--- linux-qcom-6.8.0.orig/.editorconfig
+++ linux-qcom-6.8.0/.editorconfig
@@ -5,7 +5,6 @@
 [{*.{awk,c,dts,dtsi,dtso,h,mk,s,S},Kconfig,Makefile,Makefile.*}]
 charset = utf-8
 end_of_line = lf
-trim_trailing_whitespace = true
 insert_final_newline = true
 indent_style = tab
 indent_size = 8
@@ -13,7 +12,6 @@
 [*.{json,py,rs}]
 charset = utf-8
 end_of_line = lf
-trim_trailing_whitespace = true
 insert_final_newline = true
 indent_style = space
 indent_size = 4
@@ -26,7 +24,6 @@
 [*.yaml]
 charset = utf-8
 end_of_line = lf
-trim_trailing_whitespace = unset
 insert_final_newline = true
 indent_style = space
 indent_size = 2
--- linux-qcom-6.8.0.orig/Documentation/ABI/stable/sysfs-block
+++ linux-qcom-6.8.0/Documentation/ABI/stable/sysfs-block
@@ -101,6 +101,16 @@
 		devices that support receiving integrity metadata.
 
 
+What:		/sys/block/<disk>/partscan
+Date:		May 2024
+Contact:	Christoph Hellwig <hch@lst.de>
+Description:
+		The /sys/block/<disk>/partscan files reports if partition
+		scanning is enabled for the disk.  It returns "1" if partition
+		scanning is enabled, or "0" if not.  The value type is a 32-bit
+		unsigned integer, but only "0" and "1" are valid values.
+
+
 What:		/sys/block/<disk>/<partition>/alignment_offset
 Date:		April 2009
 Contact:	Martin K. Petersen <martin.petersen@oracle.com>
@@ -166,6 +176,16 @@
 		encryption, refer to Documentation/block/inline-encryption.rst.
 
 
+What:		/sys/block/<disk>/queue/crypto/hw_wrapped_keys
+Contact:	linux-block@vger.kernel.org
+Description:
+		[RO] The presence of this file indicates that the device
+		supports hardware-wrapped inline encryption keys, i.e. key blobs
+		that can only be unwrapped and used by dedicated hardware.  For
+		more information about hardware-wrapped inline encryption keys,
+		see Documentation/block/inline-encryption.rst.
+
+
 What:		/sys/block/<disk>/queue/crypto/max_dun_bits
 Date:		February 2022
 Contact:	linux-block@vger.kernel.org
@@ -204,6 +224,14 @@
 		use with inline encryption.
 
 
+What:		/sys/block/<disk>/queue/crypto/standard_keys
+Contact:	linux-block@vger.kernel.org
+Description:
+		[RO] The presence of this file indicates that the device
+		supports standard inline encryption keys, i.e. keys that are
+		managed in raw, plaintext form in software.
+
+
 What:		/sys/block/<disk>/queue/dax
 Date:		June 2016
 Contact:	linux-block@vger.kernel.org
--- linux-qcom-6.8.0.orig/Documentation/ABI/testing/debugfs-driver-dcc
+++ linux-qcom-6.8.0/Documentation/ABI/testing/debugfs-driver-dcc
@@ -1,4 +1,4 @@
-What:           /sys/kernel/debug/dcc/.../ready
+What:           /sys/kernel/debug/qcom-dcc/.../ready
 Date:           December 2022
 Contact:        Souradeep Chowdhury <quic_schowdhu@quicinc.com>
 Description:
@@ -6,7 +6,7 @@
 		hardware if it's ready to receive user configurations.
 		A 'Y' here indicates dcc is ready.
 
-What:           /sys/kernel/debug/dcc/.../trigger
+What:           /sys/kernel/debug/qcom-dcc/.../trigger
 Date:           December 2022
 Contact:        Souradeep Chowdhury <quic_schowdhu@quicinc.com>
 Description:
@@ -14,7 +14,7 @@
 		triggers. The trigger can be invoked by writing '1'
 		to the file.
 
-What:           /sys/kernel/debug/dcc/.../config_reset
+What:           /sys/kernel/debug/qcom-dcc/.../config_reset
 Date:           December 2022
 Contact:        Souradeep Chowdhury <quic_schowdhu@quicinc.com>
 Description:
@@ -24,7 +24,7 @@
 		stored in the driver gets removed and users need to
 		reconfigure addresses again.
 
-What:           /sys/kernel/debug/dcc/.../[list-number]/config
+What:           /sys/kernel/debug/qcom-dcc/.../[list-number]/config
 Date:		 December 2022
 Contact:        Souradeep Chowdhury <quic_schowdhu@quicinc.com>
 Description:
@@ -109,7 +109,7 @@
 		    <address>
 			Space-separated list of addresses.
 
-What:           /sys/kernel/debug/dcc/.../[list-number]/enable
+What:           /sys/kernel/debug/qcom-dcc/.../[list-number]/enable
 Date:           December 2022
 Contact:        Souradeep Chowdhury <quic_schowdhu@quicinc.com>
 Description:
--- linux-qcom-6.8.0.orig/Documentation/ABI/testing/debugfs-driver-qat
+++ linux-qcom-6.8.0/Documentation/ABI/testing/debugfs-driver-qat
@@ -81,3 +81,29 @@
 			<N>: Number of Compress and Verify (CnV) errors and type
 			     of the last CnV error detected by Acceleration
 			     Engine N.
+
+What:		/sys/kernel/debug/qat_<device>_<BDF>/heartbeat/inject_error
+Date:		March 2024
+KernelVersion:	6.8
+Contact:	qat-linux@intel.com
+Description:	(WO) Write to inject an error that simulates an heartbeat
+		failure. This is to be used for testing purposes.
+
+		After writing this file, the driver stops arbitration on a
+		random engine and disables the fetching of heartbeat counters.
+		If a workload is running on the device, a job submitted to the
+		accelerator might not get a response and a read of the
+		`heartbeat/status` attribute might report -1, i.e. device
+		unresponsive.
+		The error is unrecoverable thus the device must be restarted to
+		restore its functionality.
+
+		This attribute is available only when the kernel is built with
+		CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION=y.
+
+		A write of 1 enables error injection.
+
+		The following example shows how to enable error injection::
+
+			# cd /sys/kernel/debug/qat_<device>_<BDF>
+			# echo 1 > heartbeat/inject_error
--- linux-qcom-6.8.0.orig/Documentation/ABI/testing/ima_policy
+++ linux-qcom-6.8.0/Documentation/ABI/testing/ima_policy
@@ -26,7 +26,7 @@
 				[uid=] [euid=] [gid=] [egid=]
 				[fowner=] [fgroup=]]
 			lsm:	[[subj_user=] [subj_role=] [subj_type=]
-				 [obj_user=] [obj_role=] [obj_type=]]
+				 [obj_user=] [obj_role=] [obj_type=] [lsm=]]
 			option:	[digest_type=] [template=] [permit_directio]
 				[appraise_type=] [appraise_flag=]
 				[appraise_algos=] [keyrings=]
@@ -138,6 +138,12 @@
 
 			measure subj_user=_ func=FILE_CHECK mask=MAY_READ
 
+		It is possible to explicitly specify which security
+		module a rule applies to using lsm=.  If the security
+		module specified is not active on the system the rule
+		will be rejected.  If lsm= is not specified the first
+		security module registered on the system will be assumed.
+
 		Example of measure rules using alternate PCRs::
 
 			measure func=KEXEC_KERNEL_CHECK pcr=4
--- linux-qcom-6.8.0.orig/Documentation/ABI/testing/sysfs-bus-coresight-devices-dummy-source
+++ linux-qcom-6.8.0/Documentation/ABI/testing/sysfs-bus-coresight-devices-dummy-source
@@ -0,0 +1,15 @@
+What:		/sys/bus/coresight/devices/dummy_source<N>/enable_source
+Date:		June 2024
+KernelVersion:	6.9
+Contact:	Mao Jinlong <quic_jinlmao@quicinc.com>
+Description:	(RW) Enable/disable tracing of dummy source. A sink should be activated
+		before enabling the source. The path of coresight components linking
+		the source to the sink is configured and managed automatically by the
+		coresight framework.
+
+What:		/sys/bus/coresight/devices/dummy_source<N>/traceid
+Date:		June 2024
+KernelVersion:	6.9
+Contact:	Mao Jinlong <quic_jinlmao@quicinc.com>
+Description:	(R) Show the trace ID that will appear in the trace stream
+		coming from this trace entity.
--- linux-qcom-6.8.0.orig/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
+++ linux-qcom-6.8.0/Documentation/ABI/testing/sysfs-bus-coresight-devices-tmc
@@ -91,19 +91,3 @@
 Description:	(RW) Size of the trace buffer for TMC-ETR when used in SYSFS
 		mode. Writable only for TMC-ETR configurations. The value
 		should be aligned to the kernel pagesize.
-
-What:		/sys/bus/coresight/devices/<memory_map>.tmc/buf_modes_available
-Date:		August 2023
-KernelVersion:	6.7
-Contact:	Anshuman Khandual <anshuman.khandual@arm.com>
-Description:	(Read) Shows all supported Coresight TMC-ETR buffer modes available
-		for the users to configure explicitly. This file is avaialble only
-		for TMC ETR devices.
-
-What:		/sys/bus/coresight/devices/<memory_map>.tmc/buf_mode_preferred
-Date:		August 2023
-KernelVersion:	6.7
-Contact:	Anshuman Khandual <anshuman.khandual@arm.com>
-Description:	(RW) Current Coresight TMC-ETR buffer mode selected. But user could
-		only provide a mode which is supported for a given ETR device. This
-		file is available only for TMC ETR devices.
--- linux-qcom-6.8.0.orig/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ linux-qcom-6.8.0/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -170,3 +170,90 @@
 Description:
 		(RW) Set/Get the MSR(mux select register) for the DSB subunit
 		TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_mode
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
+Description:	(Write) Set the data collection mode of CMB tpdm. Continuous
+		change creates CMB data set elements on every CMBCLK edge.
+		Trace-on-change creates CMB data set elements only when a new
+		data set element differs in value from the previous element
+		in a CMB data set.
+
+		Accepts only one of the 2 values -  0 or 1.
+		0 : Continuous CMB collection mode.
+		1 : Trace-on-change CMB collection mode.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_trig_patt/xpr[0:1]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
+Description:
+		(RW) Set/Get the value of the trigger pattern for the CMB
+		subunit TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_trig_patt/xpmr[0:1]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
+Description:
+		(RW) Set/Get the mask of the trigger pattern for the CMB
+		subunit TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/dsb_patt/tpr[0:1]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
+Description:
+		(RW) Set/Get the value of the pattern for the CMB subunit TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/dsb_patt/tpmr[0:1]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
+Description:
+		(RW) Set/Get the mask of the pattern for the CMB subunit TPDM.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
+Description:
+		(Write) Set the pattern timestamp of CMB tpdm. Read
+		the pattern timestamp of CMB tpdm.
+
+		Accepts only one of the 2 values -  0 or 1.
+		0 : Disable CMB pattern timestamp.
+		1 : Enable CMB pattern timestamp.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
+Description:
+		(RW) Set/Get the trigger timestamp of the CMB for tpdm.
+
+		Accepts only one of the 2 values -  0 or 1.
+		0 : Set the CMB trigger type to false
+		1 : Set the CMB trigger type to true
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
+Description:
+		(RW) Read or write the status of timestamp upon all interface.
+		Only value 0 and 1  can be written to this node. Set this node to 1 to requeset
+		timestamp to all trace packet.
+		Accepts only one of the 2 values -  0 or 1.
+		0 : Disable the timestamp of all trace packets.
+		1 : Enable the timestamp of all trace packets.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
+Date:		January 2024
+KernelVersion	6.9
+Contact:	Jinlong Mao (QUIC) <quic_jinlmao@quicinc.com>, Tao Zhang (QUIC) <quic_taozha@quicinc.com>
+Description:
+		(RW) Set/Get the MSR(mux select register) for the CMB subunit
+		TPDM.
--- linux-qcom-6.8.0.orig/Documentation/ABI/testing/sysfs-bus-iio-filter-admv8818
+++ linux-qcom-6.8.0/Documentation/ABI/testing/sysfs-bus-iio-filter-admv8818
@@ -3,7 +3,7 @@
 Contact:	linux-iio@vger.kernel.org
 Description:
 		Reading this returns the valid values that can be written to the
-		on_altvoltage0_mode attribute:
+		filter_mode attribute:
 
 		- auto -> Adjust bandpass filter to track changes in input clock rate.
 		- manual -> disable/unregister the clock rate notifier / input clock tracking.
--- linux-qcom-6.8.0.orig/Documentation/ABI/testing/sysfs-bus-pci
+++ linux-qcom-6.8.0/Documentation/ABI/testing/sysfs-bus-pci
@@ -163,6 +163,17 @@
 		will be present in sysfs.  Writing 1 to this file
 		will perform reset.
 
+What:		/sys/bus/pci/devices/.../reset_subordinate
+Date:		October 2024
+Contact:	linux-pci@vger.kernel.org
+Description:
+		This is visible only for bridge devices. If you want to reset
+		all devices attached through the subordinate bus of a specific
+		bridge device, writing 1 to this will try to do it.  This will
+		affect all devices attached to the system through this bridge
+		similiar to writing 1 to their individual "reset" file, so use
+		with caution.
+
 What:		/sys/bus/pci/devices/.../vpd
 Date:		February 2008
 Contact:	Ben Hutchings <bwh@kernel.org>
--- linux-qcom-6.8.0.orig/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ linux-qcom-6.8.0/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -516,6 +516,7 @@
 		/sys/devices/system/cpu/vulnerabilities/mds
 		/sys/devices/system/cpu/vulnerabilities/meltdown
 		/sys/devices/system/cpu/vulnerabilities/mmio_stale_data
+		/sys/devices/system/cpu/vulnerabilities/reg_file_data_sampling
 		/sys/devices/system/cpu/vulnerabilities/retbleed
 		/sys/devices/system/cpu/vulnerabilities/spec_store_bypass
 		/sys/devices/system/cpu/vulnerabilities/spectre_v1
@@ -561,7 +562,8 @@
 			 ================ =========================================
 
 			 If control status is "forceoff" or "notsupported" writes
-			 are rejected.
+			 are rejected. Note that enabling SMT on PowerPC skips
+			 offline cores.
 
 What:		/sys/devices/system/cpu/cpuX/power/energy_perf_bias
 Date:		March 2019
--- linux-qcom-6.8.0.orig/Documentation/ABI/testing/sysfs-driver-qat
+++ linux-qcom-6.8.0/Documentation/ABI/testing/sysfs-driver-qat
@@ -141,3 +141,23 @@
 			64
 
 		This attribute is only available for qat_4xxx devices.
+
+What:		/sys/bus/pci/devices/<BDF>/qat/auto_reset
+Date:		March 2024
+KernelVersion:	6.8
+Contact:	qat-linux@intel.com
+Description:	(RW) Reports the current state of the autoreset feature
+		for a QAT device
+
+		Write to the attribute to enable or disable device auto reset.
+
+		Device auto reset is disabled by default.
+
+		The values are:
+
+		* 1/Yy/on: auto reset enabled. If the device encounters an
+		  unrecoverable error, it will be reset automatically.
+		* 0/Nn/off: auto reset disabled. If the device encounters an
+		  unrecoverable error, it will not be reset.
+
+		This attribute is only available for qat_4xxx devices.
--- linux-qcom-6.8.0.orig/Documentation/ABI/testing/sysfs-fs-f2fs
+++ linux-qcom-6.8.0/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -311,10 +311,13 @@
 		GC approach and turns SSR mode on.
 		gc urgent low(2): lowers the bar of checking I/O idling in
 		order to process outstanding discard commands and GC a
-		little bit aggressively. uses cost benefit GC approach.
+		little bit aggressively. always uses cost benefit GC approach,
+		and will override age-threshold GC approach if ATGC is enabled
+		at the same time.
 		gc urgent mid(3): does GC forcibly in a period of given
 		gc_urgent_sleep_time and executes a mid level of I/O idling check.
-		uses cost benefit GC approach.
+		always uses cost benefit GC approach, and will override
+		age-threshold GC approach if ATGC is enabled at the same time.
 
 What:		/sys/fs/f2fs/<disk>/gc_urgent_sleep_time
 Date:		August 2017
@@ -761,3 +764,25 @@
 Contact:	"Chao Yu" <chao@kernel.org>
 Description:	It controls to enable/disable IO aware feature for background discard.
 		By default, the value is 1 which indicates IO aware is on.
+
+What:		/sys/fs/f2fs/<disk>/blkzone_alloc_policy
+Date:		July 2024
+Contact:	"Yuanhong Liao" <liaoyuanhong@vivo.com>
+Description:	The zone UFS we are currently using consists of two parts:
+		conventional zones and sequential zones. It can be used to control which part
+		to prioritize for writes, with a default value of 0.
+
+		========================  =========================================
+		value					  description
+		blkzone_alloc_policy = 0  Prioritize writing to sequential zones
+		blkzone_alloc_policy = 1  Only allow writing to sequential zones
+		blkzone_alloc_policy = 2  Prioritize writing to conventional zones
+		========================  =========================================
+
+What:		/sys/fs/f2fs/<disk>/migration_window_granularity
+Date:		September 2024
+Contact:	"Daeho Jeong" <daehojeong@google.com>
+Description:	Controls migration window granularity of garbage collection on large
+		section. it can control the scanning window granularity for GC migration
+		in a unit of segment, while migration_granularity controls the number
+		of segments which can be migrated at the same turn.
--- linux-qcom-6.8.0.orig/Documentation/ABI/testing/sysfs-fs-xfs
+++ linux-qcom-6.8.0/Documentation/ABI/testing/sysfs-fs-xfs
@@ -1,7 +1,7 @@
 What:		/sys/fs/xfs/<disk>/log/log_head_lsn
 Date:		July 2014
 KernelVersion:	3.17
-Contact:	xfs@oss.sgi.com
+Contact:	linux-xfs@vger.kernel.org
 Description:
 		The log sequence number (LSN) of the current head of the
 		log. The LSN is exported in "cycle:basic block" format.
@@ -10,7 +10,7 @@
 What:		/sys/fs/xfs/<disk>/log/log_tail_lsn
 Date:		July 2014
 KernelVersion:	3.17
-Contact:	xfs@oss.sgi.com
+Contact:	linux-xfs@vger.kernel.org
 Description:
 		The log sequence number (LSN) of the current tail of the
 		log. The LSN is exported in "cycle:basic block" format.
@@ -18,7 +18,7 @@
 What:		/sys/fs/xfs/<disk>/log/reserve_grant_head
 Date:		July 2014
 KernelVersion:	3.17
-Contact:	xfs@oss.sgi.com
+Contact:	linux-xfs@vger.kernel.org
 Description:
 		The current state of the log reserve grant head. It
 		represents the total log reservation of all currently
@@ -29,7 +29,7 @@
 What:		/sys/fs/xfs/<disk>/log/write_grant_head
 Date:		July 2014
 KernelVersion:	3.17
-Contact:	xfs@oss.sgi.com
+Contact:	linux-xfs@vger.kernel.org
 Description:
 		The current state of the log write grant head. It
 		represents the total log reservation of all currently
--- linux-qcom-6.8.0.orig/Documentation/Makefile
+++ linux-qcom-6.8.0/Documentation/Makefile
@@ -111,8 +111,10 @@
 $(YNL_RST_DIR)/%.rst: $(YNL_YAML_DIR)/%.yaml $(YNL_TOOL)
 	$(Q)$(YNL_TOOL) -i $< -o $@
 
-htmldocs: $(YNL_INDEX)
-	@$(srctree)/scripts/sphinx-pre-install --version-check
+htmldocs texinfodocs latexdocs epubdocs xmldocs: $(YNL_INDEX)
+
+htmldocs:
+	@$(srctree)/scripts/sphinx-pre-install --version-check --no-virtualenv
 	@+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,html,$(var),,$(var)))
 
 # If Rust support is available and .config exists, add rustdoc generated contents.
--- linux-qcom-6.8.0.orig/Documentation/RCU/stallwarn.rst
+++ linux-qcom-6.8.0/Documentation/RCU/stallwarn.rst
@@ -249,7 +249,7 @@
 interrupts during the current stalled grace period.
 
 The "idle=" portion of the message prints the dyntick-idle state.
-The hex number before the first "/" is the low-order 12 bits of the
+The hex number before the first "/" is the low-order 16 bits of the
 dynticks counter, which will have an even-numbered value if the CPU
 is in dyntick-idle mode and an odd-numbered value otherwise.  The hex
 number between the two "/"s is the value of the nesting, which will be
--- linux-qcom-6.8.0.orig/Documentation/accel/qaic/aic080.rst
+++ linux-qcom-6.8.0/Documentation/accel/qaic/aic080.rst
@@ -0,0 +1,14 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+===============================
+ Qualcomm Cloud AI 80 (AIC080)
+===============================
+
+Overview
+========
+
+The Qualcomm Cloud AI 80/AIC080 family of products are a derivative of AIC100.
+The number of NSPs and clock rates are reduced to fit within resource
+constrained solutions. The PCIe Product ID is 0xa080.
+
+As a derivative product, all AIC100 documentation applies.
--- linux-qcom-6.8.0.orig/Documentation/accel/qaic/index.rst
+++ linux-qcom-6.8.0/Documentation/accel/qaic/index.rst
@@ -10,4 +10,5 @@
 .. toctree::
 
    qaic
+   aic080
    aic100
--- linux-qcom-6.8.0.orig/Documentation/admin-guide/blockdev/zram.rst
+++ linux-qcom-6.8.0/Documentation/admin-guide/blockdev/zram.rst
@@ -47,6 +47,8 @@
 -ENOMEM	  zram was not able to allocate enough memory to fulfil your
 	  needs.
 -EINVAL	  invalid input has been provided.
+-EAGAIN	  re-try operation later (e.g. when attempting to run recompress
+	  and writeback simultaneously).
 ========  =============================================================
 
 If you use 'echo', the returned value is set by the 'echo' utility,
--- linux-qcom-6.8.0.orig/Documentation/admin-guide/cgroup-v2.rst
+++ linux-qcom-6.8.0/Documentation/admin-guide/cgroup-v2.rst
@@ -1694,9 +1694,10 @@
 	entries fault back in or are written out to disk.
 
   memory.zswap.writeback
-	A read-write single value file. The default value is "1". The
-	initial value of the root cgroup is 1, and when a new cgroup is
-	created, it inherits the current value of its parent.
+	A read-write single value file. The default value is "1".
+	Note that this setting is hierarchical, i.e. the writeback would be
+	implicitly disabled for child cgroups if the upper hierarchy
+	does so.
 
 	When this is set to 0, all swapping attempts to swapping devices
 	are disabled. This included both zswap writebacks, and swapping due
@@ -2320,8 +2321,12 @@
 	is always a subset of it.
 
 	Users can manually set it to a value that is different from
-	"cpuset.cpus".	The only constraint in setting it is that the
-	list of CPUs must be exclusive with respect to its sibling.
+	"cpuset.cpus".	One constraint in setting it is that the list of
+	CPUs must be exclusive with respect to "cpuset.cpus.exclusive"
+	of its sibling.  If "cpuset.cpus.exclusive" of a sibling cgroup
+	isn't set, its "cpuset.cpus" value, if set, cannot be a subset
+	of it to leave at least one CPU available when the exclusive
+	CPUs are taken away.
 
 	For a parent cgroup, any one of its exclusive CPUs can only
 	be distributed to at most one of its child cgroups.  Having an
--- linux-qcom-6.8.0.orig/Documentation/admin-guide/cifs/usage.rst
+++ linux-qcom-6.8.0/Documentation/admin-guide/cifs/usage.rst
@@ -723,40 +723,26 @@
 ======================= =======================================================
 SecurityFlags		Flags which control security negotiation and
 			also packet signing. Authentication (may/must)
-			flags (e.g. for NTLM and/or NTLMv2) may be combined with
+			flags (e.g. for NTLMv2) may be combined with
 			the signing flags.  Specifying two different password
 			hashing mechanisms (as "must use") on the other hand
 			does not make much sense. Default flags are::
 
-				0x07007
+				0x00C5
 
-			(NTLM, NTLMv2 and packet signing allowed).  The maximum
-			allowable flags if you want to allow mounts to servers
-			using weaker password hashes is 0x37037 (lanman,
-			plaintext, ntlm, ntlmv2, signing allowed).  Some
-			SecurityFlags require the corresponding menuconfig
-			options to be enabled.  Enabling plaintext
-			authentication currently requires also enabling
-			lanman authentication in the security flags
-			because the cifs module only supports sending
-			laintext passwords using the older lanman dialect
-			form of the session setup SMB.  (e.g. for authentication
-			using plain text passwords, set the SecurityFlags
-			to 0x30030)::
+			(NTLMv2 and packet signing allowed).  Some SecurityFlags
+			may require enabling a corresponding menuconfig option.
 
 			  may use packet signing			0x00001
 			  must use packet signing			0x01001
-			  may use NTLM (most common password hash)	0x00002
-			  must use NTLM					0x02002
 			  may use NTLMv2				0x00004
 			  must use NTLMv2				0x04004
-			  may use Kerberos security			0x00008
-			  must use Kerberos				0x08008
-			  may use lanman (weak) password hash		0x00010
-			  must use lanman password hash			0x10010
-			  may use plaintext passwords			0x00020
-			  must use plaintext passwords			0x20020
-			  (reserved for future packet encryption)	0x00040
+			  may use Kerberos security (krb5)		0x00008
+			  must use Kerberos                             0x08008
+			  may use NTLMSSP               		0x00080
+			  must use NTLMSSP           			0x80080
+			  seal (packet encryption)			0x00040
+			  must seal                                     0x40040
 
 cifsFYI			If set to non-zero value, additional debug information
 			will be logged to the system error log.  This field
--- linux-qcom-6.8.0.orig/Documentation/admin-guide/gpio/gpio-aggregator.rst
+++ linux-qcom-6.8.0/Documentation/admin-guide/gpio/gpio-aggregator.rst
@@ -69,6 +69,113 @@
 		    $ echo gpio-aggregator.0 > delete_device
 
 
+Aggregating GPIOs using Configfs
+--------------------------------
+
+**Group:** ``/config/gpio-aggregator``
+
+    This is the root directory of the gpio-aggregator configfs tree.
+
+**Group:** ``/config/gpio-aggregator/<example-name>``
+
+    This directory represents a GPIO aggregator device. You can assign any
+    name to ``<example-name>`` (e.g. ``agg0``), except names starting with
+    ``_sysfs`` prefix, which are reserved for auto-generated configfs
+    entries corresponding to devices created via Sysfs.
+
+**Attribute:** ``/config/gpio-aggregator/<example-name>/live``
+
+    The ``live`` attribute allows to trigger the actual creation of the device
+    once it's fully configured. Accepted values are:
+
+    * ``1``, ``yes``, ``true`` : enable the virtual device
+    * ``0``, ``no``, ``false`` : disable the virtual device
+
+**Attribute:** ``/config/gpio-aggregator/<example-name>/dev_name``
+
+    The read-only ``dev_name`` attribute exposes the name of the device as it
+    will appear in the system on the platform bus (e.g. ``gpio-aggregator.0``).
+    This is useful for identifying a character device for the newly created
+    aggregator. If it's ``gpio-aggregator.0``,
+    ``/sys/devices/platform/gpio-aggregator.0/gpiochipX`` path tells you that the
+    GPIO device id is ``X``.
+
+You must create subdirectories for each virtual line you want to
+instantiate, named exactly as ``line0``, ``line1``, ..., ``lineY``, when
+you want to instantiate ``Y+1`` (Y >= 0) lines.  Configure all lines before
+activating the device by setting ``live`` to 1.
+
+**Group:** ``/config/gpio-aggregator/<example-name>/<lineY>/``
+
+    This directory represents a GPIO line to include in the aggregator.
+
+**Attribute:** ``/config/gpio-aggregator/<example-name>/<lineY>/key``
+
+**Attribute:** ``/config/gpio-aggregator/<example-name>/<lineY>/offset``
+
+    The default values after creating the ``<lineY>`` directory are:
+
+    * ``key`` : <empty>
+    * ``offset`` : -1
+
+    ``key`` must always be explicitly configured, while ``offset`` depends.
+    Two configuration patterns exist for each ``<lineY>``:
+
+    (a). For lookup by GPIO line name:
+
+         * Set ``key`` to the line name.
+         * Ensure ``offset`` remains -1 (the default).
+
+    (b). For lookup by GPIO chip name and the line offset within the chip:
+
+         * Set ``key`` to the chip name.
+         * Set ``offset`` to the line offset (0 <= ``offset`` < 65535).
+
+**Attribute:** ``/config/gpio-aggregator/<example-name>/<lineY>/name``
+
+    The ``name`` attribute sets a custom name for lineY. If left unset, the
+    line will remain unnamed.
+
+Once the configuration is done, the ``'live'`` attribute must be set to 1
+in order to instantiate the aggregator device. It can be set back to 0 to
+destroy the virtual device. The module will synchronously wait for the new
+aggregator device to be successfully probed and if this doesn't happen, writing
+to ``'live'`` will result in an error. This is a different behaviour from the
+case when you create it using sysfs ``new_device`` interface.
+
+.. note::
+
+   For aggregators created via Sysfs, the configfs entries are
+   auto-generated and appear as ``/config/gpio-aggregator/_sysfs.<N>/``. You
+   cannot add or remove line directories with mkdir(2)/rmdir(2). To modify
+   lines, you must use the "delete_device" interface to tear down the
+   existing device and reconfigure it from scratch. However, you can still
+   toggle the aggregator with the ``live`` attribute and adjust the
+   ``key``, ``offset``, and ``name`` attributes for each line when ``live``
+   is set to 0 by hand (i.e. it's not waiting for deferred probe).
+
+Sample configuration commands
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: sh
+
+    # Create a directory for an aggregator device
+    $ mkdir /sys/kernel/config/gpio-aggregator/agg0
+
+    # Configure each line
+    $ mkdir /sys/kernel/config/gpio-aggregator/agg0/line0
+    $ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line0/key
+    $ echo 6         > /sys/kernel/config/gpio-aggregator/agg0/line0/offset
+    $ echo test0     > /sys/kernel/config/gpio-aggregator/agg0/line0/name
+    $ mkdir /sys/kernel/config/gpio-aggregator/agg0/line1
+    $ echo gpiochip0 > /sys/kernel/config/gpio-aggregator/agg0/line1/key
+    $ echo 7         > /sys/kernel/config/gpio-aggregator/agg0/line1/offset
+    $ echo test1     > /sys/kernel/config/gpio-aggregator/agg0/line1/name
+
+    # Activate the aggregator device
+    $ echo 1         > /sys/kernel/config/gpio-aggregator/agg0/live
+
+
 Generic GPIO Driver
 -------------------
 
--- linux-qcom-6.8.0.orig/Documentation/admin-guide/hw-vuln/core-scheduling.rst
+++ linux-qcom-6.8.0/Documentation/admin-guide/hw-vuln/core-scheduling.rst
@@ -67,8 +67,8 @@
     will be performed for all tasks in the task group of ``pid``.
 
 arg5:
-    userspace pointer to an unsigned long for storing the cookie returned by
-    ``PR_SCHED_CORE_GET`` command. Should be 0 for all other commands.
+    userspace pointer to an unsigned long long for storing the cookie returned
+    by ``PR_SCHED_CORE_GET`` command. Should be 0 for all other commands.
 
 In order for a process to push a cookie to, or pull a cookie from a process, it
 is required to have the ptrace access mode: `PTRACE_MODE_READ_REALCREDS` to the
--- linux-qcom-6.8.0.orig/Documentation/admin-guide/hw-vuln/index.rst
+++ linux-qcom-6.8.0/Documentation/admin-guide/hw-vuln/index.rst
@@ -21,3 +21,4 @@
    cross-thread-rsb
    srso
    gather_data_sampling
+   reg-file-data-sampling
--- linux-qcom-6.8.0.orig/Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst
+++ linux-qcom-6.8.0/Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst
@@ -0,0 +1,104 @@
+==================================
+Register File Data Sampling (RFDS)
+==================================
+
+Register File Data Sampling (RFDS) is a microarchitectural vulnerability that
+only affects Intel Atom parts(also branded as E-cores). RFDS may allow
+a malicious actor to infer data values previously used in floating point
+registers, vector registers, or integer registers. RFDS does not provide the
+ability to choose which data is inferred. CVE-2023-28746 is assigned to RFDS.
+
+Affected Processors
+===================
+Below is the list of affected Intel processors [#f1]_:
+
+   ===================  ============
+   Common name          Family_Model
+   ===================  ============
+   ATOM_GOLDMONT           06_5CH
+   ATOM_GOLDMONT_D         06_5FH
+   ATOM_GOLDMONT_PLUS      06_7AH
+   ATOM_TREMONT_D          06_86H
+   ATOM_TREMONT            06_96H
+   ALDERLAKE               06_97H
+   ALDERLAKE_L             06_9AH
+   ATOM_TREMONT_L          06_9CH
+   RAPTORLAKE              06_B7H
+   RAPTORLAKE_P            06_BAH
+   ATOM_GRACEMONT          06_BEH
+   RAPTORLAKE_S            06_BFH
+   ===================  ============
+
+As an exception to this table, Intel Xeon E family parts ALDERLAKE(06_97H) and
+RAPTORLAKE(06_B7H) codenamed Catlow are not affected. They are reported as
+vulnerable in Linux because they share the same family/model with an affected
+part. Unlike their affected counterparts, they do not enumerate RFDS_CLEAR or
+CPUID.HYBRID. This information could be used to distinguish between the
+affected and unaffected parts, but it is deemed not worth adding complexity as
+the reporting is fixed automatically when these parts enumerate RFDS_NO.
+
+Mitigation
+==========
+Intel released a microcode update that enables software to clear sensitive
+information using the VERW instruction. Like MDS, RFDS deploys the same
+mitigation strategy to force the CPU to clear the affected buffers before an
+attacker can extract the secrets. This is achieved by using the otherwise
+unused and obsolete VERW instruction in combination with a microcode update.
+The microcode clears the affected CPU buffers when the VERW instruction is
+executed.
+
+Mitigation points
+-----------------
+VERW is executed by the kernel before returning to user space, and by KVM
+before VMentry. None of the affected cores support SMT, so VERW is not required
+at C-state transitions.
+
+New bits in IA32_ARCH_CAPABILITIES
+----------------------------------
+Newer processors and microcode update on existing affected processors added new
+bits to IA32_ARCH_CAPABILITIES MSR. These bits can be used to enumerate
+vulnerability and mitigation capability:
+
+- Bit 27 - RFDS_NO - When set, processor is not affected by RFDS.
+- Bit 28 - RFDS_CLEAR - When set, processor is affected by RFDS, and has the
+  microcode that clears the affected buffers on VERW execution.
+
+Mitigation control on the kernel command line
+---------------------------------------------
+The kernel command line allows to control RFDS mitigation at boot time with the
+parameter "reg_file_data_sampling=". The valid arguments are:
+
+  ==========  =================================================================
+  on          If the CPU is vulnerable, enable mitigation; CPU buffer clearing
+              on exit to userspace and before entering a VM.
+  off         Disables mitigation.
+  ==========  =================================================================
+
+Mitigation default is selected by CONFIG_MITIGATION_RFDS.
+
+Mitigation status information
+-----------------------------
+The Linux kernel provides a sysfs interface to enumerate the current
+vulnerability status of the system: whether the system is vulnerable, and
+which mitigations are active. The relevant sysfs file is:
+
+	/sys/devices/system/cpu/vulnerabilities/reg_file_data_sampling
+
+The possible values in this file are:
+
+  .. list-table::
+
+     * - 'Not affected'
+       - The processor is not vulnerable
+     * - 'Vulnerable'
+       - The processor is vulnerable, but no mitigation enabled
+     * - 'Vulnerable: No microcode'
+       - The processor is vulnerable but microcode is not updated.
+     * - 'Mitigation: Clear Register File'
+       - The processor is vulnerable and the CPU buffer clearing mitigation is
+	 enabled.
+
+References
+----------
+.. [#f1] Affected Processors
+   https://www.intel.com/content/www/us/en/developer/topic-technology/software-security-guidance/processors-affected-consolidated-product-cpu-model.html
--- linux-qcom-6.8.0.orig/Documentation/admin-guide/hw-vuln/spectre.rst
+++ linux-qcom-6.8.0/Documentation/admin-guide/hw-vuln/spectre.rst
@@ -138,11 +138,10 @@
 the BHB might be shared across privilege levels even in the presence of
 Enhanced IBRS.
 
-Currently the only known real-world BHB attack vector is via
-unprivileged eBPF. Therefore, it's highly recommended to not enable
-unprivileged eBPF, especially when eIBRS is used (without retpolines).
-For a full mitigation against BHB attacks, it's recommended to use
-retpolines (or eIBRS combined with retpolines).
+Previously the only known real-world BHB attack vector was via unprivileged
+eBPF. Further research has found attacks that don't require unprivileged eBPF.
+For a full mitigation against BHB attacks it is recommended to set BHI_DIS_S or
+use the BHB clearing sequence.
 
 Attack scenarios
 ----------------
@@ -430,6 +429,23 @@
   'PBRSB-eIBRS: Not affected'  CPU is not affected by PBRSB
   ===========================  =======================================================
 
+  - Branch History Injection (BHI) protection status:
+
+.. list-table::
+
+ * - BHI: Not affected
+   - System is not affected
+ * - BHI: Retpoline
+   - System is protected by retpoline
+ * - BHI: BHI_DIS_S
+   - System is protected by BHI_DIS_S
+ * - BHI: SW loop, KVM SW loop
+   - System is protected by software clearing sequence
+ * - BHI: Vulnerable
+   - System is vulnerable to BHI
+ * - BHI: Vulnerable, KVM: SW loop
+   - System is vulnerable; KVM is protected by software clearing sequence
+
 Full mitigation might require a microcode update from the CPU
 vendor. When the necessary microcode is not available, the kernel will
 report vulnerability.
@@ -484,7 +500,11 @@
 
    Systems which support enhanced IBRS (eIBRS) enable IBRS protection once at
    boot, by setting the IBRS bit, and they're automatically protected against
-   Spectre v2 variant attacks.
+   some Spectre v2 variant attacks. The BHB can still influence the choice of
+   indirect branch predictor entry, and although branch predictor entries are
+   isolated between modes when eIBRS is enabled, the BHB itself is not isolated
+   between modes. Systems which support BHI_DIS_S will set it to protect against
+   BHI attacks.
 
    On Intel's enhanced IBRS systems, this includes cross-thread branch target
    injections on SMT systems (STIBP). In other words, Intel eIBRS enables
@@ -638,6 +658,18 @@
 		spectre_v2=off. Spectre variant 1 mitigations
 		cannot be disabled.
 
+	spectre_bhi=
+
+		[X86] Control mitigation of Branch History Injection
+		(BHI) vulnerability.  This setting affects the deployment
+		of the HW BHI control and the SW BHB clearing sequence.
+
+		on
+			(default) Enable the HW or SW mitigation as
+			needed.
+		off
+			Disable the mitigation.
+
 For spectre_v2_user see Documentation/admin-guide/kernel-parameters.txt
 
 Mitigation selection guide
--- linux-qcom-6.8.0.orig/Documentation/admin-guide/kernel-parameters.txt
+++ linux-qcom-6.8.0/Documentation/admin-guide/kernel-parameters.txt
@@ -679,12 +679,6 @@
 			loops can be debugged more effectively on production
 			systems.
 
-	clocksource.max_cswd_read_retries= [KNL]
-			Number of clocksource_watchdog() retries due to
-			external delays before the clock will be marked
-			unstable.  Defaults to two retries, that is,
-			three attempts to read the clock under test.
-
 	clocksource.verify_n_cpus= [KNL]
 			Limit the number of CPUs checked for clocksources
 			marked with CLOCK_SOURCE_VERIFY_PERCPU that
@@ -848,6 +842,10 @@
 			Format:
 			<first_slot>,<last_slot>,<port>,<enum_bit>[,<debug>]
 
+	cpufreq_driver= [X86] Allow only the named cpu frequency scaling driver
+			to register. Example: cpufreq_driver=powernow-k8
+			Format: { none | STRING }
+
 	cpuidle.off=1	[CPU_IDLE]
 			disable the cpuidle sub-system
 
@@ -1150,6 +1148,26 @@
 			The filter can be disabled or changed to another
 			driver later using sysfs.
 
+	reg_file_data_sampling=
+			[X86] Controls mitigation for Register File Data
+			Sampling (RFDS) vulnerability. RFDS is a CPU
+			vulnerability which may allow userspace to infer
+			kernel data values previously stored in floating point
+			registers, vector registers, or integer registers.
+			RFDS only affects Intel Atom processors.
+
+			on:	Turns ON the mitigation.
+			off:	Turns OFF the mitigation.
+
+			This parameter overrides the compile time default set
+			by CONFIG_MITIGATION_RFDS. Mitigation cannot be
+			disabled when other VERW based mitigations (like MDS)
+			are enabled. In order to disable RFDS mitigation all
+			VERW based mitigations need to be disabled.
+
+			For details see:
+			Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst
+
 	driver_async_probe=  [KNL]
 			List of driver names to be probed asynchronously. *
 			matches with all driver names. If * is specified, the
@@ -3320,9 +3338,7 @@
 
 	mem_encrypt=	[X86-64] AMD Secure Memory Encryption (SME) control
 			Valid arguments: on, off
-			Default (depends on kernel configuration option):
-			  on  (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=y)
-			  off (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=n)
+			Default: off
 			mem_encrypt=on:		Activate SME
 			mem_encrypt=off:	Do not activate SME
 
@@ -3381,6 +3397,9 @@
 			arch-independent options, each of which is an
 			aggregation of existing arch-specific options.
 
+			Note, "mitigations" is supported if and only if the
+			kernel was built with CPU_MITIGATIONS=y.
+
 			off
 				Disable all optional CPU mitigations.  This
 				improves system performance, but it may also
@@ -3398,8 +3417,10 @@
 					       nospectre_bhb [ARM64]
 					       nospectre_v1 [X86,PPC]
 					       nospectre_v2 [X86,PPC,S390,ARM64]
+					       reg_file_data_sampling=off [X86]
 					       retbleed=off [X86]
 					       spec_store_bypass_disable=off [X86,PPC]
+					       spectre_bhi=off [X86]
 					       spectre_v2_user=off [X86]
 					       srbds=off [X86,INTEL]
 					       ssbd=force-off [ARM64]
@@ -4370,6 +4391,12 @@
 		nomsi		[MSI] If the PCI_MSI kernel config parameter is
 				enabled, this kernel boot option can be used to
 				disable the use of MSI interrupts system-wide.
+		clearmsi	[X86] Clears MSI/MSI-X enable bits early in boot
+				time in order to avoid issues like adapters
+				screaming irqs and preventing boot progress.
+				Also, it enforces the PCI Local Bus spec
+				rule that those bits should be 0 in system reset
+				events (useful for kexec/kdump cases).
 		noioapicquirk	[APIC] Disable all boot interrupt quirks.
 				Safety option to keep boot IRQs enabled. This
 				should never be necessary.
@@ -4539,6 +4566,38 @@
 				bridges without forcing it upstream. Note:
 				this removes isolation between devices and
 				may put more devices in an IOMMU group.
+		config_acs=
+				Format:
+				<ACS flags>@<pci_dev>[; ...]
+				Specify one or more PCI devices (in the format
+				specified above) optionally prepended with flags
+				and separated by semicolons. The respective
+				capabilities will be enabled, disabled or
+				unchanged based on what is specified in
+				flags.
+
+				ACS Flags is defined as follows:
+				  bit-0 : ACS Source Validation
+				  bit-1 : ACS Translation Blocking
+				  bit-2 : ACS P2P Request Redirect
+				  bit-3 : ACS P2P Completion Redirect
+				  bit-4 : ACS Upstream Forwarding
+				  bit-5 : ACS P2P Egress Control
+				  bit-6 : ACS Direct Translated P2P
+				Each bit can be marked as:
+				  '0' – force disabled
+				  '1' – force enabled
+				  'x' – unchanged
+				For example,
+				  pci=config_acs=10x
+				would configure all devices that support
+				ACS to enable P2P Request Redirect, disable
+				Translation Blocking, and leave Source
+				Validation unchanged from whatever power-up
+				or firmware set it to.
+
+				Note: this may remove isolation between devices
+				and may put more devices in an IOMMU group.
 		force_floating	[S390] Force usage of floating interrupts.
 		nomio		[S390] Do not use MIO instructions.
 		norid		[S390] ignore the RID field and force use of
@@ -4665,7 +4724,9 @@
 			none - Limited to cond_resched() calls
 			voluntary - Limited to cond_resched() and might_sleep() calls
 			full - Any section that isn't explicitly preempt disabled
-			       can be preempted anytime.
+			       can be preempted anytime.  Tasks will also yield
+			       contended spinlocks (if the critical section isn't
+			       explicitly preempt disabled beyond the lock itself).
 
 	print-fatal-signals=
 			[KNL] debug: print fatal signals
@@ -4705,6 +4766,16 @@
 	printk.time=	Show timing data prefixed to each printk message line
 			Format: <bool>  (1/Y/y=enable, 0/N/n=disable)
 
+	proc_mem.force_override= [KNL]
+			Format: {always | ptrace | never}
+			Traditionally /proc/pid/mem allows memory permissions to be
+			overridden without restrictions. This option may be set to
+			restrict that. Can be one of:
+			- 'always': traditional behavior always allows mem overrides.
+			- 'ptrace': only allow mem overrides for active ptracers.
+			- 'never':  never allow mem overrides.
+			If not specified, default is the CONFIG_PROC_MEM_* choice.
+
 	processor.max_cstate=	[HW,ACPI]
 			Limit processor to maximum C-state
 			max_cstate=9 overrides any DMI blacklist limit.
@@ -4715,11 +4786,9 @@
 
 	profile=	[KNL] Enable kernel profiling via /proc/profile
 			Format: [<profiletype>,]<number>
-			Param: <profiletype>: "schedule", "sleep", or "kvm"
+			Param: <profiletype>: "schedule" or "kvm"
 				[defaults to kernel profiling]
 			Param: "schedule" - profile schedule points.
-			Param: "sleep" - profile D-state sleeping (millisecs).
-				Requires CONFIG_SCHEDSTATS
 			Param: "kvm" - profile VM exits.
 			Param: <number> - step/bucket size as a power of 2 for
 				statistical time based profiling.
@@ -5034,6 +5103,11 @@
 			this kernel boot parameter, forcibly setting it
 			to zero.
 
+	rcutree.enable_rcu_lazy= [KNL]
+			To save power, batch RCU callbacks and flush after
+			delay, memory pressure or callback list growing too
+			big.
+
 	rcuscale.gp_async= [KNL]
 			Measure performance of asynchronous
 			grace-period primitives such as call_rcu().
@@ -6012,6 +6086,15 @@
 	sonypi.*=	[HW] Sony Programmable I/O Control Device driver
 			See Documentation/admin-guide/laptops/sonypi.rst
 
+	spectre_bhi=	[X86] Control mitigation of Branch History Injection
+			(BHI) vulnerability.  This setting affects the
+			deployment of the HW BHI control and the SW BHB
+			clearing sequence.
+
+			on   - (default) Enable the HW or SW mitigation
+			       as needed.
+			off  - Disable the mitigation.
+
 	spectre_v2=	[X86] Control mitigation of Spectre variant 2
 			(indirect branch speculation) vulnerability.
 			The default operation protects the kernel from
--- linux-qcom-6.8.0.orig/Documentation/admin-guide/media/building.rst
+++ linux-qcom-6.8.0/Documentation/admin-guide/media/building.rst
@@ -15,7 +15,7 @@
 
 you should use the main media development tree ``master`` branch:
 
-    https://git.linuxtv.org/media_tree.git/
+    https://git.linuxtv.org/media.git/
 
 In this case, you may find some useful information at the
 `LinuxTv wiki pages <https://linuxtv.org/wiki>`_:
--- linux-qcom-6.8.0.orig/Documentation/admin-guide/media/saa7134.rst
+++ linux-qcom-6.8.0/Documentation/admin-guide/media/saa7134.rst
@@ -67,7 +67,7 @@
 Please mail to linux-media AT vger.kernel.org unified diffs against
 the linux media git tree:
 
-    https://git.linuxtv.org/media_tree.git/
+    https://git.linuxtv.org/media.git/
 
 This is done by committing a patch at a clone of the git tree and
 submitting the patch using ``git send-email``. Don't forget to
--- linux-qcom-6.8.0.orig/Documentation/admin-guide/mm/damon/usage.rst
+++ linux-qcom-6.8.0/Documentation/admin-guide/mm/damon/usage.rst
@@ -450,7 +450,7 @@
     # # further filter out all cgroups except one at '/having_care_already'
     echo memcg > 1/type
     echo /having_care_already > 1/memcg_path
-    echo N > 1/matching
+    echo Y > 1/matching
 
 Note that ``anon`` and ``memcg`` filters are currently supported only when
 ``paddr`` :ref:`implementation <sysfs_context>` is being used.
--- linux-qcom-6.8.0.orig/Documentation/admin-guide/mm/transhuge.rst
+++ linux-qcom-6.8.0/Documentation/admin-guide/mm/transhuge.rst
@@ -202,12 +202,11 @@
 
 	cat /sys/kernel/mm/transparent_hugepage/hpage_pmd_size
 
-khugepaged will be automatically started when one or more hugepage
-sizes are enabled (either by directly setting "always" or "madvise",
-or by setting "inherit" while the top-level enabled is set to "always"
-or "madvise"), and it'll be automatically shutdown when the last
-hugepage size is disabled (either by directly setting "never", or by
-setting "inherit" while the top-level enabled is set to "never").
+khugepaged will be automatically started when PMD-sized THP is enabled
+(either of the per-size anon control or the top-level control are set
+to "always" or "madvise"), and it'll be automatically shutdown when
+PMD-sized THP is disabled (when both the per-size anon control and the
+top-level control are "never")
 
 Khugepaged controls
 -------------------
--- linux-qcom-6.8.0.orig/Documentation/admin-guide/sysctl/net.rst
+++ linux-qcom-6.8.0/Documentation/admin-guide/sysctl/net.rst
@@ -206,6 +206,11 @@
 
 Default: 0 (off)
 
+mem_pcpu_rsv
+------------
+
+Per-cpu reserved forward alloc cache size in page units. Default 1MB per CPU.
+
 rmem_default
 ------------
 
--- linux-qcom-6.8.0.orig/Documentation/arch/arm64/elf_hwcaps.rst
+++ linux-qcom-6.8.0/Documentation/arch/arm64/elf_hwcaps.rst
@@ -174,22 +174,28 @@
     Functionality implied by ID_AA64ISAR1_EL1.DPB == 0b0010.
 
 HWCAP2_SVE2
-    Functionality implied by ID_AA64ZFR0_EL1.SVEver == 0b0001.
+    Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and
+    ID_AA64ZFR0_EL1.SVEver == 0b0001.
 
 HWCAP2_SVEAES
-    Functionality implied by ID_AA64ZFR0_EL1.AES == 0b0001.
+    Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and
+    ID_AA64ZFR0_EL1.AES == 0b0001.
 
 HWCAP2_SVEPMULL
-    Functionality implied by ID_AA64ZFR0_EL1.AES == 0b0010.
+    Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and
+    ID_AA64ZFR0_EL1.AES == 0b0010.
 
 HWCAP2_SVEBITPERM
-    Functionality implied by ID_AA64ZFR0_EL1.BitPerm == 0b0001.
+    Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and
+    ID_AA64ZFR0_EL1.BitPerm == 0b0001.
 
 HWCAP2_SVESHA3
-    Functionality implied by ID_AA64ZFR0_EL1.SHA3 == 0b0001.
+    Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and
+    ID_AA64ZFR0_EL1.SHA3 == 0b0001.
 
 HWCAP2_SVESM4
-    Functionality implied by ID_AA64ZFR0_EL1.SM4 == 0b0001.
+    Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and
+    ID_AA64ZFR0_EL1.SM4 == 0b0001.
 
 HWCAP2_FLAGM2
     Functionality implied by ID_AA64ISAR0_EL1.TS == 0b0010.
@@ -198,16 +204,20 @@
     Functionality implied by ID_AA64ISAR1_EL1.FRINTTS == 0b0001.
 
 HWCAP2_SVEI8MM
-    Functionality implied by ID_AA64ZFR0_EL1.I8MM == 0b0001.
+    Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and
+    ID_AA64ZFR0_EL1.I8MM == 0b0001.
 
 HWCAP2_SVEF32MM
-    Functionality implied by ID_AA64ZFR0_EL1.F32MM == 0b0001.
+    Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and
+    ID_AA64ZFR0_EL1.F32MM == 0b0001.
 
 HWCAP2_SVEF64MM
-    Functionality implied by ID_AA64ZFR0_EL1.F64MM == 0b0001.
+    Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and
+    ID_AA64ZFR0_EL1.F64MM == 0b0001.
 
 HWCAP2_SVEBF16
-    Functionality implied by ID_AA64ZFR0_EL1.BF16 == 0b0001.
+    Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and
+    ID_AA64ZFR0_EL1.BF16 == 0b0001.
 
 HWCAP2_I8MM
     Functionality implied by ID_AA64ISAR1_EL1.I8MM == 0b0001.
@@ -273,7 +283,8 @@
     Functionality implied by ID_AA64ISAR1_EL1.BF16 == 0b0010.
 
 HWCAP2_SVE_EBF16
-    Functionality implied by ID_AA64ZFR0_EL1.BF16 == 0b0010.
+    Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and
+    ID_AA64ZFR0_EL1.BF16 == 0b0010.
 
 HWCAP2_CSSC
     Functionality implied by ID_AA64ISAR2_EL1.CSSC == 0b0001.
@@ -282,7 +293,8 @@
     Functionality implied by ID_AA64ISAR2_EL1.RPRFM == 0b0001.
 
 HWCAP2_SVE2P1
-    Functionality implied by ID_AA64ZFR0_EL1.SVEver == 0b0010.
+    Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and
+    ID_AA64ZFR0_EL1.SVEver == 0b0010.
 
 HWCAP2_SME2
     Functionality implied by ID_AA64SMFR0_EL1.SMEver == 0b0001.
@@ -309,7 +321,8 @@
     Functionality implied by ID_AA64ISAR2_EL1.BC == 0b0001.
 
 HWCAP2_SVE_B16B16
-    Functionality implied by ID_AA64ZFR0_EL1.B16B16 == 0b0001.
+    Functionality implied by ID_AA64PFR0_EL1.SVE == 0b0001 and
+    ID_AA64ZFR0_EL1.B16B16 == 0b0001.
 
 HWCAP2_LRCPC3
     Functionality implied by ID_AA64ISAR1_EL1.LRCPC == 0b0011.
--- linux-qcom-6.8.0.orig/Documentation/arch/arm64/silicon-errata.rst
+++ linux-qcom-6.8.0/Documentation/arch/arm64/silicon-errata.rst
@@ -54,6 +54,8 @@
 +----------------+-----------------+-----------------+-----------------------------+
 | Ampere         | AmpereOne       | AC03_CPU_38     | AMPERE_ERRATUM_AC03_CPU_38  |
 +----------------+-----------------+-----------------+-----------------------------+
+| Ampere         | AmpereOne AC04  | AC04_CPU_10     | AMPERE_ERRATUM_AC03_CPU_38  |
++----------------+-----------------+-----------------+-----------------------------+
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A510     | #2457168        | ARM64_ERRATUM_2457168       |
 +----------------+-----------------+-----------------+-----------------------------+
@@ -123,22 +125,50 @@
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A77      | #1491015        | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A76      | #3324349        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A77      | #1508412        | ARM64_ERRATUM_1508412       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A77      | #3324348        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A78      | #3324344        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A78C     | #3324346,3324347| ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #2119858        | ARM64_ERRATUM_2119858       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #2054223        | ARM64_ERRATUM_2054223       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A710     | #2224489        | ARM64_ERRATUM_2224489       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A710     | #3324338        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A715     | #2645198        | ARM64_ERRATUM_2645198       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X1       | #1502854        | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A715     | #3456084        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A720     | #3456091        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A725     | #3456106        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X1       | #3324344        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X1C      | #3324346        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X2       | #2119858        | ARM64_ERRATUM_2119858       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-X2       | #2224489        | ARM64_ERRATUM_2224489       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X2       | #3324338        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X3       | #3324335        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X4       | #3194386        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-X925     | #3324334        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N1     | #1188873,1418040| ARM64_ERRATUM_1418040       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N1     | #1349291        | N/A                         |
@@ -147,6 +177,8 @@
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N1     | #1542419        | ARM64_ERRATUM_1542419       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-N1     | #3324349        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N2     | #2139208        | ARM64_ERRATUM_2139208       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-N2     | #2067961        | ARM64_ERRATUM_2067961       |
@@ -155,6 +187,16 @@
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-V1     | #1619801        | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-N2     | #3324339        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-N3     | #3456111        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-V1     | #3324341        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-V2     | #3324336        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Neoverse-V3     | #3312417        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | MMU-500         | #841119,826419  | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | MMU-600         | #1076982,1209401| N/A                         |
@@ -212,8 +254,11 @@
 +----------------+-----------------+-----------------+-----------------------------+
 | Hisilicon      | Hip08 SMMU PMCG | #162001800      | N/A                         |
 +----------------+-----------------+-----------------+-----------------------------+
-| Hisilicon      | Hip08 SMMU PMCG | #162001900      | N/A                         |
-|                | Hip09 SMMU PMCG |                 |                             |
+| Hisilicon      | Hip{08,09,09A,10| #162001900      | N/A                         |
+|                | ,10C,11}        |                 |                             |
+|                | SMMU PMCG       |                 |                             |
++----------------+-----------------+-----------------+-----------------------------+
+| Hisilicon      | Hip09           | #162100801      | HISILICON_ERRATUM_162100801 |
 +----------------+-----------------+-----------------+-----------------------------+
 +----------------+-----------------+-----------------+-----------------------------+
 | Qualcomm Tech. | Kryo/Falkor v1  | E1003           | QCOM_FALKOR_ERRATUM_1003    |
@@ -250,3 +295,5 @@
 +----------------+-----------------+-----------------+-----------------------------+
 | Microsoft      | Azure Cobalt 100| #2253138        | ARM64_ERRATUM_2253138       |
 +----------------+-----------------+-----------------+-----------------------------+
+| Microsoft      | Azure Cobalt 100| #3324339        | ARM64_ERRATUM_3194386       |
++----------------+-----------------+-----------------+-----------------------------+
--- linux-qcom-6.8.0.orig/Documentation/arch/powerpc/kvm-nested.rst
+++ linux-qcom-6.8.0/Documentation/arch/powerpc/kvm-nested.rst
@@ -546,7 +546,9 @@
 +--------+-------+----+--------+----------------------------------+
 | 0x1052 | 0x08  | RW |   T    | CTRL                             |
 +--------+-------+----+--------+----------------------------------+
-| 0x1053-|       |    |        | Reserved                         |
+| 0x1053 | 0x08  | RW |   T    | DPDES                            |
++--------+-------+----+--------+----------------------------------+
+| 0x1054-|       |    |        | Reserved                         |
 | 0x1FFF |       |    |        |                                  |
 +--------+-------+----+--------+----------------------------------+
 | 0x2000 | 0x04  | RW |   T    | CR                               |
--- linux-qcom-6.8.0.orig/Documentation/arch/x86/amd-memory-encryption.rst
+++ linux-qcom-6.8.0/Documentation/arch/x86/amd-memory-encryption.rst
@@ -87,14 +87,14 @@
 	  kernel is non-zero).
 
 SME can also be enabled and activated in the BIOS. If SME is enabled and
-activated in the BIOS, then all memory accesses will be encrypted and it will
-not be necessary to activate the Linux memory encryption support.  If the BIOS
-merely enables SME (sets bit 23 of the MSR_AMD64_SYSCFG), then Linux can activate
-memory encryption by default (CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT=y) or
-by supplying mem_encrypt=on on the kernel command line.  However, if BIOS does
-not enable SME, then Linux will not be able to activate memory encryption, even
-if configured to do so by default or the mem_encrypt=on command line parameter
-is specified.
+activated in the BIOS, then all memory accesses will be encrypted and it
+will not be necessary to activate the Linux memory encryption support.
+
+If the BIOS merely enables SME (sets bit 23 of the MSR_AMD64_SYSCFG),
+then memory encryption can be enabled by supplying mem_encrypt=on on the
+kernel command line.  However, if BIOS does not enable SME, then Linux
+will not be able to activate memory encryption, even if configured to do
+so by default or the mem_encrypt=on command line parameter is specified.
 
 Secure Nested Paging (SNP)
 ==========================
--- linux-qcom-6.8.0.orig/Documentation/arch/x86/boot.rst
+++ linux-qcom-6.8.0/Documentation/arch/x86/boot.rst
@@ -895,10 +895,19 @@
 
   The kernel runtime start address is determined by the following algorithm::
 
-	if (relocatable_kernel)
-	runtime_start = align_up(load_address, kernel_alignment)
-	else
-	runtime_start = pref_address
+   	if (relocatable_kernel) {
+   		if (load_address < pref_address)
+   			load_address = pref_address;
+   		runtime_start = align_up(load_address, kernel_alignment);
+   	} else {
+   		runtime_start = pref_address;
+   	}
+
+Hence the necessary memory window location and size can be estimated by
+a boot loader as::
+
+   	memory_window_start = runtime_start;
+   	memory_window_size = init_size;
 
 ============	===============
 Field name:	handover_offset
--- linux-qcom-6.8.0.orig/Documentation/block/inline-encryption.rst
+++ linux-qcom-6.8.0/Documentation/block/inline-encryption.rst
@@ -77,10 +77,10 @@
 ============
 
 We introduce ``struct blk_crypto_key`` to represent an inline encryption key and
-how it will be used.  This includes the actual bytes of the key; the size of the
-key; the algorithm and data unit size the key will be used with; and the number
-of bytes needed to represent the maximum data unit number the key will be used
-with.
+how it will be used.  This includes the type of the key (standard or
+hardware-wrapped); the actual bytes of the key; the size of the key; the
+algorithm and data unit size the key will be used with; and the number of bytes
+needed to represent the maximum data unit number the key will be used with.
 
 We introduce ``struct bio_crypt_ctx`` to represent an encryption context.  It
 contains a data unit number and a pointer to a blk_crypto_key.  We add pointers
@@ -301,3 +301,240 @@
 When the crypto API fallback is enabled, this means that all bios with and
 encryption context will use the fallback, and IO will complete as usual.  When
 the fallback is disabled, a bio with an encryption context will be failed.
+
+.. _hardware_wrapped_keys:
+
+Hardware-wrapped keys
+=====================
+
+Motivation and threat model
+---------------------------
+
+Linux storage encryption (dm-crypt, fscrypt, eCryptfs, etc.) traditionally
+relies on the raw encryption key(s) being present in kernel memory so that the
+encryption can be performed.  This traditionally isn't seen as a problem because
+the key(s) won't be present during an offline attack, which is the main type of
+attack that storage encryption is intended to protect from.
+
+However, there is an increasing desire to also protect users' data from other
+types of attacks (to the extent possible), including:
+
+- Cold boot attacks, where an attacker with physical access to a system suddenly
+  powers it off, then immediately dumps the system memory to extract recently
+  in-use encryption keys, then uses these keys to decrypt user data on-disk.
+
+- Online attacks where the attacker is able to read kernel memory without fully
+  compromising the system, followed by an offline attack where any extracted
+  keys can be used to decrypt user data on-disk.  An example of such an online
+  attack would be if the attacker is able to run some code on the system that
+  exploits a Meltdown-like vulnerability but is unable to escalate privileges.
+
+- Online attacks where the attacker fully compromises the system, but their data
+  exfiltration is significantly time-limited and/or bandwidth-limited, so in
+  order to completely exfiltrate the data they need to extract the encryption
+  keys to use in a later offline attack.
+
+Hardware-wrapped keys are a feature of inline encryption hardware that is
+designed to protect users' data from the above attacks (to the extent possible),
+without introducing limitations such as a maximum number of keys.
+
+Note that it is impossible to **fully** protect users' data from these attacks.
+Even in the attacks where the attacker "just" gets read access to kernel memory,
+they can still extract any user data that is present in memory, including
+plaintext pagecache pages of encrypted files.  The focus here is just on
+protecting the encryption keys, as those instantly give access to **all** user
+data in any following offline attack, rather than just some of it (where which
+data is included in that "some" might not be controlled by the attacker).
+
+Solution overview
+-----------------
+
+Inline encryption hardware typically has "keyslots" into which software can
+program keys for the hardware to use; the contents of keyslots typically can't
+be read back by software.  As such, the above security goals could be achieved
+if the kernel simply erased its copy of the key(s) after programming them into
+keyslot(s) and thereafter only referred to them via keyslot number.
+
+However, that naive approach runs into the problem that it limits the number of
+unlocked keys to the number of keyslots, which typically is a small number.  In
+cases where there is only one encryption key system-wide (e.g., a full-disk
+encryption key), that can be tolerable.  However, in general there can be many
+logged-in users with many different keys, and/or many running applications with
+application-specific encrypted storage areas.  This is especially true if
+file-based encryption (e.g. fscrypt) is being used.
+
+Thus, it is important for the kernel to still have a way to "remind" the
+hardware about a key, without actually having the raw key itself.  This would
+ensure that the number of hardware keyslots only limits the number of active I/O
+requests, not other things such as the number of logged-in users, the number of
+running apps, or the number of encrypted storage areas that apps can create.
+
+Somewhat less importantly, it is also desirable that the raw keys are never
+visible to software at all, even while being initially unlocked.  This would
+ensure that a read-only compromise of system memory will never allow a key to be
+extracted to be used off-system, even if it occurs when a key is being unlocked.
+
+To solve all these problems, some vendors of inline encryption hardware have
+made their hardware support *hardware-wrapped keys*.  Hardware-wrapped keys
+are encrypted keys that can only be unwrapped (decrypted) and used by hardware
+-- either by the inline encryption hardware itself, or by a dedicated hardware
+block that can directly provision keys to the inline encryption hardware.
+
+(We refer to them as "hardware-wrapped keys" rather than simply "wrapped keys"
+to add some clarity in cases where there could be other types of wrapped keys,
+such as in file-based encryption.  Key wrapping is a commonly used technique.)
+
+The key which wraps (encrypts) hardware-wrapped keys is a hardware-internal key
+that is never exposed to software; it is either a persistent key (a "long-term
+wrapping key") or a per-boot key (an "ephemeral wrapping key").  The long-term
+wrapped form of the key is what is initially unlocked, but it is erased from
+memory as soon as it is converted into an ephemerally-wrapped key.  In-use
+hardware-wrapped keys are always ephemerally-wrapped, not long-term wrapped.
+
+As inline encryption hardware can only be used to encrypt/decrypt data on-disk,
+the hardware also includes a level of indirection; it doesn't use the unwrapped
+key directly for inline encryption, but rather derives both an inline encryption
+key and a "software secret" from it.  Software can use the "software secret" for
+tasks that can't use the inline encryption hardware, such as filenames
+encryption.  The software secret is not protected from memory compromise.
+
+Key hierarchy
+-------------
+
+Here is the key hierarchy for a hardware-wrapped key::
+
+                       Hardware-wrapped key
+                                |
+                                |
+                          <Hardware KDF>
+                                |
+                  -----------------------------
+                  |                           |
+        Inline encryption key           Software secret
+
+The components are:
+
+- *Hardware-wrapped key*: a key for the hardware's KDF (Key Derivation
+  Function), in ephemerally-wrapped form.  The key wrapping algorithm is a
+  hardware implementation detail that doesn't impact kernel operation, but a
+  strong authenticated encryption algorithm such as AES-256-GCM is recommended.
+
+- *Hardware KDF*: a KDF (Key Derivation Function) which the hardware uses to
+  derive subkeys after unwrapping the wrapped key.  The hardware's choice of KDF
+  doesn't impact kernel operation, but it does need to be known for testing
+  purposes, and it's also assumed to have at least a 256-bit security strength.
+  All known hardware uses the SP800-108 KDF in Counter Mode with AES-256-CMAC,
+  with a particular choice of labels and contexts; new hardware should use this
+  already-vetted KDF.
+
+- *Inline encryption key*: a derived key which the hardware directly provisions
+  to a keyslot of the inline encryption hardware, without exposing it to
+  software.  In all known hardware, this will always be an AES-256-XTS key.
+  However, in principle other encryption algorithms could be supported too.
+  Hardware must derive distinct subkeys for each supported encryption algorithm.
+
+- *Software secret*: a derived key which the hardware returns to software so
+  that software can use it for cryptographic tasks that can't use inline
+  encryption.  This value is cryptographically isolated from the inline
+  encryption key, i.e. knowing one doesn't reveal the other.  (The KDF ensures
+  this.)  Currently, the software secret is always 32 bytes and thus is suitable
+  for cryptographic applications that require up to a 256-bit security strength.
+  Some use cases (e.g. full-disk encryption) won't require the software secret.
+
+Example: in the case of fscrypt, the fscrypt master key (the key that protects a
+particular set of encrypted directories) is made hardware-wrapped.  The inline
+encryption key is used as the file contents encryption key, while the software
+secret (rather than the master key directly) is used to key fscrypt's KDF
+(HKDF-SHA512) to derive other subkeys such as filenames encryption keys.
+
+Note that currently this design assumes a single inline encryption key per
+hardware-wrapped key, without any further key derivation.  Thus, in the case of
+fscrypt, currently hardware-wrapped keys are only compatible with the "inline
+encryption optimized" settings, which use one file contents encryption key per
+encryption policy rather than one per file.  This design could be extended to
+make the hardware derive per-file keys using per-file nonces passed down the
+storage stack, and in fact some hardware already supports this; future work is
+planned to remove this limitation by adding the corresponding kernel support.
+
+Kernel support
+--------------
+
+The inline encryption support of the kernel's block layer ("blk-crypto") has
+been extended to support hardware-wrapped keys as an alternative to standard
+keys, when hardware support is available.  This works in the following way:
+
+- A ``key_types_supported`` field is added to the crypto capabilities in
+  ``struct blk_crypto_profile``.  This allows device drivers to declare that
+  they support standard keys, hardware-wrapped keys, or both.
+
+- ``struct blk_crypto_key`` can now contain a hardware-wrapped key as an
+  alternative to a standard key; a ``key_type`` field is added to
+  ``struct blk_crypto_config`` to distinguish between the different key types.
+  This allows users of blk-crypto to en/decrypt data using a hardware-wrapped
+  key in a way very similar to using a standard key.
+
+- A new method ``blk_crypto_ll_ops::derive_sw_secret`` is added.  Device drivers
+  that support hardware-wrapped keys must implement this method.  Users of
+  blk-crypto can call ``blk_crypto_derive_sw_secret()`` to access this method.
+
+- The programming and eviction of hardware-wrapped keys happens via
+  ``blk_crypto_ll_ops::keyslot_program`` and
+  ``blk_crypto_ll_ops::keyslot_evict``, just like it does for standard keys.  If
+  a driver supports hardware-wrapped keys, then it must handle hardware-wrapped
+  keys being passed to these methods.
+
+blk-crypto-fallback doesn't support hardware-wrapped keys.  Therefore,
+hardware-wrapped keys can only be used with actual inline encryption hardware.
+
+All the above deals with hardware-wrapped keys in ephemerally-wrapped form only.
+To get such keys in the first place, new block device ioctls have been added to
+provide a generic interface to creating and preparing such keys:
+
+- ``BLKCRYPTOIMPORTKEY`` converts a raw key to long-term wrapped form.  It takes
+  in a pointer to a ``struct blk_crypto_import_key_arg``.  The caller must set
+  ``raw_key_ptr`` and ``raw_key_size`` to the pointer and size (in bytes) of the
+  raw key to import.  On success, ``BLKCRYPTOIMPORTKEY`` returns 0 and writes
+  the resulting long-term wrapped key blob to the buffer pointed to by
+  ``lt_key_ptr``, which is of maximum size ``lt_key_size``.  It also updates
+  ``lt_key_size`` to be the actual size of the key.  On failure, it returns -1
+  and sets errno.
+
+- ``BLKCRYPTOGENERATEKEY`` is like ``BLKCRYPTOIMPORTKEY``, but it has the
+  hardware generate the key instead of importing one.  It takes in a pointer to
+  a ``struct blk_crypto_generate_key_arg``.
+
+- ``BLKCRYPTOPREPAREKEY`` converts a key from long-term wrapped form to
+  ephemerally-wrapped form.  It takes in a pointer to a ``struct
+  blk_crypto_prepare_key_arg``.  The caller must set ``lt_key_ptr`` and
+  ``lt_key_size`` to the pointer and size (in bytes) of the long-term wrapped
+  key blob to convert.  On success, ``BLKCRYPTOPREPAREKEY`` returns 0 and writes
+  the resulting ephemerally-wrapped key blob to the buffer pointed to by
+  ``eph_key_ptr``, which is of maximum size ``eph_key_size``.  It also updates
+  ``eph_key_size`` to be the actual size of the key.  On failure, it returns -1
+  and sets errno.
+
+Userspace needs to use either ``BLKCRYPTOIMPORTKEY`` or ``BLKCRYPTOGENERATEKEY``
+once to create a key, and then ``BLKCRYPTOPREPAREKEY`` each time the key is
+unlocked and added to the kernel.  Note that these ioctls have no relevance for
+standard keys; they are only for hardware-wrapped keys.
+
+Testability
+-----------
+
+Both the hardware KDF and the inline encryption itself are well-defined
+algorithms that don't depend on any secrets other than the unwrapped key.
+Therefore, if the unwrapped key is known to software, these algorithms can be
+reproduced in software in order to verify the ciphertext that is written to disk
+by the inline encryption hardware.
+
+However, the unwrapped key will only be known to software for testing if the
+"import" functionality is used.  Proper testing is not possible in the
+"generate" case where the hardware generates the key itself.  The correct
+operation of the "generate" mode thus relies on the security and correctness of
+the hardware RNG and its use to generate the key, as well as the testing of the
+"import" mode as that should cover all parts other than the key generation.
+
+For an example of a test that verifies the ciphertext written to disk in the
+"import" mode, see the fscrypt hardware-wrapped key tests in xfstests, or
+`Android's vts_kernel_encryption_test
+<https://android.googlesource.com/platform/test/vts-testcase/kernel/+/refs/heads/master/encryption/>`_.
--- linux-qcom-6.8.0.orig/Documentation/bpf/map_lpm_trie.rst
+++ linux-qcom-6.8.0/Documentation/bpf/map_lpm_trie.rst
@@ -17,7 +17,7 @@
 
 LPM tries may be created with a maximum prefix length that is a multiple
 of 8, in the range from 8 to 2048. The key used for lookup and update
-operations is a ``struct bpf_lpm_trie_key``, extended by
+operations is a ``struct bpf_lpm_trie_key_u8``, extended by
 ``max_prefixlen/8`` bytes.
 
 - For IPv4 addresses the data length is 4 bytes
--- linux-qcom-6.8.0.orig/Documentation/cdrom/cdrom-standard.rst
+++ linux-qcom-6.8.0/Documentation/cdrom/cdrom-standard.rst
@@ -217,7 +217,7 @@
 		int (*media_changed)(struct cdrom_device_info *, int);
 		int (*tray_move)(struct cdrom_device_info *, int);
 		int (*lock_door)(struct cdrom_device_info *, int);
-		int (*select_speed)(struct cdrom_device_info *, int);
+		int (*select_speed)(struct cdrom_device_info *, unsigned long);
 		int (*get_last_session) (struct cdrom_device_info *,
 					 struct cdrom_multisession *);
 		int (*get_mcn)(struct cdrom_device_info *, struct cdrom_mcn *);
@@ -396,7 +396,7 @@
 
 ::
 
-	int select_speed(struct cdrom_device_info *cdi, int speed)
+	int select_speed(struct cdrom_device_info *cdi, unsigned long speed)
 
 Some CD-ROM drives are capable of changing their head-speed. There
 are several reasons for changing the speed of a CD-ROM drive. Badly
--- linux-qcom-6.8.0.orig/Documentation/cgroups/namespace.txt
+++ linux-qcom-6.8.0/Documentation/cgroups/namespace.txt
@@ -0,0 +1,142 @@
+			CGroup Namespaces
+
+CGroup Namespace provides a mechanism to virtualize the view of the
+/proc/<pid>/cgroup file. The CLONE_NEWCGROUP clone-flag can be used with
+clone() and unshare() syscalls to create a new cgroup namespace.
+The process running inside the cgroup namespace will have its /proc/<pid>/cgroup
+output restricted to cgroupns-root. cgroupns-root is the cgroup of the process
+at the time of creation of the cgroup namespace.
+
+Prior to CGroup Namespace, the /proc/<pid>/cgroup file used to show complete
+path of the cgroup of a process. In a container setup (where a set of cgroups
+and namespaces are intended to isolate processes), the /proc/<pid>/cgroup file
+may leak potential system level information to the isolated processes.
+
+For Example:
+  $ cat /proc/self/cgroup
+  0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1
+
+The path '/batchjobs/container_id1' can generally be considered as system-data
+and its desirable to not expose it to the isolated process.
+
+CGroup Namespaces can be used to restrict visibility of this path.
+For Example:
+  # Before creating cgroup namespace
+  $ ls -l /proc/self/ns/cgroup
+  lrwxrwxrwx 1 root root 0 2014-07-15 10:37 /proc/self/ns/cgroup -> cgroup:[4026531835]
+  $ cat /proc/self/cgroup
+  0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1
+
+  # unshare(CLONE_NEWCGROUP) and exec /bin/bash
+  $ ~/unshare -c
+  [ns]$ ls -l /proc/self/ns/cgroup
+  lrwxrwxrwx 1 root root 0 2014-07-15 10:35 /proc/self/ns/cgroup -> cgroup:[4026532183]
+  # From within new cgroupns, process sees that its in the root cgroup
+  [ns]$ cat /proc/self/cgroup
+  0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/
+
+  # From global cgroupns:
+  $ cat /proc/<pid>/cgroup
+  0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1
+
+  # Unshare cgroupns along with userns and mountns
+  # Following calls unshare(CLONE_NEWCGROUP|CLONE_NEWUSER|CLONE_NEWNS), then
+  # sets up uid/gid map and execs /bin/bash
+  $ ~/unshare -c -u -m
+  # Originally, we were in /batchjobs/container_id1 cgroup. Mount our own cgroup
+  # hierarchy.
+  [ns]$ mount -t cgroup cgroup /tmp/cgroup
+  [ns]$ ls -l /tmp/cgroup
+  total 0
+  -r--r--r-- 1 root root 0 2014-10-13 09:32 cgroup.controllers
+  -r--r--r-- 1 root root 0 2014-10-13 09:32 cgroup.populated
+  -rw-r--r-- 1 root root 0 2014-10-13 09:25 cgroup.procs
+  -rw-r--r-- 1 root root 0 2014-10-13 09:32 cgroup.subtree_control
+
+The cgroupns-root (/batchjobs/container_id1 in above example) becomes the
+filesystem root for the namespace specific cgroupfs mount.
+
+The virtualization of /proc/self/cgroup file combined with restricting
+the view of cgroup hierarchy by namespace-private cgroupfs mount
+should provide a completely isolated cgroup view inside the container.
+
+In its current form, the cgroup namespaces patcheset provides following
+behavior:
+
+(1) The 'cgroupns-root' for a cgroup namespace is the cgroup in which
+    the process calling unshare is running.
+    For ex. if a process in /batchjobs/container_id1 cgroup calls unshare,
+    cgroup /batchjobs/container_id1 becomes the cgroupns-root.
+    For the init_cgroup_ns, this is the real root ('/') cgroup
+    (identified in code as cgrp_dfl_root.cgrp).
+
+(2) The cgroupns-root cgroup does not change even if the namespace
+    creator process later moves to a different cgroup.
+    $ ~/unshare -c # unshare cgroupns in some cgroup
+    [ns]$ cat /proc/self/cgroup
+    0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/
+    [ns]$ mkdir sub_cgrp_1
+    [ns]$ echo 0 > sub_cgrp_1/cgroup.procs
+    [ns]$ cat /proc/self/cgroup
+    0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/sub_cgrp_1
+
+(3) Each process gets its CGROUPNS specific view of /proc/<pid>/cgroup
+(a) Processes running inside the cgroup namespace will be able to see
+    cgroup paths (in /proc/self/cgroup) only inside their root cgroup
+    [ns]$ sleep 100000 &  # From within unshared cgroupns
+    [1] 7353
+    [ns]$ echo 7353 > sub_cgrp_1/cgroup.procs
+    [ns]$ cat /proc/7353/cgroup
+    0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/sub_cgrp_1
+
+(b) From global cgroupns, the real cgroup path will be visible:
+    $ cat /proc/7353/cgroup
+    0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/batchjobs/container_id1/sub_cgrp_1
+
+(c) From a sibling cgroupns (cgroupns root-ed at a different cgroup), cgroup
+    path relative to its own cgroupns-root will be shown:
+    # ns2's cgroupns-root is at '/batchjobs/container_id2'
+    [ns2]$ cat /proc/7353/cgroup
+    0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/../container_id2/sub_cgrp_1
+
+    Note that the relative path always starts with '/' to indicate that its
+    relative to the cgroupns-root of the caller.
+
+(4) Processes inside a cgroupns can move in-and-out of the cgroupns-root
+    (if they have proper access to external cgroups).
+    # From inside cgroupns (with cgroupns-root at /batchjobs/container_id1), and
+    # assuming that the global hierarchy is still accessible inside cgroupns:
+    $ cat /proc/7353/cgroup
+    0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/sub_cgrp_1
+    $ echo 7353 > batchjobs/container_id2/cgroup.procs
+    $ cat /proc/7353/cgroup
+    0:cpuset,cpu,cpuacct,memory,devices,freezer,hugetlb:/../container_id2
+
+    Note that this kind of setup is not encouraged. A task inside cgroupns
+    should only be exposed to its own cgroupns hierarchy. Otherwise it makes
+    the virtualization of /proc/<pid>/cgroup less useful.
+
+(5) Setns to another cgroup namespace is allowed when:
+    (a) the process has CAP_SYS_ADMIN in its current userns
+    (b) the process has CAP_SYS_ADMIN in the target cgroupns' userns
+    No implicit cgroup changes happen with attaching to another cgroupns. It
+    is expected that the somone moves the attaching process under the target
+    cgroupns-root.
+
+(6) When some thread from a multi-threaded process unshares its
+    cgroup-namespace, the new cgroupns gets applied to the entire process (all
+    the threads). For the unified-hierarchy this is expected as it only allows
+    process-level containerization.  For the legacy hierarchies this may be
+    unexpected.  So all the threads in the process will have the same cgroup.
+
+(7) The cgroup namespace is alive as long as there is atleast 1
+    process inside it. When the last process exits, the cgroup
+    namespace is destroyed. The cgroupns-root and the actual cgroups
+    remain though.
+
+(8) Namespace specific cgroup hierarchy can be mounted by a process running
+    inside cgroupns:
+    $ mount -t cgroup -o __DEVEL__sane_behavior cgroup $MOUNT_POINT
+
+    This will mount the unified cgroup hierarchy with cgroupns-root as the
+    filesystem root. The process needs CAP_SYS_ADMIN in its userns and mntns.
--- linux-qcom-6.8.0.orig/Documentation/conf.py
+++ linux-qcom-6.8.0/Documentation/conf.py
@@ -75,6 +75,8 @@
             "__rcu",
             "__user",
             "__force",
+            "__counted_by_le",
+            "__counted_by_be",
 
             # include/linux/compiler_attributes.h:
             "__alias",
@@ -346,9 +348,9 @@
 html_static_path = ['sphinx-static']
 
 # If true, Docutils "smart quotes" will be used to convert quotes and dashes
-# to typographically correct entities.  This will convert "--" to "—",
-# which is not always what we want, so disable it.
-smartquotes = False
+# to typographically correct entities.  However, conversion of "--" to "—"
+# is not always what we want, so enable only quotes.
+smartquotes_action = 'q'
 
 # Custom sidebar templates, maps document names to template names.
 # Note that the RTD theme ignores this
--- linux-qcom-6.8.0.orig/Documentation/dev-tools/kselftest.rst
+++ linux-qcom-6.8.0/Documentation/dev-tools/kselftest.rst
@@ -255,9 +255,21 @@
 
    TEST_PROGS_EXTENDED, TEST_GEN_PROGS_EXTENDED mean it is the
    executable which is not tested by default.
+
    TEST_FILES, TEST_GEN_FILES mean it is the file which is used by
    test.
 
+   TEST_INCLUDES is similar to TEST_FILES, it lists files which should be
+   included when exporting or installing the tests, with the following
+   differences:
+
+    * symlinks to files in other directories are preserved
+    * the part of paths below tools/testing/selftests/ is preserved when
+      copying the files to the output directory
+
+   TEST_INCLUDES is meant to list dependencies located in other directories of
+   the selftests hierarchy.
+
  * First use the headers inside the kernel source and/or git repo, and then the
    system headers.  Headers for the kernel release as opposed to headers
    installed by the distro on the system should be the primary focus to be able
--- linux-qcom-6.8.0.orig/Documentation/dev-tools/ubsan.rst
+++ linux-qcom-6.8.0/Documentation/dev-tools/ubsan.rst
@@ -49,34 +49,22 @@
 Usage
 -----
 
-To enable UBSAN configure kernel with::
+To enable UBSAN, configure the kernel with::
 
-	CONFIG_UBSAN=y
+  CONFIG_UBSAN=y
 
-and to check the entire kernel::
-
-        CONFIG_UBSAN_SANITIZE_ALL=y
-
-To enable instrumentation for specific files or directories, add a line
-similar to the following to the respective kernel Makefile:
-
-- For a single file (e.g. main.o)::
-
-    UBSAN_SANITIZE_main.o := y
-
-- For all files in one directory::
-
-    UBSAN_SANITIZE := y
-
-To exclude files from being instrumented even if
-``CONFIG_UBSAN_SANITIZE_ALL=y``, use::
+To exclude files from being instrumented use::
 
   UBSAN_SANITIZE_main.o := n
 
-and::
+and to exclude all targets in one directory use::
 
   UBSAN_SANITIZE := n
 
+When disabled for all targets, specific files can be enabled using::
+
+  UBSAN_SANITIZE_main.o := y
+
 Detection of unaligned accesses controlled through the separate option -
 CONFIG_UBSAN_ALIGNMENT. It's off by default on architectures that support
 unaligned accesses (CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y). One could
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/cache/qcom,llcc.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/cache/qcom,llcc.yaml
@@ -38,11 +38,11 @@
 
   reg:
     minItems: 2
-    maxItems: 9
+    maxItems: 10
 
   reg-names:
     minItems: 2
-    maxItems: 9
+    maxItems: 10
 
   interrupts:
     maxItems: 1
@@ -66,7 +66,6 @@
         compatible:
           contains:
             enum:
-              - qcom,qdu1000-llcc
               - qcom,sc7180-llcc
               - qcom,sm6350-llcc
     then:
@@ -104,8 +103,39 @@
         compatible:
           contains:
             enum:
+              - qcom,qdu1000-llcc
               - qcom,sc8180x-llcc
               - qcom,sc8280xp-llcc
+    then:
+      properties:
+        reg:
+          items:
+            - description: LLCC0 base register region
+            - description: LLCC1 base register region
+            - description: LLCC2 base register region
+            - description: LLCC3 base register region
+            - description: LLCC4 base register region
+            - description: LLCC5 base register region
+            - description: LLCC6 base register region
+            - description: LLCC7 base register region
+            - description: LLCC broadcast base register region
+        reg-names:
+          items:
+            - const: llcc0_base
+            - const: llcc1_base
+            - const: llcc2_base
+            - const: llcc3_base
+            - const: llcc4_base
+            - const: llcc5_base
+            - const: llcc6_base
+            - const: llcc7_base
+            - const: llcc_broadcast_base
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
               - qcom,x1e80100-llcc
     then:
       properties:
@@ -120,6 +150,7 @@
             - description: LLCC6 base register region
             - description: LLCC7 base register region
             - description: LLCC broadcast base register region
+            - description: LLCC broadcast AND register region
         reg-names:
           items:
             - const: llcc0_base
@@ -131,6 +162,7 @@
             - const: llcc6_base
             - const: llcc7_base
             - const: llcc_broadcast_base
+            - const: llcc_broadcast_and_base
 
   - if:
       properties:
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/clock/adi,axi-clkgen.yaml
@@ -26,9 +26,21 @@
     description:
       Specifies the reference clock(s) from which the output frequency is
       derived. This must either reference one clock if only the first clock
-      input is connected or two if both clock inputs are connected.
-    minItems: 1
-    maxItems: 2
+      input is connected or two if both clock inputs are connected. The last
+      clock is the AXI bus clock that needs to be enabled so we can access the
+      core registers.
+    minItems: 2
+    maxItems: 3
+
+  clock-names:
+    oneOf:
+      - items:
+          - const: clkin1
+          - const: s_axi_aclk
+      - items:
+          - const: clkin1
+          - const: clkin2
+          - const: s_axi_aclk
 
   '#clock-cells':
     const: 0
@@ -40,6 +52,7 @@
   - compatible
   - reg
   - clocks
+  - clock-names
   - '#clock-cells'
 
 additionalProperties: false
@@ -50,5 +63,6 @@
       compatible = "adi,axi-clkgen-2.00.a";
       #clock-cells = <0>;
       reg = <0xff000000 0x1000>;
-      clocks = <&osc 1>;
+      clocks = <&osc 1>, <&clkc 15>;
+      clock-names = "clkin1", "s_axi_aclk";
     };
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/clock/imx93-clock.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/clock/imx93-clock.yaml
@@ -16,6 +16,7 @@
 properties:
   compatible:
     enum:
+      - fsl,imx91-ccm
       - fsl,imx93-ccm
 
   reg:
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml
@@ -27,6 +27,7 @@
 properties:
   compatible:
     enum:
+      - qcom,qcs8300-gpucc
       - qcom,sdm845-gpucc
       - qcom,sa8775p-gpucc
       - qcom,sc7180-gpucc
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/clock/qcom,qcs615-camcc.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/clock/qcom,qcs615-camcc.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,qcs615-camcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Camera Clock & Reset Controller on QCS615
+
+maintainers:
+  - Taniya Das <quic_tdas@quicinc.com>
+
+description: |
+  Qualcomm camera clock control module provides the clocks, resets and power
+  domains on QCS615
+
+  See also: include/dt-bindings/clock/qcom,qcs615-camcc.h
+
+properties:
+  compatible:
+    const: qcom,qcs615-camcc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Board XO source
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    clock-controller@ad00000 {
+      compatible = "qcom,qcs615-camcc";
+      reg = <0xad00000 0x10000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>;
+
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/clock/qcom,qcs615-dispcc.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/clock/qcom,qcs615-dispcc.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,qcs615-dispcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Display Clock & Reset Controller on QCS615
+
+maintainers:
+  - Ajit Pandey <quic_ajipan@quicinc.com>
+  - Taniya Das <quic_tdas@quicinc.com>
+
+description: |
+  Qualcomm display clock control module provides the clocks, resets and power
+  domains on QCS615
+
+  See also: include/dt-bindings/clock/qcom,qcs615-dispcc.h
+
+properties:
+  compatible:
+    const: qcom,qcs615-dispcc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: GPLL0 clock source from GCC
+      - description: Byte clock from DSI PHY0
+      - description: Pixel clock from DSI PHY0
+      - description: Pixel clock from DSI PHY1
+      - description: Display port PLL link clock
+      - description: Display port PLL VCO DIV clock
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    clock-controller@af00000 {
+      compatible = "qcom,qcs615-dispcc";
+      reg = <0x0af00000 0x20000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&gcc GCC_DISP_GPLL0_DIV_CLK_SRC>,
+               <&mdss_dsi0_phy 0>,
+               <&mdss_dsi0_phy 1>,
+               <&mdss_dsi1_phy 0>,
+               <&mdss_dp_phy   0>,
+               <&mdss_dp_vco   0>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/clock/qcom,qcs615-gcc.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/clock/qcom,qcs615-gcc.yaml
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,qcs615-gcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller on QCS615
+
+maintainers:
+  - Taniya Das <quic_tdas@quicinc.com>
+
+description: |
+  Qualcomm global clock control module provides the clocks, resets and power
+  domains on QCS615.
+
+  See also: include/dt-bindings/clock/qcom,qcs615-gcc.h
+
+properties:
+  compatible:
+    const: qcom,qcs615-gcc
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Board active XO source
+      - description: Sleep clock source
+
+  clock-names:
+    items:
+      - const: bi_tcxo
+      - const: bi_tcxo_ao
+      - const: sleep_clk
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - '#power-domain-cells'
+
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    clock-controller@100000 {
+      compatible = "qcom,qcs615-gcc";
+      reg = <0x00100000 0x1f0000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&rpmhcc RPMH_CXO_CLK_A>,
+               <&sleep_clk>;
+      clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/clock/qcom,qcs615-gpucc.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/clock/qcom,qcs615-gpucc.yaml
@@ -0,0 +1,65 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,qcs615-gpucc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Graphics Clock & Reset Controller on QCS615
+
+maintainers:
+  - Taniya Das <quic_tdas@quicinc.com>
+
+description: |
+  Qualcomm graphics clock control module provides clocks, resets and power
+  domains on QCS615 Qualcomm SoCs.
+
+  See also: include/dt-bindings/clock/qcom,qcs615-gpucc.h
+
+properties:
+  compatible:
+    const: qcom,qcs615-gpucc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: GPLL0 main branch source
+      - description: GPLL0 GPUCC div branch source
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+
+    clock-controller@5090000 {
+      compatible = "qcom,qcs615-gpucc";
+      reg = <0x5090000 0x9000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&gcc    GPLL0>,
+               <&gcc    GCC_GPU_GPLL0_DIV_CLK_SRC>;
+
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/clock/qcom,qcs615-videocc.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/clock/qcom,qcs615-videocc.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,qcs615-videocc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Video Clock & Reset Controller on QCS615
+
+maintainers:
+  - Taniya Das <quic_tdas@quicinc.com>
+
+description: |
+  Qualcomm video clock control module provides clocks, resets and power
+  domains on QCS615 Qualcomm SoCs.
+
+  See also: include/dt-bindings/clock/qcom,qcs615-videocc.h
+
+properties:
+  compatible:
+    const: qcom,qcs615-videocc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Sleep clock source
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+
+    clock-controller@ab00000 {
+      compatible = "qcom,qcs615-videocc";
+      reg = <0xab00000 0x10000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&sleep_clk>;
+
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/clock/qcom,qcs8300-gcc.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/clock/qcom,qcs8300-gcc.yaml
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,qcs8300-gcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies, Inc. Global Clock & Reset Controller on QCS8300
+
+maintainers:
+  - Taniya Das <quic_tdas@quicinc.com>
+  - Imran Shaik <quic_imrashai@quicinc.com>
+
+description: |
+  Qualcomm Technologies, Inc. Global clock control module provides the clocks, resets and
+  power domains on QCS8300
+
+  See also: include/dt-bindings/clock/qcom,qcs8300-gcc.h
+
+properties:
+  compatible:
+    const: qcom,qcs8300-gcc
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Sleep clock source
+      - description: PCIE 0 Pipe clock source
+      - description: PCIE 1 Pipe clock source
+      - description: PCIE Phy Auxiliary clock source
+      - description: First EMAC controller reference clock
+      - description: UFS Phy Rx symbol 0 clock source
+      - description: UFS Phy Rx symbol 1 clock source
+      - description: UFS Phy Tx symbol 0 clock source
+      - description: USB3 Phy wrapper pipe clock source
+
+required:
+  - compatible
+  - clocks
+  - '#power-domain-cells'
+
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    clock-controller@100000 {
+      compatible = "qcom,qcs8300-gcc";
+      reg = <0x00100000 0xc7018>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&sleep_clk>,
+               <&pcie_0_pipe_clk>,
+               <&pcie_1_pipe_clk>,
+               <&pcie_phy_aux_clk>,
+               <&rxc0_ref_clk>,
+               <&ufs_phy_rx_symbol_0_clk>,
+               <&ufs_phy_rx_symbol_1_clk>,
+               <&ufs_phy_tx_symbol_0_clk>,
+               <&usb3_phy_wrapper_gcc_usb30_prim_pipe_clk>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/clock/qcom,sa8775p-camcc.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/clock/qcom,sa8775p-camcc.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,sa8775p-camcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies, Inc. Camera Clock & Reset Controller on SA8775P
+
+maintainers:
+  - Taniya Das <quic_tdas@quicinc.com>
+
+description: |
+  Qualcomm Technologies, Inc. camera clock control module provides the clocks, resets and power
+  domains on SA8775p.
+
+  See also::
+    include/dt-bindings/clock/qcom,sa8775p-camcc.h
+
+properties:
+  compatible:
+    enum:
+      - qcom,qcs8300-camcc
+      - qcom,sa8775p-camcc
+
+  clocks:
+    items:
+      - description: Camera AHB clock from GCC
+      - description: Board XO source
+      - description: Board active XO source
+      - description: Sleep clock source
+
+  power-domains:
+    maxItems: 1
+    description:
+      A phandle and PM domain specifier for the MMCX power domain.
+
+  required-opps:
+    maxItems: 1
+    description:
+      A phandle to an OPP node describing required MMCX performance point.
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - power-domains
+  - required-opps
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    #include <dt-bindings/power/qcom-rpmpd.h>
+    #include <dt-bindings/clock/qcom,sa8775p-gcc.h>
+    clock-controller@ade0000 {
+      compatible = "qcom,sa8775p-camcc";
+      reg = <0x0ade0000 0x20000>;
+      clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+               <&rpmhcc RPMH_CXO_CLK>,
+               <&rpmhcc RPMH_CXO_CLK_A>,
+               <&sleep_clk>;
+      power-domains = <&rpmhpd SA8775P_MMCX>;
+      required-opps = <&rpmhpd_opp_low_svs>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/clock/qcom,sa8775p-dispcc.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/clock/qcom,sa8775p-dispcc.yaml
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,dispcc-sa8775p.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies, Inc. Display Clock & Reset Controller on SA8775P
+
+maintainers:
+  - Taniya Das <quic_tdas@quicinc.com>
+
+description: |
+  Qualcomm Technologies, Inc. display clock control module provides the clocks, resets and power
+  domains on SA8775P.
+
+  See also:: include/dt-bindings/clock/qcom,sa8775p-dispcc.h
+
+properties:
+  compatible:
+    const: qcom,sa8775p-dispcc0
+    const: qcom,sa8775p-dispcc1
+
+  clocks:
+    items:
+      - description: GCC AHB clock source
+      - description: Board XO source
+      - description: Board XO_AO source
+      - description: Sleep clock source
+      - description: Link clock from DP0 PHY
+      - description: VCO DIV clock from DP0 PHY
+      - description: Link clock from DP1 PHY
+      - description: VCO DIV clock from DP1 PHY
+      - description: Byte clock from DSI0 PHY
+      - description: Pixel clock from DSI0 PHY
+      - description: Byte clock from DSI1 PHY
+      - description: Pixel clock from DSI1 PHY
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  power-domains:
+    description:
+      A phandle and PM domain specifier for the MMCX power domain.
+    maxItems: 1
+
+  required-opps:
+    description:
+      A phandle to an OPP node describing required MMCX performance point.
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    #include <dt-bindings/power/qcom-rpmpd.h>
+    #include <dt-bindings/clock/qcom,sa8755p-gcc.h>
+    clock-controller@af00000 {
+      compatible = "qcom,sa8755p-dispcc0";
+      reg = <0x0af00000 0x20000>;
+      clocks = <&gcc GCC_DISP_AHB_CLK>,
+               <&rpmhcc RPMH_CXO_CLK>,
+               <&rpmhcc RPMH_CXO_CLK_A>,
+               <&sleep_clk>,
+               <0>, <0>, <0>, <0>,
+               <&dsi_phy0 0>,
+               <&dsi_phy0 1>
+               <&dsi_phy1 2>,
+               <&dsi_phy1 3>;
+      power-domains = <&rpmhpd SA8775P_MMCX>;
+      required-opps = <&rpmhpd_opp_low_svs>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/clock/qcom,sa8775p-videocc.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/clock/qcom,sa8775p-videocc.yaml
@@ -0,0 +1,82 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,sa8775p-videocc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies, Inc. Video Clock & Reset Controller on SA8775P
+
+maintainers:
+  - Taniya Das <quic_tdas@quicinc.com>
+
+description: |
+  Qualcomm Technologies, Inc. video clock control module provides the clocks, resets and power
+  domains on SA8775P.
+
+  See also:: include/dt-bindings/clock/qcom,sa8775p-videocc.h
+
+properties:
+  compatible:
+    enum:
+      - qcom,sa8775p-videocc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Video AHB clock from GCC
+      - description: Board XO source
+      - description: Board active XO source
+      - description: Sleep Clock source
+
+  power-domains:
+    maxItems: 1
+    description:
+      MMCX power domain.
+
+  required-opps:
+    maxItems: 1
+    description:
+      A phandle to an OPP node describing required MMCX performance point.
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - power-domains
+  - required-opps
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    #include <dt-bindings/power/qcom-rpmpd.h>
+    #include <dt-bindings/clock/qcom,sa8775p-gcc.h>
+    videocc: clock-controller@abf0000 {
+      compatible = "qcom,sa8775p-videocc";
+      reg = <0x0abf0000 0x10000>;
+      clocks = <&gcc GCC_VIDEO_AHB_CLK>,
+               <&rpmhcc RPMH_CXO_CLK>,
+               <&rpmhcc RPMH_CXO_CLK_A>,
+               <&sleep_clk>;
+      power-domains = <&rpmhpd SA8775P_MMCX>;
+      required-opps = <&rpmhpd_opp_low_svs>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/display/bridge/adi,adv7533.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/display/bridge/adi,adv7533.yaml
@@ -90,7 +90,7 @@
   adi,dsi-lanes:
     description: Number of DSI data lanes connected to the DSI host.
     $ref: /schemas/types.yaml#/definitions/uint32
-    enum: [ 1, 2, 3, 4 ]
+    enum: [ 2, 3, 4 ]
 
   "#sound-dai-cells":
     const: 0
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/display/msm/qcom,mdss.yaml
@@ -127,6 +127,7 @@
           - qcom,dsi-phy-20nm
           - qcom,dsi-phy-28nm-8226
           - qcom,dsi-phy-28nm-hpm
+          - qcom,dsi-phy-28nm-hpm-fam-b
           - qcom,dsi-phy-28nm-lp
           - qcom,hdmi-phy-8084
           - qcom,hdmi-phy-8660
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/display/msm/qcom,sm8150-mdss.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/display/msm/qcom,sm8150-mdss.yaml
@@ -53,6 +53,15 @@
       compatible:
         const: qcom,sm8150-dpu
 
+  "^displayport-controller@[0-9a-f]+$":
+    type: object
+    additionalProperties: true
+
+    properties:
+      compatible:
+        contains:
+          const: qcom,sm8150-dp
+
   "^dsi@[0-9a-f]+$":
     type: object
     additionalProperties: true
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/dma/fsl,edma.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/dma/fsl,edma.yaml
@@ -47,8 +47,8 @@
       - 3
 
   dma-channels:
-    minItems: 1
-    maxItems: 64
+    minimum: 1
+    maximum: 64
 
   clocks:
     minItems: 1
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/eeprom/at24.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/eeprom/at24.yaml
@@ -69,14 +69,10 @@
               - items:
                   pattern: c32$
               - items:
-                  pattern: c32d-wl$
-              - items:
                   pattern: cs32$
               - items:
                   pattern: c64$
               - items:
-                  pattern: c64d-wl$
-              - items:
                   pattern: cs64$
               - items:
                   pattern: c128$
@@ -136,6 +132,7 @@
               - renesas,r1ex24128
               - samsung,s524ad0xd1
           - const: atmel,24c128
+      - pattern: '^atmel,24c(32|64)d-wl$' # Actual vendor is st
 
   label:
     description: Descriptive name of the EEPROM.
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml
@@ -75,7 +75,7 @@
   - clocks
 
 allOf:
-  - $ref: i2c-controller.yaml
+  - $ref: /schemas/i2c/i2c-controller.yaml#
   - if:
       properties:
         compatible:
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/i2c/google,cros-ec-i2c-tunnel.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/i2c/google,cros-ec-i2c-tunnel.yaml
@@ -21,7 +21,7 @@
   google,cros-ec-spi or google,cros-ec-i2c.
 
 allOf:
-  - $ref: i2c-controller.yaml#
+  - $ref: /schemas/i2c/i2c-controller.yaml#
 
 properties:
   compatible:
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/iio/adc/adi,axi-adc.yaml
@@ -28,6 +28,9 @@
   reg:
     maxItems: 1
 
+  clocks:
+    maxItems: 1
+
   dmas:
     maxItems: 1
 
@@ -39,12 +42,16 @@
     $ref: /schemas/types.yaml#/definitions/phandle
     description:
       A reference to a the actual ADC to which this FPGA ADC interfaces to.
+    deprecated: true
+
+  '#io-backend-cells':
+    const: 0
 
 required:
   - compatible
   - dmas
   - reg
-  - adi,adc-dev
+  - clocks
 
 additionalProperties: false
 
@@ -55,7 +62,7 @@
         reg = <0x44a00000 0x10000>;
         dmas = <&rx_dma 0>;
         dma-names = "rx";
-
-        adi,adc-dev = <&spi_adc>;
+        clocks = <&axi_clk>;
+        #io-backend-cells = <0>;
     };
 ...
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/iio/dac/adi,ad3552r.yaml
@@ -26,7 +26,7 @@
     maxItems: 1
 
   spi-max-frequency:
-    maximum: 30000000
+    maximum: 66000000
 
   reset-gpios:
     maxItems: 1
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/iio/health/maxim,max30102.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/iio/health/maxim,max30102.yaml
@@ -42,7 +42,7 @@
       properties:
         compatible:
           contains:
-            const: maxim,max30100
+            const: maxim,max30102
     then:
       properties:
         maxim,green-led-current-microamp: false
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8975.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8975.yaml
@@ -23,7 +23,6 @@
           - ak8963
           - ak09911
           - ak09912
-          - ak09916
         deprecated: true
 
   reg:
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/interconnect/qcom,qcs615-rpmh.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/interconnect/qcom,qcs615-rpmh.yaml
@@ -0,0 +1,73 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interconnect/qcom,qcs615-rpmh.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm RPMh Network-On-Chip Interconnect on QCS615
+
+maintainers:
+  - Raviteja Laggyshetty <quic_rlaggysh@quicinc.com>
+
+description: |
+  RPMh interconnect providers support system bandwidth requirements through
+  RPMh hardware accelerators known as Bus Clock Manager (BCM). The provider is
+  able to communicate with the BCM through the Resource State Coordinator (RSC)
+  associated with each execution environment. Provider nodes must point to at
+  least one RPMh device child node pertaining to their RSC and each provider
+  can map to multiple RPMh resources.
+
+  See also: include/dt-bindings/interconnect/qcom,qcs615-rpmh.h
+
+properties:
+  compatible:
+    enum:
+      - qcom,qcs615-aggre1-noc
+      - qcom,qcs615-camnoc-virt
+      - qcom,qcs615-config-noc
+      - qcom,qcs615-dc-noc
+      - qcom,qcs615-gem-noc
+      - qcom,qcs615-ipa-virt
+      - qcom,qcs615-mc-virt
+      - qcom,qcs615-mmss-noc
+      - qcom,qcs615-system-noc
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+
+allOf:
+  - $ref: qcom,rpmh-common.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,qcs615-camnoc-virt
+              - qcom,qcs615-ipa-virt
+              - qcom,qcs615-mc-virt
+    then:
+      properties:
+        reg: false
+    else:
+      required:
+        - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    gem_noc: interconnect@9680000 {
+        compatible = "qcom,qcs615-gem-noc";
+        reg = <0x9680000 0x3e200>;
+        #interconnect-cells = <2>;
+        qcom,bcm-voters = <&apps_bcm_voter>;
+    };
+
+    mc_virt: interconnect-2 {
+        compatible = "qcom,qcs615-mc-virt";
+        #interconnect-cells = <2>;
+        qcom,bcm-voters = <&apps_bcm_voter>;
+    };
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/interconnect/qcom,qcs8300-rpmh.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/interconnect/qcom,qcs8300-rpmh.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interconnect/qcom,qcs8300-rpmh.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies, Inc. RPMh Network-On-Chip Interconnect on QCS8300
+
+maintainers:
+  - Bjorn Andersson <andersson@kernel.org>
+  - Konrad Dybcio <konrad.dybcio@linaro.org>
+
+description: |
+  RPMh interconnect providers support system bandwidth requirements through
+  RPMh hardware accelerators known as Bus Clock Manager (BCM).
+
+  See also:: include/dt-bindings/interconnect/qcom,qcs8300.h
+
+properties:
+  compatible:
+    enum:
+      - qcom,qcs8300-aggre1-noc
+      - qcom,qcs8300-aggre2-noc
+      - qcom,qcs8300-clk-virt
+      - qcom,qcs8300-config-noc
+      - qcom,qcs8300-dc-noc
+      - qcom,qcs8300-gem-noc
+      - qcom,qcs8300-gpdsp-anoc
+      - qcom,qcs8300-lpass-ag-noc
+      - qcom,qcs8300-mc-virt
+      - qcom,qcs8300-mmss-noc
+      - qcom,qcs8300-nspa-noc
+      - qcom,qcs8300-pcie-anoc
+      - qcom,qcs8300-system-noc
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    gem_noc: interconnect-gem-noc {
+        compatible = "qcom,qcs8300-gem-noc";
+        #interconnect-cells = <2>;
+        qcom,bcm-voters = <&apps_bcm_voter>;
+    };
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/iommu/arm,smmu.yaml
@@ -484,7 +484,12 @@
   - if:
       properties:
         compatible:
-          const: qcom,sm8450-smmu-500
+          items:
+            - const: qcom,sm8450-smmu-500
+            - const: qcom,adreno-smmu
+            - const: qcom,smmu-500
+            - const: arm,mmu-500
+
     then:
       properties:
         clock-names:
@@ -508,7 +513,11 @@
   - if:
       properties:
         compatible:
-          const: qcom,sm8550-smmu-500
+          items:
+            - const: qcom,sm8550-smmu-500
+            - const: qcom,adreno-smmu
+            - const: qcom,smmu-500
+            - const: arm,mmu-500
     then:
       properties:
         clock-names:
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml
@@ -27,7 +27,7 @@
     description: |
       For multicolor LED support this property should be defined as either
       LED_COLOR_ID_RGB or LED_COLOR_ID_MULTI which can be found in
-      include/linux/leds/common.h.
+      include/dt-bindings/leds/common.h.
     enum: [ 8, 9 ]
 
 required:
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/media/i2c/ovti,ov2680.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/media/i2c/ovti,ov2680.yaml
@@ -37,15 +37,15 @@
       active low.
     maxItems: 1
 
-  dovdd-supply:
+  DOVDD-supply:
     description:
       Definition of the regulator used as interface power supply.
 
-  avdd-supply:
+  AVDD-supply:
     description:
       Definition of the regulator used as analog power supply.
 
-  dvdd-supply:
+  DVDD-supply:
     description:
       Definition of the regulator used as digital power supply.
 
@@ -59,9 +59,9 @@
   - reg
   - clocks
   - clock-names
-  - dovdd-supply
-  - avdd-supply
-  - dvdd-supply
+  - DOVDD-supply
+  - AVDD-supply
+  - DVDD-supply
   - reset-gpios
   - port
 
@@ -82,9 +82,9 @@
                 clock-names = "xvclk";
                 reset-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
 
-                dovdd-supply = <&sw2_reg>;
-                dvdd-supply = <&sw2_reg>;
-                avdd-supply = <&reg_peri_3p15v>;
+                DOVDD-supply = <&sw2_reg>;
+                DVDD-supply = <&sw2_reg>;
+                AVDD-supply = <&reg_peri_3p15v>;
 
                 port {
                         ov2680_to_mipi: endpoint {
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/media/i2c/techwell,tw9900.yaml
@@ -36,7 +36,7 @@
 
     properties:
       port@0:
-        $ref: /schemas/graph.yaml#/$defs/port-base
+        $ref: /schemas/graph.yaml#/properties/port
         description: Analog input port
 
         properties:
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml
@@ -50,15 +50,15 @@
     minimum: 0
     maximum: 1
 
-  rohm,charger-sense-resistor-ohms:
-    minimum: 10000000
-    maximum: 50000000
+  rohm,charger-sense-resistor-micro-ohms:
+    minimum: 10000
+    maximum: 50000
     description: |
-      BD71827 and BD71828 have SAR ADC for measuring charging currents.
-      External sense resistor (RSENSE in data sheet) should be used. If
-      something other but 30MOhm resistor is used the resistance value
-      should be given here in Ohms.
-    default: 30000000
+      BD71815 has SAR ADC for measuring charging currents. External sense
+      resistor (RSENSE in data sheet) should be used. If something other
+      but a 30 mOhm resistor is used the resistance value should be given
+      here in micro Ohms.
+    default: 30000
 
   regulators:
     $ref: ../regulator/rohm,bd71815-regulator.yaml
@@ -67,7 +67,7 @@
 
   gpio-reserved-ranges:
     description: |
-      Usage of BD71828 GPIO pins can be changed via OTP. This property can be
+      Usage of BD71815 GPIO pins can be changed via OTP. This property can be
       used to mark the pins which should not be configured for GPIO. Please see
       the ../gpio/gpio.txt for more information.
 
@@ -113,7 +113,7 @@
             gpio-controller;
             #gpio-cells = <2>;
 
-            rohm,charger-sense-resistor-ohms = <10000000>;
+            rohm,charger-sense-resistor-micro-ohms = <10000>;
 
             regulators {
                 buck1: buck1 {
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/mmc/mmc-controller.yaml
@@ -25,7 +25,7 @@
   "#address-cells":
     const: 1
     description: |
-      The cell is the slot ID if a function subnode is used.
+      The cell is the SDIO function number if a function subnode is used.
 
   "#size-cells":
     const: 0
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/net/fsl,fec.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/net/fsl,fec.yaml
@@ -183,6 +183,13 @@
     description:
       Register bits of stop mode control, the format is <&gpr req_gpr req_bit>.
 
+  fsl,pps-channel:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+    description:
+      Specifies to which timer instance the PPS signal is routed.
+    enum: [0, 1, 2, 3]
+
   mdio:
     $ref: mdio.yaml#
     unevaluatedProperties: false
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/net/mediatek,net.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/net/mediatek,net.yaml
@@ -337,8 +337,8 @@
           minItems: 4
 
         clocks:
-          minItems: 34
-          maxItems: 34
+          minItems: 24
+          maxItems: 24
 
         clock-names:
           items:
@@ -351,18 +351,6 @@
             - const: ethwarp_wocpu1
             - const: ethwarp_wocpu0
             - const: esw
-            - const: netsys0
-            - const: netsys1
-            - const: sgmii_tx250m
-            - const: sgmii_rx250m
-            - const: sgmii2_tx250m
-            - const: sgmii2_rx250m
-            - const: top_usxgmii0_sel
-            - const: top_usxgmii1_sel
-            - const: top_sgm0_sel
-            - const: top_sgm1_sel
-            - const: top_xfi_phy0_xtal_sel
-            - const: top_xfi_phy1_xtal_sel
             - const: top_eth_gmii_sel
             - const: top_eth_refck_50m_sel
             - const: top_eth_sys_200m_sel
@@ -375,16 +363,10 @@
             - const: top_netsys_sync_250m_sel
             - const: top_netsys_ppefb_250m_sel
             - const: top_netsys_warp_sel
-            - const: wocpu1
-            - const: wocpu0
             - const: xgp1
             - const: xgp2
             - const: xgp3
 
-        mediatek,sgmiisys:
-          minItems: 2
-          maxItems: 2
-
 patternProperties:
   "^mac@[0-1]$":
     type: object
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/net/xlnx,axi-ethernet.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/net/xlnx,axi-ethernet.yaml
@@ -34,6 +34,7 @@
       and length of the AXI DMA controller IO space, unless
       axistream-connected is specified, in which case the reg
       attribute of the node referenced by it is used.
+    minItems: 1
     maxItems: 2
 
   interrupts:
@@ -60,7 +61,7 @@
       - gmii
       - rgmii
       - sgmii
-      - 1000BaseX
+      - 1000base-x
 
   xlnx,phy-type:
     description:
@@ -181,7 +182,7 @@
         clock-names = "s_axi_lite_clk", "axis_clk", "ref_clk", "mgt_clk";
         clocks = <&axi_clk>, <&axi_clk>, <&pl_enet_ref_clk>, <&mgt_clk>;
         phy-mode = "mii";
-        reg = <0x00 0x40000000 0x00 0x40000>;
+        reg = <0x40000000 0x40000>;
         xlnx,rxcsum = <0x2>;
         xlnx,rxmem = <0x800>;
         xlnx,txcsum = <0x2>;
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/pci/rcar-pci-host.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/pci/rcar-pci-host.yaml
@@ -77,6 +77,9 @@
   vpcie12v-supply:
     description: The 12v regulator to use for PCIe.
 
+  iommu-map: true
+  iommu-map-mask: true
+
 required:
   - compatible
   - reg
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/pci/rockchip,rk3399-pcie.yaml
@@ -37,6 +37,7 @@
     description: This property is needed if using 24MHz OSC for RC's PHY.
 
   ep-gpios:
+    maxItems: 1
     description: pre-reset GPIO
 
   vpcie12v-supply:
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml
@@ -73,7 +73,6 @@
   - reg
   - clocks
   - clock-names
-  - power-domains
   - resets
   - reset-names
   - vdda-phy-supply
@@ -134,6 +133,21 @@
         clock-names:
           maxItems: 1
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,msm8996-qmp-ufs-phy
+              - qcom,msm8998-qmp-ufs-phy
+    then:
+      properties:
+        power-domains:
+          false
+    else:
+      required:
+        - power-domains
+
 additionalProperties: false
 
 examples:
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/phy/qcom,usb-snps-femto-v2.yaml
@@ -15,9 +15,6 @@
 properties:
   compatible:
     oneOf:
-      - enum:
-          - qcom,sc8180x-usb-hs-phy
-          - qcom,usb-snps-femto-v2-phy
       - items:
           - enum:
               - qcom,sa8775p-usb-hs-phy
@@ -26,6 +23,7 @@
       - items:
           - enum:
               - qcom,sc7280-usb-hs-phy
+              - qcom,sc8180x-usb-hs-phy
               - qcom,sdx55-usb-hs-phy
               - qcom,sdx65-usb-hs-phy
               - qcom,sm6375-usb-hs-phy
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/pinctrl/mediatek,mt7622-pinctrl.yaml
@@ -97,7 +97,8 @@
             then:
               properties:
                 groups:
-                  enum: [emmc, emmc_rst]
+                  items:
+                    enum: [emmc, emmc_rst]
           - if:
               properties:
                 function:
@@ -105,8 +106,9 @@
             then:
               properties:
                 groups:
-                  enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw,
-                         rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio]
+                  items:
+                    enum: [esw, esw_p0_p1, esw_p2_p3_p4, rgmii_via_esw,
+                           rgmii_via_gmac1, rgmii_via_gmac2, mdc_mdio]
           - if:
               properties:
                 function:
@@ -123,10 +125,11 @@
             then:
               properties:
                 groups:
-                  enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data,
-                         i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws,
-                         i2s1_out_data, i2s2_out_data, i2s3_out_data,
-                         i2s4_out_data]
+                  items:
+                    enum: [i2s_in_mclk_bclk_ws, i2s1_in_data, i2s2_in_data,
+                           i2s3_in_data, i2s4_in_data, i2s_out_mclk_bclk_ws,
+                           i2s1_out_data, i2s2_out_data, i2s3_out_data,
+                           i2s4_out_data]
           - if:
               properties:
                 function:
@@ -159,10 +162,11 @@
             then:
               properties:
                 groups:
-                  enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken,
-                         pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq,
-                         pcie0_pad_perst, pcie1_pad_perst, pcie_pereset,
-                         pcie_wake, pcie_clkreq]
+                  items:
+                    enum: [pcie0_0_waken, pcie0_1_waken, pcie1_0_waken,
+                           pcie0_0_clkreq, pcie0_1_clkreq, pcie1_0_clkreq,
+                           pcie0_pad_perst, pcie1_pad_perst, pcie_pereset,
+                           pcie_wake, pcie_clkreq]
           - if:
               properties:
                 function:
@@ -178,11 +182,12 @@
             then:
               properties:
                 groups:
-                  enum: [pwm_ch1_0, pwm_ch1_1, pwm_ch1_2, pwm_ch2_0, pwm_ch2_1,
-                         pwm_ch2_2, pwm_ch3_0, pwm_ch3_1, pwm_ch3_2, pwm_ch4_0,
-                         pwm_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1,
-                         pwm_ch5_2, pwm_ch6_0, pwm_ch6_1, pwm_ch6_2, pwm_ch6_3,
-                         pwm_ch7_0, pwm_0, pwm_1]
+                  items:
+                    enum: [pwm_ch1_0, pwm_ch1_1, pwm_ch1_2, pwm_ch2_0, pwm_ch2_1,
+                           pwm_ch2_2, pwm_ch3_0, pwm_ch3_1, pwm_ch3_2, pwm_ch4_0,
+                           pwm_ch4_1, pwm_ch4_2, pwm_ch4_3, pwm_ch5_0, pwm_ch5_1,
+                           pwm_ch5_2, pwm_ch6_0, pwm_ch6_1, pwm_ch6_2, pwm_ch6_3,
+                           pwm_ch7_0, pwm_0, pwm_1]
           - if:
               properties:
                 function:
@@ -260,33 +265,34 @@
           pins:
             description:
               An array of strings. Each string contains the name of a pin.
-            enum: [GPIO_A, I2S1_IN, I2S1_OUT, I2S_BCLK, I2S_WS, I2S_MCLK, TXD0,
-                   RXD0, SPI_WP, SPI_HOLD, SPI_CLK, SPI_MOSI, SPI_MISO, SPI_CS,
-                   I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT,
-                   I2S3_OUT, I2S4_OUT, GPIO_B, MDC, MDIO, G2_TXD0, G2_TXD1,
-                   G2_TXD2, G2_TXD3, G2_TXEN, G2_TXC, G2_RXD0, G2_RXD1, G2_RXD2,
-                   G2_RXD3, G2_RXDV, G2_RXC, NCEB, NWEB, NREB, NDL4, NDL5, NDL6,
-                   NDL7, NRB, NCLE, NALE, NDL0, NDL1, NDL2, NDL3, MDI_TP_P0,
-                   MDI_TN_P0, MDI_RP_P0, MDI_RN_P0, MDI_TP_P1, MDI_TN_P1,
-                   MDI_RP_P1, MDI_RN_P1, MDI_RP_P2, MDI_RN_P2, MDI_TP_P2,
-                   MDI_TN_P2, MDI_TP_P3, MDI_TN_P3, MDI_RP_P3, MDI_RN_P3,
-                   MDI_RP_P4, MDI_RN_P4, MDI_TP_P4, MDI_TN_P4, PMIC_SCL,
-                   PMIC_SDA, SPIC1_CLK, SPIC1_MOSI, SPIC1_MISO, SPIC1_CS,
-                   GPIO_D, WATCHDOG, RTS3_N, CTS3_N, TXD3, RXD3, PERST0_N,
-                   PERST1_N, WLED_N, EPHY_LED0_N, AUXIN0, AUXIN1, AUXIN2,
-                   AUXIN3, TXD4, RXD4, RTS4_N, CST4_N, PWM1, PWM2, PWM3, PWM4,
-                   PWM5, PWM6, PWM7, GPIO_E, TOP_5G_CLK, TOP_5G_DATA,
-                   WF0_5G_HB0, WF0_5G_HB1, WF0_5G_HB2, WF0_5G_HB3, WF0_5G_HB4,
-                   WF0_5G_HB5, WF0_5G_HB6, XO_REQ, TOP_RST_N, SYS_WATCHDOG,
-                   EPHY_LED0_N_JTDO, EPHY_LED1_N_JTDI, EPHY_LED2_N_JTMS,
-                   EPHY_LED3_N_JTCLK, EPHY_LED4_N_JTRST_N, WF2G_LED_N,
-                   WF5G_LED_N, GPIO_9, GPIO_10, GPIO_11, GPIO_12, UART1_TXD,
-                   UART1_RXD, UART1_CTS, UART1_RTS, UART2_TXD, UART2_RXD,
-                   UART2_CTS, UART2_RTS, SMI_MDC, SMI_MDIO, PCIE_PERESET_N,
-                   PWM_0, GPIO_0, GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5,
-                   GPIO_6, GPIO_7, GPIO_8, UART0_TXD, UART0_RXD, TOP_2G_CLK,
-                   TOP_2G_DATA, WF0_2G_HB0, WF0_2G_HB1, WF0_2G_HB2, WF0_2G_HB3,
-                   WF0_2G_HB4, WF0_2G_HB5, WF0_2G_HB6]
+            items:
+              enum: [GPIO_A, I2S1_IN, I2S1_OUT, I2S_BCLK, I2S_WS, I2S_MCLK, TXD0,
+                     RXD0, SPI_WP, SPI_HOLD, SPI_CLK, SPI_MOSI, SPI_MISO, SPI_CS,
+                     I2C_SDA, I2C_SCL, I2S2_IN, I2S3_IN, I2S4_IN, I2S2_OUT,
+                     I2S3_OUT, I2S4_OUT, GPIO_B, MDC, MDIO, G2_TXD0, G2_TXD1,
+                     G2_TXD2, G2_TXD3, G2_TXEN, G2_TXC, G2_RXD0, G2_RXD1, G2_RXD2,
+                     G2_RXD3, G2_RXDV, G2_RXC, NCEB, NWEB, NREB, NDL4, NDL5, NDL6,
+                     NDL7, NRB, NCLE, NALE, NDL0, NDL1, NDL2, NDL3, MDI_TP_P0,
+                     MDI_TN_P0, MDI_RP_P0, MDI_RN_P0, MDI_TP_P1, MDI_TN_P1,
+                     MDI_RP_P1, MDI_RN_P1, MDI_RP_P2, MDI_RN_P2, MDI_TP_P2,
+                     MDI_TN_P2, MDI_TP_P3, MDI_TN_P3, MDI_RP_P3, MDI_RN_P3,
+                     MDI_RP_P4, MDI_RN_P4, MDI_TP_P4, MDI_TN_P4, PMIC_SCL,
+                     PMIC_SDA, SPIC1_CLK, SPIC1_MOSI, SPIC1_MISO, SPIC1_CS,
+                     GPIO_D, WATCHDOG, RTS3_N, CTS3_N, TXD3, RXD3, PERST0_N,
+                     PERST1_N, WLED_N, EPHY_LED0_N, AUXIN0, AUXIN1, AUXIN2,
+                     AUXIN3, TXD4, RXD4, RTS4_N, CST4_N, PWM1, PWM2, PWM3, PWM4,
+                     PWM5, PWM6, PWM7, GPIO_E, TOP_5G_CLK, TOP_5G_DATA,
+                     WF0_5G_HB0, WF0_5G_HB1, WF0_5G_HB2, WF0_5G_HB3, WF0_5G_HB4,
+                     WF0_5G_HB5, WF0_5G_HB6, XO_REQ, TOP_RST_N, SYS_WATCHDOG,
+                     EPHY_LED0_N_JTDO, EPHY_LED1_N_JTDI, EPHY_LED2_N_JTMS,
+                     EPHY_LED3_N_JTCLK, EPHY_LED4_N_JTRST_N, WF2G_LED_N,
+                     WF5G_LED_N, GPIO_9, GPIO_10, GPIO_11, GPIO_12, UART1_TXD,
+                     UART1_RXD, UART1_CTS, UART1_RTS, UART2_TXD, UART2_RXD,
+                     UART2_CTS, UART2_RTS, SMI_MDC, SMI_MDIO, PCIE_PERESET_N,
+                     PWM_0, GPIO_0, GPIO_1, GPIO_2, GPIO_3, GPIO_4, GPIO_5,
+                     GPIO_6, GPIO_7, GPIO_8, UART0_TXD, UART0_RXD, TOP_2G_CLK,
+                     TOP_2G_DATA, WF0_2G_HB0, WF0_2G_HB1, WF0_2G_HB2, WF0_2G_HB3,
+                     WF0_2G_HB4, WF0_2G_HB5, WF0_2G_HB6]
 
           bias-disable: true
 
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/pinctrl/qcom,sm4450-tlmm.yaml
@@ -72,40 +72,24 @@
         description:
           Specify the alternative function to be configured for the specified
           pins.
-        enum: [ gpio, atest_char, atest_char0, atest_char1, atest_char2,
-                atest_char3, atest_usb0, atest_usb00, atest_usb01, atest_usb02,
-                atest_usb03, audio_ref, cam_mclk, cci_async, cci_i2c,
-                cci_timer0, cci_timer1, cci_timer2, cci_timer3, cci_timer4,
-                cmu_rng0, cmu_rng1, cmu_rng2, cmu_rng3, coex_uart1, cri_trng,
-                cri_trng0, cri_trng1, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1,
-                dp0_hot, gcc_gp1, gcc_gp2, gcc_gp3, host2wlan_sol, ibi_i3c,
-                jitter_bist, mdp_vsync, mdp_vsync0, mdp_vsync1, mdp_vsync2,
-                mdp_vsync3, mi2s0_data0, mi2s0_data1, mi2s0_sck, mi2s0_ws,
-                mi2s2_data0, mi2s2_data1, mi2s2_sck, mi2s2_ws, mi2s_mclk0,
-                mi2s_mclk1, nav_gpio0, nav_gpio1, nav_gpio2, pcie0_clk,
-                phase_flag0, phase_flag1, phase_flag10, phase_flag11,
-                phase_flag12, phase_flag13, phase_flag14, phase_flag15,
-                phase_flag16, phase_flag17, phase_flag18, phase_flag19,
-                phase_flag2, phase_flag20, phase_flag21, phase_flag22,
-                phase_flag23, phase_flag24, phase_flag25, phase_flag26,
-                phase_flag27, phase_flag28, phase_flag29, phase_flag3,
-                phase_flag30, phase_flag31, phase_flag4, phase_flag5,
-                phase_flag6, phase_flag7, phase_flag8, phase_flag9,
-                pll_bist, pll_clk, prng_rosc0, prng_rosc1, prng_rosc2,
-                prng_rosc3, qdss_cti, qdss_gpio, qdss_gpio0, qdss_gpio1,
-                qdss_gpio10, qdss_gpio11, qdss_gpio12, qdss_gpio13, qdss_gpio14,
-                qdss_gpio15, qdss_gpio2, qdss_gpio3, qdss_gpio4, qdss_gpio5,
-                qdss_gpio6, qdss_gpio7, qdss_gpio8, qdss_gpio9, qlink0_enable,
-                qlink0_request, qlink0_wmss, qlink1_enable, qlink1_request,
-                qlink1_wmss, qlink2_enable, qlink2_request, qlink2_wmss,
-                qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4, qup0_se5,
-                qup0_se6, qup0_se7, qup1_se0, qup1_se1, qup1_se2, qup1_se3,
-                qup1_se4, qup1_se5, qup1_se6, sd_write, tb_trig, tgu_ch0,
-                tgu_ch1, tgu_ch2, tgu_ch3, tmess_prng0, tmess_prng1,
-                tmess_prng2, tmess_prng3, tsense_pwm1, tsense_pwm2, uim0_clk,
-                uim0_data, uim0_present, uim0_reset, uim1_clk, uim1_data,
-                uim1_present, uim1_reset, usb0_hs, usb0_phy, vfr_0, vfr_1,
-                vsense_trigger ]
+        enum: [ gpio, atest_char, atest_usb0, audio_ref_clk, cam_mclk,
+                cci_async_in0, cci_i2c, cci, cmu_rng, coex_uart1_rx,
+                coex_uart1_tx, cri_trng, dbg_out_clk, ddr_bist,
+                ddr_pxi0_test, ddr_pxi1_test, gcc_gp1_clk, gcc_gp2_clk,
+                gcc_gp3_clk, host2wlan_sol, ibi_i3c_qup0, ibi_i3c_qup1,
+                jitter_bist_ref, mdp_vsync0_out, mdp_vsync1_out,
+                mdp_vsync2_out, mdp_vsync3_out, mdp_vsync, nav,
+                pcie0_clk_req, phase_flag, pll_bist_sync, pll_clk_aux,
+                prng_rosc, qdss_cti_trig0, qdss_cti_trig1, qdss_gpio,
+                qlink0_enable, qlink0_request, qlink0_wmss_reset,
+                qup0_se0, qup0_se1, qup0_se2, qup0_se3, qup0_se4,
+                qup1_se0, qup1_se1, qup1_se2, qup1_se2_l2, qup1_se3,
+                qup1_se4, sd_write_protect, tb_trig_sdc1, tb_trig_sdc2,
+                tgu_ch0_trigout, tgu_ch1_trigout, tgu_ch2_trigout,
+                tgu_ch3_trigout, tmess_prng, tsense_pwm1_out,
+                tsense_pwm2_out, uim0, uim1, usb0_hs_ac, usb0_phy_ps,
+                vfr_0_mira, vfr_0_mirb, vfr_1, vsense_trigger_mirnat,
+                wlan1_adc_dtest0, wlan1_adc_dtest1 ]
 
         required:
           - pins
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml
@@ -91,14 +91,17 @@
   - if:
       properties:
         compatible:
-          # Match without "contains", to skip newer variants which are still
-          # compatible with samsung,exynos7-wakeup-eint
-          enum:
-            - samsung,s5pv210-wakeup-eint
-            - samsung,exynos4210-wakeup-eint
-            - samsung,exynos5433-wakeup-eint
-            - samsung,exynos7-wakeup-eint
-            - samsung,exynos7885-wakeup-eint
+          oneOf:
+            # Match without "contains", to skip newer variants which are still
+            # compatible with samsung,exynos7-wakeup-eint
+            - enum:
+                - samsung,exynos4210-wakeup-eint
+                - samsung,exynos7-wakeup-eint
+                - samsung,s5pv210-wakeup-eint
+            - contains:
+                enum:
+                  - samsung,exynos5433-wakeup-eint
+                  - samsung,exynos7885-wakeup-eint
     then:
       properties:
         interrupts:
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/regulator/mt6315-regulator.yaml
@@ -31,10 +31,6 @@
         $ref: regulator.yaml#
         unevaluatedProperties: false
 
-        properties:
-          regulator-compatible:
-            pattern: "^vbuck[1-4]$"
-
     additionalProperties: false
 
 required:
@@ -52,7 +48,6 @@
 
       regulators {
         vbuck1 {
-          regulator-compatible = "vbuck1";
           regulator-min-microvolt = <300000>;
           regulator-max-microvolt = <1193750>;
           regulator-enable-ramp-delay = <256>;
@@ -60,7 +55,6 @@
         };
 
         vbuck3 {
-          regulator-compatible = "vbuck3";
           regulator-min-microvolt = <300000>;
           regulator-max-microvolt = <1193750>;
           regulator-enable-ramp-delay = <256>;
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/serial/rs485.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/serial/rs485.yaml
@@ -18,16 +18,15 @@
     description: prop-encoded-array <a b>
     $ref: /schemas/types.yaml#/definitions/uint32-array
     items:
-      items:
-        - description: Delay between rts signal and beginning of data sent in
-            milliseconds. It corresponds to the delay before sending data.
-          default: 0
-          maximum: 100
-        - description: Delay between end of data sent and rts signal in milliseconds.
-            It corresponds to the delay after sending data and actual release
-            of the line.
-          default: 0
-          maximum: 100
+      - description: Delay between rts signal and beginning of data sent in
+          milliseconds. It corresponds to the delay before sending data.
+        default: 0
+        maximum: 100
+      - description: Delay between end of data sent and rts signal in milliseconds.
+          It corresponds to the delay after sending data and actual release
+          of the line.
+        default: 0
+        maximum: 100
 
   rs485-rts-active-high:
     description: drive RTS high when sending (this is the default).
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
@@ -165,6 +165,7 @@
           unevaluatedProperties: false
 
         pcie-phy:
+          type: object
           description:
             Documentation/devicetree/bindings/phy/rockchip-pcie-phy.txt
 
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.yaml
@@ -102,21 +102,21 @@
     default: 2
 
   interrupts:
-    anyOf:
-      - minItems: 1
-        items:
-          - description: TX interrupt
-          - description: RX interrupt
-      - items:
-          - description: common/combined interrupt
+    minItems: 1
+    maxItems: 2
 
   interrupt-names:
     oneOf:
-      - minItems: 1
+      - description: TX interrupt
+        const: tx
+      - description: RX interrupt
+        const: rx
+      - description: TX and RX interrupts
         items:
           - const: tx
           - const: rx
-      - const: common
+      - description: Common/combined interrupt
+        const: common
 
   fck_parent:
     $ref: /schemas/types.yaml#/definitions/string
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/sound/mt6359.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/sound/mt6359.yaml
@@ -23,8 +23,8 @@
       Indicates how many data pins are used to transmit two channels of PDM
       signal. 0 means two wires, 1 means one wire. Default value is 0.
     enum:
-      - 0 # one wire
-      - 1 # two wires
+      - 0 # two wires
+      - 1 # one wire
 
   mediatek,mic-type-0:
     $ref: /schemas/types.yaml#/definitions/uint32
@@ -53,9 +53,9 @@
 
 examples:
   - |
-    mt6359codec: mt6359codec {
-      mediatek,dmic-mode = <0>;
-      mediatek,mic-type-0 = <2>;
+    mt6359codec: audio-codec {
+        mediatek,dmic-mode = <0>;
+        mediatek,mic-type-0 = <2>;
     };
 
 ...
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/sound/rt5645.txt
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/sound/rt5645.txt
@@ -20,6 +20,11 @@
   a GPIO spec for the external headphone detect pin. If jd-mode = 0,
   we will get the JD status by getting the value of hp-detect-gpios.
 
+- cbj-sleeve-gpios:
+  a GPIO spec to control the external combo jack circuit to tie the sleeve/ring2
+  contacts to the ground or floating. It could avoid some electric noise from the
+  active speaker jacks.
+
 - realtek,in2-differential
   Boolean. Indicate MIC2 input are differential, rather than single-ended.
 
@@ -68,6 +73,7 @@
 	compatible = "realtek,rt5650";
 	reg = <0x1a>;
 	hp-detect-gpios = <&gpio 19 0>;
+	cbj-sleeve-gpios = <&gpio 20 0>;
 	interrupt-parent = <&gpio>;
 	interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
 	realtek,dmic-en = "true";
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/spi/spi-nxp-fspi.yaml
@@ -15,12 +15,19 @@
 
 properties:
   compatible:
-    enum:
-      - nxp,imx8dxl-fspi
-      - nxp,imx8mm-fspi
-      - nxp,imx8mp-fspi
-      - nxp,imx8qxp-fspi
-      - nxp,lx2160a-fspi
+    oneOf:
+      - enum:
+          - nxp,imx8dxl-fspi
+          - nxp,imx8mm-fspi
+          - nxp,imx8mp-fspi
+          - nxp,imx8qxp-fspi
+          - nxp,imx8ulp-fspi
+          - nxp,lx2160a-fspi
+      - items:
+          - enum:
+              - nxp,imx93-fspi
+              - nxp,imx95-fspi
+          - const: nxp,imx8mm-fspi
 
   reg:
     items:
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/spmi/hisilicon,hisi-spmi-controller.yaml
@@ -14,7 +14,7 @@
   It is a MIPI System Power Management (SPMI) controller.
 
   The PMIC part is provided by
-  ./Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml.
+  Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml.
 
 allOf:
   - $ref: spmi.yaml#
@@ -48,7 +48,7 @@
       PMIC properties, which are specific to the used SPMI PMIC device(s).
       When used in combination with HiSilicon 6421v600, the properties
       are documented at
-      drivers/staging/hikey9xx/hisilicon,hi6421-spmi-pmic.yaml.
+      Documentation/devicetree/bindings/mfd/hisilicon,hi6421-spmi-pmic.yaml
 
 unevaluatedProperties: false
 
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/thermal/loongson,ls2k-thermal.yaml
@@ -18,13 +18,15 @@
     oneOf:
       - enum:
           - loongson,ls2k1000-thermal
+          - loongson,ls2k2000-thermal
       - items:
           - enum:
-              - loongson,ls2k2000-thermal
+              - loongson,ls2k0500-thermal
           - const: loongson,ls2k1000-thermal
 
   reg:
-    maxItems: 1
+    minItems: 1
+    maxItems: 2
 
   interrupts:
     maxItems: 1
@@ -38,6 +40,24 @@
   - interrupts
   - '#thermal-sensor-cells'
 
+if:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - loongson,ls2k2000-thermal
+
+then:
+  properties:
+    reg:
+      minItems: 2
+      maxItems: 2
+
+else:
+  properties:
+    reg:
+      maxItems: 1
+
 unevaluatedProperties: false
 
 examples:
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/thermal/thermal-zones.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/thermal/thermal-zones.yaml
@@ -49,7 +49,10 @@
       to take when the temperature crosses those thresholds.
 
 patternProperties:
-  "^[a-zA-Z][a-zA-Z0-9\\-]{1,12}-thermal$":
+  # Node name is limited in size due to Linux kernel requirements - 19
+  # characters in total (see THERMAL_NAME_LENGTH, including terminating NUL
+  # byte):
+  "^[a-zA-Z][a-zA-Z0-9\\-]{1,10}-thermal$":
     type: object
     description:
       Each thermal zone node contains information about how frequently it
--- linux-qcom-6.8.0.orig/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ linux-qcom-6.8.0/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -957,6 +957,8 @@
     description: National Semiconductor
   "^nec,.*":
     description: NEC LCD Technologies, Ltd.
+  "^neofidelity,.*":
+    description: Neofidelity Inc.
   "^neonode,.*":
     description: Neonode Inc.
   "^netgear,.*":
--- linux-qcom-6.8.0.orig/Documentation/driver-api/crypto/iaa/iaa-crypto.rst
+++ linux-qcom-6.8.0/Documentation/driver-api/crypto/iaa/iaa-crypto.rst
@@ -270,7 +270,7 @@
       echo async_irq > /sys/bus/dsa/drivers/crypto/sync_mode
 
     Async mode without interrupts (caller must poll) can be enabled by
-    writing 'async' to it::
+    writing 'async' to it (please see Caveat)::
 
       echo async > /sys/bus/dsa/drivers/crypto/sync_mode
 
@@ -281,6 +281,13 @@
 
     The default mode is 'sync'.
 
+    Caveat: since the only mechanism that iaa_crypto currently implements
+    for async polling without interrupts is via the 'sync' mode as
+    described earlier, writing 'async' to
+    '/sys/bus/dsa/drivers/crypto/sync_mode' will internally enable the
+    'sync' mode. This is to ensure correct iaa_crypto behavior until true
+    async polling without interrupts is enabled in iaa_crypto.
+
 .. _iaa_default_config:
 
 IAA Default Configuration
--- linux-qcom-6.8.0.orig/Documentation/driver-api/dpll.rst
+++ linux-qcom-6.8.0/Documentation/driver-api/dpll.rst
@@ -214,6 +214,27 @@
 divided with ``DPLL_PIN_PHASE_OFFSET_DIVIDER`` to get integer part and
 modulo divided to get fractional part.
 
+Embedded SYNC
+=============
+
+Device may provide ability to use Embedded SYNC feature. It allows
+to embed additional SYNC signal into the base frequency of a pin - a one
+special pulse of base frequency signal every time SYNC signal pulse
+happens. The user can configure the frequency of Embedded SYNC.
+The Embedded SYNC capability is always related to a given base frequency
+and HW capabilities. The user is provided a range of Embedded SYNC
+frequencies supported, depending on current base frequency configured for
+the pin.
+
+  ========================================= =================================
+  ``DPLL_A_PIN_ESYNC_FREQUENCY``            current Embedded SYNC frequency
+  ``DPLL_A_PIN_ESYNC_FREQUENCY_SUPPORTED``  nest available Embedded SYNC
+                                            frequency ranges
+    ``DPLL_A_PIN_FREQUENCY_MIN``            attr minimum value of frequency
+    ``DPLL_A_PIN_FREQUENCY_MAX``            attr maximum value of frequency
+  ``DPLL_A_PIN_ESYNC_PULSE``                pulse type of Embedded SYNC
+  ========================================= =================================
+
 Configuration commands group
 ============================
 
--- linux-qcom-6.8.0.orig/Documentation/driver-api/fpga/fpga-bridge.rst
+++ linux-qcom-6.8.0/Documentation/driver-api/fpga/fpga-bridge.rst
@@ -6,9 +6,12 @@
 
 * struct fpga_bridge - The FPGA Bridge structure
 * struct fpga_bridge_ops - Low level Bridge driver ops
-* fpga_bridge_register() - Create and register a bridge
+* __fpga_bridge_register() - Create and register a bridge
 * fpga_bridge_unregister() - Unregister a bridge
 
+The helper macro ``fpga_bridge_register()`` automatically sets
+the module that registers the FPGA bridge as the owner.
+
 .. kernel-doc:: include/linux/fpga/fpga-bridge.h
    :functions: fpga_bridge
 
@@ -16,7 +19,7 @@
    :functions: fpga_bridge_ops
 
 .. kernel-doc:: drivers/fpga/fpga-bridge.c
-   :functions: fpga_bridge_register
+   :functions: __fpga_bridge_register
 
 .. kernel-doc:: drivers/fpga/fpga-bridge.c
    :functions: fpga_bridge_unregister
--- linux-qcom-6.8.0.orig/Documentation/driver-api/fpga/fpga-mgr.rst
+++ linux-qcom-6.8.0/Documentation/driver-api/fpga/fpga-mgr.rst
@@ -24,7 +24,8 @@
 --------------------------------
 
 To add another FPGA manager, write a driver that implements a set of ops.  The
-probe function calls fpga_mgr_register() or fpga_mgr_register_full(), such as::
+probe function calls ``fpga_mgr_register()`` or ``fpga_mgr_register_full()``,
+such as::
 
 	static const struct fpga_manager_ops socfpga_fpga_ops = {
 		.write_init = socfpga_fpga_ops_configure_init,
@@ -69,10 +70,11 @@
 	}
 
 Alternatively, the probe function could call one of the resource managed
-register functions, devm_fpga_mgr_register() or devm_fpga_mgr_register_full().
-When these functions are used, the parameter syntax is the same, but the call
-to fpga_mgr_unregister() should be removed. In the above example, the
-socfpga_fpga_remove() function would not be required.
+register functions, ``devm_fpga_mgr_register()`` or
+``devm_fpga_mgr_register_full()``.  When these functions are used, the
+parameter syntax is the same, but the call to ``fpga_mgr_unregister()`` should be
+removed. In the above example, the ``socfpga_fpga_remove()`` function would not be
+required.
 
 The ops will implement whatever device specific register writes are needed to
 do the programming sequence for this particular FPGA.  These ops return 0 for
@@ -125,15 +127,19 @@
 * struct fpga_manager -  the FPGA manager struct
 * struct fpga_manager_ops -  Low level FPGA manager driver ops
 * struct fpga_manager_info -  Parameter structure for fpga_mgr_register_full()
-* fpga_mgr_register_full() -  Create and register an FPGA manager using the
+* __fpga_mgr_register_full() -  Create and register an FPGA manager using the
   fpga_mgr_info structure to provide the full flexibility of options
-* fpga_mgr_register() -  Create and register an FPGA manager using standard
+* __fpga_mgr_register() -  Create and register an FPGA manager using standard
   arguments
-* devm_fpga_mgr_register_full() -  Resource managed version of
-  fpga_mgr_register_full()
-* devm_fpga_mgr_register() -  Resource managed version of fpga_mgr_register()
+* __devm_fpga_mgr_register_full() -  Resource managed version of
+  __fpga_mgr_register_full()
+* __devm_fpga_mgr_register() -  Resource managed version of __fpga_mgr_register()
 * fpga_mgr_unregister() -  Unregister an FPGA manager
 
+Helper macros ``fpga_mgr_register_full()``, ``fpga_mgr_register()``,
+``devm_fpga_mgr_register_full()``, and ``devm_fpga_mgr_register()`` are available
+to ease the registration.
+
 .. kernel-doc:: include/linux/fpga/fpga-mgr.h
    :functions: fpga_mgr_states
 
@@ -147,16 +153,16 @@
    :functions: fpga_manager_info
 
 .. kernel-doc:: drivers/fpga/fpga-mgr.c
-   :functions: fpga_mgr_register_full
+   :functions: __fpga_mgr_register_full
 
 .. kernel-doc:: drivers/fpga/fpga-mgr.c
-   :functions: fpga_mgr_register
+   :functions: __fpga_mgr_register
 
 .. kernel-doc:: drivers/fpga/fpga-mgr.c
-   :functions: devm_fpga_mgr_register_full
+   :functions: __devm_fpga_mgr_register_full
 
 .. kernel-doc:: drivers/fpga/fpga-mgr.c
-   :functions: devm_fpga_mgr_register
+   :functions: __devm_fpga_mgr_register
 
 .. kernel-doc:: drivers/fpga/fpga-mgr.c
    :functions: fpga_mgr_unregister
--- linux-qcom-6.8.0.orig/Documentation/driver-api/fpga/fpga-region.rst
+++ linux-qcom-6.8.0/Documentation/driver-api/fpga/fpga-region.rst
@@ -46,13 +46,16 @@
 ----------------------------
 
 * struct fpga_region - The FPGA region struct
-* struct fpga_region_info - Parameter structure for fpga_region_register_full()
-* fpga_region_register_full() -  Create and register an FPGA region using the
+* struct fpga_region_info - Parameter structure for __fpga_region_register_full()
+* __fpga_region_register_full() -  Create and register an FPGA region using the
   fpga_region_info structure to provide the full flexibility of options
-* fpga_region_register() -  Create and register an FPGA region using standard
+* __fpga_region_register() -  Create and register an FPGA region using standard
   arguments
 * fpga_region_unregister() -  Unregister an FPGA region
 
+Helper macros ``fpga_region_register()`` and ``fpga_region_register_full()``
+automatically set the module that registers the FPGA region as the owner.
+
 The FPGA region's probe function will need to get a reference to the FPGA
 Manager it will be using to do the programming.  This usually would happen
 during the region's probe function.
@@ -82,10 +85,10 @@
    :functions: fpga_region_info
 
 .. kernel-doc:: drivers/fpga/fpga-region.c
-   :functions: fpga_region_register_full
+   :functions: __fpga_region_register_full
 
 .. kernel-doc:: drivers/fpga/fpga-region.c
-   :functions: fpga_region_register
+   :functions: __fpga_region_register
 
 .. kernel-doc:: drivers/fpga/fpga-region.c
    :functions: fpga_region_unregister
--- linux-qcom-6.8.0.orig/Documentation/driver-api/ipmi.rst
+++ linux-qcom-6.8.0/Documentation/driver-api/ipmi.rst
@@ -540,7 +540,7 @@
 	alerts_broken
 
 The addresses are normal I2C addresses.  The adapter is the string
-name of the adapter, as shown in /sys/class/i2c-adapter/i2c-<n>/name.
+name of the adapter, as shown in /sys/bus/i2c/devices/i2c-<n>/name.
 It is *NOT* i2c-<n> itself.  Also, the comparison is done ignoring
 spaces, so if the name is "This is an I2C chip" you can say
 adapter_name=ThisisanI2cchip.  This is because it's hard to pass in
--- linux-qcom-6.8.0.orig/Documentation/driver-api/soundwire/stream.rst
+++ linux-qcom-6.8.0/Documentation/driver-api/soundwire/stream.rst
@@ -324,12 +324,12 @@
 
   int sdw_stream_add_master(struct sdw_bus * bus,
 		struct sdw_stream_config * stream_config,
-		struct sdw_ports_config * ports_config,
+		const struct sdw_ports_config * ports_config,
 		struct sdw_stream_runtime * stream);
 
   int sdw_stream_add_slave(struct sdw_slave * slave,
 		struct sdw_stream_config * stream_config,
-		struct sdw_ports_config * ports_config,
+		const struct sdw_ports_config * ports_config,
 		struct sdw_stream_runtime * stream);
 
 
--- linux-qcom-6.8.0.orig/Documentation/filesystems/f2fs.rst
+++ linux-qcom-6.8.0/Documentation/filesystems/f2fs.rst
@@ -126,9 +126,7 @@
 discard/nodiscard	 Enable/disable real-time discard in f2fs, if discard is
 			 enabled, f2fs will issue discard/TRIM commands when a
 			 segment is cleaned.
-no_heap			 Disable heap-style segment allocation which finds free
-			 segments for data from the beginning of main area, while
-			 for node from the end of main area.
+heap/no_heap		 Deprecated.
 nouser_xattr		 Disable Extended User Attributes. Note: xattr is enabled
 			 by default if CONFIG_F2FS_FS_XATTR is selected.
 noacl			 Disable POSIX Access Control List. Note: acl is enabled
@@ -228,8 +226,6 @@
 			 option for more randomness.
 			 Please, use these options for your experiments and we strongly
 			 recommend to re-format the filesystem after using these options.
-io_bits=%u		 Set the bit size of write IO requests. It should be set
-			 with "mode=lfs".
 usrquota		 Enable plain user disk quota accounting.
 grpquota		 Enable plain group disk quota accounting.
 prjquota		 Enable plain project quota accounting.
--- linux-qcom-6.8.0.orig/Documentation/filesystems/fscrypt.rst
+++ linux-qcom-6.8.0/Documentation/filesystems/fscrypt.rst
@@ -70,7 +70,7 @@
 --------------
 
 fscrypt (and storage encryption in general) can only provide limited
-protection, if any at all, against online attacks.  In detail:
+protection against online attacks.  In detail:
 
 Side-channel attacks
 ~~~~~~~~~~~~~~~~~~~~
@@ -99,16 +99,23 @@
 be enforced by kernel *code* and therefore would be largely redundant
 with the wide variety of access control mechanisms already available.)
 
-Kernel memory compromise
-~~~~~~~~~~~~~~~~~~~~~~~~
+Read-only kernel memory compromise
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-An attacker who compromises the system enough to read from arbitrary
-memory, e.g. by mounting a physical attack or by exploiting a kernel
-security vulnerability, can compromise all encryption keys that are
-currently in use.
+Unless `hardware-wrapped keys`_ are used, an attacker who gains the
+ability to read from arbitrary kernel memory, e.g. by mounting a
+physical attack or by exploiting a kernel security vulnerability, can
+compromise all fscrypt keys that are currently in-use.  This also
+extends to cold boot attacks; if the system is suddenly powered off,
+keys the system was using may remain in memory for a short time.
+
+However, if hardware-wrapped keys are used, then the fscrypt master
+keys and file contents encryption keys (but not other types of fscrypt
+subkeys such as filenames encryption keys) are protected from
+compromises of arbitrary kernel memory.
 
-However, fscrypt allows encryption keys to be removed from the kernel,
-which may protect them from later compromise.
+In addition, fscrypt allows encryption keys to be removed from the
+kernel, which may protect them from later compromise.
 
 In more detail, the FS_IOC_REMOVE_ENCRYPTION_KEY ioctl (or the
 FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS ioctl) can wipe a master
@@ -145,6 +152,24 @@
   accelerator hardware (if used by the crypto API to implement any of
   the algorithms), or in other places not explicitly considered here.
 
+Full system compromise
+~~~~~~~~~~~~~~~~~~~~~~
+
+An attacker who gains "root" access and/or the ability to execute
+arbitrary kernel code can freely exfiltrate data that is protected by
+any in-use fscrypt keys.  Thus, usually fscrypt provides no meaningful
+protection in this scenario.  (Data that is protected by a key that is
+absent throughout the entire attack remains protected, modulo the
+limitations of key removal mentioned above in the case where the key
+was removed prior to the attack.)
+
+However, if `hardware-wrapped keys`_ are used, such attackers will be
+unable to exfiltrate the master keys or file contents keys in a form
+that will be usable after the system is powered off.  This may be
+useful if the attacker is significantly time-limited and/or
+bandwidth-limited, so they can only exfiltrate some data and need to
+rely on a later offline attack to exfiltrate the rest of it.
+
 Limitations of v1 policies
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -171,6 +196,11 @@
 Key hierarchy
 =============
 
+Note: this section assumes the use of standard keys (i.e. "software
+keys") rather than hardware-wrapped keys.  The use of hardware-wrapped
+keys modifies the key hierarchy slightly.  For details, see the
+`Hardware-wrapped keys`_ section.
+
 Master Keys
 -----------
 
@@ -611,6 +641,8 @@
     policies`_.
   - FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32: See `IV_INO_LBLK_32
     policies`_.
+  - FSCRYPT_POLICY_FLAG_HW_WRAPPED_KEY: This flag denotes that this
+    policy uses a hardware-wrapped key.  See `Hardware-wrapped keys`_.
 
   v1 encryption policies only support the PAD_* and DIRECT_KEY flags.
   The other flags are only supported by v2 encryption policies.
@@ -833,7 +865,8 @@
             struct fscrypt_key_specifier key_spec;
             __u32 raw_size;
             __u32 key_id;
-            __u32 __reserved[8];
+            __u32 flags;
+            __u32 __reserved[7];
             __u8 raw[];
     };
 
@@ -852,7 +885,7 @@
 
     struct fscrypt_provisioning_key_payload {
             __u32 type;
-            __u32 __reserved;
+            __u32 flags;
             __u8 raw[];
     };
 
@@ -880,6 +913,12 @@
   Alternatively, if ``key_id`` is nonzero, this field must be 0, since
   in that case the size is implied by the specified Linux keyring key.
 
+- ``flags`` contains optional flags from ``<linux/fscrypt.h>``:
+
+  - FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED: This denotes that the key is a
+    hardware-wrapped key.  See `Hardware-wrapped keys`_.  This flag
+    can't be used if FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR is used.
+
 - ``key_id`` is 0 if the raw key is given directly in the ``raw``
   field.  Otherwise ``key_id`` is the ID of a Linux keyring key of
   type "fscrypt-provisioning" whose payload is
@@ -921,6 +960,8 @@
   caller does not have the CAP_SYS_ADMIN capability in the initial
   user namespace; or the raw key was specified by Linux key ID but the
   process lacks Search permission on the key.
+- ``EBADMSG``: FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED was specified, but the
+  key isn't a valid hardware-wrapped key
 - ``EDQUOT``: the key quota for this user would be exceeded by adding
   the key
 - ``EINVAL``: invalid key size or key specifier type, or reserved bits
@@ -932,7 +973,9 @@
 - ``ENOTTY``: this type of filesystem does not implement encryption
 - ``EOPNOTSUPP``: the kernel was not configured with encryption
   support for this filesystem, or the filesystem superblock has not
-  had encryption enabled on it
+  had encryption enabled on it, or FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED was
+  specified but the filesystem and/or the hardware doesn't support
+  hardware-wrapped keys
 
 Legacy method
 ~~~~~~~~~~~~~
@@ -995,9 +1038,8 @@
 These ioctls don't work on keys that were added via the legacy
 process-subscribed keyrings mechanism.
 
-Before using these ioctls, read the `Kernel memory compromise`_
-section for a discussion of the security goals and limitations of
-these ioctls.
+Before using these ioctls, read the `Online attacks`_ section for a
+discussion of the security goals and limitations of these ioctls.
 
 FS_IOC_REMOVE_ENCRYPTION_KEY
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1317,7 +1359,8 @@
 (e.g. support for the needed encryption algorithm and data unit size)
 and where blk-crypto-fallback is unusable.  (For blk-crypto-fallback
 to be usable, it must be enabled in the kernel configuration with
-CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y.)
+CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y, and the file must be
+protected by a standard key rather than a hardware-wrapped key.)
 
 Currently fscrypt always uses the filesystem block size (which is
 usually 4096 bytes) as the data unit size.  Therefore, it can only use
@@ -1325,7 +1368,84 @@
 
 Inline encryption doesn't affect the ciphertext or other aspects of
 the on-disk format, so users may freely switch back and forth between
-using "inlinecrypt" and not using "inlinecrypt".
+using "inlinecrypt" and not using "inlinecrypt".  An exception is that
+files that are protected by a hardware-wrapped key can only be
+encrypted/decrypted by the inline encryption hardware and therefore
+can only be accessed when the "inlinecrypt" mount option is used.  For
+more information about hardware-wrapped keys, see below.
+
+Hardware-wrapped keys
+---------------------
+
+fscrypt supports using *hardware-wrapped keys* when the inline
+encryption hardware supports it.  Such keys are only present in kernel
+memory in wrapped (encrypted) form; they can only be unwrapped
+(decrypted) by the inline encryption hardware and are temporally bound
+to the current boot.  This prevents the keys from being compromised if
+kernel memory is leaked.  This is done without limiting the number of
+keys that can be used and while still allowing the execution of
+cryptographic tasks that are tied to the same key but can't use inline
+encryption hardware, e.g. filenames encryption.
+
+Note that hardware-wrapped keys aren't specific to fscrypt; they are a
+block layer feature (part of *blk-crypto*).  For more details about
+hardware-wrapped keys, see the block layer documentation at
+:ref:`Documentation/block/inline-encryption.rst
+<hardware_wrapped_keys>`.  Below, we just focus on the details of how
+fscrypt can use hardware-wrapped keys.
+
+fscrypt supports hardware-wrapped keys by allowing the fscrypt master
+keys to be hardware-wrapped keys as an alternative to standard keys.
+To add a hardware-wrapped key with `FS_IOC_ADD_ENCRYPTION_KEY`_,
+userspace must specify FSCRYPT_ADD_KEY_FLAG_HW_WRAPPED in the
+``flags`` field of struct fscrypt_add_key_arg and also in the
+``flags`` field of struct fscrypt_provisioning_key_payload when
+applicable.  The key must be in ephemerally-wrapped form, not
+long-term wrapped form.
+
+To specify that files will be protected by a hardware-wrapped key,
+userspace must specify FSCRYPT_POLICY_FLAG_HW_WRAPPED_KEY in the
+encryption policy.  (Note that this flag is somewhat redundant, as the
+encryption policy also contains the key identifier, and
+hardware-wrapped keys and standard keys will have different key
+identifiers.  However, it is sometimes helpful to make it explicit
+that an encryption policy is supposed to use a hardware-wrapped key.)
+
+Some limitations apply.  First, files protected by a hardware-wrapped
+key are tied to the system's inline encryption hardware.  Therefore
+they can only be accessed when the "inlinecrypt" mount option is used,
+and they can't be included in portable filesystem images.  Second,
+currently the hardware-wrapped key support is only compatible with
+`IV_INO_LBLK_64 policies`_ and `IV_INO_LBLK_32 policies`_, as it
+assumes that there is just one file contents encryption key per
+fscrypt master key rather than one per file.  Future work may address
+this limitation by passing per-file nonces down the storage stack to
+allow the hardware to derive per-file keys.
+
+Implementation-wise, to encrypt/decrypt the contents of files that are
+protected by a hardware-wrapped key, fscrypt uses blk-crypto,
+attaching the hardware-wrapped key to the bio crypt contexts.  As is
+the case with standard keys, the block layer will program the key into
+a keyslot when it isn't already in one.  However, when programming a
+hardware-wrapped key, the hardware doesn't program the given key
+directly into a keyslot but rather unwraps it (using the hardware's
+ephemeral wrapping key) and derives the inline encryption key from it.
+The inline encryption key is the key that actually gets programmed
+into a keyslot, and it is never exposed to software.
+
+However, fscrypt doesn't just do file contents encryption; it also
+uses its master keys to derive filenames encryption keys, key
+identifiers, and sometimes some more obscure types of subkeys such as
+dirhash keys.  So even with file contents encryption out of the
+picture, fscrypt still needs a raw key to work with.  To get such a
+key from a hardware-wrapped key, fscrypt asks the inline encryption
+hardware to derive a cryptographically isolated "software secret" from
+the hardware-wrapped key.  fscrypt uses this "software secret" to key
+its KDF to derive all subkeys other than file contents keys.
+
+Note that this implies that the hardware-wrapped key feature only
+protects the file contents encryption keys.  It doesn't protect other
+fscrypt subkeys such as filenames encryption keys.
 
 Direct I/O support
 ==================
--- linux-qcom-6.8.0.orig/Documentation/filesystems/mount_api.rst
+++ linux-qcom-6.8.0/Documentation/filesystems/mount_api.rst
@@ -645,6 +645,8 @@
 	fs_param_is_blockdev	Blockdev path		* Needs lookup
 	fs_param_is_path	Path			* Needs lookup
 	fs_param_is_fd		File descriptor		result->int_32
+	fs_param_is_uid		User ID (u32)           result->uid
+	fs_param_is_gid		Group ID (u32)          result->gid
 	=======================	=======================	=====================
 
      Note that if the value is of fs_param_is_bool type, fs_parse() will try
@@ -678,6 +680,8 @@
 	fsparam_bdev()		fs_param_is_blockdev
 	fsparam_path()		fs_param_is_path
 	fsparam_fd()		fs_param_is_fd
+	fsparam_uid()		fs_param_is_uid
+	fsparam_gid()		fs_param_is_gid
 	=======================	===============================================
 
      all of which take two arguments, name string and option number - for
@@ -766,7 +770,8 @@
 
    * ::
 
-       bool fs_validate_description(const struct fs_parameter_description *desc);
+       bool fs_validate_description(const char *name,
+                                    const struct fs_parameter_description *desc);
 
      This performs some validation checks on a parameter description.  It
      returns true if the description is good and false if it is not.  It will
@@ -784,8 +789,9 @@
      option number (which it returns).
 
      If successful, and if the parameter type indicates the result is a
-     boolean, integer or enum type, the value is converted by this function and
-     the result stored in result->{boolean,int_32,uint_32,uint_64}.
+     boolean, integer, enum, uid, or gid type, the value is converted by this
+     function and the result stored in
+     result->{boolean,int_32,uint_32,uint_64,uid,gid}.
 
      If a match isn't initially made, the key is prefixed with "no" and no
      value is present then an attempt will be made to look up the key with the
--- linux-qcom-6.8.0.orig/Documentation/gpu/drm-kms-helpers.rst
+++ linux-qcom-6.8.0/Documentation/gpu/drm-kms-helpers.rst
@@ -224,6 +224,9 @@
 .. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c
    :export:
 
+.. kernel-doc:: drivers/gpu/drm/drm_panel_backlight_quirks.c
+   :export:
+
 Panel Self Refresh Helper Reference
 ===================================
 
--- linux-qcom-6.8.0.orig/Documentation/hwmon/corsair-psu.rst
+++ linux-qcom-6.8.0/Documentation/hwmon/corsair-psu.rst
@@ -15,11 +15,11 @@
 
   Corsair HX850i
 
-  Corsair HX1000i (Series 2022 and 2023)
+  Corsair HX1000i (Legacy and Series 2023)
 
-  Corsair HX1200i
+  Corsair HX1200i (Legacy and Series 2023)
 
-  Corsair HX1500i (Series 2022 and 2023)
+  Corsair HX1500i (Legacy and Series 2023)
 
   Corsair RM550i
 
--- linux-qcom-6.8.0.orig/Documentation/i2c/busses/i2c-i801.rst
+++ linux-qcom-6.8.0/Documentation/i2c/busses/i2c-i801.rst
@@ -48,6 +48,8 @@
   * Intel Raptor Lake (PCH)
   * Intel Meteor Lake (SOC and PCH)
   * Intel Birch Stream (SOC)
+  * Intel Arrow Lake (SOC)
+  * Intel Panther Lake (SOC)
 
    Datasheets: Publicly available at the Intel website
 
--- linux-qcom-6.8.0.orig/Documentation/kbuild/modules.rst
+++ linux-qcom-6.8.0/Documentation/kbuild/modules.rst
@@ -128,7 +128,7 @@
 
 	modules_install
 		Install the external module(s). The default location is
-		/lib/modules/<kernel_release>/extra/, but a prefix may
+		/lib/modules/<kernel_release>/updates/, but a prefix may
 		be added with INSTALL_MOD_PATH (discussed in section 5).
 
 	clean
@@ -417,7 +417,7 @@
 
 And external modules are installed in:
 
-	/lib/modules/$(KERNELRELEASE)/extra/
+	/lib/modules/$(KERNELRELEASE)/updates/
 
 5.1 INSTALL_MOD_PATH
 --------------------
@@ -438,10 +438,10 @@
 -------------------
 
 	External modules are by default installed to a directory under
-	/lib/modules/$(KERNELRELEASE)/extra/, but you may wish to
+	/lib/modules/$(KERNELRELEASE)/updates/, but you may wish to
 	locate modules for a specific functionality in a separate
 	directory. For this purpose, use INSTALL_MOD_DIR to specify an
-	alternative name to "extra."::
+	alternative name to "updates."::
 
 		$ make INSTALL_MOD_DIR=gandalf -C $KDIR \
 		       M=$PWD modules_install
--- linux-qcom-6.8.0.orig/Documentation/locking/hwspinlock.rst
+++ linux-qcom-6.8.0/Documentation/locking/hwspinlock.rst
@@ -87,6 +87,17 @@
 
 ::
 
+  int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id);
+
+After verifying the owner of the hwspinlock, release a previously acquired
+hwspinlock; returns 0 on success, or an appropriate error code on failure
+(e.g. -EOPNOTSUPP if the bust operation is not defined for the specific
+hwspinlock).
+
+Should be called from a process context (might sleep).
+
+::
+
   int hwspin_lock_timeout(struct hwspinlock *hwlock, unsigned int timeout);
 
 Lock a previously-assigned hwspinlock with a timeout limit (specified in
--- linux-qcom-6.8.0.orig/Documentation/locking/seqlock.rst
+++ linux-qcom-6.8.0/Documentation/locking/seqlock.rst
@@ -153,7 +153,7 @@
 from interruption by readers. This is typically the case when the read
 side can be invoked from NMI handlers.
 
-Check `raw_write_seqcount_latch()` for more information.
+Check `write_seqcount_latch()` for more information.
 
 
 .. _seqlock_t:
--- linux-qcom-6.8.0.orig/Documentation/mm/arch_pgtable_helpers.rst
+++ linux-qcom-6.8.0/Documentation/mm/arch_pgtable_helpers.rst
@@ -140,7 +140,8 @@
 +---------------------------+--------------------------------------------------+
 | pmd_swp_clear_soft_dirty  | Clears a soft dirty swapped PMD                  |
 +---------------------------+--------------------------------------------------+
-| pmd_mkinvalid             | Invalidates a mapped PMD [1]                     |
+| pmd_mkinvalid             | Invalidates a present PMD; do not call for       |
+|                           | non-present PMD [1]                              |
 +---------------------------+--------------------------------------------------+
 | pmd_set_huge              | Creates a PMD huge mapping                       |
 +---------------------------+--------------------------------------------------+
@@ -196,7 +197,8 @@
 +---------------------------+--------------------------------------------------+
 | pud_mkdevmap              | Creates a ZONE_DEVICE mapped PUD                 |
 +---------------------------+--------------------------------------------------+
-| pud_mkinvalid             | Invalidates a mapped PUD [1]                     |
+| pud_mkinvalid             | Invalidates a present PUD; do not call for       |
+|                           | non-present PUD [1]                              |
 +---------------------------+--------------------------------------------------+
 | pud_set_huge              | Creates a PUD huge mapping                       |
 +---------------------------+--------------------------------------------------+
--- linux-qcom-6.8.0.orig/Documentation/mm/page_table_check.rst
+++ linux-qcom-6.8.0/Documentation/mm/page_table_check.rst
@@ -14,7 +14,7 @@
 accessible from the userspace by getting their page table entries (PTEs PMDs
 etc.) added into the table.
 
-In case of detected corruption, the kernel is crashed. There is a small
+In case of most detected corruption, the kernel is crashed. There is a small
 performance and memory overhead associated with the page table check. Therefore,
 it is disabled by default, but can be optionally enabled on systems where the
 extra hardening outweighs the performance costs. Also, because page table check
@@ -22,6 +22,13 @@
 by crashing kernel at the time wrong mapping occurs instead of later which is
 often the case with memory corruptions bugs.
 
+It can also be used to do page table entry checks over various flags, dump
+warnings when illegal combinations of entry flags are detected.  Currently,
+userfaultfd is the only user of such to sanity check wr-protect bit against
+any writable flags.  Illegal flag combinations will not directly cause data
+corruption in this case immediately, but that will cause read-only data to
+be writable, leading to corrupt when the page content is later modified.
+
 Double mapping detection logic
 ==============================
 
--- linux-qcom-6.8.0.orig/Documentation/netlink/specs/devlink.yaml
+++ linux-qcom-6.8.0/Documentation/netlink/specs/devlink.yaml
@@ -290,7 +290,7 @@
         enum: eswitch-mode
       -
         name: eswitch-inline-mode
-        type: u16
+        type: u8
         enum: eswitch-inline-mode
       -
         name: dpipe-tables
--- linux-qcom-6.8.0.orig/Documentation/netlink/specs/dpll.yaml
+++ linux-qcom-6.8.0/Documentation/netlink/specs/dpll.yaml
@@ -274,6 +274,7 @@
       -
         name: capabilities
         type: u32
+        enum: pin-capabilities
       -
         name: parent-device
         type: nest
@@ -306,6 +307,26 @@
           Value is in PPM (parts per million).
           This may be implemented for example for pin of type
           PIN_TYPE_SYNCE_ETH_PORT.
+      -
+        name: esync-frequency
+        type: u64
+        doc: |
+          Frequency of Embedded SYNC signal. If provided, the pin is configured
+          with a SYNC signal embedded into its base clock frequency.
+      -
+        name: esync-frequency-supported
+        type: nest
+        multi-attr: true
+        nested-attributes: frequency-range
+        doc: |
+          If provided a pin is capable of embedding a SYNC signal (within given
+          range) into its base frequency signal.
+      -
+        name: esync-pulse
+        type: u32
+        doc: |
+          A ratio of high to low state of a SYNC signal pulse embedded
+          into base clock frequency. Value is in percents.
   -
     name: pin-parent-device
     subset-of: pin
@@ -469,6 +490,9 @@
             - phase-adjust-max
             - phase-adjust
             - fractional-frequency-offset
+            - esync-frequency
+            - esync-frequency-supported
+            - esync-pulse
 
       dump:
         request:
@@ -495,6 +519,7 @@
             - parent-device
             - parent-pin
             - phase-adjust
+            - esync-frequency
     -
       name: pin-create-ntf
       doc: Notification about pin appearing
--- linux-qcom-6.8.0.orig/Documentation/netlink/specs/ethtool.yaml
+++ linux-qcom-6.8.0/Documentation/netlink/specs/ethtool.yaml
@@ -64,7 +64,12 @@
         name: bits
         type: nest
         nested-attributes: bitset-bits
-
+      -
+        name: value
+        type: binary
+      -
+        name: mask
+        type: binary
   -
     name: string
     attributes:
@@ -1594,6 +1599,7 @@
         request:
           attributes:
             - header
+            - context
         reply:
           attributes:
             - header
@@ -1602,7 +1608,6 @@
             - indir
             - hkey
             - input_xfrm
-      dump: *rss-get-op
     -
       name: plca-get-cfg
       doc: Get PLCA params.
--- linux-qcom-6.8.0.orig/Documentation/netlink/specs/mptcp_pm.yaml
+++ linux-qcom-6.8.0/Documentation/netlink/specs/mptcp_pm.yaml
@@ -109,7 +109,6 @@
       -
         name: port
         type: u16
-        byte-order: big-endian
       -
         name: flags
         type: u32
@@ -294,7 +293,6 @@
       doc: Get endpoint information
       attribute-set: endpoint
       dont-validate: [ strict ]
-      flags: [ uns-admin-perm ]
       do: &get-addr-attrs
         request:
           attributes:
--- linux-qcom-6.8.0.orig/Documentation/netlink/specs/rt_link.yaml
+++ linux-qcom-6.8.0/Documentation/netlink/specs/rt_link.yaml
@@ -1144,6 +1144,12 @@
       -
         name: mcast-querier-state
         type: binary
+      -
+        name: fdb-n-learned
+        type: u32
+      -
+        name: fdb-max-learned
+        type: u32
   -
     name: linkinfo-brport-attrs
     name-prefix: ifla-brport-
--- linux-qcom-6.8.0.orig/Documentation/networking/device_drivers/wwan/t7xx.rst
+++ linux-qcom-6.8.0/Documentation/networking/device_drivers/wwan/t7xx.rst
@@ -39,6 +39,34 @@
 
 - open the AT control channel using a UART tool or a special user tool
 
+Sysfs
+=====
+The driver provides sysfs interfaces to userspace.
+
+t7xx_mode
+---------
+The sysfs interface provides userspace with access to the device mode, this interface
+supports read and write operations.
+
+Device mode:
+
+- ``unknown`` represents that device in unknown status
+- ``ready`` represents that device in ready status
+- ``reset`` represents that device in reset status
+- ``fastboot_switching`` represents that device in fastboot switching status
+- ``fastboot_download`` represents that device in fastboot download status
+- ``fastboot_dump`` represents that device in fastboot dump status
+
+Read from userspace to get the current device mode.
+
+::
+  $ cat /sys/bus/pci/devices/${bdf}/t7xx_mode
+
+Write from userspace to set the device mode.
+
+::
+  $ echo fastboot_switching > /sys/bus/pci/devices/${bdf}/t7xx_mode
+
 Management application development
 ==================================
 The driver and userspace interfaces are described below. The MBIM protocol is
@@ -97,6 +125,20 @@
 The userspace end of the control port is a /dev/wwan0at0 character
 device. Application shall use this interface to issue AT commands.
 
+fastboot port userspace ABI
+---------------------------
+
+/dev/wwan0fastboot0 character device
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The driver exposes a fastboot protocol interface by implementing
+fastboot WWAN Port. The userspace end of the fastboot channel pipe is a
+/dev/wwan0fastboot0 character device. Application shall use this interface for
+fastboot protocol communication.
+
+Please note that driver needs to be reloaded to export /dev/wwan0fastboot0
+port, because device needs a cold reset after enter ``fastboot_switching``
+mode.
+
 The MediaTek's T700 modem supports the 3GPP TS 27.007 [4] specification.
 
 References
@@ -118,3 +160,7 @@
 [4] *Specification # 27.007 - 3GPP*
 
 - https://www.3gpp.org/DynaReport/27007.htm
+
+[5] *fastboot "a mechanism for communicating with bootloaders"*
+
+- https://android.googlesource.com/platform/system/core/+/refs/heads/main/fastboot/README.md
--- linux-qcom-6.8.0.orig/Documentation/networking/ethtool-netlink.rst
+++ linux-qcom-6.8.0/Documentation/networking/ethtool-netlink.rst
@@ -1771,6 +1771,7 @@
 
 =====================================  ======  ==========================
   ``ETHTOOL_A_RSS_HEADER``             nested  reply header
+  ``ETHTOOL_A_RSS_CONTEXT``            u32     context number
   ``ETHTOOL_A_RSS_HFUNC``              u32     RSS hash func
   ``ETHTOOL_A_RSS_INDIR``              binary  Indir table bytes
   ``ETHTOOL_A_RSS_HKEY``               binary  Hash key bytes
--- linux-qcom-6.8.0.orig/Documentation/networking/j1939.rst
+++ linux-qcom-6.8.0/Documentation/networking/j1939.rst
@@ -121,7 +121,7 @@
 
 On the other hand, when using PDU1 format, the PS-field contains a so-called
 Destination Address, which is _not_ part of the PGN. When communicating a PGN
-from user space to kernel (or vice versa) and PDU2 format is used, the PS-field
+from user space to kernel (or vice versa) and PDU1 format is used, the PS-field
 of the PGN shall be set to zero. The Destination Address shall be set
 elsewhere.
 
--- linux-qcom-6.8.0.orig/Documentation/networking/net_cachelines/net_device.rst
+++ linux-qcom-6.8.0/Documentation/networking/net_cachelines/net_device.rst
@@ -13,7 +13,7 @@
 unsigned_long                       mem_end                                                         
 unsigned_long                       mem_start                                                       
 unsigned_long                       base_addr                                                       
-unsigned_long                       state                                                           
+unsigned_long                       state                   read_mostly         read_mostly         netif_running(dev)
 struct_list_head                    dev_list                                                        
 struct_list_head                    napi_list                                                       
 struct_list_head                    unreg_list                                                      
@@ -98,7 +98,7 @@
 unsigned_int                        real_num_rx_queues      -                   read_mostly         get_rps_cpu
 struct_bpf_prog*                    xdp_prog                -                   read_mostly         netif_elide_gro()
 unsigned_long                       gro_flush_timeout       -                   read_mostly         napi_complete_done
-int                                 napi_defer_hard_irqs    -                   read_mostly         napi_complete_done
+u32                                 napi_defer_hard_irqs    -                   read_mostly         napi_complete_done
 unsigned_int                        gro_max_size            -                   read_mostly         skb_gro_receive
 unsigned_int                        gro_ipv4_max_size       -                   read_mostly         skb_gro_receive
 rx_handler_func_t*                  rx_handler              read_mostly         -                   __netif_receive_skb_core
--- linux-qcom-6.8.0.orig/Documentation/networking/sfp-phylink.rst
+++ linux-qcom-6.8.0/Documentation/networking/sfp-phylink.rst
@@ -207,6 +207,11 @@
    capabilities for ``interface`` to determine the allowable ethtool link
    modes.
 
+   The :c:func:`validate` method should mask the supplied supported mask,
+   and ``state->advertising`` with the supported ethtool link modes.
+   These are the new ethtool link modes, so bitmask operations must be
+   used. For an example, see ``drivers/net/ethernet/marvell/mvneta.c``.
+
    The :c:func:`mac_link_state` method is used to read the link state
    from the MAC, and report back the settings that the MAC is currently
    using. This is particularly important for in-band negotiation
--- linux-qcom-6.8.0.orig/Documentation/networking/xsk-tx-metadata.rst
+++ linux-qcom-6.8.0/Documentation/networking/xsk-tx-metadata.rst
@@ -11,12 +11,16 @@
 General Design
 ==============
 
-The headroom for the metadata is reserved via ``tx_metadata_len`` in
-``struct xdp_umem_reg``. The metadata length is therefore the same for
-every socket that shares the same umem. The metadata layout is a fixed UAPI,
-refer to ``union xsk_tx_metadata`` in ``include/uapi/linux/if_xdp.h``.
-Thus, generally, the ``tx_metadata_len`` field above should contain
-``sizeof(union xsk_tx_metadata)``.
+The headroom for the metadata is reserved via ``tx_metadata_len`` and
+``XDP_UMEM_TX_METADATA_LEN`` flag in ``struct xdp_umem_reg``. The metadata
+length is therefore the same for every socket that shares the same umem.
+The metadata layout is a fixed UAPI, refer to ``union xsk_tx_metadata`` in
+``include/uapi/linux/if_xdp.h``. Thus, generally, the ``tx_metadata_len``
+field above should contain ``sizeof(union xsk_tx_metadata)``.
+
+Note that in the original implementation the ``XDP_UMEM_TX_METADATA_LEN``
+flag was not required. Applications might attempt to create a umem
+with a flag first and if it fails, do another attempt without a flag.
 
 The headroom and the metadata itself should be located right before
 ``xdp_desc->addr`` in the umem frame. Within a frame, the metadata
--- linux-qcom-6.8.0.orig/Documentation/power/runtime_pm.rst
+++ linux-qcom-6.8.0/Documentation/power/runtime_pm.rst
@@ -347,7 +347,9 @@
 
   `int pm_runtime_resume_and_get(struct device *dev);`
     - run pm_runtime_resume(dev) and if successful, increment the device's
-      usage counter; return the result of pm_runtime_resume
+      usage counter; returns 0 on success (whether or not the device's
+      runtime PM status was already 'active') or the error code from
+      pm_runtime_resume() on failure.
 
   `int pm_request_idle(struct device *dev);`
     - submit a request to execute the subsystem-level idle callback for the
@@ -396,10 +398,9 @@
       nonzero, increment the counter and return 1; otherwise return 0 without
       changing the counter
 
-  `int pm_runtime_get_if_active(struct device *dev, bool ign_usage_count);`
+  `int pm_runtime_get_if_active(struct device *dev);`
     - return -EINVAL if 'power.disable_depth' is nonzero; otherwise, if the
-      runtime PM status is RPM_ACTIVE, and either ign_usage_count is true
-      or the device's usage_count is non-zero, increment the counter and
+      runtime PM status is RPM_ACTIVE, increment the counter and
       return 1; otherwise return 0 without changing the counter
 
   `void pm_runtime_put_noidle(struct device *dev);`
--- linux-qcom-6.8.0.orig/Documentation/process/changes.rst
+++ linux-qcom-6.8.0/Documentation/process/changes.rst
@@ -31,7 +31,7 @@
 ====================== ===============  ========================================
 GNU C                  5.1              gcc --version
 Clang/LLVM (optional)  11.0.0           clang --version
-Rust (optional)        1.74.1           rustc --version
+Rust (optional)        1.75.0           rustc --version
 bindgen (optional)     0.65.1           bindgen --version
 GNU make               3.82             make --version
 bash                   4.2              bash --version
--- linux-qcom-6.8.0.orig/Documentation/sphinx/cdomain.py
+++ linux-qcom-6.8.0/Documentation/sphinx/cdomain.py
@@ -37,12 +37,29 @@
 
 import sphinx
 from sphinx import addnodes
-from sphinx.domains.c import c_funcptr_sig_re, c_sig_re
 from sphinx.domains.c import CObject as Base_CObject
 from sphinx.domains.c import CDomain as Base_CDomain
 from itertools import chain
 import re
 
+# fixes https://github.com/sphinx-doc/sphinx/commit/0f49e30c51b5cc5055cda5b4b294c2dd9d1df573#r38750737
+
+# pylint: disable=invalid-name
+c_sig_re = re.compile(
+    r'''^([^(]*?)          # return type
+        ([\w:.]+)  \s*     # thing name (colon allowed for C++)
+        (?: \((.*)\) )?    # optionally arguments
+        (\s+const)? $      # const specifier
+    ''', re.VERBOSE)
+
+c_funcptr_sig_re = re.compile(
+    r'''^([^(]+?)          # return type
+        (\( [^()]+ \)) \s* # name in parentheses
+        \( (.*) \)         # arguments
+        (\s+const)? $      # const specifier
+    ''', re.VERBOSE)
+# pylint: enable=invalid-name
+
 __version__  = '1.1'
 
 # Get Sphinx version
--- linux-qcom-6.8.0.orig/Documentation/sphinx/kernel_include.py
+++ linux-qcom-6.8.0/Documentation/sphinx/kernel_include.py
@@ -97,7 +97,6 @@
         # HINT: this is the only line I had to change / commented out:
         #path = utils.relative_path(None, path)
 
-        path = nodes.reprunicode(path)
         encoding = self.options.get(
             'encoding', self.state.document.settings.input_encoding)
         e_handler=self.state.document.settings.input_encoding_error_handler
--- linux-qcom-6.8.0.orig/Documentation/sphinx/kerneldoc.py
+++ linux-qcom-6.8.0/Documentation/sphinx/kerneldoc.py
@@ -61,9 +61,9 @@
         env = self.state.document.settings.env
         cmd = [env.config.kerneldoc_bin, '-rst', '-enable-lineno']
 
-	# Pass the version string to kernel-doc, as it needs to use a different
-	# dialect, depending what the C domain supports for each specific
-	# Sphinx versions
+        # Pass the version string to kernel-doc, as it needs to use a different
+        # dialect, depending what the C domain supports for each specific
+        # Sphinx versions
         cmd += ['-sphinx-version', sphinx.__version__]
 
         filename = env.config.kerneldoc_srctree + '/' + self.arguments[0]
--- linux-qcom-6.8.0.orig/Documentation/userspace-api/ioctl/ioctl-number.rst
+++ linux-qcom-6.8.0/Documentation/userspace-api/ioctl/ioctl-number.rst
@@ -82,8 +82,8 @@
 0x10  00-0F  drivers/char/s390/vmcp.h
 0x10  10-1F  arch/s390/include/uapi/sclp_ctl.h
 0x10  20-2F  arch/s390/include/uapi/asm/hypfs.h
-0x12  all    linux/fs.h
-             linux/blkpg.h
+0x12  all    linux/fs.h, linux/blkpg.h, linux/blkzoned.h,
+             linux/blk-crypto.h
 0x1b  all                                                            InfiniBand Subsystem
                                                                      <http://infiniband.sourceforge.net/>
 0x20  all    drivers/cdrom/cm206.h
@@ -136,6 +136,7 @@
 'F'   DD     video/sstfb.h                                           conflict!
 'G'   00-3F  drivers/misc/sgi-gru/grulib.h                           conflict!
 'G'   00-0F  xen/gntalloc.h, xen/gntdev.h                            conflict!
+'G'   00-0F  linux/gunyah.h                                          conflict!
 'H'   00-7F  linux/hiddev.h                                          conflict!
 'H'   00-0F  linux/hidraw.h                                          conflict!
 'H'   01     linux/mei.h                                             conflict!
--- linux-qcom-6.8.0.orig/Documentation/userspace-api/media/mediactl/media-types.rst
+++ linux-qcom-6.8.0/Documentation/userspace-api/media/mediactl/media-types.rst
@@ -375,12 +375,11 @@
 	  are origins of links.
 
     *  -  ``MEDIA_PAD_FL_MUST_CONNECT``
-       -  If this flag is set and the pad is linked to any other pad, then
-	  at least one of those links must be enabled for the entity to be
-	  able to stream. There could be temporary reasons (e.g. device
-	  configuration dependent) for the pad to need enabled links even
-	  when this flag isn't set; the absence of the flag doesn't imply
-	  there is none.
+       -  If this flag is set, then for this pad to be able to stream, it must
+	  be connected by at least one enabled link. There could be temporary
+	  reasons (e.g. device configuration dependent) for the pad to need
+	  enabled links even when this flag isn't set; the absence of the flag
+	  doesn't imply there is none.
 
 
 One and only one of ``MEDIA_PAD_FL_SINK`` and ``MEDIA_PAD_FL_SOURCE``
--- linux-qcom-6.8.0.orig/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
+++ linux-qcom-6.8.0/Documentation/userspace-api/media/v4l/ext-ctrls-codec.rst
@@ -576,6 +576,8 @@
       - Constant bitrate
     * - ``V4L2_MPEG_VIDEO_BITRATE_MODE_CQ``
       - Constant quality
+    * - ``V4L2_MPEG_VIDEO_BITRATE_MODE_MBR``
+      - Maximum bitrate
 
 
 
--- linux-qcom-6.8.0.orig/Documentation/virt/gunyah/index.rst
+++ linux-qcom-6.8.0/Documentation/virt/gunyah/index.rst
@@ -0,0 +1,114 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================
+Gunyah Hypervisor
+=================
+
+.. toctree::
+   :maxdepth: 1
+
+   vm-manager
+   message-queue
+
+Gunyah is a Type-1 hypervisor which is independent of any OS kernel, and runs in
+a higher CPU privilege level. It does not depend on any lower-privileged operating system
+for its core functionality. This increases its security and can support a much smaller
+trusted computing base than a Type-2 hypervisor.
+
+Gunyah is an open source hypervisor. The source repo is available at
+https://github.com/quic/gunyah-hypervisor.
+
+Gunyah provides these following features.
+
+- Scheduling:
+
+  A scheduler for virtual CPUs (vCPUs) on physical CPUs enables time-sharing
+  of the CPUs. Gunyah supports two models of scheduling:
+
+    1. "Behind the back" scheduling in which Gunyah hypervisor schedules vCPUS on its own.
+    2. "Proxy" scheduling in which a delegated VM can donate part of one of its vCPU slice
+       to another VM's vCPU via a hypercall.
+
+- Memory Management:
+
+  APIs handling memory, abstracted as objects, limiting direct use of physical
+  addresses. Memory ownership and usage tracking of all memory under its control.
+  Memory partitioning between VMs is a fundamental security feature.
+
+- Interrupt Virtualization:
+
+  Uses CPU hardware interrupt virtualization capabilities. Interrupts are handled
+  in the hypervisor and routed to the assigned VM.
+
+- Inter-VM Communication:
+
+  There are several different mechanisms provided for communicating between VMs.
+
+- Virtual platform:
+
+  Architectural devices such as interrupt controllers and CPU timers are directly provided
+  by the hypervisor as well as core virtual platform devices and system APIs such as ARM PSCI.
+
+- Device Virtualization:
+
+  Para-virtualization of devices is supported using inter-VM communication.
+
+Architectures supported
+=======================
+AArch64 with a GIC
+
+Resources and Capabilities
+==========================
+
+Some services or resources provided by the Gunyah hypervisor are described to a virtual machine by
+capability IDs. For instance, inter-VM communication is performed with doorbells and message queues.
+Gunyah allows access to manipulate that doorbell via the capability ID. These resources are
+described in Linux as a struct gh_resource.
+
+High level management of these resources is performed by the resource manager VM. RM informs a
+guest VM about resources it can access through either the device tree or via guest-initiated RPC.
+
+For each virtual machine, Gunyah maintains a table of resources which can be accessed by that VM.
+An entry in this table is called a "capability" and VMs can only access resources via this
+capability table. Hence, virtual Gunyah resources are referenced by a "capability IDs" and not
+"resource IDs". If 2 VMs have access to the same resource, they might not be using the same
+capability ID to access that resource since the capability tables are independent per VM.
+
+Resource Manager
+================
+
+The resource manager (RM) is a privileged application VM supporting the Gunyah Hypervisor.
+It provides policy enforcement aspects of the virtualization system. The resource manager can
+be treated as an extension of the Hypervisor but is separated to its own partition to ensure
+that the hypervisor layer itself remains small and secure and to maintain a separation of policy
+and mechanism in the platform. RM runs at arm64 NS-EL1 similar to other virtual machines.
+
+Communication with the resource manager from each guest VM happens with message-queue.rst. Details
+about the specific messages can be found in drivers/virt/gunyah/rsc_mgr.c
+
+::
+
+  +-------+   +--------+   +--------+
+  |  RM   |   |  VM_A  |   |  VM_B  |
+  +-.-.-.-+   +---.----+   +---.----+
+    | |           |            |
+  +-.-.-----------.------------.----+
+  | | \==========/             |    |
+  |  \========================/     |
+  |            Gunyah               |
+  +---------------------------------+
+
+The source for the resource manager is available at https://github.com/quic/gunyah-resource-manager.
+
+The resource manager provides the following features:
+
+- VM lifecycle management: allocating a VM, starting VMs, destruction of VMs
+- VM access control policy, including memory sharing and lending
+- Interrupt routing configuration
+- Forwarding of system-level events (e.g. VM shutdown) to owner VM
+
+When booting a virtual machine which uses a devicetree such as Linux, resource manager overlays a
+/hypervisor node. This node can let Linux know it is running as a Gunyah guest VM,
+how to communicate with resource manager, and basic description and capabilities of
+this VM. See Documentation/devicetree/bindings/firmware/gunyah-hypervisor.yaml for a description
+of this node.
--- linux-qcom-6.8.0.orig/Documentation/virt/gunyah/message-queue.rst
+++ linux-qcom-6.8.0/Documentation/virt/gunyah/message-queue.rst
@@ -0,0 +1,71 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Message Queues
+==============
+Message queue is a simple low-capacity IPC channel between two VMs. It is
+intended for sending small control and configuration messages. Each message
+queue is unidirectional, so a full-duplex IPC channel requires a pair of queues.
+
+Messages can be up to 240 bytes in length. Longer messages require a further
+protocol on top of the message queue messages themselves. For instance, communication
+with the resource manager adds a header field for sending longer messages via multiple
+message fragments.
+
+The diagram below shows how message queue works. A typical configuration involves
+2 message queues. Message queue 1 allows VM_A to send messages to VM_B. Message
+queue 2 allows VM_B to send messages to VM_A.
+
+1. VM_A sends a message of up to 240 bytes in length. It raises a hypercall
+   with the message to inform the hypervisor to add the message to
+   message queue 1's queue. The hypervisor copies memory into the internal
+   message queue representation; the memory doesn't need to be shared between
+   VM_A and VM_B.
+
+2. Gunyah raises the corresponding interrupt for VM_B (Rx vIRQ) when any of
+   these happens:
+
+   a. gh_msgq_send() has PUSH flag. Queue is immediately flushed. This is the typical case.
+   b. Explicility with gh_msgq_push command from VM_A.
+   c. Message queue has reached a threshold depth.
+
+3. VM_B calls gh_msgq_recv() and Gunyah copies message to requested buffer.
+
+4. Gunyah buffers messages in the queue. If the queue became full when VM_A added a message,
+   the return values for gh_msgq_send() include a flag that indicates the queue is full.
+   Once VM_B receives the message and, thus, there is space in the queue, Gunyah
+   will raise the Tx vIRQ on VM_A to indicate it can continue sending messages.
+
+For VM_B to send a message to VM_A, the process is identical, except that hypercalls
+reference message queue 2's capability ID. Each message queue has its own independent
+vIRQ: two TX message queues will have two vIRQs (and two capability IDs).
+
+::
+
+      +---------------+         +-----------------+         +---------------+
+      |      VM_A     |         |Gunyah hypervisor|         |      VM_B     |
+      |               |         |                 |         |               |
+      |               |         |                 |         |               |
+      |               |   Tx    |                 |         |               |
+      |               |-------->|                 | Rx vIRQ |               |
+      |gh_msgq_send() | Tx vIRQ |Message queue 1  |-------->|gh_msgq_recv() |
+      |               |<------- |                 |         |               |
+      |               |         |                 |         |               |
+      | Message Queue |         |                 |         | Message Queue |
+      | driver        |         |                 |         | driver        |
+      |               |         |                 |         |               |
+      |               |         |                 |         |               |
+      |               |         |                 |   Tx    |               |
+      |               | Rx vIRQ |                 |<--------|               |
+      |gh_msgq_recv() |<--------|Message queue 2  | Tx vIRQ |gh_msgq_send() |
+      |               |         |                 |-------->|               |
+      |               |         |                 |         |               |
+      |               |         |                 |         |               |
+      +---------------+         +-----------------+         +---------------+
+
+Gunyah message queues are exposed as mailboxes. To create the mailbox, create
+a mbox_client and call `gh_msgq_init()`. On receipt of the RX_READY interrupt,
+all messages in the RX message queue are read and pushed via the `rx_callback`
+of the registered mbox_client.
+
+.. kernel-doc:: drivers/mailbox/gunyah-msgq.c
+   :identifiers: gh_msgq_init
--- linux-qcom-6.8.0.orig/Documentation/virt/gunyah/vm-manager.rst
+++ linux-qcom-6.8.0/Documentation/virt/gunyah/vm-manager.rst
@@ -0,0 +1,143 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=======================
+Virtual Machine Manager
+=======================
+
+The Gunyah Virtual Machine Manager is a Linux driver to support launching
+virtual machines using Gunyah.
+
+Configuration of a Gunyah virtual machine is done via a devicetree. When the VM
+is launched, memory is provided by the host VM which contains the devictree.
+Gunyah reads the devicetree to configure the memory map and create resources
+such as vCPUs for the VM. Memory can be shared with the VM with
+`GH_VM_SET_USER_MEM_REGION`_. Userspace can interact with the resources in Linux
+by adding "functions" to the VM.
+
+Gunyah Functions
+================
+
+Components of a Gunyah VM's configuration that need kernel configuration are
+called "functions" and are built on top of a framework. Functions are identified
+by a string and have some argument(s) to configure them. They are typically
+created by the `GH_VM_ADD_FUNCTION`_ ioctl.
+
+Functions typically will always do at least one of these operations:
+
+1. Create resource ticket(s). Resource tickets allow a function to register
+   itself as the client for a Gunyah resource (e.g. doorbell or vCPU) and
+   the function is given the pointer to the &struct gh_resource when the
+   VM is starting.
+
+2. Register IO handler(s). IO handlers allow a function to handle stage-2 faults
+   from the virtual machine.
+
+Sample Userspace VMM
+====================
+
+A sample userspace VMM is included in samples/gunyah/ along with a minimal
+devicetree that can be used to launch a VM. To build this sample, enable
+CONFIG_SAMPLE_GUNYAH.
+
+IOCTLs and userspace VMM flows
+==============================
+
+The kernel exposes a char device interface at /dev/gunyah.
+
+To create a VM, use the `GH_CREATE_VM`_ ioctl. A successful call will return a
+"Gunyah VM" file descriptor.
+
+/dev/gunyah API Descriptions
+----------------------------
+
+GH_CREATE_VM
+~~~~~~~~~~~~
+
+Creates a Gunyah VM. The argument is reserved for future use and must be 0.
+A successful call will return a Gunyah VM file descriptor. See
+`Gunyah VM API Descriptions`_ for list of IOCTLs that can be made on this file
+file descriptor.
+
+Gunyah VM API Descriptions
+--------------------------
+
+GH_VM_SET_USER_MEM_REGION
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This ioctl allows the user to create or delete a memory parcel for a guest
+virtual machine. Each memory region is uniquely identified by a label;
+attempting to create two regions with the same label is not allowed. Labels are
+unique per virtual machine.
+
+While VMM is guest-agnostic and allows runtime addition of memory regions,
+Linux guest virtual machines do not support accepting memory regions at runtime.
+Thus, for Linux guests, memory regions should be provided before starting the VM
+and the VM must be configured via the devicetree to accept these at boot-up.
+
+The guest physical address is used by Linux kernel to check that the requested
+user regions do not overlap and to help find the corresponding memory region
+for calls like `GH_VM_SET_DTB_CONFIG`_. It must be page aligned.
+
+To add a memory region, call `GH_VM_SET_USER_MEM_REGION`_ with fields set as
+described above.
+
+.. kernel-doc:: include/uapi/linux/gunyah.h
+   :identifiers: gh_userspace_memory_region gh_mem_flags
+
+GH_VM_SET_DTB_CONFIG
+~~~~~~~~~~~~~~~~~~~~
+
+This ioctl sets the location of the VM's devicetree blob and is used by Gunyah
+Resource Manager to allocate resources. The guest physical memory must be part
+of the primary memory parcel provided to the VM prior to GH_VM_START.
+
+.. kernel-doc:: include/uapi/linux/gunyah.h
+   :identifiers: gh_vm_dtb_config
+
+GH_VM_START
+~~~~~~~~~~~
+
+This ioctl starts the VM.
+
+GH_VM_ADD_FUNCTION
+~~~~~~~~~~~~~~~~~~
+
+This ioctl registers a Gunyah VM function with the VM manager. The VM function
+is described with a &struct gh_fn_desc.type and some arguments for that type.
+Typically, the function is added before the VM starts, but the function doesn't
+"operate" until the VM starts with `GH_VM_START`_. For example, vCPU ioctls will
+all return an error until the VM starts because the vCPUs don't exist until the
+VM is started. This allows the VMM to set up all the kernel functions needed for
+the VM *before* the VM starts.
+
+.. kernel-doc:: include/uapi/linux/gunyah.h
+   :identifiers: gh_fn_desc gh_fn_type
+
+The argument types are documented below:
+
+.. kernel-doc:: include/uapi/linux/gunyah.h
+   :identifiers: gh_fn_vcpu_arg gh_fn_irqfd_arg gh_irqfd_flags gh_fn_ioeventfd_arg gh_ioeventfd_flags
+
+Gunyah VCPU API Descriptions
+----------------------------
+
+A vCPU file descriptor is created after calling `GH_VM_ADD_FUNCTION` with the type `GH_FN_VCPU`.
+
+GH_VCPU_RUN
+~~~~~~~~~~~
+
+This ioctl is used to run a guest virtual cpu.  While there are no
+explicit parameters, there is an implicit parameter block that can be
+obtained by mmap()ing the vcpu fd at offset 0, with the size given by
+`GH_VCPU_MMAP_SIZE`_. The parameter block is formatted as a 'struct
+gh_vcpu_run' (see below).
+
+GH_VCPU_MMAP_SIZE
+~~~~~~~~~~~~~~~~~
+
+The `GH_VCPU_RUN`_ ioctl communicates with userspace via a shared
+memory region. This ioctl returns the size of that region. See the
+`GH_VCPU_RUN`_ documentation for details.
+
+.. kernel-doc:: include/uapi/linux/gunyah.h
+   :identifiers: gh_vcpu_exit gh_vcpu_run gh_vm_status gh_vm_exit_info
--- linux-qcom-6.8.0.orig/Documentation/virt/index.rst
+++ linux-qcom-6.8.0/Documentation/virt/index.rst
@@ -16,6 +16,7 @@
    coco/sev-guest
    coco/tdx-guest
    hyperv/index
+   gunyah/index
 
 .. only:: html and subproject
 
--- linux-qcom-6.8.0.orig/Documentation/virt/kvm/api.rst
+++ linux-qcom-6.8.0/Documentation/virt/kvm/api.rst
@@ -1403,6 +1403,12 @@
 was a load or a store, instruction abort if it was an instruction
 fetch) is injected in the guest.
 
+S390:
+^^^^^
+
+Returns -EINVAL if the VM has the KVM_VM_S390_UCONTROL flag set.
+Returns -EINVAL if called on a protected VM.
+
 4.36 KVM_SET_TSS_ADDR
 ---------------------
 
@@ -2439,8 +2445,11 @@
   PPC     KVM_REG_PPC_PSSCR               64
   PPC     KVM_REG_PPC_DEC_EXPIRY          64
   PPC     KVM_REG_PPC_PTCR                64
+  PPC     KVM_REG_PPC_HASHKEYR            64
+  PPC     KVM_REG_PPC_HASHPKEYR           64
   PPC     KVM_REG_PPC_DAWR1               64
   PPC     KVM_REG_PPC_DAWRX1              64
+  PPC     KVM_REG_PPC_DEXCR               64
   PPC     KVM_REG_PPC_TM_GPR0             64
   ...
   PPC     KVM_REG_PPC_TM_GPR31            64
@@ -6244,6 +6253,12 @@
 is '0' for all gfns.  Userspace can control whether memory is shared/private by
 toggling KVM_MEMORY_ATTRIBUTE_PRIVATE via KVM_SET_MEMORY_ATTRIBUTES as needed.
 
+S390:
+^^^^^
+
+Returns -EINVAL if the VM has the KVM_VM_S390_UCONTROL flag set.
+Returns -EINVAL if called on a protected VM.
+
 4.141 KVM_SET_MEMORY_ATTRIBUTES
 -------------------------------
 
--- linux-qcom-6.8.0.orig/Documentation/virt/kvm/locking.rst
+++ linux-qcom-6.8.0/Documentation/virt/kvm/locking.rst
@@ -9,7 +9,7 @@
 
 The acquisition orders for mutexes are as follows:
 
-- cpus_read_lock() is taken outside kvm_lock
+- cpus_read_lock() is taken outside kvm_lock and kvm_usage_lock
 
 - kvm->lock is taken outside vcpu->mutex
 
@@ -24,6 +24,13 @@
   are taken on the waiting side when modifying memslots, so MMU notifiers
   must not take either kvm->slots_lock or kvm->slots_arch_lock.
 
+cpus_read_lock() vs kvm_lock:
+
+- Taking cpus_read_lock() outside of kvm_lock is problematic, despite that
+  being the official ordering, as it is quite easy to unknowingly trigger
+  cpus_read_lock() while holding kvm_lock.  Use caution when walking vm_list,
+  e.g. avoid complex operations when possible.
+
 For SRCU:
 
 - ``synchronize_srcu(&kvm->srcu)`` is called inside critical sections
@@ -227,10 +234,17 @@
 :Type:		mutex
 :Arch:		any
 :Protects:	- vm_list
-		- kvm_usage_count
+
+``kvm_usage_lock``
+^^^^^^^^^^^^^^^^^^
+
+:Type:		mutex
+:Arch:		any
+:Protects:	- kvm_usage_count
 		- hardware virtualization enable/disable
-:Comment:	KVM also disables CPU hotplug via cpus_read_lock() during
-		enable/disable.
+:Comment:	Exists because using kvm_lock leads to deadlock (see earlier comment
+		on cpus_read_lock() vs kvm_lock).  Note, KVM also disables CPU hotplug via
+		cpus_read_lock() when enabling/disabling virtualization.
 
 ``kvm->mn_invalidate_lock``
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -290,11 +304,12 @@
 		wakeup.
 
 ``vendor_module_lock``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+^^^^^^^^^^^^^^^^^^^^^^
 :Type:		mutex
 :Arch:		x86
 :Protects:	loading a vendor module (kvm_amd or kvm_intel)
-:Comment:	Exists because using kvm_lock leads to deadlock.  cpu_hotplug_lock is
-    taken outside of kvm_lock, e.g. in KVM's CPU online/offline callbacks, and
-    many operations need to take cpu_hotplug_lock when loading a vendor module,
-    e.g. updating static calls.
+:Comment:	Exists because using kvm_lock leads to deadlock.  kvm_lock is taken
+    in notifiers, e.g. __kvmclock_cpufreq_notifier(), that may be invoked while
+    cpu_hotplug_lock is held, e.g. from cpufreq_boost_trigger_state(), and many
+    operations need to take cpu_hotplug_lock when loading a vendor module, e.g.
+    updating static calls.
--- linux-qcom-6.8.0.orig/Kbuild
+++ linux-qcom-6.8.0/Kbuild
@@ -97,3 +97,4 @@
 obj-$(CONFIG_NET)	+= net/
 obj-y			+= virt/
 obj-y			+= $(ARCH_DRIVERS)
+obj-y			+= ubuntu/
--- linux-qcom-6.8.0.orig/Kconfig
+++ linux-qcom-6.8.0/Kconfig
@@ -19,6 +19,8 @@
 
 source "drivers/Kconfig"
 
+source "ubuntu/Kconfig"
+
 source "fs/Kconfig"
 
 source "security/Kconfig"
--- linux-qcom-6.8.0.orig/MAINTAINERS
+++ linux-qcom-6.8.0/MAINTAINERS
@@ -190,6 +190,18 @@
 F:	Documentation/devicetree/bindings/power/supply/*ab8500*
 F:	drivers/power/supply/*ab8500*
 
+AAEON DEVICE DRIVER WITH WMI INTERFACE
+M:	Edward Lin<edward1_lin@asus.com>
+M:	Kunyang Fan <kunyang_fan@asus.com>
+M:	Frank Hsieh <frank2_hsieh@asus.com>
+M:	Jacob Wu <jacob_wu@asus.com>
+S:	Supported
+F:	drivers/gpio/gpio-aaeon.c
+F:	drivers/hwmon/hwmon-aaeon.c
+F:	drivers/leds/leds-aaeon.c
+F:	drivers/mfd/mfd-aaeon.c
+F:	drivers/watchdog/wdt_aaeon.c
+
 ABI/API
 L:	linux-api@vger.kernel.org
 F:	include/linux/syscalls.h
@@ -1054,7 +1066,6 @@
 S:	Supported
 F:	Documentation/admin-guide/pm/amd-pstate.rst
 F:	drivers/cpufreq/amd-pstate*
-F:	include/linux/amd-pstate.h
 F:	tools/power/x86/amd_pstate_tracer/amd_pstate_trace.py
 
 AMD PTDMA DRIVER
@@ -2591,7 +2602,7 @@
 F:	drivers/mfd/ssbi.c
 F:	drivers/mmc/host/mmci_qcom*
 F:	drivers/mmc/host/sdhci-msm.c
-F:	drivers/pci/controller/dwc/pcie-qcom.c
+F:	drivers/pci/controller/dwc/pcie-qcom*
 F:	drivers/phy/qualcomm/
 F:	drivers/power/*/msm*
 F:	drivers/reset/reset-qcom-*
@@ -10389,6 +10400,14 @@
 S:	Maintained
 F:	drivers/media/rc/iguanair.c
 
+IIO BACKEND FRAMEWORK
+M:	Nuno Sa <nuno.sa@analog.com>
+R:	Olivier Moysan <olivier.moysan@foss.st.com>
+L:	linux-iio@vger.kernel.org
+S:	Maintained
+F:	drivers/iio/industrialio-backend.c
+F:	include/linux/iio/backend.h
+
 IIO DIGITAL POTENTIOMETER DAC
 M:	Peter Rosin <peda@axentia.se>
 L:	linux-iio@vger.kernel.org
@@ -12192,6 +12211,12 @@
 W:	http://legousb.sourceforge.net/
 F:	drivers/usb/misc/legousbtower.c
 
+LENOVO WMI HOTKEY UTILITIES DRIVER
+M:	Jackie Dong <xy-jackie@139.com>
+L:	platform-driver-x86@vger.kernel.org
+S:	Maintained
+F:	drivers/platform/x86/lenovo-wmi-hotkey-utilities.c
+
 LETSKETCH HID TABLET DRIVER
 M:	Hans de Goede <hdegoede@redhat.com>
 L:	linux-input@vger.kernel.org
@@ -14048,7 +14073,7 @@
 M:	"Paul E. McKenney" <paulmck@kernel.org>
 L:	linux-kernel@vger.kernel.org
 S:	Supported
-F:	arch/powerpc/include/asm/membarrier.h
+F:	arch/*/include/asm/membarrier.h
 F:	include/uapi/linux/membarrier.h
 F:	kernel/sched/membarrier.c
 
@@ -16960,6 +16985,14 @@
 F:	drivers/pci/p2pdma.c
 F:	include/linux/pci-p2pdma.h
 
+PCI POWER CONTROL
+M:	Bartosz Golaszewski <brgl@bgdev.pl>
+L:	linux-pci@vger.kernel.org
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git
+F:	drivers/pci/pwrctl/*
+F:	include/linux/pci-pwrctl.h
+
 PCI SUBSYSTEM
 M:	Bjorn Helgaas <bhelgaas@google.com>
 L:	linux-pci@vger.kernel.org
@@ -17066,6 +17099,7 @@
 L:	linux-pci@vger.kernel.org
 L:	linux-arm-msm@vger.kernel.org
 S:	Maintained
+F:	drivers/pci/controller/dwc/pcie-qcom-common.c
 F:	drivers/pci/controller/dwc/pcie-qcom.c
 
 PCIE DRIVER FOR ROCKCHIP
@@ -17095,6 +17129,7 @@
 L:	linux-arm-msm@vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/pci/qcom,pcie-ep.yaml
+F:	drivers/pci/controller/dwc/pcie-qcom-common.c
 F:	drivers/pci/controller/dwc/pcie-qcom-ep.c
 
 PCMCIA SUBSYSTEM
@@ -17531,6 +17566,14 @@
 F:	include/linux/powercap.h
 F:	kernel/configs/nopm.config
 
+POWER SEQUENCING
+M:	Bartosz Golaszewski <brgl@bgdev.pl>
+L:	linux-pm@vger.kernel.org
+S:	Maintained
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git
+F:	drivers/power/sequencing/
+F:	include/linux/pwrseq/
+
 POWER STATE COORDINATION INTERFACE (PSCI)
 M:	Mark Rutland <mark.rutland@arm.com>
 M:	Lorenzo Pieralisi <lpieralisi@kernel.org>
@@ -18083,6 +18126,13 @@
 F:	Documentation/devicetree/bindings/power/avs/qcom,cpr.yaml
 F:	drivers/pmdomain/qcom/cpr.c
 
+QUALCOMM CPUCP MAILBOX DRIVER
+M:	Sibi Sankar <quic_sibis@quicinc.com>
+L:	linux-arm-msm@vger.kernel.org
+S:	Supported
+F:	Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml
+F:	drivers/mailbox/qcom-cpucp-mbox.c
+
 QUALCOMM CPUFREQ DRIVER MSM8996/APQ8096
 M:	Ilia Lin <ilia.lin@kernel.org>
 L:	linux-pm@vger.kernel.org
@@ -18223,6 +18273,14 @@
 F:	drivers/net/ethernet/qualcomm/rmnet/
 F:	include/linux/if_rmnet.h
 
+QUALCOMM TRUST ZONE MEMORY ALLOCATOR
+M:	Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+L:	linux-arm-msm@vger.kernel.org
+S:	Maintained
+F:	drivers/firmware/qcom/qcom_tzmem.c
+F:	drivers/firmware/qcom/qcom_tzmem.h
+F:	include/linux/firmware/qcom/qcom_tzmem.h
+
 QUALCOMM TSENS THERMAL DRIVER
 M:	Amit Kucheria <amitk@kernel.org>
 M:	Thara Gopinath <thara.gopinath@gmail.com>
--- linux-qcom-6.8.0.orig/Makefile
+++ linux-qcom-6.8.0/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 6
 PATCHLEVEL = 8
-SUBLEVEL = 0
+SUBLEVEL = 12
 EXTRAVERSION =
 NAME = Hurr durr I'ma ninja sloth
 
@@ -515,7 +515,7 @@
 KBZIP2		= bzip2
 KLZOP		= lzop
 LZMA		= lzma
-LZ4		= lz4c
+LZ4		= lz4
 XZ		= xz
 ZSTD		= zstd
 
@@ -549,6 +549,9 @@
 		-I$(objtree)/include \
 		$(USERINCLUDE)
 
+# UBUNTU: Include our third party driver stuff too
+LINUXINCLUDE   += -I$(srctree)/ubuntu/include
+
 KBUILD_AFLAGS   := -D__ASSEMBLY__ -fno-PIE
 
 KBUILD_CFLAGS :=
@@ -943,7 +946,6 @@
 ifdef CONFIG_LTO_CLANG
 ifdef CONFIG_LTO_CLANG_THIN
 CC_FLAGS_LTO	:= -flto=thin -fsplit-lto-unit
-KBUILD_LDFLAGS	+= --thinlto-cache-dir=$(extmod_prefix).thinlto-cache
 else
 CC_FLAGS_LTO	:= -flto
 endif
@@ -1278,8 +1280,9 @@
 quiet_cmd_headers_install = INSTALL $(INSTALL_HDR_PATH)/include
       cmd_headers_install = \
 	mkdir -p $(INSTALL_HDR_PATH); \
-	rsync -mrl --include='*/' --include='*\.h' --exclude='*' \
-	usr/include $(INSTALL_HDR_PATH)
+	find usr/include -type f -name '*.h' -print0 | \
+	tar -czf - --null --no-recursion --no-wildcards-match-slash -T- | \
+	tar -xzf - --strip-components=1 -C $(INSTALL_HDR_PATH)
 
 PHONY += headers_install
 headers_install: headers
@@ -1294,6 +1297,7 @@
 	$(if $(filter um, $(SRCARCH)), $(error Headers not exportable for UML))
 	$(Q)$(MAKE) $(hdr-inst)=include/uapi
 	$(Q)$(MAKE) $(hdr-inst)=arch/$(SRCARCH)/include/uapi
+	$(Q)$(MAKE) $(hdr-inst)=ubuntu/include dst=include oldheaders=
 
 ifdef CONFIG_HEADERS_INSTALL
 prepare: headers
@@ -1479,13 +1483,13 @@
 # Directories & files removed with 'make clean'
 CLEAN_FILES += vmlinux.symvers modules-only.symvers \
 	       modules.builtin modules.builtin.modinfo modules.nsdeps \
-	       compile_commands.json .thinlto-cache rust/test \
+	       compile_commands.json rust/test \
 	       rust-project.json .vmlinux.objs .vmlinux.export.c
 
 # Directories & files removed with 'make mrproper'
 MRPROPER_FILES += include/config include/generated          \
 		  arch/$(SRCARCH)/include/generated .objdiff \
-		  debian snap tar-install \
+		  snap tar-install \
 		  .config .config.old .version \
 		  Module.symvers \
 		  certs/signing_key.pem \
@@ -1785,7 +1789,7 @@
 
 clean-dirs := $(KBUILD_EXTMOD)
 clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers $(KBUILD_EXTMOD)/modules.nsdeps \
-	$(KBUILD_EXTMOD)/compile_commands.json $(KBUILD_EXTMOD)/.thinlto-cache
+	$(KBUILD_EXTMOD)/compile_commands.json
 
 PHONY += prepare
 # now expand this into a simple variable to reduce the cost of shell evaluations
--- linux-qcom-6.8.0.orig/Ubuntu.md
+++ linux-qcom-6.8.0/Ubuntu.md
@@ -0,0 +1,8 @@
+Name:    linux-qcom
+Version: 6.8.0
+Series:  24.04 (noble)
+Description:
+    This is the source code for the Ubuntu linux kernel for the 24.04 series. This
+    source tree is used to produce the flavours: qcom.
+    This kernel is configured to support the widest range of desktop, laptop and
+    server configurations.
--- linux-qcom-6.8.0.orig/arch/Kconfig
+++ linux-qcom-6.8.0/arch/Kconfig
@@ -9,6 +9,14 @@
 #
 source "arch/$(SRCARCH)/Kconfig"
 
+config ARCH_CONFIGURES_CPU_MITIGATIONS
+	bool
+
+if !ARCH_CONFIGURES_CPU_MITIGATIONS
+config CPU_MITIGATIONS
+	def_bool y
+endif
+
 menu "General architecture-dependent options"
 
 config ARCH_HAS_SUBPAGE_FAULTS
--- linux-qcom-6.8.0.orig/arch/arc/Kconfig
+++ linux-qcom-6.8.0/arch/arc/Kconfig
@@ -292,7 +292,6 @@
 
 config ARC_PAGE_SIZE_4K
 	bool "4KB"
-	depends on ARC_MMU_V3 || ARC_MMU_V4
 
 endchoice
 
@@ -469,7 +468,8 @@
 
 config ARC_HAS_PAE40
 	bool "Support for the 40-bit Physical Address Extension"
-	depends on ISA_ARCV2
+	depends on MMU_V4
+	depends on !ARC_PAGE_SIZE_4K
 	select HIGHMEM
 	select PHYS_ADDR_T_64BIT
 	help
--- linux-qcom-6.8.0.orig/arch/arc/Makefile
+++ linux-qcom-6.8.0/arch/arc/Makefile
@@ -6,7 +6,7 @@
 KBUILD_DEFCONFIG := haps_hs_smp_defconfig
 
 ifeq ($(CROSS_COMPILE),)
-CROSS_COMPILE := $(call cc-cross-prefix, arc-linux- arceb-linux-)
+CROSS_COMPILE := $(call cc-cross-prefix, arc-linux- arceb-linux- arc-linux-gnu-)
 endif
 
 cflags-y	+= -fno-common -pipe -fno-builtin -mmedium-calls -D__linux__
--- linux-qcom-6.8.0.orig/arch/arc/boot/dts/hsdk.dts
+++ linux-qcom-6.8.0/arch/arc/boot/dts/hsdk.dts
@@ -205,7 +205,6 @@
 		};
 
 		gmac: ethernet@8000 {
-			#interrupt-cells = <1>;
 			compatible = "snps,dwmac";
 			reg = <0x8000 0x2000>;
 			interrupts = <10>;
--- linux-qcom-6.8.0.orig/arch/arc/kernel/devtree.c
+++ linux-qcom-6.8.0/arch/arc/kernel/devtree.c
@@ -62,7 +62,7 @@
 	const struct machine_desc *mdesc;
 	unsigned long dt_root;
 
-	if (!early_init_dt_scan(dt))
+	if (!early_init_dt_scan(dt, __pa(dt)))
 		return NULL;
 
 	mdesc = of_flat_dt_match_machine(NULL, arch_get_next_mach);
--- linux-qcom-6.8.0.orig/arch/arm/Kconfig
+++ linux-qcom-6.8.0/arch/arm/Kconfig
@@ -29,7 +29,7 @@
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG if CPU_V7 || CPU_V7M || CPU_V6K
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_KEEP_MEMBLOCK
-	select ARCH_HAS_UBSAN_SANITIZE_ALL
+	select ARCH_HAS_UBSAN
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
 	select ARCH_OPTIONAL_KERNEL_RWX_DEFAULT if CPU_V7
@@ -503,8 +503,8 @@
 
 config IWMMXT
 	bool "Enable iWMMXt support"
-	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 || CPU_PJ4B
-	default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 || CPU_PJ4B
+	depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK
+	default y if PXA27x || PXA3xx || ARCH_MMP
 	help
 	  Enable support for iWMMXt context switching at run time if
 	  running on a CPU that supports it.
--- linux-qcom-6.8.0.orig/arch/arm/Makefile
+++ linux-qcom-6.8.0/arch/arm/Makefile
@@ -59,6 +59,9 @@
 #
 KBUILD_CFLAGS	+= $(call cc-option,-fno-ipa-sra)
 
+# Need -msoft-float for gcc 11 for the below instruction set selection
+KBUILD_CFLAGS	+= -msoft-float
+
 # This selects which instruction set is used.
 arch-$(CONFIG_CPU_32v7M)	:=-march=armv7-m
 arch-$(CONFIG_CPU_32v7)		:=-march=armv7-a
@@ -141,7 +144,7 @@
 
 # Need -Uarm for gcc < 3.x
 KBUILD_CPPFLAGS	+=$(cpp-y)
-KBUILD_CFLAGS	+=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
+KBUILD_CFLAGS	+=$(CFLAGS_ABI) $(CFLAGS_ISA) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -Uarm
 KBUILD_AFLAGS	+=$(CFLAGS_ABI) $(AFLAGS_ISA) -Wa,$(arch-y) $(tune-y) -include asm/unified.h -msoft-float
 
 CHECKFLAGS	+= -D__arm__
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/allwinner/Makefile
+++ linux-qcom-6.8.0/arch/arm/boot/dts/allwinner/Makefile
@@ -260,68 +260,6 @@
 	sun8i-v3s-licheepi-zero.dtb \
 	sun8i-v3s-licheepi-zero-dock.dtb \
 	sun8i-v40-bananapi-m2-berry.dtb
-dtb-$(CONFIG_MACH_SUN8I) += \
-	sun8i-a23-evb.dtb \
-	sun8i-a23-gt90h-v4.dtb \
-	sun8i-a23-inet86dz.dtb \
-	sun8i-a23-ippo-q8h-v5.dtb \
-	sun8i-a23-ippo-q8h-v1.2.dtb \
-	sun8i-a23-polaroid-mid2407pxe03.dtb \
-	sun8i-a23-polaroid-mid2809pxe04.dtb \
-	sun8i-a23-q8-tablet.dtb \
-	sun8i-a33-et-q8-v1.6.dtb \
-	sun8i-a33-ga10h-v1.1.dtb \
-	sun8i-a33-inet-d978-rev2.dtb \
-	sun8i-a33-ippo-q8h-v1.2.dtb \
-	sun8i-a33-olinuxino.dtb \
-	sun8i-a33-q8-tablet.dtb \
-	sun8i-a33-sinlinx-sina33.dtb \
-	sun8i-a83t-allwinner-h8homlet-v2.dtb \
-	sun8i-a83t-bananapi-m3.dtb \
-	sun8i-a83t-cubietruck-plus.dtb \
-	sun8i-a83t-tbs-a711.dtb \
-	sun8i-h2-plus-bananapi-m2-zero.dtb \
-	sun8i-h2-plus-libretech-all-h3-cc.dtb \
-	sun8i-h2-plus-orangepi-r1.dtb \
-	sun8i-h2-plus-orangepi-zero.dtb \
-	sun8i-h3-bananapi-m2-plus.dtb \
-	sun8i-h3-bananapi-m2-plus-v1.2.dtb \
-	sun8i-h3-beelink-x2.dtb \
-	sun8i-h3-libretech-all-h3-cc.dtb \
-	sun8i-h3-mapleboard-mp130.dtb \
-	sun8i-h3-nanopi-duo2.dtb \
-	sun8i-h3-nanopi-m1.dtb\
-	\
-	sun8i-h3-nanopi-m1-plus.dtb \
-	sun8i-h3-nanopi-neo.dtb \
-	sun8i-h3-nanopi-neo-air.dtb \
-	sun8i-h3-nanopi-r1.dtb \
-	sun8i-h3-orangepi-2.dtb \
-	sun8i-h3-orangepi-lite.dtb \
-	sun8i-h3-orangepi-one.dtb \
-	sun8i-h3-orangepi-pc.dtb \
-	sun8i-h3-orangepi-pc-plus.dtb \
-	sun8i-h3-orangepi-plus.dtb \
-	sun8i-h3-orangepi-plus2e.dtb \
-	sun8i-h3-orangepi-zero-plus2.dtb \
-	sun8i-h3-rervision-dvk.dtb \
-	sun8i-h3-zeropi.dtb \
-	sun8i-h3-emlid-neutis-n5h3-devboard.dtb \
-	sun8i-r16-bananapi-m2m.dtb \
-	sun8i-r16-nintendo-nes-classic.dtb \
-	sun8i-r16-nintendo-super-nes-classic.dtb \
-	sun8i-r16-parrot.dtb \
-	sun8i-r40-bananapi-m2-ultra.dtb \
-	sun8i-r40-oka40i-c.dtb \
-	sun8i-s3-elimo-initium.dtb \
-	sun8i-s3-lichee-zero-plus.dtb \
-	sun8i-s3-pinecube.dtb \
-	sun8i-t113s-mangopi-mq-r-t113.dtb \
-	sun8i-t3-cqa3t-bv3.dtb \
-	sun8i-v3-sl631-imx179.dtb \
-	sun8i-v3s-licheepi-zero.dtb \
-	sun8i-v3s-licheepi-zero-dock.dtb \
-	sun8i-v40-bananapi-m2-berry.dtb
 dtb-$(CONFIG_MACH_SUN9I) += \
 	sun9i-a80-optimus.dtb \
 	sun9i-a80-cubieboard4.dtb
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/allwinner/sun9i-a80-cubieboard4.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/allwinner/sun9i-a80-cubieboard4.dts
@@ -280,8 +280,8 @@
 
 			reg_dcdc5: dcdc5 {
 				regulator-always-on;
-				regulator-min-microvolt = <1425000>;
-				regulator-max-microvolt = <1575000>;
+				regulator-min-microvolt = <1450000>;
+				regulator-max-microvolt = <1550000>;
 				regulator-name = "vcc-dram";
 			};
 
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/arm/arm-realview-pb1176.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/arm/arm-realview-pb1176.dts
@@ -451,7 +451,7 @@
 
 		/* Direct-mapped development chip ROM */
 		pb1176_rom@10200000 {
-			compatible = "direct-mapped";
+			compatible = "mtd-rom";
 			reg = <0x10200000 0x4000>;
 			bank-width = <1>;
 		};
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-yosemite4.dts
@@ -284,12 +284,12 @@
 &i2c11 {
 	status = "okay";
 	power-sensor@10 {
-		compatible = "adi, adm1272";
+		compatible = "adi,adm1272";
 		reg = <0x10>;
 	};
 
 	power-sensor@12 {
-		compatible = "adi, adm1272";
+		compatible = "adi,adm1272";
 		reg = <0x12>;
 	};
 
@@ -454,22 +454,20 @@
 			};
 
 			pwm@20{
-				compatible = "max31790";
+				compatible = "maxim,max31790";
 				reg = <0x20>;
-				#address-cells = <1>;
-				#size-cells = <0>;
 			};
 
 			gpio@22{
 				compatible = "ti,tca6424";
 				reg = <0x22>;
+				gpio-controller;
+				#gpio-cells = <2>;
 			};
 
 			pwm@23{
-				compatible = "max31790";
+				compatible = "maxim,max31790";
 				reg = <0x23>;
-				#address-cells = <1>;
-				#size-cells = <0>;
 			};
 
 			adc@33 {
@@ -504,22 +502,20 @@
 			};
 
 			pwm@20{
-				compatible = "max31790";
+				compatible = "maxim,max31790";
 				reg = <0x20>;
-				#address-cells = <1>;
-				#size-cells = <0>;
 			};
 
 			gpio@22{
 				compatible = "ti,tca6424";
 				reg = <0x22>;
+				gpio-controller;
+				#gpio-cells = <2>;
 			};
 
 			pwm@23{
-				compatible = "max31790";
+				compatible = "maxim,max31790";
 				reg = <0x23>;
-				#address-cells = <1>;
-				#size-cells = <0>;
 			};
 
 			adc@33 {
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/broadcom/bcm2837-rpi-cm3-io3.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/broadcom/bcm2837-rpi-cm3-io3.dts
@@ -77,7 +77,7 @@
 };
 
 &hdmi {
-	hpd-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
+	hpd-gpios = <&expgpio 0 GPIO_ACTIVE_LOW>;
 	power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/intel/socfpga/socfpga_arria10.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/intel/socfpga/socfpga_arria10.dtsi
@@ -440,7 +440,7 @@
 			clocks = <&l4_mp_clk>, <&peri_emac_ptp_clk>;
 			clock-names = "stmmaceth", "ptp_ref";
 			resets = <&rst EMAC0_RESET>, <&rst EMAC0_OCP_RESET>;
-			reset-names = "stmmaceth", "ahb";
+			reset-names = "stmmaceth", "stmmaceth-ocp";
 			snps,axi-config = <&socfpga_axi_setup>;
 			status = "disabled";
 		};
@@ -460,7 +460,7 @@
 			clocks = <&l4_mp_clk>, <&peri_emac_ptp_clk>;
 			clock-names = "stmmaceth", "ptp_ref";
 			resets = <&rst EMAC1_RESET>, <&rst EMAC1_OCP_RESET>;
-			reset-names = "stmmaceth", "ahb";
+			reset-names = "stmmaceth", "stmmaceth-ocp";
 			snps,axi-config = <&socfpga_axi_setup>;
 			status = "disabled";
 		};
@@ -480,7 +480,7 @@
 			clocks = <&l4_mp_clk>, <&peri_emac_ptp_clk>;
 			clock-names = "stmmaceth", "ptp_ref";
 			resets = <&rst EMAC2_RESET>, <&rst EMAC2_OCP_RESET>;
-			reset-names = "stmmaceth", "ahb";
+			reset-names = "stmmaceth", "stmmaceth-ocp";
 			snps,axi-config = <&socfpga_axi_setup>;
 			status = "disabled";
 		};
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/marvell/mmp2-brownstone.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/marvell/mmp2-brownstone.dts
@@ -28,7 +28,7 @@
 &twsi1 {
 	status = "okay";
 	pmic: max8925@3c {
-		compatible = "maxium,max8925";
+		compatible = "maxim,max8925";
 		reg = <0x3c>;
 		interrupts = <1>;
 		interrupt-parent = <&intcmux4>;
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/mediatek/mt7623.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/mediatek/mt7623.dtsi
@@ -308,7 +308,7 @@
 		clock-names = "spi", "wrap";
 	};
 
-	cir: cir@10013000 {
+	cir: ir-receiver@10013000 {
 		compatible = "mediatek,mt7623-cir";
 		reg = <0 0x10013000 0 0x1000>;
 		interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_LOW>;
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/microchip/at91-sama5d27_wlsom1_ek.dts
@@ -197,6 +197,7 @@
 
 &sdmmc0 {
 	bus-width = <4>;
+	no-1-8-v;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc0_default>;
 	status = "okay";
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/microchip/at91-sama5d29_curiosity.dts
@@ -501,6 +501,7 @@
 
 &sdmmc0 {
 	bus-width = <4>;
+	no-1-8-v;
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sdmmc0_default>;
 	disable-wp;
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/microchip/at91-sama7g5ek.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/microchip/at91-sama7g5ek.dts
@@ -293,7 +293,7 @@
 
 					regulator-state-standby {
 						regulator-on-in-suspend;
-						regulator-suspend-voltage = <1150000>;
+						regulator-suspend-microvolt = <1150000>;
 						regulator-mode = <4>;
 					};
 
@@ -314,7 +314,7 @@
 
 					regulator-state-standby {
 						regulator-on-in-suspend;
-						regulator-suspend-voltage = <1050000>;
+						regulator-suspend-microvolt = <1050000>;
 						regulator-mode = <4>;
 					};
 
@@ -331,7 +331,7 @@
 					regulator-always-on;
 
 					regulator-state-standby {
-						regulator-suspend-voltage = <1800000>;
+						regulator-suspend-microvolt = <1800000>;
 						regulator-on-in-suspend;
 					};
 
@@ -346,7 +346,7 @@
 					regulator-max-microvolt = <3700000>;
 
 					regulator-state-standby {
-						regulator-suspend-voltage = <1800000>;
+						regulator-suspend-microvolt = <1800000>;
 						regulator-on-in-suspend;
 					};
 
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/microchip/sam9x60.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/microchip/sam9x60.dtsi
@@ -186,6 +186,7 @@
 					dma-names = "tx", "rx";
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 13>;
 					clock-names = "usart";
+					atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
 					atmel,use-dma-rx;
 					atmel,use-dma-tx;
 					atmel,fifo-size = <16>;
@@ -384,6 +385,7 @@
 					dma-names = "tx", "rx";
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 32>;
 					clock-names = "usart";
+					atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
 					atmel,use-dma-rx;
 					atmel,use-dma-tx;
 					atmel,fifo-size = <16>;
@@ -433,6 +435,7 @@
 					dma-names = "tx", "rx";
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 33>;
 					clock-names = "usart";
+					atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
 					atmel,use-dma-rx;
 					atmel,use-dma-tx;
 					atmel,fifo-size = <16>;
@@ -590,6 +593,7 @@
 					dma-names = "tx", "rx";
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 9>;
 					clock-names = "usart";
+					atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
 					atmel,use-dma-rx;
 					atmel,use-dma-tx;
 					atmel,fifo-size = <16>;
@@ -639,6 +643,7 @@
 					dma-names = "tx", "rx";
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 10>;
 					clock-names = "usart";
+					atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
 					atmel,use-dma-rx;
 					atmel,use-dma-tx;
 					atmel,fifo-size = <16>;
@@ -688,6 +693,7 @@
 					dma-names = "tx", "rx";
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 11>;
 					clock-names = "usart";
+					atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
 					atmel,use-dma-rx;
 					atmel,use-dma-tx;
 					atmel,fifo-size = <16>;
@@ -737,6 +743,7 @@
 					dma-names = "tx", "rx";
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 5>;
 					clock-names = "usart";
+					atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
 					atmel,use-dma-rx;
 					atmel,use-dma-tx;
 					atmel,fifo-size = <16>;
@@ -805,6 +812,7 @@
 					dma-names = "tx", "rx";
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 6>;
 					clock-names = "usart";
+					atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
 					atmel,use-dma-rx;
 					atmel,use-dma-tx;
 					atmel,fifo-size = <16>;
@@ -873,6 +881,7 @@
 					dma-names = "tx", "rx";
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 7>;
 					clock-names = "usart";
+					atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
 					atmel,use-dma-rx;
 					atmel,use-dma-tx;
 					atmel,fifo-size = <16>;
@@ -941,6 +950,7 @@
 					dma-names = "tx", "rx";
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 8>;
 					clock-names = "usart";
+					atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
 					atmel,use-dma-rx;
 					atmel,use-dma-tx;
 					atmel,fifo-size = <16>;
@@ -1064,6 +1074,7 @@
 					dma-names = "tx", "rx";
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 15>;
 					clock-names = "usart";
+					atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
 					atmel,use-dma-rx;
 					atmel,use-dma-tx;
 					atmel,fifo-size = <16>;
@@ -1113,6 +1124,7 @@
 					dma-names = "tx", "rx";
 					clocks = <&pmc PMC_TYPE_PERIPHERAL 16>;
 					clock-names = "usart";
+					atmel,usart-mode = <AT91_USART_MODE_SERIAL>;
 					atmel,use-dma-rx;
 					atmel,use-dma-tx;
 					atmel,fifo-size = <16>;
@@ -1312,7 +1324,7 @@
 				compatible = "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt";
 				reg = <0xfffffe20 0x20>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
-				clocks = <&clk32k 0>;
+				clocks = <&clk32k 1>;
 			};
 
 			pit: timer@fffffe40 {
@@ -1338,7 +1350,7 @@
 				compatible = "microchip,sam9x60-rtc", "atmel,at91sam9x5-rtc";
 				reg = <0xfffffea8 0x100>;
 				interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
-				clocks = <&clk32k 0>;
+				clocks = <&clk32k 1>;
 			};
 
 			watchdog: watchdog@ffffff80 {
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/microchip/sama7g5.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/microchip/sama7g5.dtsi
@@ -272,7 +272,7 @@
 			compatible = "microchip,sama7g5-rtt", "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt";
 			reg = <0xe001d020 0x30>;
 			interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&clk32k 0>;
+			clocks = <&clk32k 1>;
 		};
 
 		clk32k: clock-controller@e001d050 {
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/nxp/imx/imx6dl-yapp4-common.dtsi
@@ -117,17 +117,9 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		phy_port2: phy@1 {
-			reg = <1>;
-		};
-
-		phy_port3: phy@2 {
-			reg = <2>;
-		};
-
 		switch@10 {
 			compatible = "qca,qca8334";
-			reg = <10>;
+			reg = <0x10>;
 			reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
 
 			switch_ports: ports {
@@ -149,15 +141,30 @@
 				eth2: port@2 {
 					reg = <2>;
 					label = "eth2";
+					phy-mode = "internal";
 					phy-handle = <&phy_port2>;
 				};
 
 				eth1: port@3 {
 					reg = <3>;
 					label = "eth1";
+					phy-mode = "internal";
 					phy-handle = <&phy_port3>;
 				};
 			};
+
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				phy_port2: ethernet-phy@1 {
+					reg = <1>;
+				};
+
+				phy_port3: ethernet-phy@2 {
+					reg = <2>;
+				};
+			};
 		};
 	};
 };
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/nxp/imx/imx6dl-yapp43-common.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/nxp/imx/imx6dl-yapp43-common.dtsi
@@ -274,24 +274,24 @@
 
 		led@0 {
 			chan-name = "R";
-			led-cur = /bits/ 8 <0x20>;
-			max-cur = /bits/ 8 <0x60>;
+			led-cur = /bits/ 8 <0x6e>;
+			max-cur = /bits/ 8 <0xc8>;
 			reg = <0>;
 			color = <LED_COLOR_ID_RED>;
 		};
 
 		led@1 {
 			chan-name = "G";
-			led-cur = /bits/ 8 <0x20>;
-			max-cur = /bits/ 8 <0x60>;
+			led-cur = /bits/ 8 <0xbe>;
+			max-cur = /bits/ 8 <0xc8>;
 			reg = <1>;
 			color = <LED_COLOR_ID_GREEN>;
 		};
 
 		led@2 {
 			chan-name = "B";
-			led-cur = /bits/ 8 <0x20>;
-			max-cur = /bits/ 8 <0x60>;
+			led-cur = /bits/ 8 <0xbe>;
+			max-cur = /bits/ 8 <0xc8>;
 			reg = <2>;
 			color = <LED_COLOR_ID_BLUE>;
 		};
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/nxp/imx/imx6q-kontron-samx6i.dtsi
@@ -5,31 +5,8 @@
 
 #include "imx6q.dtsi"
 #include "imx6qdl-kontron-samx6i.dtsi"
-#include <dt-bindings/gpio/gpio.h>
 
 / {
 	model = "Kontron SMARC sAMX6i Quad/Dual";
 	compatible = "kontron,imx6q-samx6i", "fsl,imx6q";
 };
-
-/* Quad/Dual SoMs have 3 chip-select signals */
-&ecspi4 {
-	cs-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>,
-		   <&gpio3 29 GPIO_ACTIVE_LOW>,
-		   <&gpio3 25 GPIO_ACTIVE_LOW>;
-};
-
-&pinctrl_ecspi4 {
-	fsl,pins = <
-		MX6QDL_PAD_EIM_D21__ECSPI4_SCLK 0x100b1
-		MX6QDL_PAD_EIM_D28__ECSPI4_MOSI 0x100b1
-		MX6QDL_PAD_EIM_D22__ECSPI4_MISO 0x100b1
-
-		/* SPI4_IMX_CS2# - connected to internal flash */
-		MX6QDL_PAD_EIM_D24__GPIO3_IO24 0x1b0b0
-		/* SPI4_IMX_CS0# - connected to SMARC SPI0_CS0# */
-		MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0
-		/* SPI4_CS3# - connected to  SMARC SPI0_CS1# */
-		MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x1b0b0
-	>;
-};
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/nxp/imx/imx6qdl-kontron-samx6i.dtsi
@@ -244,7 +244,8 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_ecspi4>;
 	cs-gpios = <&gpio3 24 GPIO_ACTIVE_LOW>,
-		   <&gpio3 29 GPIO_ACTIVE_LOW>;
+		   <&gpio3 29 GPIO_ACTIVE_LOW>,
+		   <&gpio3 25 GPIO_ACTIVE_LOW>;
 	status = "okay";
 
 	/* default boot source: workaround #1 for errata ERR006282 */
@@ -259,7 +260,7 @@
 &fec {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_enet>;
-	phy-mode = "rgmii";
+	phy-connection-type = "rgmii-id";
 	phy-handle = <&ethphy>;
 
 	mdio {
@@ -269,7 +270,7 @@
 		ethphy: ethernet-phy@1 {
 			compatible = "ethernet-phy-ieee802.3-c22";
 			reg = <1>;
-			reset-gpios = <&gpio1 25 GPIO_ACTIVE_LOW>;
+			reset-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
 			reset-assert-us = <1000>;
 		};
 	};
@@ -464,6 +465,8 @@
 			MX6QDL_PAD_EIM_D24__GPIO3_IO24 0x1b0b0
 			/* SPI_IMX_CS0# - connected to SMARC SPI0_CS0# */
 			MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0
+			/* SPI4_CS3# - connected to SMARC SPI0_CS1# */
+			MX6QDL_PAD_EIM_D25__GPIO3_IO25 0x1b0b0
 		>;
 	};
 
@@ -516,7 +519,7 @@
 			MX6QDL_PAD_ENET_MDIO__ENET_MDIO       0x1b0b0
 			MX6QDL_PAD_ENET_MDC__ENET_MDC         0x1b0b0
 			MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK  0x1b0b0
-			MX6QDL_PAD_ENET_CRS_DV__GPIO1_IO25    0x1b0b0 /* RST_GBE0_PHY# */
+			MX6QDL_PAD_NANDF_D1__GPIO2_IO01       0x1b0b0 /* RST_GBE0_PHY# */
 		>;
 	};
 
@@ -729,7 +732,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_pcie>;
 	wake-up-gpio = <&gpio6 18 GPIO_ACTIVE_HIGH>;
-	reset-gpio = <&gpio3 13 GPIO_ACTIVE_HIGH>;
+	reset-gpio = <&gpio3 13 GPIO_ACTIVE_LOW>;
 };
 
 /* LCD_BKLT_PWM */
@@ -817,5 +820,6 @@
 	/* CPLD is feeded by watchdog (hardwired) */
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_wdog1>;
+	fsl,ext-reset-output;
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/nxp/imx/imx6ul-geam.dts
@@ -366,7 +366,7 @@
 	};
 
 	pinctrl_tsc: tscgrp {
-		fsl,pin = <
+		fsl,pins = <
 			MX6UL_PAD_GPIO1_IO01__GPIO1_IO01	0xb0
 			MX6UL_PAD_GPIO1_IO02__GPIO1_IO02	0xb0
 			MX6UL_PAD_GPIO1_IO03__GPIO1_IO03	0xb0
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-common.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/nxp/imx/imx6ull-tarragon-common.dtsi
@@ -805,6 +805,7 @@
 		     &pinctrl_usb_pwr>;
 	dr_mode = "host";
 	power-active-high;
+	over-current-active-low;
 	disable-over-current;
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/nxp/imx/imx7-tqma7.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/nxp/imx/imx7-tqma7.dtsi
@@ -132,6 +132,7 @@
 	lm75a: temperature-sensor@48 {
 		compatible = "national,lm75a";
 		reg = <0x48>;
+		vs-supply = <&vgen4_reg>;
 	};
 
 	/* NXP SE97BTP with temperature sensor + eeprom, TQMa7x 02xx */
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/nxp/imx/imx7d-zii-rmu2.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/nxp/imx/imx7d-zii-rmu2.dts
@@ -350,7 +350,7 @@
 
 &iomuxc_lpsr {
 	pinctrl_enet1_phy_interrupt: enet1phyinterruptgrp {
-		fsl,phy = <
+		fsl,pins = <
 			MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2	0x08
 		>;
 	};
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/nxp/imx/imx7s-warp.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/nxp/imx/imx7s-warp.dts
@@ -210,6 +210,7 @@
 				remote-endpoint = <&mipi_from_sensor>;
 				clock-lanes = <0>;
 				data-lanes = <1>;
+				link-frequencies = /bits/ 64 <330000000>;
 			};
 		};
 	};
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/nxp/imx/imxrt1050.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/nxp/imx/imxrt1050.dtsi
@@ -87,7 +87,7 @@
 			reg = <0x402c0000 0x4000>;
 			interrupts = <110>;
 			clocks = <&clks IMXRT1050_CLK_IPG_PDOF>,
-				<&clks IMXRT1050_CLK_OSC>,
+				<&clks IMXRT1050_CLK_AHB_PODF>,
 				<&clks IMXRT1050_CLK_USDHC1>;
 			clock-names = "ipg", "ahb", "per";
 			bus-width = <4>;
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/qcom/qcom-msm8226-microsoft-common.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/qcom/qcom-msm8226-microsoft-common.dtsi
@@ -287,6 +287,10 @@
 	status = "okay";
 };
 
+&smbb {
+	status = "okay";
+};
+
 &usb {
 	extcon = <&smbb>;
 	dr_mode = "peripheral";
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi
@@ -1234,7 +1234,7 @@
 
 		qfprom: qfprom@fc4bc000 {
 			compatible = "qcom,msm8974-qfprom", "qcom,qfprom";
-			reg = <0xfc4bc000 0x1000>;
+			reg = <0xfc4bc000 0x2100>;
 			#address-cells = <1>;
 			#size-cells = <1>;
 
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi
@@ -580,12 +580,16 @@
 					  <&gcc GCC_USB30_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <200000000>;
 
-			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 51 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 10 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 11 IRQ_TYPE_EDGE_BOTH>,
-					      <&pdc 10 IRQ_TYPE_EDGE_BOTH>;
-			interrupt-names = "hs_phy_irq", "ss_phy_irq",
-					  "dm_hs_phy_irq", "dp_hs_phy_irq";
+					      <&pdc 51 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
+					  "dp_hs_phy_irq",
+					  "dm_hs_phy_irq",
+					  "ss_phy_irq";
 
 			power-domains = <&gcc USB30_GDSC>;
 
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi
@@ -501,14 +501,16 @@
 					  <&gcc GCC_USB30_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <200000000>;
 
-			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 76 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 19 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 18 IRQ_TYPE_EDGE_BOTH>,
-					      <&pdc 19 IRQ_TYPE_EDGE_BOTH>;
-			interrupt-names = "hs_phy_irq",
-					  "ss_phy_irq",
+					      <&pdc 76 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
+					  "dp_hs_phy_irq",
 					  "dm_hs_phy_irq",
-					  "dp_hs_phy_irq";
+					  "ss_phy_irq";
 
 			power-domains = <&gcc USB30_GDSC>;
 
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/renesas/r7s72100-genmai.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/renesas/r7s72100-genmai.dts
@@ -53,7 +53,7 @@
 
 			partition@4000000 {
 				label = "user1";
-				reg = <0x04000000 0x40000000>;
+				reg = <0x04000000 0x04000000>;
 			};
 		};
 	};
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/renesas/r8a73a4-ape6evm.dts
@@ -209,6 +209,18 @@
 	status = "okay";
 };
 
+&extal1_clk {
+	clock-frequency = <26000000>;
+};
+
+&extal2_clk {
+	clock-frequency = <48000000>;
+};
+
+&extalr_clk {
+	clock-frequency = <32768>;
+};
+
 &pfc {
 	scifa0_pins: scifa0 {
 		groups = "scifa0_data";
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/renesas/r8a73a4.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/renesas/r8a73a4.dtsi
@@ -450,17 +450,20 @@
 		extalr_clk: extalr {
 			compatible = "fixed-clock";
 			#clock-cells = <0>;
-			clock-frequency = <32768>;
+			/* This value must be overridden by the board. */
+			clock-frequency = <0>;
 		};
 		extal1_clk: extal1 {
 			compatible = "fixed-clock";
 			#clock-cells = <0>;
-			clock-frequency = <25000000>;
+			/* This value must be overridden by the board. */
+			clock-frequency = <0>;
 		};
 		extal2_clk: extal2 {
 			compatible = "fixed-clock";
 			#clock-cells = <0>;
-			clock-frequency = <48000000>;
+			/* This value must be overridden by the board. */
+			clock-frequency = <0>;
 		};
 		fsiack_clk: fsiack {
 			compatible = "fixed-clock";
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/rockchip/rk3036-kylin.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/rockchip/rk3036-kylin.dts
@@ -325,8 +325,8 @@
 &i2c2 {
 	status = "okay";
 
-	rt5616: rt5616@1b {
-		compatible = "rt5616";
+	rt5616: audio-codec@1b {
+		compatible = "realtek,rt5616";
 		reg = <0x1b>;
 		clocks = <&cru SCLK_I2S_OUT>;
 		clock-names = "mclk";
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/rockchip/rk3036.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/rockchip/rk3036.dtsi
@@ -384,12 +384,13 @@
 		};
 	};
 
-	acodec: acodec-ana@20030000 {
-		compatible = "rk3036-codec";
+	acodec: audio-codec@20030000 {
+		compatible = "rockchip,rk3036-codec";
 		reg = <0x20030000 0x4000>;
-		rockchip,grf = <&grf>;
 		clock-names = "acodec_pclk";
 		clocks = <&cru PCLK_ACODEC>;
+		rockchip,grf = <&grf>;
+		#sound-dai-cells = <0>;
 		status = "disabled";
 	};
 
@@ -399,7 +400,6 @@
 		interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru  PCLK_HDMI>;
 		clock-names = "pclk";
-		rockchip,grf = <&grf>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&hdmi_ctl>;
 		status = "disabled";
@@ -552,11 +552,11 @@
 	};
 
 	spi: spi@20074000 {
-		compatible = "rockchip,rockchip-spi";
+		compatible = "rockchip,rk3036-spi";
 		reg = <0x20074000 0x1000>;
 		interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&cru PCLK_SPI>, <&cru SCLK_SPI>;
-		clock-names = "apb-pclk","spi_pclk";
+		clocks = <&cru SCLK_SPI>, <&cru PCLK_SPI>;
+		clock-names = "spiclk", "apb_pclk";
 		dmas = <&pdma 8>, <&pdma 9>;
 		dma-names = "tx", "rx";
 		pinctrl-names = "default";
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/rockchip/rk3066a.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/rockchip/rk3066a.dtsi
@@ -128,6 +128,7 @@
 		pinctrl-0 = <&hdmii2c_xfer>, <&hdmi_hpd>;
 		power-domains = <&power RK3066_PD_VIO>;
 		rockchip,grf = <&grf>;
+		#sound-dai-cells = <0>;
 		status = "disabled";
 
 		ports {
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/rockchip/rk322x.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/rockchip/rk322x.dtsi
@@ -736,14 +736,20 @@
 		status = "disabled";
 
 		ports {
-			hdmi_in: port {
-				#address-cells = <1>;
-				#size-cells = <0>;
-				hdmi_in_vop: endpoint@0 {
-					reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			hdmi_in: port@0 {
+				reg = <0>;
+
+				hdmi_in_vop: endpoint {
 					remote-endpoint = <&vop_out_hdmi>;
 				};
 			};
+
+			hdmi_out: port@1 {
+				reg = <1>;
+			};
 		};
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/rockchip/rk3288.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/rockchip/rk3288.dtsi
@@ -1240,27 +1240,37 @@
 		compatible = "rockchip,rk3288-dw-hdmi";
 		reg = <0x0 0xff980000 0x0 0x20000>;
 		reg-io-width = <4>;
-		#sound-dai-cells = <0>;
-		rockchip,grf = <&grf>;
 		interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru  PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>, <&cru SCLK_HDMI_CEC>;
 		clock-names = "iahb", "isfr", "cec";
 		power-domains = <&power RK3288_PD_VIO>;
+		rockchip,grf = <&grf>;
+		#sound-dai-cells = <0>;
 		status = "disabled";
 
 		ports {
-			hdmi_in: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			hdmi_in: port@0 {
+				reg = <0>;
 				#address-cells = <1>;
 				#size-cells = <0>;
+
 				hdmi_in_vopb: endpoint@0 {
 					reg = <0>;
 					remote-endpoint = <&vopb_out_hdmi>;
 				};
+
 				hdmi_in_vopl: endpoint@1 {
 					reg = <1>;
 					remote-endpoint = <&vopl_out_hdmi>;
 				};
 			};
+
+			hdmi_out: port@1 {
+				reg = <1>;
+			};
 		};
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/samsung/exynos4210-smdkv310.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/samsung/exynos4210-smdkv310.dts
@@ -88,7 +88,7 @@
 &keypad {
 	samsung,keypad-num-rows = <2>;
 	samsung,keypad-num-columns = <8>;
-	linux,keypad-no-autorepeat;
+	linux,input-no-autorepeat;
 	wakeup-source;
 	pinctrl-names = "default";
 	pinctrl-0 = <&keypad_rows &keypad_cols>;
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/samsung/exynos4412-origen.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/samsung/exynos4412-origen.dts
@@ -453,7 +453,7 @@
 &keypad {
 	samsung,keypad-num-rows = <3>;
 	samsung,keypad-num-columns = <2>;
-	linux,keypad-no-autorepeat;
+	linux,input-no-autorepeat;
 	wakeup-source;
 	pinctrl-0 = <&keypad_rows &keypad_cols>;
 	pinctrl-names = "default";
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/samsung/exynos4412-smdk4412.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/samsung/exynos4412-smdk4412.dts
@@ -69,7 +69,7 @@
 &keypad {
 	samsung,keypad-num-rows = <3>;
 	samsung,keypad-num-columns = <8>;
-	linux,keypad-no-autorepeat;
+	linux,input-no-autorepeat;
 	wakeup-source;
 	pinctrl-0 = <&keypad_rows &keypad_cols>;
 	pinctrl-names = "default";
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/st/stm32mp151.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/st/stm32mp151.dtsi
@@ -50,6 +50,7 @@
 			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>;
 		interrupt-parent = <&intc>;
+		arm,no-tick-in-suspend;
 	};
 
 	clocks {
@@ -1164,7 +1165,7 @@
 			reg = <0x4c001000 0x400>;
 			st,proc-id = <0>;
 			interrupts-extended =
-				<&exti 61 1>,
+				<&exti 61 IRQ_TYPE_LEVEL_HIGH>,
 				<&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "rx", "tx";
 			clocks = <&rcc IPCC>;
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/st/stm32mp15xx-dhcom-drc02.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/st/stm32mp15xx-dhcom-drc02.dtsi
@@ -6,18 +6,6 @@
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/pwm/pwm.h>
 
-/ {
-	aliases {
-		serial0 = &uart4;
-		serial1 = &usart3;
-		serial2 = &uart8;
-	};
-
-	chosen {
-		stdout-path = "serial0:115200n8";
-	};
-};
-
 &adc {
 	status = "disabled";
 };
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/st/stm32mp15xx-dhcom-pdk2.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/st/stm32mp15xx-dhcom-pdk2.dtsi
@@ -7,16 +7,6 @@
 #include <dt-bindings/pwm/pwm.h>
 
 / {
-	aliases {
-		serial0 = &uart4;
-		serial1 = &usart3;
-		serial2 = &uart8;
-	};
-
-	chosen {
-		stdout-path = "serial0:115200n8";
-	};
-
 	clk_ext_audio_codec: clock-codec {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/st/stm32mp15xx-dhcom-picoitx.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/st/stm32mp15xx-dhcom-picoitx.dtsi
@@ -7,16 +7,6 @@
 #include <dt-bindings/pwm/pwm.h>
 
 / {
-	aliases {
-		serial0 = &uart4;
-		serial1 = &usart3;
-		serial2 = &uart8;
-	};
-
-	chosen {
-		stdout-path = "serial0:115200n8";
-	};
-
 	led {
 		compatible = "gpio-leds";
 
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
@@ -14,6 +14,13 @@
 		ethernet1 = &ksz8851;
 		rtc0 = &hwrtc;
 		rtc1 = &rtc;
+		serial0 = &uart4;
+		serial1 = &uart8;
+		serial2 = &usart3;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
 	};
 
 	memory@c0000000 {
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi
@@ -12,6 +12,7 @@
 	ranges = <0x00000000 0x4a000000 0x100000>,	/* segment 0 */
 		 <0x00100000 0x4a100000 0x100000>,	/* segment 1 */
 		 <0x00200000 0x4a200000 0x100000>;	/* segment 2 */
+	dma-ranges;
 
 	segment@0 {					/* 0x4a000000 */
 		compatible = "simple-pm-bus";
@@ -557,6 +558,7 @@
 			 <0x0007e000 0x0017e000 0x001000>,	/* ap 124 */
 			 <0x00059000 0x00159000 0x001000>,	/* ap 125 */
 			 <0x0005a000 0x0015a000 0x001000>;	/* ap 126 */
+		dma-ranges;
 
 		target-module@2000 {			/* 0x4a102000, ap 27 3c.0 */
 			compatible = "ti,sysc";
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/ti/omap/omap3-gta04.dtsi
@@ -446,6 +446,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <
 			&hsusb2_2_pins
+			&mcspi3hog_pins
 	>;
 
 	hsusb2_2_pins: hsusb2-2-pins {
@@ -459,6 +460,15 @@
 		>;
 	};
 
+	mcspi3hog_pins: mcspi3hog-pins {
+		pinctrl-single,pins = <
+			OMAP3630_CORE2_IOPAD(0x25dc, PIN_OUTPUT_PULLDOWN | MUX_MODE4)	/* etk_d0 */
+			OMAP3630_CORE2_IOPAD(0x25de, PIN_OUTPUT_PULLDOWN | MUX_MODE4)	/* etk_d1 */
+			OMAP3630_CORE2_IOPAD(0x25e0, PIN_OUTPUT_PULLDOWN | MUX_MODE4)	/* etk_d2 */
+			OMAP3630_CORE2_IOPAD(0x25e2, PIN_OUTPUT_PULLDOWN | MUX_MODE4)	/* etk_d3 */
+		>;
+	};
+
 	spi_gpio_pins: spi-gpio-pinmux-pins {
 		pinctrl-single,pins = <
 			OMAP3630_CORE2_IOPAD(0x25d8, PIN_OUTPUT | MUX_MODE4) /* clk */
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/ti/omap/omap3-n900.dts
+++ linux-qcom-6.8.0/arch/arm/boot/dts/ti/omap/omap3-n900.dts
@@ -781,7 +781,7 @@
 
 		mount-matrix =	 "-1",  "0",  "0",
 				  "0",  "1",  "0",
-				  "0",  "0",  "1";
+				  "0",  "0",  "-1";
 	};
 
 	cam1: camera@3e {
--- linux-qcom-6.8.0.orig/arch/arm/boot/dts/ti/omap/omap36xx.dtsi
+++ linux-qcom-6.8.0/arch/arm/boot/dts/ti/omap/omap36xx.dtsi
@@ -72,6 +72,7 @@
 					 <1375000 1375000 1375000>;
 			/* only on am/dm37x with speed-binned bit set */
 			opp-supported-hw = <0xffffffff 2>;
+			turbo-mode;
 		};
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm/configs/sunxi_defconfig
+++ linux-qcom-6.8.0/arch/arm/configs/sunxi_defconfig
@@ -110,6 +110,7 @@
 CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_PANEL_EDP=y
 CONFIG_DRM_SIMPLE_BRIDGE=y
+CONFIG_DRM_DW_HDMI=y
 CONFIG_DRM_LIMA=y
 CONFIG_FB_SIMPLE=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
--- linux-qcom-6.8.0.orig/arch/arm/crypto/aes-ce-glue.c
+++ linux-qcom-6.8.0/arch/arm/crypto/aes-ce-glue.c
@@ -711,7 +711,7 @@
 		algname = aes_algs[i].base.cra_name + 2;
 		drvname = aes_algs[i].base.cra_driver_name + 2;
 		basename = aes_algs[i].base.cra_driver_name;
-		simd = simd_skcipher_create_compat(algname, drvname, basename);
+		simd = simd_skcipher_create_compat(aes_algs + i, algname, drvname, basename);
 		err = PTR_ERR(simd);
 		if (IS_ERR(simd))
 			goto unregister_simds;
--- linux-qcom-6.8.0.orig/arch/arm/crypto/aes-neonbs-glue.c
+++ linux-qcom-6.8.0/arch/arm/crypto/aes-neonbs-glue.c
@@ -539,7 +539,7 @@
 		algname = aes_algs[i].base.cra_name + 2;
 		drvname = aes_algs[i].base.cra_driver_name + 2;
 		basename = aes_algs[i].base.cra_driver_name;
-		simd = simd_skcipher_create_compat(algname, drvname, basename);
+		simd = simd_skcipher_create_compat(aes_algs + i, algname, drvname, basename);
 		err = PTR_ERR(simd);
 		if (IS_ERR(simd))
 			goto unregister_simds;
--- linux-qcom-6.8.0.orig/arch/arm/crypto/sha256_glue.c
+++ linux-qcom-6.8.0/arch/arm/crypto/sha256_glue.c
@@ -24,8 +24,8 @@
 
 #include "sha256_glue.h"
 
-asmlinkage void sha256_block_data_order(u32 *digest, const void *data,
-					unsigned int num_blks);
+asmlinkage void sha256_block_data_order(struct sha256_state *state,
+					const u8 *data, int num_blks);
 
 int crypto_sha256_arm_update(struct shash_desc *desc, const u8 *data,
 			     unsigned int len)
@@ -33,23 +33,20 @@
 	/* make sure casting to sha256_block_fn() is safe */
 	BUILD_BUG_ON(offsetof(struct sha256_state, state) != 0);
 
-	return sha256_base_do_update(desc, data, len,
-				(sha256_block_fn *)sha256_block_data_order);
+	return sha256_base_do_update(desc, data, len, sha256_block_data_order);
 }
 EXPORT_SYMBOL(crypto_sha256_arm_update);
 
 static int crypto_sha256_arm_final(struct shash_desc *desc, u8 *out)
 {
-	sha256_base_do_finalize(desc,
-				(sha256_block_fn *)sha256_block_data_order);
+	sha256_base_do_finalize(desc, sha256_block_data_order);
 	return sha256_base_finish(desc, out);
 }
 
 int crypto_sha256_arm_finup(struct shash_desc *desc, const u8 *data,
 			    unsigned int len, u8 *out)
 {
-	sha256_base_do_update(desc, data, len,
-			      (sha256_block_fn *)sha256_block_data_order);
+	sha256_base_do_update(desc, data, len, sha256_block_data_order);
 	return crypto_sha256_arm_final(desc, out);
 }
 EXPORT_SYMBOL(crypto_sha256_arm_finup);
--- linux-qcom-6.8.0.orig/arch/arm/crypto/sha512-glue.c
+++ linux-qcom-6.8.0/arch/arm/crypto/sha512-glue.c
@@ -25,27 +25,25 @@
 MODULE_ALIAS_CRYPTO("sha384-arm");
 MODULE_ALIAS_CRYPTO("sha512-arm");
 
-asmlinkage void sha512_block_data_order(u64 *state, u8 const *src, int blocks);
+asmlinkage void sha512_block_data_order(struct sha512_state *state,
+					u8 const *src, int blocks);
 
 int sha512_arm_update(struct shash_desc *desc, const u8 *data,
 		      unsigned int len)
 {
-	return sha512_base_do_update(desc, data, len,
-		(sha512_block_fn *)sha512_block_data_order);
+	return sha512_base_do_update(desc, data, len, sha512_block_data_order);
 }
 
 static int sha512_arm_final(struct shash_desc *desc, u8 *out)
 {
-	sha512_base_do_finalize(desc,
-		(sha512_block_fn *)sha512_block_data_order);
+	sha512_base_do_finalize(desc, sha512_block_data_order);
 	return sha512_base_finish(desc, out);
 }
 
 int sha512_arm_finup(struct shash_desc *desc, const u8 *data,
 		     unsigned int len, u8 *out)
 {
-	sha512_base_do_update(desc, data, len,
-		(sha512_block_fn *)sha512_block_data_order);
+	sha512_base_do_update(desc, data, len, sha512_block_data_order);
 	return sha512_arm_final(desc, out);
 }
 
--- linux-qcom-6.8.0.orig/arch/arm/include/asm/mman.h
+++ linux-qcom-6.8.0/arch/arm/include/asm/mman.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MMAN_H__
+#define __ASM_MMAN_H__
+
+#include <asm/system_info.h>
+#include <uapi/asm/mman.h>
+
+static inline bool arch_memory_deny_write_exec_supported(void)
+{
+	return cpu_architecture() >= CPU_ARCH_ARMv6;
+}
+#define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported
+
+#endif /* __ASM_MMAN_H__ */
--- linux-qcom-6.8.0.orig/arch/arm/kernel/Makefile
+++ linux-qcom-6.8.0/arch/arm/kernel/Makefile
@@ -75,8 +75,6 @@
 obj-$(CONFIG_CPU_XSCALE)	+= xscale-cp0.o
 obj-$(CONFIG_CPU_XSC3)		+= xscale-cp0.o
 obj-$(CONFIG_CPU_MOHAWK)	+= xscale-cp0.o
-obj-$(CONFIG_CPU_PJ4)		+= pj4-cp0.o
-obj-$(CONFIG_CPU_PJ4B)		+= pj4-cp0.o
 obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
 obj-$(CONFIG_PERF_EVENTS)	+= perf_regs.o perf_callchain.o
 obj-$(CONFIG_HW_PERF_EVENTS)	+= perf_event_xscale.o perf_event_v6.o \
--- linux-qcom-6.8.0.orig/arch/arm/kernel/devtree.c
+++ linux-qcom-6.8.0/arch/arm/kernel/devtree.c
@@ -200,7 +200,7 @@
 
 	mdesc_best = &__mach_desc_GENERIC_DT;
 
-	if (!dt_virt || !early_init_dt_verify(dt_virt))
+	if (!dt_virt || !early_init_dt_verify(dt_virt, __pa(dt_virt)))
 		return NULL;
 
 	mdesc = of_flat_dt_match_machine(mdesc_best, arch_get_next_mach);
--- linux-qcom-6.8.0.orig/arch/arm/kernel/entry-armv.S
+++ linux-qcom-6.8.0/arch/arm/kernel/entry-armv.S
@@ -25,6 +25,7 @@
 #include <asm/tls.h>
 #include <asm/system_info.h>
 #include <asm/uaccess-asm.h>
+#include <asm/kasan_def.h>
 
 #include "entry-header.S"
 #include <asm/probes.h>
@@ -555,6 +556,13 @@
 	@ entries covering the vmalloc region.
 	@
 	ldr	r2, [ip]
+#ifdef CONFIG_KASAN_VMALLOC
+	@ Also dummy read from the KASAN shadow memory for the new stack if we
+	@ are using KASAN
+	mov_l	r2, KASAN_SHADOW_OFFSET
+	add	r2, r2, ip, lsr #KASAN_SHADOW_SCALE_SHIFT
+	ldr	r2, [r2]
+#endif
 #endif
 
 	@ When CONFIG_THREAD_INFO_IN_TASK=n, the update of SP itself is what
--- linux-qcom-6.8.0.orig/arch/arm/kernel/head.S
+++ linux-qcom-6.8.0/arch/arm/kernel/head.S
@@ -252,18 +252,23 @@
 	 */
 	add	r0, r4, #KERNEL_OFFSET >> (SECTION_SHIFT - PMD_ENTRY_ORDER)
 	ldr	r6, =(_end - 1)
+
+	/* For XIP, kernel_sec_start/kernel_sec_end are currently in RO memory */
+#ifndef CONFIG_XIP_KERNEL
 	adr_l	r5, kernel_sec_start		@ _pa(kernel_sec_start)
 #if defined CONFIG_CPU_ENDIAN_BE8 || defined CONFIG_CPU_ENDIAN_BE32
 	str	r8, [r5, #4]			@ Save physical start of kernel (BE)
 #else
 	str	r8, [r5]			@ Save physical start of kernel (LE)
 #endif
+#endif
 	orr	r3, r8, r7			@ Add the MMU flags
 	add	r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ENTRY_ORDER)
 1:	str	r3, [r0], #1 << PMD_ENTRY_ORDER
 	add	r3, r3, #1 << SECTION_SHIFT
 	cmp	r0, r6
 	bls	1b
+#ifndef CONFIG_XIP_KERNEL
 	eor	r3, r3, r7			@ Remove the MMU flags
 	adr_l	r5, kernel_sec_end		@ _pa(kernel_sec_end)
 #if defined CONFIG_CPU_ENDIAN_BE8 || defined CONFIG_CPU_ENDIAN_BE32
@@ -271,8 +276,7 @@
 #else
 	str	r3, [r5]			@ Save physical end of kernel (LE)
 #endif
-
-#ifdef CONFIG_XIP_KERNEL
+#else
 	/*
 	 * Map the kernel image separately as it is not located in RAM.
 	 */
@@ -407,7 +411,11 @@
 	/*
 	 * Use the page tables supplied from  __cpu_up.
 	 */
+#ifdef CONFIG_XIP_KERNEL
+	ldr	r3, =(secondary_data + PLAT_PHYS_OFFSET - PAGE_OFFSET)
+#else
 	adr_l	r3, secondary_data
+#endif
 	mov_l	r12, __secondary_switched
 	ldrd	r4, r5, [r3, #0]		@ get secondary_data.pgdir
 ARM_BE8(eor	r4, r4, r5)			@ Swap r5 and r4 in BE:
--- linux-qcom-6.8.0.orig/arch/arm/kernel/iwmmxt.S
+++ linux-qcom-6.8.0/arch/arm/kernel/iwmmxt.S
@@ -18,18 +18,6 @@
 #include <asm/assembler.h>
 #include "iwmmxt.h"
 
-#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B)
-#define PJ4(code...)		code
-#define XSC(code...)
-#elif defined(CONFIG_CPU_MOHAWK) || \
-	defined(CONFIG_CPU_XSC3) || \
-	defined(CONFIG_CPU_XSCALE)
-#define PJ4(code...)
-#define XSC(code...)		code
-#else
-#error "Unsupported iWMMXt architecture"
-#endif
-
 #define MMX_WR0		 	(0x00)
 #define MMX_WR1		 	(0x08)
 #define MMX_WR2		 	(0x10)
@@ -81,17 +69,13 @@
 ENTRY(iwmmxt_task_enable)
 	inc_preempt_count r10, r3
 
-	XSC(mrc	p15, 0, r2, c15, c1, 0)
-	PJ4(mrc p15, 0, r2, c1, c0, 2)
+	mrc	p15, 0, r2, c15, c1, 0
 	@ CP0 and CP1 accessible?
-	XSC(tst	r2, #0x3)
-	PJ4(tst	r2, #0xf)
+	tst	r2, #0x3
 	bne	4f				@ if so no business here
 	@ enable access to CP0 and CP1
-	XSC(orr	r2, r2, #0x3)
-	XSC(mcr	p15, 0, r2, c15, c1, 0)
-	PJ4(orr	r2, r2, #0xf)
-	PJ4(mcr	p15, 0, r2, c1, c0, 2)
+	orr	r2, r2, #0x3
+	mcr	p15, 0, r2, c15, c1, 0
 
 	ldr	r3, =concan_owner
 	ldr	r2, [r0, #S_PC]			@ current task pc value
@@ -218,12 +202,9 @@
 	bne	1f				@ no: quit
 
 	@ enable access to CP0 and CP1
-	XSC(mrc	p15, 0, r4, c15, c1, 0)
-	XSC(orr	r4, r4, #0x3)
-	XSC(mcr	p15, 0, r4, c15, c1, 0)
-	PJ4(mrc p15, 0, r4, c1, c0, 2)
-	PJ4(orr	r4, r4, #0xf)
-	PJ4(mcr	p15, 0, r4, c1, c0, 2)
+	mrc	p15, 0, r4, c15, c1, 0
+	orr	r4, r4, #0x3
+	mcr	p15, 0, r4, c15, c1, 0
 
 	mov	r0, #0				@ nothing to load
 	str	r0, [r3]			@ no more current owner
@@ -232,10 +213,8 @@
 	bl	concan_save
 
 	@ disable access to CP0 and CP1
-	XSC(bic	r4, r4, #0x3)
-	XSC(mcr	p15, 0, r4, c15, c1, 0)
-	PJ4(bic	r4, r4, #0xf)
-	PJ4(mcr	p15, 0, r4, c1, c0, 2)
+	bic	r4, r4, #0x3
+	mcr	p15, 0, r4, c15, c1, 0
 
 	mrc	p15, 0, r2, c2, c0, 0
 	mov	r2, r2				@ cpwait
@@ -330,11 +309,9 @@
  */
 ENTRY(iwmmxt_task_switch)
 
-	XSC(mrc	p15, 0, r1, c15, c1, 0)
-	PJ4(mrc	p15, 0, r1, c1, c0, 2)
+	mrc	p15, 0, r1, c15, c1, 0
 	@ CP0 and CP1 accessible?
-	XSC(tst	r1, #0x3)
-	PJ4(tst	r1, #0xf)
+	tst	r1, #0x3
 	bne	1f				@ yes: block them for next task
 
 	ldr	r2, =concan_owner
@@ -344,10 +321,8 @@
 	retne	lr				@ no: leave Concan disabled
 
 1:	@ flip Concan access
-	XSC(eor	r1, r1, #0x3)
-	XSC(mcr	p15, 0, r1, c15, c1, 0)
-	PJ4(eor r1, r1, #0xf)
-	PJ4(mcr	p15, 0, r1, c1, c0, 2)
+	eor	r1, r1, #0x3
+	mcr	p15, 0, r1, c15, c1, 0
 
 	mrc	p15, 0, r1, c2, c0, 0
 	sub	pc, lr, r1, lsr #32		@ cpwait and return
--- linux-qcom-6.8.0.orig/arch/arm/kernel/perf_callchain.c
+++ linux-qcom-6.8.0/arch/arm/kernel/perf_callchain.c
@@ -85,8 +85,7 @@
 callchain_trace(void *data, unsigned long pc)
 {
 	struct perf_callchain_entry_ctx *entry = data;
-	perf_callchain_store(entry, pc);
-	return true;
+	return perf_callchain_store(entry, pc) == 0;
 }
 
 void
--- linux-qcom-6.8.0.orig/arch/arm/kernel/psci_smp.c
+++ linux-qcom-6.8.0/arch/arm/kernel/psci_smp.c
@@ -45,8 +45,15 @@
 static int psci_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	if (psci_ops.cpu_on)
+#ifdef CONFIG_XIP_KERNEL
+		return psci_ops.cpu_on(cpu_logical_map(cpu),
+			((phys_addr_t)(&secondary_startup)
+			- XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+			+ CONFIG_XIP_PHYS_ADDR));
+#else
 		return psci_ops.cpu_on(cpu_logical_map(cpu),
 					virt_to_idmap(&secondary_startup));
+#endif
 	return -ENODEV;
 }
 
--- linux-qcom-6.8.0.orig/arch/arm/kernel/sleep.S
+++ linux-qcom-6.8.0/arch/arm/kernel/sleep.S
@@ -127,6 +127,10 @@
 	instr_sync
 #endif
 	bl	cpu_init		@ restore the und/abt/irq banked regs
+#if defined(CONFIG_KASAN) && defined(CONFIG_KASAN_STACK)
+	mov	r0, sp
+	bl	kasan_unpoison_task_stack_below
+#endif
 	mov	r0, #0			@ return zero on success
 	ldmfd	sp!, {r4 - r11, pc}
 ENDPROC(cpu_resume_after_mmu)
--- linux-qcom-6.8.0.orig/arch/arm/kernel/traps.c
+++ linux-qcom-6.8.0/arch/arm/kernel/traps.c
@@ -569,6 +569,7 @@
 static inline int
 __do_cache_op(unsigned long start, unsigned long end)
 {
+	unsigned int ua_flags;
 	int ret;
 
 	do {
@@ -577,7 +578,9 @@
 		if (fatal_signal_pending(current))
 			return 0;
 
+		ua_flags = uaccess_save_and_enable();
 		ret = flush_icache_user_range(start, start + chunk);
+		uaccess_restore(ua_flags);
 		if (ret)
 			return ret;
 
--- linux-qcom-6.8.0.orig/arch/arm/mach-at91/pm.c
+++ linux-qcom-6.8.0/arch/arm/mach-at91/pm.c
@@ -591,7 +591,21 @@
 	return 0;
 }
 
-static void at91_pm_switch_ba_to_vbat(void)
+/**
+ * at91_pm_switch_ba_to_auto() - Configure Backup Unit Power Switch
+ * to automatic/hardware mode.
+ *
+ * The Backup Unit Power Switch can be managed either by software or hardware.
+ * Enabling hardware mode allows the automatic transition of power between
+ * VDDANA (or VDDIN33) and VDDBU (or VBAT, respectively), based on the
+ * availability of these power sources.
+ *
+ * If the Backup Unit Power Switch is already in automatic mode, no action is
+ * required. If it is in software-controlled mode, it is switched to automatic
+ * mode to enhance safety and eliminate the need for toggling between power
+ * sources.
+ */
+static void at91_pm_switch_ba_to_auto(void)
 {
 	unsigned int offset = offsetof(struct at91_pm_sfrbu_regs, pswbu);
 	unsigned int val;
@@ -602,24 +616,19 @@
 
 	val = readl(soc_pm.data.sfrbu + offset);
 
-	/* Already on VBAT. */
-	if (!(val & soc_pm.sfrbu_regs.pswbu.state))
+	/* Already on auto/hardware. */
+	if (!(val & soc_pm.sfrbu_regs.pswbu.ctrl))
 		return;
 
-	val &= ~soc_pm.sfrbu_regs.pswbu.softsw;
-	val |= soc_pm.sfrbu_regs.pswbu.key | soc_pm.sfrbu_regs.pswbu.ctrl;
+	val &= ~soc_pm.sfrbu_regs.pswbu.ctrl;
+	val |= soc_pm.sfrbu_regs.pswbu.key;
 	writel(val, soc_pm.data.sfrbu + offset);
-
-	/* Wait for update. */
-	val = readl(soc_pm.data.sfrbu + offset);
-	while (val & soc_pm.sfrbu_regs.pswbu.state)
-		val = readl(soc_pm.data.sfrbu + offset);
 }
 
 static void at91_pm_suspend(suspend_state_t state)
 {
 	if (soc_pm.data.mode == AT91_PM_BACKUP) {
-		at91_pm_switch_ba_to_vbat();
+		at91_pm_switch_ba_to_auto();
 
 		cpu_suspend(0, at91_suspend_finish);
 
--- linux-qcom-6.8.0.orig/arch/arm/mach-davinci/pm.c
+++ linux-qcom-6.8.0/arch/arm/mach-davinci/pm.c
@@ -61,7 +61,7 @@
 
 	/* Configure sleep count in deep sleep register */
 	val = __raw_readl(pm_config.deepsleep_reg);
-	val &= ~DEEPSLEEP_SLEEPCOUNT_MASK,
+	val &= ~DEEPSLEEP_SLEEPCOUNT_MASK;
 	val |= pm_config.sleepcount;
 	__raw_writel(val, pm_config.deepsleep_reg);
 
--- linux-qcom-6.8.0.orig/arch/arm/mach-ep93xx/clock.c
+++ linux-qcom-6.8.0/arch/arm/mach-ep93xx/clock.c
@@ -359,7 +359,7 @@
 	u32 val = __raw_readl(psc->reg);
 	u8 index = (val & psc->mask) >> psc->shift;
 
-	if (index > psc->num_div)
+	if (index >= psc->num_div)
 		return 0;
 
 	return DIV_ROUND_UP_ULL(parent_rate, psc->div[index]);
--- linux-qcom-6.8.0.orig/arch/arm/mach-omap1/board-nokia770.c
+++ linux-qcom-6.8.0/arch/arm/mach-omap1/board-nokia770.c
@@ -289,7 +289,7 @@
 		GPIO_LOOKUP("gpio-0-15", 15, "ads7846_irq",
 			    GPIO_ACTIVE_HIGH),
 		/* GPIO used for retu IRQ */
-		GPIO_LOOKUP("gpio-48-63", 15, "retu_irq",
+		GPIO_LOOKUP("gpio-48-63", 14, "retu_irq",
 			    GPIO_ACTIVE_HIGH),
 		/* GPIO used for tahvo IRQ */
 		GPIO_LOOKUP("gpio-32-47", 8, "tahvo_irq",
--- linux-qcom-6.8.0.orig/arch/arm/mach-omap2/board-n8x0.c
+++ linux-qcom-6.8.0/arch/arm/mach-omap2/board-n8x0.c
@@ -79,10 +79,8 @@
 static struct gpiod_lookup_table tusb_gpio_table = {
 	.dev_id = "musb-tusb",
 	.table = {
-		GPIO_LOOKUP("gpio-0-15", 0, "enable",
-			    GPIO_ACTIVE_HIGH),
-		GPIO_LOOKUP("gpio-48-63", 10, "int",
-			    GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio-0-31", 0, "enable", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio-32-63", 26, "int", GPIO_ACTIVE_HIGH),
 		{ }
 	},
 };
@@ -140,12 +138,11 @@
 static int slot2_cover_open;
 static struct device *mmc_device;
 
-static struct gpiod_lookup_table nokia8xx_mmc_gpio_table = {
+static struct gpiod_lookup_table nokia800_mmc_gpio_table = {
 	.dev_id = "mmci-omap.0",
 	.table = {
 		/* Slot switch, GPIO 96 */
-		GPIO_LOOKUP("gpio-80-111", 16,
-			    "switch", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("gpio-96-127", 0, "switch", GPIO_ACTIVE_HIGH),
 		{ }
 	},
 };
@@ -153,12 +150,12 @@
 static struct gpiod_lookup_table nokia810_mmc_gpio_table = {
 	.dev_id = "mmci-omap.0",
 	.table = {
+		/* Slot switch, GPIO 96 */
+		GPIO_LOOKUP("gpio-96-127", 0, "switch", GPIO_ACTIVE_HIGH),
 		/* Slot index 1, VSD power, GPIO 23 */
-		GPIO_LOOKUP_IDX("gpio-16-31", 7,
-				"vsd", 1, GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP_IDX("gpio-0-31", 23, "vsd", 1, GPIO_ACTIVE_HIGH),
 		/* Slot index 1, VIO power, GPIO 9 */
-		GPIO_LOOKUP_IDX("gpio-0-15", 9,
-				"vio", 1, GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP_IDX("gpio-0-31", 9, "vio", 1, GPIO_ACTIVE_HIGH),
 		{ }
 	},
 };
@@ -415,8 +412,6 @@
 
 static void __init n8x0_mmc_init(void)
 {
-	gpiod_add_lookup_table(&nokia8xx_mmc_gpio_table);
-
 	if (board_is_n810()) {
 		mmc1_data.slots[0].name = "external";
 
@@ -429,6 +424,8 @@
 		mmc1_data.slots[1].name = "internal";
 		mmc1_data.slots[1].ban_openended = 1;
 		gpiod_add_lookup_table(&nokia810_mmc_gpio_table);
+	} else {
+		gpiod_add_lookup_table(&nokia800_mmc_gpio_table);
 	}
 
 	mmc1_data.nr_slots = 2;
--- linux-qcom-6.8.0.orig/arch/arm/mach-pxa/spitz.c
+++ linux-qcom-6.8.0/arch/arm/mach-pxa/spitz.c
@@ -520,10 +520,8 @@
 static struct gpiod_lookup_table spitz_lcdcon_gpio_table = {
 	.dev_id = "spi2.1",
 	.table = {
-		GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_BACKLIGHT_CONT,
-			    "BL_CONT", GPIO_ACTIVE_LOW),
-		GPIO_LOOKUP("gpio-pxa", SPITZ_GPIO_BACKLIGHT_ON,
-			    "BL_ON", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sharp-scoop.1", 6, "BL_CONT", GPIO_ACTIVE_LOW),
+		GPIO_LOOKUP("sharp-scoop.1", 7, "BL_ON", GPIO_ACTIVE_HIGH),
 		{ },
 	},
 };
@@ -531,10 +529,8 @@
 static struct gpiod_lookup_table akita_lcdcon_gpio_table = {
 	.dev_id = "spi2.1",
 	.table = {
-		GPIO_LOOKUP("gpio-pxa", AKITA_GPIO_BACKLIGHT_CONT,
-			    "BL_CONT", GPIO_ACTIVE_LOW),
-		GPIO_LOOKUP("gpio-pxa", AKITA_GPIO_BACKLIGHT_ON,
-			    "BL_ON", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("i2c-max7310", 3, "BL_ON", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("i2c-max7310", 4, "BL_CONT", GPIO_ACTIVE_LOW),
 		{ },
 	},
 };
@@ -941,12 +937,9 @@
 static struct gpiod_lookup_table spitz_audio_gpio_table = {
 	.dev_id = "spitz-audio",
 	.table = {
-		GPIO_LOOKUP("sharp-scoop.0", SPITZ_GPIO_MUTE_L - SPITZ_SCP_GPIO_BASE,
-			    "mute-l", GPIO_ACTIVE_HIGH),
-		GPIO_LOOKUP("sharp-scoop.0", SPITZ_GPIO_MUTE_R - SPITZ_SCP_GPIO_BASE,
-			    "mute-r", GPIO_ACTIVE_HIGH),
-		GPIO_LOOKUP("sharp-scoop.1", SPITZ_GPIO_MIC_BIAS - SPITZ_SCP2_GPIO_BASE,
-			    "mic", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sharp-scoop.0", 3, "mute-l", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sharp-scoop.0", 4, "mute-r", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sharp-scoop.1", 8, "mic", GPIO_ACTIVE_HIGH),
 		{ },
 	},
 };
@@ -954,12 +947,9 @@
 static struct gpiod_lookup_table akita_audio_gpio_table = {
 	.dev_id = "spitz-audio",
 	.table = {
-		GPIO_LOOKUP("sharp-scoop.0", SPITZ_GPIO_MUTE_L - SPITZ_SCP_GPIO_BASE,
-			    "mute-l", GPIO_ACTIVE_HIGH),
-		GPIO_LOOKUP("sharp-scoop.0", SPITZ_GPIO_MUTE_R - SPITZ_SCP_GPIO_BASE,
-			    "mute-r", GPIO_ACTIVE_HIGH),
-		GPIO_LOOKUP("i2c-max7310", AKITA_GPIO_MIC_BIAS - AKITA_IOEXP_GPIO_BASE,
-			    "mic", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sharp-scoop.0", 3, "mute-l", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("sharp-scoop.0", 4, "mute-r", GPIO_ACTIVE_HIGH),
+		GPIO_LOOKUP("i2c-max7310", 2, "mic", GPIO_ACTIVE_HIGH),
 		{ },
 	},
 };
--- linux-qcom-6.8.0.orig/arch/arm/mach-versatile/platsmp-realview.c
+++ linux-qcom-6.8.0/arch/arm/mach-versatile/platsmp-realview.c
@@ -70,6 +70,7 @@
 		return;
 	}
 	map = syscon_node_to_regmap(np);
+	of_node_put(np);
 	if (IS_ERR(map)) {
 		pr_err("PLATSMP: No syscon regmap\n");
 		return;
--- linux-qcom-6.8.0.orig/arch/arm/mm/flush.c
+++ linux-qcom-6.8.0/arch/arm/mm/flush.c
@@ -296,6 +296,9 @@
 		return;
 
 	folio = page_folio(pfn_to_page(pfn));
+	if (folio_test_reserved(folio))
+		return;
+
 	if (cache_is_vipt_aliasing())
 		mapping = folio_flush_mapping(folio);
 	else
--- linux-qcom-6.8.0.orig/arch/arm/mm/idmap.c
+++ linux-qcom-6.8.0/arch/arm/mm/idmap.c
@@ -84,8 +84,15 @@
 	unsigned long addr, end;
 	unsigned long next;
 
+#ifdef CONFIG_XIP_KERNEL
+	addr = (phys_addr_t)(text_start) - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+		+ CONFIG_XIP_PHYS_ADDR;
+	end = (phys_addr_t)(text_end) - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+		+ CONFIG_XIP_PHYS_ADDR;
+#else
 	addr = virt_to_idmap(text_start);
 	end = virt_to_idmap(text_end);
+#endif
 	pr_info("Setting up static identity map for 0x%lx - 0x%lx\n", addr, end);
 
 	prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF;
--- linux-qcom-6.8.0.orig/arch/arm/mm/ioremap.c
+++ linux-qcom-6.8.0/arch/arm/mm/ioremap.c
@@ -23,6 +23,7 @@
  */
 #include <linux/module.h>
 #include <linux/errno.h>
+#include <linux/kasan.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
 #include <linux/io.h>
@@ -115,16 +116,40 @@
 }
 EXPORT_SYMBOL(ioremap_page);
 
+#ifdef CONFIG_KASAN
+static unsigned long arm_kasan_mem_to_shadow(unsigned long addr)
+{
+	return (unsigned long)kasan_mem_to_shadow((void *)addr);
+}
+#else
+static unsigned long arm_kasan_mem_to_shadow(unsigned long addr)
+{
+	return 0;
+}
+#endif
+
+static void memcpy_pgd(struct mm_struct *mm, unsigned long start,
+		       unsigned long end)
+{
+	end = ALIGN(end, PGDIR_SIZE);
+	memcpy(pgd_offset(mm, start), pgd_offset_k(start),
+	       sizeof(pgd_t) * (pgd_index(end) - pgd_index(start)));
+}
+
 void __check_vmalloc_seq(struct mm_struct *mm)
 {
 	int seq;
 
 	do {
-		seq = atomic_read(&init_mm.context.vmalloc_seq);
-		memcpy(pgd_offset(mm, VMALLOC_START),
-		       pgd_offset_k(VMALLOC_START),
-		       sizeof(pgd_t) * (pgd_index(VMALLOC_END) -
-					pgd_index(VMALLOC_START)));
+		seq = atomic_read_acquire(&init_mm.context.vmalloc_seq);
+		memcpy_pgd(mm, VMALLOC_START, VMALLOC_END);
+		if (IS_ENABLED(CONFIG_KASAN_VMALLOC)) {
+			unsigned long start =
+				arm_kasan_mem_to_shadow(VMALLOC_START);
+			unsigned long end =
+				arm_kasan_mem_to_shadow(VMALLOC_END);
+			memcpy_pgd(mm, start, end);
+		}
 		/*
 		 * Use a store-release so that other CPUs that observe the
 		 * counter's new value are guaranteed to see the results of the
--- linux-qcom-6.8.0.orig/arch/arm/mm/mmu.c
+++ linux-qcom-6.8.0/arch/arm/mm/mmu.c
@@ -1403,18 +1403,6 @@
 	}
 
 	/*
-	 * Map the kernel if it is XIP.
-	 * It is always first in the modulearea.
-	 */
-#ifdef CONFIG_XIP_KERNEL
-	map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
-	map.virtual = MODULES_VADDR;
-	map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
-	map.type = MT_ROM;
-	create_mapping(&map);
-#endif
-
-	/*
 	 * Map the cache flushing regions.
 	 */
 #ifdef FLUSH_BASE
@@ -1603,12 +1591,27 @@
 	 * This will only persist until we turn on proper memory management later on
 	 * and we remap the whole kernel with page granularity.
 	 */
+#ifdef CONFIG_XIP_KERNEL
+	phys_addr_t kernel_nx_start = kernel_sec_start;
+#else
 	phys_addr_t kernel_x_start = kernel_sec_start;
 	phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
 	phys_addr_t kernel_nx_start = kernel_x_end;
+#endif
 	phys_addr_t kernel_nx_end = kernel_sec_end;
 	struct map_desc map;
 
+	/*
+	 * Map the kernel if it is XIP.
+	 * It is always first in the modulearea.
+	 */
+#ifdef CONFIG_XIP_KERNEL
+	map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
+	map.virtual = MODULES_VADDR;
+	map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
+	map.type = MT_ROM;
+	create_mapping(&map);
+#else
 	map.pfn = __phys_to_pfn(kernel_x_start);
 	map.virtual = __phys_to_virt(kernel_x_start);
 	map.length = kernel_x_end - kernel_x_start;
@@ -1618,7 +1621,7 @@
 	/* If the nx part is small it may end up covered by the tail of the RWX section */
 	if (kernel_x_end == kernel_nx_end)
 		return;
-
+#endif
 	map.pfn = __phys_to_pfn(kernel_nx_start);
 	map.virtual = __phys_to_virt(kernel_nx_start);
 	map.length = kernel_nx_end - kernel_nx_start;
@@ -1763,6 +1766,11 @@
 {
 	void *zero_page;
 
+#ifdef CONFIG_XIP_KERNEL
+	/* Store the kernel RW RAM region start/end in these variables */
+	kernel_sec_start = CONFIG_PHYS_OFFSET & SECTION_MASK;
+	kernel_sec_end = round_up(__pa(_end), SECTION_SIZE);
+#endif
 	pr_debug("physical kernel sections: 0x%08llx-0x%08llx\n",
 		 kernel_sec_start, kernel_sec_end);
 
--- linux-qcom-6.8.0.orig/arch/arm/mm/proc-v7.S
+++ linux-qcom-6.8.0/arch/arm/mm/proc-v7.S
@@ -93,7 +93,7 @@
 	ret	lr
 ENDPROC(cpu_v7_dcache_clean_area)
 
-#ifdef CONFIG_ARM_PSCI
+#if defined(CONFIG_ARM_PSCI) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
 	.arch_extension sec
 ENTRY(cpu_v7_smc_switch_mm)
 	stmfd	sp!, {r0 - r3}
--- linux-qcom-6.8.0.orig/arch/arm/net/bpf_jit_32.c
+++ linux-qcom-6.8.0/arch/arm/net/bpf_jit_32.c
@@ -871,16 +871,11 @@
 }
 
 /* dst = src (4 bytes)*/
-static inline void emit_a32_mov_r(const s8 dst, const s8 src, const u8 off,
-				  struct jit_ctx *ctx) {
+static inline void emit_a32_mov_r(const s8 dst, const s8 src, struct jit_ctx *ctx) {
 	const s8 *tmp = bpf2a32[TMP_REG_1];
 	s8 rt;
 
 	rt = arm_bpf_get_reg32(src, tmp[0], ctx);
-	if (off && off != 32) {
-		emit(ARM_LSL_I(rt, rt, 32 - off), ctx);
-		emit(ARM_ASR_I(rt, rt, 32 - off), ctx);
-	}
 	arm_bpf_put_reg32(dst, rt, ctx);
 }
 
@@ -889,15 +884,15 @@
 				  const s8 src[],
 				  struct jit_ctx *ctx) {
 	if (!is64) {
-		emit_a32_mov_r(dst_lo, src_lo, 0, ctx);
+		emit_a32_mov_r(dst_lo, src_lo, ctx);
 		if (!ctx->prog->aux->verifier_zext)
 			/* Zero out high 4 bytes */
 			emit_a32_mov_i(dst_hi, 0, ctx);
 	} else if (__LINUX_ARM_ARCH__ < 6 &&
 		   ctx->cpu_architecture < CPU_ARCH_ARMv5TE) {
 		/* complete 8 byte move */
-		emit_a32_mov_r(dst_lo, src_lo, 0, ctx);
-		emit_a32_mov_r(dst_hi, src_hi, 0, ctx);
+		emit_a32_mov_r(dst_lo, src_lo, ctx);
+		emit_a32_mov_r(dst_hi, src_hi, ctx);
 	} else if (is_stacked(src_lo) && is_stacked(dst_lo)) {
 		const u8 *tmp = bpf2a32[TMP_REG_1];
 
@@ -917,17 +912,52 @@
 static inline void emit_a32_movsx_r64(const bool is64, const u8 off, const s8 dst[], const s8 src[],
 				      struct jit_ctx *ctx) {
 	const s8 *tmp = bpf2a32[TMP_REG_1];
-	const s8 *rt;
+	s8 rs;
+	s8 rd;
 
-	rt = arm_bpf_get_reg64(dst, tmp, ctx);
+	if (is_stacked(dst_lo))
+		rd = tmp[1];
+	else
+		rd = dst_lo;
+	rs = arm_bpf_get_reg32(src_lo, rd, ctx);
+	/* rs may be one of src[1], dst[1], or tmp[1] */
+
+	/* Sign extend rs if needed. If off == 32, lower 32-bits of src are moved to dst and sign
+	 * extension only happens in the upper 64 bits.
+	 */
+	if (off != 32) {
+		/* Sign extend rs into rd */
+		emit(ARM_LSL_I(rd, rs, 32 - off), ctx);
+		emit(ARM_ASR_I(rd, rd, 32 - off), ctx);
+	} else {
+		rd = rs;
+	}
+
+	/* Write rd to dst_lo
+	 *
+	 * Optimization:
+	 * Assume:
+	 * 1. dst == src and stacked.
+	 * 2. off == 32
+	 *
+	 * In this case src_lo was loaded into rd(tmp[1]) but rd was not sign extended as off==32.
+	 * So, we don't need to write rd back to dst_lo as they have the same value.
+	 * This saves us one str instruction.
+	 */
+	if (dst_lo != src_lo || off != 32)
+		arm_bpf_put_reg32(dst_lo, rd, ctx);
 
-	emit_a32_mov_r(dst_lo, src_lo, off, ctx);
 	if (!is64) {
 		if (!ctx->prog->aux->verifier_zext)
 			/* Zero out high 4 bytes */
 			emit_a32_mov_i(dst_hi, 0, ctx);
 	} else {
-		emit(ARM_ASR_I(rt[0], rt[1], 31), ctx);
+		if (is_stacked(dst_hi)) {
+			emit(ARM_ASR_I(tmp[0], rd, 31), ctx);
+			arm_bpf_put_reg32(dst_hi, tmp[0], ctx);
+		} else {
+			emit(ARM_ASR_I(dst_hi, rd, 31), ctx);
+		}
 	}
 }
 
@@ -2222,28 +2252,21 @@
 	/* If building the body of the JITed code fails somehow,
 	 * we fall back to the interpretation.
 	 */
-	if (build_body(&ctx) < 0) {
-		image_ptr = NULL;
-		bpf_jit_binary_free(header);
-		prog = orig_prog;
-		goto out_imms;
-	}
+	if (build_body(&ctx) < 0)
+		goto out_free;
 	build_epilogue(&ctx);
 
 	/* 3.) Extra pass to validate JITed Code */
-	if (validate_code(&ctx)) {
-		image_ptr = NULL;
-		bpf_jit_binary_free(header);
-		prog = orig_prog;
-		goto out_imms;
-	}
+	if (validate_code(&ctx))
+		goto out_free;
 	flush_icache_range((u32)header, (u32)(ctx.target + ctx.idx));
 
 	if (bpf_jit_enable > 1)
 		/* there are 2 passes here */
 		bpf_jit_dump(prog->len, image_size, 2, ctx.target);
 
-	bpf_jit_binary_lock_ro(header);
+	if (bpf_jit_binary_lock_ro(header))
+		goto out_free;
 	prog->bpf_func = (void *)ctx.target;
 	prog->jited = 1;
 	prog->jited_len = image_size;
@@ -2260,5 +2283,11 @@
 		bpf_jit_prog_release_other(prog, prog == orig_prog ?
 					   tmp : orig_prog);
 	return prog;
+
+out_free:
+	image_ptr = NULL;
+	bpf_jit_binary_free(header);
+	prog = orig_prog;
+	goto out_imms;
 }
 
--- linux-qcom-6.8.0.orig/arch/arm/vfp/vfpinstr.h
+++ linux-qcom-6.8.0/arch/arm/vfp/vfpinstr.h
@@ -64,33 +64,37 @@
 
 #ifdef CONFIG_AS_VFP_VMRS_FPINST
 
-#define fmrx(_vfp_) ({			\
-	u32 __v;			\
-	asm(".fpu	vfpv2\n"	\
-	    "vmrs	%0, " #_vfp_	\
-	    : "=r" (__v) : : "cc");	\
-	__v;				\
- })
-
-#define fmxr(_vfp_,_var_)		\
-	asm(".fpu	vfpv2\n"	\
-	    "vmsr	" #_vfp_ ", %0"	\
-	   : : "r" (_var_) : "cc")
+#define fmrx(_vfp_) ({				\
+	u32 __v;				\
+	asm volatile (".fpu	vfpv2\n"	\
+		      "vmrs	%0, " #_vfp_	\
+		     : "=r" (__v) : : "cc");	\
+	__v;					\
+})
+
+#define fmxr(_vfp_, _var_) ({			\
+	asm volatile (".fpu	vfpv2\n"	\
+		      "vmsr	" #_vfp_ ", %0"	\
+		     : : "r" (_var_) : "cc");	\
+})
 
 #else
 
 #define vfpreg(_vfp_) #_vfp_
 
-#define fmrx(_vfp_) ({			\
-	u32 __v;			\
-	asm("mrc p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmrx	%0, " #_vfp_	\
-	    : "=r" (__v) : : "cc");	\
-	__v;				\
- })
-
-#define fmxr(_vfp_,_var_)		\
-	asm("mcr p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr	" #_vfp_ ", %0"	\
-	   : : "r" (_var_) : "cc")
+#define fmrx(_vfp_) ({						\
+	u32 __v;						\
+	asm volatile ("mrc p10, 7, %0, " vfpreg(_vfp_) ","	\
+		      "cr0, 0 @ fmrx	%0, " #_vfp_		\
+		     : "=r" (__v) : : "cc");			\
+	__v;							\
+})
+
+#define fmxr(_vfp_, _var_) ({					\
+	asm volatile ("mcr p10, 7, %0, " vfpreg(_vfp_) ","	\
+		      "cr0, 0 @ fmxr	" #_vfp_ ", %0"		\
+		     : : "r" (_var_) : "cc");			\
+})
 
 #endif
 
--- linux-qcom-6.8.0.orig/arch/arm64/Kbuild
+++ linux-qcom-6.8.0/arch/arm64/Kbuild
@@ -3,6 +3,7 @@
 obj-$(CONFIG_KVM)	+= kvm/
 obj-$(CONFIG_XEN)	+= xen/
 obj-$(subst m,y,$(CONFIG_HYPERV))	+= hyperv/
+obj-$(CONFIG_GUNYAH)	+= gunyah/
 obj-$(CONFIG_CRYPTO)	+= crypto/
 
 # for cleaning
--- linux-qcom-6.8.0.orig/arch/arm64/Kconfig
+++ linux-qcom-6.8.0/arch/arm64/Kconfig
@@ -107,7 +107,7 @@
 	select ARCH_WANT_LD_ORPHAN_WARN
 	select ARCH_WANTS_NO_INSTR
 	select ARCH_WANTS_THP_SWAP if ARM64_4K_PAGES
-	select ARCH_HAS_UBSAN_SANITIZE_ALL
+	select ARCH_HAS_UBSAN
 	select ARM_AMBA
 	select ARM_ARCH_TIMER
 	select ARM_GIC
@@ -193,12 +193,13 @@
 	select HAVE_DMA_CONTIGUOUS
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_DYNAMIC_FTRACE_WITH_ARGS \
-		if $(cc-option,-fpatchable-function-entry=2)
+		if (GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS || \
+		    CLANG_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS)
 	select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS \
 		if DYNAMIC_FTRACE_WITH_ARGS && DYNAMIC_FTRACE_WITH_CALL_OPS
 	select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS \
 		if (DYNAMIC_FTRACE_WITH_ARGS && !CFI_CLANG && \
-		    !CC_OPTIMIZE_FOR_SIZE)
+		    (CC_IS_CLANG || !CC_OPTIMIZE_FOR_SIZE))
 	select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \
 		if DYNAMIC_FTRACE_WITH_ARGS
 	select HAVE_SAMPLE_FTRACE_DIRECT
@@ -264,12 +265,10 @@
 	def_bool CC_IS_CLANG
 	# https://github.com/ClangBuiltLinux/linux/issues/1507
 	depends on AS_IS_GNU || (AS_IS_LLVM && (LD_IS_LLD || LD_VERSION >= 23600))
-	select HAVE_DYNAMIC_FTRACE_WITH_ARGS
 
 config GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS
 	def_bool CC_IS_GCC
 	depends on $(cc-option,-fpatchable-function-entry=2)
-	select HAVE_DYNAMIC_FTRACE_WITH_ARGS
 
 config 64BIT
 	def_bool y
@@ -422,7 +421,7 @@
 	default y
 	help
 	  This option adds an alternative code sequence to work around Ampere
-	  erratum AC03_CPU_38 on AmpereOne.
+	  errata AC03_CPU_38 and AC04_CPU_10 on AmpereOne.
 
 	  The affected design reports FEAT_HAFDBS as not implemented in
 	  ID_AA64MMFR1_EL1.HAFDBS, but (V)TCR_ELx.{HA,HD} are not RES0
@@ -1070,6 +1069,46 @@
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_3194386
+	bool "Cortex-*/Neoverse-*: workaround for MSR SSBS not self-synchronizing"
+	default y
+	help
+	  This option adds the workaround for the following errata:
+
+	  * ARM Cortex-A76 erratum 3324349
+	  * ARM Cortex-A77 erratum 3324348
+	  * ARM Cortex-A78 erratum 3324344
+	  * ARM Cortex-A78C erratum 3324346
+	  * ARM Cortex-A78C erratum 3324347
+	  * ARM Cortex-A710 erratam 3324338
+	  * ARM Cortex-A715 errartum 3456084
+	  * ARM Cortex-A720 erratum 3456091
+	  * ARM Cortex-A725 erratum 3456106
+	  * ARM Cortex-X1 erratum 3324344
+	  * ARM Cortex-X1C erratum 3324346
+	  * ARM Cortex-X2 erratum 3324338
+	  * ARM Cortex-X3 erratum 3324335
+	  * ARM Cortex-X4 erratum 3194386
+	  * ARM Cortex-X925 erratum 3324334
+	  * ARM Neoverse-N1 erratum 3324349
+	  * ARM Neoverse N2 erratum 3324339
+	  * ARM Neoverse-N3 erratum 3456111
+	  * ARM Neoverse-V1 erratum 3324341
+	  * ARM Neoverse V2 erratum 3324336
+	  * ARM Neoverse-V3 erratum 3312417
+
+	  On affected cores "MSR SSBS, #0" instructions may not affect
+	  subsequent speculative instructions, which may permit unexepected
+	  speculative store bypassing.
+
+	  Work around this problem by placing a Speculation Barrier (SB) or
+	  Instruction Synchronization Barrier (ISB) after kernel changes to
+	  SSBS. The presence of the SSBS special-purpose register is hidden
+	  from hwcaps and EL0 reads of ID_AA64PFR1_EL1, such that userspace
+	  will use the PR_SPEC_STORE_BYPASS prctl to change SSBS.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
@@ -1178,6 +1217,17 @@
 
 	  If unsure, say Y.
 
+config HISILICON_ERRATUM_162100801
+	bool "Hip09 162100801 erratum support"
+	default y
+	help
+	  When enabling GICv4.1 in hip09, VMAPP will fail to clear some caches
+	  during unmapping operation, which will cause some vSGIs lost.
+	  To fix the issue, invalidate related vPE cache through GICR_INVALLR
+	  after VMOVP.
+
+	  If unsure, say Y.
+
 config QCOM_FALKOR_ERRATUM_1003
 	bool "Falkor E1003: Incorrect translation due to ASID change"
 	default y
@@ -1550,7 +1600,7 @@
 # 64K |       29          |      16      |       13             |         13              |
 config ARCH_FORCE_MAX_ORDER
 	int
-	default "13" if ARM64_64K_PAGES
+	default "13" if ARM64_64K_PAGES || (ARCH_THUNDER && ARM64_4K_PAGES)
 	default "11" if ARM64_16K_PAGES
 	default "10"
 	help
@@ -2133,6 +2183,7 @@
 	bool "ARM Scalable Matrix Extension support"
 	default y
 	depends on ARM64_SVE
+	depends on BROKEN
 	help
 	  The Scalable Matrix Extension (SME) is an extension to the AArch64
 	  execution state which utilises a substantial subset of the SVE
--- linux-qcom-6.8.0.orig/arch/arm64/Makefile
+++ linux-qcom-6.8.0/arch/arm64/Makefile
@@ -10,7 +10,7 @@
 #
 # Copyright (C) 1995-2001 by Russell King
 
-LDFLAGS_vmlinux	:=--no-undefined -X
+LDFLAGS_vmlinux	:=--no-undefined -X --pic-veneer
 
 ifeq ($(CONFIG_RELOCATABLE), y)
 # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
@@ -390,6 +390,8 @@
 &tcon0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&lcd_rgb666_pins>;
+	assigned-clocks = <&ccu CLK_TCON0>;
+	assigned-clock-parents = <&ccu CLK_PLL_VIDEO0_2X>;
 
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi
@@ -202,6 +202,9 @@
 		interrupts = <7 5 IRQ_TYPE_EDGE_RISING>; /* PH5 */
 		vdd-supply = <&reg_dldo1>;
 		vddio-supply = <&reg_dldo1>;
+		mount-matrix = "0", "1", "0",
+			       "-1", "0", "0",
+			       "0", "0", "1";
 	};
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts
@@ -369,6 +369,8 @@
 &tcon0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&lcd_rgb666_pins>;
+	assigned-clocks = <&ccu CLK_TCON0>;
+	assigned-clock-parents = <&ccu CLK_PLL_VIDEO0_2X>;
 
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -410,6 +410,8 @@
 			clock-names = "ahb", "tcon-ch0";
 			clock-output-names = "tcon-data-clock";
 			#clock-cells = <0>;
+			assigned-clocks = <&ccu CLK_TCON0>;
+			assigned-clock-parents = <&ccu CLK_PLL_MIPI>;
 			resets = <&ccu RST_BUS_TCON0>, <&ccu RST_BUS_LVDS>;
 			reset-names = "lcd", "lvds";
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
@@ -291,6 +291,8 @@
 };
 
 &spdif {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spdif_tx_pin>;
 	status = "okay";
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix.dtsi
@@ -166,6 +166,8 @@
 };
 
 &spdif {
+	pinctrl-names = "default";
+	pinctrl-0 = <&spdif_tx_pin>;
 	status = "okay";
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -406,6 +406,7 @@
 				function = "spi1";
 			};
 
+			/omit-if-no-ref/
 			spdif_tx_pin: spdif-tx-pin {
 				pins = "PH7";
 				function = "spdif";
@@ -655,10 +656,8 @@
 			clocks = <&ccu CLK_BUS_SPDIF>, <&ccu CLK_SPDIF>;
 			clock-names = "apb", "spdif";
 			resets = <&ccu RST_BUS_SPDIF>;
-			dmas = <&dma 2>;
-			dma-names = "tx";
-			pinctrl-names = "default";
-			pinctrl-0 = <&spdif_tx_pin>;
+			dmas = <&dma 2>, <&dma 2>;
+			dma-names = "rx", "tx";
 			status = "disabled";
 		};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -215,6 +215,11 @@
 				#sound-dai-cells = <0>;
 				status = "disabled";
 
+				assigned-clocks = <&clkc CLKID_HDMI_SEL>,
+						  <&clkc CLKID_HDMI>;
+				assigned-clock-parents = <&xtal>, <0>;
+				assigned-clock-rates = <0>, <24000000>;
+
 				/* VPU VENC Input */
 				hdmi_tx_venc_port: port@0 {
 					reg = <0>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/amlogic/meson-g12.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/amlogic/meson-g12.dtsi
@@ -363,6 +363,10 @@
 	power-domains = <&pwrc PWRC_G12A_ETH_ID>;
 };
 
+&hdmi_tx {
+	power-domains = <&pwrc PWRC_G12A_VPU_ID>;
+};
+
 &vpu {
 	power-domains = <&pwrc PWRC_G12A_VPU_ID>;
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -311,10 +311,16 @@
 		 <&reset RESET_HDMI_SYSTEM_RESET>,
 		 <&reset RESET_HDMI_TX>;
 	reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy";
-	clocks = <&clkc CLKID_HDMI_PCLK>,
-		 <&clkc CLKID_CLK81>,
+	clocks = <&clkc CLKID_HDMI>,
+		 <&clkc CLKID_HDMI_PCLK>,
 		 <&clkc CLKID_GCLK_VENCI_INT0>;
 	clock-names = "isfr", "iahb", "venci";
+	power-domains = <&pwrc PWRC_GXBB_VPU_ID>;
+
+	assigned-clocks = <&clkc CLKID_HDMI_SEL>,
+			  <&clkc CLKID_HDMI>;
+	assigned-clock-parents = <&xtal>, <0>;
+	assigned-clock-rates = <0>, <24000000>;
 };
 
 &sysctrl {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -323,10 +323,16 @@
 		 <&reset RESET_HDMI_SYSTEM_RESET>,
 		 <&reset RESET_HDMI_TX>;
 	reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy";
-	clocks = <&clkc CLKID_HDMI_PCLK>,
-		 <&clkc CLKID_CLK81>,
+	clocks = <&clkc CLKID_HDMI>,
+		 <&clkc CLKID_HDMI_PCLK>,
 		 <&clkc CLKID_GCLK_VENCI_INT0>;
 	clock-names = "isfr", "iahb", "venci";
+	power-domains = <&pwrc PWRC_GXBB_VPU_ID>;
+
+	assigned-clocks = <&clkc CLKID_HDMI_SEL>,
+			  <&clkc CLKID_HDMI>;
+	assigned-clock-parents = <&xtal>, <0>;
+	assigned-clock-rates = <0>, <24000000>;
 };
 
 &sysctrl {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/amlogic/meson-s4.dtsi
@@ -65,10 +65,15 @@
 		#clock-cells = <0>;
 	};
 
-	pwrc: power-controller {
-		compatible = "amlogic,meson-s4-pwrc";
-		#power-domain-cells = <1>;
-		status = "okay";
+	firmware {
+		sm: secure-monitor {
+			compatible = "amlogic,meson-gxbb-sm";
+
+			pwrc: power-controller {
+				compatible = "amlogic,meson-s4-pwrc";
+				#power-domain-cells = <1>;
+			};
+		};
 	};
 
 	soc {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
@@ -339,7 +339,7 @@
 		};
 
 		spdifin: audio-controller@400 {
-			compatible = "amlogic,g12a-spdifin",
+			compatible = "amlogic,sm1-spdifin",
 				     "amlogic,axg-spdifin";
 			reg = <0x0 0x400 0x0 0x30>;
 			#sound-dai-cells = <0>;
@@ -353,7 +353,7 @@
 		};
 
 		spdifout_a: audio-controller@480 {
-			compatible = "amlogic,g12a-spdifout",
+			compatible = "amlogic,sm1-spdifout",
 				     "amlogic,axg-spdifout";
 			reg = <0x0 0x480 0x0 0x50>;
 			#sound-dai-cells = <0>;
@@ -518,6 +518,10 @@
 		     "amlogic,meson-gpio-intc";
 };
 
+&hdmi_tx {
+	power-domains = <&pwrc PWRC_SM1_VPU_ID>;
+};
+
 &pcie {
 	power-domains = <&pwrc PWRC_SM1_PCIE_ID>;
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/broadcom/bcmbca/bcm4908.dtsi
@@ -227,9 +227,6 @@
 				brcm,num-gphy = <5>;
 				brcm,num-rgmii-ports = <2>;
 
-				#address-cells = <1>;
-				#size-cells = <0>;
-
 				ports: ports {
 					#address-cells = <1>;
 					#size-cells = <0>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/exynos/exynos7885-jackpotlte.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/exynos/exynos7885-jackpotlte.dts
@@ -32,7 +32,7 @@
 		device_type = "memory";
 		reg = <0x0 0x80000000 0x3da00000>,
 		      <0x0 0xc0000000 0x40000000>,
-		      <0x8 0x80000000 0x40000000>;
+		      <0x8 0x80000000 0x80000000>;
 	};
 
 	gpio-keys {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8-ss-conn.dtsi
@@ -41,7 +41,7 @@
 		interrupts = <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
 		fsl,usbphy = <&usbphy1>;
 		fsl,usbmisc = <&usbmisc1 0>;
-		clocks = <&usb2_lpcg 0>;
+		clocks = <&usb2_lpcg IMX_LPCG_CLK_6>;
 		ahb-burst-config = <0x0>;
 		tx-burst-size-dword = <0x10>;
 		rx-burst-size-dword = <0x10>;
@@ -58,7 +58,7 @@
 	usbphy1: usbphy@5b100000 {
 		compatible = "fsl,imx7ulp-usbphy";
 		reg = <0x5b100000 0x1000>;
-		clocks = <&usb2_lpcg 1>;
+		clocks = <&usb2_lpcg IMX_LPCG_CLK_7>;
 		power-domains = <&pd IMX_SC_R_USB_0_PHY>;
 		status = "disabled";
 	};
@@ -67,8 +67,8 @@
 		interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
 		reg = <0x5b010000 0x10000>;
 		clocks = <&sdhc0_lpcg IMX_LPCG_CLK_4>,
-			 <&sdhc0_lpcg IMX_LPCG_CLK_0>,
-			 <&sdhc0_lpcg IMX_LPCG_CLK_5>;
+			 <&sdhc0_lpcg IMX_LPCG_CLK_5>,
+			 <&sdhc0_lpcg IMX_LPCG_CLK_0>;
 		clock-names = "ipg", "ahb", "per";
 		power-domains = <&pd IMX_SC_R_SDHC_0>;
 		status = "disabled";
@@ -78,8 +78,8 @@
 		interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
 		reg = <0x5b020000 0x10000>;
 		clocks = <&sdhc1_lpcg IMX_LPCG_CLK_4>,
-			 <&sdhc1_lpcg IMX_LPCG_CLK_0>,
-			 <&sdhc1_lpcg IMX_LPCG_CLK_5>;
+			 <&sdhc1_lpcg IMX_LPCG_CLK_5>,
+			 <&sdhc1_lpcg IMX_LPCG_CLK_0>;
 		clock-names = "ipg", "ahb", "per";
 		power-domains = <&pd IMX_SC_R_SDHC_1>;
 		fsl,tuning-start-tap = <20>;
@@ -91,8 +91,8 @@
 		interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
 		reg = <0x5b030000 0x10000>;
 		clocks = <&sdhc2_lpcg IMX_LPCG_CLK_4>,
-			 <&sdhc2_lpcg IMX_LPCG_CLK_0>,
-			 <&sdhc2_lpcg IMX_LPCG_CLK_5>;
+			 <&sdhc2_lpcg IMX_LPCG_CLK_5>,
+			 <&sdhc2_lpcg IMX_LPCG_CLK_0>;
 		clock-names = "ipg", "ahb", "per";
 		power-domains = <&pd IMX_SC_R_SDHC_2>;
 		status = "disabled";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8-ss-dma.dtsi
@@ -27,8 +27,8 @@
 		#size-cells = <0>;
 		interrupts = <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-parent = <&gic>;
-		clocks = <&spi0_lpcg 0>,
-			 <&spi0_lpcg 1>;
+		clocks = <&spi0_lpcg IMX_LPCG_CLK_0>,
+			 <&spi0_lpcg IMX_LPCG_CLK_4>;
 		clock-names = "per", "ipg";
 		assigned-clocks = <&clk IMX_SC_R_SPI_0 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <60000000>;
@@ -43,8 +43,8 @@
 		#size-cells = <0>;
 		interrupts = <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-parent = <&gic>;
-		clocks = <&spi1_lpcg 0>,
-			 <&spi1_lpcg 1>;
+		clocks = <&spi1_lpcg IMX_LPCG_CLK_0>,
+			 <&spi1_lpcg IMX_LPCG_CLK_4>;
 		clock-names = "per", "ipg";
 		assigned-clocks = <&clk IMX_SC_R_SPI_1 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <60000000>;
@@ -59,8 +59,8 @@
 		#size-cells = <0>;
 		interrupts = <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-parent = <&gic>;
-		clocks = <&spi2_lpcg 0>,
-			 <&spi2_lpcg 1>;
+		clocks = <&spi2_lpcg IMX_LPCG_CLK_0>,
+			 <&spi2_lpcg IMX_LPCG_CLK_4>;
 		clock-names = "per", "ipg";
 		assigned-clocks = <&clk IMX_SC_R_SPI_2 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <60000000>;
@@ -75,8 +75,8 @@
 		#size-cells = <0>;
 		interrupts = <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-parent = <&gic>;
-		clocks = <&spi3_lpcg 0>,
-			 <&spi3_lpcg 1>;
+		clocks = <&spi3_lpcg IMX_LPCG_CLK_0>,
+			 <&spi3_lpcg IMX_LPCG_CLK_4>;
 		clock-names = "per", "ipg";
 		assigned-clocks = <&clk IMX_SC_R_SPI_3 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <60000000>;
@@ -144,8 +144,8 @@
 		compatible = "fsl,imx8qxp-pwm", "fsl,imx27-pwm";
 		reg = <0x5a190000 0x1000>;
 		interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
-		clocks = <&adma_pwm_lpcg 1>,
-			 <&adma_pwm_lpcg 0>;
+		clocks = <&adma_pwm_lpcg IMX_LPCG_CLK_4>,
+			 <&adma_pwm_lpcg IMX_LPCG_CLK_0>;
 		clock-names = "ipg", "per";
 		assigned-clocks = <&clk IMX_SC_R_LCD_0_PWM_0 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <24000000>;
@@ -377,8 +377,8 @@
 		reg = <0x5a880000 0x10000>;
 		interrupts = <GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-parent = <&gic>;
-		clocks = <&adc0_lpcg 0>,
-			 <&adc0_lpcg 1>;
+		clocks = <&adc0_lpcg IMX_LPCG_CLK_0>,
+			 <&adc0_lpcg IMX_LPCG_CLK_4>;
 		clock-names = "per", "ipg";
 		assigned-clocks = <&clk IMX_SC_R_ADC_0 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <24000000>;
@@ -392,8 +392,8 @@
 		reg = <0x5a890000 0x10000>;
 		interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-parent = <&gic>;
-		clocks = <&adc1_lpcg 0>,
-			 <&adc1_lpcg 1>;
+		clocks = <&adc1_lpcg IMX_LPCG_CLK_0>,
+			 <&adc1_lpcg IMX_LPCG_CLK_4>;
 		clock-names = "per", "ipg";
 		assigned-clocks = <&clk IMX_SC_R_ADC_1 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <24000000>;
@@ -406,8 +406,8 @@
 		reg = <0x5a8d0000 0x10000>;
 		interrupts = <GIC_SPI 235 IRQ_TYPE_LEVEL_HIGH>;
 		interrupt-parent = <&gic>;
-		clocks = <&can0_lpcg 1>,
-			 <&can0_lpcg 0>;
+		clocks = <&can0_lpcg IMX_LPCG_CLK_4>,
+			 <&can0_lpcg IMX_LPCG_CLK_0>;
 		clock-names = "ipg", "per";
 		assigned-clocks = <&clk IMX_SC_R_CAN_0 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <40000000>;
@@ -427,8 +427,8 @@
 		 * CAN1 shares CAN0's clock and to enable CAN0's clock it
 		 * has to be powered on.
 		 */
-		clocks = <&can0_lpcg 1>,
-			 <&can0_lpcg 0>;
+		clocks = <&can0_lpcg IMX_LPCG_CLK_4>,
+			 <&can0_lpcg IMX_LPCG_CLK_0>;
 		clock-names = "ipg", "per";
 		assigned-clocks = <&clk IMX_SC_R_CAN_0 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <40000000>;
@@ -448,8 +448,8 @@
 		 * CAN2 shares CAN0's clock and to enable CAN0's clock it
 		 * has to be powered on.
 		 */
-		clocks = <&can0_lpcg 1>,
-			 <&can0_lpcg 0>;
+		clocks = <&can0_lpcg IMX_LPCG_CLK_4>,
+			 <&can0_lpcg IMX_LPCG_CLK_0>;
 		clock-names = "ipg", "per";
 		assigned-clocks = <&clk IMX_SC_R_CAN_0 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <40000000>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8-ss-lsio.dtsi
@@ -25,8 +25,8 @@
 		compatible = "fsl,imx27-pwm";
 		reg = <0x5d000000 0x10000>;
 		clock-names = "ipg", "per";
-		clocks = <&pwm0_lpcg 4>,
-			 <&pwm0_lpcg 1>;
+		clocks = <&pwm0_lpcg IMX_LPCG_CLK_6>,
+			 <&pwm0_lpcg IMX_LPCG_CLK_1>;
 		assigned-clocks = <&clk IMX_SC_R_PWM_0 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <24000000>;
 		#pwm-cells = <3>;
@@ -38,8 +38,8 @@
 		compatible = "fsl,imx27-pwm";
 		reg = <0x5d010000 0x10000>;
 		clock-names = "ipg", "per";
-		clocks = <&pwm1_lpcg 4>,
-			 <&pwm1_lpcg 1>;
+		clocks = <&pwm1_lpcg IMX_LPCG_CLK_6>,
+			 <&pwm1_lpcg IMX_LPCG_CLK_1>;
 		assigned-clocks = <&clk IMX_SC_R_PWM_1 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <24000000>;
 		#pwm-cells = <3>;
@@ -51,8 +51,8 @@
 		compatible = "fsl,imx27-pwm";
 		reg = <0x5d020000 0x10000>;
 		clock-names = "ipg", "per";
-		clocks = <&pwm2_lpcg 4>,
-			 <&pwm2_lpcg 1>;
+		clocks = <&pwm2_lpcg IMX_LPCG_CLK_6>,
+			 <&pwm2_lpcg IMX_LPCG_CLK_1>;
 		assigned-clocks = <&clk IMX_SC_R_PWM_2 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <24000000>;
 		#pwm-cells = <3>;
@@ -64,8 +64,8 @@
 		compatible = "fsl,imx27-pwm";
 		reg = <0x5d030000 0x10000>;
 		clock-names = "ipg", "per";
-		clocks = <&pwm3_lpcg 4>,
-			 <&pwm3_lpcg 1>;
+		clocks = <&pwm3_lpcg IMX_LPCG_CLK_6>,
+			 <&pwm3_lpcg IMX_LPCG_CLK_1>;
 		assigned-clocks = <&clk IMX_SC_R_PWM_3 IMX_SC_PM_CLK_PER>;
 		assigned-clock-rates = <24000000>;
 		#pwm-cells = <3>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8-ss-vpu.dtsi
@@ -15,7 +15,7 @@
 	mu_m0: mailbox@2d000000 {
 		compatible = "fsl,imx6sx-mu";
 		reg = <0x2d000000 0x20000>;
-		interrupts = <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>;
 		#mbox-cells = <2>;
 		power-domains = <&pd IMX_SC_R_VPU_MU_0>;
 		status = "disabled";
@@ -24,7 +24,7 @@
 	mu1_m0: mailbox@2d020000 {
 		compatible = "fsl,imx6sx-mu";
 		reg = <0x2d020000 0x20000>;
-		interrupts = <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>;
 		#mbox-cells = <2>;
 		power-domains = <&pd IMX_SC_R_VPU_MU_1>;
 		status = "disabled";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl-osm-s.dts
@@ -294,8 +294,8 @@
 
 	pinctrl_i2c4: i2c4grp {
 		fsl,pins = <
-			MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL			0x400001c3
-			MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA			0x400001c3
+			MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL			0x40000083
+			MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA			0x40000083
 		>;
 	};
 
@@ -313,19 +313,19 @@
 
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
-			MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX		0x140
-			MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX		0x140
-			MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B		0x140
-			MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B		0x140
+			MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX		0x0
+			MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX		0x0
+			MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B		0x0
+			MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B		0x0
 		>;
 	};
 
 	pinctrl_uart2: uart2grp {
 		fsl,pins = <
-			MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX		0x140
-			MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX		0x140
-			MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B		0x140
-			MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B		0x140
+			MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX		0x0
+			MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX		0x0
+			MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B		0x0
+			MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B		0x0
 		>;
 	};
 
@@ -337,40 +337,40 @@
 
 	pinctrl_usdhc2: usdhc2grp {
 		fsl,pins = <
-			MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK			0x190
+			MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK			0x90
 			MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD			0x1d0
 			MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d0
 			MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d0
 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d0
 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d0
-			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x019
-			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0
+			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x19
+			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0xd0
 		>;
 	};
 
 	pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
 		fsl,pins = <
-			MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK			0x194
+			MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK			0x94
 			MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD			0x1d4
 			MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d4
 			MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d4
 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d4
 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d4
-			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x019
-			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0
+			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x19
+			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0xd0
 		>;
 	};
 
 	pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
 		fsl,pins = <
-			MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK			0x196
+			MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK			0x96
 			MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD			0x1d6
 			MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d6
 			MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d6
 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d6
 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d6
-			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x019
-			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0
+			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x19
+			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0xd0
 		>;
 	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
@@ -279,8 +279,8 @@
 
 	pinctrl_i2c4: i2c4grp {
 		fsl,pins = <
-			MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL			0x400001c3
-			MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA			0x400001c3
+			MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL			0x40000083
+			MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA			0x40000083
 		>;
 	};
 
@@ -292,19 +292,19 @@
 
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
-			MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX		0x140
-			MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX		0x140
-			MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B		0x140
-			MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B		0x140
+			MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX		0x0
+			MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX		0x0
+			MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B		0x0
+			MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B		0x0
 		>;
 	};
 
 	pinctrl_uart2: uart2grp {
 		fsl,pins = <
-			MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX		0x140
-			MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX		0x140
-			MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B		0x140
-			MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B		0x140
+			MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX		0x0
+			MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX		0x0
+			MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B		0x0
+			MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B		0x0
 		>;
 	};
 
@@ -316,40 +316,40 @@
 
 	pinctrl_usdhc2: usdhc2grp {
 		fsl,pins = <
-			MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK			0x190
+			MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK			0x90
 			MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD			0x1d0
 			MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d0
 			MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d0
 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d0
 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d0
-			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x019
-			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0
+			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x19
+			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0xd0
 		>;
 	};
 
 	pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
 		fsl,pins = <
-			MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK			0x194
+			MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK			0x94
 			MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD			0x1d4
 			MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d4
 			MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d4
 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d4
 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d4
-			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x019
-			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0
+			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x19
+			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0xd0
 		>;
 	};
 
 	pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
 		fsl,pins = <
-			MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK			0x196
+			MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK			0x96
 			MX8MM_IOMUXC_SD2_CMD_USDHC2_CMD			0x1d6
 			MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0		0x1d6
 			MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1		0x1d6
 			MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2		0x1d6
 			MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3		0x1d6
-			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x019
-			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0x1d0
+			MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12		0x19
+			MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT		0xd0
 		>;
 	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8mm-kontron-osm-s.dtsi
@@ -210,7 +210,7 @@
 		reg = <0x52>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_rtc>;
-		interrupts-extended = <&gpio4 1 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts-extended = <&gpio4 1 IRQ_TYPE_LEVEL_LOW>;
 		trickle-diode-disable;
 	};
 };
@@ -252,8 +252,8 @@
 
 	pinctrl_i2c1: i2c1grp {
 		fsl,pins = <
-			MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL			0x400001c3
-			MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA			0x400001c3
+			MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL			0x40000083
+			MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA			0x40000083
 		>;
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8mm-kontron-sl.dtsi
@@ -237,8 +237,8 @@
 
 	pinctrl_i2c1: i2c1grp {
 		fsl,pins = <
-			MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL			0x400001c3
-			MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA			0x400001c3
+			MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL			0x40000083
+			MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA			0x40000083
 		>;
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8mm-venice-gw71xx.dtsi
@@ -47,17 +47,6 @@
 		gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>;
 		status = "okay";
 	};
-
-	reg_usb_otg1_vbus: regulator-usb-otg1 {
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_reg_usb1_en>;
-		compatible = "regulator-fixed";
-		regulator-name = "usb_otg1_vbus";
-		gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>;
-		enable-active-high;
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
-	};
 };
 
 /* off-board header */
@@ -144,9 +133,10 @@
 };
 
 &usbotg1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&pinctrl_usbotg1>;
 	dr_mode = "otg";
 	over-current-active-low;
-	vbus-supply = <&reg_usb_otg1_vbus>;
 	status = "okay";
 };
 
@@ -204,14 +194,6 @@
 		>;
 	};
 
-	pinctrl_reg_usb1_en: regusb1grp {
-		fsl,pins = <
-			MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10	0x41
-			MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12	0x141
-			MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC	0x41
-		>;
-	};
-
 	pinctrl_spi2: spi2grp {
 		fsl,pins = <
 			MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK	0xd6
@@ -234,4 +216,11 @@
 			MX8MM_IOMUXC_UART3_TXD_UART3_DCE_TX	0x140
 		>;
 	};
+
+	pinctrl_usbotg1: usbotg1grp {
+		fsl,pins = <
+			MX8MM_IOMUXC_GPIO1_IO12_GPIO1_IO12	0x141
+			MX8MM_IOMUXC_GPIO1_IO13_USB1_OTG_OC	0x41
+		>;
+	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
@@ -6,6 +6,7 @@
 #include <dt-bindings/phy/phy-imx8-pcie.h>
 #include <dt-bindings/pwm/pwm.h>
 #include "imx8mm.dtsi"
+#include "imx8mm-overdrive.dtsi"
 
 / {
 	chosen {
@@ -145,7 +146,7 @@
 		regulator-max-microvolt = <3300000>;
 		regulator-min-microvolt = <3300000>;
 		regulator-name = "+V3.3_SD";
-		startup-delay-us = <2000>;
+		startup-delay-us = <20000>;
 	};
 
 	reserved-memory {
@@ -929,7 +930,7 @@
 	/* Verdin GPIO_9_DSI (pulled-up as active-low) */
 	pinctrl_gpio_9_dsi: gpio9dsigrp {
 		fsl,pins =
-			<MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15		0x146>;	/* SODIMM 17 */
+			<MX8MM_IOMUXC_NAND_RE_B_GPIO3_IO15		0x1c6>;	/* SODIMM 17 */
 	};
 
 	/* Verdin GPIO_10_DSI (pulled-up as active-low) */
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8mp-beacon-kit.dts
@@ -211,13 +211,12 @@
 
 		simple-audio-card,cpu {
 			sound-dai = <&sai3>;
+			frame-master;
+			bitclock-master;
 		};
 
 		simple-audio-card,codec {
 			sound-dai = <&wm8962>;
-			clocks = <&clk IMX8MP_CLK_IPP_DO_CLKO1>;
-			frame-master;
-			bitclock-master;
 		};
 	};
 };
@@ -499,10 +498,9 @@
 &sai3 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&pinctrl_sai3>;
-	assigned-clocks = <&clk IMX8MP_CLK_SAI3>,
-			  <&clk IMX8MP_AUDIO_PLL2> ;
-	assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>;
-	assigned-clock-rates = <12288000>, <361267200>;
+	assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
+	assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
+	assigned-clock-rates = <12288000>;
 	fsl,sai-mclk-direction-output;
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
@@ -121,7 +121,7 @@
 	flash@0 {	/* W25Q128JVEI */
 		compatible = "jedec,spi-nor";
 		reg = <0>;
-		spi-max-frequency = <100000000>;	/* Up to 133 MHz */
+		spi-max-frequency = <40000000>;
 		spi-tx-bus-width = <1>;
 		spi-rx-bus-width = <1>;
 	};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi
@@ -254,7 +254,7 @@
 				  <&clk IMX8MP_CLK_CLKOUT2>,
 				  <&clk IMX8MP_AUDIO_PLL2_OUT>;
 		assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>;
-		assigned-clock-rates = <13000000>, <13000000>, <156000000>;
+		assigned-clock-rates = <13000000>, <13000000>, <208000000>;
 		reset-gpios = <&gpio4 1 GPIO_ACTIVE_HIGH>;
 		status = "disabled";
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8mp-evk.dts
@@ -23,7 +23,7 @@
 
 		port {
 			hdmi_connector_in: endpoint {
-				remote-endpoint = <&adv7533_out>;
+				remote-endpoint = <&adv7535_out>;
 			};
 		};
 	};
@@ -107,6 +107,13 @@
 		enable-active-high;
 	};
 
+	reg_vext_3v3: regulator-vext-3v3 {
+		compatible = "regulator-fixed";
+		regulator-name = "VEXT_3V3";
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+	};
+
 	sound {
 		compatible = "simple-audio-card";
 		simple-audio-card,name = "wm8960-audio";
@@ -364,7 +371,7 @@
 				regulator-always-on;
 			};
 
-			BUCK5 {
+			reg_buck5: BUCK5 {
 				regulator-name = "BUCK5";
 				regulator-min-microvolt = <1650000>;
 				regulator-max-microvolt = <1950000>;
@@ -415,14 +422,16 @@
 
 	hdmi@3d {
 		compatible = "adi,adv7535";
-		reg = <0x3d>, <0x3c>, <0x3e>, <0x3f>;
-		reg-names = "main", "cec", "edid", "packet";
+		reg = <0x3d>;
+		interrupt-parent = <&gpio1>;
+		interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
 		adi,dsi-lanes = <4>;
-		adi,input-depth = <8>;
-		adi,input-colorspace = "rgb";
-		adi,input-clock = "1x";
-		adi,input-style = <1>;
-		adi,input-justification = "evenly";
+		avdd-supply = <&reg_buck5>;
+		dvdd-supply = <&reg_buck5>;
+		pvdd-supply = <&reg_buck5>;
+		a2vdd-supply = <&reg_buck5>;
+		v3p3-supply = <&reg_vext_3v3>;
+		v1p2-supply = <&reg_buck5>;
 
 		ports {
 			#address-cells = <1>;
@@ -431,7 +440,7 @@
 			port@0 {
 				reg = <0>;
 
-				adv7533_in: endpoint {
+				adv7535_in: endpoint {
 					remote-endpoint = <&dsi_out>;
 				};
 			};
@@ -439,7 +448,7 @@
 			port@1 {
 				reg = <1>;
 
-				adv7533_out: endpoint {
+				adv7535_out: endpoint {
 					remote-endpoint = <&hdmi_connector_in>;
 				};
 			};
@@ -524,7 +533,7 @@
 			reg = <1>;
 
 			dsi_out: endpoint {
-				remote-endpoint = <&adv7533_in>;
+				remote-endpoint = <&adv7535_in>;
 				data-lanes = <1 2 3 4>;
 			};
 		};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi
@@ -14,6 +14,7 @@
 		pinctrl-0 = <&pinctrl_usbcon1>;
 		type = "micro";
 		label = "otg";
+		vbus-supply = <&reg_usb1_vbus>;
 		id-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
 
 		port {
@@ -183,7 +184,6 @@
 };
 
 &usb3_phy0 {
-	vbus-supply = <&reg_usb1_vbus>;
 	status = "okay";
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8mp-venice-gw73xx.dtsi
@@ -14,6 +14,7 @@
 		pinctrl-0 = <&pinctrl_usbcon1>;
 		type = "micro";
 		label = "otg";
+		vbus-supply = <&reg_usb1_vbus>;
 		id-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
 
 		port {
@@ -182,7 +183,7 @@
 
 	bluetooth {
 		compatible = "brcm,bcm4330-bt";
-		shutdown-gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
+		shutdown-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
 	};
 };
 
@@ -202,7 +203,6 @@
 };
 
 &usb3_phy0 {
-	vbus-supply = <&reg_usb1_vbus>;
 	status = "okay";
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8mp-verdin.dtsi
@@ -151,7 +151,7 @@
 		regulator-max-microvolt = <3300000>;
 		regulator-min-microvolt = <3300000>;
 		regulator-name = "+V3.3_SD";
-		startup-delay-us = <2000>;
+		startup-delay-us = <20000>;
 	};
 
 	reserved-memory {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -789,6 +789,23 @@
 						reg = <IMX8MP_POWER_DOMAIN_USB2_PHY>;
 					};
 
+					pgc_mlmix: power-domain@4 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_MLMIX>;
+						clocks = <&clk IMX8MP_CLK_ML_AXI>,
+							 <&clk IMX8MP_CLK_ML_AHB>,
+							 <&clk IMX8MP_CLK_NPU_ROOT>;
+						assigned-clocks = <&clk IMX8MP_CLK_ML_CORE>,
+								  <&clk IMX8MP_CLK_ML_AXI>,
+								  <&clk IMX8MP_CLK_ML_AHB>;
+						assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>,
+									 <&clk IMX8MP_SYS_PLL1_800M>,
+									 <&clk IMX8MP_SYS_PLL1_800M>;
+						assigned-clock-rates = <800000000>,
+								       <800000000>,
+								       <300000000>;
+					};
+
 					pgc_audio: power-domain@5 {
 						#power-domain-cells = <0>;
 						reg = <IMX8MP_POWER_DOMAIN_AUDIOMIX>;
@@ -821,6 +838,12 @@
 						assigned-clock-rates = <800000000>, <400000000>;
 					};
 
+					pgc_vpumix: power-domain@8 {
+						#power-domain-cells = <0>;
+						reg = <IMX8MP_POWER_DOMAIN_VPUMIX>;
+						clocks = <&clk IMX8MP_CLK_VPU_ROOT>;
+					};
+
 					pgc_gpu3d: power-domain@9 {
 						#power-domain-cells = <0>;
 						reg = <IMX8MP_POWER_DOMAIN_GPU3D>;
@@ -836,69 +859,64 @@
 							 <&clk IMX8MP_CLK_MEDIA_APB_ROOT>;
 					};
 
-					pgc_mipi_phy2: power-domain@16 {
+					pgc_vpu_g1: power-domain@11 {
 						#power-domain-cells = <0>;
-						reg = <IMX8MP_POWER_DOMAIN_MIPI_PHY2>;
+						power-domains = <&pgc_vpumix>;
+						reg = <IMX8MP_POWER_DOMAIN_VPU_G1>;
+						clocks = <&clk IMX8MP_CLK_VPU_G1_ROOT>;
 					};
 
-					pgc_hsiomix: power-domain@17 {
+					pgc_vpu_g2: power-domain@12 {
 						#power-domain-cells = <0>;
-						reg = <IMX8MP_POWER_DOMAIN_HSIOMIX>;
-						clocks = <&clk IMX8MP_CLK_HSIO_AXI>,
-							 <&clk IMX8MP_CLK_HSIO_ROOT>;
-						assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>;
-						assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>;
-						assigned-clock-rates = <500000000>;
+						power-domains = <&pgc_vpumix>;
+						reg = <IMX8MP_POWER_DOMAIN_VPU_G2>;
+						clocks = <&clk IMX8MP_CLK_VPU_G2_ROOT>;
+
 					};
 
-					pgc_ispdwp: power-domain@18 {
+					pgc_vpu_vc8000e: power-domain@13 {
 						#power-domain-cells = <0>;
-						reg = <IMX8MP_POWER_DOMAIN_MEDIAMIX_ISPDWP>;
-						clocks = <&clk IMX8MP_CLK_MEDIA_ISP_ROOT>;
+						power-domains = <&pgc_vpumix>;
+						reg = <IMX8MP_POWER_DOMAIN_VPU_VC8000E>;
+						clocks = <&clk IMX8MP_CLK_VPU_VC8KE_ROOT>;
 					};
 
-					pgc_vpumix: power-domain@19 {
+					pgc_hdmimix: power-domain@14 {
 						#power-domain-cells = <0>;
-						reg = <IMX8MP_POWER_DOMAIN_VPUMIX>;
-						clocks = <&clk IMX8MP_CLK_VPU_ROOT>;
+						reg = <IMX8MP_POWER_DOMAIN_HDMIMIX>;
+						clocks = <&clk IMX8MP_CLK_HDMI_ROOT>,
+							 <&clk IMX8MP_CLK_HDMI_APB>;
+						assigned-clocks = <&clk IMX8MP_CLK_HDMI_AXI>,
+								  <&clk IMX8MP_CLK_HDMI_APB>;
+						assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>,
+									 <&clk IMX8MP_SYS_PLL1_133M>;
+						assigned-clock-rates = <500000000>, <133000000>;
 					};
 
-					pgc_vpu_g1: power-domain@20 {
+					pgc_hdmi_phy: power-domain@15 {
 						#power-domain-cells = <0>;
-						power-domains = <&pgc_vpumix>;
-						reg = <IMX8MP_POWER_DOMAIN_VPU_G1>;
-						clocks = <&clk IMX8MP_CLK_VPU_G1_ROOT>;
+						reg = <IMX8MP_POWER_DOMAIN_HDMI_PHY>;
 					};
 
-					pgc_vpu_g2: power-domain@21 {
+					pgc_mipi_phy2: power-domain@16 {
 						#power-domain-cells = <0>;
-						power-domains = <&pgc_vpumix>;
-						reg = <IMX8MP_POWER_DOMAIN_VPU_G2>;
-						clocks = <&clk IMX8MP_CLK_VPU_G2_ROOT>;
+						reg = <IMX8MP_POWER_DOMAIN_MIPI_PHY2>;
 					};
 
-					pgc_vpu_vc8000e: power-domain@22 {
+					pgc_hsiomix: power-domain@17 {
 						#power-domain-cells = <0>;
-						power-domains = <&pgc_vpumix>;
-						reg = <IMX8MP_POWER_DOMAIN_VPU_VC8000E>;
-						clocks = <&clk IMX8MP_CLK_VPU_VC8KE_ROOT>;
+						reg = <IMX8MP_POWER_DOMAIN_HSIOMIX>;
+						clocks = <&clk IMX8MP_CLK_HSIO_AXI>,
+							 <&clk IMX8MP_CLK_HSIO_ROOT>;
+						assigned-clocks = <&clk IMX8MP_CLK_HSIO_AXI>;
+						assigned-clock-parents = <&clk IMX8MP_SYS_PLL2_500M>;
+						assigned-clock-rates = <500000000>;
 					};
 
-					pgc_mlmix: power-domain@24 {
+					pgc_ispdwp: power-domain@18 {
 						#power-domain-cells = <0>;
-						reg = <IMX8MP_POWER_DOMAIN_MLMIX>;
-						clocks = <&clk IMX8MP_CLK_ML_AXI>,
-							 <&clk IMX8MP_CLK_ML_AHB>,
-							 <&clk IMX8MP_CLK_NPU_ROOT>;
-						assigned-clocks = <&clk IMX8MP_CLK_ML_CORE>,
-								  <&clk IMX8MP_CLK_ML_AXI>,
-								  <&clk IMX8MP_CLK_ML_AHB>;
-						assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_800M>,
-									 <&clk IMX8MP_SYS_PLL1_800M>,
-									 <&clk IMX8MP_SYS_PLL1_800M>;
-						assigned-clock-rates = <800000000>,
-								       <800000000>,
-								       <300000000>;
+						reg = <IMX8MP_POWER_DOMAIN_MEDIAMIX_ISPDWP>;
+						clocks = <&clk IMX8MP_CLK_MEDIA_ISP_ROOT>;
 					};
 				};
 			};
@@ -1243,7 +1261,7 @@
 				compatible = "fsl,imx8mp-usdhc", "fsl,imx8mm-usdhc", "fsl,imx7d-usdhc";
 				reg = <0x30b40000 0x10000>;
 				interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clk IMX8MP_CLK_DUMMY>,
+				clocks = <&clk IMX8MP_CLK_IPG_ROOT>,
 					 <&clk IMX8MP_CLK_NAND_USDHC_BUS>,
 					 <&clk IMX8MP_CLK_USDHC1_ROOT>;
 				clock-names = "ipg", "ahb", "per";
@@ -1257,7 +1275,7 @@
 				compatible = "fsl,imx8mp-usdhc", "fsl,imx8mm-usdhc", "fsl,imx7d-usdhc";
 				reg = <0x30b50000 0x10000>;
 				interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clk IMX8MP_CLK_DUMMY>,
+				clocks = <&clk IMX8MP_CLK_IPG_ROOT>,
 					 <&clk IMX8MP_CLK_NAND_USDHC_BUS>,
 					 <&clk IMX8MP_CLK_USDHC2_ROOT>;
 				clock-names = "ipg", "ahb", "per";
@@ -1271,7 +1289,7 @@
 				compatible = "fsl,imx8mp-usdhc", "fsl,imx8mm-usdhc", "fsl,imx7d-usdhc";
 				reg = <0x30b60000 0x10000>;
 				interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clk IMX8MP_CLK_DUMMY>,
+				clocks = <&clk IMX8MP_CLK_IPG_ROOT>,
 					 <&clk IMX8MP_CLK_NAND_USDHC_BUS>,
 					 <&clk IMX8MP_CLK_USDHC3_ROOT>;
 				clock-names = "ipg", "ahb", "per";
@@ -1885,6 +1903,27 @@
 				#power-domain-cells = <1>;
 				#clock-cells = <0>;
 			};
+
+			hdmi_blk_ctrl: blk-ctrl@32fc0000 {
+				compatible = "fsl,imx8mp-hdmi-blk-ctrl", "syscon";
+				reg = <0x32fc0000 0x1000>;
+				clocks = <&clk IMX8MP_CLK_HDMI_APB>,
+					 <&clk IMX8MP_CLK_HDMI_ROOT>,
+					 <&clk IMX8MP_CLK_HDMI_REF_266M>,
+					 <&clk IMX8MP_CLK_HDMI_24M>,
+					 <&clk IMX8MP_CLK_HDMI_FDCC_TST>;
+				clock-names = "apb", "axi", "ref_266m", "ref_24m", "fdcc";
+				power-domains = <&pgc_hdmimix>, <&pgc_hdmimix>,
+						<&pgc_hdmimix>, <&pgc_hdmimix>,
+						<&pgc_hdmimix>, <&pgc_hdmimix>,
+						<&pgc_hdmimix>, <&pgc_hdmi_phy>,
+						<&pgc_hdmimix>, <&pgc_hdmimix>;
+				power-domain-names = "bus", "irqsteer", "lcdif",
+						     "pai", "pvi", "trng",
+						     "hdmi-tx", "hdmi-tx-phy",
+						     "hdcp", "hrv";
+				#power-domain-cells = <1>;
+			};
 		};
 
 		pcie: pcie@33800000 {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
@@ -36,7 +36,7 @@
 		regulator-name = "SD1_SPWR";
 		regulator-min-microvolt = <3000000>;
 		regulator-max-microvolt = <3000000>;
-		gpio = <&lsio_gpio4 19 GPIO_ACTIVE_HIGH>;
+		gpio = <&lsio_gpio4 7 GPIO_ACTIVE_HIGH>;
 		enable-active-high;
 	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8qm-ss-dma.dtsi
@@ -96,15 +96,30 @@
 	status = "okay";
 };
 
+/* It is eDMA1 in 8QM RM, but 8QXP it is eDMA3 */
 &edma3 {
+	reg = <0x5a9f0000 0x210000>;
+	dma-channels = <10>;
+	interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 432 IRQ_TYPE_LEVEL_HIGH>,
+		     <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH>;
 	power-domains = <&pd IMX_SC_R_DMA_1_CH0>,
-		     <&pd IMX_SC_R_DMA_1_CH1>,
-		     <&pd IMX_SC_R_DMA_1_CH2>,
-		     <&pd IMX_SC_R_DMA_1_CH3>,
-		     <&pd IMX_SC_R_DMA_1_CH4>,
-		     <&pd IMX_SC_R_DMA_1_CH5>,
-		     <&pd IMX_SC_R_DMA_1_CH6>,
-		     <&pd IMX_SC_R_DMA_1_CH7>;
+			<&pd IMX_SC_R_DMA_1_CH1>,
+			<&pd IMX_SC_R_DMA_1_CH2>,
+			<&pd IMX_SC_R_DMA_1_CH3>,
+			<&pd IMX_SC_R_DMA_1_CH4>,
+			<&pd IMX_SC_R_DMA_1_CH5>,
+			<&pd IMX_SC_R_DMA_1_CH6>,
+			<&pd IMX_SC_R_DMA_1_CH7>,
+			<&pd IMX_SC_R_DMA_1_CH8>,
+			<&pd IMX_SC_R_DMA_1_CH9>;
 };
 
 &flexcan1 {
@@ -112,15 +127,15 @@
 };
 
 &flexcan2 {
-	clocks = <&can1_lpcg 1>,
-		 <&can1_lpcg 0>;
+	clocks = <&can1_lpcg IMX_LPCG_CLK_4>,
+		 <&can1_lpcg IMX_LPCG_CLK_0>;
 	assigned-clocks = <&clk IMX_SC_R_CAN_1 IMX_SC_PM_CLK_PER>;
 	fsl,clk-source = /bits/ 8 <1>;
 };
 
 &flexcan3 {
-	clocks = <&can2_lpcg 1>,
-		 <&can2_lpcg 0>;
+	clocks = <&can2_lpcg IMX_LPCG_CLK_4>,
+		 <&can2_lpcg IMX_LPCG_CLK_0>;
 	assigned-clocks = <&clk IMX_SC_R_CAN_2 IMX_SC_PM_CLK_PER>;
 	fsl,clk-source = /bits/ 8 <1>;
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8qxp-ss-vpu.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8qxp-ss-vpu.dtsi
@@ -5,6 +5,14 @@
  * Author: Alexander Stein
  */
 
+&mu_m0 {
+	interrupts = <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>;
+};
+
+&mu1_m0 {
+	interrupts = <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>;
+};
+
 &vpu_core0 {
 	reg = <0x2d040000 0x10000>;
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -352,7 +352,7 @@
 			};
 
 			flexspi2: spi@29810000 {
-				compatible = "nxp,imx8mm-fspi";
+				compatible = "nxp,imx8ulp-fspi";
 				reg = <0x29810000 0x10000>, <0x60000000 0x10000000>;
 				reg-names = "fspi_base", "fspi_mmap";
 				#address-cells = <1>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
@@ -175,7 +175,6 @@
 	vmmc-supply = <&reg_usdhc2_vmmc>;
 	bus-width = <4>;
 	status = "okay";
-	no-sdio;
 	no-mmc;
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx93-tqma9352-mba93xxla.dts
@@ -438,7 +438,7 @@
 	pinctrl-0 = <&pinctrl_usdhc2_hs>, <&pinctrl_usdhc2_gpio>;
 	pinctrl-1 = <&pinctrl_usdhc2_uhs>, <&pinctrl_usdhc2_gpio>;
 	pinctrl-2 = <&pinctrl_usdhc2_uhs>, <&pinctrl_usdhc2_gpio>;
-	cd-gpios = <&gpio3 00 GPIO_ACTIVE_LOW>;
+	cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
 	vmmc-supply = <&reg_usdhc2_vmmc>;
 	bus-width = <4>;
 	no-sdio;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx93-tqma9352.dtsi
@@ -19,7 +19,7 @@
 		linux,cma {
 			compatible = "shared-dma-pool";
 			reusable;
-			alloc-ranges = <0 0x60000000 0 0x40000000>;
+			alloc-ranges = <0 0x80000000 0 0x40000000>;
 			size = <0 0x10000000>;
 			linux,cma-default;
 		};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/freescale/imx93.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/freescale/imx93.dtsi
@@ -841,7 +841,7 @@
 				reg-names = "ram", "regs", "rxfifo", "txfifo";
 				interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>,
 					     <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>;
-				clocks = <&clk IMX93_CLK_BUS_WAKEUP>,
+				clocks = <&clk IMX93_CLK_SPDIF_IPG>,
 					 <&clk IMX93_CLK_SPDIF_GATE>,
 					 <&clk IMX93_CLK_DUMMY>,
 					 <&clk IMX93_CLK_AUD_XCVR_GATE>;
@@ -1030,6 +1030,8 @@
 				fsl,num-tx-queues = <3>;
 				fsl,num-rx-queues = <3>;
 				fsl,stop-mode = <&wakeupmix_gpr 0x0c 1>;
+				nvmem-cells = <&eth_mac1>;
+				nvmem-cell-names = "mac-address";
 				status = "disabled";
 			};
 
@@ -1051,7 +1053,9 @@
 							 <&clk IMX93_CLK_SYS_PLL_PFD0_DIV2>;
 				assigned-clock-rates = <100000000>, <250000000>;
 				intf_mode = <&wakeupmix_gpr 0x28>;
-				snps,clk-csr = <0>;
+				snps,clk-csr = <6>;
+				nvmem-cells = <&eth_mac2>;
+				nvmem-cell-names = "mac-address";
 				status = "disabled";
 			};
 
@@ -1136,6 +1140,15 @@
 			reg = <0x47510000 0x10000>;
 			#address-cells = <1>;
 			#size-cells = <1>;
+
+			eth_mac1: mac-address@4ec {
+				reg = <0x4ec 0x6>;
+			};
+
+			eth_mac2: mac-address@4f2 {
+				reg = <0x4f2 0x6>;
+			};
+
 		};
 
 		s4muap: mailbox@47520000 {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
@@ -58,7 +58,7 @@
 	gic: interrupt-controller@f1001000 {
 		compatible = "arm,gic-400";
 		reg = <0x0 0xf1001000 0x0 0x1000>,  /* GICD */
-		      <0x0 0xf1002000 0x0 0x100>;   /* GICC */
+		      <0x0 0xf1002000 0x0 0x2000>;  /* GICC */
 		#address-cells = <0>;
 		#interrupt-cells = <3>;
 		interrupt-controller;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -431,14 +431,14 @@
 			crypto: crypto@90000 {
 				compatible = "inside-secure,safexcel-eip97ies";
 				reg = <0x90000 0x20000>;
-				interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
-					     <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+				interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
 					     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
 					     <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
 					     <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
-					     <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
-				interrupt-names = "mem", "ring0", "ring1",
-						  "ring2", "ring3", "eip";
+					     <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+				interrupt-names = "ring0", "ring1", "ring2",
+						  "ring3", "eip", "mem";
 				clocks = <&nb_periph_clk 15>;
 			};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/marvell/armada-cp11x.dtsi
@@ -511,14 +511,14 @@
 		CP11X_LABEL(crypto): crypto@800000 {
 			compatible = "inside-secure,safexcel-eip197b";
 			reg = <0x800000 0x200000>;
-			interrupts = <87 IRQ_TYPE_LEVEL_HIGH>,
-				<88 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts = <88 IRQ_TYPE_LEVEL_HIGH>,
 				<89 IRQ_TYPE_LEVEL_HIGH>,
 				<90 IRQ_TYPE_LEVEL_HIGH>,
 				<91 IRQ_TYPE_LEVEL_HIGH>,
-				<92 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "mem", "ring0", "ring1",
-				"ring2", "ring3", "eip";
+				<92 IRQ_TYPE_LEVEL_HIGH>,
+				<87 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "ring0", "ring1", "ring2", "ring3",
+					  "eip", "mem";
 			clock-names = "core", "reg";
 			clocks = <&CP11X_LABEL(clk) 1 26>,
 				 <&CP11X_LABEL(clk) 1 17>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt2712-evb.dts
@@ -129,7 +129,7 @@
 };
 
 &pio {
-	eth_default: eth_default {
+	eth_default: eth-default-pins {
 		tx_pins {
 			pinmux = <MT2712_PIN_71_GBE_TXD3__FUNC_GBE_TXD3>,
 				 <MT2712_PIN_72_GBE_TXD2__FUNC_GBE_TXD2>,
@@ -156,7 +156,7 @@
 		};
 	};
 
-	eth_sleep: eth_sleep {
+	eth_sleep: eth-sleep-pins {
 		tx_pins {
 			pinmux = <MT2712_PIN_71_GBE_TXD3__FUNC_GPIO71>,
 				 <MT2712_PIN_72_GBE_TXD2__FUNC_GPIO72>,
@@ -182,14 +182,14 @@
 		};
 	};
 
-	usb0_id_pins_float: usb0_iddig {
+	usb0_id_pins_float: usb0-iddig-pins {
 		pins_iddig {
 			pinmux = <MT2712_PIN_12_IDDIG_P0__FUNC_IDDIG_A>;
 			bias-pull-up;
 		};
 	};
 
-	usb1_id_pins_float: usb1_iddig {
+	usb1_id_pins_float: usb1-iddig-pins {
 		pins_iddig {
 			pinmux = <MT2712_PIN_14_IDDIG_P1__FUNC_IDDIG_B>;
 			bias-pull-up;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -249,10 +249,11 @@
 		#clock-cells = <1>;
 	};
 
-	infracfg: syscon@10001000 {
+	infracfg: clock-controller@10001000 {
 		compatible = "mediatek,mt2712-infracfg", "syscon";
 		reg = <0 0x10001000 0 0x1000>;
 		#clock-cells = <1>;
+		#reset-cells = <1>;
 	};
 
 	pericfg: syscon@10003000 {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt6357.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt6357.dtsi
@@ -10,6 +10,11 @@
 	mt6357_pmic: pmic {
 		compatible = "mediatek,mt6357";
 
+		pmic_adc: adc {
+			compatible = "mediatek,mt6357-auxadc";
+			#io-channel-cells = <1>;
+		};
+
 		regulators {
 			mt6357_vproc_reg: buck-vproc {
 				regulator-name = "vproc";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt6358.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt6358.dtsi
@@ -10,12 +10,17 @@
 		interrupt-controller;
 		#interrupt-cells = <2>;
 
-		mt6358codec: mt6358codec {
+		pmic_adc: adc {
+			compatible = "mediatek,mt6358-auxadc";
+			#io-channel-cells = <1>;
+		};
+
+		mt6358codec: audio-codec {
 			compatible = "mediatek,mt6358-sound";
 			mediatek,dmic-mode = <0>; /* two-wires */
 		};
 
-		mt6358regulator: mt6358regulator {
+		mt6358regulator: regulators {
 			compatible = "mediatek,mt6358-regulator";
 
 			mt6358_vdram1_reg: buck_vdram1 {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt6359.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt6359.dtsi
@@ -9,6 +9,11 @@
 		interrupt-controller;
 		#interrupt-cells = <2>;
 
+		pmic_adc: adc {
+			compatible = "mediatek,mt6359-auxadc";
+			#io-channel-cells = <1>;
+		};
+
 		mt6359codec: mt6359codec {
 		};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt7622-bananapi-bpi-r64.dts
@@ -75,6 +75,7 @@
 
 	memory@40000000 {
 		reg = <0 0x40000000 0 0x40000000>;
+		device_type = "memory";
 	};
 
 	reg_1p8v: regulator-1p8v {
@@ -316,8 +317,8 @@
 	/* eMMC is shared pin with parallel NAND */
 	emmc_pins_default: emmc-pins-default {
 		mux {
-			function = "emmc", "emmc_rst";
-			groups = "emmc";
+			function = "emmc";
+			groups = "emmc", "emmc_rst";
 		};
 
 		/* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7",
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt7622-rfb1.dts
@@ -57,6 +57,7 @@
 
 	memory@40000000 {
 		reg = <0 0x40000000 0 0x20000000>;
+		device_type = "memory";
 	};
 
 	reg_1p8v: regulator-1p8v {
@@ -243,8 +244,8 @@
 	/* eMMC is shared pin with parallel NAND */
 	emmc_pins_default: emmc-pins-default {
 		mux {
-			function = "emmc", "emmc_rst";
-			groups = "emmc";
+			function = "emmc";
+			groups = "emmc", "emmc_rst";
 		};
 
 		/* "NDL0","NDL1","NDL2","NDL3","NDL4","NDL5","NDL6","NDL7",
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt7622.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt7622.dtsi
@@ -252,7 +252,7 @@
 		clock-names = "hif_sel";
 	};
 
-	cir: cir@10009000 {
+	cir: ir-receiver@10009000 {
 		compatible = "mediatek,mt7622-cir";
 		reg = <0 0x10009000 0 0x1000>;
 		interrupts = <GIC_SPI 175 IRQ_TYPE_LEVEL_LOW>;
@@ -283,16 +283,14 @@
 		};
 	};
 
-	apmixedsys: apmixedsys@10209000 {
-		compatible = "mediatek,mt7622-apmixedsys",
-			     "syscon";
+	apmixedsys: clock-controller@10209000 {
+		compatible = "mediatek,mt7622-apmixedsys";
 		reg = <0 0x10209000 0 0x1000>;
 		#clock-cells = <1>;
 	};
 
-	topckgen: topckgen@10210000 {
-		compatible = "mediatek,mt7622-topckgen",
-			     "syscon";
+	topckgen: clock-controller@10210000 {
+		compatible = "mediatek,mt7622-topckgen";
 		reg = <0 0x10210000 0 0x1000>;
 		#clock-cells = <1>;
 	};
@@ -515,7 +513,6 @@
 			 <&pericfg CLK_PERI_AUXADC_PD>;
 		clock-names = "therm", "auxadc";
 		resets = <&pericfg MT7622_PERI_THERM_SW_RST>;
-		reset-names = "therm";
 		mediatek,auxadc = <&auxadc>;
 		mediatek,apmixedsys = <&apmixedsys>;
 		nvmem-cells = <&thermal_calibration>;
@@ -734,9 +731,8 @@
 		power-domains = <&scpsys MT7622_POWER_DOMAIN_WB>;
 	};
 
-	ssusbsys: ssusbsys@1a000000 {
-		compatible = "mediatek,mt7622-ssusbsys",
-			     "syscon";
+	ssusbsys: clock-controller@1a000000 {
+		compatible = "mediatek,mt7622-ssusbsys";
 		reg = <0 0x1a000000 0 0x1000>;
 		#clock-cells = <1>;
 		#reset-cells = <1>;
@@ -793,9 +789,8 @@
 		};
 	};
 
-	pciesys: pciesys@1a100800 {
-		compatible = "mediatek,mt7622-pciesys",
-			     "syscon";
+	pciesys: clock-controller@1a100800 {
+		compatible = "mediatek,mt7622-pciesys";
 		reg = <0 0x1a100800 0 0x1000>;
 		#clock-cells = <1>;
 		#reset-cells = <1>;
@@ -921,12 +916,13 @@
 		};
 	};
 
-	hifsys: syscon@1af00000 {
-		compatible = "mediatek,mt7622-hifsys", "syscon";
+	hifsys: clock-controller@1af00000 {
+		compatible = "mediatek,mt7622-hifsys";
 		reg = <0 0x1af00000 0 0x70>;
+		#clock-cells = <1>;
 	};
 
-	ethsys: syscon@1b000000 {
+	ethsys: clock-controller@1b000000 {
 		compatible = "mediatek,mt7622-ethsys",
 			     "syscon";
 		reg = <0 0x1b000000 0 0x1000>;
@@ -966,9 +962,7 @@
 	};
 
 	eth: ethernet@1b100000 {
-		compatible = "mediatek,mt7622-eth",
-			     "mediatek,mt2701-eth",
-			     "syscon";
+		compatible = "mediatek,mt7622-eth";
 		reg = <0 0x1b100000 0 0x20000>;
 		interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_LOW>,
 			     <GIC_SPI 224 IRQ_TYPE_LEVEL_LOW>,
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
@@ -43,7 +43,7 @@
 		#cooling-cells = <2>;
 		/* cooling level (0, 1, 2) - pwm inverted */
 		cooling-levels = <255 96 0>;
-		pwms = <&pwm 0 10000 0>;
+		pwms = <&pwm 0 10000>;
 		status = "okay";
 	};
 
@@ -146,19 +146,19 @@
 
 &cpu_thermal {
 	cooling-maps {
-		cpu-active-high {
+		map-cpu-active-high {
 			/* active: set fan to cooling level 2 */
 			cooling-device = <&fan 2 2>;
 			trip = <&cpu_trip_active_high>;
 		};
 
-		cpu-active-med {
+		map-cpu-active-med {
 			/* active: set fan to cooling level 1 */
 			cooling-device = <&fan 1 1>;
 			trip = <&cpu_trip_active_med>;
 		};
 
-		cpu-active-low {
+		map-cpu-active-low {
 			/* active: set fan to cooling level 0 */
 			cooling-device = <&fan 0 0>;
 			trip = <&cpu_trip_active_low>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt7986a-rfb.dts
@@ -237,12 +237,13 @@
 	pinctrl-0 = <&spi_flash_pins>;
 	cs-gpios = <0>, <0>;
 	status = "okay";
-	spi_nand: spi_nand@0 {
+
+	spi_nand: flash@0 {
 		compatible = "spi-nand";
 		reg = <0>;
 		spi-max-frequency = <10000000>;
-		spi-tx-buswidth = <4>;
-		spi-rx-buswidth = <4>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
 	};
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -16,49 +16,49 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
-	clk40m: oscillator-40m {
-		compatible = "fixed-clock";
-		clock-frequency = <40000000>;
-		#clock-cells = <0>;
-		clock-output-names = "clkxtal";
-	};
-
 	cpus {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		cpu0: cpu@0 {
-			device_type = "cpu";
 			compatible = "arm,cortex-a53";
-			enable-method = "psci";
 			reg = <0x0>;
+			device_type = "cpu";
+			enable-method = "psci";
 			#cooling-cells = <2>;
 		};
 
 		cpu1: cpu@1 {
-			device_type = "cpu";
 			compatible = "arm,cortex-a53";
-			enable-method = "psci";
 			reg = <0x1>;
+			device_type = "cpu";
+			enable-method = "psci";
 			#cooling-cells = <2>;
 		};
 
 		cpu2: cpu@2 {
-			device_type = "cpu";
 			compatible = "arm,cortex-a53";
-			enable-method = "psci";
 			reg = <0x2>;
+			device_type = "cpu";
+			enable-method = "psci";
 			#cooling-cells = <2>;
 		};
 
 		cpu3: cpu@3 {
-			device_type = "cpu";
-			enable-method = "psci";
 			compatible = "arm,cortex-a53";
 			reg = <0x3>;
+			device_type = "cpu";
+			enable-method = "psci";
 			#cooling-cells = <2>;
 		};
 	};
 
+	clk40m: oscillator-40m {
+		compatible = "fixed-clock";
+		clock-frequency = <40000000>;
+		#clock-cells = <0>;
+		clock-output-names = "clkxtal";
+	};
+
 	psci {
 		compatible = "arm,psci-0.2";
 		method = "smc";
@@ -121,38 +121,30 @@
 
 	};
 
-	timer {
-		compatible = "arm,armv8-timer";
-		interrupt-parent = <&gic>;
-		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
-			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
-			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
-	};
-
 	soc {
-		#address-cells = <2>;
-		#size-cells = <2>;
 		compatible = "simple-bus";
 		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
 
 		gic: interrupt-controller@c000000 {
 			compatible = "arm,gic-v3";
-			#interrupt-cells = <3>;
-			interrupt-parent = <&gic>;
-			interrupt-controller;
 			reg = <0 0x0c000000 0 0x10000>,  /* GICD */
 			      <0 0x0c080000 0 0x80000>,  /* GICR */
 			      <0 0x0c400000 0 0x2000>,   /* GICC */
 			      <0 0x0c410000 0 0x1000>,   /* GICH */
 			      <0 0x0c420000 0 0x2000>;   /* GICV */
+			interrupt-parent = <&gic>;
 			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
 		};
 
 		infracfg: infracfg@10001000 {
 			compatible = "mediatek,mt7986-infracfg", "syscon";
 			reg = <0 0x10001000 0 0x1000>;
 			#clock-cells = <1>;
+			#reset-cells = <1>;
 		};
 
 		wed_pcie: wed-pcie@10003000 {
@@ -202,6 +194,19 @@
 			#interrupt-cells = <2>;
 		};
 
+		pwm: pwm@10048000 {
+			compatible = "mediatek,mt7986-pwm";
+			reg = <0 0x10048000 0 0x1000>;
+			#pwm-cells = <2>;
+			interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&topckgen CLK_TOP_PWM_SEL>,
+				 <&infracfg CLK_INFRA_PWM_STA>,
+				 <&infracfg CLK_INFRA_PWM1_CK>,
+				 <&infracfg CLK_INFRA_PWM2_CK>;
+			clock-names = "top", "main", "pwm1", "pwm2";
+			status = "disabled";
+		};
+
 		sgmiisys0: syscon@10060000 {
 			compatible = "mediatek,mt7986-sgmiisys_0",
 				     "syscon";
@@ -234,26 +239,11 @@
 				     <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "ring0", "ring1", "ring2", "ring3";
 			clocks = <&infracfg CLK_INFRA_EIP97_CK>;
-			clock-names = "infra_eip97_ck";
 			assigned-clocks = <&topckgen CLK_TOP_EIP_B_SEL>;
 			assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>;
 			status = "disabled";
 		};
 
-		pwm: pwm@10048000 {
-			compatible = "mediatek,mt7986-pwm";
-			reg = <0 0x10048000 0 0x1000>;
-			#clock-cells = <1>;
-			#pwm-cells = <2>;
-			interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&topckgen CLK_TOP_PWM_SEL>,
-				 <&infracfg CLK_INFRA_PWM_STA>,
-				 <&infracfg CLK_INFRA_PWM1_CK>,
-				 <&infracfg CLK_INFRA_PWM2_CK>;
-			clock-names = "top", "main", "pwm1", "pwm2";
-			status = "disabled";
-		};
-
 		uart0: serial@11002000 {
 			compatible = "mediatek,mt7986-uart",
 				     "mediatek,mt6577-uart";
@@ -311,9 +301,9 @@
 
 		spi0: spi@1100a000 {
 			compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
+			reg = <0 0x1100a000 0 0x100>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			reg = <0 0x1100a000 0 0x100>;
 			interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&topckgen CLK_TOP_MPLL_D2>,
 				 <&topckgen CLK_TOP_SPI_SEL>,
@@ -325,9 +315,9 @@
 
 		spi1: spi@1100b000 {
 			compatible = "mediatek,mt7986-spi-ipm", "mediatek,spi-ipm";
+			reg = <0 0x1100b000 0 0x100>;
 			#address-cells = <1>;
 			#size-cells = <0>;
-			reg = <0 0x1100b000 0 0x100>;
 			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&topckgen CLK_TOP_MPLL_D2>,
 				 <&topckgen CLK_TOP_SPIM_MST_SEL>,
@@ -337,6 +327,20 @@
 			status = "disabled";
 		};
 
+		thermal: thermal@1100c800 {
+			compatible = "mediatek,mt7986-thermal";
+			reg = <0 0x1100c800 0 0x800>;
+			interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&infracfg CLK_INFRA_THERM_CK>,
+				 <&infracfg CLK_INFRA_ADC_26M_CK>;
+			clock-names = "therm", "auxadc";
+			nvmem-cells = <&thermal_calibration>;
+			nvmem-cell-names = "calibration-data";
+			#thermal-sensor-cells = <1>;
+			mediatek,auxadc = <&auxadc>;
+			mediatek,apmixedsys = <&apmixedsys>;
+		};
+
 		auxadc: adc@1100d000 {
 			compatible = "mediatek,mt7986-auxadc";
 			reg = <0 0x1100d000 0 0x1000>;
@@ -388,39 +392,23 @@
 			status = "disabled";
 		};
 
-		thermal: thermal@1100c800 {
-			#thermal-sensor-cells = <1>;
-			compatible = "mediatek,mt7986-thermal";
-			reg = <0 0x1100c800 0 0x800>;
-			interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&infracfg CLK_INFRA_THERM_CK>,
-				 <&infracfg CLK_INFRA_ADC_26M_CK>,
-				 <&infracfg CLK_INFRA_ADC_FRC_CK>;
-			clock-names = "therm", "auxadc", "adc_32k";
-			mediatek,auxadc = <&auxadc>;
-			mediatek,apmixedsys = <&apmixedsys>;
-			nvmem-cells = <&thermal_calibration>;
-			nvmem-cell-names = "calibration-data";
-		};
-
 		pcie: pcie@11280000 {
 			compatible = "mediatek,mt7986-pcie",
 				     "mediatek,mt8192-pcie";
+			reg = <0x00 0x11280000 0x00 0x4000>;
+			reg-names = "pcie-mac";
+			ranges = <0x82000000 0x00 0x20000000 0x00
+				  0x20000000 0x00 0x10000000>;
 			device_type = "pci";
 			#address-cells = <3>;
 			#size-cells = <2>;
-			reg = <0x00 0x11280000 0x00 0x4000>;
-			reg-names = "pcie-mac";
 			interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
 			bus-range = <0x00 0xff>;
-			ranges = <0x82000000 0x00 0x20000000 0x00
-				  0x20000000 0x00 0x10000000>;
 			clocks = <&infracfg CLK_INFRA_IPCIE_PIPE_CK>,
 				 <&infracfg CLK_INFRA_IPCIE_CK>,
 				 <&infracfg CLK_INFRA_IPCIER_CK>,
 				 <&infracfg CLK_INFRA_IPCIEB_CK>;
 			clock-names = "pl_250m", "tl_26m", "peri_26m", "top_133m";
-			status = "disabled";
 
 			phys = <&pcie_port PHY_TYPE_PCIE>;
 			phy-names = "pcie-phy";
@@ -431,6 +419,8 @@
 					<0 0 0 2 &pcie_intc 1>,
 					<0 0 0 3 &pcie_intc 2>,
 					<0 0 0 4 &pcie_intc 3>;
+			status = "disabled";
+
 			pcie_intc: interrupt-controller {
 				#address-cells = <0>;
 				#interrupt-cells = <1>;
@@ -441,9 +431,9 @@
 		pcie_phy: t-phy {
 			compatible = "mediatek,mt7986-tphy",
 				     "mediatek,generic-tphy-v2";
+			ranges;
 			#address-cells = <2>;
 			#size-cells = <2>;
-			ranges;
 			status = "disabled";
 
 			pcie_port: pcie-phy@11c00000 {
@@ -468,9 +458,9 @@
 		usb_phy: t-phy@11e10000 {
 			compatible = "mediatek,mt7986-tphy",
 				     "mediatek,generic-tphy-v2";
+			ranges = <0 0 0x11e10000 0x1700>;
 			#address-cells = <1>;
 			#size-cells = <1>;
-			ranges = <0 0 0x11e10000 0x1700>;
 			status = "disabled";
 
 			u2port0: usb-phy@0 {
@@ -498,8 +488,6 @@
 		};
 
 		ethsys: syscon@15000000 {
-			 #address-cells = <1>;
-			 #size-cells = <1>;
 			 compatible = "mediatek,mt7986-ethsys",
 				      "syscon";
 			 reg = <0 0x15000000 0 0x1000>;
@@ -533,20 +521,6 @@
 			mediatek,wo-ccif = <&wo_ccif1>;
 		};
 
-		wo_ccif0: syscon@151a5000 {
-			compatible = "mediatek,mt7986-wo-ccif", "syscon";
-			reg = <0 0x151a5000 0 0x1000>;
-			interrupt-parent = <&gic>;
-			interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
-		};
-
-		wo_ccif1: syscon@151ad000 {
-			compatible = "mediatek,mt7986-wo-ccif", "syscon";
-			reg = <0 0x151ad000 0 0x1000>;
-			interrupt-parent = <&gic>;
-			interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
-		};
-
 		eth: ethernet@15100000 {
 			compatible = "mediatek,mt7986-eth";
 			reg = <0 0x15100000 0 0x80000>;
@@ -579,26 +553,39 @@
 					  <&topckgen CLK_TOP_SGM_325M_SEL>;
 			assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
 						 <&apmixedsys CLK_APMIXED_SGMPLL>;
+			#address-cells = <1>;
+			#size-cells = <0>;
 			mediatek,ethsys = <&ethsys>;
 			mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
 			mediatek,wed-pcie = <&wed_pcie>;
 			mediatek,wed = <&wed0>, <&wed1>;
-			#reset-cells = <1>;
-			#address-cells = <1>;
-			#size-cells = <0>;
 			status = "disabled";
 		};
 
+		wo_ccif0: syscon@151a5000 {
+			compatible = "mediatek,mt7986-wo-ccif", "syscon";
+			reg = <0 0x151a5000 0 0x1000>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		wo_ccif1: syscon@151ad000 {
+			compatible = "mediatek,mt7986-wo-ccif", "syscon";
+			reg = <0 0x151ad000 0 0x1000>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
 		wifi: wifi@18000000 {
 			compatible = "mediatek,mt7986-wmac";
+			reg = <0 0x18000000 0 0x1000000>,
+			      <0 0x10003000 0 0x1000>,
+			      <0 0x11d10000 0 0x1000>;
 			resets = <&watchdog MT7986_TOPRGU_CONSYS_SW_RST>;
 			reset-names = "consys";
 			clocks = <&topckgen CLK_TOP_CONN_MCUSYS_SEL>,
 				 <&topckgen CLK_TOP_AP2CNN_HOST_SEL>;
 			clock-names = "mcu", "ap2conn";
-			reg = <0 0x18000000 0 0x1000000>,
-			      <0 0x10003000 0 0x1000>,
-			      <0 0x11d10000 0 0x1000>;
 			interrupts = <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 215 IRQ_TYPE_LEVEL_HIGH>,
@@ -646,4 +633,13 @@
 			};
 		};
 	};
+
+	timer {
+		compatible = "arm,armv8-timer";
+		interrupt-parent = <&gic>;
+		interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+			     <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt7986b-rfb.dts
@@ -152,12 +152,13 @@
 	pinctrl-0 = <&spi_flash_pins>;
 	cs-gpios = <0>, <0>;
 	status = "okay";
-	spi_nand: spi_nand@0 {
+
+	spi_nand: flash@0 {
 		compatible = "spi-nand";
 		reg = <0>;
 		spi-max-frequency = <10000000>;
-		spi-tx-buswidth = <4>;
-		spi-rx-buswidth = <4>;
+		spi-tx-bus-width = <4>;
+		spi-rx-bus-width = <4>;
 	};
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8173-elm-hana.dtsi
@@ -40,6 +40,14 @@
 		interrupts-extended = <&pio 117 IRQ_TYPE_LEVEL_LOW>;
 		reg = <0x2c>;
 		hid-descr-addr = <0x0020>;
+		/*
+		 * The trackpad needs a post-power-on delay of 100ms,
+		 * but at time of writing, the power supply for it on
+		 * this board is always on. The delay is therefore not
+		 * added to avoid impacting the readiness of the
+		 * trackpad.
+		 */
+		vdd-supply = <&mt6397_vgp6_reg>;
 		wakeup-source;
 	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
@@ -931,7 +931,7 @@
 		interrupt-controller;
 		#interrupt-cells = <2>;
 
-		clock: mt6397clock {
+		clock: clocks {
 			compatible = "mediatek,mt6397-clk";
 			#clock-cells = <1>;
 		};
@@ -942,11 +942,10 @@
 			#gpio-cells = <2>;
 		};
 
-		regulator: mt6397regulator {
+		regulators {
 			compatible = "mediatek,mt6397-regulator";
 
 			mt6397_vpca15_reg: buck_vpca15 {
-				regulator-compatible = "buck_vpca15";
 				regulator-name = "vpca15";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -956,7 +955,6 @@
 			};
 
 			mt6397_vpca7_reg: buck_vpca7 {
-				regulator-compatible = "buck_vpca7";
 				regulator-name = "vpca7";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -966,7 +964,6 @@
 			};
 
 			mt6397_vsramca15_reg: buck_vsramca15 {
-				regulator-compatible = "buck_vsramca15";
 				regulator-name = "vsramca15";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -975,7 +972,6 @@
 			};
 
 			mt6397_vsramca7_reg: buck_vsramca7 {
-				regulator-compatible = "buck_vsramca7";
 				regulator-name = "vsramca7";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -984,7 +980,6 @@
 			};
 
 			mt6397_vcore_reg: buck_vcore {
-				regulator-compatible = "buck_vcore";
 				regulator-name = "vcore";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -993,7 +988,6 @@
 			};
 
 			mt6397_vgpu_reg: buck_vgpu {
-				regulator-compatible = "buck_vgpu";
 				regulator-name = "vgpu";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -1002,7 +996,6 @@
 			};
 
 			mt6397_vdrm_reg: buck_vdrm {
-				regulator-compatible = "buck_vdrm";
 				regulator-name = "vdrm";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <1400000>;
@@ -1011,7 +1004,6 @@
 			};
 
 			mt6397_vio18_reg: buck_vio18 {
-				regulator-compatible = "buck_vio18";
 				regulator-name = "vio18";
 				regulator-min-microvolt = <1620000>;
 				regulator-max-microvolt = <1980000>;
@@ -1020,18 +1012,15 @@
 			};
 
 			mt6397_vtcxo_reg: ldo_vtcxo {
-				regulator-compatible = "ldo_vtcxo";
 				regulator-name = "vtcxo";
 				regulator-always-on;
 			};
 
 			mt6397_va28_reg: ldo_va28 {
-				regulator-compatible = "ldo_va28";
 				regulator-name = "va28";
 			};
 
 			mt6397_vcama_reg: ldo_vcama {
-				regulator-compatible = "ldo_vcama";
 				regulator-name = "vcama";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <1800000>;
@@ -1039,18 +1028,15 @@
 			};
 
 			mt6397_vio28_reg: ldo_vio28 {
-				regulator-compatible = "ldo_vio28";
 				regulator-name = "vio28";
 				regulator-always-on;
 			};
 
 			mt6397_vusb_reg: ldo_vusb {
-				regulator-compatible = "ldo_vusb";
 				regulator-name = "vusb";
 			};
 
 			mt6397_vmc_reg: ldo_vmc {
-				regulator-compatible = "ldo_vmc";
 				regulator-name = "vmc";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <3300000>;
@@ -1058,7 +1044,6 @@
 			};
 
 			mt6397_vmch_reg: ldo_vmch {
-				regulator-compatible = "ldo_vmch";
 				regulator-name = "vmch";
 				regulator-min-microvolt = <3000000>;
 				regulator-max-microvolt = <3300000>;
@@ -1066,7 +1051,6 @@
 			};
 
 			mt6397_vemc_3v3_reg: ldo_vemc3v3 {
-				regulator-compatible = "ldo_vemc3v3";
 				regulator-name = "vemc_3v3";
 				regulator-min-microvolt = <3000000>;
 				regulator-max-microvolt = <3300000>;
@@ -1074,7 +1058,6 @@
 			};
 
 			mt6397_vgp1_reg: ldo_vgp1 {
-				regulator-compatible = "ldo_vgp1";
 				regulator-name = "vcamd";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <1800000>;
@@ -1082,7 +1065,6 @@
 			};
 
 			mt6397_vgp2_reg: ldo_vgp2 {
-				regulator-compatible = "ldo_vgp2";
 				regulator-name = "vcamio";
 				regulator-min-microvolt = <3300000>;
 				regulator-max-microvolt = <3300000>;
@@ -1090,7 +1072,6 @@
 			};
 
 			mt6397_vgp3_reg: ldo_vgp3 {
-				regulator-compatible = "ldo_vgp3";
 				regulator-name = "vcamaf";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <1800000>;
@@ -1098,7 +1079,6 @@
 			};
 
 			mt6397_vgp4_reg: ldo_vgp4 {
-				regulator-compatible = "ldo_vgp4";
 				regulator-name = "vgp4";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3300000>;
@@ -1106,7 +1086,6 @@
 			};
 
 			mt6397_vgp5_reg: ldo_vgp5 {
-				regulator-compatible = "ldo_vgp5";
 				regulator-name = "vgp5";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3000000>;
@@ -1114,7 +1093,6 @@
 			};
 
 			mt6397_vgp6_reg: ldo_vgp6 {
-				regulator-compatible = "ldo_vgp6";
 				regulator-name = "vgp6";
 				regulator-min-microvolt = <3300000>;
 				regulator-max-microvolt = <3300000>;
@@ -1123,7 +1101,6 @@
 			};
 
 			mt6397_vibr_reg: ldo_vibr {
-				regulator-compatible = "ldo_vibr";
 				regulator-name = "vibr";
 				regulator-min-microvolt = <1300000>;
 				regulator-max-microvolt = <3300000>;
@@ -1131,7 +1108,7 @@
 			};
 		};
 
-		rtc: mt6397rtc {
+		rtc: rtc {
 			compatible = "mediatek,mt6397-rtc";
 		};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -307,11 +307,10 @@
 		interrupt-controller;
 		#interrupt-cells = <2>;
 
-		mt6397regulator: mt6397regulator {
+		regulators {
 			compatible = "mediatek,mt6397-regulator";
 
 			mt6397_vpca15_reg: buck_vpca15 {
-				regulator-compatible = "buck_vpca15";
 				regulator-name = "vpca15";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -320,7 +319,6 @@
 			};
 
 			mt6397_vpca7_reg: buck_vpca7 {
-				regulator-compatible = "buck_vpca7";
 				regulator-name = "vpca7";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -329,7 +327,6 @@
 			};
 
 			mt6397_vsramca15_reg: buck_vsramca15 {
-				regulator-compatible = "buck_vsramca15";
 				regulator-name = "vsramca15";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -338,7 +335,6 @@
 			};
 
 			mt6397_vsramca7_reg: buck_vsramca7 {
-				regulator-compatible = "buck_vsramca7";
 				regulator-name = "vsramca7";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -347,7 +343,6 @@
 			};
 
 			mt6397_vcore_reg: buck_vcore {
-				regulator-compatible = "buck_vcore";
 				regulator-name = "vcore";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -356,7 +351,6 @@
 			};
 
 			mt6397_vgpu_reg: buck_vgpu {
-				regulator-compatible = "buck_vgpu";
 				regulator-name = "vgpu";
 				regulator-min-microvolt = < 700000>;
 				regulator-max-microvolt = <1350000>;
@@ -365,7 +359,6 @@
 			};
 
 			mt6397_vdrm_reg: buck_vdrm {
-				regulator-compatible = "buck_vdrm";
 				regulator-name = "vdrm";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <1400000>;
@@ -374,7 +367,6 @@
 			};
 
 			mt6397_vio18_reg: buck_vio18 {
-				regulator-compatible = "buck_vio18";
 				regulator-name = "vio18";
 				regulator-min-microvolt = <1620000>;
 				regulator-max-microvolt = <1980000>;
@@ -383,19 +375,16 @@
 			};
 
 			mt6397_vtcxo_reg: ldo_vtcxo {
-				regulator-compatible = "ldo_vtcxo";
 				regulator-name = "vtcxo";
 				regulator-always-on;
 			};
 
 			mt6397_va28_reg: ldo_va28 {
-				regulator-compatible = "ldo_va28";
 				regulator-name = "va28";
 				regulator-always-on;
 			};
 
 			mt6397_vcama_reg: ldo_vcama {
-				regulator-compatible = "ldo_vcama";
 				regulator-name = "vcama";
 				regulator-min-microvolt = <1500000>;
 				regulator-max-microvolt = <2800000>;
@@ -403,18 +392,15 @@
 			};
 
 			mt6397_vio28_reg: ldo_vio28 {
-				regulator-compatible = "ldo_vio28";
 				regulator-name = "vio28";
 				regulator-always-on;
 			};
 
 			mt6397_vusb_reg: ldo_vusb {
-				regulator-compatible = "ldo_vusb";
 				regulator-name = "vusb";
 			};
 
 			mt6397_vmc_reg: ldo_vmc {
-				regulator-compatible = "ldo_vmc";
 				regulator-name = "vmc";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <3300000>;
@@ -422,7 +408,6 @@
 			};
 
 			mt6397_vmch_reg: ldo_vmch {
-				regulator-compatible = "ldo_vmch";
 				regulator-name = "vmch";
 				regulator-min-microvolt = <3000000>;
 				regulator-max-microvolt = <3300000>;
@@ -430,7 +415,6 @@
 			};
 
 			mt6397_vemc_3v3_reg: ldo_vemc3v3 {
-				regulator-compatible = "ldo_vemc3v3";
 				regulator-name = "vemc_3v3";
 				regulator-min-microvolt = <3000000>;
 				regulator-max-microvolt = <3300000>;
@@ -438,7 +422,6 @@
 			};
 
 			mt6397_vgp1_reg: ldo_vgp1 {
-				regulator-compatible = "ldo_vgp1";
 				regulator-name = "vcamd";
 				regulator-min-microvolt = <1220000>;
 				regulator-max-microvolt = <3300000>;
@@ -446,7 +429,6 @@
 			};
 
 			mt6397_vgp2_reg: ldo_vgp2 {
-				regulator-compatible = "ldo_vgp2";
 				regulator-name = "vcamio";
 				regulator-min-microvolt = <1000000>;
 				regulator-max-microvolt = <3300000>;
@@ -454,7 +436,6 @@
 			};
 
 			mt6397_vgp3_reg: ldo_vgp3 {
-				regulator-compatible = "ldo_vgp3";
 				regulator-name = "vcamaf";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3300000>;
@@ -462,7 +443,6 @@
 			};
 
 			mt6397_vgp4_reg: ldo_vgp4 {
-				regulator-compatible = "ldo_vgp4";
 				regulator-name = "vgp4";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3300000>;
@@ -470,7 +450,6 @@
 			};
 
 			mt6397_vgp5_reg: ldo_vgp5 {
-				regulator-compatible = "ldo_vgp5";
 				regulator-name = "vgp5";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3000000>;
@@ -478,7 +457,6 @@
 			};
 
 			mt6397_vgp6_reg: ldo_vgp6 {
-				regulator-compatible = "ldo_vgp6";
 				regulator-name = "vgp6";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3300000>;
@@ -486,7 +464,6 @@
 			};
 
 			mt6397_vibr_reg: ldo_vibr {
-				regulator-compatible = "ldo_vibr";
 				regulator-name = "vibr";
 				regulator-min-microvolt = <1300000>;
 				regulator-max-microvolt = <3300000>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-audio-da7219.dtsi
@@ -27,7 +27,7 @@
 			dlg,btn-cfg = <50>;
 			dlg,mic-det-thr = <500>;
 			dlg,jack-ins-deb = <20>;
-			dlg,jack-det-rate = "32ms_64ms";
+			dlg,jack-det-rate = "32_64";
 			dlg,jack-rem-deb = <1>;
 
 			dlg,a-d-btn-thr = <0xa>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-burnet.dts
@@ -30,3 +30,6 @@
 	};
 };
 
+&i2c2 {
+	i2c-scl-internal-delay-ns = <4100>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-cozmo.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-cozmo.dts
@@ -17,6 +17,8 @@
 };
 
 &i2c2 {
+	i2c-scl-internal-delay-ns = <25000>;
+
 	trackpad@2c {
 		compatible = "hid-over-i2c";
 		reg = <0x2c>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-damu.dts
@@ -26,7 +26,14 @@
 	hid-descr-addr = <0x0001>;
 };
 
+&mt6358codec {
+	mediatek,dmic-mode = <1>; /* one-wire */
+};
+
 &qca_wifi {
 	qcom,ath10k-calibration-variant = "GO_DAMU";
 };
 
+&i2c2 {
+	i2c-scl-internal-delay-ns = <20000>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-fennel.dtsi
@@ -25,3 +25,6 @@
 	};
 };
 
+&i2c2 {
+	i2c-scl-internal-delay-ns = <21500>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-kenzo.dts
@@ -11,3 +11,18 @@
 	model = "Google kenzo sku17 board";
 	compatible = "google,juniper-sku17", "google,juniper", "mediatek,mt8183";
 };
+
+&i2c0 {
+	touchscreen@40 {
+		compatible = "hid-over-i2c";
+		reg = <0x40>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&touchscreen_pins>;
+
+		interrupts-extended = <&pio 155 IRQ_TYPE_LEVEL_LOW>;
+
+		post-power-on-delay-ms = <70>;
+		hid-descr-addr = <0x0001>;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-pico6.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-pico6.dts
@@ -17,7 +17,7 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&bt_pins_wakeup>;
 
-		wobt {
+		event-wobt {
 			label = "Wake on BT";
 			gpios = <&pio 42 GPIO_ACTIVE_HIGH>;
 			linux,code = <KEY_WAKEUP>;
@@ -47,10 +47,8 @@
 	};
 };
 
-&wifi_wakeup {
-	wowlan {
-		gpios = <&pio 113 GPIO_ACTIVE_LOW>;
-	};
+&wifi_wakeup_event {
+	gpios = <&pio 113 GPIO_ACTIVE_LOW>;
 };
 
 &wifi_pwrseq {
@@ -82,7 +80,8 @@
 };
 
 &mmc1 {
-	bt_reset: bt-reset {
+	bluetooth@2 {
+		reg = <2>;
 		compatible = "mediatek,mt7921s-bluetooth";
 		pinctrl-names = "default";
 		pinctrl-0 = <&bt_pins_reset>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi-willow.dtsi
@@ -6,6 +6,21 @@
 /dts-v1/;
 #include "mt8183-kukui-jacuzzi.dtsi"
 
+&i2c0 {
+	touchscreen@40 {
+		compatible = "hid-over-i2c";
+		reg = <0x40>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&touchscreen_pins>;
+
+		interrupts-extended = <&pio 155 IRQ_TYPE_LEVEL_LOW>;
+
+		post-power-on-delay-ms = <70>;
+		hid-descr-addr = <0x0001>;
+	};
+};
+
 &i2c2 {
 	trackpad@2c {
 		compatible = "hid-over-i2c";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-jacuzzi.dtsi
@@ -8,35 +8,37 @@
 #include <arm/cros-ec-keyboard.dtsi>
 
 / {
-	pp1200_mipibrdg: pp1200-mipibrdg {
+	pp1000_mipibrdg: pp1000-mipibrdg {
 		compatible = "regulator-fixed";
-		regulator-name = "pp1200_mipibrdg";
+		regulator-name = "pp1000_mipibrdg";
+		regulator-min-microvolt = <1000000>;
+		regulator-max-microvolt = <1000000>;
 		pinctrl-names = "default";
-		pinctrl-0 = <&pp1200_mipibrdg_en>;
+		pinctrl-0 = <&pp1000_mipibrdg_en>;
 
 		enable-active-high;
 		regulator-boot-on;
 
 		gpio = <&pio 54 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&pp1800_alw>;
 	};
 
 	pp1800_mipibrdg: pp1800-mipibrdg {
 		compatible = "regulator-fixed";
 		regulator-name = "pp1800_mipibrdg";
 		pinctrl-names = "default";
-		pinctrl-0 = <&pp1800_lcd_en>;
+		pinctrl-0 = <&pp1800_mipibrdg_en>;
 
 		enable-active-high;
 		regulator-boot-on;
 
 		gpio = <&pio 36 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&pp1800_alw>;
 	};
 
 	pp3300_panel: pp3300-panel {
 		compatible = "regulator-fixed";
 		regulator-name = "pp3300_panel";
-		regulator-min-microvolt = <3300000>;
-		regulator-max-microvolt = <3300000>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&pp3300_panel_pins>;
 
@@ -44,18 +46,20 @@
 		regulator-boot-on;
 
 		gpio = <&pio 35 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&pp3300_alw>;
 	};
 
-	vddio_mipibrdg: vddio-mipibrdg {
+	pp3300_mipibrdg: pp3300-mipibrdg {
 		compatible = "regulator-fixed";
-		regulator-name = "vddio_mipibrdg";
+		regulator-name = "pp3300_mipibrdg";
 		pinctrl-names = "default";
-		pinctrl-0 = <&vddio_mipibrdg_en>;
+		pinctrl-0 = <&pp3300_mipibrdg_en>;
 
 		enable-active-high;
 		regulator-boot-on;
 
 		gpio = <&pio 37 GPIO_ACTIVE_HIGH>;
+		vin-supply = <&pp3300_alw>;
 	};
 
 	volume_buttons: volume-buttons {
@@ -151,25 +155,28 @@
 		pinctrl-0 = <&anx7625_pins>;
 		enable-gpios = <&pio 45 GPIO_ACTIVE_HIGH>;
 		reset-gpios = <&pio 73 GPIO_ACTIVE_HIGH>;
-		vdd10-supply = <&pp1200_mipibrdg>;
+		vdd10-supply = <&pp1000_mipibrdg>;
 		vdd18-supply = <&pp1800_mipibrdg>;
-		vdd33-supply = <&vddio_mipibrdg>;
+		vdd33-supply = <&pp3300_mipibrdg>;
 
-		#address-cells = <1>;
-		#size-cells = <0>;
-		port@0 {
-			reg = <0>;
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
 
-			anx7625_in: endpoint {
-				remote-endpoint = <&dsi_out>;
+			port@0 {
+				reg = <0>;
+
+				anx7625_in: endpoint {
+					remote-endpoint = <&dsi_out>;
+				};
 			};
-		};
 
-		port@1 {
-			reg = <1>;
+			port@1 {
+				reg = <1>;
 
-			anx7625_out: endpoint {
-				remote-endpoint = <&panel_in>;
+				anx7625_out: endpoint {
+					remote-endpoint = <&panel_in>;
+				};
 			};
 		};
 
@@ -393,14 +400,14 @@
 		"",
 		"";
 
-	pp1200_mipibrdg_en: pp1200-mipibrdg-en {
+	pp1000_mipibrdg_en: pp1000-mipibrdg-en {
 		pins1 {
 			pinmux = <PINMUX_GPIO54__FUNC_GPIO54>;
 			output-low;
 		};
 	};
 
-	pp1800_lcd_en: pp1800-lcd-en {
+	pp1800_mipibrdg_en: pp1800-mipibrdg-en {
 		pins1 {
 			pinmux = <PINMUX_GPIO36__FUNC_GPIO36>;
 			output-low;
@@ -462,7 +469,7 @@
 		};
 	};
 
-	vddio_mipibrdg_en: vddio-mipibrdg-en {
+	pp3300_mipibrdg_en: pp3300-mipibrdg-en {
 		pins1 {
 			pinmux = <PINMUX_GPIO37__FUNC_GPIO37>;
 			output-low;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-kakadu.dtsi
@@ -92,9 +92,9 @@
 	clock-frequency = <400000>;
 	vbus-supply = <&mt6358_vcn18_reg>;
 
-	eeprom@54 {
+	eeprom@50 {
 		compatible = "atmel,24c32";
-		reg = <0x54>;
+		reg = <0x50>;
 		pagesize = <32>;
 		vcc-supply = <&mt6358_vcn18_reg>;
 	};
@@ -360,6 +360,10 @@
 };
 
 &cros_ec {
+	cbas {
+		compatible = "google,cros-cbas";
+	};
+
 	keyboard-controller {
 		compatible = "google,cros-ec-keyb-switches";
 	};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-kodama.dtsi
@@ -79,9 +79,9 @@
 	clock-frequency = <400000>;
 	vbus-supply = <&mt6358_vcn18_reg>;
 
-	eeprom@54 {
+	eeprom@50 {
 		compatible = "atmel,24c64";
-		reg = <0x54>;
+		reg = <0x50>;
 		pagesize = <32>;
 		vcc-supply = <&mt6358_vcn18_reg>;
 	};
@@ -339,6 +339,10 @@
 };
 
 &cros_ec {
+	cbas {
+		compatible = "google,cros-cbas";
+	};
+
 	keyboard-controller {
 		compatible = "google,cros-ec-keyb-switches";
 	};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui-krane.dtsi
@@ -88,9 +88,9 @@
 	clock-frequency = <400000>;
 	vbus-supply = <&mt6358_vcn18_reg>;
 
-	eeprom@54 {
+	eeprom@50 {
 		compatible = "atmel,24c32";
-		reg = <0x54>;
+		reg = <0x50>;
 		pagesize = <32>;
 		vcc-supply = <&mt6358_vcn18_reg>;
 	};
@@ -343,6 +343,10 @@
 };
 
 &cros_ec {
+	cbas {
+		compatible = "google,cros-cbas";
+	};
+
 	keyboard-controller {
 		compatible = "google,cros-ec-keyb-switches";
 	};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
@@ -152,7 +152,7 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&wifi_pins_wakeup>;
 
-		button-wowlan {
+		wifi_wakeup_event: event-wowlan {
 			label = "Wake on WiFi";
 			gpios = <&pio 113 GPIO_ACTIVE_HIGH>;
 			linux,code = <KEY_WAKEUP>;
@@ -433,7 +433,6 @@
 };
 
 &mt6358_vgpu_reg {
-	regulator-min-microvolt = <625000>;
 	regulator-max-microvolt = <900000>;
 
 	regulator-coupled-with = <&mt6358_vsram_gpu_reg>;
@@ -804,7 +803,6 @@
 		};
 		pins-rts {
 			pinmux = <PINMUX_GPIO47__FUNC_URTS1>;
-			output-enable;
 		};
 		pins-cts {
 			pinmux = <PINMUX_GPIO46__FUNC_UCTS1>;
@@ -823,7 +821,6 @@
 		};
 		pins-rts {
 			pinmux = <PINMUX_GPIO47__FUNC_URTS1>;
-			output-enable;
 		};
 		pins-cts {
 			pinmux = <PINMUX_GPIO46__FUNC_UCTS1>;
@@ -937,10 +934,6 @@
 			google,usb-port-id = <0>;
 		};
 
-		cbas {
-			compatible = "google,cros-cbas";
-		};
-
 		typec {
 			compatible = "google,cros-ec-typec";
 			#address-cells = <1>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -1026,7 +1026,8 @@
 		};
 
 		keyboard: keyboard@10010000 {
-			compatible = "mediatek,mt6779-keypad";
+			compatible = "mediatek,mt8183-keypad",
+				     "mediatek,mt6779-keypad";
 			reg = <0 0x10010000 0 0x1000>;
 			interrupts = <GIC_SPI 186 IRQ_TYPE_EDGE_FALLING>;
 			clocks = <&clk26m>;
@@ -1628,6 +1629,7 @@
 			compatible = "mediatek,mt8183-mfgcfg", "syscon";
 			reg = <0 0x13000000 0 0x1000>;
 			#clock-cells = <1>;
+			power-domains = <&spm MT8183_POWER_DOMAIN_MFG_ASYNC>;
 		};
 
 		gpu: gpu@13040000 {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8186.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8186.dtsi
@@ -731,7 +731,7 @@
 		opp-900000000-3 {
 			opp-hz = /bits/ 64 <900000000>;
 			opp-microvolt = <850000>;
-			opp-supported-hw = <0x8>;
+			opp-supported-hw = <0xcf>;
 		};
 
 		opp-900000000-4 {
@@ -743,13 +743,13 @@
 		opp-900000000-5 {
 			opp-hz = /bits/ 64 <900000000>;
 			opp-microvolt = <825000>;
-			opp-supported-hw = <0x30>;
+			opp-supported-hw = <0x20>;
 		};
 
 		opp-950000000-3 {
 			opp-hz = /bits/ 64 <950000000>;
 			opp-microvolt = <900000>;
-			opp-supported-hw = <0x8>;
+			opp-supported-hw = <0xcf>;
 		};
 
 		opp-950000000-4 {
@@ -761,13 +761,13 @@
 		opp-950000000-5 {
 			opp-hz = /bits/ 64 <950000000>;
 			opp-microvolt = <850000>;
-			opp-supported-hw = <0x30>;
+			opp-supported-hw = <0x20>;
 		};
 
 		opp-1000000000-3 {
 			opp-hz = /bits/ 64 <1000000000>;
 			opp-microvolt = <950000>;
-			opp-supported-hw = <0x8>;
+			opp-supported-hw = <0xcf>;
 		};
 
 		opp-1000000000-4 {
@@ -779,7 +779,7 @@
 		opp-1000000000-5 {
 			opp-hz = /bits/ 64 <1000000000>;
 			opp-microvolt = <875000>;
-			opp-supported-hw = <0x30>;
+			opp-supported-hw = <0x20>;
 		};
 	};
 
@@ -931,11 +931,17 @@
 
 				power-domain@MT8186_POWER_DOMAIN_SSUSB {
 					reg = <MT8186_POWER_DOMAIN_SSUSB>;
+					clocks = <&topckgen CLK_TOP_USB_TOP>,
+						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_REF>;
+					clock-names = "sys_ck", "ref_ck";
 					#power-domain-cells = <0>;
 				};
 
 				power-domain@MT8186_POWER_DOMAIN_SSUSB_P1 {
 					reg = <MT8186_POWER_DOMAIN_SSUSB_P1>;
+					clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_SYS>,
+						 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_REF>;
+					clock-names = "sys_ck", "ref_ck";
 					#power-domain-cells = <0>;
 				};
 
@@ -1061,7 +1067,7 @@
 						reg = <MT8186_POWER_DOMAIN_VENC>;
 						clocks = <&topckgen CLK_TOP_VENC>,
 							 <&vencsys CLK_VENC_CKE1_VENC>;
-						clock-names = "venc0", "larb";
+						clock-names = "venc0", "subsys-larb";
 						mediatek,infracfg = <&infracfg_ao>;
 						#power-domain-cells = <0>;
 					};
@@ -1530,14 +1536,17 @@
 			clocks = <&topckgen CLK_TOP_USB_TOP>,
 				 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_REF>,
 				 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_HCLK>,
-				 <&infracfg_ao CLK_INFRA_AO_ICUSB>;
-			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck";
+				 <&infracfg_ao CLK_INFRA_AO_ICUSB>,
+				 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
 			interrupts = <GIC_SPI 303 IRQ_TYPE_LEVEL_HIGH 0>;
 			phys = <&u2port0 PHY_TYPE_USB2>;
 			power-domains = <&spm MT8186_POWER_DOMAIN_SSUSB>;
 			#address-cells = <2>;
 			#size-cells = <2>;
 			ranges;
+			wakeup-source;
+			mediatek,syscon-wakeup = <&pericfg 0x420 2>;
 			status = "disabled";
 
 			usb_host0: usb@11200000 {
@@ -1551,8 +1560,6 @@
 					 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_XHCI>;
 				clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
 				interrupts = <GIC_SPI 294 IRQ_TYPE_LEVEL_HIGH 0>;
-				mediatek,syscon-wakeup = <&pericfg 0x420 2>;
-				wakeup-source;
 				status = "disabled";
 			};
 		};
@@ -1595,14 +1602,17 @@
 			clocks = <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_SYS>,
 				 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_REF>,
 				 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_HCLK>,
-				 <&clk26m>;
-			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck";
+				 <&clk26m>,
+				 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_XHCI>;
+			clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck", "xhci_ck";
 			interrupts = <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH 0>;
 			phys = <&u2port1 PHY_TYPE_USB2>, <&u3port1 PHY_TYPE_USB3>;
 			power-domains = <&spm MT8186_POWER_DOMAIN_SSUSB_P1>;
 			#address-cells = <2>;
 			#size-cells = <2>;
 			ranges;
+			wakeup-source;
+			mediatek,syscon-wakeup = <&pericfg 0x424 2>;
 			status = "disabled";
 
 			usb_host1: usb@11280000 {
@@ -1616,8 +1626,6 @@
 					 <&infracfg_ao CLK_INFRA_AO_SSUSB_TOP_P1_XHCI>;
 				clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck","xhci_ck";
 				interrupts = <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH 0>;
-				mediatek,syscon-wakeup = <&pericfg 0x424 2>;
-				wakeup-source;
 				status = "disabled";
 			};
 		};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8188.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8188.dtsi
@@ -773,7 +773,6 @@
 					 <&clk26m>;
 				clock-names = "ref", "da_ref";
 				#phy-cells = <1>;
-				status = "disabled";
 			};
 		};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
@@ -147,6 +147,7 @@
 		regulator-boot-on;
 		gpio = <&pio 127 GPIO_ACTIVE_HIGH>;
 		vin-supply = <&pp3300_g>;
+		off-on-delay-us = <500000>;
 	};
 
 	/* separately switched 3.3V power rail */
@@ -1336,10 +1337,6 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 
-		base_detection: cbas {
-			compatible = "google,cros-cbas";
-		};
-
 		cros_ec_pwm: pwm {
 			compatible = "google,cros-ec-pwm";
 			#pwm-cells = <1>;
@@ -1422,9 +1419,8 @@
 
 		regulators {
 			mt6315_6_vbuck1: vbuck1 {
-				regulator-compatible = "vbuck1";
 				regulator-name = "Vbcpu";
-				regulator-min-microvolt = <300000>;
+				regulator-min-microvolt = <400000>;
 				regulator-max-microvolt = <1193750>;
 				regulator-enable-ramp-delay = <256>;
 				regulator-allowed-modes = <0 1 2>;
@@ -1432,9 +1428,8 @@
 			};
 
 			mt6315_6_vbuck3: vbuck3 {
-				regulator-compatible = "vbuck3";
 				regulator-name = "Vlcpu";
-				regulator-min-microvolt = <300000>;
+				regulator-min-microvolt = <400000>;
 				regulator-max-microvolt = <1193750>;
 				regulator-enable-ramp-delay = <256>;
 				regulator-allowed-modes = <0 1 2>;
@@ -1449,9 +1444,8 @@
 
 		regulators {
 			mt6315_7_vbuck1: vbuck1 {
-				regulator-compatible = "vbuck1";
 				regulator-name = "Vgpu";
-				regulator-min-microvolt = <606250>;
+				regulator-min-microvolt = <400000>;
 				regulator-max-microvolt = <800000>;
 				regulator-enable-ramp-delay = <256>;
 				regulator-allowed-modes = <0 1 2>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8192.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8192.dtsi
@@ -1456,6 +1456,7 @@
 			reg = <0 0x14001000 0 0x1000>;
 			interrupts = <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH 0>;
 			clocks = <&mmsys CLK_MM_DISP_MUTEX0>;
+			mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>;
 			mediatek,gce-events = <CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_0>,
 					      <CMDQ_EVENT_DISP_STREAM_DONE_ENG_EVENT_1>;
 			power-domains = <&spm MT8192_POWER_DOMAIN_DISP>;
@@ -1814,7 +1815,7 @@
 			mediatek,scp = <&scp>;
 			power-domains = <&spm MT8192_POWER_DOMAIN_VENC>;
 			clocks = <&vencsys CLK_VENC_SET1_VENC>;
-			clock-names = "venc-set1";
+			clock-names = "venc_sel";
 			assigned-clocks = <&topckgen CLK_TOP_VENC_SEL>;
 			assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL_D4>;
 		};
@@ -2225,7 +2226,7 @@
 			};
 		};
 
-		gpu0-thermal {
+		gpu-thermal {
 			polling-delay = <1000>;
 			polling-delay-passive = <250>;
 			thermal-sensors = <&lvts_ap MT8192_AP_GPU0>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r1.dts
@@ -23,3 +23,7 @@
 &ts_10 {
 	status = "okay";
 };
+
+&watchdog {
+	/delete-property/ mediatek,disable-extrst;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r2.dts
@@ -43,3 +43,7 @@
 &ts_10 {
 	status = "okay";
 };
+
+&watchdog {
+	/delete-property/ mediatek,disable-extrst;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8195-cherry-tomato-r3.dts
@@ -44,3 +44,7 @@
 &ts_10 {
 	status = "okay";
 };
+
+&watchdog {
+	/delete-property/ mediatek,disable-extrst;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
@@ -264,6 +264,38 @@
 	status = "okay";
 };
 
+&cpu0 {
+	cpu-supply = <&mt6359_vcore_buck_reg>;
+};
+
+&cpu1 {
+	cpu-supply = <&mt6359_vcore_buck_reg>;
+};
+
+&cpu2 {
+	cpu-supply = <&mt6359_vcore_buck_reg>;
+};
+
+&cpu3 {
+	cpu-supply = <&mt6359_vcore_buck_reg>;
+};
+
+&cpu4 {
+	cpu-supply = <&mt6315_6_vbuck1>;
+};
+
+&cpu5 {
+	cpu-supply = <&mt6315_6_vbuck1>;
+};
+
+&cpu6 {
+	cpu-supply = <&mt6315_6_vbuck1>;
+};
+
+&cpu7 {
+	cpu-supply = <&mt6315_6_vbuck1>;
+};
+
 &dp_intf0 {
 	status = "okay";
 
@@ -1211,9 +1243,8 @@
 
 		regulators {
 			mt6315_6_vbuck1: vbuck1 {
-				regulator-compatible = "vbuck1";
 				regulator-name = "Vbcpu";
-				regulator-min-microvolt = <300000>;
+				regulator-min-microvolt = <400000>;
 				regulator-max-microvolt = <1193750>;
 				regulator-enable-ramp-delay = <256>;
 				regulator-ramp-delay = <6250>;
@@ -1229,9 +1260,8 @@
 
 		regulators {
 			mt6315_7_vbuck1: vbuck1 {
-				regulator-compatible = "vbuck1";
 				regulator-name = "Vgpu";
-				regulator-min-microvolt = <625000>;
+				regulator-min-microvolt = <400000>;
 				regulator-max-microvolt = <1193750>;
 				regulator-enable-ramp-delay = <256>;
 				regulator-ramp-delay = <6250>;
@@ -1305,6 +1335,7 @@
 	rx-fifo-depth = <3072>;
 	vusb33-supply = <&mt6359_vusb_ldo_reg>;
 	vbus-supply = <&usb_vbus>;
+	mediatek,u3p-dis-msk = <1>;
 };
 
 &xhci2 {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8195-demo.dts
@@ -137,7 +137,6 @@
 			richtek,vinovp-microvolt = <14500000>;
 
 			otg_vbus_regulator: usb-otg-vbus-regulator {
-				regulator-compatible = "usb-otg-vbus";
 				regulator-name = "usb-otg-vbus";
 				regulator-min-microvolt = <4425000>;
 				regulator-max-microvolt = <5825000>;
@@ -149,7 +148,6 @@
 			LDO_VIN3-supply = <&mt6360_buck2>;
 
 			mt6360_buck1: buck1 {
-				regulator-compatible = "BUCK1";
 				regulator-name = "mt6360,buck1";
 				regulator-min-microvolt = <300000>;
 				regulator-max-microvolt = <1300000>;
@@ -160,7 +158,6 @@
 			};
 
 			mt6360_buck2: buck2 {
-				regulator-compatible = "BUCK2";
 				regulator-name = "mt6360,buck2";
 				regulator-min-microvolt = <300000>;
 				regulator-max-microvolt = <1300000>;
@@ -171,7 +168,6 @@
 			};
 
 			mt6360_ldo1: ldo1 {
-				regulator-compatible = "LDO1";
 				regulator-name = "mt6360,ldo1";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3600000>;
@@ -180,7 +176,6 @@
 			};
 
 			mt6360_ldo2: ldo2 {
-				regulator-compatible = "LDO2";
 				regulator-name = "mt6360,ldo2";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3600000>;
@@ -189,7 +184,6 @@
 			};
 
 			mt6360_ldo3: ldo3 {
-				regulator-compatible = "LDO3";
 				regulator-name = "mt6360,ldo3";
 				regulator-min-microvolt = <1200000>;
 				regulator-max-microvolt = <3600000>;
@@ -198,7 +192,6 @@
 			};
 
 			mt6360_ldo5: ldo5 {
-				regulator-compatible = "LDO5";
 				regulator-name = "mt6360,ldo5";
 				regulator-min-microvolt = <2700000>;
 				regulator-max-microvolt = <3600000>;
@@ -207,7 +200,6 @@
 			};
 
 			mt6360_ldo6: ldo6 {
-				regulator-compatible = "LDO6";
 				regulator-name = "mt6360,ldo6";
 				regulator-min-microvolt = <500000>;
 				regulator-max-microvolt = <2100000>;
@@ -216,7 +208,6 @@
 			};
 
 			mt6360_ldo7: ldo7 {
-				regulator-compatible = "LDO7";
 				regulator-name = "mt6360,ldo7";
 				regulator-min-microvolt = <500000>;
 				regulator-max-microvolt = <2100000>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8195.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8195.dtsi
@@ -487,7 +487,7 @@
 		};
 
 		infracfg_ao: syscon@10001000 {
-			compatible = "mediatek,mt8195-infracfg_ao", "syscon", "simple-mfd";
+			compatible = "mediatek,mt8195-infracfg_ao", "syscon";
 			reg = <0 0x10001000 0 0x1000>;
 			#clock-cells = <1>;
 			#reset-cells = <1>;
@@ -1584,9 +1584,6 @@
 			phy-names = "pcie-phy";
 			power-domains = <&spm MT8195_POWER_DOMAIN_PCIE_MAC_P1>;
 
-			resets = <&infracfg_ao MT8195_INFRA_RST2_PCIE_P1_SWRST>;
-			reset-names = "mac";
-
 			#interrupt-cells = <1>;
 			interrupt-map-mask = <0 0 0 7>;
 			interrupt-map = <0 0 0 1 &pcie_intc1 0>,
@@ -1998,6 +1995,7 @@
 			compatible = "mediatek,mt8195-vppsys0", "syscon";
 			reg = <0 0x14000000 0 0x1000>;
 			#clock-cells = <1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_1400XXXX 0 0x1000>;
 		};
 
 		dma-controller@14001000 {
@@ -2221,6 +2219,7 @@
 			compatible = "mediatek,mt8195-vppsys1", "syscon";
 			reg = <0 0x14f00000 0 0x1000>;
 			#clock-cells = <1>;
+			mediatek,gce-client-reg = <&gce1 SUBSYS_14f0XXXX 0 0x1000>;
 		};
 
 		mutex@14f01000 {
@@ -3050,6 +3049,7 @@
 			reg = <0 0x1c01a000 0 0x1000>;
 			mboxes = <&gce0 0 CMDQ_THR_PRIO_4>;
 			#clock-cells = <1>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c01XXXX 0xa000 0x1000>;
 		};
 
 
@@ -3104,7 +3104,7 @@
 		};
 
 		ovl0: ovl@1c000000 {
-			compatible = "mediatek,mt8195-disp-ovl", "mediatek,mt8183-disp-ovl";
+			compatible = "mediatek,mt8195-disp-ovl";
 			reg = <0 0x1c000000 0 0x1000>;
 			interrupts = <GIC_SPI 636 IRQ_TYPE_LEVEL_HIGH 0>;
 			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
@@ -3218,10 +3218,10 @@
 			compatible = "mediatek,mt8195-dp-intf";
 			reg = <0 0x1c015000 0 0x1000>;
 			interrupts = <GIC_SPI 657 IRQ_TYPE_LEVEL_HIGH 0>;
-			clocks = <&vdosys0  CLK_VDO0_DP_INTF0>,
-				 <&vdosys0 CLK_VDO0_DP_INTF0_DP_INTF>,
+			clocks = <&vdosys0 CLK_VDO0_DP_INTF0_DP_INTF>,
+				 <&vdosys0  CLK_VDO0_DP_INTF0>,
 				 <&apmixedsys CLK_APMIXED_TVDPLL1>;
-			clock-names = "engine", "pixel", "pll";
+			clock-names = "pixel", "engine", "pll";
 			status = "disabled";
 		};
 
@@ -3231,6 +3231,7 @@
 			interrupts = <GIC_SPI 658 IRQ_TYPE_LEVEL_HIGH 0>;
 			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS0>;
 			clocks = <&vdosys0 CLK_VDO0_DISP_MUTEX0>;
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c01XXXX 0x6000 0x1000>;
 			mediatek,gce-events = <CMDQ_EVENT_VDO0_DISP_STREAM_DONE_0>;
 		};
 
@@ -3296,11 +3297,10 @@
 		mutex1: mutex@1c101000 {
 			compatible = "mediatek,mt8195-disp-mutex";
 			reg = <0 0x1c101000 0 0x1000>;
-			reg-names = "vdo1_mutex";
 			interrupts = <GIC_SPI 494 IRQ_TYPE_LEVEL_HIGH 0>;
 			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
 			clocks = <&vdosys1 CLK_VDO1_DISP_MUTEX>;
-			clock-names = "vdo1_mutex";
+			mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x1000 0x1000>;
 			mediatek,gce-events = <CMDQ_EVENT_VDO1_STREAM_DONE_ENG_0>;
 		};
 
@@ -3486,10 +3486,10 @@
 			reg = <0 0x1c113000 0 0x1000>;
 			interrupts = <GIC_SPI 513 IRQ_TYPE_LEVEL_HIGH 0>;
 			power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>;
-			clocks = <&vdosys1 CLK_VDO1_DP_INTF0_MM>,
-				 <&vdosys1 CLK_VDO1_DPINTF>,
+			clocks = <&vdosys1 CLK_VDO1_DPINTF>,
+				 <&vdosys1 CLK_VDO1_DP_INTF0_MM>,
 				 <&apmixedsys CLK_APMIXED_TVDPLL2>;
-			clock-names = "engine", "pixel", "pll";
+			clock-names = "pixel", "engine", "pll";
 			status = "disabled";
 		};
 
@@ -3845,7 +3845,7 @@
 			};
 		};
 
-		gpu0-thermal {
+		gpu-thermal {
 			polling-delay = <1000>;
 			polling-delay-passive = <250>;
 			thermal-sensors = <&lvts_ap MT8195_AP_GPU0>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8365.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8365.dtsi
@@ -448,7 +448,8 @@
 		};
 
 		keypad: keypad@10010000 {
-			compatible = "mediatek,mt6779-keypad";
+			compatible = "mediatek,mt8365-keypad",
+				     "mediatek,mt6779-keypad";
 			reg = <0 0x10010000 0 0x1000>;
 			wakeup-source;
 			interrupts = <GIC_SPI 124 IRQ_TYPE_EDGE_FALLING>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8395-genio-1200-evk.dts
@@ -187,7 +187,7 @@
 		compatible = "snps,dwmac-mdio";
 		#address-cells = <1>;
 		#size-cells = <0>;
-		eth_phy0: eth-phy0@1 {
+		eth_phy0: ethernet-phy@1 {
 			compatible = "ethernet-phy-id001c.c916";
 			reg = <0x1>;
 		};
@@ -820,7 +820,6 @@
 
 		regulators {
 			mt6315_6_vbuck1: vbuck1 {
-				regulator-compatible = "vbuck1";
 				regulator-name = "Vbcpu";
 				regulator-min-microvolt = <300000>;
 				regulator-max-microvolt = <1193750>;
@@ -837,7 +836,6 @@
 
 		regulators {
 			mt6315_7_vbuck1: vbuck1 {
-				regulator-compatible = "vbuck1";
 				regulator-name = "Vgpu";
 				regulator-min-microvolt = <300000>;
 				regulator-max-microvolt = <1193750>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/mt8516.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/mt8516.dtsi
@@ -144,10 +144,10 @@
 		#size-cells = <2>;
 		ranges;
 
-		/* 128 KiB reserved for ARM Trusted Firmware (BL31) */
+		/* 192 KiB reserved for ARM Trusted Firmware (BL31) */
 		bl31_secmon_reserved: secmon@43000000 {
 			no-map;
-			reg = <0 0x43000000 0 0x20000>;
+			reg = <0 0x43000000 0 0x30000>;
 		};
 	};
 
@@ -206,7 +206,7 @@
 			compatible = "mediatek,mt8516-wdt",
 				     "mediatek,mt6589-wdt";
 			reg = <0 0x10007000 0 0x1000>;
-			interrupts = <GIC_SPI 198 IRQ_TYPE_EDGE_FALLING>;
+			interrupts = <GIC_SPI 198 IRQ_TYPE_LEVEL_LOW>;
 			#reset-cells = <1>;
 		};
 
@@ -268,7 +268,7 @@
 			interrupt-parent = <&gic>;
 			interrupt-controller;
 			reg = <0 0x10310000 0 0x1000>,
-			      <0 0x10320000 0 0x1000>,
+			      <0 0x1032f000 0 0x2000>,
 			      <0 0x10340000 0 0x2000>,
 			      <0 0x10360000 0 0x2000>;
 			interrupts = <GIC_PPI 9
@@ -344,6 +344,7 @@
 			reg = <0 0x11009000 0 0x90>,
 			      <0 0x11000180 0 0x80>;
 			interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_LOW>;
+			clock-div = <2>;
 			clocks = <&topckgen CLK_TOP_I2C0>,
 				 <&topckgen CLK_TOP_APDMA>;
 			clock-names = "main", "dma";
@@ -358,6 +359,7 @@
 			reg = <0 0x1100a000 0 0x90>,
 			      <0 0x11000200 0 0x80>;
 			interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_LOW>;
+			clock-div = <2>;
 			clocks = <&topckgen CLK_TOP_I2C1>,
 				 <&topckgen CLK_TOP_APDMA>;
 			clock-names = "main", "dma";
@@ -372,6 +374,7 @@
 			reg = <0 0x1100b000 0 0x90>,
 			      <0 0x11000280 0 0x80>;
 			interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_LOW>;
+			clock-div = <2>;
 			clocks = <&topckgen CLK_TOP_I2C2>,
 				 <&topckgen CLK_TOP_APDMA>;
 			clock-names = "main", "dma";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/mediatek/pumpkin-common.dtsi
@@ -47,7 +47,6 @@
 };
 
 &i2c0 {
-	clock-div = <2>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c0_pins_a>;
 	status = "okay";
@@ -156,7 +155,6 @@
 };
 
 &i2c2 {
-	clock-div = <2>;
 	pinctrl-names = "default";
 	pinctrl-0 = <&i2c2_pins_a>;
 	status = "okay";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/nvidia/tegra132-norrin.dts
@@ -9,8 +9,8 @@
 	compatible = "nvidia,norrin", "nvidia,tegra132", "nvidia,tegra124";
 
 	aliases {
-		rtc0 = "/i2c@7000d000/as3722@40";
-		rtc1 = "/rtc@7000e000";
+		rtc0 = &as3722;
+		rtc1 = &tegra_rtc;
 		serial0 = &uarta;
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/nvidia/tegra132.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/nvidia/tegra132.dtsi
@@ -572,7 +572,7 @@
 		status = "disabled";
 	};
 
-	rtc@7000e000 {
+	tegra_rtc: rtc@7000e000 {
 		compatible = "nvidia,tegra124-rtc", "nvidia,tegra20-rtc";
 		reg = <0x0 0x7000e000 0x0 0x100>;
 		interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/nvidia/tegra234-p3701-0008.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/nvidia/tegra234-p3701-0008.dtsi
@@ -44,39 +44,6 @@
 			status = "okay";
 		};
 
-		i2c@c250000 {
-			power-sensor@41 {
-				compatible = "ti,ina3221";
-				reg = <0x41>;
-				#address-cells = <1>;
-				#size-cells = <0>;
-
-				input@0 {
-					reg = <0x0>;
-					label = "CVB_ATX_12V";
-					shunt-resistor-micro-ohms = <2000>;
-				};
-
-				input@1 {
-					reg = <0x1>;
-					label = "CVB_ATX_3V3";
-					shunt-resistor-micro-ohms = <2000>;
-				};
-
-				input@2 {
-					reg = <0x2>;
-					label = "CVB_ATX_5V";
-					shunt-resistor-micro-ohms = <2000>;
-				};
-			};
-
-			power-sensor@44 {
-				compatible = "ti,ina219";
-				reg = <0x44>;
-				shunt-resistor = <2000>;
-			};
-		};
-
 		rtc@c2a0000 {
 			status = "okay";
 		};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/nvidia/tegra234-p3740-0002.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/nvidia/tegra234-p3740-0002.dtsi
@@ -183,6 +183,39 @@
 			phy-names = "usb2-0", "usb2-1", "usb2-2", "usb2-3",
 				"usb3-0", "usb3-1", "usb3-2";
 		};
+
+		i2c@c250000 {
+			power-sensor@41 {
+				compatible = "ti,ina3221";
+				reg = <0x41>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				input@0 {
+					reg = <0x0>;
+					label = "CVB_ATX_12V";
+					shunt-resistor-micro-ohms = <2000>;
+				};
+
+				input@1 {
+					reg = <0x1>;
+					label = "CVB_ATX_3V3";
+					shunt-resistor-micro-ohms = <2000>;
+				};
+
+				input@2 {
+					reg = <0x2>;
+					label = "CVB_ATX_5V";
+					shunt-resistor-micro-ohms = <2000>;
+				};
+			};
+
+			power-sensor@44 {
+				compatible = "ti,ina219";
+				reg = <0x44>;
+				shunt-resistor = <2000>;
+			};
+		};
 	};
 
 	vdd_3v3_dp: regulator-vdd-3v3-dp {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/nvidia/tegra234.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/nvidia/tegra234.dtsi
@@ -1711,7 +1711,7 @@
 			compatible = "nvidia,tegra234-sce-fabric";
 			reg = <0x0 0xb600000 0x0 0x40000>;
 			interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
-			status = "okay";
+			status = "disabled";
 		};
 
 		rce-fabric@be00000 {
@@ -1796,7 +1796,7 @@
 			assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>;
 			resets = <&bpmp TEGRA234_RESET_SPI2>;
 			reset-names = "spi";
-			dmas = <&gpcdma 19>, <&gpcdma 19>;
+			dmas = <&gpcdma 16>, <&gpcdma 16>;
 			dma-names = "rx", "tx";
 			dma-coherent;
 			status = "disabled";
@@ -1891,7 +1891,7 @@
 		};
 
 		dce-fabric@de00000 {
-			compatible = "nvidia,tegra234-sce-fabric";
+			compatible = "nvidia,tegra234-dce-fabric";
 			reg = <0x0 0xde00000 0x0 0x40000>;
 			interrupts = <GIC_SPI 381 IRQ_TYPE_LEVEL_HIGH>;
 			status = "okay";
@@ -1914,6 +1914,8 @@
 			#redistributor-regions = <1>;
 			#interrupt-cells = <3>;
 			interrupt-controller;
+
+			#address-cells = <0>;
 		};
 
 		smmu_iso: iommu@10000000 {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/Makefile
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/Makefile
@@ -88,20 +88,104 @@
 dtb-$(CONFIG_ARCH_QCOM)	+= msm8998-sony-xperia-yoshino-poplar.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= msm8998-xiaomi-sagit.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcm6490-fairphone-fp5.dtb
+#dtb-$(CONFIG_ARCH_QCOM)	+= qcm6490-addons-idp.dtb
+#dtb-$(CONFIG_ARCH_QCOM)	+= qcm6490-addons-idp-amoled.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcm6490-idp.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-1000.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs404-evb-4000.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs5430-fp1-addons-rb3gen2.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp1-addons-rb3gen2-hsp.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs5430-fp1-addons-rb3gen2-vision-mezz.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp1-addons-rb3gen2-vision-mezz-hsp.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs5430-fp1p5-addons-rb3gen2.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs5430-fp1p5-addons-rb3gen2-vision-mezz.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs5430-fp2-addons-rb3gen2.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp2-addons-rb3gen2-hsp.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs5430-fp2-addons-rb3gen2-vision-mezz.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp2-addons-rb3gen2-vision-mezz-hsp.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp2p5-addons-rb3gen2.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp2p5-addons-rb3gen2-hsp.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp2p5-addons-rb3gen2-vision-mezz.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp2p5-addons-rb3gen2-vision-mezz-hsp.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp3-addons-rb3gen2.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp3-addons-rb3gen2-hsp.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp3-addons-rb3gen2-vision-mezz.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp3-addons-rb3gen2-vision-mezz-hsp.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs615-addons-ride.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs615-ride.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-addons-rb3gen2.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs6490-addons-rb3gen2-hsp.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-addons-rb3gen2-ia-mezz.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-addons-rb3gen2-ptz-mezz.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-addons-rb3gen2-video-mezz.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-addons-rb3gen2-vision-mezz.dtb
+dtb-$(CONFIG_ARCH_QCOM) += qcs6490-addons-rb3gen2-vision-mezz-hsp.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs6490-rb3gen2-vision-mezzanine.dtb
+
+qcs8275-addons-iq-8275-evk-dtbs:= qcs8275-iq-8275-evk.dtb qcs8275-addons-iq-8275-evk.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs8275-addons-iq-8275-evk.dtb
+
+qcs8275-addons-iq-8275-evk-mezz-dtbs:= qcs8275-addons-iq-8275-evk.dtb qcs8275-addons-iq-8275-evk-mezz.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs8275-addons-iq-8275-evk-mezz.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs8275-iq-8275-evk.dtb
+
+qcs8275-addons-iq-8275-evk-pro-sku-dtbs:= qcs8275-iq-8275-evk-pro-sku.dtb qcs8275-addons-iq-8275-evk-pro-sku.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs8275-addons-iq-8275-evk-pro-sku.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs8275-iq-8275-evk-pro-sku.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs8300-addons-ride.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs8300-ride.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs8550-addons-aim300-aiot.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs8550-aim300-aiot.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs8550-rb5gen2-hdk.dtb
+
+qcs9075-addons-iq-9075-evk-mezz-dtbs:= qcs9075-addons-iq-9075-evk.dtb qcs9075-addons-iq-9075-evk-mezz.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs9075-addons-iq-9075-evk-mezz.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs9075-addons-iq-9075-evk.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs9075-addons-ride.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs9075-addons-ride-r3.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs9075-iq-9075-evk.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs9075-ride.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs9075-ride-r3.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-addons-ride.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-addons-ride-r3.dtb
+
+qcs9100-addons-ride-el2-dtbs:= qcs9100-addons-ride.dtb sa8775p-el2.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += qcs9100-addons-ride-el2.dtb
+
+qcs9100-addons-ride-r3-el2-dtbs:= qcs9100-addons-ride-r3.dtb sa8775p-el2.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += qcs9100-addons-ride-r3-el2.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-ride.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= qcs9100-ride-r3.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qdu1000-idp.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qrb2210-rb1.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qrb4210-rb2.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qrb5165-rb5.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qrb5165-rb5-vision-mezzanine.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= qru1000-idp.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= sa7255p-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sa8155p-adp.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= sa8255p-ride.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sa8295p-adp.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sa8540p-ride.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= sa8775p-addons-ride.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= sa8775p-addons-ride-r3.dtb
+
+sa8775p-addons-ride-el2-dtbs:= sa8775p-addons-ride.dtb sa8775p-el2.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += sa8775p-addons-ride-el2.dtb
+
+sa8775p-addons-ride-r3-el2-dtbs:= sa8775p-addons-ride-r3.dtb sa8775p-el2.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += sa8775p-addons-ride-r3-el2.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sa8775p-ride.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= sa8775p-ride-r3.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sc7180-acer-aspire1.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sc7180-idp.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sc7180-trogdor-coachz-r1.dtb
@@ -185,6 +269,9 @@
 dtb-$(CONFIG_ARCH_QCOM)	+= sdm845-cheza-r2.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sdm845-cheza-r3.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sdm845-db845c.dtb
+
+sdm845-db845c-navigation-mezzanine-dtbs	:= sdm845-db845c.dtb sdm845-db845c-navigation-mezzanine.dtbo
+
 dtb-$(CONFIG_ARCH_QCOM)	+= sdm845-db845c-navigation-mezzanine.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sdm845-lg-judyln.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sdm845-lg-judyp.dtb
@@ -237,5 +324,96 @@
 dtb-$(CONFIG_ARCH_QCOM)	+= sm8550-qrd.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm8650-mtp.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= sm8650-qrd.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= sm8650p-addons-aim500-aiot.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= sm8650p-aim500-aiot.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= x1e80100-addons-crd.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= x1e80100-crd.dtb
+dtb-$(CONFIG_ARCH_QCOM)	+= x1e80100-addons-qcp.dtb
 dtb-$(CONFIG_ARCH_QCOM)	+= x1e80100-qcp.dtb
+dtb-$(CONFIG_ARCH_QCOM) += rubikpi3.dtb
+
+# External overlays
+dtb-$(CONFIG_ARCH_QCOM) += qcs6490-addons-rb3gen2-video-mezz-ovl.dtb
+qcs6490-addons-rb3gen2-video-mezz-ovl-dtbs := \
+    qcs6490-addons-rb3gen2-video-mezz.dtb \
+    qcm6490-graphics.dtbo \
+    qcm6490-camera-rb3.dtbo \
+    qcm6490-video.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += qcs6490-addons-rb3gen2-vision-mezz-ovl.dtb
+qcs6490-addons-rb3gen2-vision-mezz-ovl-dtbs := \
+    qcs6490-addons-rb3gen2-vision-mezz.dtb \
+    qcm6490-graphics.dtbo \
+    qcm6490-camera-rb3.dtbo \
+    qcm6490-video.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += qcs6490-addons-rb3gen2-ia-mezz-ovl.dtb
+
+$(obj)/qcs6490-addons-rb3gen2-ia-mezz-ovl.dtb: $(obj)/qcs6490-addons-rb3gen2-ia-mezz.dtb FORCE
+	$(call if_changed,copy)
+
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp1-addons-rb3gen2-vision-mezz-ovl.dtb
+qcs5430-fp1-addons-rb3gen2-vision-mezz-ovl-dtbs := \
+    qcs5430-fp1-addons-rb3gen2-vision-mezz.dtb \
+    qcs5430-graphics.dtbo \
+    qcm5430-camera-rb3.dtbo \
+    qcm6490-video.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp2-addons-rb3gen2-vision-mezz-ovl.dtb
+qcs5430-fp2-addons-rb3gen2-vision-mezz-ovl-dtbs := \
+    qcs5430-fp2-addons-rb3gen2-vision-mezz.dtb \
+    qcs5430-graphics.dtbo \
+    qcm5430-camera-rb3.dtbo \
+    qcm6490-video.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp2p5-addons-rb3gen2-vision-mezz-ovl.dtb
+qcs5430-fp2p5-addons-rb3gen2-vision-mezz-ovl-dtbs := \
+    qcs5430-fp2p5-addons-rb3gen2-vision-mezz.dtb \
+    qcs5430-fp2p5-graphics.dtbo \
+    qcm5430-camera-rb3.dtbo \
+    qcm6490-video.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += qcs5430-fp3-addons-rb3gen2-vision-mezz-ovl.dtb
+qcs5430-fp3-addons-rb3gen2-vision-mezz-ovl-dtbs := \
+    qcs5430-fp3-addons-rb3gen2-vision-mezz.dtb \
+    qcs5430-fp2p5-graphics.dtbo \
+    qcm5430-camera-rb3.dtbo \
+    qcm6490-video.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += qcs9100-addons-ride-ovl.dtb
+qcs9100-addons-ride-ovl-dtbs := \
+    qcs9100-addons-ride.dtb \
+    sa8775p-video.dtbo \
+    qcs9100-graphics.dtbo \
+    qcs9100-ride-sx-camera.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += qcs9100-addons-ride-r3-ovl.dtb
+qcs9100-addons-ride-r3-ovl-dtbs := \
+    qcs9100-addons-ride-r3.dtb \
+    sa8775p-video.dtbo \
+    qcs9100-graphics.dtbo \
+    qcs9100-ride-sx-camera.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += qcs9075-addons-iq-9075-evk-ovl.dtb
+qcs9075-addons-iq-9075-evk-ovl-dtbs := \
+    qcs9075-addons-iq-9075-evk.dtb \
+    sa8775p-video.dtbo \
+    qcs9100-graphics.dtbo \
+    qcs9075-camera-iq-9075-evk.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM) += rubikpi3-ovl.dtb
+rubikpi3-ovl-dtbs := \
+    rubikpi3.dtb \
+    qcm6490-graphics.dtbo \
+    qcm6490-camera-rubikpi3.dtbo \
+    qcm6490-video.dtbo
+
+dtb-$(CONFIG_ARCH_QCOM)	+= combined-dtb.dtb
+
+dtbs-to-combined := $(filter %-ovl.dtb, $(dtb-y))
+
+quiet_cmd_cat = CAT     $@
+      cmd_cat = cat $(real-prereqs) > $@
+
+$(obj)/combined-dtb.dtb: $(addprefix $(obj)/, $(filter %-ovl.dtb, $(dtb-y))) FORCE
+	$(call if_changed,cat)
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/ipq6018.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/ipq6018.dtsi
@@ -642,6 +642,7 @@
 				clocks = <&xo>;
 				clock-names = "ref";
 				tx-fifo-resize;
+				snps,parkmode-disable-ss-quirk;
 				snps,is-utmi-l1-suspend;
 				snps,hird-threshold = /bits/ 8 <0x0>;
 				snps,dis_u2_susphy_quirk;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/ipq8074.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/ipq8074.dtsi
@@ -638,6 +638,7 @@
 				interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
 				phys = <&qusb_phy_0>, <&ssphy_0>;
 				phy-names = "usb2-phy", "usb3-phy";
+				snps,parkmode-disable-ss-quirk;
 				snps,is-utmi-l1-suspend;
 				snps,hird-threshold = /bits/ 8 <0x0>;
 				snps,dis_u2_susphy_quirk;
@@ -680,6 +681,7 @@
 				interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
 				phys = <&qusb_phy_1>, <&ssphy_1>;
 				phy-names = "usb2-phy", "usb3-phy";
+				snps,parkmode-disable-ss-quirk;
 				snps,is-utmi-l1-suspend;
 				snps,hird-threshold = /bits/ 8 <0x0>;
 				snps,dis_u2_susphy_quirk;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8916.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/msm8916.dtsi
@@ -125,7 +125,7 @@
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
 			#clock-cells = <0>;
-			clock-frequency = <32768>;
+			clock-frequency = <32764>;
 		};
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8939.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/msm8939.dtsi
@@ -34,7 +34,7 @@
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
 			#clock-cells = <0>;
-			clock-frequency = <32768>;
+			clock-frequency = <32764>;
 		};
 	};
 
@@ -2463,7 +2463,7 @@
 					type = "passive";
 				};
 
-				gpu_crit: gpu_crit {
+				gpu_crit: gpu-crit {
 					temperature = <95000>;
 					hysteresis = <2000>;
 					type = "critical";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8953-motorola-potter.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/msm8953-motorola-potter.dts
@@ -301,5 +301,6 @@
 };
 
 &usb3_dwc3 {
+	/delete-property/ usb-role-switch;
 	dr_mode = "peripheral";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8953-xiaomi-daisy.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/msm8953-xiaomi-daisy.dts
@@ -321,5 +321,6 @@
 };
 
 &usb3_dwc3 {
+	/delete-property/ usb-role-switch;
 	dr_mode = "peripheral";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8953-xiaomi-mido.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/msm8953-xiaomi-mido.dts
@@ -326,5 +326,6 @@
 };
 
 &usb3_dwc3 {
+	/delete-property/ usb-role-switch;
 	dr_mode = "peripheral";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8953-xiaomi-tissot.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/msm8953-xiaomi-tissot.dts
@@ -322,5 +322,6 @@
 };
 
 &usb3_dwc3 {
+	/delete-property/ usb-role-switch;
 	dr_mode = "peripheral";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts
@@ -357,5 +357,6 @@
 };
 
 &usb3_dwc3 {
+	/delete-property/ usb-role-switch;
 	dr_mode = "peripheral";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/msm8994-msft-lumia-octagon.dtsi
@@ -377,7 +377,7 @@
 &blsp2_i2c1 {
 	status = "okay";
 
-	sideinteraction: ad7147_captouch@2c {
+	sideinteraction: touch@2c {
 		compatible = "ad,ad7147_captouch";
 		reg = <0x2c>;
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/msm8994-sony-xperia-kitakami.dtsi
@@ -79,7 +79,7 @@
 			pmsg-size = <0x80000>;
 		};
 
-		fb_region: fb_region@40000000 {
+		fb_region: fb@40000000 {
 			reg = <0 0x40000000 0 0x1000000>;
 			no-map;
 		};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8994.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/msm8994.dtsi
@@ -34,7 +34,7 @@
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
 			#clock-cells = <0>;
-			clock-frequency = <32768>;
+			clock-frequency = <32764>;
 			clock-output-names = "sleep_clk";
 		};
 	};
@@ -233,7 +233,7 @@
 		#size-cells = <2>;
 		ranges;
 
-		dfps_data_mem: dfps_data_mem@3400000 {
+		dfps_data_mem: dfps-data@3400000 {
 			reg = <0 0x03400000 0 0x1000>;
 			no-map;
 		};
@@ -243,7 +243,7 @@
 			no-map;
 		};
 
-		smem_mem: smem_region@6a00000 {
+		smem_mem: smem@6a00000 {
 			reg = <0 0x06a00000 0 0x200000>;
 			no-map;
 		};
@@ -437,6 +437,15 @@
 			#size-cells = <1>;
 			ranges;
 
+			interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 311 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "qusb2_phy",
+					  "hs_phy_irq",
+					  "ss_phy_irq";
+
 			clocks = <&gcc GCC_USB30_MASTER_CLK>,
 				 <&gcc GCC_SYS_NOC_USB3_AXI_CLK>,
 				 <&gcc GCC_USB30_SLEEP_CLK>,
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi
@@ -405,7 +405,6 @@
 
 &hsusb_phy1 {
 	status = "okay";
-	extcon = <&typec>;
 
 	vdda-pll-supply = <&vreg_l12a_1p8>;
 	vdda-phy-dpdm-supply = <&vreg_l24a_3p075>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts
@@ -64,7 +64,7 @@
 		};
 
 		led@1 {
-			reg = <0>;
+			reg = <1>;
 			chan-name = "button-backlight1";
 			led-cur = /bits/ 8 <0x32>;
 			max-cur = /bits/ 8 <0xc8>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -756,12 +756,12 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 
-			qusb2p_hstx_trim: hstx_trim@24e {
+			qusb2p_hstx_trim: hstx-trim@24e {
 				reg = <0x24e 0x2>;
 				bits = <5 4>;
 			};
 
-			qusb2s_hstx_trim: hstx_trim@24f {
+			qusb2s_hstx_trim: hstx-trim@24f {
 				reg = <0x24f 0x1>;
 				bits = <1 4>;
 			};
@@ -2072,7 +2072,7 @@
 				<&gcc GCC_UFS_RX_SYMBOL_0_CLK>;
 			freq-table-hz =
 				<100000000 200000000>,
-				<0 0>,
+				<100000000 200000000>,
 				<0 0>,
 				<0 0>,
 				<0 0>,
@@ -3025,9 +3025,14 @@
 			#size-cells = <1>;
 			ranges;
 
-			interrupts = <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 347 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 243 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "hs_phy_irq", "ss_phy_irq";
+			interrupt-names = "pwr_event",
+					  "qusb2_phy",
+					  "hs_phy_irq",
+					  "ss_phy_irq";
 
 			clocks = <&gcc GCC_SYS_NOC_USB3_AXI_CLK>,
 				 <&gcc GCC_USB30_MASTER_CLK>,
@@ -3061,6 +3066,7 @@
 				snps,dis_u2_susphy_quirk;
 				snps,dis_enblslpm_quirk;
 				snps,is-utmi-l1-suspend;
+				snps,parkmode-disable-ss-quirk;
 				tx-fifo-resize;
 			};
 		};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/msm8998.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/msm8998.dtsi
@@ -1575,7 +1575,6 @@
 			 * SoC VDDMX RPM Power Domain in the Adreno driver.
 			 */
 			power-domains = <&gpucc GPU_GX_GDSC>;
-			status = "disabled";
 		};
 
 		gpucc: clock-controller@5065000 {
@@ -2146,6 +2145,7 @@
 				interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
 				snps,dis_u2_susphy_quirk;
 				snps,dis_enblslpm_quirk;
+				snps,parkmode-disable-ss-quirk;
 				phys = <&qusb2phy>, <&usb3phy>;
 				phy-names = "usb2-phy", "usb3-phy";
 				snps,has-lpm-erratum;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/pineapple-gpu-pwrlevels.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/pineapple-gpu-pwrlevels.dtsi
@@ -0,0 +1,687 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/* ACD Control register values */
+#define ACD_LEVEL_TURBO_L1    0x882f5ffd
+#define ACD_LEVEL_TURBO       0x882f5ffd
+#define ACD_LEVEL_NOM_L1      0x882f5ffd
+#define ACD_LEVEL_NOM         0xc0285ffd
+#define ACD_LEVEL_SVS_L2      0xe0295ffd
+#define ACD_LEVEL_SVS_L1      0xe0295ffd
+#define ACD_LEVEL_SVS_L0      0xc02a5ffd
+#define ACD_LEVEL_SVS         0xc02a5ffd
+#define ACD_LEVEL_LOW_SVS_L1  0xc02c5ffd
+#define ACD_LEVEL_LOW_SVS     0xc02f5ffd
+#define ACD_LEVEL_LOW_SVS_D0  0xc02f5ffd
+
+&msm_gpu {
+	/* Power levels */
+	qcom,gpu-pwrlevel-bins {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "qcom,gpu-pwrlevels-bins";
+
+		qcom,gpu-pwrlevels-0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			qcom,sku-codes = <SKU_CODE(PCODE_UNKNOWN, FC_AC)>;
+			qcom,speed-bin = <2>;
+
+			qcom,initial-pwrlevel = <12>;
+
+			/* Turbo_L1 */
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <903000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+
+				qcom,bus-freq = <9>;
+				qcom,bus-min = <9>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_TURBO_L1>;
+			};
+
+			/* Turbo */
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <869000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_TURBO>;
+
+				qcom,bus-freq = <8>;
+				qcom,bus-min = <8>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_TURBO>;
+			};
+
+			/* Nom_L1 */
+			qcom,gpu-pwrlevel@2 {
+				reg = <2>;
+				qcom,gpu-freq = <834000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+
+				qcom,bus-freq = <8>;
+				qcom,bus-min = <7>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_NOM_L1>;
+			};
+
+			/* Nom */
+			qcom,gpu-pwrlevel@3 {
+				reg = <3>;
+				qcom,gpu-freq = <770000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_NOM>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_NOM>;
+			};
+
+			/* SVS_L2 */
+			qcom,gpu-pwrlevel@4 {
+				reg = <4>;
+				qcom,gpu-freq = <720000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS_L2>;
+			};
+
+			/* SVS_L1 */
+			qcom,gpu-pwrlevel@5 {
+				reg = <5>;
+				qcom,gpu-freq = <680000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <5>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS_L1>;
+			};
+
+			/* SVS_L0 */
+			qcom,gpu-pwrlevel@6 {
+				reg = <6>;
+				qcom,gpu-freq = <629000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L0>;
+
+				qcom,bus-freq = <6>;
+				qcom,bus-min = <4>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS_L0>;
+			};
+
+			/* SVS */
+			qcom,gpu-pwrlevel@7 {
+				reg = <7>;
+				qcom,gpu-freq = <578000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS>;
+
+				qcom,bus-freq = <5>;
+				qcom,bus-min = <4>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS>;
+			};
+
+			/* Low_SVS_L1 */
+			qcom,gpu-pwrlevel@8 {
+				reg = <8>;
+				qcom,gpu-freq = <500000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>;
+
+				qcom,bus-freq = <5>;
+				qcom,bus-min = <3>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <ACD_LEVEL_LOW_SVS_L1>;
+			};
+
+			/* Low_SVS */
+			qcom,gpu-pwrlevel@9 {
+				reg = <9>;
+				qcom,gpu-freq = <422000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+
+				qcom,bus-freq = <5>;
+				qcom,bus-min = <3>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <ACD_LEVEL_LOW_SVS>;
+			};
+
+			/* Low_SVS_D0 */
+			qcom,gpu-pwrlevel@10 {
+				reg = <10>;
+				qcom,gpu-freq = <366000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <2>;
+				qcom,bus-max = <5>;
+
+				qcom,acd-level = <ACD_LEVEL_LOW_SVS_D0>;
+			};
+
+			/* Low_SVS_D1 */
+			qcom,gpu-pwrlevel@11 {
+				reg = <11>;
+				qcom,gpu-freq = <310000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+
+				qcom,bus-freq = <1>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <4>;
+			};
+
+			/* Low_SVS_D2 */
+			qcom,gpu-pwrlevel@12 {
+				reg = <12>;
+				qcom,gpu-freq = <231000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>;
+
+				qcom,bus-freq = <1>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <3>;
+			};
+		};
+
+		qcom,gpu-pwrlevels-1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			qcom,sku-codes = <SKU_CODE(PCODE_UNKNOWN, FC_AC)>;
+
+			qcom,initial-pwrlevel = <11>;
+
+			/* Turbo */
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <869000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_TURBO>;
+
+				qcom,bus-freq = <9>;
+				qcom,bus-min = <9>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_TURBO>;
+			};
+
+			/* Nom_L1 */
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <834000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+
+				qcom,bus-freq = <8>;
+				qcom,bus-min = <7>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_NOM_L1>;
+			};
+
+			/* Nom */
+			qcom,gpu-pwrlevel@2 {
+				reg = <2>;
+				qcom,gpu-freq = <770000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_NOM>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_NOM>;
+			};
+
+			/* SVS_L2 */
+			qcom,gpu-pwrlevel@3 {
+				reg = <3>;
+				qcom,gpu-freq = <720000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS_L2>;
+			};
+
+			/* SVS_L1 */
+			qcom,gpu-pwrlevel@4 {
+				reg = <4>;
+				qcom,gpu-freq = <680000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <5>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS_L1>;
+			};
+
+			/* SVS_L0 */
+			qcom,gpu-pwrlevel@5 {
+				reg = <5>;
+				qcom,gpu-freq = <629000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L0>;
+
+				qcom,bus-freq = <6>;
+				qcom,bus-min = <3>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS_L0>;
+			};
+
+			/* SVS */
+			qcom,gpu-pwrlevel@6 {
+				reg = <6>;
+				qcom,gpu-freq = <578000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS>;
+
+				qcom,bus-freq = <5>;
+				qcom,bus-min = <2>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS>;
+			};
+
+			/* Low_SVS_L1 */
+			qcom,gpu-pwrlevel@7 {
+				reg = <7>;
+				qcom,gpu-freq = <500000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>;
+
+				qcom,bus-freq = <5>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <5>;
+
+				qcom,acd-level = <ACD_LEVEL_LOW_SVS_L1>;
+			};
+
+			/* Low_SVS */
+			qcom,gpu-pwrlevel@8 {
+				reg = <8>;
+				qcom,gpu-freq = <422000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+
+				qcom,bus-freq = <5>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <5>;
+
+				qcom,acd-level = <ACD_LEVEL_LOW_SVS>;
+			};
+
+			/* Low_SVS_D0 */
+			qcom,gpu-pwrlevel@9 {
+				reg = <9>;
+				qcom,gpu-freq = <366000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <3>;
+
+				qcom,acd-level = <ACD_LEVEL_LOW_SVS_D0>;
+			};
+
+			/* Low_SVS_D1 */
+			qcom,gpu-pwrlevel@10 {
+				reg = <10>;
+				qcom,gpu-freq = <310000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+
+				qcom,bus-freq = <1>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <3>;
+			};
+
+			/* Low_SVS_D2 */
+			qcom,gpu-pwrlevel@11 {
+				reg = <11>;
+				qcom,gpu-freq = <231000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>;
+
+				qcom,bus-freq = <1>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <3>;
+			};
+		};
+
+		qcom,gpu-pwrlevels-2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			qcom,sku-codes = <SKU_CODE(PCODE_0, FC_Y0)
+					SKU_CODE(PCODE_1, FC_Y0)
+					SKU_CODE(PCODE_0, FC_Y1)>;
+
+			qcom,initial-pwrlevel = <12>;
+
+			/* Turbo_L1 */
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <903000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+
+				qcom,bus-freq = <9>;
+				qcom,bus-min = <9>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_TURBO_L1>;
+			};
+
+			/* Turbo */
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <869000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_TURBO>;
+
+				qcom,bus-freq = <8>;
+				qcom,bus-min = <8>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_TURBO>;
+			};
+
+			/* Nom_L1 */
+			qcom,gpu-pwrlevel@2 {
+				reg = <2>;
+				qcom,gpu-freq = <834000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+
+				qcom,bus-freq = <8>;
+				qcom,bus-min = <7>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_NOM_L1>;
+			};
+
+			/* Nom */
+			qcom,gpu-pwrlevel@3 {
+				reg = <3>;
+				qcom,gpu-freq = <770000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_NOM>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_NOM>;
+			};
+
+			/* SVS_L2 */
+			qcom,gpu-pwrlevel@4 {
+				reg = <4>;
+				qcom,gpu-freq = <720000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS_L2>;
+			};
+
+			/* SVS_L1 */
+			qcom,gpu-pwrlevel@5 {
+				reg = <5>;
+				qcom,gpu-freq = <680000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <5>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS_L1>;
+			};
+
+			/* SVS_L0 */
+			qcom,gpu-pwrlevel@6 {
+				reg = <6>;
+				qcom,gpu-freq = <629000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L0>;
+
+				qcom,bus-freq = <6>;
+				qcom,bus-min = <3>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS_L0>;
+			};
+
+			/* SVS */
+			qcom,gpu-pwrlevel@7 {
+				reg = <7>;
+				qcom,gpu-freq = <578000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS>;
+
+				qcom,bus-freq = <5>;
+				qcom,bus-min = <2>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS>;
+			};
+
+			/* Low_SVS_L1 */
+			qcom,gpu-pwrlevel@8 {
+				reg = <8>;
+				qcom,gpu-freq = <500000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>;
+
+				qcom,bus-freq = <5>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <5>;
+
+				qcom,acd-level = <ACD_LEVEL_LOW_SVS_L1>;
+			};
+
+			/* Low_SVS */
+			qcom,gpu-pwrlevel@9 {
+				reg = <9>;
+				qcom,gpu-freq = <422000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+
+				qcom,bus-freq = <5>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <5>;
+
+				qcom,acd-level = <ACD_LEVEL_LOW_SVS>;
+			};
+
+			/* Low_SVS_D0 */
+			qcom,gpu-pwrlevel@10 {
+				reg = <10>;
+				qcom,gpu-freq = <366000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <3>;
+
+				qcom,acd-level = <ACD_LEVEL_LOW_SVS_D0>;
+			};
+
+			/* Low_SVS_D1 */
+			qcom,gpu-pwrlevel@11 {
+				reg = <11>;
+				qcom,gpu-freq = <310000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+
+				qcom,bus-freq = <1>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <3>;
+			};
+
+			/* Low_SVS_D2 */
+			qcom,gpu-pwrlevel@12 {
+				reg = <12>;
+				qcom,gpu-freq = <231000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>;
+
+				qcom,bus-freq = <1>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <3>;
+			};
+		};
+
+		qcom,gpu-pwrlevels-3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			qcom,sku-codes = <SKU_CODE(PCODE_UNKNOWN, FC_UNKNOWN)>;
+
+			qcom,initial-pwrlevel = <10>;
+
+			/* Nom_L1 */
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <834000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+
+				qcom,bus-freq = <9>;
+				qcom,bus-min = <9>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_NOM_L1>;
+			};
+
+			/* Nom */
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <770000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_NOM>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_NOM>;
+			};
+
+			/* SVS_L2 */
+			qcom,gpu-pwrlevel@2 {
+				reg = <2>;
+				qcom,gpu-freq = <720000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS_L2>;
+			};
+
+			/* SVS_L1 */
+			qcom,gpu-pwrlevel@3 {
+				reg = <3>;
+				qcom,gpu-freq = <680000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <5>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS_L1>;
+			};
+
+			/* SVS_L0 */
+			qcom,gpu-pwrlevel@4 {
+				reg = <4>;
+				qcom,gpu-freq = <629000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L0>;
+
+				qcom,bus-freq = <6>;
+				qcom,bus-min = <3>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS_L0>;
+			};
+
+			/* SVS */
+			qcom,gpu-pwrlevel@5 {
+				reg = <5>;
+				qcom,gpu-freq = <578000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS>;
+
+				qcom,bus-freq = <5>;
+				qcom,bus-min = <2>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <ACD_LEVEL_SVS>;
+			};
+
+			/* Low_SVS_L1 */
+			qcom,gpu-pwrlevel@6 {
+				reg = <6>;
+				qcom,gpu-freq = <500000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>;
+
+				qcom,bus-freq = <5>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <5>;
+
+				qcom,acd-level = <ACD_LEVEL_LOW_SVS_L1>;
+			};
+
+			/* Low_SVS */
+			qcom,gpu-pwrlevel@7 {
+				reg = <7>;
+				qcom,gpu-freq = <422000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+
+				qcom,bus-freq = <5>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <5>;
+
+				qcom,acd-level = <ACD_LEVEL_LOW_SVS>;
+			};
+
+			/* Low_SVS_D0 */
+			qcom,gpu-pwrlevel@8 {
+				reg = <8>;
+				qcom,gpu-freq = <366000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <3>;
+
+				qcom,acd-level = <ACD_LEVEL_LOW_SVS_D0>;
+			};
+
+			/* Low_SVS_D1 */
+			qcom,gpu-pwrlevel@9 {
+				reg = <9>;
+				qcom,gpu-freq = <310000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+
+				qcom,bus-freq = <1>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <3>;
+			};
+
+			/* Low_SVS_D2 */
+			qcom,gpu-pwrlevel@10 {
+				reg = <10>;
+				qcom,gpu-freq = <231000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>;
+
+				qcom,bus-freq = <1>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <3>;
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/pineapple-gpu.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/pineapple-gpu.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,aop-qmp.h>
+#include <dt-bindings/clock/qcom,gcc-pineapple.h>
+#include <dt-bindings/clock/qcom,gpucc-pineapple.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interconnect/qcom,pineapple.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator-levels.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "pineapple-gpu.dtsi"
+#include "pineapple-gpu-pwrlevels.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. Pineapple";
+	compatible = "qcom,pineapple";
+	qcom,msm-id = <557 0x10000>, <577 0x10000>;
+	qcom,board-id = <0 0>;
+};
+
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/pineapple-gpu.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/pineapple-gpu.dtsi
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define MHZ_TO_KBPS(mhz, w) ((mhz * 1000000 * w) / (1024))
+
+/* External feature codes */
+#define FC_UNKNOWN 0x0
+#define FC_AA 0x1
+#define FC_AB 0x2
+#define FC_AC 0x3
+#define FC_AD 0x4
+
+/* Internal feature codes */
+#define FC_Y0 0x00f1
+#define FC_Y1 0x00f2
+
+/* Pcodes */
+#define PCODE_UNKNOWN 0
+#define PCODE_0 1
+#define PCODE_1 2
+#define PCODE_2 3
+#define PCODE_3 4
+#define PCODE_4 5
+#define PCODE_5 6
+#define PCODE_6 7
+#define PCODE_7 8
+
+#define SKU_CODE(pcode, featurecode) ((pcode << 16) + featurecode)
+
+&msm_gpu {
+	compatible = "qcom,adreno-gpu-gen7-9-0", "qcom,kgsl-3d0";
+	status = "ok";
+	reg = <0x3d00000 0x40000>, <0x3d61000 0x3000>,
+		<0x03d50000 0x10000>, <0x03d9e000 0x2000>,
+		<0x10900000 0x80000>, <0x10048000 0x8000>,
+		<0x10b05000 0x1000>;
+	reg-names = "kgsl_3d0_reg_memory", "cx_dbgc", "rscc", "cx_misc",
+		"qdss_gfx", "qdss_etr", "qdss_tmc";
+	interrupts = <0 300 IRQ_TYPE_LEVEL_HIGH>;
+	interrupt-names = "kgsl_3d0_irq";
+
+	clocks = <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+		<&gcc GCC_GPU_SNOC_DVM_GFX_CLK>,
+		<&gpucc GPU_CC_AHB_CLK>,
+		<&aoss_qmp QDSS_CLK>;
+	clock-names = "gcc_gpu_memnoc_gfx",
+			"gcc_gpu_snoc_dvm_gfx",
+			"gpu_cc_ahb",
+			"apb_pclk";
+
+	qcom,gpu-model = "Adreno750";
+
+	qcom,chipid = <0x43051400>;
+
+	qcom,no-nap;
+
+	qcom,min-access-length = <32>;
+
+	qcom,ubwc-mode = <4>;
+
+	qcom,gpu-qdss-stm = <0x161c0000 0x40000>; /* base addr, size */
+
+	qcom,tzone-names = "gpuss-0", "gpuss-1", "gpuss-2", "gpuss-3",
+			"gpuss-4", "gpuss-5", "gpuss-6", "gpuss-7";
+
+	interconnects = <&gem_noc MASTER_GFX3D &mc_virt SLAVE_EBI1>;
+	interconnect-names = "gpu_icc_path";
+
+	qcom,bus-table-cnoc =
+		<0>,   /* Off */
+		<100>; /* On */
+
+	qcom,bus-table-ddr =
+		<MHZ_TO_KBPS(0, 4)>,    /* index=0 */
+		<MHZ_TO_KBPS(547, 4) >, /* index=1 */
+		<MHZ_TO_KBPS(768, 4) >, /* index=2 */
+		<MHZ_TO_KBPS(1555, 4)>, /* index=3 */
+		<MHZ_TO_KBPS(1708, 4)>, /* index=4 */
+		<MHZ_TO_KBPS(2092, 4)>, /* index=5 */
+		<MHZ_TO_KBPS(2736, 4)>, /* index=6 */
+		<MHZ_TO_KBPS(3187, 4)>, /* index=7 */
+		<MHZ_TO_KBPS(3686, 4)>, /* index=8 */
+		<MHZ_TO_KBPS(4224, 4)>; /* index=9 */
+
+	nvmem-cells = <&gpu_speed_bin>;
+	nvmem-cell-names = "speed_bin";
+
+	zap-shader {
+		memory-region = <&gpu_micro_code_mem>;
+	};
+
+	qcom,gpu-mempools {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "qcom,gpu-mempools";
+
+		/* 4K Page Pool configuration */
+		qcom,gpu-mempool@0 {
+			reg = <0>;
+			qcom,mempool-page-size = <4096>;
+			qcom,mempool-reserved = <2048>;
+		};
+		/* 8K Page Pool configuration */
+		qcom,gpu-mempool@1 {
+			reg = <1>;
+			qcom,mempool-page-size = <8192>;
+			qcom,mempool-reserved = <1024>;
+		};
+		/* 64K Page Pool configuration */
+		qcom,gpu-mempool@2 {
+			reg = <2>;
+			qcom,mempool-page-size = <65536>;
+			qcom,mempool-reserved = <256>;
+		};
+		/* 128K Page Pool configuration */
+		qcom,gpu-mempool@3 {
+			reg = <3>;
+			qcom,mempool-page-size = <131072>;
+			qcom,mempool-reserved = <128>;
+		};
+		/* 256K Page Pool configuration */
+		qcom,gpu-mempool@4 {
+			reg = <4>;
+			qcom,mempool-page-size = <262144>;
+			qcom,mempool-reserved = <80>;
+		};
+		/* 1M Page Pool configuration */
+		qcom,gpu-mempool@5 {
+			reg = <5>;
+			qcom,mempool-page-size = <1048576>;
+			qcom,mempool-reserved = <32>;
+		};
+	};
+};
+
+&soc {
+	kgsl_msm_iommu: qcom,kgsl-iommu@3da0000 {
+		compatible = "qcom,kgsl-smmu-v2";
+		reg = <0x03da0000 0x40000>;
+
+		vddcx-supply = <&gpu_cc_cx_gdsc>;
+
+		gfx3d_user: gfx3d_user {
+			compatible = "qcom,smmu-kgsl-cb";
+			iommus = <&kgsl_smmu 0x0 0x000>;
+			qcom,iommu-dma = "disabled";
+		};
+
+		gfx3d_lpac: gfx3d_lpac {
+			compatible = "qcom,smmu-kgsl-cb";
+			iommus = <&kgsl_smmu 0x1 0x000>;
+			qcom,iommu-dma = "disabled";
+		};
+
+		gfx3d_secure: gfx3d_secure {
+			compatible = "qcom,smmu-kgsl-cb";
+			iommus = <&kgsl_smmu 0x2 0x000>;
+			qcom,iommu-dma = "disabled";
+		};
+	};
+
+	gmu: qcom,gmu@3d69000 {
+		compatible = "qcom,gen7-gmu";
+
+		reg = <0x3d68000 0x37000>,
+		      <0xb280000 0x10000>,
+		      <0x03D40000 0x10000>;
+
+		reg-names = "gmu", "gmu_pdc", "gmu_ao_blk_dec0";
+
+		interrupts = <0 304 IRQ_TYPE_LEVEL_HIGH>,
+			<0 305 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "hfi", "gmu";
+
+		regulator-names = "vddcx", "vdd";
+
+		vddcx-supply = <&gpu_cc_cx_gdsc>;
+		vdd-supply = <&gpu_cc_gx_gdsc>;
+
+		clocks = <&gpucc GPU_CC_CX_GMU_CLK>,
+			<&gpucc GPU_CC_CXO_CLK>,
+			<&gcc GCC_DDRSS_GPU_AXI_CLK>,
+			<&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+			<&gpucc GPU_CC_AHB_CLK>,
+			<&gpucc GPU_CC_HUB_CX_INT_CLK>;
+
+		clock-names = "gmu_clk", "cxo_clk", "axi_clk",
+			"memnoc_clk", "ahb_clk", "hub_clk";
+
+		qcom,gmu-freq-table = <260000000 RPMH_REGULATOR_LEVEL_LOW_SVS>,
+					<625000000 RPMH_REGULATOR_LEVEL_SVS>;
+		qcom,gmu-perf-ddr-bw = <MHZ_TO_KBPS(768, 4)>;
+
+		iommus = <&kgsl_smmu 0x5 0x000>;
+		qcom,iommu-dma = "disabled";
+
+		qcom,ipc-core = <0x00400000 0x140000>;
+
+		mboxes = <&qmp_aop 0>;
+		mbox-names = "aop";
+	};
+
+	coresight_cx_dgbc: qcom,gpu-coresight-cx {
+		compatible = "qcom,gpu-coresight-cx";
+
+		coresight-name = "coresight-gfx-cx";
+		coresight-atid = <52>;
+
+		out-ports {
+			port {
+				cx_dbgc_out_funnel_gfx: endpoint {
+					remote-endpoint =
+					  <&funnel_gfx_in_cx_dbgc>;
+				};
+			};
+		};
+	};
+
+	coresight_gx_dgbc: qcom,gpu-coresight-gx {
+		compatible = "qcom,gpu-coresight-gx";
+
+		coresight-name = "coresight-gfx";
+		coresight-atid = <53>;
+
+		out-ports {
+			port {
+				gx_dbgc_out_funnel_gfx: endpoint {
+					remote-endpoint =
+					  <&funnel_gfx_in_gx_dbgc>;
+				};
+			};
+		};
+	};
+};
+
+&funnel_gfx {
+	status = "ok";
+	in-ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			funnel_gfx_in_gx_dbgc: endpoint {
+			remote-endpoint =
+				<&gx_dbgc_out_funnel_gfx>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			funnel_gfx_in_cx_dbgc: endpoint {
+			remote-endpoint =
+				<&cx_dbgc_out_funnel_gfx>;
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/pineapple-v2-gpu-pwrlevels.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/pineapple-v2-gpu-pwrlevels.dtsi
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/* ACD Control register values */
+#define ACD_LEVEL_TURBO_L1    0x882f5ffd
+#define ACD_LEVEL_TURBO       0x882f5ffd
+#define ACD_LEVEL_NOM_L1      0x882f5ffd
+#define ACD_LEVEL_NOM         0xc0285ffd
+#define ACD_LEVEL_SVS_L2      0xe0295ffd
+#define ACD_LEVEL_SVS_L1      0xe0295ffd
+#define ACD_LEVEL_SVS_L0      0xc02a5ffd
+#define ACD_LEVEL_SVS         0xc02a5ffd
+#define ACD_LEVEL_LOW_SVS_L1  0xc02c5ffd
+#define ACD_LEVEL_LOW_SVS     0xc02f5ffd
+#define ACD_LEVEL_LOW_SVS_D0  0xc02f5ffd
+
+&msm_gpu {
+	/* Power levels */
+	qcom,gpu-pwrlevels {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "qcom,gpu-pwrlevels";
+
+		qcom,initial-pwrlevel = <11>;
+
+		/* Turbo */
+		qcom,gpu-pwrlevel@0 {
+			reg = <0>;
+			qcom,gpu-freq = <903000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_TURBO>;
+
+			qcom,bus-freq = <9>;
+			qcom,bus-min = <9>;
+			qcom,bus-max = <9>;
+
+			qcom,acd-level = <ACD_LEVEL_TURBO>;
+		};
+
+		/* Nom_L1 */
+		qcom,gpu-pwrlevel@1 {
+			reg = <1>;
+			qcom,gpu-freq = <834000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+
+			qcom,bus-freq = <8>;
+			qcom,bus-min = <7>;
+			qcom,bus-max = <9>;
+
+			qcom,acd-level = <ACD_LEVEL_NOM_L1>;
+		};
+
+		/* Nom */
+		qcom,gpu-pwrlevel@2 {
+			reg = <2>;
+			qcom,gpu-freq = <770000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_NOM>;
+
+			qcom,bus-freq = <7>;
+			qcom,bus-min = <6>;
+			qcom,bus-max = <9>;
+
+			qcom,acd-level = <ACD_LEVEL_NOM>;
+		};
+
+		/* SVS_L2 */
+		qcom,gpu-pwrlevel@3 {
+			reg = <3>;
+			qcom,gpu-freq = <720000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+
+			qcom,bus-freq = <7>;
+			qcom,bus-min = <6>;
+			qcom,bus-max = <9>;
+
+			qcom,acd-level = <ACD_LEVEL_SVS_L2>;
+		};
+
+		/* SVS_L1 */
+		qcom,gpu-pwrlevel@4 {
+			reg = <4>;
+			qcom,gpu-freq = <680000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+			qcom,bus-freq = <7>;
+			qcom,bus-min = <5>;
+			qcom,bus-max = <9>;
+
+			qcom,acd-level = <ACD_LEVEL_SVS_L1>;
+		};
+
+		/* SVS_L0 */
+		qcom,gpu-pwrlevel@5 {
+			reg = <5>;
+			qcom,gpu-freq = <629000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L0>;
+
+			qcom,bus-freq = <6>;
+			qcom,bus-min = <4>;
+			qcom,bus-max = <7>;
+
+			qcom,acd-level = <ACD_LEVEL_SVS_L0>;
+		};
+
+		/* SVS */
+		qcom,gpu-pwrlevel@6 {
+			reg = <6>;
+			qcom,gpu-freq = <578000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_SVS>;
+
+			qcom,bus-freq = <5>;
+			qcom,bus-min = <4>;
+			qcom,bus-max = <7>;
+
+			qcom,acd-level = <ACD_LEVEL_SVS>;
+		};
+
+		/* Low_SVS_L1 */
+		qcom,gpu-pwrlevel@7 {
+			reg = <7>;
+			qcom,gpu-freq = <500000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>;
+
+			qcom,bus-freq = <5>;
+			qcom,bus-min = <3>;
+			qcom,bus-max = <7>;
+
+			qcom,acd-level = <ACD_LEVEL_LOW_SVS_L1>;
+		};
+
+		/* Low_SVS */
+		qcom,gpu-pwrlevel@8 {
+			reg = <8>;
+			qcom,gpu-freq = <422000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+
+			qcom,bus-freq = <5>;
+			qcom,bus-min = <3>;
+			qcom,bus-max = <7>;
+
+			qcom,acd-level = <ACD_LEVEL_LOW_SVS>;
+		};
+
+		/* Low_SVS_D0 */
+		qcom,gpu-pwrlevel@9 {
+			reg = <9>;
+			qcom,gpu-freq = <366000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>;
+
+			qcom,bus-freq = <3>;
+			qcom,bus-min = <2>;
+			qcom,bus-max = <5>;
+
+			qcom,acd-level = <ACD_LEVEL_LOW_SVS_D0>;
+		};
+
+		/* Low_SVS_D1 */
+		qcom,gpu-pwrlevel@10 {
+			reg = <10>;
+			qcom,gpu-freq = <310000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+
+			qcom,bus-freq = <1>;
+			qcom,bus-min = <1>;
+			qcom,bus-max = <4>;
+		};
+
+		/* Low_SVS_D2 */
+		qcom,gpu-pwrlevel@11 {
+			reg = <11>;
+			qcom,gpu-freq = <231000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>;
+
+			qcom,bus-freq = <1>;
+			qcom,bus-min = <1>;
+			qcom,bus-max = <3>;
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/pineapple-v2-gpu.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/pineapple-v2-gpu.dts
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,aop-qmp.h>
+#include <dt-bindings/clock/qcom,gcc-pineapple.h>
+#include <dt-bindings/clock/qcom,gpucc-pineapple.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interconnect/qcom,pineapple.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator-levels.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "pineapple-v2-gpu.dtsi"
+#include "pineapple-v2-gpu-pwrlevels.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. Pineapple";
+	compatible = "qcom,pineapple";
+	qcom,msm-id = <557 0x20000>, <577 0x20000>;
+	qcom,board-id = <0 0>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/pineapple-v2-gpu.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/pineapple-v2-gpu.dtsi
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "pineapple-gpu.dtsi"
+
+&msm_gpu {
+	compatible = "qcom,adreno-gpu-gen7-9-1", "qcom,kgsl-3d0";
+
+	qcom,gpu-model = "Adreno750v2";
+
+	qcom,chipid = <0x43051401>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/pm4125.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/pm4125.dtsi
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (c) 2023, Linaro Ltd
+ */
+
+#include <dt-bindings/iio/qcom,spmi-vadc.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+
+&spmi_bus {
+	pmic@0 {
+		compatible = "qcom,pm2250", "qcom,spmi-pmic";
+		reg = <0x0 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pon@800 {
+			compatible = "qcom,pm8916-pon";
+			reg = <0x800>;
+
+			pm4125_pwrkey: pwrkey {
+				compatible = "qcom,pm8941-pwrkey";
+				interrupts-extended = <&spmi_bus 0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
+				linux,code = <KEY_POWER>;
+				debounce = <15625>;
+				bias-pull-up;
+			};
+
+			pm4125_resin: resin {
+				compatible = "qcom,pm8941-resin";
+				interrupts-extended = <&spmi_bus 0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
+				debounce = <15625>;
+				bias-pull-up;
+				status = "disabled";
+			};
+		};
+
+		rtc@6000 {
+			compatible = "qcom,pm8941-rtc";
+			reg = <0x6000>, <0x6100>;
+			reg-names = "rtc", "alarm";
+			interrupts-extended = <&spmi_bus 0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>;
+		};
+
+		pm4125_gpios: gpio@c000 {
+			compatible = "qcom,pm2250-gpio", "qcom,spmi-gpio";
+			reg = <0xc000>;
+			gpio-controller;
+			gpio-ranges = <&pm4125_gpios 0 0 10>;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	pmic@1 {
+		compatible = "qcom,pm2250", "qcom,spmi-pmic";
+		reg = <0x1 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/pm6150.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/pm6150.dtsi
@@ -13,7 +13,7 @@
 	thermal-zones {
 		pm6150_thermal: pm6150-thermal {
 			polling-delay-passive = <100>;
-			polling-delay = <0>;
+
 			thermal-sensors = <&pm6150_temp>;
 
 			trips {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/pm6150l.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/pm6150l.dtsi
@@ -10,9 +10,6 @@
 / {
 	thermal-zones {
 		pm6150l-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&pm6150l_temp>;
 
 			trips {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/pm7250b.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/pm7250b.dtsi
@@ -164,5 +164,10 @@
 		reg = <PM7250B_SID1 SPMI_USID>;
 		#address-cells = <1>;
 		#size-cells = <0>;
+
+		pm7250b_vib: pm7250b-vib@5300 {
+			compatible = "qcom,pm7250b-vib", "qcom,pmi632-vib";
+			reg = <0x5300>;
+		};
 	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/pm7325b.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/pm7325b.dtsi
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/iio/qcom,spmi-vadc.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+
+&spmi_bus {
+	pm7325b: pmic@3 {
+		compatible = "qcom,pm7325", "qcom,spmi-pmic";
+		reg = <0x3 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pm7325b_temp_alarm: temp-alarm@a00 {
+			compatible = "qcom,spmi-temp-alarm";
+			reg = <0xa00>;
+			interrupts = <0x3 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+			#thermal-sensor-cells = <0>;
+		};
+
+		pm7325b_gpios: gpio@8800 {
+			compatible = "qcom,pm7325b-gpio", "qcom,spmi-gpio";
+			reg = <0x8800>;
+			gpio-controller;
+			gpio-ranges = <&pm7325b_gpios 0 0 8>;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		pm7325b_lcdb: qcom,lcdb@fd00 {
+			compatible = "qcom,lcdb-pm7325b";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xfd00>;
+			interrupts = <0x3 0xfd 0x1 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "sc-irq";
+
+			lcdb_ldo_vreg: ldo {
+				label = "ldo";
+				regulator-name = "lcdb_ldo";
+				regulator-min-microvolt = <4400000>;
+				regulator-max-microvolt = <6000000>;
+			};
+
+			lcdb_ncp_vreg: ncp {
+				label = "ncp";
+				regulator-name = "lcdb_ncp";
+				regulator-min-microvolt = <4400000>;
+				regulator-max-microvolt = <6000000>;
+			};
+
+			lcdb_bst_vreg: bst {
+				label = "bst";
+				regulator-name = "lcdb_bst";
+				regulator-min-microvolt = <4700000>;
+				regulator-max-microvolt = <6400000>;
+			};
+		};
+
+		pm7325b_wled: qcom,wled@d800 {
+			compatible = "qcom,pm7325b-wled";
+			reg = <0xfb00>, <0xfc00>;
+			reg-names = "wled-ctrl-base", "wled-sink-base";
+			label = "backlight";
+			interrupts = <0x3 0xfb 0x1 IRQ_TYPE_EDGE_RISING>,
+					<0x3 0xfb 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "ovp", "short";
+			qcom,current-limit-microamp = <22500>;
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm2290.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm2290.dtsi
@@ -442,6 +442,11 @@
 			#hwlock-cells = <1>;
 		};
 
+		tcsr_regs: syscon@3c0000 {
+			compatible = "qcom,qcm2290-tcsr", "syscon";
+			reg = <0x0 0x003c0000 0x0 0x40000>;
+		};
+
 		tlmm: pinctrl@500000 {
 			compatible = "qcom,qcm2290-tlmm";
 			reg = <0x0 0x00500000 0x0 0x300000>;
@@ -690,6 +695,8 @@
 
 			#phy-cells = <0>;
 
+			qcom,tcsr-reg = <&tcsr_regs 0xb244>;
+
 			status = "disabled";
 		};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm5430-camera-rb3.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm5430-camera-rb3.dtso
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sc7280.h>
+#include <dt-bindings/clock/qcom,camcc-sc7280.h>
+#include <dt-bindings/interconnect/qcom,sc7280.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+
+#include "qcm6490-camera-rb3.dtsi"
+#include "qcm6490-camera-sensor-rb3.dtsi"
+
+&cam_csid2 {
+		status = "disabled";
+};
+
+&cam_vfe2 {
+		status = "disabled";
+};
\ No newline at end of file
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-addons-idp-amoled.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-addons-idp-amoled.dts
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * qcm6490-addons IDP amoled device tree source
+ *
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
+
+/dts-v1/;
+
+#include "qcm6490-addons-idp.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcm6490-addons IDP + amoled platform";
+	compatible = "qcom,qcm6490-addons-idp-amoled","qcom,sc7280";
+
+	/* This will be deprecated soon */
+	qcom,msm-id = <497 0x10000>;
+	qcom,board-id = <34 0x2>, <34 0x602>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-addons-idp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-addons-idp.dts
@@ -0,0 +1,347 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * qcm6490-addons IDP device tree source
+ *
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
+
+/dts-v1/;
+
+#include "qcm6490-idp.dts"
+#include "qcm6490-addons.dtsi"
+#include "pm7325b.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcm6490-addons IDP platform";
+	compatible = "qcom,qcm6490-addons-idp","qcom,sc7280";
+
+	pmic_glink: pmic-glink {
+	};
+};
+
+&i2c1 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	pm8008i_chip: pm8008i@8 {
+		compatible = "qcom,i2c-pmic";
+		reg = <0x8>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pm8008i_active>;
+
+		pm8008-chip@900 {
+			compatible = "qcom,pm8008-chip";
+			reg = <0x900>;
+
+			PM8008I_EN: qcom,pm8008-chip-en {
+				regulator-name = "pm8008i-chip-en";
+			};
+		};
+	};
+
+	pm8008i_ldo: pm8008i@9 {
+		compatible = "qcom,i2c-pmic";
+		reg = <0x9>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		qcom,pm8008i-regulator {
+			compatible = "qcom,pm8008-regulator";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pm8008_en-supply = <&PM8008I_EN>;
+			vdd_l1_l2-supply = <&vreg_s8b_1p272>;
+			vdd_l3_l4-supply = <&vreg_bob_3p296>;
+			vdd_l5-supply = <&vreg_s1b_1p872>;
+			vdd_l6-supply = <&vreg_bob_3p296>;
+			vdd_l7-supply = <&vreg_bob_3p296>;
+
+			L1I: PM8008I_L1: regulator@4000 {
+				reg = <0x4000>;
+				regulator-name = "pm8008i_l1";
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1200000>;
+				qcom,min-dropout-voltage = <160000>;
+				qcom,hpm-min-load = <30000>;
+			};
+
+			L2I: PM8008I_L2: regulator@4100 {
+				reg = <0x4100>;
+				regulator-name = "pm8008i_l2";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1150000>;
+				qcom,min-dropout-voltage = <128000>;
+				qcom,hpm-min-load = <30000>;
+			};
+
+			L3I: PM8008I_L3: regulator@4200 {
+				reg = <0x4200>;
+				regulator-name = "pm8008i_l3";
+				regulator-min-microvolt = <2700000>;
+				regulator-max-microvolt = <3000000>;
+				qcom,min-dropout-voltage = <144000>;
+			};
+
+			L4I: PM8008I_L4: regulator@4300 {
+				reg = <0x4300>;
+				regulator-name = "pm8008i_l4";
+				regulator-min-microvolt = <2700000>;
+				regulator-max-microvolt = <2900000>;
+				qcom,min-dropout-voltage = <128000>;
+			};
+
+			L5I: PM8008I_L5: regulator@4400 {
+				reg = <0x4400>;
+				regulator-name = "pm8008i_l5";
+				regulator-min-microvolt = <1700000>;
+				regulator-max-microvolt = <1900000>;
+				qcom,min-dropout-voltage = <136000>;
+			};
+
+			L6I: PM8008I_L6: regulator@4500 {
+				reg = <0x4500>;
+				regulator-name = "pm8008i_l6";
+				regulator-min-microvolt = <2700000>;
+				regulator-max-microvolt = <2900000>;
+				qcom,min-dropout-voltage = <128000>;
+			};
+
+			L7I: PM8008I_L7: regulator@4600 {
+				reg = <0x4600>;
+				regulator-name = "pm8008i_l7";
+				regulator-min-microvolt = <2700000>;
+				regulator-max-microvolt = <3000000>;
+				qcom,min-dropout-voltage = <312000>;
+			};
+		};
+	};
+
+	pm8008j_chip: pm8008j@c {
+		compatible = "qcom,i2c-pmic";
+		reg = <0xc>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&pm8008j_active>;
+
+		pm8008-chip@900 {
+			compatible = "qcom,pm8008-chip";
+			reg = <0x900>;
+
+			PM8008J_EN: qcom,pm8008-chip-en {
+				regulator-name = "pm8008j-chip-en";
+			};
+		};
+	};
+
+	pm8008j_ldo: pm8008j@d {
+		compatible = "qcom,i2c-pmic";
+		reg = <0xd>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		qcom,pm8008j-regulator {
+			compatible = "qcom,pm8008-regulator";
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			pm8008_en-supply = <&PM8008J_EN>;
+			vdd_l1_l2-supply = <&vreg_s8b_1p272>;
+			vdd_l3_l4-supply = <&vreg_s1b_1p872>;
+			vdd_l5-supply = <&vreg_bob_3p296>;
+			vdd_l6-supply = <&vreg_bob_3p296>;
+			vdd_l7-supply = <&vreg_bob_3p296>;
+
+			L1J: PM8008J_L1: regulator@4000 {
+				reg = <0x4000>;
+				regulator-name = "pm8008j_l1";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1150000>;
+				qcom,min-dropout-voltage = <96000>;
+				qcom,hpm-min-load = <30000>;
+			};
+
+			L2J: PM8008J_L2: regulator@4100 {
+				reg = <0x4100>;
+				regulator-name = "pm8008j_l2";
+				regulator-min-microvolt = <950000>;
+				regulator-max-microvolt = <1250000>;
+				qcom,min-dropout-voltage = <24000>;
+				qcom,hpm-min-load = <30000>;
+			};
+
+			L3J: PM8008J_L3: regulator@4200 {
+				reg = <0x4200>;
+				regulator-name = "pm8008j_l3";
+				regulator-min-microvolt = <1460000>;
+				regulator-max-microvolt = <1800000>;
+				qcom,min-dropout-voltage = <224000>;
+			};
+
+			L4J: PM8008J_L4: regulator@4300 {
+				reg = <0x4300>;
+				regulator-name = "pm8008j_l4";
+				regulator-min-microvolt = <1504000>;
+				regulator-max-microvolt = <1600000>;
+				qcom,min-dropout-voltage = <0>;
+			};
+
+			L5J: PM8008J_L5: regulator@4400 {
+				reg = <0x4400>;
+				regulator-name = "pm8008j_l5";
+				regulator-min-microvolt = <2700000>;
+				regulator-max-microvolt = <2900000>;
+				qcom,min-dropout-voltage = <104000>;
+			};
+
+			L6J: PM8008J_L6: regulator@4500 {
+				reg = <0x4500>;
+				regulator-name = "pm8008j_l6";
+				regulator-min-microvolt = <2800000>;
+				regulator-max-microvolt = <2800000>;
+				qcom,min-dropout-voltage = <112000>;
+			};
+
+			L7J: PM8008J_L7: regulator@4600 {
+				reg = <0x4600>;
+				regulator-name = "pm8008j_l7";
+				regulator-min-microvolt = <3000000>;
+				regulator-max-microvolt = <3544000>;
+				qcom,min-dropout-voltage = <96000>;
+			};
+		};
+	};
+};
+
+&pm8350c_gpios {
+	pm8008i-reset-state {
+		pm8008i_active: pm8008i-active-pins {
+			pins = "gpio3";
+			function = "normal";
+			bias-disable;
+			output-high;
+			power-source = <0>;
+		};
+	};
+
+	pm8008j-reset-state {
+		pm8008j_active: pm8008j-active-pins {
+			pins = "gpio4";
+			function = "normal";
+			bias-disable;
+			output-high;
+			power-source = <0>;
+		};
+	};
+};
+
+&q6apmbedai {
+	qcom,prmcc_clk = <&q6prmcc>;
+};
+
+&sound {
+	pinctrl-names = "default", "stub_aif1_active", "stub_aif1_sleep";
+	pinctrl-0 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+				<&mi2s0_sclk_sleep>, <&mi2s0_ws_sleep>;
+	pinctrl-1 = <&mi2s0_data0>, <&mi2s0_data1>, <&mi2s0_mclk>,
+				<&mi2s0_sclk>, <&mi2s0_ws>;
+	pinctrl-2 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+				<&mi2s0_sclk_sleep>, <&mi2s0_ws_sleep>;
+
+	mi2s-capture-dai-link {
+		link-name = "MI2S-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	mi2s-playback-dai-link {
+		link-name = "MI2S-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+	tdm-capture-dai-link {
+		link-name = "TDM-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_TX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	tdm-playback-dai-link {
+		link-name = "TDM-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_RX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+};
+
+&tlmm {
+	mi2s0_data0_sleep: mi2s0-data0-sleep {
+		pins = "gpio98";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_data1_sleep: mi2s0-data1-sleep {
+		pins = "gpio99";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_mclk_sleep: mi2s0-mclk-sleep {
+		pins = "gpio96";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_sclk_sleep: mi2s0-sclk-sleep {
+		pins = "gpio97";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_ws_sleep: mi2s0-ws-sleep {
+		pins = "gpio100";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-addons.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-addons.dtsi
@@ -0,0 +1,1982 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * qcm6490-addons device tree source
+ *
+ * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
+
+/{
+	reserved-memory {
+		audio_cma_mem: qcom,audio-ml {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x1000000>; /* 16M */
+		};
+
+		qseecom_mem: qcom,qseecom {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x1400000>; /* 20M */
+		};
+
+		qseecom_ta_mem: qcom,qseecom-ta {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x1000000>; /* 16M */
+		};
+
+		dump_mem: mem-dump-region {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			size = <0 0x2c00000>;
+		};
+	};
+
+	/* Add overlay for firmware node containing qcom_scm in sc7280.dtsi */
+	firmware {
+		qcom_mem_object {
+			compatible = "qcom,mem-object";
+		};
+
+		qcom_smcinvoke {
+			compatible = "qcom,smcinvoke";
+		};
+	};
+
+	mem-dump {
+		compatible = "qcom,mem-dump";
+		memory-region = <&dump_mem>;
+
+		c0-context {
+			qcom,dump-size = <0x800>;
+			qcom,dump-id = <0x0>;
+		};
+
+		c0-scandump {
+			qcom,dump-size = <0x10100>;
+			qcom,dump-id = <0x130>;
+		};
+
+		c100-context {
+			qcom,dump-size = <0x800>;
+			qcom,dump-id = <0x1>;
+		};
+
+		c100-scandump {
+			qcom,dump-size = <0x10100>;
+			qcom,dump-id = <0x131>;
+		};
+
+		c200-context {
+			qcom,dump-size = <0x800>;
+			qcom,dump-id = <0x2>;
+		};
+
+		c200-scandump {
+			qcom,dump-size = <0x10100>;
+			qcom,dump-id = <0x132>;
+		};
+
+		c300-context {
+			qcom,dump-size = <0x800>;
+			qcom,dump-id = <0x3>;
+		};
+
+		c300-scandump {
+			qcom,dump-size = <0x10100>;
+			qcom,dump-id = <0x133>;
+		};
+
+		c400-context {
+			qcom,dump-size = <0x800>;
+			qcom,dump-id = <0x4>;
+		};
+
+		c400-scandump {
+			qcom,dump-size = <0x40000>;
+			qcom,dump-id = <0x134>;
+		};
+
+		c500-context {
+			qcom,dump-size = <0x800>;
+			qcom,dump-id = <0x5>;
+		};
+
+		c500-scandump {
+			qcom,dump-size = <0x40000>;
+			qcom,dump-id = <0x135>;
+		};
+
+		c600-context {
+			qcom,dump-size = <0x800>;
+			qcom,dump-id = <0x6>;
+		};
+
+		c600-scandump {
+			qcom,dump-size = <0x40000>;
+			qcom,dump-id = <0x136>;
+		};
+
+		c700-context {
+			qcom,dump-size = <0x800>;
+			qcom,dump-id = <0x7>;
+		};
+
+		c700-scandump {
+			qcom,dump-size = <0x40000>;
+			qcom,dump-id = <0x137>;
+		};
+
+		cpuss-reg {
+			qcom,dump-size = <0x30000>;
+			qcom,dump-id = <0xef>;
+		};
+
+		etf-lpass {
+			qcom,dump-size = <0x4000>;
+			qcom,dump-id = <0xf4>;
+		};
+
+		etflpass-reg {
+			qcom,dump-size = <0x1000>;
+			qcom,dump-id = <0x104>;
+		};
+
+
+		etf-swao {
+			qcom,dump-size = <0x10000>;
+			qcom,dump-id = <0xf1>;
+		};
+
+		etfswao-reg {
+			qcom,dump-size = <0x1000>;
+			qcom,dump-id = <0x102>;
+		};
+
+		etr-reg {
+			qcom,dump-size = <0x1000>;
+			qcom,dump-id = <0x100>;
+		};
+
+		fcm {
+			qcom,dump-size = <0x8400>;
+			qcom,dump-id = <0xee>;
+		};
+
+		fsm-data {
+			qcom,dump-size = <0x400>;
+			qcom,dump-id = <0x165>;
+		};
+
+		gemnoc {
+			qcom,dump-size = <0x100000>;
+			qcom,dump-id = <0x162>;
+		};
+
+		l1-dcache0 {
+			qcom,dump-size = <0x9100>;
+			qcom,dump-id = <0x80>;
+		};
+
+		l1-dcache100 {
+			qcom,dump-size = <0x9100>;
+			qcom,dump-id = <0x81>;
+		};
+
+		l1-dcache200 {
+			qcom,dump-size = <0x9100>;
+			qcom,dump-id = <0x82>;
+		};
+
+		l1-dcache300 {
+			qcom,dump-size = <0x9100>;
+			qcom,dump-id = <0x83>;
+		};
+
+		l1-dcache400 {
+			qcom,dump-size = <0x9100>;
+			qcom,dump-id = <0x84>;
+		};
+
+		l1-dcache500 {
+			qcom,dump-size = <0x9100>;
+			qcom,dump-id = <0x85>;
+		};
+
+		l1-dcache600 {
+			qcom,dump-size = <0x9100>;
+			qcom,dump-id = <0x86>;
+		};
+
+		l1-dcache700 {
+			qcom,dump-size = <0x12100>;
+			qcom,dump-id = <0x87>;
+		};
+
+		l1-dtlb400 {
+			qcom,dump-size = <0x300>;
+			qcom,dump-id = <0x44>;
+		};
+
+		l1-dtlb500 {
+			qcom,dump-size = <0x300>;
+			qcom,dump-id = <0x45>;
+		};
+
+		l1-dtlb600 {
+			qcom,dump-size = <0x300>;
+			qcom,dump-id = <0x46>;
+		};
+
+		l1-dtlb700 {
+			qcom,dump-size = <0x3a0>;
+			qcom,dump-id = <0x47>;
+		};
+
+		l1-icache0 {
+			qcom,dump-size = <0x10900>;
+			qcom,dump-id = <0x60>;
+		};
+
+		l1-icache100 {
+			qcom,dump-size = <0x10900>;
+			qcom,dump-id = <0x61>;
+		};
+
+		l1-icache200 {
+			qcom,dump-size = <0x10900>;
+			qcom,dump-id = <0x62>;
+		};
+
+		l1-icache300 {
+			qcom,dump-size = <0x10900>;
+			qcom,dump-id = <0x63>;
+		};
+
+		l1-icache400 {
+			qcom,dump-size = <0x15100>;
+			qcom,dump-id = <0x64>;
+		};
+
+		l1-icache500 {
+			qcom,dump-size = <0x15100>;
+			qcom,dump-id = <0x65>;
+		};
+
+		l1-icache600 {
+			qcom,dump-size = <0x15100>;
+			qcom,dump-id = <0x66>;
+		};
+
+		l1-icache700 {
+			qcom,dump-size = <0x32100>;
+			qcom,dump-id = <0x67>;
+		};
+
+		l1-itlb400 {
+			qcom,dump-size = <0x300>;
+			qcom,dump-id = <0x24>;
+		};
+
+		l1-itlb500 {
+			qcom,dump-size = <0x300>;
+			qcom,dump-id = <0x25>;
+		};
+
+		l1-itlb600 {
+			qcom,dump-size = <0x300>;
+			qcom,dump-id = <0x26>;
+		};
+
+		l1-itlb700 {
+			qcom,dump-size = <0x400>;
+			qcom,dump-id = <0x27>;
+		};
+
+		l2-cache400 {
+			qcom,dump-size = <0x90100>;
+			qcom,dump-id = <0xc4>;
+		};
+
+		l2-cache500 {
+			qcom,dump-size = <0x90100>;
+			qcom,dump-id = <0xc5>;
+		};
+
+		l2-cache600 {
+			qcom,dump-size = <0x90100>;
+			qcom,dump-id = <0xc6>;
+		};
+
+		l2-cache700 {
+			qcom,dump-size = <0x120100>;
+			qcom,dump-id = <0xc7>;
+		};
+
+		l2-tlb0 {
+			qcom,dump-size = <0x5b00>;
+			qcom,dump-id = <0x120>;
+		};
+
+		l2-tlb100 {
+			qcom,dump-size = <0x5b00>;
+			qcom,dump-id = <0x121>;
+		};
+
+		l2-tlb200 {
+			qcom,dump-size = <0x5b00>;
+			qcom,dump-id = <0x122>;
+		};
+
+		l2-tlb300 {
+			qcom,dump-size = <0x5b00>;
+			qcom,dump-id = <0x123>;
+		};
+
+		l2-tlb400 {
+			qcom,dump-size = <0x6100>;
+			qcom,dump-id = <0x124>;
+		};
+
+		l2-tlb500 {
+			qcom,dump-size = <0x6100>;
+			qcom,dump-id = <0x125>;
+		};
+
+		l2-tlb600 {
+			qcom,dump-size = <0x6100>;
+			qcom,dump-id = <0x126>;
+		};
+
+		l2-tlb700 {
+			qcom,dump-size = <0xc100>;
+			qcom,dump-id = <0x127>;
+		};
+
+		llcc-1-dcache {
+			qcom,dump-size = <0x1141c0>;
+			qcom,dump-id = <0x140>;
+		};
+
+		llcc-2-dcache {
+			qcom,dump-size = <0x1141c0>;
+			qcom,dump-id = <0x141>;
+		};
+
+		mhm-scan {
+			qcom,dump-size = <0x20000>;
+			qcom,dump-id = <0x161>;
+		};
+
+		misc-data {
+			qcom,dump-size = <0x1000>;
+			qcom,dump-id = <0xe8>;
+		};
+
+		osm-reg {
+			qcom,dump-size = <0x400>;
+			qcom,dump-id = <0x163>;
+		};
+
+		pcu-reg {
+			qcom,dump-size = <0x400>;
+			qcom,dump-id = <0x164>;
+		};
+
+		pmic {
+			qcom,dump-size = <0x200000>;
+			qcom,dump-id = <0xe4>;
+		};
+
+		rpmh {
+			qcom,dump-size = <0x2000000>;
+			qcom,dump-id = <0xec>;
+		};
+
+		rpm-sw {
+			qcom,dump-size = <0x28000>;
+			qcom,dump-id = <0xea>;
+		};
+	};
+
+	pmic_glink: pmic-glink {
+	};
+
+	/* add overlay for smp2p nodes in sc7280.dtsi */
+	smp2p-adsp {
+		smp2p_rdbg2_out: smp2p-rdbg2-out {
+			qcom,entry-name = "rdbg";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_rdbg2_in: smp2p-rdbg2-in {
+			qcom,entry-name = "rdbg";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		sleepstate_smp2p_in: qcom,sleepstate-in {
+			qcom,entry-name = "sleepstate_see";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		sleepstate_smp2p_out: sleepstate-out {
+			qcom,entry-name = "sleepstate";
+			#qcom,smem-state-cells = <1>;
+		};
+	};
+
+	smp2p-cdsp {
+		smp2p_rdbg5_out: smp2p-rdbg5-out {
+			qcom,entry-name = "rdbg";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_rdbg5_in: smp2p-rdbg5-in {
+			qcom,entry-name = "rdbg";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	/* Gunyah expects arch_timer symbol for boot time overlay */
+	arch_timer: timer {
+	};
+
+	redriver: typec-retimer@1c {
+	};
+};
+
+/* Delete venus node properties to adapt with downstream video driver  */
+&venus {
+	/delete-property/ iommus;
+	/delete-node/ video-decoder;
+	/delete-node/ video-encoder;
+};
+
+&pm8350c {
+	pm8350c_bcl: bcl@4700 {
+		compatible = "qcom,bcl-v5";
+		reg = <0x4700 0x100>;
+		interrupts = <0x2 0x47 0x0 IRQ_TYPE_NONE>,
+				<0x2 0x47 0x1 IRQ_TYPE_NONE>,
+				<0x2 0x47 0x2 IRQ_TYPE_NONE>;
+		interrupt-names = "bcl-lvl0",
+					"bcl-lvl1",
+					"bcl-lvl2";
+		qcom,pmic7-threshold;
+		#thermal-sensor-cells = <1>;
+	};
+};
+
+&qfprom {
+	tsens_chipinfo: tsens_chipinfo@180 {
+		reg = <0x180 0x4>;
+	};
+};
+
+&remoteproc_cdsp {
+	cooling {
+		compatible = "qcom,qmi-cooling-cdsp";
+
+		cdsp_sw: cdsp_sw {
+			label = "cdsp_sw";
+			#cooling-cells = <2>;
+		};
+	};
+};
+
+&remoteproc_mpss {
+	cooling {
+		compatible = "qcom,qmi-cooling-modem";
+
+		modem_pa: modem_pa {
+			label = "pa";
+			#cooling-cells = <2>;
+		};
+
+		modem_pa_fr1: modem_pa_fr1 {
+			label = "pa_fr1";
+			#cooling-cells = <2>;
+		};
+
+		modem_skin: modem_skin {
+			label = "modem_skin";
+			#cooling-cells = <2>;
+		};
+
+		modem_pa_dsc: modem_pa_dsc {
+			label = "pa_dsc";
+			#cooling-cells = <2>;
+		};
+
+		modem_pa_fr1_dsc: modem_pa_fr1_dsc {
+			label = "pa_fr1_dsc";
+			#cooling-cells = <2>;
+		};
+
+		modem_tj: modem_tj {
+			label = "modem";
+			#cooling-cells = <2>;
+		};
+
+		modem_skin_lte_dsc: modem_skin_lte_dsc {
+			label = "modem_skin_lte_dsc";
+			#cooling-cells = <2>;
+		};
+
+		modem_skin_nr_dsc: modem_skin_nr_dsc {
+			label = "modem_skin_nr_dsc";
+			#cooling-cells = <2>;
+		};
+	};
+};
+
+&soc {
+	audio-etm0 {
+		compatible = "qcom,coresight-remote-etm";
+
+		qcom,inst-id = <5>;
+		device-name = "audio_etm0";
+
+		out-ports {
+			port {
+				audio_etm0_out_funnel_lpass_lpi: endpoint {
+					remote-endpoint =
+					<&funnel_lpass_lpi_in_audio_etm0>;
+				};
+			};
+		};
+	};
+
+	funnel@6042000 {
+		in-ports {
+			port@5 {
+				reg = <5>;
+				funnel_in1_in_funnel_modem: endpoint {
+					remote-endpoint =
+					<&funnel_modem_out_funnel_in1>;
+				};
+			};
+		};
+	};
+
+	funnel@6804000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+
+		reg = <0x0 0x06804000 0x0 0x1000>;
+		reg-names = "funnel-base";
+
+		coresight-name = "coresight-funnel-modem";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		out-ports {
+			port {
+				funnel_modem_out_funnel_in1: endpoint {
+					remote-endpoint =
+						<&funnel_in1_in_funnel_modem>;
+				};
+			};
+		};
+
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@1 {
+				reg = <1>;
+				funnel_modem_in_modem2_etm0: endpoint {
+					remote-endpoint =
+						<&modem2_etm0_out_funnel_modem>;
+				};
+			};
+
+			port@3 {
+				reg = <3>;
+				funnel_modem_in_funnel_mq6_dup: endpoint {
+					remote-endpoint =
+					  <&funnel_mq6_dup_out_funnel_modem>;
+				};
+			};
+		};
+	};
+
+	funnel@680c000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+
+		reg = <0x0 0x0680c000 0x0 0x1000>;
+		reg-names = "funnel-base";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		out-ports {
+			port {
+				funnel_modem_q6_out_funnel_mq6_dup: endpoint {
+					remote-endpoint =
+					<&funnel_mq6_dup_in_funnel_modem_q6>;
+				};
+			};
+		};
+
+		in-ports {
+			port {
+				funnel_modem_q6_in_modem_etm0: endpoint {
+					remote-endpoint =
+					<&modem_etm0_out_funnel_modem_q6>;
+				};
+			};
+		};
+	};
+
+	funnel@680d000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+		arm,primecell-periphid = <0x000bb908>;
+
+		reg = <0x0 0x0680d000 0x0 0x1000>,
+			<0x0 0x0680c000 0x0 0x1000>;
+
+		reg-names = "funnel-base-dummy", "funnel-base-real";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+		qcom,duplicate-funnel;
+
+		out-ports {
+			port {
+				funnel_mq6_dup_out_funnel_modem: endpoint {
+					remote-endpoint =
+					<&funnel_modem_in_funnel_mq6_dup>;
+				};
+			};
+		};
+
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@1 {
+				reg = <1>;
+				funnel_mq6_dup_in_funnel_modem_q6: endpoint {
+					remote-endpoint =
+					<&funnel_modem_q6_out_funnel_mq6_dup>;
+				};
+			};
+
+			port@2 {
+				reg = <2>;
+				funnel_mq6_dup_in_modem_diag: endpoint {
+					remote-endpoint =
+					<&modem_diag_out_funnel_mq6_dup>;
+				};
+			};
+		};
+	};
+
+	funnel@6985000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+
+		reg = <0x0 0x06985000 0x0 0x1000>;
+		reg-names = "funnel-base";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		out-ports {
+			port {
+				funnel_dl_turing_out_funnel_dlct5: endpoint {
+					remote-endpoint =
+						<&funnel_dlct5_in_funnel_dl_turing>;
+				};
+			};
+		};
+
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@4 {
+				reg = <4>;
+				turing_in_turing_dup: endpoint {
+					remote-endpoint =
+					  <&turing_dup_out_turing>;
+				};
+			};
+		};
+	};
+
+	funnel@6986000 {
+		compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+		arm,primecell-periphid = <0x000bb908>;
+
+		reg = <0x0 0x06986000 0x0 0x1000>,
+			<0x0 0x06985000 0x0 0x1000>;
+		reg-names = "funnel-base-dummy", "funnel-base-real";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+		qcom,duplicate-funnel;
+
+		out-ports {
+			port {
+				turing_dup_out_turing: endpoint {
+					remote-endpoint =
+					<&turing_in_turing_dup>;
+				};
+			};
+		};
+
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@3 {
+				reg = <3>;
+				funnel_dup_turing_in_turing_etm: endpoint {
+					remote-endpoint =
+					<&turing_etm_out_funnel_dup_turing>;
+				};
+			};
+		};
+	};
+
+	funnel@6b04000 {
+		in-ports {
+			port@5 {
+				reg = <5>;
+				funnel_swao_in_funnel_lpass_lpi: endpoint {
+					remote-endpoint =
+					<&funnel_lpass_lpi_out_funnel_swao>;
+				};
+			};
+		};
+	};
+
+	tgu@6b0e000 {
+		compatible = "arm,primecell", "qcom,coresight-tgu";
+		arm,primecell-periphid = <0x000bb999>;
+		reg = <0x0 0x06b0e000 0x0 0x1000>;
+		device-name = "tgu_ipcb";
+
+		tgu-steps = <3>;
+		tgu-conditions = <4>;
+		tgu-regs = <4>;
+		tgu-timer-counters = <8>;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+	};
+
+	swao_csr: csr@6b0f000 {
+		compatible = "qcom,coresight-csr";
+		reg = <0x0 0x06b0f000 0x0 0x1000>,
+		      <0x0 0x06b0f0f8 0x0 0x50>;
+		reg-names = "csr-base", "msr-base";
+
+		device-name = "swao_csr";
+		qcom,timestamp-support;
+		qcom,msr-support;
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		qcom,blk-size = <1>;
+	};
+
+	funnel@6b44000 {
+		compatible = "arm,coresight-static-funnel";
+		coresight-name = "coresight-funnel-lpass_lpi";
+
+		out-ports {
+			port {
+				funnel_lpass_lpi_out_funnel_swao: endpoint {
+					remote-endpoint =
+					<&funnel_swao_in_funnel_lpass_lpi>;
+				};
+			};
+		};
+
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				funnel_lpass_lpi_in_audio_etm0: endpoint {
+					remote-endpoint =
+					<&audio_etm0_out_funnel_lpass_lpi>;
+				};
+			};
+		};
+	};
+
+	funnel@6c38000 {
+		in-ports {
+			port@6 {
+				reg = <6>;
+				funnel_dlct5_in_funnel_dl_turing: endpoint {
+					remote-endpoint =
+					<&funnel_dl_turing_out_funnel_dlct5>;
+				};
+			};
+		};
+	};
+
+	funnel@6c73000 {
+		in-ports {
+			port@2 {
+				reg = <2>;
+				funnel_wpss_in_wpss_etm0: endpoint {
+					remote-endpoint =
+						<&wpss_etm0_out_funnel_wpss>;
+				};
+			};
+		};
+	};
+
+	modem-etm0 {
+		compatible = "qcom,coresight-remote-etm";
+
+		device-name = "modem_etm0";
+		qcom,inst-id = <2>;
+
+		out-ports {
+			port {
+				modem_etm0_out_funnel_modem_q6: endpoint {
+					remote-endpoint =
+						<&funnel_modem_q6_in_modem_etm0>;
+				};
+			};
+		};
+	};
+
+	modem2-etm0 {
+		compatible = "qcom,coresight-remote-etm";
+
+		device-name = "modem2_etm0";
+		qcom,inst-id = <11>;
+
+		out-ports {
+			port {
+				modem2_etm0_out_funnel_modem: endpoint {
+					remote-endpoint =
+						<&funnel_modem_in_modem2_etm0>;
+				};
+			};
+		};
+	};
+
+	msm_gpu: qcom,kgsl-3d0@3d00000 {
+		#cooling-cells = <2>;
+	};
+
+	msm_stub_codec: msm-stub-codec {
+		compatible = "qcom,msm-stub-codec";
+		#sound-dai-cells = <1>;
+	};
+
+	qcom,devfreq-cdev {
+		compatible = "qcom,devfreq-cdev";
+		qcom,devfreq = <&msm_gpu>;
+		#cooling-cells = <2>;
+	};
+
+	/* smp2p information */
+	qcom-smp2p-interrupt-rdbg-2-in {
+		compatible = "qcom,smp2p-interrupt-rdbg-2-in";
+		interrupts-extended = <&smp2p_rdbg2_in 0 IRQ_TYPE_NONE>;
+		interrupt-names = "rdbg-smp2p-in";
+	};
+
+	qcom-smp2p-interrupt-rdbg-2-out {
+		compatible = "qcom,smp2p-interrupt-rdbg-2-out";
+		qcom,smem-states = <&smp2p_rdbg2_out 0>;
+		qcom,smem-state-names = "rdbg-smp2p-out";
+	};
+
+	qcom-smp2p-interrupt-rdbg-5-in {
+		compatible = "qcom,smp2p-interrupt-rdbg-5-in";
+		interrupts-extended = <&smp2p_rdbg5_in 0 IRQ_TYPE_NONE>;
+		interrupt-names = "rdbg-smp2p-in";
+	};
+
+	qcom-smp2p-interrupt-rdbg-5-out {
+		compatible = "qcom,smp2p-interrupt-rdbg-5-out";
+		qcom,smem-states = <&smp2p_rdbg5_out 0>;
+		qcom,smem-state-names = "rdbg-smp2p-out";
+	};
+
+	qcom,smp2p_sleepstate {
+		compatible = "qcom,smp2p-sleepstate";
+		qcom,smem-states = <&sleepstate_smp2p_out 0>;
+		interrupt-parent = <&sleepstate_smp2p_in>;
+		interrupts = <0 0>;
+		interrupt-names = "smp2p-sleepstate-in";
+	};
+
+	spf_core_platform: spf-core-platform {
+		compatible = "qcom,spf-core-platform";
+
+		msm_audio_mem: msm-audio-mem {
+			compatible = "qcom,msm-audio-mem";
+			qcom,smmu-version = <2>;
+			qcom,smmu-enabled;
+			iommus = <&apps_smmu 0x1801 0x0>;
+			qcom,iommu-dma-addr-pool = <0x10000000 0x10000000>;
+			qcom,smmu-sid-mask = /bits/ 64 <0xf>;
+			dma-coherent;
+		};
+
+		msm_audio_mem_cma: msm-audio-mem-cma {
+			compatible = "qcom,msm-audio-mem";
+			memory-region = <&audio_cma_mem>;
+		};
+	};
+
+	source {
+		compatible = "arm,coresight-dummy-source";
+
+		device-name = "modem_diag";
+
+		arm,trace-id = <50>;
+		out-ports {
+			port {
+				modem_diag_out_funnel_mq6_dup: endpoint {
+					remote-endpoint =
+						<&funnel_mq6_dup_in_modem_diag>;
+				};
+			};
+		};
+	};
+
+	turing-etm0 {
+		compatible = "qcom,coresight-remote-etm";
+
+		device-name = "turing_etm0";
+		qcom,inst-id = <13>;
+
+		out-ports {
+			port {
+				turing_etm_out_funnel_dup_turing: endpoint {
+					remote-endpoint =
+					<&funnel_dup_turing_in_turing_etm>;
+				};
+			};
+		};
+	};
+
+	wpss-etm0 {
+		compatible = "qcom,coresight-remote-etm";
+
+		device-name = "wpss_etm0";
+		qcom,inst-id = <3>;
+
+		out-ports {
+			port {
+				wpss_etm0_out_funnel_wpss: endpoint {
+					remote-endpoint =
+					<&funnel_wpss_in_wpss_etm0>;
+				};
+			};
+		};
+	};
+
+	sram@146a5000{
+		kaslr_offset@56d0 {
+			compatible = "qcom,msm-imem-kaslr_offset";
+			reg = <0x56d0 0xc>;
+		};
+
+		mem-dump-table@5010 {
+			compatible = "qcom,msm-imem-mem-dump-table";
+			reg = <0x5010 0x8>;
+		};
+	};
+
+	qcom_tzlog: tz-log@146aa720 {
+		compatible = "qcom,tz-log";
+		reg = <0x0 0x146aa720 0x0 0x3000>;
+		qcom,hyplog-enabled;
+		hyplog-address-offset = <0x410>;
+		hyplog-size-offset = <0x414>;
+	};
+
+	qcom,mem-buf {
+		compatible = "qcom,mem-buf";
+		qcom,mem-buf-capabilities = "supplier";
+		qcom,vmid = <3>;
+	};
+
+	qcom,mem-buf-msgq {
+		compatible = "qcom,mem-buf-msgq";
+	};
+
+	qcom,secure-buffer {
+		compatible = "qcom,secure-buffer";
+		qcom,vmid-cp-camera-preview-ro;
+	};
+
+	csr: csr@6001000 {
+		compatible = "qcom,coresight-csr";
+		reg = <0x0 0x06001000 0x0 0x1000>;
+		reg-names = "csr-base";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		device-name = "csr";
+		qcom,set-byte-cntr-support;
+
+		qcom,blk-size = <1>;
+	};
+
+	etr@6048000 {
+		qcom,sw-usb;
+		coresight-csr = <&csr>;
+		interrupts = <GIC_SPI 270 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "byte-cntr-irq";
+	};
+};
+
+&thermal_zones {
+	aoss0-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			aoss0-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+	};
+
+	aoss1-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+
+			aoss1-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+	};
+
+	camera0-thermal {
+		polling-delay-passive = <100>;
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			camera0_alert1: trip-point1 {
+				temperature = <100000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			camera0-crit {
+				temperature = <118000>;
+				hysteresis = <0>;
+			};
+		};
+
+		cooling-maps {
+			//map0 {
+			//	trip = <&camera0_alert1>;
+			//	cooling-device = <&cdsp_sw 4 4>;
+			//};
+
+			map1 {
+				trip = <&camera0_alert1>;
+				cooling-device = <&modem_pa 3 3>;
+			};
+
+			map2 {
+				trip = <&camera0_alert1>;
+				cooling-device = <&msm_gpu 5 5>;
+			};
+		};
+	};
+
+	cpu0-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+			};
+
+			trip-point1 {
+				temperature = <110000>;
+				hysteresis = <5000>;
+			};
+
+			cpu-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		/delete-node/ cooling-maps;
+		cooling-maps {
+			map0 {
+				trip = <&cpu0_alert1>;
+				cooling-device = <&CPU0_idle 100 100>;
+			};
+		};
+	};
+
+	cpu1-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+			};
+
+			trip-point1 {
+				temperature = <110000>;
+				hysteresis = <5000>;
+			};
+
+			cpu-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		/delete-node/ cooling-maps;
+		cooling-maps {
+			map0 {
+				trip = <&cpu1_alert1>;
+				cooling-device = <&CPU1_idle 100 100>;
+			};
+		};
+	};
+
+	cpu2-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+			};
+
+			trip-point1 {
+				temperature = <110000>;
+				hysteresis = <5000>;
+			};
+
+			cpu-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		/delete-node/ cooling-maps;
+		cooling-maps {
+			map0 {
+				trip = <&cpu2_alert1>;
+				cooling-device = <&CPU2_idle 100 100>;
+			};
+		};
+	};
+
+	cpu3-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+			};
+
+			trip-point1 {
+				temperature = <110000>;
+				hysteresis = <5000>;
+			};
+
+			cpu-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		/delete-node/ cooling-maps;
+		cooling-maps {
+			map0 {
+				trip = <&cpu3_alert1>;
+				cooling-device = <&CPU3_idle 100 100>;
+			};
+		};
+	};
+
+	cpu4-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+			};
+
+			trip-point1 {
+				temperature = <110000>;
+				hysteresis = <5000>;
+			};
+
+			cpu-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		/delete-node/ cooling-maps;
+		cooling-maps {
+			map0 {
+				trip = <&cpu4_alert1>;
+				cooling-device = <&CPU4_idle 100 100>;
+			};
+		};
+	};
+
+	cpu5-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+			};
+
+			trip-point1 {
+				temperature = <110000>;
+				hysteresis = <5000>;
+			};
+
+			cpu-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		/delete-node/ cooling-maps;
+		cooling-maps {
+			map0 {
+				trip = <&cpu5_alert1>;
+				cooling-device = <&CPU4_idle 100 100>;
+			};
+		};
+	};
+
+	cpu6-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+			};
+
+			trip-point1 {
+				temperature = <110000>;
+				hysteresis = <5000>;
+			};
+
+			cpu-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		/delete-node/ cooling-maps;
+		cooling-maps {
+			map0 {
+				trip = <&cpu6_alert1>;
+				cooling-device = <&CPU5_idle 100 100>;
+			};
+		};
+	};
+
+	cpu7-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+			};
+
+			trip-point1 {
+				temperature = <110000>;
+				hysteresis = <5000>;
+			};
+
+			cpu-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		/delete-node/ cooling-maps;
+		cooling-maps {
+			map0 {
+				trip = <&cpu7_alert1>;
+				cooling-device = <&CPU5_idle 100 100>;
+			};
+		};
+	};
+
+	cpu8-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+			};
+
+			trip-point1 {
+				temperature = <110000>;
+				hysteresis = <5000>;
+			};
+
+			cpu-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		/delete-node/ cooling-maps;
+		cooling-maps {
+			map0 {
+				trip = <&cpu8_alert1>;
+				cooling-device = <&CPU6_idle 100 100>;
+			};
+		};
+	};
+
+	cpu9-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+			};
+
+			trip-point1 {
+				temperature = <110000>;
+				hysteresis = <5000>;
+			};
+
+			cpu-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		/delete-node/ cooling-maps;
+		cooling-maps {
+			map0 {
+				trip = <&cpu9_alert1>;
+				cooling-device = <&CPU6_idle 100 100>;
+			};
+		};
+	};
+
+	cpu10-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+			};
+
+			trip-point1 {
+				temperature = <110000>;
+				hysteresis = <5000>;
+			};
+
+			cpu-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		/delete-node/ cooling-maps;
+		cooling-maps {
+			map0 {
+				trip = <&cpu10_alert1>;
+				cooling-device = <&CPU7_idle 100 100>;
+			};
+		};
+	};
+
+	cpu11-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+			};
+
+			trip-point1 {
+				temperature = <110000>;
+				hysteresis = <5000>;
+			};
+
+			cpu-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		/delete-node/ cooling-maps;
+		cooling-maps {
+			map0 {
+				trip = <&cpu11_alert1>;
+				cooling-device = <&CPU7_idle 100 100>;
+			};
+		};
+	};
+
+	cpuss0-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			cluster0-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+	};
+
+	cpuss1-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+				type = "hot";
+			};
+
+			cluster0-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+	};
+
+	ddr-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			ddr-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+	};
+
+	gpuss0-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <2000>;
+				type = "passive";
+			};
+
+			gpuss0_alert1: trip-point1 {
+				temperature = <95000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			gpuss0-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+				type = "critical";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&gpuss0_alert1>;
+				cooling-device = <&msm_gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+
+			};
+		};
+	};
+
+	gpuss1-thermal {
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			gpuss1_alert1: trip-point1 {
+				temperature = <95000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			gpuss1-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&gpuss1_alert1>;
+				cooling-device = <&msm_gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	mdmss0-thermal {
+		polling-delay-passive = <100>;
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			mdmss0_alert1: trip-point1 {
+				temperature = <95000>;
+				hysteresis = <15000>;
+				type = "passive";
+			};
+
+			mdmss0_alert2: trip-point2 {
+				temperature = <105000>;
+				hysteresis = <15000>;
+				type = "passive";
+			};
+
+			mdmss0_alert3: trip-point3 {
+				temperature = <115000>;
+				hysteresis = <15000>;
+				type = "passive";
+			};
+
+			mdmss0-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&mdmss0_alert1>;
+				cooling-device = <&modem_tj 1 1>;
+			};
+
+			map1 {
+				trip = <&mdmss0_alert2>;
+				cooling-device = <&modem_tj 2 2>;
+			};
+
+			map2 {
+				trip = <&mdmss0_alert3>;
+				cooling-device = <&modem_tj 3 3>;
+			};
+		};
+	};
+
+	mdmss1-thermal {
+		polling-delay-passive = <100>;
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			mdmss1_alert1: trip-point1 {
+				temperature = <95000>;
+				hysteresis = <15000>;
+				type = "passive";
+			};
+
+			mdmss1_alert2: trip-point2 {
+				temperature = <105000>;
+				hysteresis = <15000>;
+				type = "passive";
+			};
+
+			mdmss1_alert3: trip-point3 {
+				temperature = <115000>;
+				hysteresis = <15000>;
+				type = "passive";
+			};
+
+			mdmss1-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&mdmss1_alert1>;
+				cooling-device = <&modem_tj 1 1>;
+			};
+
+			map1 {
+				trip = <&mdmss1_alert2>;
+				cooling-device = <&modem_tj 2 2>;
+			};
+
+			map2 {
+				trip = <&mdmss1_alert3>;
+				cooling-device = <&modem_tj 3 3>;
+			};
+		};
+	};
+
+	mdmss2-thermal {
+		polling-delay-passive = <100>;
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			mdmss2_alert1: trip-point1 {
+				temperature = <95000>;
+				hysteresis = <15000>;
+				type = "passive";
+			};
+
+			mdmss2_alert2: trip-point2 {
+				temperature = <105000>;
+				hysteresis = <15000>;
+				type = "passive";
+			};
+
+			mdmss2_alert3: trip-point3 {
+				temperature = <115000>;
+				hysteresis = <15000>;
+				type = "passive";
+			};
+
+			mdmss2-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&mdmss2_alert1>;
+				cooling-device = <&modem_tj 1 1>;
+			};
+
+			map1 {
+				trip = <&mdmss2_alert2>;
+				cooling-device = <&modem_tj 2 2>;
+			};
+
+			map2 {
+				trip = <&mdmss2_alert3>;
+				cooling-device = <&modem_tj 3 3>;
+			};
+		};
+	};
+
+	mdmss3-thermal {
+		polling-delay-passive = <100>;
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			mdmss3_alert1: trip-point1 {
+				temperature = <95000>;
+				hysteresis = <15000>;
+				type = "passive";
+			};
+
+			mdmss3_alert2: trip-point2 {
+				temperature = <105000>;
+				hysteresis = <15000>;
+				type = "passive";
+			};
+
+			mdmss3_alert3: trip-point3 {
+				temperature = <115000>;
+				hysteresis = <15000>;
+				type = "passive";
+			};
+
+			mdmss3-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&mdmss3_alert1>;
+				cooling-device = <&modem_tj 1 1>;
+			};
+
+			map1 {
+				trip = <&mdmss3_alert2>;
+				cooling-device = <&modem_tj 2 2>;
+			};
+
+			map2 {
+				trip = <&mdmss3_alert3>;
+				cooling-device = <&modem_tj 3 3>;
+			};
+		};
+	};
+
+	nspss0-thermal {
+		polling-delay-passive = <100>;
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			nspss0_alert1: trip-point1 {
+				temperature = <100000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			nspss0-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		cooling-maps {
+			//map0 {
+			//	trip = <&nspss0_alert1>;
+			//	cooling-device = <&cdsp_sw 4 4>;
+			//};
+
+			map1 {
+				trip = <&nspss0_alert1>;
+				cooling-device = <&modem_pa 3 3>;
+			};
+
+			map2 {
+				trip = <&nspss0_alert1>;
+				cooling-device = <&msm_gpu 5 5>;
+			};
+		};
+	};
+
+	nspss1-thermal {
+		polling-delay-passive = <100>;
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			nspss1_alert1: trip-point1 {
+				temperature = <100000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			nspss1-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		cooling-maps {
+			//map0 {
+			//	trip = <&nspss1_alert1>;
+			//	cooling-device = <&cdsp_sw 4 4>;
+			//};
+
+			map1 {
+				trip = <&nspss1_alert1>;
+				cooling-device = <&modem_pa 3 3>;
+			};
+
+			map2 {
+				trip = <&nspss1_alert1>;
+				cooling-device = <&msm_gpu 5 5>;
+			};
+		};
+	};
+
+	pm8350c-bcl-lvl0 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm8350c_bcl 5>;
+
+		trips {
+			c_bcl_lvl0: c-bcl-lvl0 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&c_bcl_lvl0>;
+				cooling-device = <&CPU4_idle 100 100>;
+			};
+
+			map1 {
+				trip = <&c_bcl_lvl0>;
+				cooling-device = <&CPU5_idle 100 100>;
+			};
+
+			map2 {
+				trip = <&c_bcl_lvl0>;
+				cooling-device = <&CPU6_idle 100 100>;
+			};
+
+			map3 {
+				trip = <&c_bcl_lvl0>;
+				cooling-device = <&CPU7_idle 100 100>;
+			};
+
+			map4 {
+				trip = <&c_bcl_lvl0>;
+				cooling-device = <&cdsp_sw 2 2>;
+			};
+
+			map5 {
+				trip = <&c_bcl_lvl0>;
+				cooling-device = <&modem_pa 2 2>;
+			};
+
+			map6 {
+				trip = <&c_bcl_lvl0>;
+				cooling-device = <&modem_tj 1 1>;
+			};
+		};
+	};
+
+	pm8350c-bcl-lvl1 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm8350c_bcl 6>;
+
+		trips {
+			c_bcl_lvl1: c-bcl-lvl1 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&c_bcl_lvl1>;
+				cooling-device = <&msm_gpu 5 THERMAL_NO_LIMIT>;
+			};
+
+			//map1 {
+			//	trip = <&c_bcl_lvl1>;
+			//	cooling-device = <&cdsp_sw 4 4>;
+			//};
+
+			map2 {
+				trip = <&c_bcl_lvl1>;
+				cooling-device = <&modem_tj 3 3>;
+			};
+		};
+	};
+
+	pm8350c-bcl-lvl2 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm8350c_bcl 7>;
+
+		trips {
+			c_bcl_lvl2: c-bcl-lvl2 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			//map0 {
+			//	trip = <&c_bcl_lvl2>;
+			//	cooling-device = <&cdsp_sw 5 5>;
+			//};
+		};
+	};
+
+	video-thermal {
+		polling-delay-passive = <100>;
+		trips {
+			trip-point0 {
+				temperature = <125000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			video_alert1: trip-point1 {
+				temperature = <100000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+
+			video-crit {
+				temperature = <118000>;
+				hysteresis = <2000>;
+			};
+		};
+
+		cooling-maps {
+			//map0 {
+			//	trip = <&video_alert1>;
+			//	cooling-device = <&cdsp_sw 4 4>;
+			//};
+
+			map1 {
+				trip = <&video_alert1>;
+				cooling-device = <&modem_pa 3 3>;
+			};
+
+			map2 {
+				trip = <&video_alert1>;
+				cooling-device = <&msm_gpu 5 5>;
+			};
+		};
+	};
+};
+
+&tsens0 {
+	nvmem-cells = <&tsens_chipinfo>;
+	nvmem-cell-names = "tsens_chipinfo";
+};
+
+&tsens1 {
+	nvmem-cells = <&tsens_chipinfo>;
+	nvmem-cell-names = "tsens_chipinfo";
+};
+
+#include "qcm6490-dma-heaps.dtsi"
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-camera-idp.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-camera-idp.dtso
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sc7280.h>
+#include <dt-bindings/clock/qcom,camcc-sc7280.h>
+#include <dt-bindings/interconnect/qcom,sc7280.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+
+#include "qcm6490-camera.dtsi"
+#include "qcm6490-camera-sensor-idp.dtsi"
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-camera-rb3.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-camera-rb3.dtsi
@@ -0,0 +1,2520 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <dt-bindings/msm-camera.h>
+
+&tlmm {
+	cci0_active: cci0_active {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio69","gpio70"; // Only 2
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio69","gpio70";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci0_suspend: cci0_suspend {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio69","gpio70";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio69","gpio70";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci1_active: cci1_active {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio71","gpio72";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio71","gpio72";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci1_suspend: cci1_suspend {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio71","gpio72";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio71","gpio72";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci2_active: cci2_active {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio73","gpio74";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio73","gpio74";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci2_suspend: cci2_suspend {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio73","gpio74";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio73","gpio74";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci3_active: cci3_active {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio75","gpio76";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio75","gpio76";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci3_suspend: cci3_suspend {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio75","gpio76";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio75","gpio76";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+
+	};
+
+	cam_sensor_mclk0_active: cam_sensor_mclk0_active {
+		/* MCLK0 */
+		mux {
+			pins = "gpio64";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio64";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk0_suspend: cam_sensor_mclk0_suspend {
+		/* MCLK0 */
+		mux {
+			pins = "gpio64";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio64";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk1_active: cam_sensor_mclk1_active {
+		/* MCLK1 */
+		mux {
+			pins = "gpio65";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio65";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk1_suspend: cam_sensor_mclk1_suspend {
+		/* MCLK1 */
+		mux {
+			pins = "gpio65";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio65";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk2_active: cam_sensor_mclk2_active {
+		/* MCLK2 */
+		mux {
+			pins = "gpio66";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio66";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk2_suspend: cam_sensor_mclk2_suspend {
+		/* MCLK2 */
+		mux {
+			pins = "gpio66";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio66";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk3_active: cam_sensor_mclk3_active {
+		/* MCLK3 */
+		mux {
+			pins = "gpio67";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio67";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk3_suspend: cam_sensor_mclk3_suspend {
+		/* MCLK3 */
+		mux {
+			pins = "gpio67";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio67";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk4_active: cam_sensor_mclk4_active {
+		/* MCLK4 */
+		mux {
+			pins = "gpio68";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio68";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk4_suspend: cam_sensor_mclk4_suspend {
+		/* MCLK4 */
+		mux {
+			pins = "gpio68";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio68";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk5_active: cam_sensor_mclk5_active {
+		/* MCLK5 */
+		mux {
+			pins = "gpio98";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio98";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk5_suspend: cam_sensor_mclk5_suspend {
+		/* MCLK5 */
+		mux {
+			pins = "gpio98";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio98";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_active_rst0: cam_sensor_active_rst0 {
+		/* RESET REAR */
+		mux {
+			pins = "gpio20";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio20";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst0: cam_sensor_suspend_rst0 {
+		/* RESET REAR */
+		mux {
+			pins = "gpio20";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio20";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_rst1: cam_sensor_active_rst1 {
+		/* RESET REARAUX */
+		mux {
+			pins = "gpio21";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio21";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst1: cam_sensor_suspend_rst1 {
+		/* RESET REARAUX */
+		mux {
+			pins = "gpio21";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio21";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_rst2: cam_sensor_active_rst2 {
+		/* RESET 2 */
+		mux {
+			pins = "gpio77";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio77";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst2: cam_sensor_suspend_rst2 {
+		/* RESET 2 */
+		mux {
+			pins = "gpio77";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio77";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_rst3: cam_sensor_active_rst3 {
+		/* RESET 3 */
+		mux {
+			pins = "gpio78";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio78";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst3: cam_sensor_suspend_rst3 {
+		/* RESET 3 */
+		mux {
+			pins = "gpio78";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio78";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_rst4: cam_sensor_active_rst4 {
+		/* RESET 4 */
+		mux {
+			pins = "gpio79";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio79";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst4: cam_sensor_suspend_rst4 {
+		/* RESET 4 */
+		mux {
+			pins = "gpio79";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio79";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_mux: cam_sensor_active_mux {
+		/* GC630 bypass mux */
+		mux {
+			pins = "gpio1";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio1";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_mux: cam_sensor_suspend_mux {
+		/* GC630 bypass mux */
+		mux {
+			pins = "gpio1";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio1";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+};
+
+&soc {
+	qcom,cam-req-mgr {
+		compatible = "qcom,cam-req-mgr";
+		status = "ok";
+	};
+
+	qcom,cam-sync {
+		compatible = "qcom,cam-sync";
+		status = "ok";
+	};
+
+	cam_csiphy0: qcom,csiphy0 {
+		cell-index = <0>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0x0ace0000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe0000>;
+		interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy0";
+		operating-points-v2 = <&csiphy0_opp_table>;
+		refgen-supply = <&refgen>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY0_CLK>,
+			<&camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI0PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy0_clk",
+			"csi0phytimer_clk_src",
+			"csi0phytimer_clk";
+		src-clock-name = "csi0phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_csiphy1: qcom,csiphy1 {
+		cell-index = <1>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0xace2000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe2000>;
+		interrupts = <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy1";
+		operating-points-v2 = <&csiphy1_opp_table>;
+		refgen-supply = <&refgen>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY1_CLK>,
+			<&camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI1PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy1_clk",
+			"csi1phytimer_clk_src",
+			"csi1phytimer_clk";
+		src-clock-name = "csi1phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_csiphy2: qcom,csiphy2 {
+		cell-index = <2>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0xace4000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe4000>;
+		interrupts = <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy2";
+		refgen-supply = <&refgen>;
+		operating-points-v2 = <&csiphy2_opp_table>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY2_CLK>,
+			<&camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI2PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy2_clk",
+			"csi2phytimer_clk_src",
+			"csi2phytimer_clk";
+		src-clock-name = "csi2phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_csiphy3: qcom,csiphy3 {
+		cell-index = <3>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0xace6000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe6000>;
+		interrupts = <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy3";
+		refgen-supply = <&refgen>;
+		operating-points-v2 = <&csiphy3_opp_table>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY3_CLK>,
+			<&camcc CAM_CC_CSI3PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI3PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy3_clk",
+			"csi3phytimer_clk_src",
+			"csi3phytimer_clk";
+		src-clock-name = "csi3phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_csiphy4: qcom,csiphy4 {
+		cell-index = <4>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0xace8000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe8000>;
+		interrupts = <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy4";
+		refgen-supply = <&refgen>;
+		operating-points-v2 = <&csiphy4_opp_table>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY4_CLK>,
+			<&camcc CAM_CC_CSI4PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI4PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy4_clk",
+			"csi4phytimer_clk_src",
+			"csi4phytimer_clk";
+		src-clock-name = "csi4phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy4_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_cci0: qcom,cci0 {
+		cell-index = <0>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac4a000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x4a000>;
+		interrupt-names = "cci";
+		interrupts = <GIC_SPI 460 IRQ_TYPE_EDGE_RISING>;
+		status = "ok";
+		operating-points-v2 = <&cci0_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clocks = <&camcc CAM_CC_CCI_0_CLK_SRC>,
+			<&camcc CAM_CC_CCI_0_CLK>;
+		clock-names = "cci_0_clk_src",
+			"cci_0_clk";
+		src-clock-name = "cci_0_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates = <37500000 0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cci0_active &cci1_active>;
+		pinctrl-1 = <&cci0_suspend &cci1_suspend>;
+		gpios = <&tlmm 69 0>,
+			<&tlmm 70 0>,
+			<&tlmm 71 0>,
+			<&tlmm 72 0>;
+		gpio-req-tbl-num = <0 1 2 3>;
+		gpio-req-tbl-flags = <1 1 1 1>;
+		gpio-req-tbl-label = "CCI_I2C_DATA0",
+					"CCI_I2C_CLK0",
+					"CCI_I2C_DATA1",
+					"CCI_I2C_CLK1";
+		cci0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci0: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci0: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci0: qcom,i2c_custom_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci0: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	cam_cci1: qcom,cci1 {
+		cell-index = <1>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac4b000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x4b000>;
+		interrupt-names = "cci";
+		interrupts = <GIC_SPI 271 IRQ_TYPE_EDGE_RISING>;
+		status = "ok";
+		operating-points-v2 = <&cci1_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clocks = <&camcc CAM_CC_CCI_1_CLK_SRC>,
+			<&camcc CAM_CC_CCI_1_CLK>;
+		clock-names = "cci_1_clk_src",
+			"cci_1_clk";
+		src-clock-name = "cci_1_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates = <37500000 0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cci2_active &cci3_active>;
+		pinctrl-1 = <&cci2_suspend &cci3_suspend>;
+		gpios = <&tlmm 73 0>,
+			<&tlmm 74 0>,
+			<&tlmm 75 0>,
+			<&tlmm 76 0>;
+		gpio-req-tbl-num = <0 1 2 3>;
+		gpio-req-tbl-flags = <1 1 1 1>;
+		gpio-req-tbl-label = "CCI_I2C_DATA2",
+					"CCI_I2C_CLK2",
+					"CCI_I2C_DATA3",
+					"CCI_I2C_CLK3";
+		cci1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci1: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci1: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci1: qcom,i2c_custom_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci1: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	qcom,cam_smmu {
+		compatible = "qcom,msm-cam-smmu", "simple-bus";
+		status = "ok";
+		force_cache_allocs;
+
+		msm_cam_smmu_ife {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x800 0x4E0>,
+				<&apps_smmu 0x820 0x4E0>,
+				<&apps_smmu 0x840 0x4E0>,
+				<&apps_smmu 0x860 0x4E0>,
+				<&apps_smmu 0x880 0x4E0>,
+				<&apps_smmu 0x8A0 0x4E0>,
+				<&apps_smmu 0x8C0 0x4E0>,
+				<&apps_smmu 0x8E0 0x4E0>,
+				<&apps_smmu 0xC00 0x4E0>,
+				<&apps_smmu 0xC20 0x4E0>,
+				<&apps_smmu 0xC40 0x4E0>,
+				<&apps_smmu 0xC60 0x4E0>,
+				<&apps_smmu 0xC80 0x4E0>,
+				<&apps_smmu 0xCA0 0x4E0>,
+				<&apps_smmu 0xCC0 0x4E0>,
+				<&apps_smmu 0xCE0 0x4E0>;
+			cam-smmu-label = "ife";
+			multiple-client-devices;
+			dma-coherent;
+			ife_iova_mem_map: iova-mem-map {
+				/* IO region is approximately 4 GB */
+				iova-mem-region-io {
+					iova-region-name = "io";
+					iova-region-start = <0x100000>;
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_jpeg {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x20C0 0x20>,
+				<&apps_smmu 0x20E0 0x20>;
+			cam-smmu-label = "jpeg";
+			dma-coherent;
+			jpeg_iova_mem_map: iova-mem-map {
+				/* IO region is approximately 3.4 GB */
+				iova-mem-region-io {
+					iova-region-name = "io";
+					iova-region-start = <0x100000>;
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_icp_fw {
+			compatible = "qcom,msm-cam-smmu-fw-dev";
+			label="icp";
+			memory-region = <&camera_mem>;
+		};
+
+		msm_cam_smmu_icp {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x2000 0x20>,
+				<&apps_smmu 0x2020 0x20>,
+				<&apps_smmu 0x2062 0x0>,
+				<&apps_smmu 0x2080 0x20>,
+				<&apps_smmu 0x20A0 0x20>,
+				<&apps_smmu 0x2140 0x0>;
+			cam-smmu-label = "icp";
+			dma-coherent;
+			icp_iova_mem_map: iova-mem-map {
+				iova-mem-region-firmware {
+					/* Firmware region is 5MB */
+					iova-region-name = "firmware";
+					iova-region-start = <0x0>;
+					iova-region-len = <0x500000>;
+					iova-region-id = <0x0>;
+					status = "ok";
+				};
+
+				iova-mem-region-shared {
+					/* Shared region is 150MB long */
+					iova-region-name = "shared";
+					iova-region-start = <0x7400000>;
+					iova-region-len = <0x9600000>;
+					iova-region-id = <0x1>;
+					status = "ok";
+				};
+
+				iova-mem-region-secondary-heap {
+					/* Secondary heap region is 1MB long */
+					iova-region-name = "secheap";
+					iova-region-start = <0x10a00000>;
+					iova-region-len = <0x100000>;
+					iova-region-id = <0x4>;
+					status = "ok";
+				};
+
+				iova-mem-region-io {
+					/* IO region is approximately 3.7 GB */
+					iova-region-name = "io";
+					iova-region-start = <0x10c00000>;
+					iova-region-len = <0xcf300000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+
+				iova-mem-qdss-region {
+					/* QDSS region is appropriate 1MB */
+					iova-region-name = "qdss";
+					iova-region-start = <0x10b00000>;
+					iova-region-len = <0x100000>;
+					iova-region-id = <0x5>;
+					qdss-phy-addr = <0x16790000>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_cpas_cdm {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x2040 0x0>;
+			cam-smmu-label = "cpas-cdm";
+			dma-coherent;
+			cpas_cdm_iova_mem_map: iova-mem-map {
+				iova-mem-region-io {
+					/* IO region is approximately 3.4 GB */
+					iova-region-name = "io";
+					iova-region-start = <0x100000>;
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_lrme {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x2100 0x20>,
+				<&apps_smmu 0x2120 0x20>;
+			cam-smmu-label = "lrme";
+			dma-coherent;
+			lrme_iova_mem_map: iova-mem-map {
+				iova-mem-region-shared {
+					/* Shared region is 100MB long */
+					iova-region-name = "shared";
+					iova-region-start = <0x7400000>;
+					iova-region-len = <0x6400000>;
+					iova-region-id = <0x1>;
+					status = "ok";
+				};
+				/* IO region is approximately 3.3 GB */
+				iova-mem-region-io {
+					iova-region-name = "io";
+					iova-region-start = <0x100000>;
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_secure {
+			compatible = "qcom,msm-cam-smmu-cb";
+			cam-smmu-label = "cam-secure";
+			qcom,secure-cb;
+		};
+	};
+
+	qcom,cam-cdm-intf {
+		compatible = "qcom,cam-cdm-intf";
+		cell-index = <0>;
+		label = "cam-cdm-intf";
+		num-hw-cdm = <1>;
+		cdm-client-names = "vfe",
+			"jpegdma",
+			"jpegenc",
+			"lrmecdm";
+		status = "ok";
+	};
+
+	qcom,cpas-cdm0 {
+		cell-index = <0>;
+		compatible = "qcom,cam170-cpas-cdm0";
+		label = "cpas-cdm";
+		reg = <0x0 0xac48000 0x0 0x1000>;
+		reg-names = "cpas-cdm";
+		reg-cam-base = <0x48000>;
+		interrupts = <GIC_SPI 461 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "cpas-cdm";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_slow_ahb_clk_src";
+		clock-rates = <80000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table>;
+		clock-cntl-level = "svs";
+		cdm-client-names = "ife0", "ife1", "ife2",
+				   "ife3", "ife4", "dualife";
+		status = "ok";
+		cdm_cpas_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,cam-isp {
+		compatible = "qcom,cam-isp";
+		arch-compat = "ife";
+		status = "ok";
+	};
+
+	cam_csid0: qcom,csid0 {
+		cell-index = <0>;
+		compatible = "qcom,csid165_204";
+		reg-names = "csid";
+		reg = <0x0 0xacb3000 0x0 0x1000>;
+		reg-cam-base = <0xb3000>;
+		interrupt-names = "csid0";
+		interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_0_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_0_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_0_CSID_CLK>,
+			<&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_0_CLK>,
+			<&camcc CAM_CC_IFE_0_AXI_CLK>;
+		clock-rates =
+			<300000000 0 0 380000000 0 0>,
+			<400000000 0 0 510000000 0 0>,
+			<400000000 0 0 637000000 0 0>,
+			<400000000 0 0 760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+
+		operating-points-v2 = <&csid0_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe0: qcom,vfe0 {
+		cell-index = <0>;
+		compatible = "qcom,vfe165_160";
+		reg-names = "ife";
+		reg = <0x0 0xacaf000 0x0 0x5200>;
+		reg-cam-base = <0xaf000>;
+		interrupt-names = "ife0";
+		interrupts = <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_0_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_0_CLK>,
+			<&camcc CAM_CC_IFE_0_AXI_CLK>;
+		clock-rates =
+			<380000000 0 0>,
+			<510000000 0 0>,
+			<637000000 0 0>,
+			<760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+
+		operating-points-v2 = <&vfe0_opp_table>;
+		clock-control-debugfs = "true";
+		clock-names-option =  "ife_dsp_clk";
+		clocks-option = <&camcc CAM_CC_IFE_0_DSP_CLK>;
+		clock-rates-option = <760000000>;
+		cam_hw_pid = <24 8>;
+		status = "ok";
+		vfe0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid1: qcom,csid1 {
+		cell-index = <1>;
+		compatible = "qcom,csid165_204";
+		reg-names = "csid";
+		reg = <0x0 0xacba000 0x0 0x1000>;
+		reg-cam-base = <0xba000>;
+		interrupt-names = "csid1";
+		interrupts = <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_1_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_1_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_1_CSID_CLK>,
+			<&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_1_CLK>,
+			<&camcc CAM_CC_IFE_1_AXI_CLK>;
+		clock-rates =
+			<300000000 0 0 380000000 0 0>,
+			<400000000 0 0 510000000 0 0>,
+			<400000000 0 0 637000000 0 0>,
+			<400000000 0 0 760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+
+		operating-points-v2 = <&csid1_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe1: qcom,vfe1 {
+		cell-index = <1>;
+		compatible = "qcom,vfe165_160";
+		reg-names = "ife";
+		reg = <0x0 0xacb6000 0x0 0x5200>;
+		reg-cam-base = <0xb6000>;
+		interrupt-names = "ife1";
+		interrupts = <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_1_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_1_CLK>,
+			<&camcc CAM_CC_IFE_1_AXI_CLK>;
+		clock-rates =
+			<380000000 0 0>,
+			<510000000 0 0>,
+			<637000000 0 0>,
+			<760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+		operating-points-v2 = <&vfe1_opp_table>;
+
+		clock-control-debugfs = "true";
+		clock-names-option =  "ife_dsp_clk";
+		clocks-option = <&camcc CAM_CC_IFE_1_DSP_CLK>;
+		clock-rates-option = <760000000>;
+		cam_hw_pid = <25 9>;
+		status = "ok";
+		vfe1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid2: qcom,csid2 {
+		cell-index = <2>;
+		compatible = "qcom,csid165_204";
+		reg-names = "csid";
+		reg = <0x0 0x0acc1000 0x0 0x1000>;
+		reg-cam-base = <0xc1000>;
+		interrupt-names = "csid2";
+		interrupts = <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_2_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_2_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_2_CSID_CLK>,
+			<&camcc CAM_CC_IFE_2_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_2_CLK_SRC>,
+			<&camcc CAM_CC_IFE_2_CLK>,
+			<&camcc CAM_CC_IFE_2_AXI_CLK>;
+		clock-rates =
+			<300000000 0 0 380000000 0 0>,
+			<400000000 0 0 510000000 0 0>,
+			<400000000 0 0 637000000 0 0>,
+			<400000000 0 0 760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+		operating-points-v2 = <&csid2_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe2: qcom,vfe2 {
+		cell-index = <2>;
+		compatible = "qcom,vfe165_160";
+		reg-names = "ife";
+		reg = <0x0 0x0acbd000 0x0 0x5200>;
+		reg-cam-base = <0xbd000>;
+		interrupt-names = "ife2";
+		interrupts = <GIC_SPI 641 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_2_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_2_CLK_SRC>,
+			<&camcc CAM_CC_IFE_2_CLK>,
+			<&camcc CAM_CC_IFE_2_AXI_CLK>;
+		clock-rates =
+			<380000000 0 0>,
+			<510000000 0 0>,
+			<637000000 0 0>,
+			<760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+		operating-points-v2 = <&vfe2_opp_table>;
+
+		clock-control-debugfs = "true";
+		clock-names-option =  "ife_dsp_clk";
+		clocks-option = <&camcc CAM_CC_IFE_2_DSP_CLK>;
+		clock-rates-option = <760000000>;
+		cam_hw_pid = <3 10>;
+		status = "ok";
+		vfe2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite0: qcom,csid-lite0 {
+		cell-index = <3>;
+		compatible = "qcom,csid-lite165";
+		reg-names = "csid-lite";
+		reg = <0x0 0xacc8000 0x0 0x1000>;
+		reg-cam-base = <0xc8000>;
+		interrupt-names = "csid-lite0";
+		interrupts = <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_LITE_0_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_0_CLK>;
+		clock-rates =
+			<300000000 0 0 320000000 0>,
+			<400000000 0 0 400000000 0>,
+			<400000000 0 0 480000000 0>,
+			<400000000 0 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+		operating-points-v2 = <&csid_lite0_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite0: qcom,vfe-lite0 {
+		cell-index = <3>;
+		compatible = "qcom,vfe-lite165";
+		reg-names = "ife-lite";
+		reg = <0x0 0xacc4000 0x0 0x5000>;
+		reg-cam-base = <0xc4000>;
+		interrupt-names = "ife-lite0";
+		interrupts = <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_LITE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_0_CLK>;
+		clock-rates =
+			<320000000 0>,
+			<400000000 0>,
+			<480000000 0>,
+			<600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+		operating-points-v2 = <&vfe_lite0_opp_table>;
+
+		clock-control-debugfs = "true";
+		cam_hw_pid = <11>;
+		status = "ok";
+		vfe_lite0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite1: qcom,csid-lite1 {
+		cell-index = <4>;
+		compatible = "qcom,csid-lite165";
+		reg-names = "csid-lite";
+		reg = <0x0 0x0accf000 0x0 0x1000>;
+		reg-cam-base = <0xcf000>;
+		interrupt-names = "csid-lite1";
+		interrupts = <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_LITE_1_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_1_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_1_CLK>;
+		clock-rates =
+			<300000000 0 0 320000000 0>,
+			<400000000 0 0 400000000 0>,
+			<400000000 0 0 480000000 0>,
+			<400000000 0 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+		operating-points-v2 = <&csid_lite1_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite1: qcom,vfe-lite1 {
+		cell-index = <4>;
+		compatible = "qcom,vfe-lite165";
+		reg-names = "ife-lite";
+		reg = <0x0 0x0accb000 0x0 0x5000>;
+		reg-cam-base = <0xcb000>;
+		interrupt-names = "ife-lite1";
+		interrupts = <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_LITE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_1_CLK>;
+		clock-rates =
+			<320000000 0>,
+			<400000000 0>,
+			<480000000 0>,
+			<600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+		operating-points-v2 = <&vfe_lite1_opp_table>;
+
+		clock-control-debugfs = "true";
+		cam_hw_pid = <12>;
+		status = "ok";
+		vfe_lite1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-icp {
+		compatible = "qcom,cam-icp";
+		compat-hw-name = "qcom,a5",
+			"qcom,ipe0",
+			"qcom,bps";
+		num-a5 = <1>;
+		num-ipe = <1>;
+		num-bps = <1>;
+		icp_pc_en;
+		status = "ok";
+	};
+
+	cam_a5: qcom,a5 {
+		cell-index = <0>;
+		compatible = "qcom,cam-a5";
+		reg = <0x0 0xac00000 0x0 0x6000>,
+			<0x0 0xac10000 0x0 0x8000>,
+			<0x0 0xac18000 0x0 0x3000>;
+		reg-names = "a5_qgic", "a5_sierra", "a5_csr";
+		reg-cam-base = <0x00000 0x10000 0x18000>;
+		interrupts = <GIC_SPI 463 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a5";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"soc_fast_ahb",
+			"icp_ahb_clk",
+			"icp_clk_src",
+			"icp_clk";
+		src-clock-name = "soc_fast_ahb";
+		clocks =
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_ICP_AHB_CLK>,
+			<&camcc CAM_CC_ICP_CLK_SRC>,
+			<&camcc CAM_CC_ICP_CLK>;
+		clock-rates =
+			<100000000 0 400000000 0>,
+			<200000000 0 400000000 0>,
+			<300000000 0 600000000 0>,
+			<400000000 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1",
+					"nominal";
+		operating-points-v2 = <&a5_opp_table>;
+
+		fw_name = "CAMERA_ICP_170.elf";
+		ubwc-ipe-fetch-cfg = <0x7073 0x707b>;
+		ubwc-ipe-write-cfg = <0x161cf 0x161ef>;
+		ubwc-bps-fetch-cfg = <0x7073 0x707b>;
+		ubwc-bps-write-cfg = <0x161cf 0x161ef>;
+		qos-val = <0x00000A0A>;
+		status = "ok";
+		a5_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_ipe0: qcom,ipe0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-ipe";
+		reg = <0x0 0xac87000 0x0 0xa000>;
+		reg-names = "ipe0_top";
+		reg-cam-base = <0x87000>;
+		power-domains = <&camcc CAM_CC_IPE_0_GDSC>;
+		clock-names =
+			"ipe_0_ahb_clk",
+			"ipe_0_areg_clk",
+			"ipe_0_axi_clk",
+			"ipe_0_clk_src",
+			"ipe_0_clk";
+		src-clock-name = "ipe_0_clk_src";
+		clock-control-debugfs = "true";
+		clocks =
+			<&camcc CAM_CC_IPE_0_AHB_CLK>,
+			<&camcc CAM_CC_IPE_0_AREG_CLK>,
+			<&camcc CAM_CC_IPE_0_AXI_CLK>,
+			<&camcc CAM_CC_IPE_0_CLK_SRC>,
+			<&camcc CAM_CC_IPE_0_CLK>;
+
+		clock-rates =
+			<0 0 0 300000000 0>,
+			<0 0 0 430000000 0>,
+			<0 0 0 520000000 0>,
+			<0 0 0 600000000 0>,
+			<0 0 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1",
+				"nominal", "turbo";
+		operating-points-v2 = <&ipe0_opp_table>;
+
+		status = "ok";
+		ipe0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-430000000 {
+				opp-hz = /bits/ 64 <430000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-520000000 {
+				opp-hz = /bits/ 64 <520000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_bps: qcom,bps {
+		cell-index = <0>;
+		compatible = "qcom,cam-bps";
+		reg = <0x0 0xac6f000 0x0 0x8000>;
+		reg-names = "bps_top";
+		reg-cam-base = <0x6f000>;
+		power-domains = <&camcc CAM_CC_BPS_GDSC>;
+		clock-names =
+			"bps_ahb_clk",
+			"bps_areg_clk",
+			"bps_axi_clk",
+			"bps_clk_src",
+			"bps_clk";
+		src-clock-name = "bps_clk_src";
+		clock-control-debugfs = "true";
+		clocks =
+			<&camcc CAM_CC_BPS_AHB_CLK>,
+			<&camcc CAM_CC_BPS_AREG_CLK>,
+			<&camcc CAM_CC_BPS_AXI_CLK>,
+			<&camcc CAM_CC_BPS_CLK_SRC>,
+			<&camcc CAM_CC_BPS_CLK>;
+
+		clock-rates =
+			<0 0 0 200000000 0>,
+			<0 0 0 400000000 0>,
+			<0 0 0 480000000 0>,
+			<0 0 0 600000000 0>,
+			<0 0 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1",
+				"nominal", "turbo";
+		operating-points-v2 = <&bps_opp_table>;
+
+		status = "ok";
+		bps_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-jpeg {
+		compatible = "qcom,cam-jpeg";
+		compat-hw-name = "qcom,jpegenc",
+			"qcom,jpegdma";
+		num-jpeg-enc = <1>;
+		num-jpeg-dma = <1>;
+		status = "ok";
+	};
+
+	cam_jpeg_enc: qcom,jpegenc {
+		cell-index = <0>;
+		compatible = "qcom,cam_jpeg_enc_165";
+		reg-names = "jpege_hw", "cam_camnoc";
+		reg = <0x0 0xac4e000 0x0 0x4000>,
+			<0x0 0x0ac9f000 0x0 0x10000>;
+		reg-cam-base = <0x4e000 0x9f000>;
+		interrupt-names = "jpeg";
+		interrupts = <GIC_SPI 474 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"jpegenc_clk_src",
+			"jpegenc_clk";
+		clocks =
+			<&camcc CAM_CC_JPEG_CLK_SRC>,
+			<&camcc CAM_CC_JPEG_CLK>;
+
+		clock-rates = <600000000 0>;
+		src-clock-name = "jpegenc_clk_src";
+		operating-points-v2 = <&jpeg_enc_opp_table>;
+
+		clock-cntl-level = "nominal";
+		cam_hw_pid = <22 23>;
+		cam_hw_rd_mid = <0>;
+		cam_hw_wr_mid = <2>;
+		status = "ok";
+		jpeg_enc_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_jpeg_dma: qcom,jpegdma {
+		cell-index = <0>;
+		compatible = "qcom,cam_jpeg_dma_165";
+		reg-names = "jpegdma_hw", "cam_camnoc";
+		reg = <0x0 0xac52000 0x0 0x4000>,
+			<0x0 0x0ac9f000 0x0 0x10000>;
+		reg-cam-base = <0x52000 0x9f000>;
+		interrupt-names = "jpegdma";
+		interrupts = <GIC_SPI 475 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"jpegdma_clk_src",
+			"jpegdma_clk";
+		clocks =
+			<&camcc CAM_CC_JPEG_CLK_SRC>,
+			<&camcc CAM_CC_JPEG_CLK>;
+
+		clock-rates = <600000000 0>;
+		src-clock-name = "jpegdma_clk_src";
+		operating-points-v2 = <&jpeg_dma_opp_table>;
+
+		clock-cntl-level = "nominal";
+		cam_hw_pid = <20 21>;
+		cam_hw_rd_mid = <0>;
+		cam_hw_wr_mid = <2>;
+		status = "ok";
+		jpeg_dma_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-lrme {
+		compatible = "qcom,cam-lrme";
+		arch-compat = "lrme";
+		status = "ok";
+	};
+
+	cam_lrme: qcom,lrme {
+		cell-index = <0>;
+		compatible = "qcom,lrme";
+		reg-names = "lrme";
+		reg = <0x0 0xac6b000 0x0 0x1000>;
+		reg-cam-base = <0x6b000>;
+		interrupt-names = "lrme";
+		interrupts = <GIC_SPI 476 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "lrme_clk_src",
+			"lrme_clk";
+		clocks = <&camcc CAM_CC_LRME_CLK_SRC>,
+			<&camcc CAM_CC_LRME_CLK>;
+		clock-rates = <240000000 0>,
+			<300000000 0>,
+			<320000000 0>,
+			<400000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal";
+		src-clock-name = "lrme_clk_src";
+		operating-points-v2 = <&lrme_opp_table>;
+
+		status = "ok";
+		lrme_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-240000000 {
+				opp-hz = /bits/ 64 <240000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-cpas {
+		cell-index = <0>;
+		compatible = "qcom,cam-cpas";
+		label = "cpas";
+		arch-compat = "cpas_top";
+		status = "ok";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg-names = "cam_cpas_top", "cam_camnoc";
+		reg = <0x0 0x0ac40000 0x0 0x1000>,
+			<0x0 0x0ac9f000 0x0 0x10000>;
+		reg-cam-base = <0x40000 0x9f000>;
+		cam_hw_fuse = <CAM_CPAS_ISP_FUSE 0x7801FC 0x10 CAM_CPAS_FEATURE_TYPE_DISABLE 0x4>,
+			      <CAM_CPAS_ISP_LITE_FUSE 0x7801FC 0x20 CAM_CPAS_FEATURE_TYPE_DISABLE 0x10>,
+			      <CAM_CPAS_SHDR_FUSE 0x7801FC 0x40 CAM_CPAS_FEATURE_TYPE_DISABLE 0xFF>,
+			      <CAM_CPAS_QCFA_BINNING_ENABLE 0x7801FC 0x80 CAM_CPAS_FEATURE_TYPE_DISABLE 0xFF>,
+			      <CAM_CPAS_CSIPHY_FUSE 0x7801FC 0x100 CAM_CPAS_FEATURE_TYPE_DISABLE 0x10>,
+			      <CAM_CPAS_RT_OT_FUSE 0x7801A4 0x10000000 CAM_CPAS_FEATURE_TYPE_DISABLE 0xFF>;
+		interrupt-names = "cpas_camnoc";
+		interrupts = <GIC_SPI 459 IRQ_TYPE_EDGE_RISING>;
+		camnoc-axi-min-ib-bw = <3000000000>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"gcc_camera_hf_axi_clk",
+			"gcc_camera_sf_axi_clk",
+			"cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk",
+			"cam_cc_camnoc_axi_clk_src",
+			"cam_cc_camnoc_axi_clk",
+			"cam_cc_icp_ahb_clk",
+			"cam_cc_icp_clk";
+		clocks =
+			<&gcc GCC_CAMERA_HF_AXI_CLK>,
+			<&gcc GCC_CAMERA_SF_AXI_CLK>,
+			<&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>,
+			<&camcc CAM_CC_CAMNOC_AXI_CLK_SRC>,
+			<&camcc CAM_CC_CAMNOC_AXI_CLK>,
+			<&camcc CAM_CC_ICP_AHB_CLK>,
+			<&camcc CAM_CC_ICP_CLK>;
+		src-clock-name = "cam_cc_camnoc_axi_clk_src";
+		clock-rates =
+			<0 0 0 0 0 0 0 0>,
+			<0 0 80000000 0 150000000 0 0 0>,
+			<0 0 80000000 0 240000000 0 0 0>,
+			<0 0 80000000 0 320000000 0 0 0>,
+			<0 0 80000000 0 400000000 0 0 0>,
+			<0 0 80000000 0 480000000 0 0 0>;
+		clock-cntl-level = "suspend", "lowsvs", "svs",
+			"svs_l1", "nominal", "turbo";
+		operating-points-v2 = <&cpas_opp_table>;
+		control-camnoc-axi-clk;
+		camnoc-bus-width = <32>;
+		camnoc-axi-clk-bw-margin-perc = <20>;
+		interconnect-names = "cam_ahb", "cam_hf_0", "cam_sf_0", "cam_sf_icp";
+		interconnects =<&gem_noc MASTER_APPSS_PROC 0
+			&cnoc2 SLAVE_CAMERA_CFG 0>,
+				<&mmss_noc MASTER_CAMNOC_HF 0
+			&mc_virt SLAVE_EBI1 0>,
+				<&mmss_noc MASTER_CAMNOC_SF 0
+			&mc_virt SLAVE_EBI1 0>,
+				<&mmss_noc MASTER_CAMNOC_ICP 0
+			&mc_virt SLAVE_EBI1 0>;
+
+		cam-ahb-num-cases = <7>;
+		cam-ahb-bw-KBps =
+			<0 0>, <0 76800>, <0 150000>, <0 150000>,
+			<0 300000>, <0 300000>, <0 300000>;
+		vdd-corners = <RPMH_REGULATOR_LEVEL_RETENTION
+			RPMH_REGULATOR_LEVEL_MIN_SVS
+			RPMH_REGULATOR_LEVEL_LOW_SVS
+			RPMH_REGULATOR_LEVEL_SVS
+			RPMH_REGULATOR_LEVEL_SVS_L1
+			RPMH_REGULATOR_LEVEL_NOM
+			RPMH_REGULATOR_LEVEL_NOM_L1
+			RPMH_REGULATOR_LEVEL_NOM_L2
+			RPMH_REGULATOR_LEVEL_TURBO
+			RPMH_REGULATOR_LEVEL_TURBO_L1>;
+		vdd-corner-ahb-mapping = "suspend",
+			"lowsvs", "lowsvs", "svs", "svs_l1",
+			"nominal", "nominal", "nominal",
+			"turbo", "turbo";
+		client-id-based;
+		client-names =
+			"csiphy0", "csiphy1", "csiphy2", "csiphy3",
+			"csiphy4", "cci0", "cci1",
+			"csid0", "csid1", "csid2", "csid3", "csid4",
+			"ife0", "ife1", "ife2", "ife3", "ife4",
+			"ipe0", "cam-cdm-intf0", "cpas-cdm0",
+			"bps0", "icp0", "jpeg-dma0", "jpeg-enc0",
+			"lrmecpas0";
+
+		cpas_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-150000000 {
+				opp-hz = /bits/ 64 <150000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-240000000 {
+				opp-hz = /bits/ 64 <240000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_turbo>;
+			};
+		};
+		camera-bus-nodes {
+			level0-nodes {
+				level-index = <0>;
+				ife0_rdi_wr: ife0-rdi-wr {
+					cell-index = <16>;
+					node-name = "ife0-rdi-wr";
+					client-name = "ife0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife1_rdi_wr: ife1-rdi-wr {
+					cell-index = <17>;
+					node-name = "ife1-rdi-wr";
+					client-name = "ife1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife2_rdi_wr: ife2-rdi-wr {
+					cell-index = <18>;
+					node-name = "ife2-rdi-wr";
+					client-name = "ife2";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife3_rdi_wr: ife3-rdi-wr {
+					cell-index = <19>;
+					node-name = "ife3-rdi-wr";
+					client-name = "ife3";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife4_rdi_wr: ife4-rdi-wr {
+					cell-index = <20>;
+					node-name = "ife4-rdi-wr";
+					client-name = "ife4";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife0_pixelall_wr: ife0-pixelall-wr {
+					cell-index = <21>;
+					node-name = "ife0-pixelall-wr";
+					client-name = "ife0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_PIXEL_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_DISP
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt1_write0>;
+				};
+
+				ife1_pixelall_wr: ife1-pixelall-wr {
+					cell-index = <22>;
+					node-name = "ife1-pixelall-wr";
+					client-name = "ife1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_PIXEL_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_DISP
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt1_write0>;
+				};
+
+				ife2_pixelall_wr: ife2-pixelall-wr {
+					cell-index = <23>;
+					node-name = "ife2-pixelall-wr";
+					client-name = "ife2";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_PIXEL_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_DISP
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt1_write1>;
+				};
+
+				ipe0_ref_wr: ipe0-ref-wr {
+					cell-index = <24>;
+					node-name = "ipe0-ref-wr";
+					client-name = "ipe0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IPE_WR_REF>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt0_write0>;
+				};
+
+				bps0_all_wr: bps0-all-wr {
+					cell-index = <25>;
+					node-name = "bps0-all-wr";
+					client-name = "bps0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt0_write0>;
+				};
+
+				lrme0_all_wr: lrme0-all-wr {
+					cell-index = <26>;
+					node-name = "lrme0-all-wr";
+					client-name = "lrmecpas0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt0_write0>;
+				};
+
+				ipe0_viddisp_wr: ipe0-viddisp-wr {
+					cell-index = <27>;
+					node-name = "ipe0-viddisp-wr";
+					client-name = "ipe0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IPE_WR_VID_DISP>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IPE_WR_VID
+					CAM_CPAS_PATH_DATA_IPE_WR_DISP>;
+					parent-node = <&level1_nrt0_write0>;
+				};
+
+				ipe0_all_rd: ipe0-all-rd {
+					cell-index = <28>;
+					node-name = "ipe0-all-rd";
+					client-name = "ipe0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IPE_RD_IN
+					CAM_CPAS_PATH_DATA_IPE_RD_REF>;
+					parent-node = <&level1_nrt0_read0>;
+				};
+
+				bps0_all_rd: bps0-all-rd {
+					cell-index = <29>;
+					node-name = "bps0-all-rd";
+					client-name = "bps0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt0_read0>;
+				};
+
+				lrme0_all_rd: lrme0-all-rd {
+					cell-index = <30>;
+					node-name = "lrme0-all-rd";
+					client-name = "lrmecpas0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt0_read0>;
+				};
+
+				jpeg_enc0_all_wr: jpeg-enc0-all-wr {
+					cell-index = <31>;
+					node-name = "jpeg-enc0-all-wr";
+					client-name = "jpeg-enc0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt1_write0>;
+				};
+
+				jpeg_enc0_all_rd: jpeg-enc0-all-rd {
+					cell-index = <32>;
+					node-name = "jpeg-enc0-all-rd";
+					client-name = "jpeg-enc0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt1_read0>;
+				};
+
+				jpeg_dma0_all_wr: jpeg-dma0-all-wr {
+					cell-index = <33>;
+					node-name = "jpeg-dma0-all-wr";
+					client-name = "jpeg-dma0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt1_write0>;
+				};
+
+				jpeg_dma0_all_rd: jpeg-dma0-all-rd {
+					cell-index = <34>;
+					node-name = "jpeg-dma0-all-rd";
+					client-name = "jpeg-dma0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt1_read0>;
+				};
+
+				cpas_cdm0_all_rd: cpas-cdm0-all-rd {
+					cell-index = <35>;
+					node-name = "cpas-cdm0-all-rd";
+					client-name = "cpas-cdm0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level2_nrt0_read0>;
+				};
+
+				icp0_all_rd: icp0-all-rd {
+					cell-index = <36>;
+					node-name = "icp0-all-rd";
+					client-name = "icp0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level2_nrt1_read0>;
+				};
+			};
+			level1-nodes {
+				level-index = <1>;
+				camnoc-max-needed;
+				level1_rt0_write0: level1-rt0-write0 {
+					cell-index = <8>;
+					node-name = "level1-rt0-write0";
+					parent-node = <&level2_rt0_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_rt1_write0: level1-rt1-write0 {
+					cell-index = <9>;
+					node-name = "level1-rt1-write0";
+					parent-node = <&level2_rt1_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_rt1_write1: level1-rt1-write1 {
+					cell-index = <10>;
+					node-name = "level1-rt1-write1";
+					parent-node = <&level2_rt1_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt0_write0: level1-nrt0-write0 {
+					cell-index = <11>;
+					node-name = "level1-nrt0-write0";
+					parent-node = <&level2_nrt0_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt0_read0: level1-nrt0-read0 {
+					cell-index = <12>;
+					node-name = "level1-nrt0-read0";
+					parent-node = <&level2_nrt0_read0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt1_write0: level1-nrt1-write0 {
+					cell-index = <13>;
+					node-name = "level1-nrt1-write0";
+					parent-node = <&level2_nrt0_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt1_read0: level1-nrt1-read0 {
+					cell-index = <14>;
+					node-name = "level1-nrt1-read0";
+					parent-node = <&level2_nrt0_read0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+			};
+			level2-nodes {
+				level-index = <3>;
+				camnoc-max-needed;
+				level2_rt0_write0: level2-rt0-write0 {
+					cell-index = <3>;
+					node-name = "level2-rt0-write0";
+					parent-node = <&level3_rt0_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM_INTERLEAVE>;
+				};
+
+				level2_rt1_write0: level2-rt1-write0 {
+					cell-index = <4>;
+					node-name = "level2-rt1-write0";
+					parent-node = <&level3_rt0_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM_INTERLEAVE>;
+				};
+
+				level2_nrt0_write0: level2-nrt0-write0 {
+					cell-index = <5>;
+					node-name = "level2-nrt0-write0";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt0_read0: level2-nrt0-read0 {
+					cell-index = <6>;
+					node-name = "level2-nrt0-read0";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt1_read0: level2-nrt1-read0 {
+					cell-index = <7>;
+					node-name = "level2-nrt1-read0";
+					parent-node = <&level3_nrt1_rd_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					bus-width-factor = <4>;
+				};
+			};
+			level3-nodes {
+				level-index = <3>;
+				level3_rt0_wr_sum: level3-rt0-wr-sum {
+					cell-index = <0>;
+					node-name = "level3-rt0-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					ib-bw-voting-needed;
+					qcom,axi-port-mnoc {
+						interconnect-names = "cam_hf_0";
+						interconnects =
+						<&mmss_noc MASTER_CAMNOC_HF 0
+						&mc_virt SLAVE_EBI1 0>;
+					};
+				};
+
+				level3_nrt0_rd_wr_sum: level3-nrt0-rd-wr-sum {
+					cell-index = <1>;
+					node-name = "level3-nrt0-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					qcom,axi-port-mnoc {
+						interconnect-names = "cam_sf_0";
+						interconnects =
+						<&mmss_noc MASTER_CAMNOC_SF 0
+						&mc_virt SLAVE_EBI1 0>;
+					};
+				};
+
+				level3_nrt1_rd_sum: level3-nrt1-rd-sum {
+					cell-index = <2>;
+					node-name = "level3-nrt1-rd-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					qcom,axi-port-mnoc {
+						interconnect-names = "cam_sf_icp";
+						interconnects =
+						<&mmss_noc MASTER_CAMNOC_ICP 0
+						&mc_virt SLAVE_EBI1 0>;
+					};
+				};
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-camera-rb3.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-camera-rb3.dtso
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sc7280.h>
+#include <dt-bindings/clock/qcom,camcc-sc7280.h>
+#include <dt-bindings/interconnect/qcom,sc7280.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+
+#include "qcm6490-camera-rb3.dtsi"
+#include "qcm6490-camera-sensor-rb3.dtsi"
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-camera-rubikpi3.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-camera-rubikpi3.dtsi
@@ -0,0 +1,2354 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <dt-bindings/msm-camera.h>
+#include <dt-bindings/clock/qcom,gcc-sc7280.h>
+#include <dt-bindings/clock/qcom,camcc-sc7280.h>
+#include <dt-bindings/interconnect/qcom,sc7280.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+
+&tlmm {
+	cci0_active: cci0_active {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio69","gpio70"; // Only 2
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio69","gpio70";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci0_suspend: cci0_suspend {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio69","gpio70";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio69","gpio70";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci1_active: cci1_active {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio71","gpio72";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio71","gpio72";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci1_suspend: cci1_suspend {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio71","gpio72";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio71","gpio72";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci2_active: cci2_active {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio73","gpio74";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio73","gpio74";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci2_suspend: cci2_suspend {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio73","gpio74";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio73","gpio74";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci3_active: cci3_active {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio75","gpio76";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio75","gpio76";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci3_suspend: cci3_suspend {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio75","gpio76";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio75","gpio76";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+
+	};
+
+	cam_sensor_mclk3_active: cam_sensor_mclk3_active {
+		/* MCLK3 */
+		mux {
+			pins = "gpio67";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio67";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk3_suspend: cam_sensor_mclk3_suspend {
+		/* MCLK3 */
+		mux {
+			pins = "gpio67";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio67";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk4_active: cam_sensor_mclk4_active {
+		/* MCLK4 */
+		mux {
+			pins = "gpio68";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio68";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk4_suspend: cam_sensor_mclk4_suspend {
+		/* MCLK4 */
+		mux {
+			pins = "gpio68";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio68";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk5_active: cam_sensor_mclk5_active {
+		/* MCLK5 */
+		mux {
+			pins = "gpio98";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio98";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk5_suspend: cam_sensor_mclk5_suspend {
+		/* MCLK5 */
+		mux {
+			pins = "gpio98";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio98";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_active_rst0: cam_sensor_active_rst0 {
+		/* RESET REAR */
+		mux {
+			pins = "gpio20";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio20";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst0: cam_sensor_suspend_rst0 {
+		/* RESET REAR */
+		mux {
+			pins = "gpio20";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio20";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_rst1: cam_sensor_active_rst1 {
+		/* RESET REARAUX */
+		mux {
+			pins = "gpio21";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio21";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst1: cam_sensor_suspend_rst1 {
+		/* RESET REARAUX */
+		mux {
+			pins = "gpio21";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio21";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_mux: cam_sensor_active_mux {
+		/* GC630 bypass mux */
+		mux {
+			pins = "gpio1";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio1";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_mux: cam_sensor_suspend_mux {
+		/* GC630 bypass mux */
+		mux {
+			pins = "gpio1";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio1";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+};
+
+&soc {
+	qcom,cam-req-mgr {
+		compatible = "qcom,cam-req-mgr";
+		status = "ok";
+	};
+
+	qcom,cam-sync {
+		compatible = "qcom,cam-sync";
+		status = "ok";
+	};
+
+	cam_csiphy0: qcom,csiphy0 {
+		cell-index = <0>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0x0ace0000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe0000>;
+		interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy0";
+		operating-points-v2 = <&csiphy0_opp_table>;
+		refgen-supply = <&refgen>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY0_CLK>,
+			<&camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI0PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy0_clk",
+			"csi0phytimer_clk_src",
+			"csi0phytimer_clk";
+		src-clock-name = "csi0phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_csiphy1: qcom,csiphy1 {
+		cell-index = <1>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0xace2000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe2000>;
+		interrupts = <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy1";
+		operating-points-v2 = <&csiphy1_opp_table>;
+		refgen-supply = <&refgen>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY1_CLK>,
+			<&camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI1PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy1_clk",
+			"csi1phytimer_clk_src",
+			"csi1phytimer_clk";
+		src-clock-name = "csi1phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_csiphy2: qcom,csiphy2 {
+		cell-index = <2>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0xace4000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe4000>;
+		interrupts = <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy2";
+		refgen-supply = <&refgen>;
+		operating-points-v2 = <&csiphy2_opp_table>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY2_CLK>,
+			<&camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI2PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy2_clk",
+			"csi2phytimer_clk_src",
+			"csi2phytimer_clk";
+		src-clock-name = "csi2phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_csiphy3: qcom,csiphy3 {
+		cell-index = <3>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0xace6000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe6000>;
+		interrupts = <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy3";
+		refgen-supply = <&refgen>;
+		operating-points-v2 = <&csiphy3_opp_table>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY3_CLK>,
+			<&camcc CAM_CC_CSI3PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI3PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy3_clk",
+			"csi3phytimer_clk_src",
+			"csi3phytimer_clk";
+		src-clock-name = "csi3phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_csiphy4: qcom,csiphy4 {
+		cell-index = <4>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0xace8000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe8000>;
+		interrupts = <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy4";
+		refgen-supply = <&refgen>;
+		operating-points-v2 = <&csiphy4_opp_table>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY4_CLK>,
+			<&camcc CAM_CC_CSI4PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI4PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy4_clk",
+			"csi4phytimer_clk_src",
+			"csi4phytimer_clk";
+		src-clock-name = "csi4phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy4_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_cci0: qcom,cci0 {
+		cell-index = <0>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac4a000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x4a000>;
+		interrupt-names = "cci";
+		interrupts = <GIC_SPI 460 IRQ_TYPE_EDGE_RISING>;
+		status = "ok";
+		operating-points-v2 = <&cci0_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clocks = <&camcc CAM_CC_CCI_0_CLK_SRC>,
+			<&camcc CAM_CC_CCI_0_CLK>;
+		clock-names = "cci_0_clk_src",
+			"cci_0_clk";
+		src-clock-name = "cci_0_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates = <37500000 0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cci0_active &cci1_active>;
+		pinctrl-1 = <&cci0_suspend &cci1_suspend>;
+		gpios = <&tlmm 69 0>,
+			<&tlmm 70 0>,
+			<&tlmm 71 0>,
+			<&tlmm 72 0>;
+		gpio-req-tbl-num = <0 1 2 3>;
+		gpio-req-tbl-flags = <1 1 1 1>;
+		gpio-req-tbl-label = "CCI_I2C_DATA0",
+					"CCI_I2C_CLK0",
+					"CCI_I2C_DATA1",
+					"CCI_I2C_CLK1";
+		cci0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci0: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci0: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci0: qcom,i2c_custom_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci0: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	cam_cci1: qcom,cci1 {
+		cell-index = <1>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac4b000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x4b000>;
+		interrupt-names = "cci";
+		interrupts = <GIC_SPI 271 IRQ_TYPE_EDGE_RISING>;
+		status = "ok";
+		operating-points-v2 = <&cci1_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clocks = <&camcc CAM_CC_CCI_1_CLK_SRC>,
+			<&camcc CAM_CC_CCI_1_CLK>;
+		clock-names = "cci_1_clk_src",
+			"cci_1_clk";
+		src-clock-name = "cci_1_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates = <37500000 0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cci2_active &cci3_active>;
+		pinctrl-1 = <&cci2_suspend &cci3_suspend>;
+		gpios = <&tlmm 73 0>,
+			<&tlmm 74 0>,
+			<&tlmm 75 0>,
+			<&tlmm 76 0>;
+		gpio-req-tbl-num = <0 1 2 3>;
+		gpio-req-tbl-flags = <1 1 1 1>;
+		gpio-req-tbl-label = "CCI_I2C_DATA2",
+					"CCI_I2C_CLK2",
+					"CCI_I2C_DATA3",
+					"CCI_I2C_CLK3";
+		cci1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci1: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci1: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci1: qcom,i2c_custom_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci1: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	qcom,cam_smmu {
+		compatible = "qcom,msm-cam-smmu", "simple-bus";
+		status = "ok";
+		force_cache_allocs;
+
+		msm_cam_smmu_ife {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x800 0x4E0>,
+				<&apps_smmu 0x820 0x4E0>,
+				<&apps_smmu 0x840 0x4E0>,
+				<&apps_smmu 0x860 0x4E0>,
+				<&apps_smmu 0x880 0x4E0>,
+				<&apps_smmu 0x8A0 0x4E0>,
+				<&apps_smmu 0x8C0 0x4E0>,
+				<&apps_smmu 0x8E0 0x4E0>,
+				<&apps_smmu 0xC00 0x4E0>,
+				<&apps_smmu 0xC20 0x4E0>,
+				<&apps_smmu 0xC40 0x4E0>,
+				<&apps_smmu 0xC60 0x4E0>,
+				<&apps_smmu 0xC80 0x4E0>,
+				<&apps_smmu 0xCA0 0x4E0>,
+				<&apps_smmu 0xCC0 0x4E0>,
+				<&apps_smmu 0xCE0 0x4E0>;
+			cam-smmu-label = "ife";
+			multiple-client-devices;
+			dma-coherent;
+			ife_iova_mem_map: iova-mem-map {
+				/* IO region is approximately 4 GB */
+				iova-mem-region-io {
+					iova-region-name = "io";
+					iova-region-start = <0x100000>;
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_jpeg {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x20C0 0x20>,
+				<&apps_smmu 0x20E0 0x20>;
+			cam-smmu-label = "jpeg";
+			dma-coherent;
+			jpeg_iova_mem_map: iova-mem-map {
+				/* IO region is approximately 3.4 GB */
+				iova-mem-region-io {
+					iova-region-name = "io";
+					iova-region-start = <0x100000>;
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_icp_fw {
+			compatible = "qcom,msm-cam-smmu-fw-dev";
+			label="icp";
+			memory-region = <&camera_mem>;
+		};
+
+		msm_cam_smmu_icp {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x2000 0x20>,
+				<&apps_smmu 0x2020 0x20>,
+				<&apps_smmu 0x2062 0x0>,
+				<&apps_smmu 0x2080 0x20>,
+				<&apps_smmu 0x20A0 0x20>,
+				<&apps_smmu 0x2140 0x0>;
+			cam-smmu-label = "icp";
+			dma-coherent;
+			icp_iova_mem_map: iova-mem-map {
+				iova-mem-region-firmware {
+					/* Firmware region is 5MB */
+					iova-region-name = "firmware";
+					iova-region-start = <0x0>;
+					iova-region-len = <0x500000>;
+					iova-region-id = <0x0>;
+					status = "ok";
+				};
+
+				iova-mem-region-shared {
+					/* Shared region is 150MB long */
+					iova-region-name = "shared";
+					iova-region-start = <0x7400000>;
+					iova-region-len = <0x9600000>;
+					iova-region-id = <0x1>;
+					status = "ok";
+				};
+
+				iova-mem-region-secondary-heap {
+					/* Secondary heap region is 1MB long */
+					iova-region-name = "secheap";
+					iova-region-start = <0x10a00000>;
+					iova-region-len = <0x100000>;
+					iova-region-id = <0x4>;
+					status = "ok";
+				};
+
+				iova-mem-region-io {
+					/* IO region is approximately 3.7 GB */
+					iova-region-name = "io";
+					iova-region-start = <0x10c00000>;
+					iova-region-len = <0xcf300000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+
+				iova-mem-qdss-region {
+					/* QDSS region is appropriate 1MB */
+					iova-region-name = "qdss";
+					iova-region-start = <0x10b00000>;
+					iova-region-len = <0x100000>;
+					iova-region-id = <0x5>;
+					qdss-phy-addr = <0x16790000>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_cpas_cdm {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x2040 0x0>;
+			cam-smmu-label = "cpas-cdm";
+			dma-coherent;
+			cpas_cdm_iova_mem_map: iova-mem-map {
+				iova-mem-region-io {
+					/* IO region is approximately 3.4 GB */
+					iova-region-name = "io";
+					iova-region-start = <0x100000>;
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_lrme {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x2100 0x20>,
+				<&apps_smmu 0x2120 0x20>;
+			cam-smmu-label = "lrme";
+			dma-coherent;
+			lrme_iova_mem_map: iova-mem-map {
+				iova-mem-region-shared {
+					/* Shared region is 100MB long */
+					iova-region-name = "shared";
+					iova-region-start = <0x7400000>;
+					iova-region-len = <0x6400000>;
+					iova-region-id = <0x1>;
+					status = "ok";
+				};
+				/* IO region is approximately 3.3 GB */
+				iova-mem-region-io {
+					iova-region-name = "io";
+					iova-region-start = <0x100000>;
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_secure {
+			compatible = "qcom,msm-cam-smmu-cb";
+			cam-smmu-label = "cam-secure";
+			qcom,secure-cb;
+		};
+	};
+
+	qcom,cam-cdm-intf {
+		compatible = "qcom,cam-cdm-intf";
+		cell-index = <0>;
+		label = "cam-cdm-intf";
+		num-hw-cdm = <1>;
+		cdm-client-names = "vfe",
+			"jpegdma",
+			"jpegenc",
+			"lrmecdm";
+		status = "ok";
+	};
+
+	qcom,cpas-cdm0 {
+		cell-index = <0>;
+		compatible = "qcom,cam170-cpas-cdm0";
+		label = "cpas-cdm";
+		reg = <0x0 0xac48000 0x0 0x1000>;
+		reg-names = "cpas-cdm";
+		reg-cam-base = <0x48000>;
+		interrupts = <GIC_SPI 461 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "cpas-cdm";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_slow_ahb_clk_src";
+		clock-rates = <80000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table>;
+		clock-cntl-level = "svs";
+		cdm-client-names = "ife0", "ife1", "ife2",
+				   "ife3", "ife4", "dualife";
+		status = "ok";
+		cdm_cpas_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,cam-isp {
+		compatible = "qcom,cam-isp";
+		arch-compat = "ife";
+		status = "ok";
+	};
+
+	cam_csid0: qcom,csid0 {
+		cell-index = <0>;
+		compatible = "qcom,csid165_204";
+		reg-names = "csid";
+		reg = <0x0 0xacb3000 0x0 0x1000>;
+		reg-cam-base = <0xb3000>;
+		interrupt-names = "csid0";
+		interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_0_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_0_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_0_CSID_CLK>,
+			<&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_0_CLK>,
+			<&camcc CAM_CC_IFE_0_AXI_CLK>;
+		clock-rates =
+			<300000000 0 0 380000000 0 0>,
+			<400000000 0 0 510000000 0 0>,
+			<400000000 0 0 637000000 0 0>,
+			<400000000 0 0 760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+
+		operating-points-v2 = <&csid0_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe0: qcom,vfe0 {
+		cell-index = <0>;
+		compatible = "qcom,vfe165_160";
+		reg-names = "ife";
+		reg = <0x0 0xacaf000 0x0 0x5200>;
+		reg-cam-base = <0xaf000>;
+		interrupt-names = "ife0";
+		interrupts = <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_0_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_0_CLK>,
+			<&camcc CAM_CC_IFE_0_AXI_CLK>;
+		clock-rates =
+			<380000000 0 0>,
+			<510000000 0 0>,
+			<637000000 0 0>,
+			<760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+
+		operating-points-v2 = <&vfe0_opp_table>;
+		clock-control-debugfs = "true";
+		clock-names-option =  "ife_dsp_clk";
+		clocks-option = <&camcc CAM_CC_IFE_0_DSP_CLK>;
+		clock-rates-option = <760000000>;
+		cam_hw_pid = <24 8>;
+		status = "ok";
+		vfe0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid1: qcom,csid1 {
+		cell-index = <1>;
+		compatible = "qcom,csid165_204";
+		reg-names = "csid";
+		reg = <0x0 0xacba000 0x0 0x1000>;
+		reg-cam-base = <0xba000>;
+		interrupt-names = "csid1";
+		interrupts = <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_1_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_1_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_1_CSID_CLK>,
+			<&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_1_CLK>,
+			<&camcc CAM_CC_IFE_1_AXI_CLK>;
+		clock-rates =
+			<300000000 0 0 380000000 0 0>,
+			<400000000 0 0 510000000 0 0>,
+			<400000000 0 0 637000000 0 0>,
+			<400000000 0 0 760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+
+		operating-points-v2 = <&csid1_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe1: qcom,vfe1 {
+		cell-index = <1>;
+		compatible = "qcom,vfe165_160";
+		reg-names = "ife";
+		reg = <0x0 0xacb6000 0x0 0x5200>;
+		reg-cam-base = <0xb6000>;
+		interrupt-names = "ife1";
+		interrupts = <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_1_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_1_CLK>,
+			<&camcc CAM_CC_IFE_1_AXI_CLK>;
+		clock-rates =
+			<380000000 0 0>,
+			<510000000 0 0>,
+			<637000000 0 0>,
+			<760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+		operating-points-v2 = <&vfe1_opp_table>;
+
+		clock-control-debugfs = "true";
+		clock-names-option =  "ife_dsp_clk";
+		clocks-option = <&camcc CAM_CC_IFE_1_DSP_CLK>;
+		clock-rates-option = <760000000>;
+		cam_hw_pid = <25 9>;
+		status = "ok";
+		vfe1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid2: qcom,csid2 {
+		cell-index = <2>;
+		compatible = "qcom,csid165_204";
+		reg-names = "csid";
+		reg = <0x0 0x0acc1000 0x0 0x1000>;
+		reg-cam-base = <0xc1000>;
+		interrupt-names = "csid2";
+		interrupts = <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_2_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_2_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_2_CSID_CLK>,
+			<&camcc CAM_CC_IFE_2_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_2_CLK_SRC>,
+			<&camcc CAM_CC_IFE_2_CLK>,
+			<&camcc CAM_CC_IFE_2_AXI_CLK>;
+		clock-rates =
+			<300000000 0 0 380000000 0 0>,
+			<400000000 0 0 510000000 0 0>,
+			<400000000 0 0 637000000 0 0>,
+			<400000000 0 0 760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+		operating-points-v2 = <&csid2_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe2: qcom,vfe2 {
+		cell-index = <2>;
+		compatible = "qcom,vfe165_160";
+		reg-names = "ife";
+		reg = <0x0 0x0acbd000 0x0 0x5200>;
+		reg-cam-base = <0xbd000>;
+		interrupt-names = "ife2";
+		interrupts = <GIC_SPI 641 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_2_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_2_CLK_SRC>,
+			<&camcc CAM_CC_IFE_2_CLK>,
+			<&camcc CAM_CC_IFE_2_AXI_CLK>;
+		clock-rates =
+			<380000000 0 0>,
+			<510000000 0 0>,
+			<637000000 0 0>,
+			<760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+		operating-points-v2 = <&vfe2_opp_table>;
+
+		clock-control-debugfs = "true";
+		clock-names-option =  "ife_dsp_clk";
+		clocks-option = <&camcc CAM_CC_IFE_2_DSP_CLK>;
+		clock-rates-option = <760000000>;
+		cam_hw_pid = <3 10>;
+		status = "ok";
+		vfe2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite0: qcom,csid-lite0 {
+		cell-index = <3>;
+		compatible = "qcom,csid-lite165";
+		reg-names = "csid-lite";
+		reg = <0x0 0xacc8000 0x0 0x1000>;
+		reg-cam-base = <0xc8000>;
+		interrupt-names = "csid-lite0";
+		interrupts = <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_LITE_0_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_0_CLK>;
+		clock-rates =
+			<300000000 0 0 320000000 0>,
+			<400000000 0 0 400000000 0>,
+			<400000000 0 0 480000000 0>,
+			<400000000 0 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+		operating-points-v2 = <&csid_lite0_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite0: qcom,vfe-lite0 {
+		cell-index = <3>;
+		compatible = "qcom,vfe-lite165";
+		reg-names = "ife-lite";
+		reg = <0x0 0xacc4000 0x0 0x5000>;
+		reg-cam-base = <0xc4000>;
+		interrupt-names = "ife-lite0";
+		interrupts = <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_LITE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_0_CLK>;
+		clock-rates =
+			<320000000 0>,
+			<400000000 0>,
+			<480000000 0>,
+			<600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+		operating-points-v2 = <&vfe_lite0_opp_table>;
+
+		clock-control-debugfs = "true";
+		cam_hw_pid = <11>;
+		status = "ok";
+		vfe_lite0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite1: qcom,csid-lite1 {
+		cell-index = <4>;
+		compatible = "qcom,csid-lite165";
+		reg-names = "csid-lite";
+		reg = <0x0 0x0accf000 0x0 0x1000>;
+		reg-cam-base = <0xcf000>;
+		interrupt-names = "csid-lite1";
+		interrupts = <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_LITE_1_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_1_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_1_CLK>;
+		clock-rates =
+			<300000000 0 0 320000000 0>,
+			<400000000 0 0 400000000 0>,
+			<400000000 0 0 480000000 0>,
+			<400000000 0 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+		operating-points-v2 = <&csid_lite1_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite1: qcom,vfe-lite1 {
+		cell-index = <4>;
+		compatible = "qcom,vfe-lite165";
+		reg-names = "ife-lite";
+		reg = <0x0 0x0accb000 0x0 0x5000>;
+		reg-cam-base = <0xcb000>;
+		interrupt-names = "ife-lite1";
+		interrupts = <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_LITE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_1_CLK>;
+		clock-rates =
+			<320000000 0>,
+			<400000000 0>,
+			<480000000 0>,
+			<600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+		operating-points-v2 = <&vfe_lite1_opp_table>;
+
+		clock-control-debugfs = "true";
+		cam_hw_pid = <12>;
+		status = "ok";
+		vfe_lite1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-icp {
+		compatible = "qcom,cam-icp";
+		compat-hw-name = "qcom,a5",
+			"qcom,ipe0",
+			"qcom,bps";
+		num-a5 = <1>;
+		num-ipe = <1>;
+		num-bps = <1>;
+		icp_pc_en;
+		status = "ok";
+	};
+
+	cam_a5: qcom,a5 {
+		cell-index = <0>;
+		compatible = "qcom,cam-a5";
+		reg = <0x0 0xac00000 0x0 0x6000>,
+			<0x0 0xac10000 0x0 0x8000>,
+			<0x0 0xac18000 0x0 0x3000>;
+		reg-names = "a5_qgic", "a5_sierra", "a5_csr";
+		reg-cam-base = <0x00000 0x10000 0x18000>;
+		interrupts = <GIC_SPI 463 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a5";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"soc_fast_ahb",
+			"icp_ahb_clk",
+			"icp_clk_src",
+			"icp_clk";
+		src-clock-name = "soc_fast_ahb";
+		clocks =
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_ICP_AHB_CLK>,
+			<&camcc CAM_CC_ICP_CLK_SRC>,
+			<&camcc CAM_CC_ICP_CLK>;
+		clock-rates =
+			<100000000 0 400000000 0>,
+			<200000000 0 400000000 0>,
+			<300000000 0 600000000 0>,
+			<400000000 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1",
+					"nominal";
+		operating-points-v2 = <&a5_opp_table>;
+
+		fw_name = "CAMERA_ICP_170.elf";
+		ubwc-ipe-fetch-cfg = <0x7073 0x707b>;
+		ubwc-ipe-write-cfg = <0x161cf 0x161ef>;
+		ubwc-bps-fetch-cfg = <0x7073 0x707b>;
+		ubwc-bps-write-cfg = <0x161cf 0x161ef>;
+		qos-val = <0x00000A0A>;
+		status = "ok";
+		a5_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_ipe0: qcom,ipe0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-ipe";
+		reg = <0x0 0xac87000 0x0 0xa000>;
+		reg-names = "ipe0_top";
+		reg-cam-base = <0x87000>;
+		power-domains = <&camcc CAM_CC_IPE_0_GDSC>;
+		clock-names =
+			"ipe_0_ahb_clk",
+			"ipe_0_areg_clk",
+			"ipe_0_axi_clk",
+			"ipe_0_clk_src",
+			"ipe_0_clk";
+		src-clock-name = "ipe_0_clk_src";
+		clock-control-debugfs = "true";
+		clocks =
+			<&camcc CAM_CC_IPE_0_AHB_CLK>,
+			<&camcc CAM_CC_IPE_0_AREG_CLK>,
+			<&camcc CAM_CC_IPE_0_AXI_CLK>,
+			<&camcc CAM_CC_IPE_0_CLK_SRC>,
+			<&camcc CAM_CC_IPE_0_CLK>;
+
+		clock-rates =
+			<0 0 0 300000000 0>,
+			<0 0 0 430000000 0>,
+			<0 0 0 520000000 0>,
+			<0 0 0 600000000 0>,
+			<0 0 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1",
+				"nominal", "turbo";
+		operating-points-v2 = <&ipe0_opp_table>;
+
+		status = "ok";
+		ipe0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-430000000 {
+				opp-hz = /bits/ 64 <430000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-520000000 {
+				opp-hz = /bits/ 64 <520000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_bps: qcom,bps {
+		cell-index = <0>;
+		compatible = "qcom,cam-bps";
+		reg = <0x0 0xac6f000 0x0 0x8000>;
+		reg-names = "bps_top";
+		reg-cam-base = <0x6f000>;
+		power-domains = <&camcc CAM_CC_BPS_GDSC>;
+		clock-names =
+			"bps_ahb_clk",
+			"bps_areg_clk",
+			"bps_axi_clk",
+			"bps_clk_src",
+			"bps_clk";
+		src-clock-name = "bps_clk_src";
+		clock-control-debugfs = "true";
+		clocks =
+			<&camcc CAM_CC_BPS_AHB_CLK>,
+			<&camcc CAM_CC_BPS_AREG_CLK>,
+			<&camcc CAM_CC_BPS_AXI_CLK>,
+			<&camcc CAM_CC_BPS_CLK_SRC>,
+			<&camcc CAM_CC_BPS_CLK>;
+
+		clock-rates =
+			<0 0 0 200000000 0>,
+			<0 0 0 400000000 0>,
+			<0 0 0 480000000 0>,
+			<0 0 0 600000000 0>,
+			<0 0 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1",
+				"nominal", "turbo";
+		operating-points-v2 = <&bps_opp_table>;
+
+		status = "ok";
+		bps_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-jpeg {
+		compatible = "qcom,cam-jpeg";
+		compat-hw-name = "qcom,jpegenc",
+			"qcom,jpegdma";
+		num-jpeg-enc = <1>;
+		num-jpeg-dma = <1>;
+		status = "ok";
+	};
+
+	cam_jpeg_enc: qcom,jpegenc {
+		cell-index = <0>;
+		compatible = "qcom,cam_jpeg_enc_165";
+		reg-names = "jpege_hw", "cam_camnoc";
+		reg = <0x0 0xac4e000 0x0 0x4000>,
+			<0x0 0x0ac9f000 0x0 0x10000>;
+		reg-cam-base = <0x4e000 0x9f000>;
+		interrupt-names = "jpeg";
+		interrupts = <GIC_SPI 474 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"jpegenc_clk_src",
+			"jpegenc_clk";
+		clocks =
+			<&camcc CAM_CC_JPEG_CLK_SRC>,
+			<&camcc CAM_CC_JPEG_CLK>;
+
+		clock-rates = <600000000 0>;
+		src-clock-name = "jpegenc_clk_src";
+		operating-points-v2 = <&jpeg_enc_opp_table>;
+
+		clock-cntl-level = "nominal";
+		cam_hw_pid = <22 23>;
+		cam_hw_rd_mid = <0>;
+		cam_hw_wr_mid = <2>;
+		status = "ok";
+		jpeg_enc_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_jpeg_dma: qcom,jpegdma {
+		cell-index = <0>;
+		compatible = "qcom,cam_jpeg_dma_165";
+		reg-names = "jpegdma_hw", "cam_camnoc";
+		reg = <0x0 0xac52000 0x0 0x4000>,
+			<0x0 0x0ac9f000 0x0 0x10000>;
+		reg-cam-base = <0x52000 0x9f000>;
+		interrupt-names = "jpegdma";
+		interrupts = <GIC_SPI 475 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"jpegdma_clk_src",
+			"jpegdma_clk";
+		clocks =
+			<&camcc CAM_CC_JPEG_CLK_SRC>,
+			<&camcc CAM_CC_JPEG_CLK>;
+
+		clock-rates = <600000000 0>;
+		src-clock-name = "jpegdma_clk_src";
+		operating-points-v2 = <&jpeg_dma_opp_table>;
+
+		clock-cntl-level = "nominal";
+		cam_hw_pid = <20 21>;
+		cam_hw_rd_mid = <0>;
+		cam_hw_wr_mid = <2>;
+		status = "ok";
+		jpeg_dma_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-lrme {
+		compatible = "qcom,cam-lrme";
+		arch-compat = "lrme";
+		status = "ok";
+	};
+
+	cam_lrme: qcom,lrme {
+		cell-index = <0>;
+		compatible = "qcom,lrme";
+		reg-names = "lrme";
+		reg = <0x0 0xac6b000 0x0 0x1000>;
+		reg-cam-base = <0x6b000>;
+		interrupt-names = "lrme";
+		interrupts = <GIC_SPI 476 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "lrme_clk_src",
+			"lrme_clk";
+		clocks = <&camcc CAM_CC_LRME_CLK_SRC>,
+			<&camcc CAM_CC_LRME_CLK>;
+		clock-rates = <240000000 0>,
+			<300000000 0>,
+			<320000000 0>,
+			<400000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal";
+		src-clock-name = "lrme_clk_src";
+		operating-points-v2 = <&lrme_opp_table>;
+
+		status = "ok";
+		lrme_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-240000000 {
+				opp-hz = /bits/ 64 <240000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-cpas {
+		cell-index = <0>;
+		compatible = "qcom,cam-cpas";
+		label = "cpas";
+		arch-compat = "cpas_top";
+		status = "ok";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg-names = "cam_cpas_top", "cam_camnoc";
+		reg = <0x0 0x0ac40000 0x0 0x1000>,
+			<0x0 0x0ac9f000 0x0 0x10000>;
+		reg-cam-base = <0x40000 0x9f000>;
+		cam_hw_fuse = <CAM_CPAS_ISP_FUSE 0x7801FC 0x10 CAM_CPAS_FEATURE_TYPE_DISABLE 0x4>,
+			      <CAM_CPAS_ISP_LITE_FUSE 0x7801FC 0x20 CAM_CPAS_FEATURE_TYPE_DISABLE 0x10>,
+			      <CAM_CPAS_SHDR_FUSE 0x7801FC 0x40 CAM_CPAS_FEATURE_TYPE_DISABLE 0xFF>,
+			      <CAM_CPAS_QCFA_BINNING_ENABLE 0x7801FC 0x80 CAM_CPAS_FEATURE_TYPE_DISABLE 0xFF>,
+			      <CAM_CPAS_CSIPHY_FUSE 0x7801FC 0x100 CAM_CPAS_FEATURE_TYPE_DISABLE 0x10>,
+			      <CAM_CPAS_RT_OT_FUSE 0x7801A4 0x10000000 CAM_CPAS_FEATURE_TYPE_DISABLE 0xFF>;
+		interrupt-names = "cpas_camnoc";
+		interrupts = <GIC_SPI 459 IRQ_TYPE_EDGE_RISING>;
+		camnoc-axi-min-ib-bw = <3000000000>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"gcc_camera_hf_axi_clk",
+			"gcc_camera_sf_axi_clk",
+			"cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk",
+			"cam_cc_camnoc_axi_clk_src",
+			"cam_cc_camnoc_axi_clk",
+			"cam_cc_icp_ahb_clk",
+			"cam_cc_icp_clk";
+		clocks =
+			<&gcc GCC_CAMERA_HF_AXI_CLK>,
+			<&gcc GCC_CAMERA_SF_AXI_CLK>,
+			<&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>,
+			<&camcc CAM_CC_CAMNOC_AXI_CLK_SRC>,
+			<&camcc CAM_CC_CAMNOC_AXI_CLK>,
+			<&camcc CAM_CC_ICP_AHB_CLK>,
+			<&camcc CAM_CC_ICP_CLK>;
+		src-clock-name = "cam_cc_camnoc_axi_clk_src";
+		clock-rates =
+			<0 0 0 0 0 0 0 0>,
+			<0 0 80000000 0 150000000 0 0 0>,
+			<0 0 80000000 0 240000000 0 0 0>,
+			<0 0 80000000 0 320000000 0 0 0>,
+			<0 0 80000000 0 400000000 0 0 0>,
+			<0 0 80000000 0 480000000 0 0 0>;
+		clock-cntl-level = "suspend", "lowsvs", "svs",
+			"svs_l1", "nominal", "turbo";
+		operating-points-v2 = <&cpas_opp_table>;
+		control-camnoc-axi-clk;
+		camnoc-bus-width = <32>;
+		camnoc-axi-clk-bw-margin-perc = <20>;
+		interconnect-names = "cam_ahb", "cam_hf_0", "cam_sf_0", "cam_sf_icp";
+		interconnects =<&gem_noc MASTER_APPSS_PROC 0
+			&cnoc2 SLAVE_CAMERA_CFG 0>,
+				<&mmss_noc MASTER_CAMNOC_HF 0
+			&mc_virt SLAVE_EBI1 0>,
+				<&mmss_noc MASTER_CAMNOC_SF 0
+			&mc_virt SLAVE_EBI1 0>,
+				<&mmss_noc MASTER_CAMNOC_ICP 0
+			&mc_virt SLAVE_EBI1 0>;
+
+		cam-ahb-num-cases = <7>;
+		cam-ahb-bw-KBps =
+			<0 0>, <0 76800>, <0 150000>, <0 150000>,
+			<0 300000>, <0 300000>, <0 300000>;
+		vdd-corners = <RPMH_REGULATOR_LEVEL_RETENTION
+			RPMH_REGULATOR_LEVEL_MIN_SVS
+			RPMH_REGULATOR_LEVEL_LOW_SVS
+			RPMH_REGULATOR_LEVEL_SVS
+			RPMH_REGULATOR_LEVEL_SVS_L1
+			RPMH_REGULATOR_LEVEL_NOM
+			RPMH_REGULATOR_LEVEL_NOM_L1
+			RPMH_REGULATOR_LEVEL_NOM_L2
+			RPMH_REGULATOR_LEVEL_TURBO
+			RPMH_REGULATOR_LEVEL_TURBO_L1>;
+		vdd-corner-ahb-mapping = "suspend",
+			"lowsvs", "lowsvs", "svs", "svs_l1",
+			"nominal", "nominal", "nominal",
+			"turbo", "turbo";
+		client-id-based;
+		client-names =
+			"csiphy0", "csiphy1", "csiphy2", "csiphy3",
+			"csiphy4", "cci0", "cci1",
+			"csid0", "csid1", "csid2", "csid3", "csid4",
+			"ife0", "ife1", "ife2", "ife3", "ife4",
+			"ipe0", "cam-cdm-intf0", "cpas-cdm0",
+			"bps0", "icp0", "jpeg-dma0", "jpeg-enc0",
+			"lrmecpas0";
+
+		cpas_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-150000000 {
+				opp-hz = /bits/ 64 <150000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-240000000 {
+				opp-hz = /bits/ 64 <240000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_turbo>;
+			};
+		};
+		camera-bus-nodes {
+			level0-nodes {
+				level-index = <0>;
+				ife0_rdi_wr: ife0-rdi-wr {
+					cell-index = <16>;
+					node-name = "ife0-rdi-wr";
+					client-name = "ife0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife1_rdi_wr: ife1-rdi-wr {
+					cell-index = <17>;
+					node-name = "ife1-rdi-wr";
+					client-name = "ife1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife2_rdi_wr: ife2-rdi-wr {
+					cell-index = <18>;
+					node-name = "ife2-rdi-wr";
+					client-name = "ife2";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife3_rdi_wr: ife3-rdi-wr {
+					cell-index = <19>;
+					node-name = "ife3-rdi-wr";
+					client-name = "ife3";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife4_rdi_wr: ife4-rdi-wr {
+					cell-index = <20>;
+					node-name = "ife4-rdi-wr";
+					client-name = "ife4";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife0_pixelall_wr: ife0-pixelall-wr {
+					cell-index = <21>;
+					node-name = "ife0-pixelall-wr";
+					client-name = "ife0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_PIXEL_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_DISP
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt1_write0>;
+				};
+
+				ife1_pixelall_wr: ife1-pixelall-wr {
+					cell-index = <22>;
+					node-name = "ife1-pixelall-wr";
+					client-name = "ife1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_PIXEL_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_DISP
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt1_write0>;
+				};
+
+				ife2_pixelall_wr: ife2-pixelall-wr {
+					cell-index = <23>;
+					node-name = "ife2-pixelall-wr";
+					client-name = "ife2";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_PIXEL_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_DISP
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt1_write1>;
+				};
+
+				ipe0_ref_wr: ipe0-ref-wr {
+					cell-index = <24>;
+					node-name = "ipe0-ref-wr";
+					client-name = "ipe0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IPE_WR_REF>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt0_write0>;
+				};
+
+				bps0_all_wr: bps0-all-wr {
+					cell-index = <25>;
+					node-name = "bps0-all-wr";
+					client-name = "bps0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt0_write0>;
+				};
+
+				lrme0_all_wr: lrme0-all-wr {
+					cell-index = <26>;
+					node-name = "lrme0-all-wr";
+					client-name = "lrmecpas0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt0_write0>;
+				};
+
+				ipe0_viddisp_wr: ipe0-viddisp-wr {
+					cell-index = <27>;
+					node-name = "ipe0-viddisp-wr";
+					client-name = "ipe0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IPE_WR_VID_DISP>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IPE_WR_VID
+					CAM_CPAS_PATH_DATA_IPE_WR_DISP>;
+					parent-node = <&level1_nrt0_write0>;
+				};
+
+				ipe0_all_rd: ipe0-all-rd {
+					cell-index = <28>;
+					node-name = "ipe0-all-rd";
+					client-name = "ipe0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IPE_RD_IN
+					CAM_CPAS_PATH_DATA_IPE_RD_REF>;
+					parent-node = <&level1_nrt0_read0>;
+				};
+
+				bps0_all_rd: bps0-all-rd {
+					cell-index = <29>;
+					node-name = "bps0-all-rd";
+					client-name = "bps0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt0_read0>;
+				};
+
+				lrme0_all_rd: lrme0-all-rd {
+					cell-index = <30>;
+					node-name = "lrme0-all-rd";
+					client-name = "lrmecpas0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt0_read0>;
+				};
+
+				jpeg_enc0_all_wr: jpeg-enc0-all-wr {
+					cell-index = <31>;
+					node-name = "jpeg-enc0-all-wr";
+					client-name = "jpeg-enc0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt1_write0>;
+				};
+
+				jpeg_enc0_all_rd: jpeg-enc0-all-rd {
+					cell-index = <32>;
+					node-name = "jpeg-enc0-all-rd";
+					client-name = "jpeg-enc0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt1_read0>;
+				};
+
+				jpeg_dma0_all_wr: jpeg-dma0-all-wr {
+					cell-index = <33>;
+					node-name = "jpeg-dma0-all-wr";
+					client-name = "jpeg-dma0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt1_write0>;
+				};
+
+				jpeg_dma0_all_rd: jpeg-dma0-all-rd {
+					cell-index = <34>;
+					node-name = "jpeg-dma0-all-rd";
+					client-name = "jpeg-dma0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt1_read0>;
+				};
+
+				cpas_cdm0_all_rd: cpas-cdm0-all-rd {
+					cell-index = <35>;
+					node-name = "cpas-cdm0-all-rd";
+					client-name = "cpas-cdm0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level2_nrt0_read0>;
+				};
+
+				icp0_all_rd: icp0-all-rd {
+					cell-index = <36>;
+					node-name = "icp0-all-rd";
+					client-name = "icp0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level2_nrt1_read0>;
+				};
+			};
+			level1-nodes {
+				level-index = <1>;
+				camnoc-max-needed;
+				level1_rt0_write0: level1-rt0-write0 {
+					cell-index = <8>;
+					node-name = "level1-rt0-write0";
+					parent-node = <&level2_rt0_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_rt1_write0: level1-rt1-write0 {
+					cell-index = <9>;
+					node-name = "level1-rt1-write0";
+					parent-node = <&level2_rt1_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_rt1_write1: level1-rt1-write1 {
+					cell-index = <10>;
+					node-name = "level1-rt1-write1";
+					parent-node = <&level2_rt1_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt0_write0: level1-nrt0-write0 {
+					cell-index = <11>;
+					node-name = "level1-nrt0-write0";
+					parent-node = <&level2_nrt0_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt0_read0: level1-nrt0-read0 {
+					cell-index = <12>;
+					node-name = "level1-nrt0-read0";
+					parent-node = <&level2_nrt0_read0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt1_write0: level1-nrt1-write0 {
+					cell-index = <13>;
+					node-name = "level1-nrt1-write0";
+					parent-node = <&level2_nrt0_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt1_read0: level1-nrt1-read0 {
+					cell-index = <14>;
+					node-name = "level1-nrt1-read0";
+					parent-node = <&level2_nrt0_read0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+			};
+			level2-nodes {
+				level-index = <3>;
+				camnoc-max-needed;
+				level2_rt0_write0: level2-rt0-write0 {
+					cell-index = <3>;
+					node-name = "level2-rt0-write0";
+					parent-node = <&level3_rt0_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM_INTERLEAVE>;
+				};
+
+				level2_rt1_write0: level2-rt1-write0 {
+					cell-index = <4>;
+					node-name = "level2-rt1-write0";
+					parent-node = <&level3_rt0_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM_INTERLEAVE>;
+				};
+
+				level2_nrt0_write0: level2-nrt0-write0 {
+					cell-index = <5>;
+					node-name = "level2-nrt0-write0";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt0_read0: level2-nrt0-read0 {
+					cell-index = <6>;
+					node-name = "level2-nrt0-read0";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt1_read0: level2-nrt1-read0 {
+					cell-index = <7>;
+					node-name = "level2-nrt1-read0";
+					parent-node = <&level3_nrt1_rd_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					bus-width-factor = <4>;
+				};
+			};
+			level3-nodes {
+				level-index = <3>;
+				level3_rt0_wr_sum: level3-rt0-wr-sum {
+					cell-index = <0>;
+					node-name = "level3-rt0-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					ib-bw-voting-needed;
+					qcom,axi-port-mnoc {
+						interconnect-names = "cam_hf_0";
+						interconnects =
+						<&mmss_noc MASTER_CAMNOC_HF 0
+						&mc_virt SLAVE_EBI1 0>;
+					};
+				};
+
+				level3_nrt0_rd_wr_sum: level3-nrt0-rd-wr-sum {
+					cell-index = <1>;
+					node-name = "level3-nrt0-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					qcom,axi-port-mnoc {
+						interconnect-names = "cam_sf_0";
+						interconnects =
+						<&mmss_noc MASTER_CAMNOC_SF 0
+						&mc_virt SLAVE_EBI1 0>;
+					};
+				};
+
+				level3_nrt1_rd_sum: level3-nrt1-rd-sum {
+					cell-index = <2>;
+					node-name = "level3-nrt1-rd-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					qcom,axi-port-mnoc {
+						interconnect-names = "cam_sf_icp";
+						interconnects =
+						<&mmss_noc MASTER_CAMNOC_ICP 0
+						&mc_virt SLAVE_EBI1 0>;
+					};
+				};
+			};
+		};
+	};
+};
\ No newline at end of file
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-camera-rubikpi3.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-camera-rubikpi3.dtso
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Thundercomm All rights reserved.
+ */
+/dts-v1/;
+/plugin/;
+
+#include "qcm6490-camera-rubikpi3.dtsi"
+#include "qcm6490-camera-sensor-rubikpi3.dtsi"
\ No newline at end of file
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-camera-sensor-idp.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-camera-sensor-idp.dtsi
@@ -0,0 +1,506 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <dt-bindings/msm-camera.h>
+
+&soc {
+
+	led_flash_triple_rear: qcom,camera-flash@4 {
+		cell-index = <4>;
+		compatible = "qcom,camera-flash";
+		status = "disabled";
+	};
+
+	led_flash_triple_rear_aux: qcom,camera-flash@5 {
+		cell-index = <5>;
+		compatible = "qcom,camera-flash";
+		status = "disabled";
+	};
+
+	led_flash_triple_rear_aux2: qcom,camera-flash@6 {
+		cell-index = <6>;
+		compatible = "qcom,camera-flash";
+		status = "disabled";
+	};
+
+	qcom,cam-res-mgr {
+		compatible = "qcom,cam-res-mgr";
+		status = "ok";
+	};
+};
+
+&cam_cci0 {
+
+	actuator_triple_wide: qcom,actuator0 {
+		cell-index = <4>;
+		compatible = "qcom,actuator";
+		cci-master = <0>;
+		cam_vaf-supply = <&L7I>;
+		regulator-names = "cam_vaf";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <2960000>;
+		rgltr-max-voltage = <3000000>;
+		rgltr-load-current = <103000>;
+	};
+
+	actuator_triple_tele: qcom,actuator1 {
+		cell-index = <5>;
+		compatible = "qcom,actuator";
+		cci-master = <1>;
+		cam_vaf-supply = <&L7I>;
+		regulator-names = "cam_vaf";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <2960000>;
+		rgltr-max-voltage = <3000000>;
+		rgltr-load-current = <103000>;
+	};
+
+	eeprom_triple_wide: qcom,eeprom0 {
+		cell-index = <4>;
+		compatible = "qcom,eeprom";
+		cam_vio-supply = <&L3J>;
+		cam_vana-supply = <&L3I>;
+		cam_vana1-supply = <&L5I>;
+		cam_vdig-supply = <&L1I>;
+		cam_vaf-supply = <&L7I>;
+		regulator-names = "cam_vio", "cam_vana", "cam_vana1",
+			"cam_vdig", "cam_vaf";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1800000 2904000 1800000 1104000 2960000>;
+		rgltr-max-voltage = <1800000 3000000 1900000 1200000 3000000>;
+		rgltr-load-current = <5000 68000 74000 805000 103000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_active
+				&cam_sensor_active_rst0>;
+		pinctrl-1 = <&cam_sensor_mclk0_suspend
+				&cam_sensor_suspend_rst0>;
+		gpios = <&tlmm 64 0>,
+			<&tlmm 20 0>;
+		gpio-reset = <1>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <1 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK0",
+					"CAM_RESET0";
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	eeprom_triple_tele: qcom,eeprom1 {
+		cell-index = <5>;
+		compatible = "qcom,eeprom";
+		cam_vio-supply = <&L3J>;
+		cam_vana-supply = <&L4I>;
+		cam_vdig-supply = <&L2I>;
+		cam_vaf-supply = <&L7I>;
+		regulator-names = "cam_vio", "cam_vana", "cam_vdig",
+			"cam_vaf";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1800000 2800000 1056000 2960000>;
+		rgltr-max-voltage = <1800000 2900000 1150000 3000000>;
+		rgltr-load-current = <10000 52000 140000 103000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active
+				 &cam_sensor_active_rst1>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend
+				 &cam_sensor_suspend_rst1>;
+		gpios = <&tlmm 65 0>,
+			<&tlmm 21 0>;
+		gpio-reset = <1>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <1 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK1",
+					"CAM_RESET1";
+		cci-master = <1>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/* Rear (W) */
+	idp_slot0: qcom,cam-sensor0 {
+		cell-index = <4>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <0>;
+		sensor-position-roll = <90>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		actuator-src = <&actuator_triple_wide>;
+		eeprom-src = <&eeprom_triple_wide>;
+		led-flash-src = <&led_flash_triple_rear>;
+		cam_vio-supply = <&L3J>;
+		cam_vana-supply = <&L3I>;
+		cam_vaf-supply = <&L7I>;
+		cam_v_custom1-supply = <&L5I>;
+		cam_vdig-supply = <&L1I>;
+		cam_bob-supply = <&vreg_bob_3p296>;
+		regulator-names = "cam_vio", "cam_vana", "cam_vaf", "cam_v_custom1",
+			"cam_vdig", "cam_bob";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1800000 2904000 2960000 1800000 1104000 3296000>;
+		rgltr-max-voltage = <1800000 3000000 3000000 1900000 1200000 3960000>;
+		rgltr-load-current = <5000 68000 103000 74000 805000 2000000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_active
+				&cam_sensor_active_rst0>;
+		pinctrl-1 = <&cam_sensor_mclk0_suspend
+				&cam_sensor_suspend_rst0>;
+		gpios = <&tlmm 64 0>,
+			<&tlmm 20 0>;
+		gpio-reset = <1>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <1 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK0",
+					"CAM_RESET0";
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/* Rear-aux (T) */
+	idp_slot1: qcom,cam-sensor1 {
+		cell-index = <5>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <1>;
+		sensor-position-roll = <90>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		eeprom-src = <&eeprom_triple_tele>;
+		actuator-src = <&actuator_triple_tele>;
+		led-flash-src = <&led_flash_triple_rear_aux>;
+		cam_vio-supply = <&L3J>;
+		cam_vana-supply = <&L4I>;
+		cam_vaf-supply = <&L7I>;
+		cam_vdig-supply = <&L2I>;
+		cam_bob-supply = <&vreg_bob_3p296>;
+		regulator-names = "cam_vio", "cam_vana", "cam_vaf", "cam_vdig",
+			"cam_bob";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1800000 2800000 2960000 1056000 3296000>;
+		rgltr-max-voltage = <1800000 2900000 3000000 1150000 3960000>;
+		rgltr-load-current = <10000 52000 103000 140000 2000000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active
+				&cam_sensor_active_rst1>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend
+				&cam_sensor_suspend_rst1>;
+		gpios = <&tlmm 65 0>,
+			<&tlmm 21 0>;
+		gpio-reset = <1>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <1 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK1",
+					"CAM_RESET1";
+		cci-master = <1>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	eeprom_tof: qcom,eeprom4 {
+		cell-index = <7>;
+		compatible = "qcom,eeprom";
+		cam_vio-supply = <&L3J>;
+		cam_vana-supply = <&L3I>;
+		regulator-names = "cam_vio", "cam_vana";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1800000 2904000>;
+		rgltr-max-voltage = <1800000 3000000>;
+		rgltr-load-current = <2000 20000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active
+				&cam_sensor_active_rst1>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend
+				&cam_sensor_suspend_rst1>;
+		gpios = <&tlmm 65 0>,
+			<&tlmm 21 0>;
+		gpio-reset = <1>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <1 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK1",
+					"CAM_RESET1";
+		cci-master = <1>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "turbo";
+		clock-rates = <24000000>;
+	};
+
+	/* TOF */
+	qcom,cam-sensor5 {
+		cell-index = <7>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <1>;
+		sensor-position-roll = <270>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		eeprom-src = <&eeprom_tof>;
+		cam_vio-supply = <&L3J>;
+		cam_vana-supply = <&L3I>;
+		regulator-names = "cam_vio", "cam_vana";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1800000 2904000>;
+		rgltr-max-voltage = <1800000 3000000>;
+		rgltr-load-current = <2000 20000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active
+				&cam_sensor_active_rst1>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend
+				&cam_sensor_suspend_rst1>;
+		gpios = <&tlmm 65 0>,
+			<&tlmm 21 0>,
+			<&tlmm 0 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags = <1 0 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK1",
+					"CAM_RESET1",
+					"CUSTOM_GPIO1";
+		cci-master = <1>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "turbo";
+		clock-rates = <24000000>;
+	};
+};
+
+&cam_cci1 {
+	actuator_triple_uw: qcom,actuator2 {
+		cell-index = <6>;
+		compatible = "qcom,actuator";
+		cci-master = <0>;
+		cam_vaf-supply = <&L7I>;
+		regulator-names = "cam_vaf";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <2960000>;
+		rgltr-max-voltage = <3000000>;
+		rgltr-load-current = <103000>;
+	};
+
+	eeprom_triple_uw: qcom,eeprom2 {
+		cell-index = <6>;
+		compatible = "qcom,eeprom";
+		cam_vio-supply = <&L3J>;
+		cam_vana-supply = <&L6I>;
+		cam_vdig-supply = <&L2I>;
+		cam_vaf-supply = <&L7I>;
+		regulator-names = "cam_vio", "cam_vana", "cam_vdig",
+			"cam_vaf";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1800000 2800000 1056000 2960000>;
+		rgltr-max-voltage = <1800000 2900000 1150000 3000000>;
+		rgltr-load-current = <3000 52000 257000 103000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_active
+				 &cam_sensor_active_rst2>;
+		pinctrl-1 = <&cam_sensor_mclk2_suspend
+				 &cam_sensor_suspend_rst2>;
+		gpios = <&tlmm 66 0>,
+			<&tlmm 77 0>;
+		gpio-reset = <1>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <1 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK2",
+					"CAM_RESET2";
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK2_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	eeprom_front: qcom,eeprom3 {
+		cell-index = <2>;
+		compatible = "qcom,eeprom";
+		cam_vio-supply = <&L3J>;
+		cam_vana-supply = <&L5J>;
+		cam_vdig-supply = <&L1J>;
+		regulator-names = "cam_vio", "cam_vana", "cam_vdig";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1800000 2800000 1056000>;
+		rgltr-max-voltage = <1800000 2900000 1150000>;
+		rgltr-load-current = <5000 35000 301000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk3_active
+				 &cam_sensor_active_rst3>;
+		pinctrl-1 = <&cam_sensor_mclk3_suspend
+				 &cam_sensor_suspend_rst3>;
+		gpios = <&tlmm 67 0>,
+			<&tlmm 78 0>;
+		gpio-reset = <1>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <1 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK3",
+					"CAM_RESET3";
+		cci-master = <1>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/* Rear-aux (UW) */
+	idp_slot2: qcom,cam-sensor2 {
+		cell-index = <6>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <2>;
+		sensor-position-roll = <90>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		eeprom-src = <&eeprom_triple_uw>;
+		actuator-src = <&actuator_triple_uw>;
+		led-flash-src = <&led_flash_triple_rear_aux2>;
+		cam_vio-supply = <&L3J>;
+		cam_vana-supply = <&L6I>;
+		cam_vaf-supply = <&L7I>;
+		cam_vdig-supply = <&L2I>;
+		cam_bob-supply = <&vreg_bob_3p296>;
+		regulator-names = "cam_vio", "cam_vana", "cam_vaf", "cam_vdig",
+			"cam_bob";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1800000 2800000 2960000 1056000 3296000>;
+		rgltr-max-voltage = <1800000 2900000 3000000 1150000 3960000>;
+		rgltr-load-current = <3000 52000 103000 257000 2000000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_active
+				 &cam_sensor_active_rst2>;
+		pinctrl-1 = <&cam_sensor_mclk2_suspend
+				 &cam_sensor_suspend_rst2>;
+		gpios = <&tlmm 66 0>,
+			<&tlmm 77 0>;
+		gpio-reset = <1>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <1 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK2",
+					"CAM_RESET2";
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK2_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/* Front */
+	idp_slot3: qcom,cam-sensor3 {
+		cell-index = <2>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <3>;
+		sensor-position-roll = <270>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <0>;
+		eeprom-src = <&eeprom_front>;
+		cam_vio-supply = <&L3J>;
+		cam_vana-supply = <&L5J>;
+		cam_vdig-supply = <&L1J>;
+		cam_bob-supply = <&vreg_bob_3p296>;
+		regulator-names = "cam_vio", "cam_vana", "cam_vdig",
+			"cam_bob";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1800000 2800000 1056000 3296000>;
+		rgltr-max-voltage = <1800000 2900000 1150000 3960000>;
+		rgltr-load-current = <5000 35000 301000 2000000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk3_active
+				 &cam_sensor_active_rst3>;
+		pinctrl-1 = <&cam_sensor_mclk3_suspend
+				 &cam_sensor_suspend_rst3>;
+		gpios = <&tlmm 67 0>,
+			<&tlmm 78 0>;
+		gpio-reset = <1>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <1 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK3",
+					"CAM_RESET3";
+		cci-master = <1>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/* Rear */
+	qcom,cam-sensor4 {
+		cell-index = <1>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <1>;
+		sensor-position-roll = <270>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		eeprom-src = <&eeprom_triple_uw>;
+		actuator-src = <&actuator_triple_uw>;
+		cam_vio-supply = <&L3J>;
+		cam_vana-supply = <&L6I>;
+		cam_vdig-supply = <&L2I>;
+		regulator-names = "cam_vio", "cam_vana", "cam_vdig";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1800000 2800000 1056000>;
+		rgltr-max-voltage = <1800000 2900000 1150000>;
+		rgltr-load-current = <3000 52000 257000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend", "cam_mux";
+		pinctrl-0 = <&cam_sensor_mclk2_active
+				&cam_sensor_active_rst2
+				&cam_sensor_active_mux>;
+		pinctrl-1 = <&cam_sensor_mclk2_suspend
+				&cam_sensor_suspend_rst2
+				&cam_sensor_suspend_mux>;
+		gpios = <&tlmm 66 0>,
+			<&tlmm 77 0>,
+			<&tlmm 1 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags = <1 0 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK2",
+					"CAM_RESET2",
+					"CAM_MUX";
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK2_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "turbo";
+		clock-rates = <24000000>;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-camera-sensor-rb3.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-camera-sensor-rb3.dtsi
@@ -0,0 +1,547 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <dt-bindings/msm-camera.h>
+
+&soc {
+	qcom,cam-res-mgr {
+		compatible = "qcom,cam-res-mgr";
+		status = "ok";
+		gpios-shared-pinctrl = <640>;
+		shared-pctrl-gpio-names = "gmsl";
+		pinctrl-names = "gmsl_active", "gmsl_suspend";
+		pinctrl-0 = <&cam_sensor_active_gmsl>;
+		pinctrl-1 = <&cam_sensor_suspend_gmsl>;
+	};
+};
+&tlmm {
+	cam_sensor_active_rst5: cam_sensor_active_rst5 {
+		/* RESET 5 */
+		mux {
+			pins = "gpio115";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio115";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst5: cam_sensor_suspend_rst5 {
+		/* RESET 5 */
+		mux {
+			pins = "gpio115";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio115";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_gmsl: cam_sensor_active_gmsl {
+		/* GMSL_ENABLE */
+		mux {
+			pins = "gpio93";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio93";
+			bias-pull-up;
+			drive-strength = <2>; /* 2 MA */
+			output-high;
+		};
+	};
+
+	cam_sensor_suspend_gmsl: cam_sensor_suspend_gmsl {
+		/* GMSL_ENABLE */
+		mux {
+			pins = "gpio93";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio93";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+};
+
+&cam_cci0 {
+	/*cam0a-ov9282*/
+	rb3_slot0a: qcom,cam-sensor1 {
+		cell-index = <1>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <0>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_l18b_1p8>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_active
+				&cam_sensor_active_rst0>;
+		pinctrl-1 = <&cam_sensor_mclk0_suspend
+				&cam_sensor_suspend_rst0>;
+		gpios = <&tlmm 64 0>,
+			<&tlmm 20 0>;
+		gpio-reset = <1>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <1 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK0",
+					"CAM_RESET0";
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+    /*cam1-ov9282*/
+	rb3_slot1: qcom,cam-sensor6 {
+		cell-index = <6>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <1>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_l18b_1p8>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active
+				&cam_sensor_active_rst1>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend
+				&cam_sensor_suspend_rst1>;
+		gpios = <&tlmm 65 0>,
+			<&tlmm 21 0>,
+			<&pm7250b_gpios 3 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags = <1 0 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK1",
+					"CAM_RESET1",
+					"CAM_CUSTOM1";
+		sensor-mode = <0>;
+		cci-master = <1>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	//cam1 interpose on dk csi0
+	actuator_rear_cam11: qcom,actuator11 {
+		cell-index = <11>;
+		compatible = "qcom,actuator";
+		cci-master = <1>;
+		regulator-names = "cam_vaf";
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <2856000>;
+		rgltr-max-voltage = <3104000>;
+		rgltr-load-current = <100000>;
+	};
+
+	eeprom_rear_cam11: qcom,eeprom11 {
+		cell-index = <11>;
+		compatible = "qcom,eeprom";
+		cam_vio-supply = <&vreg_l18b_1p8>;
+		regulator-names = "cam_vio", "cam_clk";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000 0>;
+		rgltr-max-voltage = <1800000 0>;
+		rgltr-load-current = <120000 0>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active
+				 &cam_sensor_active_rst1>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend
+				 &cam_sensor_suspend_rst1>;
+		gpios = <&tlmm 65 0>,
+			<&tlmm 21 0>,
+			<&pm7250b_gpios 3 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags = <1 0 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK1",
+					"CAM_RESET1",
+					"CAM_CUSTOM1";
+		sensor-mode = <0>;
+		cci-master = <1>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/*cam1-imx586/imx686*/
+	qcom,cam-sensor11 {
+		cell-index = <11>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <1>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		actuator-src = <&actuator_rear_cam11>;
+		eeprom-src = <&eeprom_rear_cam11>;
+		cam_vio-supply = <&vreg_l18b_1p8>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		regulator-names = "cam_vio", "cam_clk";
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000 0>;
+		rgltr-max-voltage = <1800000 0>;
+		rgltr-load-current = <120000 0>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active
+				&cam_sensor_active_rst1>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend
+				&cam_sensor_suspend_rst1>;
+		gpios = <&tlmm 65 0>,
+			<&tlmm 21 0>,
+			<&pm7250b_gpios 3 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags = <1 0 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK1",
+					"CAM_RESET1",
+					"CAM_CUSTOM1";
+		sensor-mode = <0>;
+		cci-master = <1>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+};
+
+&cam_cci1 {
+	eeprom_cam2: qcom,eeprom0 {
+		cell-index = <8>;
+		compatible = "qcom,eeprom";
+		cam_vio-supply = <&vreg_l18b_1p8>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_active
+				 &cam_sensor_active_rst2>;
+		pinctrl-1 = <&cam_sensor_mclk2_suspend
+				 &cam_sensor_suspend_rst2>;
+		gpios = <&tlmm 66 0>,
+			<&tlmm 77 0>,
+			<&pm7250b_gpios 7 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags = <1 0 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK2",
+					"CAM_RESET2",
+					"CAM_CUSTOM1";
+		sensor-mode = <0>;
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK2_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	eeprom_cam3: qcom,eeprom3 {
+		cell-index = <0>;
+		compatible = "qcom,eeprom";
+		cam_vio-supply = <&vreg_l18b_1p8>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk3_active
+			&cam_sensor_active_rst3>;
+		pinctrl-1 = <&cam_sensor_mclk3_suspend
+			&cam_sensor_suspend_rst3>;
+		gpios = <&tlmm 67 0>,
+			<&tlmm 78 0>;
+		gpio-reset = <1>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <1 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK3",
+			"CAM_RESET3";
+		sensor-position = <1>;
+		sensor-mode = <0>;
+		cci-master = <1>;
+		qcom,cam-power-seq-type ="cam_reset","cam_vio","cam_clk","cam_reset";
+		qcom,cam-power-seq-val = "cam_reset","cam_vio"
+			,"cam_mclk","cam_reset";
+		qcom,cam-power-seq-cfg-val = <0 1 24000000 1>;
+		qcom,cam-power-seq-delay = <1 0 1 18>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/*cam3-imx577*/
+	rb3_slot3: qcom,cam-sensor0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <3>;
+		eeprom-src = <&eeprom_cam3>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_l18b_1p8>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk3_active
+				&cam_sensor_active_rst3>;
+		pinctrl-1 = <&cam_sensor_mclk3_suspend
+				&cam_sensor_suspend_rst3>;
+		gpios = <&tlmm 67 0>,
+			<&tlmm 78 0>;
+		gpio-reset = <1>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <1 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK3",
+					"CAM_RESET3";
+		sensor-mode = <0>;
+		cci-master = <1>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/* GMSL 1 */
+	qcom,cam-sensor4 {
+		cell-index = <4>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <4>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_l18b_1p8>;
+		regulator-names = "cam_vio";
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		gpios = <&tlmm 93 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_4";
+		sensor-mode = <0>;
+		cci-master = <1>;
+		status = "ok";
+	};
+
+	/* GMSL 2 */
+	qcom,cam-sensor5 {
+		cell-index = <5>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <3>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_l18b_1p8>;
+		regulator-names = "cam_vio";
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		gpios = <&tlmm 93 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_5";
+		sensor-mode = <0>;
+		cci-master = <1>;
+		status = "ok";
+	};
+
+	/*cam0b-ov9282*/
+	rb3_slot0b: qcom,cam-sensor7 {
+		cell-index = <7>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <0>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_l18b_1p8>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk4_active
+			&cam_sensor_active_rst5>;
+		pinctrl-1 = <&cam_sensor_mclk4_suspend
+			&cam_sensor_suspend_rst5>;
+		gpios = <&tlmm 68 0>,
+			<&tlmm 149 0>;
+		gpio-reset = <1>;
+		gpio-req-tbl-num = <0 1>;
+		gpio-req-tbl-flags = <1 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK4",
+				"CAM_RESET5";
+		sensor-mode = <0>;
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK4_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/*cam2-imx577*/
+	rb3_slot2: qcom,cam-sensor8 {
+		cell-index = <8>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <2>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		eeprom-src = <&eeprom_cam2>;
+		cam_vio-supply = <&vreg_l18b_1p8>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_active
+				 &cam_sensor_active_rst2>;
+		pinctrl-1 = <&cam_sensor_mclk2_suspend
+				 &cam_sensor_suspend_rst2>;
+		gpios = <&tlmm 66 0>,
+			<&tlmm 77 0>,
+			<&pm7250b_gpios 7 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags = <1 0 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK2",
+					"CAM_RESET2",
+					"CAM_CUSTOM1";
+		sensor-mode = <0>;
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK2_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/* GMSL 3 */
+	qcom,cam-sensor9 {
+		cell-index = <9>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <4>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_l18b_1p8>;
+		regulator-names = "cam_vio";
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		gpios = <&tlmm 93 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_9";
+		sensor-mode = <0>;
+		cci-master = <1>;
+		status = "ok";
+	};
+
+	/* GMSL 4 */
+	qcom,cam-sensor10 {
+		cell-index = <10>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <4>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_l18b_1p8>;
+		regulator-names = "cam_vio";
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		gpios = <&tlmm 93 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_10";
+		sensor-mode = <0>;
+		cci-master = <1>;
+		status = "ok";
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-camera-sensor-rubikpi3.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-camera-sensor-rubikpi3.dtsi
@@ -0,0 +1,314 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Thundercomm All rights reserved.
+ */
+
+&soc {
+	camera1_vio_ldo: gpio-regulator@0 {
+		compatible = "regulator-fixed";
+		reg = <0x00 0x00>;
+		regulator-name = "camera1_vio_ldo";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-enable-ramp-delay = <233>;
+		enable-active-high;
+		gpio = <&tlmm 18 0>;
+		status = "ok";
+	};
+
+	camera2_vio_ldo: gpio-regulator@1 {
+		compatible = "regulator-fixed";
+		reg = <0x01 0x00>;
+		regulator-name = "camera2_vio_ldo";
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		regulator-enable-ramp-delay = <233>;
+		enable-active-high;
+		gpio = <&tlmm 19 0>;
+		status = "ok";
+	};
+
+	qcom,cam-res-mgr {
+		status = "ok";
+		compatible = "qcom,cam-res-mgr";
+	};
+};
+
+&tlmm {
+	cam_sensor_mclk2_active: cam_sensor_mclk2_active {
+		/* MCLK2 */
+		mux {
+			pins = "gpio66";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio66";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk2_suspend: cam_sensor_mclk2_suspend {
+		/* MCLK2 */
+		mux {
+			pins = "gpio66";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio66";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_active_rst2: cam_sensor_active_rst2 {
+		/* RESET 2 */
+		mux {
+			pins = "gpio58";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio58";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst2: cam_sensor_suspend_rst2 {
+		/* RESET 2 */
+		mux {
+			pins = "gpio58";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio58";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_mclk1_active: cam_sensor_mclk1_active {
+		/* MCLK1 */
+		mux {
+			pins = "gpio65";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio65";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk1_suspend: cam_sensor_mclk1_suspend {
+		/* MCLK1 */
+		mux {
+			pins = "gpio65";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio65";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_active_rst3: cam_sensor_active_rst3 {
+		/* RESET 3 */
+		mux {
+			pins = "gpio46";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio46";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst3: cam_sensor_suspend_rst3 {
+		/* RESET 3 */
+		mux {
+			pins = "gpio46";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio46";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_mclk0_active: cam_sensor_mclk0_active {
+		/* MCLK0 */
+		mux {
+			pins = "gpio64";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio64";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk0_suspend: cam_sensor_mclk0_suspend {
+		/* MCLK0 */
+		mux {
+			pins = "gpio64";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio64";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_active_rst4: cam_sensor_active_rst4 {
+		/* RESET 4 */
+		mux {
+			pins = "gpio57";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio57";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst4: cam_sensor_suspend_rst4 {
+		/* RESET 4 */
+		mux {
+			pins = "gpio57";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio57";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+};
+
+&soc {
+	qcom,cci0 {
+		qcom,actuator0 {
+			status = "disabled";
+		};
+
+		qcom,actuator1 {
+			status = "disabled";
+		};
+
+		qcom,eeprom0 {
+			status = "disabled";
+		};
+
+		qcom,eeprom1 {
+			status = "disabled";
+		};
+
+        /* camera2 */
+		qcom,cam-sensor1 {
+			cell-index = <1>;
+			compatible = "qcom,cam-sensor";
+			csiphy-sd-index = <4>;
+			sensor-position-roll = <0>;
+			sensor-position-pitch = <0>;
+			sensor-position-yaw = <0>;
+			cam_vio-supply = <&camera2_vio_ldo>;
+			regulator-names = "cam_vio";
+			power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+			rgltr-cntrl-support;
+			rgltr-min-voltage = <1800000>;
+			rgltr-max-voltage = <1800000>;
+			rgltr-load-current = <120000>;
+			gpio-no-mux = <0>;
+			pinctrl-names = "cam_default", "cam_suspend";
+			pinctrl-0 = <&cam_sensor_mclk2_active
+						&cam_sensor_active_rst2>;
+			pinctrl-1 = <&cam_sensor_mclk2_suspend
+						&cam_sensor_suspend_rst2>;
+			gpios = <&tlmm 66 0>, <&tlmm 58 0>;
+			gpio-reset = <1>;
+			gpio-req-tbl-num = <0 1>;
+			gpio-req-tbl-flags = <1 0>;
+			gpio-req-tbl-label = "CAMIF_MCLK2", "CAM_RESET2";
+			cci-master = <0>;
+			status = "ok";
+			clocks = <&camcc CAM_CC_MCLK2_CLK>;
+			clock-names = "cam_clk";
+			clock-cntl-level = "nominal";
+			clock-rates = <24000000>;
+		};
+
+		qcom,eeprom4 {
+			status = "disabled";
+		};
+	};
+
+	qcom,cci1 {
+		qcom,actuator2 {
+			status = "disabled";
+		};
+
+		qcom,eeprom2 {
+			status = "disabled";
+		};
+
+		qcom,eeprom3 {
+			status = "disabled";
+		};
+
+        /* camera1 */
+		qcom,cam-sensor0 {
+			cell-index = <0>;
+			compatible = "qcom,cam-sensor";
+			csiphy-sd-index = <1>;
+			sensor-position-roll = <0>;
+			sensor-position-pitch = <0>;
+			sensor-position-yaw = <0>;
+			cam_vio-supply = <&camera1_vio_ldo>;
+			regulator-names = "cam_vio";
+			power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+			rgltr-cntrl-support;
+			rgltr-min-voltage = <1800000>;
+			rgltr-max-voltage = <1800000>;
+			rgltr-load-current = <120000>;
+			gpio-no-mux = <0>;
+			pinctrl-names = "cam_default", "cam_suspend";
+			pinctrl-0 = <&cam_sensor_mclk0_active
+					&cam_sensor_active_rst4>;
+			pinctrl-1 = <&cam_sensor_mclk0_suspend
+					&cam_sensor_suspend_rst4>;
+			gpios = <&tlmm 64 0>, <&tlmm 57 0>;
+			gpio-reset = <1>;
+			gpio-req-tbl-num = <0 1>;
+			gpio-req-tbl-flags = <1 0>;
+			gpio-req-tbl-label = "CAMIF_MCLK0", "CAM_RESET4";
+			cci-master = <0>;
+			status = "ok";
+			clocks = <&camcc CAM_CC_MCLK0_CLK>;
+			clock-names = "cam_clk";
+			clock-cntl-level = "nominal";
+			clock-rates = <24000000>;
+		};
+	};
+};
\ No newline at end of file
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-camera.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-camera.dtsi
@@ -0,0 +1,2520 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <dt-bindings/msm-camera.h>
+
+&tlmm {
+	cci0_active: cci0_active {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio69","gpio70"; // Only 2
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio69","gpio70";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci0_suspend: cci0_suspend {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio69","gpio70";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio69","gpio70";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci1_active: cci1_active {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio71","gpio72";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio71","gpio72";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci1_suspend: cci1_suspend {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio71","gpio72";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio71","gpio72";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci2_active: cci2_active {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio73","gpio74";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio73","gpio74";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci2_suspend: cci2_suspend {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio73","gpio74";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio73","gpio74";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci3_active: cci3_active {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio75","gpio76";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio75","gpio76";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci3_suspend: cci3_suspend {
+		mux {
+			/* DATA, CLK */
+			pins = "gpio75","gpio76";
+			function = "cci_i2c";
+		};
+
+		config {
+			pins = "gpio75","gpio76";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+
+	};
+
+	cam_sensor_mclk0_active: cam_sensor_mclk0_active {
+		/* MCLK0 */
+		mux {
+			pins = "gpio64";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio64";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk0_suspend: cam_sensor_mclk0_suspend {
+		/* MCLK0 */
+		mux {
+			pins = "gpio64";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio64";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk1_active: cam_sensor_mclk1_active {
+		/* MCLK1 */
+		mux {
+			pins = "gpio65";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio65";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk1_suspend: cam_sensor_mclk1_suspend {
+		/* MCLK1 */
+		mux {
+			pins = "gpio65";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio65";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk2_active: cam_sensor_mclk2_active {
+		/* MCLK2 */
+		mux {
+			pins = "gpio66";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio66";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk2_suspend: cam_sensor_mclk2_suspend {
+		/* MCLK2 */
+		mux {
+			pins = "gpio66";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio66";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk3_active: cam_sensor_mclk3_active {
+		/* MCLK3 */
+		mux {
+			pins = "gpio67";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio67";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk3_suspend: cam_sensor_mclk3_suspend {
+		/* MCLK3 */
+		mux {
+			pins = "gpio67";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio67";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk4_active: cam_sensor_mclk4_active {
+		/* MCLK4 */
+		mux {
+			pins = "gpio68";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio68";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk4_suspend: cam_sensor_mclk4_suspend {
+		/* MCLK4 */
+		mux {
+			pins = "gpio68";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio68";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk5_active: cam_sensor_mclk5_active {
+		/* MCLK5 */
+		mux {
+			pins = "gpio98";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio98";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk5_suspend: cam_sensor_mclk5_suspend {
+		/* MCLK5 */
+		mux {
+			pins = "gpio98";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio98";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_active_rst0: cam_sensor_active_rst0 {
+		/* RESET REAR */
+		mux {
+			pins = "gpio20";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio20";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst0: cam_sensor_suspend_rst0 {
+		/* RESET REAR */
+		mux {
+			pins = "gpio20";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio20";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_rst1: cam_sensor_active_rst1 {
+		/* RESET REARAUX */
+		mux {
+			pins = "gpio21";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio21";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst1: cam_sensor_suspend_rst1 {
+		/* RESET REARAUX */
+		mux {
+			pins = "gpio21";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio21";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_rst2: cam_sensor_active_rst2 {
+		/* RESET 2 */
+		mux {
+			pins = "gpio77";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio77";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst2: cam_sensor_suspend_rst2 {
+		/* RESET 2 */
+		mux {
+			pins = "gpio77";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio77";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_rst3: cam_sensor_active_rst3 {
+		/* RESET 3 */
+		mux {
+			pins = "gpio78";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio78";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst3: cam_sensor_suspend_rst3 {
+		/* RESET 3 */
+		mux {
+			pins = "gpio78";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio78";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_rst4: cam_sensor_active_rst4 {
+		/* RESET 4 */
+		mux {
+			pins = "gpio79";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio79";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst4: cam_sensor_suspend_rst4 {
+		/* RESET 4 */
+		mux {
+			pins = "gpio79";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio79";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_mux: cam_sensor_active_mux {
+		/* GC630 bypass mux */
+		mux {
+			pins = "gpio1";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio1";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_mux: cam_sensor_suspend_mux {
+		/* GC630 bypass mux */
+		mux {
+			pins = "gpio1";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio1";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+};
+
+&soc {
+	qcom,cam-req-mgr {
+		compatible = "qcom,cam-req-mgr";
+		status = "ok";
+	};
+
+	qcom,cam-sync {
+		compatible = "qcom,cam-sync";
+		status = "ok";
+	};
+
+	cam_csiphy0: qcom,csiphy0 {
+		cell-index = <0>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0x0ace0000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe0000>;
+		interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy0";
+		operating-points-v2 = <&csiphy0_opp_table>;
+		refgen-supply = <&refgen>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY0_CLK>,
+			<&camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI0PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy0_clk",
+			"csi0phytimer_clk_src",
+			"csi0phytimer_clk";
+		src-clock-name = "csi0phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_csiphy1: qcom,csiphy1 {
+		cell-index = <1>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0xace2000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe2000>;
+		interrupts = <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy1";
+		operating-points-v2 = <&csiphy1_opp_table>;
+		refgen-supply = <&refgen>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY1_CLK>,
+			<&camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI1PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy1_clk",
+			"csi1phytimer_clk_src",
+			"csi1phytimer_clk";
+		src-clock-name = "csi1phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_csiphy2: qcom,csiphy2 {
+		cell-index = <2>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0xace4000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe4000>;
+		interrupts = <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy2";
+		refgen-supply = <&refgen>;
+		operating-points-v2 = <&csiphy2_opp_table>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY2_CLK>,
+			<&camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI2PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy2_clk",
+			"csi2phytimer_clk_src",
+			"csi2phytimer_clk";
+		src-clock-name = "csi2phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_csiphy3: qcom,csiphy3 {
+		cell-index = <3>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0xace6000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe6000>;
+		interrupts = <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy3";
+		refgen-supply = <&refgen>;
+		operating-points-v2 = <&csiphy3_opp_table>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY3_CLK>,
+			<&camcc CAM_CC_CSI3PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI3PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy3_clk",
+			"csi3phytimer_clk_src",
+			"csi3phytimer_clk";
+		src-clock-name = "csi3phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_csiphy4: qcom,csiphy4 {
+		cell-index = <4>;
+		compatible = "qcom,csiphy-v1.2.1", "qcom,csiphy";
+		reg = <0x0 0xace8000 0x0 0x2000>;
+		reg-names = "csiphy";
+		reg-cam-base = <0xe8000>;
+		interrupts = <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "csiphy4";
+		refgen-supply = <&refgen>;
+		operating-points-v2 = <&csiphy4_opp_table>;
+		csi-vdd-1p2-supply = <&vreg_l6b_1p2>;
+		csi-vdd-0p9-supply = <&vreg_l10c_0p88>;
+		regulator-names = "refgen", "csi-vdd-1p2",
+			"csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <0 1200000 880000>;
+		rgltr-max-voltage = <0 1260000 1050000>;
+		rgltr-load-current = <0 54000 96400>;
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY4_CLK>,
+			<&camcc CAM_CC_CSI4PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI4PHYTIMER_CLK>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy4_clk",
+			"csi4phytimer_clk_src",
+			"csi4phytimer_clk";
+		src-clock-name = "csi4phytimer_clk_src";
+		clock-cntl-level = "lowsvs", "svs";
+		clock-rates =
+			<300000000 0 300000000 0>,
+			<400000000 0 300000000 0>;
+		status = "ok";
+		csiphy4_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+		};
+	};
+
+	cam_cci0: qcom,cci0 {
+		cell-index = <0>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac4a000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x4a000>;
+		interrupt-names = "cci";
+		interrupts = <GIC_SPI 460 IRQ_TYPE_EDGE_RISING>;
+		status = "ok";
+		operating-points-v2 = <&cci0_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clocks = <&camcc CAM_CC_CCI_0_CLK_SRC>,
+			<&camcc CAM_CC_CCI_0_CLK>;
+		clock-names = "cci_0_clk_src",
+			"cci_0_clk";
+		src-clock-name = "cci_0_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates = <37500000 0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cci0_active &cci1_active>;
+		pinctrl-1 = <&cci0_suspend &cci1_suspend>;
+		gpios = <&tlmm 69 0>,
+			<&tlmm 70 0>,
+			<&tlmm 71 0>,
+			<&tlmm 72 0>;
+		gpio-req-tbl-num = <0 1 2 3>;
+		gpio-req-tbl-flags = <1 1 1 1>;
+		gpio-req-tbl-label = "CCI_I2C_DATA0",
+					"CCI_I2C_CLK0",
+					"CCI_I2C_DATA1",
+					"CCI_I2C_CLK1";
+		cci0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci0: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci0: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci0: qcom,i2c_custom_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci0: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	cam_cci1: qcom,cci1 {
+		cell-index = <1>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac4b000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x4b000>;
+		interrupt-names = "cci";
+		interrupts = <GIC_SPI 271 IRQ_TYPE_EDGE_RISING>;
+		status = "ok";
+		operating-points-v2 = <&cci1_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clocks = <&camcc CAM_CC_CCI_1_CLK_SRC>,
+			<&camcc CAM_CC_CCI_1_CLK>;
+		clock-names = "cci_1_clk_src",
+			"cci_1_clk";
+		src-clock-name = "cci_1_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates = <37500000 0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cci2_active &cci3_active>;
+		pinctrl-1 = <&cci2_suspend &cci3_suspend>;
+		gpios = <&tlmm 73 0>,
+			<&tlmm 74 0>,
+			<&tlmm 75 0>,
+			<&tlmm 76 0>;
+		gpio-req-tbl-num = <0 1 2 3>;
+		gpio-req-tbl-flags = <1 1 1 1>;
+		gpio-req-tbl-label = "CCI_I2C_DATA2",
+					"CCI_I2C_CLK2",
+					"CCI_I2C_DATA3",
+					"CCI_I2C_CLK3";
+		cci1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci1: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci1: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci1: qcom,i2c_custom_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci1: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	qcom,cam_smmu {
+		compatible = "qcom,msm-cam-smmu", "simple-bus";
+		status = "ok";
+		force_cache_allocs;
+
+		msm_cam_smmu_ife {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x800 0x4E0>,
+				<&apps_smmu 0x820 0x4E0>,
+				<&apps_smmu 0x840 0x4E0>,
+				<&apps_smmu 0x860 0x4E0>,
+				<&apps_smmu 0x880 0x4E0>,
+				<&apps_smmu 0x8A0 0x4E0>,
+				<&apps_smmu 0x8C0 0x4E0>,
+				<&apps_smmu 0x8E0 0x4E0>,
+				<&apps_smmu 0xC00 0x4E0>,
+				<&apps_smmu 0xC20 0x4E0>,
+				<&apps_smmu 0xC40 0x4E0>,
+				<&apps_smmu 0xC60 0x4E0>,
+				<&apps_smmu 0xC80 0x4E0>,
+				<&apps_smmu 0xCA0 0x4E0>,
+				<&apps_smmu 0xCC0 0x4E0>,
+				<&apps_smmu 0xCE0 0x4E0>;
+			cam-smmu-label = "ife";
+			multiple-client-devices;
+			dma-coherent;
+			ife_iova_mem_map: iova-mem-map {
+				/* IO region is approximately 4 GB */
+				iova-mem-region-io {
+					iova-region-name = "io";
+					iova-region-start = <0x100000>;
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_jpeg {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x20C0 0x20>,
+				<&apps_smmu 0x20E0 0x20>;
+			cam-smmu-label = "jpeg";
+			dma-coherent;
+			jpeg_iova_mem_map: iova-mem-map {
+				/* IO region is approximately 3.4 GB */
+				iova-mem-region-io {
+					iova-region-name = "io";
+					iova-region-start = <0x100000>;
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_icp_fw {
+			compatible = "qcom,msm-cam-smmu-fw-dev";
+			label="icp";
+			memory-region = <&camera_mem>;
+		};
+
+		msm_cam_smmu_icp {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x2000 0x20>,
+				<&apps_smmu 0x2020 0x20>,
+				<&apps_smmu 0x2062 0x0>,
+				<&apps_smmu 0x2080 0x20>,
+				<&apps_smmu 0x20A0 0x20>,
+				<&apps_smmu 0x2140 0x0>;
+			cam-smmu-label = "icp";
+			dma-coherent;
+			icp_iova_mem_map: iova-mem-map {
+				iova-mem-region-firmware {
+					/* Firmware region is 5MB */
+					iova-region-name = "firmware";
+					iova-region-start = <0x0>;
+					iova-region-len = <0x500000>;
+					iova-region-id = <0x0>;
+					status = "ok";
+				};
+
+				iova-mem-region-shared {
+					/* Shared region is 150MB long */
+					iova-region-name = "shared";
+					iova-region-start = <0x7400000>;
+					iova-region-len = <0x9600000>;
+					iova-region-id = <0x1>;
+					status = "ok";
+				};
+
+				iova-mem-region-secondary-heap {
+					/* Secondary heap region is 1MB long */
+					iova-region-name = "secheap";
+					iova-region-start = <0x10a00000>;
+					iova-region-len = <0x100000>;
+					iova-region-id = <0x4>;
+					status = "ok";
+				};
+
+				iova-mem-region-io {
+					/* IO region is approximately 3.7 GB */
+					iova-region-name = "io";
+					iova-region-start = <0x10c00000>;
+					iova-region-len = <0xcf300000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+
+				iova-mem-qdss-region {
+					/* QDSS region is appropriate 1MB */
+					iova-region-name = "qdss";
+					iova-region-start = <0x10b00000>;
+					iova-region-len = <0x100000>;
+					iova-region-id = <0x5>;
+					qdss-phy-addr = <0x16790000>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_cpas_cdm {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x2040 0x0>;
+			cam-smmu-label = "cpas-cdm";
+			dma-coherent;
+			cpas_cdm_iova_mem_map: iova-mem-map {
+				iova-mem-region-io {
+					/* IO region is approximately 3.4 GB */
+					iova-region-name = "io";
+					iova-region-start = <0x100000>;
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_lrme {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x2100 0x20>,
+				<&apps_smmu 0x2120 0x20>;
+			cam-smmu-label = "lrme";
+			dma-coherent;
+			lrme_iova_mem_map: iova-mem-map {
+				iova-mem-region-shared {
+					/* Shared region is 100MB long */
+					iova-region-name = "shared";
+					iova-region-start = <0x7400000>;
+					iova-region-len = <0x6400000>;
+					iova-region-id = <0x1>;
+					status = "ok";
+				};
+				/* IO region is approximately 3.3 GB */
+				iova-mem-region-io {
+					iova-region-name = "io";
+					iova-region-start = <0x100000>;
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_secure {
+			compatible = "qcom,msm-cam-smmu-cb";
+			cam-smmu-label = "cam-secure";
+			qcom,secure-cb;
+		};
+	};
+
+	qcom,cam-cdm-intf {
+		compatible = "qcom,cam-cdm-intf";
+		cell-index = <0>;
+		label = "cam-cdm-intf";
+		num-hw-cdm = <1>;
+		cdm-client-names = "vfe",
+			"jpegdma",
+			"jpegenc",
+			"lrmecdm";
+		status = "ok";
+	};
+
+	qcom,cpas-cdm0 {
+		cell-index = <0>;
+		compatible = "qcom,cam170-cpas-cdm0";
+		label = "cpas-cdm";
+		reg = <0x0 0xac48000 0x0 0x1000>;
+		reg-names = "cpas-cdm";
+		reg-cam-base = <0x48000>;
+		interrupts = <GIC_SPI 461 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "cpas-cdm";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_slow_ahb_clk_src";
+		clock-rates = <80000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table>;
+		clock-cntl-level = "svs";
+		cdm-client-names = "ife0", "ife1", "ife2",
+				   "ife3", "ife4", "dualife";
+		status = "ok";
+		cdm_cpas_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,cam-isp {
+		compatible = "qcom,cam-isp";
+		arch-compat = "ife";
+		status = "ok";
+	};
+
+	cam_csid0: qcom,csid0 {
+		cell-index = <0>;
+		compatible = "qcom,csid165_204";
+		reg-names = "csid";
+		reg = <0x0 0xacb3000 0x0 0x1000>;
+		reg-cam-base = <0xb3000>;
+		interrupt-names = "csid0";
+		interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_0_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_0_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_0_CSID_CLK>,
+			<&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_0_CLK>,
+			<&camcc CAM_CC_IFE_0_AXI_CLK>;
+		clock-rates =
+			<300000000 0 0 380000000 0 0>,
+			<400000000 0 0 510000000 0 0>,
+			<400000000 0 0 637000000 0 0>,
+			<400000000 0 0 760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+
+		operating-points-v2 = <&csid0_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe0: qcom,vfe0 {
+		cell-index = <0>;
+		compatible = "qcom,vfe165_160";
+		reg-names = "ife";
+		reg = <0x0 0xacaf000 0x0 0x5200>;
+		reg-cam-base = <0xaf000>;
+		interrupt-names = "ife0";
+		interrupts = <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_0_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_0_CLK>,
+			<&camcc CAM_CC_IFE_0_AXI_CLK>;
+		clock-rates =
+			<380000000 0 0>,
+			<510000000 0 0>,
+			<637000000 0 0>,
+			<760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+
+		operating-points-v2 = <&vfe0_opp_table>;
+		clock-control-debugfs = "true";
+		clock-names-option =  "ife_dsp_clk";
+		clocks-option = <&camcc CAM_CC_IFE_0_DSP_CLK>;
+		clock-rates-option = <760000000>;
+		cam_hw_pid = <24 8>;
+		status = "ok";
+		vfe0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid1: qcom,csid1 {
+		cell-index = <1>;
+		compatible = "qcom,csid165_204";
+		reg-names = "csid";
+		reg = <0x0 0xacba000 0x0 0x1000>;
+		reg-cam-base = <0xba000>;
+		interrupt-names = "csid1";
+		interrupts = <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_1_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_1_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_1_CSID_CLK>,
+			<&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_1_CLK>,
+			<&camcc CAM_CC_IFE_1_AXI_CLK>;
+		clock-rates =
+			<300000000 0 0 380000000 0 0>,
+			<400000000 0 0 510000000 0 0>,
+			<400000000 0 0 637000000 0 0>,
+			<400000000 0 0 760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+
+		operating-points-v2 = <&csid1_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe1: qcom,vfe1 {
+		cell-index = <1>;
+		compatible = "qcom,vfe165_160";
+		reg-names = "ife";
+		reg = <0x0 0xacb6000 0x0 0x5200>;
+		reg-cam-base = <0xb6000>;
+		interrupt-names = "ife1";
+		interrupts = <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_1_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_1_CLK>,
+			<&camcc CAM_CC_IFE_1_AXI_CLK>;
+		clock-rates =
+			<380000000 0 0>,
+			<510000000 0 0>,
+			<637000000 0 0>,
+			<760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+		operating-points-v2 = <&vfe1_opp_table>;
+
+		clock-control-debugfs = "true";
+		clock-names-option =  "ife_dsp_clk";
+		clocks-option = <&camcc CAM_CC_IFE_1_DSP_CLK>;
+		clock-rates-option = <760000000>;
+		cam_hw_pid = <25 9>;
+		status = "ok";
+		vfe1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid2: qcom,csid2 {
+		cell-index = <2>;
+		compatible = "qcom,csid165_204";
+		reg-names = "csid";
+		reg = <0x0 0x0acc1000 0x0 0x1000>;
+		reg-cam-base = <0xc1000>;
+		interrupt-names = "csid2";
+		interrupts = <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_2_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_2_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_2_CSID_CLK>,
+			<&camcc CAM_CC_IFE_2_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_2_CLK_SRC>,
+			<&camcc CAM_CC_IFE_2_CLK>,
+			<&camcc CAM_CC_IFE_2_AXI_CLK>;
+		clock-rates =
+			<300000000 0 0 380000000 0 0>,
+			<400000000 0 0 510000000 0 0>,
+			<400000000 0 0 637000000 0 0>,
+			<400000000 0 0 760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+		operating-points-v2 = <&csid2_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe2: qcom,vfe2 {
+		cell-index = <2>;
+		compatible = "qcom,vfe165_160";
+		reg-names = "ife";
+		reg = <0x0 0x0acbd000 0x0 0x5200>;
+		reg-cam-base = <0xbd000>;
+		interrupt-names = "ife2";
+		interrupts = <GIC_SPI 641 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_IFE_2_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk",
+			"ife_axi_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_2_CLK_SRC>,
+			<&camcc CAM_CC_IFE_2_CLK>,
+			<&camcc CAM_CC_IFE_2_AXI_CLK>;
+		clock-rates =
+			<380000000 0 0>,
+			<510000000 0 0>,
+			<637000000 0 0>,
+			<760000000 0 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+		operating-points-v2 = <&vfe2_opp_table>;
+
+		clock-control-debugfs = "true";
+		clock-names-option =  "ife_dsp_clk";
+		clocks-option = <&camcc CAM_CC_IFE_2_DSP_CLK>;
+		clock-rates-option = <760000000>;
+		cam_hw_pid = <3 10>;
+		status = "ok";
+		vfe2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-380000000 {
+				opp-hz = /bits/ 64 <380000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-510000000 {
+				opp-hz = /bits/ 64 <510000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-637000000 {
+				opp-hz = /bits/ 64 <637000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-760000000 {
+				opp-hz = /bits/ 64 <760000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite0: qcom,csid-lite0 {
+		cell-index = <3>;
+		compatible = "qcom,csid-lite165";
+		reg-names = "csid-lite";
+		reg = <0x0 0xacc8000 0x0 0x1000>;
+		reg-cam-base = <0xc8000>;
+		interrupt-names = "csid-lite0";
+		interrupts = <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_LITE_0_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_0_CLK>;
+		clock-rates =
+			<300000000 0 0 320000000 0>,
+			<400000000 0 0 400000000 0>,
+			<400000000 0 0 480000000 0>,
+			<400000000 0 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+		operating-points-v2 = <&csid_lite0_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite0: qcom,vfe-lite0 {
+		cell-index = <3>;
+		compatible = "qcom,vfe-lite165";
+		reg-names = "ife-lite";
+		reg = <0x0 0xacc4000 0x0 0x5000>;
+		reg-cam-base = <0xc4000>;
+		interrupt-names = "ife-lite0";
+		interrupts = <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_LITE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_0_CLK>;
+		clock-rates =
+			<320000000 0>,
+			<400000000 0>,
+			<480000000 0>,
+			<600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+		operating-points-v2 = <&vfe_lite0_opp_table>;
+
+		clock-control-debugfs = "true";
+		cam_hw_pid = <11>;
+		status = "ok";
+		vfe_lite0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite1: qcom,csid-lite1 {
+		cell-index = <4>;
+		compatible = "qcom,csid-lite165";
+		reg-names = "csid-lite";
+		reg = <0x0 0x0accf000 0x0 0x1000>;
+		reg-cam-base = <0xcf000>;
+		interrupt-names = "csid-lite1";
+		interrupts = <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"ife_csid_clk_src",
+			"ife_csid_clk",
+			"ife_cphy_rx_clk",
+			"ife_clk_src",
+			"ife_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_LITE_1_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_1_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_1_CLK>;
+		clock-rates =
+			<300000000 0 0 320000000 0>,
+			<400000000 0 0 400000000 0>,
+			<400000000 0 0 480000000 0>,
+			<400000000 0 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_csid_clk_src";
+		operating-points-v2 = <&csid_lite1_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite1: qcom,vfe-lite1 {
+		cell-index = <4>;
+		compatible = "qcom,vfe-lite165";
+		reg-names = "ife-lite";
+		reg = <0x0 0x0accb000 0x0 0x5000>;
+		reg-cam-base = <0xcb000>;
+		interrupt-names = "ife-lite1";
+		interrupts = <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"ife_clk_src",
+			"ife_clk";
+		clocks =
+			<&camcc CAM_CC_IFE_LITE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_1_CLK>;
+		clock-rates =
+			<320000000 0>,
+			<400000000 0>,
+			<480000000 0>,
+			<600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "turbo";
+		src-clock-name = "ife_clk_src";
+		operating-points-v2 = <&vfe_lite1_opp_table>;
+
+		clock-control-debugfs = "true";
+		cam_hw_pid = <12>;
+		status = "ok";
+		vfe_lite1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-icp {
+		compatible = "qcom,cam-icp";
+		compat-hw-name = "qcom,a5",
+			"qcom,ipe0",
+			"qcom,bps";
+		num-a5 = <1>;
+		num-ipe = <1>;
+		num-bps = <1>;
+		icp_pc_en;
+		status = "ok";
+	};
+
+	cam_a5: qcom,a5 {
+		cell-index = <0>;
+		compatible = "qcom,cam-a5";
+		reg = <0x0 0xac00000 0x0 0x6000>,
+			<0x0 0xac10000 0x0 0x8000>,
+			<0x0 0xac18000 0x0 0x3000>;
+		reg-names = "a5_qgic", "a5_sierra", "a5_csr";
+		reg-cam-base = <0x00000 0x10000 0x18000>;
+		interrupts = <GIC_SPI 463 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a5";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"soc_fast_ahb",
+			"icp_ahb_clk",
+			"icp_clk_src",
+			"icp_clk";
+		src-clock-name = "soc_fast_ahb";
+		clocks =
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_ICP_AHB_CLK>,
+			<&camcc CAM_CC_ICP_CLK_SRC>,
+			<&camcc CAM_CC_ICP_CLK>;
+		clock-rates =
+			<100000000 0 400000000 0>,
+			<200000000 0 400000000 0>,
+			<300000000 0 600000000 0>,
+			<400000000 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1",
+					"nominal";
+		operating-points-v2 = <&a5_opp_table>;
+
+		fw_name = "CAMERA_ICP_170.elf";
+		ubwc-ipe-fetch-cfg = <0x7073 0x707b>;
+		ubwc-ipe-write-cfg = <0x161cf 0x161ef>;
+		ubwc-bps-fetch-cfg = <0x7073 0x707b>;
+		ubwc-bps-write-cfg = <0x161cf 0x161ef>;
+		qos-val = <0x00000A0A>;
+		status = "ok";
+		a5_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-100000000 {
+				opp-hz = /bits/ 64 <100000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_ipe0: qcom,ipe0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-ipe";
+		reg = <0x0 0xac87000 0x0 0xa000>;
+		reg-names = "ipe0_top";
+		reg-cam-base = <0x87000>;
+		power-domains = <&camcc CAM_CC_IPE_0_GDSC>;
+		clock-names =
+			"ipe_0_ahb_clk",
+			"ipe_0_areg_clk",
+			"ipe_0_axi_clk",
+			"ipe_0_clk_src",
+			"ipe_0_clk";
+		src-clock-name = "ipe_0_clk_src";
+		clock-control-debugfs = "true";
+		clocks =
+			<&camcc CAM_CC_IPE_0_AHB_CLK>,
+			<&camcc CAM_CC_IPE_0_AREG_CLK>,
+			<&camcc CAM_CC_IPE_0_AXI_CLK>,
+			<&camcc CAM_CC_IPE_0_CLK_SRC>,
+			<&camcc CAM_CC_IPE_0_CLK>;
+
+		clock-rates =
+			<0 0 0 300000000 0>,
+			<0 0 0 430000000 0>,
+			<0 0 0 520000000 0>,
+			<0 0 0 600000000 0>,
+			<0 0 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1",
+				"nominal", "turbo";
+		operating-points-v2 = <&ipe0_opp_table>;
+
+		status = "ok";
+		ipe0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-430000000 {
+				opp-hz = /bits/ 64 <430000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-520000000 {
+				opp-hz = /bits/ 64 <520000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_bps: qcom,bps {
+		cell-index = <0>;
+		compatible = "qcom,cam-bps";
+		reg = <0x0 0xac6f000 0x0 0x8000>;
+		reg-names = "bps_top";
+		reg-cam-base = <0x6f000>;
+		power-domains = <&camcc CAM_CC_BPS_GDSC>;
+		clock-names =
+			"bps_ahb_clk",
+			"bps_areg_clk",
+			"bps_axi_clk",
+			"bps_clk_src",
+			"bps_clk";
+		src-clock-name = "bps_clk_src";
+		clock-control-debugfs = "true";
+		clocks =
+			<&camcc CAM_CC_BPS_AHB_CLK>,
+			<&camcc CAM_CC_BPS_AREG_CLK>,
+			<&camcc CAM_CC_BPS_AXI_CLK>,
+			<&camcc CAM_CC_BPS_CLK_SRC>,
+			<&camcc CAM_CC_BPS_CLK>;
+
+		clock-rates =
+			<0 0 0 200000000 0>,
+			<0 0 0 400000000 0>,
+			<0 0 0 480000000 0>,
+			<0 0 0 600000000 0>,
+			<0 0 0 600000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1",
+				"nominal", "turbo";
+		operating-points-v2 = <&bps_opp_table>;
+
+		status = "ok";
+		bps_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-200000000 {
+				opp-hz = /bits/ 64 <200000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-jpeg {
+		compatible = "qcom,cam-jpeg";
+		compat-hw-name = "qcom,jpegenc",
+			"qcom,jpegdma";
+		num-jpeg-enc = <1>;
+		num-jpeg-dma = <1>;
+		status = "ok";
+	};
+
+	cam_jpeg_enc: qcom,jpegenc {
+		cell-index = <0>;
+		compatible = "qcom,cam_jpeg_enc_165";
+		reg-names = "jpege_hw", "cam_camnoc";
+		reg = <0x0 0xac4e000 0x0 0x4000>,
+			<0x0 0x0ac9f000 0x0 0x10000>;
+		reg-cam-base = <0x4e000 0x9f000>;
+		interrupt-names = "jpeg";
+		interrupts = <GIC_SPI 474 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"jpegenc_clk_src",
+			"jpegenc_clk";
+		clocks =
+			<&camcc CAM_CC_JPEG_CLK_SRC>,
+			<&camcc CAM_CC_JPEG_CLK>;
+
+		clock-rates = <600000000 0>;
+		src-clock-name = "jpegenc_clk_src";
+		operating-points-v2 = <&jpeg_enc_opp_table>;
+
+		clock-cntl-level = "nominal";
+		cam_hw_pid = <22 23>;
+		cam_hw_rd_mid = <0>;
+		cam_hw_wr_mid = <2>;
+		status = "ok";
+		jpeg_enc_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_jpeg_dma: qcom,jpegdma {
+		cell-index = <0>;
+		compatible = "qcom,cam_jpeg_dma_165";
+		reg-names = "jpegdma_hw", "cam_camnoc";
+		reg = <0x0 0xac52000 0x0 0x4000>,
+			<0x0 0x0ac9f000 0x0 0x10000>;
+		reg-cam-base = <0x52000 0x9f000>;
+		interrupt-names = "jpegdma";
+		interrupts = <GIC_SPI 475 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"jpegdma_clk_src",
+			"jpegdma_clk";
+		clocks =
+			<&camcc CAM_CC_JPEG_CLK_SRC>,
+			<&camcc CAM_CC_JPEG_CLK>;
+
+		clock-rates = <600000000 0>;
+		src-clock-name = "jpegdma_clk_src";
+		operating-points-v2 = <&jpeg_dma_opp_table>;
+
+		clock-cntl-level = "nominal";
+		cam_hw_pid = <20 21>;
+		cam_hw_rd_mid = <0>;
+		cam_hw_wr_mid = <2>;
+		status = "ok";
+		jpeg_dma_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-lrme {
+		compatible = "qcom,cam-lrme";
+		arch-compat = "lrme";
+		status = "ok";
+	};
+
+	cam_lrme: qcom,lrme {
+		cell-index = <0>;
+		compatible = "qcom,lrme";
+		reg-names = "lrme";
+		reg = <0x0 0xac6b000 0x0 0x1000>;
+		reg-cam-base = <0x6b000>;
+		interrupt-names = "lrme";
+		interrupts = <GIC_SPI 476 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "lrme_clk_src",
+			"lrme_clk";
+		clocks = <&camcc CAM_CC_LRME_CLK_SRC>,
+			<&camcc CAM_CC_LRME_CLK>;
+		clock-rates = <240000000 0>,
+			<300000000 0>,
+			<320000000 0>,
+			<400000000 0>;
+		clock-cntl-level = "lowsvs", "svs", "svs_l1", "nominal";
+		src-clock-name = "lrme_clk_src";
+		operating-points-v2 = <&lrme_opp_table>;
+
+		status = "ok";
+		lrme_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-240000000 {
+				opp-hz = /bits/ 64 <240000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-cpas {
+		cell-index = <0>;
+		compatible = "qcom,cam-cpas";
+		label = "cpas";
+		arch-compat = "cpas_top";
+		status = "ok";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg-names = "cam_cpas_top", "cam_camnoc";
+		reg = <0x0 0x0ac40000 0x0 0x1000>,
+			<0x0 0x0ac9f000 0x0 0x10000>;
+		reg-cam-base = <0x40000 0x9f000>;
+		cam_hw_fuse = <CAM_CPAS_ISP_FUSE 0x7801FC 0x10 CAM_CPAS_FEATURE_TYPE_DISABLE 0x4>,
+			      <CAM_CPAS_ISP_LITE_FUSE 0x7801FC 0x20 CAM_CPAS_FEATURE_TYPE_DISABLE 0x10>,
+			      <CAM_CPAS_SHDR_FUSE 0x7801FC 0x40 CAM_CPAS_FEATURE_TYPE_DISABLE 0xFF>,
+			      <CAM_CPAS_QCFA_BINNING_ENABLE 0x7801FC 0x80 CAM_CPAS_FEATURE_TYPE_DISABLE 0xFF>,
+			      <CAM_CPAS_CSIPHY_FUSE 0x7801FC 0x100 CAM_CPAS_FEATURE_TYPE_DISABLE 0x10>,
+			      <CAM_CPAS_RT_OT_FUSE 0x7801A4 0x10000000 CAM_CPAS_FEATURE_TYPE_DISABLE 0xFF>;
+		interrupt-names = "cpas_camnoc";
+		interrupts = <GIC_SPI 459 IRQ_TYPE_EDGE_RISING>;
+		camnoc-axi-min-ib-bw = <3000000000>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"gcc_camera_hf_axi_clk",
+			"gcc_camera_sf_axi_clk",
+			"cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk",
+			"cam_cc_camnoc_axi_clk_src",
+			"cam_cc_camnoc_axi_clk",
+			"cam_cc_icp_ahb_clk",
+			"cam_cc_icp_clk";
+		clocks =
+			<&gcc GCC_CAMERA_HF_AXI_CLK>,
+			<&gcc GCC_CAMERA_SF_AXI_CLK>,
+			<&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>,
+			<&camcc CAM_CC_CAMNOC_AXI_CLK_SRC>,
+			<&camcc CAM_CC_CAMNOC_AXI_CLK>,
+			<&camcc CAM_CC_ICP_AHB_CLK>,
+			<&camcc CAM_CC_ICP_CLK>;
+		src-clock-name = "cam_cc_camnoc_axi_clk_src";
+		clock-rates =
+			<0 0 0 0 0 0 0 0>,
+			<0 0 80000000 0 150000000 0 0 0>,
+			<0 0 80000000 0 240000000 0 0 0>,
+			<0 0 80000000 0 320000000 0 0 0>,
+			<0 0 80000000 0 400000000 0 0 0>,
+			<0 0 80000000 0 480000000 0 0 0>;
+		clock-cntl-level = "suspend", "lowsvs", "svs",
+			"svs_l1", "nominal", "turbo";
+		operating-points-v2 = <&cpas_opp_table>;
+		control-camnoc-axi-clk;
+		camnoc-bus-width = <32>;
+		camnoc-axi-clk-bw-margin-perc = <20>;
+		interconnect-names = "cam_ahb", "cam_hf_0", "cam_sf_0", "cam_sf_icp";
+		interconnects =<&gem_noc MASTER_APPSS_PROC 0
+			&cnoc2 SLAVE_CAMERA_CFG 0>,
+				<&mmss_noc MASTER_CAMNOC_HF 0
+			&mc_virt SLAVE_EBI1 0>,
+				<&mmss_noc MASTER_CAMNOC_SF 0
+			&mc_virt SLAVE_EBI1 0>,
+				<&mmss_noc MASTER_CAMNOC_ICP 0
+			&mc_virt SLAVE_EBI1 0>;
+
+		cam-ahb-num-cases = <7>;
+		cam-ahb-bw-KBps =
+			<0 0>, <0 76800>, <0 150000>, <0 150000>,
+			<0 300000>, <0 300000>, <0 300000>;
+		vdd-corners = <RPMH_REGULATOR_LEVEL_RETENTION
+			RPMH_REGULATOR_LEVEL_MIN_SVS
+			RPMH_REGULATOR_LEVEL_LOW_SVS
+			RPMH_REGULATOR_LEVEL_SVS
+			RPMH_REGULATOR_LEVEL_SVS_L1
+			RPMH_REGULATOR_LEVEL_NOM
+			RPMH_REGULATOR_LEVEL_NOM_L1
+			RPMH_REGULATOR_LEVEL_NOM_L2
+			RPMH_REGULATOR_LEVEL_TURBO
+			RPMH_REGULATOR_LEVEL_TURBO_L1>;
+		vdd-corner-ahb-mapping = "suspend",
+			"lowsvs", "lowsvs", "svs", "svs_l1",
+			"nominal", "nominal", "nominal",
+			"turbo", "turbo";
+		client-id-based;
+		client-names =
+			"csiphy0", "csiphy1", "csiphy2", "csiphy3",
+			"csiphy4", "cci0", "cci1",
+			"csid0", "csid1", "csid2", "csid3", "csid4",
+			"ife0", "ife1", "ife2", "ife3", "ife4",
+			"ipe0", "cam-cdm-intf0", "cpas-cdm0",
+			"bps0", "icp0", "jpeg-dma0", "jpeg-enc0",
+			"lrmecpas0";
+
+		cpas_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-150000000 {
+				opp-hz = /bits/ 64 <150000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+			opp-240000000 {
+				opp-hz = /bits/ 64 <240000000>;
+				required-opps = <&rpmhpd_opp_svs>;
+			};
+			opp-320000000 {
+				opp-hz = /bits/ 64 <320000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_turbo>;
+			};
+		};
+		camera-bus-nodes {
+			level0-nodes {
+				level-index = <0>;
+				ife0_rdi_wr: ife0-rdi-wr {
+					cell-index = <16>;
+					node-name = "ife0-rdi-wr";
+					client-name = "ife0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife1_rdi_wr: ife1-rdi-wr {
+					cell-index = <17>;
+					node-name = "ife1-rdi-wr";
+					client-name = "ife1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife2_rdi_wr: ife2-rdi-wr {
+					cell-index = <18>;
+					node-name = "ife2-rdi-wr";
+					client-name = "ife2";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife3_rdi_wr: ife3-rdi-wr {
+					cell-index = <19>;
+					node-name = "ife3-rdi-wr";
+					client-name = "ife3";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife4_rdi_wr: ife4-rdi-wr {
+					cell-index = <20>;
+					node-name = "ife4-rdi-wr";
+					client-name = "ife4";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3>;
+					parent-node = <&level1_rt0_write0>;
+				};
+
+				ife0_pixelall_wr: ife0-pixelall-wr {
+					cell-index = <21>;
+					node-name = "ife0-pixelall-wr";
+					client-name = "ife0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_PIXEL_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_DISP
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt1_write0>;
+				};
+
+				ife1_pixelall_wr: ife1-pixelall-wr {
+					cell-index = <22>;
+					node-name = "ife1-pixelall-wr";
+					client-name = "ife1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_PIXEL_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_DISP
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt1_write0>;
+				};
+
+				ife2_pixelall_wr: ife2-pixelall-wr {
+					cell-index = <23>;
+					node-name = "ife2-pixelall-wr";
+					client-name = "ife2";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_PIXEL_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_DISP
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt1_write1>;
+				};
+
+				ipe0_ref_wr: ipe0-ref-wr {
+					cell-index = <24>;
+					node-name = "ipe0-ref-wr";
+					client-name = "ipe0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IPE_WR_REF>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt0_write0>;
+				};
+
+				bps0_all_wr: bps0-all-wr {
+					cell-index = <25>;
+					node-name = "bps0-all-wr";
+					client-name = "bps0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt0_write0>;
+				};
+
+				lrme0_all_wr: lrme0-all-wr {
+					cell-index = <26>;
+					node-name = "lrme0-all-wr";
+					client-name = "lrmecpas0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt0_write0>;
+				};
+
+				ipe0_viddisp_wr: ipe0-viddisp-wr {
+					cell-index = <27>;
+					node-name = "ipe0-viddisp-wr";
+					client-name = "ipe0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IPE_WR_VID_DISP>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IPE_WR_VID
+					CAM_CPAS_PATH_DATA_IPE_WR_DISP>;
+					parent-node = <&level1_nrt0_write0>;
+				};
+
+				ipe0_all_rd: ipe0-all-rd {
+					cell-index = <28>;
+					node-name = "ipe0-all-rd";
+					client-name = "ipe0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IPE_RD_IN
+					CAM_CPAS_PATH_DATA_IPE_RD_REF>;
+					parent-node = <&level1_nrt0_read0>;
+				};
+
+				bps0_all_rd: bps0-all-rd {
+					cell-index = <29>;
+					node-name = "bps0-all-rd";
+					client-name = "bps0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt0_read0>;
+				};
+
+				lrme0_all_rd: lrme0-all-rd {
+					cell-index = <30>;
+					node-name = "lrme0-all-rd";
+					client-name = "lrmecpas0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt0_read0>;
+				};
+
+				jpeg_enc0_all_wr: jpeg-enc0-all-wr {
+					cell-index = <31>;
+					node-name = "jpeg-enc0-all-wr";
+					client-name = "jpeg-enc0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt1_write0>;
+				};
+
+				jpeg_enc0_all_rd: jpeg-enc0-all-rd {
+					cell-index = <32>;
+					node-name = "jpeg-enc0-all-rd";
+					client-name = "jpeg-enc0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt1_read0>;
+				};
+
+				jpeg_dma0_all_wr: jpeg-dma0-all-wr {
+					cell-index = <33>;
+					node-name = "jpeg-dma0-all-wr";
+					client-name = "jpeg-dma0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					parent-node = <&level1_nrt1_write0>;
+				};
+
+				jpeg_dma0_all_rd: jpeg-dma0-all-rd {
+					cell-index = <34>;
+					node-name = "jpeg-dma0-all-rd";
+					client-name = "jpeg-dma0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt1_read0>;
+				};
+
+				cpas_cdm0_all_rd: cpas-cdm0-all-rd {
+					cell-index = <35>;
+					node-name = "cpas-cdm0-all-rd";
+					client-name = "cpas-cdm0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level2_nrt0_read0>;
+				};
+
+				icp0_all_rd: icp0-all-rd {
+					cell-index = <36>;
+					node-name = "icp0-all-rd";
+					client-name = "icp0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level2_nrt1_read0>;
+				};
+			};
+			level1-nodes {
+				level-index = <1>;
+				camnoc-max-needed;
+				level1_rt0_write0: level1-rt0-write0 {
+					cell-index = <8>;
+					node-name = "level1-rt0-write0";
+					parent-node = <&level2_rt0_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_rt1_write0: level1-rt1-write0 {
+					cell-index = <9>;
+					node-name = "level1-rt1-write0";
+					parent-node = <&level2_rt1_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_rt1_write1: level1-rt1-write1 {
+					cell-index = <10>;
+					node-name = "level1-rt1-write1";
+					parent-node = <&level2_rt1_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt0_write0: level1-nrt0-write0 {
+					cell-index = <11>;
+					node-name = "level1-nrt0-write0";
+					parent-node = <&level2_nrt0_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt0_read0: level1-nrt0-read0 {
+					cell-index = <12>;
+					node-name = "level1-nrt0-read0";
+					parent-node = <&level2_nrt0_read0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt1_write0: level1-nrt1-write0 {
+					cell-index = <13>;
+					node-name = "level1-nrt1-write0";
+					parent-node = <&level2_nrt0_write0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt1_read0: level1-nrt1-read0 {
+					cell-index = <14>;
+					node-name = "level1-nrt1-read0";
+					parent-node = <&level2_nrt0_read0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+			};
+			level2-nodes {
+				level-index = <3>;
+				camnoc-max-needed;
+				level2_rt0_write0: level2-rt0-write0 {
+					cell-index = <3>;
+					node-name = "level2-rt0-write0";
+					parent-node = <&level3_rt0_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM_INTERLEAVE>;
+				};
+
+				level2_rt1_write0: level2-rt1-write0 {
+					cell-index = <4>;
+					node-name = "level2-rt1-write0";
+					parent-node = <&level3_rt0_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM_INTERLEAVE>;
+				};
+
+				level2_nrt0_write0: level2-nrt0-write0 {
+					cell-index = <5>;
+					node-name = "level2-nrt0-write0";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt0_read0: level2-nrt0-read0 {
+					cell-index = <6>;
+					node-name = "level2-nrt0-read0";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt1_read0: level2-nrt1-read0 {
+					cell-index = <7>;
+					node-name = "level2-nrt1-read0";
+					parent-node = <&level3_nrt1_rd_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					bus-width-factor = <4>;
+				};
+			};
+			level3-nodes {
+				level-index = <3>;
+				level3_rt0_wr_sum: level3-rt0-wr-sum {
+					cell-index = <0>;
+					node-name = "level3-rt0-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					ib-bw-voting-needed;
+					qcom,axi-port-mnoc {
+						interconnect-names = "cam_hf_0";
+						interconnects =
+						<&mmss_noc MASTER_CAMNOC_HF 0
+						&mc_virt SLAVE_EBI1 0>;
+					};
+				};
+
+				level3_nrt0_rd_wr_sum: level3-nrt0-rd-wr-sum {
+					cell-index = <1>;
+					node-name = "level3-nrt0-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					qcom,axi-port-mnoc {
+						interconnect-names = "cam_sf_0";
+						interconnects =
+						<&mmss_noc MASTER_CAMNOC_SF 0
+						&mc_virt SLAVE_EBI1 0>;
+					};
+				};
+
+				level3_nrt1_rd_sum: level3-nrt1-rd-sum {
+					cell-index = <2>;
+					node-name = "level3-nrt1-rd-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					qcom,axi-port-mnoc {
+						interconnect-names = "cam_sf_icp";
+						interconnects =
+						<&mmss_noc MASTER_CAMNOC_ICP 0
+						&mc_virt SLAVE_EBI1 0>;
+					};
+				};
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-dma-heaps.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-dma-heaps.dtsi
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/arm/qcom_dma_heap_dt_constants.h>
+
+&soc {
+	qcom,dma-heaps {
+		compatible = "qcom,dma-heaps";
+
+		qcom,qseecom {
+			qcom,dma-heap-name = "qcom,qseecom";
+			qcom,dma-heap-type = <HEAP_TYPE_CMA>;
+			memory-region = <&qseecom_mem>;
+		};
+
+		qcom,qseecom_ta {
+			qcom,dma-heap-name = "qcom,qseecom-ta";
+			qcom,dma-heap-type = <HEAP_TYPE_CMA>;
+			memory-region = <&qseecom_ta_mem>;
+		};
+
+		qcom,secure_cdsp {
+			qcom,dma-heap-name = "qcom,cma-secure-cdsp";
+			qcom,dma-heap-type = <HEAP_TYPE_CMA>;
+			memory-region = <&cdsp_secure_heap>;
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
@@ -71,6 +71,41 @@
 		};
 	};
 
+	pmic-glink {
+		compatible = "qcom,qcm6490-pmic-glink", "qcom,pmic-glink";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		connector@0 {
+			compatible = "usb-c-connector";
+			reg = <0>;
+			power-role = "dual";
+			data-role = "dual";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					pmic_glink_hs_in: endpoint {
+						remote-endpoint = <&usb_1_dwc3_hs>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					pmic_glink_ss_in: endpoint {
+						remote-endpoint = <&usb_1_dwc3_ss>;
+					};
+				};
+			};
+		};
+	};
+
 	reserved-memory {
 		cont_splash_mem: cont-splash@e1000000 {
 			reg = <0x0 0xe1000000 0x0 0x2300000>;
@@ -82,6 +117,11 @@
 			no-map;
 		};
 
+		removed_mem: removed@c0000000 {
+			reg = <0x0 0xc0000000 0x0 0x5100000>;
+			no-map;
+		};
+
 		rmtfs_mem: memory@f8500000 {
 			compatible = "qcom,rmtfs-mem";
 			reg = <0x0 0xf8500000 0x0 0x600000>;
@@ -822,7 +862,6 @@
 };
 
 &uart5 {
-	compatible = "qcom,geni-debug-uart";
 	status = "okay";
 };
 
@@ -886,7 +925,16 @@
 };
 
 &usb_1_dwc3 {
-	dr_mode = "peripheral";
+	dr_mode = "otg";
+	usb-role-switch;
+};
+
+&usb_1_dwc3_hs {
+	remote-endpoint = <&pmic_glink_hs_in>;
+};
+
+&usb_1_dwc3_ss {
+	remote-endpoint = <&pmic_glink_ss_in>;
 };
 
 &usb_1_hsphy {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-graphics-pwrlevels.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-graphics-pwrlevels.dtsi
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+// SPDX-License-Identifier: BSD-3-Clause
+
+&msm_gpu {
+	/*
+	 * Speed-bin zero is default speed bin.
+	 * For rest of the speed bins, speed-bin value
+	 * is calculated as FMAX/4.8 MHz round up to zero
+	 * decimal places plus two margin to account for
+	 * clock jitters.
+	 */
+	qcom,gpu-pwrlevel-bins {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		compatible = "qcom,gpu-pwrlevel-bins";
+		qcom,gpu-pwrlevels-0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			qcom,speed-bin = <0>;
+			qcom,initial-pwrlevel = <5>;
+
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <812000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+
+				qcom,bus-freq = <10>;
+				qcom,bus-min = <9>;
+				qcom,bus-max = <10>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <700000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_NOM>;
+
+				qcom,bus-freq = <9>;
+				qcom,bus-min = <8>;
+				qcom,bus-max = <10>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@2 {
+				reg = <2>;
+				qcom,gpu-freq = <608000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+
+				qcom,bus-freq = <8>;
+				qcom,bus-min = <7>;
+				qcom,bus-max = <10>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@3 {
+				reg = <3>;
+				qcom,gpu-freq = <550000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@4 {
+				reg = <4>;
+				qcom,gpu-freq = <450000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS>;
+
+				qcom,bus-freq = <6>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <8>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@5 {
+				reg = <5>;
+				qcom,gpu-freq = <315000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <2>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <0x882F5FFD>;
+			};
+		};
+
+		qcom,gpu-pwrlevels-1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* Keeping speed bin for FMAX 812 */
+			qcom,speed-bin = <172>;
+			qcom,initial-pwrlevel = <5>;
+
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <812000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+
+				qcom,bus-freq = <10>;
+				qcom,bus-min = <9>;
+				qcom,bus-max = <10>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <700000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_NOM>;
+
+				qcom,bus-freq = <9>;
+				qcom,bus-min = <8>;
+				qcom,bus-max = <10>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@2 {
+				reg = <2>;
+				qcom,gpu-freq = <608000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+
+				qcom,bus-freq = <8>;
+				qcom,bus-min = <7>;
+				qcom,bus-max = <10>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@3 {
+				reg = <3>;
+				qcom,gpu-freq = <550000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@4 {
+				reg = <4>;
+				qcom,gpu-freq = <450000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS>;
+
+				qcom,bus-freq = <6>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <8>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@5 {
+				reg = <5>;
+				qcom,gpu-freq = <315000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <2>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <0x882F5FFD>;
+			};
+		};
+
+		qcom,gpu-pwrlevels-2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			qcom,speed-bin = <117>;
+			qcom,initial-pwrlevel = <2>;
+
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <550000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <450000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS>;
+
+				qcom,bus-freq = <6>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <8>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@2 {
+				reg = <2>;
+				qcom,gpu-freq = <315000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <2>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <0x882F5FFD>;
+			};
+		};
+		qcom,gpu-pwrlevels-3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			qcom,speed-bin = <96>;
+			qcom,initial-pwrlevel = <1>;
+
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <450000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS>;
+
+				qcom,bus-freq = <6>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <8>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <315000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <2>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <0x882F5FFD>;
+			};
+		};
+
+		qcom,gpu-pwrlevels-4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			qcom,speed-bin = <129>;
+			qcom,initial-pwrlevel = <3>;
+
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <608000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+
+				qcom,bus-freq = <8>;
+				qcom,bus-min = <7>;
+				qcom,bus-max = <10>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <550000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@2 {
+				reg = <2>;
+				qcom,gpu-freq = <450000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS>;
+
+				qcom,bus-freq = <6>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <8>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@3 {
+				reg = <3>;
+				qcom,gpu-freq = <315000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <2>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <0x882F5FFD>;
+			};
+		};
+
+		qcom,gpu-pwrlevels-5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			qcom,speed-bin = <148>;
+			qcom,initial-pwrlevel = <4>;
+
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <700000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_NOM>;
+
+				qcom,bus-freq = <9>;
+				qcom,bus-min = <8>;
+				qcom,bus-max = <10>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <608000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L2>;
+
+				qcom,bus-freq = <8>;
+				qcom,bus-min = <7>;
+				qcom,bus-max = <10>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@2 {
+				reg = <2>;
+				qcom,gpu-freq = <550000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@3 {
+				reg = <3>;
+				qcom,gpu-freq = <450000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS>;
+
+				qcom,bus-freq = <6>;
+				qcom,bus-min = <6>;
+				qcom,bus-max = <8>;
+
+				qcom,acd-level = <0x802B5FFD>;
+			};
+
+			qcom,gpu-pwrlevel@4 {
+				reg = <4>;
+				qcom,gpu-freq = <315000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <2>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <0x882F5FFD>;
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-graphics.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-graphics.dtsi
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2024-2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+// SPDX-License-Identifier: BSD-3-Clause
+
+#define MHZ_TO_KBPS(mhz, w) ((mhz * 1000000 * w) / (1024))
+
+&msm_gpu {
+	compatible = "qcom,kgsl",
+		"qcom,adreno-gpu-a643";
+	status = "ok";
+
+	reg = <0x0 0x3d00000 0x0 0x40000>, <0x0 0x3d61000 0x0 0x800>,
+		<0x0 0x3de0000 0x0 0x10000>, <0x0 0x3d8b000 0x0 0x2000>,
+		<0x0 0x06900000 0x0 0x80000>, <0x0 0x0636000 0x0 0x1000>,
+		<0x0 0x3d9e000 0x0 0x1000>;
+
+	reg-names = "kgsl_3d0_reg_memory", "cx_dbgc", "rscc",
+		"isense_cntl", "qdss_gfx", "rdpm_mx",
+		"cx_misc";
+
+	interrupts = <0 300 IRQ_TYPE_LEVEL_HIGH>;
+	interrupt-names = "kgsl_3d0_irq";
+
+	clocks = <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+		<&gcc GCC_GPU_SNOC_DVM_GFX_CLK>,
+		<&gpucc GPU_CC_AHB_CLK>,
+		<&aoss_qmp>,
+		<&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>,
+		<&gpucc GPU_CC_CX_GMU_CLK>,
+		<&gpucc GPU_CC_HUB_AON_CLK>,
+		<&gpucc GPU_CC_HUB_CX_INT_CLK>;
+
+	clock-names = "gcc_gpu_memnoc_gfx",
+			"gcc_gpu_snoc_dvm_gfx",
+			"gpu_cc_ahb",
+			"apb_pclk",
+			"gpu_cc_hlos1_vote_gpu_smmu",
+			"gpu_cc_cx_gmu",
+			"gpu_cc_hub_aon",
+			"gpu_cc_hub_cx_int";
+
+	qcom,chipid = <0x06030500>;
+	qcom,gpu-model = "Adreno643v1";
+
+	qcom,min-access-length = <32>;
+	qcom,ubwc-mode = <3>;
+
+	nvmem-cells = <&gpu_speed_bin>;
+	nvmem-cell-names = "speed_bin";
+
+	qcom,tzone-names = "gpuss-0-usr", "gpuss-1-usr";
+
+	interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>;
+	interconnect-names = "gpu_icc_path";
+
+	qcom,bus-table-ddr =
+		<MHZ_TO_KBPS(0, 4)>,    /* index=0 */
+		<MHZ_TO_KBPS(200, 4)>,  /* index=1,  LOW_SVS */
+		<MHZ_TO_KBPS(451, 4)>,  /* index=2,  LOW_SVS  */
+		<MHZ_TO_KBPS(547, 4)>,  /* index=3,  LOW_SVS  */
+		<MHZ_TO_KBPS(681, 4)>,  /* index=4,  SVS */
+		<MHZ_TO_KBPS(768, 4)>,  /* index=5,  SVS  */
+		<MHZ_TO_KBPS(1555, 4)>, /* index=6,  SVS  */
+		<MHZ_TO_KBPS(1708, 4)>, /* index=7,  SVS_L1  */
+		<MHZ_TO_KBPS(2092, 4)>, /* index=8,  NOM  */
+		<MHZ_TO_KBPS(2736, 4)>, /* index=9, TURBO_L1  */
+		<MHZ_TO_KBPS(3196, 4)>; /* index=10, TURBO_L1  */
+
+	qcom,bus-table-cnoc =
+		<0>,   /* Off */
+		<100>; /* On */
+
+	zap-shader {
+		memory-region = <&gpu_microcode_mem>;
+	};
+
+	qcom,gpu-mempools {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "qcom,gpu-mempools";
+
+		/* 4K Page Pool configuration */
+		qcom,gpu-mempool@0 {
+			reg = <0>;
+			qcom,mempool-page-size = <4096>;
+			qcom,mempool-reserved = <2048>;
+			qcom,mempool-allocate;
+		};
+		/* 8K Page Pool configuration */
+		qcom,gpu-mempool@1 {
+			reg = <1>;
+			qcom,mempool-page-size = <8192>;
+			qcom,mempool-reserved = <1024>;
+			qcom,mempool-allocate;
+		};
+		/* 64K Page Pool configuration */
+		qcom,gpu-mempool@2 {
+			reg = <2>;
+			qcom,mempool-page-size = <65536>;
+			qcom,mempool-reserved = <256>;
+		};
+		/* 1M Page Pool configuration */
+		qcom,gpu-mempool@3 {
+			reg = <3>;
+			qcom,mempool-page-size = <1048576>;
+			qcom,mempool-reserved = <32>;
+		};
+	};
+};
+
+&soc {
+	kgsl_msm_iommu: qcom,kgsl-iommu@3da0000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		compatible = "qcom,kgsl-smmu-v2";
+
+		reg = <0x03da0000 0x20000>;
+
+		power-domains = <&gpucc GPU_CC_CX_GDSC>;
+
+		gfx3d_user: gfx3d_user {
+			compatible = "qcom,smmu-kgsl-cb", "qcom,adreno-gmu";
+			iommus = <&adreno_smmu 0 0x400>, <&adreno_smmu 1 0x400>;
+			qcom,iommu-dma = "disabled";
+		};
+
+	};
+
+	gmu: qcom,gmu@3d6a000 {
+		compatible = "qcom,gpu-gmu";
+
+		reg = <0x0 0x3d6a000 0x0 0x34000>,
+			<0x0 0xb290000 0x0 0x10000>;
+
+		reg-names = "kgsl_gmu_reg",
+			"kgsl_gmu_pdc_cfg";
+
+		interrupts = <0 304 IRQ_TYPE_LEVEL_HIGH>,
+			<0 305 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "kgsl_hfi_irq", "kgsl_gmu_irq";
+
+
+		iommus = <&adreno_smmu 0x5 0x400>;
+		qcom,iommu-dma = "disabled";
+
+		power-domains = <&gpucc GPU_CC_CX_GDSC>, <&gpucc GPU_CC_GX_GDSC>;
+		power-domain-names = "cx", "gx";
+
+		clocks = <&gpucc GPU_CC_CX_GMU_CLK>,
+			<&gpucc GPU_CC_CXO_CLK>,
+			<&gcc GCC_DDRSS_GPU_AXI_CLK>,
+			<&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+			<&gpucc GPU_CC_AHB_CLK>,
+			<&gpucc GPU_CC_HUB_CX_INT_CLK>,
+			<&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>;
+
+		clock-names = "gmu_clk", "cxo_clk", "axi_clk",
+			"memnoc_clk", "ahb_clk", "hub_clk", "smmu_vote";
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-graphics.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-graphics.dtso
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+// SPDX-License-Identifier: BSD-3-Clause
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sc7280.h>
+#include <dt-bindings/clock/qcom,gpucc-sc7280.h>
+#include <dt-bindings/interconnect/qcom,sc7280.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/reset/qcom,sdm845-pdc.h>
+#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+#include <dt-bindings/thermal/thermal.h>
+
+#include "qcm6490-graphics.dtsi"
+#include "qcm6490-graphics-pwrlevels.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCM6490 IDP";
+	compatible = "qcom,qcm6490-idp", "qcom,qcm6490";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
@@ -5,8 +5,16 @@
 
 /dts-v1/;
 
+/* PM7250B is configured to use SID8/9 */
+#define PM7250B_SID 8
+#define PM7250B_SID1 9
+
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
 #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
 #include "sc7280.dtsi"
+#include "pm7250b.dtsi"
 #include "pm7325.dtsi"
 #include "pm8350c.dtsi"
 #include "pmk8350.dtsi"
@@ -29,10 +37,45 @@
 		serial0 = &uart5;
 	};
 
+	pm8350c_pwm_backlight: backlight {
+		compatible = "pwm-backlight";
+		pwms = <&pm8350c_pwm 3 65535>;
+		enable-gpios = <&pm8350c_gpios 7 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&pmic_lcd_bl_en>;
+		pinctrl-names = "default";
+	};
+
 	chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
+	lcd_disp_bias: regulator-lcd-disp-bias {
+		compatible = "regulator-fixed";
+		regulator-name = "lcd_disp_bias";
+		regulator-min-microvolt = <5500000>;
+		regulator-max-microvolt = <5500000>;
+		gpio = <&pm7250b_gpios 2 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+		pinctrl-0 = <&lcd_disp_bias_en>;
+		pinctrl-names = "default";
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		pinctrl-0 = <&key_vol_up_default>;
+		pinctrl-names = "default";
+
+		key-volume-up {
+			label = "Volume_up";
+			gpios = <&pm7325_gpios 6 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_VOLUMEUP>;
+			wakeup-source;
+			debounce-interval = <15>;
+			linux,can-disable;
+		};
+	};
+
 	reserved-memory {
 		xbl_mem: xbl@80700000 {
 			reg = <0x0 0x80700000 0x0 0x100000>;
@@ -109,7 +152,7 @@
 			no-map;
 		};
 
-		trusted_apps_mem: trusted_apps@c1800000 {
+		trusted_apps_mem: trusted-apps@c1800000 {
 			reg = <0x0 0xc1800000 0x0 0x1c00000>;
 			no-map;
 		};
@@ -123,8 +166,8 @@
 	vph_pwr: vph-pwr-regulator {
 		compatible = "regulator-fixed";
 		regulator-name = "vph_pwr";
-		regulator-min-microvolt = <2500000>;
-		regulator-max-microvolt = <4350000>;
+		regulator-min-microvolt = <3700000>;
+		regulator-max-microvolt = <3700000>;
 	};
 };
 
@@ -152,129 +195,151 @@
 		vdd-l14-l16-supply = <&vreg_s8b_1p272>;
 
 		vreg_s1b_1p872: smps1 {
+			regulator-name = "vreg_s1b_1p872";
 			regulator-min-microvolt = <1840000>;
 			regulator-max-microvolt = <2040000>;
 		};
 
 		vreg_s2b_0p876: smps2 {
+			regulator-name = "vreg_s2b_0p876";
 			regulator-min-microvolt = <570070>;
 			regulator-max-microvolt = <1050000>;
 		};
 
 		vreg_s7b_0p972: smps7 {
+			regulator-name = "vreg_s7b_0p972";
 			regulator-min-microvolt = <535000>;
 			regulator-max-microvolt = <1120000>;
 		};
 
 		vreg_s8b_1p272: smps8 {
+			regulator-name = "vreg_s8b_1p272";
 			regulator-min-microvolt = <1200000>;
 			regulator-max-microvolt = <1500000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_RET>;
 		};
 
 		vreg_l1b_0p912: ldo1 {
+			regulator-name = "vreg_l1b_0p912";
 			regulator-min-microvolt = <825000>;
 			regulator-max-microvolt = <925000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l2b_3p072: ldo2 {
+			regulator-name = "vreg_l2b_3p072";
 			regulator-min-microvolt = <2700000>;
 			regulator-max-microvolt = <3544000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l3b_0p504: ldo3 {
+			regulator-name = "vreg_l3b_0p504";
 			regulator-min-microvolt = <312000>;
 			regulator-max-microvolt = <910000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l4b_0p752: ldo4 {
+			regulator-name = "vreg_l4b_0p752";
 			regulator-min-microvolt = <752000>;
 			regulator-max-microvolt = <820000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		reg_l5b_0p752: ldo5 {
+			regulator-name = "reg_l5b_0p752";
 			regulator-min-microvolt = <552000>;
 			regulator-max-microvolt = <832000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l6b_1p2: ldo6 {
+			regulator-name = "vreg_l6b_1p2";
 			regulator-min-microvolt = <1140000>;
 			regulator-max-microvolt = <1260000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l7b_2p952: ldo7 {
+			regulator-name = "vreg_l7b_2p952";
 			regulator-min-microvolt = <2400000>;
 			regulator-max-microvolt = <3544000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l8b_0p904: ldo8 {
+			regulator-name = "vreg_l8b_0p904";
 			regulator-min-microvolt = <870000>;
 			regulator-max-microvolt = <970000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l9b_1p2: ldo9 {
+			regulator-name = "vreg_l9b_1p2";
 			regulator-min-microvolt = <1200000>;
 			regulator-max-microvolt = <1304000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l11b_1p504: ldo11 {
+			regulator-name = "vreg_l11b_1p504";
 			regulator-min-microvolt = <1504000>;
 			regulator-max-microvolt = <2000000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l12b_0p751: ldo12 {
+			regulator-name = "vreg_l12b_0p751";
 			regulator-min-microvolt = <751000>;
 			regulator-max-microvolt = <824000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l13b_0p53: ldo13 {
+			regulator-name = "vreg_l13b_0p53";
 			regulator-min-microvolt = <530000>;
 			regulator-max-microvolt = <824000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l14b_1p08: ldo14 {
+			regulator-name = "vreg_l14b_1p08";
 			regulator-min-microvolt = <1080000>;
 			regulator-max-microvolt = <1304000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l15b_0p765: ldo15 {
+			regulator-name = "vreg_l15b_0p765";
 			regulator-min-microvolt = <765000>;
 			regulator-max-microvolt = <1020000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l16b_1p1: ldo16 {
+			regulator-name = "vreg_l16b_1p1";
 			regulator-min-microvolt = <1100000>;
 			regulator-max-microvolt = <1300000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l17b_1p7: ldo17 {
+			regulator-name = "vreg_l17b_1p7";
 			regulator-min-microvolt = <1700000>;
 			regulator-max-microvolt = <1900000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l18b_1p8: ldo18 {
+			regulator-name = "vreg_l18b_1p8";
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <2000000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l19b_1p8: ldo19 {
+			regulator-name = "vreg_l19b_1p8";
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <2000000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
@@ -306,119 +371,299 @@
 		vdd-bob-supply = <&vph_pwr>;
 
 		vreg_s1c_2p19: smps1 {
+			regulator-name = "vreg_s1c_2p19";
 			regulator-min-microvolt = <2190000>;
 			regulator-max-microvolt = <2210000>;
 		};
 
 		vreg_s2c_0p752: smps2 {
+			regulator-name = "vreg_s2c_0p752";
 			regulator-min-microvolt = <750000>;
 			regulator-max-microvolt = <800000>;
 		};
 
 		vreg_s5c_0p752: smps5 {
+			regulator-name = "vreg_s5c_0p752";
 			regulator-min-microvolt = <465000>;
 			regulator-max-microvolt = <1050000>;
 		};
 
 		vreg_s7c_0p752: smps7 {
+			regulator-name = "vreg_s7c_0p752";
 			regulator-min-microvolt = <465000>;
 			regulator-max-microvolt = <800000>;
 		};
 
 		vreg_s9c_1p084: smps9 {
+			regulator-name = "vreg_s9c_1p084";
 			regulator-min-microvolt = <1010000>;
 			regulator-max-microvolt = <1170000>;
 		};
 
 		vreg_l1c_1p8: ldo1 {
+			regulator-name = "vreg_l1c_1p8";
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <1980000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l2c_1p62: ldo2 {
+			regulator-name = "vreg_l2c_1p62";
 			regulator-min-microvolt = <1620000>;
 			regulator-max-microvolt = <1980000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l3c_2p8: ldo3 {
+			regulator-name = "vreg_l3c_2p8";
 			regulator-min-microvolt = <2800000>;
 			regulator-max-microvolt = <3540000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l4c_1p62: ldo4 {
+			regulator-name = "vreg_l4c_1p62";
 			regulator-min-microvolt = <1620000>;
 			regulator-max-microvolt = <3300000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l5c_1p62: ldo5 {
+			regulator-name = "vreg_l5c_1p62";
 			regulator-min-microvolt = <1620000>;
 			regulator-max-microvolt = <3300000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l6c_2p96: ldo6 {
+			regulator-name = "vreg_l6c_2p96";
 			regulator-min-microvolt = <1650000>;
 			regulator-max-microvolt = <3544000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l7c_3p0: ldo7 {
+			regulator-name = "vreg_l7c_3p0";
 			regulator-min-microvolt = <3000000>;
 			regulator-max-microvolt = <3544000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l8c_1p62: ldo8 {
+			regulator-name = "vreg_l8c_1p62";
 			regulator-min-microvolt = <1620000>;
 			regulator-max-microvolt = <2000000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l9c_2p96: ldo9 {
+			regulator-name = "vreg_l9c_2p96";
 			regulator-min-microvolt = <2700000>;
 			regulator-max-microvolt = <35440000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l10c_0p88: ldo10 {
+			regulator-name = "vreg_l10c_0p88";
 			regulator-min-microvolt = <720000>;
 			regulator-max-microvolt = <1050000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l11c_2p8: ldo11 {
+			regulator-name = "vreg_l11c_2p8";
 			regulator-min-microvolt = <2800000>;
 			regulator-max-microvolt = <3544000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l12c_1p65: ldo12 {
+			regulator-name = "vreg_l12c_1p65";
 			regulator-min-microvolt = <1650000>;
 			regulator-max-microvolt = <2000000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l13c_2p7: ldo13 {
+			regulator-name = "vreg_l13c_2p7";
 			regulator-min-microvolt = <2700000>;
 			regulator-max-microvolt = <3544000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_bob_3p296: bob {
+			regulator-name = "vreg_bob_3p296";
 			regulator-min-microvolt = <3008000>;
 			regulator-max-microvolt = <3960000>;
 		};
 	};
 };
 
+&gpu {
+	status = "okay";
+};
+
+&gpu_zap_shader {
+	firmware-name = "qcom/qcm6490/a660_zap.mbn";
+};
+
+&mdss {
+	status = "okay";
+};
+
+&mdss_dsi {
+	vdda-supply = <&vreg_l6b_1p2>;
+	status = "okay";
+
+	panel@0 {
+		compatible = "novatek,nt36672e";
+		reg = <0>;
+
+		reset-gpios = <&tlmm 44 GPIO_ACTIVE_HIGH>;
+
+		vddi-supply = <&vreg_l8c_1p62>;
+		avdd-supply = <&lcd_disp_bias>;
+		avee-supply = <&lcd_disp_bias>;
+
+		backlight = <&pm8350c_pwm_backlight>;
+
+		port {
+			panel0_in: endpoint {
+				remote-endpoint = <&mdss_dsi0_out>;
+			};
+		};
+	};
+};
+
+&mdss_dsi0_out {
+	remote-endpoint = <&panel0_in>;
+	data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi_phy {
+	vdds-supply = <&vreg_l10c_0p88>;
+	status = "okay";
+};
+
+&pm7250b_gpios {
+	lcd_disp_bias_en: lcd-disp-bias-en-state {
+		pins = "gpio2";
+		function = "func1";
+		bias-disable;
+		qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+		input-disable;
+		output-enable;
+		power-source = <0>;
+	};
+};
+
+&pm8350c_gpios {
+	pmic_lcd_bl_en: pmic-lcd-bl-en-state {
+		pins = "gpio7";
+		function = "normal";
+		bias-disable;
+		qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+		output-low;
+		power-source = <0>;
+	};
+
+	pmic_lcd_bl_pwm: pmic-lcd-bl-pwm-state {
+		pins = "gpio8";
+		function = "func1";
+		bias-disable;
+		qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+		output-low;
+		power-source = <0>;
+	};
+};
+
+&pm7325_gpios {
+	key_vol_up_default: key-vol-up-state {
+		pins = "gpio6";
+		function = "normal";
+		input-enable;
+		bias-pull-up;
+		qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+	};
+};
+
+&pm8350c_pwm {
+	pinctrl-0 = <&pmic_lcd_bl_pwm>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	multi-led {
+		color = <LED_COLOR_ID_RGB>;
+		function = LED_FUNCTION_STATUS;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		led@1 {
+			reg = <1>;
+			color = <LED_COLOR_ID_RED>;
+		};
+
+		led@2 {
+			reg = <2>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		led@3 {
+			reg = <3>;
+			color = <LED_COLOR_ID_BLUE>;
+		};
+	};
+};
+
+&pon_pwrkey {
+	status = "okay";
+};
+
+&pon_resin {
+	linux,code = <KEY_VOLUMEDOWN>;
+	status = "okay";
+};
+
 &qupv3_id_0 {
 	status = "okay";
 };
 
+&remoteproc_adsp {
+	firmware-name = "qcom/qcm6490/adsp.mbn";
+	status = "okay";
+};
+
+&remoteproc_cdsp {
+	firmware-name = "qcom/qcm6490/cdsp.mbn";
+	status = "okay";
+};
+
+&remoteproc_mpss {
+	firmware-name = "qcom/qcm6490/modem.mbn";
+	status = "okay";
+};
+
+&remoteproc_wpss {
+	firmware-name = "qcom/qcm6490/wpss.mbn";
+	status = "okay";
+};
+
+&sdc2_clk {
+	bias-disable;
+	drive-strength = <16>;
+};
+
+&sdc2_cmd {
+	bias-pull-up;
+	drive-strength = <10>;
+};
+
+&sdc2_data {
+	bias-pull-up;
+	drive-strength = <10>;
+};
+
 &sdhc_1 {
 	non-removable;
 	no-sd;
@@ -430,13 +675,30 @@
 	status = "okay";
 };
 
+&sdhc_2 {
+	status = "okay";
+
+	pinctrl-0 = <&sdc2_clk>, <&sdc2_cmd>, <&sdc2_data>, <&sd_cd>;
+	pinctrl-1 = <&sdc2_clk_sleep>, <&sdc2_cmd_sleep>, <&sdc2_data_sleep>, <&sd_cd>;
+
+	vmmc-supply = <&vreg_l9c_2p96>;
+	vqmmc-supply = <&vreg_l6c_2p96>;
+
+	cd-gpios = <&tlmm 91 GPIO_ACTIVE_LOW>;
+};
+
 &tlmm {
 	gpio-reserved-ranges = <32 2>, /* ADSP */
 			       <48 4>; /* NFC */
+
+	sd_cd: sd-cd-state {
+		pins = "gpio91";
+		function = "gpio";
+		bias-pull-up;
+	};
 };
 
 &uart5 {
-	compatible = "qcom,geni-debug-uart";
 	status = "okay";
 };
 
@@ -445,6 +707,7 @@
 };
 
 &usb_1_dwc3 {
+	/delete-property/ usb-role-switch;
 	dr_mode = "peripheral";
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-video.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-video.dtsi
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+&venus {
+	compatible = "qcom,qcm6490-iris-vpu";
+	status = "okay";
+	interconnect-names = "iris-cnoc", "iris-ddr";
+	non-secure-cb {
+		compatible = "qcom,vidc,cb-ns";
+		iommus = <&apps_smmu 0x2180 0x20>;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490-video.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490-video.dtso
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+/plugin/;
+
+#include "qcm6490-video.dtsi"
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm6490.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm6490.dtsi
@@ -0,0 +1,605 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/soc/qcom,gpr.h>
+#include <dt-bindings/sound/qcom,q6afe.h>
+#include "sc7280.dtsi"
+
+/*
+ * Delete unused sc7280 memory nodes and define the memory regions
+ * required by qcm6490
+ */
+/delete-node/ &rmtfs_mem;
+/delete-node/ &wpss_mem;
+/delete-node/ &adsp_mem;
+/delete-node/ &cdsp_mem;
+/delete-node/ &remoteproc_adsp;
+
+/{
+	firmware {
+		scm {
+			qcom,dload-mode = <&tcsr_2 0x13000>;
+		};
+	};
+
+	psci {
+		mode-bootloader = <0x10001 0x2>;
+		mode-edl = <0 0x1>;
+	};
+
+	reboot-mode {
+		status = "disabled";
+	};
+
+	reserved-memory {
+		camera_mem: camera@84300000 {
+			reg = <0x0 0x84300000 0x0 0x500000>;
+			no-map;
+		};
+
+		wpss_mem: wpss@84800000 {
+			reg = <0x0 0x84800000 0x0 0x1900000>;
+			no-map;
+		};
+
+		adsp_mem: adsp@86100000 {
+			reg = <0x0 0x86100000 0x0 0x2800000>;
+			no-map;
+		};
+
+		cdsp_mem: cdsp@88900000 {
+			reg = <0x0 0x88900000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		cvp_mem: cvp@8ae00000 {
+			reg = <0x0 0x8ae00000 0x0 0x500000>;
+			no-map;
+		};
+
+		ipa_gsi_mem: ipa-gsi@8b310000 {
+			reg = <0x0 0x8b310000 0x0 0xa000>;
+			no-map;
+		};
+
+		gpu_microcode_mem: gpu-microcode@8b31a000 {
+			reg = <0x0 0x8b31a000 0x0 0x2000>;
+			no-map;
+		};
+
+		mpss_mem: mpss@8b800000 {
+			reg = <0x0 0x8b800000 0x0 0xf600000>;
+			no-map;
+		};
+
+		tz_stat_mem: tz-stat@c0000000 {
+			reg = <0x0 0xc0000000 0x0 0x100000>;
+			no-map;
+		};
+
+		tags_mem: tags@c0100000 {
+			reg = <0x0 0xc0100000 0x0 0x1200000>;
+			no-map;
+		};
+
+		qtee_mem: qtee@c1300000 {
+			reg = <0x0 0xc1300000 0x0 0x500000>;
+			no-map;
+		};
+
+		trusted_apps_mem: trusted_apps@c1800000 {
+			reg = <0x0 0xc1800000 0x0 0x1c00000>;
+			no-map;
+		};
+
+		debug_vm_mem: debug-vm@d0600000 {
+			reg = <0x0 0xd0600000 0x0 0x100000>;
+			no-map;
+		};
+
+		adsp_heap_mem: adsp-heap {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0xc00000>;
+		};
+
+		cdsp_secure_heap: secure-cdsp-region { /* Secure DSP */
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x2000000>;
+		};
+	};
+};
+
+&CPU0 {
+	CPU0_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <2000000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU1 {
+	CPU1_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <2000000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU2 {
+	CPU2_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <2000000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU3 {
+	CPU3_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <2000000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU4 {
+	CPU4_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <2000000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU5 {
+	CPU5_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <2000000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU6 {
+	CPU6_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <2000000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU7 {
+	CPU7_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <2000000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&gcc {
+	protected-clocks = <GCC_AGGRE_NOC_PCIE_1_AXI_CLK> ,<GCC_PCIE_1_AUX_CLK>,
+			<GCC_PCIE_1_AUX_CLK_SRC>, <GCC_PCIE_1_CFG_AHB_CLK>,
+			<GCC_PCIE_1_MSTR_AXI_CLK>, <GCC_PCIE_1_PHY_RCHNG_CLK_SRC>,
+			<GCC_PCIE_1_PIPE_CLK>, <GCC_PCIE_1_PIPE_CLK_SRC>,
+			<GCC_PCIE_1_SLV_AXI_CLK>, <GCC_PCIE_1_SLV_Q2A_AXI_CLK>,
+			<GCC_QSPI_CNOC_PERIPH_AHB_CLK>, <GCC_QSPI_CORE_CLK>,
+			<GCC_QSPI_CORE_CLK_SRC>,<GCC_USB30_SEC_MASTER_CLK>,
+			<GCC_USB30_SEC_MASTER_CLK_SRC>, <GCC_USB30_SEC_MOCK_UTMI_CLK>,
+			<GCC_USB30_SEC_MOCK_UTMI_CLK_SRC>,
+			<GCC_USB30_SEC_MOCK_UTMI_POSTDIV_CLK_SRC>, <GCC_USB30_SEC_SLEEP_CLK>,
+			<GCC_USB3_SEC_PHY_AUX_CLK>, <GCC_USB3_SEC_PHY_AUX_CLK_SRC>,
+			<GCC_USB3_SEC_PHY_COM_AUX_CLK>, <GCC_USB3_SEC_PHY_PIPE_CLK>,
+			<GCC_USB3_SEC_PHY_PIPE_CLK_SRC>, <GCC_CFG_NOC_LPASS_CLK>,
+			<GCC_MSS_GPLL0_MAIN_DIV_CLK_SRC>, <GCC_MSS_CFG_AHB_CLK>,
+			<GCC_MSS_OFFLINE_AXI_CLK>, <GCC_MSS_SNOC_AXI_CLK>,
+			<GCC_MSS_Q6_MEMNOC_AXI_CLK>, <GCC_MSS_Q6SS_BOOT_CLK_SRC>,
+			<GCC_SEC_CTRL_CLK_SRC>, <GCC_WPSS_AHB_CLK>,
+			<GCC_WPSS_AHB_BDG_MST_CLK>, <GCC_WPSS_RSCP_CLK>;
+};
+
+&ipa {
+	qcom,gsi-loader = "self";
+	memory-region = <&ipa_fw_mem>;
+	firmware-name = "qcom/qcm6490/ipa_fws.mdt";
+	status = "okay";
+};
+
+&ipa_fw_mem {
+	reg = <0x0 0x8b300000 0x0 0x10000>;
+};
+
+&lpass_audiocc {
+	qcom,adsp-skip-pll;
+	protected-clocks = <LPASS_AUDIO_CC_CDIV_RX_MCLK_DIV_CLK_SRC>,
+		<LPASS_AUDIO_CC_CODEC_MEM0_CLK>, <LPASS_AUDIO_CC_CODEC_MEM1_CLK>,
+		<LPASS_AUDIO_CC_CODEC_MEM2_CLK>, <LPASS_AUDIO_CC_CODEC_MEM_CLK>,
+		<LPASS_AUDIO_CC_EXT_MCLK0_CLK>, <LPASS_AUDIO_CC_EXT_MCLK0_CLK_SRC>,
+		<LPASS_AUDIO_CC_EXT_MCLK1_CLK>, <LPASS_AUDIO_CC_EXT_MCLK1_CLK_SRC>,
+		<LPASS_AUDIO_CC_PLL>, <LPASS_AUDIO_CC_PLL_OUT_AUX2>,
+		<LPASS_AUDIO_CC_PLL_OUT_AUX2_DIV_CLK_SRC>,
+		<LPASS_AUDIO_CC_PLL_OUT_MAIN_DIV_CLK_SRC>,
+		<LPASS_AUDIO_CC_RX_MCLK_2X_CLK>, <LPASS_AUDIO_CC_RX_MCLK_CLK>,
+		<LPASS_AUDIO_CC_RX_MCLK_CLK_SRC>;
+	/delete-property/ power-domains;
+};
+
+&lpass_aon {
+	status = "disabled";
+};
+
+&lpass_core {
+	status = "disabled";
+};
+
+&lpass_hm {
+	status = "disabled";
+};
+
+&lpass_rx_macro {
+	/delete-property/ power-domains;
+	/delete-property/ power-domain-names;
+	clocks = <&q6prmcc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&q6prmcc LPASS_CLK_ID_TX_CORE_NPL_MCLK  LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&q6prmcc LPASS_CLK_ID_RX_CORE_MCLK  LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&q6prmcc LPASS_CLK_ID_RX_CORE_NPL_MCLK  LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&lpass_va_macro>;
+	clock-names = "mclk", "npl", "rx-mclk", "rx-npl", "macro", "dcodec", "fsgen";
+
+	qcom,rx_mclk_mode_muxsel = <0x033240D8>;
+
+	status = "okay";
+};
+
+&lpass_tlmm {
+	clocks = <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+	clock-names = "core", "audio";
+
+	lpass_dmic45_clk: dmic45-clk-state {
+		pins = "gpio12";
+		function = "dmic3_clk";
+	};
+
+	lpass_dmic45_data: dmic45-data-state {
+		pins = "gpio13";
+		function = "dmic3_data";
+	};
+};
+
+&lpass_tx_macro {
+	/delete-property/ power-domains;
+	/delete-property/ power-domain-names;
+	clocks = <&q6prmcc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&q6prmcc LPASS_CLK_ID_TX_CORE_NPL_MCLK  LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&lpass_va_macro>;
+	clock-names = "mclk", "npl", "macro", "dcodec", "fsgen";
+
+	status = "okay";
+};
+
+&lpass_va_macro {
+	/delete-property/ power-domains;
+	/delete-property/ power-domain-names;
+	clocks = <&q6prmcc LPASS_CLK_ID_VA_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+	clock-names = "mclk", "macro", "dcodec";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&lpass_dmic01_clk>, <&lpass_dmic01_data>,
+		    <&lpass_dmic23_clk>, <&lpass_dmic23_data>,
+		    <&lpass_dmic45_clk>, <&lpass_dmic45_data>;
+
+	status = "okay";
+};
+
+&lpass_wsa_macro {
+	/delete-property/ power-domains;
+	/delete-property/ power-domain-names;
+	clocks = <&q6prmcc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&q6prmcc LPASS_CLK_ID_TX_CORE_NPL_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+		 <&lpass_va_macro>;
+	clock-names = "mclk", "npl", "macro", "dcodec", "fsgen";
+
+	status = "okay";
+};
+
+&soc {
+	refgen:regulator@88e7000 {
+		compatible = "qcom,sm8250-refgen-regulator";
+		reg = <0x0 0x088e7000 0x0 0x84>;
+	};
+
+	remoteproc_adsp: remoteproc@3000000 {
+		compatible = "qcom,sc7280-adsp-pas";
+		reg = <0x0 0x03000000 0x0 0x100>;
+
+		interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
+					<&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+					<&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+					<&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+					<&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>,
+					<&adsp_smp2p_in 7 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "wdog", "fatal", "ready", "handover",
+				"stop-ack", "shutdown-ack";
+
+		clocks = <&rpmhcc RPMH_CXO_CLK>;
+		clock-names = "xo";
+
+		power-domains = <&rpmhpd SC7280_CX>,
+				<&rpmhpd SC7280_MX>;
+		power-domain-names = "cx", "mx";
+
+		memory-region = <&adsp_mem>;
+
+		qcom,qmp = <&aoss_qmp>;
+
+		qcom,smem-states = <&adsp_smp2p_out 0>;
+		qcom,smem-state-names = "stop";
+
+		status = "disabled";
+
+		remoteproc_adsp_glink: glink-edge {
+			interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+						IPCC_MPROC_SIGNAL_GLINK_QMP
+						IRQ_TYPE_EDGE_RISING>;
+			mboxes = <&ipcc IPCC_CLIENT_LPASS
+					IPCC_MPROC_SIGNAL_GLINK_QMP>;
+			label = "adsp";
+			qcom,remote-pid = <2>;
+
+			fastrpc {
+				compatible = "qcom,fastrpc";
+				qcom,glink-channels = "fastrpcglink-apps-dsp";
+				label = "adsp";
+				memory-region = <&adsp_heap_mem>;
+				qcom,vmids = <22 37>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				compute-cb@1 {
+					compatible = "qcom,fastrpc-compute-cb";
+					reg = <3>;
+					iommus = <&apps_smmu 0x1803 0x0>;
+					dma-coherent;
+				};
+
+				compute-cb@2 {
+					compatible = "qcom,fastrpc-compute-cb";
+					reg = <4>;
+					iommus = <&apps_smmu 0x1804 0x0>;
+					dma-coherent;
+				};
+
+				compute-cb@3 {
+					compatible = "qcom,fastrpc-compute-cb";
+					reg = <5>;
+					iommus = <&apps_smmu 0x1805 0x0>;
+					qcom,nsessions = <5>;
+					dma-coherent;
+				};
+			};
+
+			gpr {
+				compatible = "qcom,gpr";
+				qcom,glink-channels = "adsp_apps";
+				qcom,domain = <GPR_DOMAIN_ID_ADSP>;
+				qcom,intents = <512 20>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				q6apm: service@1 {
+					compatible = "qcom,q6apm";
+					reg = <GPR_APM_MODULE_IID>;
+					#sound-dai-cells = <0>;
+
+					q6apmbedai: bedais {
+						compatible = "qcom,q6apm-lpass-dais";
+						#sound-dai-cells = <1>;
+					};
+					q6apmdai: dais {
+						compatible = "qcom,q6apm-dais";
+						iommus = <&apps_smmu 0x1801 0x0>;
+					};
+				};
+
+				q6prm: service@2 {
+					compatible = "qcom,q6prm";
+					reg = <GPR_PRM_MODULE_IID>;
+
+					q6prmcc: clock-controller {
+						compatible = "qcom,q6prm-lpass-clocks";
+						#clock-cells = <2>;
+					};
+				};
+
+				spf-core {
+					compatible = "qcom,spf_core";
+					reg = <GPR_AMDB_MODULE_IID>;
+				};
+
+				audio-pkt {
+					compatible = "qcom,audio-pkt";
+					reg = <GPR_VCPM_MODULE_IID>;
+
+					qcom,audiopkt-ch-name = "apr_audio_svc";
+				};
+			};
+		};
+	};
+
+	remoteproc_cdsp: remoteproc@a300000 {
+		compatible = "qcom,sc7280-cdsp-pas";
+		reg = <0x0 0x0a300000 0x0 0x100000>;
+
+		interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
+					<&cdsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+					<&cdsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+					<&cdsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+					<&cdsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>,
+					<&cdsp_smp2p_in 7 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "wdog", "fatal", "ready", "handover",
+				"stop-ack", "shutdown-ack";
+
+		clocks = <&rpmhcc RPMH_CXO_CLK>;
+		clock-names = "xo";
+
+		power-domains = <&rpmhpd SC7280_CX>,
+				<&rpmhpd SC7280_MX>;
+		power-domain-names = "cx", "mx";
+
+		memory-region = <&cdsp_mem>;
+
+		qcom,qmp = <&aoss_qmp>;
+
+		qcom,smem-states = <&cdsp_smp2p_out 0>;
+		qcom,smem-state-names = "stop";
+
+		interconnects = <&nsp_noc MASTER_CDSP_PROC 0 &mc_virt SLAVE_EBI1 0>;
+
+		status = "disabled";
+
+		glink-edge {
+			interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
+						IPCC_MPROC_SIGNAL_GLINK_QMP
+						IRQ_TYPE_EDGE_RISING>;
+			mboxes = <&ipcc IPCC_CLIENT_CDSP
+					IPCC_MPROC_SIGNAL_GLINK_QMP>;
+			label = "cdsp";
+			qcom,remote-pid = <5>;
+
+			fastrpc {
+				compatible = "qcom,fastrpc";
+				qcom,glink-channels = "fastrpcglink-apps-dsp";
+				label = "cdsp";
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				compute-cb@1 {
+					compatible = "qcom,fastrpc-compute-cb";
+					reg = <1>;
+					iommus = <&apps_smmu 0x11A1 0x0420>,
+						 <&apps_smmu 0x1181 0x0420>;
+					dma-coherent;
+				};
+
+				compute-cb@2 {
+					compatible = "qcom,fastrpc-compute-cb";
+					reg = <2>;
+					iommus = <&apps_smmu 0x11A2 0x0420>,
+						 <&apps_smmu 0x1182 0x0420>;
+					dma-coherent;
+				};
+
+				compute-cb@3 {
+					compatible = "qcom,fastrpc-compute-cb";
+					reg = <3>;
+					iommus = <&apps_smmu 0x11A3 0x0420>,
+						 <&apps_smmu 0x1183 0x0420>;
+					dma-coherent;
+				};
+
+				compute-cb@4 {
+					compatible = "qcom,fastrpc-compute-cb";
+					reg = <4>;
+					iommus = <&apps_smmu 0x11A4 0x0420>,
+						 <&apps_smmu 0x1184 0x0420>;
+					dma-coherent;
+				};
+
+				compute-cb@5 {
+					compatible = "qcom,fastrpc-compute-cb";
+					reg = <5>;
+					iommus = <&apps_smmu 0x11A5 0x0420>,
+						 <&apps_smmu 0x1185 0x0420>;
+					dma-coherent;
+				};
+
+				compute-cb@6 {
+					compatible = "qcom,fastrpc-compute-cb";
+					reg = <6>;
+					iommus = <&apps_smmu 0x11A6 0x0420>,
+						 <&apps_smmu 0x1186 0x0420>;
+					dma-coherent;
+				};
+
+				compute-cb@7 {
+					compatible = "qcom,fastrpc-compute-cb";
+					reg = <7>;
+					iommus = <&apps_smmu 0x11A7 0x0420>,
+						 <&apps_smmu 0x1187 0x0420>;
+					dma-coherent;
+				};
+
+				compute-cb@8 {
+					compatible = "qcom,fastrpc-compute-cb";
+					reg = <8>;
+					iommus = <&apps_smmu 0x11A8 0x0420>,
+						 <&apps_smmu 0x1188 0x0420>;
+					dma-coherent;
+				};
+
+				/* note: secure cb9 in downstream */
+
+				compute-cb@10 {
+					compatible = "qcom,fastrpc-compute-cb";
+					reg = <12>;
+					iommus = <&apps_smmu 0x11AC 0x0420>,
+						 <&apps_smmu 0x118C 0x0420>;
+					dma-coherent;
+				};
+
+				compute-cb@11 {
+					compatible = "qcom,fastrpc-compute-cb";
+					reg = <13>;
+					iommus = <&apps_smmu 0x11AD 0x0420>,
+						 <&apps_smmu 0x118D 0x0420>;
+					dma-coherent;
+				};
+
+				compute-cb@12 {
+					compatible = "qcom,fastrpc-compute-cb";
+					reg = <14>;
+					iommus = <&apps_smmu 0x11AE 0x0420>,
+						 <&apps_smmu 0x118E 0x0420>;
+					dma-coherent;
+				};
+			};
+		};
+	};
+};
+
+&swr0 {
+	status = "okay";
+};
+
+&swr1 {
+	status = "okay";
+};
+
+&swr2 {
+	status = "okay";
+};
+
+&tlmm {
+	gpio-reserved-ranges = <32 2>, <48 4>;
+};
+
+&video_mem {
+	reg = <0x0 0x8a700000 0x0 0x700000>;
+};
+
+&xbl_mem {
+	reg = <0x0 0x80700000 0x0 0x100000>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcm8550.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcm8550.dtsi
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "sm8550.dtsi"
+
+/delete-node/ &reserved_memory;
+
+/ {
+	reserved_memory: reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/*
+		 * There are 3 types of reserved memory regions here:
+		 * 1. Firmware related regions.
+		 *     This will be described as: reserved-region@address. Current
+		 * reserved-region may have reserved area which was not yet used,
+		 * release note of the firmware can have such kind of information.
+		 * 2. Firmware related which shared with kernel access.
+		 *     Each region will have a specific node with specific label
+		 * name for later phandle reference from other driver dt node. May
+		 * overlapping with above type regions.
+		 * 3. PIL regions.
+		 *     PIL regions are allocated by kernel and assigned to subsystem
+		 * firmware later.
+		 * Here is a map for this platform:
+		 * 0x100000000 +------------------+
+		 *             |                  |
+		 *             | Firmware Related |
+		 *             |                  |
+		 *  0xd4d00000 +------------------+
+		 *             |                  |
+		 *             | Kernel Available |
+		 *             |                  |
+		 *  0xA7000000 +------------------+
+		 *             |                  |
+		 *             |    PIL Region    |
+		 *             |                  |
+		 *  0x8A800000 +------------------+
+		 *             |                  |
+		 *             | Firmware Related |
+		 *             |                  |
+		 *  0x80000000 +------------------+
+		 * Note that:
+		 * 1. 0xA7000000 to 0xA8000000 was used by bootloader as well, not
+		 * suggest for other usage.
+		 * 2. Kernel start address was start at 0xA8000000.
+		 */
+
+		/* Firmware related regions */
+		reserved-region@80000000 {
+			reg = <0x0 0x80000000 0x0 0xa800000>;
+			no-map;
+		};
+
+		aop_image_mem: aop-image-region@81c00000 {
+			reg = <0x0 0x81c00000 0x0 0x60000>;
+			no-map;
+		};
+
+		aop_cmd_db_mem: aop-cmd-db-region@81c60000 {
+			compatible = "qcom,cmd-db";
+			reg = <0x0 0x81c60000 0x0 0x20000>;
+			no-map;
+		};
+
+		aop_config_mem: aop-config-region@81c80000 {
+			no-map;
+			reg = <0x0 0x81c80000 0x0 0x20000>;
+		};
+
+		smem_mem: smem-region@81d00000 {
+			compatible = "qcom,smem";
+			reg = <0x0 0x81d00000 0x0 0x200000>;
+			hwlocks = <&tcsr_mutex 3>;
+			no-map;
+		};
+
+		adsp_mhi_mem: adsp-mhi-region@81f00000 {
+			reg = <0x0 0x81f00000 0x0 0x20000>;
+			no-map;
+		};
+
+		/* PIL region */
+		mpss_mem: mpss-region@8a800000 {
+			reg = <0x0 0x8a800000 0x0 0x10800000>;
+			no-map;
+		};
+
+		q6_mpss_dtb_mem: q6-mpss-dtb-region@9b000000 {
+			reg = <0x0 0x9b000000 0x0 0x80000>;
+			no-map;
+		};
+
+		ipa_fw_mem: ipa-fw-region@9b080000 {
+			reg = <0x0 0x9b080000 0x0 0x10000>;
+			no-map;
+		};
+
+		ipa_gsi_mem: ipa-gsi-region@9b090000 {
+			reg = <0x0 0x9b090000 0x0 0xa000>;
+			no-map;
+		};
+
+		gpu_micro_code_mem: gpu-micro-code-region@9b09a000 {
+			reg = <0x0 0x9b09a000 0x0 0x2000>;
+			no-map;
+		};
+
+		spss_region_mem: spss-region@9b100000 {
+			reg = <0x0 0x9b100000 0x0 0x180000>;
+			no-map;
+		};
+
+		spu_secure_shared_memory_mem: spu-secure-shared-memory-region@9b280000 {
+			reg = <0x0 0x9b280000 0x0 0x80000>;
+			no-map;
+		};
+
+		camera_mem: camera-region@9b300000 {
+			reg = <0x0 0x9b300000 0x0 0x800000>;
+			no-map;
+		};
+
+		video_mem: video-region@9bb00000 {
+			reg = <0x0 0x9bb00000 0x0 0x700000>;
+			no-map;
+		};
+
+		cvp_mem: cvp-region@9c200000 {
+			reg = <0x0 0x9c200000 0x0 0x700000>;
+			no-map;
+		};
+
+		cdsp_mem: cdsp-region@9c900000 {
+			reg = <0x0 0x9c900000 0x0 0x2000000>;
+			no-map;
+		};
+
+		q6_cdsp_dtb_mem: q6-cdsp-dtb-region@9e900000 {
+			reg = <0x0 0x9e900000 0x0 0x80000>;
+			no-map;
+		};
+
+		q6_adsp_dtb_mem: q6-adsp-dtb-region@9e980000 {
+			reg = <0x0 0x9e980000 0x0 0x80000>;
+			no-map;
+		};
+
+		adspslpi_mem: adspslpi-region@9ea00000 {
+			reg = <0x0 0x9ea00000 0x0 0x4080000>;
+			no-map;
+		};
+
+		/* Firmware related regions */
+		mpss_dsm_mem: mpss_dsm_region@d4d00000 {
+			reg = <0x0 0xd4d00000 0x0 0x3300000>;
+			no-map;
+		};
+
+		reserved-region@d8000000 {
+			reg = <0x0 0xd8000000 0x0 0x28000000>;
+			no-map;
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi
@@ -62,7 +62,7 @@
 		vddrf-supply = <&vreg_l1_1p3>;
 		vddch0-supply = <&vdd_ch0_3p3>;
 
-		local-bd-address = [ 02 00 00 00 5a ad ];
+		local-bd-address = [ 00 00 00 00 00 00 ];
 
 		max-speed = <3200000>;
 	};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs404.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs404.dtsi
@@ -28,7 +28,7 @@
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
 			#clock-cells = <0>;
-			clock-frequency = <32768>;
+			clock-frequency = <32764>;
 		};
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp1-addons-rb3gen2-hsp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp1-addons-rb3gen2-hsp.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp1-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp1 addons rb3gen2 hsp platform";
+	compatible = "qcom,qcs5430-fp1-addons-rb3gen2-hsp","qcom,qcs5430";
+	qcom,msm-id = <0x1023F 0x10000>;
+	qcom,board-id = <32 0x6>, <32 0x606>;
+};
+
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp1-addons-rb3gen2-vision-mezz-hsp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp1-addons-rb3gen2-vision-mezz-hsp.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp1-addons-rb3gen2-vision-mezz.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp1 addons rb3gen2 vision mezz hsp platform";
+	compatible = "qcom,qcs5430-fp1-addons-rb3gen2-vision-mezz-hsp","qcom,qcs5430";
+	qcom,msm-id = <0x1023F 0x10000>;
+	qcom,board-id = <32 0x7>, <32 0x607>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp1-addons-rb3gen2-vision-mezz.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp1-addons-rb3gen2-vision-mezz.dts
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp1-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp1 addons rb3gen2 vision mezz platform";
+	compatible = "qcom,qcs5430-fp1-addons-rb3gen2-vision-mezz","qcom,qcs5430";
+	qcom,msm-id = <0x1023F 0x10000>;
+	qcom,board-id = <32 0x2>, <32 0x602>;
+};
+
+&mi2s0_data0 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_data1 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_mclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_sclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_ws {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&q6apmbedai {
+	qcom,prmcc_clk = <&q6prmcc>;
+};
+
+&sound {
+	compatible = "qcom,qcm6490-sndcard";
+	model = "qcm6490-rb3-vision-snd-card";
+
+	audio-routing =
+		"SpkrLeft IN", "WSA_SPK1 OUT",
+		"SpkrRight IN", "WSA_SPK2 OUT",
+		"VA DMIC0", "vdd-micb",
+		"VA DMIC1", "vdd-micb",
+		"VA DMIC2", "vdd-micb",
+		"VA DMIC3", "vdd-micb",
+		"VA DMIC4", "vdd-micb",
+		"VA DMIC5", "vdd-micb";
+
+	pinctrl-names = "default", "stub_aif1_active", "stub_aif1_sleep";
+	pinctrl-0 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>,<&mi2s0_ws_sleep>;
+	pinctrl-1 = <&mi2s0_data0>, <&mi2s0_data1>, <&mi2s0_mclk>, <&mi2s0_sclk>, <&mi2s0_ws>;
+	pinctrl-2 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>,<&mi2s0_ws_sleep>;
+
+	mi2s-capture-dai-link {
+		link-name = "MI2S-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	mi2s-playback-dai-link {
+		link-name = "MI2S-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+	tdm-capture-dai-link {
+		link-name = "TDM-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_TX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	tdm-playback-dai-link {
+		link-name = "TDM-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_RX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+};
+
+&tlmm {
+	mi2s0_data0_sleep: mi2s0-data0-sleep {
+		pins = "gpio98";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_data1_sleep: mi2s0-data1-sleep {
+		pins = "gpio99";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_mclk_sleep: mi2s0-mclk-sleep {
+		pins = "gpio96";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_sclk_sleep: mi2s0-sclk-sleep {
+		pins = "gpio97";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_ws_sleep: mi2s0-ws-sleep {
+		pins = "gpio100";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp1-addons-rb3gen2.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp1-addons-rb3gen2.dts
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs6490-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp1 addons rb3gen2 platform";
+	compatible = "qcom,qcs5430-fp1-addons-rb3gen2","qcom,qcs5430";
+	qcom,msm-id = <0x1023F 0x10000>;
+	qcom,board-id = <32 0x5>, <32 0x605>;
+
+	cpus {
+		cpu-map {
+			cluster0 {
+				/delete-node/ core6;
+				/delete-node/ core7;
+			};
+		};
+	};
+};
+
+&CPU6 {
+	enable-method = "none";
+};
+
+&CPU7 {
+	enable-method = "none";
+};
+
+&pcie1 {
+	status = "ok";
+};
+
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp1p5-addons-rb3gen2-vision-mezz.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp1p5-addons-rb3gen2-vision-mezz.dts
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp1p5-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp1p5 addons rb3gen2 vision mezz platform";
+	compatible = "qcom,qcs5430-fp1p5-addons-rb3gen2-vision-mezz","qcom,qcs5430";
+	qcom,msm-id = <0x9023F 0x10000>;
+	qcom,board-id = <32 0x2>, <32 0x602>;
+};
+
+&mi2s0_data0 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_data1 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_mclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_sclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_ws {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&q6apmbedai {
+	qcom,prmcc_clk = <&q6prmcc>;
+};
+
+&sound {
+	compatible = "qcom,qcm6490-sndcard";
+	model = "qcm6490-rb3-vision-snd-card";
+
+	audio-routing =
+		"SpkrLeft IN", "WSA_SPK1 OUT",
+		"SpkrRight IN", "WSA_SPK2 OUT",
+		"VA DMIC0", "vdd-micb",
+		"VA DMIC1", "vdd-micb",
+		"VA DMIC2", "vdd-micb",
+		"VA DMIC3", "vdd-micb",
+		"VA DMIC4", "vdd-micb",
+		"VA DMIC5", "vdd-micb";
+
+	pinctrl-names = "default", "stub_aif1_active", "stub_aif1_sleep";
+	pinctrl-0 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>,<&mi2s0_ws_sleep>;
+	pinctrl-1 = <&mi2s0_data0>, <&mi2s0_data1>, <&mi2s0_mclk>, <&mi2s0_sclk>, <&mi2s0_ws>;
+	pinctrl-2 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>,<&mi2s0_ws_sleep>;
+
+	mi2s-capture-dai-link {
+		link-name = "MI2S-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	mi2s-playback-dai-link {
+		link-name = "MI2S-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+	tdm-capture-dai-link {
+		link-name = "TDM-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_TX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	tdm-playback-dai-link {
+		link-name = "TDM-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_RX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+};
+
+&tlmm {
+	mi2s0_data0_sleep: mi2s0-data0-sleep {
+		pins = "gpio98";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_data1_sleep: mi2s0-data1-sleep {
+		pins = "gpio99";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_mclk_sleep: mi2s0-mclk-sleep {
+		pins = "gpio96";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_sclk_sleep: mi2s0-sclk-sleep {
+		pins = "gpio97";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_ws_sleep: mi2s0-ws-sleep {
+		pins = "gpio100";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp1p5-addons-rb3gen2.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp1p5-addons-rb3gen2.dts
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp1-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp1p5 addons rb3gen2 platform";
+	compatible = "qcom,qcs5430-fp1p5-addons-rb3gen2","qcom,qcs5430";
+	qcom,msm-id = <0x9023F 0x10000>;
+	qcom,board-id = <32 0x5>, <32 0x605>;
+};
+
+&pcie1 {
+	status = "ok";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp2-addons-rb3gen2-hsp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp2-addons-rb3gen2-hsp.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp2-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp2 addons rb3gen2 hsp platform";
+	compatible = "qcom,qcs5430-fp2-addons-rb3gen2-hsp","qcom,qcs5430";
+	qcom,msm-id = <0x2023F 0x10000>;
+	qcom,board-id = <32 0x6>, <32 0x606>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp2-addons-rb3gen2-vision-mezz-hsp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp2-addons-rb3gen2-vision-mezz-hsp.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp2-addons-rb3gen2-vision-mezz.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp2 addons rb3gen2 vision mezz hsp platform";
+	compatible = "qcom,qcs5430-fp2-addons-rb3gen2-vision-mezz-hsp","qcom,qcs5430";
+	qcom,msm-id = <0x2023F 0x10000>;
+	qcom,board-id = <32 0x7>, <32 0x607>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp2-addons-rb3gen2-vision-mezz.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp2-addons-rb3gen2-vision-mezz.dts
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp2-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp2 addons rb3gen2 vision mezz platform";
+	compatible = "qcom,qcs5430-fp2-addons-rb3gen2-vision-mezz","qcom,qcs5430";
+	qcom,msm-id = <0x2023F 0x10000>;
+	qcom,board-id = <32 0x2>, <32 0x602>;
+};
+
+&mi2s0_data0 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_data1 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_mclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_sclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_ws {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&q6apmbedai {
+	qcom,prmcc_clk = <&q6prmcc>;
+};
+
+&sound {
+	compatible = "qcom,qcm6490-sndcard";
+	model = "qcm6490-rb3-vision-snd-card";
+
+	audio-routing =
+		"SpkrLeft IN", "WSA_SPK1 OUT",
+		"SpkrRight IN", "WSA_SPK2 OUT",
+		"VA DMIC0", "vdd-micb",
+		"VA DMIC1", "vdd-micb",
+		"VA DMIC2", "vdd-micb",
+		"VA DMIC3", "vdd-micb",
+		"VA DMIC4", "vdd-micb",
+		"VA DMIC5", "vdd-micb";
+
+	pinctrl-names = "default", "stub_aif1_active", "stub_aif1_sleep";
+	pinctrl-0 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>,<&mi2s0_ws_sleep>;
+	pinctrl-1 = <&mi2s0_data0>, <&mi2s0_data1>, <&mi2s0_mclk>, <&mi2s0_sclk>, <&mi2s0_ws>;
+	pinctrl-2 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>,<&mi2s0_ws_sleep>;
+
+	mi2s-capture-dai-link {
+		link-name = "MI2S-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	mi2s-playback-dai-link {
+		link-name = "MI2S-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+	tdm-capture-dai-link {
+		link-name = "TDM-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_TX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	tdm-playback-dai-link {
+		link-name = "TDM-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_RX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+};
+
+&tlmm {
+	mi2s0_data0_sleep: mi2s0-data0-sleep {
+		pins = "gpio98";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_data1_sleep: mi2s0-data1-sleep {
+		pins = "gpio99";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_mclk_sleep: mi2s0-mclk-sleep {
+		pins = "gpio96";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_sclk_sleep: mi2s0-sclk-sleep {
+		pins = "gpio97";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_ws_sleep: mi2s0-ws-sleep {
+		pins = "gpio100";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp2-addons-rb3gen2.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp2-addons-rb3gen2.dts
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp1-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp2 addons rb3gen2 platform";
+	compatible = "qcom,qcs5430-fp2-addons-rb3gen2","qcom,qcs5430";
+	qcom,msm-id = <0x2023F 0x10000>;
+	qcom,board-id = <32 0x5>, <32 0x605>;
+
+	cpus {
+		cpu-map {
+			cluster0 {
+				core6 {
+					cpu = <&CPU6>;
+				};
+
+				core7 {
+					cpu = <&CPU7>;
+				};
+			};
+		};
+	};
+};
+
+&CPU6 {
+	enable-method = "psci";
+};
+
+&CPU7 {
+	enable-method = "psci";
+};
+
+&pcie1 {
+        status = "ok";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp2p5-addons-rb3gen2-hsp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp2p5-addons-rb3gen2-hsp.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp2p5-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp2p5 addons rb3gen2 hsp platform";
+	compatible = "qcom,qcs5430-fp2p5-addons-rb3gen2-hsp","qcom,qcs5430";
+	qcom,msm-id = <0x8023F 0x10000>;
+	qcom,board-id = <32 0x6>, <32 0x606>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp2p5-addons-rb3gen2-vision-mezz-hsp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp2p5-addons-rb3gen2-vision-mezz-hsp.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp2p5-addons-rb3gen2-vision-mezz.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp2p5 addons rb3gen2 vision mezz hsp platform";
+	compatible = "qcom,qcs5430-fp2p5-addons-rb3gen2-vision-mezz-hsp","qcom,qcs5430";
+	qcom,msm-id = <0x8023F 0x10000>;
+	qcom,board-id = <32 0x7>, <32 0x607>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp2p5-addons-rb3gen2-vision-mezz.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp2p5-addons-rb3gen2-vision-mezz.dts
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp2p5-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp2p5 addons rb3gen2 vision mezz platform";
+	compatible = "qcom,qcs5430-fp2p5-addons-rb3gen2-vision-mezz","qcom,qcs5430";
+	qcom,msm-id = <0x8023F 0x10000>;
+	qcom,board-id = <32 0x2>, <32 0x602>;
+};
+
+&mi2s0_data0 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_data1 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_mclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_sclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_ws {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&q6apmbedai {
+	qcom,prmcc_clk = <&q6prmcc>;
+};
+
+&sound {
+	compatible = "qcom,qcm6490-sndcard";
+	model = "qcm6490-rb3-vision-snd-card";
+
+	audio-routing =
+		"SpkrLeft IN", "WSA_SPK1 OUT",
+		"SpkrRight IN", "WSA_SPK2 OUT",
+		"VA DMIC0", "vdd-micb",
+		"VA DMIC1", "vdd-micb",
+		"VA DMIC2", "vdd-micb",
+		"VA DMIC3", "vdd-micb",
+		"VA DMIC4", "vdd-micb",
+		"VA DMIC5", "vdd-micb";
+
+	pinctrl-names = "default", "stub_aif1_active", "stub_aif1_sleep";
+	pinctrl-0 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>,<&mi2s0_ws_sleep>;
+	pinctrl-1 = <&mi2s0_data0>, <&mi2s0_data1>, <&mi2s0_mclk>, <&mi2s0_sclk>, <&mi2s0_ws>;
+	pinctrl-2 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>,<&mi2s0_ws_sleep>;
+
+	mi2s-capture-dai-link {
+		link-name = "MI2S-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	mi2s-playback-dai-link {
+		link-name = "MI2S-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+	tdm-capture-dai-link {
+		link-name = "TDM-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_TX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	tdm-playback-dai-link {
+		link-name = "TDM-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_RX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+};
+
+&tlmm {
+	mi2s0_data0_sleep: mi2s0-data0-sleep {
+		pins = "gpio98";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_data1_sleep: mi2s0-data1-sleep {
+		pins = "gpio99";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_mclk_sleep: mi2s0-mclk-sleep {
+		pins = "gpio96";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_sclk_sleep: mi2s0-sclk-sleep {
+		pins = "gpio97";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_ws_sleep: mi2s0-ws-sleep {
+		pins = "gpio100";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp2p5-addons-rb3gen2.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp2p5-addons-rb3gen2.dts
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp1-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp2p5 addons rb3gen2 platform";
+	compatible = "qcom,qcs5430-fp2p5-addons-rb3gen2","qcom,qcs5430";
+	qcom,msm-id = <0x8023F 0x10000>;
+	qcom,board-id = <32 0x5>, <32 0x605>;
+
+	cpus {
+		cpu-map {
+			cluster0 {
+				core6 {
+					cpu = <&CPU6>;
+				};
+
+				core7 {
+					cpu = <&CPU7>;
+				};
+			};
+		};
+	};
+};
+
+&CPU6 {
+	enable-method = "psci";
+};
+
+&CPU7 {
+	enable-method = "psci";
+};
+
+&pcie1 {
+	status = "ok";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp2p5-graphics-pwrlevels.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp2p5-graphics-pwrlevels.dtsi
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+// SPDX-License-Identifier: BSD-3-Clause
+
+&msm_gpu {
+	qcom,initial-pwrlevel = <2>;
+
+	/* Power levels */
+	qcom,gpu-pwrlevels {
+		compatible="qcom,gpu-pwrlevels";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		qcom,gpu-pwrlevel@0 {
+			reg = <0>;
+			qcom,gpu-freq = <550000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+			qcom,bus-freq = <7>;
+			qcom,bus-min = <6>;
+			qcom,bus-max = <9>;
+
+			qcom,acd-level = <0x802B5FFD>;
+		};
+
+		qcom,gpu-pwrlevel@1 {
+			reg = <1>;
+			qcom,gpu-freq = <450000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_SVS>;
+
+			qcom,bus-freq = <6>;
+			qcom,bus-min = <6>;
+			qcom,bus-max = <8>;
+
+			qcom,acd-level = <0x802B5FFD>;
+		};
+
+		qcom,gpu-pwrlevel@2 {
+			reg = <2>;
+			qcom,gpu-freq = <315000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+
+			qcom,bus-freq = <3>;
+			qcom,bus-min = <2>;
+			qcom,bus-max = <7>;
+
+			qcom,acd-level = <0x882F5FFD>;
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp2p5-graphics.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp2p5-graphics.dtso
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+// SPDX-License-Identifier: BSD-3-Clause
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sc7280.h>
+#include <dt-bindings/clock/qcom,gpucc-sc7280.h>
+#include <dt-bindings/interconnect/qcom,sc7280.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/reset/qcom,sdm845-pdc.h>
+#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+#include <dt-bindings/thermal/thermal.h>
+
+#include "qcs5430-graphics.dtsi"
+#include "qcs5430-fp2p5-graphics-pwrlevels.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 rb3gen2 platform";
+	compatible = "qcom,qcs5430-fp2p5-addons-rb3gen2",
+			"qcom,qcs5430-fp2p5-addons-rb3gen2-vision-mezz",
+			"qcom,qcs5430-fp3-addons-rb3gen2",
+			"qcom,qcs5430-fp3-addons-rb3gen2-vision-mezz",
+			"qcom,qcs5430";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp3-addons-rb3gen2-hsp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp3-addons-rb3gen2-hsp.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp3-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp3 addons rb3gen2 hsp platform";
+	compatible = "qcom,qcs5430-fp3-addons-rb3gen2-hsp","qcom,qcs5430";
+	qcom,msm-id = <0x3023F 0x10000>;
+	qcom,board-id = <32 0x6>, <32 0x606>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp3-addons-rb3gen2-vision-mezz-hsp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp3-addons-rb3gen2-vision-mezz-hsp.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp3-addons-rb3gen2-vision-mezz.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp3 addons rb3gen2 vision mezz hsp platform";
+	compatible = "qcom,qcs5430-fp3-addons-rb3gen2-vision-mezz-hsp","qcom,qcs5430";
+	qcom,msm-id = <0x3023F 0x10000>;
+	qcom,board-id = <32 0x7>, <32 0x607>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp3-addons-rb3gen2-vision-mezz.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp3-addons-rb3gen2-vision-mezz.dts
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp3-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp3 addons rb3gen2 vision mezz platform";
+	compatible = "qcom,qcs5430-fp3-addons-rb3gen2-vision-mezz","qcom,qcs5430";
+	qcom,msm-id = <0x3023F 0x10000>;
+	qcom,board-id = <32 0x2>, <32 0x602>;
+};
+
+&mi2s0_data0 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_data1 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_mclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_sclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_ws {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&q6apmbedai {
+	qcom,prmcc_clk = <&q6prmcc>;
+};
+
+&sound {
+	compatible = "qcom,qcm6490-sndcard";
+	model = "qcm6490-rb3-vision-snd-card";
+
+	audio-routing =
+		"SpkrLeft IN", "WSA_SPK1 OUT",
+		"SpkrRight IN", "WSA_SPK2 OUT",
+		"VA DMIC0", "vdd-micb",
+		"VA DMIC1", "vdd-micb",
+		"VA DMIC2", "vdd-micb",
+		"VA DMIC3", "vdd-micb",
+		"VA DMIC4", "vdd-micb",
+		"VA DMIC5", "vdd-micb";
+
+	pinctrl-names = "default", "stub_aif1_active", "stub_aif1_sleep";
+	pinctrl-0 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>,<&mi2s0_ws_sleep>;
+	pinctrl-1 = <&mi2s0_data0>, <&mi2s0_data1>, <&mi2s0_mclk>, <&mi2s0_sclk>, <&mi2s0_ws>;
+	pinctrl-2 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>,<&mi2s0_ws_sleep>;
+
+	mi2s-capture-dai-link {
+		link-name = "MI2S-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	mi2s-playback-dai-link {
+		link-name = "MI2S-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+	tdm-capture-dai-link {
+		link-name = "TDM-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_TX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	tdm-playback-dai-link {
+		link-name = "TDM-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_RX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+};
+
+&tlmm {
+	mi2s0_data0_sleep: mi2s0-data0-sleep {
+		pins = "gpio98";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_data1_sleep: mi2s0-data1-sleep {
+		pins = "gpio99";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_mclk_sleep: mi2s0-mclk-sleep {
+		pins = "gpio96";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_sclk_sleep: mi2s0-sclk-sleep {
+		pins = "gpio97";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_ws_sleep: mi2s0-ws-sleep {
+		pins = "gpio100";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-fp3-addons-rb3gen2.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-fp3-addons-rb3gen2.dts
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs5430-fp1-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 fp3 addons rb3gen2 platform";
+	compatible = "qcom,qcs5430-fp3-addons-rb3gen2","qcom,qcs5430";
+	qcom,msm-id = <0x3023F 0x10000>;
+	qcom,board-id = <32 0x5>, <32 0x605>;
+
+	cpus {
+		cpu-map {
+			cluster0 {
+				core6 {
+					cpu = <&CPU6>;
+				};
+
+				core7 {
+					cpu = <&CPU7>;
+				};
+			};
+		};
+	};
+};
+
+&CPU6 {
+	enable-method = "psci";
+};
+
+&CPU7 {
+	enable-method = "psci";
+};
+
+&pcie1 {
+	status = "ok";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-graphics-pwrlevels.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-graphics-pwrlevels.dtsi
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+// SPDX-License-Identifier: BSD-3-Clause
+
+&msm_gpu {
+	qcom,initial-pwrlevel = <0>;
+
+	/* Power levels */
+	qcom,gpu-pwrlevels {
+		compatible="qcom,gpu-pwrlevels";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		qcom,gpu-pwrlevel@0 {
+			reg = <0>;
+			qcom,gpu-freq = <315000000>;
+			qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+
+			qcom,bus-freq = <3>;
+			qcom,bus-min = <2>;
+			qcom,bus-max = <7>;
+
+			qcom,acd-level = <0x882F5FFD>;
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-graphics.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-graphics.dtsi
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+// SPDX-License-Identifier: BSD-3-Clause
+
+#include "qcm6490-graphics.dtsi"
+
+&msm_gpu {
+	qcom,gpu-model = "Adreno642l";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs5430-graphics.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs5430-graphics.dtso
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+// SPDX-License-Identifier: BSD-3-Clause
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,gcc-sc7280.h>
+#include <dt-bindings/clock/qcom,gpucc-sc7280.h>
+#include <dt-bindings/interconnect/qcom,sc7280.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/reset/qcom,sdm845-pdc.h>
+#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+#include <dt-bindings/thermal/thermal.h>
+
+#include "qcs5430-graphics.dtsi"
+#include "qcs5430-graphics-pwrlevels.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. qcs5430 rb3gen2 platform";
+	compatible = "qcom,qcs5430-fp1-addons-rb3gen2",
+			"qcom,qcs5430-fp1-addons-rb3gen2-vision-mezz",
+			"qcom,qcs5430-fp1p5-addons-rb3gen2",
+			"qcom,qcs5430-fp1p5-addons-rb3gen2-vision-mezz",
+			"qcom,qcs5430-fp2-addons-rb3gen2",
+			"qcom,qcs5430-fp2-addons-rb3gen2-vision-mezz",
+			"qcom,qcs5430";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs615-addons-ride.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs615-addons-ride.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * qcs615-addons ride device tree source
+ *
+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
+
+/dts-v1/;
+
+#include "qcs615-ride.dts"
+#include "qcs615-addons.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS615-addons RIDE";
+	compatible = "qcom,qcs615-addons-ride", "qcom,qcs615";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs615-addons.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs615-addons.dtsi
@@ -0,0 +1,314 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * qcs615-addons device tree source
+ *
+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
+/ {
+	reserved-memory {
+		dump_mem: mem_dump_region {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0 0x00000000 0 0xffffffff>;
+			reusable;
+			size = <0 0x2800000>;
+		};
+	};
+
+	mem_dump {
+		compatible = "qcom,mem-dump";
+		memory-region = <&dump_mem>;
+
+		c0-context {
+			qcom,dump-id = <0x0>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c100-context {
+			qcom,dump-id = <0x1>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c200-context {
+			qcom,dump-id = <0x2>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c300-context {
+			qcom,dump-id = <0x3>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c400-context {
+			qcom,dump-id = <0x4>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c500-context {
+			qcom,dump-id = <0x5>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c600-context {
+			qcom,dump-id = <0x6>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c700-context {
+			qcom,dump-id = <0x7>;
+			qcom,dump-size = <0x800>;
+		};
+
+		etfswao-reg {
+			qcom,dump-size = <0x1000>;
+			qcom,dump-id = <0x102>;
+		};
+
+		etf-reg {
+			qcom,dump-size = <0x1000>;
+			qcom,dump-id = <0x101>;
+		};
+
+		etf-swao {
+			qcom,dump-size = <0x8000>;
+			qcom,dump-id = <0xf1>;
+		};
+
+		etr-reg {
+			qcom,dump-size = <0x1000>;
+			qcom,dump-id = <0x100>;
+		};
+
+		fcm {
+			qcom,dump-id = <0xee>;
+			qcom,dump-size = <0x8400>;
+		};
+
+		l1-dcache0 {
+			qcom,dump-id = <0x80>;
+			qcom,dump-size = <0x9000>;
+		};
+
+		l1-dcache100 {
+			qcom,dump-id = <0x81>;
+			qcom,dump-size = <0x9000>;
+		};
+
+		l1-dcache200 {
+			qcom,dump-id = <0x82>;
+			qcom,dump-size = <0x9000>;
+		};
+
+		l1-dcache300 {
+			qcom,dump-id = <0x83>;
+			qcom,dump-size = <0x9000>;
+		};
+
+		l1-dcache400 {
+			qcom,dump-id = <0x84>;
+			qcom,dump-size = <0x9000>;
+		};
+
+		l1-dcache500 {
+			qcom,dump-id = <0x85>;
+			qcom,dump-size = <0x9000>;
+		};
+
+		l1-dcache600 {
+			qcom,dump-id = <0x86>;
+			qcom,dump-size = <0x12000>;
+		};
+
+		l1-dcache700 {
+			qcom,dump-id = <0x87>;
+			qcom,dump-size = <0x12000>;
+		};
+
+		l1-dtlb600 {
+			qcom,dump-id = <0x46>;
+			qcom,dump-size = <0x480>;
+		};
+
+		l1-dtlb700 {
+			qcom,dump-id = <0x47>;
+			qcom,dump-size = <0x480>;
+		};
+
+		l1-icache0 {
+			qcom,dump-id = <0x60>;
+			qcom,dump-size = <0x8800>;
+		};
+
+		l1-icache100 {
+			qcom,dump-id = <0x61>;
+			qcom,dump-size = <0x8800>;
+		};
+
+		l1-icache200 {
+			qcom,dump-id = <0x62>;
+			qcom,dump-size = <0x8800>;
+		};
+
+		l1-icache300 {
+			qcom,dump-id = <0x63>;
+			qcom,dump-size = <0x8800>;
+		};
+
+		l1-icache400 {
+			qcom,dump-id = <0x64>;
+			qcom,dump-size = <0x8800>;
+		};
+
+		l1-icache500 {
+			qcom,dump-id = <0x65>;
+			qcom,dump-size = <0x8800>;
+		};
+
+		l1-icache600 {
+			qcom,dump-id = <0x66>;
+			qcom,dump-size = <0x11000>;
+		};
+
+		l1-icache700 {
+			qcom,dump-id = <0x67>;
+			qcom,dump-size = <0x11000>;
+		};
+
+		l1-itlb600 {
+			qcom,dump-id = <0x26>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-itlb700 {
+			qcom,dump-id = <0x27>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l2-cache600 {
+			qcom,dump-id = <0xc6>;
+			qcom,dump-size = <0x48000>;
+		};
+
+		l2-cache700 {
+			qcom,dump-id = <0xc7>;
+			qcom,dump-size = <0x48000>;
+		};
+
+		l2-tlb0 {
+			qcom,dump-id = <0x120>;
+			qcom,dump-size = <0x5000>;
+		};
+
+		l2-tlb100 {
+			qcom,dump-id = <0x121>;
+			qcom,dump-size = <0x5000>;
+		};
+
+		l2-tlb200 {
+			qcom,dump-id = <0x122>;
+			qcom,dump-size = <0x5000>;
+		};
+
+		l2-tlb300 {
+			qcom,dump-id = <0x123>;
+			qcom,dump-size = <0x5000>;
+		};
+
+		l2-tlb400 {
+			qcom,dump-id = <0x124>;
+			qcom,dump-size = <0x5000>;
+		};
+
+		l2-tlb500 {
+			qcom,dump-id = <0x125>;
+			qcom,dump-size = <0x5000>;
+		};
+
+		l2-tlb600 {
+			qcom,dump-id = <0x126>;
+			qcom,dump-size = <0x7800>;
+		};
+
+		l2-tlb700 {
+			qcom,dump-id = <0x127>;
+			qcom,dump-size = <0x7800>;
+		};
+
+		llcc1-d-cache {
+			qcom,dump-id = <0x140>;
+			qcom,dump-size = <0x6c000>;
+		};
+
+		misc-data {
+			qcom,dump-id = <0xe8>;
+			qcom,dump-size = <0x1000>;
+		};
+
+		pmic {
+			qcom,dump-id = <0xe4>;
+			qcom,dump-size = <0x10000>;
+		};
+
+		rpmh {
+			qcom,dump-id = <0xec>;
+			qcom,dump-size = <0x2000000>;
+		};
+
+		rpm-sw {
+			qcom,dump-id = <0xea>;
+			qcom,dump-size = <0x28000>;
+		};
+
+		tmc-etf {
+			qcom,dump-id = <0xf0>;
+			qcom,dump-size = <0x8000>;
+		};
+	};
+};
+
+&soc {
+	csr: csr@6001000 {
+		compatible = "qcom,coresight-csr";
+		reg = <0x0 0x6001000 0x0 0x1000>;
+		reg-names = "csr-base";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		qcom,blk-size = <1>;
+		qcom,hwctrl-set-support;
+		qcom,set-byte-cntr-support;
+		qcom,usb-bam-support;
+	};
+
+	dma@10a2000 {
+		compatible = "qcom,dcc-v1", "qcom,dcc";
+		reg = <0x0 0x010a2000 0x0 0x1000>,
+		      <0x0 0x010ae000 0x0 0x2000>;
+
+		qcom,dcc-offset = <0x6000>;
+	};
+
+	tmc_etr: tmc@6048000 {
+		interrupts = <GIC_SPI 270 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "byte-cntr-irq";
+		qcom,sw-usb;
+		qcom,mem_support;
+		coresight-csr = <&csr>;
+		csr-irqctrl-offset = <0x6c>;
+		byte-cntr-name = "byte-cntr";
+		byte-cntr-class-name = "coresight-tmc-etr-stream";
+	};
+
+	swao_csr: csr@6b0e000 {
+		compatible = "qcom,coresight-csr";
+		reg = <0x0 0x6b0e000 0x0 0x1000>;
+		reg-names = "csr-base";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		qcom,blk-size = <1>;
+		qcom,timestamp-support;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs615-ride.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs615-ride.dts
@@ -0,0 +1,451 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include <dt-bindings/gpio/gpio.h>
+#include "qcs615.dtsi"
+#include "pm8150.dtsi"
+/ {
+	model = "Qualcomm Technologies, Inc. QCS615 Ride";
+	compatible = "qcom,qcs615-ride", "qcom,qcs615";
+	chassis-type = "embedded";
+	qcom,msm-id = <377 0x0>, <380 0>, <384 0x0>, <680 0x0>;
+	qcom,board-id = <0x03010019 0>, <0x03020019 0>, <0x10019 0>, <0x20019 0>;
+
+	aliases {
+		mmc0 = &sdhc_1;
+		mmc1 = &sdhc_2;
+		serial0 = &uart0;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	clocks {
+		sleep_clk: sleep-clk {
+			compatible = "fixed-clock";
+			clock-frequency = <32000>;
+			#clock-cells = <0>;
+		};
+
+		xo_board_clk: xo-board-clk {
+			compatible = "fixed-clock";
+			clock-frequency = <38400000>;
+			#clock-cells = <0>;
+		};
+	};
+
+	regulator-usb2-vbus {
+		compatible = "regulator-fixed";
+		regulator-name = "USB2_VBUS";
+		gpio = <&pm8150_gpios 10 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&usb2_en>;
+		pinctrl-names = "default";
+		enable-active-high;
+		regulator-always-on;
+	};
+};
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pm8150-rpmh-regulators";
+		qcom,pmic-id = "a";
+
+		vreg_s3a: smps3 {
+			regulator-name = "vreg_s3a";
+			regulator-min-microvolt = <600000>;
+			regulator-max-microvolt = <650000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s4a: smps4 {
+			regulator-name = "vreg_s4a";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1829000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s5a: smps5 {
+			regulator-name = "vreg_s5a";
+			regulator-min-microvolt = <1896000>;
+			regulator-max-microvolt = <2040000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s6a: smps6 {
+			regulator-name = "vreg_s6a";
+			regulator-min-microvolt = <1304000>;
+			regulator-max-microvolt = <1404000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1a: ldo1 {
+			regulator-name = "vreg_l1a";
+			regulator-min-microvolt = <488000>;
+			regulator-max-microvolt = <852000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2a: ldo2 {
+			regulator-name = "vreg_l2a";
+			regulator-min-microvolt = <1650000>;
+			regulator-max-microvolt = <3100000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3a: ldo3 {
+			regulator-name = "vreg_l3a";
+			regulator-min-microvolt = <1000000>;
+			regulator-max-microvolt = <1248000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5a: ldo5 {
+			regulator-name = "vreg_l5a";
+			regulator-min-microvolt = <875000>;
+			regulator-max-microvolt = <975000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7a: ldo7 {
+			regulator-name = "vreg_l7a";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1900000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8a: ldo8 {
+			regulator-name = "vreg_l8a";
+			regulator-min-microvolt = <1150000>;
+			regulator-max-microvolt = <1350000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l10a: ldo10 {
+			regulator-name = "vreg_l10a";
+			regulator-min-microvolt = <2950000>;
+			regulator-max-microvolt = <3312000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l11a: ldo11 {
+			regulator-name = "vreg_l11a";
+			regulator-min-microvolt = <1232000>;
+			regulator-max-microvolt = <1260000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l12a: ldo12 {
+			regulator-name = "vreg_l12a";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1890000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l13a: ldo13 {
+			regulator-name = "vreg_l13a";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3230000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l15a: ldo15 {
+			regulator-name = "vreg_l15a";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1904000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l16a: ldo16 {
+			regulator-name = "vreg_l16a";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3312000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l17a: ldo17 {
+			regulator-name = "vreg_l17a";
+			regulator-min-microvolt = <2950000>;
+			regulator-max-microvolt = <3312000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&ethernet {
+	status = "okay";
+
+	pinctrl-0 = <&ethernet_defaults>;
+	pinctrl-names = "default";
+
+	phy-handle = <&rgmii_phy>;
+	phy-mode = "rgmii";
+	max-speed = <1000>;
+	qcom,rx-prog-swap;
+
+	snps,mtl-rx-config = <&mtl_rx_setup>;
+	snps,mtl-tx-config = <&mtl_tx_setup>;
+
+	mdio: mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		rgmii_phy: phy@7 {
+			compatible = "ethernet-phy-ieee802.3-c22";
+			reg = <0x7>;
+
+			interrupts-extended = <&tlmm 121 IRQ_TYPE_EDGE_FALLING>;
+			device_type = "ethernet-phy";
+			reset-gpios = <&tlmm 104 GPIO_ACTIVE_LOW>;
+			reset-assert-us = <11000>;
+			reset-deassert-us = <70000>;
+		};
+	};
+
+	mtl_rx_setup: rx-queues-config {
+		snps,rx-queues-to-use = <1>;
+		snps,rx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x0>;
+			snps,route-up;
+			snps,priority = <0x1>;
+		};
+	};
+
+	mtl_tx_setup: tx-queues-config {
+		snps,tx-queues-to-use = <1>;
+		snps,tx-sched-wrr;
+
+		queue0 {
+			snps,weight = <0x10>;
+			snps,dcb-algorithm;
+			snps,priority = <0x0>;
+		};
+	};
+};
+
+&gcc {
+	clocks = <&rpmhcc RPMH_CXO_CLK>,
+		 <&rpmhcc RPMH_CXO_CLK_A>,
+		 <&sleep_clk>;
+};
+
+&pm8150_gpios {
+	usb2_en: usb2-en-state {
+		pins = "gpio10";
+		function = "normal";
+		output-enable;
+		power-source = <0>;
+	};
+};
+
+&pon_pwrkey {
+	status = "okay";
+};
+
+&pon_resin {
+	linux,code = <KEY_VOLUMEDOWN>;
+
+	status = "okay";
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&rpmhcc {
+	clocks = <&xo_board_clk>;
+};
+
+&sdhc_1 {
+	pinctrl-0 = <&sdc1_state_on>;
+	pinctrl-1 = <&sdc1_state_off>;
+	pinctrl-names = "default", "sleep";
+
+	bus-width = <8>;
+	mmc-ddr-1_8v;
+	mmc-hs200-1_8v;
+	mmc-hs400-1_8v;
+	mmc-hs400-enhanced-strobe;
+	vmmc-supply = <&vreg_l17a>;
+	vqmmc-supply = <&vreg_s4a>;
+
+	non-removable;
+	no-sd;
+	no-sdio;
+
+	status = "okay";
+};
+
+&sdhc_2 {
+	pinctrl-0 = <&sdc2_state_on>;
+	pinctrl-1 = <&sdc2_state_off>;
+	pinctrl-names = "default", "sleep";
+
+	bus-width = <4>;
+	cd-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>;
+
+	vmmc-supply = <&vreg_l10a>;
+	vqmmc-supply = <&vreg_s4a>;
+
+	status = "okay";
+};
+
+&tlmm {
+	ethernet_defaults: ethernet-defaults-state {
+		mdc-pins {
+			pins = "gpio113";
+			function = "rgmii";
+			bias-pull-up;
+		};
+
+		mdio-pins {
+			pins = "gpio114";
+			function = "rgmii";
+			bias-pull-up;
+		};
+
+		rgmii-rx-pins {
+			pins = "gpio81", "gpio82", "gpio83", "gpio102", "gpio103", "gpio112";
+			function = "rgmii";
+			bias-disable;
+			drive-strength = <2>;
+		};
+
+		rgmii-tx-pins {
+			pins = "gpio92", "gpio93", "gpio94", "gpio95", "gpio96", "gpio97";
+			function = "rgmii";
+			bias-pull-up;
+			drive-strength = <16>;
+		};
+
+		phy-intr-pins {
+			pins = "gpio121";
+			function = "gpio";
+			bias-disable;
+			drive-strength = <8>;
+		};
+
+		pps-pins {
+			pins = "gpio91";
+			function = "rgmii";
+			bias-disable;
+			drive-strength = <8>;
+		};
+
+		phy-reset-pins {
+			pins = "gpio104";
+			function = "gpio";
+			bias-pull-up;
+			drive-strength = <16>;
+		};
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&usb_1_hsphy {
+	vdd-supply = <&vreg_l5a>;
+	vdda-pll-supply = <&vreg_l12a>;
+	vdda-phy-dpdm-supply = <&vreg_l13a>;
+
+	status = "okay";
+};
+
+&usb_qmpphy {
+	vdda-phy-supply = <&vreg_l5a>;
+	vdda-pll-supply = <&vreg_l12a>;
+
+	status = "okay";
+};
+
+&usb_1 {
+	status = "okay";
+};
+
+&usb_1_dwc3 {
+	dr_mode = "peripheral";
+};
+
+&usb_hsphy_2 {
+	vdd-supply = <&vreg_l5a>;
+	vdda-pll-supply = <&vreg_l12a>;
+	vdda-phy-dpdm-supply = <&vreg_l13a>;
+
+	status = "okay";
+};
+
+&usb_2 {
+	status = "okay";
+};
+
+&usb_2_dwc3 {
+	dr_mode = "host";
+};
+
+&ufs_mem_hc {
+	reset-gpios = <&tlmm 123 GPIO_ACTIVE_LOW>;
+	vcc-supply = <&vreg_l17a>;
+	vcc-max-microamp = <600000>;
+	vccq2-supply = <&vreg_s4a>;
+	vccq2-max-microamp = <600000>;
+
+	status = "okay";
+};
+
+&ufs_mem_phy {
+	vdda-phy-supply = <&vreg_l5a>;
+	vdda-pll-supply = <&vreg_l12a>;
+
+	status = "okay";
+};
+
+&watchdog {
+	clocks = <&sleep_clk>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs615.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs615.dtsi
@@ -0,0 +1,4333 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024-2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/clock/qcom,qcs615-camcc.h>
+#include <dt-bindings/clock/qcom,qcs615-dispcc.h>
+#include <dt-bindings/clock/qcom,qcs615-gcc.h>
+#include <dt-bindings/clock/qcom,qcs615-gpucc.h>
+#include <dt-bindings/clock/qcom,qcs615-videocc.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/dma/qcom-gpi.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
+#include <dt-bindings/interconnect/qcom,qcs615-rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/power/qcom,rpmhpd.h>
+#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+
+/ {
+	interrupt-parent = <&intc>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	audio-etm0 {
+		compatible = "qcom,coresight-remote-etm";
+		device-name = "audio_etm0";
+
+		qcom,inst-id = <5>;
+		atid = <40>;
+
+		out-ports {
+			port {
+				audio_out: endpoint {
+					remote-endpoint = <&dup_funnel_monaq_in1>;
+				};
+			};
+		};
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			power-domains = <&cpu_pd0>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			next-level-cache = <&l2_0>;
+			clocks = <&cpufreq_hw 0>;
+			qcom,freq-domain = <&cpufreq_hw 0>;
+			#cooling-cells = <2>;
+
+			l2_0: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      cache-unified;
+			      next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu1: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			power-domains = <&cpu_pd1>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			next-level-cache = <&l2_100>;
+			clocks = <&cpufreq_hw 0>;
+			qcom,freq-domain = <&cpufreq_hw 0>;
+
+			l2_100: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      cache-unified;
+			      next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu2: cpu@200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			power-domains = <&cpu_pd2>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			next-level-cache = <&l2_200>;
+			clocks = <&cpufreq_hw 0>;
+			qcom,freq-domain = <&cpufreq_hw 0>;
+
+			l2_200: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      cache-unified;
+			      next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu3: cpu@300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x300>;
+			enable-method = "psci";
+			power-domains = <&cpu_pd3>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			next-level-cache = <&l2_300>;
+			clocks = <&cpufreq_hw 0>;
+			qcom,freq-domain = <&cpufreq_hw 0>;
+
+			l2_300: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      cache-unified;
+			      next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu4: cpu@400 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x400>;
+			enable-method = "psci";
+			power-domains = <&cpu_pd4>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			next-level-cache = <&l2_400>;
+			clocks = <&cpufreq_hw 0>;
+			qcom,freq-domain = <&cpufreq_hw 0>;
+
+			l2_400: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      cache-unified;
+			      next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu5: cpu@500 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x500>;
+			enable-method = "psci";
+			power-domains = <&cpu_pd5>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			next-level-cache = <&l2_500>;
+			clocks = <&cpufreq_hw 0>;
+			qcom,freq-domain = <&cpufreq_hw 0>;
+
+			l2_500: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      cache-unified;
+			      next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu6: cpu@600 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a76";
+			reg = <0x0 0x600>;
+			enable-method = "psci";
+			power-domains = <&cpu_pd6>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1740>;
+			dynamic-power-coefficient = <404>;
+			next-level-cache = <&l2_600>;
+			clocks = <&cpufreq_hw 1>;
+			qcom,freq-domain = <&cpufreq_hw 1>;
+			#cooling-cells = <2>;
+
+			l2_600: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      cache-unified;
+			      next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu7: cpu@700 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a76";
+			reg = <0x0 0x700>;
+			enable-method = "psci";
+			power-domains = <&cpu_pd7>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1740>;
+			dynamic-power-coefficient = <404>;
+			next-level-cache = <&l2_700>;
+			clocks = <&cpufreq_hw 1>;
+			qcom,freq-domain = <&cpufreq_hw 1>;
+
+			l2_700: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      cache-unified;
+			      next-level-cache = <&l3_0>;
+			};
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+
+				core1 {
+					cpu = <&cpu1>;
+				};
+
+				core2 {
+					cpu = <&cpu2>;
+				};
+
+				core3 {
+					cpu = <&cpu3>;
+				};
+
+				core4 {
+					cpu = <&cpu4>;
+				};
+
+				core5 {
+					cpu = <&cpu5>;
+				};
+
+				core6 {
+					cpu = <&cpu6>;
+				};
+
+				core7 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+
+		l3_0: l3-cache {
+			compatible = "cache";
+			cache-level = <3>;
+			cache-unified;
+		};
+	};
+
+	dummy_eud: dummy-sink {
+		compatible = "arm,coresight-dummy-sink";
+
+		in-ports {
+			port {
+				eud_in: endpoint {
+					remote-endpoint = <&replicator_swao_out1>;
+				};
+			};
+		};
+	};
+
+	idle-states {
+		entry-method = "psci";
+
+		little_cpu_sleep_0: cpu-sleep-0-0 {
+			compatible = "arm,idle-state";
+			idle-state-name = "silver-power-collapse";
+			arm,psci-suspend-param = <0x40000003>;
+			entry-latency-us = <549>;
+			exit-latency-us = <901>;
+			min-residency-us = <1774>;
+			local-timer-stop;
+		};
+
+		little_cpu_sleep_1: cpu-sleep-0-1 {
+			compatible = "arm,idle-state";
+			idle-state-name = "silver-rail-power-collapse";
+			arm,psci-suspend-param = <0x40000004>;
+			entry-latency-us = <702>;
+			exit-latency-us = <915>;
+			min-residency-us = <4001>;
+			local-timer-stop;
+		};
+
+		big_cpu_sleep_0: cpu-sleep-1-0 {
+			compatible = "arm,idle-state";
+			idle-state-name = "gold-power-collapse";
+			arm,psci-suspend-param = <0x40000003>;
+			entry-latency-us = <523>;
+			exit-latency-us = <1244>;
+			min-residency-us = <2207>;
+			local-timer-stop;
+		};
+
+		big_cpu_sleep_1: cpu-sleep-1-1 {
+			compatible = "arm,idle-state";
+			idle-state-name = "gold-rail-power-collapse";
+			arm,psci-suspend-param = <0x40000004>;
+			entry-latency-us = <526>;
+			exit-latency-us = <1854>;
+			min-residency-us = <5555>;
+			local-timer-stop;
+		};
+	};
+
+	domain-idle-states {
+		cluster_sleep_0: cluster-sleep-0 {
+			compatible = "domain-idle-state";
+			arm,psci-suspend-param = <0x41000044>;
+			entry-latency-us = <2752>;
+			exit-latency-us = <3048>;
+			min-residency-us = <6118>;
+		};
+
+		cluster_sleep_1: cluster-sleep-1 {
+			compatible = "domain-idle-state";
+			arm,psci-suspend-param = <0x41001344>;
+			entry-latency-us = <3263>;
+			exit-latency-us = <4562>;
+			min-residency-us = <8467>;
+		};
+
+		cluster_sleep_2: cluster-sleep-2 {
+			compatible = "domain-idle-state";
+			arm,psci-suspend-param = <0x4100b344>;
+			entry-latency-us = <3638>;
+			exit-latency-us = <6562>;
+			min-residency-us = <9826>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		/* We expect the bootloader to fill in the size */
+		reg = <0 0x80000000 0 0>;
+	};
+
+	firmware {
+		scm {
+			compatible = "qcom,scm-qcs615", "qcom,scm";
+			qcom,dload-mode = <&tcsr 0x13000>;
+		};
+	};
+
+	camnoc_virt: interconnect-0 {
+		compatible = "qcom,qcs615-camnoc-virt";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	ipa_virt: interconnect-1 {
+		compatible = "qcom,qcs615-ipa-virt";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	mc_virt: interconnect-2 {
+		compatible = "qcom,qcs615-mc-virt";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	qup_opp_table: opp-table-qup {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		opp-75000000 {
+			opp-hz = /bits/ 64 <75000000>;
+			required-opps = <&rpmhpd_opp_low_svs>;
+		};
+
+		opp-100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+			required-opps = <&rpmhpd_opp_svs>;
+		};
+
+		opp-128000000 {
+			opp-hz = /bits/ 64 <128000000>;
+			required-opps = <&rpmhpd_opp_nom>;
+		};
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+
+		cpu_pd0: power-domain-cpu0 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+		};
+
+		cpu_pd1: power-domain-cpu1 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+		};
+
+		cpu_pd2: power-domain-cpu2 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+		};
+
+		cpu_pd3: power-domain-cpu3 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+		};
+
+		cpu_pd4: power-domain-cpu4 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+		};
+
+		cpu_pd5: power-domain-cpu5 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
+		};
+
+		cpu_pd6: power-domain-cpu6 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>;
+		};
+
+		cpu_pd7: power-domain-cpu7 {
+			#power-domain-cells = <0>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>;
+		};
+
+		cluster_pd: power-domain-cluster {
+			#power-domain-cells = <0>;
+			domain-idle-states = <&cluster_sleep_0
+					      &cluster_sleep_1
+					      &cluster_sleep_2>;
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		aop_cmd_db_mem: aop-cmd-db@85f20000 {
+			compatible = "qcom,cmd-db";
+			reg = <0x0 0x85f20000 0x0 0x20000>;
+			no-map;
+		};
+
+		smem_region: smem@86000000 {
+			compatible = "qcom,smem";
+			reg = <0x0 0x86000000 0x0 0x200000>;
+			no-map;
+			hwlocks = <&tcsr_mutex 3>;
+		};
+	};
+
+	soc: soc@0 {
+		compatible = "simple-bus";
+		ranges = <0 0 0 0 0x10 0>;
+		dma-ranges = <0 0 0 0 0x10 0>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ethernet: ethernet@20000 {
+			compatible = "qcom,qcs615-ethqos";
+			reg = <0x0 0x00020000 0x0 0x00010000>,
+			      <0x0 0x00036000 0x0 0x00000100>;
+			reg-names = "stmmaceth", "rgmii";
+
+			clocks = <&gcc GCC_EMAC_AXI_CLK>,
+				 <&gcc GCC_EMAC_SLV_AHB_CLK>,
+				 <&gcc GCC_EMAC_PTP_CLK>,
+				 <&gcc GCC_EMAC_RGMII_CLK>;
+			clock-names = "stmmaceth",
+				      "pclk",
+				      "ptp_ref",
+				      "rgmii";
+
+			interrupts = <GIC_SPI 660 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 661 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq", "eth_lpi";
+
+			power-domains = <&gcc EMAC_GDSC>;
+			resets = <&gcc GCC_EMAC_BCR>;
+
+			iommus = <&apps_smmu 0x1c0 0x0>;
+
+			snps,tso;
+			snps,pbl = <32>;
+			rx-fifo-depth = <16384>;
+			tx-fifo-depth = <20480>;
+
+			status = "disabled";
+		};
+
+		gcc: clock-controller@100000 {
+			compatible = "qcom,qcs615-gcc";
+			reg = <0 0x00100000 0 0x1f0000>;
+
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
+		qfprom: efuse@780000 {
+			compatible = "qcom,qcs615-qfprom", "qcom,qfprom";
+			reg = <0x0 0x00780000 0x0 0x7000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			qusb2_hstx_trim: hstx-trim@1f8 {
+				reg = <0x1fb 0x1>;
+				bits = <1 4>;
+			};
+		};
+
+		sdhc_1: mmc@7c4000 {
+			compatible = "qcom,qcs615-sdhci", "qcom,sdhci-msm-v5";
+			reg = <0x0 0x007c4000 0x0 0x1000>,
+			      <0x0 0x007c5000 0x0 0x1000>,
+			      <0x0 0x007c8000 0x0 0x8000>;
+			reg-names = "hc",
+				    "cqhci",
+				    "ice";
+
+			interrupts = <GIC_SPI 641 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 644 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "hc_irq",
+					  "pwr_irq";
+
+			clocks = <&gcc GCC_SDCC1_AHB_CLK>,
+				 <&gcc GCC_SDCC1_APPS_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_SDCC1_ICE_CORE_CLK>;
+			clock-names = "iface",
+				      "core",
+				      "xo",
+				      "ice";
+
+			resets = <&gcc GCC_SDCC1_BCR>;
+
+			power-domains = <&rpmhpd RPMHPD_CX>;
+			operating-points-v2 = <&sdhc1_opp_table>;
+			iommus = <&apps_smmu 0x02c0 0x0>;
+			interconnects = <&aggre1_noc MASTER_SDCC_1 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &config_noc SLAVE_SDCC_1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+			interconnect-names = "sdhc-ddr",
+					     "cpu-sdhc";
+
+			qcom,dll-config = <0x000f642c>;
+			qcom,ddr-config = <0x80040868>;
+			supports-cqe;
+			dma-coherent;
+
+			status = "disabled";
+
+			sdhc1_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-50000000 {
+					opp-hz = /bits/ 64 <50000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+				};
+
+				opp-100000000 {
+					opp-hz = /bits/ 64 <100000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+				};
+
+				opp-200000000 {
+					opp-hz = /bits/ 64 <200000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+				};
+
+				opp-384000000 {
+					opp-hz = /bits/ 64 <384000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+				};
+			};
+		};
+
+		gpi_dma0: dma-controller@800000  {
+			compatible = "qcom,qcs615-gpi-dma", "qcom,sdm845-gpi-dma";
+			reg = <0x0 0x800000 0x0 0x60000>;
+			#dma-cells = <3>;
+			interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH>;
+			dma-channels = <8>;
+			dma-channel-mask = <0xf>;
+			iommus = <&apps_smmu 0xd6 0x0>;
+			status = "disabled";
+		};
+
+		qupv3_id_0: geniqup@8c0000 {
+			compatible = "qcom,geni-se-qup";
+			reg = <0x0 0x008c0000 0x0 0x6000>;
+			ranges;
+			clocks = <&gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>,
+				 <&gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>;
+			clock-names = "m-ahb",
+				      "s-ahb";
+			iommus = <&apps_smmu 0xc3 0x0>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			status = "disabled";
+
+			uart0: serial@880000 {
+				compatible = "qcom,geni-debug-uart";
+				reg = <0x0 0x00880000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart0_tx>, <&qup_uart0_rx>;
+				pinctrl-names = "default";
+				interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&aggre1_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				status = "disabled";
+			};
+
+			i2c1: i2c@884000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x884000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_i2c1_data_clk>;
+				pinctrl-names = "default";
+				interconnects = <&aggre1_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				dmas = <&gpi_dma0 0 1 QCOM_GPI_I2C>,
+				       <&gpi_dma0 1 1 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			i2c2: i2c@888000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x888000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_i2c2_data_clk>;
+				pinctrl-names = "default";
+				interconnects = <&aggre1_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				dmas = <&gpi_dma0 0 2 QCOM_GPI_I2C>,
+				       <&gpi_dma0 1 2 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			spi2: spi@888000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x00888000 0x0 0x4000>;
+				interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_spi2_data_clk>, <&qup_spi2_cs>;
+				pinctrl-names = "default";
+				interconnects = <&aggre1_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				dmas = <&gpi_dma0 0 2 QCOM_GPI_SPI>,
+				       <&gpi_dma0 1 2 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			uart2: serial@888000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x00888000 0x0 0x4000>;
+				interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart2_cts>, <&qup_uart2_rts>,
+					    <&qup_uart2_tx>, <&qup_uart2_rx>;
+				pinctrl-names = "default";
+				interconnects = <&aggre1_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				status = "disabled";
+			};
+
+			i2c3: i2c@88c000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x88c000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_i2c3_data_clk>;
+				pinctrl-names = "default";
+				interconnects = <&aggre1_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				dmas = <&gpi_dma0 0 3 QCOM_GPI_I2C>,
+				       <&gpi_dma0 1 3 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+		};
+
+		gpi_dma1: dma-controller@a00000 {
+			compatible = "qcom,qcs615-gpi-dma", "qcom,sdm845-gpi-dma";
+			reg = <0x0 0xa00000 0x0 0x60000>;
+			#dma-cells = <3>;
+			interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 293 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 294 IRQ_TYPE_LEVEL_HIGH>;
+			dma-channels = <8>;
+			dma-channel-mask = <0xf>;
+			iommus = <&apps_smmu 0x376 0x0>;
+			status = "disabled";
+		};
+
+		qupv3_id_1: geniqup@ac0000 {
+			compatible = "qcom,geni-se-qup";
+			reg = <0x0 0xac0000 0x0 0x2000>;
+			ranges;
+			clocks = <&gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>,
+				 <&gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>;
+			clock-names = "m-ahb",
+				      "s-ahb";
+			iommus = <&apps_smmu 0x363 0x0>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			status = "disabled";
+
+			i2c4: i2c@a80000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0xa80000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_i2c4_data_clk>;
+				pinctrl-names = "default";
+				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnects = <&aggre1_noc MASTER_BLSP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_BLSP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 0 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			spi4: spi@a80000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0xa80000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_spi4_data_clk>, <&qup_spi4_cs>;
+				pinctrl-names = "default";
+				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnects = <&aggre1_noc MASTER_BLSP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma1 0 0 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 0 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart4: serial@a80000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0xa80000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart4_cts>, <&qup_uart4_rts>,
+					    <&qup_uart4_tx>, <&qup_uart4_rx>;
+				pinctrl-names = "default";
+				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&aggre1_noc MASTER_BLSP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c5: i2c@a84000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0xa84000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_i2c5_data_clk>;
+				pinctrl-names = "default";
+				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnects = <&aggre1_noc MASTER_BLSP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_BLSP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 1 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			i2c6: i2c@a88000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0xa88000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_i2c6_data_clk>;
+				pinctrl-names = "default";
+				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnects = <&aggre1_noc MASTER_BLSP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_BLSP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 2 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			spi6: spi@a88000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0xa88000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_spi6_data_clk>, <&qup_spi6_cs>;
+				pinctrl-names = "default";
+				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnects = <&aggre1_noc MASTER_BLSP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma1 0 2 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 2 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart6: serial@a88000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0xa88000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart6_cts>, <&qup_uart6_rts>,
+					    <&qup_uart6_tx>, <&qup_uart6_rx>;
+				pinctrl-names = "default";
+				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&aggre1_noc MASTER_BLSP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c7: i2c@a8c000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0xa8c000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_i2c7_data_clk>;
+				pinctrl-names = "default";
+				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnects = <&aggre1_noc MASTER_BLSP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>,
+						<&aggre1_noc MASTER_BLSP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config",
+						     "qup-memory";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 3 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			spi7: spi@a8c000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0xa8c000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_spi7_data_clk>, <&qup_spi7_cs>;
+				pinctrl-names = "default";
+				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnects = <&aggre1_noc MASTER_BLSP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma1 0 3 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 3 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart7: serial@a8c000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0xa8c000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart7_cts>, <&qup_uart7_rts>,
+					    <&qup_uart7_tx>, <&qup_uart7_rx>;
+				pinctrl-names = "default";
+				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&aggre1_noc MASTER_BLSP_1 QCOM_ICC_TAG_ALWAYS
+						 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
+				power-domains = <&rpmhpd RPMHPD_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+		};
+
+		config_noc: interconnect@1500000 {
+			reg = <0x0 0x01500000 0x0 0x5080>;
+			compatible = "qcom,qcs615-config-noc";
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		system_noc: interconnect@1620000 {
+			reg = <0x0 0x01620000 0x0 0x1f300>;
+			compatible = "qcom,qcs615-system-noc";
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		aggre1_noc: interconnect@1700000 {
+			reg = <0x0 0x01700000 0x0 0x3f200>;
+			compatible = "qcom,qcs615-aggre1-noc";
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		mmss_noc: interconnect@1740000 {
+			reg = <0x0 0x01740000 0x0 0x1c100>;
+			compatible = "qcom,qcs615-mmss-noc";
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		ufs_mem_hc: ufshc@1d84000 {
+			compatible = "qcom,qcs615-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
+			reg = <0x0 0x01d84000 0x0 0x3000>,
+			      <0x0 0x01d90000 0x0 0x8000>;
+			reg-names = "std",
+				    "ice";
+
+			interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_UFS_PHY_AXI_CLK>,
+				 <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+				 <&gcc GCC_UFS_PHY_AHB_CLK>,
+				 <&gcc GCC_UFS_PHY_UNIPRO_CORE_CLK>,
+				 <&gcc GCC_UFS_PHY_ICE_CORE_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>,
+				 <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>;
+			clock-names = "core_clk",
+				      "bus_aggr_clk",
+				      "iface_clk",
+				      "core_clk_unipro",
+				      "core_clk_ice",
+				      "ref_clk",
+				      "tx_lane0_sync_clk",
+				      "rx_lane0_sync_clk";
+
+			resets = <&gcc GCC_UFS_PHY_BCR>;
+			reset-names = "rst";
+
+			operating-points-v2 = <&ufs_opp_table>;
+			interconnects = <&aggre1_noc MASTER_UFS_MEM QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &config_noc SLAVE_UFS_MEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+			interconnect-names = "ufs-ddr",
+					     "cpu-ufs";
+
+			power-domains = <&gcc UFS_PHY_GDSC>;
+
+			iommus = <&apps_smmu 0x300 0x0>;
+			dma-coherent;
+
+			lanes-per-direction = <1>;
+
+			phys = <&ufs_mem_phy>;
+			phy-names = "ufsphy";
+
+			#reset-cells = <1>;
+
+			status = "disabled";
+
+			ufs_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-50000000 {
+					opp-hz = /bits/ 64 <50000000>,
+						 /bits/ 64 <0>,
+						 /bits/ 64 <0>,
+						 /bits/ 64 <37500000>,
+						 /bits/ 64 <75000000>,
+						 /bits/ 64 <0>,
+						 /bits/ 64 <0>,
+						 /bits/ 64 <0>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+				};
+
+				opp-100000000 {
+					opp-hz = /bits/ 64 <100000000>,
+						 /bits/ 64 <0>,
+						 /bits/ 64 <0>,
+						 /bits/ 64 <75000000>,
+						 /bits/ 64 <150000000>,
+						 /bits/ 64 <0>,
+						 /bits/ 64 <0>,
+						 /bits/ 64 <0>;
+					required-opps = <&rpmhpd_opp_svs>;
+				};
+
+				opp-200000000 {
+					opp-hz = /bits/ 64 <200000000>,
+						 /bits/ 64 <0>,
+						 /bits/ 64 <0>,
+						 /bits/ 64 <150000000>,
+						 /bits/ 64 <300000000>,
+						 /bits/ 64 <0>,
+						 /bits/ 64 <0>,
+						 /bits/ 64 <0>;
+					required-opps = <&rpmhpd_opp_nom>;
+				};
+			};
+		};
+
+		ufs_mem_phy: phy@1d87000 {
+			compatible = "qcom,qcs615-qmp-ufs-phy", "qcom,sm6115-qmp-ufs-phy";
+			reg = <0x0 0x01d87000 0x0 0xe00>;
+			clocks = <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+				 <&gcc GCC_UFS_MEM_CLKREF_CLK>;
+			clock-names = "ref",
+				      "ref_aux",
+				      "qref";
+
+			power-domains = <&gcc UFS_PHY_GDSC>;
+
+			resets = <&ufs_mem_hc 0>;
+			reset-names = "ufsphy";
+
+			#clock-cells = <1>;
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
+		tcsr_mutex: hwlock@1f40000 {
+			compatible = "qcom,tcsr-mutex";
+			reg = <0x0 0x01f40000 0x0 0x20000>;
+			#hwlock-cells = <1>;
+		};
+
+		tcsr: syscon@1fc0000 {
+			compatible = "qcom,qcs615-tcsr", "syscon";
+			reg = <0x0 0x01fc0000 0x0 0x30000>;
+		};
+
+		tlmm: pinctrl@3100000 {
+			compatible = "qcom,qcs615-tlmm";
+			reg = <0x0 0x03100000 0x0 0x300000>,
+			      <0x0 0x03500000 0x0 0x300000>,
+			      <0x0 0x03d00000 0x0 0x300000>;
+			reg-names = "east",
+				    "west",
+				    "south";
+			interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+			gpio-ranges = <&tlmm 0 0 124>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			wakeup-parent = <&pdc>;
+
+			qup_i2c1_data_clk: qup-i2c1-data-clk-state {
+				pins = "gpio4", "gpio5";
+				function = "qup0";
+
+			};
+
+			qup_i2c2_data_clk: qup-i2c2-data-clk-state {
+				pins = "gpio0", "gpio1";
+				function = "qup0";
+			};
+
+			qup_i2c3_data_clk: qup-i2c3-data-clk-state {
+				pins = "gpio18", "gpio19";
+				function = "qup0";
+			};
+
+			qup_i2c4_data_clk: qup-i2c4-data-clk-state {
+				pins = "gpio20", "gpio21";
+				function = "qup1";
+			};
+
+			qup_i2c5_data_clk: qup-i2c5-data-clk-state {
+				pins = "gpio14", "gpio15";
+				function = "qup1";
+			};
+
+			qup_i2c6_data_clk: qup-i2c6-data-clk-state {
+				pins = "gpio6", "gpio7";
+				function = "qup1";
+			};
+
+			qup_i2c7_data_clk: qup-i2c7-data-clk-state {
+				pins = "gpio10", "gpio11";
+				function = "qup1";
+			};
+
+			qup_spi2_data_clk: qup-spi2-data-clk-state {
+				pins = "gpio0", "gpio1", "gpio2";
+				function = "qup0";
+			};
+
+			qup_spi2_cs: qup-spi2-cs-state {
+				pins = "gpio3";
+				function = "qup0";
+			};
+
+			qup_spi2_cs_gpio: qup-spi2-cs-gpio-state {
+				pins = "gpio3";
+				function = "gpio";
+			};
+
+			qup_spi4_data_clk: qup-spi4-data-clk-state {
+				pins = "gpio20", "gpio21", "gpio22";
+				function = "qup1";
+			};
+
+			qup_spi4_cs: qup-spi4-cs-state {
+				pins = "gpio23";
+				function = "qup1";
+			};
+
+			qup_spi4_cs_gpio: qup-spi4-cs-gpio-state {
+				pins = "gpio23";
+				function = "gpio";
+			};
+
+			qup_spi6_data_clk: qup-spi6-data-clk-state {
+				pins = "gpio6", "gpio7", "gpio8";
+				function = "qup1";
+			};
+
+			qup_spi6_cs: qup-spi6-cs-state {
+				pins = "gpio9";
+				function = "qup1";
+			};
+
+			qup_spi6_cs_gpio: qup-spi6-cs-gpio-state {
+				pins = "gpio9";
+				function = "gpio";
+			};
+
+			qup_spi7_data_clk: qup-spi7-data-clk-state {
+				pins = "gpio10", "gpio11", "gpio12";
+				function = "qup1";
+			};
+
+			qup_spi7_cs: qup-spi7-cs-state {
+				pins = "gpio13";
+				function = "qup1";
+			};
+
+			qup_spi7_cs_gpio: qup-spi7-cs-gpio-state {
+				pins = "gpio13";
+				function = "gpio";
+			};
+
+			qup_uart0_tx: qup-uart0-tx-state {
+				pins = "gpio16";
+				function = "qup0";
+			};
+
+			qup_uart0_rx: qup-uart0-rx-state {
+				pins = "gpio17";
+				function = "qup0";
+			};
+
+			qup_uart2_cts: qup-uart2-cts-state {
+				pins = "gpio0";
+				function = "qup0";
+			};
+
+			qup_uart2_rts: qup-uart2-rts-state {
+				pins = "gpio1";
+				function = "qup0";
+			};
+
+			qup_uart2_tx: qup-uart2-tx-state {
+				pins = "gpio2";
+				function = "qup0";
+			};
+
+			qup_uart2_rx: qup-uart2-rx-state {
+				pins = "gpio3";
+				function = "qup0";
+			};
+
+			qup_uart4_cts: qup-uart4-cts-state {
+				pins = "gpio20";
+				function = "qup1";
+			};
+
+			qup_uart4_rts: qup-uart4-rts-state {
+				pins = "gpio21";
+				function = "qup1";
+			};
+
+			qup_uart4_tx: qup-uart4-tx-state {
+				pins = "gpio22";
+				function = "qup1";
+			};
+
+			qup_uart4_rx: qup-uart4-rx-state {
+				pins = "gpio23";
+				function = "qup1";
+			};
+
+			qup_uart6_cts: qup-uart6-cts-state {
+				pins = "gpio6";
+				function = "qup1";
+			};
+
+			qup_uart6_rts: qup-uart6-rts-state {
+				pins = "gpio7";
+				function = "qup1";
+			};
+
+			qup_uart6_tx: qup-uart6-tx-state {
+				pins = "gpio8";
+				function = "qup1";
+			};
+
+			qup_uart6_rx: qup-uart6-rx-state {
+				pins = "gpio9";
+				function = "qup1";
+			};
+
+			qup_uart7_cts: qup-uart7-cts-state {
+				pins = "gpio10";
+				function = "qup1";
+			};
+
+			qup_uart7_rts: qup-uart7-rts-state {
+				pins = "gpio11";
+				function = "qup1";
+			};
+
+			qup_uart7_tx: qup-uart7-tx-state {
+				pins = "gpio12";
+				function = "qup1";
+			};
+
+			qup_uart7_rx: qup-uart7-rx-state {
+				pins = "gpio13";
+				function = "qup1";
+			};
+
+			sdc1_state_on: sdc1-on-state {
+				clk-pins {
+					pins = "sdc1_clk";
+					bias-disable;
+					drive-strength = <16>;
+				};
+
+				cmd-pins {
+					pins = "sdc1_cmd";
+					bias-pull-up;
+					drive-strength = <10>;
+				};
+
+				data-pins {
+					pins = "sdc1_data";
+					bias-pull-up;
+					drive-strength = <10>;
+				};
+
+				rclk-pins {
+					pins = "sdc1_rclk";
+					bias-pull-down;
+				};
+			};
+
+			sdc1_state_off: sdc1-off-state {
+				clk-pins {
+					pins = "sdc1_clk";
+					bias-disable;
+					drive-strength = <2>;
+				};
+
+				cmd-pins {
+					pins = "sdc1_cmd";
+					bias-pull-up;
+					drive-strength = <2>;
+				};
+
+				data-pins {
+					pins = "sdc1_data";
+					bias-pull-up;
+					drive-strength = <2>;
+				};
+
+				rclk-pins {
+					pins = "sdc1_rclk";
+					bias-pull-down;
+				};
+			};
+
+			sdc2_state_on: sdc2-on-state {
+				clk-pins {
+					pins = "sdc2_clk";
+					bias-disable;
+					drive-strength = <16>;
+				};
+
+				cmd-pins {
+					pins = "sdc2_cmd";
+					bias-pull-up;
+					drive-strength = <10>;
+				};
+
+				data-pins {
+					pins = "sdc2_data";
+					bias-pull-up;
+					drive-strength = <10>;
+				};
+			};
+
+			sdc2_state_off: sdc2-off-state {
+				clk-pins {
+					pins = "sdc2_clk";
+					bias-disable;
+					drive-strength = <2>;
+				};
+
+				cmd-pins {
+					pins = "sdc2_cmd";
+					bias-pull-up;
+					drive-strength = <2>;
+				};
+
+				data-pins {
+					pins = "sdc2_data";
+					bias-pull-up;
+					drive-strength = <2>;
+				};
+			};
+		};
+
+		stm@6002000 {
+			compatible = "arm,coresight-stm", "arm,primecell";
+			reg = <0x0 0x06002000 0x0 0x1000>,
+			      <0x0 0x16280000 0x0 0x180000>;
+			reg-names = "stm-base",
+				    "stm-stimulus-base";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					stm_out: endpoint {
+						remote-endpoint = <&funnel_in0_in7>;
+					};
+				};
+			};
+		};
+
+		tpda@6004000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x06004000 0x0 0x1000>;
+			device-name = "tpda_qdss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					tpda_qdss_in0: endpoint {
+						remote-endpoint = <&tpdm_center_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+
+					tpda_qdss_in4: endpoint {
+						remote-endpoint = <&funnel_monaq_out>;
+					};
+				};
+
+				port@5 {
+					reg = <5>;
+
+					tpda_qdss_in5: endpoint {
+						remote-endpoint = <&funnel_ddr_0_out>;
+					};
+				};
+
+				port@6 {
+					reg = <6>;
+
+					tpda_qdss_in6: endpoint {
+						remote-endpoint = <&funnel_turing_out>;
+					};
+				};
+
+				port@7 {
+					reg = <7>;
+
+					tpda_qdss_in7: endpoint {
+						remote-endpoint = <&tpdm_vsense_out>;
+					};
+				};
+
+				port@8 {
+					reg = <8>;
+
+					tpda_qdss_in8: endpoint {
+						remote-endpoint = <&tpdm_dcc_out>;
+					};
+				};
+
+				port@9 {
+					reg = <9>;
+
+					tpda_qdss_in9: endpoint {
+						remote-endpoint = <&tpdm_prng_out>;
+					};
+				};
+
+				port@b {
+					reg = <11>;
+
+					tpda_qdss_in11: endpoint {
+						remote-endpoint = <&tpdm_qm_out>;
+					};
+				};
+
+				port@c {
+					reg = <12>;
+
+					tpda_qdss_in12: endpoint {
+						remote-endpoint = <&tpdm_west_out>;
+					};
+				};
+
+				port@d {
+					reg = <13>;
+
+					tpda_qdss_in13: endpoint {
+						remote-endpoint = <&tpdm_pimem_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					tpda_qdss_out: endpoint {
+						remote-endpoint = <&funnel_qatb_in>;
+					};
+				};
+			};
+		};
+
+		funnel@6005000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x06005000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					funnel_qatb_in: endpoint {
+						remote-endpoint = <&tpda_qdss_out>;
+					};
+				};
+
+				port@5 {
+					reg = <5>;
+
+					funnel_qatb_in5: endpoint {
+						remote-endpoint = <&dup_funnel_monaq_out>;
+					};
+				};
+
+				port@7 {
+					reg = <7>;
+
+					funnel_qatb_in7: endpoint {
+						remote-endpoint = <&dup_funnel_turing_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					funnel_qatb_out: endpoint {
+						remote-endpoint = <&funnel_in0_in6>;
+					};
+				};
+			};
+		};
+
+		cti@6010000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06010000 0x0 0x1000>;
+			device-name = "cti_qdss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6011000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06011000 0x0 0x1000>;
+			device-name = "cti_qdss_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6012000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06012000 0x0 0x1000>;
+			device-name = "cti_qdss_2";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6013000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06013000 0x0 0x1000>;
+			device-name = "cti_qdss_3";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6014000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06014000 0x0 0x1000>;
+			device-name = "cti_qdss_4";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6015000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06015000 0x0 0x1000>;
+			device-name = "cti_qdss_5";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6016000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06016000 0x0 0x1000>;
+			device-name = "cti_qdss_6";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6017000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06017000 0x0 0x1000>;
+			device-name = "cti_qdss_7";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6018000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06018000 0x0 0x1000>;
+			device-name = "cti_qdss_8";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6019000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06019000 0x0 0x1000>;
+			device-name = "cti_qdss_9";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@601a000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0601a000 0x0 0x1000>;
+			device-name = "cti_qdss_10";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@601b000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0601b000 0x0 0x1000>;
+			device-name = "cti_qdss_11";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@601c000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0601c000 0x0 0x1000>;
+			device-name = "cti_qdss_12";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@601d000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0601d000 0x0 0x1000>;
+			device-name = "cti_qdss_13";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@601e000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0601e000 0x0 0x1000>;
+			device-name = "cti_qdss_14";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@601f000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0601f000 0x0 0x1000>;
+			device-name = "cti_qdss_15";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		funnel@6041000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x06041000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@6 {
+					reg = <6>;
+
+					funnel_in0_in6: endpoint {
+						remote-endpoint = <&funnel_qatb_out>;
+					};
+				};
+
+				port@7 {
+					reg = <7>;
+
+					funnel_in0_in7: endpoint {
+						remote-endpoint = <&stm_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					funnel_in0_out: endpoint {
+						remote-endpoint = <&funnel_merg_in0>;
+					};
+				};
+			};
+		};
+
+		funnel@6042000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x06042000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@3 {
+					reg = <3>;
+
+					funnel_in1_in3: endpoint {
+						remote-endpoint = <&replicator_swao_out0>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+
+					funnel_in1_in4: endpoint {
+						remote-endpoint = <&tpdm_wcss_out>;
+					};
+				};
+
+				port@7 {
+					reg = <7>;
+
+					funnel_in1_in7: endpoint {
+						remote-endpoint = <&funnel_apss_merg_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					funnel_in1_out: endpoint {
+						remote-endpoint = <&funnel_merg_in1>;
+					};
+				};
+			};
+		};
+
+		funnel@6045000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x06045000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					funnel_merg_in0: endpoint {
+						remote-endpoint = <&funnel_in0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					funnel_merg_in1: endpoint {
+						remote-endpoint = <&funnel_in1_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					funnel_merg_out: endpoint {
+						remote-endpoint = <&tmc_etf_in>;
+					};
+				};
+			};
+		};
+
+		replicator@6046000 {
+			compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+			reg = <0x0 0x06046000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					replicator0_in: endpoint {
+						remote-endpoint= <&tmc_etf_out>;
+					};
+				};
+			};
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					replicator0_out0: endpoint {
+						remote-endpoint = <&tmc_etr_in>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					replicator0_out1: endpoint {
+						remote-endpoint= <&replicator1_in>;
+					};
+				};
+			};
+		};
+
+		tmc@6047000 {
+			compatible = "arm,coresight-tmc", "arm,primecell";
+			reg = <0x0 0x06047000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					tmc_etf_in: endpoint {
+						remote-endpoint = <&funnel_merg_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					tmc_etf_out: endpoint {
+						remote-endpoint = <&replicator0_in>;
+					};
+				};
+			};
+		};
+
+		tmc_etr: tmc@6048000 {
+			compatible = "arm,coresight-tmc", "arm,primecell";
+			reg = <0x0 0x06048000 0x0 0x1000>,
+			      <0x0 0x06064000 0x0 0x15000>;
+			reg-names = "tmc-base",
+				    "bam-base";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			iommus = <&apps_smmu 0x00a0 0x0>,
+				 <&apps_smmu 0x01e0 0x0>;
+
+			arm,scatter-gather;
+			arm,buffer-size = <0x400000>;
+
+			in-ports {
+				port {
+					tmc_etr_in: endpoint {
+						remote-endpoint = <&replicator0_out0>;
+					};
+				};
+			};
+		};
+
+		replicator@604a000 {
+			compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+			reg = <0x0 0x0604a000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					replicator1_in: endpoint {
+						remote-endpoint= <&replicator0_out1>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					replicator1_out: endpoint {
+						remote-endpoint= <&funnel_swao_in6>;
+					};
+				};
+			};
+		};
+
+		funnel@6080000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x06080000 0x0 0x10>,
+			      <0x0 0x06861000 0x0 0x1000>;
+			reg-names = "funnel-base-dummy",
+				    "funnel-base-real";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			arm,primecell-periphid = <0x000bb908>;
+			qcom,duplicate-funnel;
+
+			in-ports {
+				port {
+					dup_funnel_turing_in: endpoint {
+						remote-endpoint = <&turing0_etm0_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					dup_funnel_turing_out: endpoint {
+						remote-endpoint = <&funnel_qatb_in7>;
+					};
+				};
+			};
+		};
+
+		cti@683b000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0683b000 0x0 0x1000>;
+			device-name = "cti_qdsp6";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		tpdm@6840000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06840000 0x0 0x1000>;
+			device-name = "tpdm_vsense";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					tpdm_vsense_out: endpoint {
+						remote-endpoint = <&tpda_qdss_in7>;
+					};
+				};
+			};
+		};
+
+		tpdm@684c000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x0684c000 0x0 0x1000>;
+			device-name = "tpdm_prng";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					tpdm_prng_out: endpoint {
+						remote-endpoint = <&tpda_qdss_in9>;
+					};
+				};
+			};
+		};
+
+		tpdm@6850000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06850000 0x0 0x1000>;
+			device-name = "tpdm_pimem";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					tpdm_pimem_out: endpoint {
+						remote-endpoint = <&tpda_qdss_in13>;
+					};
+				};
+			};
+		};
+
+		tpdm@6860000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06860000 0x0 0x1000>;
+			device-name = "tpdm_turing";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					tpdm_turing_out: endpoint {
+						remote-endpoint = <&funnel_turing_in>;
+					};
+				};
+			};
+		};
+
+		funnel@6861000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x06861000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					funnel_turing_in: endpoint {
+						remote-endpoint = <&tpdm_turing_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					funnel_turing_out: endpoint {
+						remote-endpoint = <&tpda_qdss_in6>;
+					};
+				};
+			};
+		};
+
+		cti@6867000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06867000 0x0 0x1000>;
+			device-name = "cti_turing";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		tpdm@6870000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06870000 0x0 0x1000>;
+			device-name = "tpdm_dcc";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					tpdm_dcc_out: endpoint {
+						remote-endpoint = <&tpda_qdss_in8>;
+					};
+				};
+			};
+		};
+
+		tpdm@699c000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x0699c000 0x0 0x1000>;
+			device-name = "tpdm_wcss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					tpdm_wcss_out: endpoint {
+						remote-endpoint = <&funnel_in1_in4>;
+					};
+				};
+			};
+		};
+
+		tpdm@69c0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x069c0000 0x0 0x1000>;
+			device-name = "tpdm_monaq";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					tpdm_monaq_out: endpoint {
+						remote-endpoint = <&funnel_monaq_in>;
+					};
+				};
+			};
+		};
+
+		funnel@69c1000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x069c1000 0x0 0x1>,
+			      <0x0 0x069c3000 0x0 0x1000>;
+			reg-names = "funnel-base-dummy",
+				    "funnel-base-real";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			arm,primecell-periphid = <0x000bb908>;
+			qcom,duplicate-funnel;
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					reg = <1>;
+
+					dup_funnel_monaq_in1: endpoint {
+						remote-endpoint = <&audio_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					dup_funnel_monaq_out: endpoint {
+						remote-endpoint = <&funnel_qatb_in5>;
+					};
+				};
+			};
+		};
+
+		funnel@69c3000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x069c3000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					funnel_monaq_in: endpoint {
+						remote-endpoint = <&tpdm_monaq_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					funnel_monaq_out: endpoint {
+						remote-endpoint = <&tpda_qdss_in4>;
+					};
+				};
+			};
+		};
+
+		tpdm@69d0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x069d0000 0x0 0x1000>;
+			device-name = "tpdm_qm";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					tpdm_qm_out: endpoint {
+						remote-endpoint = <&tpda_qdss_in11>;
+					};
+				};
+			};
+		};
+
+		tpdm@6a00000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06a00000 0x0 0x1000>;
+			device-name = "tpdm_ddr";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					tpdm_ddr_out: endpoint {
+						remote-endpoint = <&funnel_ddr_0_in>;
+					};
+				};
+			};
+		};
+
+		cti@6a02000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06a02000 0x0 0x1000>;
+			device-name = "cti_ddr_dl0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6a03000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06a03000 0x0 0x1000>;
+			device-name = "cti_ddr_dl0_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6a10000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06a10000 0x0 0x1000>;
+			device-name = "cti_ddr_dl1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6a11000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06a11000 0x0 0x1000>;
+			device-name = "cti_ddr_dl1_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		funnel@6a05000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x06a05000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					funnel_ddr_0_in: endpoint {
+						remote-endpoint = <&tpdm_ddr_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					funnel_ddr_0_out: endpoint {
+						remote-endpoint = <&tpda_qdss_in5>;
+					};
+				};
+			};
+		};
+
+		tpda@6b01000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x06b01000 0x0 0x1000>;
+			device-name = "tpda_swao";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					tpda_swao_in0: endpoint {
+						remote-endpoint = <&tpdm_swao0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					tpda_swao_in1: endpoint {
+						remote-endpoint = <&tpdm_swao1_out>;
+					};
+
+				};
+			};
+
+			out-ports {
+				port {
+					tpda_swao_out: endpoint {
+						remote-endpoint = <&funnel_swao_in7>;
+					};
+				};
+			};
+		};
+
+		tpdm@6b02000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06b02000 0x0 0x1000>;
+			device-name = "tpdm_swao_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					tpdm_swao0_out: endpoint {
+						remote-endpoint = <&tpda_swao_in0>;
+					};
+				};
+			};
+		};
+
+		tpdm@6b03000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06b03000 0x0 0x1000>;
+			device-name = "tpdm_swao_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					tpdm_swao1_out: endpoint {
+						remote-endpoint = <&tpda_swao_in1>;
+					};
+				};
+			};
+		};
+
+		cti@6b04000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06b04000 0x0 0x1000>;
+			device-name = "cti_swao";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6b05000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06b05000 0x0 0x1000>;
+			device-name = "cti_swao_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6b06000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06b06000 0x0 0x1000>;
+			device-name = "cti_swao_2";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6b07000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06b07000 0x0 0x1000>;
+			device-name = "cti_swao_3";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		funnel@6b08000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x06b08000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@6 {
+					reg = <6>;
+
+					funnel_swao_in6: endpoint {
+						remote-endpoint= <&replicator1_out>;
+					};
+				};
+
+				port@7 {
+					reg = <7>;
+
+					funnel_swao_in7: endpoint {
+						remote-endpoint= <&tpda_swao_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					funnel_swao_out: endpoint {
+						remote-endpoint = <&tmc_etf_swao_in>;
+					};
+				};
+			};
+		};
+
+		tmc@6b09000 {
+			compatible = "arm,coresight-tmc", "arm,primecell";
+			reg = <0x0 0x06b09000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					tmc_etf_swao_in: endpoint {
+						remote-endpoint= <&funnel_swao_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					tmc_etf_swao_out: endpoint {
+						remote-endpoint= <&replicator_swao_in>;
+					};
+				};
+			};
+		};
+
+		replicator@6b0a000 {
+			compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+			reg = <0x0 0x06b0a000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					replicator_swao_in: endpoint {
+						remote-endpoint = <&tmc_etf_swao_out>;
+					};
+				};
+			};
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					replicator_swao_out0: endpoint {
+						remote-endpoint = <&funnel_in1_in3>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					replicator_swao_out1: endpoint {
+						remote-endpoint = <&eud_in>;
+					};
+				};
+			};
+		};
+
+		cti@6b21000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06b21000 0x0 0x1000>;
+			device-name = "cti_aop_m3";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		tpdm@6b48000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06b48000 0x0 0x1000>;
+			device-name = "tpdm_west";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					tpdm_west_out: endpoint {
+						remote-endpoint = <&tpda_qdss_in12>;
+					};
+				};
+			};
+		};
+
+		cti@6c13000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06c13000 0x0 0x1000>;
+			device-name = "cti_titan";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6c20000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06c20000 0x0 0x1000>;
+			device-name = "cti_venus";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		tpdm@6c28000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06c28000 0x0 0x1000>;
+			device-name = "tpdm_center";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					tpdm_center_out: endpoint {
+						remote-endpoint = <&tpda_qdss_in0>;
+					};
+				};
+			};
+		};
+
+		cti@6c29000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06c29000 0x0 0x1000>;
+			device-name = "cti_dlct";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6c2a000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06c2a000 0x0 0x1000>;
+			device-name = "cti_dlct_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@7020000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07020000 0x0 0x1000>;
+			device-name = "cti_apss_apb_2";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		etm@7040000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x07040000 0x0 0x1000>;
+			cpu = <&cpu0>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm0_out: endpoint {
+						remote-endpoint = <&funnel_apss_in0>;
+					};
+				};
+			};
+		};
+
+		cti@7120000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07120000 0x0 0x1000>;
+			device-name = "cti_apss_apb_3";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		etm@7140000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x07140000 0x0 0x1000>;
+			cpu = <&cpu1>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm1_out: endpoint {
+						remote-endpoint = <&funnel_apss_in1>;
+					};
+				};
+			};
+		};
+
+		cti@7220000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07220000 0x0 0x1000>;
+			device-name = "cti_apss_apb_4";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		etm@7240000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x07240000 0x0 0x1000>;
+			cpu = <&cpu2>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm2_out: endpoint {
+						remote-endpoint = <&funnel_apss_in2>;
+					};
+				};
+			};
+		};
+
+		cti@7320000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07320000 0x0 0x1000>;
+			device-name = "cti_apss_apb_5";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		etm@7340000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x07340000 0x0 0x1000>;
+			cpu = <&cpu3>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm3_out: endpoint {
+						remote-endpoint = <&funnel_apss_in3>;
+					};
+				};
+			};
+		};
+
+		cti@7420000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07420000 0x0 0x1000>;
+			device-name = "cti_apss_apb_6";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		etm@7440000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x07440000 0x0 0x1000>;
+			cpu = <&cpu4>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm4_out: endpoint {
+						remote-endpoint = <&funnel_apss_in4>;
+					};
+				};
+			};
+		};
+
+		cti@7520000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07520000 0x0 0x1000>;
+			device-name = "cti_apss_apb_7";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		etm@7540000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x07540000 0x0 0x1000>;
+			cpu = <&cpu5>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm5_out: endpoint {
+						remote-endpoint = <&funnel_apss_in5>;
+					};
+				};
+			};
+		};
+
+		cti@7620000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07620000 0x0 0x1000>;
+			device-name = "cti_apss_apb_8";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		etm@7640000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x07640000 0x0 0x1000>;
+			cpu = <&cpu6>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm6_out: endpoint {
+						remote-endpoint = <&funnel_apss_in6>;
+					};
+				};
+			};
+		};
+
+		cti@7720000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07720000 0x0 0x1000>;
+			device-name = "cti_apss_apb_9";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		etm@7740000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x07740000 0x0 0x1000>;
+			cpu = <&cpu7>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm7_out: endpoint {
+						remote-endpoint = <&funnel_apss_in7>;
+					};
+				};
+			};
+		};
+
+		funnel@7800000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x07800000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					funnel_apss_in0: endpoint {
+						remote-endpoint = <&etm0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					funnel_apss_in1: endpoint {
+						remote-endpoint = <&etm1_out>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+
+					funnel_apss_in2: endpoint {
+						remote-endpoint = <&etm2_out>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+
+					funnel_apss_in3: endpoint {
+						remote-endpoint = <&etm3_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+
+					funnel_apss_in4: endpoint {
+						remote-endpoint = <&etm4_out>;
+					};
+				};
+
+				port@5 {
+					reg = <5>;
+
+					funnel_apss_in5: endpoint {
+						remote-endpoint = <&etm5_out>;
+					};
+				};
+
+				port@6 {
+					reg = <6>;
+
+					funnel_apss_in6: endpoint {
+						remote-endpoint = <&etm6_out>;
+					};
+				};
+
+				port@7 {
+					reg = <7>;
+
+					funnel_apss_in7: endpoint {
+						remote-endpoint = <&etm7_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					funnel_apss_out: endpoint {
+						remote-endpoint = <&funnel_apss_merg_in0>;
+					};
+				};
+			};
+		};
+
+		funnel@7810000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x07810000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					funnel_apss_merg_in0: endpoint {
+						remote-endpoint = <&funnel_apss_out>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+
+					funnel_apss_merg_in2: endpoint {
+						remote-endpoint = <&tpda_olc_out>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+
+					funnel_apss_merg_in3: endpoint {
+						remote-endpoint = <&tpda_llm_silver_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+
+					funnel_apss_merg_in4: endpoint {
+						remote-endpoint = <&tpda_llm_gold_out>;
+					};
+				};
+
+				port@5 {
+					reg = <5>;
+
+					funnel_apss_merg_in5: endpoint {
+						remote-endpoint = <&tpda_apss_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					funnel_apss_merg_out: endpoint {
+						remote-endpoint = <&funnel_in1_in7>;
+					};
+				};
+			};
+		};
+
+		tpdm@7830000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x07830000 0x0 0x1000>;
+			device-name = "tpdm_olc";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					tpdm_olc_out: endpoint {
+						remote-endpoint = <&tpda_olc_in>;
+					};
+				};
+			};
+		};
+
+		tpda@7832000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x07832000 0x0 0x1000>;
+			device-name = "tpda_olc";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					tpda_olc_in: endpoint {
+						remote-endpoint = <&tpdm_olc_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					tpda_olc_out: endpoint {
+						remote-endpoint = <&funnel_apss_merg_in2>;
+					};
+				};
+			};
+		};
+
+		tpdm@7860000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x07860000 0x0 0x1000>;
+			device-name = "tpdm_apss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					tpdm_apss_out: endpoint {
+						remote-endpoint = <&tpda_apss_in>;
+					};
+				};
+			};
+		};
+
+		tpda@7862000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x07862000 0x0 0x1000>;
+			device-name = "tpda_apss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					tpda_apss_in: endpoint {
+						remote-endpoint = <&tpdm_apss_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					tpda_apss_out: endpoint {
+						remote-endpoint = <&funnel_apss_merg_in5>;
+					};
+				};
+			};
+		};
+
+		tpdm@78a0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x078a0000 0x0 0x1000>;
+			device-name = "tpdm_llm_silver";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					tpdm_llm_silver_out: endpoint {
+						remote-endpoint = <&tpda_llm_silver_in>;
+					};
+				};
+			};
+		};
+
+		tpdm@78b0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x078b0000 0x0 0x1000>;
+			device-name = "tpdm_llm_gold";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					tpdm_llm_gold_out: endpoint {
+						remote-endpoint = <&tpda_llm_gold_in>;
+					};
+				};
+			};
+		};
+
+		tpda@78c0000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x078c0000 0x0 0x1000>;
+			device-name = "tpda_llm_silver";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					tpda_llm_silver_in: endpoint {
+						remote-endpoint = <&tpdm_llm_silver_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					tpda_llm_silver_out: endpoint {
+						remote-endpoint = <&funnel_apss_merg_in3>;
+					};
+				};
+			};
+		};
+
+		tpda@78d0000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x078d0000 0x0 0x1000>;
+			device-name = "tpda_llm_gold";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					tpda_llm_gold_in: endpoint {
+						remote-endpoint = <&tpdm_llm_gold_out>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					tpda_llm_gold_out: endpoint {
+						remote-endpoint = <&funnel_apss_merg_in4>;
+					};
+				};
+			};
+		};
+
+		cti@78e0000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x078e0000 0x0 0x1000>;
+			device-name = "cti_apss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@78f0000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x078f0000 0x0 0x1000>;
+			device-name = "cti_apss_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@7900000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07900000 0x0 0x1000>;
+			device-name = "cti_apss_2";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		pmu@90b6300 {
+			compatible = "qcom,qcs615-cpu-bwmon", "qcom,sdm845-bwmon";
+			reg = <0x0 0x090b6300 0x0 0x600>;
+			interrupts = <GIC_SPI 581 IRQ_TYPE_LEVEL_HIGH>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+			operating-points-v2 = <&cpu_bwmon_opp_table>;
+
+			cpu_bwmon_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-0 {
+					opp-peak-kBps = <12896000>;
+				};
+
+				opp-1 {
+					opp-peak-kBps = <14928000>;
+				};
+			};
+		};
+
+		pmu@90cd000 {
+			compatible = "qcom,qcs615-llcc-bwmon", "qcom,sc7280-llcc-bwmon";
+			reg = <0x0 0x090cd000 0x0 0x1000>;
+			interrupts = <GIC_SPI 667 IRQ_TYPE_LEVEL_HIGH>;
+			interconnects = <&mc_virt MASTER_LLCC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+			operating-points-v2 = <&llcc_bwmon_opp_table>;
+
+			llcc_bwmon_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-0 {
+					opp-peak-kBps = <800000>;
+				};
+
+				opp-1 {
+					opp-peak-kBps = <1200000>;
+				};
+
+				opp-2 {
+					opp-peak-kBps = <1804800>;
+				};
+
+				opp-3 {
+					opp-peak-kBps = <2188800>;
+				};
+
+				opp-4 {
+					opp-peak-kBps = <2726400>;
+				};
+
+				opp-5 {
+					opp-peak-kBps = <3072000>;
+				};
+
+				opp-6 {
+					opp-peak-kBps = <4070400>;
+				};
+
+				opp-7 {
+					opp-peak-kBps = <5414400>;
+				};
+
+				opp-8 {
+					opp-peak-kBps = <6220800>;
+				};
+			};
+		};
+
+		sdhc_2: mmc@8804000 {
+			compatible = "qcom,qcs615-sdhci", "qcom,sdhci-msm-v5";
+			reg = <0x0 0x08804000 0x0 0x1000>;
+			reg-names = "hc";
+
+			interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "hc_irq",
+					  "pwr_irq";
+
+			clocks = <&gcc GCC_SDCC2_AHB_CLK>,
+				 <&gcc GCC_SDCC2_APPS_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "iface",
+				      "core",
+				      "xo";
+
+			power-domains = <&rpmhpd RPMHPD_CX>;
+			operating-points-v2 = <&sdhc2_opp_table>;
+			iommus = <&apps_smmu 0x02a0 0x0>;
+			resets = <&gcc GCC_SDCC2_BCR>;
+			interconnects = <&aggre1_noc MASTER_SDCC_2 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &config_noc SLAVE_SDCC_2 QCOM_ICC_TAG_ACTIVE_ONLY>;
+			interconnect-names = "sdhc-ddr",
+					     "cpu-sdhc";
+
+			qcom,dll-config = <0x0007642c>;
+			qcom,ddr-config = <0x80040868>;
+			dma-coherent;
+
+			status = "disabled";
+
+			sdhc2_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-50000000 {
+					opp-hz = /bits/ 64 <50000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+				};
+
+				opp-100000000 {
+					opp-hz = /bits/ 64 <100000000>;
+					required-opps = <&rpmhpd_opp_svs>;
+				};
+
+				opp-202000000 {
+					opp-hz = /bits/ 64 <202000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+				};
+			};
+		};
+
+		gpucc: clock-controller@5090000 {
+			compatible = "qcom,qcs615-gpucc";
+			reg = <0x0 0x05090000 0x0 0x9000>;
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GPLL0>;
+
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
+		dc_noc: interconnect@9160000 {
+			reg = <0x0 0x09160000 0x0 0x3200>;
+			compatible = "qcom,qcs615-dc-noc";
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		llcc: system-cache-controller@9200000 {
+			compatible = "qcom,qcs615-llcc";
+			reg = <0x0 0x09200000 0x0 0x50000>,
+			      <0x0 0x09600000 0x0 0x50000>;
+			reg-names = "llcc0_base",
+				    "llcc_broadcast_base";
+		};
+
+		gem_noc: interconnect@9680000 {
+			reg = <0x0 0x09680000 0x0 0x3e200>;
+			compatible = "qcom,qcs615-gem-noc";
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		videocc: clock-controller@ab00000 {
+			compatible = "qcom,qcs615-videocc";
+			reg = <0x0 0x0ab00000 0x0 0x10000>;
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>,
+				 <&sleep_clk>;
+
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
+		camcc: clock-controller@ad00000 {
+			compatible = "qcom,qcs615-camcc";
+			reg = <0x0 0x0ad00000 0x0 0x10000>;
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
+		dispcc: clock-controller@af00000 {
+			compatible = "qcom,qcs615-dispcc";
+			reg = <0x0 0x0af00000 0x0 0x20000>;
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_DISP_GPLL0_DIV_CLK_SRC>;
+
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
+		pdc: interrupt-controller@b220000 {
+			compatible = "qcom,qcs615-pdc", "qcom,pdc";
+			reg = <0x0 0x0b220000 0x0 0x30000>,
+			      <0x0 0x17c000f0 0x0 0x64>;
+			qcom,pdc-ranges = <0 480 94>, <94 609 31>, <125 63 1>;
+			interrupt-parent = <&intc>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+		};
+
+		aoss_qmp: power-controller@c300000 {
+			compatible = "qcom,qcs615-aoss-qmp", "qcom,aoss-qmp";
+			reg = <0x0 0x0c300000 0x0 0x400>;
+			interrupts = <GIC_SPI 389 IRQ_TYPE_EDGE_RISING>;
+			mboxes = <&apss_shared 0>;
+
+			#clock-cells = <0>;
+			#power-domain-cells = <1>;
+		};
+
+		sram@c3f0000 {
+			compatible = "qcom,rpmh-stats";
+			reg = <0x0 0x0c3f0000 0x0 0x400>;
+		};
+
+		apps_smmu: iommu@15000000 {
+			compatible = "qcom,qcs615-smmu-500", "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x15000000 0x0 0x80000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <1>;
+			dma-coherent;
+
+			interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		spmi_bus: spmi@c440000 {
+			compatible = "qcom,spmi-pmic-arb";
+			reg = <0x0 0x0c440000 0x0 0x1100>,
+			      <0x0 0x0c600000 0x0 0x2000000>,
+			      <0x0 0x0e600000 0x0 0x100000>,
+			      <0x0 0x0e700000 0x0 0xa0000>,
+			      <0x0 0x0c40a000 0x0 0x26000>;
+			reg-names = "core",
+				    "chnls",
+				    "obsrvr",
+				    "intr",
+				    "cnfg";
+			interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "periph_irq";
+			interrupt-controller;
+			#interrupt-cells = <4>;
+			#address-cells = <2>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			qcom,channel = <0>;
+			qcom,ee = <0>;
+		};
+
+		intc: interrupt-controller@17a00000 {
+			compatible = "arm,gic-v3";
+			reg = <0x0 0x17a00000 0x0 0x10000>,     /* GICD */
+			      <0x0 0x17a60000 0x0 0x100000>;    /* GICR * 8 */
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			#redistributor-regions = <1>;
+			redistributor-stride = <0x0 0x20000>;
+		};
+
+		apss_shared: mailbox@17c00000 {
+			compatible = "qcom,qcs615-apss-shared",
+				     "qcom,sdm845-apss-shared";
+			reg = <0x0 0x17c00000 0x0 0x1000>;
+			#mbox-cells = <1>;
+		};
+
+		watchdog: watchdog@17c10000 {
+			compatible = "qcom,apss-wdt-qcs615", "qcom,kpss-wdt";
+			reg = <0x0 0x17c10000 0x0 0x1000>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		timer@17c20000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x17c20000 0x0 0x1000>;
+			ranges = <0 0 0 0x20000000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			frame@17c21000 {
+				reg = <0x17c21000 0x1000>,
+				      <0x17c22000 0x1000>;
+				frame-number = <0>;
+				interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			};
+
+			frame@17c23000 {
+				reg = <0x17c23000 0x1000>;
+				frame-number = <1>;
+				interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame@17c25000 {
+				reg = <0x17c25000 0x1000>;
+				frame-number = <2>;
+				interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame@17c27000 {
+				reg = <0x17c27000 0x1000>;
+				frame-number = <3>;
+				interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame@17c29000 {
+				reg = <0x17c29000 0x1000>;
+				frame-number = <4>;
+				interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame@17c2b000 {
+				reg = <0x17c2b000 0x1000>;
+				frame-number = <5>;
+				interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame@17c2d000 {
+				reg = <0x17c2d000 0x1000>;
+				frame-number = <6>;
+				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+		};
+
+		apps_rsc: rsc@18200000 {
+			compatible = "qcom,rpmh-rsc";
+			reg = <0x0 0x18200000 0x0 0x10000>,
+			      <0x0 0x18210000 0x0 0x10000>,
+			      <0x0 0x18220000 0x0 0x10000>;
+			reg-names = "drv-0",
+				    "drv-1",
+				    "drv-2";
+
+			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+
+			qcom,drv-id = <2>;
+			qcom,tcs-offset = <0xd00>;
+			qcom,tcs-config = <ACTIVE_TCS    2>,
+					  <SLEEP_TCS     3>,
+					  <WAKE_TCS      3>,
+					  <CONTROL_TCS   1>;
+
+			label = "apps_rsc";
+			power-domains = <&cluster_pd>;
+
+			apps_bcm_voter: bcm-voter {
+				compatible = "qcom,bcm-voter";
+			};
+
+			rpmhcc: clock-controller {
+				compatible = "qcom,qcs615-rpmh-clk";
+				clock-names = "xo";
+
+				#clock-cells = <1>;
+			};
+
+			rpmhpd: power-controller {
+				compatible = "qcom,qcs615-rpmhpd";
+				#power-domain-cells = <1>;
+				operating-points-v2 = <&rpmhpd_opp_table>;
+
+				rpmhpd_opp_table: opp-table {
+					compatible = "operating-points-v2";
+
+					rpmhpd_opp_ret: opp-0 {
+						opp-level = <RPMH_REGULATOR_LEVEL_RETENTION>;
+					};
+
+					rpmhpd_opp_min_svs: opp-1 {
+						opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
+					};
+
+					rpmhpd_opp_low_svs: opp-2 {
+						opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+					};
+
+					rpmhpd_opp_svs: opp-3 {
+						opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+					};
+
+					rpmhpd_opp_svs_l1: opp-4 {
+						opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+					};
+
+					rpmhpd_opp_nom: opp-5 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+					};
+
+					rpmhpd_opp_nom_l1: opp-6 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+					};
+
+					rpmhpd_opp_nom_l2: opp-7 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM_L2>;
+					};
+
+					rpmhpd_opp_turbo: opp-8 {
+						opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+					};
+
+					rpmhpd_opp_turbo_l1: opp-9 {
+						opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+					};
+				};
+			};
+		};
+
+		usb_1_hsphy: phy@88e2000 {
+			compatible = "qcom,qcs615-qusb2-phy";
+			reg = <0x0 0x88e2000 0x0 0x180>;
+
+			clocks = <&gcc GCC_AHB2PHY_WEST_CLK>, <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "cfg_ahb", "ref";
+
+			resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
+			nvmem-cells = <&qusb2_hstx_trim>;
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
+		usb_hsphy_2: phy@88e3000 {
+			compatible = "qcom,qcs615-qusb2-phy";
+			reg = <0x0 0x088e3000 0x0 0x180>;
+
+			clocks = <&gcc GCC_AHB2PHY_WEST_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "cfg_ahb",
+				      "ref";
+
+			resets = <&gcc GCC_QUSB2PHY_SEC_BCR>;
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
+		usb_qmpphy: phy@88e6000 {
+			compatible = "qcom,qcs615-qmp-usb3-phy";
+			reg = <0x0 0x88e6000 0x0 0x1000>;
+
+			clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
+				 <&gcc GCC_USB3_PRIM_CLKREF_CLK>,
+				 <&gcc GCC_AHB2PHY_WEST_CLK>,
+				 <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+			clock-names = "aux",
+				      "ref",
+				      "cfg_ahb",
+				      "pipe";
+
+			resets = <&gcc GCC_USB3_PHY_PRIM_SP0_BCR>,
+				 <&gcc GCC_USB3PHY_PHY_PRIM_SP0_BCR>;
+			reset-names = "phy", "phy_phy";
+
+			qcom,tcsr-reg = <&tcsr 0xb244>;
+
+			clock-output-names = "usb3_phy_pipe_clk_src";
+			#clock-cells = <0>;
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
+		usb_1: usb@a6f8800 {
+			compatible = "qcom,qcs615-dwc3", "qcom,dwc3";
+			reg = <0x0 0x0a6f8800 0x0 0x400>;
+
+			clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>,
+				 <&gcc GCC_USB30_PRIM_MASTER_CLK>,
+				 <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>,
+				 <&gcc GCC_USB30_PRIM_SLEEP_CLK>,
+				 <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
+				 <&gcc GCC_USB3_PRIM_CLKREF_CLK>;
+			clock-names = "cfg_noc",
+				      "core",
+				      "iface",
+				      "sleep",
+				      "mock_utmi",
+				      "xo";
+
+			assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
+					  <&gcc GCC_USB30_PRIM_MASTER_CLK>;
+			assigned-clock-rates = <19200000>, <200000000>;
+
+			interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 8 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 6 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
+					  "dp_hs_phy_irq",
+					  "dm_hs_phy_irq",
+					  "ss_phy_irq";
+
+			power-domains = <&gcc USB30_PRIM_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
+
+			resets = <&gcc GCC_USB30_PRIM_BCR>;
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			status = "disabled";
+
+			usb_1_dwc3: usb@a600000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x0a600000 0x0 0xcd00>;
+
+				iommus = <&apps_smmu 0x140 0x0>;
+				interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+
+				phys = <&usb_1_hsphy>, <&usb_qmpphy>;
+				phy-names = "usb2-phy", "usb3-phy";
+
+				snps,dis-u1-entry-quirk;
+				snps,dis-u2-entry-quirk;
+				snps,dis_u2_susphy_quirk;
+				snps,dis_enblslpm_quirk;
+				snps,has-lpm-erratum;
+				snps,hird-threshold = /bits/ 8 <0x10>;
+				snps,usb3_lpm_capable;
+			};
+		};
+
+		usb_2: usb@a8f8800 {
+			compatible = "qcom,qcs615-dwc3", "qcom,dwc3";
+			reg = <0x0 0x0a8f8800 0x0 0x400>;
+
+			clocks = <&gcc GCC_CFG_NOC_USB2_SEC_AXI_CLK>,
+				 <&gcc GCC_USB20_SEC_MASTER_CLK>,
+				 <&gcc GCC_AGGRE_USB2_SEC_AXI_CLK>,
+				 <&gcc GCC_USB20_SEC_SLEEP_CLK>,
+				 <&gcc GCC_USB20_SEC_MOCK_UTMI_CLK>,
+				 <&gcc GCC_USB2_PRIM_CLKREF_CLK>;
+			clock-names = "cfg_noc",
+				      "core",
+				      "iface",
+				      "sleep",
+				      "mock_utmi",
+				      "xo";
+
+			assigned-clocks = <&gcc GCC_USB20_SEC_MOCK_UTMI_CLK>,
+					  <&gcc GCC_USB20_SEC_MASTER_CLK>;
+			assigned-clock-rates = <19200000>, <200000000>;
+
+			interrupts-extended = <&intc GIC_SPI 663 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 662 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 11 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 10 IRQ_TYPE_EDGE_BOTH>;
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
+					  "dp_hs_phy_irq",
+					  "dm_hs_phy_irq";
+
+			power-domains = <&gcc USB20_SEC_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
+
+			resets = <&gcc GCC_USB20_SEC_BCR>;
+
+			qcom,select-utmi-as-pipe-clk;
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			status = "disabled";
+
+			usb_2_dwc3: usb@a800000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x0a800000 0x0 0xcd00>;
+
+				iommus = <&apps_smmu 0xe0 0x0>;
+				interrupts = <GIC_SPI 664 IRQ_TYPE_LEVEL_HIGH>;
+
+				phys = <&usb_hsphy_2>;
+				phy-names = "usb2-phy";
+
+				snps,dis_u2_susphy_quirk;
+				snps,dis_enblslpm_quirk;
+				snps,has-lpm-erratum;
+				snps,hird-threshold = /bits/ 8 <0x10>;
+
+				maximum-speed = "high-speed";
+			};
+		};
+
+		tsens0: tsens@c222000 {
+			compatible = "qcom,qcs615-tsens", "qcom,tsens-v2";
+			reg = <0x0 0xc263000 0x0 0x1ff>,
+				<0x0 0xc222000 0x0 0x8>;
+			interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH>;
+			#qcom,sensors = <16>;
+			interrupt-names = "uplow", "critical";
+			#thermal-sensor-cells = <1>;
+		};
+
+	};
+
+	turing0-etm0 {
+		compatible = "qcom,coresight-remote-etm";
+		device-name = "turing0_etm0";
+
+		qcom,atid-num = <2>;
+		qcom,inst-id = <13>;
+		atid = <38 39>;
+
+		out-ports {
+			port {
+				turing0_etm0_out: endpoint {
+					remote-endpoint = <&dup_funnel_turing_in>;
+				};
+			};
+		};
+	};
+
+	cpufreq_hw: cpufreq@18323000 {
+		compatible = "qcom,cpufreq-hw";
+		reg = <0x0 0x18323000 0x0 0x1400>,
+		      <0x0 0x18325800 0x0 0x1400>;
+		reg-names = "freq-domain0", "freq-domain1";
+
+		clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GPLL0>;
+		clock-names = "xo", "alternate";
+
+		#freq-domain-cells = <1>;
+		#clock-cells = <1>;
+	};
+
+	arch_timer: timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 1 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 2 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 3 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 0 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	thermal-zones {
+		aoss-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&tsens0 0>;
+
+			trips {
+
+				trip-point0 {
+					temperature = <110000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpuss-0-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&tsens0 1>;
+
+			trips {
+
+				trip-point0 {
+					temperature = <115000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <118000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+
+		};
+
+		cpuss-1-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&tsens0 2>;
+
+			trips {
+
+				trip-point0 {
+					temperature = <115000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <118000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+
+		};
+
+		cpuss-2-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&tsens0 3>;
+
+			trips {
+
+				trip-point0 {
+					temperature = <115000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <118000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpuss-3-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&tsens0 4>;
+
+			trips {
+
+				trip-point0 {
+					temperature = <115000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <118000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-0-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&tsens0 5>;
+
+			trips {
+
+				trip-point0 {
+					temperature = <115000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <118000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-1-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&tsens0 6>;
+
+			trips {
+
+				trip-point0 {
+					temperature = <115000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <118000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+
+		};
+
+		cpu-1-2-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&tsens0 7>;
+
+			trips {
+
+				trip-point0 {
+					temperature = <115000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <118000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-3-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&tsens0 8>;
+
+			trips {
+
+				trip-point0 {
+					temperature = <115000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <118000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+
+		};
+
+		gpu-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&tsens0 9>;
+
+			trips {
+
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <110000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+
+		};
+
+		q6-hvx-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&tsens0 10>;
+
+			trips {
+
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <110000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+
+		mdm-core-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&tsens0 11>;
+
+			trips {
+				trip-point0 {
+					temperature = <110000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		camera-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&tsens0 12>;
+
+			trips {
+				trip-point0 {
+					temperature = <110000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+
+		wlan-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&tsens0 13>;
+
+			trips {
+				trip-point0 {
+					temperature = <110000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+
+		display-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&tsens0 14>;
+
+			trips {
+				trip-point0 {
+					temperature = <110000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+
+		video-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+
+			thermal-sensors = <&tsens0 15>;
+
+			trips {
+				trip-point0 {
+					temperature = <110000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2-hsp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2-hsp.dts
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * qcs6490-addons RB3gen2 device tree source
+ *
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
+
+/dts-v1/;
+
+#include "qcs6490-addons-rb3gen2.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. Robotics RB3gen2 addons hsp platform";
+	compatible = "qcom,qcs6490-addons-rb3gen2-hsp","qcom,qcm6490";
+
+	qcom,msm-id = <497 0x10000>, <498 0x10000>, <475 0x10000>, <515 0x10000>;
+	qcom,board-id = <32 0x6>, <32 0x606>;
+};
+
+&pcie0 {
+	perst-gpios = <&tlmm 87 GPIO_ACTIVE_LOW>;
+	pinctrl-0 = <&pcie0_reset_n>, <&pcie0_wake_n>, <&pcie0_clkreq_n>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	pcie0_port0: pcie@0 {
+		reg = <0x0 0x0 0x0 0x0 0x0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		ranges;
+
+		bus-range = <0x01 0xff>;
+		device_type = "pci";
+
+		wake-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&pcie0_phy {
+	status = "okay";
+	vdda-phy-supply = <&vreg_l10c_0p88>;
+	vdda-pll-supply = <&vreg_l6b_1p2>;
+};
+
+&remoteproc_mpss {
+	status = "disabled";
+};
+
+&remoteproc_wpss {
+	status = "disabled";
+};
+
+&uart7 {
+	/delete-node/ bluetooth;
+
+	bluetooth: bluetooth {
+		compatible = "qcom,wcn6855-bt";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bt_en>, <&sw_ctrl>;
+		enable-gpios = <&tlmm 85 GPIO_ACTIVE_HIGH>;
+		swctrl-gpios = <&tlmm 86 GPIO_ACTIVE_HIGH>;
+		vddio-supply = <&vreg_s7b_0p972>;
+		vddbtcxmx-supply = <&vreg_s7b_0p972>;
+		vddrfacmn-supply = <&vreg_s7b_0p972>;
+		vddrfa0p8-supply = <&vreg_s7b_0p972>;
+		vddrfa1p7-supply = <&vreg_s1b_1p872>;
+		vddrfa1p2-supply = <&vreg_s8b_1p272>;
+		max-speed = <3200000>;
+	};
+};
+
+&wifi {
+	status = "disabled";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2-ia-mezz.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2-ia-mezz.dts
@@ -0,0 +1,656 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs6490-rb3gen2.dts"
+#include "qcs6490-addons-rb3gen2.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. Robotics RB3gen2 addons ia mezz platform";
+	compatible = "qcom,qcs6490-addons-rb3gen2-ia-mezz", "qcom,qcm6490";
+
+	qcom,msm-id = <497 0x10000>, <498 0x10000>, <475 0x10000>, <515 0x10000>;
+	qcom,board-id = <32 0x9>, <32 0x609>;
+
+	aliases {
+		hsuart0 = &uart4;
+	};
+
+	wcd9375: audio-codec-0 {
+		compatible = "qcom,wcd9370-codec";
+		pinctrl-names = "default", "sleep";
+		pinctrl-0 = <&wcd_reset_n>;
+		pinctrl-1 = <&wcd_reset_n_sleep>;
+		reset-gpios = <&tlmm 83 GPIO_ACTIVE_HIGH>;
+		qcom,micbias1-microvolt = <1800000>;
+		qcom,micbias2-microvolt = <1800000>;
+		qcom,micbias3-microvolt = <1800000>;
+		qcom,rx-device = <&wcd937x_rx>;
+		qcom,tx-device = <&wcd937x_tx>;
+		qcom,hphl-jack-type-normally-closed = <1>;
+		qcom,ground-jack-type-normally-closed = <1>;
+		qcom,always-on-supply;
+		#sound-dai-cells = <1>;
+	};
+
+	qps615_rc0_resx_vreg: qps615-rc0-resx-vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "qps615_rc0_resx_vreg";
+		gpio = <&tlmm 78 0>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		enable-active-high;
+		regulator-enable-ramp-delay = <10000>;
+	};
+
+	qps615_rc1_resx_vreg: qps615-rc1-resx-vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "qps615_rc1_resx_vreg";
+		gpio = <&tlmm 124 0>;
+		vin-supply = <&qps615_1p8_vreg>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		enable-active-high;
+		regulator-enable-ramp-delay = <10000>;
+	};
+};
+
+&i2c1 {
+	status = "okay";
+
+	i2c-mux@71 {
+		compatible = "nxp,pca9847";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x71>;
+
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+			usb-hub@2d {
+				compatible = "microchip,usb5807";
+				reg = <0x2d>;
+				/* Swapped D+/D- on port 0 */
+				swap-dx-lanes = <1>;
+			};
+		};
+
+		i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+			usb-hub@2d {
+				compatible = "microchip,usb5807";
+				reg = <0x2d>;
+				/* Swapped D+/D- on port 0 */
+				swap-dx-lanes = <1>;
+			};
+		};
+
+		i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+
+		i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+		};
+
+		i2c@5 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <5>;
+		};
+
+		i2c@6 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <6>;
+		};
+
+		i2c@7 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <7>;
+		};
+	};
+
+	qps615_rc0_switch: pcie-switch-0@33 {
+		compatible = "qcom,switch-i2c";
+		reg = <0x33>;
+		vdda-supply = <&qps615_rc0_resx_vreg>;
+		status = "okay";
+	};
+};
+
+&i2c2 {
+	status = "okay";
+
+	i2c-mux@71 {
+		compatible = "nxp,pca9847";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x71>;
+
+		i2c@0 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0>;
+		};
+
+		i2c@1 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <1>;
+		};
+
+		i2c@2 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <2>;
+		};
+
+		i2c@3 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <3>;
+		};
+
+		i2c@4 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <4>;
+		};
+	};
+
+	qps615_rc1_switch: pcie-switch-1@77 {
+		compatible = "qcom,switch-i2c";
+		reg = <0x77>;
+		status = "okay";
+	};
+};
+
+&lpass_rx_swr_clk {
+	drive-strength = <2>;
+	slew-rate = <1>;
+	bias-disable;
+};
+
+&lpass_rx_swr_data {
+	drive-strength = <2>;
+	slew-rate = <1>;
+	bias-bus-hold;
+};
+
+&lpass_tx_swr_clk {
+	drive-strength = <2>;
+	slew-rate = <1>;
+	bias-disable;
+};
+
+&lpass_tx_swr_data {
+	drive-strength = <2>;
+	slew-rate = <1>;
+	bias-bus-hold;
+};
+
+
+&pcie0 {
+	bus-range = <0x80 0xff>;
+	iommu-map = <0x8000 &apps_smmu 0x1c00 0x1>,
+		    <0x8100 &apps_smmu 0x1c01 0x1>,
+		    <0x8208 &apps_smmu 0x1c04 0x1>,
+		    <0x8210 &apps_smmu 0x1c05 0x1>,
+		    <0x8218 &apps_smmu 0x1c06 0x1>,
+		    <0x8300 &apps_smmu 0x1c07 0x1>,
+		    <0x8400 &apps_smmu 0x1c08 0x1>,
+		    <0x8500 &apps_smmu 0x1c09 0x1>,
+		    <0x8501 &apps_smmu 0x1c10 0x1>;
+	dummy-supply = <&qps615_rc0_switch>;
+	status = "okay";
+
+	pcieport: pcie@0 {
+		device_type = "pci";
+		reg = <0x0 0x0 0x0 0x0 0x0>;
+		#address-cells = <5>;
+		#size-cells = <0>;
+		/* BDF 1.0.0 */
+		pcie0_bus1_dev0_fn0: pcie0-bus1-dev0-fn0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			/* BDF 2.1.0 */
+			pcie0_bus2_dev1_fn0: pcie0-bus2-dev1-fn0 {
+				reg = <0x800 0x0 0x0 0x0 0x0>;
+				/* BDF 3.0.0 */
+				pcie0_bus3_dev0_fn0: pcie0-bus3-dev0-fn0 {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+				};
+			};
+			/* BDF 2.2.0 */
+			pcie0_bus2_dev2_fn0: pcie0-bus2-dev2-fn0 {
+				reg = <0x1000 0x0 0x0 0x0 0x0>;
+				/* BDF 4.0.0 */
+				pcie0_bus4_dev0_fn0: pcie0-bus4-dev0-fn0 {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+				};
+			};
+			/* BDF 2.3.0 */
+			pcie0_bus2_dev3_fn0: pcie0-bus2-dev3-fn0 {
+				reg = <0x1800 0x0 0x0 0x0 0x0>;
+				pcie0_qps615_eth0,pcie0_qps615_eth0@pcie0_rp {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&rtl_rc0_intn_wol_sig>;
+					phy-rst-som-gpios = <&tlmm 90 GPIO_ACTIVE_HIGH>;
+					interrupts-extended = <&tlmm 136 IRQ_TYPE_EDGE_FALLING>;
+					qcom,phy-port-interface = <4>;
+					qcom,mdc-clk = <0x8>;
+					qcom,c45-state = <0>;
+					qcom,link-down-macrst = <0>;
+					interrupt-names = "wol_irq";
+					qcom,always-on-supply;
+					qcom,phy-rst-delay-us = <75000>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+				};
+
+
+				/* BDF 5.0.0 */
+				pcie0_bus5_dev0_fn0: pcie1-qps-eth0 {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+				};
+
+
+				pcie0_qps615_eth1,pcie0_qps615_eth1@pcie0_rp {
+					reg = <0x100 0x0 0x0 0x0 0x0>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&napa_rc0_intn_wol_sig>;
+					phy-rst-som-gpios = <&tlmm 25 GPIO_ACTIVE_HIGH>;
+					interrupts-extended = <&tlmm 142 IRQ_TYPE_EDGE_FALLING>;
+					interrupt-names = "wol_irq";
+					qcom,always-on-supply;
+					qcom,phy-rst-delay-us = <20000>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+				};
+				/* BDF 5.0.1 */
+				pcie0_bus5_dev0_fn1: pcie1-qps-eth1 {
+					reg = <0x100 0x0 0x0 0x0 0x0>;
+				};
+			};
+		};
+	};
+};
+
+&pcie0_phy {
+	qcom,refclk-always-on;
+	status = "okay";
+};
+
+&pcie1 {
+	iommu-map = <0x0 &apps_smmu 0x1c80 0x1>,
+		    <0x100 &apps_smmu 0x1c81 0x1>,
+		    <0x208 &apps_smmu 0x1c84 0x1>,
+		    <0x210 &apps_smmu 0x1c85 0x1>,
+		    <0x218 &apps_smmu 0x1c86 0x1>,
+		    <0x300 &apps_smmu 0x1c87 0x1>,
+		    <0x408 &apps_smmu 0x1c90 0x1>,
+		    <0x410 &apps_smmu 0x1c91 0x1>,
+		    <0x418 &apps_smmu 0x1c92 0x1>,
+		    <0x500 &apps_smmu 0x1c93 0x1>,
+		    <0x600 &apps_smmu 0x1c94 0x1>,
+		    <0x700 &apps_smmu 0x1c95 0x1>,
+		    <0x701 &apps_smmu 0x1c96 0x1>,
+		    <0x800 &apps_smmu 0x1c97 0x1>,
+		    <0x900 &apps_smmu 0x1c98 0x1>,
+		    <0x901 &apps_smmu 0x1c99 0x1>;
+};
+
+&pcie1_bus3_dev0_fn0 {
+	reg = <0x0 0x0 0x0 0x0 0x0>;
+
+	/* BDF 4.1.0 */
+	pcie1_bus4_dev1_fn0: pcie1-bus4-dev1-fn0 {
+		reg = <0x800 0x0 0x0 0x0 0x0>;
+
+		/* BDF 5.0.0 */
+		pcie1_bus5_rc1_dev0_fn0: pcie1-bus5-rc1-dev0-fn0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+		};
+	};
+
+	/* BDF 4.2.0 */
+	pcie1_bus4_dev2_fn0: pcie1-bus4-dev2-fn0 {
+		reg = <0x1000 0x0 0x0 0x0 0x0>;
+
+		/* BDF 6.0.0 */
+		pcie1_bus6_dev0_fn0: pcie1-bus6-dev0-fn0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+		};
+	};
+
+	/* BDF 4.3.0 */
+	pcie1_bus4_dev3_fn0: pcie1-bus4-dev3-fn0 {
+		reg = <0x1800 0x0 0x0 0x0 0x0>;
+		/* BDF 7.0.0 */
+		pcie1_bus7_dev0_fn0: pcie1-bus7-dev0-fn0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+		};
+
+		/* BDF 7.0.1 */
+		pcie1_bus7_dev0_fn1: pcie1-bus7-dev0-fn1 {
+			reg = <0x100 0x0 0x0 0x0 0x0>;
+		};
+	};
+};
+
+&pm7250b_gpios {
+	gpio5_tpm_dig_out {
+		gpio5_dig_out_default: gpio5_dig_out_default {
+			pins = "gpio5";
+			function = "normal";
+			power-source = <1>;
+			output-high;
+			input-disable;
+			bias-pull-up;
+			qcom,drive-strength = <3>;
+		};
+	};
+};
+
+&qps615_rsex_vreg {
+	vin-supply = <&qps615_rc1_resx_vreg>;
+};
+
+&qupv3_id_1 {
+	status = "okay";
+};
+
+&redriver_ss_in {
+	data-lanes = <0 1 2 3>;
+	remote-endpoint = <&usb_1_qmpphy_out>;
+};
+
+&sound {
+	compatible = "qcom,qcs6490-rb3gen2-ia-sndcard";
+	model = "qcm6490-rb3-ia-snd-card";
+	audio-routing =
+		"SpkrLeft IN", "WSA_SPK1 OUT",
+		"SpkrRight IN", "WSA_SPK2 OUT",
+		"IN1_HPHL", "HPHL_OUT",
+		"IN2_HPHR", "HPHR_OUT",
+		"AMIC2", "MIC BIAS2",
+		"TX SWR_ADC1", "ADC2_OUTPUT",
+		"VA DMIC0", "vdd-micb",
+		"VA DMIC1", "vdd-micb",
+		"VA DMIC2", "vdd-micb",
+		"VA DMIC3", "vdd-micb";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	wcd-playback-dai-link {
+		link-name = "CODEC_DMA-LPAIF_RXTX-RX-0";
+		cpu {
+			sound-dai = <&q6apmbedai RX_CODEC_DMA_RX_0>;
+		};
+
+
+		codec {
+			sound-dai = <&wcd9375 0>, <&swr0 0>, <&lpass_rx_macro 0>;
+		};
+	};
+
+
+	wcd-capture-dai-link {
+		link-name = "CODEC_DMA-LPAIF_RXTX-TX-3";
+		cpu {
+			sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>;
+		};
+
+
+		codec {
+			sound-dai = <&wcd9375 1>, <&swr1 0>, <&lpass_tx_macro 0>;
+		};
+	};
+};
+
+&spi11 {
+	status = "okay";
+
+	st33htpm0: st33htpm@0 {
+		compatible = "st,st33htpm-spi";
+		reg = <0>;
+		spi-max-frequency = <20000000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&gpio5_dig_out_default>;
+		status = "okay";
+	};
+};
+
+&spmi_bus {
+	pmic@PM7250B_SID {
+		pm7250b_bcl: bcl@1d00 {
+			compatible = "qcom,bcl-v5";
+			reg = <0x1d00>;
+			interrupts = <PM7250B_SID 0x1d 0x0 IRQ_TYPE_EDGE_RISING>,
+					<PM7250B_SID 0x1d 0x1 IRQ_TYPE_EDGE_RISING>,
+					<PM7250B_SID 0x1d 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "bcl-lvl0",
+						"bcl-lvl1",
+						"bcl-lvl2";
+			#thermal-sensor-cells = <1>;
+		};
+	};
+};
+
+&swr0 {
+	wcd937x_rx: codec@0,4 {
+		compatible = "sdw20217010a00";
+		reg = <0 4>;
+		qcom,rx-port-mapping = <1 2 3 4 5>;
+	};
+};
+
+&swr1 {
+	wcd937x_tx: codec@0,3 {
+		compatible = "sdw20217010a00";
+		reg = <0 3>;
+		qcom,tx-port-mapping = <1 1 2 3>;
+	};
+};
+
+&thermal_zones {
+	pm7250b-ibat-lvl0 {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 0>;
+
+		trips {
+			ibat_lvl0:ibat-lvl0 {
+				temperature = <6000>;
+				hysteresis = <200>;
+				type = "passive";
+			};
+		};
+	};
+
+	pm7250b-ibat-lvl1 {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 1>;
+
+		trips {
+			ibat_lvl1:ibat-lvl1 {
+				temperature = <7500>;
+				hysteresis = <200>;
+				type = "passive";
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl0 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 5>;
+
+		trips {
+			b_bcl_lvl0: b-bcl-lvl0 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU4_idle 100 100>;
+			};
+
+			map1 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU5_idle 100 100>;
+			};
+
+			map2 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU6_idle 100 100>;
+			};
+
+			map3 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU7_idle 100 100>;
+			};
+
+			map4 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&cdsp_sw 2 2>;
+			};
+
+			map5 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&modem_pa 2 2>;
+			};
+
+			map6 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&modem_tj 1 1>;
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl1 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 6>;
+
+		trips {
+			b_bcl_lvl1: b-bcl-lvl1 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&b_bcl_lvl1>;
+				cooling-device = <&msm_gpu 5 THERMAL_NO_LIMIT>;
+			};
+
+			//map1 {
+			//	trip = <&b_bcl_lvl1>;
+			//	cooling-device = <&cdsp_sw 4 4>;
+			//};
+
+			map2 {
+				trip = <&b_bcl_lvl1>;
+				cooling-device = <&modem_tj 3 3>;
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl2 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 7>;
+
+		trips {
+			b_bcl_lvl2: b-bcl-lvl2 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			//map0 {
+			//	trip = <&b_bcl_lvl2>;
+			//	cooling-device = <&cdsp_sw 5 5>;
+			//};
+		};
+	};
+};
+
+&tlmm {
+	qps615_rc0_intn_wol {
+		rtl_rc0_intn_wol_sig: rtl-rc0-intn-wol-sig {
+			pins = "gpio136";
+			function = "gpio";
+			input-enable;
+			bias-disable;
+		};
+
+		napa_rc0_intn_wol_sig: napa-rc0-intn-wol-sig {
+			pins = "gpio142";
+			function = "gpio";
+			input-enable;
+			bias-disable;
+		};
+	};
+
+	wcd_reset_n: wcd-reset-n-state {
+		pins = "gpio83";
+		function = "gpio";
+		drive-strength = <8>;
+	};
+
+
+	wcd_reset_n_sleep: wcd-reset-n-sleep-state {
+		pins = "gpio83";
+		function = "gpio";
+		drive-strength = <8>;
+		bias-disable;
+	};
+};
+
+&uart4 {
+	status = "okay";
+};
+
+&uart7 {
+	status = "disabled";
+};
+
+&soc {
+	leds {
+		compatible = "gpio-leds";
+
+		led-0 {
+			label = "blue:user1";
+			function = LED_FUNCTION_INDICATOR;
+			color = <LED_COLOR_ID_BLUE>;
+			gpios = <&pm8350c_gpios 9 GPIO_ACTIVE_HIGH>;
+			default-state = "off";
+			panic-indicator;
+			status = "okay";
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2-ptz-mezz.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2-ptz-mezz.dts
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs6490-rb3gen2.dts"
+#include "qcs6490-addons-rb3gen2.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. Robotics RB3gen2 addons ptz mezz platform";
+	compatible = "qcom,qcs6490-addons-rb3gen2-ptz-mezz", "qcom,qcm6490";
+};
+
+&spmi_bus {
+	pmic@PM7250B_SID {
+		pm7250b_bcl: bcl@1d00 {
+			compatible = "qcom,bcl-v5";
+			reg = <0x1d00>;
+			interrupts = <PM7250B_SID 0x1d 0x0 IRQ_TYPE_EDGE_RISING>,
+					<PM7250B_SID 0x1d 0x1 IRQ_TYPE_EDGE_RISING>,
+					<PM7250B_SID 0x1d 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "bcl-lvl0",
+						"bcl-lvl1",
+						"bcl-lvl2";
+			#thermal-sensor-cells = <1>;
+		};
+	};
+};
+
+&thermal_zones {
+	pm7250b-ibat-lvl0 {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 0>;
+
+		trips {
+			ibat_lvl0:ibat-lvl0 {
+				temperature = <6000>;
+				hysteresis = <200>;
+				type = "passive";
+			};
+		};
+	};
+
+	pm7250b-ibat-lvl1 {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 1>;
+
+		trips {
+			ibat_lvl1:ibat-lvl1 {
+				temperature = <7500>;
+				hysteresis = <200>;
+				type = "passive";
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl0 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 5>;
+
+		trips {
+			b_bcl_lvl0: b-bcl-lvl0 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU4_idle 100 100>;
+			};
+
+			map1 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU5_idle 100 100>;
+			};
+
+			map2 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU6_idle 100 100>;
+			};
+
+			map3 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU7_idle 100 100>;
+			};
+
+			map4 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&cdsp_sw 2 2>;
+			};
+
+			map5 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&modem_pa 2 2>;
+			};
+
+			map6 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&modem_tj 1 1>;
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl1 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 6>;
+
+		trips {
+			b_bcl_lvl1: b-bcl-lvl1 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&b_bcl_lvl1>;
+				cooling-device = <&msm_gpu 5 THERMAL_NO_LIMIT>;
+			};
+
+			//map1 {
+			//	trip = <&b_bcl_lvl1>;
+			//	cooling-device = <&cdsp_sw 4 4>;
+			//};
+
+			map2 {
+				trip = <&b_bcl_lvl1>;
+				cooling-device = <&modem_tj 3 3>;
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl2 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 7>;
+
+		trips {
+			b_bcl_lvl2: b-bcl-lvl2 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			//map0 {
+			//	trip = <&b_bcl_lvl2>;
+			//	cooling-device = <&cdsp_sw 5 5>;
+			//};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2-video-mezz.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2-video-mezz.dts
@@ -0,0 +1,318 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs6490-rb3gen2.dts"
+#include "qcs6490-addons-rb3gen2.dtsi"
+/ {
+	model = "Qualcomm Technologies, Inc. Robotics RB3gen2 addons video mezz platform";
+	compatible = "qcom,qcs6490-addons-rb3gen2-video-mezz", "qcom,qcm6490";
+
+	qcom,msm-id = <497 0x10000>, <498 0x10000>, <475 0x10000>, <515 0x10000>;
+	qcom,board-id = <32 0x1>, <32 0x601>;
+
+	aliases {
+		serial2 = &uart4;
+	};
+};
+
+&q6apmbedai {
+	qcom,prmcc_clk = <&q6prmcc>;
+};
+
+&sound {
+	compatible = "qcom,qcm6490-sndcard";
+	model = "qcm6490-rb3-vc-snd-card";
+
+	audio-routing =
+		"SpkrLeft IN", "WSA_SPK1 OUT",
+		"SpkrRight IN", "WSA_SPK2 OUT",
+		"VA DMIC0", "vdd-micb",
+		"VA DMIC1", "vdd-micb",
+		"VA DMIC2", "vdd-micb",
+		"VA DMIC3", "vdd-micb",
+		"VA DMIC4", "vdd-micb",
+		"VA DMIC5", "vdd-micb";
+
+	pinctrl-names = "default", "stub_aif1_active", "stub_aif1_sleep";
+	pinctrl-0 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>, <&mi2s0_ws_sleep>;
+	pinctrl-1 = <&mi2s0_data0>, <&mi2s0_data1>, <&mi2s0_mclk>, <&mi2s0_sclk>, <&mi2s0_ws>;
+	pinctrl-2 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>, <&mi2s0_ws_sleep>;
+
+	mi2s-capture-dai-link {
+		link-name = "MI2S-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	mi2s-playback-dai-link {
+		link-name = "MI2S-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+	tdm-capture-dai-link {
+		link-name = "TDM-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_TX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	tdm-playback-dai-link {
+		link-name = "TDM-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_RX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+};
+
+&spmi_bus {
+	pmic@PM7250B_SID {
+		pm7250b_bcl: bcl@1d00 {
+			compatible = "qcom,bcl-v5";
+			reg = <0x1d00>;
+			interrupts = <PM7250B_SID 0x1d 0x0 IRQ_TYPE_EDGE_RISING>,
+					<PM7250B_SID 0x1d 0x1 IRQ_TYPE_EDGE_RISING>,
+					<PM7250B_SID 0x1d 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "bcl-lvl0",
+						"bcl-lvl1",
+						"bcl-lvl2";
+			#thermal-sensor-cells = <1>;
+		};
+	};
+};
+
+&thermal_zones {
+	pm7250b-ibat-lvl0 {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 0>;
+
+		trips {
+			ibat_lvl0:ibat-lvl0 {
+				temperature = <6000>;
+				hysteresis = <200>;
+				type = "passive";
+			};
+		};
+	};
+
+	pm7250b-ibat-lvl1 {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 1>;
+
+		trips {
+			ibat_lvl1:ibat-lvl1 {
+				temperature = <7500>;
+				hysteresis = <200>;
+				type = "passive";
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl0 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 5>;
+
+		trips {
+			b_bcl_lvl0: b-bcl-lvl0 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU4_idle 100 100>;
+			};
+
+			map1 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU5_idle 100 100>;
+			};
+
+			map2 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU6_idle 100 100>;
+			};
+
+			map3 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU7_idle 100 100>;
+			};
+
+			map4 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&cdsp_sw 2 2>;
+			};
+
+			map5 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&modem_pa 2 2>;
+			};
+
+			map6 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&modem_tj 1 1>;
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl1 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 6>;
+
+		trips {
+			b_bcl_lvl1: b-bcl-lvl1 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&b_bcl_lvl1>;
+				cooling-device = <&msm_gpu 5 THERMAL_NO_LIMIT>;
+			};
+
+			//map1 {
+			//	trip = <&b_bcl_lvl1>;
+			//	cooling-device = <&cdsp_sw 4 4>;
+			//};
+
+			map2 {
+				trip = <&b_bcl_lvl1>;
+				cooling-device = <&modem_tj 3 3>;
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl2 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 7>;
+
+		trips {
+			b_bcl_lvl2: b-bcl-lvl2 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			//map0 {
+			//	trip = <&b_bcl_lvl2>;
+			//	cooling-device = <&cdsp_sw 5 5>;
+			//};
+		};
+	};
+};
+
+&tlmm {
+	mi2s0_data0_sleep: mi2s0-data0-sleep {
+		pins = "gpio98";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_data1_sleep: mi2s0-data1-sleep {
+		pins = "gpio99";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_mclk_sleep: mi2s0-mclk-sleep {
+		pins = "gpio96";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_sclk_sleep: mi2s0-sclk-sleep {
+		pins = "gpio97";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_ws_sleep: mi2s0-ws-sleep {
+		pins = "gpio100";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+};
+
+&uart4 {
+	status = "okay";
+};
+
+&mi2s0_data0 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_data1 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_mclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_sclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_ws {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2-vision-mezz-hsp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2-vision-mezz-hsp.dts
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs6490-addons-rb3gen2-vision-mezz.dts"
+
+/ {
+	model = "Qualcomm Technologies, Inc. Robotics RB3gen2 addons vision mezz hsp platform";
+	compatible = "qcom,qcs6490-addons-rb3gen2-vision-mezz-hsp", "qcom,qcm6490";
+
+	qcom,msm-id = <497 0x10000>, <498 0x10000>, <475 0x10000>, <515 0x10000>;
+	qcom,board-id = <32 0x7>, <32 0x607>;
+
+	aliases {
+		serial2 = &uart4;
+	};
+};
+
+&pcie0 {
+	perst-gpios = <&tlmm 87 GPIO_ACTIVE_LOW>;
+	pinctrl-0 = <&pcie0_reset_n>, <&pcie0_wake_n>, <&pcie0_clkreq_n>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	pcie0_port0: pcie@0 {
+		reg = <0x0 0x0 0x0 0x0 0x0>;
+		#address-cells = <3>;
+		#size-cells = <2>;
+		ranges;
+
+		bus-range = <0x01 0xff>;
+		device_type = "pci";
+
+		wake-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&pcie0_phy {
+	status = "okay";
+	vdda-phy-supply = <&vreg_l10c_0p88>;
+	vdda-pll-supply = <&vreg_l6b_1p2>;
+};
+
+&remoteproc_mpss {
+	status = "disabled";
+};
+
+&remoteproc_wpss {
+	status = "disabled";
+};
+
+&uart7 {
+	/delete-node/ bluetooth;
+
+	bluetooth: bluetooth {
+		compatible = "qcom,wcn6855-bt";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bt_en>, <&sw_ctrl>;
+		enable-gpios = <&tlmm 85 GPIO_ACTIVE_HIGH>;
+		swctrl-gpios = <&tlmm 86 GPIO_ACTIVE_HIGH>;
+		vddio-supply = <&vreg_s7b_0p972>;
+		vddbtcxmx-supply = <&vreg_s7b_0p972>;
+		vddrfacmn-supply = <&vreg_s7b_0p972>;
+		vddrfa0p8-supply = <&vreg_s7b_0p972>;
+		vddrfa1p7-supply = <&vreg_s1b_1p872>;
+		vddrfa1p2-supply = <&vreg_s8b_1p272>;
+		max-speed = <3200000>;
+	};
+};
+
+&wifi {
+	status = "disabled";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2-vision-mezz.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2-vision-mezz.dts
@@ -0,0 +1,319 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs6490-rb3gen2.dts"
+#include "qcs6490-addons-rb3gen2.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. Robotics RB3gen2 addons vision mezz platform";
+	compatible = "qcom,qcs6490-addons-rb3gen2-vision-mezz", "qcom,qcm6490";
+
+	qcom,msm-id = <497 0x10000>, <498 0x10000>, <475 0x10000>, <515 0x10000>;
+	qcom,board-id = <32 0x2>, <32 0x602>;
+
+	aliases {
+		serial2 = &uart4;
+	};
+};
+
+&q6apmbedai {
+	qcom,prmcc_clk = <&q6prmcc>;
+};
+
+&sound {
+	compatible = "qcom,qcm6490-sndcard";
+	model = "qcm6490-rb3-vision-snd-card";
+
+	audio-routing =
+		"SpkrLeft IN", "WSA_SPK1 OUT",
+		"SpkrRight IN", "WSA_SPK2 OUT",
+		"VA DMIC0", "vdd-micb",
+		"VA DMIC1", "vdd-micb",
+		"VA DMIC2", "vdd-micb",
+		"VA DMIC3", "vdd-micb",
+		"VA DMIC4", "vdd-micb",
+		"VA DMIC5", "vdd-micb";
+
+	pinctrl-names = "default", "stub_aif1_active", "stub_aif1_sleep";
+	pinctrl-0 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>,<&mi2s0_ws_sleep>;
+	pinctrl-1 = <&mi2s0_data0>, <&mi2s0_data1>, <&mi2s0_mclk>, <&mi2s0_sclk>, <&mi2s0_ws>;
+	pinctrl-2 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>,<&mi2s0_ws_sleep>;
+
+	mi2s-capture-dai-link {
+		link-name = "MI2S-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	mi2s-playback-dai-link {
+		link-name = "MI2S-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+	tdm-capture-dai-link {
+		link-name = "TDM-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_TX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+	};
+
+	tdm-playback-dai-link {
+		link-name = "TDM-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_RX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+	};
+
+};
+
+&spmi_bus {
+	pmic@PM7250B_SID {
+		pm7250b_bcl: bcl@1d00 {
+			compatible = "qcom,bcl-v5";
+			reg = <0x1d00>;
+			interrupts = <PM7250B_SID 0x1d 0x0 IRQ_TYPE_EDGE_RISING>,
+					<PM7250B_SID 0x1d 0x1 IRQ_TYPE_EDGE_RISING>,
+					<PM7250B_SID 0x1d 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "bcl-lvl0",
+						"bcl-lvl1",
+						"bcl-lvl2";
+			#thermal-sensor-cells = <1>;
+		};
+	};
+};
+
+&thermal_zones {
+	pm7250b-ibat-lvl0 {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 0>;
+
+		trips {
+			ibat_lvl0:ibat-lvl0 {
+				temperature = <6000>;
+				hysteresis = <200>;
+				type = "passive";
+			};
+		};
+	};
+
+	pm7250b-ibat-lvl1 {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 1>;
+
+		trips {
+			ibat_lvl1:ibat-lvl1 {
+				temperature = <7500>;
+				hysteresis = <200>;
+				type = "passive";
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl0 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 5>;
+
+		trips {
+			b_bcl_lvl0: b-bcl-lvl0 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU4_idle 100 100>;
+			};
+
+			map1 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU5_idle 100 100>;
+			};
+
+			map2 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU6_idle 100 100>;
+			};
+
+			map3 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU7_idle 100 100>;
+			};
+
+			map4 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&cdsp_sw 2 2>;
+			};
+
+			map5 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&modem_pa 2 2>;
+			};
+
+			map6 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&modem_tj 1 1>;
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl1 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 6>;
+
+		trips {
+			b_bcl_lvl1: b-bcl-lvl1 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&b_bcl_lvl1>;
+				cooling-device = <&msm_gpu 5 THERMAL_NO_LIMIT>;
+			};
+
+			//map1 {
+			//	trip = <&b_bcl_lvl1>;
+			//	cooling-device = <&cdsp_sw 4 4>;
+			//};
+
+			map2 {
+				trip = <&b_bcl_lvl1>;
+				cooling-device = <&modem_tj 3 3>;
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl2 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 7>;
+
+		trips {
+			b_bcl_lvl2: b-bcl-lvl2 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			//map0 {
+			//	trip = <&b_bcl_lvl2>;
+			//	cooling-device = <&cdsp_sw 5 5>;
+			//};
+		};
+	};
+};
+
+&tlmm {
+	mi2s0_data0_sleep: mi2s0-data0-sleep {
+		pins = "gpio98";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_data1_sleep: mi2s0-data1-sleep {
+		pins = "gpio99";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_mclk_sleep: mi2s0-mclk-sleep {
+		pins = "gpio96";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_sclk_sleep: mi2s0-sclk-sleep {
+		pins = "gpio97";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_ws_sleep: mi2s0-ws-sleep {
+		pins = "gpio100";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+};
+
+&uart4 {
+	status = "okay";
+};
+
+&mi2s0_data0 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_data1 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_mclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_sclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_ws {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * qcs6490-addons RB3gen2 device tree source
+ *
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
+
+/dts-v1/;
+
+#include "qcs6490-rb3gen2.dts"
+#include "qcs6490-addons-rb3gen2.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. Robotics RB3gen2 addons platform";
+	compatible = "qcom,qcs6490-addons-rb3gen2","qcom,qcm6490";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs6490-addons-rb3gen2.dtsi
@@ -0,0 +1,579 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * qcm6490-addons-rb3gen2 device tree source include
+ *
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
+#include "qcm6490-addons.dtsi"
+
+/ {
+	qps615_0p9_vreg: qps615-0p9-vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "qps615_0p9_vreg";
+		gpio = <&pm8350c_gpios 2 0>;
+		regulator-min-microvolt = <1000000>;
+		regulator-max-microvolt = <1000000>;
+		enable-active-high;
+		regulator-enable-ramp-delay = <4300>;
+	};
+
+	qps615_1p8_vreg: qps615-1p8-vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "qps615_1p8_vreg";
+		gpio = <&pm8350c_gpios 3 0>;
+		vin-supply = <&qps615_0p9_vreg>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		enable-active-high;
+		regulator-enable-ramp-delay = <10000>;
+	};
+
+	qps615_rsex_vreg: qps615-rsex-vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "qps615_rsex_vreg";
+		gpio = <&pm8350c_gpios 1 0>;
+		vin-supply = <&qps615_1p8_vreg>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		enable-active-high;
+		regulator-enable-ramp-delay = <10000>;
+	};
+
+	upd_3p3_vreg: upd_3p3_vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "upd_3p3_vreg";
+		gpio = <&pm7250b_gpios 1 0>;
+		vin-supply = <&qps615_rsex_vreg>;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		regulator-enable-ramp-delay = <10000>;
+		regulator-always-on;
+	};
+
+	upd_rest_vreg: upd_rest_vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "upd_rest_vreg";
+		gpio = <&pm8350c_gpios 4 0>;
+		vin-supply = <&upd_3p3_vreg>;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		regulator-always-on;
+	};
+
+	usbhub_rest_vreg: usbhub_rest_vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "usbhub_rest_vreg";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pcie1_usb_hub_reset_default>;
+		gpio = <&tlmm 162 GPIO_ACTIVE_LOW>;
+		enable-active-high;
+	};
+
+	qep_vreg: qep_vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "qep_vreg";
+		gpio = <&pm7325_gpios 8 0>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		enable-active-high;
+	};
+
+	aqr_vreg: aqr_vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "aqr_vreg";
+		gpio = <&pm7250b_gpios 4 0>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		enable-active-high;
+	};
+};
+
+&camcc {
+	status = "okay";
+};
+
+&camss {
+	status = "disabled";
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* The port index denotes CSIPHY id i.e. csiphy2 */
+		port@3 {
+			reg = <3>;
+			csiphy3_ep: endpoint {
+				clock-lanes = <7>;
+				data-lanes = <0 1 2 3>;
+				remote-endpoint = <&imx577_ep>;
+			};
+		};
+	};
+};
+
+&cci1 {
+	status = "disabled";
+};
+
+&cci1_i2c1 {
+	camera@1a {
+		compatible = "sony,imx577";
+		reg = <0x1a>;
+
+		reset-gpios = <&tlmm 78 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default", "suspend";
+		pinctrl-0 = <&cam2_default>;
+		pinctrl-1 = <&cam2_suspend>;
+
+		clocks = <&camcc CAM_CC_MCLK3_CLK>,
+			 <&camcc CAM_CC_MCLK2_CLK>;
+		assigned-clocks = <&camcc CAM_CC_MCLK3_CLK>,
+				  <&camcc CAM_CC_MCLK2_CLK>;
+		assigned-clock-rates = <24000000>,
+				       <24000000>;
+
+		dovdd-supply  = <&vreg_l18b_1p8>;
+
+		port {
+			imx577_ep: endpoint {
+				clock-lanes = <7>;
+				link-frequencies = /bits/ 64 <600000000>;
+				data-lanes = <0 1 2 3>;
+				remote-endpoint = <&csiphy3_ep>;
+			};
+		};
+	};
+};
+
+&i2c0 {
+	clock-frequency = <100000>;
+	status = "okay";
+
+	qps615_switch: pcie-switch@77 {
+		compatible = "qcom,switch-i2c";
+		reg = <0x77>;
+		vdda-supply = <&qps615_rsex_vreg>;
+
+		status = "okay";
+	};
+};
+
+&pcie1 {
+	dummy-supply = <&qps615_switch>;
+	pcieport0: pcie@0 {
+		device_type = "pci";
+		reg = <0x0 0x0 0x0 0x0 0x0>;
+		#address-cells = <5>;
+		#size-cells = <0>;
+
+		/* BDF 1.0.0 */
+		pcie1_bus1_dev0_fn0: pcie1_bus1_dev0_fn0 {
+			reg = <0 0 0 0 0>;
+
+			/* BDF 2.1.0 */
+			pcie1_bus2_dev1_fn0: pcie1_bus2_dev1_fn0 {
+				reg = <0x800 0x0 0x0 0x0 0x0>;
+
+				/* BDF 3.0.0 */
+				pcie1_bus3_dev0_fn0: pcie1_bus3_dev0_fn0 {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+				};
+			};
+
+			/* BDF 2.2.0 */
+			pcie1_bus2_dev2_fn0: pcie1_bus2_dev2_fn0 {
+				reg = <0x1000 0x0 0x0 0x0 0x0>;
+
+				/* BDF 4.0.0 */
+				pcie1_bus4_dev0_fn0: pcie1_bus4_dev0_fn0 {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+				};
+			};
+
+			/* BDF 2.3.0 */
+			pcie1_bus2_dev3_fn0: pcie1_bus2_dev3_fn0 {
+				reg = <0x1800 0x0 0x0 0x0 0x0>;
+				qps615_eth0,qps615_eth0@pcie1_rp {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&aqr_intn_wol_sig>;
+					qcom,phy-rst-gpio-id = <0>;
+					interrupts-extended = <&tlmm 141 IRQ_TYPE_EDGE_FALLING>;
+					interrupt-names = "wol_irq";
+					phy-supply = <&aqr_vreg>;
+					qcom,phy-rst-delay-us = <221000>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+				};
+
+				/* BDF 5.0.0 */
+				pcie1_bus5_dev0_fn0: pcie1_qps_eth0 {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+					qcom,iommu-group = <&eth0_pci_iommu_group>;
+					eth0_pci_iommu_group: eth0_pci_iommu_group {
+						qcom,iommu-dma = "atomic";
+					};
+				};
+
+				qps615_eth1,qps615_eth1@pcie1_rp {
+					reg = <0x100 0x0 0x0 0x0 0x0>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&napa_intn_wol_sig>;
+					qcom,phy-rst-gpio-id = <1>;
+					interrupts-extended = <&tlmm 101 IRQ_TYPE_EDGE_FALLING>;
+					interrupt-names = "wol_irq";
+					phy-supply = <&qep_vreg>;
+					qcom,phy-rst-delay-us = <20000>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+				};
+
+				/* BDF 5.0.1 */
+				pcie1_bus5_dev0_fn1: pcie1_qps_eth1 {
+					reg = <0x100 0x0 0x0 0x0 0x0>;
+					qcom,iommu-group = <&eth1_pci_iommu_group>;
+					eth1_pci_iommu_group: eth1_pci_iommu_group {
+						qcom,iommu-dma = "atomic";
+					};
+				};
+			};
+
+		};
+	};
+};
+
+&pcie1_phy {
+	qcom,refclk-always-on;
+};
+
+&q6apmbedai {
+	qcom,prmcc_clk = <&q6prmcc>;
+};
+
+&sound {
+
+	pinctrl-names = "default", "stub_aif1_active", "stub_aif1_sleep";
+	pinctrl-0 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>, <&mi2s0_ws_sleep>;
+	pinctrl-1 = <&mi2s0_data0>, <&mi2s0_data1>, <&mi2s0_mclk>, <&mi2s0_sclk>, <&mi2s0_ws>;
+	pinctrl-2 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk_sleep>,
+		    <&mi2s0_sclk_sleep>, <&mi2s0_ws_sleep>;
+
+	mi2s-capture-dai-link {
+		link-name = "MI2S-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+		platform {
+			sound-dai = <&q6apm>;
+		};
+	};
+
+	mi2s-playback-dai-link {
+		link-name = "MI2S-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+		platform {
+			sound-dai = <&q6apm>;
+		};
+	};
+
+	tdm-capture-dai-link {
+		link-name = "TDM-LPAIF-TX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_TX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 1>;
+		};
+		platform {
+			sound-dai = <&q6apm>;
+		};
+	};
+
+	tdm-playback-dai-link {
+		link-name = "TDM-LPAIF-RX-PRIMARY";
+
+		cpu {
+			sound-dai = <&q6apmbedai PRIMARY_TDM_RX_0>;
+		};
+
+		codec {
+			sound-dai = <&msm_stub_codec 0>;
+		};
+		platform {
+			sound-dai = <&q6apm>;
+		};
+	};
+
+};
+
+&tlmm {
+	mi2s0_data0_sleep: mi2s0-data0-sleep {
+		pins = "gpio98";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_data1_sleep: mi2s0-data1-sleep {
+		pins = "gpio99";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_mclk_sleep: mi2s0-mclk-sleep {
+		pins = "gpio96";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_sclk_sleep: mi2s0-sclk-sleep {
+		pins = "gpio97";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_ws_sleep: mi2s0-ws-sleep {
+		pins = "gpio100";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	pcie1_usb_hub_reset_default: pcie1_usb_hub_reset_default {
+		pins = "gpio162";
+		function = "gpio";
+		drive-strength = <2>;
+		output-high;
+		bias-pull-down;
+	};
+
+	qps615_intn_wol {
+		aqr_intn_wol_sig: aqr_intn_wol_sig {
+			mux {
+				pins = "gpio141";
+				function = "gpio";
+			};
+
+			config {
+				pins = "gpio141";
+				input-enable;
+				bias-disable;
+			};
+		};
+
+		napa_intn_wol_sig: napa_intn_wol_sig {
+			mux {
+				pins = "gpio101";
+				function = "gpio";
+			};
+
+			config {
+				pins = "gpio101";
+				input-enable;
+				bias-disable;
+			};
+		};
+	};
+};
+
+&mi2s0_data0 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_data1 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_mclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_sclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_ws {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&spmi_bus {
+	pmic@PM7250B_SID {
+		pm7250b_bcl: bcl@1d00 {
+			compatible = "qcom,bcl-v5";
+			reg = <0x1d00>;
+			interrupts = <PM7250B_SID 0x1d 0x0 IRQ_TYPE_EDGE_RISING>,
+					<PM7250B_SID 0x1d 0x1 IRQ_TYPE_EDGE_RISING>,
+					<PM7250B_SID 0x1d 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "bcl-lvl0",
+						"bcl-lvl1",
+						"bcl-lvl2";
+			#thermal-sensor-cells = <1>;
+		};
+	};
+};
+
+&thermal_zones {
+	pm7250b-ibat-lvl0 {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 0>;
+
+		trips {
+			ibat_lvl0:ibat-lvl0 {
+				temperature = <6000>;
+				hysteresis = <200>;
+				type = "passive";
+			};
+		};
+	};
+
+	pm7250b-ibat-lvl1 {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 1>;
+
+		trips {
+			ibat_lvl1:ibat-lvl1 {
+				temperature = <7500>;
+				hysteresis = <200>;
+				type = "passive";
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl0 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 5>;
+
+		trips {
+			b_bcl_lvl0: b-bcl-lvl0 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU4_idle 100 100>;
+			};
+
+			map1 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU5_idle 100 100>;
+			};
+
+			map2 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU6_idle 100 100>;
+			};
+
+			map3 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU7_idle 100 100>;
+			};
+
+			map4 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&cdsp_sw 2 2>;
+			};
+
+			map5 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&modem_pa 2 2>;
+			};
+
+			map6 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&modem_tj 1 1>;
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl1 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 6>;
+
+		trips {
+			b_bcl_lvl1: b-bcl-lvl1 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&b_bcl_lvl1>;
+				cooling-device = <&msm_gpu 5 THERMAL_NO_LIMIT>;
+			};
+
+			//map1 {
+			//	trip = <&b_bcl_lvl1>;
+			//	cooling-device = <&cdsp_sw 4 4>;
+			//};
+
+			map2 {
+				trip = <&b_bcl_lvl1>;
+				cooling-device = <&modem_tj 3 3>;
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl2 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 7>;
+
+		trips {
+			b_bcl_lvl2: b-bcl-lvl2 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			//map0 {
+			//	trip = <&b_bcl_lvl2>;
+			//	cooling-device = <&cdsp_sw 5 5>;
+			//};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dts
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs6490-rb3gen2.dts"
+
+&camcc {
+	status = "okay";
+};
+
+&camss {
+	vdda-phy-supply = <&vreg_l10c_0p88>;
+	vdda-pll-supply = <&vreg_l6b_1p2>;
+	status = "okay";
+
+	ports {
+		/* The port index denotes CSIPHY id i.e. csiphy3 */
+		port@3 {
+			reg = <3>;
+			csiphy3_ep: endpoint {
+				clock-lanes = <7>;
+				data-lanes = <0 1 2 3>;
+				remote-endpoint = <&imx577_ep>;
+			};
+		};
+	};
+};
+
+&cci1 {
+	status = "okay";
+};
+
+&cci1_i2c1 {
+	camera@1a {
+		compatible = "sony,imx577";
+		reg = <0x1a>;
+
+		reset-gpios = <&tlmm 78 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default", "suspend";
+		pinctrl-0 = <&cam2_default>;
+		pinctrl-1 = <&cam2_suspend>;
+
+		clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		assigned-clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		assigned-clock-rates = <24000000>;
+
+		dovdd-supply  = <&vreg_l18b_1p8>;
+
+		port {
+			imx577_ep: endpoint {
+				clock-lanes = <7>;
+				link-frequencies = /bits/ 64 <600000000>;
+				data-lanes = <0 1 2 3>;
+				remote-endpoint = <&csiphy3_ep>;
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: BSD-3-Clause
 /*
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 /dts-v1/;
@@ -9,123 +9,222 @@
 #define PM7250B_SID 8
 #define PM7250B_SID1 9
 
+#include <dt-bindings/iio/qcom,spmi-adc7-pm7325.h>
+#include <dt-bindings/iio/qcom,spmi-adc7-pmk8350.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
 #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
-#include "sc7280.dtsi"
+#include "qcm6490.dtsi"
 #include "pm7250b.dtsi"
 #include "pm7325.dtsi"
 #include "pm8350c.dtsi"
 #include "pmk8350.dtsi"
 
-/delete-node/ &ipa_fw_mem;
-/delete-node/ &remoteproc_mpss;
-/delete-node/ &rmtfs_mem;
-/delete-node/ &adsp_mem;
-/delete-node/ &cdsp_mem;
-/delete-node/ &video_mem;
-/delete-node/ &wlan_ce_mem;
-/delete-node/ &wpss_mem;
-/delete-node/ &xbl_mem;
+/delete-node/ &usb_2_dwc3;
 
 / {
 	model = "Qualcomm Technologies, Inc. Robotics RB3gen2";
-	compatible = "qcom,qcs6490-rb3gen2", "qcom,qcm6490";
-	chassis-type = "embedded";
+	compatible = "qcom,qcm6490-rb3gen2", "qcom,qcm6490";
+
+	qcom,msm-id = <497 0x10000>, <498 0x10000>, <475 0x10000>, <515 0x10000>;
+	qcom,board-id = <32 0x5>, <32 0x605>;
 
 	aliases {
 		serial0 = &uart5;
+		bluetooth0 = &bluetooth;
+		serial1 = &uart7;
 	};
 
 	chosen {
 		stdout-path = "serial0:115200n8";
 	};
 
-	reserved-memory {
-		xbl_mem: xbl@80700000 {
-			reg = <0x0 0x80700000 0x0 0x100000>;
-			no-map;
-		};
-
-		cdsp_secure_heap_mem: cdsp-secure-heap@81800000 {
-			reg = <0x0 0x81800000 0x0 0x1e00000>;
-			no-map;
-		};
-
-		camera_mem: camera@84300000 {
-			reg = <0x0 0x84300000 0x0 0x500000>;
-			no-map;
-		};
-
-		wpss_mem: wpss@84800000 {
-			reg = <0x0 0x84800000 0x0 0x1900000>;
-			no-map;
-		};
-
-		adsp_mem: adsp@86100000 {
-			reg = <0x0 0x86100000 0x0 0x2800000>;
-			no-map;
-		};
-
-		cdsp_mem: cdsp@88900000 {
-			reg = <0x0 0x88900000 0x0 0x1e00000>;
-			no-map;
-		};
-
-		video_mem: video@8a700000 {
-			reg = <0x0 0x8a700000 0x0 0x700000>;
-			no-map;
-		};
-
-		cvp_mem: cvp@8ae00000 {
-			reg = <0x0 0x8ae00000 0x0 0x500000>;
-			no-map;
-		};
-
-		ipa_fw_mem: ipa-fw@8b300000 {
-			reg = <0x0 0x8b300000 0x0 0x10000>;
-			no-map;
-		};
-
-		ipa_gsi_mem: ipa-gsi@8b310000 {
-			reg = <0x0 0x8b310000 0x0 0xa000>;
-			no-map;
-		};
-
-		gpu_microcode_mem: gpu-microcode@8b31a000 {
-			reg = <0x0 0x8b31a000 0x0 0x2000>;
-			no-map;
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+
+		port {
+			hdmi_con: endpoint {
+				remote-endpoint = <&lt9611_out>;
+			};
 		};
+	};
 
-		tz_stat_mem: tz-stat@c0000000 {
-			reg = <0x0 0xc0000000 0x0 0x100000>;
-			no-map;
-		};
+	lt9611_1v2: lt9611-vdd12-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "LT9611_1V2";
 
-		tags_mem: tags@c0100000 {
-			reg = <0x0 0xc0100000 0x0 0x1200000>;
-			no-map;
-		};
+		regulator-min-microvolt = <1200000>;
+		regulator-max-microvolt = <1200000>;
+	};
 
-		qtee_mem: qtee@c1300000 {
-			reg = <0x0 0xc1300000 0x0 0x500000>;
-			no-map;
+	gpio-keys {
+		compatible = "gpio-keys";
+		label = "gpio-keys";
+
+		pinctrl-0 = <&key_vol_up_default>;
+		pinctrl-names = "default";
+
+		key-volume-up {
+			label = "volume_up";
+			gpios = <&pm7325_gpios 6 GPIO_ACTIVE_LOW>;
+			linux,input-type = <1>;
+			linux,code = <KEY_VOLUMEUP>;
+			wakeup-source;
+			debounce-interval = <15>;
+			linux,can-disable;
 		};
+	};
 
-		trusted_apps_mem: trusted_apps@c1800000 {
-			reg = <0x0 0xc1800000 0x0 0x1c00000>;
-			no-map;
+	pmic-glink {
+		compatible = "qcom,sm8350-pmic-glink", "qcom,pmic-glink";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		orientation-gpios = <&tlmm 140 GPIO_ACTIVE_HIGH>;
+		qcom,thermal-mitigation = <3000000 1500000 1000000 500000>;
+
+		connector@0 {
+			compatible = "usb-c-connector";
+			reg = <0>;
+			power-role = "dual";
+			data-role = "dual";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					pmic_glink_hs_in: endpoint {
+						remote-endpoint = <&eud_con>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					pmic_glink_ss_in: endpoint {
+						remote-endpoint = <&redriver_ss_out>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+
+					pmic_glink_sbu: endpoint {
+						remote-endpoint = <&fsa4480_sbu_mux>;
+					};
+				};
+			};
 		};
+	};
 
-		debug_vm_mem: debug-vm@d0600000 {
-			reg = <0x0 0xd0600000 0x0 0x100000>;
-			no-map;
+	sound: sound {
+		compatible = "qcom,qcm6490-sndcard";
+		model = "qcm6490-rb3-snd-card";
+
+		audio-routing =
+			"SpkrLeft IN", "WSA_SPK1 OUT",
+			"SpkrRight IN", "WSA_SPK2 OUT",
+			"VA DMIC0", "vdd-micb",
+			"VA DMIC1", "vdd-micb",
+			"VA DMIC2", "vdd-micb",
+			"VA DMIC3", "vdd-micb";
+
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+		wsa-dai-link {
+			link-name = "CODEC_DMA-LPAIF_WSA-RX-0";
+
+			cpu {
+				sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>;
+			};
+
+			codec {
+				sound-dai = <&left_spkr>, <&right_spkr>, <&swr2 0>,
+					    <&lpass_wsa_macro 0>;
+			};
+			platform {
+				sound-dai = <&q6apm>;
+			};
+		};
+
+		va-dai-link {
+			link-name = "CODEC_DMA-LPAIF_VA-TX-0";
+
+			cpu {
+				sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>;
+			};
+
+			codec {
+				sound-dai = <&lpass_va_macro 0>;
+			};
+			platform {
+				sound-dai = <&q6apm>;
+			};
+		};
+
+		vi-feedback-dai-link {
+			link-name = "CODEC_DMA-LPAIF_WSA-TX-0";
+
+			cpu {
+				sound-dai = <&q6apmbedai WSA_CODEC_DMA_TX_0>;
+			};
+
+			codec {
+				sound-dai = <&swr2 6>, <&lpass_wsa_macro 2>;
+			};
+			platform {
+				sound-dai = <&q6apm>;
+			};
 		};
 	};
 
-	vph_pwr: vph-pwr-regulator {
-		compatible = "regulator-fixed";
-		regulator-name = "vph_pwr";
-		regulator-min-microvolt = <2500000>;
-		regulator-max-microvolt = <4350000>;
+	thermal-zones {
+		quiet-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmk8350_adc_tm 1>;
+
+			trips {
+				active-config0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+			};
+		};
+
+		sdm-skin-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmk8350_adc_tm 3>;
+
+			trips {
+				active-config0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+			};
+		};
+
+		xo-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmk8350_adc_tm 0>;
+
+			trips {
+				active-config0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+			};
+		};
 	};
 };
 
@@ -134,24 +233,6 @@
 		compatible = "qcom,pm7325-rpmh-regulators";
 		qcom,pmic-id = "b";
 
-		vdd-s1-supply = <&vph_pwr>;
-		vdd-s2-supply = <&vph_pwr>;
-		vdd-s3-supply = <&vph_pwr>;
-		vdd-s4-supply = <&vph_pwr>;
-		vdd-s5-supply = <&vph_pwr>;
-		vdd-s6-supply = <&vph_pwr>;
-		vdd-s7-supply = <&vph_pwr>;
-		vdd-s8-supply = <&vph_pwr>;
-		vdd-l1-l4-l12-l15-supply = <&vreg_s7b_0p972>;
-		vdd-l2-l7-supply = <&vreg_bob_3p296>;
-		vdd-l3-supply = <&vreg_s2b_0p876>;
-		vdd-l5-supply = <&vreg_s2b_0p876>;
-		vdd-l6-l9-l10-supply = <&vreg_s8b_1p272>;
-		vdd-l8-supply = <&vreg_s7b_0p972>;
-		vdd-l11-l17-l18-l19-supply = <&vreg_s1b_1p872>;
-		vdd-l13-supply = <&vreg_s7b_0p972>;
-		vdd-l14-l16-supply = <&vreg_s8b_1p272>;
-
 		vreg_s1b_1p872: smps1 {
 			regulator-min-microvolt = <1840000>;
 			regulator-max-microvolt = <2040000>;
@@ -170,11 +251,10 @@
 		vreg_s8b_1p272: smps8 {
 			regulator-min-microvolt = <1200000>;
 			regulator-max-microvolt = <1500000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_RET>;
 		};
 
 		vreg_l1b_0p912: ldo1 {
-			regulator-min-microvolt = <825000>;
+			regulator-min-microvolt = <912000>;
 			regulator-max-microvolt = <925000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
@@ -197,7 +277,7 @@
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
-		reg_l5b_0p752: ldo5 {
+		vreg_l5b_0p752: ldo5 {
 			regulator-min-microvolt = <552000>;
 			regulator-max-microvolt = <832000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
@@ -286,23 +366,6 @@
 		compatible = "qcom,pm8350c-rpmh-regulators";
 		qcom,pmic-id = "c";
 
-		vdd-s1-supply = <&vph_pwr>;
-		vdd-s2-supply = <&vph_pwr>;
-		vdd-s3-supply = <&vph_pwr>;
-		vdd-s4-supply = <&vph_pwr>;
-		vdd-s5-supply = <&vph_pwr>;
-		vdd-s6-supply = <&vph_pwr>;
-		vdd-s7-supply = <&vph_pwr>;
-		vdd-s8-supply = <&vph_pwr>;
-		vdd-s9-supply = <&vph_pwr>;
-		vdd-s10-supply = <&vph_pwr>;
-		vdd-l1-l12-supply = <&vreg_s1b_1p872>;
-		vdd-l2-l8-supply = <&vreg_s1b_1p872>;
-		vdd-l3-l4-l5-l7-l13-supply = <&vreg_bob_3p296>;
-		vdd-l6-l9-l11-supply = <&vreg_bob_3p296>;
-		vdd-l10-supply = <&vreg_s7b_0p972>;
-		vdd-bob-supply = <&vph_pwr>;
-
 		vreg_s1c_2p19: smps1 {
 			regulator-min-microvolt = <2190000>;
 			regulator-max-microvolt = <2210000>;
@@ -328,6 +391,11 @@
 			regulator-max-microvolt = <1170000>;
 		};
 
+		vreg_s10c_0p752:smps10 {
+			regulator-min-microvolt = <752000>;
+			regulator-max-microvolt = <800000>;
+		};
+
 		vreg_l1c_1p8: ldo1 {
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <1980000>;
@@ -378,12 +446,12 @@
 
 		vreg_l9c_2p96: ldo9 {
 			regulator-min-microvolt = <2700000>;
-			regulator-max-microvolt = <35440000>;
+			regulator-max-microvolt = <3544000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
 		vreg_l10c_0p88: ldo10 {
-			regulator-min-microvolt = <720000>;
+			regulator-min-microvolt = <880000>;
 			regulator-max-microvolt = <1050000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
@@ -413,13 +481,554 @@
 	};
 };
 
+&eud {
+	usb-role-switch;
+	status = "okay";
+};
+
+&eud_con {
+	remote-endpoint = <&pmic_glink_hs_in>;
+};
+
+&eud_ep {
+	remote-endpoint = <&usb_1_dwc3_hs>;
+};
+
+&gcc {
+	protected-clocks = <GCC_QSPI_CNOC_PERIPH_AHB_CLK>, <GCC_QSPI_CORE_CLK>,
+			<GCC_QSPI_CORE_CLK_SRC>, <GCC_CFG_NOC_LPASS_CLK>,
+			<GCC_MSS_GPLL0_MAIN_DIV_CLK_SRC>, <GCC_MSS_CFG_AHB_CLK>,
+			<GCC_MSS_OFFLINE_AXI_CLK>, <GCC_MSS_SNOC_AXI_CLK>,
+			<GCC_MSS_Q6_MEMNOC_AXI_CLK>, <GCC_MSS_Q6SS_BOOT_CLK_SRC>,
+			<GCC_SEC_CTRL_CLK_SRC>, <GCC_WPSS_AHB_CLK>,
+			<GCC_WPSS_AHB_BDG_MST_CLK>, <GCC_WPSS_RSCP_CLK>;
+};
+
+&gpu {
+	status = "okay";
+};
+
+&gpu_zap_shader {
+	firmware-name = "qcom/qcs6490/a660_zap.mbn";
+};
+
+&i2c0 {
+	clock-frequency = <400000>;
+	status = "okay";
+
+	lt9611_codec: hdmi-bridge@2b {
+		compatible = "lontium,lt9611uxc";
+		reg = <0x2b>;
+
+		interrupts-extended = <&tlmm 24 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&pm7250b_gpios 2 GPIO_ACTIVE_HIGH>;
+
+		vdd-supply = <&lt9611_1v2>;
+		vcc-supply = <&vreg_l11c_2p8>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&lt9611_irq_pin &lt9611_rst_pin>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				lt9611_a: endpoint {
+					remote-endpoint = <&mdss_dsi0_out>;
+				};
+			};
+
+			port@2 {
+				reg = <2>;
+
+				lt9611_out: endpoint {
+					remote-endpoint = <&hdmi_con>;
+				};
+			};
+		};
+	};
+};
+
+&i2c1 {
+	clock-frequency = <100000>;
+	status = "okay";
+
+	typec-mux@42 {
+		compatible = "fcs,fsa4480";
+		reg = <0x42>;
+		interrupts-extended = <&tlmm 2 IRQ_TYPE_LEVEL_LOW>;
+		vcc-supply = <&vreg_bob_3p296>;
+		mode-switch;
+		orientation-switch;
+		svid = /bits/ 16 <0xff01>;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				fsa4480_sbu_mux: endpoint {
+					remote-endpoint = <&pmic_glink_sbu>;
+				};
+			};
+		};
+	};
+
+	typec-retimer@1c {
+		compatible = "onnn,nb7vpq904m";
+		reg = <0x1c>;
+
+		vcc-supply = <&vreg_l7b_2p952>;
+
+		retimer-switch;
+		orientation-switch;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				redriver_ss_out: endpoint {
+					remote-endpoint = <&pmic_glink_ss_in>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				redriver_ss_in: endpoint {
+					data-lanes = <3 2 1 0>;
+					remote-endpoint = <&usb_1_qmpphy_out>;
+				};
+			};
+		};
+	};
+};
+
+&ipa {
+	status = "disabled";
+};
+
+&lpasscc {
+	status = "disabled";
+};
+
+&pm7325_gpios {
+	key_vol_up_default: key-vol-up-state {
+		pins = "gpio6";
+		function = "normal";
+		input-enable;
+		bias-pull-up;
+		power-source = <0>;
+		qcom,drive-strength = <3>;
+	};
+};
+
+&pm7325_temp_alarm {
+	io-channels = <&pmk8350_vadc PM7325_ADC7_DIE_TEMP>;
+	io-channel-names = "thermal";
+};
+
+&pm8350c_pwm {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	led@1 {
+		reg = <1>;
+		color = <LED_COLOR_ID_RED>;
+		label = "red";
+	};
+
+	led@2 {
+		reg = <2>;
+		color = <LED_COLOR_ID_GREEN>;
+		label = "green";
+	};
+
+	led@3 {
+		reg = <3>;
+		color = <LED_COLOR_ID_BLUE>;
+		label = "blue";
+	};
+};
+
+&pmk8350_adc_tm {
+	status = "okay";
+
+	xo-therm@0 {
+		reg = <0>;
+		io-channels = <&pmk8350_vadc PMK8350_ADC7_AMUX_THM1_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time-us = <200>;
+	};
+
+	quiet-therm@1 {
+		reg = <1>;
+		io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM1_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time-us = <200>;
+	};
+
+	sdm-skin-therm@3 {
+		reg = <3>;
+		io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM3_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time-us = <200>;
+	};
+};
+
+&pmk8350_pon {
+	status = "okay";
+};
+
+&pmk8350_rtc {
+	status = "okay";
+};
+
+&pmk8350_vadc {
+	channel@44 {
+		reg = <PMK8350_ADC7_AMUX_THM1_100K_PU>;
+		label = "xo_therm";
+		qcom,hw-settle-time = <200>;
+		qcom,pre-scaling = <1 1>;
+		qcom,ratiometric;
+	};
+
+	channel@103 {
+		reg = <PM7325_ADC7_DIE_TEMP>;
+		label = "pm7325_die_temp";
+		qcom,pre-scaling = <1 1>;
+	};
+
+	channel@144 {
+		reg = <PM7325_ADC7_AMUX_THM1_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time = <200>;
+		qcom,pre-scaling = <1 1>;
+		label = "pm7325_quiet_therm";
+	};
+
+	channel@146 {
+		reg = <PM7325_ADC7_AMUX_THM3_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time = <200>;
+		qcom,pre-scaling = <1 1>;
+		label = "pm7325_sdm_skin_therm";
+	};
+
+	pmk8350-die-temp@3 {
+		reg = <PMK8350_ADC7_DIE_TEMP>;
+		label = "pmk8350_die_temp";
+		qcom,pre-scaling = <1 1>;
+	};
+};
+
+&pon_pwrkey {
+	status = "okay";
+};
+
+&pon_resin {
+	linux,code = <KEY_VOLUMEDOWN>;
+	status = "okay";
+};
+
+&lpass_dmic01_clk {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&lpass_dmic01_data {
+	bias-pull-down;
+};
+
+&lpass_dmic23_clk {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&lpass_dmic23_data {
+	bias-pull-down;
+};
+
+&lpass_dmic45_clk {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&lpass_dmic45_data {
+	bias-pull-down;
+};
+
+&lpass_wsa_swr_clk {
+	drive-strength = <2>;
+	slew-rate = <1>;
+	bias-disable;
+};
+
+&lpass_wsa_swr_data {
+	drive-strength = <2>;
+	slew-rate = <1>;
+	bias-bus-hold;
+};
+
+&mdss {
+	status = "okay";
+};
+
+&mdss_dp {
+	status = "okay";
+};
+
+&mdss_dp_out {
+	data-lanes = <0 1>;
+	remote-endpoint = <&usb_1_qmpphy_dp_in>;
+};
+
+&mdss_dsi {
+	vdda-supply = <&vreg_l6b_1p2>;
+	status = "okay";
+};
+
+&mdss_dsi0_out {
+	remote-endpoint = <&lt9611_a>;
+	data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi_phy {
+	vdds-supply = <&vreg_l10c_0p88>;
+	status = "okay";
+};
+
+&pcie1 {
+	perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+
+	pinctrl-0 = <&pcie1_reset_n>, <&pcie1_wake_n>, <&pcie1_clkreq_n>;
+	pinctrl-names = "default";
+
+	iommu-map = <0x0 &apps_smmu 0x1c80 0x1>,
+		    <0x100 &apps_smmu 0x1c81 0x1>,
+		    <0x208 &apps_smmu 0x1c84 0x1>,
+		    <0x210 &apps_smmu 0x1c85 0x1>,
+		    <0x218 &apps_smmu 0x1c86 0x1>,
+		    <0x300 &apps_smmu 0x1c87 0x1>,
+		    <0x400 &apps_smmu 0x1c88 0x1>,
+		    <0x500 &apps_smmu 0x1c89 0x1>,
+		    <0x501 &apps_smmu 0x1c90 0x1>;
+
+	status = "okay";
+};
+
+&pcie1_phy {
+	vdda-phy-supply = <&vreg_l10c_0p88>;
+	vdda-pll-supply = <&vreg_l6b_1p2>;
+
+	status = "okay";
+};
+
+&qup_uart5_rx {
+	drive-strength = <2>;
+	bias-pull-up;
+};
+
+&qup_uart5_tx {
+	drive-strength = <2>;
+	bias-disable;
+};
+
+&qup_uart7_cts {
+	/*
+	 * Configure a bias-bus-hold on CTS to lower power
+	 * usage when Bluetooth is turned off. Bus hold will
+	 * maintain a low power state regardless of whether
+	 * the Bluetooth module drives the pin in either
+	 * direction or leaves the pin fully unpowered.
+	 */
+	bias-bus-hold;
+};
+
+&qup_uart7_rts {
+	/* We'll drive RTS, so no pull */
+	drive-strength = <2>;
+	bias-disable;
+};
+
+&qup_uart7_rx {
+	/*
+	 * Configure a pull-up on RX. This is needed to avoid
+	 * garbage data when the TX pin of the Bluetooth module is
+	 * in tri-state (module powered off or not driving the
+	 * signal yet).
+	 */
+	bias-pull-up;
+};
+
+&qup_uart7_tx {
+	/* We'll drive TX, so no pull */
+	drive-strength = <2>;
+	bias-disable;
+};
+
+&gpi_dma0 {
+	status = "okay";
+};
+
+&gpi_dma1 {
+	status = "okay";
+};
+
 &qupv3_id_0 {
 	status = "okay";
 };
 
+&qupv3_id_1 {
+	status = "okay";
+};
+
+&remoteproc_adsp {
+	firmware-name = "qcom/qcs6490/adsp.mdt";
+	status = "okay";
+};
+
+&remoteproc_cdsp {
+	firmware-name = "qcom/qcs6490/cdsp.mdt";
+	status = "okay";
+};
+
+&remoteproc_mpss {
+	firmware-name = "qcom/qcs6490/modem.mdt";
+	status = "okay";
+};
+
+&remoteproc_wpss {
+	firmware-name = "qcom/qcs6490/wpss.mbn";
+	status = "okay";
+};
+
+&spi3 {
+	status = "okay";
+
+	mcp2518fd: can@0 {
+		compatible = "microchip,mcp2518fd";
+		reg = <0>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		clock-frequency = <40000000>;
+		spi-max-frequency = <10000000>;
+		interrupt-names = "can_irq";
+		interrupts-extended = <&tlmm 7 IRQ_TYPE_LEVEL_LOW>;
+		status = "okay";
+	};
+};
+
+&swr2 {
+	qcom,din-ports = <0>;
+	qcom,dout-ports = <8>;
+
+	left_spkr: speaker@0,1 {
+		compatible = "sdw10217020200";
+		reg = <0 1>;
+		powerdown-gpios = <&tlmm 158 GPIO_ACTIVE_LOW>;
+		#sound-dai-cells = <0>;
+		sound-name-prefix = "SpkrLeft";
+		#thermal-sensor-cells = <0>;
+		vdd-supply = <&vreg_l18b_1p8>;
+		qcom,port-mapping = <1 2 3 7>;
+	};
+
+	right_spkr: speaker@0,2 {
+		compatible = "sdw10217020200";
+		reg = <0 2>;
+		powerdown-gpios = <&tlmm 158 GPIO_ACTIVE_LOW>;
+		#sound-dai-cells = <0>;
+		sound-name-prefix = "SpkrRight";
+		#thermal-sensor-cells = <0>;
+		vdd-supply = <&vreg_l18b_1p8>;
+		qcom,port-mapping = <4 5 6 8>;
+	};
+};
+
 &tlmm {
-	gpio-reserved-ranges = <32 2>, /* ADSP */
-			       <48 4>; /* NFC */
+	bt_en: bt-en-state {
+		pins = "gpio85";
+		function = "gpio";
+		output-low;
+		bias-disable;
+	};
+
+	pcie1_reset_n: pcie1-reset-n-state {
+		pins = "gpio2";
+		function = "gpio";
+		drive-strength = <16>;
+		output-low;
+		bias-disable;
+	};
+
+	pcie1_wake_n: pcie1-wake-n-state {
+		pins = "gpio3";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-up;
+	};
+
+	qup_uart7_sleep_cts: qup-uart7-sleep-cts-state {
+		pins = "gpio28";
+		function = "gpio";
+		/*
+		 * Configure a bias-bus-hold on CTS to lower power
+		 * usage when Bluetooth is turned off. Bus hold will
+		 * maintain a low power state regardless of whether
+		 * the Bluetooth module drives the pin in either
+		 * direction or leaves the pin fully unpowered.
+		 */
+		bias-bus-hold;
+	};
+
+	qup_uart7_sleep_rts: qup-uart7-sleep-rts-state {
+		pins = "gpio29";
+		function = "gpio";
+		/*
+		 * Configure pull-down on RTS. As RTS is active low
+		 * signal, pull it low to indicate the BT SoC that it
+		 * can wakeup the system anytime from suspend state by
+		 * pulling RX low (by sending wakeup bytes).
+		 */
+		bias-pull-down;
+	};
+
+	qup_uart7_sleep_rx: qup-uart7-sleep-rx-state {
+		pins = "gpio31";
+		function = "gpio";
+		/*
+		 * Configure a pull-up on RX. This is needed to avoid
+		 * garbage data when the TX pin of the Bluetooth module
+		 * is floating which may cause spurious wakeups.
+		 */
+		bias-pull-up;
+	};
+
+	qup_uart7_sleep_tx: qup-uart7-sleep-tx-state {
+		pins = "gpio30";
+		function = "gpio";
+		/*
+		 * Configure pull-up on TX when it isn't actively driven
+		 * to prevent BT SoC from receiving garbage during sleep.
+		 */
+		bias-pull-up;
+	};
+
+	sw_ctrl: sw-ctrl-state {
+		pins = "gpio86";
+		function = "gpio";
+		bias-pull-down;
+	};
 };
 
 &uart5 {
@@ -427,18 +1036,117 @@
 	status = "okay";
 };
 
+&uart7 {
+	status = "okay";
+	/delete-property/interrupts;
+	interrupts-extended = <&intc GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>,
+				<&tlmm 31 IRQ_TYPE_EDGE_FALLING>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-1 = <&qup_uart7_sleep_cts>, <&qup_uart7_sleep_rts>,
+			<&qup_uart7_sleep_tx>, <&qup_uart7_sleep_rx>;
+
+	bluetooth: bluetooth {
+		compatible = "qcom,wcn6750-bt";
+		pinctrl-names = "default";
+		pinctrl-0 = <&bt_en>, <&sw_ctrl>;
+		enable-gpios = <&tlmm 85 GPIO_ACTIVE_HIGH>;
+		swctrl-gpios = <&tlmm 86 GPIO_ACTIVE_HIGH>;
+		vddaon-supply = <&vreg_s7b_0p972>;
+		vddbtcxmx-supply = <&vreg_s7b_0p972>;
+		vddrfacmn-supply = <&vreg_s7b_0p972>;
+		vddrfa0p8-supply = <&vreg_s7b_0p972>;
+		vddrfa1p7-supply = <&vreg_s1b_1p872>;
+		vddrfa1p2-supply = <&vreg_s8b_1p272>;
+		vddrfa2p2-supply = <&vreg_s1c_2p19>;
+		vddasd-supply = <&vreg_l11c_2p8>;
+		max-speed = <3200000>;
+		local-bd-address = [ad 5a 00 00 90 64];
+	};
+};
+
+&ufs_mem_hc {
+	reset-gpios = <&tlmm 175 GPIO_ACTIVE_LOW>;
+	vcc-supply = <&vreg_l7b_2p952>;
+	vcc-max-microamp = <800000>;
+	vccq-supply = <&vreg_l9b_1p2>;
+	vccq-max-microamp = <900000>;
+	vccq2-supply = <&vreg_l9b_1p2>;
+	vccq2-max-microamp = <900000>;
+
+	status = "okay";
+};
+
+&ufs_mem_phy {
+	vdda-phy-supply = <&vreg_l10c_0p88>;
+	vdda-pll-supply = <&vreg_l6b_1p2>;
+
+	status = "okay";
+};
+
+&sdhc_2 {
+	status = "okay";
+
+	pinctrl-0 = <&sdc2_clk>, <&sdc2_cmd>, <&sdc2_data>, <&sd_cd>;
+	pinctrl-1 = <&sdc2_clk_sleep>, <&sdc2_cmd_sleep>, <&sdc2_data_sleep>, <&sd_cd>;
+
+	vmmc-supply = <&vreg_l9c_2p96>;
+	vqmmc-supply = <&vreg_l6c_2p96>;
+
+	cd-gpios = <&tlmm 91 GPIO_ACTIVE_LOW>;
+};
+
+/delete-node/ &usb_1_dwc3;
+
 &usb_1 {
+
+	reg = <0x0 0x0a600000 0x0 0x200000>;
+
+	interrupts-extended = <&intc GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+			      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+			      <&pdc 14 IRQ_TYPE_LEVEL_HIGH>,
+			      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
+			      <&pdc 17 IRQ_TYPE_EDGE_BOTH>;
+	interrupt-names = "dwc_usb3",
+			  "hs_phy_irq",
+			  "dp_hs_phy_irq",
+			  "dm_hs_phy_irq",
+			  "ss_phy_irq";
+
+	iommus = <&apps_smmu 0xe0 0x0>;
+	snps,dis_u2_susphy_quirk;
+	snps,dis_enblslpm_quirk;
+	phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
+	phy-names = "usb2-phy", "usb3-phy";
+	maximum-speed = "super-speed";
+	snps,dis-u2-entry-quirk;
+	snps,dis-u1-entry-quirk;
+	dr_mode = "otg";
+	usb-role-switch;
+	qcom,enable-rt;
+	wakeup-source;
+
 	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			usb_1_dwc3_hs: endpoint {
+			};
+		};
+	};
 };
 
-&usb_1_dwc3 {
-	dr_mode = "peripheral";
+&usb_1_dwc3_hs {
+	remote-endpoint = <&eud_ep>;
 };
 
 &usb_1_hsphy {
 	vdda-pll-supply = <&vreg_l10c_0p88>;
-	vdda33-supply = <&vreg_l2b_3p072>;
 	vdda18-supply = <&vreg_l1c_1p8>;
+	vdda33-supply = <&vreg_l2b_3p072>;
 
 	status = "okay";
 };
@@ -447,9 +1155,185 @@
 	vdda-phy-supply = <&vreg_l6b_1p2>;
 	vdda-pll-supply = <&vreg_l1b_0p912>;
 
+	orientation-switch;
+	status = "okay";
+};
+
+&usb_1_qmpphy_out {
+	remote-endpoint = <&redriver_ss_in>;
+};
+
+&usb_1_qmpphy_dp_in {
+	remote-endpoint = <&mdss_dp_out>;
+};
+
+&vreg_l7b_2p952 {
+	/delete-property/regulator-min-microvolt;
+	/delete-property/regulator-max-microvolt;
+	regulator-allow-set-load;
+	regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM RPMH_REGULATOR_MODE_HPM>;
+};
+
+&vreg_l9b_1p2 {
+	/delete-property/regulator-min-microvolt;
+	/delete-property/regulator-max-microvolt;
+	regulator-allow-set-load;
+	regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM RPMH_REGULATOR_MODE_HPM>;
+};
+
+/*     USB2 Related Start        */
+/*==============================*/
+
+&pm7325_gpios {
+	usb2_vbus_det_default: usb2_vbus_det_state {
+		pins = "gpio9";
+		function = "normal";
+		bias-pull-down;
+		input-enable;
+		power-source = <0>;
+	};
+};
+
+&sdc2_clk {
+	bias-disable;
+	drive-strength = <16>;
+};
+
+&sdc2_cmd {
+	bias-pull-up;
+	drive-strength = <10>;
+};
+
+&sdc2_data {
+	bias-pull-up;
+	drive-strength = <10>;
+};
+
+&tlmm {
+	usb2_id_det_default: usb2_id_det_default {
+		pins = "gpio61";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-up;
+	};
+
+	sd_cd: sd-cd-state {
+		pins = "gpio91";
+		function = "gpio";
+		bias-pull-up;
+	};
+};
+
+&soc {
+	vbus_supply_regulator: vbus_supply_regulator {
+	       compatible = "regulator-fixed";
+	       regulator-name = "vbus_supply";
+	       gpio = <&tlmm 63 GPIO_ACTIVE_HIGH>;
+	       regulator-min-microvolt = <5000000>;
+	       regulator-max-microvolt = <5000000>;
+	       regulator-boot-on;
+	       enable-active-high;
+	};
+
+	connector_usb2: connector_usb2 {
+		compatible = "gpio-usb-b-connector";
+		vbus-gpio = <&pm7325_gpios 9 GPIO_ACTIVE_HIGH>;
+		id-gpio = <&tlmm 61 GPIO_ACTIVE_HIGH>;
+		vbus-supply = <&vbus_supply_regulator>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb2_vbus_det_default>,
+			     <&usb2_id_det_default>;
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				usb2_port_connector: endpoint {
+					remote-endpoint = <&usb2_port>;
+				};
+			};
+		};
+	};
+};
+
+&usb_2 {
+	reg = <0x0 0x08c00000 0x0 0x100000>;
+
+	interrupts-extended = <&intc GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>,
+				<&intc GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+				<&pdc 12 IRQ_TYPE_LEVEL_HIGH>,
+				<&pdc 13 IRQ_TYPE_EDGE_BOTH>;
+	interrupt-names = "dwc_usb2",
+			"hs_phy_irq",
+			"dp_hs_phy_irq",
+			"dm_hs_phy_irq";
+
+	iommus = <&apps_smmu 0xa0 0x0>;
+	snps,dis_u2_susphy_quirk;
+	snps,dis_enblslpm_quirk;
+	phys = <&usb_2_hsphy>;
+	phy-names = "usb2-phy";
+	maximum-speed = "high-speed";
+	snps,dis-u2-entry-quirk;
+	snps,dis-u1-entry-quirk;
+
+	usb-role-switch;
+	qcom,enable-rt;
+	wakeup-source;
+	dr_mode = "otg";
+
 	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			usb2_port: endpoint {
+				remote-endpoint = <&usb2_port_connector>;
+			};
+		};
+
+		port@1 {
+			usb2_role_switch: endpoint {
+				remote-endpoint = <&eud_ep>;
+			};
+		};
+	};
+};
+
+&pm7250b_gpios {
+	lt9611_rst_pin: lt9611-rst-state {
+		pins = "gpio2";
+		function = "normal";
+
+		output-high;
+		input-disable;
+		power-source = <0>;
+	};
+};
+
+&tlmm {
+	lt9611_irq_pin: lt9611-irq-state {
+		pins = "gpio24";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+	};
 };
 
+&usb_2_hsphy {
+	vdda-pll-supply = <&vreg_l10c_0p88>;
+	vdda18-supply = <&vreg_l1c_1p8>;
+	vdda33-supply = <&vreg_l2b_3p072>;
+
+	status = "okay";
+};
+
+/* moved from qcm6490-wlan-upstream.dtsi */
 &wifi {
-	memory-region = <&wlan_fw_mem>;
+	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8275-addons-iq-8275-evk-mezz.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8275-addons-iq-8275-evk-mezz.dtso
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+&{/} {
+	model = "Qualcomm Technologies, Inc. Addons IQ8-8275-evk Mezzanine";
+	qcom,board-id = <0x00010020 1>, <0x00010019 1>;
+
+	qps615_rsex_vreg: qps615-rsex-vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "qps615_rsex_vreg";
+		gpio = <&tlmm 124 GPIO_ACTIVE_HIGH>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		enable-active-high;
+		regulator-enable-ramp-delay = <10000>;
+	};
+};
+
+&i2c15 {
+
+	status = "okay";
+
+	qps615_switch: pcie-switch@77 {
+		compatible = "qcom,switch-i2c";
+		reg = <0x77>;
+		vdda-supply = <&qps615_rsex_vreg>;
+
+		status = "okay";
+	};
+
+};
+
+&pcie0 {
+	dummy-supply = <&qps615_switch>;
+	max-link-speed = <2>;
+	iommu-map = <0x0 &apps_smmu 0x0000 0x1>,
+	            <0x100 &pcie_smmu 0x0001 0x1>,
+	            <0x208 &pcie_smmu 0x0002 0x1>,
+	            <0x210 &pcie_smmu 0x0003 0x1>,
+	            <0x218 &pcie_smmu 0x0004 0x1>,
+	            <0x300 &pcie_smmu 0x0005 0x1>,
+	            <0x400 &pcie_smmu 0x0006 0x1>,
+	            <0x500 &pcie_smmu 0x0007 0x1>,
+	            <0x501 &pcie_smmu 0x0008 0x1>;
+
+	pcieport0: pcie@0 {
+		device_type = "pci";
+		reg = <0x0 0x0 0x0 0x0 0x0>;
+		#address-cells = <5>;
+		#size-cells = <0>;
+
+		/* BDF 1.0.0 */
+		pcie0_bus1_dev0_fn0: pcie0_bus1_dev0_fn0 {
+			reg = <0 0 0 0 0>;
+
+			/* BDF 2.1.0 */
+			pcie0_bus2_dev1_fn0: pcie0_bus2_dev1_fn0 {
+				reg = <0x800 0x0 0x0 0x0 0x0>;
+
+				/* BDF 3.0.0 */
+				pcie0_bus3_dev0_fn0: pcie0_bus3_dev0_fn0 {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+				};
+			};
+
+			/* BDF 2.2.0 */
+			pcie0_bus2_dev2_fn0: pcie0_bus2_dev2_fn0 {
+				reg = <0x1000 0x0 0x0 0x0 0x0>;
+
+				/* BDF 4.0.0 */
+				pcie0_bus4_dev0_fn0: pcie0_bus4_dev0_fn0 {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+				};
+			};
+
+			/* BDF 2.3.0 */
+			pcie0_bus2_dev3_fn0: pcie0_bus2_dev3_fn0 {
+				reg = <0x1800 0x0 0x0 0x0 0x0>;
+
+				/* BDF 5.0.0 */
+				pcie0_bus5_dev0_fn0: pcie0_qps_eth0 {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+				};
+
+				/* BDF 5.0.1 */
+				pcie0_bus5_dev0_fn1: pcie0_qps_eth1 {
+					reg = <0x100 0x0 0x0 0x0 0x0>;
+				};
+			};
+		};
+	};
+};
+
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8275-addons-iq-8275-evk-pro-sku.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8275-addons-iq-8275-evk-pro-sku.dtso
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include "qcs8300-addons.dtsi"
+
+&{/} {
+	model = "Qualcomm Technologies, Inc. IQ8 8275 addons Pro SKU EVK";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8275-addons-iq-8275-evk.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8275-addons-iq-8275-evk.dtso
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include "qcs8300-addons.dtsi"
+
+&{/} {
+	sound {
+		compatible = "qcom,iq8-8275-evk-sndcard";
+		model = "iq8-8275-evk-snd-card";
+
+		clocks = <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+			    <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+		clock-names = "macro", "dcodec";
+
+		pinctrl-names = "default", "mi2s_aud_out_active", "mi2s_aud_out_sleep";
+		pinctrl-0 = <&hs0_mi2s_data0_sleep>, <&hs0_mi2s_sclk_sleep>,
+			    <&hs0_mi2s_data1_sleep>, <&hs0_mi2s_ws_sleep>,
+			    <&hs2_mi2s_data0_sleep>, <&hs2_mi2s_data1_sleep>,
+			    <&hs2_mi2s_sck_sleep>, <&hs2_mi2s_ws_sleep>;
+		pinctrl-1 = <&hs0_mi2s_data0>, <&hs0_mi2s_sclk>,
+			    <&hs0_mi2s_data1>, <&hs0_mi2s_ws>,
+			    <&hs2_mi2s_data0>, <&hs2_mi2s_data1>,
+			    <&hs2_mi2s_sck>, <&hs2_mi2s_ws>;
+		pinctrl-2 = <&hs0_mi2s_data0_sleep>, <&hs0_mi2s_sclk_sleep>,
+			    <&hs0_mi2s_data1_sleep>, <&hs0_mi2s_ws_sleep>,
+			    <&hs2_mi2s_data0_sleep>, <&hs2_mi2s_data1_sleep>,
+			    <&hs2_mi2s_sck_sleep>, <&hs2_mi2s_ws_sleep>;
+
+		hs0-mi2s-playback-dai-link {
+			link-name = "MI2S-LPAIF_SDR-RX-PRIMARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_SDR_MI2S_RX>;
+			};
+
+			codec {
+				sound-dai = <&max98357a>;
+			};
+		};
+
+		hs2-mi2s-capture-dai-link {
+			link-name = "MI2S-LPAIF_SDR-TX-TERTIARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai TERTIARY_SDR_MI2S_TX>;
+			};
+
+			codec {
+				sound-dai = <&dmic_codec>;
+			};
+		};
+
+	};
+};
+
+&soc {
+
+	msm_stub_codec: msm-stub-codec {
+		compatible = "qcom,msm-stub-codec";
+		#sound-dai-cells = <1>;
+	};
+
+	max98357a: audio-codec-0 {
+		compatible = "maxim,max98357a";
+		#sound-dai-cells = <0>;
+	};
+
+	dmic_codec: dmic-codec {
+		compatible = "dmic-codec";
+		#sound-dai-cells = <0>;
+		num-channels = <1>;
+	};
+
+	spf_core_platform: spf-core-platform {
+		compatible = "qcom,spf-core-platform";
+
+		msm_audio_mem: msm-audio-mem {
+			compatible = "qcom,msm-audio-mem";
+			qcom,smmu-version = <2>;
+			qcom,smmu-enabled;
+			iommus = <&apps_smmu 0x2001 0x0>;
+			qcom,iommu-dma-addr-pool = <0x10000000 0x10000000>;
+			qcom,smmu-sid-mask = /bits/ 64 <0xf>;
+			dma-coherent;
+		};
+
+		msm_audio_mem_cma: msm-audio-mem-cma {
+			compatible = "qcom,msm-audio-mem";
+			memory-region = <&audio_cma_mem>;
+		};
+	};
+};
+
+&tlmm {
+	hs0_mi2s_data0_sleep: hs0-mi2s-data0-sleep-state {
+		pins = "gpio108";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs0_mi2s_data0: hs0-mi2s-data0-state {
+		pins = "gpio108";
+		function = "hs0_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	hs0_mi2s_data1_sleep: hs0-mi2s-data1-sleep-state {
+		pins = "gpio109";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs0_mi2s_data1: hs0-mi2s-data1-state {
+		pins = "gpio109";
+		function = "hs0_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	hs0_mi2s_sclk_sleep: hs0-mi2s-sclk-sleep-state {
+		pins = "gpio106";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs0_mi2s_sclk: hs0-mi2s-sclk-state {
+		pins = "gpio106";
+		function = "hs0_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	hs0_mi2s_ws_sleep: hs0-mi2s-ws-sleep-state {
+		pins = "gpio107";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs0_mi2s_ws: hs0-mi2s-ws-state {
+		pins = "gpio107";
+		function = "hs0_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	hs2_mi2s_data0: hs2-mi2s-data0-state {
+		pins = "gpio49";
+		function = "hs2_mi2s";
+		drive-strength = <8>;
+		input-enable;
+		bias-disable;
+	};
+
+	hs2_mi2s_data0_sleep: hs2-mi2s-data0-sleep-state {
+		pins = "gpio49";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs2_mi2s_data1: hs2-mi2s-data1-state {
+		pins = "gpio50";
+		function = "hs2_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	hs2_mi2s_data1_sleep: hs2-mi2s-data1-sleep-state {
+		pins = "gpio50";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs2_mi2s_sck: hs2-mi2s-sck-state {
+		pins = "gpio51";
+		function = "hs2_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	hs2_mi2s_sck_sleep: hs2-mi2s-sck-sleep-state {
+		pins = "gpio51";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs2_mi2s_ws: hs2-mi2s-ws-state {
+		pins = "gpio52";
+		function = "hs2_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	hs2_mi2s_ws_sleep: hs2-mi2s-ws-sleep-state {
+		pins = "gpio52";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+};
+
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8275-camera-iq-8275-evk.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8275-camera-iq-8275-evk.dtsi
@@ -0,0 +1,2633 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+#include <dt-bindings/msm-camera.h>
+
+&tlmm {
+	cci_i2c_sda0_active: cci_i2c_sda0_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio57";
+			function = "cci_i2c_sda0";
+		};
+
+		config {
+			pins = "gpio57";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda0_suspend: cci_i2c_sda0_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio57";
+			function = "cci_i2c_sda0";
+		};
+
+		config {
+			pins = "gpio57";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl0_active: cci_i2c_scl0_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio58";
+			function = "cci_i2c_scl0";
+		};
+
+		config {
+			pins = "gpio58";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl0_suspend: cci_i2c_scl0_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio58";
+			function = "cci_i2c_scl0";
+		};
+
+		config {
+			pins = "gpio58";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda1_active: cci_i2c_sda1_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio29";
+			function = "cci_i2c_sda1";
+		};
+
+		config {
+			pins = "gpio29";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda1_suspend: cci_i2c_sda1_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio29";
+			function = "cci_i2c_sda1";
+		};
+
+		config {
+			pins = "gpio29";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl1_active: cci_i2c_scl1_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio30";
+			function = "cci_i2c_scl1";
+		};
+
+		config {
+			pins = "gpio30";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl1_suspend: cci_i2c_scl1_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio30";
+			function = "cci_i2c_scl1";
+		};
+
+		config {
+			pins = "gpio30";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda2_active: cci_i2c_sda2_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio59";
+			function = "cci_i2c_sda2";
+		};
+
+		config {
+			pins = "gpio59";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda2_suspend: cci_i2c_sda2_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio59";
+			function = "cci_i2c_sda2";
+		};
+
+		config {
+			pins = "gpio59";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl2_active: cci_i2c_scl2_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio60";
+			function = "cci_i2c_scl2";
+		};
+
+		config {
+			pins = "gpio60";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl2_suspend: cci_i2c_scl2_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio60";
+			function = "cci_i2c_scl2";
+		};
+
+		config {
+			pins = "gpio60";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda3_active: cci_i2c_sda3_active {
+		mux {
+			pins = "gpio31";
+			function = "cci_i2c_sda3";
+		};
+
+		config {
+			pins = "gpio31";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda3_suspend: cci_i2c_sda3_suspend {
+		mux {
+			pins = "gpio31";
+			function = "cci_i2c_sda3";
+		};
+
+		config {
+			pins = "gpio31";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl3_active: cci_i2c_scl3_active {
+		mux {
+			pins = "gpio32";
+			function = "cci_i2c_scl3";
+		};
+
+		config {
+			pins = "gpio32";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl3_suspend: cci_i2c_scl3_suspend {
+		mux {
+			pins = "gpio32";
+			function = "cci_i2c_scl3";
+		};
+
+		config {
+			pins = "gpio32";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda4_active: cci_i2c_sda4_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio61";
+			function = "cci_i2c_sda4";
+		};
+
+		config {
+			pins = "gpio61";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda4_suspend: cci_i2c_sda4_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio61";
+			function = "cci_i2c_sda4";
+		};
+
+		config {
+			pins = "gpio61";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl4_active: cci_i2c_scl4_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio62";
+			function = "cci_i2c_scl4";
+		};
+
+		config {
+			pins = "gpio62";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl4_suspend: cci_i2c_scl4_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio62";
+			function = "cci_i2c_scl4";
+		};
+
+		config {
+			pins = "gpio62";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda5_active: cci_i2c_sda5_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio54";
+			function = "cci_i2c_sda5";
+		};
+
+		config {
+			pins = "gpio54";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda5_suspend: cci_i2c_sda5_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio54";
+			function = "cci_i2c_sda5";
+		};
+
+		config {
+			pins = "gpio54";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl5_active: cci_i2c_scl5_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio55";
+			function = "cci_i2c_scl5";
+		};
+
+		config {
+			pins = "gpio55";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl5_suspend: cci_i2c_scl5_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio55";
+			function = "cci_i2c_scl5";
+		};
+
+		config {
+			pins = "gpio55";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk0_active: cam_sensor_mclk0_active {
+		/* MCLK0 */
+		mux {
+			pins = "gpio67";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio67";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk0_suspend: cam_sensor_mclk0_suspend {
+		/* MCLK0 */
+		mux {
+			pins = "gpio67";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio67";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk1_active: cam_sensor_mclk1_active {
+		/* MCLK1 */
+		mux {
+			pins = "gpio68";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio68";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk1_suspend: cam_sensor_mclk1_suspend {
+		/* MCLK1 */
+		mux {
+			pins = "gpio68";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio68";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk2_active: cam_sensor_mclk2_active {
+		/* MCLK2 */
+		mux {
+			pins = "gpio69";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio69";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk2_suspend: cam_sensor_mclk2_suspend {
+		/* MCLK2 */
+		mux {
+			pins = "gpio69";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio69";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+	cam_sensor_active_rst0: cam_sensor_active_rst0 {
+		/* RESET */
+		mux {
+			pins = "gpio73";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio73";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst0: cam_sensor_suspend_rst0 {
+		/* RESET */
+		mux {
+			pins = "gpio73";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio73";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_rst1: cam_sensor_active_rst1 {
+		/* RESET */
+		mux {
+			pins = "gpio74";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio74";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst1: cam_sensor_suspend_rst1 {
+		/* RESET */
+		mux {
+			pins = "gpio74";
+			function = "gpio";
+		};
+		config {
+			pins = "gpio74";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_rst2: cam_sensor_active_rst2 {
+		/* RESET */
+		mux {
+			pins = "gpio75";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio75";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst2: cam_sensor_suspend_rst2 {
+		/* RESET */
+		mux {
+			pins = "gpio75";
+			function = "gpio";
+		};
+		config {
+			pins = "gpio75";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+};
+
+&soc {
+	qcom,cam-req-mgr {
+		compatible = "qcom,cam-req-mgr";
+		status = "ok";
+	};
+
+	qcom,cam-sync {
+		compatible = "qcom,cam-sync";
+		status = "ok";
+	};
+
+	qcom,cam-i3c-id-table {
+		i3c-sensor-id-table = <0x1B0 0x0766>;
+		i3c-eeprom-id-table = <>;
+		i3c-actuator-id-table = <>;
+		i3c-ois-id-table = <>;
+		status = "disabled";
+	};
+
+	cam_csiphy_tpg13: qcom,tpg13@acac000 {
+		cell-index = <13>;
+		phy-id = <0>;
+		compatible = "qcom,cam-tpg1031";
+		reg-names = "tpg0", "cam_cpas_top";
+		reg = <0x0 0xacac000 0x0 0x400>,
+			<0x0 0xac11000 0x0 0x1000>;
+		reg-cam-base = <0xac000 0x11000>;
+		operating-points-v2 = <&csiphy_tpg0_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		interrupt-names = "tpg0";
+		interrupts = <GIC_SPI 545 IRQ_TYPE_EDGE_RISING>;
+		shared-clks = <1 0>;
+		clock-names =
+			"cphy_rx_clk_src",
+			"csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cphy_rx_clk_src";
+		status = "ok";
+		csiphy_tpg0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy_tpg14: qcom,tpg14@acad000 {
+		cell-index = <14>;
+		phy-id = <1>;
+		compatible = "qcom,cam-tpg1031";
+		reg-names = "tpg1", "cam_cpas_top";
+		reg = <0x0 0xacad000 0x0 0x400>,
+			<0x0 0xac11000 0x0 0x1000>;
+		reg-cam-base = <0xad000 0x11000>;
+		operating-points-v2 = <&csiphy_tpg1_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		interrupt-names = "tpg1";
+		interrupts = <GIC_SPI 546 IRQ_TYPE_EDGE_RISING>;
+		shared-clks = <1 0>;
+		clock-names =
+			"cphy_rx_clk_src",
+			"csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cphy_rx_clk_src";
+		status = "ok";
+		csiphy_tpg1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy_tpg15: qcom,tpg15@acae000 {
+		cell-index = <15>;
+		phy-id = <2>;
+		compatible = "qcom,cam-tpg1031";
+		reg-names = "tpg2", "cam_cpas_top";
+		reg = <0x0 0xacae000 0x0 0x400>,
+			<0x0 0xac11000 0x0 0x1000>;
+		reg-cam-base = <0xae000 0x11000>;
+		operating-points-v2 = <&csiphy_tpg2_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		interrupt-names = "tpg2";
+		interrupts = <GIC_SPI 547 IRQ_TYPE_EDGE_RISING>;
+		shared-clks = <1 0>;
+		clock-names =
+			"cphy_rx_clk_src",
+			"csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cphy_rx_clk_src";
+		status = "ok";
+		csiphy_tpg2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy0: qcom,csiphy0@ac9c000 {
+		cell-index = <0>;
+		aggregator-rx;
+		compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy";
+		reg = <0x0 0x0ac9c000 0x0 0x2000>;
+		reg-names = "csiphy";
+		operating-points-v2 = <&csiphy0_opp_table>;
+		reg-cam-base = <0x9c000>;
+		interrupt-names = "CSIPHY0";
+		interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>;
+		csi-vdd-1p2-supply = <&vreg_l5a>;
+		csi-vdd-0p9-supply = <&vreg_l4a>;
+		regulator-names = "csi-vdd-1p2", "csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1200000 880000>;
+		rgltr-max-voltage = <1200000 912000>;
+		rgltr-load-current = <8900 15900>;
+		shared-clks = <1 0 0 0>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy0_clk",
+			"csi0phytimer_clk_src",
+			"csi0phytimer_clk";
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY0_CLK>,
+			<&camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI0PHYTIMER_CLK>;
+		src-clock-name = "cphy_rx_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates =
+			<400000000 0 400000000 0>;
+		status = "ok";
+		csiphy0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy1: qcom,csiphy1@ac9e000 {
+		cell-index = <1>;
+		aggregator-rx;
+		compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy";
+		reg = <0x0 0xac9e000 0x0 0x2000>;
+		reg-names = "csiphy";
+		operating-points-v2 = <&csiphy1_opp_table>;
+		reg-cam-base = <0x9e000>;
+		interrupt-names = "CSIPHY1";
+		interrupts = <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>;
+		csi-vdd-1p2-supply = <&vreg_l5a>;
+		csi-vdd-0p9-supply = <&vreg_l4a>;
+		regulator-names = "csi-vdd-1p2", "csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1200000 880000>;
+		rgltr-max-voltage = <1200000 912000>;
+		rgltr-load-current = <8900 15900>;
+		shared-clks = <1 0 0 0>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy1_clk",
+			"csi1phytimer_clk_src",
+			"csi1phytimer_clk";
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY1_CLK>,
+			<&camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI1PHYTIMER_CLK>;
+		src-clock-name = "cphy_rx_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates =
+			<400000000 0 400000000 0>;
+		status = "ok";
+		csiphy1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy2: qcom,csiphy2@aca0000 {
+		cell-index = <2>;
+		aggregator-rx;
+		compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy";
+		reg = <0x0 0xaca0000 0x0 0x2000>;
+		reg-names = "csiphy";
+		operating-points-v2 = <&csiphy2_opp_table>;
+		reg-cam-base = <0xa0000>;
+		interrupt-names = "CSIPHY2";
+		interrupts = <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>;
+		csi-vdd-1p2-supply = <&vreg_l5a>;
+		csi-vdd-0p9-supply = <&vreg_l4a>;
+		regulator-names = "csi-vdd-1p2", "csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1200000 880000>;
+		rgltr-max-voltage = <1200000 912000>;
+		rgltr-load-current = <8900 15900>;
+		shared-clks = <1 0 0 0>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy2_clk",
+			"csi2phytimer_clk_src",
+			"csi2phytimer_clk";
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY2_CLK>,
+			<&camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI2PHYTIMER_CLK>;
+		src-clock-name = "cphy_rx_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates =
+			<400000000 0 400000000 0>;
+		status = "ok";
+		csiphy2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_cci0: qcom,cci0@ac13000 {
+		cell-index = <0>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac13000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x13000>;
+		interrupt-names = "CCI0";
+		interrupts = <GIC_SPI 460 IRQ_TYPE_EDGE_RISING>;
+		operating-points-v2 = <&cci0_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cci_0_clk_src",
+			"cci_0_clk";
+		clocks = <&camcc CAM_CC_CCI_0_CLK_SRC>,
+			<&camcc CAM_CC_CCI_0_CLK>;
+		clock-rates = <37500000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cci_0_clk_src";
+		pctrl-idx-mapping = <CCI_MASTER_0 CCI_MASTER_1>;
+		pctrl-map-names = "m0", "m1";
+		pinctrl-names = "m0_active", "m0_suspend",
+			"m1_active", "m1_suspend";
+		pinctrl-0 = <&cci_i2c_scl0_active &cci_i2c_sda0_active>;
+		pinctrl-1 = <&cci_i2c_scl0_suspend &cci_i2c_sda0_suspend>;
+		pinctrl-2 = <&cci_i2c_scl1_active &cci_i2c_sda1_active>;
+		pinctrl-3 = <&cci_i2c_scl1_suspend &cci_i2c_sda1_suspend>;
+		status = "ok";
+		cci0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci0: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci0: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci0: qcom,i2c_custom_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci0: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	cam_cci1: qcom,cci1@ac14000 {
+		cell-index = <1>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac14000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x14000>;
+		interrupt-names = "CCI1";
+		interrupts = <GIC_SPI 271 IRQ_TYPE_EDGE_RISING>;
+		operating-points-v2 = <&cci1_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cci_1_clk_src",
+			"cci_1_clk";
+		clocks = <&camcc CAM_CC_CCI_1_CLK_SRC>,
+			<&camcc CAM_CC_CCI_1_CLK>;
+		clock-rates = <37500000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cci_1_clk_src";
+		pctrl-idx-mapping = <CCI_MASTER_0 CCI_MASTER_1>;
+		pctrl-map-names = "m0", "m1";
+		pinctrl-names = "m0_active", "m0_suspend",
+			"m1_active", "m1_suspend";
+		pinctrl-0 = <&cci_i2c_scl2_active &cci_i2c_sda2_active>;
+		pinctrl-1 = <&cci_i2c_scl2_suspend &cci_i2c_sda2_suspend>;
+		pinctrl-2 = <&cci_i2c_scl3_active &cci_i2c_sda3_active>;
+		pinctrl-3 = <&cci_i2c_scl3_suspend &cci_i2c_sda3_suspend>;
+		status = "ok";
+		cci1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci1: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci1: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci1: qcom,i2c_custom_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci1: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	cam_cci2: qcom,cci2@ac15000 {
+		cell-index = <2>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac15000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x15000>;
+		interrupt-names = "CCI2";
+		interrupts = <GIC_SPI 651 IRQ_TYPE_EDGE_RISING>;
+		operating-points-v2 = <&cci2_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cci_2_clk_src",
+			"cci_2_clk";
+		clocks = <&camcc CAM_CC_CCI_2_CLK_SRC>,
+			<&camcc CAM_CC_CCI_2_CLK>;
+		clock-rates = <37500000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cci_2_clk_src";
+		pctrl-idx-mapping = <CCI_MASTER_0 CCI_MASTER_1>;
+		pctrl-map-names = "m0", "m1";
+		pinctrl-names = "m0_active", "m0_suspend",
+			"m1_active", "m1_suspend";
+		pinctrl-0 = <&cci_i2c_scl4_active &cci_i2c_sda4_active>;
+		pinctrl-1 = <&cci_i2c_scl4_suspend &cci_i2c_sda4_suspend>;
+		pinctrl-2 = <&cci_i2c_scl5_active &cci_i2c_sda5_active>;
+		pinctrl-3 = <&cci_i2c_scl5_suspend &cci_i2c_sda5_suspend>;
+		status = "ok";
+		cci2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci2: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci2: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci2: qcom,i2c_custom_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci2: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	qcom,cam_smmu {
+		compatible = "qcom,msm-cam-smmu", "simple-bus";
+		status = "ok";
+		force_cache_allocs;
+
+		msm_cam_smmu_ife {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x2400 0x0020>,
+				<&apps_smmu 0x2420 0x0020>;
+			cam-smmu-label = "ife", "sfe";
+			multiple-client-devices;
+			dma-coherent;
+			ife_iova_mem_map: iova-mem-map {
+				/* IO region is approximately 64 GB */
+				iova-mem-region-io {
+					iova-region-name = "io";
+					/* start address: 0x100000 */
+					/* leaving 1 MB pad at start  */
+					iova-region-start = <0x100000>;
+					/* Length: 0xfffe00000 */
+					/* leaving 1 MB pad at end */
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_icp {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus =
+				<&apps_smmu 0x0800 0x400>,
+				<&apps_smmu 0x0840 0x480>,
+				<&apps_smmu 0x08C0 0x480>,
+				<&apps_smmu 0x0C00 0x400>,
+				<&apps_smmu 0x0C40 0x480>,
+				<&apps_smmu 0x0CC0 0x480>;
+			cam-smmu-label = "icp";
+			qcom,iommu-faults = "stall-disable", "non-fatal";
+			dma-coherent;
+			icp_iova_mem_map: iova-mem-map {
+				iova-mem-region-shared {
+					/* Shared region is ~250MB long */
+					iova-region-name = "shared";
+					iova-region-start = <0x800000>;
+					iova-region-len = <0xfc00000>;
+					iova-region-id = <0x1>;
+					status = "ok";
+				};
+
+				iova-mem-region-fwuncached-region {
+					/* FW uncached region is 7MB long */
+					iova-region-name = "fw_uncached";
+					iova-region-start = <0x10400000>;
+					iova-region-len = <0x700000>;
+					iova-region-id = <0x6>;
+					subregion_support;
+					status = "ok";
+					/* Used for HFI queues/sec heap */
+					iova-mem-region-generic-region {
+						iova-region-name = "icp_hfi";
+						iova-region-start = <0x10400000>;
+						iova-region-len = <0x200000>;
+						iova-region-id = <0x0>;
+					};
+				};
+
+				iova-mem-region-io {
+					/* IO region is approximately 3.8 GB */
+					iova-region-name = "io";
+					iova-region-start = <0x10c00000>;
+					iova-region-len = <0xee300000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+
+				iova-mem-qdss-region {
+					/* QDSS region is appropriate 1MB */
+					iova-region-name = "qdss";
+					iova-region-start = <0x10b00000>;
+					iova-region-len = <0x100000>;
+					iova-region-id = <0x5>;
+					qdss-phy-addr = <0x16790000>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_cdm {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x0860 0x400>,
+				<&apps_smmu 0x0C60 0x400>;
+			cam-smmu-label = "rt-cdm";
+			dma-coherent;
+			multiple-client-devices;
+			rt_cdm_iova_mem_map: iova-mem-map {
+				iova-mem-region-io {
+					/* IO region is approximately 4.0 GB */
+					iova-region-name = "io";
+					/* 1 MB pad for start */
+					iova-region-start = <0x100000>;
+					/* 1 MB pad for end */
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_secure {
+			compatible = "qcom,msm-cam-smmu-cb";
+			cam-smmu-label = "cam-secure";
+			qcom,secure-cb;
+		};
+	};
+
+	qcom,cam-cdm-intf {
+		compatible = "qcom,cam-cdm-intf";
+		cell-index = <0>;
+		label = "cam-cdm-intf";
+		num-hw-cdm = <1>;
+		cdm-client-names = "vfe";
+		status = "ok";
+	};
+
+	qcom,rt-cdm0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac26000 0x0 0x1000>;
+		reg-names = "rt-cdm0";
+		reg-cam-base = <0x26000>;
+		interrupts = <GIC_SPI 543 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm0";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_fast_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_fast_ahb_clk_src";
+		clock-rates = <300000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table0>;
+		clock-cntl-level = "svs";
+		cdm-client-names = "ife0", "dualife0";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table0: opp-table {
+			compatible = "operating-points-v2";
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,rt-cdm1 {
+		cell-index = <1>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac27000 0x0 0x1000>;
+		reg-names = "rt-cdm1";
+		reg-cam-base = <0x27000>;
+		interrupts = <GIC_SPI 544 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm1";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_fast_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_fast_ahb_clk_src";
+		clock-rates = <300000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table1>;
+		clock-cntl-level = "svs_l1";
+		cdm-client-names = "ife1", "dualife1";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table1: opp-table {
+			compatible = "operating-points-v2";
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,rt-cdm2 {
+		cell-index = <2>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac28000 0x0 0x1000>;
+		reg-names = "rt-cdm2";
+		reg-cam-base = <0x28000>;
+		interrupts = <GIC_SPI 567 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm2";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_slow_ahb_clk_src";
+		clock-rates = <80000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table2>;
+		clock-cntl-level = "svs_l1";
+		cdm-client-names = "ife2", "ife3", "ife4", "ife5", "ife6";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table2: opp-table {
+			compatible = "operating-points-v2";
+			opp-80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,rt-cdm3 {
+		cell-index = <3>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac29000 0x0 0x1000>;
+		reg-names = "rt-cdm3";
+		reg-cam-base = <0x29000>;
+		interrupts = <GIC_SPI 566 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm3";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_slow_ahb_clk_src";
+		clock-rates = <80000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table3>;
+		clock-cntl-level = "svs";
+		cdm-client-names = "ife2", "ife3", "ife4", "ife5", "ife6";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table3: opp-table {
+			compatible = "operating-points-v2";
+			opp-80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,cam-isp {
+		compatible = "qcom,cam-isp";
+		arch-compat = "ife";
+		status = "ok";
+	};
+
+	cam_csid0: qcom,csid0 {
+		cell-index = <0>;
+		compatible = "qcom,csid692";
+		reg-names = "csid0", "csid_top";
+		reg = <0x0 0xac7a000 0x0 0xf01>,
+			<0x0 0xac78000 0x0 0x1000>;
+		reg-cam-base = <0x7a000 0x78000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "csid0";
+		interrupts = <GIC_SPI 565 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_csid_clk_src",
+			"cam_cc_csid_clk",
+			"cam_cc_csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CSID_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CLK>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0 0>;
+		clock-cntl-level = "svs_l1";
+		src-clock-name = "cam_cc_csid_clk_src";
+		operating-points-v2 = <&csid0_opp_table>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+		};
+	};
+
+	cam_vfe0: qcom,ife0 {
+		cell-index = <0>;
+		compatible = "qcom,vfe692";
+		reg-names = "ife0", "cam_camnoc";
+		reg = <0x0 0xac4d000 0x0 0xf000>,
+			<0x0 0xac1a000 0x0 0x9400>;
+		reg-cam-base = <0x4d000 0x1a000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "ife0";
+		interrupts = <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_0_clk",
+			"cam_cc_ife_0_clk",
+			"cam_cc_ife_0_clk_src",
+			"cam_cc_ife_0_fast_ahb_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_0_CLK>,
+			<&camcc CAM_CC_IFE_0_CLK>,
+			<&camcc CAM_CC_IFE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_0_FAST_AHB_CLK>;
+		clock-rates =
+			<0 0 480000000 0>,
+			<0 0 600000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_0_clk_src";
+		operating-points-v2 = <&vfe0_opp_table>;
+		clock-control-debugfs = "true";
+		ubwc-static-cfg = <0x1026 0x1036>;
+		cam_hw_pid = <8 16>;
+		status = "ok";
+		vfe0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid1: qcom,csid1 {
+		cell-index = <1>;
+		compatible = "qcom,csid692";
+		reg-names = "csid1", "csid_top";
+		reg = <0x0 0xac7c000 0x0 0xf01>,
+			<0x0 0xac78000 0x0 0x1000>;
+		reg-cam-base = <0x7c000 0x78000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "csid1";
+		interrupts = <GIC_SPI 564 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_csid_clk_src",
+			"cam_cc_csid_clk",
+			"cam_cc_csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CSID_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CLK>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0 0>;
+		clock-cntl-level = "svs_l1";
+		src-clock-name = "cam_cc_csid_clk_src";
+		operating-points-v2 = <&csid1_opp_table>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+		};
+	};
+
+	cam_vfe1: qcom,ife1 {
+		cell-index = <1>;
+		compatible = "qcom,vfe692";
+		reg-names = "ife1", "cam_camnoc";
+		reg = <0x0 0xac60000 0x0 0xf000>,
+			<0x0 0xac1a000 0x0 0x9400>;
+		reg-cam-base = <0x60000 0x1a000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "ife1";
+		interrupts = <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_1_clk",
+			"cam_cc_ife_1_clk",
+			"cam_cc_ife_1_clk_src",
+			"cam_cc_ife_1_fast_ahb_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_1_CLK>,
+			<&camcc CAM_CC_IFE_1_CLK>,
+			<&camcc CAM_CC_IFE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_1_FAST_AHB_CLK>;
+		clock-rates =
+			<0 0 480000000 0>,
+			<0 0 600000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_1_clk_src";
+		operating-points-v2 = <&vfe1_opp_table>;
+		clock-control-debugfs = "true";
+		ubwc-static-cfg = <0x1026 0x1036>;
+		cam_hw_pid = <9 17>;
+		status = "ok";
+		vfe1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite0: qcom,csid-lite0 {
+		cell-index = <2>;
+		compatible = "qcom,csid-lite692";
+		reg-names = "csid-lite0";
+		reg = <0x0 0xac84000 0x0 0xf01>;
+		reg-cam-base = <0x84000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite0";
+		interrupts = <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite0_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite0: qcom,ife-lite0 {
+		cell-index = <2>;
+		compatible = "qcom,vfe-lite692";
+		reg-names = "ife-lite0";
+		reg = <0x0 0xac84000 0x0 0x1d00>;
+		reg-cam-base = <0x84000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite0";
+		interrupts = <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite0_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite1: qcom,csid-lite1 {
+		cell-index = <3>;
+		compatible = "qcom,csid-lite692";
+		reg-names = "csid-lite1";
+		reg = <0x0 0xac88000 0x0 0xf01>;
+		reg-cam-base = <0x88000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite1";
+		interrupts = <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite1_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite1: qcom,ife-lite1 {
+		cell-index = <3>;
+		compatible = "qcom,vfe-lite692";
+		reg-names = "ife-lite1";
+		reg = <0x0 0xac88000 0x0 0x1d00>;
+		reg-cam-base = <0x88000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite1";
+		interrupts = <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite1_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite2: qcom,csid-lite2 {
+		cell-index = <4>;
+		compatible = "qcom,csid-lite692";
+		reg-names = "csid-lite2";
+		reg = <0x0 0xac8c000 0x0 0xf01>;
+		reg-cam-base = <0x8c000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite2";
+		interrupts = <GIC_SPI 759 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite2_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite2: qcom,ife-lite2 {
+		cell-index = <4>;
+		compatible = "qcom,vfe-lite692";
+		reg-names = "ife-lite2";
+		reg = <0x0 0xac8c000 0x0 0x1d00>;
+		reg-cam-base = <0x8c000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite2";
+		interrupts = <GIC_SPI 761 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite2_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite3: qcom,csid-lite3 {
+		cell-index = <5>;
+		compatible = "qcom,csid-lite692";
+		reg-names = "csid-lite3";
+		reg = <0x0 0xac90000 0x0 0xf01>;
+		reg-cam-base = <0x90000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite3";
+		interrupts = <GIC_SPI 758 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite3_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite3: qcom,ife-lite3 {
+		cell-index = <5>;
+		compatible = "qcom,vfe-lite692";
+		reg-names = "ife-lite3";
+		reg = <0x0 0xac90000 0x0 0x1d00>;
+		reg-cam-base = <0x90000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite3";
+		interrupts = <GIC_SPI 760 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite3_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite4: qcom,csid-lite4 {
+		cell-index = <6>;
+		compatible = "qcom,csid-lite692";
+		reg-names = "csid-lite4";
+		reg = <0x0 0xac94000 0x0 0xf01>;
+		reg-cam-base = <0x94000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite4";
+		interrupts = <GIC_SPI 604 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite4_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite4_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite4: qcom,ife-lite4 {
+		cell-index = <6>;
+		compatible = "qcom,vfe-lite692";
+		reg-names = "ife-lite4";
+		reg = <0x0 0xac94000 0x0 0x1d00>;
+		reg-cam-base = <0x94000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite4";
+		interrupts = <GIC_SPI 605 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite4_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite4_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_sfe_lite0: qcom,sfe-lite0 {
+		cell-index = <0>;
+		compatible = "qcom,sfe-lite692";
+		reg-names = "sfe-lite0";
+		reg = <0x0 0xac74000 0x0 0x1000>;
+		reg-cam-base = <0x74000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "sfe-lite0";
+		interrupts = <GIC_SPI 563 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_sfe_lite_0_fast_ahb_clk",
+			"cam_cc_sfe_lite_0_clk",
+			"cam_cc_cpas_sfe_lite_0_clk";
+		clocks =
+			<&camcc CAM_CC_SFE_LITE_0_FAST_AHB_CLK>,
+			<&camcc CAM_CC_SFE_LITE_0_CLK>,
+			<&camcc CAM_CC_CPAS_SFE_LITE_0_CLK>;
+		clock-rates =
+			<0 480000000 300000000>,
+			<0 600000000 400000000>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_sfe_lite_0_clk";
+		operating-points-v2 = <&cam_sfe_lite_opp_table0>;
+		cam_hw_pid = <4>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		cam_sfe_lite_opp_table0: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_sfe_lite1: qcom,sfe-lite1 {
+		cell-index = <1>;
+		compatible = "qcom,sfe-lite692";
+		reg-names = "sfe-lite1";
+		reg = <0x0 0xac75000 0x0 0x1000>;
+		reg-cam-base = <0x75000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "sfe-lite1";
+		interrupts = <GIC_SPI 562 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_sfe_lite_1_fast_ahb_clk",
+			"cam_cc_sfe_lite_1_clk",
+			"cam_cc_cpas_sfe_1_clk";
+		clocks =
+			<&camcc CAM_CC_SFE_LITE_1_FAST_AHB_CLK>,
+			<&camcc CAM_CC_SFE_LITE_1_CLK>,
+			<&camcc CAM_CC_CPAS_SFE_LITE_1_CLK>;
+		clock-rates =
+			<0 480000000 300000000>,
+			<0 600000000 400000000>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_sfe_lite_1_clk";
+		operating-points-v2 = <&cam_sfe_lite_opp_table1>;
+		cam_hw_pid = <5>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		cam_sfe_lite_opp_table1: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-icp {
+		compatible = "qcom,cam-icp";
+		compat-hw-name = "qcom,icp",
+			"qcom,ipe0";
+		num-icp = <1>;
+		num-ipe = <1>;
+		icp_use_pil;
+		status = "ok";
+	};
+
+	cam_icp: qcom,icp {
+		cell-index = <0>;
+		compatible = "qcom,cam-icp_v3_0";
+		icp-version = <0x0300>;
+
+		reg-names ="icp_csr", "icp_cirq", "icp_wd0";
+		reg = <0x0 0xac01000 0x0 0x400>,
+			<0x0 0xac01800 0x0 0x400>,
+			<0x0 0xac04000 0x0 0x1000>;
+		reg-cam-base = <0x1000 0x1800 0x4000>;
+		interrupt-names = "icp";
+		interrupts = <GIC_SPI 463 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		memory-region = <&camera_mem>;
+		clock-names =
+			"cam_cc_soc_fast_ahb_clk_src",
+			"cam_cc_icp_ahb_clk",
+			"cam_cc_icp_clk_src",
+			"cam_cc_icp_clk";
+		src-clock-name = "cam_cc_icp_clk_src";
+		clocks =
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_ICP_AHB_CLK>,
+			<&camcc CAM_CC_ICP_CLK_SRC>,
+			<&camcc CAM_CC_ICP_CLK>;
+		clock-rates =
+			<300000000 0 480000000 0>,
+			<400000000 0 600000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		nrt-device;
+		fw_name = "CAMERA_ICP";
+		ubwc-ipe-fetch-cfg = <0x707b 0x7083>;
+		ubwc-ipe-write-cfg = <0x161ef 0x1620f>;
+		qos-val = <0xa0a>;
+		operating-points-v2 = <&icp_opp_table>;
+		cam_hw_pid = <12>;
+		status = "ok";
+		icp_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_ipe0: qcom,ipe0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-ipe";
+		reg-names = "ipe0_top";
+		reg = <0x0 0xac2d000 0x0 0x18000>;
+		reg-cam-base = <0x2d000>;
+
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+
+		clock-names =
+			"cam_cc_cpas_ipe_clk",
+			"cam_cc_ipe_ahb_clk",
+			"cam_cc_ipe_clk",
+			"cam_cc_ipe_clk_src",
+			"cam_cc_ipe_fast_ahb_clk",
+			"cam_cc_fast_ahb_clk_src";
+		src-clock-name = "cam_cc_ipe_clk_src";
+		clocks =
+			<&camcc CAM_CC_CPAS_IPE_CLK>,
+			<&camcc CAM_CC_IPE_AHB_CLK>,
+			<&camcc CAM_CC_IPE_CLK>,
+			<&camcc CAM_CC_IPE_CLK_SRC>,
+			<&camcc CAM_CC_IPE_FAST_AHB_CLK>,
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>;
+		clock-rates =
+			<0 0 0 480000000 0 300000000>,
+			<0 0 0 600000000 0 400000000>;
+		clock-cntl-level = "svs_l1", "nominal";
+
+		operating-points-v2 = <&ipe0_opp_table>;
+		nrt-device;
+		cam_hw_pid = <14 15>;
+		status = "ok";
+
+		ipe0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+
+	};
+
+	qcom,cam-cpas {
+		cell-index = <0>;
+		compatible = "qcom,cam-cpas";
+		label = "cpas";
+		arch-compat = "cpas_top";
+		reg-names = "cam_cpas_top", "cam_camnoc", "cam_rpmh";
+		reg = <0x0 0xac11000 0x0 0x1000>,
+			<0x0 0xac1A000 0x0 0x9400>,
+			<0x0 0xbbf0000 0x0 0x1f00>;
+		reg-cam-base = <0x11000 0x1A000 0x0bbf0000>;
+		interrupt-names = "cpas_camnoc";
+		interrupts = <GIC_SPI 459 IRQ_TYPE_EDGE_RISING>;
+		camnoc-axi-min-ib-bw = <3000000000>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"gcc_camera_ahb_clk",
+			"gcc_camera_hf_axi_clk",
+			"gcc_camera_sf_axi_clk",
+			"cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk",
+			"cam_cc_core_ahb_clk",
+			"cam_cc_fast_ahb_clk_src",
+			"cam_cc_cpas_fast_ahb_clk",
+			"cam_cc_camnoc_axi_clk_src",
+			"cam_cc_camnoc_axi_clk",
+			"cam_cc_qdss_debug_xo_clk";
+		clocks =
+			<&gcc GCC_CAMERA_AHB_CLK>,
+			<&gcc GCC_CAMERA_HF_AXI_CLK>,
+			<&gcc GCC_CAMERA_SF_AXI_CLK>,
+			<&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>,
+			<&camcc CAM_CC_CORE_AHB_CLK>,
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_FAST_AHB_CLK>,
+			<&camcc CAM_CC_CAMNOC_AXI_CLK_SRC>,
+			<&camcc CAM_CC_CAMNOC_AXI_CLK>,
+			<&camcc CAM_CC_QDSS_DEBUG_XO_CLK>;
+		src-clock-name = "cam_cc_fast_ahb_clk_src";
+		clock-rates =
+			<0 0 0 0 0 0 0 0 0 0 0>,
+			<0 0 0 80000000 0 0 300000000 0 400000000 0 0>,
+			<0 0 0 80000000 0 0 400000000 0 400000000 0 0>;
+		clock-cntl-level = "suspend", "svs_l1", "nominal";
+		clock-names-option = "cam_icp_clk";
+		clocks-option = <&camcc CAM_CC_ICP_CLK>;
+		clock-rates-option = <480000000>;
+		operating-points-v2 = <&cpas_opp_table>;
+		control-camnoc-axi-clk;
+		camnoc-bus-width = <32>;
+		camnoc-axi-clk-bw-margin-perc = <20>;
+		cam-icc-path-names = "cam_ahb";
+		interconnect-names = "cam_ahb", "cam_hf_0", "cam_sf_0", "cam_sf_icp";
+		interconnects =<&gem_noc MASTER_APPSS_PROC 0
+			&config_noc SLAVE_CAMERA_CFG 0>,
+				<&mmss_noc MASTER_CAMNOC_HF 0
+			&mc_virt SLAVE_EBI1 0>,
+				<&mmss_noc MASTER_CAMNOC_SF 0
+			&mc_virt SLAVE_EBI1 0>,
+				<&mmss_noc MASTER_CAMNOC_ICP 0
+			&mc_virt SLAVE_EBI1 0>;
+		cam-ahb-num-cases = <7>;
+		cam-ahb-bw-KBps =
+			<0 0>, <0 76800>, <0 150000>, <0 150000>,
+			<0 300000>, <0 300000>, <0 300000>;
+		vdd-corners = <RPMH_REGULATOR_LEVEL_RETENTION
+			RPMH_REGULATOR_LEVEL_MIN_SVS
+			RPMH_REGULATOR_LEVEL_LOW_SVS
+			RPMH_REGULATOR_LEVEL_SVS
+			RPMH_REGULATOR_LEVEL_SVS_L1
+			RPMH_REGULATOR_LEVEL_NOM
+			RPMH_REGULATOR_LEVEL_NOM_L1
+			RPMH_REGULATOR_LEVEL_NOM_L2
+			RPMH_REGULATOR_LEVEL_TURBO
+			RPMH_REGULATOR_LEVEL_TURBO_L1>;
+		vdd-corner-ahb-mapping = "suspend",
+			"lowsvs", "lowsvs", "svs", "svs_l1",
+			"nominal", "nominal", "nominal",
+			"turbo", "turbo";
+		client-id-based;
+		client-names =
+			"csiphy0", "csiphy1", "csiphy2",
+			"cci0", "cci1", "cci2",
+			"csid0", "csid1", "csid2", "csid3",
+			"csid4", "csid5", "csid6", "ife0",
+			"ife1",	"ife2", "ife3", "ife4",
+			"ife5",	"ife6", "ipe0", "sfe0", "sfe1",
+			"cam-cdm-intf0", "rt-cdm0", "rt-cdm1", "rt-cdm2",
+			"rt-cdm3", "icp0", "tpg13", "tpg14", "tpg15";
+
+		status = "ok";
+		enable-secure-qos-update;
+		cpas_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+
+		camera-bus-nodes {
+			level3-nodes {
+				level-index = <3>;
+				level3_rt_rd_wr_sum: level3-rt-rd-wr-sum {
+					cell-index = <0>;
+					node-name = "level3-rt-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					ib-bw-voting-needed;
+					qcom,axi-port-mnoc {
+						cam-icc-path-names = "cam_hf_0";
+					};
+				};
+
+				level3_nrt0_rd_wr_sum: level3-nrt0-rd-wr-sum {
+					cell-index = <1>;
+					node-name = "level3-nrt0-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					qcom,axi-port-mnoc {
+						cam-icc-path-names = "cam_sf_0";
+					};
+				};
+
+				level3_nrt1_rd_wr_sum: level3-nrt1-rd-wr-sum {
+					cell-index = <2>;
+					node-name = "level3-nrt1-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					qcom,axi-port-mnoc {
+						cam-icc-path-names = "cam_sf_icp";
+					};
+				};
+			};
+
+			level2-nodes {
+				level-index = <2>;
+				camnoc-max-needed;
+				level2_rt_wr0: level2-rt-wr0 {
+					cell-index = <3>;
+					node-name = "level2-rt-wr0";
+					parent-node = <&level3_rt_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_rt_wr1: level2-rt-wr1 {
+					cell-index = <4>;
+					node-name = "level2-rt-wr1";
+					parent-node = <&level3_rt_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt_wr2: level2-nrt-wr2 {
+					cell-index = <5>;
+					node-name = "level2-nrt-wr2";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_rt_rd0: level2-rt-read0 {
+					cell-index = <6>;
+					node-name = "level2-rt-rd0";
+					parent-node = <&level3_rt_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt_rd1: level2-nrt-rd1 {
+					cell-index = <7>;
+					node-name = "level2-nrt-rd1";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt_rd2: level2-nrt-rd2 {
+					cell-index = <8>;
+					node-name = "level2-nrt-rd2";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_icp_rd: level2-icp-rd {
+					cell-index = <9>;
+					node-name = "level2-icp-rd";
+					parent-node = <&level3_nrt1_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+			};
+
+			level1-nodes {
+				level-index = <1>;
+				camnoc-max-needed;
+				level1_rt_wr0: level1-rt-wr0 {
+					cell-index = <10>;
+					node-name = "level1-rt-wr0";
+					parent-node = <&level2_rt_wr0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_rt_wr1: level1-rt-wr1 {
+					cell-index = <11>;
+					node-name = "level1-rt-wr1";
+					parent-node = <&level2_rt_wr1>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_rt_rd0: level1-rt-read0 {
+					cell-index = <13>;
+					node-name = "level1-rt-rd0";
+					parent-node = <&level2_rt_rd0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt_rd2: level1-nrt-rd2 {
+					cell-index = <15>;
+					node-name = "level1-nrt-rd2";
+					parent-node = <&level2_nrt_rd2>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+			};
+
+			level0-nodes {
+				level-index = <0>;
+				ife_0_wr_0: ife-0-wr-0 {
+					cell-index = <16>;
+					node-name = "ife-0-wr-0";
+					client-name = "ife0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_1_wr_0: ife-1-wr-0 {
+					cell-index = <17>;
+					node-name = "ife-1-wr-0";
+					client-name = "ife1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_0_wr_0: ife-lite-0-wr-0 {
+					cell-index = <18>;
+					node-name = "ife-lite-0-wr-0";
+					client-name = "ife2";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_1_wr_0: ife-lite-1-wr-0 {
+					cell-index = <19>;
+					node-name = "ife-lite-1-wr-0";
+					client-name = "ife3";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_2_wr_0: ife-lite-2-wr-0 {
+					cell-index = <20>;
+					node-name = "ife-lite-2-wr-0";
+					client-name = "ife4";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_3_wr_0: ife-lite-3-wr-0 {
+					cell-index = <21>;
+					node-name = "ife-lite-3-wr-0";
+					client-name = "ife5";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_4_wr_0: ife-lite-4-wr-0 {
+					cell-index = <22>;
+					node-name = "ife-lite-4-wr-0";
+					client-name = "ife6";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_0_wr_1: ife-0-wr-1 {
+					cell-index = <23>;
+					node-name = "ife-0-wr-1";
+					client-name = "ife0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_UBWC>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_DISP>;
+					parent-node = <&level1_rt_wr1>;
+				};
+				ife_1_wr_1: ife-1-wr-1 {
+					cell-index = <24>;
+					node-name = "ife-1-wr-1";
+					client-name = "ife1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_UBWC>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_DISP>;
+					parent-node = <&level1_rt_wr1>;
+				};
+				sfe_0_rd_0: sfe-0-rd-0 {
+					cell-index = <25>;
+					node-name = "sfe-0-rd-0";
+					client-name = "sfe0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_SFE_NRDI>;
+					parent-node = <&level1_rt_rd0>;
+				};
+				sfe_1_rd_0: sfe-1-rd-0 {
+					cell-index = <26>;
+					node-name = "sfe-1-rd-0";
+					client-name = "sfe1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_SFE_NRDI>;
+					parent-node = <&level1_rt_rd0>;
+				};
+				ipe_0_wr_2: ipe-0-wr-2 {
+					cell-index = <27>;
+					node-name = "ipe-0-wr-2";
+					client-name = "ipe0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IPE_WR_VID
+					CAM_CPAS_PATH_DATA_IPE_WR_DISP
+					CAM_CPAS_PATH_DATA_IPE_WR_REF
+					CAM_CPAS_PATH_DATA_IPE_WR_APP>;
+					parent-node = <&level2_nrt_wr2>;
+				};
+				ipe_0_rd_all: ipe-0-rd-all {
+					cell-index = <28>;
+					node-name = "ipe-0-rd-all";
+					client-name = "ipe0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IPE_RD_IN
+					CAM_CPAS_PATH_DATA_IPE_RD_REF>;
+					parent-node = <&level2_nrt_rd1>;
+				};
+				rt_cdm0_all_rd_2: rt-cdm0-all-rd-2 {
+					cell-index = <29>;
+					node-name = "rt-cdm0-all-rd-2";
+					client-name = "rt-cdm0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				rt_cdm1_all_rd_2: rt-cdm1-all-rd-2 {
+					cell-index = <30>;
+					node-name = "rt-cdm1-all-rd-2";
+					client-name = "rt-cdm1";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				rt_cdm2_all_rd_2: rt-cdm2-all-rd-2 {
+					cell-index = <31>;
+					node-name = "rt-cdm2-all-rd-2";
+					client-name = "rt-cdm2";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				rt_cdm3_all_rd_2: rt-cdm3-all-rd-2 {
+					cell-index = <32>;
+					node-name = "rt-cdm3-all-rd-2";
+					client-name = "rt-cdm3";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				ipe_cdm0_all_rd: ipe-cdm0-all-rd {
+					cell-index = <33>;
+					node-name = "ipe-cdm0-all-rd";
+					client-name = "ipe0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				icp_all_rd: icp-all-rd {
+					cell-index = <34>;
+					node-name = "icp-all-rd";
+					client-name = "icp0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level2_icp_rd>;
+				};
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8275-camera-iq-8275-evk.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8275-camera-iq-8275-evk.dtso
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,qcs8300-gcc.h>
+#include <dt-bindings/clock/qcom,sa8775p-camcc.h>
+#include <dt-bindings/interconnect/qcom,qcs8300-rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+
+#include "qcs8275-camera-iq-8275-evk.dtsi"
+#include "qcs8275-camera-sensor-iq-8275-evk.dtsi"
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8275-camera-sensor-iq-8275-evk.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8275-camera-sensor-iq-8275-evk.dtsi
@@ -0,0 +1,482 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+#include <dt-bindings/msm-camera.h>
+
+&soc {
+	qcom,cam-res-mgr {
+		compatible = "qcom,cam-res-mgr";
+		status = "ok";
+		gpios-shared = <609 610 611>;
+	};
+};
+&expander2{
+         vcc-supply = <&vreg_s4a>;
+};
+
+&cam_cci0 {
+
+	/* GMSL deserializer 0 */
+	qcom,cam-gmsl-deserializer0 {
+		cell-index = <0>;
+		csiphy-sd-index = <0>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_active>;
+		pinctrl-1 = <&cam_sensor_mclk0_suspend>;
+		gpios = <&tlmm 73 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_RESET0";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+
+		port@0 {
+			reg = <0>;
+			deser0_port0: endpoint {
+				remote-endpoint = <&gmsl_sensor0_ep>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			deser0_port1: endpoint {
+				remote-endpoint = <&gmsl_sensor1_ep>;
+			};
+		};
+
+		port@2 {
+			reg = <0>;
+			deser0_port2: endpoint {
+				remote-endpoint = <&gmsl_sensor2_ep>;
+			};
+		};
+
+		port@3 {
+			reg = <1>;
+			deser0_port3: endpoint {
+				remote-endpoint = <&gmsl_sensor3_ep>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 0 */
+	qcom,cam-gmsl-sensor0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor0_ep: endpoint {
+				remote-endpoint = <&deser0_port0>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 1 */
+	qcom,cam-gmsl-sensor1 {
+		cell-index = <1>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor1_ep: endpoint {
+				remote-endpoint = <&deser0_port1>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 2 */
+	qcom,cam-gmsl-sensor2 {
+		cell-index = <2>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor2_ep: endpoint {
+				remote-endpoint = <&deser0_port2>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 3 */
+	qcom,cam-gmsl-sensor3 {
+		cell-index = <3>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor3_ep: endpoint {
+				remote-endpoint = <&deser0_port3>;
+			};
+		};
+	};
+
+	/*cam0-ov9282*/
+ 	qcom,cam-sensor16 {
+ 		cell-index = <16>;
+ 		compatible = "qcom,cam-sensor";
+ 		csiphy-sd-index = <0>;
+ 		sensor-position-roll = <0>;
+ 		sensor-position-pitch = <0>;
+ 		sensor-position-yaw = <180>;
+ 		cam_vio-supply = <&vreg_s4a>;
+ 		regulator-names = "cam_vio";
+ 		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+ 		rgltr-cntrl-support;
+ 		pwm-switch;
+ 		rgltr-min-voltage = <1800000>;
+ 		rgltr-max-voltage = <1800000>;
+ 		rgltr-load-current = <120000>;
+ 		gpio-no-mux = <0>;
+ 		pinctrl-names = "cam_default", "cam_suspend";
+ 		pinctrl-0 = <&cam_sensor_mclk0_active
+ 		                &cam_sensor_active_rst0>;
+ 		pinctrl-1 = <&cam_sensor_mclk0_suspend
+ 		                &cam_sensor_suspend_rst0>;
+ 		gpios = <&tlmm 67 0>,
+ 			<&tlmm 73 0>,
+			<&expander2 0 0>;
+ 		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+ 		gpio-req-tbl-num = <0 1 2>;
+ 		gpio-req-tbl-flags   	 = <1 0 0>;
+ 		gpio-req-tbl-label = "CAM_MCLK0",
+ 		                       "CAMIF_RESET0",
+				       "CAM_CUSTOM1";
+ 		cci-master = <0>;
+ 		clocks = <&camcc CAM_CC_MCLK0_CLK>;
+ 		clock-names = "cam_clk";
+ 		clock-cntl-level = "nominal";
+ 		clock-rates = <24000000>;
+ 		status = "ok";
+ 	};
+};
+
+
+&cam_cci1 {
+
+	/* GMSL deserializer 1 */
+	qcom,cam-gmsl-deserializer1 {
+		cell-index = <1>;
+		csiphy-sd-index = <1>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend>;
+		gpios = <&tlmm 74 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_RESET1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+
+		port@0 {
+			reg = <0>;
+			deser1_port0: endpoint {
+				remote-endpoint = <&gmsl_sensor4_ep>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			deser1_port1: endpoint {
+				remote-endpoint = <&gmsl_sensor5_ep>;
+			};
+		};
+
+		port@2 {
+			reg = <0>;
+			deser1_port2: endpoint {
+				remote-endpoint = <&gmsl_sensor6_ep>;
+			};
+		};
+
+		port@3 {
+			reg = <1>;
+			deser1_port3: endpoint {
+				remote-endpoint = <&gmsl_sensor7_ep>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 0 */
+	qcom,cam-gmsl-sensor4 {
+		cell-index = <4>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor4_ep: endpoint {
+				remote-endpoint = <&deser1_port0>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 1 */
+	qcom,cam-gmsl-sensor5 {
+		cell-index = <5>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor5_ep: endpoint {
+				remote-endpoint = <&deser1_port1>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 2 */
+	qcom,cam-gmsl-sensor6 {
+		cell-index = <6>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor6_ep: endpoint {
+				remote-endpoint = <&deser1_port2>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 3 */
+	qcom,cam-gmsl-sensor7 {
+		cell-index = <7>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor7_ep: endpoint {
+				remote-endpoint = <&deser1_port3>;
+			};
+		};
+	};
+	/*cam1-ov9282*/
+ 	qcom,cam-sensor17 {
+ 		cell-index = <17>;
+ 		compatible = "qcom,cam-sensor";
+ 		csiphy-sd-index = <1>;
+ 		sensor-position-roll = <0>;
+ 		sensor-position-pitch = <0>;
+ 		sensor-position-yaw = <180>;
+ 		cam_vio-supply = <&vreg_s4a>;
+ 		regulator-names = "cam_vio";
+ 		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+ 		rgltr-cntrl-support;
+ 		pwm-switch;
+ 		rgltr-min-voltage = <1800000>;
+ 		rgltr-max-voltage = <1800000>;
+ 		rgltr-load-current = <120000>;
+ 		gpio-no-mux = <0>;
+ 		pinctrl-names = "cam_default", "cam_suspend";
+ 		pinctrl-0 = <&cam_sensor_mclk1_active
+ 		                &cam_sensor_active_rst1>;
+ 		pinctrl-1 = <&cam_sensor_mclk1_suspend
+ 		                &cam_sensor_suspend_rst1>;
+ 		gpios = <&tlmm 68 0>,
+ 			<&tlmm 74 0>,
+			<&expander2 1 0>;
+ 		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+ 		gpio-req-tbl-num = <0 1 2>;
+ 		gpio-req-tbl-flags   	 = <1 0 0>;
+ 		gpio-req-tbl-label = "CAM_MCLK1",
+ 		                       "CAMIF_RESET1",
+				       "CAM_CUSTOM1";
+ 		cci-master = <0>;
+ 		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+ 		clock-names = "cam_clk";
+ 		clock-cntl-level = "nominal";
+ 		clock-rates = <24000000>;
+ 		status = "ok";
+ 	};
+};
+
+&cam_cci2 {
+
+	/* GMSL deserializer 2 */
+	qcom,cam-gmsl-deserializer2 {
+		cell-index = <2>;
+		csiphy-sd-index = <2>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_active>;
+		pinctrl-1 = <&cam_sensor_mclk2_suspend>;
+		gpios = <&tlmm 75 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_RESET2";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK2_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+
+		port@0 {
+			reg = <0>;
+			deser2_port0: endpoint {
+				remote-endpoint = <&gmsl_sensor8_ep>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			deser2_port1: endpoint {
+				remote-endpoint = <&gmsl_sensor9_ep>;
+			};
+		};
+
+		port@2 {
+			reg = <0>;
+			deser2_port2: endpoint {
+				remote-endpoint = <&gmsl_sensor10_ep>;
+			};
+		};
+
+		port@3 {
+			reg = <1>;
+			deser2_port3: endpoint {
+				remote-endpoint = <&gmsl_sensor11_ep>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 0 */
+	qcom,cam-gmsl-sensor8 {
+		cell-index = <8>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor8_ep: endpoint {
+				remote-endpoint = <&deser2_port0>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 1 */
+	qcom,cam-gmsl-sensor9 {
+		cell-index = <9>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor9_ep: endpoint {
+				remote-endpoint = <&deser2_port1>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 2 */
+	qcom,cam-gmsl-sensor10 {
+		cell-index = <10>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor10_ep: endpoint {
+				remote-endpoint = <&deser2_port2>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 3 */
+	qcom,cam-gmsl-sensor11 {
+		cell-index = <11>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor11_ep: endpoint {
+				remote-endpoint = <&deser2_port3>;
+			};
+		};
+	};
+	/*cam2-ov9282*/
+ 	qcom,cam-sensor18 {
+ 		cell-index = <18>;
+ 		compatible = "qcom,cam-sensor";
+ 		csiphy-sd-index = <2>;
+ 		sensor-position-roll = <0>;
+ 		sensor-position-pitch = <0>;
+ 		sensor-position-yaw = <180>;
+ 		cam_vio-supply = <&vreg_s4a>;
+ 		regulator-names = "cam_vio";
+ 		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+ 		rgltr-cntrl-support;
+ 		pwm-switch;
+ 		rgltr-min-voltage = <1800000>;
+ 		rgltr-max-voltage = <1800000>;
+ 		rgltr-load-current = <120000>;
+ 		gpio-no-mux = <0>;
+ 		pinctrl-names = "cam_default", "cam_suspend";
+ 		pinctrl-0 = <&cam_sensor_mclk2_active
+ 		                &cam_sensor_active_rst2>;
+ 		pinctrl-1 = <&cam_sensor_mclk2_suspend
+ 		                &cam_sensor_suspend_rst2>;
+ 		gpios = <&tlmm 69 0>,
+ 			<&tlmm 75 0>,
+			<&expander2 2 0>;
+ 		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+ 		gpio-req-tbl-num = <0 1 2>;
+ 		gpio-req-tbl-flags   	 = <1 0 0>;
+ 		gpio-req-tbl-label = "CAM_MCLK2",
+ 		                       "CAMIF_RESET2",
+				       "CAM_CUSTOM1";
+ 		cci-master = <0>;
+ 		clocks = <&camcc CAM_CC_MCLK2_CLK>;
+ 		clock-names = "cam_clk";
+ 		clock-cntl-level = "nominal";
+ 		clock-rates = <24000000>;
+ 		status = "ok";
+ 	};
+};
+
+
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8275-iq-8275-evk-pro-sku.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8275-iq-8275-evk-pro-sku.dts
@@ -0,0 +1,597 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/spmi/spmi.h>
+#include "qcs8300.dtsi"
+#include "qcs8300-pmics.dtsi"
+
+/delete-node/ &usb_1_dwc3;
+/delete-node/ &usb_2_dwc3;
+/ {
+	model = "Qualcomm Technologies, Inc. IQ8 8275 Pro SKU EVK";
+	compatible = "qcom,qcs8275-iq-8275-evk-pro-sku", "qcom,qcs8275", "qcom,qcs8300";
+
+	qcom,msm-id = <675 0x10000>;
+	qcom,board-id = <0x00010020 2>, <0x00010019 2>;
+
+	aliases {
+		serial0 = &uart7;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	dummy_reg: regulator-dummy {
+		compatible = "regulator-fixed";
+		regulator-name = "dummy-supply";
+
+		regulator-min-microvolt = <2950000>;
+		regulator-max-microvolt = <2950000>;
+	};
+
+	dummy_s4a: regulator-dummy-s4a {
+		compatible = "regulator-fixed";
+		regulator-name = "dummy-supply-s4a";
+
+		regulator-min-microvolt = <2950000>;
+		regulator-max-microvolt = <2950000>;
+	};
+};
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "a";
+
+		vreg_l3a: ldo3 {
+			regulator-name = "vreg_l3a";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4a: ldo4 {
+			regulator-name = "vreg_l4a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5a: ldo5 {
+			regulator-name = "vreg_l5a";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6a: ldo6 {
+			regulator-name = "vreg_l6a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7a: ldo7 {
+			regulator-name = "vreg_l7a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8a: ldo8 {
+			regulator-name = "vreg_l8a";
+			regulator-min-microvolt = <2504000>;
+			regulator-max-microvolt = <2960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9a: ldo9 {
+			regulator-name = "vreg_l9a";
+			regulator-min-microvolt = <2970000>;
+			regulator-max-microvolt = <3072000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "c";
+
+		vreg_s5c: smps5 {
+			regulator-name = "vreg_s5c";
+			regulator-min-microvolt = <1104000>;
+			regulator-max-microvolt = <1104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1c: ldo1 {
+			regulator-name = "vreg_l1c";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <512000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2c: ldo2 {
+			regulator-name = "vreg_l2c";
+			regulator-min-microvolt = <900000>;
+			regulator-max-microvolt = <904000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4c: ldo4 {
+			regulator-name = "vreg_l4c";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7c: ldo7 {
+			regulator-name = "vreg_l7c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8c: ldo8 {
+			regulator-name = "vreg_l8c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9c: ldo9 {
+			regulator-name = "vreg_l9c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&i2c0 {
+	pinctrl-0 = <&qup_i2c0_default>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	hd3ss3220@67 {
+		compatible = "ti,hd3ss3220";
+		reg = <0x67>;
+		interrupts = < 45 IRQ_TYPE_EDGE_FALLING>;
+		wakeup-source;
+
+		connector@0 {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			data-role = "dual";
+			power-role = "dual";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					hd3ss3220_ep: endpoint {
+						remote-endpoint = <&usb_role_switch>;
+					};
+				};
+			};
+		};
+	};
+};
+
+&i2c15 {
+	pinctrl-0 = <&qup_i2c15_default>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	expander0: pca953x@38 {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x38>;
+	};
+
+	expander1: pca953x@39 {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x39>;
+
+		io-exp-hog2 {
+			gpio-hog;
+			gpios = <2 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "io_exp_gpio2";
+		};
+	};
+
+	expander2: pca953x@3a {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x3a>;
+	};
+
+	expander3: pca953x@3b {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x3b>;
+	};
+
+	expander4: pca953x@3c {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x3c>;
+	};
+
+	expander5: pca953x@3d {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x3d>;
+	};
+
+	expander6: pca953x@3e {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x3e>;
+	};
+
+};
+
+&pmm8650au_1_gpios {
+	usb2_en_state: usb2-en-state {
+		pins = "gpio7";
+		function = "normal";
+		output-high;
+		power-source = <0>;
+	};
+};
+
+&pcie0 {
+	perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_default_state>;
+
+	status = "okay";
+};
+
+&pcie1 {
+	perst-gpios = <&tlmm 23 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_default_state>;
+
+	status = "okay";
+};
+
+&pcie0_phy {
+	vdda-phy-supply = <&vreg_l6a>;
+	vdda-pll-supply = <&vreg_l5a>;
+
+	status = "okay";
+};
+
+&pcie1_phy {
+	vdda-phy-supply = <&vreg_l6a>;
+	vdda-pll-supply = <&vreg_l5a>;
+
+	status = "okay";
+};
+
+&pcieport0 {
+	wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&qupv3_id_1 {
+	status = "okay";
+};
+
+&sdhc_2 {
+	vmmc-supply = <&dummy_reg>;
+	vqmmc-supply = <&dummy_s4a>;
+
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&sdc2_clk>, <&sdc2_cmd>, <&sdc2_data>, <&sd_cd>;
+	pinctrl-1 = <&sdc2_clk_sleep>, <&sdc2_cmd_sleep>, <&sdc2_data_sleep>, <&sd_cd>;
+
+	cap-sd-highspeed;
+
+	cd-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>;
+	iommus = <&apps_smmu 0x0 0x0>;
+
+	status = "okay";
+};
+
+&soc {
+	vbus_supply_regulator_0: vbus_supply_regulator_0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vbus_supply_0";
+		gpio = <&expander1 2 GPIO_ACTIVE_HIGH>;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+	};
+};
+
+&tlmm {
+
+	dp_hot_plug_det: dp-hot-plug-det-state {
+	/* TODO: Add the required nodes once mdss_dp0 is available.*/
+	};
+
+	qup_i2c0_default: qup-i2c0-state {
+		pins = "gpio17", "gpio18";
+		function = "qup0_se0";
+		drive-strength = <2>;
+		bias-pull-up;
+	};
+
+	pcie0_default_state: pcie0-default-state {
+		perst-pins {
+			pins = "gpio2";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+
+		clkreq-pins {
+			pins = "gpio1";
+			function = "pcie0_clkreq";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		wake-pins {
+			pins = "gpio0";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+	};
+
+	pcie1_default_state: pcie1-default-state {
+		perst-pins {
+			pins = "gpio23";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+
+		clkreq-pins {
+			pins = "gpio22";
+			function = "pcie1_clkreq";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		wake-pins {
+			pins = "gpio21";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+	};
+
+	qup_i2c15_default: qup-i2c15-state {
+		pins = "gpio91", "gpio92";
+		function = "qup1_se7";
+		drive-strength = <2>;
+		bias-pull-up;
+	};
+
+	sdc2_clk: sdc2-clk-state {
+		pins = "sdc2_clk";
+		bias-disable;
+		drive-strength = <16>;
+	};
+
+	sdc2_cmd: sdc2-cmd-state {
+		pins = "sdc2_cmd";
+		bias-pull-up;
+		drive-strength = <10>;
+	};
+
+	sdc2_data: sdc2-data-state {
+		pins = "sdc2_data";
+		bias-pull-up;
+		drive-strength = <10>;
+	};
+
+	sdc2_clk_sleep: sdc2-clk-sleep-state {
+		pins = "sdc2_clk";
+		drive-strength = <2>;
+		bias-bus-hold;
+	};
+
+	sdc2_cmd_sleep: sdc2-cmd-sleep-state {
+		pins = "sdc2_cmd";
+		drive-strength = <2>;
+		bias-bus-hold;
+	};
+
+	sdc2_data_sleep: sdc2-data-sleep-state {
+		pins = "sdc2_data";
+		drive-strength = <2>;
+		bias-bus-hold;
+	};
+
+	sd_cd: sd-cd-state {
+		pins = "gpio11";
+		function = "gpio";
+		bias-pull-up;
+	};
+};
+
+&uart7 {
+	status = "okay";
+};
+
+&ufs_mem_hc {
+	reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>;
+	vcc-supply = <&vreg_l8a>;
+	vcc-max-microamp = <1100000>;
+	vccq-supply = <&vreg_l4c>;
+	vccq-max-microamp = <1200000>;
+	status = "okay";
+};
+
+&ufs_mem_phy {
+	vdda-phy-supply = <&vreg_l4a>;
+	vdda-pll-supply = <&vreg_l5a>;
+	status = "okay";
+};
+
+&usb_1 {
+	reg = <0x0 0x0a600000 0x0 0x20000>;
+
+	interrupts-extended = <&intc GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH>,
+			      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+			      <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
+			      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
+			      <&pdc 12 IRQ_TYPE_LEVEL_HIGH>;
+	interrupt-names = "dwc_usb3",
+			  "pwr_event",
+			  "dp_hs_phy_irq",
+			  "dm_hs_phy_irq",
+			  "ss_phy_irq";
+
+	iommus = <&apps_smmu 0x80 0x0>;
+	snps,dis_u2_susphy_quirk;
+	snps,dis_enblslpm_quirk;
+	phys = <&usb_1_hsphy>, <&usb_qmpphy>;
+	phy-names = "usb2-phy", "usb3-phy";
+	maximum-speed = "super-speed-plus";
+
+	usb-role-switch;
+	dr_mode = "otg";
+
+	qcom,enable-rt;
+	wakeup-source;
+	maximum-speed = "super-speed";
+	vbus_dwc3-supply = <&vbus_supply_regulator_0>;
+	status = "okay";
+
+	ports {
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			usb_role_switch: endpoint {
+				remote-endpoint = <&hd3ss3220_ep>;
+			};
+		};
+
+	};
+};
+
+&usb_1_hsphy {
+	vdda-pll-supply = <&vreg_l7a>;
+	vdda18-supply = <&vreg_l7c>;
+	vdda33-supply = <&vreg_l9a>;
+
+	status = "okay";
+};
+
+&usb_qmpphy {
+	vdda-phy-supply = <&vreg_l7a>;
+	vdda-pll-supply = <&vreg_l5a>;
+
+	status = "okay";
+};
+
+&usb_2 {
+	reg = <0x0 0x0a400000 0x0 0x200000>;
+
+	interrupts-extended = <&intc GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>,
+				<&intc GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>,
+				<&pdc 10 IRQ_TYPE_EDGE_BOTH>,
+				<&pdc 9 IRQ_TYPE_EDGE_BOTH>;
+	interrupt-names = "dwc_usb2",
+			"pwr_event",
+			"dp_hs_phy_irq",
+			"dm_hs_phy_irq";
+
+	iommus = <&apps_smmu 0x20 0x0>;
+	phys = <&usb_2_hsphy>;
+	phy-names = "usb2-phy";
+	maximum-speed = "high-speed";
+
+	dr_mode = "otg";
+	usb-role-switch;
+	role-switch-default-mode = "host";
+	qcom,enable-rt;
+	wakeup-source;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb2_en_state>;
+
+	status = "okay";
+};
+
+&usb_2_hsphy {
+	vdda-pll-supply = <&vreg_l7a>;
+	vdda18-supply = <&vreg_l7c>;
+	vdda33-supply = <&vreg_l9a>;
+
+	status = "okay";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8275-iq-8275-evk.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8275-iq-8275-evk.dts
@@ -0,0 +1,774 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "qcs8300.dtsi"
+#include "qcs8300-pmics.dtsi"
+
+/delete-node/ &usb_1_dwc3;
+/delete-node/ &usb_2_dwc3;
+/ {
+	model = "Qualcomm Technologies, Inc. IQ 8275 EVK";
+	compatible = "qcom,qcs8275-iq-8275-evk", "qcom,qcs8275", "qcom,qcs8300";
+
+	qcom,msm-id = <675 0x10000>;
+	qcom,board-id = <0x00010020 0>, <0x00010019 0>;
+
+	aliases {
+		serial0 = &uart7;
+		serial1 = &uart2;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	dummy_reg: regulator-dummy {
+		compatible = "regulator-fixed";
+		regulator-name = "dummy-supply";
+
+		regulator-min-microvolt = <2950000>;
+		regulator-max-microvolt = <2950000>;
+	};
+
+	dummy_s4a: regulator-dummy-s4a {
+		compatible = "regulator-fixed";
+		regulator-name = "dummy-supply-s4a";
+
+		regulator-min-microvolt = <2950000>;
+		regulator-max-microvolt = <2950000>;
+	};
+};
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "a";
+
+		vreg_s4a: smps4 {
+			regulator-name = "vreg_s4a";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s9a: smps9 {
+			regulator-name = "vreg_s9a";
+			regulator-min-microvolt = <1352000>;
+			regulator-max-microvolt = <1352000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3a: ldo3 {
+			regulator-name = "vreg_l3a";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4a: ldo4 {
+			regulator-name = "vreg_l4a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5a: ldo5 {
+			regulator-name = "vreg_l5a";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6a: ldo6 {
+			regulator-name = "vreg_l6a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7a: ldo7 {
+			regulator-name = "vreg_l7a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8a: ldo8 {
+			regulator-name = "vreg_l8a";
+			regulator-min-microvolt = <2504000>;
+			regulator-max-microvolt = <2960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9a: ldo9 {
+			regulator-name = "vreg_l9a";
+			regulator-min-microvolt = <2970000>;
+			regulator-max-microvolt = <3072000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "c";
+
+		vreg_s5c: smps5 {
+			regulator-name = "vreg_s5c";
+			regulator-min-microvolt = <1104000>;
+			regulator-max-microvolt = <1104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1c: ldo1 {
+			regulator-name = "vreg_l1c";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <500000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2c: ldo2 {
+			regulator-name = "vreg_l2c";
+			regulator-min-microvolt = <900000>;
+			regulator-max-microvolt = <904000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4c: ldo4 {
+			regulator-name = "vreg_l4c";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6c: ldo6 {
+			regulator-name = "vreg_l6c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7c: ldo7 {
+			regulator-name = "vreg_l7c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8c: ldo8 {
+			regulator-name = "vreg_l8c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9c: ldo9 {
+			regulator-name = "vreg_l9c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&ethernet0 {
+	phy-mode = "sgmii";
+	phy-handle = <&sgmii_phy0>;
+
+	pinctrl-0 = <&ethernet0_default>;
+	pinctrl-names = "default";
+
+	snps,mtl-rx-config = <&mtl_rx_setup>;
+	snps,mtl-tx-config = <&mtl_tx_setup>;
+	snps,ps-speed = <1000>;
+
+	status = "okay";
+
+	mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		sgmii_phy0: phy@1c {
+			compatible = "ethernet-phy-id004d.d101";
+			reg = <0x1c>;
+			device_type = "ethernet-phy";
+			reset-gpios = <&tlmm 31 GPIO_ACTIVE_LOW>;
+			reset-assert-us = <11000>;
+			reset-deassert-us = <70000>;
+		};
+	};
+
+	mtl_rx_setup: rx-queues-config {
+		snps,rx-queues-to-use = <4>;
+		snps,rx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x0>;
+			snps,route-up;
+			snps,priority = <0x1>;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x1>;
+			snps,route-ptp;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x2>;
+			snps,route-avcp;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x3>;
+			snps,priority = <0xc>;
+		};
+	};
+
+	mtl_tx_setup: tx-queues-config {
+		snps,tx-queues-to-use = <4>;
+		snps,tx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+	};
+};
+
+&i2c0 {
+	pinctrl-0 = <&qup_i2c0_default>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	hd3ss3220@67 {
+		compatible = "ti,hd3ss3220";
+		reg = <0x67>;
+		interrupts = < 45 IRQ_TYPE_EDGE_FALLING>;
+		wakeup-source;
+
+		connector@0 {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			data-role = "dual";
+			power-role = "dual";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					hd3ss3220_ep: endpoint {
+						remote-endpoint = <&usb_role_switch>;
+					};
+				};
+			};
+		};
+	};
+};
+
+&i2c15 {
+	pinctrl-0 = <&qup_i2c15_default>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	expander0: pca953x@38 {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x38>;
+	};
+
+	expander1: pca953x@39 {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x39>;
+
+		io-exp-hog2 {
+			gpio-hog;
+			gpios = <2 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "io_exp_gpio2";
+		};
+	};
+
+	expander2: pca953x@3a {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x3a>;
+	};
+
+	expander3: pca953x@3b {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x3b>;
+	};
+
+	expander4: pca953x@3c {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x3c>;
+	};
+
+	expander5: pca953x@3d {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x3d>;
+	};
+
+	expander6: pca953x@3e {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x3e>;
+	};
+};
+
+&gpi_dma0 {
+	status = "okay";
+};
+
+&gpi_dma1 {
+	status = "okay";
+};
+
+&pcie0 {
+	perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_default_state>;
+
+	status = "okay";
+};
+
+&pcie1 {
+	perst-gpios = <&tlmm 23 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_default_state>;
+
+	status = "okay";
+};
+
+&pcie0_phy {
+	vdda-phy-supply = <&vreg_l6a>;
+	vdda-pll-supply = <&vreg_l5a>;
+
+	status = "okay";
+};
+
+&pcie1_phy {
+	vdda-phy-supply = <&vreg_l6a>;
+	vdda-pll-supply = <&vreg_l5a>;
+
+	status = "okay";
+};
+
+&pmm8650au_1_gpios {
+	usb2_en_state: usb2-en-state {
+		pins = "gpio7";
+		function = "normal";
+		output-high;
+		power-source = <0>;
+	};
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&qupv3_id_1 {
+	status = "okay";
+};
+
+&remoteproc_adsp {
+	firmware-name = "qcom/qcs8300/adsp.mbn";
+	status = "okay";
+};
+
+&remoteproc_cdsp {
+	firmware-name = "qcom/qcs8300/cdsp0.mbn";
+	status = "okay";
+};
+
+&remoteproc_gpdsp {
+	firmware-name = "qcom/qcs8300/gpdsp0.mbn";
+	status = "okay";
+};
+
+&sdhc_2 {
+	vmmc-supply = <&dummy_reg>;
+	vqmmc-supply = <&dummy_s4a>;
+
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&sdc2_clk>, <&sdc2_cmd>, <&sdc2_data>, <&sd_cd>;
+	pinctrl-1 = <&sdc2_clk_sleep>, <&sdc2_cmd_sleep>, <&sdc2_data_sleep>, <&sd_cd>;
+
+	cap-sd-highspeed;
+
+	cd-gpios = <&tlmm 11 GPIO_ACTIVE_LOW>;
+
+	iommus = <&apps_smmu 0x0 0x0>;
+
+	status = "okay";
+};
+
+&serdes0 {
+	phy-supply = <&vreg_l5a>;
+	status = "okay";
+};
+
+&soc {
+	vbus_supply_regulator_0: vbus_supply_regulator_0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vbus_supply_0";
+		gpio = <&expander1 2 GPIO_ACTIVE_HIGH>;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		enable-active-high;
+	};
+};
+
+&spi10 {
+	status = "okay";
+
+	st33htpm0: st33htpm@0 {
+		compatible = "st,st33htpm-spi";
+		reg = <0>;
+		spi-max-frequency = <20000000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+	};
+};
+
+&tlmm {
+
+	dp_hot_plug_det: dp-hot-plug-det-state {
+	/* TODO: Add the required nodes once mdss_dp0 is available.*/
+	};
+
+	ethernet0_default: ethernet0-default-state {
+		ethernet0_mdc: ethernet0-mdc-pins {
+			pins = "gpio5";
+			function = "emac0_mdc";
+			drive-strength = <16>;
+			bias-pull-up;
+		};
+
+		ethernet0_mdio: ethernet0-mdio-pins {
+			pins = "gpio6";
+			function = "emac0_mdio";
+			drive-strength = <16>;
+			bias-pull-up;
+		};
+	};
+
+	pcie0_default_state: pcie0-default-state {
+		perst-pins {
+			pins = "gpio2";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+
+		clkreq-pins {
+			pins = "gpio1";
+			function = "pcie0_clkreq";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		wake-pins {
+			pins = "gpio0";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+	};
+
+	pcie1_default_state: pcie1-default-state {
+		perst-pins {
+			pins = "gpio23";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+
+		clkreq-pins {
+			pins = "gpio22";
+			function = "pcie1_clkreq";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		wake-pins {
+			pins = "gpio21";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+	};
+
+	qup_i2c0_default: qup-i2c0-state {
+		pins = "gpio17", "gpio18";
+		function = "qup0_se0";
+		drive-strength = <2>;
+		bias-pull-up;
+	};
+
+	qup_i2c15_default: qup-i2c15-state {
+		pins = "gpio91", "gpio92";
+		function = "qup1_se7";
+		drive-strength = <2>;
+		bias-pull-up;
+	};
+
+	sdc2_clk: sdc2-clk-state {
+		pins = "sdc2_clk";
+		bias-disable;
+		drive-strength = <16>;
+	};
+
+	sdc2_cmd: sdc2-cmd-state {
+		pins = "sdc2_cmd";
+		bias-pull-up;
+		drive-strength = <10>;
+	};
+
+	sdc2_data: sdc2-data-state {
+		pins = "sdc2_data";
+		bias-pull-up;
+		drive-strength = <10>;
+	};
+
+	sdc2_clk_sleep: sdc2-clk-sleep-state {
+		pins = "sdc2_clk";
+		drive-strength = <2>;
+		bias-bus-hold;
+	};
+
+	sdc2_cmd_sleep: sdc2-cmd-sleep-state {
+		pins = "sdc2_cmd";
+		drive-strength = <2>;
+		bias-bus-hold;
+	};
+
+	sdc2_data_sleep: sdc2-data-sleep-state {
+		pins = "sdc2_data";
+		drive-strength = <2>;
+		bias-bus-hold;
+	};
+
+	sd_cd: sd-cd-state {
+		pins = "gpio11";
+		function = "gpio";
+		bias-pull-up;
+	};
+};
+
+&uart2 {
+	pinctrl-names = "default";
+	status = "okay";
+
+	/* HS UART Instance */
+	bluetooth: bluetooth {
+		compatible = "qcom,wcn6855-bt";
+		pinctrl-names = "default";
+		max-speed = <3200000>;
+	};
+};
+
+&uart7 {
+	status = "okay";
+};
+
+&ufs_mem_hc {
+	reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>;
+	vcc-supply = <&vreg_l8a>;
+	vcc-max-microamp = <1100000>;
+	vccq-supply = <&vreg_l4c>;
+	vccq-max-microamp = <1200000>;
+	status = "okay";
+};
+
+&ufs_mem_phy {
+	vdda-phy-supply = <&vreg_l4a>;
+	vdda-pll-supply = <&vreg_l5a>;
+	status = "okay";
+};
+
+&usb_1 {
+	reg = <0x0 0x0a600000 0x0 0x20000>;
+
+	interrupts-extended = <&intc GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH>,
+			      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+			      <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
+			      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
+			      <&pdc 12 IRQ_TYPE_LEVEL_HIGH>;
+	interrupt-names = "dwc_usb3",
+			  "pwr_event",
+			  "dp_hs_phy_irq",
+			  "dm_hs_phy_irq",
+			  "ss_phy_irq";
+
+	iommus = <&apps_smmu 0x80 0x0>;
+	snps,dis_u2_susphy_quirk;
+	snps,dis_enblslpm_quirk;
+	phys = <&usb_1_hsphy>, <&usb_qmpphy>;
+	phy-names = "usb2-phy", "usb3-phy";
+	maximum-speed = "super-speed-plus";
+
+	usb-role-switch;
+	dr_mode = "otg";
+
+	qcom,enable-rt;
+	wakeup-source;
+	maximum-speed = "super-speed";
+	vbus_dwc3-supply = <&vbus_supply_regulator_0>;
+	status = "okay";
+
+	ports {
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			usb_role_switch: endpoint {
+				remote-endpoint = <&hd3ss3220_ep>;
+			};
+		};
+
+	};
+};
+
+&usb_1_hsphy {
+	vdda-pll-supply = <&vreg_l7a>;
+	vdda18-supply = <&vreg_l7c>;
+	vdda33-supply = <&vreg_l9a>;
+
+	status = "okay";
+};
+
+&usb_qmpphy {
+	vdda-phy-supply = <&vreg_l7a>;
+	vdda-pll-supply = <&vreg_l5a>;
+
+	status = "okay";
+};
+
+&usb_2 {
+	reg = <0x0 0x0a400000 0x0 0x200000>;
+
+	interrupts-extended = <&intc GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>,
+				<&intc GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>,
+				<&pdc 10 IRQ_TYPE_EDGE_BOTH>,
+				<&pdc 9 IRQ_TYPE_EDGE_BOTH>;
+	interrupt-names = "dwc_usb2",
+			"pwr_event",
+			"dp_hs_phy_irq",
+			"dm_hs_phy_irq";
+
+	iommus = <&apps_smmu 0x20 0x0>;
+	phys = <&usb_2_hsphy>;
+	phy-names = "usb2-phy";
+	maximum-speed = "high-speed";
+
+	dr_mode = "otg";
+	usb-role-switch;
+	role-switch-default-mode = "host";
+	qcom,enable-rt;
+	wakeup-source;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb2_en_state>;
+
+	status = "okay";
+};
+
+&usb_2_hsphy {
+	vdda-pll-supply = <&vreg_l7a>;
+	vdda18-supply = <&vreg_l7c>;
+	vdda33-supply = <&vreg_l9a>;
+
+	status = "okay";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8300-addons-ride.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8300-addons-ride.dts
@@ -0,0 +1,497 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs8300-ride.dts"
+#include "qcs8300-addons.dtsi"
+
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS8300-addons RIDE";
+	compatible = "qcom,qcs8300-addons-ride", "qcom,qcs8300-ride", "qcom,qcs8275",
+		     "qcom,qcs8300";
+
+	sound {
+		compatible = "qcom,qcs8300-sndcard";
+		model = "qcs8300-ridesx-snd-card";
+
+		clocks = <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+			 <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+		clock-names = "macro", "dcodec";
+
+		pinctrl-names = "default", "stub_aif1_active", "stub_aif1_sleep",
+				"stub_aif2_active", "stub_aif2_sleep", "stub_aif3_active",
+				"stub_aif3_sleep", "stub_aif4_active", "stub_aif4_sleep";
+		pinctrl-0 = <&mi2s1_data0_sleep>, <&mi2s1_data1_sleep>, <&mi2s1_sck_sleep>,
+			    <&mi2s1_ws_sleep>, <&lpass_i2s1_clk_sleep>,
+			    <&lpass_i2s1_data_sleep>, <&lpass_i2s1_ws_sleep>, <&mi2s_mclk_sleep>,
+			    <&hs0_mi2s_data0_sleep>, <&hs0_mi2s_sck_sleep>, <&hs0_mi2s_data1_sleep>,
+			    <&hs0_mi2s_ws_sleep>;
+		pinctrl-1 = <&mi2s1_data0>, <&mi2s1_data1>, <&mi2s1_sck>, <&mi2s1_ws>;
+		pinctrl-2 = <&mi2s1_data0_sleep>, <&mi2s1_data1_sleep>, <&mi2s1_sck_sleep>,
+			    <&mi2s1_ws_sleep>;
+		pinctrl-3 = <&lpass_i2s1_clk>, <&lpass_i2s1_data>, <&lpass_i2s1_ws>;
+		pinctrl-4 = <&lpass_i2s1_clk_sleep>, <&lpass_i2s1_data_sleep>,
+			    <&lpass_i2s1_ws_sleep>;
+		pinctrl-5 = <&hs0_mi2s_data0>, <&hs0_mi2s_data1>, <&hs0_mi2s_sck>, <&mi2s_mclk>,
+			    <&hs0_mi2s_ws>;
+		pinctrl-6 = <&hs0_mi2s_data0_sleep>, <&hs0_mi2s_data1_sleep>, <&hs0_mi2s_sck_sleep>,
+			    <&mi2s_mclk_sleep>,<&hs0_mi2s_ws_sleep>;
+		pinctrl-7 = <&mi2s1_data0>, <&mi2s1_data1>, <&mi2s1_sck>, <&mi2s_mclk>,
+			    <&mi2s1_ws>;
+		pinctrl-8 = <&mi2s1_data0_sleep>, <&mi2s1_data1_sleep>, <&mi2s1_sck_sleep>,
+			    <&mi2s1_ws_sleep>, <&mi2s_mclk_sleep>;
+
+		mi2s1-capture-dai-link {
+			link-name = "MI2S-LPAIF-TX-SECONDARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai SECONDARY_MI2S_TX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 1>;
+			};
+		};
+
+		mi2s1-playback-dai-link {
+			link-name = "MI2S-LPAIF-RX-SECONDARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai SECONDARY_MI2S_RX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 0>;
+			};
+		};
+
+		lpi-mi2s1-capture-dai-link {
+			link-name = "MI2S-LPAIF_VA-TX-PRIMARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 3>;
+			};
+		};
+
+		lpi-mi2s1-playback-dai-link {
+			link-name = "MI2S-LPAIF_VA-RX-PRIMARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 2>;
+			};
+		};
+
+		tdm1-capture-dai-link {
+			link-name = "TDM-LPAIF-TX-SECONDARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai SECONDARY_TDM_TX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 1>;
+			};
+		};
+
+		tdm1-playback-dai-link {
+			link-name = "TDM-LPAIF-RX-SECONDARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai SECONDARY_TDM_RX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 0>;
+			};
+		};
+
+		lpi-tdm1-capture-dai-link {
+			link-name = "TDM-LPAIF_VA-TX-PRIMARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_TDM_TX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 3>;
+			};
+		};
+
+		lpi-tdm1-playback-dai-link {
+			link-name = "TDM-LPAIF_VA-RX-PRIMARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_TDM_RX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 2>;
+			};
+		};
+
+		hs0-mi2s-capture-dai-link {
+			link-name = "MI2S-LPAIF_SDR-TX-PRIMARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_SDR_MI2S_TX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 5>;
+			};
+		};
+
+		hs0-mi2s-playback-dai-link {
+			link-name = "MI2S-LPAIF_SDR-RX-PRIMARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_SDR_MI2S_RX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 4>;
+			};
+		};
+
+		tdm0-capture-dai-link {
+			link-name = "TDM-LPAIF_SDR-TX-PRIMARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_SDR_TDM_TX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 5>;
+			};
+		};
+
+		tdm0-playback-dai-link {
+			link-name = "TDM-LPAIF_SDR-RX-PRIMARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_SDR_TDM_RX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 4>;
+			};
+		};
+
+		hs3-mi2s-capture-dai-link {
+			link-name = "MI2S-LPAIF_SDR-TX-QUATERNARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai QUATERNARY_SDR_MI2S_TX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 7>;
+			};
+		};
+
+		hs3-mi2s-playback-dai-link {
+			link-name = "MI2S-LPAIF_SDR-RX-QUATERNARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai QUATERNARY_SDR_MI2S_RX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 6>;
+			};
+		};
+
+		tdm3-capture-dai-link {
+			link-name = "TDM-LPAIF_SDR-TX-QUATERNARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai QUATERNARY_SDR_TDM_TX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 7>;
+			};
+		};
+
+		tdm3-playback-dai-link {
+			link-name = "TDM-LPAIF_SDR-RX-QUATERNARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai QUATERNARY_SDR_TDM_RX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 6>;
+			};
+		};
+	};
+};
+
+&lpass_tlmm {
+	lpass_i2s1_clk: i2s1-clk-state {
+			pins = "gpio6";
+			function = "i2s1_clk";
+			drive-strength = <8>;
+			bias-disable;
+			output-high;
+	};
+
+	lpass_i2s1_clk_sleep: i2s1-clk-sleep-state {
+			pins = "gpio6";
+			function = "i2s1_clk";
+			drive-strength = <2>;
+			bias-pull-down;
+			input-enable;
+	};
+
+	lpass_i2s1_data: i2s1-data-state {
+			pins = "gpio8", "gpio9";
+			function = "i2s1_data";
+			drive-strength = <8>;
+			bias-disable;
+	};
+
+	lpass_i2s1_data_sleep: i2s1-data-sleep-state {
+			pins = "gpio8", "gpio9";
+			function = "i2s1_data";
+			drive-strength = <2>;
+			bias-pull-down;
+			input-enable;
+	};
+
+	lpass_i2s1_ws: i2s1-ws-state {
+			pins = "gpio7";
+			function = "i2s1_ws";
+			drive-strength = <8>;
+			output-high;
+	};
+
+	lpass_i2s1_ws_sleep: i2s1-ws-sleep-state {
+			pins = "gpio7";
+			function = "i2s1_ws";
+			drive-strength = <2>;
+			bias-pull-down;
+			input-enable;
+	};
+};
+
+&soc {
+	msm_stub_codec: msm-stub-codec {
+		compatible = "qcom,msm-stub-codec";
+		#sound-dai-cells = <1>;
+	};
+
+	spf_core_platform: spf-core-platform {
+		compatible = "qcom,spf-core-platform";
+
+		msm_audio_mem: msm-audio-mem {
+			compatible = "qcom,msm-audio-mem";
+			qcom,smmu-version = <2>;
+			qcom,smmu-enabled;
+			iommus = <&apps_smmu 0x2001 0x0>;
+			qcom,iommu-dma-addr-pool = <0x10000000 0x10000000>;
+			qcom,smmu-sid-mask = /bits/ 64 <0xf>;
+			dma-coherent;
+		};
+
+		msm_audio_mem_cma: msm-audio-mem-cma {
+			compatible = "qcom,msm-audio-mem";
+			memory-region = <&audio_cma_mem>;
+		};
+	};
+};
+
+&tlmm {
+	hs1_mi2s: hs1-mi2s-state {
+		pins = "gpio45", "gpio46", "gpio47", "gpio48";
+		function = "hs1_mi2s";
+	};
+
+	hs2_mi2s: hs2-mi2s-state {
+		pins = "gpio49", "gpio50", "gpio51", "gpio52";
+		function = "hs2_mi2s";
+	};
+
+	hs0_mi2s_data0: hs0-mi2s-data0-state {
+		pins = "gpio108";
+		function = "hs0_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	hs0_mi2s_data0_sleep: hs0-mi2s-data0-sleep-state {
+		pins = "gpio108";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs0_mi2s_data1: hs0-mi2s-data1-state {
+		pins = "gpio109";
+		function = "hs0_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	hs0_mi2s_data1_sleep: hs0-mi2s-data1-sleep-state {
+		pins = "gpio109";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs0_mi2s_sck: hs0-mi2s-sck-state {
+		pins = "gpio106";
+		function = "hs0_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	hs0_mi2s_sck_sleep: hs0-mi2s-sck-sleep-state {
+		pins = "gpio106";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s_mclk: mi2s-mclk-state {
+		pins = "gpio97";
+		function = "mi2s_mclk0";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	mi2s_mclk_sleep: mi2s-mclk-sleep-state {
+		pins = "gpio97";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs0_mi2s_ws: hs0-mi2s-ws-state {
+		pins = "gpio107";
+		function = "hs0_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	hs0_mi2s_ws_sleep: hs0-mi2s-ws-sleep-state {
+		pins = "gpio107";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s1_data0: mi2s1-data0-state {
+		pins = "gpio100";
+		function = "mi2s1_data0";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	mi2s1_data0_sleep: mi2s1-data0-sleep-state {
+		pins = "gpio100";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s1_data1: mi2s1-data1-state {
+		pins = "gpio101";
+		function = "mi2s1_data1";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	mi2s1_data1_sleep: mi2s1-data1-sleep-state {
+		pins = "gpio101";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s1_sck: mi2s1-sck-state {
+		pins = "gpio98";
+		function = "mi2s1_sck";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	mi2s1_sck_sleep: mi2s1-sck-sleep-state {
+		pins = "gpio98";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s1_ws: mi2s1-ws-state {
+		pins = "gpio99";
+		function = "mi2s1_ws";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	mi2s1_ws_sleep: mi2s1-ws-sleep-state {
+		pins = "gpio99";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s2_data0: mi2s2-data0-state {
+		pins = "gpio104";
+		function = "mi2s2_data0";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	mi2s2_data1: mi2s2-data1-state {
+		pins = "gpio105";
+		function = "mi2s2_data1";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	mi2s2_sck: mi2s2-sck-state {
+		pins = "gpio102";
+		function = "mi2s2_sck";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	mi2s2_ws: mi2s2-ws-state {
+		pins = "gpio103";
+		function = "mi2s2_ws";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8300-addons.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8300-addons.dtsi
@@ -0,0 +1,536 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/arm/qcom_dma_heap_dt_constants.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
+
+&{/} {
+	firmware {
+		qcom_mem_object {
+			compatible = "qcom,mem-object";
+		};
+
+		qcom_smcinvoke {
+			compatible = "qcom,smcinvoke";
+		};
+	};
+
+	reserved-memory {
+		audio_cma_mem: qcom,audio-ml {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x1000000>;
+		};
+
+		dump_mem: mem-dump-region {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			size = <0x0 0x3000000>;
+		};
+
+		qseecom_mem: qcom,qseecom {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x1400000>; /* 20M */
+		};
+
+		qseecom_ta_mem: qcom,qseecom-ta {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x1000000>; /* 16M */
+		};
+	};
+
+	mem-dump {
+		compatible = "qcom,mem-dump";
+		memory-region = <&dump_mem>;
+
+		c0-context {
+			qcom,dump-id = <0x0>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c0-scandump {
+			qcom,dump-id = <0x130>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		c100-context {
+			qcom,dump-id = <0x1>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c100-scandump {
+			qcom,dump-id = <0x131>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		c200-context {
+			qcom,dump-id = <0x2>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c200-scandump {
+			qcom,dump-id = <0x132>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		c300-context {
+			qcom,dump-id = <0x3>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c300-scandump {
+			qcom,dump-id = <0x133>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		c400-context {
+			qcom,dump-id = <0x4>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c500-context {
+			qcom,dump-id = <0x5>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c600-context {
+			qcom,dump-id = <0x6>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c700-context {
+			qcom,dump-id = <0x7>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c10000-scandump {
+			qcom,dump-id = <0x134>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		c10100-scandump {
+			qcom,dump-id = <0x135>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		c10200-scandump {
+			qcom,dump-id = <0x136>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		c10300-scandump {
+			qcom,dump-id = <0x137>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		cpuss-reg {
+			qcom,dump-id = <0xef>;
+			qcom,dump-size = <0x20000>;
+		};
+
+		etf-reg {
+			qcom,dump-id = <0x101>;
+			qcom,dump-size = <0x1000>;
+		};
+
+
+		etf-swao {
+			qcom,dump-id = <0xf1>;
+			qcom,dump-size = <0x8400>;
+		};
+
+		etfswao-reg {
+			qcom,dump-id = <0x102>;
+			qcom,dump-size = <0x1000>;
+		};
+
+		etr-reg {
+			qcom,dump-id = <0x100>;
+			qcom,dump-size = <0x1000>;
+		};
+
+		fcm {
+			qcom,dump-id = <0xee>;
+			qcom,dump-size = <0x8400>;
+		};
+
+		l1-dcache0 {
+			qcom,dump-id = <0x80>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dcache100 {
+			qcom,dump-id = <0x81>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dcache200 {
+			qcom,dump-id = <0x82>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dcache300 {
+			qcom,dump-id = <0x83>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dcache10000 {
+			qcom,dump-id = <0x84>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dcache10100 {
+			qcom,dump-id = <0x85>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dcache10200 {
+			qcom,dump-id = <0x86>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dcache10300 {
+			qcom,dump-id = <0x87>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dtlb10000 {
+			qcom,dump-id = <0x44>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-dtlb10100 {
+			qcom,dump-id = <0x45>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-dtlb10200 {
+			qcom,dump-id = <0x46>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-dtlb10300 {
+			qcom,dump-id = <0x47>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-icache0 {
+			qcom,dump-id = <0x60>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-icache100 {
+			qcom,dump-id = <0x61>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-icache200 {
+			qcom,dump-id = <0x62>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-icache300 {
+			qcom,dump-id = <0x63>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-icache10000 {
+			qcom,dump-id = <0x64>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-icache10100 {
+			qcom,dump-id = <0x65>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-icache10200 {
+			qcom,dump-id = <0x66>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-icache10300 {
+			qcom,dump-id = <0x67>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-itlb10000 {
+			qcom,dump-id = <0x24>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-itlb10100 {
+			qcom,dump-id = <0x25>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-itlb10200 {
+			qcom,dump-id = <0x26>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-itlb10300 {
+			qcom,dump-id = <0x27>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l2-cache10000 {
+			qcom,dump-id = <0xc4>;
+			qcom,dump-size = <0x90100>;
+		};
+
+		l2-cache10100 {
+			qcom,dump-id = <0xc5>;
+			qcom,dump-size = <0x90100>;
+		};
+
+		l2-cache10200 {
+			qcom,dump-id = <0xc6>;
+			qcom,dump-size = <0x90100>;
+		};
+
+		l2-cache10300 {
+			qcom,dump-id = <0xc7>;
+			qcom,dump-size = <0x90100>;
+		};
+
+		l2-tlb0 {
+			qcom,dump-id = <0x120>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		l2-tlb100 {
+			qcom,dump-id = <0x121>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		l2-tlb200 {
+			qcom,dump-id = <0x122>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		l2-tlb300 {
+			qcom,dump-id = <0x123>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		l2-tlb10000 {
+			qcom,dump-id = <0x124>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		l2-tlb10100 {
+			qcom,dump-id = <0x125>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		l2-tlb10200 {
+			qcom,dump-id = <0x126>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		l2-tlb10300 {
+			qcom,dump-id = <0x127>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		misc-data {
+			qcom,dump-id = <0xe8>;
+			qcom,dump-size = <0x1000>;
+		};
+
+		pmic {
+			qcom,dump-id = <0xe4>;
+			qcom,dump-size = <0x80000>;
+		};
+
+		rpm-sw {
+			qcom,dump-id = <0xea>;
+			qcom,dump-size = <0x28000>;
+		};
+
+		rpmh {
+			qcom,dump-id = <0xec>;
+			qcom,dump-size = <0x2000000>;
+		};
+
+		tmc-etf {
+			qcom,dump-id = <0xf0>;
+			qcom,dump-size = <0x10000>;
+		};
+	};
+};
+
+&soc {
+	lpass_tlmm: pinctrl@3440000 {
+		compatible = "qcom,qcs8300-lpass-lpi-pinctrl";
+		reg = <0x0 0x03440000 0x0 0x20000>,
+		      <0x0 0x034D0000 0x0 0x10000>;
+
+		clocks = <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+			 <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+		clock-names = "core", "audio";
+
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-ranges = <&lpass_tlmm 0 0 23>;
+	};
+
+	csr: csr@4001000 {
+		compatible = "qcom,coresight-csr";
+		reg = <0x0 0x4001000 0x0 0x1000>;
+		reg-names = "csr-base";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		qcom,hwctrl-set-support;
+		qcom,set-byte-cntr-support;
+		qcom,blk-size = <1>;
+	};
+
+	tmc_etr: tmc@4048000 {
+		interrupts = <GIC_SPI 270 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "byte-cntr-irq";
+		qcom,sw-usb;
+		coresight-csr = <&csr>;
+		csr-atid-offset = <0xf8>;
+		csr-irqctrl-offset = <0x6c>;
+		byte-cntr-name = "byte-cntr";
+		byte-cntr-class-name = "coresight-tmc-etr-stream";
+	};
+
+	tmc_etr1: tmc@404f000 {
+		interrupts = <GIC_SPI 262 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "byte-cntr-irq";
+		coresight-csr = <&csr>;
+		csr-atid-offset = <0x108>;
+		csr-irqctrl-offset = <0x70>;
+		byte-cntr-name = "byte-cntr1";
+		byte-cntr-class-name = "coresight-tmc-etr1-stream";
+	};
+
+	dma@40ff000 {
+		compatible = "qcom,dcc-v3", "qcom,dcc";
+		reg = <0x0 0x040ff000 0x0 0x1000>,
+		      <0x0 0x040b8800 0x0 0x6000>;
+
+		qcom,dcc-offset = <0x38800>;
+	};
+
+	tgu@4b0e000 {
+		compatible = "arm,primecell", "qcom,coresight-tgu";
+		reg = <0x0 0x4b0e000 0x0 0x1000>;
+		reg-names = "tgu-base";
+		device-name = "tgu_ipcb";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		arm,primecell-periphid = <0x0003b999>;
+		tgu-conditions = <4>;
+		tgu-regs = <4>;
+		tgu-steps = <3>;
+		tgu-timer-counters = <8>;
+	};
+
+	tgu@4b0f000 {
+		compatible = "arm,primecell", "qcom,coresight-tgu";
+		reg = <0x0 0x4b0f000 0x0 0x1000>;
+		reg-names = "tgu-base";
+		device-name = "tgu_spmi0";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		arm,primecell-periphid = <0x0003b999>;
+		tgu-conditions = <4>;
+		tgu-regs = <8>;
+		tgu-steps = <3>;
+		tgu-timer-counters = <8>;
+	};
+
+	swao_csr: csr@4b11000 {
+		compatible = "qcom,coresight-csr";
+		reg = <0x0 0x4b11000 0x0 0x1000>,
+		      <0x0 0x4b110f8 0x0 0x50>;
+		reg-names = "csr-base", "msr-base";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		qcom,timestamp-support;
+		qcom,msr-support;
+		qcom,blk-size = <1>;
+	};
+
+	qcom_tzlog: tz-log@146d8720 {
+		compatible = "qcom,tz-log";
+		reg = <0x0 0x146d8720 0x0 0x3000>;
+		qcom,hyplog-enabled;
+		hyplog-address-offset = <0x410>;
+		hyplog-size-offset = <0x414>;
+	};
+
+	qcom,dma-heaps {
+		compatible = "qcom,dma-heaps";
+
+		qcom,qseecom {
+			qcom,dma-heap-name = "qcom,qseecom";
+			qcom,dma-heap-type = <HEAP_TYPE_CMA>;
+			memory-region = <&qseecom_mem>;
+		};
+
+		qcom,qseecom_ta {
+			qcom,dma-heap-name = "qcom,qseecom-ta";
+			qcom,dma-heap-type = <HEAP_TYPE_CMA>;
+			memory-region = <&qseecom_ta_mem>;
+		};
+
+		qcom,secure_cdsp {
+			qcom,dma-heap-name = "qcom,cma-secure-cdsp";
+			qcom,dma-heap-type = <HEAP_TYPE_CMA>;
+			memory-region = <&cdsp_secure_heap>;
+		};
+	};
+
+	qcom,mem-buf {
+		compatible = "qcom,mem-buf";
+		qcom,mem-buf-capabilities = "supplier";
+		qcom,vmid = <3>;
+	};
+
+	qcom,mem-buf-msgq {
+		compatible = "qcom,mem-buf-msgq";
+	};
+
+	qcom,secure-buffer {
+		compatible = "qcom,secure-buffer";
+		qcom,vmid-cp-camera-preview-ro;
+	};
+
+};
+
+&sram {
+	mem_dump_table@10 {
+		compatible = "qcom,msm-imem-mem-dump-table";
+		reg = <0x10 0x8>;
+	};
+
+	kaslr_offset@6d0 {
+		compatible = "qcom,msm-imem-kaslr_offset";
+		reg = <0x6d0 0xc>;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8300-camera-sensor-idp.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8300-camera-sensor-idp.dtsi
@@ -0,0 +1,364 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <dt-bindings/msm-camera.h>
+
+&soc {
+	qcom,cam-res-mgr {
+		compatible = "qcom,cam-res-mgr";
+		status = "ok";
+		gpios-shared = <609 610 611>;
+	};
+};
+
+&cam_cci0 {
+
+	/* GMSL deserializer 0 */
+	qcom,cam-gmsl-deserializer0 {
+		cell-index = <0>;
+		csiphy-sd-index = <0>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_active>;
+		pinctrl-1 = <&cam_sensor_mclk0_suspend>;
+		gpios = <&tlmm 73 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_RESET0";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+
+		port@0 {
+			reg = <0>;
+			deser0_port0: endpoint {
+				remote-endpoint = <&gmsl_sensor0_ep>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			deser0_port1: endpoint {
+				remote-endpoint = <&gmsl_sensor1_ep>;
+			};
+		};
+
+		port@2 {
+			reg = <0>;
+			deser0_port2: endpoint {
+				remote-endpoint = <&gmsl_sensor2_ep>;
+			};
+		};
+
+		port@3 {
+			reg = <1>;
+			deser0_port3: endpoint {
+				remote-endpoint = <&gmsl_sensor3_ep>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 0 */
+	qcom,cam-gmsl-sensor0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor0_ep: endpoint {
+				remote-endpoint = <&deser0_port0>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 1 */
+	qcom,cam-gmsl-sensor1 {
+		cell-index = <1>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor1_ep: endpoint {
+				remote-endpoint = <&deser0_port1>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 2 */
+	qcom,cam-gmsl-sensor2 {
+		cell-index = <2>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor2_ep: endpoint {
+				remote-endpoint = <&deser0_port2>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 3 */
+	qcom,cam-gmsl-sensor3 {
+		cell-index = <3>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor3_ep: endpoint {
+				remote-endpoint = <&deser0_port3>;
+			};
+		};
+	};
+
+};
+
+
+&cam_cci1 {
+
+	/* GMSL deserializer 1 */
+	qcom,cam-gmsl-deserializer1 {
+		cell-index = <1>;
+		csiphy-sd-index = <1>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend>;
+		gpios = <&tlmm 74 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_RESET1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+
+		port@0 {
+			reg = <0>;
+			deser1_port0: endpoint {
+				remote-endpoint = <&gmsl_sensor4_ep>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			deser1_port1: endpoint {
+				remote-endpoint = <&gmsl_sensor5_ep>;
+			};
+		};
+
+		port@2 {
+			reg = <0>;
+			deser1_port2: endpoint {
+				remote-endpoint = <&gmsl_sensor6_ep>;
+			};
+		};
+
+		port@3 {
+			reg = <1>;
+			deser1_port3: endpoint {
+				remote-endpoint = <&gmsl_sensor7_ep>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 0 */
+	qcom,cam-gmsl-sensor4 {
+		cell-index = <4>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor4_ep: endpoint {
+				remote-endpoint = <&deser1_port0>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 1 */
+	qcom,cam-gmsl-sensor5 {
+		cell-index = <5>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor5_ep: endpoint {
+				remote-endpoint = <&deser1_port1>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 2 */
+	qcom,cam-gmsl-sensor6 {
+		cell-index = <6>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor6_ep: endpoint {
+				remote-endpoint = <&deser1_port2>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 3 */
+	qcom,cam-gmsl-sensor7 {
+		cell-index = <7>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor7_ep: endpoint {
+				remote-endpoint = <&deser1_port3>;
+			};
+		};
+	};
+
+};
+
+&cam_cci2 {
+
+	/* GMSL deserializer 2 */
+	qcom,cam-gmsl-deserializer2 {
+		cell-index = <2>;
+		csiphy-sd-index = <2>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_active>;
+		pinctrl-1 = <&cam_sensor_mclk2_suspend>;
+		gpios = <&tlmm 75 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_RESET2";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK2_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+
+		port@0 {
+			reg = <0>;
+			deser2_port0: endpoint {
+				remote-endpoint = <&gmsl_sensor8_ep>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			deser2_port1: endpoint {
+				remote-endpoint = <&gmsl_sensor9_ep>;
+			};
+		};
+
+		port@2 {
+			reg = <0>;
+			deser2_port2: endpoint {
+				remote-endpoint = <&gmsl_sensor10_ep>;
+			};
+		};
+
+		port@3 {
+			reg = <1>;
+			deser2_port3: endpoint {
+				remote-endpoint = <&gmsl_sensor11_ep>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 0 */
+	qcom,cam-gmsl-sensor8 {
+		cell-index = <8>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor8_ep: endpoint {
+				remote-endpoint = <&deser2_port0>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 1 */
+	qcom,cam-gmsl-sensor9 {
+		cell-index = <9>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor9_ep: endpoint {
+				remote-endpoint = <&deser2_port1>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 2 */
+	qcom,cam-gmsl-sensor10 {
+		cell-index = <10>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor10_ep: endpoint {
+				remote-endpoint = <&deser2_port2>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 3 */
+	qcom,cam-gmsl-sensor11 {
+		cell-index = <11>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor11_ep: endpoint {
+				remote-endpoint = <&deser2_port3>;
+			};
+		};
+	};
+
+};
+
+
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8300-camera.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8300-camera.dtsi
@@ -0,0 +1,2548 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <dt-bindings/msm-camera.h>
+
+&tlmm {
+	cci_i2c_sda0_active: cci_i2c_sda0_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio57";
+			function = "cci_i2c_sda0";
+		};
+
+		config {
+			pins = "gpio57";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda0_suspend: cci_i2c_sda0_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio57";
+			function = "cci_i2c_sda0";
+		};
+
+		config {
+			pins = "gpio57";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl0_active: cci_i2c_scl0_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio58";
+			function = "cci_i2c_scl0";
+		};
+
+		config {
+			pins = "gpio58";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl0_suspend: cci_i2c_scl0_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio58";
+			function = "cci_i2c_scl0";
+		};
+
+		config {
+			pins = "gpio58";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda1_active: cci_i2c_sda1_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio29";
+			function = "cci_i2c_sda1";
+		};
+
+		config {
+			pins = "gpio29";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda1_suspend: cci_i2c_sda1_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio29";
+			function = "cci_i2c_sda1";
+		};
+
+		config {
+			pins = "gpio29";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl1_active: cci_i2c_scl1_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio30";
+			function = "cci_i2c_scl1";
+		};
+
+		config {
+			pins = "gpio30";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl1_suspend: cci_i2c_scl1_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio30";
+			function = "cci_i2c_scl1";
+		};
+
+		config {
+			pins = "gpio30";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda2_active: cci_i2c_sda2_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio59";
+			function = "cci_i2c_sda2";
+		};
+
+		config {
+			pins = "gpio59";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda2_suspend: cci_i2c_sda2_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio59";
+			function = "cci_i2c_sda2";
+		};
+
+		config {
+			pins = "gpio59";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl2_active: cci_i2c_scl2_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio60";
+			function = "cci_i2c_scl2";
+		};
+
+		config {
+			pins = "gpio60";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl2_suspend: cci_i2c_scl2_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio60";
+			function = "cci_i2c_scl2";
+		};
+
+		config {
+			pins = "gpio60";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda3_active: cci_i2c_sda3_active {
+		mux {
+			pins = "gpio31";
+			function = "cci_i2c_sda3";
+		};
+
+		config {
+			pins = "gpio31";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda3_suspend: cci_i2c_sda3_suspend {
+		mux {
+			pins = "gpio31";
+			function = "cci_i2c_sda3";
+		};
+
+		config {
+			pins = "gpio31";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl3_active: cci_i2c_scl3_active {
+		mux {
+			pins = "gpio32";
+			function = "cci_i2c_scl3";
+		};
+
+		config {
+			pins = "gpio32";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl3_suspend: cci_i2c_scl3_suspend {
+		mux {
+			pins = "gpio32";
+			function = "cci_i2c_scl3";
+		};
+
+		config {
+			pins = "gpio32";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda4_active: cci_i2c_sda4_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio61";
+			function = "cci_i2c_sda4";
+		};
+
+		config {
+			pins = "gpio61";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda4_suspend: cci_i2c_sda4_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio61";
+			function = "cci_i2c_sda4";
+		};
+
+		config {
+			pins = "gpio61";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl4_active: cci_i2c_scl4_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio62";
+			function = "cci_i2c_scl4";
+		};
+
+		config {
+			pins = "gpio62";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl4_suspend: cci_i2c_scl4_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio62";
+			function = "cci_i2c_scl4";
+		};
+
+		config {
+			pins = "gpio62";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda5_active: cci_i2c_sda5_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio54";
+			function = "cci_i2c_sda5";
+		};
+
+		config {
+			pins = "gpio54";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda5_suspend: cci_i2c_sda5_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio54";
+			function = "cci_i2c_sda5";
+		};
+
+		config {
+			pins = "gpio54";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl5_active: cci_i2c_scl5_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio55";
+			function = "cci_i2c_scl5";
+		};
+
+		config {
+			pins = "gpio55";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl5_suspend: cci_i2c_scl5_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio55";
+			function = "cci_i2c_scl5";
+		};
+
+		config {
+			pins = "gpio55";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk0_active: cam_sensor_mclk0_active {
+		/* MCLK0 */
+		mux {
+			pins = "gpio67";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio67";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk0_suspend: cam_sensor_mclk0_suspend {
+		/* MCLK0 */
+		mux {
+			pins = "gpio67";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio67";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk1_active: cam_sensor_mclk1_active {
+		/* MCLK1 */
+		mux {
+			pins = "gpio68";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio68";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk1_suspend: cam_sensor_mclk1_suspend {
+		/* MCLK1 */
+		mux {
+			pins = "gpio68";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio68";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk2_active: cam_sensor_mclk2_active {
+		/* MCLK2 */
+		mux {
+			pins = "gpio69";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio69";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk2_suspend: cam_sensor_mclk2_suspend {
+		/* MCLK2 */
+		mux {
+			pins = "gpio69";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio69";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+};
+
+&soc {
+	qcom,cam-req-mgr {
+		compatible = "qcom,cam-req-mgr";
+		status = "ok";
+	};
+
+	qcom,cam-sync {
+		compatible = "qcom,cam-sync";
+		status = "ok";
+	};
+
+	qcom,cam-i3c-id-table {
+		i3c-sensor-id-table = <0x1B0 0x0766>;
+		i3c-eeprom-id-table = <>;
+		i3c-actuator-id-table = <>;
+		i3c-ois-id-table = <>;
+		status = "disabled";
+	};
+
+	cam_csiphy_tpg13: qcom,tpg13@acac000 {
+		cell-index = <13>;
+		phy-id = <0>;
+		compatible = "qcom,cam-tpg1031";
+		reg-names = "tpg0", "cam_cpas_top";
+		reg = <0x0 0xacac000 0x0 0x400>,
+			<0x0 0xac11000 0x0 0x1000>;
+		reg-cam-base = <0xac000 0x11000>;
+		operating-points-v2 = <&csiphy_tpg0_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		interrupt-names = "tpg0";
+		interrupts = <GIC_SPI 545 IRQ_TYPE_EDGE_RISING>;
+		shared-clks = <1 0>;
+		clock-names =
+			"cphy_rx_clk_src",
+			"csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cphy_rx_clk_src";
+		status = "ok";
+		csiphy_tpg0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy_tpg14: qcom,tpg14@acad000 {
+		cell-index = <14>;
+		phy-id = <1>;
+		compatible = "qcom,cam-tpg1031";
+		reg-names = "tpg1", "cam_cpas_top";
+		reg = <0x0 0xacad000 0x0 0x400>,
+			<0x0 0xac11000 0x0 0x1000>;
+		reg-cam-base = <0xad000 0x11000>;
+		operating-points-v2 = <&csiphy_tpg1_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		interrupt-names = "tpg1";
+		interrupts = <GIC_SPI 546 IRQ_TYPE_EDGE_RISING>;
+		shared-clks = <1 0>;
+		clock-names =
+			"cphy_rx_clk_src",
+			"csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cphy_rx_clk_src";
+		status = "ok";
+		csiphy_tpg1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy_tpg15: qcom,tpg15@acae000 {
+		cell-index = <15>;
+		phy-id = <2>;
+		compatible = "qcom,cam-tpg1031";
+		reg-names = "tpg2", "cam_cpas_top";
+		reg = <0x0 0xacae000 0x0 0x400>,
+			<0x0 0xac11000 0x0 0x1000>;
+		reg-cam-base = <0xae000 0x11000>;
+		operating-points-v2 = <&csiphy_tpg2_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		interrupt-names = "tpg2";
+		interrupts = <GIC_SPI 547 IRQ_TYPE_EDGE_RISING>;
+		shared-clks = <1 0>;
+		clock-names =
+			"cphy_rx_clk_src",
+			"csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cphy_rx_clk_src";
+		status = "ok";
+		csiphy_tpg2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy0: qcom,csiphy0@ac9c000 {
+		cell-index = <0>;
+		aggregator-rx;
+		compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy";
+		reg = <0x0 0x0ac9c000 0x0 0x2000>;
+		reg-names = "csiphy";
+		operating-points-v2 = <&csiphy0_opp_table>;
+		reg-cam-base = <0x9c000>;
+		interrupt-names = "CSIPHY0";
+		interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>;
+		csi-vdd-1p2-supply = <&vreg_l5a>;
+		csi-vdd-0p9-supply = <&vreg_l4a>;
+		regulator-names = "csi-vdd-1p2", "csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1200000 880000>;
+		rgltr-max-voltage = <1200000 912000>;
+		rgltr-load-current = <8900 15900>;
+		shared-clks = <1 0 0 0>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy0_clk",
+			"csi0phytimer_clk_src",
+			"csi0phytimer_clk";
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY0_CLK>,
+			<&camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI0PHYTIMER_CLK>;
+		src-clock-name = "cphy_rx_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates =
+			<400000000 0 400000000 0>;
+		status = "ok";
+		csiphy0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy1: qcom,csiphy1@ac9e000 {
+		cell-index = <1>;
+		aggregator-rx;
+		compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy";
+		reg = <0x0 0xac9e000 0x0 0x2000>;
+		reg-names = "csiphy";
+		operating-points-v2 = <&csiphy1_opp_table>;
+		reg-cam-base = <0x9e000>;
+		interrupt-names = "CSIPHY1";
+		interrupts = <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>;
+		csi-vdd-1p2-supply = <&vreg_l5a>;
+		csi-vdd-0p9-supply = <&vreg_l4a>;
+		regulator-names = "csi-vdd-1p2", "csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1200000 880000>;
+		rgltr-max-voltage = <1200000 912000>;
+		rgltr-load-current = <8900 15900>;
+		shared-clks = <1 0 0 0>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy1_clk",
+			"csi1phytimer_clk_src",
+			"csi1phytimer_clk";
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY1_CLK>,
+			<&camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI1PHYTIMER_CLK>;
+		src-clock-name = "cphy_rx_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates =
+			<400000000 0 400000000 0>;
+		status = "ok";
+		csiphy1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy2: qcom,csiphy2@aca0000 {
+		cell-index = <2>;
+		aggregator-rx;
+		compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy";
+		reg = <0x0 0xaca0000 0x0 0x2000>;
+		reg-names = "csiphy";
+		operating-points-v2 = <&csiphy2_opp_table>;
+		reg-cam-base = <0xa0000>;
+		interrupt-names = "CSIPHY2";
+		interrupts = <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>;
+		csi-vdd-1p2-supply = <&vreg_l5a>;
+		csi-vdd-0p9-supply = <&vreg_l4a>;
+		regulator-names = "csi-vdd-1p2", "csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1200000 880000>;
+		rgltr-max-voltage = <1200000 912000>;
+		rgltr-load-current = <8900 15900>;
+		shared-clks = <1 0 0 0>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy2_clk",
+			"csi2phytimer_clk_src",
+			"csi2phytimer_clk";
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY2_CLK>,
+			<&camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI2PHYTIMER_CLK>;
+		src-clock-name = "cphy_rx_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates =
+			<400000000 0 400000000 0>;
+		status = "ok";
+		csiphy2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_cci0: qcom,cci0@ac13000 {
+		cell-index = <0>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac13000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x13000>;
+		interrupt-names = "CCI0";
+		interrupts = <GIC_SPI 460 IRQ_TYPE_EDGE_RISING>;
+		operating-points-v2 = <&cci0_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cci_0_clk_src",
+			"cci_0_clk";
+		clocks = <&camcc CAM_CC_CCI_0_CLK_SRC>,
+			<&camcc CAM_CC_CCI_0_CLK>;
+		clock-rates = <37500000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cci_0_clk_src";
+		pctrl-idx-mapping = <CCI_MASTER_0 CCI_MASTER_1>;
+		pctrl-map-names = "m0", "m1";
+		pinctrl-names = "m0_active", "m0_suspend",
+			"m1_active", "m1_suspend";
+		pinctrl-0 = <&cci_i2c_scl0_active &cci_i2c_sda0_active>;
+		pinctrl-1 = <&cci_i2c_scl0_suspend &cci_i2c_sda0_suspend>;
+		pinctrl-2 = <&cci_i2c_scl1_active &cci_i2c_sda1_active>;
+		pinctrl-3 = <&cci_i2c_scl1_suspend &cci_i2c_sda1_suspend>;
+		status = "ok";
+		cci0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci0: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci0: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci0: qcom,i2c_custom_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci0: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	cam_cci1: qcom,cci1@ac14000 {
+		cell-index = <1>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac14000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x14000>;
+		interrupt-names = "CCI1";
+		interrupts = <GIC_SPI 271 IRQ_TYPE_EDGE_RISING>;
+		operating-points-v2 = <&cci1_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cci_1_clk_src",
+			"cci_1_clk";
+		clocks = <&camcc CAM_CC_CCI_1_CLK_SRC>,
+			<&camcc CAM_CC_CCI_1_CLK>;
+		clock-rates = <37500000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cci_1_clk_src";
+		pctrl-idx-mapping = <CCI_MASTER_0 CCI_MASTER_1>;
+		pctrl-map-names = "m0", "m1";
+		pinctrl-names = "m0_active", "m0_suspend",
+			"m1_active", "m1_suspend";
+		pinctrl-0 = <&cci_i2c_scl2_active &cci_i2c_sda2_active>;
+		pinctrl-1 = <&cci_i2c_scl2_suspend &cci_i2c_sda2_suspend>;
+		pinctrl-2 = <&cci_i2c_scl3_active &cci_i2c_sda3_active>;
+		pinctrl-3 = <&cci_i2c_scl3_suspend &cci_i2c_sda3_suspend>;
+		status = "ok";
+		cci1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci1: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci1: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci1: qcom,i2c_custom_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci1: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	cam_cci2: qcom,cci2@ac15000 {
+		cell-index = <2>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac15000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x15000>;
+		interrupt-names = "CCI2";
+		interrupts = <GIC_SPI 651 IRQ_TYPE_EDGE_RISING>;
+		operating-points-v2 = <&cci2_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cci_2_clk_src",
+			"cci_2_clk";
+		clocks = <&camcc CAM_CC_CCI_2_CLK_SRC>,
+			<&camcc CAM_CC_CCI_2_CLK>;
+		clock-rates = <37500000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cci_2_clk_src";
+		pctrl-idx-mapping = <CCI_MASTER_0 CCI_MASTER_1>;
+		pctrl-map-names = "m0", "m1";
+		pinctrl-names = "m0_active", "m0_suspend",
+			"m1_active", "m1_suspend";
+		pinctrl-0 = <&cci_i2c_scl4_active &cci_i2c_sda4_active>;
+		pinctrl-1 = <&cci_i2c_scl4_suspend &cci_i2c_sda4_suspend>;
+		pinctrl-2 = <&cci_i2c_scl5_active &cci_i2c_sda5_active>;
+		pinctrl-3 = <&cci_i2c_scl5_suspend &cci_i2c_sda5_suspend>;
+		status = "ok";
+		cci2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci2: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci2: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci2: qcom,i2c_custom_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci2: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	qcom,cam_smmu {
+		compatible = "qcom,msm-cam-smmu", "simple-bus";
+		status = "ok";
+		force_cache_allocs;
+
+		msm_cam_smmu_ife {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x2400 0x0020>,
+				<&apps_smmu 0x2420 0x0020>;
+			cam-smmu-label = "ife", "sfe";
+			multiple-client-devices;
+			dma-coherent;
+			ife_iova_mem_map: iova-mem-map {
+				/* IO region is approximately 64 GB */
+				iova-mem-region-io {
+					iova-region-name = "io";
+					/* start address: 0x100000 */
+					/* leaving 1 MB pad at start  */
+					iova-region-start = <0x100000>;
+					/* Length: 0xfffe00000 */
+					/* leaving 1 MB pad at end */
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_icp {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus =
+				<&apps_smmu 0x0800 0x400>,
+				<&apps_smmu 0x0840 0x480>,
+				<&apps_smmu 0x08C0 0x480>,
+				<&apps_smmu 0x0C00 0x400>,
+				<&apps_smmu 0x0C40 0x480>,
+				<&apps_smmu 0x0CC0 0x480>;
+			cam-smmu-label = "icp";
+			qcom,iommu-faults = "stall-disable", "non-fatal";
+			dma-coherent;
+			icp_iova_mem_map: iova-mem-map {
+				iova-mem-region-shared {
+					/* Shared region is ~250MB long */
+					iova-region-name = "shared";
+					iova-region-start = <0x800000>;
+					iova-region-len = <0xfc00000>;
+					iova-region-id = <0x1>;
+					status = "ok";
+				};
+
+				iova-mem-region-fwuncached-region {
+					/* FW uncached region is 7MB long */
+					iova-region-name = "fw_uncached";
+					iova-region-start = <0x10400000>;
+					iova-region-len = <0x700000>;
+					iova-region-id = <0x6>;
+					subregion_support;
+					status = "ok";
+					/* Used for HFI queues/sec heap */
+					iova-mem-region-generic-region {
+						iova-region-name = "icp_hfi";
+						iova-region-start = <0x10400000>;
+						iova-region-len = <0x200000>;
+						iova-region-id = <0x0>;
+					};
+				};
+
+				iova-mem-region-io {
+					/* IO region is approximately 3.8 GB */
+					iova-region-name = "io";
+					iova-region-start = <0x10c00000>;
+					iova-region-len = <0xee300000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+
+				iova-mem-qdss-region {
+					/* QDSS region is appropriate 1MB */
+					iova-region-name = "qdss";
+					iova-region-start = <0x10b00000>;
+					iova-region-len = <0x100000>;
+					iova-region-id = <0x5>;
+					qdss-phy-addr = <0x16790000>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_cdm {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x0860 0x400>,
+				<&apps_smmu 0x0C60 0x400>;
+			cam-smmu-label = "rt-cdm";
+			dma-coherent;
+			multiple-client-devices;
+			rt_cdm_iova_mem_map: iova-mem-map {
+				iova-mem-region-io {
+					/* IO region is approximately 4.0 GB */
+					iova-region-name = "io";
+					/* 1 MB pad for start */
+					iova-region-start = <0x100000>;
+					/* 1 MB pad for end */
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_secure {
+			compatible = "qcom,msm-cam-smmu-cb";
+			cam-smmu-label = "cam-secure";
+			qcom,secure-cb;
+		};
+	};
+
+	qcom,cam-cdm-intf {
+		compatible = "qcom,cam-cdm-intf";
+		cell-index = <0>;
+		label = "cam-cdm-intf";
+		num-hw-cdm = <1>;
+		cdm-client-names = "vfe";
+		status = "ok";
+	};
+
+	qcom,rt-cdm0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac26000 0x0 0x1000>;
+		reg-names = "rt-cdm0";
+		reg-cam-base = <0x26000>;
+		interrupts = <GIC_SPI 543 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm0";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_fast_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_fast_ahb_clk_src";
+		clock-rates = <300000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table0>;
+		clock-cntl-level = "svs";
+		cdm-client-names = "ife0", "dualife0";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table0: opp-table {
+			compatible = "operating-points-v2";
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,rt-cdm1 {
+		cell-index = <1>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac27000 0x0 0x1000>;
+		reg-names = "rt-cdm1";
+		reg-cam-base = <0x27000>;
+		interrupts = <GIC_SPI 544 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm1";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_fast_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_fast_ahb_clk_src";
+		clock-rates = <300000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table1>;
+		clock-cntl-level = "svs_l1";
+		cdm-client-names = "ife1", "dualife1";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table1: opp-table {
+			compatible = "operating-points-v2";
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,rt-cdm2 {
+		cell-index = <2>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac28000 0x0 0x1000>;
+		reg-names = "rt-cdm2";
+		reg-cam-base = <0x28000>;
+		interrupts = <GIC_SPI 567 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm2";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_slow_ahb_clk_src";
+		clock-rates = <80000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table2>;
+		clock-cntl-level = "svs_l1";
+		cdm-client-names = "ife2", "ife3", "ife4", "ife5", "ife6";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table2: opp-table {
+			compatible = "operating-points-v2";
+			opp-80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,rt-cdm3 {
+		cell-index = <3>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac29000 0x0 0x1000>;
+		reg-names = "rt-cdm3";
+		reg-cam-base = <0x29000>;
+		interrupts = <GIC_SPI 566 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm3";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_slow_ahb_clk_src";
+		clock-rates = <80000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table3>;
+		clock-cntl-level = "svs";
+		cdm-client-names = "ife2", "ife3", "ife4", "ife5", "ife6";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table3: opp-table {
+			compatible = "operating-points-v2";
+			opp-80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,cam-isp {
+		compatible = "qcom,cam-isp";
+		arch-compat = "ife";
+		status = "ok";
+	};
+
+	cam_csid0: qcom,csid0 {
+		cell-index = <0>;
+		compatible = "qcom,csid692";
+		reg-names = "csid0", "csid_top";
+		reg = <0x0 0xac7a000 0x0 0xf01>,
+			<0x0 0xac78000 0x0 0x1000>;
+		reg-cam-base = <0x7a000 0x78000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "csid0";
+		interrupts = <GIC_SPI 565 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_csid_clk_src",
+			"cam_cc_csid_clk",
+			"cam_cc_csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CSID_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CLK>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0 0>;
+		clock-cntl-level = "svs_l1";
+		src-clock-name = "cam_cc_csid_clk_src";
+		operating-points-v2 = <&csid0_opp_table>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+		};
+	};
+
+	cam_vfe0: qcom,ife0 {
+		cell-index = <0>;
+		compatible = "qcom,vfe692";
+		reg-names = "ife0", "cam_camnoc";
+		reg = <0x0 0xac4d000 0x0 0xf000>,
+			<0x0 0xac1a000 0x0 0x9400>;
+		reg-cam-base = <0x4d000 0x1a000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "ife0";
+		interrupts = <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_0_clk",
+			"cam_cc_ife_0_clk",
+			"cam_cc_ife_0_clk_src",
+			"cam_cc_ife_0_fast_ahb_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_0_CLK>,
+			<&camcc CAM_CC_IFE_0_CLK>,
+			<&camcc CAM_CC_IFE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_0_FAST_AHB_CLK>;
+		clock-rates =
+			<0 0 480000000 0>,
+			<0 0 600000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_0_clk_src";
+		operating-points-v2 = <&vfe0_opp_table>;
+		clock-control-debugfs = "true";
+		ubwc-static-cfg = <0x1026 0x1036>;
+		cam_hw_pid = <8 16>;
+		status = "ok";
+		vfe0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid1: qcom,csid1 {
+		cell-index = <1>;
+		compatible = "qcom,csid692";
+		reg-names = "csid1", "csid_top";
+		reg = <0x0 0xac7c000 0x0 0xf01>,
+			<0x0 0xac78000 0x0 0x1000>;
+		reg-cam-base = <0x7c000 0x78000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "csid1";
+		interrupts = <GIC_SPI 564 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_csid_clk_src",
+			"cam_cc_csid_clk",
+			"cam_cc_csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CSID_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CLK>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0 0>;
+		clock-cntl-level = "svs_l1";
+		src-clock-name = "cam_cc_csid_clk_src";
+		operating-points-v2 = <&csid1_opp_table>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+		};
+	};
+
+	cam_vfe1: qcom,ife1 {
+		cell-index = <1>;
+		compatible = "qcom,vfe692";
+		reg-names = "ife1", "cam_camnoc";
+		reg = <0x0 0xac60000 0x0 0xf000>,
+			<0x0 0xac1a000 0x0 0x9400>;
+		reg-cam-base = <0x60000 0x1a000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "ife1";
+		interrupts = <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_1_clk",
+			"cam_cc_ife_1_clk",
+			"cam_cc_ife_1_clk_src",
+			"cam_cc_ife_1_fast_ahb_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_1_CLK>,
+			<&camcc CAM_CC_IFE_1_CLK>,
+			<&camcc CAM_CC_IFE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_1_FAST_AHB_CLK>;
+		clock-rates =
+			<0 0 480000000 0>,
+			<0 0 600000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_1_clk_src";
+		operating-points-v2 = <&vfe1_opp_table>;
+		clock-control-debugfs = "true";
+		ubwc-static-cfg = <0x1026 0x1036>;
+		cam_hw_pid = <9 17>;
+		status = "ok";
+		vfe1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite0: qcom,csid-lite0 {
+		cell-index = <2>;
+		compatible = "qcom,csid-lite692";
+		reg-names = "csid-lite0";
+		reg = <0x0 0xac84000 0x0 0xf01>;
+		reg-cam-base = <0x84000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite0";
+		interrupts = <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite0_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite0: qcom,ife-lite0 {
+		cell-index = <2>;
+		compatible = "qcom,vfe-lite692";
+		reg-names = "ife-lite0";
+		reg = <0x0 0xac84000 0x0 0x1d00>;
+		reg-cam-base = <0x84000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite0";
+		interrupts = <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite0_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite1: qcom,csid-lite1 {
+		cell-index = <3>;
+		compatible = "qcom,csid-lite692";
+		reg-names = "csid-lite1";
+		reg = <0x0 0xac88000 0x0 0xf01>;
+		reg-cam-base = <0x88000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite1";
+		interrupts = <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite1_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite1: qcom,ife-lite1 {
+		cell-index = <3>;
+		compatible = "qcom,vfe-lite692";
+		reg-names = "ife-lite1";
+		reg = <0x0 0xac88000 0x0 0x1d00>;
+		reg-cam-base = <0x88000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite1";
+		interrupts = <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite1_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite2: qcom,csid-lite2 {
+		cell-index = <4>;
+		compatible = "qcom,csid-lite692";
+		reg-names = "csid-lite2";
+		reg = <0x0 0xac8c000 0x0 0xf01>;
+		reg-cam-base = <0x8c000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite2";
+		interrupts = <GIC_SPI 759 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite2_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite2: qcom,ife-lite2 {
+		cell-index = <4>;
+		compatible = "qcom,vfe-lite692";
+		reg-names = "ife-lite2";
+		reg = <0x0 0xac8c000 0x0 0x1d00>;
+		reg-cam-base = <0x8c000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite2";
+		interrupts = <GIC_SPI 761 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite2_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite3: qcom,csid-lite3 {
+		cell-index = <5>;
+		compatible = "qcom,csid-lite692";
+		reg-names = "csid-lite3";
+		reg = <0x0 0xac90000 0x0 0xf01>;
+		reg-cam-base = <0x90000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite3";
+		interrupts = <GIC_SPI 758 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite3_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite3: qcom,ife-lite3 {
+		cell-index = <5>;
+		compatible = "qcom,vfe-lite692";
+		reg-names = "ife-lite3";
+		reg = <0x0 0xac90000 0x0 0x1d00>;
+		reg-cam-base = <0x90000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite3";
+		interrupts = <GIC_SPI 760 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite3_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite4: qcom,csid-lite4 {
+		cell-index = <6>;
+		compatible = "qcom,csid-lite692";
+		reg-names = "csid-lite4";
+		reg = <0x0 0xac94000 0x0 0xf01>;
+		reg-cam-base = <0x94000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite4";
+		interrupts = <GIC_SPI 604 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite4_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite4_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite4: qcom,ife-lite4 {
+		cell-index = <6>;
+		compatible = "qcom,vfe-lite692";
+		reg-names = "ife-lite4";
+		reg = <0x0 0xac94000 0x0 0x1d00>;
+		reg-cam-base = <0x94000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite4";
+		interrupts = <GIC_SPI 605 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite4_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite4_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_sfe_lite0: qcom,sfe-lite0 {
+		cell-index = <0>;
+		compatible = "qcom,sfe-lite692";
+		reg-names = "sfe-lite0";
+		reg = <0x0 0xac74000 0x0 0x1000>;
+		reg-cam-base = <0x74000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "sfe-lite0";
+		interrupts = <GIC_SPI 563 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_sfe_lite_0_fast_ahb_clk",
+			"cam_cc_sfe_lite_0_clk",
+			"cam_cc_cpas_sfe_lite_0_clk";
+		clocks =
+			<&camcc CAM_CC_SFE_LITE_0_FAST_AHB_CLK>,
+			<&camcc CAM_CC_SFE_LITE_0_CLK>,
+			<&camcc CAM_CC_CPAS_SFE_LITE_0_CLK>;
+		clock-rates =
+			<0 480000000 300000000>,
+			<0 600000000 400000000>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_sfe_lite_0_clk";
+		operating-points-v2 = <&cam_sfe_lite_opp_table0>;
+		cam_hw_pid = <4>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		cam_sfe_lite_opp_table0: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_sfe_lite1: qcom,sfe-lite1 {
+		cell-index = <1>;
+		compatible = "qcom,sfe-lite692";
+		reg-names = "sfe-lite1";
+		reg = <0x0 0xac75000 0x0 0x1000>;
+		reg-cam-base = <0x75000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "sfe-lite1";
+		interrupts = <GIC_SPI 562 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_sfe_lite_1_fast_ahb_clk",
+			"cam_cc_sfe_lite_1_clk",
+			"cam_cc_cpas_sfe_1_clk";
+		clocks =
+			<&camcc CAM_CC_SFE_LITE_1_FAST_AHB_CLK>,
+			<&camcc CAM_CC_SFE_LITE_1_CLK>,
+			<&camcc CAM_CC_CPAS_SFE_LITE_1_CLK>;
+		clock-rates =
+			<0 480000000 300000000>,
+			<0 600000000 400000000>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_sfe_lite_1_clk";
+		operating-points-v2 = <&cam_sfe_lite_opp_table1>;
+		cam_hw_pid = <5>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		cam_sfe_lite_opp_table1: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-icp {
+		compatible = "qcom,cam-icp";
+		compat-hw-name = "qcom,icp",
+			"qcom,ipe0";
+		num-icp = <1>;
+		num-ipe = <1>;
+		icp_use_pil;
+		status = "ok";
+	};
+
+	cam_icp: qcom,icp {
+		cell-index = <0>;
+		compatible = "qcom,cam-icp_v3_0";
+		icp-version = <0x0300>;
+
+		reg-names ="icp_csr", "icp_cirq", "icp_wd0";
+		reg = <0x0 0xac01000 0x0 0x400>,
+			<0x0 0xac01800 0x0 0x400>,
+			<0x0 0xac04000 0x0 0x1000>;
+		reg-cam-base = <0x1000 0x1800 0x4000>;
+		interrupt-names = "icp";
+		interrupts = <GIC_SPI 463 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		memory-region = <&camera_mem>;
+		clock-names =
+			"cam_cc_soc_fast_ahb_clk_src",
+			"cam_cc_icp_ahb_clk",
+			"cam_cc_icp_clk_src",
+			"cam_cc_icp_clk";
+		src-clock-name = "cam_cc_icp_clk_src";
+		clocks =
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_ICP_AHB_CLK>,
+			<&camcc CAM_CC_ICP_CLK_SRC>,
+			<&camcc CAM_CC_ICP_CLK>;
+		clock-rates =
+			<300000000 0 480000000 0>,
+			<400000000 0 600000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		nrt-device;
+		fw_name = "CAMERA_ICP";
+		ubwc-ipe-fetch-cfg = <0x707b 0x7083>;
+		ubwc-ipe-write-cfg = <0x161ef 0x1620f>;
+		qos-val = <0xa0a>;
+		operating-points-v2 = <&icp_opp_table>;
+		cam_hw_pid = <12>;
+		status = "ok";
+		icp_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_ipe0: qcom,ipe0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-ipe";
+		reg-names = "ipe0_top";
+		reg = <0x0 0xac2d000 0x0 0x18000>;
+		reg-cam-base = <0x2d000>;
+
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+
+		clock-names =
+			"cam_cc_cpas_ipe_clk",
+			"cam_cc_ipe_ahb_clk",
+			"cam_cc_ipe_clk",
+			"cam_cc_ipe_clk_src",
+			"cam_cc_ipe_fast_ahb_clk",
+			"cam_cc_fast_ahb_clk_src";
+		src-clock-name = "cam_cc_ipe_clk_src";
+		clocks =
+			<&camcc CAM_CC_CPAS_IPE_CLK>,
+			<&camcc CAM_CC_IPE_AHB_CLK>,
+			<&camcc CAM_CC_IPE_CLK>,
+			<&camcc CAM_CC_IPE_CLK_SRC>,
+			<&camcc CAM_CC_IPE_FAST_AHB_CLK>,
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>;
+		clock-rates =
+			<0 0 0 480000000 0 300000000>,
+			<0 0 0 600000000 0 400000000>;
+		clock-cntl-level = "svs_l1", "nominal";
+
+		operating-points-v2 = <&ipe0_opp_table>;
+		nrt-device;
+		cam_hw_pid = <14 15>;
+		status = "ok";
+
+		ipe0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+
+	};
+
+	qcom,cam-cpas {
+		cell-index = <0>;
+		compatible = "qcom,cam-cpas";
+		label = "cpas";
+		arch-compat = "cpas_top";
+		reg-names = "cam_cpas_top", "cam_camnoc", "cam_rpmh";
+		reg = <0x0 0xac11000 0x0 0x1000>,
+			<0x0 0xac1A000 0x0 0x9400>,
+			<0x0 0xbbf0000 0x0 0x1f00>;
+		reg-cam-base = <0x11000 0x1A000 0x0bbf0000>;
+		interrupt-names = "cpas_camnoc";
+		interrupts = <GIC_SPI 459 IRQ_TYPE_EDGE_RISING>;
+		camnoc-axi-min-ib-bw = <3000000000>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"gcc_camera_ahb_clk",
+			"gcc_camera_hf_axi_clk",
+			"gcc_camera_sf_axi_clk",
+			"cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk",
+			"cam_cc_core_ahb_clk",
+			"cam_cc_fast_ahb_clk_src",
+			"cam_cc_cpas_fast_ahb_clk",
+			"cam_cc_camnoc_axi_clk_src",
+			"cam_cc_camnoc_axi_clk",
+			"cam_cc_qdss_debug_xo_clk";
+		clocks =
+			<&gcc GCC_CAMERA_AHB_CLK>,
+			<&gcc GCC_CAMERA_HF_AXI_CLK>,
+			<&gcc GCC_CAMERA_SF_AXI_CLK>,
+			<&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>,
+			<&camcc CAM_CC_CORE_AHB_CLK>,
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_FAST_AHB_CLK>,
+			<&camcc CAM_CC_CAMNOC_AXI_CLK_SRC>,
+			<&camcc CAM_CC_CAMNOC_AXI_CLK>,
+			<&camcc CAM_CC_QDSS_DEBUG_XO_CLK>;
+		src-clock-name = "cam_cc_fast_ahb_clk_src";
+		clock-rates =
+			<0 0 0 0 0 0 0 0 0 0 0>,
+			<0 0 0 80000000 0 0 300000000 0 400000000 0 0>,
+			<0 0 0 80000000 0 0 400000000 0 400000000 0 0>;
+		clock-cntl-level = "suspend", "svs_l1", "nominal";
+		clock-names-option = "cam_icp_clk";
+		clocks-option = <&camcc CAM_CC_ICP_CLK>;
+		clock-rates-option = <480000000>;
+		operating-points-v2 = <&cpas_opp_table>;
+		control-camnoc-axi-clk;
+		camnoc-bus-width = <32>;
+		camnoc-axi-clk-bw-margin-perc = <20>;
+		cam-icc-path-names = "cam_ahb";
+		interconnect-names = "cam_ahb", "cam_hf_0", "cam_sf_0", "cam_sf_icp";
+		interconnects =<&gem_noc MASTER_APPSS_PROC 0
+			&config_noc SLAVE_CAMERA_CFG 0>,
+				<&mmss_noc MASTER_CAMNOC_HF 0
+			&mc_virt SLAVE_EBI1 0>,
+				<&mmss_noc MASTER_CAMNOC_SF 0
+			&mc_virt SLAVE_EBI1 0>,
+				<&mmss_noc MASTER_CAMNOC_ICP 0
+			&mc_virt SLAVE_EBI1 0>;
+		cam-ahb-num-cases = <7>;
+		cam-ahb-bw-KBps =
+			<0 0>, <0 76800>, <0 150000>, <0 150000>,
+			<0 300000>, <0 300000>, <0 300000>;
+		vdd-corners = <RPMH_REGULATOR_LEVEL_RETENTION
+			RPMH_REGULATOR_LEVEL_MIN_SVS
+			RPMH_REGULATOR_LEVEL_LOW_SVS
+			RPMH_REGULATOR_LEVEL_SVS
+			RPMH_REGULATOR_LEVEL_SVS_L1
+			RPMH_REGULATOR_LEVEL_NOM
+			RPMH_REGULATOR_LEVEL_NOM_L1
+			RPMH_REGULATOR_LEVEL_NOM_L2
+			RPMH_REGULATOR_LEVEL_TURBO
+			RPMH_REGULATOR_LEVEL_TURBO_L1>;
+		vdd-corner-ahb-mapping = "suspend",
+			"lowsvs", "lowsvs", "svs", "svs_l1",
+			"nominal", "nominal", "nominal",
+			"turbo", "turbo";
+		client-id-based;
+		client-names =
+			"csiphy0", "csiphy1", "csiphy2",
+			"cci0", "cci1", "cci2",
+			"csid0", "csid1", "csid2", "csid3",
+			"csid4", "csid5", "csid6", "ife0",
+			"ife1",	"ife2", "ife3", "ife4",
+			"ife5",	"ife6", "ipe0", "sfe0", "sfe1",
+			"cam-cdm-intf0", "rt-cdm0", "rt-cdm1", "rt-cdm2",
+			"rt-cdm3", "icp0", "tpg13", "tpg14", "tpg15";
+
+		status = "ok";
+		enable-secure-qos-update;
+		cpas_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+
+		camera-bus-nodes {
+			level3-nodes {
+				level-index = <3>;
+				level3_rt_rd_wr_sum: level3-rt-rd-wr-sum {
+					cell-index = <0>;
+					node-name = "level3-rt-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					ib-bw-voting-needed;
+					qcom,axi-port-mnoc {
+						cam-icc-path-names = "cam_hf_0";
+					};
+				};
+
+				level3_nrt0_rd_wr_sum: level3-nrt0-rd-wr-sum {
+					cell-index = <1>;
+					node-name = "level3-nrt0-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					qcom,axi-port-mnoc {
+						cam-icc-path-names = "cam_sf_0";
+					};
+				};
+
+				level3_nrt1_rd_wr_sum: level3-nrt1-rd-wr-sum {
+					cell-index = <2>;
+					node-name = "level3-nrt1-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					qcom,axi-port-mnoc {
+						cam-icc-path-names = "cam_sf_icp";
+					};
+				};
+			};
+
+			level2-nodes {
+				level-index = <2>;
+				camnoc-max-needed;
+				level2_rt_wr0: level2-rt-wr0 {
+					cell-index = <3>;
+					node-name = "level2-rt-wr0";
+					parent-node = <&level3_rt_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_rt_wr1: level2-rt-wr1 {
+					cell-index = <4>;
+					node-name = "level2-rt-wr1";
+					parent-node = <&level3_rt_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt_wr2: level2-nrt-wr2 {
+					cell-index = <5>;
+					node-name = "level2-nrt-wr2";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_rt_rd0: level2-rt-read0 {
+					cell-index = <6>;
+					node-name = "level2-rt-rd0";
+					parent-node = <&level3_rt_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt_rd1: level2-nrt-rd1 {
+					cell-index = <7>;
+					node-name = "level2-nrt-rd1";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt_rd2: level2-nrt-rd2 {
+					cell-index = <8>;
+					node-name = "level2-nrt-rd2";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_icp_rd: level2-icp-rd {
+					cell-index = <9>;
+					node-name = "level2-icp-rd";
+					parent-node = <&level3_nrt1_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+			};
+
+			level1-nodes {
+				level-index = <1>;
+				camnoc-max-needed;
+				level1_rt_wr0: level1-rt-wr0 {
+					cell-index = <10>;
+					node-name = "level1-rt-wr0";
+					parent-node = <&level2_rt_wr0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_rt_wr1: level1-rt-wr1 {
+					cell-index = <11>;
+					node-name = "level1-rt-wr1";
+					parent-node = <&level2_rt_wr1>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_rt_rd0: level1-rt-read0 {
+					cell-index = <13>;
+					node-name = "level1-rt-rd0";
+					parent-node = <&level2_rt_rd0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt_rd2: level1-nrt-rd2 {
+					cell-index = <15>;
+					node-name = "level1-nrt-rd2";
+					parent-node = <&level2_nrt_rd2>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+			};
+
+			level0-nodes {
+				level-index = <0>;
+				ife_0_wr_0: ife-0-wr-0 {
+					cell-index = <16>;
+					node-name = "ife-0-wr-0";
+					client-name = "ife0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_1_wr_0: ife-1-wr-0 {
+					cell-index = <17>;
+					node-name = "ife-1-wr-0";
+					client-name = "ife1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_0_wr_0: ife-lite-0-wr-0 {
+					cell-index = <18>;
+					node-name = "ife-lite-0-wr-0";
+					client-name = "ife2";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_1_wr_0: ife-lite-1-wr-0 {
+					cell-index = <19>;
+					node-name = "ife-lite-1-wr-0";
+					client-name = "ife3";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_2_wr_0: ife-lite-2-wr-0 {
+					cell-index = <20>;
+					node-name = "ife-lite-2-wr-0";
+					client-name = "ife4";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_3_wr_0: ife-lite-3-wr-0 {
+					cell-index = <21>;
+					node-name = "ife-lite-3-wr-0";
+					client-name = "ife5";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_4_wr_0: ife-lite-4-wr-0 {
+					cell-index = <22>;
+					node-name = "ife-lite-4-wr-0";
+					client-name = "ife6";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_0_wr_1: ife-0-wr-1 {
+					cell-index = <23>;
+					node-name = "ife-0-wr-1";
+					client-name = "ife0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_UBWC>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_DISP>;
+					parent-node = <&level1_rt_wr1>;
+				};
+				ife_1_wr_1: ife-1-wr-1 {
+					cell-index = <24>;
+					node-name = "ife-1-wr-1";
+					client-name = "ife1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_UBWC>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_DISP>;
+					parent-node = <&level1_rt_wr1>;
+				};
+				sfe_0_rd_0: sfe-0-rd-0 {
+					cell-index = <25>;
+					node-name = "sfe-0-rd-0";
+					client-name = "sfe0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_SFE_NRDI>;
+					parent-node = <&level1_rt_rd0>;
+				};
+				sfe_1_rd_0: sfe-1-rd-0 {
+					cell-index = <26>;
+					node-name = "sfe-1-rd-0";
+					client-name = "sfe1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_SFE_NRDI>;
+					parent-node = <&level1_rt_rd0>;
+				};
+				ipe_0_wr_2: ipe-0-wr-2 {
+					cell-index = <27>;
+					node-name = "ipe-0-wr-2";
+					client-name = "ipe0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IPE_WR_VID
+					CAM_CPAS_PATH_DATA_IPE_WR_DISP
+					CAM_CPAS_PATH_DATA_IPE_WR_REF
+					CAM_CPAS_PATH_DATA_IPE_WR_APP>;
+					parent-node = <&level2_nrt_wr2>;
+				};
+				ipe_0_rd_all: ipe-0-rd-all {
+					cell-index = <28>;
+					node-name = "ipe-0-rd-all";
+					client-name = "ipe0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IPE_RD_IN
+					CAM_CPAS_PATH_DATA_IPE_RD_REF>;
+					parent-node = <&level2_nrt_rd1>;
+				};
+				rt_cdm0_all_rd_2: rt-cdm0-all-rd-2 {
+					cell-index = <29>;
+					node-name = "rt-cdm0-all-rd-2";
+					client-name = "rt-cdm0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				rt_cdm1_all_rd_2: rt-cdm1-all-rd-2 {
+					cell-index = <30>;
+					node-name = "rt-cdm1-all-rd-2";
+					client-name = "rt-cdm1";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				rt_cdm2_all_rd_2: rt-cdm2-all-rd-2 {
+					cell-index = <31>;
+					node-name = "rt-cdm2-all-rd-2";
+					client-name = "rt-cdm2";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				rt_cdm3_all_rd_2: rt-cdm3-all-rd-2 {
+					cell-index = <32>;
+					node-name = "rt-cdm3-all-rd-2";
+					client-name = "rt-cdm3";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				ipe_cdm0_all_rd: ipe-cdm0-all-rd {
+					cell-index = <33>;
+					node-name = "ipe-cdm0-all-rd";
+					client-name = "ipe0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				icp_all_rd: icp-all-rd {
+					cell-index = <34>;
+					node-name = "icp-all-rd";
+					client-name = "icp0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level2_icp_rd>;
+				};
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8300-camera.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8300-camera.dtso
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,qcs8300-gcc.h>
+#include <dt-bindings/clock/qcom,sa8775p-camcc.h>
+#include <dt-bindings/interconnect/qcom,qcs8300-rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+
+#include "qcs8300-camera.dtsi"
+#include "qcs8300-camera-sensor-idp.dtsi"
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8300-dma-heaps.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8300-dma-heaps.dtsi
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/arm/qcom_dma_heap_dt_constants.h>
+
+&soc {
+	qcom,dma-heaps {
+		compatible = "qcom,dma-heaps";
+
+		qcom,qseecom {
+			qcom,dma-heap-name = "qcom,qseecom";
+			qcom,dma-heap-type = <HEAP_TYPE_CMA>;
+			memory-region = <&qseecom_mem>;
+		};
+
+		qcom,qseecom_ta {
+			qcom,dma-heap-name = "qcom,qseecom-ta";
+			qcom,dma-heap-type = <HEAP_TYPE_CMA>;
+			memory-region = <&qseecom_ta_mem>;
+		};
+
+		qcom,secure_cdsp {
+			qcom,dma-heap-name = "qcom,cma-secure-cdsp";
+			qcom,dma-heap-type = <HEAP_TYPE_CMA>;
+			memory-region = <&cdsp_secure_heap>;
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8300-graphics.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8300-graphics.dtsi
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2024-2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+// SPDX-License-Identifier: BSD-3-Clause
+
+#define MHZ_TO_KBPS(mhz, w) ((mhz * 1000000 * w) / (1024))
+
+&soc {
+	msm_gpu: qcom,kgsl-3d0@3d00000 {
+		compatible = "qcom,kgsl";
+		status = "ok";
+		reg = <0 0x3d00000 0 0x40000>, <0 0x3d61000 0 0x800>,
+			<0 0x3de0000 0 0x10000>, <0 0x4900000 0 0x80000>,
+			<0 0x3dff000 0 0x1000>;
+		reg-names = "kgsl_3d0_reg_memory", "cx_dbgc", "rscc",
+			"qdss_gfx", "fusa";
+		interrupts = <0 300 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "kgsl_3d0_irq";
+
+		clocks = <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+			<&gcc GCC_GPU_SNOC_DVM_GFX_CLK>,
+			<&gpucc GPU_CC_AHB_CLK>,
+			<&gpucc GPU_CC_CX_GMU_CLK>,
+			<&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>,
+			<&gpucc GPU_CC_HUB_AON_CLK>,
+			<&gpucc GPU_CC_HUB_CX_INT_CLK>;
+		clock-names = "gcc_gpu_memnoc_gfx",
+				"gcc_gpu_snoc_dvm_gfx",
+				"gpu_cc_ahb",
+				"gpu_cc_cx_gmu",
+				"gpu_cc_hlos1_vote_gpu_smmu",
+				"gpu_cc_hub_aon",
+				"gpu_cc_hub_cx_int";
+
+		qcom,chipid = <0x06020300>;
+		qcom,gpu-model = "Adreno623";
+
+		qcom,min-access-length = <32>;
+
+		qcom,ubwc-mode = <4>;
+
+		qcom,gpu-qdss-stm = <0x161c0000 0x40000>; /* base addr, size */
+
+		qcom,tzone-names = "gpuss-0-usr", "gpuss-1-usr";
+
+		interconnect-names = "gpu_icc_path";
+		interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>;
+		qcom,bus-table-ddr =
+			<MHZ_TO_KBPS(0, 4)>,    /* index=0  */
+			<MHZ_TO_KBPS(200, 4)>,  /* index=1  */
+			<MHZ_TO_KBPS(451, 4)>,  /* index=2  */
+			<MHZ_TO_KBPS(547, 4)>,  /* index=3  */
+			<MHZ_TO_KBPS(681, 4)>,  /* index=4  */
+			<MHZ_TO_KBPS(768, 4)>,  /* index=5  */
+			<MHZ_TO_KBPS(1017, 4)>, /* index=6  */
+			<MHZ_TO_KBPS(1353, 4)>, /* index=7  */
+			<MHZ_TO_KBPS(1555, 4)>, /* index=8  */
+			<MHZ_TO_KBPS(1708, 4)>, /* index=9  */
+			<MHZ_TO_KBPS(2092, 4)>, /* index=10  */
+			<MHZ_TO_KBPS(2736, 4)>, /* index=11  */
+			<MHZ_TO_KBPS(3196, 4)>; /* index=12  */
+
+		qcom,bus-table-cnoc =
+			<0>,   /* Off */
+			<100>; /* On */
+
+		nvmem-cells = <&gpu_speed_bin>;
+		nvmem-cell-names = "speed_bin";
+
+		zap-shader {
+			memory-region = <&gpu_microcode_mem>;
+		};
+
+		qcom,gpu-mempools {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "qcom,gpu-mempools";
+
+			/* 4K Page Pool configuration */
+			qcom,gpu-mempool@0 {
+				reg = <0>;
+				qcom,mempool-page-size = <4096>;
+				qcom,mempool-reserved = <2048>;
+			};
+			/* 8K Page Pool configuration */
+			qcom,gpu-mempool@1 {
+				reg = <1>;
+				qcom,mempool-page-size = <8192>;
+				qcom,mempool-reserved = <1024>;
+			};
+			/* 64K Page Pool configuration */
+			qcom,gpu-mempool@2 {
+				reg = <2>;
+				qcom,mempool-page-size = <65536>;
+				qcom,mempool-reserved = <256>;
+			};
+			/* 128K Page Pool configuration */
+			qcom,gpu-mempool@3 {
+				reg = <3>;
+				qcom,mempool-page-size = <131072>;
+				qcom,mempool-reserved = <128>;
+			};
+			/* 256K Page Pool configuration */
+			qcom,gpu-mempool@4 {
+				reg = <4>;
+				qcom,mempool-page-size = <262144>;
+				qcom,mempool-reserved = <80>;
+			};
+			/* 1M Page Pool configuration */
+			qcom,gpu-mempool@5 {
+				reg = <5>;
+				qcom,mempool-page-size = <1048576>;
+				qcom,mempool-reserved = <32>;
+			};
+		};
+
+		qcom,gpu-pwrlevel-bins {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			compatible = "qcom,gpu-pwrlevel-bins";
+
+			qcom,gpu-pwrlevels-0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				qcom,speed-bin = <0>;
+				qcom,initial-pwrlevel = <3>;
+
+				qcom,gpu-pwrlevel@0 {
+					reg = <0>;
+					qcom,gpu-freq = <877000000>;
+					qcom,level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+
+					qcom,bus-freq = <12>;
+					qcom,bus-min = <12>;
+					qcom,bus-max = <12>;
+				};
+
+				qcom,gpu-pwrlevel@1 {
+					reg = <1>;
+					qcom,gpu-freq = <780000000>;
+					qcom,level = <RPMH_REGULATOR_LEVEL_TURBO>;
+
+					qcom,bus-freq = <11>;
+					qcom,bus-min = <11>;
+					qcom,bus-max = <12>;
+				};
+
+				qcom,gpu-pwrlevel@2 {
+					reg = <2>;
+					qcom,gpu-freq = <599000000>;
+					qcom,level = <RPMH_REGULATOR_LEVEL_NOM>;
+
+					qcom,bus-freq = <10>;
+					qcom,bus-min = <10>;
+					qcom,bus-max = <11>;
+				};
+
+				qcom,gpu-pwrlevel@3 {
+					reg = <3>;
+					qcom,gpu-freq = <479000000>;
+					qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+					qcom,bus-freq = <7>;
+					qcom,bus-min = <7>;
+					qcom,bus-max = <10>;
+				};
+
+			};
+
+			qcom,gpu-pwrlevels-1 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				qcom,speed-bin = <185>;
+				qcom,initial-pwrlevel = <3>;
+
+				qcom,gpu-pwrlevel@0 {
+					reg = <0>;
+					qcom,gpu-freq = <877000000>;
+					qcom,level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+
+					qcom,bus-freq = <12>;
+					qcom,bus-min = <12>;
+					qcom,bus-max = <12>;
+				};
+
+				qcom,gpu-pwrlevel@1 {
+					reg = <1>;
+					qcom,gpu-freq = <780000000>;
+					qcom,level = <RPMH_REGULATOR_LEVEL_TURBO>;
+
+					qcom,bus-freq = <11>;
+					qcom,bus-min = <11>;
+					qcom,bus-max = <12>;
+				};
+
+				qcom,gpu-pwrlevel@2 {
+					reg = <2>;
+					qcom,gpu-freq = <599000000>;
+					qcom,level = <RPMH_REGULATOR_LEVEL_NOM>;
+
+					qcom,bus-freq = <10>;
+					qcom,bus-min = <10>;
+					qcom,bus-max = <11>;
+				};
+
+				qcom,gpu-pwrlevel@3 {
+					reg = <3>;
+					qcom,gpu-freq = <479000000>;
+					qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+					qcom,bus-freq = <7>;
+					qcom,bus-min = <7>;
+					qcom,bus-max = <10>;
+				};
+
+			};
+
+			qcom,gpu-pwrlevels-2 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				qcom,speed-bin = <127>;
+				qcom,initial-pwrlevel = <1>;
+
+				qcom,gpu-pwrlevel@0 {
+					reg = <0>;
+					qcom,gpu-freq = <599000000>;
+					qcom,level = <RPMH_REGULATOR_LEVEL_NOM>;
+
+					qcom,bus-freq = <10>;
+					qcom,bus-min = <10>;
+					qcom,bus-max = <11>;
+				};
+
+				qcom,gpu-pwrlevel@1 {
+					reg = <1>;
+					qcom,gpu-freq = <479000000>;
+					qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+					qcom,bus-freq = <7>;
+					qcom,bus-min = <7>;
+					qcom,bus-max = <10>;
+				};
+
+			};
+		};
+	};
+
+	kgsl_msm_iommu: qcom,kgsl-iommu@3da0000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "qcom,kgsl-smmu-v2";
+		reg = <0x03da0000 0x20000>;
+
+		power-domains = <&gpucc GPU_CC_CX_GDSC>;
+
+		gfx3d_user: gfx3d_user {
+			compatible = "qcom,smmu-kgsl-cb" , "qcom,adreno-gmu";
+			iommus = <&adreno_smmu 0x0 0xc00>, <&adreno_smmu 0x1 0xc00>;
+			qcom,iommu-dma = "disabled";
+		};
+	};
+
+	gmu: qcom,gmu@3d6a000 {
+		compatible = "qcom,gpu-gmu";
+
+		reg = <0 0x3d6a000 0 0x34000>,
+			<0 0xb290000 0 0x10000>;
+
+		reg-names = "kgsl_gmu_reg",
+			"kgsl_gmu_pdc_cfg";
+
+		interrupts = <0 304 IRQ_TYPE_LEVEL_HIGH>,
+			<0 305 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "kgsl_hfi_irq", "kgsl_gmu_irq";
+
+		iommus = <&adreno_smmu 0x5 0xc00>;
+		qcom,iommu-dma = "disabled";
+
+		power-domains = <&gpucc GPU_CC_CX_GDSC>, <&gpucc GPU_CC_GX_GDSC>;
+		power-domain-names = "cx", "gx";
+
+		clocks = <&gpucc GPU_CC_CX_GMU_CLK>,
+			<&gpucc GPU_CC_CXO_CLK>,
+			<&gcc GCC_DDRSS_GPU_AXI_CLK>,
+			<&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+			<&gpucc GPU_CC_AHB_CLK>,
+			<&gpucc GPU_CC_HUB_CX_INT_CLK>;
+
+		clock-names = "gmu_clk", "cxo_clk", "axi_clk",
+			"memnoc_clk", "ahb_clk", "hub_clk";
+
+		qcom,qmp = <&aoss_qmp>;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8300-graphics.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8300-graphics.dtso
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+// SPDX-License-Identifier: BSD-3-Clause
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,qcs8300-gcc.h>
+#include <dt-bindings/clock/qcom,sa8775p-gpucc.h>
+#include <dt-bindings/interconnect/qcom,qcs8300-rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+
+#include "qcs8300-graphics.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS8300 Ride";
+	compatible = "qcom,qcs8300-ride", "qcom,qcs8300";
+
+	qcom,msm-id = <606 0x10000>;
+	qcom,board-id = <0x00010019 0>, <0x01010019 1>;
+};
+
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8300-pmics.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8300-pmics.dtsi
@@ -0,0 +1,403 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/iio/qcom,spmi-adc5-gen3-pm8775.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/spmi/spmi.h>
+
+/ {
+	thermal-zones {
+		pmm8620au_0_mbg_tz {
+			polling-delay-passive = <100>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8620au_sail_0_tz>;
+
+			trips {
+				trip0 {
+					temperature = <115000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <135000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+
+		pmm8620au-0-therm {
+			polling-delay-passive = <100>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8620au_0_temp_alarm>;
+
+			trips {
+				trip0 {
+					temperature = <105000>;
+					hysteresis = <0>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <125000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+		};
+
+		pmm8620au_0_sail_xo {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8620au_0_adc PM8775_1_ADC5_GEN3_AMUX6_THM_100K_PU>;
+			trips {
+				trip0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+			};
+		};
+
+		pmm8620au_0_ufs0 {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8620au_0_adc PM8775_1_ADC5_GEN3_AMUX5_THM_100K_PU>;
+			trips {
+				trip0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+			};
+		};
+
+		pmm8620au_0_xo {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8620au_0_adc PM8775_1_ADC5_GEN3_AMUX1_THM_100K_PU>;
+			trips {
+				trip0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+			};
+		};
+
+		pmm8650au_1_mbg_tz {
+			polling-delay-passive = <100>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8620au_sail_1_tz>;
+
+			trips {
+				trip0 {
+					temperature = <115000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <135000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+
+		pmm8650au-1-therm {
+			polling-delay-passive = <100>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8650au_1_temp_alarm>;
+
+			trips {
+				trip0 {
+					temperature = <105000>;
+					hysteresis = <0>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <125000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+		};
+
+		pmm8650au_1_sdram {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8650au_1_adc PM8775_2_ADC5_GEN3_AMUX6_THM_100K_PU>;
+			trips {
+				trip0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+			};
+		};
+	};
+};
+
+&spmi_bus {
+	pmm8620au_0: pmic@0 {
+		compatible = "qcom,spmi-pmic";
+		reg = <0x0 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pmm8620au_0_adc: vadc@8000 {
+			compatible = "qcom,spmi-adc5-gen3";
+			reg = <0x8000>;
+			reg-names = "adc5-gen3-base";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts-extended = <&spmi_bus 0x0 0x80 0x1 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "adc-sdam0";
+			#io-channel-cells = <1>;
+			#thermal-sensor-cells = <1>;
+
+			pmm8620au_0_ref_gnd {
+				reg = <PM8775_1_ADC5_GEN3_OFFSET_REF>;
+				label = "pmm8620au_0_ref_gnd";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8620au_0_vref_1p25 {
+				reg = <PM8775_1_ADC5_GEN3_1P25VREF>;
+				label = "pmm8620au_0_vref_1p25";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8620au_0_die_temp {
+				reg = <PM8775_1_ADC5_GEN3_DIE_TEMP>;
+				label = "pmm8620au_0_die_temp";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8620au_0_vph_pwr {
+				reg = <PM8775_1_ADC5_GEN3_VPH_PWR>;
+				label = "pmm8620au_0_vph_pwr";
+				qcom,pre-scaling = <1 3>;
+			};
+
+			pmm8620au_0_sail_xo_therm {
+				reg = <PM8775_1_ADC5_GEN3_AMUX6_THM_100K_PU>;
+				label = "pmm8620au_0_sail_xo_therm";
+				qcom,ratiometric;
+				qcom,hw-settle-time = <200>;
+				qcom,adc-tm;
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8620au_0_ufs0_therm {
+				reg = <PM8775_1_ADC5_GEN3_AMUX5_THM_100K_PU>;
+				label = "pmm8620au_0_ufs0_therm";
+				qcom,ratiometric;
+				qcom,hw-settle-time = <200>;
+				qcom,adc-tm;
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8620au_0_xo_therm {
+				reg = <PM8775_1_ADC5_GEN3_AMUX1_THM_100K_PU>;
+				label = "pmm8620au_0_xo_therm";
+				qcom,ratiometric;
+				qcom,hw-settle-time = <700>;
+				qcom,adc-tm;
+				qcom,pre-scaling = <1 1>;
+			};
+		};
+
+		pmm8620au_0_temp_alarm: temp-alarm@a00 {
+			compatible = "qcom,spmi-temp-alarm";
+			reg = <0xa00>;
+			interrupts-extended = <&spmi_bus 0x0 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+			io-channels = <&pmm8620au_0_adc PM8775_1_ADC5_GEN3_DIE_TEMP>;
+			io-channel-names = "thermal";
+			#thermal-sensor-cells = <0>;
+		};
+
+		pmm8620au_0_pon: pon@1200 {
+			compatible = "qcom,pmk8350-pon";
+			reg = <0x1200>, <0x800>;
+			reg-names = "hlos", "pbs";
+
+			pmm8620au_0_pon_pwrkey: pwrkey {
+				compatible = "qcom,pmk8350-pwrkey";
+				interrupts-extended = <&spmi_bus 0x0 0x12 0x7 IRQ_TYPE_EDGE_BOTH>;
+				linux,code = <KEY_POWER>;
+				debounce = <15625>;
+			};
+
+			pmm8620au_0_pon_resin: resin {
+				compatible = "qcom,pmk8350-resin";
+				interrupts-extended = <&spmi_bus 0x0 0x12 0x6 IRQ_TYPE_EDGE_BOTH>;
+				debounce = <15625>;
+				linux,code = <KEY_VOLUMEDOWN>;
+			};
+		};
+
+		pmm8620au_0_rtc: rtc@6100 {
+			compatible = "qcom,pmk8350-rtc";
+			reg = <0x6100>, <0x6200>;
+			reg-names = "rtc", "alarm";
+			interrupts = <0x0 0x62 0x1 IRQ_TYPE_EDGE_RISING>;
+			allow-set-time;
+		};
+
+		pmm8620au_0_sdam_0: nvram@7100 {
+			compatible = "qcom,spmi-sdam";
+			reg = <0x7100>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+			ranges = <0 0x7100 0x100>;
+
+			reboot_reason: reboot-reason@48 {
+				reg = <0x48 0x1>;
+				bits = <1 7>;
+			};
+		};
+
+		pmm8620au_0_gpios: gpio@8800 {
+			compatible = "qcom,pmm8654au-gpio";
+			reg = <0x8800>;
+			gpio-controller;
+			gpio-ranges = <&pmm8620au_0_gpios 0 0 12>;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	pmm8620au_sail_0: pmic@1 {
+		compatible = "qcom,spmi-pmic";
+		reg = <1 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pmm8620au_sail_0_tz: qcom,mbg-tm@d700 {
+			compatible = "qcom,spmi-mgb-tm";
+			reg = <0xd700>;
+			io-channels = <&pmm8620au_0_adc PM8775_1_ADC5_GEN3_DIE_TEMP>;
+			io-channel-names = "thermal";
+			interrupts-extended = <&spmi_bus 0x1 0xd7 0x0 IRQ_TYPE_EDGE_RISING>;
+			#thermal-sensor-cells = <0>;
+		};
+	};
+
+	pmm8650au_1: pmic@2 {
+		compatible = "qcom,spmi-pmic";
+		reg = <0x2 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pmm8650au_1_adc: vadc@8000 {
+			compatible = "qcom,spmi-adc5-gen3";
+			reg = <0x8000>;
+			reg-names = "adc5-gen3-base";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts-extended = <&spmi_bus 0x2 0x80 0x1 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "adc-sdam0";
+			#io-channel-cells = <1>;
+			#thermal-sensor-cells = <1>;
+
+			pmm8650au_1_ref_gnd {
+				reg = <PM8775_2_ADC5_GEN3_OFFSET_REF>;
+				label = "pmm8650au_1_ref_gnd";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8650au_1_vref_1p25 {
+				reg = <PM8775_2_ADC5_GEN3_1P25VREF>;
+				label = "pmm8650au_1_vref_1p25";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8650au_1_die_temp {
+				reg = <PM8775_2_ADC5_GEN3_DIE_TEMP>;
+				label = "pmm8650au_1_die_temp";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8650au_1_vph_pwr {
+				reg = <PM8775_2_ADC5_GEN3_VPH_PWR>;
+				label = "pmm8650au_1_vph_pwr";
+				qcom,pre-scaling = <1 3>;
+			};
+
+			pmm8650au_1_sdram_therm {
+				reg = <PM8775_2_ADC5_GEN3_AMUX6_THM_100K_PU>;
+				label = "pmm8650au_1_sdram_therm";
+				qcom,ratiometric;
+				qcom,hw-settle-time = <200>;
+				qcom,adc-tm;
+				qcom,pre-scaling = <1 1>;
+			};
+		};
+
+		pmm8650au_1_temp_alarm: temp-alarm@a00 {
+			compatible = "qcom,spmi-temp-alarm";
+			reg = <0xa00>;
+			interrupts-extended = <&spmi_bus 0x2 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+			io-channels = <&pmm8650au_1_adc PM8775_2_ADC5_GEN3_DIE_TEMP>;
+			io-channel-names = "thermal";
+			#thermal-sensor-cells = <0>;
+		};
+
+		pmm8650au_1_gpios: gpio@8800 {
+			compatible = "qcom,pmm8654au-gpio";
+			reg = <0x8800>;
+			gpio-controller;
+			gpio-ranges = <&pmm8650au_1_gpios 0 0 12>;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	pmm8650au_sail_1: pmic@3 {
+		compatible = "qcom,spmi-pmic";
+		reg = <3 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pmm8620au_sail_1_tz: qcom,mbg-tm@d700 {
+			compatible = "qcom,spmi-mgb-tm";
+			reg = <0xd700>;
+			io-channels = <&pmm8650au_1_adc PM8775_2_ADC5_GEN3_DIE_TEMP>;
+			io-channel-names = "thermal";
+			interrupts-extended = <&spmi_bus 0x3 0xd7 0x0 IRQ_TYPE_EDGE_RISING>;
+			#thermal-sensor-cells = <0>;
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
@@ -0,0 +1,859 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include <dt-bindings/spmi/spmi.h>
+
+#include "qcs8300.dtsi"
+#include "qcs8300-pmics.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS8300 Ride";
+	compatible = "qcom,qcs8300-ride", "qcom,qcs8275", "qcom,qcs8300";
+
+	qcom,msm-id = <606 0x10000>, <674 0x10000>, <675 0x10000>;
+	qcom,board-id = <0x00010019 0>, <0x01010019 1>;
+
+	aliases {
+		serial0 = &uart7;
+		serial1 = &uart2;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	dsi0-connector {
+		compatible = "dp-connector";
+		type = "full-size";
+		label = "DSI0";
+
+		port {
+			 dsi0_connector_in: endpoint {
+			};
+		};
+	};
+
+	/* PWR_CTR2_VDD_1P8 supply */
+	vreg_conn_1p8: vreg_conn_1p8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vreg_conn_1p8";
+		startup-delay-us = <4000>;
+		enable-active-high;
+		gpio = <&pmm8650au_1_gpios 4 GPIO_ACTIVE_HIGH>;
+	};
+
+	/* PWR_CTR1_VDD_PA supply */
+	vreg_conn_pa: vreg_conn_pa {
+		compatible = "regulator-fixed";
+		regulator-name = "vreg_conn_pa";
+		startup-delay-us = <4000>;
+		enable-active-high;
+		gpio = <&pmm8650au_1_gpios 6 GPIO_ACTIVE_HIGH>;
+	};
+
+	wcn6855-pmu {
+		compatible = "qcom,wcn6855-pmu";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&wlan_en_state>;
+
+		vddctrl1-supply = <&vreg_conn_pa>;
+		vddctrl2-supply = <&vreg_conn_1p8>;
+		vddaon-supply = <&vreg_conn_pa>;
+		vddvm-supply = <&vreg_conn_1p8>;
+		vddvl-supply = <&vreg_conn_pa>;
+		vddvh-supply = <&vreg_conn_1p8>;
+
+		wlan-enable-gpios = <&tlmm 54 GPIO_ACTIVE_HIGH>;
+
+		regulators {
+			vreg_pmu_rfa_cmn: ldo0 {
+				regulator-name = "vreg_pmu_rfa_cmn";
+			};
+
+			vreg_pmu_aon_0p59: ldo1 {
+				regulator-name = "vreg_pmu_aon_0p59";
+			};
+
+			vreg_pmu_wlcx_0p8: ldo2 {
+				regulator-name = "vreg_pmu_wlcx_0p8";
+			};
+
+			vreg_pmu_wlmx_0p85: ldo3 {
+				regulator-name = "vreg_pmu_wlmx_0p85";
+			};
+
+			vreg_pmu_btcmx_0p85: ldo4 {
+				regulator-name = "vreg_pmu_btcmx_0p85";
+			};
+
+			vreg_pmu_rfa_0p8: ldo5 {
+				regulator-name = "vreg_pmu_rfa_0p8";
+			};
+
+			vreg_pmu_rfa_1p2: ldo6 {
+				regulator-name = "vreg_pmu_rfa_1p2";
+			};
+
+			vreg_pmu_rfa_1p7: ldo7 {
+				regulator-name = "vreg_pmu_rfa_1p7";
+			};
+
+			vreg_pmu_pcie_0p9: ldo8 {
+				regulator-name = "vreg_pmu_pcie_0p9";
+			};
+
+			vreg_pmu_pcie_1p8: ldo9 {
+				regulator-name = "vreg_pmu_pcie_1p8";
+			};
+		};
+	};
+};
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "a";
+
+		vreg_s4a: smps4 {
+			regulator-name = "vreg_s4a";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s9a: smps9 {
+			regulator-name = "vreg_s9a";
+			regulator-min-microvolt = <1352000>;
+			regulator-max-microvolt = <1352000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3a: ldo3 {
+			regulator-name = "vreg_l3a";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4a: ldo4 {
+			regulator-name = "vreg_l4a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5a: ldo5 {
+			regulator-name = "vreg_l5a";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6a: ldo6 {
+			regulator-name = "vreg_l6a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7a: ldo7 {
+			regulator-name = "vreg_l7a";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8a: ldo8 {
+			regulator-name = "vreg_l8a";
+			regulator-min-microvolt = <2504000>;
+			regulator-max-microvolt = <2960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9a: ldo9 {
+			regulator-name = "vreg_l9a";
+			regulator-min-microvolt = <2970000>;
+			regulator-max-microvolt = <3072000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "c";
+
+		vreg_s5c: smps5 {
+			regulator-name = "vreg_s5c";
+			regulator-min-microvolt = <1104000>;
+			regulator-max-microvolt = <1104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1c: ldo1 {
+			regulator-name = "vreg_l1c";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <500000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2c: ldo2 {
+			regulator-name = "vreg_l2c";
+			regulator-min-microvolt = <900000>;
+			regulator-max-microvolt = <904000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4c: ldo4 {
+			regulator-name = "vreg_l4c";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6c: ldo6 {
+			regulator-name = "vreg_l6c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7c: ldo7 {
+			regulator-name = "vreg_l7c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8c: ldo8 {
+			regulator-name = "vreg_l8c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9c: ldo9 {
+			regulator-name = "vreg_l9c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&dsi0_connector_in {
+	remote-endpoint = <&anx7625_1_out>;
+};
+
+&ethernet0 {
+	phy-mode = "2500base-x";
+	phy-handle = <&sgmii_phy0>;
+
+	pinctrl-0 = <&ethernet0_default>;
+	pinctrl-names = "default";
+
+	snps,mtl-rx-config = <&mtl_rx_setup>;
+	snps,mtl-tx-config = <&mtl_tx_setup>;
+	snps,ps-speed = <1000>;
+
+	status = "okay";
+
+	mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		sgmii_phy0: phy@8 {
+			compatible = "ethernet-phy-id31c3.1c33";
+			reg = <0x8>;
+			device_type = "ethernet-phy";
+			interrupts-extended = <&tlmm 4 IRQ_TYPE_EDGE_FALLING>;
+			reset-gpios = <&tlmm 31 GPIO_ACTIVE_LOW>;
+			reset-assert-us = <11000>;
+			reset-deassert-us = <70000>;
+		};
+	};
+
+	mtl_rx_setup: rx-queues-config {
+		snps,rx-queues-to-use = <4>;
+		snps,rx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x0>;
+			snps,route-up;
+			snps,priority = <0x1>;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x1>;
+			snps,route-ptp;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x2>;
+			snps,route-avcp;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x3>;
+			snps,priority = <0xc>;
+		};
+	};
+
+	mtl_tx_setup: tx-queues-config {
+		snps,tx-queues-to-use = <4>;
+		snps,tx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+	};
+};
+
+&eud {
+	status = "okay";
+};
+
+&i2c8 {
+	clock-frequency = <400000>;
+	pinctrl-0 = <&qup_i2c8_data_clk
+		     &io_expander_intr_active
+		     &io_expander_reset_active>;
+	pinctrl-names = "default";
+
+	status = "okay";
+
+	io_expander: gpio@74 {
+		compatible = "ti,tca9539";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x74>;
+		interrupt-parent = <&tlmm>;
+		interrupts = <93 IRQ_TYPE_EDGE_BOTH>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&dsi0_hpd_cfg_pins
+			    &dsi0_cdet_cfg_pins>;
+
+		dsi0_hpd_cfg_pins: gpio2-cfg {
+			pins = "gpio2";
+			input-enable;
+			bias-disable;
+		};
+
+		dsi0_cdet_cfg_pins: gpio3-cfg {
+			pins = "gpio3";
+			bias-pull-down;
+		};
+	};
+
+	i2c-mux@70 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+
+		#size-cells = <0>;
+		reg = <0x70>;
+
+		i2c@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			anx_7625_1: anx7625@58 {
+				compatible = "analogix,anx7625";
+				reg = <0x58>;
+				interrupt-parent = <&io_expander>;
+				interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+				enable-gpios = <&io_expander 1 0>;
+				reset-gpios = <&io_expander 0 0>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					dsi2dp_bridge_1_in: port@0 {
+						reg = <0>;
+						anx7625_1_in: endpoint {
+							remote-endpoint = <&mdss_dsi0_out>;
+						};
+					};
+
+					dsi2dp_bridge_1_out: port@1 {
+						reg = <1>;
+						anx7625_1_out: endpoint {
+							remote-endpoint = <&dsi0_connector_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
+
+&i2c15 {
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&ice {
+	status = "okay";
+};
+
+&ice_mmc {
+	status = "okay";
+};
+
+&iris {
+	status = "okay";
+};
+
+&mdss_dsi0 {
+	vdda-supply = <&vreg_l5a>;
+
+	status = "okay";
+};
+
+&mdss_dsi0_phy {
+	vdds-supply = <&vreg_l4a>;
+
+	status = "okay";
+};
+
+&mdss_dsi0_out {
+	data-lanes = <0 1 2 3>;
+	remote-endpoint = <&anx7625_1_in>;
+};
+
+&pcieport0 {
+	wifi@0 {
+		compatible = "qcom,wcn6855-wifi";
+		reg = <0x10000 0x0 0x0 0x0 0x0>;
+
+		vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+		vddaon-supply = <&vreg_pmu_aon_0p59>;
+		vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
+		vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
+		vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+		vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+		vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>;
+		vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>;
+		vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>;
+	};
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&qupv3_id_1 {
+	status = "okay";
+};
+
+&mdss {
+	status = "okay";
+};
+
+&mdss_dp0 {
+	status = "okay";
+};
+
+&mdss_dp_out {
+	data-lanes = <0 1 2 3>;
+	link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+};
+
+&mdss_edp_phy {
+	status = "okay";
+};
+
+&spmi_bus {
+	pmm8654au_2: pmic@2 {
+		compatible = "qcom,pmm8654au", "qcom,spmi-pmic";
+		reg = <2 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pmm8654au_2_gpios: gpio@8800 {
+			compatible = "qcom,pmm8654au-gpio", "qcom,spmi-gpio";
+			reg = <0x8800>;
+			gpio-controller;
+			gpio-ranges = <&pmm8654au_2_gpios 0 0 12>;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+};
+
+&tlmm {
+	bt_en_state: bt-en-state {
+		pins = "gpio55";
+		function = "normal";
+		output-low;
+		bias-pull-down;
+	};
+
+	dp_hot_plug_det: dp-hot-plug-det-state {
+		pins = "gpio94";
+		function = "edp0_hot";
+		bias-disable;
+	};
+
+	ethernet0_default: ethernet0-default-state {
+		ethernet0_mdc: ethernet0-mdc-pins {
+			pins = "gpio5";
+			function = "emac0_mdc";
+			drive-strength = <16>;
+			bias-pull-up;
+		};
+
+		ethernet0_mdio: ethernet0-mdio-pins {
+			pins = "gpio6";
+			function = "emac0_mdio";
+			drive-strength = <16>;
+			bias-pull-up;
+		};
+	};
+
+	io_expander_intr_active: io_expander_intr_active {
+		pins = "gpio93";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+	};
+
+	io_expander_reset_active: io_expander_reset_active {
+		pins = "gpio66";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+		output-high;
+	};
+
+	wlan_en_state: wlan-en-state {
+		pins = "gpio54";
+		function = "normal";
+		output-low;
+		bias-pull-up;
+	};
+};
+
+&remoteproc_adsp {
+	firmware-name = "qcom/qcs8300/adsp.mbn";
+	status = "okay";
+};
+
+&remoteproc_cdsp {
+	firmware-name = "qcom/qcs8300/cdsp0.mbn";
+	status = "okay";
+};
+
+&remoteproc_gpdsp {
+	firmware-name = "qcom/qcs8300/gpdsp0.mbn";
+	status = "okay";
+};
+
+&serdes0 {
+	phy-supply = <&vreg_l5a>;
+	status = "okay";
+};
+
+/* HS UART Instance */
+&uart2 {
+	status = "okay";
+	bluetooth: bluetooth {
+		compatible = "qcom,wcn6855-bt";
+		firmware-name = "QCA6698/hpnv21", "QCA6698/hpbtfw21.tlv";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&bt_en_state>;
+		enable-gpios = <&tlmm 55 GPIO_ACTIVE_HIGH>; /* BT_EN */
+
+		vddio-supply       = <&vreg_conn_pa>;         /* bt-vdd-ctrl1-supply */
+		vddbtcxmx-supply   = <&vreg_conn_1p8>;        /* bt-vdd-ctrl2-supply */
+		vddrfacmn-supply   = <&vreg_conn_1p8>;             /* bt-vdd-aon-supply, dummy */
+		vddrfa0p8-supply   = <&vreg_conn_1p8>;             /* bt-vdd-aon-supply, dummy */
+		vddrfa1p7-supply   = <&vreg_conn_1p8>;             /* bt-vdd-aon-supply, dummy */
+		vddrfa1p2-supply   = <&vreg_conn_1p8>;             /* bt-vdd-aon-supply, dummy */
+		//vddrfacmn-supply   = <&vreg_l2c>;             /* bt-vdd-aon-supply */
+		//vddrfa0p8-supply   = <&vreg_l2c>;             /* bt-vdd-rfa1-supply */
+		//vddrfa1p7-supply   = <&vreg_s5a>;             /* bt-vdd-rfa2-supply */
+		//vddrfa1p2-supply   = <&vreg_l6e>;             /* bt-vdd-rfa3-supply */
+		max-speed = <3200000>;
+	};
+};
+
+&tlmm {
+	pcie0_default_state: pcie0-default-state {
+		perst-pins {
+			pins = "gpio2";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+
+		clkreq-pins {
+			pins = "gpio1";
+			function = "pcie0_clkreq";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		wake-pins {
+			pins = "gpio0";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+	};
+
+	pcie1_default_state: pcie1-default-state {
+		perst-pins {
+			pins = "gpio23";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+
+		clkreq-pins {
+			pins = "gpio22";
+			function = "pcie1_clkreq";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		wake-pins {
+			pins = "gpio21";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+	};
+};
+
+&pcie0 {
+	perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_default_state>;
+
+	status = "okay";
+};
+
+&pcie1 {
+	perst-gpios = <&tlmm 23 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_default_state>;
+
+	status = "okay";
+};
+
+&pcie0_phy {
+	vdda-phy-supply = <&vreg_l6a>;
+	vdda-pll-supply = <&vreg_l5a>;
+
+	status = "okay";
+};
+
+&pcie1_phy {
+	vdda-phy-supply = <&vreg_l6a>;
+	vdda-pll-supply = <&vreg_l5a>;
+
+	status = "okay";
+};
+
+&uart7 {
+	status = "okay";
+};
+
+&ufs_mem_hc {
+	reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>;
+	vcc-supply = <&vreg_l8a>;
+	vcc-max-microamp = <1100000>;
+	vccq-supply = <&vreg_l4c>;
+	vccq-max-microamp = <1200000>;
+	status = "okay";
+};
+
+&ufs_mem_phy {
+	vdda-phy-supply = <&vreg_l4a>;
+	vdda-pll-supply = <&vreg_l5a>;
+	status = "okay";
+};
+
+&pmm8654au_2_gpios {
+	usb1_en_state: usb1-en-state {
+		pins = "gpio7";
+		function = "normal";
+		output-high;
+		power-source = <0>;
+	};
+};
+
+&usb_qmpphy {
+	vdda-phy-supply = <&vreg_l7a>;
+	vdda-pll-supply = <&vreg_l5a>;
+
+	status = "okay";
+};
+
+&usb_1_hsphy {
+	vdda-pll-supply = <&vreg_l7a>;
+	vdda18-supply = <&vreg_l7c>;
+	vdda33-supply = <&vreg_l9a>;
+
+	status = "okay";
+};
+
+&usb_2_hsphy {
+	vdda-pll-supply = <&vreg_l7a>;
+	vdda18-supply = <&vreg_l7c>;
+	vdda33-supply = <&vreg_l9a>;
+
+	status = "okay";
+};
+
+&usb_1 {
+	status = "okay";
+};
+
+&usb_1_dwc3 {
+	snps,dis-u2-entry-quirk;
+	snps,dis-u1-entry-quirk;
+	snps,dis_u2_susphy_quirk;
+	snps,dis_u3_susphy_quirk;
+
+	dr_mode = "peripheral";
+};
+
+&usb_2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb1_en_state>;
+	status = "okay";
+};
+
+&usb_2_dwc3 {
+	dr_mode = "host";
+};
+
+&spi10 {
+	status = "okay";
+	spidev@0 {
+		compatible = "rohm,dh2228fv";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+		spi-cpha;
+	};
+};
+
+&sdc1_clk {
+	bias-disable;
+	drive-strength = <16>;
+};
+
+&sdc1_cmd {
+	bias-pull-up;
+	drive-strength = <10>;
+};
+
+&sdc1_data {
+	bias-pull-up;
+	drive-strength = <10>;
+};
+
+&sdc1_rclk {
+	bias-pull-down;
+};
+
+&sdhc_1 {
+	vmmc-supply = <&vreg_l8a>;
+	vqmmc-supply = <&vreg_s4a>;
+
+	no-sd;
+	no-sdio;
+	non-removable;
+
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&sdc1_clk>, <&sdc1_cmd>, <&sdc1_data>;
+	pinctrl-1 = <&sdc1_clk_sleep>, <&sdc1_cmd_sleep>, <&sdc1_data_sleep>;
+	status = "okay";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8300-video.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8300-video.dtsi
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+&soc {
+	iris: video-codec@aa00000 {
+		compatible = "qcom,qcs8300-iris";
+
+		reg = <0 0x0aa00000 0 0xf0000>;
+		interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+
+		power-domains = <&videocc VIDEO_CC_MVS0C_GDSC>,
+			<&videocc VIDEO_CC_MVS0_GDSC>,
+			<&rpmhpd QCS8300_MX>,
+			<&rpmhpd QCS8300_MMCX>;
+
+		power-domain-names = "iris-ctl", "vcodec", "mx", "mmcx";
+		operating-points-v2 = <&iris_opp_table>;
+
+		clocks = <&gcc GCC_VIDEO_AXI0_CLK>,
+				<&videocc VIDEO_CC_MVS0C_CLK>,
+				<&videocc VIDEO_CC_MVS0_CLK>;
+		clock-names = "gcc_video_axi0", "core_clk", "vcodec_clk";
+
+		interconnects =
+			<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+				&config_noc SLAVE_VENUS_CFG QCOM_ICC_TAG_ALWAYS>,
+			<&mmss_noc MASTER_VIDEO_P0 QCOM_ICC_TAG_ALWAYS
+				&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+		interconnect-names = "iris-cnoc", "iris-ddr";
+
+		/* FW load region */
+		memory-region = <&video_mem>;
+
+		resets = <&gcc GCC_VIDEO_AXI0_CLK_ARES>;
+		reset-names = "video_axi_reset";
+
+		status = "okay";
+
+		/* MMUs */
+		video_resv_region: video_resv_region {
+			iommu-addresses = <&non_secure_cb 0x0 0x0 0x0 0x25800000>,
+					<&non_secure_cb 0x0 0xe0000000 0x0 0x20000000>,
+					<&non_secure_pixel_cb 0x0 0x0 0x0 0x00100000>,
+					<&non_secure_pixel_cb 0x0 0xe0000000 0x0 0x20000000>;
+		};
+
+		non_secure_cb: non_secure_cb {
+			compatible = "qcom,vidc,cb-ns";
+			iommus = <&apps_smmu 0x0880 0x0400>;
+			memory-region = <&video_resv_region>;
+		};
+
+		non_secure_pixel_cb: non_secure_pixel_cb {
+			compatible = "qcom,vidc,cb-ns-pxl";
+			iommus = <&apps_smmu 0x0887 0x0400>;
+			memory-region = <&video_resv_region>;
+		};
+
+		iris_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-366000000 {
+				opp-hz = /bits/ 64 <366000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>,
+						<&rpmhpd_opp_svs_l1>;
+			};
+
+			opp-444000000 {
+				opp-hz = /bits/ 64 <444000000>;
+				required-opps = <&rpmhpd_opp_nom>,
+						<&rpmhpd_opp_nom>;
+			};
+
+			opp-533000000 {
+				opp-hz = /bits/ 64 <533000000>;
+				required-opps = <&rpmhpd_opp_turbo>,
+						<&rpmhpd_opp_turbo>;
+			};
+
+			opp-560000000 {
+				opp-hz = /bits/ 64 <560000000>;
+				required-opps = <&rpmhpd_opp_turbo_l1>,
+						<&rpmhpd_opp_turbo_l1>;
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8300-video.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8300-video.dtso
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
+#include <dt-bindings/clock/qcom,qcs8300-gcc.h>
+#include <dt-bindings/interconnect/qcom,qcs8300-rpmh.h>
+#include <dt-bindings/clock/qcom,sa8775p-dispcc.h>
+#include <dt-bindings/clock/qcom,sa8775p-videocc.h>
+#include "qcs8300-video.dtsi"
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8300.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8300.dtsi
@@ -0,0 +1,8122 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/clock/qcom,qcs8300-gcc.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/clock/qcom,sa8775p-camcc.h>
+#include <dt-bindings/clock/qcom,sa8775p-dispcc.h>
+#include <dt-bindings/clock/qcom,sa8775p-gpucc.h>
+#include <dt-bindings/clock/qcom,sa8775p-videocc.h>
+#include <dt-bindings/dma/qcom-gpi.h>
+#include <dt-bindings/firmware/qcom,scm.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
+#include <dt-bindings/interconnect/qcom,qcs8300-rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/mailbox/qcom-ipcc.h>
+#include <dt-bindings/power/qcom,rpmhpd.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+#include <dt-bindings/soc/qcom,gpr.h>
+#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
+#include <dt-bindings/interconnect/qcom,osm-l3.h>
+
+/ {
+	interrupt-parent = <&intc>;
+
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	chosen { };
+
+	aliases {
+		i2c0 = &i2c0;
+		i2c1 = &i2c1;
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		i2c4 = &i2c4;
+		i2c5 = &i2c5;
+		i2c6 = &i2c6;
+		i2c8 = &i2c8;
+		i2c9 = &i2c9;
+		i2c10 = &i2c10;
+		i2c11 = &i2c11;
+		i2c12 = &i2c12;
+		i2c13 = &i2c13;
+		i2c14 = &i2c14;
+		i2c15 = &i2c15;
+		mmc0 = &sdhc_1;
+		mmc1 = &sdhc_2; /* SDC2 SD card slot */
+		spi0 = &spi0;
+		spi1 = &spi1;
+		spi2 = &spi2;
+		spi3 = &spi3;
+		spi4 = &spi4;
+		spi5 = &spi5;
+		spi6 = &spi6;
+		spi8 = &spi8;
+		spi9 = &spi9;
+		spi10 = &spi10;
+		spi12 = &spi12;
+		spi13 = &spi13;
+		spi14 = &spi14;
+		spi15 = &spi15;
+		serial0 = &uart7;
+	};
+
+	audio-etm0 {
+		compatible = "qcom,coresight-remote-etm";
+		device-name = "audio_etm0";
+
+		qcom,inst-id = <5>;
+		atid = <40>;
+
+		out-ports {
+			port {
+				audio_out: endpoint {
+					remote-endpoint =
+					<&lpi_funnel_in0>;
+				};
+			};
+		};
+	};
+
+	clocks {
+		xo_board: xo-board {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <38400000>;
+		};
+
+		sleep_clk: sleep-clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+			clock-frequency = <32000>;
+		};
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		CPU0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78c";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			next-level-cache = <&L2_0>;
+			power-domains = <&CPU_PD0>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1946>;
+			dynamic-power-coefficient = <472>;
+			qcom,freq-domain = <&cpufreq_hw 0>;
+			operating-points-v2 = <&cpu0_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl0 MASTER_EPSS_L3_APPS
+					 &epss_l3_cl0 SLAVE_EPSS_L3_SHARED>;
+
+			L2_0: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_0>;
+
+				L3_0: l3-cache {
+					compatible = "cache";
+					cache-level = <3>;
+					cache-unified;
+				};
+			};
+		};
+
+		CPU1: cpu@100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78c";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			next-level-cache = <&L2_1>;
+			power-domains = <&CPU_PD1>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1946>;
+			dynamic-power-coefficient = <472>;
+			qcom,freq-domain = <&cpufreq_hw 0>;
+			operating-points-v2 = <&cpu0_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl0 MASTER_EPSS_L3_APPS
+					 &epss_l3_cl0 SLAVE_EPSS_L3_SHARED>;
+
+			L2_1: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_0>;
+			};
+		};
+
+		CPU2: cpu@200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78c";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			next-level-cache = <&L2_2>;
+			power-domains = <&CPU_PD2>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1946>;
+			dynamic-power-coefficient = <507>;
+			qcom,freq-domain = <&cpufreq_hw 1>;
+			operating-points-v2 = <&cpu2_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl0 MASTER_EPSS_L3_APPS
+					 &epss_l3_cl0 SLAVE_EPSS_L3_SHARED>;
+
+			L2_2: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_0>;
+			};
+		};
+
+		CPU3: cpu@300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a78c";
+			reg = <0x0 0x300>;
+			enable-method = "psci";
+			next-level-cache = <&L2_3>;
+			power-domains = <&CPU_PD3>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1946>;
+			dynamic-power-coefficient = <507>;
+			qcom,freq-domain = <&cpufreq_hw 1>;
+			operating-points-v2 = <&cpu2_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl0 MASTER_EPSS_L3_APPS
+					 &epss_l3_cl0 SLAVE_EPSS_L3_SHARED>;
+
+			L2_3: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_0>;
+			};
+		};
+
+		CPU4: cpu@10000 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x10000>;
+			enable-method = "psci";
+			next-level-cache = <&L2_4>;
+			power-domains = <&CPU_PD4>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			qcom,freq-domain = <&cpufreq_hw 2>;
+			operating-points-v2 = <&cpu4_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl1 MASTER_EPSS_L3_APPS
+					 &epss_l3_cl1 SLAVE_EPSS_L3_SHARED>;
+
+			L2_4: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_1>;
+
+				L3_1: l3-cache {
+					compatible = "cache";
+					cache-level = <3>;
+					cache-unified;
+				};
+			};
+		};
+
+		CPU5: cpu@10100 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x10100>;
+			enable-method = "psci";
+			next-level-cache = <&L2_5>;
+			power-domains = <&CPU_PD5>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			qcom,freq-domain = <&cpufreq_hw 2>;
+			operating-points-v2 = <&cpu4_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl1 MASTER_EPSS_L3_APPS
+					 &epss_l3_cl1 SLAVE_EPSS_L3_SHARED>;
+
+			L2_5: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_1>;
+			};
+		};
+
+		CPU6: cpu@10200 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x10200>;
+			enable-method = "psci";
+			next-level-cache = <&L2_6>;
+			power-domains = <&CPU_PD6>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			qcom,freq-domain = <&cpufreq_hw 2>;
+			operating-points-v2 = <&cpu4_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl1 MASTER_EPSS_L3_APPS
+					 &epss_l3_cl1 SLAVE_EPSS_L3_SHARED>;
+
+			L2_6: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_1>;
+			};
+		};
+
+		CPU7: cpu@10300 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a55";
+			reg = <0x0 0x10300>;
+			enable-method = "psci";
+			next-level-cache = <&L2_7>;
+			power-domains = <&CPU_PD7>;
+			power-domain-names = "psci";
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			qcom,freq-domain = <&cpufreq_hw 2>;
+			operating-points-v2 = <&cpu4_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl1 MASTER_EPSS_L3_APPS
+					 &epss_l3_cl1 SLAVE_EPSS_L3_SHARED>;
+
+			L2_7: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_1>;
+			};
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+
+				core1 {
+					cpu = <&CPU1>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&CPU2>;
+				};
+
+				core1 {
+					cpu = <&CPU3>;
+				};
+			};
+
+			cluster2 {
+				core0 {
+					cpu = <&CPU4>;
+				};
+
+				core1 {
+					cpu = <&CPU5>;
+				};
+
+				core2 {
+					cpu = <&CPU6>;
+				};
+
+				core3 {
+					cpu = <&CPU7>;
+				};
+			};
+		};
+
+		idle-states {
+			entry-method = "psci";
+
+			LITTLE_CPU_SLEEP_0: cpu-sleep-0-0 {
+				compatible = "arm,idle-state";
+				idle-state-name = "silver-power-collapse";
+				arm,psci-suspend-param = <0x40000003>;
+				entry-latency-us = <449>;
+				exit-latency-us = <801>;
+				min-residency-us = <1574>;
+				local-timer-stop;
+			};
+
+			LITTLE_CPU_SLEEP_1: cpu-sleep-0-1 {
+				compatible = "arm,idle-state";
+				idle-state-name = "silver-rail-power-collapse";
+				arm,psci-suspend-param = <0x40000004>;
+				entry-latency-us = <602>;
+				exit-latency-us = <961>;
+				min-residency-us = <4288>;
+				local-timer-stop;
+			};
+
+			BIG_CPU_SLEEP_0: cpu-sleep-1-0 {
+				compatible = "arm,idle-state";
+				idle-state-name = "gold-power-collapse";
+				arm,psci-suspend-param = <0x40000003>;
+				entry-latency-us = <549>;
+				exit-latency-us = <901>;
+				min-residency-us = <1774>;
+				local-timer-stop;
+			};
+
+			BIG_CPU_SLEEP_1: cpu-sleep-1-1 {
+				compatible = "arm,idle-state";
+				idle-state-name = "gold-rail-power-collapse";
+				arm,psci-suspend-param = <0x40000004>;
+				entry-latency-us = <702>;
+				exit-latency-us = <1061>;
+				min-residency-us = <4488>;
+				local-timer-stop;
+			};
+		};
+
+		domain-idle-states {
+			SILVER_CLUSTER_SLEEP: cluster-sleep-0 {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x41000044>;
+				entry-latency-us = <2552>;
+				exit-latency-us = <2848>;
+				min-residency-us = <5908>;
+			};
+
+			GOLD_CLUSTER_SLEEP: cluster-sleep-1 {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x41000044>;
+				entry-latency-us = <2752>;
+				exit-latency-us = <3048>;
+				min-residency-us = <6118>;
+			};
+
+			SYSTEM_SLEEP: domain-sleep {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x42000144>;
+				entry-latency-us = <3263>;
+				exit-latency-us = <6562>;
+				min-residency-us = <9987>;
+			};
+		};
+	};
+
+	cpu0_opp_table: opp-table-cpu0 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		cpu0_opp_1190mhz: opp-1190400000 {
+			opp-hz = /bits/ 64 <1190400000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu0_opp_1267mhz: opp-1267200000 {
+			opp-hz = /bits/ 64 <1267200000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu0_opp_1344mhz: opp-1344000000 {
+			opp-hz = /bits/ 64 <1344000000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu0_opp_1420mhz: opp-1420800000 {
+			opp-hz = /bits/ 64 <1420800000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu0_opp_1497mhz: opp-1497600000 {
+			opp-hz = /bits/ 64 <1497600000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu0_opp_1574mhz: opp-1574400000 {
+			opp-hz = /bits/ 64 <1574400000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu0_opp_1670mhz: opp-1670400000 {
+			opp-hz = /bits/ 64 <1670400000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu0_opp_1747mhz: opp-1747200000 {
+			opp-hz = /bits/ 64 <1747200000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu0_opp_1824mhz: opp-1824000000 {
+			opp-hz = /bits/ 64 <1824000000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu0_opp_1900mhz: opp-1900800000 {
+			opp-hz = /bits/ 64 <1900800000>;
+			opp-peak-kBps = <8371200 47318400>;
+		};
+
+		cpu0_opp_1977mhz: opp-1977600000 {
+			opp-hz = /bits/ 64 <1977600000>;
+			opp-peak-kBps = <8371200 47318400>;
+		};
+
+		cpu0_opp_2054mhz: opp-2054400000 {
+			opp-hz = /bits/ 64 <2054400000>;
+			opp-peak-kBps = <8371200 47318400>;
+		};
+
+		cpu0_opp_2112mhz: opp-2112000000 {
+			opp-hz = /bits/ 64 <2112000000>;
+			opp-peak-kBps = <12787200 51609600>;
+		};
+	};
+
+	cpu2_opp_table: opp-table-cpu2 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		cpu2_opp_1267mhz: opp-1267200000 {
+			opp-hz = /bits/ 64 <1267200000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu2_opp_1344mhz: opp-1344000000 {
+			opp-hz = /bits/ 64 <1344000000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu2_opp_1420mhz: opp-1420800000 {
+			opp-hz = /bits/ 64 <1420800000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu2_opp_1497mhz: opp-1497600000 {
+			opp-hz = /bits/ 64 <1497600000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu2_opp_1574mhz: opp-1574400000 {
+			opp-hz = /bits/ 64 <1574400000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu2_opp_1632mhz: opp-1632000000 {
+			opp-hz = /bits/ 64 <1632000000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu2_opp_1708mhz: opp-1708800000 {
+			opp-hz = /bits/ 64 <1708800000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu2_opp_1804mhz: opp-1804800000 {
+			opp-hz = /bits/ 64 <1804800000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu2_opp_1900mhz: opp-1900800000 {
+			opp-hz = /bits/ 64 <1900800000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu2_opp_1977mhz: opp-1977600000 {
+			opp-hz = /bits/ 64 <1977600000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu2_opp_2054mhz: opp-2054400000 {
+			opp-hz = /bits/ 64 <2054400000>;
+			opp-peak-kBps = <8371200 47318400>;
+		};
+
+		cpu2_opp_2131mhz: opp-2131200000 {
+			opp-hz = /bits/ 64 <2131200000>;
+			opp-peak-kBps = <8371200 47318400>;
+		};
+
+		cpu2_opp_2208mhz: opp-2208000000 {
+			opp-hz = /bits/ 64 <2208000000>;
+			opp-peak-kBps = <8371200 47318400>;
+		};
+
+		cpu2_opp_2284mhz: opp-2284800000 {
+			opp-hz = /bits/ 64 <2284800000>;
+			opp-peak-kBps = <8371200 47318400>;
+		};
+
+		cpu2_opp_2361mhz: opp-2361600000 {
+			opp-hz = /bits/ 64 <2361600000>;
+			opp-peak-kBps = <12787200 51609600>;
+		};
+	};
+
+	cpu4_opp_table: opp-table-cpu4 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		cpu4_opp_1113mhz: opp-1113600000 {
+			opp-hz = /bits/ 64 <1113600000>;
+			opp-peak-kBps = <3072000 29491200>;
+		};
+
+		cpu4_opp_1209mhz: opp-1209600000 {
+			opp-hz = /bits/ 64 <1209600000>;
+			opp-peak-kBps = <3072000 29491200>;
+		};
+
+		cpu4_opp_1305mhz: opp-1305600000 {
+			opp-hz = /bits/ 64 <1305600000>;
+			opp-peak-kBps = <3072000 29491200>;
+		};
+
+		cpu4_opp_1382mhz: opp-1382400000 {
+			opp-hz = /bits/ 64 <1382400000>;
+			opp-peak-kBps = <3072000 29491200>;
+		};
+
+		cpu4_opp_1459mhz: opp-1459200000 {
+			opp-hz = /bits/ 64 <14592000000>;
+			opp-peak-kBps = <5414400 39321600>;
+		};
+
+		cpu4_opp_1497mhz: opp-1497600000 {
+			opp-hz = /bits/ 64 <1497600000>;
+			opp-peak-kBps = <5414400 39321600>;
+		};
+
+		cpu4_opp_1574mhz: opp-1574400000 {
+			opp-hz = /bits/ 64 <1574400000>;
+			opp-peak-kBps = <5414400 39321600>;
+		};
+
+		cpu4_opp_1651mhz: opp-1651200000 {
+			opp-hz = /bits/ 64 <1651200000>;
+			opp-peak-kBps = <5414400 39321600>;
+		};
+
+		cpu4_opp_1728mhz: opp-1728000000 {
+			opp-hz = /bits/ 64 <1728000000>;
+			opp-peak-kBps = <5414400 39321600>;
+		};
+
+		cpu4_opp_1804mhz: opp-1804800000 {
+			opp-hz = /bits/ 64 <1804800000>;
+			opp-peak-kBps = <6835200 47318400>;
+		};
+
+		cpu4_opp_1881mhz: opp-1881600000 {
+			opp-hz = /bits/ 64 <1881600000>;
+			opp-peak-kBps = <6835200 47318400>;
+		};
+
+		cpu4_opp_1958mhz: opp-1958400000 {
+			opp-hz = /bits/ 64 <1958400000>;
+			opp-peak-kBps = <8371200 51609600>;
+		};
+	};
+
+	dummy_eud: dummy-sink {
+		compatible = "arm,coresight-dummy-sink";
+		device-name = "eud";
+
+		in-ports {
+			port {
+				eud_in: endpoint {
+					remote-endpoint =
+					<&swao_rep_out1>;
+				};
+			};
+		};
+	};
+
+	firmware {
+		scm: scm {
+			compatible = "qcom,scm-qcs8300", "qcom,scm";
+			qcom,dload-mode = <&tcsr 0x13000>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		/* We expect the bootloader to fill in the size */
+		reg = <0x0 0x80000000 0x0 0x0>;
+	};
+
+	pmu-a55 {
+		compatible = "arm,cortex-a55-pmu";
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	pmu-a78 {
+		compatible = "arm,cortex-a78-pmu";
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+		mode-bootloader = <0x10001 0x2>;
+		mode-edl = <0x0 0x1>;
+
+		CPU_PD0: power-domain-cpu0 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD0>;
+			domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
+		};
+
+		CPU_PD1: power-domain-cpu1 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD0>;
+			domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
+		};
+
+		CPU_PD2: power-domain-cpu2 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD0>;
+			domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
+		};
+
+		CPU_PD3: power-domain-cpu3 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD0>;
+			domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
+		};
+
+		CPU_PD4: power-domain-cpu4 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD1>;
+			domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+		};
+
+		CPU_PD5: power-domain-cpu5 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD1>;
+			domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+		};
+
+		CPU_PD6: power-domain-cpu6 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD1>;
+			domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+		};
+
+		CPU_PD7: power-domain-cpu7 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_PD1>;
+			domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+		};
+
+		CLUSTER_PD0: power-domain-cluster0 {
+			#power-domain-cells = <0>;
+			power-domains = <&SYSTEM_PD>;
+			domain-idle-states = <&GOLD_CLUSTER_SLEEP>;
+		};
+
+		CLUSTER_PD1: power-domain-cluster1 {
+			#power-domain-cells = <0>;
+			power-domains = <&SYSTEM_PD>;
+			domain-idle-states = <&SILVER_CLUSTER_SLEEP>;
+		};
+
+		SYSTEM_PD: power-domain-system {
+			#power-domain-cells = <0>;
+			domain-idle-states = <&SYSTEM_SLEEP>;
+		};
+	};
+
+	aggre1_noc: interconnect-aggre1-noc {
+		compatible = "qcom,qcs8300-aggre1-noc";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	aggre2_noc: interconnect-aggre2-noc {
+		compatible = "qcom,qcs8300-aggre2-noc";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	clk_virt: interconnect-clk-virt {
+		compatible = "qcom,qcs8300-clk-virt";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	config_noc: interconnect-config-noc {
+		compatible = "qcom,qcs8300-config-noc";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	dc_noc: interconnect-dc-noc {
+		compatible = "qcom,qcs8300-dc-noc";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	gem_noc: interconnect-gem-noc {
+		compatible = "qcom,qcs8300-gem-noc";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	gpdsp_anoc: interconnect-gpdsp-anoc {
+		compatible = "qcom,qcs8300-gpdsp-anoc";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	lpass_ag_noc: interconnect-lpass-ag-noc {
+		compatible = "qcom,qcs8300-lpass-ag-noc";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	mc_virt: interconnect-mc-virt {
+		compatible = "qcom,qcs8300-mc-virt";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	mmss_noc: interconnect-mmss-noc {
+		compatible = "qcom,qcs8300-mmss-noc";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	nspa_noc: interconnect-nspa-noc {
+		compatible = "qcom,qcs8300-nspa-noc";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	pcie_anoc: interconnect-pcie-anoc {
+		compatible = "qcom,qcs8300-pcie-anoc";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	system_noc: interconnect-system-noc {
+		compatible = "qcom,qcs8300-system-noc";
+		#interconnect-cells = <2>;
+		qcom,bcm-voters = <&apps_bcm_voter>;
+	};
+
+	qup_opp_table: opp-table-qup {
+		compatible = "operating-points-v2";
+
+		opp-120000000 {
+			opp-hz = /bits/ 64 <120000000>;
+			required-opps = <&rpmhpd_opp_svs_l1>;
+		};
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		sail_ss_mem: sail-ss-region@80000000 {
+			reg = <0x0 0x80000000 0x0 0x10000000>;
+			no-map;
+		};
+
+		hyp_mem: hyp-region@90000000 {
+			reg = <0x0 0x90000000 0x0 0x600000>;
+			no-map;
+		};
+
+		xbl_boot_mem: xbl-boot-region@90600000 {
+			reg = <0x0 0x90600000 0x0 0x200000>;
+			no-map;
+		};
+
+		aop_image_mem: aop-image-region@90800000 {
+			reg = <0x0 0x90800000 0x0 0x60000>;
+			no-map;
+		};
+
+		aop_cmd_db_mem: aop-cmd-db-region@90860000 {
+			compatible = "qcom,cmd-db";
+			reg = <0x0 0x90860000 0x0 0x20000>;
+			no-map;
+		};
+
+		uefi_logs_mem: uefi-logs-region@908b0000 {
+			reg = <0x0 0x908b0000 0x0 0x10000>;
+			no-map;
+		};
+
+		ddr_training_checksum_data_mem: ddr-training-checksum-data-region@908c0000 {
+			reg = <0x0 0x908c0000 0x0 0x1000>;
+			no-map;
+		};
+
+		reserved_mem: reserved-region@908f0000 {
+			reg = <0x0 0x908f0000 0x0 0xe000>;
+			no-map;
+		};
+
+		secboot_emulation_mem: secboot-emulation-region@908fe000 {
+			reg = <0x0 0x908fe000 0x0 0x2000>;
+			no-map;
+		};
+
+		smem_mem: smem@90900000 {
+			compatible = "qcom,smem";
+			reg = <0x0 0x90900000 0x0 0x200000>;
+			no-map;
+			hwlocks = <&tcsr_mutex 3>;
+		};
+
+		tz_sail_mailbox_mem: tz-sail-mailbox-region@90c00000 {
+			reg = <0x0 0x90c00000 0x0 0x100000>;
+			no-map;
+		};
+
+		sail_mailbox_mem: sail-mailbox-region@90d00000 {
+			reg = <0x0 0x90d00000 0x0 0x100000>;
+			no-map;
+		};
+
+		sail_ota_mem: sail-ota-region@90e00000 {
+			reg = <0x0 0x90e00000 0x0 0x300000>;
+			no-map;
+		};
+
+		xbl_dtlog_mem: xbl-dtlog-region@91a40000 {
+			reg = <0x0 0x91a40000 0x0 0x40000>;
+			no-map;
+		};
+
+		gunyah_md_mem: gunyah-md-region@91a80000 {
+			reg = <0x0 0x91a80000 0x0 0x80000>;
+			no-map;
+		};
+
+		aoss_backup_mem: aoss-backup-region@91b00000 {
+			reg = <0x0 0x91b00000 0x0 0x40000>;
+			no-map;
+		};
+
+		cpucp_backup_mem: cpucp-backup-region@91b40000 {
+			reg = <0x0 0x91b40000 0x0 0x40000>;
+			no-map;
+		};
+
+		tz_config_backup_mem: tz-config-backup-region@91b80000 {
+			reg = <0x0 0x91b80000 0x0 0x10000>;
+			no-map;
+		};
+
+		ddr_training_data_mem: ddr-training-data-region@91b90000 {
+			reg = <0x0 0x91b90000 0x0 0x10000>;
+			no-map;
+		};
+
+		cdt_data_backup_mem: cdt-data-backup-region@91ba0000 {
+			reg = <0x0 0x91ba0000 0x0 0x1000>;
+			no-map;
+		};
+
+		lpass_machine_learning_mem: lpass-machine-learning-region@93b00000 {
+			reg = <0x0 0x93b00000 0x0 0xf00000>;
+			no-map;
+		};
+
+		adsp_rpc_remote_heap_mem: adsp-rpc-remote-heap-region@94a00000 {
+			reg = <0x0 0x94a00000 0x0 0x800000>;
+			no-map;
+		};
+
+		camera_mem: pil-camera-region@95200000 {
+			reg = <0x0 0x95200000 0x0 0x700000>;
+			no-map;
+		};
+
+		adsp_mem: pil-adsp-region@95c00000 {
+			no-map;
+			reg = <0x0 0x95c00000 0x0 0x1e00000>;
+		};
+
+		q6_adsp_dtb_mem: q6-adsp-dtb-region@97a00000 {
+			reg = <0x0 0x97a00000 0x0 0x80000>;
+			no-map;
+		};
+
+		q6_gpdsp_dtb_mem: q6-gpdsp-dtb-region@97a80000 {
+			reg = <0x0 0x97a80000 0x0 0x80000>;
+			no-map;
+		};
+
+		gpdsp_mem: pil-gpdsp-region@97b00000 {
+			reg = <0x0 0x97b00000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		q6_cdsp_dtb_mem: q6-cdsp-dtb-region@9b700000 {
+			reg = <0x0 0x9b700000 0x0 0x80000>;
+			no-map;
+		};
+
+		cdsp_mem: pil_cdsp-region@99900000 {
+			reg = <0x0 0x99900000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		gpu_microcode_mem: pil-gpu-region@9b780000 {
+			reg = <0x0 0x9b780000 0x0 0x2000>;
+			no-map;
+		};
+
+		cvp_mem: pil-cvp-region@9b782000 {
+			reg = <0x0 0x9b782000 0x0 0x700000>;
+			no-map;
+		};
+
+		video_mem: pil-video-region@9be82000 {
+			reg = <0x0 0x9be82000 0x0 0x700000>;
+			no-map;
+		};
+
+		audio_mdf_mem: audio-mdf-region@ae000000 {
+			reg = <0x0 0xae000000 0x0 0x1000000>;
+			no-map;
+		};
+
+		firmware_mem: firmware-region@b0000000 {
+			reg = <0x0 0xb0000000 0x0 0x800000>;
+			no-map;
+		};
+
+		firmware_scmi_mem: scmi-region@d0000000 {
+			reg = <0x0 0xd0000000 0x0 0x40000>;
+			no-map;
+		};
+
+		firmware_logs_mem: firmware-logs-region@d0040000 {
+			reg = <0x0 0xd0040000 0x0 0x10000>;
+			no-map;
+		};
+
+		firmware_audio_mem: firmware-audio-region@d0050000 {
+			reg = <0x0 0xd0050000 0x0 0x4000>;
+			no-map;
+		};
+
+		firmware_reserved_mem: firmware-reserved@d0054000 {
+			reg = <0x0 0xd0054000 0x0 0x9c000>;
+			no-map;
+		};
+
+		firmwarequantum_test_mem: firmwarequantum-test-region@d00f0000 {
+			reg = <0x0 0xd00f0000 0x0 0x10000>;
+			no-map;
+		};
+
+		tags_mem: tags-region@d0100000 {
+			reg = <0x0 0xd0100000 0x0 0x800000>;
+			no-map;
+		};
+
+		qtee_mem: qtee-region@d1300000 {
+			reg = <0x0 0xd1300000 0x0 0x500000>;
+			no-map;
+		};
+
+		deep_sleep_back_up_mem: deep-sleep-back-up-region@d1800000 {
+			reg = <0x0 0xd1800000 0x0 0x100000>;
+			no-map;
+		};
+
+		trusted_apps_mem: trusted-apps-region@d1900000 {
+			reg = <0x0 0xd1900000 0x0 0x1900000>;
+			no-map;
+		};
+
+		tz_stat_mem: tz-stat-region@db100000 {
+			reg = <0x0 0xdb100000 0x0 0x100000>;
+			no-map;
+		};
+
+		cpucp_fw_mem: cpucp-fw-region@db200000 {
+			reg = <0x0 0xdb200000 0x0 0x100000>;
+			no-map;
+		};
+
+		cdsp_secure_heap: secure-cdsp-region {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x2000000>;
+		};
+	};
+
+	smp2p-adsp {
+		compatible = "qcom,smp2p";
+		qcom,smem = <443>, <429>;
+		interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+					     IPCC_MPROC_SIGNAL_SMP2P
+					     IRQ_TYPE_EDGE_RISING>;
+		mboxes = <&ipcc IPCC_CLIENT_LPASS
+				IPCC_MPROC_SIGNAL_SMP2P>;
+
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <2>;
+
+		smp2p_adsp_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_adsp_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		smp2p_rdbg2_out: smp2p-rdbg2-out {
+			qcom,entry-name = "rdbg";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_rdbg2_in: smp2p-rdbg2-in {
+			qcom,entry-name = "rdbg";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	smp2p-cdsp {
+		compatible = "qcom,smp2p";
+		qcom,smem = <94>, <432>;
+		interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
+					     IPCC_MPROC_SIGNAL_SMP2P
+					     IRQ_TYPE_EDGE_RISING>;
+		mboxes = <&ipcc IPCC_CLIENT_CDSP
+				IPCC_MPROC_SIGNAL_SMP2P>;
+
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <5>;
+
+		smp2p_cdsp_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_cdsp_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		smp2p_rdbg5_out: smp2p-rdbg5-out {
+			qcom,entry-name = "rdbg";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_rdbg5_in: smp2p-rdbg5-in {
+			qcom,entry-name = "rdbg";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	smp2p-gpdsp {
+		compatible = "qcom,smp2p";
+		qcom,smem = <617>, <616>;
+		interrupts-extended = <&ipcc IPCC_CLIENT_GPDSP0
+					     IPCC_MPROC_SIGNAL_SMP2P
+					     IRQ_TYPE_EDGE_RISING>;
+		mboxes = <&ipcc IPCC_CLIENT_GPDSP0
+				IPCC_MPROC_SIGNAL_SMP2P>;
+
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <17>;
+
+		smp2p_gpdsp_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_gpdsp_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	qcom-smp2p-interrupt-rdbg-2-in {
+		compatible = "qcom,smp2p-interrupt-rdbg-2-in";
+		interrupts-extended = <&smp2p_rdbg2_in 0 IRQ_TYPE_NONE>;
+		interrupt-names = "rdbg-smp2p-in";
+	};
+
+	qcom-smp2p-interrupt-rdbg-2-out {
+		compatible = "qcom,smp2p-interrupt-rdbg-2-out";
+		qcom,smem-states = <&smp2p_rdbg2_out 0>;
+		qcom,smem-state-names = "rdbg-smp2p-out";
+	};
+
+	qcom-smp2p-interrupt-rdbg-5-in {
+		compatible = "qcom,smp2p-interrupt-rdbg-5-in";
+		interrupts-extended = <&smp2p_rdbg5_in 0 IRQ_TYPE_NONE>;
+		interrupt-names = "rdbg-smp2p-in";
+	};
+
+	qcom-smp2p-interrupt-rdbg-5-out {
+		compatible = "qcom,smp2p-interrupt-rdbg-5-out";
+		qcom,smem-states = <&smp2p_rdbg5_out 0>;
+		qcom,smem-state-names = "rdbg-smp2p-out";
+	};
+
+	soc: soc@0 {
+		compatible = "simple-bus";
+		ranges = <0 0 0 0 0x10 0>;
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		ethernet0: ethernet@23040000 {
+			compatible = "qcom,qcs8300-ethqos";
+			reg = <0x0 0x23040000 0x0 0x10000>,
+			      <0x0 0x23056000 0x0 0x100>;
+			reg-names = "stmmaceth", "rgmii";
+
+			interrupts = <GIC_SPI 946 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 783 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq", "sfty";
+
+			clocks = <&gcc GCC_EMAC0_AXI_CLK>,
+				 <&gcc GCC_EMAC0_SLV_AHB_CLK>,
+				 <&gcc GCC_EMAC0_PTP_CLK>,
+				 <&gcc GCC_EMAC0_PHY_AUX_CLK>;
+			clock-names = "stmmaceth",
+				      "pclk",
+				      "ptp_ref",
+				      "phyaux";
+			power-domains = <&gcc GCC_EMAC0_GDSC>;
+
+			phys = <&serdes0>;
+			phy-names = "serdes";
+
+			iommus = <&apps_smmu 0x120 0xf>;
+			dma-coherent;
+
+			snps,tso;
+			snps,pbl = <32>;
+			rx-fifo-depth = <16384>;
+			tx-fifo-depth = <20480>;
+
+			status = "disabled";
+		};
+
+		gcc: clock-controller@100000 {
+			compatible = "qcom,qcs8300-gcc";
+			reg = <0x0 0x00100000 0x0 0xc7018>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+			clocks = <&rpmhcc RPMH_CXO_CLK>,
+				 <&sleep_clk>,
+				 <&pcie0_phy>,
+				 <&pcie1_phy>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>,
+				 <0>;
+		};
+
+		ipcc: mailbox@408000 {
+			compatible = "qcom,qcs8300-ipcc", "qcom,ipcc";
+			reg = <0x0 0x408000 0x0 0x1000>;
+			interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			#mbox-cells = <2>;
+		};
+
+		qfprom: efuse@784000 {
+			compatible = "qcom,qcs8300-qfprom", "qcom,qfprom";
+			reg = <0x0 0x00784000 0x0 0x2410>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			gpu_speed_bin: gpu_speed_bin@240c {
+				reg = <0x240c 0x1>;
+				bits = <0 8>;
+			};
+		};
+
+		gpi_dma0: qcom,gpi-dma@900000 {
+			compatible = "qcom,sm6350-gpi-dma";
+			#dma-cells = <3>;
+			reg = <0x0 0x900000 0x0 0x60000>;
+			interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>;
+			iommus = <&apps_smmu 0x416 0x0>;
+			dma-channels = <12>;
+			dma-channel-mask = <0xfff>;
+			dma-coherent;
+			status = "ok";
+		};
+
+		qupv3_id_0: geniqup@9c0000 {
+			compatible = "qcom,geni-se-qup";
+			reg = <0x0 0x9c0000 0x0 0x2000>;
+			ranges;
+			clocks = <&gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>,
+				 <&gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>;
+			clock-names = "m-ahb", "s-ahb";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			iommus = <&apps_smmu 0x403 0x0>;
+			dma-coherent;
+			status = "disabled";
+
+			i2c0: i2c@980000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x980000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c0_data_clk>;
+				interrupts = <GIC_SPI 550 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>,
+				<&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma0 0 0 QCOM_GPI_I2C>,
+					<&gpi_dma0 1 0 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi0: spi@980000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x980000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi0_data_clk>, <&qup_spi0_cs>;
+				interrupts = <GIC_SPI 550 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma0 0 0 QCOM_GPI_SPI>,
+					<&gpi_dma0 1 0 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart0: serial@980000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x980000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart0_cts>, <&qup_uart0_rts>,
+					    <&qup_uart0_tx>, <&qup_uart0_rx>;
+				interrupts = <GIC_SPI 550 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c1: i2c@984000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x984000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c1_data_clk>;
+				interrupts = <GIC_SPI 551 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>,
+				<&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma0 0 1 QCOM_GPI_I2C>,
+					<&gpi_dma0 1 1 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi1: spi@984000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x984000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi1_data_clk>, <&qup_spi1_cs>;
+				interrupts = <GIC_SPI 551 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma0 0 1 QCOM_GPI_SPI>,
+					<&gpi_dma0 1 1 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart1: serial@984000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x984000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart1_cts>, <&qup_uart1_rts>,
+					    <&qup_uart1_tx>, <&qup_uart1_rx>;
+				interrupts = <GIC_SPI 551 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c2: i2c@988000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x988000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c2_data_clk>;
+				interrupts = <GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>,
+				<&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma0 0 2 QCOM_GPI_I2C>,
+					<&gpi_dma0 1 2 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi2: spi@988000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x988000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi2_data_clk>, <&qup_spi2_cs>;
+				interrupts = <GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma0 0 2 QCOM_GPI_SPI>,
+					<&gpi_dma0 1 2 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart2: serial@988000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x988000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart2_cts>, <&qup_uart2_rts>,
+					    <&qup_uart2_tx>, <&qup_uart2_rx>;
+				interrupts = <GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c3: i2c@98c000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x98c000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c3_data_clk>;
+				interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>,
+				<&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma0 0 3 QCOM_GPI_I2C>,
+					<&gpi_dma0 1 3 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi3: spi@98c000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x98c000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi3_data_clk>, <&qup_spi3_cs>;
+				interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma0 0 3 QCOM_GPI_SPI>,
+					<&gpi_dma0 1 3 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart3: serial@98c000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x98c000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart3_cts>, <&qup_uart3_rts>,
+					    <&qup_uart3_tx>, <&qup_uart3_rx>;
+				interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c4: i2c@990000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x990000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c4_data_clk>;
+				interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>,
+				<&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma0 0 4 QCOM_GPI_I2C>,
+					<&gpi_dma0 1 4 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi4: spi@990000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x990000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi4_data_clk>, <&qup_spi4_cs>;
+				interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma0 0 4 QCOM_GPI_SPI>,
+					<&gpi_dma0 1 4 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart4: serial@990000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x990000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart4_cts>, <&qup_uart4_rts>,
+					    <&qup_uart4_tx>, <&qup_uart4_rx>;
+				interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c5: i2c@994000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x994000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c5_data_clk>;
+				interrupts = <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>,
+				<&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma0 0 5 QCOM_GPI_I2C>,
+					<&gpi_dma0 1 5 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi5: spi@994000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x994000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi5_data_clk>, <&qup_spi5_cs>;
+				interrupts = <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma0 0 5 QCOM_GPI_SPI>,
+					<&gpi_dma0 1 5 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart5: serial@994000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x994000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart5_cts>, <&qup_uart5_rts>,
+					    <&qup_uart5_tx>, <&qup_uart5_rx>;
+				interrupts = <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c6: i2c@998000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0x998000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S6_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c6_data_clk>;
+				interrupts = <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>,
+				<&aggre2_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma0 0 6 QCOM_GPI_I2C>,
+					<&gpi_dma0 1 6 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi6: spi@998000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0x998000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S6_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi6_data_clk>, <&qup_spi6_cs>;
+				interrupts = <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma0 0 6 QCOM_GPI_SPI>,
+					<&gpi_dma0 1 6 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart6: serial@998000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x998000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S6_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart6_cts>, <&qup_uart6_rts>,
+					    <&qup_uart6_tx>, <&qup_uart6_rx>;
+				interrupts = <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			uart7: serial@99c000 {
+				compatible = "qcom,geni-debug-uart";
+				reg = <0x0 0x0099c000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S7_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart7_tx>, <&qup_uart7_rx>;
+				interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_0 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+		};
+
+		gpi_dma1: qcom,gpi-dma@a00000 {
+			compatible = "qcom,sm6350-gpi-dma";
+			#dma-cells = <3>;
+			reg = <0x0 0xa00000 0x0 0x60000>;
+			interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 293 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 294 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 295 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 296 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 297 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>;
+			iommus = <&apps_smmu 0x456 0x0>;
+			dma-channels = <12>;
+			dma-channel-mask = <0xfff>;
+			dma-coherent;
+			status = "ok";
+		};
+
+		qupv3_id_1: geniqup@ac0000 {
+			compatible = "qcom,geni-se-qup";
+			reg = <0x0 0xac0000 0x0 0x2000>;
+			ranges;
+			clocks = <&gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>,
+				 <&gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>;
+			clock-names = "m-ahb", "s-ahb";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			iommus = <&apps_smmu 0x443 0x0>;
+			dma-coherent;
+			status = "disabled";
+
+			i2c8: i2c@a80000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0xa80000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+				clock-names = "se";
+				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+				<&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>,
+					<&gpi_dma1 1 0 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi8: spi@a80000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0xa80000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi8_data_clk>, <&qup_spi8_cs>;
+				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma1 0 0 QCOM_GPI_SPI>,
+					<&gpi_dma1 1 0 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart8: serial@a80000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0xa80000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart8_cts>, <&qup_uart8_rts>,
+					    <&qup_uart8_tx>, <&qup_uart8_rx>;
+				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c9: i2c@a84000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0xa84000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c9_data_clk>;
+				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+				<&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>,
+					<&gpi_dma1 1 1 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi9: spi@a84000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0xa84000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi9_data_clk>, <&qup_spi9_cs>;
+				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma1 0 1 QCOM_GPI_SPI>,
+					<&gpi_dma1 1 1 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart9: serial@a84000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0xa84000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart9_cts>, <&qup_uart9_rts>,
+					    <&qup_uart9_tx>, <&qup_uart9_rx>;
+				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c10: i2c@a88000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0xa88000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c10_data_clk>;
+				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+				<&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>,
+					<&gpi_dma1 1 2 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi10: spi@a88000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0xa88000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi10_data_clk>, <&qup_spi10_cs>;
+				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma1 0 2 QCOM_GPI_SPI>,
+					<&gpi_dma1 1 2 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart10: serial@a88000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0xa88000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart10_cts>, <&qup_uart10_rts>,
+					    <&qup_uart10_tx>, <&qup_uart10_rx>;
+				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c11: i2c@a8c000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0xa8c000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c11_data_clk>;
+				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+				<&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>,
+					<&gpi_dma1 1 3 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart11: serial@a8c000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0xa8c000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart11_tx>, <&qup_uart11_rx>;
+				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c12: i2c@a90000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0xa90000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c12_data_clk>;
+				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+				<&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma1 0 4 QCOM_GPI_I2C>,
+					<&gpi_dma1 1 4 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi12: spi@a90000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0xa90000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi12_data_clk>, <&qup_spi12_cs>;
+				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma1 0 4 QCOM_GPI_SPI>,
+					<&gpi_dma1 1 4 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart12: serial@a90000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0xa90000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart12_cts>, <&qup_uart12_rts>,
+					    <&qup_uart12_tx>, <&qup_uart12_rx>;
+				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c13: i2c@a94000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0xa94000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c13_data_clk>;
+				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+				<&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma1 0 5 QCOM_GPI_I2C>,
+					<&gpi_dma1 1 5 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi13: spi@a94000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0xa94000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi13_data_clk>, <&qup_spi13_cs>;
+				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma1 0 5 QCOM_GPI_SPI>,
+					<&gpi_dma1 1 5 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart13: serial@a94000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0xa94000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart13_cts>, <&qup_uart13_rts>,
+					    <&qup_uart13_tx>, <&qup_uart13_rx>;
+				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c14: i2c@a98000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0xa98000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c14_data_clk>;
+				interrupts = <GIC_SPI 835 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+				<&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma1 0 6 QCOM_GPI_I2C>,
+					<&gpi_dma1 1 6 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi14: spi@a98000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0xa98000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi14_data_clk>, <&qup_spi14_cs>;
+				interrupts = <GIC_SPI 835 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma1 0 6 QCOM_GPI_SPI>,
+					<&gpi_dma1 1 6 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart14: serial@a98000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0xa98000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart14_cts>, <&qup_uart14_rts>,
+					    <&qup_uart14_tx>, <&qup_uart14_rx>;
+				interrupts = <GIC_SPI 835 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+
+			i2c15: i2c@a9c000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0xa9c000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S7_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c15_data_clk>;
+				interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>,
+				<&aggre2_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma1 0 7 QCOM_GPI_I2C>,
+					<&gpi_dma1 1 7 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi15: spi@a9c000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0xa9c000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S7_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi15_data_clk>, <&qup_spi15_cs>;
+				interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma1 0 7 QCOM_GPI_SPI>,
+					<&gpi_dma1 1 7 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart15: serial@a9c000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0xa9c000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP1_S7_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart15_cts>, <&qup_uart15_rts>,
+					    <&qup_uart15_tx>, <&qup_uart15_rx>;
+				interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+		};
+
+		gpi_dma3: qcom,gpi-dma@b00000 {
+			compatible = "qcom,sm6350-gpi-dma";
+			#dma-cells = <3>;
+			reg = <0x0 0xb00000 0x0 0x60000>;
+			interrupts = <GIC_SPI 368 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 527 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 528 IRQ_TYPE_LEVEL_HIGH>;
+			iommus = <&apps_smmu 0x56 0x0>;
+			dma-channels = <4>;
+			dma-channel-mask = <0xf>;
+			dma-coherent;
+			status = "ok";
+		};
+
+		qupv3_id_3: geniqup@bc0000 {
+			compatible = "qcom,geni-se-qup";
+			reg = <0x0 0xbc0000 0x0 0x2000>;
+			ranges;
+			clocks = <&gcc GCC_QUPV3_WRAP_3_M_AHB_CLK>,
+				 <&gcc GCC_QUPV3_WRAP_3_S_AHB_CLK>;
+			clock-names = "m-ahb", "s-ahb";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			iommus = <&apps_smmu 0x43 0x0>;
+			dma-coherent;
+			status = "disabled";
+
+			i2c16: i2c@b80000 {
+				compatible = "qcom,geni-i2c";
+				reg = <0x0 0xb80000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP3_S0_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_i2c16_data_clk>;
+				interrupts = <GIC_SPI 830 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config", "qup-memory";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_3 0 &clk_virt SLAVE_QUP_CORE_3 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_3 0>,
+				<&aggre2_noc MASTER_QUP_3 0 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+				dmas = <&gpi_dma3 0 0 QCOM_GPI_I2C>,
+					<&gpi_dma3 1 0 QCOM_GPI_I2C>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			spi16: spi@b80000 {
+				compatible = "qcom,geni-spi";
+				reg = <0x0 0xb80000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP3_S0_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_spi16_data_clk>, <&qup_spi16_cs>;
+				interrupts = <GIC_SPI 830 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_3 0 &clk_virt SLAVE_QUP_CORE_3 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_3 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				dmas = <&gpi_dma3 0 0 QCOM_GPI_SPI>,
+					<&gpi_dma3 1 0 QCOM_GPI_SPI>;
+				dma-names = "tx", "rx";
+				status = "disabled";
+			};
+
+			uart16: serial@b80000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0xb80000 0x0 0x4000>;
+				clocks = <&gcc GCC_QUPV3_WRAP3_S0_CLK>;
+				clock-names = "se";
+				pinctrl-names = "default";
+				pinctrl-0 = <&qup_uart16_cts>, <&qup_uart16_rts>,
+					    <&qup_uart16_tx>, <&qup_uart16_rx>;
+				interrupts = <GIC_SPI 830 IRQ_TYPE_LEVEL_HIGH>;
+				interconnect-names = "qup-core", "qup-config";
+				interconnects =
+				<&clk_virt MASTER_QUP_CORE_3 0 &clk_virt SLAVE_QUP_CORE_3 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_3 0>;
+				power-domains = <&rpmhpd QCS8300_CX>;
+				operating-points-v2 = <&qup_opp_table>;
+				status = "disabled";
+			};
+		};
+
+		rng: rng@10d2000 {
+			compatible = "qcom,qcs8300-trng", "qcom,trng";
+			reg = <0 0x010d2000 0 0x1000>;
+		};
+
+		pcie0: pci@1c00000 {
+			compatible = "qcom,pcie-qcs8300";
+			reg = <0x0 0x01c00000 0x0 0x3000>,
+				<0x0 0x40000000 0x0 0xf20>,
+				<0x0 0x40000f20 0x0 0xa8>,
+				<0x0 0x40001000 0x0 0x4000>,
+				<0x0 0x40100000 0x0 0x100000>,
+				<0x0 0x01c03000 0x0 0x1000>;
+			reg-names = "parf", "dbi", "elbi", "atu", "config", "mhi";
+			device_type = "pci";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
+				<0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <0>;
+			num-lanes = <2>;
+
+			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi0", "msi1", "msi2", "msi3",
+					"msi4", "msi5", "msi6", "msi7";
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &intc GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+				<&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				<&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
+				<&gcc GCC_PCIE_0_SLV_AXI_CLK>,
+				<&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>;
+
+			clock-names = "aux",
+					"cfg",
+					"bus_master",
+					"bus_slave",
+					"slave_q2a";
+
+			assigned-clocks = <&gcc GCC_PCIE_0_AUX_CLK>;
+			assigned-clock-rates = <19200000>;
+
+			interconnects = <&pcie_anoc MASTER_PCIE_0 0 &mc_virt SLAVE_EBI1 0>,
+					<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_PCIE_0 0>;
+			interconnect-names = "pcie-mem", "cpu-pcie";
+
+			iommu-map = <0x0 &pcie_smmu 0x0000 0x1>,
+					<0x100 &pcie_smmu 0x0001 0x1>;
+
+			resets = <&gcc GCC_PCIE_0_BCR>;
+			reset-names = "pci";
+			power-domains = <&gcc GCC_PCIE_0_GDSC>;
+
+			phys = <&pcie0_phy>;
+			phy-names = "pciephy";
+
+			status = "disabled";
+
+			pcie3_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				/* GEN 1 x1 */
+				opp-2500000 {
+					opp-hz = /bits/ 64 <2500000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+					opp-peak-kBps = <250000 1>;
+				};
+
+				/* GEN 1 x2 and GEN 2 x1 */
+				opp-5000000 {
+					opp-hz = /bits/ 64 <5000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+					opp-peak-kBps = <500000 1>;
+				};
+
+				/* GEN 2 x2 */
+				opp-10000000 {
+					opp-hz = /bits/ 64 <10000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+					opp-peak-kBps = <1000000 1>;
+				};
+
+				/* GEN 3 x1 */
+				opp-8000000 {
+					opp-hz = /bits/ 64 <8000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+					opp-peak-kBps = <984500 1>;
+				};
+
+				/* GEN 3 x2 and GEN 4 x1 */
+				opp-16000000 {
+					opp-hz = /bits/ 64 <16000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <1969000 1>;
+				};
+
+				/* GEN 4 x2 */
+				opp-32000000 {
+					opp-hz = /bits/ 64 <32000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <3938000 1>;
+				};
+			};
+
+			pcieport0: pcie@0 {
+				device_type = "pci";
+				reg = <0x0 0x0 0x0 0x0 0x0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				ranges;
+				bus-range = <0x01 0xff>;
+			};
+		};
+
+		pcie0_phy: phy@1c04000 {
+			compatible = "qcom,qcs8300-qmp-gen4x2-pcie-phy";
+			reg = <0x0 0x1c04000 0x0 0x2000>;
+
+			clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+				<&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				<&gcc GCC_PCIE_CLKREF_EN>,
+				<&gcc GCC_PCIE_0_PHY_RCHNG_CLK>,
+				<&gcc GCC_PCIE_0_PIPE_CLK>,
+				<&gcc GCC_PCIE_0_PIPEDIV2_CLK>,
+				<&gcc GCC_PCIE_0_PHY_AUX_CLK>;
+
+			clock-names = "aux", "cfg_ahb", "ref", "rchng", "pipe",
+					"pipediv2", "phy_aux";
+
+			assigned-clocks = <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>;
+
+			resets = <&gcc GCC_PCIE_0_PHY_BCR>;
+			reset-names = "phy";
+
+			#clock-cells = <0>;
+			clock-output-names = "pcie_0_pipe_clk";
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
+
+		pcie1: pci@1c10000 {
+			compatible = "qcom,pcie-qcs8300";
+			reg = <0x0 0x01c10000 0x0 0x3000>,
+			      <0x0 0x60000000 0x0 0xf20>,
+			      <0x0 0x60000f20 0x0 0xa8>,
+			      <0x0 0x60001000 0x0 0x4000>,
+			      <0x0 0x60100000 0x0 0x100000>,
+			      <0x0 0x01c13000 0x0 0x1000>;
+			reg-names = "parf", "dbi", "elbi", "atu", "config", "mhi";
+			device_type = "pci";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x1fd00000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <1>;
+			num-lanes = <4>;
+
+			interrupts = <GIC_SPI 519 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi0", "msi1", "msi2", "msi3",
+					  "msi4", "msi5", "msi6", "msi7";
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &intc GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_1_AUX_CLK>,
+				 <&gcc GCC_PCIE_1_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_1_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_1_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_1_SLV_Q2A_AXI_CLK>;
+
+			clock-names = "aux",
+				      "cfg",
+				      "bus_master",
+				      "bus_slave",
+				      "slave_q2a";
+
+			assigned-clocks = <&gcc GCC_PCIE_1_AUX_CLK>;
+			assigned-clock-rates = <19200000>;
+
+			interconnects = <&pcie_anoc MASTER_PCIE_1 0 &mc_virt SLAVE_EBI1 0>,
+					<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_PCIE_1 0>;
+			interconnect-names = "pcie-mem", "cpu-pcie";
+
+			iommu-map = <0x0 &pcie_smmu 0x0080 0x1>,
+				    <0x100 &pcie_smmu 0x0081 0x1>;
+
+			resets = <&gcc GCC_PCIE_1_BCR>;
+			reset-names = "pci";
+			power-domains = <&gcc GCC_PCIE_1_GDSC>;
+
+			phys = <&pcie1_phy>;
+			phy-names = "pciephy";
+
+			status = "disabled";
+		};
+
+		pcie1_phy: phy@1c14000 {
+			compatible = "qcom,sa8775p-qmp-gen4x4-pcie-phy";
+			reg = <0x0 0x1c14000 0x0 0x4000>;
+
+			clocks = <&gcc GCC_PCIE_1_AUX_CLK>,
+				<&gcc GCC_PCIE_1_CFG_AHB_CLK>,
+				<&gcc GCC_PCIE_CLKREF_EN>,
+				<&gcc GCC_PCIE_1_PHY_RCHNG_CLK>,
+				<&gcc GCC_PCIE_1_PIPE_CLK>,
+				<&gcc GCC_PCIE_1_PIPEDIV2_CLK>,
+				<&gcc GCC_PCIE_1_PHY_AUX_CLK>;
+
+			clock-names = "aux", "cfg_ahb", "ref", "rchng", "pipe",
+					"pipediv2", "phy_aux";
+
+			assigned-clocks = <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>;
+
+			resets = <&gcc GCC_PCIE_1_PHY_BCR>;
+			reset-names = "phy";
+
+			#clock-cells = <0>;
+			clock-output-names = "pcie_1_pipe_clk";
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
+		ufs_mem_hc: ufs@1d84000 {
+			compatible = "qcom,qcs8300-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
+			reg = <0x0 0x01d84000 0x0 0x3000>;
+			interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+			phys = <&ufs_mem_phy>;
+			phy-names = "ufsphy";
+			lanes-per-direction = <2>;
+			#reset-cells = <1>;
+			reset-gpios = <&tlmm 133 1>;
+			resets = <&gcc GCC_UFS_PHY_BCR>;
+			reset-names = "rst";
+
+			power-domains = <&gcc GCC_UFS_PHY_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
+
+			iommus = <&apps_smmu 0x100 0x0>;
+			dma-coherent;
+
+			interconnects = <&aggre1_noc MASTER_UFS_MEM 0
+					&mc_virt SLAVE_EBI1 0>,
+					<&gem_noc MASTER_APPSS_PROC 0
+					&config_noc SLAVE_UFS_MEM_CFG 0>;
+			interconnect-names = "ufs-ddr", "cpu-ufs";
+
+			clocks = <&gcc GCC_UFS_PHY_AXI_CLK>,
+				 <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+				 <&gcc GCC_UFS_PHY_AHB_CLK>,
+				 <&gcc GCC_UFS_PHY_UNIPRO_CORE_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>,
+				 <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>,
+				 <&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>;
+			clock-names = "core_clk",
+				      "bus_aggr_clk",
+				      "iface_clk",
+				      "core_clk_unipro",
+				      "ref_clk",
+				      "tx_lane0_sync_clk",
+				      "rx_lane0_sync_clk",
+				      "rx_lane1_sync_clk";
+			freq-table-hz = <75000000 300000000>,
+					<0 0>,
+					<0 0>,
+					<75000000 300000000>,
+					<0 0>,
+					<0 0>,
+					<0 0>,
+					<0 0>;
+			qcom,ice = <&ice>;
+			status = "disabled";
+		};
+
+		ufs_mem_phy: phy@1d87000 {
+			compatible = "qcom,qcs8300-qmp-ufs-phy";
+			reg = <0x0 0x01d87000 0x0 0xe10>;
+			/*
+			 * Yes, GCC_EDP_REF_CLKREF_EN is correct in qref. It
+			 * enables the CXO clock to eDP *and* UFS PHY.
+			 */
+			clocks = <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+				 <&gcc GCC_EDP_REF_CLKREF_EN>;
+			clock-names = "ref", "ref_aux", "qref";
+			power-domains = <&gcc GCC_UFS_PHY_GDSC>;
+
+			resets = <&ufs_mem_hc 0>;
+			reset-names = "ufsphy";
+
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		ice: crypto@1d88000 {
+			compatible = "qcom,inline-crypto-engine";
+			reg = <0x0 0x01d88000 0x0 0x10000>;
+			qcom,ice-use-hwkm;
+			clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>;
+		};
+
+		cryptobam: dma-controller@1dc4000 {
+			compatible = "qcom,bam-v1.7.4", "qcom,bam-v1.7.0";
+			reg = <0x0 0x01dc4000 0x0 0x28000>;
+			interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			qcom,ee = <0>;
+			qcom,controlled-remotely;
+			num-channels = <20>;
+			qcom,num-ees = <4>;
+			iommus = <&apps_smmu 0x480 0x00>,
+				 <&apps_smmu 0x481 0x00>;
+		};
+
+		crypto: crypto@1dfa000 {
+			compatible = "qcom,qcs8300-qce", "qcom,qce";
+			reg = <0x0 0x01dfa000 0x0 0x6000>;
+			dmas = <&cryptobam 4>, <&cryptobam 5>;
+			dma-names = "rx", "tx";
+			iommus = <&apps_smmu 0x480 0x00>,
+				 <&apps_smmu 0x481 0x00>;
+			interconnects = <&aggre2_noc MASTER_CRYPTO_CORE0 0 &mc_virt SLAVE_EBI1 0>;
+			interconnect-names = "memory";
+			qcom,icc_bw = <12473>;
+		};
+
+		remoteproc_adsp: remoteproc@3000000 {
+			compatible = "qcom,qcs8300-adsp-pas";
+			reg = <0x0 0x3000000 0x0 0x00100>;
+
+			interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog", "fatal", "ready",
+					  "handover", "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_LCX>,
+					<&rpmhpd RPMHPD_LMX>;
+			power-domain-names = "lcx", "lmx";
+
+			memory-region = <&adsp_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_adsp_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			remoteproc_adsp_glink: glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_LPASS
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "lpass";
+				qcom,remote-pid = <2>;
+
+				fastrpc {
+					compatible = "qcom,fastrpc";
+					qcom,glink-channels = "fastrpcglink-apps-dsp";
+					label = "adsp";
+					memory-region = <&adsp_rpc_remote_heap_mem>;
+					qcom,vmids = <QCOM_SCM_VMID_LPASS
+						      QCOM_SCM_VMID_ADSP_HEAP>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					compute-cb@3 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <3>;
+						iommus = <&apps_smmu 0x2003 0x0>;
+						dma-coherent;
+					};
+
+					compute-cb@4 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <4>;
+						iommus = <&apps_smmu 0x2004 0x0>;
+						dma-coherent;
+					};
+
+					compute-cb@5 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <5>;
+						iommus = <&apps_smmu 0x2005 0x0>;
+						dma-coherent;
+					};
+				};
+
+				gpr {
+					compatible = "qcom,gpr";
+					qcom,glink-channels = "adsp_apps";
+					qcom,domain = <GPR_DOMAIN_ID_ADSP>;
+					qcom,intents = <512 20>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					q6apm: service@1 {
+						compatible = "qcom,q6apm";
+						reg = <GPR_APM_MODULE_IID>;
+						#sound-dai-cells = <0>;
+
+						q6apmbedai: bedais {
+							compatible = "qcom,q6apm-lpass-dais";
+							q6apm-dai-uses-dummy-ops;
+							#sound-dai-cells = <1>;
+						};
+					};
+
+					q6prm: service@2 {
+						compatible = "qcom,q6prm";
+						reg = <GPR_PRM_MODULE_IID>;
+
+						q6prmcc: clock-controller {
+							compatible = "qcom,q6prm-lpass-clocks";
+							#clock-cells = <2>;
+						};
+					};
+
+					spf-core {
+						compatible = "qcom,spf_core";
+						reg = <GPR_AMDB_MODULE_IID>;
+					};
+
+					audio-pkt {
+						compatible = "qcom,audio-pkt";
+						reg = <GPR_VCPM_MODULE_IID>;
+						qcom,audiopkt-ch-name = "apr_audio_svc";
+					};
+				};
+			};
+		};
+
+		serdes0: phy@8909000 {
+			compatible = "qcom,qcs8300-dwmac-sgmii-phy";
+			reg = <0x0 0x8909000 0x0 0xe10>;
+			clocks = <&gcc GCC_SGMI_CLKREF_EN>;
+			clock-names = "sgmi_ref";
+			#phy-cells = <0>;
+			status = "disabled";
+		};
+
+		tcsr_mutex: hwlock@1f40000 {
+			compatible = "qcom,tcsr-mutex";
+			reg = <0x0 0x01f40000 0x0 0x20000>;
+			#hwlock-cells = <1>;
+		};
+
+		gpucc: clock-controller@3d90000 {
+			compatible = "qcom,qcs8300-gpucc";
+			reg = <0x0 0x03d90000 0x0 0xa000>;
+			clocks = <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_GPU_GPLL0_CLK_SRC>,
+				 <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>;
+			clock-names = "bi_tcxo",
+				      "gcc_gpu_gpll0_clk_src",
+				      "gcc_gpu_gpll0_div_clk_src";
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
+		adreno_smmu: iommu@3da0000 {
+			compatible = "qcom,qcs8300-smmu-500", "qcom,adreno-smmu",
+				     "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x3da0000 0x0 0x20000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <2>;
+			dma-coherent;
+
+			power-domains = <&gpucc GPU_CC_CX_GDSC>;
+			clocks = <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+				 <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>,
+				 <&gpucc GPU_CC_AHB_CLK>,
+				 <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>,
+				 <&gpucc GPU_CC_CX_GMU_CLK>,
+				 <&gpucc GPU_CC_HUB_CX_INT_CLK>,
+				 <&gpucc GPU_CC_HUB_AON_CLK>;
+			clock-names = "gcc_gpu_memnoc_gfx_clk",
+				      "gcc_gpu_snoc_dvm_gfx_clk",
+				      "gpu_cc_ahb_clk",
+				      "gpu_cc_hlos1_vote_gpu_smmu_clk",
+				      "gpu_cc_cx_gmu_clk",
+				      "gpu_cc_hub_cx_int_clk",
+				      "gpu_cc_hub_aon_clk";
+			interrupts = <GIC_SPI 672 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 673 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 681 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 682 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		eud: eud@8901000 {
+			compatible = "qcom,secure-eud";
+			reg = <0x0 0x8901000 0x0 0x2000>,
+			      <0x0 0x8903000 0x0 0x1000>;
+			interrupts-extended = <&pdc 11 IRQ_TYPE_LEVEL_HIGH>;
+
+			status = "disabled";
+		};
+
+		pmu@9091000 {
+			compatible = "qcom,qcs8300-llcc-bwmon", "qcom,sc7280-llcc-bwmon";
+			reg = <0x0 0x9091000 0x0 0x1000>;
+
+			interrupts = <GIC_SPI 620 IRQ_TYPE_LEVEL_HIGH>;
+
+			interconnects = <&mc_virt MASTER_LLCC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+			operating-points-v2 = <&llcc_bwmon_opp_table>;
+
+			llcc_bwmon_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-0 {
+					opp-peak-kBps = <762000>;
+				};
+
+				opp-1 {
+					opp-peak-kBps = <1720000>;
+				};
+
+				opp-2 {
+					opp-peak-kBps = <2086000>;
+				};
+
+				opp-3 {
+					opp-peak-kBps = <2601000>;
+				};
+
+				opp-4 {
+					opp-peak-kBps = <2929000>;
+				};
+
+				opp-5 {
+					opp-peak-kBps = <5931000>;
+				};
+
+				opp-6 {
+					opp-peak-kBps = <6515000>;
+				};
+
+				opp-7 {
+					opp-peak-kBps = <7984000>;
+				};
+
+				opp-8 {
+					opp-peak-kBps = <10437000>;
+				};
+
+				opp-9 {
+					opp-peak-kBps = <12195000>;
+				};
+			};
+		};
+
+		pmu@90b5400 {
+			compatible = "qcom,qcs8300-cpu-bwmon", "qcom,sdm845-bwmon";
+			reg = <0x0 0x90b5400 0x0 0x600>;
+			interrupts = <GIC_SPI 581 IRQ_TYPE_LEVEL_HIGH>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+			operating-points-v2 = <&cpu_bwmon_opp_table>;
+
+			cpu_bwmon_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-0 {
+					opp-peak-kBps = <9155000>;
+				};
+
+				opp-1 {
+					opp-peak-kBps = <12298000>;
+				};
+
+				opp-2 {
+					opp-peak-kBps = <14236000>;
+				};
+
+				opp-3 {
+					opp-peak-kBps = <16265000>;
+				};
+			};
+		};
+
+		pmu@90b6400 {
+			compatible = "qcom,qcs8300-cpu-bwmon", "qcom,sdm845-bwmon";
+			reg = <0x0 0x90b6400 0x0 0x600>;
+			interrupts = <GIC_SPI 581 IRQ_TYPE_LEVEL_HIGH>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+			operating-points-v2 = <&cpu_bwmon_opp_table>;
+		};
+
+		llcc: system-cache-controller@9200000 {
+			compatible = "qcom,qcs8300-llcc";
+			reg = <0x0 0x09200000 0x0 0x80000>,
+			      <0x0 0x09300000 0x0 0x80000>,
+			      <0x0 0x09400000 0x0 0x80000>,
+			      <0x0 0x09500000 0x0 0x80000>,
+			      <0x0 0x09a00000 0x0 0x80000>;
+			reg-names = "llcc0_base",
+				    "llcc1_base",
+				    "llcc2_base",
+				    "llcc3_base",
+				    "llcc_broadcast_base";
+			interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>;
+			num-banks = <4>;
+		};
+
+		iris: video-codec@aa00000 {
+			compatible = "qcom,qcs8300-iris";
+
+			reg = <0x0 0x0aa00000 0x0 0xf0000>;
+			interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+
+			power-domains = <&videocc VIDEO_CC_MVS0C_GDSC>,
+					<&videocc VIDEO_CC_MVS0_GDSC>,
+					<&rpmhpd RPMHPD_MX>,
+					<&rpmhpd RPMHPD_MMCX>;
+			power-domain-names = "venus",
+					     "vcodec0",
+					     "mxc",
+					     "mmcx";
+
+			operating-points-v2 = <&iris_opp_table>;
+
+			clocks = <&gcc GCC_VIDEO_AXI0_CLK>,
+				 <&videocc VIDEO_CC_MVS0C_CLK>,
+				 <&videocc VIDEO_CC_MVS0_CLK>;
+			clock-names = "iface",
+				      "core",
+				      "vcodec0_core";
+
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &config_noc SLAVE_VENUS_CFG QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&mmss_noc MASTER_VIDEO_P0 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "cpu-cfg",
+					     "video-mem";
+
+			memory-region = <&video_mem>;
+
+			resets = <&gcc GCC_VIDEO_AXI0_CLK_ARES>;
+			reset-names = "bus";
+
+			iommus = <&apps_smmu 0x0880 0x0400>,
+				 <&apps_smmu 0x0887 0x0400>;
+			dma-coherent;
+
+			status = "disabled";
+
+			iris_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-366000000 {
+					opp-hz = /bits/ 64 <366000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>,
+							<&rpmhpd_opp_svs_l1>;
+				};
+
+				opp-444000000 {
+					opp-hz = /bits/ 64 <444000000>;
+					required-opps = <&rpmhpd_opp_nom>,
+							<&rpmhpd_opp_nom>;
+				};
+
+				opp-533333334 {
+					opp-hz = /bits/ 64 <533333334>;
+					required-opps = <&rpmhpd_opp_turbo>,
+							<&rpmhpd_opp_turbo>;
+				};
+
+				opp-560000000 {
+					opp-hz = /bits/ 64 <560000000>;
+					required-opps = <&rpmhpd_opp_turbo_l1>,
+							<&rpmhpd_opp_turbo_l1>;
+				};
+			};
+		};
+
+		videocc: clock-controller@abf0000 {
+			compatible = "qcom,qcs8300-videocc";
+			reg = <0x0 0x0abf0000 0x0 0x10000>;
+			clocks = <&gcc GCC_VIDEO_AHB_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK_A>,
+				 <&sleep_clk>;
+			power-domains = <&rpmhpd QCS8300_MMCX>;
+			required-opps = <&rpmhpd_opp_low_svs>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
+		camss: isp@ac7a000 {
+			compatible = "qcom,qcs8300-camss";
+
+			reg = <0x0 0x0ac7a000 0x0 0x0f01>,
+			      <0x0 0x0ac7c000 0x0 0x0f01>,
+			      <0x0 0x0ac84000 0x0 0x0f01>,
+			      <0x0 0x0ac88000 0x0 0x0f01>,
+			      <0x0 0x0ac8c000 0x0 0x0f01>,
+			      <0x0 0x0ac90000 0x0 0x0f01>,
+			      <0x0 0x0ac94000 0x0 0x0f01>,
+			      <0x0 0x0ac78000 0x0 0x1000>,
+			      <0x0 0x0ac9c000 0x0 0x2000>,
+			      <0x0 0x0ac9e000 0x0 0x2000>,
+			      <0x0 0x0aca0000 0x0 0x2000>,
+			      <0x0 0x0acac000 0x0 0x0400>,
+			      <0x0 0x0acad000 0x0 0x0400>,
+			      <0x0 0x0acae000 0x0 0x0400>,
+			      <0x0 0x0ac4d000 0x0 0xf000>,
+			      <0x0 0x0ac60000 0x0 0xf000>,
+			      <0x0 0x0ac85000 0x0 0x0d00>,
+			      <0x0 0x0ac89000 0x0 0x0d00>,
+			      <0x0 0x0ac8d000 0x0 0x0d00>,
+			      <0x0 0x0ac91000 0x0 0x0d00>,
+			      <0x0 0x0ac95000 0x0 0x0d00>;
+			reg-names = "csid0",
+				    "csid1",
+				    "csid_lite0",
+				    "csid_lite1",
+				    "csid_lite2",
+				    "csid_lite3",
+				    "csid_lite4",
+				    "csid_top",
+				    "csiphy0",
+				    "csiphy1",
+				    "csiphy2",
+				    "tpg0",
+				    "tpg1",
+				    "tpg2",
+				    "vfe0",
+				    "vfe1",
+				    "vfe_lite0",
+				    "vfe_lite1",
+				    "vfe_lite2",
+				    "vfe_lite3",
+				    "vfe_lite4";
+
+			clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+				 <&camcc CAM_CC_CCI_0_CLK>,
+				 <&camcc CAM_CC_CCI_1_CLK>,
+				 <&camcc CAM_CC_CCI_2_CLK>,
+				 <&camcc CAM_CC_CORE_AHB_CLK>,
+				 <&camcc CAM_CC_CPAS_AHB_CLK>,
+				 <&camcc CAM_CC_CPAS_FAST_AHB_CLK>,
+				 <&camcc CAM_CC_CPAS_IFE_0_CLK>,
+				 <&camcc CAM_CC_CPAS_IFE_1_CLK>,
+				 <&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+				 <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+				 <&camcc CAM_CC_CSID_CLK>,
+				 <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>,
+				 <&camcc CAM_CC_CSIPHY0_CLK>,
+				 <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY1_CLK>,
+				 <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY2_CLK>,
+				 <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
+				 <&gcc   GCC_CAMERA_HF_AXI_CLK>,
+				 <&gcc   GCC_CAMERA_SF_AXI_CLK>,
+				 <&gcc   GCC_CAMERA_AHB_CLK>,
+				 <&camcc CAM_CC_ICP_AHB_CLK>,
+				 <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+				 <&camcc CAM_CC_IFE_0_CLK>,
+				 <&camcc CAM_CC_IFE_0_FAST_AHB_CLK>,
+				 <&camcc CAM_CC_IFE_1_CLK>,
+				 <&camcc CAM_CC_IFE_1_FAST_AHB_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_CSID_CLK>;
+			clock-names = "camnoc_axi",
+				      "cci_0",
+				      "cci_1",
+				      "cci_2",
+				      "core_ahb",
+				      "cpas_ahb",
+				      "cpas_fast_ahb_clk",
+				      "cpas_vfe0",
+				      "cpas_vfe1",
+				      "cpas_vfe_lite",
+				      "cphy_rx_clk",
+				      "csid",
+				      "csid_csiphy_rx",
+				      "csiphy0",
+				      "csiphy0_timer",
+				      "csiphy1",
+				      "csiphy1_timer",
+				      "csiphy2",
+				      "csiphy2_timer",
+				      "gcc_axi_hf",
+				      "gcc_axi_sf",
+				      "gcc_camera_ahb",
+				      "icp_ahb",
+				      "slow_ahb_src",
+				      "vfe0",
+				      "vfe0_fast_ahb",
+				      "vfe1",
+				      "vfe1_fast_ahb",
+				      "vfe_lite",
+				      "vfe_lite_ahb",
+				      "vfe_lite_cphy_rx",
+				      "vfe_lite_csid";
+
+			interconnects = <&gem_noc MASTER_APPSS_PROC 0
+					 &config_noc SLAVE_CAMERA_CFG 0>,
+					<&mmss_noc MASTER_CAMNOC_HF 0 &mc_virt SLAVE_EBI1 0>,
+					<&mmss_noc MASTER_CAMNOC_SF 0 &mc_virt SLAVE_EBI1 0>;
+			interconnect-names = "ahb", "hf_0", "sf_0";
+
+			interrupts = <GIC_SPI 565 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 564 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 759 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 758 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 604 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 545 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 546 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 547 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 761 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 760 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 605 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "csid0",
+					  "csid1",
+					  "csid-lite0",
+					  "csid-lite1",
+					  "csid-lite2",
+					  "csid-lite3",
+					  "csid-lite4",
+					  "csiphy0",
+					  "csiphy1",
+					  "csiphy2",
+					  "tpg0",
+					  "tpg1",
+					  "tpg2",
+					  "vfe0",
+					  "vfe1",
+					  "vfe-lite0",
+					  "vfe-lite1",
+					  "vfe-lite2",
+					  "vfe-lite3",
+					  "vfe-lite4";
+
+			iommus = <&apps_smmu 0x2400 0x20>;
+
+			power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+			power-domain-names = "top";
+			operating-points-v2 = <&camss_opp_table>;
+
+			status = "disabled";
+
+			camss_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-400000000 {
+					opp-hz = /bits/ 64 <400000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+				};
+
+				opp-480000000 {
+					opp-hz = /bits/ 64 <480000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+				};
+
+				opp-600000000 {
+					opp-hz = /bits/ 64 <600000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+				};
+			};
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+				};
+
+				port@1 {
+					reg = <1>;
+				};
+
+				port@2 {
+					reg = <2>;
+				};
+			};
+		};
+
+		camcc: clock-controller@ade0000 {
+			compatible = "qcom,qcs8300-camcc";
+			reg = <0x0 0x0ade0000 0x0 0x20000>;
+			clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK_A>,
+				 <&sleep_clk>;
+			power-domains = <&rpmhpd QCS8300_MMCX>,
+					<&rpmhpd QCS8300_MXC>;
+			required-opps = <&rpmhpd_opp_low_svs>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
+		mdss: display-subsystem@ae00000 {
+			compatible = "qcom,qcs8300-mdss";
+			reg = <0x0 0x0ae00000 0x0 0x1000>;
+			reg-names = "mdss";
+
+			/* same path used twice */
+			interconnects = <&mmss_noc MASTER_MDP0 0 &mc_virt SLAVE_EBI1 0>,
+					<&mmss_noc MASTER_MDP1 0 &mc_virt SLAVE_EBI1 0>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+			interconnect-names = "mdp0-mem",
+					     "mdp1-mem",
+					     "cpu-cfg";
+
+			power-domains = <&dispcc0 MDSS_DISP_CC_MDSS_CORE_GDSC>;
+
+			clocks = <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>,
+				 <&gcc GCC_DISP_HF_AXI_CLK>,
+				 <&dispcc0 MDSS_DISP_CC_MDSS_MDP_CLK>;
+
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+
+			iommus = <&apps_smmu 0x1000 0x402>;
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			status = "disabled";
+
+			mdss_mdp: display-controller@ae01000 {
+				compatible = "qcom,qcs8300-dpu";
+				reg = <0x0 0x0ae01000 0x0 0x8f000>,
+				      <0x0 0x0aeb0000 0x0 0x2008>;
+				reg-names = "mdp", "vbif";
+
+				clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
+					<&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>,
+					<&dispcc0 MDSS_DISP_CC_MDSS_MDP_LUT_CLK>,
+					<&dispcc0 MDSS_DISP_CC_MDSS_MDP_CLK>,
+					<&dispcc0 MDSS_DISP_CC_MDSS_VSYNC_CLK>;
+				clock-names = "bus",
+					      "iface",
+					      "lut",
+					      "core",
+					      "vsync";
+
+				assigned-clocks = <&dispcc0 MDSS_DISP_CC_MDSS_VSYNC_CLK>;
+				assigned-clock-rates = <19200000>;
+
+				operating-points-v2 = <&mdp_opp_table>;
+				power-domains = <&rpmhpd QCS8300_MMCX>;
+
+				interrupt-parent = <&mdss>;
+				interrupts = <0>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port@0 {
+						reg = <0>;
+						dpu_intf0_out: endpoint {
+							remote-endpoint = <&mdss_dp0_in>;
+						};
+					};
+
+					port@1 {
+						reg = <1>;
+						dpu_intf1_out: endpoint {
+							remote-endpoint = <&mdss_dsi0_in>;
+						};
+					};
+				};
+
+				mdp_opp_table: opp-table {
+					compatible = "operating-points-v2";
+
+					opp-375000000 {
+						opp-hz = /bits/ 64 <375000000>;
+						required-opps = <&rpmhpd_opp_svs_l1>;
+					};
+
+					opp-500000000 {
+						opp-hz = /bits/ 64 <500000000>;
+						required-opps = <&rpmhpd_opp_nom>;
+					};
+
+					opp-575000000 {
+						opp-hz = /bits/ 64 <575000000>;
+						required-opps = <&rpmhpd_opp_turbo>;
+					};
+
+					opp-650000000 {
+						opp-hz = /bits/ 64 <650000000>;
+						required-opps = <&rpmhpd_opp_turbo_l1>;
+					};
+				};
+			};
+
+			mdss_dsi0: dsi@ae94000 {
+				compatible = "qcom,mdss-dsi-ctrl";
+				reg = <0x0 0x0ae94000 0x0 0x400>;
+				reg-names = "dsi_ctrl";
+
+				interrupt-parent = <&mdss>;
+				interrupts = <4>;
+
+				clocks = <&dispcc0 MDSS_DISP_CC_MDSS_BYTE0_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_BYTE0_INTF_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_PCLK0_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_ESC0_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>,
+					 <&gcc GCC_DISP_HF_AXI_CLK>;
+				clock-names = "byte",
+					      "byte_intf",
+					      "pixel",
+					      "core",
+					      "iface",
+					      "bus";
+
+				assigned-clocks = <&dispcc0 MDSS_DISP_CC_MDSS_BYTE0_CLK_SRC>,
+						  <&dispcc0 MDSS_DISP_CC_MDSS_PCLK0_CLK_SRC>;
+				assigned-clock-parents = <&mdss_dsi0_phy 0>,
+							 <&mdss_dsi0_phy 1>;
+
+				phys = <&mdss_dsi0_phy>;
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port@0 {
+						reg = <0>;
+						mdss_dsi0_in: endpoint {
+							remote-endpoint = <&dpu_intf1_out>;
+						};
+					};
+
+					port@1 {
+						reg = <1>;
+						mdss_dsi0_out: endpoint {
+						};
+					};
+				};
+
+				dsi0_opp_table: opp-table {
+					compatible = "operating-points-v2";
+
+					opp-358000000 {
+						opp-hz = /bits/ 64 <358000000>;
+						required-opps = <&rpmhpd_opp_svs_l1>;
+					};
+				};
+			};
+
+			mdss_dsi0_phy: phy@ae94400 {
+				compatible = "qcom,sa8775p-dsi-phy-5nm";
+				reg = <0x0 0x0ae94400 0x0 0x200>,
+				      <0x0 0x0ae94600 0x0 0x280>,
+				      <0x0 0x0ae94900 0x0 0x27c>;
+				reg-names = "dsi_phy",
+					    "dsi_phy_lane",
+					    "dsi_pll";
+
+				#clock-cells = <1>;
+				#phy-cells = <0>;
+
+				clocks = <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>,
+					 <&rpmhcc RPMH_CXO_CLK>;
+				clock-names = "iface", "ref";
+
+				status = "disabled";
+			};
+
+			mdss_edp_phy: phy@aec2a00 {
+				compatible = "qcom,qcs8300-edp-phy";
+
+				reg = <0x0 0xaec2a00 0x0 0x200>,
+					<0x0 0xaec2200 0x0 0xd0>,
+					<0x0 0xaec2600 0x0 0xd0>,
+					<0x0 0xaec2000 0x0 0x1c8>;
+
+				clocks = <&rpmhcc RPMH_CXO_CLK>,
+					 <&gcc GCC_EDP_REF_CLKREF_EN>;
+				clock-names = "aux",
+					      "cfg_ahb";
+
+				vdda-phy-supply = <&vreg_l5a>;
+				vdda-pll-supply = <&vreg_l4a>;
+				#clock-cells = <1>;
+				#phy-cells = <0>;
+
+				status = "disabled";
+			};
+
+			mdss_dp0: displayport-controller@af54000 {
+				compatible = "qcom,qcs8300-dp";
+
+				pinctrl-0 = <&dp_hot_plug_det>;
+				pinctrl-names = "default";
+
+
+				reg = <0x0 0xaf54000 0x0 0x104>,
+					<0x0 0xaf54200 0x0 0x0c0>,
+					<0x0 0xaf55000 0x0 0x770>,
+					<0x0 0xaf56000 0x0 0x09c>,
+					<0x0 0xaf57000 0x0 0x09c>,
+					<0x0 0xaf58000 0x0 0x09c>,
+					<0x0 0xaf59000 0x0 0x09c>,
+					<0x0 0xaf5a000 0x0 0x23c>,
+					<0x0 0xaf5b000 0x0 0x23c>;
+
+
+				interrupt-parent = <&mdss>;
+				interrupts = <12>;
+
+				clocks = <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_LINK_INTF_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK>;
+
+				clock-names = "core_iface",
+						"core_aux",
+						"ctrl_link",
+						"ctrl_link_iface",
+						"stream_pixel",
+						"stream_1_pixel",
+						"stream_2_pixel",
+						"stream_3_pixel";
+
+				assigned-clocks = <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK_SRC>,
+						  <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC>,
+						  <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC>,
+						  <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK_SRC>,
+						  <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK_SRC>;
+
+				assigned-clock-parents = <&mdss_edp_phy 0>,
+							 <&mdss_edp_phy 1>,
+							 <&mdss_edp_phy 1>,
+							 <&mdss_edp_phy 1>,
+							 <&mdss_edp_phy 1>;
+				phys = <&mdss_edp_phy>;
+				phy-names = "dp";
+
+				operating-points-v2 = <&dp_opp_table>;
+				power-domains = <&rpmhpd QCS8300_MMCX>;
+
+				#sound-dai-cells = <0>;
+
+				status = "disabled";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port@0 {
+						reg = <0>;
+						mdss_dp0_in: endpoint {
+							remote-endpoint = <&dpu_intf0_out>;
+						};
+					};
+
+					port@1 {
+						reg = <1>;
+						mdss_dp_out: endpoint { };
+					};
+				};
+
+				dp_opp_table: opp-table {
+					compatible = "operating-points-v2";
+
+					opp-160000000 {
+						opp-hz = /bits/ 64 <160000000>;
+						required-opps = <&rpmhpd_opp_low_svs>;
+					};
+
+					opp-270000000 {
+						opp-hz = /bits/ 64 <270000000>;
+						required-opps = <&rpmhpd_opp_svs>;
+					};
+
+					opp-540000000 {
+						opp-hz = /bits/ 64 <540000000>;
+						required-opps = <&rpmhpd_opp_svs_l1>;
+					};
+
+					opp-810000000 {
+						opp-hz = /bits/ 64 <810000000>;
+						required-opps = <&rpmhpd_opp_nom>;
+					};
+				};
+			};
+		};
+
+		dispcc0: clock-controller@af00000 {
+			compatible = "qcom,sa8775p-dispcc0";
+			reg = <0x0 0x0af00000 0x0 0x20000>;
+			clocks = <&gcc GCC_DISP_AHB_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK_A>,
+				 <&sleep_clk>,
+				 <&mdss_edp_phy 0>, <&mdss_edp_phy 1>,
+				 <0>, <0>,
+				 <&mdss_dsi0_phy 0>, <&mdss_dsi0_phy 1>,
+				 <0>, <0>;
+			power-domains = <&rpmhpd QCS8300_MMCX>;
+			required-opps = <&rpmhpd_opp_low_svs>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
+		pdc: interrupt-controller@b220000 {
+			compatible = "qcom,qcs8300-pdc", "qcom,pdc";
+			reg = <0x0 0xb220000 0x0 0x30000>,
+			      <0x0 0x17c000f0 0x0 0x64>;
+			qcom,pdc-ranges = <0 480 40>,
+					  <40 140 14>,
+					  <54 263 1>,
+					  <55 306 4>,
+					  <59 312 3>,
+					  <62 374 2>,
+					  <64 434 2>,
+					  <66 438 2>,
+					  <70 520 1>,
+					  <73 523 1>,
+					  <118 568 6>,
+					  <124 609 3>,
+					  <159 638 1>,
+					  <160 720 3>,
+					  <169 728 30>,
+					  <199 416 2>,
+					  <201 449 1>,
+					  <202 89 1>,
+					  <203 451 1>,
+					  <204 462 1>,
+					  <205 264 1>,
+					  <206 579 1>,
+					  <207 653 1>,
+					  <208 656 1>,
+					  <209 659 1>,
+					  <210 122 1>,
+					  <211 699 1>,
+					  <212 705 1>,
+					  <213 450 1>,
+					  <214 643 2>,
+					  <216 646 5>,
+					  <221 390 5>,
+					  <226 700 2>,
+					  <228 440 1>,
+					  <229 663 1>,
+					  <230 524 2>,
+					  <232 612 3>,
+					  <235 723 5>;
+			interrupt-parent = <&intc>;
+			#interrupt-cells = <2>;
+			interrupt-controller;
+		};
+
+		aoss_qmp: power-management@c300000 {
+			compatible = "qcom,qcs8300-aoss-qmp", "qcom,aoss-qmp";
+			reg = <0x0 0x0c300000 0x0 0x400>;
+			interrupts-extended = <&ipcc IPCC_CLIENT_AOP
+					       IPCC_MPROC_SIGNAL_GLINK_QMP
+					       IRQ_TYPE_EDGE_RISING>;
+			mboxes = <&ipcc IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_GLINK_QMP>;
+			#clock-cells = <0>;
+		};
+
+		spmi_bus: spmi@c440000 {
+			compatible = "qcom,spmi-pmic-arb";
+			reg = <0x0 0x0c440000 0x0 0x1100>,
+			      <0x0 0x0c600000 0x0 0x2000000>,
+			      <0x0 0x0e600000 0x0 0x100000>,
+			      <0x0 0x0e700000 0x0 0xa0000>,
+			      <0x0 0x0c40a000 0x0 0x26000>;
+			reg-names = "core",
+				    "chnls",
+				    "obsrvr",
+				    "intr",
+				    "cnfg";
+			qcom,channel = <0>;
+			qcom,ee = <0>;
+			interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "periph_irq";
+			interrupt-controller;
+			#interrupt-cells = <4>;
+			#address-cells = <2>;
+			#size-cells = <0>;
+		};
+
+		intc: interrupt-controller@17a00000 {
+			compatible = "arm,gic-v3";
+			reg = <0x0 0x17a00000 0x0 0x10000>,     /* GICD */
+			      <0x0 0x17a60000 0x0 0x100000>;    /* GICR * 8 */
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#interrupt-cells = <3>;
+			interrupt-controller;
+			#redistributor-regions = <1>;
+			redistributor-stride = <0x0 0x20000>;
+		};
+
+		sram: sram@146d8000 {
+			compatible = "qcom,qcs8300-imem", "syscon", "simple-mfd";
+			reg = <0x0 0x146d8000 0x0 0x1000>;
+
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			ranges = <0x0 0x0 0x146d8000 0x1000>;
+
+			pil-reloc@94c {
+				compatible = "qcom,pil-reloc-info";
+				reg = <0x94c 0xc8>;
+			};
+		};
+
+		apps_smmu: iommu@15000000 {
+			compatible = "qcom,qcs8300-smmu-500", "qcom,smmu-500", "arm,mmu-500";
+
+			reg = <0x0 0x15000000 0x0 0x100000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <2>;
+			dma-coherent;
+
+			interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI  98 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI  99 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 706 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 689 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 690 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 691 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 692 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 693 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 694 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 695 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 696 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 413 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 708 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 709 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 710 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 711 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 414 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 712 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 713 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 714 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 715 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 912 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 911 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 910 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 909 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 908 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 907 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 906 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 905 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 904 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 903 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 902 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 901 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 900 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 899 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 898 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 897 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 896 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 895 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pcie_smmu: iommu@15200000 {
+			compatible = "qcom,qcs8300-smmu-500", "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x15200000 0x0 0x80000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <2>;
+			dma-coherent;
+
+			interrupts = <GIC_SPI 920 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 921 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 925 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 926 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 927 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 928 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 950 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 951 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 952 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 953 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 954 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 955 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 956 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 957 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 958 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 885 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 886 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 887 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 888 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 820 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 823 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 452 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 840 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 841 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 842 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 843 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 844 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 845 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 846 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 847 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 848 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 849 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 802 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 803 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 804 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 805 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 806 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 807 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 808 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 809 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 810 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 811 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 812 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 813 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 814 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 837 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 838 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 839 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 854 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 855 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 856 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 790 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 791 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 792 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 793 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 794 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 795 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 796 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		tcsr: syscon@1fc0000 {
+		       compatible = "qcom,qcs8300-tcsr", "syscon";
+		       reg = <0x0 0x1fc0000 0x0 0x30000>;
+		};
+
+		watchdog@17c10000 {
+			compatible = "qcom,apss-wdt-qcs8300", "qcom,kpss-wdt";
+			reg = <0x0 0x17c10000 0x0 0x1000>;
+			clocks = <&sleep_clk>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_EDGE_RISING>;
+		};
+
+		memtimer: timer@17c20000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x17c20000 0x0 0x1000>;
+			ranges = <0x0 0x0 0x0 0x20000000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			frame@17c21000 {
+				reg = <0x17c21000 0x1000>,
+				      <0x17c22000 0x1000>;
+				frame-number = <0>;
+				interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+			};
+
+			frame@17c23000 {
+				reg = <0x17c23000 0x1000>;
+				frame-number = <1>;
+				interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame@17c25000 {
+				reg = <0x17c25000 0x1000>;
+				frame-number = <2>;
+				interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame@17c27000 {
+				reg = <0x17c27000 0x1000>;
+				frame-number = <3>;
+				interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame@17c29000 {
+				reg = <0x17c29000 0x1000>;
+				frame-number = <4>;
+				interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame@17c2b000 {
+				reg = <0x17c2b000 0x1000>;
+				frame-number = <5>;
+				interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			frame@17c2d000 {
+				reg = <0x17c2d000 0x1000>;
+				frame-number = <6>;
+				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+		};
+
+		apps_rsc: rsc@18200000 {
+			compatible = "qcom,rpmh-rsc";
+			reg = <0x0 0x18200000 0x0 0x10000>,
+			      <0x0 0x18210000 0x0 0x10000>,
+			      <0x0 0x18220000 0x0 0x10000>;
+			reg-names = "drv-0", "drv-1", "drv-2";
+			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+			qcom,tcs-offset = <0xd00>;
+			qcom,drv-id = <2>;
+			qcom,tcs-config = <ACTIVE_TCS 2>,
+					  <SLEEP_TCS 3>,
+					  <WAKE_TCS 3>,
+					  <CONTROL_TCS 0>;
+			label = "apps_rsc";
+			power-domains = <&SYSTEM_PD>;
+
+			apps_bcm_voter: bcm-voter {
+				compatible = "qcom,bcm-voter";
+			};
+
+			rpmhcc: clock-controller {
+				compatible = "qcom,sa8775p-rpmh-clk";
+				#clock-cells = <1>;
+				clocks = <&xo_board>;
+				clock-names = "xo";
+			};
+
+			rpmhpd: power-controller {
+				compatible = "qcom,qcs8300-rpmhpd";
+				#power-domain-cells = <1>;
+				operating-points-v2 = <&rpmhpd_opp_table>;
+
+				rpmhpd_opp_table: opp-table {
+					compatible = "operating-points-v2";
+
+					rpmhpd_opp_ret: opp-0 {
+						opp-level = <RPMH_REGULATOR_LEVEL_RETENTION>;
+					};
+
+					rpmhpd_opp_min_svs: opp-1 {
+						opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
+					};
+
+					rpmhpd_opp_low_svs: opp2 {
+						opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+					};
+
+					rpmhpd_opp_svs: opp3 {
+						opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+					};
+
+					rpmhpd_opp_svs_l1: opp-4 {
+						opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+					};
+
+					rpmhpd_opp_nom: opp-5 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+					};
+
+					rpmhpd_opp_nom_l1: opp-6 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+					};
+
+					rpmhpd_opp_nom_l2: opp-7 {
+						opp-level = <RPMH_REGULATOR_LEVEL_NOM_L2>;
+					};
+
+					rpmhpd_opp_turbo: opp-8 {
+						opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+					};
+
+					rpmhpd_opp_turbo_l1: opp-9 {
+						opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+					};
+				};
+			};
+		};
+
+		epss_l3_cl0: interconnect@18590000 {
+			compatible = "qcom,sa8775p-epss-l3-cl0",
+				     "qcom,epss-l3";
+			reg = <0x0 0x18590000 0x0 0x1000>;
+			clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>;
+			clock-names = "xo", "alternate";
+			#interconnect-cells = <1>;
+		};
+
+		cpufreq_hw: cpufreq@18591000 {
+			compatible = "qcom,qcs8300-cpufreq-epss", "qcom,cpufreq-epss";
+			reg = <0x0 0x18591000 0x0 0x1000>,
+			      <0x0 0x18594000 0x0 0x1000>,
+			      <0x0 0x18593000 0x0 0x1000>;
+			reg-names = "freq-domain0", "freq-domain1", "freq-domain2";
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "dcvsh-irq-0", "dcvsh-irq-1", "dcvsh-irq-2";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>;
+			clock-names = "xo", "alternate";
+
+			#freq-domain-cells = <1>;
+		};
+
+		epss_l3_cl1: interconnect@18592000 {
+			compatible = "qcom,sa8775p-epss-l3-cl1",
+				     "qcom,epss-l3";
+			reg = <0x0 0x18592000 0x0 0x1000>;
+			clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>;
+			clock-names = "xo", "alternate";
+			#interconnect-cells = <1>;
+		};
+
+		remoteproc_gpdsp: remoteproc@20c00000 {
+			compatible = "qcom,qcs8300-gpdsp-pas";
+			reg = <0x0 0x20c00000 0x0 0x10000>;
+
+			interrupts-extended = <&intc GIC_SPI 768 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_gpdsp_in 0 0>,
+					      <&smp2p_gpdsp_in 2 0>,
+					      <&smp2p_gpdsp_in 1 0>,
+					      <&smp2p_gpdsp_in 3 0>;
+			interrupt-names = "wdog", "fatal", "handover",
+					  "ready", "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_CX>,
+					<&rpmhpd RPMHPD_MXC>;
+			power-domain-names = "cx", "mxc";
+
+			interconnects = <&gpdsp_anoc MASTER_DSP0 0 &config_noc SLAVE_CLK_CTL 0>;
+
+			memory-region = <&gpdsp_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_gpdsp_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_GPDSP0
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_GPDSP0
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "gpdsp";
+				qcom,remote-pid = <17>;
+			};
+		};
+
+		remoteproc_cdsp: remoteproc@26300000 {
+			compatible = "qcom,qcs8300-cdsp-pas";
+			reg = <0x0 0x26300000 0x0 0x10000>;
+
+			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog", "fatal", "ready",
+					  "handover", "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_CX>,
+					<&rpmhpd RPMHPD_MXC>,
+					<&rpmhpd RPMHPD_NSP0>;
+
+			power-domain-names = "cx", "mxc", "nsp0";
+
+			interconnects = <&nspa_noc MASTER_CDSP_PROC 0 &mc_virt SLAVE_EBI1 0>;
+
+			memory-region = <&cdsp_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_cdsp_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_CDSP
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "cdsp";
+				qcom,remote-pid = <5>;
+
+				fastrpc {
+					compatible = "qcom,fastrpc";
+					qcom,glink-channels = "fastrpcglink-apps-dsp";
+					label = "cdsp";
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					compute-cb@1 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <1>;
+						iommus = <&apps_smmu 0x19c1 0x0440>,
+							 <&apps_smmu 0x1961 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@2 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <2>;
+						iommus = <&apps_smmu 0x19c2 0x0440>,
+							 <&apps_smmu 0x1962 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@3 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <3>;
+						iommus = <&apps_smmu 0x19c3 0x0440>,
+							 <&apps_smmu 0x1963 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@4 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <4>;
+						iommus = <&apps_smmu 0x19c4 0x0440>,
+							 <&apps_smmu 0x1964 0x0400>;
+						dma-coherent;
+					};
+				};
+			};
+		};
+
+		tlmm: pinctrl@f100000 {
+			compatible = "qcom,qcs8300-tlmm";
+			reg = <0x0 0x0f100000 0x0 0x300000>;
+			interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			gpio-ranges = <&tlmm 0 0 133>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			wakeup-parent = <&pdc>;
+
+			qup_i2c0_data_clk: qup-i2c0-data-clk-state {
+				pins = "gpio17", "gpio18";
+				function = "qup0_se0";
+			};
+
+			qup_i2c1_data_clk: qup-i2c1-data-clk-state {
+				pins = "gpio19", "gpio20";
+				function = "qup0_se1";
+			};
+
+			qup_i2c2_data_clk: qup-i2c2-data-clk-state {
+				pins = "gpio33", "gpio34";
+				function = "qup0_se2";
+			};
+
+			qup_i2c3_data_clk: qup-i2c3-data-clk-state {
+				pins = "gpio25", "gpio26";
+				function = "qup0_se3";
+			};
+
+			qup_i2c4_data_clk: qup-i2c4-data-clk-state {
+				pins = "gpio29", "gpio30";
+				function = "qup0_se4";
+			};
+
+			qup_i2c5_data_clk: qup-i2c5-data-clk-state {
+				pins = "gpio21", "gpio22";
+				function = "qup0_se5";
+			};
+
+			qup_i2c6_data_clk: qup-i2c6-data-clk-state {
+				pins = "gpio80", "gpio81";
+				function = "qup0_se6";
+			};
+
+			qup_i2c8_data_clk: qup-i2c8-data-clk-state {
+				pins = "gpio37", "gpio38";
+				function = "qup1_se0";
+			};
+
+			qup_i2c9_data_clk: qup-i2c9-data-clk-state {
+				pins = "gpio39", "gpio40";
+				function = "qup1_se1";
+			};
+
+			qup_i2c10_data_clk: qup-i2c10-data-clk-state {
+				pins = "gpio84", "gpio85";
+				function = "qup1_se2";
+			};
+
+			qup_i2c11_data_clk: qup-i2c11-data-clk-state {
+				pins = "gpio41", "gpio42";
+				function = "qup1_se3";
+			};
+
+			qup_i2c12_data_clk: qup-i2c12-data-clk-state {
+				pins = "gpio45", "gpio46";
+				function = "qup1_se4";
+			};
+
+			qup_i2c13_data_clk: qup-i2c13-data-clk-state {
+				pins = "gpio49", "gpio50";
+				function = "qup1_se5";
+			};
+
+			qup_i2c14_data_clk: qup-i2c14-data-clk-state {
+				pins = "gpio89", "gpio90";
+				function = "qup1_se6";
+			};
+
+			qup_i2c15_data_clk: qup-i2c15-data-clk-state {
+				pins = "gpio91", "gpio92";
+				function = "qup1_se7";
+			};
+
+			qup_i2c16_data_clk: qup-i2c16-data-clk-state {
+				pins = "gpio10", "gpio11";
+				function = "qup2_se0";
+			};
+
+			qup_spi0_data_clk: qup-spi0-data-clk-state {
+				pins = "gpio17", "gpio18", "gpio19";
+				function = "qup0_se0";
+			};
+
+			qup_spi0_cs: qup-spi0-cs-state {
+				pins = "gpio20";
+				function = "qup0_se0";
+			};
+
+			qup_spi0_cs_gpio: qup-spi0-cs-gpio-state {
+				pins = "gpio20";
+				function = "gpio";
+			};
+
+			qup_spi1_data_clk: qup-spi1-data-clk-state {
+				pins = "gpio19", "gpio20", "gpio17";
+				function = "qup0_se1";
+			};
+
+			qup_spi1_cs: qup-spi1-cs-state {
+				pins = "gpio18";
+				function = "qup0_se1";
+			};
+
+			qup_spi1_cs_gpio: qup-spi1-cs-gpio-state {
+				pins = "gpio18";
+				function = "gpio";
+			};
+
+			qup_spi2_data_clk: qup-spi2-data-clk-state {
+				pins = "gpio33", "gpio34", "gpio35";
+				function = "qup0_se2";
+			};
+
+			qup_spi2_cs: qup-spi2-cs-state {
+				pins = "gpio36";
+				function = "qup0_se2";
+			};
+
+			qup_spi2_cs_gpio: qup-spi2-cs-gpio-state {
+				pins = "gpio36";
+				function = "gpio";
+			};
+
+			qup_spi3_data_clk: qup-spi3-data-clk-state {
+				pins = "gpio25", "gpio26", "gpio27";
+				function = "qup0_se3";
+			};
+
+			qup_spi3_cs: qup-spi3-cs-state {
+				pins = "gpio28";
+				function = "qup0_se3";
+			};
+
+			qup_spi3_cs_gpio: qup-spi3-cs-gpio-state {
+				pins = "gpio28";
+				function = "gpio";
+			};
+
+			qup_spi4_data_clk: qup-spi4-data-clk-state {
+				pins = "gpio29", "gpio30", "gpio31";
+				function = "qup0_se4";
+			};
+
+			qup_spi4_cs: qup-spi4-cs-state {
+				pins = "gpio32";
+				function = "qup0_se4";
+			};
+
+			qup_spi4_cs_gpio: qup-spi4-cs-gpio-state {
+				pins = "gpio32";
+				function = "gpio";
+			};
+
+			qup_spi5_data_clk: qup-spi5-data-clk-state {
+				pins = "gpio21", "gpio22", "gpio23";
+				function = "qup0_se5";
+			};
+
+			qup_spi5_cs: qup-spi5-cs-state {
+				pins = "gpio24";
+				function = "qup0_se5";
+			};
+
+			qup_spi5_cs_gpio: qup-spi5-cs-gpio-state {
+				pins = "gpio24";
+				function = "gpio";
+			};
+
+			qup_spi6_data_clk: qup-spi6-data-clk-state {
+				pins = "gpio80", "gpio81", "gpio82";
+				function = "qup0_se6";
+			};
+
+			qup_spi6_cs: qup-spi6-cs-state {
+				pins = "gpio83";
+				function = "qup0_se6";
+			};
+
+			qup_spi6_cs_gpio: qup-spi6-cs-gpio-state {
+				pins = "gpio83";
+				function = "gpio";
+			};
+
+			qup_spi8_data_clk: qup-spi8-data-clk-state {
+				pins = "gpio37", "gpio38", "gpio39";
+				function = "qup1_se0";
+			};
+
+			qup_spi8_cs: qup-spi8-cs-state {
+				pins = "gpio40";
+				function = "qup1_se0";
+			};
+
+			qup_spi8_cs_gpio: qup-spi8-cs-gpio-state {
+				pins = "gpio40";
+				function = "gpio";
+			};
+
+			qup_spi9_data_clk: qup-spi9-data-clk-state {
+				pins = "gpio39", "gpio40", "gpio37";
+				function = "qup1_se1";
+			};
+
+			qup_spi9_cs: qup-spi9-cs-state {
+				pins = "gpio38";
+				function = "qup1_se1";
+			};
+
+			qup_spi9_cs_gpio: qup-spi9-cs-gpio-state {
+				pins = "gpio38";
+				function = "gpio";
+			};
+
+			qup_spi10_data_clk: qup-spi10-data-clk-state {
+				pins = "gpio84", "gpio85", "gpio86";
+				function = "qup1_se2";
+			};
+
+			qup_spi10_cs: qup-spi10-cs-state {
+				pins = "gpio87";
+				function = "qup1_se2";
+			};
+
+			qup_spi10_cs_gpio: qup-spi10-cs-gpio-state {
+				pins = "gpio87";
+				function = "gpio";
+			};
+
+			qup_spi12_data_clk: qup-spi12-data-clk-state {
+				pins = "gpio45", "gpio46", "gpio47";
+				function = "qup1_se4";
+			};
+
+			qup_spi12_cs: qup-spi12-cs-state {
+				pins = "gpio48";
+				function = "qup1_se4";
+			};
+
+			qup_spi12_cs_gpio: qup-spi12-cs-gpio-state {
+				pins = "gpio48";
+				function = "gpio";
+			};
+
+			qup_spi13_data_clk: qup-spi13-data-clk-state {
+				pins = "gpio49", "gpio50", "gpio51";
+				function = "qup1_se5";
+			};
+
+			qup_spi13_cs: qup-spi13-cs-state {
+				pins = "gpio52";
+				function = "qup1_se5";
+			};
+
+			qup_spi13_cs_gpio: qup-spi13-cs-gpio-state {
+				pins = "gpio52";
+				function = "gpio";
+			};
+
+			qup_spi14_data_clk: qup-spi14-data-clk-state {
+				pins = "gpio89", "gpio90", "gpio91";
+				function = "qup1_se6";
+			};
+
+			qup_spi14_cs: qup-spi14-cs-state {
+				pins = "gpio92";
+				function = "qup1_se6";
+			};
+
+			qup_spi14_cs_gpio: qup-spi14-cs-gpio-state {
+				pins = "gpio92";
+				function = "gpio";
+			};
+
+			qup_spi15_data_clk: qup-spi15-data-clk-state {
+				pins = "gpio91", "gpio92", "gpio89";
+				function = "qup1_se7";
+			};
+
+			qup_spi15_cs: qup-spi15-cs-state {
+				pins = "gpio90";
+				function = "qup1_se7";
+			};
+
+			qup_spi15_cs_gpio: qup-spi15-cs-gpio-state {
+				pins = "gpio90";
+				function = "gpio";
+			};
+
+			qup_spi16_data_clk: qup-spi16-data-clk-state {
+				pins = "gpio10", "gpio11", "gpio12";
+				function = "qup2_se0";
+			};
+
+			qup_spi16_cs: qup-spi16-cs-state {
+				pins = "gpio13";
+				function = "qup2_se0";
+			};
+
+			qup_spi16_cs_gpio: qup-spi16-cs-gpio-state {
+				pins = "gpio13";
+				function = "gpio";
+			};
+
+			qup_uart0_cts: qup-uart0-cts-state {
+				pins = "gpio17";
+				function = "qup0_se0";
+			};
+
+			qup_uart0_rts: qup-uart0-rts-state {
+				pins = "gpio18";
+				function = "qup0_se0";
+			};
+
+			qup_uart0_tx: qup-uart0-tx-state {
+				pins = "gpio19";
+				function = "qup0_se0";
+			};
+
+			qup_uart0_rx: qup-uart0-rx-state {
+				pins = "gpio20";
+				function = "qup0_se0";
+			};
+
+			qup_uart1_cts: qup-uart1-cts-state {
+				pins = "gpio19";
+				function = "qup0_se1";
+			};
+
+			qup_uart1_rts: qup-uart1-rts-state {
+				pins = "gpio20";
+				function = "qup0_se1";
+			};
+
+			qup_uart1_tx: qup-uart1-tx-state {
+				pins = "gpio17";
+				function = "qup0_se1";
+			};
+
+			qup_uart1_rx: qup-uart1-rx-state {
+				pins = "gpio18";
+				function = "qup0_se1";
+			};
+
+			qup_uart2_cts: qup-uart2-cts-state {
+				pins = "gpio33";
+				function = "qup0_se2";
+			};
+
+			qup_uart2_rts: qup-uart2-rts-state {
+				pins = "gpio34";
+				function = "qup0_se2";
+			};
+
+			qup_uart2_tx: qup-uart2-tx-state {
+				pins = "gpio35";
+				function = "qup0_se2";
+			};
+
+			qup_uart2_rx: qup-uart2-rx-state {
+				pins = "gpio36";
+				function = "qup0_se2";
+			};
+
+			qup_uart3_cts: qup-uart3-cts-state {
+				pins = "gpio25";
+				function = "qup0_se3";
+			};
+
+			qup_uart3_rts: qup-uart3-rts-state {
+				pins = "gpio26";
+				function = "qup0_se3";
+			};
+
+			qup_uart3_tx: qup-uart3-tx-state {
+				pins = "gpio27";
+				function = "qup0_se3";
+			};
+
+			qup_uart3_rx: qup-uart3-rx-state {
+				pins = "gpio28";
+				function = "qup0_se3";
+			};
+
+			qup_uart4_cts: qup-uart4-cts-state {
+				pins = "gpio29";
+				function = "qup0_se4";
+			};
+
+			qup_uart4_rts: qup-uart4-rts-state {
+				pins = "gpio30";
+				function = "qup0_se4";
+			};
+
+			qup_uart4_tx: qup-uart4-tx-state {
+				pins = "gpio31";
+				function = "qup0_se4";
+			};
+
+			qup_uart4_rx: qup-uart4-rx-state {
+				pins = "gpio32";
+				function = "qup0_se4";
+			};
+
+			qup_uart5_cts: qup-uart5-cts-state {
+				pins = "gpio21";
+				function = "qup0_se5";
+			};
+
+			qup_uart5_rts: qup-uart5-rts-state {
+				pins = "gpio22";
+				function = "qup0_se5";
+			};
+
+			qup_uart5_tx: qup-uart5-tx-state {
+				pins = "gpio23";
+				function = "qup0_se5";
+			};
+
+			qup_uart5_rx: qup-uart5-rx-state {
+				pins = "gpio23";
+				function = "qup0_se5";
+			};
+
+			qup_uart6_cts: qup-uart6-cts-state {
+				pins = "gpio80";
+				function = "qup0_se6";
+			};
+
+			qup_uart6_rts: qup-uart6-rts-state {
+				pins = "gpio81";
+				function = "qup0_se6";
+			};
+
+			qup_uart6_tx: qup-uart6-tx-state {
+				pins = "gpio82";
+				function = "qup0_se6";
+			};
+
+			qup_uart6_rx: qup-uart6-rx-state {
+				pins = "gpio83";
+				function = "qup0_se6";
+			};
+
+			qup_uart7_tx: qup-uart7-tx-state {
+				pins = "gpio43";
+				function = "qup0_se7";
+			};
+
+			qup_uart7_rx: qup-uart7-rx-state {
+				pins = "gpio44";
+				function = "qup0_se7";
+			};
+
+			qup_uart8_cts: qup-uart8-cts-state {
+				pins = "gpio37";
+				function = "qup1_se0";
+			};
+
+			qup_uart8_rts: qup-uart8-rts-state {
+				pins = "gpio38";
+				function = "qup1_se0";
+			};
+
+			qup_uart8_tx: qup-uart8-tx-state {
+				pins = "gpio39";
+				function = "qup1_se0";
+			};
+
+			qup_uart8_rx: qup-uart8-rx-state {
+				pins = "gpio40";
+				function = "qup1_se0";
+			};
+
+			qup_uart9_cts: qup-uart9-cts-state {
+				pins = "gpio39";
+				function = "qup1_se1";
+			};
+
+			qup_uart9_rts: qup-uart9-rts-state {
+				pins = "gpio40";
+				function = "qup1_se1";
+			};
+
+			qup_uart9_tx: qup-uart9-tx-state {
+				pins = "gpio37";
+				function = "qup1_se1";
+			};
+
+			qup_uart9_rx: qup-uart9-rx-state {
+				pins = "gpio38";
+				function = "qup1_se1";
+			};
+
+			qup_uart10_cts: qup-uart10-cts-state {
+				pins = "gpio84";
+				function = "qup1_se2";
+			};
+
+			qup_uart10_rts: qup-uart10-rts-state {
+				pins = "gpio84";
+				function = "qup1_se2";
+			};
+
+			qup_uart10_tx: qup-uart10-tx-state {
+				pins = "gpio85";
+				function = "qup1_se2";
+			};
+
+			qup_uart10_rx: qup-uart10-rx-state {
+				pins = "gpio87";
+				function = "qup1_se2";
+			};
+
+			qup_uart11_tx: qup-uart11-tx-state {
+				pins = "gpio41";
+				function = "qup1_se3";
+			};
+
+			qup_uart11_rx: qup-uart11-rx-state {
+				pins = "gpio42";
+				function = "qup1_se3";
+			};
+
+			qup_uart12_cts: qup-uart12-cts-state {
+				pins = "gpio45";
+				function = "qup1_se4";
+			};
+
+			qup_uart12_rts: qup-uart12-rts-state {
+				pins = "gpio46";
+				function = "qup1_se4";
+			};
+
+			qup_uart12_tx: qup-uart12-tx-state {
+				pins = "gpio47";
+				function = "qup1_se4";
+			};
+
+			qup_uart12_rx: qup-uart12-rx-state {
+				pins = "gpio48";
+				function = "qup1_se4";
+			};
+
+			qup_uart13_cts: qup-uart13-cts-state {
+				pins = "gpio49";
+				function = "qup1_se5";
+			};
+
+			qup_uart13_rts: qup-uart13-rts-state {
+				pins = "gpio50";
+				function = "qup1_se5";
+			};
+
+			qup_uart13_tx: qup-uart13-tx-state {
+				pins = "gpio51";
+				function = "qup1_se5";
+			};
+
+			qup_uart13_rx: qup-uart13-rx-state {
+				pins = "gpio52";
+				function = "qup1_se5";
+			};
+
+			qup_uart14_cts: qup-uart14-cts-state {
+				pins = "gpio89";
+				function = "qup1_se6";
+			};
+
+			qup_uart14_rts: qup-uart14-rts-state {
+				pins = "gpio90";
+				function = "qup1_se6";
+			};
+
+			qup_uart14_tx: qup-uart14-tx-state {
+				pins = "gpio91";
+				function = "qup1_se6";
+			};
+
+			qup_uart14_rx: qup-uart14-rx-state {
+				pins = "gpio92";
+				function = "qup1_se6";
+			};
+
+			qup_uart15_cts: qup-uart15-cts-state {
+				pins = "gpio91";
+				function = "qup1_se7";
+			};
+
+			qup_uart15_rts: qup-uart15-rts-state {
+				pins = "gpio92";
+				function = "qup1_se7";
+			};
+
+			qup_uart15_tx: qup-uart15-tx-state {
+				pins = "gpio89";
+				function = "qup1_se7";
+			};
+
+			qup_uart15_rx: qup-uart15-rx-state {
+				pins = "gpio90";
+				function = "qup1_se7";
+			};
+
+			qup_uart16_cts: qup-uart16-cts-state {
+				pins = "gpio10";
+				function = "qup2_se0";
+			};
+
+			qup_uart16_rts: qup-uart16-rts-state {
+				pins = "gpio11";
+				function = "qup2_se0";
+			};
+
+			qup_uart16_tx: qup-uart16-tx-state {
+				pins = "gpio12";
+				function = "qup2_se0";
+			};
+
+			qup_uart16_rx: qup-uart16-rx-state {
+				pins = "gpio13";
+				function = "qup2_se0";
+			};
+
+			sdc1_clk: sdc1-clk-state {
+				pins = "sdc1_clk";
+
+			};
+
+			sdc1_cmd: sdc1-cmd-state {
+				pins = "sdc1_cmd";
+			};
+
+			sdc1_data: sdc1-data-state {
+				pins = "sdc1_data";
+			};
+
+			sdc1_rclk: sdc1-rclk-state {
+				pins = "sdc1_rclk";
+			};
+
+			sdc1_clk_sleep: sdc1-clk-sleep-state {
+				pins = "sdc1_clk";
+				drive-strength = <2>;
+				bias-bus-hold;
+			};
+
+			sdc1_cmd_sleep: sdc1-cmd-sleep-state {
+				pins = "sdc1_cmd";
+				drive-strength = <2>;
+				bias-bus-hold;
+			};
+
+			sdc1_data_sleep: sdc1-data-sleep-state {
+				pins = "sdc1_data";
+				drive-strength = <2>;
+				bias-bus-hold;
+			};
+
+			sdc1_rclk_sleep: sdc1-rclk-sleep-state {
+				pins = "sdc1_rclk";
+				drive-strength = <2>;
+				bias-bus-hold;
+			};
+
+		};
+
+		stm@4002000 {
+			compatible = "arm,coresight-stm", "arm,primecell";
+			reg = <0x0 0x4002000 0x0 0x1000>,
+			      <0x0 0x16280000 0x0 0x180000>;
+			reg-names = "stm-base", "stm-stimulus-base";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					stm_out: endpoint {
+						remote-endpoint =
+						<&funnel0_in7>;
+					};
+				};
+			};
+		};
+
+		tpdm@4003000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4003000 0x0 0x1000>;
+			device-name = "tpdm_dcc";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					qdss_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&qdss_tpda_in0>;
+					};
+				};
+			};
+		};
+
+		tpda@4004000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4004000 0x0 0x1000>;
+			device-name = "tpda_qdss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					qdss_tpda_out: endpoint {
+						remote-endpoint =
+						<&funnel0_in6>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					qdss_tpda_in0: endpoint {
+						remote-endpoint =
+						<&qdss_tpdm0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					qdss_tpda_in1: endpoint {
+						remote-endpoint =
+						<&qdss_tpdm1_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@400f000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x400f000 0x0 0x1000>;
+			device-name = "tpdm_spdm";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					qdss_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&qdss_tpda_in1>;
+					};
+				};
+			};
+		};
+
+		cti@4010000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4010000 0x0 0x1000>;
+			device-name = "cti_qdss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4041000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4041000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					funnel0_out: endpoint {
+						remote-endpoint =
+						<&qdss_funnel_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@6 {
+					reg = <6>;
+					funnel0_in6: endpoint {
+						remote-endpoint =
+						<&qdss_tpda_out>;
+					};
+				};
+
+				port@7 {
+					reg = <7>;
+					funnel0_in7: endpoint {
+						remote-endpoint =
+						<&stm_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4042000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4042000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					funnel1_out: endpoint {
+						remote-endpoint =
+						<&qdss_funnel_in1>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@4 {
+					reg = <4>;
+					funnel1_in4: endpoint {
+						remote-endpoint =
+						<&apss_funnel1_out>;
+					};
+				};
+
+				port@5 {
+					reg = <5>;
+					funnel1_in5: endpoint {
+						remote-endpoint =
+						<&dlct0_funnel_out>;
+					};
+				};
+
+				port@6 {
+					reg = <6>;
+					funnel1_in6: endpoint {
+						remote-endpoint =
+						<&dlmm_funnel_out>;
+					};
+				};
+
+				port@7 {
+					reg = <7>;
+					funnel1_in7: endpoint {
+						remote-endpoint =
+						<&dlst_ch_funnel_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4045000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4045000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					qdss_funnel_out: endpoint {
+						remote-endpoint =
+						<&aoss_funnel_in7>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					qdss_funnel_in0: endpoint {
+						remote-endpoint =
+						<&funnel0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					qdss_funnel_in1: endpoint {
+						remote-endpoint =
+						<&funnel1_out>;
+					};
+				};
+			};
+		};
+
+		replicator@4046000 {
+			compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+			reg = <0x0 0x4046000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					qdss_rep_out0: endpoint {
+						remote-endpoint =
+						<&etr_rep_in>;
+					};
+				};
+			};
+
+			in-ports {
+				port {
+					qdss_rep_in: endpoint {
+						remote-endpoint =
+						<&swao_rep_out0>;
+					};
+				};
+			};
+		};
+
+		tmc_etr: tmc@4048000 {
+			compatible = "arm,coresight-tmc", "arm,primecell";
+			reg = <0x0 0x4048000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			iommus = <&apps_smmu 0x04c0 0x00>;
+
+			arm,scatter-gather;
+
+			in-ports {
+				port {
+					etr0_in: endpoint {
+						remote-endpoint =
+						<&etr_rep_out0>;
+					};
+				};
+			};
+		};
+
+		replicator@404e000 {
+			compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+			reg = <0x0 0x404e000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					etr_rep_out0: endpoint {
+						remote-endpoint =
+						<&etr0_in>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					etr_rep_out1: endpoint {
+						remote-endpoint =
+						<&etr1_in>;
+					};
+				};
+			};
+
+			in-ports {
+				port {
+					etr_rep_in: endpoint {
+						remote-endpoint =
+						<&qdss_rep_out0>;
+					};
+				};
+			};
+		};
+
+		tmc_etr1: tmc@404f000 {
+			compatible = "arm,coresight-tmc", "arm,primecell";
+			reg = <0x0 0x404f000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			iommus = <&apps_smmu 0x04a0 0x40>;
+
+			arm,scatter-gather;
+			arm,buffer-size = <0x400000>;
+
+			in-ports {
+				port {
+					etr1_in: endpoint {
+						remote-endpoint =
+						<&etr_rep_out1>;
+					};
+				};
+			};
+		};
+
+		tpdm@482c000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x482c000 0x0 0x1000>;
+			device-name = "tpdm_gcc";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					gcc_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in20>;
+					};
+				};
+			};
+		};
+
+		cti@4831000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4831000 0x0 0x1000>;
+			device-name = "cti_venus";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+			status = "disabled";
+		};
+
+		tpdm@4841000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4841000 0x0 0x1000>;
+			device-name = "tpdm_prng";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					prng_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in19>;
+					};
+				};
+			};
+		};
+
+		cti@4845000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4845000 0x0 0x1000>;
+			device-name = "cti_lpass";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpdm@4850000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4850000 0x0 0x1000>;
+			device-name = "tpdm_pimem";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					pimem_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in25>;
+					};
+				};
+			};
+		};
+
+		tpdm@4860000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4860000 0x0 0x1000>;
+			device-name = "tpdm_dl_ch_south";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					dlst_ch_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&dlst_ch_tpda_in8>;
+					};
+				};
+			};
+		};
+
+		tpdm@4861000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4861000 0x0 0x1000>;
+			device-name = "tpdm_dl_ch_south_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					dlst_ch_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&dlst_ch_tpda_in9>;
+					};
+				};
+			};
+		};
+
+		cti@4862000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4862000 0x0 0x1000>;
+			device-name = "cti_dl_ch_south";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		cti@4863000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4863000 0x0 0x1000>;
+			device-name = "cti_dl_ch_south_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@4864000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4864000 0x0 0x1000>;
+			device-name = "tpda_dlst_ch";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlst_ch_tpda_out: endpoint {
+						remote-endpoint =
+						<&dlst_ch_funnel_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@8 {
+					reg = <8>;
+					dlst_ch_tpda_in8: endpoint {
+						remote-endpoint =
+						<&dlst_ch_tpdm0_out>;
+					};
+				};
+
+				port@9 {
+					reg = <9>;
+					dlst_ch_tpda_in9: endpoint {
+						remote-endpoint =
+						<&dlst_ch_tpdm1_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4865000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4865000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlst_ch_funnel_out: endpoint {
+						remote-endpoint =
+						<&funnel1_in7>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					dlst_ch_funnel_in0: endpoint {
+						remote-endpoint =
+						<&dlst_ch_tpda_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					dlst_ch_funnel_in4: endpoint {
+						remote-endpoint =
+						<&dlst_funnel_out>;
+					};
+				};
+
+				port@6 {
+					reg = <6>;
+					dlst_ch_funnel_in6: endpoint {
+						remote-endpoint =
+						<&gdsp_funnel_out>;
+					};
+				};
+			};
+		};
+
+		cti@4901000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4901000 0x0 0x1000>;
+			device-name = "cti_gfx";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4940000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4940000 0x0 0x1000>,
+			      <0x0 0x4b87000 0x0 0x1000>;
+			reg-names = "funnel-base-dummy", "funnel-base-real";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,duplicate-funnel;
+			arm,primecell-periphid = <0x000bb908>;
+
+			out-ports {
+				port {
+					turing0_dup_funnel_out: endpoint {
+						remote-endpoint =
+						<&turing0_funnel_in4>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@3 {
+					reg = <3>;
+					turing0_dup_funnel_in3: endpoint {
+						remote-endpoint =
+						<&turing0_etm0_out>;
+					};
+				};
+			};
+		};
+
+		cti@4961000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4961000 0x0 0x1000>;
+			device-name = "cti_gfx_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		cti@4962000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4962000 0x0 0x1000>;
+			device-name = "cti_gfx_2";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		tpdm@4980000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4980000 0x0 0x1000>;
+			device-name = "tpdm_turing";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					turing2_tpdm_out: endpoint {
+						remote-endpoint =
+						<&turing2_funnel_in0>;
+					};
+				};
+			};
+		};
+
+		cti@4982000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4982000 0x0 0x1000>;
+			device-name = "cti_turing";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4983000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4983000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					turing2_funnel_out0: endpoint {
+						remote-endpoint =
+						<&gdsp_tpda_in5>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					turing2_funnel_in0: endpoint {
+						remote-endpoint =
+						<&turing2_tpdm_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@49ca000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x49ca000 0x0 0x1000>;
+			device-name = "tpdm_sdcc_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					sdcc_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlst_tpda_in1>;
+					};
+				};
+			};
+		};
+
+		tpdm@49c0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x49c0000 0x0 0x1000>;
+			device-name = "tpdm_rdpm_mxa";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					rdpm_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in23>;
+					};
+				};
+			};
+		};
+
+		tpdm@49d0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x49d0000 0x0 0x1000>;
+			device-name = "tpdm_qm";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					qm_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in21>;
+					};
+				};
+			};
+		};
+
+		tpdm@4ac0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4ac0000 0x0 0x1000>;
+			device-name = "tpdm_mmnoc_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					dlmm_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&dlmm_tpda_in27>;
+					};
+				};
+			};
+		};
+
+		tpdm@4ac1000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4ac1000 0x0 0x1000>;
+			device-name = "tpdm_mmnoc_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					dlmm_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&dlmm_tpda_in28>;
+					};
+				};
+			};
+		};
+
+		cti@4ac2000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4ac2000 0x0 0x1000>;
+			device-name = "cti_mmnoc_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		cti@4ac3000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4ac3000 0x0 0x1000>;
+			device-name = "cti_mmnoc_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@4ac4000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4ac4000 0x0 0x1000>;
+			device-name = "tpda_dlmm";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlmm_tpda_out: endpoint {
+						remote-endpoint =
+						<&dlmm_funnel_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@8 {
+					reg = <8>;
+					dlmm_tpda_in8: endpoint {
+						remote-endpoint =
+						<&mdss1_tpdm_out>;
+					};
+				};
+
+				port@1b {
+					reg = <27>;
+					dlmm_tpda_in27: endpoint {
+						remote-endpoint =
+						<&dlmm_tpdm0_out>;
+					};
+				};
+
+				port@1c {
+					reg = <28>;
+					dlmm_tpda_in28: endpoint {
+						remote-endpoint =
+						<&dlmm_tpdm1_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4ac5000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4ac5000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlmm_funnel_out: endpoint {
+						remote-endpoint =
+						<&funnel1_in6>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					dlmm_funnel_in0: endpoint {
+						remote-endpoint =
+						<&dlmm_tpda_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@4ad0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4ad0000 0x0 0x1000>;
+			device-name = "tpdm_dlct";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					dlct0_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in26>;
+					};
+				};
+			};
+		};
+
+		tpdm@4ad1000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4ad1000 0x0 0x1000>;
+			device-name = "tpdm_ipcc";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					dlct0_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in27>;
+					};
+				};
+			};
+		};
+
+		cti@4ad2000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4ad2000 0x0 0x1000>;
+			device-name = "cti_dlct";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@4ad3000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4ad3000 0x0 0x1000>;
+			device-name = "tpda_dlct0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlct0_tpda_out: endpoint {
+						remote-endpoint =
+						<&dlct0_funnel_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@13 {
+					reg = <19>;
+					dlct0_tpda_in19: endpoint {
+						remote-endpoint =
+						<&prng_tpdm_out>;
+					};
+				};
+
+				port@14 {
+					reg = <20>;
+					dlct0_tpda_in20: endpoint {
+						remote-endpoint =
+						<&gcc_tpdm_out>;
+					};
+				};
+
+				port@15 {
+					reg = <21>;
+					dlct0_tpda_in21: endpoint {
+						remote-endpoint =
+						<&qm_tpdm_out>;
+					};
+				};
+
+				port@17 {
+					reg = <23>;
+					dlct0_tpda_in23: endpoint {
+						remote-endpoint =
+						<&rdpm_tpdm_out>;
+					};
+				};
+
+				port@19 {
+					reg = <25>;
+					dlct0_tpda_in25: endpoint {
+						remote-endpoint =
+						<&pimem_tpdm_out>;
+					};
+				};
+
+				port@1a {
+					reg = <26>;
+					dlct0_tpda_in26: endpoint {
+						remote-endpoint =
+						<&dlct0_tpdm0_out>;
+					};
+				};
+
+				port@1b {
+					reg = <27>;
+					dlct0_tpda_in27: endpoint {
+						remote-endpoint =
+						<&dlct0_tpdm1_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4ad4000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4ad4000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlct0_funnel_out: endpoint {
+						remote-endpoint =
+						<&funnel1_in5>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					dlct0_funnel_in0: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					dlct0_funnel_in4: endpoint {
+						remote-endpoint =
+						<&ddr_funnel5_out>;
+					};
+				};
+			};
+		};
+
+		cti@4b00000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4b00000 0x0 0x1000>;
+			device-name = "cti_swao";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4b04000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4b04000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					aoss_funnel_out: endpoint {
+						remote-endpoint =
+						<&etf0_in>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@5 {
+					reg = <5>;
+					aoss_funnel_in5: endpoint {
+						remote-endpoint =
+						<&lpi_funnel_out>;
+					};
+				};
+
+				port@6 {
+					reg = <6>;
+					aoss_funnel_in6: endpoint {
+						remote-endpoint =
+						<&aoss_tpda_out>;
+					};
+				};
+
+				port@7 {
+					reg = <7>;
+					aoss_funnel_in7: endpoint {
+						remote-endpoint =
+						<&qdss_funnel_out>;
+					};
+				};
+			};
+		};
+
+		tmc_etf: tmc@4b05000 {
+			compatible = "arm,coresight-tmc", "arm,primecell";
+			reg = <0x0 0x4b05000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					etf0_out: endpoint {
+						remote-endpoint =
+						<&swao_rep_in>;
+					};
+				};
+			};
+
+			in-ports {
+				port {
+					etf0_in: endpoint {
+						remote-endpoint =
+						<&aoss_funnel_out>;
+					};
+				};
+			};
+		};
+
+		replicator@4b06000 {
+			compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+			reg = <0x0 0x4b06000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					swao_rep_out0: endpoint {
+						remote-endpoint =
+						<&qdss_rep_in>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					swao_rep_out1: endpoint {
+						remote-endpoint =
+						<&eud_in>;
+					};
+				};
+			};
+
+			in-ports {
+				port {
+					swao_rep_in: endpoint {
+						remote-endpoint =
+						<&etf0_out>;
+					};
+				};
+			};
+		};
+
+		tpda@4b08000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4b08000 0x0 0x1000>;
+			device-name = "tpda_aoss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					aoss_tpda_out: endpoint {
+						remote-endpoint =
+						<&aoss_funnel_in6>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					aoss_tpda_in0: endpoint {
+						remote-endpoint =
+						<&aoss_tpdm0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					aoss_tpda_in1: endpoint {
+						remote-endpoint =
+						<&aoss_tpdm1_out>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					aoss_tpda_in2: endpoint {
+						remote-endpoint =
+						<&aoss_tpdm2_out>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+					aoss_tpda_in3: endpoint {
+						remote-endpoint =
+						<&aoss_tpdm3_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					aoss_tpda_in4: endpoint {
+						remote-endpoint =
+						<&aoss_tpdm4_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@4b09000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b09000 0x0 0x1000>;
+			device-name = "tpdm_swao_prio_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					aoss_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&aoss_tpda_in0>;
+					};
+				};
+			};
+		};
+
+		tpdm@4b0a000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b0a000 0x0 0x1000>;
+			device-name = "tpdm_swao_prio_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					aoss_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&aoss_tpda_in1>;
+					};
+				};
+			};
+		};
+
+		tpdm@4b0b000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b0b000 0x0 0x1000>;
+			device-name = "tpdm_swao_prio_2";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					aoss_tpdm2_out: endpoint {
+						remote-endpoint =
+						<&aoss_tpda_in2>;
+					};
+				};
+			};
+		};
+
+		tpdm@4b0c000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b0c000 0x0 0x1000>;
+			device-name = "tpdm_swao_prio_3";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					aoss_tpdm3_out: endpoint {
+						remote-endpoint =
+						<&aoss_tpda_in3>;
+					};
+				};
+			};
+		};
+
+		tpdm@4b0d000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b0d000 0x0 0x1000>;
+			device-name = "tpdm_swao_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					aoss_tpdm4_out: endpoint {
+						remote-endpoint =
+						<&aoss_tpda_in4>;
+					};
+				};
+			};
+		};
+
+		cti@4b13000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4b13000 0x0 0x1000>;
+			device-name = "cti_aoss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@4b41000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4b41000 0x0 0x1000>;
+			device-name = "cti_lpass_core";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		tpdm@4b46000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b46000 0x0 0x1000>;
+			device-name = "tpdm_lpass_lpi";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					lpi_tpdm_out: endpoint {
+						remote-endpoint =
+						<&lpi_tpda_in>;
+					};
+				};
+			};
+		};
+
+		tpda@4b47000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4b47000 0x0 0x1000>;
+			device-name = "tpda_lpi";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+
+			out-ports {
+				port {
+					lpi_tpda_out: endpoint {
+						remote-endpoint =
+						<&lpi_funnel_in5>;
+					};
+				};
+			};
+
+			in-ports {
+				port {
+					lpi_tpda_in: endpoint {
+						remote-endpoint =
+						<&lpi_tpdm_out>;
+					};
+				};
+			};
+		};
+
+		cti@4b4b000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4b4b000 0x0 0x1000>;
+			device-name = "cti_lpass_lpi";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		tpdm@4b80000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b80000 0x0 0x1000>;
+			device-name = "tpdm_turing_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					turing0_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&turing0_tpda_in0>;
+					};
+				};
+			};
+		};
+
+		tpdm@4b81000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b81000 0x0 0x1000>;
+			device-name = "tpdm_turing_llm_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					turing0_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&turing0_tpda_in1>;
+					};
+				};
+			};
+		};
+
+		tpdm@4b82000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b82000 0x0 0x1000>;
+			device-name = "tpdm_turing_llm_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					turing0_tpdm2_out: endpoint {
+						remote-endpoint =
+						<&turing0_tpda_in2>;
+					};
+				};
+			};
+		};
+
+		tpdm@4b83000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b83000 0x0 0x1000>;
+			device-name = "tpdm_turing_llm_2";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					turing0_tpdm3_out: endpoint {
+						remote-endpoint =
+						<&turing0_tpda_in3>;
+					};
+				};
+			};
+		};
+
+		tpdm@4b84000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b84000 0x0 0x1000>;
+			device-name = "tpdm_turing_llm_3";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					turing0_tpdm4_out: endpoint {
+						remote-endpoint =
+						<&turing0_tpda_in4>;
+					};
+				};
+			};
+		};
+
+		cti@4b85000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4b85000 0x0 0x1000>;
+			device-name = "cti_turing_llm";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@4b86000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4b86000 0x0 0x1000>;
+			device-name = "tpda_turing0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					turing0_tpda_out: endpoint {
+						remote-endpoint =
+						<&turing0_funnel_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					turing0_tpda_in0: endpoint {
+						remote-endpoint =
+						<&turing0_tpdm0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					turing0_tpda_in1: endpoint {
+						remote-endpoint =
+						<&turing0_tpdm1_out>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					turing0_tpda_in2: endpoint {
+						remote-endpoint =
+						<&turing0_tpdm2_out>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+					turing0_tpda_in3: endpoint {
+						remote-endpoint =
+						<&turing0_tpdm3_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					turing0_tpda_in4: endpoint {
+						remote-endpoint =
+						<&turing0_tpdm4_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4b87000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4b87000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					turing0_funnel_out: endpoint {
+						remote-endpoint =
+						<&gdsp_funnel_in4>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					turing0_funnel_in0: endpoint {
+						remote-endpoint =
+						<&turing0_tpda_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					turing0_funnel_in4: endpoint {
+						remote-endpoint =
+						<&turing0_etm0_out>;
+					};
+				};
+			};
+		};
+
+		cti@4b8b000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4b8b000 0x0 0x1000>;
+			device-name = "cti_turing_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		tpdm@4c40000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4c40000 0x0 0x1000>;
+			device-name = "tpdm_gpdsp_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					gdsp_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&gdsp_tpda_in8>;
+					};
+				};
+			};
+		};
+
+		tpdm@4c41000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4c41000 0x0 0x1000>;
+			device-name = "tpdm_gpdsp_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					gdsp_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&gdsp_tpda_in9>;
+					};
+				};
+			};
+		};
+
+		cti@4c42000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4c42000 0x0 0x1000>;
+			device-name = "cti_gpdsp_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		cti@4c43000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4c43000 0x0 0x1000>;
+			device-name = "cti_gpdsp_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@4c44000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4c44000 0x0 0x1000>;
+			device-name = "tpda_gpdsp";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					gdsp_tpda_out: endpoint {
+						remote-endpoint =
+						<&gdsp_funnel_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@5 {
+					reg = <5>;
+					gdsp_tpda_in5: endpoint {
+						remote-endpoint =
+						<&turing2_funnel_out0>;
+					};
+				};
+
+				port@8 {
+					reg = <8>;
+					gdsp_tpda_in8: endpoint {
+						remote-endpoint =
+						<&gdsp_tpdm0_out>;
+					};
+				};
+
+				port@9 {
+					reg = <9>;
+					gdsp_tpda_in9: endpoint {
+						remote-endpoint =
+						<&gdsp_tpdm1_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4c45000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4c45000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					gdsp_funnel_out: endpoint {
+						remote-endpoint =
+						<&dlst_ch_funnel_in6>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					gdsp_funnel_in0: endpoint {
+						remote-endpoint =
+						<&gdsp_tpda_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					gdsp_funnel_in4: endpoint {
+						remote-endpoint =
+						<&turing0_funnel_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@4c50000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4c50000 0x0 0x1000>;
+			device-name = "tpdm_dl_south";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					dlst_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&dlst_tpda_in8>;
+					};
+				};
+			};
+		};
+
+		tpdm@4c51000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4c51000 0x0 0x1000>;
+			device-name = "tpdm_dl_south_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					dlst_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&dlst_tpda_in9>;
+					};
+				};
+			};
+		};
+
+		cti@4c52000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4c52000 0x0 0x1000>;
+			device-name = "cti_dl_south";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		cti@4c53000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4c53000 0x0 0x1000>;
+			device-name = "cti_dl_south_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@4c54000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4c54000 0x0 0x1000>;
+			device-name = "tpda_dlst";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlst_tpda_out: endpoint {
+						remote-endpoint =
+						<&dlst_funnel_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					reg = <1>;
+					dlst_tpda_in1: endpoint {
+						remote-endpoint =
+						<&sdcc_tpdm_out>;
+					};
+				};
+
+				port@8 {
+					reg = <8>;
+					dlst_tpda_in8: endpoint {
+						remote-endpoint =
+						<&dlst_tpdm0_out>;
+					};
+				};
+
+				port@9 {
+					reg = <9>;
+					dlst_tpda_in9: endpoint {
+						remote-endpoint =
+						<&dlst_tpdm1_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4c55000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4c55000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlst_funnel_out: endpoint {
+						remote-endpoint =
+						<&dlst_ch_funnel_in4>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					dlst_funnel_in0: endpoint {
+						remote-endpoint =
+						<&dlst_tpda_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@4c70000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4c70000 0x0 0x1000>;
+			device-name = "tpdm_mdss_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					mdss1_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlmm_tpda_in8>;
+					};
+				};
+			};
+		};
+
+		cti@4c71000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4c71000 0x0 0x1000>;
+			device-name = "cti_mdss_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+			status = "disabled";
+		};
+
+		tpdm@4e00000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4e00000 0x0 0x1000>;
+			device-name = "tpdm_ddr";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					ddr_tpdm3_out: endpoint {
+						remote-endpoint =
+						<&ddr_tpda_in4>;
+					};
+				};
+			};
+		};
+
+		tpdm@4e01000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4e01000 0x0 0x1000>;
+			device-name = "tpdm_shrm";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					ddr_tpdm4_out: endpoint {
+						remote-endpoint =
+						<&ddr_tpda_in5>;
+					};
+				};
+			};
+		};
+
+		cti@4e02000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4e02000 0x0 0x1000>;
+			device-name = "cti_ddr";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@4e03000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4e03000 0x0 0x1000>;
+			device-name = "tpda_ddr";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					ddr_tpda_out: endpoint {
+						remote-endpoint =
+						<&ddr_funnel5_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ddr_tpda_in0: endpoint {
+						remote-endpoint =
+						<&ddr_funnel0_out0>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ddr_tpda_in1: endpoint {
+						remote-endpoint =
+						<&ddr_funnel1_out0>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					ddr_tpda_in4: endpoint {
+						remote-endpoint =
+						<&ddr_tpdm3_out>;
+					};
+				};
+
+				port@5 {
+					reg = <5>;
+					ddr_tpda_in5: endpoint {
+						remote-endpoint =
+						<&ddr_tpdm4_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4e04000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4e04000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					ddr_funnel5_out: endpoint {
+						remote-endpoint =
+						<&dlct0_funnel_in4>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ddr_funnel5_in0: endpoint {
+						remote-endpoint =
+						<&ddr_tpda_out>;
+					};
+				};
+			};
+		};
+
+		cti@4e0c000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4e0c000 0x0 0x1000>;
+			device-name = "cti_ddr_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpdm@4e10000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4e10000 0x0 0x1000>;
+			device-name = "tpdm_ddr_ch0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					ddr_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&ddr_funnel0_in0>;
+					};
+				};
+			};
+		};
+
+		cti@4e11000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4e11000 0x0 0x1000>;
+			device-name = "cti_ddr_ch0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4e12000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4e12000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					ddr_funnel0_out0: endpoint {
+						remote-endpoint =
+						<&ddr_tpda_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ddr_funnel0_in0: endpoint {
+						remote-endpoint =
+						<&ddr_tpdm0_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@4e20000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4e20000 0x0 0x1000>;
+			device-name = "tpdm_ddr_ch1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					ddr_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&ddr_funnel1_in0>;
+					};
+				};
+			};
+		};
+
+		cti@4e21000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4e21000 0x0 0x1000>;
+			device-name = "cti_ddr_ch1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4e22000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4e22000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					ddr_funnel1_out0: endpoint {
+						remote-endpoint =
+						<&ddr_tpda_in1>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ddr_funnel1_in0: endpoint {
+						remote-endpoint =
+						<&ddr_tpdm1_out>;
+					};
+				};
+			};
+		};
+
+		cti@4e34000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4e34000 0x0 0x1000>;
+			device-name = "cti_ddr_2";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		etm@6040000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6040000 0x0 0x1000>;
+			cpu = <&CPU0>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm0_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in0>;
+					};
+				};
+			};
+		};
+
+		etm@6140000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6140000 0x0 0x1000>;
+			cpu = <&CPU1>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm1_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in1>;
+					};
+				};
+			};
+		};
+
+		etm@6240000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6240000 0x0 0x1000>;
+			cpu = <&CPU2>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm2_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in2>;
+					};
+				};
+			};
+		};
+
+		etm@6340000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6340000 0x0 0x1000>;
+			cpu = <&CPU3>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm3_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in3>;
+					};
+				};
+			};
+		};
+
+		etm@6440000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6440000 0x0 0x1000>;
+			cpu = <&CPU4>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm4_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in4>;
+					};
+				};
+			};
+		};
+
+		etm@6540000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6540000 0x0 0x1000>;
+			cpu = <&CPU5>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm5_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in5>;
+					};
+				};
+			};
+		};
+
+		etm@6640000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6640000 0x0 0x1000>;
+			cpu = <&CPU6>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm6_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in6>;
+					};
+				};
+			};
+		};
+
+		etm@6740000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6740000 0x0 0x1000>;
+			cpu = <&CPU7>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm7_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in7>;
+					};
+				};
+			};
+		};
+
+		funnel@6800000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x6800000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					apss_funnel0_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel1_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					apss_funnel0_in0: endpoint {
+						remote-endpoint =
+						<&etm0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					apss_funnel0_in1: endpoint {
+						remote-endpoint =
+						<&etm1_out>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					apss_funnel0_in2: endpoint {
+						remote-endpoint =
+						<&etm2_out>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+					apss_funnel0_in3: endpoint {
+						remote-endpoint =
+						<&etm3_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					apss_funnel0_in4: endpoint {
+						remote-endpoint =
+						<&etm4_out>;
+					};
+				};
+
+				port@5 {
+					reg = <5>;
+					apss_funnel0_in5: endpoint {
+						remote-endpoint =
+						<&etm5_out>;
+					};
+				};
+
+				port@6 {
+					reg = <6>;
+					apss_funnel0_in6: endpoint {
+						remote-endpoint =
+						<&etm6_out>;
+					};
+				};
+
+				port@7 {
+					reg = <7>;
+					apss_funnel0_in7: endpoint {
+						remote-endpoint =
+						<&etm7_out>;
+					};
+				};
+			};
+		};
+
+		funnel@6810000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x6810000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					apss_funnel1_out: endpoint {
+						remote-endpoint =
+						<&funnel1_in4>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					apss_funnel1_in0: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_out>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+					apss_funnel1_in3: endpoint {
+						remote-endpoint =
+						<&apss_tpda_out>;
+					};
+				};
+			};
+		};
+
+		cti@682b000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x682b000 0x0 0x1000>;
+			device-name = "cti_apss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		tpdm@6860000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x6860000 0x0 0x1000>;
+			device-name = "tpdm_actpm";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					apss_tpdm3_out: endpoint {
+						remote-endpoint =
+						<&apss_tpda_in3>;
+					};
+				};
+			};
+		};
+
+		tpdm@6861000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x6861000 0x0 0x1000>;
+			device-name = "tpdm_apss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					apss_tpdm4_out: endpoint {
+						remote-endpoint =
+						<&apss_tpda_in4>;
+					};
+				};
+			};
+		};
+
+		cti@6862000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x6862000 0x0 0x1000>;
+			device-name = "cti_apss_riscv";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@6863000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x6863000 0x0 0x1000>;
+			device-name = "tpda_apss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					apss_tpda_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel1_in3>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					apss_tpda_in0: endpoint {
+						remote-endpoint =
+						<&apss_tpdm0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					apss_tpda_in1: endpoint {
+						remote-endpoint =
+						<&apss_tpdm1_out>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					apss_tpda_in2: endpoint {
+						remote-endpoint =
+						<&apss_tpdm2_out>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+					apss_tpda_in3: endpoint {
+						remote-endpoint =
+						<&apss_tpdm3_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					apss_tpda_in4: endpoint {
+						remote-endpoint =
+						<&apss_tpdm4_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@68a0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x68a0000 0x0 0x1000>;
+			device-name = "tpdm_llm_gold";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					apss_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&apss_tpda_in1>;
+					};
+				};
+			};
+		};
+
+		tpdm@68b0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x68b0000 0x0 0x1000>;
+			device-name = "tpdm_llm_silver";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					apss_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&apss_tpda_in0>;
+					};
+				};
+			};
+		};
+
+		tpdm@68c0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x68c0000 0x0 0x1000>;
+			device-name = "tpdm_ext_dsb";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					apss_tpdm2_out: endpoint {
+						remote-endpoint =
+						<&apss_tpda_in2>;
+					};
+				};
+			};
+		};
+
+		cti@68e0000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x68e0000 0x0 0x1000>;
+			device-name = "cti_llm_gold";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@68f0000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x68f0000 0x0 0x1000>;
+			device-name = "cti_llm_silver";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6900000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x6900000 0x0 0x1000>;
+			device-name = "cti_ext_dsb";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		sdhc_1: mmc@87C4000 {
+			compatible = "qcom,sdhci-msm-v5";
+			status = "disabled";
+
+			reg = <0x0 0x87C4000 0x0 0x1000>,
+				<0x0 0x87C5000 0x0 0x1000>;
+			reg-names = "hc", "cqhci";
+
+			interrupts = <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>,
+					<GIC_SPI 521 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "hc_irq", "pwr_irq";
+
+			clocks = <&gcc GCC_SDCC1_AHB_CLK>,
+					<&gcc GCC_SDCC1_APPS_CLK>,
+					<&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "iface", "core", "xo";
+			interconnects = <&aggre1_noc MASTER_SDC 0 &mc_virt SLAVE_EBI1 0>,
+					<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_SDC1 0>;
+			interconnect-names = "sdhc-ddr","cpu-sdhc";
+
+			operating-points-v2 = <&sdhc1_opp_table>;
+			bus-width = <8>;
+			supports-cqe;
+			dma-coherent;
+
+			qcom,dll-config = <0x000F64EE>;
+			qcom,ddr-config = <0x80040868>;
+
+			mmc-ddr-1_8v;
+			mmc-hs200-1_8v;
+			mmc-hs400-1_8v;
+			mmc-hs400-enhanced-strobe;
+
+			iommus = <&apps_smmu 0x0 0x0>;
+
+			resets = <&gcc GCC_SDCC1_BCR>;
+			qcom,ice = <&ice_mmc>;
+
+			sdhc1_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-100000000 {
+					opp-hz = /bits/ 64 <100000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1800000 400000>;
+					opp-avg-kBps = <100000 0>;
+				};
+
+				opp-384000000 {
+					opp-hz = /bits/ 64 <384000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <5400000 1600000>;
+					opp-avg-kBps = <390000 0>;
+				};
+			};
+		};
+
+		sdhc_2: mmc@0x87c4000 {
+			compatible = "qcom,sdhci-msm-v5";
+			status = "disabled";
+
+			reg = <0x0 0x087C4000 0x0 0x1000>;
+
+			interrupts = <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 521 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "hc_irq", "pwr_irq";
+
+			clocks = <&gcc GCC_SDCC1_AHB_CLK>,
+				<&gcc GCC_SDCC1_APPS_CLK>;
+			clock-names = "iface", "core";
+
+			interconnects = <&aggre1_noc MASTER_SDC 0 &mc_virt SLAVE_EBI1 0>,
+					<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_SDC1 0>;
+			interconnect-names = "sdhc-ddr","cpu-sdhc";
+
+			power-domains = <&rpmhpd RPMHPD_CX>;
+			operating-points-v2 = <&sdhc2_opp_table>;
+
+			no-sdio;
+			no-mmc;
+
+			bus-width = <4>;
+			dma-coherent;
+
+			qcom,dll-config = <0x000F64EE>;
+			qcom,ddr-config = <0x80040868>;
+
+			resets = <&gcc GCC_SDCC1_BCR>;
+
+			sdhc2_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-100000000 {
+					opp-hz = /bits/ 64 <100000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1800000 400000>;
+					opp-avg-kBps = <100000 0>;
+				};
+
+				opp-384000000 {
+					opp-hz = /bits/ 64 <384000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <5400000 1600000>;
+					opp-avg-kBps = <390000 0>;
+				};
+			};
+		};
+
+		ice_mmc: crypto@87c8000 {
+			compatible = "qcom,inline-crypto-engine";
+			reg = <0x0 0x87c8000 0x0 0x18000>;
+			qcom,ice-use-hwkm;
+			clocks = <&gcc GCC_SDCC1_ICE_CORE_CLK>;
+		};
+	};
+
+	lpass-stm {
+		compatible = "arm,coresight-dummy-source";
+		device-name = "stm_lpass";
+
+		arm,trace-id = <25>;
+
+		out-ports {
+			port {
+				lpass_stm_out: endpoint {
+					remote-endpoint =
+					<&lpi_funnel_in1>;
+				};
+			};
+		};
+	};
+
+	lpi_funnel {
+		compatible = "arm,coresight-static-funnel";
+
+		out-ports {
+			port {
+				lpi_funnel_out: endpoint {
+					remote-endpoint =
+						<&aoss_funnel_in5>;
+				};
+			};
+		};
+
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				lpi_funnel_in0: endpoint {
+					remote-endpoint =
+					<&audio_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				lpi_funnel_in1: endpoint {
+					remote-endpoint =
+					<&lpass_stm_out>;
+				};
+			};
+
+			port@5 {
+				reg = <5>;
+				lpi_funnel_in5: endpoint {
+					remote-endpoint =
+					<&lpi_tpda_out>;
+				};
+			};
+		};
+	};
+
+	usb_qmpphy: phy@88e8000 {
+		compatible = "qcom,qcs8300-qmp-usb3-uni-phy";
+		reg = <0x0 0x8907000 0x0 0x2000>;
+
+		clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
+			 <&gcc GCC_USB_CLKREF_EN>,
+			 <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>,
+			 <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+		clock-names = "aux", "ref", "com_aux", "pipe";
+
+		resets = <&gcc GCC_USB3_PHY_PRIM_BCR>,
+			 <&gcc GCC_USB3PHY_PHY_PRIM_BCR>;
+		reset-names = "phy", "phy_phy";
+
+		power-domains = <&gcc GCC_USB30_PRIM_GDSC>;
+
+		#clock-cells = <0>;
+		clock-output-names = "usb3_prim_phy_pipe_clk_src";
+
+		#phy-cells = <0>;
+
+		status = "disabled";
+	};
+
+	usb_1_hsphy: phy@8904000 {
+		compatible = "qcom,qcs8300-usb-hs-phy",
+			     "qcom,usb-snps-hs-7nm-phy";
+		reg = <0x0 0x8904000 0x0 0x400>;
+
+		status = "disabled";
+
+		#phy-cells = <0>;
+
+		clocks = <&rpmhcc RPMH_CXO_CLK>;
+		clock-names = "ref";
+
+		resets = <&gcc GCC_USB2_PHY_PRIM_BCR>;
+	};
+
+	usb_2_hsphy: phy@8906000 {
+		compatible = "qcom,qcs8300-usb-hs-phy",
+			     "qcom,usb-snps-hs-7nm-phy";
+		reg = <0x0 0x08906000 0x0 0x400>;
+		status = "disabled";
+		#phy-cells = <0>;
+
+		clocks = <&rpmhcc RPMH_CXO_CLK>;
+		clock-names = "ref";
+
+		resets = <&gcc GCC_USB2_PHY_SEC_BCR>;
+	};
+
+	usb_1: usb@a6f8800 {
+		compatible = "qcom,qcs8300-dwc3", "qcom,dwc3";
+		reg = <0x0 0x0a6f8800 0x0 0x400>;
+		status = "disabled";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		dma-ranges;
+
+		clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>,
+			 <&gcc GCC_USB30_PRIM_MASTER_CLK>,
+			 <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>,
+			 <&gcc GCC_USB30_PRIM_SLEEP_CLK>,
+			 <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>;
+		clock-names = "cfg_noc",
+			      "core",
+			      "iface",
+			      "sleep",
+			      "mock_utmi";
+
+		assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
+				  <&gcc GCC_USB30_PRIM_MASTER_CLK>;
+		assigned-clock-rates = <19200000>, <200000000>;
+
+		interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+				      <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
+				      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
+				      <&pdc 12 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "pwr_event",
+				  "dp_hs_phy_irq",
+				  "dm_hs_phy_irq",
+				  "ss_phy_irq";
+
+		power-domains = <&gcc GCC_USB30_PRIM_GDSC>;
+		required-opps = <&rpmhpd_opp_nom>;
+
+		resets = <&gcc GCC_USB30_PRIM_BCR>;
+		interconnects = <&aggre1_noc MASTER_USB3_0 0 &mc_virt SLAVE_EBI1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_0 0>;
+		interconnect-names = "usb-ddr", "apps-usb";
+
+		wakeup-source;
+
+		usb_1_dwc3: usb@a600000 {
+			compatible = "snps,dwc3";
+			reg = <0x0 0x0a600000 0x0 0xe000>;
+			interrupts = <GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH>;
+			iommus = <&apps_smmu 0x80 0x0>;
+			snps,dis_u2_susphy_quirk;
+			snps,dis_enblslpm_quirk;
+			phys = <&usb_1_hsphy>, <&usb_qmpphy>;
+			phy-names = "usb2-phy", "usb3-phy";
+			maximum-speed = "super-speed-plus";
+			role-switch;
+		};
+	};
+
+	usb_2: usb@a4f8800 {
+		compatible = "qcom,qcs8300-dwc3", "qcom,dwc3";
+		reg = <0x0 0x0a4f8800 0x0 0x400>;
+		status = "disabled";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+		dma-ranges;
+
+		clocks = <&gcc GCC_CFG_NOC_USB2_PRIM_AXI_CLK>,
+			 <&gcc GCC_USB20_MASTER_CLK>,
+			 <&gcc GCC_AGGRE_USB2_PRIM_AXI_CLK>,
+			 <&gcc GCC_USB20_SLEEP_CLK>,
+			 <&gcc GCC_USB20_MOCK_UTMI_CLK>;
+		clock-names = "cfg_noc",
+			      "core",
+			      "iface",
+			      "sleep",
+			      "mock_utmi";
+
+		assigned-clocks = <&gcc GCC_USB20_MOCK_UTMI_CLK>,
+				  <&gcc GCC_USB20_MASTER_CLK>;
+		assigned-clock-rates = <19200000>, <120000000>;
+
+		interrupts-extended = <&intc GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>,
+				      <&pdc 10 IRQ_TYPE_EDGE_BOTH>,
+				      <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
+		interrupt-names = "pwr_event",
+				  "dp_hs_phy_irq",
+				  "dm_hs_phy_irq";
+
+		power-domains = <&gcc GCC_USB20_PRIM_GDSC>;
+		required-opps = <&rpmhpd_opp_nom>;
+
+		resets = <&gcc GCC_USB20_PRIM_BCR>;
+
+		interconnects = <&aggre1_noc MASTER_USB2 0 &mc_virt SLAVE_EBI1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB2 0>;
+		interconnect-names = "usb-ddr", "apps-usb";
+
+		usb_2_dwc3: usb@a400000 {
+			compatible = "snps,dwc3";
+			reg = <0x0 0x0a400000 0x0 0xe000>;
+			interrupts = <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>;
+			iommus = <&apps_smmu 0x20 0x0>;
+			snps,dis_u2_susphy_quirk;
+			snps,dis_enblslpm_quirk;
+			phys = <&usb_2_hsphy>;
+			phy-names = "usb2-phy";
+			maximum-speed = "high-speed";
+		};
+	};
+
+	arch_timer: timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	turing0-etm0 {
+		compatible = "qcom,coresight-remote-etm";
+		device-name = "turing_etm0";
+
+		qcom,atid-num = <2>;
+		qcom,inst-id = <13>;
+		atid = <38 39>;
+
+		out-ports {
+			port {
+				turing0_etm0_out: endpoint {
+					remote-endpoint =
+					<&turing0_dup_funnel_in3>;
+				};
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8550-addons-aim300-aiot.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8550-addons-aim300-aiot.dts
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs8550-aim300-aiot.dts"
+#include "qcs8550-addons.dtsi"
+
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS8550-addons AIM300 AIOT";
+	compatible = "qcom,qcs8550-addons-aim300-aiot", "qcom,qcs8550-aim300", "qcom,qcs8550",
+		     "qcom,qcm8550", "qcom,sm8550";
+
+	qps615_vreg: qps615-vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "qps615_vreg";
+		gpio = <&tlmm 178 GPIO_ACTIVE_HIGH>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		enable-active-high;
+		regulator-enable-ramp-delay = <10000>;
+	};
+};
+
+&i2c_hub_2 {
+	qps615_switch: pcie-switch@77 {
+		compatible = "qcom,switch-i2c";
+		reg = <0x77>;
+		vdda-supply = <&qps615_vreg>;
+		status = "okay";
+	};
+};
+
+&pcie1 {
+	dummy-supply = <&qps615_switch>;
+};
+
+&pcie1_phy {
+	qcom,refclk-always-on;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8550-addons.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8550-addons.dtsi
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/{
+	reserved-memory {
+		qseecom_mem: qcom,qseecom {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x1400000>; /* 20M */
+		};
+
+		qseecom_ta_mem: qcom,qseecom-ta {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x1000000>; /* 16M */
+		};
+	};
+
+	/* Add overlay for firmware node containing qcom_scm in sm8550.dtsi */
+	firmware {
+		qcom_mem_object {
+			compatible = "qcom,mem-object";
+		};
+
+		qcom_smcinvoke {
+			compatible = "qcom,smcinvoke";
+		};
+	};
+};
+
+&soc {
+	wdog_gh: qcom,wdt_gh {
+		compatible = "qcom,gh-watchdog";
+		interrupts = <0 0 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	qcom_tzlog: tz-log@146aa720 {
+		compatible = "qcom,tz-log";
+		reg = <0x0 0x146aa720 0x0 0x3000>;
+		qcom,hyplog-enabled;
+		hyplog-address-offset = <0x410>;
+		hyplog-size-offset = <0x414>;
+	};
+
+	qcom,mem-buf {
+		compatible = "qcom,mem-buf";
+		qcom,mem-buf-capabilities = "supplier";
+		qcom,vmid = <3>;
+	};
+
+	qcom,mem-buf-msgq {
+		compatible = "qcom,mem-buf-msgq";
+	};
+
+	qcom,secure-buffer {
+		compatible = "qcom,secure-buffer";
+		qcom,vmid-cp-camera-preview-ro;
+	};
+};
+
+#include "qcs8550-dma-heaps.dtsi"
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8550-aim300-aiot.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8550-aim300-aiot.dts
@@ -0,0 +1,629 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include "qcs8550-aim300.dtsi"
+#include "pm8010.dtsi"
+#include "pmr735d_a.dtsi"
+#include "pmr735d_b.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS8550 AIM300 AIOT";
+	compatible = "qcom,qcs8550-aim300-aiot", "qcom,qcs8550-aim300", "qcom,qcs8550",
+		     "qcom,qcm8550", "qcom,sm8550";
+	qcom,msm-id = <603 0x20000>;
+	qcom,board-id = <0x1011f 3>;
+
+	aliases {
+		serial0 = &uart7;
+	};
+
+	wcd938x: audio-codec {
+		compatible = "qcom,wcd9385-codec";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&wcd_default>;
+
+		qcom,micbias1-microvolt = <1800000>;
+		qcom,micbias2-microvolt = <1800000>;
+		qcom,micbias3-microvolt = <1800000>;
+		qcom,micbias4-microvolt = <1800000>;
+		qcom,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 500000
+							  500000 500000 500000>;
+		qcom,mbhc-headset-vthreshold-microvolt = <1700000>;
+		qcom,mbhc-headphone-vthreshold-microvolt = <50000>;
+		qcom,rx-device = <&wcd_rx>;
+		qcom,tx-device = <&wcd_tx>;
+
+		reset-gpios = <&tlmm 108 GPIO_ACTIVE_LOW>;
+
+		#sound-dai-cells = <1>;
+
+		vdd-buck-supply = <&vreg_l15b_1p8>;
+		vdd-rxtx-supply = <&vreg_l15b_1p8>;
+		vdd-io-supply = <&vreg_l15b_1p8>;
+		vdd-mic-bias-supply = <&vreg_bob1>;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		pinctrl-0 = <&volume_up_n>;
+		pinctrl-names = "default";
+
+		key-volume-up {
+			label = "Volume Up";
+			debounce-interval = <15>;
+			gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_VOLUMEUP>;
+			linux,can-disable;
+			wakeup-source;
+		};
+	};
+
+	pmic-glink {
+		compatible = "qcom,sm8550-pmic-glink", "qcom,pmic-glink";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		orientation-gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>;
+
+		connector@0 {
+			compatible = "usb-c-connector";
+			reg = <0>;
+			power-role = "dual";
+			data-role = "dual";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					pmic_glink_hs_in: endpoint {
+						remote-endpoint = <&usb_1_dwc3_hs>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					pmic_glink_ss_in: endpoint {
+						remote-endpoint = <&redriver_ss_out>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+
+					pmic_glink_sbu: endpoint {
+						remote-endpoint = <&fsa4480_sbu_mux>;
+					};
+				};
+			};
+		};
+	};
+
+	sound {
+		compatible = "qcom,sm8550-sndcard", "qcom,sm8450-sndcard";
+		model = "AIM300-AIOT";
+		audio-routing = "SpkrLeft IN", "WSA_SPK1 OUT",
+				"SpkrRight IN", "WSA_SPK2 OUT",
+				"IN1_HPHL", "HPHL_OUT",
+				"IN2_HPHR", "HPHR_OUT",
+				"AMIC2", "MIC BIAS2",
+				"VA DMIC0", "MIC BIAS1",
+				"VA DMIC1", "MIC BIAS1",
+				"VA DMIC2", "MIC BIAS3",
+				"TX DMIC0", "MIC BIAS1",
+				"TX DMIC1", "MIC BIAS2",
+				"TX DMIC2", "MIC BIAS3",
+				"TX SWR_ADC1", "ADC2_OUTPUT";
+
+		wcd-capture-dai-link {
+			link-name = "WCD Capture";
+
+			cpu {
+				sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>;
+			};
+
+			codec {
+				sound-dai = <&wcd938x 1>, <&swr2 0>, <&lpass_txmacro 0>;
+			};
+
+			platform {
+				sound-dai = <&q6apm>;
+			};
+		};
+
+		wcd-playback-dai-link {
+			link-name = "WCD Playback";
+
+			cpu {
+				sound-dai = <&q6apmbedai RX_CODEC_DMA_RX_0>;
+			};
+
+			codec {
+				sound-dai = <&wcd938x 0>, <&swr1 0>, <&lpass_rxmacro 0>;
+			};
+
+			platform {
+				sound-dai = <&q6apm>;
+			};
+		};
+
+		wsa-dai-link {
+			link-name = "WSA Playback";
+
+			cpu {
+				sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>;
+			};
+
+			codec {
+				sound-dai = <&north_spkr>, <&south_spkr>,
+					    <&swr0 0>, <&lpass_wsamacro 0>;
+			};
+
+			platform {
+				sound-dai = <&q6apm>;
+			};
+		};
+
+		va-dai-link {
+			link-name = "VA Capture";
+
+			cpu {
+				sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>;
+			};
+
+			codec {
+				sound-dai = <&lpass_vamacro 0>;
+			};
+
+			platform {
+				sound-dai = <&q6apm>;
+			};
+		};
+	};
+};
+
+&i2c_master_hub_0 {
+	status = "okay";
+};
+
+&i2c_hub_2 {
+	status = "okay";
+
+	typec-mux@42 {
+		compatible = "fcs,fsa4480";
+		reg = <0x42>;
+
+		vcc-supply = <&vreg_bob1>;
+
+		mode-switch;
+		orientation-switch;
+
+		port {
+			fsa4480_sbu_mux: endpoint {
+				remote-endpoint = <&pmic_glink_sbu>;
+			};
+		};
+	};
+
+	typec-retimer@1c {
+		compatible = "onnn,nb7vpq904m";
+		reg = <0x1c>;
+
+		vcc-supply = <&vreg_l15b_1p8>;
+
+		orientation-switch;
+		retimer-switch;
+
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+
+				redriver_ss_out: endpoint {
+					remote-endpoint = <&pmic_glink_ss_in>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+
+				redriver_ss_in: endpoint {
+					data-lanes = <3 2 1 0>;
+					remote-endpoint = <&usb_dp_qmpphy_out>;
+				};
+			};
+		};
+	};
+};
+
+&gcc {
+	clocks = <&bi_tcxo_div2>, <&sleep_clk>,
+		 <&pcie0_phy>,
+		 <&pcie1_phy>,
+		 <0>,
+		 <&ufs_mem_phy 0>,
+		 <&ufs_mem_phy 1>,
+		 <&ufs_mem_phy 2>,
+		 <&usb_dp_qmpphy QMP_USB43DP_USB3_PIPE_CLK>;
+};
+
+&lpass_tlmm {
+	spkr_1_sd_n_active: spkr-1-sd-n-active-state {
+		pins = "gpio17";
+		function = "gpio";
+		drive-strength = <16>;
+		bias-disable;
+		output-low;
+	};
+
+	spkr_2_sd_n_active: spkr-2-sd-n-active-state {
+		pins = "gpio18";
+		function = "gpio";
+		drive-strength = <16>;
+		bias-disable;
+		output-low;
+	};
+};
+
+&mdss {
+	status = "okay";
+};
+
+&mdss_dp0 {
+	status = "okay";
+};
+
+&mdss_dp0_out {
+	data-lanes = <0 1>;
+	remote-endpoint = <&usb_dp_qmpphy_dp_in>;
+};
+
+&mdss_dsi0 {
+	vdda-supply = <&vreg_l3e_1p2>;
+	status = "okay";
+
+	panel@0 {
+		compatible = "visionox,vtdr6130";
+		reg = <0>;
+
+		pinctrl-0 = <&dsi_active>, <&te_active>;
+		pinctrl-1 = <&dsi_suspend>, <&te_suspend>;
+		pinctrl-names = "default", "sleep";
+
+		reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>;
+
+		vci-supply = <&vreg_l13b_3p0>;
+		vdd-supply = <&vreg_l11b_1p2>;
+		vddio-supply = <&vreg_l12b_1p8>;
+
+		port {
+			panel0_in: endpoint {
+				remote-endpoint = <&mdss_dsi0_out>;
+			};
+		};
+	};
+};
+
+&mdss_dsi0_out {
+	remote-endpoint = <&panel0_in>;
+	data-lanes = <0 1 2 3>;
+};
+
+&mdss_dsi0_phy {
+	vdds-supply = <&vreg_l1e_0p88>;
+	status = "okay";
+};
+
+&pcie_1_phy_aux_clk {
+	clock-frequency = <1000>;
+};
+
+&pcie1 {
+	perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-0 = <&pcie1_default_state>;
+	pinctrl-names = "default";
+
+	iommu-map = <0x0 &apps_smmu 0x1480 0x1>,
+		<0x100 &apps_smmu 0x1481 0x1>,
+		<0x208 &apps_smmu 0x1482 0x1>,
+		<0x210 &apps_smmu 0x1483 0x1>,
+		<0x218 &apps_smmu 0x1484 0x1>,
+		<0x300 &apps_smmu 0x1487 0x1>,
+		<0x400 &apps_smmu 0x1488 0x1>,
+		<0x500 &apps_smmu 0x148c 0x1>,
+		<0x501 &apps_smmu 0x148e 0x1>;
+
+	status = "okay";
+};
+
+&pcie1_phy {
+	vdda-phy-supply = <&vreg_l3c_0p9>;
+	vdda-pll-supply = <&vreg_l3e_1p2>;
+	vdda-qref-supply = <&vreg_l1e_0p88>;
+
+	status = "okay";
+};
+
+&pcie0 {
+	wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
+	perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_default_state>;
+
+	status = "okay";
+};
+
+&pcie0_phy {
+	vdda-phy-supply = <&vreg_l1e_0p88>;
+	vdda-pll-supply = <&vreg_l3e_1p2>;
+
+	status = "okay";
+};
+
+&pm8550_flash {
+	status = "okay";
+
+	led-0 {
+		function = LED_FUNCTION_FLASH;
+		color = <LED_COLOR_ID_YELLOW>;
+		flash-max-microamp = <2000000>;
+		flash-max-timeout-us = <1280000>;
+		function-enumerator = <0>;
+		led-sources = <1>, <4>;
+		led-max-microamp = <500000>;
+	};
+
+	led-1 {
+		function = LED_FUNCTION_FLASH;
+		color = <LED_COLOR_ID_WHITE>;
+		flash-max-microamp = <2000000>;
+		flash-max-timeout-us = <1280000>;
+		function-enumerator = <1>;
+		led-sources = <2>, <3>;
+		led-max-microamp = <500000>;
+	};
+};
+
+&pm8550_gpios {
+	volume_up_n: volume-up-n-state {
+		pins = "gpio6";
+		function = "normal";
+		power-source = <1>;
+		bias-pull-up;
+		input-enable;
+	};
+};
+
+&pm8550_pwm {
+	status = "okay";
+
+	multi-led {
+		color = <LED_COLOR_ID_RGB>;
+		function = LED_FUNCTION_STATUS;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		led@1 {
+			reg = <1>;
+			color = <LED_COLOR_ID_RED>;
+		};
+
+		led@2 {
+			reg = <2>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		led@3 {
+			reg = <3>;
+			color = <LED_COLOR_ID_BLUE>;
+		};
+	};
+};
+
+&pm8550b_eusb2_repeater {
+	vdd18-supply = <&vreg_l15b_1p8>;
+	vdd3-supply = <&vreg_l5b_3p1>;
+};
+
+
+&pon_pwrkey {
+	status = "okay";
+};
+
+&pon_resin {
+	linux,code = <KEY_VOLUMEDOWN>;
+
+	status = "okay";
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&remoteproc_adsp {
+	firmware-name = "qcom/qcs8550/adsp.mbn",
+			"qcom/qcs8550/adsp_dtbs.elf";
+	status = "okay";
+};
+
+&remoteproc_cdsp {
+	firmware-name = "qcom/qcs8550/cdsp.mbn",
+			"qcom/qcs8550/cdsp_dtbs.elf";
+	status = "okay";
+};
+
+&remoteproc_mpss {
+	firmware-name = "qcom/qcs8550/qdsp6sw.mbn",
+			"qcom/qcs8550/qdsp6sw_dtbs.elf";
+	status = "okay";
+};
+
+&sleep_clk {
+	clock-frequency = <32000>;
+};
+
+&swr0 {
+	status = "okay";
+
+	/* WSA8845, Speaker North */
+	north_spkr: speaker@0,0 {
+		compatible = "sdw20217020400";
+		reg = <0 0>;
+		pinctrl-0 = <&spkr_1_sd_n_active>;
+		pinctrl-names = "default";
+		powerdown-gpios = <&lpass_tlmm 17 GPIO_ACTIVE_LOW>;
+		#sound-dai-cells = <0>;
+		sound-name-prefix = "SpkrLeft";
+		vdd-1p8-supply = <&vreg_l15b_1p8>;
+		vdd-io-supply = <&vreg_l3g_1p2>;
+	};
+
+	/* WSA8845, Speaker South */
+	south_spkr: speaker@0,1 {
+		compatible = "sdw20217020400";
+		reg = <0 1>;
+		pinctrl-0 = <&spkr_2_sd_n_active>;
+		pinctrl-names = "default";
+		powerdown-gpios = <&lpass_tlmm 18 GPIO_ACTIVE_LOW>;
+		#sound-dai-cells = <0>;
+		sound-name-prefix = "SpkrRight";
+		vdd-1p8-supply = <&vreg_l15b_1p8>;
+		vdd-io-supply = <&vreg_l3g_1p2>;
+	};
+};
+
+&swr1 {
+	status = "okay";
+
+	/* WCD9385 RX */
+	wcd_rx: codec@0,4 {
+		compatible = "sdw20217010d00";
+		reg = <0 4>;
+		qcom,rx-port-mapping = <1 2 3 4 5>;
+	};
+};
+
+&swr2 {
+	status = "okay";
+
+	/* WCD9385 TX */
+	wcd_tx: codec@0,3 {
+		compatible = "sdw20217010d00";
+		reg = <0 3>;
+		qcom,tx-port-mapping = <1 1 2 3>;
+	};
+};
+
+&tlmm {
+	gpio-reserved-ranges = <32 8>;
+
+	dsi_active: dsi-active-state {
+		pins = "gpio133";
+		function = "gpio";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	dsi_suspend: dsi-suspend-state {
+		pins = "gpio133";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+	};
+
+	te_active: te-active-state {
+		pins = "gpio86";
+		function = "mdp_vsync";
+		drive-strength = <2>;
+		bias-pull-down;
+	};
+
+	te_suspend: te-suspend-state {
+		pins = "gpio86";
+		function = "mdp_vsync";
+		drive-strength = <2>;
+		bias-pull-down;
+	};
+
+	wcd_default: wcd-reset-n-active-state {
+		pins = "gpio108";
+		function = "gpio";
+		drive-strength = <16>;
+		bias-disable;
+		output-low;
+	};
+};
+
+&uart7 {
+	status = "okay";
+};
+
+&usb_1 {
+	status = "okay";
+};
+
+&usb_1_dwc3 {
+	dr_mode = "otg";
+	usb-role-switch;
+};
+
+&usb_1_dwc3_hs {
+	remote-endpoint = <&pmic_glink_hs_in>;
+};
+
+&usb_1_dwc3_ss {
+	remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>;
+};
+
+&usb_1_hsphy {
+	phys = <&pm8550b_eusb2_repeater>;
+
+	vdd-supply = <&vreg_l1e_0p88>;
+	vdda12-supply = <&vreg_l3e_1p2>;
+
+	status = "okay";
+};
+
+&usb_dp_qmpphy {
+	vdda-phy-supply = <&vreg_l3e_1p2>;
+	vdda-pll-supply = <&vreg_l3f_0p88>;
+
+	orientation-switch;
+
+	status = "okay";
+};
+
+&usb_dp_qmpphy_dp_in {
+	remote-endpoint = <&mdss_dp0_out>;
+};
+
+&usb_dp_qmpphy_out {
+	remote-endpoint = <&redriver_ss_in>;
+};
+
+&usb_dp_qmpphy_usb_ss_in {
+	remote-endpoint = <&usb_1_dwc3_ss>;
+};
+
+&xo_board {
+	clock-frequency = <76800000>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8550-aim300.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8550-aim300.dtsi
@@ -0,0 +1,409 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "qcs8550.dtsi"
+#include "pm8550.dtsi"
+#include "pm8550b.dtsi"
+#define PMK8550VE_SID 5
+#include "pm8550ve.dtsi"
+#include "pm8550vs.dtsi"
+#include "pmk8550.dtsi"
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pm8550-rpmh-regulators";
+		qcom,pmic-id = "b";
+
+		vdd-l1-l4-l10-supply = <&vreg_s6g_1p86>;
+		vdd-l2-l13-l14-supply = <&vreg_bob1>;
+		vdd-l3-supply = <&vreg_s4g_1p25>;
+		vdd-l5-l16-supply = <&vreg_bob1>;
+		vdd-l6-l7-supply = <&vreg_bob1>;
+		vdd-l8-l9-supply = <&vreg_bob1>;
+		vdd-l11-supply = <&vreg_s4g_1p25>;
+		vdd-l12-supply = <&vreg_s6g_1p86>;
+		vdd-l15-supply = <&vreg_s6g_1p86>;
+		vdd-l17-supply = <&vreg_bob2>;
+
+		vreg_bob1: bob1 {
+			regulator-name = "vreg_bob1";
+			regulator-min-microvolt = <3296000>;
+			regulator-max-microvolt = <3960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_bob2: bob2 {
+			regulator-name = "vreg_bob2";
+			regulator-min-microvolt = <2720000>;
+			regulator-max-microvolt = <3960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1b_1p8: ldo1 {
+			regulator-name = "vreg_l1b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2b_3p0: ldo2 {
+			regulator-name = "vreg_l2b_3p0";
+			regulator-min-microvolt = <3008000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5b_3p1: ldo5 {
+			regulator-name = "vreg_l5b_3p1";
+			regulator-min-microvolt = <3104000>;
+			regulator-max-microvolt = <3104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6b_1p8: ldo6 {
+			regulator-name = "vreg_l6b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7b_1p8: ldo7 {
+			regulator-name = "vreg_l7b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8b_1p8: ldo8 {
+			regulator-name = "vreg_l8b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9b_2p9: ldo9 {
+			regulator-name = "vreg_l9b_2p9";
+			regulator-min-microvolt = <2960000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l11b_1p2: ldo11 {
+			regulator-name = "vreg_l11b_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1504000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l12b_1p8: ldo12 {
+			regulator-name = "vreg_l12b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l13b_3p0: ldo13 {
+			regulator-name = "vreg_l13b_3p0";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l14b_3p2: ldo14 {
+			regulator-name = "vreg_l14b_3p2";
+			regulator-min-microvolt = <3200000>;
+			regulator-max-microvolt = <3200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l15b_1p8: ldo15 {
+			regulator-name = "vreg_l15b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l16b_2p8: ldo16 {
+			regulator-name = "vreg_l16b_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l17b_2p5: ldo17 {
+			regulator-name = "vreg_l17b_2p5";
+			regulator-min-microvolt = <2504000>;
+			regulator-max-microvolt = <2504000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pm8550vs-rpmh-regulators";
+		qcom,pmic-id = "c";
+
+		vdd-l1-supply = <&vreg_s4g_1p25>;
+		vdd-l2-supply = <&vreg_s4e_0p95>;
+		vdd-l3-supply = <&vreg_s4e_0p95>;
+
+		vreg_l3c_0p9: ldo3 {
+			regulator-name = "vreg_l3c_0p9";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-2 {
+		compatible = "qcom,pm8550vs-rpmh-regulators";
+		qcom,pmic-id = "d";
+
+		vdd-l1-supply = <&vreg_s4e_0p95>;
+		vdd-l2-supply = <&vreg_s4e_0p95>;
+		vdd-l3-supply = <&vreg_s4e_0p95>;
+
+		vreg_l1d_0p88: ldo1 {
+			regulator-name = "vreg_l1d_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <920000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-3 {
+		compatible = "qcom,pm8550vs-rpmh-regulators";
+		qcom,pmic-id = "e";
+
+		vdd-l1-supply = <&vreg_s4e_0p95>;
+		vdd-l2-supply = <&vreg_s4e_0p95>;
+		vdd-l3-supply = <&vreg_s4g_1p25>;
+
+		vreg_s4e_0p95: smps4 {
+			regulator-name = "vreg_s4e_0p95";
+			regulator-min-microvolt = <904000>;
+			regulator-max-microvolt = <984000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s5e_1p08: smps5 {
+			regulator-name = "vreg_s5e_1p08";
+			regulator-min-microvolt = <1010000>;
+			regulator-max-microvolt = <1120000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1e_0p88: ldo1 {
+			regulator-name = "vreg_l1e_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2e_0p9: ldo2 {
+			regulator-name = "vreg_l2e_0p9";
+			regulator-min-microvolt = <870000>;
+			regulator-max-microvolt = <970000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3e_1p2: ldo3 {
+			regulator-name = "vreg_l3e_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-4 {
+		compatible = "qcom,pm8550ve-rpmh-regulators";
+		qcom,pmic-id = "f";
+
+		vdd-l1-supply = <&vreg_s4e_0p95>;
+		vdd-l2-supply = <&vreg_s4e_0p95>;
+		vdd-l3-supply = <&vreg_s4e_0p95>;
+
+		vreg_s4f_0p5: smps4 {
+			regulator-name = "vreg_s4f_0p5";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <700000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1f_0p9: ldo1 {
+			regulator-name = "vreg_l1f_0p9";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2f_0p88: ldo2 {
+			regulator-name = "vreg_l2f_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3f_0p88: ldo3 {
+			regulator-name = "vreg_l3f_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-5 {
+		compatible = "qcom,pm8550vs-rpmh-regulators";
+		qcom,pmic-id = "g";
+		vdd-l1-supply = <&vreg_s4g_1p25>;
+		vdd-l2-supply = <&vreg_s4g_1p25>;
+		vdd-l3-supply = <&vreg_s4g_1p25>;
+
+		vreg_s1g_1p25: smps1 {
+			regulator-name = "vreg_s1g_1p25";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s2g_0p85: smps2 {
+			regulator-name = "vreg_s2g_0p85";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1036000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s3g_0p8: smps3 {
+			regulator-name = "vreg_s3g_0p8";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <1004000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s4g_1p25: smps4 {
+			regulator-name = "vreg_s4g_1p25";
+			regulator-min-microvolt = <1256000>;
+			regulator-max-microvolt = <1408000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s5g_0p85: smps5 {
+			regulator-name = "vreg_s5g_0p85";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1004000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s6g_1p86: smps6 {
+			regulator-name = "vreg_s6g_1p86";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1g_1p2: ldo1 {
+			regulator-name = "vreg_l1g_1p2";
+			regulator-min-microvolt = <1128000>;
+			regulator-max-microvolt = <1272000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2g_1p2: ldo2 {
+			regulator-name = "vreg_l2g_1p2";
+			regulator-min-microvolt = <1100000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3g_1p2: ldo3 {
+			regulator-name = "vreg_l3g_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&mdss_dsi0 {
+	vdda-supply = <&vreg_l3e_1p2>;
+};
+
+&mdss_dsi0_phy {
+	vdds-supply = <&vreg_l1e_0p88>;
+};
+
+&pcie0 {
+	perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-0 = <&pcie0_default_state>;
+	pinctrl-names = "default";
+};
+
+&pcie0_phy {
+	vdda-phy-supply = <&vreg_l1e_0p88>;
+	vdda-pll-supply = <&vreg_l3e_1p2>;
+};
+
+&pcie1 {
+	perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-0 = <&pcie1_default_state>;
+	pinctrl-names = "default";
+};
+
+&pcie1_phy {
+	vdda-phy-supply = <&vreg_l3c_0p9>;
+	vdda-pll-supply = <&vreg_l3e_1p2>;
+	vdda-qref-supply = <&vreg_l1e_0p88>;
+};
+
+&pm8550b_eusb2_repeater {
+	vdd18-supply = <&vreg_l15b_1p8>;
+	vdd3-supply = <&vreg_l5b_3p1>;
+};
+
+&sleep_clk {
+	clock-frequency = <32000>;
+};
+
+&iris {
+	status = "okay";
+};
+
+&ufs_mem_hc {
+	reset-gpios = <&tlmm 210 GPIO_ACTIVE_LOW>;
+	vcc-supply = <&vreg_l17b_2p5>;
+	vcc-max-microamp = <1300000>;
+	vccq-supply = <&vreg_l1g_1p2>;
+	vccq-max-microamp = <1200000>;
+	vdd-hba-supply = <&vreg_l3g_1p2>;
+
+	status = "okay";
+};
+
+&ufs_mem_phy {
+	vdda-phy-supply = <&vreg_l1d_0p88>;
+	vdda-pll-supply = <&vreg_l3e_1p2>;
+
+	status = "okay";
+};
+
+&usb_1_hsphy {
+	phys = <&pm8550b_eusb2_repeater>;
+
+	vdd-supply = <&vreg_l1e_0p88>;
+	vdda12-supply = <&vreg_l3e_1p2>;
+};
+
+&usb_dp_qmpphy {
+	vdda-phy-supply = <&vreg_l3e_1p2>;
+	vdda-pll-supply = <&vreg_l3f_0p88>;
+};
+
+&xo_board {
+	clock-frequency = <76800000>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8550-dma-heaps.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8550-dma-heaps.dtsi
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/arm/qcom_dma_heap_dt_constants.h>
+
+&soc {
+	qcom,dma-heaps {
+		compatible = "qcom,dma-heaps";
+
+		qcom,qseecom {
+			qcom,dma-heap-name = "qcom,qseecom";
+			qcom,dma-heap-type = <HEAP_TYPE_CMA>;
+			memory-region = <&qseecom_mem>;
+		};
+
+		qcom,qseecom_ta {
+			qcom,dma-heap-name = "qcom,qseecom-ta";
+			qcom,dma-heap-type = <HEAP_TYPE_CMA>;
+			memory-region = <&qseecom_ta_mem>;
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8550-graphics.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8550-graphics.dtsi
@@ -0,0 +1,282 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define MHZ_TO_KBPS(mhz, w) ((mhz * 1000000 * w) / (1024))
+
+&soc {
+	msm_gpu: qcom,kgsl-3d0@3d00000 {
+		compatible = "qcom,kgsl-3d0",
+			"qcom,adreno-gpu-gen7-2-1";
+		status = "ok";
+		reg = <0 0x3d00000 0 0x40000>, <0 0x3d61000 0 0x800>,
+			<0 0x03d50000 0 0x10000>, <0 0x3d8b000 0 0x2000>,
+			<0 0x03d9e000 0 0x1000>, <0 0x10900000 0 0x80000>,
+			<0 0x10048000 0 0x8000>, <0 0x10b05000 0 0x1000>;
+		reg-names = "kgsl_3d0_reg_memory", "cx_dbgc", "rscc",
+			"isense_cntl", "cx_misc", "qdss_gfx", "qdss_etr",
+			"qdss_tmc";
+		interrupts = <0 300 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "kgsl_3d0_irq";
+
+		clocks = <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+			<&gcc GCC_GPU_SNOC_DVM_GFX_CLK>,
+			<&gpucc GPU_CC_AHB_CLK>,
+			<&aoss_qmp>;
+		clock-names = "gcc_gpu_memnoc_gfx",
+				"gcc_gpu_snoc_dvm_gfx",
+				"gpu_cc_ahb", "apb_pclk";
+
+		qcom,chipid = <0x43050a01>;
+		qcom,gpu-model = "Adreno740v2";
+
+		qcom,min-access-length = <32>;
+
+		qcom,ubwc-mode = <4>;
+
+		qcom,gpu-qdss-stm = <0x161c0000 0x40000>; /* base addr, size */
+
+		qcom,tzone-names = "gpuss-0", "gpuss-1", "gpuss-2", "gpuss-3",
+				"gpuss-4", "gpuss-5", "gpuss-6", "gpuss-7";
+
+		interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>;
+		interconnect-names = "gpu_icc_path";
+
+		qcom,initial-pwrlevel = <7>;
+		qcom,initial-min-pwrlevel = <7>;
+
+		qcom,bus-table-cnoc =
+			<0>,   /* Off */
+			<100>; /* On */
+
+		qcom,bus-table-ddr =
+			<MHZ_TO_KBPS(0, 4)>,    /* index=0 */
+			<MHZ_TO_KBPS(547, 4) >, /* index=1 */
+			<MHZ_TO_KBPS(768, 4) >, /* index=2 */
+			<MHZ_TO_KBPS(1555, 4)>, /* index=3 */
+			<MHZ_TO_KBPS(1708, 4)>, /* index=4 */
+			<MHZ_TO_KBPS(2092, 4)>, /* index=5 */
+			<MHZ_TO_KBPS(2736, 4)>, /* index=6 */
+			<MHZ_TO_KBPS(3187, 4)>, /* index=7 */
+			<MHZ_TO_KBPS(3686, 4)>, /* index=8 */
+			<MHZ_TO_KBPS(4224, 4)>; /* index=9 */
+
+		zap-shader {
+			memory-region = <&gpu_micro_code_mem>;
+		};
+
+		qcom,gpu-mempools {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "qcom,gpu-mempools";
+
+			/* 4K Page Pool configuration */
+			qcom,gpu-mempool@0 {
+				reg = <0>;
+				qcom,mempool-page-size = <4096>;
+				qcom,mempool-reserved = <2048>;
+			};
+			/* 8K Page Pool configuration */
+			qcom,gpu-mempool@1 {
+				reg = <1>;
+				qcom,mempool-page-size = <8192>;
+				qcom,mempool-reserved = <1024>;
+			};
+			/* 64K Page Pool configuration */
+			qcom,gpu-mempool@2 {
+				reg = <2>;
+				qcom,mempool-page-size = <65536>;
+				qcom,mempool-reserved = <256>;
+			};
+			/* 128K Page Pool configuration */
+			qcom,gpu-mempool@3 {
+				reg = <3>;
+				qcom,mempool-page-size = <131072>;
+				qcom,mempool-reserved = <128>;
+			};
+			/* 256K Page Pool configuration */
+			qcom,gpu-mempool@4 {
+				reg = <4>;
+				qcom,mempool-page-size = <262144>;
+				qcom,mempool-reserved = <80>;
+			};
+			/* 1M Page Pool configuration */
+			qcom,gpu-mempool@5 {
+				reg = <5>;
+				qcom,mempool-page-size = <1048576>;
+				qcom,mempool-reserved = <32>;
+			};
+		};
+
+		/* Power levels */
+		qcom,gpu-pwrlevels {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			compatible = "qcom,gpu-pwrlevels";
+
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <680000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+				qcom,bus-freq = <9>;
+				qcom,bus-min = <9>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <0x882e5ffd>;
+			};
+
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <615000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L0>;
+
+				qcom,bus-freq = <6>;
+				qcom,bus-min = <3>;
+				qcom,bus-max = <9>;
+
+				qcom,acd-level = <0xa82f5ffd>;
+			};
+
+			qcom,gpu-pwrlevel@2 {
+				reg = <2>;
+				qcom,gpu-freq = <550000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <2>;
+				qcom,bus-max = <7>;
+
+				qcom,acd-level = <0xe0285ffd>;
+			};
+
+			qcom,gpu-pwrlevel@3 {
+				reg = <3>;
+				qcom,gpu-freq = <475000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <5>;
+
+				qcom,acd-level = <0xe0285ffd>;
+			};
+
+			qcom,gpu-pwrlevel@4 {
+				reg = <4>;
+				qcom,gpu-freq = <401000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <4>;
+
+				qcom,acd-level = <0xc02a5ffd>;
+			};
+
+			qcom,gpu-pwrlevel@5 {
+				reg = <5>;
+				qcom,gpu-freq = <348000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <3>;
+
+				qcom,acd-level = <0xe02b5ffd>;
+			};
+
+			qcom,gpu-pwrlevel@6 {
+				reg = <6>;
+				qcom,gpu-freq = <295000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>;
+
+				qcom,bus-freq = <3>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <3>;
+
+				qcom,acd-level = <0xe02d5ffd>;
+			};
+
+			qcom,gpu-pwrlevel@7 {
+				reg = <7>;
+				qcom,gpu-freq = <220000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>;
+
+				qcom,bus-freq = <1>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <3>;
+
+				qcom,acd-level = <0xc02f5ffd>;
+			};
+
+			qcom,gpu-pwrlevel@8 {
+				reg = <8>;
+				qcom,gpu-freq = <124800000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>;
+
+				qcom,bus-freq = <1>;
+				qcom,bus-min = <1>;
+				qcom,bus-max = <1>;
+			};
+		};
+	};
+
+	kgsl_msm_iommu: qcom,kgsl-iommu@3da0000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		compatible = "qcom,kgsl-smmu-v2";
+
+		reg = <0x03da0000 0x40000>;
+
+		power-domains = <&gpucc GPU_CC_CX_GDSC>;
+
+		gfx3d_user: gfx3d_user {
+			compatible = "qcom,smmu-kgsl-cb", "qcom,adreno";
+			iommus = <&adreno_smmu 0x0 0x000>, <&adreno_smmu 0x1 0x000>;
+			qcom,iommu-dma = "disabled";
+		};
+	};
+
+	gmu: qcom,gmu@3d68000 {
+		compatible = "qcom,gen7-gmu";
+
+		reg = <0 0x3d68000 0 0x37000>,
+			<0 0xb280000 0 0x10000>,
+			<0 0x03D40000 0 0x10000>;
+
+		reg-names = "gmu", "gmu_pdc", "gmu_ao_blk_dec0";
+
+		interrupts = <0 304 IRQ_TYPE_LEVEL_HIGH>,
+			<0 305 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "hfi", "gmu";
+
+		power-domains = <&gpucc GPU_CC_CX_GDSC>, <&gpucc GPU_CC_GX_GDSC>;
+		power-domain-names = "cx", "gx";
+
+		clocks = <&gpucc GPU_CC_CX_GMU_CLK>,
+			<&gpucc GPU_CC_CXO_CLK>,
+			<&gcc GCC_DDRSS_GPU_AXI_CLK>,
+			<&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+			<&gpucc GPU_CC_AHB_CLK>,
+			<&gpucc GPU_CC_HUB_CX_INT_CLK>;
+
+		clock-names = "gmu_clk", "cxo_clk", "axi_clk",
+			"memnoc_clk", "ahb_clk", "hub_clk";
+
+		qcom,gmu-freq-table = <220000000 RPMH_REGULATOR_LEVEL_LOW_SVS>,
+					<550000000 RPMH_REGULATOR_LEVEL_SVS>;
+
+		iommus = <&adreno_smmu 0x5 0x000>;
+		qcom,iommu-dma = "disabled";
+
+		qcom,qmp = <&aoss_qmp>;
+
+		qcom,ipc-core = <0x00400000 0xfc000>;
+	};
+
+};
+
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8550-graphics.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8550-graphics.dtso
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,sm8550-gcc.h>
+#include <dt-bindings/clock/qcom,sm8550-gpucc.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/interconnect/qcom,sm8550-rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "qcs8550-graphics.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS8550 AIM300";
+	compatible = "qcom,kalama", "qcom,kalamap", "qcom,qcs8550-aim300", "qcom,qcs8550";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8550-qps615.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8550-qps615.dtsi
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+*/
+
+#include <dt-bindings/gpio/gpio.h>
+
+&pcie1 {
+	pcie1_rp: pcie1-rp {
+		reg = <0x0 0x0 0x0 0x0 0x0>;
+	};
+};
+
+&pcie1_rp {
+	#address-cells = <5>;
+	#size-cells = <0>;
+
+	/* BDF 1.0.0 */
+	pcie1_bus1_dev0_fn0: pcie1-bus1-dev0-fn0 {
+		reg = <0x0 0x0 0x0 0x0 0x0>;
+
+		/* BDF 2.3.0 */
+		pcie1_bus2_dev3_fn0: pcie1-bus2-dev3-fn0 {
+			reg = <0x1800 0x0 0x0 0x0 0x0>;
+			qps615_rlt8211_eth1,qps615-rlt8211-eth1@pcie1_rp {
+				reg = <0x100 0x0 0x0 0x0 0x0>;
+				qcom,not-need-pinctrl;
+				qcom,phy-port-interface = <2>;
+				/* phy intn_wol int */
+				qcom,phy-built-in-wol;
+
+				/* phy reset*/
+				qcom,phy-rst-gpio-id = <1>;
+				qcom,phy-rst-delay-us = <10000>;
+				qcom,phy-rst-settling-delay-us = <72000>;
+				qcom,phy-reverse-rst;
+
+				/* power enable*/
+				phy-supply = <&ethernet_phy_vreg>;
+			};
+		};
+	};
+};
+
+&soc {
+	ethernet_phy_vreg: phy-vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "ethernet_phy_vreg";
+		gpio = <&tlmm 106 GPIO_ACTIVE_HIGH>;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		regulator-enable-ramp-delay = <10000>;
+	};
+};
\ No newline at end of file
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8550-qps615.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8550-qps615.dtso
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+*/
+/dts-v1/;
+/plugin/;
+
+#include "qcs8550-qps615.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS8550 AIM300";
+	compatible = "qcom,qcs8550-aim300", "qcom,qcs8550";
+};
\ No newline at end of file
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8550-rb5gen2-hdk.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8550-rb5gen2-hdk.dts
@@ -0,0 +1,226 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include "qcs8550-rb5gen2.dtsi"
+#include "pm8010.dtsi"
+#include "pmr735d_a.dtsi"
+#include "pmr735d_b.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS8550 RB5Gen2 HDK";
+	compatible = "qcom,qcs8550-rb5gen2-hdk", "qcom,qcs8550-rb5gen2",
+			"qcom,qcs8550", "qcom,qcm8550", "qcom,sm8550";
+
+	qcom,msm-id = <603 0x20000>;
+	qcom,board-id = <0x1001f 2>;
+
+	aliases {
+		serial0 = &uart7;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		pinctrl-0 = <&volume_up_n>;
+		pinctrl-names = "default";
+
+		key-volume-up {
+			label = "Volume Up";
+			debounce-interval = <15>;
+			gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_VOLUMEUP>;
+			linux,can-disable;
+			wakeup-source;
+		};
+	};
+
+	pmic-glink {
+		compatible = "qcom,sm8550-pmic-glink", "qcom,pmic-glink";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		connector@0 {
+			compatible = "usb-c-connector";
+			reg = <0>;
+			power-role = "dual";
+			data-role = "dual";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					pmic_glink_hs_in: endpoint {
+						remote-endpoint = <&usb_1_dwc3_hs>;
+					};
+				};
+			};
+		};
+	};
+
+	vph_pwr: vph-pwr-regulator {
+		compatible = "regulator-fixed";
+		regulator-name = "vph_pwr";
+		regulator-min-microvolt = <3700000>;
+		regulator-max-microvolt = <3700000>;
+
+		regulator-always-on;
+		regulator-boot-on;
+	};
+};
+
+&apps_rsc {
+	regulators-0 {
+		vdd-bob1-supply = <&vph_pwr>;
+		vdd-bob2-supply = <&vph_pwr>;
+	};
+
+	regulators-2 {
+		vdd-s4-supply = <&vph_pwr>;
+		vdd-s5-supply = <&vph_pwr>;
+	};
+
+	regulators-3 {
+		vdd-s1-supply = <&vph_pwr>;
+		vdd-s3-supply = <&vph_pwr>;
+		vdd-s4-supply = <&vph_pwr>;
+		vdd-s5-supply = <&vph_pwr>;
+		vdd-s6-supply = <&vph_pwr>;
+	};
+
+	regulators-4 {
+		vdd-s1-supply = <&vph_pwr>;
+		vdd-s3-supply = <&vph_pwr>;
+		vdd-s4-supply = <&vph_pwr>;
+		vdd-s5-supply = <&vph_pwr>;
+		vdd-s7-supply = <&vph_pwr>;
+	};
+
+	regulators-5 {
+		vdd-s1-supply = <&vph_pwr>;
+		vdd-s2-supply = <&vph_pwr>;
+		vdd-s3-supply = <&vph_pwr>;
+		vdd-s4-supply = <&vph_pwr>;
+		vdd-s5-supply = <&vph_pwr>;
+		vdd-s6-supply = <&vph_pwr>;
+	};
+};
+
+&pm8550_flash {
+	status = "okay";
+
+	led-0 {
+		function = LED_FUNCTION_FLASH;
+		color = <LED_COLOR_ID_YELLOW>;
+		flash-max-microamp = <2000000>;
+		flash-max-timeout-us = <1280000>;
+		function-enumerator = <0>;
+		led-sources = <1>, <4>;
+		led-max-microamp = <500000>;
+	};
+
+	led-1 {
+		function = LED_FUNCTION_FLASH;
+		color = <LED_COLOR_ID_WHITE>;
+		flash-max-microamp = <2000000>;
+		flash-max-timeout-us = <1280000>;
+		function-enumerator = <1>;
+		led-sources = <2>, <3>;
+		led-max-microamp = <500000>;
+	};
+};
+
+&pm8550_gpios {
+	volume_up_n: volume-up-n-state {
+		pins = "gpio6";
+		function = "normal";
+		power-source = <1>;
+		bias-pull-up;
+		input-enable;
+	};
+};
+
+&pm8550_pwm {
+	status = "okay";
+
+	multi-led {
+		color = <LED_COLOR_ID_RGB>;
+		function = LED_FUNCTION_STATUS;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		led@1 {
+			reg = <1>;
+			color = <LED_COLOR_ID_RED>;
+		};
+
+		led@2 {
+			reg = <2>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		led@3 {
+			reg = <3>;
+			color = <LED_COLOR_ID_BLUE>;
+		};
+	};
+};
+
+&pm8550b_eusb2_repeater {
+	vdd18-supply = <&vreg_l15b_1p8>;
+	vdd3-supply = <&vreg_l5b_3p1>;
+};
+
+&pon_pwrkey {
+	status = "okay";
+};
+
+&pon_resin {
+	linux,code = <KEY_VOLUMEDOWN>;
+	status = "okay";
+};
+
+&uart7 {
+	status = "okay";
+};
+
+&usb_1 {
+	status = "okay";
+};
+
+&usb_1_dwc3 {
+	dr_mode = "otg";
+	usb-role-switch;
+};
+
+&usb_1_dwc3_hs {
+	remote-endpoint = <&pmic_glink_hs_in>;
+};
+
+&usb_1_hsphy {
+	vdd-supply = <&vreg_l1e_0p88>;
+	vdda12-supply = <&vreg_l3e_1p2>;
+
+	phys = <&pm8550b_eusb2_repeater>;
+
+	status = "okay";
+};
+
+&usb_dp_qmpphy {
+	vdda-phy-supply = <&vreg_l3e_1p2>;
+	vdda-pll-supply = <&vreg_l3f_0p88>;
+
+	status = "okay";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8550-rb5gen2.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8550-rb5gen2.dtsi
@@ -0,0 +1,460 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "qcs8550.dtsi"
+#include "pm8550.dtsi"
+#include "pm8550b.dtsi"
+#define PMK8550VE_SID 5
+#include "pm8550ve.dtsi"
+#include "pm8550vs.dtsi"
+#include "pmk8550.dtsi"
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pm8550-rpmh-regulators";
+		qcom,pmic-id = "b";
+
+		vdd-l1-l4-l10-supply = <&vreg_s6g_1p86>;
+		vdd-l2-l13-l14-supply = <&vreg_bob1>;
+		vdd-l5-l16-supply = <&vreg_bob1>;
+		vdd-l6-l7-supply = <&vreg_bob1>;
+		vdd-l8-l9-supply = <&vreg_bob1>;
+		vdd-l11-supply = <&vreg_s4g_1p25>;
+		vdd-l12-supply = <&vreg_s6g_1p86>;
+		vdd-l15-supply = <&vreg_s6g_1p86>;
+		vdd-l17-supply = <&vreg_bob2>;
+
+		vreg_bob1: bob1 {
+			regulator-name = "vreg_bob1";
+			regulator-min-microvolt = <3296000>;
+			regulator-max-microvolt = <3960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_bob2: bob2 {
+			regulator-name = "vreg_bob2";
+			regulator-min-microvolt = <2720000>;
+			regulator-max-microvolt = <3960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1b_1p8: ldo1 {
+			regulator-name = "vreg_l1b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2b_3p0: ldo2 {
+			regulator-name = "vreg_l2b_3p0";
+			regulator-min-microvolt = <3008000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5b_3p1: ldo5 {
+			regulator-name = "vreg_l5b_3p1";
+			regulator-min-microvolt = <3104000>;
+			regulator-max-microvolt = <3104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6b_1p8: ldo6 {
+			regulator-name = "vreg_l6b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7b_1p8: ldo7 {
+			regulator-name = "vreg_l7b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8b_1p8: ldo8 {
+			regulator-name = "vreg_l8b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9b_2p9: ldo9 {
+			regulator-name = "vreg_l9b_2p9";
+			regulator-min-microvolt = <2960000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l10b_1p8: ldo10 {
+			regulator-name = "vreg_l10b_1p8";
+			regulator-min-microvolt = <1620000>;
+			regulator-max-microvolt = <1980000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l11b_1p2: ldo11 {
+			regulator-name = "vreg_l11b_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1504000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l12b_1p8: ldo12 {
+			regulator-name = "vreg_l12b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l13b_3p0: ldo13 {
+			regulator-name = "vreg_l13b_3p0";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l14b_3p2: ldo14 {
+			regulator-name = "vreg_l14b_3p2";
+			regulator-min-microvolt = <3200000>;
+			regulator-max-microvolt = <3200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l15b_1p8: ldo15 {
+			regulator-name = "vreg_l15b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l16b_2p8: ldo16 {
+			regulator-name = "vreg_l16b_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l17b_2p5: ldo17 {
+			regulator-name = "vreg_l17b_2p5";
+			regulator-min-microvolt = <2504000>;
+			regulator-max-microvolt = <2504000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pm8550vs-rpmh-regulators";
+		qcom,pmic-id = "c";
+
+		vdd-l1-supply = <&vreg_s4g_1p25>;
+		vdd-l3-supply = <&vreg_s4e_0p95>;
+
+		vreg_l1c_1p2: ldo1 {
+			regulator-name = "vreg_l1c_1p2";
+			regulator-min-microvolt = <1100000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3c_0p9: ldo3 {
+			regulator-name = "vreg_l3c_0p9";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-2 {
+		compatible = "qcom,pm8550vs-rpmh-regulators";
+		qcom,pmic-id = "d";
+
+		vdd-l1-supply = <&vreg_s4e_0p95>;
+		vdd-l2-supply = <&vreg_s4e_0p95>;
+
+		vreg_s4d_0p628: smps4 {
+			regulator-name = "vreg_s4d_0p628";
+			regulator-min-microvolt = <572000>;
+			regulator-max-microvolt = <800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s5d_0p728: smps5 {
+			regulator-name = "vreg_s5d_0p728";
+			regulator-min-microvolt = <465000>;
+			regulator-max-microvolt = <815000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1d_0p88: ldo1 {
+			regulator-name = "vreg_l1d_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <920000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2d_0p752: ldo2 {
+			regulator-name = "vreg_l2d_0p752";
+			regulator-min-microvolt = <752000>;
+			regulator-max-microvolt = <800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-3 {
+		compatible = "qcom,pm8550vs-rpmh-regulators";
+		qcom,pmic-id = "e";
+
+		vdd-l1-supply = <&vreg_s4e_0p95>;
+		vdd-l2-supply = <&vreg_s4e_0p95>;
+		vdd-l3-supply = <&vreg_s4g_1p25>;
+
+		vreg_l1e_0p88: ldo1 {
+			regulator-name = "vreg_l1e_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <880000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2e_0p9: ldo2 {
+			regulator-name = "vreg_l2e_0p9";
+			regulator-min-microvolt = <904000>;
+			regulator-max-microvolt = <970000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3e_1p2: ldo3 {
+			regulator-name = "vreg_l3e_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s1e_0p728: smps1 {
+			regulator-name = "vreg_s1e_0p728";
+			regulator-min-microvolt = <675000>;
+			regulator-max-microvolt = <832000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s3e_0p752: smps3 {
+			regulator-name = "vreg_s3e_0p752";
+			regulator-min-microvolt = <752000>;
+			regulator-max-microvolt = <795000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s4e_0p95: smps4 {
+			regulator-name = "vreg_s4e_0p95";
+			regulator-min-microvolt = <904000>;
+			regulator-max-microvolt = <984000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s5e_1p08: smps5 {
+			regulator-name = "vreg_s5e_1p08";
+			regulator-min-microvolt = <1080000>;
+			regulator-max-microvolt = <1120000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s6e_0p728: smps6 {
+			regulator-name = "vreg_s6e_0p728";
+			regulator-min-microvolt = <675000>;
+			regulator-max-microvolt = <800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-4 {
+		compatible = "qcom,pm8550ve-rpmh-regulators";
+		qcom,pmic-id = "f";
+
+		vdd-l1-supply = <&vreg_s4e_0p95>;
+		vdd-l2-supply = <&vreg_s4e_0p95>;
+		vdd-l3-supply = <&vreg_s4e_0p95>;
+
+		vreg_l1f_0p9: ldo1 {
+			regulator-name = "vreg_l1f_0p9";
+			regulator-min-microvolt = <912000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2f_0p88: ldo2 {
+			regulator-name = "vreg_l2f_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3f_0p88: ldo3 {
+			regulator-name = "vreg_l3f_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s1f_0p728: smps1 {
+			regulator-name = "vreg_s1f_0p728";
+			regulator-min-microvolt = <584000>;
+			regulator-max-microvolt = <856000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s3f_0p825: smps3 {
+			regulator-name = "vreg_s3f_0p825";
+			regulator-min-microvolt = <640000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s4f_0p5: smps4 {
+			regulator-name = "vreg_s4f_0p5";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <700000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s5f_0p752: smps5 {
+			regulator-name = "vreg_s5f_0p752";
+			regulator-min-microvolt = <752000>;
+			regulator-max-microvolt = <800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s7f_0p628: smps7 {
+			regulator-name = "vreg_s7f_0p628";
+			regulator-min-microvolt = <465000>;
+			regulator-max-microvolt = <1050000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-5 {
+		compatible = "qcom,pm8550vs-rpmh-regulators";
+		qcom,pmic-id = "g";
+
+		vdd-l1-supply = <&vreg_s4g_1p25>;
+		vdd-l2-supply = <&vreg_s4g_1p25>;
+		vdd-l3-supply = <&vreg_s4g_1p25>;
+
+		vreg_l1g_1p2: ldo1 {
+			regulator-name = "vreg_l1g_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2g_1p2: ldo2 {
+			regulator-name = "vreg_l2g_1p2";
+			regulator-min-microvolt = <1100000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3g_1p2: ldo3 {
+			regulator-name = "vreg_l3g_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s1g_1p25: smps1 {
+			regulator-name = "vreg_s1g_1p25";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s2g_0p85: smps2 {
+			regulator-name = "vreg_s2g_0p85";
+			regulator-min-microvolt = <800000>;
+			regulator-max-microvolt = <1000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s3g_0p8: smps3 {
+			regulator-name = "vreg_s3g_0p8";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <1004000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s4g_1p25: smps4 {
+			regulator-name = "vreg_s4g_1p25";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1352000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s5g_0p85: smps5 {
+			regulator-name = "vreg_s5g_0p85";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1004000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s6g_1p86: smps6 {
+			regulator-name = "vreg_s6g_1p86";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&iris {
+	status = "okay";
+};
+
+&remoteproc_adsp {
+	firmware-name = "qcom/qcs8550/adsp.mdt",
+			"qcom/qcs8550/adsp_dtb.mdt";
+	status = "okay";
+};
+
+&remoteproc_cdsp {
+	firmware-name = "qcom/qcs8550/cdsp.mdt",
+			"qcom/qcs8550/cdsp_dtb.mdt";
+	status = "okay";
+};
+
+&remoteproc_mpss {
+	firmware-name = "qcom/qcs8550/modem.mdt",
+			"qcom/qcs8550/modem_dtb.mdt";
+	status = "okay";
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&sleep_clk {
+	clock-frequency = <32000>;
+};
+
+&ufs_mem_hc {
+	reset-gpios = <&tlmm 210 GPIO_ACTIVE_LOW>;
+	vcc-supply = <&vreg_l17b_2p5>;
+	vcc-max-microamp = <1300000>;
+	vccq-supply = <&vreg_l1g_1p2>;
+	vccq-max-microamp = <1200000>;
+
+	status = "okay";
+};
+
+&ufs_mem_phy {
+	vdda-phy-supply = <&vreg_l1d_0p88>;
+	vdda-pll-supply = <&vreg_l3e_1p2>;
+
+	status = "okay";
+};
+
+&xo_board {
+	clock-frequency = <76800000>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs8550.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs8550.dtsi
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "sm8550.dtsi"
+
+/delete-node/ &reserved_memory;
+
+/ {
+	reserved_memory: reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+
+		/* These are 3 types of reserved memory regions here:
+		 * 1. Firmware related regions which aren't shared with kernel.
+		 *     The device tree source in kernel doesn't need to have node to
+		 * indicate the firmware related reserved information. Bootloader
+		 * conveys the information by updating devicetree at runtime.
+		 *     This will be described as: UEFI saves the physical address of
+		 * the UEFI System Table to dts file's chosen node. Kernel read this
+		 * table and add reserved memory regions to efi config table. Current
+		 * reserved memory region may have reserved region which was not yet
+		 * used, release note of the firmware have such kind of information.
+		 * 2. Firmware related memory regions which are shared with Kernel
+		 *     The device tree source in the kernel needs to include nodes
+		 * that indicate fimware-related shared information. A label name
+		 * is suggested because this type of shared information needs to
+		 * be referenced by specific drivers for handling purposes.
+		 *     Unlike previous platforms, QCS8550 boots using EFI and describes
+		 * most reserved regions in the ESRT memory map. As a result, reserved
+		 * memory regions which aren't relevant to the kernel(like the hypervisor
+		 ( region) don't need to be described in DT.
+		 * 3. Remoteproc regions.
+		 *     Remoteproc regions will be reserved and then assigned to
+		 * subsystem firmware later.
+		 * Here is a reserved memory map for this platform:
+		 *  0x80000000 +-------------------+
+		 *             |                   |
+		 *             | Firmware Related  |
+		 *             |                   |
+		 *  0x8a800000 +-------------------+
+		 *             |                   |
+		 *             | Remoteproc Region |
+		 *             |                   |
+		 *  0xa7000000 +-------------------+
+		 *             |                   |
+		 *             | Kernel Available  |
+		 *             |                   |
+		 *  0xd4d00000 +-------------------+
+		 *             |                   |
+		 *             | Firmware Related  |
+		 *             |                   |
+		 * 0x100000000 +-------------------+
+		 */
+
+		aop_image_mem: aop-image-region@81c00000 {
+			reg = <0x0 0x81c00000 0x0 0x60000>;
+			no-map;
+		};
+
+		aop_cmd_db_mem: aop-cmd-db-region@81c60000 {
+			compatible = "qcom,cmd-db";
+			reg = <0x0 0x81c60000 0x0 0x20000>;
+			no-map;
+		};
+
+		aop_config_mem: aop-config-region@81c80000 {
+			no-map;
+			reg = <0x0 0x81c80000 0x0 0x20000>;
+		};
+
+		smem_mem: smem-region@81d00000 {
+			compatible = "qcom,smem";
+			reg = <0x0 0x81d00000 0x0 0x200000>;
+			hwlocks = <&tcsr_mutex 3>;
+			no-map;
+		};
+
+		adsp_mhi_mem: adsp-mhi-region@81f00000 {
+			reg = <0x0 0x81f00000 0x0 0x20000>;
+			no-map;
+		};
+
+		mpss_mem: mpss-region@8a800000 {
+			reg = <0x0 0x8a800000 0x0 0x10800000>;
+			no-map;
+		};
+
+		q6_mpss_dtb_mem: q6-mpss-dtb-region@9b000000 {
+			reg = <0x0 0x9b000000 0x0 0x80000>;
+			no-map;
+		};
+
+		ipa_fw_mem: ipa-fw-region@9b080000 {
+			reg = <0x0 0x9b080000 0x0 0x10000>;
+			no-map;
+		};
+
+		ipa_gsi_mem: ipa-gsi-region@9b090000 {
+			reg = <0x0 0x9b090000 0x0 0xa000>;
+			no-map;
+		};
+
+		gpu_micro_code_mem: gpu-micro-code-region@9b09a000 {
+			reg = <0x0 0x9b09a000 0x0 0x2000>;
+			no-map;
+		};
+
+		spss_region_mem: spss-region@9b100000 {
+			reg = <0x0 0x9b100000 0x0 0x180000>;
+			no-map;
+		};
+
+		spu_secure_shared_memory_mem: spu-secure-shared-memory-region@9b280000 {
+			reg = <0x0 0x9b280000 0x0 0x80000>;
+			no-map;
+		};
+
+		camera_mem: camera-region@9b300000 {
+			reg = <0x0 0x9b300000 0x0 0x800000>;
+			no-map;
+		};
+
+		video_mem: video-region@9bb00000 {
+			reg = <0x0 0x9bb00000 0x0 0x700000>;
+			no-map;
+		};
+
+		cvp_mem: cvp-region@9c200000 {
+			reg = <0x0 0x9c200000 0x0 0x700000>;
+			no-map;
+		};
+
+		cdsp_mem: cdsp-region@9c900000 {
+			reg = <0x0 0x9c900000 0x0 0x2000000>;
+			no-map;
+		};
+
+		q6_cdsp_dtb_mem: q6-cdsp-dtb-region@9e900000 {
+			reg = <0x0 0x9e900000 0x0 0x80000>;
+			no-map;
+		};
+
+		q6_adsp_dtb_mem: q6-adsp-dtb-region@9e980000 {
+			reg = <0x0 0x9e980000 0x0 0x80000>;
+			no-map;
+		};
+
+		adspslpi_mem: adspslpi-region@9ea00000 {
+			reg = <0x0 0x9ea00000 0x0 0x4080000>;
+			no-map;
+		};
+
+		mpss_dsm_mem: mpss_dsm_region@d4d00000 {
+			reg = <0x0 0xd4d00000 0x0 0x3300000>;
+			no-map;
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9075-addons-iq-9075-evk-mezz.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9075-addons-iq-9075-evk-mezz.dtso
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+&{/} {
+	model = "Qualcomm Technologies, Inc. IQ-9075-evk Addons Mezzanine";
+	qcom,board-id = <0x00010020 1>, <0x00010019 1>;
+
+	qps615_rsex_vreg: qps615-rsex-vreg {
+	        compatible = "regulator-fixed";
+	        regulator-name = "qps615_rsex_vreg";
+	        gpio = <&tlmm 140 GPIO_ACTIVE_HIGH>;
+	        regulator-min-microvolt = <1800000>;
+	        regulator-max-microvolt = <1800000>;
+	        enable-active-high;
+	        regulator-enable-ramp-delay = <10000>;
+	};
+};
+
+&connector_usb1 {
+	status = "disabled";
+};
+
+&i2c18 {
+    qps615_switch: pcie-switch@77 {
+        compatible = "qcom,switch-i2c";
+        reg = <0x77>;
+        vdda-supply = <&qps615_rsex_vreg>;
+
+        status = "okay";
+	};
+
+};
+
+&pcie0 {
+	dummy-supply = <&qps615_switch>;
+	iommu-map = <0x0 &apps_smmu 0x0000 0x1>,
+		<0x100 &pcie_smmu 0x0001 0x1>,
+		<0x208 &pcie_smmu 0x0002 0x1>,
+		<0x210 &pcie_smmu 0x0003 0x1>,
+		<0x218 &pcie_smmu 0x0004 0x1>,
+		<0x300 &pcie_smmu 0x0005 0x1>,
+		<0x400 &pcie_smmu 0x0006 0x1>,
+		<0x500 &pcie_smmu 0x0007 0x1>,
+		<0x501 &pcie_smmu 0x0008 0x1>;
+
+	pcieport0: pcie@0 {
+		device_type = "pci";
+		reg = <0x0 0x0 0x0 0x0 0x0>;
+		#address-cells = <5>;
+		#size-cells = <0>;
+
+		/* BDF 1.0.0 */
+		pcie0_bus1_dev0_fn0: pcie0_bus1_dev0_fn0 {
+			reg = <0 0 0 0 0>;
+
+			/* BDF 2.1.0 */
+			pcie0_bus2_dev1_fn0: pcie0_bus2_dev1_fn0 {
+				reg = <0x800 0x0 0x0 0x0 0x0>;
+
+				/* BDF 3.0.0 */
+				pcie0_bus3_dev0_fn0: pcie0_bus3_dev0_fn0 {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+				};
+			};
+
+			/* BDF 2.2.0 */
+			pcie0_bus2_dev2_fn0: pcie0_bus2_dev2_fn0 {
+				reg = <0x1000 0x0 0x0 0x0 0x0>;
+
+				/* BDF 4.0.0 */
+				pcie0_bus4_dev0_fn0: pcie0_bus4_dev0_fn0 {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+				};
+			};
+
+			/* BDF 2.3.0 */
+			pcie0_bus2_dev3_fn0: pcie0_bus2_dev3_fn0 {
+				reg = <0x1800 0x0 0x0 0x0 0x0>;
+				qps615_eth0,qps615_eth0@pcie0_rp {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+				};
+
+				/* BDF 5.0.0 */
+				pcie0_bus5_dev0_fn0: pcie0_qps_eth0 {
+					reg = <0x0 0x0 0x0 0x0 0x0>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&aqr_intn_wol_sig>;
+					phy-rst-som-gpios = <&tlmm 28 GPIO_ACTIVE_HIGH>;
+					interrupts-extended = <&tlmm 56 IRQ_TYPE_EDGE_FALLING>;
+					interrupt-names = "wol_irq";
+					qcom,always-on-supply;
+					qcom,phy-rst-delay-us = <221000>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+
+					qcom,iommu-group = <&eth0_pci_iommu_group>;
+					eth0_pci_iommu_group: eth0_pci_iommu_group {
+						qcom,iommu-dma = "atomic";
+					};
+				};
+
+				qps615_eth1,qps615_eth1@pcie0_rp {
+					reg = <0x100 0x0 0x0 0x0 0x0>;
+				};
+
+				/* BDF 5.0.1 */
+				pcie0_bus5_dev0_fn1: pcie0_qps_eth1 {
+					reg = <0x100 0x0 0x0 0x0 0x0>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&napa_intn_wol_sig>;
+					phy-rst-som-gpios = <&pmm8654au_3_gpios 8 GPIO_ACTIVE_HIGH>;
+					interrupts-extended = <&tlmm 57 IRQ_TYPE_EDGE_FALLING>;
+					interrupt-names = "wol_irq";
+					qcom,always-on-supply;
+					qcom,phy-rst-delay-us = <20000>;
+					#address-cells = <1>;
+					#size-cells = <1>;
+
+					qcom,iommu-group = <&eth1_pci_iommu_group>;
+					eth1_pci_iommu_group: eth1_pci_iommu_group {
+						qcom,iommu-dma = "atomic";
+					};
+				};
+			};
+		};
+	};
+};
+
+&ethernet1 {
+	phy-handle = <&sgmii_phy1>;
+	phy-mode = "sgmii";
+
+	pinctrl-0 = <&ethernet1_default>;
+	pinctrl-names = "default";
+
+	snps,mtl-rx-config = <&mtl_rx_setup1>;
+	snps,mtl-tx-config = <&mtl_tx_setup1>;
+	snps,ps-speed = <1000>;
+
+	status = "okay";
+
+	mdio1 {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		sgmii_phy1: phy@18 {
+			compatible = "ethernet-phy-id004d.d101";
+			reg = <0x18>;
+			device_type = "ethernet-phy";
+			reset-gpios = <&pmm8654au_2_gpios 9 GPIO_ACTIVE_LOW>;
+			reset-assert-us = <11000>;
+			reset-deassert-us = <70000>;
+		};
+	};
+
+	mtl_rx_setup1: rx-queues-config {
+		snps,rx-queues-to-use = <4>;
+		snps,rx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x0>;
+			snps,route-up;
+			snps,priority = <0x1>;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x1>;
+			snps,route-ptp;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x2>;
+			snps,route-avcp;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x3>;
+			snps,priority = <0xc>;
+		};
+	};
+
+	mtl_tx_setup1: tx-queues-config {
+		snps,tx-queues-to-use = <4>;
+		snps,tx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+	};
+};
+
+&serdes1 {
+	phy-supply = <&vreg_l5a>;
+	status = "okay";
+};
+
+&tlmm {
+	ethernet1_default: ethernet1-default-state {
+		ethernet1_mdc: ethernet1-mdc-pins {
+			pins = "gpio20";
+			function = "emac1_mdc";
+			drive-strength = <16>;
+			bias-pull-up;
+		};
+
+		ethernet1_mdio: ethernet1-mdio-pins {
+			pins = "gpio21";
+			function = "emac1_mdio";
+			drive-strength = <16>;
+			bias-pull-up;
+		};
+	};
+
+	qps615_intn_wol {
+		aqr_intn_wol_sig: aqr-intn-wol-sig {
+				pins = "gpio56";
+				function = "gpio";
+				input-enable;
+				bias-disable;
+		};
+
+		napa_intn_wol_sig: napa-intn-wol-sig {
+				pins = "gpio57";
+				function = "gpio";
+				input-enable;
+				bias-disable;
+		};
+	};
+};
+
+&usb1_id_det_default {
+	status = "disabled";
+};
+
+&usb_1 {
+	vbus_dwc3-supply = <&vbus_supply_regulator_1>;
+
+	ports {
+		status = "disabled";
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9075-addons-iq-9075-evk.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9075-addons-iq-9075-evk.dts
@@ -0,0 +1,378 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024-2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+
+#include "qcs9075-iq-9075-evk.dts"
+#include "sa8775p-addons.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. Addons IQ 9075 EVK";
+	compatible = "qcom,qcs9075-addons-iq-9075-evk", "qcom,qcs9075", "qcom,sa8775p";
+
+	aliases {
+		ethernet1 = &ethernet1;
+	};
+
+	sound {
+		compatible = "qcom,qcs9075-rb8-sndcard";
+		model = "qcs9075-iq-evk-snd-card";
+
+		clocks = <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+			    <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+		clock-names = "macro", "dcodec";
+
+		pinctrl-names = "default", "mi2s_aud_out_active", "mi2s_aud_out_sleep";
+		pinctrl-0 = <&hs1_mi2s_data0_sleep>, <&mi2s_mclk_sleep>, <&hs0_mi2s_data0_sleep>,
+			    <&hs0_mi2s_sclk_sleep>, <&hs0_mi2s_data1_sleep>, <&hs0_mi2s_ws_sleep>,
+			    <&hs1_mi2s_sclk_sleep>, <&hs1_mi2s_data1_sleep>, <&hs1_mi2s_ws_sleep>,
+			    <&hs2_mi2s_data0_sleep>, <&hs2_mi2s_data1_sleep>, <&hs2_mi2s_sck_sleep>,
+			    <&hs2_mi2s_ws_sleep>, <&lpass_quad_clk_sleep>, <&lpass_quad_data_sleep>,
+			    <&lpass_quad_ws_sleep>;
+		pinctrl-1 = <&hs1_mi2s_data0>, <&mi2s_mclk>, <&hs0_mi2s_data0>,
+			    <&hs0_mi2s_sclk>, <&hs0_mi2s_data1>, <&hs0_mi2s_ws>,
+			    <&hs1_mi2s_sclk>, <&hs1_mi2s_data1>, <&hs1_mi2s_ws>,
+			    <&hs2_mi2s_data0>, <&hs2_mi2s_data1>, <&hs2_mi2s_sck>,
+			    <&hs2_mi2s_ws>, <&lpass_quad_clk>, <&lpass_quad_data>,
+			    <&lpass_quad_ws>;
+		pinctrl-2 = <&hs1_mi2s_data0_sleep>, <&mi2s_mclk_sleep>, <&hs0_mi2s_data0_sleep>,
+			    <&hs0_mi2s_sclk_sleep>, <&hs0_mi2s_data1_sleep>, <&hs0_mi2s_ws_sleep>,
+			    <&hs1_mi2s_sclk_sleep>, <&hs1_mi2s_data1_sleep>, <&hs1_mi2s_ws_sleep>,
+			    <&hs2_mi2s_data0_sleep>, <&hs2_mi2s_data1_sleep>, <&hs2_mi2s_sck_sleep>,
+			    <&hs2_mi2s_ws_sleep>, <&lpass_quad_clk_sleep>, <&lpass_quad_data_sleep>,
+			    <&lpass_quad_ws_sleep>;
+
+		hs0-mi2s-playback-dai-link {
+			link-name = "MI2S-LPAIF_SDR-RX-PRIMARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+			};
+
+			codec {
+				sound-dai = <&max98357a>;
+			};
+
+			platform {
+				sound-dai = <&q6apm>;
+			};
+		};
+
+		hs2-mi2s-capture-dai-link {
+			link-name = "MI2S-LPAIF_SDR-TX-TERTIARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai TERTIARY_MI2S_TX>;
+			};
+
+			codec {
+				sound-dai = <&dmic_codec>;
+			};
+
+			platform {
+				sound-dai = <&q6apm>;
+			};
+		};
+	};
+};
+
+&lpass_tlmm {
+	lpass_i2s1_data: i2s1-data-state {
+			pins = "gpio8", "gpio9";
+			function = "i2s1_data";
+			drive-strength = <8>;
+			bias-disable;
+	};
+
+	lpass_i2s1_data_sleep: i2s1-data-sleep-state {
+			pins = "gpio8", "gpio9";
+			function = "i2s1_data";
+			drive-strength = <2>;
+			bias-pull-down;
+			input-enable;
+	};
+
+	lpass_i2s1_ws: i2s1-ws-state {
+			pins = "gpio7";
+			function = "i2s1_ws";
+			drive-strength = <8>;
+			output-high;
+	};
+
+	lpass_i2s1_ws_sleep: i2s1-ws-sleep-state {
+			pins = "gpio7";
+			function = "i2s1_ws";
+			drive-strength = <2>;
+			bias-pull-down;
+			input-enable;
+	};
+
+	lpass_quad_clk_sleep: quad-clk-sleep-state {
+			pins = "gpio0";
+			function = "qua_mi2s_sclk";
+			drive-strength = <2>;
+			bias-pull-down;
+			input-enable;
+	};
+
+	lpass_quad_clk: quad-clk-state {
+			pins = "gpio0";
+			function = "qua_mi2s_sclk";
+			drive-strength = <8>;
+			bias-disable;
+			output-high;
+	};
+
+	lpass_quad_data_sleep: quad-data-sleep-state {
+			pins = "gpio2", "gpio3", "gpio4", "gpio5";
+			function = "qua_mi2s_data";
+			drive-strength = <2>;
+			bias-pull-down;
+			input-enable;
+	};
+
+	lpass_quad_data: quad-data-state {
+			pins = "gpio2", "gpio3", "gpio4", "gpio5";
+			function = "qua_mi2s_data";
+			drive-strength = <8>;
+			bias-disable;
+	};
+
+	lpass_quad_ws_sleep: quad-ws-sleep-state {
+			pins = "gpio1";
+			function = "qua_mi2s_ws";
+			drive-strength = <2>;
+			bias-pull-down;
+			input-enable;
+	};
+
+	lpass_quad_ws: quad-ws-state {
+			pins = "gpio1";
+			function = "qua_mi2s_ws";
+			drive-strength = <8>;
+			output-high;
+	};
+};
+
+&soc {
+	msm_stub_codec: msm-stub-codec {
+		compatible = "qcom,msm-stub-codec";
+		#sound-dai-cells = <1>;
+		status = "disabled";
+	};
+	max98357a: audio-codec-0 {
+		compatible = "maxim,max98357a";
+		#sound-dai-cells = <0>;
+	};
+
+	dmic_codec: dmic-codec {
+		compatible = "dmic-codec";
+		#sound-dai-cells = <0>;
+		num-channels = <1>;
+	};
+};
+
+&tlmm {
+	hs0_mi2s_data0_sleep: hs0-mi2s-data0-sleep-state {
+		pins = "gpio116";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs0_mi2s_data0: hs0-mi2s-data0-state {
+		pins = "gpio116";
+		function = "hs0_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	hs0_mi2s_data1_sleep: hs0-mi2s-data1-sleep-state {
+		pins = "gpio117";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs0_mi2s_data1: hs0-mi2s-data1-state {
+		pins = "gpio117";
+		function = "hs0_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	hs0_mi2s_sclk_sleep: hs0-mi2s-sclk-sleep-state {
+		pins = "gpio114";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs0_mi2s_sclk: hs0-mi2s-sclk-state {
+		pins = "gpio114";
+		function = "hs0_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	hs0_mi2s_ws_sleep: hs0-mi2s-ws-sleep-state {
+		pins = "gpio115";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs0_mi2s_ws: hs0-mi2s-ws-state {
+		pins = "gpio115";
+		function = "hs0_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	hs1_mi2s_data0: hs1-mi2s-data0-state {
+		pins = "gpio120";
+		function = "hs1_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	hs1_mi2s_data0_sleep: hs1-mi2s-data0-sleep-state {
+		pins = "gpio120";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs1_mi2s_data1: hs1-mi2s-data1-state {
+		pins = "gpio121";
+		function = "hs1_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	hs1_mi2s_data1_sleep: hs1-mi2s-data1-sleep-state {
+		pins = "gpio121";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs1_mi2s_sclk: hs1-mi2s-sclk-state {
+		pins = "gpio119";
+		function = "hs1_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	hs1_mi2s_sclk_sleep: hs1-mi2s-sclk-sleep-state {
+		pins = "gpio119";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs1_mi2s_ws: hs1-mi2s-ws-state {
+		pins = "gpio118";
+		function = "hs1_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	hs1_mi2s_ws_sleep: hs1-mi2s-ws-sleep-state {
+		pins = "gpio118";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs2_mi2s_data0: hs2-mi2s-data0-state {
+		pins = "gpio124";
+		function = "hs2_mi2s";
+		drive-strength = <8>;
+		input-enable;
+		bias-disable;
+	};
+
+	hs2_mi2s_data0_sleep: hs2-mi2s-data0-sleep-state {
+		pins = "gpio124";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs2_mi2s_data1: hs2-mi2s-data1-state {
+		pins = "gpio125";
+		function = "hs2_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	hs2_mi2s_data1_sleep: hs2-mi2s-data1-sleep-state {
+		pins = "gpio125";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs2_mi2s_sck: hs2-mi2s-sck-state {
+		pins = "gpio122";
+		function = "hs2_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	hs2_mi2s_sck_sleep: hs2-mi2s-sck-sleep-state {
+		pins = "gpio122";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs2_mi2s_ws: hs2-mi2s-ws-state {
+		pins = "gpio123";
+		function = "hs2_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	hs2_mi2s_ws_sleep: hs2-mi2s-ws-sleep-state {
+		pins = "gpio123";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s_mclk: mi2s-mclk-state {
+		pins = "gpio105";
+		function = "mi2s_mclk0";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	mi2s_mclk_sleep: mi2s-mclk-sleep-state {
+		pins = "gpio105";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9075-addons-ride-r3.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9075-addons-ride-r3.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+
+#include "qcs9075-ride-r3.dts"
+#include "sa8775p-addons-ride.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS9075 Addons Ride Rev3";
+	compatible = "qcom,qcs9075-addons-ride-r3", "qcom,qcs9075", "qcom,sa8775p";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9075-addons-ride.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9075-addons-ride.dts
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+
+#include "qcs9075-ride.dts"
+#include "sa8775p-addons-ride.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS9075 Addons Ride";
+	compatible = "qcom,qcs9075-addons-ride", "qcom,qcs9075", "qcom,sa8775p";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9075-camera-iq-9075-evk.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9075-camera-iq-9075-evk.dtsi
@@ -0,0 +1,2943 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <dt-bindings/msm-camera.h>
+
+&tlmm {
+	cci_i2c_sda0_active: cci_i2c_sda0_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio60";
+			function = "cci_i2c_sda0";
+		};
+
+		config {
+			pins = "gpio60";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda0_suspend: cci_i2c_sda0_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio60";
+			function = "cci_i2c_sda0";
+		};
+
+		config {
+			pins = "gpio60";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl0_active: cci_i2c_scl0_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio61";
+			function = "cci_i2c_scl0";
+		};
+
+		config {
+			pins = "gpio61";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl0_suspend: cci_i2c_scl0_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio61";
+			function = "cci_i2c_scl0";
+		};
+
+		config {
+			pins = "gpio61";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda1_active: cci_i2c_sda1_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio52";
+			function = "cci_i2c_sda1";
+		};
+
+		config {
+			pins = "gpio52";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda1_suspend: cci_i2c_sda1_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio52";
+			function = "cci_i2c_sda1";
+		};
+
+		config {
+			pins = "gpio52";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl1_active: cci_i2c_scl1_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio53";
+			function = "cci_i2c_scl1";
+		};
+
+		config {
+			pins = "gpio53";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl1_suspend: cci_i2c_scl1_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio53";
+			function = "cci_i2c_scl1";
+		};
+
+		config {
+			pins = "gpio53";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda2_active: cci_i2c_sda2_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio62";
+			function = "cci_i2c_sda2";
+		};
+
+		config {
+			pins = "gpio62";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda2_suspend: cci_i2c_sda2_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio62";
+			function = "cci_i2c_sda2";
+		};
+
+		config {
+			pins = "gpio62";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl2_active: cci_i2c_scl2_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio63";
+			function = "cci_i2c_scl2";
+		};
+
+		config {
+			pins = "gpio63";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl2_suspend: cci_i2c_scl2_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio63";
+			function = "cci_i2c_scl2";
+		};
+
+		config {
+			pins = "gpio63";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda3_active: cci_i2c_sda3_active {
+		mux {
+			pins = "gpio54";
+			function = "cci_i2c_sda3";
+		};
+
+		config {
+			pins = "gpio54";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda3_suspend: cci_i2c_sda3_suspend {
+		mux {
+			pins = "gpio54";
+			function = "cci_i2c_sda3";
+		};
+
+		config {
+			pins = "gpio54";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl3_active: cci_i2c_scl3_active {
+		mux {
+			pins = "gpio55";
+			function = "cci_i2c_scl3";
+		};
+
+		config {
+			pins = "gpio55";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl3_suspend: cci_i2c_scl3_suspend {
+		mux {
+			pins = "gpio55";
+			function = "cci_i2c_scl3";
+		};
+
+		config {
+			pins = "gpio55";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda4_active: cci_i2c_sda4_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio64";
+			function = "cci_i2c_sda4";
+		};
+
+		config {
+			pins = "gpio64";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda4_suspend: cci_i2c_sda4_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio64";
+			function = "cci_i2c_sda4";
+		};
+
+		config {
+			pins = "gpio64";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl4_active: cci_i2c_scl4_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio65";
+			function = "cci_i2c_scl4";
+		};
+
+		config {
+			pins = "gpio65";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl4_suspend: cci_i2c_scl4_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio65";
+			function = "cci_i2c_scl4";
+		};
+
+		config {
+			pins = "gpio65";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda5_active: cci_i2c_sda5_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio56";
+			function = "cci_i2c_sda5";
+		};
+
+		config {
+			pins = "gpio56";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda5_suspend: cci_i2c_sda5_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio56";
+			function = "cci_i2c_sda5";
+		};
+
+		config {
+			pins = "gpio56";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl5_active: cci_i2c_scl5_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio57";
+			function = "cci_i2c_scl5";
+		};
+
+		config {
+			pins = "gpio57";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl5_suspend: cci_i2c_scl5_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio57";
+			function = "cci_i2c_scl5";
+		};
+
+		config {
+			pins = "gpio57";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda6_active: cci_i2c_sda6_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio66";
+			function = "cci_i2c_sda6";
+		};
+
+		config {
+			pins = "gpio66";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda6_suspend: cci_i2c_sda6_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio66";
+			function = "cci_i2c_sda6";
+		};
+
+		config {
+			pins = "gpio66";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl6_active: cci_i2c_scl6_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio67";
+			function = "cci_i2c_scl6";
+		};
+
+		config {
+			pins = "gpio67";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl6_suspend: cci_i2c_scl6_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio67";
+			function = "cci_i2c_scl6";
+		};
+
+		config {
+			pins = "gpio67";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda7_active: cci_i2c_sda7_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio58";
+			function = "cci_i2c_sda7";
+		};
+
+		config {
+			pins = "gpio58";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda7_suspend: cci_i2c_sda7_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio58";
+			function = "cci_i2c_sda7";
+		};
+
+		config {
+			pins = "gpio58";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl7_active: cci_i2c_scl7_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio59";
+			function = "cci_i2c_scl7";
+		};
+
+		config {
+			pins = "gpio59";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl7_suspend: cci_i2c_scl7_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio59";
+			function = "cci_i2c_scl7";
+		};
+
+		config {
+			pins = "gpio59";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk0_active: cam_sensor_mclk0_active {
+		/* MCLK0 */
+		mux {
+			pins = "gpio72";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio72";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk0_suspend: cam_sensor_mclk0_suspend {
+		/* MCLK0 */
+		mux {
+			pins = "gpio72";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio72";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk1_active: cam_sensor_mclk1_active {
+		/* MCLK1 */
+		mux {
+			pins = "gpio73";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio73";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk1_suspend: cam_sensor_mclk1_suspend {
+		/* MCLK1 */
+		mux {
+			pins = "gpio73";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio73";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk2_active: cam_sensor_mclk2_active {
+		/* MCLK2 */
+		mux {
+			pins = "gpio74";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio74";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk2_suspend: cam_sensor_mclk2_suspend {
+		/* MCLK2 */
+		mux {
+			pins = "gpio74";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio74";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk3_active: cam_sensor_mclk3_active {
+		/* MCLK3 */
+		mux {
+			pins = "gpio75";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio75";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk3_suspend: cam_sensor_mclk3_suspend {
+		/* MCLK3 */
+		mux {
+			pins = "gpio75";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio75";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+	
+	cam_sensor_active_rst0: cam_sensor_active_rst0 {
+		/* RESET */
+		mux {
+			pins = "gpio132";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio132";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst0: cam_sensor_suspend_rst0 {
+		/* RESET */
+		mux {
+			pins = "gpio132";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio132";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_rst1: cam_sensor_active_rst1 {
+		/* RESET */
+		mux {
+			pins = "gpio133";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio133";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst1: cam_sensor_suspend_rst1 {
+		/* RESET */
+		mux {
+			pins = "gpio133";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio133";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_rst2: cam_sensor_active_rst2 {
+		/* RESET */
+		mux {
+			pins = "gpio134";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio134";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst2: cam_sensor_suspend_rst2 {
+		/* RESET */
+		mux {
+			pins = "gpio134";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio134";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+
+	cam_sensor_active_rst3: cam_sensor_active_rst3 {
+		/* RESET */
+		mux {
+			pins = "gpio135";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio135";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_suspend_rst3: cam_sensor_suspend_rst3 {
+		/* RESET */
+		mux {
+			pins = "gpio135";
+			function = "gpio";
+		};
+
+		config {
+			pins = "gpio135";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+			output-low;
+		};
+	};
+};
+
+&soc {
+	qcom,cam-req-mgr {
+		compatible = "qcom,cam-req-mgr";
+		status = "ok";
+	};
+
+	qcom,cam-sync {
+		compatible = "qcom,cam-sync";
+		status = "ok";
+	};
+
+	qcom,cam-i3c-id-table {
+		i3c-sensor-id-table = <0x1B0 0x0766>;
+		i3c-eeprom-id-table = <>;
+		i3c-actuator-id-table = <>;
+		i3c-ois-id-table = <>;
+		status = "disabled";
+	};
+
+	cam_csiphy_tpg17: qcom,tpg17@acac000 {
+		cell-index = <17>;
+		phy-id = <0>;
+		compatible = "qcom,cam-tpg1031";
+		reg-names = "tpg0", "cam_cpas_top";
+		reg = <0x0 0xacac000 0x0 0x400>,
+			<0x0 0xac11000 0x0 0x1000>;
+		reg-cam-base = <0xac000 0x11000>;
+		operating-points-v2 = <&csiphy_tpg0_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		interrupt-names = "tpg0";
+		interrupts = <GIC_SPI 545 IRQ_TYPE_EDGE_RISING>;
+		shared-clks = <1 0>;
+		clock-names =
+			"cphy_rx_clk_src",
+			"csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cphy_rx_clk_src";
+		status = "ok";
+		csiphy_tpg0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy_tpg18: qcom,tpg18@acad000 {
+		cell-index = <18>;
+		phy-id = <1>;
+		compatible = "qcom,cam-tpg1031";
+		reg-names = "tpg1", "cam_cpas_top";
+		reg = <0x0 0xacad000 0x0 0x400>,
+			<0x0 0xac11000 0x0 0x1000>;
+		reg-cam-base = <0xad000 0x11000>;
+		operating-points-v2 = <&csiphy_tpg1_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		interrupt-names = "tpg1";
+		interrupts = <GIC_SPI 546 IRQ_TYPE_EDGE_RISING>;
+		shared-clks = <1 0>;
+		clock-names =
+			"cphy_rx_clk_src",
+			"csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cphy_rx_clk_src";
+		status = "ok";
+		csiphy_tpg1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy_tpg19: qcom,tpg19@acae000 {
+		cell-index = <19>;
+		phy-id = <2>;
+		compatible = "qcom,cam-tpg1031";
+		reg-names = "tpg2", "cam_cpas_top";
+		reg = <0x0 0xacae000 0x0 0x400>,
+			<0x0 0xac11000 0x0 0x1000>;
+		reg-cam-base = <0xae000 0x11000>;
+		operating-points-v2 = <&csiphy_tpg2_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		interrupt-names = "tpg2";
+		interrupts = <GIC_SPI 547 IRQ_TYPE_EDGE_RISING>;
+		shared-clks = <1 0>;
+		clock-names =
+			"cphy_rx_clk_src",
+			"csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cphy_rx_clk_src";
+		status = "ok";
+		csiphy_tpg2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy0: qcom,csiphy0@ac9c000 {
+		cell-index = <0>;
+		aggregator-rx;
+		compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy";
+		reg = <0x0 0x0ac9c000 0x0 0x2000>;
+		reg-names = "csiphy";
+		operating-points-v2 = <&csiphy0_opp_table>;
+		reg-cam-base = <0x9c000>;
+		interrupt-names = "CSIPHY0";
+		interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>;
+		csi-vdd-1p2-supply = <&vreg_l1c>;
+		csi-vdd-0p9-supply = <&vreg_l4a>;
+		regulator-names = "csi-vdd-1p2", "csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1140000 831000>;
+		rgltr-max-voltage = <1260000 920000>;
+		rgltr-load-current = <8900 15900>;
+		shared-clks = <1 0 0 0>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy0_clk",
+			"csi0phytimer_clk_src",
+			"csi0phytimer_clk";
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY0_CLK>,
+			<&camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI0PHYTIMER_CLK>;
+		src-clock-name = "cphy_rx_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates =
+			<400000000 0 400000000 0>;
+		status = "ok";
+		csiphy0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy1: qcom,csiphy1@ac9e000 {
+		cell-index = <1>;
+		aggregator-rx;
+		compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy";
+		reg = <0x0 0xac9e000 0x0 0x2000>;
+		reg-names = "csiphy";
+		operating-points-v2 = <&csiphy1_opp_table>;
+		reg-cam-base = <0x9e000>;
+		interrupt-names = "CSIPHY1";
+		interrupts = <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>;
+		csi-vdd-1p2-supply = <&vreg_l1c>;
+		csi-vdd-0p9-supply = <&vreg_l4a>;
+		regulator-names = "csi-vdd-1p2", "csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1140000 831000>;
+		rgltr-max-voltage = <1260000 920000>;
+		rgltr-load-current = <8900 15900>;
+		shared-clks = <1 0 0 0>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy1_clk",
+			"csi1phytimer_clk_src",
+			"csi1phytimer_clk";
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY1_CLK>,
+			<&camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI1PHYTIMER_CLK>;
+		src-clock-name = "cphy_rx_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates =
+			<400000000 0 400000000 0>;
+		status = "ok";
+		csiphy1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy2: qcom,csiphy2@aca0000 {
+		cell-index = <2>;
+		aggregator-rx;
+		compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy";
+		reg = <0x0 0xaca0000 0x0 0x2000>;
+		reg-names = "csiphy";
+		operating-points-v2 = <&csiphy2_opp_table>;
+		reg-cam-base = <0xa0000>;
+		interrupt-names = "CSIPHY2";
+		interrupts = <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>;
+		csi-vdd-1p2-supply = <&vreg_l1c>;
+		csi-vdd-0p9-supply = <&vreg_l4a>;
+		regulator-names = "csi-vdd-1p2", "csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1140000 831000>;
+		rgltr-max-voltage = <1260000 920000>;
+		rgltr-load-current = <8900 15900>;
+		shared-clks = <1 0 0 0>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy2_clk",
+			"csi2phytimer_clk_src",
+			"csi2phytimer_clk";
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY2_CLK>,
+			<&camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI2PHYTIMER_CLK>;
+		src-clock-name = "cphy_rx_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates =
+			<400000000 0 400000000 0>;
+		status = "ok";
+		csiphy2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy3: qcom,csiphy3@aca2000 {
+		cell-index = <3>;
+		aggregator-rx;
+		compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy";
+		reg = <0x0 0xaca2000 0x0 0x2000>;
+		reg-names = "csiphy";
+		operating-points-v2 = <&csiphy3_opp_table>;
+		reg-cam-base = <0xa2000>;
+		interrupt-names = "CSIPHY3";
+		interrupts = <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>;
+		csi-vdd-1p2-supply = <&vreg_l1c>;
+		csi-vdd-0p9-supply = <&vreg_l4a>;
+		regulator-names = "csi-vdd-1p2", "csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1140000 831000>;
+		rgltr-max-voltage = <1260000 920000>;
+		rgltr-load-current = <8900 15900>;
+		shared-clks = <1 0 0 0>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy3_clk",
+			"csi3phytimer_clk_src",
+			"csi3phytimer_clk";
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY3_CLK>,
+			<&camcc CAM_CC_CSI3PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI3PHYTIMER_CLK>;
+		src-clock-name = "cphy_rx_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates =
+			<400000000 0 400000000 0>;
+		status = "ok";
+		csiphy3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_cci0: qcom,cci0@ac13000 {
+		cell-index = <0>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac13000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x13000>;
+		interrupt-names = "CCI0";
+		interrupts = <GIC_SPI 460 IRQ_TYPE_EDGE_RISING>;
+		operating-points-v2 = <&cci0_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cci_0_clk_src",
+			"cci_0_clk";
+		clocks = <&camcc CAM_CC_CCI_0_CLK_SRC>,
+			<&camcc CAM_CC_CCI_0_CLK>;
+		clock-rates = <37500000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cci_0_clk_src";
+		pctrl-idx-mapping = <CCI_MASTER_0 CCI_MASTER_1>;
+		pctrl-map-names = "m0", "m1";
+		pinctrl-names = "m0_active", "m0_suspend",
+			"m1_active", "m1_suspend";
+		pinctrl-0 = <&cci_i2c_scl0_active &cci_i2c_sda0_active>;
+		pinctrl-1 = <&cci_i2c_scl0_suspend &cci_i2c_sda0_suspend>;
+		pinctrl-2 = <&cci_i2c_scl1_active &cci_i2c_sda1_active>;
+		pinctrl-3 = <&cci_i2c_scl1_suspend &cci_i2c_sda1_suspend>;
+		status = "ok";
+		cci0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci0: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci0: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci0: qcom,i2c_custom_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci0: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	cam_cci1: qcom,cci1@ac14000 {
+		cell-index = <1>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac14000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x14000>;
+		interrupt-names = "CCI1";
+		interrupts = <GIC_SPI 271 IRQ_TYPE_EDGE_RISING>;
+		operating-points-v2 = <&cci1_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cci_1_clk_src",
+			"cci_1_clk";
+		clocks = <&camcc CAM_CC_CCI_1_CLK_SRC>,
+			<&camcc CAM_CC_CCI_1_CLK>;
+		clock-rates = <37500000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cci_1_clk_src";
+		pctrl-idx-mapping = <CCI_MASTER_0 CCI_MASTER_1>;
+		pctrl-map-names = "m0", "m1";
+		pinctrl-names = "m0_active", "m0_suspend",
+			"m1_active", "m1_suspend";
+		pinctrl-0 = <&cci_i2c_scl2_active &cci_i2c_sda2_active>;
+		pinctrl-1 = <&cci_i2c_scl2_suspend &cci_i2c_sda2_suspend>;
+		pinctrl-2 = <&cci_i2c_scl3_active &cci_i2c_sda3_active>;
+		pinctrl-3 = <&cci_i2c_scl3_suspend &cci_i2c_sda3_suspend>;
+		status = "ok";
+		cci1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci1: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci1: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci1: qcom,i2c_custom_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci1: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	cam_cci2: qcom,cci2@ac15000 {
+		cell-index = <2>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac15000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x15000>;
+		interrupt-names = "CCI2";
+		interrupts = <GIC_SPI 651 IRQ_TYPE_EDGE_RISING>;
+		operating-points-v2 = <&cci2_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cci_2_clk_src",
+			"cci_2_clk";
+		clocks = <&camcc CAM_CC_CCI_2_CLK_SRC>,
+			<&camcc CAM_CC_CCI_2_CLK>;
+		clock-rates = <37500000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cci_2_clk_src";
+		pctrl-idx-mapping = <CCI_MASTER_0 CCI_MASTER_1>;
+		pctrl-map-names = "m0", "m1";
+		pinctrl-names = "m0_active", "m0_suspend",
+			"m1_active", "m1_suspend";
+		pinctrl-0 = <&cci_i2c_scl4_active &cci_i2c_sda4_active>;
+		pinctrl-1 = <&cci_i2c_scl4_suspend &cci_i2c_sda4_suspend>;
+		pinctrl-2 = <&cci_i2c_scl5_active &cci_i2c_sda5_active>;
+		pinctrl-3 = <&cci_i2c_scl5_suspend &cci_i2c_sda5_suspend>;
+		status = "ok";
+		cci2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci2: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci2: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci2: qcom,i2c_custom_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci2: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	cam_cci3: qcom,cci3@ac16000 {
+		cell-index = <3>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac16000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x16000>;
+		interrupt-names = "CCI3";
+		interrupts = <GIC_SPI 771 IRQ_TYPE_EDGE_RISING>;
+		operating-points-v2 = <&cci3_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cci_3_clk_src",
+			"cci_3_clk";
+		clocks = <&camcc CAM_CC_CCI_3_CLK_SRC>,
+			<&camcc CAM_CC_CCI_3_CLK>;
+		clock-rates = <37500000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cci_3_clk_src";
+		pctrl-idx-mapping = <CCI_MASTER_0 CCI_MASTER_1>;
+		pctrl-map-names = "m0", "m1";
+		pinctrl-names = "m0_active", "m0_suspend",
+			"m1_active", "m1_suspend";
+		pinctrl-0 = <&cci_i2c_scl6_active &cci_i2c_sda6_active>;
+		pinctrl-1 = <&cci_i2c_scl6_suspend &cci_i2c_sda6_suspend>;
+		pinctrl-2 = <&cci_i2c_scl7_active &cci_i2c_sda7_active>;
+		pinctrl-3 = <&cci_i2c_scl7_suspend &cci_i2c_sda7_suspend>;
+		status = "ok";
+		cci3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci3: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci3: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci3: qcom,i2c_custom_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci3: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	qcom,cam_smmu {
+		compatible = "qcom,msm-cam-smmu", "simple-bus";
+		status = "ok";
+		force_cache_allocs;
+
+		msm_cam_smmu_ife {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x3400 0x0020>,
+				<&apps_smmu 0x3420 0x0020>;
+			cam-smmu-label = "ife", "sfe";
+			multiple-client-devices;
+			dma-coherent;
+			ife_iova_mem_map: iova-mem-map {
+				/* IO region is approximately 64 GB */
+				iova-mem-region-io {
+					iova-region-name = "io";
+					/* start address: 0x100000 */
+					/* leaving 1 MB pad at start  */
+					iova-region-start = <0x100000>;
+					/* Length: 0xfffe00000 */
+					/* leaving 1 MB pad at end */
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_icp {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus =
+				<&apps_smmu 0x0800 0x400>,
+				<&apps_smmu 0x0840 0x480>,
+				<&apps_smmu 0x08C0 0x480>,
+				<&apps_smmu 0x0C00 0x400>,
+				<&apps_smmu 0x0C40 0x480>,
+				<&apps_smmu 0x0CC0 0x480>;
+			cam-smmu-label = "icp";
+			qcom,iommu-faults = "stall-disable", "non-fatal";
+			dma-coherent;
+			icp_iova_mem_map: iova-mem-map {
+				iova-mem-region-shared {
+					/* Shared region is ~250MB long */
+					iova-region-name = "shared";
+					iova-region-start = <0x800000>;
+					iova-region-len = <0xfc00000>;
+					iova-region-id = <0x1>;
+					status = "ok";
+				};
+
+				iova-mem-region-fwuncached-region {
+					/* FW uncached region is 7MB long */
+					iova-region-name = "fw_uncached";
+					iova-region-start = <0x10400000>;
+					iova-region-len = <0x700000>;
+					iova-region-id = <0x6>;
+					subregion_support;
+					status = "ok";
+					/* Used for HFI queues/sec heap */
+					iova-mem-region-generic-region {
+						iova-region-name = "icp_hfi";
+						iova-region-start = <0x10400000>;
+						iova-region-len = <0x200000>;
+						iova-region-id = <0x0>;
+					};
+				};
+
+				iova-mem-region-io {
+					/* IO region is approximately 3.8 GB */
+					iova-region-name = "io";
+					iova-region-start = <0x10c00000>;
+					iova-region-len = <0xee300000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+
+				iova-mem-qdss-region {
+					/* QDSS region is appropriate 1MB */
+					iova-region-name = "qdss";
+					iova-region-start = <0x10b00000>;
+					iova-region-len = <0x100000>;
+					iova-region-id = <0x5>;
+					qdss-phy-addr = <0x16790000>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_cdm {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x0860 0x400>,
+				<&apps_smmu 0x0C60 0x400>;
+			cam-smmu-label = "rt-cdm";
+			dma-coherent;
+			multiple-client-devices;
+			rt_cdm_iova_mem_map: iova-mem-map {
+				iova-mem-region-io {
+					/* IO region is approximately 4.0 GB */
+					iova-region-name = "io";
+					/* 1 MB pad for start */
+					iova-region-start = <0x100000>;
+					/* 1 MB pad for end */
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_secure {
+			compatible = "qcom,msm-cam-smmu-cb";
+			cam-smmu-label = "cam-secure";
+			qcom,secure-cb;
+		};
+	};
+
+	qcom,cam-cdm-intf {
+		compatible = "qcom,cam-cdm-intf";
+		cell-index = <0>;
+		label = "cam-cdm-intf";
+		num-hw-cdm = <1>;
+		cdm-client-names = "vfe";
+		status = "ok";
+	};
+
+	qcom,rt-cdm0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac26000 0x0 0x1000>;
+		reg-names = "rt-cdm0";
+		reg-cam-base = <0x26000>;
+		interrupts = <GIC_SPI 543 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm0";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_fast_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_fast_ahb_clk_src";
+		clock-rates = <300000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table0>;
+		clock-cntl-level = "svs";
+		cdm-client-names = "ife0", "dualife0";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table0: opp-table {
+			compatible = "operating-points-v2";
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,rt-cdm1 {
+		cell-index = <1>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac27000 0x0 0x1000>;
+		reg-names = "rt-cdm1";
+		reg-cam-base = <0x27000>;
+		interrupts = <GIC_SPI 544 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm1";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_fast_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_fast_ahb_clk_src";
+		clock-rates = <300000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table1>;
+		clock-cntl-level = "svs_l1";
+		cdm-client-names = "ife1", "dualife1";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table1: opp-table {
+			compatible = "operating-points-v2";
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,rt-cdm2 {
+		cell-index = <2>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac28000 0x0 0x1000>;
+		reg-names = "rt-cdm2";
+		reg-cam-base = <0x28000>;
+		interrupts = <GIC_SPI 567 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm2";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_slow_ahb_clk_src";
+		clock-rates = <80000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table2>;
+		clock-cntl-level = "svs_l1";
+		cdm-client-names = "ife2", "ife3", "ife4", "ife5", "ife6";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table2: opp-table {
+			compatible = "operating-points-v2";
+			opp-80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,rt-cdm3 {
+		cell-index = <3>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac29000 0x0 0x1000>;
+		reg-names = "rt-cdm3";
+		reg-cam-base = <0x29000>;
+		interrupts = <GIC_SPI 566 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm3";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_slow_ahb_clk_src";
+		clock-rates = <80000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table3>;
+		clock-cntl-level = "svs";
+		cdm-client-names = "ife2", "ife3", "ife4", "ife5", "ife6";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table3: opp-table {
+			compatible = "operating-points-v2";
+			opp-80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,cam-isp {
+		compatible = "qcom,cam-isp";
+		arch-compat = "ife";
+		status = "ok";
+	};
+
+	cam_csid0: qcom,csid0 {
+		cell-index = <0>;
+		compatible = "qcom,csid690";
+		reg-names = "csid0", "csid_top";
+		reg = <0x0 0xac7a000 0x0 0xf01>,
+			<0x0 0xac78000 0x0 0x1000>;
+		reg-cam-base = <0x7a000 0x78000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "csid0";
+		interrupts = <GIC_SPI 565 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_csid_clk_src",
+			"cam_cc_csid_clk",
+			"cam_cc_csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CSID_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CLK>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0 0>;
+		clock-cntl-level = "svs_l1";
+		src-clock-name = "cam_cc_csid_clk_src";
+		operating-points-v2 = <&csid0_opp_table>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+		};
+	};
+
+	cam_vfe0: qcom,ife0 {
+		cell-index = <0>;
+		compatible = "qcom,vfe690";
+		reg-names = "ife0", "cam_camnoc";
+		reg = <0x0 0xac4d000 0x0 0xd000>,
+			<0x0 0xac1a000 0x0 0x9400>;
+		reg-cam-base = <0x4d000 0x1a000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "ife0";
+		interrupts = <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_0_clk",
+			"cam_cc_ife_0_clk",
+			"cam_cc_ife_0_clk_src",
+			"cam_cc_ife_0_fast_ahb_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_0_CLK>,
+			<&camcc CAM_CC_IFE_0_CLK>,
+			<&camcc CAM_CC_IFE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_0_FAST_AHB_CLK>;
+		clock-rates =
+			<0 0 480000000 0>,
+			<0 0 600000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_0_clk_src";
+		operating-points-v2 = <&vfe0_opp_table>;
+		clock-control-debugfs = "true";
+		ubwc-static-cfg = <0x1026 0x1036>;
+		cam_hw_pid = <8 16>;
+		status = "ok";
+		vfe0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid1: qcom,csid1 {
+		cell-index = <1>;
+		compatible = "qcom,csid690";
+		reg-names = "csid1", "csid_top";
+		reg = <0x0 0xac7c000 0x0 0xf01>,
+			<0x0 0xac78000 0x0 0x1000>;
+		reg-cam-base = <0x7c000 0x78000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "csid0";
+		interrupts = <GIC_SPI 564 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_csid_clk_src",
+			"cam_cc_csid_clk",
+			"cam_cc_csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CSID_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CLK>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0 0>;
+		clock-cntl-level = "svs_l1";
+		src-clock-name = "cam_cc_csid_clk_src";
+		operating-points-v2 = <&csid1_opp_table>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+		};
+	};
+
+	cam_vfe1: qcom,ife1 {
+		cell-index = <1>;
+		compatible = "qcom,vfe690";
+		reg-names = "ife1", "cam_camnoc";
+		reg = <0x0 0xac5a000 0x0 0xd000>,
+			<0x0 0xac1a000 0x0 0x9400>;
+		reg-cam-base = <0x5a000 0x1a000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "ife1";
+		interrupts = <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_1_clk",
+			"cam_cc_ife_1_clk",
+			"cam_cc_ife_1_clk_src",
+			"cam_cc_ife_1_fast_ahb_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_1_CLK>,
+			<&camcc CAM_CC_IFE_1_CLK>,
+			<&camcc CAM_CC_IFE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_1_FAST_AHB_CLK>;
+		clock-rates =
+			<0 0 480000000 0>,
+			<0 0 600000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_1_clk_src";
+		operating-points-v2 = <&vfe1_opp_table>;
+		clock-control-debugfs = "true";
+		ubwc-static-cfg = <0x1026 0x1036>;
+		cam_hw_pid = <9 17>;
+		status = "ok";
+		vfe1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite0: qcom,csid-lite0 {
+		cell-index = <2>;
+		compatible = "qcom,csid-lite690";
+		reg-names = "csid-lite0";
+		reg = <0x0 0xac84000 0x0 0xf01>;
+		reg-cam-base = <0x84000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite0";
+		interrupts = <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite0_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite0: qcom,ife-lite0 {
+		cell-index = <2>;
+		compatible = "qcom,vfe-lite690";
+		reg-names = "ife-lite0";
+		reg = <0x0 0xac84000 0x0 0x1d00>;
+		reg-cam-base = <0x84000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite0";
+		interrupts = <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite0_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite1: qcom,csid-lite1 {
+		cell-index = <3>;
+		compatible = "qcom,csid-lite690";
+		reg-names = "csid-lite1";
+		reg = <0x0 0xac88000 0x0 0xf01>;
+		reg-cam-base = <0x88000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite1";
+		interrupts = <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite1_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite1: qcom,ife-lite1 {
+		cell-index = <3>;
+		compatible = "qcom,vfe-lite690";
+		reg-names = "ife-lite1";
+		reg = <0x0 0xac88000 0x0 0x1d00>;
+		reg-cam-base = <0x88000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite1";
+		interrupts = <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite1_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite2: qcom,csid-lite2 {
+		cell-index = <4>;
+		compatible = "qcom,csid-lite690";
+		reg-names = "csid-lite2";
+		reg = <0x0 0xac8c000 0x0 0xf01>;
+		reg-cam-base = <0x8c000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite2";
+		interrupts = <GIC_SPI 759 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite2_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite2: qcom,ife-lite2 {
+		cell-index = <4>;
+		compatible = "qcom,vfe-lite690";
+		reg-names = "ife-lite2";
+		reg = <0x0 0xac8c000 0x0 0x1d00>;
+		reg-cam-base = <0x8c000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite2";
+		interrupts = <GIC_SPI 761 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite2_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite3: qcom,csid-lite3 {
+		cell-index = <5>;
+		compatible = "qcom,csid-lite690";
+		reg-names = "csid-lite3";
+		reg = <0x0 0xac90000 0x0 0xf01>;
+		reg-cam-base = <0x90000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite3";
+		interrupts = <GIC_SPI 758 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite3_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite3: qcom,ife-lite3 {
+		cell-index = <5>;
+		compatible = "qcom,vfe-lite690";
+		reg-names = "ife-lite3";
+		reg = <0x0 0xac90000 0x0 0x1d00>;
+		reg-cam-base = <0x90000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite3";
+		interrupts = <GIC_SPI 760 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite3_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite4: qcom,csid-lite4 {
+		cell-index = <6>;
+		compatible = "qcom,csid-lite690";
+		reg-names = "csid-lite4";
+		reg = <0x0 0xac94000 0x0 0xf01>;
+		reg-cam-base = <0x94000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite4";
+		interrupts = <GIC_SPI 604 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite4_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite4_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite4: qcom,ife-lite4 {
+		cell-index = <6>;
+		compatible = "qcom,vfe-lite690";
+		reg-names = "ife-lite4";
+		reg = <0x0 0xac94000 0x0 0x1d00>;
+		reg-cam-base = <0x94000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite4";
+		interrupts = <GIC_SPI 605 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite4_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite4_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_sfe_lite0: qcom,sfe-lite0 {
+		cell-index = <0>;
+		compatible = "qcom,sfe-lite690";
+		reg-names = "sfe-lite0";
+		reg = <0x0 0xac74000 0x0 0x1000>;
+		reg-cam-base = <0x74000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "sfe-lite0";
+		interrupts = <GIC_SPI 563 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_sfe_lite_0_fast_ahb_clk",
+			"cam_cc_sfe_lite_0_clk",
+			"cam_cc_cpas_sfe_lite_0_clk";
+		clocks =
+			<&camcc CAM_CC_SFE_LITE_0_FAST_AHB_CLK>,
+			<&camcc CAM_CC_SFE_LITE_0_CLK>,
+			<&camcc CAM_CC_CPAS_SFE_LITE_0_CLK>;
+		clock-rates =
+			<0 480000000 300000000>,
+			<0 600000000 400000000>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_sfe_lite_0_clk";
+		operating-points-v2 = <&cam_sfe_lite_opp_table0>;
+		cam_hw_pid = <4>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		cam_sfe_lite_opp_table0: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_sfe_lite1: qcom,sfe-lite1 {
+		cell-index = <1>;
+		compatible = "qcom,sfe-lite690";
+		reg-names = "sfe-lite1";
+		reg = <0x0 0xac75000 0x0 0x1000>;
+		reg-cam-base = <0x75000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "sfe-lite1";
+		interrupts = <GIC_SPI 562 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_sfe_lite_1_fast_ahb_clk",
+			"cam_cc_sfe_lite_1_clk",
+			"cam_cc_cpas_sfe_1_clk";
+		clocks =
+			<&camcc CAM_CC_SFE_LITE_1_FAST_AHB_CLK>,
+			<&camcc CAM_CC_SFE_LITE_1_CLK>,
+			<&camcc CAM_CC_CPAS_SFE_LITE_1_CLK>;
+		clock-rates =
+			<0 480000000 300000000>,
+			<0 600000000 400000000>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_sfe_lite_1_clk";
+		operating-points-v2 = <&cam_sfe_lite_opp_table1>;
+		cam_hw_pid = <5>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		cam_sfe_lite_opp_table1: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-icp {
+		compatible = "qcom,cam-icp";
+		compat-hw-name = "qcom,icp",
+			"qcom,ipe0";
+		num-icp = <1>;
+		num-ipe = <1>;
+		icp_use_pil;
+		status = "ok";
+	};
+
+	cam_icp: qcom,icp {
+		cell-index = <0>;
+		compatible = "qcom,cam-icp_v3_0";
+		icp-version = <0x0300>;
+
+		reg-names ="icp_csr", "icp_cirq", "icp_wd0";
+		reg = <0x0 0xac01000 0x0 0x400>,
+			<0x0 0xac01800 0x0 0x400>,
+			<0x0 0xac04000 0x0 0x1000>;
+		reg-cam-base = <0x1000 0x1800 0x4000>;
+		interrupt-names = "icp";
+		interrupts = <GIC_SPI 463 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		memory-region = <&pil_camera_mem>;
+		clock-names =
+			"cam_cc_soc_fast_ahb_clk_src",
+			"cam_cc_icp_ahb_clk",
+			"cam_cc_icp_clk_src",
+			"cam_cc_icp_clk";
+		src-clock-name = "cam_cc_icp_clk_src";
+		clocks =
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_ICP_AHB_CLK>,
+			<&camcc CAM_CC_ICP_CLK_SRC>,
+			<&camcc CAM_CC_ICP_CLK>;
+		clock-rates =
+			<300000000 0 480000000 0>,
+			<400000000 0 600000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		nrt-device;
+		fw_name = "CAMERA_ICP";
+		ubwc-ipe-fetch-cfg = <0x707b 0x7083>;
+		ubwc-ipe-write-cfg = <0x161ef 0x1620f>;
+		qos-val = <0xa0a>;
+		operating-points-v2 = <&icp_opp_table>;
+		cam_hw_pid = <12>;
+		status = "ok";
+		icp_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_ipe0: qcom,ipe0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-ipe";
+		reg-names = "ipe0_top";
+		reg = <0x0 0xac2d000 0x0 0x18000>;
+		reg-cam-base = <0x2d000>;
+
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+
+		clock-names =
+			"cam_cc_cpas_ipe_clk",
+			"cam_cc_ipe_ahb_clk",
+			"cam_cc_ipe_clk",
+			"cam_cc_ipe_clk_src",
+			"cam_cc_ipe_fast_ahb_clk",
+			"cam_cc_fast_ahb_clk_src";
+		src-clock-name = "cam_cc_ipe_clk_src";
+		clocks =
+			<&camcc CAM_CC_CPAS_IPE_CLK>,
+			<&camcc CAM_CC_IPE_AHB_CLK>,
+			<&camcc CAM_CC_IPE_CLK>,
+			<&camcc CAM_CC_IPE_CLK_SRC>,
+			<&camcc CAM_CC_IPE_FAST_AHB_CLK>,
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>;
+		clock-rates =
+			<0 0 0 480000000 0 300000000>,
+			<0 0 0 600000000 0 400000000>;
+		clock-cntl-level = "svs_l1", "nominal";
+
+		operating-points-v2 = <&ipe0_opp_table>;
+		nrt-device;
+		cam_hw_pid = <14 15>;
+		status = "ok";
+
+		ipe0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+
+	};
+
+	qcom,cam-cpas {
+		cell-index = <0>;
+		compatible = "qcom,cam-cpas";
+		label = "cpas";
+		arch-compat = "cpas_top";
+		reg-names = "cam_cpas_top", "cam_camnoc", "cam_rpmh";
+		reg = <0x0 0xac11000 0x0 0x1000>,
+			<0x0 0xac1A000 0x0 0x9400>,
+			<0x0 0xbbf0000 0x0 0x1f00>;
+		reg-cam-base = <0x11000 0x1A000 0x0bbf0000>;
+		interrupt-names = "cpas_camnoc";
+		interrupts = <GIC_SPI 459 IRQ_TYPE_EDGE_RISING>;
+		camnoc-axi-min-ib-bw = <3000000000>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"gcc_camera_ahb_clk",
+			"gcc_camera_hf_axi_clk",
+			"gcc_camera_sf_axi_clk",
+			"cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk",
+			"cam_cc_core_ahb_clk",
+			"cam_cc_fast_ahb_clk_src",
+			"cam_cc_cpas_fast_ahb_clk",
+			"cam_cc_camnoc_axi_clk_src",
+			"cam_cc_camnoc_axi_clk",
+			"cam_cc_qdss_debug_xo_clk";
+		clocks =
+			<&gcc GCC_CAMERA_AHB_CLK>,
+			<&gcc GCC_CAMERA_HF_AXI_CLK>,
+			<&gcc GCC_CAMERA_SF_AXI_CLK>,
+			<&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>,
+			<&camcc CAM_CC_CORE_AHB_CLK>,
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_FAST_AHB_CLK>,
+			<&camcc CAM_CC_CAMNOC_AXI_CLK_SRC>,
+			<&camcc CAM_CC_CAMNOC_AXI_CLK>,
+			<&camcc CAM_CC_QDSS_DEBUG_XO_CLK>;
+		src-clock-name = "cam_cc_fast_ahb_clk_src";
+		clock-rates =
+			<0 0 0 0 0 0 0 0 0 0 0>,
+			<0 0 0 80000000 0 0 300000000 0 400000000 0 0>,
+			<0 0 0 80000000 0 0 400000000 0 400000000 0 0>;
+		clock-cntl-level = "suspend", "svs_l1", "nominal";
+		clock-names-option = "cam_icp_clk";
+		clocks-option = <&camcc CAM_CC_ICP_CLK>;
+		clock-rates-option = <480000000>;
+		operating-points-v2 = <&cpas_opp_table>;
+		control-camnoc-axi-clk;
+		camnoc-bus-width = <32>;
+		camnoc-axi-clk-bw-margin-perc = <20>;
+		cam-icc-path-names = "cam_ahb";
+		interconnect-names = "cam_ahb", "cam_hf_0", "cam_sf_0", "cam_sf_icp";
+		interconnects =<&gem_noc MASTER_APPSS_PROC 0
+			&config_noc SLAVE_CAMERA_CFG 0>,
+				<&mmss_noc MASTER_CAMNOC_HF 0
+			&mc_virt SLAVE_EBI1 0>,
+				<&mmss_noc MASTER_CAMNOC_SF 0
+			&mc_virt SLAVE_EBI1 0>,
+				<&mmss_noc MASTER_CAMNOC_ICP 0
+			&mc_virt SLAVE_EBI1 0>;
+		cam-ahb-num-cases = <7>;
+		cam-ahb-bw-KBps =
+			<0 0>, <0 76800>, <0 150000>, <0 150000>,
+			<0 300000>, <0 300000>, <0 300000>;
+		vdd-corners = <RPMH_REGULATOR_LEVEL_RETENTION
+			RPMH_REGULATOR_LEVEL_MIN_SVS
+			RPMH_REGULATOR_LEVEL_LOW_SVS
+			RPMH_REGULATOR_LEVEL_SVS
+			RPMH_REGULATOR_LEVEL_SVS_L1
+			RPMH_REGULATOR_LEVEL_NOM
+			RPMH_REGULATOR_LEVEL_NOM_L1
+			RPMH_REGULATOR_LEVEL_NOM_L2
+			RPMH_REGULATOR_LEVEL_TURBO
+			RPMH_REGULATOR_LEVEL_TURBO_L1>;
+		vdd-corner-ahb-mapping = "suspend",
+			"lowsvs", "lowsvs", "svs", "svs_l1",
+			"nominal", "nominal", "nominal",
+			"turbo", "turbo";
+		client-id-based;
+		client-names =
+			"csiphy0", "csiphy1", "csiphy2", "csiphy3",
+			"cci0", "cci1", "cci2", "cci3","csid0", "csid1",
+			"csid2", "csid3", "csid4", "csid5", "csid6",
+			"ife0", "ife1",	"ife2", "ife3", "ife4",
+			"ife5",	"ife6", "ipe0", "sfe0", "sfe1",
+			"cam-cdm-intf0", "rt-cdm0", "rt-cdm1", "rt-cdm2",
+			"rt-cdm3", "icp0", "tpg17", "tpg18", "tpg19";
+
+		status = "ok";
+		enable-secure-qos-update;
+		cpas_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+
+		camera-bus-nodes {
+			level3-nodes {
+				level-index = <3>;
+				level3_rt_rd_wr_sum: level3-rt-rd-wr-sum {
+					cell-index = <0>;
+					node-name = "level3-rt-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					ib-bw-voting-needed;
+					qcom,axi-port-mnoc {
+						cam-icc-path-names = "cam_hf_0";
+					};
+				};
+
+				level3_nrt0_rd_wr_sum: level3-nrt0-rd-wr-sum {
+					cell-index = <1>;
+					node-name = "level3-nrt0-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					qcom,axi-port-mnoc {
+						cam-icc-path-names = "cam_sf_0";
+					};
+				};
+
+				level3_nrt1_rd_wr_sum: level3-nrt1-rd-wr-sum {
+					cell-index = <2>;
+					node-name = "level3-nrt1-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					qcom,axi-port-mnoc {
+						cam-icc-path-names = "cam_sf_icp";
+					};
+				};
+			};
+
+			level2-nodes {
+				level-index = <2>;
+				camnoc-max-needed;
+				level2_rt_wr0: level2-rt-wr0 {
+					cell-index = <3>;
+					node-name = "level2-rt-wr0";
+					parent-node = <&level3_rt_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_rt_wr1: level2-rt-wr1 {
+					cell-index = <4>;
+					node-name = "level2-rt-wr1";
+					parent-node = <&level3_rt_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt_wr2: level2-nrt-wr2 {
+					cell-index = <5>;
+					node-name = "level2-nrt-wr2";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_rt_rd0: level2-rt-read0 {
+					cell-index = <6>;
+					node-name = "level2-rt-rd0";
+					parent-node = <&level3_rt_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt_rd1: level2-nrt-rd1 {
+					cell-index = <7>;
+					node-name = "level2-nrt-rd1";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt_rd2: level2-nrt-rd2 {
+					cell-index = <8>;
+					node-name = "level2-nrt-rd2";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_icp_rd: level2-icp-rd {
+					cell-index = <9>;
+					node-name = "level2-icp-rd";
+					parent-node = <&level3_nrt1_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+			};
+
+			level1-nodes {
+				level-index = <1>;
+				camnoc-max-needed;
+				level1_rt_wr0: level1-rt-wr0 {
+					cell-index = <10>;
+					node-name = "level1-rt-wr0";
+					parent-node = <&level2_rt_wr0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_rt_wr1: level1-rt-wr1 {
+					cell-index = <11>;
+					node-name = "level1-rt-wr1";
+					parent-node = <&level2_rt_wr1>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_rt_rd0: level1-rt-read0 {
+					cell-index = <13>;
+					node-name = "level1-rt-rd0";
+					parent-node = <&level2_rt_rd0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt_rd2: level1-nrt-rd2 {
+					cell-index = <15>;
+					node-name = "level1-nrt-rd2";
+					parent-node = <&level2_nrt_rd2>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+			};
+
+			level0-nodes {
+				level-index = <0>;
+				ife_0_wr_0: ife-0-wr-0 {
+					cell-index = <16>;
+					node-name = "ife-0-wr-0";
+					client-name = "ife0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_1_wr_0: ife-1-wr-0 {
+					cell-index = <17>;
+					node-name = "ife-1-wr-0";
+					client-name = "ife1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_0_wr_0: ife-lite-0-wr-0 {
+					cell-index = <18>;
+					node-name = "ife-lite-0-wr-0";
+					client-name = "ife2";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_1_wr_0: ife-lite-1-wr-0 {
+					cell-index = <19>;
+					node-name = "ife-lite-1-wr-0";
+					client-name = "ife3";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_2_wr_0: ife-lite-2-wr-0 {
+					cell-index = <20>;
+					node-name = "ife-lite-2-wr-0";
+					client-name = "ife4";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_3_wr_0: ife-lite-3-wr-0 {
+					cell-index = <21>;
+					node-name = "ife-lite-3-wr-0";
+					client-name = "ife5";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_4_wr_0: ife-lite-4-wr-0 {
+					cell-index = <22>;
+					node-name = "ife-lite-4-wr-0";
+					client-name = "ife6";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_0_wr_1: ife-0-wr-1 {
+					cell-index = <23>;
+					node-name = "ife-0-wr-1";
+					client-name = "ife0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_UBWC>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_DISP>;
+					parent-node = <&level1_rt_wr1>;
+				};
+				ife_1_wr_1: ife-1-wr-1 {
+					cell-index = <24>;
+					node-name = "ife-1-wr-1";
+					client-name = "ife1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_UBWC>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_DISP>;
+					parent-node = <&level1_rt_wr1>;
+				};
+				sfe_0_rd_0: sfe-0-rd-0 {
+					cell-index = <25>;
+					node-name = "sfe-0-rd-0";
+					client-name = "sfe0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_SFE_NRDI>;
+					parent-node = <&level1_rt_rd0>;
+				};
+				sfe_1_rd_0: sfe-1-rd-0 {
+					cell-index = <26>;
+					node-name = "sfe-1-rd-0";
+					client-name = "sfe1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_SFE_NRDI>;
+					parent-node = <&level1_rt_rd0>;
+				};
+				ipe_0_wr_2: ipe-0-wr-2 {
+					cell-index = <27>;
+					node-name = "ipe-0-wr-2";
+					client-name = "ipe0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IPE_WR_VID
+					CAM_CPAS_PATH_DATA_IPE_WR_DISP
+					CAM_CPAS_PATH_DATA_IPE_WR_REF
+					CAM_CPAS_PATH_DATA_IPE_WR_APP>;
+					parent-node = <&level2_nrt_wr2>;
+				};
+				ipe_0_rd_all: ipe-0-rd-all {
+					cell-index = <28>;
+					node-name = "ipe-0-rd-all";
+					client-name = "ipe0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IPE_RD_IN
+					CAM_CPAS_PATH_DATA_IPE_RD_REF>;
+					parent-node = <&level2_nrt_rd1>;
+				};
+				rt_cdm0_all_rd_2: rt-cdm0-all-rd-2 {
+					cell-index = <29>;
+					node-name = "rt-cdm0-all-rd-2";
+					client-name = "rt-cdm0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				rt_cdm1_all_rd_2: rt-cdm1-all-rd-2 {
+					cell-index = <30>;
+					node-name = "rt-cdm1-all-rd-2";
+					client-name = "rt-cdm1";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				rt_cdm2_all_rd_2: rt-cdm2-all-rd-2 {
+					cell-index = <31>;
+					node-name = "rt-cdm2-all-rd-2";
+					client-name = "rt-cdm2";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				rt_cdm3_all_rd_2: rt-cdm3-all-rd-2 {
+					cell-index = <32>;
+					node-name = "rt-cdm3-all-rd-2";
+					client-name = "rt-cdm3";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				ipe_cdm0_all_rd: ipe-cdm0-all-rd {
+					cell-index = <33>;
+					node-name = "ipe-cdm0-all-rd";
+					client-name = "ipe0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				icp_all_rd: icp-all-rd {
+					cell-index = <34>;
+					node-name = "icp-all-rd";
+					client-name = "icp0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level2_icp_rd>;
+				};
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9075-camera-iq-9075-evk.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9075-camera-iq-9075-evk.dtso
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,sa8775p-gcc.h>
+#include <dt-bindings/clock/qcom,sa8775p-camcc.h>
+#include <dt-bindings/interconnect/qcom,sa8775p-rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+
+#include "qcs9075-camera-iq-9075-evk.dtsi"
+#include "qcs9075-camera-sensor-iq-9075-evk.dtsi"
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9075-camera-sensor-iq-9075-evk.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9075-camera-sensor-iq-9075-evk.dtsi
@@ -0,0 +1,1097 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <dt-bindings/msm-camera.h>
+
+&soc {
+	qcom,cam-res-mgr {
+		compatible = "qcom,cam-res-mgr";
+		status = "ok";
+		gpios-shared = <518 519 520 521>;
+	};
+};
+
+&cam_cci0 {
+
+	/* GMSL deserializer 0 */
+	qcom,cam-gmsl-deserializer0 {
+		cell-index = <0>;
+		csiphy-sd-index = <0>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_active>;
+		pinctrl-1 = <&cam_sensor_mclk0_suspend>;
+		gpios = <&pmm8654au_0_gpios 7 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_RESET0";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+
+		port@0 {
+			reg = <0>;
+			deser0_port0: endpoint {
+				remote-endpoint = <&gmsl_sensor0_ep>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			deser0_port1: endpoint {
+				remote-endpoint = <&gmsl_sensor1_ep>;
+			};
+		};
+
+		port@2 {
+			reg = <0>;
+			deser0_port2: endpoint {
+				remote-endpoint = <&gmsl_sensor2_ep>;
+			};
+		};
+
+		port@3 {
+			reg = <1>;
+			deser0_port3: endpoint {
+				remote-endpoint = <&gmsl_sensor3_ep>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 0 */
+	qcom,cam-gmsl-sensor0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor0_ep: endpoint {
+				remote-endpoint = <&deser0_port0>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 1 */
+	qcom,cam-gmsl-sensor1 {
+		cell-index = <1>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor1_ep: endpoint {
+				remote-endpoint = <&deser0_port1>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 2 */
+	qcom,cam-gmsl-sensor2 {
+		cell-index = <2>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor2_ep: endpoint {
+				remote-endpoint = <&deser0_port2>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 3 */
+	qcom,cam-gmsl-sensor3 {
+		cell-index = <3>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor3_ep: endpoint {
+				remote-endpoint = <&deser0_port3>;
+			};
+		};
+	};
+
+	/*cam0a-ov9282*/
+	qcom,cam-sensor1 {
+		cell-index = <20>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <0>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_active
+		                &cam_sensor_active_rst0>;
+		pinctrl-1 = <&cam_sensor_mclk0_suspend
+		                &cam_sensor_suspend_rst0>;
+		gpios = <&tlmm 72 0>,
+			<&tlmm 132 0>,
+			<&pmm8654au_0_gpios 7 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags   	 = <1 0 0>;
+		gpio-req-tbl-label = "CAM_MCLK0",
+		                       "CAMIF_RESET0",
+		                         "CAM_CUSTOM1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+	};
+
+    eeprom_cam24: qcom,eeprom24 {
+		cell-index = <24>;
+		compatible = "qcom,eeprom";
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_active
+		                &cam_sensor_active_rst0>;
+		pinctrl-1 = <&cam_sensor_mclk0_suspend
+		                &cam_sensor_suspend_rst0>;
+		gpios = <&tlmm 72 0>,
+			<&tlmm 132 0>,
+			<&pmm8654au_0_gpios 7 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags   	 = <1 0 0>;
+		gpio-req-tbl-label = "CAM_MCLK0",
+		                       "CAMIF_RESET0",
+		                         "CAM_CUSTOM1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+	};
+
+	/*cam24-ov13858*/
+	qcom,cam-sensor24 {
+		cell-index = <24>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <0>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		eeprom-src = <&eeprom_cam24>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_active
+		                &cam_sensor_active_rst0>;
+		pinctrl-1 = <&cam_sensor_mclk0_suspend
+		                &cam_sensor_suspend_rst0>;
+		gpios = <&tlmm 72 0>,
+			<&tlmm 132 0>,
+			<&pmm8654au_0_gpios 7 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags   	 = <1 0 0>;
+		gpio-req-tbl-label = "CAM_MCLK0",
+		                       "CAMIF_RESET0",
+		                         "CAM_CUSTOM1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+	};
+
+	eeprom_cam27: qcom,eeprom27 {
+		cell-index = <27>;
+		compatible = "qcom,eeprom";
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-0 = <&cam_sensor_mclk0_active
+		                &cam_sensor_active_rst0>;
+		pinctrl-1 = <&cam_sensor_mclk0_suspend
+		                &cam_sensor_suspend_rst0>;
+		gpios = <&tlmm 72 0>,
+			<&tlmm 132 0>,
+			<&pmm8654au_0_gpios 7 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags   	 = <1 0 0>;
+		gpio-req-tbl-label = "CAM_MCLK0",
+		                       "CAMIF_RESET0",
+		                         "CAM_CUSTOM1";
+		sensor-mode = <0>;
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/*cam0-cmk_imx577*/
+	qcom,cam-sensor27 {
+		cell-index = <27>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <0>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		eeprom-src = <&eeprom_cam27>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_active
+		                &cam_sensor_active_rst0>;
+		pinctrl-1 = <&cam_sensor_mclk0_suspend
+		                &cam_sensor_suspend_rst0>;
+		gpios = <&tlmm 72 0>,
+			<&tlmm 132 0>,
+			<&pmm8654au_0_gpios 7 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags   	 = <1 0 0>;
+		gpio-req-tbl-label = "CAM_MCLK0",
+		                       "CAMIF_RESET0",
+		                         "CAM_CUSTOM1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+	};
+
+};
+
+&cam_cci1 {
+
+	/* GMSL deserializer 1 */
+	qcom,cam-gmsl-deserializer1 {
+		cell-index = <1>;
+		csiphy-sd-index = <1>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend>;
+		gpios = <&pmm8654au_0_gpios 8 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_RESET1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+
+		port@0 {
+			reg = <0>;
+			deser1_port0: endpoint {
+				remote-endpoint = <&gmsl_sensor4_ep>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			deser1_port1: endpoint {
+				remote-endpoint = <&gmsl_sensor5_ep>;
+			};
+		};
+
+		port@2 {
+			reg = <0>;
+			deser1_port2: endpoint {
+				remote-endpoint = <&gmsl_sensor6_ep>;
+			};
+		};
+
+		port@3 {
+			reg = <1>;
+			deser1_port3: endpoint {
+				remote-endpoint = <&gmsl_sensor7_ep>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 0 */
+	qcom,cam-gmsl-sensor4 {
+		cell-index = <4>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor4_ep: endpoint {
+				remote-endpoint = <&deser1_port0>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 1 */
+	qcom,cam-gmsl-sensor5 {
+		cell-index = <5>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor5_ep: endpoint {
+				remote-endpoint = <&deser1_port1>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 2 */
+	qcom,cam-gmsl-sensor6 {
+		cell-index = <6>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor6_ep: endpoint {
+				remote-endpoint = <&deser1_port2>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 3 */
+	qcom,cam-gmsl-sensor7 {
+		cell-index = <7>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor7_ep: endpoint {
+				remote-endpoint = <&deser1_port3>;
+			};
+		};
+	};
+
+	/*cam1-ov9282*/
+	qcom,cam-sensor21 {
+		cell-index = <21>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <1>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active
+		                &cam_sensor_active_rst1>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend
+		                &cam_sensor_suspend_rst1>;
+		gpios = <&tlmm 73 0>,
+			<&tlmm 133 0>,
+			<&pmm8654au_0_gpios 8 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags   	 = <1 0 0>;
+		gpio-req-tbl-label = "CAM_MCLK1",
+		                       "CAMIF_RESET1",
+		                         "CAM_CUSTOM1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+	};
+
+	eeprom_cam26: qcom,eeprom26 {
+		cell-index = <26>;
+		compatible = "qcom,eeprom";
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active
+				 &cam_sensor_active_rst1>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend
+				 &cam_sensor_suspend_rst1>;
+		gpios = <&tlmm 73 0>,
+			<&tlmm 133 0>,
+			<&pmm8654au_0_gpios 8 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags = <1 0 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK1",
+					"CAM_RESET1",
+					"CAM_CUSTOM1";
+		sensor-mode = <0>;
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/*cam1-imx577*/
+	qcom,cam-sensor26 {
+		cell-index = <26>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <1>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		eeprom-src = <&eeprom_cam26>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active
+		                &cam_sensor_active_rst1>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend
+		                &cam_sensor_suspend_rst1>;
+		gpios = <&tlmm 73 0>,
+			<&tlmm 133 0>,
+			<&pmm8654au_0_gpios 8 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags = <1 0 0>;
+		gpio-req-tbl-label = "CAM_MCLK1",
+		                       "CAMIF_RESET1",
+		                         "CAM_CUSTOM1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+	};
+
+	eeprom_cam28: qcom,eeprom28 {
+		cell-index = <28>;
+		compatible = "qcom,eeprom";
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active
+				 &cam_sensor_active_rst1>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend
+				 &cam_sensor_suspend_rst1>;
+		gpios = <&tlmm 73 0>,
+			<&tlmm 133 0>,
+			<&pmm8654au_0_gpios 8 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags = <1 0 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK1",
+					"CAM_RESET1",
+					"CAM_CUSTOM1";
+		sensor-mode = <0>;
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/*cam1-cmk_imx577*/
+	qcom,cam-sensor28 {
+		cell-index = <28>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <1>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		eeprom-src = <&eeprom_cam28>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active
+		                &cam_sensor_active_rst1>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend
+		                &cam_sensor_suspend_rst1>;
+		gpios = <&tlmm 73 0>,
+			<&tlmm 133 0>,
+			<&pmm8654au_0_gpios 8 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags   	 = <1 0 0>;
+		gpio-req-tbl-label = "CAM_MCLK1",
+		                       "CAMIF_RESET1",
+		                         "CAM_CUSTOM1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+	};
+
+};
+
+&cam_cci2 {
+
+	/* GMSL deserializer 2 */
+	qcom,cam-gmsl-deserializer2 {
+		cell-index = <2>;
+		csiphy-sd-index = <2>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_active>;
+		pinctrl-1 = <&cam_sensor_mclk2_suspend>;
+		gpios = <&pmm8654au_0_gpios 9 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_RESET2";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK2_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+
+		port@0 {
+			reg = <0>;
+			deser2_port0: endpoint {
+				remote-endpoint = <&gmsl_sensor8_ep>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			deser2_port1: endpoint {
+				remote-endpoint = <&gmsl_sensor9_ep>;
+			};
+		};
+
+		port@2 {
+			reg = <0>;
+			deser2_port2: endpoint {
+				remote-endpoint = <&gmsl_sensor10_ep>;
+			};
+		};
+
+		port@3 {
+			reg = <1>;
+			deser2_port3: endpoint {
+				remote-endpoint = <&gmsl_sensor11_ep>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 0 */
+	qcom,cam-gmsl-sensor8 {
+		cell-index = <8>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor8_ep: endpoint {
+				remote-endpoint = <&deser2_port0>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 1 */
+	qcom,cam-gmsl-sensor9 {
+		cell-index = <9>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor9_ep: endpoint {
+				remote-endpoint = <&deser2_port1>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 2 */
+	qcom,cam-gmsl-sensor10 {
+		cell-index = <10>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor10_ep: endpoint {
+				remote-endpoint = <&deser2_port2>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 3 */
+	qcom,cam-gmsl-sensor11 {
+		cell-index = <11>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor11_ep: endpoint {
+				remote-endpoint = <&deser2_port3>;
+			};
+		};
+	};
+
+	/*cam2-ov9282*/
+	qcom,cam-sensor22 {
+		cell-index = <22>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <2>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_active
+		                &cam_sensor_active_rst2>;
+		pinctrl-1 = <&cam_sensor_mclk2_suspend
+		                &cam_sensor_suspend_rst2>;
+		gpios = <&tlmm 74 0>,
+			<&tlmm 134 0>,
+			<&pmm8654au_0_gpios 9 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags   	 = <1 0 0>;
+		gpio-req-tbl-label = "CAM_MCLK2",
+		                       "CAMIF_RESET2",
+		                         "CAM_CUSTOM1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK2_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+	};
+
+	eeprom_cam29: qcom,eeprom29 {
+		cell-index = <29>;
+		compatible = "qcom,eeprom";
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_active
+				 &cam_sensor_active_rst2>;
+		pinctrl-1 = <&cam_sensor_mclk2_suspend
+				 &cam_sensor_suspend_rst2>;
+		gpios = <&tlmm 74 0>,
+			<&tlmm 134 0>,
+			<&pmm8654au_0_gpios 9 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags = <1 0 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK2",
+					"CAM_RESET2",
+					"CAM_CUSTOM1";
+		sensor-mode = <0>;
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK2_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/*cam2-cmk_imx577*/
+	qcom,cam-sensor29 {
+		cell-index = <29>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <2>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		eeprom-src = <&eeprom_cam29>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_active
+		                &cam_sensor_active_rst2>;
+		pinctrl-1 = <&cam_sensor_mclk2_suspend
+		                &cam_sensor_suspend_rst2>;
+		gpios = <&tlmm 74 0>,
+			<&tlmm 134 0>,
+			<&pmm8654au_0_gpios 9 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags   	 = <1 0 0>;
+		gpio-req-tbl-label = "CAM_MCLK2",
+		                       "CAMIF_RESET2",
+		                         "CAM_CUSTOM1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK2_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+	};
+};
+
+&cam_cci3 {
+
+	/* GMSL deserializer 3 */
+	qcom,cam-gmsl-deserializer3 {
+		cell-index = <3>;
+		csiphy-sd-index = <3>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk3_active>;
+		pinctrl-1 = <&cam_sensor_mclk3_suspend>;
+		gpios = <&pmm8654au_0_gpios 10 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_RESET3";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+
+		port@0 {
+			reg = <0>;
+			deser3_port0: endpoint {
+				remote-endpoint = <&gmsl_sensor12_ep>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			deser3_port1: endpoint {
+				remote-endpoint = <&gmsl_sensor13_ep>;
+			};
+		};
+
+		port@2 {
+			reg = <0>;
+			deser3_port2: endpoint {
+				remote-endpoint = <&gmsl_sensor14_ep>;
+			};
+		};
+
+		port@3 {
+			reg = <1>;
+			deser3_port3: endpoint {
+				remote-endpoint = <&gmsl_sensor15_ep>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 3 sensor 0 */
+	qcom,cam-gmsl-sensor12 {
+		cell-index = <12>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <3>;
+		status = "ok";
+		port {
+			gmsl_sensor12_ep: endpoint {
+				remote-endpoint = <&deser3_port0>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 3 sensor 1 */
+	qcom,cam-gmsl-sensor13 {
+		cell-index = <13>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <3>;
+		status = "ok";
+		port {
+			gmsl_sensor13_ep: endpoint {
+				remote-endpoint = <&deser3_port1>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 3 sensor 2 */
+	qcom,cam-gmsl-sensor14 {
+		cell-index = <14>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <3>;
+		status = "ok";
+		port {
+			gmsl_sensor14_ep: endpoint {
+				remote-endpoint = <&deser3_port2>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 3 sensor 3 */
+	qcom,cam-gmsl-sensor15 {
+		cell-index = <15>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <3>;
+		status = "ok";
+		port {
+			gmsl_sensor15_ep: endpoint {
+				remote-endpoint = <&deser3_port3>;
+			};
+		};
+	};
+
+	/*cam3-ov9282*/
+	qcom,cam-sensor23 {
+		cell-index = <23>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <3>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk3_active
+		                &cam_sensor_active_rst3>;
+		pinctrl-1 = <&cam_sensor_mclk3_suspend
+		                &cam_sensor_suspend_rst3>;
+		gpios = <&tlmm 75 0>,
+			<&tlmm 135 0>,
+			<&pmm8654au_0_gpios 10 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags   	 = <1 0 0>;
+		gpio-req-tbl-label = "CAM_MCLK3",
+		                       "CAMIF_RESET3",
+		                         "CAM_CUSTOM1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+	};
+
+	eeprom_cam30: qcom,eeprom30 {
+		cell-index = <30>;
+		compatible = "qcom,eeprom";
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk3_active
+				 &cam_sensor_active_rst3>;
+		pinctrl-1 = <&cam_sensor_mclk3_suspend
+				 &cam_sensor_suspend_rst3>;
+		gpios = <&tlmm 75 0>,
+			<&tlmm 135 0>,
+			<&pmm8654au_0_gpios 10 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags = <1 0 0>;
+		gpio-req-tbl-label = "CAMIF_MCLK3",
+					"CAM_RESET3",
+					"CAM_CUSTOM1";
+		sensor-mode = <0>;
+		cci-master = <0>;
+		status = "ok";
+		clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+	};
+
+	/*cam3-cmk_imx577*/
+	qcom,cam-sensor30 {
+		cell-index = <30>;
+		compatible = "qcom,cam-sensor";
+		csiphy-sd-index = <3>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		eeprom-src = <&eeprom_cam30>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk3_active
+		                &cam_sensor_active_rst3>;
+		pinctrl-1 = <&cam_sensor_mclk3_suspend
+		                &cam_sensor_suspend_rst3>;
+		gpios = <&tlmm 75 0>,
+			<&tlmm 135 0>,
+			<&pmm8654au_0_gpios 10 0>;
+		gpio-reset = <1>;
+		gpio-custom1 = <2>;
+		gpio-req-tbl-num = <0 1 2>;
+		gpio-req-tbl-flags   	 = <1 0 0>;
+		gpio-req-tbl-label = "CAM_MCLK3",
+		                       "CAMIF_RESET3",
+		                         "CAM_CUSTOM1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+	};
+
+};
+
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9075-iq-9075-evk.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9075-iq-9075-evk.dts
@@ -0,0 +1,1410 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+#include "sa8775p.dtsi"
+#include "sa8775p-pmics.dtsi"
+#include "qcs9075-thermal.dtsi"
+#include "qcs9xxx-reserved-memory.dtsi"
+
+/delete-node/ &usb_2_dwc3;
+
+/ {
+	model = "Qualcomm Technologies, Inc. IQ 9075 EVK";
+	compatible = "qcom,qcs9075-iq-9075-evk", "qcom,qcs9075", "qcom,sa8775p";
+	qcom,msm-id = <676 0x20000>;
+	qcom,board-id = <0x10020 0>, <0x10019 0>;
+
+	aliases {
+		ethernet0 = &ethernet0;
+		serial0 = &uart10;
+		serial1 = &uart17;
+		serial2 = &uart0;
+		spi16 = &spi16;
+		ufshc1 = &ufs_mem_hc;
+		mmc0 = &sdhc_1; /* SDC1 SD card slot */
+		i2c18 = &i2c18;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	wcn6855-pmu {
+		compatible = "qcom,wcn6855-pmu";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&wlan_en_state>;
+		wlan-enable-gpios = <&pmm8654au_1_gpios 7 GPIO_ACTIVE_HIGH>;
+
+		regulators {
+			vreg_pmu_rfa_cmn: ldo0 {
+				regulator-name = "vreg_pmu_rfa_cmn";
+			};
+
+			vreg_pmu_aon_0p59: ldo1 {
+				regulator-name = "vreg_pmu_aon_0p59";
+			};
+
+			vreg_pmu_wlcx_0p8: ldo2 {
+				regulator-name = "vreg_pmu_wlcx_0p8";
+			};
+
+			vreg_pmu_wlmx_0p85: ldo3 {
+				regulator-name = "vreg_pmu_wlmx_0p85";
+			};
+
+			vreg_pmu_btcmx_0p85: ldo4 {
+				regulator-name = "vreg_pmu_btcmx_0p85";
+			};
+
+			vreg_pmu_rfa_0p8: ldo5 {
+				regulator-name = "vreg_pmu_rfa_0p8";
+			};
+
+			vreg_pmu_rfa_1p2: ldo6 {
+				regulator-name = "vreg_pmu_rfa_1p2";
+			};
+
+			vreg_pmu_rfa_1p7: ldo7 {
+				regulator-name = "vreg_pmu_rfa_1p7";
+			};
+
+			vreg_pmu_pcie_0p9: ldo8 {
+				regulator-name = "vreg_pmu_pcie_0p9";
+			};
+
+			vreg_pmu_pcie_1p8: ldo9 {
+				regulator-name = "vreg_pmu_pcie_1p8";
+			};
+		};
+	};
+
+	dummy_reg: regulator-dummy {
+		compatible = "regulator-fixed";
+		regulator-name = "dummy-supply";
+
+		regulator-min-microvolt = <2950000>;
+		regulator-max-microvolt = <2950000>;
+	};
+};
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "a";
+
+		vreg_s4a: smps4 {
+			regulator-name = "vreg_s4a";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1816000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s5a: smps5 {
+			regulator-name = "vreg_s5a";
+			regulator-min-microvolt = <1850000>;
+			regulator-max-microvolt = <1996000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s9a: smps9 {
+			regulator-name = "vreg_s9a";
+			regulator-min-microvolt = <535000>;
+			regulator-max-microvolt = <1120000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4a: ldo4 {
+			regulator-name = "vreg_l4a";
+			regulator-min-microvolt = <788000>;
+			regulator-max-microvolt = <1050000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5a: ldo5 {
+			regulator-name = "vreg_l5a";
+			regulator-min-microvolt = <870000>;
+			regulator-max-microvolt = <950000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6a: ldo6 {
+			regulator-name = "vreg_l6a";
+			regulator-min-microvolt = <870000>;
+			regulator-max-microvolt = <970000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7a: ldo7 {
+			regulator-name = "vreg_l7a";
+			regulator-min-microvolt = <720000>;
+			regulator-max-microvolt = <950000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8a: ldo8 {
+			regulator-name = "vreg_l8a";
+			regulator-min-microvolt = <2504000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9a: ldo9 {
+			regulator-name = "vreg_l9a";
+			regulator-min-microvolt = <2970000>;
+			regulator-max-microvolt = <3544000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "c";
+
+		vreg_l1c: ldo1 {
+			regulator-name = "vreg_l1c";
+			regulator-min-microvolt = <1140000>;
+			regulator-max-microvolt = <1260000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2c: ldo2 {
+			regulator-name = "vreg_l2c";
+			regulator-min-microvolt = <900000>;
+			regulator-max-microvolt = <1100000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3c: ldo3 {
+			regulator-name = "vreg_l3c";
+			regulator-min-microvolt = <1100000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4c: ldo4 {
+			regulator-name = "vreg_l4c";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			/*
+			 * FIXME: This should have regulator-allow-set-load but
+			 * we're getting an over-current fault from the PMIC
+			 * when switching to LPM.
+			 */
+		};
+
+		vreg_l5c: ldo5 {
+			regulator-name = "vreg_l5c";
+			regulator-min-microvolt = <1100000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6c: ldo6 {
+			regulator-name = "vreg_l6c";
+			regulator-min-microvolt = <1620000>;
+			regulator-max-microvolt = <1980000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7c: ldo7 {
+			regulator-name = "vreg_l7c";
+			regulator-min-microvolt = <1620000>;
+			regulator-max-microvolt = <2000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8c: ldo8 {
+			regulator-name = "vreg_l8c";
+			regulator-min-microvolt = <2400000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9c: ldo9 {
+			regulator-name = "vreg_l9c";
+			regulator-min-microvolt = <1650000>;
+			regulator-max-microvolt = <2700000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-2 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "e";
+
+		vreg_s4e: smps4 {
+			regulator-name = "vreg_s4e";
+			regulator-min-microvolt = <970000>;
+			regulator-max-microvolt = <1520000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s7e: smps7 {
+			regulator-name = "vreg_s7e";
+			regulator-min-microvolt = <1010000>;
+			regulator-max-microvolt = <1170000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s9e: smps9 {
+			regulator-name = "vreg_s9e";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <570000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6e: ldo6 {
+			regulator-name = "vreg_l6e";
+			regulator-min-microvolt = <1280000>;
+			regulator-max-microvolt = <1450000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8e: ldo8 {
+			regulator-name = "vreg_l8e";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1950000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&ethernet0 {
+	phy-handle = <&sgmii_phy0>;
+	phy-mode = "sgmii";
+
+	pinctrl-0 = <&ethernet0_default>;
+	pinctrl-names = "default";
+
+	snps,mtl-rx-config = <&mtl_rx_setup>;
+	snps,mtl-tx-config = <&mtl_tx_setup>;
+	snps,ps-speed = <1000>;
+	eeprom-for-mac = <&eeprom0>;
+
+	status = "okay";
+
+	mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		sgmii_phy0: phy@1c {
+			compatible = "ethernet-phy-id004d.d101";
+			reg = <0x1c>;
+			device_type = "ethernet-phy";
+			reset-gpios = <&pmm8654au_2_gpios 8 GPIO_ACTIVE_LOW>;
+			reset-assert-us = <11000>;
+			reset-deassert-us = <70000>;
+		};
+	};
+
+	mtl_rx_setup: rx-queues-config {
+		snps,rx-queues-to-use = <4>;
+		snps,rx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x0>;
+			snps,route-up;
+			snps,priority = <0x1>;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x1>;
+			snps,route-ptp;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x2>;
+			snps,route-avcp;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x3>;
+			snps,priority = <0xc>;
+		};
+	};
+
+	mtl_tx_setup: tx-queues-config {
+		snps,tx-queues-to-use = <4>;
+		snps,tx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+	};
+};
+
+&eud {
+	status = "okay";
+};
+
+&i2c0 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c1 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c2 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c3 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c4 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c5 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c7 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c8 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c9 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c10 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c11 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+
+	pinctrl-0 = <&qup_i2c11_default>, <&usb0_intr_state>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	hd3ss3220@67 {
+		compatible = "ti,hd3ss3220";
+		reg = <0x67>;
+		interrupt-parent = <&pmm8654au_2_gpios>;
+		interrupts = < 5 IRQ_TYPE_EDGE_FALLING>;
+		wakeup-source;
+
+		connector@0 {
+			compatible = "usb-c-connector";
+			label = "USB-C";
+			data-role = "dual";
+			power-role = "dual";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					hd3ss3220_ep: endpoint {
+						remote-endpoint = <&usb_role_switch>;
+					};
+				};
+			};
+		};
+	};
+};
+
+&i2c12 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c13 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c14 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c15 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c16 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c17 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&i2c18 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+	pinctrl-0 = <&qup_i2c18_default>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	expander0: pca953x@38 {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x38>;
+	};
+
+	expander1: pca953x@39 {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x39>;
+
+		io-exp-hog2 {
+			gpio-hog;
+			gpios = <2 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "io_exp_gpio2";
+		};
+
+		io-exp-hog3 {
+			gpio-hog;
+			gpios = <3 GPIO_ACTIVE_HIGH>;
+			output-low;
+			line-name = "io_exp_gpio3";
+		};
+	};
+
+	expander2: pca953x@3a {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x3a>;
+	};
+
+	expander3: pca953x@3b {
+		compatible = "ti,tca9538";
+		#gpio-cells = <2>;
+		gpio-controller;
+		reg = <0x3b>;
+	};
+
+	eeprom0: 24c256@50 {
+		compatible = "atmel,24c256";
+		reg = <0x50>;
+		pagesize = <64>;
+		i2c_id = <0x12>;
+	};
+};
+
+&i2c19 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+	pinctrl-0 = <&qup_i2c19_default>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	fan: fan@18 {
+		compatible = "ti,amc6821";
+		reg = <0x18>;
+	};
+};
+
+&llcc {
+	status = "okay";
+};
+
+&mdss0 {
+	status = "okay";
+};
+
+&mdss0_dp0 {
+	status = "okay";
+};
+
+&mdss0_dp0_out {
+	data-lanes = <0 1 2 3>;
+	link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+};
+
+&mdss0_dp1 {
+	status = "okay";
+};
+
+&mdss0_dp1_out {
+	data-lanes = <0 1 2 3>;
+	link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+};
+
+&mdss0_edp_phy {
+	status = "okay";
+};
+
+&mdss0_edp1_phy {
+	status = "okay";
+};
+
+&pmm8654au_1_gpios {
+	gpio-line-names = "PMIC_C_ID0",
+			  "PMIC_C_ID1",
+			  "UFS1_VER_ID",
+			  "IPA_PWR",
+			  "",
+			  "WLAN_DBU4_EN",
+			  "WLAN_EN",
+			  "BT_EN",
+			  "USB2_PWR_EN",
+			  "USB2_FAULT";
+
+	usb2_en_state: usb2-en-state {
+		pins = "gpio9";
+		function = "normal";
+		output-high;
+		power-source = <0>;
+	};
+
+	wlan_en_state: wlan-en-state {
+		pins = "gpio7";
+		function = "normal";
+		output-low;
+		bias-pull-down;
+	};
+};
+
+&pmm8654au_2_gpios {
+	usb0_intr_state: usb0-intr-state {
+		pins = "gpio5";
+		function = "normal";
+		input-enable;
+		bias-pull-up;
+		power-source = <0>;
+	};
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&qupv3_id_1 {
+	status = "okay";
+};
+
+&qupv3_id_2 {
+	status = "okay";
+};
+
+&qup_uart0_tx {
+	bias-pull-up;
+};
+
+&qup_uart0_rx {
+	bias-pull-down;
+};
+
+&qup_uart17_cts {
+	bias-disable;
+};
+
+&qup_uart17_rts {
+	bias-pull-down;
+};
+
+&qup_uart17_tx {
+	bias-pull-up;
+};
+
+&qup_uart17_rx {
+	bias-pull-down;
+};
+
+&remoteproc_adsp {
+	firmware-name = "qcom/sa8775p/adsp.mbn";
+	status = "okay";
+};
+
+&remoteproc_cdsp0 {
+	firmware-name = "qcom/sa8775p/cdsp0.mbn";
+	status = "okay";
+};
+
+&remoteproc_cdsp1 {
+	firmware-name = "qcom/sa8775p/cdsp1.mbn";
+	status = "okay";
+};
+
+&remoteproc_gpdsp0 {
+	firmware-name = "qcom/sa8775p/gpdsp0.mbn";
+	status = "okay";
+};
+
+&remoteproc_gpdsp1 {
+	firmware-name = "qcom/sa8775p/gpdsp1.mbn";
+	status = "okay";
+};
+
+&serdes0 {
+	phy-supply = <&vreg_l5a>;
+	status = "okay";
+};
+
+&sleep_clk {
+	clock-frequency = <32768>;
+};
+
+&spi0 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi1 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi2 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi3 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi4 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi5 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi7 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi8 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi9 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi10 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi11 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi12 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi14 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi15 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi16 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi17 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi18 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&spi19 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&tlmm {
+	dp_hot_plug_det: dp-hot-plug-det-state {
+		pins = "gpio101";
+		function = "edp0_hot";
+		bias-disable;
+	};
+
+	dp1_hot_plug_det: dp1-hot-plug-det-state {
+		pins = "gpio102";
+		function = "edp1_hot";
+		bias-disable;
+	};
+
+	ethernet0_default: ethernet0-default-state {
+		ethernet0_mdc: ethernet0-mdc-pins {
+			pins = "gpio8";
+			function = "emac0_mdc";
+			drive-strength = <16>;
+			bias-pull-up;
+		};
+
+		ethernet0_mdio: ethernet0-mdio-pins {
+			pins = "gpio9";
+			function = "emac0_mdio";
+			drive-strength = <16>;
+			bias-pull-up;
+		};
+	};
+
+	pcie0_default_state: pcie0-default-state {
+		perst-pins {
+			pins = "gpio2";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+
+		clkreq-pins {
+			pins = "gpio1";
+			function = "pcie0_clkreq";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		wake-pins {
+			pins = "gpio0";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+	};
+
+	pcie1_default_state: pcie1-default-state {
+		perst-pins {
+			pins = "gpio4";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+
+		clkreq-pins {
+			pins = "gpio3";
+			function = "pcie1_clkreq";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		wake-pins {
+			pins = "gpio5";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+	};
+
+	qup_i2c18_default: qup-i2c18-state {
+		pins = "gpio95", "gpio96";
+		function = "qup2_se4";
+		drive-strength = <2>;
+		bias-pull-up;
+	};
+
+	qup_i2c11_default: qup-i2c11-state {
+		pins = "gpio48", "gpio49";
+		function = "qup1_se4";
+		drive-strength = <2>;
+		bias-pull-up;
+	};
+
+	qup_spi16_cs: qup-spi16-cs-state {
+		pins = "gpio89";
+		function = "qup2_se2";
+	};
+
+	qup_spi16_data_clk: qup-spi16-data-clk-state {
+		pins = "gpio86", "gpio87", "gpio88";
+		function = "qup2_se2";
+	};
+
+	qup_i2c19_default: qup-i2c19-state {
+		pins = "gpio99", "gpio100";
+		function = "qup2_se5";
+		drive-strength = <2>;
+		bias-pull-up;
+	};
+
+	sdc1_clk: sdc1-clk-state {
+		pins = "sdc1_clk";
+		bias-disable;
+		drive-strength = <16>;
+	};
+
+	sdc1_cmd: sdc1-cmd-state {
+		pins = "sdc1_cmd";
+		bias-pull-up;
+		drive-strength = <10>;
+	};
+
+	sdc1_data: sdc1-data-state {
+		pins = "sdc1_data";
+		bias-pull-up;
+		drive-strength = <10>;
+	};
+
+	sdc1_clk_sleep: sdc1-clk-sleep-state {
+		pins = "sdc1_clk";
+		drive-strength = <2>;
+		bias-bus-hold;
+	};
+
+	sdc1_cmd_sleep: sdc1-cmd-sleep-state {
+		pins = "sdc1_cmd";
+		drive-strength = <2>;
+		bias-bus-hold;
+	};
+
+	sdc1_data_sleep: sdc1-data-sleep-state {
+		pins = "sdc1_data";
+		drive-strength = <2>;
+		bias-bus-hold;
+	};
+
+	sd_cd: sd-cd-state {
+		pins = "gpio36";
+		function = "gpio";
+		bias-pull-up;
+	};
+
+	usb1_id_det_default: usb1-id-det-default {
+		pins = "gpio51";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-up;
+	};
+};
+
+&pcie0 {
+	perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_default_state>;
+
+	status = "okay";
+};
+
+&pcie1 {
+	perst-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 5 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_default_state>;
+
+	status = "okay";
+};
+
+&pcie0_phy {
+	vdda-phy-supply = <&vreg_l5a>;
+	vdda-pll-supply = <&vreg_l1c>;
+
+	status = "okay";
+};
+
+&pcie1_phy {
+	vdda-phy-supply = <&vreg_l5a>;
+	vdda-pll-supply = <&vreg_l1c>;
+
+	status = "okay";
+};
+
+&pcieport0 {
+	wifi@0 {
+		compatible = "qcom,wcn6855-wifi";
+		reg = <0x10000 0x0 0x0 0x0 0x0>;
+
+		vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+		vddaon-supply = <&vreg_pmu_aon_0p59>;
+		vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
+		vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
+		vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+		vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+		vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>;
+		vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>;
+		vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>;
+	};
+};
+
+&pmm8654au_0_pon_resin {
+	linux,code = <KEY_VOLUMEDOWN>;
+	status = "okay";
+};
+
+/delete-node/ &qup_uart0_rts;
+/delete-node/ &qup_uart0_cts;
+
+&uart0 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+	status = "okay";
+};
+
+&uart1 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&uart2 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&uart3 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&uart4 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&uart5 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&uart7 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&uart8 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&uart9 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&uart10 {
+	compatible = "qcom,geni-debug-uart";
+	status = "okay";
+};
+
+&uart11 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&uart12 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&uart14 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&uart15 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&uart16 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&uart17 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+	status = "okay";
+
+	/* HS UART Instance */
+	bluetooth: bluetooth {
+		compatible = "qcom,wcn6855-bt";
+		pinctrl-names = "default";
+		max-speed = <3200000>;
+	};
+};
+
+&uart18 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&uart19 {
+	qcom,load-firmware;
+	qcom,xfer-mode = <1>;
+};
+
+&ufs_mem_hc {
+	reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>;
+	vcc-supply = <&vreg_l8a>;
+	vcc-max-microamp = <1100000>;
+	vccq-supply = <&vreg_l4c>;
+	vccq-max-microamp = <1200000>;
+
+	status = "okay";
+};
+
+&ufs_mem_phy {
+	vdda-phy-supply = <&vreg_l4a>;
+	vdda-pll-supply = <&vreg_l1c>;
+
+	status = "okay";
+};
+
+&soc {
+	connector_usb1: connector-usb1 {
+		compatible = "gpio-usb-b-connector";
+		id-gpio = <&tlmm 51 GPIO_ACTIVE_HIGH>;
+		vbus-supply = <&vbus_supply_regulator_1>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&usb1_id_det_default>;
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				usb1_port_connector: endpoint {
+					remote-endpoint = <&usb1_port>;
+				};
+			};
+		};
+	};
+
+	vreg_sdc: regulator-sdc {
+		compatible = "regulator-gpio";
+
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <2950000>;
+		regulator-name = "vreg_sdc";
+		regulator-type = "voltage";
+
+		startup-delay-us = <100>;
+
+		gpios = <&expander1 7 GPIO_ACTIVE_HIGH>;
+
+		states = <1800000 0x1
+			  2950000 0x0>;
+	};
+
+	vbus_supply_regulator_0: vbus_supply_regulator_0 {
+		compatible = "regulator-fixed";
+		regulator-name = "vbus_supply_0";
+		gpio = <&expander1 2 GPIO_ACTIVE_HIGH>;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-boot-on;
+		enable-active-high;
+	};
+
+	vbus_supply_regulator_1: vbus_supply_regulator_1 {
+		compatible = "regulator-fixed";
+		regulator-name = "vbus_supply_1";
+		gpio = <&expander1 3 GPIO_ACTIVE_HIGH>;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		regulator-boot-on;
+		enable-active-high;
+	};
+};
+
+&spi16 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&qup_spi16_cs>, <&qup_spi16_data_clk>;
+	status = "okay";
+
+	st33htpm0: st33htpm@0 {
+		compatible = "st,st33htpm-spi";
+		reg = <0>;
+		spi-max-frequency = <20000000>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+		status = "okay";
+	};
+};
+
+/delete-node/ &usb_0_dwc3;
+
+&usb_0 {
+	reg = <0x0 0x0a600000 0x0 0x200000>;
+
+	interrupts-extended = <&intc GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH>,
+			      <&intc GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>,
+			      <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
+			      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
+			      <&pdc 12 IRQ_TYPE_LEVEL_HIGH>;
+	interrupt-names = "dwc_usb3",
+			  "pwr_event",
+			  "dp_hs_phy_irq",
+			  "dm_hs_phy_irq",
+			  "ss_phy_irq";
+
+	iommus = <&apps_smmu 0x080 0x0>;
+	phys = <&usb_0_hsphy>, <&usb_0_qmpphy>;
+	phy-names = "usb2-phy", "usb3-phy";
+
+	dr_mode = "otg";
+	usb-role-switch;
+	snps,dis_u2_susphy_quirk;
+	snps,dis_enblslpm_quirk;
+	maximum-speed = "super-speed";
+	qcom,enable-rt;
+	wakeup-source;
+	vbus_dwc3-supply = <&vbus_supply_regulator_0>;
+	status = "okay";
+
+	ports {
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			usb_role_switch: endpoint {
+				remote-endpoint = <&hd3ss3220_ep>;
+			};
+		};
+
+	};
+};
+
+&usb_0_hsphy {
+	vdda-pll-supply = <&vreg_l7a>;
+	vdda18-supply = <&vreg_l6c>;
+	vdda33-supply = <&vreg_l9a>;
+
+	status = "okay";
+};
+
+&usb_0_qmpphy {
+	vdda-phy-supply = <&vreg_l1c>;
+	vdda-pll-supply = <&vreg_l7a>;
+
+	status = "okay";
+};
+
+/delete-node/ &usb_1_dwc3;
+
+&usb_1 {
+	reg = <0x0 0x0a800000 0x0 0x200000>;
+	interrupts-extended = <&intc GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH>,
+				<&intc GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>,
+				<&pdc 8 IRQ_TYPE_EDGE_BOTH>,
+				<&pdc 7 IRQ_TYPE_EDGE_BOTH>,
+				<&pdc 13 IRQ_TYPE_LEVEL_HIGH>;
+	interrupt-names = "dwc_usb3",
+			"pwr_event",
+			"dp_hs_phy_irq",
+			"dm_hs_phy_irq",
+			"ss_phy_irq";
+
+	iommus = <&apps_smmu 0x0a0 0x0>;
+	phys = <&usb_1_hsphy>, <&usb_1_qmpphy>;
+	phy-names = "usb2-phy", "usb3-phy";
+	snps,dis_u2_susphy_quirk;
+	snps,dis_enblslpm_quirk;
+	qcom,enable-rt;
+	wakeup-source;
+	maximum-speed = "super-speed";
+	dr_mode = "otg";
+	usb-role-switch;
+	status = "okay";
+
+	ports {
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			usb1_port: endpoint {
+				remote-endpoint = <&usb1_port_connector>;
+			};
+		};
+
+	};
+};
+
+&usb_1_hsphy {
+	vdda-pll-supply = <&vreg_l7a>;
+	vdda18-supply = <&vreg_l6c>;
+	vdda33-supply = <&vreg_l9a>;
+
+	status = "okay";
+};
+
+&usb_1_qmpphy {
+	vdda-phy-supply = <&vreg_l1c>;
+	vdda-pll-supply = <&vreg_l7a>;
+
+	status = "okay";
+};
+
+&usb_2 {
+	reg = <0x0 0x0a400000 0x0 0x200000>;
+	interrupts-extended = <&intc GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>,
+				<&intc GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>,
+				<&pdc 10 IRQ_TYPE_EDGE_BOTH>,
+				<&pdc 9 IRQ_TYPE_EDGE_BOTH>;
+	interrupt-names = "dwc_usb3",
+			"pwr_event",
+			"dp_hs_phy_irq",
+			"dm_hs_phy_irq";
+
+	iommus = <&apps_smmu 0x020 0x0>;
+	phys = <&usb_2_hsphy>;
+	phy-names = "usb2-phy";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb2_en_state>;
+
+	dr_mode = "otg";
+	usb-role-switch;
+	role-switch-default-mode = "host";
+	qcom,enable-rt;
+	wakeup-source;
+
+	status = "okay";
+};
+
+&usb_2_hsphy {
+	vdda-pll-supply = <&vreg_l7a>;
+	vdda18-supply = <&vreg_l6c>;
+	vdda33-supply = <&vreg_l9a>;
+
+	status = "okay";
+};
+
+&xo_board_clk {
+	clock-frequency = <38400000>;
+};
+
+&sdhc_1 {
+	vmmc-supply = <&dummy_reg>;
+	vqmmc-supply = <&vreg_sdc>;
+
+	pinctrl-names = "default", "sleep";
+	pinctrl-0 = <&sdc1_clk>, <&sdc1_cmd>, <&sdc1_data>, <&sd_cd>;
+	pinctrl-1 = <&sdc1_clk_sleep>, <&sdc1_cmd_sleep>, <&sdc1_data_sleep>, <&sd_cd>;
+
+	cd-gpios = <&tlmm 36 GPIO_ACTIVE_LOW>;
+
+	iommus = <&apps_smmu 0x0 0x0>;
+
+	status = "okay";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9075-ride-r3.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024,2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+
+#include "sa8775p-ride-r3.dts"
+#include "qcs9075-thermal.dtsi"
+#include "qcs9xxx-reserved-memory.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS9075 Ride Rev3";
+	compatible = "qcom,qcs9075-ride-r3", "qcom,qcs9075", "qcom,sa8775p";
+	qcom,msm-id = <676 0x20000>;
+	qcom,board-id = <0x20025 1>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9075-ride-sx-camera.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9075-ride-sx-camera.dtso
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,sa8775p-gcc.h>
+#include <dt-bindings/clock/qcom,sa8775p-camcc.h>
+#include <dt-bindings/interconnect/qcom,sa8775p-rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+
+#include "sa8775p-camera.dtsi"
+#include "qcs9100-camera-sensor-idp.dtsi"
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9075-ride.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9075-ride.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024,2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+
+#include "sa8775p-ride.dts"
+#include "qcs9075-thermal.dtsi"
+#include "qcs9xxx-reserved-memory.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. QCS9075 Ride";
+	compatible = "qcom,qcs9075-ride", "qcom,qcs9075", "qcom,sa8775p";
+	qcom,msm-id = <676 0x20000>;
+	qcom,board-id = <0x10025 1>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9075-thermal.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9075-thermal.dtsi
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+&CPU0 {
+	#cooling-cells = <2>;
+};
+
+&CPU1 {
+	#cooling-cells = <2>;
+	CPU1_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU2 {
+	#cooling-cells = <2>;
+	CPU2_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU3 {
+	#cooling-cells = <2>;
+	CPU3_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU4 {
+	#cooling-cells = <2>;
+	CPU4_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU5 {
+	#cooling-cells = <2>;
+	CPU5_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU6 {
+	#cooling-cells = <2>;
+	CPU6_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU7 {
+	#cooling-cells = <2>;
+	CPU7_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&thermal_zones {
+	cpu-0-1-0-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_0_1_0_alert1>;
+				cooling-device = <&CPU1_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-0-2-0-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_0_2_0_alert1>;
+				cooling-device = <&CPU2_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-0-3-0-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_0_3_0_alert1>;
+				cooling-device = <&CPU3_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-0-1-1-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_0_1_1_alert1>;
+				cooling-device = <&CPU1_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-0-2-1-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_0_2_1_alert1>;
+				cooling-device = <&CPU2_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-0-3-1-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_0_3_1_alert1>;
+				cooling-device = <&CPU3_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-0-0-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_0_0_alert1>;
+				cooling-device = <&CPU4_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-1-0-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_1_0_alert1>;
+				cooling-device = <&CPU5_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-2-0-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_2_0_alert1>;
+				cooling-device = <&CPU6_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-3-0-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_3_0_alert1>;
+				cooling-device = <&CPU7_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-0-1-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_0_1_alert1>;
+				cooling-device = <&CPU4_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-1-1-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_1_1_alert1>;
+				cooling-device = <&CPU5_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-2-1-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_2_1_alert1>;
+				cooling-device = <&CPU6_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-3-1-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_3_1_alert1>;
+				cooling-device = <&CPU7_idle 100 100>;
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9100-addons-ride-r3.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9100-addons-ride-r3.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs9100-ride-r3.dts"
+#include "sa8775p-addons-ride.dtsi"
+
+/ {
+	model = "Qualcomm QCS9100 Ride Rev3";
+	compatible = "qcom,qcs9100-addons-ride-r3", "qcom,qcs9100", "qcom,sa8775p";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9100-addons-ride.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9100-addons-ride.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "qcs9100-ride.dts"
+#include "sa8775p-addons-ride.dtsi"
+
+/ {
+	model = "Qualcomm QCS9100 Ride";
+	compatible = "qcom,qcs9100-addons-ride", "qcom,qcs9100", "qcom,sa8775p";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9100-camera-sensor-idp.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9100-camera-sensor-idp.dtsi
@@ -0,0 +1,480 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <dt-bindings/msm-camera.h>
+
+&soc {
+	qcom,cam-res-mgr {
+		compatible = "qcom,cam-res-mgr";
+		status = "ok";
+		gpios-shared = <518 519 520 521>;
+	};
+};
+
+&cam_cci0 {
+
+	/* GMSL deserializer 0 */
+	qcom,cam-gmsl-deserializer0 {
+		cell-index = <0>;
+		csiphy-sd-index = <0>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk0_active>;
+		pinctrl-1 = <&cam_sensor_mclk0_suspend>;
+		gpios = <&pmm8654au_0_gpios 7 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_RESET0";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+
+		port@0 {
+			reg = <0>;
+			deser0_port0: endpoint {
+				remote-endpoint = <&gmsl_sensor0_ep>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			deser0_port1: endpoint {
+				remote-endpoint = <&gmsl_sensor1_ep>;
+			};
+		};
+
+		port@2 {
+			reg = <0>;
+			deser0_port2: endpoint {
+				remote-endpoint = <&gmsl_sensor2_ep>;
+			};
+		};
+
+		port@3 {
+			reg = <1>;
+			deser0_port3: endpoint {
+				remote-endpoint = <&gmsl_sensor3_ep>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 0 */
+	qcom,cam-gmsl-sensor0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor0_ep: endpoint {
+				remote-endpoint = <&deser0_port0>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 1 */
+	qcom,cam-gmsl-sensor1 {
+		cell-index = <1>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor1_ep: endpoint {
+				remote-endpoint = <&deser0_port1>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 2 */
+	qcom,cam-gmsl-sensor2 {
+		cell-index = <2>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor2_ep: endpoint {
+				remote-endpoint = <&deser0_port2>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 0 sensor 3 */
+	qcom,cam-gmsl-sensor3 {
+		cell-index = <3>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <0>;
+		status = "ok";
+		port {
+			gmsl_sensor3_ep: endpoint {
+				remote-endpoint = <&deser0_port3>;
+			};
+		};
+	};
+
+};
+
+
+&cam_cci1 {
+
+	/* GMSL deserializer 1 */
+	qcom,cam-gmsl-deserializer1 {
+		cell-index = <1>;
+		csiphy-sd-index = <1>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk1_active>;
+		pinctrl-1 = <&cam_sensor_mclk1_suspend>;
+		gpios = <&pmm8654au_0_gpios 8 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_RESET1";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK1_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+
+		port@0 {
+			reg = <0>;
+			deser1_port0: endpoint {
+				remote-endpoint = <&gmsl_sensor4_ep>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			deser1_port1: endpoint {
+				remote-endpoint = <&gmsl_sensor5_ep>;
+			};
+		};
+
+		port@2 {
+			reg = <0>;
+			deser1_port2: endpoint {
+				remote-endpoint = <&gmsl_sensor6_ep>;
+			};
+		};
+
+		port@3 {
+			reg = <1>;
+			deser1_port3: endpoint {
+				remote-endpoint = <&gmsl_sensor7_ep>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 0 */
+	qcom,cam-gmsl-sensor4 {
+		cell-index = <4>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor4_ep: endpoint {
+				remote-endpoint = <&deser1_port0>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 1 */
+	qcom,cam-gmsl-sensor5 {
+		cell-index = <5>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor5_ep: endpoint {
+				remote-endpoint = <&deser1_port1>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 2 */
+	qcom,cam-gmsl-sensor6 {
+		cell-index = <6>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor6_ep: endpoint {
+				remote-endpoint = <&deser1_port2>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 1 sensor 3 */
+	qcom,cam-gmsl-sensor7 {
+		cell-index = <7>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <1>;
+		status = "ok";
+		port {
+			gmsl_sensor7_ep: endpoint {
+				remote-endpoint = <&deser1_port3>;
+			};
+		};
+	};
+
+};
+
+&cam_cci2 {
+
+	/* GMSL deserializer 2 */
+	qcom,cam-gmsl-deserializer2 {
+		cell-index = <2>;
+		csiphy-sd-index = <2>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk2_active>;
+		pinctrl-1 = <&cam_sensor_mclk2_suspend>;
+		gpios = <&pmm8654au_0_gpios 9 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_RESET2";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK2_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+
+		port@0 {
+			reg = <0>;
+			deser2_port0: endpoint {
+				remote-endpoint = <&gmsl_sensor8_ep>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			deser2_port1: endpoint {
+				remote-endpoint = <&gmsl_sensor9_ep>;
+			};
+		};
+
+		port@2 {
+			reg = <0>;
+			deser2_port2: endpoint {
+				remote-endpoint = <&gmsl_sensor10_ep>;
+			};
+		};
+
+		port@3 {
+			reg = <1>;
+			deser2_port3: endpoint {
+				remote-endpoint = <&gmsl_sensor11_ep>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 0 */
+	qcom,cam-gmsl-sensor8 {
+		cell-index = <8>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor8_ep: endpoint {
+				remote-endpoint = <&deser2_port0>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 1 */
+	qcom,cam-gmsl-sensor9 {
+		cell-index = <9>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor9_ep: endpoint {
+				remote-endpoint = <&deser2_port1>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 2 */
+	qcom,cam-gmsl-sensor10 {
+		cell-index = <10>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor10_ep: endpoint {
+				remote-endpoint = <&deser2_port2>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 2 sensor 3 */
+	qcom,cam-gmsl-sensor11 {
+		cell-index = <11>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <2>;
+		status = "ok";
+		port {
+			gmsl_sensor11_ep: endpoint {
+				remote-endpoint = <&deser2_port3>;
+			};
+		};
+	};
+
+};
+
+
+&cam_cci3 {
+
+	/* GMSL deserializer 3 */
+	qcom,cam-gmsl-deserializer3 {
+		cell-index = <3>;
+		csiphy-sd-index = <3>;
+		sensor-position-roll = <0>;
+		sensor-position-pitch = <0>;
+		sensor-position-yaw = <180>;
+		cam_vio-supply = <&vreg_s4a>;
+		regulator-names = "cam_vio";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		pwm-switch;
+		rgltr-min-voltage = <1800000>;
+		rgltr-max-voltage = <1800000>;
+		rgltr-load-current = <120000>;
+		gpio-no-mux = <0>;
+		pinctrl-names = "cam_default", "cam_suspend";
+		pinctrl-0 = <&cam_sensor_mclk3_active>;
+		pinctrl-1 = <&cam_sensor_mclk3_suspend>;
+		gpios = <&pmm8654au_0_gpios 10 0>;
+		gpio-reset = <0>;
+		gpio-req-tbl-num = <0>;
+		gpio-req-tbl-flags = <0>;
+		gpio-req-tbl-label = "CAM_RESET3";
+		cci-master = <0>;
+		clocks = <&camcc CAM_CC_MCLK3_CLK>;
+		clock-names = "cam_clk";
+		clock-cntl-level = "nominal";
+		clock-rates = <24000000>;
+		status = "ok";
+
+		port@0 {
+			reg = <0>;
+			deser3_port0: endpoint {
+				remote-endpoint = <&gmsl_sensor12_ep>;
+			};
+		};
+
+		port@1 {
+			reg = <1>;
+			deser3_port1: endpoint {
+				remote-endpoint = <&gmsl_sensor13_ep>;
+			};
+		};
+
+		port@2 {
+			reg = <0>;
+			deser3_port2: endpoint {
+				remote-endpoint = <&gmsl_sensor14_ep>;
+			};
+		};
+
+		port@3 {
+			reg = <1>;
+			deser3_port3: endpoint {
+				remote-endpoint = <&gmsl_sensor15_ep>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 3 sensor 0 */
+	qcom,cam-gmsl-sensor12 {
+		cell-index = <12>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <3>;
+		status = "ok";
+		port {
+			gmsl_sensor12_ep: endpoint {
+				remote-endpoint = <&deser3_port0>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 3 sensor 1 */
+	qcom,cam-gmsl-sensor13 {
+		cell-index = <13>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <3>;
+		status = "ok";
+		port {
+			gmsl_sensor13_ep: endpoint {
+				remote-endpoint = <&deser3_port1>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 3 sensor 2 */
+	qcom,cam-gmsl-sensor14 {
+		cell-index = <14>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <3>;
+		status = "ok";
+		port {
+			gmsl_sensor14_ep: endpoint {
+				remote-endpoint = <&deser3_port2>;
+			};
+		};
+	};
+
+	/* GMSL deserializer 3 sensor 3 */
+	qcom,cam-gmsl-sensor15 {
+		cell-index = <15>;
+		compatible = "qcom,cam-gmsl-sensor";
+		csiphy-sd-index = <3>;
+		status = "ok";
+		port {
+			gmsl_sensor15_ep: endpoint {
+				remote-endpoint = <&deser3_port3>;
+			};
+		};
+	};
+
+};
+
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9100-graphics.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9100-graphics.dtsi
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2024-2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+// SPDX-License-Identifier: BSD-3-Clause
+
+#define MHZ_TO_KBPS(mhz, w) ((mhz * 1000000 * w) / (1024))
+
+&soc {
+	msm_gpu: qcom,kgsl-3d0@3d00000 {
+		compatible = "qcom,kgsl";
+		status = "ok";
+		reg = <0 0x3d00000 0 0x40000>, <0 0x3d61000 0 0x800>,
+			<0 0x3de0000 0 0x10000>, <0 0x4900000 0 0x80000>,
+			<0 0x3dff000 0 0x1000>;
+		reg-names = "kgsl_3d0_reg_memory", "cx_dbgc", "rscc",
+			"qdss_gfx", "fusa";
+		interrupts = <0 300 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "kgsl_3d0_irq";
+
+		clocks = <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+			<&gcc GCC_GPU_SNOC_DVM_GFX_CLK>,
+			<&gpucc GPU_CC_AHB_CLK>,
+			<&gpucc GPU_CC_CX_GMU_CLK>,
+			<&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>,
+			<&gpucc GPU_CC_HUB_AON_CLK>,
+			<&gpucc GPU_CC_HUB_CX_INT_CLK>;
+		clock-names = "gcc_gpu_memnoc_gfx",
+				"gcc_gpu_snoc_dvm_gfx",
+				"gpu_cc_ahb",
+				"gpu_cc_cx_gmu",
+				"gpu_cc_hlos1_vote_gpu_smmu",
+				"gpu_cc_hub_aon",
+				"gpu_cc_hub_cx_int";
+
+		qcom,chipid = <0x06060300>;
+		qcom,gpu-model = "Adreno663v1";
+
+		qcom,initial-pwrlevel = <3>;
+
+		qcom,highest-bank-bit = <16>;
+
+		qcom,min-access-length = <32>;
+
+		qcom,ubwc-mode = <4>;
+
+		qcom,gpu-qdss-stm = <0x161c0000 0x40000>; /* base addr, size */
+
+		qcom,tzone-names = "gpuss-0-usr", "gpuss-1-usr";
+
+		interconnect-names = "gpu_icc_path";
+		interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>;
+
+		qcom,bus-table-ddr =
+			<MHZ_TO_KBPS(0, 4)>,    /* index=0  */
+			<MHZ_TO_KBPS(200, 4)>,  /* index=1  */
+			<MHZ_TO_KBPS(451, 4)>,  /* index=2  */
+			<MHZ_TO_KBPS(547, 4)>,  /* index=3  */
+			<MHZ_TO_KBPS(681, 4)>,  /* index=4  */
+			<MHZ_TO_KBPS(768, 4)>,  /* index=5  */
+			<MHZ_TO_KBPS(1017, 4)>, /* index=6  */
+			<MHZ_TO_KBPS(1353, 4)>, /* index=7  */
+			<MHZ_TO_KBPS(1555, 4)>, /* index=8  */
+			<MHZ_TO_KBPS(1708, 4)>, /* index=9  */
+			<MHZ_TO_KBPS(2092, 4)>, /* index=10  */
+			<MHZ_TO_KBPS(2736, 4)>, /* index=11  */
+			<MHZ_TO_KBPS(3196, 4)>; /* index=12  */
+
+		qcom,bus-table-cnoc =
+			<0>,   /* Off */
+			<100>; /* On */
+
+		zap-shader {
+			memory-region = <&pil_gpu_mem>;
+		};
+
+		qcom,gpu-mempools {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "qcom,gpu-mempools";
+
+			/* 4K Page Pool configuration */
+			qcom,gpu-mempool@0 {
+				reg = <0>;
+				qcom,mempool-page-size = <4096>;
+				qcom,mempool-reserved = <2048>;
+			};
+			/* 8K Page Pool configuration */
+			qcom,gpu-mempool@1 {
+				reg = <1>;
+				qcom,mempool-page-size = <8192>;
+				qcom,mempool-reserved = <1024>;
+			};
+			/* 64K Page Pool configuration */
+			qcom,gpu-mempool@2 {
+				reg = <2>;
+				qcom,mempool-page-size = <65536>;
+				qcom,mempool-reserved = <256>;
+			};
+			/* 128K Page Pool configuration */
+			qcom,gpu-mempool@3 {
+				reg = <3>;
+				qcom,mempool-page-size = <131072>;
+				qcom,mempool-reserved = <128>;
+			};
+			/* 256K Page Pool configuration */
+			qcom,gpu-mempool@4 {
+				reg = <4>;
+				qcom,mempool-page-size = <262144>;
+				qcom,mempool-reserved = <80>;
+			};
+			/* 1M Page Pool configuration */
+			qcom,gpu-mempool@5 {
+				reg = <5>;
+				qcom,mempool-page-size = <1048576>;
+				qcom,mempool-reserved = <32>;
+			};
+		};
+
+		/* Power levels */
+		qcom,gpu-pwrlevels {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			compatible = "qcom,gpu-pwrlevels";
+
+			qcom,gpu-pwrlevel@0 {
+				reg = <0>;
+				qcom,gpu-freq = <800000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+
+				qcom,bus-freq = <12>;
+				qcom,bus-min = <12>;
+				qcom,bus-max = <12>;
+			};
+
+			qcom,gpu-pwrlevel@1 {
+				reg = <1>;
+				qcom,gpu-freq = <778000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_TURBO>;
+
+				qcom,bus-freq = <11>;
+				qcom,bus-min = <11>;
+				qcom,bus-max = <12>;
+			};
+
+			qcom,gpu-pwrlevel@2 {
+				reg = <2>;
+				qcom,gpu-freq = <676000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_NOM>;
+
+				qcom,bus-freq = <10>;
+				qcom,bus-min = <10>;
+				qcom,bus-max = <11>;
+			};
+
+			qcom,gpu-pwrlevel@3 {
+				reg = <3>;
+				qcom,gpu-freq = <405000000>;
+				qcom,level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+
+				qcom,bus-freq = <7>;
+				qcom,bus-min = <7>;
+				qcom,bus-max = <10>;
+			};
+		};
+	};
+
+	kgsl_msm_iommu: qcom,kgsl-iommu@3da0000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		compatible = "qcom,kgsl-smmu-v2";
+
+		reg = <0x03da0000 0x20000>;
+
+		power-domains = <&gpucc GPU_CC_CX_GDSC>;
+
+		gfx3d_user: gfx3d_user {
+			compatible = "qcom,smmu-kgsl-cb", "qcom,adreno-gmu";
+			iommus = <&adreno_smmu 0x0 0xc00>, <&adreno_smmu 0x1 0xc00>;
+			qcom,iommu-dma = "disabled";
+		};
+	};
+
+	gmu: qcom,gmu@3d6a000 {
+		compatible = "qcom,gpu-gmu";
+
+		reg = <0 0x3d6a000 0 0x34000>,
+			<0 0xb290000 0 0x10000>;
+
+		reg-names = "kgsl_gmu_reg",
+			"kgsl_gmu_pdc_cfg";
+
+		interrupts = <0 304 IRQ_TYPE_LEVEL_HIGH>,
+			<0 305 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "kgsl_hfi_irq", "kgsl_gmu_irq";
+
+		iommus = <&adreno_smmu 0x5 0xc00>;
+		qcom,iommu-dma = "disabled";
+
+		power-domains = <&gpucc GPU_CC_CX_GDSC>, <&gpucc GPU_CC_GX_GDSC>;
+		power-domain-names = "cx", "gx";
+
+		clocks = <&gpucc GPU_CC_CX_GMU_CLK>,
+			<&gpucc GPU_CC_CXO_CLK>,
+			<&gcc GCC_DDRSS_GPU_AXI_CLK>,
+			<&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+			<&gpucc GPU_CC_AHB_CLK>,
+			<&gpucc GPU_CC_HUB_CX_INT_CLK>;
+
+		clock-names = "gmu_clk", "cxo_clk", "axi_clk",
+			"memnoc_clk", "ahb_clk", "hub_clk";
+
+		qcom,qmp = <&aoss_qmp>;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9100-graphics.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9100-graphics.dtso
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+// SPDX-License-Identifier: BSD-3-Clause
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,sa8775p-gcc.h>
+#include <dt-bindings/clock/qcom,sa8775p-gpucc.h>
+#include <dt-bindings/interconnect/qcom,sa8775p-rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+
+#include "qcs9100-graphics.dtsi"
+
+/ {
+	model = "Qualcomm SA8775P Ride";
+	compatible = "qcom,sa8775p-ride", "qcom,sa8775p";
+	qcom,msm-id = <533 0x10000>, <534 0x10000>, <534 0x20000>;
+	qcom,board-id = <0x19 0>, <0x25 1>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9100-ride-r3.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9100-ride-r3.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024,2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+
+#include "sa8775p-ride-r3.dts"
+#include "qcs9100-thermal.dtsi"
+#include "qcs9xxx-reserved-memory.dtsi"
+
+/ {
+	model = "Qualcomm QCS9100 Ride Rev3";
+	compatible = "qcom,qcs9100-ride-r3", "qcom,qcs9100", "qcom,sa8775p";
+	qcom,msm-id = <667 0x10000>, <667 0x20000>;
+	qcom,board-id = <0x20025 1>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9100-ride-sx-camera.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9100-ride-sx-camera.dtso
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,sa8775p-gcc.h>
+#include <dt-bindings/clock/qcom,sa8775p-camcc.h>
+#include <dt-bindings/interconnect/qcom,sa8775p-rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+
+#include "sa8775p-camera.dtsi"
+#include "qcs9100-camera-sensor-idp.dtsi"
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9100-ride.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9100-ride.dts
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024,2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+
+#include "sa8775p-ride.dts"
+#include "qcs9100-thermal.dtsi"
+#include "qcs9xxx-reserved-memory.dtsi"
+
+/ {
+	model = "Qualcomm QCS9100 Ride";
+	compatible = "qcom,qcs9100-ride", "qcom,qcs9100", "qcom,sa8775p";
+	qcom,msm-id = <667 0x10000>, <667 0x20000>;
+	qcom,board-id = <0x10019 0>, <0x10025 1>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9100-thermal.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9100-thermal.dtsi
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+&CPU0 {
+	#cooling-cells = <2>;
+};
+
+&CPU1 {
+	#cooling-cells = <2>;
+	CPU1_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU2 {
+	#cooling-cells = <2>;
+	CPU2_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU3 {
+	#cooling-cells = <2>;
+	CPU3_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU4 {
+	#cooling-cells = <2>;
+	CPU4_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU5 {
+	#cooling-cells = <2>;
+	CPU5_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU6 {
+	#cooling-cells = <2>;
+	CPU6_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&CPU7 {
+	#cooling-cells = <2>;
+	CPU7_idle: thermal-idle {
+		#cooling-cells = <2>;
+		duration-us = <800000>;
+		exit-latency-us = <10000>;
+	};
+};
+
+&thermal_zones {
+	cpu-0-1-0-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_0_1_0_alert1>;
+				cooling-device = <&CPU1_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-0-2-0-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_0_2_0_alert1>;
+				cooling-device = <&CPU2_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-0-3-0-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_0_3_0_alert1>;
+				cooling-device = <&CPU3_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-0-1-1-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_0_1_1_alert1>;
+				cooling-device = <&CPU1_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-0-2-1-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_0_2_1_alert1>;
+				cooling-device = <&CPU2_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-0-3-1-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_0_3_1_alert1>;
+				cooling-device = <&CPU3_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-0-0-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_0_0_alert1>;
+				cooling-device = <&CPU4_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-1-0-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_1_0_alert1>;
+				cooling-device = <&CPU5_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-2-0-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_2_0_alert1>;
+				cooling-device = <&CPU6_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-3-0-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_3_0_alert1>;
+				cooling-device = <&CPU7_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-0-1-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_0_1_alert1>;
+				cooling-device = <&CPU4_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-1-1-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_1_1_alert1>;
+				cooling-device = <&CPU5_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-2-1-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_2_1_alert1>;
+				cooling-device = <&CPU6_idle 100 100>;
+			};
+		};
+	};
+
+	cpu-1-3-1-thermal {
+		trips {
+			trip-point1 {
+				temperature = <116000>;
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&cpu_1_3_1_alert1>;
+				cooling-device = <&CPU7_idle 100 100>;
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qcs9xxx-reserved-memory.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qcs9xxx-reserved-memory.dtsi
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/delete-node/ &pil_adsp_mem;
+/delete-node/ &pil_gdsp0_mem;
+/delete-node/ &pil_gdsp1_mem;
+/delete-node/ &pil_cdsp0_mem;
+/delete-node/ &pil_gpu_mem;
+/delete-node/ &pil_cdsp1_mem;
+/delete-node/ &pil_cvp_mem;
+/delete-node/ &pil_video_mem;
+/delete-node/ &audio_mdf_mem;
+/delete-node/ &trusted_apps_mem;
+/delete-node/ &hyptz_reserved_mem;
+/delete-node/ &tz_ffi_mem;
+
+/ {
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		gunyah_md_mem: gunyah-md@91a80000 {
+			reg = <0x0 0x91a80000 0x0 0x80000>;
+			no-map;
+		};
+
+		pil_adsp_mem: pil-adsp@95900000 {
+			reg = <0x0 0x95900000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		q6_adsp_dtb_mem: q6-adsp-dtb@97700000 {
+			reg = <0x0 0x97700000 0x0 0x80000>;
+			no-map;
+		};
+
+		q6_gdsp0_dtb_mem: q6-gdsp0-dtb@97780000 {
+			reg = <0x0 0x97780000 0x0 0x80000>;
+			no-map;
+		};
+
+		pil_gdsp0_mem: pil-gdsp0@97800000 {
+			reg = <0x0 0x97800000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		pil_gdsp1_mem: pil-gdsp1@99600000 {
+			reg = <0x0 0x99600000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		q6_gdsp1_dtb_mem: q6-gdsp1-dtb@9b400000 {
+			reg = <0x0 0x9b400000 0x0 0x80000>;
+			no-map;
+		};
+
+		q6_cdsp0_dtb_mem: q6-cdsp0-dtb@9b480000 {
+			reg = <0x0 0x9b480000 0x0 0x80000>;
+			no-map;
+		};
+
+		pil_cdsp0_mem: pil-cdsp0@9b500000 {
+			reg = <0x0 0x9b500000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		pil_gpu_mem: pil-gpu@9d300000 {
+			reg = <0x0 0x9d300000 0x0 0x2000>;
+			no-map;
+		};
+
+		q6_cdsp1_dtb_mem: q6-cdsp1-dtb@9d380000 {
+			reg = <0x0 0x9d380000 0x0 0x80000>;
+			no-map;
+		};
+
+		pil_cdsp1_mem: pil-cdsp1@9d400000 {
+			reg = <0x0 0x9d400000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		pil_cvp_mem: pil-cvp@9f200000 {
+			reg = <0x0 0x9f200000 0x0 0x700000>;
+			no-map;
+		};
+
+		pil_video_mem: pil-video@9f900000 {
+			reg = <0x0 0x9f900000 0x0 0x1000000>;
+			no-map;
+		};
+
+		trusted_apps_mem: trusted-apps@d1900000 {
+			reg = <0x0 0xd1900000 0x0 0x1c00000>;
+			no-map;
+		};
+	};
+
+	firmware {
+		scm {
+			/delete-property/ memory-region;
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qdu1000-idp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qdu1000-idp.dts
@@ -31,7 +31,7 @@
 
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
-			clock-frequency = <32000>;
+			clock-frequency = <32764>;
 			#clock-cells = <0>;
 		};
 	};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qdu1000.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qdu1000.dtsi
@@ -1459,11 +1459,40 @@
 
 		system-cache-controller@19200000 {
 			compatible = "qcom,qdu1000-llcc";
-			reg = <0 0x19200000 0 0xd80000>,
+			reg = <0 0x19200000 0 0x80000>,
+			      <0 0x19300000 0 0x80000>,
+			      <0 0x19600000 0 0x80000>,
+			      <0 0x19700000 0 0x80000>,
+			      <0 0x19a00000 0 0x80000>,
+			      <0 0x19b00000 0 0x80000>,
+			      <0 0x19e00000 0 0x80000>,
+			      <0 0x19f00000 0 0x80000>,
 			      <0 0x1a200000 0 0x80000>;
 			reg-names = "llcc0_base",
+				    "llcc1_base",
+				    "llcc2_base",
+				    "llcc3_base",
+				    "llcc4_base",
+				    "llcc5_base",
+				    "llcc6_base",
+				    "llcc7_base",
 				    "llcc_broadcast_base";
 			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+
+			nvmem-cells = <&multi_chan_ddr>;
+			nvmem-cell-names = "multi-chan-ddr";
+		};
+
+		sec_qfprom: efuse@221c8000 {
+			compatible = "qcom,qdu1000-sec-qfprom", "qcom,sec-qfprom";
+			reg = <0 0x221c8000 0 0x1000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			multi_chan_ddr: multi-chan-ddr@12b {
+				reg = <0x12b 0x1>;
+				bits = <0 2>;
+			};
 		};
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts
@@ -7,7 +7,7 @@
 
 #include <dt-bindings/leds/common.h>
 #include "qcm2290.dtsi"
-#include "pm2250.dtsi"
+#include "pm4125.dtsi"
 
 / {
 	model = "Qualcomm Technologies, Inc. Robotics RB1";
@@ -59,6 +59,17 @@
 		};
 	};
 
+	i2c2_gpio: i2c {
+		compatible = "i2c-gpio";
+
+		sda-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>;
+		scl-gpios = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+	};
+
 	leds {
 		compatible = "gpio-leds";
 
@@ -177,11 +188,29 @@
 	};
 };
 
+&CPU_PD0 {
+	/delete-property/ power-domains;
+};
+
+&CPU_PD1 {
+	/delete-property/ power-domains;
+};
+
+&CPU_PD2 {
+	/delete-property/ power-domains;
+};
+
+&CPU_PD3 {
+	/delete-property/ power-domains;
+};
+
+/delete-node/ &CLUSTER_PD;
+
 &gpi_dma0 {
 	status = "okay";
 };
 
-&i2c2 {
+&i2c2_gpio {
 	clock-frequency = <400000>;
 	status = "okay";
 
@@ -226,7 +255,7 @@
 };
 
 &mdss_dsi0 {
-	vdda-supply = <&pm2250_l5>;
+	vdda-supply = <&pm4125_l5>;
 	status = "okay";
 };
 
@@ -239,7 +268,7 @@
 	status = "okay";
 };
 
-&pm2250_resin {
+&pm4125_resin {
 	linux,code = <KEY_VOLUMEDOWN>;
 	status = "okay";
 };
@@ -263,23 +292,23 @@
 		compatible = "qcom,rpm-pm2250-regulators";
 		vdd_s3-supply = <&vph_pwr>;
 		vdd_s4-supply = <&vph_pwr>;
-		vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12-supply = <&pm2250_s3>;
+		vdd_l1_l2_l3_l5_l6_l7_l8_l9_l10_l11_l12-supply = <&pm4125_s3>;
 		vdd_l4_l17_l18_l19_l20_l21_l22-supply = <&vph_pwr>;
-		vdd_l13_l14_l15_l16-supply = <&pm2250_s4>;
+		vdd_l13_l14_l15_l16-supply = <&pm4125_s4>;
 
 		/*
 		 * S1 - VDD_APC
 		 * S2 - VDD_CX
 		 */
 
-		pm2250_s3: s3 {
+		pm4125_s3: s3 {
 			/* 0.4V-1.6625V -> 1.3V (Power tree requirements) */
 			regulator-min-microvolt = <1352000>;
 			regulator-max-microvolt = <1352000>;
 			regulator-boot-on;
 		};
 
-		pm2250_s4: s4 {
+		pm4125_s4: s4 {
 			/* 1.2V-2.35V -> 2.05V (Power tree requirements) */
 			regulator-min-microvolt = <2072000>;
 			regulator-max-microvolt = <2072000>;
@@ -288,7 +317,7 @@
 
 		/* L1 - VDD_MX */
 
-		pm2250_l2: l2 {
+		pm4125_l2: l2 {
 			/* LPDDR4X VDD2 */
 			regulator-min-microvolt = <1136000>;
 			regulator-max-microvolt = <1136000>;
@@ -296,7 +325,7 @@
 			regulator-boot-on;
 		};
 
-		pm2250_l3: l3 {
+		pm4125_l3: l3 {
 			/* LPDDR4X VDDQ */
 			regulator-min-microvolt = <616000>;
 			regulator-max-microvolt = <616000>;
@@ -304,14 +333,14 @@
 			regulator-boot-on;
 		};
 
-		pm2250_l4: l4 {
+		pm4125_l4: l4 {
 			/* max = 3.05V -> max = 2.7 to disable 3V signaling (SDHCI2) */
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <2700000>;
 			regulator-allow-set-load;
 		};
 
-		pm2250_l5: l5 {
+		pm4125_l5: l5 {
 			/* CSI/DSI */
 			regulator-min-microvolt = <1232000>;
 			regulator-max-microvolt = <1232000>;
@@ -319,7 +348,7 @@
 			regulator-boot-on;
 		};
 
-		pm2250_l6: l6 {
+		pm4125_l6: l6 {
 			/* DRAM PLL */
 			regulator-min-microvolt = <928000>;
 			regulator-max-microvolt = <928000>;
@@ -327,7 +356,7 @@
 			regulator-boot-on;
 		};
 
-		pm2250_l7: l7 {
+		pm4125_l7: l7 {
 			/* Wi-Fi CX/MX */
 			regulator-min-microvolt = <664000>;
 			regulator-max-microvolt = <664000>;
@@ -338,20 +367,20 @@
 		 * L9 - VDD_LPI_MX
 		 */
 
-		pm2250_l10: l10 {
+		pm4125_l10: l10 {
 			/* Wi-Fi RFA */
 			regulator-min-microvolt = <1304000>;
 			regulator-max-microvolt = <1304000>;
 		};
 
-		pm2250_l11: l11 {
+		pm4125_l11: l11 {
 			/* GPS RF1 */
 			regulator-min-microvolt = <1000000>;
 			regulator-max-microvolt = <1000000>;
 			regulator-boot-on;
 		};
 
-		pm2250_l12: l12 {
+		pm4125_l12: l12 {
 			/* USB PHYs */
 			regulator-min-microvolt = <928000>;
 			regulator-max-microvolt = <928000>;
@@ -359,7 +388,7 @@
 			regulator-boot-on;
 		};
 
-		pm2250_l13: l13 {
+		pm4125_l13: l13 {
 			/* USB/QFPROM/PLLs */
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <1800000>;
@@ -367,7 +396,7 @@
 			regulator-boot-on;
 		};
 
-		pm2250_l14: l14 {
+		pm4125_l14: l14 {
 			/* SDHCI1 VQMMC */
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <1800000>;
@@ -376,7 +405,7 @@
 			regulator-always-on;
 		};
 
-		pm2250_l15: l15 {
+		pm4125_l15: l15 {
 			/* WCD/DSI/BT VDDIO */
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <1800000>;
@@ -385,38 +414,38 @@
 			regulator-boot-on;
 		};
 
-		pm2250_l16: l16 {
+		pm4125_l16: l16 {
 			/* GPS RF2 */
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <1800000>;
 			regulator-boot-on;
 		};
 
-		pm2250_l17: l17 {
+		pm4125_l17: l17 {
 			regulator-min-microvolt = <3000000>;
 			regulator-max-microvolt = <3000000>;
 		};
 
-		pm2250_l18: l18 {
+		pm4125_l18: l18 {
 			/* VDD_PXn */
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <1800000>;
 		};
 
-		pm2250_l19: l19 {
+		pm4125_l19: l19 {
 			/* VDD_PXn */
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <1800000>;
 		};
 
-		pm2250_l20: l20 {
+		pm4125_l20: l20 {
 			/* SDHCI1 VMMC */
 			regulator-min-microvolt = <2400000>;
 			regulator-max-microvolt = <3600000>;
 			regulator-allow-set-load;
 		};
 
-		pm2250_l21: l21 {
+		pm4125_l21: l21 {
 			/* SDHCI2 VMMC */
 			regulator-min-microvolt = <2960000>;
 			regulator-max-microvolt = <3300000>;
@@ -424,7 +453,7 @@
 			regulator-boot-on;
 		};
 
-		pm2250_l22: l22 {
+		pm4125_l22: l22 {
 			/* Wi-Fi */
 			regulator-min-microvolt = <3312000>;
 			regulator-max-microvolt = <3312000>;
@@ -433,8 +462,8 @@
 };
 
 &sdhc_1 {
-	vmmc-supply = <&pm2250_l20>;
-	vqmmc-supply = <&pm2250_l14>;
+	vmmc-supply = <&pm4125_l20>;
+	vqmmc-supply = <&pm4125_l14>;
 	pinctrl-0 = <&sdc1_state_on>;
 	pinctrl-1 = <&sdc1_state_off>;
 	pinctrl-names = "default", "sleep";
@@ -446,8 +475,8 @@
 };
 
 &sdhc_2 {
-	vmmc-supply = <&pm2250_l21>;
-	vqmmc-supply = <&pm2250_l4>;
+	vmmc-supply = <&pm4125_l21>;
+	vqmmc-supply = <&pm4125_l4>;
 	cd-gpios = <&tlmm 88 GPIO_ACTIVE_LOW>;
 	pinctrl-0 = <&sdc2_state_on &sd_det_in_on>;
 	pinctrl-1 = <&sdc2_state_off &sd_det_in_off>;
@@ -518,8 +547,8 @@
 };
 
 &usb_qmpphy {
-	vdda-phy-supply = <&pm2250_l12>;
-	vdda-pll-supply = <&pm2250_l13>;
+	vdda-phy-supply = <&pm4125_l12>;
+	vdda-pll-supply = <&pm4125_l13>;
 	status = "okay";
 };
 
@@ -528,17 +557,17 @@
 };
 
 &usb_hsphy {
-	vdd-supply = <&pm2250_l12>;
-	vdda-pll-supply = <&pm2250_l13>;
-	vdda-phy-dpdm-supply = <&pm2250_l21>;
+	vdd-supply = <&pm4125_l12>;
+	vdda-pll-supply = <&pm4125_l13>;
+	vdda-phy-dpdm-supply = <&pm4125_l21>;
 	status = "okay";
 };
 
 &wifi {
-	vdd-0.8-cx-mx-supply = <&pm2250_l7>;
-	vdd-1.8-xo-supply = <&pm2250_l13>;
-	vdd-1.3-rfa-supply = <&pm2250_l10>;
-	vdd-3.3-ch0-supply = <&pm2250_l22>;
+	vdd-0.8-cx-mx-supply = <&pm4125_l7>;
+	vdd-1.8-xo-supply = <&pm4125_l13>;
+	vdd-1.3-rfa-supply = <&pm4125_l10>;
+	vdd-3.3-ch0-supply = <&pm4125_l22>;
 	qcom,ath10k-calibration-variant = "Thundercomm_RB1";
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts
@@ -58,6 +58,17 @@
 		};
 	};
 
+	i2c2_gpio: i2c {
+		compatible = "i2c-gpio";
+
+		sda-gpios = <&tlmm 6 GPIO_ACTIVE_HIGH>;
+		scl-gpios = <&tlmm 7 GPIO_ACTIVE_HIGH>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+	};
+
 	leds {
 		compatible = "gpio-leds";
 
@@ -188,7 +199,7 @@
 	};
 };
 
-&i2c2 {
+&i2c2_gpio {
 	clock-frequency = <400000>;
 	status = "okay";
 
@@ -361,6 +372,8 @@
 			regulator-min-microvolt = <1800000>;
 			regulator-max-microvolt = <1800000>;
 			regulator-allow-set-load;
+			regulator-always-on;
+			regulator-boot-on;
 		};
 
 		vreg_l10a_1p8: l10 {
@@ -490,7 +503,7 @@
 };
 
 &sleep_clk {
-	clock-frequency = <32000>;
+	clock-frequency = <32764>;
 };
 
 &tlmm {
@@ -607,10 +620,6 @@
 	status = "okay";
 };
 
-&usb_dwc3 {
-	maximum-speed = "super-speed";
-};
-
 &usb_hsphy {
 	vdd-supply = <&vreg_l4a_0p9>;
 	vdda-pll-supply = <&vreg_l12a_1p8>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/qru1000-idp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/qru1000-idp.dts
@@ -31,7 +31,7 @@
 
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
-			clock-frequency = <32000>;
+			clock-frequency = <32764>;
 			#clock-cells = <0>;
 		};
 	};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/rubikpi3.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/rubikpi3.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Thundercomm All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "rubikpi3.dtsi"
+
+/ {
+	model = "Thundercomm, Inc. RUBIK Pi 3";
+	compatible = "qcom,qcm6490-addons-idp","qcom,sc7280";
+
+	/* This will be deprecated soon */
+	qcom,msm-id = <497 0x10000>, <498 0x10000>, <475 0x10000>, <515 0x10000>;
+	qcom,board-id = <32 0xb>, <32 0x60b>;
+};
+
+
+/* partial revert of "UBUNTU: SAUCE: arm64: dts: qcm6490: enable platform sound-dai"*/
+/delete-node/ &q6apmdai;
+
+&q6apmbedai {
+	q6apm-dai-uses-dummy-ops;
+};
\ No newline at end of file
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/rubikpi3.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/rubikpi3.dtsi
@@ -0,0 +1,1565 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Thundercomm All rights reserved.
+ */
+#define PM7250B_SID 8
+#define PM7250B_SID1 9
+
+#include <dt-bindings/iio/qcom,spmi-adc7-pm7325.h>
+#include <dt-bindings/iio/qcom,spmi-adc7-pmk8350.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "qcm6490.dtsi"
+#include "pm7250b.dtsi"
+#include "pm7325.dtsi"
+#include "pm8350c.dtsi"
+#include "pmk8350.dtsi"
+#include "qcm6490-addons.dtsi"
+#include "pm7325b.dtsi"
+
+/ {
+	model = "Thundercomm, Inc. RUBIK Pi 3";
+	compatible = "qcom,qcm6490-rb3gen2", "qcom,qcm6490";
+
+	qcom,msm-id = <497 0x10000>, <498 0x10000>, <475 0x10000>, <515 0x10000>;
+	qcom,board-id =<32 0xb>, <32 0x60b>;
+
+	aliases {
+		serial0 = &uart5;
+		serial2 = &uart2;
+		serial3 = &uart3;
+		serial6 = &uart6;
+		serial7 = &uart7;
+		serial8 = &uart8;
+		serial12 = &uart12;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		label = "gpio-keys";
+
+		pinctrl-0 = <&key_vol_up_default>;
+		pinctrl-names = "default";
+
+		key-volume-up {
+			label = "volume_up";
+			gpios = <&pm7325_gpios 6 GPIO_ACTIVE_LOW>;
+			linux,input-type = <1>;
+			linux,code = <KEY_VOLUMEUP>;
+			wakeup-source;
+			debounce-interval = <15>;
+			linux,can-disable;
+		};
+	};
+
+	pmic-glink {
+		compatible = "qcom,sm8350-pmic-glink", "qcom,pmic-glink";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		orientation-gpios = <&tlmm 140 GPIO_ACTIVE_HIGH>;
+		qcom,thermal-mitigation = <3000000 1500000 1000000 500000>;
+
+		connector@0 {
+			compatible = "usb-c-connector";
+			reg = <0>;
+			power-role = "dual";
+			data-role = "dual";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					pmic_glink_hs_in: endpoint {
+						remote-endpoint = <&usb_1_dwc3_hs>;
+					};
+				};
+			};
+		};
+	};
+
+	thermal-zones {
+		quiet-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmk8350_adc_tm 1>;
+
+			trips {
+				active-config0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+			};
+		};
+
+		sdm-skin-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmk8350_adc_tm 3>;
+
+			trips {
+				active-config0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+			};
+		};
+
+		xo-thermal {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmk8350_adc_tm 0>;
+
+			trips {
+				active-config0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+			};
+		};
+	};
+};
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pm7325-rpmh-regulators";
+		qcom,pmic-id = "b";
+
+		vreg_s1b_1p872: smps1 {
+			regulator-min-microvolt = <1840000>;
+			regulator-max-microvolt = <2040000>;
+		};
+
+		vreg_s2b_0p876: smps2 {
+			regulator-min-microvolt = <570070>;
+			regulator-max-microvolt = <1050000>;
+		};
+
+		vreg_s7b_0p972: smps7 {
+			regulator-min-microvolt = <535000>;
+			regulator-max-microvolt = <1120000>;
+		};
+
+		vreg_s8b_1p272: smps8 {
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1500000>;
+		};
+
+		vreg_l1b_0p912: ldo1 {
+			regulator-min-microvolt = <912000>;
+			regulator-max-microvolt = <925000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2b_3p072: ldo2 {
+			regulator-min-microvolt = <2700000>;
+			regulator-max-microvolt = <3544000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3b_0p504: ldo3 {
+			regulator-min-microvolt = <312000>;
+			regulator-max-microvolt = <910000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4b_0p752: ldo4 {
+			regulator-min-microvolt = <752000>;
+			regulator-max-microvolt = <820000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5b_0p752: ldo5 {
+			regulator-min-microvolt = <552000>;
+			regulator-max-microvolt = <832000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6b_1p2: ldo6 {
+			regulator-min-microvolt = <1140000>;
+			regulator-max-microvolt = <1260000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7b_2p952: ldo7 {
+			regulator-min-microvolt = <2400000>;
+			regulator-max-microvolt = <3544000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8b_0p904: ldo8 {
+			regulator-min-microvolt = <870000>;
+			regulator-max-microvolt = <970000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9b_1p2: ldo9 {
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1304000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l11b_1p504: ldo11 {
+			regulator-min-microvolt = <1504000>;
+			regulator-max-microvolt = <2000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l12b_0p751: ldo12 {
+			regulator-min-microvolt = <751000>;
+			regulator-max-microvolt = <824000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l13b_0p53: ldo13 {
+			regulator-min-microvolt = <530000>;
+			regulator-max-microvolt = <824000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l14b_1p08: ldo14 {
+			regulator-min-microvolt = <1080000>;
+			regulator-max-microvolt = <1304000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l15b_0p765: ldo15 {
+			regulator-min-microvolt = <765000>;
+			regulator-max-microvolt = <1020000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l16b_1p1: ldo16 {
+			regulator-min-microvolt = <1100000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l17b_1p7: ldo17 {
+			regulator-min-microvolt = <1700000>;
+			regulator-max-microvolt = <1900000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l18b_1p8: ldo18 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l19b_1p8: ldo19 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <2000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pm8350c-rpmh-regulators";
+		qcom,pmic-id = "c";
+
+		vreg_s1c_2p19: smps1 {
+			regulator-min-microvolt = <2190000>;
+			regulator-max-microvolt = <2210000>;
+		};
+
+		vreg_s2c_0p752: smps2 {
+			regulator-min-microvolt = <750000>;
+			regulator-max-microvolt = <800000>;
+		};
+
+		vreg_s5c_0p752: smps5 {
+			regulator-min-microvolt = <465000>;
+			regulator-max-microvolt = <1050000>;
+		};
+
+		vreg_s7c_0p752: smps7 {
+			regulator-min-microvolt = <465000>;
+			regulator-max-microvolt = <800000>;
+		};
+
+		vreg_s9c_1p084: smps9 {
+			regulator-min-microvolt = <1010000>;
+			regulator-max-microvolt = <1170000>;
+		};
+
+		vreg_s10c_0p752:smps10 {
+			regulator-min-microvolt = <752000>;
+			regulator-max-microvolt = <800000>;
+		};
+
+		vreg_l1c_1p8: ldo1 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1980000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2c_1p62: ldo2 {
+			regulator-min-microvolt = <1620000>;
+			regulator-max-microvolt = <1980000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3c_2p8: ldo3 {
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <3540000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4c_1p62: ldo4 {
+			regulator-min-microvolt = <1620000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5c_1p62: ldo5 {
+			regulator-min-microvolt = <1620000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6c_2p96: ldo6 {
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7c_3p0: ldo7 {
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3544000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8c_1p62: ldo8 {
+			regulator-min-microvolt = <1620000>;
+			regulator-max-microvolt = <2000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9c_2p96: ldo9 {
+			regulator-min-microvolt = <2700000>;
+			regulator-max-microvolt = <3544000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l10c_0p88: ldo10 {
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <1050000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l11c_2p8: ldo11 {
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <3544000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l12c_1p65: ldo12 {
+			regulator-min-microvolt = <1650000>;
+			regulator-max-microvolt = <2000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l13c_2p7: ldo13 {
+			regulator-min-microvolt = <2700000>;
+			regulator-max-microvolt = <3544000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_bob_3p296: bob {
+			regulator-min-microvolt = <3008000>;
+			regulator-max-microvolt = <3960000>;
+		};
+	};
+};
+
+&gcc {
+	protected-clocks = <GCC_QSPI_CNOC_PERIPH_AHB_CLK>, <GCC_QSPI_CORE_CLK>,
+			<GCC_QSPI_CORE_CLK_SRC>, <GCC_CFG_NOC_LPASS_CLK>,
+			<GCC_MSS_GPLL0_MAIN_DIV_CLK_SRC>, <GCC_MSS_CFG_AHB_CLK>,
+			<GCC_MSS_OFFLINE_AXI_CLK>, <GCC_MSS_SNOC_AXI_CLK>,
+			<GCC_MSS_Q6_MEMNOC_AXI_CLK>, <GCC_MSS_Q6SS_BOOT_CLK_SRC>,
+			<GCC_SEC_CTRL_CLK_SRC>, <GCC_WPSS_AHB_CLK>,
+			<GCC_WPSS_AHB_BDG_MST_CLK>, <GCC_WPSS_RSCP_CLK>;
+};
+
+&gpu {
+	status = "okay";
+};
+
+&gpu_zap_shader {
+	firmware-name = "qcom/qcs6490/a660_zap.mbn";
+};
+
+&ipa {
+	status = "disabled";
+};
+
+&lpasscc {
+	status = "disabled";
+};
+
+&pm7325_gpios {
+	key_vol_up_default: key-vol-up-state {
+		pins = "gpio6";
+		function = "normal";
+		input-enable;
+		bias-pull-up;
+		power-source = <0>;
+		qcom,drive-strength = <3>;
+	};
+};
+
+&pm7325_temp_alarm {
+	io-channels = <&pmk8350_vadc PM7325_ADC7_DIE_TEMP>;
+	io-channel-names = "thermal";
+};
+
+&pm8350c_pwm {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	status = "okay";
+
+	led@1 {
+		reg = <1>;
+		color = <LED_COLOR_ID_RED>;
+		label = "red";
+	};
+
+	led@2 {
+		reg = <2>;
+		color = <LED_COLOR_ID_GREEN>;
+		label = "green";
+	};
+
+	led@3 {
+		reg = <3>;
+		color = <LED_COLOR_ID_BLUE>;
+		label = "blue";
+	};
+};
+
+&pmk8350_adc_tm {
+	status = "okay";
+
+	xo-therm@0 {
+		reg = <0>;
+		io-channels = <&pmk8350_vadc PMK8350_ADC7_AMUX_THM1_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time-us = <200>;
+	};
+
+	quiet-therm@1 {
+		reg = <1>;
+		io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM1_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time-us = <200>;
+	};
+
+	sdm-skin-therm@3 {
+		reg = <3>;
+		io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM3_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time-us = <200>;
+	};
+};
+
+&pmk8350_pon {
+	status = "okay";
+};
+
+&pmk8350_rtc {
+	status = "okay";
+	allow-set-time;
+};
+
+&pmk8350_vadc {
+	channel@44 {
+		reg = <PMK8350_ADC7_AMUX_THM1_100K_PU>;
+		label = "xo_therm";
+		qcom,hw-settle-time = <200>;
+		qcom,pre-scaling = <1 1>;
+		qcom,ratiometric;
+	};
+
+	channel@103 {
+		reg = <PM7325_ADC7_DIE_TEMP>;
+		label = "pm7325_die_temp";
+		qcom,pre-scaling = <1 1>;
+	};
+
+	channel@144 {
+		reg = <PM7325_ADC7_AMUX_THM1_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time = <200>;
+		qcom,pre-scaling = <1 1>;
+		label = "pm7325_quiet_therm";
+	};
+
+	channel@146 {
+		reg = <PM7325_ADC7_AMUX_THM3_100K_PU>;
+		qcom,ratiometric;
+		qcom,hw-settle-time = <200>;
+		qcom,pre-scaling = <1 1>;
+		label = "pm7325_sdm_skin_therm";
+	};
+
+	pmk8350-die-temp@3 {
+		reg = <PMK8350_ADC7_DIE_TEMP>;
+		label = "pmk8350_die_temp";
+		qcom,pre-scaling = <1 1>;
+	};
+};
+
+&pon_pwrkey {
+	status = "okay";
+};
+
+&pon_resin {
+	linux,code = <KEY_VOLUMEDOWN>;
+	status = "okay";
+};
+
+&mdss {
+	status = "okay";
+};
+
+&mdss_dsi {
+	vdda-supply = <&vreg_l6b_1p2>;
+	status = "okay";
+};
+
+&mdss_dsi_phy {
+	vdds-supply = <&vreg_l10c_0p88>;
+	status = "okay";
+};
+
+&qup_uart5_rx {
+	drive-strength = <2>;
+	bias-pull-up;
+};
+
+&qup_uart5_tx {
+	drive-strength = <2>;
+	bias-disable;
+};
+
+&gpi_dma0 {
+	status = "okay";
+};
+
+&gpi_dma1 {
+	status = "okay";
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&qupv3_id_1 {
+	status = "okay";
+};
+
+&remoteproc_adsp {
+	firmware-name = "qcom/qcs6490/adsp.mdt";
+	status = "okay";
+};
+
+&remoteproc_cdsp {
+	firmware-name = "qcom/qcs6490/cdsp.mdt";
+	status = "okay";
+};
+
+&remoteproc_mpss {
+	firmware-name = "qcom/qcs6490/modem.mdt";
+	status = "okay";
+};
+
+&remoteproc_wpss {
+	firmware-name = "qcom/qcs6490/wpss.mdt";
+	status = "okay";
+};
+
+&uart5 {
+	compatible = "qcom,geni-debug-uart";
+	status = "okay";
+};
+
+&ufs_mem_hc {
+	reset-gpios = <&tlmm 175 GPIO_ACTIVE_LOW>;
+	vcc-supply = <&vreg_l7b_2p952>;
+	vcc-max-microamp = <800000>;
+	vccq-supply = <&vreg_l9b_1p2>;
+	vccq-max-microamp = <900000>;
+	vccq2-supply = <&vreg_l9b_1p2>;
+	vccq2-max-microamp = <900000>;
+
+	status = "okay";
+};
+
+&ufs_mem_phy {
+	vdda-phy-supply = <&vreg_l10c_0p88>;
+	vdda-pll-supply = <&vreg_l6b_1p2>;
+
+	status = "okay";
+};
+
+&tlmm {
+	wifi_reset_active: wifi_reset_active {
+		pins = "gpio16";
+		function = "gpio";
+		drive-strength = <2>;
+		output-high;
+		bias-disable;
+	};
+
+	wifi_host_wake: wifi_host_wake {
+		pins = "gpio38";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+	};
+
+	wifi_power_on: wifi_power_on {
+		pins = "gpio125";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+	};
+};
+
+/ {
+	vreg_sdio_wifi_1p8: vreg_sdio_wifi_1p8 {
+		compatible = "regulator-fixed";
+		pinctrl-0 = <&wifi_reset_active>, <&wifi_host_wake>, <&wifi_power_on>;
+		pinctrl-names = "default";
+		regulator-name = "vreg_sdio_wifi_1p8";
+		enable-active-high;
+		gpio = <&tlmm 125 GPIO_ACTIVE_HIGH>;
+		regulator-always-on;
+		regulator-enable-ramp-delay = <50000>;
+	};
+
+	bcmdhd_wlan: bcmdhd_wlan {
+		status = "okay";
+		compatible = "linux,bcmdhd_wlan";
+		gpio_wl_reg_on = <&tlmm 16 GPIO_ACTIVE_HIGH>;
+		gpio_wl_host_wake = <&tlmm 38 GPIO_ACTIVE_HIGH>;
+		vdda-supply = <&vreg_sdio_wifi_1p8>;
+	};
+};
+
+&sdhc_2 {
+	status = "okay";
+
+	pinctrl-0 = <&sdc2_clk>, <&sdc2_cmd>, <&sdc2_data>;
+	pinctrl-1 = <&sdc2_clk_sleep>, <&sdc2_cmd_sleep>, <&sdc2_data_sleep>;
+
+	vmmc-supply = <&vreg_l9c_2p96>;
+	vqmmc-supply = <&vreg_l6c_2p96>;
+
+	non-removable;
+	keep-power-in-suspend;
+
+	/delete-property/ cd-gpios;
+};
+
+/delete-node/ &usb_1_dwc3;
+
+&usb_1 {
+
+	reg = <0x0 0x0a600000 0x0 0x200000>;
+
+	interrupts-extended = <&intc GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
+			      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+			      <&pdc 14 IRQ_TYPE_LEVEL_HIGH>,
+			      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
+			      <&pdc 17 IRQ_TYPE_EDGE_BOTH>;
+	interrupt-names = "dwc_usb3",
+			  "hs_phy_irq",
+			  "dp_hs_phy_irq",
+			  "dm_hs_phy_irq",
+			  "ss_phy_irq";
+
+	iommus = <&apps_smmu 0xe0 0x0>;
+	snps,dis_u2_susphy_quirk;
+	snps,dis_enblslpm_quirk;
+	phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
+	phy-names = "usb2-phy", "usb3-phy";
+	maximum-speed = "super-speed";
+	snps,dis-u2-entry-quirk;
+	snps,dis-u1-entry-quirk;
+	dr_mode = "otg";
+	usb-role-switch;
+	qcom,enable-rt;
+	wakeup-source;
+
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			reg = <0>;
+			usb_1_dwc3_hs: endpoint {
+			};
+		};
+	};
+};
+
+&usb_1_dwc3_hs {
+	remote-endpoint = <&pmic_glink_hs_in>;
+};
+
+&usb_1_hsphy {
+	vdda-pll-supply = <&vreg_l10c_0p88>;
+	vdda18-supply = <&vreg_l1c_1p8>;
+	vdda33-supply = <&vreg_l2b_3p072>;
+
+	status = "okay";
+};
+
+&usb_1_qmpphy {
+	vdda-phy-supply = <&vreg_l6b_1p2>;
+	vdda-pll-supply = <&vreg_l1b_0p912>;
+
+	orientation-switch;
+	status = "okay";
+};
+
+&vreg_l7b_2p952 {
+	/delete-property/regulator-min-microvolt;
+	/delete-property/regulator-max-microvolt;
+	regulator-allow-set-load;
+	regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM RPMH_REGULATOR_MODE_HPM>;
+};
+
+&vreg_l9b_1p2 {
+	/delete-property/regulator-min-microvolt;
+	/delete-property/regulator-max-microvolt;
+	regulator-allow-set-load;
+	regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM RPMH_REGULATOR_MODE_HPM>;
+};
+
+/*     USB2 Related Start        */
+/*==============================*/
+
+&pm7325_gpios {
+	usb2_vbus_det_default: usb2_vbus_det_state {
+		pins = "gpio9";
+		function = "normal";
+		bias-pull-down;
+		input-enable;
+		power-source = <0>;
+	};
+};
+
+&sdc2_clk {
+	bias-disable;
+	drive-strength = <16>;
+};
+
+&sdc2_cmd {
+	bias-pull-up;
+	drive-strength = <10>;
+};
+
+&sdc2_data {
+	bias-pull-up;
+	drive-strength = <10>;
+};
+
+&tlmm {
+	usb2_1p8_vreg_default: usb2_1p8_vreg_default {
+		pins = "gpio119";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+		output-high;
+	};
+};
+
+/delete-node/ &usb_2_dwc3;
+
+&usb_2 {
+	pinctrl-0 = <&usb2_1p8_vreg_default>;
+	pinctrl-names = "default";
+
+	reg = <0x0 0x08c00000 0x0 0x100000>;
+
+	interrupts-extended = <&intc GIC_SPI 242 IRQ_TYPE_LEVEL_HIGH>,
+				<&intc GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+				<&pdc 12 IRQ_TYPE_LEVEL_HIGH>,
+				<&pdc 13 IRQ_TYPE_EDGE_BOTH>;
+	interrupt-names = "dwc_usb2",
+			"hs_phy_irq",
+			"dp_hs_phy_irq",
+			"dm_hs_phy_irq";
+
+	iommus = <&apps_smmu 0xa0 0x0>;
+	snps,dis_u2_susphy_quirk;
+	snps,dis_enblslpm_quirk;
+	phys = <&usb_2_hsphy>;
+	phy-names = "usb2-phy";
+	maximum-speed = "high-speed";
+	snps,dis-u2-entry-quirk;
+	snps,dis-u1-entry-quirk;
+
+	usb-role-switch;
+	qcom,enable-rt;
+	wakeup-source;
+	dr_mode = "host";
+
+	status = "okay";
+
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		port@0 {
+			usb2_role_switch: endpoint {
+				remote-endpoint = <&eud_ep>;
+			};
+		};
+	};
+};
+
+&usb_2_hsphy {
+	vdda-pll-supply = <&vreg_l10c_0p88>;
+	vdda18-supply = <&vreg_l1c_1p8>;
+	vdda33-supply = <&vreg_l2b_3p072>;
+
+	status = "okay";
+};
+
+&spmi_bus {
+	pmic@PM7250B_SID {
+		pm7250b_bcl: bcl@1d00 {
+			compatible = "qcom,bcl-v5";
+			reg = <0x1d00>;
+			interrupts = <PM7250B_SID 0x1d 0x0 IRQ_TYPE_EDGE_RISING>,
+					<PM7250B_SID 0x1d 0x1 IRQ_TYPE_EDGE_RISING>,
+					<PM7250B_SID 0x1d 0x2 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "bcl-lvl0",
+						"bcl-lvl1",
+						"bcl-lvl2";
+			#thermal-sensor-cells = <1>;
+		};
+	};
+};
+
+&thermal_zones {
+	pm7250b-ibat-lvl0 {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 0>;
+
+		trips {
+			ibat_lvl0:ibat-lvl0 {
+				temperature = <6000>;
+				hysteresis = <200>;
+				type = "passive";
+			};
+		};
+	};
+
+	pm7250b-ibat-lvl1 {
+		polling-delay-passive = <0>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 1>;
+
+		trips {
+			ibat_lvl1:ibat-lvl1 {
+				temperature = <7500>;
+				hysteresis = <200>;
+				type = "passive";
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl0 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 5>;
+
+		trips {
+			b_bcl_lvl0: b-bcl-lvl0 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU4_idle 100 100>;
+			};
+
+			map1 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU5_idle 100 100>;
+			};
+
+			map2 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU6_idle 100 100>;
+			};
+
+			map3 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&CPU7_idle 100 100>;
+			};
+
+			map4 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&cdsp_sw 2 2>;
+			};
+
+			map5 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&modem_pa 2 2>;
+			};
+
+			map6 {
+				trip = <&b_bcl_lvl0>;
+				cooling-device = <&modem_tj 1 1>;
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl1 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 6>;
+
+		trips {
+			b_bcl_lvl1: b-bcl-lvl1 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&b_bcl_lvl1>;
+				cooling-device = <&msm_gpu 5 THERMAL_NO_LIMIT>;
+			};
+
+			map1 {
+				trip = <&b_bcl_lvl1>;
+				cooling-device = <&cdsp_sw 4 4>;
+			};
+
+			map2 {
+				trip = <&b_bcl_lvl1>;
+				cooling-device = <&modem_tj 3 3>;
+			};
+		};
+	};
+
+	pm7250b-bcl-lvl2 {
+		polling-delay-passive = <100>;
+		polling-delay = <0>;
+		thermal-sensors = <&pm7250b_bcl 7>;
+
+		trips {
+			b_bcl_lvl2: b-bcl-lvl2 {
+				temperature = <1>;
+				hysteresis = <1>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&b_bcl_lvl2>;
+				cooling-device = <&cdsp_sw 5 5>;
+			};
+		};
+	};
+};
+
+/ {
+	vreg_usb_hub0_1p8: vreg_usb_hub0_1p8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vreg_usb_hub0_1p8";
+		gpio = <&tlmm 86 0>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		enable-active-high;
+		regulator-always-on;
+		regulator-enable-ramp-delay = <50000>;
+	};
+
+	vreg_usb_eth_1p8: vreg_usb_eth_1p8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vreg_usb_eth_1p8";
+		gpio = <&tlmm 7 0>;
+		vin-supply = <&vreg_usb_hub0_1p8>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		enable-active-high;
+		regulator-enable-ramp-delay = <50000>;
+	};
+
+	vreg_usb_hub0_rest: vreg_usb_hub0_rest {
+		compatible = "regulator-fixed";
+		regulator-name = "vreg_usb_hub0_rest";
+		gpio = <&tlmm 136 0>;
+		vin-supply = <&vreg_usb_eth_1p8>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		enable-active-high;
+		regulator-always-on;
+		regulator-enable-ramp-delay = <50000>;
+	};
+};
+
+&pcie0 {
+	perst-gpios = <&tlmm 87 GPIO_ACTIVE_LOW>;
+	pinctrl-0 = <&pcie0_reset_n>, <&pcie0_wake_n>, <&pcie0_clkreq_n>;
+	pinctrl-names = "default";
+	status = "okay";
+	vdda-supply = <&vreg_usb_hub0_rest>;
+};
+
+&pcie0_phy {
+	status = "okay";
+	vdda-phy-supply = <&vreg_l10c_0p88>;
+	vdda-pll-supply = <&vreg_l6b_1p2>;
+};
+
+&tlmm {
+	pcie1_reset_n: pcie1-reset-n-state {
+		pins = "gpio2";
+		function = "gpio";
+		drive-strength = <16>;
+		output-low;
+		bias-disable;
+	};
+
+	pcie1_wake_n: pcie1-wake-n-state {
+		pins = "gpio3";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-up;
+	};
+};
+
+/ {
+	vreg_m2_1p8: verg_m2_1p8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vreg_m2_1p8";
+		gpio = <&tlmm 56 0>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		enable-active-high;
+		regulator-enable-ramp-delay = <50000>;
+	};
+};
+
+&pcie1 {
+	perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+
+	pinctrl-0 = <&pcie1_reset_n>, <&pcie1_wake_n>, <&pcie1_clkreq_n>;
+	pinctrl-names = "default";
+
+	vdda-supply = <&vreg_m2_1p8>;
+
+	status = "okay";
+
+	pcieport1: pcie@1 {
+		device_type = "pci";
+		reg = <0x0 0x0 0x0 0x0 0x0>;
+		#address-cells = <5>;
+		#size-cells = <0>;
+		pcie1_bus1_dev0_fn0: pcie1_bus1_dev0_fn0 {
+			reg = <0 0 0 0 0>;
+		};
+	};
+};
+
+&pcie1_phy {
+	vdda-phy-supply = <&vreg_l10c_0p88>;
+	vdda-pll-supply = <&vreg_l6b_1p2>;
+
+	status = "okay";
+};
+
+/ {
+	fan0: pwm-fan {
+		compatible = "pwm-fan";
+		pwms = <&pm8350c_pwm 3 1000000>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&fan_pwm_out_default>;
+	};
+};
+
+&pm8350c_gpios {
+	fan_pwm_out_default: fan_pwm_out_default {
+		pins = "gpio8";
+		function = "func1";
+		power-source = <1>;
+		drive-push-pull;
+		output-high;
+		qcom,drive-strength = <3>;
+	};
+};
+
+&tlmm {
+	qup_uart7_sleep_cts: qup-uart7-sleep-cts-state {
+		pins = "gpio28";
+		function = "gpio";
+		/*
+		 * Configure a bias-bus-hold on CTS to lower power
+		 * usage when Bluetooth is turned off. Bus hold will
+		 * maintain a low power state regardless of whether
+		 * the Bluetooth module drives the pin in either
+		 * direction or leaves the pin fully unpowered.
+		 */
+		bias-bus-hold;
+	};
+
+	qup_uart7_sleep_rts: qup-uart7-sleep-rts-state {
+		pins = "gpio29";
+		function = "gpio";
+		/*
+		 * Configure pull-down on RTS. As RTS is active low
+		 * signal, pull it low to indicate the BT SoC that it
+		 * can wakeup the system anytime from suspend state by
+		 * pulling RX low (by sending wakeup bytes).
+		 */
+		bias-pull-down;
+	};
+
+	qup_uart7_sleep_rx: qup-uart7-sleep-rx-state {
+		pins = "gpio31";
+		function = "gpio";
+		/*
+		 * Configure a pull-up on RX. This is needed to avoid
+		 * garbage data when the TX pin of the Bluetooth module
+		 * is floating which may cause spurious wakeups.
+		 */
+		bias-pull-up;
+	};
+
+	qup_uart7_sleep_tx: qup-uart7-sleep-tx-state {
+		pins = "gpio30";
+		function = "gpio";
+		/*
+		 * Configure pull-up on TX when it isn't actively driven
+		 * to prevent BT SoC from receiving garbage during sleep.
+		 */
+		bias-pull-up;
+	};
+};
+
+&tlmm {
+	bt_device_wake: bt_device_wake {
+		pins = "gpio39";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+	};
+
+	bt_host_wake: bt_host_wake {
+		pins = "gpio137";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+	};
+
+	bt_reset: bt_reset {
+		pins = "gpio17";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+	};
+};
+
+&uart7 {
+	status = "okay";
+	/delete-property/interrupts;
+	interrupts-extended = <&intc GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>,
+				<&tlmm 31 IRQ_TYPE_EDGE_FALLING>;
+	pinctrl-names = "default", "sleep";
+	pinctrl-1 = <&qup_uart7_sleep_cts>, <&qup_uart7_sleep_rts>,
+			<&qup_uart7_sleep_tx>, <&qup_uart7_sleep_rx>;
+
+	bluetooth {
+		compatible = "brcm,bcm4345c5";
+		clocks = <&sleep_clk>;
+		clock-names = "lpo";
+		device-wakeup-gpios = <&tlmm 39 GPIO_ACTIVE_HIGH>;
+		host-wakeup-gpios = <&tlmm 137 GPIO_ACTIVE_HIGH>;
+		reset-gpios = <&tlmm 17 GPIO_ACTIVE_LOW>;
+		pinctrl-0 = <&bt_device_wake>, <&bt_host_wake>, <&bt_reset>;
+		pinctrl-names = "default";
+		vbat-supply = <&vreg_sdio_wifi_1p8>;
+		vddio-supply = <&vreg_sdio_wifi_1p8>;
+	};
+};
+
+/ {
+	hdmi-connector {
+		compatible = "hdmi-connector";
+		type = "a";
+		port {
+			hdmi_con: endpoint {
+				remote-endpoint = <&lt9611_out>;
+			};
+		};
+	};
+};
+
+&soc {
+	vreg_lt9611_3p3: lt9611-3p3-vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "vreg_lt9611_3p3";
+		gpio = <&tlmm 83 0>;
+		regulator-min-microvolt = <3300000>;
+		regulator-max-microvolt = <3300000>;
+		enable-active-high;
+		regulator-enable-ramp-delay = <10000>;
+	};
+};
+
+&apps_rsc {
+	regulators-0 {
+		vreg_l6b_1p2: ldo6 {
+			regulator-min-microvolt = <1140000>;
+			regulator-max-microvolt = <1260000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+	regulators-1 {
+		vreg_l10c_0p88: ldo10 {
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <1050000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&i2c9 {
+	status = "okay";
+	lt9611_codec: hdmi-bridge@39 {
+		compatible = "lontium,lt9611";
+		reg = <0x39>;
+		interrupts-extended = <&tlmm 20 IRQ_TYPE_EDGE_BOTH>;
+		reset-gpios = <&tlmm 21 0>;
+		enable-gpios = <&tlmm 40 0>;
+		ocb-gpios = <&tlmm 41 0>;
+		vcc-supply = <&vreg_lt9611_3p3>;
+		config-mode = "edidAdaptiveResolution";
+		ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			port@0 {
+				reg = <0>;
+				lt9611_a: endpoint {
+					remote-endpoint = <&mdss_dsi0_out>;
+				};
+			};
+			port@2 {
+				reg = <2>;
+				lt9611_out: endpoint {
+					remote-endpoint = <&hdmi_con>;
+				};
+			};
+		};
+	};
+};
+
+&mdss_dsi0_out {
+	remote-endpoint = <&lt9611_a>;
+	data-lanes = <0 1 2 3>;
+};
+
+&q6apmbedai {
+	qcom,prmcc_clk = <&q6prmcc>;
+};
+
+&lpass_va_macro {
+	status = "disabled";
+};
+
+&lpass_rx_macro {
+	status = "disabled";
+};
+
+&lpass_tx_macro {
+	status = "disabled";
+};
+
+&lpass_wsa_macro {
+	status = "disabled";
+};
+
+&swr0 {
+	status = "disabled";
+};
+
+&swr1 {
+	status = "disabled";
+};
+
+&swr2 {
+	status = "disabled";
+};
+
+&tlmm {
+	mi2s0_data0_sleep: mi2s0-data0-sleep {
+		pins = "gpio98";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_data1_sleep: mi2s0-data1-sleep {
+		pins = "gpio99";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_sclk_sleep: mi2s0-sclk-sleep {
+		pins = "gpio97";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s0_ws_sleep: mi2s0-ws-sleep {
+		pins = "gpio100";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+};
+
+&mi2s0_data0 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_data1 {
+	drive-strength = <8>;
+	bias-disable;
+};
+
+&mi2s0_sclk {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&mi2s0_ws {
+	drive-strength = <8>;
+	bias-disable;
+	output-high;
+};
+
+&i2c0 {
+	status = "ok";
+	es8316: es8316@11 {
+		compatible = "everest,es8316";
+		reg = <0x11>;
+		#sound-dai-cells = <0>;
+		power_en-gpio = <&tlmm 117 0>;
+		irq-gpio = <&tlmm 63 0>;
+		status = "ok";
+	};
+};
+
+&lpass_tlmm {
+	lpass_ext_mas_clk1_a: ext-master-clk1-a-state {
+		pins = "gpio13";
+		function = "ext_mas_clk1_a";
+	};
+
+	lpass_ext_mas_clk1_a_sleep: ext-master-clk1-a-sleep {
+		pins = "gpio13";
+		function = "ext_mas_clk1_a";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	lpass_qua_mi2s_sclk: qua-mi2s-sclk-state {
+		pins = "gpio0";
+		function = "qua_mi2s_sclk";
+	};
+
+	lpass_qua_mi2s_sclk_sleep: qua-mi2s-sclk-sleep {
+		pins = "gpio0";
+		function = "qua_mi2s_sclk";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	lpass_qua_mi2s_ws: qua-mi2s-ws-state {
+		pins = "gpio1";
+		function = "qua_mi2s_ws";
+	};
+
+	lpass_qua_mi2s_ws_sleep: qua-mi2s-ws-sleep {
+		pins = "gpio1";
+		function = "qua_mi2s_ws";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	lpass_qua_mi2s_data0: qua-mi2s-data0-state {
+		pins = "gpio2";
+		function = "qua_mi2s_data";
+	};
+
+	lpass_qua_mi2s_data0_sleep: qua-mi2s-data0-sleep {
+		pins = "gpio2";
+		function = "qua_mi2s_data";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	lpass_qua_mi2s_data1: qua-mi2s-data1-state {
+		pins = "gpio3";
+		function = "qua_mi2s_data";
+	};
+
+	lpass_qua_mi2s_data1_sleep: qua-mi2s-data1-sleep {
+		pins = "gpio3";
+		function = "qua_mi2s_data";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	lpass_qua_mi2s_data2: qua-mi2s-data2-state {
+		pins = "gpio4";
+		function = "qua_mi2s_data";
+	};
+
+	lpass_qua_mi2s_data2_sleep: qua-mi2s-data2-sleep {
+		pins = "gpio4";
+		function = "qua_mi2s_data";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	lpass_qua_mi2s_data3: qua-mi2s-data3-state {
+		pins = "gpio5";
+		function = "qua_mi2s_data";
+	};
+
+	lpass_qua_mi2s_data3_sleep: qua-mi2s-data3-sleep {
+		pins = "gpio5";
+		function = "qua_mi2s_data";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+};
+
+/ {
+	sound: sound {
+		compatible = "qcom,qcm6490-sndcard";
+		model = "qcm6490-idp-snd-card";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pinctrl-names = "default", "stub_aif0_active", "stub_aif0_sleep";
+		pinctrl-0 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk>,
+					<&mi2s0_sclk_sleep>, <&mi2s0_ws_sleep>,
+					<&lpass_ext_mas_clk1_a_sleep>, <&lpass_qua_mi2s_sclk_sleep>,
+					<&lpass_qua_mi2s_ws_sleep>, <&lpass_qua_mi2s_data0_sleep>,
+					<&lpass_qua_mi2s_data1_sleep>, <&lpass_qua_mi2s_data2_sleep>,
+					<&lpass_qua_mi2s_data3_sleep>;
+		pinctrl-1 = <&mi2s0_data0>, <&mi2s0_data1>, <&mi2s0_mclk>,
+					<&mi2s0_sclk>, <&mi2s0_ws>,
+					<&lpass_ext_mas_clk1_a>, <&lpass_qua_mi2s_sclk>,
+					<&lpass_qua_mi2s_ws>, <&lpass_qua_mi2s_data0>,
+					<&lpass_qua_mi2s_data1>, <&lpass_qua_mi2s_data2>,
+					<&lpass_qua_mi2s_data3>;
+		pinctrl-2 = <&mi2s0_data0_sleep>, <&mi2s0_data1_sleep>, <&mi2s0_mclk>,
+					<&mi2s0_sclk_sleep>, <&mi2s0_ws_sleep>,
+					<&lpass_ext_mas_clk1_a_sleep>, <&lpass_qua_mi2s_sclk_sleep>,
+					<&lpass_qua_mi2s_ws_sleep>, <&lpass_qua_mi2s_data0_sleep>,
+					<&lpass_qua_mi2s_data1_sleep>, <&lpass_qua_mi2s_data2_sleep>,
+					<&lpass_qua_mi2s_data3_sleep>;
+
+		mi2s-playback-dai-link {
+			link-name = "MI2S-LPAIF-RX-PRIMARY";
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+			};
+			codec {
+				sound-dai = <&msm_stub_codec 0>, <&es8316>;
+			};
+		};
+
+		mi2s-capture-dai-link {
+			link-name = "MI2S-LPAIF-TX-PRIMARY";
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>;
+			};
+			codec {
+				sound-dai = <&msm_stub_codec 1>, <&es8316>;
+			};
+		};
+
+		quaternary-mi2s-playback-dai-link {
+			link-name = "MI2S-LPAIF_RXTX-RX-PRIMARY";
+			cpu {
+				sound-dai = <&q6apmbedai QUATERNARY_MI2S_RX>;
+			};
+			codec {
+				sound-dai = <&msm_stub_codec 0>;
+			};
+		};
+	};
+};
+
+&uart2 {
+	status = "okay";
+};
+
+&i2c1 {
+	status = "okay";
+};
+
+&tlmm {
+	/delete-property/ gpio-reserved-ranges;
+};
+
+&spi12 {
+	status = "okay";
+	spidev@0 {
+		compatible = "silabs,em3581";
+		spi-max-frequency = <50000000>;
+		reg = <0>;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa7255p-ride.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa7255p-ride.dts
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "sa7255p.dtsi"
+#include "sa7255p-scmi.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SA7255P Ride";
+	compatible = "qcom,sa7255p-ride","qcom,sa7255p";
+	qcom,msm-id = <606 0x10000>;
+	qcom,board-id = <0x10019 0>, <0x1010019 1>;
+
+	aliases {
+		i2c8 = &i2c8;
+		i2c15 = &i2c15;
+		serial0 = &uart7;
+		serial1 = &uart12;
+		spi10 = &spi10;
+		scmichannels = &scmichannels;
+		ufshc1 = &ufs_mem_hc;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&adreno_smmu {
+	power-domains = <&scmi15_pd 0>;
+
+	status = "okay";
+};
+
+&gpll0_board_clk {
+	clock-frequency = <300000000>;
+};
+
+&i2c8 {
+	clock-frequency = <400000>;
+	power-domains = <&scmi9_pd 8>;
+
+	status = "okay";
+};
+
+&i2c15 {
+	clock-frequency = <400000>;
+	power-domains = <&scmi9_pd 15>;
+
+	status = "okay";
+};
+
+&pcie0 {
+	power-domains = <&scmi5_pd 0>;
+	power-domain-names = "power";
+	status = "okay";
+};
+
+&pcie1 {
+	power-domains = <&scmi6_pd 0>;
+	power-domain-names = "power";
+	status = "okay";
+};
+
+&pcie0_ep {
+	#dma-cells = <1>;
+	dmas = <&pcie0_ep 0>, <&pcie0_ep 1>;
+	dma-names = "rx", "tx";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_ep_clkreq_default &pcie0_ep_perst_default
+		    &pcie0_ep_wake_default>;
+
+	reset-gpio = <&tlmm 2 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
+
+	power-domains = <&scmi5_pd 1>;
+	power-domain-names = "power";
+
+	status = "disabled";
+};
+
+&pcie1_ep {
+	#dma-cells = <1>;
+	dmas = <&pcie1_ep 0>, <&pcie1_ep 1>;
+	dma-names = "rx", "tx";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_ep_clkreq_default &pcie1_ep_perst_default
+		    &pcie1_ep_wake_default>;
+
+	reset-gpio = <&tlmm 23 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+
+	power-domains = <&scmi6_pd 1>;
+	power-domain-names = "power";
+
+	status = "disabled";
+};
+
+&tlmm {
+		pcie0_ep_perst_default: pcie-ep-perst-default-state {
+			pins = "gpio2";
+			function = "gpio";
+			drive-strength = <16>;
+			bias-pull-down;
+		};
+
+		pcie0_ep_wake_default: pcie-ep-wake-default-state {
+			pins = "gpio0";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-disable;
+		};
+
+		pcie0_ep_clkreq_default: pcie-ep-clkreq-default-state {
+			pins = "gpio1";
+			function = "pcie0_clkreq";
+			drive-strength = <2>;
+			bias-disable;
+		};
+
+		pcie1_ep_perst_default: pcie-ep-perst-default-state {
+			pins = "gpio23";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+
+		pcie1_ep_wake_default: pcie-ep-wake-default-state {
+			pins = "gpio21";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-disable;
+		};
+
+		pcie1_ep_clkreq_default: pcie-ep-clkreq-default-state {
+			pins = "gpio22";
+			function = "pcie1_clkreq";
+			drive-strength = <2>;
+			bias-disable;
+		};
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&qupv3_id_1 {
+	status = "okay";
+};
+
+&qupv3_id_3 {
+	status = "okay";
+};
+
+&scmi0 {
+	status = "okay";
+};
+
+&scmi2 {
+	status = "okay";
+};
+
+&scmi3 {
+	status = "okay";
+};
+
+&scmi5 {
+	status = "okay";
+};
+
+&scmi6 {
+	status = "okay";
+};
+
+&scmi9 {
+	status = "okay";
+};
+
+&scmi10 {
+	status = "okay";
+};
+
+&scmi11 {
+	status = "okay";
+};
+
+&scmi12 {
+	status = "okay";
+};
+
+&scmi14 {
+	status = "okay";
+};
+
+&scmi15 {
+	status = "okay";
+};
+
+&sleep_clk {
+	clock-frequency = <32000>;
+};
+
+&spi10 {
+	power-domains = <&scmi10_pd 10>, <&scmi10_dvfs 10>;
+	power-domain-names = "power", "perf";
+
+	status = "okay";
+};
+
+&uart7 {
+	power-domains = <&scmi11_pd 7>, <&scmi11_dvfs 7>;
+	power-domain-names = "power", "perf";
+
+	status = "okay";
+};
+
+&uart12 {
+	power-domains = <&scmi11_pd 12>, <&scmi11_dvfs 12>;
+	power-domain-names = "power", "perf";
+
+	status = "okay";
+};
+
+&ufs_mem_hc {
+	reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>;
+	power-domains = <&scmi3_pd 0>;
+
+	status = "okay";
+};
+
+&usb_0 {
+	power-domains = <&scmi0_pd 0>, <&scmi0_pd 1>;
+	power-domain-names = "usb_transfer", "usb_core";
+
+	status = "okay";
+};
+
+&usb_0_dwc3 {
+	dr_mode = "peripheral";
+};
+
+&usb_0_hsphy {
+	power-domains = <&scmi12_pd 0>, <&scmi12_pd 1>;
+	power-domain-names = "usb_transfer", "usb_core";
+
+	status = "okay";
+};
+
+&usb_0_qmpphy {
+	power-domains = <&scmi12_pd 2>, <&scmi12_pd 3>;
+	power-domain-names = "usb_transfer", "usb_core";
+
+	status = "okay";
+};
+
+&usb_1 {
+	power-domains = <&scmi2_pd 0>, <&scmi2_pd 1>;
+	power-domain-names = "usb_transfer", "usb_core";
+
+	status = "okay";
+};
+
+&usb_1_dwc3 {
+	dr_mode = "host";
+};
+
+&usb_1_hsphy {
+	power-domains = <&scmi14_pd 0>, <&scmi14_pd 1>;
+	power-domain-names = "usb_transfer", "usb_core";
+
+	status = "okay";
+};
+
+&xo_board_clk {
+	clock-frequency = <38400000>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa7255p-scmi.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa7255p-scmi.dtsi
@@ -0,0 +1,2184 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+&firmware {
+	scmi0: scmi-0 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem0>;
+
+		interrupts = <GIC_SPI 963 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi0_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi0_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi0_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi1: scmi-1 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem1>;
+
+		interrupts = <GIC_SPI 964 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi1_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi1_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi1_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi2: scmi-2 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem2>;
+
+		interrupts = <GIC_SPI 965 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi2_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi2_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi2_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi3: scmi-3 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem3>;
+
+		interrupts = <GIC_SPI 966 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi3_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi3_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi3_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi4: scmi-4 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem4>;
+
+		interrupts = <GIC_SPI 967 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi4_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi4_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi4_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi5: scmi-5 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem5>;
+
+		interrupts = <GIC_SPI 968 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi5_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi5_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi5_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi6: scmi-6 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem6>;
+
+		interrupts = <GIC_SPI 969 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi6_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi6_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi6_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi7: scmi-7 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem7>;
+
+		interrupts = <GIC_SPI 970 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi7_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi7_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi7_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi8: scmi-8 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem8>;
+
+		interrupts = <GIC_SPI 971 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi8_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi8_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi8_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi9: scmi-9 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem9>;
+
+		interrupts = <GIC_SPI 972 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi9_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi9_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi9_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi10: scmi-10 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem10>;
+
+		interrupts = <GIC_SPI 973 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi10_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi10_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi10_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi11: scmi-11 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem11>;
+
+		interrupts = <GIC_SPI 974 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi11_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi11_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi11_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi12: scmi-12 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem12>;
+
+		interrupts = <GIC_SPI 975 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi12_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi12_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi12_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi13: scmi-13 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem13>;
+
+		interrupts = <GIC_SPI 976 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi13_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi13_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi13_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi14: scmi-14 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem14>;
+
+		interrupts = <GIC_SPI 977 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi14_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi14_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi14_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi15: scmi-15 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem15>;
+
+		interrupts = <GIC_SPI 978 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi15_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi15_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi15_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi16: scmi-16 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem16>;
+
+		interrupts = <GIC_SPI 979 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi16_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi16_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi16_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi17: scmi-17 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem17>;
+
+		interrupts = <GIC_SPI 980 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi17_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi17_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi17_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi18: scmi-18 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem18>;
+
+		interrupts = <GIC_SPI 981 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi18_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi18_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi18_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi19: scmi-19 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem19>;
+
+		interrupts = <GIC_SPI 982 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi19_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi19_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi19_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi20: scmi-20 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem20>;
+
+		interrupts = <GIC_SPI 983 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi20_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi20_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi20_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi21: scmi-21 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem21>;
+
+		interrupts = <GIC_SPI 984 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi21_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi21_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi21_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi22: scmi-22 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem22>;
+
+		interrupts = <GIC_SPI 985 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi22_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi22_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi22_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi23: scmi-23 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem23>;
+
+		interrupts = <GIC_SPI 986 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi23_sensor: protocol@15 {
+			reg = <0x15>;
+			#thermal-sensor-cells = <1>;
+		};
+	};
+
+	scmi24: scmi-24 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem24>;
+
+		interrupts = <GIC_SPI 987 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi24_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi24_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi24_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi25: scmi-25 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem25>;
+
+		interrupts = <GIC_ESPI 0 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi25_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi25_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi25_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi26: scmi-26 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem26>;
+
+		interrupts = <GIC_ESPI 1 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi26_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi26_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi26_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi27: scmi-27 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem27>;
+
+		interrupts = <GIC_ESPI 2 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi27_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi27_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi27_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi28: scmi-28 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem28>;
+
+		interrupts = <GIC_ESPI 3 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi28_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi28_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi28_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi29: scmi-29 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem29>;
+
+		interrupts = <GIC_ESPI 4 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi29_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi29_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi29_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi30: scmi-30 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem30>;
+
+		interrupts = <GIC_ESPI 5 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi30_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi30_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi30_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi31: scmi-31 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem31>;
+
+		interrupts = <GIC_ESPI 6 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi31_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi31_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi31_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi32: scmi-32 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem32>;
+
+		interrupts = <GIC_ESPI 7 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi32_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi32_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi32_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi33: scmi-33 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem33>;
+
+		interrupts = <GIC_ESPI 8 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi33_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi33_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi33_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi34: scmi-34 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem34>;
+
+		interrupts = <GIC_ESPI 9 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi34_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi34_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi34_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi35: scmi-35 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem35>;
+
+		interrupts = <GIC_ESPI 10 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi35_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi35_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi35_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi36: scmi-36 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem36>;
+
+		interrupts = <GIC_ESPI 11 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi36_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi36_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi36_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi37: scmi-37 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem37>;
+
+		interrupts = <GIC_ESPI 12 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi37_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi37_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi37_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi38: scmi-38 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem38>;
+
+		interrupts = <GIC_ESPI 13 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi38_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi38_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi38_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi39: scmi-39 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem39>;
+
+		interrupts = <GIC_ESPI 14 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi39_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi39_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi39_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi40: scmi-40 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem40>;
+
+		interrupts = <GIC_ESPI 15 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi40_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi40_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi40_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi41: scmi-41 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem41>;
+
+		interrupts = <GIC_ESPI 16 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi41_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi41_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi41_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi42: scmi-42 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem42>;
+
+		interrupts = <GIC_ESPI 17 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi42_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi42_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi42_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi43: scmi-43 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem43>;
+
+		interrupts = <GIC_ESPI 18 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi43_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi43_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi43_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi44: scmi-44 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem44>;
+
+		interrupts = <GIC_ESPI 19 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi44_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi44_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi44_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi45: scmi-45 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem45>;
+
+		interrupts = <GIC_ESPI 20 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi45_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi45_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi45_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi46: scmi-46 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem46>;
+
+		interrupts = <GIC_ESPI 21 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi46_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi46_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi46_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi47: scmi-47 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem47>;
+
+		interrupts = <GIC_ESPI 22 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi47_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi47_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi47_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi48: scmi-48 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem48>;
+
+		interrupts = <GIC_ESPI 23 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi48_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi48_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi48_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi49: scmi-49 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem49>;
+
+		interrupts = <GIC_ESPI 24 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi49_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi49_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi49_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi50: scmi-50 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem50>;
+
+		interrupts = <GIC_ESPI 25 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi50_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi50_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi50_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi51: scmi-51 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem51>;
+
+		interrupts = <GIC_ESPI 26 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi51_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi51_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi51_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi52: scmi-52 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem52>;
+
+		interrupts = <GIC_ESPI 27 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi52_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi52_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi52_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi53: scmi-53 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem53>;
+
+		interrupts = <GIC_ESPI 28 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi53_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi53_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi53_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi54: scmi-54 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem54>;
+
+		interrupts = <GIC_ESPI 29 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi54_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi54_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi54_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi55: scmi-55 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem55>;
+
+		interrupts = <GIC_ESPI 30 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi55_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi55_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi55_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi56: scmi-56 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem56>;
+
+		interrupts = <GIC_ESPI 31 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi56_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi56_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi56_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi57: scmi-57 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem57>;
+
+		interrupts = <GIC_ESPI 32 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi57_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi57_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi57_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi58: scmi-58 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem58>;
+
+		interrupts = <GIC_ESPI 33 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi58_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi58_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi58_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi59: scmi-59 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem59>;
+
+		interrupts = <GIC_ESPI 34 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi59_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi59_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi59_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi60: scmi-60 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem60>;
+
+		interrupts = <GIC_ESPI 35 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi60_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi60_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi60_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi61: scmi-61 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem61>;
+
+		interrupts = <GIC_ESPI 36 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi61_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi61_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi61_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi62: scmi-62 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem62>;
+
+		interrupts = <GIC_ESPI 37 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi62_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi62_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi62_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi63: scmi-63 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem63>;
+
+		interrupts = <GIC_ESPI 38 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		status = "disabled";
+
+		scmi63_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi63_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi63_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+};
+
+&soc {
+	scmichannels: sram@d0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "mmio-sram";
+		reg = <0x0 0xd0000000 0x0 0x40000>;
+		ranges = <0x0 0x0 0x0 0xffffffff>;
+
+		shmem0: scmi-sram@d0000000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0000000 0x1000>;
+		};
+
+		shmem1: scmi-sram@d0001000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0001000 0x1000>;
+		};
+
+		shmem2: scmi-sram@d0002000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0002000 0x1000>;
+		};
+
+		shmem3: scmi-sram@d0003000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0003000 0x1000>;
+		};
+
+		shmem4: scmi-sram@d0004000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0004000 0x1000>;
+		};
+
+		shmem5: scmi-sram@d0005000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0005000 0x1000>;
+		};
+
+		shmem6: scmi-sram@d0006000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0006000 0x1000>;
+		};
+
+		shmem7: scmi-sram@d0007000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0007000 0x1000>;
+		};
+
+		shmem8: scmi-sram@d0008000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0008000 0x1000>;
+		};
+
+		shmem9: scmi-sram@d0009000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0009000 0x1000>;
+		};
+
+		shmem10: scmi-sram@d000a000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd000a000 0x1000>;
+		};
+
+		shmem11: scmi-sram@d000b000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd000b000 0x1000>;
+		};
+
+		shmem12: scmi-sram@d000c000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd000c000 0x1000>;
+		};
+
+		shmem13: scmi-sram@d000d000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd000d000 0x1000>;
+		};
+
+		shmem14: scmi-sram@d000e000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd000e000 0x1000>;
+		};
+
+		shmem15: scmi-sram@d000f000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd000f000 0x1000>;
+		};
+
+		shmem16: scmi-sram@d0010000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0010000 0x1000>;
+		};
+
+		shmem17: scmi-sram@d0011000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0011000 0x1000>;
+		};
+
+		shmem18: scmi-sram@d0012000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0012000 0x1000>;
+		};
+
+		shmem19: scmi-sram@d0013000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0013000 0x1000>;
+		};
+
+		shmem20: scmi-sram@d0014000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0014000 0x1000>;
+		};
+
+		shmem21: scmi-sram@d0015000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0015000 0x1000>;
+		};
+
+		shmem22: scmi-sram@d0016000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0016000 0x1000>;
+		};
+
+		shmem23: scmi-sram@d0017000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0017000 0x1000>;
+		};
+
+		shmem24: scmi-sram@d0018000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0018000 0x1000>;
+		};
+
+		shmem25: scmi-sram@d0019000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0019000 0x1000>;
+		};
+
+		shmem26: scmi-sram@d001a000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd001a000 0x1000>;
+		};
+
+		shmem27: scmi-sram@d001b000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd001b000 0x1000>;
+		};
+
+		shmem28: scmi-sram@d001c000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd001c000 0x1000>;
+		};
+
+		shmem29: scmi-sram@d001d000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd001d000 0x1000>;
+		};
+
+		shmem30: scmi-sram@d001e000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd001e000 0x1000>;
+		};
+
+		shmem31: scmi-sram@d001f000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd001f000 0x1000>;
+		};
+
+		shmem32: scmi-sram@d0020000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0020000 0x1000>;
+		};
+
+		shmem33: scmi-sram@d0021000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0021000 0x1000>;
+		};
+
+		shmem34: scmi-sram@d0022000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0022000 0x1000>;
+		};
+
+		shmem35: scmi-sram@d0023000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0023000 0x1000>;
+		};
+
+		shmem36: scmi-sram@d0024000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0024000 0x1000>;
+		};
+
+		shmem37: scmi-sram@d0025000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0025000 0x1000>;
+		};
+
+		shmem38: scmi-sram@d0026000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0026000 0x1000>;
+		};
+
+		shmem39: scmi-sram@d0027000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0027000 0x1000>;
+		};
+
+		shmem40: scmi-sram@d0028000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0028000 0x1000>;
+		};
+
+		shmem41: scmi-sram@d0029000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0029000 0x1000>;
+		};
+
+		shmem42: scmi-sram@d002a000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd002a000 0x1000>;
+		};
+
+		shmem43: scmi-sram@d002b000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd002b000 0x1000>;
+		};
+
+		shmem44: scmi-sram@d002c000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd002c000 0x1000>;
+		};
+
+		shmem45: scmi-sram@d002d000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd002d000 0x1000>;
+		};
+
+		shmem46: scmi-sram@d002e000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd002e000 0x1000>;
+		};
+
+		shmem47: scmi-sram@d002f000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd002f000 0x1000>;
+		};
+
+		shmem48: scmi-sram@d0030000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0030000 0x1000>;
+		};
+
+		shmem49: scmi-sram@d0031000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0031000 0x1000>;
+		};
+
+		shmem50: scmi-sram@d0032000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0032000 0x1000>;
+		};
+
+		shmem51: scmi-sram@d0033000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0033000 0x1000>;
+		};
+
+		shmem52: scmi-sram@d0034000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0034000 0x1000>;
+		};
+
+		shmem53: scmi-sram@d0035000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0035000 0x1000>;
+		};
+
+		shmem54: scmi-sram@d0036000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0036000 0x1000>;
+		};
+
+		shmem55: scmi-sram@d0037000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0037000 0x1000>;
+		};
+
+		shmem56: scmi-sram@d0038000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0038000 0x1000>;
+		};
+
+		shmem57: scmi-sram@d0039000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0039000 0x1000>;
+		};
+
+		shmem58: scmi-sram@d003a000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd003a000 0x1000>;
+		};
+
+		shmem59: scmi-sram@d003b000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd003b000 0x1000>;
+		};
+
+		shmem60: scmi-sram@d003c000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd003c000 0x1000>;
+		};
+
+		shmem61: scmi-sram@d003d000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd003d000 0x1000>;
+		};
+
+		shmem62: scmi-sram@d003e000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd003e000 0x1000>;
+		};
+
+		shmem63: scmi-sram@d003f000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd003f000 0x1000>;
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa7255p.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa7255p.dtsi
@@ -0,0 +1,2328 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/mailbox/qcom-ipcc.h>
+
+/ {
+	interrupt-parent = <&intc>;
+
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	clocks {
+		bi_tcxo_div2: bi-tcxo-div2-clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&xo_board_clk>;
+			clock-mult = <1>;
+			clock-div = <2>;
+			#clock-cells = <0>;
+		};
+
+		gpll0_board_clk: gpll0-board-clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+		};
+
+		sleep_clk: sleep-clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+		};
+
+		xo_board_clk: xo-board-clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+		};
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 0>;
+			next-level-cache = <&L2_0>;
+			L2_0: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      next-level-cache = <&L3_0>;
+
+				L3_0: l3-cache {
+				      compatible = "cache";
+				      cache-level = <3>;
+				};
+			};
+		};
+
+		cpu1: cpu@100 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 0>;
+			next-level-cache = <&L2_1>;
+			L2_1: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      next-level-cache = <&L3_0>;
+			};
+		};
+
+		cpu2: cpu@200 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 1>;
+			next-level-cache = <&L2_2>;
+			L2_2: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      next-level-cache = <&L3_0>;
+			};
+		};
+
+		cpu3: cpu@300 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x300>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 1>;
+			next-level-cache = <&L2_3>;
+			L2_3: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      next-level-cache = <&L3_0>;
+			};
+		};
+
+		cpu4: cpu@10000 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x10000>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 2>;
+			next-level-cache = <&L2_4>;
+			L2_4: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      next-level-cache = <&L3_1>;
+				L3_1: l3-cache {
+				      compatible = "cache";
+				      cache-level = <3>;
+				};
+			};
+		};
+
+		cpu5: cpu@10100 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x10100>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 2>;
+			next-level-cache = <&L2_5>;
+			L2_5: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      next-level-cache = <&L3_1>;
+			};
+		};
+
+		cpu6: cpu@10200 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x10200>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 2>;
+			next-level-cache = <&L2_6>;
+			L2_6: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      next-level-cache = <&L3_1>;
+			};
+		};
+
+		cpu7: cpu@10300 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x10300>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 2>;
+			next-level-cache = <&L2_7>;
+			L2_7: l2-cache {
+			      compatible = "cache";
+			      cache-level = <2>;
+			      next-level-cache = <&L3_1>;
+			};
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&cpu0>;
+				};
+
+				core1 {
+					cpu = <&cpu1>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&cpu2>;
+				};
+
+				core1 {
+					cpu = <&cpu3>;
+				};
+			};
+
+			cluster2 {
+				core0 {
+					cpu = <&cpu4>;
+				};
+
+				core1 {
+					cpu = <&cpu5>;
+				};
+
+				core2 {
+					cpu = <&cpu6>;
+				};
+
+				core3 {
+					cpu = <&cpu7>;
+				};
+			};
+		};
+	};
+
+	firmware: firmware {
+		scm {
+			compatible = "qcom,scm-sa7255p", "qcom,scm";
+			memory-region = <&tz_ffi_mem>;
+		};
+	};
+
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x0>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+		mode-bootloader = <0x10001 0x2>;
+		mode-edl = <0 0x1>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		sail_ss_mem: sail-ss@80000000 {
+			reg = <0x0 0x80000000 0x0 0x10000000>;
+			no-map;
+		};
+
+		hyp_mem: hyp@90000000 {
+			reg = <0x0 0x90000000 0x0 0x600000>;
+			no-map;
+		};
+
+		xbl_boot_mem: xbl-boot@90600000 {
+			reg = <0x0 0x90600000 0x0 0x200000>;
+			no-map;
+		};
+
+		aop_image_mem: aop-image-region@90800000 {
+			no-map;
+			reg = <0x0 0x90800000 0x0 0x60000>;
+		};
+
+		aop_cmd_db_mem: aop-cmd-db-region@90860000 {
+			compatible = "qcom,cmd-db";
+			no-map;
+			reg = <0x0 0x90860000 0x0 0x20000>;
+		};
+
+		uefi_log: uefi-log@908b0000 {
+			reg = <0x0 0x908b0000 0x0 0x10000>;
+			no-map;
+		};
+
+		ddr_training_checksum: ddr-training-checksum@908c0000 {
+			reg = <0x0 0x908c0000 0x0 0x1000>;
+			no-map;
+		};
+
+		reserved_mem: reserved@908f0000 {
+			reg = <0x0 0x908f0000 0x0 0xe000>;
+			no-map;
+		};
+
+		secdata_apss_mem: secdata-apss@908fe000 {
+			reg = <0x0 0x908fe000 0x0 0x2000>;
+			no-map;
+		};
+
+		smem_mem: smem@90900000 {
+			compatible = "qcom,smem";
+			reg = <0x0 0x90900000 0x0 0x200000>;
+			no-map;
+			hwlocks = <&tcsr_mutex 3>;
+		};
+
+		tz_sail_mailbox_mem: tz-sail-mailbox@90c00000 {
+			reg = <0x0 0x90c00000 0x0 0x100000>;
+			no-map;
+		};
+
+		sail_mailbox_mem: sail-ss@90d00000 {
+			reg = <0x0 0x90d00000 0x0 0x100000>;
+			no-map;
+		};
+
+		sail_ota_mem: sail-ss@90e00000 {
+			reg = <0x0 0x90e00000 0x0 0x300000>;
+			no-map;
+		};
+
+		aoss_backup_mem: aoss-backup-region@91b00000 {
+			no-map;
+			reg = <0x0 0x91b00000 0x0 0x40000>;
+		};
+
+		cpucp_backup_mem: cpucp-backup@91b40000 {
+			reg = <0x0 0x91b40000 0x0 0x40000>;
+			no-map;
+		};
+
+		tz_config_backup_mem: tz-config-backup@91b80000 {
+			reg = <0x0 0x91b80000 0x0 0x10000>;
+			no-map;
+		};
+
+		ddr_training_data_mem: ddr-training-data@91b90000 {
+			reg = <0x0 0x91b90000 0x0 0x10000>;
+			no-map;
+		};
+
+		cdt_data_backup_mem: cdt-data-backup@91ba0000 {
+			reg = <0x0 0x91ba0000 0x0 0x1000>;
+			no-map;
+		};
+
+		tz_ffi_mem: tz-ffi@91c00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x0 0x91c00000 0x0 0x1400000>;
+			no-map;
+		};
+
+		lpass_machine_learning_mem: lpass-machine-learning@93b00000 {
+			reg = <0x0 0x93b00000 0x0 0xf00000>;
+			no-map;
+		};
+
+		adsp_rpc_remote_heap_mem: adsp-rpc-remote-heap-region@94a00000 {
+			no-map;
+			reg = <0x0 0x94a00000 0x0 0x800000>;
+		};
+
+		camera_mem: camera-region@95200000 {
+			no-map;
+			reg = <0x0 0x95200000 0x0 0x500000>;
+		};
+
+		mproc_umdpil_mem: mproc-umdpil-region@95700000 {
+			no-map;
+			reg = <0x0 0x95700000 0x0 0x500000>;
+		};
+
+		adsp_mem: adsp-region@95c00000 {
+			no-map;
+			reg = <0x0 0x95c00000 0x0 0x1e00000>;
+		};
+
+		gpdsp_mem: gpdsp-region@97b00000 {
+			no-map;
+			reg = <0x0 0x97b00000 0x0 0x1e00000>;
+		};
+
+		cdsp_mem: cdsp-region@99980000 {
+			no-map;
+			reg = <0x0 0x99980000 0x0 0x1e00000>;
+		};
+
+		gpu_microcode_mem: gpu-microcode-region@9b780000 {
+			no-map;
+			reg = <0x0 0x9b780000 0x0 0x2000>;
+		};
+
+		cvp_mem: cvp-region@9b782000 {
+			no-map;
+			reg = <0x0 0x9b782000 0x0 0x700000>;
+		};
+
+		video_mem: video-region@9be82000 {
+			no-map;
+			reg = <0x0 0x9be82000 0x0 0x700000>;
+		};
+
+		audio_mdf_mem: audio-mdf-region@ae000000 {
+			reg = <0x0 0xae000000 0x0 0x2000000>;
+			no-map;
+		};
+
+		firmware_mem: firmware-region@b0000000 {
+			reg = <0x0 0xb0000000 0x0 0x800000>;
+			no-map;
+		};
+
+		hyptz_reserved_mem: hyptz-reserved@beb00000 {
+			reg = <0x0 0xbeb00000 0x0 0x11500000>;
+			no-map;
+		};
+
+		scmi_mem: scmi-region@d0000000 {
+			reg = <0x0 0xd0000000 0x0 0x40000>;
+			no-map;
+		};
+
+		firmware_logs_mem: firmware-logs@d0040000 {
+			reg = <0x0 0xd0040000 0x0 0x10000>;
+			no-map;
+		};
+
+		firmware_reserved_mem: firmware-reserved@d0054000 {
+			reg = <0x0 0xd0054000 0x0 0x9c000>;
+			no-map;
+		};
+
+		firmware_quantum_test_mem: firmware-quantum-test@d00f0000 {
+			reg = <0x0 0xd00f0000 0x0 0x10000>;
+			no-map;
+		};
+
+		tags_mem: tags@d0100000 {
+			reg = <0x0 0xd0100000 0x0 0x1200000>;
+			no-map;
+		};
+
+		qtee_mem: qtee@d1300000 {
+			reg = <0x0 0xd1300000 0x0 0x500000>;
+			no-map;
+		};
+
+		deep_sleep_back_up_mem: deep-sleep-back-up-region@d1800000 {
+			no-map;
+			reg = <0x0 0xd1800000 0x0 0x100000>;
+		};
+
+		trusted_apps_mem: trusted-apps@d1900000 {
+			reg = <0x0 0xd1900000 0x0 0x3800000>;
+			no-map;
+		};
+
+		tz_stat_mem: tz-stat@db100000 {
+			reg = <0x0 0xdb100000 0x0 0x100000>;
+			no-map;
+		};
+
+		cpucp_fw_mem: cpucp-fw@db200000 {
+			reg = <0x0 0xdb200000 0x0 0x100000>;
+			no-map;
+		};
+
+		cma: linux,cma {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xdfffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x2000000>;
+			linux,cma-default;
+		};
+	};
+
+	soc: soc@0 {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges = <0 0 0 0 0x10 0>;
+
+		dcc: dma@40ff000 {
+			compatible = "qcom,dcc-v3", "qcom,dcc";
+			reg = <0x0 0x040ff000 0x0 0x1000>,
+			      <0x0 0x040b8800 0x0 0x6000>;
+			qcom,dcc-offset = <0x38800>;
+		};
+
+		ipcc0: mailbox@408000 {
+			compatible = "qcom,sa7255p-ipcc", "qcom,ipcc";
+			reg = <0x0 0x408000 0x0 0x1000>;
+			interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			#mbox-cells = <2>;
+		};
+
+		ipcc1: mailbox@488000 {
+			compatible = "qcom,sa7255p-ipcc", "qcom,ipcc";
+			reg = <0x0 0x488000 0x0 0x1000>;
+			interrupts = <GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			#mbox-cells = <2>;
+			status = "disabled";
+		};
+
+		qupv3_id_0: geniqup@9c0000 {
+			compatible = "qcom,sa7255p-geni-se-qup";
+			reg = <0x0 0x9c0000 0x0 0x2000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			iommus = <&apps_smmu 0x403 0x0>;
+			status = "disabled";
+
+			i2c0: i2c@980000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0x980000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 550 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi0: spi@980000 {
+				compatible = "qcom,sa7255p-geni-spi";
+				reg = <0x0 0x980000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 550 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart0: serial@980000 {
+				compatible = "qcom,sa7255p-geni-uart";
+				reg = <0x0 0x980000 0x0 0x4000>;
+				interrupts = <GIC_SPI 550 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c1: i2c@984000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0x984000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 551 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi1: spi@984000 {
+				compatible = "qcom,sa7255p-geni-spi";
+				reg = <0x0 0x984000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 551 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart1: serial@984000 {
+				compatible = "qcom,sa7255p-geni-uart";
+				reg = <0x0 0x984000 0x0 0x4000>;
+				interrupts = <GIC_SPI 551 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c2: i2c@988000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0x988000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi2: spi@988000 {
+				compatible = "qcom,sa7255p-geni-spi";
+				reg = <0x0 0x988000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart2: serial@988000 {
+				compatible = "qcom,sa7255p-geni-uart";
+				reg = <0x0 0x988000 0x0 0x4000>;
+				interrupts = <GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c3: i2c@98c000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0x98c000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi3: spi@98c000 {
+				compatible = "qcom,sa7255p-geni-spi";
+				reg = <0x0 0x98c000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart3: serial@98c000 {
+				compatible = "qcom,sa7255p-geni-uart";
+				reg = <0x0 0x98c000 0x0 0x4000>;
+				interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c4: i2c@990000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0x990000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi4: spi@990000 {
+				compatible = "qcom,sa7255p-geni-spi";
+				reg = <0x0 0x990000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart4: serial@990000 {
+				compatible = "qcom,sa7255p-geni-uart";
+				reg = <0x0 0x990000 0x0 0x4000>;
+				interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c5: i2c@994000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0x994000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi5: spi@994000 {
+				compatible = "qcom,sa7255p-geni-spi";
+				reg = <0x0 0x994000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart5: serial@994000 {
+				compatible = "qcom,sa7255p-geni-uart";
+				reg = <0x0 0x994000 0x0 0x4000>;
+				interrupts = <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c6: i2c@998000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0x998000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi6: spi@998000 {
+				compatible = "qcom,sa7255p-geni-spi";
+				reg = <0x0 0x998000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart7: serial@99c000 {
+				compatible = "qcom,sa7255p-geni-debug-uart";
+				reg = <0x0 0x0099c000 0x0 0x4000>;
+				interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+		};
+
+		qupv3_id_1: geniqup@ac0000 {
+			compatible = "qcom,sa7255p-geni-se-qup";
+			reg = <0x0 0x00ac0000 0x0 0x2000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			iommus = <&apps_smmu 0x443 0x0>;
+			status = "disabled";
+
+			i2c8: i2c@a80000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0xa80000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi8: spi@a80000 {
+				compatible = "qcom,sa7255p-geni-spi";
+				reg = <0x0 0xa80000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c9: i2c@a84000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0xa84000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi9: spi@a84000 {
+				compatible = "qcom,sa7255p-geni-spi";
+				reg = <0x0 0xa84000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart9: serial@a84000 {
+				compatible = "qcom,sa7255p-geni-uart";
+				reg = <0x0 0x00a84000 0x0 0x4000>;
+				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c10: i2c@a88000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0xa88000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi10: spi@a88000 {
+				compatible = "qcom,sa7255p-geni-spi";
+				reg = <0x0 0xa88000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart10: serial@a88000 {
+				compatible = "qcom,sa7255p-geni-uart";
+				reg = <0x0 0xa88000 0x0 0x4000>;
+				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c11: i2c@a8c000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0xa8c000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi11: spi@a8c000 {
+				compatible = "qcom,sa7255p-geni-spi";
+				reg = <0x0 0xa8c000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart11: serial@a8c000 {
+				compatible = "qcom,sa7255p-geni-debug-uart";
+				reg = <0x0 0x00a8c000 0x0 0x4000>;
+				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c12: i2c@a90000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0xa90000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi12: spi@a90000 {
+				compatible = "qcom,sa7255p-geni-spi";
+				reg = <0x0 0xa90000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart12: serial@a90000 {
+				compatible = "qcom,sa7255p-geni-uart";
+				reg = <0x0 0x00a90000 0x0 0x4000>;
+				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c13: i2c@a94000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0xa94000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi13: spi@a94000 {
+				compatible = "qcom,sa7255p-geni-spi";
+				reg = <0x0 0xa94000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart13: serial@a94000 {
+				compatible = "qcom,sa7255p-geni-uart";
+				reg = <0x0 0x00a94000 0x0 0x4000>;
+				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c14: i2c@a98000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0xa98000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 835 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c15: i2c@a9c000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0xa9c000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+		};
+
+		qupv3_id_3: geniqup@bc0000 {
+			compatible = "qcom,sa7255p-geni-se-qup";
+			reg = <0x0 0xbc0000 0x0 0x2000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			iommus = <&apps_smmu 0x43 0x0>;
+			status = "disabled";
+
+			i2c16: i2c@b80000 {
+				compatible = "qcom,sa7255p-geni-i2c";
+				reg = <0x0 0xb80000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 830 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi16: spi@b80000 {
+				compatible = "qcom,sa7255p-geni-spi";
+				reg = <0x0 0xb80000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 830 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+		};
+
+		pcie0_ep: pcie-ep@1c00000 {
+			compatible = "qcom,sa8775p-pcie-ep";
+
+			reg = <0x0 0x01c00000 0x0 0x3000>,
+			      <0x0 0x40000000 0x0 0xf20>,
+			      <0x0 0x40000f20 0x0 0xa8>,
+			      <0x0 0x40001000 0x0 0x4000>,
+			      <0x0 0x40200000 0x0 0x100000>,
+			      <0x0 0x01c03000 0x0 0x1000>,
+			      <0x0 0x40005000 0x0 0x2000>,
+			      <0x0 0x01c05200 0x0 0x1e8>;
+			reg-names = "parf", "dbi", "elbi", "atu", "addr_space",
+				    "mmio", "dma", "phy_pcs";
+
+			interrupts = <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 630 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "global", "doorbell", "dma";
+
+			dma-coherent;
+			iommus = <&pcie_smmu 0x0000 0x7f>;
+			max-link-speed = <4>;
+			num-lanes = <2>;
+
+			status = "disabled";
+		};
+
+		pcie1_ep: pcie-ep@1c10000 {
+			compatible = "qcom,sa8775p-pcie-ep";
+
+			reg = <0x0 0x01c10000 0x0 0x3000>,
+			      <0x0 0x60000000 0x0 0xf20>,
+			      <0x0 0x60000f20 0x0 0xa8>,
+			      <0x0 0x60001000 0x0 0x4000>,
+			      <0x0 0x60200000 0x0 0x100000>,
+			      <0x0 0x01c13000 0x0 0x1000>,
+			      <0x0 0x60005000 0x0 0x2000>,
+			      <0x0 0x01c16200 0x0 0x1e8>;
+			reg-names = "parf", "dbi", "elbi", "atu", "addr_space",
+				    "mmio", "dma", "phy_pcs";
+
+			interrupts = <GIC_SPI 518 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "global", "doorbell", "dma";
+
+			dma-coherent;
+			iommus = <&pcie_smmu 0x80 0x7f>;
+			max-link-speed = <4>;
+			num-lanes = <4>;
+
+			status = "disabled";
+		};
+
+		ufs_mem_hc: ufs@1d84000 {
+			compatible = "qcom,sa7255p-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
+			reg = <0x0 0x01d84000 0x0 0x3000>;
+			interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+			lanes-per-direction = <2>;
+			iommus = <&apps_smmu 0x100 0x0>;
+			dma-coherent;
+			qcom,ice = <&ice>;
+			status = "disabled";
+		};
+
+		ice: crypto@1d88000 {
+			compatible = "qcom,sa7255p-inline-crypto-engine",
+				     "qcom,inline-crypto-engine";
+			reg = <0x0 0x01d88000 0x0 0x10000>;
+			qcom,ice-use-hwkm;
+			qcom,ice-skip-clk;
+		};
+
+		tcsr_mutex: hwlock@1f40000 {
+			compatible = "qcom,tcsr-mutex";
+			reg = <0x0 0x01f40000 0x0 0x20000>;
+			#hwlock-cells = <1>;
+		};
+
+		tcsr: syscon@1fc0000 {
+			compatible = "qcom,sa7255p-tcsr", "syscon";
+			reg = <0x0 0x1fc0000 0x0 0x30000>;
+		};
+
+		adreno_smmu: iommu@3da0000 {
+			compatible = "qcom,sa7255p-smmu-500", "qcom,adreno-smmu",
+				     "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x03da0000 0x0 0x20000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <2>;
+			dma-coherent;
+
+			interrupts = <GIC_SPI 672 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 673 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 681 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 682 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		usb_0_hsphy: phy@8904000 {
+			compatible = "qcom,sa7255p-usb-hs-phy",
+				     "qcom,usb-snps-hs-5nm-phy";
+			reg = <0x0 0x08904000 0x0 0x120>;
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
+		usb_1_hsphy: phy@8906000 {
+			compatible = "qcom,sa7255p-usb-hs-phy",
+				     "qcom,usb-snps-hs-5nm-phy";
+			reg = <0x0 0x08906000 0x0 0x120>;
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
+		usb_0_qmpphy: phy@8907000 {
+			compatible = "qcom,sa7255p-qmp-usb3-uni-phy";
+			reg = <0x0 0x08907000 0x0 0x2000>;
+
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
+		usb_1: usb@a4f8800 {
+			compatible = "qcom,sa7255p-dwc3", "qcom,dwc3";
+			reg = <0x0 0x0a4f8800 0x0 0x400>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			interrupts-extended = <&intc GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 10 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
+			interrupt-names = "pwr_event",
+					  "dp_hs_phy_irq",
+					  "dm_hs_phy_irq";
+
+			status = "disabled";
+
+			usb_1_dwc3: usb@a400000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x0a400000 0x0 0xe000>;
+				interrupts = <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>;
+				iommus = <&apps_smmu 0x020 0x0>;
+				phys = <&usb_1_hsphy>;
+				phy-names = "usb2-phy";
+			};
+		};
+
+		usb_0: usb@a6f8800 {
+			compatible = "qcom,sa7255p-dwc3", "qcom,dwc3";
+			reg = <0x0 0x0a6f8800 0x0 0x400>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			interrupts-extended = <&intc GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 12 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "dp_hs_phy_irq",
+					  "dm_hs_phy_irq",
+					  "ss_phy_irq";
+
+			status = "disabled";
+
+			usb_0_dwc3: usb@a600000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x0a600000 0x0 0xe000>;
+				interrupts = <GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH>;
+				iommus = <&apps_smmu 0x080 0x0>;
+				phys = <&usb_0_hsphy>, <&usb_0_qmpphy>;
+				phy-names = "usb2-phy", "usb3-phy";
+
+				snps,dis-u1-entry-quirk;
+				snps,dis-u2-entry-quirk;
+			};
+		};
+
+		pdc: interrupt-controller@b220000 {
+			compatible = "qcom,sa7255p-pdc", "qcom,pdc";
+			reg = <0x0 0x0b220000 0x0 0x30000>,
+			      <0x0 0x17c000f0 0x0 0x64>;
+			qcom,pdc-ranges = <0 480 40>,
+					  <40 140 14>,
+					  <54 263 1>,
+					  <55 306 4>,
+					  <59 312 3>,
+					  <62 374 2>,
+					  <64 434 2>,
+					  <66 438 2>,
+					  <70 520 1>,
+					  <73 523 1>,
+					  <118 568 6>,
+					  <124 609 3>,
+					  <159 638 1>,
+					  <160 720 3>,
+					  <169 728 30>,
+					  <199 416 2>,
+					  <201 449 1>,
+					  <202 89 1>,
+					  <203 451 1>,
+					  <204 462 1>,
+					  <205 264 1>,
+					  <206 579 1>,
+					  <207 653 1>,
+					  <208 656 1>,
+					  <209 659 1>,
+					  <210 122 1>,
+					  <211 699 1>,
+					  <212 705 1>,
+					  <213 450 1>,
+					  <214 643 2>,
+					  <216 646 5>,
+					  <221 390 5>,
+					  <226 700 2>,
+					  <228 440 1>,
+					  <229 663 1>,
+					  <230 524 2>,
+					  <232 612 3>,
+					  <235 723 5>;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&intc>;
+			interrupt-controller;
+		};
+
+		tsens2: thermal-sensor@c251000 {
+			compatible = "qcom,sa7255p-tsens", "qcom,tsens-v2";
+			reg = <0x0 0x0c251000 0x0 0x1ff>,
+			      <0x0 0x0c224000 0x0 0x8>;
+			interrupts = <GIC_SPI 572 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 609 IRQ_TYPE_LEVEL_HIGH>;
+			#qcom,sensors = <10>;
+			interrupt-names = "uplow", "critical";
+			#thermal-sensor-cells = <1>;
+		};
+
+		tsens3: thermal-sensor@c252000 {
+			compatible = "qcom,sa7255p-tsens", "qcom,tsens-v2";
+			reg = <0x0 0x0c252000 0x0 0x1ff>,
+			      <0x0 0x0c225000 0x0 0x8>;
+			interrupts = <GIC_SPI 573 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 610 IRQ_TYPE_LEVEL_HIGH>;
+			#qcom,sensors = <10>;
+			interrupt-names = "uplow", "critical";
+			#thermal-sensor-cells = <1>;
+		};
+
+		tsens0: thermal-sensor@c263000 {
+			compatible = "qcom,sa7255p-tsens", "qcom,tsens-v2";
+			reg = <0x0 0x0c263000 0x0 0x1ff>,
+			      <0x0 0x0c222000 0x0 0x8>;
+			interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH>;
+			#qcom,sensors = <10>;
+			interrupt-names = "uplow", "critical";
+			#thermal-sensor-cells = <1>;
+		};
+
+		tsens1: thermal-sensor@c265000 {
+			compatible = "qcom,sa7255p-tsens", "qcom,tsens-v2";
+			reg = <0x0 0x0c265000 0x0 0x1ff>,
+			      <0x0 0x0c223000 0x0 0x8>;
+			interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 509 IRQ_TYPE_LEVEL_HIGH>;
+			#qcom,sensors = <10>;
+			interrupt-names = "uplow", "critical";
+			#thermal-sensor-cells = <1>;
+		};
+
+		tlmm: pinctrl@f000000 {
+			compatible = "qcom,sa7255p-tlmm";
+			reg = <0x0 0x0f000000 0x0 0x1000000>;
+			interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			gpio-ranges = <&tlmm 0 0 133>;
+			wakeup-parent = <&pdc>;
+		};
+
+		apps_smmu: iommu@15000000 {
+			compatible = "qcom,sa7255p-smmu-500", "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x15000000 0x0 0x100000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <2>;
+
+			interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI  98 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI  99 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 706 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 689 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 690 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 691 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 692 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 693 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 694 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 695 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 696 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 413 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 708 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 709 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 710 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 711 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 414 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 712 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 713 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 714 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 715 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 912 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 911 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 910 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 909 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 908 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 907 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 906 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 905 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 904 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 903 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 902 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 901 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 900 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 899 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 898 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 897 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 896 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 895 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pcie_smmu: iommu@15200000 {
+			compatible = "qcom,sa7255p-smmu-500", "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x15200000 0x0 0x80000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <2>;
+			dma-coherent;
+
+			interrupts = <GIC_SPI 920 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 921 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 925 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 926 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 927 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 928 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 950 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 951 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 952 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 953 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 954 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 955 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 956 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 957 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 958 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 885 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 886 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 887 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 888 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 820 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 823 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 452 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 840 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 841 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 842 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 843 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 844 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 845 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 846 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 847 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 848 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 849 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 802 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 803 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 804 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 805 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 806 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 807 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 808 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 809 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 810 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 811 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 812 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 813 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 814 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 837 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 838 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 839 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 854 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 855 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 856 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 790 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 791 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 792 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 793 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 794 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 795 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 796 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		intc: interrupt-controller@17a00000 {
+			compatible = "arm,gic-v3";
+			reg = <0x0 0x17a00000 0x0 0x10000>,	/* GICD */
+			      <0x0 0x17a60000 0x0 0x100000>;	/* GICR * 8 */
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#redistributor-regions = <1>;
+			redistributor-stride = <0x0 0x20000>;
+		};
+
+		memtimer: timer@17c20000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x17c20000 0x0 0x1000>;
+			ranges = <0x0 0x0 0x0 0x20000000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			frame@17c21000 {
+				reg = <0x17c21000 0x1000>,
+				      <0x17c22000 0x1000>;
+				interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+				frame-number = <0>;
+			};
+
+			frame@17c23000 {
+				reg = <0x17c23000 0x1000>;
+				interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+				frame-number = <1>;
+				status = "disabled";
+			};
+
+			frame@17c25000 {
+				reg = <0x17c25000 0x1000>;
+				interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+				frame-number = <2>;
+				status = "disabled";
+			};
+
+			frame@17c27000 {
+				reg = <0x17c27000 0x1000>;
+				interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+				frame-number = <3>;
+				status = "disabled";
+			};
+
+			frame@17c29000 {
+				reg = <0x17c29000 0x1000>;
+				interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+				frame-number = <4>;
+				status = "disabled";
+			};
+
+			frame@17c2b000 {
+				reg = <0x17c2b000 0x1000>;
+				interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+				frame-number = <5>;
+				status = "disabled";
+			};
+
+			frame@17c2d000 {
+				reg = <0x17c2d000 0x1000>;
+				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+				frame-number = <6>;
+				status = "disabled";
+			};
+		};
+
+		watchdog@17c10000 {
+			compatible = "qcom,apss-wdt-sa7255p", "qcom,kpss-wdt";
+			reg = <0x0 0x17c10000 0x0 0x1000>;
+			clocks = <&sleep_clk>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_EDGE_RISING>;
+		};
+
+		cpufreq_hw: cpufreq-hw@18591000 {
+			compatible = "qcom,cpufreq-epss",
+				     "qcom,qcs8300-cpufreq-epss";
+			reg = <0x0 0x18591000 0x0 0x1000>,
+			      <0x0 0x18594000 0x0 0x1000>,
+			      <0x0 0x18593000 0x0 0x1000>;
+			reg-names = "freq-domain0", "freq-domain1", "freq-domain2";
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "dcvsh-irq-0", "dcvsh-irq-1", "dcvsh-irq-2";
+
+			clocks = <&bi_tcxo_div2>, <&gpll0_board_clk>;
+			clock-names = "xo", "alternate";
+
+			#freq-domain-cells = <1>;
+		};
+
+		pcie0: pci@400000000 {
+			compatible = "qcom,pcie-ecam-rc";
+			reg = <0x4 0x00000000 0x0 0x10000000>;
+
+			device_type = "pci";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			ranges = <0x01000000 0x0 0x40000000 0x0 0x40000000 0x0 0x100000>,
+				 <0x02000000 0x0 0x40100000 0x0 0x40100000 0x0 0x1ff00000>,
+				 <0x43000000 0x4 0x10100000 0x4 0x10100000 0x0 0x100000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <0>;
+
+			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-parent = <&intc>;
+
+			iommus = <&pcie_smmu 0x00 0x7f>;
+			iommu-map = <0x0 &pcie_smmu 0x0000 0x1>,
+				    <0x100 &pcie_smmu 0x0001 0x1>,
+				    <0x200 &pcie_smmu 0x0002 0x1>,
+				    <0x300 &pcie_smmu 0x0003 0x1>;
+
+			status = "disabled";
+		};
+
+		pcie1: pci@600000000 {
+			compatible = "qcom,pcie-ecam-rc";
+			reg = <0x6 0x00000000 0x0 0x10000000>;
+
+			device_type = "pci";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			ranges = <0x01000000 0x0 0x60000000 0x0 0x60000000 0x0 0x100000>,
+				 <0x02000000 0x0 0x60100000 0x0 0x60100000 0x0 0x1ff00000>,
+				 <0x43000000 0x6 0x10100000 0x6 0x10100000 0x0 0x100000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <1>;
+
+			interrupts = <GIC_SPI 519 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-parent = <&intc>;
+
+			iommus = <&pcie_smmu 0x80 0x7f>;
+			iommu-map = <0x0 &pcie_smmu 0x0080 0x1>,
+				    <0x100 &pcie_smmu 0x0081 0x1>,
+				    <0x200 &pcie_smmu 0x0082 0x1>,
+				    <0x208 &pcie_smmu 0x0083 0x1>,
+				    <0x210 &pcie_smmu 0x0084 0x1>,
+				    <0x300 &pcie_smmu 0x0085 0x1>,
+				    <0xab00 &pcie_smmu 0x0086 0x1>;
+
+			status = "disabled";
+		};
+
+	};
+
+	thermal-zones {
+		aoss-0-thermal {
+			thermal-sensors = <&tsens0 0>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-0-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens0 1>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-1-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens0 2>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-2-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens0 3>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-3-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens0 4>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		gpuss-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens0 5>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		audio-thermal {
+			thermal-sensors = <&tsens0 6>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		camss-0-thermal {
+			thermal-sensors = <&tsens0 7>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		pcie-0-thermal {
+			thermal-sensors = <&tsens0 8>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpuss-0-0-thermal {
+			thermal-sensors = <&tsens0 9>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		aoss-1-thermal {
+			thermal-sensors = <&tsens1 0>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-0-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens1 1>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-1-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens1 2>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-2-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens1 3>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-3-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens1 4>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		gpuss-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens1 5>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		video-thermal {
+			thermal-sensors = <&tsens1 6>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		camss-1-thermal {
+			thermal-sensors = <&tsens1 7>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		pcie-1-thermal {
+			thermal-sensors = <&tsens1 8>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpuss-0-1-thermal {
+			thermal-sensors = <&tsens1 9>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		aoss-2-thermal {
+			thermal-sensors = <&tsens2 0>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-0-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 1>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-1-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 2>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-2-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 3>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-3-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 4>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-0-0-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 5>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-0-1-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 6>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-0-2-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 7>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		ddrss-0-thermal {
+			thermal-sensors = <&tsens2 8>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpuss-1-0-thermal {
+			thermal-sensors = <&tsens2 9>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		aoss-3-thermal {
+			thermal-sensors = <&tsens3 0>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-0-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 1>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-1-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 2>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-2-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 3>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-3-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 4>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-0-0-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 5>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-0-1-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 6>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-0-2-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 7>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		ddrss-1-thermal {
+			thermal-sensors = <&tsens3 8>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpuss-1-1-thermal {
+			thermal-sensors = <&tsens3 9>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+	};
+
+	arch_timer: timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 12 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+		clock-frequency = <19200000>;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8155p-adp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8155p-adp.dts
@@ -367,6 +367,16 @@
 	};
 };
 
+&pmm8155au_1_gpios {
+	pmm8155au_1_sdc2_cd: sdc2-cd-default-state {
+		pins = "gpio4";
+		function = "normal";
+		input-enable;
+		bias-pull-up;
+		power-source = <0>;
+	};
+};
+
 &qupv3_id_1 {
 	status = "okay";
 };
@@ -384,10 +394,10 @@
 &sdhc_2 {
 	status = "okay";
 
-	cd-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>;
+	cd-gpios = <&pmm8155au_1_gpios 4 GPIO_ACTIVE_LOW>;
 	pinctrl-names = "default", "sleep";
-	pinctrl-0 = <&sdc2_on>;
-	pinctrl-1 = <&sdc2_off>;
+	pinctrl-0 = <&sdc2_on &pmm8155au_1_sdc2_cd>;
+	pinctrl-1 = <&sdc2_off &pmm8155au_1_sdc2_cd>;
 	vqmmc-supply = <&vreg_l13c_2p96>; /* IO line power */
 	vmmc-supply = <&vreg_l17a_2p96>;  /* Card power line */
 	bus-width = <4>;
@@ -505,13 +515,6 @@
 			bias-pull-up;		/* pull up */
 			drive-strength = <16>;	/* 16 MA */
 		};
-
-		sd-cd-pins {
-			pins = "gpio96";
-			function = "gpio";
-			bias-pull-up;		/* pull up */
-			drive-strength = <2>;	/* 2 MA */
-		};
 	};
 
 	sdc2_off: sdc2-off-state {
@@ -532,13 +535,6 @@
 			bias-pull-up;		/* pull up */
 			drive-strength = <2>;	/* 2 MA */
 		};
-
-		sd-cd-pins {
-			pins = "gpio96";
-			function = "gpio";
-			bias-pull-up;		/* pull up */
-			drive-strength = <2>;	/* 2 MA */
-		};
 	};
 
 	usb2phy_ac_en1_default: usb2phy-ac-en1-default-state {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8255p-pmics.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8255p-pmics.dtsi
@@ -0,0 +1,84 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024-2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/ {
+	thermal-zones {
+		pmm8654au_0_thermal: xo-thermal {
+			polling-delay-passive = <100>;
+			polling-delay = <0>;
+
+			trips {
+				trip0 {
+					temperature = <105000>;
+					hysteresis = <0>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <125000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+		};
+
+		pmm8654au_1_thermal: ufs0-thermal {
+			polling-delay-passive = <100>;
+			polling-delay = <0>;
+
+			trips {
+				trip0 {
+					temperature = <105000>;
+					hysteresis = <0>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <125000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+		};
+
+		pmm8654au_2_thermal: soc0-thermal {
+			polling-delay-passive = <100>;
+			polling-delay = <0>;
+
+			trips {
+				trip0 {
+					temperature = <105000>;
+					hysteresis = <0>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <125000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+		};
+
+		pmm8654au_3_thermal: sdram0-thermal {
+			polling-delay-passive = <100>;
+			polling-delay = <0>;
+
+			trips {
+				trip0 {
+					temperature = <105000>;
+					hysteresis = <0>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <125000>;
+					hysteresis = <0>;
+					type = "critical";
+				};
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8255p-ride.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8255p-ride.dts
@@ -0,0 +1,545 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+
+#include "sa8255p.dtsi"
+#include "sa8255p-pmics.dtsi"
+#include "sa8255p-scmi.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. SA8255P Ride";
+	compatible = "qcom,sa8255p-ride","qcom,sa8255p";
+
+	aliases {
+		ethernet0 = &ethernet0;
+		ethernet1 = &ethernet1;
+		i2c11 = &i2c11;
+		i2c18 = &i2c18;
+		serial0 = &uart10;
+		serial1 = &uart4;
+		spi16 = &spi16;
+		ufshc1 = &ufs_mem_hc;
+		scmichannels = &scmichannels;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+};
+
+&aoss_qmp {
+	status = "disabled";
+};
+
+&adreno_smmu {
+	power-domains = <&scmi15_pd 0>;
+
+	status = "okay";
+};
+
+&ethernet0 {
+	phy-mode = "sgmii";
+	phy-handle = <&sgmii_phy0>;
+
+	pinctrl-0 = <&ethernet0_default>;
+	pinctrl-names = "default";
+
+	snps,mtl-rx-config = <&mtl_rx_setup>;
+	snps,mtl-tx-config = <&mtl_tx_setup>;
+	snps,ps-speed = <1000>;
+
+	power-domains = <&scmi7_pd 0>, <&scmi7_pd 1>,<&scmi7_dvfs 0>;
+	power-domain-names = "power_core", "power_mdio","perf_serdes";
+
+	status = "okay";
+
+	mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		sgmii_phy0: phy@8 {
+			compatible = "ethernet-phy-id0141.0dd4";
+			reg = <0x8>;
+			device_type = "ethernet-phy";
+			resets = <&scmi7_rst 0>;
+			reset-names = "phy";
+			reset-assert-us = <11000>;
+			reset-deassert-us = <70000>;
+		};
+
+		sgmii_phy1: phy@a {
+			compatible = "ethernet-phy-id0141.0dd4";
+			reg = <0xa>;
+			device_type = "ethernet-phy";
+			resets = <&scmi8_rst 0>;
+			reset-names = "phy";
+			reset-assert-us = <11000>;
+			reset-deassert-us = <70000>;
+		};
+	};
+
+	mtl_rx_setup: rx-queues-config {
+		snps,rx-queues-to-use = <4>;
+		snps,rx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x0>;
+			snps,route-up;
+			snps,priority = <0x1>;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x1>;
+			snps,route-ptp;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x2>;
+			snps,route-avcp;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x3>;
+			snps,priority = <0xc>;
+		};
+	};
+
+	mtl_tx_setup: tx-queues-config {
+		snps,tx-queues-to-use = <4>;
+		snps,tx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+	};
+};
+
+&ethernet1 {
+	phy-mode = "sgmii";
+	phy-handle = <&sgmii_phy1>;
+
+	snps,mtl-rx-config = <&mtl_rx_setup1>;
+	snps,mtl-tx-config = <&mtl_tx_setup1>;
+	snps,ps-speed = <1000>;
+
+	power-domains = <&scmi8_pd 0>, <&scmi8_pd 1>,<&scmi8_dvfs 0>;
+	power-domain-names = "power_core", "power_mdio","perf_serdes";
+
+	status = "okay";
+
+	mtl_rx_setup1: rx-queues-config {
+		snps,rx-queues-to-use = <4>;
+		snps,rx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x0>;
+			snps,route-up;
+			snps,priority = <0x1>;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x1>;
+			snps,route-ptp;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x2>;
+			snps,route-avcp;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x3>;
+			snps,priority = <0xc>;
+		};
+	};
+
+	mtl_tx_setup1: tx-queues-config {
+		snps,tx-queues-to-use = <4>;
+		snps,tx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+	};
+};
+
+&gpll0_board_clk {
+	clock-frequency = <300000000>;
+};
+
+&i2c11 {
+	clock-frequency = <400000>;
+	power-domains = <&scmi9_pd 11>;
+
+	status = "okay";
+};
+
+&i2c18 {
+	clock-frequency = <400000>;
+	power-domains = <&scmi9_pd 18>;
+
+	status = "okay";
+};
+
+&pcie0 {
+	power-domains = <&scmi5_pd 0>;
+	power-domain-names = "power";
+	status = "disabled";
+};
+
+&pcie0_ep {
+	#dma-cells = <1>;
+	dmas = <&pcie0_ep 0>, <&pcie0_ep 1>;
+	dma-names = "rx", "tx";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_ep_clkreq_default &pcie0_ep_perst_default
+		    &pcie0_ep_wake_default>;
+	reset-gpio = <&tlmm 2 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
+	power-domains = <&scmi5_pd 1>;
+	power-domain-names = "power";
+
+	status = "disabled";
+};
+
+&pcie1 {
+	power-domains = <&scmi6_pd 0>;
+	power-domain-names = "power";
+	status = "okay";
+};
+
+&pcie1_ep {
+	#dma-cells = <1>;
+	dmas = <&pcie1_ep 0>, <&pcie1_ep 1>;
+	dma-names = "rx", "tx";
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_ep_clkreq_default &pcie1_ep_perst_default
+		    &pcie1_ep_wake_default>;
+	reset-gpio = <&tlmm 4 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 5 GPIO_ACTIVE_HIGH>;
+	power-domains = <&scmi6_pd 1>;
+	power-domain-names = "power";
+
+	status = "disabled";
+};
+
+&pmm8654au_0_thermal {
+	thermal-sensors = <&scmi23_sensor 0>;
+};
+
+&pmm8654au_1_thermal {
+	thermal-sensors = <&scmi23_sensor 1>;
+};
+
+&pmm8654au_2_thermal {
+	thermal-sensors = <&scmi23_sensor 2>;
+};
+
+&pmm8654au_3_thermal {
+	thermal-sensors = <&scmi23_sensor 3>;
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&qupv3_id_1 {
+	status = "okay";
+};
+
+&qupv3_id_2 {
+	status = "okay";
+};
+
+&scmi0 {
+	status = "okay";
+};
+
+&scmi1 {
+	status = "okay";
+};
+
+&scmi2 {
+	status = "okay";
+};
+
+&scmi3 {
+	status = "okay";
+};
+
+&scmi5 {
+	status = "okay";
+};
+
+&scmi6 {
+	status = "okay";
+};
+
+&scmi7 {
+	status = "okay";
+};
+
+&scmi8 {
+	status = "okay";
+};
+
+&scmi9 {
+	status = "okay";
+};
+
+&scmi10 {
+	status = "okay";
+};
+
+&scmi11 {
+	status = "okay";
+};
+
+&scmi12 {
+	status = "okay";
+};
+
+&scmi13 {
+	status = "okay";
+};
+
+&scmi14 {
+	status = "okay";
+};
+
+&scmi15 {
+	status = "okay";
+};
+
+&scmi23 {
+	status = "okay";
+};
+
+&sleep_clk {
+	clock-frequency = <32000>;
+};
+
+&spi16 {
+	power-domains = <&scmi10_pd 16>, <&scmi10_dvfs 16>;
+	power-domain-names = "power", "perf";
+
+	status = "okay";
+};
+
+&tlmm {
+	ethernet0_default: ethernet0-default-state {
+		ethernet0_mdc: ethernet0-mdc-pins {
+			pins = "gpio8";
+			function = "emac0_mdc";
+			drive-strength = <16>;
+			bias-pull-up;
+		};
+
+		ethernet0_mdio: ethernet0-mdio-pins {
+			pins = "gpio9";
+			function = "emac0_mdio";
+			drive-strength = <16>;
+			bias-pull-up;
+		};
+	};
+
+	pcie0_ep_clkreq_default: pcie-ep-clkreq-default-state {
+		pins = "gpio1";
+		function = "pcie0_clkreq";
+		drive-strength = <2>;
+		bias-disable;
+	};
+
+	pcie0_ep_perst_default: pcie-ep-perst-default-state {
+		pins = "gpio2";
+		function = "gpio";
+		drive-strength = <16>;
+		bias-pull-down;
+	};
+
+	pcie0_ep_wake_default: pcie-ep-wake-default-state {
+		pins = "gpio0";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+	};
+
+	pcie1_ep_clkreq_default: pcie-ep-clkreq-default-state {
+		pins = "gpio3";
+		function = "pcie1_clkreq";
+		drive-strength = <2>;
+		bias-disable;
+	};
+
+	pcie1_ep_perst_default: pcie-ep-perst-default-state {
+		pins = "gpio4";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+	};
+
+	pcie1_ep_wake_default: pcie-ep-wake-default-state {
+		pins = "gpio5";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+	};
+};
+
+&uart4 {
+	power-domains = <&scmi11_pd 4>, <&scmi11_dvfs 4>;
+	power-domain-names = "power", "perf";
+
+	status = "okay";
+};
+
+&uart10 {
+	power-domains = <&scmi11_pd 10>, <&scmi11_dvfs 10>;
+	power-domain-names = "power", "perf";
+
+	status = "okay";
+};
+
+&ufs_mem_hc {
+	reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>;
+	power-domains = <&scmi3_pd 0>;
+
+	status = "okay";
+};
+
+&usb_0 {
+	power-domains = <&scmi0_pd 0>, <&scmi0_pd 1>;
+	power-domain-names = "usb_transfer", "usb_core";
+
+	/delete-property/ wakeup-source;
+
+	status = "okay";
+};
+
+&usb_0_dwc3 {
+	dr_mode = "otg";
+	usb-role-switch;
+};
+
+&usb_0_hsphy {
+	power-domains = <&scmi12_pd 0>, <&scmi12_pd 1>;
+	power-domain-names = "usb_transfer", "usb_core";
+
+	status = "okay";
+};
+
+&usb_0_qmpphy {
+	power-domains = <&scmi12_pd 2>, <&scmi12_pd 3>;
+	power-domain-names = "usb_transfer", "usb_core";
+
+	status = "okay";
+};
+
+&usb_1 {
+	power-domains = <&scmi1_pd 0>, <&scmi1_pd 1>;
+	power-domain-names = "usb_transfer", "usb_core";
+
+	/delete-property/ wakeup-source;
+
+	status = "okay";
+};
+
+&usb_1_dwc3 {
+	dr_mode = "otg";
+	usb-role-switch;
+	role-switch-default-mode = "host";
+};
+
+&usb_1_hsphy {
+	power-domains = <&scmi13_pd 0>, <&scmi13_pd 1>;
+	power-domain-names = "usb_transfer", "usb_core";
+
+	status = "okay";
+};
+
+&usb_1_qmpphy {
+	power-domains = <&scmi13_pd 2>, <&scmi13_pd 3>;
+	power-domain-names = "usb_transfer", "usb_core";
+
+	status = "okay";
+};
+
+&usb_2 {
+	power-domains = <&scmi2_pd 0>, <&scmi2_pd 1>;
+	power-domain-names = "usb_transfer", "usb_core";
+
+	/delete-property/ wakeup-source;
+
+	status = "okay";
+};
+
+&usb_2_dwc3 {
+	dr_mode = "otg";
+	usb-role-switch;
+	role-switch-default-mode = "host";
+};
+
+&usb_2_hsphy {
+	power-domains = <&scmi14_pd 0>, <&scmi14_pd 1>;
+	power-domain-names = "usb_transfer", "usb_core";
+
+	status = "okay";
+};
+
+&xo_board_clk {
+	clock-frequency = <38400000>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8255p-scmi.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8255p-scmi.dtsi
@@ -0,0 +1,2184 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+&firmware {
+	scmi0: scmi0 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem0>;
+
+		interrupts = <GIC_SPI 963 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi0_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi0_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi0_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi1: scmi1 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem1>;
+
+		interrupts = <GIC_SPI 964 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi1_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi1_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi1_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi2: scmi2 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem2>;
+
+		interrupts = <GIC_SPI 965 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi2_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi2_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi2_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi3: scmi3 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem3>;
+
+		interrupts = <GIC_SPI 966 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi3_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi3_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi3_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi4: scmi4 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem4>;
+
+		interrupts = <GIC_SPI 967 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi4_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi4_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi4_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi5: scmi5 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem5>;
+
+		interrupts = <GIC_SPI 968 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi5_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi5_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi5_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi6: scmi6 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem6>;
+
+		interrupts = <GIC_SPI 969 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi6_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi6_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi6_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi7: scmi7 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem7>;
+
+		interrupts = <GIC_SPI 970 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi7_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi7_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi7_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi8: scmi8 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem8>;
+
+		interrupts = <GIC_SPI 971 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi8_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi8_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi8_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi9: scmi9 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem9>;
+
+		interrupts = <GIC_SPI 972 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi9_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi9_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi9_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi10: scmi10 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem10>;
+
+		interrupts = <GIC_SPI 973 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi10_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi10_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi10_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi11: scmi11 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem11>;
+
+		interrupts = <GIC_SPI 974 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi11_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi11_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi11_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi12: scmi12 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem12>;
+
+		interrupts = <GIC_SPI 975 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi12_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi12_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi12_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi13: scmi13 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem13>;
+
+		interrupts = <GIC_SPI 976 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi13_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi13_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi13_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi14: scmi14 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem14>;
+
+		interrupts = <GIC_SPI 977 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi14_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi14_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi14_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi15: scmi15 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem15>;
+
+		interrupts = <GIC_SPI 978 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi15_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi15_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi15_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi16: scmi16 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem16>;
+
+		interrupts = <GIC_SPI 979 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi16_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi16_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi16_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi17: scmi17 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem17>;
+
+		interrupts = <GIC_SPI 980 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi17_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi17_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi17_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi18: scmi18 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem18>;
+
+		interrupts = <GIC_SPI 981 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi18_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi18_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi18_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi19: scmi19 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem19>;
+
+		interrupts = <GIC_SPI 982 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi19_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi19_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi19_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi20: scmi20 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem20>;
+
+		interrupts = <GIC_SPI 983 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi20_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi20_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi20_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi21: scmi21 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem21>;
+
+		interrupts = <GIC_SPI 984 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi21_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi21_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi21_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi22: scmi22 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem22>;
+
+		interrupts = <GIC_SPI 985 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi22_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi22_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi22_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi23: scmi23 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem23>;
+
+		interrupts = <GIC_SPI 986 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi23_sensor: protocol@15 {
+			reg = <0x15>;
+			#thermal-sensor-cells = <1>;
+		};
+	};
+
+	scmi24: scmi24 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem24>;
+
+		interrupts = <GIC_SPI 987 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi24_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi24_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi24_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi25: scmi25 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem25>;
+
+		interrupts = <GIC_ESPI 0 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi25_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi25_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi25_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi26: scmi26 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem26>;
+
+		interrupts = <GIC_ESPI 1 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi26_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi26_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi26_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi27: scmi27 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem27>;
+
+		interrupts = <GIC_ESPI 2 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi27_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi27_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi27_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi28: scmi28 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem28>;
+
+		interrupts = <GIC_ESPI 3 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi28_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi28_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi28_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi29: scmi29 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem29>;
+
+		interrupts = <GIC_ESPI 4 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi29_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi29_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi29_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi30: scmi30 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem30>;
+
+		interrupts = <GIC_ESPI 5 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi30_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi30_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi30_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi31: scmi31 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem31>;
+
+		interrupts = <GIC_ESPI 6 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi31_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi31_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi31_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi32: scmi32 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem32>;
+
+		interrupts = <GIC_ESPI 7 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi32_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi32_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi32_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi33: scmi33 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem33>;
+
+		interrupts = <GIC_ESPI 8 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi33_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi33_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi33_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi34: scmi34 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem34>;
+
+		interrupts = <GIC_ESPI 9 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi34_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi34_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi34_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi35: scmi35 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem35>;
+
+		interrupts = <GIC_ESPI 10 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi35_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi35_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi35_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi36: scmi36 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem36>;
+
+		interrupts = <GIC_ESPI 11 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi36_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi36_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi36_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi37: scmi37 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem37>;
+
+		interrupts = <GIC_ESPI 12 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi37_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi37_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi37_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi38: scmi38 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem38>;
+
+		interrupts = <GIC_ESPI 13 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi38_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi38_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi38_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi39: scmi39 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem39>;
+
+		interrupts = <GIC_ESPI 14 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi39_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi39_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi39_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi40: scmi40 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem40>;
+
+		interrupts = <GIC_ESPI 15 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi40_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi40_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi40_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi41: scmi41 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem41>;
+
+		interrupts = <GIC_ESPI 16 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi41_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi41_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi41_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi42: scmi42 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem42>;
+
+		interrupts = <GIC_ESPI 17 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi42_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi42_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi42_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi43: scmi43 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem43>;
+
+		interrupts = <GIC_ESPI 18 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi43_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi43_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi43_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi44: scmi44 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem44>;
+
+		interrupts = <GIC_ESPI 19 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi44_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi44_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi44_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi45: scmi45 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem45>;
+
+		interrupts = <GIC_ESPI 20 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi45_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi45_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi45_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi46: scmi46 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem46>;
+
+		interrupts = <GIC_ESPI 21 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi46_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi46_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi46_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi47: scmi47 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem47>;
+
+		interrupts = <GIC_ESPI 22 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi47_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi47_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi47_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi48: scmi48 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem48>;
+
+		interrupts = <GIC_ESPI 23 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi48_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi48_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi48_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi49: scmi49 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem49>;
+
+		interrupts = <GIC_ESPI 24 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi49_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi49_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi49_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi50: scmi50 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem50>;
+
+		interrupts = <GIC_ESPI 25 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi50_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi50_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi50_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi51: scmi51 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem51>;
+
+		interrupts = <GIC_ESPI 26 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi51_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi51_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi51_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi52: scmi52 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem52>;
+
+		interrupts = <GIC_ESPI 27 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi52_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi52_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi52_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi53: scmi53 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem53>;
+
+		interrupts = <GIC_ESPI 28 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi53_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi53_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi53_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi54: scmi54 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem54>;
+
+		interrupts = <GIC_ESPI 29 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi54_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi54_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi54_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi55: scmi55 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem55>;
+
+		interrupts = <GIC_ESPI 30 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi55_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi55_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi55_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi56: scmi56 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem56>;
+
+		interrupts = <GIC_ESPI 31 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi56_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi56_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi56_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi57: scmi57 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem57>;
+
+		interrupts = <GIC_ESPI 32 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi57_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi57_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi57_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi58: scmi58 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem58>;
+
+		interrupts = <GIC_ESPI 33 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi58_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi58_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi58_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi59: scmi59 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem59>;
+
+		interrupts = <GIC_ESPI 34 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi59_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi59_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi59_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi60: scmi60 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem60>;
+
+		interrupts = <GIC_ESPI 35 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi60_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi60_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi60_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi61: scmi61 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem61>;
+
+		interrupts = <GIC_ESPI 36 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi61_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi61_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi61_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi62: scmi62 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem62>;
+
+		interrupts = <GIC_ESPI 37 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi62_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi62_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi62_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+
+	scmi63: scmi63 {
+		compatible = "qcom,scmi-smc";
+		arm,smc-id = <0xc6008012>;
+		shmem = <&shmem63>;
+
+		interrupts = <GIC_ESPI 38 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "a2p";
+
+		status = "disabled";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		scmi63_pd: protocol@11 {
+			reg = <0x11>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi63_dvfs: protocol@13 {
+			reg = <0x13>;
+			#power-domain-cells = <1>;
+		};
+
+		scmi63_rst: protocol@16 {
+			reg = <0x16>;
+			#reset-cells = <1>;
+		};
+	};
+};
+
+&soc {
+	scmichannels: sram@d0000000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "mmio-sram";
+		reg = <0x0 0xd0000000 0x0 0x40000>;
+		ranges = <0x0 0x0 0x0 0xffffffff>;
+
+		shmem0: scmi-sram@d0000000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0000000 0x1000>;
+		};
+
+		shmem1: scmi-sram@d0001000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0001000 0x1000>;
+		};
+
+		shmem2: scmi-sram@d0002000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0002000 0x1000>;
+		};
+
+		shmem3: scmi-sram@d0003000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0003000 0x1000>;
+		};
+
+		shmem4: scmi-sram@d0004000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0004000 0x1000>;
+		};
+
+		shmem5: scmi-sram@d0005000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0005000 0x1000>;
+		};
+
+		shmem6: scmi-sram@d0006000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0006000 0x1000>;
+		};
+
+		shmem7: scmi-sram@d0007000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0007000 0x1000>;
+		};
+
+		shmem8: scmi-sram@d0008000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0008000 0x1000>;
+		};
+
+		shmem9: scmi-sram@d0009000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0009000 0x1000>;
+		};
+
+		shmem10: scmi-sram@d000a000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd000a000 0x1000>;
+		};
+
+		shmem11: scmi-sram@d000b000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd000b000 0x1000>;
+		};
+
+		shmem12: scmi-sram@d000c000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd000c000 0x1000>;
+		};
+
+		shmem13: scmi-sram@d000d000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd000d000 0x1000>;
+		};
+
+		shmem14: scmi-sram@d000e000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd000e000 0x1000>;
+		};
+
+		shmem15: scmi-sram@d000f000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd000f000 0x1000>;
+		};
+
+		shmem16: scmi-sram@d0010000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0010000 0x1000>;
+		};
+
+		shmem17: scmi-sram@d0011000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0011000 0x1000>;
+		};
+
+		shmem18: scmi-sram@d0012000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0012000 0x1000>;
+		};
+
+		shmem19: scmi-sram@d0013000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0013000 0x1000>;
+		};
+
+		shmem20: scmi-sram@d0014000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0014000 0x1000>;
+		};
+
+		shmem21: scmi-sram@d0015000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0015000 0x1000>;
+		};
+
+		shmem22: scmi-sram@d0016000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0016000 0x1000>;
+		};
+
+		shmem23: scmi-sram@d0017000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0017000 0x1000>;
+		};
+
+		shmem24: scmi-sram@d0018000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0018000 0x1000>;
+		};
+
+		shmem25: scmi-sram@d0019000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0019000 0x1000>;
+		};
+
+		shmem26: scmi-sram@d001a000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd001a000 0x1000>;
+		};
+
+		shmem27: scmi-sram@d001b000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd001b000 0x1000>;
+		};
+
+		shmem28: scmi-sram@d001c000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd001c000 0x1000>;
+		};
+
+		shmem29: scmi-sram@d001d000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd001d000 0x1000>;
+		};
+
+		shmem30: scmi-sram@d001e000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd001e000 0x1000>;
+		};
+
+		shmem31: scmi-sram@d001f000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd001f000 0x1000>;
+		};
+
+		shmem32: scmi-sram@d0020000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0020000 0x1000>;
+		};
+
+		shmem33: scmi-sram@d0021000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0021000 0x1000>;
+		};
+
+		shmem34: scmi-sram@d0022000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0022000 0x1000>;
+		};
+
+		shmem35: scmi-sram@d0023000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0023000 0x1000>;
+		};
+
+		shmem36: scmi-sram@d0024000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0024000 0x1000>;
+		};
+
+		shmem37: scmi-sram@d0025000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0025000 0x1000>;
+		};
+
+		shmem38: scmi-sram@d0026000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0026000 0x1000>;
+		};
+
+		shmem39: scmi-sram@d0027000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0027000 0x1000>;
+		};
+
+		shmem40: scmi-sram@d0028000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0028000 0x1000>;
+		};
+
+		shmem41: scmi-sram@d0029000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0029000 0x1000>;
+		};
+
+		shmem42: scmi-sram@d002a000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd002a000 0x1000>;
+		};
+
+		shmem43: scmi-sram@d002b000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd002b000 0x1000>;
+		};
+
+		shmem44: scmi-sram@d002c000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd002c000 0x1000>;
+		};
+
+		shmem45: scmi-sram@d002d000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd002d000 0x1000>;
+		};
+
+		shmem46: scmi-sram@d002e000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd002e000 0x1000>;
+		};
+
+		shmem47: scmi-sram@d002f000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd002f000 0x1000>;
+		};
+
+		shmem48: scmi-sram@d0030000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0030000 0x1000>;
+		};
+
+		shmem49: scmi-sram@d0031000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0031000 0x1000>;
+		};
+
+		shmem50: scmi-sram@d0032000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0032000 0x1000>;
+		};
+
+		shmem51: scmi-sram@d0033000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0033000 0x1000>;
+		};
+
+		shmem52: scmi-sram@d0034000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0034000 0x1000>;
+		};
+
+		shmem53: scmi-sram@d0035000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0035000 0x1000>;
+		};
+
+		shmem54: scmi-sram@d0036000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0036000 0x1000>;
+		};
+
+		shmem55: scmi-sram@d0037000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0037000 0x1000>;
+		};
+
+		shmem56: scmi-sram@d0038000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0038000 0x1000>;
+		};
+
+		shmem57: scmi-sram@d0039000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd0039000 0x1000>;
+		};
+
+		shmem58: scmi-sram@d003a000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd003a000 0x1000>;
+		};
+
+		shmem59: scmi-sram@d003b000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd003b000 0x1000>;
+		};
+
+		shmem60: scmi-sram@d003c000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd003c000 0x1000>;
+		};
+
+		shmem61: scmi-sram@d003d000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd003d000 0x1000>;
+		};
+
+		shmem62: scmi-sram@d003e000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd003e000 0x1000>;
+		};
+
+		shmem63: scmi-sram@d003f000 {
+			compatible = "arm,scmi-shmem";
+			reg = <0xd003f000 0x1000>;
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8255p.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8255p.dtsi
@@ -0,0 +1,2826 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/mailbox/qcom-ipcc.h>
+
+/ {
+	interrupt-parent = <&intc>;
+
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	clocks {
+		xo_board_clk: xo-board-clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+		};
+
+		sleep_clk: sleep-clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+		};
+
+		gpll0_board_clk: gpll0-board-clk {
+			compatible = "fixed-clock";
+			#clock-cells = <0>;
+		};
+
+		bi_tcxo_div2: bi-tcxo-div2-clk {
+			compatible = "fixed-factor-clock";
+			clocks = <&xo_board_clk>;
+			clock-mult = <1>;
+			clock-div = <2>;
+			#clock-cells = <0>;
+		};
+	};
+
+	cpus {
+		#address-cells = <2>;
+		#size-cells = <0>;
+
+		CPU0: cpu@0 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 0>;
+			next-level-cache = <&L2_0>;
+			L2_0: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_0>;
+				L3_0: l3-cache {
+					compatible = "cache";
+					cache-level = <3>;
+					cache-unified;
+				};
+			};
+		};
+
+		CPU1: cpu@100 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 0>;
+			next-level-cache = <&L2_1>;
+			L2_1: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_0>;
+			};
+		};
+
+		CPU2: cpu@200 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 0>;
+			next-level-cache = <&L2_2>;
+			L2_2: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_0>;
+			};
+		};
+
+		CPU3: cpu@300 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x300>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 0>;
+			next-level-cache = <&L2_3>;
+			L2_3: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_0>;
+			};
+		};
+
+		CPU4: cpu@10000 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x10000>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 1>;
+			next-level-cache = <&L2_4>;
+			L2_4: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_1>;
+				L3_1: l3-cache {
+					compatible = "cache";
+					cache-level = <3>;
+					cache-unified;
+				};
+
+			};
+		};
+
+		CPU5: cpu@10100 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x10100>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 1>;
+			next-level-cache = <&L2_5>;
+			L2_5: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_1>;
+			};
+		};
+
+		CPU6: cpu@10200 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x10200>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 1>;
+			next-level-cache = <&L2_6>;
+			L2_6: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_1>;
+			};
+		};
+
+		CPU7: cpu@10300 {
+			device_type = "cpu";
+			compatible = "qcom,kryo";
+			reg = <0x0 0x10300>;
+			enable-method = "psci";
+			qcom,freq-domain = <&cpufreq_hw 1>;
+			next-level-cache = <&L2_7>;
+			L2_7: l2-cache {
+				compatible = "cache";
+				cache-level = <2>;
+				cache-unified;
+				next-level-cache = <&L3_1>;
+			};
+		};
+
+		cpu-map {
+			cluster0 {
+				core0 {
+					cpu = <&CPU0>;
+				};
+
+				core1 {
+					cpu = <&CPU1>;
+				};
+
+				core2 {
+					cpu = <&CPU2>;
+				};
+
+				core3 {
+					cpu = <&CPU3>;
+				};
+			};
+
+			cluster1 {
+				core0 {
+					cpu = <&CPU4>;
+				};
+
+				core1 {
+					cpu = <&CPU5>;
+				};
+
+				core2 {
+					cpu = <&CPU6>;
+				};
+
+				core3 {
+					cpu = <&CPU7>;
+				};
+			};
+		};
+	};
+
+	firmware: firmware {
+		scm {
+			compatible = "qcom,scm-sa8255p", "qcom,scm";
+			memory-region = <&tz_ffi_mem>;
+			qcom,dload-mode = <&tcsr 0x13000>;
+		};
+	};
+
+	/* Will be updated by the bootloader. */
+	memory@80000000 {
+		device_type = "memory";
+		reg = <0x0 0x80000000 0x0 0x0>;
+	};
+
+	pmu {
+		compatible = "arm,armv8-pmuv3";
+		interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	psci {
+		compatible = "arm,psci-1.0";
+		method = "smc";
+		mode-bootloader = <0x10001 0x2>;
+		mode-edl = <0 0x1>;
+	};
+
+	reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		sail_ss_mem: sail-ss@80000000 {
+			reg = <0x0 0x80000000 0x0 0x10000000>;
+			no-map;
+		};
+
+		hyp_mem: hyp@90000000 {
+			reg = <0x0 0x90000000 0x0 0x600000>;
+			no-map;
+		};
+
+		xbl_boot_mem: xbl-boot@90600000 {
+			reg = <0x0 0x90600000 0x0 0x200000>;
+			no-map;
+		};
+
+		aop_image_mem: aop-image@90800000 {
+			reg = <0x0 0x90800000 0x0 0x60000>;
+			no-map;
+		};
+
+		aop_cmd_db_mem: aop-cmd-db@90860000 {
+			compatible = "qcom,cmd-db";
+			reg = <0x0 0x90860000 0x0 0x20000>;
+			no-map;
+		};
+
+		uefi_log: uefi-log@908b0000 {
+			reg = <0x0 0x908b0000 0x0 0x10000>;
+			no-map;
+		};
+
+		ddr_training_checksum: ddr-training-checksum@908c0000 {
+			reg = <0x0 0x908c0000 0x0 0x1000>;
+			no-map;
+		};
+
+		reserved_mem: reserved@908f0000 {
+			reg = <0x0 0x908f0000 0x0 0xe000>;
+			no-map;
+		};
+
+		secdata_apss_mem: secdata-apss@908fe000 {
+			reg = <0x0 0x908fe000 0x0 0x2000>;
+			no-map;
+		};
+
+		smem_mem: smem@90900000 {
+			compatible = "qcom,smem";
+			reg = <0x0 0x90900000 0x0 0x200000>;
+			no-map;
+			hwlocks = <&tcsr_mutex 3>;
+		};
+
+		tz_sail_mailbox_mem: tz-sail-mailbox@90c00000 {
+			reg = <0x0 0x90c00000 0x0 0x100000>;
+			no-map;
+		};
+
+		sail_mailbox_mem: sail-ss@90d00000 {
+			reg = <0x0 0x90d00000 0x0 0x100000>;
+			no-map;
+		};
+
+		sail_ota_mem: sail-ss@90e00000 {
+			reg = <0x0 0x90e00000 0x0 0x300000>;
+			no-map;
+		};
+
+		aoss_backup_mem: aoss-backup@91b00000 {
+			reg = <0x0 0x91b00000 0x0 0x40000>;
+			no-map;
+		};
+
+		cpucp_backup_mem: cpucp-backup@91b40000 {
+			reg = <0x0 0x91b40000 0x0 0x40000>;
+			no-map;
+		};
+
+		tz_config_backup_mem: tz-config-backup@91b80000 {
+			reg = <0x0 0x91b80000 0x0 0x10000>;
+			no-map;
+		};
+
+		ddr_training_data_mem: ddr-training-data@91b90000 {
+			reg = <0x0 0x91b90000 0x0 0x10000>;
+			no-map;
+		};
+
+		cdt_data_backup_mem: cdt-data-backup@91ba0000 {
+			reg = <0x0 0x91ba0000 0x0 0x1000>;
+			no-map;
+		};
+
+		tz_ffi_mem: tz-ffi@91c00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x0 0x91c00000 0x0 0x1400000>;
+			no-map;
+		};
+
+		lpass_machine_learning_mem: lpass-machine-learning@93b00000 {
+			reg = <0x0 0x93b00000 0x0 0xf00000>;
+			no-map;
+		};
+
+		adsp_rpc_remote_heap_mem: adsp-rpc-remote-heap@94a00000 {
+			reg = <0x0 0x94a00000 0x0 0x800000>;
+			no-map;
+		};
+
+		pil_camera_mem: pil-camera@95200000 {
+			reg = <0x0 0x95200000 0x0 0x500000>;
+			no-map;
+		};
+
+		pil_adsp_mem: pil-adsp@95c00000 {
+			reg = <0x0 0x95c00000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		pil_gdsp0_mem: pil-gdsp0@97b00000 {
+			reg = <0x0 0x97b00000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		pil_gdsp1_mem: pil-gdsp1@99900000 {
+			reg = <0x0 0x99900000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		pil_cdsp0_mem: pil-cdsp0@9b800000 {
+			reg = <0x0 0x9b800000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		pil_gpu_mem: pil-gpu@9d600000 {
+			reg = <0x0 0x9d600000 0x0 0x2000>;
+			no-map;
+		};
+
+		pil_cdsp1_mem: pil-cdsp1@9d700000 {
+			reg = <0x0 0x9d700000 0x0 0x1e00000>;
+			no-map;
+		};
+
+		pil_cvp_mem: pil-cvp@9f500000 {
+			reg = <0x0 0x9f500000 0x0 0x700000>;
+			no-map;
+		};
+
+		pil_video_mem: pil-video@9fc00000 {
+			reg = <0x0 0x9fc00000 0x0 0x700000>;
+			no-map;
+		};
+
+		audio_mdf_mem: audio-mdf-region@ae000000 {
+			reg = <0x0 0xae000000 0x0 0x1000000>;
+			no-map;
+		};
+
+		firmware_mem: firmware-region@b0000000 {
+			reg = <0x0 0xb0000000 0x0 0x800000>;
+			no-map;
+		};
+
+		hyptz_reserved_mem: hyptz-reserved@beb00000 {
+			reg = <0x0 0xbeb00000 0x0 0x11500000>;
+			no-map;
+		};
+
+		scmi_mem: scmi-region@d0000000 {
+			reg = <0x0 0xd0000000 0x0 0x40000>;
+			no-map;
+		};
+
+		firmware_logs_mem: firmware-logs@d0040000 {
+			reg = <0x0 0xd0040000 0x0 0x10000>;
+			no-map;
+		};
+
+		firmware_audio_mem: firmware-audio@d0050000 {
+			reg = <0x0 0xd0050000 0x0 0x4000>;
+			no-map;
+		};
+
+		firmware_reserved_mem: firmware-reserved@d0054000 {
+			reg = <0x0 0xd0054000 0x0 0x9c000>;
+			no-map;
+		};
+
+		firmware_quantum_test_mem: firmware-quantum-test@d00f0000 {
+			reg = <0x0 0xd00f0000 0x0 0x10000>;
+			no-map;
+		};
+
+		tags_mem: tags@d0100000 {
+			reg = <0x0 0xd0100000 0x0 0x1200000>;
+			no-map;
+		};
+
+		qtee_mem: qtee@d1300000 {
+			reg = <0x0 0xd1300000 0x0 0x500000>;
+			no-map;
+		};
+
+		deepsleep_backup_mem: deepsleep-backup@d1800000 {
+			reg = <0x0 0xd1800000 0x0 0x100000>;
+			no-map;
+		};
+
+		trusted_apps_mem: trusted-apps@d1900000 {
+			reg = <0x0 0xd1900000 0x0 0x3800000>;
+			no-map;
+		};
+
+		tz_stat_mem: tz-stat@db100000 {
+			reg = <0x0 0xdb100000 0x0 0x100000>;
+			no-map;
+		};
+
+		cpucp_fw_mem: cpucp-fw@db200000 {
+			reg = <0x0 0xdb200000 0x0 0x100000>;
+			no-map;
+		};
+
+		cma: linux,cma {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xdfffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x2000000>;
+			linux,cma-default;
+		};
+	};
+
+	soc: soc@0 {
+		compatible = "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges = <0 0 0 0 0x10 0>;
+
+		dcc: dma@40ff000 {
+			compatible = "qcom,dcc-v3", "qcom,dcc";
+			reg = <0x0 0x040ff000 0x0 0x1000>,
+			      <0x0 0x040b8800 0x0 0x6000>;
+			qcom,dcc-offset = <0x38800>;
+		};
+
+		ipcc0: mailbox@408000 {
+			compatible = "qcom,sa8255p-ipcc", "qcom,ipcc";
+			reg = <0x0 0x00408000 0x0 0x1000>;
+			interrupts = <GIC_SPI 229 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			#mbox-cells = <2>;
+		};
+
+		ipcc1: mailbox@488000 {
+			compatible = "qcom,sa8255p-ipcc", "qcom,ipcc";
+			reg = <0x0 0x488000 0x0 0x1000>;
+			interrupts = <GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			#mbox-cells = <2>;
+			status = "disabled";
+		};
+
+		qupv3_id_2: geniqup@8c0000 {
+			compatible = "qcom,sa8255p-geni-se-qup";
+			reg = <0x0 0x008c0000 0x0 0x6000>;
+			ranges;
+			iommus = <&apps_smmu 0x5a3 0x0>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			status = "disabled";
+
+			i2c14: i2c@880000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0x880000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi14: spi@880000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0x880000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart14: serial@880000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x00880000 0x0 0x4000>;
+				interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c15: i2c@884000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0x884000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi15: spi@884000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0x884000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart15: serial@884000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x00884000 0x0 0x4000>;
+				interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c16: i2c@888000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0x888000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi16: spi@888000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0x00888000 0x0 0x4000>;
+				interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			uart16: serial@888000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x00888000 0x0 0x4000>;
+				interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c17: i2c@88c000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0x88c000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi17: spi@88c000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0x88c000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart17: serial@88c000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x0088c000 0x0 0x4000>;
+				interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c18: i2c@890000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0x00890000 0x0 0x4000>;
+				interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				status = "disabled";
+			};
+
+			spi18: spi@890000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0x890000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart18: serial@890000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x00890000 0x0 0x4000>;
+				interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c19: i2c@894000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0x894000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi19: spi@894000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0x894000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart19: serial@894000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x00894000 0x0 0x4000>;
+				interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c20: i2c@898000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0x898000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 834 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi20: spi@898000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0x898000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 834 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart20: serial@898000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x00898000 0x0 0x4000>;
+				interrupts = <GIC_SPI 834 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+		};
+
+		qupv3_id_0: geniqup@9c0000 {
+			compatible = "qcom,sa8255p-geni-se-qup";
+			reg = <0x0 0x9c0000 0x0 0x6000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			iommus = <&apps_smmu 0x403 0x0>;
+			status = "disabled";
+
+			i2c0: i2c@980000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0x980000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 550 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi0: spi@980000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0x980000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 550 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart0: serial@980000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x980000 0x0 0x4000>;
+				interrupts = <GIC_SPI 550 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c1: i2c@984000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0x984000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 551 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi1: spi@984000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0x984000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 551 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart1: serial@984000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x984000 0x0 0x4000>;
+				interrupts = <GIC_SPI 551 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c2: i2c@988000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0x988000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi2: spi@988000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0x988000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart2: serial@988000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x988000 0x0 0x4000>;
+				interrupts = <GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c3: i2c@98c000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0x98c000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi3: spi@98c000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0x98c000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart3: serial@98c000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x98c000 0x0 0x4000>;
+				interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c4: i2c@990000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0x990000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi4: spi@990000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0x990000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart4: serial@990000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x990000 0x0 0x4000>;
+				interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c5: i2c@994000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0x994000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi5: spi@994000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0x994000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart5: serial@994000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x994000 0x0 0x4000>;
+				interrupts = <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+		};
+
+		qupv3_id_1: geniqup@ac0000 {
+			compatible = "qcom,sa8255p-geni-se-qup";
+			reg = <0x0 0x00ac0000 0x0 0x6000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			iommus = <&apps_smmu 0x443 0x0>;
+			status = "disabled";
+
+			i2c7: i2c@a80000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0xa80000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi7: spi@a80000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0xa80000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart7: serial@a80000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x00a80000 0x0 0x4000>;
+				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c8: i2c@a84000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0xa84000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi8: spi@a84000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0xa84000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart8: serial@a84000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x00a84000 0x0 0x4000>;
+				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c9: i2c@a88000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0xa88000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi9: spi@a88000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0xa88000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart9: serial@a88000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0xa88000 0x0 0x4000>;
+				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c10: i2c@a8c000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0xa8c000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi10: spi@a8c000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0xa8c000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart10: serial@a8c000 {
+				compatible = "qcom,sa8255p-geni-debug-uart";
+				reg = <0x0 0x00a8c000 0x0 0x4000>;
+				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c11: i2c@a90000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0xa90000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi11: spi@a90000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0xa90000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart11: serial@a90000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x00a90000 0x0 0x4000>;
+				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c12: i2c@a94000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0xa94000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi12: spi@a94000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0xa94000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart12: serial@a94000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x00a94000 0x0 0x4000>;
+				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			i2c13: i2c@a98000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0xa98000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+		};
+
+		qupv3_id_3: geniqup@bc0000 {
+			compatible = "qcom,sa8255p-geni-se-qup";
+			reg = <0x0 0xbc0000 0x0 0x6000>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			iommus = <&apps_smmu 0x43 0x0>;
+			status = "disabled";
+
+			i2c21: i2c@b80000 {
+				compatible = "qcom,sa8255p-geni-i2c";
+				reg = <0x0 0xb80000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 831 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			spi21: spi@b80000 {
+				compatible = "qcom,sa8255p-geni-spi";
+				reg = <0x0 0xb80000 0x0 0x4000>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+				interrupts = <GIC_SPI 831 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+
+			uart21: serial@b80000 {
+				compatible = "qcom,sa8255p-geni-uart";
+				reg = <0x0 0x00b80000 0x0 0x4000>;
+				interrupts = <GIC_SPI 831 IRQ_TYPE_LEVEL_HIGH>;
+				status = "disabled";
+			};
+		};
+
+		rng: rng@10d2000 {
+			compatible = "qcom,sa8255p-trng", "qcom,trng";
+			reg = <0x0 0x010d2000 0x0 0x1000>;
+		};
+
+		pcie0_ep: pcie-ep@1c00000 {
+			compatible = "qcom,sa8775p-pcie-ep";
+			reg = <0x0 0x01c00000 0x0 0x3000>,
+			      <0x0 0x40000000 0x0 0xf20>,
+			      <0x0 0x40000f20 0x0 0xa8>,
+			      <0x0 0x40001000 0x0 0x4000>,
+			      <0x0 0x40200000 0x0 0x100000>,
+			      <0x0 0x01c03000 0x0 0x1000>,
+			      <0x0 0x40005000 0x0 0x2000>,
+			      <0x0 0x01c05200 0x0 0x1e8>;
+			reg-names = "parf", "dbi", "elbi", "atu", "addr_space",
+				    "mmio", "dma", "phy_pcs";
+
+			interrupts = <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 630 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "global", "doorbell", "dma";
+
+			dma-coherent;
+			iommus = <&pcie_smmu 0x0000 0x7f>;
+			max-link-speed = <4>;
+			num-lanes = <2>;
+
+			status = "disabled";
+		};
+
+		pcie1_ep: pcie-ep@1c10000 {
+			compatible = "qcom,sa8775p-pcie-ep";
+			reg = <0x0 0x01c10000 0x0 0x3000>,
+			      <0x0 0x60000000 0x0 0xf20>,
+			      <0x0 0x60000f20 0x0 0xa8>,
+			      <0x0 0x60001000 0x0 0x4000>,
+			      <0x0 0x60200000 0x0 0x100000>,
+			      <0x0 0x01c13000 0x0 0x1000>,
+			      <0x0 0x60005000 0x0 0x2000>,
+			      <0x0 0x01c16200 0x0 0x1e8>;
+			reg-names = "parf", "dbi", "elbi", "atu", "addr_space",
+				    "mmio", "dma", "phy_pcs";
+
+			interrupts = <GIC_SPI 518 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+
+			interrupt-names = "global", "doorbell", "dma";
+
+			dma-coherent;
+			iommus = <&pcie_smmu 0x80 0x7f>;
+			max-link-speed = <4>;
+			num-lanes = <4>;
+
+			status = "disabled";
+		};
+
+		ufs_mem_hc: ufs@1d84000 {
+			compatible = "qcom,sa8255p-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
+			reg = <0x0 0x01d84000 0x0 0x3000>;
+			interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+			lanes-per-direction = <2>;
+			iommus = <&apps_smmu 0x100 0x0>;
+			dma-coherent;
+			qcom,ice = <&ice>;
+			status = "disabled";
+		};
+
+		ice: crypto@1d88000 {
+			compatible = "qcom,sa8255p-inline-crypto-engine",
+				     "qcom,inline-crypto-engine";
+			reg = <0x0 0x01d88000 0x0 0x10000>;
+			qcom,ice-use-hwkm;
+			qcom,ice-skip-clk;
+		};
+
+		usb_0_hsphy: phy@88e4000 {
+			compatible = "qcom,sa8255p-usb-hs-phy",
+				     "qcom,usb-snps-hs-5nm-phy";
+			reg = <0x0 0x088e4000 0x0 0x120>;
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
+		usb_0_qmpphy: phy@88e8000 {
+			compatible = "qcom,sa8255p-qmp-usb3-uni-phy";
+			reg = <0x0 0x088e8000 0x0 0x2000>;
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
+		usb_0: usb@a6f8800 {
+			compatible = "qcom,sa8255p-dwc3", "qcom,dwc3";
+			reg = <0x0 0x0a6f8800 0x0 0x400>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			interrupts-extended = <&intc GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 12 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "dp_hs_phy_irq",
+					  "dm_hs_phy_irq",
+					  "ss_phy_irq";
+
+			wakeup-source;
+
+			status = "disabled";
+
+			usb_0_dwc3: usb@a600000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x0a600000 0x0 0xe000>;
+				interrupts = <GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH>;
+				iommus = <&apps_smmu 0x080 0x0>;
+				phys = <&usb_0_hsphy>, <&usb_0_qmpphy>;
+				phy-names = "usb2-phy", "usb3-phy";
+
+				snps,dis-u1-entry-quirk;
+				snps,dis-u2-entry-quirk;
+			};
+		};
+
+		usb_1_hsphy: phy@88e6000 {
+			compatible = "qcom,sa8255p-usb-hs-phy",
+				     "qcom,usb-snps-hs-5nm-phy";
+			reg = <0x0 0x088e6000 0x0 0x120>;
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
+		usb_1_qmpphy: phy@88ea000 {
+			compatible = "qcom,sa8255p-qmp-usb3-uni-phy";
+			reg = <0x0 0x088ea000 0x0 0x2000>;
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
+		usb_1: usb@a8f8800 {
+			compatible = "qcom,sa8255p-dwc3", "qcom,dwc3";
+			reg = <0x0 0x0a8f8800 0x0 0x400>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			interrupts-extended = <&intc GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 8 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 7 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 13 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "dp_hs_phy_irq",
+					  "dm_hs_phy_irq",
+					  "ss_phy_irq";
+
+			wakeup-source;
+
+			status = "disabled";
+
+			usb_1_dwc3: usb@a800000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x0a800000 0x0 0xe000>;
+				interrupts = <GIC_SPI 349 IRQ_TYPE_LEVEL_HIGH>;
+				iommus = <&apps_smmu 0x0a0 0x0>;
+				phys = <&usb_1_hsphy>, <&usb_1_qmpphy>;
+				phy-names = "usb2-phy", "usb3-phy";
+
+				snps,dis-u1-entry-quirk;
+				snps,dis-u2-entry-quirk;
+			};
+		};
+
+		usb_2_hsphy: phy@88e7000 {
+			compatible = "qcom,sa8255p-usb-hs-phy",
+				     "qcom,usb-snps-hs-5nm-phy";
+			reg = <0x0 0x088e7000 0x0 0x120>;
+			#phy-cells = <0>;
+
+			status = "disabled";
+		};
+
+		usb_2: usb@a4f8800 {
+			compatible = "qcom,sa8255p-dwc3", "qcom,dwc3";
+			reg = <0x0 0x0a4f8800 0x0 0x400>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			interrupts-extended = <&intc GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 10 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
+			interrupt-names = "pwr_event",
+					  "dp_hs_phy_irq",
+					  "dm_hs_phy_irq";
+
+			wakeup-source;
+
+			status = "disabled";
+
+			usb_2_dwc3: usb@a400000 {
+				compatible = "snps,dwc3";
+				reg = <0x0 0x0a400000 0x0 0xe000>;
+				interrupts = <GIC_SPI 442 IRQ_TYPE_LEVEL_HIGH>;
+				iommus = <&apps_smmu 0x020 0x0>;
+				phys = <&usb_2_hsphy>;
+				phy-names = "usb2-phy";
+			};
+		};
+
+		tcsr_mutex: hwlock@1f40000 {
+			compatible = "qcom,tcsr-mutex";
+			reg = <0x0 0x01f40000 0x0 0x20000>;
+			#hwlock-cells = <1>;
+		};
+
+		tcsr: syscon@1fc0000 {
+			compatible = "qcom,sa8255p-tcsr", "syscon";
+			reg = <0x0 0x1fc0000 0x0 0x30000>;
+		};
+
+		adreno_smmu: iommu@3da0000 {
+			compatible = "qcom,sa8255p-smmu-500", "qcom,adreno-smmu",
+				     "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x03da0000 0x0 0x20000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <2>;
+			dma-coherent;
+			interrupts = <GIC_SPI 673 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 674 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 681 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 682 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pdc: interrupt-controller@b220000 {
+			compatible = "qcom,sa8255p-pdc", "qcom,pdc";
+			reg = <0x0 0x0b220000 0x0 0x30000>,
+			      <0x0 0x17c000f0 0x0 0x64>;
+			qcom,pdc-ranges = <0 480 40>,
+					  <40 140 14>,
+					  <54 263 1>,
+					  <55 306 4>,
+					  <59 312 3>,
+					  <62 374 2>,
+					  <64 434 2>,
+					  <66 438 2>,
+					  <70 520 1>,
+					  <73 523 1>,
+					  <118 568 6>,
+					  <124 609 3>,
+					  <159 638 1>,
+					  <160 720 3>,
+					  <169 728 30>,
+					  <199 416 2>,
+					  <201 449 1>,
+					  <202 89 1>,
+					  <203 451 1>,
+					  <204 462 1>,
+					  <205 264 1>,
+					  <206 579 1>,
+					  <207 653 1>,
+					  <208 656 1>,
+					  <209 659 1>,
+					  <210 122 1>,
+					  <211 699 1>,
+					  <212 705 1>,
+					  <213 450 1>,
+					  <214 643 2>,
+					  <216 646 5>,
+					  <221 390 5>,
+					  <226 700 2>,
+					  <228 440 1>,
+					  <229 663 1>,
+					  <230 524 2>,
+					  <232 612 3>,
+					  <235 723 5>;
+			#interrupt-cells = <2>;
+			interrupt-parent = <&intc>;
+			interrupt-controller;
+		};
+
+		tsens2: thermal-sensor@c251000 {
+			compatible = "qcom,sa8255p-tsens", "qcom,tsens-v2";
+			reg = <0x0 0x0c251000 0x0 0x1ff>,
+			      <0x0 0x0c224000 0x0 0x8>;
+			interrupts = <GIC_SPI 572 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 609 IRQ_TYPE_LEVEL_HIGH>;
+			#qcom,sensors = <13>;
+			interrupt-names = "uplow", "critical";
+			#thermal-sensor-cells = <1>;
+		};
+
+		tsens3: thermal-sensor@c252000 {
+			compatible = "qcom,sa8255p-tsens", "qcom,tsens-v2";
+			reg = <0x0 0x0c252000 0x0 0x1ff>,
+			      <0x0 0x0c225000 0x0 0x8>;
+			interrupts = <GIC_SPI 573 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 610 IRQ_TYPE_LEVEL_HIGH>;
+			#qcom,sensors = <13>;
+			interrupt-names = "uplow", "critical";
+			#thermal-sensor-cells = <1>;
+		};
+
+		tsens0: thermal-sensor@c263000 {
+			compatible = "qcom,sa8255p-tsens", "qcom,tsens-v2";
+			reg = <0x0 0x0c263000 0x0 0x1ff>,
+			      <0x0 0x0c222000 0x0 0x8>;
+			interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH>;
+			#qcom,sensors = <12>;
+			interrupt-names = "uplow", "critical";
+			#thermal-sensor-cells = <1>;
+		};
+
+		tsens1: thermal-sensor@c265000 {
+			compatible = "qcom,sa8255p-tsens", "qcom,tsens-v2";
+			reg = <0x0 0x0c265000 0x0 0x1ff>,
+			      <0x0 0x0c223000 0x0 0x8>;
+			interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 509 IRQ_TYPE_LEVEL_HIGH>;
+			#qcom,sensors = <12>;
+			interrupt-names = "uplow", "critical";
+			#thermal-sensor-cells = <1>;
+		};
+
+		aoss_qmp: power-management@c300000 {
+			compatible = "qcom,sa8255p-aoss-qmp", "qcom,aoss-qmp";
+			reg = <0x0 0x0c300000 0x0 0x400>;
+			interrupts-extended = <&ipcc0 IPCC_CLIENT_AOP
+					       IPCC_MPROC_SIGNAL_GLINK_QMP
+					       IRQ_TYPE_EDGE_RISING>;
+			mboxes = <&ipcc0 IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_GLINK_QMP>;
+			#clock-cells = <0>;
+		};
+
+		sram@c3f0000 {
+			compatible = "qcom,rpmh-stats";
+			reg = <0x0 0x0c3f0000 0x0 0x400>;
+		};
+
+		tlmm: pinctrl@f000000 {
+			compatible = "qcom,sa8255p-tlmm";
+			reg = <0x0 0x0f000000 0x0 0x1000000>;
+			interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			gpio-ranges = <&tlmm 0 0 149>;
+			wakeup-parent = <&pdc>;
+		};
+
+		apps_smmu: iommu@15000000 {
+			compatible = "qcom,sa8255p-smmu-500", "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x15000000 0x0 0x100000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <2>;
+
+			interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 316 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 317 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 320 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 321 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 322 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 327 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 328 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 329 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 331 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 332 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 333 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 706 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 689 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 690 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 691 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 692 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 693 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 694 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 695 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 696 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 413 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 708 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 709 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 710 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 711 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 414 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 712 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 713 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 714 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 715 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 912 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 911 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 910 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 909 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 908 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 907 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 906 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 905 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 904 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 903 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 902 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 901 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 900 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 899 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 898 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 897 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 896 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 895 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 894 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 893 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 892 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 891 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		pcie_smmu: iommu@15200000 {
+			compatible = "qcom,sa8255p-smmu-500", "qcom,smmu-500", "arm,mmu-500";
+			reg = <0x0 0x15200000 0x0 0x80000>;
+			#iommu-cells = <2>;
+			#global-interrupts = <2>;
+			dma-coherent;
+
+			interrupts = <GIC_SPI 920 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 921 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 925 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 926 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 927 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 928 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 950 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 951 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 952 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 953 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 954 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 955 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 956 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 957 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 958 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 885 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 886 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 887 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 888 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 820 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 823 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 310 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 452 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 840 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 841 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 842 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 843 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 844 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 845 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 846 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 847 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 848 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 849 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 802 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 803 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 804 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 805 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 806 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 807 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 808 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 809 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 810 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 811 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 812 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 813 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 814 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 837 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 838 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 839 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 854 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 855 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 856 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 790 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 791 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 792 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 793 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 794 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 795 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 796 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		intc: interrupt-controller@17a00000 {
+			compatible = "arm,gic-v3";
+			reg = <0x0 0x17a00000 0x0 0x10000>,	/* GICD */
+			      <0x0 0x17a60000 0x0 0x100000>;	/* GICR * 8 */
+			interrupt-controller;
+			#interrupt-cells = <3>;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+			#redistributor-regions = <1>;
+			redistributor-stride = <0x0 0x20000>;
+		};
+
+		watchdog@17c10000 {
+			compatible = "qcom,apss-wdt-sa8255p", "qcom,kpss-wdt";
+			reg = <0x0 0x17c10000 0x0 0x1000>;
+			clocks = <&sleep_clk>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_EDGE_RISING>;
+		};
+
+		memtimer: timer@17c20000 {
+			compatible = "arm,armv7-timer-mem";
+			reg = <0x0 0x17c20000 0x0 0x1000>;
+			ranges = <0x0 0x0 0x0 0x20000000>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			frame@17c21000 {
+				reg = <0x17c21000 0x1000>,
+				      <0x17c22000 0x1000>;
+				interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+				frame-number = <0>;
+			};
+
+			frame@17c23000 {
+				reg = <0x17c23000 0x1000>;
+				interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+				frame-number = <1>;
+				status = "disabled";
+			};
+
+			frame@17c25000 {
+				reg = <0x17c25000 0x1000>;
+				interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+				frame-number = <2>;
+				status = "disabled";
+			};
+
+			frame@17c27000 {
+				reg = <0x17c27000 0x1000>;
+				interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+				frame-number = <3>;
+				status = "disabled";
+			};
+
+			frame@17c29000 {
+				reg = <0x17c29000 0x1000>;
+				interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+				frame-number = <4>;
+				status = "disabled";
+			};
+
+			frame@17c2b000 {
+				reg = <0x17c2b000 0x1000>;
+				interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+				frame-number = <5>;
+				status = "disabled";
+			};
+
+			frame@17c2d000 {
+				reg = <0x17c2d000 0x1000>;
+				interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+				frame-number = <6>;
+				status = "disabled";
+			};
+		};
+
+		cpufreq_hw: cpufreq@18591000 {
+			compatible = "qcom,sa8255p-cpufreq-epss",
+				     "qcom,cpufreq-epss";
+			reg = <0x0 0x18591000 0x0 0x1000>,
+			      <0x0 0x18593000 0x0 0x1000>;
+			reg-names = "freq-domain0", "freq-domain1";
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "dcvsh-irq-0", "dcvsh-irq-1";
+
+			clocks = <&bi_tcxo_div2>, <&gpll0_board_clk>;
+			clock-names = "xo", "alternate";
+
+			#freq-domain-cells = <1>;
+		};
+
+		ethernet1: ethernet@23000000 {
+			compatible = "qcom,sa8255p-ethqos";
+			reg = <0x0 0x23000000 0x0 0x10000>,
+			      <0x0 0x23016000 0x0 0x100>;
+			reg-names = "stmmaceth", "rgmii";
+
+			interrupts = <GIC_SPI 929 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 781 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq", "sfty";
+
+			iommus = <&apps_smmu 0x140 0xf>;
+			dma-coherent;
+
+			snps,tso;
+			snps,pbl = <32>;
+			rx-fifo-depth = <16384>;
+			tx-fifo-depth = <16384>;
+
+			status = "disabled";
+		};
+
+		ethernet0: ethernet@23040000 {
+			compatible = "qcom,sa8255p-ethqos";
+			reg = <0x0 0x23040000 0x0 0x10000>,
+			      <0x0 0x23056000 0x0 0x100>;
+			reg-names = "stmmaceth", "rgmii";
+
+			interrupts = <GIC_SPI 946 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 782 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq", "sfty";
+
+			iommus = <&apps_smmu 0x120 0xf>;
+			dma-coherent;
+
+			snps,tso;
+			snps,pbl = <32>;
+			rx-fifo-depth = <16384>;
+			tx-fifo-depth = <16384>;
+
+			status = "disabled";
+		};
+
+		pcie0: pci@400000000 {
+			compatible = "qcom,pcie-ecam-rc";
+			reg = <0x4 0x00000000 0x0 0x10000000>;
+
+			device_type = "pci";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			ranges = <0x01000000 0x0 0x40000000 0x0 0x40000000 0x0 0x100000>,
+				 <0x02000000 0x0 0x40100000 0x0 0x40100000 0x0 0x1ff00000>,
+				 <0x43000000 0x4 0x10100000 0x4 0x10100000 0x0 0x100000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <0>;
+
+			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-parent = <&intc>;
+
+			iommus = <&pcie_smmu 0x00 0x7f>;
+			iommu-map = <0x0 &pcie_smmu 0x0000 0x1>,
+				    <0x100 &pcie_smmu 0x0001 0x1>,
+				    <0x200 &pcie_smmu 0x0002 0x1>,
+				    <0x300 &pcie_smmu 0x0003 0x1>;
+
+			status = "disabled";
+		};
+
+		pcie1: pci@600000000 {
+			compatible = "qcom,pcie-ecam-rc";
+			reg = <0x6 0x00000000 0x0 0x10000000>;
+
+			device_type = "pci";
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			ranges = <0x01000000 0x0 0x60000000 0x0 0x60000000 0x0 0x100000>,
+				 <0x02000000 0x0 0x60100000 0x0 0x60100000 0x0 0x1ff00000>,
+				 <0x43000000 0x6 0x10100000 0x6 0x10100000 0x0 0x100000>;
+			bus-range = <0x00 0xff>;
+
+			dma-coherent;
+
+			linux,pci-domain = <1>;
+
+			interrupts = <GIC_SPI 519 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-parent = <&intc>;
+
+			iommus = <&pcie_smmu 0x80 0x7f>;
+			iommu-map = <0x0 &pcie_smmu 0x0080 0x1>,
+				    <0x100 &pcie_smmu 0x0081 0x1>,
+				    <0x200 &pcie_smmu 0x0082 0x1>,
+				    <0x208 &pcie_smmu 0x0083 0x1>,
+				    <0x210 &pcie_smmu 0x0084 0x1>,
+				    <0x300 &pcie_smmu 0x0085 0x1>,
+				    <0xab00 &pcie_smmu 0x0086 0x1>;
+
+			status = "disabled";
+		};
+	};
+
+	thermal-zones {
+		aoss-0-thermal {
+			thermal-sensors = <&tsens0 0>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-0-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens0 1>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-1-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens0 2>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-2-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens0 3>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-3-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens0 4>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		gpuss-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens0 5>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		gpuss-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens0 6>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		gpuss-2-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens0 7>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		audio-thermal {
+			thermal-sensors = <&tsens0 8>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		camss-0-thermal {
+			thermal-sensors = <&tsens0 9>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		pcie-0-thermal {
+			thermal-sensors = <&tsens0 10>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpuss-0-0-thermal {
+			thermal-sensors = <&tsens0 11>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		aoss-1-thermal {
+			thermal-sensors = <&tsens1 0>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-0-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens1 1>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-1-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens1 2>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-2-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens1 3>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-0-3-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens1 4>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		gpuss-3-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens1 5>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		gpuss-4-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens1 6>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		gpuss-5-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens1 7>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		video-thermal {
+			thermal-sensors = <&tsens1 8>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		camss-1-thermal {
+			thermal-sensors = <&tsens1 9>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		pcie-1-thermal {
+			thermal-sensors = <&tsens1 10>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpuss-0-1-thermal {
+			thermal-sensors = <&tsens1 11>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		aoss-2-thermal {
+			thermal-sensors = <&tsens2 0>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-0-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 1>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-1-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 2>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-2-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 3>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-3-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 4>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-0-0-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 5>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-0-1-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 6>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-0-2-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 7>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-1-0-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 8>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-1-1-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 9>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-1-2-0-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens2 10>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		ddrss-0-thermal {
+			thermal-sensors = <&tsens2 11>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpuss-1-0-thermal {
+			thermal-sensors = <&tsens2 12>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		aoss-3-thermal {
+			thermal-sensors = <&tsens3 0>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-0-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 1>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-1-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 2>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-2-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 3>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpu-1-3-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 4>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-0-0-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 5>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-0-1-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 6>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-0-2-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 7>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-1-0-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 8>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-1-1-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 9>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		nsp-1-2-1-thermal {
+			polling-delay-passive = <10>;
+
+			thermal-sensors = <&tsens3 10>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		ddrss-1-thermal {
+			thermal-sensors = <&tsens3 11>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+
+		cpuss-1-1-thermal {
+			thermal-sensors = <&tsens3 12>;
+
+			trips {
+				trip-point0 {
+					temperature = <105000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+
+				trip-point1 {
+					temperature = <115000>;
+					hysteresis = <10000>;
+					type = "passive";
+				};
+			};
+		};
+	};
+
+	arch_timer: timer {
+		compatible = "arm,armv8-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8540p.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8540p.dtsi
@@ -168,6 +168,9 @@
 };
 
 &gpucc {
+	/* SA8295P and SA8540P doesn't provide gfx.lvl */
+	/delete-property/ power-domains;
+
 	status = "disabled";
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p-addons-ride-r3.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8775p-addons-ride-r3.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "sa8775p-ride-r3.dts"
+#include "sa8775p-addons-ride.dtsi"
+
+/ {
+	model = "Qualcomm SA8775P Ride Rev3";
+	compatible = "qcom,sa8775p-addons-ride-r3", "qcom,sa8775p";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p-addons-ride.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8775p-addons-ride.dts
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "sa8775p-ride.dts"
+#include "sa8775p-addons-ride.dtsi"
+
+/ {
+	model = "Qualcomm SA8775P Ride";
+	compatible = "qcom,sa8775p-addons-ride", "qcom,sa8775p";
+};
+
+
+&remoteproc_adsp {
+	firmware-name = "qcom/sa8775p/adsp.mdt";
+	status = "okay";
+};
+
+&remoteproc_cdsp0 {
+	firmware-name = "qcom/sa8775p/cdsp0.mdt";
+	status = "okay";
+};
+
+&remoteproc_cdsp1 {
+	firmware-name = "qcom/sa8775p/cdsp1.mdt";
+	status = "okay";
+};
+
+&remoteproc_gpdsp0 {
+	firmware-name = "qcom/sa8775p/gpdsp0.mdt";
+	status = "okay";
+};
+
+&remoteproc_gpdsp1 {
+	firmware-name = "qcom/sa8775p/gpdsp1.mdt";
+	status = "okay";
+};
+
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p-addons-ride.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8775p-addons-ride.dtsi
@@ -0,0 +1,501 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "sa8775p-addons.dtsi"
+
+/ {
+	sound {
+		compatible = "qcom,qcs9100-sndcard";
+		model = "qcs9100-ridesx-snd-card";
+
+		clocks = <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+			    <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+		clock-names = "macro", "dcodec";
+
+		pinctrl-names = "default", "stub_aif0_active", "stub_aif0_sleep",
+				"stub_aif1_active", "stub_aif1_sleep", "stub_aif2_active",
+				"stub_aif2_sleep", "stub_aif3_active", "stub_aif3_sleep";
+		pinctrl-0 = <&mi2s1_data0_sleep>, <&mi2s1_data1_sleep>, <&mi2s1_sck_sleep>,
+			    <&mi2s1_ws_sleep>, <&lpass_i2s1_clk_sleep>, <&lpass_i2s1_data_sleep>,
+			    <&lpass_i2s1_ws_sleep>, <&hs2_mi2s_data0_sleep>, <&mi2s_mclk_sleep>,
+			    <&hs2_mi2s_sck_sleep>, <&hs2_mi2s_data1_sleep>,<&hs2_mi2s_ws_sleep>;
+		pinctrl-1 = <&lpass_i2s1_clk>, <&lpass_i2s1_data>, <&lpass_i2s1_ws>;
+		pinctrl-2 = <&lpass_i2s1_clk_sleep>, <&lpass_i2s1_data_sleep>,
+			    <&lpass_i2s1_ws_sleep>;
+		pinctrl-3 = <&mi2s1_data0>, <&mi2s1_data1>, <&mi2s1_sck>, <&mi2s1_ws>;
+		pinctrl-4 = <&mi2s1_data0_sleep>, <&mi2s1_data1_sleep>, <&mi2s1_sck_sleep>,
+			    <&mi2s1_ws_sleep>;
+		pinctrl-5 = <&hs2_mi2s_data0>, <&hs2_mi2s_data1>, <&hs2_mi2s_sck>, <&mi2s_mclk>,
+			    <&hs2_mi2s_ws>;
+		pinctrl-6 = <&hs2_mi2s_data0_sleep>, <&hs2_mi2s_data1_sleep>, <&hs2_mi2s_sck_sleep>,
+			    <&mi2s_mclk_sleep>,<&hs2_mi2s_ws_sleep>;
+		pinctrl-7 = <&mi2s1_data0>, <&mi2s1_data1>, <&mi2s1_sck>, <&mi2s_mclk>,
+			    <&mi2s1_ws>;
+		pinctrl-8 = <&mi2s1_data0_sleep>, <&mi2s1_data1_sleep>, <&mi2s1_sck_sleep>,
+			    <&mi2s1_ws_sleep>, <&mi2s_mclk_sleep>;
+
+		mi2s1-capture-dai-link {
+			link-name = "MI2S-LPAIF-TX-SECONDARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai SECONDARY_MI2S_TX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 3>;
+			};
+		};
+
+		mi2s1-playback-dai-link {
+			link-name = "MI2S-LPAIF-RX-SECONDARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai SECONDARY_MI2S_RX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 2>;
+			};
+		};
+
+		lpi-mi2s1-capture-dai-link {
+			link-name = "MI2S-LPAIF_VA-TX-PRIMARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_MI2S_TX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 1>;
+			};
+		};
+
+		lpi-mi2s1-playback-dai-link {
+			link-name = "MI2S-LPAIF_VA-RX-PRIMARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 0>;
+			};
+		};
+
+		tdm1-capture-dai-link {
+			link-name = "TDM-LPAIF-TX-SECONDARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai SECONDARY_TDM_TX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 3>;
+			};
+		};
+
+		tdm1-playback-dai-link {
+			link-name = "TDM-LPAIF-RX-SECONDARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai SECONDARY_TDM_RX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 2>;
+			};
+		};
+
+		lpi-tdm1-capture-dai-link {
+			link-name = "TDM-LPAIF_VA-TX-PRIMARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_TDM_TX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 1>;
+			};
+		};
+
+		lpi-tdm1-playback-dai-link {
+			link-name = "TDM-LPAIF_VA-RX-PRIMARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai PRIMARY_TDM_RX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 0>;
+			};
+		};
+
+		hs2-mi2s-capture-dai-link {
+			link-name = "MI2S-LPAIF_SDR-TX-TERTIARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai TERTIARY_SDR_MI2S_TX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 5>;
+			};
+		};
+
+		hs2-mi2s-playback-dai-link {
+			link-name = "MI2S-LPAIF_SDR-RX-TERTIARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai TERTIARY_SDR_MI2S_RX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 4>;
+			};
+		};
+
+		tdm2-capture-dai-link {
+			link-name = "TDM-LPAIF_SDR-TX-TERTIARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai TERTIARY_SDR_TDM_TX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 5>;
+			};
+		};
+
+		tdm2-playback-dai-link {
+			link-name = "TDM-LPAIF_SDR-RX-TERTIARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai TERTIARY_SDR_TDM_RX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 4>;
+			};
+		};
+
+		hs3-mi2s-capture-dai-link {
+			link-name = "MI2S-LPAIF_SDR-TX-QUATERNARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai QUATERNARY_SDR_MI2S_TX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 7>;
+			};
+		};
+
+		hs3-mi2s-playback-dai-link {
+			link-name = "MI2S-LPAIF_SDR-RX-QUATERNARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai QUATERNARY_SDR_MI2S_RX>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 6>;
+			};
+		};
+
+		tdm3-capture-dai-link {
+			link-name = "TDM-LPAIF_SDR-TX-QUATERNARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai QUATERNARY_SDR_TDM_TX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 7>;
+			};
+		};
+
+		tdm3-playback-dai-link {
+			link-name = "TDM-LPAIF_SDR-RX-QUATERNARY";
+
+			cpu {
+				sound-dai = <&q6apmbedai QUATERNARY_SDR_TDM_RX_0>;
+			};
+
+			codec {
+				sound-dai = <&msm_stub_codec 6>;
+			};
+		};
+
+		dp0-dai-link {
+
+			link-name = "DISPLAY_PORT-RX";
+
+			cpu {
+				sound-dai = <&q6apmbedai DISPLAY_PORT_RX_0>;
+			};
+
+			codec {
+				sound-dai = <&mdss0_dp0>;
+			};
+		};
+	};
+};
+
+&lpass_tlmm {
+	lpass_i2s1_clk: i2s1-clk-state {
+			pins = "gpio6";
+			function = "i2s1_clk";
+			drive-strength = <8>;
+			bias-disable;
+			output-high;
+	};
+
+	lpass_i2s1_clk_sleep: i2s1-clk-sleep-state {
+			pins = "gpio6";
+			function = "i2s1_clk";
+			drive-strength = <2>;
+			bias-pull-down;
+			input-enable;
+	};
+
+	lpass_i2s1_data: i2s1-data-state {
+			pins = "gpio8", "gpio9";
+			function = "i2s1_data";
+			drive-strength = <8>;
+			bias-disable;
+	};
+
+	lpass_i2s1_data_sleep: i2s1-data-sleep-state {
+			pins = "gpio8", "gpio9";
+			function = "i2s1_data";
+			drive-strength = <2>;
+			bias-pull-down;
+			input-enable;
+	};
+
+	lpass_i2s1_ws: i2s1-ws-state {
+			pins = "gpio7";
+			function = "i2s1_ws";
+			drive-strength = <8>;
+			output-high;
+	};
+
+	lpass_i2s1_ws_sleep: i2s1-ws-sleep-state {
+			pins = "gpio7";
+			function = "i2s1_ws";
+			drive-strength = <2>;
+			bias-pull-down;
+			input-enable;
+	};
+};
+
+&soc {
+	msm_stub_codec: msm-stub-codec {
+		compatible = "qcom,msm-stub-codec";
+		#sound-dai-cells = <1>;
+	};
+
+	spf_core_platform: spf-core-platform {
+		compatible = "qcom,spf-core-platform";
+
+		msm_audio_mem: msm-audio-mem {
+			compatible = "qcom,msm-audio-mem";
+			qcom,smmu-version = <2>;
+			qcom,smmu-enabled;
+			iommus = <&apps_smmu 0x3001 0x0>;
+			qcom,iommu-dma-addr-pool = <0x10000000 0x10000000>;
+			qcom,smmu-sid-mask = /bits/ 64 <0xf>;
+			dma-coherent;
+		};
+
+		msm_audio_mem_cma: msm-audio-mem-cma {
+			compatible = "qcom,msm-audio-mem";
+			memory-region = <&audio_cma_mem>;
+		};
+	};
+};
+
+&tlmm {
+	hs0_mi2s: hs0-mi2s-state {
+		pins = "gpio114", "gpio115", "gpio116", "gpio117";
+		function = "hs0_mi2s";
+	};
+
+	hs1_mi2s: hs1-mi2s-state {
+		pins = "gpio118", "gpio119", "gpio120", "gpio121";
+		function = "hs1_mi2s";
+	};
+
+	hs2_mi2s_data0: hs2-mi2s-data0-state {
+		pins = "gpio124";
+		function = "hs2_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	hs2_mi2s_data0_sleep: hs2-mi2s-data0-sleep-state {
+		pins = "gpio124";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs2_mi2s_data1: hs2-mi2s-data1-state {
+		pins = "gpio125";
+		function = "hs2_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	hs2_mi2s_data1_sleep: hs2-mi2s-data1-sleep-state {
+		pins = "gpio125";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs2_mi2s_sck: hs2-mi2s-sck-state {
+		pins = "gpio122";
+		function = "hs2_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	hs2_mi2s_sck_sleep: hs2-mi2s-sck-sleep-state {
+		pins = "gpio122";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s_mclk: mi2s-mclk-state {
+		pins = "gpio105";
+		function = "mi2s_mclk0";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	mi2s_mclk_sleep: mi2s-mclk-sleep-state {
+		pins = "gpio105";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	hs2_mi2s_ws: hs2-mi2s-ws-state {
+		pins = "gpio123";
+		function = "hs2_mi2s";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	hs2_mi2s_ws_sleep: hs2-mi2s-ws-sleep-state {
+		pins = "gpio123";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s1_data0: mi2s1-data0-state {
+		pins = "gpio108";
+		function = "mi2s1_data0";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	mi2s1_data0_sleep: mi2s1-data0-sleep-state {
+		pins = "gpio108";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s1_data1: mi2s1-data1-state {
+		pins = "gpio109";
+		function = "mi2s1_data1";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	mi2s1_data1_sleep: mi2s1-data1-sleep-state {
+		pins = "gpio109";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s1_sck: mi2s1-sck-state {
+		pins = "gpio106";
+		function = "mi2s1_sck";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	mi2s1_sck_sleep: mi2s1-sck-sleep-state {
+		pins = "gpio106";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s1_ws: mi2s1-ws-state {
+		pins = "gpio107";
+		function = "mi2s1_ws";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	mi2s1_ws_sleep: mi2s1-ws-sleep-state {
+		pins = "gpio107";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+		input-enable;
+	};
+
+	mi2s2_data0: mi2s2-data0-state {
+		pins = "gpio112";
+		function = "mi2s2_data0";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	mi2s2_data1: mi2s2-data1-state {
+		pins = "gpio113";
+		function = "mi2s2_data1";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	mi2s2_sck: mi2s2-sck-state {
+		pins = "gpio110";
+		function = "mi2s2_sck";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+
+	mi2s2_ws: mi2s2-ws-state {
+		pins = "gpio111";
+		function = "mi2s2_ws";
+		drive-strength = <8>;
+		bias-disable;
+		output-high;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p-addons.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8775p-addons.dtsi
@@ -0,0 +1,821 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "sa8775p-dma-heaps.dtsi"
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+	reserved-memory {
+		audio_cma_mem: qcom,audio-ml {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x1000000>;
+		};
+
+		dump_mem: mem-dump-region {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			size = <0x0 0x3000000>;
+		};
+
+		qseecom_mem: qcom,qseecom {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x1400000>; /* 20M */
+		};
+
+		qseecom_ta_mem: qcom,qseecom-ta {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x1000000>; /* 16M */
+		};
+	};
+
+	firmware {
+		qcom_mem_object {
+			compatible = "qcom,mem-object";
+		};
+
+		qcom_smcinvoke {
+			compatible = "qcom,smcinvoke";
+		};
+	};
+
+	mem-dump {
+		compatible = "qcom,mem-dump";
+		memory-region = <&dump_mem>;
+
+		c0-context {
+			qcom,dump-id = <0x0>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c0-scandump {
+			qcom,dump-id = <0x130>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		c100-context {
+			qcom,dump-id = <0x1>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c100-scandump {
+			qcom,dump-id = <0x131>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		c200-context {
+			qcom,dump-id = <0x2>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c200-scandump {
+			qcom,dump-id = <0x132>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		c300-context {
+			qcom,dump-id = <0x3>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c300-scandump {
+			qcom,dump-id = <0x133>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		c400-context {
+			qcom,dump-id = <0x4>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c500-context {
+			qcom,dump-id = <0x5>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c600-context {
+			qcom,dump-id = <0x6>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c700-context {
+			qcom,dump-id = <0x7>;
+			qcom,dump-size = <0x800>;
+		};
+
+		c10000-scandump {
+			qcom,dump-id = <0x134>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		c10100-scandump {
+			qcom,dump-id = <0x135>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		c10200-scandump {
+			qcom,dump-id = <0x136>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		c10300-scandump {
+			qcom,dump-id = <0x137>;
+			qcom,dump-size = <0x40000>;
+		};
+
+		cpuss-reg {
+			qcom,dump-id = <0xef>;
+			qcom,dump-size = <0x20000>;
+		};
+
+		etf-swao {
+			qcom,dump-id = <0xf1>;
+			qcom,dump-size = <0x10000>;
+		};
+
+		etfswao-reg {
+			qcom,dump-id = <0x102>;
+			qcom,dump-size = <0x1000>;
+		};
+
+		etr-reg {
+			qcom,dump-id = <0x100>;
+			qcom,dump-size = <0x1000>;
+		};
+
+		fcm {
+			qcom,dump-id = <0xee>;
+			qcom,dump-size = <0x8400>;
+		};
+
+		l1-dcache0 {
+			qcom,dump-id = <0x80>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dcache100 {
+			qcom,dump-id = <0x81>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dcache200 {
+			qcom,dump-id = <0x82>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dcache300 {
+			qcom,dump-id = <0x83>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dcache10000 {
+			qcom,dump-id = <0x84>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dcache10100 {
+			qcom,dump-id = <0x85>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dcache10200 {
+			qcom,dump-id = <0x86>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dcache10300 {
+			qcom,dump-id = <0x87>;
+			qcom,dump-size = <0x12100>;
+		};
+
+		l1-dtlb10000 {
+			qcom,dump-id = <0x44>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-dtlb10100 {
+			qcom,dump-id = <0x45>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-dtlb10200 {
+			qcom,dump-id = <0x46>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-dtlb10300 {
+			qcom,dump-id = <0x47>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-icache0 {
+			qcom,dump-id = <0x60>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-icache100 {
+			qcom,dump-id = <0x61>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-icache200 {
+			qcom,dump-id = <0x62>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-icache300 {
+			qcom,dump-id = <0x63>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-icache10000 {
+			qcom,dump-id = <0x64>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-icache10100 {
+			qcom,dump-id = <0x65>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-icache10200 {
+			qcom,dump-id = <0x66>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-icache10300 {
+			qcom,dump-id = <0x67>;
+			qcom,dump-size = <0x26100>;
+		};
+
+		l1-itlb10000 {
+			qcom,dump-id = <0x24>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-itlb10100 {
+			qcom,dump-id = <0x25>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-itlb10200 {
+			qcom,dump-id = <0x26>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l1-itlb10300 {
+			qcom,dump-id = <0x27>;
+			qcom,dump-size = <0x300>;
+		};
+
+		l2-cache10000 {
+			qcom,dump-id = <0xc4>;
+			qcom,dump-size = <0x90100>;
+		};
+
+		l2-cache10100 {
+			qcom,dump-id = <0xc5>;
+			qcom,dump-size = <0x90100>;
+		};
+
+		l2-cache10200 {
+			qcom,dump-id = <0xc6>;
+			qcom,dump-size = <0x90100>;
+		};
+
+		l2-cache10300 {
+			qcom,dump-id = <0xc7>;
+			qcom,dump-size = <0x90100>;
+		};
+
+		l2-tlb0 {
+			qcom,dump-id = <0x120>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		l2-tlb100 {
+			qcom,dump-id = <0x121>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		l2-tlb200 {
+			qcom,dump-id = <0x122>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		l2-tlb300 {
+			qcom,dump-id = <0x123>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		l2-tlb10000 {
+			qcom,dump-id = <0x124>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		l2-tlb10100 {
+			qcom,dump-id = <0x125>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		l2-tlb10200 {
+			qcom,dump-id = <0x126>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		l2-tlb10300 {
+			qcom,dump-id = <0x127>;
+			qcom,dump-size = <0x6100>;
+		};
+
+		misc-data {
+			qcom,dump-id = <0xe8>;
+			qcom,dump-size = <0x1000>;
+		};
+
+		pmic {
+			qcom,dump-id = <0xe4>;
+			qcom,dump-size = <0x80000>;
+		};
+
+		rpm-sw {
+			qcom,dump-id = <0xea>;
+			qcom,dump-size = <0x28000>;
+		};
+
+		rpmh {
+			qcom,dump-id = <0xec>;
+			qcom,dump-size = <0x2000000>;
+		};
+	};
+};
+
+&remoteproc_cdsp0 {
+	cooling {
+		compatible = "qcom,qmi-cooling-cdsp";
+
+		cdsp_sw0: cdsp_sw {
+			label = "cdsp_sw";
+			#cooling-cells = <2>;
+		};
+	};
+};
+
+&remoteproc_cdsp1 {
+	cooling {
+		compatible = "qcom,qmi-cooling-cdsp1";
+
+		cdsp_sw1: cdsp_sw {
+			label = "cdsp_sw";
+			#cooling-cells = <2>;
+		};
+	};
+};
+
+&soc {
+	qcom,mem-buf {
+		compatible = "qcom,mem-buf";
+		qcom,mem-buf-capabilities = "supplier";
+		qcom,vmid = <3>;
+	};
+
+	qcom,mem-buf-msgq {
+		compatible = "qcom,mem-buf-msgq";
+	};
+
+	qcom,secure-buffer {
+		compatible = "qcom,secure-buffer";
+		qcom,vmid-cp-camera-preview-ro;
+	};
+
+	qcom_tzlog: tz-log@146d8720 {
+		compatible = "qcom,tz-log";
+		reg = <0x0 0x146d8720 0x0 0x3000>;
+		qcom,hyplog-enabled;
+		hyplog-address-offset = <0x410>;
+		hyplog-size-offset = <0x414>;
+	};
+
+	lpass_tlmm: pinctrl@3440000 {
+		compatible = "qcom,qcs9100-lpass-lpi-pinctrl";
+		reg = <0x0 0x03440000 0x0 0x20000>,
+		      <0x0 0x034D0000 0x0 0x10000>;
+
+		clocks = <&q6prmcc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+			 <&q6prmcc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+		clock-names = "core", "audio";
+
+		gpio-controller;
+		#gpio-cells = <2>;
+		gpio-ranges = <&lpass_tlmm 0 0 23>;
+	};
+
+	csr: csr@4001000 {
+		compatible = "qcom,coresight-csr";
+		reg = <0x0 0x4001000 0x0 0x1000>;
+		reg-names = "csr-base";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		qcom,hwctrl-set-support;
+		qcom,set-byte-cntr-support;
+		qcom,blk-size = <1>;
+	};
+
+	msm_gpu: qcom,kgsl-3d0@3d00000 {
+		#cooling-cells = <2>;
+	};
+
+	tmc_etr: tmc@4048000 {
+		interrupts = <GIC_SPI 270 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "byte-cntr-irq";
+		qcom,sw-usb;
+		coresight-csr = <&csr>;
+		csr-atid-offset = <0xf8>;
+		csr-irqctrl-offset = <0x6c>;
+		byte-cntr-name = "byte-cntr";
+		byte-cntr-class-name = "coresight-tmc-etr-stream";
+	};
+
+	tmc_etr1: tmc@404f000 {
+		interrupts = <GIC_SPI 262 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "byte-cntr-irq";
+		coresight-csr = <&csr>;
+		csr-atid-offset = <0x108>;
+		csr-irqctrl-offset = <0x70>;
+		byte-cntr-name = "byte-cntr1";
+		byte-cntr-class-name = "coresight-tmc-etr1-stream";
+	};
+
+	dma@40ff000 {
+		compatible = "qcom,dcc-v3", "qcom,dcc";
+		reg = <0x0 0x040ff000 0x0 0x1000>,
+		      <0x0 0x040b8800 0x0 0x6000>;
+
+		qcom,dcc-offset = <0x38800>;
+	};
+
+	tgu@4b0e000 {
+		compatible = "arm,primecell", "qcom,coresight-tgu";
+		reg = <0x0 0x4b0e000 0x0 0x1000>;
+		reg-names = "tgu-base";
+		device-name = "tgu_ipcb";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		arm,primecell-periphid = <0x0003b999>;
+		tgu-conditions = <4>;
+		tgu-regs = <4>;
+		tgu-steps = <3>;
+		tgu-timer-counters = <8>;
+	};
+
+	tgu@4b0f000 {
+		compatible = "arm,primecell", "qcom,coresight-tgu";
+		reg = <0x0 0x4b0f000 0x0 0x1000>;
+		reg-names = "tgu-base";
+		device-name = "tgu_spmi0";
+
+		clocks = <&aoss_qmp>;
+		clock-names = "apb_pclk";
+
+		arm,primecell-periphid = <0x0003b999>;
+		tgu-conditions = <4>;
+		tgu-regs = <8>;
+		tgu-steps = <3>;
+		tgu-timer-counters = <8>;
+	};
+};
+
+&sram {
+	mem_dump_table@10 {
+		compatible = "qcom,msm-imem-mem-dump-table";
+		reg = <0x10 0x8>;
+	};
+
+	kaslr_offset@6d0 {
+		compatible = "qcom,msm-imem-kaslr_offset";
+		reg = <0x6d0 0xc>;
+	};
+};
+
+&thermal_zones {
+	gpuss-0-thermal {
+		trips {
+			gpuss_0_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&gpuss_0_passive>;
+				cooling-device = <&msm_gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	gpuss-1-thermal {
+		trips {
+			gpuss_1_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&gpuss_1_passive>;
+				cooling-device = <&msm_gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	gpuss-2-thermal {
+		trips {
+			gpuss_2_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&gpuss_2_passive>;
+				cooling-device = <&msm_gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	gpuss-3-thermal {
+		trips {
+			gpuss_3_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&gpuss_3_passive>;
+				cooling-device = <&msm_gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	gpuss-4-thermal {
+		trips {
+			gpuss_4_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&gpuss_4_passive>;
+				cooling-device = <&msm_gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	gpuss-5-thermal {
+		trips {
+			gpuss_5_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&gpuss_5_passive>;
+				cooling-device = <&msm_gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	nsp-0-0-0-thermal {
+		trips {
+			nsp_0_0_0_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&nsp_0_0_0_passive>;
+				cooling-device = <&cdsp_sw0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	nsp-0-1-0-thermal {
+		trips {
+			nsp_0_1_0_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&nsp_0_1_0_passive>;
+				cooling-device = <&cdsp_sw0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	nsp-0-2-0-thermal {
+		trips {
+			nsp_0_2_0_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&nsp_0_2_0_passive>;
+				cooling-device = <&cdsp_sw0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	nsp-1-0-0-thermal {
+		trips {
+			nsp_1_0_0_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&nsp_1_0_0_passive>;
+				cooling-device = <&cdsp_sw1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	nsp-1-1-0-thermal {
+		trips {
+			nsp_1_1_0_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&nsp_1_1_0_passive>;
+				cooling-device = <&cdsp_sw1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	nsp-1-2-0-thermal {
+		trips {
+			nsp_1_2_0_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&nsp_1_2_0_passive>;
+				cooling-device = <&cdsp_sw1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	nsp-0-0-1-thermal {
+		trips {
+			nsp_0_0_1_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&nsp_0_0_1_passive>;
+				cooling-device = <&cdsp_sw0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	nsp-0-1-1-thermal {
+		trips {
+			nsp_0_1_1_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&nsp_0_1_1_passive>;
+				cooling-device = <&cdsp_sw0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	nsp-0-2-1-thermal {
+		trips {
+			nsp_0_2_1_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&nsp_0_2_1_passive>;
+				cooling-device = <&cdsp_sw0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	nsp-1-0-1-thermal {
+		trips {
+			nsp_1_0_1_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&nsp_1_0_1_passive>;
+				cooling-device = <&cdsp_sw1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	nsp-1-1-1-thermal {
+		trips {
+			nsp_1_1_1_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&nsp_1_1_1_passive>;
+				cooling-device = <&cdsp_sw1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+
+	nsp-1-2-1-thermal {
+		trips {
+			nsp_1_2_1_passive: trip-point1 {
+				temperature = <105000>;
+				hysteresis = <5000>;
+				type = "passive";
+			};
+		};
+
+		cooling-maps {
+			map0 {
+				trip = <&nsp_1_2_1_passive>;
+				cooling-device = <&cdsp_sw1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p-camera.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8775p-camera.dtsi
@@ -0,0 +1,2827 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <dt-bindings/msm-camera.h>
+
+&tlmm {
+	cci_i2c_sda0_active: cci_i2c_sda0_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio60";
+			function = "cci_i2c_sda0";
+		};
+
+		config {
+			pins = "gpio60";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda0_suspend: cci_i2c_sda0_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio60";
+			function = "cci_i2c_sda0";
+		};
+
+		config {
+			pins = "gpio60";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl0_active: cci_i2c_scl0_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio61";
+			function = "cci_i2c_scl0";
+		};
+
+		config {
+			pins = "gpio61";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl0_suspend: cci_i2c_scl0_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio61";
+			function = "cci_i2c_scl0";
+		};
+
+		config {
+			pins = "gpio61";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda1_active: cci_i2c_sda1_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio52";
+			function = "cci_i2c_sda1";
+		};
+
+		config {
+			pins = "gpio52";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda1_suspend: cci_i2c_sda1_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio52";
+			function = "cci_i2c_sda1";
+		};
+
+		config {
+			pins = "gpio52";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl1_active: cci_i2c_scl1_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio53";
+			function = "cci_i2c_scl1";
+		};
+
+		config {
+			pins = "gpio53";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl1_suspend: cci_i2c_scl1_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio53";
+			function = "cci_i2c_scl1";
+		};
+
+		config {
+			pins = "gpio53";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda2_active: cci_i2c_sda2_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio62";
+			function = "cci_i2c_sda2";
+		};
+
+		config {
+			pins = "gpio62";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda2_suspend: cci_i2c_sda2_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio62";
+			function = "cci_i2c_sda2";
+		};
+
+		config {
+			pins = "gpio62";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl2_active: cci_i2c_scl2_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio63";
+			function = "cci_i2c_scl2";
+		};
+
+		config {
+			pins = "gpio63";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl2_suspend: cci_i2c_scl2_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio63";
+			function = "cci_i2c_scl2";
+		};
+
+		config {
+			pins = "gpio63";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda3_active: cci_i2c_sda3_active {
+		mux {
+			pins = "gpio54";
+			function = "cci_i2c_sda3";
+		};
+
+		config {
+			pins = "gpio54";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda3_suspend: cci_i2c_sda3_suspend {
+		mux {
+			pins = "gpio54";
+			function = "cci_i2c_sda3";
+		};
+
+		config {
+			pins = "gpio54";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl3_active: cci_i2c_scl3_active {
+		mux {
+			pins = "gpio55";
+			function = "cci_i2c_scl3";
+		};
+
+		config {
+			pins = "gpio55";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl3_suspend: cci_i2c_scl3_suspend {
+		mux {
+			pins = "gpio55";
+			function = "cci_i2c_scl3";
+		};
+
+		config {
+			pins = "gpio55";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda4_active: cci_i2c_sda4_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio64";
+			function = "cci_i2c_sda4";
+		};
+
+		config {
+			pins = "gpio64";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda4_suspend: cci_i2c_sda4_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio64";
+			function = "cci_i2c_sda4";
+		};
+
+		config {
+			pins = "gpio64";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl4_active: cci_i2c_scl4_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio65";
+			function = "cci_i2c_scl4";
+		};
+
+		config {
+			pins = "gpio65";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl4_suspend: cci_i2c_scl4_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio65";
+			function = "cci_i2c_scl4";
+		};
+
+		config {
+			pins = "gpio65";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda5_active: cci_i2c_sda5_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio56";
+			function = "cci_i2c_sda5";
+		};
+
+		config {
+			pins = "gpio56";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda5_suspend: cci_i2c_sda5_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio56";
+			function = "cci_i2c_sda5";
+		};
+
+		config {
+			pins = "gpio56";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl5_active: cci_i2c_scl5_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio57";
+			function = "cci_i2c_scl5";
+		};
+
+		config {
+			pins = "gpio57";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl5_suspend: cci_i2c_scl5_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio57";
+			function = "cci_i2c_scl5";
+		};
+
+		config {
+			pins = "gpio57";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda6_active: cci_i2c_sda6_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio66";
+			function = "cci_i2c_sda6";
+		};
+
+		config {
+			pins = "gpio66";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda6_suspend: cci_i2c_sda6_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio66";
+			function = "cci_i2c_sda6";
+		};
+
+		config {
+			pins = "gpio66";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl6_active: cci_i2c_scl6_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio67";
+			function = "cci_i2c_scl6";
+		};
+
+		config {
+			pins = "gpio67";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl6_suspend: cci_i2c_scl6_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio67";
+			function = "cci_i2c_scl6";
+		};
+
+		config {
+			pins = "gpio67";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_sda7_active: cci_i2c_sda7_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio58";
+			function = "cci_i2c_sda7";
+		};
+
+		config {
+			pins = "gpio58";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_sda7_suspend: cci_i2c_sda7_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio58";
+			function = "cci_i2c_sda7";
+		};
+
+		config {
+			pins = "gpio58";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cci_i2c_scl7_active: cci_i2c_scl7_active {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio59";
+			function = "cci_i2c_scl7";
+		};
+
+		config {
+			pins = "gpio59";
+			bias-pull-up; /* PULL UP*/
+			drive-strength = <2>; /* 2 MA */
+			qcom,i2c_pull;
+		};
+	};
+
+	cci_i2c_scl7_suspend: cci_i2c_scl7_suspend {
+		mux {
+			/* CLK, DATA */
+			pins = "gpio59";
+			function = "cci_i2c_scl7";
+		};
+
+		config {
+			pins = "gpio59";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk0_active: cam_sensor_mclk0_active {
+		/* MCLK0 */
+		mux {
+			pins = "gpio72";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio72";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk0_suspend: cam_sensor_mclk0_suspend {
+		/* MCLK0 */
+		mux {
+			pins = "gpio72";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio72";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk1_active: cam_sensor_mclk1_active {
+		/* MCLK1 */
+		mux {
+			pins = "gpio73";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio73";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk1_suspend: cam_sensor_mclk1_suspend {
+		/* MCLK1 */
+		mux {
+			pins = "gpio73";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio73";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk2_active: cam_sensor_mclk2_active {
+		/* MCLK2 */
+		mux {
+			pins = "gpio74";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio74";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk2_suspend: cam_sensor_mclk2_suspend {
+		/* MCLK2 */
+		mux {
+			pins = "gpio74";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio74";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk3_active: cam_sensor_mclk3_active {
+		/* MCLK3 */
+		mux {
+			pins = "gpio75";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio75";
+			bias-disable; /* No PULL */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+
+	cam_sensor_mclk3_suspend: cam_sensor_mclk3_suspend {
+		/* MCLK3 */
+		mux {
+			pins = "gpio75";
+			function = "cam_mclk";
+		};
+
+		config {
+			pins = "gpio75";
+			bias-pull-down; /* PULL DOWN */
+			drive-strength = <2>; /* 2 MA */
+		};
+	};
+};
+
+&soc {
+	qcom,cam-req-mgr {
+		compatible = "qcom,cam-req-mgr";
+		status = "ok";
+	};
+
+	qcom,cam-sync {
+		compatible = "qcom,cam-sync";
+		status = "ok";
+	};
+
+	qcom,cam-i3c-id-table {
+		i3c-sensor-id-table = <0x1B0 0x0766>;
+		i3c-eeprom-id-table = <>;
+		i3c-actuator-id-table = <>;
+		i3c-ois-id-table = <>;
+		status = "disabled";
+	};
+
+	cam_csiphy_tpg17: qcom,tpg17@acac000 {
+		cell-index = <17>;
+		phy-id = <0>;
+		compatible = "qcom,cam-tpg1031";
+		reg-names = "tpg0", "cam_cpas_top";
+		reg = <0x0 0xacac000 0x0 0x400>,
+			<0x0 0xac11000 0x0 0x1000>;
+		reg-cam-base = <0xac000 0x11000>;
+		operating-points-v2 = <&csiphy_tpg0_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		interrupt-names = "tpg0";
+		interrupts = <GIC_SPI 545 IRQ_TYPE_EDGE_RISING>;
+		shared-clks = <1 0>;
+		clock-names =
+			"cphy_rx_clk_src",
+			"csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cphy_rx_clk_src";
+		status = "ok";
+		csiphy_tpg0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy_tpg18: qcom,tpg18@acad000 {
+		cell-index = <18>;
+		phy-id = <1>;
+		compatible = "qcom,cam-tpg1031";
+		reg-names = "tpg1", "cam_cpas_top";
+		reg = <0x0 0xacad000 0x0 0x400>,
+			<0x0 0xac11000 0x0 0x1000>;
+		reg-cam-base = <0xad000 0x11000>;
+		operating-points-v2 = <&csiphy_tpg1_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		interrupt-names = "tpg1";
+		interrupts = <GIC_SPI 546 IRQ_TYPE_EDGE_RISING>;
+		shared-clks = <1 0>;
+		clock-names =
+			"cphy_rx_clk_src",
+			"csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cphy_rx_clk_src";
+		status = "ok";
+		csiphy_tpg1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy_tpg19: qcom,tpg19@acae000 {
+		cell-index = <19>;
+		phy-id = <2>;
+		compatible = "qcom,cam-tpg1031";
+		reg-names = "tpg2", "cam_cpas_top";
+		reg = <0x0 0xacae000 0x0 0x400>,
+			<0x0 0xac11000 0x0 0x1000>;
+		reg-cam-base = <0xae000 0x11000>;
+		operating-points-v2 = <&csiphy_tpg2_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		interrupt-names = "tpg2";
+		interrupts = <GIC_SPI 547 IRQ_TYPE_EDGE_RISING>;
+		shared-clks = <1 0>;
+		clock-names =
+			"cphy_rx_clk_src",
+			"csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cphy_rx_clk_src";
+		status = "ok";
+		csiphy_tpg2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy0: qcom,csiphy0@ac9c000 {
+		cell-index = <0>;
+		aggregator-rx;
+		compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy";
+		reg = <0x0 0x0ac9c000 0x0 0x2000>;
+		reg-names = "csiphy";
+		operating-points-v2 = <&csiphy0_opp_table>;
+		reg-cam-base = <0x9c000>;
+		interrupt-names = "CSIPHY0";
+		interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>;
+		csi-vdd-1p2-supply = <&vreg_l1c>;
+		csi-vdd-0p9-supply = <&vreg_l4a>;
+		regulator-names = "csi-vdd-1p2", "csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1140000 831000>;
+		rgltr-max-voltage = <1260000 920000>;
+		rgltr-load-current = <8900 15900>;
+		shared-clks = <1 0 0 0>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy0_clk",
+			"csi0phytimer_clk_src",
+			"csi0phytimer_clk";
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY0_CLK>,
+			<&camcc CAM_CC_CSI0PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI0PHYTIMER_CLK>;
+		src-clock-name = "cphy_rx_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates =
+			<400000000 0 400000000 0>;
+		status = "ok";
+		csiphy0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy1: qcom,csiphy1@ac9e000 {
+		cell-index = <1>;
+		aggregator-rx;
+		compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy";
+		reg = <0x0 0xac9e000 0x0 0x2000>;
+		reg-names = "csiphy";
+		operating-points-v2 = <&csiphy1_opp_table>;
+		reg-cam-base = <0x9e000>;
+		interrupt-names = "CSIPHY1";
+		interrupts = <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>;
+		csi-vdd-1p2-supply = <&vreg_l1c>;
+		csi-vdd-0p9-supply = <&vreg_l4a>;
+		regulator-names = "csi-vdd-1p2", "csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1140000 831000>;
+		rgltr-max-voltage = <1260000 920000>;
+		rgltr-load-current = <8900 15900>;
+		shared-clks = <1 0 0 0>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy1_clk",
+			"csi1phytimer_clk_src",
+			"csi1phytimer_clk";
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY1_CLK>,
+			<&camcc CAM_CC_CSI1PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI1PHYTIMER_CLK>;
+		src-clock-name = "cphy_rx_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates =
+			<400000000 0 400000000 0>;
+		status = "ok";
+		csiphy1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy2: qcom,csiphy2@aca0000 {
+		cell-index = <2>;
+		aggregator-rx;
+		compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy";
+		reg = <0x0 0xaca0000 0x0 0x2000>;
+		reg-names = "csiphy";
+		operating-points-v2 = <&csiphy2_opp_table>;
+		reg-cam-base = <0xa0000>;
+		interrupt-names = "CSIPHY2";
+		interrupts = <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>;
+		csi-vdd-1p2-supply = <&vreg_l1c>;
+		csi-vdd-0p9-supply = <&vreg_l4a>;
+		regulator-names = "csi-vdd-1p2", "csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1140000 831000>;
+		rgltr-max-voltage = <1260000 920000>;
+		rgltr-load-current = <8900 15900>;
+		shared-clks = <1 0 0 0>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy2_clk",
+			"csi2phytimer_clk_src",
+			"csi2phytimer_clk";
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY2_CLK>,
+			<&camcc CAM_CC_CSI2PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI2PHYTIMER_CLK>;
+		src-clock-name = "cphy_rx_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates =
+			<400000000 0 400000000 0>;
+		status = "ok";
+		csiphy2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_csiphy3: qcom,csiphy3@aca2000 {
+		cell-index = <3>;
+		aggregator-rx;
+		compatible = "qcom,csiphy-v1.3.0", "qcom,csiphy";
+		reg = <0x0 0xaca2000 0x0 0x2000>;
+		reg-names = "csiphy";
+		operating-points-v2 = <&csiphy3_opp_table>;
+		reg-cam-base = <0xa2000>;
+		interrupt-names = "CSIPHY3";
+		interrupts = <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>;
+		csi-vdd-1p2-supply = <&vreg_l1c>;
+		csi-vdd-0p9-supply = <&vreg_l4a>;
+		regulator-names = "csi-vdd-1p2", "csi-vdd-0p9";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		rgltr-cntrl-support;
+		rgltr-min-voltage = <1140000 831000>;
+		rgltr-max-voltage = <1260000 920000>;
+		rgltr-load-current = <8900 15900>;
+		shared-clks = <1 0 0 0>;
+		clock-names = "cphy_rx_clk_src",
+			"csiphy3_clk",
+			"csi3phytimer_clk_src",
+			"csi3phytimer_clk";
+		clocks = <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+			<&camcc CAM_CC_CSIPHY3_CLK>,
+			<&camcc CAM_CC_CSI3PHYTIMER_CLK_SRC>,
+			<&camcc CAM_CC_CSI3PHYTIMER_CLK>;
+		src-clock-name = "cphy_rx_clk_src";
+		clock-cntl-level = "lowsvs";
+		clock-rates =
+			<400000000 0 400000000 0>;
+		status = "ok";
+		csiphy3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	cam_cci0: qcom,cci0@ac13000 {
+		cell-index = <0>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac13000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x13000>;
+		interrupt-names = "CCI0";
+		interrupts = <GIC_SPI 460 IRQ_TYPE_EDGE_RISING>;
+		operating-points-v2 = <&cci0_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cci_0_clk_src",
+			"cci_0_clk";
+		clocks = <&camcc CAM_CC_CCI_0_CLK_SRC>,
+			<&camcc CAM_CC_CCI_0_CLK>;
+		clock-rates = <37500000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cci_0_clk_src";
+		pctrl-idx-mapping = <CCI_MASTER_0 CCI_MASTER_1>;
+		pctrl-map-names = "m0", "m1";
+		pinctrl-names = "m0_active", "m0_suspend",
+			"m1_active", "m1_suspend";
+		pinctrl-0 = <&cci_i2c_scl0_active &cci_i2c_sda0_active>;
+		pinctrl-1 = <&cci_i2c_scl0_suspend &cci_i2c_sda0_suspend>;
+		pinctrl-2 = <&cci_i2c_scl1_active &cci_i2c_sda1_active>;
+		pinctrl-3 = <&cci_i2c_scl1_suspend &cci_i2c_sda1_suspend>;
+		status = "ok";
+		cci0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci0: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci0: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci0: qcom,i2c_custom_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci0: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	cam_cci1: qcom,cci1@ac14000 {
+		cell-index = <1>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac14000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x14000>;
+		interrupt-names = "CCI1";
+		interrupts = <GIC_SPI 271 IRQ_TYPE_EDGE_RISING>;
+		operating-points-v2 = <&cci1_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cci_1_clk_src",
+			"cci_1_clk";
+		clocks = <&camcc CAM_CC_CCI_1_CLK_SRC>,
+			<&camcc CAM_CC_CCI_1_CLK>;
+		clock-rates = <37500000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cci_1_clk_src";
+		pctrl-idx-mapping = <CCI_MASTER_0 CCI_MASTER_1>;
+		pctrl-map-names = "m0", "m1";
+		pinctrl-names = "m0_active", "m0_suspend",
+			"m1_active", "m1_suspend";
+		pinctrl-0 = <&cci_i2c_scl2_active &cci_i2c_sda2_active>;
+		pinctrl-1 = <&cci_i2c_scl2_suspend &cci_i2c_sda2_suspend>;
+		pinctrl-2 = <&cci_i2c_scl3_active &cci_i2c_sda3_active>;
+		pinctrl-3 = <&cci_i2c_scl3_suspend &cci_i2c_sda3_suspend>;
+		status = "ok";
+		cci1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci1: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci1: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci1: qcom,i2c_custom_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci1: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	cam_cci2: qcom,cci2@ac15000 {
+		cell-index = <2>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac15000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x15000>;
+		interrupt-names = "CCI2";
+		interrupts = <GIC_SPI 651 IRQ_TYPE_EDGE_RISING>;
+		operating-points-v2 = <&cci2_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cci_2_clk_src",
+			"cci_2_clk";
+		clocks = <&camcc CAM_CC_CCI_2_CLK_SRC>,
+			<&camcc CAM_CC_CCI_2_CLK>;
+		clock-rates = <37500000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cci_2_clk_src";
+		pctrl-idx-mapping = <CCI_MASTER_0 CCI_MASTER_1>;
+		pctrl-map-names = "m0", "m1";
+		pinctrl-names = "m0_active", "m0_suspend",
+			"m1_active", "m1_suspend";
+		pinctrl-0 = <&cci_i2c_scl4_active &cci_i2c_sda4_active>;
+		pinctrl-1 = <&cci_i2c_scl4_suspend &cci_i2c_sda4_suspend>;
+		pinctrl-2 = <&cci_i2c_scl5_active &cci_i2c_sda5_active>;
+		pinctrl-3 = <&cci_i2c_scl5_suspend &cci_i2c_sda5_suspend>;
+		status = "ok";
+		cci2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci2: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci2: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci2: qcom,i2c_custom_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci2: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	cam_cci3: qcom,cci3@ac16000 {
+		cell-index = <3>;
+		compatible = "qcom,cci", "simple-bus";
+		reg = <0x0 0xac16000 0x0 0x1000>;
+		reg-names = "cci";
+		reg-cam-base = <0x16000>;
+		interrupt-names = "CCI3";
+		interrupts = <GIC_SPI 771 IRQ_TYPE_EDGE_RISING>;
+		operating-points-v2 = <&cci3_opp_table>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cci_3_clk_src",
+			"cci_3_clk";
+		clocks = <&camcc CAM_CC_CCI_3_CLK_SRC>,
+			<&camcc CAM_CC_CCI_3_CLK>;
+		clock-rates = <37500000 0>;
+		clock-cntl-level = "lowsvs";
+		src-clock-name = "cci_3_clk_src";
+		pctrl-idx-mapping = <CCI_MASTER_0 CCI_MASTER_1>;
+		pctrl-map-names = "m0", "m1";
+		pinctrl-names = "m0_active", "m0_suspend",
+			"m1_active", "m1_suspend";
+		pinctrl-0 = <&cci_i2c_scl6_active &cci_i2c_sda6_active>;
+		pinctrl-1 = <&cci_i2c_scl6_suspend &cci_i2c_sda6_suspend>;
+		pinctrl-2 = <&cci_i2c_scl7_active &cci_i2c_sda7_active>;
+		pinctrl-3 = <&cci_i2c_scl7_suspend &cci_i2c_sda7_suspend>;
+		status = "ok";
+		cci3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+			opp-37500000 {
+				opp-hz = /bits/ 64 <37500000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+
+		i2c_freq_100Khz_cci3: qcom,i2c_standard_mode {
+			hw-thigh = <201>;
+			hw-tlow = <174>;
+			hw-tsu-sto = <204>;
+			hw-tsu-sta = <231>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <162>;
+			hw-tbuf = <227>;
+			hw-scl-stretch-en = <0>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_400Khz_cci3: qcom,i2c_fast_mode {
+			hw-thigh = <38>;
+			hw-tlow = <56>;
+			hw-tsu-sto = <40>;
+			hw-tsu-sta = <40>;
+			hw-thd-dat = <22>;
+			hw-thd-sta = <35>;
+			hw-tbuf = <62>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <6>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_custom_cci3: qcom,i2c_custom_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+
+		i2c_freq_1Mhz_cci3: qcom,i2c_fast_plus_mode {
+			hw-thigh = <16>;
+			hw-tlow = <22>;
+			hw-tsu-sto = <17>;
+			hw-tsu-sta = <18>;
+			hw-thd-dat = <16>;
+			hw-thd-sta = <15>;
+			hw-tbuf = <24>;
+			hw-scl-stretch-en = <1>;
+			hw-trdhld = <3>;
+			hw-tsp = <3>;
+			cci-clk-src = <37500000>;
+			status = "ok";
+		};
+	};
+
+	qcom,cam_smmu {
+		compatible = "qcom,msm-cam-smmu", "simple-bus";
+		status = "ok";
+		force_cache_allocs;
+
+		msm_cam_smmu_ife {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x3400 0x0020>,
+				<&apps_smmu 0x3420 0x0020>;
+			cam-smmu-label = "ife", "sfe";
+			multiple-client-devices;
+			dma-coherent;
+			ife_iova_mem_map: iova-mem-map {
+				/* IO region is approximately 64 GB */
+				iova-mem-region-io {
+					iova-region-name = "io";
+					/* start address: 0x100000 */
+					/* leaving 1 MB pad at start  */
+					iova-region-start = <0x100000>;
+					/* Length: 0xfffe00000 */
+					/* leaving 1 MB pad at end */
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_icp {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus =
+				<&apps_smmu 0x0800 0x400>,
+				<&apps_smmu 0x0840 0x480>,
+				<&apps_smmu 0x08C0 0x480>,
+				<&apps_smmu 0x0C00 0x400>,
+				<&apps_smmu 0x0C40 0x480>,
+				<&apps_smmu 0x0CC0 0x480>;
+			cam-smmu-label = "icp";
+			qcom,iommu-faults = "stall-disable", "non-fatal";
+			dma-coherent;
+			icp_iova_mem_map: iova-mem-map {
+				iova-mem-region-shared {
+					/* Shared region is ~250MB long */
+					iova-region-name = "shared";
+					iova-region-start = <0x800000>;
+					iova-region-len = <0xfc00000>;
+					iova-region-id = <0x1>;
+					status = "ok";
+				};
+
+				iova-mem-region-fwuncached-region {
+					/* FW uncached region is 7MB long */
+					iova-region-name = "fw_uncached";
+					iova-region-start = <0x10400000>;
+					iova-region-len = <0x700000>;
+					iova-region-id = <0x6>;
+					subregion_support;
+					status = "ok";
+					/* Used for HFI queues/sec heap */
+					iova-mem-region-generic-region {
+						iova-region-name = "icp_hfi";
+						iova-region-start = <0x10400000>;
+						iova-region-len = <0x200000>;
+						iova-region-id = <0x0>;
+					};
+				};
+
+				iova-mem-region-io {
+					/* IO region is approximately 3.8 GB */
+					iova-region-name = "io";
+					iova-region-start = <0x10c00000>;
+					iova-region-len = <0xee300000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+
+				iova-mem-qdss-region {
+					/* QDSS region is appropriate 1MB */
+					iova-region-name = "qdss";
+					iova-region-start = <0x10b00000>;
+					iova-region-len = <0x100000>;
+					iova-region-id = <0x5>;
+					qdss-phy-addr = <0x16790000>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_cdm {
+			compatible = "qcom,msm-cam-smmu-cb";
+			iommus = <&apps_smmu 0x0860 0x400>,
+				<&apps_smmu 0x0C60 0x400>;
+			cam-smmu-label = "rt-cdm";
+			dma-coherent;
+			multiple-client-devices;
+			rt_cdm_iova_mem_map: iova-mem-map {
+				iova-mem-region-io {
+					/* IO region is approximately 4.0 GB */
+					iova-region-name = "io";
+					/* 1 MB pad for start */
+					iova-region-start = <0x100000>;
+					/* 1 MB pad for end */
+					iova-region-len = <0xffe00000>;
+					iova-region-id = <0x3>;
+					status = "ok";
+				};
+			};
+		};
+
+		msm_cam_smmu_secure {
+			compatible = "qcom,msm-cam-smmu-cb";
+			cam-smmu-label = "cam-secure";
+			qcom,secure-cb;
+		};
+	};
+
+	qcom,cam-cdm-intf {
+		compatible = "qcom,cam-cdm-intf";
+		cell-index = <0>;
+		label = "cam-cdm-intf";
+		num-hw-cdm = <1>;
+		cdm-client-names = "vfe";
+		status = "ok";
+	};
+
+	qcom,rt-cdm0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac26000 0x0 0x1000>;
+		reg-names = "rt-cdm0";
+		reg-cam-base = <0x26000>;
+		interrupts = <GIC_SPI 543 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm0";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_fast_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_fast_ahb_clk_src";
+		clock-rates = <300000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table0>;
+		clock-cntl-level = "svs";
+		cdm-client-names = "ife0", "dualife0";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table0: opp-table {
+			compatible = "operating-points-v2";
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,rt-cdm1 {
+		cell-index = <1>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac27000 0x0 0x1000>;
+		reg-names = "rt-cdm1";
+		reg-cam-base = <0x27000>;
+		interrupts = <GIC_SPI 544 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm1";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_fast_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_fast_ahb_clk_src";
+		clock-rates = <300000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table1>;
+		clock-cntl-level = "svs_l1";
+		cdm-client-names = "ife1", "dualife1";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table1: opp-table {
+			compatible = "operating-points-v2";
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,rt-cdm2 {
+		cell-index = <2>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac28000 0x0 0x1000>;
+		reg-names = "rt-cdm2";
+		reg-cam-base = <0x28000>;
+		interrupts = <GIC_SPI 567 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm2";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_slow_ahb_clk_src";
+		clock-rates = <80000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table2>;
+		clock-cntl-level = "svs_l1";
+		cdm-client-names = "ife2", "ife3", "ife4", "ife5", "ife6";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table2: opp-table {
+			compatible = "operating-points-v2";
+			opp-80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,rt-cdm3 {
+		cell-index = <3>;
+		compatible = "qcom,cam-rt-cdm2_1";
+		label = "rt-cdm";
+		reg = <0x0 0xac29000 0x0 0x1000>;
+		reg-names = "rt-cdm3";
+		reg-cam-base = <0x29000>;
+		interrupts = <GIC_SPI 566 IRQ_TYPE_EDGE_RISING>;
+		interrupt-names = "rt-cdm3";
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names = "cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk";
+		clocks = <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>;
+		src-clock-name = "cam_cc_slow_ahb_clk_src";
+		clock-rates = <80000000 0>;
+		operating-points-v2 = <&cdm_cpas_opp_table3>;
+		clock-cntl-level = "svs";
+		cdm-client-names = "ife2", "ife3", "ife4", "ife5", "ife6";
+		single-context-cdm;
+		status = "ok";
+		cdm_cpas_opp_table3: opp-table {
+			compatible = "operating-points-v2";
+			opp-80000000 {
+				opp-hz = /bits/ 64 <80000000>;
+				required-opps = <&rpmhpd_opp_low_svs>;
+			};
+		};
+	};
+
+	qcom,cam-isp {
+		compatible = "qcom,cam-isp";
+		arch-compat = "ife";
+		status = "ok";
+	};
+
+	cam_csid0: qcom,csid0 {
+		cell-index = <0>;
+		compatible = "qcom,csid690";
+		reg-names = "csid0", "csid_top";
+		reg = <0x0 0xac7a000 0x0 0xf01>,
+			<0x0 0xac78000 0x0 0x1000>;
+		reg-cam-base = <0x7a000 0x78000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "csid0";
+		interrupts = <GIC_SPI 565 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_csid_clk_src",
+			"cam_cc_csid_clk",
+			"cam_cc_csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CSID_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CLK>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0 0>;
+		clock-cntl-level = "svs_l1";
+		src-clock-name = "cam_cc_csid_clk_src";
+		operating-points-v2 = <&csid0_opp_table>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+		};
+	};
+
+	cam_vfe0: qcom,ife0 {
+		cell-index = <0>;
+		compatible = "qcom,vfe690";
+		reg-names = "ife0", "cam_camnoc";
+		reg = <0x0 0xac4d000 0x0 0xd000>,
+			<0x0 0xac1a000 0x0 0x9400>;
+		reg-cam-base = <0x4d000 0x1a000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "ife0";
+		interrupts = <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_0_clk",
+			"cam_cc_ife_0_clk",
+			"cam_cc_ife_0_clk_src",
+			"cam_cc_ife_0_fast_ahb_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_0_CLK>,
+			<&camcc CAM_CC_IFE_0_CLK>,
+			<&camcc CAM_CC_IFE_0_CLK_SRC>,
+			<&camcc CAM_CC_IFE_0_FAST_AHB_CLK>;
+		clock-rates =
+			<0 0 480000000 0>,
+			<0 0 600000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_0_clk_src";
+		operating-points-v2 = <&vfe0_opp_table>;
+		clock-control-debugfs = "true";
+		ubwc-static-cfg = <0x1026 0x1036>;
+		cam_hw_pid = <8 16>;
+		status = "ok";
+		vfe0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid1: qcom,csid1 {
+		cell-index = <1>;
+		compatible = "qcom,csid690";
+		reg-names = "csid1", "csid_top";
+		reg = <0x0 0xac7c000 0x0 0xf01>,
+			<0x0 0xac78000 0x0 0x1000>;
+		reg-cam-base = <0x7c000 0x78000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "csid0";
+		interrupts = <GIC_SPI 564 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_csid_clk_src",
+			"cam_cc_csid_clk",
+			"cam_cc_csid_csiphy_rx_clk";
+		clocks =
+			<&camcc CAM_CC_CSID_CLK_SRC>,
+			<&camcc CAM_CC_CSID_CLK>,
+			<&camcc CAM_CC_CSID_CSIPHY_RX_CLK>;
+		clock-rates =
+			<400000000 0 0>;
+		clock-cntl-level = "svs_l1";
+		src-clock-name = "cam_cc_csid_clk_src";
+		operating-points-v2 = <&csid1_opp_table>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+		};
+	};
+
+	cam_vfe1: qcom,ife1 {
+		cell-index = <1>;
+		compatible = "qcom,vfe690";
+		reg-names = "ife1", "cam_camnoc";
+		reg = <0x0 0xac5a000 0x0 0xd000>,
+			<0x0 0xac1a000 0x0 0x9400>;
+		reg-cam-base = <0x5a000 0x1a000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "ife1";
+		interrupts = <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_1_clk",
+			"cam_cc_ife_1_clk",
+			"cam_cc_ife_1_clk_src",
+			"cam_cc_ife_1_fast_ahb_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_1_CLK>,
+			<&camcc CAM_CC_IFE_1_CLK>,
+			<&camcc CAM_CC_IFE_1_CLK_SRC>,
+			<&camcc CAM_CC_IFE_1_FAST_AHB_CLK>;
+		clock-rates =
+			<0 0 480000000 0>,
+			<0 0 600000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_1_clk_src";
+		operating-points-v2 = <&vfe1_opp_table>;
+		clock-control-debugfs = "true";
+		ubwc-static-cfg = <0x1026 0x1036>;
+		cam_hw_pid = <9 17>;
+		status = "ok";
+		vfe1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite0: qcom,csid-lite0 {
+		cell-index = <2>;
+		compatible = "qcom,csid-lite690";
+		reg-names = "csid-lite0";
+		reg = <0x0 0xac84000 0x0 0xf01>;
+		reg-cam-base = <0x84000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite0";
+		interrupts = <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite0_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite0: qcom,ife-lite0 {
+		cell-index = <2>;
+		compatible = "qcom,vfe-lite690";
+		reg-names = "ife-lite0";
+		reg = <0x0 0xac84000 0x0 0x1d00>;
+		reg-cam-base = <0x84000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite0";
+		interrupts = <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite0_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite1: qcom,csid-lite1 {
+		cell-index = <3>;
+		compatible = "qcom,csid-lite690";
+		reg-names = "csid-lite1";
+		reg = <0x0 0xac88000 0x0 0xf01>;
+		reg-cam-base = <0x88000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite1";
+		interrupts = <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite1_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite1: qcom,ife-lite1 {
+		cell-index = <3>;
+		compatible = "qcom,vfe-lite690";
+		reg-names = "ife-lite1";
+		reg = <0x0 0xac88000 0x0 0x1d00>;
+		reg-cam-base = <0x88000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite1";
+		interrupts = <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite1_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite1_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite2: qcom,csid-lite2 {
+		cell-index = <4>;
+		compatible = "qcom,csid-lite690";
+		reg-names = "csid-lite2";
+		reg = <0x0 0xac8c000 0x0 0xf01>;
+		reg-cam-base = <0x8c000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite2";
+		interrupts = <GIC_SPI 759 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite2_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite2: qcom,ife-lite2 {
+		cell-index = <4>;
+		compatible = "qcom,vfe-lite690";
+		reg-names = "ife-lite2";
+		reg = <0x0 0xac8c000 0x0 0x1d00>;
+		reg-cam-base = <0x8c000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite2";
+		interrupts = <GIC_SPI 761 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite2_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite2_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite3: qcom,csid-lite3 {
+		cell-index = <5>;
+		compatible = "qcom,csid-lite690";
+		reg-names = "csid-lite3";
+		reg = <0x0 0xac90000 0x0 0xf01>;
+		reg-cam-base = <0x90000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite3";
+		interrupts = <GIC_SPI 758 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite3_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite3: qcom,ife-lite3 {
+		cell-index = <5>;
+		compatible = "qcom,vfe-lite690";
+		reg-names = "ife-lite3";
+		reg = <0x0 0xac90000 0x0 0x1d00>;
+		reg-cam-base = <0x90000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite3";
+		interrupts = <GIC_SPI 760 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite3_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite3_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_csid_lite4: qcom,csid-lite4 {
+		cell-index = <6>;
+		compatible = "qcom,csid-lite690";
+		reg-names = "csid-lite4";
+		reg = <0x0 0xac94000 0x0 0xf01>;
+		reg-cam-base = <0x94000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "csid-lite4";
+		interrupts = <GIC_SPI 604 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_csid_clk_src";
+		operating-points-v2 = <&csid_lite4_opp_table>;
+
+		clock-control-debugfs = "true";
+		status = "ok";
+		csid_lite4_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_vfe_lite4: qcom,ife-lite4 {
+		cell-index = <6>;
+		compatible = "qcom,vfe-lite690";
+		reg-names = "ife-lite4";
+		reg = <0x0 0xac94000 0x0 0x1d00>;
+		reg-cam-base = <0x94000>;
+		rt-wrapper-base = <0x83000>;
+		interrupt-names = "ife-lite4";
+		interrupts = <GIC_SPI 605 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_cpas_ife_lite_clk",
+			"cam_cc_ife_lite_ahb_clk",
+			"cam_cc_ife_lite_csid_clk_src",
+			"cam_cc_ife_lite_csid_clk",
+			"cam_cc_ife_lite_cphy_rx_clk",
+			"cam_cc_ife_lite_clk_src",
+			"cam_cc_ife_lite_clk";
+		clocks =
+			<&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+			<&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CSID_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+			<&camcc CAM_CC_IFE_LITE_CLK_SRC>,
+			<&camcc CAM_CC_IFE_LITE_CLK>;
+		clock-rates =
+			<0 0 400000000 0 0 400000000 0>,
+			<0 0 400000000 0 0 480000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_ife_lite_clk_src";
+		operating-points-v2 = <&vfe_lite4_opp_table>;
+		clock-control-debugfs = "true";
+		cam_hw_pid = <27>;
+		status = "ok";
+		vfe_lite4_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_sfe_lite0: qcom,sfe-lite0 {
+		cell-index = <0>;
+		compatible = "qcom,sfe-lite690";
+		reg-names = "sfe-lite0";
+		reg = <0x0 0xac74000 0x0 0x1000>;
+		reg-cam-base = <0x74000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "sfe-lite0";
+		interrupts = <GIC_SPI 563 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_sfe_lite_0_fast_ahb_clk",
+			"cam_cc_sfe_lite_0_clk",
+			"cam_cc_cpas_sfe_lite_0_clk";
+		clocks =
+			<&camcc CAM_CC_SFE_LITE_0_FAST_AHB_CLK>,
+			<&camcc CAM_CC_SFE_LITE_0_CLK>,
+			<&camcc CAM_CC_CPAS_SFE_LITE_0_CLK>;
+		clock-rates =
+			<0 480000000 300000000>,
+			<0 600000000 400000000>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_sfe_lite_0_clk";
+		operating-points-v2 = <&cam_sfe_lite_opp_table0>;
+		cam_hw_pid = <4>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		cam_sfe_lite_opp_table0: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_sfe_lite1: qcom,sfe-lite1 {
+		cell-index = <1>;
+		compatible = "qcom,sfe-lite690";
+		reg-names = "sfe-lite1";
+		reg = <0x0 0xac75000 0x0 0x1000>;
+		reg-cam-base = <0x75000>;
+		rt-wrapper-base = <0x4d000>;
+		interrupt-names = "sfe-lite1";
+		interrupts = <GIC_SPI 562 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"cam_cc_sfe_lite_1_fast_ahb_clk",
+			"cam_cc_sfe_lite_1_clk",
+			"cam_cc_cpas_sfe_1_clk";
+		clocks =
+			<&camcc CAM_CC_SFE_LITE_1_FAST_AHB_CLK>,
+			<&camcc CAM_CC_SFE_LITE_1_CLK>,
+			<&camcc CAM_CC_CPAS_SFE_LITE_1_CLK>;
+		clock-rates =
+			<0 480000000 300000000>,
+			<0 600000000 400000000>;
+		clock-cntl-level = "svs_l1", "nominal";
+		src-clock-name = "cam_cc_sfe_lite_1_clk";
+		operating-points-v2 = <&cam_sfe_lite_opp_table1>;
+		cam_hw_pid = <5>;
+		clock-control-debugfs = "true";
+		status = "ok";
+		cam_sfe_lite_opp_table1: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	qcom,cam-icp {
+		compatible = "qcom,cam-icp";
+		compat-hw-name = "qcom,icp",
+			"qcom,ipe0";
+		num-icp = <1>;
+		num-ipe = <1>;
+		icp_use_pil;
+		status = "ok";
+	};
+
+	cam_icp: qcom,icp {
+		cell-index = <0>;
+		compatible = "qcom,cam-icp_v3_0";
+		icp-version = <0x0300>;
+
+		reg-names ="icp_csr", "icp_cirq", "icp_wd0";
+		reg = <0x0 0xac01000 0x0 0x400>,
+			<0x0 0xac01800 0x0 0x400>,
+			<0x0 0xac04000 0x0 0x1000>;
+		reg-cam-base = <0x1000 0x1800 0x4000>;
+		interrupt-names = "icp";
+		interrupts = <GIC_SPI 463 IRQ_TYPE_EDGE_RISING>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		memory-region = <&pil_camera_mem>;
+		clock-names =
+			"cam_cc_soc_fast_ahb_clk_src",
+			"cam_cc_icp_ahb_clk",
+			"cam_cc_icp_clk_src",
+			"cam_cc_icp_clk";
+		src-clock-name = "cam_cc_icp_clk_src";
+		clocks =
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_ICP_AHB_CLK>,
+			<&camcc CAM_CC_ICP_CLK_SRC>,
+			<&camcc CAM_CC_ICP_CLK>;
+		clock-rates =
+			<300000000 0 480000000 0>,
+			<400000000 0 600000000 0>;
+		clock-cntl-level = "svs_l1", "nominal";
+		nrt-device;
+		fw_name = "CAMERA_ICP";
+		ubwc-ipe-fetch-cfg = <0x707b 0x7083>;
+		ubwc-ipe-write-cfg = <0x161ef 0x1620f>;
+		qos-val = <0xa0a>;
+		operating-points-v2 = <&icp_opp_table>;
+		cam_hw_pid = <12>;
+		status = "ok";
+		icp_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+	};
+
+	cam_ipe0: qcom,ipe0 {
+		cell-index = <0>;
+		compatible = "qcom,cam-ipe";
+		reg-names = "ipe0_top";
+		reg = <0x0 0xac2d000 0x0 0x18000>;
+		reg-cam-base = <0x2d000>;
+
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+
+		clock-names =
+			"cam_cc_cpas_ipe_clk",
+			"cam_cc_ipe_ahb_clk",
+			"cam_cc_ipe_clk",
+			"cam_cc_ipe_clk_src",
+			"cam_cc_ipe_fast_ahb_clk",
+			"cam_cc_fast_ahb_clk_src";
+		src-clock-name = "cam_cc_ipe_clk_src";
+		clocks =
+			<&camcc CAM_CC_CPAS_IPE_CLK>,
+			<&camcc CAM_CC_IPE_AHB_CLK>,
+			<&camcc CAM_CC_IPE_CLK>,
+			<&camcc CAM_CC_IPE_CLK_SRC>,
+			<&camcc CAM_CC_IPE_FAST_AHB_CLK>,
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>;
+		clock-rates =
+			<0 0 0 480000000 0 300000000>,
+			<0 0 0 600000000 0 400000000>;
+		clock-cntl-level = "svs_l1", "nominal";
+
+		operating-points-v2 = <&ipe0_opp_table>;
+		nrt-device;
+		cam_hw_pid = <14 15>;
+		status = "ok";
+
+		ipe0_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-480000000 {
+				opp-hz = /bits/ 64 <480000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-600000000 {
+				opp-hz = /bits/ 64 <600000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+
+	};
+
+	qcom,cam-cpas {
+		cell-index = <0>;
+		compatible = "qcom,cam-cpas";
+		label = "cpas";
+		arch-compat = "cpas_top";
+		reg-names = "cam_cpas_top", "cam_camnoc", "cam_rpmh";
+		reg = <0x0 0xac11000 0x0 0x1000>,
+			<0x0 0xac1A000 0x0 0x9400>,
+			<0x0 0xbbf0000 0x0 0x1f00>;
+		reg-cam-base = <0x11000 0x1A000 0x0bbf0000>;
+		interrupt-names = "cpas_camnoc";
+		interrupts = <GIC_SPI 459 IRQ_TYPE_EDGE_RISING>;
+		camnoc-axi-min-ib-bw = <3000000000>;
+		power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+		clock-names =
+			"gcc_camera_ahb_clk",
+			"gcc_camera_hf_axi_clk",
+			"gcc_camera_sf_axi_clk",
+			"cam_cc_slow_ahb_clk_src",
+			"cam_cc_cpas_ahb_clk",
+			"cam_cc_core_ahb_clk",
+			"cam_cc_fast_ahb_clk_src",
+			"cam_cc_cpas_fast_ahb_clk",
+			"cam_cc_camnoc_axi_clk_src",
+			"cam_cc_camnoc_axi_clk",
+			"cam_cc_qdss_debug_xo_clk";
+		clocks =
+			<&gcc GCC_CAMERA_AHB_CLK>,
+			<&gcc GCC_CAMERA_HF_AXI_CLK>,
+			<&gcc GCC_CAMERA_SF_AXI_CLK>,
+			<&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_AHB_CLK>,
+			<&camcc CAM_CC_CORE_AHB_CLK>,
+			<&camcc CAM_CC_FAST_AHB_CLK_SRC>,
+			<&camcc CAM_CC_CPAS_FAST_AHB_CLK>,
+			<&camcc CAM_CC_CAMNOC_AXI_CLK_SRC>,
+			<&camcc CAM_CC_CAMNOC_AXI_CLK>,
+			<&camcc CAM_CC_QDSS_DEBUG_XO_CLK>;
+		src-clock-name = "cam_cc_fast_ahb_clk_src";
+		clock-rates =
+			<0 0 0 0 0 0 0 0 0 0 0>,
+			<0 0 0 80000000 0 0 300000000 0 400000000 0 0>,
+			<0 0 0 80000000 0 0 400000000 0 400000000 0 0>;
+		clock-cntl-level = "suspend", "svs_l1", "nominal";
+		clock-names-option = "cam_icp_clk";
+		clocks-option = <&camcc CAM_CC_ICP_CLK>;
+		clock-rates-option = <480000000>;
+		operating-points-v2 = <&cpas_opp_table>;
+		control-camnoc-axi-clk;
+		camnoc-bus-width = <32>;
+		camnoc-axi-clk-bw-margin-perc = <20>;
+		cam-icc-path-names = "cam_ahb";
+		interconnect-names = "cam_ahb", "cam_hf_0", "cam_sf_0", "cam_sf_icp";
+		interconnects =<&gem_noc MASTER_APPSS_PROC 0
+			&config_noc SLAVE_CAMERA_CFG 0>,
+				<&mmss_noc MASTER_CAMNOC_HF 0
+			&mc_virt SLAVE_EBI1 0>,
+				<&mmss_noc MASTER_CAMNOC_SF 0
+			&mc_virt SLAVE_EBI1 0>,
+				<&mmss_noc MASTER_CAMNOC_ICP 0
+			&mc_virt SLAVE_EBI1 0>;
+		cam-ahb-num-cases = <7>;
+		cam-ahb-bw-KBps =
+			<0 0>, <0 76800>, <0 150000>, <0 150000>,
+			<0 300000>, <0 300000>, <0 300000>;
+		vdd-corners = <RPMH_REGULATOR_LEVEL_RETENTION
+			RPMH_REGULATOR_LEVEL_MIN_SVS
+			RPMH_REGULATOR_LEVEL_LOW_SVS
+			RPMH_REGULATOR_LEVEL_SVS
+			RPMH_REGULATOR_LEVEL_SVS_L1
+			RPMH_REGULATOR_LEVEL_NOM
+			RPMH_REGULATOR_LEVEL_NOM_L1
+			RPMH_REGULATOR_LEVEL_NOM_L2
+			RPMH_REGULATOR_LEVEL_TURBO
+			RPMH_REGULATOR_LEVEL_TURBO_L1>;
+		vdd-corner-ahb-mapping = "suspend",
+			"lowsvs", "lowsvs", "svs", "svs_l1",
+			"nominal", "nominal", "nominal",
+			"turbo", "turbo";
+		client-id-based;
+		client-names =
+			"csiphy0", "csiphy1", "csiphy2", "csiphy3",
+			"cci0", "cci1", "cci2", "cci3","csid0", "csid1",
+			"csid2", "csid3", "csid4", "csid5", "csid6",
+			"ife0", "ife1",	"ife2", "ife3", "ife4",
+			"ife5",	"ife6", "ipe0", "sfe0", "sfe1",
+			"cam-cdm-intf0", "rt-cdm0", "rt-cdm1", "rt-cdm2",
+			"rt-cdm3", "icp0", "tpg17", "tpg18", "tpg19";
+
+		status = "ok";
+		enable-secure-qos-update;
+		cpas_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-300000000 {
+				opp-hz = /bits/ 64 <300000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>;
+			};
+			opp-400000000 {
+				opp-hz = /bits/ 64 <400000000>;
+				required-opps = <&rpmhpd_opp_nom>;
+			};
+		};
+
+		camera-bus-nodes {
+			level3-nodes {
+				level-index = <3>;
+				level3_rt_rd_wr_sum: level3-rt-rd-wr-sum {
+					cell-index = <0>;
+					node-name = "level3-rt-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					ib-bw-voting-needed;
+					qcom,axi-port-mnoc {
+						cam-icc-path-names = "cam_hf_0";
+					};
+				};
+
+				level3_nrt0_rd_wr_sum: level3-nrt0-rd-wr-sum {
+					cell-index = <1>;
+					node-name = "level3-nrt0-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					qcom,axi-port-mnoc {
+						cam-icc-path-names = "cam_sf_0";
+					};
+				};
+
+				level3_nrt1_rd_wr_sum: level3-nrt1-rd-wr-sum {
+					cell-index = <2>;
+					node-name = "level3-nrt1-rd-wr-sum";
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+					qcom,axi-port-mnoc {
+						cam-icc-path-names = "cam_sf_icp";
+					};
+				};
+			};
+
+			level2-nodes {
+				level-index = <2>;
+				camnoc-max-needed;
+				level2_rt_wr0: level2-rt-wr0 {
+					cell-index = <3>;
+					node-name = "level2-rt-wr0";
+					parent-node = <&level3_rt_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_rt_wr1: level2-rt-wr1 {
+					cell-index = <4>;
+					node-name = "level2-rt-wr1";
+					parent-node = <&level3_rt_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt_wr2: level2-nrt-wr2 {
+					cell-index = <5>;
+					node-name = "level2-nrt-wr2";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_rt_rd0: level2-rt-read0 {
+					cell-index = <6>;
+					node-name = "level2-rt-rd0";
+					parent-node = <&level3_rt_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt_rd1: level2-nrt-rd1 {
+					cell-index = <7>;
+					node-name = "level2-nrt-rd1";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_nrt_rd2: level2-nrt-rd2 {
+					cell-index = <8>;
+					node-name = "level2-nrt-rd2";
+					parent-node = <&level3_nrt0_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level2_icp_rd: level2-icp-rd {
+					cell-index = <9>;
+					node-name = "level2-icp-rd";
+					parent-node = <&level3_nrt1_rd_wr_sum>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+			};
+
+			level1-nodes {
+				level-index = <1>;
+				camnoc-max-needed;
+				level1_rt_wr0: level1-rt-wr0 {
+					cell-index = <10>;
+					node-name = "level1-rt-wr0";
+					parent-node = <&level2_rt_wr0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_rt_wr1: level1-rt-wr1 {
+					cell-index = <11>;
+					node-name = "level1-rt-wr1";
+					parent-node = <&level2_rt_wr1>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_rt_rd0: level1-rt-read0 {
+					cell-index = <13>;
+					node-name = "level1-rt-rd0";
+					parent-node = <&level2_rt_rd0>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+
+				level1_nrt_rd2: level1-nrt-rd2 {
+					cell-index = <15>;
+					node-name = "level1-nrt-rd2";
+					parent-node = <&level2_nrt_rd2>;
+					traffic-merge-type =
+					<CAM_CPAS_TRAFFIC_MERGE_SUM>;
+				};
+			};
+
+			level0-nodes {
+				level-index = <0>;
+				ife_0_wr_0: ife-0-wr-0 {
+					cell-index = <16>;
+					node-name = "ife-0-wr-0";
+					client-name = "ife0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_1_wr_0: ife-1-wr-0 {
+					cell-index = <17>;
+					node-name = "ife-1-wr-0";
+					client-name = "ife1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_0_wr_0: ife-lite-0-wr-0 {
+					cell-index = <18>;
+					node-name = "ife-lite-0-wr-0";
+					client-name = "ife2";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_1_wr_0: ife-lite-1-wr-0 {
+					cell-index = <19>;
+					node-name = "ife-lite-1-wr-0";
+					client-name = "ife3";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_2_wr_0: ife-lite-2-wr-0 {
+					cell-index = <20>;
+					node-name = "ife-lite-2-wr-0";
+					client-name = "ife4";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_3_wr_0: ife-lite-3-wr-0 {
+					cell-index = <21>;
+					node-name = "ife-lite-3-wr-0";
+					client-name = "ife5";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_lite_4_wr_0: ife-lite-4-wr-0 {
+					cell-index = <22>;
+					node-name = "ife-lite-4-wr-0";
+					client-name = "ife6";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_RDI_PIXEL_RAW>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_RDI0
+					CAM_CPAS_PATH_DATA_IFE_RDI1
+					CAM_CPAS_PATH_DATA_IFE_RDI2
+					CAM_CPAS_PATH_DATA_IFE_RDI3
+					CAM_CPAS_PATH_DATA_IFE_PIXEL_RAW>;
+					parent-node = <&level1_rt_wr0>;
+				};
+				ife_0_wr_1: ife-0-wr-1 {
+					cell-index = <23>;
+					node-name = "ife-0-wr-1";
+					client-name = "ife0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_UBWC>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_DISP>;
+					parent-node = <&level1_rt_wr1>;
+				};
+				ife_1_wr_1: ife-1-wr-1 {
+					cell-index = <24>;
+					node-name = "ife-1-wr-1";
+					client-name = "ife1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_IFE_UBWC>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IFE_VID
+					CAM_CPAS_PATH_DATA_IFE_LINEAR
+					CAM_CPAS_PATH_DATA_IFE_STATS
+					CAM_CPAS_PATH_DATA_IFE_PDAF
+					CAM_CPAS_PATH_DATA_IFE_DISP>;
+					parent-node = <&level1_rt_wr1>;
+				};
+				sfe_0_rd_0: sfe-0-rd-0 {
+					cell-index = <25>;
+					node-name = "sfe-0-rd-0";
+					client-name = "sfe0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_SFE_NRDI>;
+					parent-node = <&level1_rt_rd0>;
+				};
+				sfe_1_rd_0: sfe-1-rd-0 {
+					cell-index = <26>;
+					node-name = "sfe-1-rd-0";
+					client-name = "sfe1";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_SFE_NRDI>;
+					parent-node = <&level1_rt_rd0>;
+				};
+				ipe_0_wr_2: ipe-0-wr-2 {
+					cell-index = <27>;
+					node-name = "ipe-0-wr-2";
+					client-name = "ipe0";
+					traffic-data =
+					<CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_WRITE>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IPE_WR_VID
+					CAM_CPAS_PATH_DATA_IPE_WR_DISP
+					CAM_CPAS_PATH_DATA_IPE_WR_REF
+					CAM_CPAS_PATH_DATA_IPE_WR_APP>;
+					parent-node = <&level2_nrt_wr2>;
+				};
+				ipe_0_rd_all: ipe-0-rd-all {
+					cell-index = <28>;
+					node-name = "ipe-0-rd-all";
+					client-name = "ipe0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					constituent-paths =
+					<CAM_CPAS_PATH_DATA_IPE_RD_IN
+					CAM_CPAS_PATH_DATA_IPE_RD_REF>;
+					parent-node = <&level2_nrt_rd1>;
+				};
+				rt_cdm0_all_rd_2: rt-cdm0-all-rd-2 {
+					cell-index = <29>;
+					node-name = "rt-cdm0-all-rd-2";
+					client-name = "rt-cdm0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				rt_cdm1_all_rd_2: rt-cdm1-all-rd-2 {
+					cell-index = <30>;
+					node-name = "rt-cdm1-all-rd-2";
+					client-name = "rt-cdm1";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				rt_cdm2_all_rd_2: rt-cdm2-all-rd-2 {
+					cell-index = <31>;
+					node-name = "rt-cdm2-all-rd-2";
+					client-name = "rt-cdm2";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				rt_cdm3_all_rd_2: rt-cdm3-all-rd-2 {
+					cell-index = <32>;
+					node-name = "rt-cdm3-all-rd-2";
+					client-name = "rt-cdm3";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				ipe_cdm0_all_rd: ipe-cdm0-all-rd {
+					cell-index = <33>;
+					node-name = "ipe-cdm0-all-rd";
+					client-name = "ipe0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level1_nrt_rd2>;
+				};
+				icp_all_rd: icp-all-rd {
+					cell-index = <34>;
+					node-name = "icp-all-rd";
+					client-name = "icp0";
+					traffic-data = <CAM_CPAS_PATH_DATA_ALL>;
+					traffic-transaction-type =
+					<CAM_CPAS_TRANSACTION_READ>;
+					parent-node = <&level2_icp_rd>;
+				};
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p-dma-heaps.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8775p-dma-heaps.dtsi
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/arm/qcom_dma_heap_dt_constants.h>
+
+&soc {
+	qcom,dma-heaps {
+		compatible = "qcom,dma-heaps";
+
+		qcom,qseecom {
+			qcom,dma-heap-name = "qcom,qseecom";
+			qcom,dma-heap-type = <HEAP_TYPE_CMA>;
+			memory-region = <&qseecom_mem>;
+		};
+
+		qcom,qseecom_ta {
+			qcom,dma-heap-name = "qcom,qseecom-ta";
+			qcom,dma-heap-type = <HEAP_TYPE_CMA>;
+			memory-region = <&qseecom_ta_mem>;
+		};
+
+		qcom,secure_cdsp {
+			qcom,dma-heap-name = "qcom,cma-secure-cdsp";
+			qcom,dma-heap-type = <HEAP_TYPE_CMA>;
+			memory-region = <&cdsp_secure_heap>;
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p-el2.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8775p-el2.dtso
@@ -0,0 +1,272 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+/plugin/;
+
+&remoteproc_adsp {
+	iommus = <&apps_smmu 0x3000 0x0>;
+	qcom,devmem = <0x00110000 0x00110000 0x4000 0x1>,
+			<0x00123000 0x00123000 0x1000 0x3>,
+			<0x00124000 0x00124000 0x3000 0x3>,
+			<0x00127000 0x00127000 0x2000 0x3>,
+			<0x0012a000 0x0012a000 0x3000 0x3>,
+			<0x0012e000 0x0012e000 0x1000 0x3>,
+			<0x0012f000 0x0012f000 0x1000 0x1>,
+			<0x00144000 0x00144000 0x1000 0x1>,
+			<0x00148000 0x00148000 0x1000 0x1>,
+			<0x00149000 0x00149000 0xe000 0x3>,
+			<0x00157000 0x00157000 0x1000 0x3>,
+			<0x00158000 0x00158000 0xd000 0x3>,
+			<0x00165000 0x00165000 0x1000 0x3>,
+			<0x00172000 0x00172000 0x1000 0x3>,
+			<0x00173000 0x00173000 0x8000 0x3>,
+			<0x0017b000 0x0017b000 0x2000 0x3>,
+			<0x0017f000 0x0017f000 0x1000 0x3>,
+			<0x00184000 0x00184000 0x1000 0x1>,
+			<0x00186000 0x00186000 0x1000 0x1>,
+			<0x0019c000 0x0019c000 0x3000 0x3>,
+			<0x0019f000 0x0019f000 0xe000 0x3>,
+			<0x001ad000 0x001ad000 0x2000 0x3>,
+			<0x001b0000 0x001b0000 0x1000 0x3>,
+			<0x001b2000 0x001b2000 0x1000 0x3>,
+			<0x001b4000 0x001b4000 0x1000 0x3>,
+			<0x001b6000 0x001b6000 0x1000 0x3>,
+			<0x001be000 0x001be000 0x1000 0x3>,
+			<0x001bf000 0x001bf000 0x10000 0x3>,
+			<0x001cf000 0x001cf000 0x1000 0x3>,
+			<0x00403000 0x00403000 0x1000 0x3>,
+			<0x00443000 0x00443000 0x1000 0x3>,
+			<0x00483000 0x00483000 0x1000 0x3>,
+			<0x004c3000 0x004c3000 0x1000 0x3>,
+			<0x004fc000 0x004fc000 0x1000 0x1>,
+			<0x00780000 0x00780000 0x7000 0x1>,
+			<0x010d0000 0x010d0000 0x1000 0x1>,
+			<0x010d4000 0x010d4000 0x1000 0x1>,
+			<0x01dc4000 0x01dc4000 0x1000 0x1>,
+			<0x01dc5000 0x01dc5000 0x1000 0x3>,
+			<0x01dc8000 0x01dc8000 0x1000 0x3>,
+			<0x01dfa000 0x01dfa000 0x1000 0x3>,
+			<0x01dfd000 0x01dfd000 0x1000 0x3>,
+			<0x01f40000 0x01f40000 0x40000 0x3>,
+			<0x01fc0000 0x01fc0000 0x29000 0x1>,
+			<0x01fe9000 0x01fe9000 0x1000 0x3>,
+			<0x01fea000 0x01fea000 0x1000 0x1>,
+			<0x01feb000 0x01feb000 0x1000 0x1>,
+			<0x01fec000 0x01fec000 0x4000 0x1>,
+			<0x03c41000 0x03c41000 0x3000 0x3>,
+			<0x03c4f000 0x03c4f000 0x1000 0x3>,
+			<0x04001000 0x04001000 0x1000 0x3>,
+			<0x04002000 0x04002000 0x1000 0x3>,
+			<0x04041000 0x04041000 0x1000 0x3>,
+			<0x04042000 0x04042000 0x1000 0x3>,
+			<0x04043000 0x04043000 0x1000 0x3>,
+			<0x04045000 0x04045000 0x1000 0x3>,
+			<0x04046000 0x04046000 0x1000 0x3>,
+			<0x0404e000 0x0404e000 0x1000 0x3>,
+			<0x0404f000 0x0404f000 0x1000 0x3>,
+			<0x04b04000 0x04b04000 0x1000 0x3>,
+			<0x04b05000 0x04b05000 0x1000 0x3>,
+			<0x04b11000 0x04b11000 0x1000 0x3>,
+			<0x04b40000 0x04b40000 0x20000 0x3>,
+			<0x09080000 0x09080000 0x1000 0x3>,
+			<0x09200000 0x09200000 0x28000 0x3>,
+			<0x09300000 0x09300000 0x28000 0x3>,
+			<0x09400000 0x09400000 0x28000 0x3>,
+			<0x09500000 0x09500000 0x28000 0x3>,
+			<0x09600000 0x09600000 0x28000 0x3>,
+			<0x09700000 0x09700000 0x28000 0x3>,
+			<0x0b250000 0x0b250000 0x10000 0x3>,
+			<0x0b450000 0x0b450000 0x10000 0x3>,
+			<0x0bbf0000 0x0bbf0000 0x2000 0x1>,
+			<0x0c210000 0x0c210000 0x80000 0x1>,
+			<0x0c340000 0x0c340000 0x1000 0x3>,
+			<0x0c370000 0x0c370000 0x1000 0x1>,
+			<0x0c380000 0x0c380000 0x1000 0x1>,
+			<0x0c390000 0x0c390000 0x1000 0x1>,
+			<0x0c3a0000 0x0c3a0000 0x1000 0x1>,
+			<0x0c3b0000 0x0c3b0000 0x1000 0x1>,
+			<0x0c3c0000 0x0c3c0000 0x1000 0x1>,
+			<0x0c3d0000 0x0c3d0000 0x1000 0x1>,
+			<0x0c3e0000 0x0c3e0000 0x1000 0x3>,
+			<0x0c3f0000 0x0c3f0000 0x1000 0x1>,
+			<0x0c400000 0x0c400000 0x30000 0x3>,
+			<0x0c440000 0x0c440000 0x10000 0x3>,
+			<0x0c460000 0x0c460000 0x81000 0x1>,
+			<0x0e600000 0x0e600000 0x100000 0x3>,
+			<0x0e700000 0x0e700000 0xa0000 0x1>,
+			<0x0f000000 0x0f000000 0x1000000 0x3>,
+			<0x146d8000 0x146d8000 0x1000 0x3>,
+			<0x16000000 0x16000000 0x1000000 0x2>,
+			<0x80b00000 0x80b00000 0x100000 0x3>,
+			<0x90860000 0x90860000 0x20000 0x3>,
+			<0x90900000 0x90900000 0x200000 0x3>;
+};
+
+&remoteproc_cdsp0 {
+	iommus = <&apps_smmu 0x21c0 0x0400>;
+	qcom,devmem = <0x00110000   0x00110000   0x4000     0x1>,
+			<0x00114000   0x00114000   0xf000     0x3>,
+			<0x00123000   0x00123000   0x1000     0x3>,
+			<0x00124000   0x00124000   0x3000     0x3>,
+			<0x00127000   0x00127000   0x3000     0x3>,
+			<0x0012a000   0x0012a000   0x3000     0x3>,
+			<0x0012e000   0x0012e000   0x1000     0x3>,
+			<0x0012f000   0x0012f000   0x1000     0x1>,
+			<0x00144000   0x00144000   0x1000     0x1>,
+			<0x00148000   0x00148000   0x1000     0x1>,
+			<0x00149000   0x00149000   0xc000     0x3>,
+			<0x00155000   0x00155000   0x1000     0x3>,
+			<0x0016b000   0x0016b000   0x1000     0x3>,
+			<0x00172000   0x00172000   0x1000     0x3>,
+			<0x00173000   0x00173000   0x11000    0x3>,
+			<0x00184000   0x00184000   0x1000     0x1>,
+			<0x00186000   0x00186000   0x1000     0x1>,
+			<0x00187000   0x00187000   0x45000    0x3>,
+			<0x001cc000   0x001cc000   0x1000     0x3>,
+			<0x00406000   0x00406000   0x1000     0x3>,
+			<0x00412000   0x00412000   0x1000     0x3>,
+			<0x00446000   0x00446000   0x1000     0x3>,
+			<0x00452000   0x00452000   0x1000     0x3>,
+			<0x00486000   0x00486000   0x1000     0x3>,
+			<0x00492000   0x00492000   0x1000     0x3>,
+			<0x004c6000   0x004c6000   0x1000     0x3>,
+			<0x004d2000   0x004d2000   0x1000     0x3>,
+			<0x004fc000   0x004fc000   0x1000     0x1>,
+			<0x0063a000   0x0063a000   0x4000     0x3>,
+			<0x0063e000   0x0063e000   0x4000     0x3>,
+			<0x00780000   0x00780000   0x10000    0x1>,
+			<0x010d0000   0x010d0000   0x1000     0x1>,
+			<0x010da000   0x010da000   0x1000     0x1>,
+			<0x016c2000   0x016c2000   0x9000     0x3>,
+			<0x01703000   0x01703000   0x5000     0x3>,
+			<0x01f40000   0x01f40000   0x40000    0x3>,
+			<0x01fc0000   0x01fc0000   0x2b000    0x1>,
+			<0x01feb000   0x01feb000   0x1000     0x3>,
+			<0x01fec000   0x01fec000   0x4000     0x1>,
+			<0x01fff000   0x01fff000   0x1000     0x1>,
+			<0x09080000   0x09080000   0x1000     0x3>,
+			<0x090b4000   0x090b4000   0x1000     0x3>,
+			<0x090b8000   0x090b8000   0x1000     0x3>,
+			<0x09200000   0x09200000   0x28000    0x3>,
+			<0x09300000   0x09300000   0x28000    0x3>,
+			<0x09400000   0x09400000   0x28000    0x3>,
+			<0x09500000   0x09500000   0x28000    0x3>,
+			<0x09600000   0x09600000   0x28000    0x3>,
+			<0x09700000   0x09700000   0x28000    0x3>,
+			<0x0b2c0000   0x0b2c0000   0x10000    0x3>,
+			<0x0b2f0000   0x0b2f0000   0x10000    0x3>,
+			<0x0b4c0000   0x0b4c0000   0x10000    0x3>,
+			<0x0b4f0000   0x0b4f0000   0x10000    0x3>,
+			<0x0bbf0000   0x0bbf0000   0x2000     0x1>,
+			<0x0c20a000   0x0c20a000   0x1000     0x3>,
+			<0x0c20b000   0x0c20b000   0x1000     0x3>,
+			<0x0c210000   0x0c210000   0x80000    0x1>,
+			<0x0c330000   0x0c330000   0x1000     0x3>,
+			<0x0c370000   0x0c370000   0x1000     0x1>,
+			<0x0c380000   0x0c380000   0x1000     0x3>,
+			<0x0c390000   0x0c390000   0x1000     0x1>,
+			<0x0c3a0000   0x0c3a0000   0x1000     0x1>,
+			<0x0c3b0000   0x0c3b0000   0x1000     0x1>,
+			<0x0c3c0000   0x0c3c0000   0x1000     0x1>,
+			<0x0c3d0000   0x0c3d0000   0x1000     0x1>,
+			<0x0c3e0000   0x0c3e0000   0x1000     0x1>,
+			<0x0c3f0000   0x0c3f0000   0x1000     0x1>,
+			<0x0c440000   0x0c440000   0x10000    0x3>,
+			<0x0c460000   0x0c460000   0x81000    0x1>,
+			<0x0e600000   0x0e600000   0x100000   0x3>,
+			<0x0e700000   0x0e700000   0xa0000    0x1>,
+			<0x0f000000   0x0f000000   0x1000000  0x3>,
+			<0x146d8000   0x146d8000   0x1000     0x3>,
+			<0x16000000   0x16000000   0x1000000  0x2>,
+			<0x23007000   0x23007000   0x1000     0x1>,
+			<0x23047000   0x23047000   0x1000     0x1>,
+			<0x2304e000   0x2304e000   0x2000     0x3>,
+			<0x90860000   0x90860000   0x20000    0x3>,
+			<0x90900000   0x90900000   0x200000   0x3>;
+};
+
+&remoteproc_cdsp1 {
+	iommus = <&apps_smmu 0x29c0 0x0400>;
+	qcom,devmem = <0x00110000   0x00110000   0x4000     0x1>,
+			<0x00114000   0x00114000   0xf000     0x3>,
+			<0x00123000   0x00123000   0x1000     0x3>,
+			<0x00124000   0x00124000   0x3000     0x3>,
+			<0x00127000   0x00127000   0x3000     0x3>,
+			<0x0012a000   0x0012a000   0x3000     0x3>,
+			<0x0012e000   0x0012e000   0x1000     0x3>,
+			<0x0012f000   0x0012f000   0x1000     0x1>,
+			<0x00144000   0x00144000   0x1000     0x1>,
+			<0x00148000   0x00148000   0x1000     0x1>,
+			<0x00149000   0x00149000   0xc000     0x3>,
+			<0x00155000   0x00155000   0x1000     0x3>,
+			<0x0016b000   0x0016b000   0x1000     0x3>,
+			<0x00172000   0x00172000   0x1000     0x3>,
+			<0x00173000   0x00173000   0x11000    0x3>,
+			<0x00184000   0x00184000   0x1000     0x1>,
+			<0x00186000   0x00186000   0x1000     0x1>,
+			<0x00187000   0x00187000   0x45000    0x3>,
+			<0x001cc000   0x001cc000   0x1000     0x3>,
+			<0x00406000   0x00406000   0x1000     0x3>,
+			<0x00412000   0x00412000   0x1000     0x3>,
+			<0x00446000   0x00446000   0x1000     0x3>,
+			<0x00452000   0x00452000   0x1000     0x3>,
+			<0x00486000   0x00486000   0x1000     0x3>,
+			<0x00492000   0x00492000   0x1000     0x3>,
+			<0x004c6000   0x004c6000   0x1000     0x3>,
+			<0x004d2000   0x004d2000   0x1000     0x3>,
+			<0x004fc000   0x004fc000   0x1000     0x1>,
+			<0x0063a000   0x0063a000   0x4000     0x3>,
+			<0x0063e000   0x0063e000   0x4000     0x3>,
+			<0x00780000   0x00780000   0x10000    0x1>,
+			<0x010d0000   0x010d0000   0x1000     0x1>,
+			<0x010da000   0x010da000   0x1000     0x1>,
+			<0x016c2000   0x016c2000   0x9000     0x3>,
+			<0x01703000   0x01703000   0x5000     0x3>,
+			<0x01f40000   0x01f40000   0x40000    0x3>,
+			<0x01fc0000   0x01fc0000   0x2b000    0x1>,
+			<0x01feb000   0x01feb000   0x1000     0x3>,
+			<0x01fec000   0x01fec000   0x4000     0x1>,
+			<0x01fff000   0x01fff000   0x1000     0x1>,
+			<0x09080000   0x09080000   0x1000     0x3>,
+			<0x090b4000   0x090b4000   0x1000     0x3>,
+			<0x090b8000   0x090b8000   0x1000     0x3>,
+			<0x09200000   0x09200000   0x28000    0x3>,
+			<0x09300000   0x09300000   0x28000    0x3>,
+			<0x09400000   0x09400000   0x28000    0x3>,
+			<0x09500000   0x09500000   0x28000    0x3>,
+			<0x09600000   0x09600000   0x28000    0x3>,
+			<0x09700000   0x09700000   0x28000    0x3>,
+			<0x0b2c0000   0x0b2c0000   0x10000    0x3>,
+			<0x0b2f0000   0x0b2f0000   0x10000    0x3>,
+			<0x0b4c0000   0x0b4c0000   0x10000    0x3>,
+			<0x0b4f0000   0x0b4f0000   0x10000    0x3>,
+			<0x0bbf0000   0x0bbf0000   0x2000     0x1>,
+			<0x0c20a000   0x0c20a000   0x1000     0x3>,
+			<0x0c20b000   0x0c20b000   0x1000     0x3>,
+			<0x0c210000   0x0c210000   0x80000    0x1>,
+			<0x0c330000   0x0c330000   0x1000     0x3>,
+			<0x0c370000   0x0c370000   0x1000     0x1>,
+			<0x0c380000   0x0c380000   0x1000     0x3>,
+			<0x0c390000   0x0c390000   0x1000     0x1>,
+			<0x0c3a0000   0x0c3a0000   0x1000     0x1>,
+			<0x0c3b0000   0x0c3b0000   0x1000     0x1>,
+			<0x0c3c0000   0x0c3c0000   0x1000     0x1>,
+			<0x0c3d0000   0x0c3d0000   0x1000     0x1>,
+			<0x0c3e0000   0x0c3e0000   0x1000     0x1>,
+			<0x0c3f0000   0x0c3f0000   0x1000     0x1>,
+			<0x0c440000   0x0c440000   0x10000    0x3>,
+			<0x0c460000   0x0c460000   0x81000    0x1>,
+			<0x0e600000   0x0e600000   0x100000   0x3>,
+			<0x0e700000   0x0e700000   0xa0000    0x1>,
+			<0x0f000000   0x0f000000   0x1000000  0x3>,
+			<0x146d8000   0x146d8000   0x1000     0x3>,
+			<0x16000000   0x16000000   0x1000000  0x2>,
+			<0x23007000   0x23007000   0x1000     0x1>,
+			<0x23047000   0x23047000   0x1000     0x1>,
+			<0x2304e000   0x2304e000   0x2000     0x3>,
+			<0x90860000   0x90860000   0x20000    0x3>,
+			<0x90900000   0x90900000   0x200000   0x3>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p-pmics.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8775p-pmics.dtsi
@@ -1,8 +1,10 @@
 // SPDX-License-Identifier: BSD-3-Clause
 /*
  * Copyright (c) 2023, Linaro Limited
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
+#include <dt-bindings/iio/qcom,spmi-adc5-gen3-pm8775.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/spmi/spmi.h>
 
@@ -10,7 +12,7 @@
 	thermal-zones {
 		pmm8654au_0_thermal: pm8775-0-thermal {
 			polling-delay-passive = <100>;
-			polling-delay = <0>;
+
 			thermal-sensors = <&pmm8654au_0_temp_alarm>;
 
 			trips {
@@ -30,7 +32,7 @@
 
 		pmm8654au_1_thermal: pm8775-1-thermal {
 			polling-delay-passive = <100>;
-			polling-delay = <0>;
+
 			thermal-sensors = <&pmm8654au_1_temp_alarm>;
 
 			trips {
@@ -50,7 +52,7 @@
 
 		pmm8654au_2_thermal: pm8775-2-thermal {
 			polling-delay-passive = <100>;
-			polling-delay = <0>;
+
 			thermal-sensors = <&pmm8654au_2_temp_alarm>;
 
 			trips {
@@ -70,7 +72,7 @@
 
 		pmm8654au_3_thermal: pm8775-3-thermal {
 			polling-delay-passive = <100>;
-			polling-delay = <0>;
+
 			thermal-sensors = <&pmm8654au_3_temp_alarm>;
 
 			trips {
@@ -87,6 +89,163 @@
 				};
 			};
 		};
+
+		pmm8654au_0_mbg_tm: pmm8654au_0_mbg_tz {
+			polling-delay-passive = <100>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8654au_0_tz>;
+
+			trips {
+				trip0 {
+					temperature = <115000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <135000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+
+		pmm8654au_1_mbg_tm: pmm8654au_1_mbg_tz {
+			polling-delay-passive = <100>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8654au_1_tz>;
+
+			trips {
+				trip0 {
+					temperature = <115000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <135000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+
+		pmm8654au_2_mbg_tm: pmm8654au_2_mbg_tz {
+			polling-delay-passive = <100>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8654au_2_tz>;
+
+			trips {
+				trip0 {
+					temperature = <115000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <135000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+			};
+		};
+
+		pmm8654au_3_mbg_tm: pmm8654au_3_mbg_tz {
+			polling-delay-passive = <100>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8654au_3_tz>;
+
+			trips {
+				trip0 {
+					temperature = <115000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <135000>;
+					hysteresis = <5000>;
+					type = "passive";
+				};
+
+			};
+		};
+
+		sdram-therm {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8654au_2_adc PM8775_3_ADC5_GEN3_AMUX6_THM_100K_PU>;
+			trips {
+				trip0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+			};
+		};
+
+		soc-therm {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8654au_0_adc PM8775_1_ADC5_GEN3_AMUX6_THM_100K_PU>;
+			trips {
+				trip0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+			};
+		};
+
+		ufs0-therm {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8654au_0_adc PM8775_1_ADC5_GEN3_AMUX5_THM_100K_PU>;
+			trips {
+				trip0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+			};
+		};
+
+		xo-therm {
+			polling-delay-passive = <0>;
+			polling-delay = <0>;
+			thermal-sensors = <&pmm8654au_0_adc PM8775_1_ADC5_GEN3_AMUX1_THM_100K_PU>;
+			trips {
+				trip0 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+
+				trip1 {
+					temperature = <125000>;
+					hysteresis = <1000>;
+					type = "passive";
+				};
+			};
+		};
 	};
 
 	reboot-mode {
@@ -101,14 +260,79 @@
 &spmi_bus {
 	pmm8654au_0: pmic@0 {
 		compatible = "qcom,pmm8654au", "qcom,spmi-pmic";
-		reg = <0x0 SPMI_USID>;
+		reg = <0 SPMI_USID>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 
+		pmm8654au_0_adc: vadc@8000 {
+			compatible = "qcom,spmi-adc5-gen3";
+			reg = <0x8000>;
+			reg-names = "adc5-gen3-base";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts-extended = <&spmi_bus 0x0 0x80 0x1 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "adc-sdam0";
+			#io-channel-cells = <1>;
+			#thermal-sensor-cells = <1>;
+
+			pmm8654au_0_ref_gnd {
+				reg = <PM8775_1_ADC5_GEN3_OFFSET_REF>;
+				label = "pm8775_1_ref_gnd";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8654au_0_vref_1p25 {
+				reg = <PM8775_1_ADC5_GEN3_1P25VREF>;
+				label = "pm8775_1_vref_1p25";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8654au_0_die_temp {
+				reg = <PM8775_1_ADC5_GEN3_DIE_TEMP>;
+				label = "pm8775_1_die_temp";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8654au_0_vph_pwr {
+				reg = <PM8775_1_ADC5_GEN3_VPH_PWR>;
+				label = "pm8775_1_vph_pwr";
+				qcom,pre-scaling = <1 3>;
+			};
+
+			soc_therm {
+				reg = <PM8775_1_ADC5_GEN3_AMUX6_THM_100K_PU>;
+				label = "pmm8654au_0_soc_therm";
+				qcom,ratiometric;
+				qcom,hw-settle-time = <200>;
+				qcom,adc-tm;
+				qcom,pre-scaling = <1 1>;
+			};
+
+			ufs0_therm {
+				reg = <PM8775_1_ADC5_GEN3_AMUX5_THM_100K_PU>;
+				label = "pmm8654au_0_ufs0_therm";
+				qcom,ratiometric;
+				qcom,hw-settle-time = <200>;
+				qcom,adc-tm;
+				qcom,pre-scaling = <1 1>;
+			};
+
+			xo_therm {
+				reg = <PM8775_1_ADC5_GEN3_AMUX1_THM_100K_PU>;
+				label = "pmm8654au_0_xo_therm";
+				qcom,ratiometric;
+				qcom,hw-settle-time = <700>;
+				qcom,adc-tm;
+				qcom,pre-scaling = <1 1>;
+			};
+		};
+
 		pmm8654au_0_temp_alarm: temp-alarm@a00 {
 			compatible = "qcom,spmi-temp-alarm";
 			reg = <0xa00>;
 			interrupts-extended = <&spmi_bus 0x0 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+			io-channels = <&pmm8654au_0_adc PM8775_1_ADC5_GEN3_DIE_TEMP>;
+			io-channel-names = "thermal";
 			#thermal-sensor-cells = <0>;
 		};
 
@@ -132,14 +356,11 @@
 			};
 		};
 
-		pmm8654au_0_gpios: gpio@8800 {
-			compatible = "qcom,pmm8654au-gpio", "qcom,spmi-gpio";
-			reg = <0x8800>;
-			gpio-controller;
-			gpio-ranges = <&pmm8654au_0_gpios 0 0 12>;
-			#gpio-cells = <2>;
-			interrupt-controller;
-			#interrupt-cells = <2>;
+		pmm8654au_0_rtc: rtc@6100 {
+			compatible = "qcom,pmk8350-rtc";
+			reg = <0x6100>, <0x6200>;
+			reg-names = "rtc", "alarm";
+			interrupts = <0x0 0x62 0x1 IRQ_TYPE_NONE>;
 		};
 
 		pmm8654au_0_sdam_0: nvram@7100 {
@@ -154,18 +375,82 @@
 				bits = <1 7>;
 			};
 		};
+
+		pmm8654au_0_gpios: gpio@8800 {
+			compatible = "qcom,pmm8654au-gpio", "qcom,spmi-gpio";
+			reg = <0x8800>;
+			gpio-controller;
+			gpio-ranges = <&pmm8654au_0_gpios 0 0 12>;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	pmm8654au_sail_0: pmic@1 {
+		compatible = "qcom,pmm8654au", "qcom,spmi-pmic";
+		reg = <1 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pmm8654au_0_tz: qcom,mbg-tm@d700 {
+			compatible = "qcom,spmi-mgb-tm";
+			reg = <0xd700>;
+			io-channels = <&pmm8654au_0_adc PM8775_1_ADC5_GEN3_DIE_TEMP>;
+			io-channel-names = "thermal";
+			interrupts-extended = <&spmi_bus 0x1 0xd7 0x0 IRQ_TYPE_EDGE_RISING>;
+			#thermal-sensor-cells = <0>;
+		};
 	};
 
 	pmm8654au_1: pmic@2 {
 		compatible = "qcom,pmm8654au", "qcom,spmi-pmic";
-		reg = <0x2 SPMI_USID>;
+		reg = <2 SPMI_USID>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 
+		pmm8654au_1_adc: vadc@8000 {
+			compatible = "qcom,spmi-adc5-gen3";
+			reg = <0x8000>;
+			reg-names = "adc5-gen3-base";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts-extended = <&spmi_bus 0x2 0x80 0x1 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "adc-sdam0";
+			#io-channel-cells = <1>;
+			#thermal-sensor-cells = <1>;
+
+			pmm8654au_1_ref_gnd {
+				reg = <PM8775_2_ADC5_GEN3_OFFSET_REF>;
+				label = "pm8775_2_ref_gnd";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8654au_1_vref_1p25 {
+				reg = <PM8775_2_ADC5_GEN3_1P25VREF>;
+				label = "pm8775_2_vref_1p25";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8654au_1_die_temp {
+				reg = <PM8775_2_ADC5_GEN3_DIE_TEMP>;
+				label = "pm8775_2_die_temp";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8654au_1_vph_pwr {
+				reg = <PM8775_2_ADC5_GEN3_VPH_PWR>;
+				label = "pm8775_2_vph_pwr";
+				qcom,pre-scaling = <1 3>;
+			};
+		};
+
 		pmm8654au_1_temp_alarm: temp-alarm@a00 {
 			compatible = "qcom,spmi-temp-alarm";
 			reg = <0xa00>;
 			interrupts-extended = <&spmi_bus 0x2 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+			io-channels = <&pmm8654au_1_adc PM8775_2_ADC5_GEN3_DIE_TEMP>;
+			io-channel-names = "thermal";
 			#thermal-sensor-cells = <0>;
 		};
 
@@ -180,16 +465,79 @@
 		};
 	};
 
+	pmm8654au_sail_1: pmic@3 {
+		compatible = "qcom,pmm8654au", "qcom,spmi-pmic";
+		reg = <3 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pmm8654au_1_tz: qcom,mbg-tm@d700 {
+			compatible = "qcom,spmi-mgb-tm";
+			reg = <0xd700>;
+			io-channels = <&pmm8654au_1_adc PM8775_2_ADC5_GEN3_DIE_TEMP>;
+			io-channel-names = "thermal";
+			interrupts-extended = <&spmi_bus 0x3 0xd7 0x0 IRQ_TYPE_EDGE_RISING>;
+			#thermal-sensor-cells = <0>;
+		};
+	};
+
 	pmm8654au_2: pmic@4 {
 		compatible = "qcom,pmm8654au", "qcom,spmi-pmic";
-		reg = <0x4 SPMI_USID>;
+		reg = <4 SPMI_USID>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 
+		pmm8654au_2_adc: vadc@8000 {
+			compatible = "qcom,spmi-adc5-gen3";
+			reg = <0x8000>;
+			reg-names = "adc5-gen3-base";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts-extended = <&spmi_bus 0x4 0x80 0x1 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "adc-sdam0";
+			#io-channel-cells = <1>;
+			#thermal-sensor-cells = <1>;
+
+			pmm8654au_2_ref_gnd {
+				reg = <PM8775_3_ADC5_GEN3_OFFSET_REF>;
+				label = "pm8775_3_ref_gnd";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8654au_2_vref_1p25 {
+				reg = <PM8775_3_ADC5_GEN3_1P25VREF>;
+				label = "pm8775_3_vref_1p25";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8654au_2_die_temp {
+				reg = <PM8775_3_ADC5_GEN3_DIE_TEMP>;
+				label = "pm8775_3_die_temp";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8654au_2_vph_pwr {
+				reg = <PM8775_3_ADC5_GEN3_VPH_PWR>;
+				label = "pm8775_3_vph_pwr";
+				qcom,pre-scaling = <1 3>;
+			};
+
+			sdram_therm {
+				reg = <PM8775_3_ADC5_GEN3_AMUX6_THM_100K_PU>;
+				label = "pmm8654au_2_sdram_therm1";
+				qcom,ratiometric;
+				qcom,hw-settle-time = <200>;
+				qcom,adc-tm;
+				qcom,pre-scaling = <1 1>;
+			};
+		};
+
 		pmm8654au_2_temp_alarm: temp-alarm@a00 {
 			compatible = "qcom,spmi-temp-alarm";
 			reg = <0xa00>;
 			interrupts-extended = <&spmi_bus 0x4 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+			io-channels = <&pmm8654au_2_adc PM8775_3_ADC5_GEN3_DIE_TEMP>;
+			io-channel-names = "thermal";
 			#thermal-sensor-cells = <0>;
 		};
 
@@ -204,16 +552,70 @@
 		};
 	};
 
+	pmm8654au_sail_2: pmic@5 {
+		compatible = "qcom,pmm8654au", "qcom,spmi-pmic";
+		reg = <5 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pmm8654au_2_tz: qcom,mbg-tm@d700 {
+			compatible = "qcom,spmi-mgb-tm";
+			reg = <0xd700>;
+			io-channels = <&pmm8654au_2_adc PM8775_3_ADC5_GEN3_DIE_TEMP>;
+			io-channel-names = "thermal";
+			interrupts-extended = <&spmi_bus 0x5 0xd7 0x0 IRQ_TYPE_EDGE_RISING>;
+			#thermal-sensor-cells = <0>;
+		};
+	};
+
 	pmm8654au_3: pmic@6 {
 		compatible = "qcom,pmm8654au", "qcom,spmi-pmic";
-		reg = <0x6 SPMI_USID>;
+		reg = <6 SPMI_USID>;
 		#address-cells = <1>;
 		#size-cells = <0>;
 
+		pmm8654au_3_adc: vadc@8000 {
+			compatible = "qcom,spmi-adc5-gen3";
+			reg = <0x8000>;
+			reg-names = "adc5-gen3-base";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			interrupts-extended = <&spmi_bus 0x6 0x80 0x1 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "adc-sdam0";
+			#io-channel-cells = <1>;
+			#thermal-sensor-cells = <1>;
+
+			pmm8654au_3_ref_gnd {
+				reg = <PM8775_4_ADC5_GEN3_OFFSET_REF>;
+				label = "pm8775_4_ref_gnd";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8654au_3_vref_1p25 {
+				reg = <PM8775_4_ADC5_GEN3_1P25VREF>;
+				label = "pm8775_4_vref_1p25";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8654au_3_die_temp {
+				reg = <PM8775_4_ADC5_GEN3_DIE_TEMP>;
+				label = "pm8775_4_die_temp";
+				qcom,pre-scaling = <1 1>;
+			};
+
+			pmm8654au_3_vph_pwr {
+				reg = <PM8775_4_ADC5_GEN3_VPH_PWR>;
+				label = "pm8775_4_vph_pwr";
+				qcom,pre-scaling = <1 3>;
+			};
+		};
+
 		pmm8654au_3_temp_alarm: temp-alarm@a00 {
 			compatible = "qcom,spmi-temp-alarm";
 			reg = <0xa00>;
 			interrupts-extended = <&spmi_bus 0x6 0xa 0x0 IRQ_TYPE_EDGE_BOTH>;
+			io-channels = <&pmm8654au_3_adc PM8775_4_ADC5_GEN3_DIE_TEMP>;
+			io-channel-names = "thermal";
 			#thermal-sensor-cells = <0>;
 		};
 
@@ -227,4 +629,20 @@
 			#interrupt-cells = <2>;
 		};
 	};
+
+	pmm8654au_sail_3: pmic@7 {
+		compatible = "qcom,pmm8654au", "qcom,spmi-pmic";
+		reg = <7 SPMI_USID>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		pmm8654au_3_tz: qcom,mbg-tm@d700 {
+			compatible = "qcom,spmi-mgb-tm";
+			reg = <0xd700>;
+			io-channels = <&pmm8654au_3_adc PM8775_4_ADC5_GEN3_DIE_TEMP>;
+			io-channel-names = "thermal";
+			interrupts-extended = <&spmi_bus 0x7 0xd7 0x0 IRQ_TYPE_EDGE_RISING>;
+			#thermal-sensor-cells = <0>;
+		};
+	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p-ride-r3.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8775p-ride-r3.dts
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+/dts-v1/;
+
+#include "sa8775p-ride.dtsi"
+
+/ {
+	model = "Qualcomm SA8775P Ride Rev3";
+	compatible = "qcom,sa8775p-ride-r3", "qcom,sa8775p";
+	qcom,msm-id = <533 0x10000>, <534 0x10000>, <534 0x20000>;
+	qcom,board-id = <0x20025 1>;
+};
+
+&ethernet0 {
+	phy-mode = "2500base-x";
+};
+
+&ethernet1 {
+	phy-mode = "2500base-x";
+};
+
+&mdio {
+	compatible = "snps,dwmac-mdio";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	sgmii_phy0: phy@8 {
+		compatible = "ethernet-phy-id31c3.1c33";
+		reg = <0x8>;
+		device_type = "ethernet-phy";
+		interrupts-extended = <&tlmm 7 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&pmm8654au_2_gpios 8 GPIO_ACTIVE_LOW>;
+		reset-assert-us = <11000>;
+		reset-deassert-us = <70000>;
+	};
+
+	sgmii_phy1: phy@0 {
+		compatible = "ethernet-phy-id31c3.1c33";
+		reg = <0x0>;
+		device_type = "ethernet-phy";
+		interrupts-extended = <&tlmm 26 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&pmm8654au_2_gpios 9 GPIO_ACTIVE_LOW>;
+		reset-assert-us = <11000>;
+		reset-deassert-us = <70000>;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p-ride.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8775p-ride.dts
@@ -1,839 +1,50 @@
 // SPDX-License-Identifier: BSD-3-Clause
 /*
  * Copyright (c) 2023, Linaro Limited
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 /dts-v1/;
 
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
-
-#include "sa8775p.dtsi"
-#include "sa8775p-pmics.dtsi"
+#include "sa8775p-ride.dtsi"
 
 / {
 	model = "Qualcomm SA8775P Ride";
 	compatible = "qcom,sa8775p-ride", "qcom,sa8775p";
-
-	aliases {
-		ethernet0 = &ethernet0;
-		ethernet1 = &ethernet1;
-		i2c11 = &i2c11;
-		i2c18 = &i2c18;
-		serial0 = &uart10;
-		serial1 = &uart12;
-		serial2 = &uart17;
-		spi16 = &spi16;
-		ufshc1 = &ufs_mem_hc;
-	};
-
-	chosen {
-		stdout-path = "serial0:115200n8";
-	};
-};
-
-&apps_rsc {
-	regulators-0 {
-		compatible = "qcom,pmm8654au-rpmh-regulators";
-		qcom,pmic-id = "a";
-
-		vreg_s4a: smps4 {
-			regulator-name = "vreg_s4a";
-			regulator-min-microvolt = <1800000>;
-			regulator-max-microvolt = <1816000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_s5a: smps5 {
-			regulator-name = "vreg_s5a";
-			regulator-min-microvolt = <1850000>;
-			regulator-max-microvolt = <1996000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_s9a: smps9 {
-			regulator-name = "vreg_s9a";
-			regulator-min-microvolt = <535000>;
-			regulator-max-microvolt = <1120000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l4a: ldo4 {
-			regulator-name = "vreg_l4a";
-			regulator-min-microvolt = <788000>;
-			regulator-max-microvolt = <1050000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l5a: ldo5 {
-			regulator-name = "vreg_l5a";
-			regulator-min-microvolt = <870000>;
-			regulator-max-microvolt = <950000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l6a: ldo6 {
-			regulator-name = "vreg_l6a";
-			regulator-min-microvolt = <870000>;
-			regulator-max-microvolt = <970000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l7a: ldo7 {
-			regulator-name = "vreg_l7a";
-			regulator-min-microvolt = <720000>;
-			regulator-max-microvolt = <950000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l8a: ldo8 {
-			regulator-name = "vreg_l8a";
-			regulator-min-microvolt = <2504000>;
-			regulator-max-microvolt = <3300000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l9a: ldo9 {
-			regulator-name = "vreg_l9a";
-			regulator-min-microvolt = <2970000>;
-			regulator-max-microvolt = <3544000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-	};
-
-	regulators-1 {
-		compatible = "qcom,pmm8654au-rpmh-regulators";
-		qcom,pmic-id = "c";
-
-		vreg_l1c: ldo1 {
-			regulator-name = "vreg_l1c";
-			regulator-min-microvolt = <1140000>;
-			regulator-max-microvolt = <1260000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l2c: ldo2 {
-			regulator-name = "vreg_l2c";
-			regulator-min-microvolt = <900000>;
-			regulator-max-microvolt = <1100000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l3c: ldo3 {
-			regulator-name = "vreg_l3c";
-			regulator-min-microvolt = <1100000>;
-			regulator-max-microvolt = <1300000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l4c: ldo4 {
-			regulator-name = "vreg_l4c";
-			regulator-min-microvolt = <1200000>;
-			regulator-max-microvolt = <1200000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			/*
-			 * FIXME: This should have regulator-allow-set-load but
-			 * we're getting an over-current fault from the PMIC
-			 * when switching to LPM.
-			 */
-		};
-
-		vreg_l5c: ldo5 {
-			regulator-name = "vreg_l5c";
-			regulator-min-microvolt = <1100000>;
-			regulator-max-microvolt = <1300000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l6c: ldo6 {
-			regulator-name = "vreg_l6c";
-			regulator-min-microvolt = <1620000>;
-			regulator-max-microvolt = <1980000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l7c: ldo7 {
-			regulator-name = "vreg_l7c";
-			regulator-min-microvolt = <1620000>;
-			regulator-max-microvolt = <2000000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l8c: ldo8 {
-			regulator-name = "vreg_l8c";
-			regulator-min-microvolt = <2400000>;
-			regulator-max-microvolt = <3300000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l9c: ldo9 {
-			regulator-name = "vreg_l9c";
-			regulator-min-microvolt = <1650000>;
-			regulator-max-microvolt = <2700000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-	};
-
-	regulators-2 {
-		compatible = "qcom,pmm8654au-rpmh-regulators";
-		qcom,pmic-id = "e";
-
-		vreg_s4e: smps4 {
-			regulator-name = "vreg_s4e";
-			regulator-min-microvolt = <970000>;
-			regulator-max-microvolt = <1520000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_s7e: smps7 {
-			regulator-name = "vreg_s7e";
-			regulator-min-microvolt = <1010000>;
-			regulator-max-microvolt = <1170000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_s9e: smps9 {
-			regulator-name = "vreg_s9e";
-			regulator-min-microvolt = <300000>;
-			regulator-max-microvolt = <570000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l6e: ldo6 {
-			regulator-name = "vreg_l6e";
-			regulator-min-microvolt = <1280000>;
-			regulator-max-microvolt = <1450000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-
-		vreg_l8e: ldo8 {
-			regulator-name = "vreg_l8e";
-			regulator-min-microvolt = <1800000>;
-			regulator-max-microvolt = <1950000>;
-			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
-			regulator-allow-set-load;
-			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
-						   RPMH_REGULATOR_MODE_HPM>;
-		};
-	};
+	qcom,msm-id = <533 0x10000>, <534 0x10000>, <534 0x20000>;
+	qcom,board-id = <0x10019 0>, <0x10025 1>;
 };
 
 &ethernet0 {
 	phy-mode = "sgmii";
-	phy-handle = <&sgmii_phy0>;
-
-	pinctrl-0 = <&ethernet0_default>;
-	pinctrl-names = "default";
-
-	snps,mtl-rx-config = <&mtl_rx_setup>;
-	snps,mtl-tx-config = <&mtl_tx_setup>;
-	snps,ps-speed = <1000>;
-
-	status = "okay";
-
-	mdio {
-		compatible = "snps,dwmac-mdio";
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		sgmii_phy0: phy@8 {
-			compatible = "ethernet-phy-id0141.0dd4";
-			reg = <0x8>;
-			device_type = "ethernet-phy";
-			interrupts-extended = <&tlmm 7 IRQ_TYPE_EDGE_FALLING>;
-			reset-gpios = <&pmm8654au_2_gpios 8 GPIO_ACTIVE_LOW>;
-			reset-assert-us = <11000>;
-			reset-deassert-us = <70000>;
-		};
-
-		sgmii_phy1: phy@a {
-			compatible = "ethernet-phy-id0141.0dd4";
-			reg = <0xa>;
-			device_type = "ethernet-phy";
-			interrupts-extended = <&tlmm 26 IRQ_TYPE_EDGE_FALLING>;
-			reset-gpios = <&pmm8654au_2_gpios 9 GPIO_ACTIVE_LOW>;
-			reset-assert-us = <11000>;
-			reset-deassert-us = <70000>;
-		};
-	};
-
-	mtl_rx_setup: rx-queues-config {
-		snps,rx-queues-to-use = <4>;
-		snps,rx-sched-sp;
-
-		queue0 {
-			snps,dcb-algorithm;
-			snps,map-to-dma-channel = <0x0>;
-			snps,route-up;
-			snps,priority = <0x1>;
-		};
-
-		queue1 {
-			snps,dcb-algorithm;
-			snps,map-to-dma-channel = <0x1>;
-			snps,route-ptp;
-		};
-
-		queue2 {
-			snps,avb-algorithm;
-			snps,map-to-dma-channel = <0x2>;
-			snps,route-avcp;
-		};
-
-		queue3 {
-			snps,avb-algorithm;
-			snps,map-to-dma-channel = <0x3>;
-			snps,priority = <0xc>;
-		};
-	};
-
-	mtl_tx_setup: tx-queues-config {
-		snps,tx-queues-to-use = <4>;
-		snps,tx-sched-sp;
-
-		queue0 {
-			snps,dcb-algorithm;
-		};
-
-		queue1 {
-			snps,dcb-algorithm;
-		};
-
-		queue2 {
-			snps,avb-algorithm;
-			snps,send_slope = <0x1000>;
-			snps,idle_slope = <0x1000>;
-			snps,high_credit = <0x3e800>;
-			snps,low_credit = <0xffc18000>;
-		};
-
-		queue3 {
-			snps,avb-algorithm;
-			snps,send_slope = <0x1000>;
-			snps,idle_slope = <0x1000>;
-			snps,high_credit = <0x3e800>;
-			snps,low_credit = <0xffc18000>;
-		};
-	};
 };
 
 &ethernet1 {
 	phy-mode = "sgmii";
-	phy-handle = <&sgmii_phy1>;
-
-	snps,mtl-rx-config = <&mtl_rx_setup1>;
-	snps,mtl-tx-config = <&mtl_tx_setup1>;
-	snps,ps-speed = <1000>;
-
-	status = "okay";
-
-	mtl_rx_setup1: rx-queues-config {
-		snps,rx-queues-to-use = <4>;
-		snps,rx-sched-sp;
-
-		queue0 {
-			snps,dcb-algorithm;
-			snps,map-to-dma-channel = <0x0>;
-			snps,route-up;
-			snps,priority = <0x1>;
-		};
-
-		queue1 {
-			snps,dcb-algorithm;
-			snps,map-to-dma-channel = <0x1>;
-			snps,route-ptp;
-		};
-
-		queue2 {
-			snps,avb-algorithm;
-			snps,map-to-dma-channel = <0x2>;
-			snps,route-avcp;
-		};
-
-		queue3 {
-			snps,avb-algorithm;
-			snps,map-to-dma-channel = <0x3>;
-			snps,priority = <0xc>;
-		};
-	};
-
-	mtl_tx_setup1: tx-queues-config {
-		snps,tx-queues-to-use = <4>;
-		snps,tx-sched-sp;
-
-		queue0 {
-			snps,dcb-algorithm;
-		};
-
-		queue1 {
-			snps,dcb-algorithm;
-		};
-
-		queue2 {
-			snps,avb-algorithm;
-			snps,send_slope = <0x1000>;
-			snps,idle_slope = <0x1000>;
-			snps,high_credit = <0x3e800>;
-			snps,low_credit = <0xffc18000>;
-		};
-
-		queue3 {
-			snps,avb-algorithm;
-			snps,send_slope = <0x1000>;
-			snps,idle_slope = <0x1000>;
-			snps,high_credit = <0x3e800>;
-			snps,low_credit = <0xffc18000>;
-		};
-	};
-};
-
-&i2c11 {
-	clock-frequency = <400000>;
-	pinctrl-0 = <&qup_i2c11_default>;
-	pinctrl-names = "default";
-	status = "okay";
 };
 
-&i2c18 {
-	clock-frequency = <400000>;
-	pinctrl-0 = <&qup_i2c18_default>;
-	pinctrl-names = "default";
-	status = "okay";
-};
-
-&pmm8654au_0_gpios {
-	gpio-line-names = "DS_EN",
-			  "POFF_COMPLETE",
-			  "UFS0_VER_ID",
-			  "FAST_POFF",
-			  "DBU1_PON_DONE",
-			  "AOSS_SLEEP",
-			  "CAM_DES0_EN",
-			  "CAM_DES1_EN",
-			  "CAM_DES2_EN",
-			  "CAM_DES3_EN",
-			  "UEFI",
-			  "ANALOG_PON_OPT";
-};
-
-&pmm8654au_0_pon_resin {
-	linux,code = <KEY_VOLUMEDOWN>;
-	status = "okay";
-};
-
-&pmm8654au_1_gpios {
-	gpio-line-names = "PMIC_C_ID0",
-			  "PMIC_C_ID1",
-			  "UFS1_VER_ID",
-			  "IPA_PWR",
-			  "",
-			  "WLAN_DBU4_EN",
-			  "WLAN_EN",
-			  "BT_EN",
-			  "USB2_PWR_EN",
-			  "USB2_FAULT";
-
-	usb2_en_state: usb2-en-state {
-		pins = "gpio9";
-		function = "normal";
-		output-high;
-		power-source = <0>;
-	};
-};
-
-&pmm8654au_2_gpios {
-	gpio-line-names = "PMIC_E_ID0",
-			  "PMIC_E_ID1",
-			  "USB0_PWR_EN",
-			  "USB0_FAULT",
-			  "SENSOR_IRQ_1",
-			  "SENSOR_IRQ_2",
-			  "SENSOR_RST",
-			  "SGMIIO0_RST",
-			  "SGMIIO1_RST",
-			  "USB1_PWR_ENABLE",
-			  "USB1_FAULT",
-			  "VMON_SPX8";
-
-	usb0_en_state: usb0-en-state {
-		pins = "gpio3";
-		function = "normal";
-		output-high;
-		power-source = <0>;
+&mdio {
+	compatible = "snps,dwmac-mdio";
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	sgmii_phy0: phy@8 {
+		compatible = "ethernet-phy-id0141.0dd4";
+		reg = <0x8>;
+		device_type = "ethernet-phy";
+		interrupts-extended = <&tlmm 7 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&pmm8654au_2_gpios 8 GPIO_ACTIVE_LOW>;
+		reset-assert-us = <11000>;
+		reset-deassert-us = <70000>;
+	};
+
+	sgmii_phy1: phy@a {
+		compatible = "ethernet-phy-id0141.0dd4";
+		reg = <0xa>;
+		device_type = "ethernet-phy";
+		interrupts-extended = <&tlmm 26 IRQ_TYPE_EDGE_FALLING>;
+		reset-gpios = <&pmm8654au_2_gpios 9 GPIO_ACTIVE_LOW>;
+		reset-assert-us = <11000>;
+		reset-deassert-us = <70000>;
 	};
-
-	usb1_en_state: usb1-en-state {
-		pins = "gpio10";
-		function = "normal";
-		output-high;
-		power-source = <0>;
-	};
-};
-
-&pmm8654au_3_gpios {
-	gpio-line-names = "PMIC_G_ID0",
-			  "PMIC_G_ID1",
-			  "GNSS_RST",
-			  "GNSS_EN",
-			  "GNSS_BOOT_MODE";
-};
-
-&qupv3_id_1 {
-	status = "okay";
-};
-
-&qupv3_id_2 {
-	status = "okay";
-};
-
-&serdes0 {
-	phy-supply = <&vreg_l5a>;
-	status = "okay";
-};
-
-&serdes1 {
-	phy-supply = <&vreg_l5a>;
-	status = "okay";
-};
-
-&sleep_clk {
-	clock-frequency = <32764>;
-};
-
-&spi16 {
-	pinctrl-0 = <&qup_spi16_default>;
-	pinctrl-names = "default";
-	status = "okay";
-};
-
-&tlmm {
-	ethernet0_default: ethernet0-default-state {
-		ethernet0_mdc: ethernet0-mdc-pins {
-			pins = "gpio8";
-			function = "emac0_mdc";
-			drive-strength = <16>;
-			bias-pull-up;
-		};
-
-		ethernet0_mdio: ethernet0-mdio-pins {
-			pins = "gpio9";
-			function = "emac0_mdio";
-			drive-strength = <16>;
-			bias-pull-up;
-		};
-	};
-
-	qup_uart10_default: qup-uart10-state {
-		pins = "gpio46", "gpio47";
-		function = "qup1_se3";
-	};
-
-	qup_spi16_default: qup-spi16-state {
-		pins = "gpio86", "gpio87", "gpio88", "gpio89";
-		function = "qup2_se2";
-		drive-strength = <6>;
-		bias-disable;
-	};
-
-	qup_i2c11_default: qup-i2c11-state {
-		pins = "gpio48", "gpio49";
-		function = "qup1_se4";
-		drive-strength = <2>;
-		bias-pull-up;
-	};
-
-	qup_i2c18_default: qup-i2c18-state {
-		pins = "gpio95", "gpio96";
-		function = "qup2_se4";
-		drive-strength = <2>;
-		bias-pull-up;
-	};
-
-	qup_uart12_default: qup-uart12-state {
-		qup_uart12_cts: qup-uart12-cts-pins {
-			pins = "gpio52";
-			function = "qup1_se5";
-			bias-disable;
-		};
-
-		qup_uart12_rts: qup-uart12-rts-pins {
-			pins = "gpio53";
-			function = "qup1_se5";
-			bias-pull-down;
-		};
-
-		qup_uart12_tx: qup-uart12-tx-pins {
-			pins = "gpio54";
-			function = "qup1_se5";
-			bias-pull-up;
-		};
-
-		qup_uart12_rx: qup-uart12-rx-pins {
-			pins = "gpio55";
-			function = "qup1_se5";
-			bias-pull-down;
-		};
-	};
-
-	qup_uart17_default: qup-uart17-state {
-		qup_uart17_cts: qup-uart17-cts-pins {
-			pins = "gpio91";
-			function = "qup2_se3";
-			bias-disable;
-		};
-
-		qup_uart17_rts: qup0-uart17-rts-pins {
-			pins = "gpio92";
-			function = "qup2_se3";
-			bias-pull-down;
-		};
-
-		qup_uart17_tx: qup0-uart17-tx-pins {
-			pins = "gpio93";
-			function = "qup2_se3";
-			bias-pull-up;
-		};
-
-		qup_uart17_rx: qup0-uart17-rx-pins {
-			pins = "gpio94";
-			function = "qup2_se3";
-			bias-pull-down;
-		};
-	};
-
-	pcie0_default_state: pcie0-default-state {
-		perst-pins {
-			pins = "gpio2";
-			function = "gpio";
-			drive-strength = <2>;
-			bias-pull-down;
-		};
-
-		clkreq-pins {
-			pins = "gpio1";
-			function = "pcie0_clkreq";
-			drive-strength = <2>;
-			bias-pull-up;
-		};
-
-		wake-pins {
-			pins = "gpio0";
-			function = "gpio";
-			drive-strength = <2>;
-			bias-pull-up;
-		};
-	};
-
-	pcie1_default_state: pcie1-default-state {
-		perst-pins {
-			pins = "gpio4";
-			function = "gpio";
-			drive-strength = <2>;
-			bias-pull-down;
-		};
-
-		clkreq-pins {
-			pins = "gpio3";
-			function = "pcie1_clkreq";
-			drive-strength = <2>;
-			bias-pull-up;
-		};
-
-		wake-pins {
-			pins = "gpio5";
-			function = "gpio";
-			drive-strength = <2>;
-			bias-pull-up;
-		};
-	};
-};
-
-&pcie0 {
-	perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
-	wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
-
-	pinctrl-names = "default";
-	pinctrl-0 = <&pcie0_default_state>;
-
-	status = "okay";
-};
-
-&pcie1 {
-	perst-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>;
-	wake-gpios = <&tlmm 5 GPIO_ACTIVE_HIGH>;
-
-	pinctrl-names = "default";
-	pinctrl-0 = <&pcie1_default_state>;
-
-	status = "okay";
-};
-
-&pcie0_phy {
-	vdda-phy-supply = <&vreg_l5a>;
-	vdda-pll-supply = <&vreg_l1c>;
-
-	status = "okay";
-};
-
-&pcie1_phy {
-	vdda-phy-supply = <&vreg_l5a>;
-	vdda-pll-supply = <&vreg_l1c>;
-
-	status = "okay";
-};
-
-&uart10 {
-	compatible = "qcom,geni-debug-uart";
-	pinctrl-0 = <&qup_uart10_default>;
-	pinctrl-names = "default";
-	status = "okay";
-};
-
-&uart12 {
-	pinctrl-0 = <&qup_uart12_default>;
-	pinctrl-names = "default";
-	status = "okay";
-};
-
-&uart17 {
-	pinctrl-0 = <&qup_uart17_default>;
-	pinctrl-names = "default";
-	status = "okay";
-};
-
-&ufs_mem_hc {
-	reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>;
-	vcc-supply = <&vreg_l8a>;
-	vcc-max-microamp = <1100000>;
-	vccq-supply = <&vreg_l4c>;
-	vccq-max-microamp = <1200000>;
-
-	status = "okay";
-};
-
-&ufs_mem_phy {
-	vdda-phy-supply = <&vreg_l4a>;
-	vdda-pll-supply = <&vreg_l1c>;
-
-	status = "okay";
-};
-
-&usb_0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&usb0_en_state>;
-
-	status = "okay";
-};
-
-&usb_0_dwc3 {
-	dr_mode = "peripheral";
-};
-
-&usb_0_hsphy {
-	vdda-pll-supply = <&vreg_l7a>;
-	vdda18-supply = <&vreg_l6c>;
-	vdda33-supply = <&vreg_l9a>;
-
-	status = "okay";
-};
-
-&usb_0_qmpphy {
-	vdda-phy-supply = <&vreg_l1c>;
-	vdda-pll-supply = <&vreg_l7a>;
-
-	status = "okay";
-};
-
-&usb_1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&usb1_en_state>;
-
-	status = "okay";
-};
-
-&usb_1_dwc3 {
-	dr_mode = "host";
-};
-
-&usb_1_hsphy {
-	vdda-pll-supply = <&vreg_l7a>;
-	vdda18-supply = <&vreg_l6c>;
-	vdda33-supply = <&vreg_l9a>;
-
-	status = "okay";
-};
-
-&usb_1_qmpphy {
-	vdda-phy-supply = <&vreg_l1c>;
-	vdda-pll-supply = <&vreg_l7a>;
-
-	status = "okay";
-};
-
-&usb_2 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&usb2_en_state>;
-
-	status = "okay";
-};
-
-&usb_2_dwc3 {
-	dr_mode = "host";
-};
-
-&usb_2_hsphy {
-	vdda-pll-supply = <&vreg_l7a>;
-	vdda18-supply = <&vreg_l6c>;
-	vdda33-supply = <&vreg_l9a>;
-
-	status = "okay";
-};
-
-&xo_board_clk {
-	clock-frequency = <38400000>;
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p-ride.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8775p-ride.dtsi
@@ -0,0 +1,1291 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+
+#include "sa8775p.dtsi"
+#include "sa8775p-pmics.dtsi"
+
+/ {
+	aliases {
+		ethernet0 = &ethernet0;
+		ethernet1 = &ethernet1;
+		i2c11 = &i2c11;
+		i2c18 = &i2c18;
+		serial0 = &uart10;
+		serial1 = &uart12;
+		serial2 = &uart17;
+		spi16 = &spi16;
+		ufshc1 = &ufs_mem_hc;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	vreg_conn_1p8: vreg_conn_1p8 {
+		compatible = "regulator-fixed";
+		regulator-name = "vreg_conn_1p8";
+		startup-delay-us = <4000>;
+		enable-active-high;
+		gpio = <&pmm8654au_1_gpios 4 GPIO_ACTIVE_HIGH>;
+	};
+
+	dsi_dp1 {
+		compatible = "dp-connector";
+		type = "full-size";
+
+		port {
+			dsi_dp_1_in: endpoint {
+			};
+		};
+	};
+
+	dsi_dp2 {
+		compatible = "dp-connector";
+		type = "full-size";
+
+		port {
+			dsi_dp_2_in: endpoint {
+			};
+		};
+	};
+
+	vreg_conn_pa: vreg_conn_pa {
+		compatible = "regulator-fixed";
+		regulator-name = "vreg_conn_pa";
+		startup-delay-us = <4000>;
+		enable-active-high;
+		gpio = <&pmm8654au_1_gpios 6 GPIO_ACTIVE_HIGH>;
+	};
+
+	wcn6855-pmu {
+		compatible = "qcom,wcn6855-pmu";
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&bt_en_state>, <&wlan_en_state>;
+
+		vddio-supply = <&vreg_conn_pa>;
+		vddaon-supply = <&vreg_l2c>;
+		vddpmu-supply = <&vreg_conn_1p8>;
+		vddrfa0p95-supply = <&vreg_l2c>;
+		vddrfa1p3-supply = <&vreg_l6e>;
+		vddrfa1p9-supply = <&vreg_s5a>;
+		vddpcie1p3-supply = <&vreg_l6e>;
+		vddpcie1p9-supply = <&vreg_s5a>;
+
+		bt-enable-gpios = <&pmm8654au_1_gpios 8 GPIO_ACTIVE_HIGH>;
+		wlan-enable-gpios = <&pmm8654au_1_gpios 7 GPIO_ACTIVE_HIGH>;
+
+		regulators {
+			vreg_pmu_rfa_cmn: ldo0 {
+				regulator-name = "vreg_pmu_rfa_cmn";
+			};
+
+			vreg_pmu_aon_0p59: ldo1 {
+				regulator-name = "vreg_pmu_aon_0p59";
+			};
+
+			vreg_pmu_wlcx_0p8: ldo2 {
+				regulator-name = "vreg_pmu_wlcx_0p8";
+			};
+
+			vreg_pmu_wlmx_0p85: ldo3 {
+				regulator-name = "vreg_pmu_wlmx_0p85";
+			};
+
+			vreg_pmu_btcmx_0p85: ldo4 {
+				regulator-name = "vreg_pmu_btcmx_0p85";
+			};
+
+			vreg_pmu_rfa_0p8: ldo5 {
+				regulator-name = "vreg_pmu_rfa_0p8";
+			};
+
+			vreg_pmu_rfa_1p2: ldo6 {
+				regulator-name = "vreg_pmu_rfa_1p2";
+			};
+
+			vreg_pmu_rfa_1p7: ldo7 {
+				regulator-name = "vreg_pmu_rfa_1p7";
+			};
+
+			vreg_pmu_pcie_0p9: ldo8 {
+				regulator-name = "vreg_pmu_pcie_0p9";
+			};
+
+			vreg_pmu_pcie_1p8: ldo9 {
+				regulator-name = "vreg_pmu_pcie_1p8";
+			};
+		};
+	};
+};
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "a";
+
+		vreg_s4a: smps4 {
+			regulator-name = "vreg_s4a";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1816000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s5a: smps5 {
+			regulator-name = "vreg_s5a";
+			regulator-min-microvolt = <1850000>;
+			regulator-max-microvolt = <1996000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s9a: smps9 {
+			regulator-name = "vreg_s9a";
+			regulator-min-microvolt = <535000>;
+			regulator-max-microvolt = <1120000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4a: ldo4 {
+			regulator-name = "vreg_l4a";
+			regulator-min-microvolt = <788000>;
+			regulator-max-microvolt = <1050000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5a: ldo5 {
+			regulator-name = "vreg_l5a";
+			regulator-min-microvolt = <870000>;
+			regulator-max-microvolt = <950000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6a: ldo6 {
+			regulator-name = "vreg_l6a";
+			regulator-min-microvolt = <870000>;
+			regulator-max-microvolt = <970000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7a: ldo7 {
+			regulator-name = "vreg_l7a";
+			regulator-min-microvolt = <720000>;
+			regulator-max-microvolt = <950000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8a: ldo8 {
+			regulator-name = "vreg_l8a";
+			regulator-min-microvolt = <2504000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9a: ldo9 {
+			regulator-name = "vreg_l9a";
+			regulator-min-microvolt = <2970000>;
+			regulator-max-microvolt = <3544000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "c";
+
+		vreg_l1c: ldo1 {
+			regulator-name = "vreg_l1c";
+			regulator-min-microvolt = <1140000>;
+			regulator-max-microvolt = <1260000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2c: ldo2 {
+			regulator-name = "vreg_l2c";
+			regulator-min-microvolt = <900000>;
+			regulator-max-microvolt = <1100000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3c: ldo3 {
+			regulator-name = "vreg_l3c";
+			regulator-min-microvolt = <1100000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l4c: ldo4 {
+			regulator-name = "vreg_l4c";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			/*
+			 * FIXME: This should have regulator-allow-set-load but
+			 * we're getting an over-current fault from the PMIC
+			 * when switching to LPM.
+			 */
+		};
+
+		vreg_l5c: ldo5 {
+			regulator-name = "vreg_l5c";
+			regulator-min-microvolt = <1100000>;
+			regulator-max-microvolt = <1300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6c: ldo6 {
+			regulator-name = "vreg_l6c";
+			regulator-min-microvolt = <1620000>;
+			regulator-max-microvolt = <1980000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7c: ldo7 {
+			regulator-name = "vreg_l7c";
+			regulator-min-microvolt = <1620000>;
+			regulator-max-microvolt = <2000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8c: ldo8 {
+			regulator-name = "vreg_l8c";
+			regulator-min-microvolt = <2400000>;
+			regulator-max-microvolt = <3300000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l9c: ldo9 {
+			regulator-name = "vreg_l9c";
+			regulator-min-microvolt = <1650000>;
+			regulator-max-microvolt = <2700000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-2 {
+		compatible = "qcom,pmm8654au-rpmh-regulators";
+		qcom,pmic-id = "e";
+
+		vreg_s4e: smps4 {
+			regulator-name = "vreg_s4e";
+			regulator-min-microvolt = <970000>;
+			regulator-max-microvolt = <1520000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s7e: smps7 {
+			regulator-name = "vreg_s7e";
+			regulator-min-microvolt = <1010000>;
+			regulator-max-microvolt = <1170000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s9e: smps9 {
+			regulator-name = "vreg_s9e";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <570000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6e: ldo6 {
+			regulator-name = "vreg_l6e";
+			regulator-min-microvolt = <1280000>;
+			regulator-max-microvolt = <1450000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8e: ldo8 {
+			regulator-name = "vreg_l8e";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1950000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&ethernet0 {
+	phy-handle = <&sgmii_phy0>;
+
+	pinctrl-0 = <&ethernet0_default>;
+	pinctrl-names = "default";
+
+	snps,mtl-rx-config = <&mtl_rx_setup>;
+	snps,mtl-tx-config = <&mtl_tx_setup>;
+	snps,ps-speed = <1000>;
+
+	status = "okay";
+
+	mdio: mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+	};
+
+	mtl_rx_setup: rx-queues-config {
+		snps,rx-queues-to-use = <4>;
+		snps,rx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x0>;
+			snps,route-up;
+			snps,priority = <0x1>;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x1>;
+			snps,route-ptp;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x2>;
+			snps,route-avcp;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x3>;
+			snps,priority = <0xc>;
+		};
+	};
+
+	mtl_tx_setup: tx-queues-config {
+		snps,tx-queues-to-use = <4>;
+		snps,tx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+	};
+};
+
+&ethernet1 {
+	phy-handle = <&sgmii_phy1>;
+
+	snps,mtl-rx-config = <&mtl_rx_setup1>;
+	snps,mtl-tx-config = <&mtl_tx_setup1>;
+	snps,ps-speed = <1000>;
+
+	status = "okay";
+
+	mtl_rx_setup1: rx-queues-config {
+		snps,rx-queues-to-use = <4>;
+		snps,rx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x0>;
+			snps,route-up;
+			snps,priority = <0x1>;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+			snps,map-to-dma-channel = <0x1>;
+			snps,route-ptp;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x2>;
+			snps,route-avcp;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,map-to-dma-channel = <0x3>;
+			snps,priority = <0xc>;
+		};
+	};
+
+	mtl_tx_setup1: tx-queues-config {
+		snps,tx-queues-to-use = <4>;
+		snps,tx-sched-sp;
+
+		queue0 {
+			snps,dcb-algorithm;
+		};
+
+		queue1 {
+			snps,dcb-algorithm;
+		};
+
+		queue2 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+
+		queue3 {
+			snps,avb-algorithm;
+			snps,send_slope = <0x1000>;
+			snps,idle_slope = <0x1000>;
+			snps,high_credit = <0x3e800>;
+			snps,low_credit = <0xffc18000>;
+		};
+	};
+};
+
+&eud {
+	status = "okay";
+};
+
+&gpi_dma0 {
+	status = "okay";
+};
+
+&gpi_dma1 {
+	status = "okay";
+};
+
+&gpi_dma2 {
+	status = "okay";
+};
+
+&gpi_dma3 {
+	status = "okay";
+};
+
+&i2c11 {
+	clock-frequency = <400000>;
+	status = "okay";
+};
+
+&i2c18 {
+	clock-frequency = <400000>;
+	/delete-property/ pinctrl-0;
+	pinctrl-0 = <&qup_i2c18_default
+		    &ioexp_intr_active
+		    &ioexp_reset_active>;
+	status = "okay";
+
+	ioexp: gpio@74 {
+		compatible = "ti,tca9539";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		reg = <0x74>;
+		interrupt-parent = <&tlmm>;
+		interrupts = <98 IRQ_TYPE_EDGE_BOTH>;
+		gpio-controller;
+		#gpio-cells = <2>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&dsi0_hpd_cfg_pins
+			    &dsi0_cdet_cfg_pins
+			    &dsi1_hpd_cfg_pins
+			    &dsi1_cdet_cfg_pins>;
+
+		dsi0_hpd_cfg_pins: gpio2-cfg {
+			pins = "gpio2";
+			input-enable;
+			bias-disable;
+		};
+
+		dsi0_cdet_cfg_pins: gpio3-cfg {
+			pins = "gpio3";
+			bias-pull-down;
+		};
+
+		dsi1_hpd_cfg_pins: gpio10-cfg {
+			pins = "gpio10";
+			input-enable;
+			bias-disable;
+		};
+
+		dsi1_cdet_cfg_pins: gpio11-cfg {
+			pins = "gpio11";
+			bias-pull-down;
+		};
+	};
+
+	i2c-mux@70 {
+		compatible = "nxp,pca9543";
+		#address-cells = <1>;
+
+		#size-cells = <0>;
+		reg = <0x70>;
+
+		i2c@0 {
+			reg = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			anx_7625_1: anx7625@58 {
+				compatible = "analogix,anx7625";
+				reg = <0x58>;
+				interrupt-parent = <&ioexp>;
+				interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+				enable-gpios = <&ioexp 1 0>;
+				reset-gpios = <&ioexp 0 0>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					mipi2dp_bridge_1_in: port@0 {
+						reg = <0>;
+						anx7625_1_in: endpoint {
+							remote-endpoint = <&mdss0_dsi0_out>;
+						};
+					};
+
+					mipi2dp_bridge_1_out: port@1 {
+						reg = <1>;
+						anx7625_1_out: endpoint {
+							remote-endpoint = <&dsi_dp_1_in>;
+						};
+					};
+				};
+			};
+		};
+
+		i2c@1 {
+			reg = <1>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			anx_7625_2: anx7625@58 {
+				compatible = "analogix,anx7625";
+				reg = <0x58>;
+				interrupt-parent = <&ioexp>;
+				interrupts = <10 IRQ_TYPE_EDGE_FALLING>;
+				enable-gpios = <&ioexp 9 0>;
+				reset-gpios = <&ioexp 8 0>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					mipi2dp_bridge_2_in: port@0 {
+						reg = <0>;
+						anx7625_2_in: endpoint {
+							remote-endpoint = <&mdss0_dsi1_out>;
+						};
+					};
+
+					mipi2dp_bridge_2_out: port@1 {
+						reg = <1>;
+						anx7625_2_out: endpoint {
+							remote-endpoint = <&dsi_dp_2_in>;
+						};
+					};
+				};
+			};
+		};
+	};
+};
+
+&iris {
+	firmware-name = "qcom/vpu/vpu30_p4_s6.mbn";
+
+	status = "okay";
+};
+
+&mdss0 {
+	status = "okay";
+};
+
+&mdss0_dsi0 {
+	vdda-supply = <&vreg_l1c>;
+	status = "okay";
+};
+
+&mdss0_dsi1 {
+	vdda-supply = <&vreg_l1c>;
+	status = "okay";
+};
+
+&mdss0_dsi0_phy {
+	vdds-supply = <&vreg_l4a>;
+	status = "okay";
+};
+
+&mdss0_dsi1_phy {
+	vdds-supply = <&vreg_l4a>;
+	status = "okay";
+};
+
+&mdss0_dp0 {
+	status = "okay";
+};
+
+&mdss0_dp0_out {
+	data-lanes = <0 1 2 3>;
+	link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+};
+
+&mdss0_edp_phy {
+	status = "okay";
+};
+
+&mdss0_dp1 {
+	status = "okay";
+};
+
+&mdss0_dp1_out {
+	data-lanes = <0 1 2 3>;
+	link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>;
+};
+
+&mdss0_edp1_phy {
+	status = "okay";
+};
+
+&mdss0_dsi0_out {
+	data-lanes = <0 1 2 3>;
+	remote-endpoint = <&anx7625_1_in>;
+};
+
+&mdss0_dsi1_out {
+	data-lanes = <0 1 2 3>;
+	remote-endpoint = <&anx7625_2_in>;
+};
+
+&dsi_dp_1_in {
+	remote-endpoint = <&anx7625_1_out>;
+};
+
+&dsi_dp_2_in {
+	remote-endpoints = <&anx7625_2_out>;
+};
+
+&pmm8654au_0_gpios {
+	gpio-line-names = "DS_EN",
+			  "POFF_COMPLETE",
+			  "UFS0_VER_ID",
+			  "FAST_POFF",
+			  "DBU1_PON_DONE",
+			  "AOSS_SLEEP",
+			  "CAM_DES0_EN",
+			  "CAM_DES1_EN",
+			  "CAM_DES2_EN",
+			  "CAM_DES3_EN",
+			  "UEFI",
+			  "ANALOG_PON_OPT";
+};
+
+&pmm8654au_0_pon_resin {
+	linux,code = <KEY_VOLUMEDOWN>;
+	status = "okay";
+};
+
+&pmm8654au_1_gpios {
+	gpio-line-names = "PMIC_C_ID0",
+			  "PMIC_C_ID1",
+			  "UFS1_VER_ID",
+			  "IPA_PWR",
+			  "",
+			  "WLAN_DBU4_EN",
+			  "WLAN_EN",
+			  "BT_EN",
+			  "USB2_PWR_EN",
+			  "USB2_FAULT";
+
+	wlan_en_state: wlan-en-state {
+		pins = "gpio7";
+		function = "normal";
+		output-low;
+		bias-pull-down;
+	};
+
+	bt_en_state: bt-en-state {
+		pins = "gpio8";
+		function = "normal";
+		output-low;
+		bias-pull-down;
+	};
+
+	usb2_en_state: usb2-en-state {
+		pins = "gpio9";
+		function = "normal";
+		output-high;
+		power-source = <0>;
+	};
+};
+
+&pmm8654au_2_gpios {
+	gpio-line-names = "PMIC_E_ID0",
+			  "PMIC_E_ID1",
+			  "USB0_PWR_EN",
+			  "USB0_FAULT",
+			  "SENSOR_IRQ_1",
+			  "SENSOR_IRQ_2",
+			  "SENSOR_RST",
+			  "SGMIIO0_RST",
+			  "SGMIIO1_RST",
+			  "USB1_PWR_ENABLE",
+			  "USB1_FAULT",
+			  "VMON_SPX8";
+
+	usb0_en_state: usb0-en-state {
+		pins = "gpio3";
+		function = "normal";
+		output-high;
+		power-source = <0>;
+	};
+
+	usb1_en_state: usb1-en-state {
+		pins = "gpio10";
+		function = "normal";
+		output-high;
+		power-source = <0>;
+	};
+};
+
+&pmm8654au_3_gpios {
+	gpio-line-names = "PMIC_G_ID0",
+			  "PMIC_G_ID1",
+			  "GNSS_RST",
+			  "GNSS_EN",
+			  "GNSS_BOOT_MODE";
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&qupv3_id_1 {
+	status = "okay";
+};
+
+&qupv3_id_2 {
+	status = "okay";
+};
+
+&qupv3_id_3 {
+	status = "okay";
+};
+
+&qup_spi16_default {
+	drive-strength = <6>;
+	bias-disable;
+};
+
+&qup_i2c11_default {
+	drive-strength = <2>;
+	bias-pull-up;
+};
+
+&qup_i2c18_default {
+	drive-strength = <2>;
+	bias-pull-up;
+};
+
+&qup_uart12_cts {
+	bias-disable;
+};
+
+&qup_uart12_rts {
+	bias-pull-down;
+};
+
+&qup_uart12_tx {
+	bias-pull-up;
+};
+
+&qup_uart12_rx {
+	bias-pull-down;
+};
+
+&qup_uart17_cts {
+	bias-disable;
+};
+
+&qup_uart17_rts {
+	bias-pull-down;
+};
+
+&qup_uart17_tx {
+	bias-pull-up;
+};
+
+&qup_uart17_rx {
+	bias-pull-down;
+};
+
+&serdes0 {
+	phy-supply = <&vreg_l5a>;
+	status = "okay";
+};
+
+&serdes1 {
+	phy-supply = <&vreg_l5a>;
+	status = "okay";
+};
+
+&sleep_clk {
+	clock-frequency = <32000>;
+};
+
+&spi16 {
+	status = "okay";
+	spidev@0 {
+		compatible = "rohm,dh2228fv";
+		reg = <0>;
+		spi-max-frequency = <10000000>;
+		spi-cpha;
+	};
+};
+
+&tlmm {
+	dp_hot_plug_det: dp-hot-plug-det-state {
+		pins = "gpio101";
+		function = "edp0_hot";
+	};
+
+	dp1_hot_plug_det: dp1-hot-plug-det-state {
+		pins = "gpio102";
+		function = "edp1_hot";
+		bias-disable;
+	};
+
+	dp1_hot_plug_det: dp1-hot-plug-det-state {
+		pins = "gpio102";
+		function = "edp1_hot";
+		bias-disable;
+	};
+
+	ioexp_intr_active: ioexp_intr_active {
+		pins = "gpio98";
+		function = "gpio";
+		drive-strength = <2>;
+		input-enable;
+		bias-disable;
+	};
+
+	ioexp_reset_active: ioexp_reset_active {
+		pins = "gpio97";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-disable;
+		output-high;
+	};
+
+	ethernet0_default: ethernet0-default-state {
+		ethernet0_mdc: ethernet0-mdc-pins {
+			pins = "gpio8";
+			function = "emac0_mdc";
+			drive-strength = <16>;
+			bias-pull-up;
+		};
+
+		ethernet0_mdio: ethernet0-mdio-pins {
+			pins = "gpio9";
+			function = "emac0_mdio";
+			drive-strength = <16>;
+			bias-pull-up;
+		};
+	};
+
+	pcie0_default_state: pcie0-default-state {
+		perst-pins {
+			pins = "gpio2";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+
+		clkreq-pins {
+			pins = "gpio1";
+			function = "pcie0_clkreq";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		wake-pins {
+			pins = "gpio0";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+	};
+
+	pcie1_default_state: pcie1-default-state {
+		perst-pins {
+			pins = "gpio4";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-down;
+		};
+
+		clkreq-pins {
+			pins = "gpio3";
+			function = "pcie1_clkreq";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+
+		wake-pins {
+			pins = "gpio5";
+			function = "gpio";
+			drive-strength = <2>;
+			bias-pull-up;
+		};
+	};
+};
+
+&pcie0 {
+	perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie0_default_state>;
+
+	iommu-map = <0x0 &pcie_smmu 0x0000 0x1>,
+		    <0x100 &pcie_smmu 0x0001 0x1>,
+		    <0x101 &pcie_smmu 0x0002 0x1>,
+		    <0x208 &pcie_smmu 0x0003 0x1>,
+		    <0x210 &pcie_smmu 0x0004 0x1>,
+		    <0x218 &pcie_smmu 0x0005 0x1>,
+		    <0x280 &pcie_smmu 0x0006 0x1>,
+		    <0x281 &pcie_smmu 0x0007 0x1>,
+		    <0x282 &pcie_smmu 0x0008 0x1>,
+		    <0x283 &pcie_smmu 0x0009 0x1>,
+		    <0x284 &pcie_smmu 0x000a 0x1>,
+		    <0x285 &pcie_smmu 0x000b 0x1>,
+		    <0x286 &pcie_smmu 0x000c 0x1>,
+		    <0x287 &pcie_smmu 0x000d 0x1>,
+		    <0x288 &pcie_smmu 0x000e 0x1>,
+		    <0x289 &pcie_smmu 0x000f 0x1>,
+		    <0x28a &pcie_smmu 0x0010 0x1>,
+		    <0x28b &pcie_smmu 0x0011 0x1>,
+		    <0x28c &pcie_smmu 0x0012 0x1>,
+		    <0x28d &pcie_smmu 0x0013 0x1>,
+		    <0x28e &pcie_smmu 0x0014 0x1>,
+		    <0x28f &pcie_smmu 0x0015 0x1>,
+		    <0x290 &pcie_smmu 0x0016 0x1>,
+		    <0x291 &pcie_smmu 0x0017 0x1>,
+		    <0x292 &pcie_smmu 0x0018 0x1>,
+		    <0x293 &pcie_smmu 0x0019 0x1>,
+		    <0x300 &pcie_smmu 0x001a 0x1>,
+		    <0x400 &pcie_smmu 0x001b 0x1>,
+		    <0x500 &pcie_smmu 0x001c 0x1>,
+		    <0x501 &pcie_smmu 0x001d 0x1>;
+
+	status = "okay";
+};
+
+&pcie1 {
+	perst-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 5 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&pcie1_default_state>;
+
+	iommu-map = <0x0 &pcie_smmu 0x0080 0x1>,
+		    <0x100 &pcie_smmu 0x0081 0x1>,
+		    <0x101 &pcie_smmu 0x0082 0x1>,
+		    <0x208 &pcie_smmu 0x0083 0x1>,
+		    <0x210 &pcie_smmu 0x0084 0x1>,
+		    <0x218 &pcie_smmu 0x0085 0x1>,
+		    <0x280 &pcie_smmu 0x0086 0x1>,
+		    <0x281 &pcie_smmu 0x0087 0x1>,
+		    <0x282 &pcie_smmu 0x0088 0x1>,
+		    <0x283 &pcie_smmu 0x0089 0x1>,
+		    <0x284 &pcie_smmu 0x008a 0x1>,
+		    <0x285 &pcie_smmu 0x008b 0x1>,
+		    <0x286 &pcie_smmu 0x008c 0x1>,
+		    <0x287 &pcie_smmu 0x008d 0x1>,
+		    <0x288 &pcie_smmu 0x008e 0x1>,
+		    <0x289 &pcie_smmu 0x008f 0x1>,
+		    <0x28a &pcie_smmu 0x0090 0x1>,
+		    <0x28b &pcie_smmu 0x0091 0x1>,
+		    <0x28c &pcie_smmu 0x0092 0x1>,
+		    <0x28d &pcie_smmu 0x0093 0x1>,
+		    <0x28e &pcie_smmu 0x0094 0x1>,
+		    <0x28f &pcie_smmu 0x0095 0x1>,
+		    <0x290 &pcie_smmu 0x0096 0x1>,
+		    <0x291 &pcie_smmu 0x0097 0x1>,
+		    <0x292 &pcie_smmu 0x0098 0x1>,
+		    <0x29d &pcie_smmu 0x0099 0x1>,
+		    <0x300 &pcie_smmu 0x009a 0x1>,
+		    <0x400 &pcie_smmu 0x009b 0x1>,
+		    <0x500 &pcie_smmu 0x009c 0x1>,
+		    <0x501 &pcie_smmu 0x009d 0x1>;
+
+	status = "okay";
+};
+
+&pcie0_phy {
+	vdda-phy-supply = <&vreg_l5a>;
+	vdda-pll-supply = <&vreg_l1c>;
+
+	status = "okay";
+};
+
+&pcie1_phy {
+	vdda-phy-supply = <&vreg_l5a>;
+	vdda-pll-supply = <&vreg_l1c>;
+
+	status = "okay";
+};
+
+&pcieport0 {
+	wifi@0 {
+		compatible = "pci17cb,1101";
+		reg = <0x10000 0x0 0x0 0x0 0x0>;
+
+		qcom,ath11k-calibration-variant = "QC_SA8775P_Ride";
+
+		vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+		vddaon-supply = <&vreg_pmu_aon_0p59>;
+		vddwlcx-supply = <&vreg_pmu_wlcx_0p8>;
+		vddwlmx-supply = <&vreg_pmu_wlmx_0p85>;
+		vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+		vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+		vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>;
+		vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>;
+		vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>;
+	};
+};
+
+&remoteproc_adsp {
+	firmware-name = "qcom/sa8775p/adsp.mbn";
+	status = "okay";
+};
+
+&remoteproc_cdsp0 {
+	firmware-name = "qcom/sa8775p/cdsp0.mbn";
+	status = "okay";
+};
+
+&remoteproc_cdsp1 {
+	firmware-name = "qcom/sa8775p/cdsp1.mbn";
+	status = "okay";
+};
+
+&remoteproc_gpdsp0 {
+	firmware-name = "qcom/sa8775p/gpdsp0.mbn";
+	status = "okay";
+};
+
+&remoteproc_gpdsp1 {
+	firmware-name = "qcom/sa8775p/gpdsp1.mbn";
+	status = "okay";
+};
+
+&gpi_dma0 {
+	status = "okay";
+};
+
+&gpi_dma1 {
+	status = "okay";
+};
+
+&gpi_dma2 {
+	status = "okay";
+};
+
+&gpi_dma3 {
+	status = "okay";
+};
+
+&uart10 {
+	compatible = "qcom,geni-debug-uart";
+	pinctrl-0 = <&qup_uart10_default>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&uart12 {
+	pinctrl-0 = <&qup_uart12_default>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&uart17 {
+	pinctrl-0 = <&qup_uart17_default>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	bluetooth {
+		compatible = "qcom,wcn6855-bt";
+		firmware-name = "QCA6698/hpnv21", "QCA6698/hpbtfw21.tlv";
+
+		vddrfacmn-supply = <&vreg_pmu_rfa_cmn>;
+		vddaon-supply = <&vreg_pmu_aon_0p59>;
+		vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>;
+		vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>;
+		vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>;
+		vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>;
+	};
+};
+
+&ufs_mem_hc {
+	reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>;
+	vcc-supply = <&vreg_l8a>;
+	vcc-max-microamp = <1100000>;
+	vccq-supply = <&vreg_l4c>;
+	vccq-max-microamp = <1200000>;
+
+	status = "okay";
+};
+
+&ufs_mem_phy {
+	vdda-phy-supply = <&vreg_l4a>;
+	vdda-pll-supply = <&vreg_l1c>;
+
+	status = "okay";
+};
+
+&usb_0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb0_en_state>;
+
+	status = "okay";
+};
+
+&usb_0_dwc3 {
+	snps,dis-u2-entry-quirk;
+	snps,dis-u1-entry-quirk;
+	snps,dis_u2_susphy_quirk;
+	snps,dis_u3_susphy_quirk;
+
+	dr_mode = "peripheral";
+};
+
+&usb_0_hsphy {
+	vdda-pll-supply = <&vreg_l7a>;
+	vdda18-supply = <&vreg_l6c>;
+	vdda33-supply = <&vreg_l9a>;
+
+	status = "okay";
+};
+
+&usb_0_qmpphy {
+	vdda-phy-supply = <&vreg_l1c>;
+	vdda-pll-supply = <&vreg_l7a>;
+
+	status = "okay";
+};
+
+&usb_1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb1_en_state>;
+
+	status = "okay";
+};
+
+&usb_1_dwc3 {
+	snps,dwc3_guctl_resbwhseps_quirk;
+	dr_mode = "host";
+};
+
+&usb_1_hsphy {
+	vdda-pll-supply = <&vreg_l7a>;
+	vdda18-supply = <&vreg_l6c>;
+	vdda33-supply = <&vreg_l9a>;
+
+	status = "okay";
+};
+
+&usb_1_qmpphy {
+	vdda-phy-supply = <&vreg_l1c>;
+	vdda-pll-supply = <&vreg_l7a>;
+
+	status = "okay";
+};
+
+&usb_2 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&usb2_en_state>;
+
+	status = "okay";
+};
+
+&usb_2_dwc3 {
+	snps,dwc3_guctl_resbwhseps_quirk;
+	dr_mode = "host";
+};
+
+&usb_2_hsphy {
+	vdda-pll-supply = <&vreg_l7a>;
+	vdda18-supply = <&vreg_l6c>;
+	vdda33-supply = <&vreg_l9a>;
+
+	status = "okay";
+};
+
+&xo_board_clk {
+	clock-frequency = <38400000>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p-video.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8775p-video.dtsi
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+&soc {
+	iris: video-codec@aa00000 {
+		compatible = "qcom,sa8775p-iris";
+
+		reg = <0 0x0aa00000 0 0xf0000>;
+		interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+
+		power-domains = <&videocc VIDEO_CC_MVS0C_GDSC>,
+			<&videocc VIDEO_CC_MVS0_GDSC>,
+			<&rpmhpd SA8775P_MX>,
+			<&rpmhpd SA8775P_MMCX>;
+
+		power-domain-names = "iris-ctl", "vcodec", "mx", "mmcx";
+		operating-points-v2 = <&iris_opp_table>;
+
+		clocks = <&gcc GCC_VIDEO_AXI0_CLK>,
+				<&videocc VIDEO_CC_MVS0C_CLK>,
+				<&videocc VIDEO_CC_MVS0_CLK>;
+		clock-names = "gcc_video_axi0", "core_clk", "vcodec_clk";
+
+		interconnects =
+			<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+				&config_noc SLAVE_VENUS_CFG QCOM_ICC_TAG_ALWAYS>,
+			<&mmss_noc MASTER_VIDEO_P0 QCOM_ICC_TAG_ALWAYS
+				&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+		interconnect-names = "iris-cnoc", "iris-ddr";
+
+		/* FW load region */
+		memory-region = <&pil_video_mem>;
+
+		resets = <&gcc GCC_VIDEO_AXI0_CLK_ARES>;
+		reset-names = "video_axi_reset";
+
+		status = "okay";
+
+		/* MMUs */
+		video_resv_region: video_resv_region {
+			iommu-addresses = <&non_secure_cb 0x0 0x0 0x0 0x25800000>,
+					<&non_secure_cb 0x0 0xe0000000 0x0 0x20000000>,
+					<&non_secure_pixel_cb 0x0 0x0 0x0 0x00100000>,
+					<&non_secure_pixel_cb 0x0 0xe0000000 0x0 0x20000000>;
+		};
+
+		non_secure_cb: non_secure_cb {
+			compatible = "qcom,vidc,cb-ns";
+			iommus = <&apps_smmu 0x0880 0x0400>;
+			memory-region = <&video_resv_region>;
+		};
+
+		non_secure_pixel_cb: non_secure_pixel_cb {
+			compatible = "qcom,vidc,cb-ns-pxl";
+			iommus = <&apps_smmu 0x0887 0x0400>;
+			memory-region = <&video_resv_region>;
+		};
+
+		iris_opp_table: opp-table {
+			compatible = "operating-points-v2";
+
+			opp-366000000 {
+				opp-hz = /bits/ 64 <366000000>;
+				required-opps = <&rpmhpd_opp_svs_l1>,
+						<&rpmhpd_opp_svs_l1>;
+			};
+
+			opp-444000000 {
+				opp-hz = /bits/ 64 <444000000>;
+				required-opps = <&rpmhpd_opp_nom>,
+						<&rpmhpd_opp_nom>;
+			};
+
+			opp-533000000 {
+				opp-hz = /bits/ 64 <533000000>;
+				required-opps = <&rpmhpd_opp_turbo>,
+						<&rpmhpd_opp_turbo>;
+			};
+
+			opp-560000000 {
+				opp-hz = /bits/ 64 <560000000>;
+				required-opps = <&rpmhpd_opp_turbo_l1>,
+						<&rpmhpd_opp_turbo_l1>;
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p-video.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8775p-video.dtso
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
+#include <dt-bindings/clock/qcom,sa8775p-gcc.h>
+#include <dt-bindings/interconnect/qcom,sa8775p-rpmh.h>
+#include <dt-bindings/clock/qcom,sa8775p-dispcc.h>
+#include <dt-bindings/clock/qcom,sa8775p-videocc.h>
+#include "sa8775p-video.dtsi"
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sa8775p.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sa8775p.dtsi
@@ -1,17 +1,27 @@
 // SPDX-License-Identifier: BSD-3-Clause
 /*
  * Copyright (c) 2023, Linaro Limited
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <dt-bindings/interconnect/qcom,icc.h>
+#include <dt-bindings/interconnect/qcom,osm-l3.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/clock/qcom,sa8775p-camcc.h>
+#include <dt-bindings/clock/qcom,sa8775p-dispcc.h>
 #include <dt-bindings/clock/qcom,sa8775p-gcc.h>
 #include <dt-bindings/clock/qcom,sa8775p-gpucc.h>
+#include <dt-bindings/clock/qcom,sa8775p-videocc.h>
+#include <dt-bindings/dma/qcom-gpi.h>
 #include <dt-bindings/interconnect/qcom,sa8775p-rpmh.h>
 #include <dt-bindings/mailbox/qcom-ipcc.h>
+#include <dt-bindings/firmware/qcom,scm.h>
+#include <dt-bindings/power/qcom,rpmhpd.h>
 #include <dt-bindings/power/qcom-rpmpd.h>
 #include <dt-bindings/soc/qcom,rpmh-rsc.h>
+#include <dt-bindings/soc/qcom,gpr.h>
+#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
 
 / {
 	interrupt-parent = <&intc>;
@@ -19,6 +29,23 @@
 	#address-cells = <2>;
 	#size-cells = <2>;
 
+	audio-etm0 {
+		compatible = "qcom,coresight-remote-etm";
+		device-name = "audio_etm0";
+
+		qcom,inst-id = <5>;
+		atid = <40>;
+
+		out-ports {
+			port {
+				audio_out: endpoint {
+					remote-endpoint =
+					<&lpi_funnel_in0>;
+				};
+			};
+		};
+	};
+
 	clocks {
 		xo_board_clk: xo-board-clk {
 			compatible = "fixed-clock";
@@ -40,8 +67,17 @@
 			compatible = "qcom,kryo";
 			reg = <0x0 0x0>;
 			enable-method = "psci";
+			power-domains = <&CPU_PD0>;
+			power-domain-names = "psci";
 			qcom,freq-domain = <&cpufreq_hw 0>;
 			next-level-cache = <&L2_0>;
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			operating-points-v2 = <&cpu0_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl0 MASTER_EPSS_L3_APPS
+					&epss_l3_cl0 SLAVE_EPSS_L3_SHARED>;
 			L2_0: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
@@ -60,8 +96,17 @@
 			compatible = "qcom,kryo";
 			reg = <0x0 0x100>;
 			enable-method = "psci";
+			power-domains = <&CPU_PD1>;
+			power-domain-names = "psci";
 			qcom,freq-domain = <&cpufreq_hw 0>;
 			next-level-cache = <&L2_1>;
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			operating-points-v2 = <&cpu0_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl0 MASTER_EPSS_L3_APPS
+					&epss_l3_cl0 SLAVE_EPSS_L3_SHARED>;
 			L2_1: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
@@ -75,8 +120,17 @@
 			compatible = "qcom,kryo";
 			reg = <0x0 0x200>;
 			enable-method = "psci";
+			power-domains = <&CPU_PD2>;
+			power-domain-names = "psci";
 			qcom,freq-domain = <&cpufreq_hw 0>;
 			next-level-cache = <&L2_2>;
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			operating-points-v2 = <&cpu0_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl0 MASTER_EPSS_L3_APPS
+					&epss_l3_cl0 SLAVE_EPSS_L3_SHARED>;
 			L2_2: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
@@ -90,8 +144,17 @@
 			compatible = "qcom,kryo";
 			reg = <0x0 0x300>;
 			enable-method = "psci";
+			power-domains = <&CPU_PD3>;
+			power-domain-names = "psci";
 			qcom,freq-domain = <&cpufreq_hw 0>;
 			next-level-cache = <&L2_3>;
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			operating-points-v2 = <&cpu0_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl0 MASTER_EPSS_L3_APPS
+					&epss_l3_cl0 SLAVE_EPSS_L3_SHARED>;
 			L2_3: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
@@ -105,8 +168,17 @@
 			compatible = "qcom,kryo";
 			reg = <0x0 0x10000>;
 			enable-method = "psci";
+			power-domains = <&CPU_PD4>;
+			power-domain-names = "psci";
 			qcom,freq-domain = <&cpufreq_hw 1>;
 			next-level-cache = <&L2_4>;
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			operating-points-v2 = <&cpu4_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl1 MASTER_EPSS_L3_APPS
+					&epss_l3_cl1 SLAVE_EPSS_L3_SHARED>;
 			L2_4: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
@@ -126,8 +198,17 @@
 			compatible = "qcom,kryo";
 			reg = <0x0 0x10100>;
 			enable-method = "psci";
+			power-domains = <&CPU_PD5>;
+			power-domain-names = "psci";
 			qcom,freq-domain = <&cpufreq_hw 1>;
 			next-level-cache = <&L2_5>;
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			operating-points-v2 = <&cpu4_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl1 MASTER_EPSS_L3_APPS
+					&epss_l3_cl1 SLAVE_EPSS_L3_SHARED>;
 			L2_5: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
@@ -141,8 +222,17 @@
 			compatible = "qcom,kryo";
 			reg = <0x0 0x10200>;
 			enable-method = "psci";
+			power-domains = <&CPU_PD6>;
+			power-domain-names = "psci";
 			qcom,freq-domain = <&cpufreq_hw 1>;
 			next-level-cache = <&L2_6>;
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			operating-points-v2 = <&cpu4_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl1 MASTER_EPSS_L3_APPS
+					&epss_l3_cl1 SLAVE_EPSS_L3_SHARED>;
 			L2_6: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
@@ -156,8 +246,17 @@
 			compatible = "qcom,kryo";
 			reg = <0x0 0x10300>;
 			enable-method = "psci";
+			power-domains = <&CPU_PD7>;
+			power-domain-names = "psci";
 			qcom,freq-domain = <&cpufreq_hw 1>;
 			next-level-cache = <&L2_7>;
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
+			operating-points-v2 = <&cpu4_opp_table>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					&mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&epss_l3_cl1 MASTER_EPSS_L3_APPS
+					&epss_l3_cl1 SLAVE_EPSS_L3_SHARED>;
 			L2_7: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
@@ -203,58 +302,243 @@
 				};
 			};
 		};
-	};
 
-	firmware {
-		scm {
-			compatible = "qcom,scm-sa8775p", "qcom,scm";
+		idle-states {
+			entry-method = "psci";
+
+			GOLD_CPU_SLEEP_0: cpu-sleep-0 {
+				compatible = "arm,idle-state";
+				idle-state-name = "gold-power-collapse";
+				arm,psci-suspend-param = <0x40000003>;
+				entry-latency-us = <549>;
+				exit-latency-us = <901>;
+				min-residency-us = <1774>;
+				local-timer-stop;
+			};
+
+			GOLD_RAIL_CPU_SLEEP_0: cpu-sleep-1 {
+				compatible = "arm,idle-state";
+				idle-state-name = "gold-rail-power-collapse";
+				arm,psci-suspend-param = <0x40000004>;
+				entry-latency-us = <702>;
+				exit-latency-us = <1061>;
+				min-residency-us = <4488>;
+				local-timer-stop;
+			};
 		};
-	};
 
-	aggre1_noc: interconnect-aggre1-noc {
-		compatible = "qcom,sa8775p-aggre1-noc";
-		#interconnect-cells = <2>;
-		qcom,bcm-voters = <&apps_bcm_voter>;
+		domain-idle-states {
+			CLUSTER_SLEEP_GOLD: cluster-sleep-0 {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x41000044>;
+				entry-latency-us = <2752>;
+				exit-latency-us = <3048>;
+				min-residency-us = <6118>;
+			};
+
+			CLUSTER_SLEEP_APSS_RSC_PC: cluster-sleep-1 {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x42000144>;
+				entry-latency-us = <3263>;
+				exit-latency-us = <6562>;
+				min-residency-us = <9987>;
+			};
+		};
 	};
 
-	aggre2_noc: interconnect-aggre2-noc {
-		compatible = "qcom,sa8775p-aggre2-noc";
-		#interconnect-cells = <2>;
-		qcom,bcm-voters = <&apps_bcm_voter>;
-	};
+	cpu0_opp_table: opp-table-cpu0 {
+		compatible = "operating-points-v2";
+		opp-shared;
 
-	clk_virt: interconnect-clk-virt {
-		compatible = "qcom,sa8775p-clk-virt";
-		#interconnect-cells = <2>;
-		qcom,bcm-voters = <&apps_bcm_voter>;
-	};
+		cpu0_opp_1267mhz: opp-1267200000 {
+			opp-hz = /bits/ 64 <1267200000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
 
-	config_noc: interconnect-config-noc {
-		compatible = "qcom,sa8775p-config-noc";
-		#interconnect-cells = <2>;
-		qcom,bcm-voters = <&apps_bcm_voter>;
+		cpu0_opp_1363mhz: opp-1363200000 {
+			opp-hz = /bits/ 64 <1363200000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu0_opp_1459mhz: opp-1459200000 {
+			opp-hz = /bits/ 64 <1459200000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu0_opp_1536mhz: opp-1536000000 {
+			opp-hz = /bits/ 64 <1536000000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu0_opp_1632mhz: opp-1632000000 {
+			opp-hz = /bits/ 64 <1632000000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu0_opp_1708mhz: opp-1708800000 {
+			opp-hz = /bits/ 64 <1708800000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu0_opp_1785mhz: opp-1785600000 {
+			opp-hz = /bits/ 64 <1785600000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu0_opp_1862mhz: opp-1862400000 {
+			opp-hz = /bits/ 64 <1862400000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu0_opp_1939mhz: opp-1939200000 {
+			opp-hz = /bits/ 64 <1939200000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu0_opp_2016mhz: opp-2016000000 {
+			opp-hz = /bits/ 64 <2016000000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu0_opp_2112mhz: opp-2112000000 {
+			opp-hz = /bits/ 64 <2112000000>;
+			opp-peak-kBps = <8371200 49766400>;
+		};
+
+		cpu0_opp_2188mhz: opp-2188800000 {
+			opp-hz = /bits/ 64 <2188800000>;
+			opp-peak-kBps = <8371200 49766400>;
+		};
+
+		cpu0_opp_2265mhz: opp-2265600000 {
+			opp-hz = /bits/ 64 <2265600000>;
+			opp-peak-kBps = <8371200 49766400>;
+		};
+
+		cpu0_opp_2361mhz: opp-2361600000 {
+			opp-hz = /bits/ 64 <2361600000>;
+			opp-peak-kBps = <12787200 51609600>;
+		};
+
+		cpu0_opp_2457mhz: opp-2457600000 {
+			opp-hz = /bits/ 64 <2457600000>;
+			opp-peak-kBps = <12787200 51609600>;
+		};
+
+		cpu0_opp_2553mhz: opp-2553600000 {
+			opp-hz = /bits/ 64 <2553600000>;
+			opp-peak-kBps = <12787200 54681600>;
+		};
 	};
 
-	dc_noc: interconnect-dc-noc {
-		compatible = "qcom,sa8775p-dc-noc";
-		#interconnect-cells = <2>;
-		qcom,bcm-voters = <&apps_bcm_voter>;
+	cpu4_opp_table: opp-table-cpu4 {
+		compatible = "operating-points-v2";
+		opp-shared;
+
+		cpu4_opp_1267mhz: opp-1267200000 {
+			opp-hz = /bits/ 64 <1267200000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu4_opp_1363mhz: opp-1363200000 {
+			opp-hz = /bits/ 64 <1363200000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu4_opp_1459mhz: opp-1459200000 {
+			opp-hz = /bits/ 64 <1459200000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu4_opp_1536mhz: opp-1536000000 {
+			opp-hz = /bits/ 64 <1536000000>;
+			opp-peak-kBps = <6220800 29491200>;
+		};
+
+		cpu4_opp_1632mhz: opp-1632000000 {
+			opp-hz = /bits/ 64 <1632000000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu4_opp_1708mhz: opp-1708800000 {
+			opp-hz = /bits/ 64 <1708800000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu4_opp_1785mhz: opp-1785600000 {
+			opp-hz = /bits/ 64 <1785600000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu4_opp_1862mhz: opp-1862400000 {
+			opp-hz = /bits/ 64 <1862400000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu4_opp_1939mhz: opp-1939200000 {
+			opp-hz = /bits/ 64 <1939200000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu4_opp_2016mhz: opp-2016000000 {
+			opp-hz = /bits/ 64 <2016000000>;
+			opp-peak-kBps = <6835200 39321600>;
+		};
+
+		cpu4_opp_2112mhz: opp-2112000000 {
+			opp-hz = /bits/ 64 <2112000000>;
+			opp-peak-kBps = <8371200 49766400>;
+		};
+
+		cpu4_opp_2188mhz: opp-2188800000 {
+			opp-hz = /bits/ 64 <2188800000>;
+			opp-peak-kBps = <8371200 49766400>;
+		};
+
+		cpu4_opp_2265mhz: opp-2265600000 {
+			opp-hz = /bits/ 64 <2265600000>;
+			opp-peak-kBps = <8371200 49766400>;
+		};
+
+		cpu4_opp_2361mhz: opp-2361600000 {
+			opp-hz = /bits/ 64 <2361600000>;
+			opp-peak-kBps = <12787200 51609600>;
+		};
+
+		cpu4_opp_2457mhz: opp-2457600000 {
+			opp-hz = /bits/ 64 <2457600000>;
+			opp-peak-kBps = <12787200 51609600>;
+		};
+
+		cpu4_opp_2553mhz: opp-2553600000 {
+			opp-hz = /bits/ 64 <2553600000>;
+			opp-peak-kBps = <12787200 54681600>;
+		};
 	};
 
-	gem_noc: interconnect-gem-noc {
-		compatible = "qcom,sa8775p-gem-noc";
-		#interconnect-cells = <2>;
-		qcom,bcm-voters = <&apps_bcm_voter>;
+	dummy-sink {
+		compatible = "arm,coresight-dummy-sink";
+
+		in-ports {
+			port {
+				eud_in: endpoint {
+					remote-endpoint =
+					<&swao_rep_out1>;
+				};
+			};
+		};
 	};
 
-	gpdsp_anoc: interconnect-gpdsp-anoc {
-		compatible = "qcom,sa8775p-gpdsp-anoc";
-		#interconnect-cells = <2>;
-		qcom,bcm-voters = <&apps_bcm_voter>;
+	firmware {
+		scm {
+			compatible = "qcom,scm-sa8775p", "qcom,scm";
+			qcom,dload-mode = <&tcsr 0x13000>;
+			memory-region = <&tz_ffi_mem>;
+		};
 	};
 
-	lpass_ag_noc: interconnect-lpass-ag-noc {
-		compatible = "qcom,sa8775p-lpass-ag-noc";
+	clk_virt: interconnect-clk-virt {
+		compatible = "qcom,sa8775p-clk-virt";
 		#interconnect-cells = <2>;
 		qcom,bcm-voters = <&apps_bcm_voter>;
 	};
@@ -265,34 +549,108 @@
 		qcom,bcm-voters = <&apps_bcm_voter>;
 	};
 
-	mmss_noc: interconnect-mmss-noc {
-		compatible = "qcom,sa8775p-mmss-noc";
-		#interconnect-cells = <2>;
-		qcom,bcm-voters = <&apps_bcm_voter>;
-	};
+	lpass-funnel {
+		compatible = "arm,coresight-static-funnel";
 
-	nspa_noc: interconnect-nspa-noc {
-		compatible = "qcom,sa8775p-nspa-noc";
-		#interconnect-cells = <2>;
-		qcom,bcm-voters = <&apps_bcm_voter>;
+		out-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				lpass_funnel_out0: endpoint {
+					remote-endpoint =
+					<&dlct0_tpda_in0>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				lpass_funnel_out1: endpoint {
+					remote-endpoint =
+					<&dlct0_funnel_in1>;
+				};
+			};
+		};
+
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				lpass_funnel_in0: endpoint {
+					remote-endpoint =
+					<&lpass_tpdm_out>;
+				};
+			};
+		};
 	};
 
-	nspb_noc: interconnect-nspb-noc {
-		compatible = "qcom,sa8775p-nspb-noc";
-		#interconnect-cells = <2>;
-		qcom,bcm-voters = <&apps_bcm_voter>;
+	lpass-stm {
+		compatible = "arm,coresight-dummy-source";
+		device-name = "stm_lpass";
+
+		arm,trace-id = <25>;
+
+		out-ports {
+			port {
+				lpass_stm_out: endpoint {
+					remote-endpoint =
+					<&lpi_funnel_in1>;
+				};
+			};
+		};
 	};
 
-	pcie_anoc: interconnect-pcie-anoc {
-		compatible = "qcom,sa8775p-pcie-anoc";
-		#interconnect-cells = <2>;
-		qcom,bcm-voters = <&apps_bcm_voter>;
+	lpi-funnel {
+		compatible = "arm,coresight-static-funnel";
+
+		out-ports {
+			port {
+				lpi_funnel_out: endpoint {
+					remote-endpoint =
+					<&aoss_funnel_in5>;
+				};
+			};
+		};
+
+		in-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			port@0 {
+				reg = <0>;
+				lpi_funnel_in0: endpoint {
+					remote-endpoint =
+					<&audio_out>;
+				};
+			};
+
+			port@1 {
+				reg = <1>;
+				lpi_funnel_in1: endpoint {
+					remote-endpoint =
+					<&lpass_stm_out>;
+				};
+			};
+
+			port@5 {
+				reg = <5>;
+				lpi_funnel_in5: endpoint {
+					remote-endpoint =
+					<&lpi_tpdm_out>;
+				};
+			};
+		};
 	};
 
-	system_noc: interconnect-system-noc {
-		compatible = "qcom,sa8775p-system-noc";
-		#interconnect-cells = <2>;
-		qcom,bcm-voters = <&apps_bcm_voter>;
+	qcom,smp2p_sleepstate {
+		compatible = "qcom,smp2p-sleepstate";
+		qcom,smem-states = <&sleepstate_smp2p_out 0>;
+		interrupt-parent = <&sleepstate_smp2p_in>;
+		interrupts = <0 0>;
+		interrupt-names = "smp2p-sleepstate-in";
 	};
 
 	/* Will be updated by the bootloader. */
@@ -318,6 +676,81 @@
 	psci {
 		compatible = "arm,psci-1.0";
 		method = "smc";
+		mode-bootloader = <0x10001 0x2>;
+		mode-edl = <0 0x1>;
+
+		CPU_PD0: power-domain-cpu0 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_0_PD>;
+			domain-idle-states = <&GOLD_CPU_SLEEP_0>,
+					     <&GOLD_RAIL_CPU_SLEEP_0>;
+		};
+
+		CPU_PD1: power-domain-cpu1 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_0_PD>;
+			domain-idle-states = <&GOLD_CPU_SLEEP_0>,
+					     <&GOLD_RAIL_CPU_SLEEP_0>;
+		};
+
+		CPU_PD2: power-domain-cpu2 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_0_PD>;
+			domain-idle-states = <&GOLD_CPU_SLEEP_0>,
+					     <&GOLD_RAIL_CPU_SLEEP_0>;
+		};
+
+		CPU_PD3: power-domain-cpu3 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_0_PD>;
+			domain-idle-states = <&GOLD_CPU_SLEEP_0>,
+					     <&GOLD_RAIL_CPU_SLEEP_0>;
+		};
+
+		CPU_PD4: power-domain-cpu4 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_1_PD>;
+			domain-idle-states = <&GOLD_CPU_SLEEP_0>,
+					     <&GOLD_RAIL_CPU_SLEEP_0>;
+		};
+
+		CPU_PD5: power-domain-cpu5 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_1_PD>;
+			domain-idle-states = <&GOLD_CPU_SLEEP_0>,
+					     <&GOLD_RAIL_CPU_SLEEP_0>;
+		};
+
+		CPU_PD6: power-domain-cpu6 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_1_PD>;
+			domain-idle-states = <&GOLD_CPU_SLEEP_0>,
+					     <&GOLD_RAIL_CPU_SLEEP_0>;
+		};
+
+		CPU_PD7: power-domain-cpu7 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_1_PD>;
+			domain-idle-states = <&GOLD_CPU_SLEEP_0>,
+					     <&GOLD_RAIL_CPU_SLEEP_0>;
+		};
+
+		CLUSTER_0_PD: power-domain-cluster0 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_2_PD>;
+			domain-idle-states = <&CLUSTER_SLEEP_GOLD>;
+		};
+
+		CLUSTER_1_PD: power-domain-cluster1 {
+			#power-domain-cells = <0>;
+			power-domains = <&CLUSTER_2_PD>;
+			domain-idle-states = <&CLUSTER_SLEEP_GOLD>;
+		};
+
+		CLUSTER_2_PD: power-domain-cluster2 {
+			#power-domain-cells = <0>;
+			domain-idle-states = <&CLUSTER_SLEEP_APSS_RSC_PC>;
+		};
 	};
 
 	reserved-memory {
@@ -356,13 +789,18 @@
 			no-map;
 		};
 
+		ddr_training_checksum: ddr-training-checksum@908c0000 {
+			reg = <0x0 0x908c0000 0x0 0x1000>;
+			no-map;
+		};
+
 		reserved_mem: reserved@908f0000 {
-			reg = <0x0 0x908f0000 0x0 0xf000>;
+			reg = <0x0 0x908f0000 0x0 0xe000>;
 			no-map;
 		};
 
-		secdata_apss_mem: secdata-apss@908ff000 {
-			reg = <0x0 0x908ff000 0x0 0x1000>;
+		secdata_apss_mem: secdata-apss@908fe000 {
+			reg = <0x0 0x908fe000 0x0 0x2000>;
 			no-map;
 		};
 
@@ -373,8 +811,49 @@
 			hwlocks = <&tcsr_mutex 3>;
 		};
 
-		cpucp_fw_mem: cpucp-fw@90b00000 {
-			reg = <0x0 0x90b00000 0x0 0x100000>;
+		tz_sail_mailbox_mem: tz-sail-mailbox@90c00000 {
+			reg = <0x0 0x90c00000 0x0 0x100000>;
+			no-map;
+		};
+
+		sail_mailbox_mem: sail-ss@90d00000 {
+			reg = <0x0 0x90d00000 0x0 0x100000>;
+			no-map;
+		};
+
+		sail_ota_mem: sail-ss@90e00000 {
+			reg = <0x0 0x90e00000 0x0 0x300000>;
+			no-map;
+		};
+
+		aoss_backup_mem: aoss-backup@91b00000 {
+			reg = <0x0 0x91b00000 0x0 0x40000>;
+			no-map;
+		};
+
+		cpucp_backup_mem: cpucp-backup@91b40000 {
+			reg = <0x0 0x91b40000 0x0 0x40000>;
+			no-map;
+		};
+
+		tz_config_backup_mem: tz-config-backup@91b80000 {
+			reg = <0x0 0x91b80000 0x0 0x10000>;
+			no-map;
+		};
+
+		ddr_training_data_mem: ddr-training-data@91b90000 {
+			reg = <0x0 0x91b90000 0x0 0x10000>;
+			no-map;
+		};
+
+		cdt_data_backup_mem: cdt-data-backup@91ba0000 {
+			reg = <0x0 0x91ba0000 0x0 0x1000>;
+			no-map;
+		};
+
+		tz_ffi_mem: tz-ffi@91c00000 {
+			compatible = "shared-dma-pool";
+			reg = <0x0 0x91c00000 0x0 0x1400000>;
 			no-map;
 		};
 
@@ -389,7 +868,7 @@
 		};
 
 		pil_camera_mem: pil-camera@95200000 {
-			reg = <0x0 0x95200000 0x0 0x500000>;
+			reg = <0x0 0x95200000 0x0 0x700000>;
 			no-map;
 		};
 
@@ -433,13 +912,43 @@
 			no-map;
 		};
 
+		audio_mdf_mem: audio-mdf-region@ae000000 {
+			reg = <0x0 0xae000000 0x0 0x1000000>;
+			no-map;
+		};
+
+		firmware_mem: firmware-region@b0000000 {
+			reg = <0x0 0xb0000000 0x0 0x800000>;
+			no-map;
+		};
+
 		hyptz_reserved_mem: hyptz-reserved@beb00000 {
 			reg = <0x0 0xbeb00000 0x0 0x11500000>;
 			no-map;
 		};
 
-		tz_stat_mem: tz-stat@d0000000 {
-			reg = <0x0 0xd0000000 0x0 0x100000>;
+		scmi_mem: scmi-region@d0000000 {
+			reg = <0x0 0xd0000000 0x0 0x40000>;
+			no-map;
+		};
+
+		firmware_logs_mem: firmware-logs@d0040000 {
+			reg = <0x0 0xd0040000 0x0 0x10000>;
+			no-map;
+		};
+
+		firmware_audio_mem: firmware-audio@d0050000 {
+			reg = <0x0 0xd0050000 0x0 0x4000>;
+			no-map;
+		};
+
+		firmware_reserved_mem: firmware-reserved@d0054000 {
+			reg = <0x0 0xd0054000 0x0 0x9c000>;
+			no-map;
+		};
+
+		firmware_quantum_test_mem: firmware-quantum-test@d00f0000 {
+			reg = <0x0 0xd00f0000 0x0 0x10000>;
 			no-map;
 		};
 
@@ -453,10 +962,274 @@
 			no-map;
 		};
 
-		trusted_apps_mem: trusted-apps@d1800000 {
-			reg = <0x0 0xd1800000 0x0 0x3900000>;
+		deepsleep_backup_mem: deepsleep-backup@d1800000 {
+			reg = <0x0 0xd1800000 0x0 0x100000>;
 			no-map;
 		};
+
+		trusted_apps_mem: trusted-apps@d1900000 {
+			reg = <0x0 0xd1900000 0x0 0x3800000>;
+			no-map;
+		};
+
+		tz_stat_mem: tz-stat@db100000 {
+			reg = <0x0 0xdb100000 0x0 0x100000>;
+			no-map;
+		};
+
+		cpucp_fw_mem: cpucp-fw@db200000 {
+			reg = <0x0 0xdb200000 0x0 0x100000>;
+			no-map;
+		};
+
+		cdsp_secure_heap: secure-cdsp-region {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>;
+			reusable;
+			alignment = <0x0 0x400000>;
+			size = <0x0 0x2000000>;
+		};
+	};
+
+	smp2p-adsp {
+		compatible = "qcom,smp2p";
+		qcom,smem = <443>, <429>;
+		interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+					     IPCC_MPROC_SIGNAL_SMP2P
+					     IRQ_TYPE_EDGE_RISING>;
+		mboxes = <&ipcc IPCC_CLIENT_LPASS IPCC_MPROC_SIGNAL_SMP2P>;
+
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <2>;
+
+		smp2p_adsp_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_adsp_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		sleepstate_smp2p_in: sleepstate-in {
+			qcom,entry-name = "sleepstate_see";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		sleepstate_smp2p_out: sleepstate-out {
+			qcom,entry-name = "sleepstate";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_rdbg2_out: smp2p-rdbg2-out {
+			qcom,entry-name = "rdbg";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_rdbg2_in: smp2p-rdbg2-in {
+			qcom,entry-name = "rdbg";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	smp2p-cdsp0 {
+		compatible = "qcom,smp2p";
+		qcom,smem = <94>, <432>;
+		interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
+					     IPCC_MPROC_SIGNAL_SMP2P
+					     IRQ_TYPE_EDGE_RISING>;
+		mboxes = <&ipcc IPCC_CLIENT_CDSP IPCC_MPROC_SIGNAL_SMP2P>;
+
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <5>;
+
+		smp2p_cdsp0_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_cdsp0_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		smp2p_rdbg5_out: smp2p-rdbg5-out {
+			qcom,entry-name = "rdbg";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_rdbg5_in: smp2p-rdbg5-in {
+			qcom,entry-name = "rdbg";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	smp2p-cdsp1 {
+		compatible = "qcom,smp2p";
+		qcom,smem = <617>, <616>;
+		interrupts-extended = <&ipcc IPCC_CLIENT_NSP1
+					     IPCC_MPROC_SIGNAL_SMP2P
+					     IRQ_TYPE_EDGE_RISING>;
+		mboxes = <&ipcc IPCC_CLIENT_NSP1 IPCC_MPROC_SIGNAL_SMP2P>;
+
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <12>;
+
+		smp2p_cdsp1_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_cdsp1_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		smp2p_rdbg12_out: smp2p-rdbg12-out {
+			qcom,entry-name = "rdbg";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_rdbg12_in: smp2p-rdbg12-in {
+			qcom,entry-name = "rdbg";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	smp2p-gpdsp0 {
+		compatible = "qcom,smp2p";
+		qcom,smem = <617>, <616>;
+		interrupts-extended = <&ipcc IPCC_CLIENT_GPDSP0
+					     IPCC_MPROC_SIGNAL_SMP2P
+					     IRQ_TYPE_EDGE_RISING>;
+		mboxes = <&ipcc IPCC_CLIENT_GPDSP0 IPCC_MPROC_SIGNAL_SMP2P>;
+
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <17>;
+
+		smp2p_gpdsp0_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_gpdsp0_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		smp2p_rdbg17_out: smp2p-rdbg17-out {
+			qcom,entry-name = "rdbg";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_rdbg17_in: smp2p-rdbg17-in {
+			qcom,entry-name = "rdbg";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	smp2p-gpdsp1 {
+		compatible = "qcom,smp2p";
+		qcom,smem = <617>, <616>;
+		interrupts-extended = <&ipcc IPCC_CLIENT_GPDSP1
+					     IPCC_MPROC_SIGNAL_SMP2P
+					     IRQ_TYPE_EDGE_RISING>;
+		mboxes = <&ipcc IPCC_CLIENT_GPDSP1 IPCC_MPROC_SIGNAL_SMP2P>;
+
+		qcom,local-pid = <0>;
+		qcom,remote-pid = <18>;
+
+		smp2p_gpdsp1_out: master-kernel {
+			qcom,entry-name = "master-kernel";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_gpdsp1_in: slave-kernel {
+			qcom,entry-name = "slave-kernel";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		smp2p_rdbg18_out: smp2p-rdbg18-out {
+			qcom,entry-name = "rdbg";
+			#qcom,smem-state-cells = <1>;
+		};
+
+		smp2p_rdbg18_in: smp2p-rdbg18-in {
+			qcom,entry-name = "rdbg";
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+	};
+
+	qcom-smp2p-interrupt-rdbg-2-in {
+		compatible = "qcom,smp2p-interrupt-rdbg-2-in";
+		interrupts-extended = <&smp2p_rdbg2_in 0 IRQ_TYPE_NONE>;
+		interrupt-names = "rdbg-smp2p-in";
+	};
+
+	qcom-smp2p-interrupt-rdbg-2-out {
+		compatible = "qcom,smp2p-interrupt-rdbg-2-out";
+		qcom,smem-states = <&smp2p_rdbg2_out 0>;
+		qcom,smem-state-names = "rdbg-smp2p-out";
+	};
+
+	qcom-smp2p-interrupt-rdbg-5-in {
+		compatible = "qcom,smp2p-interrupt-rdbg-5-in";
+		interrupts-extended = <&smp2p_rdbg5_in 0 IRQ_TYPE_NONE>;
+		interrupt-names = "rdbg-smp2p-in";
+	};
+
+	qcom-smp2p-interrupt-rdbg-5-out {
+		compatible = "qcom,smp2p-interrupt-rdbg-5-out";
+		qcom,smem-states = <&smp2p_rdbg5_out 0>;
+		qcom,smem-state-names = "rdbg-smp2p-out";
+	};
+
+	qcom-smp2p-interrupt-rdbg-12-in {
+		compatible = "qcom,smp2p-interrupt-rdbg-12-in";
+		interrupts-extended = <&smp2p_rdbg12_in 0 IRQ_TYPE_NONE>;
+		interrupt-names = "rdbg-smp2p-in";
+	};
+
+	qcom-smp2p-interrupt-rdbg-12-out {
+		compatible = "qcom,smp2p-interrupt-rdbg-12-out";
+		qcom,smem-states = <&smp2p_rdbg12_out 0>;
+		qcom,smem-state-names = "rdbg-smp2p-out";
+	};
+
+	qcom-smp2p-interrupt-rdbg-17-in {
+		compatible = "qcom,smp2p-interrupt-rdbg-17-in";
+		interrupts-extended = <&smp2p_rdbg17_in 0 IRQ_TYPE_NONE>;
+		interrupt-names = "rdbg-smp2p-in";
+	};
+
+	qcom-smp2p-interrupt-rdbg-17-out {
+		compatible = "qcom,smp2p-interrupt-rdbg-17-out";
+		qcom,smem-states = <&smp2p_rdbg17_out 0>;
+		qcom,smem-state-names = "rdbg-smp2p-out";
+	};
+
+	qcom-smp2p-interrupt-rdbg-18-in {
+		compatible = "qcom,smp2p-interrupt-rdbg-18-in";
+		interrupts-extended = <&smp2p_rdbg18_in 0 IRQ_TYPE_NONE>;
+		interrupt-names = "rdbg-smp2p-in";
+	};
+
+	qcom-smp2p-interrupt-rdbg-18-out {
+		compatible = "qcom,smp2p-interrupt-rdbg-18-out";
+		qcom,smem-states = <&smp2p_rdbg18_out 0>;
+		qcom,smem-state-names = "rdbg-smp2p-out";
 	};
 
 	soc: soc@0 {
@@ -498,6 +1271,40 @@
 			#mbox-cells = <2>;
 		};
 
+		qfprom: efuse@784000 {
+			compatible = "qcom,qfprom";
+			reg = <0x0 0x00784000 0x0 0x11d0>;
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			gpu_speed_bin: gpu-speed-bin@15c {
+				reg = <0x15c 0x1>;
+				bits = <5 3>;
+			};
+		};
+
+		gpi_dma2: qcom,gpi-dma@800000  {
+			compatible = "qcom,sm6350-gpi-dma";
+			reg = <0x0 0x00800000 0x0 0x60000>;
+			#dma-cells = <3>;
+			interrupts = <GIC_SPI 588 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 589 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 590 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 591 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 592 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 593 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 594 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 595 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 596 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 597 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 598 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 599 IRQ_TYPE_LEVEL_HIGH>;
+			dma-channels = <12>;
+			dma-channel-mask = <0xfff>;
+			iommus = <&apps_smmu 0x5b6 0x0>;
+			status = "disabled";
+		};
+
 		qupv3_id_2: geniqup@8c0000 {
 			compatible = "qcom,geni-se-qup";
 			reg = <0x0 0x008c0000 0x0 0x6000>;
@@ -518,6 +1325,8 @@
 				interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S0_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c14_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -528,6 +1337,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma2 0 0 QCOM_GPI_I2C>,
+				       <&gpi_dma2 1 0 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -539,6 +1352,8 @@
 				interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S0_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi14_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -549,6 +1364,27 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma2 0 0 QCOM_GPI_SPI>,
+				       <&gpi_dma2 1 0 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart14: serial@880000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x00880000 0x0 0x4000>;
+				interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP2_S0_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart14_default>;
+				pinctrl-names = "default";
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core", "qup-config";
+				power-domains = <&rpmhpd SA8775P_CX>;
 				status = "disabled";
 			};
 
@@ -560,6 +1396,8 @@
 				interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S1_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c15_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -570,6 +1408,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma2 0 1 QCOM_GPI_I2C>,
+				       <&gpi_dma2 1 1 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -581,6 +1423,8 @@
 				interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S1_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi15_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -591,6 +1435,27 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma2 0 1 QCOM_GPI_SPI>,
+				       <&gpi_dma2 1 1 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart15: serial@884000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x00884000 0x0 0x4000>;
+				interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP2_S1_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart15_default>;
+				pinctrl-names = "default";
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core", "qup-config";
+				power-domains = <&rpmhpd SA8775P_CX>;
 				status = "disabled";
 			};
 
@@ -602,6 +1467,8 @@
 				interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S2_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c16_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -612,6 +1479,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma2 0 2 QCOM_GPI_I2C>,
+				       <&gpi_dma2 1 2 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -621,6 +1492,8 @@
 				interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S2_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi16_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -631,11 +1504,32 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma2 0 2 QCOM_GPI_SPI>,
+				       <&gpi_dma2 1 2 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
 				#address-cells = <1>;
 				#size-cells = <0>;
 				status = "disabled";
 			};
 
+			uart16: serial@888000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x00888000 0x0 0x4000>;
+				interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP2_S2_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart16_default>;
+				pinctrl-names = "default";
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core", "qup-config";
+				power-domains = <&rpmhpd SA8775P_CX>;
+				status = "disabled";
+			};
+
 			i2c17: i2c@88c000 {
 				compatible = "qcom,geni-i2c";
 				reg = <0x0 0x88c000 0x0 0x4000>;
@@ -644,6 +1538,8 @@
 				interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c17_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -654,6 +1550,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma2 0 3 QCOM_GPI_I2C>,
+				       <&gpi_dma2 1 3 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -665,6 +1565,8 @@
 				interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi17_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -675,6 +1577,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma2 0 3 QCOM_GPI_SPI>,
+				       <&gpi_dma2 1 3 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -684,6 +1590,8 @@
 				interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_uart17_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -699,6 +1607,8 @@
 				interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S4_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c18_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -709,6 +1619,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma2 0 4 QCOM_GPI_I2C>,
+				       <&gpi_dma2 1 4 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				#address-cells = <1>;
 				#size-cells = <0>;
 				status = "disabled";
@@ -722,6 +1636,8 @@
 				interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S4_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi18_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -732,6 +1648,27 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma2 0 4 QCOM_GPI_SPI>,
+				       <&gpi_dma2 1 4 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart18: serial@890000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x00890000 0x0 0x4000>;
+				interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP2_S4_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart18_default>;
+				pinctrl-names = "default";
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core", "qup-config";
+				power-domains = <&rpmhpd SA8775P_CX>;
 				status = "disabled";
 			};
 
@@ -743,6 +1680,8 @@
 				interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S5_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c19_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -753,6 +1692,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma2 0 5 QCOM_GPI_I2C>,
+				       <&gpi_dma2 1 5 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -764,6 +1707,8 @@
 				interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S5_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi19_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -774,6 +1719,27 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma2 0 5 QCOM_GPI_SPI>,
+				       <&gpi_dma2 1 5 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart19: serial@894000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x00894000 0x0 0x4000>;
+				interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP2_S5_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart19_default>;
+				pinctrl-names = "default";
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core", "qup-config";
+				power-domains = <&rpmhpd SA8775P_CX>;
 				status = "disabled";
 			};
 
@@ -785,6 +1751,8 @@
 				interrupts = <GIC_SPI 834 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S6_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c20_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -795,6 +1763,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma2 0 6 QCOM_GPI_I2C>,
+				       <&gpi_dma2 1 6 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -806,6 +1778,8 @@
 				interrupts = <GIC_SPI 834 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP2_S6_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi20_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -816,8 +1790,61 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma2 0 6 QCOM_GPI_SPI>,
+				       <&gpi_dma2 1 6 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
+
+			uart20: serial@898000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x00898000 0x0 0x4000>;
+				interrupts = <GIC_SPI 834 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP2_S6_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart20_default>;
+				pinctrl-names = "default";
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core", "qup-config";
+				power-domains = <&rpmhpd SA8775P_CX>;
+				status = "disabled";
+			};
+
+		};
+
+		gpi_dma0: qcom,gpi-dma@900000  {
+			compatible = "qcom,sm6350-gpi-dma";
+			reg = <0x0 0x00900000 0x0 0x60000>;
+			#dma-cells = <3>;
+			interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 251 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 252 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 253 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>;
+			dma-channels = <12>;
+			dma-channel-mask = <0xfff>;
+			iommus = <&apps_smmu 0x416 0x0>;
+			status = "disabled";
+		};
+
+		eud: eud@88e1000 {
+			compatible = "qcom,secure-eud";
+			reg = <0x0 0x088E1000 0x0 0x2000>,
+			      <0x0 0x088E3000 0x0 0x1000>;
+			interrupts-extended = <&pdc 11 IRQ_TYPE_LEVEL_HIGH>;
+
+			status = "disabled";
 		};
 
 		qupv3_id_0: geniqup@9c0000 {
@@ -840,6 +1867,8 @@
 				interrupts = <GIC_SPI 550 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c0_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -850,6 +1879,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma0 0 0 QCOM_GPI_I2C>,
+				       <&gpi_dma0 1 0 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -861,6 +1894,8 @@
 				interrupts = <GIC_SPI 550 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi0_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -871,6 +1906,27 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma0 0 0 QCOM_GPI_SPI>,
+				     <&gpi_dma0 1 0 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart0: serial@980000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x980000 0x0 0x4000>;
+				interrupts = <GIC_SPI 550 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart0_default>;
+				pinctrl-names = "default";
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core", "qup-config";
+				power-domains = <&rpmhpd SA8775P_CX>;
 				status = "disabled";
 			};
 
@@ -882,6 +1938,8 @@
 				interrupts = <GIC_SPI 551 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c1_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -892,6 +1950,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma0 0 1 QCOM_GPI_I2C>,
+				       <&gpi_dma0 1 1 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -903,6 +1965,8 @@
 				interrupts = <GIC_SPI 551 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi1_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -913,6 +1977,27 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma0 0 1 QCOM_GPI_SPI>,
+				       <&gpi_dma0 1 1 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart1: serial@984000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x984000 0x0 0x4000>;
+				interrupts = <GIC_SPI 551 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart1_default>;
+				pinctrl-names = "default";
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core", "qup-config";
+				power-domains = <&rpmhpd SA8775P_CX>;
 				status = "disabled";
 			};
 
@@ -924,6 +2009,8 @@
 				interrupts = <GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c2_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -934,6 +2021,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma0 0 2 QCOM_GPI_I2C>,
+				       <&gpi_dma0 1 2 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -945,6 +2036,8 @@
 				interrupts = <GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi2_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -955,6 +2048,27 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma0 0 2 QCOM_GPI_SPI>,
+				       <&gpi_dma0 1 2 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart2: serial@988000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x988000 0x0 0x4000>;
+				interrupts = <GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart2_default>;
+				pinctrl-names = "default";
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core", "qup-config";
+				power-domains = <&rpmhpd SA8775P_CX>;
 				status = "disabled";
 			};
 
@@ -966,6 +2080,8 @@
 				interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c3_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -976,6 +2092,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma0 0 3 QCOM_GPI_I2C>,
+				       <&gpi_dma0 1 3 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -987,6 +2107,8 @@
 				interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi3_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -997,6 +2119,27 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma0 0 3 QCOM_GPI_SPI>,
+				       <&gpi_dma0 1 3 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart3: serial@98c000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x98c000 0x0 0x4000>;
+				interrupts = <GIC_SPI 530 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart3_default>;
+				pinctrl-names = "default";
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core", "qup-config";
+				power-domains = <&rpmhpd SA8775P_CX>;
 				status = "disabled";
 			};
 
@@ -1008,6 +2151,8 @@
 				interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c4_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1018,6 +2163,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma0 0 4 QCOM_GPI_I2C>,
+				       <&gpi_dma0 1 4 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -1029,6 +2178,8 @@
 				interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi4_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1039,6 +2190,27 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma0 0 4 QCOM_GPI_SPI>,
+				       <&gpi_dma0 1 4 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart4: serial@990000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x990000 0x0 0x4000>;
+				interrupts = <GIC_SPI 531 IRQ_TYPE_LEVEL_HIGH>;
+				clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>;
+				clock-names = "se";
+				pinctrl-0 = <&qup_uart4_default>;
+				pinctrl-names = "default";
+				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core", "qup-config";
+				power-domains = <&rpmhpd SA8775P_CX>;
 				status = "disabled";
 			};
 
@@ -1050,6 +2222,8 @@
 				interrupts = <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c5_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1060,6 +2234,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma0 0 5 QCOM_GPI_I2C>,
+				       <&gpi_dma0 1 5 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -1071,6 +2249,8 @@
 				interrupts = <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi5_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1081,6 +2261,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma0 0 5 QCOM_GPI_SPI>,
+				       <&gpi_dma0 1 5 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -1090,6 +2274,8 @@
 				interrupts = <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_uart5_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1100,6 +2286,28 @@
 			};
 		};
 
+		gpi_dma1: qcom,gpi-dma@a00000  {
+			compatible = "qcom,sm6350-gpi-dma";
+			reg = <0x0 0x00a00000 0x0 0x60000>;
+			#dma-cells = <3>;
+			interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 280 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 293 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 294 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 295 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 296 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 297 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>;
+			iommus = <&apps_smmu 0x456 0x0>;
+			dma-channels = <12>;
+			dma-channel-mask = <0xfff>;
+			status = "disabled";
+		};
+
 		qupv3_id_1: geniqup@ac0000 {
 			compatible = "qcom,geni-se-qup";
 			reg = <0x0 0x00ac0000 0x0 0x6000>;
@@ -1120,6 +2328,8 @@
 				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c7_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1130,6 +2340,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 0 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -1141,6 +2355,8 @@
 				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi7_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1151,6 +2367,28 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma1 0 0 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 0 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart7: serial@a80000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x00a80000 0x0 0x4000>;
+				interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+				clock-names = "se";
+				clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+				pinctrl-0 = <&qup_uart7_default>;
+				pinctrl-names = "default";
+				interconnect-names = "qup-core", "qup-config";
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>;
+				power-domains = <&rpmhpd SA8775P_CX>;
+				operating-points-v2 = <&qup_opp_table_100mhz>;
 				status = "disabled";
 			};
 
@@ -1162,6 +2400,8 @@
 				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c8_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1172,6 +2412,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 1 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -1183,6 +2427,8 @@
 				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi8_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1193,6 +2439,28 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma1 0 1 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 1 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart8: serial@a84000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x00a84000 0x0 0x4000>;
+				interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+				clock-names = "se";
+				clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
+				pinctrl-0 = <&qup_uart8_default>;
+				pinctrl-names = "default";
+				interconnect-names = "qup-core", "qup-config";
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>;
+				power-domains = <&rpmhpd SA8775P_CX>;
+				operating-points-v2 = <&qup_opp_table_100mhz>;
 				status = "disabled";
 			};
 
@@ -1204,6 +2472,8 @@
 				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c9_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1214,6 +2484,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 2 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -1225,6 +2499,8 @@
 				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi9_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1235,6 +2511,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma1 0 2 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 2 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -1244,6 +2524,8 @@
 				interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_uart9_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1261,6 +2543,8 @@
 				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c10_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1271,6 +2555,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 3 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -1282,6 +2570,8 @@
 				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi10_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1292,6 +2582,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma1 0 3 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 3 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -1301,6 +2595,8 @@
 				interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
 				clock-names = "se";
 				clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
+				pinctrl-0 = <&qup_uart10_default>;
+				pinctrl-names = "default";
 				interconnect-names = "qup-core", "qup-config";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 0
 						 &clk_virt SLAVE_QUP_CORE_1 0>,
@@ -1319,6 +2615,8 @@
 				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c11_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1329,6 +2627,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma1 0 4 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 4 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -1340,6 +2642,8 @@
 				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi11_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1350,6 +2654,28 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma1 0 4 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 4 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart11: serial@a90000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x00a90000 0x0 0x4000>;
+				interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+				clock-names = "se";
+				clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
+				pinctrl-0 = <&qup_uart11_default>;
+				pinctrl-names = "default";
+				interconnect-names = "qup-core", "qup-config";
+				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>;
+				power-domains = <&rpmhpd SA8775P_CX>;
+				operating-points-v2 = <&qup_opp_table_100mhz>;
 				status = "disabled";
 			};
 
@@ -1361,6 +2687,8 @@
 				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c12_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1371,6 +2699,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma1 0 5 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 5 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -1382,6 +2714,8 @@
 				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi12_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1392,6 +2726,10 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma1 0 5 QCOM_GPI_SPI>,
+				       <&gpi_dma1 1 5 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -1401,6 +2739,8 @@
 				interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_uart12_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1418,6 +2758,8 @@
 				interrupts = <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c13_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS
 						 &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>,
 						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1428,10 +2770,29 @@
 						     "qup-config",
 						     "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma1 0 6 QCOM_GPI_I2C>,
+				       <&gpi_dma1 1 6 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
+
 			};
 		};
 
+		gpi_dma3: qcom,gpi-dma@b00000  {
+			compatible = "qcom,sm6350-gpi-dma";
+			reg = <0x0 0x00b00000 0x0 0x58000>;
+			#dma-cells = <3>;
+			interrupts = <GIC_SPI 368 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 527 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 528 IRQ_TYPE_LEVEL_HIGH>;
+			iommus = <&apps_smmu 0x056 0x0>;
+			dma-channels = <4>;
+			dma-channel-mask = <0xf>;
+			status = "disabled";
+		};
+
 		qupv3_id_3: geniqup@bc0000 {
 			compatible = "qcom,geni-se-qup";
 			reg = <0x0 0xbc0000 0x0 0x6000>;
@@ -1452,6 +2813,8 @@
 				interrupts = <GIC_SPI 831 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP3_S0_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_i2c21_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS
 						&clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>,
 					   <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1462,6 +2825,10 @@
 							 "qup-config",
 							 "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma3 0 0 QCOM_GPI_I2C>,
+				       <&gpi_dma3 1 0 QCOM_GPI_I2C>;
+				dma-names = "tx",
+					    "rx";
 				status = "disabled";
 			};
 
@@ -1473,6 +2840,8 @@
 				interrupts = <GIC_SPI 831 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&gcc GCC_QUPV3_WRAP3_S0_CLK>;
 				clock-names = "se";
+				pinctrl-0 = <&qup_spi21_default>;
+				pinctrl-names = "default";
 				interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS
 						&clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>,
 					   <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
@@ -1483,6 +2852,28 @@
 							 "qup-config",
 							 "qup-memory";
 				power-domains = <&rpmhpd SA8775P_CX>;
+				dmas = <&gpi_dma3 0 0 QCOM_GPI_SPI>,
+				       <&gpi_dma3 1 0 QCOM_GPI_SPI>;
+				dma-names = "tx",
+					    "rx";
+				status = "disabled";
+			};
+
+			uart21: serial@b80000 {
+				compatible = "qcom,geni-uart";
+				reg = <0x0 0x00b80000 0x0 0x4000>;
+				interrupts = <GIC_SPI 831 IRQ_TYPE_LEVEL_HIGH>;
+				clock-names = "se";
+				clocks = <&gcc GCC_QUPV3_WRAP3_S0_CLK>;
+				interconnect-names = "qup-core", "qup-config";
+				pinctrl-0 = <&qup_uart21_default>;
+				pinctrl-names = "default";
+				interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ALWAYS>;
+				power-domains = <&rpmhpd SA8775P_CX>;
+				operating-points-v2 = <&qup_opp_table_100mhz>;
 				status = "disabled";
 			};
 		};
@@ -1492,6 +2883,62 @@
 			reg = <0 0x010d2000 0 0x1000>;
 		};
 
+		config_noc: interconnect-config-noc@14c0000 {
+			compatible = "qcom,sa8775p-config-noc";
+			reg = <0x0 0x014c0000 0x0 0x13080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		system_noc: interconnect-system-noc@01680000 {
+			compatible = "qcom,sa8775p-system-noc";
+			reg = <0x0 0x01680000 0x0 0x15080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		aggre1_noc: interconnect-aggre1-noc@16c0000 {
+			compatible = "qcom,sa8775p-aggre1-noc";
+			reg = <0x0 0x016c0000 0x0 0x18080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+			clocks = <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+				 <&gcc GCC_AGGRE_NOC_QUPV3_AXI_CLK>,
+				 <&gcc GCC_AGGRE_USB2_PRIM_AXI_CLK>,
+				 <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>,
+				 <&gcc GCC_AGGRE_USB3_SEC_AXI_CLK>;
+		};
+
+		aggre2_noc: interconnect-aggre2-noc@1700000 {
+			compatible = "qcom,sa8775p-aggre2-noc";
+			reg = <0x0 0x01700000 0x0 0x1b080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+			clocks = <&gcc GCC_AGGRE_UFS_CARD_AXI_CLK>,
+				 <&rpmhcc RPMH_IPA_CLK>;
+		};
+
+		pcie_anoc: interconnect-pcie-anoc@1760000 {
+			compatible = "qcom,sa8775p-pcie-anoc";
+			reg = <0x0 0x01760000 0x0 0xc080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		gpdsp_anoc: interconnect-gpdsp-anoc@1780000 {
+			compatible = "qcom,sa8775p-gpdsp-anoc";
+			reg = <0x0 0x01780000 0x0 0xe080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		mmss_noc: interconnect-mmss-noc@17a0000 {
+			compatible = "qcom,sa8775p-mmss-noc";
+			reg = <0x0 0x017a0000 0x0 0x40000>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
 		ufs_mem_hc: ufs@1d84000 {
 			compatible = "qcom,sa8775p-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
 			reg = <0x0 0x01d84000 0x0 0x3000>;
@@ -1555,10 +3002,3047 @@
 		ice: crypto@1d88000 {
 			compatible = "qcom,sa8775p-inline-crypto-engine",
 				     "qcom,inline-crypto-engine";
-			reg = <0x0 0x01d88000 0x0 0x8000>;
+			reg = <0x0 0x01d88000 0x0 0x18000>;
 			clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>;
 		};
 
+		sdhc_1: mmc@0x087C4000 {
+			compatible = "qcom,sdhci-msm-v5";
+			status = "disabled";
+
+			reg = <0x0 0x087C4000 0x0 0x1000>;
+
+			interrupts = <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>,
+				<GIC_SPI 521 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "hc_irq", "pwr_irq";
+
+			clocks = <&gcc GCC_SDCC1_AHB_CLK>,
+				<&gcc GCC_SDCC1_APPS_CLK>;
+			clock-names = "iface", "core";
+
+			interconnects = <&aggre1_noc MASTER_SDC 0 &mc_virt SLAVE_EBI1 0>,
+					<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_SDC1 0>;
+			interconnect-names = "sdhc-ddr","cpu-sdhc";
+
+			power-domains = <&rpmhpd RPMHPD_CX>;
+			operating-points-v2 = <&sdhc1_opp_table>;
+
+			qcom,iommu-dma = "fastmap";
+
+			qcom,iommu-dma-addr-pool = <0x40000000 0x10000000>;
+			qcom,iommu-geometry = <0x40000000 0x10000000>;
+
+			no-sdio;
+			no-mmc;
+
+			bus-width = <4>;
+			dma-coherent;
+			qcom,dll-config = <0x0007642C>;
+
+			resets = <&gcc GCC_SDCC1_BCR>;
+
+			sdhc1_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-100000000 {
+					opp-hz = /bits/ 64 <100000000>;
+					required-opps = <&rpmhpd_opp_low_svs>;
+					opp-peak-kBps = <1800000 400000>;
+					opp-avg-kBps = <100000 0>;
+				};
+
+				opp-384000000 {
+					opp-hz = /bits/ 64 <384000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+					opp-peak-kBps = <5400000 1600000>;
+					opp-avg-kBps = <390000 0>;
+				};
+			};
+		};
+
+		cryptobam: dma-controller@1dc4000 {
+			compatible = "qcom,bam-v1.7.4", "qcom,bam-v1.7.0";
+			reg = <0x0 0x01dc4000 0x0 0x28000>;
+			interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			qcom,ee = <0>;
+			qcom,controlled-remotely;
+			iommus = <&apps_smmu 0x480 0x00>,
+				 <&apps_smmu 0x481 0x00>;
+		};
+
+		crypto: crypto@1dfa000 {
+			compatible = "qcom,sa8775p-qce", "qcom,qce";
+			reg = <0x0 0x01dfa000 0x0 0x6000>;
+			dmas = <&cryptobam 4>, <&cryptobam 5>;
+			dma-names = "rx", "tx";
+			iommus = <&apps_smmu 0x480 0x00>,
+				 <&apps_smmu 0x481 0x00>;
+			interconnects = <&aggre2_noc MASTER_CRYPTO_CORE0 0 &mc_virt SLAVE_EBI1 0>;
+			interconnect-names = "memory";
+			qcom,icc_bw = <12473>;
+		};
+
+		stm: stm@4002000 {
+			compatible = "arm,coresight-stm", "arm,primecell";
+			reg = <0x0 0x4002000 0x0 0x1000>,
+				  <0x0 0x16280000 0x0 0x180000>;
+			reg-names = "stm-base", "stm-stimulus-base";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					stm_out: endpoint {
+						remote-endpoint =
+						<&funnel0_in7>;
+					};
+				};
+			};
+		};
+
+		tpdm@4003000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4003000 0x0 0x1000>;
+			device-name = "tpdm_dcc";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					qdss_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&qdss_tpda_in0>;
+					};
+				};
+			};
+		};
+
+		tpda@4004000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4004000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					qdss_tpda_out: endpoint {
+						remote-endpoint =
+						<&funnel0_in6>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					qdss_tpda_in0: endpoint {
+						remote-endpoint =
+						<&qdss_tpdm0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					qdss_tpda_in1: endpoint {
+						remote-endpoint =
+						<&qdss_tpdm1_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@400f000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x400f000 0x0 0x1000>;
+			device-name = "tpdm_spdm";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					qdss_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&qdss_tpda_in1>;
+					};
+				};
+			};
+		};
+
+		cti@4010000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4010000 0x0 0x1000>;
+			device-name = "cti_qdss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4041000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4041000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					funnel0_out: endpoint {
+						remote-endpoint =
+						<&qdss_funnel_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@6 {
+					reg = <6>;
+					funnel0_in6: endpoint {
+						remote-endpoint =
+						<&qdss_tpda_out>;
+					};
+				};
+
+				port@7 {
+					reg = <7>;
+					funnel0_in7: endpoint {
+						remote-endpoint =
+						<&stm_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4042000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4042000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					funnel1_out: endpoint {
+						remote-endpoint =
+						<&qdss_funnel_in1>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@4 {
+					reg = <4>;
+					funnel1_in4: endpoint {
+						remote-endpoint =
+						<&apss_funnel1_out>;
+					};
+				};
+				port@5 {
+					reg = <5>;
+					funnel1_in5: endpoint {
+						remote-endpoint =
+						<&dlct0_funnel_out>;
+					};
+				};
+
+				port@6 {
+					reg = <6>;
+					funnel1_in6: endpoint {
+						remote-endpoint =
+						<&dlhm_funnel_out>;
+					};
+				};
+
+				port@7 {
+					reg = <7>;
+					funnel1_in7: endpoint {
+						remote-endpoint =
+						<&dlmm_funnel_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4045000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4045000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					qdss_funnel_out: endpoint {
+						remote-endpoint =
+						<&aoss_funnel_in7>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					qdss_funnel_in0: endpoint {
+						remote-endpoint =
+						<&funnel0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					qdss_funnel_in1: endpoint {
+						remote-endpoint =
+						<&funnel1_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@482c000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x482c000 0x0 0x1000>;
+			device-name = "tpdm_gcc";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					gcc_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in20>;
+					};
+				};
+			};
+		};
+
+		tpdm@4830000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4830000 0x0 0x1000>;
+			device-name = "tpdm_video";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					video_tpdm_out: endpoint {
+						remote-endpoint =
+						<&video_funnel_in0>;
+					};
+				};
+			};
+		};
+
+		funnel@4832000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4832000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					video_funnel_out0: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in2>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					video_funnel_in0: endpoint {
+						remote-endpoint =
+						<&video_tpdm_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@4841000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4841000 0x0 0x1000>;
+			device-name = "tpdm_prng";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					prng_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in19>;
+					};
+				};
+			};
+		};
+
+		tpdm@4844000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4844000 0x0 0x1000>;
+			device-name = "tpdm_lpass";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					lpass_tpdm_out: endpoint {
+						remote-endpoint =
+						<&lpass_funnel_in0>;
+					};
+				};
+			};
+		};
+
+		cti@4845000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4845000 0x0 0x1000>;
+			device-name = "cti_lpass";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpdm@4850000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4850000 0x0 0x1000>;
+			device-name = "tpdm_pimem";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					pimem_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in25>;
+					};
+				};
+			};
+		};
+
+		tpdm@4860000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4860000 0x0 0x1000>;
+			device-name = "tpdm_gdsp";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					gdsp_tpdm_out: endpoint {
+						remote-endpoint =
+						<&gdsp_tpda_in31>;
+					};
+				};
+			};
+		};
+
+		cti@4861000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4861000 0x0 0x1000>;
+			device-name = "cti_gdsp_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		cti@4862000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4862000 0x0 0x1000>;
+			device-name = "cti_gdsp_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@4863000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4863000 0x0 0x1000>;
+			device-name = "gdsp-tpda";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					gdsp_tpda_out: endpoint {
+						remote-endpoint =
+						<&gdsp_funnel_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@9 {
+					reg = <9>;
+					gdsp_tpda_in9: endpoint {
+						remote-endpoint =
+						<&turing2_funnel_out0>;
+					};
+				};
+
+				port@e {
+					reg = <14>;
+					gdsp_tpda_in14: endpoint {
+						remote-endpoint =
+						<&turing3_funnel_out0>;
+					};
+				};
+
+				port@13 {
+					reg = <19>;
+					gdsp_tpda_in19: endpoint {
+						remote-endpoint =
+						<&turing1_funnel_out>;
+					};
+				};
+
+				port@1f {
+					reg = <31>;
+					gdsp_tpda_in31: endpoint {
+						remote-endpoint =
+						<&gdsp_tpdm_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4864000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4864000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					gdsp_funnel_out: endpoint {
+						remote-endpoint =
+						<&dlhm_funnel_in5>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					gdsp_funnel_in0: endpoint {
+						remote-endpoint =
+						<&gdsp_tpda_out>;
+					};
+				};
+			};
+		};
+
+		cti@4901000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4901000 0x0 0x1000>;
+			device-name = "cti_gfx_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4902000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4902000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					gfx_funnel1_out0: endpoint {
+						remote-endpoint =
+						<&dlhm_tpda_in9>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					reg = <1>;
+					gfx_funnel1_in1: endpoint {
+						remote-endpoint =
+						<&gfx_funnel0_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4940000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4940000 0x0 0x1000>,
+			      <0x0 0x4b83000 0x0 0x1000>;
+			reg-names = "funnel-base-dummy", "funnel-base-real";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,duplicate-funnel;
+			arm,primecell-periphid = <0x000bb908>;
+
+			out-ports {
+				port {
+					turing0_dup_funnel_out: endpoint {
+						remote-endpoint =
+						<&turing0_funnel_in5>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@4 {
+					reg = <4>;
+					turing0_dup_funnel_in4: endpoint {
+						remote-endpoint =
+						<&turing0_etm0_out>;
+					};
+				};
+			};
+		};
+
+		cti@4961000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4961000 0x0 0x1000>;
+			device-name = "cti_gfx_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		cti@4962000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4962000 0x0 0x1000>;
+			device-name = "cti_gfx_2";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		funnel@4963000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4963000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+
+			out-ports {
+				port {
+					gfx_funnel0_out: endpoint {
+						remote-endpoint =
+						<&gfx_funnel1_in1>;
+					};
+				};
+			};
+		};
+
+		tpdm@4980000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4980000 0x0 0x1000>;
+			device-name = "tpdm_turing";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					turing2_tpdm_out: endpoint {
+						remote-endpoint =
+						<&turing2_funnel_in0>;
+					};
+				};
+			};
+		};
+
+		cti@4982000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4982000 0x0 0x1000>;
+			device-name = "cti_gdsp0_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4983000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4983000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					turing2_funnel_out0: endpoint {
+						remote-endpoint =
+						<&gdsp_tpda_in9>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					turing2_funnel_in0: endpoint {
+						remote-endpoint =
+						<&turing2_tpdm_out>;
+					};
+				};
+			};
+		};
+
+		cti@498b000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x498b000 0x0 0x1000>;
+			reg-names = "cti-base";
+			device-name = "cti_gdsp0_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		tpdm@49a0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x49a0000 0x0 0x1000>;
+			device-name = "tpdm_turing_gdsp_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					turing3_tpdm_out: endpoint {
+						remote-endpoint =
+						<&turing3_funnel_in0>;
+					};
+				};
+			};
+		};
+
+		cti@49a2000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x49a2000 0x0 0x1000>;
+			device-name = "cti_gdsp1_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@49a3000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x49a3000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					turing3_funnel_out0: endpoint {
+						remote-endpoint =
+						<&gdsp_tpda_in14>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					turing3_funnel_in0: endpoint {
+						remote-endpoint =
+						<&turing3_tpdm_out>;
+					};
+				};
+			};
+		};
+
+		cti@49ab000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x49ab000 0x0 0x1000>;
+			device-name = "cti_gdsp1_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		tpdm@49c0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x49c0000 0x0 0x1000>;
+			device-name = "tpdm_rdpm_mxa";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					rdpm_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in23>;
+					};
+				};
+			};
+		};
+
+		tpdm@49ca000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x49ca000 0x0 0x1000>;
+			device-name = "tpdm_sdcc_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					sdcc_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlst_tpda_in0>;
+					};
+				};
+			};
+		};
+
+		tpdm@49d0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x49d0000 0x0 0x1000>;
+			device-name = "tpdm_qm";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					qm_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in21>;
+					};
+				};
+			};
+		};
+
+		tpdm@4ac0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4ac0000 0x0 0x1000>;
+			device-name = "tpdm_dlmm";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					dlmm_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&dlmm_tpda_in27>;
+					};
+				};
+			};
+		};
+
+		tpdm@4ac1000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4ac1000 0x0 0x1000>;
+			device-name = "tpdm_dlmm_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					dlmm_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&dlmm_tpda_in28>;
+					};
+				};
+			};
+		};
+
+		cti@4ac2000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4ac2000 0x0 0x1000>;
+			device-name = "cti_dlmm_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		cti@4ac3000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4ac3000 0x0 0x1000>;
+			device-name = "cti_dlmm_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@4ac4000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4ac4000 0x0 0x1000>;
+			device-name = "dlmm-tpda";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlmm_tpda_out: endpoint {
+						remote-endpoint =
+						<&dlmm_funnel_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@5 {
+					reg = <5>;
+					dlmm_tpda_in5: endpoint {
+						remote-endpoint =
+						<&mdss0_tpdm_out>;
+					};
+				};
+
+				port@8 {
+					reg = <8>;
+					dlmm_tpda_in8: endpoint {
+						remote-endpoint =
+						<&mdss1_tpdm_out>;
+					};
+				};
+
+				port@1b {
+					reg = <27>;
+					dlmm_tpda_in27: endpoint {
+						remote-endpoint =
+						<&dlmm_tpdm0_out>;
+					};
+				};
+
+				port@1c {
+					reg = <28>;
+					dlmm_tpda_in28: endpoint {
+						remote-endpoint =
+						<&dlmm_tpdm1_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4ac5000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4ac5000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlmm_funnel_out: endpoint {
+						remote-endpoint =
+						<&funnel1_in7>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					dlmm_funnel_in0: endpoint {
+						remote-endpoint =
+						<&dlmm_tpda_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					dlmm_funnel_in1: endpoint {
+						remote-endpoint =
+						<&titan_funnel_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@4ad0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4ad0000 0x0 0x1000>;
+			device-name = "tpdm_dlct";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					dlct0_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in26>;
+					};
+				};
+			};
+		};
+
+		tpdm@4ad1000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4ad1000 0x0 0x1000>;
+			device-name = "tpdm_ipcc";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					dlct0_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in27>;
+					};
+				};
+			};
+		};
+
+		cti0: cti@4ad2000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4ad2000 0x0 0x1000>;
+			reg-names = "cti-base";
+			device-name = "cti_dlct0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@4ad3000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4ad3000 0x0 0x1000>;
+			device-name = "dlct0-tpda";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlct0_tpda_out: endpoint {
+						remote-endpoint =
+						<&dlct0_funnel_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					dlct0_tpda_in0: endpoint {
+						remote-endpoint =
+						<&lpass_funnel_out0>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					dlct0_tpda_in2: endpoint {
+						remote-endpoint =
+						<&video_funnel_out0>;
+					};
+				};
+
+				port@9 {
+					reg = <9>;
+					dlct0_tpda_in9: endpoint {
+						remote-endpoint =
+						<&dlct1_funnel_out0>;
+					};
+				};
+
+				port@13 {
+					reg = <19>;
+					dlct0_tpda_in19: endpoint {
+						remote-endpoint =
+						<&prng_tpdm_out>;
+					};
+				};
+
+				port@14 {
+					reg = <20>;
+					dlct0_tpda_in20: endpoint {
+						remote-endpoint =
+						<&gcc_tpdm_out>;
+					};
+				};
+
+				port@15 {
+					reg = <21>;
+					dlct0_tpda_in21: endpoint {
+						remote-endpoint =
+						<&qm_tpdm_out>;
+					};
+				};
+
+				port@17 {
+					reg = <23>;
+					dlct0_tpda_in23: endpoint {
+						remote-endpoint =
+						<&rdpm_tpdm_out>;
+					};
+				};
+
+				port@19 {
+					reg = <25>;
+					dlct0_tpda_in25: endpoint {
+						remote-endpoint =
+						<&pimem_tpdm_out>;
+					};
+				};
+
+				port@1a {
+					reg = <26>;
+					dlct0_tpda_in26: endpoint {
+						remote-endpoint =
+						<&dlct0_tpdm0_out>;
+					};
+				};
+
+				port@1b {
+					reg = <27>;
+					dlct0_tpda_in27: endpoint {
+						remote-endpoint =
+						<&dlct0_tpdm1_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4ad4000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4ad4000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlct0_funnel_out: endpoint {
+						remote-endpoint =
+						<&funnel1_in5>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					dlct0_funnel_in0: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					dlct0_funnel_in1: endpoint {
+						remote-endpoint =
+						<&lpass_funnel_out1>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					dlct0_funnel_in4: endpoint {
+						remote-endpoint =
+						<&ddr_funnel5_out>;
+					};
+				};
+
+				port@6 {
+					reg = <6>;
+					dlct0_funnel_in6: endpoint {
+						remote-endpoint =
+						<&turing0_funnel_out>;
+					};
+				};
+			};
+		};
+
+		cti@4b00000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4b00000 0x0 0x1000>;
+			device-name = "cti_swao";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4b04000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4b04000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					aoss_funnel_out: endpoint {
+						remote-endpoint =
+						<&etf0_in>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@5 {
+					reg = <5>;
+					aoss_funnel_in5: endpoint {
+						remote-endpoint =
+						<&lpi_funnel_out>;
+					};
+				};
+
+				port@6 {
+					reg = <6>;
+					aoss_funnel_in6: endpoint {
+						remote-endpoint =
+						<&aoss_tpda_out>;
+					};
+				};
+
+				port@7 {
+					reg = <7>;
+					aoss_funnel_in7: endpoint {
+						remote-endpoint =
+						<&qdss_funnel_out>;
+					};
+				};
+			};
+		};
+
+		tmc_etf: tmc@4b05000 {
+			compatible = "arm,coresight-tmc", "arm,primecell";
+			reg = <0x0 0x4b05000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					etf0_out: endpoint {
+						remote-endpoint =
+						<&swao_rep_in>;
+					};
+				};
+			};
+
+			in-ports {
+				port {
+					etf0_in: endpoint {
+						remote-endpoint =
+						<&aoss_funnel_out>;
+					};
+				};
+			};
+		};
+
+		replicator@4b06000 {
+			compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+			reg = <0x0 0x4b06000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@1 {
+					reg = <1>;
+					swao_rep_out1: endpoint {
+						remote-endpoint =
+						<&eud_in>;
+					};
+				};
+			};
+
+			in-ports {
+				port {
+					swao_rep_in: endpoint {
+						remote-endpoint =
+						<&etf0_out>;
+					};
+				};
+			};
+		};
+
+		tpda@4b08000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4b08000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					aoss_tpda_out: endpoint {
+						remote-endpoint =
+						<&aoss_funnel_in6>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					aoss_tpda_in0: endpoint {
+						remote-endpoint =
+						<&aoss_tpdm0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					aoss_tpda_in1: endpoint {
+						remote-endpoint =
+						<&aoss_tpdm1_out>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					aoss_tpda_in2: endpoint {
+						remote-endpoint =
+						<&aoss_tpdm2_out>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+					aoss_tpda_in3: endpoint {
+						remote-endpoint =
+						<&aoss_tpdm3_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					aoss_tpda_in4: endpoint {
+						remote-endpoint =
+						<&aoss_tpdm4_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@4b09000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b09000 0x0 0x1000>;
+			device-name = "tpdm_swao_prio_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					aoss_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&aoss_tpda_in0>;
+					};
+				};
+			};
+		};
+
+		tpdm@4b0a000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b0a000 0x0 0x1000>;
+			device-name = "tpdm_swao_prio_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					aoss_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&aoss_tpda_in1>;
+					};
+				};
+			};
+		};
+
+		tpdm@4b0b000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b0b000 0x0 0x1000>;
+			device-name = "tpdm_swao_prio_2";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					aoss_tpdm2_out: endpoint {
+						remote-endpoint =
+						<&aoss_tpda_in2>;
+					};
+				};
+			};
+		};
+
+		tpdm@4b0c000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b0c000 0x0 0x1000>;
+			device-name = "tpdm_swao_prio_3";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					aoss_tpdm3_out: endpoint {
+						remote-endpoint =
+						<&aoss_tpda_in3>;
+					};
+				};
+			};
+		};
+
+		tpdm@4b0d000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b0d000 0x0 0x1000>;
+			device-name = "tpdm_swao_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					aoss_tpdm4_out: endpoint {
+						remote-endpoint =
+						<&aoss_tpda_in4>;
+					};
+				};
+			};
+		};
+
+		aoss_cti: cti@4b13000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4b13000 0x0 0x1000>;
+			device-name = "cti_aoss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@4b41000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4b41000 0x0 0x1000>;
+			device-name = "cti_lpi_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		tpdm@4b46000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4b46000 0x0 0x1000>;
+			device-name = "tpdm_lpass_lpi";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					lpi_tpdm_out: endpoint {
+						remote-endpoint =
+						<&lpi_funnel_in5>;
+					};
+				};
+			};
+		};
+
+		cti@4b4b000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4b4b000 0x0 0x1000>;
+			device-name = "cti_lpi_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+		};
+
+		cti@4b82000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4b82000 0x0 0x1000>;
+			device-name = "cti_turing0_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4b83000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4b83000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					turing0_funnel_out: endpoint {
+						remote-endpoint =
+						<&dlct0_funnel_in6>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@5 {
+					reg = <5>;
+					turing0_funnel_in5: endpoint {
+						remote-endpoint =
+						<&turing0_dup_funnel_out>;
+					};
+				};
+			};
+		};
+
+		cti@4b8b000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4b8b000 0x0 0x1000>;
+			device-name = "cti_turing0_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@4ba2000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4ba2000 0x0 0x1000>;
+			device-name = "cti_turing1_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpdm@4ba0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4ba0000 0x0 0x1000>;
+			device-name = "tpdm_turing_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					turing1_tpdm_out: endpoint {
+						remote-endpoint =
+						<&turing1_funnel_in0>;
+					};
+				};
+			};
+		};
+
+		funnel@4ba3000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4ba3000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					turing1_funnel_out: endpoint {
+						remote-endpoint =
+						<&gdsp_tpda_in19>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					turing1_funnel_in0: endpoint {
+						remote-endpoint =
+						<&turing1_tpdm_out>;
+					};
+				};
+			};
+		};
+
+		cti@4bab000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4bab000 0x0 0x1000>;
+			device-name = "cti_turing1_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		tpdm@4c10000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4c10000 0x0 0x1000>;
+			device-name = "tpdm_rdpm_mx";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					dlct1_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&dlct1_funnel_in0>;
+					};
+				};
+			};
+		};
+
+		tpdm@4c11000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4c11000 0x0 0x1000>;
+			device-name = "tpdm_rdpm";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					dlct1_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&dlct1_funnel_in1>;
+					};
+				};
+			};
+		};
+
+		funnel@4c12000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4c12000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					dlct1_funnel_out0: endpoint {
+						remote-endpoint =
+						<&dlct0_tpda_in9>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					dlct1_funnel_in0: endpoint {
+						remote-endpoint =
+						<&dlct1_tpdm0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					dlct1_funnel_in1: endpoint {
+						remote-endpoint =
+						<&dlct1_tpdm1_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4c24000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4c24000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			status = "disabled";
+
+			out-ports {
+				port {
+					titan_funnel_out: endpoint {
+						remote-endpoint =
+						<&dlmm_funnel_in1>;
+					};
+				};
+			};
+		};
+
+		tpdm@4c40000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4c40000 0x0 0x1000>;
+			device-name= "tpdm_dlhm";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					dlhm_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlhm_tpda_in31>;
+					};
+				};
+			};
+		};
+
+		cti@4c41000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4c41000 0x0 0x1000>;
+			device-name = "cti_dlhm_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		cti@4c42000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4c42000 0x0 0x1000>;
+			device-name = "cti_dlhm_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@4c43000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4c43000 0x0 0x1000>;
+			device-name = "dlhm-tpda";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlhm_tpda_out: endpoint {
+						remote-endpoint =
+						<&dlhm_funnel_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@9 {
+					reg = <9>;
+					dlhm_tpda_in9: endpoint {
+						remote-endpoint =
+						<&gfx_funnel1_out0>;
+					};
+				};
+
+				port@1f {
+					reg = <31>;
+					dlhm_tpda_in31: endpoint {
+						remote-endpoint =
+						<&dlhm_tpdm_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4c44000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4c44000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlhm_funnel_out: endpoint {
+						remote-endpoint =
+						<&funnel1_in6>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					dlhm_funnel_in0: endpoint {
+						remote-endpoint =
+						<&dlhm_tpda_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					dlhm_funnel_in4: endpoint {
+						remote-endpoint =
+						<&dlst_funnel_out>;
+					};
+				};
+
+				port@5 {
+					reg = <5>;
+					dlhm_funnel_in5: endpoint {
+						remote-endpoint =
+						<&gdsp_funnel_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@4c50000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4c50000 0x0 0x1000>;
+			device-name = "tpdm_dl_south";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					dlst_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlst_tpda_in10>;
+					};
+				};
+			};
+		};
+
+		cti@4c51000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4c51000 0x0 0x1000>;
+			device-name = "cti_dlst";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@4c52000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4c52000 0x0 0x1000>;
+			device-name = "dlst-tpda";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlst_tpda_out: endpoint {
+						remote-endpoint =
+						<&dlst_funnel_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					dlst_tpda_in0: endpoint {
+						remote-endpoint =
+						<&sdcc_tpdm_out>;
+					};
+				};
+
+				port@a {
+					reg = <10>;
+					dlst_tpda_in10: endpoint {
+						remote-endpoint =
+						<&dlst_tpdm_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4c53000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4c53000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					dlst_funnel_out: endpoint {
+						remote-endpoint =
+						<&dlhm_funnel_in4>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					dlst_funnel_in0: endpoint {
+						remote-endpoint =
+						<&dlst_tpda_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@4c60000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4c60000 0x0 0x1000>;
+			device-name = "tpdm_mdss_2";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					mdss1_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlmm_tpda_in8>;
+					};
+				};
+			};
+		};
+
+		cti@4c61000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4c61000 0x0 0x1000>;
+			device-name = "cti_mdss1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+			status = "disabled";
+		};
+
+		tpdm@4c70000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4c70000 0x0 0x1000>;
+			device-name = "tpdm_mdss_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					mdss0_tpdm_out: endpoint {
+						remote-endpoint =
+						<&dlmm_tpda_in5>;
+					};
+				};
+			};
+		};
+
+		cti@4c71000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4c71000 0x0 0x1000>;
+			device-name = "cti_mdss0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+			status = "disabled";
+		};
+
+		tpdm@4e00000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4e00000 0x0 0x1000>;
+			device-name = "tpdm_ddr";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					ddr_tpdm3_out: endpoint {
+						remote-endpoint =
+						<&ddr_tpda_in4>;
+					};
+				};
+			};
+		};
+
+		tpdm@4e01000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4e01000 0x0 0x1000>;
+			device-name = "tpdm_shrm";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					ddr_tpdm4_out: endpoint {
+						remote-endpoint =
+						<&ddr_tpda_in5>;
+					};
+				};
+			};
+		};
+
+		cti@4e02000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4e02000 0x0 0x1000>;
+			device-name = "cti_ddr_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@4e03000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x4e03000 0x0 0x1000>;
+			device-name = "ddr-tpda";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					ddr_tpda_out: endpoint {
+						remote-endpoint =
+						<&ddr_funnel5_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ddr_tpda_in0: endpoint {
+						remote-endpoint =
+						<&ddr_funnel0_out0>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					ddr_tpda_in1: endpoint {
+						remote-endpoint =
+						<&ddr_funnel1_out0>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					ddr_tpda_in2: endpoint {
+						remote-endpoint =
+						<&ddr_funnel2_out0>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					ddr_tpda_in4: endpoint {
+						remote-endpoint =
+						<&ddr_tpdm3_out>;
+					};
+				};
+
+				port@5 {
+					reg = <5>;
+					ddr_tpda_in5: endpoint {
+						remote-endpoint =
+						<&ddr_tpdm4_out>;
+					};
+				};
+			};
+		};
+
+		funnel@4e04000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4e04000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					ddr_funnel5_out: endpoint {
+						remote-endpoint =
+						<&dlct0_funnel_in4>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ddr_funnel5_in0: endpoint {
+						remote-endpoint =
+						<&ddr_tpda_out>;
+					};
+				};
+
+				port@5 {
+					reg = <5>;
+					ddr_funnel5_in5: endpoint {
+						remote-endpoint =
+						<&ddr_funnel3_out>;
+					};
+				};
+
+				port@6 {
+					reg = <6>;
+					ddr_funnel5_in6: endpoint {
+						remote-endpoint =
+						<&ddr_funnel4_out>;
+					};
+				};
+			};
+		};
+
+		cti@4e0c000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4e0c000 0x0 0x1000>;
+			device-name = "cti_ddr_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4e0d000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4e0d000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					ddr_funnel3_out: endpoint {
+						remote-endpoint =
+						<&ddr_funnel5_in5>;
+					};
+				};
+			};
+		};
+
+		tpdm@4e10000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4e10000 0x0 0x1000>;
+			device-name = "tpdm_ddr_ch0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					ddr_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&ddr_funnel0_in0>;
+					};
+				};
+			};
+		};
+
+		cti@4e11000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4e11000 0x0 0x1000>;
+			device-name = "cti_ddr_2";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4e12000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4e12000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ddr_funnel0_out0: endpoint {
+						remote-endpoint =
+						<&ddr_tpda_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ddr_funnel0_in0: endpoint {
+						remote-endpoint =
+						<&ddr_tpdm0_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@4e20000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4e20000 0x0 0x1000>;
+			device-name = "tpdm_ddr_ch1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					ddr_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&ddr_funnel1_in0>;
+					};
+				};
+			};
+		};
+
+		cti@4e21000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4e21000 0x0 0x1000>;
+			device-name = "cti_ddr_3";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4e22000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4e22000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ddr_funnel1_out0: endpoint {
+						remote-endpoint =
+						<&ddr_tpda_in1>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ddr_funnel1_in0: endpoint {
+						remote-endpoint =
+						<&ddr_tpdm1_out>;
+					};
+				};
+			};
+		};
+
+		cti@4e34000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4e34000 0x0 0x1000>;
+			device-name = "cti_ddr_4";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4e35000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4e35000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					ddr_funnel4_out: endpoint {
+						remote-endpoint =
+						<&ddr_funnel5_in6>;
+					};
+				};
+			};
+		};
+
+		tpdm@4e40000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x4e40000 0x0 0x1000>;
+			device-name = "tpdm_ddr_ch2";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					ddr_tpdm2_out: endpoint {
+						remote-endpoint =
+						<&ddr_funnel2_in0>;
+					};
+				};
+			};
+		};
+
+		cti@4e41000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x4e41000 0x0 0x1000>;
+			device-name = "cti_ddr_5";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		funnel@4e42000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x4e42000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ddr_funnel2_out0: endpoint {
+						remote-endpoint =
+						<&ddr_tpda_in2>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					ddr_funnel2_in0: endpoint {
+						remote-endpoint =
+						<&ddr_tpdm2_out>;
+					};
+				};
+			};
+		};
+
+		etm@6040000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6040000 0x0 0x1000>;
+			cpu = <&CPU0>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm0_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in0>;
+					};
+				};
+			};
+		};
+
+		etm@6140000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6140000 0x0 0x1000>;
+			cpu = <&CPU1>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm1_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in1>;
+					};
+				};
+			};
+		};
+
+		etm@6240000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6240000 0x0 0x1000>;
+			cpu = <&CPU2>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm2_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in2>;
+					};
+				};
+			};
+		};
+
+		etm@6340000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6340000 0x0 0x1000>;
+			cpu = <&CPU3>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm3_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in3>;
+					};
+				};
+			};
+		};
+
+		etm@6440000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6440000 0x0 0x1000>;
+			cpu = <&CPU4>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm4_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in4>;
+					};
+				};
+			};
+		};
+
+		etm@6540000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6540000 0x0 0x1000>;
+			cpu = <&CPU5>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm5_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in5>;
+					};
+				};
+			};
+		};
+
+		etm@6640000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6640000 0x0 0x1000>;
+			cpu = <&CPU6>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm6_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in6>;
+					};
+				};
+			};
+		};
+
+		etm@6740000 {
+			compatible = "arm,primecell";
+			reg = <0x0 0x6740000 0x0 0x1000>;
+			cpu = <&CPU7>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			arm,coresight-loses-context-with-cpu;
+			qcom,skip-power-up;
+
+			out-ports {
+				port {
+					etm7_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_in7>;
+					};
+				};
+			};
+		};
+
+		funnel@6800000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x6800000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					apss_funnel0_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel1_in0>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					apss_funnel0_in0: endpoint {
+						remote-endpoint =
+						<&etm0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					apss_funnel0_in1: endpoint {
+						remote-endpoint =
+						<&etm1_out>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					apss_funnel0_in2: endpoint {
+						remote-endpoint =
+						<&etm2_out>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+					apss_funnel0_in3: endpoint {
+						remote-endpoint =
+						<&etm3_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					apss_funnel0_in4: endpoint {
+						remote-endpoint =
+						<&etm4_out>;
+					};
+				};
+
+				port@5 {
+					reg = <5>;
+					apss_funnel0_in5: endpoint {
+						remote-endpoint =
+						<&etm5_out>;
+					};
+				};
+
+				port@6 {
+					reg = <6>;
+					apss_funnel0_in6: endpoint {
+						remote-endpoint =
+						<&etm6_out>;
+					};
+				};
+
+				port@7 {
+					reg = <7>;
+					apss_funnel0_in7: endpoint {
+						remote-endpoint =
+						<&etm7_out>;
+					};
+				};
+			};
+		};
+
+		funnel@6810000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x6810000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					apss_funnel1_out: endpoint {
+						remote-endpoint =
+						<&funnel1_in4>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					apss_funnel1_in0: endpoint {
+						remote-endpoint =
+						<&apss_funnel0_out>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+					apss_funnel1_in3: endpoint {
+						remote-endpoint =
+						<&apss_tpda_out>;
+					};
+				};
+			};
+		};
+
+		cti@682b000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x682b000 0x0 0x1000>;
+			device-name = "cti_apss_0";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		tpdm@6860000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x6860000 0x0 0x1000>;
+			device-name = "tpdm_actpm";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					apss_tpdm3_out: endpoint {
+						remote-endpoint =
+						<&apss_tpda_in3>;
+					};
+				};
+			};
+		};
+
+		tpdm@6861000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x6861000 0x0 0x1000>;
+			device-name = "tpdm_apss";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					apss_tpdm4_out: endpoint {
+						remote-endpoint =
+						<&apss_tpda_in4>;
+					};
+				};
+			};
+		};
+
+		cti@6862000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x6862000 0x0 0x1000>;
+			device-name = "cti_apss_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,extended_cti;
+		};
+
+		tpda@6863000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x6863000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					apss_tpda_out: endpoint {
+						remote-endpoint =
+						<&apss_funnel1_in3>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					apss_tpda_in0: endpoint {
+						remote-endpoint =
+						<&apss_tpdm0_out>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					apss_tpda_in1: endpoint {
+						remote-endpoint =
+						<&apss_tpdm1_out>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+					apss_tpda_in3: endpoint {
+						remote-endpoint =
+						<&apss_tpdm3_out>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					apss_tpda_in4: endpoint {
+						remote-endpoint =
+						<&apss_tpdm4_out>;
+					};
+				};
+			};
+		};
+
+		tpdm@68a0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x68a0000 0x0 0x1000>;
+			device-name = "tpdm_llm_silver";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					apss_tpdm0_out: endpoint {
+						remote-endpoint =
+						<&apss_tpda_in0>;
+					};
+				};
+			};
+		};
+
+		tpdm@68b0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x68b0000 0x0 0x1000>;
+			device-name = "tpdm_llm_gold";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					apss_tpdm1_out: endpoint {
+						remote-endpoint =
+						<&apss_tpda_in1>;
+					};
+				};
+			};
+		};
+
+		cti@68e0000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x68e0000 0x0 0x1000>;
+			device-name = "cti_apss_2";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@68f0000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x68f0000 0x0 0x1000>;
+			device-name = "cti_apss_3";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6900000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x6900000 0x0 0x1000>;
+			device-name = "cti_apss_4";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		lpass_ag_noc: interconnect-lpass-ag-noc@3c40000 {
+			compatible = "qcom,sa8775p-lpass-ag-noc";
+			reg = <0x0 0x03c40000 0x0 0x17200>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
 		usb_0_hsphy: phy@88e4000 {
 			compatible = "qcom,sa8775p-usb-hs-phy",
 				     "qcom,usb-snps-hs-5nm-phy";
@@ -1596,6 +6080,20 @@
 			status = "disabled";
 		};
 
+		dc_noc: interconnect-dc-noc@90e0000 {
+			compatible = "qcom,sa8775p-dc-noc";
+			reg = <0x0 0x090e0000 0x0 0x5080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		gem_noc: interconnect-gem-noc@9100000 {
+			compatible = "qcom,sa8775p-gem-noc";
+			reg = <0x0 0x09100000 0x0 0xf6080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
 		usb_0: usb@a6f8800 {
 			compatible = "qcom,sa8775p-dwc3", "qcom,dwc3";
 			reg = <0 0x0a6f8800 0 0x400>;
@@ -1615,10 +6113,12 @@
 			assigned-clock-rates = <19200000>, <200000000>;
 
 			interrupts-extended = <&intc GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 261 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 12 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
 					  "dp_hs_phy_irq",
 					  "dm_hs_phy_irq",
 					  "ss_phy_irq";
@@ -1643,6 +6143,9 @@
 				iommus = <&apps_smmu 0x080 0x0>;
 				phys = <&usb_0_hsphy>, <&usb_0_qmpphy>;
 				phy-names = "usb2-phy", "usb3-phy";
+				snps,dis-u1-entry-quirk;
+				snps,dis-u2-entry-quirk;
+				role-switch;
 			};
 		};
 
@@ -1702,10 +6205,12 @@
 			assigned-clock-rates = <19200000>, <200000000>;
 
 			interrupts-extended = <&intc GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 351 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc 8 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 7 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 13 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
 					  "dp_hs_phy_irq",
 					  "dm_hs_phy_irq",
 					  "ss_phy_irq";
@@ -1730,6 +6235,8 @@
 				iommus = <&apps_smmu 0x0a0 0x0>;
 				phys = <&usb_1_hsphy>, <&usb_1_qmpphy>;
 				phy-names = "usb2-phy", "usb3-phy";
+				snps,dis-u1-entry-quirk;
+				snps,dis-u2-entry-quirk;
 			};
 		};
 
@@ -1765,9 +6272,11 @@
 			assigned-clock-rates = <19200000>, <200000000>;
 
 			interrupts-extended = <&intc GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc 10 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
 					  "dp_hs_phy_irq",
 					  "dm_hs_phy_irq";
 
@@ -1791,6 +6300,8 @@
 				iommus = <&apps_smmu 0x020 0x0>;
 				phys = <&usb_2_hsphy>;
 				phy-names = "usb2-phy";
+				snps,dis-u1-entry-quirk;
+				snps,dis-u2-entry-quirk;
 			};
 		};
 
@@ -1800,6 +6311,103 @@
 			#hwlock-cells = <1>;
 		};
 
+		tcsr: syscon@1fc0000 {
+			compatible = "qcom,sa8775p-tcsr", "syscon";
+			reg = <0x0 0x1fc0000 0x0 0x30000>;
+		};
+
+		gpu: gpu@3d00000 {
+			compatible = "qcom,adreno-663.0", "qcom,adreno";
+			reg = <0x0 0x03d00000 0x0 0x40000>,
+			      <0x0 0x03d9e000 0x0 0x1000>,
+			      <0x0 0x03d61000 0x0 0x800>;
+			reg-names = "kgsl_3d0_reg_memory",
+				    "cx_mem",
+				    "cx_dbgc";
+			interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>;
+			iommus = <&adreno_smmu 0 0xc00>,
+				 <&adreno_smmu 1 0xc00>;
+			operating-points-v2 = <&gpu_opp_table>;
+			qcom,gmu = <&gmu>;
+			interconnects = <&gem_noc MASTER_GFX3D QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "gfx-mem";
+			#cooling-cells = <2>;
+
+			gpu_zap_shader: zap-shader {
+				memory-region = <&pil_gpu_mem>;
+				firmware-name = "qcom/sa8775p/a663_zap.mbn";
+			};
+
+			gpu_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-405000000 {
+					opp-hz = /bits/ 64 <405000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+					opp-peak-kBps = <5285156>;
+				};
+
+				opp-676000000 {
+					opp-hz = /bits/ 64 <676000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+					opp-peak-kBps = <8171875>;
+				};
+
+				opp-778000000 {
+					opp-hz = /bits/ 64 <778000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+					opp-peak-kBps = <10687500>;
+				};
+
+				opp-800000000 {
+					opp-hz = /bits/ 64 <800000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+					opp-peak-kBps = <12484375>;
+				};
+			};
+		};
+
+		gmu: gmu@3d6a000 {
+			compatible = "qcom,adreno-gmu-663.0", "qcom,adreno-gmu";
+			reg = <0x0 0x03d6a000 0x0 0x34000>,
+			      <0x0 0x03de0000 0x0 0x10000>,
+			      <0x0 0x0b290000 0x0 0x10000>;
+			reg-names = "gmu", "rscc", "gmu_pdc";
+			interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "hfi", "gmu";
+			clocks = <&gpucc GPU_CC_CX_GMU_CLK>,
+				 <&gpucc GPU_CC_CXO_CLK>,
+				 <&gcc GCC_DDRSS_GPU_AXI_CLK>,
+				 <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
+				 <&gpucc GPU_CC_AHB_CLK>,
+				 <&gpucc GPU_CC_HUB_CX_INT_CLK>,
+				 <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>;
+			clock-names = "gmu",
+				      "cxo",
+				      "axi",
+				      "memnoc",
+				      "ahb",
+				      "hub",
+				      "smmu_vote";
+			power-domains = <&gpucc GPU_CC_CX_GDSC>,
+					<&gpucc GPU_CC_GX_GDSC>;
+			power-domain-names = "cx",
+					     "gx";
+			iommus = <&adreno_smmu 5 0xc00>;
+			operating-points-v2 = <&gmu_opp_table>;
+
+			gmu_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-200000000 {
+					opp-hz = /bits/ 64 <200000000>;
+					opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
+				};
+			};
+		};
+
 		gpucc: clock-controller@3d90000 {
 			compatible = "qcom,sa8775p-gpucc";
 			reg = <0x0 0x03d90000 0x0 0xa000>;
@@ -1821,6 +6429,9 @@
 			#iommu-cells = <2>;
 			#global-interrupts = <2>;
 			dma-coherent;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
 			power-domains = <&gpucc GPU_CC_CX_GDSC>;
 			clocks = <&gcc GCC_GPU_MEMNOC_GFX_CLK>,
 				 <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>,
@@ -1848,6 +6459,20 @@
 				     <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>;
+
+			gfx_0_tbu: gfx_0_tbu@3dd1000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x3dd1000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x0 0x400>;
+			};
+
+			gfx_1_tbu: gfx_1_tbu@3dd9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x3dd9000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x400 0x400>;
+			};
 		};
 
 		serdes0: phy@8901000 {
@@ -1868,6 +6493,927 @@
 			status = "disabled";
 		};
 
+		pmu@9091000 {
+			compatible = "qcom,sa8775p-llcc-bwmon", "qcom,sc7280-llcc-bwmon";
+			reg = <0x0 0x9091000 0x0 0x1000>;
+			interrupts = <GIC_SPI 620 IRQ_TYPE_LEVEL_HIGH>;
+			interconnects = <&mc_virt MASTER_LLCC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+			operating-points-v2 = <&llcc_bwmon_opp_table>;
+
+			llcc_bwmon_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-0 {
+					opp-peak-kBps = <762000>;
+				};
+
+				opp-1 {
+					opp-peak-kBps = <1720000>;
+				};
+
+				opp-2 {
+					opp-peak-kBps = <2086000>;
+				};
+
+				opp-3 {
+					opp-peak-kBps = <2601000>;
+				};
+
+				opp-4 {
+					opp-peak-kBps = <2929000>;
+				};
+
+				opp-5 {
+					opp-peak-kBps = <5931000>;
+				};
+
+				opp-6 {
+					opp-peak-kBps = <6515000>;
+				};
+
+				opp-7 {
+					opp-peak-kBps = <7984000>;
+				};
+
+				opp-8 {
+					opp-peak-kBps = <10437000>;
+				};
+
+				opp-9 {
+					opp-peak-kBps = <12195000>;
+				};
+			};
+		};
+
+		pmu@90b5400 {
+			compatible = "qcom,sa8775p-cpu-bwmon", "qcom,sdm845-bwmon";
+			reg = <0x0 0x90b5400 0x0 0x600>;
+			interrupts = <GIC_SPI 581 IRQ_TYPE_LEVEL_HIGH>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+			operating-points-v2 = <&cpu_bwmon_opp_table>;
+
+			cpu_bwmon_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-0 {
+					opp-peak-kBps = <9155000>;
+				};
+
+				opp-1 {
+					opp-peak-kBps = <12298000>;
+				};
+
+				opp-2 {
+					opp-peak-kBps = <14236000>;
+				};
+
+				opp-3 {
+					opp-peak-kBps = <16265000>;
+				};
+			};
+
+		};
+
+		pmu@90b6400 {
+			compatible = "qcom,sa8775p-cpu-bwmon", "qcom,sdm845-bwmon";
+			reg = <0x0 0x90b6400 0x0 0x600>;
+			interrupts = <GIC_SPI 581 IRQ_TYPE_LEVEL_HIGH>;
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ACTIVE_ONLY>;
+
+			operating-points-v2 = <&cpu_bwmon_opp_table>;
+		};
+
+		llcc: system-cache-controller@9200000 {
+			compatible = "qcom,sa8775p-llcc";
+			reg = <0x0 0x09200000 0x0 0x80000>,
+			      <0x0 0x09300000 0x0 0x80000>,
+			      <0x0 0x09400000 0x0 0x80000>,
+			      <0x0 0x09500000 0x0 0x80000>,
+			      <0x0 0x09600000 0x0 0x80000>,
+			      <0x0 0x09700000 0x0 0x80000>,
+			      <0x0 0x09a00000 0x0 0x80000>;
+			reg-names = "llcc0_base",
+				    "llcc1_base",
+				    "llcc2_base",
+				    "llcc3_base",
+				    "llcc4_base",
+				    "llcc5_base",
+				    "llcc_broadcast_base";
+			interrupts = <GIC_SPI 580 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
+		iris: video-codec@aa00000 {
+			compatible = "qcom,sa8775p-iris", "qcom,sm8550-iris";
+
+			reg = <0x0 0x0aa00000 0x0 0xf0000>;
+			interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+
+			power-domains = <&videocc VIDEO_CC_MVS0C_GDSC>,
+					<&videocc VIDEO_CC_MVS0_GDSC>,
+					<&rpmhpd SA8775P_MX>,
+					<&rpmhpd SA8775P_MMCX>;
+			power-domain-names = "venus",
+					     "vcodec0",
+					     "mxc",
+					     "mmcx";
+			operating-points-v2 = <&iris_opp_table>;
+
+			clocks = <&gcc GCC_VIDEO_AXI0_CLK>,
+				 <&videocc VIDEO_CC_MVS0C_CLK>,
+				 <&videocc VIDEO_CC_MVS0_CLK>;
+			clock-names = "iface",
+				      "core",
+				      "vcodec0_core";
+
+			interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &config_noc SLAVE_VENUS_CFG QCOM_ICC_TAG_ACTIVE_ONLY>,
+					<&mmss_noc MASTER_VIDEO_P0 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "cpu-cfg",
+					     "video-mem";
+
+			memory-region = <&pil_video_mem>;
+
+			resets = <&gcc GCC_VIDEO_AXI0_CLK_ARES>;
+			reset-names = "bus";
+
+			iommus = <&apps_smmu 0x0880 0x0400>,
+				 <&apps_smmu 0x0887 0x0400>;
+			dma-coherent;
+
+			status = "disabled";
+
+			iris_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-366000000 {
+					opp-hz = /bits/ 64 <366000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>,
+							<&rpmhpd_opp_svs_l1>;
+				};
+
+				opp-444000000 {
+					opp-hz = /bits/ 64 <444000000>;
+					required-opps = <&rpmhpd_opp_nom>,
+							<&rpmhpd_opp_nom>;
+				};
+
+				opp-533000000 {
+					opp-hz = /bits/ 64 <533000000>;
+					required-opps = <&rpmhpd_opp_turbo>,
+							<&rpmhpd_opp_turbo>;
+				};
+
+				opp-560000000 {
+					opp-hz = /bits/ 64 <560000000>;
+					required-opps = <&rpmhpd_opp_turbo_l1>,
+							<&rpmhpd_opp_turbo_l1>;
+				};
+			};
+		};
+
+		videocc: clock-controller@abf0000 {
+			compatible = "qcom,sa8775p-videocc";
+			reg = <0x0 0x0abf0000 0x0 0x10000>;
+			clocks = <&gcc GCC_VIDEO_AHB_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK_A>,
+				 <&sleep_clk>;
+			power-domains = <&rpmhpd SA8775P_MMCX>;
+			required-opps = <&rpmhpd_opp_low_svs>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
+		camss: isp@ac7a000 {
+			compatible = "qcom,sa8775p-camss";
+
+			reg = <0x0 0x0ac7a000 0x0 0x0f01>,
+			      <0x0 0x0ac7c000 0x0 0x0f01>,
+			      <0x0 0x0ac84000 0x0 0x0f01>,
+			      <0x0 0x0ac88000 0x0 0x0f01>,
+			      <0x0 0x0ac8c000 0x0 0x0f01>,
+			      <0x0 0x0ac90000 0x0 0x0f01>,
+			      <0x0 0x0ac94000 0x0 0x0f01>,
+			      <0x0 0x0ac78000 0x0 0x1000>,
+			      <0x0 0x0ac9c000 0x0 0x2000>,
+			      <0x0 0x0ac9e000 0x0 0x2000>,
+			      <0x0 0x0aca0000 0x0 0x2000>,
+			      <0x0 0x0aca2000 0x0 0x2000>,
+			      <0x0 0x0acac000 0x0 0x0400>,
+			      <0x0 0x0acad000 0x0 0x0400>,
+			      <0x0 0x0acae000 0x0 0x0400>,
+			      <0x0 0x0ac4d000 0x0 0xd000>,
+			      <0x0 0x0ac5a000 0x0 0xd000>,
+			      <0x0 0x0ac85000 0x0 0x0d00>,
+			      <0x0 0x0ac89000 0x0 0x0d00>,
+			      <0x0 0x0ac8d000 0x0 0x0d00>,
+			      <0x0 0x0ac91000 0x0 0x0d00>,
+			      <0x0 0x0ac95000 0x0 0x0d00>;
+			reg-names = "csid0",
+				    "csid1",
+				    "csid_lite0",
+				    "csid_lite1",
+				    "csid_lite2",
+				    "csid_lite3",
+				    "csid_lite4",
+				    "csid_top",
+				    "csiphy0",
+				    "csiphy1",
+				    "csiphy2",
+				    "csiphy3",
+				    "tpg0",
+				    "tpg1",
+				    "tpg2",
+				    "vfe0",
+				    "vfe1",
+				    "vfe_lite0",
+				    "vfe_lite1",
+				    "vfe_lite2",
+				    "vfe_lite3",
+				    "vfe_lite4";
+
+			clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+				 <&camcc CAM_CC_CCI_0_CLK>,
+				 <&camcc CAM_CC_CCI_1_CLK>,
+				 <&camcc CAM_CC_CCI_2_CLK>,
+				 <&camcc CAM_CC_CCI_3_CLK>,
+				 <&camcc CAM_CC_CORE_AHB_CLK>,
+				 <&camcc CAM_CC_CPAS_AHB_CLK>,
+				 <&camcc CAM_CC_CPAS_FAST_AHB_CLK>,
+				 <&camcc CAM_CC_CPAS_IFE_0_CLK>,
+				 <&camcc CAM_CC_CPAS_IFE_1_CLK>,
+				 <&camcc CAM_CC_CPAS_IFE_LITE_CLK>,
+				 <&camcc CAM_CC_CPHY_RX_CLK_SRC>,
+				 <&camcc CAM_CC_CSID_CLK>,
+				 <&camcc CAM_CC_CSID_CSIPHY_RX_CLK>,
+				 <&camcc CAM_CC_CSIPHY0_CLK>,
+				 <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY1_CLK>,
+				 <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY2_CLK>,
+				 <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY3_CLK>,
+				 <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
+				 <&gcc   GCC_CAMERA_HF_AXI_CLK>,
+				 <&gcc   GCC_CAMERA_SF_AXI_CLK>,
+				 <&gcc   GCC_CAMERA_AHB_CLK>,
+				 <&camcc CAM_CC_ICP_AHB_CLK>,
+				 <&camcc CAM_CC_SLOW_AHB_CLK_SRC>,
+				 <&camcc CAM_CC_IFE_0_CLK>,
+				 <&camcc CAM_CC_IFE_0_FAST_AHB_CLK>,
+				 <&camcc CAM_CC_IFE_1_CLK>,
+				 <&camcc CAM_CC_IFE_1_FAST_AHB_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_AHB_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_CSID_CLK>;
+			clock-names = "camnoc_axi",
+				      "cci_0",
+				      "cci_1",
+				      "cci_2",
+				      "cci_3",
+				      "core_ahb",
+				      "cpas_ahb",
+				      "cpas_fast_ahb_clk",
+				      "cpas_vfe0",
+				      "cpas_vfe1",
+				      "cpas_vfe_lite",
+				      "cphy_rx_clk",
+				      "csid",
+				      "csid_csiphy_rx",
+				      "csiphy0",
+				      "csiphy0_timer",
+				      "csiphy1",
+				      "csiphy1_timer",
+				      "csiphy2",
+				      "csiphy2_timer",
+				      "csiphy3",
+				      "csiphy3_timer",
+				      "gcc_axi_hf",
+				      "gcc_axi_sf",
+				      "gcc_camera_ahb",
+				      "icp_ahb",
+				      "slow_ahb_src",
+				      "vfe0",
+				      "vfe0_fast_ahb",
+				      "vfe1",
+				      "vfe1_fast_ahb",
+				      "vfe_lite",
+				      "vfe_lite_ahb",
+				      "vfe_lite_cphy_rx",
+				      "vfe_lite_csid";
+
+			interconnects = <&gem_noc MASTER_APPSS_PROC 0
+					 &config_noc SLAVE_CAMERA_CFG 0>,
+					<&mmss_noc MASTER_CAMNOC_HF 0 &mc_virt SLAVE_EBI1 0>,
+					<&mmss_noc MASTER_CAMNOC_SF 0 &mc_virt SLAVE_EBI1 0>;
+			interconnect-names = "ahb", "hf_0", "sf_0";
+
+			interrupts = <GIC_SPI 565 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 564 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 759 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 758 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 604 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 545 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 546 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 547 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 761 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 760 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 605 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "csid0",
+					  "csid1",
+					  "csid-lite0",
+					  "csid-lite1",
+					  "csid-lite2",
+					  "csid-lite3",
+					  "csid-lite4",
+					  "csiphy0",
+					  "csiphy1",
+					  "csiphy2",
+					  "csiphy3",
+					  "tpg0",
+					  "tpg1",
+					  "tpg2",
+					  "vfe0",
+					  "vfe1",
+					  "vfe-lite0",
+					  "vfe-lite1",
+					  "vfe-lite2",
+					  "vfe-lite3",
+					  "vfe-lite4";
+
+			iommus = <&apps_smmu 0x3400 0x20>;
+
+			power-domains = <&camcc CAM_CC_TITAN_TOP_GDSC>;
+			power-domain-names = "top";
+			operating-points-v2 = <&camss_opp_table>;
+
+			status = "disabled";
+
+			camss_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-400000000 {
+					opp-hz = /bits/ 64 <400000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+				};
+
+				opp-480000000 {
+					opp-hz = /bits/ 64 <480000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>;
+				};
+
+				opp-600000000 {
+					opp-hz = /bits/ 64 <600000000>;
+					required-opps = <&rpmhpd_opp_nom>;
+				};
+			};
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+				};
+
+				port@1 {
+					reg = <1>;
+				};
+
+				port@2 {
+					reg = <2>;
+				};
+
+				port@3 {
+					reg = <3>;
+				};
+			};
+		};
+
+		camcc: clock-controller@ade0000 {
+			compatible = "qcom,sa8775p-camcc";
+			reg = <0x0 0x0ade0000 0x0 0x20000>;
+			clocks = <&gcc GCC_CAMERA_AHB_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK_A>,
+				 <&sleep_clk>;
+			power-domains = <&rpmhpd SA8775P_MMCX>,
+					<&rpmhpd SA8775P_MXC>;
+			required-opps = <&rpmhpd_opp_low_svs>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
+		mdss0: display-subsystem@ae00000 {
+			compatible = "qcom,sa8775p-mdss";
+			reg = <0x0 0x0ae00000 0x0 0x1000>;
+			reg-names = "mdss";
+
+			/* same path used twice */
+			interconnects = <&mmss_noc MASTER_MDP0 0 &mc_virt SLAVE_EBI1 0>,
+					<&mmss_noc MASTER_MDP1 0 &mc_virt SLAVE_EBI1 0>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY
+					 &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ACTIVE_ONLY>;
+			interconnect-names = "mdp0-mem",
+					     "mdp1-mem",
+					     "cpu-cfg";
+
+			power-domains = <&dispcc0 MDSS_DISP_CC_MDSS_CORE_GDSC>;
+
+			clocks = <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>,
+				 <&gcc GCC_DISP_HF_AXI_CLK>,
+				 <&dispcc0 MDSS_DISP_CC_MDSS_MDP_CLK>;
+
+			interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+
+			iommus = <&apps_smmu 0x1000 0x402>;
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			status = "disabled";
+
+			mdss0_mdp: display-controller@ae01000 {
+				compatible = "qcom,sa8775p-dpu";
+				reg = <0x0 0x0ae01000 0x0 0x8f000>,
+				      <0x0 0x0aeb0000 0x0 0x2008>;
+				reg-names = "mdp", "vbif";
+
+				clocks = <&gcc GCC_DISP_HF_AXI_CLK>,
+					<&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>,
+					<&dispcc0 MDSS_DISP_CC_MDSS_MDP_LUT_CLK>,
+					<&dispcc0 MDSS_DISP_CC_MDSS_MDP_CLK>,
+					<&dispcc0 MDSS_DISP_CC_MDSS_VSYNC_CLK>;
+				clock-names = "bus",
+					      "iface",
+					      "lut",
+					      "core",
+					      "vsync";
+
+				assigned-clocks = <&dispcc0 MDSS_DISP_CC_MDSS_VSYNC_CLK>;
+				assigned-clock-rates = <19200000>;
+
+				operating-points-v2 = <&mdss0_mdp_opp_table>;
+				power-domains = <&rpmhpd SA8775P_MMCX>;
+
+				interrupt-parent = <&mdss0>;
+				interrupts = <0>;
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port@0 {
+						reg = <0>;
+						dpu_intf0_out: endpoint {
+							remote-endpoint = <&mdss0_dp0_in>;
+						};
+					};
+
+					port@1 {
+						reg = <1>;
+						dpu_intf4_out: endpoint {
+							remote-endpoint = <&mdss0_dp1_in>;
+						};
+					};
+
+					port@2 {
+						reg = <2>;
+						dpu_intf1_out: endpoint {
+							remote-endpoint = <&mdss0_dsi0_in>;
+						};
+					};
+
+					port@3 {
+						reg = <3>;
+						dpu_intf2_out: endpoint {
+							remote-endpoint = <&mdss0_dsi1_in>;
+						};
+					};
+				};
+
+				mdss0_mdp_opp_table: opp-table {
+					compatible = "operating-points-v2";
+
+					opp-375000000 {
+						opp-hz = /bits/ 64 <375000000>;
+						required-opps = <&rpmhpd_opp_svs_l1>;
+					};
+
+					opp-500000000 {
+						opp-hz = /bits/ 64 <500000000>;
+						required-opps = <&rpmhpd_opp_nom>;
+					};
+
+					opp-575000000 {
+						opp-hz = /bits/ 64 <575000000>;
+						required-opps = <&rpmhpd_opp_turbo>;
+					};
+
+					opp-650000000 {
+						opp-hz = /bits/ 64 <650000000>;
+						required-opps = <&rpmhpd_opp_turbo_l1>;
+					};
+				};
+			};
+
+			mdss0_dsi0: dsi@ae94000 {
+				compatible = "qcom,mdss-dsi-ctrl";
+				reg = <0x0 0x0ae94000 0x0 0x400>;
+				reg-names = "dsi_ctrl";
+
+				interrupt-parent = <&mdss0>;
+				interrupts = <4>;
+
+				clocks = <&dispcc0 MDSS_DISP_CC_MDSS_BYTE0_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_BYTE0_INTF_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_PCLK0_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_ESC0_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>,
+					 <&gcc GCC_DISP_HF_AXI_CLK>;
+				clock-names = "byte",
+					      "byte_intf",
+					      "pixel",
+					      "core",
+					      "iface",
+					      "bus";
+
+				assigned-clocks = <&dispcc0 MDSS_DISP_CC_MDSS_BYTE0_CLK_SRC>,
+						  <&dispcc0 MDSS_DISP_CC_MDSS_PCLK0_CLK_SRC>;
+				assigned-clock-parents = <&mdss0_dsi0_phy 0>,
+							 <&mdss0_dsi0_phy 1>;
+
+				phys = <&mdss0_dsi0_phy>;
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port@0 {
+						reg = <0>;
+						mdss0_dsi0_in: endpoint {
+							remote-endpoint = <&dpu_intf1_out>;
+						};
+					};
+
+					port@1 {
+						reg = <1>;
+						mdss0_dsi0_out: endpoint {
+						};
+					};
+				};
+			};
+
+			mdss0_dsi0_phy: phy@ae94400 {
+				compatible = "qcom,sa8775p-dsi-phy-5nm";
+				reg = <0x0 0x0ae94400 0x0 0x200>,
+				      <0x0 0x0ae94600 0x0 0x280>,
+				      <0x0 0x0ae94900 0x0 0x27c>;
+				reg-names = "dsi_phy",
+					    "dsi_phy_lane",
+					    "dsi_pll";
+
+				#clock-cells = <1>;
+				#phy-cells = <0>;
+
+				clocks = <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>,
+					 <&rpmhcc RPMH_CXO_CLK>;
+				clock-names = "iface", "ref";
+
+				status = "disabled";
+			};
+
+			mdss0_dsi1: dsi@ae96000 {
+				compatible = "qcom,mdss-dsi-ctrl";
+				reg = <0x0 0x0ae96000 0x0 0x400>;
+				reg-names = "dsi_ctrl";
+
+				interrupt-parent = <&mdss0>;
+				interrupts = <5>;
+
+
+				clocks = <&dispcc0 MDSS_DISP_CC_MDSS_BYTE1_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_BYTE1_INTF_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_PCLK1_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_ESC1_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>,
+					 <&gcc GCC_DISP_HF_AXI_CLK>;
+				clock-names = "byte",
+					      "byte_intf",
+					      "pixel",
+					      "core",
+					      "iface",
+					      "bus";
+
+				assigned-clocks = <&dispcc0 MDSS_DISP_CC_MDSS_BYTE1_CLK_SRC>,
+						  <&dispcc0 MDSS_DISP_CC_MDSS_PCLK1_CLK_SRC>;
+				assigned-clock-parents = <&mdss0_dsi1_phy 0>,
+							 <&mdss0_dsi1_phy 1>;
+
+				phys = <&mdss0_dsi1_phy>;
+
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				status = "disabled";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port@0 {
+						reg = <0>;
+						mdss0_dsi1_in: endpoint {
+							remote-endpoint = <&dpu_intf2_out>;
+						};
+					};
+
+					port@1 {
+						reg = <1>;
+						mdss0_dsi1_out: endpoint {
+						};
+					};
+				};
+			};
+
+			mdss0_dsi1_phy: phy@ae96400 {
+				compatible = "qcom,sa8775p-dsi-phy-5nm";
+				reg = <0x0 0x0ae96400 0x0 0x200>,
+				      <0x0 0x0ae96600 0x0 0x280>,
+				      <0x0 0x0ae96900 0x0 0x27c>;
+				reg-names = "dsi_phy",
+					    "dsi_phy_lane",
+					    "dsi_pll";
+
+				#clock-cells = <1>;
+				#phy-cells = <0>;
+
+				clocks = <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>,
+					 <&rpmhcc RPMH_CXO_CLK>;
+				clock-names = "iface", "ref";
+
+				status = "disabled";
+			};
+
+			mdss0_edp_phy: phy@aec2a00 {
+				compatible = "qcom,sa8775p-edp-phy";
+
+				reg = <0x0 0xaec2a00 0x0 0x200>,
+					<0x0 0xaec2200 0x0 0xd0>,
+					<0x0 0xaec2600 0x0 0xd0>,
+					<0x0 0xaec2000 0x0 0x1c8>;
+
+				clocks = <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>;
+				clock-names = "aux",
+					      "cfg_ahb";
+
+				vdda-phy-supply = <&vreg_l1c>;
+				vdda-pll-supply = <&vreg_l4a>;
+				#clock-cells = <1>;
+				#phy-cells = <0>;
+
+				status = "disabled";
+			};
+
+			mdss0_edp1_phy: phy@aec5a00 {
+				compatible = "qcom,sa8775p-edp-phy";
+
+				reg = <0x0 0xaec5a00 0x0 0x200>,
+				      <0x0 0xaec5200 0x0 0xd0>,
+				      <0x0 0xaec5600 0x0 0xd0>,
+				      <0x0 0xaec5000 0x0 0x1c8>;
+
+				clocks =<&dispcc0 MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK>,
+					<&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>;
+				clock-names = "aux",
+					      "cfg_ahb";
+
+				vdda-phy-supply = <&vreg_l1c>;
+				vdda-pll-supply = <&vreg_l4a>;
+				#clock-cells = <1>;
+				#phy-cells = <0>;
+
+				status = "disabled";
+			};
+
+			mdss0_dp0: displayport-controller@af54000 {
+				compatible = "qcom,sa8775p-dp";
+
+				pinctrl-0 = <&dp_hot_plug_det>;
+				pinctrl-names = "default";
+
+				reg = <0x0 0xaf54000 0x0 0x104>,
+					<0x0 0xaf54200 0x0 0x0c0>,
+					<0x0 0xaf55000 0x0 0x770>,
+					<0x0 0xaf56000 0x0 0x09c>,
+					<0x0 0xaf57000 0x0 0x09c>;
+
+				interrupt-parent = <&mdss0>;
+				interrupts = <12>;
+
+				clocks = <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_LINK_INTF_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK>;
+				clock-names = "core_iface",
+						"core_aux",
+						"ctrl_link",
+						"ctrl_link_iface",
+						"stream_pixel",
+						"stream_1_pixel";
+				assigned-clocks = <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK_SRC>,
+						  <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC>,
+						  <&dispcc0 MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC>;
+				assigned-clock-parents = <&mdss0_edp_phy 0>,
+							 <&mdss0_edp_phy 1>,
+							 <&mdss0_edp_phy 1>;
+				phys = <&mdss0_edp_phy>;
+				phy-names = "dp";
+
+				operating-points-v2 = <&dp_opp_table>;
+				power-domains = <&rpmhpd SA8775P_MMCX>;
+
+				#sound-dai-cells = <0>;
+
+				status = "disabled";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port@0 {
+						reg = <0>;
+						mdss0_dp0_in: endpoint {
+							remote-endpoint = <&dpu_intf0_out>;
+						};
+					};
+
+					port@1 {
+						reg = <1>;
+						mdss0_dp0_out: endpoint { };
+					};
+				};
+
+				dp_opp_table: opp-table {
+					compatible = "operating-points-v2";
+
+					opp-160000000 {
+						opp-hz = /bits/ 64 <160000000>;
+						required-opps = <&rpmhpd_opp_low_svs>;
+					};
+
+					opp-270000000 {
+						opp-hz = /bits/ 64 <270000000>;
+						required-opps = <&rpmhpd_opp_svs>;
+					};
+
+					opp-540000000 {
+						opp-hz = /bits/ 64 <540000000>;
+						required-opps = <&rpmhpd_opp_svs_l1>;
+					};
+
+					opp-810000000 {
+						opp-hz = /bits/ 64 <810000000>;
+						required-opps = <&rpmhpd_opp_nom>;
+					};
+				};
+			};
+
+			mdss0_dp1: displayport-controller@af5c000 {
+				compatible = "qcom,sa8775p-dp";
+
+				pinctrl-0 = <&dp1_hot_plug_det>;
+				pinctrl-names = "default";
+
+				reg = <0x0 0xaf5c000 0x0 0x104>,
+				      <0x0 0xaf5c200 0x0 0x0c0>,
+				      <0x0 0xaf5d000 0x0 0x770>,
+				      <0x0 0xaf5e000 0x0 0x09c>,
+				      <0x0 0xaf5f000 0x0 0x09c>;
+
+				interrupt-parent = <&mdss0>;
+				interrupts = <13>;
+
+				clocks = <&dispcc0 MDSS_DISP_CC_MDSS_AHB_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX1_LINK_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX1_LINK_INTF_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX1_PIXEL0_CLK>,
+					 <&dispcc0 MDSS_DISP_CC_MDSS_DPTX1_PIXEL1_CLK>;
+				clock-names = "core_iface",
+					      "core_aux",
+					      "ctrl_link",
+					      "ctrl_link_iface",
+					      "stream_pixel",
+					      "stream_1_pixel";
+				assigned-clocks = <&dispcc0 MDSS_DISP_CC_MDSS_DPTX1_LINK_CLK_SRC>,
+						  <&dispcc0 MDSS_DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC>,
+						  <&dispcc0 MDSS_DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC>;
+				assigned-clock-parents = <&mdss0_edp1_phy 0>,
+							 <&mdss0_edp1_phy 1>,
+							 <&mdss0_edp1_phy 1>;
+				phys = <&mdss0_edp1_phy>;
+				phy-names = "dp";
+
+				operating-points-v2 = <&dp1_opp_table>;
+				power-domains = <&rpmhpd SA8775P_MMCX>;
+
+				#sound-dai-cells = <0>;
+
+				status = "disabled";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port@0 {
+						reg = <0>;
+
+						mdss0_dp1_in: endpoint {
+							remote-endpoint = <&dpu_intf4_out>;
+						};
+					};
+
+					port@1 {
+						reg = <1>;
+
+						mdss0_dp1_out: endpoint { };
+					};
+				};
+
+				dp1_opp_table: opp-table {
+					compatible = "operating-points-v2";
+
+					opp-160000000 {
+						opp-hz = /bits/ 64 <160000000>;
+						required-opps = <&rpmhpd_opp_low_svs>;
+					};
+
+					opp-270000000 {
+						opp-hz = /bits/ 64 <270000000>;
+						required-opps = <&rpmhpd_opp_svs>;
+					};
+
+					opp-540000000 {
+						opp-hz = /bits/ 64 <540000000>;
+						required-opps = <&rpmhpd_opp_svs_l1>;
+					};
+
+					opp-810000000 {
+						opp-hz = /bits/ 64 <810000000>;
+						required-opps = <&rpmhpd_opp_nom>;
+					};
+				};
+			};
+		};
+
+		dispcc0: clock-controller@af00000 {
+			compatible = "qcom,sa8775p-dispcc0";
+			reg = <0x0 0x0af00000 0x0 0x20000>;
+			clocks = <&gcc GCC_DISP_AHB_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK_A>,
+				 <&sleep_clk>,
+				 <&mdss0_edp_phy 0>, <&mdss0_edp_phy 1>,
+				 <&mdss0_edp1_phy 0>, <&mdss0_edp1_phy 1>,
+				 <&mdss0_dsi0_phy 0>, <&mdss0_dsi0_phy 1>,
+				 <&mdss0_dsi1_phy 0>, <&mdss0_dsi1_phy 1>;
+			power-domains = <&rpmhpd SA8775P_MMCX>;
+			required-opps = <&rpmhpd_opp_low_svs>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
 		pdc: interrupt-controller@b220000 {
 			compatible = "qcom,sa8775p-pdc", "qcom,pdc";
 			reg = <0x0 0x0b220000 0x0 0x30000>,
@@ -2006,6 +7552,648 @@
 			#interrupt-cells = <2>;
 			gpio-ranges = <&tlmm 0 0 149>;
 			wakeup-parent = <&pdc>;
+
+			qup_i2c0_default: qup-i2c0-state {
+				pins = "gpio20", "gpio21";
+				function = "qup0_se0";
+			};
+
+			qup_i2c1_default: qup-i2c1-state {
+				pins = "gpio24", "gpio25";
+				function = "qup0_se1";
+			};
+
+			qup_i2c2_default: qup-i2c2-state {
+				pins = "gpio36", "gpio37";
+				function = "qup0_se2";
+			};
+
+			qup_i2c3_default: qup-i2c3-state {
+				pins = "gpio28", "gpio29";
+				function = "qup0_se3";
+			};
+
+			qup_i2c4_default: qup-i2c4-state {
+				pins = "gpio32", "gpio33";
+				function = "qup0_se4";
+			};
+
+			qup_i2c5_default: qup-i2c5-state {
+				pins = "gpio36", "gpio37";
+				function = "qup0_se5";
+			};
+
+			qup_i2c7_default: qup-i2c7-state {
+				pins = "gpio40", "gpio41";
+				function = "qup1_se0";
+			};
+
+			qup_i2c8_default: qup-i2c8-state {
+				pins = "gpio42", "gpio43";
+				function = "qup1_se1";
+			};
+
+			qup_i2c9_default: qup-i2c9-state {
+				pins = "gpio46", "gpio47";
+				function = "qup1_se2";
+			};
+
+			qup_i2c10_default: qup-i2c10-state {
+				pins = "gpio44", "gpio45";
+				function = "qup1_se3";
+			};
+
+			qup_i2c11_default: qup-i2c11-state {
+				pins = "gpio48", "gpio49";
+				function = "qup1_se4";
+			};
+
+			qup_i2c12_default: qup-i2c12-state {
+				pins = "gpio52", "gpio53";
+				function = "qup1_se5";
+			};
+
+			qup_i2c13_default: qup-i2c13-state {
+				pins = "gpio56", "gpio57";
+				function = "qup1_se6";
+			};
+
+			qup_i2c14_default: qup-i2c14-state {
+				pins = "gpio80", "gpio81";
+				function = "qup2_se0";
+			};
+
+			qup_i2c15_default: qup-i2c15-state {
+				pins = "gpio84", "gpio85";
+				function = "qup2_se1";
+			};
+
+			qup_i2c16_default: qup-i2c16-state {
+				pins = "gpio86", "gpio87";
+				function = "qup2_se2";
+			};
+
+			qup_i2c17_default: qup-i2c17-state {
+				pins = "gpio91", "gpio92";
+				function = "qup2_se3";
+			};
+
+			qup_i2c18_default: qup-i2c18-state {
+				pins = "gpio95", "gpio96";
+				function = "qup2_se4";
+			};
+
+			qup_i2c19_default: qup-i2c19-state {
+				pins = "gpio99", "gpio100";
+				function = "qup2_se5";
+			};
+
+			qup_i2c20_default: qup-i2c20-state {
+				pins = "gpio97", "gpio98";
+				function = "qup2_se6";
+			};
+
+			qup_i2c21_default: qup-i2c21-state {
+				pins = "gpio13", "gpio14";
+				function = "qup3_se0";
+			};
+
+			qup_spi0_default: qup-spi0-state {
+				pins = "gpio20", "gpio21", "gpio22", "gpio23";
+				function = "qup0_se0";
+			};
+
+			qup_spi1_default: qup-spi1-state {
+				pins = "gpio24", "gpio25", "gpio26", "gpio27";
+				function = "qup0_se1";
+			};
+
+			qup_spi2_default: qup-spi2-state {
+				pins = "gpio36", "gpio37", "gpio38", "gpio39";
+				function = "qup0_se2";
+			};
+
+			qup_spi3_default: qup-spi3-state {
+				pins = "gpio28", "gpio29", "gpio30", "gpio31";
+				function = "qup0_se3";
+			};
+
+			qup_spi4_default: qup-spi4-state {
+				pins = "gpio32", "gpio33", "gpio34", "gpio35";
+				function = "qup0_se4";
+			};
+
+			qup_spi5_default: qup-spi5-state {
+				pins = "gpio36", "gpio37", "gpio38", "gpio39";
+				function = "qup0_se5";
+			};
+
+			qup_spi7_default: qup-spi7-state {
+				pins = "gpio40", "gpio41", "gpio42", "gpio43";
+				function = "qup1_se0";
+			};
+
+			qup_spi8_default: qup-spi8-state {
+				pins = "gpio42", "gpio43", "gpio40", "gpio41";
+				function = "qup1_se1";
+			};
+
+			qup_spi9_default: qup-spi9-state {
+				pins = "gpio46", "gpio47", "gpio44", "gpio45";
+				function = "qup1_se2";
+			};
+
+			qup_spi10_default: qup-spi10-state {
+				pins = "gpio44", "gpio45", "gpio46", "gpio47";
+				function = "qup1_se3";
+			};
+
+			qup_spi11_default: qup-spi11-state {
+				pins = "gpio48", "gpio49", "gpio50", "gpio51";
+				function = "qup1_se4";
+			};
+
+			qup_spi12_default: qup-spi12-state {
+				pins = "gpio52", "gpio53", "gpio54", "gpio55";
+				function = "qup1_se5";
+			};
+
+			qup_spi14_default: qup-spi14-state {
+				pins = "gpio80", "gpio81", "gpio82", "gpio83";
+				function = "qup2_se0";
+			};
+
+			qup_spi15_default: qup-spi15-state {
+				pins = "gpio84", "gpio85", "gpio99", "gpio100";
+				function = "qup2_se1";
+			};
+
+			qup_spi16_default: qup-spi16-state {
+				pins = "gpio86", "gpio87", "gpio88", "gpio89";
+				function = "qup2_se2";
+			};
+
+			qup_spi17_default: qup-spi17-state {
+				pins = "gpio91", "gpio92", "gpio93", "gpio94";
+				function = "qup2_se3";
+			};
+
+			qup_spi18_default: qup-spi18-state {
+				pins = "gpio95", "gpio96", "gpio97", "gpio98";
+				function = "qup2_se4";
+			};
+
+			qup_spi19_default: qup-spi19-state {
+				pins = "gpio99", "gpio100", "gpio84", "gpio85";
+				function = "qup2_se5";
+			};
+
+			qup_spi20_default: qup-spi20-state {
+				pins = "gpio97", "gpio98", "gpio95", "gpio96";
+				function = "qup2_se6";
+			};
+
+			qup_spi21_default: qup-spi21-state {
+				pins = "gpio13", "gpio14", "gpio15", "gpio16";
+				function = "qup3_se0";
+			};
+
+			qup_uart0_default: qup-uart0-state {
+				qup_uart0_cts: qup-uart0-cts-pins {
+					pins = "gpio20";
+					function = "qup0_se0";
+				};
+
+				qup_uart0_rts: qup-uart0-rts-pins {
+					pins = "gpio21";
+					function = "qup0_se0";
+				};
+
+				qup_uart0_tx: qup-uart0-tx-pins {
+					pins = "gpio22";
+					function = "qup0_se0";
+				};
+
+				qup_uart0_rx: qup-uart0-rx-pins {
+					pins = "gpio23";
+					function = "qup0_se0";
+				};
+			};
+
+			qup_uart1_default: qup-uart1-state {
+				qup_uart1_cts: qup-uart1-cts-pins {
+					pins = "gpio24";
+					function = "qup0_se1";
+				};
+
+				qup_uart1_rts: qup-uart1-rts-pins {
+					pins = "gpio25";
+					function = "qup0_se1";
+				};
+
+				qup_uart1_tx: qup-uart1-tx-pins {
+					pins = "gpio26";
+					function = "qup0_se1";
+				};
+
+				qup_uart1_rx: qup-uart1-rx-pins {
+					pins = "gpio27";
+					function = "qup0_se1";
+				};
+			};
+
+			qup_uart2_default: qup-uart2-state {
+				qup_uart2_cts: qup-uart2-cts-pins {
+					pins = "gpio36";
+					function = "qup0_se2";
+				};
+
+				qup_uart2_rts: qup-uart2-rts-pins {
+					pins = "gpio37";
+					function = "qup0_se2";
+				};
+
+				qup_uart2_tx: qup-uart2-tx-pins {
+					pins = "gpio38";
+					function = "qup0_se2";
+				};
+
+				qup_uart2_rx: qup-uart2-rx-pins {
+					pins = "gpio39";
+					function = "qup0_se2";
+				};
+			};
+
+			qup_uart3_default: qup-uart3-state {
+				qup_uart3_cts: qup-uart3-cts-pins {
+					pins = "gpio28";
+					function = "qup0_se3";
+				};
+
+				qup_uart3_rts: qup-uart3-rts-pins {
+					pins = "gpio29";
+					function = "qup0_se3";
+				};
+
+				qup_uart3_tx: qup-uart3-tx-pins {
+					pins = "gpio30";
+					function = "qup0_se3";
+				};
+
+				qup_uart3_rx: qup-uart3-rx-pins {
+					pins = "gpio31";
+					function = "qup0_se3";
+				};
+			};
+
+			qup_uart4_default: qup-uart4-state {
+				qup_uart4_cts: qup-uart4-cts-pins {
+					pins = "gpio32";
+					function = "qup0_se4";
+				};
+
+				qup_uart4_rts: qup-uart4-rts-pins {
+					pins = "gpio33";
+					function = "qup0_se4";
+				};
+
+				qup_uart4_tx: qup-uart4-tx-pins {
+					pins = "gpio34";
+					function = "qup0_se4";
+				};
+
+				qup_uart4_rx: qup-uart4-rx-pins {
+					pins = "gpio35";
+					function = "qup0_se4";
+				};
+			};
+
+			qup_uart5_default: qup-uart5-state {
+				qup_uart5_cts: qup-uart5-cts-pins {
+					pins = "gpio36";
+					function = "qup0_se5";
+				};
+
+				qup_uart5_rts: qup-uart5-rts-pins {
+					pins = "gpio37";
+					function = "qup0_se5";
+				};
+
+				qup_uart5_tx: qup-uart5-tx-pins {
+					pins = "gpio38";
+					function = "qup0_se5";
+				};
+
+				qup_uart5_rx: qup-uart5-rx-pins {
+					pins = "gpio39";
+					function = "qup0_se5";
+				};
+			};
+
+			qup_uart7_default: qup-uart7-state {
+				qup_uart7_cts: qup-uart7-cts-pins {
+					pins = "gpio40";
+					function = "qup1_se0";
+				};
+
+				qup_uart7_rts: qup-uart7-rts-pins {
+					pins = "gpio41";
+					function = "qup1_se0";
+				};
+
+				qup_uart7_tx: qup-uart7-tx-pins {
+					pins = "gpio42";
+					function = "qup1_se0";
+				};
+
+				qup_uart7_rx: qup-uart7-rx-pins {
+					pins = "gpio43";
+					function = "qup1_se0";
+				};
+			};
+
+			qup_uart8_default: qup-uart8-state {
+				qup_uart8_cts: qup-uart8-cts-pins {
+					pins = "gpio42";
+					function = "qup1_se1";
+				};
+
+				qup_uart8_rts: qup-uart8-rts-pins {
+					pins = "gpio43";
+					function = "qup1_se1";
+				};
+
+				qup_uart8_tx: qup-uart8-tx-pins {
+					pins = "gpio40";
+					function = "qup1_se1";
+				};
+
+				qup_uart8_rx: qup-uart8-rx-pins {
+					pins = "gpio41";
+					function = "qup1_se1";
+				};
+			};
+
+			qup_uart9_default: qup-uart9-state {
+				qup_uart9_cts: qup-uart9-cts-pins {
+					pins = "gpio46";
+					function = "qup1_se2";
+				};
+
+				qup_uart9_rts: qup-uart9-rts-pins {
+					pins = "gpio47";
+					function = "qup1_se2";
+				};
+
+				qup_uart9_tx: qup-uart9-tx-pins {
+					pins = "gpio44";
+					function = "qup1_se2";
+				};
+
+				qup_uart9_rx: qup-uart9-rx-pins {
+					pins = "gpio45";
+					function = "qup1_se2";
+				};
+			};
+
+			qup_uart10_default: qup-uart10-state {
+				pins = "gpio46", "gpio47";
+				function = "qup1_se3";
+			};
+
+			qup_uart11_default: qup-uart11-state {
+				qup_uart11_cts: qup-uart11-cts-pins {
+					pins = "gpio48";
+					function = "qup1_se4";
+				};
+
+				qup_uart11_rts: qup-uart11-rts-pins {
+					pins = "gpio49";
+					function = "qup1_se4";
+				};
+
+				qup_uart11_tx: qup-uart11-tx-pins {
+					pins = "gpio50";
+					function = "qup1_se4";
+				};
+
+				qup_uart11_rx: qup-uart11-rx-pins {
+					pins = "gpio51";
+					function = "qup1_se4";
+				};
+			};
+
+			qup_uart12_default: qup-uart12-state {
+				qup_uart12_cts: qup-uart12-cts-pins {
+					pins = "gpio52";
+					function = "qup1_se5";
+				};
+
+				qup_uart12_rts: qup-uart12-rts-pins {
+					pins = "gpio53";
+					function = "qup1_se5";
+				};
+
+				qup_uart12_tx: qup-uart12-tx-pins {
+					pins = "gpio54";
+					function = "qup1_se5";
+				};
+
+				qup_uart12_rx: qup-uart12-rx-pins {
+					pins = "gpio55";
+					function = "qup1_se5";
+				};
+			};
+
+			qup_uart14_default: qup-uart14-state {
+				qup_uart14_cts: qup-uart14-cts-pins {
+					pins = "gpio80";
+					function = "qup2_se0";
+				};
+
+				qup_uart14_rts: qup-uart14-rts-pins {
+					pins = "gpio81";
+					function = "qup2_se0";
+				};
+
+				qup_uart14_tx: qup-uart14-tx-pins {
+					pins = "gpio82";
+					function = "qup2_se0";
+				};
+
+				qup_uart14_rx: qup-uart14-rx-pins {
+					pins = "gpio83";
+					function = "qup2_se0";
+				};
+			};
+
+			qup_uart15_default: qup-uart15-state {
+				qup_uart15_cts: qup-uart15-cts-pins {
+					pins = "gpio84";
+					function = "qup2_se1";
+				};
+
+				qup_uart15_rts: qup-uart15-rts-pins {
+					pins = "gpio85";
+					function = "qup2_se1";
+				};
+
+				qup_uart15_tx: qup-uart15-tx-pins {
+					pins = "gpio99";
+					function = "qup2_se1";
+				};
+
+				qup_uart15_rx: qup-uart15-rx-pins {
+					pins = "gpio100";
+					function = "qup2_se1";
+				};
+			};
+
+			qup_uart16_default: qup-uart16-state {
+				qup_uart16_cts: qup-uart16-cts-pins {
+					pins = "gpio86";
+					function = "qup2_se2";
+				};
+
+				qup_uart16_rts: qup-uart16-rts-pins {
+					pins = "gpio87";
+					function = "qup2_se2";
+				};
+
+				qup_uart16_tx: qup-uart16-tx-pins {
+					pins = "gpio88";
+					function = "qup2_se2";
+				};
+
+				qup_uart16_rx: qup-uart16-rx-pins {
+					pins = "gpio89";
+					function = "qup2_se2";
+				};
+			};
+
+			qup_uart17_default: qup-uart17-state {
+				qup_uart17_cts: qup-uart17-cts-pins {
+					pins = "gpio91";
+					function = "qup2_se3";
+				};
+
+				qup_uart17_rts: qup0-uart17-rts-pins {
+					pins = "gpio92";
+					function = "qup2_se3";
+				};
+
+				qup_uart17_tx: qup0-uart17-tx-pins {
+					pins = "gpio93";
+					function = "qup2_se3";
+				};
+
+				qup_uart17_rx: qup0-uart17-rx-pins {
+					pins = "gpio94";
+					function = "qup2_se3";
+				};
+			};
+
+			qup_uart18_default: qup-uart18-state {
+				qup_uart18_cts: qup-uart18-cts-pins {
+					pins = "gpio95";
+					function = "qup2_se4";
+				};
+
+				qup_uart18_rts: qup-uart18-rts-pins {
+					pins = "gpio96";
+					function = "qup2_se4";
+				};
+
+				qup_uart18_tx: qup-uart18-tx-pins {
+					pins = "gpio97";
+					function = "qup2_se4";
+				};
+
+				qup_uart18_rx: qup-uart18-rx-pins {
+					pins = "gpio98";
+					function = "qup2_se4";
+				};
+			};
+
+			qup_uart19_default: qup-uart19-state {
+				qup_uart19_cts: qup-uart19-cts-pins {
+					pins = "gpio99";
+					function = "qup2_se5";
+				};
+
+				qup_uart19_rts: qup-uart19-rts-pins {
+					pins = "gpio100";
+					function = "qup2_se5";
+				};
+
+				qup_uart19_tx: qup-uart19-tx-pins {
+					pins = "gpio84";
+					function = "qup2_se5";
+				};
+
+				qup_uart19_rx: qup-uart19-rx-pins {
+					pins = "gpio85";
+					function = "qup2_se5";
+				};
+			};
+
+			qup_uart20_default: qup-uart20-state {
+				qup_uart20_cts: qup-uart20-cts-pins {
+					pins = "gpio97";
+					function = "qup2_se6";
+				};
+
+				qup_uart20_rts: qup-uart20-rts-pins {
+					pins = "gpio98";
+					function = "qup2_se6";
+				};
+
+				qup_uart20_tx: qup-uart20-tx-pins {
+					pins = "gpio95";
+					function = "qup2_se6";
+				};
+
+				qup_uart20_rx: qup-uart20-rx-pins {
+					pins = "gpio96";
+					function = "qup2_se6";
+				};
+			};
+
+			qup_uart21_default: qup-uart21-state {
+				qup_uart21_cts: qup-uart21-cts-pins {
+					pins = "gpio13";
+					function = "qup3_se0";
+				};
+
+				qup_uart21_rts: qup-uart21-rts-pins {
+					pins = "gpio14";
+					function = "qup3_se0";
+				};
+
+				qup_uart21_tx: qup-uart21-tx-pins {
+					pins = "gpio15";
+					function = "qup3_se0";
+				};
+
+				qup_uart21_rx: qup-uart21-rx-pins {
+					pins = "gpio16";
+					function = "qup3_se0";
+				};
+			};
+		};
+
+		sram: sram@146d8000 {
+			compatible = "qcom,sa8775p-imem", "syscon", "simple-mfd";
+			reg = <0x0 0x146d8000 0x0 0x1000>;
+			ranges = <0x0 0x0 0x146d8000 0x1000>;
+
+			#address-cells = <1>;
+			#size-cells = <1>;
+
+			pil-reloc@94c {
+				compatible = "qcom,pil-reloc-info";
+				reg = <0x94c 0xc8>;
+			};
 		};
 
 		apps_smmu: iommu@15000000 {
@@ -2013,6 +8201,10 @@
 			reg = <0x0 0x15000000 0x0 0x100000>;
 			#iommu-cells = <2>;
 			#global-interrupts = <2>;
+			dma-coherent;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
 
 			interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
@@ -2144,6 +8336,111 @@
 				     <GIC_SPI 893 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 892 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 891 IRQ_TYPE_LEVEL_HIGH>;
+
+			anoc_1_tbu: anoc_1_tbu@15189000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x15189000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x0 0x400>;
+			};
+
+			anoc_2_tbu: anoc_2_tbu@15191000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x15191000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x400 0x400>;
+			};
+
+			mmnoc_sf_0_tbu: mmnoc_sf_0_tbu@15199000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x15199000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x800 0x400>;
+			};
+
+			mmnoc_sf_1_tbu: mmnoc_sf_1_tbu@151a1000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151a1000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0xc00 0x400>;
+			};
+
+			mdp_00_tbu: mdp_00_tbu@151a9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151a9000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x1000 0x400>;
+			};
+
+			mdp_01_tbu: mdp_01_tbu@151b1000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151b1000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x1400 0x400>;
+			};
+
+			mdp_10_tbu: mdp_10_tbu@151b9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151b9000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x1800 0x400>;
+			};
+
+			mdp_11_tbu: mdp_11_tbu@151c1000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151c1000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x1c00 0x400>;
+			};
+
+			nsp_00_tbu: nsp_00_tbu@151c9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151c9000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x2000 0x400>;
+			};
+
+			nsp_01_tbu: nsp_01_tbu@151d1000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151d1000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x2400 0x400>;
+			};
+
+			nsp_10_tbu: nsp_10_tbu@151d9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151d9000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x2800 0x400>;
+			};
+
+			nsp_11_tbu: nsp_11_tbu@151e1000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151e1000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x2c00 0x400>;
+			};
+
+			lpass_tbu: lpass_tbu@151e9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151e9000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x3000 0x400>;
+			};
+
+			cam_tbu: cam_tbu@151f1000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151f1000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x3400 0x400>;
+			};
+
+			gpdsp_sail_ss_tbu: gpdsp_sail_ss_tbu@151f9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151f9000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x3800 0x400>;
+			};
 		};
 
 		pcie_smmu: iommu@15200000 {
@@ -2151,6 +8448,10 @@
 			reg = <0x0 0x15200000 0x0 0x80000>;
 			#iommu-cells = <2>;
 			#global-interrupts = <2>;
+			dma-coherent;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
 
 			interrupts = <GIC_SPI 920 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 921 IRQ_TYPE_LEVEL_HIGH>,
@@ -2218,6 +8519,13 @@
 				     <GIC_SPI 639 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 640 IRQ_TYPE_LEVEL_HIGH>;
+
+			pcie_0_tbu: pcie_0_tbu@152f9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x152f9000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x0 0x440>;
+			};
 		};
 
 		intc: interrupt-controller@17a00000 {
@@ -2375,12 +8683,23 @@
 			};
 		};
 
+		epss_l3_cl0: interconnect@18590000 {
+			compatible = "qcom,sa8775p-epss-l3-cl0";
+			reg = <0x0 0x18590000 0x0 0x1000>;
+			clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>;
+			clock-names = "xo", "alternate";
+			#interconnect-cells = <1>;
+		};
+
 		cpufreq_hw: cpufreq@18591000 {
 			compatible = "qcom,sa8775p-cpufreq-epss",
 				     "qcom,cpufreq-epss";
 			reg = <0x0 0x18591000 0x0 0x1000>,
 			      <0x0 0x18593000 0x0 0x1000>;
 			reg-names = "freq-domain0", "freq-domain1";
+			interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "dcvsh-irq-0", "dcvsh-irq-1";
 
 			clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>;
 			clock-names = "xo", "alternate";
@@ -2388,14 +8707,183 @@
 			#freq-domain-cells = <1>;
 		};
 
+		remoteproc_gpdsp0: remoteproc@20c00000 {
+			compatible = "qcom,sa8775p-gpdsp0-pas";
+			reg = <0x0 0x20c00000 0x0 0x10000>;
+
+			interrupts-extended = <&intc GIC_SPI 768 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_gpdsp0_in 0 0>,
+					      <&smp2p_gpdsp0_in 1 0>,
+					      <&smp2p_gpdsp0_in 2 0>,
+					      <&smp2p_gpdsp0_in 3 0>;
+			interrupt-names = "wdog", "fatal", "ready",
+					  "handover", "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_CX>,
+					<&rpmhpd RPMHPD_MXC>;
+			power-domain-names = "cx", "mxc";
+
+			interconnects = <&gpdsp_anoc MASTER_DSP0 0
+					 &config_noc SLAVE_CLK_CTL 0>;
+
+			memory-region = <&pil_gdsp0_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_gpdsp0_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_GPDSP0
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_GPDSP0
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "gdsp0";
+				qcom,remote-pid = <17>;
+
+				fastrpc {
+					compatible = "qcom,fastrpc";
+					qcom,glink-channels = "fastrpcglink-apps-dsp";
+					label = "gdsp0";
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					compute-cb@1 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <1>;
+						iommus = <&apps_smmu 0x38a1 0x0>;
+						dma-coherent;
+					};
+
+					compute-cb@2 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <2>;
+						iommus = <&apps_smmu 0x38a2 0x0>;
+						dma-coherent;
+					};
+
+					compute-cb@3 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <3>;
+						iommus = <&apps_smmu 0x38a3 0x0>;
+						dma-coherent;
+					};
+				};
+			};
+		};
+
+		remoteproc_gpdsp1: remoteproc@21c00000 {
+			compatible = "qcom,sa8775p-gpdsp1-pas";
+			reg = <0x0 0x21c00000 0x0 0x10000>;
+
+			interrupts-extended = <&intc GIC_SPI 624 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_gpdsp1_in 0 0>,
+					      <&smp2p_gpdsp1_in 1 0>,
+					      <&smp2p_gpdsp1_in 2 0>,
+					      <&smp2p_gpdsp1_in 3 0>;
+			interrupt-names = "wdog", "fatal", "ready",
+					  "handover", "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_CX>,
+					<&rpmhpd RPMHPD_MXC>;
+			power-domain-names = "cx", "mxc";
+
+			interconnects = <&gpdsp_anoc MASTER_DSP1 0
+					 &config_noc SLAVE_CLK_CTL 0>;
+
+			memory-region = <&pil_gdsp1_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_gpdsp1_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_GPDSP1
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_GPDSP1
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "gdsp1";
+				qcom,remote-pid = <18>;
+
+				fastrpc {
+					compatible = "qcom,fastrpc";
+					qcom,glink-channels = "fastrpcglink-apps-dsp";
+					label = "gdsp1";
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					compute-cb@1 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <1>;
+						iommus = <&apps_smmu 0x38c1 0x0>;
+						dma-coherent;
+					};
+
+					compute-cb@2 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <2>;
+						iommus = <&apps_smmu 0x38c2 0x0>;
+						dma-coherent;
+					};
+
+					compute-cb@3 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <3>;
+						iommus = <&apps_smmu 0x38c3 0x0>;
+						dma-coherent;
+					};
+				};
+			};
+		};
+
+		epss_l3_cl1: interconnect@18592000 {
+			compatible = "qcom,sa8775p-epss-l3-cl1";
+			reg = <0x0 0x18592000 0x0 0x1000>;
+			clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>;
+			clock-names = "xo", "alternate";
+			#interconnect-cells = <1>;
+		};
+
+		dispcc1: clock-controller@22100000 {
+			compatible = "qcom,sa8775p-dispcc1";
+			reg = <0x0 0x22100000 0x0 0x20000>;
+			clocks = <&gcc GCC_DISP_AHB_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&rpmhcc RPMH_CXO_CLK_A>,
+				 <&sleep_clk>,
+				 <0>, <0>, <0>, <0>,
+				 <0>, <0>, <0>, <0>;
+			power-domains = <&rpmhpd SA8775P_MMCX>;
+			required-opps = <&rpmhpd_opp_low_svs>;
+			#clock-cells = <1>;
+			#reset-cells = <1>;
+			#power-domain-cells = <1>;
+		};
+
 		ethernet1: ethernet@23000000 {
 			compatible = "qcom,sa8775p-ethqos";
 			reg = <0x0 0x23000000 0x0 0x10000>,
 			      <0x0 0x23016000 0x0 0x100>;
 			reg-names = "stmmaceth", "rgmii";
 
-			interrupts = <GIC_SPI 929 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "macirq";
+			interrupts = <GIC_SPI 929 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 781 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq", "sfty";
 
 			clocks = <&gcc GCC_EMAC1_AXI_CLK>,
 				 <&gcc GCC_EMAC1_SLV_AHB_CLK>,
@@ -2406,12 +8894,19 @@
 				      "ptp_ref",
 				      "phyaux";
 
+			interconnects = <&aggre1_noc MASTER_EMAC_1 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+					 &config_noc SLAVE_EMAC1_CFG QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "mac-mem", "cpu-mac";
+
 			power-domains = <&gcc EMAC1_GDSC>;
 
 			phys = <&serdes1>;
 			phy-names = "serdes";
 
 			iommus = <&apps_smmu 0x140 0xf>;
+			dma-coherent;
 
 			snps,tso;
 			snps,pbl = <32>;
@@ -2427,8 +8922,9 @@
 			      <0x0 0x23056000 0x0 0x100>;
 			reg-names = "stmmaceth", "rgmii";
 
-			interrupts = <GIC_SPI 946 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "macirq";
+			interrupts = <GIC_SPI 946 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 782 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq", "sfty";
 
 			clocks = <&gcc GCC_EMAC0_AXI_CLK>,
 				 <&gcc GCC_EMAC0_SLV_AHB_CLK>,
@@ -2439,12 +8935,19 @@
 				      "ptp_ref",
 				      "phyaux";
 
+			interconnects = <&aggre1_noc MASTER_EMAC QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+					 &config_noc SLAVE_EMAC_CFG QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "mac-mem", "cpu-mac";
+
 			power-domains = <&gcc EMAC0_GDSC>;
 
 			phys = <&serdes0>;
 			phy-names = "serdes";
 
 			iommus = <&apps_smmu 0x120 0xf>;
+			dma-coherent;
 
 			snps,tso;
 			snps,pbl = <32>;
@@ -2453,13 +8956,426 @@
 
 			status = "disabled";
 		};
+
+		remoteproc_cdsp0: remoteproc@26300000 {
+			compatible = "qcom,sa8775p-cdsp0-pas";
+			reg = <0x0 0x26300000 0x0 0x10000>;
+
+			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp0_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp0_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp0_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp0_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog", "fatal", "ready",
+					  "handover", "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_CX>,
+					<&rpmhpd RPMHPD_MXC>,
+					<&rpmhpd RPMHPD_NSP0>;
+			power-domain-names = "cx", "mxc", "nsp";
+
+			interconnects = <&nspa_noc MASTER_CDSP_PROC 0
+					 &mc_virt SLAVE_EBI1 0>;
+
+			memory-region = <&pil_cdsp0_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_cdsp0_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_CDSP
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "cdsp";
+				qcom,remote-pid = <5>;
+
+				fastrpc {
+					compatible = "qcom,fastrpc";
+					qcom,glink-channels = "fastrpcglink-apps-dsp";
+					label = "cdsp";
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					compute-cb@1 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <1>;
+						iommus = <&apps_smmu 0x2141 0x04a0>,
+							 <&apps_smmu 0x2181 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@2 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <2>;
+						iommus = <&apps_smmu 0x2142 0x04a0>,
+							 <&apps_smmu 0x2182 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@3 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <3>;
+						iommus = <&apps_smmu 0x2143 0x04a0>,
+							 <&apps_smmu 0x2183 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@4 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <4>;
+						iommus = <&apps_smmu 0x2144 0x04a0>,
+							 <&apps_smmu 0x2184 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@5 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <5>;
+						iommus = <&apps_smmu 0x2145 0x04a0>,
+							 <&apps_smmu 0x2185 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@6 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <6>;
+						iommus = <&apps_smmu 0x2146 0x04a0>,
+							 <&apps_smmu 0x2186 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@7 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <7>;
+						iommus = <&apps_smmu 0x2147 0x04a0>,
+							 <&apps_smmu 0x2187 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@8 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <8>;
+						iommus = <&apps_smmu 0x2148 0x04a0>,
+							 <&apps_smmu 0x2188 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@9 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <9>;
+						iommus = <&apps_smmu 0x2149 0x04a0>,
+							 <&apps_smmu 0x2189 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@11 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <11>;
+						iommus = <&apps_smmu 0x214b 0x04a0>,
+							 <&apps_smmu 0x218b 0x0400>;
+						dma-coherent;
+					};
+				};
+			};
+		};
+
+		remoteproc_cdsp1: remoteproc@2a300000 {
+			compatible = "qcom,sa8775p-cdsp1-pas";
+			reg = <0x0 0x2A300000 0x0 0x10000>;
+
+			interrupts-extended = <&intc GIC_SPI 798 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp1_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp1_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp1_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp1_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog", "fatal", "ready",
+					  "handover", "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_CX>,
+					<&rpmhpd RPMHPD_MXC>,
+					<&rpmhpd RPMHPD_NSP1>;
+			power-domain-names = "cx", "mxc", "nsp";
+
+			interconnects = <&nspb_noc MASTER_CDSP_PROC_B 0
+					 &mc_virt SLAVE_EBI1 0>;
+
+			memory-region = <&pil_cdsp1_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_cdsp1_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_NSP1
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_NSP1
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "cdsp";
+				qcom,remote-pid = <12>;
+
+				fastrpc {
+					compatible = "qcom,fastrpc";
+					qcom,glink-channels = "fastrpcglink-apps-dsp";
+					label = "cdsp1";
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					compute-cb@1 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <1>;
+						iommus = <&apps_smmu 0x2941 0x04a0>,
+							 <&apps_smmu 0x2981 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@2 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <2>;
+						iommus = <&apps_smmu 0x2942 0x04a0>,
+							 <&apps_smmu 0x2982 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@3 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <3>;
+						iommus = <&apps_smmu 0x2943 0x04a0>,
+							 <&apps_smmu 0x2983 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@4 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <4>;
+						iommus = <&apps_smmu 0x2944 0x04a0>,
+							 <&apps_smmu 0x2984 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@5 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <5>;
+						iommus = <&apps_smmu 0x2945 0x04a0>,
+							 <&apps_smmu 0x2985 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@6 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <6>;
+						iommus = <&apps_smmu 0x2946 0x04a0>,
+							 <&apps_smmu 0x2986 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@7 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <7>;
+						iommus = <&apps_smmu 0x2947 0x04a0>,
+							 <&apps_smmu 0x2987 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@8 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <8>;
+						iommus = <&apps_smmu 0x2948 0x04a0>,
+							 <&apps_smmu 0x2988 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@9 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <9>;
+						iommus = <&apps_smmu 0x2949 0x04a0>,
+							 <&apps_smmu 0x2989 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@10 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <10>;
+						iommus = <&apps_smmu 0x294a 0x04a0>,
+							 <&apps_smmu 0x298a 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@11 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <11>;
+						iommus = <&apps_smmu 0x294b 0x04a0>,
+							 <&apps_smmu 0x298b 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@12 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <12>;
+						iommus = <&apps_smmu 0x294c 0x04a0>,
+							 <&apps_smmu 0x298c 0x0400>;
+						dma-coherent;
+					};
+
+					compute-cb@13 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <13>;
+						iommus = <&apps_smmu 0x294d 0x04a0>,
+							 <&apps_smmu 0x298d 0x0400>;
+						dma-coherent;
+					};
+				};
+			};
+		};
+
+		remoteproc_adsp: remoteproc@30000000 {
+			compatible = "qcom,sa8775p-adsp-pas";
+			reg = <0x0 0x30000000 0x0 0x100>;
+
+			interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog", "fatal", "ready", "handover",
+					  "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_LCX>,
+					<&rpmhpd RPMHPD_LMX>;
+			power-domain-names = "lcx", "lmx";
+
+			interconnects = <&lpass_ag_noc MASTER_LPASS_PROC 0 &mc_virt SLAVE_EBI1 0>;
+
+			memory-region = <&pil_adsp_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_adsp_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			remoteproc_adsp_glink: glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_LPASS
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "lpass";
+				qcom,remote-pid = <2>;
+
+				fastrpc {
+					compatible = "qcom,fastrpc";
+					qcom,glink-channels = "fastrpcglink-apps-dsp";
+					label = "adsp";
+					memory-region = <&adsp_rpc_remote_heap_mem>;
+					qcom,vmids = <QCOM_SCM_VMID_LPASS
+							  QCOM_SCM_VMID_ADSP_HEAP>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					compute-cb@3 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <3>;
+						iommus = <&apps_smmu 0x3003 0x0>;
+						dma-coherent;
+					};
+
+					compute-cb@4 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <4>;
+						iommus = <&apps_smmu 0x3004 0x0>;
+						dma-coherent;
+					};
+
+					compute-cb@5 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <5>;
+						iommus = <&apps_smmu 0x3005 0x0>;
+						qcom,nsessions = <5>;
+						dma-coherent;
+					};
+				};
+
+				gpr {
+					compatible = "qcom,gpr";
+					qcom,glink-channels = "adsp_apps";
+					qcom,domain = <GPR_DOMAIN_ID_ADSP>;
+					qcom,intents = <512 20>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					q6apm: service@1 {
+						compatible = "qcom,q6apm";
+						reg = <GPR_APM_MODULE_IID>;
+						#sound-dai-cells = <0>;
+						qcom,protection-domain = "avs/audio",
+									 "msm/adsp/audio_pd";
+
+						q6apmdai: dais {
+							compatible = "qcom,q6apm-dais";
+							iommus = <&apps_smmu 0x3001 0x0>;
+						};
+
+						q6apmbedai: bedais {
+							compatible = "qcom,q6apm-lpass-dais";
+							#sound-dai-cells = <1>;
+						};
+					};
+
+					q6prm: service@2 {
+						compatible = "qcom,q6prm";
+						reg = <GPR_PRM_MODULE_IID>;
+						qcom,protection-domain = "avs/audio",
+									 "msm/adsp/audio_pd";
+
+						q6prmcc: clock-controller {
+							compatible = "qcom,q6prm-lpass-clocks";
+							#clock-cells = <2>;
+						};
+					};
+				};
+			};
+		};
+
+		nspa_noc: interconnect-nspa-noc@260c0000 {
+			compatible = "qcom,sa8775p-nspa-noc";
+			reg = <0x0 0x260c0000 0x0 0x16080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
+
+		nspb_noc: interconnect-nspb-noc@2a0c0000 {
+			compatible = "qcom,sa8775p-nspb-noc";
+			reg = <0x0 0x2a0c0000 0x0 0x16080>;
+			#interconnect-cells = <2>;
+			qcom,bcm-voters = <&apps_bcm_voter>;
+		};
 	};
 
-	thermal-zones {
+	thermal_zones: thermal-zones {
 		aoss-0-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens0 0>;
 
 			trips {
@@ -2479,7 +9395,6 @@
 
 		cpu-0-0-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 1>;
 
@@ -2490,7 +9405,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_0_0_0_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -2500,7 +9415,6 @@
 
 		cpu-0-1-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 2>;
 
@@ -2511,7 +9425,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_0_1_0_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -2521,7 +9435,6 @@
 
 		cpu-0-2-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 3>;
 
@@ -2532,7 +9445,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_0_2_0_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -2542,7 +9455,6 @@
 
 		cpu-0-3-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 4>;
 
@@ -2553,7 +9465,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_0_3_0_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -2563,7 +9475,6 @@
 
 		gpuss-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 5>;
 
@@ -2584,7 +9495,6 @@
 
 		gpuss-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 6>;
 
@@ -2605,7 +9515,6 @@
 
 		gpuss-2-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 7>;
 
@@ -2625,9 +9534,6 @@
 		};
 
 		audio-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens0 8>;
 
 			trips {
@@ -2646,9 +9552,6 @@
 		};
 
 		camss-0-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens0 9>;
 
 			trips {
@@ -2667,9 +9570,6 @@
 		};
 
 		pcie-0-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens0 10>;
 
 			trips {
@@ -2688,9 +9588,6 @@
 		};
 
 		cpuss-0-0-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens0 11>;
 
 			trips {
@@ -2709,9 +9606,6 @@
 		};
 
 		aoss-1-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens1 0>;
 
 			trips {
@@ -2731,7 +9625,6 @@
 
 		cpu-0-0-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 1>;
 
@@ -2742,7 +9635,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_0_0_1_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -2752,7 +9645,6 @@
 
 		cpu-0-1-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 2>;
 
@@ -2763,7 +9655,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_0_1_1_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -2773,7 +9665,6 @@
 
 		cpu-0-2-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 3>;
 
@@ -2784,7 +9675,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_0_2_1_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -2794,7 +9685,6 @@
 
 		cpu-0-3-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 4>;
 
@@ -2805,7 +9695,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_0_3_1_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -2815,7 +9705,6 @@
 
 		gpuss-3-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 5>;
 
@@ -2836,7 +9725,6 @@
 
 		gpuss-4-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 6>;
 
@@ -2857,7 +9745,6 @@
 
 		gpuss-5-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 7>;
 
@@ -2877,9 +9764,6 @@
 		};
 
 		video-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens1 8>;
 
 			trips {
@@ -2898,9 +9782,6 @@
 		};
 
 		camss-1-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens1 9>;
 
 			trips {
@@ -2919,9 +9800,6 @@
 		};
 
 		pcie-1-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens1 10>;
 
 			trips {
@@ -2940,9 +9818,6 @@
 		};
 
 		cpuss-0-1-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens1 11>;
 
 			trips {
@@ -2961,9 +9836,6 @@
 		};
 
 		aoss-2-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens2 0>;
 
 			trips {
@@ -2983,7 +9855,6 @@
 
 		cpu-1-0-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens2 1>;
 
@@ -2994,7 +9865,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_1_0_0_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -3004,7 +9875,6 @@
 
 		cpu-1-1-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens2 2>;
 
@@ -3015,7 +9885,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_1_1_0_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -3025,7 +9895,6 @@
 
 		cpu-1-2-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens2 3>;
 
@@ -3036,7 +9905,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_1_2_0_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -3046,7 +9915,6 @@
 
 		cpu-1-3-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens2 4>;
 
@@ -3057,7 +9925,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_1_3_0_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -3067,7 +9935,6 @@
 
 		nsp-0-0-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens2 5>;
 
@@ -3088,7 +9955,6 @@
 
 		nsp-0-1-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens2 6>;
 
@@ -3109,7 +9975,6 @@
 
 		nsp-0-2-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens2 7>;
 
@@ -3130,7 +9995,6 @@
 
 		nsp-1-0-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens2 8>;
 
@@ -3151,7 +10015,6 @@
 
 		nsp-1-1-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens2 9>;
 
@@ -3172,7 +10035,6 @@
 
 		nsp-1-2-0-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens2 10>;
 
@@ -3192,9 +10054,6 @@
 		};
 
 		ddrss-0-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens2 11>;
 
 			trips {
@@ -3213,9 +10072,6 @@
 		};
 
 		cpuss-1-0-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens2 12>;
 
 			trips {
@@ -3234,9 +10090,6 @@
 		};
 
 		aoss-3-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens3 0>;
 
 			trips {
@@ -3256,7 +10109,6 @@
 
 		cpu-1-0-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens3 1>;
 
@@ -3267,7 +10119,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_1_0_1_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -3277,7 +10129,6 @@
 
 		cpu-1-1-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens3 2>;
 
@@ -3288,7 +10139,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_1_1_1_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -3298,7 +10149,6 @@
 
 		cpu-1-2-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens3 3>;
 
@@ -3309,7 +10159,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_1_2_1_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -3319,7 +10169,6 @@
 
 		cpu-1-3-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens3 4>;
 
@@ -3330,7 +10179,7 @@
 					type = "passive";
 				};
 
-				trip-point1 {
+				cpu_1_3_1_alert1: trip-point1 {
 					temperature = <115000>;
 					hysteresis = <5000>;
 					type = "passive";
@@ -3340,7 +10189,6 @@
 
 		nsp-0-0-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens3 5>;
 
@@ -3361,7 +10209,6 @@
 
 		nsp-0-1-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens3 6>;
 
@@ -3382,7 +10229,6 @@
 
 		nsp-0-2-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens3 7>;
 
@@ -3403,7 +10249,6 @@
 
 		nsp-1-0-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens3 8>;
 
@@ -3424,7 +10269,6 @@
 
 		nsp-1-1-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens3 9>;
 
@@ -3445,7 +10289,6 @@
 
 		nsp-1-2-1-thermal {
 			polling-delay-passive = <10>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens3 10>;
 
@@ -3465,9 +10308,6 @@
 		};
 
 		ddrss-1-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens3 11>;
 
 			trips {
@@ -3486,9 +10326,6 @@
 		};
 
 		cpuss-1-1-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&tsens3 12>;
 
 			trips {
@@ -3512,7 +10349,25 @@
 		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
 			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 12 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_LOW)>;
+	};
+
+	turing0-etm0 {
+		compatible = "qcom,coresight-remote-etm";
+		device-name = "turing_etm0";
+
+		qcom,atid-num = <2>;
+		qcom,inst-id = <13>;
+		atid = <38 39>;
+
+		out-ports {
+			port {
+				turing0_etm0_out: endpoint {
+					remote-endpoint =
+					<&turing0_dup_funnel_in4>;
+				};
+			};
+		};
 	};
 
 	pcie0: pcie@1c00000 {
@@ -3583,6 +10438,68 @@
 		phys = <&pcie0_phy>;
 		phy-names = "pciephy";
 
+		eq-presets-8gts = /bits/ 16 <0x5555 0x5555 0x5555 0x5555
+					     0x5555 0x5555 0x5555 0x5555>;
+		eq-presets-16gts = /bits/ 8 <0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55>;
+
+		status = "disabled";
+
+		pcieport0: pcie@0 {
+			device_type = "pci";
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			bus-range = <0x01 0xff>;
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges;
+		};
+	};
+
+	pcie0_ep: pcie-ep@1c00000 {
+		compatible = "qcom,sa8775p-pcie-ep";
+		reg = <0x0 0x01c00000 0x0 0x3000>,
+		      <0x0 0x40000000 0x0 0xf20>,
+		      <0x0 0x40000f20 0x0 0xa8>,
+		      <0x0 0x40001000 0x0 0x4000>,
+		      <0x0 0x40200000 0x0 0x100000>,
+		      <0x0 0x01c03000 0x0 0x1000>,
+		      <0x0 0x40005000 0x0 0x2000>;
+		reg-names = "parf", "dbi", "elbi", "atu", "addr_space",
+			    "mmio", "dma";
+
+		clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+			<&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+			<&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
+			<&gcc GCC_PCIE_0_SLV_AXI_CLK>,
+			<&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>;
+
+		clock-names = "aux",
+			      "cfg",
+			      "bus_master",
+			      "bus_slave",
+			      "slave_q2a";
+
+		interrupts = <GIC_SPI 306 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 630 IRQ_TYPE_LEVEL_HIGH>;
+
+		interrupt-names = "global", "doorbell", "dma";
+
+		interconnects = <&pcie_anoc MASTER_PCIE_0 0 &mc_virt SLAVE_EBI1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_PCIE_0 0>;
+		interconnect-names = "pcie-mem", "cpu-pcie";
+
+		dma-coherent;
+		iommus = <&pcie_smmu 0x0000 0x7f>;
+		resets = <&gcc GCC_PCIE_0_BCR>;
+		reset-names = "core";
+		power-domains = <&gcc PCIE_0_GDSC>;
+		phys = <&pcie0_phy>;
+		phy-names = "pciephy";
+		max-link-speed = <3>; /* FIXME: Limiting the Gen speed due to stability issues */
+		num-lanes = <2>;
+		linux,pci-domain = <0>;
+
 		status = "disabled";
 	};
 
@@ -3683,6 +10600,68 @@
 		phys = <&pcie1_phy>;
 		phy-names = "pciephy";
 
+		eq-presets-8gts = /bits/ 16 <0x5555 0x5555 0x5555 0x5555
+			     0x5555 0x5555 0x5555 0x5555>;
+		eq-presets-16gts = /bits/ 8 <0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55>;
+
+		status = "disabled";
+
+		pcie@0 {
+			device_type = "pci";
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			bus-range = <0x01 0xff>;
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+			ranges;
+		};
+	};
+
+	pcie1_ep: pcie-ep@1c10000 {
+		compatible = "qcom,sa8775p-pcie-ep";
+		reg = <0x0 0x01c10000 0x0 0x3000>,
+		      <0x0 0x60000000 0x0 0xf20>,
+		      <0x0 0x60000f20 0x0 0xa8>,
+		      <0x0 0x60001000 0x0 0x4000>,
+		      <0x0 0x60200000 0x0 0x100000>,
+		      <0x0 0x01c13000 0x0 0x1000>,
+		      <0x0 0x60005000 0x0 0x2000>;
+		reg-names = "parf", "dbi", "elbi", "atu", "addr_space",
+			    "mmio", "dma";
+
+		clocks = <&gcc GCC_PCIE_1_AUX_CLK>,
+			 <&gcc GCC_PCIE_1_CFG_AHB_CLK>,
+			 <&gcc GCC_PCIE_1_MSTR_AXI_CLK>,
+			 <&gcc GCC_PCIE_1_SLV_AXI_CLK>,
+			 <&gcc GCC_PCIE_1_SLV_Q2A_AXI_CLK>;
+
+		clock-names = "aux",
+			      "cfg",
+			      "bus_master",
+			      "bus_slave",
+			      "slave_q2a";
+
+		interrupts = <GIC_SPI 518 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
+			     <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>;
+
+		interrupt-names = "global", "doorbell", "dma";
+
+		interconnects = <&pcie_anoc MASTER_PCIE_1 0 &mc_virt SLAVE_EBI1 0>,
+				<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_PCIE_1 0>;
+		interconnect-names = "pcie-mem", "cpu-pcie";
+
+		dma-coherent;
+		iommus = <&pcie_smmu 0x80 0x7f>;
+		resets = <&gcc GCC_PCIE_1_BCR>;
+		reset-names = "core";
+		power-domains = <&gcc PCIE_1_GDSC>;
+		phys = <&pcie1_phy>;
+		phy-names = "pciephy";
+		max-link-speed = <3>; /* FIXME: Limiting the Gen speed due to stability issues */
+		num-lanes = <4>;
+		linux,pci-domain = <1>;
+
 		status = "disabled";
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-firmware-tfa.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-firmware-tfa.dtsi
@@ -6,82 +6,82 @@
  * by Qualcomm firmware.
  */
 
-&CPU0 {
+&cpu0 {
 	/delete-property/ power-domains;
 	/delete-property/ power-domain-names;
 
-	cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-			   &LITTLE_CPU_SLEEP_1
-			   &CLUSTER_SLEEP_0>;
+	cpu-idle-states = <&little_cpu_sleep_0
+			   &little_cpu_sleep_1
+			   &cluster_sleep_0>;
 };
 
-&CPU1 {
+&cpu1 {
 	/delete-property/ power-domains;
 	/delete-property/ power-domain-names;
 
-	cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-			   &LITTLE_CPU_SLEEP_1
-			   &CLUSTER_SLEEP_0>;
+	cpu-idle-states = <&little_cpu_sleep_0
+			   &little_cpu_sleep_1
+			   &cluster_sleep_0>;
 };
 
-&CPU2 {
+&cpu2 {
 	/delete-property/ power-domains;
 	/delete-property/ power-domain-names;
 
-	cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-			   &LITTLE_CPU_SLEEP_1
-			   &CLUSTER_SLEEP_0>;
+	cpu-idle-states = <&little_cpu_sleep_0
+			   &little_cpu_sleep_1
+			   &cluster_sleep_0>;
 };
 
-&CPU3 {
+&cpu3 {
 	/delete-property/ power-domains;
 	/delete-property/ power-domain-names;
 
-	cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-			   &LITTLE_CPU_SLEEP_1
-			   &CLUSTER_SLEEP_0>;
+	cpu-idle-states = <&little_cpu_sleep_0
+			   &little_cpu_sleep_1
+			   &cluster_sleep_0>;
 };
 
-&CPU4 {
+&cpu4 {
 	/delete-property/ power-domains;
 	/delete-property/ power-domain-names;
 
-	cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-			   &LITTLE_CPU_SLEEP_1
-			   &CLUSTER_SLEEP_0>;
+	cpu-idle-states = <&little_cpu_sleep_0
+			   &little_cpu_sleep_1
+			   &cluster_sleep_0>;
 };
 
-&CPU5 {
+&cpu5 {
 	/delete-property/ power-domains;
 	/delete-property/ power-domain-names;
 
-	cpu-idle-states = <&LITTLE_CPU_SLEEP_0
-			   &LITTLE_CPU_SLEEP_1
-			   &CLUSTER_SLEEP_0>;
+	cpu-idle-states = <&little_cpu_sleep_0
+			   &little_cpu_sleep_1
+			   &cluster_sleep_0>;
 };
 
-&CPU6 {
+&cpu6 {
 	/delete-property/ power-domains;
 	/delete-property/ power-domain-names;
 
-	cpu-idle-states = <&BIG_CPU_SLEEP_0
-			   &BIG_CPU_SLEEP_1
-			   &CLUSTER_SLEEP_0>;
+	cpu-idle-states = <&big_cpu_sleep_0
+			   &big_cpu_sleep_1
+			   &cluster_sleep_0>;
 };
 
-&CPU7 {
+&cpu7 {
 	/delete-property/ power-domains;
 	/delete-property/ power-domain-names;
 
-	cpu-idle-states = <&BIG_CPU_SLEEP_0
-			   &BIG_CPU_SLEEP_1
-			   &CLUSTER_SLEEP_0>;
+	cpu-idle-states = <&big_cpu_sleep_0
+			   &big_cpu_sleep_1
+			   &cluster_sleep_0>;
 };
 
 /delete-node/ &domain_idle_states;
 
 &idle_states {
-	CLUSTER_SLEEP_0: cluster-sleep-0 {
+	cluster_sleep_0: cluster-sleep-0 {
 		compatible = "arm,idle-state";
 		idle-state-name = "cluster-power-down";
 		arm,psci-suspend-param = <0x40003444>;
@@ -92,15 +92,15 @@
 	};
 };
 
-/delete-node/ &CPU_PD0;
-/delete-node/ &CPU_PD1;
-/delete-node/ &CPU_PD2;
-/delete-node/ &CPU_PD3;
-/delete-node/ &CPU_PD4;
-/delete-node/ &CPU_PD5;
-/delete-node/ &CPU_PD6;
-/delete-node/ &CPU_PD7;
-/delete-node/ &CLUSTER_PD;
+/delete-node/ &cpu_pd0;
+/delete-node/ &cpu_pd1;
+/delete-node/ &cpu_pd2;
+/delete-node/ &cpu_pd3;
+/delete-node/ &cpu_pd4;
+/delete-node/ &cpu_pd5;
+/delete-node/ &cpu_pd6;
+/delete-node/ &cpu_pd7;
+/delete-node/ &cluster_pd;
 
 &apps_rsc {
 	/delete-property/ power-domains;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor-coachz.dtsi
@@ -25,7 +25,6 @@
 	thermal-zones {
 		skin_temp_thermal: skin-temp-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&pm6150_adc_tm 1>;
 			sustainable-power = <965>;
@@ -53,14 +52,14 @@
 			cooling-maps {
 				map0 {
 					trip = <&skin_temp_alert0>;
-					cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 
 				map1 {
 					trip = <&skin_temp_alert1>;
-					cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
@@ -45,7 +45,6 @@
 	thermal-zones {
 		skin_temp_thermal: skin-temp-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&pm6150_adc_tm 1>;
 			sustainable-power = <965>;
@@ -73,14 +72,14 @@
 			cooling-maps {
 				map0 {
 					trip = <&skin_temp_alert0>;
-					cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 
 				map1 {
 					trip = <&skin_temp_alert1>;
-					cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-kb.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-kb.dts
@@ -12,6 +12,6 @@
 	compatible = "google,lazor-rev1-sku2", "google,lazor-rev2-sku2", "qcom,sc7180";
 };
 
-&keyboard_backlight {
+&pwmleds {
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-lte.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1-lte.dts
@@ -17,6 +17,6 @@
 	status = "okay";
 };
 
-&keyboard_backlight {
+&pwmleds {
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-kb.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-kb.dts
@@ -18,6 +18,6 @@
 	compatible = "google,lazor-sku2", "qcom,sc7180";
 };
 
-&keyboard_backlight {
+&pwmleds {
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-lte.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r10-lte.dts
@@ -22,6 +22,6 @@
 	status = "okay";
 };
 
-&keyboard_backlight {
+&pwmleds {
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-kb.dts
@@ -21,6 +21,6 @@
 		"qcom,sc7180";
 };
 
-&keyboard_backlight {
+&pwmleds {
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r3-lte.dts
@@ -25,6 +25,6 @@
 	status = "okay";
 };
 
-&keyboard_backlight {
+&pwmleds {
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-kb.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-kb.dts
@@ -18,6 +18,6 @@
 	compatible = "google,lazor-rev9-sku2", "qcom,sc7180";
 };
 
-&keyboard_backlight {
+&pwmleds {
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-lte.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r9-lte.dts
@@ -22,6 +22,6 @@
 	status = "okay";
 };
 
-&keyboard_backlight {
+&pwmleds {
 	status = "okay";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom.dtsi
@@ -13,14 +13,11 @@
 
 / {
 	thermal-zones {
-		5v-choke-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <250>;
-
+		choke-5v-thermal {
 			thermal-sensors = <&pm6150_adc_tm 1>;
 
 			trips {
-				5v-choke-crit {
+				choke-5v-crit {
 					temperature = <125000>;
 					hysteresis = <1000>;
 					type = "critical";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor-quackingstick.dtsi
@@ -86,6 +86,7 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&lcd_rst>;
 		avdd-supply = <&ppvar_lcd>;
+		avee-supply = <&ppvar_lcd>;
 		pp1800-supply = <&v1p8_disp>;
 		pp3300-supply = <&pp3300_dx_edp>;
 		backlight = <&backlight>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor-wormdingler.dtsi
@@ -50,7 +50,6 @@
 	thermal-zones {
 		skin_temp_thermal: skin-temp-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&pm6150_adc_tm 1>;
 			sustainable-power = <574>;
@@ -78,14 +77,14 @@
 			cooling-maps {
 				map0 {
 					trip = <&skin_temp_alert0>;
-					cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 
 				map1 {
 					trip = <&skin_temp_alert1>;
-					cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi
@@ -21,9 +21,6 @@
 / {
 	thermal-zones {
 		charger_thermal: charger-thermal {
-			polling-delay-passive = <0>;
-			polling-delay = <0>;
-
 			thermal-sensors = <&pm6150_adc_tm 0>;
 
 			trips {
@@ -359,10 +356,11 @@
 		#sound-dai-cells = <0>;
 	};
 
-	pwmleds {
+	pwmleds: pwmleds {
 		compatible = "pwm-leds";
+		status = "disabled";
+
 		keyboard_backlight: led-0 {
-			status = "disabled";
 			label = "cros_ec::kbd_backlight";
 			function = LED_FUNCTION_KBD_BACKLIGHT;
 			pwms = <&cros_ec_pwm 0>;
@@ -943,6 +941,8 @@
 		vddrf-supply = <&pp1300_l2c>;
 		vddch0-supply = <&pp3300_l10c>;
 		max-speed = <3200000>;
+
+		qcom,local-bd-address-broken;
 	};
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -77,28 +77,28 @@
 		#address-cells = <2>;
 		#size-cells = <0>;
 
-		CPU0: cpu@0 {
+		cpu0: cpu@0 {
 			device_type = "cpu";
 			compatible = "qcom,kryo468";
 			reg = <0x0 0x0>;
 			clocks = <&cpufreq_hw 0>;
 			enable-method = "psci";
-			power-domains = <&CPU_PD0>;
+			power-domains = <&cpu_pd0>;
 			power-domain-names = "psci";
 			capacity-dmips-mhz = <415>;
 			dynamic-power-coefficient = <137>;
 			operating-points-v2 = <&cpu0_opp_table>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
-			next-level-cache = <&L2_0>;
+			next-level-cache = <&l2_0>;
 			#cooling-cells = <2>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
-			L2_0: l2-cache {
+			l2_0: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
 				cache-unified;
-				next-level-cache = <&L3_0>;
-				L3_0: l3-cache {
+				next-level-cache = <&l3_0>;
+				l3_0: l3-cache {
 					compatible = "cache";
 					cache-level = <3>;
 					cache-unified;
@@ -106,206 +106,206 @@
 			};
 		};
 
-		CPU1: cpu@100 {
+		cpu1: cpu@100 {
 			device_type = "cpu";
 			compatible = "qcom,kryo468";
 			reg = <0x0 0x100>;
 			clocks = <&cpufreq_hw 0>;
 			enable-method = "psci";
-			power-domains = <&CPU_PD1>;
+			power-domains = <&cpu_pd1>;
 			power-domain-names = "psci";
 			capacity-dmips-mhz = <415>;
 			dynamic-power-coefficient = <137>;
-			next-level-cache = <&L2_100>;
+			next-level-cache = <&l2_100>;
 			operating-points-v2 = <&cpu0_opp_table>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			#cooling-cells = <2>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
-			L2_100: l2-cache {
+			l2_100: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
 				cache-unified;
-				next-level-cache = <&L3_0>;
+				next-level-cache = <&l3_0>;
 			};
 		};
 
-		CPU2: cpu@200 {
+		cpu2: cpu@200 {
 			device_type = "cpu";
 			compatible = "qcom,kryo468";
 			reg = <0x0 0x200>;
 			clocks = <&cpufreq_hw 0>;
 			enable-method = "psci";
-			power-domains = <&CPU_PD2>;
+			power-domains = <&cpu_pd2>;
 			power-domain-names = "psci";
 			capacity-dmips-mhz = <415>;
 			dynamic-power-coefficient = <137>;
-			next-level-cache = <&L2_200>;
+			next-level-cache = <&l2_200>;
 			operating-points-v2 = <&cpu0_opp_table>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			#cooling-cells = <2>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
-			L2_200: l2-cache {
+			l2_200: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
 				cache-unified;
-				next-level-cache = <&L3_0>;
+				next-level-cache = <&l3_0>;
 			};
 		};
 
-		CPU3: cpu@300 {
+		cpu3: cpu@300 {
 			device_type = "cpu";
 			compatible = "qcom,kryo468";
 			reg = <0x0 0x300>;
 			clocks = <&cpufreq_hw 0>;
 			enable-method = "psci";
-			power-domains = <&CPU_PD3>;
+			power-domains = <&cpu_pd3>;
 			power-domain-names = "psci";
 			capacity-dmips-mhz = <415>;
 			dynamic-power-coefficient = <137>;
-			next-level-cache = <&L2_300>;
+			next-level-cache = <&l2_300>;
 			operating-points-v2 = <&cpu0_opp_table>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			#cooling-cells = <2>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
-			L2_300: l2-cache {
+			l2_300: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
 				cache-unified;
-				next-level-cache = <&L3_0>;
+				next-level-cache = <&l3_0>;
 			};
 		};
 
-		CPU4: cpu@400 {
+		cpu4: cpu@400 {
 			device_type = "cpu";
 			compatible = "qcom,kryo468";
 			reg = <0x0 0x400>;
 			clocks = <&cpufreq_hw 0>;
 			enable-method = "psci";
-			power-domains = <&CPU_PD4>;
+			power-domains = <&cpu_pd4>;
 			power-domain-names = "psci";
 			capacity-dmips-mhz = <415>;
 			dynamic-power-coefficient = <137>;
-			next-level-cache = <&L2_400>;
+			next-level-cache = <&l2_400>;
 			operating-points-v2 = <&cpu0_opp_table>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			#cooling-cells = <2>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
-			L2_400: l2-cache {
+			l2_400: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
 				cache-unified;
-				next-level-cache = <&L3_0>;
+				next-level-cache = <&l3_0>;
 			};
 		};
 
-		CPU5: cpu@500 {
+		cpu5: cpu@500 {
 			device_type = "cpu";
 			compatible = "qcom,kryo468";
 			reg = <0x0 0x500>;
 			clocks = <&cpufreq_hw 0>;
 			enable-method = "psci";
-			power-domains = <&CPU_PD5>;
+			power-domains = <&cpu_pd5>;
 			power-domain-names = "psci";
 			capacity-dmips-mhz = <415>;
 			dynamic-power-coefficient = <137>;
-			next-level-cache = <&L2_500>;
+			next-level-cache = <&l2_500>;
 			operating-points-v2 = <&cpu0_opp_table>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			#cooling-cells = <2>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
-			L2_500: l2-cache {
+			l2_500: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
 				cache-unified;
-				next-level-cache = <&L3_0>;
+				next-level-cache = <&l3_0>;
 			};
 		};
 
-		CPU6: cpu@600 {
+		cpu6: cpu@600 {
 			device_type = "cpu";
 			compatible = "qcom,kryo468";
 			reg = <0x0 0x600>;
 			clocks = <&cpufreq_hw 1>;
 			enable-method = "psci";
-			power-domains = <&CPU_PD6>;
+			power-domains = <&cpu_pd6>;
 			power-domain-names = "psci";
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <480>;
-			next-level-cache = <&L2_600>;
+			next-level-cache = <&l2_600>;
 			operating-points-v2 = <&cpu6_opp_table>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			#cooling-cells = <2>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
-			L2_600: l2-cache {
+			l2_600: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
 				cache-unified;
-				next-level-cache = <&L3_0>;
+				next-level-cache = <&l3_0>;
 			};
 		};
 
-		CPU7: cpu@700 {
+		cpu7: cpu@700 {
 			device_type = "cpu";
 			compatible = "qcom,kryo468";
 			reg = <0x0 0x700>;
 			clocks = <&cpufreq_hw 1>;
 			enable-method = "psci";
-			power-domains = <&CPU_PD7>;
+			power-domains = <&cpu_pd7>;
 			power-domain-names = "psci";
 			capacity-dmips-mhz = <1024>;
 			dynamic-power-coefficient = <480>;
-			next-level-cache = <&L2_700>;
+			next-level-cache = <&l2_700>;
 			operating-points-v2 = <&cpu6_opp_table>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&osm_l3 MASTER_OSM_L3_APPS &osm_l3 SLAVE_OSM_L3>;
 			#cooling-cells = <2>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
-			L2_700: l2-cache {
+			l2_700: l2-cache {
 				compatible = "cache";
 				cache-level = <2>;
 				cache-unified;
-				next-level-cache = <&L3_0>;
+				next-level-cache = <&l3_0>;
 			};
 		};
 
 		cpu-map {
 			cluster0 {
 				core0 {
-					cpu = <&CPU0>;
+					cpu = <&cpu0>;
 				};
 
 				core1 {
-					cpu = <&CPU1>;
+					cpu = <&cpu1>;
 				};
 
 				core2 {
-					cpu = <&CPU2>;
+					cpu = <&cpu2>;
 				};
 
 				core3 {
-					cpu = <&CPU3>;
+					cpu = <&cpu3>;
 				};
 
 				core4 {
-					cpu = <&CPU4>;
+					cpu = <&cpu4>;
 				};
 
 				core5 {
-					cpu = <&CPU5>;
+					cpu = <&cpu5>;
 				};
 
 				core6 {
-					cpu = <&CPU6>;
+					cpu = <&cpu6>;
 				};
 
 				core7 {
-					cpu = <&CPU7>;
+					cpu = <&cpu7>;
 				};
 			};
 		};
@@ -313,7 +313,7 @@
 		idle_states: idle-states {
 			entry-method = "psci";
 
-			LITTLE_CPU_SLEEP_0: cpu-sleep-0-0 {
+			little_cpu_sleep_0: cpu-sleep-0-0 {
 				compatible = "arm,idle-state";
 				idle-state-name = "little-power-down";
 				arm,psci-suspend-param = <0x40000003>;
@@ -323,7 +323,7 @@
 				local-timer-stop;
 			};
 
-			LITTLE_CPU_SLEEP_1: cpu-sleep-0-1 {
+			little_cpu_sleep_1: cpu-sleep-0-1 {
 				compatible = "arm,idle-state";
 				idle-state-name = "little-rail-power-down";
 				arm,psci-suspend-param = <0x40000004>;
@@ -333,7 +333,7 @@
 				local-timer-stop;
 			};
 
-			BIG_CPU_SLEEP_0: cpu-sleep-1-0 {
+			big_cpu_sleep_0: cpu-sleep-1-0 {
 				compatible = "arm,idle-state";
 				idle-state-name = "big-power-down";
 				arm,psci-suspend-param = <0x40000003>;
@@ -343,7 +343,7 @@
 				local-timer-stop;
 			};
 
-			BIG_CPU_SLEEP_1: cpu-sleep-1-1 {
+			big_cpu_sleep_1: cpu-sleep-1-1 {
 				compatible = "arm,idle-state";
 				idle-state-name = "big-rail-power-down";
 				arm,psci-suspend-param = <0x40000004>;
@@ -355,7 +355,7 @@
 		};
 
 		domain_idle_states: domain-idle-states {
-			CLUSTER_SLEEP_PC: cluster-sleep-0 {
+			cluster_sleep_pc: cluster-sleep-0 {
 				compatible = "domain-idle-state";
 				idle-state-name = "cluster-l3-power-collapse";
 				arm,psci-suspend-param = <0x41000044>;
@@ -364,7 +364,7 @@
 				min-residency-us = <6118>;
 			};
 
-			CLUSTER_SLEEP_CX_RET: cluster-sleep-1 {
+			cluster_sleep_cx_ret: cluster-sleep-1 {
 				compatible = "domain-idle-state";
 				idle-state-name = "cluster-cx-retention";
 				arm,psci-suspend-param = <0x41001244>;
@@ -373,7 +373,7 @@
 				min-residency-us = <8467>;
 			};
 
-			CLUSTER_AOSS_SLEEP: cluster-sleep-2 {
+			cluster_aoss_sleep: cluster-sleep-2 {
 				compatible = "domain-idle-state";
 				idle-state-name = "cluster-power-down";
 				arm,psci-suspend-param = <0x4100b244>;
@@ -583,59 +583,59 @@
 		compatible = "arm,psci-1.0";
 		method = "smc";
 
-		CPU_PD0: cpu0 {
+		cpu_pd0: power-domain-cpu0 {
 			#power-domain-cells = <0>;
-			power-domains = <&CLUSTER_PD>;
-			domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
 		};
 
-		CPU_PD1: cpu1 {
+		cpu_pd1: power-domain-cpu1 {
 			#power-domain-cells = <0>;
-			power-domains = <&CLUSTER_PD>;
-			domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
 		};
 
-		CPU_PD2: cpu2 {
+		cpu_pd2: power-domain-cpu2 {
 			#power-domain-cells = <0>;
-			power-domains = <&CLUSTER_PD>;
-			domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
 		};
 
-		CPU_PD3: cpu3 {
+		cpu_pd3: power-domain-cpu3 {
 			#power-domain-cells = <0>;
-			power-domains = <&CLUSTER_PD>;
-			domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
 		};
 
-		CPU_PD4: cpu4 {
+		cpu_pd4: power-domain-cpu4 {
 			#power-domain-cells = <0>;
-			power-domains = <&CLUSTER_PD>;
-			domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
 		};
 
-		CPU_PD5: cpu5 {
+		cpu_pd5: power-domain-cpu5 {
 			#power-domain-cells = <0>;
-			power-domains = <&CLUSTER_PD>;
-			domain-idle-states = <&LITTLE_CPU_SLEEP_0 &LITTLE_CPU_SLEEP_1>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&little_cpu_sleep_0 &little_cpu_sleep_1>;
 		};
 
-		CPU_PD6: cpu6 {
+		cpu_pd6: power-domain-cpu6 {
 			#power-domain-cells = <0>;
-			power-domains = <&CLUSTER_PD>;
-			domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>;
 		};
 
-		CPU_PD7: cpu7 {
+		cpu_pd7: power-domain-cpu7 {
 			#power-domain-cells = <0>;
-			power-domains = <&CLUSTER_PD>;
-			domain-idle-states = <&BIG_CPU_SLEEP_0 &BIG_CPU_SLEEP_1>;
+			power-domains = <&cluster_pd>;
+			domain-idle-states = <&big_cpu_sleep_0 &big_cpu_sleep_1>;
 		};
 
-		CLUSTER_PD: cpu-cluster0 {
+		cluster_pd: power-domain-cluster {
 			#power-domain-cells = <0>;
-			domain-idle-states = <&CLUSTER_SLEEP_PC
-					      &CLUSTER_SLEEP_CX_RET
-					      &CLUSTER_AOSS_SLEEP>;
+			domain-idle-states = <&cluster_sleep_pc
+					      &cluster_sleep_cx_ret
+					      &cluster_aoss_sleep>;
 		};
 	};
 
@@ -817,7 +817,7 @@
 				bits = <1 3>;
 			};
 
-			gpu_speed_bin: gpu_speed_bin@1d2 {
+			gpu_speed_bin: gpu-speed-bin@1d2 {
 				reg = <0x1d2 0x2>;
 				bits = <5 8>;
 			};
@@ -2473,7 +2473,7 @@
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07040000 0 0x1000>;
 
-			cpu = <&CPU0>;
+			cpu = <&cpu0>;
 
 			clocks = <&aoss_qmp>;
 			clock-names = "apb_pclk";
@@ -2493,7 +2493,7 @@
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07140000 0 0x1000>;
 
-			cpu = <&CPU1>;
+			cpu = <&cpu1>;
 
 			clocks = <&aoss_qmp>;
 			clock-names = "apb_pclk";
@@ -2513,7 +2513,7 @@
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07240000 0 0x1000>;
 
-			cpu = <&CPU2>;
+			cpu = <&cpu2>;
 
 			clocks = <&aoss_qmp>;
 			clock-names = "apb_pclk";
@@ -2533,7 +2533,7 @@
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07340000 0 0x1000>;
 
-			cpu = <&CPU3>;
+			cpu = <&cpu3>;
 
 			clocks = <&aoss_qmp>;
 			clock-names = "apb_pclk";
@@ -2553,7 +2553,7 @@
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07440000 0 0x1000>;
 
-			cpu = <&CPU4>;
+			cpu = <&cpu4>;
 
 			clocks = <&aoss_qmp>;
 			clock-names = "apb_pclk";
@@ -2573,7 +2573,7 @@
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07540000 0 0x1000>;
 
-			cpu = <&CPU5>;
+			cpu = <&cpu5>;
 
 			clocks = <&aoss_qmp>;
 			clock-names = "apb_pclk";
@@ -2593,7 +2593,7 @@
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07640000 0 0x1000>;
 
-			cpu = <&CPU6>;
+			cpu = <&cpu6>;
 
 			clocks = <&aoss_qmp>;
 			clock-names = "apb_pclk";
@@ -2613,7 +2613,7 @@
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07740000 0 0x1000>;
 
-			cpu = <&CPU7>;
+			cpu = <&cpu7>;
 
 			clocks = <&aoss_qmp>;
 			clock-names = "apb_pclk";
@@ -2964,12 +2964,16 @@
 					  <&gcc GCC_USB30_PRIM_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <150000000>;
 
-			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 6 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 8 IRQ_TYPE_EDGE_BOTH>,
-					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
-			interrupt-names = "hs_phy_irq", "ss_phy_irq",
-					  "dm_hs_phy_irq", "dp_hs_phy_irq";
+					      <&pdc 6 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
+					  "dp_hs_phy_irq",
+					  "dm_hs_phy_irq",
+					  "ss_phy_irq";
 
 			power-domains = <&gcc USB30_PRIM_GDSC>;
 			required-opps = <&rpmhpd_opp_nom>;
@@ -2989,6 +2993,7 @@
 				iommus = <&apps_smmu 0x540 0>;
 				snps,dis_u2_susphy_quirk;
 				snps,dis_enblslpm_quirk;
+				snps,parkmode-disable-ss-quirk;
 				phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
 				phy-names = "usb2-phy", "usb3-phy";
 				maximum-speed = "super-speed";
@@ -3656,7 +3661,7 @@
 					  <SLEEP_TCS   3>,
 					  <WAKE_TCS    3>,
 					  <CONTROL_TCS 1>;
-			power-domains = <&CLUSTER_PD>;
+			power-domains = <&cluster_pd>;
 
 			rpmhcc: clock-controller {
 				compatible = "qcom,sc7180-rpmh-clk";
@@ -3958,7 +3963,6 @@
 	thermal-zones {
 		cpu0_thermal: cpu0-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 1>;
 			sustainable-power = <1052>;
@@ -3986,28 +3990,27 @@
 			cooling-maps {
 				map0 {
 					trip = <&cpu0_alert0>;
-					cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 				map1 {
 					trip = <&cpu0_alert1>;
-					cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
 
 		cpu1_thermal: cpu1-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 2>;
 			sustainable-power = <1052>;
@@ -4035,28 +4038,27 @@
 			cooling-maps {
 				map0 {
 					trip = <&cpu1_alert0>;
-					cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 				map1 {
 					trip = <&cpu1_alert1>;
-					cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
 
 		cpu2_thermal: cpu2-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 3>;
 			sustainable-power = <1052>;
@@ -4084,28 +4086,27 @@
 			cooling-maps {
 				map0 {
 					trip = <&cpu2_alert0>;
-					cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 				map1 {
 					trip = <&cpu2_alert1>;
-					cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
 
 		cpu3_thermal: cpu3-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 4>;
 			sustainable-power = <1052>;
@@ -4133,28 +4134,27 @@
 			cooling-maps {
 				map0 {
 					trip = <&cpu3_alert0>;
-					cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 				map1 {
 					trip = <&cpu3_alert1>;
-					cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
 
 		cpu4_thermal: cpu4-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 5>;
 			sustainable-power = <1052>;
@@ -4182,28 +4182,27 @@
 			cooling-maps {
 				map0 {
 					trip = <&cpu4_alert0>;
-					cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 				map1 {
 					trip = <&cpu4_alert1>;
-					cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
 
 		cpu5_thermal: cpu5-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 6>;
 			sustainable-power = <1052>;
@@ -4231,28 +4230,27 @@
 			cooling-maps {
 				map0 {
 					trip = <&cpu5_alert0>;
-					cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 				map1 {
 					trip = <&cpu5_alert1>;
-					cooling-device = <&CPU0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
 
 		cpu6_thermal: cpu6-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 9>;
 			sustainable-power = <1425>;
@@ -4280,20 +4278,19 @@
 			cooling-maps {
 				map0 {
 					trip = <&cpu6_alert0>;
-					cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 				map1 {
 					trip = <&cpu6_alert1>;
-					cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
 
 		cpu7_thermal: cpu7-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 10>;
 			sustainable-power = <1425>;
@@ -4321,20 +4318,19 @@
 			cooling-maps {
 				map0 {
 					trip = <&cpu7_alert0>;
-					cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 				map1 {
 					trip = <&cpu7_alert1>;
-					cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
 
 		cpu8_thermal: cpu8-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 11>;
 			sustainable-power = <1425>;
@@ -4362,20 +4358,19 @@
 			cooling-maps {
 				map0 {
 					trip = <&cpu8_alert0>;
-					cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 				map1 {
 					trip = <&cpu8_alert1>;
-					cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
 
 		cpu9_thermal: cpu9-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 12>;
 			sustainable-power = <1425>;
@@ -4403,20 +4398,19 @@
 			cooling-maps {
 				map0 {
 					trip = <&cpu9_alert0>;
-					cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 				map1 {
 					trip = <&cpu9_alert1>;
-					cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
-							 <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+					cooling-device = <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+							 <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
 				};
 			};
 		};
 
 		aoss0-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 0>;
 
@@ -4437,7 +4431,6 @@
 
 		cpuss0-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 7>;
 
@@ -4457,7 +4450,6 @@
 
 		cpuss1-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 8>;
 
@@ -4477,7 +4469,6 @@
 
 		gpuss0-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 13>;
 
@@ -4505,7 +4496,6 @@
 
 		gpuss1-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens0 14>;
 
@@ -4533,7 +4523,6 @@
 
 		aoss1-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 0>;
 
@@ -4554,7 +4543,6 @@
 
 		cwlan-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 1>;
 
@@ -4575,7 +4563,6 @@
 
 		audio-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 2>;
 
@@ -4596,7 +4583,6 @@
 
 		ddr-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 3>;
 
@@ -4617,7 +4603,6 @@
 
 		q6-hvx-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 4>;
 
@@ -4638,7 +4623,6 @@
 
 		camera-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 5>;
 
@@ -4659,7 +4643,6 @@
 
 		mdm-core-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 6>;
 
@@ -4680,7 +4663,6 @@
 
 		mdm-dsp-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 7>;
 
@@ -4701,7 +4683,6 @@
 
 		npu-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 8>;
 
@@ -4722,7 +4703,6 @@
 
 		video-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
 
 			thermal-sensors = <&tsens1 9>;
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi
@@ -18,6 +18,7 @@
  */
 
 /delete-node/ &cdsp_mem;
+/delete-node/ &domain_idle_states;
 /delete-node/ &gpu_zap_mem;
 /delete-node/ &gpu_zap_shader;
 /delete-node/ &hyp_mem;
@@ -26,6 +27,18 @@
 /delete-node/ &sec_apps_mem;
 
 / {
+	cpus {
+		domain_idle_states: domain-idle-states {
+			CLUSTER_SLEEP_0: cluster-sleep-0 {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x40003444>;
+				entry-latency-us = <2752>;
+				exit-latency-us = <6562>;
+				min-residency-us = <9926>;
+			};
+		};
+	};
+
 	reserved-memory {
 		camera_mem: memory@8ad00000 {
 			reg = <0x0 0x8ad00000 0x0 0x500000>;
@@ -39,6 +52,14 @@
 	};
 };
 
+&CLUSTER_PD {
+	domain-idle-states = <&CLUSTER_SLEEP_0>;
+};
+
+&gpu {
+	status = "okay";
+};
+
 &lpass_aon {
 	status = "okay";
 };
@@ -123,6 +144,14 @@
 	status = "okay";
 };
 
+&venus {
+	status = "okay";
+
+	video-firmware {
+		iommus = <&apps_smmu 0x21a2 0x0>;
+	};
+};
+
 &wifi {
 	status = "okay";
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7280-idp.dtsi
@@ -495,7 +495,6 @@
 };
 
 &uart5 {
-	compatible = "qcom,geni-debug-uart";
 	status = "okay";
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7280-qcard.dtsi
@@ -427,7 +427,6 @@
 };
 
 uart_dbg: &uart5 {
-	compatible = "qcom,geni-debug-uart";
 	status = "okay";
 };
 
@@ -678,3 +677,11 @@
 		bias-disable;
 	};
 };
+
+&venus {
+	status = "okay";
+
+	video-firmware {
+		iommus = <&apps_smmu 0x21a2 0x0>;
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -53,8 +53,8 @@
 		i2c13 = &i2c13;
 		i2c14 = &i2c14;
 		i2c15 = &i2c15;
-		mmc1 = &sdhc_1;
-		mmc2 = &sdhc_2;
+		mmc0 = &sdhc_1;
+		mmc1 = &sdhc_2;
 		spi0 = &spi0;
 		spi1 = &spi1;
 		spi2 = &spi2;
@@ -82,7 +82,7 @@
 
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
-			clock-frequency = <32000>;
+			clock-frequency = <32764>;
 			#clock-cells = <0>;
 		};
 	};
@@ -202,6 +202,8 @@
 			power-domain-names = "psci";
 			next-level-cache = <&L2_0>;
 			operating-points-v2 = <&cpu0_opp_table>;
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
@@ -229,6 +231,8 @@
 			power-domain-names = "psci";
 			next-level-cache = <&L2_100>;
 			operating-points-v2 = <&cpu0_opp_table>;
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
@@ -251,6 +255,8 @@
 			power-domain-names = "psci";
 			next-level-cache = <&L2_200>;
 			operating-points-v2 = <&cpu0_opp_table>;
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
@@ -273,6 +279,8 @@
 			power-domain-names = "psci";
 			next-level-cache = <&L2_300>;
 			operating-points-v2 = <&cpu0_opp_table>;
+			capacity-dmips-mhz = <1024>;
+			dynamic-power-coefficient = <100>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
 			qcom,freq-domain = <&cpufreq_hw 0>;
@@ -295,6 +303,8 @@
 			power-domain-names = "psci";
 			next-level-cache = <&L2_400>;
 			operating-points-v2 = <&cpu4_opp_table>;
+			capacity-dmips-mhz = <1946>;
+			dynamic-power-coefficient = <520>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
@@ -317,6 +327,8 @@
 			power-domain-names = "psci";
 			next-level-cache = <&L2_500>;
 			operating-points-v2 = <&cpu4_opp_table>;
+			capacity-dmips-mhz = <1946>;
+			dynamic-power-coefficient = <520>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
@@ -339,6 +351,8 @@
 			power-domain-names = "psci";
 			next-level-cache = <&L2_600>;
 			operating-points-v2 = <&cpu4_opp_table>;
+			capacity-dmips-mhz = <1946>;
+			dynamic-power-coefficient = <520>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
 			qcom,freq-domain = <&cpufreq_hw 1>;
@@ -361,6 +375,8 @@
 			power-domain-names = "psci";
 			next-level-cache = <&L2_700>;
 			operating-points-v2 = <&cpu7_opp_table>;
+			capacity-dmips-mhz = <1985>;
+			dynamic-power-coefficient = <552>;
 			interconnects = <&gem_noc MASTER_APPSS_PROC 3 &mc_virt SLAVE_EBI1 3>,
 					<&epss_l3 MASTER_EPSS_L3_APPS &epss_l3 SLAVE_EPSS_L3_SHARED>;
 			qcom,freq-domain = <&cpufreq_hw 2>;
@@ -453,15 +469,29 @@
 			};
 		};
 
-		domain-idle-states {
-			CLUSTER_SLEEP_0: cluster-sleep-0 {
+		domain_idle_states: domain-idle-states {
+			CLUSTER_SLEEP_APSS_OFF: cluster-sleep-0 {
 				compatible = "domain-idle-state";
-				idle-state-name = "cluster-power-down";
-				arm,psci-suspend-param = <0x40003444>;
+				arm,psci-suspend-param = <0x41000044>;
+				entry-latency-us = <2752>;
+				exit-latency-us = <3048>;
+				min-residency-us = <6118>;
+			};
+
+			CLUSTER_SLEEP_CX_RET: cluster-sleep-1 {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x41001344>;
 				entry-latency-us = <3263>;
+				exit-latency-us = <4562>;
+				min-residency-us = <8467>;
+			};
+
+			CLUSTER_SLEEP_LLCC_OFF: cluster-sleep-2 {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x4100b344>;
+				entry-latency-us = <3638>;
 				exit-latency-us = <6562>;
-				min-residency-us = <9926>;
-				local-timer-stop;
+				min-residency-us = <9826>;
 			};
 		};
 	};
@@ -587,12 +617,12 @@
 
 		cpu4_opp_2400mhz: opp-2400000000 {
 			opp-hz = /bits/ 64 <2400000000>;
-			opp-peak-kBps = <8532000 48537600>;
+			opp-peak-kBps = <12787200 48537600>;
 		};
 
 		cpu4_opp_2611mhz: opp-2611200000 {
 			opp-hz = /bits/ 64 <2611200000>;
-			opp-peak-kBps = <8532000 48537600>;
+			opp-peak-kBps = <12787200 48537600>;
 		};
 	};
 
@@ -652,22 +682,22 @@
 
 		cpu7_opp_2400mhz: opp-2400000000 {
 			opp-hz = /bits/ 64 <2400000000>;
-			opp-peak-kBps = <8532000 48537600>;
+			opp-peak-kBps = <12787200 48537600>;
 		};
 
 		cpu7_opp_2515mhz: opp-2515200000 {
 			opp-hz = /bits/ 64 <2515200000>;
-			opp-peak-kBps = <8532000 48537600>;
+			opp-peak-kBps = <12787200 48537600>;
 		};
 
 		cpu7_opp_2707mhz: opp-2707200000 {
 			opp-hz = /bits/ 64 <2707200000>;
-			opp-peak-kBps = <8532000 48537600>;
+			opp-peak-kBps = <12787200 48537600>;
 		};
 
 		cpu7_opp_3014mhz: opp-3014400000 {
 			opp-hz = /bits/ 64 <3014400000>;
-			opp-peak-kBps = <8532000 48537600>;
+			opp-peak-kBps = <12787200 48537600>;
 		};
 	};
 
@@ -872,7 +902,7 @@
 
 		CLUSTER_PD: power-domain-cluster {
 			#power-domain-cells = <0>;
-			domain-idle-states = <&CLUSTER_SLEEP_0>;
+			domain-idle-states = <&CLUSTER_SLEEP_APSS_OFF &CLUSTER_SLEEP_CX_RET &CLUSTER_SLEEP_LLCC_OFF>;
 		};
 	};
 
@@ -931,7 +961,7 @@
 			reg = <0 0x00100000 0 0x1f0000>;
 			clocks = <&rpmhcc RPMH_CXO_CLK>,
 				 <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>,
-				 <0>, <&pcie1_phy>,
+				 <&pcie0_phy>, <&pcie1_phy>,
 				 <&ufs_mem_phy 0>, <&ufs_mem_phy 1>, <&ufs_mem_phy 2>,
 				 <&usb_1_qmpphy QMP_USB43DP_USB3_PIPE_CLK>;
 			clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk",
@@ -966,7 +996,7 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 
-			gpu_speed_bin: gpu_speed_bin@1e9 {
+			gpu_speed_bin: gpu-speed-bin@1e9 {
 				reg = <0x1e9 0x2>;
 				bits = <5 8>;
 			};
@@ -1410,12 +1440,12 @@
 			};
 
 			uart5: serial@994000 {
-				compatible = "qcom,geni-uart";
+				compatible = "qcom,geni-debug-uart";
 				reg = <0 0x00994000 0 0x4000>;
 				clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
 				clock-names = "se";
 				pinctrl-names = "default";
-				pinctrl-0 = <&qup_uart5_cts>, <&qup_uart5_rts>, <&qup_uart5_tx>, <&qup_uart5_rx>;
+				pinctrl-0 = <&qup_uart5_tx>, <&qup_uart5_rx>;
 				interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>;
 				power-domains = <&rpmhpd SC7280_CX>;
 				operating-points-v2 = <&qup_opp_table>;
@@ -2099,6 +2129,8 @@
 			reg = <0 0x016e0000 0 0x1c080>;
 			#interconnect-cells = <2>;
 			qcom,bcm-voters = <&apps_bcm_voter>;
+			clocks = <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+				<&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>;
 		};
 
 		aggre2_noc: interconnect@1700000 {
@@ -2106,6 +2138,7 @@
 			compatible = "qcom,sc7280-aggre2-noc";
 			#interconnect-cells = <2>;
 			qcom,bcm-voters = <&apps_bcm_voter>;
+			clocks = <&rpmhcc RPMH_IPA_CLK>;
 		};
 
 		mmss_noc: interconnect@1740000 {
@@ -2158,6 +2191,114 @@
 			qcom,smem-state-names = "wlan-smp2p-out";
 		};
 
+		pcie0: pci@1c00000 {
+			compatible = "qcom,pcie-sc7280";
+			reg = <0x0 0x01c00000 0x0 0x3000>,
+				<0x0 0x60000000 0x0 0xf1d>,
+				<0x0 0x60000f20 0x0 0xa8>,
+				<0x0 0x60001000 0x0 0x1000>,
+				<0x0 0x60100000 0x0 0x100000>;
+
+			reg-names = "parf", "dbi", "elbi", "atu", "config";
+			device_type = "pci";
+			linux,pci-domain = <0>;
+			bus-range = <0x00 0xff>;
+			num-lanes = <1>;
+
+			#address-cells = <3>;
+			#size-cells = <2>;
+
+			ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>,
+				 <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x3d00000>;
+
+			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi";
+			#interrupt-cells = <1>;
+			interrupt-map-mask = <0 0 0 0x7>;
+			interrupt-map = <0 0 0 1 &intc 0 0 0 149 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 2 &intc 0 0 0 150 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 3 &intc 0 0 0 151 IRQ_TYPE_LEVEL_HIGH>,
+					<0 0 0 4 &intc 0 0 0 152 IRQ_TYPE_LEVEL_HIGH>;
+
+			clocks = <&gcc GCC_PCIE_0_PIPE_CLK>,
+				 <&gcc GCC_PCIE_0_PIPE_CLK_SRC>,
+				 <&pcie0_phy>,
+				 <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_PCIE_0_AUX_CLK>,
+				 <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				 <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
+				 <&gcc GCC_PCIE_0_SLV_AXI_CLK>,
+				 <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>,
+				 <&gcc GCC_AGGRE_NOC_PCIE_TBU_CLK>,
+				 <&gcc GCC_DDRSS_PCIE_SF_CLK>,
+				 <&gcc GCC_AGGRE_NOC_PCIE_CENTER_SF_AXI_CLK>,
+				 <&gcc GCC_AGGRE_NOC_PCIE_0_AXI_CLK>;
+
+			clock-names = "pipe",
+					"pipe_mux",
+					"phy_pipe",
+					"ref",
+					"aux",
+					"cfg",
+					"bus_master",
+					"bus_slave",
+					"slave_q2a",
+					"tbu",
+					"ddrss_sf_tbu",
+					"aggre0",
+					"aggre1";
+
+			assigned-clocks = <&gcc GCC_PCIE_0_AUX_CLK>;
+			assigned-clock-rates = <19200000>;
+
+			resets = <&gcc GCC_PCIE_0_BCR>;
+			reset-names = "pci";
+
+			power-domains = <&gcc GCC_PCIE_0_GDSC>;
+
+			phys = <&pcie0_phy>;
+			phy-names = "pciephy";
+
+			perst-gpios = <&tlmm 87 GPIO_ACTIVE_LOW>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&pcie0_clkreq_n>, <&pcie0_reset_n>, <&pcie0_wake_n>;
+
+			dma-coherent;
+
+			iommu-map = <0x0 &apps_smmu 0x1c00 0x1>,
+				   <0x100 &apps_smmu 0x1c01 0x1>;
+
+			status = "disabled";
+		};
+
+		pcie0_phy: phy@1c06000 {
+			compatible = "qcom,sm8250-qmp-gen3x1-pcie-phy";
+			reg = <0x0 0x01c06000 0x0 0x1000>;
+			clocks = <&gcc GCC_PCIE_0_AUX_CLK>,
+				<&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+				<&gcc GCC_PCIE_CLKREF_EN>,
+				<&gcc GCC_PCIE0_PHY_RCHNG_CLK>,
+				<&gcc GCC_PCIE_0_PIPE_CLK>;
+			clock-names = "aux",
+				      "cfg_ahb",
+				      "ref",
+				      "refgen",
+				      "pipe";
+
+			clock-output-names = "pcie_0_pipe_clk";
+			#clock-cells = <0>;
+
+			#phy-cells = <0>;
+
+			resets = <&gcc GCC_PCIE_0_PHY_BCR>;
+			reset-names = "phy";
+
+			assigned-clocks = <&gcc GCC_PCIE0_PHY_RCHNG_CLK>;
+			assigned-clock-rates = <100000000>;
+
+			status = "disabled";
+		};
+
 		pcie1: pcie@1c08000 {
 			compatible = "qcom,pcie-sc7280";
 			reg = <0 0x01c08000 0 0x3000>,
@@ -2178,8 +2319,16 @@
 			ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
 				 <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
 
-			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "msi";
+			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi0", "msi1", "msi2", "msi3",
+					  "msi4", "msi5", "msi6", "msi7";
 			#interrupt-cells = <1>;
 			interrupt-map-mask = <0 0 0 0x7>;
 			interrupt-map = <0 0 0 1 &intc 0 0 0 434 IRQ_TYPE_LEVEL_HIGH>,
@@ -2314,6 +2463,7 @@
 				<0 0>,
 				<0 0>,
 				<0 0>;
+			qcom,ice = <&ice>;
 			status = "disabled";
 		};
 
@@ -2345,6 +2495,8 @@
 				 <&apps_smmu 0x4e6 0x0011>;
 			qcom,ee = <0>;
 			qcom,controlled-remotely;
+			num-channels = <16>;
+			qcom,num-ees = <4>;
 		};
 
 		crypto: crypto@1dfa000 {
@@ -2356,6 +2508,7 @@
 				 <&apps_smmu 0x4e4 0x0011>;
 			interconnects = <&aggre2_noc MASTER_CRYPTO 0 &mc_virt SLAVE_EBI1 0>;
 			interconnect-names = "memory";
+			qcom,icc_bw = <12473>;
 		};
 
 		ipa: ipa@1e40000 {
@@ -2523,10 +2676,69 @@
 			qcom,ports-block-pack-mode =	/bits/ 8 <0xff 0xff 0xff>;
 			qcom,ports-block-group-count =	/bits/ 8 <0xff 0xff 0xff>;
 			qcom,ports-lane-control =	/bits/ 8 <0x00 0x01 0x00>;
+			qcom,ports-chmask =		/bits/ 8 <0x02 0x00 0x04>;
+
+			#sound-dai-cells = <1>;
+			#address-cells = <2>;
+			#size-cells = <0>;
+
+			status = "disabled";
+		};
 
+		lpass_wsa_macro: codec@3240000 {
+			compatible = "qcom,sc7280-lpass-wsa-macro";
+			reg = <0x0 0x03240000 0x0 0x1000>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&lpass_wsa_swr_clk>, <&lpass_wsa_swr_data>;
+
+			clocks = <&lpass_aon LPASS_AON_CC_TX_MCLK_CLK>,
+				 <&lpass_aon LPASS_AON_CC_TX_MCLK_2X_CLK>,
+				 <&lpass_va_macro>;
+			clock-names = "mclk", "npl", "fsgen";
+
+			power-domains = <&lpass_hm LPASS_CORE_CC_LPASS_CORE_HM_GDSC>,
+					<&lpass_aon LPASS_AON_CC_LPASS_AUDIO_HM_GDSC>;
+			power-domain-names = "macro", "dcodec";
+
+			#clock-cells = <0>;
+			clock-output-names = "mclk";
 			#sound-dai-cells = <1>;
+
+			status = "disabled";
+		};
+
+		swr2: soundwire@3250000 {
+			compatible = "qcom,soundwire-v1.6.0";
+			reg = <0x0 0x03250000 0x0 0x2000>;
+
+			interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&lpass_wsa_macro>;
+			clock-names = "iface";
+
+			qcom,din-ports = <2>;
+			qcom,dout-ports = <6>;
+
+			resets = <&lpass_audiocc LPASS_AUDIO_SWR_WSA_CGCR>;
+			reset-names = "swr_audio_cgcr";
+
+			qcom,ports-sinterval-low = /bits/ 8 <0x07 0x1f 0x3f 0x07
+								0x1f 0x3f 0x0f 0x0f>;
+			qcom,ports-offset1 = /bits/ 8 <0x01 0x02 0x0c 0x06 0x12 0x0d 0x07 0x0a>;
+			qcom,ports-offset2 = /bits/ 8 <0xff 0x00 0x1f 0xff 0x00 0x1f 0x00 0x00>;
+			qcom,ports-hstart = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
+			qcom,ports-hstop = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
+			qcom,ports-word-length = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff>;
+			qcom,ports-block-pack-mode = /bits/ 8 <0xff 0xff 0x01 0xff 0xff 0x01
+							       0xff 0xff>;
+			qcom,ports-block-group-count = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff
+								0xff 0xff>;
+			qcom,ports-lane-control = /bits/ 8 <0xff 0xff 0xff 0xff 0xff 0xff
+							    0xff 0xff>;
+
 			#address-cells = <2>;
 			#size-cells = <0>;
+			#sound-dai-cells = <1>;
 
 			status = "disabled";
 		};
@@ -2648,6 +2860,31 @@
 			status = "disabled";
 		};
 
+		slimbam: dma-controller@3a84000 {
+			compatible = "qcom,bam-v1.7.0";
+			reg = <0 0x03a84000 0 0x20000>;
+			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			qcom,controlled-remotely;
+			num-channels  = <31>;
+			qcom,ee = <1>;
+			qcom,num-ees = <2>;
+			iommus = <&apps_smmu 0x1826 0x0>;
+			status = "disabled";
+		};
+
+		slim: slim-ngd@3ac0000 {
+			compatible = "qcom,slim-ngd-v1.5.0";
+			reg = <0 0x03ac0000 0 0x2c000>;
+			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&slimbam 3>, <&slimbam 4>;
+			dma-names = "rx", "tx";
+			iommus = <&apps_smmu 0x1826 0x0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		lpass_hm: clock-controller@3c00000 {
 			compatible = "qcom,sc7280-lpasshm";
 			reg = <0 0x03c00000 0 0x28>;
@@ -2712,6 +2949,16 @@
 				pins = "gpio1", "gpio2", "gpio14";
 				function = "swr_tx_data";
 			};
+
+			lpass_wsa_swr_clk: wsa-swr-clk-state {
+				pins = "gpio10";
+				function = "wsa_swr_clk";
+			};
+
+			lpass_wsa_swr_data: wsa-swr-data-state {
+				pins = "gpio11";
+				function = "wsa_swr_data";
+			};
 		};
 
 		gpu: gpu@3d00000 {
@@ -2734,6 +2981,8 @@
 			nvmem-cells = <&gpu_speed_bin>;
 			nvmem-cell-names = "speed_bin";
 
+			status = "disabled";
+
 			gpu_zap_shader: zap-shader {
 				memory-region = <&gpu_zap_mem>;
 			};
@@ -2862,15 +3111,18 @@
 		};
 
 		dma@117f000 {
-			compatible = "qcom,sc7280-dcc", "qcom,dcc";
+			compatible = "qcom,dcc-v2", "qcom,dcc";
 			reg = <0x0 0x0117f000 0x0 0x1000>,
 			      <0x0 0x01112000 0x0 0x6000>;
+
+			qcom,dcc-offset = <0x12000>;
 		};
 
 		adreno_smmu: iommu@3da0000 {
 			compatible = "qcom,sc7280-smmu-500", "qcom,adreno-smmu",
 				     "qcom,smmu-500", "arm,mmu-500";
 			reg = <0 0x03da0000 0 0x20000>;
+			ranges;
 			#iommu-cells = <2>;
 			#global-interrupts = <2>;
 			interrupts = <GIC_SPI 673 IRQ_TYPE_LEVEL_HIGH>,
@@ -2903,6 +3155,23 @@
 
 			power-domains = <&gpucc GPU_CC_CX_GDSC>;
 			dma-coherent;
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+
+			gfx_0_tbu: gfx_0_tbu@3dd9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x3dd9000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x0 0x400>;
+			};
+
+			gfx_1_tbu: gfx_1_tbu@3ddd000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x3ddd000 0x0 0x1000>;
+				reg-names = "base";
+				qcom,stream-id-range = <0x400 0x400>;
+			};
 		};
 
 		remoteproc_mpss: remoteproc@4080000 {
@@ -2963,6 +3232,306 @@
 			};
 		};
 
+		tpda@6004000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x06004000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					tpda_out_funnel_qatb: endpoint {
+						remote-endpoint =
+							<&funnel_qatb_in_tpda>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@15 {
+					reg = <21>;
+					tpda_in_funnel_wpss: endpoint {
+						remote-endpoint =
+							<&funnel_wpss_out_tpda>;
+					};
+				};
+
+				port@17 {
+					reg = <23>;
+					tpda_in_tpdm_dcc: endpoint {
+						remote-endpoint =
+							<&tpdm_dcc_out_tpda>;
+					};
+				};
+
+				port@18 {
+					reg = <24>;
+					tpda_in_tpdm_prng: endpoint {
+						remote-endpoint =
+							<&tpdm_prng_out_tpda>;
+					};
+				};
+
+				port@19 {
+					reg = <25>;
+					tpda_in_tpdm_qm: endpoint {
+						remote-endpoint =
+							<&tpdm_qm_out_tpda>;
+					};
+				};
+
+				port@1a {
+					reg = <26>;
+					tpda_in_tpdm_gcc: endpoint {
+						remote-endpoint =
+							<&tpdm_gcc_out_tpda>;
+					};
+				};
+
+				port@1b {
+					reg = <27>;
+					tpda_in_tpdm_vsense: endpoint {
+						remote-endpoint =
+							<&tpdm_vsense_out_tpda>;
+					};
+				};
+
+				port@1c {
+					reg = <28>;
+					tpda_in_tpdm_spdm: endpoint {
+						remote-endpoint =
+							<&tpdm_spdm_out_tpda>;
+					};
+				};
+
+				port@1d {
+					reg = <29>;
+					tpda_in_tpdm_sdcc_2: endpoint {
+						remote-endpoint =
+							<&tpdm_sdcc_2_out_tpda>;
+					};
+				};
+
+				port@1f {
+					reg = <31>;
+					tpda_in_tpdm_pimem: endpoint {
+						remote-endpoint =
+							<&tpdm_pimem_out_tpda>;
+					};
+				};
+			};
+		};
+
+		funnel@6005000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			arm,primecell-periphid = <0x000bb908>;
+
+			reg = <0x0 0x06005000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					funnel_qatb_out_funnel_in0: endpoint {
+						remote-endpoint =
+							<&funnel_in0_in_funnel_qatb>;
+					};
+				};
+			};
+
+			in-ports {
+
+				port {
+					funnel_qatb_in_tpda: endpoint {
+						remote-endpoint =
+							<&tpda_out_funnel_qatb>;
+					};
+				};
+			};
+		};
+
+		tpdm@600f000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x0600f000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			device-name = "tpdm_spdm";
+			qcom,cmb-element-bits = <32>;
+
+			out-ports {
+				port {
+					tpdm_spdm_out_tpda: endpoint {
+						remote-endpoint = <&tpda_in_tpdm_spdm>;
+					};
+				};
+			};
+		};
+
+		cti@6010000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06010000 0x0 0x1000>;
+
+			device-name = "cti0";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
+		cti@6011000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06011000 0x0 0x1000>;
+
+			device-name = "cti1";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
+		cti@6012000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06012000 0x0 0x1000>;
+
+			device-name = "cti2";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6013000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06013000 0x0 0x1000>;
+
+			device-name = "cti3";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
+		cti@6014000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06014000 0x0 0x1000>;
+
+			device-name = "cti4";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
+		cti@6015000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06015000 0x0 0x1000>;
+
+			device-name = "cti5";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
+		cti@6016000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06016000 0x0 0x1000>;
+
+			device-name = "cti6";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
+		cti@6017000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06017000 0x0 0x1000>;
+
+			device-name = "cti7";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
+		cti@6018000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06018000 0x0 0x1000>;
+
+			device-name = "cti8";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
+		cti@6019000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06019000 0x0 0x1000>;
+
+			device-name = "cti9";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
+		cti@601a000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0601a000 0x0 0x1000>;
+
+			device-name = "cti10";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
+		cti@601b000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0601b000 0x0 0x1000>;
+
+			device-name = "cti11";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
+		cti@601c000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0601c000 0x0 0x1000>;
+
+			device-name = "cti12";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
+		cti@601d000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0601d000 0x0 0x1000>;
+
+			device-name = "cti13";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
+		cti@601e000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0601e000 0x0 0x1000>;
+
+			device-name = "cti14";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
+		cti@601f000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0601f000 0x0 0x1000>;
+
+			device-name = "cti15";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
 		funnel@6041000 {
 			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
 			reg = <0 0x06041000 0 0x1000>;
@@ -2982,6 +3551,14 @@
 				#address-cells = <1>;
 				#size-cells = <0>;
 
+				port@6 {
+					reg = <6>;
+					funnel_in0_in_funnel_qatb: endpoint {
+						remote-endpoint =
+							<&funnel_qatb_out_funnel_in0>;
+					};
+				};
+
 				port@7 {
 					reg = <7>;
 					funnel0_in7: endpoint {
@@ -3016,6 +3593,22 @@
 						remote-endpoint = <&apss_merge_funnel_out>;
 					};
 				};
+
+				port@5 {
+					reg = <5>;
+					funnel_in1_in_funnel_modem: endpoint {
+						remote-endpoint =
+						<&funnel_modem_out_funnel_in1>;
+					};
+				};
+
+				port@6 {
+					reg = <6>;
+					funnel_in1_in_funnel_dlct5: endpoint {
+						remote-endpoint =
+						<&funnel_dlct5_out_funnel_in1>;
+					};
+				};
 			};
 		};
 
@@ -3080,7 +3673,7 @@
 
 		etr@6048000 {
 			compatible = "arm,coresight-tmc", "arm,primecell";
-			reg = <0 0x06048000 0 0x1000>;
+			reg = <0x0 0x06048000 0x0 0x1000>;
 			iommus = <&apps_smmu 0x04c0 0>;
 
 			clocks = <&aoss_qmp>;
@@ -3096,9 +3689,387 @@
 			};
 		};
 
+		tpdm@6800000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x6800000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			device-name = "tpdm_modem_0";
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <16>;
+
+			out-ports {
+				port {
+					tpdm_modem_0_out_tpda_modem: endpoint {
+						remote-endpoint = <&tpda_modem_in_tpdm_modem_0>;
+					};
+				};
+			};
+		};
+
+		tpdm@6801000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06801000 0x0 0x1000>;
+
+			status = "disabled";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,cmb-element-bits = <64>;
+			device-name = "tpdm_modem_1";
+
+			out-ports {
+				port {
+					tpdm_modem_1_out_tpda_modem: endpoint {
+						remote-endpoint = <&tpda_modem_in_tpdm_modem_1>;
+					};
+				};
+			};
+		};
+
+		tpda@6803000	 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x06803000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					tpda_modem_out_funnel_modem: endpoint {
+						remote-endpoint =
+							<&funnel_modem_in_tpda_modem>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+					tpda_modem_in_tpdm_modem_0: endpoint {
+						remote-endpoint =
+							<&tpdm_modem_0_out_tpda_modem>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					tpda_modem_in_tpdm_modem_1: endpoint {
+						remote-endpoint =
+							<&tpdm_modem_1_out_tpda_modem>;
+					};
+				};
+			};
+		};
+
+		funnel@6804000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+
+			reg = <0x0 0x06804000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					funnel_modem_out_funnel_in1: endpoint {
+						remote-endpoint =
+							<&funnel_in1_in_funnel_modem>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+					funnel_modem_in_tpda_modem: endpoint {
+						remote-endpoint =
+							<&tpda_modem_out_funnel_modem>;
+					};
+				};
+			};
+		};
+
+		cti@680b000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0680b000 0x0 0x1000>;
+
+			status = "disabled";
+
+			device-name = "cti_mss_q6";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6813000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06813000 0x0 0x1000>;
+
+			status = "disabled";
+
+			device-name = "cti_mss_vq6";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		tpdm@682c000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x0682c000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			qcom,dsb-element-bits = <32>;
+			device-name = "tpdm_gcc";
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					tpdm_gcc_out_tpda: endpoint {
+						remote-endpoint = <&tpda_in_tpdm_gcc>;
+					};
+				};
+			};
+		};
+
+		tpdm@6840000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06840000 0x0 0x1000>;
+
+			status = "disabled";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,cmb-element-bits = <32>;
+			device-name = "tpdm_vsense";
+
+			out-ports {
+				port {
+					tpdm_vsense_out_tpda: endpoint {
+						remote-endpoint =
+							<&tpda_in_tpdm_vsense>;
+					};
+				};
+			};
+		};
+
+		tpdm@6841000 {
+			ccompatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06841000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			device-name = "tpdm_prng";
+			qcom,cmb-element-bits = <32>;
+
+			out-ports {
+				port {
+					tpdm_prng_out_tpda: endpoint {
+						remote-endpoint = <&tpda_in_tpdm_prng>;
+					};
+				};
+			};
+		};
+
+		tpdm@6844000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06844000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			device-name = "tpdm_lpass";
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <16>;
+
+			out-ports {
+				port {
+					tpdm_lpass_out_funnel_lpass: endpoint {
+						remote-endpoint =
+							<&funnel_lpass_in_tpdm_lpass>;
+					};
+				};
+			};
+		};
+
+		cti@6845000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06845000 0x0 0x1000>;
+
+			device-name = "cti_lpass_dl";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		funnel@6846000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+			reg = <0x0 0x06846000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					funnel_lpass_out_tpda_dlct5: endpoint {
+						remote-endpoint =
+							<&tpda_dlct5_in_funnel_lpass>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+					funnel_lpass_in_tpdm_lpass: endpoint {
+						remote-endpoint =
+							<&tpdm_lpass_out_funnel_lpass>;
+					};
+				};
+			};
+		};
+
+		tpdm@684f000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x0684f000 0x0 0x1000>;
+
+			status = "disabled";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			device-name = "tpdm_sdcc_2";
+			qcom,cmb-element-bits = <32>;
+
+			out-ports {
+				port {
+					tpdm_sdcc_2_out_tpda: endpoint {
+						remote-endpoint =
+						<&tpda_in_tpdm_sdcc_2>;
+					};
+				};
+			};
+		};
+
+		tpdm@6850000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06850000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			device-name = "tpdm_pimem";
+			qcom,cmb-element-bits = <64>;
+
+			out-ports {
+				port {
+					tpdm_pimem_out_tpda: endpoint {
+						remote-endpoint = <&tpda_in_tpdm_pimem>;
+					};
+				};
+			};
+		};
+
+		tpdm@6870000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06870000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			device-name = "tpdm_dcc";
+			qcom,cmb-element-bits = <32>;
+			status = "disabled";
+
+			out-ports {
+				port {
+					tpdm_dcc_out_tpda: endpoint {
+						remote-endpoint = <&tpda_in_tpdm_dcc>;
+					};
+				};
+			};
+		};
+
+		cti@6961000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06961000 0x0 0x1000>;
+
+			status = "disabled";
+
+			device-name = "cti_gpu_isdb";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6982000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06982000 0x0 0x1000>;
+
+			device-name = "cti_turing_dl";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@698b000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x0698b000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			device-name = "cti_turing_q6";
+		};
+
+		tpdm@69d0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x069d0000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			qcom,dsb-element-bits = <32>;
+			device-name = "tpdm_qm";
+
+			out-ports {
+				port {
+					tpdm_qm_out_tpda: endpoint {
+						remote-endpoint = <&tpda_in_tpdm_qm>;
+					};
+				};
+			};
+		};
+
+		cti@6b00000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06b00000 0x0 0x1000>;
+
+			device-name = "cti_swao_0";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6b01000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06b01000 0x0 0x1000>;
+
+			device-name = "cti_swao_1";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6b03000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06b03000 0x0 0x1000>;
+
+			device-name = "cti_swao_3";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
 		funnel@6b04000 {
 			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
-			reg = <0 0x06b04000 0 0x1000>;
+			reg = <0x0 0x06b04000 0x0 0x1000>;
 
 			clocks = <&aoss_qmp>;
 			clock-names = "apb_pclk";
@@ -3115,6 +4086,14 @@
 				#address-cells = <1>;
 				#size-cells = <0>;
 
+				port@6 {
+					reg = <6>;
+					funnel_swao_in_tpda_swao: endpoint {
+						remote-endpoint =
+							<&tpda_swao_out_funnel_swao>;
+					};
+				};
+
 				port@7 {
 					reg = <7>;
 					swao_funnel_in: endpoint {
@@ -3126,7 +4105,7 @@
 
 		etf@6b05000 {
 			compatible = "arm,coresight-tmc", "arm,primecell";
-			reg = <0 0x06b05000 0 0x1000>;
+			reg = <0x0 0x06b05000 0x0 0x1000>;
 
 			clocks = <&aoss_qmp>;
 			clock-names = "apb_pclk";
@@ -3150,7 +4129,7 @@
 
 		replicator@6b06000 {
 			compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
-			reg = <0 0x06b06000 0 0x1000>;
+			reg = <0x0 0x06b06000 0x0 0x1000>;
 
 			clocks = <&aoss_qmp>;
 			clock-names = "apb_pclk";
@@ -3173,6 +4152,485 @@
 			};
 		};
 
+		tpda@6b08000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x06b08000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+					tpda_swao_in_tpdm_swao_p0: endpoint {
+						remote-endpoint =
+							<&tpdm_swao_p0_out_tpda_swao>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					tpda_swao_in_tpdm_swao_p1: endpoint {
+						remote-endpoint =
+							<&tpdm_swao_p1_out_tpda_swao>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					tpda_swao_in_tpdm_swao_p2: endpoint {
+						remote-endpoint =
+							<&tpdm_swao_p2_out_tpda_swao>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+					tpda_swao_in_tpdm_swao_p3: endpoint {
+						remote-endpoint =
+							<&tpdm_swao_p3_out_tpda_swao>;
+					};
+				};
+
+				port@4 {
+					reg = <4>;
+					tpda_swao_in_tpdm_swao1: endpoint {
+						remote-endpoint =
+							<&tpdm_swao1_out_tpda_swao>;
+					};
+				};
+			};
+
+			out-ports {
+				port {
+					tpda_swao_out_funnel_swao: endpoint {
+						remote-endpoint =
+							<&funnel_swao_in_tpda_swao>;
+					};
+
+				};
+			};
+		};
+
+		tpdm@6b09000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06b09000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			device-name = "tpdm_swao_prio_0";
+			qcom,cmb-element-bits = <64>;
+
+			out-ports {
+				port {
+					tpdm_swao_p0_out_tpda_swao: endpoint {
+						remote-endpoint =
+							<&tpda_swao_in_tpdm_swao_p0>;
+					};
+				};
+			};
+		};
+
+		tpdm@6b0a000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06b0a000 0x0 0x1000>;
+
+			qcom,cmb-element-bits = <64>;
+			device-name = "tpdm_swao_prio_1";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					tpdm_swao_p1_out_tpda_swao: endpoint {
+						remote-endpoint =
+							<&tpda_swao_in_tpdm_swao_p1>;
+					};
+				};
+			};
+		};
+
+		tpdm@6b0b000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06b0b000 0x0 0x1000>;
+
+			qcom,cmb-element-bits = <64>;
+			device-name = "tpdm_swao_prio_2";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					tpdm_swao_p2_out_tpda_swao: endpoint {
+						remote-endpoint =
+							<&tpda_swao_in_tpdm_swao_p2>;
+					};
+				};
+			};
+		};
+
+		tpdm@6b0c000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06b0c000 0x0 0x1000>;
+
+			qcom,cmb-element-bits = <64>;
+			device-name = "tpdm_swao_prio_3";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					tpdm_swao_p3_out_tpda_swao: endpoint {
+						remote-endpoint =
+							<&tpda_swao_in_tpdm_swao_p3>;
+					};
+				};
+			};
+		};
+
+		tpdm@6b0d000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x6b0d000 0x0 0x1000>;
+
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+			device-name = "tpdm_swao_1";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					tpdm_swao1_out_tpda_swao: endpoint {
+						remote-endpoint =
+							<&tpda_swao_in_tpdm_swao1>;
+					};
+				};
+			};
+		};
+
+		cti@6b41000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06b41000 0x0 0x1000>;
+
+			status = "disabled";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6b4b000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06b4b000 0x0 0x1000>;
+
+			status = "disabled";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		tpdm@6c60000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06c60000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			device-name = "tpdm_mdss";
+			qcom,cmb-element-bits = <32>;
+			qcom,dsb-msrs-num = <16>;
+
+			out-ports {
+				port {
+					tpdm_mdss_out_tpda_dlct5: endpoint {
+						remote-endpoint =
+							<&tpda_dlct5_in_tpdm_mdss>;
+					};
+				};
+			};
+		};
+
+		tpdm@6c08000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06c08000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			device-name = "tpdm_dl_south";
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <16>;
+
+			out-ports {
+				port {
+					tpdm_dl_south_out_tpda_dlct5: endpoint {
+						remote-endpoint =
+							<&tpda_dlct5_in_tpdm_dl_south>;
+					};
+				};
+			};
+		};
+
+		cti@6c13000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06c13000 0x0 0x1000>;
+
+			status = "disabled";
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		tpdm@6c30000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06c30000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			device-name = "tpdm_dlct";
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <16>;
+
+			out-ports {
+				port {
+					tpdm_dlct_out_tpda_dlct5: endpoint {
+						remote-endpoint =
+							<&tpda_dlct5_in_tpdm_dlct>;
+					};
+				};
+			};
+		};
+
+		tpdm@6c31000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x06c31000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			device-name = "tpdm_ipcc";
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <1>;
+
+			out-ports {
+				port {
+					tpdm_ipcc_out_tpda_dlct5: endpoint {
+						remote-endpoint =
+							<&tpda_dlct5_in_tpdm_ipcc>;
+					};
+				};
+			};
+		};
+
+		tpda@6c37000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x06c37000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					tpda_dlct5_out_funnel_dlct5: endpoint {
+						remote-endpoint =
+							<&funnel_dlct5_in_tpda_dlct5>;
+					};
+
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@2 {
+					reg = <2>;
+					tpda_dlct5_in_funnel_lpass: endpoint {
+						remote-endpoint =
+							<&funnel_lpass_out_tpda_dlct5>;
+					};
+				};
+
+				port@5 {
+					reg = <5>;
+					tpda_dlct5_in_tpdm_dl_south: endpoint {
+						remote-endpoint =
+							<&tpdm_dl_south_out_tpda_dlct5>;
+					};
+				};
+
+				port@8 {
+					reg = <8>;
+					tpda_dlct5_in_tpdm_mdss: endpoint {
+						remote-endpoint =
+							<&tpdm_mdss_out_tpda_dlct5>;
+					};
+				};
+
+				port@1b {
+					reg = <27>;
+					tpda_dlct5_in_tpdm_dlct: endpoint {
+						remote-endpoint =
+							<&tpdm_dlct_out_tpda_dlct5>;
+					};
+				};
+
+				port@1c {
+					reg = <28>;
+					tpda_dlct5_in_tpdm_ipcc: endpoint {
+						remote-endpoint =
+							<&tpdm_ipcc_out_tpda_dlct5>;
+					};
+				};
+			};
+		};
+
+		funnel@6c38000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+
+			reg = <0x0 0x06c38000 0x0 0x1000>;
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					funnel_dlct5_out_funnel_in1: endpoint {
+						remote-endpoint =
+							<&funnel_in1_in_funnel_dlct5>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+					funnel_dlct5_in_tpda_dlct5: endpoint {
+						remote-endpoint =
+						<&tpda_dlct5_out_funnel_dlct5>;
+					};
+				};
+
+			};
+		};
+
+		cti@6c61000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06c61000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			device-name = "cti_mdss_dl";
+		};
+
+		tpdm@6c70000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+
+			reg = <0x0 0x06c70000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+			device-name = "tpdm_wpss";
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <16>;
+
+			out-ports {
+				port {
+					tpdm_wpss_out_funnel_wpss: endpoint {
+						remote-endpoint =
+							<&funnel_wpss_in_tpdm_wpss>;
+					};
+				};
+			};
+		};
+
+		funnel@6c73000 {
+			compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+
+			reg = <0x0 0x06c73000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			in-ports {
+				port {
+					funnel_wpss_in_tpdm_wpss: endpoint {
+						remote-endpoint =
+						<&tpdm_wpss_out_funnel_wpss>;
+					};
+				};
+
+			};
+
+			out-ports {
+				port {
+					funnel_wpss_out_tpda: endpoint {
+						remote-endpoint =
+							<&tpda_in_funnel_wpss>;
+					};
+				};
+			};
+		};
+
+		cti@6e02000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06e02000 0x0 0x1000>;
+
+			device-name = "cti_ddr_dl_0_cti_0";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6e0c000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06e0c000 0x0 0x1000>;
+
+			device-name = "cti_ddr_dl_1_cti_0";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6e0d000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06e0d000 0x0 0x1000>;
+
+			device-name = "cti_ddr_dl_1_cti_1";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6e0e000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06e0e000 0x0 0x1000>;
+
+			device-name = "cti_ddr_dl_1_cti_2";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@6e11000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x06e11000 0x0 0x1000>;
+
+			device-name = "cti_ddr_ch01_dl_cti_0";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@7020000 {
+			compatible = "arm,coresight-cti-v8-arch",
+					"arm,coresight-cti","arm,primecell";
+			reg = <0x0 0x07020000 0x0 0x1000>;
+			cpu = <&CPU0>;
+
+			device-name = "cti_cpu0";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+		};
+
 		etm@7040000 {
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07040000 0 0x1000>;
@@ -3193,6 +4651,17 @@
 			};
 		};
 
+		cti@7120000 {
+			compatible = "arm,coresight-cti-v8-arch",
+					"arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07120000 0x0 0x1000>;
+			cpu = <&CPU1>;
+
+			device-name = "cti_cpu1";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
 		etm@7140000 {
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07140000 0 0x1000>;
@@ -3213,6 +4682,17 @@
 			};
 		};
 
+		cti@7220000 {
+			compatible = "arm,coresight-cti-v8-arch",
+				"arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07220000 0x0 0x1000>;
+			cpu = <&CPU2>;
+
+			device-name = "cti_cpu2";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
 		etm@7240000 {
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07240000 0 0x1000>;
@@ -3233,6 +4713,17 @@
 			};
 		};
 
+		cti@7320000 {
+			compatible = "arm,coresight-cti-v8-arch",
+					"arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07320000 0x0 0x1000>;
+			cpu = <&CPU3>;
+
+			device-name = "cti_cpu3";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
 		etm@7340000 {
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07340000 0 0x1000>;
@@ -3253,6 +4744,17 @@
 			};
 		};
 
+		cti@7420000 {
+			compatible = "arm,coresight-cti-v8-arch",
+					"arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07420000 0x0 0x1000>;
+			cpu = <&CPU4>;
+
+			device-name = "cti_cpu4";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
 		etm@7440000 {
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07440000 0 0x1000>;
@@ -3273,6 +4775,17 @@
 			};
 		};
 
+		cti@7520000 {
+			compatible = "arm,coresight-cti-v8-arch",
+					"arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07520000 0x0 0x1000>;
+			cpu = <&CPU5>;
+
+			device-name = "cti_cpu5";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
 		etm@7540000 {
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07540000 0 0x1000>;
@@ -3293,6 +4806,17 @@
 			};
 		};
 
+		cti@7620000 {
+			compatible = "arm,coresight-cti-v8-arch",
+					"arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07620000 0x0 0x1000>;
+			cpu = <&CPU6>;
+
+			device-name = "cti_cpu6";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
 		etm@7640000 {
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07640000 0 0x1000>;
@@ -3313,6 +4837,17 @@
 			};
 		};
 
+		cti@7720000 {
+			compatible = "arm,coresight-cti-v8-arch",
+					"arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07720000 0x0 0x1000>;
+			cpu = <&CPU7>;
+
+			device-name = "cti_cpu7";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
 		etm@7740000 {
 			compatible = "arm,coresight-etm4x", "arm,primecell";
 			reg = <0 0x07740000 0 0x1000>;
@@ -3426,14 +4961,199 @@
 			};
 
 			in-ports {
-				port {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
 					apss_merge_funnel_in: endpoint {
 						remote-endpoint = <&apss_funnel_out>;
 					};
 				};
+
+				port@3 {
+					reg = <3>;
+					funnel_apss_merg_in_tpda_apss: endpoint {
+						remote-endpoint =
+						  <&tpda_apss_out_funnel_apss_merg>;
+					};
+				};
+			};
+		};
+
+		tpdm@7860000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x07860000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			device-name = "tpdm_actpm";
+			qcom,cmb-element-bits = <64>;
+			qcom,cmb-msrs-num = <1>;
+
+			out-ports {
+				port {
+					tpdm_actpm_out_tpda_apss: endpoint {
+						remote-endpoint =
+							<&tpda_apss_in_tpdm_actpm>;
+					};
+				};
 			};
 		};
 
+		tpdm@7861000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x07861000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			device-name = "tpdm_apss";
+			qcom,dsb-element-bits = <32>;
+			qcom,dsb-msrs-num = <32>;
+
+			out-ports {
+				port {
+					tpdm_apss_out_tpda_apss: endpoint {
+						remote-endpoint =
+							<&tpda_apss_in_tpdm_apss>;
+					};
+				};
+			};
+		};
+
+		cti@7862000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07862000 0x0 0x1000>;
+
+			device-name = "cti_apss_dl_cti0";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		tpda@7863000 {
+			compatible = "qcom,coresight-tpda", "arm,primecell";
+			reg = <0x0 0x07863000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			out-ports {
+				port {
+					tpda_apss_out_funnel_apss_merg: endpoint {
+						remote-endpoint =
+							   <&funnel_apss_merg_in_tpda_apss>;
+					};
+				};
+			};
+
+			in-ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				port@0 {
+					reg = <0>;
+					tpda_apss_in_tpdm_llm_silver: endpoint {
+						remote-endpoint =
+							   <&tpdm_llm_silver_out_tpda_apss>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					tpda_apss_in_tpdm_llm_gold: endpoint {
+						remote-endpoint =
+							   <&tpdm_llm_gold_out_tpda_apss>;
+					};
+				};
+
+				port@2 {
+					reg = <2>;
+					tpda_apss_in_tpdm_actpm: endpoint {
+						remote-endpoint =
+							   <&tpdm_actpm_out_tpda_apss>;
+					};
+				};
+
+				port@3 {
+					reg = <3>;
+					tpda_apss_in_tpdm_apss: endpoint {
+						remote-endpoint =
+							   <&tpdm_apss_out_tpda_apss>;
+					};
+				};
+			};
+		};
+
+		tpdm@78a0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x078a0000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			device-name = "tpdm_llm_silver";
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <12>;
+
+			out-ports {
+				port {
+					tpdm_llm_silver_out_tpda_apss: endpoint {
+						remote-endpoint =
+							<&tpda_apss_in_tpdm_llm_silver>;
+					};
+				};
+			};
+		};
+
+		tpdm@78b0000 {
+			compatible = "qcom,coresight-tpdm", "arm,primecell";
+			reg = <0x0 0x078b0000 0x0 0x1000>;
+
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+
+			device-name = "tpdm_llm_gold";
+			qcom,cmb-element-bits = <32>;
+			qcom,cmb-msrs-num = <12>;
+
+			out-ports {
+				port {
+					tpdm_llm_gold_out_tpda_apss: endpoint {
+						remote-endpoint =
+							<&tpda_apss_in_tpdm_llm_gold>;
+					};
+				};
+			};
+		};
+
+		cti@78e0000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x078e0000 0x0 0x1000>;
+
+			device-name = "cti_apss_cti0";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@78f0000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x078f0000 0x0 0x1000>;
+
+			device-name = "cti_apss_cti1";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
+		cti@7900000 {
+			compatible = "arm,coresight-cti", "arm,primecell";
+			reg = <0x0 0x07900000 0x0 0x1000>;
+
+			device-name = "cti_apss_cti2";
+			clocks = <&aoss_qmp>;
+			clock-names = "apb_pclk";
+		};
+
 		sdhc_2: mmc@8804000 {
 			compatible = "qcom,sc7280-sdhci", "qcom,sdhci-msm-v5";
 			pinctrl-names = "default", "sleep";
@@ -3484,6 +5204,14 @@
 			};
 		};
 
+		ice: crypto@1d88000 {
+			compatible = "qcom,inline-crypto-engine";
+			reg = <0x0 0x01d88000 0x0 0x10000>;
+			qcom,ice-use-hwkm;
+			clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>;
+			status = "okay";
+		};
+
 		usb_1_hsphy: phy@88e3000 {
 			compatible = "qcom,sc7280-usb-hs-phy",
 				     "qcom,usb-snps-hs-7nm-phy";
@@ -3538,21 +5266,21 @@
 				port@0 {
 					reg = <0>;
 
-					usb_dp_qmpphy_out: endpoint {
+					usb_1_qmpphy_out: endpoint {
 					};
 				};
 
 				port@1 {
 					reg = <1>;
 
-					usb_dp_qmpphy_usb_ss_in: endpoint {
+					usb_1_qmpphy_usb_ss_in: endpoint {
 					};
 				};
 
 				port@2 {
 					reg = <2>;
 
-					usb_dp_qmpphy_dp_in: endpoint {
+					usb_1_qmpphy_dp_in: endpoint {
 					};
 				};
 			};
@@ -3582,10 +5310,12 @@
 					  <&gcc GCC_USB30_SEC_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <200000000>;
 
-			interrupts-extended = <&intc GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc 12 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 13 IRQ_TYPE_EDGE_BOTH>;
-			interrupt-names = "hs_phy_irq",
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
 					  "dp_hs_phy_irq",
 					  "dm_hs_phy_irq";
 
@@ -3608,13 +5338,6 @@
 				phys = <&usb_2_hsphy>;
 				phy-names = "usb2-phy";
 				maximum-speed = "high-speed";
-				usb-role-switch;
-
-				port {
-					usb2_role_switch: endpoint {
-						remote-endpoint = <&eud_ep>;
-					};
-				};
 			};
 		};
 
@@ -3640,7 +5363,7 @@
 			compatible = "qcom,sc7280-adsp-pas";
 			reg = <0 0x03700000 0 0x100>;
 
-			interrupts-extended = <&pdc 6 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
 					      <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
 					      <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
 					      <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
@@ -3784,6 +5507,12 @@
 				opp-7 {
 					opp-peak-kBps = <8532000>;
 				};
+				opp-8 {
+					opp-peak-kBps = <10944000>;
+				};
+				opp-9 {
+					opp-peak-kBps = <12787200>;
+				};
 			};
 		};
 
@@ -3846,11 +5575,13 @@
 		};
 
 		eud: eud@88e0000 {
-			compatible = "qcom,sc7280-eud", "qcom,eud";
+			compatible = "qcom,secure-eud";
 			reg = <0 0x88e0000 0 0x2000>,
 			      <0 0x88e2000 0 0x1000>;
 			interrupts-extended = <&pdc 11 IRQ_TYPE_LEVEL_HIGH>;
 
+			phys = <&usb_1_hsphy>;
+			phy-names = "usb2-phy";
 			status = "disabled";
 
 			ports {
@@ -3860,7 +5591,12 @@
 				port@0 {
 					reg = <0>;
 					eud_ep: endpoint {
-						remote-endpoint = <&usb2_role_switch>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+					eud_con: endpoint {
 					};
 				};
 			};
@@ -3877,7 +5613,7 @@
 			compatible = "qcom,sc7280-cdsp-pas";
 			reg = <0 0x0a300000 0 0x10000>;
 
-			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
 					      <&cdsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
 					      <&cdsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
 					      <&cdsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
@@ -4035,11 +5771,13 @@
 					  <&gcc GCC_USB30_PRIM_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <200000000>;
 
-			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "hs_phy_irq",
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
 					  "dp_hs_phy_irq",
 					  "dm_hs_phy_irq",
 					  "ss_phy_irq";
@@ -4062,9 +5800,29 @@
 				iommus = <&apps_smmu 0xe0 0x0>;
 				snps,dis_u2_susphy_quirk;
 				snps,dis_enblslpm_quirk;
+				snps,parkmode-disable-ss-quirk;
 				phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
 				phy-names = "usb2-phy", "usb3-phy";
 				maximum-speed = "super-speed";
+
+				ports {
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					port@0 {
+						reg = <0>;
+
+						usb_1_dwc3_hs: endpoint {
+						};
+					};
+
+					port@1 {
+						reg = <1>;
+
+						usb_1_dwc3_ss: endpoint {
+						};
+					};
+				};
 			};
 		};
 
@@ -4095,6 +5853,8 @@
 				 <&apps_smmu 0x2184 0x20>;
 			memory-region = <&video_mem>;
 
+			status = "disabled";
+
 			video-decoder {
 				compatible = "venus-decoder";
 			};
@@ -4103,10 +5863,6 @@
 				compatible = "venus-encoder";
 			};
 
-			video-firmware {
-				iommus = <&apps_smmu 0x21a2 0x0>;
-			};
-
 			venus_opp_table: opp-table {
 				compatible = "operating-points-v2";
 
@@ -4228,6 +5984,181 @@
 			};
 		};
 
+		camss: camss@acaf000 {
+			compatible = "qcom,sc7280-camss";
+
+			clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_0_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_1_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_2_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CSID_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CSID_CLK>,
+				 <&camcc CAM_CC_CSIPHY0_CLK>,
+				 <&camcc CAM_CC_CSI0PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY1_CLK>,
+				 <&camcc CAM_CC_CSI1PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY2_CLK>,
+				 <&camcc CAM_CC_CSI2PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY3_CLK>,
+				 <&camcc CAM_CC_CSI3PHYTIMER_CLK>,
+				 <&camcc CAM_CC_CSIPHY4_CLK>,
+				 <&camcc CAM_CC_CSI4PHYTIMER_CLK>,
+				 <&gcc GCC_CAMERA_AHB_CLK>,
+				 <&gcc GCC_CAMERA_HF_AXI_CLK>,
+				 <&camcc CAM_CC_CPAS_AHB_CLK>,
+				 <&camcc CAM_CC_IFE_0_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_0_CLK>,
+				 <&camcc CAM_CC_IFE_0_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_1_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_1_CLK>,
+				 <&camcc CAM_CC_IFE_1_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_2_AXI_CLK>,
+				 <&camcc CAM_CC_IFE_2_CLK>,
+				 <&camcc CAM_CC_IFE_2_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_0_CPHY_RX_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CLK>,
+				 <&camcc CAM_CC_IFE_LITE_1_CPHY_RX_CLK>;
+
+			clock-names = "camnoc_axi",
+				      "csi0",
+				      "csi1",
+				      "csi2",
+				      "csi3",
+				      "csi4",
+				      "csiphy0",
+				      "csiphy0_timer",
+				      "csiphy1",
+				      "csiphy1_timer",
+				      "csiphy2",
+				      "csiphy2_timer",
+				      "csiphy3",
+				      "csiphy3_timer",
+				      "csiphy4",
+				      "csiphy4_timer",
+				      "gcc_camera_ahb",
+				      "gcc_camera_axi",
+				      "soc_ahb",
+				      "vfe0_axi",
+				      "vfe0",
+				      "vfe0_cphy_rx",
+				      "vfe1_axi",
+				      "vfe1",
+				      "vfe1_cphy_rx",
+				      "vfe2_axi",
+				      "vfe2",
+				      "vfe2_cphy_rx",
+				      "vfe0_lite",
+				      "vfe0_lite_cphy_rx",
+				      "vfe1_lite",
+				      "vfe1_lite_cphy_rx";
+
+			interconnects = <&gem_noc  MASTER_APPSS_PROC 0 &cnoc2 SLAVE_CAMERA_CFG 0>,
+					<&mmss_noc MASTER_CAMNOC_HF  0 &mc_virt SLAVE_EBI1     0>;
+
+			interconnect-names = "ahb", "hf_0";
+
+			interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 640 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 122 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 641 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
+
+			interrupt-names = "csid0",
+					  "csid1",
+					  "csid2",
+					  "csid_lite0",
+					  "csid_lite1",
+					  "csiphy0",
+					  "csiphy1",
+					  "csiphy2",
+					  "csiphy3",
+					  "csiphy4",
+					  "vfe0",
+					  "vfe1",
+					  "vfe2",
+					  "vfe_lite0",
+					  "vfe_lite1";
+
+			iommus = <&apps_smmu 0x800 0x4e0>;
+
+			power-domains = <&camcc CAM_CC_IFE_0_GDSC>,
+					<&camcc CAM_CC_IFE_1_GDSC>,
+					<&camcc CAM_CC_IFE_2_GDSC>,
+					<&camcc CAM_CC_TITAN_TOP_GDSC>;
+
+			power-domains-names = "ife0", "ife1", "ife2", "top";
+
+			reg = <0x0 0x0acb3000 0x0 0x1000>,
+			      <0x0 0x0acba000 0x0 0x1000>,
+			      <0x0 0x0acc1000 0x0 0x1000>,
+			      <0x0 0x0acc8000 0x0 0x1000>,
+			      <0x0 0x0accf000 0x0 0x1000>,
+			      <0x0 0x0ace0000 0x0 0x2000>,
+			      <0x0 0x0ace2000 0x0 0x2000>,
+			      <0x0 0x0ace4000 0x0 0x2000>,
+			      <0x0 0x0ace6000 0x0 0x2000>,
+			      <0x0 0x0ace8000 0x0 0x2000>,
+			      <0x0 0x0acaf000 0x0 0x4000>,
+			      <0x0 0x0acb6000 0x0 0x4000>,
+			      <0x0 0x0acbd000 0x0 0x4000>,
+			      <0x0 0x0acc4000 0x0 0x4000>,
+			      <0x0 0x0accb000 0x0 0x4000>;
+
+			reg-names = "csid0",
+				    "csid1",
+				    "csid2",
+				    "csid_lite0",
+				    "csid_lite1",
+				    "csiphy0",
+				    "csiphy1",
+				    "csiphy2",
+				    "csiphy3",
+				    "csiphy4",
+				    "vfe0",
+				    "vfe1",
+				    "vfe2",
+				    "vfe_lite0",
+				    "vfe_lite1";
+
+			status = "disabled";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+				};
+
+				port@1 {
+					reg = <1>;
+				};
+
+				port@2 {
+					reg = <2>;
+				};
+
+				port@3 {
+					reg = <3>;
+				};
+
+				port@4 {
+					reg = <4>;
+				};
+			};
+		};
+
 		camcc: clock-controller@ad00000 {
 			compatible = "qcom,sc7280-camcc";
 			reg = <0 0x0ad00000 0 0x10000>;
@@ -4373,6 +6304,11 @@
 						opp-hz = /bits/ 64 <506666667>;
 						required-opps = <&rpmhpd_opp_nom>;
 					};
+
+					opp-608000000 {
+						opp-hz = /bits/ 64 <608000000>;
+						required-opps = <&rpmhpd_opp_turbo>;
+					};
 				};
 			};
 
@@ -4793,6 +6729,39 @@
 				bias-pull-down;
 			};
 
+			cam2_default: cam2-default {
+				mclk {
+					pins = "gpio67";
+					function = "cam_mclk";
+					drive-strength = <2>;
+					bias-disable;
+				};
+
+				rst {
+					pins = "gpio78";
+					function = "gpio";
+					drive-strength = <2>;
+					bias-disable;
+				};
+			};
+
+			cam2_suspend: cam2-suspend {
+				mclk {
+					pins = "gpio67";
+					function = "cam_mclk";
+					drive-strength = <2>;
+					bias-pull-down;
+				};
+
+				rst {
+					pins = "gpio78";
+					function = "gpio";
+					drive-strength = <2>;
+					bias-pull-down;
+					output-low;
+				};
+			};
+
 			dp_hot_plug_det: dp-hot-plug-det-state {
 				pins = "gpio47";
 				function = "dp_hot";
@@ -4833,6 +6802,11 @@
 				function = "mi2s1_data0";
 			};
 
+			mi2s1_mclk: mi2s1-mclk-state {
+				pins = "gpio105";
+				function = "sec_mi2s";
+			};
+
 			mi2s1_sclk: mi2s1-sclk-state {
 				pins = "gpio106";
 				function = "mi2s1_sck";
@@ -4843,6 +6817,31 @@
 				function = "mi2s1_ws";
 			};
 
+			pcie0_reset_n: pcie0-reset-n-state {
+				pins = "gpio87";
+				function = "gpio";
+
+				drive-strength = <16>;
+				output-low;
+				bias-disable;
+			};
+
+			pcie0_wake_n: pcie0-wake-n-state {
+				pins = "gpio89";
+				function = "gpio";
+
+				drive-strength = <2>;
+				bias-pull-up;
+			};
+
+			pcie0_clkreq_n: pcie0-clkreq-n-state {
+				pins = "gpio88";
+				function = "pcie0_clkreqn";
+
+				bias-pull-up;
+				drive-strength = <2>;
+			};
+
 			pcie1_clkreq_n: pcie1-clkreq-n-state {
 				pins = "gpio79";
 				function = "pcie1_clkreqn";
@@ -5298,16 +7297,6 @@
 				function = "qup04";
 			};
 
-			qup_uart5_cts: qup-uart5-cts-state {
-				pins = "gpio20";
-				function = "qup05";
-			};
-
-			qup_uart5_rts: qup-uart5-rts-state {
-				pins = "gpio21";
-				function = "qup05";
-			};
-
 			qup_uart5_tx: qup-uart5-tx-state {
 				pins = "gpio22";
 				function = "qup05";
@@ -5607,6 +7596,7 @@
 		apps_smmu: iommu@15000000 {
 			compatible = "qcom,sc7280-smmu-500", "arm,mmu-500";
 			reg = <0 0x15000000 0 0x100000>;
+			ranges;
 			#iommu-cells = <2>;
 			#global-interrupts = <1>;
 			dma-coherent;
@@ -5691,6 +7681,95 @@
 				     <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>;
+
+			#address-cells = <2>;
+			#size-cells = <2>;
+
+			anoc_1_tbu: anoc_1_tbu@151dd000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151dd000 0x0 0x1000>;
+				reg-names = "base";
+				interconnects = <&gem_noc MASTER_APPSS_PROC 0
+						 &cnoc3 SLAVE_TCU 0>;
+				qcom,stream-id-range = <0x0 0x400>;
+			};
+
+			anoc_2_tbu: anoc_2_tbu@151e1000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151e1000 0x0 0x1000>;
+				reg-names = "base";
+				interconnects = <&gem_noc MASTER_APPSS_PROC 0
+						 &cnoc3 SLAVE_TCU 0>;
+				qcom,stream-id-range = <0x400 0x400>;
+			};
+
+			mnoc_hf_0_tbu: mnoc_hf_0_tbu@151e5000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151e5000 0x0 0x1000>;
+				reg-names = "base";
+				interconnects = <&mmss_noc MASTER_MDP0 0
+						 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&gcc HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC>;
+				qcom,stream-id-range = <0x800 0x400>;
+			};
+
+			mnoc_hf_1_tbu: mnoc_hf_1_tbu@151e9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151e9000 0x0 0x1000>;
+				reg-names = "base";
+				interconnects = <&mmss_noc MASTER_MDP0 0
+						 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&gcc HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC>;
+				qcom,stream-id-range = <0xc00 0x400>;
+			};
+
+			compute_dsp_0_tbu: compute_dsp_0_tbu@151ed000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151ed000 0x0 0x1000>;
+				reg-names = "base";
+				interconnects = <&nsp_noc MASTER_CDSP_PROC 0
+						 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&gcc HLOS1_VOTE_TURING_MMU_TBU1_GDSC>;
+				qcom,stream-id-range = <0x1000 0x400>;
+			};
+
+			compute_dsp_1_tbu: compute_dsp_1_tbu@151f1000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151f1000 0x0 0x1000>;
+				reg-names = "base";
+				interconnects = <&nsp_noc MASTER_CDSP_PROC 0
+						 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&gcc HLOS1_VOTE_TURING_MMU_TBU0_GDSC>;
+				qcom,stream-id-range = <0x1400 0x400>;
+			};
+
+			adsp_tbu: adsp_tbu@151f5000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151f5000 0x0 0x1000>;
+				reg-names = "base";
+				interconnects = <&gem_noc MASTER_APPSS_PROC 0
+						 &lpass_ag_noc SLAVE_LPASS_CORE_CFG 0>;
+				qcom,stream-id-range = <0x1800 0x400>;
+			};
+
+			anoc_1_pcie_tbu: anoc_1_pcie_tbu@151f9000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151f9000 0x0 0x1000>;
+				reg-names = "base";
+				interconnects = <&gem_noc MASTER_APPSS_PROC 0
+						 &cnoc3 SLAVE_TCU 0>;
+				qcom,stream-id-range = <0x1c00 0x400>;
+			};
+
+			mnoc_sf_0_tbu: mnoc_sf_0_tbu@151fd000 {
+				compatible = "qcom,qsmmuv500-tbu";
+				reg = <0x0 0x151fd000 0x0 0x1000>;
+				reg-names = "base";
+				interconnects = <&mmss_noc MASTER_CAMNOC_SF 0
+						 &mc_virt SLAVE_EBI1 0>;
+				power-domains = <&gcc HLOS1_VOTE_MMNOC_MMU_TBU_SF0_GDSC>;
+				qcom,stream-id-range = <0x2000 0x400>;
+			};
 		};
 
 		intc: interrupt-controller@17a00000 {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc8180x.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc8180x.dtsi
@@ -2,6 +2,7 @@
 /*
  * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
  * Copyright (c) 2020-2023, Linaro Limited
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <dt-bindings/clock/qcom,dispcc-sm8250.h>
@@ -290,7 +291,7 @@
 			BIG_CPU_SLEEP_0: cpu-sleep-1-0 {
 				compatible = "arm,idle-state";
 				arm,psci-suspend-param = <0x40000004>;
-				entry-latency-us = <241>;
+				entry-latency-us = <2411>;
 				exit-latency-us = <1461>;
 				min-residency-us = <4488>;
 				local-timer-stop;
@@ -298,7 +299,15 @@
 		};
 
 		domain-idle-states {
-			CLUSTER_SLEEP_0: cluster-sleep-0 {
+			CLUSTER_SLEEP_APSS_OFF: cluster-sleep-0 {
+				compatible = "domain-idle-state";
+				arm,psci-suspend-param = <0x41000044>;
+				entry-latency-us = <3300>;
+				exit-latency-us = <3300>;
+				min-residency-us = <6000>;
+			};
+
+			CLUSTER_SLEEP_AOSS_SLEEP: cluster-sleep-1 {
 				compatible = "domain-idle-state";
 				arm,psci-suspend-param = <0x4100a344>;
 				entry-latency-us = <3263>;
@@ -582,7 +591,7 @@
 
 		CLUSTER_PD: power-domain-cpu-cluster0 {
 			#power-domain-cells = <0>;
-			domain-idle-states = <&CLUSTER_SLEEP_0>;
+			domain-idle-states = <&CLUSTER_SLEEP_APSS_OFF &CLUSTER_SLEEP_AOSS_SLEEP>;
 		};
 	};
 
@@ -782,6 +791,7 @@
 			clock-names = "bi_tcxo",
 				      "bi_tcxo_ao",
 				      "sleep_clk";
+			power-domains = <&rpmhpd SC8180X_CX>;
 		};
 
 		qupv3_id_0: geniqup@8c0000 {
@@ -1843,7 +1853,7 @@
 			power-domains = <&gcc PCIE_3_GDSC>;
 
 			interconnects = <&aggre2_noc MASTER_PCIE_3 0 &mc_virt SLAVE_EBI_CH0 0>,
-					<&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>;
+					<&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_3 0>;
 			interconnect-names = "pcie-mem", "cpu-pcie";
 
 			phys = <&pcie3_phy>;
@@ -1941,7 +1951,7 @@
 			power-domains = <&gcc PCIE_1_GDSC>;
 
 			interconnects = <&aggre2_noc MASTER_PCIE_1 0 &mc_virt SLAVE_EBI_CH0 0>,
-					<&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>;
+					<&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_1 0>;
 			interconnect-names = "pcie-mem", "cpu-pcie";
 
 			phys = <&pcie1_phy>;
@@ -2039,7 +2049,7 @@
 			power-domains = <&gcc PCIE_2_GDSC>;
 
 			interconnects = <&aggre2_noc MASTER_PCIE_2 0 &mc_virt SLAVE_EBI_CH0 0>,
-					<&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>;
+					<&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_2 0>;
 			interconnect-names = "pcie-mem", "cpu-pcie";
 
 			phys = <&pcie2_phy>;
@@ -2138,6 +2148,8 @@
 			resets = <&ufs_mem_hc 0>;
 			reset-names = "ufsphy";
 
+			power-domains = <&gcc UFS_PHY_GDSC>;
+
 			#phy-cells = <0>;
 
 			status = "disabled";
@@ -2539,11 +2551,14 @@
 
 		system-cache-controller@9200000 {
 			compatible = "qcom,sc8180x-llcc";
-			reg = <0 0x09200000 0 0x50000>, <0 0x09280000 0 0x50000>,
-			      <0 0x09300000 0 0x50000>, <0 0x09380000 0 0x50000>,
-			      <0 0x09600000 0 0x50000>;
+			reg = <0 0x09200000 0 0x58000>, <0 0x09280000 0 0x58000>,
+			      <0 0x09300000 0 0x58000>, <0 0x09380000 0 0x58000>,
+			      <0 0x09400000 0 0x58000>, <0 0x09480000 0 0x58000>,
+			      <0 0x09500000 0 0x58000>, <0 0x09580000 0 0x58000>,
+			      <0 0x09600000 0 0x58000>;
 			reg-names = "llcc0_base", "llcc1_base", "llcc2_base",
-				    "llcc3_base", "llcc_broadcast_base";
+				    "llcc3_base", "llcc4_base", "llcc5_base",
+				    "llcc6_base", "llcc7_base",  "llcc_broadcast_base";
 			interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
@@ -2606,6 +2621,9 @@
 				phys = <&usb_prim_hsphy>, <&usb_prim_ssphy>;
 				phy-names = "usb2-phy", "usb3-phy";
 
+				snps,dis-u1-entry-quirk;
+				snps,dis-u2-entry-quirk;
+
 				port {
 					usb_prim_role_switch: endpoint {
 					};
@@ -2632,7 +2650,7 @@
 			resets = <&gcc GCC_USB30_SEC_BCR>;
 			power-domains = <&gcc USB30_SEC_GDSC>;
 			interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 7 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 40 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc 10 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 11 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
@@ -2663,6 +2681,9 @@
 				phys = <&usb_sec_hsphy>, <&usb_sec_ssphy>;
 				phy-names = "usb2-phy", "usb3-phy";
 
+				snps,dis-u1-entry-quirk;
+				snps,dis-u2-entry-quirk;
+
 				port {
 					usb_sec_role_switch: endpoint {
 					};
@@ -2692,9 +2713,15 @@
 			interrupt-controller;
 			#interrupt-cells = <1>;
 
-			interconnects = <&mmss_noc MASTER_MDP_PORT0 0 &mc_virt SLAVE_EBI_CH0 0>,
-					<&mmss_noc MASTER_MDP_PORT1 0 &mc_virt SLAVE_EBI_CH0 0>;
-			interconnect-names = "mdp0-mem", "mdp1-mem";
+			interconnects = <&mmss_noc MASTER_MDP_PORT0 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI_CH0 QCOM_ICC_TAG_ALWAYS>,
+					<&mmss_noc MASTER_MDP_PORT1 QCOM_ICC_TAG_ALWAYS
+					 &mc_virt SLAVE_EBI_CH0 QCOM_ICC_TAG_ALWAYS>,
+					<&gem_noc MASTER_AMPSS_M0 QCOM_ICC_TAG_ALWAYS
+					 &config_noc SLAVE_DISPLAY_CFG QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "mdp0-mem",
+					     "mdp1-mem",
+					     "cpu-cfg";
 
 			iommus = <&apps_smmu 0x800 0x420>;
 
@@ -2723,10 +2750,8 @@
 					      "rot",
 					      "lut";
 
-				assigned-clocks = <&dispcc DISP_CC_MDSS_MDP_CLK>,
-						  <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
-				assigned-clock-rates = <460000000>,
-						       <19200000>;
+				assigned-clocks = <&dispcc DISP_CC_MDSS_VSYNC_CLK>;
+				assigned-clock-rates = <19200000>;
 
 				operating-points-v2 = <&mdp_opp_table>;
 				power-domains = <&rpmhpd SC8180X_MMCX>;
@@ -3184,7 +3209,7 @@
 				 <&dispcc DISP_CC_MDSS_AHB_CLK>;
 			clock-names = "aux", "cfg_ahb";
 
-			power-domains = <&dispcc MDSS_GDSC>;
+			power-domains = <&rpmhpd SC8180X_MX>;
 
 			#clock-cells = <1>;
 			#phy-cells = <0>;
@@ -3210,6 +3235,7 @@
 				      "edp_phy_pll_link_clk",
 				      "edp_phy_pll_vco_div_clk";
 			power-domains = <&rpmhpd SC8180X_MMCX>;
+			required-opps = <&rpmhpd_opp_low_svs>;
 			#clock-cells = <1>;
 			#reset-cells = <1>;
 			#power-domain-cells = <1>;
@@ -3248,7 +3274,7 @@
 
 		aoss_qmp: power-controller@c300000 {
 			compatible = "qcom,sc8180x-aoss-qmp", "qcom,aoss-qmp";
-			reg = <0x0 0x0c300000 0x0 0x100000>;
+			reg = <0x0 0x0c300000 0x0 0x400>;
 			interrupts = <GIC_SPI 389 IRQ_TYPE_EDGE_RISING>;
 			mboxes = <&apss_shared 0>;
 
@@ -3613,7 +3639,7 @@
 		};
 
 		cpufreq_hw: cpufreq@18323000 {
-			compatible = "qcom,cpufreq-hw";
+			compatible = "qcom,sc8180x-cpufreq-hw", "qcom,cpufreq-hw";
 			reg = <0 0x18323000 0 0x1400>, <0 0x18325800 0 0x1400>;
 			reg-names = "freq-domain0", "freq-domain1";
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
@@ -299,7 +299,7 @@
 	thermal-zones {
 		skin-temp-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <0>;
+
 			thermal-sensors = <&pmk8280_adc_tm 5>;
 
 			trips {
@@ -416,6 +416,13 @@
 			regulator-always-on;
 		};
 
+		vreg_l1b: ldo1 {
+			regulator-name = "vreg_l1b";
+			regulator-min-microvolt = <912000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
 		vreg_l3b: ldo3 {
 			regulator-name = "vreg_l3b";
 			regulator-min-microvolt = <1200000>;
@@ -466,6 +473,13 @@
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
+		vreg_l8c: ldo8 {
+			regulator-name = "vreg_l8c";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
 		vreg_l12c: ldo12 {
 			regulator-name = "vreg_l12c";
 			regulator-min-microvolt = <1800000>;
@@ -499,6 +513,13 @@
 		vdd-l6-l9-l10-supply = <&vreg_s12b>;
 		vdd-l8-supply = <&vreg_s12b>;
 
+		vreg_l2d: ldo2 {
+			regulator-name = "vreg_l2d";
+			regulator-min-microvolt = <3072000>;
+			regulator-max-microvolt = <3072000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
 		vreg_l3d: ldo3 {
 			regulator-name = "vreg_l3d";
 			regulator-min-microvolt = <1200000>;
@@ -527,12 +548,26 @@
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
 
+		vreg_l8d: ldo8 {
+			regulator-name = "vreg_l8d";
+			regulator-min-microvolt = <912000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
 		vreg_l9d: ldo9 {
 			regulator-name = "vreg_l9d";
 			regulator-min-microvolt = <912000>;
 			regulator-max-microvolt = <912000>;
 			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
 		};
+
+		vreg_l10d: ldo10 {
+			regulator-name = "vreg_l10d";
+			regulator-min-microvolt = <912000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
 	};
 };
 
@@ -620,15 +655,16 @@
 
 	status = "okay";
 
-	/* FIXME: verify */
 	touchscreen@10 {
-		compatible = "hid-over-i2c";
+		compatible = "elan,ekth5015m", "elan,ekth6915";
 		reg = <0x10>;
 
-		hid-descr-addr = <0x1>;
 		interrupts-extended = <&tlmm 175 IRQ_TYPE_LEVEL_LOW>;
-		vdd-supply = <&vreg_misc_3p3>;
-		vddl-supply = <&vreg_s10b>;
+		reset-gpios = <&tlmm 99 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+		no-reset-on-power-off;
+
+		vcc33-supply = <&vreg_misc_3p3>;
+		vccio-supply = <&vreg_misc_3p3>;
 
 		pinctrl-names = "default";
 		pinctrl-0 = <&ts0_default>;
@@ -1203,6 +1239,60 @@
 	remote-endpoint = <&pmic_glink_con1_hs>;
 };
 
+&usb_2 {
+	status = "okay";
+};
+
+&usb_2_dwc3 {
+	dr_mode = "host";
+};
+
+&usb_2_hsphy0 {
+	vdda-pll-supply = <&vreg_l1b>;
+	vdda18-supply = <&vreg_l1c>;
+	vdda33-supply = <&vreg_l7d>;
+
+	status = "okay";
+};
+
+&usb_2_hsphy1 {
+	vdda-pll-supply = <&vreg_l8d>;
+	vdda18-supply = <&vreg_l1c>;
+	vdda33-supply = <&vreg_l7d>;
+
+	status = "okay";
+};
+
+&usb_2_hsphy2 {
+	vdda-pll-supply = <&vreg_l10d>;
+	vdda18-supply = <&vreg_l8c>;
+	vdda33-supply = <&vreg_l2d>;
+
+	status = "okay";
+};
+
+&usb_2_hsphy3 {
+	vdda-pll-supply = <&vreg_l10d>;
+	vdda18-supply = <&vreg_l8c>;
+	vdda33-supply = <&vreg_l2d>;
+
+	status = "okay";
+};
+
+&usb_2_qmpphy0 {
+	vdda-phy-supply = <&vreg_l1b>;
+	vdda-pll-supply = <&vreg_l4d>;
+
+	status = "okay";
+};
+
+&usb_2_qmpphy1 {
+	vdda-phy-supply = <&vreg_l8d>;
+	vdda-pll-supply = <&vreg_l4d>;
+
+	status = "okay";
+};
+
 &vamacro {
 	pinctrl-0 = <&dmic01_default>, <&dmic02_default>;
 	pinctrl-names = "default";
@@ -1452,8 +1542,8 @@
 		reset-n-pins {
 			pins = "gpio99";
 			function = "gpio";
-			output-high;
-			drive-strength = <16>;
+			drive-strength = <2>;
+			bias-disable;
 		};
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc8280xp-pmics.dtsi
@@ -11,7 +11,7 @@
 	thermal-zones {
 		pm8280_1_thermal: pm8280-1-thermal {
 			polling-delay-passive = <100>;
-			polling-delay = <0>;
+
 			thermal-sensors = <&pm8280_1_temp_alarm>;
 
 			trips {
@@ -31,7 +31,7 @@
 
 		pm8280_2_thermal: pm8280-2-thermal {
 			polling-delay-passive = <100>;
-			polling-delay = <0>;
+
 			thermal-sensors = <&pm8280_2_temp_alarm>;
 
 			trips {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
@@ -2,6 +2,7 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
  * Copyright (c) 2022, Linaro Limited
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <dt-bindings/clock/qcom,dispcc-sc8280xp.h>
@@ -1774,6 +1775,7 @@
 			reset-names = "pci";
 
 			power-domains = <&gcc PCIE_4_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
 
 			phys = <&pcie4_phy>;
 			phy-names = "pciephy";
@@ -1798,6 +1800,7 @@
 			assigned-clock-rates = <100000000>;
 
 			power-domains = <&gcc PCIE_4_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
 
 			resets = <&gcc GCC_PCIE_4_PHY_BCR>;
 			reset-names = "phy";
@@ -1872,6 +1875,7 @@
 			reset-names = "pci";
 
 			power-domains = <&gcc PCIE_3B_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
 
 			phys = <&pcie3b_phy>;
 			phy-names = "pciephy";
@@ -1896,6 +1900,7 @@
 			assigned-clock-rates = <100000000>;
 
 			power-domains = <&gcc PCIE_3B_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
 
 			resets = <&gcc GCC_PCIE_3B_PHY_BCR>;
 			reset-names = "phy";
@@ -1970,6 +1975,7 @@
 			reset-names = "pci";
 
 			power-domains = <&gcc PCIE_3A_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
 
 			phys = <&pcie3a_phy>;
 			phy-names = "pciephy";
@@ -1995,6 +2001,7 @@
 			assigned-clock-rates = <100000000>;
 
 			power-domains = <&gcc PCIE_3A_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
 
 			resets = <&gcc GCC_PCIE_3A_PHY_BCR>;
 			reset-names = "phy";
@@ -2071,6 +2078,7 @@
 			reset-names = "pci";
 
 			power-domains = <&gcc PCIE_2B_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
 
 			phys = <&pcie2b_phy>;
 			phy-names = "pciephy";
@@ -2095,6 +2103,7 @@
 			assigned-clock-rates = <100000000>;
 
 			power-domains = <&gcc PCIE_2B_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
 
 			resets = <&gcc GCC_PCIE_2B_PHY_BCR>;
 			reset-names = "phy";
@@ -2169,6 +2178,7 @@
 			reset-names = "pci";
 
 			power-domains = <&gcc PCIE_2A_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
 
 			phys = <&pcie2a_phy>;
 			phy-names = "pciephy";
@@ -2194,6 +2204,7 @@
 			assigned-clock-rates = <100000000>;
 
 			power-domains = <&gcc PCIE_2A_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
 
 			resets = <&gcc GCC_PCIE_2A_PHY_BCR>;
 			reset-names = "phy";
@@ -2633,9 +2644,9 @@
 
 		remoteproc_adsp: remoteproc@3000000 {
 			compatible = "qcom,sc8280xp-adsp-pas";
-			reg = <0 0x03000000 0 0x100>;
+			reg = <0 0x03000000 0 0x10000>;
 
-			interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
@@ -3331,6 +3342,88 @@
 			interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
+		usb_2: usb@a4f8800 {
+			compatible = "qcom,sc8280xp-dwc3-mp", "qcom,dwc3";
+			reg = <0 0x0a4f8800 0 0x400>;
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+
+			clocks = <&gcc GCC_CFG_NOC_USB3_MP_AXI_CLK>,
+				 <&gcc GCC_USB30_MP_MASTER_CLK>,
+				 <&gcc GCC_AGGRE_USB3_MP_AXI_CLK>,
+				 <&gcc GCC_USB30_MP_SLEEP_CLK>,
+				 <&gcc GCC_USB30_MP_MOCK_UTMI_CLK>,
+				 <&gcc GCC_AGGRE_USB_NOC_AXI_CLK>,
+				 <&gcc GCC_AGGRE_USB_NOC_NORTH_AXI_CLK>,
+				 <&gcc GCC_AGGRE_USB_NOC_SOUTH_AXI_CLK>,
+				 <&gcc GCC_SYS_NOC_USB_AXI_CLK>;
+			clock-names = "cfg_noc", "core", "iface", "sleep", "mock_utmi",
+				      "noc_aggr", "noc_aggr_north", "noc_aggr_south", "noc_sys";
+
+			assigned-clocks = <&gcc GCC_USB30_MP_MOCK_UTMI_CLK>,
+					  <&gcc GCC_USB30_MP_MASTER_CLK>;
+			assigned-clock-rates = <19200000>, <200000000>;
+
+			interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 857 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 856 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 860 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 859 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 127 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 126 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 129 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 128 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 131 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 130 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 133 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 132 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 16 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
+
+			interrupt-names = "pwr_event_1", "pwr_event_2",
+					  "pwr_event_3", "pwr_event_4",
+					  "hs_phy_1",	 "hs_phy_2",
+					  "hs_phy_3",	 "hs_phy_4",
+					  "dp_hs_phy_1", "dm_hs_phy_1",
+					  "dp_hs_phy_2", "dm_hs_phy_2",
+					  "dp_hs_phy_3", "dm_hs_phy_3",
+					  "dp_hs_phy_4", "dm_hs_phy_4",
+					  "ss_phy_1",	 "ss_phy_2";
+
+			power-domains = <&gcc USB30_MP_GDSC>;
+			required-opps = <&rpmhpd_opp_nom>;
+
+			resets = <&gcc GCC_USB30_MP_BCR>;
+
+			interconnects = <&aggre1_noc MASTER_USB3_MP 0 &mc_virt SLAVE_EBI1 0>,
+					<&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB3_MP 0>;
+			interconnect-names = "usb-ddr", "apps-usb";
+
+			wakeup-source;
+
+			status = "disabled";
+
+			usb_2_dwc3: usb@a400000 {
+				compatible = "snps,dwc3";
+				reg = <0 0x0a400000 0 0xcd00>;
+				interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+				iommus = <&apps_smmu 0x800 0x0>;
+				phys = <&usb_2_hsphy0>, <&usb_2_qmpphy0>,
+				       <&usb_2_hsphy1>, <&usb_2_qmpphy1>,
+				       <&usb_2_hsphy2>,
+				       <&usb_2_hsphy3>;
+				phy-names = "usb2-0", "usb3-0",
+					    "usb2-1", "usb3-1",
+					    "usb2-2",
+					    "usb2-3";
+				dr_mode = "host";
+			};
+		};
+
 		usb_0: usb@a6f8800 {
 			compatible = "qcom,sc8280xp-dwc3", "qcom,dwc3";
 			reg = <0 0x0a6f8800 0 0x400>;
@@ -3384,6 +3477,9 @@
 				phys = <&usb_0_hsphy>, <&usb_0_qmpphy QMP_USB43DP_USB3_PHY>;
 				phy-names = "usb2-phy", "usb3-phy";
 
+				snps,dis-u1-entry-quirk;
+				snps,dis-u2-entry-quirk;
+
 				port {
 					usb_0_role_switch: endpoint {
 					};
@@ -3444,6 +3540,9 @@
 				phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
 				phy-names = "usb2-phy", "usb3-phy";
 
+				snps,dis-u1-entry-quirk;
+				snps,dis-u2-entry-quirk;
+
 				port {
 					usb_1_role_switch: endpoint {
 					};
@@ -4405,9 +4504,9 @@
 
 		remoteproc_nsp0: remoteproc@1b300000 {
 			compatible = "qcom,sc8280xp-nsp0-pas";
-			reg = <0 0x1b300000 0 0x100>;
+			reg = <0 0x1b300000 0 0x10000>;
 
-			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_nsp0_in 0 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_nsp0_in 1 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_nsp0_in 2 IRQ_TYPE_EDGE_RISING>,
@@ -4536,9 +4635,9 @@
 
 		remoteproc_nsp1: remoteproc@21300000 {
 			compatible = "qcom,sc8280xp-nsp1-pas";
-			reg = <0 0x21300000 0 0x100>;
+			reg = <0 0x21300000 0 0x10000>;
 
-			interrupts-extended = <&intc GIC_SPI 887 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 887 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_nsp1_in 0 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_nsp1_in 1 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_nsp1_in 2 IRQ_TYPE_EDGE_RISING>,
@@ -5079,7 +5178,6 @@
 	thermal-zones {
 		cpu0-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <1000>;
 
 			thermal-sensors = <&tsens0 1>;
 
@@ -5094,7 +5192,6 @@
 
 		cpu1-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <1000>;
 
 			thermal-sensors = <&tsens0 2>;
 
@@ -5109,7 +5206,6 @@
 
 		cpu2-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <1000>;
 
 			thermal-sensors = <&tsens0 3>;
 
@@ -5124,7 +5220,6 @@
 
 		cpu3-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <1000>;
 
 			thermal-sensors = <&tsens0 4>;
 
@@ -5139,7 +5234,6 @@
 
 		cpu4-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <1000>;
 
 			thermal-sensors = <&tsens0 5>;
 
@@ -5154,7 +5248,6 @@
 
 		cpu5-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <1000>;
 
 			thermal-sensors = <&tsens0 6>;
 
@@ -5169,7 +5262,6 @@
 
 		cpu6-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <1000>;
 
 			thermal-sensors = <&tsens0 7>;
 
@@ -5184,7 +5276,6 @@
 
 		cpu7-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <1000>;
 
 			thermal-sensors = <&tsens0 8>;
 
@@ -5199,7 +5290,6 @@
 
 		cluster0-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <1000>;
 
 			thermal-sensors = <&tsens0 9>;
 
@@ -5214,7 +5304,6 @@
 
 		mem-thermal {
 			polling-delay-passive = <250>;
-			polling-delay = <1000>;
 
 			thermal-sensors = <&tsens1 15>;
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sdm450-motorola-ali.dts
@@ -248,5 +248,6 @@
 };
 
 &usb3_dwc3 {
+	/delete-property/ usb-role-switch;
 	dr_mode = "peripheral";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sdm630.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sdm630.dtsi
@@ -1296,6 +1296,7 @@
 				interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
 				snps,dis_u2_susphy_quirk;
 				snps,dis_enblslpm_quirk;
+				snps,parkmode-disable-ss-quirk;
 
 				/*
 				 * SDM630 technically supports USB3 but I
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sdm632-motorola-ocean.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sdm632-motorola-ocean.dts
@@ -287,5 +287,6 @@
 };
 
 &usb3_dwc3 {
+	/delete-property/ usb-role-switch;
 	dr_mode = "peripheral";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sdm845-db845c-navigation-mezzanine.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sdm845-db845c-navigation-mezzanine.dtso
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022, Linaro Ltd.
+ */
+
+/dts-v1/;
+/plugin/;
+
+#include <dt-bindings/clock/qcom,camcc-sdm845.h>
+#include <dt-bindings/gpio/gpio.h>
+
+&camss {
+	vdda-phy-supply = <&vreg_l1a_0p875>;
+	vdda-pll-supply = <&vreg_l26a_1p2>;
+
+	status = "okay";
+
+	ports {
+		port@0 {
+			csiphy0_ep: endpoint {
+				data-lanes = <0 1 2 3>;
+				remote-endpoint = <&ov8856_ep>;
+			};
+		};
+	};
+};
+
+&cci {
+	status = "okay";
+};
+
+&cci_i2c0 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+
+	camera@10 {
+		compatible = "ovti,ov8856";
+		reg = <0x10>;
+
+		/* CAM0_RST_N */
+		reset-gpios = <&tlmm 9 GPIO_ACTIVE_LOW>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&cam0_default>;
+
+		clocks = <&clock_camcc CAM_CC_MCLK0_CLK>;
+		clock-names = "xvclk";
+		clock-frequency = <19200000>;
+
+		/*
+		 * The &vreg_s4a_1p8 trace is powered on as a,
+		 * so it is represented by a fixed regulator.
+		 *
+		 * The 2.8V vdda-supply and 1.2V vddd-supply regulators
+		 * both have to be enabled through the power management
+		 * gpios.
+		 */
+		dovdd-supply = <&vreg_lvs1a_1p8>;
+		avdd-supply = <&cam0_avdd_2v8>;
+		dvdd-supply = <&cam0_dvdd_1v2>;
+
+		port {
+			ov8856_ep: endpoint {
+				link-frequencies = /bits/ 64
+					<360000000 180000000>;
+				data-lanes = <1 2 3 4>;
+				remote-endpoint = <&csiphy0_ep>;
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
@@ -580,7 +580,7 @@
 &pcie0 {
 	status = "okay";
 	perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>;
-	enable-gpio = <&tlmm 134 GPIO_ACTIVE_HIGH>;
+	wake-gpios = <&tlmm 134 GPIO_ACTIVE_HIGH>;
 
 	vddpe-3v3-supply = <&pcie0_3p3v_dual>;
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
@@ -508,13 +508,13 @@
 };
 
 &q6afedai {
-	qi2s@22 {
-		reg = <22>;
+	dai@22 {
+		reg = <QUATERNARY_MI2S_RX>;
 		qcom,sd-lines = <1>;
 	};
 
-	qi2s@23 {
-		reg = <23>;
+	dai@23 {
+		reg = <QUATERNARY_MI2S_TX>;
 		qcom,sd-lines = <0>;
 	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts
@@ -60,7 +60,7 @@
 	};
 
 	reserved-memory {
-		framebuffer_region@9d400000 {
+		framebuffer@9d400000 {
 			reg = <0x0 0x9d400000 0x0 (1080 * 2160 * 4)>;
 			no-map;
 		};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -2644,6 +2644,8 @@
 			clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
 				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
 
+			power-domains = <&gcc UFS_PHY_GDSC>;
+
 			resets = <&ufs_mem_hc 0>;
 			reset-names = "ufsphy";
 
@@ -3366,8 +3368,8 @@
 
 			qcom,qmp = <&aoss_qmp>;
 
-			power-domains = <&rpmhpd SDM845_CX>,
-					<&rpmhpd SDM845_MX>;
+			power-domains = <&rpmhpd SDM845_LCX>,
+					<&rpmhpd SDM845_LMX>;
 			power-domain-names = "lcx", "lmx";
 
 			memory-region = <&slpi_mem>;
@@ -4080,6 +4082,7 @@
 				iommus = <&apps_smmu 0x740 0>;
 				snps,dis_u2_susphy_quirk;
 				snps,dis_enblslpm_quirk;
+				snps,parkmode-disable-ss-quirk;
 				phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
 				phy-names = "usb2-phy", "usb3-phy";
 			};
@@ -4131,6 +4134,7 @@
 				iommus = <&apps_smmu 0x760 0>;
 				snps,dis_u2_susphy_quirk;
 				snps,dis_enblslpm_quirk;
+				snps,parkmode-disable-ss-quirk;
 				phys = <&usb_2_hsphy>, <&usb_2_qmpphy>;
 				phy-names = "usb2-phy", "usb3-phy";
 			};
@@ -4242,16 +4246,16 @@
 				"vfe1",
 				"vfe_lite";
 
-			interrupts = <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>,
-				<GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>,
-				<GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>,
-				<GIC_SPI 477 IRQ_TYPE_LEVEL_HIGH>,
-				<GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>,
-				<GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>,
-				<GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>,
-				<GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>,
-				<GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>,
-				<GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>;
+			interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
+				<GIC_SPI 466 IRQ_TYPE_EDGE_RISING>,
+				<GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
+				<GIC_SPI 477 IRQ_TYPE_EDGE_RISING>,
+				<GIC_SPI 478 IRQ_TYPE_EDGE_RISING>,
+				<GIC_SPI 479 IRQ_TYPE_EDGE_RISING>,
+				<GIC_SPI 448 IRQ_TYPE_EDGE_RISING>,
+				<GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
+				<GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
+				<GIC_SPI 469 IRQ_TYPE_EDGE_RISING>;
 			interrupt-names = "csid0",
 				"csid1",
 				"csid2",
@@ -5568,7 +5572,7 @@
 					hysteresis = <2000>;
 					type = "hot";
 				};
-				cluster0_crit: cluster0_crit {
+				cluster0_crit: cluster0-crit {
 					temperature = <110000>;
 					hysteresis = <2000>;
 					type = "critical";
@@ -5588,7 +5592,7 @@
 					hysteresis = <2000>;
 					type = "hot";
 				};
-				cluster1_crit: cluster1_crit {
+				cluster1_crit: cluster1-crit {
 					temperature = <110000>;
 					hysteresis = <2000>;
 					type = "critical";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
@@ -494,6 +494,7 @@
 &ipa {
 	qcom,gsi-loader = "self";
 	memory-region = <&ipa_fw_mem>;
+	firmware-name = "qcom/sdm850/LENOVO/81JL/ipa_fws.elf";
 	status = "okay";
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sdx75.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sdx75.dtsi
@@ -31,7 +31,7 @@
 
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
-			clock-frequency = <32000>;
+			clock-frequency = <32764>;
 			#clock-cells = <0>;
 		};
 	};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm4250-oneplus-billie2.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm4250-oneplus-billie2.dts
@@ -240,6 +240,7 @@
 };
 
 &usb_dwc3 {
+	/delete-property/ usb-role-switch;
 	maximum-speed = "high-speed";
 	dr_mode = "peripheral";
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm4450.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm4450.dtsi
@@ -26,7 +26,7 @@
 
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
-			clock-frequency = <32000>;
+			clock-frequency = <32764>;
 			#clock-cells = <0>;
 		};
 	};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm6115-fxtec-pro1x.dts
@@ -234,6 +234,7 @@
 };
 
 &usb_dwc3 {
+	/delete-property/ usb-role-switch;
 	maximum-speed = "high-speed";
 	dr_mode = "peripheral";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm6115.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm6115.dtsi
@@ -614,6 +614,11 @@
 			#hwlock-cells = <1>;
 		};
 
+		tcsr_regs: syscon@3c0000 {
+			compatible = "qcom,sm6115-tcsr", "syscon";
+			reg = <0x0 0x003c0000 0x0 0x40000>;
+		};
+
 		tlmm: pinctrl@500000 {
 			compatible = "qcom,sm6115-tlmm";
 			reg = <0x0 0x00500000 0x0 0x400000>,
@@ -879,6 +884,8 @@
 
 			#phy-cells = <0>;
 
+			qcom,tcsr-reg = <&tcsr_regs 0xb244>;
+
 			status = "disabled";
 		};
 
@@ -1061,6 +1068,7 @@
 
 			power-domains = <&rpmpd SM6115_VDDCX>;
 			operating-points-v2 = <&sdhc1_opp_table>;
+			iommus = <&apps_smmu 0x00c0 0x0>;
 			interconnects = <&system_noc MASTER_SDCC_1 RPM_ALWAYS_TAG
 					 &bimc SLAVE_EBI_CH0 RPM_ALWAYS_TAG>,
 					<&bimc MASTER_AMPSS_M0 RPM_ALWAYS_TAG
@@ -1197,6 +1205,8 @@
 			clocks = <&gcc GCC_UFS_CLKREF_CLK>, <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
 			clock-names = "ref", "ref_aux";
 
+			power-domains = <&gcc GCC_UFS_PHY_GDSC>;
+
 			resets = <&ufs_mem_hc 0>;
 			reset-names = "ufsphy";
 
@@ -1603,7 +1613,6 @@
 			interconnect-names = "usb-ddr",
 					     "apps-usb";
 
-			qcom,select-utmi-as-pipe-clk;
 			status = "disabled";
 
 			usb_dwc3: usb@4e00000 {
@@ -1961,7 +1970,7 @@
 
 		remoteproc_mpss: remoteproc@6080000 {
 			compatible = "qcom,sm6115-mpss-pas";
-			reg = <0x0 0x06080000 0x0 0x100>;
+			reg = <0x0 0x06080000 0x0 0x10000>;
 
 			interrupts-extended = <&intc GIC_SPI 307 IRQ_TYPE_EDGE_RISING>,
 					      <&modem_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
@@ -2604,9 +2613,9 @@
 			};
 		};
 
-		remoteproc_adsp: remoteproc@ab00000 {
+		remoteproc_adsp: remoteproc@a400000 {
 			compatible = "qcom,sm6115-adsp-pas";
-			reg = <0x0 0x0ab00000 0x0 0x100>;
+			reg = <0x0 0x0a400000 0x0 0x4040>;
 
 			interrupts-extended = <&intc GIC_SPI 282 IRQ_TYPE_EDGE_RISING>,
 					      <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
@@ -2678,7 +2687,7 @@
 
 		remoteproc_cdsp: remoteproc@b300000 {
 			compatible = "qcom,sm6115-cdsp-pas";
-			reg = <0x0 0x0b300000 0x0 0x100000>;
+			reg = <0x0 0x0b300000 0x0 0x4040>;
 
 			interrupts-extended = <&intc GIC_SPI 265 IRQ_TYPE_EDGE_RISING>,
 					      <&cdsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
@@ -3088,7 +3097,7 @@
 					type = "passive";
 				};
 
-				cpu4_crit: cpu_crit {
+				cpu4_crit: cpu-crit {
 					temperature = <110000>;
 					hysteresis = <1000>;
 					type = "critical";
@@ -3114,7 +3123,7 @@
 					type = "passive";
 				};
 
-				cpu5_crit: cpu_crit {
+				cpu5_crit: cpu-crit {
 					temperature = <110000>;
 					hysteresis = <1000>;
 					type = "critical";
@@ -3140,7 +3149,7 @@
 					type = "passive";
 				};
 
-				cpu6_crit: cpu_crit {
+				cpu6_crit: cpu-crit {
 					temperature = <110000>;
 					hysteresis = <1000>;
 					type = "critical";
@@ -3166,7 +3175,7 @@
 					type = "passive";
 				};
 
-				cpu7_crit: cpu_crit {
+				cpu7_crit: cpu-crit {
 					temperature = <110000>;
 					hysteresis = <1000>;
 					type = "critical";
@@ -3192,7 +3201,7 @@
 					type = "passive";
 				};
 
-				cpu45_crit: cpu_crit {
+				cpu45_crit: cpu-crit {
 					temperature = <110000>;
 					hysteresis = <1000>;
 					type = "critical";
@@ -3218,7 +3227,7 @@
 					type = "passive";
 				};
 
-				cpu67_crit: cpu_crit {
+				cpu67_crit: cpu-crit {
 					temperature = <110000>;
 					hysteresis = <1000>;
 					type = "critical";
@@ -3244,7 +3253,7 @@
 					type = "passive";
 				};
 
-				cpu0123_crit: cpu_crit {
+				cpu0123_crit: cpu-crit {
 					temperature = <110000>;
 					hysteresis = <1000>;
 					type = "critical";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm6115p-lenovo-j606f.dts
@@ -359,6 +359,7 @@
 };
 
 &usb_dwc3 {
+	/delete-property/ usb-role-switch;
 	maximum-speed = "high-speed";
 	dr_mode = "peripheral";
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm6125.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm6125.dtsi
@@ -28,7 +28,7 @@
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
 			#clock-cells = <0>;
-			clock-frequency = <32000>;
+			clock-frequency = <32764>;
 			clock-output-names = "sleep_clk";
 		};
 	};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm6350.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm6350.dtsi
@@ -935,7 +935,7 @@
 				power-domains = <&rpmhpd SM6350_CX>;
 				operating-points-v2 = <&qup_opp_table>;
 				interconnects = <&clk_virt MASTER_QUP_CORE_0 0 &clk_virt SLAVE_QUP_CORE_0 0>,
-						<&aggre1_noc MASTER_QUP_0 0 &clk_virt SLAVE_EBI_CH0 0>;
+						<&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_QUP_0 0>;
 				interconnect-names = "qup-core", "qup-config";
 				status = "disabled";
 			};
@@ -1194,6 +1194,8 @@
 			clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
 				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
 
+			power-domains = <&gcc UFS_PHY_GDSC>;
+
 			resets = <&ufs_mem_hc 0>;
 			reset-names = "ufsphy";
 
@@ -1247,9 +1249,9 @@
 
 		adsp: remoteproc@3000000 {
 			compatible = "qcom,sm6350-adsp-pas";
-			reg = <0 0x03000000 0 0x100>;
+			reg = <0x0 0x03000000 0x0 0x10000>;
 
-			interrupts-extended = <&pdc 6 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
@@ -1287,6 +1289,7 @@
 					compatible = "qcom,fastrpc";
 					qcom,glink-channels = "fastrpcglink-apps-dsp";
 					label = "adsp";
+					qcom,non-secure-domain;
 					#address-cells = <1>;
 					#size-cells = <0>;
 
@@ -1338,43 +1341,43 @@
 				opp-850000000 {
 					opp-hz = /bits/ 64 <850000000>;
 					opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
-					opp-supported-hw = <0x02>;
+					opp-supported-hw = <0x03>;
 				};
 
 				opp-800000000 {
 					opp-hz = /bits/ 64 <800000000>;
 					opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
-					opp-supported-hw = <0x04>;
+					opp-supported-hw = <0x07>;
 				};
 
 				opp-650000000 {
 					opp-hz = /bits/ 64 <650000000>;
 					opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
-					opp-supported-hw = <0x08>;
+					opp-supported-hw = <0x0f>;
 				};
 
 				opp-565000000 {
 					opp-hz = /bits/ 64 <565000000>;
 					opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
-					opp-supported-hw = <0x10>;
+					opp-supported-hw = <0x1f>;
 				};
 
 				opp-430000000 {
 					opp-hz = /bits/ 64 <430000000>;
 					opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
-					opp-supported-hw = <0xff>;
+					opp-supported-hw = <0x1f>;
 				};
 
 				opp-355000000 {
 					opp-hz = /bits/ 64 <355000000>;
 					opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
-					opp-supported-hw = <0xff>;
+					opp-supported-hw = <0x1f>;
 				};
 
 				opp-253000000 {
 					opp-hz = /bits/ 64 <253000000>;
 					opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
-					opp-supported-hw = <0xff>;
+					opp-supported-hw = <0x1f>;
 				};
 			};
 		};
@@ -1467,7 +1470,7 @@
 
 		mpss: remoteproc@4080000 {
 			compatible = "qcom,sm6350-mpss-pas";
-			reg = <0x0 0x04080000 0x0 0x4040>;
+			reg = <0x0 0x04080000 0x0 0x10000>;
 
 			interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_EDGE_RISING>,
 					      <&modem_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
@@ -1509,7 +1512,7 @@
 			compatible = "qcom,sm6350-cdsp-pas";
 			reg = <0 0x08300000 0 0x10000>;
 
-			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>,
@@ -1547,6 +1550,7 @@
 					compatible = "qcom,fastrpc";
 					qcom,glink-channels = "fastrpcglink-apps-dsp";
 					label = "cdsp";
+					qcom,non-secure-domain;
 					#address-cells = <1>;
 					#size-cells = <0>;
 
@@ -1854,6 +1858,7 @@
 				snps,dis_enblslpm_quirk;
 				snps,has-lpm-erratum;
 				snps,hird-threshold = /bits/ 8 <0x10>;
+				snps,parkmode-disable-ss-quirk;
 				phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>;
 				phy-names = "usb2-phy", "usb3-phy";
 			};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm6375.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm6375.dtsi
@@ -29,7 +29,7 @@
 
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
-			clock-frequency = <32000>;
+			clock-frequency = <32764>;
 			#clock-cells = <0>;
 		};
 	};
@@ -1431,13 +1431,15 @@
 			assigned-clock-rates = <19200000>, <133333333>;
 
 			interrupts-extended = <&intc GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>,
-					      <&mpm 12 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>,
+					      <&mpm 94 IRQ_TYPE_EDGE_BOTH>,
 					      <&mpm 93 IRQ_TYPE_EDGE_BOTH>,
-					      <&mpm 94 IRQ_TYPE_EDGE_BOTH>;
-			interrupt-names = "hs_phy_irq",
-					  "ss_phy_irq",
+					      <&mpm 12 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
+					  "dp_hs_phy_irq",
 					  "dm_hs_phy_irq",
-					  "dp_hs_phy_irq";
+					  "ss_phy_irq";
 
 			power-domains = <&gcc USB30_PRIM_GDSC>;
 
@@ -1514,9 +1516,9 @@
 			#power-domain-cells = <1>;
 		};
 
-		remoteproc_mss: remoteproc@6000000 {
+		remoteproc_mss: remoteproc@6080000 {
 			compatible = "qcom,sm6375-mpss-pas";
-			reg = <0 0x06000000 0 0x4040>;
+			reg = <0x0 0x06080000 0x0 0x10000>;
 
 			interrupts-extended = <&intc GIC_SPI 307 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>,
@@ -1557,9 +1559,9 @@
 
 		remoteproc_adsp: remoteproc@a400000 {
 			compatible = "qcom,sm6375-adsp-pas";
-			reg = <0 0x0a400000 0 0x100>;
+			reg = <0 0x0a400000 0 0x10000>;
 
-			interrupts-extended = <&intc GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 282 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
@@ -1593,9 +1595,9 @@
 			};
 		};
 
-		remoteproc_cdsp: remoteproc@b000000 {
+		remoteproc_cdsp: remoteproc@b300000 {
 			compatible = "qcom,sm6375-cdsp-pas";
-			reg = <0x0 0x0b000000 0x0 0x100000>;
+			reg = <0x0 0x0b300000 0x0 0x10000>;
 
 			interrupts-extended = <&intc GIC_SPI 265 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm7125.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm7125.dtsi
@@ -6,11 +6,11 @@
 #include "sc7180.dtsi"
 
 /* SM7125 uses Kryo 465 instead of Kryo 468 */
-&CPU0 { compatible = "qcom,kryo465"; };
-&CPU1 { compatible = "qcom,kryo465"; };
-&CPU2 { compatible = "qcom,kryo465"; };
-&CPU3 { compatible = "qcom,kryo465"; };
-&CPU4 { compatible = "qcom,kryo465"; };
-&CPU5 { compatible = "qcom,kryo465"; };
-&CPU6 { compatible = "qcom,kryo465"; };
-&CPU7 { compatible = "qcom,kryo465"; };
+&cpu0 { compatible = "qcom,kryo465"; };
+&cpu1 { compatible = "qcom,kryo465"; };
+&cpu2 { compatible = "qcom,kryo465"; };
+&cpu3 { compatible = "qcom,kryo465"; };
+&cpu4 { compatible = "qcom,kryo465"; };
+&cpu5 { compatible = "qcom,kryo465"; };
+&cpu6 { compatible = "qcom,kryo465"; };
+&cpu7 { compatible = "qcom,kryo465"; };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
@@ -31,7 +31,7 @@
 	chassis-type = "handset";
 
 	/* required for bootloader to select correct board */
-	qcom,msm-id = <434 0x10000>, <459 0x10000>;
+	qcom,msm-id = <459 0x10000>;
 	qcom,board-id = <8 32>;
 
 	aliases {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8150-microsoft-surface-duo.dts
@@ -376,8 +376,8 @@
 		pinctrl-0 = <&da7280_intr_default>;
 
 		dlg,actuator-type = "LRA";
-		dlg,dlg,const-op-mode = <1>;
-		dlg,dlg,periodic-op-mode = <1>;
+		dlg,const-op-mode = <1>;
+		dlg,periodic-op-mode = <1>;
 		dlg,nom-microvolt = <2000000>;
 		dlg,abs-max-microvolt = <2000000>;
 		dlg,imax-microamp = <129000>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8150.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -967,7 +967,7 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 
-			gpu_speed_bin: gpu_speed_bin@133 {
+			gpu_speed_bin: gpu-speed-bin@133 {
 				reg = <0x133 0x1>;
 				bits = <5 3>;
 			};
@@ -1879,7 +1879,7 @@
 			phy-names = "pciephy";
 
 			perst-gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>;
-			enable-gpio = <&tlmm 37 GPIO_ACTIVE_HIGH>;
+			wake-gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>;
 
 			pinctrl-names = "default";
 			pinctrl-0 = <&pcie0_default_state>;
@@ -2428,7 +2428,7 @@
 				bias-disable;
 			};
 
-			qup_spi6_default: qup-spi6_default-state {
+			qup_spi6_default: qup-spi6-default-state {
 				pins = "gpio4", "gpio5", "gpio6", "gpio7";
 				function = "qup6";
 				drive-strength = <6>;
@@ -2442,7 +2442,7 @@
 				bias-disable;
 			};
 
-			qup_spi7_default: qup-spi7_default-state {
+			qup_spi7_default: qup-spi7-default-state {
 				pins = "gpio98", "gpio99", "gpio100", "gpio101";
 				function = "qup7";
 				drive-strength = <6>;
@@ -3573,12 +3573,16 @@
 					  <&gcc GCC_USB30_PRIM_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <200000000>;
 
-			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 6 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 8 IRQ_TYPE_EDGE_BOTH>,
-					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
-			interrupt-names = "hs_phy_irq", "ss_phy_irq",
-					  "dm_hs_phy_irq", "dp_hs_phy_irq";
+					      <&pdc 6 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
+					  "dp_hs_phy_irq",
+					  "dm_hs_phy_irq",
+					  "ss_phy_irq";
 
 			power-domains = <&gcc USB30_PRIM_GDSC>;
 
@@ -3645,12 +3649,16 @@
 					  <&gcc GCC_USB30_SEC_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <200000000>;
 
-			interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 7 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 11 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 10 IRQ_TYPE_EDGE_BOTH>,
-					      <&pdc 11 IRQ_TYPE_EDGE_BOTH>;
-			interrupt-names = "hs_phy_irq", "ss_phy_irq",
-					  "dm_hs_phy_irq", "dp_hs_phy_irq";
+					      <&pdc 7 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
+					  "dp_hs_phy_irq",
+					  "dm_hs_phy_irq",
+					  "ss_phy_irq";
 
 			power-domains = <&gcc USB30_SEC_GDSC>;
 
@@ -5067,7 +5075,7 @@
 					hysteresis = <2000>;
 					type = "hot";
 				};
-				cluster0_crit: cluster0_crit {
+				cluster0_crit: cluster0-crit {
 					temperature = <110000>;
 					hysteresis = <2000>;
 					type = "critical";
@@ -5087,7 +5095,7 @@
 					hysteresis = <2000>;
 					type = "hot";
 				};
-				cluster1_crit: cluster1_crit {
+				cluster1_crit: cluster1-crit {
 					temperature = <110000>;
 					hysteresis = <2000>;
 					type = "critical";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -86,7 +86,7 @@
 
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
-			clock-frequency = <32768>;
+			clock-frequency = <32764>;
 			#clock-cells = <0>;
 		};
 	};
@@ -975,7 +975,7 @@
 			#address-cells = <1>;
 			#size-cells = <1>;
 
-			gpu_speed_bin: gpu_speed_bin@19b {
+			gpu_speed_bin: gpu-speed-bin@19b {
 				reg = <0x19b 0x1>;
 				bits = <5 3>;
 			};
@@ -2514,6 +2514,8 @@
 			resets = <&ufs_mem_hc 0>;
 			reset-names = "ufsphy";
 
+			power-domains = <&gcc UFS_PHY_GDSC>;
+
 			#phy-cells = <0>;
 
 			status = "disabled";
@@ -3025,7 +3027,7 @@
 			compatible = "qcom,sm8250-slpi-pas";
 			reg = <0 0x05c00000 0 0x4000>;
 
-			interrupts-extended = <&pdc 9 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&pdc 9 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_slpi_in 0 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_slpi_in 1 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_slpi_in 2 IRQ_TYPE_EDGE_RISING>,
@@ -3729,7 +3731,7 @@
 			compatible = "qcom,sm8250-cdsp-pas";
 			reg = <0 0x08300000 0 0x10000>;
 
-			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>,
@@ -4128,14 +4130,16 @@
 					  <&gcc GCC_USB30_PRIM_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <200000000>;
 
-			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 17 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
-					      <&pdc 14 IRQ_TYPE_EDGE_BOTH>;
-			interrupt-names = "hs_phy_irq",
-					  "ss_phy_irq",
+					      <&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
+					  "dp_hs_phy_irq",
 					  "dm_hs_phy_irq",
-					  "dp_hs_phy_irq";
+					  "ss_phy_irq";
 
 			power-domains = <&gcc USB30_PRIM_GDSC>;
 			wakeup-source;
@@ -4197,14 +4201,16 @@
 					  <&gcc GCC_USB30_SEC_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <200000000>;
 
-			interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 16 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 12 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 13 IRQ_TYPE_EDGE_BOTH>,
-					      <&pdc 12 IRQ_TYPE_EDGE_BOTH>;
-			interrupt-names = "hs_phy_irq",
-					  "ss_phy_irq",
+					      <&pdc 16 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
+					  "dp_hs_phy_irq",
 					  "dm_hs_phy_irq",
-					  "dp_hs_phy_irq";
+					  "ss_phy_irq";
 
 			power-domains = <&gcc USB30_SEC_GDSC>;
 			wakeup-source;
@@ -4409,20 +4415,20 @@
 				    "vfe_lite0",
 				    "vfe_lite1";
 
-			interrupts = <GIC_SPI 477 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
+			interrupts = <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 448 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 86 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 89 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 468 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 359 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 360 IRQ_TYPE_EDGE_RISING>;
 			interrupt-names = "csiphy0",
 					  "csiphy1",
 					  "csiphy2",
@@ -5887,7 +5893,7 @@
 			compatible = "qcom,sm8250-adsp-pas";
 			reg = <0 0x17300000 0 0x100>;
 
-			interrupts-extended = <&pdc 6 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
@@ -6757,7 +6763,7 @@
 					hysteresis = <2000>;
 					type = "hot";
 				};
-				cluster0_crit: cluster0_crit {
+				cluster0_crit: cluster0-crit {
 					temperature = <110000>;
 					hysteresis = <2000>;
 					type = "critical";
@@ -6777,7 +6783,7 @@
 					hysteresis = <2000>;
 					type = "hot";
 				};
-				cluster1_crit: cluster1_crit {
+				cluster1_crit: cluster1-crit {
 					temperature = <110000>;
 					hysteresis = <2000>;
 					type = "critical";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8350.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8350.dtsi
@@ -41,7 +41,7 @@
 
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
-			clock-frequency = <32000>;
+			clock-frequency = <32764>;
 			#clock-cells = <0>;
 		};
 	};
@@ -1731,6 +1731,8 @@
 			clocks = <&rpmhcc RPMH_CXO_CLK>,
 				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
 
+			power-domains = <&gcc UFS_PHY_GDSC>;
+
 			resets = <&ufs_mem_hc 0>;
 			reset-names = "ufsphy";
 
@@ -1816,6 +1818,142 @@
 			reg = <0x0 0x1fc0000 0x0 0x30000>;
 		};
 
+		adsp: remoteproc@3000000 {
+			compatible = "qcom,sm8350-adsp-pas";
+			reg = <0x0 0x03000000 0x0 0x10000>;
+
+			interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog", "fatal", "ready",
+					  "handover", "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_LCX>,
+					<&rpmhpd RPMHPD_LMX>;
+			power-domain-names = "lcx", "lmx";
+
+			memory-region = <&pil_adsp_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_adsp_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_LPASS
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "lpass";
+				qcom,remote-pid = <2>;
+
+				apr {
+					compatible = "qcom,apr-v2";
+					qcom,glink-channels = "apr_audio_svc";
+					qcom,domain = <APR_DOMAIN_ADSP>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					service@3 {
+						reg = <APR_SVC_ADSP_CORE>;
+						compatible = "qcom,q6core";
+						qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
+					};
+
+					q6afe: service@4 {
+						compatible = "qcom,q6afe";
+						reg = <APR_SVC_AFE>;
+						qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
+
+						q6afedai: dais {
+							compatible = "qcom,q6afe-dais";
+							#address-cells = <1>;
+							#size-cells = <0>;
+							#sound-dai-cells = <1>;
+						};
+
+						q6afecc: clock-controller {
+							compatible = "qcom,q6afe-clocks";
+							#clock-cells = <2>;
+						};
+					};
+
+					q6asm: service@7 {
+						compatible = "qcom,q6asm";
+						reg = <APR_SVC_ASM>;
+						qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
+
+						q6asmdai: dais {
+							compatible = "qcom,q6asm-dais";
+							#address-cells = <1>;
+							#size-cells = <0>;
+							#sound-dai-cells = <1>;
+							iommus = <&apps_smmu 0x1801 0x0>;
+
+							dai@0 {
+								reg = <0>;
+							};
+
+							dai@1 {
+								reg = <1>;
+							};
+
+							dai@2 {
+								reg = <2>;
+							};
+						};
+					};
+
+					q6adm: service@8 {
+						compatible = "qcom,q6adm";
+						reg = <APR_SVC_ADM>;
+						qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
+
+						q6routing: routing {
+							compatible = "qcom,q6adm-routing";
+							#sound-dai-cells = <0>;
+						};
+					};
+				};
+
+				fastrpc {
+					compatible = "qcom,fastrpc";
+					qcom,glink-channels = "fastrpcglink-apps-dsp";
+					label = "adsp";
+					qcom,non-secure-domain;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					compute-cb@3 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <3>;
+						iommus = <&apps_smmu 0x1803 0x0>;
+					};
+
+					compute-cb@4 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <4>;
+						iommus = <&apps_smmu 0x1804 0x0>;
+					};
+
+					compute-cb@5 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <5>;
+						iommus = <&apps_smmu 0x1805 0x0>;
+					};
+				};
+			};
+		};
+
 		lpass_tlmm: pinctrl@33c0000 {
 			compatible = "qcom,sm8350-lpass-lpi-pinctrl";
 			reg = <0 0x033c0000 0 0x20000>,
@@ -2017,7 +2155,7 @@
 
 		mpss: remoteproc@4080000 {
 			compatible = "qcom,sm8350-mpss-pas";
-			reg = <0x0 0x04080000 0x0 0x4040>;
+			reg = <0x0 0x04080000 0x0 0x10000>;
 
 			interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>,
@@ -2289,6 +2427,115 @@
 			qcom,bcm-voters = <&apps_bcm_voter>;
 		};
 
+		cdsp: remoteproc@a300000 {
+			compatible = "qcom,sm8350-cdsp-pas";
+			reg = <0x0 0x0a300000 0x0 0x10000>;
+
+			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_cdsp_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog", "fatal", "ready",
+					  "handover", "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_CX>,
+					<&rpmhpd RPMHPD_MXC>;
+			power-domain-names = "cx", "mxc";
+
+			interconnects = <&compute_noc MASTER_CDSP_PROC 0 &mc_virt SLAVE_EBI1 0>;
+
+			memory-region = <&pil_cdsp_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_cdsp_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_CDSP
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "cdsp";
+				qcom,remote-pid = <5>;
+
+				fastrpc {
+					compatible = "qcom,fastrpc";
+					qcom,glink-channels = "fastrpcglink-apps-dsp";
+					label = "cdsp";
+					qcom,non-secure-domain;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					compute-cb@1 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <1>;
+						iommus = <&apps_smmu 0x2161 0x0400>,
+							 <&apps_smmu 0x1181 0x0420>;
+					};
+
+					compute-cb@2 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <2>;
+						iommus = <&apps_smmu 0x2162 0x0400>,
+							 <&apps_smmu 0x1182 0x0420>;
+					};
+
+					compute-cb@3 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <3>;
+						iommus = <&apps_smmu 0x2163 0x0400>,
+							 <&apps_smmu 0x1183 0x0420>;
+					};
+
+					compute-cb@4 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <4>;
+						iommus = <&apps_smmu 0x2164 0x0400>,
+							 <&apps_smmu 0x1184 0x0420>;
+					};
+
+					compute-cb@5 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <5>;
+						iommus = <&apps_smmu 0x2165 0x0400>,
+							 <&apps_smmu 0x1185 0x0420>;
+					};
+
+					compute-cb@6 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <6>;
+						iommus = <&apps_smmu 0x2166 0x0400>,
+							 <&apps_smmu 0x1186 0x0420>;
+					};
+
+					compute-cb@7 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <7>;
+						iommus = <&apps_smmu 0x2167 0x0400>,
+							 <&apps_smmu 0x1187 0x0420>;
+					};
+
+					compute-cb@8 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <8>;
+						iommus = <&apps_smmu 0x2168 0x0400>,
+							 <&apps_smmu 0x1188 0x0420>;
+					};
+
+					/* note: secure cb9 in downstream */
+				};
+			};
+		};
+
 		usb_1: usb@a6f8800 {
 			compatible = "qcom,sm8350-dwc3", "qcom,dwc3";
 			reg = <0 0x0a6f8800 0 0x400>;
@@ -2312,14 +2559,16 @@
 					  <&gcc GCC_USB30_PRIM_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <200000000>;
 
-			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 17 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
-					      <&pdc 14 IRQ_TYPE_EDGE_BOTH>;
-			interrupt-names = "hs_phy_irq",
-					  "ss_phy_irq",
+					      <&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
+					  "dp_hs_phy_irq",
 					  "dm_hs_phy_irq",
-					  "dp_hs_phy_irq";
+					  "ss_phy_irq";
 
 			power-domains = <&gcc USB30_PRIM_GDSC>;
 
@@ -2385,14 +2634,16 @@
 					  <&gcc GCC_USB30_SEC_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <200000000>;
 
-			interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 16 IRQ_TYPE_LEVEL_HIGH>,
+			interrupts-extended = <&intc GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 12 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 13 IRQ_TYPE_EDGE_BOTH>,
-					      <&pdc 12 IRQ_TYPE_EDGE_BOTH>;
-			interrupt-names = "hs_phy_irq",
-					  "ss_phy_irq",
+					      <&pdc 16 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
+					  "dp_hs_phy_irq",
 					  "dm_hs_phy_irq",
-					  "dp_hs_phy_irq";
+					  "ss_phy_irq";
 
 			power-domains = <&gcc USB30_SEC_GDSC>;
 
@@ -3194,142 +3445,6 @@
 				     <GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
-		adsp: remoteproc@17300000 {
-			compatible = "qcom,sm8350-adsp-pas";
-			reg = <0 0x17300000 0 0x100>;
-
-			interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
-			interrupt-names = "wdog", "fatal", "ready",
-					  "handover", "stop-ack";
-
-			clocks = <&rpmhcc RPMH_CXO_CLK>;
-			clock-names = "xo";
-
-			power-domains = <&rpmhpd RPMHPD_LCX>,
-					<&rpmhpd RPMHPD_LMX>;
-			power-domain-names = "lcx", "lmx";
-
-			memory-region = <&pil_adsp_mem>;
-
-			qcom,qmp = <&aoss_qmp>;
-
-			qcom,smem-states = <&smp2p_adsp_out 0>;
-			qcom,smem-state-names = "stop";
-
-			status = "disabled";
-
-			glink-edge {
-				interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
-							     IPCC_MPROC_SIGNAL_GLINK_QMP
-							     IRQ_TYPE_EDGE_RISING>;
-				mboxes = <&ipcc IPCC_CLIENT_LPASS
-						IPCC_MPROC_SIGNAL_GLINK_QMP>;
-
-				label = "lpass";
-				qcom,remote-pid = <2>;
-
-				apr {
-					compatible = "qcom,apr-v2";
-					qcom,glink-channels = "apr_audio_svc";
-					qcom,domain = <APR_DOMAIN_ADSP>;
-					#address-cells = <1>;
-					#size-cells = <0>;
-
-					service@3 {
-						reg = <APR_SVC_ADSP_CORE>;
-						compatible = "qcom,q6core";
-						qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
-					};
-
-					q6afe: service@4 {
-						compatible = "qcom,q6afe";
-						reg = <APR_SVC_AFE>;
-						qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
-
-						q6afedai: dais {
-							compatible = "qcom,q6afe-dais";
-							#address-cells = <1>;
-							#size-cells = <0>;
-							#sound-dai-cells = <1>;
-						};
-
-						q6afecc: clock-controller {
-							compatible = "qcom,q6afe-clocks";
-							#clock-cells = <2>;
-						};
-					};
-
-					q6asm: service@7 {
-						compatible = "qcom,q6asm";
-						reg = <APR_SVC_ASM>;
-						qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
-
-						q6asmdai: dais {
-							compatible = "qcom,q6asm-dais";
-							#address-cells = <1>;
-							#size-cells = <0>;
-							#sound-dai-cells = <1>;
-							iommus = <&apps_smmu 0x1801 0x0>;
-
-							dai@0 {
-								reg = <0>;
-							};
-
-							dai@1 {
-								reg = <1>;
-							};
-
-							dai@2 {
-								reg = <2>;
-							};
-						};
-					};
-
-					q6adm: service@8 {
-						compatible = "qcom,q6adm";
-						reg = <APR_SVC_ADM>;
-						qcom,protection-domain = "avs/audio", "msm/adsp/audio_pd";
-
-						q6routing: routing {
-							compatible = "qcom,q6adm-routing";
-							#sound-dai-cells = <0>;
-						};
-					};
-				};
-
-				fastrpc {
-					compatible = "qcom,fastrpc";
-					qcom,glink-channels = "fastrpcglink-apps-dsp";
-					label = "adsp";
-					qcom,non-secure-domain;
-					#address-cells = <1>;
-					#size-cells = <0>;
-
-					compute-cb@3 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <3>;
-						iommus = <&apps_smmu 0x1803 0x0>;
-					};
-
-					compute-cb@4 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <4>;
-						iommus = <&apps_smmu 0x1804 0x0>;
-					};
-
-					compute-cb@5 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <5>;
-						iommus = <&apps_smmu 0x1805 0x0>;
-					};
-				};
-			};
-		};
-
 		intc: interrupt-controller@17a00000 {
 			compatible = "arm,gic-v3";
 			#interrupt-cells = <3>;
@@ -3498,115 +3613,6 @@
 			#freq-domain-cells = <1>;
 			#clock-cells = <1>;
 		};
-
-		cdsp: remoteproc@98900000 {
-			compatible = "qcom,sm8350-cdsp-pas";
-			reg = <0 0x98900000 0 0x1400000>;
-
-			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_cdsp_in 3 IRQ_TYPE_EDGE_RISING>;
-			interrupt-names = "wdog", "fatal", "ready",
-					  "handover", "stop-ack";
-
-			clocks = <&rpmhcc RPMH_CXO_CLK>;
-			clock-names = "xo";
-
-			power-domains = <&rpmhpd RPMHPD_CX>,
-					<&rpmhpd RPMHPD_MXC>;
-			power-domain-names = "cx", "mxc";
-
-			interconnects = <&compute_noc MASTER_CDSP_PROC 0 &mc_virt SLAVE_EBI1 0>;
-
-			memory-region = <&pil_cdsp_mem>;
-
-			qcom,qmp = <&aoss_qmp>;
-
-			qcom,smem-states = <&smp2p_cdsp_out 0>;
-			qcom,smem-state-names = "stop";
-
-			status = "disabled";
-
-			glink-edge {
-				interrupts-extended = <&ipcc IPCC_CLIENT_CDSP
-							     IPCC_MPROC_SIGNAL_GLINK_QMP
-							     IRQ_TYPE_EDGE_RISING>;
-				mboxes = <&ipcc IPCC_CLIENT_CDSP
-						IPCC_MPROC_SIGNAL_GLINK_QMP>;
-
-				label = "cdsp";
-				qcom,remote-pid = <5>;
-
-				fastrpc {
-					compatible = "qcom,fastrpc";
-					qcom,glink-channels = "fastrpcglink-apps-dsp";
-					label = "cdsp";
-					qcom,non-secure-domain;
-					#address-cells = <1>;
-					#size-cells = <0>;
-
-					compute-cb@1 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <1>;
-						iommus = <&apps_smmu 0x2161 0x0400>,
-							 <&apps_smmu 0x1181 0x0420>;
-					};
-
-					compute-cb@2 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <2>;
-						iommus = <&apps_smmu 0x2162 0x0400>,
-							 <&apps_smmu 0x1182 0x0420>;
-					};
-
-					compute-cb@3 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <3>;
-						iommus = <&apps_smmu 0x2163 0x0400>,
-							 <&apps_smmu 0x1183 0x0420>;
-					};
-
-					compute-cb@4 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <4>;
-						iommus = <&apps_smmu 0x2164 0x0400>,
-							 <&apps_smmu 0x1184 0x0420>;
-					};
-
-					compute-cb@5 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <5>;
-						iommus = <&apps_smmu 0x2165 0x0400>,
-							 <&apps_smmu 0x1185 0x0420>;
-					};
-
-					compute-cb@6 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <6>;
-						iommus = <&apps_smmu 0x2166 0x0400>,
-							 <&apps_smmu 0x1186 0x0420>;
-					};
-
-					compute-cb@7 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <7>;
-						iommus = <&apps_smmu 0x2167 0x0400>,
-							 <&apps_smmu 0x1187 0x0420>;
-					};
-
-					compute-cb@8 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <8>;
-						iommus = <&apps_smmu 0x2168 0x0400>,
-							 <&apps_smmu 0x1188 0x0420>;
-					};
-
-					/* note: secure cb9 in downstream */
-				};
-			};
-		};
 	};
 
 	thermal_zones: thermal-zones {
@@ -4165,7 +4171,7 @@
 					hysteresis = <2000>;
 					type = "hot";
 				};
-				cluster0_crit: cluster0_crit {
+				cluster0_crit: cluster0-crit {
 					temperature = <110000>;
 					hysteresis = <2000>;
 					type = "critical";
@@ -4185,7 +4191,7 @@
 					hysteresis = <2000>;
 					type = "hot";
 				};
-				cluster1_crit: cluster1_crit {
+				cluster1_crit: cluster1-crit {
 					temperature = <110000>;
 					hysteresis = <2000>;
 					type = "critical";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8450-hdk.dts
@@ -938,8 +938,8 @@
 			"TX DMIC3", "MIC BIAS1",
 			"TX SWR_INPUT0", "ADC1_OUTPUT",
 			"TX SWR_INPUT1", "ADC2_OUTPUT",
-			"TX SWR_INPUT2", "ADC3_OUTPUT",
-			"TX SWR_INPUT3", "ADC4_OUTPUT";
+			"TX SWR_INPUT0", "ADC3_OUTPUT",
+			"TX SWR_INPUT1", "ADC4_OUTPUT";
 
 	wcd-playback-dai-link {
 		link-name = "WCD Playback";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8450.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8450.dtsi
@@ -43,7 +43,7 @@
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
 			#clock-cells = <0>;
-			clock-frequency = <32000>;
+			clock-frequency = <32764>;
 		};
 	};
 
@@ -1028,6 +1028,12 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&qup_uart20_default>;
 				interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
 				status = "disabled";
 			};
 
@@ -1420,6 +1426,12 @@
 				pinctrl-names = "default";
 				pinctrl-0 = <&qup_uart7_tx>, <&qup_uart7_rx>;
 				interrupts = <GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>;
+				interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS
+						 &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>,
+						<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+						 &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>;
+				interconnect-names = "qup-core",
+						     "qup-config";
 				status = "disabled";
 			};
 		};
@@ -1765,12 +1777,8 @@
 			ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x100000>,
 				 <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x3d00000>;
 
-			/*
-			 * MSIs for BDF (1:0.0) only works with Device ID 0x5980.
-			 * Hence, the IDs are swapped.
-			 */
-			msi-map = <0x0 &gic_its 0x5981 0x1>,
-				  <0x100 &gic_its 0x5980 0x1>;
+			msi-map = <0x0 &gic_its 0x5980 0x1>,
+				  <0x100 &gic_its 0x5981 0x1>;
 			msi-map-mask = <0xff00>;
 			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "msi";
@@ -1874,12 +1882,8 @@
 			ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>,
 				 <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x1fd00000>;
 
-			/*
-			 * MSIs for BDF (1:0.0) only works with Device ID 0x5a00.
-			 * Hence, the IDs are swapped.
-			 */
-			msi-map = <0x0 &gic_its 0x5a01 0x1>,
-				  <0x100 &gic_its 0x5a00 0x1>;
+			msi-map = <0x0 &gic_its 0x5a00 0x1>,
+				  <0x100 &gic_its 0x5a01 0x1>;
 			msi-map-mask = <0xff00>;
 			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "msi";
@@ -2322,6 +2326,7 @@
 					compatible = "qcom,fastrpc";
 					qcom,glink-channels = "fastrpcglink-apps-dsp";
 					label = "sdsp";
+					qcom,non-secure-domain;
 					#address-cells = <1>;
 					#size-cells = <0>;
 
@@ -2347,6 +2352,112 @@
 			};
 		};
 
+		remoteproc_adsp: remoteproc@3000000 {
+			compatible = "qcom,sm8450-adsp-pas";
+			reg = <0x0 0x03000000 0x0 0x10000>;
+
+			interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog", "fatal", "ready",
+					  "handover", "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_LCX>,
+					<&rpmhpd RPMHPD_LMX>;
+			power-domain-names = "lcx", "lmx";
+
+			memory-region = <&adsp_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_adsp_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			remoteproc_adsp_glink: glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_LPASS
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "lpass";
+				qcom,remote-pid = <2>;
+
+				gpr {
+					compatible = "qcom,gpr";
+					qcom,glink-channels = "adsp_apps";
+					qcom,domain = <GPR_DOMAIN_ID_ADSP>;
+					qcom,intents = <512 20>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					q6apm: service@1 {
+						compatible = "qcom,q6apm";
+						reg = <GPR_APM_MODULE_IID>;
+						#sound-dai-cells = <0>;
+						qcom,protection-domain = "avs/audio",
+									 "msm/adsp/audio_pd";
+
+						q6apmdai: dais {
+							compatible = "qcom,q6apm-dais";
+							iommus = <&apps_smmu 0x1801 0x0>;
+						};
+
+						q6apmbedai: bedais {
+							compatible = "qcom,q6apm-lpass-dais";
+							#sound-dai-cells = <1>;
+						};
+					};
+
+					q6prm: service@2 {
+						compatible = "qcom,q6prm";
+						reg = <GPR_PRM_MODULE_IID>;
+						qcom,protection-domain = "avs/audio",
+									 "msm/adsp/audio_pd";
+
+						q6prmcc: clock-controller {
+							compatible = "qcom,q6prm-lpass-clocks";
+							#clock-cells = <2>;
+						};
+					};
+				};
+
+				fastrpc {
+					compatible = "qcom,fastrpc";
+					qcom,glink-channels = "fastrpcglink-apps-dsp";
+					label = "adsp";
+					qcom,non-secure-domain;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					compute-cb@3 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <3>;
+						iommus = <&apps_smmu 0x1803 0x0>;
+					};
+
+					compute-cb@4 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <4>;
+						iommus = <&apps_smmu 0x1804 0x0>;
+					};
+
+					compute-cb@5 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <5>;
+						iommus = <&apps_smmu 0x1805 0x0>;
+					};
+				};
+			};
+		};
+
 		wsa2macro: codec@31e0000 {
 			compatible = "qcom,sm8450-lpass-wsa-macro";
 			reg = <0 0x031e0000 0 0x1000>;
@@ -2543,114 +2654,9 @@
 			status = "disabled";
 		};
 
-		remoteproc_adsp: remoteproc@30000000 {
-			compatible = "qcom,sm8450-adsp-pas";
-			reg = <0 0x30000000 0 0x100>;
-
-			interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
-			interrupt-names = "wdog", "fatal", "ready",
-					  "handover", "stop-ack";
-
-			clocks = <&rpmhcc RPMH_CXO_CLK>;
-			clock-names = "xo";
-
-			power-domains = <&rpmhpd RPMHPD_LCX>,
-					<&rpmhpd RPMHPD_LMX>;
-			power-domain-names = "lcx", "lmx";
-
-			memory-region = <&adsp_mem>;
-
-			qcom,qmp = <&aoss_qmp>;
-
-			qcom,smem-states = <&smp2p_adsp_out 0>;
-			qcom,smem-state-names = "stop";
-
-			status = "disabled";
-
-			remoteproc_adsp_glink: glink-edge {
-				interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
-							     IPCC_MPROC_SIGNAL_GLINK_QMP
-							     IRQ_TYPE_EDGE_RISING>;
-				mboxes = <&ipcc IPCC_CLIENT_LPASS
-						IPCC_MPROC_SIGNAL_GLINK_QMP>;
-
-				label = "lpass";
-				qcom,remote-pid = <2>;
-
-				gpr {
-					compatible = "qcom,gpr";
-					qcom,glink-channels = "adsp_apps";
-					qcom,domain = <GPR_DOMAIN_ID_ADSP>;
-					qcom,intents = <512 20>;
-					#address-cells = <1>;
-					#size-cells = <0>;
-
-					q6apm: service@1 {
-						compatible = "qcom,q6apm";
-						reg = <GPR_APM_MODULE_IID>;
-						#sound-dai-cells = <0>;
-						qcom,protection-domain = "avs/audio",
-									 "msm/adsp/audio_pd";
-
-						q6apmdai: dais {
-							compatible = "qcom,q6apm-dais";
-							iommus = <&apps_smmu 0x1801 0x0>;
-						};
-
-						q6apmbedai: bedais {
-							compatible = "qcom,q6apm-lpass-dais";
-							#sound-dai-cells = <1>;
-						};
-					};
-
-					q6prm: service@2 {
-						compatible = "qcom,q6prm";
-						reg = <GPR_PRM_MODULE_IID>;
-						qcom,protection-domain = "avs/audio",
-									 "msm/adsp/audio_pd";
-
-						q6prmcc: clock-controller {
-							compatible = "qcom,q6prm-lpass-clocks";
-							#clock-cells = <2>;
-						};
-					};
-				};
-
-				fastrpc {
-					compatible = "qcom,fastrpc";
-					qcom,glink-channels = "fastrpcglink-apps-dsp";
-					label = "adsp";
-					#address-cells = <1>;
-					#size-cells = <0>;
-
-					compute-cb@3 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <3>;
-						iommus = <&apps_smmu 0x1803 0x0>;
-					};
-
-					compute-cb@4 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <4>;
-						iommus = <&apps_smmu 0x1804 0x0>;
-					};
-
-					compute-cb@5 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <5>;
-						iommus = <&apps_smmu 0x1805 0x0>;
-					};
-				};
-			};
-		};
-
 		remoteproc_cdsp: remoteproc@32300000 {
 			compatible = "qcom,sm8450-cdsp-pas";
-			reg = <0 0x32300000 0 0x1400000>;
+			reg = <0 0x32300000 0 0x10000>;
 
 			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
@@ -2690,6 +2696,7 @@
 					compatible = "qcom,fastrpc";
 					qcom,glink-channels = "fastrpcglink-apps-dsp";
 					label = "cdsp";
+					qcom,non-secure-domain;
 					#address-cells = <1>;
 					#size-cells = <0>;
 
@@ -2756,7 +2763,7 @@
 
 		remoteproc_mpss: remoteproc@4080000 {
 			compatible = "qcom,sm8450-mpss-pas";
-			reg = <0x0 0x04080000 0x0 0x4040>;
+			reg = <0x0 0x04080000 0x0 0x10000>;
 
 			interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>,
@@ -4373,6 +4380,8 @@
 				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
 				 <&gcc GCC_UFS_0_CLKREF_EN>;
 
+			power-domains = <&gcc UFS_PHY_GDSC>;
+
 			resets = <&ufs_mem_hc 0>;
 			reset-names = "ufsphy";
 
@@ -4485,13 +4494,15 @@
 			assigned-clock-rates = <19200000>, <200000000>;
 
 			interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 17 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
-					      <&pdc 14 IRQ_TYPE_EDGE_BOTH>;
-			interrupt-names = "hs_phy_irq",
-					  "ss_phy_irq",
+					      <&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
+					  "dp_hs_phy_irq",
 					  "dm_hs_phy_irq",
-					  "dp_hs_phy_irq";
+					  "ss_phy_irq";
 
 			power-domains = <&gcc USB30_PRIM_GDSC>;
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
@@ -56,6 +56,10 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	iris {
+		status = "okay";
+	};
+
 	pmic-glink {
 		compatible = "qcom,sm8550-pmic-glink", "qcom,pmic-glink";
 		#address-cells = <1>;
@@ -823,7 +827,7 @@
 };
 
 &sleep_clk {
-	clock-frequency = <32000>;
+	clock-frequency = <32764>;
 };
 
 &swr0 {
@@ -874,7 +878,7 @@
 	wcd_tx: codec@0,3 {
 		compatible = "sdw20217010d00";
 		reg = <0 3>;
-		qcom,tx-port-mapping = <1 1 2 3>;
+		qcom,tx-port-mapping = <2 2 3 4>;
 	};
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
@@ -927,7 +927,7 @@
 };
 
 &sleep_clk {
-	clock-frequency = <32000>;
+	clock-frequency = <32764>;
 };
 
 &swr0 {
@@ -978,7 +978,7 @@
 	wcd_tx: codec@0,3 {
 		compatible = "sdw20217010d00";
 		reg = <0 3>;
-		qcom,tx-port-mapping = <1 1 2 3>;
+		qcom,tx-port-mapping = <2 2 3 4>;
 	};
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8550.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8550.dtsi
@@ -6,22 +6,23 @@
 #include <dt-bindings/clock/qcom,rpmh.h>
 #include <dt-bindings/clock/qcom,sm8450-videocc.h>
 #include <dt-bindings/clock/qcom,sm8550-camcc.h>
+#include <dt-bindings/clock/qcom,sm8550-dispcc.h>
 #include <dt-bindings/clock/qcom,sm8550-gcc.h>
 #include <dt-bindings/clock/qcom,sm8550-gpucc.h>
 #include <dt-bindings/clock/qcom,sm8550-tcsr.h>
-#include <dt-bindings/clock/qcom,sm8550-dispcc.h>
 #include <dt-bindings/dma/qcom-gpi.h>
 #include <dt-bindings/firmware/qcom,scm.h>
 #include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
 #include <dt-bindings/interconnect/qcom,sm8550-rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/mailbox/qcom-ipcc.h>
-#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/phy/phy-qcom-qmp.h>
 #include <dt-bindings/power/qcom,rpmhpd.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
 #include <dt-bindings/soc/qcom,gpr.h>
 #include <dt-bindings/soc/qcom,rpmh-rsc.h>
 #include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
-#include <dt-bindings/phy/phy-qcom-qmp.h>
 #include <dt-bindings/thermal/thermal.h>
 
 / {
@@ -1713,8 +1714,22 @@
 			linux,pci-domain = <0>;
 			num-lanes = <2>;
 
-			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "msi";
+			interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi0",
+					  "msi1",
+					  "msi2",
+					  "msi3",
+					  "msi4",
+					  "msi5",
+					  "msi6",
+					  "msi7";
 
 			#interrupt-cells = <1>;
 			interrupt-map-mask = <0 0 0 0x7>;
@@ -1804,8 +1819,22 @@
 			linux,pci-domain = <1>;
 			num-lanes = <2>;
 
-			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "msi";
+			interrupts = <GIC_SPI 307 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 308 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 309 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 312 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 313 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "msi0",
+					  "msi1",
+					  "msi2",
+					  "msi3",
+					  "msi4",
+					  "msi5",
+					  "msi6",
+					  "msi7";
 
 			#interrupt-cells = <1>;
 			interrupt-map-mask = <0 0 0 0x7>;
@@ -1977,7 +2006,8 @@
 		ice: crypto@1d88000 {
 			compatible = "qcom,sm8550-inline-crypto-engine",
 				     "qcom,inline-crypto-engine";
-			reg = <0 0x01d88000 0 0x8000>;
+			reg = <0x0 0x01d88000 0x0 0x10000>;
+			qcom,ice-use-hwkm;
 			clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>;
 		};
 
@@ -2213,7 +2243,7 @@
 
 		remoteproc_mpss: remoteproc@4080000 {
 			compatible = "qcom,sm8550-mpss-pas";
-			reg = <0x0 0x04080000 0x0 0x4040>;
+			reg = <0x0 0x04080000 0x0 0x10000>;
 
 			interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>,
@@ -2253,6 +2283,137 @@
 			};
 		};
 
+		remoteproc_adsp: remoteproc@6800000 {
+			compatible = "qcom,sm8550-adsp-pas";
+			reg = <0x0 0x06800000 0x0 0x10000>;
+
+			interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
+					      <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "wdog", "fatal", "ready",
+					  "handover", "stop-ack";
+
+			clocks = <&rpmhcc RPMH_CXO_CLK>;
+			clock-names = "xo";
+
+			power-domains = <&rpmhpd RPMHPD_LCX>,
+					<&rpmhpd RPMHPD_LMX>;
+			power-domain-names = "lcx", "lmx";
+
+			interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC 0 &mc_virt SLAVE_EBI1 0>;
+
+			memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>;
+
+			qcom,qmp = <&aoss_qmp>;
+
+			qcom,smem-states = <&smp2p_adsp_out 0>;
+			qcom,smem-state-names = "stop";
+
+			status = "disabled";
+
+			remoteproc_adsp_glink: glink-edge {
+				interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
+							     IPCC_MPROC_SIGNAL_GLINK_QMP
+							     IRQ_TYPE_EDGE_RISING>;
+				mboxes = <&ipcc IPCC_CLIENT_LPASS
+						IPCC_MPROC_SIGNAL_GLINK_QMP>;
+
+				label = "lpass";
+				qcom,remote-pid = <2>;
+
+				fastrpc {
+					compatible = "qcom,fastrpc";
+					qcom,glink-channels = "fastrpcglink-apps-dsp";
+					label = "adsp";
+					qcom,non-secure-domain;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					compute-cb@3 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <3>;
+						iommus = <&apps_smmu 0x1003 0x80>,
+							 <&apps_smmu 0x1063 0x0>;
+						dma-coherent;
+					};
+
+					compute-cb@4 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <4>;
+						iommus = <&apps_smmu 0x1004 0x80>,
+							 <&apps_smmu 0x1064 0x0>;
+						dma-coherent;
+					};
+
+					compute-cb@5 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <5>;
+						iommus = <&apps_smmu 0x1005 0x80>,
+							 <&apps_smmu 0x1065 0x0>;
+						dma-coherent;
+					};
+
+					compute-cb@6 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <6>;
+						iommus = <&apps_smmu 0x1006 0x80>,
+							 <&apps_smmu 0x1066 0x0>;
+						dma-coherent;
+					};
+
+					compute-cb@7 {
+						compatible = "qcom,fastrpc-compute-cb";
+						reg = <7>;
+						iommus = <&apps_smmu 0x1007 0x80>,
+							 <&apps_smmu 0x1067 0x0>;
+						dma-coherent;
+					};
+				};
+
+				gpr {
+					compatible = "qcom,gpr";
+					qcom,glink-channels = "adsp_apps";
+					qcom,domain = <GPR_DOMAIN_ID_ADSP>;
+					qcom,intents = <512 20>;
+					#address-cells = <1>;
+					#size-cells = <0>;
+
+					q6apm: service@1 {
+						compatible = "qcom,q6apm";
+						reg = <GPR_APM_MODULE_IID>;
+						#sound-dai-cells = <0>;
+						qcom,protection-domain = "avs/audio",
+									 "msm/adsp/audio_pd";
+
+						q6apmdai: dais {
+							compatible = "qcom,q6apm-dais";
+							iommus = <&apps_smmu 0x1001 0x80>,
+								 <&apps_smmu 0x1061 0x0>;
+						};
+
+						q6apmbedai: bedais {
+							compatible = "qcom,q6apm-lpass-dais";
+							#sound-dai-cells = <1>;
+						};
+					};
+
+					q6prm: service@2 {
+						compatible = "qcom,q6prm";
+						reg = <GPR_PRM_MODULE_IID>;
+						qcom,protection-domain = "avs/audio",
+									 "msm/adsp/audio_pd";
+
+						q6prmcc: clock-controller {
+							compatible = "qcom,q6prm-lpass-clocks";
+							#clock-cells = <2>;
+						};
+					};
+				};
+			};
+		};
+
 		lpass_wsa2macro: codec@6aa0000 {
 			compatible = "qcom,sm8550-lpass-wsa-macro";
 			reg = <0 0x06aa0000 0 0x1000>;
@@ -2399,6 +2560,31 @@
 			status = "disabled";
 		};
 
+		slimbam: dma-controller@6c04000 {
+			compatible = "qcom,bam-v1.7.0";
+			reg = <0x0 0x6c04000 0x0 0x20000>, <0x0 0x6c8b000 0x0 0x1000>;
+			reg-names = "bam", "bam_remote_mem";
+			interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			qcom,controlled-remotely;
+			num-channels  = <31>;
+			qcom,ee = <1>;
+			qcom,num-ees = <2>;
+			status = "disabled";
+		};
+
+		slim: slim-ngd@6c40000 {
+			compatible = "qcom,slim-ngd-v1.5.0";
+			reg = <0x0 0x6c40000 0x0 0x2c000>, <0x0 0x6c8a000 0x0 0x1000>;
+			reg-names = "ctrl", "slimbus_remote_mem";
+			interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>;
+			dmas = <&slimbam 3>, <&slimbam 4>;
+			dma-names = "rx", "tx";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		swr2: soundwire@6d30000 {
 			compatible = "qcom,soundwire-v2.0.0";
 			reg = <0 0x06d30000 0 0x10000>;
@@ -2635,6 +2821,79 @@
 			};
 		};
 
+		iris: video-codec@aa00000 {
+			compatible = "qcom,sm8550-iris";
+
+			reg = <0 0x0aa00000 0 0xf0000>;
+			interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+
+			power-domains = <&videocc VIDEO_CC_MVS0C_GDSC>,
+					<&videocc VIDEO_CC_MVS0_GDSC>,
+					<&rpmhpd RPMHPD_MXC>,
+					<&rpmhpd RPMHPD_MMCX>;
+			power-domain-names = "iris-ctl", "vcodec", "mxc", "mmcx";
+			operating-points-v2 = <&iris_opp_table>;
+
+			clocks = <&gcc GCC_VIDEO_AXI0_CLK>,
+				 <&videocc VIDEO_CC_MVS0C_CLK>,
+				 <&videocc VIDEO_CC_MVS0_CLK>;
+			clock-names = "gcc_video_axi0", "core_clk", "vcodec_core";
+
+			interconnects =
+				<&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS
+				 &config_noc SLAVE_VENUS_CFG QCOM_ICC_TAG_ALWAYS>,
+				<&mmss_noc MASTER_VIDEO QCOM_ICC_TAG_ALWAYS
+				 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
+			interconnect-names = "iris-cnoc", "iris-ddr";
+
+			/* FW load region */
+			memory-region = <&video_mem>;
+
+			resets = <&gcc GCC_VIDEO_AXI0_CLK_ARES>;
+			reset-names = "video_axi_reset";
+
+			iommus = <&apps_smmu 0x1940 0x0000>,
+				 <&apps_smmu 0x1947 0x0000>;
+			dma-coherent;
+
+			status = "disabled";
+
+			iris_opp_table: opp-table {
+				compatible = "operating-points-v2";
+
+				opp-240000000 {
+					opp-hz = /bits/ 64 <240000000>;
+					required-opps = <&rpmhpd_opp_svs>,
+							<&rpmhpd_opp_low_svs>;
+				};
+
+				opp-338000000 {
+					opp-hz = /bits/ 64 <338000000>;
+					required-opps = <&rpmhpd_opp_svs>,
+							<&rpmhpd_opp_svs>;
+				};
+
+				opp-366000000 {
+					opp-hz = /bits/ 64 <366000000>;
+					required-opps = <&rpmhpd_opp_svs_l1>,
+							<&rpmhpd_opp_svs_l1>;
+				};
+
+				opp-444000000 {
+					opp-hz = /bits/ 64 <444000000>;
+					required-opps = <&rpmhpd_opp_turbo>,
+							<&rpmhpd_opp_turbo>;
+				};
+
+				opp-533333334 {
+					opp-hz = /bits/ 64 <533333334>;
+					required-opps = <&rpmhpd_opp_turbo_l1>,
+							<&rpmhpd_opp_turbo_l1>;
+				};
+
+			};
+		};
+
 		videocc: clock-controller@aaf0000 {
 			compatible = "qcom,sm8550-videocc";
 			reg = <0 0x0aaf0000 0 0x10000>;
@@ -2679,9 +2938,8 @@
 
 			power-domains = <&dispcc MDSS_GDSC>;
 
-			interconnects = <&mmss_noc MASTER_MDP 0 &gem_noc SLAVE_LLCC 0>,
-					<&mc_virt MASTER_LLCC 0 &mc_virt SLAVE_EBI1 0>;
-			interconnect-names = "mdp0-mem", "mdp1-mem";
+			interconnects = <&mmss_noc MASTER_MDP 0 &mc_virt SLAVE_EBI1 0>;
+			interconnect-names = "mdp0-mem";
 
 			iommus = <&apps_smmu 0x1c00 0x2>;
 
@@ -3133,13 +3391,15 @@
 			assigned-clock-rates = <19200000>, <200000000>;
 
 			interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 17 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
-					      <&pdc 14 IRQ_TYPE_EDGE_BOTH>;
-			interrupt-names = "hs_phy_irq",
-					  "ss_phy_irq",
+					      <&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "pwr_event",
+					  "hs_phy_irq",
+					  "dp_hs_phy_irq",
 					  "dm_hs_phy_irq",
-					  "dp_hs_phy_irq";
+					  "ss_phy_irq";
 
 			power-domains = <&gcc USB30_PRIM_GDSC>;
 			required-opps = <&rpmhpd_opp_nom>;
@@ -3248,7 +3508,7 @@
 		spmi_bus: spmi@c400000 {
 			compatible = "qcom,spmi-pmic-arb";
 			reg = <0 0x0c400000 0 0x3000>,
-			      <0 0x0c500000 0 0x4000000>,
+			      <0 0x0c500000 0 0x400000>,
 			      <0 0x0c440000 0 0x80000>,
 			      <0 0x0c4c0000 0 0x20000>,
 			      <0 0x0c42d000 0 0x4000>;
@@ -4202,131 +4462,6 @@
 			interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
-		remoteproc_adsp: remoteproc@30000000 {
-			compatible = "qcom,sm8550-adsp-pas";
-			reg = <0x0 0x30000000 0x0 0x100>;
-
-			interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
-					      <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
-			interrupt-names = "wdog", "fatal", "ready",
-					  "handover", "stop-ack";
-
-			clocks = <&rpmhcc RPMH_CXO_CLK>;
-			clock-names = "xo";
-
-			power-domains = <&rpmhpd RPMHPD_LCX>,
-					<&rpmhpd RPMHPD_LMX>;
-			power-domain-names = "lcx", "lmx";
-
-			interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC 0 &mc_virt SLAVE_EBI1 0>;
-
-			memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>;
-
-			qcom,qmp = <&aoss_qmp>;
-
-			qcom,smem-states = <&smp2p_adsp_out 0>;
-			qcom,smem-state-names = "stop";
-
-			status = "disabled";
-
-			remoteproc_adsp_glink: glink-edge {
-				interrupts-extended = <&ipcc IPCC_CLIENT_LPASS
-							     IPCC_MPROC_SIGNAL_GLINK_QMP
-							     IRQ_TYPE_EDGE_RISING>;
-				mboxes = <&ipcc IPCC_CLIENT_LPASS
-						IPCC_MPROC_SIGNAL_GLINK_QMP>;
-
-				label = "lpass";
-				qcom,remote-pid = <2>;
-
-				fastrpc {
-					compatible = "qcom,fastrpc";
-					qcom,glink-channels = "fastrpcglink-apps-dsp";
-					label = "adsp";
-					#address-cells = <1>;
-					#size-cells = <0>;
-
-					compute-cb@3 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <3>;
-						iommus = <&apps_smmu 0x1003 0x80>,
-							 <&apps_smmu 0x1063 0x0>;
-					};
-
-					compute-cb@4 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <4>;
-						iommus = <&apps_smmu 0x1004 0x80>,
-							 <&apps_smmu 0x1064 0x0>;
-					};
-
-					compute-cb@5 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <5>;
-						iommus = <&apps_smmu 0x1005 0x80>,
-							 <&apps_smmu 0x1065 0x0>;
-					};
-
-					compute-cb@6 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <6>;
-						iommus = <&apps_smmu 0x1006 0x80>,
-							 <&apps_smmu 0x1066 0x0>;
-					};
-
-					compute-cb@7 {
-						compatible = "qcom,fastrpc-compute-cb";
-						reg = <7>;
-						iommus = <&apps_smmu 0x1007 0x80>,
-							 <&apps_smmu 0x1067 0x0>;
-					};
-				};
-
-				gpr {
-					compatible = "qcom,gpr";
-					qcom,glink-channels = "adsp_apps";
-					qcom,domain = <GPR_DOMAIN_ID_ADSP>;
-					qcom,intents = <512 20>;
-					#address-cells = <1>;
-					#size-cells = <0>;
-
-					q6apm: service@1 {
-						compatible = "qcom,q6apm";
-						reg = <GPR_APM_MODULE_IID>;
-						#sound-dai-cells = <0>;
-						qcom,protection-domain = "avs/audio",
-									 "msm/adsp/audio_pd";
-
-						q6apmdai: dais {
-							compatible = "qcom,q6apm-dais";
-							iommus = <&apps_smmu 0x1001 0x80>,
-								 <&apps_smmu 0x1061 0x0>;
-						};
-
-						q6apmbedai: bedais {
-							compatible = "qcom,q6apm-lpass-dais";
-							#sound-dai-cells = <1>;
-						};
-					};
-
-					q6prm: service@2 {
-						compatible = "qcom,q6prm";
-						reg = <GPR_PRM_MODULE_IID>;
-						qcom,protection-domain = "avs/audio",
-									 "msm/adsp/audio_pd";
-
-						q6prmcc: clock-controller {
-							compatible = "qcom,q6prm-lpass-clocks";
-							#clock-cells = <2>;
-						};
-					};
-				};
-			};
-		};
-
 		nsp_noc: interconnect@320c0000 {
 			compatible = "qcom,sm8550-nsp-noc";
 			reg = <0 0x320c0000 0 0xe080>;
@@ -4336,7 +4471,7 @@
 
 		remoteproc_cdsp: remoteproc@32300000 {
 			compatible = "qcom,sm8550-cdsp-pas";
-			reg = <0x0 0x32300000 0x0 0x1400000>;
+			reg = <0x0 0x32300000 0x0 0x10000>;
 
 			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
@@ -4379,6 +4514,7 @@
 					compatible = "qcom,fastrpc";
 					qcom,glink-channels = "fastrpcglink-apps-dsp";
 					label = "cdsp";
+					qcom,non-secure-domain;
 					#address-cells = <1>;
 					#size-cells = <0>;
 
@@ -4388,6 +4524,7 @@
 						iommus = <&apps_smmu 0x1961 0x0>,
 							 <&apps_smmu 0x0c01 0x20>,
 							 <&apps_smmu 0x19c1 0x10>;
+						dma-coherent;
 					};
 
 					compute-cb@2 {
@@ -4396,6 +4533,7 @@
 						iommus = <&apps_smmu 0x1962 0x0>,
 							 <&apps_smmu 0x0c02 0x20>,
 							 <&apps_smmu 0x19c2 0x10>;
+						dma-coherent;
 					};
 
 					compute-cb@3 {
@@ -4404,6 +4542,7 @@
 						iommus = <&apps_smmu 0x1963 0x0>,
 							 <&apps_smmu 0x0c03 0x20>,
 							 <&apps_smmu 0x19c3 0x10>;
+						dma-coherent;
 					};
 
 					compute-cb@4 {
@@ -4412,6 +4551,7 @@
 						iommus = <&apps_smmu 0x1964 0x0>,
 							 <&apps_smmu 0x0c04 0x20>,
 							 <&apps_smmu 0x19c4 0x10>;
+						dma-coherent;
 					};
 
 					compute-cb@5 {
@@ -4420,6 +4560,7 @@
 						iommus = <&apps_smmu 0x1965 0x0>,
 							 <&apps_smmu 0x0c05 0x20>,
 							 <&apps_smmu 0x19c5 0x10>;
+						dma-coherent;
 					};
 
 					compute-cb@6 {
@@ -4428,6 +4569,7 @@
 						iommus = <&apps_smmu 0x1966 0x0>,
 							 <&apps_smmu 0x0c06 0x20>,
 							 <&apps_smmu 0x19c6 0x10>;
+						dma-coherent;
 					};
 
 					compute-cb@7 {
@@ -4436,6 +4578,7 @@
 						iommus = <&apps_smmu 0x1967 0x0>,
 							 <&apps_smmu 0x0c07 0x20>,
 							 <&apps_smmu 0x19c7 0x10>;
+						dma-coherent;
 					};
 
 					compute-cb@8 {
@@ -4444,6 +4587,7 @@
 						iommus = <&apps_smmu 0x1968 0x0>,
 							 <&apps_smmu 0x0c08 0x20>,
 							 <&apps_smmu 0x19c8 0x10>;
+						dma-coherent;
 					};
 
 					/* note: secure cb9 in downstream */
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8650-mtp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8650-mtp.dts
@@ -587,7 +587,7 @@
 };
 
 &sleep_clk {
-	clock-frequency = <32000>;
+	clock-frequency = <32764>;
 };
 
 &swr0 {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
@@ -630,7 +630,7 @@
 };
 
 &sleep_clk {
-	clock-frequency = <32000>;
+	clock-frequency = <32764>;
 };
 
 &spi4 {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8650.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8650.dtsi
@@ -2448,10 +2448,12 @@
 			compatible = "qcom,sm8650-qmp-ufs-phy";
 			reg = <0 0x01d80000 0 0x2000>;
 
-			clocks = <&tcsr TCSR_UFS_CLKREF_EN>,
-				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+			clocks = <&rpmhcc RPMH_CXO_CLK>,
+				 <&gcc GCC_UFS_PHY_PHY_AUX_CLK>,
+				 <&tcsr TCSR_UFS_CLKREF_EN>;
 			clock-names = "ref",
-				      "ref_aux";
+				      "ref_aux",
+				      "qref";
 
 			resets = <&ufs_mem_hc 0>;
 			reset-names = "ufsphy";
@@ -2600,7 +2602,7 @@
 
 		remoteproc_mpss: remoteproc@4080000 {
 			compatible = "qcom,sm8650-mpss-pas";
-			reg = <0 0x04080000 0 0x4040>;
+			reg = <0x0 0x04080000 0x0 0x10000>;
 
 			interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>,
@@ -3078,11 +3080,8 @@
 			resets = <&dispcc DISP_CC_MDSS_CORE_BCR>;
 
 			interconnects = <&mmss_noc MASTER_MDP QCOM_ICC_TAG_ALWAYS
-					 &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ALWAYS>,
-					<&mc_virt MASTER_LLCC QCOM_ICC_TAG_ALWAYS
 					 &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>;
-			interconnect-names = "mdp0-mem",
-					     "mdp1-mem";
+			interconnect-names = "mdp0-mem";
 
 			power-domains = <&dispcc MDSS_GDSC>;
 
@@ -3703,7 +3702,7 @@
 		spmi_bus: spmi@c400000 {
 			compatible = "qcom,spmi-pmic-arb";
 			reg = <0 0x0c400000 0 0x3000>,
-			      <0 0x0c500000 0 0x4000000>,
+			      <0 0x0c500000 0 0x400000>,
 			      <0 0x0c440000 0 0x80000>,
 			      <0 0x0c4c0000 0 0x20000>,
 			      <0 0x0c42d000 0 0x4000>;
@@ -4808,6 +4807,7 @@
 
 						iommus = <&apps_smmu 0x1003 0x80>,
 							 <&apps_smmu 0x1043 0x20>;
+						dma-coherent;
 					};
 
 					compute-cb@4 {
@@ -4816,6 +4816,7 @@
 
 						iommus = <&apps_smmu 0x1004 0x80>,
 							 <&apps_smmu 0x1044 0x20>;
+						dma-coherent;
 					};
 
 					compute-cb@5 {
@@ -4824,6 +4825,7 @@
 
 						iommus = <&apps_smmu 0x1005 0x80>,
 							 <&apps_smmu 0x1045 0x20>;
+						dma-coherent;
 					};
 
 					compute-cb@6 {
@@ -4832,6 +4834,7 @@
 
 						iommus = <&apps_smmu 0x1006 0x80>,
 							 <&apps_smmu 0x1046 0x20>;
+						dma-coherent;
 					};
 
 					compute-cb@7 {
@@ -4841,6 +4844,7 @@
 						iommus = <&apps_smmu 0x1007 0x40>,
 							 <&apps_smmu 0x1067 0x0>,
 							 <&apps_smmu 0x1087 0x0>;
+						dma-coherent;
 					};
 				};
 
@@ -4897,7 +4901,7 @@
 
 		remoteproc_cdsp: remoteproc@32300000 {
 			compatible = "qcom,sm8650-cdsp-pas";
-			reg = <0 0x32300000 0 0x1400000>;
+			reg = <0x0 0x32300000 0x0 0x10000>;
 
 			interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
 					      <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>,
@@ -4961,6 +4965,7 @@
 						iommus = <&apps_smmu 0x1961 0x0>,
 							 <&apps_smmu 0x0c01 0x20>,
 							 <&apps_smmu 0x19c1 0x0>;
+						dma-coherent;
 					};
 
 					compute-cb@2 {
@@ -4970,6 +4975,7 @@
 						iommus = <&apps_smmu 0x1962 0x0>,
 							 <&apps_smmu 0x0c02 0x20>,
 							 <&apps_smmu 0x19c2 0x0>;
+						dma-coherent;
 					};
 
 					compute-cb@3 {
@@ -4979,6 +4985,7 @@
 						iommus = <&apps_smmu 0x1963 0x0>,
 							 <&apps_smmu 0x0c03 0x20>,
 							 <&apps_smmu 0x19c3 0x0>;
+						dma-coherent;
 					};
 
 					compute-cb@4 {
@@ -4988,6 +4995,7 @@
 						iommus = <&apps_smmu 0x1964 0x0>,
 							 <&apps_smmu 0x0c04 0x20>,
 							 <&apps_smmu 0x19c4 0x0>;
+						dma-coherent;
 					};
 
 					compute-cb@5 {
@@ -4997,6 +5005,7 @@
 						iommus = <&apps_smmu 0x1965 0x0>,
 							 <&apps_smmu 0x0c05 0x20>,
 							 <&apps_smmu 0x19c5 0x0>;
+						dma-coherent;
 					};
 
 					compute-cb@6 {
@@ -5006,6 +5015,7 @@
 						iommus = <&apps_smmu 0x1966 0x0>,
 							 <&apps_smmu 0x0c06 0x20>,
 							 <&apps_smmu 0x19c6 0x0>;
+						dma-coherent;
 					};
 
 					compute-cb@7 {
@@ -5015,6 +5025,7 @@
 						iommus = <&apps_smmu 0x1967 0x0>,
 							 <&apps_smmu 0x0c07 0x20>,
 							 <&apps_smmu 0x19c7 0x0>;
+						dma-coherent;
 					};
 
 					compute-cb@8 {
@@ -5024,6 +5035,7 @@
 						iommus = <&apps_smmu 0x1968 0x0>,
 							 <&apps_smmu 0x0c08 0x20>,
 							 <&apps_smmu 0x19c8 0x0>;
+						dma-coherent;
 					};
 				};
 			};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8650p-addons-aim500-aiot.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8650p-addons-aim500-aiot.dts
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "sm8650p-aim500-aiot.dts"
+#include "sm8650p-addons.dtsi"
+
+
+/ {
+	model = "Qualcomm Technologies, Inc. SM8650P-addons AIM500 AIOT";
+	compatible = "qcom,sm8650p-addons-aim500-aiot", "qcom,sm8650p-aim500", "qcom,sm8650p",
+		     "qcom,sm8650";
+
+	qps615_vreg: qps615-vreg {
+		compatible = "regulator-fixed";
+		regulator-name = "qps615_vreg";
+		gpio = <&tlmm 21 GPIO_ACTIVE_HIGH>;
+		regulator-min-microvolt = <1800000>;
+		regulator-max-microvolt = <1800000>;
+		enable-active-high;
+		regulator-enable-ramp-delay = <10000>;
+	};
+};
+
+&i2c_master_hub_0 {
+	status = "okay";
+};
+
+&i2c_hub_4 {
+	status = "okay";
+	qps615_switch: pcie-switch@77 {
+		compatible = "qcom,switch-i2c";
+		reg = <0x77>;
+		vdda-supply = <&qps615_vreg>;
+		status = "okay";
+	};
+};
+
+&pcie1 {
+	dummy-supply = <&qps615_switch>;
+};
+
+&pcie1_phy {
+	qcom,refclk-always-on;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8650p-addons.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8650p-addons.dtsi
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+&soc {
+	/* reserved */
+};
+
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8650p-aim500-aiot.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8650p-aim500-aiot.dts
@@ -0,0 +1,345 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/leds/common.h>
+#include "sm8650p-aim500.dtsi"
+#include "pm8010.dtsi"
+#include "pmr735d_a.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. AIM500 AIOT";
+	compatible = "qcom,sm8650p-aim500-aiot", "qcom,sm8650p-aim500", "qcom,sm8650p",
+		     "qcom,sm8650";
+
+	qcom,msm-id = <577 0x20000>;
+	qcom,board-id = <0x1001f 0x1>;
+
+	aliases {
+		serial0 = &uart15;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	gpio-keys {
+		compatible = "gpio-keys";
+
+		pinctrl-0 = <&volume_up_n>;
+		pinctrl-names = "default";
+
+		key-volume-up {
+			label = "Volume Up";
+			linux,code = <KEY_VOLUMEUP>;
+			gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>;
+			debounce-interval = <15>;
+			linux,can-disable;
+			wakeup-source;
+		};
+	};
+
+	pmic-glink {
+		compatible = "qcom,sm8650-pmic-glink",
+			     "qcom,sm8550-pmic-glink",
+			     "qcom,pmic-glink";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		orientation-gpios = <&tlmm 29 GPIO_ACTIVE_HIGH>;
+
+		connector@0 {
+			compatible = "usb-c-connector";
+			reg = <0>;
+
+			power-role = "dual";
+			data-role = "dual";
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				port@0 {
+					reg = <0>;
+
+					pmic_glink_hs_in: endpoint {
+						remote-endpoint = <&usb_1_dwc3_hs>;
+					};
+				};
+
+				port@1 {
+					reg = <1>;
+
+					pmic_glink_ss_in: endpoint {
+						remote-endpoint = <&usb_1_dwc3_ss>;
+					};
+				};
+			};
+		};
+	};
+};
+
+&dispcc {
+	status = "okay";
+};
+
+&gpi_dma1 {
+	status = "okay";
+};
+
+&pcie_1_phy_aux_clk {
+	clock-frequency = <1000>;
+};
+
+&pcie0 {
+	perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
+	wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
+
+	pinctrl-0 = <&pcie0_default_state>;
+	pinctrl-names = "default";
+
+	status = "okay";
+};
+
+&pcie0_phy {
+	vdda-phy-supply = <&vreg_l1i_0p88>;
+	vdda-pll-supply = <&vreg_l3i_1p2>;
+
+	status = "okay";
+};
+
+&pcie1 {
+	wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>;
+	perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>;
+
+	pinctrl-0 = <&pcie1_default_state>;
+	pinctrl-names = "default";
+
+	iommu-map = <0x0 &apps_smmu 0x1480 0x1>,
+		<0x100 &apps_smmu 0x1481 0x1>,
+		<0x208 &apps_smmu 0x1482 0x1>,
+		<0x210 &apps_smmu 0x1483 0x1>,
+		<0x218 &apps_smmu 0x1484 0x1>,
+		<0x300 &apps_smmu 0x1487 0x1>,
+		<0x400 &apps_smmu 0x1488 0x1>,
+		<0x500 &apps_smmu 0x148c 0x1>,
+		<0x501 &apps_smmu 0x148e 0x1>;
+
+	status = "okay";
+};
+
+&pcie1_phy {
+	vdda-phy-supply = <&vreg_l3e_0p9>;
+	vdda-pll-supply = <&vreg_l3i_1p2>;
+	vdda-qref-supply = <&vreg_l1i_0p88>;
+
+	status = "okay";
+};
+
+&pm8550_flash {
+	status = "okay";
+
+	led-0 {
+		function = LED_FUNCTION_FLASH;
+		color = <LED_COLOR_ID_YELLOW>;
+		flash-max-microamp = <2000000>;
+		flash-max-timeout-us = <1280000>;
+		function-enumerator = <0>;
+		led-sources = <1>, <4>;
+		led-max-microamp = <500000>;
+	};
+
+	led-1 {
+		function = LED_FUNCTION_FLASH;
+		color = <LED_COLOR_ID_WHITE>;
+		flash-max-microamp = <2000000>;
+		flash-max-timeout-us = <1280000>;
+		function-enumerator = <1>;
+		led-sources = <2>, <3>;
+		led-max-microamp = <500000>;
+	};
+};
+
+&pm8550_gpios {
+	volume_up_n: volume-up-n-state {
+		pins = "gpio6";
+		function = "normal";
+		power-source = <1>;
+		bias-pull-up;
+		input-enable;
+	};
+};
+
+&pm8550_pwm {
+	status = "okay";
+
+	multi-led {
+		color = <LED_COLOR_ID_RGB>;
+		function = LED_FUNCTION_STATUS;
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		led@1 {
+			reg = <1>;
+			color = <LED_COLOR_ID_RED>;
+		};
+
+		led@2 {
+			reg = <2>;
+			color = <LED_COLOR_ID_GREEN>;
+		};
+
+		led@3 {
+			reg = <3>;
+			color = <LED_COLOR_ID_BLUE>;
+		};
+	};
+};
+
+&pm8550b_eusb2_repeater {
+	vdd18-supply = <&vreg_l15b_1p8>;
+	vdd3-supply = <&vreg_l5b_3p1>;
+};
+
+&pmk8550_rtc {
+	status = "okay";
+};
+
+&pon_pwrkey {
+	status = "okay";
+};
+
+&pon_resin {
+	linux,code = <KEY_VOLUMEDOWN>;
+
+	status = "okay";
+};
+
+&qupv3_id_0 {
+	status = "okay";
+};
+
+&remoteproc_adsp {
+	firmware-name = "qcom/sm8650/adsp.mbn",
+			"qcom/sm8650/adsp_dtb.mbn";
+
+	status = "okay";
+};
+
+&remoteproc_cdsp {
+	firmware-name = "qcom/sm8650/cdsp.mbn",
+			"qcom/sm8650/cdsp_dtb.mbn";
+
+	status = "okay";
+};
+
+&sleep_clk {
+	clock-frequency = <32000>;
+};
+
+&tlmm {
+	gpio-reserved-ranges = <32 8>, <74 2>;
+
+	sde_dsi_active: sde-dsi-active-state {
+		pins = "gpio133";
+		function = "gpio";
+		drive-strength = <8>;
+		bias-disable;
+	};
+
+	sde_dsi_suspend: sde-dsi-suspend-state {
+		pins = "gpio133";
+		function = "gpio";
+		drive-strength = <2>;
+		bias-pull-down;
+	};
+
+	sde_te_active: sde-te-active-state {
+		pins = "gpio86";
+		function = "mdp_vsync";
+		drive-strength = <2>;
+		bias-pull-down;
+	};
+
+	sde_te_suspend: sde-te-suspend-state {
+		pins = "gpio86";
+		function = "mdp_vsync";
+		drive-strength = <2>;
+		bias-pull-down;
+	};
+
+	ts_irq: ts-irq-state {
+		pins = "gpio161";
+		function = "gpio";
+		drive-strength = <8>;
+		bias-pull-up;
+		output-disable;
+	};
+
+	ts_reset: ts-reset-state {
+		pins = "gpio162";
+		function = "gpio";
+		drive-strength = <8>;
+		bias-pull-up;
+	};
+};
+
+&uart15 {
+	status = "okay";
+};
+
+/*
+ * DPAUX -> WCD9395 -> USB_SBU -> USB-C
+ * eUSB2 DP/DM -> PM85550HS -> eUSB2 DP/DM -> WCD9395 -> USB-C
+ * USB SS -> NB7VPQ904MMUTWG -> USB-C
+ */
+
+&usb_1 {
+	status = "okay";
+};
+
+&usb_1_dwc3 {
+	dr_mode = "otg";
+	usb-role-switch;
+};
+
+&usb_1_dwc3_hs {
+	remote-endpoint = <&pmic_glink_hs_in>;
+};
+
+&usb_1_dwc3_ss {
+	remote-endpoint = <&pmic_glink_ss_in>;
+};
+
+&usb_1_hsphy {
+	vdd-supply = <&vreg_l1i_0p88>;
+	vdda12-supply = <&vreg_l3i_1p2>;
+
+	phys = <&pm8550b_eusb2_repeater>;
+
+	status = "okay";
+};
+
+&usb_dp_qmpphy {
+	vdda-phy-supply = <&vreg_l3i_1p2>;
+	vdda-pll-supply = <&vreg_l3g_0p91>;
+
+	status = "okay";
+};
+
+&vph_pwr {
+	compatible = "regulator-fixed";
+	regulator-name = "vph_pwr";
+	regulator-min-microvolt = <3700000>;
+	regulator-max-microvolt = <3700000>;
+
+	regulator-always-on;
+	regulator-boot-on;
+};
+
+&xo_board {
+	clock-frequency = <76800000>;
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8650p-aim500.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8650p-aim500.dtsi
@@ -0,0 +1,409 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sm8650p.dtsi"
+#include "pm8550.dtsi"
+#include "pm8550b.dtsi"
+#define PMK8550VE_SID 8
+#include "pm8550ve.dtsi"
+#include "pm8550vs.dtsi"
+#include "pmk8550.dtsi"
+
+/ {
+	aliases {
+		serial1 = &uart14;
+	};
+
+	vph_pwr: vph-pwr-regulator { };
+};
+
+&apps_rsc {
+	regulators-0 {
+		compatible = "qcom,pm8550-rpmh-regulators";
+
+		vdd-bob1-supply = <&vph_pwr>;
+		vdd-bob2-supply = <&vph_pwr>;
+		vdd-l2-l13-l14-supply = <&vreg_bob1>;
+		vdd-l3-supply = <&vreg_s1c_1p2>;
+		vdd-l5-l16-supply = <&vreg_bob1>;
+		vdd-l6-l7-supply = <&vreg_bob1>;
+		vdd-l8-l9-supply = <&vreg_bob1>;
+		vdd-l11-supply = <&vreg_s1c_1p2>;
+		vdd-l12-supply = <&vreg_s6c_1p8>;
+		vdd-l15-supply = <&vreg_s6c_1p8>;
+		vdd-l17-supply = <&vreg_bob2>;
+
+		qcom,pmic-id = "b";
+
+		vreg_bob1: bob1 {
+			regulator-name = "vreg_bob1";
+			regulator-min-microvolt = <3008000>;
+			regulator-max-microvolt = <3960000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_bob2: bob2 {
+			regulator-name = "vreg_bob2";
+			regulator-min-microvolt = <2704000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2b_3p0: ldo2 {
+			regulator-name = "vreg_l2b_3p0";
+			regulator-min-microvolt = <3008000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l5b_3p1: ldo5 {
+			regulator-name = "vreg_l5b_3p1";
+			regulator-min-microvolt = <3104000>;
+			regulator-max-microvolt = <3104000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l6b_1p8: ldo6 {
+			regulator-name = "vreg_l6b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l7b_1p8: ldo7 {
+			regulator-name = "vreg_l7b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l8b_1p8: ldo8 {
+			regulator-name = "vreg_l8b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <3008000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l11b_1p2: ldo11 {
+			regulator-name = "vreg_l11b_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l12b_1p8: ldo12 {
+			regulator-name = "vreg_l12b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l13b_3p0: ldo13 {
+			regulator-name = "vreg_l13b_3p0";
+			regulator-min-microvolt = <3000000>;
+			regulator-max-microvolt = <3000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l14b_3p2: ldo14 {
+			regulator-name = "vreg_l14b_3p2";
+			regulator-min-microvolt = <3200000>;
+			regulator-max-microvolt = <3200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l15b_1p8: ldo15 {
+			regulator-name = "vreg_l15b_1p8";
+			regulator-min-microvolt = <1800000>;
+			regulator-max-microvolt = <1800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l16b_2p8: ldo16 {
+			regulator-name = "vreg_l16b_2p8";
+			regulator-min-microvolt = <2800000>;
+			regulator-max-microvolt = <2800000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l17b_2p5: ldo17 {
+			regulator-name = "vreg_l17b_2p5";
+			regulator-min-microvolt = <2504000>;
+			regulator-max-microvolt = <2504000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-1 {
+		compatible = "qcom,pm8550vs-rpmh-regulators";
+
+		vdd-l1-supply = <&vreg_s1c_1p2>;
+		vdd-l2-supply = <&vreg_s1c_1p2>;
+		vdd-l3-supply = <&vreg_s1c_1p2>;
+		vdd-s1-supply = <&vph_pwr>;
+		vdd-s2-supply = <&vph_pwr>;
+		vdd-s3-supply = <&vph_pwr>;
+		vdd-s4-supply = <&vph_pwr>;
+		vdd-s5-supply = <&vph_pwr>;
+		vdd-s6-supply = <&vph_pwr>;
+
+		qcom,pmic-id = "c";
+
+		vreg_s1c_1p2: smps1 {
+			regulator-name = "vreg_s1c_1p2";
+			regulator-min-microvolt = <1224000>;
+			regulator-max-microvolt = <1348000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s2c_0p8: smps2 {
+			regulator-name = "vreg_s2c_0p8";
+			regulator-min-microvolt = <500000>;
+			regulator-max-microvolt = <1036000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s3c_0p9: smps3 {
+			regulator-name = "vreg_s3c_0p9";
+			regulator-min-microvolt = <904000>;
+			regulator-max-microvolt = <1068000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s4c_1p2: smps4 {
+			regulator-name = "vreg_s4c_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1280000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s5c_0p7: smps5 {
+			regulator-name = "vreg_s5c_0p7";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <900000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_s6c_1p8: smps6 {
+			regulator-name = "vreg_s6c_1p8";
+			regulator-min-microvolt = <1856000>;
+			regulator-max-microvolt = <2000000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1c_1p2: ldo1 {
+			regulator-name = "vreg_l1c_1p2";
+			regulator-min-microvolt = <1100000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3c_1p2: ldo3 {
+			regulator-name = "vreg_l3c_1p2";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-2 {
+		compatible = "qcom,pm8550vs-rpmh-regulators";
+
+		vdd-l1-supply = <&vreg_s3c_0p9>;
+
+		qcom,pmic-id = "d";
+
+		vreg_l1d_0p88: ldo1 {
+			regulator-name = "vreg_l1d_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <920000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-3 {
+		compatible = "qcom,pm8550vs-rpmh-regulators";
+
+		vdd-l3-supply = <&vreg_s3c_0p9>;
+
+		qcom,pmic-id = "e";
+
+		vreg_l3e_0p9: ldo3 {
+			regulator-name = "vreg_l3e_0p9";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <920000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-4 {
+		compatible = "qcom,pm8550vs-rpmh-regulators";
+
+		vdd-l1-supply = <&vreg_s3c_0p9>;
+		vdd-l3-supply = <&vreg_s3c_0p9>;
+
+		qcom,pmic-id = "g";
+
+		vreg_l1g_0p91: ldo1 {
+			regulator-name = "vreg_l1g_0p91";
+			regulator-min-microvolt = <912000>;
+			regulator-max-microvolt = <936000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3g_0p91: ldo3 {
+			regulator-name = "vreg_l3g_0p91";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+
+	regulators-5 {
+		compatible = "qcom,pm8550ve-rpmh-regulators";
+
+		vdd-l1-supply = <&vreg_s3c_0p9>;
+		vdd-l2-supply = <&vreg_s3c_0p9>;
+		vdd-l3-supply = <&vreg_s1c_1p2>;
+		vdd-s4-supply = <&vph_pwr>;
+
+		qcom,pmic-id = "i";
+
+		vreg_s4i_0p85: smps4 {
+			regulator-name = "vreg_s4i_0p85";
+			regulator-min-microvolt = <300000>;
+			regulator-max-microvolt = <1004000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l1i_0p88: ldo1 {
+			regulator-name = "vreg_l1i_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l2i_0p88: ldo2 {
+			regulator-name = "vreg_l2i_0p88";
+			regulator-min-microvolt = <880000>;
+			regulator-max-microvolt = <912000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+
+		vreg_l3i_1p2: ldo3 {
+			regulator-name = "vreg_l3i_0p91";
+			regulator-min-microvolt = <1200000>;
+			regulator-max-microvolt = <1200000>;
+			regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+			regulator-allow-set-load;
+			regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM
+						   RPMH_REGULATOR_MODE_HPM>;
+		};
+	};
+};
+
+&qupv3_id_1 {
+	status = "okay";
+};
+
+&tlmm {
+	bt_default: bt-default-state {
+		bt-en-pins {
+			pins = "gpio17";
+			function = "gpio";
+			drive-strength = <16>;
+			bias-disable;
+		};
+
+		sw-ctrl-pins {
+			pins = "gpio18";
+			function = "gpio";
+			bias-pull-down;
+		};
+	};
+};
+
+&uart14 {
+	status = "okay";
+
+	bluetooth {
+		compatible = "qcom,wcn7850-bt";
+
+		clocks = <&rpmhcc RPMH_RF_CLK1>;
+
+		vddio-supply = <&vreg_l3c_1p2>;
+		vddaon-supply = <&vreg_l15b_1p8>;
+		vdddig-supply = <&vreg_s3c_0p9>;
+		vddrfa0p8-supply = <&vreg_s3c_0p9>;
+		vddrfa1p2-supply = <&vreg_s1c_1p2>;
+		vddrfa1p9-supply = <&vreg_s6c_1p8>;
+
+		max-speed = <3200000>;
+
+		enable-gpios = <&tlmm 17 GPIO_ACTIVE_HIGH>;
+		swctrl-gpios = <&tlmm 18 GPIO_ACTIVE_HIGH>;
+
+		pinctrl-0 = <&bt_default>;
+		pinctrl-names = "default";
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/sm8650p.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/sm8650p.dtsi
@@ -0,0 +1,180 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "sm8650.dtsi"
+
+/delete-node/ &reserved_memory;
+
+/ {
+	reserved_memory: reserved-memory {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		ranges;
+
+		/*
+		 * There are 3 types of reserved memory regions here:
+		 * 1. Firmware related regions.
+		 *     This will be described as: reserved-region@address. Current
+		 * reserved-region may have reserved area which was not yet used,
+		 * release note of the firmware can have such kind of information.
+		 * 2. Firmware related which shared with kernel access.
+		 *     Each region will have a specific node with specific label
+		 * name for later phandle reference from other driver dt node. May
+		 * overlapping with above type regions.
+		 * 3. PIL regions.
+		 *     PIL regions are allocated by kernel and assigned to subsystem
+		 * firmware later.
+		 * Here is a map for this platform:
+		 * 0x100000000 +------------------+
+		 *             |                  |
+		 *             | Firmware Related |
+		 *             |                  |
+		 *  0xd8000000 +------------------+
+		 *             |                  |
+		 *             | Kernel Available |
+		 *             |                  |
+		 *  0xA7000000 +------------------+
+		 *             |                  |
+		 *             |    PIL Region    |
+		 *             |                  |
+		 *  0x8BC00000 +------------------+
+		 *             |                  |
+		 *             | Firmware Related |
+		 *             |                  |
+		 *  0x80000000 +------------------+
+		 * Note that:
+		 * 1. 0xA7000000 to 0xA8000000 was used by bootloader as well, not
+		 * suggest for other usage.
+		 * 2. Kernel start address was start at 0xA8000000.
+		 */
+
+		/* Firmware related regions */
+		reserved-region@80000000 {
+			reg = <0x0 0x80000000 0x0 0xbc00000>;
+			no-map;
+		};
+
+		aop_image_mem: aop-image-region@81c00000 {
+			reg = <0x0 0x81c00000 0x0 0x60000>;
+			no-map;
+		};
+
+		aop_cmd_db_mem: aop-cmd-db-region@81c60000 {
+			compatible = "qcom,cmd-db";
+			reg = <0x0 0x81c60000 0x0 0x20000>;
+			no-map;
+		};
+
+		aop_config_mem: aop-config-region@81c80000 {
+			no-map;
+			reg = <0x0 0x81c80000 0x0 0x20000>;
+		};
+
+		smem_mem: smem-region@81d00000 {
+			compatible = "qcom,smem";
+			reg = <0x0 0x81d00000 0x0 0x200000>;
+			hwlocks = <&tcsr_mutex 3>;
+			no-map;
+		};
+
+		adsp_mhi_mem: adsp-mhi-region@81f00000 {
+			reg = <0x0 0x81f00000 0x0 0x20000>;
+			no-map;
+		};
+
+		global_sync_mem: global-sync@82600000 {
+			reg = <0x0 0x82600000 0x0 0x100000>;
+			no-map;
+		};
+
+		mpss_dsm_mem: mpss-dsm@86b00000 {
+			reg = <0x0 0x86b00000 0x0 0x4900000>;
+			no-map;
+		};
+
+		mpss_dsm_mem_2: mpss-dsm-2@8b400000 {
+			reg = <0x0 0x8b400000 0x0 0x800000>;
+			no-map;
+		};
+
+		/* PIL region */
+		mpss_mem: mpss-region@8bc00000 {
+			reg = <0x0 0x8bc00000 0x0 0xf400000>;
+			no-map;
+		};
+
+		q6_mpss_dtb_mem: q6-mpss-dtb-region@9b000000 {
+			reg = <0x0 0x9b000000 0x0 0x80000>;
+			no-map;
+		};
+
+		ipa_fw_mem: ipa-fw-region@9b080000 {
+			reg = <0x0 0x9b080000 0x0 0x10000>;
+			no-map;
+		};
+
+		ipa_gsi_mem: ipa-gsi-region@9b090000 {
+			reg = <0x0 0x9b090000 0x0 0xa000>;
+			no-map;
+		};
+
+		gpu_micro_code_mem: gpu-micro-code-region@9b09a000 {
+			reg = <0x0 0x9b09a000 0x0 0x2000>;
+			no-map;
+		};
+
+		spss_region_mem: spss-region@9b0a0000 {
+			reg = <0x0 0x9b0a0000 0x0 0x1e0000>;
+			no-map;
+		};
+
+		spu_secure_shared_memory_mem: spu-secure-shared-memory-region@9b280000 {
+			reg = <0x0 0x9b280000 0x0 0x80000>;
+			no-map;
+		};
+
+		camera_mem: camera-region@9b300000 {
+			reg = <0x0 0x9b300000 0x0 0x800000>;
+			no-map;
+		};
+
+		video_mem: video-region@9bb00000 {
+			reg = <0x0 0x9bb00000 0x0 0x800000>;
+			no-map;
+		};
+
+		cvp_mem: cvp-region@9c300000 {
+			reg = <0x0 0x9c300000 0x0 0x700000>;
+			no-map;
+		};
+
+		cdsp_mem: cdsp-region@9ca00000 {
+			reg = <0x0 0x9ca00000 0x0 0x1400000>;
+			no-map;
+		};
+
+		q6_cdsp_dtb_mem: q6-cdsp-dtb-region@9de00000 {
+			reg = <0x0 0x9de00000 0x0 0x80000>;
+			no-map;
+		};
+
+		q6_adsp_dtb_mem: q6-adsp-dtb-region@9de80000 {
+			reg = <0x0 0x9de80000 0x0 0x80000>;
+			no-map;
+		};
+
+		adspslpi_mem: adspslpi-region@9df00000 {
+			reg = <0x0 0x9df00000 0x0 0x4080000>;
+			no-map;
+		};
+
+		/* Firmware related regions */
+		reserved-region@d8000000 {
+			reg = <0x0 0xd8000000 0x0 0x28000000>;
+			no-map;
+		};
+
+	};
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/x1e80100-addons-crd.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/x1e80100-addons-crd.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * x1e80100-addons CRD device tree source
+ *
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
+
+/dts-v1/;
+
+#include "x1e80100-crd.dts"
+#include "x1e80100-addons.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. X1E80100-addons CRD";
+	compatible = "qcom,x1e80100-addons-crd", "qcom,x1e80100";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/x1e80100-addons-qcp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/x1e80100-addons-qcp.dts
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * x1e80100-addons IDP device tree source
+ *
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
+
+/dts-v1/;
+
+#include "x1e80100-qcp.dts"
+#include "x1e80100-addons.dtsi"
+
+/ {
+	model = "Qualcomm Technologies, Inc. X1E80100-addons QCP";
+	compatible = "qcom,x1e80100-addons-qcp", "qcom,x1e80100";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/x1e80100-addons.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/x1e80100-addons.dtsi
@@ -0,0 +1,7 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * x1e80100-addons device tree source
+ *
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
@@ -22,6 +22,15 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	reserved-memory {
+		linux,cma {
+			compatible = "shared-dma-pool";
+			size = <0x0 0x8000000>;
+			reusable;
+			linux,cma-default;
+		};
+	};
+
 	vph_pwr: vph-pwr-regulator {
 		compatible = "regulator-fixed";
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts
@@ -21,6 +21,15 @@
 		stdout-path = "serial0:115200n8";
 	};
 
+	reserved-memory {
+		linux,cma {
+			compatible = "shared-dma-pool";
+			size = <0x0 0x8000000>;
+			reusable;
+			linux,cma-default;
+		};
+	};
+
 	vph_pwr: vph-pwr-regulator {
 		compatible = "regulator-fixed";
 
@@ -243,7 +252,7 @@
 		qcom,pmic-id = "e";
 
 		vdd-l2-supply = <&vreg_s1f_0p7>;
-		vdd-l3-supply = <&vph_pwr>;
+		vdd-l3-supply = <&vreg_s5j_1p2>;
 
 		vreg_l2e_0p8: ldo2 {
 			regulator-name = "vreg_l2e_0p8";
@@ -349,7 +358,7 @@
 		qcom,pmic-id = "j";
 
 		vdd-l1-supply = <&vreg_s1f_0p7>;
-		vdd-l2-supply = <&vph_pwr>;
+		vdd-l2-supply = <&vreg_s5j_1p2>;
 		vdd-l3-supply = <&vreg_s1f_0p7>;
 		vdd-s5-supply = <&vph_pwr>;
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/qcom/x1e80100.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/qcom/x1e80100.dtsi
@@ -30,7 +30,7 @@
 
 		sleep_clk: sleep-clk {
 			compatible = "fixed-clock";
-			clock-frequency = <32000>;
+			clock-frequency = <32764>;
 			#clock-cells = <0>;
 		};
 
@@ -271,14 +271,14 @@
 				idle-state-name = "ret";
 				arm,psci-suspend-param = <0x00000004>;
 				entry-latency-us = <180>;
-				exit-latency-us = <320>;
-				min-residency-us = <1000>;
+				exit-latency-us = <500>;
+				min-residency-us = <600>;
 			};
 		};
 
 		domain-idle-states {
 			CLUSTER_CL4: cluster-sleep-0 {
-				compatible = "arm,idle-state";
+				compatible = "domain-idle-state";
 				idle-state-name = "l2-ret";
 				arm,psci-suspend-param = <0x01000044>;
 				entry-latency-us = <350>;
@@ -287,11 +287,11 @@
 			};
 
 			CLUSTER_CL5: cluster-sleep-1 {
-				compatible = "arm,idle-state";
+				compatible = "domain-idle-state";
 				idle-state-name = "ret-pll-off";
 				arm,psci-suspend-param = <0x01000054>;
 				entry-latency-us = <2200>;
-				exit-latency-us = <2500>;
+				exit-latency-us = <4000>;
 				min-residency-us = <7000>;
 			};
 		};
@@ -3284,7 +3284,7 @@
 		intc: interrupt-controller@17000000 {
 			compatible = "arm,gic-v3";
 			reg = <0 0x17000000 0 0x10000>,     /* GICD */
-			      <0 0x17080000 0 0x480000>;    /* GICR * 12 */
+			      <0 0x17080000 0 0x300000>;    /* GICR * 12 */
 
 			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
 
@@ -3315,7 +3315,6 @@
 			      <0 0x17510000 0 0x10000>,
 			      <0 0x17520000 0 0x10000>;
 			reg-names = "drv-0", "drv-1", "drv-2";
-			qcom,drv-count = <3>;
 
 			interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/renesas/hihope-rev2.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/renesas/hihope-rev2.dtsi
@@ -69,9 +69,6 @@
 
 	status = "okay";
 
-	/* Single DAI */
-	#sound-dai-cells = <0>;
-
 	rsnd_port: port {
 		rsnd_endpoint: endpoint {
 			remote-endpoint = <&dw_hdmi0_snd_in>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi
@@ -84,9 +84,6 @@
 	pinctrl-names = "default";
 	status = "okay";
 
-	/* Single DAI */
-	#sound-dai-cells = <0>;
-
 	/* audio_clkout0/1/2/3 */
 	#clock-cells = <1>;
 	clock-frequency = <12288000 11289600>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
@@ -658,7 +658,7 @@
 		avb0: ethernet@e6800000 {
 			compatible = "renesas,etheravb-r8a779a0",
 				     "renesas,etheravb-rcar-gen4";
-			reg = <0 0xe6800000 0 0x800>;
+			reg = <0 0xe6800000 0 0x1000>;
 			interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>,
@@ -706,7 +706,7 @@
 		avb1: ethernet@e6810000 {
 			compatible = "renesas,etheravb-r8a779a0",
 				     "renesas,etheravb-rcar-gen4";
-			reg = <0 0xe6810000 0 0x800>;
+			reg = <0 0xe6810000 0 0x1000>;
 			interrupts = <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>,
@@ -2910,6 +2910,9 @@
 		interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
 				      <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 				      <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-				      <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+				      <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+				      <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+				  "hyp-virt";
 	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
@@ -1315,7 +1315,10 @@
 		interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
 				      <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 				      <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-				      <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+				      <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+				      <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+				  "hyp-virt";
 	};
 
 	ufs30_clk: ufs30-clk {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
@@ -161,11 +161,6 @@
 		};
 	};
 
-	psci {
-		compatible = "arm,psci-1.0", "arm,psci-0.2";
-		method = "smc";
-	};
-
 	extal_clk: extal {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
@@ -185,13 +180,24 @@
 		interrupts-extended = <&gic GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
 	};
 
-	/* External SCIF clock - to be overridden by boards that provide it */
+	psci {
+		compatible = "arm,psci-1.0", "arm,psci-0.2";
+		method = "smc";
+	};
+
+	/* External SCIF clocks - to be overridden by boards that provide them */
 	scif_clk: scif {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
 		clock-frequency = <0>;
 	};
 
+	scif_clk2: scif2 {
+		compatible = "fixed-clock";
+		#clock-cells = <0>;
+		clock-frequency = <0>;
+	};
+
 	soc: soc {
 		compatible = "simple-bus";
 		interrupt-parent = <&gic>;
@@ -681,7 +687,7 @@
 			interrupts = <GIC_SPI 248 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 516>,
 				 <&cpg CPG_CORE R8A779G0_CLK_SASYNCPERD1>,
-				 <&scif_clk>;
+				 <&scif_clk2>;
 			clock-names = "fck", "brg_int", "scif_clk";
 			dmas = <&dmac0 0x35>, <&dmac0 0x34>,
 			       <&dmac1 0x35>, <&dmac1 0x34>;
@@ -761,7 +767,7 @@
 		avb0: ethernet@e6800000 {
 			compatible = "renesas,etheravb-r8a779g0",
 				     "renesas,etheravb-rcar-gen4";
-			reg = <0 0xe6800000 0 0x800>;
+			reg = <0 0xe6800000 0 0x1000>;
 			interrupts = <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
@@ -808,7 +814,7 @@
 		avb1: ethernet@e6810000 {
 			compatible = "renesas,etheravb-r8a779g0",
 				     "renesas,etheravb-rcar-gen4";
-			reg = <0 0xe6810000 0 0x800>;
+			reg = <0 0xe6810000 0 0x1000>;
 			interrupts = <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 362 IRQ_TYPE_LEVEL_HIGH>,
@@ -1057,7 +1063,7 @@
 			interrupts = <GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH>;
 			clocks = <&cpg CPG_MOD 705>,
 				 <&cpg CPG_CORE R8A779G0_CLK_SASYNCPERD1>,
-				 <&scif_clk>;
+				 <&scif_clk2>;
 			clock-names = "fck", "brg_int", "scif_clk";
 			dmas = <&dmac0 0x59>, <&dmac0 0x58>,
 			       <&dmac1 0x59>, <&dmac1 0x58>;
@@ -1777,6 +1783,37 @@
 			};
 		};
 
+		mmc0: mmc@ee140000 {
+			compatible = "renesas,sdhi-r8a779g0",
+				     "renesas,rcar-gen4-sdhi";
+			reg = <0 0xee140000 0 0x2000>;
+			interrupts = <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 706>,
+				 <&cpg CPG_CORE R8A779G0_CLK_SD0H>;
+			clock-names = "core", "clkh";
+			power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>;
+			resets = <&cpg 706>;
+			max-frequency = <200000000>;
+			iommus = <&ipmmu_ds0 32>;
+			status = "disabled";
+		};
+
+		rpc: spi@ee200000 {
+			compatible = "renesas,r8a779g0-rpc-if",
+				     "renesas,rcar-gen4-rpc-if";
+			reg = <0 0xee200000 0 0x200>,
+			      <0 0x08000000 0 0x04000000>,
+			      <0 0xee208000 0 0x100>;
+			reg-names = "regs", "dirmap", "wbuf";
+			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&cpg CPG_MOD 629>;
+			power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>;
+			resets = <&cpg 629>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			status = "disabled";
+		};
+
 		ipmmu_rt0: iommu@ee480000 {
 			compatible = "renesas,ipmmu-r8a779g0",
 				     "renesas,rcar-gen4-ipmmu-vmsa";
@@ -1886,37 +1923,6 @@
 			#iommu-cells = <1>;
 		};
 
-		mmc0: mmc@ee140000 {
-			compatible = "renesas,sdhi-r8a779g0",
-				     "renesas,rcar-gen4-sdhi";
-			reg = <0 0xee140000 0 0x2000>;
-			interrupts = <GIC_SPI 440 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 706>,
-				 <&cpg CPG_CORE R8A779G0_CLK_SD0H>;
-			clock-names = "core", "clkh";
-			power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>;
-			resets = <&cpg 706>;
-			max-frequency = <200000000>;
-			iommus = <&ipmmu_ds0 32>;
-			status = "disabled";
-		};
-
-		rpc: spi@ee200000 {
-			compatible = "renesas,r8a779g0-rpc-if",
-				     "renesas,rcar-gen4-rpc-if";
-			reg = <0 0xee200000 0 0x200>,
-			      <0 0x08000000 0 0x04000000>,
-			      <0 0xee208000 0 0x100>;
-			reg-names = "regs", "dirmap", "wbuf";
-			interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
-			clocks = <&cpg CPG_MOD 629>;
-			power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>;
-			resets = <&cpg 629>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			status = "disabled";
-		};
-
 		gic: interrupt-controller@f1000000 {
 			compatible = "arm,gic-v3";
 			#interrupt-cells = <3>;
@@ -2344,6 +2350,9 @@
 		interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
 				      <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 				      <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-				      <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+				      <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+				      <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+				  "hyp-virt";
 	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/renesas/r9a07g043u.dtsi
@@ -50,7 +50,10 @@
 		interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
 				      <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 				      <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-				      <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+				      <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+				      <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+				  "hyp-virt";
 	};
 };
 
@@ -109,7 +112,13 @@
 			     <SOC_PERIPHERAL_IRQ(473) IRQ_TYPE_LEVEL_HIGH>,
 			     <SOC_PERIPHERAL_IRQ(474) IRQ_TYPE_LEVEL_HIGH>,
 			     <SOC_PERIPHERAL_IRQ(475) IRQ_TYPE_LEVEL_HIGH>,
-			     <SOC_PERIPHERAL_IRQ(25) IRQ_TYPE_EDGE_RISING>;
+			     <SOC_PERIPHERAL_IRQ(25) IRQ_TYPE_EDGE_RISING>,
+			     <SOC_PERIPHERAL_IRQ(34) IRQ_TYPE_EDGE_RISING>,
+			     <SOC_PERIPHERAL_IRQ(35) IRQ_TYPE_EDGE_RISING>,
+			     <SOC_PERIPHERAL_IRQ(36) IRQ_TYPE_EDGE_RISING>,
+			     <SOC_PERIPHERAL_IRQ(37) IRQ_TYPE_EDGE_RISING>,
+			     <SOC_PERIPHERAL_IRQ(38) IRQ_TYPE_EDGE_RISING>,
+			     <SOC_PERIPHERAL_IRQ(39) IRQ_TYPE_EDGE_RISING>;
 		interrupt-names = "nmi",
 				  "irq0", "irq1", "irq2", "irq3",
 				  "irq4", "irq5", "irq6", "irq7",
@@ -121,7 +130,9 @@
 				  "tint20", "tint21", "tint22", "tint23",
 				  "tint24", "tint25", "tint26", "tint27",
 				  "tint28", "tint29", "tint30", "tint31",
-				  "bus-err";
+				  "bus-err", "ec7tie1-0", "ec7tie2-0",
+				  "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1",
+				  "ec7tiovf-1";
 		clocks = <&cpg CPG_MOD R9A07G043_IA55_CLK>,
 			<&cpg CPG_MOD R9A07G043_IA55_PCLK>;
 		clock-names = "clk", "pclk";
@@ -134,8 +145,8 @@
 		#interrupt-cells = <3>;
 		#address-cells = <0>;
 		interrupt-controller;
-		reg = <0x0 0x11900000 0 0x40000>,
-		      <0x0 0x11940000 0 0x60000>;
+		reg = <0x0 0x11900000 0 0x20000>,
+		      <0x0 0x11940000 0 0x40000>;
 		interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
 	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/renesas/r9a07g044.dtsi
@@ -905,7 +905,27 @@
 				     <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>;
+				     <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 37 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 38 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 39 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "nmi", "irq0", "irq1", "irq2", "irq3",
+					  "irq4", "irq5", "irq6", "irq7",
+					  "tint0", "tint1", "tint2", "tint3",
+					  "tint4", "tint5", "tint6", "tint7",
+					  "tint8", "tint9", "tint10", "tint11",
+					  "tint12", "tint13", "tint14", "tint15",
+					  "tint16", "tint17", "tint18", "tint19",
+					  "tint20", "tint21", "tint22", "tint23",
+					  "tint24", "tint25", "tint26", "tint27",
+					  "tint28", "tint29", "tint30", "tint31",
+					  "bus-err", "ec7tie1-0", "ec7tie2-0",
+					  "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1",
+					  "ec7tiovf-1";
 			clocks = <&cpg CPG_MOD R9A07G044_IA55_CLK>,
 				 <&cpg CPG_MOD R9A07G044_IA55_PCLK>;
 			clock-names = "clk", "pclk";
@@ -977,8 +997,8 @@
 			#interrupt-cells = <3>;
 			#address-cells = <0>;
 			interrupt-controller;
-			reg = <0x0 0x11900000 0 0x40000>,
-			      <0x0 0x11940000 0 0x60000>;
+			reg = <0x0 0x11900000 0 0x20000>,
+			      <0x0 0x11940000 0 0x40000>;
 			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
 		};
 
@@ -1268,6 +1288,9 @@
 		interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
 				      <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 				      <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-				      <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+				      <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+				      <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+				  "hyp-virt";
 	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/renesas/r9a07g054.dtsi
@@ -912,7 +912,27 @@
 				     <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>;
+				     <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 34 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 37 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 38 IRQ_TYPE_EDGE_RISING>,
+				     <GIC_SPI 39 IRQ_TYPE_EDGE_RISING>;
+			interrupt-names = "nmi", "irq0", "irq1", "irq2", "irq3",
+					  "irq4", "irq5", "irq6", "irq7",
+					  "tint0", "tint1", "tint2", "tint3",
+					  "tint4", "tint5", "tint6", "tint7",
+					  "tint8", "tint9", "tint10", "tint11",
+					  "tint12", "tint13", "tint14", "tint15",
+					  "tint16", "tint17", "tint18", "tint19",
+					  "tint20", "tint21", "tint22", "tint23",
+					  "tint24", "tint25", "tint26", "tint27",
+					  "tint28", "tint29", "tint30", "tint31",
+					  "bus-err", "ec7tie1-0", "ec7tie2-0",
+					  "ec7tiovf-0", "ec7tie1-1", "ec7tie2-1",
+					  "ec7tiovf-1";
 			clocks = <&cpg CPG_MOD R9A07G054_IA55_CLK>,
 				 <&cpg CPG_MOD R9A07G054_IA55_PCLK>;
 			clock-names = "clk", "pclk";
@@ -984,8 +1004,8 @@
 			#interrupt-cells = <3>;
 			#address-cells = <0>;
 			interrupt-controller;
-			reg = <0x0 0x11900000 0 0x40000>,
-			      <0x0 0x11940000 0 0x60000>;
+			reg = <0x0 0x11900000 0 0x20000>,
+			      <0x0 0x11940000 0 0x40000>;
 			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
 		};
 
@@ -1275,6 +1295,9 @@
 		interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
 				      <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 				      <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-				      <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+				      <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+				      <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+				  "hyp-virt";
 	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
@@ -152,7 +152,10 @@
 				     <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+				     <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "nmi",
 					  "irq0", "irq1", "irq2", "irq3",
 					  "irq4", "irq5", "irq6", "irq7",
@@ -164,7 +167,8 @@
 					  "tint20", "tint21", "tint22", "tint23",
 					  "tint24", "tint25", "tint26", "tint27",
 					  "tint28", "tint29", "tint30", "tint31",
-					  "bus-err";
+					  "bus-err", "ec7tie1-0", "ec7tie2-0",
+					  "ec7tiovf-0";
 			clocks = <&cpg CPG_MOD R9A08G045_IA55_CLK>,
 				 <&cpg CPG_MOD R9A08G045_IA55_PCLK>;
 			clock-names = "clk", "pclk";
@@ -260,8 +264,8 @@
 			#interrupt-cells = <3>;
 			#address-cells = <0>;
 			interrupt-controller;
-			reg = <0x0 0x12400000 0 0x40000>,
-			      <0x0 0x12440000 0 0x60000>;
+			reg = <0x0 0x12400000 0 0x20000>,
+			      <0x0 0x12440000 0 0x40000>;
 			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
 		};
 	};
@@ -271,6 +275,9 @@
 		interrupts-extended = <&gic GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
 				      <&gic GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
 				      <&gic GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-				      <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+				      <&gic GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>,
+				      <&gic GIC_PPI 12 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-names = "sec-phys", "phys", "virt", "hyp-phys",
+				  "hyp-virt";
 	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi
@@ -41,11 +41,6 @@
 #endif
 	};
 
-	chosen {
-		bootargs = "ignore_loglevel";
-		stdout-path = "serial0:115200n8";
-	};
-
 	memory@48000000 {
 		device_type = "memory";
 		/* First 128MB is reserved for secure area. */
@@ -193,12 +188,14 @@
 #endif
 
 &pinctrl {
+#if SW_CONFIG3 == SW_ON
 	eth0-phy-irq-hog {
 		gpio-hog;
 		gpios = <RZG2L_GPIO(12, 0) GPIO_ACTIVE_LOW>;
 		input;
 		line-name = "eth0-phy-irq";
 	};
+#endif
 
 	eth0_pins: eth0 {
 		txc {
@@ -234,12 +231,14 @@
 		};
 	};
 
+#if SW_CONFIG3 == SW_ON
 	eth1-phy-irq-hog {
 		gpio-hog;
 		gpios = <RZG2L_GPIO(12, 1) GPIO_ACTIVE_LOW>;
 		input;
 		line-name = "eth1-phy-irq";
 	};
+#endif
 
 	eth1_pins: eth1 {
 		txc {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
@@ -10,10 +10,15 @@
 
 / {
 	aliases {
-		serial0 = &scif0;
+		serial3 = &scif0;
 		mmc1 = &sdhi1;
 	};
 
+	chosen {
+		bootargs = "ignore_loglevel";
+		stdout-path = "serial3:115200n8";
+	};
+
 	vcc_sdhi1: regulator-vcc-sdhi1 {
 		compatible = "regulator-fixed";
 		regulator-name = "SDHI1 Vcc";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/Makefile
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/Makefile
@@ -18,6 +18,7 @@
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2c-plus.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-nanopi-r2s-plus.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-orangepi-r1-plus-lts.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3328-rock64.dtb
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/px30-ringneck.dtsi
@@ -66,7 +66,6 @@
 	bus-width = <8>;
 	cap-mmc-highspeed;
 	mmc-hs200-1_8v;
-	supports-emmc;
 	mmc-pwrseq = <&emmc_pwrseq>;
 	non-removable;
 	vmmc-supply = <&vcc_3v3>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3308-roc-cc.dts
@@ -36,14 +36,14 @@
 
 		power_led: led-0 {
 			label = "firefly:red:power";
-			linux,default-trigger = "ir-power-click";
+			linux,default-trigger = "default-on";
 			default-state = "on";
 			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
 		};
 
 		user_led: led-1 {
 			label = "firefly:blue:user";
-			linux,default-trigger = "ir-user-click";
+			linux,default-trigger = "rc-feedback";
 			default-state = "off";
 			gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_HIGH>;
 		};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3308-rock-pi-s.dts
@@ -5,6 +5,8 @@
  */
 
 /dts-v1/;
+
+#include <dt-bindings/leds/common.h>
 #include "rk3308.dtsi"
 
 / {
@@ -15,6 +17,7 @@
 		ethernet0 = &gmac;
 		mmc0 = &emmc;
 		mmc1 = &sdmmc;
+		mmc2 = &sdio;
 	};
 
 	chosen {
@@ -24,17 +27,21 @@
 	leds {
 		compatible = "gpio-leds";
 		pinctrl-names = "default";
-		pinctrl-0 = <&green_led_gio>, <&heartbeat_led_gpio>;
+		pinctrl-0 = <&green_led>, <&heartbeat_led>;
 
 		green-led {
+			color = <LED_COLOR_ID_GREEN>;
 			default-state = "on";
+			function = LED_FUNCTION_POWER;
 			gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
 			label = "rockpis:green:power";
 			linux,default-trigger = "default-on";
 		};
 
 		blue-led {
+			color = <LED_COLOR_ID_BLUE>;
 			default-state = "on";
+			function = LED_FUNCTION_HEARTBEAT;
 			gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_HIGH>;
 			label = "rockpis:blue:user";
 			linux,default-trigger = "heartbeat";
@@ -126,21 +133,37 @@
 };
 
 &emmc {
-	bus-width = <4>;
 	cap-mmc-highspeed;
-	mmc-hs200-1_8v;
+	cap-sd-highspeed;
+	no-sdio;
 	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>;
 	vmmc-supply = <&vcc_io>;
 	status = "okay";
 };
 
 &gmac {
 	clock_in_out = "output";
+	phy-handle = <&rtl8201f>;
 	phy-supply = <&vcc_io>;
-	snps,reset-gpio = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
-	snps,reset-active-low;
-	snps,reset-delays-us = <0 50000 50000>;
 	status = "okay";
+
+	mdio {
+		compatible = "snps,dwmac-mdio";
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		rtl8201f: ethernet-phy@1 {
+			compatible = "ethernet-phy-ieee802.3-c22";
+			reg = <1>;
+			pinctrl-names = "default";
+			pinctrl-0 = <&mac_rst>;
+			reset-assert-us = <20000>;
+			reset-deassert-us = <50000>;
+			reset-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
+		};
+	};
 };
 
 &gpio0 {
@@ -213,12 +236,32 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&rtc_32k>;
 
+	bluetooth {
+		bt_reg_on: bt-reg-on {
+			rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+
+		bt_wake_host: bt-wake-host {
+			rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+
+		host_wake_bt: host-wake-bt {
+			rockchip,pins = <4 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
+	gmac {
+		mac_rst: mac-rst {
+			rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>;
+		};
+	};
+
 	leds {
-		green_led_gio: green-led-gpio {
+		green_led: green-led {
 			rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 
-		heartbeat_led_gpio: heartbeat-led-gpio {
+		heartbeat_led: heartbeat-led {
 			rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
 		};
 	};
@@ -256,15 +299,31 @@
 	cap-sd-highspeed;
 	cap-sdio-irq;
 	keep-power-in-suspend;
-	max-frequency = <1000000>;
+	max-frequency = <100000000>;
 	mmc-pwrseq = <&sdio_pwrseq>;
+	no-mmc;
+	no-sd;
 	non-removable;
-	sd-uhs-sdr104;
+	sd-uhs-sdr50;
+	vmmc-supply = <&vcc_io>;
+	vqmmc-supply = <&vcc_1v8>;
 	status = "okay";
+
+	rtl8723ds: wifi@1 {
+		reg = <1>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <RK_PA0 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "host-wake";
+		pinctrl-names = "default";
+		pinctrl-0 = <&wifi_host_wake>;
+	};
 };
 
 &sdmmc {
+	cap-mmc-highspeed;
 	cap-sd-highspeed;
+	disable-wp;
+	vmmc-supply = <&vcc_io>;
 	status = "okay";
 };
 
@@ -283,16 +342,22 @@
 };
 
 &uart0 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart0_xfer>;
 	status = "okay";
 };
 
 &uart4 {
+	uart-has-rtscts;
 	status = "okay";
 
 	bluetooth {
-		compatible = "realtek,rtl8723bs-bt";
-		device-wake-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
+		compatible = "realtek,rtl8723ds-bt";
+		device-wake-gpios = <&gpio4 RK_PB2 GPIO_ACTIVE_HIGH>;
+		enable-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>;
 		host-wake-gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&bt_reg_on &bt_wake_host &host_wake_bt>;
 	};
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s-plus.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3328-nanopi-r2s-plus.dts
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * (C) Copyright 2018 FriendlyElec Computer Tech. Co., Ltd.
+ * (http://www.friendlyarm.com)
+ *
+ * (C) Copyright 2016 Rockchip Electronics Co., Ltd
+ */
+
+/dts-v1/;
+#include "rk3328-nanopi-r2s.dts"
+
+/ {
+	compatible = "friendlyarm,nanopi-r2s-plus", "rockchip,rk3328";
+	model = "FriendlyElec NanoPi R2S Plus";
+
+	aliases {
+		mmc1 = &emmc;
+	};
+};
+
+&emmc {
+	bus-width = <8>;
+	cap-mmc-highspeed;
+	disable-wp;
+	mmc-hs200-1_8v;
+	non-removable;
+	pinctrl-names = "default";
+	pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>;
+	status = "okay";
+};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3328-rock-pi-e.dts
@@ -241,8 +241,8 @@
 	rk805: pmic@18 {
 		compatible = "rockchip,rk805";
 		reg = <0x18>;
-		interrupt-parent = <&gpio2>;
-		interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
+		interrupt-parent = <&gpio0>;
+		interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
 		#clock-cells = <1>;
 		clock-output-names = "xin32k", "rk805-clkout2";
 		gpio-controller;
@@ -387,7 +387,7 @@
 
 	pmic {
 		pmic_int_l: pmic-int-l {
-			rockchip,pins = <2 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
+			rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
 		};
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3328.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -306,6 +306,7 @@
 
 			power-domain@RK3328_PD_HEVC {
 				reg = <RK3328_PD_HEVC>;
+				clocks = <&cru SCLK_VENC_CORE>;
 				#power-domain-cells = <0>;
 			};
 			power-domain@RK3328_PD_VIDEO {
@@ -727,8 +728,7 @@
 		compatible = "rockchip,rk3328-dw-hdmi";
 		reg = <0x0 0xff3c0000 0x0 0x20000>;
 		reg-io-width = <4>;
-		interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
-			     <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+		interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&cru PCLK_HDMI>,
 			 <&cru SCLK_HDMI_SFC>,
 			 <&cru SCLK_RTC32K>;
@@ -744,11 +744,20 @@
 		status = "disabled";
 
 		ports {
-			hdmi_in: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			hdmi_in: port@0 {
+				reg = <0>;
+
 				hdmi_in_vop: endpoint {
 					remote-endpoint = <&vop_out_hdmi>;
 				};
 			};
+
+			hdmi_out: port@1 {
+				reg = <1>;
+			};
 		};
 	};
 
@@ -814,8 +823,8 @@
 			<0>, <24000000>,
 			<24000000>, <24000000>,
 			<15000000>, <15000000>,
-			<100000000>, <100000000>,
-			<100000000>, <100000000>,
+			<300000000>, <100000000>,
+			<400000000>, <100000000>,
 			<50000000>, <100000000>,
 			<100000000>, <100000000>,
 			<50000000>, <50000000>,
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3368-lion.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3368-lion.dtsi
@@ -61,7 +61,6 @@
 			fan: fan@18 {
 				compatible = "ti,amc6821";
 				reg = <0x18>;
-				#cooling-cells = <2>;
 			};
 
 			rtc_twi: rtc@6f {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3368.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3368.dtsi
@@ -793,6 +793,7 @@
 		dma-names = "tx";
 		pinctrl-names = "default";
 		pinctrl-0 = <&spdif_tx>;
+		#sound-dai-cells = <0>;
 		status = "disabled";
 	};
 
@@ -804,6 +805,7 @@
 		clocks = <&cru SCLK_I2S_2CH>, <&cru HCLK_I2S_2CH>;
 		dmas = <&dmac_bus 6>, <&dmac_bus 7>;
 		dma-names = "tx", "rx";
+		#sound-dai-cells = <0>;
 		status = "disabled";
 	};
 
@@ -817,6 +819,7 @@
 		dma-names = "tx", "rx";
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2s_8ch_bus>;
+		#sound-dai-cells = <0>;
 		status = "disabled";
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3399-eaidk-610.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3399-eaidk-610.dts
@@ -542,7 +542,7 @@
 	status = "okay";
 
 	rt5651: audio-codec@1a {
-		compatible = "rockchip,rt5651";
+		compatible = "realtek,rt5651";
 		reg = <0x1a>;
 		clocks = <&cru SCLK_I2S_8CH_OUT>;
 		clock-names = "mclk";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3399-gru.dtsi
@@ -450,7 +450,7 @@
 			dlg,btn-cfg = <50>;
 			dlg,mic-det-thr = <500>;
 			dlg,jack-ins-deb = <20>;
-			dlg,jack-det-rate = "32ms_64ms";
+			dlg,jack-det-rate = "32_64";
 			dlg,jack-rem-deb = <1>;
 
 			dlg,a-d-btn-thr = <0xa>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
@@ -32,12 +32,12 @@
 	backlight: edp-backlight {
 		compatible = "pwm-backlight";
 		power-supply = <&vcc_12v>;
-		pwms = <&pwm0 0 740740 0>;
+		pwms = <&pwm0 0 125000 0>;
 	};
 
 	bat: battery {
 		compatible = "simple-battery";
-		charge-full-design-microamp-hours = <9800000>;
+		charge-full-design-microamp-hours = <10000000>;
 		voltage-max-design-microvolt = <4350000>;
 		voltage-min-design-microvolt = <3000000>;
 	};
@@ -779,7 +779,6 @@
 };
 
 &pcie0 {
-	bus-scan-delay-ms = <1000>;
 	ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
 	num-lanes = <4>;
 	pinctrl-names = "default";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts
@@ -138,7 +138,6 @@
 		regulator-max-microvolt = <1800000>;
 		vin-supply = <&vcc3v3_sys>;
 		gpio = <&gpio3 RK_PA5 GPIO_ACTIVE_HIGH>;
-		pinctrl-names = "default";
 	};
 
 	/* MIPI DSI panel 2.8v supply */
@@ -150,7 +149,6 @@
 		regulator-max-microvolt = <2800000>;
 		vin-supply = <&vcc3v3_sys>;
 		gpio = <&gpio3 RK_PA1 GPIO_ACTIVE_HIGH>;
-		pinctrl-names = "default";
 	};
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3399-puma.dtsi
@@ -134,6 +134,22 @@
 	};
 };
 
+&gpio3 {
+	/*
+	 * The Qseven BIOS_DISABLE signal on the RK3399-Q7 keeps the on-module
+	 * eMMC and SPI flash powered-down initially (in fact it keeps the
+	 * reset signal asserted). BIOS_DISABLE_OVERRIDE pin allows to override
+	 * that signal so that eMMC and SPI can be used regardless of the state
+	 * of the signal.
+	 */
+	bios-disable-override-hog {
+		gpios = <RK_PD5 GPIO_ACTIVE_LOW>;
+		gpio-hog;
+		line-name = "bios_disable_override";
+		output-high;
+	};
+};
+
 &gmac {
 	assigned-clocks = <&cru SCLK_RMII_SRC>;
 	assigned-clock-parents = <&clkin_gmac>;
@@ -146,7 +162,7 @@
 	snps,reset-active-low;
 	snps,reset-delays-us = <0 10000 50000>;
 	tx_delay = <0x10>;
-	rx_delay = <0x10>;
+	rx_delay = <0x23>;
 	status = "okay";
 };
 
@@ -389,6 +405,7 @@
 
 &i2s0 {
 	pinctrl-0 = <&i2s0_2ch_bus>;
+	pinctrl-1 = <&i2s0_2ch_bus_bclk_off>;
 	rockchip,playback-channels = <2>;
 	rockchip,capture-channels = <2>;
 	status = "okay";
@@ -397,8 +414,8 @@
 /*
  * As Q7 does not specify neither a global nor a RX clock for I2S these
  * signals are not used. Furthermore I2S0_LRCK_RX is used as GPIO.
- * Therefore we have to redefine the i2s0_2ch_bus definition to prevent
- * conflicts.
+ * Therefore we have to redefine the i2s0_2ch_bus and i2s0_2ch_bus_bclk_off
+ * definitions to prevent conflicts.
  */
 &i2s0_2ch_bus {
 	rockchip,pins =
@@ -408,6 +425,14 @@
 		<3 RK_PD7 1 &pcfg_pull_none>;
 };
 
+&i2s0_2ch_bus_bclk_off {
+	rockchip,pins =
+		<3 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>,
+		<3 RK_PD2 1 &pcfg_pull_none>,
+		<3 RK_PD3 1 &pcfg_pull_none>,
+		<3 RK_PD7 1 &pcfg_pull_none>;
+};
+
 &io_domains {
 	status = "okay";
 	bt656-supply = <&vcc_1v8>;
@@ -416,16 +441,27 @@
 	gpio1830-supply = <&vcc_1v8>;
 };
 
-&pmu_io_domains {
-	status = "okay";
-	pmu1830-supply = <&vcc_1v8>;
-};
-
-&pwm2 {
-	status = "okay";
+&pcie_clkreqn_cpm {
+	rockchip,pins =
+		<2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>;
 };
 
 &pinctrl {
+	pinctrl-names = "default";
+	pinctrl-0 = <&q7_thermal_pin &bios_disable_override_hog_pin>;
+
+	gpios {
+		bios_disable_override_hog_pin: bios-disable-override-hog-pin {
+			rockchip,pins =
+				<3 RK_PD5 RK_FUNC_GPIO &pcfg_pull_down>;
+		};
+
+		q7_thermal_pin: q7-thermal-pin {
+			rockchip,pins =
+				<0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+		};
+	};
+
 	i2c8 {
 		i2c8_xfer_a: i2c8-xfer {
 			rockchip,pins =
@@ -458,11 +494,20 @@
 	usb3 {
 		usb3_id: usb3-id {
 			rockchip,pins =
-			  <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+			  <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_up>;
 		};
 	};
 };
 
+&pmu_io_domains {
+	status = "okay";
+	pmu1830-supply = <&vcc_1v8>;
+};
+
+&pwm2 {
+	status = "okay";
+};
+
 &sdhci {
 	/*
 	 * Signal integrity isn't great at 200MHz but 100MHz has proven stable
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi
@@ -577,7 +577,7 @@
 	bluetooth {
 		compatible = "brcm,bcm43438-bt";
 		clocks = <&rk808 1>;
-		clock-names = "ext_clock";
+		clock-names = "txco";
 		device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>;
 		host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;
 		shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts
@@ -163,7 +163,7 @@
 	status = "okay";
 
 	rt5651: rt5651@1a {
-		compatible = "rockchip,rt5651";
+		compatible = "realtek,rt5651";
 		reg = <0x1a>;
 		clocks = <&cru SCLK_I2S_8CH_OUT>;
 		clock-names = "mclk";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -1956,6 +1956,7 @@
 	hdmi: hdmi@ff940000 {
 		compatible = "rockchip,rk3399-dw-hdmi";
 		reg = <0x0 0xff940000 0x0 0x20000>;
+		reg-io-width = <4>;
 		interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH 0>;
 		clocks = <&cru PCLK_HDMI_CTRL>,
 			 <&cru SCLK_HDMI_SFR>,
@@ -1964,13 +1965,16 @@
 			 <&cru PLL_VPLL>;
 		clock-names = "iahb", "isfr", "cec", "grf", "ref";
 		power-domains = <&power RK3399_PD_HDCP>;
-		reg-io-width = <4>;
 		rockchip,grf = <&grf>;
 		#sound-dai-cells = <0>;
 		status = "disabled";
 
 		ports {
-			hdmi_in: port {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			hdmi_in: port@0 {
+				reg = <0>;
 				#address-cells = <1>;
 				#size-cells = <0>;
 
@@ -1983,6 +1987,10 @@
 					remote-endpoint = <&vopl_out_hdmi>;
 				};
 			};
+
+			hdmi_out: port@1 {
+				reg = <1>;
+			};
 		};
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353p.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353p.dts
@@ -92,7 +92,7 @@
 };
 
 &i2c2 {
-	pintctrl-names = "default";
+	pinctrl-names = "default";
 	pinctrl-0 = <&i2c2m1_xfer>;
 	status = "okay";
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353v.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3566-anbernic-rg353v.dts
@@ -79,7 +79,7 @@
 };
 
 &i2c2 {
-	pintctrl-names = "default";
+	pinctrl-names = "default";
 	pinctrl-0 = <&i2c2m1_xfer>;
 	status = "okay";
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3566-box-demo.dts
@@ -449,9 +449,9 @@
 	bluetooth {
 		compatible = "brcm,bcm43438-bt";
 		clocks = <&pmucru CLK_RTC_32K>;
-		clock-names = "ext_clock";
-		device-wake-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>;
-		host-wake-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
+		clock-names = "txco";
+		device-wakeup-gpios = <&gpio2 RK_PC1 GPIO_ACTIVE_HIGH>;
+		host-wakeup-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
 		shutdown-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_HIGH>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3566-lubancat-1.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3566-lubancat-1.dts
@@ -508,7 +508,6 @@
 	non-removable;
 	pinctrl-names = "default";
 	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>;
-	supports-emmc;
 	status = "okay";
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3566-pinenote.dtsi
@@ -683,11 +683,11 @@
 		compatible = "brcm,bcm43438-bt";
 		clocks = <&rk817 1>;
 		clock-names = "lpo";
-		device-wake-gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_HIGH>;
-		host-wake-gpios = <&gpio0 RK_PC3 GPIO_ACTIVE_HIGH>;
-		reset-gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_LOW>;
+		device-wakeup-gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_HIGH>;
+		host-wakeup-gpios = <&gpio0 RK_PC3 GPIO_ACTIVE_HIGH>;
 		pinctrl-0 = <&bt_enable_h>, <&bt_host_wake_l>, <&bt_wake_h>;
 		pinctrl-names = "default";
+		shutdown-gpios = <&gpio0 RK_PC4 GPIO_ACTIVE_HIGH>;
 		vbat-supply = <&vcc_wl>;
 		vddio-supply = <&vcca_1v8_pmu>;
 	};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3566-quartz64-b.dts
@@ -289,7 +289,7 @@
 				regulator-name = "vdd_gpu";
 				regulator-always-on;
 				regulator-boot-on;
-				regulator-min-microvolt = <900000>;
+				regulator-min-microvolt = <500000>;
 				regulator-max-microvolt = <1350000>;
 				regulator-ramp-delay = <6001>;
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3566-radxa-cm3.dtsi
@@ -402,9 +402,9 @@
 		clock-names = "lpo";
 		device-wakeup-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_HIGH>;
 		host-wakeup-gpios = <&gpio2 RK_PB1 GPIO_ACTIVE_HIGH>;
-		reset-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_LOW>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&bt_host_wake_h &bt_reg_on_h &bt_wake_host_h>;
+		shutdown-gpios = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>;
 		vbat-supply = <&vcc_3v3>;
 		vddio-supply = <&vcc_1v8>;
 	};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3566-roc-pc.dts
@@ -269,7 +269,7 @@
 		vcc9-supply = <&vcc3v3_sys>;
 
 		codec {
-			mic-in-differential;
+			rockchip,mic-in-differential;
 		};
 
 		regulators {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3568-bpi-r2-pro.dts
@@ -416,6 +416,8 @@
 
 			vccio_sd: LDO_REG5 {
 				regulator-name = "vccio_sd";
+				regulator-always-on;
+				regulator-boot-on;
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <3300000>;
 
@@ -525,9 +527,9 @@
 	#address-cells = <1>;
 	#size-cells = <0>;
 
-	switch@0 {
+	switch@1f {
 		compatible = "mediatek,mt7531";
-		reg = <0>;
+		reg = <0x1f>;
 
 		ports {
 			#address-cells = <1>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3568-evb1-v10.dts
@@ -475,7 +475,7 @@
 		};
 
 		codec {
-			mic-in-differential;
+			rockchip,mic-in-differential;
 		};
 	};
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts
@@ -11,6 +11,10 @@
 	};
 };
 
+&pmu_io_domains {
+	vccio3-supply = <&vccio_sd>;
+};
+
 &sdmmc0 {
 	bus-width = <4>;
 	cap-mmc-highspeed;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dtsi
@@ -39,9 +39,9 @@
 		};
 	};
 
-	dc_12v: dc-12v-regulator {
+	vcc12v_dcin: vcc12v-dcin-regulator {
 		compatible = "regulator-fixed";
-		regulator-name = "dc_12v";
+		regulator-name = "vcc12v_dcin";
 		regulator-always-on;
 		regulator-boot-on;
 		regulator-min-microvolt = <12000000>;
@@ -65,7 +65,7 @@
 		regulator-boot-on;
 		regulator-min-microvolt = <3300000>;
 		regulator-max-microvolt = <3300000>;
-		vin-supply = <&dc_12v>;
+		vin-supply = <&vcc12v_dcin>;
 	};
 
 	vcc5v0_sys: vcc5v0-sys-regulator {
@@ -75,16 +75,7 @@
 		regulator-boot-on;
 		regulator-min-microvolt = <5000000>;
 		regulator-max-microvolt = <5000000>;
-		vin-supply = <&dc_12v>;
-	};
-
-	vcc5v0_usb_host: vcc5v0-usb-host-regulator {
-		compatible = "regulator-fixed";
-		regulator-name = "vcc5v0_usb_host";
-		regulator-always-on;
-		regulator-boot-on;
-		regulator-min-microvolt = <5000000>;
-		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc12v_dcin>;
 	};
 
 	vcc5v0_usb_otg: vcc5v0-usb-otg-regulator {
@@ -94,8 +85,9 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&vcc5v0_usb_otg_en>;
 		regulator-name = "vcc5v0_usb_otg";
-		regulator-always-on;
-		regulator-boot-on;
+		regulator-min-microvolt = <5000000>;
+		regulator-max-microvolt = <5000000>;
+		vin-supply = <&vcc5v0_sys>;
 	};
 };
 
@@ -123,6 +115,10 @@
 	cpu-supply = <&vdd_cpu>;
 };
 
+&display_subsystem {
+	status = "disabled";
+};
+
 &gpu {
 	mali-supply = <&vdd_gpu>;
 	status = "okay";
@@ -405,8 +401,8 @@
 &pmu_io_domains {
 	pmuio1-supply = <&vcc3v3_pmu>;
 	pmuio2-supply = <&vcc3v3_pmu>;
-	vccio1-supply = <&vccio_acodec>;
-	vccio3-supply = <&vccio_sd>;
+	vccio1-supply = <&vcc_3v3>;
+	vccio2-supply = <&vcc_1v8>;
 	vccio4-supply = <&vcc_1v8>;
 	vccio5-supply = <&vcc_3v3>;
 	vccio6-supply = <&vcc_1v8>;
@@ -429,28 +425,12 @@
 	status = "okay";
 };
 
-&usb_host0_ehci {
-	status = "okay";
-};
-
-&usb_host0_ohci {
-	status = "okay";
-};
-
 &usb_host0_xhci {
 	dr_mode = "host";
 	extcon = <&usb2phy0>;
 	status = "okay";
 };
 
-&usb_host1_ehci {
-	status = "okay";
-};
-
-&usb_host1_ohci {
-	status = "okay";
-};
-
 &usb_host1_xhci {
 	status = "okay";
 };
@@ -460,7 +440,7 @@
 };
 
 &usb2phy0_host {
-	phy-supply = <&vcc5v0_usb_host>;
+	phy-supply = <&vcc5v0_sys>;
 	status = "okay";
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r68s.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r68s.dts
@@ -39,7 +39,7 @@
 		     &gmac0_rx_bus2
 		     &gmac0_rgmii_clk
 		     &gmac0_rgmii_bus>;
-	snps,reset-gpio = <&gpio0 RK_PB0 GPIO_ACTIVE_LOW>;
+	snps,reset-gpio = <&gpio1 RK_PB0 GPIO_ACTIVE_LOW>;
 	snps,reset-active-low;
 	/* Reset time is 15ms, 50ms for rtl8211f */
 	snps,reset-delays-us = <0 15000 50000>;
@@ -61,7 +61,7 @@
 		     &gmac1m1_rx_bus2
 		     &gmac1m1_rgmii_clk
 		     &gmac1m1_rgmii_bus>;
-	snps,reset-gpio = <&gpio0 RK_PB1 GPIO_ACTIVE_LOW>;
+	snps,reset-gpio = <&gpio1 RK_PB1 GPIO_ACTIVE_LOW>;
 	snps,reset-active-low;
 	/* Reset time is 15ms, 50ms for rtl8211f */
 	snps,reset-delays-us = <0 15000 50000>;
@@ -71,18 +71,18 @@
 };
 
 &mdio0 {
-	rgmii_phy0: ethernet-phy@0 {
+	rgmii_phy0: ethernet-phy@1 {
 		compatible = "ethernet-phy-ieee802.3-c22";
-		reg = <0>;
+		reg = <0x1>;
 		pinctrl-0 = <&eth_phy0_reset_pin>;
 		pinctrl-names = "default";
 	};
 };
 
 &mdio1 {
-	rgmii_phy1: ethernet-phy@0 {
+	rgmii_phy1: ethernet-phy@1 {
 		compatible = "ethernet-phy-ieee802.3-c22";
-		reg = <0>;
+		reg = <0x1>;
 		pinctrl-0 = <&eth_phy1_reset_pin>;
 		pinctrl-names = "default";
 	};
@@ -102,6 +102,10 @@
 	};
 };
 
+&pmu_io_domains {
+	vccio3-supply = <&vcc_3v3>;
+};
+
 &sdhci {
 	bus-width = <8>;
 	max-frequency = <200000000>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3568-lubancat-2.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3568-lubancat-2.dts
@@ -590,7 +590,6 @@
 	non-removable;
 	pinctrl-names = "default";
 	pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>;
-	supports-emmc;
 	status = "okay";
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3568-odroid-m1.dts
@@ -13,7 +13,7 @@
 
 / {
 	model = "Hardkernel ODROID-M1";
-	compatible = "rockchip,rk3568-odroid-m1", "rockchip,rk3568";
+	compatible = "hardkernel,odroid-m1", "rockchip,rk3568";
 
 	aliases {
 		ethernet0 = &gmac0;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3568-roc-pc.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3568-roc-pc.dts
@@ -272,7 +272,6 @@
 				regulator-name = "vdd_logic";
 				regulator-always-on;
 				regulator-boot-on;
-				regulator-init-microvolt = <900000>;
 				regulator-initial-mode = <0x2>;
 				regulator-min-microvolt = <500000>;
 				regulator-max-microvolt = <1350000>;
@@ -285,7 +284,6 @@
 
 			vdd_gpu: DCDC_REG2 {
 				regulator-name = "vdd_gpu";
-				regulator-init-microvolt = <900000>;
 				regulator-initial-mode = <0x2>;
 				regulator-min-microvolt = <500000>;
 				regulator-max-microvolt = <1350000>;
@@ -309,7 +307,6 @@
 
 			vdd_npu: DCDC_REG4 {
 				regulator-name = "vdd_npu";
-				regulator-init-microvolt = <900000>;
 				regulator-initial-mode = <0x2>;
 				regulator-min-microvolt = <500000>;
 				regulator-max-microvolt = <1350000>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3568-rock-3a.dts
@@ -531,10 +531,6 @@
 				};
 			};
 		};
-
-		codec {
-			mic-in-differential;
-		};
 	};
 };
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3568.dtsi
@@ -223,6 +223,7 @@
 		assigned-clocks = <&pmucru CLK_PCIEPHY0_REF>;
 		assigned-clock-rates = <100000000>;
 		resets = <&cru SRST_PIPEPHY0>;
+		reset-names = "phy";
 		rockchip,pipe-grf = <&pipegrf>;
 		rockchip,pipe-phy-grf = <&pipe_phy_grf0>;
 		#phy-cells = <1>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk356x.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk356x.dtsi
@@ -597,6 +597,7 @@
 		compatible = "rockchip,rk3568-vpu";
 		reg = <0x0 0xfdea0000 0x0 0x800>;
 		interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+		interrupt-names = "vdpu";
 		clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
 		clock-names = "aclk", "hclk";
 		iommus = <&vdpu_mmu>;
@@ -748,6 +749,7 @@
 		clocks = <&cru ACLK_VOP>, <&cru HCLK_VOP>;
 		clock-names = "aclk", "iface";
 		#iommu-cells = <0>;
+		power-domains = <&power RK3568_PD_VO>;
 		status = "disabled";
 	};
 
@@ -1123,7 +1125,7 @@
 		dmas = <&dmac1 4>, <&dmac1 5>;
 		dma-names = "tx", "rx";
 		resets = <&cru SRST_M_I2S2_2CH>;
-		reset-names = "m";
+		reset-names = "tx-m";
 		rockchip,grf = <&grf>;
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2s2m0_sclktx
@@ -1711,6 +1713,7 @@
 		assigned-clocks = <&pmucru CLK_PCIEPHY1_REF>;
 		assigned-clock-rates = <100000000>;
 		resets = <&cru SRST_PIPEPHY1>;
+		reset-names = "phy";
 		rockchip,pipe-grf = <&pipegrf>;
 		rockchip,pipe-phy-grf = <&pipe_phy_grf1>;
 		#phy-cells = <1>;
@@ -1727,6 +1730,7 @@
 		assigned-clocks = <&pmucru CLK_PCIEPHY2_REF>;
 		assigned-clock-rates = <100000000>;
 		resets = <&cru SRST_PIPEPHY2>;
+		reset-names = "phy";
 		rockchip,pipe-grf = <&pipegrf>;
 		rockchip,pipe-phy-grf = <&pipe_phy_grf2>;
 		#phy-cells = <1>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi
@@ -216,9 +216,9 @@
 	pinctrl-0 = <&i2c7m0_xfer>;
 	status = "okay";
 
-	es8316: audio-codec@11 {
+	es8316: audio-codec@10 {
 		compatible = "everest,es8316";
-		reg = <0x11>;
+		reg = <0x10>;
 		assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
 		assigned-clock-rates = <12288000>;
 		clocks = <&cru I2S0_8CH_MCLKOUT>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3588-orangepi-5-plus.dts
@@ -486,6 +486,7 @@
 		pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
 			    <&rk806_dvs2_null>, <&rk806_dvs3_null>;
 		spi-max-frequency = <1000000>;
+		system-power-controller;
 
 		vcc1-supply = <&vcc5v0_sys>;
 		vcc2-supply = <&vcc5v0_sys>;
@@ -507,7 +508,7 @@
 		#gpio-cells = <2>;
 
 		rk806_dvs1_null: dvs1-null-pins {
-			pins = "gpio_pwrctrl2";
+			pins = "gpio_pwrctrl1";
 			function = "pin_fun0";
 		};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3588-turing-rk1.dtsi
@@ -297,6 +297,7 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
 			    <&rk806_dvs2_null>, <&rk806_dvs3_null>;
+		system-power-controller;
 
 		vcc1-supply = <&vcc5v0_sys>;
 		vcc2-supply = <&vcc5v0_sys>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
@@ -283,9 +283,9 @@
 	pinctrl-0 = <&i2c7m0_xfer>;
 	status = "okay";
 
-	es8316: audio-codec@11 {
+	es8316: audio-codec@10 {
 		compatible = "everest,es8316";
-		reg = <0x11>;
+		reg = <0x10>;
 		assigned-clocks = <&cru I2S0_8CH_MCLKOUT>;
 		assigned-clock-rates = <12288000>;
 		clocks = <&cru I2S0_8CH_MCLKOUT>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -62,7 +62,7 @@
 
 	sound {
 		compatible = "audio-graph-card";
-		label = "rockchip,es8388-codec";
+		label = "rockchip,es8388";
 		widgets = "Microphone", "Mic Jack",
 			  "Headphone", "Headphones";
 		routing = "LINPUT2", "Mic Jack",
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5.dts
@@ -70,7 +70,6 @@
 
 	vcc_3v3_sd_s0: vcc-3v3-sd-s0-regulator {
 		compatible = "regulator-fixed";
-		enable-active-low;
 		gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_LOW>;
 		regulator-name = "vcc_3v3_sd_s0";
 		regulator-boot-on;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -394,6 +394,7 @@
 		pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>,
 			    <&rk806_dvs2_null>, <&rk806_dvs3_null>;
 		spi-max-frequency = <1000000>;
+		system-power-controller;
 
 		vcc1-supply = <&vcc5v0_sys>;
 		vcc2-supply = <&vcc5v0_sys>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/rockchip/rk3588s.dtsi
@@ -1704,7 +1704,6 @@
 		dmas = <&dmac1 0>, <&dmac1 1>;
 		dma-names = "tx", "rx";
 		power-domains = <&power RK3588_PD_AUDIO>;
-		rockchip,trcm-sync-tx-only;
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2s2m1_lrck
 			     &i2s2m1_sclk
@@ -1725,7 +1724,6 @@
 		dmas = <&dmac1 2>, <&dmac1 3>;
 		dma-names = "tx", "rx";
 		power-domains = <&power RK3588_PD_AUDIO>;
-		rockchip,trcm-sync-tx-only;
 		pinctrl-names = "default";
 		pinctrl-0 = <&i2s3_lrck
 			     &i2s3_sclk
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/Makefile
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/Makefile
@@ -57,6 +57,7 @@
 dtb-$(CONFIG_ARCH_K3) += k3-am654-gp-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-evm.dtb
 dtb-$(CONFIG_ARCH_K3) += k3-am654-idk.dtb
+dtb-$(CONFIG_ARCH_K3) += k3-am654-base-board-rocktech-rk101-panel.dtbo
 
 # Boards with J7200 SoC
 k3-j7200-evm-dtbs := k3-j7200-common-proc-board.dtb k3-j7200-evm-quad-port-eth-exp.dtbo
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am62-main.dtsi
@@ -23,7 +23,6 @@
 		interrupt-controller;
 		reg = <0x00 0x01800000 0x00 0x10000>,	/* GICD */
 		      <0x00 0x01880000 0x00 0xc0000>,	/* GICR */
-		      <0x00 0x01880000 0x00 0xc0000>,   /* GICR */
 		      <0x01 0x00000000 0x00 0x2000>,    /* GICC */
 		      <0x01 0x00010000 0x00 0x1000>,    /* GICH */
 		      <0x01 0x00020000 0x00 0x2000>;    /* GICV */
@@ -142,8 +141,8 @@
 			compatible = "ti,am64-dmss-pktdma";
 			reg = <0x00 0x485c0000 0x00 0x100>,
 			      <0x00 0x4a800000 0x00 0x20000>,
-			      <0x00 0x4aa00000 0x00 0x40000>,
-			      <0x00 0x4b800000 0x00 0x400000>,
+			      <0x00 0x4aa00000 0x00 0x20000>,
+			      <0x00 0x4b800000 0x00 0x200000>,
 			      <0x00 0x485e0000 0x00 0x10000>,
 			      <0x00 0x484a0000 0x00 0x2000>,
 			      <0x00 0x484c0000 0x00 0x2000>,
@@ -640,6 +639,8 @@
 			interrupt-names = "host", "peripheral";
 			maximum-speed = "high-speed";
 			dr_mode = "otg";
+			snps,usb2-gadget-lpm-disable;
+			snps,usb2-lpm-disable;
 		};
 	};
 
@@ -663,6 +664,8 @@
 			interrupt-names = "host", "peripheral";
 			maximum-speed = "high-speed";
 			dr_mode = "otg";
+			snps,usb2-gadget-lpm-disable;
+			snps,usb2-lpm-disable;
 		};
 	};
 
@@ -779,9 +782,10 @@
 		      <0x00 0x30207000 0x00 0x1000>, /* ovr1 */
 		      <0x00 0x30208000 0x00 0x1000>, /* ovr2 */
 		      <0x00 0x3020a000 0x00 0x1000>, /* vp1: Used for OLDI */
-		      <0x00 0x3020b000 0x00 0x1000>; /* vp2: Used as DPI Out */
+		      <0x00 0x3020b000 0x00 0x1000>, /* vp2: Used as DPI Out */
+		      <0x00 0x30201000 0x00 0x1000>; /* common1 */
 		reg-names = "common", "vidl1", "vid",
-			    "ovr1", "ovr2", "vp1", "vp2";
+			    "ovr1", "ovr2", "vp1", "vp2", "common1";
 		power-domains = <&k3_pds 186 TI_SCI_PD_EXCLUSIVE>;
 		clocks = <&k3_clks 186 6>,
 			 <&dss_vp1_clk>,
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
@@ -60,7 +60,7 @@
 
 	memory@80000000 {
 		device_type = "memory";
-		reg = <0x00000000 0x80000000 0x00000000 0x40000000>; /* 1G RAM */
+		reg = <0x00000000 0x80000000 0x00000000 0x80000000>; /* 2G RAM */
 	};
 
 	opp-table {
@@ -134,7 +134,7 @@
 		regulator-max-microvolt = <3300000>;
 		regulator-min-microvolt = <3300000>;
 		regulator-name = "+V3.3_SD";
-		startup-delay-us = <2000>;
+		startup-delay-us = <20000>;
 	};
 
 	reg_sdhc1_vqmmc: regulator-sdhci1-vqmmc {
@@ -1322,8 +1322,6 @@
 	       0 0 0 0
 	>;
 	tdm-slots = <2>;
-	rx-num-evt = <32>;
-	tx-num-evt = <32>;
 	#sound-dai-cells = <0>;
 	status = "disabled";
 };
@@ -1340,8 +1338,6 @@
 	       0 0 0 0
 	>;
 	tdm-slots = <2>;
-	rx-num-evt = <32>;
-	tx-num-evt = <32>;
 	#sound-dai-cells = <0>;
 	status = "disabled";
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
@@ -935,6 +935,4 @@
 	       0 0 0 0
 	       0 0 0 0
 	>;
-	tx-num-evt = <32>;
-	rx-num-evt = <32>;
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -18,7 +18,6 @@
 		compatible = "arm,gic-v3";
 		reg = <0x00 0x01800000 0x00 0x10000>,	/* GICD */
 		      <0x00 0x01880000 0x00 0xc0000>,	/* GICR */
-		      <0x00 0x01880000 0x00 0xc0000>,   /* GICR */
 		      <0x01 0x00000000 0x00 0x2000>,    /* GICC */
 		      <0x01 0x00010000 0x00 0x1000>,    /* GICH */
 		      <0x01 0x00020000 0x00 0x2000>;    /* GICV */
@@ -121,8 +120,8 @@
 			compatible = "ti,am64-dmss-pktdma";
 			reg = <0x00 0x485c0000 0x00 0x100>,
 			      <0x00 0x4a800000 0x00 0x20000>,
-			      <0x00 0x4aa00000 0x00 0x40000>,
-			      <0x00 0x4b800000 0x00 0x400000>,
+			      <0x00 0x4aa00000 0x00 0x20000>,
+			      <0x00 0x4b800000 0x00 0x200000>,
 			      <0x00 0x485e0000 0x00 0x10000>,
 			      <0x00 0x484a0000 0x00 0x2000>,
 			      <0x00 0x484c0000 0x00 0x2000>,
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
@@ -580,6 +580,4 @@
 	       0 0 0 0
 	       0 0 0 0
 	>;
-	tx-num-evt = <32>;
-	rx-num-evt = <32>;
 };
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am62p-main.dtsi
@@ -123,8 +123,8 @@
 			compatible = "ti,am64-dmss-pktdma";
 			reg = <0x00 0x485c0000 0x00 0x100>,
 			      <0x00 0x4a800000 0x00 0x20000>,
-			      <0x00 0x4aa00000 0x00 0x40000>,
-			      <0x00 0x4b800000 0x00 0x400000>,
+			      <0x00 0x4aa00000 0x00 0x20000>,
+			      <0x00 0x4b800000 0x00 0x200000>,
 			      <0x00 0x485e0000 0x00 0x10000>,
 			      <0x00 0x484a0000 0x00 0x2000>,
 			      <0x00 0x484c0000 0x00 0x2000>,
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am62p-mcu.dtsi
@@ -187,6 +187,8 @@
 		ranges = <0x79000000 0x00 0x79000000 0x8000>,
 			 <0x79020000 0x00 0x79020000 0x8000>;
 		power-domains = <&k3_pds 7 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
+
 		mcu_r5fss0_core0: r5f@79000000 {
 			compatible = "ti,am62-r5f";
 			reg = <0x79000000 0x00008000>,
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am62p-wakeup.dtsi
@@ -78,6 +78,7 @@
 		ranges = <0x78000000 0x00 0x78000000 0x8000>,
 			 <0x78100000 0x00 0x78100000 0x8000>;
 		power-domains = <&k3_pds 119 TI_SCI_PD_EXCLUSIVE>;
+		status = "disabled";
 
 		wkup_r5fss0_core0: r5f@78000000 {
 			compatible = "ti,am62-r5f";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62p.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am62p.dtsi
@@ -71,7 +71,7 @@
 			 <0x00 0x43600000 0x00 0x43600000 0x00 0x00010000>, /* SA3 sproxy data */
 			 <0x00 0x44043000 0x00 0x44043000 0x00 0x00000fe0>, /* TI SCI DEBUG */
 			 <0x00 0x44860000 0x00 0x44860000 0x00 0x00040000>, /* SA3 sproxy config */
-			 <0x00 0x48000000 0x00 0x48000000 0x00 0x06400000>, /* DMSS */
+			 <0x00 0x48000000 0x00 0x48000000 0x00 0x06408000>, /* DMSS */
 			 <0x00 0x60000000 0x00 0x60000000 0x00 0x08000000>, /* FSS0 DAT1 */
 			 <0x00 0x70000000 0x00 0x70000000 0x00 0x00010000>, /* OCSRAM */
 			 <0x01 0x00000000 0x01 0x00000000 0x00 0x00310000>, /* A53 PERIPHBASE */
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -205,7 +205,7 @@
 		pinctrl-single,pins = <
 			AM62PX_IOPAD(0x0090, PIN_INPUT, 2) /* (U24) GPMC0_BE0n_CLE.MCASP1_ACLKX */
 			AM62PX_IOPAD(0x0098, PIN_INPUT, 2) /* (AA24) GPMC0_WAIT0.MCASP1_AFSX */
-			AM62PX_IOPAD(0x008c, PIN_INPUT, 2) /* (T25) GPMC0_WEn.MCASP1_AXR0 */
+			AM62PX_IOPAD(0x008c, PIN_OUTPUT, 2) /* (T25) GPMC0_WEn.MCASP1_AXR0 */
 			AM62PX_IOPAD(0x0084, PIN_INPUT, 2) /* (R25) GPMC0_ADVn_ALE.MCASP1_AXR2 */
 		>;
 	};
@@ -445,6 +445,10 @@
 };
 
 &cpsw3g_mdio {
+	pinctrl-names = "default";
+	pinctrl-0 = <&main_mdio1_pins_default>;
+	status = "okay";
+
 	cpsw3g_phy0: ethernet-phy@0 {
 		reg = <0>;
 		ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
@@ -476,8 +480,6 @@
 	       0 0 0 0
 	       0 0 0 0
 	>;
-	tx-num-evt = <32>;
-	rx-num-evt = <32>;
 };
 
 &fss {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
@@ -504,8 +504,6 @@
 	       0 0 0 0
 	       0 0 0 0
 	>;
-	tx-num-evt = <32>;
-	rx-num-evt = <32>;
 };
 
 &dss {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am64-main.dtsi
@@ -633,6 +633,9 @@
 		ti,otap-del-sel-mmc-hs = <0x0>;
 		ti,otap-del-sel-ddr52 = <0x6>;
 		ti,otap-del-sel-hs200 = <0x7>;
+		ti,itap-del-sel-legacy = <0x10>;
+		ti,itap-del-sel-mmc-hs = <0xa>;
+		ti,itap-del-sel-ddr52 = <0x3>;
 		status = "disabled";
 	};
 
@@ -645,12 +648,16 @@
 		clock-names = "clk_ahb", "clk_xin";
 		ti,trm-icp = <0x2>;
 		ti,otap-del-sel-legacy = <0x0>;
-		ti,otap-del-sel-sd-hs = <0xf>;
+		ti,otap-del-sel-sd-hs = <0x0>;
 		ti,otap-del-sel-sdr12 = <0xf>;
 		ti,otap-del-sel-sdr25 = <0xf>;
 		ti,otap-del-sel-sdr50 = <0xc>;
 		ti,otap-del-sel-sdr104 = <0x6>;
 		ti,otap-del-sel-ddr50 = <0x9>;
+		ti,itap-del-sel-legacy = <0x0>;
+		ti,itap-del-sel-sd-hs = <0x0>;
+		ti,itap-del-sel-sdr12 = <0x0>;
+		ti,itap-del-sel-sdr25 = <0x0>;
 		ti,clkbuf-sel = <0x7>;
 		status = "disabled";
 	};
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am65-main.dtsi
@@ -1019,9 +1019,10 @@
 		      <0x0 0x04a07000 0x0 0x1000>, /* ovr1 */
 		      <0x0 0x04a08000 0x0 0x1000>, /* ovr2 */
 		      <0x0 0x04a0a000 0x0 0x1000>, /* vp1 */
-		      <0x0 0x04a0b000 0x0 0x1000>; /* vp2 */
+		      <0x0 0x04a0b000 0x0 0x1000>, /* vp2 */
+		      <0x0 0x04a01000 0x0 0x1000>; /* common1 */
 		reg-names = "common", "vidl1", "vid",
-			"ovr1", "ovr2", "vp1", "vp2";
+			"ovr1", "ovr2", "vp1", "vp2", "common1";
 
 		ti,am65x-oldi-io-ctrl = <&dss_oldi_io_ctrl>;
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am654-idk.dtso
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am654-idk.dtso
@@ -58,9 +58,7 @@
 		       <&main_udmap 0xc107>, /* egress slice 1 */
 
 		       <&main_udmap 0x4100>, /* ingress slice 0 */
-		       <&main_udmap 0x4101>, /* ingress slice 1 */
-		       <&main_udmap 0x4102>, /* mgmnt rsp slice 0 */
-		       <&main_udmap 0x4103>; /* mgmnt rsp slice 1 */
+		       <&main_udmap 0x4101>; /* ingress slice 1 */
 		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
 			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
 			    "rx0", "rx1";
@@ -126,9 +124,7 @@
 		       <&main_udmap 0xc207>, /* egress slice 1 */
 
 		       <&main_udmap 0x4200>, /* ingress slice 0 */
-		       <&main_udmap 0x4201>, /* ingress slice 1 */
-		       <&main_udmap 0x4202>, /* mgmnt rsp slice 0 */
-		       <&main_udmap 0x4203>; /* mgmnt rsp slice 1 */
+		       <&main_udmap 0x4201>; /* ingress slice 1 */
 		dma-names = "tx0-0", "tx0-1", "tx0-2", "tx0-3",
 			    "tx1-0", "tx1-1", "tx1-2", "tx1-3",
 			    "rx0", "rx1";
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-am69-sk.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-am69-sk.dts
@@ -646,7 +646,7 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&pmic_irq_pins_default>;
 		interrupt-parent = <&wkup_gpio0>;
-		interrupts = <39 IRQ_TYPE_EDGE_FALLING>;
+		interrupts = <83 IRQ_TYPE_EDGE_FALLING>;
 		gpio-controller;
 		#gpio-cells = <2>;
 		ti,primary-pmic;
@@ -918,13 +918,9 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&dss_vout0_pins_default>;
 	assigned-clocks = <&k3_clks 218 2>,
-			  <&k3_clks 218 5>,
-			  <&k3_clks 218 14>,
-			  <&k3_clks 218 18>;
+			  <&k3_clks 218 5>;
 	assigned-clock-parents = <&k3_clks 218 3>,
-				 <&k3_clks 218 7>,
-				 <&k3_clks 218 16>,
-				 <&k3_clks 218 22>;
+				 <&k3_clks 218 7>;
 };
 
 &serdes_wiz4 {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
@@ -91,24 +91,25 @@
 };
 
 &wkup_pmx0 {
+};
+
+&wkup_pmx2 {
 	mcu_uart0_pins_default: mcu-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721E_WKUP_IOPAD(0xf4, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
-			J721E_WKUP_IOPAD(0xf0, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
-			J721E_WKUP_IOPAD(0xf8, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
-			J721E_WKUP_IOPAD(0xfc, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
+			J721E_WKUP_IOPAD(0x90, PIN_INPUT, 0) /* (E20) MCU_UART0_CTSn */
+			J721E_WKUP_IOPAD(0x94, PIN_OUTPUT, 0) /* (E21) MCU_UART0_RTSn */
+			J721E_WKUP_IOPAD(0x8c, PIN_INPUT, 0) /* (D20) MCU_UART0_RXD */
+			J721E_WKUP_IOPAD(0x88, PIN_OUTPUT, 0) /* (D19) MCU_UART0_TXD */
 		>;
 	};
 
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721E_WKUP_IOPAD(0xb0, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
-			J721E_WKUP_IOPAD(0xb4, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
+			J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (B14) WKUP_UART0_RXD */
+			J721E_WKUP_IOPAD(0x4c, PIN_OUTPUT, 0) /* (A14) WKUP_UART0_TXD */
 		>;
 	};
-};
 
-&wkup_pmx2 {
 	mcu_cpsw_pins_default: mcu-cpsw-default-pins {
 		pinctrl-single,pins = <
 			J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_RGMII1_TX_CTL */
@@ -191,7 +192,7 @@
 	};
 };
 
-&main_pmx1 {
+&main_pmx2 {
 	main_usbss0_pins_default: main-usbss0-default-pins {
 		pinctrl-single,pins = <
 			J721E_IOPAD(0x04, PIN_OUTPUT, 0) /* (T4) USB0_DRVVBUS */
@@ -210,7 +211,6 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&mcu_uart0_pins_default>;
-	clock-frequency = <96000000>;
 };
 
 &main_uart0 {
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi
@@ -399,7 +399,7 @@
 
 	/* TIMERIO pad input CTRLMMR_TIMER*_CTRL registers */
 	main_timerio_input: pinctrl@104200 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		reg = <0x0 0x104200 0x0 0x50>;
 		#pinctrl-cells = <1>;
 		pinctrl-single,register-width = <32>;
@@ -408,7 +408,7 @@
 
 	/* TIMERIO pad output CTCTRLMMR_TIMERIO*_CTRL registers */
 	main_timerio_output: pinctrl@104280 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		reg = <0x0 0x104280 0x0 0x20>;
 		#pinctrl-cells = <1>;
 		pinctrl-single,register-width = <32>;
@@ -416,7 +416,7 @@
 	};
 
 	main_pmx0: pinctrl@11c000 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		/* Proxy 0 addressing */
 		reg = <0x00 0x11c000 0x00 0x10c>;
 		#pinctrl-cells = <1>;
@@ -424,10 +424,28 @@
 		pinctrl-single,function-mask = <0xffffffff>;
 	};
 
-	main_pmx1: pinctrl@11c11c {
-		compatible = "pinctrl-single";
+	main_pmx1: pinctrl@11c110 {
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		/* Proxy 0 addressing */
-		reg = <0x00 0x11c11c 0x00 0xc>;
+		reg = <0x00 0x11c110 0x00 0x004>;
+		#pinctrl-cells = <1>;
+		pinctrl-single,register-width = <32>;
+		pinctrl-single,function-mask = <0xffffffff>;
+	};
+
+	main_pmx2: pinctrl@11c11c {
+		compatible = "ti,j7200-padconf", "pinctrl-single";
+		/* Proxy 0 addressing */
+		reg = <0x00 0x11c11c 0x00 0x00c>;
+		#pinctrl-cells = <1>;
+		pinctrl-single,register-width = <32>;
+		pinctrl-single,function-mask = <0xffffffff>;
+	};
+
+	main_pmx3: pinctrl@11c164 {
+		compatible = "ti,j7200-padconf", "pinctrl-single";
+		/* Proxy 0 addressing */
+		reg = <0x00 0x11c164 0x00 0x008>;
 		#pinctrl-cells = <1>;
 		pinctrl-single,register-width = <32>;
 		pinctrl-single,function-mask = <0xffffffff>;
@@ -902,7 +920,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 266 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 266 1>;
+		clocks = <&k3_clks 266 4>;
 		status = "disabled";
 	};
 
@@ -913,7 +931,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 267 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 267 1>;
+		clocks = <&k3_clks 267 4>;
 		status = "disabled";
 	};
 
@@ -924,7 +942,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 268 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 268 1>;
+		clocks = <&k3_clks 268 4>;
 		status = "disabled";
 	};
 
@@ -935,7 +953,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 269 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 269 1>;
+		clocks = <&k3_clks 269 4>;
 		status = "disabled";
 	};
 
@@ -946,7 +964,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 270 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 270 1>;
+		clocks = <&k3_clks 270 2>;
 		status = "disabled";
 	};
 
@@ -957,7 +975,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 271 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 271 1>;
+		clocks = <&k3_clks 271 4>;
 		status = "disabled";
 	};
 
@@ -968,7 +986,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 272 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 272 1>;
+		clocks = <&k3_clks 272 4>;
 		status = "disabled";
 	};
 
@@ -979,7 +997,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 273 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 273 1>;
+		clocks = <&k3_clks 273 4>;
 		status = "disabled";
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-j7200-mcu-wakeup.dtsi
@@ -192,7 +192,7 @@
 
 	/* MCU_TIMERIO pad input CTRLMMR_MCU_TIMER*_CTRL registers */
 	mcu_timerio_input: pinctrl@40f04200 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		reg = <0x0 0x40f04200 0x0 0x28>;
 		#pinctrl-cells = <1>;
 		pinctrl-single,register-width = <32>;
@@ -202,7 +202,7 @@
 
 	/* MCU_TIMERIO pad output CTRLMMR_MCU_TIMERIO*_CTRL registers */
 	mcu_timerio_output: pinctrl@40f04280 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		reg = <0x0 0x40f04280 0x0 0x28>;
 		#pinctrl-cells = <1>;
 		pinctrl-single,register-width = <32>;
@@ -211,7 +211,7 @@
 	};
 
 	wkup_pmx0: pinctrl@4301c000 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		/* Proxy 0 addressing */
 		reg = <0x00 0x4301c000 0x00 0x34>;
 		#pinctrl-cells = <1>;
@@ -220,7 +220,7 @@
 	};
 
 	wkup_pmx1: pinctrl@4301c038 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		/* Proxy 0 addressing */
 		reg = <0x00 0x4301c038 0x00 0x8>;
 		#pinctrl-cells = <1>;
@@ -229,7 +229,7 @@
 	};
 
 	wkup_pmx2: pinctrl@4301c068 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		/* Proxy 0 addressing */
 		reg = <0x00 0x4301c068 0x00 0xec>;
 		#pinctrl-cells = <1>;
@@ -238,7 +238,7 @@
 	};
 
 	wkup_pmx3: pinctrl@4301c174 {
-		compatible = "pinctrl-single";
+		compatible = "ti,j7200-padconf", "pinctrl-single";
 		/* Proxy 0 addressing */
 		reg = <0x00 0x4301c174 0x00 0x20>;
 		#pinctrl-cells = <1>;
@@ -492,7 +492,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 274 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 274 0>;
+		clocks = <&k3_clks 274 4>;
 		status = "disabled";
 	};
 
@@ -503,7 +503,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 275 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 275 0>;
+		clocks = <&k3_clks 275 4>;
 		status = "disabled";
 	};
 
@@ -514,7 +514,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 276 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 276 0>;
+		clocks = <&k3_clks 276 2>;
 		status = "disabled";
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-j721e-beagleboneai64.dts
@@ -123,7 +123,7 @@
 			no-map;
 		};
 
-		c66_1_dma_memory_region: c66-dma-memory@a6000000 {
+		c66_0_dma_memory_region: c66-dma-memory@a6000000 {
 			compatible = "shared-dma-pool";
 			reg = <0x00 0xa6000000 0x00 0x100000>;
 			no-map;
@@ -135,7 +135,7 @@
 			no-map;
 		};
 
-		c66_0_dma_memory_region: c66-dma-memory@a7000000 {
+		c66_1_dma_memory_region: c66-dma-memory@a7000000 {
 			compatible = "shared-dma-pool";
 			reg = <0x00 0xa7000000 0x00 0x100000>;
 			no-map;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-j721e-mcu-wakeup.dtsi
@@ -353,9 +353,9 @@
 
 		hbmc_mux: mux-controller@47000004 {
 			compatible = "reg-mux";
-			reg = <0x00 0x47000004 0x00 0x2>;
+			reg = <0x00 0x47000004 0x00 0x4>;
 			#mux-control-cells = <1>;
-			mux-reg-masks = <0x4 0x2>; /* HBMC select */
+			mux-reg-masks = <0x0 0x2>; /* HBMC select */
 		};
 
 		hbmc: hyperbus@47034000 {
@@ -648,7 +648,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 274 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 274 0>;
+		clocks = <&k3_clks 274 1>;
 		status = "disabled";
 	};
 
@@ -659,7 +659,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 275 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 275 0>;
+		clocks = <&k3_clks 275 1>;
 		status = "disabled";
 	};
 
@@ -670,7 +670,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 276 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 276 0>;
+		clocks = <&k3_clks 276 1>;
 		status = "disabled";
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-j721e-sk.dts
@@ -119,7 +119,7 @@
 			no-map;
 		};
 
-		c66_1_dma_memory_region: c66-dma-memory@a6000000 {
+		c66_0_dma_memory_region: c66-dma-memory@a6000000 {
 			compatible = "shared-dma-pool";
 			reg = <0x00 0xa6000000 0x00 0x100000>;
 			no-map;
@@ -131,7 +131,7 @@
 			no-map;
 		};
 
-		c66_0_dma_memory_region: c66-dma-memory@a7000000 {
+		c66_1_dma_memory_region: c66-dma-memory@a7000000 {
 			compatible = "shared-dma-pool";
 			reg = <0x00 0xa7000000 0x00 0x100000>;
 			no-map;
@@ -574,7 +574,7 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&pmic_irq_pins_default>;
 		interrupt-parent = <&wkup_gpio0>;
-		interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+		interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
 		gpio-controller;
 		#gpio-cells = <2>;
 		ti,primary-pmic;
@@ -651,7 +651,7 @@
 		reg = <0x4c>;
 		system-power-controller;
 		interrupt-parent = <&wkup_gpio0>;
-		interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
+		interrupts = <7 IRQ_TYPE_EDGE_FALLING>;
 		gpio-controller;
 		#gpio-cells = <2>;
 		buck1234-supply = <&vsys_3v3>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
@@ -190,8 +190,6 @@
 &wkup_pmx2 {
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		pinctrl-single,pins = <
-			J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (E25) WKUP_GPIO0_6.WKUP_UART0_CTSn */
-			J721S2_WKUP_IOPAD(0x074, PIN_OUTPUT, 0) /* (F28) WKUP_GPIO0_7.WKUP_UART0_RTSn */
 			J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (D28) WKUP_UART0_RXD */
 			J721S2_WKUP_IOPAD(0x04c, PIN_OUTPUT, 0) /* (D27) WKUP_UART0_TXD */
 		>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
@@ -1591,7 +1591,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 339 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 339 1>;
+		clocks = <&k3_clks 339 2>;
 		status = "disabled";
 	};
 
@@ -1602,7 +1602,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 340 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 340 1>;
+		clocks = <&k3_clks 340 2>;
 		status = "disabled";
 	};
 
@@ -1613,7 +1613,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 341 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 341 1>;
+		clocks = <&k3_clks 341 2>;
 		status = "disabled";
 	};
 
@@ -1624,7 +1624,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 342 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 342 1>;
+		clocks = <&k3_clks 342 2>;
 		status = "disabled";
 	};
 
@@ -1635,7 +1635,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 343 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 343 1>;
+		clocks = <&k3_clks 343 2>;
 		status = "disabled";
 	};
 
@@ -1646,7 +1646,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 344 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 344 1>;
+		clocks = <&k3_clks 344 2>;
 		status = "disabled";
 	};
 
@@ -1657,7 +1657,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 345 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 345 1>;
+		clocks = <&k3_clks 345 2>;
 		status = "disabled";
 	};
 
@@ -1668,7 +1668,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 346 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 346 1>;
+		clocks = <&k3_clks 346 2>;
 		status = "disabled";
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-j721s2-mcu-wakeup.dtsi
@@ -423,7 +423,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 347 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 347 0>;
+		clocks = <&k3_clks 347 2>;
 		status = "disabled";
 	};
 
@@ -434,7 +434,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 348 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 348 0>;
+		clocks = <&k3_clks 348 2>;
 		status = "disabled";
 	};
 
@@ -445,7 +445,7 @@
 		#address-cells = <1>;
 		#size-cells = <0>;
 		power-domains = <&k3_pds 349 TI_SCI_PD_EXCLUSIVE>;
-		clocks = <&k3_clks 349 0>;
+		clocks = <&k3_clks 349 2>;
 		status = "disabled";
 	};
 
@@ -663,7 +663,7 @@
 		compatible = "ti,j7200-vtm";
 		reg = <0x00 0x42040000 0x0 0x350>,
 		      <0x00 0x42050000 0x0 0x350>;
-		power-domains = <&k3_pds 154 TI_SCI_PD_SHARED>;
+		power-domains = <&k3_pds 180 TI_SCI_PD_SHARED>;
 		#thermal-sensor-cells = <1>;
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
@@ -335,8 +335,6 @@
 	wkup_uart0_pins_default: wkup-uart0-default-pins {
 		bootph-all;
 		pinctrl-single,pins = <
-			J721S2_WKUP_IOPAD(0x070, PIN_INPUT, 0) /* (L37) WKUP_GPIO0_6.WKUP_UART0_CTSn */
-			J721S2_WKUP_IOPAD(0x074, PIN_INPUT, 0) /* (L36) WKUP_GPIO0_7.WKUP_UART0_RTSn */
 			J721S2_WKUP_IOPAD(0x048, PIN_INPUT, 0) /* (K35) WKUP_UART0_RXD */
 			J721S2_WKUP_IOPAD(0x04c, PIN_INPUT, 0) /* (K34) WKUP_UART0_TXD */
 		>;
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi
@@ -52,12 +52,12 @@
 			compatible = "reg-mux";
 			reg = <0x00004080 0x30>;
 			#mux-control-cells = <1>;
-			mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */
-					<0x4088 0x3>, <0x408c 0x3>, /* SERDES0 lane2/3 select */
-					<0x4090 0x3>, <0x4094 0x3>, /* SERDES1 lane0/1 select */
-					<0x4098 0x3>, <0x409c 0x3>, /* SERDES1 lane2/3 select */
-					<0x40a0 0x3>, <0x40a4 0x3>, /* SERDES2 lane0/1 select */
-					<0x40a8 0x3>, <0x40ac 0x3>; /* SERDES2 lane2/3 select */
+			mux-reg-masks = <0x0 0x3>, <0x4 0x3>, /* SERDES0 lane0/1 select */
+					<0x8 0x3>, <0xc 0x3>, /* SERDES0 lane2/3 select */
+					<0x10 0x3>, <0x14 0x3>, /* SERDES1 lane0/1 select */
+					<0x18 0x3>, <0x1c 0x3>, /* SERDES1 lane2/3 select */
+					<0x20 0x3>, <0x24 0x3>, /* SERDES2 lane0/1 select */
+					<0x28 0x3>, <0x2c 0x3>; /* SERDES2 lane2/3 select */
 			idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>,
 				      <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
 				      <J784S4_SERDES0_LANE2_IP3_UNUSED>,
--- linux-qcom-6.8.0.orig/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
+++ linux-qcom-6.8.0/arch/arm64/boot/dts/ti/k3-j784s4-mcu-wakeup.dtsi
@@ -628,7 +628,7 @@
 		compatible = "ti,j7200-vtm";
 		reg = <0x00 0x42040000 0x00 0x350>,
 		      <0x00 0x42050000 0x00 0x350>;
-		power-domains = <&k3_pds 154 TI_SCI_PD_SHARED>;
+		power-domains = <&k3_pds 243 TI_SCI_PD_SHARED>;
 		#thermal-sensor-cells = <1>;
 	};
 
--- linux-qcom-6.8.0.orig/arch/arm64/configs/defconfig
+++ linux-qcom-6.8.0/arch/arm64/configs/defconfig
@@ -253,6 +253,7 @@
 CONFIG_MTK_ADSP_IPC=m
 CONFIG_EFI_CAPSULE_LOADER=y
 CONFIG_IMX_SCU=y
+CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y
 CONFIG_QCOM_QSEECOM=y
 CONFIG_QCOM_QSEECOM_UEFISECAPP=y
 CONFIG_GNSS=m
@@ -588,6 +589,7 @@
 CONFIG_PINCTRL_MSM8998=y
 CONFIG_PINCTRL_QCM2290=y
 CONFIG_PINCTRL_QCS404=y
+CONFIG_PINCTRL_QCS615=y
 CONFIG_PINCTRL_QDF2XXX=y
 CONFIG_PINCTRL_QDU1000=y
 CONFIG_PINCTRL_SA8775P=y
@@ -632,6 +634,7 @@
 CONFIG_GPIO_UNIPHIER=y
 CONFIG_GPIO_VISCONTI=y
 CONFIG_GPIO_WCD934X=m
+CONFIG_GPIO_VF610=y
 CONFIG_GPIO_XGENE=y
 CONFIG_GPIO_XGENE_SB=y
 CONFIG_GPIO_MAX732X=y
@@ -857,6 +860,7 @@
 CONFIG_DRM_PANEL_EDP=m
 CONFIG_DRM_PANEL_ILITEK_ILI9882T=m
 CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
+CONFIG_DRM_PANEL_NOVATEK_NT36672E=m
 CONFIG_DRM_PANEL_RAYDIUM_RM67191=m
 CONFIG_DRM_PANEL_SITRONIX_ST7703=m
 CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
@@ -1264,8 +1268,15 @@
 CONFIG_MSM_MMCC_8998=m
 CONFIG_QCM_GCC_2290=y
 CONFIG_QCM_DISPCC_2290=m
+CONFIG_QCS_DISPCC_615=m
+CONFIG_QCS_CAMCC_615=m
 CONFIG_QCS_GCC_404=y
+CONFIG_QCS_GCC_615=y
+CONFIG_SC_CAMCC_7280=m
+CONFIG_QDU_GCC_1000=y
 CONFIG_SC_CAMCC_8280XP=m
+CONFIG_QCS_GPUCC_615=m
+CONFIG_QCS_VIDEOCC_615=m
 CONFIG_SC_DISPCC_8280XP=m
 CONFIG_SA_GCC_8775P=y
 CONFIG_SA_GPUCC_8775P=m
@@ -1275,6 +1286,8 @@
 CONFIG_SC_GCC_8280XP=y
 CONFIG_SC_GPUCC_8280XP=m
 CONFIG_SC_LPASSCC_8280XP=m
+CONFIG_SC_LPASS_CORECC_7280=m
+CONFIG_SC_VIDEOCC_7280=m
 CONFIG_SDM_CAMCC_845=m
 CONFIG_SDM_GPUCC_845=y
 CONFIG_SDM_VIDEOCC_845=y
@@ -1552,6 +1565,8 @@
 CONFIG_INTERCONNECT_QCOM_OSM_L3=m
 CONFIG_INTERCONNECT_QCOM_QCM2290=m
 CONFIG_INTERCONNECT_QCOM_QCS404=m
+CONFIG_INTERCONNECT_QCOM_QCS615=y
+CONFIG_INTERCONNECT_QCOM_QDU1000=y
 CONFIG_INTERCONNECT_QCOM_SA8775P=y
 CONFIG_INTERCONNECT_QCOM_SC7180=y
 CONFIG_INTERCONNECT_QCOM_SC7280=y
@@ -1559,6 +1574,7 @@
 CONFIG_INTERCONNECT_QCOM_SC8280XP=y
 CONFIG_INTERCONNECT_QCOM_SDM845=y
 CONFIG_INTERCONNECT_QCOM_SDX75=y
+CONFIG_INTERCONNECT_QCOM_SM6115=y
 CONFIG_INTERCONNECT_QCOM_SM8150=m
 CONFIG_INTERCONNECT_QCOM_SM8250=m
 CONFIG_INTERCONNECT_QCOM_SM8350=m
--- linux-qcom-6.8.0.orig/arch/arm64/configs/qcom_addons.config
+++ linux-qcom-6.8.0/arch/arm64/configs/qcom_addons.config
@@ -0,0 +1,56 @@
+CONFIG_BACKLIGHT_QCOM_WLED=y
+CONFIG_CAN_GS_USB=m
+CONFIG_CORESIGHT_REMOTE_ETM=m
+CONFIG_CORESIGHT_TGU=m
+CONFIG_GH_VIRT_WATCHDOG=y
+CONFIG_GUNYAH=y
+CONFIG_GUNYAH_DRIVERS=y
+CONFIG_GUNYAH_IOEVENTFD=y
+CONFIG_GUNYAH_IRQFD=y
+CONFIG_GUNYAH_PLATFORM_HOOKS=y
+CONFIG_GUNYAH_QCOM_PLATFORM=y
+CONFIG_GUNYAH_VCPU=y
+CONFIG_MFD_I2C_PMIC=y
+CONFIG_MSM_RDBG=m
+CONFIG_PANIC_TIMEOUT=-1
+CONFIG_PINCTRL_QCS8300_LPASS_LPI=m
+CONFIG_PINCTRL_SA8775P_LPASS_LPI=m
+CONFIG_QCOM_DCC=y
+CONFIG_QCOM_DMABUF_HEAPS=y
+CONFIG_QCOM_DMABUF_HEAPS_CMA=y
+CONFIG_QCOM_DMABUF_HEAPS_SYSTEM=y
+CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_SECURE=y
+# CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC=y
+CONFIG_QCOM_MEMORY_DUMP_V2=y
+CONFIG_QCOM_MEM_BUF=y
+CONFIG_QCOM_MEM_BUF_DEV=y
+CONFIG_QCOM_PANEL_EVENT_NOTIFIER=m
+CONFIG_QCOM_PMIC_PDCHARGER_ULOG=y
+CONFIG_QCOM_QMI_COOLING=m
+CONFIG_QCOM_QPS615_PCIE_SWITCH=y
+CONFIG_QCOM_SCM_ADDON=y
+CONFIG_QCOM_SECURE_BUFFER=y
+CONFIG_QCOM_SI_CORE=m
+CONFIG_QCOM_SI_CORE_MEM_OBJECT=m
+CONFIG_QCOM_SI_CORE_WQ=y
+CONFIG_QCOM_SI_CORE_XTS=m
+CONFIG_QCOM_SMP2P_SLEEPSTATE=y
+CONFIG_QCOM_SOC_DEBUG=y
+CONFIG_QCOM_SPMI_ADC5_GEN3=m
+CONFIG_QCOM_SPMI_MBG_TM=m
+CONFIG_QCOM_WDT=y
+CONFIG_QCOM_WDT_CORE=y
+CONFIG_QTI_BCL_PMIC5=y
+CONFIG_QTI_DEVFREQ_CDEV=m
+CONFIG_QTI_TZ_LOG=m
+CONFIG_REGULATOR_DEBUG_CONTROL=y
+CONFIG_REGULATOR_PROXY_CONSUMER=y
+CONFIG_REGULATOR_QCOM_PM8008=y
+CONFIG_REGULATOR_QPNP_LCDB=y
+CONFIG_SND_SOC_MSM_STUB=y
+CONFIG_STM_PROTO_OST=m
+CONFIG_USB_F_QDSS=m
+CONFIG_USB_HUB_USB5807=m
+CONFIG_VIRT_DRIVERS=y
+CONFIG_SENSORS_EMC2305=y
+CONFIG_SND_SOC_QCS9100=m
--- linux-qcom-6.8.0.orig/arch/arm64/configs/qcom_debug.config
+++ linux-qcom-6.8.0/arch/arm64/configs/qcom_debug.config
@@ -0,0 +1,34 @@
+CONFIG_ATH11K_COREDUMP=y
+CONFIG_ATH11K_DEBUG=y
+CONFIG_ATH11K_DEBUGFS=y
+CONFIG_ATH11K_TRACING=y
+CONFIG_BUG_ON_DATA_CORRUPTION=y
+CONFIG_CMA_DEBUG=y
+CONFIG_CMA_DEBUGFS=y
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
+CONFIG_CORESIGHT_SOURCE_ETM4X=m
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_OBJECTS=y
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DMABUF_SYSFS_STATS=y
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_EFI_VARS_PSTORE is not set
+# CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE is not set
+# CONFIG_FW_LOADER_DEBUG is not set
+CONFIG_HARDLOCKUP_DETECTOR=y
+CONFIG_LOCALVERSION="-debug"
+CONFIG_MAC80211_DEBUGFS=y
+CONFIG_PAGE_POISONING=y
+CONFIG_PID_IN_CONTEXTIDR=y
+CONFIG_PSTORE=y
+# CONFIG_PSTORE_BLK is not set
+# CONFIG_PSTORE_COMPRESS is not set
+CONFIG_PSTORE_CONSOLE=y
+CONFIG_PSTORE_DEFAULT_KMSG_BYTES=10240
+CONFIG_PSTORE_PMSG=y
+CONFIG_REED_SOLOMON=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
--- linux-qcom-6.8.0.orig/arch/arm64/configs/qcom_defconfig
+++ linux-qcom-6.8.0/arch/arm64/configs/qcom_defconfig
@@ -0,0 +1,904 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_AUDIT=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
+CONFIG_BPF_JIT=y
+CONFIG_PREEMPT=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOCALVERSION="-perf"
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_UCLAMP_TASK=y
+CONFIG_NUMA_BALANCING=y
+CONFIG_CGROUP_FAVOR_DYNMODS=y
+CONFIG_MEMCG=y
+CONFIG_BLK_CGROUP=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_UCLAMP_TASK_GROUP=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_HUGETLB=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
+CONFIG_CGROUP_BPF=y
+CONFIG_USER_NS=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_BOOT_CONFIG=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_PROFILING=y
+CONFIG_ARCH_QCOM=y
+CONFIG_SCHED_MC=y
+CONFIG_SCHED_SMT=y
+CONFIG_NUMA=y
+CONFIG_XEN=y
+CONFIG_ARM64_SW_TTBR0_PAN=y
+CONFIG_COMPAT=y
+CONFIG_RANDOMIZE_BASE=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
+CONFIG_ENERGY_MODEL=y
+CONFIG_ARM_PSCI_CPUIDLE=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_ACPI_CPPC_CPUFREQ=m
+CONFIG_ARM_SCPI_CPUFREQ=y
+CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
+CONFIG_ARM_QCOM_CPUFREQ_HW=y
+CONFIG_ARM_SCMI_CPUFREQ=y
+CONFIG_ACPI=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM=y
+CONFIG_KPROBES=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_BLK_INLINE_ENCRYPTION=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_SLAB_FREELIST_RANDOM=y
+CONFIG_SLAB_FREELIST_HARDENED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_KSM=y
+CONFIG_MEMORY_FAILURE=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_CMA=y
+CONFIG_CMA_DEBUG=y
+CONFIG_CMA_SYSFS=y
+CONFIG_CMA_AREAS=32
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IPV6=m
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE_NETFILTER=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NETFILTER_XT_MARK=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_IP_VS=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_NAT=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_NET_DSA=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_VLAN_8021Q_MVRP=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBS=m
+CONFIG_NET_SCH_ETF=m
+CONFIG_NET_SCH_TAPRIO=m
+CONFIG_NET_SCH_MQPRIO=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_FLOWER=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_BPF=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=m
+CONFIG_NET_CLS_MATCHALL=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_GATE=m
+CONFIG_VSOCKETS=y
+CONFIG_QRTR_SMD=m
+CONFIG_QRTR_TUN=m
+CONFIG_CAN=m
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+# CONFIG_BT_LE is not set
+CONFIG_BT_LEDS=y
+# CONFIG_BT_DEBUGFS is not set
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIUART_QCA=y
+CONFIG_BT_QCOMSMD=m
+CONFIG_CFG80211=m
+CONFIG_NL80211_TESTMODE=y
+CONFIG_CFG80211_CERTIFICATION_ONUS=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_LEDS=y
+CONFIG_RFKILL=m
+CONFIG_NET_9P=y
+CONFIG_NET_9P_VIRTIO=y
+CONFIG_NFC=m
+CONFIG_NFC_NCI=m
+CONFIG_NFC_S3FWRN5_I2C=m
+CONFIG_PAGE_POOL_STATS=y
+CONFIG_PCI=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+CONFIG_PCI_IOV=y
+CONFIG_PCI_PASID=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_ACPI=y
+CONFIG_PCI_HOST_GENERIC=y
+CONFIG_PCIE_DW_PLAT_HOST=y
+CONFIG_PCIE_QCOM=y
+CONFIG_PCI_ENDPOINT=y
+CONFIG_PCI_ENDPOINT_CONFIGFS=y
+CONFIG_PCI_EPF_TEST=m
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_FW_LOADER_USER_HELPER=y
+CONFIG_MHI_BUS_PCI_GENERIC=m
+CONFIG_MHI_BUS_EP=y
+CONFIG_ARM_SCMI_PROTOCOL=y
+CONFIG_ARM_SCPI_PROTOCOL=y
+# CONFIG_EFI_DISABLE_RUNTIME is not set
+CONFIG_GNSS=m
+CONFIG_ZRAM=m
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=m
+CONFIG_VIRTIO_BLK=y
+CONFIG_BLK_DEV_NVME=m
+CONFIG_QCOM_COINCELL=m
+CONFIG_QCOM_FASTRPC=m
+CONFIG_SRAM=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_BSG=y
+CONFIG_SCSI_SAS_ATA=y
+CONFIG_SCSI_HISI_SAS=y
+CONFIG_SCSI_HISI_SAS_PCI=y
+CONFIG_MEGARAID_SAS=y
+CONFIG_SCSI_MPT3SAS=m
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_CEVA=y
+CONFIG_SATA_SIL24=y
+CONFIG_PATA_OF_PLATFORM=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_NETDEVICES=y
+CONFIG_MACVLAN=y
+CONFIG_MACVTAP=y
+CONFIG_TUN=y
+CONFIG_VETH=m
+CONFIG_VIRTIO_NET=y
+CONFIG_MHI_NET=m
+CONFIG_ATL1C=m
+CONFIG_QCOM_EMAC=m
+CONFIG_RMNET=m
+CONFIG_QCOM_IPA=m
+CONFIG_AT803X_PHY=m
+CONFIG_REALTEK_PHY=m
+CONFIG_CAN_MCP251XFD=m
+CONFIG_MDIO_BITBANG=m
+CONFIG_MDIO_GPIO=m
+CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m
+CONFIG_MDIO_BUS_MUX_MMIOREG=m
+CONFIG_USB_USBNET=m
+CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y
+CONFIG_ATH10K=m
+CONFIG_ATH10K_PCI=m
+CONFIG_ATH10K_SDIO=m
+CONFIG_ATH10K_SNOC=m
+CONFIG_WCN36XX=m
+CONFIG_ATH11K=m
+CONFIG_ATH11K_AHB=m
+CONFIG_ATH11K_PCI=m
+CONFIG_WWAN=m
+CONFIG_MHI_WWAN_CTRL=m
+CONFIG_MHI_WWAN_MBIM=m
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_KEYBOARD_ADC=m
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PM8941_PWRKEY=y
+CONFIG_INPUT_PM8XXX_VIBRATOR=y
+CONFIG_INPUT_PWM_BEEPER=m
+CONFIG_INPUT_PWM_VIBRA=m
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_QCOM_GENI=y
+CONFIG_SERIAL_QCOM_GENI_CONSOLE=y
+CONFIG_NULL_TTY=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_IPMI_HANDLER=m
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_VIRTIO=y
+# CONFIG_DEVMEM is not set
+CONFIG_TCG_TPM=y
+CONFIG_TCG_TIS=m
+CONFIG_TCG_TIS_SPI=m
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_GPIO=m
+CONFIG_I2C_QCOM_CCI=m
+CONFIG_I2C_QCOM_GENI=m
+CONFIG_I2C_QUP=y
+CONFIG_I2C_SLAVE=y
+CONFIG_I3C=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_SPI_QCOM_QSPI=m
+CONFIG_SPI_QUP=y
+CONFIG_SPI_QCOM_GENI=m
+CONFIG_SPI_SPIDEV=m
+CONFIG_SPMI=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_PINCTRL_MSM=y
+CONFIG_PINCTRL_IPQ5332=y
+CONFIG_PINCTRL_IPQ8074=y
+CONFIG_PINCTRL_IPQ6018=y
+CONFIG_PINCTRL_IPQ9574=y
+CONFIG_PINCTRL_MSM8916=y
+CONFIG_PINCTRL_MSM8953=y
+CONFIG_PINCTRL_MSM8976=y
+CONFIG_PINCTRL_MSM8994=y
+CONFIG_PINCTRL_MSM8996=y
+CONFIG_PINCTRL_MSM8998=y
+CONFIG_PINCTRL_QCM2290=y
+CONFIG_PINCTRL_QCS404=y
+CONFIG_PINCTRL_QCS615=y
+CONFIG_PINCTRL_QCS8300=y
+CONFIG_PINCTRL_QDF2XXX=y
+CONFIG_PINCTRL_QDU1000=y
+CONFIG_PINCTRL_SA8775P=y
+CONFIG_PINCTRL_SC7180=y
+CONFIG_PINCTRL_SC7280=y
+CONFIG_PINCTRL_SC8180X=y
+CONFIG_PINCTRL_SC8280XP=y
+CONFIG_PINCTRL_SDM660=y
+CONFIG_PINCTRL_SDM670=y
+CONFIG_PINCTRL_SDM845=y
+CONFIG_PINCTRL_SM6115=y
+CONFIG_PINCTRL_SM6125=y
+CONFIG_PINCTRL_SM6350=y
+CONFIG_PINCTRL_SM6375=y
+CONFIG_PINCTRL_SM8150=y
+CONFIG_PINCTRL_SM8250=y
+CONFIG_PINCTRL_SM8350=y
+CONFIG_PINCTRL_SM8450=y
+CONFIG_PINCTRL_SM8550=y
+CONFIG_PINCTRL_SM8650=y
+CONFIG_PINCTRL_X1E80100=y
+CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+CONFIG_PINCTRL_LPASS_LPI=m
+CONFIG_PINCTRL_SC7280_LPASS_LPI=m
+CONFIG_PINCTRL_SM8250_LPASS_LPI=m
+CONFIG_PINCTRL_SM8450_LPASS_LPI=m
+CONFIG_PINCTRL_SC8280XP_LPASS_LPI=m
+CONFIG_PINCTRL_SM8550_LPASS_LPI=m
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_PL061=y
+CONFIG_GPIO_WCD934X=m
+CONFIG_POWER_RESET_MSM=y
+CONFIG_POWER_RESET_QCOM_PON=m
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_SYSCON_REBOOT_MODE=y
+CONFIG_BATTERY_QCOM_BATTMGR=m
+CONFIG_SENSORS_ARM_SCMI=y
+CONFIG_SENSORS_ARM_SCPI=y
+CONFIG_SENSORS_GPIO_FAN=m
+CONFIG_SENSORS_PWM_FAN=m
+CONFIG_SENSORS_AMC6821=y
+CONFIG_THERMAL_NETLINK=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=10000
+CONFIG_THERMAL_WRITABLE_TRIPS=y
+CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
+CONFIG_CPU_THERMAL=y
+CONFIG_CPU_IDLE_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
+CONFIG_THERMAL_EMULATION=y
+CONFIG_GENERIC_ADC_THERMAL=m
+CONFIG_QCOM_TSENS=y
+CONFIG_QCOM_SPMI_ADC_TM5=m
+CONFIG_QCOM_SPMI_TEMP_ALARM=y
+CONFIG_QCOM_LMH=m
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_SYSFS=y
+CONFIG_WATCHDOG_PRETIMEOUT_GOV=y
+CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP=y
+CONFIG_ARM_SBSA_WATCHDOG=y
+CONFIG_MFD_SPMI_PMIC=y
+CONFIG_MFD_WCD934X=m
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_REGULATOR_QCOM_REFGEN=y
+CONFIG_REGULATOR_QCOM_RPMH=y
+CONFIG_REGULATOR_QCOM_SMD_RPM=y
+CONFIG_REGULATOR_QCOM_SPMI=y
+CONFIG_REGULATOR_VCTRL=m
+CONFIG_RC_CORE=m
+CONFIG_RC_DECODERS=y
+CONFIG_RC_DEVICES=y
+CONFIG_MEDIA_CEC_SUPPORT=y
+CONFIG_CEC_GPIO=m
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_SDR_SUPPORT=y
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SDR_PLATFORM_DRIVERS=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_IMX412=m
+CONFIG_VIDEO_QCOM_CAMSS=m
+CONFIG_VIDEO_QCOM_VENUS=m
+CONFIG_VIDEO_QCOM_IRIS=m
+CONFIG_DRM=m
+CONFIG_DRM_LONTIUM_LT9611UXC=m
+CONFIG_DRM_ANALOGIX_ANX7625=m
+CONFIG_DRM_LONTIUM_LT9611UXC=m
+# CONFIG_DRM_FBDEV_EMULATION is not set
+CONFIG_DRM_HDLCD=m
+CONFIG_DRM_MSM=m
+# CONFIG_DRM_MSM_MDP4 is not set
+# CONFIG_DRM_MSM_MDP5 is not set
+# CONFIG_DRM_MSM_HDMI is not set
+CONFIG_DRM_PANEL_LVDS=m
+CONFIG_DRM_PANEL_SIMPLE=m
+CONFIG_DRM_PANEL_EDP=m
+CONFIG_DRM_PANEL_NOVATEK_NT36672E=m
+CONFIG_DRM_DISPLAY_CONNECTOR=m
+CONFIG_FB=y
+CONFIG_FB_EFI=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=m
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_ALOOP=m
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_AUDIO_MIDI_V2=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_QCOM=y
+CONFIG_SND_SOC_APQ8016_SBC=m
+CONFIG_SND_SOC_QDSP6=y
+CONFIG_SND_SOC_MSM8996=m
+CONFIG_SND_SOC_SDM845=m
+CONFIG_SND_SOC_SM8250=m
+CONFIG_SND_SOC_SC7180=m
+CONFIG_SND_SOC_SC7280=m
+CONFIG_SND_SOC_QCM6490=m
+CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m
+CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m
+CONFIG_SND_SOC_WCD9335=m
+CONFIG_SND_SOC_WCD934X=m
+CONFIG_SND_SOC_WCD937X_SDW=y
+CONFIG_SND_SOC_WSA881X=m
+CONFIG_SND_SOC_WSA883X=y
+CONFIG_SND_SOC_LPASS_VA_MACRO=m
+CONFIG_SND_SIMPLE_CARD=m
+CONFIG_SND_AUDIO_GRAPH_CARD=m
+CONFIG_SND_AUDIO_GRAPH_CARD2=m
+CONFIG_UHID=m
+CONFIG_HID_MULTITOUCH=m
+CONFIG_USB_HID=m
+CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_I2C_HID_ACPI=m
+CONFIG_I2C_HID_OF=m
+CONFIG_USB_CONN_GPIO=y
+CONFIG_USB=y
+CONFIG_USB_OTG=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PCI_RENESAS=m
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_ACM=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_UAS=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_CH341=m
+CONFIG_USB_SERIAL_CP210X=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_QCOM_EUD=m
+CONFIG_USB_ONBOARD_HUB=m
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_ULPI=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_UAC2=y
+CONFIG_USB_CONFIGFS_F_UVC=y
+CONFIG_TYPEC=m
+CONFIG_TYPEC_TCPM=m
+CONFIG_TYPEC_TCPCI=m
+CONFIG_TYPEC_UCSI=m
+CONFIG_UCSI_PMIC_GLINK=m
+CONFIG_TYPEC_MUX_FSA4480=m
+CONFIG_TYPEC_MUX_GPIO_SBU=m
+CONFIG_TYPEC_MUX_NB7VPQ904M=m
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_CRYPTO=y
+CONFIG_MMC_ARMMMCI=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ACPI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_MMC_SPI=y
+CONFIG_SCSI_UFSHCD=y
+CONFIG_SCSI_UFS_BSG=y
+CONFIG_SCSI_UFS_CRYPTO=y
+CONFIG_SCSI_UFSHCD_PLATFORM=y
+CONFIG_SCSI_UFS_QCOM=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_CLASS_FLASH=m
+CONFIG_LEDS_CLASS_MULTICOLOR=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_SYSCON=y
+CONFIG_LEDS_QCOM_FLASH=m
+CONFIG_LEDS_QCOM_LPG=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_PANIC=y
+CONFIG_LEDS_TRIGGER_PATTERN=y
+CONFIG_EDAC=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_EFI=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_RTC_DRV_PM8XXX=m
+CONFIG_DMADEVICES=y
+CONFIG_PL330_DMA=y
+CONFIG_QCOM_BAM_DMA=y
+CONFIG_QCOM_GPI_DMA=m
+CONFIG_QCOM_HIDMA_MGMT=y
+CONFIG_QCOM_HIDMA=y
+CONFIG_DMABUF_HEAPS_SYSTEM=y
+CONFIG_DMABUF_HEAPS_CMA=y
+CONFIG_UIO=y
+CONFIG_VFIO=y
+CONFIG_VFIO_PCI=y
+CONFIG_VFIO_PLATFORM=m
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_XEN_GNTDEV=y
+CONFIG_XEN_GRANT_DEV_ALLOC=y
+CONFIG_VHOST_NET=y
+CONFIG_VHOST_VSOCK=y
+CONFIG_STAGING=y
+CONFIG_STAGING_MEDIA=y
+CONFIG_COMMON_CLK_SCMI=y
+CONFIG_COMMON_CLK_SCPI=y
+CONFIG_COMMON_CLK_PWM=y
+CONFIG_COMMON_CLK_QCOM=y
+CONFIG_CLK_X1E80100_GCC=y
+CONFIG_QCOM_A53PLL=y
+CONFIG_QCOM_CLK_APCS_MSM8916=y
+CONFIG_QCOM_CLK_APCC_MSM8996=y
+CONFIG_QCOM_CLK_SMD_RPM=y
+CONFIG_QCOM_CLK_RPMH=y
+CONFIG_IPQ_APSS_6018=y
+CONFIG_IPQ_GCC_5332=y
+CONFIG_IPQ_GCC_6018=y
+CONFIG_IPQ_GCC_8074=y
+CONFIG_IPQ_GCC_9574=y
+CONFIG_MSM_GCC_8916=y
+CONFIG_MSM_MMCC_8994=m
+CONFIG_MSM_GCC_8994=y
+CONFIG_MSM_MMCC_8996=m
+CONFIG_MSM_GCC_8998=y
+CONFIG_MSM_MMCC_8998=m
+CONFIG_QCM_GCC_2290=y
+CONFIG_QCM_DISPCC_2290=m
+CONFIG_QCS_DISPCC_615=m
+CONFIG_QCS_CAMCC_615=m
+CONFIG_QCS_GCC_404=y
+CONFIG_QCS_GCC_615=y
+CONFIG_QCS_GPUCC_615=m
+CONFIG_QCS_VIDEOCC_615=m
+CONFIG_QCS_GCC_8300=y
+CONFIG_SC_CAMCC_7280=y
+CONFIG_SC_DISPCC_7280=y
+CONFIG_SC_DISPCC_8280XP=m
+CONFIG_SA_GCC_8775P=y
+CONFIG_SA_CAMCC_8775P=m
+CONFIG_SA_DISPCC_8775P=m
+CONFIG_SA_VIDEOCC_8775P=m
+CONFIG_SA_GPUCC_8775P=y
+CONFIG_SC_GCC_7180=y
+CONFIG_SC_GCC_8180X=y
+CONFIG_SC_GCC_8280XP=y
+CONFIG_SC_GPUCC_7280=y
+CONFIG_SC_LPASSCC_8280XP=m
+CONFIG_SC_LPASS_CORECC_7280=y
+CONFIG_SC_VIDEOCC_7280=y
+CONFIG_SDM_CAMCC_845=m
+CONFIG_SDM_GPUCC_845=y
+CONFIG_SDM_VIDEOCC_845=y
+CONFIG_SDM_DISPCC_845=y
+CONFIG_SDM_LPASSCC_845=m
+CONFIG_SM_CAMCC_8250=m
+CONFIG_SM_CAMCC_8550=m
+CONFIG_SM_DISPCC_6115=m
+CONFIG_SM_DISPCC_8250=y
+CONFIG_SM_DISPCC_8450=m
+CONFIG_SM_DISPCC_8550=m
+CONFIG_SM_DISPCC_8650=y
+CONFIG_SM_GCC_6115=y
+CONFIG_SM_GCC_8350=y
+CONFIG_SM_GCC_8450=y
+CONFIG_SM_GCC_8650=y
+CONFIG_SM_GPUCC_6115=m
+CONFIG_SM_GPUCC_8150=y
+CONFIG_SM_GPUCC_8250=y
+CONFIG_SM_GPUCC_8550=y
+CONFIG_SM_GPUCC_8650=y
+CONFIG_SM_TCSRCC_8550=y
+CONFIG_SM_TCSRCC_8650=y
+CONFIG_SM_VIDEOCC_8250=y
+CONFIG_SM_VIDEOCC_8550=y
+CONFIG_QCOM_HFPLL=y
+CONFIG_CLK_GFM_LPASS_SM8250=m
+CONFIG_HWSPINLOCK=y
+CONFIG_HWSPINLOCK_QCOM=y
+CONFIG_ARM_MHU=y
+CONFIG_PLATFORM_MHU=y
+CONFIG_QCOM_APCS_IPC=y
+CONFIG_QCOM_IPCC=y
+CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y
+CONFIG_IOMMU_IO_PGTABLE_DART=y
+CONFIG_ARM_SMMU=y
+CONFIG_ARM_SMMU_QCOM_TBU=y
+CONFIG_ARM_SMMU_V3=y
+CONFIG_QCOM_IOMMU=y
+CONFIG_REMOTEPROC=y
+CONFIG_QCOM_Q6V5_ADSP=m
+CONFIG_QCOM_Q6V5_MSS=m
+CONFIG_QCOM_Q6V5_PAS=m
+CONFIG_QCOM_SYSMON=m
+CONFIG_QCOM_WCNSS_PIL=m
+CONFIG_RPMSG_CHAR=m
+CONFIG_RPMSG_CTRL=m
+CONFIG_RPMSG_QCOM_GLINK_RPM=y
+CONFIG_RPMSG_QCOM_GLINK_SMEM=m
+CONFIG_RPMSG_QCOM_SMD=y
+CONFIG_SOUNDWIRE=y
+CONFIG_SOUNDWIRE_QCOM=y
+CONFIG_SOC_BRCMSTB=y
+CONFIG_FSL_RCPM=y
+CONFIG_QCOM_AOSS_QMP=y
+CONFIG_QCOM_COMMAND_DB=y
+CONFIG_QCOM_CPR=y
+CONFIG_QCOM_GENI_SE=y
+CONFIG_QCOM_LLCC=m
+CONFIG_QCOM_OCMEM=m
+CONFIG_QCOM_PMIC_GLINK=m
+CONFIG_QCOM_RMTFS_MEM=m
+CONFIG_QCOM_RPMH=y
+CONFIG_QCOM_RPMHPD=y
+CONFIG_QCOM_RPMPD=y
+CONFIG_QCOM_SMEM=y
+CONFIG_QCOM_SMD_RPM=y
+CONFIG_QCOM_SMP2P=y
+CONFIG_QCOM_SMSM=y
+CONFIG_QCOM_SOCINFO=m
+CONFIG_QCOM_SPM=m
+CONFIG_QCOM_STATS=m
+CONFIG_QCOM_WCNSS_CTRL=m
+CONFIG_QCOM_APR=y
+CONFIG_QCOM_ICC_BWMON=m
+CONFIG_DEVFREQ_GOV_USERSPACE=y
+CONFIG_DEVFREQ_GOV_PASSIVE=m
+CONFIG_EXTCON_USB_GPIO=y
+CONFIG_MEMORY=y
+CONFIG_IIO=y
+CONFIG_QCOM_SPMI_VADC=m
+CONFIG_QCOM_SPMI_ADC5=y
+CONFIG_PWM=y
+CONFIG_QCOM_PDC=y
+CONFIG_QCOM_MPM=y
+CONFIG_RESET_QCOM_AOSS=y
+CONFIG_RESET_QCOM_PDC=m
+CONFIG_PHY_CAN_TRANSCEIVER=m
+CONFIG_PHY_QCOM_EDP=m
+CONFIG_PHY_QCOM_PCIE2=m
+CONFIG_PHY_QCOM_QMP=y
+CONFIG_PHY_QCOM_QUSB2=m
+CONFIG_PHY_QCOM_SNPS_EUSB2=m
+CONFIG_PHY_QCOM_EUSB2_REPEATER=m
+CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=y
+CONFIG_PHY_QCOM_USB_HS_28NM=m
+CONFIG_PHY_QCOM_USB_SS=m
+CONFIG_POWERCAP=y
+CONFIG_IDLE_INJECT=y
+CONFIG_ARM_CCI_PMU=m
+CONFIG_ARM_CCN=m
+CONFIG_ARM_CMN=m
+CONFIG_ARM_SMMU_V3_PMU=m
+CONFIG_ARM_DSU_PMU=m
+CONFIG_QCOM_L2_PMU=y
+CONFIG_QCOM_L3_PMU=y
+CONFIG_ARM_SPE_PMU=m
+CONFIG_ARM_DMC620_PMU=m
+CONFIG_HISI_PMU=y
+CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m
+CONFIG_NVMEM_QCOM_QFPROM=y
+CONFIG_NVMEM_RMEM=m
+CONFIG_NVMEM_SPMI_SDAM=m
+CONFIG_STM_SOURCE_CONSOLE=m
+CONFIG_STM_SOURCE_HEARTBEAT=m
+CONFIG_STM_SOURCE_FTRACE=m
+CONFIG_FPGA=y
+CONFIG_FPGA_MGR_ALTERA_CVP=m
+CONFIG_FPGA_BRIDGE=m
+CONFIG_ALTERA_FREEZE_BRIDGE=m
+CONFIG_FPGA_REGION=m
+CONFIG_OF_FPGA_REGION=m
+CONFIG_TEE=y
+CONFIG_OPTEE=y
+CONFIG_MUX_MMIO=m
+CONFIG_SLIMBUS=m
+CONFIG_SLIM_QCOM_CTRL=m
+CONFIG_SLIM_QCOM_NGD_CTRL=m
+CONFIG_INTERCONNECT=y
+CONFIG_INTERCONNECT_QCOM=y
+CONFIG_INTERCONNECT_QCOM_MSM8916=m
+CONFIG_INTERCONNECT_QCOM_MSM8996=m
+CONFIG_INTERCONNECT_QCOM_OSM_L3=m
+CONFIG_INTERCONNECT_QCOM_QCM2290=m
+CONFIG_INTERCONNECT_QCOM_QCS404=m
+CONFIG_INTERCONNECT_QCOM_QCS615=y
+CONFIG_INTERCONNECT_QCOM_QCS8300=y
+CONFIG_INTERCONNECT_QCOM_SA8775P=y
+CONFIG_INTERCONNECT_QCOM_SC7180=y
+CONFIG_INTERCONNECT_QCOM_SC7280=y
+CONFIG_INTERCONNECT_QCOM_SC8180X=y
+CONFIG_INTERCONNECT_QCOM_SC8280XP=y
+CONFIG_INTERCONNECT_QCOM_SDM845=y
+CONFIG_INTERCONNECT_QCOM_SM8150=m
+CONFIG_INTERCONNECT_QCOM_SM8250=m
+CONFIG_INTERCONNECT_QCOM_SM8350=m
+CONFIG_INTERCONNECT_QCOM_SM8450=y
+CONFIG_INTERCONNECT_QCOM_SM8550=y
+CONFIG_INTERCONNECT_QCOM_SM8650=y
+CONFIG_INTERCONNECT_QCOM_X1E80100=y
+CONFIG_COUNTER=m
+CONFIG_HTE=y
+# CONFIG_EXT2_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_EXT4_USE_FOR_EXT2=y
+CONFIG_FS_ENCRYPTION=y
+CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_OVERLAY_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_HUGETLBFS=y
+CONFIG_EFIVAR_FS=y
+CONFIG_SQUASHFS=y
+CONFIG_EFI_PARTITION=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
+CONFIG_ROOT_NFS=y
+CONFIG_9P_FS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_FORTIFY_SOURCE=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_ECHAINIV=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_LZ4=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_CRYPTO_USER_API_RNG=m
+CONFIG_CRYPTO_USER_API_AEAD=y
+CONFIG_CRYPTO_CHACHA20_NEON=m
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+CONFIG_CRYPTO_SHA1_ARM64_CE=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_SHA512_ARM64_CE=m
+CONFIG_CRYPTO_SHA3_ARM64=m
+CONFIG_CRYPTO_SM3_ARM64_CE=m
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
+CONFIG_CRYPTO_AES_ARM64_BS=m
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_DEV_QCE=m
+CONFIG_CRYPTO_DEV_QCOM_RNG=m
+CONFIG_CRYPTO_DEV_CCREE=m
+# CONFIG_HW_RANDOM_ARM_SMCCC_TRNG is not set
+CONFIG_INDIRECT_PIO=y
+CONFIG_TRACE_MMIO_ACCESS=y
+CONFIG_CRC_CCITT=m
+CONFIG_DMA_RESTRICTED_POOL=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=32
+CONFIG_PRINTK_TIME=y
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=6
+CONFIG_DYNAMIC_DEBUG_CORE=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_PAGE_OWNER=y
+CONFIG_PANIC_ON_OOPS=y
+CONFIG_SCHEDSTATS=y
+CONFIG_CORESIGHT=m
+CONFIG_CORESIGHT_LINK_AND_SINK_TMC=m
+CONFIG_CORESIGHT_CATU=m
+CONFIG_CORESIGHT_SINK_TPIU=m
+CONFIG_CORESIGHT_SINK_ETBV10=m
+CONFIG_CORESIGHT_STM=m
+CONFIG_CORESIGHT_CPU_DEBUG=m
+CONFIG_CORESIGHT_CTI=m
+CONFIG_CORESIGHT_TPDM=m
+CONFIG_CORESIGHT_DUMMY=m
+CONFIG_NFT_NAT=y
+CONFIG_NF_NAT=y
+CONFIG_NF_TABLES=y
+CONFIG_NF_TABLES_INET=y
+CONFIG_NETFILTER_NETLINK_QUEUE=m
+CONFIG_NF_FLOW_TABLE=m
+CONFIG_NFT_FLOW_OFFLOAD=m
+CONFIG_NFT_QUEUE=m
+CONFIG_NETFILTER_XTABLES=m
+CONFIG_NETFILTER_XTABLES_COMPAT=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_IP6=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_NF_TABLES_NETDEV=y
+CONFIG_STMMAC_ETH=m
+CONFIG_STMMAC_SELFTESTS=y
+CONFIG_MARVELL_PHY=m
+CONFIG_PHY_QCOM_SGMII_ETH=m
+CONFIG_ATH11K_DEBUGFS=y
+CONFIG_MAC80211_DEBUGFS=y
+CONFIG_ARM64_PMEM=y
+CONFIG_IXGBE=y
+CONFIG_IXGBEVF=y
+CONFIG_AQUANTIA_PHY=y
+CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y
+CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT=y
+CONFIG_EEPROM_AT24=m
+CONFIG_TYPEC_HD3SS3220=m
--- linux-qcom-6.8.0.orig/arch/arm64/configs/qcom_gen4auto.config
+++ linux-qcom-6.8.0/arch/arm64/configs/qcom_gen4auto.config
@@ -0,0 +1,80 @@
+
+# CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU is not set
+# CONFIG_ARM_SCMI_CPUFREQ is not set
+# CONFIG_ARM_SMMU_QCOM_TBU is not set
+# CONFIG_ATH11K is not set
+CONFIG_BACKLIGHT_QCOM_WLED=y
+CONFIG_BLK_DEV_DM=y
+# CONFIG_CORESIGHT is not set
+CONFIG_DM_INIT=y
+CONFIG_DM_VERITY=y
+CONFIG_DW_EDMA=y
+CONFIG_DW_EDMA_PCIE=y
+CONFIG_GH_VIRT_WATCHDOG=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_IOMMU_DEFAULT_DMA_LAZY=y
+CONFIG_MFD_I2C_PMIC=y
+CONFIG_MHI_BUS=y
+# CONFIG_MHI_BUS_DEBUG is not set
+CONFIG_MHI_BUS_PCI_GENERIC=y
+CONFIG_MHI_EP_NET=y
+CONFIG_MHI_NET=y
+# CONFIG_MHI_WWAN_CTRL is not set
+# CONFIG_MHI_WWAN_MBIM is not set
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_MHI_BUS_EP=y
+CONFIG_MSM_RDBG=m
+CONFIG_NET_KEY=m
+CONFIG_NO_HZ_FULL=y
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_PHY_QCOM_QMP=m
+CONFIG_PHY_QCOM_QMP_PCIE=m
+CONFIG_PHY_QCOM_QMP_PCIE_8996=m
+CONFIG_PHY_QCOM_QMP_UFS=m
+CONFIG_PHY_QCOM_QMP_USB=m
+CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=m
+CONFIG_PINCTRL_SA7255P=y
+CONFIG_PINCTRL_SA8775P_LPASS_LPI=m
+CONFIG_QCOM_DCC=m
+CONFIG_QCOM_DMABUF_HEAPS=y
+CONFIG_QCOM_DMABUF_HEAPS_CMA=y
+CONFIG_QCOM_DMABUF_HEAPS_SYSTEM=y
+CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_SECURE=y
+CONFIG_QCOM_MEM_BUF=y
+CONFIG_QCOM_MEM_BUF_DEV=y
+# CONFIG_QCOM_PANEL_EVENT_NOTIFIER is not set
+CONFIG_PCI_EPF_MHI=y
+CONFIG_PCIE_QCOM_EP=m
+CONFIG_QCOM_PMIC_PDCHARGER_ULOG=y
+CONFIG_QCOM_QMI_COOLING=m
+CONFIG_QCOM_QPS615_PCIE_SWITCH=y
+CONFIG_QCOM_SCM_ADDON=y
+CONFIG_QCOM_SECURE_BUFFER=y
+CONFIG_QCOM_SI_CORE=m
+CONFIG_QCOM_SI_CORE_MEM_OBJECT=m
+CONFIG_QCOM_SI_CORE_WQ=y
+CONFIG_QCOM_SI_CORE_XTS=m
+CONFIG_QCOM_SMP2P_SLEEPSTATE=y
+# CONFIG_QCOM_SOC_DEBUG is not set
+CONFIG_QCOM_SPMI_ADC5_GEN3=m
+CONFIG_QCOM_SPMI_MBG_TM=m
+CONFIG_QCOM_WDT=y
+CONFIG_QCOM_WDT_CORE=y
+CONFIG_QTI_BCL_PMIC5=y
+CONFIG_QTI_DEVFREQ_CDEV=m
+CONFIG_QTI_TZ_LOG=m
+CONFIG_REGULATOR_DEBUG_CONTROL=y
+CONFIG_REGULATOR_PROXY_CONSUMER=y
+CONFIG_REGULATOR_QCOM_PM8008=y
+CONFIG_REGULATOR_QPNP_LCDB=y
+# CONFIG_SERIAL_QCOM_GENI_CONSOLE is not set
+CONFIG_SND_SOC_MSM_STUB=y
+CONFIG_STM_PROTO_OST=m
+CONFIG_USB_DWC3_QCOM=m
+# CONFIG_USB_F_QDSS is not set
+CONFIG_VIRT_DRIVERS=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_QCOM_DMABUF_HEAPS_CARVEOUT=y
--- linux-qcom-6.8.0.orig/arch/arm64/configs/qcom_gen4auto_debug.config
+++ linux-qcom-6.8.0/arch/arm64/configs/qcom_gen4auto_debug.config
@@ -0,0 +1,27 @@
+CONFIG_BUG_ON_DATA_CORRUPTION=y
+CONFIG_CMA_DEBUG=y
+CONFIG_CMA_DEBUGFS=y
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_OBJECTS=y
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DMABUF_SYSFS_STATS=y
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_FW_LOADER_DEBUG is not set
+CONFIG_HARDLOCKUP_DETECTOR=y
+CONFIG_HWLAT_TRACER=y
+CONFIG_LOCALVERSION="-debug"
+CONFIG_MAC80211_DEBUGFS=y
+CONFIG_PAGE_POISONING=y
+CONFIG_PID_IN_CONTEXTIDR=y
+CONFIG_PM_DEBUG=y
+CONFIG_SCHED_TRACER=y
+CONFIG_SERIAL_QCOM_GENI_CONSOLE=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_STACK_TRACER=y
+# CONFIG_TEST_DYNAMIC_DEBUG is not set
+CONFIG_TIMERLAT_TRACER=y
--- linux-qcom-6.8.0.orig/arch/arm64/configs/qcom_gen5auto.config
+++ linux-qcom-6.8.0/arch/arm64/configs/qcom_gen5auto.config
@@ -0,0 +1,65 @@
+# CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU is not set
+CONFIG_ARM_SCMI_CPUFREQ=y
+# CONFIG_ARM_SMMU_QCOM_TBU is not set
+# CONFIG_ATH11K is not set
+CONFIG_BLK_DEV_DM=y
+# CONFIG_CORESIGHT is not set
+CONFIG_DM_INIT=y
+CONFIG_DM_VERITY=y
+CONFIG_DW_EDMA=y
+CONFIG_DW_EDMA_PCIE=y
+CONFIG_IOMMU_DEFAULT_DMA_LAZY=y
+CONFIG_MHI_BUS=y
+# CONFIG_MHI_BUS_DEBUG is not set
+CONFIG_MHI_BUS_EP=y
+CONFIG_MHI_BUS_PCI_GENERIC=y
+CONFIG_MHI_EP_NET=y
+CONFIG_MHI_NET=y
+# CONFIG_MHI_WWAN_CTRL is not set
+# CONFIG_MHI_WWAN_MBIM is not set
+# CONFIG_MODULE_SIG_FORCE is not set
+CONFIG_MSM_RDBG=m
+CONFIG_NET_KEY=m
+CONFIG_NO_HZ_FULL=y
+CONFIG_PANIC_TIMEOUT=0
+CONFIG_PHY_QCOM_QMP=m
+CONFIG_PHY_QCOM_QMP_COMBO=m
+CONFIG_PHY_QCOM_QMP_PCIE=m
+CONFIG_PHY_QCOM_QMP_UFS=m
+CONFIG_PHY_QCOM_SNPS_EUSB2=m
+CONFIG_PINCTRL_SA8797P=y
+CONFIG_QCOM_DCC=m
+CONFIG_QCOM_DMABUF_HEAPS=y
+CONFIG_QCOM_DMABUF_HEAPS_CARVEOUT=y
+CONFIG_QCOM_DMABUF_HEAPS_CMA=y
+CONFIG_QCOM_DMABUF_HEAPS_SYSTEM=y
+CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_SECURE=y
+CONFIG_QCOM_MEM_BUF=y
+CONFIG_QCOM_MEM_BUF_DEV=y
+# CONFIG_QCOM_PANEL_EVENT_NOTIFIER is not set
+CONFIG_PCI_EPF_MHI=y
+CONFIG_PCIE_QCOM_EP=m
+CONFIG_QCOM_CPUCP_MBOX=y
+CONFIG_QCOM_MEMORY_DUMP_V2=y
+CONFIG_QCOM_SCM_ADDON=y
+CONFIG_QCOM_SECURE_BUFFER=y
+CONFIG_QCOM_SMCINVOKE=m
+CONFIG_QCOM_SMP2P_SLEEPSTATE=y
+# CONFIG_QCOM_SOC_DEBUG is not set
+CONFIG_QCOM_WDT_CORE=y
+CONFIG_QRTR=y
+CONFIG_QRTR_SMD=y
+CONFIG_QRTR_MHI=m
+CONFIG_QTI_BCL_PMIC5=y
+CONFIG_QTI_DEVFREQ_CDEV=m
+CONFIG_QTI_TZ_LOG=m
+CONFIG_REGULATOR_DEBUG_CONTROL=y
+CONFIG_REGULATOR_PROXY_CONSUMER=y
+CONFIG_SCSI_UFS_QCOM=y
+CONFIG_SERIAL_QCOM_GENI_CONSOLE=y
+CONFIG_SND_SOC_MSM_STUB=y
+CONFIG_USB_DWC3_QCOM=m
+# CONFIG_USB_F_QDSS is not set
+CONFIG_VIRT_DRIVERS=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
--- linux-qcom-6.8.0.orig/arch/arm64/configs/qcom_gen5auto_debug.config
+++ linux-qcom-6.8.0/arch/arm64/configs/qcom_gen5auto_debug.config
@@ -0,0 +1,79 @@
+CONFIG_BUG_ON_DATA_CORRUPTION=y
+CONFIG_CMA_DEBUG=y
+CONFIG_CMA_DEBUGFS=y
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
+CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_DEBUG_IRQFLAGS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_KMEMLEAK=y
+CONFIG_DEBUG_KMEMLEAK_AUTO_SCAN=y
+# CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF is not set
+CONFIG_DEBUG_KMEMLEAK_MEM_POOL_SIZE=16000
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_LOCKDEP=y
+CONFIG_DEBUG_LOCK_ALLOC=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_OBJECTS=y
+CONFIG_DEBUG_PAGEALLOC=y
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_RWSEMS=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_WW_MUTEX_SLOWPATH=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DMABUF_SYSFS_STATS=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DYNAMIC_FTRACE=y
+CONFIG_DYNAMIC_FTRACE_WITH_ARGS=y
+CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS=y
+CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y
+CONFIG_FTRACE_MCOUNT_RECORD=y
+CONFIG_FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY=y
+CONFIG_FTRACE_SYSCALLS=y
+CONFIG_FUNCTION_ALIGNMENT=8
+CONFIG_FUNCTION_ALIGNMENT_8B=y
+CONFIG_FUNCTION_GRAPH_TRACER=y
+CONFIG_FUNCTION_TRACER=y
+# CONFIG_FW_LOADER_DEBUG is not set
+CONFIG_GENERIC_TRACER=y
+CONFIG_HARDLOCKUP_DETECTOR=y
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS=y
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS=y
+CONFIG_HWLAT_TRACER=y
+CONFIG_KASAN_GENERIC=y
+# CONFIG_KASAN_HW_TAGS is not set
+CONFIG_KASAN_INLINE=y
+# CONFIG_KASAN_MODULE_TEST is not set
+# CONFIG_KASAN_OUTLINE is not set
+CONFIG_KASAN_SHADOW_OFFSET=0xdfffffc000000000
+CONFIG_KASAN_STACK=y
+CONFIG_LOCALVERSION="-debug"
+CONFIG_LOCKDEP=y
+CONFIG_LOCKDEP_BITS=15
+CONFIG_LOCKDEP_CHAINS_BITS=16
+CONFIG_LOCKDEP_CIRCULAR_QUEUE_BITS=12
+CONFIG_LOCKDEP_STACK_TRACE_BITS=19
+CONFIG_LOCKDEP_STACK_TRACE_HASH_BITS=14
+CONFIG_LOCK_STAT=y
+CONFIG_MAC80211_DEBUGFS=y
+CONFIG_PAGE_POISONING=y
+CONFIG_PID_IN_CONTEXTIDR=y
+CONFIG_PREEMPTIRQ_TRACEPOINTS=y
+CONFIG_PROVE_LOCKING=y
+# CONFIG_PROVE_RAW_LOCK_NESTING is not set
+CONFIG_PROVE_RCU=y
+# CONFIG_PROVE_RCU_LIST is not set
+CONFIG_RCU_CPU_STALL_CPUTIME=y
+CONFIG_SCHED_TRACER=y
+CONFIG_SOFTLOCKUP_DETECTOR=y
+CONFIG_STACK_TRACER=y
+# CONFIG_TEST_DYNAMIC_DEBUG is not set
+CONFIG_TIMERLAT_TRACER=y
+CONFIG_TRACER_MAX_TRACE=y
+CONFIG_TRACER_SNAPSHOT=y
+# CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set
+CONFIG_TRACE_IRQFLAGS=y
+CONFIG_TRACE_IRQFLAGS_NMI=y
+CONFIG_WQ_CPU_INTENSIVE_REPORT=y
+CONFIG_WQ_WATCHDOG=y
--- linux-qcom-6.8.0.orig/arch/arm64/configs/qcom_kvm.config
+++ linux-qcom-6.8.0/arch/arm64/configs/qcom_kvm.config
@@ -0,0 +1 @@
+CONFIG_QCOM_KVM_ENABLED=y
--- linux-qcom-6.8.0.orig/arch/arm64/configs/qcom_vm_defconfig
+++ linux-qcom-6.8.0/arch/arm64/configs/qcom_vm_defconfig
@@ -0,0 +1,769 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_AUDIT=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
+CONFIG_BPF_JIT=y
+CONFIG_PREEMPT=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_UCLAMP_TASK=y
+CONFIG_NUMA_BALANCING=y
+CONFIG_MEMCG=y
+CONFIG_BLK_CGROUP=y
+CONFIG_UCLAMP_TASK_GROUP=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_HUGETLB=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
+CONFIG_CGROUP_BPF=y
+CONFIG_USER_NS=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_BOOT_CONFIG=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_PROFILING=y
+CONFIG_ARCH_QCOM=y
+CONFIG_SCHED_MC=y
+CONFIG_SCHED_SMT=y
+CONFIG_NR_CPUS=16
+CONFIG_NUMA=y
+CONFIG_XEN=y
+CONFIG_ARM64_SW_TTBR0_PAN=y
+CONFIG_COMPAT=y
+CONFIG_RANDOMIZE_BASE=y
+CONFIG_HIBERNATION=y
+CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
+CONFIG_ENERGY_MODEL=y
+CONFIG_ARM_PSCI_CPUIDLE=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPUFREQ_DT=y
+CONFIG_ACPI_CPPC_CPUFREQ=m
+CONFIG_ARM_SCPI_CPUFREQ=y
+CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
+CONFIG_ARM_QCOM_CPUFREQ_HW=y
+CONFIG_ARM_SCMI_CPUFREQ=y
+CONFIG_ACPI=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM=y
+CONFIG_KPROBES=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_BLK_INLINE_ENCRYPTION=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_SLAB_FREELIST_RANDOM=y
+CONFIG_SLAB_FREELIST_HARDENED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_KSM=y
+CONFIG_MEMORY_FAILURE=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_CMA=y
+CONFIG_CMA_DEBUG=y
+CONFIG_CMA_SYSFS=y
+CONFIG_CMA_AREAS=32
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IPV6=m
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE_NETFILTER=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NETFILTER_XT_MARK=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_IP_VS=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_NAT=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_NET_DSA=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_VLAN_8021Q_MVRP=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBS=m
+CONFIG_NET_SCH_ETF=m
+CONFIG_NET_SCH_TAPRIO=m
+CONFIG_NET_SCH_MQPRIO=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_FLOWER=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_GACT=m
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_GATE=m
+CONFIG_VSOCKETS=y
+CONFIG_VIRTIO_VSOCKETS=y
+CONFIG_QRTR_SMD=m
+CONFIG_QRTR_TUN=m
+CONFIG_CAN=m
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_HIDP=m
+# CONFIG_BT_LE is not set
+CONFIG_BT_LEDS=y
+# CONFIG_BT_DEBUGFS is not set
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIUART_QCA=y
+CONFIG_BT_QCOMSMD=m
+CONFIG_CFG80211=m
+CONFIG_MAC80211=m
+CONFIG_MAC80211_LEDS=y
+CONFIG_RFKILL=m
+CONFIG_NET_9P=y
+CONFIG_NET_9P_VIRTIO=y
+CONFIG_NFC=m
+CONFIG_NFC_NCI=m
+CONFIG_NFC_S3FWRN5_I2C=m
+CONFIG_PAGE_POOL_STATS=y
+CONFIG_PCI=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+CONFIG_PCI_IOV=y
+CONFIG_PCI_PASID=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_ACPI=y
+CONFIG_PCI_HOST_GENERIC=y
+CONFIG_PCIE_QCOM=y
+CONFIG_PCI_ENDPOINT=y
+CONFIG_PCI_ENDPOINT_CONFIGFS=y
+CONFIG_PCI_EPF_TEST=m
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_FW_LOADER_USER_HELPER=y
+CONFIG_MHI_BUS_PCI_GENERIC=m
+CONFIG_ARM_SCMI_PROTOCOL=y
+CONFIG_ARM_SCPI_PROTOCOL=y
+CONFIG_GNSS=m
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=m
+CONFIG_VIRTIO_BLK=y
+CONFIG_BLK_DEV_NVME=m
+CONFIG_QCOM_COINCELL=m
+CONFIG_QCOM_FASTRPC=m
+CONFIG_SRAM=y
+CONFIG_VCPU_STALL_DETECTOR=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_SAS_ATA=y
+CONFIG_SCSI_HISI_SAS=y
+CONFIG_SCSI_HISI_SAS_PCI=y
+CONFIG_MEGARAID_SAS=y
+CONFIG_SCSI_MPT3SAS=m
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_CEVA=y
+CONFIG_SATA_SIL24=y
+CONFIG_PATA_OF_PLATFORM=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_NETDEVICES=y
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_TUN=y
+CONFIG_VETH=m
+CONFIG_VIRTIO_NET=y
+CONFIG_MHI_NET=m
+CONFIG_ATL1C=m
+CONFIG_QCOM_EMAC=m
+CONFIG_RMNET=m
+CONFIG_QCOM_IPA=m
+CONFIG_AT803X_PHY=m
+CONFIG_MDIO_BITBANG=m
+CONFIG_MDIO_GPIO=m
+CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m
+CONFIG_MDIO_BUS_MUX_MMIOREG=m
+CONFIG_USB_USBNET=m
+CONFIG_ATH10K=m
+CONFIG_ATH10K_PCI=m
+CONFIG_ATH10K_SDIO=m
+CONFIG_ATH10K_SNOC=m
+CONFIG_WCN36XX=m
+CONFIG_ATH11K=m
+CONFIG_ATH11K_AHB=m
+CONFIG_ATH11K_PCI=m
+CONFIG_WWAN=m
+CONFIG_MHI_WWAN_CTRL=m
+CONFIG_MHI_WWAN_MBIM=m
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_ADC=m
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PM8941_PWRKEY=y
+CONFIG_INPUT_PM8XXX_VIBRATOR=y
+CONFIG_INPUT_PWM_BEEPER=m
+CONFIG_INPUT_PWM_VIBRA=m
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_QCOM_GENI=y
+CONFIG_SERIAL_QCOM_GENI_CONSOLE=y
+CONFIG_NULL_TTY=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_IPMI_HANDLER=m
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_VIRTIO=y
+# CONFIG_DEVMEM is not set
+CONFIG_TCG_TPM=y
+CONFIG_TCG_TIS=m
+CONFIG_TCG_TIS_SPI=m
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_GPIO=m
+CONFIG_I2C_QCOM_CCI=m
+CONFIG_I2C_QCOM_GENI=m
+CONFIG_I2C_QUP=y
+CONFIG_I2C_VIRTIO=y
+CONFIG_I2C_SLAVE=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_SPI_QCOM_QSPI=m
+CONFIG_SPI_QUP=y
+CONFIG_SPI_QCOM_GENI=m
+CONFIG_SPI_SPIDEV=m
+CONFIG_SPMI=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_PINCTRL_MSM=y
+CONFIG_PINCTRL_IPQ5332=y
+CONFIG_PINCTRL_IPQ8074=y
+CONFIG_PINCTRL_IPQ6018=y
+CONFIG_PINCTRL_IPQ9574=y
+CONFIG_PINCTRL_MSM8916=y
+CONFIG_PINCTRL_MSM8953=y
+CONFIG_PINCTRL_MSM8976=y
+CONFIG_PINCTRL_MSM8994=y
+CONFIG_PINCTRL_MSM8996=y
+CONFIG_PINCTRL_MSM8998=y
+CONFIG_PINCTRL_QCM2290=y
+CONFIG_PINCTRL_QCS404=y
+CONFIG_PINCTRL_QDF2XXX=y
+CONFIG_PINCTRL_QDU1000=y
+CONFIG_PINCTRL_SA8775P=y
+CONFIG_PINCTRL_SC7180=y
+CONFIG_PINCTRL_SC7280=y
+CONFIG_PINCTRL_SC8180X=y
+CONFIG_PINCTRL_SC8280XP=y
+CONFIG_PINCTRL_SDM660=y
+CONFIG_PINCTRL_SDM670=y
+CONFIG_PINCTRL_SDM845=y
+CONFIG_PINCTRL_SM6115=y
+CONFIG_PINCTRL_SM6125=y
+CONFIG_PINCTRL_SM6350=y
+CONFIG_PINCTRL_SM6375=y
+CONFIG_PINCTRL_SM8150=y
+CONFIG_PINCTRL_SM8250=y
+CONFIG_PINCTRL_SM8350=y
+CONFIG_PINCTRL_SM8450=y
+CONFIG_PINCTRL_SM8550=y
+CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+CONFIG_PINCTRL_LPASS_LPI=m
+CONFIG_PINCTRL_SC7280_LPASS_LPI=m
+CONFIG_PINCTRL_SM8250_LPASS_LPI=m
+CONFIG_PINCTRL_SM8450_LPASS_LPI=m
+CONFIG_PINCTRL_SC8280XP_LPASS_LPI=m
+CONFIG_PINCTRL_SM8550_LPASS_LPI=m
+CONFIG_GPIO_PL061=y
+CONFIG_GPIO_WCD934X=m
+CONFIG_GPIO_VIRTIO=y
+CONFIG_POWER_RESET_MSM=y
+CONFIG_POWER_RESET_QCOM_PON=m
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_SYSCON_REBOOT_MODE=y
+CONFIG_NVMEM_REBOOT_MODE=m
+CONFIG_BATTERY_QCOM_BATTMGR=m
+CONFIG_SENSORS_ARM_SCMI=y
+CONFIG_SENSORS_ARM_SCPI=y
+CONFIG_SENSORS_GPIO_FAN=m
+CONFIG_SENSORS_PWM_FAN=m
+CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
+CONFIG_CPU_THERMAL=y
+CONFIG_CPU_IDLE_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
+CONFIG_THERMAL_EMULATION=y
+CONFIG_GENERIC_ADC_THERMAL=m
+CONFIG_QCOM_TSENS=y
+CONFIG_QCOM_SPMI_ADC_TM5=m
+CONFIG_QCOM_SPMI_TEMP_ALARM=y
+CONFIG_QCOM_LMH=m
+CONFIG_WATCHDOG=y
+CONFIG_ARM_SBSA_WATCHDOG=y
+CONFIG_I6300ESB_WDT=y
+CONFIG_MFD_SPMI_PMIC=y
+CONFIG_MFD_WCD934X=m
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_REGULATOR_QCOM_REFGEN=y
+CONFIG_REGULATOR_QCOM_RPMH=y
+CONFIG_REGULATOR_QCOM_SMD_RPM=y
+CONFIG_REGULATOR_QCOM_SPMI=y
+CONFIG_REGULATOR_VCTRL=m
+CONFIG_RC_CORE=m
+CONFIG_RC_DECODERS=y
+CONFIG_RC_DEVICES=y
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_SDR_SUPPORT=y
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SDR_PLATFORM_DRIVERS=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_QCOM_CAMSS=m
+CONFIG_VIDEO_QCOM_VENUS=m
+CONFIG_VIDEO_QCOM_IRIS=m
+CONFIG_DRM=m
+# CONFIG_DRM_FBDEV_EMULATION is not set
+CONFIG_DRM_HDLCD=m
+CONFIG_DRM_VIRTIO_GPU=m
+CONFIG_DRM_MSM=m
+# CONFIG_DRM_MSM_MDP4 is not set
+# CONFIG_DRM_MSM_MDP5 is not set
+# CONFIG_DRM_MSM_DP is not set
+# CONFIG_DRM_MSM_HDMI is not set
+CONFIG_DRM_PANEL_LVDS=m
+CONFIG_DRM_PANEL_SIMPLE=m
+CONFIG_DRM_PANEL_EDP=m
+CONFIG_DRM_DISPLAY_CONNECTOR=m
+CONFIG_FB=y
+CONFIG_FB_EFI=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=m
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_ALOOP=m
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_QCOM=y
+CONFIG_SND_SOC_APQ8016_SBC=m
+CONFIG_SND_SOC_QDSP6=y
+CONFIG_SND_SOC_MSM8996=m
+CONFIG_SND_SOC_SDM845=m
+CONFIG_SND_SOC_SM8250=m
+CONFIG_SND_SOC_SC7180=m
+CONFIG_SND_SOC_SC7280=m
+CONFIG_SND_SOC_QCM6490=m
+CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m
+CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m
+CONFIG_SND_SOC_WCD9335=m
+CONFIG_SND_SOC_WCD934X=m
+CONFIG_SND_SOC_WCD937X_SDW=y
+CONFIG_SND_SOC_WSA881X=m
+CONFIG_SND_SOC_WSA883X=y
+CONFIG_SND_SOC_LPASS_VA_MACRO=m
+CONFIG_SND_SIMPLE_CARD=m
+CONFIG_SND_AUDIO_GRAPH_CARD=m
+CONFIG_SND_AUDIO_GRAPH_CARD2=m
+CONFIG_SND_VIRTIO=y
+CONFIG_UHID=m
+CONFIG_HID_MULTITOUCH=m
+CONFIG_I2C_HID_ACPI=m
+CONFIG_I2C_HID_OF=m
+CONFIG_USB_CONN_GPIO=y
+CONFIG_USB=y
+CONFIG_USB_OTG=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_ACM=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_QCOM_EUD=m
+CONFIG_USB_ONBOARD_HUB=m
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_ULPI=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_TYPEC=m
+CONFIG_TYPEC_TCPM=m
+CONFIG_TYPEC_TCPCI=m
+CONFIG_TYPEC_UCSI=m
+CONFIG_UCSI_PMIC_GLINK=m
+CONFIG_TYPEC_MUX_FSA4480=m
+CONFIG_TYPEC_MUX_GPIO_SBU=m
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_ARMMMCI=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ACPI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_MMC_SPI=y
+CONFIG_SCSI_UFSHCD=y
+CONFIG_SCSI_UFS_BSG=y
+CONFIG_SCSI_UFS_CRYPTO=y
+CONFIG_SCSI_UFSHCD_PLATFORM=y
+CONFIG_SCSI_UFS_QCOM=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_CLASS_MULTICOLOR=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_SYSCON=y
+CONFIG_LEDS_QCOM_LPG=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_PANIC=y
+CONFIG_LEDS_TRIGGER_PATTERN=y
+CONFIG_EDAC=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_EFI=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_RTC_DRV_PM8XXX=m
+CONFIG_DMADEVICES=y
+CONFIG_PL330_DMA=y
+CONFIG_QCOM_BAM_DMA=y
+CONFIG_QCOM_GPI_DMA=m
+CONFIG_QCOM_HIDMA_MGMT=y
+CONFIG_QCOM_HIDMA=y
+CONFIG_DMABUF_HEAPS_SYSTEM=y
+CONFIG_DMABUF_HEAPS_CMA=y
+CONFIG_VFIO=y
+CONFIG_VFIO_PCI=y
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_MEM=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_XEN_GNTDEV=y
+CONFIG_XEN_GRANT_DEV_ALLOC=y
+CONFIG_STAGING=y
+CONFIG_STAGING_MEDIA=y
+CONFIG_COMMON_CLK_SCMI=y
+CONFIG_COMMON_CLK_SCPI=y
+CONFIG_COMMON_CLK_PWM=y
+CONFIG_COMMON_CLK_QCOM=y
+CONFIG_QCOM_A53PLL=y
+CONFIG_QCOM_CLK_APCS_MSM8916=y
+CONFIG_QCOM_CLK_APCC_MSM8996=y
+CONFIG_QCOM_CLK_SMD_RPM=y
+CONFIG_QCOM_CLK_RPMH=y
+CONFIG_IPQ_APSS_6018=y
+CONFIG_IPQ_GCC_5332=y
+CONFIG_IPQ_GCC_6018=y
+CONFIG_IPQ_GCC_8074=y
+CONFIG_IPQ_GCC_9574=y
+CONFIG_MSM_GCC_8916=y
+CONFIG_MSM_MMCC_8994=m
+CONFIG_MSM_GCC_8994=y
+CONFIG_MSM_MMCC_8996=m
+CONFIG_MSM_GCC_8998=y
+CONFIG_MSM_MMCC_8998=m
+CONFIG_QCM_GCC_2290=y
+CONFIG_QCM_DISPCC_2290=m
+CONFIG_QCS_GCC_404=y
+CONFIG_SC_CAMCC_7280=y
+CONFIG_SC_DISPCC_7280=y
+CONFIG_SC_DISPCC_8280XP=m
+CONFIG_SA_GCC_8775P=y
+CONFIG_SA_GPUCC_8775P=m
+CONFIG_SC_GCC_7180=y
+CONFIG_SC_GCC_8180X=y
+CONFIG_SC_GCC_8280XP=y
+CONFIG_SC_GPUCC_7280=y
+CONFIG_SC_LPASSCC_8280XP=m
+CONFIG_SC_LPASS_CORECC_7280=y
+CONFIG_SC_VIDEOCC_7280=y
+CONFIG_SDM_CAMCC_845=m
+CONFIG_SDM_GPUCC_845=y
+CONFIG_SDM_VIDEOCC_845=y
+CONFIG_SDM_DISPCC_845=y
+CONFIG_SDM_LPASSCC_845=m
+CONFIG_SM_CAMCC_8250=m
+CONFIG_SM_DISPCC_6115=m
+CONFIG_SM_DISPCC_8250=y
+CONFIG_SM_DISPCC_8450=m
+CONFIG_SM_DISPCC_8550=m
+CONFIG_SM_GCC_6115=y
+CONFIG_SM_GCC_8350=y
+CONFIG_SM_GCC_8450=y
+CONFIG_SM_GCC_8550=y
+CONFIG_SM_GPUCC_6115=m
+CONFIG_SM_GPUCC_8150=y
+CONFIG_SM_GPUCC_8250=y
+CONFIG_SM_TCSRCC_8550=y
+CONFIG_SM_VIDEOCC_8250=y
+CONFIG_QCOM_HFPLL=y
+CONFIG_CLK_GFM_LPASS_SM8250=m
+CONFIG_HWSPINLOCK=y
+CONFIG_HWSPINLOCK_QCOM=y
+CONFIG_ARM_MHU=y
+CONFIG_PLATFORM_MHU=y
+CONFIG_QCOM_APCS_IPC=y
+CONFIG_QCOM_IPCC=y
+CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y
+CONFIG_IOMMU_IO_PGTABLE_DART=y
+CONFIG_ARM_SMMU=y
+CONFIG_ARM_SMMU_QCOM_TBU=y
+CONFIG_ARM_SMMU_V3=y
+CONFIG_QCOM_IOMMU=y
+CONFIG_VIRTIO_IOMMU=y
+CONFIG_REMOTEPROC=y
+CONFIG_QCOM_Q6V5_ADSP=m
+CONFIG_QCOM_Q6V5_MSS=m
+CONFIG_QCOM_Q6V5_PAS=m
+CONFIG_QCOM_SYSMON=m
+CONFIG_QCOM_WCNSS_PIL=m
+CONFIG_RPMSG_CHAR=m
+CONFIG_RPMSG_CTRL=m
+CONFIG_RPMSG_QCOM_GLINK_RPM=y
+CONFIG_RPMSG_QCOM_GLINK_SMEM=m
+CONFIG_RPMSG_QCOM_SMD=y
+CONFIG_SOUNDWIRE=y
+CONFIG_SOUNDWIRE_QCOM=y
+CONFIG_SOC_BRCMSTB=y
+CONFIG_FSL_RCPM=y
+CONFIG_QCOM_AOSS_QMP=y
+CONFIG_QCOM_COMMAND_DB=y
+CONFIG_QCOM_CPR=y
+CONFIG_QCOM_GENI_SE=y
+CONFIG_QCOM_LLCC=m
+CONFIG_QCOM_OCMEM=m
+CONFIG_QCOM_PMIC_GLINK=m
+CONFIG_QCOM_RMTFS_MEM=m
+CONFIG_QCOM_RPMH=y
+CONFIG_QCOM_RPMHPD=y
+CONFIG_QCOM_RPMPD=y
+CONFIG_QCOM_SMEM=y
+CONFIG_QCOM_SMD_RPM=y
+CONFIG_QCOM_SMP2P=y
+CONFIG_QCOM_SMSM=y
+CONFIG_QCOM_SOCINFO=m
+CONFIG_QCOM_SPM=m
+CONFIG_QCOM_STATS=m
+CONFIG_QCOM_WCNSS_CTRL=m
+CONFIG_QCOM_APR=y
+CONFIG_QCOM_ICC_BWMON=m
+CONFIG_DEVFREQ_GOV_USERSPACE=y
+CONFIG_DEVFREQ_GOV_PASSIVE=m
+CONFIG_EXTCON_USB_GPIO=y
+CONFIG_MEMORY=y
+CONFIG_IIO=y
+CONFIG_QCOM_SPMI_VADC=m
+CONFIG_QCOM_SPMI_ADC5=y
+CONFIG_PWM=y
+CONFIG_QCOM_PDC=y
+CONFIG_QCOM_MPM=y
+CONFIG_RESET_QCOM_AOSS=y
+CONFIG_RESET_QCOM_PDC=m
+CONFIG_PHY_CAN_TRANSCEIVER=m
+CONFIG_PHY_QCOM_EDP=m
+CONFIG_PHY_QCOM_PCIE2=m
+CONFIG_PHY_QCOM_QMP=y
+CONFIG_PHY_QCOM_QUSB2=m
+CONFIG_PHY_QCOM_SNPS_EUSB2=m
+CONFIG_PHY_QCOM_EUSB2_REPEATER=m
+CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=y
+CONFIG_PHY_QCOM_USB_HS_28NM=m
+CONFIG_PHY_QCOM_USB_SS=m
+CONFIG_PHY_SAMSUNG_USB2=y
+CONFIG_POWERCAP=y
+CONFIG_IDLE_INJECT=y
+CONFIG_ARM_CCI_PMU=m
+CONFIG_ARM_CCN=m
+CONFIG_ARM_CMN=m
+CONFIG_ARM_SMMU_V3_PMU=m
+CONFIG_ARM_DSU_PMU=m
+CONFIG_QCOM_L2_PMU=y
+CONFIG_QCOM_L3_PMU=y
+CONFIG_ARM_SPE_PMU=m
+CONFIG_ARM_DMC620_PMU=m
+CONFIG_HISI_PMU=y
+CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m
+CONFIG_NVMEM_QCOM_QFPROM=y
+CONFIG_NVMEM_RMEM=m
+CONFIG_NVMEM_SPMI_SDAM=m
+CONFIG_STM_SOURCE_CONSOLE=m
+CONFIG_STM_SOURCE_HEARTBEAT=m
+CONFIG_STM_SOURCE_FTRACE=m
+CONFIG_FPGA=y
+CONFIG_FPGA_MGR_ALTERA_CVP=m
+CONFIG_FPGA_BRIDGE=m
+CONFIG_ALTERA_FREEZE_BRIDGE=m
+CONFIG_FPGA_REGION=m
+CONFIG_OF_FPGA_REGION=m
+CONFIG_TEE=y
+CONFIG_OPTEE=y
+CONFIG_MUX_MMIO=m
+CONFIG_SLIMBUS=m
+CONFIG_SLIM_QCOM_CTRL=m
+CONFIG_SLIM_QCOM_NGD_CTRL=m
+CONFIG_INTERCONNECT=y
+CONFIG_INTERCONNECT_QCOM=y
+CONFIG_INTERCONNECT_QCOM_MSM8916=m
+CONFIG_INTERCONNECT_QCOM_MSM8996=m
+CONFIG_INTERCONNECT_QCOM_OSM_L3=m
+CONFIG_INTERCONNECT_QCOM_QCM2290=m
+CONFIG_INTERCONNECT_QCOM_QCS404=m
+CONFIG_INTERCONNECT_QCOM_SA8775P=y
+CONFIG_INTERCONNECT_QCOM_SC7180=y
+CONFIG_INTERCONNECT_QCOM_SC7280=y
+CONFIG_INTERCONNECT_QCOM_SC8180X=y
+CONFIG_INTERCONNECT_QCOM_SC8280XP=y
+CONFIG_INTERCONNECT_QCOM_SDM845=y
+CONFIG_INTERCONNECT_QCOM_SM8150=m
+CONFIG_INTERCONNECT_QCOM_SM8250=m
+CONFIG_INTERCONNECT_QCOM_SM8350=m
+CONFIG_INTERCONNECT_QCOM_SM8450=y
+CONFIG_INTERCONNECT_QCOM_SM8550=y
+CONFIG_COUNTER=m
+CONFIG_HTE=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_FS_ENCRYPTION=y
+CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=m
+CONFIG_VIRTIO_FS=y
+CONFIG_OVERLAY_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_HUGETLBFS=y
+CONFIG_EFIVAR_FS=y
+CONFIG_SQUASHFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
+CONFIG_ROOT_NFS=y
+CONFIG_9P_FS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_FORTIFY_SOURCE=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_ECHAINIV=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_CRYPTO_USER_API_RNG=m
+CONFIG_CRYPTO_USER_API_AEAD=y
+CONFIG_CRYPTO_CHACHA20_NEON=m
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+CONFIG_CRYPTO_SHA1_ARM64_CE=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_SHA512_ARM64_CE=m
+CONFIG_CRYPTO_SHA3_ARM64=m
+CONFIG_CRYPTO_SM3_ARM64_CE=m
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
+CONFIG_CRYPTO_AES_ARM64_BS=m
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_DEV_QCE=m
+CONFIG_CRYPTO_DEV_QCOM_RNG=m
+CONFIG_CRYPTO_DEV_CCREE=m
+CONFIG_INDIRECT_PIO=y
+CONFIG_TRACE_MMIO_ACCESS=y
+CONFIG_CRC_CCITT=m
+CONFIG_DMA_RESTRICTED_POOL=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=32
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_PAGE_OWNER=y
+CONFIG_PANIC_ON_OOPS=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_SCHEDSTATS=y
+CONFIG_CORESIGHT=m
+CONFIG_CORESIGHT_LINK_AND_SINK_TMC=m
+CONFIG_CORESIGHT_CATU=m
+CONFIG_CORESIGHT_SINK_TPIU=m
+CONFIG_CORESIGHT_SINK_ETBV10=m
+CONFIG_CORESIGHT_STM=m
+CONFIG_CORESIGHT_CPU_DEBUG=m
+CONFIG_CORESIGHT_CTI=m
+CONFIG_CORESIGHT_TPDM=m
+CONFIG_CORESIGHT_DUMMY=m
--- linux-qcom-6.8.0.orig/arch/arm64/configs/rubikpi3_defconfig
+++ linux-qcom-6.8.0/arch/arm64/configs/rubikpi3_defconfig
@@ -0,0 +1,881 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_AUDIT=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
+CONFIG_BPF_JIT=y
+CONFIG_PREEMPT=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOCALVERSION="-perf"
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_UCLAMP_TASK=y
+CONFIG_NUMA_BALANCING=y
+CONFIG_CGROUP_FAVOR_DYNMODS=y
+CONFIG_MEMCG=y
+CONFIG_BLK_CGROUP=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_UCLAMP_TASK_GROUP=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_HUGETLB=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
+CONFIG_CGROUP_BPF=y
+CONFIG_USER_NS=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_BOOT_CONFIG=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_PROFILING=y
+CONFIG_ARCH_QCOM=y
+CONFIG_SCHED_MC=y
+CONFIG_SCHED_SMT=y
+CONFIG_NUMA=y
+CONFIG_XEN=y
+CONFIG_ARM64_SW_TTBR0_PAN=y
+CONFIG_COMPAT=y
+CONFIG_RANDOMIZE_BASE=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
+CONFIG_ENERGY_MODEL=y
+CONFIG_ARM_PSCI_CPUIDLE=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=m
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_ACPI_CPPC_CPUFREQ=m
+CONFIG_ARM_SCPI_CPUFREQ=y
+CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
+CONFIG_ARM_QCOM_CPUFREQ_HW=y
+CONFIG_ARM_SCMI_CPUFREQ=y
+CONFIG_ACPI=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM=y
+CONFIG_KPROBES=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_BLK_INLINE_ENCRYPTION=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_SLAB_FREELIST_RANDOM=y
+CONFIG_SLAB_FREELIST_HARDENED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MEMORY_HOTPLUG=y
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_KSM=y
+CONFIG_MEMORY_FAILURE=y
+CONFIG_TRANSPARENT_HUGEPAGE=y
+CONFIG_CMA=y
+CONFIG_CMA_DEBUG=y
+CONFIG_CMA_SYSFS=y
+CONFIG_CMA_AREAS=32
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IPV6=m
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE_NETFILTER=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NETFILTER_XT_MARK=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_IP_VS=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_NAT=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_NET_DSA=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_VLAN_8021Q_MVRP=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBS=m
+CONFIG_NET_SCH_ETF=m
+CONFIG_NET_SCH_TAPRIO=m
+CONFIG_NET_SCH_MQPRIO=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_FLOWER=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_BPF=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=m
+CONFIG_NET_CLS_MATCHALL=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_GATE=m
+CONFIG_VSOCKETS=y
+CONFIG_QRTR_SMD=m
+CONFIG_QRTR_TUN=m
+CONFIG_CAN=m
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+# CONFIG_BT_LE is not set
+CONFIG_BT_LEDS=y
+# CONFIG_BT_DEBUGFS is not set
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_LL=y
+CONFIG_BT_HCIUART_QCA=y
+CONFIG_BT_QCOMSMD=m
+CONFIG_CFG80211=m
+CONFIG_NL80211_TESTMODE=y
+CONFIG_CFG80211_CERTIFICATION_ONUS=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_LEDS=y
+CONFIG_RFKILL=m
+CONFIG_NET_9P=y
+CONFIG_NET_9P_VIRTIO=y
+CONFIG_NFC=m
+CONFIG_NFC_NCI=m
+CONFIG_NFC_S3FWRN5_I2C=m
+CONFIG_PAGE_POOL_STATS=y
+CONFIG_PCI=y
+CONFIG_PCIEPORTBUS=y
+CONFIG_PCIEAER=y
+CONFIG_PCI_IOV=y
+CONFIG_PCI_PASID=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_ACPI=y
+CONFIG_PCI_HOST_GENERIC=y
+CONFIG_PCIE_DW_PLAT_HOST=y
+CONFIG_PCIE_QCOM=y
+CONFIG_PCI_ENDPOINT=y
+CONFIG_PCI_ENDPOINT_CONFIGFS=y
+CONFIG_PCI_EPF_TEST=m
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_FW_LOADER_USER_HELPER=y
+CONFIG_MHI_BUS_PCI_GENERIC=m
+CONFIG_MHI_BUS_EP=y
+CONFIG_ARM_SCMI_PROTOCOL=y
+CONFIG_ARM_SCPI_PROTOCOL=y
+# CONFIG_EFI_DISABLE_RUNTIME is not set
+CONFIG_GNSS=m
+CONFIG_ZRAM=m
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=m
+CONFIG_VIRTIO_BLK=y
+CONFIG_BLK_DEV_NVME=m
+CONFIG_QCOM_COINCELL=m
+CONFIG_QCOM_FASTRPC=m
+CONFIG_SRAM=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_BSG=y
+CONFIG_SCSI_SAS_ATA=y
+CONFIG_SCSI_HISI_SAS=y
+CONFIG_SCSI_HISI_SAS_PCI=y
+CONFIG_MEGARAID_SAS=y
+CONFIG_SCSI_MPT3SAS=m
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_CEVA=y
+CONFIG_SATA_SIL24=y
+CONFIG_PATA_OF_PLATFORM=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_ZERO=m
+CONFIG_NETDEVICES=y
+CONFIG_MACVLAN=y
+CONFIG_MACVTAP=y
+CONFIG_TUN=y
+CONFIG_VETH=m
+CONFIG_VIRTIO_NET=y
+CONFIG_MHI_NET=m
+CONFIG_ATL1C=m
+CONFIG_QCOM_EMAC=m
+CONFIG_RMNET=m
+CONFIG_QCOM_IPA=m
+CONFIG_AT803X_PHY=m
+CONFIG_REALTEK_PHY=m
+CONFIG_CAN_MCP251XFD=m
+CONFIG_MDIO_BITBANG=m
+CONFIG_MDIO_GPIO=m
+CONFIG_MDIO_BUS_MUX_MULTIPLEXER=m
+CONFIG_MDIO_BUS_MUX_MMIOREG=m
+CONFIG_USB_USBNET=m
+CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y
+CONFIG_ATH10K=m
+CONFIG_ATH10K_PCI=m
+CONFIG_ATH10K_SDIO=m
+CONFIG_ATH10K_SNOC=m
+CONFIG_WCN36XX=m
+CONFIG_ATH11K=m
+CONFIG_ATH11K_AHB=m
+CONFIG_ATH11K_PCI=m
+CONFIG_WWAN=m
+CONFIG_MHI_WWAN_CTRL=m
+CONFIG_MHI_WWAN_MBIM=m
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_KEYBOARD_ADC=m
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_PM8941_PWRKEY=y
+CONFIG_INPUT_PM8XXX_VIBRATOR=y
+CONFIG_INPUT_PWM_BEEPER=m
+CONFIG_INPUT_PWM_VIBRA=m
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_QCOM_GENI=y
+CONFIG_SERIAL_QCOM_GENI_CONSOLE=y
+CONFIG_NULL_TTY=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_IPMI_HANDLER=m
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_VIRTIO=y
+# CONFIG_DEVMEM is not set
+CONFIG_TCG_TPM=y
+CONFIG_TCG_TIS=m
+CONFIG_TCG_TIS_SPI=m
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_GPIO=m
+CONFIG_I2C_QCOM_CCI=m
+CONFIG_I2C_QCOM_GENI=m
+CONFIG_I2C_QUP=y
+CONFIG_I2C_SLAVE=y
+CONFIG_I3C=y
+CONFIG_SPI=y
+CONFIG_SPI_PL022=y
+CONFIG_SPI_QCOM_QSPI=m
+CONFIG_SPI_QUP=y
+CONFIG_SPI_QCOM_GENI=m
+CONFIG_SPI_SPIDEV=m
+CONFIG_SPMI=y
+CONFIG_PINCTRL_SINGLE=y
+CONFIG_PINCTRL_MSM=y
+CONFIG_PINCTRL_IPQ5332=y
+CONFIG_PINCTRL_IPQ8074=y
+CONFIG_PINCTRL_IPQ6018=y
+CONFIG_PINCTRL_IPQ9574=y
+CONFIG_PINCTRL_MSM8916=y
+CONFIG_PINCTRL_MSM8953=y
+CONFIG_PINCTRL_MSM8976=y
+CONFIG_PINCTRL_MSM8994=y
+CONFIG_PINCTRL_MSM8996=y
+CONFIG_PINCTRL_MSM8998=y
+CONFIG_PINCTRL_QCM2290=y
+CONFIG_PINCTRL_QCS404=y
+CONFIG_PINCTRL_QCS615=y
+CONFIG_PINCTRL_QCS8300=y
+CONFIG_PINCTRL_QDF2XXX=y
+CONFIG_PINCTRL_QDU1000=y
+CONFIG_PINCTRL_SA8775P=y
+CONFIG_PINCTRL_SC7180=y
+CONFIG_PINCTRL_SC7280=y
+CONFIG_PINCTRL_SC8180X=y
+CONFIG_PINCTRL_SC8280XP=y
+CONFIG_PINCTRL_SDM660=y
+CONFIG_PINCTRL_SDM670=y
+CONFIG_PINCTRL_SDM845=y
+CONFIG_PINCTRL_SM6115=y
+CONFIG_PINCTRL_SM6125=y
+CONFIG_PINCTRL_SM6350=y
+CONFIG_PINCTRL_SM6375=y
+CONFIG_PINCTRL_SM8150=y
+CONFIG_PINCTRL_SM8250=y
+CONFIG_PINCTRL_SM8350=y
+CONFIG_PINCTRL_SM8450=y
+CONFIG_PINCTRL_SM8550=y
+CONFIG_PINCTRL_SM8650=y
+CONFIG_PINCTRL_X1E80100=y
+CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+CONFIG_PINCTRL_LPASS_LPI=m
+CONFIG_PINCTRL_SC7280_LPASS_LPI=m
+CONFIG_PINCTRL_SM8250_LPASS_LPI=m
+CONFIG_PINCTRL_SM8450_LPASS_LPI=m
+CONFIG_PINCTRL_SC8280XP_LPASS_LPI=m
+CONFIG_PINCTRL_SM8550_LPASS_LPI=m
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_PL061=y
+CONFIG_GPIO_WCD934X=m
+CONFIG_POWER_RESET_MSM=y
+CONFIG_POWER_RESET_QCOM_PON=m
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_SYSCON_REBOOT_MODE=y
+CONFIG_BATTERY_QCOM_BATTMGR=m
+CONFIG_SENSORS_ARM_SCMI=y
+CONFIG_SENSORS_ARM_SCPI=y
+CONFIG_SENSORS_GPIO_FAN=m
+CONFIG_SENSORS_PWM_FAN=m
+CONFIG_THERMAL_NETLINK=y
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=10000
+CONFIG_THERMAL_WRITABLE_TRIPS=y
+CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
+CONFIG_CPU_THERMAL=y
+CONFIG_CPU_IDLE_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
+CONFIG_THERMAL_EMULATION=y
+CONFIG_GENERIC_ADC_THERMAL=m
+CONFIG_QCOM_TSENS=y
+CONFIG_QCOM_SPMI_ADC_TM5=m
+CONFIG_QCOM_SPMI_TEMP_ALARM=y
+CONFIG_QCOM_LMH=m
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_SYSFS=y
+CONFIG_WATCHDOG_PRETIMEOUT_GOV=y
+CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP=y
+CONFIG_ARM_SBSA_WATCHDOG=y
+CONFIG_MFD_SPMI_PMIC=y
+CONFIG_MFD_WCD934X=m
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_PWM=y
+CONFIG_REGULATOR_QCOM_REFGEN=y
+CONFIG_REGULATOR_QCOM_RPMH=y
+CONFIG_REGULATOR_QCOM_SMD_RPM=y
+CONFIG_REGULATOR_QCOM_SPMI=y
+CONFIG_REGULATOR_VCTRL=m
+CONFIG_RC_CORE=m
+CONFIG_RC_DECODERS=y
+CONFIG_RC_DEVICES=y
+CONFIG_MEDIA_CEC_SUPPORT=y
+CONFIG_CEC_GPIO=m
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_SDR_SUPPORT=y
+CONFIG_MEDIA_PLATFORM_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SDR_PLATFORM_DRIVERS=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_IMX412=m
+CONFIG_VIDEO_QCOM_CAMSS=m
+CONFIG_VIDEO_QCOM_VENUS=m
+CONFIG_VIDEO_QCOM_IRIS=m
+CONFIG_DRM=m
+CONFIG_DRM_LONTIUM_LT9611UXC=m
+CONFIG_DRM_ANALOGIX_ANX7625=m
+CONFIG_DRM_LONTIUM_LT9611UXC=m
+# CONFIG_DRM_FBDEV_EMULATION is not set
+CONFIG_DRM_HDLCD=m
+CONFIG_DRM_MSM=m
+# CONFIG_DRM_MSM_MDP4 is not set
+# CONFIG_DRM_MSM_MDP5 is not set
+# CONFIG_DRM_MSM_HDMI is not set
+CONFIG_DRM_PANEL_LVDS=m
+CONFIG_DRM_PANEL_SIMPLE=m
+CONFIG_DRM_PANEL_EDP=m
+CONFIG_DRM_PANEL_NOVATEK_NT36672E=m
+CONFIG_DRM_DISPLAY_CONNECTOR=m
+CONFIG_FB=y
+CONFIG_FB_EFI=y
+CONFIG_FB_MODE_HELPERS=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_PWM=m
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_ALOOP=m
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_AUDIO_MIDI_V2=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_QCOM=y
+CONFIG_SND_SOC_APQ8016_SBC=m
+CONFIG_SND_SOC_QDSP6=y
+CONFIG_SND_SOC_MSM8996=m
+CONFIG_SND_SOC_SDM845=m
+CONFIG_SND_SOC_SM8250=m
+CONFIG_SND_SOC_SC7180=m
+CONFIG_SND_SOC_SC7280=m
+CONFIG_SND_SOC_QCM6490=m
+CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m
+CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m
+CONFIG_SND_SOC_WCD9335=m
+CONFIG_SND_SOC_WCD934X=m
+CONFIG_SND_SOC_WCD937X_SDW=y
+CONFIG_SND_SOC_WSA881X=m
+CONFIG_SND_SOC_WSA883X=y
+CONFIG_SND_SOC_LPASS_VA_MACRO=m
+CONFIG_SND_SIMPLE_CARD=m
+CONFIG_SND_AUDIO_GRAPH_CARD=m
+CONFIG_SND_AUDIO_GRAPH_CARD2=m
+CONFIG_UHID=m
+CONFIG_HID_MULTITOUCH=m
+CONFIG_USB_HID=m
+CONFIG_HID_PID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_I2C_HID_ACPI=m
+CONFIG_I2C_HID_OF=m
+CONFIG_USB_CONN_GPIO=y
+CONFIG_USB=y
+CONFIG_USB_OTG=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_PCI_RENESAS=m
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_ACM=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_UAS=y
+CONFIG_USB_DWC3=y
+CONFIG_USB_DWC2=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_CH341=m
+CONFIG_USB_SERIAL_CP210X=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_QCOM_EUD=m
+CONFIG_USB_ONBOARD_HUB=m
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_ULPI=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_CONFIGFS=y
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_CONFIGFS_F_UAC2=y
+CONFIG_USB_CONFIGFS_F_UVC=y
+CONFIG_TYPEC=m
+CONFIG_TYPEC_TCPM=m
+CONFIG_TYPEC_TCPCI=m
+CONFIG_TYPEC_UCSI=m
+CONFIG_UCSI_PMIC_GLINK=m
+CONFIG_TYPEC_MUX_FSA4480=m
+CONFIG_TYPEC_MUX_GPIO_SBU=m
+CONFIG_TYPEC_MUX_NB7VPQ904M=m
+CONFIG_MMC=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_CRYPTO=y
+CONFIG_MMC_ARMMMCI=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ACPI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_MMC_SPI=y
+CONFIG_SCSI_UFSHCD=y
+CONFIG_SCSI_UFS_BSG=y
+CONFIG_SCSI_UFS_CRYPTO=y
+CONFIG_SCSI_UFSHCD_PLATFORM=y
+CONFIG_SCSI_UFS_QCOM=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_CLASS_FLASH=m
+CONFIG_LEDS_CLASS_MULTICOLOR=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
+CONFIG_LEDS_SYSCON=y
+CONFIG_LEDS_QCOM_FLASH=m
+CONFIG_LEDS_QCOM_LPG=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_PANIC=y
+CONFIG_LEDS_TRIGGER_PATTERN=y
+CONFIG_EDAC=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_EFI=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_RTC_DRV_PM8XXX=m
+CONFIG_DMADEVICES=y
+CONFIG_PL330_DMA=y
+CONFIG_QCOM_BAM_DMA=y
+CONFIG_QCOM_GPI_DMA=m
+CONFIG_QCOM_HIDMA_MGMT=y
+CONFIG_QCOM_HIDMA=y
+CONFIG_DMABUF_HEAPS_SYSTEM=y
+CONFIG_DMABUF_HEAPS_CMA=y
+CONFIG_UIO=y
+CONFIG_VFIO=y
+CONFIG_VFIO_PCI=y
+CONFIG_VFIO_PLATFORM=m
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_XEN_GNTDEV=y
+CONFIG_XEN_GRANT_DEV_ALLOC=y
+CONFIG_VHOST_NET=y
+CONFIG_VHOST_VSOCK=y
+CONFIG_STAGING=y
+CONFIG_STAGING_MEDIA=y
+CONFIG_COMMON_CLK_SCMI=y
+CONFIG_COMMON_CLK_SCPI=y
+CONFIG_COMMON_CLK_PWM=y
+CONFIG_COMMON_CLK_QCOM=y
+CONFIG_CLK_X1E80100_GCC=y
+CONFIG_QCOM_A53PLL=y
+CONFIG_QCOM_CLK_APCS_MSM8916=y
+CONFIG_QCOM_CLK_APCC_MSM8996=y
+CONFIG_QCOM_CLK_SMD_RPM=y
+CONFIG_QCOM_CLK_RPMH=y
+CONFIG_IPQ_APSS_6018=y
+CONFIG_IPQ_GCC_5332=y
+CONFIG_IPQ_GCC_6018=y
+CONFIG_IPQ_GCC_8074=y
+CONFIG_IPQ_GCC_9574=y
+CONFIG_MSM_GCC_8916=y
+CONFIG_MSM_MMCC_8994=m
+CONFIG_MSM_GCC_8994=y
+CONFIG_MSM_MMCC_8996=m
+CONFIG_MSM_GCC_8998=y
+CONFIG_MSM_MMCC_8998=m
+CONFIG_QCM_GCC_2290=y
+CONFIG_QCM_DISPCC_2290=m
+CONFIG_QCS_DISPCC_615=m
+CONFIG_QCS_CAMCC_615=m
+CONFIG_QCS_GCC_404=y
+CONFIG_QCS_GCC_615=y
+CONFIG_QCS_GPUCC_615=m
+CONFIG_QCS_VIDEOCC_615=m
+CONFIG_QCS_GCC_8300=y
+CONFIG_SC_CAMCC_7280=y
+CONFIG_SC_DISPCC_7280=y
+CONFIG_SC_DISPCC_8280XP=m
+CONFIG_SA_GCC_8775P=y
+CONFIG_SA_CAMCC_8775P=m
+CONFIG_SA_DISPCC_8775P=m
+CONFIG_SA_VIDEOCC_8775P=m
+CONFIG_SA_GPUCC_8775P=y
+CONFIG_SC_GCC_7180=y
+CONFIG_SC_GCC_8180X=y
+CONFIG_SC_GCC_8280XP=y
+CONFIG_SC_GPUCC_7280=y
+CONFIG_SC_LPASSCC_8280XP=m
+CONFIG_SC_LPASS_CORECC_7280=y
+CONFIG_SC_VIDEOCC_7280=y
+CONFIG_SDM_CAMCC_845=m
+CONFIG_SDM_GPUCC_845=y
+CONFIG_SDM_VIDEOCC_845=y
+CONFIG_SDM_DISPCC_845=y
+CONFIG_SDM_LPASSCC_845=m
+CONFIG_SM_CAMCC_8250=m
+CONFIG_SM_CAMCC_8550=m
+CONFIG_SM_DISPCC_6115=m
+CONFIG_SM_DISPCC_8250=y
+CONFIG_SM_DISPCC_8450=m
+CONFIG_SM_DISPCC_8550=m
+CONFIG_SM_DISPCC_8650=y
+CONFIG_SM_GCC_6115=y
+CONFIG_SM_GCC_8350=y
+CONFIG_SM_GCC_8450=y
+CONFIG_SM_GCC_8650=y
+CONFIG_SM_GPUCC_6115=m
+CONFIG_SM_GPUCC_8150=y
+CONFIG_SM_GPUCC_8250=y
+CONFIG_SM_GPUCC_8550=y
+CONFIG_SM_GPUCC_8650=y
+CONFIG_SM_TCSRCC_8550=y
+CONFIG_SM_TCSRCC_8650=y
+CONFIG_SM_VIDEOCC_8250=y
+CONFIG_SM_VIDEOCC_8550=y
+CONFIG_QCOM_HFPLL=y
+CONFIG_CLK_GFM_LPASS_SM8250=m
+CONFIG_HWSPINLOCK=y
+CONFIG_HWSPINLOCK_QCOM=y
+CONFIG_ARM_MHU=y
+CONFIG_PLATFORM_MHU=y
+CONFIG_QCOM_APCS_IPC=y
+CONFIG_QCOM_IPCC=y
+CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y
+CONFIG_IOMMU_IO_PGTABLE_DART=y
+CONFIG_ARM_SMMU=y
+CONFIG_ARM_SMMU_QCOM_TBU=y
+CONFIG_ARM_SMMU_V3=y
+CONFIG_QCOM_IOMMU=y
+CONFIG_REMOTEPROC=y
+CONFIG_QCOM_Q6V5_ADSP=m
+CONFIG_QCOM_Q6V5_MSS=m
+CONFIG_QCOM_Q6V5_PAS=m
+CONFIG_QCOM_SYSMON=m
+CONFIG_QCOM_WCNSS_PIL=m
+CONFIG_RPMSG_CHAR=m
+CONFIG_RPMSG_CTRL=m
+CONFIG_RPMSG_QCOM_GLINK_RPM=y
+CONFIG_RPMSG_QCOM_GLINK_SMEM=m
+CONFIG_RPMSG_QCOM_SMD=y
+CONFIG_SOUNDWIRE=y
+CONFIG_SOUNDWIRE_QCOM=y
+CONFIG_SOC_BRCMSTB=y
+CONFIG_FSL_RCPM=y
+CONFIG_QCOM_AOSS_QMP=y
+CONFIG_QCOM_COMMAND_DB=y
+CONFIG_QCOM_CPR=y
+CONFIG_QCOM_GENI_SE=y
+CONFIG_QCOM_LLCC=m
+CONFIG_QCOM_OCMEM=m
+CONFIG_QCOM_PMIC_GLINK=m
+CONFIG_QCOM_RMTFS_MEM=m
+CONFIG_QCOM_RPMH=y
+CONFIG_QCOM_RPMHPD=y
+CONFIG_QCOM_RPMPD=y
+CONFIG_QCOM_SMEM=y
+CONFIG_QCOM_SMD_RPM=y
+CONFIG_QCOM_SMP2P=y
+CONFIG_QCOM_SMSM=y
+CONFIG_QCOM_SOCINFO=m
+CONFIG_QCOM_SPM=m
+CONFIG_QCOM_STATS=m
+CONFIG_QCOM_WCNSS_CTRL=m
+CONFIG_QCOM_APR=y
+CONFIG_QCOM_ICC_BWMON=m
+CONFIG_DEVFREQ_GOV_USERSPACE=y
+CONFIG_DEVFREQ_GOV_PASSIVE=m
+CONFIG_EXTCON_USB_GPIO=y
+CONFIG_MEMORY=y
+CONFIG_IIO=y
+CONFIG_QCOM_SPMI_VADC=m
+CONFIG_QCOM_SPMI_ADC5=y
+CONFIG_PWM=y
+CONFIG_QCOM_PDC=y
+CONFIG_QCOM_MPM=y
+CONFIG_RESET_QCOM_AOSS=y
+CONFIG_RESET_QCOM_PDC=m
+CONFIG_PHY_CAN_TRANSCEIVER=m
+CONFIG_PHY_QCOM_EDP=m
+CONFIG_PHY_QCOM_PCIE2=m
+CONFIG_PHY_QCOM_QMP=y
+CONFIG_PHY_QCOM_QUSB2=m
+CONFIG_PHY_QCOM_SNPS_EUSB2=m
+CONFIG_PHY_QCOM_EUSB2_REPEATER=m
+CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2=y
+CONFIG_PHY_QCOM_USB_HS_28NM=m
+CONFIG_PHY_QCOM_USB_SS=m
+CONFIG_POWERCAP=y
+CONFIG_IDLE_INJECT=y
+CONFIG_ARM_CCI_PMU=m
+CONFIG_ARM_CCN=m
+CONFIG_ARM_CMN=m
+CONFIG_ARM_SMMU_V3_PMU=m
+CONFIG_ARM_DSU_PMU=m
+CONFIG_QCOM_L2_PMU=y
+CONFIG_QCOM_L3_PMU=y
+CONFIG_ARM_SPE_PMU=m
+CONFIG_ARM_DMC620_PMU=m
+CONFIG_HISI_PMU=y
+CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU=m
+CONFIG_NVMEM_QCOM_QFPROM=y
+CONFIG_NVMEM_RMEM=m
+CONFIG_NVMEM_SPMI_SDAM=m
+CONFIG_STM_SOURCE_CONSOLE=m
+CONFIG_STM_SOURCE_HEARTBEAT=m
+CONFIG_STM_SOURCE_FTRACE=m
+CONFIG_FPGA=y
+CONFIG_FPGA_MGR_ALTERA_CVP=m
+CONFIG_FPGA_BRIDGE=m
+CONFIG_ALTERA_FREEZE_BRIDGE=m
+CONFIG_FPGA_REGION=m
+CONFIG_OF_FPGA_REGION=m
+CONFIG_TEE=y
+CONFIG_OPTEE=y
+CONFIG_MUX_MMIO=m
+CONFIG_SLIMBUS=m
+CONFIG_SLIM_QCOM_CTRL=m
+CONFIG_SLIM_QCOM_NGD_CTRL=m
+CONFIG_INTERCONNECT=y
+CONFIG_INTERCONNECT_QCOM=y
+CONFIG_INTERCONNECT_QCOM_MSM8916=m
+CONFIG_INTERCONNECT_QCOM_MSM8996=m
+CONFIG_INTERCONNECT_QCOM_OSM_L3=m
+CONFIG_INTERCONNECT_QCOM_QCM2290=m
+CONFIG_INTERCONNECT_QCOM_QCS404=m
+CONFIG_INTERCONNECT_QCOM_QCS615=y
+CONFIG_INTERCONNECT_QCOM_QCS8300=y
+CONFIG_INTERCONNECT_QCOM_SA8775P=y
+CONFIG_INTERCONNECT_QCOM_SC7180=y
+CONFIG_INTERCONNECT_QCOM_SC7280=y
+CONFIG_INTERCONNECT_QCOM_SC8180X=y
+CONFIG_INTERCONNECT_QCOM_SC8280XP=y
+CONFIG_INTERCONNECT_QCOM_SDM845=y
+CONFIG_INTERCONNECT_QCOM_SM8150=m
+CONFIG_INTERCONNECT_QCOM_SM8250=m
+CONFIG_INTERCONNECT_QCOM_SM8350=m
+CONFIG_INTERCONNECT_QCOM_SM8450=y
+CONFIG_INTERCONNECT_QCOM_SM8550=y
+CONFIG_INTERCONNECT_QCOM_SM8650=y
+CONFIG_INTERCONNECT_QCOM_X1E80100=y
+CONFIG_COUNTER=m
+CONFIG_HTE=y
+# CONFIG_EXT2_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_EXT4_USE_FOR_EXT2=y
+CONFIG_FS_ENCRYPTION=y
+CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_OVERLAY_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_HUGETLBFS=y
+CONFIG_EFIVAR_FS=y
+CONFIG_SQUASHFS=y
+CONFIG_EFI_PARTITION=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
+CONFIG_ROOT_NFS=y
+CONFIG_9P_FS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_FORTIFY_SOURCE=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_ECHAINIV=y
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_LZ4=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_CRYPTO_USER_API_HASH=y
+CONFIG_CRYPTO_USER_API_SKCIPHER=y
+CONFIG_CRYPTO_USER_API_RNG=m
+CONFIG_CRYPTO_USER_API_AEAD=y
+CONFIG_CRYPTO_CHACHA20_NEON=m
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+CONFIG_CRYPTO_SHA1_ARM64_CE=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_SHA512_ARM64_CE=m
+CONFIG_CRYPTO_SHA3_ARM64=m
+CONFIG_CRYPTO_SM3_ARM64_CE=m
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
+CONFIG_CRYPTO_AES_ARM64_BS=m
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_DEV_QCE=m
+CONFIG_CRYPTO_DEV_QCOM_RNG=m
+CONFIG_CRYPTO_DEV_CCREE=m
+# CONFIG_HW_RANDOM_ARM_SMCCC_TRNG is not set
+CONFIG_INDIRECT_PIO=y
+CONFIG_TRACE_MMIO_ACCESS=y
+CONFIG_CRC_CCITT=m
+CONFIG_DMA_RESTRICTED_POOL=y
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=32
+CONFIG_PRINTK_TIME=y
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=6
+CONFIG_DYNAMIC_DEBUG_CORE=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_PAGE_OWNER=y
+CONFIG_PANIC_ON_OOPS=y
+CONFIG_SCHEDSTATS=y
+CONFIG_CORESIGHT=m
+CONFIG_CORESIGHT_LINK_AND_SINK_TMC=m
+CONFIG_CORESIGHT_CATU=m
+CONFIG_CORESIGHT_SINK_TPIU=m
+CONFIG_CORESIGHT_SINK_ETBV10=m
+CONFIG_CORESIGHT_STM=m
+CONFIG_CORESIGHT_CPU_DEBUG=m
+CONFIG_CORESIGHT_CTI=m
+CONFIG_CORESIGHT_TPDM=m
+CONFIG_CORESIGHT_DUMMY=m
+CONFIG_NFT_NAT=y
+CONFIG_NF_NAT=y
+CONFIG_NF_TABLES=y
+CONFIG_NF_TABLES_INET=y
+CONFIG_STMMAC_ETH=m
+CONFIG_MARVELL_PHY=m
+CONFIG_PHY_QCOM_SGMII_ETH=m
+CONFIG_ATH11K_DEBUGFS=y
+CONFIG_MAC80211_DEBUGFS=y
+CONFIG_ARM64_PMEM=y
+CONFIG_IXGBE=y
+CONFIG_IXGBEVF=y
+CONFIG_AQUANTIA_PHY=y
+CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y
+CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT=y
+CONFIG_TYPEC_HD3SS3220=m
+CONFIG_AX88179B=m
+CONFIG_WLAN_VENDOR_BCMDHD=y
+CONFIG_BCMDHD=m
+CONFIG_BCMDHD_FW_PATH="/lib/firmware/fw_bcmdhd.bin"
+CONFIG_BCMDHD_NVRAM_PATH="/lib/firmware/nvram.txt"
+CONFIG_BCMDHD_PCIE=n
+CONFIG_BCMDHD_USB=n
+CONFIG_BCMDHD_SDIO_IRQ=n
+CONFIG_BCMDHD_SDIO=y
+CONFIG_BCMDHD_OOB=y
--- linux-qcom-6.8.0.orig/arch/arm64/gunyah/Makefile
+++ linux-qcom-6.8.0/arch/arm64/gunyah/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_GUNYAH) += gunyah_hypercall.o
--- linux-qcom-6.8.0.orig/arch/arm64/gunyah/gunyah_hypercall.c
+++ linux-qcom-6.8.0/arch/arm64/gunyah/gunyah_hypercall.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/module.h>
+#include <linux/gunyah.h>
+#include <linux/uuid.h>
+
+/* {c1d58fcd-a453-5fdb-9265-ce36673d5f14} */
+static const uuid_t GUNYAH_UUID =
+	UUID_INIT(0xc1d58fcd, 0xa453, 0x5fdb, 0x92, 0x65, 0xce, 0x36, 0x67, 0x3d, 0x5f, 0x14);
+
+bool arch_is_gh_guest(void)
+{
+	struct arm_smccc_res res;
+	uuid_t uuid;
+	u32 *up;
+
+	arm_smccc_1_1_hvc(ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID, &res);
+
+	up = (u32 *)&uuid.b[0];
+	up[0] = lower_32_bits(res.a0);
+	up[1] = lower_32_bits(res.a1);
+	up[2] = lower_32_bits(res.a2);
+	up[3] = lower_32_bits(res.a3);
+
+	return uuid_equal(&uuid, &GUNYAH_UUID);
+}
+EXPORT_SYMBOL_GPL(arch_is_gh_guest);
+
+#define GH_HYPERCALL(fn)	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \
+						   ARM_SMCCC_OWNER_VENDOR_HYP, \
+						   fn)
+
+#define GH_HYPERCALL_HYP_IDENTIFY		GH_HYPERCALL(0x8000)
+#define GH_HYPERCALL_BELL_SEND			GH_HYPERCALL(0x8012)
+#define GH_HYPERCALL_BELL_SET_MASK		GH_HYPERCALL(0x8015)
+#define GH_HYPERCALL_MSGQ_SEND			GH_HYPERCALL(0x801B)
+#define GH_HYPERCALL_MSGQ_RECV			GH_HYPERCALL(0x801C)
+#define GH_HYPERCALL_VCPU_RUN			GH_HYPERCALL(0x8065)
+
+/**
+ * gh_hypercall_hyp_identify() - Returns build information and feature flags
+ *                               supported by Gunyah.
+ * @hyp_identity: filled by the hypercall with the API info and feature flags.
+ */
+void gh_hypercall_hyp_identify(struct gh_hypercall_hyp_identify_resp *hyp_identity)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_hvc(GH_HYPERCALL_HYP_IDENTIFY, &res);
+
+	hyp_identity->api_info = res.a0;
+	hyp_identity->flags[0] = res.a1;
+	hyp_identity->flags[1] = res.a2;
+	hyp_identity->flags[2] = res.a3;
+}
+EXPORT_SYMBOL_GPL(gh_hypercall_hyp_identify);
+
+enum gh_error gh_hypercall_bell_send(u64 capid, u64 new_flags, u64 *old_flags)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_hvc(GH_HYPERCALL_BELL_SEND, capid, new_flags, 0, &res);
+
+	if (res.a0 == GH_ERROR_OK && old_flags)
+		*old_flags = res.a1;
+
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(gh_hypercall_bell_send);
+
+enum gh_error gh_hypercall_bell_set_mask(u64 capid, u64 enable_mask, u64 ack_mask)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_hvc(GH_HYPERCALL_BELL_SET_MASK, capid, enable_mask, ack_mask, 0, &res);
+
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(gh_hypercall_bell_set_mask);
+
+enum gh_error gh_hypercall_msgq_send(u64 capid, size_t size, void *buff, u64 tx_flags, bool *ready)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_hvc(GH_HYPERCALL_MSGQ_SEND, capid, size, (uintptr_t)buff, tx_flags, 0, &res);
+
+	if (res.a0 == GH_ERROR_OK)
+		*ready = !!res.a1;
+
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(gh_hypercall_msgq_send);
+
+enum gh_error gh_hypercall_msgq_recv(u64 capid, void *buff, size_t size, size_t *recv_size,
+					bool *ready)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_1_1_hvc(GH_HYPERCALL_MSGQ_RECV, capid, (uintptr_t)buff, size, 0, &res);
+
+	if (res.a0 == GH_ERROR_OK) {
+		*recv_size = res.a1;
+		*ready = !!res.a2;
+	}
+
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(gh_hypercall_msgq_recv);
+
+enum gh_error gh_hypercall_vcpu_run(u64 capid, u64 *resume_data,
+					struct gh_hypercall_vcpu_run_resp *resp)
+{
+	struct arm_smccc_1_2_regs args = {
+		.a0 = GH_HYPERCALL_VCPU_RUN,
+		.a1 = capid,
+		.a2 = resume_data[0],
+		.a3 = resume_data[1],
+		.a4 = resume_data[2],
+		/* C language says this will be implictly zero. Gunyah requires 0, so be explicit */
+		.a5 = 0,
+	};
+	struct arm_smccc_1_2_regs res;
+
+	arm_smccc_1_2_hvc(&args, &res);
+
+	if (res.a0 == GH_ERROR_OK) {
+		resp->sized_state = res.a1;
+		resp->state_data[0] = res.a2;
+		resp->state_data[1] = res.a3;
+		resp->state_data[2] = res.a4;
+	}
+
+	return res.a0;
+}
+EXPORT_SYMBOL_GPL(gh_hypercall_vcpu_run);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Gunyah Hypervisor Hypercalls");
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/acpi.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/acpi.h
@@ -119,6 +119,18 @@
 	return	acpi_cpu_get_madt_gicc(cpu)->uid;
 }
 
+static inline int get_cpu_for_acpi_id(u32 uid)
+{
+	int cpu;
+
+	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
+		if (acpi_cpu_get_madt_gicc(cpu) &&
+		    uid == get_acpi_id_for_cpu(cpu))
+			return cpu;
+
+	return -EINVAL;
+}
+
 static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 void __init acpi_init_cpus(void);
 int apei_claim_sea(struct pt_regs *regs);
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/asm-bug.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/asm-bug.h
@@ -28,6 +28,7 @@
 	14470:	.long 14471f - .;			\
 _BUGVERBOSE_LOCATION(__FILE__, __LINE__)		\
 		.short flags; 				\
+		.align 2;				\
 		.popsection;				\
 	14471:
 #else
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/barrier.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/barrier.h
@@ -40,6 +40,10 @@
  */
 #define dgh()		asm volatile("hint #6" : : : "memory")
 
+#define spec_bar()	asm volatile(ALTERNATIVE("dsb nsh\nisb\n",		\
+						 SB_BARRIER_INSN"nop\n",	\
+						 ARM64_HAS_SB))
+
 #ifdef CONFIG_ARM64_PSEUDO_NMI
 #define pmr_sync()						\
 	do {							\
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/cpucaps.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/cpucaps.h
@@ -58,6 +58,8 @@
 		return IS_ENABLED(CONFIG_NVIDIA_CARMEL_CNP_ERRATUM);
 	case ARM64_WORKAROUND_REPEAT_TLBI:
 		return IS_ENABLED(CONFIG_ARM64_WORKAROUND_REPEAT_TLBI);
+	case ARM64_WORKAROUND_SPECULATIVE_SSBS:
+		return IS_ENABLED(CONFIG_ARM64_WORKAROUND_SPECULATIVE_SSBS);
 	}
 
 	return true;
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/cputype.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/cputype.h
@@ -86,6 +86,15 @@
 #define ARM_CPU_PART_CORTEX_X2		0xD48
 #define ARM_CPU_PART_NEOVERSE_N2	0xD49
 #define ARM_CPU_PART_CORTEX_A78C	0xD4B
+#define ARM_CPU_PART_CORTEX_X1C		0xD4C
+#define ARM_CPU_PART_CORTEX_X3		0xD4E
+#define ARM_CPU_PART_NEOVERSE_V2	0xD4F
+#define ARM_CPU_PART_CORTEX_A720	0xD81
+#define ARM_CPU_PART_CORTEX_X4		0xD82
+#define ARM_CPU_PART_NEOVERSE_V3	0xD84
+#define ARM_CPU_PART_CORTEX_X925	0xD85
+#define ARM_CPU_PART_CORTEX_A725	0xD87
+#define ARM_CPU_PART_NEOVERSE_N3	0xD8E
 
 #define APM_CPU_PART_XGENE		0x000
 #define APM_CPU_VAR_POTENZA		0x00
@@ -135,6 +144,7 @@
 #define APPLE_CPU_PART_M2_AVALANCHE_MAX	0x039
 
 #define AMPERE_CPU_PART_AMPERE1		0xAC3
+#define AMPERE_CPU_PART_AMPERE1A	0xAC4
 
 #define MICROSOFT_CPU_PART_AZURE_COBALT_100	0xD49 /* Based on r0p0 of ARM Neoverse N2 */
 
@@ -159,6 +169,15 @@
 #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2)
 #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2)
 #define MIDR_CORTEX_A78C	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C)
+#define MIDR_CORTEX_X1C	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1C)
+#define MIDR_CORTEX_X3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X3)
+#define MIDR_NEOVERSE_V2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V2)
+#define MIDR_CORTEX_A720 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720)
+#define MIDR_CORTEX_X4 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X4)
+#define MIDR_NEOVERSE_V3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_V3)
+#define MIDR_CORTEX_X925 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X925)
+#define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
+#define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)
 #define MIDR_THUNDERX	MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
 #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
 #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX)
@@ -196,6 +215,7 @@
 #define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)
 #define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX)
 #define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1)
+#define MIDR_AMPERE1A MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1A)
 #define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_AZURE_COBALT_100)
 
 /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/esr.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/esr.h
@@ -10,63 +10,63 @@
 #include <asm/memory.h>
 #include <asm/sysreg.h>
 
-#define ESR_ELx_EC_UNKNOWN	(0x00)
-#define ESR_ELx_EC_WFx		(0x01)
+#define ESR_ELx_EC_UNKNOWN	UL(0x00)
+#define ESR_ELx_EC_WFx		UL(0x01)
 /* Unallocated EC: 0x02 */
-#define ESR_ELx_EC_CP15_32	(0x03)
-#define ESR_ELx_EC_CP15_64	(0x04)
-#define ESR_ELx_EC_CP14_MR	(0x05)
-#define ESR_ELx_EC_CP14_LS	(0x06)
-#define ESR_ELx_EC_FP_ASIMD	(0x07)
-#define ESR_ELx_EC_CP10_ID	(0x08)	/* EL2 only */
-#define ESR_ELx_EC_PAC		(0x09)	/* EL2 and above */
+#define ESR_ELx_EC_CP15_32	UL(0x03)
+#define ESR_ELx_EC_CP15_64	UL(0x04)
+#define ESR_ELx_EC_CP14_MR	UL(0x05)
+#define ESR_ELx_EC_CP14_LS	UL(0x06)
+#define ESR_ELx_EC_FP_ASIMD	UL(0x07)
+#define ESR_ELx_EC_CP10_ID	UL(0x08)	/* EL2 only */
+#define ESR_ELx_EC_PAC		UL(0x09)	/* EL2 and above */
 /* Unallocated EC: 0x0A - 0x0B */
-#define ESR_ELx_EC_CP14_64	(0x0C)
-#define ESR_ELx_EC_BTI		(0x0D)
-#define ESR_ELx_EC_ILL		(0x0E)
+#define ESR_ELx_EC_CP14_64	UL(0x0C)
+#define ESR_ELx_EC_BTI		UL(0x0D)
+#define ESR_ELx_EC_ILL		UL(0x0E)
 /* Unallocated EC: 0x0F - 0x10 */
-#define ESR_ELx_EC_SVC32	(0x11)
-#define ESR_ELx_EC_HVC32	(0x12)	/* EL2 only */
-#define ESR_ELx_EC_SMC32	(0x13)	/* EL2 and above */
+#define ESR_ELx_EC_SVC32	UL(0x11)
+#define ESR_ELx_EC_HVC32	UL(0x12)	/* EL2 only */
+#define ESR_ELx_EC_SMC32	UL(0x13)	/* EL2 and above */
 /* Unallocated EC: 0x14 */
-#define ESR_ELx_EC_SVC64	(0x15)
-#define ESR_ELx_EC_HVC64	(0x16)	/* EL2 and above */
-#define ESR_ELx_EC_SMC64	(0x17)	/* EL2 and above */
-#define ESR_ELx_EC_SYS64	(0x18)
-#define ESR_ELx_EC_SVE		(0x19)
-#define ESR_ELx_EC_ERET		(0x1a)	/* EL2 only */
+#define ESR_ELx_EC_SVC64	UL(0x15)
+#define ESR_ELx_EC_HVC64	UL(0x16)	/* EL2 and above */
+#define ESR_ELx_EC_SMC64	UL(0x17)	/* EL2 and above */
+#define ESR_ELx_EC_SYS64	UL(0x18)
+#define ESR_ELx_EC_SVE		UL(0x19)
+#define ESR_ELx_EC_ERET		UL(0x1a)	/* EL2 only */
 /* Unallocated EC: 0x1B */
-#define ESR_ELx_EC_FPAC		(0x1C)	/* EL1 and above */
-#define ESR_ELx_EC_SME		(0x1D)
+#define ESR_ELx_EC_FPAC		UL(0x1C)	/* EL1 and above */
+#define ESR_ELx_EC_SME		UL(0x1D)
 /* Unallocated EC: 0x1E */
-#define ESR_ELx_EC_IMP_DEF	(0x1f)	/* EL3 only */
-#define ESR_ELx_EC_IABT_LOW	(0x20)
-#define ESR_ELx_EC_IABT_CUR	(0x21)
-#define ESR_ELx_EC_PC_ALIGN	(0x22)
+#define ESR_ELx_EC_IMP_DEF	UL(0x1f)	/* EL3 only */
+#define ESR_ELx_EC_IABT_LOW	UL(0x20)
+#define ESR_ELx_EC_IABT_CUR	UL(0x21)
+#define ESR_ELx_EC_PC_ALIGN	UL(0x22)
 /* Unallocated EC: 0x23 */
-#define ESR_ELx_EC_DABT_LOW	(0x24)
-#define ESR_ELx_EC_DABT_CUR	(0x25)
-#define ESR_ELx_EC_SP_ALIGN	(0x26)
-#define ESR_ELx_EC_MOPS		(0x27)
-#define ESR_ELx_EC_FP_EXC32	(0x28)
+#define ESR_ELx_EC_DABT_LOW	UL(0x24)
+#define ESR_ELx_EC_DABT_CUR	UL(0x25)
+#define ESR_ELx_EC_SP_ALIGN	UL(0x26)
+#define ESR_ELx_EC_MOPS		UL(0x27)
+#define ESR_ELx_EC_FP_EXC32	UL(0x28)
 /* Unallocated EC: 0x29 - 0x2B */
-#define ESR_ELx_EC_FP_EXC64	(0x2C)
+#define ESR_ELx_EC_FP_EXC64	UL(0x2C)
 /* Unallocated EC: 0x2D - 0x2E */
-#define ESR_ELx_EC_SERROR	(0x2F)
-#define ESR_ELx_EC_BREAKPT_LOW	(0x30)
-#define ESR_ELx_EC_BREAKPT_CUR	(0x31)
-#define ESR_ELx_EC_SOFTSTP_LOW	(0x32)
-#define ESR_ELx_EC_SOFTSTP_CUR	(0x33)
-#define ESR_ELx_EC_WATCHPT_LOW	(0x34)
-#define ESR_ELx_EC_WATCHPT_CUR	(0x35)
+#define ESR_ELx_EC_SERROR	UL(0x2F)
+#define ESR_ELx_EC_BREAKPT_LOW	UL(0x30)
+#define ESR_ELx_EC_BREAKPT_CUR	UL(0x31)
+#define ESR_ELx_EC_SOFTSTP_LOW	UL(0x32)
+#define ESR_ELx_EC_SOFTSTP_CUR	UL(0x33)
+#define ESR_ELx_EC_WATCHPT_LOW	UL(0x34)
+#define ESR_ELx_EC_WATCHPT_CUR	UL(0x35)
 /* Unallocated EC: 0x36 - 0x37 */
-#define ESR_ELx_EC_BKPT32	(0x38)
+#define ESR_ELx_EC_BKPT32	UL(0x38)
 /* Unallocated EC: 0x39 */
-#define ESR_ELx_EC_VECTOR32	(0x3A)	/* EL2 only */
+#define ESR_ELx_EC_VECTOR32	UL(0x3A)	/* EL2 only */
 /* Unallocated EC: 0x3B */
-#define ESR_ELx_EC_BRK64	(0x3C)
+#define ESR_ELx_EC_BRK64	UL(0x3C)
 /* Unallocated EC: 0x3D - 0x3F */
-#define ESR_ELx_EC_MAX		(0x3F)
+#define ESR_ELx_EC_MAX		UL(0x3F)
 
 #define ESR_ELx_EC_SHIFT	(26)
 #define ESR_ELx_EC_WIDTH	(6)
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/gunyah.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/gunyah.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#ifndef _ASM_GUNYAH_H
+#define _ASM_GUNYAH_H
+
+#include <linux/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+static inline int arch_gh_fill_irq_fwspec_params(u32 virq, struct irq_fwspec *fwspec)
+{
+	/* Assume that Gunyah gave us an SPI; defensively check it */
+	if (WARN_ON(virq < 32 || virq > 1019))
+		return -EINVAL;
+
+	fwspec->param_count = 3;
+	fwspec->param[0] = GIC_SPI;
+	fwspec->param[1] = virq - 32;
+	fwspec->param[2] = IRQ_TYPE_EDGE_RISING;
+	return 0;
+}
+
+#endif
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/insn.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/insn.h
@@ -347,6 +347,7 @@
 __AARCH64_INSN_FUNCS(exclusive,	0x3F800000, 0x08000000)
 __AARCH64_INSN_FUNCS(load_ex,	0x3F400000, 0x08400000)
 __AARCH64_INSN_FUNCS(store_ex,	0x3F400000, 0x08000000)
+__AARCH64_INSN_FUNCS(mops,	0x3B200C00, 0x19000400)
 __AARCH64_INSN_FUNCS(stp,	0x7FC00000, 0x29000000)
 __AARCH64_INSN_FUNCS(ldp,	0x7FC00000, 0x29400000)
 __AARCH64_INSN_FUNCS(stp_post,	0x7FC00000, 0x28800000)
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/irqflags.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/irqflags.h
@@ -5,7 +5,6 @@
 #ifndef __ASM_IRQFLAGS_H
 #define __ASM_IRQFLAGS_H
 
-#include <asm/alternative.h>
 #include <asm/barrier.h>
 #include <asm/ptrace.h>
 #include <asm/sysreg.h>
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/jump_label.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/jump_label.h
@@ -13,6 +13,7 @@
 #include <linux/types.h>
 #include <asm/insn.h>
 
+#define HAVE_JUMP_LABEL_BATCH
 #define JUMP_LABEL_NOP_SIZE		AARCH64_INSN_SIZE
 
 static __always_inline bool arch_static_branch(struct static_key * const key,
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/kvm_host.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/kvm_host.h
@@ -73,8 +73,6 @@
 static inline enum kvm_mode kvm_get_mode(void) { return KVM_MODE_NONE; };
 #endif
 
-DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
-
 extern unsigned int __ro_after_init kvm_sve_max_vl;
 int __init kvm_arm_init_sve(void);
 
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/mman.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/mman.h
@@ -3,6 +3,8 @@
 #define __ASM_MMAN_H__
 
 #include <linux/compiler.h>
+#include <linux/fs.h>
+#include <linux/shmem_fs.h>
 #include <linux/types.h>
 #include <uapi/asm/mman.h>
 
@@ -21,19 +23,21 @@
 }
 #define arch_calc_vm_prot_bits(prot, pkey) arch_calc_vm_prot_bits(prot, pkey)
 
-static inline unsigned long arch_calc_vm_flag_bits(unsigned long flags)
+static inline unsigned long arch_calc_vm_flag_bits(struct file *file,
+						   unsigned long flags)
 {
 	/*
 	 * Only allow MTE on anonymous mappings as these are guaranteed to be
 	 * backed by tags-capable memory. The vm_flags may be overridden by a
 	 * filesystem supporting MTE (RAM-based).
 	 */
-	if (system_supports_mte() && (flags & MAP_ANONYMOUS))
+	if (system_supports_mte() &&
+	    ((flags & MAP_ANONYMOUS) || shmem_file(file)))
 		return VM_MTE_ALLOWED;
 
 	return 0;
 }
-#define arch_calc_vm_flag_bits(flags) arch_calc_vm_flag_bits(flags)
+#define arch_calc_vm_flag_bits(file, flags) arch_calc_vm_flag_bits(file, flags)
 
 static inline bool arch_validate_prot(unsigned long prot,
 	unsigned long addr __always_unused)
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/pgtable.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/pgtable.h
@@ -275,6 +275,11 @@
 	}
 }
 
+static inline void set_pte_nosync(pte_t *ptep, pte_t pte)
+{
+	WRITE_ONCE(*ptep, pte);
+}
+
 extern void __sync_icache_dcache(pte_t pteval);
 bool pgattr_change_is_safe(u64 old, u64 new);
 
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/sysreg.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/sysreg.h
@@ -1036,18 +1036,18 @@
  * Permission Indirection Extension (PIE) permission encodings.
  * Encodings with the _O suffix, have overlays applied (Permission Overlay Extension).
  */
-#define PIE_NONE_O	0x0
-#define PIE_R_O		0x1
-#define PIE_X_O		0x2
-#define PIE_RX_O	0x3
-#define PIE_RW_O	0x5
-#define PIE_RWnX_O	0x6
-#define PIE_RWX_O	0x7
-#define PIE_R		0x8
-#define PIE_GCS		0x9
-#define PIE_RX		0xa
-#define PIE_RW		0xc
-#define PIE_RWX		0xe
+#define PIE_NONE_O	UL(0x0)
+#define PIE_R_O		UL(0x1)
+#define PIE_X_O		UL(0x2)
+#define PIE_RX_O	UL(0x3)
+#define PIE_RW_O	UL(0x5)
+#define PIE_RWnX_O	UL(0x6)
+#define PIE_RWX_O	UL(0x7)
+#define PIE_R		UL(0x8)
+#define PIE_GCS		UL(0x9)
+#define PIE_RX		UL(0xa)
+#define PIE_RW		UL(0xc)
+#define PIE_RWX		UL(0xe)
 
 #define PIRx_ELx_PERM(idx, perm)	((perm) << ((idx) * 4))
 
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/tlbflush.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/tlbflush.h
@@ -161,12 +161,18 @@
 #define MAX_TLBI_RANGE_PAGES		__TLBI_RANGE_PAGES(31, 3)
 
 /*
- * Generate 'num' values from -1 to 30 with -1 rejected by the
- * __flush_tlb_range() loop below.
- */
-#define TLBI_RANGE_MASK			GENMASK_ULL(4, 0)
-#define __TLBI_RANGE_NUM(pages, scale)	\
-	((((pages) >> (5 * (scale) + 1)) & TLBI_RANGE_MASK) - 1)
+ * Generate 'num' values from -1 to 31 with -1 rejected by the
+ * __flush_tlb_range() loop below. Its return value is only
+ * significant for a maximum of MAX_TLBI_RANGE_PAGES pages. If
+ * 'pages' is more than that, you must iterate over the overall
+ * range.
+ */
+#define __TLBI_RANGE_NUM(pages, scale)					\
+	({								\
+		int __pages = min((pages),				\
+				  __TLBI_RANGE_PAGES(31, (scale)));	\
+		(__pages >> (5 * (scale) + 1)) - 1;			\
+	})
 
 /*
  *	TLB Invalidation
@@ -379,10 +385,6 @@
  * 3. If there is 1 page remaining, flush it through non-range operations. Range
  *    operations can only span an even number of pages. We save this for last to
  *    ensure 64KB start alignment is maintained for the LPA2 case.
- *
- * Note that certain ranges can be represented by either num = 31 and
- * scale or num = 0 and scale + 1. The loop below favours the latter
- * since num is limited to 30 by the __TLBI_RANGE_NUM() macro.
  */
 #define __flush_tlb_range_op(op, start, pages, stride,			\
 				asid, tlb_level, tlbi_user, lpa2)	\
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/unistd32.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/unistd32.h
@@ -840,7 +840,7 @@
 #define __NR_ppoll_time64 414
 __SYSCALL(__NR_ppoll_time64, compat_sys_ppoll_time64)
 #define __NR_io_pgetevents_time64 416
-__SYSCALL(__NR_io_pgetevents_time64, sys_io_pgetevents)
+__SYSCALL(__NR_io_pgetevents_time64, compat_sys_io_pgetevents_time64)
 #define __NR_recvmmsg_time64 417
 __SYSCALL(__NR_recvmmsg_time64, compat_sys_recvmmsg_time64)
 #define __NR_mq_timedsend_time64 418
--- linux-qcom-6.8.0.orig/arch/arm64/include/asm/uprobes.h
+++ linux-qcom-6.8.0/arch/arm64/include/asm/uprobes.h
@@ -10,11 +10,9 @@
 #include <asm/insn.h>
 #include <asm/probes.h>
 
-#define MAX_UINSN_BYTES		AARCH64_INSN_SIZE
-
 #define UPROBE_SWBP_INSN	cpu_to_le32(BRK64_OPCODE_UPROBES)
 #define UPROBE_SWBP_INSN_SIZE	AARCH64_INSN_SIZE
-#define UPROBE_XOL_SLOT_BYTES	MAX_UINSN_BYTES
+#define UPROBE_XOL_SLOT_BYTES	AARCH64_INSN_SIZE
 
 typedef __le32 uprobe_opcode_t;
 
@@ -23,8 +21,8 @@
 
 struct arch_uprobe {
 	union {
-		u8 insn[MAX_UINSN_BYTES];
-		u8 ixol[MAX_UINSN_BYTES];
+		__le32 insn;
+		__le32 ixol;
 	};
 	struct arch_probe_insn api;
 	bool simulate;
--- linux-qcom-6.8.0.orig/arch/arm64/include/uapi/asm/sigcontext.h
+++ linux-qcom-6.8.0/arch/arm64/include/uapi/asm/sigcontext.h
@@ -312,10 +312,10 @@
 	((sizeof(struct za_context) + (__SVE_VQ_BYTES - 1))	\
 		/ __SVE_VQ_BYTES * __SVE_VQ_BYTES)
 
-#define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES))
+#define ZA_SIG_REGS_SIZE(vq) (((vq) * __SVE_VQ_BYTES) * ((vq) * __SVE_VQ_BYTES))
 
 #define ZA_SIG_ZAV_OFFSET(vq, n) (ZA_SIG_REGS_OFFSET + \
-				  (SVE_SIG_ZREG_SIZE(vq) * n))
+				  (SVE_SIG_ZREG_SIZE(vq) * (n)))
 
 #define ZA_SIG_CONTEXT_SIZE(vq) \
 		(ZA_SIG_REGS_OFFSET + ZA_SIG_REGS_SIZE(vq))
@@ -326,7 +326,7 @@
 
 #define ZT_SIG_REGS_OFFSET sizeof(struct zt_context)
 
-#define ZT_SIG_REGS_SIZE(n) (ZT_SIG_REG_BYTES * n)
+#define ZT_SIG_REGS_SIZE(n) (ZT_SIG_REG_BYTES * (n))
 
 #define ZT_SIG_CONTEXT_SIZE(n) \
 	(sizeof(struct zt_context) + ZT_SIG_REGS_SIZE(n))
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/acpi_numa.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/acpi_numa.c
@@ -27,24 +27,13 @@
 
 #include <asm/numa.h>
 
-static int acpi_early_node_map[NR_CPUS] __initdata = { NUMA_NO_NODE };
+static int acpi_early_node_map[NR_CPUS] __initdata = { [0 ... NR_CPUS - 1] = NUMA_NO_NODE };
 
 int __init acpi_numa_get_nid(unsigned int cpu)
 {
 	return acpi_early_node_map[cpu];
 }
 
-static inline int get_cpu_for_acpi_id(u32 uid)
-{
-	int cpu;
-
-	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
-		if (uid == get_acpi_id_for_cpu(cpu))
-			return cpu;
-
-	return -EINVAL;
-}
-
 static int __init acpi_parse_gicc_pxm(union acpi_subtable_headers *header,
 				      const unsigned long end)
 {
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/armv8_deprecated.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/armv8_deprecated.c
@@ -462,6 +462,9 @@
 	for (int i = 0; i < ARRAY_SIZE(insn_emulations); i++) {
 		struct insn_emulation *insn = insn_emulations[i];
 		bool enable = READ_ONCE(insn->current_mode) == INSN_HW;
+		if (insn->status == INSN_UNAVAILABLE)
+			continue;
+
 		if (insn->set_hw_mode && insn->set_hw_mode(enable)) {
 			pr_warn("CPU[%u] cannot support the emulation of %s",
 				cpu, insn->name);
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/cpu_errata.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/cpu_errata.c
@@ -432,6 +432,41 @@
 };
 #endif
 
+#ifdef CONFIG_ARM64_ERRATUM_3194386
+static const struct midr_range erratum_spec_ssbs_list[] = {
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A76),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A77),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A78),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A78C),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A710),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A715),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A720),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A725),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_X1),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_X1C),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_X2),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_X3),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_X4),
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_X925),
+	MIDR_ALL_VERSIONS(MIDR_MICROSOFT_AZURE_COBALT_100),
+	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1),
+	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2),
+	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N3),
+	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V1),
+	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2),
+	MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V3),
+	{}
+};
+#endif
+
+#ifdef CONFIG_AMPERE_ERRATUM_AC03_CPU_38
+static const struct midr_range erratum_ac03_cpu_38_list[] = {
+	MIDR_ALL_VERSIONS(MIDR_AMPERE1),
+	MIDR_ALL_VERSIONS(MIDR_AMPERE1A),
+	{},
+};
+#endif
+
 const struct arm64_cpu_capabilities arm64_errata[] = {
 #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
 	{
@@ -729,6 +764,13 @@
 		MIDR_FIXED(MIDR_CPU_VAR_REV(1,1), BIT(25)),
 	},
 #endif
+#ifdef CONFIG_ARM64_ERRATUM_3194386
+	{
+		.desc = "SSBS not fully self-synchronizing",
+		.capability = ARM64_WORKAROUND_SPECULATIVE_SSBS,
+		ERRATA_MIDR_RANGE_LIST(erratum_spec_ssbs_list),
+	},
+#endif
 #ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
 	{
 		.desc = "ARM errata 2966298, 3117295",
@@ -741,7 +783,7 @@
 	{
 		.desc = "AmpereOne erratum AC03_CPU_38",
 		.capability = ARM64_WORKAROUND_AMPERE_AC03_CPU_38,
-		ERRATA_MIDR_ALL_VERSIONS(MIDR_AMPERE1),
+		ERRATA_MIDR_RANGE_LIST(erratum_ac03_cpu_38_list),
 	},
 #endif
 	{
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/cpufeature.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/cpufeature.c
@@ -1068,12 +1068,6 @@
 	    id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
 		unsigned long cpacr = cpacr_save_enable_kernel_sme();
 
-		/*
-		 * We mask out SMPS since even if the hardware
-		 * supports priorities the kernel does not at present
-		 * and we block access to them.
-		 */
-		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
 		vec_init_vq_map(ARM64_VEC_SME);
 
 		cpacr_restore(cpacr);
@@ -1314,13 +1308,6 @@
 	    id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1))) {
 		unsigned long cpacr = cpacr_save_enable_kernel_sme();
 
-		/*
-		 * We mask out SMPS since even if the hardware
-		 * supports priorities the kernel does not at present
-		 * and we block access to them.
-		 */
-		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
-
 		/* Probe vector lengths */
 		if (!system_capabilities_finalized())
 			vec_update_vq_map(ARM64_VEC_SME);
@@ -2218,6 +2205,14 @@
 		if (regp)
 			regp->user_mask &= ~ID_AA64ISAR1_EL1_BF16_MASK;
 	}
+
+	if (cpus_have_cap(ARM64_WORKAROUND_SPECULATIVE_SSBS)) {
+		struct arm64_ftr_reg *regp;
+
+		regp = get_arm64_ftr_reg(SYS_ID_AA64PFR1_EL1);
+		if (regp)
+			regp->user_mask &= ~ID_AA64PFR1_EL1_SSBS_MASK;
+	}
 }
 
 static void elf_hwcap_fixup(void)
@@ -2771,6 +2766,13 @@
 		.matches = match,						\
 	}
 
+#define HWCAP_CAP_MATCH_ID(match, reg, field, min_value, cap_type, cap)		\
+	{									\
+		__HWCAP_CAP(#cap, cap_type, cap)				\
+		HWCAP_CPUID_MATCH(reg, field, min_value) 			\
+		.matches = match,						\
+	}
+
 #ifdef CONFIG_ARM64_PTR_AUTH
 static const struct arm64_cpu_capabilities ptr_auth_hwcap_addr_matches[] = {
 	{
@@ -2799,6 +2801,13 @@
 };
 #endif
 
+#ifdef CONFIG_ARM64_SVE
+static bool has_sve_feature(const struct arm64_cpu_capabilities *cap, int scope)
+{
+	return system_supports_sve() && has_user_cpuid_feature(cap, scope);
+}
+#endif
+
 static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
 	HWCAP_CAP(ID_AA64ISAR0_EL1, AES, PMULL, CAP_HWCAP, KERNEL_HWCAP_PMULL),
 	HWCAP_CAP(ID_AA64ISAR0_EL1, AES, AES, CAP_HWCAP, KERNEL_HWCAP_AES),
@@ -2838,19 +2847,19 @@
 	HWCAP_CAP(ID_AA64MMFR2_EL1, AT, IMP, CAP_HWCAP, KERNEL_HWCAP_USCAT),
 #ifdef CONFIG_ARM64_SVE
 	HWCAP_CAP(ID_AA64PFR0_EL1, SVE, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE),
-	HWCAP_CAP(ID_AA64ZFR0_EL1, SVEver, SVE2p1, CAP_HWCAP, KERNEL_HWCAP_SVE2P1),
-	HWCAP_CAP(ID_AA64ZFR0_EL1, SVEver, SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
-	HWCAP_CAP(ID_AA64ZFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
-	HWCAP_CAP(ID_AA64ZFR0_EL1, AES, PMULL128, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
-	HWCAP_CAP(ID_AA64ZFR0_EL1, BitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
-	HWCAP_CAP(ID_AA64ZFR0_EL1, B16B16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE_B16B16),
-	HWCAP_CAP(ID_AA64ZFR0_EL1, BF16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
-	HWCAP_CAP(ID_AA64ZFR0_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_SVE_EBF16),
-	HWCAP_CAP(ID_AA64ZFR0_EL1, SHA3, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
-	HWCAP_CAP(ID_AA64ZFR0_EL1, SM4, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESM4),
-	HWCAP_CAP(ID_AA64ZFR0_EL1, I8MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM),
-	HWCAP_CAP(ID_AA64ZFR0_EL1, F32MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM),
-	HWCAP_CAP(ID_AA64ZFR0_EL1, F64MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM),
+	HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SVEver, SVE2p1, CAP_HWCAP, KERNEL_HWCAP_SVE2P1),
+	HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SVEver, SVE2, CAP_HWCAP, KERNEL_HWCAP_SVE2),
+	HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, AES, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEAES),
+	HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, AES, PMULL128, CAP_HWCAP, KERNEL_HWCAP_SVEPMULL),
+	HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, BitPerm, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBITPERM),
+	HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, B16B16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVE_B16B16),
+	HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, BF16, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEBF16),
+	HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_SVE_EBF16),
+	HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SHA3, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESHA3),
+	HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, SM4, IMP, CAP_HWCAP, KERNEL_HWCAP_SVESM4),
+	HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, I8MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEI8MM),
+	HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, F32MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF32MM),
+	HWCAP_CAP_MATCH_ID(has_sve_feature, ID_AA64ZFR0_EL1, F64MM, IMP, CAP_HWCAP, KERNEL_HWCAP_SVEF64MM),
 #endif
 	HWCAP_CAP(ID_AA64PFR1_EL1, SSBS, SSBS2, CAP_HWCAP, KERNEL_HWCAP_SSBS),
 #ifdef CONFIG_ARM64_BTI
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/cpuinfo.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/cpuinfo.c
@@ -458,6 +458,16 @@
 	if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
 		__cpuinfo_store_cpu_32bit(&info->aarch32);
 
+	if (IS_ENABLED(CONFIG_ARM64_SME) &&
+	    id_aa64pfr1_sme(info->reg_id_aa64pfr1)) {
+		/*
+		 * We mask out SMPS since even if the hardware
+		 * supports priorities the kernel does not at present
+		 * and we block access to them.
+		 */
+		info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
+	}
+
 	cpuinfo_detect_icache_policy(info);
 }
 
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/fpsimd.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/fpsimd.c
@@ -1350,6 +1350,7 @@
 	} else {
 		fpsimd_to_sve(current);
 		current->thread.fp_type = FP_STATE_SVE;
+		fpsimd_flush_task_state(current);
 	}
 }
 
@@ -1518,6 +1519,27 @@
 	task->thread.kernel_fpsimd_cpu = smp_processor_id();
 }
 
+/*
+ * Invalidate any task's FPSIMD state that is present on this cpu.
+ * The FPSIMD context should be acquired with get_cpu_fpsimd_context()
+ * before calling this function.
+ */
+static void fpsimd_flush_cpu_state(void)
+{
+	WARN_ON(!system_supports_fpsimd());
+	__this_cpu_write(fpsimd_last_state.st, NULL);
+
+	/*
+	 * Leaving streaming mode enabled will cause issues for any kernel
+	 * NEON and leaving streaming mode or ZA enabled may increase power
+	 * consumption.
+	 */
+	if (system_supports_sme())
+		sme_smstop();
+
+	set_thread_flag(TIF_FOREIGN_FPSTATE);
+}
+
 void fpsimd_thread_switch(struct task_struct *next)
 {
 	bool wrong_task, wrong_cpu;
@@ -1535,7 +1557,7 @@
 
 	if (test_tsk_thread_flag(next, TIF_KERNEL_FPSTATE)) {
 		fpsimd_load_kernel_state(next);
-		set_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE);
+		fpsimd_flush_cpu_state();
 	} else {
 		/*
 		 * Fix up TIF_FOREIGN_FPSTATE to correctly describe next's
@@ -1825,27 +1847,6 @@
 }
 
 /*
- * Invalidate any task's FPSIMD state that is present on this cpu.
- * The FPSIMD context should be acquired with get_cpu_fpsimd_context()
- * before calling this function.
- */
-static void fpsimd_flush_cpu_state(void)
-{
-	WARN_ON(!system_supports_fpsimd());
-	__this_cpu_write(fpsimd_last_state.st, NULL);
-
-	/*
-	 * Leaving streaming mode enabled will cause issues for any kernel
-	 * NEON and leaving streaming mode or ZA enabled may increase power
-	 * consumption.
-	 */
-	if (system_supports_sme())
-		sme_smstop();
-
-	set_thread_flag(TIF_FOREIGN_FPSTATE);
-}
-
-/*
  * Save the FPSIMD state to memory and invalidate cpu view.
  * This function must be called with preemption disabled.
  */
@@ -1923,7 +1924,7 @@
 
 	put_cpu_fpsimd_context();
 }
-EXPORT_SYMBOL_GPL(kernel_neon_begin);
+EXPORT_SYMBOL(kernel_neon_begin);
 
 /*
  * kernel_neon_end(): give the CPU FPSIMD registers back to the current task
@@ -1950,7 +1951,7 @@
 	else
 		clear_thread_flag(TIF_KERNEL_FPSTATE);
 }
-EXPORT_SYMBOL_GPL(kernel_neon_end);
+EXPORT_SYMBOL(kernel_neon_end);
 
 #ifdef CONFIG_EFI
 
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/head.S
+++ linux-qcom-6.8.0/arch/arm64/kernel/head.S
@@ -569,6 +569,11 @@
 	adr_l	x1, __hyp_text_end
 	adr_l	x2, dcache_clean_poc
 	blr	x2
+
+	mov_q	x0, INIT_SCTLR_EL2_MMU_OFF
+	pre_disable_mmu_workaround
+	msr	sctlr_el2, x0
+	isb
 0:
 	mov_q	x0, HCR_HOST_NVHE_FLAGS
 	msr	hcr_el2, x0
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/idreg-override.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/idreg-override.c
@@ -308,7 +308,8 @@
 		match_options(buf);
 
 		for (i = 0; parse_aliases && i < ARRAY_SIZE(aliases); i++)
-			if (!memcmp(buf, aliases[i].alias, len + 1))
+			if (len == strlen(aliases[i].alias) &&
+			    !memcmp(buf, aliases[i].alias, len + 1))
 				__parse_cmdline(aliases[i].feature, false);
 	} while (1);
 }
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/jump_label.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/jump_label.c
@@ -7,11 +7,12 @@
  */
 #include <linux/kernel.h>
 #include <linux/jump_label.h>
+#include <linux/smp.h>
 #include <asm/insn.h>
 #include <asm/patching.h>
 
-void arch_jump_label_transform(struct jump_entry *entry,
-			       enum jump_label_type type)
+bool arch_jump_label_transform_queue(struct jump_entry *entry,
+				     enum jump_label_type type)
 {
 	void *addr = (void *)jump_entry_code(entry);
 	u32 insn;
@@ -25,4 +26,10 @@
 	}
 
 	aarch64_insn_patch_text_nosync(addr, insn);
+	return true;
+}
+
+void arch_jump_label_transform_apply(void)
+{
+	kick_all_cpus_sync();
 }
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/probes/decode-insn.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/probes/decode-insn.c
@@ -58,10 +58,13 @@
 	 * Instructions which load PC relative literals are not going to work
 	 * when executed from an XOL slot. Instructions doing an exclusive
 	 * load/store are not going to complete successfully when single-step
-	 * exception handling happens in the middle of the sequence.
+	 * exception handling happens in the middle of the sequence. Memory
+	 * copy/set instructions require that all three instructions be placed
+	 * consecutively in memory.
 	 */
 	if (aarch64_insn_uses_literal(insn) ||
-	    aarch64_insn_is_exclusive(insn))
+	    aarch64_insn_is_exclusive(insn) ||
+	    aarch64_insn_is_mops(insn))
 		return false;
 
 	return true;
@@ -99,10 +102,6 @@
 	    aarch64_insn_is_blr(insn) ||
 	    aarch64_insn_is_ret(insn)) {
 		api->handler = simulate_br_blr_ret;
-	} else if (aarch64_insn_is_ldr_lit(insn)) {
-		api->handler = simulate_ldr_literal;
-	} else if (aarch64_insn_is_ldrsw_lit(insn)) {
-		api->handler = simulate_ldrsw_literal;
 	} else {
 		/*
 		 * Instruction cannot be stepped out-of-line and we don't
@@ -140,6 +139,17 @@
 	probe_opcode_t insn = le32_to_cpu(*addr);
 	probe_opcode_t *scan_end = NULL;
 	unsigned long size = 0, offset = 0;
+	struct arch_probe_insn *api = &asi->api;
+
+	if (aarch64_insn_is_ldr_lit(insn)) {
+		api->handler = simulate_ldr_literal;
+		decoded = INSN_GOOD_NO_SLOT;
+	} else if (aarch64_insn_is_ldrsw_lit(insn)) {
+		api->handler = simulate_ldrsw_literal;
+		decoded = INSN_GOOD_NO_SLOT;
+	} else {
+		decoded = arm_probe_decode_insn(insn, &asi->api);
+	}
 
 	/*
 	 * If there's a symbol defined in front of and near enough to
@@ -157,7 +167,6 @@
 		else
 			scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE;
 	}
-	decoded = arm_probe_decode_insn(insn, &asi->api);
 
 	if (decoded != INSN_REJECTED && scan_end)
 		if (is_probed_address_atomic(addr - 1, scan_end))
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/probes/simulate-insn.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/probes/simulate-insn.c
@@ -171,17 +171,15 @@
 void __kprobes
 simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs)
 {
-	u64 *load_addr;
+	unsigned long load_addr;
 	int xn = opcode & 0x1f;
-	int disp;
 
-	disp = ldr_displacement(opcode);
-	load_addr = (u64 *) (addr + disp);
+	load_addr = addr + ldr_displacement(opcode);
 
 	if (opcode & (1 << 30))	/* x0-x30 */
-		set_x_reg(regs, xn, *load_addr);
+		set_x_reg(regs, xn, READ_ONCE(*(u64 *)load_addr));
 	else			/* w0-w30 */
-		set_w_reg(regs, xn, *load_addr);
+		set_w_reg(regs, xn, READ_ONCE(*(u32 *)load_addr));
 
 	instruction_pointer_set(regs, instruction_pointer(regs) + 4);
 }
@@ -189,14 +187,12 @@
 void __kprobes
 simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs)
 {
-	s32 *load_addr;
+	unsigned long load_addr;
 	int xn = opcode & 0x1f;
-	int disp;
 
-	disp = ldr_displacement(opcode);
-	load_addr = (s32 *) (addr + disp);
+	load_addr = addr + ldr_displacement(opcode);
 
-	set_x_reg(regs, xn, *load_addr);
+	set_x_reg(regs, xn, READ_ONCE(*(s32 *)load_addr));
 
 	instruction_pointer_set(regs, instruction_pointer(regs) + 4);
 }
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/probes/uprobes.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/probes/uprobes.c
@@ -42,7 +42,7 @@
 	else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE))
 		return -EINVAL;
 
-	insn = *(probe_opcode_t *)(&auprobe->insn[0]);
+	insn = le32_to_cpu(auprobe->insn);
 
 	switch (arm_probe_decode_insn(insn, &auprobe->api)) {
 	case INSN_REJECTED:
@@ -108,7 +108,7 @@
 	if (!auprobe->simulate)
 		return false;
 
-	insn = *(probe_opcode_t *)(&auprobe->insn[0]);
+	insn = le32_to_cpu(auprobe->insn);
 	addr = instruction_pointer(regs);
 
 	if (auprobe->api.handler)
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/process.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/process.c
@@ -429,7 +429,7 @@
 
 	if (is_compat_thread(task_thread_info(next)))
 		write_sysreg(next->thread.uw.tp_value, tpidrro_el0);
-	else if (!arm64_kernel_unmapped_at_el0())
+	else
 		write_sysreg(0, tpidrro_el0);
 
 	write_sysreg(*task_user_tls(next), tpidr_el0);
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/proton-pack.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/proton-pack.c
@@ -558,6 +558,18 @@
 
 	/* SCTLR_EL1.DSSBS was initialised to 0 during boot */
 	set_pstate_ssbs(0);
+
+	/*
+	 * SSBS is self-synchronizing and is intended to affect subsequent
+	 * speculative instructions, but some CPUs can speculate with a stale
+	 * value of SSBS.
+	 *
+	 * Mitigate this with an unconditional speculation barrier, as CPUs
+	 * could mis-speculate branches and bypass a conditional barrier.
+	 */
+	if (IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386))
+		spec_bar();
+
 	return SPECTRE_MITIGATED;
 }
 
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/ptrace.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/ptrace.c
@@ -729,7 +729,6 @@
 {
 	unsigned int vq;
 	bool active;
-	bool fpsimd_only;
 	enum vec_type task_type;
 
 	memset(header, 0, sizeof(*header));
@@ -745,12 +744,10 @@
 	case ARM64_VEC_SVE:
 		if (test_tsk_thread_flag(target, TIF_SVE_VL_INHERIT))
 			header->flags |= SVE_PT_VL_INHERIT;
-		fpsimd_only = !test_tsk_thread_flag(target, TIF_SVE);
 		break;
 	case ARM64_VEC_SME:
 		if (test_tsk_thread_flag(target, TIF_SME_VL_INHERIT))
 			header->flags |= SVE_PT_VL_INHERIT;
-		fpsimd_only = false;
 		break;
 	default:
 		WARN_ON_ONCE(1);
@@ -758,7 +755,7 @@
 	}
 
 	if (active) {
-		if (fpsimd_only) {
+		if (target->thread.fp_type == FP_STATE_FPSIMD) {
 			header->flags |= SVE_PT_REGS_FPSIMD;
 		} else {
 			header->flags |= SVE_PT_REGS_SVE;
@@ -1389,7 +1386,7 @@
 {
 	long ctrl = get_tagged_addr_ctrl(target);
 
-	if (IS_ERR_VALUE(ctrl))
+	if (WARN_ON_ONCE(IS_ERR_VALUE(ctrl)))
 		return ctrl;
 
 	return membuf_write(&to, &ctrl, sizeof(ctrl));
@@ -1403,6 +1400,10 @@
 	int ret;
 	long ctrl;
 
+	ctrl = get_tagged_addr_ctrl(target);
+	if (WARN_ON_ONCE(IS_ERR_VALUE(ctrl)))
+		return ctrl;
+
 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl, 0, -1);
 	if (ret)
 		return ret;
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/setup.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/setup.c
@@ -190,7 +190,11 @@
 	if (dt_virt)
 		memblock_reserve(dt_phys, size);
 
-	if (!dt_virt || !early_init_dt_scan(dt_virt)) {
+	/*
+	 * dt_virt is a fixmap address, hence __pa(dt_virt) can't be used.
+	 * Pass dt_phys directly.
+	 */
+	if (!early_init_dt_scan(dt_virt, dt_phys)) {
 		pr_crit("\n"
 			"Error: invalid device tree blob at physical address %pa (virtual address 0x%px)\n"
 			"The dtb must be 8-byte aligned and must not exceed 2 MB in size\n"
@@ -371,9 +375,6 @@
 	smp_init_cpus();
 	smp_build_mpidr_hash();
 
-	/* Init percpu seeds for random tags after cpus are set up. */
-	kasan_init_sw_tags();
-
 #ifdef CONFIG_ARM64_SW_TTBR0_PAN
 	/*
 	 * Make sure init_thread_info.ttbr0 always generates translation
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/smccc-call.S
+++ linux-qcom-6.8.0/arch/arm64/kernel/smccc-call.S
@@ -7,48 +7,19 @@
 
 #include <asm/asm-offsets.h>
 #include <asm/assembler.h>
-#include <asm/thread_info.h>
-
-/*
- * If we have SMCCC v1.3 and (as is likely) no SVE state in
- * the registers then set the SMCCC hint bit to say there's no
- * need to preserve it.  Do this by directly adjusting the SMCCC
- * function value which is already stored in x0 ready to be called.
- */
-SYM_FUNC_START(__arm_smccc_sve_check)
-
-	ldr_l	x16, smccc_has_sve_hint
-	cbz	x16, 2f
-
-	get_current_task x16
-	ldr	x16, [x16, #TSK_TI_FLAGS]
-	tbnz	x16, #TIF_FOREIGN_FPSTATE, 1f	// Any live FP state?
-	tbnz	x16, #TIF_SVE, 2f		// Does that state include SVE?
-
-1:	orr	x0, x0, ARM_SMCCC_1_3_SVE_HINT
-
-2:	ret
-SYM_FUNC_END(__arm_smccc_sve_check)
-EXPORT_SYMBOL(__arm_smccc_sve_check)
 
 	.macro SMCCC instr
-	stp     x29, x30, [sp, #-16]!
-	mov	x29, sp
-alternative_if ARM64_SVE
-	bl	__arm_smccc_sve_check
-alternative_else_nop_endif
 	\instr	#0
-	ldr	x4, [sp, #16]
+	ldr	x4, [sp]
 	stp	x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS]
 	stp	x2, x3, [x4, #ARM_SMCCC_RES_X2_OFFS]
-	ldr	x4, [sp, #24]
+	ldr	x4, [sp, #8]
 	cbz	x4, 1f /* no quirk structure */
 	ldr	x9, [x4, #ARM_SMCCC_QUIRK_ID_OFFS]
 	cmp	x9, #ARM_SMCCC_QUIRK_QCOM_A6
 	b.ne	1f
 	str	x6, [x4, ARM_SMCCC_QUIRK_STATE_OFFS]
-1:	ldp     x29, x30, [sp], #16
-	ret
+1:	ret
 	.endm
 
 /*
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/smp.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/smp.c
@@ -71,7 +71,7 @@
 	IPI_RESCHEDULE,
 	IPI_CALL_FUNC,
 	IPI_CPU_STOP,
-	IPI_CPU_CRASH_STOP,
+	IPI_CPU_STOP_NMI,
 	IPI_TIMER,
 	IPI_IRQ_WORK,
 	NR_IPI,
@@ -88,6 +88,8 @@
 static int nr_ipi __ro_after_init = NR_IPI;
 static struct irq_desc *ipi_desc[MAX_IPI] __ro_after_init;
 
+static bool crash_stop;
+
 static void ipi_setup(int cpu);
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -462,6 +464,8 @@
 		init_gic_priority_masking();
 
 	kasan_init_hw_tags();
+	/* Init percpu seeds for random tags after cpus are set up. */
+	kasan_init_sw_tags();
 }
 
 /*
@@ -760,13 +764,15 @@
 	}
 }
 
-static const char *ipi_types[NR_IPI] __tracepoint_string = {
+static const char *ipi_types[MAX_IPI] __tracepoint_string = {
 	[IPI_RESCHEDULE]	= "Rescheduling interrupts",
 	[IPI_CALL_FUNC]		= "Function call interrupts",
 	[IPI_CPU_STOP]		= "CPU stop interrupts",
-	[IPI_CPU_CRASH_STOP]	= "CPU stop (for crash dump) interrupts",
+	[IPI_CPU_STOP_NMI]	= "CPU stop NMIs",
 	[IPI_TIMER]		= "Timer broadcast interrupts",
 	[IPI_IRQ_WORK]		= "IRQ work interrupts",
+	[IPI_CPU_BACKTRACE]	= "CPU backtrace interrupts",
+	[IPI_KGDB_ROUNDUP]	= "KGDB roundup interrupts",
 };
 
 static void smp_cross_call(const struct cpumask *target, unsigned int ipinr);
@@ -777,7 +783,7 @@
 {
 	unsigned int cpu, i;
 
-	for (i = 0; i < NR_IPI; i++) {
+	for (i = 0; i < MAX_IPI; i++) {
 		seq_printf(p, "%*s%u:%s", prec - 1, "IPI", i,
 			   prec >= 4 ? " " : "");
 		for_each_online_cpu(cpu)
@@ -806,9 +812,9 @@
 }
 #endif
 
-static void __noreturn local_cpu_stop(void)
+static void __noreturn local_cpu_stop(unsigned int cpu)
 {
-	set_cpu_online(smp_processor_id(), false);
+	set_cpu_online(cpu, false);
 
 	local_daif_mask();
 	sdei_mask_local_cpu();
@@ -822,21 +828,26 @@
  */
 void __noreturn panic_smp_self_stop(void)
 {
-	local_cpu_stop();
+	local_cpu_stop(smp_processor_id());
 }
 
-#ifdef CONFIG_KEXEC_CORE
-static atomic_t waiting_for_crash_ipi = ATOMIC_INIT(0);
-#endif
-
 static void __noreturn ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs)
 {
 #ifdef CONFIG_KEXEC_CORE
+	/*
+	 * Use local_daif_mask() instead of local_irq_disable() to make sure
+	 * that pseudo-NMIs are disabled. The "crash stop" code starts with
+	 * an IRQ and falls back to NMI (which might be pseudo). If the IRQ
+	 * finally goes through right as we're timing out then the NMI could
+	 * interrupt us. It's better to prevent the NMI and let the IRQ
+	 * finish since the pt_regs will be better.
+	 */
+	local_daif_mask();
+
 	crash_save_cpu(regs, cpu);
 
-	atomic_dec(&waiting_for_crash_ipi);
+	set_cpu_online(cpu, false);
 
-	local_irq_disable();
 	sdei_mask_local_cpu();
 
 	if (IS_ENABLED(CONFIG_HOTPLUG_CPU))
@@ -901,14 +912,12 @@
 		break;
 
 	case IPI_CPU_STOP:
-		local_cpu_stop();
-		break;
-
-	case IPI_CPU_CRASH_STOP:
-		if (IS_ENABLED(CONFIG_KEXEC_CORE)) {
+	case IPI_CPU_STOP_NMI:
+		if (IS_ENABLED(CONFIG_KEXEC_CORE) && crash_stop) {
 			ipi_cpu_crash_stop(cpu, get_irq_regs());
-
 			unreachable();
+		} else {
+			local_cpu_stop(cpu);
 		}
 		break;
 
@@ -963,8 +972,7 @@
 		return false;
 
 	switch (ipi) {
-	case IPI_CPU_STOP:
-	case IPI_CPU_CRASH_STOP:
+	case IPI_CPU_STOP_NMI:
 	case IPI_CPU_BACKTRACE:
 	case IPI_KGDB_ROUNDUP:
 		return true;
@@ -1077,79 +1085,109 @@
 
 void smp_send_stop(void)
 {
+	static unsigned long stop_in_progress;
+	cpumask_t mask;
 	unsigned long timeout;
 
-	if (num_other_online_cpus()) {
-		cpumask_t mask;
+	/*
+	 * If this cpu is the only one alive at this point in time, online or
+	 * not, there are no stop messages to be sent around, so just back out.
+	 */
+	if (num_other_online_cpus() == 0)
+		goto skip_ipi;
 
-		cpumask_copy(&mask, cpu_online_mask);
-		cpumask_clear_cpu(smp_processor_id(), &mask);
+	/* Only proceed if this is the first CPU to reach this code */
+	if (test_and_set_bit(0, &stop_in_progress))
+		return;
 
-		if (system_state <= SYSTEM_RUNNING)
-			pr_crit("SMP: stopping secondary CPUs\n");
-		smp_cross_call(&mask, IPI_CPU_STOP);
-	}
+	/*
+	 * Send an IPI to all currently online CPUs except the CPU running
+	 * this code.
+	 *
+	 * NOTE: we don't do anything here to prevent other CPUs from coming
+	 * online after we snapshot `cpu_online_mask`. Ideally, the calling code
+	 * should do something to prevent other CPUs from coming up. This code
+	 * can be called in the panic path and thus it doesn't seem wise to
+	 * grab the CPU hotplug mutex ourselves. Worst case:
+	 * - If a CPU comes online as we're running, we'll likely notice it
+	 *   during the 1 second wait below and then we'll catch it when we try
+	 *   with an NMI (assuming NMIs are enabled) since we re-snapshot the
+	 *   mask before sending an NMI.
+	 * - If we leave the function and see that CPUs are still online we'll
+	 *   at least print a warning. Especially without NMIs this function
+	 *   isn't foolproof anyway so calling code will just have to accept
+	 *   the fact that there could be cases where a CPU can't be stopped.
+	 */
+	cpumask_copy(&mask, cpu_online_mask);
+	cpumask_clear_cpu(smp_processor_id(), &mask);
 
-	/* Wait up to one second for other CPUs to stop */
+	if (system_state <= SYSTEM_RUNNING)
+		pr_crit("SMP: stopping secondary CPUs\n");
+
+	/*
+	 * Start with a normal IPI and wait up to one second for other CPUs to
+	 * stop. We do this first because it gives other processors a chance
+	 * to exit critical sections / drop locks and makes the rest of the
+	 * stop process (especially console flush) more robust.
+	 */
+	smp_cross_call(&mask, IPI_CPU_STOP);
 	timeout = USEC_PER_SEC;
 	while (num_other_online_cpus() && timeout--)
 		udelay(1);
 
-	if (num_other_online_cpus())
+	/*
+	 * If CPUs are still online, try an NMI. There's no excuse for this to
+	 * be slow, so we only give them an extra 10 ms to respond.
+	 */
+	if (num_other_online_cpus() && ipi_should_be_nmi(IPI_CPU_STOP_NMI)) {
+		smp_rmb();
+		cpumask_copy(&mask, cpu_online_mask);
+		cpumask_clear_cpu(smp_processor_id(), &mask);
+
+		pr_info("SMP: retry stop with NMI for CPUs %*pbl\n",
+			cpumask_pr_args(&mask));
+
+		smp_cross_call(&mask, IPI_CPU_STOP_NMI);
+		timeout = USEC_PER_MSEC * 10;
+		while (num_other_online_cpus() && timeout--)
+			udelay(1);
+	}
+
+	if (num_other_online_cpus()) {
+		smp_rmb();
+		cpumask_copy(&mask, cpu_online_mask);
+		cpumask_clear_cpu(smp_processor_id(), &mask);
+
 		pr_warn("SMP: failed to stop secondary CPUs %*pbl\n",
-			cpumask_pr_args(cpu_online_mask));
+			cpumask_pr_args(&mask));
+	}
 
+skip_ipi:
 	sdei_mask_local_cpu();
 }
 
 #ifdef CONFIG_KEXEC_CORE
 void crash_smp_send_stop(void)
 {
-	static int cpus_stopped;
-	cpumask_t mask;
-	unsigned long timeout;
-
 	/*
 	 * This function can be called twice in panic path, but obviously
 	 * we execute this only once.
+	 *
+	 * We use this same boolean to tell whether the IPI we send was a
+	 * stop or a "crash stop".
 	 */
-	if (cpus_stopped)
+	if (crash_stop)
 		return;
+	crash_stop = 1;
 
-	cpus_stopped = 1;
+	smp_send_stop();
 
-	/*
-	 * If this cpu is the only one alive at this point in time, online or
-	 * not, there are no stop messages to be sent around, so just back out.
-	 */
-	if (num_other_online_cpus() == 0)
-		goto skip_ipi;
-
-	cpumask_copy(&mask, cpu_online_mask);
-	cpumask_clear_cpu(smp_processor_id(), &mask);
-
-	atomic_set(&waiting_for_crash_ipi, num_other_online_cpus());
-
-	pr_crit("SMP: stopping secondary CPUs\n");
-	smp_cross_call(&mask, IPI_CPU_CRASH_STOP);
-
-	/* Wait up to one second for other CPUs to stop */
-	timeout = USEC_PER_SEC;
-	while ((atomic_read(&waiting_for_crash_ipi) > 0) && timeout--)
-		udelay(1);
-
-	if (atomic_read(&waiting_for_crash_ipi) > 0)
-		pr_warn("SMP: failed to stop secondary CPUs %*pbl\n",
-			cpumask_pr_args(&mask));
-
-skip_ipi:
-	sdei_mask_local_cpu();
 	sdei_handler_abort();
 }
 
 bool smp_crash_stop_failed(void)
 {
-	return (atomic_read(&waiting_for_crash_ipi) > 0);
+	return num_other_online_cpus() != 0;
 }
 #endif
 
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/syscall.c
+++ linux-qcom-6.8.0/arch/arm64/kernel/syscall.c
@@ -56,17 +56,15 @@
 	syscall_set_return_value(current, regs, 0, ret);
 
 	/*
-	 * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(),
-	 * but not enough for arm64 stack utilization comfort. To keep
-	 * reasonable stack head room, reduce the maximum offset to 9 bits.
+	 * This value will get limited by KSTACK_OFFSET_MAX(), which is 10
+	 * bits. The actual entropy will be further reduced by the compiler
+	 * when applying stack alignment constraints: the AAPCS mandates a
+	 * 16-byte aligned SP at function boundaries, which will remove the
+	 * 4 low bits from any entropy chosen here.
 	 *
-	 * The actual entropy will be further reduced by the compiler when
-	 * applying stack alignment constraints: the AAPCS mandates a
-	 * 16-byte (i.e. 4-bit) aligned SP at function boundaries.
-	 *
-	 * The resulting 5 bits of entropy is seen in SP[8:4].
+	 * The resulting 6 bits of entropy is seen in SP[9:4].
 	 */
-	choose_random_kstack_offset(get_random_u16() & 0x1FF);
+	choose_random_kstack_offset(get_random_u16());
 }
 
 static inline bool has_syscall_work(unsigned long flags)
--- linux-qcom-6.8.0.orig/arch/arm64/kernel/vmlinux.lds.S
+++ linux-qcom-6.8.0/arch/arm64/kernel/vmlinux.lds.S
@@ -285,6 +285,9 @@
 	__initdata_end = .;
 	__init_end = .;
 
+	.data.rel.ro : { *(.data.rel.ro) }
+	ASSERT(SIZEOF(.data.rel.ro) == 0, "Unexpected RELRO detected!")
+
 	_data = .;
 	_sdata = .;
 	RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
@@ -336,9 +339,6 @@
 		*(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt)
 	}
 	ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
-
-	.data.rel.ro : { *(.data.rel.ro) }
-	ASSERT(SIZEOF(.data.rel.ro) == 0, "Unexpected RELRO detected!")
 }
 
 #include "image-vars.h"
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/arch_timer.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/arch_timer.c
@@ -206,8 +206,7 @@
 
 static inline bool userspace_irqchip(struct kvm *kvm)
 {
-	return static_branch_unlikely(&userspace_irqchip_in_use) &&
-		unlikely(!irqchip_in_kernel(kvm));
+	return unlikely(!irqchip_in_kernel(kvm));
 }
 
 static void soft_timer_start(struct hrtimer *hrt, u64 ns)
@@ -467,10 +466,8 @@
 
 	trace_kvm_timer_emulate(ctx, should_fire);
 
-	if (should_fire != ctx->irq.level) {
+	if (should_fire != ctx->irq.level)
 		kvm_timer_update_irq(ctx->vcpu, should_fire, ctx);
-		return;
-	}
 
 	/*
 	 * If the timer can fire now, we don't need to have a soft timer
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/arm.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/arm.c
@@ -57,7 +57,6 @@
 static bool vgic_present, kvm_arm_initialised;
 
 static DEFINE_PER_CPU(unsigned char, kvm_hyp_initialized);
-DEFINE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
 
 bool is_kvm_arm_initialised(void)
 {
@@ -191,6 +190,23 @@
 }
 
 
+static void kvm_destroy_mpidr_data(struct kvm *kvm)
+{
+	struct kvm_mpidr_data *data;
+
+	mutex_lock(&kvm->arch.config_lock);
+
+	data = rcu_dereference_protected(kvm->arch.mpidr_data,
+					 lockdep_is_held(&kvm->arch.config_lock));
+	if (data) {
+		rcu_assign_pointer(kvm->arch.mpidr_data, NULL);
+		synchronize_rcu();
+		kfree(data);
+	}
+
+	mutex_unlock(&kvm->arch.config_lock);
+}
+
 /**
  * kvm_arch_destroy_vm - destroy the VM data structure
  * @kvm:	pointer to the KVM struct
@@ -205,7 +221,8 @@
 	if (is_protected_kvm_enabled())
 		pkvm_destroy_hyp_vm(kvm);
 
-	kfree(kvm->arch.mpidr_data);
+	kvm_destroy_mpidr_data(kvm);
+
 	kvm_destroy_vcpus(kvm);
 
 	kvm_unshare_hyp(kvm, kvm + 1);
@@ -390,6 +407,13 @@
 
 	vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu;
 
+	/*
+	 * This vCPU may have been created after mpidr_data was initialized.
+	 * Throw out the pre-computed mappings if that is the case which forces
+	 * KVM to fall back to iteratively searching the vCPUs.
+	 */
+	kvm_destroy_mpidr_data(vcpu->kvm);
+
 	err = kvm_vgic_vcpu_init(vcpu);
 	if (err)
 		return err;
@@ -403,9 +427,6 @@
 
 void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
 {
-	if (vcpu_has_run_once(vcpu) && unlikely(!irqchip_in_kernel(vcpu->kvm)))
-		static_branch_dec(&userspace_irqchip_in_use);
-
 	kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
 	kvm_timer_vcpu_terminate(vcpu);
 	kvm_pmu_vcpu_destroy(vcpu);
@@ -589,7 +610,8 @@
 
 	mutex_lock(&kvm->arch.config_lock);
 
-	if (kvm->arch.mpidr_data || atomic_read(&kvm->online_vcpus) == 1)
+	if (rcu_access_pointer(kvm->arch.mpidr_data) ||
+	    atomic_read(&kvm->online_vcpus) == 1)
 		goto out;
 
 	kvm_for_each_vcpu(c, vcpu, kvm) {
@@ -626,7 +648,7 @@
 		data->cmpidr_to_idx[index] = c;
 	}
 
-	kvm->arch.mpidr_data = data;
+	rcu_assign_pointer(kvm->arch.mpidr_data, data);
 out:
 	mutex_unlock(&kvm->arch.config_lock);
 }
@@ -688,14 +710,6 @@
 			return ret;
 	}
 
-	if (!irqchip_in_kernel(kvm)) {
-		/*
-		 * Tell the rest of the code that there are userspace irqchip
-		 * VMs in the wild.
-		 */
-		static_branch_inc(&userspace_irqchip_in_use);
-	}
-
 	/*
 	 * Initialize traps for protected VMs.
 	 * NOTE: Move to run in EL2 directly, rather than via a hypercall, once
@@ -838,6 +852,9 @@
 static int check_vcpu_requests(struct kvm_vcpu *vcpu)
 {
 	if (kvm_request_pending(vcpu)) {
+		if (kvm_check_request(KVM_REQ_VM_DEAD, vcpu))
+			return -EIO;
+
 		if (kvm_check_request(KVM_REQ_SLEEP, vcpu))
 			kvm_vcpu_sleep(vcpu);
 
@@ -913,7 +930,7 @@
 	 * state gets updated in kvm_timer_update_run and
 	 * kvm_pmu_update_run below).
 	 */
-	if (static_branch_unlikely(&userspace_irqchip_in_use)) {
+	if (unlikely(!irqchip_in_kernel(vcpu->kvm))) {
 		if (kvm_timer_should_notify_user(vcpu) ||
 		    kvm_pmu_should_notify_user(vcpu)) {
 			*ret = -EINTR;
@@ -969,7 +986,7 @@
 
 	if (run->exit_reason == KVM_EXIT_MMIO) {
 		ret = kvm_handle_mmio_return(vcpu);
-		if (ret)
+		if (ret <= 0)
 			return ret;
 	}
 
@@ -1035,7 +1052,7 @@
 			vcpu->mode = OUTSIDE_GUEST_MODE;
 			isb(); /* Ensure work in x_flush_hwstate is committed */
 			kvm_pmu_sync_hwstate(vcpu);
-			if (static_branch_unlikely(&userspace_irqchip_in_use))
+			if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
 				kvm_timer_sync_user(vcpu);
 			kvm_vgic_sync_hwstate(vcpu);
 			local_irq_enable();
@@ -1081,7 +1098,7 @@
 		 * we don't want vtimer interrupts to race with syncing the
 		 * timer virtual interrupt state.
 		 */
-		if (static_branch_unlikely(&userspace_irqchip_in_use))
+		if (unlikely(!irqchip_in_kernel(vcpu->kvm)))
 			kvm_timer_sync_user(vcpu);
 
 		kvm_arch_vcpu_ctxsync_fp(vcpu);
@@ -1842,8 +1859,7 @@
 static void __init cpu_prepare_hyp_mode(int cpu, u32 hyp_va_bits)
 {
 	struct kvm_nvhe_init_params *params = per_cpu_ptr_nvhe_sym(kvm_init_params, cpu);
-	u64 mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
-	unsigned long tcr;
+	unsigned long tcr, ips;
 
 	/*
 	 * Calculate the raw per-cpu offset without a translation from the
@@ -1857,6 +1873,7 @@
 	params->mair_el2 = read_sysreg(mair_el1);
 
 	tcr = read_sysreg(tcr_el1);
+	ips = FIELD_GET(TCR_IPS_MASK, tcr);
 	if (cpus_have_final_cap(ARM64_KVM_HVHE)) {
 		tcr |= TCR_EPD1_MASK;
 	} else {
@@ -1866,8 +1883,8 @@
 	tcr &= ~TCR_T0SZ_MASK;
 	tcr |= TCR_T0SZ(hyp_va_bits);
 	tcr &= ~TCR_EL2_PS_MASK;
-	tcr |= FIELD_PREP(TCR_EL2_PS_MASK, kvm_get_parange(mmfr0));
-	if (kvm_lpa2_is_enabled())
+	tcr |= FIELD_PREP(TCR_EL2_PS_MASK, ips);
+	if (lpa2_is_enabled())
 		tcr |= TCR_EL2_DS;
 	params->tcr_el2 = tcr;
 
@@ -2459,21 +2476,27 @@
 
 struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr)
 {
-	struct kvm_vcpu *vcpu;
+	struct kvm_vcpu *vcpu = NULL;
+	struct kvm_mpidr_data *data;
 	unsigned long i;
 
 	mpidr &= MPIDR_HWID_BITMASK;
 
-	if (kvm->arch.mpidr_data) {
-		u16 idx = kvm_mpidr_index(kvm->arch.mpidr_data, mpidr);
+	rcu_read_lock();
+	data = rcu_dereference(kvm->arch.mpidr_data);
+
+	if (data) {
+		u16 idx = kvm_mpidr_index(data, mpidr);
 
-		vcpu = kvm_get_vcpu(kvm,
-				    kvm->arch.mpidr_data->cmpidr_to_idx[idx]);
+		vcpu = kvm_get_vcpu(kvm, data->cmpidr_to_idx[idx]);
 		if (mpidr != kvm_vcpu_get_mpidr_aff(vcpu))
 			vcpu = NULL;
+	}
+
+	rcu_read_unlock();
 
+	if (vcpu)
 		return vcpu;
-	}
 
 	kvm_for_each_vcpu(i, vcpu, kvm) {
 		if (mpidr == kvm_vcpu_get_mpidr_aff(vcpu))
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/guest.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/guest.c
@@ -251,6 +251,7 @@
 		case PSR_AA32_MODE_SVC:
 		case PSR_AA32_MODE_ABT:
 		case PSR_AA32_MODE_UND:
+		case PSR_AA32_MODE_SYS:
 			if (!vcpu_el1_is_32bit(vcpu))
 				return -EINVAL;
 			break;
@@ -276,7 +277,7 @@
 	if (*vcpu_cpsr(vcpu) & PSR_MODE32_BIT) {
 		int i, nr_reg;
 
-		switch (*vcpu_cpsr(vcpu)) {
+		switch (*vcpu_cpsr(vcpu) & PSR_AA32_MODE_MASK) {
 		/*
 		 * Either we are dealing with user mode, and only the
 		 * first 15 registers (+ PC) must be narrowed to 32bit.
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/hyp/aarch32.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/hyp/aarch32.c
@@ -50,9 +50,23 @@
 	u32 cpsr_cond;
 	int cond;
 
-	/* Top two bits non-zero?  Unconditional. */
-	if (kvm_vcpu_get_esr(vcpu) >> 30)
+	/*
+	 * These are the exception classes that could fire with a
+	 * conditional instruction.
+	 */
+	switch (kvm_vcpu_trap_get_class(vcpu)) {
+	case ESR_ELx_EC_CP15_32:
+	case ESR_ELx_EC_CP15_64:
+	case ESR_ELx_EC_CP14_MR:
+	case ESR_ELx_EC_CP14_LS:
+	case ESR_ELx_EC_FP_ASIMD:
+	case ESR_ELx_EC_CP10_ID:
+	case ESR_ELx_EC_CP14_64:
+	case ESR_ELx_EC_SVC32:
+		break;
+	default:
 		return true;
+	}
 
 	/* Is condition field valid? */
 	cond = kvm_vcpu_get_condition(vcpu);
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -415,9 +415,9 @@
 	return;
 }
 
-static __always_inline void do_ffa_mem_xfer(const u64 func_id,
-					    struct arm_smccc_res *res,
-					    struct kvm_cpu_context *ctxt)
+static void __do_ffa_mem_xfer(const u64 func_id,
+			      struct arm_smccc_res *res,
+			      struct kvm_cpu_context *ctxt)
 {
 	DECLARE_REG(u32, len, ctxt, 1);
 	DECLARE_REG(u32, fraglen, ctxt, 2);
@@ -429,9 +429,6 @@
 	u32 offset, nr_ranges;
 	int ret = 0;
 
-	BUILD_BUG_ON(func_id != FFA_FN64_MEM_SHARE &&
-		     func_id != FFA_FN64_MEM_LEND);
-
 	if (addr_mbz || npages_mbz || fraglen > len ||
 	    fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) {
 		ret = FFA_RET_INVALID_PARAMETERS;
@@ -450,6 +447,11 @@
 		goto out_unlock;
 	}
 
+	if (len > ffa_desc_buf.len) {
+		ret = FFA_RET_NO_MEMORY;
+		goto out_unlock;
+	}
+
 	buf = hyp_buffers.tx;
 	memcpy(buf, host_buffers.tx, fraglen);
 
@@ -501,6 +503,13 @@
 	goto out_unlock;
 }
 
+#define do_ffa_mem_xfer(fid, res, ctxt)				\
+	do {							\
+		BUILD_BUG_ON((fid) != FFA_FN64_MEM_SHARE &&	\
+			     (fid) != FFA_FN64_MEM_LEND);	\
+		__do_ffa_mem_xfer((fid), (res), (ctxt));	\
+	} while (0);
+
 static void do_ffa_mem_reclaim(struct arm_smccc_res *res,
 			       struct kvm_cpu_context *ctxt)
 {
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/hyp/nvhe/tlb.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/hyp/nvhe/tlb.c
@@ -154,7 +154,8 @@
 	/* Switch to requested VMID */
 	__tlb_switch_to_guest(mmu, &cxt, false);
 
-	__flush_s2_tlb_range_op(ipas2e1is, start, pages, stride, 0);
+	__flush_s2_tlb_range_op(ipas2e1is, start, pages, stride,
+				TLBI_TTL_UNKNOWN);
 
 	dsb(ish);
 	__tlbi(vmalle1is);
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/hyp/pgtable.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/hyp/pgtable.c
@@ -528,7 +528,7 @@
 
 		kvm_clear_pte(ctx->ptep);
 		dsb(ishst);
-		__tlbi_level(vae2is, __TLBI_VADDR(ctx->addr, 0), ctx->level);
+		__tlbi_level(vae2is, __TLBI_VADDR(ctx->addr, 0), 0);
 	} else {
 		if (ctx->end - ctx->addr < granule)
 			return -EINVAL;
@@ -829,12 +829,15 @@
 		 * Perform the appropriate TLB invalidation based on the
 		 * evicted pte value (if any).
 		 */
-		if (kvm_pte_table(ctx->old, ctx->level))
-			kvm_tlb_flush_vmid_range(mmu, ctx->addr,
-						kvm_granule_size(ctx->level));
-		else if (kvm_pte_valid(ctx->old))
+		if (kvm_pte_table(ctx->old, ctx->level)) {
+			u64 size = kvm_granule_size(ctx->level);
+			u64 addr = ALIGN_DOWN(ctx->addr, size);
+
+			kvm_tlb_flush_vmid_range(mmu, addr, size);
+		} else if (kvm_pte_valid(ctx->old)) {
 			kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu,
 				     ctx->addr, ctx->level);
+		}
 	}
 
 	if (stage2_pte_is_counted(ctx->old))
@@ -882,9 +885,13 @@
 	if (kvm_pte_valid(ctx->old)) {
 		kvm_clear_pte(ctx->ptep);
 
-		if (!stage2_unmap_defer_tlb_flush(pgt))
-			kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu,
-					ctx->addr, ctx->level);
+		if (kvm_pte_table(ctx->old, ctx->level)) {
+			kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu, ctx->addr,
+				     0);
+		} else if (!stage2_unmap_defer_tlb_flush(pgt)) {
+			kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, mmu, ctx->addr,
+				     ctx->level);
+		}
 	}
 
 	mm_ops->put_page(ctx->ptep);
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/hyp/vhe/tlb.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/hyp/vhe/tlb.c
@@ -171,7 +171,8 @@
 	/* Switch to requested VMID */
 	__tlb_switch_to_guest(mmu, &cxt);
 
-	__flush_s2_tlb_range_op(ipas2e1is, start, pages, stride, 0);
+	__flush_s2_tlb_range_op(ipas2e1is, start, pages, stride,
+				TLBI_TTL_UNKNOWN);
 
 	dsb(ish);
 	__tlbi(vmalle1is);
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/mmio.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/mmio.c
@@ -72,6 +72,31 @@
 	return data;
 }
 
+static bool kvm_pending_sync_exception(struct kvm_vcpu *vcpu)
+{
+	if (!vcpu_get_flag(vcpu, PENDING_EXCEPTION))
+		return false;
+
+	if (vcpu_el1_is_32bit(vcpu)) {
+		switch (vcpu_get_flag(vcpu, EXCEPT_MASK)) {
+		case unpack_vcpu_flag(EXCEPT_AA32_UND):
+		case unpack_vcpu_flag(EXCEPT_AA32_IABT):
+		case unpack_vcpu_flag(EXCEPT_AA32_DABT):
+			return true;
+		default:
+			return false;
+		}
+	} else {
+		switch (vcpu_get_flag(vcpu, EXCEPT_MASK)) {
+		case unpack_vcpu_flag(EXCEPT_AA64_EL1_SYNC):
+		case unpack_vcpu_flag(EXCEPT_AA64_EL2_SYNC):
+			return true;
+		default:
+			return false;
+		}
+	}
+}
+
 /**
  * kvm_handle_mmio_return -- Handle MMIO loads after user space emulation
  *			     or in-kernel IO emulation
@@ -84,9 +109,12 @@
 	unsigned int len;
 	int mask;
 
-	/* Detect an already handled MMIO return */
-	if (unlikely(!vcpu->mmio_needed))
-		return 0;
+	/*
+	 * Detect if the MMIO return was already handled or if userspace aborted
+	 * the MMIO access.
+	 */
+	if (unlikely(!vcpu->mmio_needed || kvm_pending_sync_exception(vcpu)))
+		return 1;
 
 	vcpu->mmio_needed = 0;
 
@@ -117,7 +145,7 @@
 	 */
 	kvm_incr_pc(vcpu);
 
-	return 0;
+	return 1;
 }
 
 int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa)
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/mmu.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/mmu.c
@@ -1631,7 +1631,7 @@
 	fault_ipa = kvm_vcpu_get_fault_ipa(vcpu);
 	is_iabt = kvm_vcpu_trap_is_iabt(vcpu);
 
-	if (esr_fsc_is_permission_fault(esr)) {
+	if (esr_fsc_is_translation_fault(esr)) {
 		/* Beyond sanitised PARange (which is the IPA limit) */
 		if (fault_ipa >= BIT_ULL(get_kvm_ipa_limit())) {
 			kvm_inject_size_fault(vcpu);
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/pmu-emul.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/pmu-emul.c
@@ -342,7 +342,6 @@
 
 	if ((kvm_vcpu_read_pmcr(vcpu) & ARMV8_PMU_PMCR_E)) {
 		reg = __vcpu_sys_reg(vcpu, PMOVSSET_EL0);
-		reg &= __vcpu_sys_reg(vcpu, PMCNTENSET_EL0);
 		reg &= __vcpu_sys_reg(vcpu, PMINTENSET_EL1);
 	}
 
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/sys_regs.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/sys_regs.c
@@ -32,6 +32,7 @@
 #include <trace/events/kvm.h>
 
 #include "sys_regs.h"
+#include "vgic/vgic.h"
 
 #include "trace.h"
 
@@ -427,6 +428,11 @@
 {
 	bool g1;
 
+	if (!kvm_has_gicv3(vcpu->kvm)) {
+		kvm_inject_undefined(vcpu);
+		return false;
+	}
+
 	if (!p->is_write)
 		return read_from_write_only(vcpu, p, r);
 
@@ -1531,6 +1537,7 @@
 			val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE);
 
 		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME);
+		val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MPAM_frac);
 		break;
 	case SYS_ID_AA64ISAR1_EL1:
 		if (!vcpu_has_ptrauth(vcpu))
@@ -1677,6 +1684,13 @@
 
 	val &= ~ID_AA64PFR0_EL1_AMU_MASK;
 
+	/*
+	 * MPAM is disabled by default as KVM also needs a set of PARTID to
+	 * program the MPAMVPMx_EL2 PARTID remapping registers with. But some
+	 * older kernels let the guest see the ID bit.
+	 */
+	val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
+
 	return val;
 }
 
@@ -1786,6 +1800,42 @@
 	return set_id_reg(vcpu, rd, val);
 }
 
+static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
+			       const struct sys_reg_desc *rd, u64 user_val)
+{
+	u64 hw_val = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
+	u64 mpam_mask = ID_AA64PFR0_EL1_MPAM_MASK;
+
+	/*
+	 * Commit 011e5f5bf529f ("arm64/cpufeature: Add remaining feature bits
+	 * in ID_AA64PFR0 register") exposed the MPAM field of AA64PFR0_EL1 to
+	 * guests, but didn't add trap handling. KVM doesn't support MPAM and
+	 * always returns an UNDEF for these registers. The guest must see 0
+	 * for this field.
+	 *
+	 * But KVM must also accept values from user-space that were provided
+	 * by KVM. On CPUs that support MPAM, permit user-space to write
+	 * the sanitizied value to ID_AA64PFR0_EL1.MPAM, but ignore this field.
+	 */
+	if ((hw_val & mpam_mask) == (user_val & mpam_mask))
+		user_val &= ~ID_AA64PFR0_EL1_MPAM_MASK;
+
+	return set_id_reg(vcpu, rd, user_val);
+}
+
+static int set_id_aa64pfr1_el1(struct kvm_vcpu *vcpu,
+			       const struct sys_reg_desc *rd, u64 user_val)
+{
+	u64 hw_val = read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1);
+	u64 mpam_mask = ID_AA64PFR1_EL1_MPAM_frac_MASK;
+
+	/* See set_id_aa64pfr0_el1 for comment about MPAM */
+	if ((hw_val & mpam_mask) == (user_val & mpam_mask))
+		user_val &= ~ID_AA64PFR1_EL1_MPAM_frac_MASK;
+
+	return set_id_reg(vcpu, rd, user_val);
+}
+
 /*
  * cpufeature ID register user accessors
  *
@@ -1934,7 +1984,7 @@
 	 * one cache line.
 	 */
 	if (kvm_has_mte(vcpu->kvm))
-		clidr |= 2 << CLIDR_TTYPE_SHIFT(loc);
+		clidr |= 2ULL << CLIDR_TTYPE_SHIFT(loc);
 
 	__vcpu_sys_reg(vcpu, r->reg) = clidr;
 
@@ -2282,7 +2332,7 @@
 	{ SYS_DESC(SYS_ID_AA64PFR0_EL1),
 	  .access = access_id_reg,
 	  .get_user = get_id_reg,
-	  .set_user = set_id_reg,
+	  .set_user = set_id_aa64pfr0_el1,
 	  .reset = read_sanitised_id_aa64pfr0_el1,
 	  .val = ~(ID_AA64PFR0_EL1_AMU |
 		   ID_AA64PFR0_EL1_MPAM |
@@ -2291,7 +2341,11 @@
 		   ID_AA64PFR0_EL1_GIC |
 		   ID_AA64PFR0_EL1_AdvSIMD |
 		   ID_AA64PFR0_EL1_FP), },
-	ID_SANITISED(ID_AA64PFR1_EL1),
+	{ SYS_DESC(SYS_ID_AA64PFR1_EL1),
+	  .access = access_id_reg,
+	  .get_user = get_id_reg,
+	  .set_user = set_id_aa64pfr1_el1,
+	  .reset = kvm_read_sanitised_id_reg, },
 	ID_UNALLOCATED(4,2),
 	ID_UNALLOCATED(4,3),
 	ID_WRITABLE(ID_AA64ZFR0_EL1, ~ID_AA64ZFR0_EL1_RES0),
@@ -2334,7 +2388,8 @@
 	ID_WRITABLE(ID_AA64MMFR0_EL1, ~(ID_AA64MMFR0_EL1_RES0 |
 					ID_AA64MMFR0_EL1_TGRAN4_2 |
 					ID_AA64MMFR0_EL1_TGRAN64_2 |
-					ID_AA64MMFR0_EL1_TGRAN16_2)),
+					ID_AA64MMFR0_EL1_TGRAN16_2 |
+					ID_AA64MMFR0_EL1_ASIDBITS)),
 	ID_WRITABLE(ID_AA64MMFR1_EL1, ~(ID_AA64MMFR1_EL1_RES0 |
 					ID_AA64MMFR1_EL1_HCX |
 					ID_AA64MMFR1_EL1_XNX |
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/vgic/vgic-init.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/vgic/vgic-init.c
@@ -355,7 +355,7 @@
 
 	if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
 		list_for_each_entry_safe(rdreg, next, &dist->rd_regions, list)
-			vgic_v3_free_redist_region(rdreg);
+			vgic_v3_free_redist_region(kvm, rdreg);
 		INIT_LIST_HEAD(&dist->rd_regions);
 	} else {
 		dist->vgic_cpu_base = VGIC_ADDR_UNDEF;
@@ -494,10 +494,10 @@
 out:
 	mutex_unlock(&kvm->arch.config_lock);
 out_slots:
-	mutex_unlock(&kvm->slots_lock);
-
 	if (ret)
-		kvm_vgic_destroy(kvm);
+		kvm_vm_dead(kvm);
+
+	mutex_unlock(&kvm->slots_lock);
 
 	return ret;
 }
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/vgic/vgic-its.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/vgic/vgic-its.c
@@ -861,6 +861,9 @@
 
 	ite = find_ite(its, device_id, event_id);
 	if (ite && its_is_collection_mapped(ite->collection)) {
+		struct its_device *device = find_its_device(its, device_id);
+		int ite_esz = vgic_its_get_abi(its)->ite_esz;
+		gpa_t gpa = device->itt_addr + ite->event_id * ite_esz;
 		/*
 		 * Though the spec talks about removing the pending state, we
 		 * don't bother here since we clear the ITTE anyway and the
@@ -869,7 +872,8 @@
 		vgic_its_invalidate_cache(kvm);
 
 		its_free_ite(kvm, ite);
-		return 0;
+
+		return vgic_its_write_entry_lock(its, gpa, 0, ite_esz);
 	}
 
 	return E_ITS_DISCARD_UNMAPPED_INTERRUPT;
@@ -1217,9 +1221,11 @@
 	bool valid = its_cmd_get_validbit(its_cmd);
 	u8 num_eventid_bits = its_cmd_get_size(its_cmd);
 	gpa_t itt_addr = its_cmd_get_ittaddr(its_cmd);
+	int dte_esz = vgic_its_get_abi(its)->dte_esz;
 	struct its_device *device;
+	gpa_t gpa;
 
-	if (!vgic_its_check_id(its, its->baser_device_table, device_id, NULL))
+	if (!vgic_its_check_id(its, its->baser_device_table, device_id, &gpa))
 		return E_ITS_MAPD_DEVICE_OOR;
 
 	if (valid && num_eventid_bits > VITS_TYPER_IDBITS)
@@ -1240,7 +1246,7 @@
 	 * is an error, so we are done in any case.
 	 */
 	if (!valid)
-		return 0;
+		return vgic_its_write_entry_lock(its, gpa, 0, dte_esz);
 
 	device = vgic_its_alloc_device(its, device_id, itt_addr,
 				       num_eventid_bits);
@@ -2212,7 +2218,6 @@
 static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev,
 			      struct its_ite *ite, gpa_t gpa, int ite_esz)
 {
-	struct kvm *kvm = its->dev->kvm;
 	u32 next_offset;
 	u64 val;
 
@@ -2221,7 +2226,8 @@
 	       ((u64)ite->irq->intid << KVM_ITS_ITE_PINTID_SHIFT) |
 		ite->collection->collection_id;
 	val = cpu_to_le64(val);
-	return vgic_write_guest_lock(kvm, gpa, &val, ite_esz);
+
+	return vgic_its_write_entry_lock(its, gpa, val, ite_esz);
 }
 
 /**
@@ -2362,7 +2368,6 @@
 static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev,
 			     gpa_t ptr, int dte_esz)
 {
-	struct kvm *kvm = its->dev->kvm;
 	u64 val, itt_addr_field;
 	u32 next_offset;
 
@@ -2373,7 +2378,8 @@
 	       (itt_addr_field << KVM_ITS_DTE_ITTADDR_SHIFT) |
 		(dev->num_eventid_bits - 1));
 	val = cpu_to_le64(val);
-	return vgic_write_guest_lock(kvm, ptr, &val, dte_esz);
+
+	return vgic_its_write_entry_lock(its, ptr, val, dte_esz);
 }
 
 /**
@@ -2560,7 +2566,8 @@
 	       ((u64)collection->target_addr << KVM_ITS_CTE_RDBASE_SHIFT) |
 	       collection->collection_id);
 	val = cpu_to_le64(val);
-	return vgic_write_guest_lock(its->dev->kvm, gpa, &val, esz);
+
+	return vgic_its_write_entry_lock(its, gpa, val, esz);
 }
 
 /*
@@ -2576,8 +2583,7 @@
 	u64 val;
 	int ret;
 
-	BUG_ON(esz > sizeof(val));
-	ret = kvm_read_guest_lock(kvm, gpa, &val, esz);
+	ret = vgic_its_read_entry_lock(its, gpa, &val, esz);
 	if (ret)
 		return ret;
 	val = le64_to_cpu(val);
@@ -2615,7 +2621,6 @@
 	u64 baser = its->baser_coll_table;
 	gpa_t gpa = GITS_BASER_ADDR_48_to_52(baser);
 	struct its_collection *collection;
-	u64 val;
 	size_t max_size, filled = 0;
 	int ret, cte_esz = abi->cte_esz;
 
@@ -2639,10 +2644,7 @@
 	 * table is not fully filled, add a last dummy element
 	 * with valid bit unset
 	 */
-	val = 0;
-	BUG_ON(cte_esz > sizeof(val));
-	ret = vgic_write_guest_lock(its->dev->kvm, gpa, &val, cte_esz);
-	return ret;
+	return vgic_its_write_entry_lock(its, gpa, 0, cte_esz);
 }
 
 /**
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/vgic/vgic-kvm-device.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/vgic/vgic-kvm-device.c
@@ -338,12 +338,12 @@
 int vgic_v2_parse_attr(struct kvm_device *dev, struct kvm_device_attr *attr,
 		       struct vgic_reg_attr *reg_attr)
 {
-	int cpuid;
+	int cpuid = FIELD_GET(KVM_DEV_ARM_VGIC_CPUID_MASK, attr->attr);
 
-	cpuid = FIELD_GET(KVM_DEV_ARM_VGIC_CPUID_MASK, attr->attr);
-
-	reg_attr->vcpu = kvm_get_vcpu_by_id(dev->kvm, cpuid);
 	reg_attr->addr = attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK;
+	reg_attr->vcpu = kvm_get_vcpu_by_id(dev->kvm, cpuid);
+	if (!reg_attr->vcpu)
+		return -EINVAL;
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/vgic/vgic-mmio-v3.c
+++ linux-qcom-6.8.0/arch/arm64/kvm/vgic/vgic-mmio-v3.c
@@ -530,6 +530,7 @@
 				   unsigned long val)
 {
 	struct vgic_irq *irq;
+	u32 intid;
 
 	/*
 	 * If the guest wrote only to the upper 32bit part of the
@@ -541,9 +542,13 @@
 	if ((addr & 4) || !vgic_lpis_enabled(vcpu))
 		return;
 
+	intid = lower_32_bits(val);
+	if (intid < VGIC_MIN_LPI)
+		return;
+
 	vgic_set_rdist_busy(vcpu, true);
 
-	irq = vgic_get_irq(vcpu->kvm, NULL, lower_32_bits(val));
+	irq = vgic_get_irq(vcpu->kvm, NULL, intid);
 	if (irq) {
 		vgic_its_inv_lpi(vcpu->kvm, irq);
 		vgic_put_irq(vcpu->kvm, irq);
@@ -919,8 +924,19 @@
 	return ret;
 }
 
-void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg)
+void vgic_v3_free_redist_region(struct kvm *kvm, struct vgic_redist_region *rdreg)
 {
+	struct kvm_vcpu *vcpu;
+	unsigned long c;
+
+	lockdep_assert_held(&kvm->arch.config_lock);
+
+	/* Garbage collect the region */
+	kvm_for_each_vcpu(c, vcpu, kvm) {
+		if (vcpu->arch.vgic_cpu.rdreg == rdreg)
+			vcpu->arch.vgic_cpu.rdreg = NULL;
+	}
+
 	list_del(&rdreg->list);
 	kfree(rdreg);
 }
@@ -945,7 +961,7 @@
 
 		mutex_lock(&kvm->arch.config_lock);
 		rdreg = vgic_v3_rdist_region_from_index(kvm, index);
-		vgic_v3_free_redist_region(rdreg);
+		vgic_v3_free_redist_region(kvm, rdreg);
 		mutex_unlock(&kvm->arch.config_lock);
 		return ret;
 	}
--- linux-qcom-6.8.0.orig/arch/arm64/kvm/vgic/vgic.h
+++ linux-qcom-6.8.0/arch/arm64/kvm/vgic/vgic.h
@@ -145,6 +145,29 @@
 	return ret;
 }
 
+static inline int vgic_its_read_entry_lock(struct vgic_its *its, gpa_t eaddr,
+					   u64 *eval, unsigned long esize)
+{
+	struct kvm *kvm = its->dev->kvm;
+
+	if (KVM_BUG_ON(esize != sizeof(*eval), kvm))
+		return -EINVAL;
+
+	return kvm_read_guest_lock(kvm, eaddr, eval, esize);
+
+}
+
+static inline int vgic_its_write_entry_lock(struct vgic_its *its, gpa_t eaddr,
+					    u64 eval, unsigned long esize)
+{
+	struct kvm *kvm = its->dev->kvm;
+
+	if (KVM_BUG_ON(esize != sizeof(eval), kvm))
+		return -EINVAL;
+
+	return vgic_write_guest_lock(kvm, eaddr, &eval, esize);
+}
+
 /*
  * This struct provides an intermediate representation of the fields contained
  * in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC
@@ -310,7 +333,7 @@
 
 struct vgic_redist_region *vgic_v3_rdist_region_from_index(struct kvm *kvm,
 							   u32 index);
-void vgic_v3_free_redist_region(struct vgic_redist_region *rdreg);
+void vgic_v3_free_redist_region(struct kvm *kvm, struct vgic_redist_region *rdreg);
 
 bool vgic_v3_rdist_overlap(struct kvm *kvm, gpa_t base, size_t size);
 
@@ -343,4 +366,11 @@
 void vgic_v4_get_vlpi_state(struct vgic_irq *irq, bool *val);
 int vgic_v4_request_vpe_irq(struct kvm_vcpu *vcpu, int irq);
 
+static inline bool kvm_has_gicv3(struct kvm *kvm)
+{
+	return (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif) &&
+		irqchip_in_kernel(kvm) &&
+		kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3);
+}
+
 #endif
--- linux-qcom-6.8.0.orig/arch/arm64/mm/context.c
+++ linux-qcom-6.8.0/arch/arm64/mm/context.c
@@ -32,9 +32,9 @@
 static unsigned long *pinned_asid_map;
 
 #define ASID_MASK		(~GENMASK(asid_bits - 1, 0))
-#define ASID_FIRST_VERSION	(1UL << asid_bits)
+#define ASID_FIRST_VERSION	(1UL << 16)
 
-#define NUM_USER_ASIDS		ASID_FIRST_VERSION
+#define NUM_USER_ASIDS		(1UL << asid_bits)
 #define ctxid2asid(asid)	((asid) & ~ASID_MASK)
 #define asid2ctxid(asid, genid)	((asid) | (genid))
 
--- linux-qcom-6.8.0.orig/arch/arm64/mm/hugetlbpage.c
+++ linux-qcom-6.8.0/arch/arm64/mm/hugetlbpage.c
@@ -526,6 +526,18 @@
 
 static int __init hugetlbpage_init(void)
 {
+	/*
+	 * HugeTLB pages are supported on maximum four page table
+	 * levels (PUD, CONT PMD, PMD, CONT PTE) for a given base
+	 * page size, corresponding to hugetlb_add_hstate() calls
+	 * here.
+	 *
+	 * HUGE_MAX_HSTATE should at least match maximum supported
+	 * HugeTLB page sizes on the platform. Any new addition to
+	 * supported HugeTLB page sizes will also require changing
+	 * HUGE_MAX_HSTATE as well.
+	 */
+	BUILD_BUG_ON(HUGE_MAX_HSTATE < 4);
 	if (pud_sect_supported())
 		hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
 
--- linux-qcom-6.8.0.orig/arch/arm64/mm/mmu.c
+++ linux-qcom-6.8.0/arch/arm64/mm/mmu.c
@@ -103,28 +103,12 @@
 static phys_addr_t __init early_pgtable_alloc(int shift)
 {
 	phys_addr_t phys;
-	void *ptr;
 
 	phys = memblock_phys_alloc_range(PAGE_SIZE, PAGE_SIZE, 0,
 					 MEMBLOCK_ALLOC_NOLEAKTRACE);
 	if (!phys)
 		panic("Failed to allocate page table page\n");
 
-	/*
-	 * The FIX_{PGD,PUD,PMD} slots may be in active use, but the FIX_PTE
-	 * slot will be free, so we can (ab)use the FIX_PTE slot to initialise
-	 * any level of table.
-	 */
-	ptr = pte_set_fixmap(phys);
-
-	memset(ptr, 0, PAGE_SIZE);
-
-	/*
-	 * Implicit barriers also ensure the zeroed page is visible to the page
-	 * table walker
-	 */
-	pte_clear_fixmap();
-
 	return phys;
 }
 
@@ -166,16 +150,25 @@
 	return ((old ^ new) & ~mask) == 0;
 }
 
-static void init_pte(pmd_t *pmdp, unsigned long addr, unsigned long end,
-		     phys_addr_t phys, pgprot_t prot)
+static void init_clear_pgtable(void *table)
 {
-	pte_t *ptep;
+	clear_page(table);
+
+	/* Ensure the zeroing is observed by page table walks. */
+	dsb(ishst);
+}
 
-	ptep = pte_set_fixmap_offset(pmdp, addr);
+static void init_pte(pte_t *ptep, unsigned long addr, unsigned long end,
+		     phys_addr_t phys, pgprot_t prot)
+{
 	do {
 		pte_t old_pte = READ_ONCE(*ptep);
 
-		set_pte(ptep, pfn_pte(__phys_to_pfn(phys), prot));
+		/*
+		 * Required barriers to make this visible to the table walker
+		 * are deferred to the end of alloc_init_cont_pte().
+		 */
+		set_pte_nosync(ptep, pfn_pte(__phys_to_pfn(phys), prot));
 
 		/*
 		 * After the PTE entry has been populated once, we
@@ -186,8 +179,6 @@
 
 		phys += PAGE_SIZE;
 	} while (ptep++, addr += PAGE_SIZE, addr != end);
-
-	pte_clear_fixmap();
 }
 
 static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr,
@@ -198,6 +189,7 @@
 {
 	unsigned long next;
 	pmd_t pmd = READ_ONCE(*pmdp);
+	pte_t *ptep;
 
 	BUG_ON(pmd_sect(pmd));
 	if (pmd_none(pmd)) {
@@ -208,10 +200,14 @@
 			pmdval |= PMD_TABLE_PXN;
 		BUG_ON(!pgtable_alloc);
 		pte_phys = pgtable_alloc(PAGE_SHIFT);
+		ptep = pte_set_fixmap(pte_phys);
+		init_clear_pgtable(ptep);
+		ptep += pte_index(addr);
 		__pmd_populate(pmdp, pte_phys, pmdval);
-		pmd = READ_ONCE(*pmdp);
+	} else {
+		BUG_ON(pmd_bad(pmd));
+		ptep = pte_set_fixmap_offset(pmdp, addr);
 	}
-	BUG_ON(pmd_bad(pmd));
 
 	do {
 		pgprot_t __prot = prot;
@@ -223,20 +219,26 @@
 		    (flags & NO_CONT_MAPPINGS) == 0)
 			__prot = __pgprot(pgprot_val(prot) | PTE_CONT);
 
-		init_pte(pmdp, addr, next, phys, __prot);
+		init_pte(ptep, addr, next, phys, __prot);
 
+		ptep += pte_index(next) - pte_index(addr);
 		phys += next - addr;
 	} while (addr = next, addr != end);
+
+	/*
+	 * Note: barriers and maintenance necessary to clear the fixmap slot
+	 * ensure that all previous pgtable writes are visible to the table
+	 * walker.
+	 */
+	pte_clear_fixmap();
 }
 
-static void init_pmd(pud_t *pudp, unsigned long addr, unsigned long end,
+static void init_pmd(pmd_t *pmdp, unsigned long addr, unsigned long end,
 		     phys_addr_t phys, pgprot_t prot,
 		     phys_addr_t (*pgtable_alloc)(int), int flags)
 {
 	unsigned long next;
-	pmd_t *pmdp;
 
-	pmdp = pmd_set_fixmap_offset(pudp, addr);
 	do {
 		pmd_t old_pmd = READ_ONCE(*pmdp);
 
@@ -262,8 +264,6 @@
 		}
 		phys += next - addr;
 	} while (pmdp++, addr = next, addr != end);
-
-	pmd_clear_fixmap();
 }
 
 static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr,
@@ -273,6 +273,7 @@
 {
 	unsigned long next;
 	pud_t pud = READ_ONCE(*pudp);
+	pmd_t *pmdp;
 
 	/*
 	 * Check for initial section mappings in the pgd/pud.
@@ -286,10 +287,14 @@
 			pudval |= PUD_TABLE_PXN;
 		BUG_ON(!pgtable_alloc);
 		pmd_phys = pgtable_alloc(PMD_SHIFT);
+		pmdp = pmd_set_fixmap(pmd_phys);
+		init_clear_pgtable(pmdp);
+		pmdp += pmd_index(addr);
 		__pud_populate(pudp, pmd_phys, pudval);
-		pud = READ_ONCE(*pudp);
+	} else {
+		BUG_ON(pud_bad(pud));
+		pmdp = pmd_set_fixmap_offset(pudp, addr);
 	}
-	BUG_ON(pud_bad(pud));
 
 	do {
 		pgprot_t __prot = prot;
@@ -301,10 +306,13 @@
 		    (flags & NO_CONT_MAPPINGS) == 0)
 			__prot = __pgprot(pgprot_val(prot) | PTE_CONT);
 
-		init_pmd(pudp, addr, next, phys, __prot, pgtable_alloc, flags);
+		init_pmd(pmdp, addr, next, phys, __prot, pgtable_alloc, flags);
 
+		pmdp += pmd_index(next) - pmd_index(addr);
 		phys += next - addr;
 	} while (addr = next, addr != end);
+
+	pmd_clear_fixmap();
 }
 
 static void alloc_init_pud(pgd_t *pgdp, unsigned long addr, unsigned long end,
@@ -325,12 +333,15 @@
 			p4dval |= P4D_TABLE_PXN;
 		BUG_ON(!pgtable_alloc);
 		pud_phys = pgtable_alloc(PUD_SHIFT);
+		pudp = pud_set_fixmap(pud_phys);
+		init_clear_pgtable(pudp);
+		pudp += pud_index(addr);
 		__p4d_populate(p4dp, pud_phys, p4dval);
-		p4d = READ_ONCE(*p4dp);
+	} else {
+		BUG_ON(p4d_bad(p4d));
+		pudp = pud_set_fixmap_offset(p4dp, addr);
 	}
-	BUG_ON(p4d_bad(p4d));
 
-	pudp = pud_set_fixmap_offset(p4dp, addr);
 	do {
 		pud_t old_pud = READ_ONCE(*pudp);
 
@@ -412,11 +423,10 @@
 
 static phys_addr_t __pgd_pgtable_alloc(int shift)
 {
-	void *ptr = (void *)__get_free_page(GFP_PGTABLE_KERNEL);
-	BUG_ON(!ptr);
+	/* Page is zeroed by init_clear_pgtable() so don't duplicate effort. */
+	void *ptr = (void *)__get_free_page(GFP_PGTABLE_KERNEL & ~__GFP_ZERO);
 
-	/* Ensure the zeroed page is visible to the page table walker */
-	dsb(ishst);
+	BUG_ON(!ptr);
 	return __pa(ptr);
 }
 
--- linux-qcom-6.8.0.orig/arch/arm64/mm/pageattr.c
+++ linux-qcom-6.8.0/arch/arm64/mm/pageattr.c
@@ -219,9 +219,6 @@
 	pte_t *ptep;
 	unsigned long addr = (unsigned long)page_address(page);
 
-	if (!can_set_direct_map())
-		return true;
-
 	pgdp = pgd_offset_k(addr);
 	if (pgd_none(READ_ONCE(*pgdp)))
 		return false;
--- linux-qcom-6.8.0.orig/arch/arm64/mm/trans_pgd.c
+++ linux-qcom-6.8.0/arch/arm64/mm/trans_pgd.c
@@ -42,14 +42,16 @@
 		 * the temporary mappings we use during restore.
 		 */
 		set_pte(dst_ptep, pte_mkwrite_novma(pte));
-	} else if ((debug_pagealloc_enabled() ||
-		   is_kfence_address((void *)addr)) && !pte_none(pte)) {
+	} else if (!pte_none(pte)) {
 		/*
 		 * debug_pagealloc will removed the PTE_VALID bit if
 		 * the page isn't in use by the resume kernel. It may have
 		 * been in use by the original kernel, in which case we need
 		 * to put it back in our copy to do the restore.
 		 *
+		 * Other cases include kfence / vmalloc / memfd_secret which
+		 * may call `set_direct_map_invalid_noflush()`.
+		 *
 		 * Before marking this entry valid, check the pfn should
 		 * be mapped.
 		 */
--- linux-qcom-6.8.0.orig/arch/arm64/net/bpf_jit_comp.c
+++ linux-qcom-6.8.0/arch/arm64/net/bpf_jit_comp.c
@@ -26,7 +26,7 @@
 
 #define TMP_REG_1 (MAX_BPF_JIT_REG + 0)
 #define TMP_REG_2 (MAX_BPF_JIT_REG + 1)
-#define TCALL_CNT (MAX_BPF_JIT_REG + 2)
+#define TCCNT_PTR (MAX_BPF_JIT_REG + 2)
 #define TMP_REG_3 (MAX_BPF_JIT_REG + 3)
 #define FP_BOTTOM (MAX_BPF_JIT_REG + 4)
 
@@ -62,8 +62,8 @@
 	[TMP_REG_1] = A64_R(10),
 	[TMP_REG_2] = A64_R(11),
 	[TMP_REG_3] = A64_R(12),
-	/* tail_call_cnt */
-	[TCALL_CNT] = A64_R(26),
+	/* tail_call_cnt_ptr */
+	[TCCNT_PTR] = A64_R(26),
 	/* temporary register for blinding constants */
 	[BPF_REG_AX] = A64_R(9),
 	[FP_BOTTOM] = A64_R(27),
@@ -269,13 +269,35 @@
  *      mov x29, sp
  *      stp x19, x20, [sp, #-16]!
  *      stp x21, x22, [sp, #-16]!
- *      stp x25, x26, [sp, #-16]!
+ *      stp x26, x25, [sp, #-16]!
+ *      stp x26, x25, [sp, #-16]!
  *      stp x27, x28, [sp, #-16]!
  *      mov x25, sp
  *      mov tcc, #0
  *      // PROLOGUE_OFFSET
  */
 
+static void prepare_bpf_tail_call_cnt(struct jit_ctx *ctx)
+{
+	const struct bpf_prog *prog = ctx->prog;
+	const bool is_main_prog = !bpf_is_subprog(prog);
+	const u8 ptr = bpf2a64[TCCNT_PTR];
+	const u8 fp = bpf2a64[BPF_REG_FP];
+	const u8 tcc = ptr;
+
+	emit(A64_PUSH(ptr, fp, A64_SP), ctx);
+	if (is_main_prog) {
+		/* Initialize tail_call_cnt. */
+		emit(A64_MOVZ(1, tcc, 0, 0), ctx);
+		emit(A64_PUSH(tcc, fp, A64_SP), ctx);
+		emit(A64_MOV(1, ptr, A64_SP), ctx);
+	} else {
+		emit(A64_PUSH(ptr, fp, A64_SP), ctx);
+		emit(A64_NOP, ctx);
+		emit(A64_NOP, ctx);
+	}
+}
+
 #define BTI_INSNS (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) ? 1 : 0)
 #define PAC_INSNS (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL) ? 1 : 0)
 
@@ -283,7 +305,7 @@
 #define POKE_OFFSET (BTI_INSNS + 1)
 
 /* Tail call offset to jump into */
-#define PROLOGUE_OFFSET (BTI_INSNS + 2 + PAC_INSNS + 8)
+#define PROLOGUE_OFFSET (BTI_INSNS + 2 + PAC_INSNS + 10)
 
 static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
 {
@@ -294,7 +316,6 @@
 	const u8 r8 = bpf2a64[BPF_REG_8];
 	const u8 r9 = bpf2a64[BPF_REG_9];
 	const u8 fp = bpf2a64[BPF_REG_FP];
-	const u8 tcc = bpf2a64[TCALL_CNT];
 	const u8 fpb = bpf2a64[FP_BOTTOM];
 	const int idx0 = ctx->idx;
 	int cur_offset;
@@ -344,16 +365,13 @@
 	/* Save callee-saved registers */
 	emit(A64_PUSH(r6, r7, A64_SP), ctx);
 	emit(A64_PUSH(r8, r9, A64_SP), ctx);
-	emit(A64_PUSH(fp, tcc, A64_SP), ctx);
+	prepare_bpf_tail_call_cnt(ctx);
 	emit(A64_PUSH(fpb, A64_R(28), A64_SP), ctx);
 
 	/* Set up BPF prog stack base register */
 	emit(A64_MOV(1, fp, A64_SP), ctx);
 
 	if (!ebpf_from_cbpf && is_main_prog) {
-		/* Initialize tail_call_cnt */
-		emit(A64_MOVZ(1, tcc, 0, 0), ctx);
-
 		cur_offset = ctx->idx - idx0;
 		if (cur_offset != PROLOGUE_OFFSET) {
 			pr_err_once("PROLOGUE_OFFSET = %d, expected %d!\n",
@@ -384,7 +402,8 @@
 
 	const u8 tmp = bpf2a64[TMP_REG_1];
 	const u8 prg = bpf2a64[TMP_REG_2];
-	const u8 tcc = bpf2a64[TCALL_CNT];
+	const u8 tcc = bpf2a64[TMP_REG_3];
+	const u8 ptr = bpf2a64[TCCNT_PTR];
 	const int idx0 = ctx->idx;
 #define cur_offset (ctx->idx - idx0)
 #define jmp_offset (out_offset - (cur_offset))
@@ -401,11 +420,12 @@
 	emit(A64_B_(A64_COND_CS, jmp_offset), ctx);
 
 	/*
-	 * if (tail_call_cnt >= MAX_TAIL_CALL_CNT)
+	 * if ((*tail_call_cnt_ptr) >= MAX_TAIL_CALL_CNT)
 	 *     goto out;
-	 * tail_call_cnt++;
+	 * (*tail_call_cnt_ptr)++;
 	 */
 	emit_a64_mov_i64(tmp, MAX_TAIL_CALL_CNT, ctx);
+	emit(A64_LDR64I(tcc, ptr, 0), ctx);
 	emit(A64_CMP(1, tcc, tmp), ctx);
 	emit(A64_B_(A64_COND_CS, jmp_offset), ctx);
 	emit(A64_ADD_I(1, tcc, tcc, 1), ctx);
@@ -421,6 +441,9 @@
 	emit(A64_LDR64(prg, tmp, prg), ctx);
 	emit(A64_CBZ(1, prg, jmp_offset), ctx);
 
+	/* Update tail_call_cnt if the slot is populated. */
+	emit(A64_STR64I(tcc, ptr, 0), ctx);
+
 	/* goto *(prog->bpf_func + prologue_offset); */
 	off = offsetof(struct bpf_prog, bpf_func);
 	emit_a64_mov_i64(tmp, off, ctx);
@@ -661,6 +684,7 @@
 	const u8 r8 = bpf2a64[BPF_REG_8];
 	const u8 r9 = bpf2a64[BPF_REG_9];
 	const u8 fp = bpf2a64[BPF_REG_FP];
+	const u8 ptr = bpf2a64[TCCNT_PTR];
 	const u8 fpb = bpf2a64[FP_BOTTOM];
 
 	/* We're done with BPF stack */
@@ -669,7 +693,8 @@
 	/* Restore x27 and x28 */
 	emit(A64_POP(fpb, A64_R(28), A64_SP), ctx);
 	/* Restore fs (x25) and x26 */
-	emit(A64_POP(fp, A64_R(26), A64_SP), ctx);
+	emit(A64_POP(ptr, fp, A64_SP), ctx);
+	emit(A64_POP(ptr, fp, A64_SP), ctx);
 
 	/* Restore callee-saved register */
 	emit(A64_POP(r8, r9, A64_SP), ctx);
@@ -876,7 +901,7 @@
 			emit(A64_UXTH(is64, dst, dst), ctx);
 			break;
 		case 32:
-			emit(A64_REV32(is64, dst, dst), ctx);
+			emit(A64_REV32(0, dst, dst), ctx);
 			/* upper 32 bits already cleared */
 			break;
 		case 64:
@@ -1189,7 +1214,7 @@
 			} else {
 				emit_a64_mov_i(1, tmp, off, ctx);
 				if (sign_extend)
-					emit(A64_LDRSW(dst, src_adj, off_adj), ctx);
+					emit(A64_LDRSW(dst, src, tmp), ctx);
 				else
 					emit(A64_LDR32(dst, src, tmp), ctx);
 			}
@@ -1648,7 +1673,8 @@
 			prog->jited_len = 0;
 			goto out_off;
 		}
-		bpf_jit_binary_lock_ro(header);
+		if (bpf_jit_binary_lock_ro(header))
+			goto out_off;
 	} else {
 		jit_data->ctx = ctx;
 		jit_data->image = image_ptr;
@@ -1738,15 +1764,15 @@
 
 	emit_call(enter_prog, ctx);
 
+	/* save return value to callee saved register x20 */
+	emit(A64_MOV(1, A64_R(20), A64_R(0)), ctx);
+
 	/* if (__bpf_prog_enter(prog) == 0)
 	 *         goto skip_exec_of_prog;
 	 */
 	branch = ctx->image + ctx->idx;
 	emit(A64_NOP, ctx);
 
-	/* save return value to callee saved register x20 */
-	emit(A64_MOV(1, A64_R(20), A64_R(0)), ctx);
-
 	emit(A64_ADD_I(1, A64_R(0), A64_SP, args_off), ctx);
 	if (!p->jited)
 		emit_addr_mov_i64(A64_R(1), (const u64)p->insnsi, ctx);
@@ -1816,6 +1842,12 @@
 	}
 }
 
+static bool is_struct_ops_tramp(const struct bpf_tramp_links *fentry_links)
+{
+	return fentry_links->nr_links == 1 &&
+		fentry_links->links[0]->link.type == BPF_LINK_TYPE_STRUCT_OPS;
+}
+
 /* Based on the x86's implementation of arch_prepare_bpf_trampoline().
  *
  * bpf prog and function entry before bpf trampoline hooked:
@@ -1845,6 +1877,7 @@
 	struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN];
 	bool save_ret;
 	__le32 **branches = NULL;
+	bool is_struct_ops = is_struct_ops_tramp(fentry);
 
 	/* trampoline stack layout:
 	 *                  [ parent ip         ]
@@ -1913,11 +1946,14 @@
 	 */
 	emit_bti(A64_BTI_JC, ctx);
 
-	/* frame for parent function */
-	emit(A64_PUSH(A64_FP, A64_R(9), A64_SP), ctx);
-	emit(A64_MOV(1, A64_FP, A64_SP), ctx);
+	/* x9 is not set for struct_ops */
+	if (!is_struct_ops) {
+		/* frame for parent function */
+		emit(A64_PUSH(A64_FP, A64_R(9), A64_SP), ctx);
+		emit(A64_MOV(1, A64_FP, A64_SP), ctx);
+	}
 
-	/* frame for patched function */
+	/* frame for patched function for tracing, or caller for struct_ops */
 	emit(A64_PUSH(A64_FP, A64_LR, A64_SP), ctx);
 	emit(A64_MOV(1, A64_FP, A64_SP), ctx);
 
@@ -1942,7 +1978,11 @@
 	emit(A64_STR64I(A64_R(20), A64_SP, regs_off + 8), ctx);
 
 	if (flags & BPF_TRAMP_F_CALL_ORIG) {
-		emit_addr_mov_i64(A64_R(0), (const u64)im, ctx);
+		/* for the first pass, assume the worst case */
+		if (!ctx->image)
+			ctx->idx += 4;
+		else
+			emit_a64_mov_i64(A64_R(0), (const u64)im, ctx);
 		emit_call((const u64)__bpf_tramp_enter, ctx);
 	}
 
@@ -1986,7 +2026,11 @@
 
 	if (flags & BPF_TRAMP_F_CALL_ORIG) {
 		im->ip_epilogue = ctx->image + ctx->idx;
-		emit_addr_mov_i64(A64_R(0), (const u64)im, ctx);
+		/* for the first pass, assume the worst case */
+		if (!ctx->image)
+			ctx->idx += 4;
+		else
+			emit_a64_mov_i64(A64_R(0), (const u64)im, ctx);
 		emit_call((const u64)__bpf_tramp_exit, ctx);
 	}
 
@@ -2003,19 +2047,24 @@
 	/* reset SP  */
 	emit(A64_MOV(1, A64_SP, A64_FP), ctx);
 
-	/* pop frames  */
-	emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx);
-	emit(A64_POP(A64_FP, A64_R(9), A64_SP), ctx);
-
-	if (flags & BPF_TRAMP_F_SKIP_FRAME) {
-		/* skip patched function, return to parent */
-		emit(A64_MOV(1, A64_LR, A64_R(9)), ctx);
-		emit(A64_RET(A64_R(9)), ctx);
+	if (is_struct_ops) {
+		emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx);
+		emit(A64_RET(A64_LR), ctx);
 	} else {
-		/* return to patched function */
-		emit(A64_MOV(1, A64_R(10), A64_LR), ctx);
-		emit(A64_MOV(1, A64_LR, A64_R(9)), ctx);
-		emit(A64_RET(A64_R(10)), ctx);
+		/* pop frames */
+		emit(A64_POP(A64_FP, A64_LR, A64_SP), ctx);
+		emit(A64_POP(A64_FP, A64_R(9), A64_SP), ctx);
+
+		if (flags & BPF_TRAMP_F_SKIP_FRAME) {
+			/* skip patched function, return to parent */
+			emit(A64_MOV(1, A64_LR, A64_R(9)), ctx);
+			emit(A64_RET(A64_R(9)), ctx);
+		} else {
+			/* return to patched function */
+			emit(A64_MOV(1, A64_R(10), A64_LR), ctx);
+			emit(A64_MOV(1, A64_LR, A64_R(9)), ctx);
+			emit(A64_RET(A64_R(10)), ctx);
+		}
 	}
 
 	if (ctx->image)
--- linux-qcom-6.8.0.orig/arch/arm64/tools/cpucaps
+++ linux-qcom-6.8.0/arch/arm64/tools/cpucaps
@@ -99,4 +99,5 @@
 WORKAROUND_QCOM_FALKOR_E1003
 WORKAROUND_REPEAT_TLBI
 WORKAROUND_SPECULATIVE_AT
+WORKAROUND_SPECULATIVE_SSBS
 WORKAROUND_SPECULATIVE_UNPRIV_LOAD
--- linux-qcom-6.8.0.orig/arch/csky/include/uapi/asm/unistd.h
+++ linux-qcom-6.8.0/arch/csky/include/uapi/asm/unistd.h
@@ -6,6 +6,7 @@
 #define __ARCH_WANT_SYS_CLONE3
 #define __ARCH_WANT_SET_GET_RLIMIT
 #define __ARCH_WANT_TIME32_SYSCALLS
+#define __ARCH_WANT_SYNC_FILE_RANGE2
 #include <asm-generic/unistd.h>
 
 #define __NR_set_thread_area	(__NR_arch_specific_syscall + 0)
--- linux-qcom-6.8.0.orig/arch/csky/kernel/probes/ftrace.c
+++ linux-qcom-6.8.0/arch/csky/kernel/probes/ftrace.c
@@ -12,6 +12,9 @@
 	struct kprobe_ctlblk *kcb;
 	struct pt_regs *regs;
 
+	if (unlikely(kprobe_ftrace_disabled))
+		return;
+
 	bit = ftrace_test_recursion_trylock(ip, parent_ip);
 	if (bit < 0)
 		return;
--- linux-qcom-6.8.0.orig/arch/csky/kernel/setup.c
+++ linux-qcom-6.8.0/arch/csky/kernel/setup.c
@@ -112,9 +112,9 @@
 	pre_trap_init();
 
 	if (dtb_start == NULL)
-		early_init_dt_scan(__dtb_start);
+		early_init_dt_scan(__dtb_start, __pa(dtb_start));
 	else
-		early_init_dt_scan(dtb_start);
+		early_init_dt_scan(dtb_start, __pa(dtb_start));
 
 	start_kernel();
 
--- linux-qcom-6.8.0.orig/arch/hexagon/Makefile
+++ linux-qcom-6.8.0/arch/hexagon/Makefile
@@ -32,3 +32,9 @@
 TIR_NAME := r19
 KBUILD_CFLAGS += -ffixed-$(TIR_NAME) -DTHREADINFO_REG=$(TIR_NAME) -D__linux__
 KBUILD_AFLAGS += -DTHREADINFO_REG=$(TIR_NAME)
+
+# Disable HexagonConstExtenders pass for LLVM versions prior to 19.1.0
+# https://github.com/llvm/llvm-project/issues/99714
+ifneq ($(call clang-min-version, 190100),y)
+KBUILD_CFLAGS += -mllvm -hexagon-cext=false
+endif
--- linux-qcom-6.8.0.orig/arch/hexagon/include/asm/cmpxchg.h
+++ linux-qcom-6.8.0/arch/hexagon/include/asm/cmpxchg.h
@@ -56,7 +56,7 @@
 	__typeof__(ptr) __ptr = (ptr);				\
 	__typeof__(*(ptr)) __old = (old);			\
 	__typeof__(*(ptr)) __new = (new);			\
-	__typeof__(*(ptr)) __oldval = 0;			\
+	__typeof__(*(ptr)) __oldval = (__typeof__(*(ptr))) 0;	\
 								\
 	asm volatile(						\
 		"1:	%0 = memw_locked(%1);\n"		\
--- linux-qcom-6.8.0.orig/arch/hexagon/include/asm/syscalls.h
+++ linux-qcom-6.8.0/arch/hexagon/include/asm/syscalls.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <asm-generic/syscalls.h>
+
+asmlinkage long sys_hexagon_fadvise64_64(int fd, int advice,
+	                                  u32 a2, u32 a3, u32 a4, u32 a5);
--- linux-qcom-6.8.0.orig/arch/hexagon/include/uapi/asm/unistd.h
+++ linux-qcom-6.8.0/arch/hexagon/include/uapi/asm/unistd.h
@@ -36,5 +36,6 @@
 #define __ARCH_WANT_SYS_VFORK
 #define __ARCH_WANT_SYS_FORK
 #define __ARCH_WANT_TIME32_SYSCALLS
+#define __ARCH_WANT_SYNC_FILE_RANGE2
 
 #include <asm-generic/unistd.h>
--- linux-qcom-6.8.0.orig/arch/hexagon/kernel/syscalltab.c
+++ linux-qcom-6.8.0/arch/hexagon/kernel/syscalltab.c
@@ -14,6 +14,13 @@
 #undef __SYSCALL
 #define __SYSCALL(nr, call) [nr] = (call),
 
+SYSCALL_DEFINE6(hexagon_fadvise64_64, int, fd, int, advice,
+		SC_ARG64(offset), SC_ARG64(len))
+{
+	return ksys_fadvise64_64(fd, SC_VAL64(loff_t, offset), SC_VAL64(loff_t, len), advice);
+}
+#define sys_fadvise64_64 sys_hexagon_fadvise64_64
+
 void *sys_call_table[__NR_syscalls] = {
 #include <asm/unistd.h>
 };
--- linux-qcom-6.8.0.orig/arch/hexagon/kernel/traps.c
+++ linux-qcom-6.8.0/arch/hexagon/kernel/traps.c
@@ -195,8 +195,10 @@
 	printk(KERN_EMERG "Oops: %s[#%d]:\n", str, ++die.counter);
 
 	if (notify_die(DIE_OOPS, str, regs, err, pt_cause(regs), SIGSEGV) ==
-	    NOTIFY_STOP)
+	    NOTIFY_STOP) {
+		spin_unlock_irq(&die.lock);
 		return 1;
+	}
 
 	print_modules();
 	show_regs(regs);
--- linux-qcom-6.8.0.orig/arch/hexagon/kernel/vmlinux.lds.S
+++ linux-qcom-6.8.0/arch/hexagon/kernel/vmlinux.lds.S
@@ -63,6 +63,7 @@
 	STABS_DEBUG
 	DWARF_DEBUG
 	ELF_DETAILS
+	.hexagon.attributes 0 : { *(.hexagon.attributes) }
 
 	DISCARDS
 }
--- linux-qcom-6.8.0.orig/arch/loongarch/boot/dts/loongson-2k0500-ref.dts
+++ linux-qcom-6.8.0/arch/loongarch/boot/dts/loongson-2k0500-ref.dts
@@ -44,14 +44,14 @@
 &gmac0 {
 	status = "okay";
 
-	phy-mode = "rgmii";
+	phy-mode = "rgmii-id";
 	bus_id = <0x0>;
 };
 
 &gmac1 {
 	status = "okay";
 
-	phy-mode = "rgmii";
+	phy-mode = "rgmii-id";
 	bus_id = <0x1>;
 };
 
--- linux-qcom-6.8.0.orig/arch/loongarch/boot/dts/loongson-2k1000-ref.dts
+++ linux-qcom-6.8.0/arch/loongarch/boot/dts/loongson-2k1000-ref.dts
@@ -43,7 +43,7 @@
 &gmac0 {
 	status = "okay";
 
-	phy-mode = "rgmii";
+	phy-mode = "rgmii-id";
 	phy-handle = <&phy0>;
 	mdio {
 		compatible = "snps,dwmac-mdio";
@@ -58,7 +58,7 @@
 &gmac1 {
 	status = "okay";
 
-	phy-mode = "rgmii";
+	phy-mode = "rgmii-id";
 	phy-handle = <&phy1>;
 	mdio {
 		compatible = "snps,dwmac-mdio";
--- linux-qcom-6.8.0.orig/arch/loongarch/configs/loongson3_defconfig
+++ linux-qcom-6.8.0/arch/loongarch/configs/loongson3_defconfig
@@ -93,7 +93,6 @@
 CONFIG_ZSWAP=y
 CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y
 CONFIG_ZBUD=y
-CONFIG_Z3FOLD=y
 CONFIG_ZSMALLOC=m
 # CONFIG_COMPAT_BRK is not set
 CONFIG_MEMORY_HOTPLUG=y
--- linux-qcom-6.8.0.orig/arch/loongarch/crypto/crc32-loongarch.c
+++ linux-qcom-6.8.0/arch/loongarch/crypto/crc32-loongarch.c
@@ -44,7 +44,6 @@
 
 		CRC32(crc, value, w);
 		p += sizeof(u32);
-		len -= sizeof(u32);
 	}
 
 	if (len & sizeof(u16)) {
@@ -80,7 +79,6 @@
 
 		CRC32C(crc, value, w);
 		p += sizeof(u32);
-		len -= sizeof(u32);
 	}
 
 	if (len & sizeof(u16)) {
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/Kbuild
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/Kbuild
@@ -4,6 +4,7 @@
 generic-y += parport.h
 generic-y += early_ioremap.h
 generic-y += qrwlock.h
+generic-y += qspinlock.h
 generic-y += rwsem.h
 generic-y += segment.h
 generic-y += user.h
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/bootinfo.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/bootinfo.h
@@ -26,6 +26,10 @@
 
 #define NR_WORDS DIV_ROUND_UP(NR_CPUS, BITS_PER_LONG)
 
+/*
+ * The "core" of cores_per_node and cores_per_package stands for a
+ * logical core, which means in a SMT system it stands for a thread.
+ */
 struct loongson_system_configuration {
 	int nr_cpus;
 	int nr_nodes;
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/hugetlb.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/hugetlb.h
@@ -29,12 +29,22 @@
 	return 0;
 }
 
+#define __HAVE_ARCH_HUGE_PTE_CLEAR
+static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr,
+				  pte_t *ptep, unsigned long sz)
+{
+	pte_t clear;
+
+	pte_val(clear) = (unsigned long)invalid_pte_table;
+	set_pte_at(mm, addr, ptep, clear);
+}
+
 #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR
 static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
 					    unsigned long addr, pte_t *ptep)
 {
 	pte_t clear;
-	pte_t pte = *ptep;
+	pte_t pte = ptep_get(ptep);
 
 	pte_val(clear) = (unsigned long)invalid_pte_table;
 	set_pte_at(mm, addr, ptep, clear);
@@ -65,7 +75,7 @@
 					     pte_t *ptep, pte_t pte,
 					     int dirty)
 {
-	int changed = !pte_same(*ptep, pte);
+	int changed = !pte_same(ptep_get(ptep), pte);
 
 	if (changed) {
 		set_pte_at(vma->vm_mm, addr, ptep, pte);
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/hw_breakpoint.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/hw_breakpoint.h
@@ -38,8 +38,8 @@
  * Limits.
  * Changing these will require modifications to the register accessors.
  */
-#define LOONGARCH_MAX_BRP		8
-#define LOONGARCH_MAX_WRP		8
+#define LOONGARCH_MAX_BRP		14
+#define LOONGARCH_MAX_WRP		14
 
 /* Virtual debug register bases. */
 #define CSR_CFG_ADDR	0
@@ -75,6 +75,8 @@
 #define CSR_MWPC_NUM		0x3f
 
 #define CTRL_PLV_ENABLE		0x1e
+#define CTRL_PLV0_ENABLE	0x02
+#define CTRL_PLV3_ENABLE	0x10
 
 #define MWPnCFG3_LoadEn		8
 #define MWPnCFG3_StoreEn	9
@@ -101,7 +103,7 @@
 struct perf_event_attr;
 
 extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
-				  int *gen_len, int *gen_type, int *offset);
+				  int *gen_len, int *gen_type);
 extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
 extern int hw_breakpoint_arch_parse(struct perf_event *bp,
 				    const struct perf_event_attr *attr,
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/hw_irq.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/hw_irq.h
@@ -9,6 +9,8 @@
 
 extern atomic_t irq_err_count;
 
+#define ARCH_IRQ_INIT_FLAGS	IRQ_NOPROBE
+
 /*
  * interrupt-retrigger: NOP for now. This may not be appropriate for all
  * machines, we'll see ...
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/inst.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/inst.h
@@ -678,7 +678,17 @@
 DEF_EMIT_REG2I16_FORMAT(bge, bge_op)
 DEF_EMIT_REG2I16_FORMAT(bltu, bltu_op)
 DEF_EMIT_REG2I16_FORMAT(bgeu, bgeu_op)
-DEF_EMIT_REG2I16_FORMAT(jirl, jirl_op)
+
+static inline void emit_jirl(union loongarch_instruction *insn,
+			     enum loongarch_gpr rd,
+			     enum loongarch_gpr rj,
+			     int offset)
+{
+	insn->reg2i16_format.opcode = jirl_op;
+	insn->reg2i16_format.immediate = offset;
+	insn->reg2i16_format.rd = rd;
+	insn->reg2i16_format.rj = rj;
+}
 
 #define DEF_EMIT_REG2BSTRD_FORMAT(NAME, OP)				\
 static inline void emit_##NAME(union loongarch_instruction *insn,	\
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/io.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/io.h
@@ -71,6 +71,8 @@
 #define memcpy_fromio(a, c, l) __memcpy_fromio((a), (c), (l))
 #define memcpy_toio(c, a, l)   __memcpy_toio((c), (a), (l))
 
+#define __io_aw() mmiowb()
+
 #include <asm-generic/io.h>
 
 #define ARCH_HAS_VALID_PHYS_ADDR_RANGE
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/kasan.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/kasan.h
@@ -16,7 +16,7 @@
 #define XRANGE_SHIFT (48)
 
 /* Valid address length */
-#define XRANGE_SHADOW_SHIFT	(PGDIR_SHIFT + PAGE_SHIFT - 3)
+#define XRANGE_SHADOW_SHIFT	min(cpu_vabits, VA_BITS)
 /* Used for taking out the valid address */
 #define XRANGE_SHADOW_MASK	GENMASK_ULL(XRANGE_SHADOW_SHIFT - 1, 0)
 /* One segment whole address space size */
@@ -25,6 +25,7 @@
 /* 64-bit segment value. */
 #define XKPRANGE_UC_SEG		(0x8000)
 #define XKPRANGE_CC_SEG		(0x9000)
+#define XKPRANGE_WC_SEG		(0xa000)
 #define XKVRANGE_VC_SEG		(0xffff)
 
 /* Cached */
@@ -41,20 +42,28 @@
 #define XKPRANGE_UC_SHADOW_SIZE		(XKPRANGE_UC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
 #define XKPRANGE_UC_SHADOW_END		(XKPRANGE_UC_KASAN_OFFSET + XKPRANGE_UC_SHADOW_SIZE)
 
+/* WriteCombine */
+#define XKPRANGE_WC_START		WRITECOMBINE_BASE
+#define XKPRANGE_WC_SIZE		XRANGE_SIZE
+#define XKPRANGE_WC_KASAN_OFFSET	XKPRANGE_UC_SHADOW_END
+#define XKPRANGE_WC_SHADOW_SIZE		(XKPRANGE_WC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
+#define XKPRANGE_WC_SHADOW_END		(XKPRANGE_WC_KASAN_OFFSET + XKPRANGE_WC_SHADOW_SIZE)
+
 /* VMALLOC (Cached or UnCached)  */
 #define XKVRANGE_VC_START		MODULES_VADDR
 #define XKVRANGE_VC_SIZE		round_up(KFENCE_AREA_END - MODULES_VADDR + 1, PGDIR_SIZE)
-#define XKVRANGE_VC_KASAN_OFFSET	XKPRANGE_UC_SHADOW_END
+#define XKVRANGE_VC_KASAN_OFFSET	XKPRANGE_WC_SHADOW_END
 #define XKVRANGE_VC_SHADOW_SIZE		(XKVRANGE_VC_SIZE >> KASAN_SHADOW_SCALE_SHIFT)
 #define XKVRANGE_VC_SHADOW_END		(XKVRANGE_VC_KASAN_OFFSET + XKVRANGE_VC_SHADOW_SIZE)
 
 /* KAsan shadow memory start right after vmalloc. */
 #define KASAN_SHADOW_START		round_up(KFENCE_AREA_END, PGDIR_SIZE)
 #define KASAN_SHADOW_SIZE		(XKVRANGE_VC_SHADOW_END - XKPRANGE_CC_KASAN_OFFSET)
-#define KASAN_SHADOW_END		round_up(KASAN_SHADOW_START + KASAN_SHADOW_SIZE, PGDIR_SIZE)
+#define KASAN_SHADOW_END		(round_up(KASAN_SHADOW_START + KASAN_SHADOW_SIZE, PGDIR_SIZE) - 1)
 
 #define XKPRANGE_CC_SHADOW_OFFSET	(KASAN_SHADOW_START + XKPRANGE_CC_KASAN_OFFSET)
 #define XKPRANGE_UC_SHADOW_OFFSET	(KASAN_SHADOW_START + XKPRANGE_UC_KASAN_OFFSET)
+#define XKPRANGE_WC_SHADOW_OFFSET	(KASAN_SHADOW_START + XKPRANGE_WC_KASAN_OFFSET)
 #define XKVRANGE_VC_SHADOW_OFFSET	(KASAN_SHADOW_START + XKVRANGE_VC_KASAN_OFFSET)
 
 extern bool kasan_early_stage;
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/kfence.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/kfence.h
@@ -43,13 +43,13 @@
 {
 	pte_t *pte = virt_to_kpte(addr);
 
-	if (WARN_ON(!pte) || pte_none(*pte))
+	if (WARN_ON(!pte) || pte_none(ptep_get(pte)))
 		return false;
 
 	if (protect)
-		set_pte(pte, __pte(pte_val(*pte) & ~(_PAGE_VALID | _PAGE_PRESENT)));
+		set_pte(pte, __pte(pte_val(ptep_get(pte)) & ~(_PAGE_VALID | _PAGE_PRESENT)));
 	else
-		set_pte(pte, __pte(pte_val(*pte) | (_PAGE_VALID | _PAGE_PRESENT)));
+		set_pte(pte, __pte(pte_val(ptep_get(pte)) | (_PAGE_VALID | _PAGE_PRESENT)));
 
 	preempt_disable();
 	local_flush_tlb_one(addr);
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/loongarch.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/loongarch.h
@@ -243,7 +243,7 @@
 #define  CSR_ESTAT_IS_WIDTH		14
 #define  CSR_ESTAT_IS			(_ULCAST_(0x3fff) << CSR_ESTAT_IS_SHIFT)
 
-#define LOONGARCH_CSR_ERA		0x6	/* ERA */
+#define LOONGARCH_CSR_ERA		0x6	/* Exception return address */
 
 #define LOONGARCH_CSR_BADV		0x7	/* Bad virtual address */
 
@@ -937,6 +937,36 @@
 #define LOONGARCH_CSR_DB7CTRL		0x34a	/* data breakpoint 7 control */
 #define LOONGARCH_CSR_DB7ASID		0x34b	/* data breakpoint 7 asid */
 
+#define LOONGARCH_CSR_DB8ADDR		0x350	/* data breakpoint 8 address */
+#define LOONGARCH_CSR_DB8MASK		0x351	/* data breakpoint 8 mask */
+#define LOONGARCH_CSR_DB8CTRL		0x352	/* data breakpoint 8 control */
+#define LOONGARCH_CSR_DB8ASID		0x353	/* data breakpoint 8 asid */
+
+#define LOONGARCH_CSR_DB9ADDR		0x358	/* data breakpoint 9 address */
+#define LOONGARCH_CSR_DB9MASK		0x359	/* data breakpoint 9 mask */
+#define LOONGARCH_CSR_DB9CTRL		0x35a	/* data breakpoint 9 control */
+#define LOONGARCH_CSR_DB9ASID		0x35b	/* data breakpoint 9 asid */
+
+#define LOONGARCH_CSR_DB10ADDR		0x360	/* data breakpoint 10 address */
+#define LOONGARCH_CSR_DB10MASK		0x361	/* data breakpoint 10 mask */
+#define LOONGARCH_CSR_DB10CTRL		0x362	/* data breakpoint 10 control */
+#define LOONGARCH_CSR_DB10ASID		0x363	/* data breakpoint 10 asid */
+
+#define LOONGARCH_CSR_DB11ADDR		0x368	/* data breakpoint 11 address */
+#define LOONGARCH_CSR_DB11MASK		0x369	/* data breakpoint 11 mask */
+#define LOONGARCH_CSR_DB11CTRL		0x36a	/* data breakpoint 11 control */
+#define LOONGARCH_CSR_DB11ASID		0x36b	/* data breakpoint 11 asid */
+
+#define LOONGARCH_CSR_DB12ADDR		0x370	/* data breakpoint 12 address */
+#define LOONGARCH_CSR_DB12MASK		0x371	/* data breakpoint 12 mask */
+#define LOONGARCH_CSR_DB12CTRL		0x372	/* data breakpoint 12 control */
+#define LOONGARCH_CSR_DB12ASID		0x373	/* data breakpoint 12 asid */
+
+#define LOONGARCH_CSR_DB13ADDR		0x378	/* data breakpoint 13 address */
+#define LOONGARCH_CSR_DB13MASK		0x379	/* data breakpoint 13 mask */
+#define LOONGARCH_CSR_DB13CTRL		0x37a	/* data breakpoint 13 control */
+#define LOONGARCH_CSR_DB13ASID		0x37b	/* data breakpoint 13 asid */
+
 #define LOONGARCH_CSR_FWPC		0x380	/* instruction breakpoint config */
 #define LOONGARCH_CSR_FWPS		0x381	/* instruction breakpoint status */
 
@@ -980,6 +1010,36 @@
 #define LOONGARCH_CSR_IB7CTRL		0x3ca	/* inst breakpoint 7 control */
 #define LOONGARCH_CSR_IB7ASID		0x3cb	/* inst breakpoint 7 asid */
 
+#define LOONGARCH_CSR_IB8ADDR		0x3d0	/* inst breakpoint 8 address */
+#define LOONGARCH_CSR_IB8MASK		0x3d1	/* inst breakpoint 8 mask */
+#define LOONGARCH_CSR_IB8CTRL		0x3d2	/* inst breakpoint 8 control */
+#define LOONGARCH_CSR_IB8ASID		0x3d3	/* inst breakpoint 8 asid */
+
+#define LOONGARCH_CSR_IB9ADDR		0x3d8	/* inst breakpoint 9 address */
+#define LOONGARCH_CSR_IB9MASK		0x3d9	/* inst breakpoint 9 mask */
+#define LOONGARCH_CSR_IB9CTRL		0x3da	/* inst breakpoint 9 control */
+#define LOONGARCH_CSR_IB9ASID		0x3db	/* inst breakpoint 9 asid */
+
+#define LOONGARCH_CSR_IB10ADDR		0x3e0	/* inst breakpoint 10 address */
+#define LOONGARCH_CSR_IB10MASK		0x3e1	/* inst breakpoint 10 mask */
+#define LOONGARCH_CSR_IB10CTRL		0x3e2	/* inst breakpoint 10 control */
+#define LOONGARCH_CSR_IB10ASID		0x3e3	/* inst breakpoint 10 asid */
+
+#define LOONGARCH_CSR_IB11ADDR		0x3e8	/* inst breakpoint 11 address */
+#define LOONGARCH_CSR_IB11MASK		0x3e9	/* inst breakpoint 11 mask */
+#define LOONGARCH_CSR_IB11CTRL		0x3ea	/* inst breakpoint 11 control */
+#define LOONGARCH_CSR_IB11ASID		0x3eb	/* inst breakpoint 11 asid */
+
+#define LOONGARCH_CSR_IB12ADDR		0x3f0	/* inst breakpoint 12 address */
+#define LOONGARCH_CSR_IB12MASK		0x3f1	/* inst breakpoint 12 mask */
+#define LOONGARCH_CSR_IB12CTRL		0x3f2	/* inst breakpoint 12 control */
+#define LOONGARCH_CSR_IB12ASID		0x3f3	/* inst breakpoint 12 asid */
+
+#define LOONGARCH_CSR_IB13ADDR		0x3f8	/* inst breakpoint 13 address */
+#define LOONGARCH_CSR_IB13MASK		0x3f9	/* inst breakpoint 13 mask */
+#define LOONGARCH_CSR_IB13CTRL		0x3fa	/* inst breakpoint 13 control */
+#define LOONGARCH_CSR_IB13ASID		0x3fb	/* inst breakpoint 13 asid */
+
 #define LOONGARCH_CSR_DEBUG		0x500	/* debug config */
 #define LOONGARCH_CSR_DERA		0x501	/* debug era */
 #define LOONGARCH_CSR_DESAVE		0x502	/* debug save */
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/numa.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/numa.h
@@ -56,6 +56,7 @@
 static inline void early_numa_add_cpu(int cpuid, s16 node)	{ }
 static inline void numa_add_cpu(unsigned int cpu)		{ }
 static inline void numa_remove_cpu(unsigned int cpu)		{ }
+static inline void set_cpuid_to_node(int cpuid, s16 node)	{ }
 
 static inline int early_cpu_to_node(int cpu)
 {
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/page.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/page.h
@@ -94,10 +94,7 @@
 extern int __virt_addr_valid(volatile void *kaddr);
 #define virt_addr_valid(kaddr)	__virt_addr_valid((volatile void *)(kaddr))
 
-#define VM_DATA_DEFAULT_FLAGS \
-	(VM_READ | VM_WRITE | \
-	 ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
-	 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+#define VM_DATA_DEFAULT_FLAGS	VM_DATA_FLAGS_TSK_EXEC
 
 #include <asm-generic/memory_model.h>
 #include <asm-generic/getorder.h>
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/percpu.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/percpu.h
@@ -29,7 +29,12 @@
 	__my_cpu_offset = off;
 	csr_write64(off, PERCPU_BASE_KS);
 }
-#define __my_cpu_offset __my_cpu_offset
+
+#define __my_cpu_offset					\
+({							\
+	__asm__ __volatile__("":"+r"(__my_cpu_offset));	\
+	__my_cpu_offset;				\
+})
 
 #define PERCPU_OP(op, asm_op, c_op)					\
 static __always_inline unsigned long __percpu_##op(void *ptr,		\
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/perf_event.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/perf_event.h
@@ -7,6 +7,13 @@
 #ifndef __LOONGARCH_PERF_EVENT_H__
 #define __LOONGARCH_PERF_EVENT_H__
 
+#include <asm/ptrace.h>
+
 #define perf_arch_bpf_user_pt_regs(regs) (struct user_pt_regs *)regs
 
+#define perf_arch_fetch_caller_regs(regs, __ip) { \
+	(regs)->csr_era = (__ip); \
+	(regs)->regs[3] = (unsigned long) __builtin_frame_address(0); \
+}
+
 #endif /* __LOONGARCH_PERF_EVENT_H__ */
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/pgtable.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/pgtable.h
@@ -106,6 +106,9 @@
 #define KFENCE_AREA_START	(VMEMMAP_END + 1)
 #define KFENCE_AREA_END		(KFENCE_AREA_START + KFENCE_AREA_SIZE - 1)
 
+#define ptep_get(ptep) READ_ONCE(*(ptep))
+#define pmdp_get(pmdp) READ_ONCE(*(pmdp))
+
 #define pte_ERROR(e) \
 	pr_err("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
 #ifndef __PAGETABLE_PMD_FOLDED
@@ -147,11 +150,6 @@
 	return p4d_val(p4d) != (unsigned long)invalid_pud_table;
 }
 
-static inline void p4d_clear(p4d_t *p4dp)
-{
-	p4d_val(*p4dp) = (unsigned long)invalid_pud_table;
-}
-
 static inline pud_t *p4d_pgtable(p4d_t p4d)
 {
 	return (pud_t *)p4d_val(p4d);
@@ -159,7 +157,12 @@
 
 static inline void set_p4d(p4d_t *p4d, p4d_t p4dval)
 {
-	*p4d = p4dval;
+	WRITE_ONCE(*p4d, p4dval);
+}
+
+static inline void p4d_clear(p4d_t *p4dp)
+{
+	set_p4d(p4dp, __p4d((unsigned long)invalid_pud_table));
 }
 
 #define p4d_phys(p4d)		PHYSADDR(p4d_val(p4d))
@@ -193,17 +196,20 @@
 	return pud_val(pud) != (unsigned long)invalid_pmd_table;
 }
 
-static inline void pud_clear(pud_t *pudp)
+static inline pmd_t *pud_pgtable(pud_t pud)
 {
-	pud_val(*pudp) = ((unsigned long)invalid_pmd_table);
+	return (pmd_t *)pud_val(pud);
 }
 
-static inline pmd_t *pud_pgtable(pud_t pud)
+static inline void set_pud(pud_t *pud, pud_t pudval)
 {
-	return (pmd_t *)pud_val(pud);
+	WRITE_ONCE(*pud, pudval);
 }
 
-#define set_pud(pudptr, pudval) do { *(pudptr) = (pudval); } while (0)
+static inline void pud_clear(pud_t *pudp)
+{
+	set_pud(pudp, __pud((unsigned long)invalid_pmd_table));
+}
 
 #define pud_phys(pud)		PHYSADDR(pud_val(pud))
 #define pud_page(pud)		(pfn_to_page(pud_phys(pud) >> PAGE_SHIFT))
@@ -231,12 +237,15 @@
 	return pmd_val(pmd) != (unsigned long)invalid_pte_table;
 }
 
-static inline void pmd_clear(pmd_t *pmdp)
+static inline void set_pmd(pmd_t *pmd, pmd_t pmdval)
 {
-	pmd_val(*pmdp) = ((unsigned long)invalid_pte_table);
+	WRITE_ONCE(*pmd, pmdval);
 }
 
-#define set_pmd(pmdptr, pmdval) do { *(pmdptr) = (pmdval); } while (0)
+static inline void pmd_clear(pmd_t *pmdp)
+{
+	set_pmd(pmdp, __pmd((unsigned long)invalid_pte_table));
+}
 
 #define pmd_phys(pmd)		PHYSADDR(pmd_val(pmd))
 
@@ -314,7 +323,8 @@
 
 static inline void set_pte(pte_t *ptep, pte_t pteval)
 {
-	*ptep = pteval;
+	WRITE_ONCE(*ptep, pteval);
+
 	if (pte_val(pteval) & _PAGE_GLOBAL) {
 		pte_t *buddy = ptep_buddy(ptep);
 		/*
@@ -341,8 +351,8 @@
 		: [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
 		: [global] "r" (page_global));
 #else /* !CONFIG_SMP */
-		if (pte_none(*buddy))
-			pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL;
+		if (pte_none(ptep_get(buddy)))
+			WRITE_ONCE(*buddy, __pte(pte_val(ptep_get(buddy)) | _PAGE_GLOBAL));
 #endif /* CONFIG_SMP */
 	}
 }
@@ -350,7 +360,7 @@
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
 	/* Preserve global status for the pair */
-	if (pte_val(*ptep_buddy(ptep)) & _PAGE_GLOBAL)
+	if (pte_val(ptep_get(ptep_buddy(ptep))) & _PAGE_GLOBAL)
 		set_pte(ptep, __pte(_PAGE_GLOBAL));
 	else
 		set_pte(ptep, __pte(0));
@@ -592,7 +602,7 @@
 static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
 					    unsigned long address, pmd_t *pmdp)
 {
-	pmd_t old = *pmdp;
+	pmd_t old = pmdp_get(pmdp);
 
 	pmd_clear(pmdp);
 
--- linux-qcom-6.8.0.orig/arch/loongarch/include/asm/stackframe.h
+++ linux-qcom-6.8.0/arch/loongarch/include/asm/stackframe.h
@@ -41,7 +41,7 @@
 	.macro JUMP_VIRT_ADDR temp1 temp2
 	li.d	\temp1, CACHE_BASE
 	pcaddi	\temp2, 0
-	or	\temp1, \temp1, \temp2
+	bstrins.d  \temp1, \temp2, (DMW_PABITS - 1), 0
 	jirl	zero, \temp1, 0xc
 	.endm
 
--- linux-qcom-6.8.0.orig/arch/loongarch/include/uapi/asm/ptrace.h
+++ linux-qcom-6.8.0/arch/loongarch/include/uapi/asm/ptrace.h
@@ -72,6 +72,16 @@
 	} dbg_regs[8];
 };
 
+struct user_watch_state_v2 {
+	uint64_t dbg_info;
+	struct {
+		uint64_t    addr;
+		uint64_t    mask;
+		uint32_t    ctrl;
+		uint32_t    pad;
+	} dbg_regs[14];
+};
+
 #define PTRACE_SYSEMU			0x1f
 #define PTRACE_SYSEMU_SINGLESTEP	0x20
 
--- linux-qcom-6.8.0.orig/arch/loongarch/include/uapi/asm/unistd.h
+++ linux-qcom-6.8.0/arch/loongarch/include/uapi/asm/unistd.h
@@ -1,4 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#define __ARCH_WANT_NEW_STAT
 #define __ARCH_WANT_SYS_CLONE
 #define __ARCH_WANT_SYS_CLONE3
 
--- linux-qcom-6.8.0.orig/arch/loongarch/kernel/efi.c
+++ linux-qcom-6.8.0/arch/loongarch/kernel/efi.c
@@ -66,6 +66,12 @@
 	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
 }
 
+bool efi_poweroff_required(void)
+{
+	return efi_enabled(EFI_RUNTIME_SERVICES) &&
+		(acpi_gbl_reduced_hardware || acpi_no_s5);
+}
+
 unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR;
 
 #if defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON)
@@ -89,7 +95,7 @@
 	memset(si, 0, sizeof(*si));
 	early_memunmap(si, sizeof(*si));
 
-	memblock_reserve(screen_info.lfb_base, screen_info.lfb_size);
+	memblock_reserve(__screen_info_lfb_base(&screen_info), screen_info.lfb_size);
 }
 
 void __init efi_init(void)
--- linux-qcom-6.8.0.orig/arch/loongarch/kernel/ftrace_dyn.c
+++ linux-qcom-6.8.0/arch/loongarch/kernel/ftrace_dyn.c
@@ -287,6 +287,9 @@
 	struct kprobe *p;
 	struct kprobe_ctlblk *kcb;
 
+	if (unlikely(kprobe_ftrace_disabled))
+		return;
+
 	bit = ftrace_test_recursion_trylock(ip, parent_ip);
 	if (bit < 0)
 		return;
--- linux-qcom-6.8.0.orig/arch/loongarch/kernel/head.S
+++ linux-qcom-6.8.0/arch/loongarch/kernel/head.S
@@ -22,7 +22,7 @@
 _head:
 	.word	MZ_MAGIC		/* "MZ", MS-DOS header */
 	.org	0x8
-	.dword	kernel_entry		/* Kernel entry point */
+	.dword	_kernel_entry		/* Kernel entry point (physical address) */
 	.dword	_kernel_asize		/* Kernel image effective size */
 	.quad	PHYS_LINK_KADDR		/* Kernel image load offset from start of RAM */
 	.org	0x38			/* 0x20 ~ 0x37 reserved */
--- linux-qcom-6.8.0.orig/arch/loongarch/kernel/hw_breakpoint.c
+++ linux-qcom-6.8.0/arch/loongarch/kernel/hw_breakpoint.c
@@ -51,7 +51,13 @@
 	READ_WB_REG_CASE(OFF, 4, REG, T, VAL);		\
 	READ_WB_REG_CASE(OFF, 5, REG, T, VAL);		\
 	READ_WB_REG_CASE(OFF, 6, REG, T, VAL);		\
-	READ_WB_REG_CASE(OFF, 7, REG, T, VAL);
+	READ_WB_REG_CASE(OFF, 7, REG, T, VAL);		\
+	READ_WB_REG_CASE(OFF, 8, REG, T, VAL);		\
+	READ_WB_REG_CASE(OFF, 9, REG, T, VAL);		\
+	READ_WB_REG_CASE(OFF, 10, REG, T, VAL);		\
+	READ_WB_REG_CASE(OFF, 11, REG, T, VAL);		\
+	READ_WB_REG_CASE(OFF, 12, REG, T, VAL);		\
+	READ_WB_REG_CASE(OFF, 13, REG, T, VAL);
 
 #define GEN_WRITE_WB_REG_CASES(OFF, REG, T, VAL)	\
 	WRITE_WB_REG_CASE(OFF, 0, REG, T, VAL);		\
@@ -61,7 +67,13 @@
 	WRITE_WB_REG_CASE(OFF, 4, REG, T, VAL);		\
 	WRITE_WB_REG_CASE(OFF, 5, REG, T, VAL);		\
 	WRITE_WB_REG_CASE(OFF, 6, REG, T, VAL);		\
-	WRITE_WB_REG_CASE(OFF, 7, REG, T, VAL);
+	WRITE_WB_REG_CASE(OFF, 7, REG, T, VAL);		\
+	WRITE_WB_REG_CASE(OFF, 8, REG, T, VAL);		\
+	WRITE_WB_REG_CASE(OFF, 9, REG, T, VAL);		\
+	WRITE_WB_REG_CASE(OFF, 10, REG, T, VAL);	\
+	WRITE_WB_REG_CASE(OFF, 11, REG, T, VAL);	\
+	WRITE_WB_REG_CASE(OFF, 12, REG, T, VAL);	\
+	WRITE_WB_REG_CASE(OFF, 13, REG, T, VAL);
 
 static u64 read_wb_reg(int reg, int n, int t)
 {
@@ -174,11 +186,21 @@
 static int hw_breakpoint_control(struct perf_event *bp,
 				 enum hw_breakpoint_ops ops)
 {
-	u32 ctrl;
+	u32 ctrl, privilege;
 	int i, max_slots, enable;
+	struct pt_regs *regs;
 	struct perf_event **slots;
 	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
 
+	if (arch_check_bp_in_kernelspace(info))
+		privilege = CTRL_PLV0_ENABLE;
+	else
+		privilege = CTRL_PLV3_ENABLE;
+
+	/*  Whether bp belongs to a task. */
+	if (bp->hw.target)
+		regs = task_pt_regs(bp->hw.target);
+
 	if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) {
 		/* Breakpoint */
 		slots = this_cpu_ptr(bp_on_reg);
@@ -197,31 +219,38 @@
 	switch (ops) {
 	case HW_BREAKPOINT_INSTALL:
 		/* Set the FWPnCFG/MWPnCFG 1~4 register. */
-		write_wb_reg(CSR_CFG_ADDR, i, 0, info->address);
-		write_wb_reg(CSR_CFG_ADDR, i, 1, info->address);
-		write_wb_reg(CSR_CFG_MASK, i, 0, info->mask);
-		write_wb_reg(CSR_CFG_MASK, i, 1, info->mask);
-		write_wb_reg(CSR_CFG_ASID, i, 0, 0);
-		write_wb_reg(CSR_CFG_ASID, i, 1, 0);
 		if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) {
-			write_wb_reg(CSR_CFG_CTRL, i, 0, CTRL_PLV_ENABLE);
+			write_wb_reg(CSR_CFG_ADDR, i, 0, info->address);
+			write_wb_reg(CSR_CFG_MASK, i, 0, info->mask);
+			write_wb_reg(CSR_CFG_ASID, i, 0, 0);
+			write_wb_reg(CSR_CFG_CTRL, i, 0, privilege);
 		} else {
+			write_wb_reg(CSR_CFG_ADDR, i, 1, info->address);
+			write_wb_reg(CSR_CFG_MASK, i, 1, info->mask);
+			write_wb_reg(CSR_CFG_ASID, i, 1, 0);
 			ctrl = encode_ctrl_reg(info->ctrl);
-			write_wb_reg(CSR_CFG_CTRL, i, 1, ctrl | CTRL_PLV_ENABLE);
+			write_wb_reg(CSR_CFG_CTRL, i, 1, ctrl | privilege);
 		}
 		enable = csr_read64(LOONGARCH_CSR_CRMD);
 		csr_write64(CSR_CRMD_WE | enable, LOONGARCH_CSR_CRMD);
+		if (bp->hw.target && test_tsk_thread_flag(bp->hw.target, TIF_LOAD_WATCH))
+			regs->csr_prmd |= CSR_PRMD_PWE;
 		break;
 	case HW_BREAKPOINT_UNINSTALL:
 		/* Reset the FWPnCFG/MWPnCFG 1~4 register. */
-		write_wb_reg(CSR_CFG_ADDR, i, 0, 0);
-		write_wb_reg(CSR_CFG_ADDR, i, 1, 0);
-		write_wb_reg(CSR_CFG_MASK, i, 0, 0);
-		write_wb_reg(CSR_CFG_MASK, i, 1, 0);
-		write_wb_reg(CSR_CFG_CTRL, i, 0, 0);
-		write_wb_reg(CSR_CFG_CTRL, i, 1, 0);
-		write_wb_reg(CSR_CFG_ASID, i, 0, 0);
-		write_wb_reg(CSR_CFG_ASID, i, 1, 0);
+		if (info->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) {
+			write_wb_reg(CSR_CFG_ADDR, i, 0, 0);
+			write_wb_reg(CSR_CFG_MASK, i, 0, 0);
+			write_wb_reg(CSR_CFG_CTRL, i, 0, 0);
+			write_wb_reg(CSR_CFG_ASID, i, 0, 0);
+		} else {
+			write_wb_reg(CSR_CFG_ADDR, i, 1, 0);
+			write_wb_reg(CSR_CFG_MASK, i, 1, 0);
+			write_wb_reg(CSR_CFG_CTRL, i, 1, 0);
+			write_wb_reg(CSR_CFG_ASID, i, 1, 0);
+		}
+		if (bp->hw.target)
+			regs->csr_prmd &= ~CSR_PRMD_PWE;
 		break;
 	}
 
@@ -283,7 +312,7 @@
  * to generic breakpoint descriptions.
  */
 int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
-			   int *gen_len, int *gen_type, int *offset)
+			   int *gen_len, int *gen_type)
 {
 	/* Type */
 	switch (ctrl.type) {
@@ -303,11 +332,6 @@
 		return -EINVAL;
 	}
 
-	if (!ctrl.len)
-		return -EINVAL;
-
-	*offset = __ffs(ctrl.len);
-
 	/* Len */
 	switch (ctrl.len) {
 	case LOONGARCH_BREAKPOINT_LEN_1:
@@ -386,21 +410,17 @@
 			     struct arch_hw_breakpoint *hw)
 {
 	int ret;
-	u64 alignment_mask, offset;
+	u64 alignment_mask;
 
 	/* Build the arch_hw_breakpoint. */
 	ret = arch_build_bp_info(bp, attr, hw);
 	if (ret)
 		return ret;
 
-	if (hw->ctrl.type != LOONGARCH_BREAKPOINT_EXECUTE)
-		alignment_mask = 0x7;
-	else
+	if (hw->ctrl.type == LOONGARCH_BREAKPOINT_EXECUTE) {
 		alignment_mask = 0x3;
-	offset = hw->address & alignment_mask;
-
-	hw->address &= ~alignment_mask;
-	hw->ctrl.len <<= offset;
+		hw->address &= ~alignment_mask;
+	}
 
 	return 0;
 }
@@ -471,12 +491,15 @@
 	slots = this_cpu_ptr(bp_on_reg);
 
 	for (i = 0; i < boot_cpu_data.watch_ireg_count; ++i) {
-		bp = slots[i];
-		if (bp == NULL)
-			continue;
-		perf_bp_event(bp, regs);
+		if ((csr_read32(LOONGARCH_CSR_FWPS) & (0x1 << i))) {
+			bp = slots[i];
+			if (bp == NULL)
+				continue;
+			perf_bp_event(bp, regs);
+			csr_write32(0x1 << i, LOONGARCH_CSR_FWPS);
+			update_bp_registers(regs, 0, 0);
+		}
 	}
-	update_bp_registers(regs, 0, 0);
 }
 NOKPROBE_SYMBOL(breakpoint_handler);
 
@@ -488,12 +511,15 @@
 	slots = this_cpu_ptr(wp_on_reg);
 
 	for (i = 0; i < boot_cpu_data.watch_dreg_count; ++i) {
-		wp = slots[i];
-		if (wp == NULL)
-			continue;
-		perf_bp_event(wp, regs);
+		if ((csr_read32(LOONGARCH_CSR_MWPS) & (0x1 << i))) {
+			wp = slots[i];
+			if (wp == NULL)
+				continue;
+			perf_bp_event(wp, regs);
+			csr_write32(0x1 << i, LOONGARCH_CSR_MWPS);
+			update_bp_registers(regs, 0, 1);
+		}
 	}
-	update_bp_registers(regs, 0, 1);
 }
 NOKPROBE_SYMBOL(watchpoint_handler);
 
--- linux-qcom-6.8.0.orig/arch/loongarch/kernel/inst.c
+++ linux-qcom-6.8.0/arch/loongarch/kernel/inst.c
@@ -332,7 +332,7 @@
 		return INSN_BREAK;
 	}
 
-	emit_jirl(&insn, rj, rd, imm >> 2);
+	emit_jirl(&insn, rd, rj, imm >> 2);
 
 	return insn.word;
 }
--- linux-qcom-6.8.0.orig/arch/loongarch/kernel/irq.c
+++ linux-qcom-6.8.0/arch/loongarch/kernel/irq.c
@@ -122,9 +122,6 @@
 		panic("IPI IRQ request failed\n");
 #endif
 
-	for (i = 0; i < NR_IRQS; i++)
-		irq_set_noprobe(i);
-
 	for_each_possible_cpu(i) {
 		page = alloc_pages_node(cpu_to_node(i), GFP_KERNEL, order);
 
--- linux-qcom-6.8.0.orig/arch/loongarch/kernel/perf_event.c
+++ linux-qcom-6.8.0/arch/loongarch/kernel/perf_event.c
@@ -884,4 +884,4 @@
 
 	return 0;
 }
-early_initcall(init_hw_perf_events);
+pure_initcall(init_hw_perf_events);
--- linux-qcom-6.8.0.orig/arch/loongarch/kernel/process.c
+++ linux-qcom-6.8.0/arch/loongarch/kernel/process.c
@@ -293,13 +293,15 @@
 {
 	unsigned long top = TASK_SIZE & PAGE_MASK;
 
-	/* Space for the VDSO & data page */
-	top -= PAGE_ALIGN(current->thread.vdso->size);
-	top -= VVAR_SIZE;
+	if (current->thread.vdso) {
+		/* Space for the VDSO & data page */
+		top -= PAGE_ALIGN(current->thread.vdso->size);
+		top -= VVAR_SIZE;
 
-	/* Space to randomize the VDSO base */
-	if (current->flags & PF_RANDOMIZE)
-		top -= VDSO_RANDOMIZE_SIZE;
+		/* Space to randomize the VDSO base */
+		if (current->flags & PF_RANDOMIZE)
+			top -= VDSO_RANDOMIZE_SIZE;
+	}
 
 	return top;
 }
--- linux-qcom-6.8.0.orig/arch/loongarch/kernel/ptrace.c
+++ linux-qcom-6.8.0/arch/loongarch/kernel/ptrace.c
@@ -494,28 +494,14 @@
 				     struct arch_hw_breakpoint_ctrl ctrl,
 				     struct perf_event_attr *attr)
 {
-	int err, len, type, offset;
+	int err, len, type;
 
-	err = arch_bp_generic_fields(ctrl, &len, &type, &offset);
+	err = arch_bp_generic_fields(ctrl, &len, &type);
 	if (err)
 		return err;
 
-	switch (note_type) {
-	case NT_LOONGARCH_HW_BREAK:
-		if ((type & HW_BREAKPOINT_X) != type)
-			return -EINVAL;
-		break;
-	case NT_LOONGARCH_HW_WATCH:
-		if ((type & HW_BREAKPOINT_RW) != type)
-			return -EINVAL;
-		break;
-	default:
-		return -EINVAL;
-	}
-
 	attr->bp_len	= len;
 	attr->bp_type	= type;
-	attr->bp_addr	+= offset;
 
 	return 0;
 }
@@ -603,16 +589,36 @@
 	struct perf_event *bp;
 	struct perf_event_attr attr;
 	struct arch_hw_breakpoint_ctrl ctrl;
+	struct thread_info *ti = task_thread_info(tsk);
 
 	bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx);
 	if (IS_ERR(bp))
 		return PTR_ERR(bp);
 
 	attr = bp->attr;
-	decode_ctrl_reg(uctrl, &ctrl);
-	err = ptrace_hbp_fill_attr_ctrl(note_type, ctrl, &attr);
-	if (err)
-		return err;
+
+	switch (note_type) {
+	case NT_LOONGARCH_HW_BREAK:
+		ctrl.type = LOONGARCH_BREAKPOINT_EXECUTE;
+		ctrl.len = LOONGARCH_BREAKPOINT_LEN_4;
+		break;
+	case NT_LOONGARCH_HW_WATCH:
+		decode_ctrl_reg(uctrl, &ctrl);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (uctrl & CTRL_PLV_ENABLE) {
+		err = ptrace_hbp_fill_attr_ctrl(note_type, ctrl, &attr);
+		if (err)
+			return err;
+		attr.disabled = 0;
+		set_ti_thread_flag(ti, TIF_LOAD_WATCH);
+	} else {
+		attr.disabled = 1;
+		clear_ti_thread_flag(ti, TIF_LOAD_WATCH);
+	}
 
 	return modify_user_hw_breakpoint(bp, &attr);
 }
@@ -643,6 +649,10 @@
 	struct perf_event *bp;
 	struct perf_event_attr attr;
 
+	/* Kernel-space address cannot be monitored by user-space */
+	if ((unsigned long)addr >= XKPRANGE)
+		return -EINVAL;
+
 	bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx);
 	if (IS_ERR(bp))
 		return PTR_ERR(bp);
@@ -710,7 +720,7 @@
 	unsigned int note_type = regset->core_note_type;
 
 	/* Resource info */
-	offset = offsetof(struct user_watch_state, dbg_regs);
+	offset = offsetof(struct user_watch_state_v2, dbg_regs);
 	user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 0, offset);
 
 	/* (address, mask, ctrl) registers */
@@ -910,7 +920,7 @@
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 	[REGSET_HW_BREAK] = {
 		.core_note_type = NT_LOONGARCH_HW_BREAK,
-		.n = sizeof(struct user_watch_state) / sizeof(u32),
+		.n = sizeof(struct user_watch_state_v2) / sizeof(u32),
 		.size = sizeof(u32),
 		.align = sizeof(u32),
 		.regset_get = hw_break_get,
@@ -918,7 +928,7 @@
 	},
 	[REGSET_HW_WATCH] = {
 		.core_note_type = NT_LOONGARCH_HW_WATCH,
-		.n = sizeof(struct user_watch_state) / sizeof(u32),
+		.n = sizeof(struct user_watch_state_v2) / sizeof(u32),
 		.size = sizeof(u32),
 		.align = sizeof(u32),
 		.regset_get = hw_break_get,
--- linux-qcom-6.8.0.orig/arch/loongarch/kernel/relocate.c
+++ linux-qcom-6.8.0/arch/loongarch/kernel/relocate.c
@@ -13,6 +13,7 @@
 #include <asm/bootinfo.h>
 #include <asm/early_ioremap.h>
 #include <asm/inst.h>
+#include <asm/io.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 
@@ -170,7 +171,7 @@
 	unsigned long kernel_length;
 	unsigned long random_offset = 0;
 	void *location_new = _text; /* Default to original kernel start */
-	char *cmdline = early_ioremap(fw_arg1, COMMAND_LINE_SIZE); /* Boot command line is passed in fw_arg1 */
+	char *cmdline = early_memremap_ro(fw_arg1, COMMAND_LINE_SIZE); /* Boot command line is passed in fw_arg1 */
 
 	strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE);
 
@@ -182,6 +183,7 @@
 		random_offset = (unsigned long)location_new - (unsigned long)(_text);
 #endif
 	reloc_offset = (unsigned long)_text - VMLINUX_LOAD_ADDRESS;
+	early_memunmap(cmdline, COMMAND_LINE_SIZE);
 
 	if (random_offset) {
 		kernel_length = (long)(_end) - (long)(_text);
--- linux-qcom-6.8.0.orig/arch/loongarch/kernel/setup.c
+++ linux-qcom-6.8.0/arch/loongarch/kernel/setup.c
@@ -54,6 +54,7 @@
 #define SMBIOS_FREQHIGH_OFFSET		0x17
 #define SMBIOS_FREQLOW_MASK		0xFF
 #define SMBIOS_CORE_PACKAGE_OFFSET	0x23
+#define SMBIOS_THREAD_PACKAGE_OFFSET	0x25
 #define LOONGSON_EFI_ENABLE		(1 << 3)
 
 unsigned long fw_arg0, fw_arg1, fw_arg2;
@@ -124,7 +125,7 @@
 	cpu_clock_freq = freq_temp * 1000000;
 
 	loongson_sysconf.cpuname = (void *)dmi_string_parse(dm, dmi_data[16]);
-	loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_CORE_PACKAGE_OFFSET);
+	loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_THREAD_PACKAGE_OFFSET);
 
 	pr_info("CpuClock = %llu\n", cpu_clock_freq);
 }
@@ -281,7 +282,7 @@
 		return;
 
 	/* Prefer to use built-in dtb, checking its legality first. */
-	if (!fdt_check_header(__dtb_start))
+	if (IS_ENABLED(CONFIG_BUILTIN_DTB) && !fdt_check_header(__dtb_start))
 		fdt_pointer = __dtb_start;
 	else
 		fdt_pointer = efi_fdt_pointer(); /* Fallback to firmware dtb */
@@ -289,7 +290,7 @@
 	if (!fdt_pointer || fdt_check_header(fdt_pointer))
 		return;
 
-	early_init_dt_scan(fdt_pointer);
+	early_init_dt_scan(fdt_pointer, __pa(fdt_pointer));
 	early_init_fdt_reserve_self();
 
 	max_low_pfn = PFN_PHYS(memblock_end_of_DRAM());
--- linux-qcom-6.8.0.orig/arch/loongarch/kernel/smp.c
+++ linux-qcom-6.8.0/arch/loongarch/kernel/smp.c
@@ -262,7 +262,6 @@
 
 		if (cpuid == loongson_sysconf.boot_cpu_id) {
 			cpu = 0;
-			numa_add_cpu(cpu);
 		} else {
 			cpu = cpumask_next_zero(-1, cpu_present_mask);
 		}
@@ -272,6 +271,9 @@
 		set_cpu_present(cpu, true);
 		__cpu_number_map[cpuid] = cpu;
 		__cpu_logical_map[cpu] = cpuid;
+
+		early_numa_add_cpu(cpuid, 0);
+		set_cpuid_to_node(cpuid, 0);
 	}
 
 	loongson_sysconf.nr_cpus = num_processors;
@@ -456,6 +458,7 @@
 	set_cpu_possible(0, true);
 	set_cpu_online(0, true);
 	set_my_cpu_offset(per_cpu_offset(0));
+	numa_add_cpu(0);
 
 	rr_node = first_node(node_online_map);
 	for_each_possible_cpu(cpu) {
--- linux-qcom-6.8.0.orig/arch/loongarch/kernel/traps.c
+++ linux-qcom-6.8.0/arch/loongarch/kernel/traps.c
@@ -529,6 +529,9 @@
 #else
 	unsigned int *pc;
 
+	if (regs->csr_prmd & CSR_PRMD_PIE)
+		local_irq_enable();
+
 	perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->csr_badvaddr);
 
 	/*
@@ -553,6 +556,8 @@
 	die_if_kernel("Kernel ale access", regs);
 	force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr);
 out:
+	if (regs->csr_prmd & CSR_PRMD_PIE)
+		local_irq_disable();
 #endif
 	irqentry_exit(regs, state);
 }
--- linux-qcom-6.8.0.orig/arch/loongarch/kernel/vmlinux.lds.S
+++ linux-qcom-6.8.0/arch/loongarch/kernel/vmlinux.lds.S
@@ -5,6 +5,7 @@
 
 #define PAGE_SIZE _PAGE_SIZE
 #define RO_EXCEPTION_TABLE_ALIGN	4
+#define PHYSADDR_MASK			0xffffffffffff /* 48-bit */
 
 /*
  * Put .bss..swapper_pg_dir as the first thing in .bss. This will
@@ -139,10 +140,11 @@
 
 #ifdef CONFIG_EFI_STUB
 	/* header symbols */
-	_kernel_asize = _end - _text;
-	_kernel_fsize = _edata - _text;
-	_kernel_vsize = _end - __initdata_begin;
-	_kernel_rsize = _edata - __initdata_begin;
+	_kernel_entry = ABSOLUTE(kernel_entry & PHYSADDR_MASK);
+	_kernel_asize = ABSOLUTE(_end - _text);
+	_kernel_fsize = ABSOLUTE(_edata - _text);
+	_kernel_vsize = ABSOLUTE(_end - __initdata_begin);
+	_kernel_rsize = ABSOLUTE(_edata - __initdata_begin);
 #endif
 
 	.gptab.sdata : {
--- linux-qcom-6.8.0.orig/arch/loongarch/kvm/mmu.c
+++ linux-qcom-6.8.0/arch/loongarch/kvm/mmu.c
@@ -727,19 +727,19 @@
 	 * value) and then p*d_offset() walks into the target huge page instead
 	 * of the old page table (sees the new value).
 	 */
-	pgd = READ_ONCE(*pgd_offset(kvm->mm, hva));
+	pgd = pgdp_get(pgd_offset(kvm->mm, hva));
 	if (pgd_none(pgd))
 		goto out;
 
-	p4d = READ_ONCE(*p4d_offset(&pgd, hva));
+	p4d = p4dp_get(p4d_offset(&pgd, hva));
 	if (p4d_none(p4d) || !p4d_present(p4d))
 		goto out;
 
-	pud = READ_ONCE(*pud_offset(&p4d, hva));
+	pud = pudp_get(pud_offset(&p4d, hva));
 	if (pud_none(pud) || !pud_present(pud))
 		goto out;
 
-	pmd = READ_ONCE(*pmd_offset(&pud, hva));
+	pmd = pmdp_get(pmd_offset(&pud, hva));
 	if (pmd_none(pmd) || !pmd_present(pmd))
 		goto out;
 
--- linux-qcom-6.8.0.orig/arch/loongarch/kvm/timer.c
+++ linux-qcom-6.8.0/arch/loongarch/kvm/timer.c
@@ -174,10 +174,11 @@
 		vcpu->arch.expire = expire;
 
 		/*
-		 * HRTIMER_MODE_PINNED is suggested since vcpu may run in
-		 * the same physical cpu in next time
+		 * HRTIMER_MODE_PINNED_HARD is suggested since vcpu may run in
+		 * the same physical cpu in next time, and the timer should run
+		 * in hardirq context even in the PREEMPT_RT case.
 		 */
-		hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED);
+		hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED_HARD);
 	} else if (vcpu->stat.generic.blocking) {
 		/*
 		 * Inject timer interrupt so that halt polling can dectect and exit.
--- linux-qcom-6.8.0.orig/arch/loongarch/kvm/vcpu.c
+++ linux-qcom-6.8.0/arch/loongarch/kvm/vcpu.c
@@ -61,7 +61,7 @@
  */
 static int kvm_enter_guest_check(struct kvm_vcpu *vcpu)
 {
-	int ret;
+	int idx, ret;
 
 	/*
 	 * Check conditions before entering the guest
@@ -70,7 +70,9 @@
 	if (ret < 0)
 		return ret;
 
+	idx = srcu_read_lock(&vcpu->kvm->srcu);
 	ret = kvm_check_requests(vcpu);
+	srcu_read_unlock(&vcpu->kvm->srcu, idx);
 
 	return ret;
 }
@@ -875,7 +877,7 @@
 
 	vcpu->arch.vpid = 0;
 
-	hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED);
+	hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED_HARD);
 	vcpu->arch.swtimer.function = kvm_swtimer_wakeup;
 
 	vcpu->arch.handle_exit = kvm_handle_exit;
--- linux-qcom-6.8.0.orig/arch/loongarch/mm/fault.c
+++ linux-qcom-6.8.0/arch/loongarch/mm/fault.c
@@ -202,10 +202,10 @@
 		if (!(vma->vm_flags & VM_WRITE))
 			goto bad_area;
 	} else {
-		if (!(vma->vm_flags & VM_READ) && address != exception_era(regs))
-			goto bad_area;
 		if (!(vma->vm_flags & VM_EXEC) && address == exception_era(regs))
 			goto bad_area;
+		if (!(vma->vm_flags & (VM_READ | VM_WRITE)) && address != exception_era(regs))
+			goto bad_area;
 	}
 
 	/*
--- linux-qcom-6.8.0.orig/arch/loongarch/mm/hugetlbpage.c
+++ linux-qcom-6.8.0/arch/loongarch/mm/hugetlbpage.c
@@ -39,11 +39,11 @@
 	pmd_t *pmd = NULL;
 
 	pgd = pgd_offset(mm, addr);
-	if (pgd_present(*pgd)) {
+	if (pgd_present(pgdp_get(pgd))) {
 		p4d = p4d_offset(pgd, addr);
-		if (p4d_present(*p4d)) {
+		if (p4d_present(p4dp_get(p4d))) {
 			pud = pud_offset(p4d, addr);
-			if (pud_present(*pud))
+			if (pud_present(pudp_get(pud)))
 				pmd = pmd_offset(pud, addr);
 		}
 	}
--- linux-qcom-6.8.0.orig/arch/loongarch/mm/init.c
+++ linux-qcom-6.8.0/arch/loongarch/mm/init.c
@@ -140,7 +140,7 @@
 int __meminit vmemmap_check_pmd(pmd_t *pmd, int node,
 				unsigned long addr, unsigned long next)
 {
-	int huge = pmd_val(*pmd) & _PAGE_HUGE;
+	int huge = pmd_val(pmdp_get(pmd)) & _PAGE_HUGE;
 
 	if (huge)
 		vmemmap_verify((pte_t *)pmd, node, addr, next);
@@ -172,7 +172,7 @@
 	pud_t *pud;
 	pmd_t *pmd;
 
-	if (p4d_none(*p4d)) {
+	if (p4d_none(p4dp_get(p4d))) {
 		pud = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 		if (!pud)
 			panic("%s: Failed to allocate memory\n", __func__);
@@ -183,7 +183,7 @@
 	}
 
 	pud = pud_offset(p4d, addr);
-	if (pud_none(*pud)) {
+	if (pud_none(pudp_get(pud))) {
 		pmd = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
 		if (!pmd)
 			panic("%s: Failed to allocate memory\n", __func__);
@@ -194,7 +194,7 @@
 	}
 
 	pmd = pmd_offset(pud, addr);
-	if (!pmd_present(*pmd)) {
+	if (!pmd_present(pmdp_get(pmd))) {
 		pte_t *pte;
 
 		pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
@@ -215,7 +215,7 @@
 	BUG_ON(idx <= FIX_HOLE || idx >= __end_of_fixed_addresses);
 
 	ptep = populate_kernel_pte(addr);
-	if (!pte_none(*ptep)) {
+	if (!pte_none(ptep_get(ptep))) {
 		pte_ERROR(*ptep);
 		return;
 	}
--- linux-qcom-6.8.0.orig/arch/loongarch/mm/kasan_init.c
+++ linux-qcom-6.8.0/arch/loongarch/mm/kasan_init.c
@@ -13,6 +13,13 @@
 
 static pgd_t kasan_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE);
 
+#ifdef __PAGETABLE_P4D_FOLDED
+#define __pgd_none(early, pgd) (0)
+#else
+#define __pgd_none(early, pgd) (early ? (pgd_val(pgd) == 0) : \
+(__pa(pgd_val(pgd)) == (unsigned long)__pa(kasan_early_shadow_p4d)))
+#endif
+
 #ifdef __PAGETABLE_PUD_FOLDED
 #define __p4d_none(early, p4d) (0)
 #else
@@ -55,6 +62,9 @@
 		case XKPRANGE_UC_SEG:
 			offset = XKPRANGE_UC_SHADOW_OFFSET;
 			break;
+		case XKPRANGE_WC_SEG:
+			offset = XKPRANGE_WC_SHADOW_OFFSET;
+			break;
 		case XKVRANGE_VC_SEG:
 			offset = XKVRANGE_VC_SHADOW_OFFSET;
 			break;
@@ -79,6 +89,8 @@
 
 	if (addr >= XKVRANGE_VC_SHADOW_OFFSET)
 		return (void *)(((addr - XKVRANGE_VC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKVRANGE_VC_START);
+	else if (addr >= XKPRANGE_WC_SHADOW_OFFSET)
+		return (void *)(((addr - XKPRANGE_WC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_WC_START);
 	else if (addr >= XKPRANGE_UC_SHADOW_OFFSET)
 		return (void *)(((addr - XKPRANGE_UC_SHADOW_OFFSET) << KASAN_SHADOW_SCALE_SHIFT) + XKPRANGE_UC_START);
 	else if (addr >= XKPRANGE_CC_SHADOW_OFFSET)
@@ -105,7 +117,7 @@
 
 static pte_t *__init kasan_pte_offset(pmd_t *pmdp, unsigned long addr, int node, bool early)
 {
-	if (__pmd_none(early, READ_ONCE(*pmdp))) {
+	if (__pmd_none(early, pmdp_get(pmdp))) {
 		phys_addr_t pte_phys = early ?
 				__pa_symbol(kasan_early_shadow_pte) : kasan_alloc_zeroed_page(node);
 		if (!early)
@@ -118,7 +130,7 @@
 
 static pmd_t *__init kasan_pmd_offset(pud_t *pudp, unsigned long addr, int node, bool early)
 {
-	if (__pud_none(early, READ_ONCE(*pudp))) {
+	if (__pud_none(early, pudp_get(pudp))) {
 		phys_addr_t pmd_phys = early ?
 				__pa_symbol(kasan_early_shadow_pmd) : kasan_alloc_zeroed_page(node);
 		if (!early)
@@ -131,7 +143,7 @@
 
 static pud_t *__init kasan_pud_offset(p4d_t *p4dp, unsigned long addr, int node, bool early)
 {
-	if (__p4d_none(early, READ_ONCE(*p4dp))) {
+	if (__p4d_none(early, p4dp_get(p4dp))) {
 		phys_addr_t pud_phys = early ?
 			__pa_symbol(kasan_early_shadow_pud) : kasan_alloc_zeroed_page(node);
 		if (!early)
@@ -142,6 +154,19 @@
 	return pud_offset(p4dp, addr);
 }
 
+static p4d_t *__init kasan_p4d_offset(pgd_t *pgdp, unsigned long addr, int node, bool early)
+{
+	if (__pgd_none(early, pgdp_get(pgdp))) {
+		phys_addr_t p4d_phys = early ?
+			__pa_symbol(kasan_early_shadow_p4d) : kasan_alloc_zeroed_page(node);
+		if (!early)
+			memcpy(__va(p4d_phys), kasan_early_shadow_p4d, sizeof(kasan_early_shadow_p4d));
+		pgd_populate(&init_mm, pgdp, (p4d_t *)__va(p4d_phys));
+	}
+
+	return p4d_offset(pgdp, addr);
+}
+
 static void __init kasan_pte_populate(pmd_t *pmdp, unsigned long addr,
 				      unsigned long end, int node, bool early)
 {
@@ -154,7 +179,7 @@
 					      : kasan_alloc_zeroed_page(node);
 		next = addr + PAGE_SIZE;
 		set_pte(ptep, pfn_pte(__phys_to_pfn(page_phys), PAGE_KERNEL));
-	} while (ptep++, addr = next, addr != end && __pte_none(early, READ_ONCE(*ptep)));
+	} while (ptep++, addr = next, addr != end && __pte_none(early, ptep_get(ptep)));
 }
 
 static void __init kasan_pmd_populate(pud_t *pudp, unsigned long addr,
@@ -166,7 +191,7 @@
 	do {
 		next = pmd_addr_end(addr, end);
 		kasan_pte_populate(pmdp, addr, next, node, early);
-	} while (pmdp++, addr = next, addr != end && __pmd_none(early, READ_ONCE(*pmdp)));
+	} while (pmdp++, addr = next, addr != end && __pmd_none(early, pmdp_get(pmdp)));
 }
 
 static void __init kasan_pud_populate(p4d_t *p4dp, unsigned long addr,
@@ -178,19 +203,19 @@
 	do {
 		next = pud_addr_end(addr, end);
 		kasan_pmd_populate(pudp, addr, next, node, early);
-	} while (pudp++, addr = next, addr != end);
+	} while (pudp++, addr = next, addr != end && __pud_none(early, READ_ONCE(*pudp)));
 }
 
 static void __init kasan_p4d_populate(pgd_t *pgdp, unsigned long addr,
 					    unsigned long end, int node, bool early)
 {
 	unsigned long next;
-	p4d_t *p4dp = p4d_offset(pgdp, addr);
+	p4d_t *p4dp = kasan_p4d_offset(pgdp, addr, node, early);
 
 	do {
 		next = p4d_addr_end(addr, end);
 		kasan_pud_populate(p4dp, addr, next, node, early);
-	} while (p4dp++, addr = next, addr != end);
+	} while (p4dp++, addr = next, addr != end && __p4d_none(early, READ_ONCE(*p4dp)));
 }
 
 static void __init kasan_pgd_populate(unsigned long addr, unsigned long end,
@@ -218,7 +243,7 @@
 asmlinkage void __init kasan_early_init(void)
 {
 	BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE));
-	BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));
+	BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END + 1, PGDIR_SIZE));
 }
 
 static inline void kasan_set_pgd(pgd_t *pgdp, pgd_t pgdval)
@@ -233,7 +258,7 @@
 	 * swapper_pg_dir. pgd_clear() can't be used
 	 * here because it's nop on 2,3-level pagetable setups
 	 */
-	for (; start < end; start += PGDIR_SIZE)
+	for (; start < end; start = pgd_addr_end(start, end))
 		kasan_set_pgd((pgd_t *)pgd_offset_k(start), __pgd(0));
 }
 
@@ -243,6 +268,17 @@
 	phys_addr_t pa_start, pa_end;
 
 	/*
+	 * If PGDIR_SIZE is too large for cpu_vabits, KASAN_SHADOW_END will
+	 * overflow UINTPTR_MAX and then looks like a user space address.
+	 * For example, PGDIR_SIZE of CONFIG_4KB_4LEVEL is 2^39, which is too
+	 * large for Loongson-2K series whose cpu_vabits = 39.
+	 */
+	if (KASAN_SHADOW_END < vm_map_base) {
+		pr_warn("PGDIR_SIZE too large for cpu_vabits, KernelAddressSanitizer disabled.\n");
+		return;
+	}
+
+	/*
 	 * PGD was populated as invalid_pmd_table or invalid_pud_table
 	 * in pagetable_init() which depends on how many levels of page
 	 * table you are using, but we had to clean the gpd of kasan
--- linux-qcom-6.8.0.orig/arch/loongarch/mm/pgtable.c
+++ linux-qcom-6.8.0/arch/loongarch/mm/pgtable.c
@@ -128,7 +128,7 @@
 void set_pmd_at(struct mm_struct *mm, unsigned long addr,
 		pmd_t *pmdp, pmd_t pmd)
 {
-	*pmdp = pmd;
+	WRITE_ONCE(*pmdp, pmd);
 	flush_tlb_all();
 }
 
--- linux-qcom-6.8.0.orig/arch/loongarch/mm/tlb.c
+++ linux-qcom-6.8.0/arch/loongarch/mm/tlb.c
@@ -292,7 +292,7 @@
 		/* Avoid lockdep warning */
 		rcutree_report_cpu_starting(cpu);
 
-#ifdef CONFIG_NUMA
+#if defined(CONFIG_NUMA) && !defined(CONFIG_PREEMPT_RT)
 		vec_sz = sizeof(exception_handlers);
 
 		if (pcpu_handlers[cpu])
--- linux-qcom-6.8.0.orig/arch/loongarch/net/bpf_jit.c
+++ linux-qcom-6.8.0/arch/loongarch/net/bpf_jit.c
@@ -179,15 +179,15 @@
 
 	if (!is_tail_call) {
 		/* Set return value */
-		move_reg(ctx, LOONGARCH_GPR_A0, regmap[BPF_REG_0]);
+		emit_insn(ctx, addiw, LOONGARCH_GPR_A0, regmap[BPF_REG_0], 0);
 		/* Return to the caller */
-		emit_insn(ctx, jirl, LOONGARCH_GPR_RA, LOONGARCH_GPR_ZERO, 0);
+		emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_RA, 0);
 	} else {
 		/*
 		 * Call the next bpf prog and skip the first instruction
 		 * of TCC initialization.
 		 */
-		emit_insn(ctx, jirl, LOONGARCH_GPR_T3, LOONGARCH_GPR_ZERO, 1);
+		emit_insn(ctx, jirl, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_T3, 1);
 	}
 }
 
@@ -904,7 +904,7 @@
 			return ret;
 
 		move_addr(ctx, t1, func_addr);
-		emit_insn(ctx, jirl, t1, LOONGARCH_GPR_RA, 0);
+		emit_insn(ctx, jirl, LOONGARCH_GPR_RA, t1, 0);
 		move_reg(ctx, regmap[BPF_REG_0], LOONGARCH_GPR_A0);
 		break;
 
@@ -1294,16 +1294,19 @@
 	flush_icache_range((unsigned long)header, (unsigned long)(ctx.image + ctx.idx));
 
 	if (!prog->is_func || extra_pass) {
+		int err;
+
 		if (extra_pass && ctx.idx != jit_data->ctx.idx) {
 			pr_err_once("multi-func JIT bug %d != %d\n",
 				    ctx.idx, jit_data->ctx.idx);
-			bpf_jit_binary_free(header);
-			prog->bpf_func = NULL;
-			prog->jited = 0;
-			prog->jited_len = 0;
-			goto out_offset;
+			goto out_free;
+		}
+		err = bpf_jit_binary_lock_ro(header);
+		if (err) {
+			pr_err_once("bpf_jit_binary_lock_ro() returned %d\n",
+				    err);
+			goto out_free;
 		}
-		bpf_jit_binary_lock_ro(header);
 	} else {
 		jit_data->ctx = ctx;
 		jit_data->image = image_ptr;
@@ -1334,6 +1337,13 @@
 	out_offset = -1;
 
 	return prog;
+
+out_free:
+	bpf_jit_binary_free(header);
+	prog->bpf_func = NULL;
+	prog->jited = 0;
+	prog->jited_len = 0;
+	goto out_offset;
 }
 
 /* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */
--- linux-qcom-6.8.0.orig/arch/loongarch/pci/acpi.c
+++ linux-qcom-6.8.0/arch/loongarch/pci/acpi.c
@@ -225,6 +225,7 @@
 	if (bus) {
 		memcpy(bus->sysdata, info->cfg, sizeof(struct pci_config_window));
 		kfree(info);
+		kfree(root_ops);
 	} else {
 		struct pci_bus *child;
 
--- linux-qcom-6.8.0.orig/arch/loongarch/power/platform.c
+++ linux-qcom-6.8.0/arch/loongarch/power/platform.c
@@ -17,7 +17,7 @@
 	if (acpi_gbl_reduced_hardware)
 	       return;
 
-	acpi_enable_all_wakeup_gpes();
+	acpi_hw_enable_all_wakeup_gpes();
 }
 
 void enable_pci_wakeup(void)
--- linux-qcom-6.8.0.orig/arch/loongarch/vdso/Makefile
+++ linux-qcom-6.8.0/arch/loongarch/vdso/Makefile
@@ -22,7 +22,7 @@
 cflags-vdso := $(ccflags-vdso) \
 	-isystem $(shell $(CC) -print-file-name=include) \
 	$(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
-	-O2 -g -fno-strict-aliasing -fno-common -fno-builtin \
+	-std=gnu11 -O2 -g -fno-strict-aliasing -fno-common -fno-builtin \
 	-fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \
 	$(call cc-option, -fno-asynchronous-unwind-tables) \
 	$(call cc-option, -fno-stack-protector)
--- linux-qcom-6.8.0.orig/arch/m68k/amiga/config.c
+++ linux-qcom-6.8.0/arch/m68k/amiga/config.c
@@ -180,6 +180,15 @@
 			dev->slotsize = be16_to_cpu(cd->cd_SlotSize);
 			dev->boardaddr = be32_to_cpu(cd->cd_BoardAddr);
 			dev->boardsize = be32_to_cpu(cd->cd_BoardSize);
+
+			/* CS-LAB Warp 1260 workaround */
+			if (be16_to_cpu(dev->rom.er_Manufacturer) == ZORRO_MANUF(ZORRO_PROD_CSLAB_WARP_1260) &&
+			    dev->rom.er_Product == ZORRO_PROD(ZORRO_PROD_CSLAB_WARP_1260)) {
+
+				/* turn off all interrupts */
+				pr_info("Warp 1260 card detected: applying interrupt storm workaround\n");
+				*(uint32_t *)(dev->boardaddr + 0x1000) = 0xfff;
+			}
 		} else
 			pr_warn("amiga_parse_bootinfo: too many AutoConfig devices\n");
 #endif /* CONFIG_ZORRO */
--- linux-qcom-6.8.0.orig/arch/m68k/atari/ataints.c
+++ linux-qcom-6.8.0/arch/m68k/atari/ataints.c
@@ -301,11 +301,7 @@
 
 	if (ATARIHW_PRESENT(SCU)) {
 		/* init the SCU if present */
-		tt_scu.sys_mask = 0x10;		/* enable VBL (for the cursor) and
-									 * disable HSYNC interrupts (who
-									 * needs them?)  MFP and SCC are
-									 * enabled in VME mask
-									 */
+		tt_scu.sys_mask = 0x0;		/* disable all interrupts */
 		tt_scu.vme_mask = 0x60;		/* enable MFP and SCC ints */
 	} else {
 		/* If no SCU and no Hades, the HSYNC interrupt needs to be
--- linux-qcom-6.8.0.orig/arch/m68k/coldfire/device.c
+++ linux-qcom-6.8.0/arch/m68k/coldfire/device.c
@@ -93,7 +93,7 @@
 	.dev.platform_data	= mcf_uart_platform_data,
 };
 
-#if IS_ENABLED(CONFIG_FEC)
+#ifdef MCFFEC_BASE0
 
 #ifdef CONFIG_M5441x
 #define FEC_NAME	"enet-fec"
@@ -145,6 +145,7 @@
 		.platform_data		= FEC_PDATA,
 	}
 };
+#endif /* MCFFEC_BASE0 */
 
 #ifdef MCFFEC_BASE1
 static struct resource mcf_fec1_resources[] = {
@@ -182,7 +183,6 @@
 	}
 };
 #endif /* MCFFEC_BASE1 */
-#endif /* CONFIG_FEC */
 
 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
 /*
@@ -624,12 +624,12 @@
 
 static struct platform_device *mcf_devices[] __initdata = {
 	&mcf_uart,
-#if IS_ENABLED(CONFIG_FEC)
+#ifdef MCFFEC_BASE0
 	&mcf_fec0,
+#endif
 #ifdef MCFFEC_BASE1
 	&mcf_fec1,
 #endif
-#endif
 #if IS_ENABLED(CONFIG_SPI_COLDFIRE_QSPI)
 	&mcf_qspi,
 #endif
--- linux-qcom-6.8.0.orig/arch/m68k/include/asm/cmpxchg.h
+++ linux-qcom-6.8.0/arch/m68k/include/asm/cmpxchg.h
@@ -32,7 +32,7 @@
 		x = tmp;
 		break;
 	default:
-		tmp = __invalid_xchg_size(x, ptr, size);
+		x = __invalid_xchg_size(x, ptr, size);
 		break;
 	}
 
--- linux-qcom-6.8.0.orig/arch/m68k/include/asm/mcfgpio.h
+++ linux-qcom-6.8.0/arch/m68k/include/asm/mcfgpio.h
@@ -136,7 +136,7 @@
  * read-modify-write as well as those controlled by the EPORT and GPIO modules.
  */
 #define MCFGPIO_SCR_START		40
-#elif defined(CONFIGM5441x)
+#elif defined(CONFIG_M5441x)
 /* The m5441x EPORT doesn't have its own GPIO port, uses PORT C */
 #define MCFGPIO_SCR_START		0
 #else
--- linux-qcom-6.8.0.orig/arch/m68k/include/asm/mvme147hw.h
+++ linux-qcom-6.8.0/arch/m68k/include/asm/mvme147hw.h
@@ -93,8 +93,8 @@
 #define M147_SCC_B_ADDR		0xfffe3000
 #define M147_SCC_PCLK		5000000
 
-#define MVME147_IRQ_SCSI_PORT	(IRQ_USER+0x45)
-#define MVME147_IRQ_SCSI_DMA	(IRQ_USER+0x46)
+#define MVME147_IRQ_SCSI_PORT	(IRQ_USER + 5)
+#define MVME147_IRQ_SCSI_DMA	(IRQ_USER + 6)
 
 /* SCC interrupts, for MVME147 */
 
--- linux-qcom-6.8.0.orig/arch/m68k/include/asm/vga.h
+++ linux-qcom-6.8.0/arch/m68k/include/asm/vga.h
@@ -9,7 +9,7 @@
  */
 #ifndef CONFIG_PCI
 
-#include <asm/raw_io.h>
+#include <asm/io.h>
 #include <asm/kmap.h>
 
 /*
@@ -29,9 +29,9 @@
 #define inw_p(port)		0
 #define outb_p(port, val)	do { } while (0)
 #define outw(port, val)		do { } while (0)
-#define readb			raw_inb
-#define writeb			raw_outb
-#define writew			raw_outw
+#define readb			__raw_readb
+#define writeb			__raw_writeb
+#define writew			__raw_writew
 
 #endif /* CONFIG_PCI */
 #endif /* _ASM_M68K_VGA_H */
--- linux-qcom-6.8.0.orig/arch/m68k/kernel/early_printk.c
+++ linux-qcom-6.8.0/arch/m68k/kernel/early_printk.c
@@ -13,6 +13,7 @@
 #include <asm/setup.h>
 
 
+#include "../mvme147/mvme147.h"
 #include "../mvme16x/mvme16x.h"
 
 asmlinkage void __init debug_cons_nputs(const char *s, unsigned n);
@@ -22,7 +23,9 @@
 {
 #if !(defined(CONFIG_SUN3) || defined(CONFIG_M68000) || \
       defined(CONFIG_COLDFIRE))
-	if (MACH_IS_MVME16x)
+	if (MACH_IS_MVME147)
+		mvme147_scc_write(c, s, n);
+	else if (MACH_IS_MVME16x)
 		mvme16x_cons_write(c, s, n);
 	else
 		debug_cons_nputs(s, n);
--- linux-qcom-6.8.0.orig/arch/m68k/kernel/entry.S
+++ linux-qcom-6.8.0/arch/m68k/kernel/entry.S
@@ -430,7 +430,9 @@
 	movec	%a0,%dfc
 
 	/* restore status register */
-	movew	%a1@(TASK_THREAD+THREAD_SR),%sr
+	movew	%a1@(TASK_THREAD+THREAD_SR),%d0
+	oriw	#0x0700,%d0
+	movew	%d0,%sr
 
 	rts
 
--- linux-qcom-6.8.0.orig/arch/m68k/kernel/process.c
+++ linux-qcom-6.8.0/arch/m68k/kernel/process.c
@@ -117,7 +117,7 @@
 {
 	/* regs will be equal to current_pt_regs() */
 	struct kernel_clone_args args = {
-		.flags		= regs->d1 & ~CSIGNAL,
+		.flags		= (u32)(regs->d1) & ~CSIGNAL,
 		.pidfd		= (int __user *)regs->d3,
 		.child_tid	= (int __user *)regs->d4,
 		.parent_tid	= (int __user *)regs->d3,
--- linux-qcom-6.8.0.orig/arch/m68k/mac/misc.c
+++ linux-qcom-6.8.0/arch/m68k/mac/misc.c
@@ -453,30 +453,18 @@
 
 void mac_reset(void)
 {
-	if (macintosh_config->adb_type == MAC_ADB_II &&
-	    macintosh_config->ident != MAC_MODEL_SE30) {
-		/* need ROMBASE in booter */
-		/* indeed, plus need to MAP THE ROM !! */
-
-		if (mac_bi_data.rombase == 0)
-			mac_bi_data.rombase = 0x40800000;
-
-		/* works on some */
-		rom_reset = (void *) (mac_bi_data.rombase + 0xa);
-
-		local_irq_disable();
-		rom_reset();
 #ifdef CONFIG_ADB_CUDA
-	} else if (macintosh_config->adb_type == MAC_ADB_EGRET ||
-	           macintosh_config->adb_type == MAC_ADB_CUDA) {
+	if (macintosh_config->adb_type == MAC_ADB_EGRET ||
+	    macintosh_config->adb_type == MAC_ADB_CUDA) {
 		cuda_restart();
+	} else
 #endif
 #ifdef CONFIG_ADB_PMU
-	} else if (macintosh_config->adb_type == MAC_ADB_PB2) {
+	if (macintosh_config->adb_type == MAC_ADB_PB2) {
 		pmu_restart();
+	} else
 #endif
-	} else if (CPU_IS_030) {
-
+	if (CPU_IS_030) {
 		/* 030-specific reset routine.  The idea is general, but the
 		 * specific registers to reset are '030-specific.  Until I
 		 * have a non-030 machine, I can't test anything else.
@@ -524,6 +512,18 @@
 		    "jmp %/a0@\n\t" /* jump to the reset vector */
 		    ".chip 68k"
 		    : : "r" (offset), "a" (rombase) : "a0");
+	} else {
+		/* need ROMBASE in booter */
+		/* indeed, plus need to MAP THE ROM !! */
+
+		if (mac_bi_data.rombase == 0)
+			mac_bi_data.rombase = 0x40800000;
+
+		/* works on some */
+		rom_reset = (void *)(mac_bi_data.rombase + 0xa);
+
+		local_irq_disable();
+		rom_reset();
 	}
 
 	/* should never get here */
--- linux-qcom-6.8.0.orig/arch/m68k/mvme147/config.c
+++ linux-qcom-6.8.0/arch/m68k/mvme147/config.c
@@ -32,6 +32,7 @@
 #include <asm/mvme147hw.h>
 #include <asm/config.h>
 
+#include "mvme147.h"
 
 static void mvme147_get_model(char *model);
 extern void mvme147_sched_init(void);
@@ -185,3 +186,32 @@
 	}
 	return 0;
 }
+
+static void scc_delay(void)
+{
+	__asm__ __volatile__ ("nop; nop;");
+}
+
+static void scc_write(char ch)
+{
+	do {
+		scc_delay();
+	} while (!(in_8(M147_SCC_A_ADDR) & BIT(2)));
+	scc_delay();
+	out_8(M147_SCC_A_ADDR, 8);
+	scc_delay();
+	out_8(M147_SCC_A_ADDR, ch);
+}
+
+void mvme147_scc_write(struct console *co, const char *str, unsigned int count)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	while (count--)	{
+		if (*str == '\n')
+			scc_write('\r');
+		scc_write(*str++);
+	}
+	local_irq_restore(flags);
+}
--- linux-qcom-6.8.0.orig/arch/m68k/mvme147/mvme147.h
+++ linux-qcom-6.8.0/arch/m68k/mvme147/mvme147.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+struct console;
+
+/* config.c */
+void mvme147_scc_write(struct console *co, const char *str, unsigned int count);
--- linux-qcom-6.8.0.orig/arch/microblaze/kernel/Makefile
+++ linux-qcom-6.8.0/arch/microblaze/kernel/Makefile
@@ -7,7 +7,6 @@
 # Do not trace early boot code and low level code
 CFLAGS_REMOVE_timer.o = -pg
 CFLAGS_REMOVE_intc.o = -pg
-CFLAGS_REMOVE_early_printk.o = -pg
 CFLAGS_REMOVE_ftrace.o = -pg
 CFLAGS_REMOVE_process.o = -pg
 endif
--- linux-qcom-6.8.0.orig/arch/microblaze/kernel/cpu/cpuinfo-static.c
+++ linux-qcom-6.8.0/arch/microblaze/kernel/cpu/cpuinfo-static.c
@@ -18,7 +18,7 @@
 static const char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER;
 
 #define err_printk(x) \
-	early_printk("ERROR: Microblaze " x "-different for kernel and DTS\n");
+	pr_err("ERROR: Microblaze " x "-different for kernel and DTS\n");
 
 void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
 {
--- linux-qcom-6.8.0.orig/arch/microblaze/kernel/microblaze_ksyms.c
+++ linux-qcom-6.8.0/arch/microblaze/kernel/microblaze_ksyms.c
@@ -16,6 +16,7 @@
 #include <asm/page.h>
 #include <linux/ftrace.h>
 #include <linux/uaccess.h>
+#include <asm/xilinx_mb_manager.h>
 
 #ifdef CONFIG_FUNCTION_TRACER
 extern void _mcount(void);
@@ -46,3 +47,12 @@
 EXPORT_SYMBOL(__udivsi3);
 extern void __umodsi3(void);
 EXPORT_SYMBOL(__umodsi3);
+
+#ifdef CONFIG_MB_MANAGER
+extern void xmb_manager_register(uintptr_t phys_baseaddr, u32 cr_val,
+				 void (*callback)(void *data),
+				 void *priv, void (*reset_callback)(void *data));
+EXPORT_SYMBOL(xmb_manager_register);
+extern asmlinkage void xmb_inject_err(void);
+EXPORT_SYMBOL(xmb_inject_err);
+#endif
--- linux-qcom-6.8.0.orig/arch/microblaze/kernel/prom.c
+++ linux-qcom-6.8.0/arch/microblaze/kernel/prom.c
@@ -18,7 +18,7 @@
 {
 	pr_debug(" -> early_init_devtree(%p)\n", params);
 
-	early_init_dt_scan(params);
+	early_init_dt_scan(params, __pa(params));
 	if (!strlen(boot_command_line))
 		strscpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
 
--- linux-qcom-6.8.0.orig/arch/microblaze/mm/init.c
+++ linux-qcom-6.8.0/arch/microblaze/mm/init.c
@@ -193,11 +193,6 @@
 {
 	unsigned int kstart, ksize;
 
-	if (!memblock.reserved.cnt) {
-		pr_emerg("Error memory count\n");
-		machine_restart(NULL);
-	}
-
 	if ((u32) memblock.memory.regions[0].size < 0x400000) {
 		pr_emerg("Memory must be greater than 4MB\n");
 		machine_restart(NULL);
--- linux-qcom-6.8.0.orig/arch/mips/Kconfig
+++ linux-qcom-6.8.0/arch/mips/Kconfig
@@ -14,7 +14,7 @@
 	select ARCH_HAS_STRNCPY_FROM_USER
 	select ARCH_HAS_STRNLEN_USER
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
-	select ARCH_HAS_UBSAN_SANITIZE_ALL
+	select ARCH_HAS_UBSAN
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_KEEP_MEMBLOCK
 	select ARCH_USE_BUILTIN_BSWAP
--- linux-qcom-6.8.0.orig/arch/mips/Makefile
+++ linux-qcom-6.8.0/arch/mips/Makefile
@@ -299,7 +299,7 @@
 ifdef CONFIG_64BIT
   ifndef KBUILD_SYM32
     ifeq ($(shell expr $(load-y) \< 0xffffffff80000000), 0)
-      KBUILD_SYM32 = y
+      KBUILD_SYM32 = $(call cc-option-yn, -msym32)
     endif
   endif
 
--- linux-qcom-6.8.0.orig/arch/mips/bmips/setup.c
+++ linux-qcom-6.8.0/arch/mips/bmips/setup.c
@@ -110,7 +110,8 @@
 	 * RAC flush causes kernel panics on BCM6358 when booting from TP1
 	 * because the bootloader is not initializing it properly.
 	 */
-	bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31));
+	bmips_rac_flush_disable = !!(read_c0_brcm_cmt_local() & (1 << 31)) ||
+				  !!BMIPS_GET_CBR();
 }
 
 static void bcm6368_quirks(void)
--- linux-qcom-6.8.0.orig/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi
+++ linux-qcom-6.8.0/arch/mips/boot/dts/loongson/loongson64-2k1000.dtsi
@@ -23,14 +23,6 @@
 		};
 	};
 
-	memory@200000 {
-		compatible = "memory";
-		device_type = "memory";
-		reg = <0x00000000 0x00200000 0x00000000 0x0ee00000>, /* 238 MB at 2 MB */
-			<0x00000000 0x20000000 0x00000000 0x1f000000>, /* 496 MB at 512 MB */
-			<0x00000001 0x10000000 0x00000001 0xb0000000>; /* 6912 MB at 4352MB */
-	};
-
 	cpu_clk: cpu_clk {
 		#clock-cells = <0>;
 		compatible = "fixed-clock";
@@ -52,6 +44,13 @@
 			0 0x40000000 0 0x40000000 0 0x40000000
 			0xfe 0x00000000 0xfe 0x00000000 0 0x40000000>;
 
+		isa@18000000 {
+			compatible = "isa";
+			#size-cells = <1>;
+			#address-cells = <2>;
+			ranges = <1 0x0 0x0 0x18000000 0x4000>;
+		};
+
 		pm: reset-controller@1fe07000 {
 			compatible = "loongson,ls2k-pm";
 			reg = <0 0x1fe07000 0 0x422>;
@@ -100,8 +99,8 @@
 		rtc0: rtc@1fe07800 {
 			compatible = "loongson,ls2k1000-rtc";
 			reg = <0 0x1fe07800 0 0x78>;
-			interrupt-parent = <&liointc0>;
-			interrupts = <60 IRQ_TYPE_LEVEL_LOW>;
+			interrupt-parent = <&liointc1>;
+			interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
 		uart0: serial@1fe00000 {
@@ -109,7 +108,7 @@
 			reg = <0 0x1fe00000 0 0x8>;
 			clock-frequency = <125000000>;
 			interrupt-parent = <&liointc0>;
-			interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+			interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
 			no-loopback-test;
 		};
 
@@ -118,7 +117,6 @@
 			device_type = "pci";
 			#address-cells = <3>;
 			#size-cells = <2>;
-			#interrupt-cells = <2>;
 
 			reg = <0 0x1a000000 0 0x02000000>,
 				<0xfe 0x00000000 0 0x20000000>;
@@ -133,11 +131,12 @@
 						   "pciclass0c03";
 
 				reg = <0x1800 0x0 0x0 0x0 0x0>;
-				interrupts = <12 IRQ_TYPE_LEVEL_LOW>,
-					     <13 IRQ_TYPE_LEVEL_LOW>;
+				interrupts = <12 IRQ_TYPE_LEVEL_HIGH>,
+					     <13 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-names = "macirq", "eth_lpi";
 				interrupt-parent = <&liointc0>;
-				phy-mode = "rgmii";
+				phy-mode = "rgmii-id";
+				phy-handle = <&phy1>;
 				mdio {
 					#address-cells = <1>;
 					#size-cells = <0>;
@@ -156,11 +155,12 @@
 						   "loongson, pci-gmac";
 
 				reg = <0x1900 0x0 0x0 0x0 0x0>;
-				interrupts = <14 IRQ_TYPE_LEVEL_LOW>,
-					     <15 IRQ_TYPE_LEVEL_LOW>;
+				interrupts = <14 IRQ_TYPE_LEVEL_HIGH>,
+					     <15 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-names = "macirq", "eth_lpi";
 				interrupt-parent = <&liointc0>;
-				phy-mode = "rgmii";
+				phy-mode = "rgmii-id";
+				phy-handle = <&phy1>;
 				mdio {
 					#address-cells = <1>;
 					#size-cells = <0>;
@@ -178,7 +178,7 @@
 						   "pciclass0c03";
 
 				reg = <0x2100 0x0 0x0 0x0 0x0>;
-				interrupts = <18 IRQ_TYPE_LEVEL_LOW>;
+				interrupts = <18 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&liointc1>;
 			};
 
@@ -189,7 +189,7 @@
 						   "pciclass0c03";
 
 				reg = <0x2200 0x0 0x0 0x0 0x0>;
-				interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
+				interrupts = <19 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&liointc1>;
 			};
 
@@ -200,97 +200,121 @@
 						   "pciclass0106";
 
 				reg = <0x4000 0x0 0x0 0x0 0x0>;
-				interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
+				interrupts = <19 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&liointc0>;
 			};
 
-			pci_bridge@9,0 {
+			pcie@9,0 {
 				compatible = "pci0014,7a19.0",
 						   "pci0014,7a19",
 						   "pciclass060400",
 						   "pciclass0604";
 
 				reg = <0x4800 0x0 0x0 0x0 0x0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
-				interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+				interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&liointc1>;
 				interrupt-map-mask = <0 0 0 0>;
-				interrupt-map = <0 0 0 0 &liointc1 0 IRQ_TYPE_LEVEL_LOW>;
+				interrupt-map = <0 0 0 0 &liointc1 0 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 				external-facing;
 			};
 
-			pci_bridge@a,0 {
+			pcie@a,0 {
 				compatible = "pci0014,7a09.0",
 						   "pci0014,7a09",
 						   "pciclass060400",
 						   "pciclass0604";
 
 				reg = <0x5000 0x0 0x0 0x0 0x0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
-				interrupts = <1 IRQ_TYPE_LEVEL_LOW>;
+				interrupts = <1 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&liointc1>;
 				interrupt-map-mask = <0 0 0 0>;
-				interrupt-map = <0 0 0 0 &liointc1 1 IRQ_TYPE_LEVEL_LOW>;
+				interrupt-map = <0 0 0 0 &liointc1 1 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 				external-facing;
 			};
 
-			pci_bridge@b,0 {
+			pcie@b,0 {
 				compatible = "pci0014,7a09.0",
 						   "pci0014,7a09",
 						   "pciclass060400",
 						   "pciclass0604";
 
 				reg = <0x5800 0x0 0x0 0x0 0x0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
-				interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+				interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&liointc1>;
 				interrupt-map-mask = <0 0 0 0>;
-				interrupt-map = <0 0 0 0 &liointc1 2 IRQ_TYPE_LEVEL_LOW>;
+				interrupt-map = <0 0 0 0 &liointc1 2 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 				external-facing;
 			};
 
-			pci_bridge@c,0 {
+			pcie@c,0 {
 				compatible = "pci0014,7a09.0",
 						   "pci0014,7a09",
 						   "pciclass060400",
 						   "pciclass0604";
 
 				reg = <0x6000 0x0 0x0 0x0 0x0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
-				interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
+				interrupts = <3 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&liointc1>;
 				interrupt-map-mask = <0 0 0 0>;
-				interrupt-map = <0 0 0 0 &liointc1 3 IRQ_TYPE_LEVEL_LOW>;
+				interrupt-map = <0 0 0 0 &liointc1 3 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 				external-facing;
 			};
 
-			pci_bridge@d,0 {
+			pcie@d,0 {
 				compatible = "pci0014,7a19.0",
 						   "pci0014,7a19",
 						   "pciclass060400",
 						   "pciclass0604";
 
 				reg = <0x6800 0x0 0x0 0x0 0x0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
-				interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
+				interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&liointc1>;
 				interrupt-map-mask = <0 0 0 0>;
-				interrupt-map = <0 0 0 0 &liointc1 4 IRQ_TYPE_LEVEL_LOW>;
+				interrupt-map = <0 0 0 0 &liointc1 4 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 				external-facing;
 			};
 
-			pci_bridge@e,0 {
+			pcie@e,0 {
 				compatible = "pci0014,7a09.0",
 						   "pci0014,7a09",
 						   "pciclass060400",
 						   "pciclass0604";
 
 				reg = <0x7000 0x0 0x0 0x0 0x0>;
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
-				interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+				interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&liointc1>;
 				interrupt-map-mask = <0 0 0 0>;
-				interrupt-map = <0 0 0 0 &liointc1 5 IRQ_TYPE_LEVEL_LOW>;
+				interrupt-map = <0 0 0 0 &liointc1 5 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 				external-facing;
 			};
 
--- linux-qcom-6.8.0.orig/arch/mips/boot/dts/loongson/loongson64g_4core_ls7a.dts
+++ linux-qcom-6.8.0/arch/mips/boot/dts/loongson/loongson64g_4core_ls7a.dts
@@ -33,6 +33,7 @@
 		compatible = "loongson,pch-msi-1.0";
 		reg = <0 0x2ff00000 0 0x8>;
 		interrupt-controller;
+		#interrupt-cells = <1>;
 		msi-controller;
 		loongson,msi-base-vec = <64>;
 		loongson,msi-num-vecs = <192>;
--- linux-qcom-6.8.0.orig/arch/mips/boot/dts/loongson/ls7a-pch.dtsi
+++ linux-qcom-6.8.0/arch/mips/boot/dts/loongson/ls7a-pch.dtsi
@@ -70,7 +70,6 @@
 			device_type = "pci";
 			#address-cells = <3>;
 			#size-cells = <2>;
-			#interrupt-cells = <2>;
 			msi-parent = <&msi>;
 
 			reg = <0 0x1a000000 0 0x02000000>,
@@ -234,7 +233,7 @@
 				};
 			};
 
-			pci_bridge@9,0 {
+			pcie@9,0 {
 				compatible = "pci0014,7a19.1",
 						   "pci0014,7a19",
 						   "pciclass060400",
@@ -244,12 +243,16 @@
 				interrupts = <32 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&pic>;
 
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
 				interrupt-map-mask = <0 0 0 0>;
 				interrupt-map = <0 0 0 0 &pic 32 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 			};
 
-			pci_bridge@a,0 {
+			pcie@a,0 {
 				compatible = "pci0014,7a09.1",
 						   "pci0014,7a09",
 						   "pciclass060400",
@@ -259,12 +262,16 @@
 				interrupts = <33 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&pic>;
 
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
 				interrupt-map-mask = <0 0 0 0>;
 				interrupt-map = <0 0 0 0 &pic 33 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 			};
 
-			pci_bridge@b,0 {
+			pcie@b,0 {
 				compatible = "pci0014,7a09.1",
 						   "pci0014,7a09",
 						   "pciclass060400",
@@ -274,12 +281,16 @@
 				interrupts = <34 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&pic>;
 
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
 				interrupt-map-mask = <0 0 0 0>;
 				interrupt-map = <0 0 0 0 &pic 34 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 			};
 
-			pci_bridge@c,0 {
+			pcie@c,0 {
 				compatible = "pci0014,7a09.1",
 						   "pci0014,7a09",
 						   "pciclass060400",
@@ -289,12 +300,16 @@
 				interrupts = <35 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&pic>;
 
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
 				interrupt-map-mask = <0 0 0 0>;
 				interrupt-map = <0 0 0 0 &pic 35 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 			};
 
-			pci_bridge@d,0 {
+			pcie@d,0 {
 				compatible = "pci0014,7a19.1",
 						   "pci0014,7a19",
 						   "pciclass060400",
@@ -304,12 +319,16 @@
 				interrupts = <36 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&pic>;
 
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
 				interrupt-map-mask = <0 0 0 0>;
 				interrupt-map = <0 0 0 0 &pic 36 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 			};
 
-			pci_bridge@e,0 {
+			pcie@e,0 {
 				compatible = "pci0014,7a09.1",
 						   "pci0014,7a09",
 						   "pciclass060400",
@@ -319,12 +338,16 @@
 				interrupts = <37 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&pic>;
 
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
 				interrupt-map-mask = <0 0 0 0>;
 				interrupt-map = <0 0 0 0 &pic 37 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 			};
 
-			pci_bridge@f,0 {
+			pcie@f,0 {
 				compatible = "pci0014,7a29.1",
 						   "pci0014,7a29",
 						   "pciclass060400",
@@ -334,12 +357,16 @@
 				interrupts = <40 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&pic>;
 
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
 				interrupt-map-mask = <0 0 0 0>;
 				interrupt-map = <0 0 0 0 &pic 40 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 			};
 
-			pci_bridge@10,0 {
+			pcie@10,0 {
 				compatible = "pci0014,7a19.1",
 						   "pci0014,7a19",
 						   "pciclass060400",
@@ -349,12 +376,16 @@
 				interrupts = <41 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&pic>;
 
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
 				interrupt-map-mask = <0 0 0 0>;
 				interrupt-map = <0 0 0 0 &pic 41 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 			};
 
-			pci_bridge@11,0 {
+			pcie@11,0 {
 				compatible = "pci0014,7a29.1",
 						   "pci0014,7a29",
 						   "pciclass060400",
@@ -364,12 +395,16 @@
 				interrupts = <42 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&pic>;
 
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
 				interrupt-map-mask = <0 0 0 0>;
 				interrupt-map = <0 0 0 0 &pic 42 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 			};
 
-			pci_bridge@12,0 {
+			pcie@12,0 {
 				compatible = "pci0014,7a19.1",
 						   "pci0014,7a19",
 						   "pciclass060400",
@@ -379,12 +414,16 @@
 				interrupts = <43 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&pic>;
 
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
 				interrupt-map-mask = <0 0 0 0>;
 				interrupt-map = <0 0 0 0 &pic 43 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 			};
 
-			pci_bridge@13,0 {
+			pcie@13,0 {
 				compatible = "pci0014,7a29.1",
 						   "pci0014,7a29",
 						   "pciclass060400",
@@ -394,12 +433,16 @@
 				interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&pic>;
 
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
 				interrupt-map-mask = <0 0 0 0>;
 				interrupt-map = <0 0 0 0 &pic 38 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 			};
 
-			pci_bridge@14,0 {
+			pcie@14,0 {
 				compatible = "pci0014,7a19.1",
 						   "pci0014,7a19",
 						   "pciclass060400",
@@ -409,9 +452,13 @@
 				interrupts = <39 IRQ_TYPE_LEVEL_HIGH>;
 				interrupt-parent = <&pic>;
 
+				#address-cells = <3>;
+				#size-cells = <2>;
+				device_type = "pci";
 				#interrupt-cells = <1>;
 				interrupt-map-mask = <0 0 0 0>;
 				interrupt-map = <0 0 0 0 &pic 39 IRQ_TYPE_LEVEL_HIGH>;
+				ranges;
 			};
 		};
 
--- linux-qcom-6.8.0.orig/arch/mips/include/asm/mach-loongson64/boot_param.h
+++ linux-qcom-6.8.0/arch/mips/include/asm/mach-loongson64/boot_param.h
@@ -42,12 +42,14 @@
 	Legacy_1B = 0x5,
 	Legacy_2G = 0x6,
 	Legacy_2H = 0x7,
+	Legacy_2K = 0x8,
 	Loongson_1A = 0x100,
 	Loongson_1B = 0x101,
 	Loongson_2E = 0x200,
 	Loongson_2F = 0x201,
 	Loongson_2G = 0x202,
 	Loongson_2H = 0x203,
+	Loongson_2K = 0x204,
 	Loongson_3A = 0x300,
 	Loongson_3B = 0x301
 };
--- linux-qcom-6.8.0.orig/arch/mips/include/asm/mips-cm.h
+++ linux-qcom-6.8.0/arch/mips/include/asm/mips-cm.h
@@ -33,6 +33,19 @@
  */
 extern phys_addr_t __mips_cm_phys_base(void);
 
+/**
+ * mips_cm_l2sync_phys_base - retrieve the physical base address of the CM
+ *                            L2-sync region
+ *
+ * This function returns the physical base address of the Coherence Manager
+ * L2-cache only region. It provides a default implementation which reads the
+ * CMGCRL2OnlySyncBase register where available or returns a 4K region just
+ * behind the CM GCR base address. It may be overridden by platforms which
+ * determine this address in a different way by defining a function with the
+ * same prototype.
+ */
+extern phys_addr_t mips_cm_l2sync_phys_base(void);
+
 /*
  * mips_cm_is64 - determine CM register width
  *
@@ -228,6 +241,10 @@
 GCR_ACCESSOR_RO(32, 0x0f0, cpc_status)
 #define CM_GCR_CPC_STATUS_EX			BIT(0)
 
+/* GCR_ACCESS - Controls core/IOCU access to GCRs */
+GCR_ACCESSOR_RW(32, 0x120, access_cm3)
+#define CM_GCR_ACCESS_ACCESSEN			GENMASK(7, 0)
+
 /* GCR_L2_CONFIG - Indicates L2 cache configuration when Config5.L2C=1 */
 GCR_ACCESSOR_RW(32, 0x130, l2_config)
 #define CM_GCR_L2_CONFIG_BYPASS			BIT(20)
--- linux-qcom-6.8.0.orig/arch/mips/include/asm/mipsregs.h
+++ linux-qcom-6.8.0/arch/mips/include/asm/mipsregs.h
@@ -2078,7 +2078,14 @@
 		_ASM_INSN_IF_MIPS(0x4200000c)				\
 		_ASM_INSN32_IF_MM(0x0000517c)
 #else	/* !TOOLCHAIN_SUPPORTS_VIRT */
-#define _ASM_SET_VIRT ".set\tvirt\n\t"
+#if MIPS_ISA_REV >= 5
+#define _ASM_SET_VIRT_ISA
+#elif defined(CONFIG_64BIT)
+#define _ASM_SET_VIRT_ISA ".set\tmips64r5\n\t"
+#else
+#define _ASM_SET_VIRT_ISA ".set\tmips32r5\n\t"
+#endif
+#define _ASM_SET_VIRT _ASM_SET_VIRT_ISA ".set\tvirt\n\t"
 #define _ASM_SET_MFGC0	_ASM_SET_VIRT
 #define _ASM_SET_DMFGC0	_ASM_SET_VIRT
 #define _ASM_SET_MTGC0	_ASM_SET_VIRT
@@ -2099,7 +2106,6 @@
 ({ int __res;								\
 	__asm__ __volatile__(						\
 		".set\tpush\n\t"					\
-		".set\tmips32r5\n\t"					\
 		_ASM_SET_MFGC0						\
 		"mfgc0\t%0, " #source ", %1\n\t"			\
 		_ASM_UNSET_MFGC0					\
@@ -2113,7 +2119,6 @@
 ({ unsigned long long __res;						\
 	__asm__ __volatile__(						\
 		".set\tpush\n\t"					\
-		".set\tmips64r5\n\t"					\
 		_ASM_SET_DMFGC0						\
 		"dmfgc0\t%0, " #source ", %1\n\t"			\
 		_ASM_UNSET_DMFGC0					\
@@ -2127,7 +2132,6 @@
 do {									\
 	__asm__ __volatile__(						\
 		".set\tpush\n\t"					\
-		".set\tmips32r5\n\t"					\
 		_ASM_SET_MTGC0						\
 		"mtgc0\t%z0, " #register ", %1\n\t"			\
 		_ASM_UNSET_MTGC0					\
@@ -2140,7 +2144,6 @@
 do {									\
 	__asm__ __volatile__(						\
 		".set\tpush\n\t"					\
-		".set\tmips64r5\n\t"					\
 		_ASM_SET_DMTGC0						\
 		"dmtgc0\t%z0, " #register ", %1\n\t"			\
 		_ASM_UNSET_DMTGC0					\
--- linux-qcom-6.8.0.orig/arch/mips/include/asm/ptrace.h
+++ linux-qcom-6.8.0/arch/mips/include/asm/ptrace.h
@@ -159,7 +159,7 @@
 #define exception_ip(regs) exception_ip(regs)
 #define profile_pc(regs) instruction_pointer(regs)
 
-extern asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall);
+extern asmlinkage long syscall_trace_enter(struct pt_regs *regs);
 extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);
 
 extern void die(const char *, struct pt_regs *) __noreturn;
--- linux-qcom-6.8.0.orig/arch/mips/include/asm/switch_to.h
+++ linux-qcom-6.8.0/arch/mips/include/asm/switch_to.h
@@ -97,7 +97,7 @@
 	}								\
 } while (0)
 #else
-# define __sanitize_fcr31(next)
+# define __sanitize_fcr31(next) do { (void) (next); } while (0)
 #endif
 
 /*
--- linux-qcom-6.8.0.orig/arch/mips/kernel/asm-offsets.c
+++ linux-qcom-6.8.0/arch/mips/kernel/asm-offsets.c
@@ -101,6 +101,7 @@
 	OFFSET(TI_CPU, thread_info, cpu);
 	OFFSET(TI_PRE_COUNT, thread_info, preempt_count);
 	OFFSET(TI_REGS, thread_info, regs);
+	OFFSET(TI_SYSCALL, thread_info, syscall);
 	DEFINE(_THREAD_SIZE, THREAD_SIZE);
 	DEFINE(_THREAD_MASK, THREAD_MASK);
 	DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);
--- linux-qcom-6.8.0.orig/arch/mips/kernel/cevt-r4k.c
+++ linux-qcom-6.8.0/arch/mips/kernel/cevt-r4k.c
@@ -303,13 +303,6 @@
 	if (!c0_compare_int_usable())
 		return -ENXIO;
 
-	/*
-	 * With vectored interrupts things are getting platform specific.
-	 * get_c0_compare_int is a hook to allow a platform to return the
-	 * interrupt number of its liking.
-	 */
-	irq = get_c0_compare_int();
-
 	cd = &per_cpu(mips_clockevent_device, cpu);
 
 	cd->name		= "MIPS";
@@ -320,7 +313,6 @@
 	min_delta		= calculate_min_delta();
 
 	cd->rating		= 300;
-	cd->irq			= irq;
 	cd->cpumask		= cpumask_of(cpu);
 	cd->set_next_event	= mips_next_event;
 	cd->event_handler	= mips_event_handler;
@@ -332,6 +324,13 @@
 
 	cp0_timer_irq_installed = 1;
 
+	/*
+	 * With vectored interrupts things are getting platform specific.
+	 * get_c0_compare_int is a hook to allow a platform to return the
+	 * interrupt number of its liking.
+	 */
+	irq = get_c0_compare_int();
+
 	if (request_irq(irq, c0_compare_interrupt, flags, "timer",
 			c0_compare_interrupt))
 		pr_err("Failed to request irq %d (timer)\n", irq);
--- linux-qcom-6.8.0.orig/arch/mips/kernel/cmpxchg.c
+++ linux-qcom-6.8.0/arch/mips/kernel/cmpxchg.c
@@ -102,3 +102,4 @@
 			return old;
 	}
 }
+EXPORT_SYMBOL(__cmpxchg_small);
--- linux-qcom-6.8.0.orig/arch/mips/kernel/cpu-probe.c
+++ linux-qcom-6.8.0/arch/mips/kernel/cpu-probe.c
@@ -1724,12 +1724,16 @@
 		c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
 			MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2);
 		c->ases &= ~MIPS_ASE_VZ; /* VZ of Loongson-3A2000/3000 is incomplete */
+		change_c0_config6(LOONGSON_CONF6_EXTIMER | LOONGSON_CONF6_INTIMER,
+				  LOONGSON_CONF6_INTIMER);
 		break;
 	case PRID_IMP_LOONGSON_64G:
 		__cpu_name[cpu] = "ICT Loongson-3";
 		set_elf_platform(cpu, "loongson3a");
 		set_isa(c, MIPS_CPU_ISA_M64R2);
 		decode_cpucfg(c);
+		change_c0_config6(LOONGSON_CONF6_EXTIMER | LOONGSON_CONF6_INTIMER,
+				  LOONGSON_CONF6_INTIMER);
 		break;
 	default:
 		panic("Unknown Loongson Processor ID!");
--- linux-qcom-6.8.0.orig/arch/mips/kernel/ftrace.c
+++ linux-qcom-6.8.0/arch/mips/kernel/ftrace.c
@@ -248,7 +248,7 @@
 #define S_R_SP	(0xafb0 << 16)	/* s{d,w} R, offset(sp) */
 #define OFFSET_MASK	0xffff	/* stack offset range: 0 ~ PT_SIZE */
 
-unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long
+static unsigned long ftrace_get_parent_ra_addr(unsigned long self_ra, unsigned long
 		old_parent_ra, unsigned long parent_ra_addr, unsigned long fp)
 {
 	unsigned long sp, ip, tmp;
--- linux-qcom-6.8.0.orig/arch/mips/kernel/mips-cm.c
+++ linux-qcom-6.8.0/arch/mips/kernel/mips-cm.c
@@ -201,7 +201,7 @@
 phys_addr_t mips_cm_phys_base(void)
 	__attribute__((weak, alias("__mips_cm_phys_base")));
 
-static phys_addr_t __mips_cm_l2sync_phys_base(void)
+phys_addr_t __weak mips_cm_l2sync_phys_base(void)
 {
 	u32 base_reg;
 
@@ -217,9 +217,6 @@
 	return mips_cm_phys_base() + MIPS_CM_GCR_SIZE;
 }
 
-phys_addr_t mips_cm_l2sync_phys_base(void)
-	__attribute__((weak, alias("__mips_cm_l2sync_phys_base")));
-
 static void mips_cm_probe_l2sync(void)
 {
 	unsigned major_rev;
--- linux-qcom-6.8.0.orig/arch/mips/kernel/prom.c
+++ linux-qcom-6.8.0/arch/mips/kernel/prom.c
@@ -41,7 +41,7 @@
 
 void __init __dt_setup_arch(void *bph)
 {
-	if (!early_init_dt_scan(bph))
+	if (!early_init_dt_scan(bph, __pa(bph)))
 		return;
 
 	mips_set_machine_name(of_flat_dt_get_machine_name());
--- linux-qcom-6.8.0.orig/arch/mips/kernel/ptrace.c
+++ linux-qcom-6.8.0/arch/mips/kernel/ptrace.c
@@ -1317,16 +1317,13 @@
  * Notification of system call entry/exit
  * - triggered by current->work.syscall_trace
  */
-asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
+asmlinkage long syscall_trace_enter(struct pt_regs *regs)
 {
 	user_exit();
 
-	current_thread_info()->syscall = syscall;
-
 	if (test_thread_flag(TIF_SYSCALL_TRACE)) {
 		if (ptrace_report_syscall_entry(regs))
 			return -1;
-		syscall = current_thread_info()->syscall;
 	}
 
 #ifdef CONFIG_SECCOMP
@@ -1335,7 +1332,7 @@
 		struct seccomp_data sd;
 		unsigned long args[6];
 
-		sd.nr = syscall;
+		sd.nr = current_thread_info()->syscall;
 		sd.arch = syscall_get_arch(current);
 		syscall_get_arguments(current, regs, args);
 		for (i = 0; i < 6; i++)
@@ -1345,23 +1342,23 @@
 		ret = __secure_computing(&sd);
 		if (ret == -1)
 			return ret;
-		syscall = current_thread_info()->syscall;
 	}
 #endif
 
 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
 		trace_sys_enter(regs, regs->regs[2]);
 
-	audit_syscall_entry(syscall, regs->regs[4], regs->regs[5],
+	audit_syscall_entry(current_thread_info()->syscall,
+			    regs->regs[4], regs->regs[5],
 			    regs->regs[6], regs->regs[7]);
 
 	/*
 	 * Negative syscall numbers are mistaken for rejected syscalls, but
 	 * won't have had the return value set appropriately, so we do so now.
 	 */
-	if (syscall < 0)
+	if (current_thread_info()->syscall < 0)
 		syscall_set_return_value(current, regs, -ENOSYS, 0);
-	return syscall;
+	return current_thread_info()->syscall;
 }
 
 /*
--- linux-qcom-6.8.0.orig/arch/mips/kernel/relocate.c
+++ linux-qcom-6.8.0/arch/mips/kernel/relocate.c
@@ -337,7 +337,7 @@
 #if defined(CONFIG_USE_OF)
 	/* Deal with the device tree */
 	fdt = plat_get_fdt();
-	early_init_dt_scan(fdt);
+	early_init_dt_scan(fdt, __pa(fdt));
 	if (boot_command_line[0]) {
 		/* Boot command line was passed in device tree */
 		strscpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
--- linux-qcom-6.8.0.orig/arch/mips/kernel/scall32-o32.S
+++ linux-qcom-6.8.0/arch/mips/kernel/scall32-o32.S
@@ -77,6 +77,18 @@
 	PTR_WD	load_a7, bad_stack_a7
 	.previous
 
+	/*
+	 * syscall number is in v0 unless we called syscall(__NR_###)
+	 * where the real syscall number is in a0
+	 */
+	subu	t2, v0,  __NR_O32_Linux
+	bnez	t2, 1f /* __NR_syscall at offset 0 */
+	LONG_S	a0, TI_SYSCALL($28)	# Save a0 as syscall number
+	b	2f
+1:
+	LONG_S	v0, TI_SYSCALL($28)	# Save v0 as syscall number
+2:
+
 	lw	t0, TI_FLAGS($28)	# syscall tracing enabled?
 	li	t1, _TIF_WORK_SYSCALL_ENTRY
 	and	t0, t1
@@ -114,16 +126,7 @@
 	SAVE_STATIC
 	move	a0, sp
 
-	/*
-	 * syscall number is in v0 unless we called syscall(__NR_###)
-	 * where the real syscall number is in a0
-	 */
-	move	a1, v0
-	subu	t2, v0,  __NR_O32_Linux
-	bnez	t2, 1f /* __NR_syscall at offset 0 */
-	lw	a1, PT_R4(sp)
-
-1:	jal	syscall_trace_enter
+	jal	syscall_trace_enter
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
 
--- linux-qcom-6.8.0.orig/arch/mips/kernel/scall64-n32.S
+++ linux-qcom-6.8.0/arch/mips/kernel/scall64-n32.S
@@ -44,6 +44,8 @@
 
 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 
+	LONG_S	v0, TI_SYSCALL($28)     # Store syscall number
+
 	li	t1, _TIF_WORK_SYSCALL_ENTRY
 	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
 	and	t0, t1, t0
@@ -72,7 +74,6 @@
 n32_syscall_trace_entry:
 	SAVE_STATIC
 	move	a0, sp
-	move	a1, v0
 	jal	syscall_trace_enter
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
--- linux-qcom-6.8.0.orig/arch/mips/kernel/scall64-n64.S
+++ linux-qcom-6.8.0/arch/mips/kernel/scall64-n64.S
@@ -46,6 +46,8 @@
 
 	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
 
+	LONG_S	v0, TI_SYSCALL($28)     # Store syscall number
+
 	li	t1, _TIF_WORK_SYSCALL_ENTRY
 	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
 	and	t0, t1, t0
@@ -82,7 +84,6 @@
 syscall_trace_entry:
 	SAVE_STATIC
 	move	a0, sp
-	move	a1, v0
 	jal	syscall_trace_enter
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
--- linux-qcom-6.8.0.orig/arch/mips/kernel/scall64-o32.S
+++ linux-qcom-6.8.0/arch/mips/kernel/scall64-o32.S
@@ -79,6 +79,22 @@
 	PTR_WD	load_a7, bad_stack_a7
 	.previous
 
+	/*
+	 * absolute syscall number is in v0 unless we called syscall(__NR_###)
+	 * where the real syscall number is in a0
+	 * note: NR_syscall is the first O32 syscall but the macro is
+	 * only defined when compiling with -mabi=32 (CONFIG_32BIT)
+	 * therefore __NR_O32_Linux is used (4000)
+	 */
+
+	subu	t2, v0,  __NR_O32_Linux
+	bnez	t2, 1f /* __NR_syscall at offset 0 */
+	LONG_S	a0, TI_SYSCALL($28)	# Save a0 as syscall number
+	b	2f
+1:
+	LONG_S	v0, TI_SYSCALL($28)	# Save v0 as syscall number
+2:
+
 	li	t1, _TIF_WORK_SYSCALL_ENTRY
 	LONG_L	t0, TI_FLAGS($28)	# syscall tracing enabled?
 	and	t0, t1, t0
@@ -113,22 +129,7 @@
 	sd	a7, PT_R11(sp)		# For indirect syscalls
 
 	move	a0, sp
-	/*
-	 * absolute syscall number is in v0 unless we called syscall(__NR_###)
-	 * where the real syscall number is in a0
-	 * note: NR_syscall is the first O32 syscall but the macro is
-	 * only defined when compiling with -mabi=32 (CONFIG_32BIT)
-	 * therefore __NR_O32_Linux is used (4000)
-	 */
-	.set	push
-	.set	reorder
-	subu	t1, v0,  __NR_O32_Linux
-	move	a1, v0
-	bnez	t1, 1f /* __NR_syscall at offset 0 */
-	ld	a1, PT_R4(sp) /* Arg1 for __NR_syscall case */
-	.set	pop
-
-1:	jal	syscall_trace_enter
+	jal	syscall_trace_enter
 
 	bltz	v0, 1f			# seccomp failed? Skip syscall
 
--- linux-qcom-6.8.0.orig/arch/mips/kernel/smp-cps.c
+++ linux-qcom-6.8.0/arch/mips/kernel/smp-cps.c
@@ -222,7 +222,10 @@
 	write_gcr_co_reset_ext_base(CM_GCR_Cx_RESET_EXT_BASE_UEB);
 
 	/* Ensure the core can access the GCRs */
-	set_gcr_access(1 << core);
+	if (mips_cm_revision() < CM_REV_CM3)
+		set_gcr_access(1 << core);
+	else
+		set_gcr_access_cm3(1 << core);
 
 	if (mips_cpc_present()) {
 		/* Reset the core */
--- linux-qcom-6.8.0.orig/arch/mips/kernel/syscalls/syscall_n32.tbl
+++ linux-qcom-6.8.0/arch/mips/kernel/syscalls/syscall_n32.tbl
@@ -354,7 +354,7 @@
 412	n32	utimensat_time64		sys_utimensat
 413	n32	pselect6_time64			compat_sys_pselect6_time64
 414	n32	ppoll_time64			compat_sys_ppoll_time64
-416	n32	io_pgetevents_time64		sys_io_pgetevents
+416	n32	io_pgetevents_time64		compat_sys_io_pgetevents_time64
 417	n32	recvmmsg_time64			compat_sys_recvmmsg_time64
 418	n32	mq_timedsend_time64		sys_mq_timedsend
 419	n32	mq_timedreceive_time64		sys_mq_timedreceive
--- linux-qcom-6.8.0.orig/arch/mips/kernel/syscalls/syscall_o32.tbl
+++ linux-qcom-6.8.0/arch/mips/kernel/syscalls/syscall_o32.tbl
@@ -27,7 +27,7 @@
 17	o32	break				sys_ni_syscall
 # 18 was sys_stat
 18	o32	unused18			sys_ni_syscall
-19	o32	lseek				sys_lseek
+19	o32	lseek				sys_lseek			compat_sys_lseek
 20	o32	getpid				sys_getpid
 21	o32	mount				sys_mount
 22	o32	umount				sys_oldumount
@@ -403,7 +403,7 @@
 412	o32	utimensat_time64		sys_utimensat			sys_utimensat
 413	o32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
 414	o32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
-416	o32	io_pgetevents_time64		sys_io_pgetevents		sys_io_pgetevents
+416	o32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
 417	o32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
 418	o32	mq_timedsend_time64		sys_mq_timedsend		sys_mq_timedsend
 419	o32	mq_timedreceive_time64		sys_mq_timedreceive		sys_mq_timedreceive
--- linux-qcom-6.8.0.orig/arch/mips/loongson64/boardinfo.c
+++ linux-qcom-6.8.0/arch/mips/loongson64/boardinfo.c
@@ -21,13 +21,11 @@
 		       "BIOS Info\n"
 		       "Vendor\t\t\t: %s\n"
 		       "Version\t\t\t: %s\n"
-		       "ROM Size\t\t: %d KB\n"
 		       "Release Date\t\t: %s\n",
 		       strsep(&tmp_board_manufacturer, "-"),
 		       eboard->name,
 		       strsep(&tmp_bios_vendor, "-"),
 		       einter->description,
-		       einter->size,
 		       especial->special_name);
 }
 static struct kobj_attribute boardinfo_attr = __ATTR(boardinfo, 0444,
--- linux-qcom-6.8.0.orig/arch/mips/loongson64/env.c
+++ linux-qcom-6.8.0/arch/mips/loongson64/env.c
@@ -88,6 +88,12 @@
 	cpu_clock_freq = ecpu->cpu_clock_freq;
 	loongson_sysconf.cputype = ecpu->cputype;
 	switch (ecpu->cputype) {
+	case Legacy_2K:
+	case Loongson_2K:
+		smp_group[0] = 0x900000001fe11000;
+		loongson_sysconf.cores_per_node = 2;
+		loongson_sysconf.cores_per_package = 2;
+		break;
 	case Legacy_3A:
 	case Loongson_3A:
 		loongson_sysconf.cores_per_node = 4;
@@ -221,6 +227,8 @@
 		default:
 			break;
 		}
+	} else if ((read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64R) {
+		loongson_fdt_blob = __dtb_loongson64_2core_2k1000_begin;
 	} else if ((read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64G) {
 		if (loongson_sysconf.bridgetype == LS7A)
 			loongson_fdt_blob = __dtb_loongson64g_4core_ls7a_begin;
--- linux-qcom-6.8.0.orig/arch/mips/loongson64/reset.c
+++ linux-qcom-6.8.0/arch/mips/loongson64/reset.c
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/kexec.h>
 #include <linux/pm.h>
+#include <linux/reboot.h>
 #include <linux/slab.h>
 
 #include <asm/bootinfo.h>
@@ -21,36 +22,21 @@
 #include <loongson.h>
 #include <boot_param.h>
 
-static void loongson_restart(char *command)
+static int firmware_restart(struct sys_off_data *unusedd)
 {
 
 	void (*fw_restart)(void) = (void *)loongson_sysconf.restart_addr;
 
 	fw_restart();
-	while (1) {
-		if (cpu_wait)
-			cpu_wait();
-	}
+	return NOTIFY_DONE;
 }
 
-static void loongson_poweroff(void)
+static int firmware_poweroff(struct sys_off_data *unused)
 {
 	void (*fw_poweroff)(void) = (void *)loongson_sysconf.poweroff_addr;
 
 	fw_poweroff();
-	while (1) {
-		if (cpu_wait)
-			cpu_wait();
-	}
-}
-
-static void loongson_halt(void)
-{
-	pr_notice("\n\n** You can safely turn off the power now **\n\n");
-	while (1) {
-		if (cpu_wait)
-			cpu_wait();
-	}
+	return NOTIFY_DONE;
 }
 
 #ifdef CONFIG_KEXEC_CORE
@@ -154,9 +140,17 @@
 
 static int __init mips_reboot_setup(void)
 {
-	_machine_restart = loongson_restart;
-	_machine_halt = loongson_halt;
-	pm_power_off = loongson_poweroff;
+	if (loongson_sysconf.restart_addr) {
+		register_sys_off_handler(SYS_OFF_MODE_RESTART,
+				 SYS_OFF_PRIO_FIRMWARE,
+				 firmware_restart, NULL);
+	}
+
+	if (loongson_sysconf.poweroff_addr) {
+		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
+				 SYS_OFF_PRIO_FIRMWARE,
+				 firmware_poweroff, NULL);
+	}
 
 #ifdef CONFIG_KEXEC_CORE
 	kexec_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL);
--- linux-qcom-6.8.0.orig/arch/mips/loongson64/smp.c
+++ linux-qcom-6.8.0/arch/mips/loongson64/smp.c
@@ -466,12 +466,25 @@
 static void __init loongson3_smp_setup(void)
 {
 	int i = 0, num = 0; /* i: physical id, num: logical id */
+	int max_cpus = 0;
 
 	init_cpu_possible(cpu_none_mask);
 
+	for (i = 0; i < ARRAY_SIZE(smp_group); i++) {
+		if (!smp_group[i])
+			break;
+		max_cpus += loongson_sysconf.cores_per_node;
+	}
+
+	if (max_cpus < loongson_sysconf.nr_cpus) {
+		pr_err("SMP Groups are less than the number of CPUs\n");
+		loongson_sysconf.nr_cpus = max_cpus ? max_cpus : 1;
+	}
+
 	/* For unified kernel, NR_CPUS is the maximum possible value,
 	 * loongson_sysconf.nr_cpus is the really present value
 	 */
+	i = 0;
 	while (i < loongson_sysconf.nr_cpus) {
 		if (loongson_sysconf.reserved_cpus_mask & (1<<i)) {
 			/* Reserved physical CPU cores */
@@ -492,14 +505,14 @@
 		__cpu_logical_map[num] = -1;
 		num++;
 	}
-
 	csr_ipi_probe();
 	ipi_set0_regs_init();
 	ipi_clear0_regs_init();
 	ipi_status0_regs_init();
 	ipi_en0_regs_init();
 	ipi_mailbox_buf_init();
-	ipi_write_enable(0);
+	if (smp_group[0])
+		ipi_write_enable(0);
 
 	cpu_set_core(&cpu_data[0],
 		     cpu_logical_map(0) % loongson_sysconf.cores_per_package);
@@ -818,6 +831,9 @@
 	uint64_t core_id = cpu_core(&cpu_data[cpu]);
 	uint64_t package_id = cpu_data[cpu].package;
 
+	if (!loongson_chipcfg[package_id] || !loongson_freqctrl[package_id])
+		return 0;
+
 	if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
 		LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id));
 	} else {
@@ -832,6 +848,9 @@
 	uint64_t core_id = cpu_core(&cpu_data[cpu]);
 	uint64_t package_id = cpu_data[cpu].package;
 
+	if (!loongson_chipcfg[package_id] || !loongson_freqctrl[package_id])
+		return 0;
+
 	if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1) {
 		LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id);
 	} else {
--- linux-qcom-6.8.0.orig/arch/mips/math-emu/cp1emu.c
+++ linux-qcom-6.8.0/arch/mips/math-emu/cp1emu.c
@@ -1660,7 +1660,7 @@
 		break;
 	}
 
-	case 0x3:
+	case 0x7:
 		if (MIPSInst_FUNC(ir) != pfetch_op)
 			return SIGILL;
 
--- linux-qcom-6.8.0.orig/arch/mips/net/bpf_jit_comp.c
+++ linux-qcom-6.8.0/arch/mips/net/bpf_jit_comp.c
@@ -1012,7 +1012,8 @@
 	bpf_prog_fill_jited_linfo(prog, &ctx.descriptors[1]);
 
 	/* Set as read-only exec and flush instruction cache */
-	bpf_jit_binary_lock_ro(header);
+	if (bpf_jit_binary_lock_ro(header))
+		goto out_err;
 	flush_icache_range((unsigned long)header,
 			   (unsigned long)&ctx.target[ctx.jit_index]);
 
--- linux-qcom-6.8.0.orig/arch/mips/pci/ops-rc32434.c
+++ linux-qcom-6.8.0/arch/mips/pci/ops-rc32434.c
@@ -112,8 +112,8 @@
 	 * gives them time to settle
 	 */
 	if (where == PCI_VENDOR_ID) {
-		if (ret == 0xffffffff || ret == 0x00000000 ||
-		    ret == 0x0000ffff || ret == 0xffff0000) {
+		if (*val == 0xffffffff || *val == 0x00000000 ||
+		    *val == 0x0000ffff || *val == 0xffff0000) {
 			if (delay > 4)
 				return 0;
 			delay *= 2;
--- linux-qcom-6.8.0.orig/arch/mips/pci/pci-legacy.c
+++ linux-qcom-6.8.0/arch/mips/pci/pci-legacy.c
@@ -29,6 +29,14 @@
 
 static int pci_initialized;
 
+unsigned long pci_address_to_pio(phys_addr_t address)
+{
+	if (address > IO_SPACE_LIMIT)
+		return (unsigned long)-1;
+
+	return (unsigned long) address;
+}
+
 /*
  * We need to avoid collisions with `mirrored' VGA ports
  * and other strange ISA hardware, so we always want the
--- linux-qcom-6.8.0.orig/arch/mips/pci/pcie-octeon.c
+++ linux-qcom-6.8.0/arch/mips/pci/pcie-octeon.c
@@ -230,12 +230,18 @@
 {
 	union cvmx_pcie_address pcie_addr;
 	union cvmx_pciercx_cfg006 pciercx_cfg006;
+	union cvmx_pciercx_cfg032 pciercx_cfg032;
 
 	pciercx_cfg006.u32 =
 	    cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG006(pcie_port));
 	if ((bus <= pciercx_cfg006.s.pbnum) && (dev != 0))
 		return 0;
 
+	pciercx_cfg032.u32 =
+		cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
+	if ((pciercx_cfg032.s.dlla == 0) || (pciercx_cfg032.s.lt == 1))
+		return 0;
+
 	pcie_addr.u64 = 0;
 	pcie_addr.config.upper = 2;
 	pcie_addr.config.io = 1;
--- linux-qcom-6.8.0.orig/arch/mips/sgi-ip30/ip30-console.c
+++ linux-qcom-6.8.0/arch/mips/sgi-ip30/ip30-console.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include <linux/io.h>
+#include <linux/processor.h>
 
 #include <asm/sn/ioc3.h>
 #include <asm/setup.h>
--- linux-qcom-6.8.0.orig/arch/nios2/kernel/prom.c
+++ linux-qcom-6.8.0/arch/nios2/kernel/prom.c
@@ -26,12 +26,12 @@
 	if (be32_to_cpup((__be32 *)CONFIG_NIOS2_DTB_PHYS_ADDR) ==
 		 OF_DT_HEADER) {
 		params = (void *)CONFIG_NIOS2_DTB_PHYS_ADDR;
-		early_init_dt_scan(params);
+		early_init_dt_scan(params, __pa(params));
 		return;
 	}
 #endif
 	if (be32_to_cpu((__be32) *dtb) == OF_DT_HEADER)
 		params = (void *)__dtb_start;
 
-	early_init_dt_scan(params);
+	early_init_dt_scan(params, __pa(params));
 }
--- linux-qcom-6.8.0.orig/arch/openrisc/Kconfig
+++ linux-qcom-6.8.0/arch/openrisc/Kconfig
@@ -64,6 +64,9 @@
 config LOCKDEP_SUPPORT
 	def_bool  y
 
+config FIX_EARLYCON_MEM
+	def_bool y
+
 menu "Processor type and features"
 
 choice
--- linux-qcom-6.8.0.orig/arch/openrisc/include/asm/fixmap.h
+++ linux-qcom-6.8.0/arch/openrisc/include/asm/fixmap.h
@@ -26,59 +26,19 @@
 #include <linux/bug.h>
 #include <asm/page.h>
 
-/*
- * On OpenRISC we use these special fixed_addresses for doing ioremap
- * early in the boot process before memory initialization is complete.
- * This is used, in particular, by the early serial console code.
- *
- * It's not really 'fixmap', per se, but fits loosely into the same
- * paradigm.
- */
 enum fixed_addresses {
-	/*
-	 * FIX_IOREMAP entries are useful for mapping physical address
-	 * space before ioremap() is useable, e.g. really early in boot
-	 * before kmalloc() is working.
-	 */
-#define FIX_N_IOREMAPS  32
-	FIX_IOREMAP_BEGIN,
-	FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS - 1,
+	FIX_EARLYCON_MEM_BASE,
 	__end_of_fixed_addresses
 };
 
 #define FIXADDR_SIZE		(__end_of_fixed_addresses << PAGE_SHIFT)
 /* FIXADDR_BOTTOM might be a better name here... */
 #define FIXADDR_START		(FIXADDR_TOP - FIXADDR_SIZE)
+#define FIXMAP_PAGE_IO		PAGE_KERNEL_NOCACHE
 
-#define __fix_to_virt(x)	(FIXADDR_TOP - ((x) << PAGE_SHIFT))
-#define __virt_to_fix(x)	((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
+extern void __set_fixmap(enum fixed_addresses idx,
+			 phys_addr_t phys, pgprot_t flags);
 
-/*
- * 'index to address' translation. If anyone tries to use the idx
- * directly without tranlation, we catch the bug with a NULL-deference
- * kernel oops. Illegal ranges of incoming indices are caught too.
- */
-static __always_inline unsigned long fix_to_virt(const unsigned int idx)
-{
-	/*
-	 * this branch gets completely eliminated after inlining,
-	 * except when someone tries to use fixaddr indices in an
-	 * illegal way. (such as mixing up address types or using
-	 * out-of-range indices).
-	 *
-	 * If it doesn't get removed, the linker will complain
-	 * loudly with a reasonably clear error message..
-	 */
-	if (idx >= __end_of_fixed_addresses)
-		BUG();
-
-	return __fix_to_virt(idx);
-}
-
-static inline unsigned long virt_to_fix(const unsigned long vaddr)
-{
-	BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
-	return __virt_to_fix(vaddr);
-}
+#include <asm-generic/fixmap.h>
 
 #endif
--- linux-qcom-6.8.0.orig/arch/openrisc/kernel/prom.c
+++ linux-qcom-6.8.0/arch/openrisc/kernel/prom.c
@@ -22,6 +22,6 @@
 
 void __init early_init_devtree(void *params)
 {
-	early_init_dt_scan(params);
+	early_init_dt_scan(params, __pa(params));
 	memblock_allow_resize();
 }
--- linux-qcom-6.8.0.orig/arch/openrisc/kernel/setup.c
+++ linux-qcom-6.8.0/arch/openrisc/kernel/setup.c
@@ -255,6 +255,9 @@
 
 void __init setup_arch(char **cmdline_p)
 {
+	/* setup memblock allocator */
+	setup_memory();
+
 	unflatten_and_copy_device_tree();
 
 	setup_cpuinfo();
@@ -278,9 +281,6 @@
 	}
 #endif
 
-	/* setup memblock allocator */
-	setup_memory();
-
 	/* paging_init() sets up the MMU and marks all pages as reserved */
 	paging_init();
 
--- linux-qcom-6.8.0.orig/arch/openrisc/kernel/traps.c
+++ linux-qcom-6.8.0/arch/openrisc/kernel/traps.c
@@ -180,29 +180,39 @@
 
 asmlinkage void do_fpe_trap(struct pt_regs *regs, unsigned long address)
 {
-	int code = FPE_FLTUNK;
-	unsigned long fpcsr = regs->fpcsr;
-
-	if (fpcsr & SPR_FPCSR_IVF)
-		code = FPE_FLTINV;
-	else if (fpcsr & SPR_FPCSR_OVF)
-		code = FPE_FLTOVF;
-	else if (fpcsr & SPR_FPCSR_UNF)
-		code = FPE_FLTUND;
-	else if (fpcsr & SPR_FPCSR_DZF)
-		code = FPE_FLTDIV;
-	else if (fpcsr & SPR_FPCSR_IXF)
-		code = FPE_FLTRES;
-
-	/* Clear all flags */
-	regs->fpcsr &= ~SPR_FPCSR_ALLF;
-
-	force_sig_fault(SIGFPE, code, (void __user *)regs->pc);
+	if (user_mode(regs)) {
+		int code = FPE_FLTUNK;
+		unsigned long fpcsr = regs->fpcsr;
+
+		if (fpcsr & SPR_FPCSR_IVF)
+			code = FPE_FLTINV;
+		else if (fpcsr & SPR_FPCSR_OVF)
+			code = FPE_FLTOVF;
+		else if (fpcsr & SPR_FPCSR_UNF)
+			code = FPE_FLTUND;
+		else if (fpcsr & SPR_FPCSR_DZF)
+			code = FPE_FLTDIV;
+		else if (fpcsr & SPR_FPCSR_IXF)
+			code = FPE_FLTRES;
+
+		/* Clear all flags */
+		regs->fpcsr &= ~SPR_FPCSR_ALLF;
+
+		force_sig_fault(SIGFPE, code, (void __user *)regs->pc);
+	} else {
+		pr_emerg("KERNEL: Illegal fpe exception 0x%.8lx\n", regs->pc);
+		die("Die:", regs, SIGFPE);
+	}
 }
 
 asmlinkage void do_trap(struct pt_regs *regs, unsigned long address)
 {
-	force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc);
+	if (user_mode(regs)) {
+		force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->pc);
+	} else {
+		pr_emerg("KERNEL: Illegal trap exception 0x%.8lx\n", regs->pc);
+		die("Die:", regs, SIGILL);
+	}
 }
 
 asmlinkage void do_unaligned_access(struct pt_regs *regs, unsigned long address)
--- linux-qcom-6.8.0.orig/arch/openrisc/mm/init.c
+++ linux-qcom-6.8.0/arch/openrisc/mm/init.c
@@ -207,6 +207,43 @@
 	return;
 }
 
+static int __init map_page(unsigned long va, phys_addr_t pa, pgprot_t prot)
+{
+	p4d_t *p4d;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+
+	p4d = p4d_offset(pgd_offset_k(va), va);
+	pud = pud_offset(p4d, va);
+	pmd = pmd_offset(pud, va);
+	pte = pte_alloc_kernel(pmd, va);
+
+	if (pte == NULL)
+		return -ENOMEM;
+
+	if (pgprot_val(prot))
+		set_pte_at(&init_mm, va, pte, pfn_pte(pa >> PAGE_SHIFT, prot));
+	else
+		pte_clear(&init_mm, va, pte);
+
+	local_flush_tlb_page(NULL, va);
+	return 0;
+}
+
+void __init __set_fixmap(enum fixed_addresses idx,
+			 phys_addr_t phys, pgprot_t prot)
+{
+	unsigned long address = __fix_to_virt(idx);
+
+	if (idx >= __end_of_fixed_addresses) {
+		BUG();
+		return;
+	}
+
+	map_page(address, phys, prot);
+}
+
 static const pgprot_t protection_map[16] = {
 	[VM_NONE]					= PAGE_NONE,
 	[VM_READ]					= PAGE_READONLY_X,
--- linux-qcom-6.8.0.orig/arch/parisc/Kconfig
+++ linux-qcom-6.8.0/arch/parisc/Kconfig
@@ -12,12 +12,14 @@
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_STRICT_KERNEL_RWX
 	select ARCH_HAS_STRICT_MODULE_RWX
-	select ARCH_HAS_UBSAN_SANITIZE_ALL
+	select ARCH_HAS_UBSAN
 	select ARCH_HAS_PTE_SPECIAL
 	select ARCH_NO_SG_CHAIN
+	select ARCH_SPLIT_ARG64 if !64BIT
 	select ARCH_SUPPORTS_HUGETLBFS if PA20
 	select ARCH_SUPPORTS_MEMORY_FAILURE
 	select ARCH_STACKWALK
+	select ARCH_HAS_CACHE_LINE_SIZE
 	select ARCH_HAS_DEBUG_VM_PGTABLE
 	select HAVE_RELIABLE_STACKTRACE
 	select DMA_OPS
@@ -56,8 +58,8 @@
 	select HAVE_ARCH_MMAP_RND_BITS
 	select HAVE_ARCH_AUDITSYSCALL
 	select HAVE_ARCH_HASH
-	select HAVE_ARCH_JUMP_LABEL
-	select HAVE_ARCH_JUMP_LABEL_RELATIVE
+	# select HAVE_ARCH_JUMP_LABEL
+	# select HAVE_ARCH_JUMP_LABEL_RELATIVE
 	select HAVE_ARCH_KFENCE
 	select HAVE_ARCH_SECCOMP_FILTER
 	select HAVE_ARCH_TRACEHOOK
@@ -84,6 +86,7 @@
 	select HAVE_SOFTIRQ_ON_OWN_STACK if IRQSTACKS
 	select TRACE_IRQFLAGS_SUPPORT
 	select HAVE_FUNCTION_DESCRIPTORS if 64BIT
+	select PCI_MSI_ARCH_FALLBACKS if PCI_MSI
 
 	help
 	  The PA-RISC microprocessor is designed by Hewlett-Packard and used
--- linux-qcom-6.8.0.orig/arch/parisc/include/asm/assembly.h
+++ linux-qcom-6.8.0/arch/parisc/include/asm/assembly.h
@@ -97,26 +97,28 @@
 	 * version takes two arguments: a src and destination register.
 	 * However, the source and destination registers can not be
 	 * the same register.
+	 *
+	 * We use add,l to avoid clobbering the C/B bits in the PSW.
 	 */
 
 	.macro  tophys  grvirt, grphys
-	ldil    L%(__PAGE_OFFSET), \grphys
-	sub     \grvirt, \grphys, \grphys
+	ldil    L%(-__PAGE_OFFSET), \grphys
+	addl    \grvirt, \grphys, \grphys
 	.endm
-	
+
 	.macro  tovirt  grphys, grvirt
 	ldil    L%(__PAGE_OFFSET), \grvirt
-	add     \grphys, \grvirt, \grvirt
+	addl    \grphys, \grvirt, \grvirt
 	.endm
 
 	.macro  tophys_r1  gr
-	ldil    L%(__PAGE_OFFSET), %r1
-	sub     \gr, %r1, \gr
+	ldil    L%(-__PAGE_OFFSET), %r1
+	addl    \gr, %r1, \gr
 	.endm
-	
+
 	.macro  tovirt_r1  gr
 	ldil    L%(__PAGE_OFFSET), %r1
-	add     \gr, %r1, \gr
+	addl    \gr, %r1, \gr
 	.endm
 
 	.macro delay value
--- linux-qcom-6.8.0.orig/arch/parisc/include/asm/cache.h
+++ linux-qcom-6.8.0/arch/parisc/include/asm/cache.h
@@ -20,7 +20,16 @@
 
 #define SMP_CACHE_BYTES L1_CACHE_BYTES
 
-#define ARCH_DMA_MINALIGN	L1_CACHE_BYTES
+#ifdef CONFIG_PA20
+#define ARCH_DMA_MINALIGN	128
+#else
+#define ARCH_DMA_MINALIGN	32
+#endif
+#define ARCH_KMALLOC_MINALIGN	16	/* ldcw requires 16-byte alignment */
+
+#define arch_slab_minalign()	((unsigned)dcache_stride)
+#define cache_line_size()	dcache_stride
+#define dma_get_cache_alignment cache_line_size
 
 #define __read_mostly __section(".data..read_mostly")
 
--- linux-qcom-6.8.0.orig/arch/parisc/include/asm/cacheflush.h
+++ linux-qcom-6.8.0/arch/parisc/include/asm/cacheflush.h
@@ -31,18 +31,17 @@
 void flush_cache_all(void);
 void flush_cache_mm(struct mm_struct *mm);
 
-void flush_kernel_dcache_page_addr(const void *addr);
-
 #define flush_kernel_dcache_range(start,size) \
 	flush_kernel_dcache_range_asm((start), (start)+(size));
 
+/* The only way to flush a vmap range is to flush whole cache */
 #define ARCH_IMPLEMENTS_FLUSH_KERNEL_VMAP_RANGE 1
 void flush_kernel_vmap_range(void *vaddr, int size);
 void invalidate_kernel_vmap_range(void *vaddr, int size);
 
-#define flush_cache_vmap(start, end)		flush_cache_all()
+void flush_cache_vmap(unsigned long start, unsigned long end);
 #define flush_cache_vmap_early(start, end)	do { } while (0)
-#define flush_cache_vunmap(start, end)		flush_cache_all()
+void flush_cache_vunmap(unsigned long start, unsigned long end);
 
 void flush_dcache_folio(struct folio *folio);
 #define flush_dcache_folio flush_dcache_folio
@@ -77,17 +76,11 @@
 void flush_cache_range(struct vm_area_struct *vma,
 		unsigned long start, unsigned long end);
 
-/* defined in pacache.S exported in cache.c used by flush_anon_page */
-void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
-
 #define ARCH_HAS_FLUSH_ANON_PAGE
 void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr);
 
 #define ARCH_HAS_FLUSH_ON_KUNMAP
-static inline void kunmap_flush_on_unmap(const void *addr)
-{
-	flush_kernel_dcache_page_addr(addr);
-}
+void kunmap_flush_on_unmap(const void *addr);
 
 #endif /* _PARISC_CACHEFLUSH_H */
 
--- linux-qcom-6.8.0.orig/arch/parisc/include/asm/checksum.h
+++ linux-qcom-6.8.0/arch/parisc/include/asm/checksum.h
@@ -40,7 +40,7 @@
 "	addc		%0, %5, %0\n"
 "	addc		%0, %3, %0\n"
 "1:	ldws,ma		4(%1), %3\n"
-"	addib,<		0, %2, 1b\n"
+"	addib,>		-1, %2, 1b\n"
 "	addc		%0, %3, %0\n"
 "\n"
 "	extru		%0, 31, 16, %4\n"
@@ -126,6 +126,7 @@
 	** Try to keep 4 registers with "live" values ahead of the ALU.
 	*/
 
+"	depdi		0, 31, 32, %0\n"/* clear upper half of incoming checksum */
 "	ldd,ma		8(%1), %4\n"	/* get 1st saddr word */
 "	ldd,ma		8(%2), %5\n"	/* get 1st daddr word */
 "	add		%4, %0, %0\n"
@@ -137,8 +138,8 @@
 "	add,dc		%3, %0, %0\n"  /* fold in proto+len | carry bit */
 "	extrd,u		%0, 31, 32, %4\n"/* copy upper half down */
 "	depdi		0, 31, 32, %0\n"/* clear upper half */
-"	add		%4, %0, %0\n"	/* fold into 32-bits */
-"	addc		0, %0, %0\n"	/* add carry */
+"	add,dc		%4, %0, %0\n"	/* fold into 32-bits, plus carry */
+"	addc		0, %0, %0\n"	/* add final carry */
 
 #else
 
@@ -163,7 +164,8 @@
 "	ldw,ma		4(%2), %7\n"	/* 4th daddr */
 "	addc		%6, %0, %0\n"
 "	addc		%7, %0, %0\n"
-"	addc		%3, %0, %0\n"	/* fold in proto+len, catch carry */
+"	addc		%3, %0, %0\n"	/* fold in proto+len */
+"	addc		0, %0, %0\n"	/* add carry */
 
 #endif
 	: "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len),
--- linux-qcom-6.8.0.orig/arch/parisc/include/asm/mman.h
+++ linux-qcom-6.8.0/arch/parisc/include/asm/mman.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_MMAN_H__
+#define __ASM_MMAN_H__
+
+#include <linux/fs.h>
+#include <uapi/asm/mman.h>
+
+/* PARISC cannot allow mdwe as it needs writable stacks */
+static inline bool arch_memory_deny_write_exec_supported(void)
+{
+	return false;
+}
+#define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported
+
+static inline unsigned long arch_calc_vm_flag_bits(struct file *file, unsigned long flags)
+{
+	/*
+	 * The stack on parisc grows upwards, so if userspace requests memory
+	 * for a stack, mark it with VM_GROWSUP so that the stack expansion in
+	 * the fault handler will work.
+	 */
+	if (flags & MAP_STACK)
+		return VM_GROWSUP;
+
+	return 0;
+}
+#define arch_calc_vm_flag_bits(file, flags) arch_calc_vm_flag_bits(file, flags)
+
+#endif /* __ASM_MMAN_H__ */
--- linux-qcom-6.8.0.orig/arch/parisc/include/asm/page.h
+++ linux-qcom-6.8.0/arch/parisc/include/asm/page.h
@@ -16,6 +16,7 @@
 #define PAGE_SIZE	(_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK	(~(PAGE_SIZE-1))
 
+#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
 
 #ifndef __ASSEMBLY__
 
--- linux-qcom-6.8.0.orig/arch/parisc/include/asm/pgtable.h
+++ linux-qcom-6.8.0/arch/parisc/include/asm/pgtable.h
@@ -448,14 +448,17 @@
 	return pte;
 }
 
+static inline pte_t ptep_get(pte_t *ptep)
+{
+	return READ_ONCE(*ptep);
+}
+#define ptep_get ptep_get
+
 static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep)
 {
 	pte_t pte;
 
-	if (!pte_young(*ptep))
-		return 0;
-
-	pte = *ptep;
+	pte = ptep_get(ptep);
 	if (!pte_young(pte)) {
 		return 0;
 	}
@@ -463,17 +466,10 @@
 	return 1;
 }
 
-struct mm_struct;
-static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
-	pte_t old_pte;
-
-	old_pte = *ptep;
-	set_pte(ptep, __pte(0));
-
-	return old_pte;
-}
+int ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep);
+pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep);
 
+struct mm_struct;
 static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
 	set_pte(ptep, pte_wrprotect(*ptep));
@@ -511,7 +507,8 @@
 #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
 
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
-#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
+#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
 #define __HAVE_ARCH_PTE_SAME
 
--- linux-qcom-6.8.0.orig/arch/parisc/include/asm/signal.h
+++ linux-qcom-6.8.0/arch/parisc/include/asm/signal.h
@@ -4,23 +4,11 @@
 
 #include <uapi/asm/signal.h>
 
-#define _NSIG		64
-/* bits-per-word, where word apparently means 'long' not 'int' */
-#define _NSIG_BPW	BITS_PER_LONG
-#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
-
 # ifndef __ASSEMBLY__
 
 /* Most things should be clean enough to redefine this at will, if care
    is taken to make libc match.  */
 
-typedef unsigned long old_sigset_t;		/* at least 32 bits */
-
-typedef struct {
-	/* next_signal() assumes this is a long - no choice */
-	unsigned long sig[_NSIG_WORDS];
-} sigset_t;
-
 #include <asm/sigcontext.h>
 
 #endif /* !__ASSEMBLY */
--- linux-qcom-6.8.0.orig/arch/parisc/include/uapi/asm/signal.h
+++ linux-qcom-6.8.0/arch/parisc/include/uapi/asm/signal.h
@@ -57,10 +57,20 @@
 
 #include <asm-generic/signal-defs.h>
 
+#define _NSIG		64
+#define _NSIG_BPW	(sizeof(unsigned long) * 8)
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
 # ifndef __ASSEMBLY__
 
 #  include <linux/types.h>
 
+typedef unsigned long old_sigset_t;	/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
 /* Avoid too many header ordering problems.  */
 struct siginfo;
 
--- linux-qcom-6.8.0.orig/arch/parisc/kernel/cache.c
+++ linux-qcom-6.8.0/arch/parisc/kernel/cache.c
@@ -20,6 +20,7 @@
 #include <linux/sched.h>
 #include <linux/sched/mm.h>
 #include <linux/syscalls.h>
+#include <linux/vmalloc.h>
 #include <asm/pdc.h>
 #include <asm/cache.h>
 #include <asm/cacheflush.h>
@@ -31,20 +32,31 @@
 #include <asm/mmu_context.h>
 #include <asm/cachectl.h>
 
+#define PTR_PAGE_ALIGN_DOWN(addr) PTR_ALIGN_DOWN(addr, PAGE_SIZE)
+
+/*
+ * When nonzero, use _PAGE_ACCESSED bit to try to reduce the number
+ * of page flushes done flush_cache_page_if_present. There are some
+ * pros and cons in using this option. It may increase the risk of
+ * random segmentation faults.
+ */
+#define CONFIG_FLUSH_PAGE_ACCESSED	0
+
 int split_tlb __ro_after_init;
 int dcache_stride __ro_after_init;
 int icache_stride __ro_after_init;
 EXPORT_SYMBOL(dcache_stride);
 
+/* Internal implementation in arch/parisc/kernel/pacache.S */
 void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
 EXPORT_SYMBOL(flush_dcache_page_asm);
 void purge_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
 void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr);
-
-/* Internal implementation in arch/parisc/kernel/pacache.S */
 void flush_data_cache_local(void *);  /* flushes local data-cache only */
 void flush_instruction_cache_local(void); /* flushes local code-cache only */
 
+static void flush_kernel_dcache_page_addr(const void *addr);
+
 /* On some machines (i.e., ones with the Merced bus), there can be
  * only a single PxTLB broadcast at a time; this must be guaranteed
  * by software. We need a spinlock around all TLB flushes to ensure
@@ -321,6 +333,18 @@
 {
 	if (!static_branch_likely(&parisc_has_cache))
 		return;
+
+	/*
+	 * The TLB is the engine of coherence on parisc.  The CPU is
+	 * entitled to speculate any page with a TLB mapping, so here
+	 * we kill the mapping then flush the page along a special flush
+	 * only alias mapping. This guarantees that the page is no-longer
+	 * in the cache for any process and nor may it be speculatively
+	 * read in (until the user or kernel specifically accesses it,
+	 * of course).
+	 */
+	flush_tlb_page(vma, vmaddr);
+
 	preempt_disable();
 	flush_dcache_page_asm(physaddr, vmaddr);
 	if (vma->vm_flags & VM_EXEC)
@@ -328,46 +352,44 @@
 	preempt_enable();
 }
 
-static void flush_user_cache_page(struct vm_area_struct *vma, unsigned long vmaddr)
+static void flush_kernel_dcache_page_addr(const void *addr)
 {
-	unsigned long flags, space, pgd, prot;
-#ifdef CONFIG_TLB_PTLOCK
-	unsigned long pgd_lock;
-#endif
+	unsigned long vaddr = (unsigned long)addr;
+	unsigned long flags;
 
-	vmaddr &= PAGE_MASK;
+	/* Purge TLB entry to remove translation on all CPUs */
+	purge_tlb_start(flags);
+	pdtlb(SR_KERNEL, addr);
+	purge_tlb_end(flags);
 
+	/* Use tmpalias flush to prevent data cache move-in */
 	preempt_disable();
+	flush_dcache_page_asm(__pa(vaddr), vaddr);
+	preempt_enable();
+}
 
-	/* Set context for flush */
-	local_irq_save(flags);
-	prot = mfctl(8);
-	space = mfsp(SR_USER);
-	pgd = mfctl(25);
-#ifdef CONFIG_TLB_PTLOCK
-	pgd_lock = mfctl(28);
-#endif
-	switch_mm_irqs_off(NULL, vma->vm_mm, NULL);
-	local_irq_restore(flags);
-
-	flush_user_dcache_range_asm(vmaddr, vmaddr + PAGE_SIZE);
-	if (vma->vm_flags & VM_EXEC)
-		flush_user_icache_range_asm(vmaddr, vmaddr + PAGE_SIZE);
-	flush_tlb_page(vma, vmaddr);
+static void flush_kernel_icache_page_addr(const void *addr)
+{
+	unsigned long vaddr = (unsigned long)addr;
+	unsigned long flags;
 
-	/* Restore previous context */
-	local_irq_save(flags);
-#ifdef CONFIG_TLB_PTLOCK
-	mtctl(pgd_lock, 28);
-#endif
-	mtctl(pgd, 25);
-	mtsp(space, SR_USER);
-	mtctl(prot, 8);
-	local_irq_restore(flags);
+	/* Purge TLB entry to remove translation on all CPUs */
+	purge_tlb_start(flags);
+	pdtlb(SR_KERNEL, addr);
+	purge_tlb_end(flags);
 
+	/* Use tmpalias flush to prevent instruction cache move-in */
+	preempt_disable();
+	flush_icache_page_asm(__pa(vaddr), vaddr);
 	preempt_enable();
 }
 
+void kunmap_flush_on_unmap(const void *addr)
+{
+	flush_kernel_dcache_page_addr(addr);
+}
+EXPORT_SYMBOL(kunmap_flush_on_unmap);
+
 void flush_icache_pages(struct vm_area_struct *vma, struct page *page,
 		unsigned int nr)
 {
@@ -375,13 +397,16 @@
 
 	for (;;) {
 		flush_kernel_dcache_page_addr(kaddr);
-		flush_kernel_icache_page(kaddr);
+		flush_kernel_icache_page_addr(kaddr);
 		if (--nr == 0)
 			break;
 		kaddr += PAGE_SIZE;
 	}
 }
 
+/*
+ * Walk page directory for MM to find PTEP pointer for address ADDR.
+ */
 static inline pte_t *get_ptep(struct mm_struct *mm, unsigned long addr)
 {
 	pte_t *ptep = NULL;
@@ -410,6 +435,41 @@
 		== (_PAGE_PRESENT | _PAGE_ACCESSED);
 }
 
+/*
+ * Return user physical address. Returns 0 if page is not present.
+ */
+static inline unsigned long get_upa(struct mm_struct *mm, unsigned long addr)
+{
+	unsigned long flags, space, pgd, prot, pa;
+#ifdef CONFIG_TLB_PTLOCK
+	unsigned long pgd_lock;
+#endif
+
+	/* Save context */
+	local_irq_save(flags);
+	prot = mfctl(8);
+	space = mfsp(SR_USER);
+	pgd = mfctl(25);
+#ifdef CONFIG_TLB_PTLOCK
+	pgd_lock = mfctl(28);
+#endif
+
+	/* Set context for lpa_user */
+	switch_mm_irqs_off(NULL, mm, NULL);
+	pa = lpa_user(addr);
+
+	/* Restore previous context */
+#ifdef CONFIG_TLB_PTLOCK
+	mtctl(pgd_lock, 28);
+#endif
+	mtctl(pgd, 25);
+	mtsp(space, SR_USER);
+	mtctl(prot, 8);
+	local_irq_restore(flags);
+
+	return pa;
+}
+
 void flush_dcache_folio(struct folio *folio)
 {
 	struct address_space *mapping = folio_flush_mapping(folio);
@@ -458,50 +518,23 @@
 		if (addr + nr * PAGE_SIZE > vma->vm_end)
 			nr = (vma->vm_end - addr) / PAGE_SIZE;
 
-		if (parisc_requires_coherency()) {
-			for (i = 0; i < nr; i++) {
-				pte_t *ptep = get_ptep(vma->vm_mm,
-							addr + i * PAGE_SIZE);
-				if (!ptep)
-					continue;
-				if (pte_needs_flush(*ptep))
-					flush_user_cache_page(vma,
-							addr + i * PAGE_SIZE);
-				/* Optimise accesses to the same table? */
-				pte_unmap(ptep);
-			}
-		} else {
+		if (old_addr == 0 || (old_addr & (SHM_COLOUR - 1))
+					!= (addr & (SHM_COLOUR - 1))) {
+			for (i = 0; i < nr; i++)
+				__flush_cache_page(vma,
+					addr + i * PAGE_SIZE,
+					(pfn + i) * PAGE_SIZE);
 			/*
-			 * The TLB is the engine of coherence on parisc:
-			 * The CPU is entitled to speculate any page
-			 * with a TLB mapping, so here we kill the
-			 * mapping then flush the page along a special
-			 * flush only alias mapping. This guarantees that
-			 * the page is no-longer in the cache for any
-			 * process and nor may it be speculatively read
-			 * in (until the user or kernel specifically
-			 * accesses it, of course)
+			 * Software is allowed to have any number
+			 * of private mappings to a page.
 			 */
-			for (i = 0; i < nr; i++)
-				flush_tlb_page(vma, addr + i * PAGE_SIZE);
-			if (old_addr == 0 || (old_addr & (SHM_COLOUR - 1))
-					!= (addr & (SHM_COLOUR - 1))) {
-				for (i = 0; i < nr; i++)
-					__flush_cache_page(vma,
-						addr + i * PAGE_SIZE,
-						(pfn + i) * PAGE_SIZE);
-				/*
-				 * Software is allowed to have any number
-				 * of private mappings to a page.
-				 */
-				if (!(vma->vm_flags & VM_SHARED))
-					continue;
-				if (old_addr)
-					pr_err("INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %pD\n",
-						old_addr, addr, vma->vm_file);
-				if (nr == folio_nr_pages(folio))
-					old_addr = addr;
-			}
+			if (!(vma->vm_flags & VM_SHARED))
+				continue;
+			if (old_addr)
+				pr_err("INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %pD\n",
+					old_addr, addr, vma->vm_file);
+			if (nr == folio_nr_pages(folio))
+				old_addr = addr;
 		}
 		WARN_ON(++count == 4096);
 	}
@@ -591,35 +624,28 @@
 extern void clear_user_page_asm(void *, unsigned long);
 extern void copy_user_page_asm(void *, void *, unsigned long);
 
-void flush_kernel_dcache_page_addr(const void *addr)
-{
-	unsigned long flags;
-
-	flush_kernel_dcache_page_asm(addr);
-	purge_tlb_start(flags);
-	pdtlb(SR_KERNEL, addr);
-	purge_tlb_end(flags);
-}
-EXPORT_SYMBOL(flush_kernel_dcache_page_addr);
-
 static void flush_cache_page_if_present(struct vm_area_struct *vma,
-	unsigned long vmaddr, unsigned long pfn)
+	unsigned long vmaddr)
 {
+#if CONFIG_FLUSH_PAGE_ACCESSED
 	bool needs_flush = false;
-	pte_t *ptep;
+	pte_t *ptep, pte;
 
-	/*
-	 * The pte check is racy and sometimes the flush will trigger
-	 * a non-access TLB miss. Hopefully, the page has already been
-	 * flushed.
-	 */
 	ptep = get_ptep(vma->vm_mm, vmaddr);
 	if (ptep) {
-		needs_flush = pte_needs_flush(*ptep);
+		pte = ptep_get(ptep);
+		needs_flush = pte_needs_flush(pte);
 		pte_unmap(ptep);
 	}
 	if (needs_flush)
-		flush_cache_page(vma, vmaddr, pfn);
+		__flush_cache_page(vma, vmaddr, PFN_PHYS(pte_pfn(pte)));
+#else
+	struct mm_struct *mm = vma->vm_mm;
+	unsigned long physaddr = get_upa(mm, vmaddr);
+
+	if (physaddr)
+		__flush_cache_page(vma, vmaddr, PAGE_ALIGN_DOWN(physaddr));
+#endif
 }
 
 void copy_user_highpage(struct page *to, struct page *from,
@@ -629,7 +655,7 @@
 
 	kfrom = kmap_local_page(from);
 	kto = kmap_local_page(to);
-	flush_cache_page_if_present(vma, vaddr, page_to_pfn(from));
+	__flush_cache_page(vma, vaddr, PFN_PHYS(page_to_pfn(from)));
 	copy_page_asm(kto, kfrom);
 	kunmap_local(kto);
 	kunmap_local(kfrom);
@@ -638,16 +664,17 @@
 void copy_to_user_page(struct vm_area_struct *vma, struct page *page,
 		unsigned long user_vaddr, void *dst, void *src, int len)
 {
-	flush_cache_page_if_present(vma, user_vaddr, page_to_pfn(page));
+	__flush_cache_page(vma, user_vaddr, PFN_PHYS(page_to_pfn(page)));
 	memcpy(dst, src, len);
-	flush_kernel_dcache_range_asm((unsigned long)dst, (unsigned long)dst + len);
+	flush_kernel_dcache_page_addr(PTR_PAGE_ALIGN_DOWN(dst));
 }
 
 void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
 		unsigned long user_vaddr, void *dst, void *src, int len)
 {
-	flush_cache_page_if_present(vma, user_vaddr, page_to_pfn(page));
+	__flush_cache_page(vma, user_vaddr, PFN_PHYS(page_to_pfn(page)));
 	memcpy(dst, src, len);
+	flush_kernel_dcache_page_addr(PTR_PAGE_ALIGN_DOWN(src));
 }
 
 /* __flush_tlb_range()
@@ -681,32 +708,10 @@
 
 static void flush_cache_pages(struct vm_area_struct *vma, unsigned long start, unsigned long end)
 {
-	unsigned long addr, pfn;
-	pte_t *ptep;
+	unsigned long addr;
 
-	for (addr = start; addr < end; addr += PAGE_SIZE) {
-		bool needs_flush = false;
-		/*
-		 * The vma can contain pages that aren't present. Although
-		 * the pte search is expensive, we need the pte to find the
-		 * page pfn and to check whether the page should be flushed.
-		 */
-		ptep = get_ptep(vma->vm_mm, addr);
-		if (ptep) {
-			needs_flush = pte_needs_flush(*ptep);
-			pfn = pte_pfn(*ptep);
-			pte_unmap(ptep);
-		}
-		if (needs_flush) {
-			if (parisc_requires_coherency()) {
-				flush_user_cache_page(vma, addr);
-			} else {
-				if (WARN_ON(!pfn_valid(pfn)))
-					return;
-				__flush_cache_page(vma, addr, PFN_PHYS(pfn));
-			}
-		}
-	}
+	for (addr = start; addr < end; addr += PAGE_SIZE)
+		flush_cache_page_if_present(vma, addr);
 }
 
 static inline unsigned long mm_total_size(struct mm_struct *mm)
@@ -757,21 +762,19 @@
 		if (WARN_ON(IS_ENABLED(CONFIG_SMP) && arch_irqs_disabled()))
 			return;
 		flush_tlb_range(vma, start, end);
-		flush_cache_all();
+		if (vma->vm_flags & VM_EXEC)
+			flush_cache_all();
+		else
+			flush_data_cache();
 		return;
 	}
 
-	flush_cache_pages(vma, start, end);
+	flush_cache_pages(vma, start & PAGE_MASK, end);
 }
 
 void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long pfn)
 {
-	if (WARN_ON(!pfn_valid(pfn)))
-		return;
-	if (parisc_requires_coherency())
-		flush_user_cache_page(vma, vmaddr);
-	else
-		__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
+	__flush_cache_page(vma, vmaddr, PFN_PHYS(pfn));
 }
 
 void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
@@ -779,34 +782,133 @@
 	if (!PageAnon(page))
 		return;
 
-	if (parisc_requires_coherency()) {
-		if (vma->vm_flags & VM_SHARED)
-			flush_data_cache();
-		else
-			flush_user_cache_page(vma, vmaddr);
+	__flush_cache_page(vma, vmaddr, PFN_PHYS(page_to_pfn(page)));
+}
+
+int ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long addr,
+			   pte_t *ptep)
+{
+	pte_t pte = ptep_get(ptep);
+
+	if (!pte_young(pte))
+		return 0;
+	set_pte(ptep, pte_mkold(pte));
+#if CONFIG_FLUSH_PAGE_ACCESSED
+	__flush_cache_page(vma, addr, PFN_PHYS(pte_pfn(pte)));
+#endif
+	return 1;
+}
+
+/*
+ * After a PTE is cleared, we have no way to flush the cache for
+ * the physical page. On PA8800 and PA8900 processors, these lines
+ * can cause random cache corruption. Thus, we must flush the cache
+ * as well as the TLB when clearing a PTE that's valid.
+ */
+pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr,
+		       pte_t *ptep)
+{
+	struct mm_struct *mm = (vma)->vm_mm;
+	pte_t pte = ptep_get_and_clear(mm, addr, ptep);
+	unsigned long pfn = pte_pfn(pte);
+
+	if (pfn_valid(pfn))
+		__flush_cache_page(vma, addr, PFN_PHYS(pfn));
+	else if (pte_accessible(mm, pte))
+		flush_tlb_page(vma, addr);
+
+	return pte;
+}
+
+/*
+ * The physical address for pages in the ioremap case can be obtained
+ * from the vm_struct struct. I wasn't able to successfully handle the
+ * vmalloc and vmap cases. We have an array of struct page pointers in
+ * the uninitialized vmalloc case but the flush failed using page_to_pfn.
+ */
+void flush_cache_vmap(unsigned long start, unsigned long end)
+{
+	unsigned long addr, physaddr;
+	struct vm_struct *vm;
+
+	/* Prevent cache move-in */
+	flush_tlb_kernel_range(start, end);
+
+	if (end - start >= parisc_cache_flush_threshold) {
+		flush_cache_all();
 		return;
 	}
 
-	flush_tlb_page(vma, vmaddr);
-	preempt_disable();
-	flush_dcache_page_asm(page_to_phys(page), vmaddr);
-	preempt_enable();
+	if (WARN_ON_ONCE(!is_vmalloc_addr((void *)start))) {
+		flush_cache_all();
+		return;
+	}
+
+	vm = find_vm_area((void *)start);
+	if (WARN_ON_ONCE(!vm)) {
+		flush_cache_all();
+		return;
+	}
+
+	/* The physical addresses of IOREMAP regions are contiguous */
+	if (vm->flags & VM_IOREMAP) {
+		physaddr = vm->phys_addr;
+		for (addr = start; addr < end; addr += PAGE_SIZE) {
+			preempt_disable();
+			flush_dcache_page_asm(physaddr, start);
+			flush_icache_page_asm(physaddr, start);
+			preempt_enable();
+			physaddr += PAGE_SIZE;
+		}
+		return;
+	}
+
+	flush_cache_all();
 }
+EXPORT_SYMBOL(flush_cache_vmap);
 
+/*
+ * The vm_struct has been retired and the page table is set up. The
+ * last page in the range is a guard page. Its physical address can't
+ * be determined using lpa, so there is no way to flush the range
+ * using flush_dcache_page_asm.
+ */
+void flush_cache_vunmap(unsigned long start, unsigned long end)
+{
+	/* Prevent cache move-in */
+	flush_tlb_kernel_range(start, end);
+	flush_data_cache();
+}
+EXPORT_SYMBOL(flush_cache_vunmap);
+
+/*
+ * On systems with PA8800/PA8900 processors, there is no way to flush
+ * a vmap range other than using the architected loop to flush the
+ * entire cache. The page directory is not set up, so we can't use
+ * fdc, etc. FDCE/FICE don't work to flush a portion of the cache.
+ * L2 is physically indexed but FDCE/FICE instructions in virtual
+ * mode output their virtual address on the core bus, not their
+ * real address. As a result, the L2 cache index formed from the
+ * virtual address will most likely not be the same as the L2 index
+ * formed from the real address.
+ */
 void flush_kernel_vmap_range(void *vaddr, int size)
 {
 	unsigned long start = (unsigned long)vaddr;
 	unsigned long end = start + size;
 
-	if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
-	    (unsigned long)size >= parisc_cache_flush_threshold) {
-		flush_tlb_kernel_range(start, end);
-		flush_data_cache();
+	flush_tlb_kernel_range(start, end);
+
+	if (!static_branch_likely(&parisc_has_dcache))
+		return;
+
+	/* If interrupts are disabled, we can only do local flush */
+	if (WARN_ON(IS_ENABLED(CONFIG_SMP) && arch_irqs_disabled())) {
+		flush_data_cache_local(NULL);
 		return;
 	}
 
-	flush_kernel_dcache_range_asm(start, end);
-	flush_tlb_kernel_range(start, end);
+	flush_data_cache();
 }
 EXPORT_SYMBOL(flush_kernel_vmap_range);
 
@@ -818,15 +920,18 @@
 	/* Ensure DMA is complete */
 	asm_syncdma();
 
-	if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
-	    (unsigned long)size >= parisc_cache_flush_threshold) {
-		flush_tlb_kernel_range(start, end);
-		flush_data_cache();
+	flush_tlb_kernel_range(start, end);
+
+	if (!static_branch_likely(&parisc_has_dcache))
+		return;
+
+	/* If interrupts are disabled, we can only do local flush */
+	if (WARN_ON(IS_ENABLED(CONFIG_SMP) && arch_irqs_disabled())) {
+		flush_data_cache_local(NULL);
 		return;
 	}
 
-	purge_kernel_dcache_range_asm(start, end);
-	flush_tlb_kernel_range(start, end);
+	flush_data_cache();
 }
 EXPORT_SYMBOL(invalidate_kernel_vmap_range);
 
--- linux-qcom-6.8.0.orig/arch/parisc/kernel/entry.S
+++ linux-qcom-6.8.0/arch/parisc/kernel/entry.S
@@ -1051,8 +1051,7 @@
 	STREG           %r16, PT_ISR(%r29)
 	STREG           %r17, PT_IOR(%r29)
 
-#if 0 && defined(CONFIG_64BIT)
-	/* Revisit when we have 64-bit code above 4Gb */
+#if defined(CONFIG_64BIT)
 	b,n		intr_save2
 
 skip_save_ior:
@@ -1060,8 +1059,7 @@
 	 * need to adjust iasq/iaoq here in the same way we adjusted isr/ior
 	 * above.
 	 */
-	extrd,u,*	%r8,PSW_W_BIT,1,%r1
-	cmpib,COND(=),n	1,%r1,intr_save2
+	bb,COND(>=),n	%r8,PSW_W_BIT,intr_save2
 	LDREG		PT_IASQ0(%r29), %r16
 	LDREG		PT_IAOQ0(%r29), %r17
 	/* adjust iasq/iaoq */
--- linux-qcom-6.8.0.orig/arch/parisc/kernel/ftrace.c
+++ linux-qcom-6.8.0/arch/parisc/kernel/ftrace.c
@@ -87,7 +87,7 @@
 
 int ftrace_disable_ftrace_graph_caller(void)
 {
-	static_key_enable(&ftrace_graph_enable.key);
+	static_key_disable(&ftrace_graph_enable.key);
 	return 0;
 }
 #endif
@@ -206,6 +206,9 @@
 	struct kprobe *p;
 	int bit;
 
+	if (unlikely(kprobe_ftrace_disabled))
+		return;
+
 	bit = ftrace_test_recursion_trylock(ip, parent_ip);
 	if (bit < 0)
 		return;
--- linux-qcom-6.8.0.orig/arch/parisc/kernel/irq.c
+++ linux-qcom-6.8.0/arch/parisc/kernel/irq.c
@@ -498,7 +498,7 @@
 
 	old_regs = set_irq_regs(regs);
 	local_irq_disable();
-	irq_enter();
+	irq_enter_rcu();
 
 	eirr_val = mfctl(23) & cpu_eiem & per_cpu(local_ack_eiem, cpu);
 	if (!eirr_val)
@@ -533,7 +533,7 @@
 #endif /* CONFIG_IRQSTACKS */
 
  out:
-	irq_exit();
+	irq_exit_rcu();
 	set_irq_regs(old_regs);
 	return;
 
--- linux-qcom-6.8.0.orig/arch/parisc/kernel/parisc_ksyms.c
+++ linux-qcom-6.8.0/arch/parisc/kernel/parisc_ksyms.c
@@ -22,6 +22,7 @@
 #include <linux/atomic.h>
 EXPORT_SYMBOL(__xchg8);
 EXPORT_SYMBOL(__xchg32);
+EXPORT_SYMBOL(__cmpxchg_u8);
 EXPORT_SYMBOL(__cmpxchg_u32);
 EXPORT_SYMBOL(__cmpxchg_u64);
 #ifdef CONFIG_SMP
--- linux-qcom-6.8.0.orig/arch/parisc/kernel/sys_parisc32.c
+++ linux-qcom-6.8.0/arch/parisc/kernel/sys_parisc32.c
@@ -23,12 +23,3 @@
     	current->comm, current->pid, r20);
     return -ENOSYS;
 }
-
-asmlinkage long sys32_fanotify_mark(compat_int_t fanotify_fd, compat_uint_t flags,
-	compat_uint_t mask0, compat_uint_t mask1, compat_int_t dfd,
-	const char  __user * pathname)
-{
-	return sys_fanotify_mark(fanotify_fd, flags,
-			((__u64)mask1 << 32) | mask0,
-			 dfd, pathname);
-}
--- linux-qcom-6.8.0.orig/arch/parisc/kernel/syscall.S
+++ linux-qcom-6.8.0/arch/parisc/kernel/syscall.S
@@ -243,10 +243,10 @@
 
 #ifdef CONFIG_64BIT
 	ldil	L%sys_call_table, %r1
-	or,=	%r2,%r2,%r2
-	addil	L%(sys_call_table64-sys_call_table), %r1
+	or,ev	%r2,%r2,%r2
+	ldil	L%sys_call_table64, %r1
 	ldo	R%sys_call_table(%r1), %r19
-	or,=	%r2,%r2,%r2
+	or,ev	%r2,%r2,%r2
 	ldo	R%sys_call_table64(%r1), %r19
 #else
 	load32	sys_call_table, %r19
@@ -379,10 +379,10 @@
 	extrd,u	%r19,63,1,%r2			/* W hidden in bottom bit */
 
 	ldil	L%sys_call_table, %r1
-	or,=	%r2,%r2,%r2
-	addil	L%(sys_call_table64-sys_call_table), %r1
+	or,ev	%r2,%r2,%r2
+	ldil	L%sys_call_table64, %r1
 	ldo	R%sys_call_table(%r1), %r19
-	or,=	%r2,%r2,%r2
+	or,ev	%r2,%r2,%r2
 	ldo	R%sys_call_table64(%r1), %r19
 #else
 	load32	sys_call_table, %r19
@@ -1327,6 +1327,8 @@
 END(sys_call_table)
 
 #ifdef CONFIG_64BIT
+#undef __SYSCALL_WITH_COMPAT
+#define __SYSCALL_WITH_COMPAT(nr, native, compat)	__SYSCALL(nr, native)
 	.align 8
 ENTRY(sys_call_table64)
 #include <asm/syscall_table_64.h>    /* 64-bit syscalls */
--- linux-qcom-6.8.0.orig/arch/parisc/kernel/syscalls/syscall.tbl
+++ linux-qcom-6.8.0/arch/parisc/kernel/syscalls/syscall.tbl
@@ -108,7 +108,7 @@
 95	common	fchown			sys_fchown
 96	common	getpriority		sys_getpriority
 97	common	setpriority		sys_setpriority
-98	common	recv			sys_recv
+98	common	recv			sys_recv			compat_sys_recv
 99	common	statfs			sys_statfs			compat_sys_statfs
 100	common	fstatfs			sys_fstatfs			compat_sys_fstatfs
 101	common	stat64			sys_stat64
@@ -135,7 +135,7 @@
 120	common	clone			sys_clone_wrapper
 121	common	setdomainname		sys_setdomainname
 122	common	sendfile		sys_sendfile			compat_sys_sendfile
-123	common	recvfrom		sys_recvfrom
+123	common	recvfrom		sys_recvfrom			compat_sys_recvfrom
 124	32	adjtimex		sys_adjtimex_time32
 124	64	adjtimex		sys_adjtimex
 125	common	mprotect		sys_mprotect
@@ -364,7 +364,7 @@
 320	common	accept4			sys_accept4
 321	common	prlimit64		sys_prlimit64
 322	common	fanotify_init		sys_fanotify_init
-323	common	fanotify_mark		sys_fanotify_mark		sys32_fanotify_mark
+323	common	fanotify_mark		sys_fanotify_mark		compat_sys_fanotify_mark
 324	32	clock_adjtime		sys_clock_adjtime32
 324	64	clock_adjtime		sys_clock_adjtime
 325	common	name_to_handle_at	sys_name_to_handle_at
--- linux-qcom-6.8.0.orig/arch/parisc/kernel/unaligned.c
+++ linux-qcom-6.8.0/arch/parisc/kernel/unaligned.c
@@ -169,6 +169,7 @@
 static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
 {
 	unsigned long saddr = regs->ior;
+	unsigned long shift, temp1;
 	__u64 val = 0;
 	ASM_EXCEPTIONTABLE_VAR(ret);
 
@@ -180,25 +181,22 @@
 
 #ifdef CONFIG_64BIT
 	__asm__ __volatile__  (
-"	depd,z	%3,60,3,%%r19\n"		/* r19=(ofs&7)*8 */
-"	mtsp	%4, %%sr1\n"
-"	depd	%%r0,63,3,%3\n"
-"1:	ldd	0(%%sr1,%3),%0\n"
-"2:	ldd	8(%%sr1,%3),%%r20\n"
-"	subi	64,%%r19,%%r19\n"
-"	mtsar	%%r19\n"
-"	shrpd	%0,%%r20,%%sar,%0\n"
+"	depd,z	%2,60,3,%3\n"		/* shift=(ofs&7)*8 */
+"	mtsp	%5, %%sr1\n"
+"	depd	%%r0,63,3,%2\n"
+"1:	ldd	0(%%sr1,%2),%0\n"
+"2:	ldd	8(%%sr1,%2),%4\n"
+"	subi	64,%3,%3\n"
+"	mtsar	%3\n"
+"	shrpd	%0,%4,%%sar,%0\n"
 "3:	\n"
 	ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 3b, "%1")
 	ASM_EXCEPTIONTABLE_ENTRY_EFAULT(2b, 3b, "%1")
-	: "=r" (val), "+r" (ret)
-	: "0" (val), "r" (saddr), "r" (regs->isr)
-	: "r19", "r20" );
+	: "+r" (val), "+r" (ret), "+r" (saddr), "=&r" (shift), "=&r" (temp1)
+	: "r" (regs->isr) );
 #else
-    {
-	unsigned long shift, temp1;
 	__asm__ __volatile__  (
-"	zdep	%2,29,2,%3\n"		/* r19=(ofs&3)*8 */
+"	zdep	%2,29,2,%3\n"		/* shift=(ofs&3)*8 */
 "	mtsp	%5, %%sr1\n"
 "	dep	%%r0,31,2,%2\n"
 "1:	ldw	0(%%sr1,%2),%0\n"
@@ -214,7 +212,6 @@
 	ASM_EXCEPTIONTABLE_ENTRY_EFAULT(3b, 4b, "%1")
 	: "+r" (val), "+r" (ret), "+r" (saddr), "=&r" (shift), "=&r" (temp1)
 	: "r" (regs->isr) );
-    }
 #endif
 
 	DPRINTF("val = 0x%llx\n", val);
--- linux-qcom-6.8.0.orig/arch/parisc/mm/init.c
+++ linux-qcom-6.8.0/arch/parisc/mm/init.c
@@ -458,7 +458,6 @@
 	unsigned long kernel_end  = (unsigned long)&_end;
 
 	/* Remap kernel text and data, but do not touch init section yet. */
-	kernel_set_to_readonly = true;
 	map_pages(init_end, __pa(init_end), kernel_end - init_end,
 		  PAGE_KERNEL, 0);
 
@@ -492,11 +491,18 @@
 #ifdef CONFIG_STRICT_KERNEL_RWX
 void mark_rodata_ro(void)
 {
-	/* rodata memory was already mapped with KERNEL_RO access rights by
-           pagetable_init() and map_pages(). No need to do additional stuff here */
-	unsigned long roai_size = __end_ro_after_init - __start_ro_after_init;
+	unsigned long start = (unsigned long) &__start_rodata;
+	unsigned long end = (unsigned long) &__end_rodata;
+
+	pr_info("Write protecting the kernel read-only data: %luk\n",
+	       (end - start) >> 10);
+
+	kernel_set_to_readonly = true;
+	map_pages(start, __pa(start), end - start, PAGE_KERNEL, 0);
 
-	pr_info("Write protected read-only-after-init data: %luk\n", roai_size >> 10);
+	/* force the kernel to see the new page table entries */
+	flush_cache_all();
+	flush_tlb_all();
 }
 #endif
 
--- linux-qcom-6.8.0.orig/arch/parisc/net/bpf_jit_core.c
+++ linux-qcom-6.8.0/arch/parisc/net/bpf_jit_core.c
@@ -114,7 +114,7 @@
 			jit_data->header =
 				bpf_jit_binary_alloc(prog_size + extable_size,
 						     &jit_data->image,
-						     sizeof(u32),
+						     sizeof(long),
 						     bpf_fill_ill_insns);
 			if (!jit_data->header) {
 				prog = orig_prog;
@@ -167,7 +167,13 @@
 	bpf_flush_icache(jit_data->header, ctx->insns + ctx->ninsns);
 
 	if (!prog->is_func || extra_pass) {
-		bpf_jit_binary_lock_ro(jit_data->header);
+		if (bpf_jit_binary_lock_ro(jit_data->header)) {
+			bpf_jit_binary_free(jit_data->header);
+			prog->bpf_func = NULL;
+			prog->jited = 0;
+			prog->jited_len = 0;
+			goto out_offset;
+		}
 		prologue_len = ctx->epilogue_offset - ctx->body_len;
 		for (i = 0; i < prog->len; i++)
 			ctx->offset[i] += prologue_len;
--- linux-qcom-6.8.0.orig/arch/powerpc/Kconfig
+++ linux-qcom-6.8.0/arch/powerpc/Kconfig
@@ -154,7 +154,7 @@
 	select ARCH_HAS_SYSCALL_WRAPPER		if !SPU_BASE && !COMPAT
 	select ARCH_HAS_TICK_BROADCAST		if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_HAS_UACCESS_FLUSHCACHE
-	select ARCH_HAS_UBSAN_SANITIZE_ALL
+	select ARCH_HAS_UBSAN
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select ARCH_KEEP_MEMBLOCK
 	select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE	if PPC_RADIX_MMU
@@ -273,8 +273,8 @@
 	select HAVE_RSEQ
 	select HAVE_SETUP_PER_CPU_AREA		if PPC64
 	select HAVE_SOFTIRQ_ON_OWN_STACK
-	select HAVE_STACKPROTECTOR		if PPC32 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2)
-	select HAVE_STACKPROTECTOR		if PPC64 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13)
+	select HAVE_STACKPROTECTOR		if PPC32 && $(cc-option,$(m32-flag) -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 -mstack-protector-guard-offset=0)
+	select HAVE_STACKPROTECTOR		if PPC64 && $(cc-option,$(m64-flag) -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 -mstack-protector-guard-offset=0)
 	select HAVE_STATIC_CALL			if PPC32
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_VIRT_CPU_ACCOUNTING
--- linux-qcom-6.8.0.orig/arch/powerpc/Makefile
+++ linux-qcom-6.8.0/arch/powerpc/Makefile
@@ -100,13 +100,6 @@
 KBUILD_LDFLAGS	+= -m elf$(BITS)$(LDEMULATION)
 endif
 
-cflags-$(CONFIG_STACKPROTECTOR)	+= -mstack-protector-guard=tls
-ifdef CONFIG_PPC64
-cflags-$(CONFIG_STACKPROTECTOR)	+= -mstack-protector-guard-reg=r13
-else
-cflags-$(CONFIG_STACKPROTECTOR)	+= -mstack-protector-guard-reg=r2
-endif
-
 LDFLAGS_vmlinux-y := -Bstatic
 LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) := -pie
 LDFLAGS_vmlinux-$(CONFIG_RELOCATABLE) += -z notext
@@ -238,7 +231,7 @@
 all: zImage
 
 # With make 3.82 we cannot mix normal and wildcard targets
-BOOT_TARGETS1 := zImage zImage.initrd uImage
+BOOT_TARGETS1 := zImage zImage.initrd uImage vmlinux.strip
 BOOT_TARGETS2 := zImage% dtbImage% treeImage.% cuImage.% simpleImage.% uImage.%
 
 PHONY += $(BOOT_TARGETS1) $(BOOT_TARGETS2)
@@ -400,9 +393,11 @@
 PHONY += stack_protector_prepare
 stack_protector_prepare: prepare0
 ifdef CONFIG_PPC64
-	$(eval KBUILD_CFLAGS += -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h))
+	$(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r13 \
+				-mstack-protector-guard-offset=$(shell awk '{if ($$2 == "PACA_CANARY") print $$3;}' include/generated/asm-offsets.h))
 else
-	$(eval KBUILD_CFLAGS += -mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' include/generated/asm-offsets.h))
+	$(eval KBUILD_CFLAGS += -mstack-protector-guard=tls -mstack-protector-guard-reg=r2 \
+				-mstack-protector-guard-offset=$(shell awk '{if ($$2 == "TASK_CANARY") print $$3;}' include/generated/asm-offsets.h))
 endif
 endif
 
--- linux-qcom-6.8.0.orig/arch/powerpc/boot/simple_alloc.c
+++ linux-qcom-6.8.0/arch/powerpc/boot/simple_alloc.c
@@ -112,8 +112,11 @@
 		return ptr;
 
 	new = simple_malloc(size);
-	memcpy(new, ptr, p->size);
-	simple_free(ptr);
+	if (new) {
+		memcpy(new, ptr, p->size);
+		simple_free(ptr);
+	}
+
 	return new;
 }
 
--- linux-qcom-6.8.0.orig/arch/powerpc/configs/85xx-hw.config
+++ linux-qcom-6.8.0/arch/powerpc/configs/85xx-hw.config
@@ -24,6 +24,7 @@
 CONFIG_FSL_CORENET_CF=y
 CONFIG_FSL_DMA=y
 CONFIG_FSL_HV_MANAGER=y
+CONFIG_FSL_IFC=y
 CONFIG_FSL_PQ_MDIO=y
 CONFIG_FSL_RIO=y
 CONFIG_FSL_XGMAC_MDIO=y
@@ -58,6 +59,7 @@
 CONFIG_MARVELL_PHY=y
 CONFIG_MDIO_BUS_MUX_GPIO=y
 CONFIG_MDIO_BUS_MUX_MMIOREG=y
+CONFIG_MEMORY=y
 CONFIG_MMC_SDHCI_OF_ESDHC=y
 CONFIG_MMC_SDHCI_PLTFM=y
 CONFIG_MMC_SDHCI=y
--- linux-qcom-6.8.0.orig/arch/powerpc/configs/ppc64_defconfig
+++ linux-qcom-6.8.0/arch/powerpc/configs/ppc64_defconfig
@@ -81,7 +81,6 @@
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_BINFMT_MISC=m
 CONFIG_ZSWAP=y
-CONFIG_Z3FOLD=y
 CONFIG_ZSMALLOC=y
 # CONFIG_SLAB_MERGE_DEFAULT is not set
 CONFIG_SLAB_FREELIST_RANDOM=y
--- linux-qcom-6.8.0.orig/arch/powerpc/configs/ps3_defconfig
+++ linux-qcom-6.8.0/arch/powerpc/configs/ps3_defconfig
@@ -24,7 +24,6 @@
 CONFIG_PS3_LPM=m
 # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
 CONFIG_KEXEC=y
-# CONFIG_PPC64_BIG_ENDIAN_ELF_ABI_V2 is not set
 CONFIG_PPC_4K_PAGES=y
 CONFIG_SCHED_SMT=y
 CONFIG_PM=y
--- linux-qcom-6.8.0.orig/arch/powerpc/crypto/Kconfig
+++ linux-qcom-6.8.0/arch/powerpc/crypto/Kconfig
@@ -96,6 +96,7 @@
 
 config CRYPTO_AES_GCM_P10
 	tristate "Stitched AES/GCM acceleration support on P10 or later CPU (PPC)"
+	depends on BROKEN
 	depends on PPC64 && CPU_LITTLE_ENDIAN && VSX
 	select CRYPTO_LIB_AES
 	select CRYPTO_ALGAPI
--- linux-qcom-6.8.0.orig/arch/powerpc/crypto/chacha-p10-glue.c
+++ linux-qcom-6.8.0/arch/powerpc/crypto/chacha-p10-glue.c
@@ -197,6 +197,9 @@
 
 static int __init chacha_p10_init(void)
 {
+	if (!cpu_has_feature(CPU_FTR_ARCH_31))
+		return 0;
+
 	static_branch_enable(&have_p10);
 
 	return crypto_register_skciphers(algs, ARRAY_SIZE(algs));
@@ -204,10 +207,13 @@
 
 static void __exit chacha_p10_exit(void)
 {
+	if (!static_branch_likely(&have_p10))
+		return;
+
 	crypto_unregister_skciphers(algs, ARRAY_SIZE(algs));
 }
 
-module_cpu_feature_match(PPC_MODULE_FEATURE_P10, chacha_p10_init);
+module_init(chacha_p10_init);
 module_exit(chacha_p10_exit);
 
 MODULE_DESCRIPTION("ChaCha and XChaCha stream ciphers (P10 accelerated)");
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/asm-compat.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/asm-compat.h
@@ -39,6 +39,12 @@
 #define STDX_BE	stringify_in_c(stdbrx)
 #endif
 
+#ifdef CONFIG_CC_IS_CLANG
+#define DS_FORM_CONSTRAINT "Z<>"
+#else
+#define DS_FORM_CONSTRAINT "YZ<>"
+#endif
+
 #else /* 32-bit */
 
 /* operations for longs and pointers */
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/atomic.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/atomic.h
@@ -11,6 +11,7 @@
 #include <asm/cmpxchg.h>
 #include <asm/barrier.h>
 #include <asm/asm-const.h>
+#include <asm/asm-compat.h>
 
 /*
  * Since *_return_relaxed and {cmp}xchg_relaxed are implemented with
@@ -197,7 +198,7 @@
 	if (IS_ENABLED(CONFIG_PPC_KERNEL_PREFIXED))
 		__asm__ __volatile__("ld %0,0(%1)" : "=r"(t) : "b"(&v->counter));
 	else
-		__asm__ __volatile__("ld%U1%X1 %0,%1" : "=r"(t) : "m<>"(v->counter));
+		__asm__ __volatile__("ld%U1%X1 %0,%1" : "=r"(t) : DS_FORM_CONSTRAINT (v->counter));
 
 	return t;
 }
@@ -208,7 +209,7 @@
 	if (IS_ENABLED(CONFIG_PPC_KERNEL_PREFIXED))
 		__asm__ __volatile__("std %1,0(%2)" : "=m"(v->counter) : "r"(i), "b"(&v->counter));
 	else
-		__asm__ __volatile__("std%U0%X0 %1,%0" : "=m<>"(v->counter) : "r"(i));
+		__asm__ __volatile__("std%U0%X0 %1,%0" : "=" DS_FORM_CONSTRAINT (v->counter) : "r"(i));
 }
 
 #define ATOMIC64_OP(op, asm_op)						\
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/cputhreads.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/cputhreads.h
@@ -3,6 +3,7 @@
 #define _ASM_POWERPC_CPUTHREADS_H
 
 #ifndef __ASSEMBLY__
+#include <asm/cpu_has_feature.h>
 #include <linux/cpumask.h>
 #include <asm/cpu_has_feature.h>
 
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/dtl.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/dtl.h
@@ -1,8 +1,8 @@
 #ifndef _ASM_POWERPC_DTL_H
 #define _ASM_POWERPC_DTL_H
 
+#include <linux/rwsem.h>
 #include <asm/lppaca.h>
-#include <linux/spinlock_types.h>
 
 /*
  * Layout of entries in the hypervisor's dispatch trace log buffer.
@@ -35,7 +35,7 @@
 #define DTL_LOG_ALL		(DTL_LOG_CEDE | DTL_LOG_PREEMPT | DTL_LOG_FAULT)
 
 extern struct kmem_cache *dtl_cache;
-extern rwlock_t dtl_access_lock;
+extern struct rw_semaphore dtl_access_lock;
 
 extern void register_dtl_buffer(int cpu);
 extern void alloc_dtl_buffers(unsigned long *time_limit);
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/fadump.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/fadump.h
@@ -32,4 +32,11 @@
 				      int depth, void *data);
 extern int fadump_reserve_mem(void);
 #endif
+
+#if defined(CONFIG_FA_DUMP) && defined(CONFIG_CMA)
+void fadump_cma_init(void);
+#else
+static inline void fadump_cma_init(void) { }
+#endif
+
 #endif /* _ASM_POWERPC_FADUMP_H */
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/guest-state-buffer.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/guest-state-buffer.h
@@ -81,6 +81,7 @@
 #define KVMPPC_GSID_HASHKEYR			0x1050
 #define KVMPPC_GSID_HASHPKEYR			0x1051
 #define KVMPPC_GSID_CTRL			0x1052
+#define KVMPPC_GSID_DPDES			0x1053
 
 #define KVMPPC_GSID_CR				0x2000
 #define KVMPPC_GSID_PIDR			0x2001
@@ -110,7 +111,7 @@
 #define KVMPPC_GSE_META_COUNT (KVMPPC_GSE_META_END - KVMPPC_GSE_META_START + 1)
 
 #define KVMPPC_GSE_DW_REGS_START KVMPPC_GSID_GPR(0)
-#define KVMPPC_GSE_DW_REGS_END KVMPPC_GSID_CTRL
+#define KVMPPC_GSE_DW_REGS_END KVMPPC_GSID_DPDES
 #define KVMPPC_GSE_DW_REGS_COUNT \
 	(KVMPPC_GSE_DW_REGS_END - KVMPPC_GSE_DW_REGS_START + 1)
 
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/hugetlb.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/hugetlb.h
@@ -15,6 +15,15 @@
 
 extern bool hugetlb_disabled;
 
+static inline bool hugepages_supported(void)
+{
+	if (hugetlb_disabled)
+		return false;
+
+	return HPAGE_SHIFT != 0;
+}
+#define hugepages_supported hugepages_supported
+
 void __init hugetlbpage_init_defaultsize(void);
 
 int slice_is_hugepage_only_range(struct mm_struct *mm, unsigned long addr,
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/hvcall.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/hvcall.h
@@ -524,7 +524,7 @@
  * Used for all but the craziest of phyp interfaces (see plpar_hcall9)
  */
 #define PLPAR_HCALL_BUFSIZE 4
-long plpar_hcall(unsigned long opcode, unsigned long *retbuf, ...);
+long plpar_hcall(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL_BUFSIZE], ...);
 
 /**
  * plpar_hcall_raw: - Make a hypervisor call without calculating hcall stats
@@ -538,7 +538,7 @@
  * plpar_hcall, but plpar_hcall_raw works in real mode and does not
  * calculate hypervisor call statistics.
  */
-long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...);
+long plpar_hcall_raw(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL_BUFSIZE], ...);
 
 /**
  * plpar_hcall9: - Make a pseries hypervisor call with up to 9 return arguments
@@ -549,8 +549,8 @@
  * PLPAR_HCALL9_BUFSIZE to size the return argument buffer.
  */
 #define PLPAR_HCALL9_BUFSIZE 9
-long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...);
-long plpar_hcall9_raw(unsigned long opcode, unsigned long *retbuf, ...);
+long plpar_hcall9(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL9_BUFSIZE], ...);
+long plpar_hcall9_raw(unsigned long opcode, unsigned long retbuf[static PLPAR_HCALL9_BUFSIZE], ...);
 
 /* pseries hcall tracing */
 extern struct static_key hcall_tracepoint_key;
@@ -570,7 +570,7 @@
 	unsigned long backing_mem;
 };
 
-int h_get_mpp(struct hvcall_mpp_data *);
+long h_get_mpp(struct hvcall_mpp_data *mpp_data);
 
 struct hvcall_mpp_x_data {
 	unsigned long coalesced_bytes;
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/interrupt.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/interrupt.h
@@ -336,6 +336,14 @@
 	if (IS_ENABLED(CONFIG_KASAN))
 		return;
 
+	/*
+	 * Likewise, do not use it in real mode if percpu first chunk is not
+	 * embedded. With CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK enabled there
+	 * are chances where percpu allocation can come from vmalloc area.
+	 */
+	if (percpu_first_chunk_is_paged)
+		return;
+
 	/* Otherwise, it should be safe to call it */
 	nmi_enter();
 }
@@ -351,6 +359,8 @@
 		// no nmi_exit for a pseries hash guest taking a real mode exception
 	} else if (IS_ENABLED(CONFIG_KASAN)) {
 		// no nmi_exit for KASAN in real mode
+	} else if (percpu_first_chunk_is_paged) {
+		// no nmi_exit if percpu first chunk is not embedded
 	} else {
 		nmi_exit();
 	}
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/io.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/io.h
@@ -37,7 +37,7 @@
  * define properly based on the platform
  */
 #ifndef CONFIG_PCI
-#define _IO_BASE	0
+#define _IO_BASE	POISON_POINTER_DELTA
 #define _ISA_MEM_BASE	0
 #define PCI_DRAM_OFFSET 0
 #elif defined(CONFIG_PPC32)
@@ -585,12 +585,12 @@
 #define __do_inw(port)		_rec_inw(port)
 #define __do_inl(port)		_rec_inl(port)
 #else /* CONFIG_PPC32 */
-#define __do_outb(val, port)	writeb(val,(PCI_IO_ADDR)_IO_BASE+port);
-#define __do_outw(val, port)	writew(val,(PCI_IO_ADDR)_IO_BASE+port);
-#define __do_outl(val, port)	writel(val,(PCI_IO_ADDR)_IO_BASE+port);
-#define __do_inb(port)		readb((PCI_IO_ADDR)_IO_BASE + port);
-#define __do_inw(port)		readw((PCI_IO_ADDR)_IO_BASE + port);
-#define __do_inl(port)		readl((PCI_IO_ADDR)_IO_BASE + port);
+#define __do_outb(val, port)	writeb(val,(PCI_IO_ADDR)(_IO_BASE+port));
+#define __do_outw(val, port)	writew(val,(PCI_IO_ADDR)(_IO_BASE+port));
+#define __do_outl(val, port)	writel(val,(PCI_IO_ADDR)(_IO_BASE+port));
+#define __do_inb(port)		readb((PCI_IO_ADDR)(_IO_BASE + port));
+#define __do_inw(port)		readw((PCI_IO_ADDR)(_IO_BASE + port));
+#define __do_inl(port)		readl((PCI_IO_ADDR)(_IO_BASE + port));
 #endif /* !CONFIG_PPC32 */
 
 #ifdef CONFIG_EEH
@@ -606,12 +606,12 @@
 #define __do_writesw(a, b, n)	_outsw(PCI_FIX_ADDR(a),(b),(n))
 #define __do_writesl(a, b, n)	_outsl(PCI_FIX_ADDR(a),(b),(n))
 
-#define __do_insb(p, b, n)	readsb((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
-#define __do_insw(p, b, n)	readsw((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
-#define __do_insl(p, b, n)	readsl((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
-#define __do_outsb(p, b, n)	writesb((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
-#define __do_outsw(p, b, n)	writesw((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
-#define __do_outsl(p, b, n)	writesl((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
+#define __do_insb(p, b, n)	readsb((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n))
+#define __do_insw(p, b, n)	readsw((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n))
+#define __do_insl(p, b, n)	readsl((PCI_IO_ADDR)(_IO_BASE+(p)), (b), (n))
+#define __do_outsb(p, b, n)	writesb((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n))
+#define __do_outsw(p, b, n)	writesw((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n))
+#define __do_outsl(p, b, n)	writesl((PCI_IO_ADDR)(_IO_BASE+(p)),(b),(n))
 
 #define __do_memset_io(addr, c, n)	\
 				_memset_io(PCI_FIX_ADDR(addr), c, n)
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/kfence.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/kfence.h
@@ -15,10 +15,19 @@
 #define ARCH_FUNC_PREFIX "."
 #endif
 
+#ifdef CONFIG_KFENCE
+extern bool kfence_disabled;
+
+static inline void disable_kfence(void)
+{
+	kfence_disabled = true;
+}
+
 static inline bool arch_kfence_init_pool(void)
 {
-	return true;
+	return !kfence_disabled;
 }
+#endif
 
 #ifdef CONFIG_PPC64
 static inline bool kfence_protect_page(unsigned long addr, bool protect)
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/kvm_book3s.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/kvm_book3s.h
@@ -594,6 +594,7 @@
 
 
 KVMPPC_BOOK3S_VCORE_ACCESSOR(vtb, 64, KVMPPC_GSID_VTB)
+KVMPPC_BOOK3S_VCORE_ACCESSOR(dpdes, 64, KVMPPC_GSID_DPDES)
 KVMPPC_BOOK3S_VCORE_ACCESSOR_GET(arch_compat, 32, KVMPPC_GSID_LOGICAL_PVR)
 KVMPPC_BOOK3S_VCORE_ACCESSOR_GET(lpcr, 64, KVMPPC_GSID_LPCR)
 KVMPPC_BOOK3S_VCORE_ACCESSOR_SET(tb_offset, 64, KVMPPC_GSID_TB_OFFSET)
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/kvm_host.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/kvm_host.h
@@ -599,6 +599,9 @@
 	ulong dawrx0;
 	ulong dawr1;
 	ulong dawrx1;
+	ulong dexcr;
+	ulong hashkeyr;
+	ulong hashpkeyr;
 	ulong ciabr;
 	ulong cfar;
 	ulong ppr;
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/nohash/mmu-e500.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/nohash/mmu-e500.h
@@ -303,8 +303,7 @@
 extern int book3e_htw_mode;
 
 #define PPC_HTW_NONE	0
-#define PPC_HTW_IBM	1
-#define PPC_HTW_E6500	2
+#define PPC_HTW_E6500	1
 
 /*
  * 64-bit booke platforms don't load the tlb in the tlb miss handler code.
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/percpu.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/percpu.h
@@ -15,6 +15,16 @@
 #endif /* CONFIG_SMP */
 #endif /* __powerpc64__ */
 
+#if defined(CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK) && defined(CONFIG_SMP)
+#include <linux/jump_label.h>
+DECLARE_STATIC_KEY_FALSE(__percpu_first_chunk_is_paged);
+
+#define percpu_first_chunk_is_paged	\
+		(static_key_enabled(&__percpu_first_chunk_is_paged.key))
+#else
+#define percpu_first_chunk_is_paged	false
+#endif /* CONFIG_PPC64 && CONFIG_SMP */
+
 #include <asm-generic/percpu.h>
 
 #include <asm/paca.h>
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/plpks.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/plpks.h
@@ -44,9 +44,8 @@
 #define PLPKS_MAX_DATA_SIZE		4000
 
 // Timeouts for PLPKS operations
-#define PLPKS_MAX_TIMEOUT		5000 // msec
-#define PLPKS_FLUSH_SLEEP		10 // msec
-#define PLPKS_FLUSH_SLEEP_RANGE		400
+#define PLPKS_MAX_TIMEOUT		(5 * USEC_PER_SEC)
+#define PLPKS_FLUSH_SLEEP		10000 // usec
 
 struct plpks_var {
 	char *component;
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/ppc-opcode.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/ppc-opcode.h
@@ -510,6 +510,7 @@
 #define PPC_RAW_STB(r, base, i)		(0x98000000 | ___PPC_RS(r) | ___PPC_RA(base) | IMM_L(i))
 #define PPC_RAW_LBZ(r, base, i)		(0x88000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
 #define PPC_RAW_LDX(r, base, b)		(0x7c00002a | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
+#define PPC_RAW_LHA(r, base, i)		(0xa8000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
 #define PPC_RAW_LHZ(r, base, i)		(0xa0000000 | ___PPC_RT(r) | ___PPC_RA(base) | IMM_L(i))
 #define PPC_RAW_LHBRX(r, base, b)	(0x7c00062c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
 #define PPC_RAW_LWBRX(r, base, b)	(0x7c00042c | ___PPC_RT(r) | ___PPC_RA(base) | ___PPC_RB(b))
@@ -532,6 +533,7 @@
 #define PPC_RAW_MULW(d, a, b)		(0x7c0001d6 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
 #define PPC_RAW_MULHWU(d, a, b)		(0x7c000016 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
 #define PPC_RAW_MULI(d, a, i)		(0x1c000000 | ___PPC_RT(d) | ___PPC_RA(a) | IMM_L(i))
+#define PPC_RAW_DIVW(d, a, b)		(0x7c0003d6 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
 #define PPC_RAW_DIVWU(d, a, b)		(0x7c000396 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
 #define PPC_RAW_DIVDU(d, a, b)		(0x7c000392 | ___PPC_RT(d) | ___PPC_RA(a) | ___PPC_RB(b))
 #define PPC_RAW_DIVDE(t, a, b)		(0x7c000352 | ___PPC_RT(t) | ___PPC_RA(a) | ___PPC_RB(b))
@@ -550,6 +552,8 @@
 #define PPC_RAW_XOR(d, a, b)		(0x7c000278 | ___PPC_RA(d) | ___PPC_RS(a) | ___PPC_RB(b))
 #define PPC_RAW_XORI(d, a, i)		(0x68000000 | ___PPC_RA(d) | ___PPC_RS(a) | IMM_L(i))
 #define PPC_RAW_XORIS(d, a, i)		(0x6c000000 | ___PPC_RA(d) | ___PPC_RS(a) | IMM_L(i))
+#define PPC_RAW_EXTSB(d, a)		(0x7c000774 | ___PPC_RA(d) | ___PPC_RS(a))
+#define PPC_RAW_EXTSH(d, a)		(0x7c000734 | ___PPC_RA(d) | ___PPC_RS(a))
 #define PPC_RAW_EXTSW(d, a)		(0x7c0007b4 | ___PPC_RA(d) | ___PPC_RS(a))
 #define PPC_RAW_SLW(d, a, s)		(0x7c000030 | ___PPC_RA(d) | ___PPC_RS(a) | ___PPC_RB(s))
 #define PPC_RAW_SLD(d, a, s)		(0x7c000036 | ___PPC_RA(d) | ___PPC_RS(a) | ___PPC_RB(s))
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/reg_fsl_emb.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/reg_fsl_emb.h
@@ -12,9 +12,16 @@
 #ifndef __ASSEMBLY__
 /* Performance Monitor Registers */
 #define mfpmr(rn)	({unsigned int rval; \
-			asm volatile("mfpmr %0," __stringify(rn) \
+			asm volatile(".machine push; " \
+				     ".machine e300; " \
+				     "mfpmr %0," __stringify(rn) ";" \
+				     ".machine pop; " \
 				     : "=r" (rval)); rval;})
-#define mtpmr(rn, v)	asm volatile("mtpmr " __stringify(rn) ",%0" : : "r" (v))
+#define mtpmr(rn, v)	asm volatile(".machine push; " \
+				     ".machine e300; " \
+				     "mtpmr " __stringify(rn) ",%0; " \
+				     ".machine pop; " \
+				     : : "r" (v))
 #endif /* __ASSEMBLY__ */
 
 /* Freescale Book E Performance Monitor APU Registers */
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/sstep.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/sstep.h
@@ -173,9 +173,4 @@
  */
 extern int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op);
 
-extern void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
-			     const void *mem, bool cross_endian);
-extern void emulate_vsx_store(struct instruction_op *op,
-			      const union vsx_reg *reg, void *mem,
-			      bool cross_endian);
 extern int emulate_dcbz(unsigned long ea, struct pt_regs *regs);
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/topology.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/topology.h
@@ -145,6 +145,7 @@
 
 #ifdef CONFIG_HOTPLUG_SMT
 #include <linux/cpu_smt.h>
+#include <linux/cpumask.h>
 #include <asm/cputhreads.h>
 
 static inline bool topology_is_primary_thread(unsigned int cpu)
@@ -156,6 +157,18 @@
 {
 	return cpu_thread_in_core(cpu) < cpu_smt_num_threads;
 }
+
+#define topology_is_core_online topology_is_core_online
+static inline bool topology_is_core_online(unsigned int cpu)
+{
+	int i, first_cpu = cpu_first_thread_sibling(cpu);
+
+	for (i = first_cpu; i < first_cpu + threads_per_core; ++i) {
+		if (cpu_online(i))
+			return true;
+	}
+	return false;
+}
 #endif
 
 #endif /* __KERNEL__ */
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/uaccess.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/uaccess.h
@@ -6,6 +6,7 @@
 #include <asm/page.h>
 #include <asm/extable.h>
 #include <asm/kup.h>
+#include <asm/asm-compat.h>
 
 #ifdef __powerpc64__
 /* We use TASK_SIZE_USER64 as TASK_SIZE is not constant */
@@ -93,8 +94,18 @@
 #endif
 
 #ifdef __powerpc64__
+#ifdef CONFIG_PPC_KERNEL_PREFIXED
 #define __put_user_asm2_goto(x, ptr, label)			\
 	__put_user_asm_goto(x, ptr, label, "std")
+#else
+#define __put_user_asm2_goto(x, addr, label)			\
+	asm goto ("1: std%U1%X1 %0,%1	# put_user\n"		\
+		EX_TABLE(1b, %l2)				\
+		:						\
+		: "r" (x), DS_FORM_CONSTRAINT (*addr)		\
+		:						\
+		: label)
+#endif // CONFIG_PPC_KERNEL_PREFIXED
 #else /* __powerpc64__ */
 #define __put_user_asm2_goto(x, addr, label)			\
 	asm goto(					\
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/vdso.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/vdso.h
@@ -25,6 +25,7 @@
 #ifdef __VDSO64__
 #define V_FUNCTION_BEGIN(name)		\
 	.globl name;			\
+	.type name,@function; 		\
 	name:				\
 
 #define V_FUNCTION_END(name)		\
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/vdso_datapage.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/vdso_datapage.h
@@ -111,6 +111,21 @@
 	addi	\ptr, \ptr, (_vdso_datapage - 999b)@l
 .endm
 
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+
+.macro get_realdatapage ptr scratch
+	get_datapage \ptr
+#ifdef CONFIG_TIME_NS
+	lwz	\scratch, VDSO_CLOCKMODE_OFFSET(\ptr)
+	xoris	\scratch, \scratch, VDSO_CLOCKMODE_TIMENS@h
+	xori	\scratch, \scratch, VDSO_CLOCKMODE_TIMENS@l
+	cntlzw	\scratch, \scratch
+	rlwinm	\scratch, \scratch, PAGE_SHIFT - 5, 1 << PAGE_SHIFT
+	add	\ptr, \ptr, \scratch
+#endif
+.endm
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
--- linux-qcom-6.8.0.orig/arch/powerpc/include/asm/vmalloc.h
+++ linux-qcom-6.8.0/arch/powerpc/include/asm/vmalloc.h
@@ -7,14 +7,14 @@
 #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP
 
 #define arch_vmap_pud_supported arch_vmap_pud_supported
-static inline bool arch_vmap_pud_supported(pgprot_t prot)
+static __always_inline bool arch_vmap_pud_supported(pgprot_t prot)
 {
 	/* HPT does not cope with large pages in the vmalloc area */
 	return radix_enabled();
 }
 
 #define arch_vmap_pmd_supported arch_vmap_pmd_supported
-static inline bool arch_vmap_pmd_supported(pgprot_t prot)
+static __always_inline bool arch_vmap_pmd_supported(pgprot_t prot)
 {
 	return radix_enabled();
 }
--- linux-qcom-6.8.0.orig/arch/powerpc/include/uapi/asm/kvm.h
+++ linux-qcom-6.8.0/arch/powerpc/include/uapi/asm/kvm.h
@@ -646,6 +646,9 @@
 #define KVM_REG_PPC_SIER3	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc3)
 #define KVM_REG_PPC_DAWR1	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc4)
 #define KVM_REG_PPC_DAWRX1	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc5)
+#define KVM_REG_PPC_DEXCR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc6)
+#define KVM_REG_PPC_HASHKEYR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc7)
+#define KVM_REG_PPC_HASHPKEYR	(KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc8)
 
 /* Transactional Memory checkpointed state:
  * This is all GPRs, all VSX regs and a subset of SPRs
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/asm-offsets.c
+++ linux-qcom-6.8.0/arch/powerpc/kernel/asm-offsets.c
@@ -348,6 +348,8 @@
 #else
 	OFFSET(CFG_SYSCALL_MAP32, vdso_arch_data, syscall_map);
 #endif
+	OFFSET(VDSO_CLOCKMODE_OFFSET, vdso_arch_data, data[0].clock_mode);
+	DEFINE(VDSO_CLOCKMODE_TIMENS, VDSO_CLOCKMODE_TIMENS);
 
 #ifdef CONFIG_BUG
 	DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/dt_cpu_ftrs.c
+++ linux-qcom-6.8.0/arch/powerpc/kernel/dt_cpu_ftrs.c
@@ -857,7 +857,7 @@
 	using_dt_cpu_ftrs = false;
 
 	/* Setup and verify the FDT, if it fails we just bail */
-	if (!early_init_dt_verify(fdt))
+	if (!early_init_dt_verify(fdt, __pa(fdt)))
 		return false;
 
 	if (!of_scan_flat_dt(fdt_find_cpu_features, NULL))
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/eeh_pe.c
+++ linux-qcom-6.8.0/arch/powerpc/kernel/eeh_pe.c
@@ -849,6 +849,7 @@
 {
 	struct eeh_dev *edev;
 	struct pci_dev *pdev;
+	struct pci_bus *bus = NULL;
 
 	if (pe->type & EEH_PE_PHB)
 		return pe->phb->bus;
@@ -859,9 +860,11 @@
 
 	/* Retrieve the parent PCI bus of first (top) PCI device */
 	edev = list_first_entry_or_null(&pe->edevs, struct eeh_dev, entry);
+	pci_lock_rescan_remove();
 	pdev = eeh_dev_to_pci_dev(edev);
 	if (pdev)
-		return pdev->bus;
+		bus = pdev->bus;
+	pci_unlock_rescan_remove();
 
-	return NULL;
+	return bus;
 }
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/fadump.c
+++ linux-qcom-6.8.0/arch/powerpc/kernel/fadump.c
@@ -80,27 +80,23 @@
  * But for some reason even if it fails we still have the memory reservation
  * with us and we can still continue doing fadump.
  */
-static int __init fadump_cma_init(void)
+void __init fadump_cma_init(void)
 {
 	unsigned long long base, size;
 	int rc;
 
-	if (!fw_dump.fadump_enabled)
-		return 0;
-
+	if (!fw_dump.fadump_supported || !fw_dump.fadump_enabled ||
+			fw_dump.dump_active)
+		return;
 	/*
 	 * Do not use CMA if user has provided fadump=nocma kernel parameter.
-	 * Return 1 to continue with fadump old behaviour.
 	 */
-	if (fw_dump.nocma)
-		return 1;
+	if (fw_dump.nocma || !fw_dump.boot_memory_size)
+		return;
 
 	base = fw_dump.reserve_dump_area_start;
 	size = fw_dump.boot_memory_size;
 
-	if (!size)
-		return 0;
-
 	rc = cma_init_reserved_mem(base, size, 0, "fadump_cma", &fadump_cma);
 	if (rc) {
 		pr_err("Failed to init cma area for firmware-assisted dump,%d\n", rc);
@@ -110,7 +106,7 @@
 		 * blocked from production system usage.  Hence return 1,
 		 * so that we can continue with fadump.
 		 */
-		return 1;
+		return;
 	}
 
 	/*
@@ -127,10 +123,7 @@
 		cma_get_size(fadump_cma),
 		(unsigned long)cma_get_base(fadump_cma) >> 20,
 		fw_dump.reserve_dump_area_size);
-	return 1;
 }
-#else
-static int __init fadump_cma_init(void) { return 1; }
 #endif /* CONFIG_CMA */
 
 /* Scan the Firmware Assisted dump configuration details. */
@@ -647,8 +640,6 @@
 
 		pr_info("Reserved %lldMB of memory at %#016llx (System RAM: %lldMB)\n",
 			(size >> 20), base, (memblock_phys_mem_size() >> 20));
-
-		ret = fadump_cma_init();
 	}
 
 	return ret;
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/head_64.S
+++ linux-qcom-6.8.0/arch/powerpc/kernel/head_64.S
@@ -647,8 +647,9 @@
  * Note: This process overwrites the OF exception vectors.
  */
 	LOAD_REG_IMMEDIATE(r3, PAGE_OFFSET)
-	mr.	r4,r26			/* In some cases the loader may  */
-	beq	9f			/* have already put us at zero */
+	mr	r4,r26			/* Load the virtual source address into r4 */
+	cmpld	r3,r4			/* Check if source == dest */
+	beq	9f			/* If so skip the copy  */
 	li	r6,0x100		/* Start offset, the first 0x100 */
 					/* bytes were copied earlier.	 */
 
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/head_8xx.S
+++ linux-qcom-6.8.0/arch/powerpc/kernel/head_8xx.S
@@ -41,12 +41,12 @@
 #include "head_32.h"
 
 .macro compare_to_kernel_boundary scratch, addr
-#if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000
+#if CONFIG_TASK_SIZE <= 0x80000000 && MODULES_VADDR >= 0x80000000
 /* By simply checking Address >= 0x80000000, we know if its a kernel address */
 	not.	\scratch, \addr
 #else
 	rlwinm	\scratch, \addr, 16, 0xfff8
-	cmpli	cr0, \scratch, PAGE_OFFSET@h
+	cmpli	cr0, \scratch, TASK_SIZE@h
 #endif
 .endm
 
@@ -404,7 +404,7 @@
 	mfspr	r10, SPRN_SRR0
 	mtspr	SPRN_MD_EPN, r10
 	rlwinm	r11, r10, 16, 0xfff8
-	cmpli	cr1, r11, PAGE_OFFSET@h
+	cmpli	cr1, r11, TASK_SIZE@h
 	mfspr	r11, SPRN_M_TWB	/* Get level 1 table */
 	blt+	cr1, 3f
 
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/iommu.c
+++ linux-qcom-6.8.0/arch/powerpc/kernel/iommu.c
@@ -686,7 +686,7 @@
 static void iommu_table_reserve_pages(struct iommu_table *tbl,
 		unsigned long res_start, unsigned long res_end)
 {
-	int i;
+	unsigned long i;
 
 	WARN_ON_ONCE(res_end < res_start);
 	/*
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/kprobes-ftrace.c
+++ linux-qcom-6.8.0/arch/powerpc/kernel/kprobes-ftrace.c
@@ -21,6 +21,9 @@
 	struct pt_regs *regs;
 	int bit;
 
+	if (unlikely(kprobe_ftrace_disabled))
+		return;
+
 	bit = ftrace_test_recursion_trylock(nip, parent_nip);
 	if (bit < 0)
 		return;
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/module_64.c
+++ linux-qcom-6.8.0/arch/powerpc/kernel/module_64.c
@@ -347,12 +347,13 @@
 static void dedotify_versions(struct modversion_info *vers,
 			      unsigned long size)
 {
-	struct modversion_info *end;
+	struct modversion_info *end = (void *)vers + size;
 
-	for (end = (void *)vers + size; vers < end; vers++)
+	for (; vers < end && vers->next; vers = (void *)vers + vers->next) {
 		if (vers->name[0] == '.') {
 			memmove(vers->name, vers->name+1, strlen(vers->name));
 		}
+	}
 }
 
 /*
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/pci-common.c
+++ linux-qcom-6.8.0/arch/powerpc/kernel/pci-common.c
@@ -360,6 +360,7 @@
 	}
 	return NULL;
 }
+EXPORT_SYMBOL(pci_find_hose_for_OF_device);
 
 struct pci_controller *pci_find_controller_for_domain(int domain_nr)
 {
@@ -1630,6 +1631,7 @@
 {
 	return pci_bus_find_capability(fake_pci_bus(hose, bus), devfn, cap);
 }
+EXPORT_SYMBOL_GPL(early_find_capability);
 
 struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus)
 {
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/prom.c
+++ linux-qcom-6.8.0/arch/powerpc/kernel/prom.c
@@ -327,6 +327,7 @@
 					  void *data)
 {
 	const char *type = of_get_flat_dt_prop(node, "device_type", NULL);
+	const __be32 *cpu_version = NULL;
 	const __be32 *prop;
 	const __be32 *intserv;
 	int i, nthreads;
@@ -375,6 +376,18 @@
 	if (IS_ENABLED(CONFIG_PPC64))
 		boot_cpu_hwid = be32_to_cpu(intserv[found_thread]);
 
+	if (nr_cpu_ids % nthreads != 0) {
+		set_nr_cpu_ids(ALIGN(nr_cpu_ids, nthreads));
+		pr_warn("nr_cpu_ids was not a multiple of threads_per_core, adjusted to %d\n",
+			nr_cpu_ids);
+	}
+
+	if (boot_cpuid >= nr_cpu_ids) {
+		set_nr_cpu_ids(min(CONFIG_NR_CPUS, ALIGN(boot_cpuid + 1, nthreads)));
+		pr_warn("Boot CPU %d >= nr_cpu_ids, adjusted nr_cpu_ids to %d\n",
+			boot_cpuid, nr_cpu_ids);
+	}
+
 	/*
 	 * PAPR defines "logical" PVR values for cpus that
 	 * meet various levels of the architecture:
@@ -398,7 +411,7 @@
 		prop = of_get_flat_dt_prop(node, "cpu-version", NULL);
 		if (prop && (be32_to_cpup(prop) & 0xff000000) == 0x0f000000) {
 			identify_cpu(0, be32_to_cpup(prop));
-			seq_buf_printf(&ppc_hw_desc, "0x%04x ", be32_to_cpup(prop));
+			cpu_version = prop;
 		}
 
 		check_cpu_feature_properties(node);
@@ -409,6 +422,12 @@
 	}
 
 	identical_pvr_fixup(node);
+
+	// We can now add the CPU name & PVR to the hardware description
+	seq_buf_printf(&ppc_hw_desc, "%s 0x%04lx ", cur_cpu_spec->cpu_name, mfspr(SPRN_PVR));
+	if (cpu_version)
+		seq_buf_printf(&ppc_hw_desc, "0x%04x ", be32_to_cpup(cpu_version));
+
 	init_mmu_slb_size(node);
 
 #ifdef CONFIG_PPC64
@@ -762,7 +781,7 @@
 	DBG(" -> early_init_devtree(%px)\n", params);
 
 	/* Too early to BUG_ON(), do it by hand */
-	if (!early_init_dt_verify(params))
+	if (!early_init_dt_verify(params, __pa(params)))
 		panic("BUG: Failed verifying flat device tree, bad version?");
 
 	of_scan_flat_dt(early_init_dt_scan_model, NULL);
@@ -846,9 +865,6 @@
 
 	dt_cpu_ftrs_scan();
 
-	// We can now add the CPU name & PVR to the hardware description
-	seq_buf_printf(&ppc_hw_desc, "%s 0x%04lx ", cur_cpu_spec->cpu_name, mfspr(SPRN_PVR));
-
 	/* Retrieve CPU related informations from the flat tree
 	 * (altivec support, boot CPU ID, ...)
 	 */
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/prom_init.c
+++ linux-qcom-6.8.0/arch/powerpc/kernel/prom_init.c
@@ -2924,7 +2924,7 @@
 #endif
 
 #if defined(CONFIG_PPC64) && defined(CONFIG_PPC_PMAC)
-static void __init fixup_device_tree_pmac(void)
+static void __init fixup_device_tree_pmac64(void)
 {
 	phandle u3, i2c, mpic;
 	u32 u3_rev;
@@ -2964,7 +2964,31 @@
 		     &parent, sizeof(parent));
 }
 #else
-#define fixup_device_tree_pmac()
+#define fixup_device_tree_pmac64()
+#endif
+
+#ifdef CONFIG_PPC_PMAC
+static void __init fixup_device_tree_pmac(void)
+{
+	__be32 val = 1;
+	char type[8];
+	phandle node;
+
+	// Some pmacs are missing #size-cells on escc nodes
+	for (node = 0; prom_next_node(&node); ) {
+		type[0] = '\0';
+		prom_getprop(node, "device_type", type, sizeof(type));
+		if (prom_strcmp(type, "escc"))
+			continue;
+
+		if (prom_getproplen(node, "#size-cells") != PROM_ERROR)
+			continue;
+
+		prom_setprop(node, NULL, "#size-cells", &val, sizeof(val));
+	}
+}
+#else
+static inline void fixup_device_tree_pmac(void) { }
 #endif
 
 #ifdef CONFIG_PPC_EFIKA
@@ -3189,6 +3213,7 @@
 	fixup_device_tree_maple_memory_controller();
 	fixup_device_tree_chrp();
 	fixup_device_tree_pmac();
+	fixup_device_tree_pmac64();
 	fixup_device_tree_efika();
 	fixup_device_tree_pasemi();
 }
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/rtas.c
+++ linux-qcom-6.8.0/arch/powerpc/kernel/rtas.c
@@ -19,6 +19,7 @@
 #include <linux/lockdep.h>
 #include <linux/memblock.h>
 #include <linux/mutex.h>
+#include <linux/nospec.h>
 #include <linux/of.h>
 #include <linux/of_fdt.h>
 #include <linux/reboot.h>
@@ -1916,6 +1917,9 @@
 	    || nargs + nret > ARRAY_SIZE(args.args))
 		return -EINVAL;
 
+	nargs = array_index_nospec(nargs, ARRAY_SIZE(args.args));
+	nret = array_index_nospec(nret, ARRAY_SIZE(args.args) - nargs);
+
 	/* Copy in args. */
 	if (copy_from_user(args.args, uargs->args,
 			   nargs * sizeof(rtas_arg_t)) != 0)
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/setup-common.c
+++ linux-qcom-6.8.0/arch/powerpc/kernel/setup-common.c
@@ -35,6 +35,7 @@
 #include <linux/of_irq.h>
 #include <linux/hugetlb.h>
 #include <linux/pgtable.h>
+#include <linux/security.h>
 #include <asm/io.h>
 #include <asm/paca.h>
 #include <asm/processor.h>
@@ -67,6 +68,7 @@
 #include <asm/cpu_has_feature.h>
 #include <asm/kasan.h>
 #include <asm/mce.h>
+#include <asm/secure_boot.h>
 
 #include "setup.h"
 
@@ -896,6 +898,16 @@
 	 */
 	initialize_cache_info();
 
+	/*
+	 * Lock down the kernel if booted in secure mode. This is required to
+	 * maintain kernel integrity.
+	 */
+	if (IS_ENABLED(CONFIG_LOCK_DOWN_IN_SECURE_BOOT)) {
+		if (is_ppc_secureboot_enabled())
+			security_lock_kernel_down("PowerNV Secure Boot mode",
+						  LOCKDOWN_INTEGRITY_MAX);
+	}
+
 	/* Initialize RTAS if available. */
 	rtas_initialize();
 
@@ -933,6 +945,7 @@
 	mem_topology_setup();
 	/* Set max_mapnr before paging_init() */
 	set_max_mapnr(max_pfn);
+	high_memory = (void *)__va(max_low_pfn * PAGE_SIZE);
 
 	/*
 	 * Release secondary cpus out of their spinloops at 0x60 now that
@@ -970,9 +983,11 @@
 	initmem_init();
 
 	/*
-	 * Reserve large chunks of memory for use by CMA for KVM and hugetlb. These must
-	 * be called after initmem_init(), so that pageblock_order is initialised.
+	 * Reserve large chunks of memory for use by CMA for fadump, KVM and
+	 * hugetlb. These must be called after initmem_init(), so that
+	 * pageblock_order is initialised.
 	 */
+	fadump_cma_init();
 	kvm_cma_reserve();
 	gigantic_hugetlb_cma_reserve();
 
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/setup_64.c
+++ linux-qcom-6.8.0/arch/powerpc/kernel/setup_64.c
@@ -834,6 +834,7 @@
 
 unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
 EXPORT_SYMBOL(__per_cpu_offset);
+DEFINE_STATIC_KEY_FALSE(__percpu_first_chunk_is_paged);
 
 void __init setup_per_cpu_areas(void)
 {
@@ -876,6 +877,7 @@
 	if (rc < 0)
 		panic("cannot initialize percpu area (err=%d)", rc);
 
+	static_key_enable(&__percpu_first_chunk_is_paged.key);
 	delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
 	for_each_possible_cpu(cpu) {
                 __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu];
@@ -922,6 +924,7 @@
 	hardlockup_detector_disable();
 #else
 	if (firmware_has_feature(FW_FEATURE_LPAR)) {
+		check_kvm_guest();
 		if (is_kvm_guest())
 			hardlockup_detector_disable();
 	}
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/syscalls/syscall.tbl
+++ linux-qcom-6.8.0/arch/powerpc/kernel/syscalls/syscall.tbl
@@ -230,8 +230,10 @@
 178	nospu 	rt_sigsuspend			sys_rt_sigsuspend		compat_sys_rt_sigsuspend
 179	32	pread64				sys_ppc_pread64			compat_sys_ppc_pread64
 179	64	pread64				sys_pread64
+179	spu	pread64				sys_pread64
 180	32	pwrite64			sys_ppc_pwrite64		compat_sys_ppc_pwrite64
 180	64	pwrite64			sys_pwrite64
+180	spu	pwrite64			sys_pwrite64
 181	common	chown				sys_chown
 182	common	getcwd				sys_getcwd
 183	common	capget				sys_capget
@@ -246,6 +248,7 @@
 190	common	ugetrlimit			sys_getrlimit			compat_sys_getrlimit
 191	32	readahead			sys_ppc_readahead		compat_sys_ppc_readahead
 191	64	readahead			sys_readahead
+191	spu	readahead			sys_readahead
 192	32	mmap2				sys_mmap2			compat_sys_mmap2
 193	32	truncate64			sys_ppc_truncate64		compat_sys_ppc_truncate64
 194	32	ftruncate64			sys_ppc_ftruncate64		compat_sys_ppc_ftruncate64
@@ -293,6 +296,7 @@
 232	nospu	set_tid_address			sys_set_tid_address
 233	32	fadvise64			sys_ppc32_fadvise64		compat_sys_ppc32_fadvise64
 233	64	fadvise64			sys_fadvise64
+233	spu	fadvise64			sys_fadvise64
 234	nospu	exit_group			sys_exit_group
 235	nospu	lookup_dcookie			sys_ni_syscall
 236	common	epoll_create			sys_epoll_create
@@ -502,7 +506,7 @@
 412	32	utimensat_time64		sys_utimensat			sys_utimensat
 413	32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
 414	32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
-416	32	io_pgetevents_time64		sys_io_pgetevents		sys_io_pgetevents
+416	32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
 417	32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
 418	32	mq_timedsend_time64		sys_mq_timedsend		sys_mq_timedsend
 419	32	mq_timedreceive_time64		sys_mq_timedreceive		sys_mq_timedreceive
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/vdso/Makefile
+++ linux-qcom-6.8.0/arch/powerpc/kernel/vdso/Makefile
@@ -10,28 +10,11 @@
 
 ifneq ($(c-gettimeofday-y),)
   CFLAGS_vgettimeofday-32.o += -include $(c-gettimeofday-y)
-  CFLAGS_vgettimeofday-32.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
-  CFLAGS_vgettimeofday-32.o += $(call cc-option, -fno-stack-protector)
-  CFLAGS_vgettimeofday-32.o += -DDISABLE_BRANCH_PROFILING
-  CFLAGS_vgettimeofday-32.o += -ffreestanding -fasynchronous-unwind-tables
-  CFLAGS_REMOVE_vgettimeofday-32.o = $(CC_FLAGS_FTRACE)
-  CFLAGS_REMOVE_vgettimeofday-32.o += -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc
-  # This flag is supported by clang for 64-bit but not 32-bit so it will cause
-  # an unused command line flag warning for this file.
-  ifdef CONFIG_CC_IS_CLANG
-  CFLAGS_REMOVE_vgettimeofday-32.o += -fno-stack-clash-protection
-  endif
-  CFLAGS_vgettimeofday-64.o += -include $(c-gettimeofday-y)
-  CFLAGS_vgettimeofday-64.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
-  CFLAGS_vgettimeofday-64.o += $(call cc-option, -fno-stack-protector)
-  CFLAGS_vgettimeofday-64.o += -DDISABLE_BRANCH_PROFILING
-  CFLAGS_vgettimeofday-64.o += -ffreestanding -fasynchronous-unwind-tables
-  CFLAGS_REMOVE_vgettimeofday-64.o = $(CC_FLAGS_FTRACE)
 # Go prior to 1.16.x assumes r30 is not clobbered by any VDSO code. That used to be true
 # by accident when the VDSO was hand-written asm code, but may not be now that the VDSO is
 # compiler generated. To avoid breaking Go tell GCC not to use r30. Impact on code
 # generation is minimal, it will just use r29 instead.
-  CFLAGS_vgettimeofday-64.o += $(call cc-option, -ffixed-r30)
+  CFLAGS_vgettimeofday-64.o += -include $(c-gettimeofday-y) $(call cc-option, -ffixed-r30)
 endif
 
 # Build rules
@@ -54,6 +37,11 @@
 KCSAN_SANITIZE := n
 
 ccflags-y := -fno-common -fno-builtin
+ccflags-y += $(DISABLE_LATENT_ENTROPY_PLUGIN)
+ccflags-y += $(call cc-option, -fno-stack-protector)
+ccflags-y += -DDISABLE_BRANCH_PROFILING
+ccflags-y += -ffreestanding -fasynchronous-unwind-tables
+ccflags-remove-y := $(CC_FLAGS_FTRACE)
 ldflags-y := -Wl,--hash-style=both -nostdlib -shared -z noexecstack $(CLANG_FLAGS)
 ldflags-$(CONFIG_LD_IS_LLD) += $(call cc-option,--ld-path=$(LD),-fuse-ld=lld)
 ldflags-$(CONFIG_LD_ORPHAN_WARN) += -Wl,--orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
@@ -62,6 +50,16 @@
 ldflags-y += $(filter-out $(CC_AUTO_VAR_INIT_ZERO_ENABLER) $(CC_FLAGS_FTRACE) -Wa$(comma)%, $(KBUILD_CFLAGS))
 
 CC32FLAGS := -m32
+CC32FLAGSREMOVE := -mcmodel=medium -mabi=elfv1 -mabi=elfv2 -mcall-aixdesc
+ifdef CONFIG_CC_IS_CLANG
+# This flag is supported by clang for 64-bit but not 32-bit so it will cause
+# an unused command line flag warning for this file.
+CC32FLAGSREMOVE += -fno-stack-clash-protection
+# -mstack-protector-guard values from the 64-bit build are not valid for the
+# 32-bit one. clang validates the values passed to these arguments during
+# parsing, even when -fno-stack-protector is passed afterwards.
+CC32FLAGSREMOVE += -mstack-protector-guard%
+endif
 LD32FLAGS := -Wl,-soname=linux-vdso32.so.1
 AS32FLAGS := -D__VDSO32__
 
@@ -108,7 +106,7 @@
 quiet_cmd_vdso32as = VDSO32A $@
       cmd_vdso32as = $(VDSOCC) $(a_flags) $(CC32FLAGS) $(AS32FLAGS) -c -o $@ $<
 quiet_cmd_vdso32cc = VDSO32C $@
-      cmd_vdso32cc = $(VDSOCC) $(c_flags) $(CC32FLAGS) -c -o $@ $<
+      cmd_vdso32cc = $(VDSOCC) $(filter-out $(CC32FLAGSREMOVE), $(c_flags)) $(CC32FLAGS) -c -o $@ $<
 
 quiet_cmd_vdso64ld_and_check = VDSO64L $@
       cmd_vdso64ld_and_check = $(VDSOCC) $(ldflags-y) $(LD64FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^); $(cmd_vdso_check)
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/vdso/cacheflush.S
+++ linux-qcom-6.8.0/arch/powerpc/kernel/vdso/cacheflush.S
@@ -30,7 +30,7 @@
 #ifdef CONFIG_PPC64
 	mflr	r12
   .cfi_register lr,r12
-	get_datapage	r10
+	get_realdatapage	r10, r11
 	mtlr	r12
   .cfi_restore	lr
 #endif
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/vdso/datapage.S
+++ linux-qcom-6.8.0/arch/powerpc/kernel/vdso/datapage.S
@@ -28,7 +28,7 @@
 	mflr	r12
   .cfi_register lr,r12
 	mr.	r4,r3
-	get_datapage	r3
+	get_realdatapage	r3, r11
 	mtlr	r12
 #ifdef __powerpc64__
 	addi	r3,r3,CFG_SYSCALL_MAP64
@@ -52,7 +52,7 @@
   .cfi_startproc
 	mflr	r12
   .cfi_register lr,r12
-	get_datapage	r3
+	get_realdatapage	r3, r11
 #ifndef __powerpc64__
 	lwz	r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
 #endif
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/vdso/gettimeofday.S
+++ linux-qcom-6.8.0/arch/powerpc/kernel/vdso/gettimeofday.S
@@ -38,11 +38,7 @@
 	.else
 	addi		r4, r5, VDSO_DATA_OFFSET
 	.endif
-#ifdef __powerpc64__
 	bl		CFUNC(DOTSYM(\funct))
-#else
-	bl		\funct
-#endif
 	PPC_LL		r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
 #ifdef __powerpc64__
 	PPC_LL		r2, PPC_MIN_STKFRM + STK_GOT(r1)
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/vdso/vdso32.lds.S
+++ linux-qcom-6.8.0/arch/powerpc/kernel/vdso/vdso32.lds.S
@@ -74,6 +74,8 @@
 	.got		: { *(.got) }			:text
 	.plt		: { *(.plt) }
 
+	.rela.dyn	: { *(.rela .rela*) }
+
 	_end = .;
 	__end = .;
 	PROVIDE(end = .);
@@ -87,7 +89,7 @@
 		*(.branch_lt)
 		*(.data .data.* .gnu.linkonce.d.* .sdata*)
 		*(.bss .sbss .dynbss .dynsbss)
-		*(.got1 .glink .iplt .rela*)
+		*(.got1 .glink .iplt)
 	}
 }
 
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/vdso/vdso64.lds.S
+++ linux-qcom-6.8.0/arch/powerpc/kernel/vdso/vdso64.lds.S
@@ -69,7 +69,7 @@
 	.eh_frame_hdr	: { *(.eh_frame_hdr) }		:text	:eh_frame_hdr
 	.eh_frame	: { KEEP (*(.eh_frame)) }	:text
 	.gcc_except_table : { *(.gcc_except_table) }
-	.rela.dyn ALIGN(8) : { *(.rela.dyn) }
+	.rela.dyn ALIGN(8) : { *(.rela .rela*) }
 
 	.got ALIGN(8)	: { *(.got .toc) }
 
@@ -86,7 +86,7 @@
 		*(.data .data.* .gnu.linkonce.d.* .sdata*)
 		*(.bss .sbss .dynbss .dynsbss)
 		*(.opd)
-		*(.glink .iplt .plt .rela*)
+		*(.glink .iplt .plt)
 	}
 }
 
--- linux-qcom-6.8.0.orig/arch/powerpc/kernel/vmlinux.lds.S
+++ linux-qcom-6.8.0/arch/powerpc/kernel/vmlinux.lds.S
@@ -123,8 +123,6 @@
 		 */
 		*(.sfpr);
 		*(.text.asan.* .text.tsan.*)
-		MEM_KEEP(init.text)
-		MEM_KEEP(exit.text)
 	} :text
 
 	. = ALIGN(PAGE_SIZE);
--- linux-qcom-6.8.0.orig/arch/powerpc/kexec/core_64.c
+++ linux-qcom-6.8.0/arch/powerpc/kexec/core_64.c
@@ -26,6 +26,7 @@
 #include <asm/paca.h>
 #include <asm/mmu.h>
 #include <asm/sections.h>	/* _end */
+#include <asm/setup.h>
 #include <asm/smp.h>
 #include <asm/hw_breakpoint.h>
 #include <asm/svm.h>
@@ -315,6 +316,16 @@
 	if (!kdump_in_progress())
 		kexec_prepare_cpus();
 
+#ifdef CONFIG_PPC_PSERIES
+	/*
+	 * This must be done after other CPUs have shut down, otherwise they
+	 * could execute the 'scv' instruction, which is not supported with
+	 * reloc disabled (see configure_exceptions()).
+	 */
+	if (firmware_has_feature(FW_FEATURE_SET_MODE))
+		pseries_disable_reloc_on_exc();
+#endif
+
 	printk("kexec: Starting switchover sequence.\n");
 
 	/* switch to a staticly allocated stack.  Based on irq stack code.
--- linux-qcom-6.8.0.orig/arch/powerpc/kexec/file_load_64.c
+++ linux-qcom-6.8.0/arch/powerpc/kexec/file_load_64.c
@@ -916,13 +916,18 @@
 	if (dn) {
 		u64 val;
 
-		of_property_read_u64(dn, "opal-base-address", &val);
+		ret = of_property_read_u64(dn, "opal-base-address", &val);
+		if (ret)
+			goto out;
+
 		ret = kexec_purgatory_get_set_symbol(image, "opal_base", &val,
 						     sizeof(val), false);
 		if (ret)
 			goto out;
 
-		of_property_read_u64(dn, "opal-entry-address", &val);
+		ret = of_property_read_u64(dn, "opal-entry-address", &val);
+		if (ret)
+			goto out;
 		ret = kexec_purgatory_get_set_symbol(image, "opal_entry", &val,
 						     sizeof(val), false);
 	}
--- linux-qcom-6.8.0.orig/arch/powerpc/kvm/book3s_64_vio.c
+++ linux-qcom-6.8.0/arch/powerpc/kvm/book3s_64_vio.c
@@ -130,14 +130,16 @@
 	}
 	rcu_read_unlock();
 
-	fdput(f);
-
-	if (!found)
+	if (!found) {
+		fdput(f);
 		return -EINVAL;
+	}
 
 	table_group = iommu_group_get_iommudata(grp);
-	if (WARN_ON(!table_group))
+	if (WARN_ON(!table_group)) {
+		fdput(f);
 		return -EFAULT;
+	}
 
 	for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
 		struct iommu_table *tbltmp = table_group->tables[i];
@@ -158,8 +160,10 @@
 			break;
 		}
 	}
-	if (!tbl)
+	if (!tbl) {
+		fdput(f);
 		return -EINVAL;
+	}
 
 	rcu_read_lock();
 	list_for_each_entry_rcu(stit, &stt->iommu_tables, next) {
@@ -170,6 +174,7 @@
 			/* stit is being destroyed */
 			iommu_tce_table_put(tbl);
 			rcu_read_unlock();
+			fdput(f);
 			return -ENOTTY;
 		}
 		/*
@@ -177,6 +182,7 @@
 		 * its KVM reference counter and can return.
 		 */
 		rcu_read_unlock();
+		fdput(f);
 		return 0;
 	}
 	rcu_read_unlock();
@@ -184,6 +190,7 @@
 	stit = kzalloc(sizeof(*stit), GFP_KERNEL);
 	if (!stit) {
 		iommu_tce_table_put(tbl);
+		fdput(f);
 		return -ENOMEM;
 	}
 
@@ -192,6 +199,7 @@
 
 	list_add_rcu(&stit->next, &stt->iommu_tables);
 
+	fdput(f);
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/arch/powerpc/kvm/book3s_hv.c
+++ linux-qcom-6.8.0/arch/powerpc/kvm/book3s_hv.c
@@ -2304,7 +2304,7 @@
 		*val = get_reg_val(id, kvmppc_get_siar_hv(vcpu));
 		break;
 	case KVM_REG_PPC_SDAR:
-		*val = get_reg_val(id, kvmppc_get_siar_hv(vcpu));
+		*val = get_reg_val(id, kvmppc_get_sdar_hv(vcpu));
 		break;
 	case KVM_REG_PPC_SIER:
 		*val = get_reg_val(id, kvmppc_get_sier_hv(vcpu, 0));
@@ -2348,6 +2348,15 @@
 	case KVM_REG_PPC_DAWRX1:
 		*val = get_reg_val(id, kvmppc_get_dawrx1_hv(vcpu));
 		break;
+	case KVM_REG_PPC_DEXCR:
+		*val = get_reg_val(id, kvmppc_get_dexcr_hv(vcpu));
+		break;
+	case KVM_REG_PPC_HASHKEYR:
+		*val = get_reg_val(id, kvmppc_get_hashkeyr_hv(vcpu));
+		break;
+	case KVM_REG_PPC_HASHPKEYR:
+		*val = get_reg_val(id, kvmppc_get_hashpkeyr_hv(vcpu));
+		break;
 	case KVM_REG_PPC_CIABR:
 		*val = get_reg_val(id, kvmppc_get_ciabr_hv(vcpu));
 		break;
@@ -2539,7 +2548,7 @@
 		vcpu->arch.mmcrs = set_reg_val(id, *val);
 		break;
 	case KVM_REG_PPC_MMCR3:
-		*val = get_reg_val(id, vcpu->arch.mmcr[3]);
+		kvmppc_set_mmcr_hv(vcpu, 3, set_reg_val(id, *val));
 		break;
 	case KVM_REG_PPC_PMC1 ... KVM_REG_PPC_PMC8:
 		i = id - KVM_REG_PPC_PMC1;
@@ -2591,6 +2600,15 @@
 	case KVM_REG_PPC_DAWRX1:
 		kvmppc_set_dawrx1_hv(vcpu, set_reg_val(id, *val) & ~DAWRX_HYP);
 		break;
+	case KVM_REG_PPC_DEXCR:
+		kvmppc_set_dexcr_hv(vcpu, set_reg_val(id, *val));
+		break;
+	case KVM_REG_PPC_HASHKEYR:
+		kvmppc_set_hashkeyr_hv(vcpu, set_reg_val(id, *val));
+		break;
+	case KVM_REG_PPC_HASHPKEYR:
+		kvmppc_set_hashpkeyr_hv(vcpu, set_reg_val(id, *val));
+		break;
 	case KVM_REG_PPC_CIABR:
 		kvmppc_set_ciabr_hv(vcpu, set_reg_val(id, *val));
 		/* Don't allow setting breakpoints in hypervisor code */
@@ -4115,6 +4133,11 @@
 	int trap;
 	long rc;
 
+	if (vcpu->arch.doorbell_request) {
+		vcpu->arch.doorbell_request = 0;
+		kvmppc_set_dpdes(vcpu, 1);
+	}
+
 	io = &vcpu->arch.nestedv2_io;
 
 	msr = mfmsr();
@@ -4205,6 +4228,15 @@
 	hvregs.hdec_expiry = time_limit;
 
 	/*
+	 * hvregs has the doorbell status, so zero it here which
+	 * enables us to receive doorbells when H_ENTER_NESTED is
+	 * in progress for this vCPU
+	 */
+
+	if (vcpu->arch.doorbell_request)
+		vcpu->arch.doorbell_request = 0;
+
+	/*
 	 * When setting DEC, we must always deal with irq_work_raise
 	 * via NMI vs setting DEC. The problem occurs right as we
 	 * switch into guest mode if a NMI hits and sets pending work
@@ -4793,9 +4825,20 @@
 							   BOOK3S_INTERRUPT_EXTERNAL, 0);
 			else
 				lpcr |= LPCR_MER;
+		} else {
+			/*
+			 * L1's copy of L2's LPCR (vcpu->arch.vcore->lpcr) can get its MER bit
+			 * unexpectedly set - for e.g. during NMI handling when all register
+			 * states are synchronized from L0 to L1. L1 needs to inform L0 about
+			 * MER=1 only when there are pending external interrupts.
+			 * In the above if check, MER bit is set if there are pending
+			 * external interrupts. Hence, explicity mask off MER bit
+			 * here as otherwise it may generate spurious interrupts in L2 KVM
+			 * causing an endless loop, which results in L2 guest getting hung.
+			 */
+			lpcr &= ~LPCR_MER;
 		}
 	} else if (vcpu->arch.pending_exceptions ||
-		   vcpu->arch.doorbell_request ||
 		   xive_interrupt_pending(vcpu)) {
 		vcpu->arch.ret = RESUME_HOST;
 		goto out;
@@ -4856,7 +4899,7 @@
 	 * entering a nested guest in which case the decrementer is now owned
 	 * by L2 and the L1 decrementer is provided in hdec_expires
 	 */
-	if (!kvmhv_is_nestedv2() && kvmppc_core_pending_dec(vcpu) &&
+	if (kvmppc_core_pending_dec(vcpu) &&
 			((tb < kvmppc_dec_expires_host_tb(vcpu)) ||
 			 (trap == BOOK3S_INTERRUPT_SYSCALL &&
 			  kvmppc_get_gpr(vcpu, 3) == H_ENTER_NESTED)))
@@ -6374,10 +6417,6 @@
 	.fast_vcpu_kick = kvmppc_fast_vcpu_kick_hv,
 	.arch_vm_ioctl  = kvm_arch_vm_ioctl_hv,
 	.hcall_implemented = kvmppc_hcall_impl_hv,
-#ifdef CONFIG_KVM_XICS
-	.irq_bypass_add_producer = kvmppc_irq_bypass_add_producer_hv,
-	.irq_bypass_del_producer = kvmppc_irq_bypass_del_producer_hv,
-#endif
 	.configure_mmu = kvmhv_configure_mmu,
 	.get_rmmu_info = kvmhv_get_rmmu_info,
 	.set_smt_mode = kvmhv_set_smt_mode,
@@ -6495,6 +6534,22 @@
 		return r;
 	}
 
+#if defined(CONFIG_KVM_XICS)
+	/*
+	 * IRQ bypass is supported only for interrupts whose EOI operations are
+	 * handled via OPAL calls. Therefore, register IRQ bypass handlers
+	 * exclusively for PowerNV KVM when booted with 'xive=off', indicating
+	 * the use of the emulated XICS interrupt controller.
+	 */
+	if (!kvmhv_on_pseries()) {
+		pr_info("KVM-HV: Enabling IRQ bypass\n");
+		kvm_ops_hv.irq_bypass_add_producer =
+			kvmppc_irq_bypass_add_producer_hv;
+		kvm_ops_hv.irq_bypass_del_producer =
+			kvmppc_irq_bypass_del_producer_hv;
+	}
+#endif
+
 	kvm_ops_hv.owner = THIS_MODULE;
 	kvmppc_hv_ops = &kvm_ops_hv;
 
--- linux-qcom-6.8.0.orig/arch/powerpc/kvm/book3s_hv.h
+++ linux-qcom-6.8.0/arch/powerpc/kvm/book3s_hv.h
@@ -116,6 +116,9 @@
 KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawr1, 64, KVMPPC_GSID_DAWR1)
 KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawrx0, 64, KVMPPC_GSID_DAWRX0)
 KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawrx1, 64, KVMPPC_GSID_DAWRX1)
+KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dexcr, 64, KVMPPC_GSID_DEXCR)
+KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(hashkeyr, 64, KVMPPC_GSID_HASHKEYR)
+KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(hashpkeyr, 64, KVMPPC_GSID_HASHPKEYR)
 KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ciabr, 64, KVMPPC_GSID_CIABR)
 KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(wort, 64, KVMPPC_GSID_WORT)
 KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ppr, 64, KVMPPC_GSID_PPR)
--- linux-qcom-6.8.0.orig/arch/powerpc/kvm/book3s_hv_nested.c
+++ linux-qcom-6.8.0/arch/powerpc/kvm/book3s_hv_nested.c
@@ -32,7 +32,7 @@
 	struct kvmppc_vcore *vc = vcpu->arch.vcore;
 
 	hr->pcr = vc->pcr | PCR_MASK;
-	hr->dpdes = vc->dpdes;
+	hr->dpdes = vcpu->arch.doorbell_request;
 	hr->hfscr = vcpu->arch.hfscr;
 	hr->tb_offset = vc->tb_offset;
 	hr->dawr0 = vcpu->arch.dawr0;
@@ -105,7 +105,7 @@
 {
 	struct kvmppc_vcore *vc = vcpu->arch.vcore;
 
-	hr->dpdes = vc->dpdes;
+	hr->dpdes = vcpu->arch.doorbell_request;
 	hr->purr = vcpu->arch.purr;
 	hr->spurr = vcpu->arch.spurr;
 	hr->ic = vcpu->arch.ic;
@@ -143,7 +143,7 @@
 	struct kvmppc_vcore *vc = vcpu->arch.vcore;
 
 	vc->pcr = hr->pcr | PCR_MASK;
-	vc->dpdes = hr->dpdes;
+	vcpu->arch.doorbell_request = hr->dpdes;
 	vcpu->arch.hfscr = hr->hfscr;
 	vcpu->arch.dawr0 = hr->dawr0;
 	vcpu->arch.dawrx0 = hr->dawrx0;
@@ -170,7 +170,13 @@
 {
 	struct kvmppc_vcore *vc = vcpu->arch.vcore;
 
-	vc->dpdes = hr->dpdes;
+	/*
+	 * This L2 vCPU might have received a doorbell while H_ENTER_NESTED was being handled.
+	 * Make sure we preserve the doorbell if it was either:
+	 *   a) Sent after H_ENTER_NESTED was called on this vCPU (arch.doorbell_request would be 1)
+	 *   b) Doorbell was not handled and L2 exited for some other reason (hr->dpdes would be 1)
+	 */
+	vcpu->arch.doorbell_request = vcpu->arch.doorbell_request | hr->dpdes;
 	vcpu->arch.hfscr = hr->hfscr;
 	vcpu->arch.purr = hr->purr;
 	vcpu->arch.spurr = hr->spurr;
--- linux-qcom-6.8.0.orig/arch/powerpc/kvm/book3s_hv_nestedv2.c
+++ linux-qcom-6.8.0/arch/powerpc/kvm/book3s_hv_nestedv2.c
@@ -71,8 +71,8 @@
 	}
 
 	if (kvmppc_gsm_includes(gsm, KVMPPC_GSID_RUN_OUTPUT)) {
-		kvmppc_gse_put_buff_info(gsb, KVMPPC_GSID_RUN_OUTPUT,
-					 cfg->vcpu_run_output_cfg);
+		rc = kvmppc_gse_put_buff_info(gsb, KVMPPC_GSID_RUN_OUTPUT,
+					      cfg->vcpu_run_output_cfg);
 		if (rc < 0)
 			return rc;
 	}
@@ -193,6 +193,15 @@
 		case KVMPPC_GSID_DAWRX1:
 			rc = kvmppc_gse_put_u32(gsb, iden, vcpu->arch.dawrx1);
 			break;
+		case KVMPPC_GSID_DEXCR:
+			rc = kvmppc_gse_put_u64(gsb, iden, vcpu->arch.dexcr);
+			break;
+		case KVMPPC_GSID_HASHKEYR:
+			rc = kvmppc_gse_put_u64(gsb, iden, vcpu->arch.hashkeyr);
+			break;
+		case KVMPPC_GSID_HASHPKEYR:
+			rc = kvmppc_gse_put_u64(gsb, iden, vcpu->arch.hashpkeyr);
+			break;
 		case KVMPPC_GSID_CIABR:
 			rc = kvmppc_gse_put_u64(gsb, iden, vcpu->arch.ciabr);
 			break;
@@ -311,6 +320,10 @@
 			rc = kvmppc_gse_put_u64(gsb, iden,
 						vcpu->arch.vcore->vtb);
 			break;
+		case KVMPPC_GSID_DPDES:
+			rc = kvmppc_gse_put_u64(gsb, iden,
+						vcpu->arch.vcore->dpdes);
+			break;
 		case KVMPPC_GSID_LPCR:
 			rc = kvmppc_gse_put_u64(gsb, iden,
 						vcpu->arch.vcore->lpcr);
@@ -441,6 +454,15 @@
 		case KVMPPC_GSID_DAWRX1:
 			vcpu->arch.dawrx1 = kvmppc_gse_get_u32(gse);
 			break;
+		case KVMPPC_GSID_DEXCR:
+			vcpu->arch.dexcr = kvmppc_gse_get_u64(gse);
+			break;
+		case KVMPPC_GSID_HASHKEYR:
+			vcpu->arch.hashkeyr = kvmppc_gse_get_u64(gse);
+			break;
+		case KVMPPC_GSID_HASHPKEYR:
+			vcpu->arch.hashpkeyr = kvmppc_gse_get_u64(gse);
+			break;
 		case KVMPPC_GSID_CIABR:
 			vcpu->arch.ciabr = kvmppc_gse_get_u64(gse);
 			break;
@@ -543,6 +565,9 @@
 		case KVMPPC_GSID_VTB:
 			vcpu->arch.vcore->vtb = kvmppc_gse_get_u64(gse);
 			break;
+		case KVMPPC_GSID_DPDES:
+			vcpu->arch.vcore->dpdes = kvmppc_gse_get_u64(gse);
+			break;
 		case KVMPPC_GSID_LPCR:
 			vcpu->arch.vcore->lpcr = kvmppc_gse_get_u64(gse);
 			break;
--- linux-qcom-6.8.0.orig/arch/powerpc/kvm/powerpc.c
+++ linux-qcom-6.8.0/arch/powerpc/kvm/powerpc.c
@@ -1984,8 +1984,10 @@
 			break;
 
 		r = -ENXIO;
-		if (!xive_enabled())
+		if (!xive_enabled()) {
+			fdput(f);
 			break;
+		}
 
 		r = -EPERM;
 		dev = kvm_device_from_filp(f.file);
--- linux-qcom-6.8.0.orig/arch/powerpc/kvm/test-guest-state-buffer.c
+++ linux-qcom-6.8.0/arch/powerpc/kvm/test-guest-state-buffer.c
@@ -151,7 +151,7 @@
 		i++;
 	}
 
-	for (u16 iden = KVMPPC_GSID_GPR(0); iden <= KVMPPC_GSID_CTRL; iden++) {
+	for (u16 iden = KVMPPC_GSID_GPR(0); iden <= KVMPPC_GSE_DW_REGS_END; iden++) {
 		kvmppc_gsbm_set(&gsbm, iden);
 		kvmppc_gsbm_set(&gsbm1, iden);
 		KUNIT_EXPECT_TRUE(test, kvmppc_gsbm_test(&gsbm, iden));
--- linux-qcom-6.8.0.orig/arch/powerpc/lib/Makefile
+++ linux-qcom-6.8.0/arch/powerpc/lib/Makefile
@@ -76,7 +76,7 @@
 obj-$(CONFIG_FTR_FIXUP_SELFTEST) += feature-fixups-test.o
 
 obj-$(CONFIG_ALTIVEC)	+= xor_vmx.o xor_vmx_glue.o
-CFLAGS_xor_vmx.o += -maltivec $(call cc-option,-mabi=altivec)
+CFLAGS_xor_vmx.o += -mhard-float -maltivec $(call cc-option,-mabi=altivec)
 # Enable <altivec.h>
 CFLAGS_xor_vmx.o += -isystem $(shell $(CC) -print-file-name=include)
 
--- linux-qcom-6.8.0.orig/arch/powerpc/lib/qspinlock.c
+++ linux-qcom-6.8.0/arch/powerpc/lib/qspinlock.c
@@ -697,7 +697,15 @@
 	}
 
 release:
-	qnodesp->count--; /* release the node */
+	/*
+	 * Clear the lock before releasing the node, as another CPU might see stale
+	 * values if an interrupt occurs after we increment qnodesp->count
+	 * but before node->lock is initialized. The barrier ensures that
+	 * there are no further stores to the node after it has been released.
+	 */
+	node->lock = NULL;
+	barrier();
+	qnodesp->count--;
 }
 
 void queued_spin_lock_slowpath(struct qspinlock *lock)
--- linux-qcom-6.8.0.orig/arch/powerpc/lib/sstep.c
+++ linux-qcom-6.8.0/arch/powerpc/lib/sstep.c
@@ -8,6 +8,7 @@
 #include <linux/kprobes.h>
 #include <linux/ptrace.h>
 #include <linux/prefetch.h>
+#include <asm/cpu_has_feature.h>
 #include <asm/sstep.h>
 #include <asm/processor.h>
 #include <linux/uaccess.h>
@@ -780,8 +781,8 @@
 #endif /* __powerpc64 */
 
 #ifdef CONFIG_VSX
-void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
-		      const void *mem, bool rev)
+static nokprobe_inline void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg,
+					     const void *mem, bool rev)
 {
 	int size, read_size;
 	int i, j;
@@ -863,11 +864,9 @@
 		break;
 	}
 }
-EXPORT_SYMBOL_GPL(emulate_vsx_load);
-NOKPROBE_SYMBOL(emulate_vsx_load);
 
-void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg,
-		       void *mem, bool rev)
+static nokprobe_inline void emulate_vsx_store(struct instruction_op *op, const union vsx_reg *reg,
+					      void *mem, bool rev)
 {
 	int size, write_size;
 	int i, j;
@@ -955,8 +954,6 @@
 		break;
 	}
 }
-EXPORT_SYMBOL_GPL(emulate_vsx_store);
-NOKPROBE_SYMBOL(emulate_vsx_store);
 
 static nokprobe_inline int do_vsx_load(struct instruction_op *op,
 				       unsigned long ea, struct pt_regs *regs,
--- linux-qcom-6.8.0.orig/arch/powerpc/mm/book3s64/pgtable.c
+++ linux-qcom-6.8.0/arch/powerpc/mm/book3s64/pgtable.c
@@ -130,7 +130,7 @@
 
 	WARN_ON(pte_hw_valid(pud_pte(*pudp)));
 	assert_spin_locked(pud_lockptr(mm, pudp));
-	WARN_ON(!(pud_large(pud)));
+	WARN_ON(!(pud_leaf(pud)));
 #endif
 	trace_hugepage_set_pud(addr, pud_val(pud));
 	return set_pte_at(mm, addr, pudp_ptep(pudp), pud_pte(pud));
@@ -170,6 +170,7 @@
 {
 	unsigned long old_pmd;
 
+	VM_WARN_ON_ONCE(!pmd_present(*pmdp));
 	old_pmd = pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_PRESENT, _PAGE_INVALID);
 	flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
 	return __pmd(old_pmd);
--- linux-qcom-6.8.0.orig/arch/powerpc/mm/book3s64/radix_pgtable.c
+++ linux-qcom-6.8.0/arch/powerpc/mm/book3s64/radix_pgtable.c
@@ -17,6 +17,7 @@
 #include <linux/hugetlb.h>
 #include <linux/string_helpers.h>
 #include <linux/memory.h>
+#include <linux/kfence.h>
 
 #include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
@@ -31,6 +32,7 @@
 #include <asm/uaccess.h>
 #include <asm/ultravisor.h>
 #include <asm/set_memory.h>
+#include <asm/kfence.h>
 
 #include <trace/events/thp.h>
 
@@ -293,7 +295,8 @@
 
 static int __meminit create_physical_mapping(unsigned long start,
 					     unsigned long end,
-					     int nid, pgprot_t _prot)
+					     int nid, pgprot_t _prot,
+					     unsigned long mapping_sz_limit)
 {
 	unsigned long vaddr, addr, mapping_size = 0;
 	bool prev_exec, exec = false;
@@ -301,7 +304,10 @@
 	int psize;
 	unsigned long max_mapping_size = memory_block_size;
 
-	if (debug_pagealloc_enabled_or_kfence())
+	if (mapping_sz_limit < max_mapping_size)
+		max_mapping_size = mapping_sz_limit;
+
+	if (debug_pagealloc_enabled())
 		max_mapping_size = PAGE_SIZE;
 
 	start = ALIGN(start, PAGE_SIZE);
@@ -356,8 +362,74 @@
 	return 0;
 }
 
+#ifdef CONFIG_KFENCE
+static bool __ro_after_init kfence_early_init = !!CONFIG_KFENCE_SAMPLE_INTERVAL;
+
+static int __init parse_kfence_early_init(char *arg)
+{
+	int val;
+
+	if (get_option(&arg, &val))
+		kfence_early_init = !!val;
+	return 0;
+}
+early_param("kfence.sample_interval", parse_kfence_early_init);
+
+static inline phys_addr_t alloc_kfence_pool(void)
+{
+	phys_addr_t kfence_pool;
+
+	/*
+	 * TODO: Support to enable KFENCE after bootup depends on the ability to
+	 *       split page table mappings. As such support is not currently
+	 *       implemented for radix pagetables, support enabling KFENCE
+	 *       only at system startup for now.
+	 *
+	 *       After support for splitting mappings is available on radix,
+	 *       alloc_kfence_pool() & map_kfence_pool() can be dropped and
+	 *       mapping for __kfence_pool memory can be
+	 *       split during arch_kfence_init_pool().
+	 */
+	if (!kfence_early_init)
+		goto no_kfence;
+
+	kfence_pool = memblock_phys_alloc(KFENCE_POOL_SIZE, PAGE_SIZE);
+	if (!kfence_pool)
+		goto no_kfence;
+
+	memblock_mark_nomap(kfence_pool, KFENCE_POOL_SIZE);
+	return kfence_pool;
+
+no_kfence:
+	disable_kfence();
+	return 0;
+}
+
+static inline void map_kfence_pool(phys_addr_t kfence_pool)
+{
+	if (!kfence_pool)
+		return;
+
+	if (create_physical_mapping(kfence_pool, kfence_pool + KFENCE_POOL_SIZE,
+				    -1, PAGE_KERNEL, PAGE_SIZE))
+		goto err;
+
+	memblock_clear_nomap(kfence_pool, KFENCE_POOL_SIZE);
+	__kfence_pool = __va(kfence_pool);
+	return;
+
+err:
+	memblock_phys_free(kfence_pool, KFENCE_POOL_SIZE);
+	disable_kfence();
+}
+#else
+static inline phys_addr_t alloc_kfence_pool(void) { return 0; }
+static inline void map_kfence_pool(phys_addr_t kfence_pool) { }
+#endif
+
 static void __init radix_init_pgtable(void)
 {
+	phys_addr_t kfence_pool;
 	unsigned long rts_field;
 	phys_addr_t start, end;
 	u64 i;
@@ -365,6 +437,8 @@
 	/* We don't support slb for radix */
 	slb_set_size(0);
 
+	kfence_pool = alloc_kfence_pool();
+
 	/*
 	 * Create the linear mapping
 	 */
@@ -381,9 +455,11 @@
 		}
 
 		WARN_ON(create_physical_mapping(start, end,
-						-1, PAGE_KERNEL));
+						-1, PAGE_KERNEL, ~0UL));
 	}
 
+	map_kfence_pool(kfence_pool);
+
 	if (!cpu_has_feature(CPU_FTR_HVMODE) &&
 			cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) {
 		/*
@@ -875,7 +951,7 @@
 	}
 
 	return create_physical_mapping(__pa(start), __pa(end),
-				       nid, prot);
+				       nid, prot, ~0UL);
 }
 
 int __meminit radix__remove_section_mapping(unsigned long start, unsigned long end)
--- linux-qcom-6.8.0.orig/arch/powerpc/mm/fault.c
+++ linux-qcom-6.8.0/arch/powerpc/mm/fault.c
@@ -432,10 +432,16 @@
 	/*
 	 * The kernel should never take an execute fault nor should it
 	 * take a page fault to a kernel address or a page fault to a user
-	 * address outside of dedicated places
+	 * address outside of dedicated places.
+	 *
+	 * Rather than kfence directly reporting false negatives, search whether
+	 * the NIP belongs to the fixup table for cases where fault could come
+	 * from functions like copy_from_kernel_nofault().
 	 */
 	if (unlikely(!is_user && bad_kernel_fault(regs, error_code, address, is_write))) {
-		if (kfence_handle_page_fault(address, is_write, regs))
+		if (is_kfence_address((void *)address) &&
+		    !search_exception_tables(instruction_pointer(regs)) &&
+		    kfence_handle_page_fault(address, is_write, regs))
 			return 0;
 
 		return SIGSEGV;
--- linux-qcom-6.8.0.orig/arch/powerpc/mm/init-common.c
+++ linux-qcom-6.8.0/arch/powerpc/mm/init-common.c
@@ -31,6 +31,9 @@
 
 bool disable_kuep = !IS_ENABLED(CONFIG_PPC_KUEP);
 bool disable_kuap = !IS_ENABLED(CONFIG_PPC_KUAP);
+#ifdef CONFIG_KFENCE
+bool __ro_after_init kfence_disabled;
+#endif
 
 static int __init parse_nosmep(char *p)
 {
--- linux-qcom-6.8.0.orig/arch/powerpc/mm/mem.c
+++ linux-qcom-6.8.0/arch/powerpc/mm/mem.c
@@ -288,8 +288,6 @@
 	swiotlb_init(ppc_swiotlb_enable, ppc_swiotlb_flags);
 #endif
 
-	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
-
 	kasan_late_init();
 
 	memblock_free_all();
--- linux-qcom-6.8.0.orig/arch/powerpc/mm/nohash/8xx.c
+++ linux-qcom-6.8.0/arch/powerpc/mm/nohash/8xx.c
@@ -94,7 +94,8 @@
 		return -EINVAL;
 
 	set_huge_pte_at(&init_mm, va, ptep,
-			pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)), psize);
+			pte_mkhuge(pfn_pte(pa >> PAGE_SHIFT, prot)),
+			1UL << mmu_psize_to_shift(psize));
 
 	return 0;
 }
@@ -150,11 +151,11 @@
 
 	mmu_mapin_immr();
 
-	mmu_mapin_ram_chunk(0, boundary, PAGE_KERNEL_TEXT, true);
+	mmu_mapin_ram_chunk(0, boundary, PAGE_KERNEL_X, true);
 	if (debug_pagealloc_enabled_or_kfence()) {
 		top = boundary;
 	} else {
-		mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL_TEXT, true);
+		mmu_mapin_ram_chunk(boundary, einittext8, PAGE_KERNEL_X, true);
 		mmu_mapin_ram_chunk(einittext8, top, PAGE_KERNEL, true);
 	}
 
--- linux-qcom-6.8.0.orig/arch/powerpc/mm/nohash/Makefile
+++ linux-qcom-6.8.0/arch/powerpc/mm/nohash/Makefile
@@ -3,7 +3,7 @@
 ccflags-$(CONFIG_PPC64)	:= $(NO_MINIMAL_TOC)
 
 obj-y				+= mmu_context.o tlb.o tlb_low.o kup.o
-obj-$(CONFIG_PPC_BOOK3E_64)  	+= tlb_low_64e.o book3e_pgtable.o
+obj-$(CONFIG_PPC_BOOK3E_64)  	+= tlb_64e.o tlb_low_64e.o book3e_pgtable.o
 obj-$(CONFIG_40x)		+= 40x.o
 obj-$(CONFIG_44x)		+= 44x.o
 obj-$(CONFIG_PPC_8xx)		+= 8xx.o
--- linux-qcom-6.8.0.orig/arch/powerpc/mm/nohash/tlb.c
+++ linux-qcom-6.8.0/arch/powerpc/mm/nohash/tlb.c
@@ -110,28 +110,6 @@
 };
 #endif
 
-/* The variables below are currently only used on 64-bit Book3E
- * though this will probably be made common with other nohash
- * implementations at some point
- */
-#ifdef CONFIG_PPC64
-
-int mmu_pte_psize;		/* Page size used for PTE pages */
-int mmu_vmemmap_psize;		/* Page size used for the virtual mem map */
-int book3e_htw_mode;		/* HW tablewalk?  Value is PPC_HTW_* */
-unsigned long linear_map_top;	/* Top of linear mapping */
-
-
-/*
- * Number of bytes to add to SPRN_SPRG_TLB_EXFRAME on crit/mcheck/debug
- * exceptions.  This is used for bolted and e6500 TLB miss handlers which
- * do not modify this SPRG in the TLB miss code; for other TLB miss handlers,
- * this is set to zero.
- */
-int extlb_level_exc;
-
-#endif /* CONFIG_PPC64 */
-
 #ifdef CONFIG_PPC_E500
 /* next_tlbcam_idx is used to round-robin tlbcam entry assignment */
 DEFINE_PER_CPU(int, next_tlbcam_idx);
@@ -358,381 +336,7 @@
 	flush_tlb_mm(tlb->mm);
 }
 
-/*
- * Below are functions specific to the 64-bit variant of Book3E though that
- * may change in the future
- */
-
-#ifdef CONFIG_PPC64
-
-/*
- * Handling of virtual linear page tables or indirect TLB entries
- * flushing when PTE pages are freed
- */
-void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address)
-{
-	int tsize = mmu_psize_defs[mmu_pte_psize].enc;
-
-	if (book3e_htw_mode != PPC_HTW_NONE) {
-		unsigned long start = address & PMD_MASK;
-		unsigned long end = address + PMD_SIZE;
-		unsigned long size = 1UL << mmu_psize_defs[mmu_pte_psize].shift;
-
-		/* This isn't the most optimal, ideally we would factor out the
-		 * while preempt & CPU mask mucking around, or even the IPI but
-		 * it will do for now
-		 */
-		while (start < end) {
-			__flush_tlb_page(tlb->mm, start, tsize, 1);
-			start += size;
-		}
-	} else {
-		unsigned long rmask = 0xf000000000000000ul;
-		unsigned long rid = (address & rmask) | 0x1000000000000000ul;
-		unsigned long vpte = address & ~rmask;
-
-		vpte = (vpte >> (PAGE_SHIFT - 3)) & ~0xffful;
-		vpte |= rid;
-		__flush_tlb_page(tlb->mm, vpte, tsize, 0);
-	}
-}
-
-static void __init setup_page_sizes(void)
-{
-	unsigned int tlb0cfg;
-	unsigned int tlb0ps;
-	unsigned int eptcfg;
-	int i, psize;
-
-#ifdef CONFIG_PPC_E500
-	unsigned int mmucfg = mfspr(SPRN_MMUCFG);
-	int fsl_mmu = mmu_has_feature(MMU_FTR_TYPE_FSL_E);
-
-	if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) {
-		unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG);
-		unsigned int min_pg, max_pg;
-
-		min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
-		max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT;
-
-		for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
-			struct mmu_psize_def *def;
-			unsigned int shift;
-
-			def = &mmu_psize_defs[psize];
-			shift = def->shift;
-
-			if (shift == 0 || shift & 1)
-				continue;
-
-			/* adjust to be in terms of 4^shift Kb */
-			shift = (shift - 10) >> 1;
-
-			if ((shift >= min_pg) && (shift <= max_pg))
-				def->flags |= MMU_PAGE_SIZE_DIRECT;
-		}
-
-		goto out;
-	}
-
-	if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2) {
-		u32 tlb1cfg, tlb1ps;
-
-		tlb0cfg = mfspr(SPRN_TLB0CFG);
-		tlb1cfg = mfspr(SPRN_TLB1CFG);
-		tlb1ps = mfspr(SPRN_TLB1PS);
-		eptcfg = mfspr(SPRN_EPTCFG);
-
-		if ((tlb1cfg & TLBnCFG_IND) && (tlb0cfg & TLBnCFG_PT))
-			book3e_htw_mode = PPC_HTW_E6500;
-
-		/*
-		 * We expect 4K subpage size and unrestricted indirect size.
-		 * The lack of a restriction on indirect size is a Freescale
-		 * extension, indicated by PSn = 0 but SPSn != 0.
-		 */
-		if (eptcfg != 2)
-			book3e_htw_mode = PPC_HTW_NONE;
-
-		for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
-			struct mmu_psize_def *def = &mmu_psize_defs[psize];
-
-			if (!def->shift)
-				continue;
-
-			if (tlb1ps & (1U << (def->shift - 10))) {
-				def->flags |= MMU_PAGE_SIZE_DIRECT;
-
-				if (book3e_htw_mode && psize == MMU_PAGE_2M)
-					def->flags |= MMU_PAGE_SIZE_INDIRECT;
-			}
-		}
-
-		goto out;
-	}
-#endif
-
-	tlb0cfg = mfspr(SPRN_TLB0CFG);
-	tlb0ps = mfspr(SPRN_TLB0PS);
-	eptcfg = mfspr(SPRN_EPTCFG);
-
-	/* Look for supported direct sizes */
-	for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
-		struct mmu_psize_def *def = &mmu_psize_defs[psize];
-
-		if (tlb0ps & (1U << (def->shift - 10)))
-			def->flags |= MMU_PAGE_SIZE_DIRECT;
-	}
-
-	/* Indirect page sizes supported ? */
-	if ((tlb0cfg & TLBnCFG_IND) == 0 ||
-	    (tlb0cfg & TLBnCFG_PT) == 0)
-		goto out;
-
-	book3e_htw_mode = PPC_HTW_IBM;
-
-	/* Now, we only deal with one IND page size for each
-	 * direct size. Hopefully all implementations today are
-	 * unambiguous, but we might want to be careful in the
-	 * future.
-	 */
-	for (i = 0; i < 3; i++) {
-		unsigned int ps, sps;
-
-		sps = eptcfg & 0x1f;
-		eptcfg >>= 5;
-		ps = eptcfg & 0x1f;
-		eptcfg >>= 5;
-		if (!ps || !sps)
-			continue;
-		for (psize = 0; psize < MMU_PAGE_COUNT; psize++) {
-			struct mmu_psize_def *def = &mmu_psize_defs[psize];
-
-			if (ps == (def->shift - 10))
-				def->flags |= MMU_PAGE_SIZE_INDIRECT;
-			if (sps == (def->shift - 10))
-				def->ind = ps + 10;
-		}
-	}
-
-out:
-	/* Cleanup array and print summary */
-	pr_info("MMU: Supported page sizes\n");
-	for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
-		struct mmu_psize_def *def = &mmu_psize_defs[psize];
-		const char *__page_type_names[] = {
-			"unsupported",
-			"direct",
-			"indirect",
-			"direct & indirect"
-		};
-		if (def->flags == 0) {
-			def->shift = 0;	
-			continue;
-		}
-		pr_info("  %8ld KB as %s\n", 1ul << (def->shift - 10),
-			__page_type_names[def->flags & 0x3]);
-	}
-}
-
-static void __init setup_mmu_htw(void)
-{
-	/*
-	 * If we want to use HW tablewalk, enable it by patching the TLB miss
-	 * handlers to branch to the one dedicated to it.
-	 */
-
-	switch (book3e_htw_mode) {
-	case PPC_HTW_IBM:
-		patch_exception(0x1c0, exc_data_tlb_miss_htw_book3e);
-		patch_exception(0x1e0, exc_instruction_tlb_miss_htw_book3e);
-		break;
-#ifdef CONFIG_PPC_E500
-	case PPC_HTW_E6500:
-		extlb_level_exc = EX_TLB_SIZE;
-		patch_exception(0x1c0, exc_data_tlb_miss_e6500_book3e);
-		patch_exception(0x1e0, exc_instruction_tlb_miss_e6500_book3e);
-		break;
-#endif
-	}
-	pr_info("MMU: Book3E HW tablewalk %s\n",
-		book3e_htw_mode != PPC_HTW_NONE ? "enabled" : "not supported");
-}
-
-/*
- * Early initialization of the MMU TLB code
- */
-static void early_init_this_mmu(void)
-{
-	unsigned int mas4;
-
-	/* Set MAS4 based on page table setting */
-
-	mas4 = 0x4 << MAS4_WIMGED_SHIFT;
-	switch (book3e_htw_mode) {
-	case PPC_HTW_E6500:
-		mas4 |= MAS4_INDD;
-		mas4 |= BOOK3E_PAGESZ_2M << MAS4_TSIZED_SHIFT;
-		mas4 |= MAS4_TLBSELD(1);
-		mmu_pte_psize = MMU_PAGE_2M;
-		break;
-
-	case PPC_HTW_IBM:
-		mas4 |= MAS4_INDD;
-		mas4 |=	BOOK3E_PAGESZ_1M << MAS4_TSIZED_SHIFT;
-		mmu_pte_psize = MMU_PAGE_1M;
-		break;
-
-	case PPC_HTW_NONE:
-		mas4 |=	BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT;
-		mmu_pte_psize = mmu_virtual_psize;
-		break;
-	}
-	mtspr(SPRN_MAS4, mas4);
-
-#ifdef CONFIG_PPC_E500
-	if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
-		unsigned int num_cams;
-		bool map = true;
-
-		/* use a quarter of the TLBCAM for bolted linear map */
-		num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
-
-		/*
-		 * Only do the mapping once per core, or else the
-		 * transient mapping would cause problems.
-		 */
-#ifdef CONFIG_SMP
-		if (hweight32(get_tensr()) > 1)
-			map = false;
-#endif
-
-		if (map)
-			linear_map_top = map_mem_in_cams(linear_map_top,
-							 num_cams, false, true);
-	}
-#endif
-
-	/* A sync won't hurt us after mucking around with
-	 * the MMU configuration
-	 */
-	mb();
-}
-
-static void __init early_init_mmu_global(void)
-{
-	/* XXX This should be decided at runtime based on supported
-	 * page sizes in the TLB, but for now let's assume 16M is
-	 * always there and a good fit (which it probably is)
-	 *
-	 * Freescale booke only supports 4K pages in TLB0, so use that.
-	 */
-	if (mmu_has_feature(MMU_FTR_TYPE_FSL_E))
-		mmu_vmemmap_psize = MMU_PAGE_4K;
-	else
-		mmu_vmemmap_psize = MMU_PAGE_16M;
-
-	/* XXX This code only checks for TLB 0 capabilities and doesn't
-	 *     check what page size combos are supported by the HW. It
-	 *     also doesn't handle the case where a separate array holds
-	 *     the IND entries from the array loaded by the PT.
-	 */
-	/* Look for supported page sizes */
-	setup_page_sizes();
-
-	/* Look for HW tablewalk support */
-	setup_mmu_htw();
-
-#ifdef CONFIG_PPC_E500
-	if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
-		if (book3e_htw_mode == PPC_HTW_NONE) {
-			extlb_level_exc = EX_TLB_SIZE;
-			patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e);
-			patch_exception(0x1e0,
-				exc_instruction_tlb_miss_bolted_book3e);
-		}
-	}
-#endif
-
-	/* Set the global containing the top of the linear mapping
-	 * for use by the TLB miss code
-	 */
-	linear_map_top = memblock_end_of_DRAM();
-
-	ioremap_bot = IOREMAP_BASE;
-}
-
-static void __init early_mmu_set_memory_limit(void)
-{
-#ifdef CONFIG_PPC_E500
-	if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
-		/*
-		 * Limit memory so we dont have linear faults.
-		 * Unlike memblock_set_current_limit, which limits
-		 * memory available during early boot, this permanently
-		 * reduces the memory available to Linux.  We need to
-		 * do this because highmem is not supported on 64-bit.
-		 */
-		memblock_enforce_memory_limit(linear_map_top);
-	}
-#endif
-
-	memblock_set_current_limit(linear_map_top);
-}
-
-/* boot cpu only */
-void __init early_init_mmu(void)
-{
-	early_init_mmu_global();
-	early_init_this_mmu();
-	early_mmu_set_memory_limit();
-}
-
-void early_init_mmu_secondary(void)
-{
-	early_init_this_mmu();
-}
-
-void setup_initial_memory_limit(phys_addr_t first_memblock_base,
-				phys_addr_t first_memblock_size)
-{
-	/* On non-FSL Embedded 64-bit, we adjust the RMA size to match
-	 * the bolted TLB entry. We know for now that only 1G
-	 * entries are supported though that may eventually
-	 * change.
-	 *
-	 * on FSL Embedded 64-bit, usually all RAM is bolted, but with
-	 * unusual memory sizes it's possible for some RAM to not be mapped
-	 * (such RAM is not used at all by Linux, since we don't support
-	 * highmem on 64-bit).  We limit ppc64_rma_size to what would be
-	 * mappable if this memblock is the only one.  Additional memblocks
-	 * can only increase, not decrease, the amount that ends up getting
-	 * mapped.  We still limit max to 1G even if we'll eventually map
-	 * more.  This is due to what the early init code is set up to do.
-	 *
-	 * We crop it to the size of the first MEMBLOCK to
-	 * avoid going over total available memory just in case...
-	 */
-#ifdef CONFIG_PPC_E500
-	if (early_mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
-		unsigned long linear_sz;
-		unsigned int num_cams;
-
-		/* use a quarter of the TLBCAM for bolted linear map */
-		num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
-
-		linear_sz = map_mem_in_cams(first_memblock_size, num_cams,
-					    true, true);
-
-		ppc64_rma_size = min_t(u64, linear_sz, 0x40000000);
-	} else
-#endif
-		ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
-
-	/* Finally limit subsequent allocations */
-	memblock_set_current_limit(first_memblock_base + ppc64_rma_size);
-}
-#else /* ! CONFIG_PPC64 */
+#ifndef CONFIG_PPC64
 void __init early_init_mmu(void)
 {
 	unsigned long root = of_get_flat_dt_root();
--- linux-qcom-6.8.0.orig/arch/powerpc/mm/nohash/tlb_64e.c
+++ linux-qcom-6.8.0/arch/powerpc/mm/nohash/tlb_64e.c
@@ -0,0 +1,361 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2008,2009 Ben Herrenschmidt <benh@kernel.crashing.org>
+ *                     IBM Corp.
+ *
+ *  Derived from arch/ppc/mm/init.c:
+ *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ *    Copyright (C) 1996 Paul Mackerras
+ *
+ *  Derived from "arch/i386/mm/init.c"
+ *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ */
+
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/pagemap.h>
+#include <linux/memblock.h>
+
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+#include <asm/tlb.h>
+#include <asm/code-patching.h>
+#include <asm/cputhreads.h>
+
+#include <mm/mmu_decl.h>
+
+/* The variables below are currently only used on 64-bit Book3E
+ * though this will probably be made common with other nohash
+ * implementations at some point
+ */
+static int mmu_pte_psize;	/* Page size used for PTE pages */
+int mmu_vmemmap_psize;		/* Page size used for the virtual mem map */
+int book3e_htw_mode;		/* HW tablewalk?  Value is PPC_HTW_* */
+unsigned long linear_map_top;	/* Top of linear mapping */
+
+
+/*
+ * Number of bytes to add to SPRN_SPRG_TLB_EXFRAME on crit/mcheck/debug
+ * exceptions.  This is used for bolted and e6500 TLB miss handlers which
+ * do not modify this SPRG in the TLB miss code; for other TLB miss handlers,
+ * this is set to zero.
+ */
+int extlb_level_exc;
+
+/*
+ * Handling of virtual linear page tables or indirect TLB entries
+ * flushing when PTE pages are freed
+ */
+void tlb_flush_pgtable(struct mmu_gather *tlb, unsigned long address)
+{
+	int tsize = mmu_psize_defs[mmu_pte_psize].enc;
+
+	if (book3e_htw_mode != PPC_HTW_NONE) {
+		unsigned long start = address & PMD_MASK;
+		unsigned long end = address + PMD_SIZE;
+		unsigned long size = 1UL << mmu_psize_defs[mmu_pte_psize].shift;
+
+		/* This isn't the most optimal, ideally we would factor out the
+		 * while preempt & CPU mask mucking around, or even the IPI but
+		 * it will do for now
+		 */
+		while (start < end) {
+			__flush_tlb_page(tlb->mm, start, tsize, 1);
+			start += size;
+		}
+	} else {
+		unsigned long rmask = 0xf000000000000000ul;
+		unsigned long rid = (address & rmask) | 0x1000000000000000ul;
+		unsigned long vpte = address & ~rmask;
+
+		vpte = (vpte >> (PAGE_SHIFT - 3)) & ~0xffful;
+		vpte |= rid;
+		__flush_tlb_page(tlb->mm, vpte, tsize, 0);
+	}
+}
+
+static void __init setup_page_sizes(void)
+{
+	unsigned int tlb0cfg;
+	unsigned int eptcfg;
+	int psize;
+
+#ifdef CONFIG_PPC_E500
+	unsigned int mmucfg = mfspr(SPRN_MMUCFG);
+	int fsl_mmu = mmu_has_feature(MMU_FTR_TYPE_FSL_E);
+
+	if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V1) {
+		unsigned int tlb1cfg = mfspr(SPRN_TLB1CFG);
+		unsigned int min_pg, max_pg;
+
+		min_pg = (tlb1cfg & TLBnCFG_MINSIZE) >> TLBnCFG_MINSIZE_SHIFT;
+		max_pg = (tlb1cfg & TLBnCFG_MAXSIZE) >> TLBnCFG_MAXSIZE_SHIFT;
+
+		for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+			struct mmu_psize_def *def;
+			unsigned int shift;
+
+			def = &mmu_psize_defs[psize];
+			shift = def->shift;
+
+			if (shift == 0 || shift & 1)
+				continue;
+
+			/* adjust to be in terms of 4^shift Kb */
+			shift = (shift - 10) >> 1;
+
+			if ((shift >= min_pg) && (shift <= max_pg))
+				def->flags |= MMU_PAGE_SIZE_DIRECT;
+		}
+
+		goto out;
+	}
+
+	if (fsl_mmu && (mmucfg & MMUCFG_MAVN) == MMUCFG_MAVN_V2) {
+		u32 tlb1cfg, tlb1ps;
+
+		tlb0cfg = mfspr(SPRN_TLB0CFG);
+		tlb1cfg = mfspr(SPRN_TLB1CFG);
+		tlb1ps = mfspr(SPRN_TLB1PS);
+		eptcfg = mfspr(SPRN_EPTCFG);
+
+		if ((tlb1cfg & TLBnCFG_IND) && (tlb0cfg & TLBnCFG_PT))
+			book3e_htw_mode = PPC_HTW_E6500;
+
+		/*
+		 * We expect 4K subpage size and unrestricted indirect size.
+		 * The lack of a restriction on indirect size is a Freescale
+		 * extension, indicated by PSn = 0 but SPSn != 0.
+		 */
+		if (eptcfg != 2)
+			book3e_htw_mode = PPC_HTW_NONE;
+
+		for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+			struct mmu_psize_def *def = &mmu_psize_defs[psize];
+
+			if (!def->shift)
+				continue;
+
+			if (tlb1ps & (1U << (def->shift - 10))) {
+				def->flags |= MMU_PAGE_SIZE_DIRECT;
+
+				if (book3e_htw_mode && psize == MMU_PAGE_2M)
+					def->flags |= MMU_PAGE_SIZE_INDIRECT;
+			}
+		}
+
+		goto out;
+	}
+#endif
+out:
+	/* Cleanup array and print summary */
+	pr_info("MMU: Supported page sizes\n");
+	for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
+		struct mmu_psize_def *def = &mmu_psize_defs[psize];
+		const char *__page_type_names[] = {
+			"unsupported",
+			"direct",
+			"indirect",
+			"direct & indirect"
+		};
+		if (def->flags == 0) {
+			def->shift = 0;
+			continue;
+		}
+		pr_info("  %8ld KB as %s\n", 1ul << (def->shift - 10),
+			__page_type_names[def->flags & 0x3]);
+	}
+}
+
+static void __init setup_mmu_htw(void)
+{
+	/*
+	 * If we want to use HW tablewalk, enable it by patching the TLB miss
+	 * handlers to branch to the one dedicated to it.
+	 */
+
+	switch (book3e_htw_mode) {
+#ifdef CONFIG_PPC_E500
+	case PPC_HTW_E6500:
+		extlb_level_exc = EX_TLB_SIZE;
+		patch_exception(0x1c0, exc_data_tlb_miss_e6500_book3e);
+		patch_exception(0x1e0, exc_instruction_tlb_miss_e6500_book3e);
+		break;
+#endif
+	}
+	pr_info("MMU: Book3E HW tablewalk %s\n",
+		book3e_htw_mode != PPC_HTW_NONE ? "enabled" : "not supported");
+}
+
+/*
+ * Early initialization of the MMU TLB code
+ */
+static void early_init_this_mmu(void)
+{
+	unsigned int mas4;
+
+	/* Set MAS4 based on page table setting */
+
+	mas4 = 0x4 << MAS4_WIMGED_SHIFT;
+	switch (book3e_htw_mode) {
+	case PPC_HTW_E6500:
+		mas4 |= MAS4_INDD;
+		mas4 |= BOOK3E_PAGESZ_2M << MAS4_TSIZED_SHIFT;
+		mas4 |= MAS4_TLBSELD(1);
+		mmu_pte_psize = MMU_PAGE_2M;
+		break;
+
+	case PPC_HTW_NONE:
+		mas4 |=	BOOK3E_PAGESZ_4K << MAS4_TSIZED_SHIFT;
+		mmu_pte_psize = mmu_virtual_psize;
+		break;
+	}
+	mtspr(SPRN_MAS4, mas4);
+
+#ifdef CONFIG_PPC_E500
+	if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
+		unsigned int num_cams;
+		bool map = true;
+
+		/* use a quarter of the TLBCAM for bolted linear map */
+		num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
+
+		/*
+		 * Only do the mapping once per core, or else the
+		 * transient mapping would cause problems.
+		 */
+#ifdef CONFIG_SMP
+		if (hweight32(get_tensr()) > 1)
+			map = false;
+#endif
+
+		if (map)
+			linear_map_top = map_mem_in_cams(linear_map_top,
+							 num_cams, false, true);
+	}
+#endif
+
+	/* A sync won't hurt us after mucking around with
+	 * the MMU configuration
+	 */
+	mb();
+}
+
+static void __init early_init_mmu_global(void)
+{
+	/* XXX This should be decided at runtime based on supported
+	 * page sizes in the TLB, but for now let's assume 16M is
+	 * always there and a good fit (which it probably is)
+	 *
+	 * Freescale booke only supports 4K pages in TLB0, so use that.
+	 */
+	if (mmu_has_feature(MMU_FTR_TYPE_FSL_E))
+		mmu_vmemmap_psize = MMU_PAGE_4K;
+	else
+		mmu_vmemmap_psize = MMU_PAGE_16M;
+
+	/* XXX This code only checks for TLB 0 capabilities and doesn't
+	 *     check what page size combos are supported by the HW. It
+	 *     also doesn't handle the case where a separate array holds
+	 *     the IND entries from the array loaded by the PT.
+	 */
+	/* Look for supported page sizes */
+	setup_page_sizes();
+
+	/* Look for HW tablewalk support */
+	setup_mmu_htw();
+
+#ifdef CONFIG_PPC_E500
+	if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
+		if (book3e_htw_mode == PPC_HTW_NONE) {
+			extlb_level_exc = EX_TLB_SIZE;
+			patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e);
+			patch_exception(0x1e0,
+				exc_instruction_tlb_miss_bolted_book3e);
+		}
+	}
+#endif
+
+	/* Set the global containing the top of the linear mapping
+	 * for use by the TLB miss code
+	 */
+	linear_map_top = memblock_end_of_DRAM();
+
+	ioremap_bot = IOREMAP_BASE;
+}
+
+static void __init early_mmu_set_memory_limit(void)
+{
+#ifdef CONFIG_PPC_E500
+	if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
+		/*
+		 * Limit memory so we dont have linear faults.
+		 * Unlike memblock_set_current_limit, which limits
+		 * memory available during early boot, this permanently
+		 * reduces the memory available to Linux.  We need to
+		 * do this because highmem is not supported on 64-bit.
+		 */
+		memblock_enforce_memory_limit(linear_map_top);
+	}
+#endif
+
+	memblock_set_current_limit(linear_map_top);
+}
+
+/* boot cpu only */
+void __init early_init_mmu(void)
+{
+	early_init_mmu_global();
+	early_init_this_mmu();
+	early_mmu_set_memory_limit();
+}
+
+void early_init_mmu_secondary(void)
+{
+	early_init_this_mmu();
+}
+
+void setup_initial_memory_limit(phys_addr_t first_memblock_base,
+				phys_addr_t first_memblock_size)
+{
+	/* On non-FSL Embedded 64-bit, we adjust the RMA size to match
+	 * the bolted TLB entry. We know for now that only 1G
+	 * entries are supported though that may eventually
+	 * change.
+	 *
+	 * on FSL Embedded 64-bit, usually all RAM is bolted, but with
+	 * unusual memory sizes it's possible for some RAM to not be mapped
+	 * (such RAM is not used at all by Linux, since we don't support
+	 * highmem on 64-bit).  We limit ppc64_rma_size to what would be
+	 * mappable if this memblock is the only one.  Additional memblocks
+	 * can only increase, not decrease, the amount that ends up getting
+	 * mapped.  We still limit max to 1G even if we'll eventually map
+	 * more.  This is due to what the early init code is set up to do.
+	 *
+	 * We crop it to the size of the first MEMBLOCK to
+	 * avoid going over total available memory just in case...
+	 */
+#ifdef CONFIG_PPC_E500
+	if (early_mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
+		unsigned long linear_sz;
+		unsigned int num_cams;
+
+		/* use a quarter of the TLBCAM for bolted linear map */
+		num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
+
+		linear_sz = map_mem_in_cams(first_memblock_size, num_cams,
+					    true, true);
+
+		ppc64_rma_size = min_t(u64, linear_sz, 0x40000000);
+	} else
+#endif
+		ppc64_rma_size = min_t(u64, first_memblock_size, 0x40000000);
+
+	/* Finally limit subsequent allocations */
+	memblock_set_current_limit(first_memblock_base + ppc64_rma_size);
+}
--- linux-qcom-6.8.0.orig/arch/powerpc/mm/nohash/tlb_low_64e.S
+++ linux-qcom-6.8.0/arch/powerpc/mm/nohash/tlb_low_64e.S
@@ -893,201 +893,6 @@
 	TLB_MISS_EPILOG_ERROR
 	b	exc_data_storage_book3e
 
-
-/**************************************************************
- *                                                            *
- * TLB miss handling for Book3E with hw page table support    *
- *                                                            *
- **************************************************************/
-
-
-/* Data TLB miss */
-	START_EXCEPTION(data_tlb_miss_htw)
-	TLB_MISS_PROLOG
-
-	/* Now we handle the fault proper. We only save DEAR in normal
-	 * fault case since that's the only interesting values here.
-	 * We could probably also optimize by not saving SRR0/1 in the
-	 * linear mapping case but I'll leave that for later
-	 */
-	mfspr	r14,SPRN_ESR
-	mfspr	r16,SPRN_DEAR		/* get faulting address */
-	srdi	r11,r16,44		/* get region */
-	xoris	r11,r11,0xc
-	cmpldi	cr0,r11,0		/* linear mapping ? */
-	beq	tlb_load_linear		/* yes -> go to linear map load */
-	cmpldi	cr1,r11,1		/* vmalloc mapping ? */
-
-	/* We do the user/kernel test for the PID here along with the RW test
-	 */
-	srdi.	r11,r16,60		/* Check for user region */
-	ld	r15,PACAPGD(r13)	/* Load user pgdir */
-	beq	htw_tlb_miss
-
-	/* XXX replace the RMW cycles with immediate loads + writes */
-1:	mfspr	r10,SPRN_MAS1
-	rlwinm	r10,r10,0,16,1		/* Clear TID */
-	mtspr	SPRN_MAS1,r10
-	ld	r15,PACA_KERNELPGD(r13)	/* Load kernel pgdir */
-	beq+	cr1,htw_tlb_miss
-
-	/* We got a crappy address, just fault with whatever DEAR and ESR
-	 * are here
-	 */
-	TLB_MISS_EPILOG_ERROR
-	b	exc_data_storage_book3e
-
-/* Instruction TLB miss */
-	START_EXCEPTION(instruction_tlb_miss_htw)
-	TLB_MISS_PROLOG
-
-	/* If we take a recursive fault, the second level handler may need
-	 * to know whether we are handling a data or instruction fault in
-	 * order to get to the right store fault handler. We provide that
-	 * info by keeping a crazy value for ESR in r14
-	 */
-	li	r14,-1	/* store to exception frame is done later */
-
-	/* Now we handle the fault proper. We only save DEAR in the non
-	 * linear mapping case since we know the linear mapping case will
-	 * not re-enter. We could indeed optimize and also not save SRR0/1
-	 * in the linear mapping case but I'll leave that for later
-	 *
-	 * Faulting address is SRR0 which is already in r16
-	 */
-	srdi	r11,r16,44		/* get region */
-	xoris	r11,r11,0xc
-	cmpldi	cr0,r11,0		/* linear mapping ? */
-	beq	tlb_load_linear		/* yes -> go to linear map load */
-	cmpldi	cr1,r11,1		/* vmalloc mapping ? */
-
-	/* We do the user/kernel test for the PID here along with the RW test
-	 */
-	srdi.	r11,r16,60		/* Check for user region */
-	ld	r15,PACAPGD(r13)		/* Load user pgdir */
-	beq	htw_tlb_miss
-
-	/* XXX replace the RMW cycles with immediate loads + writes */
-1:	mfspr	r10,SPRN_MAS1
-	rlwinm	r10,r10,0,16,1			/* Clear TID */
-	mtspr	SPRN_MAS1,r10
-	ld	r15,PACA_KERNELPGD(r13)		/* Load kernel pgdir */
-	beq+	htw_tlb_miss
-
-	/* We got a crappy address, just fault */
-	TLB_MISS_EPILOG_ERROR
-	b	exc_instruction_storage_book3e
-
-
-/*
- * This is the guts of the second-level TLB miss handler for direct
- * misses. We are entered with:
- *
- * r16 = virtual page table faulting address
- * r15 = PGD pointer
- * r14 = ESR
- * r13 = PACA
- * r12 = TLB exception frame in PACA
- * r11 = crap (free to use)
- * r10 = crap (free to use)
- *
- * It can be re-entered by the linear mapping miss handler. However, to
- * avoid too much complication, it will save/restore things for us
- */
-htw_tlb_miss:
-#ifdef CONFIG_PPC_KUAP
-	mfspr	r10,SPRN_MAS1
-	rlwinm.	r10,r10,0,0x3fff0000
-	beq-	htw_tlb_miss_fault /* KUAP fault */
-#endif
-	/* Search if we already have a TLB entry for that virtual address, and
-	 * if we do, bail out.
-	 *
-	 * MAS1:IND should be already set based on MAS4
-	 */
-	PPC_TLBSRX_DOT(0,R16)
-	beq	htw_tlb_miss_done
-
-	/* Now, we need to walk the page tables. First check if we are in
-	 * range.
-	 */
-	rldicl.	r10,r16,64-PGTABLE_EADDR_SIZE,PGTABLE_EADDR_SIZE+4
-	bne-	htw_tlb_miss_fault
-
-	/* Get the PGD pointer */
-	cmpldi	cr0,r15,0
-	beq-	htw_tlb_miss_fault
-
-	/* Get to PGD entry */
-	rldicl	r11,r16,64-(PGDIR_SHIFT-3),64-PGD_INDEX_SIZE-3
-	clrrdi	r10,r11,3
-	ldx	r15,r10,r15
-	cmpdi	cr0,r15,0
-	bge	htw_tlb_miss_fault
-
-	/* Get to PUD entry */
-	rldicl	r11,r16,64-(PUD_SHIFT-3),64-PUD_INDEX_SIZE-3
-	clrrdi	r10,r11,3
-	ldx	r15,r10,r15
-	cmpdi	cr0,r15,0
-	bge	htw_tlb_miss_fault
-
-	/* Get to PMD entry */
-	rldicl	r11,r16,64-(PMD_SHIFT-3),64-PMD_INDEX_SIZE-3
-	clrrdi	r10,r11,3
-	ldx	r15,r10,r15
-	cmpdi	cr0,r15,0
-	bge	htw_tlb_miss_fault
-
-	/* Ok, we're all right, we can now create an indirect entry for
-	 * a 1M or 256M page.
-	 *
-	 * The last trick is now that because we use "half" pages for
-	 * the HTW (1M IND is 2K and 256M IND is 32K) we need to account
-	 * for an added LSB bit to the RPN. For 64K pages, there is no
-	 * problem as we already use 32K arrays (half PTE pages), but for
-	 * 4K page we need to extract a bit from the virtual address and
-	 * insert it into the "PA52" bit of the RPN.
-	 */
-	rlwimi	r15,r16,32-9,20,20
-	/* Now we build the MAS:
-	 *
-	 * MAS 0   :	Fully setup with defaults in MAS4 and TLBnCFG
-	 * MAS 1   :	Almost fully setup
-	 *               - PID already updated by caller if necessary
-	 *               - TSIZE for now is base ind page size always
-	 * MAS 2   :	Use defaults
-	 * MAS 3+7 :	Needs to be done
-	 */
-	ori	r10,r15,(BOOK3E_PAGESZ_4K << MAS3_SPSIZE_SHIFT)
-
-	srdi	r16,r10,32
-	mtspr	SPRN_MAS3,r10
-	mtspr	SPRN_MAS7,r16
-
-	tlbwe
-
-htw_tlb_miss_done:
-	/* We don't bother with restoring DEAR or ESR since we know we are
-	 * level 0 and just going back to userland. They are only needed
-	 * if you are going to take an access fault
-	 */
-	TLB_MISS_EPILOG_SUCCESS
-	rfi
-
-htw_tlb_miss_fault:
-	/* We need to check if it was an instruction miss. We know this
-	 * though because r14 would contain -1
-	 */
-	cmpdi	cr0,r14,-1
-	beq	1f
-	mtspr	SPRN_DEAR,r16
-	mtspr	SPRN_ESR,r14
-	TLB_MISS_EPILOG_ERROR
-	b	exc_data_storage_book3e
-1:	TLB_MISS_EPILOG_ERROR
-	b	exc_instruction_storage_book3e
-
 /*
  * This is the guts of "any" level TLB miss handler for kernel linear
  * mapping misses. We are entered with:
--- linux-qcom-6.8.0.orig/arch/powerpc/net/bpf_jit_comp32.c
+++ linux-qcom-6.8.0/arch/powerpc/net/bpf_jit_comp32.c
@@ -450,10 +450,16 @@
 			}
 			break;
 		case BPF_ALU | BPF_DIV | BPF_X: /* (u32) dst /= (u32) src */
-			EMIT(PPC_RAW_DIVWU(dst_reg, src2_reg, src_reg));
+			if (off)
+				EMIT(PPC_RAW_DIVW(dst_reg, src2_reg, src_reg));
+			else
+				EMIT(PPC_RAW_DIVWU(dst_reg, src2_reg, src_reg));
 			break;
 		case BPF_ALU | BPF_MOD | BPF_X: /* (u32) dst %= (u32) src */
-			EMIT(PPC_RAW_DIVWU(_R0, src2_reg, src_reg));
+			if (off)
+				EMIT(PPC_RAW_DIVW(_R0, src2_reg, src_reg));
+			else
+				EMIT(PPC_RAW_DIVWU(_R0, src2_reg, src_reg));
 			EMIT(PPC_RAW_MULW(_R0, src_reg, _R0));
 			EMIT(PPC_RAW_SUB(dst_reg, src2_reg, _R0));
 			break;
@@ -467,10 +473,16 @@
 			if (imm == 1) {
 				EMIT(PPC_RAW_MR(dst_reg, src2_reg));
 			} else if (is_power_of_2((u32)imm)) {
-				EMIT(PPC_RAW_SRWI(dst_reg, src2_reg, ilog2(imm)));
+				if (off)
+					EMIT(PPC_RAW_SRAWI(dst_reg, src2_reg, ilog2(imm)));
+				else
+					EMIT(PPC_RAW_SRWI(dst_reg, src2_reg, ilog2(imm)));
 			} else {
 				PPC_LI32(_R0, imm);
-				EMIT(PPC_RAW_DIVWU(dst_reg, src2_reg, _R0));
+				if (off)
+					EMIT(PPC_RAW_DIVW(dst_reg, src2_reg, _R0));
+				else
+					EMIT(PPC_RAW_DIVWU(dst_reg, src2_reg, _R0));
 			}
 			break;
 		case BPF_ALU | BPF_MOD | BPF_K: /* (u32) dst %= (u32) imm */
@@ -480,11 +492,19 @@
 			if (!is_power_of_2((u32)imm)) {
 				bpf_set_seen_register(ctx, tmp_reg);
 				PPC_LI32(tmp_reg, imm);
-				EMIT(PPC_RAW_DIVWU(_R0, src2_reg, tmp_reg));
+				if (off)
+					EMIT(PPC_RAW_DIVW(_R0, src2_reg, tmp_reg));
+				else
+					EMIT(PPC_RAW_DIVWU(_R0, src2_reg, tmp_reg));
 				EMIT(PPC_RAW_MULW(_R0, tmp_reg, _R0));
 				EMIT(PPC_RAW_SUB(dst_reg, src2_reg, _R0));
 			} else if (imm == 1) {
 				EMIT(PPC_RAW_LI(dst_reg, 0));
+			} else if (off) {
+				EMIT(PPC_RAW_SRAWI(_R0, src2_reg, ilog2(imm)));
+				EMIT(PPC_RAW_ADDZE(_R0, _R0));
+				EMIT(PPC_RAW_SLWI(_R0, _R0, ilog2(imm)));
+				EMIT(PPC_RAW_SUB(dst_reg, src2_reg, _R0));
 			} else {
 				imm = ilog2((u32)imm);
 				EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg, 0, 32 - imm, 31));
@@ -497,11 +517,21 @@
 				imm = -imm;
 			if (!is_power_of_2(imm))
 				return -EOPNOTSUPP;
-			if (imm == 1)
+			if (imm == 1) {
 				EMIT(PPC_RAW_LI(dst_reg, 0));
-			else
+				EMIT(PPC_RAW_LI(dst_reg_h, 0));
+			} else if (off) {
+				EMIT(PPC_RAW_SRAWI(dst_reg_h, src2_reg_h, 31));
+				EMIT(PPC_RAW_XOR(dst_reg, src2_reg, dst_reg_h));
+				EMIT(PPC_RAW_SUBFC(dst_reg, dst_reg_h, dst_reg));
+				EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 0, 32 - ilog2(imm), 31));
+				EMIT(PPC_RAW_XOR(dst_reg, dst_reg, dst_reg_h));
+				EMIT(PPC_RAW_SUBFC(dst_reg, dst_reg_h, dst_reg));
+				EMIT(PPC_RAW_SUBFE(dst_reg_h, dst_reg_h, dst_reg_h));
+			} else {
 				EMIT(PPC_RAW_RLWINM(dst_reg, src2_reg, 0, 32 - ilog2(imm), 31));
-			EMIT(PPC_RAW_LI(dst_reg_h, 0));
+				EMIT(PPC_RAW_LI(dst_reg_h, 0));
+			}
 			break;
 		case BPF_ALU64 | BPF_DIV | BPF_K: /* dst /= imm */
 			if (!imm)
@@ -727,15 +757,30 @@
 		 * MOV
 		 */
 		case BPF_ALU64 | BPF_MOV | BPF_X: /* dst = src */
-			if (dst_reg == src_reg)
-				break;
-			EMIT(PPC_RAW_MR(dst_reg, src_reg));
-			EMIT(PPC_RAW_MR(dst_reg_h, src_reg_h));
+			if (off == 8) {
+				EMIT(PPC_RAW_EXTSB(dst_reg, src_reg));
+				EMIT(PPC_RAW_SRAWI(dst_reg_h, dst_reg, 31));
+			} else if (off == 16) {
+				EMIT(PPC_RAW_EXTSH(dst_reg, src_reg));
+				EMIT(PPC_RAW_SRAWI(dst_reg_h, dst_reg, 31));
+			} else if (off == 32 && dst_reg == src_reg) {
+				EMIT(PPC_RAW_SRAWI(dst_reg_h, src_reg, 31));
+			} else if (off == 32) {
+				EMIT(PPC_RAW_MR(dst_reg, src_reg));
+				EMIT(PPC_RAW_SRAWI(dst_reg_h, src_reg, 31));
+			} else if (dst_reg != src_reg) {
+				EMIT(PPC_RAW_MR(dst_reg, src_reg));
+				EMIT(PPC_RAW_MR(dst_reg_h, src_reg_h));
+			}
 			break;
 		case BPF_ALU | BPF_MOV | BPF_X: /* (u32) dst = src */
 			/* special mov32 for zext */
 			if (imm == 1)
 				EMIT(PPC_RAW_LI(dst_reg_h, 0));
+			else if (off == 8)
+				EMIT(PPC_RAW_EXTSB(dst_reg, src_reg));
+			else if (off == 16)
+				EMIT(PPC_RAW_EXTSH(dst_reg, src_reg));
 			else if (dst_reg != src_reg)
 				EMIT(PPC_RAW_MR(dst_reg, src_reg));
 			break;
@@ -751,6 +796,7 @@
 		 * BPF_FROM_BE/LE
 		 */
 		case BPF_ALU | BPF_END | BPF_FROM_LE:
+		case BPF_ALU64 | BPF_END | BPF_FROM_LE:
 			switch (imm) {
 			case 16:
 				/* Copy 16 bits to upper part */
@@ -785,6 +831,8 @@
 				EMIT(PPC_RAW_MR(dst_reg_h, tmp_reg));
 				break;
 			}
+			if (BPF_CLASS(code) == BPF_ALU64 && imm != 64)
+				EMIT(PPC_RAW_LI(dst_reg_h, 0));
 			break;
 		case BPF_ALU | BPF_END | BPF_FROM_BE:
 			switch (imm) {
@@ -852,6 +900,15 @@
 
 			/* Get offset into TMP_REG */
 			EMIT(PPC_RAW_LI(tmp_reg, off));
+			/*
+			 * Enforce full ordering for operations with BPF_FETCH by emitting a 'sync'
+			 * before and after the operation.
+			 *
+			 * This is a requirement in the Linux Kernel Memory Model.
+			 * See __cmpxchg_u32() in asm/cmpxchg.h as an example.
+			 */
+			if ((imm & BPF_FETCH) && IS_ENABLED(CONFIG_SMP))
+				EMIT(PPC_RAW_SYNC());
 			tmp_idx = ctx->idx * 4;
 			/* load value from memory into r0 */
 			EMIT(PPC_RAW_LWARX(_R0, tmp_reg, dst_reg, 0));
@@ -905,6 +962,9 @@
 
 			/* For the BPF_FETCH variant, get old data into src_reg */
 			if (imm & BPF_FETCH) {
+				/* Emit 'sync' to enforce full ordering */
+				if (IS_ENABLED(CONFIG_SMP))
+					EMIT(PPC_RAW_SYNC());
 				EMIT(PPC_RAW_MR(ret_reg, ax_reg));
 				if (!fp->aux->verifier_zext)
 					EMIT(PPC_RAW_LI(ret_reg - 1, 0)); /* higher 32-bit */
@@ -918,11 +978,17 @@
 		 * BPF_LDX
 		 */
 		case BPF_LDX | BPF_MEM | BPF_B: /* dst = *(u8 *)(ul) (src + off) */
+		case BPF_LDX | BPF_MEMSX | BPF_B:
 		case BPF_LDX | BPF_PROBE_MEM | BPF_B:
+		case BPF_LDX | BPF_PROBE_MEMSX | BPF_B:
 		case BPF_LDX | BPF_MEM | BPF_H: /* dst = *(u16 *)(ul) (src + off) */
+		case BPF_LDX | BPF_MEMSX | BPF_H:
 		case BPF_LDX | BPF_PROBE_MEM | BPF_H:
+		case BPF_LDX | BPF_PROBE_MEMSX | BPF_H:
 		case BPF_LDX | BPF_MEM | BPF_W: /* dst = *(u32 *)(ul) (src + off) */
+		case BPF_LDX | BPF_MEMSX | BPF_W:
 		case BPF_LDX | BPF_PROBE_MEM | BPF_W:
+		case BPF_LDX | BPF_PROBE_MEMSX | BPF_W:
 		case BPF_LDX | BPF_MEM | BPF_DW: /* dst = *(u64 *)(ul) (src + off) */
 		case BPF_LDX | BPF_PROBE_MEM | BPF_DW:
 			/*
@@ -931,7 +997,7 @@
 			 * load only if addr is kernel address (see is_kernel_addr()), otherwise
 			 * set dst_reg=0 and move on.
 			 */
-			if (BPF_MODE(code) == BPF_PROBE_MEM) {
+			if (BPF_MODE(code) == BPF_PROBE_MEM || BPF_MODE(code) == BPF_PROBE_MEMSX) {
 				PPC_LI32(_R0, TASK_SIZE - off);
 				EMIT(PPC_RAW_CMPLW(src_reg, _R0));
 				PPC_BCC_SHORT(COND_GT, (ctx->idx + 4) * 4);
@@ -953,30 +1019,48 @@
 				 * as there are two load instructions for dst_reg_h & dst_reg
 				 * respectively.
 				 */
-				if (size == BPF_DW)
+				if (size == BPF_DW ||
+				    (size == BPF_B && BPF_MODE(code) == BPF_PROBE_MEMSX))
 					PPC_JMP((ctx->idx + 3) * 4);
 				else
 					PPC_JMP((ctx->idx + 2) * 4);
 			}
 
-			switch (size) {
-			case BPF_B:
-				EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
-				break;
-			case BPF_H:
-				EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
-				break;
-			case BPF_W:
-				EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
-				break;
-			case BPF_DW:
-				EMIT(PPC_RAW_LWZ(dst_reg_h, src_reg, off));
-				EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off + 4));
-				break;
-			}
+			if (BPF_MODE(code) == BPF_MEMSX || BPF_MODE(code) == BPF_PROBE_MEMSX) {
+				switch (size) {
+				case BPF_B:
+					EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
+					EMIT(PPC_RAW_EXTSB(dst_reg, dst_reg));
+					break;
+				case BPF_H:
+					EMIT(PPC_RAW_LHA(dst_reg, src_reg, off));
+					break;
+				case BPF_W:
+					EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
+					break;
+				}
+				if (!fp->aux->verifier_zext)
+					EMIT(PPC_RAW_SRAWI(dst_reg_h, dst_reg, 31));
 
-			if (size != BPF_DW && !fp->aux->verifier_zext)
-				EMIT(PPC_RAW_LI(dst_reg_h, 0));
+			} else {
+				switch (size) {
+				case BPF_B:
+					EMIT(PPC_RAW_LBZ(dst_reg, src_reg, off));
+					break;
+				case BPF_H:
+					EMIT(PPC_RAW_LHZ(dst_reg, src_reg, off));
+					break;
+				case BPF_W:
+					EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off));
+					break;
+				case BPF_DW:
+					EMIT(PPC_RAW_LWZ(dst_reg_h, src_reg, off));
+					EMIT(PPC_RAW_LWZ(dst_reg, src_reg, off + 4));
+					break;
+				}
+				if (size != BPF_DW && !fp->aux->verifier_zext)
+					EMIT(PPC_RAW_LI(dst_reg_h, 0));
+			}
 
 			if (BPF_MODE(code) == BPF_PROBE_MEM) {
 				int insn_idx = ctx->idx - 1;
@@ -1068,6 +1152,9 @@
 		case BPF_JMP | BPF_JA:
 			PPC_JMP(addrs[i + 1 + off]);
 			break;
+		case BPF_JMP32 | BPF_JA:
+			PPC_JMP(addrs[i + 1 + imm]);
+			break;
 
 		case BPF_JMP | BPF_JGT | BPF_K:
 		case BPF_JMP | BPF_JGT | BPF_X:
--- linux-qcom-6.8.0.orig/arch/powerpc/net/bpf_jit_comp64.c
+++ linux-qcom-6.8.0/arch/powerpc/net/bpf_jit_comp64.c
@@ -202,7 +202,8 @@
 	EMIT(PPC_RAW_BLR());
 }
 
-static int bpf_jit_emit_func_call_hlp(u32 *image, struct codegen_context *ctx, u64 func)
+static int
+bpf_jit_emit_func_call_hlp(u32 *image, u32 *fimage, struct codegen_context *ctx, u64 func)
 {
 	unsigned long func_addr = func ? ppc_function_entry((void *)func) : 0;
 	long reladdr;
@@ -211,19 +212,20 @@
 		return -EINVAL;
 
 	if (IS_ENABLED(CONFIG_PPC_KERNEL_PCREL)) {
-		reladdr = func_addr - CTX_NIA(ctx);
+		reladdr = func_addr - local_paca->kernelbase;
 
 		if (reladdr >= (long)SZ_8G || reladdr < -(long)SZ_8G) {
-			pr_err("eBPF: address of %ps out of range of pcrel address.\n",
-				(void *)func);
+			pr_err("eBPF: address of %ps out of range of 34-bit relative address.\n",
+			       (void *)func);
 			return -ERANGE;
 		}
-		/* pla r12,addr */
-		EMIT(PPC_PREFIX_MLS | __PPC_PRFX_R(1) | IMM_H18(reladdr));
-		EMIT(PPC_INST_PADDI | ___PPC_RT(_R12) | IMM_L(reladdr));
-		EMIT(PPC_RAW_MTCTR(_R12));
-		EMIT(PPC_RAW_BCTR());
-
+		EMIT(PPC_RAW_LD(_R12, _R13, offsetof(struct paca_struct, kernelbase)));
+		/* Align for subsequent prefix instruction */
+		if (!IS_ALIGNED((unsigned long)fimage + CTX_NIA(ctx), 8))
+			EMIT(PPC_RAW_NOP());
+		/* paddi r12,r12,addr */
+		EMIT(PPC_PREFIX_MLS | __PPC_PRFX_R(0) | IMM_H18(reladdr));
+		EMIT(PPC_INST_PADDI | ___PPC_RT(_R12) | ___PPC_RA(_R12) | IMM_L(reladdr));
 	} else {
 		reladdr = func_addr - kernel_toc_addr();
 		if (reladdr > 0x7FFFFFFF || reladdr < -(0x80000000L)) {
@@ -233,9 +235,9 @@
 
 		EMIT(PPC_RAW_ADDIS(_R12, _R2, PPC_HA(reladdr)));
 		EMIT(PPC_RAW_ADDI(_R12, _R12, PPC_LO(reladdr)));
-		EMIT(PPC_RAW_MTCTR(_R12));
-		EMIT(PPC_RAW_BCTRL());
 	}
+	EMIT(PPC_RAW_MTCTR(_R12));
+	EMIT(PPC_RAW_BCTRL());
 
 	return 0;
 }
@@ -285,7 +287,7 @@
 	int b2p_index = bpf_to_ppc(BPF_REG_3);
 	int bpf_tailcall_prologue_size = 8;
 
-	if (IS_ENABLED(CONFIG_PPC64_ELF_ABI_V2))
+	if (!IS_ENABLED(CONFIG_PPC_KERNEL_PCREL) && IS_ENABLED(CONFIG_PPC64_ELF_ABI_V2))
 		bpf_tailcall_prologue_size += 4; /* skip past the toc load */
 
 	/*
@@ -803,6 +805,15 @@
 
 			/* Get offset into TMP_REG_1 */
 			EMIT(PPC_RAW_LI(tmp1_reg, off));
+			/*
+			 * Enforce full ordering for operations with BPF_FETCH by emitting a 'sync'
+			 * before and after the operation.
+			 *
+			 * This is a requirement in the Linux Kernel Memory Model.
+			 * See __cmpxchg_u64() in asm/cmpxchg.h as an example.
+			 */
+			if ((imm & BPF_FETCH) && IS_ENABLED(CONFIG_SMP))
+				EMIT(PPC_RAW_SYNC());
 			tmp_idx = ctx->idx * 4;
 			/* load value from memory into TMP_REG_2 */
 			if (size == BPF_DW)
@@ -865,6 +876,9 @@
 			PPC_BCC_SHORT(COND_NE, tmp_idx);
 
 			if (imm & BPF_FETCH) {
+				/* Emit 'sync' to enforce full ordering */
+				if (IS_ENABLED(CONFIG_SMP))
+					EMIT(PPC_RAW_SYNC());
 				EMIT(PPC_RAW_MR(ret_reg, _R0));
 				/*
 				 * Skip unnecessary zero-extension for 32-bit cmpxchg.
@@ -993,7 +1007,7 @@
 				return ret;
 
 			if (func_addr_fixed)
-				ret = bpf_jit_emit_func_call_hlp(image, ctx, func_addr);
+				ret = bpf_jit_emit_func_call_hlp(image, fimage, ctx, func_addr);
 			else
 				ret = bpf_jit_emit_func_call_rel(image, fimage, ctx, func_addr);
 
--- linux-qcom-6.8.0.orig/arch/powerpc/perf/hv-gpci.c
+++ linux-qcom-6.8.0/arch/powerpc/perf/hv-gpci.c
@@ -695,6 +695,20 @@
 
 	ret = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
 			virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE);
+
+	/*
+	 * ret value as 'H_PARAMETER' with detail_rc as 'GEN_BUF_TOO_SMALL',
+	 * specifies that the current buffer size cannot accommodate
+	 * all the information and a partial buffer returned.
+	 * Since in this function we are only accessing data for a given starting index,
+	 * we don't need to accommodate whole data and can get required count by
+	 * accessing first entry data.
+	 * Hence hcall fails only incase the ret value is other than H_SUCCESS or
+	 * H_PARAMETER with detail_rc value as GEN_BUF_TOO_SMALL(0x1B).
+	 */
+	if (ret == H_PARAMETER && be32_to_cpu(arg->params.detail_rc) == 0x1B)
+		ret = 0;
+
 	if (ret) {
 		pr_devel("hcall failed: 0x%lx\n", ret);
 		goto out;
@@ -759,6 +773,7 @@
 {
 	u64 count;
 	u8 length;
+	unsigned long ret;
 
 	/* Not our event */
 	if (event->attr.type != event->pmu->type)
@@ -789,13 +804,23 @@
 	}
 
 	/* check if the request works... */
-	if (single_gpci_request(event_get_request(event),
+	ret = single_gpci_request(event_get_request(event),
 				event_get_starting_index(event),
 				event_get_secondary_index(event),
 				event_get_counter_info_version(event),
 				event_get_offset(event),
 				length,
-				&count)) {
+				&count);
+
+	/*
+	 * ret value as H_AUTHORITY implies that partition is not permitted to retrieve
+	 * performance information, and required to set
+	 * "Enable Performance Information Collection" option.
+	 */
+	if (ret == H_AUTHORITY)
+		return -EPERM;
+
+	if (ret) {
 		pr_devel("gpci hcall failed\n");
 		return -EINVAL;
 	}
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/44x/warp.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/44x/warp.c
@@ -8,6 +8,7 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/of_platform.h>
+#include <linux/platform_device.h>
 #include <linux/kthread.h>
 #include <linux/leds.h>
 #include <linux/i2c.h>
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/85xx/smp.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/85xx/smp.c
@@ -398,6 +398,7 @@
 	hard_irq_disable();
 	mpic_teardown_this_cpu(secondary);
 
+#ifdef CONFIG_CRASH_DUMP
 	if (cpu == crashing_cpu && cpu_thread_in_core(cpu) != 0) {
 		/*
 		 * We enter the crash kernel on whatever cpu crashed,
@@ -406,9 +407,11 @@
 		 */
 		disable_threadbit = 1;
 		disable_cpu = cpu_first_thread_sibling(cpu);
-	} else if (sibling != crashing_cpu &&
-		   cpu_thread_in_core(cpu) == 0 &&
-		   cpu_thread_in_core(sibling) != 0) {
+	} else if (sibling == crashing_cpu) {
+		return;
+	}
+#endif
+	if (cpu_thread_in_core(cpu) == 0 && cpu_thread_in_core(sibling) != 0) {
 		disable_threadbit = 2;
 		disable_cpu = sibling;
 	}
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/book3s/vas-api.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/book3s/vas-api.c
@@ -464,7 +464,43 @@
 	return VM_FAULT_SIGBUS;
 }
 
+/*
+ * During mmap() paste address, mapping VMA is saved in VAS window
+ * struct which is used to unmap during migration if the window is
+ * still open. But the user space can remove this mapping with
+ * munmap() before closing the window and the VMA address will
+ * be invalid. Set VAS window VMA to NULL in this function which
+ * is called before VMA free.
+ */
+static void vas_mmap_close(struct vm_area_struct *vma)
+{
+	struct file *fp = vma->vm_file;
+	struct coproc_instance *cp_inst = fp->private_data;
+	struct vas_window *txwin;
+
+	/* Should not happen */
+	if (!cp_inst || !cp_inst->txwin) {
+		pr_err("No attached VAS window for the paste address mmap\n");
+		return;
+	}
+
+	txwin = cp_inst->txwin;
+	/*
+	 * task_ref.vma is set in coproc_mmap() during mmap paste
+	 * address. So it has to be the same VMA that is getting freed.
+	 */
+	if (WARN_ON(txwin->task_ref.vma != vma)) {
+		pr_err("Invalid paste address mmaping\n");
+		return;
+	}
+
+	mutex_lock(&txwin->task_ref.mmap_mutex);
+	txwin->task_ref.vma = NULL;
+	mutex_unlock(&txwin->task_ref.mmap_mutex);
+}
+
 static const struct vm_operations_struct vas_vm_ops = {
+	.close = vas_mmap_close,
 	.fault = vas_mmap_fault,
 };
 
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/embedded6xx/linkstation.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/embedded6xx/linkstation.c
@@ -99,9 +99,6 @@
 	mpic_init(mpic);
 }
 
-extern void avr_uart_configure(void);
-extern void avr_uart_send(const char);
-
 static void __noreturn linkstation_restart(char *cmd)
 {
 	local_irq_disable();
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/embedded6xx/mpc10x.h
+++ linux-qcom-6.8.0/arch/powerpc/platforms/embedded6xx/mpc10x.h
@@ -156,4 +156,7 @@
 /* For MPC107 boards that use the built-in openpic */
 void mpc10x_set_openpic(void);
 
+void avr_uart_configure(void);
+void avr_uart_send(const char c);
+
 #endif	/* __PPC_KERNEL_MPC10X_H */
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/powermac/Kconfig
+++ linux-qcom-6.8.0/arch/powerpc/platforms/powermac/Kconfig
@@ -2,7 +2,7 @@
 config PPC_PMAC
 	bool "Apple PowerMac based machines"
 	depends on PPC_BOOK3S && CPU_BIG_ENDIAN
-	select ADB_CUDA if POWER_RESET && PPC32
+	select ADB_CUDA if POWER_RESET && ADB
 	select MPIC
 	select FORCE_PCI
 	select PPC_INDIRECT_PCI if PPC32
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/powernv/opal-irqchip.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/powernv/opal-irqchip.c
@@ -282,6 +282,7 @@
 				 name, NULL);
 		if (rc) {
 			pr_warn("Error %d requesting OPAL irq %d\n", rc, (int)r->start);
+			kfree(name);
 			continue;
 		}
 	}
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/ps3/Kconfig
+++ linux-qcom-6.8.0/arch/powerpc/platforms/ps3/Kconfig
@@ -67,6 +67,7 @@
 config PS3_PS3AV
 	depends on PPC_PS3
 	tristate "PS3 AV settings driver" if PS3_ADVANCED
+	select VIDEO
 	select PS3_VUART
 	default y
 	help
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/dlpar.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/dlpar.c
@@ -334,23 +334,6 @@
 {
 	int rc;
 
-	/* pseries error logs are in BE format, convert to cpu type */
-	switch (hp_elog->id_type) {
-	case PSERIES_HP_ELOG_ID_DRC_COUNT:
-		hp_elog->_drc_u.drc_count =
-				be32_to_cpu(hp_elog->_drc_u.drc_count);
-		break;
-	case PSERIES_HP_ELOG_ID_DRC_INDEX:
-		hp_elog->_drc_u.drc_index =
-				be32_to_cpu(hp_elog->_drc_u.drc_index);
-		break;
-	case PSERIES_HP_ELOG_ID_DRC_IC:
-		hp_elog->_drc_u.ic.count =
-				be32_to_cpu(hp_elog->_drc_u.ic.count);
-		hp_elog->_drc_u.ic.index =
-				be32_to_cpu(hp_elog->_drc_u.ic.index);
-	}
-
 	switch (hp_elog->resource) {
 	case PSERIES_HP_ELOG_RESOURCE_MEM:
 		rc = dlpar_memory(hp_elog);
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/dtl.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/dtl.c
@@ -191,7 +191,7 @@
 		return -EBUSY;
 
 	/* ensure there are no other conflicting dtl users */
-	if (!read_trylock(&dtl_access_lock))
+	if (!down_read_trylock(&dtl_access_lock))
 		return -EBUSY;
 
 	n_entries = dtl_buf_entries;
@@ -199,7 +199,7 @@
 	if (!buf) {
 		printk(KERN_WARNING "%s: buffer alloc failed for cpu %d\n",
 				__func__, dtl->cpu);
-		read_unlock(&dtl_access_lock);
+		up_read(&dtl_access_lock);
 		return -ENOMEM;
 	}
 
@@ -217,7 +217,7 @@
 	spin_unlock(&dtl->lock);
 
 	if (rc) {
-		read_unlock(&dtl_access_lock);
+		up_read(&dtl_access_lock);
 		kmem_cache_free(dtl_cache, buf);
 	}
 
@@ -232,7 +232,7 @@
 	dtl->buf = NULL;
 	dtl->buf_entries = 0;
 	spin_unlock(&dtl->lock);
-	read_unlock(&dtl_access_lock);
+	up_read(&dtl_access_lock);
 }
 
 /* file interface */
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -580,8 +580,10 @@
 
 	switch(rets[0]) {
 	case 0:
-		result = EEH_STATE_MMIO_ACTIVE |
-			 EEH_STATE_DMA_ACTIVE;
+		result = EEH_STATE_MMIO_ACTIVE	|
+			 EEH_STATE_DMA_ACTIVE	|
+			 EEH_STATE_MMIO_ENABLED	|
+			 EEH_STATE_DMA_ENABLED;
 		break;
 	case 1:
 		result = EEH_STATE_RESET_ACTIVE |
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -757,7 +757,7 @@
 	u32 drc_index;
 	int rc;
 
-	drc_index = hp_elog->_drc_u.drc_index;
+	drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
 
 	lock_device_hotplug();
 
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -817,16 +817,16 @@
 	case PSERIES_HP_ELOG_ACTION_ADD:
 		switch (hp_elog->id_type) {
 		case PSERIES_HP_ELOG_ID_DRC_COUNT:
-			count = hp_elog->_drc_u.drc_count;
+			count = be32_to_cpu(hp_elog->_drc_u.drc_count);
 			rc = dlpar_memory_add_by_count(count);
 			break;
 		case PSERIES_HP_ELOG_ID_DRC_INDEX:
-			drc_index = hp_elog->_drc_u.drc_index;
+			drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
 			rc = dlpar_memory_add_by_index(drc_index);
 			break;
 		case PSERIES_HP_ELOG_ID_DRC_IC:
-			count = hp_elog->_drc_u.ic.count;
-			drc_index = hp_elog->_drc_u.ic.index;
+			count = be32_to_cpu(hp_elog->_drc_u.ic.count);
+			drc_index = be32_to_cpu(hp_elog->_drc_u.ic.index);
 			rc = dlpar_memory_add_by_ic(count, drc_index);
 			break;
 		default:
@@ -838,16 +838,16 @@
 	case PSERIES_HP_ELOG_ACTION_REMOVE:
 		switch (hp_elog->id_type) {
 		case PSERIES_HP_ELOG_ID_DRC_COUNT:
-			count = hp_elog->_drc_u.drc_count;
+			count = be32_to_cpu(hp_elog->_drc_u.drc_count);
 			rc = dlpar_memory_remove_by_count(count);
 			break;
 		case PSERIES_HP_ELOG_ID_DRC_INDEX:
-			drc_index = hp_elog->_drc_u.drc_index;
+			drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
 			rc = dlpar_memory_remove_by_index(drc_index);
 			break;
 		case PSERIES_HP_ELOG_ID_DRC_IC:
-			count = hp_elog->_drc_u.ic.count;
-			drc_index = hp_elog->_drc_u.ic.index;
+			count = be32_to_cpu(hp_elog->_drc_u.ic.count);
+			drc_index = be32_to_cpu(hp_elog->_drc_u.ic.index);
 			rc = dlpar_memory_remove_by_ic(count, drc_index);
 			break;
 		default:
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/iommu.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/iommu.c
@@ -786,8 +786,16 @@
 	 * parent bus. During reboot, there will be ibm,dma-window property to
 	 * define DMA window. For kdump, there will at least be default window or DDW
 	 * or both.
+	 * There is an exception to the above. In case the PE goes into frozen
+	 * state, firmware may not provide ibm,dma-window property at the time
+	 * of LPAR boot up.
 	 */
 
+	if (!pdn) {
+		pr_debug("  no ibm,dma-window property !\n");
+		return;
+	}
+
 	ppci = PCI_DN(pdn);
 
 	pr_debug("  parent is %pOF, iommu_table: 0x%p\n",
@@ -1500,7 +1508,8 @@
 
 		iommu_table_setparms_common(newtbl, pci->phb->bus->number, create.liobn, win_addr,
 					    1UL << len, page_shift, NULL, &iommu_table_lpar_multi_ops);
-		iommu_init_table(newtbl, pci->phb->node, start, end);
+		iommu_init_table(newtbl, pci->phb->node,
+				 start >> page_shift, end >> page_shift);
 
 		pci->table_group->tables[1] = newtbl;
 
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/kexec.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/kexec.c
@@ -61,11 +61,3 @@
 	} else
 		xics_kexec_teardown_cpu(secondary);
 }
-
-void pseries_machine_kexec(struct kimage *image)
-{
-	if (firmware_has_feature(FW_FEATURE_SET_MODE))
-		pseries_disable_reloc_on_exc();
-
-	default_machine_kexec(image);
-}
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/lpar.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/lpar.c
@@ -169,7 +169,7 @@
  */
 #define NR_CPUS_H	NR_CPUS
 
-DEFINE_RWLOCK(dtl_access_lock);
+DECLARE_RWSEM(dtl_access_lock);
 static DEFINE_PER_CPU(struct vcpu_dispatch_data, vcpu_disp_data);
 static DEFINE_PER_CPU(u64, dtl_entry_ridx);
 static DEFINE_PER_CPU(struct dtl_worker, dtl_workers);
@@ -463,7 +463,7 @@
 {
 	int rc = 0, state;
 
-	if (!write_trylock(&dtl_access_lock)) {
+	if (!down_write_trylock(&dtl_access_lock)) {
 		rc = -EBUSY;
 		goto out;
 	}
@@ -479,7 +479,7 @@
 		pr_err("vcpudispatch_stats: unable to setup workqueue for DTL processing\n");
 		free_dtl_buffers(time_limit);
 		reset_global_dtl_mask();
-		write_unlock(&dtl_access_lock);
+		up_write(&dtl_access_lock);
 		rc = -EINVAL;
 		goto out;
 	}
@@ -494,7 +494,7 @@
 	cpuhp_remove_state(dtl_worker_state);
 	free_dtl_buffers(time_limit);
 	reset_global_dtl_mask();
-	write_unlock(&dtl_access_lock);
+	up_write(&dtl_access_lock);
 }
 
 static ssize_t vcpudispatch_stats_write(struct file *file, const char __user *p,
@@ -1886,10 +1886,10 @@
  * h_get_mpp
  * H_GET_MPP hcall returns info in 7 parms
  */
-int h_get_mpp(struct hvcall_mpp_data *mpp_data)
+long h_get_mpp(struct hvcall_mpp_data *mpp_data)
 {
-	int rc;
-	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
+	long rc;
 
 	rc = plpar_hcall9(H_GET_MPP, retbuf);
 
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/lparcfg.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/lparcfg.c
@@ -113,8 +113,8 @@
  */
 static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data)
 {
-	unsigned long rc;
-	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = {0};
+	long rc;
 
 	rc = plpar_hcall9(H_GET_PPP, retbuf);
 
@@ -193,7 +193,7 @@
 	struct hvcall_ppp_data ppp_data;
 	struct device_node *root;
 	const __be32 *perf_level;
-	int rc;
+	long rc;
 
 	rc = h_get_ppp(&ppp_data);
 	if (rc)
@@ -357,8 +357,8 @@
 
 static void read_lpar_name(struct seq_file *m)
 {
-	if (read_rtas_lpar_name(m) && read_dt_lpar_name(m))
-		pr_err_once("Error can't get the LPAR name");
+	if (read_rtas_lpar_name(m))
+		read_dt_lpar_name(m);
 }
 
 #define SPLPAR_MAXLENGTH 1026*(sizeof(char))
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/papr_platform_attributes.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/papr_platform_attributes.c
@@ -101,10 +101,12 @@
 		esi_buf_size = ESI_HDR_SIZE + (CURR_MAX_ESI_ATTRS * max_esi_attrs);
 
 		temp_buf = krealloc(buf, esi_buf_size, GFP_KERNEL);
-		if (temp_buf)
+		if (temp_buf) {
 			buf = temp_buf;
-		else
-			return -ENOMEM;
+		} else {
+			ret = -ENOMEM;
+			goto out_buf;
+		}
 
 		goto retry;
 	}
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/plpks.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/plpks.c
@@ -415,8 +415,7 @@
 			break;
 		}
 
-		usleep_range(PLPKS_FLUSH_SLEEP,
-			     PLPKS_FLUSH_SLEEP + PLPKS_FLUSH_SLEEP_RANGE);
+		fsleep(PLPKS_FLUSH_SLEEP);
 		timeout = timeout + PLPKS_FLUSH_SLEEP;
 	} while (timeout < PLPKS_MAX_TIMEOUT);
 
@@ -464,9 +463,10 @@
 
 		continuetoken = retbuf[0];
 		if (pseries_status_to_err(rc) == -EBUSY) {
-			int delay_ms = get_longbusy_msecs(rc);
-			mdelay(delay_ms);
-			timeout += delay_ms;
+			int delay_us = get_longbusy_msecs(rc) * 1000;
+
+			fsleep(delay_us);
+			timeout += delay_us;
 		}
 		rc = pseries_status_to_err(rc);
 	} while (rc == -EBUSY && timeout < PLPKS_MAX_TIMEOUT);
@@ -683,7 +683,7 @@
 out:
 	fdt_nop_property(fdt, chosen_node, "ibm,plpks-pw");
 	// Since we've cleared the password, we must update the FDT checksum
-	early_init_dt_verify(fdt);
+	early_init_dt_verify(fdt, __pa(fdt));
 }
 
 static __init int pseries_plpks_init(void)
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/pmem.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/pmem.c
@@ -121,7 +121,7 @@
 		return -EINVAL;
 	}
 
-	drc_index = hp_elog->_drc_u.drc_index;
+	drc_index = be32_to_cpu(hp_elog->_drc_u.drc_index);
 
 	lock_device_hotplug();
 
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/pseries.h
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/pseries.h
@@ -38,7 +38,6 @@
 #endif
 
 extern void pseries_kexec_cpu_down(int crash_shutdown, int secondary);
-void pseries_machine_kexec(struct kimage *image);
 
 extern void pSeries_final_fixup(void);
 
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/setup.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/setup.c
@@ -343,8 +343,8 @@
 {
 	void (*ctor)(void *) = get_dtl_cache_ctor();
 
-	dtl_cache = kmem_cache_create("dtl", DISPATCH_LOG_BYTES,
-						DISPATCH_LOG_BYTES, 0, ctor);
+	dtl_cache = kmem_cache_create_usercopy("dtl", DISPATCH_LOG_BYTES,
+						DISPATCH_LOG_BYTES, 0, 0, DISPATCH_LOG_BYTES, ctor);
 	if (!dtl_cache) {
 		pr_warn("Failed to create dispatch trace log buffer cache\n");
 		pr_warn("Stolen time statistics will be unreliable\n");
@@ -1153,7 +1153,6 @@
 	.machine_check_exception = pSeries_machine_check_exception,
 	.machine_check_log_err	= pSeries_machine_check_log_err,
 #ifdef CONFIG_KEXEC_CORE
-	.machine_kexec          = pseries_machine_kexec,
 	.kexec_cpu_down         = pseries_kexec_cpu_down,
 #endif
 #ifdef CONFIG_MEMORY_HOTPLUG
--- linux-qcom-6.8.0.orig/arch/powerpc/platforms/pseries/vio.c
+++ linux-qcom-6.8.0/arch/powerpc/platforms/pseries/vio.c
@@ -39,7 +39,6 @@
 	.name = "vio",
 	.type = "",
 	.dev.init_name = "vio",
-	.dev.bus = &vio_bus_type,
 };
 
 #ifdef CONFIG_PPC_SMLPAR
--- linux-qcom-6.8.0.orig/arch/powerpc/sysdev/fsl_msi.c
+++ linux-qcom-6.8.0/arch/powerpc/sysdev/fsl_msi.c
@@ -566,10 +566,12 @@
 	.msiir_offset = 0x38,
 };
 
+#ifdef CONFIG_EPAPR_PARAVIRT
 static const struct fsl_msi_feature vmpic_msi_feature = {
 	.fsl_pic_ip = FSL_PIC_IP_VMPIC,
 	.msiir_offset = 0,
 };
+#endif
 
 static const struct of_device_id fsl_of_msi_ids[] = {
 	{
--- linux-qcom-6.8.0.orig/arch/powerpc/sysdev/xive/native.c
+++ linux-qcom-6.8.0/arch/powerpc/sysdev/xive/native.c
@@ -559,9 +559,7 @@
 	struct device_node *np;
 	struct resource r;
 	void __iomem *tima;
-	struct property *prop;
 	u8 max_prio = 7;
-	const __be32 *p;
 	u32 val, cpu;
 	s64 rc;
 
@@ -592,7 +590,7 @@
 		max_prio = val - 1;
 
 	/* Iterate the EQ sizes and pick one */
-	of_property_for_each_u32(np, "ibm,xive-eq-sizes", prop, p, val) {
+	of_property_for_each_u32(np, "ibm,xive-eq-sizes", val) {
 		xive_queue_shift = val;
 		if (val == PAGE_SHIFT)
 			break;
--- linux-qcom-6.8.0.orig/arch/powerpc/sysdev/xive/spapr.c
+++ linux-qcom-6.8.0/arch/powerpc/sysdev/xive/spapr.c
@@ -814,7 +814,6 @@
 	struct device_node *np;
 	struct resource r;
 	void __iomem *tima;
-	struct property *prop;
 	u8 max_prio;
 	u32 val;
 	u32 len;
@@ -866,7 +865,7 @@
 	}
 
 	/* Iterate the EQ sizes and pick one */
-	of_property_for_each_u32(np, "ibm,xive-eq-sizes", prop, reg, val) {
+	of_property_for_each_u32(np, "ibm,xive-eq-sizes", val) {
 		xive_queue_shift = val;
 		if (val == PAGE_SHIFT)
 			break;
--- linux-qcom-6.8.0.orig/arch/powerpc/xmon/ppc-dis.c
+++ linux-qcom-6.8.0/arch/powerpc/xmon/ppc-dis.c
@@ -122,32 +122,21 @@
   bool insn_is_short;
   ppc_cpu_t dialect;
 
-  dialect = PPC_OPCODE_PPC | PPC_OPCODE_COMMON
-            | PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC;
+  dialect = PPC_OPCODE_PPC | PPC_OPCODE_COMMON;
 
-  if (cpu_has_feature(CPU_FTRS_POWER5))
-    dialect |= PPC_OPCODE_POWER5;
+  if (IS_ENABLED(CONFIG_PPC64))
+    dialect |= PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_CELL |
+	PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 |
+	PPC_OPCODE_POWER9;
 
-  if (cpu_has_feature(CPU_FTRS_CELL))
-    dialect |= (PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC);
+  if (cpu_has_feature(CPU_FTR_TM))
+    dialect |= PPC_OPCODE_HTM;
 
-  if (cpu_has_feature(CPU_FTRS_POWER6))
-    dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC);
-
-  if (cpu_has_feature(CPU_FTRS_POWER7))
-    dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7
-                | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX);
-
-  if (cpu_has_feature(CPU_FTRS_POWER8))
-    dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7
-		| PPC_OPCODE_POWER8 | PPC_OPCODE_HTM
-		| PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_VSX);
-
-  if (cpu_has_feature(CPU_FTRS_POWER9))
-    dialect |= (PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7
-		| PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9 | PPC_OPCODE_HTM
-		| PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2
-		| PPC_OPCODE_VSX | PPC_OPCODE_VSX3);
+  if (cpu_has_feature(CPU_FTR_ALTIVEC))
+    dialect |= PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2;
+
+  if (cpu_has_feature(CPU_FTR_VSX))
+    dialect |= PPC_OPCODE_VSX | PPC_OPCODE_VSX3;
 
   /* Get the major opcode of the insn.  */
   opcode = NULL;
--- linux-qcom-6.8.0.orig/arch/powerpc/xmon/xmon.c
+++ linux-qcom-6.8.0/arch/powerpc/xmon/xmon.c
@@ -1352,7 +1352,7 @@
 	}
 	termch = cpu;
 
-	if (!scanhex(&cpu)) {
+	if (!scanhex(&cpu) || cpu >= num_possible_cpus()) {
 		/* print cpus waiting or in xmon */
 		printf("cpus stopped:");
 		last_cpu = first_cpu = NR_CPUS;
@@ -2774,7 +2774,7 @@
 
 	termch = c;	/* Put c back, it wasn't 'a' */
 
-	if (scanhex(&num))
+	if (scanhex(&num) && num < num_possible_cpus())
 		dump_one_paca(num);
 	else
 		dump_one_paca(xmon_owner);
@@ -2847,7 +2847,7 @@
 
 	termch = c;	/* Put c back, it wasn't 'a' */
 
-	if (scanhex(&num))
+	if (scanhex(&num) && num < num_possible_cpus())
 		dump_one_xive(num);
 	else
 		dump_one_xive(xmon_owner);
--- linux-qcom-6.8.0.orig/arch/riscv/Kconfig
+++ linux-qcom-6.8.0/arch/riscv/Kconfig
@@ -27,6 +27,7 @@
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_GIGANTIC_PAGE
 	select ARCH_HAS_KCOV
+	select ARCH_HAS_MEMBARRIER_CALLBACKS
 	select ARCH_HAS_MMIOWB
 	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
 	select ARCH_HAS_PMEM_API
@@ -37,7 +38,7 @@
 	select ARCH_HAS_STRICT_MODULE_RWX if MMU && !XIP_KERNEL
 	select ARCH_HAS_SYSCALL_WRAPPER
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
-	select ARCH_HAS_UBSAN_SANITIZE_ALL
+	select ARCH_HAS_UBSAN
 	select ARCH_HAS_VDSO_DATA
 	select ARCH_KEEP_MEMBLOCK if ACPI
 	select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
@@ -96,7 +97,7 @@
 	select HAS_IOPORT if MMU
 	select HAVE_ARCH_AUDITSYSCALL
 	select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP
-	select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT && !XIP_KERNEL
+	select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT
 	select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
 	select HAVE_ARCH_JUMP_LABEL_RELATIVE if !XIP_KERNEL
 	select HAVE_ARCH_KASAN if MMU && 64BIT
@@ -286,6 +287,11 @@
 config FIX_EARLYCON_MEM
 	def_bool MMU
 
+config ILLEGAL_POINTER_VALUE
+	hex
+	default 0 if 32BIT
+	default 0xdead000000000000 if 64BIT
+
 config PGTABLE_LEVELS
 	int
 	default 5 if 64BIT
@@ -519,8 +525,8 @@
 config TOOLCHAIN_HAS_V
 	bool
 	default y
-	depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64iv)
-	depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32iv)
+	depends on !64BIT || $(cc-option,-mabi=lp64 -march=rv64imv)
+	depends on !32BIT || $(cc-option,-mabi=ilp32 -march=rv32imv)
 	depends on LLD_VERSION >= 140000 || LD_VERSION >= 23800
 	depends on AS_HAS_OPTION_ARCH
 
@@ -679,8 +685,7 @@
 config THREAD_SIZE_ORDER
 	int "Kernel stack size (in power-of-two numbers of page size)" if VMAP_STACK && EXPERT
 	range 0 4
-	default 1 if 32BIT && !KASAN
-	default 3 if 64BIT && KASAN
+	default 1 if 32BIT
 	default 2
 	help
 	  Specify the Pages of thread stack size (from 4KB to 64KB), which also
--- linux-qcom-6.8.0.orig/arch/riscv/Kconfig.errata
+++ linux-qcom-6.8.0/arch/riscv/Kconfig.errata
@@ -82,14 +82,14 @@
 
 	  Otherwise, please say "N" here to avoid unnecessary overhead.
 
-config ERRATA_THEAD_PBMT
-	bool "Apply T-Head memory type errata"
+config ERRATA_THEAD_MAE
+	bool "Apply T-Head's memory attribute extension (XTheadMae) errata"
 	depends on ERRATA_THEAD && 64BIT && MMU
 	select RISCV_ALTERNATIVE_EARLY
 	default y
 	help
-	  This will apply the memory type errata to handle the non-standard
-	  memory type bits in page-table-entries on T-Head SoCs.
+	  This will apply the memory attribute extension errata to handle the
+	  non-standard PTE utilization on T-Head SoCs (XTheadMae).
 
 	  If you don't know what to do here, say "Y".
 
--- linux-qcom-6.8.0.orig/arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dts
+++ linux-qcom-6.8.0/arch/riscv/boot/dts/microchip/mpfs-icicle-kit.dts
@@ -160,9 +160,11 @@
 	status = "okay";
 };
 
+/* UBUNTU: PCIe support is not yet ready, so disable it for now
 &pcie {
 	status = "okay";
 };
+*/
 
 &qspi {
 	status = "okay";
--- linux-qcom-6.8.0.orig/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
+++ linux-qcom-6.8.0/arch/riscv/boot/dts/sifive/fu740-c000.dtsi
@@ -42,7 +42,7 @@
 			};
 		};
 		cpu1: cpu@1 {
-			compatible = "sifive,bullet0", "riscv";
+			compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
 			d-cache-block-size = <64>;
 			d-cache-sets = <64>;
 			d-cache-size = <32768>;
@@ -69,7 +69,7 @@
 			};
 		};
 		cpu2: cpu@2 {
-			compatible = "sifive,bullet0", "riscv";
+			compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
 			d-cache-block-size = <64>;
 			d-cache-sets = <64>;
 			d-cache-size = <32768>;
@@ -96,7 +96,7 @@
 			};
 		};
 		cpu3: cpu@3 {
-			compatible = "sifive,bullet0", "riscv";
+			compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
 			d-cache-block-size = <64>;
 			d-cache-sets = <64>;
 			d-cache-size = <32768>;
@@ -123,7 +123,7 @@
 			};
 		};
 		cpu4: cpu@4 {
-			compatible = "sifive,bullet0", "riscv";
+			compatible = "sifive,u74-mc", "sifive,bullet0", "riscv";
 			d-cache-block-size = <64>;
 			d-cache-sets = <64>;
 			d-cache-size = <32768>;
--- linux-qcom-6.8.0.orig/arch/riscv/boot/dts/sifive/hifive-unleashed-a00-microsemi.dts
+++ linux-qcom-6.8.0/arch/riscv/boot/dts/sifive/hifive-unleashed-a00-microsemi.dts
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+#include "hifive-unleashed-a00.dts"
+
+/ {
+	soc {
+		pcie: pcie@2030000000 {
+			#address-cells = <0x3>;
+			#interrupt-cells = <0x1>;
+			#size-cells = <0x2>;
+			compatible = "microsemi,ms-pf-axi-pcie-host";
+			device_type = "pci";
+			bus-range = <0x01 0x7f>;
+			interrupt-map = <0 0 0 1 &ms_pcie_intc 0 0 0 0 2 &ms_pcie_intc 1 0 0 0 3 &ms_pcie_intc 2 0 0 0 4 &ms_pcie_intc 3>;
+			interrupt-map-mask = <0 0 0 7>;
+			interrupt-parent = <&plic0>;
+			interrupts = <32>;
+			ranges = <0x3000000 0x0 0x40000000 0x0 0x40000000 0x0 0x20000000>;
+			reg = <0x20 0x30000000 0x0 0x4000000 0x20 0x0 0x0 0x100000>;
+			reg-names = "control", "apb";
+			ms_pcie_intc: interrupt-controller {
+				#address-cells = <0>;
+				#interrupt-cells = <1>;
+				interrupt-controller;
+			};
+		};
+	};
+};
--- linux-qcom-6.8.0.orig/arch/riscv/boot/dts/starfive/jh7100.dtsi
+++ linux-qcom-6.8.0/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -116,6 +116,7 @@
 	osc_sys: osc-sys {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
+		clock-output-names = "osc_sys";
 		/* This value must be overridden by the board */
 		clock-frequency = <0>;
 	};
@@ -123,6 +124,7 @@
 	osc_aud: osc-aud {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
+		clock-output-names = "osc_aud";
 		/* This value must be overridden by the board */
 		clock-frequency = <0>;
 	};
@@ -130,6 +132,7 @@
 	gmac_rmii_ref: gmac-rmii-ref {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
+		clock-output-names = "gmac_rmii_ref";
 		/* Should be overridden by the board when needed */
 		clock-frequency = <0>;
 	};
@@ -137,6 +140,7 @@
 	gmac_gr_mii_rxclk: gmac-gr-mii-rxclk {
 		compatible = "fixed-clock";
 		#clock-cells = <0>;
+		clock-output-names = "gmac_gr_mii_rxclk";
 		/* Should be overridden by the board when needed */
 		clock-frequency = <0>;
 	};
--- linux-qcom-6.8.0.orig/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
+++ linux-qcom-6.8.0/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
@@ -189,7 +189,6 @@
 	axp15060: pmic@36 {
 		compatible = "x-powers,axp15060";
 		reg = <0x36>;
-		interrupts = <0>;
 		interrupt-controller;
 		#interrupt-cells = <1>;
 
@@ -230,24 +229,6 @@
 	status = "okay";
 };
 
-&i2srx {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2srx_pins>;
-	status = "okay";
-};
-
-&i2stx0 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&mclk_ext_pins>;
-	status = "okay";
-};
-
-&i2stx1 {
-	pinctrl-names = "default";
-	pinctrl-0 = <&i2stx1_pins>;
-	status = "okay";
-};
-
 &mmc0 {
 	max-frequency = <100000000>;
 	assigned-clocks = <&syscrg JH7110_SYSCLK_SDIO0_SDCARD>;
@@ -335,6 +316,12 @@
 	};
 };
 
+&syscrg {
+	assigned-clocks = <&syscrg JH7110_SYSCLK_CPU_CORE>,
+			  <&pllclk JH7110_PLLCLK_PLL0_OUT>;
+	assigned-clock-rates = <500000000>, <1500000000>;
+};
+
 &sysgpio {
 	i2c0_pins: i2c0-0 {
 		i2c-pins {
@@ -392,46 +379,6 @@
 		};
 	};
 
-	i2srx_pins: i2srx-0 {
-		clk-sd-pins {
-			pinmux = <GPIOMUX(38, GPOUT_LOW,
-					      GPOEN_DISABLE,
-					      GPI_SYS_I2SRX_BCLK)>,
-				 <GPIOMUX(63, GPOUT_LOW,
-					      GPOEN_DISABLE,
-					      GPI_SYS_I2SRX_LRCK)>,
-				 <GPIOMUX(38, GPOUT_LOW,
-					      GPOEN_DISABLE,
-					      GPI_SYS_I2STX1_BCLK)>,
-				 <GPIOMUX(63, GPOUT_LOW,
-					      GPOEN_DISABLE,
-					      GPI_SYS_I2STX1_LRCK)>,
-				 <GPIOMUX(61, GPOUT_LOW,
-					      GPOEN_DISABLE,
-					      GPI_SYS_I2SRX_SDIN0)>;
-			input-enable;
-		};
-	};
-
-	i2stx1_pins: i2stx1-0 {
-		sd-pins {
-			pinmux = <GPIOMUX(44, GPOUT_SYS_I2STX1_SDO0,
-					      GPOEN_ENABLE,
-					      GPI_NONE)>;
-			bias-disable;
-			input-disable;
-		};
-	};
-
-	mclk_ext_pins: mclk-ext-0 {
-		mclk-ext-pins {
-			pinmux = <GPIOMUX(4, GPOUT_LOW,
-					     GPOEN_DISABLE,
-					     GPI_SYS_MCLK_EXT)>;
-			input-enable;
-		};
-	};
-
 	mmc0_pins: mmc0-0 {
 		 rst-pins {
 			pinmux = <GPIOMUX(62, GPOUT_SYS_SDIO0_RST,
@@ -551,40 +498,6 @@
 		};
 	};
 
-	tdm_pins: tdm-0 {
-		tx-pins {
-			pinmux = <GPIOMUX(44, GPOUT_SYS_TDM_TXD,
-					      GPOEN_ENABLE,
-					      GPI_NONE)>;
-			bias-pull-up;
-			drive-strength = <2>;
-			input-disable;
-			input-schmitt-disable;
-			slew-rate = <0>;
-		};
-
-		rx-pins {
-			pinmux = <GPIOMUX(61, GPOUT_HIGH,
-					      GPOEN_DISABLE,
-					      GPI_SYS_TDM_RXD)>;
-			input-enable;
-		};
-
-		sync-pins {
-			pinmux = <GPIOMUX(63, GPOUT_HIGH,
-					      GPOEN_DISABLE,
-					      GPI_SYS_TDM_SYNC)>;
-			input-enable;
-		};
-
-		pcmclk-pins {
-			pinmux = <GPIOMUX(38, GPOUT_HIGH,
-					      GPOEN_DISABLE,
-					      GPI_SYS_TDM_CLK)>;
-			input-enable;
-		};
-	};
-
 	uart0_pins: uart0-0 {
 		tx-pins {
 			pinmux = <GPIOMUX(5, GPOUT_SYS_UART0_TX,
@@ -610,12 +523,6 @@
 	};
 };
 
-&tdm {
-	pinctrl-names = "default";
-	pinctrl-0 = <&tdm_pins>;
-	status = "okay";
-};
-
 &uart0 {
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart0_pins>;
--- linux-qcom-6.8.0.orig/arch/riscv/errata/thead/errata.c
+++ linux-qcom-6.8.0/arch/riscv/errata/thead/errata.c
@@ -19,20 +19,26 @@
 #include <asm/patch.h>
 #include <asm/vendorid_list.h>
 
-static bool errata_probe_pbmt(unsigned int stage,
-			      unsigned long arch_id, unsigned long impid)
+#define CSR_TH_SXSTATUS		0x5c0
+#define SXSTATUS_MAEE		_AC(0x200000, UL)
+
+static bool errata_probe_mae(unsigned int stage,
+			     unsigned long arch_id, unsigned long impid)
 {
-	if (!IS_ENABLED(CONFIG_ERRATA_THEAD_PBMT))
+	if (!IS_ENABLED(CONFIG_ERRATA_THEAD_MAE))
 		return false;
 
 	if (arch_id != 0 || impid != 0)
 		return false;
 
-	if (stage == RISCV_ALTERNATIVES_EARLY_BOOT ||
-	    stage == RISCV_ALTERNATIVES_MODULE)
-		return true;
+	if (stage != RISCV_ALTERNATIVES_EARLY_BOOT &&
+	    stage != RISCV_ALTERNATIVES_MODULE)
+		return false;
+
+	if (!(csr_read(CSR_TH_SXSTATUS) & SXSTATUS_MAEE))
+		return false;
 
-	return false;
+	return true;
 }
 
 /*
@@ -140,8 +146,8 @@
 {
 	u32 cpu_req_errata = 0;
 
-	if (errata_probe_pbmt(stage, archid, impid))
-		cpu_req_errata |= BIT(ERRATA_THEAD_PBMT);
+	if (errata_probe_mae(stage, archid, impid))
+		cpu_req_errata |= BIT(ERRATA_THEAD_MAE);
 
 	errata_probe_cmo(stage, archid, impid);
 
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/asm.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/asm.h
@@ -183,6 +183,16 @@
 	REG_L x31, PT_T6(sp)
 	.endm
 
+/* Annotate a function as being unsuitable for kprobes. */
+#ifdef CONFIG_KPROBES
+#define ASM_NOKPROBE(name)				\
+	.pushsection "_kprobe_blacklist", "aw";		\
+	RISCV_PTR name;					\
+	.popsection
+#else
+#define ASM_NOKPROBE(name)
+#endif
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_RISCV_ASM_H */
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/cacheflush.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/cacheflush.h
@@ -13,6 +13,12 @@
 	asm volatile ("fence.i" ::: "memory");
 }
 
+static inline void local_flush_icache_range(unsigned long start,
+					    unsigned long end)
+{
+	local_flush_icache_all();
+}
+
 #define PG_dcache_clean PG_arch_1
 
 static inline void flush_dcache_folio(struct folio *folio)
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/errata_list.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/errata_list.h
@@ -23,7 +23,7 @@
 #endif
 
 #ifdef CONFIG_ERRATA_THEAD
-#define	ERRATA_THEAD_PBMT 0
+#define	ERRATA_THEAD_MAE 0
 #define	ERRATA_THEAD_PMU 1
 #define	ERRATA_THEAD_NUMBER 2
 #endif
@@ -43,30 +43,40 @@
 	    CONFIG_ERRATA_SIFIVE_CIP_453)
 #else /* !__ASSEMBLY__ */
 
-#define ALT_FLUSH_TLB_PAGE(x)						\
+#define ALT_SFENCE_VMA_ASID(asid)					\
+asm(ALTERNATIVE("sfence.vma x0, %0", "sfence.vma", SIFIVE_VENDOR_ID,	\
+		ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200)	\
+		: : "r" (asid) : "memory")
+
+#define ALT_SFENCE_VMA_ADDR(addr)					\
 asm(ALTERNATIVE("sfence.vma %0", "sfence.vma", SIFIVE_VENDOR_ID,	\
 		ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200)	\
 		: : "r" (addr) : "memory")
 
+#define ALT_SFENCE_VMA_ADDR_ASID(addr, asid)				\
+asm(ALTERNATIVE("sfence.vma %0, %1", "sfence.vma", SIFIVE_VENDOR_ID,	\
+		ERRATA_SIFIVE_CIP_1200, CONFIG_ERRATA_SIFIVE_CIP_1200)	\
+		: : "r" (addr), "r" (asid) : "memory")
+
 /*
  * _val is marked as "will be overwritten", so need to set it to 0
  * in the default case.
  */
 #define ALT_SVPBMT_SHIFT 61
-#define ALT_THEAD_PBMT_SHIFT 59
+#define ALT_THEAD_MAE_SHIFT 59
 #define ALT_SVPBMT(_val, prot)						\
 asm(ALTERNATIVE_2("li %0, 0\t\nnop",					\
 		  "li %0, %1\t\nslli %0,%0,%3", 0,			\
 			RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT,	\
 		  "li %0, %2\t\nslli %0,%0,%4", THEAD_VENDOR_ID,	\
-			ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT)	\
+			ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)	\
 		: "=r"(_val)						\
 		: "I"(prot##_SVPBMT >> ALT_SVPBMT_SHIFT),		\
-		  "I"(prot##_THEAD >> ALT_THEAD_PBMT_SHIFT),		\
+		  "I"(prot##_THEAD >> ALT_THEAD_MAE_SHIFT),		\
 		  "I"(ALT_SVPBMT_SHIFT),				\
-		  "I"(ALT_THEAD_PBMT_SHIFT))
+		  "I"(ALT_THEAD_MAE_SHIFT))
 
-#ifdef CONFIG_ERRATA_THEAD_PBMT
+#ifdef CONFIG_ERRATA_THEAD_MAE
 /*
  * IO/NOCACHE memory types are handled together with svpbmt,
  * so on T-Head chips, check if no other memory type is set,
@@ -83,11 +93,11 @@
 	"slli    t3, t3, %3\n\t"					\
 	"or      %0, %0, t3\n\t"					\
 	"2:",  THEAD_VENDOR_ID,						\
-		ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT)		\
+		ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)		\
 	: "+r"(_val)							\
-	: "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_PBMT_SHIFT),		\
-	  "I"(_PAGE_PMA_THEAD >> ALT_THEAD_PBMT_SHIFT),			\
-	  "I"(ALT_THEAD_PBMT_SHIFT)					\
+	: "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_MAE_SHIFT),		\
+	  "I"(_PAGE_PMA_THEAD >> ALT_THEAD_MAE_SHIFT),			\
+	  "I"(ALT_THEAD_MAE_SHIFT)					\
 	: "t3")
 #else
 #define ALT_THEAD_PMA(_val)
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/insn.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/insn.h
@@ -145,7 +145,7 @@
 
 /* parts of opcode for RVF, RVD and RVQ */
 #define RVFDQ_FL_FS_WIDTH_OFF	12
-#define RVFDQ_FL_FS_WIDTH_MASK	GENMASK(3, 0)
+#define RVFDQ_FL_FS_WIDTH_MASK	GENMASK(2, 0)
 #define RVFDQ_FL_FS_WIDTH_W	2
 #define RVFDQ_FL_FS_WIDTH_D	3
 #define RVFDQ_LS_FS_WIDTH_Q	4
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/kfence.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/kfence.h
@@ -22,7 +22,9 @@
 	else
 		set_pte(pte, __pte(pte_val(ptep_get(pte)) | _PAGE_PRESENT));
 
-	flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+	preempt_disable();
+	local_flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+	preempt_enable();
 
 	return true;
 }
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/kvm_vcpu_pmu.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/kvm_vcpu_pmu.h
@@ -10,6 +10,7 @@
 #define __KVM_VCPU_RISCV_PMU_H
 
 #include <linux/perf/riscv_pmu.h>
+#include <asm/kvm_vcpu_insn.h>
 #include <asm/sbi.h>
 
 #ifdef CONFIG_RISCV_PMU_SBI
@@ -57,11 +58,11 @@
 
 #if defined(CONFIG_32BIT)
 #define KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS \
-{.base = CSR_CYCLEH,	.count = 31,	.func = kvm_riscv_vcpu_pmu_read_hpm }, \
-{.base = CSR_CYCLE,	.count = 31,	.func = kvm_riscv_vcpu_pmu_read_hpm },
+{.base = CSR_CYCLEH,	.count = 32,	.func = kvm_riscv_vcpu_pmu_read_hpm }, \
+{.base = CSR_CYCLE,	.count = 32,	.func = kvm_riscv_vcpu_pmu_read_hpm },
 #else
 #define KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS \
-{.base = CSR_CYCLE,	.count = 31,	.func = kvm_riscv_vcpu_pmu_read_hpm },
+{.base = CSR_CYCLE,	.count = 32,	.func = kvm_riscv_vcpu_pmu_read_hpm },
 #endif
 
 int kvm_riscv_vcpu_pmu_incr_fw(struct kvm_vcpu *vcpu, unsigned long fid);
@@ -92,8 +93,20 @@
 struct kvm_pmu {
 };
 
+static inline int kvm_riscv_vcpu_pmu_read_legacy(struct kvm_vcpu *vcpu, unsigned int csr_num,
+						 unsigned long *val, unsigned long new_val,
+						 unsigned long wr_mask)
+{
+	if (csr_num == CSR_CYCLE || csr_num == CSR_INSTRET) {
+		*val = 0;
+		return KVM_INSN_CONTINUE_NEXT_SEPC;
+	} else {
+		return KVM_INSN_ILLEGAL_TRAP;
+	}
+}
+
 #define KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS \
-{.base = 0,	.count = 0,	.func = NULL },
+{.base = CSR_CYCLE,	.count = 3,	.func = kvm_riscv_vcpu_pmu_read_legacy },
 
 static inline void kvm_riscv_vcpu_pmu_init(struct kvm_vcpu *vcpu) {}
 static inline int kvm_riscv_vcpu_pmu_incr_fw(struct kvm_vcpu *vcpu, unsigned long fid)
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/membarrier.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/membarrier.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASM_RISCV_MEMBARRIER_H
+#define _ASM_RISCV_MEMBARRIER_H
+
+static inline void membarrier_arch_switch_mm(struct mm_struct *prev,
+					     struct mm_struct *next,
+					     struct task_struct *tsk)
+{
+	/*
+	 * Only need the full barrier when switching between processes.
+	 * Barrier when switching from kernel to userspace is not
+	 * required here, given that it is implied by mmdrop(). Barrier
+	 * when switching from userspace to kernel is not needed after
+	 * store to rq->curr.
+	 */
+	if (IS_ENABLED(CONFIG_SMP) &&
+	    likely(!(atomic_read(&next->membarrier_state) &
+		     (MEMBARRIER_STATE_PRIVATE_EXPEDITED |
+		      MEMBARRIER_STATE_GLOBAL_EXPEDITED)) || !prev))
+		return;
+
+	/*
+	 * The membarrier system call requires a full memory barrier
+	 * after storing to rq->curr, before going back to user-space.
+	 * Matches a full barrier in the proximity of the membarrier
+	 * system call entry.
+	 */
+	smp_mb();
+}
+
+#endif /* _ASM_RISCV_MEMBARRIER_H */
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/page.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/page.h
@@ -89,7 +89,7 @@
 #define PTE_FMT "%08lx"
 #endif
 
-#ifdef CONFIG_64BIT
+#if defined(CONFIG_64BIT) && defined(CONFIG_MMU)
 /*
  * We override this value as its generic definition uses __pa too early in
  * the boot process (before kernel_map.va_pa_offset is set).
@@ -122,6 +122,7 @@
 
 extern struct kernel_mapping kernel_map;
 extern phys_addr_t phys_ram_base;
+extern unsigned long vmemmap_start_pfn;
 
 #define is_kernel_mapping(x)	\
 	((x) >= kernel_map.virt_addr && (x) < (kernel_map.virt_addr + kernel_map.size))
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/patch.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/patch.h
@@ -6,6 +6,7 @@
 #ifndef _ASM_RISCV_PATCH_H
 #define _ASM_RISCV_PATCH_H
 
+int patch_insn_write(void *addr, const void *insn, size_t len);
 int patch_text_nosync(void *addr, const void *insns, size_t len);
 int patch_text_set_nosync(void *addr, u8 c, size_t len);
 int patch_text(void *addr, u32 *insns, int ninsns);
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/pgtable.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/pgtable.h
@@ -84,7 +84,7 @@
  * Define vmemmap for pfn_to_page & page_to_pfn calls. Needed if kernel
  * is configured with CONFIG_SPARSEMEM_VMEMMAP enabled.
  */
-#define vmemmap		((struct page *)VMEMMAP_START - (phys_ram_base >> PAGE_SHIFT))
+#define vmemmap		((struct page *)VMEMMAP_START - vmemmap_start_pfn)
 
 #define PCI_IO_SIZE      SZ_16M
 #define PCI_IO_END       VMEMMAP_START
@@ -439,9 +439,11 @@
 	return pte;
 }
 
+#ifdef CONFIG_RISCV_ISA_SVNAPOT
 #define pte_leaf_size(pte)	(pte_napot(pte) ?				\
 					napot_cont_size(napot_cont_order(pte)) :\
 					PAGE_SIZE)
+#endif
 
 #ifdef CONFIG_NUMA_BALANCING
 /*
@@ -886,7 +888,7 @@
 #define PAGE_SHARED		__pgprot(0)
 #define PAGE_KERNEL		__pgprot(0)
 #define swapper_pg_dir		NULL
-#define TASK_SIZE		0xffffffffUL
+#define TASK_SIZE		_AC(-1, UL)
 #define VMALLOC_START		_AC(0, UL)
 #define VMALLOC_END		TASK_SIZE
 
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/sbi.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/sbi.h
@@ -9,6 +9,7 @@
 
 #include <linux/types.h>
 #include <linux/cpumask.h>
+#include <linux/jump_label.h>
 
 #ifdef CONFIG_RISCV_SBI
 enum sbi_ext_id {
@@ -292,10 +293,13 @@
 };
 
 void sbi_init(void);
-struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
-			unsigned long arg1, unsigned long arg2,
-			unsigned long arg3, unsigned long arg4,
-			unsigned long arg5);
+long __sbi_base_ecall(int fid);
+struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1,
+			  unsigned long arg2, unsigned long arg3,
+			  unsigned long arg4, unsigned long arg5,
+			  int fid, int ext);
+#define sbi_ecall(e, f, a0, a1, a2, a3, a4, a5)	\
+		__sbi_ecall(a0, a1, a2, a3, a4, a5, f, e)
 
 #ifdef CONFIG_RISCV_SBI_V01
 void sbi_console_putchar(int ch);
@@ -359,7 +363,23 @@
 		SBI_SPEC_VERSION_MAJOR_SHIFT) | minor;
 }
 
-int sbi_err_map_linux_errno(int err);
+static inline int sbi_err_map_linux_errno(int err)
+{
+	switch (err) {
+	case SBI_SUCCESS:
+		return 0;
+	case SBI_ERR_DENIED:
+		return -EPERM;
+	case SBI_ERR_INVALID_PARAM:
+		return -EINVAL;
+	case SBI_ERR_INVALID_ADDRESS:
+		return -EFAULT;
+	case SBI_ERR_NOT_SUPPORTED:
+	case SBI_ERR_FAILURE:
+	default:
+		return -ENOTSUPP;
+	};
+}
 
 extern bool sbi_debug_console_available;
 int sbi_debug_console_write(const char *bytes, unsigned int num_bytes);
@@ -370,6 +390,8 @@
 static inline void sbi_init(void) {}
 #endif /* CONFIG_RISCV_SBI */
 
+unsigned long riscv_get_mvendorid(void);
+unsigned long riscv_get_marchid(void);
 unsigned long riscv_cached_mvendorid(unsigned int cpu_id);
 unsigned long riscv_cached_marchid(unsigned int cpu_id);
 unsigned long riscv_cached_mimpid(unsigned int cpu_id);
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/sparsemem.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/sparsemem.h
@@ -7,7 +7,7 @@
 #ifdef CONFIG_64BIT
 #define MAX_PHYSMEM_BITS	56
 #else
-#define MAX_PHYSMEM_BITS	34
+#define MAX_PHYSMEM_BITS	32
 #endif /* CONFIG_64BIT */
 #define SECTION_SIZE_BITS	27
 #endif /* CONFIG_SPARSEMEM */
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/string.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/string.h
@@ -19,6 +19,7 @@
 extern asmlinkage void *memmove(void *, const void *, size_t);
 extern asmlinkage void *__memmove(void *, const void *, size_t);
 
+#if !(defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS))
 #define __HAVE_ARCH_STRCMP
 extern asmlinkage int strcmp(const char *cs, const char *ct);
 
@@ -27,6 +28,7 @@
 
 #define __HAVE_ARCH_STRNCMP
 extern asmlinkage int strncmp(const char *cs, const char *ct, size_t count);
+#endif
 
 /* For those files which don't want to check by kasan. */
 #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/thread_info.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/thread_info.h
@@ -12,7 +12,12 @@
 #include <linux/const.h>
 
 /* thread information allocation */
-#define THREAD_SIZE_ORDER	CONFIG_THREAD_SIZE_ORDER
+#ifdef CONFIG_KASAN
+#define KASAN_STACK_ORDER	1
+#else
+#define KASAN_STACK_ORDER	0
+#endif
+#define THREAD_SIZE_ORDER	(CONFIG_THREAD_SIZE_ORDER + KASAN_STACK_ORDER)
 #define THREAD_SIZE		(PAGE_SIZE << THREAD_SIZE_ORDER)
 
 /*
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/tlbflush.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/tlbflush.h
@@ -22,10 +22,27 @@
 	__asm__ __volatile__ ("sfence.vma" : : : "memory");
 }
 
+static inline void local_flush_tlb_all_asid(unsigned long asid)
+{
+	if (asid != FLUSH_TLB_NO_ASID)
+		ALT_SFENCE_VMA_ASID(asid);
+	else
+		local_flush_tlb_all();
+}
+
 /* Flush one page from local TLB */
 static inline void local_flush_tlb_page(unsigned long addr)
 {
-	ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory"));
+	ALT_SFENCE_VMA_ADDR(addr);
+}
+
+static inline void local_flush_tlb_page_asid(unsigned long addr,
+					     unsigned long asid)
+{
+	if (asid != FLUSH_TLB_NO_ASID)
+		ALT_SFENCE_VMA_ADDR_ASID(addr, asid);
+	else
+		local_flush_tlb_page(addr);
 }
 #else /* CONFIG_MMU */
 #define local_flush_tlb_all()			do { } while (0)
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/trace.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/trace.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM riscv
+
+#if !defined(_TRACE_RISCV_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_RISCV_H
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT_CONDITION(sbi_call,
+	TP_PROTO(int ext, int fid),
+	TP_ARGS(ext, fid),
+	TP_CONDITION(ext != SBI_EXT_HSM),
+
+	TP_STRUCT__entry(
+		__field(int, ext)
+		__field(int, fid)
+	),
+
+	TP_fast_assign(
+		__entry->ext = ext;
+		__entry->fid = fid;
+	),
+
+	TP_printk("ext=0x%x fid=%d", __entry->ext, __entry->fid)
+);
+
+TRACE_EVENT_CONDITION(sbi_return,
+	TP_PROTO(int ext, long error, long value),
+	TP_ARGS(ext, error, value),
+	TP_CONDITION(ext != SBI_EXT_HSM),
+
+	TP_STRUCT__entry(
+		__field(long, error)
+		__field(long, value)
+	),
+
+	TP_fast_assign(
+		__entry->error = error;
+		__entry->value = value;
+	),
+
+	TP_printk("error=%ld value=0x%lx", __entry->error, __entry->value)
+);
+
+#endif /* _TRACE_RISCV_H */
+
+#undef TRACE_INCLUDE_PATH
+#undef TRACE_INCLUDE_FILE
+
+#define TRACE_INCLUDE_PATH asm
+#define TRACE_INCLUDE_FILE trace
+
+#include <trace/define_trace.h>
--- linux-qcom-6.8.0.orig/arch/riscv/include/asm/uaccess.h
+++ linux-qcom-6.8.0/arch/riscv/include/asm/uaccess.h
@@ -319,7 +319,7 @@
 
 #define __get_kernel_nofault(dst, src, type, err_label)			\
 do {									\
-	long __kr_err;							\
+	long __kr_err = 0;						\
 									\
 	__get_user_nocheck(*((type *)(dst)), (type *)(src), __kr_err);	\
 	if (unlikely(__kr_err))						\
@@ -328,7 +328,7 @@
 
 #define __put_kernel_nofault(dst, src, type, err_label)			\
 do {									\
-	long __kr_err;							\
+	long __kr_err = 0;						\
 									\
 	__put_user_nocheck(*((type *)(src)), (type *)(dst), __kr_err);	\
 	if (unlikely(__kr_err))						\
--- linux-qcom-6.8.0.orig/arch/riscv/include/uapi/asm/auxvec.h
+++ linux-qcom-6.8.0/arch/riscv/include/uapi/asm/auxvec.h
@@ -34,7 +34,7 @@
 #define AT_L3_CACHEGEOMETRY	47
 
 /* entries in ARCH_DLINFO */
-#define AT_VECTOR_SIZE_ARCH	9
+#define AT_VECTOR_SIZE_ARCH	10
 #define AT_MINSIGSTKSZ		51
 
 #endif /* _UAPI_ASM_RISCV_AUXVEC_H */
--- linux-qcom-6.8.0.orig/arch/riscv/include/uapi/asm/hwprobe.h
+++ linux-qcom-6.8.0/arch/riscv/include/uapi/asm/hwprobe.h
@@ -54,7 +54,7 @@
 #define		RISCV_HWPROBE_EXT_ZFHMIN	(1 << 28)
 #define		RISCV_HWPROBE_EXT_ZIHINTNTL	(1 << 29)
 #define		RISCV_HWPROBE_EXT_ZVFH		(1 << 30)
-#define		RISCV_HWPROBE_EXT_ZVFHMIN	(1 << 31)
+#define		RISCV_HWPROBE_EXT_ZVFHMIN	(1ULL << 31)
 #define		RISCV_HWPROBE_EXT_ZFA		(1ULL << 32)
 #define		RISCV_HWPROBE_EXT_ZTSO		(1ULL << 33)
 #define		RISCV_HWPROBE_EXT_ZACAS		(1ULL << 34)
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/Makefile
+++ linux-qcom-6.8.0/arch/riscv/kernel/Makefile
@@ -20,17 +20,21 @@
 ifdef CONFIG_RISCV_ALTERNATIVE_EARLY
 CFLAGS_alternative.o := -mcmodel=medany
 CFLAGS_cpufeature.o := -mcmodel=medany
+CFLAGS_sbi_ecall.o := -mcmodel=medany
 ifdef CONFIG_FTRACE
 CFLAGS_REMOVE_alternative.o = $(CC_FLAGS_FTRACE)
 CFLAGS_REMOVE_cpufeature.o = $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_sbi_ecall.o = $(CC_FLAGS_FTRACE)
 endif
 ifdef CONFIG_RELOCATABLE
 CFLAGS_alternative.o += -fno-pie
 CFLAGS_cpufeature.o += -fno-pie
+CFLAGS_sbi_ecall.o += -fno-pie
 endif
 ifdef CONFIG_KASAN
 KASAN_SANITIZE_alternative.o := n
 KASAN_SANITIZE_cpufeature.o := n
+KASAN_SANITIZE_sbi_ecall.o := n
 endif
 endif
 
@@ -83,7 +87,7 @@
 
 obj-$(CONFIG_PERF_EVENTS)	+= perf_callchain.o
 obj-$(CONFIG_HAVE_PERF_REGS)	+= perf_regs.o
-obj-$(CONFIG_RISCV_SBI)		+= sbi.o
+obj-$(CONFIG_RISCV_SBI)		+= sbi.o sbi_ecall.o
 ifeq ($(CONFIG_RISCV_SBI), y)
 obj-$(CONFIG_SMP)		+= sbi-ipi.o
 obj-$(CONFIG_SMP) += cpu_ops_sbi.o
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/acpi.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/acpi.c
@@ -205,7 +205,7 @@
 	if (!size)
 		return NULL;
 
-	return early_ioremap(phys, size);
+	return early_memremap(phys, size);
 }
 
 void __init __acpi_unmap_table(void __iomem *map, unsigned long size)
@@ -213,7 +213,7 @@
 	if (!map || !size)
 		return;
 
-	early_iounmap(map, size);
+	early_memunmap(map, size);
 }
 
 void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/asm-offsets.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/asm-offsets.c
@@ -4,8 +4,6 @@
  * Copyright (C) 2017 SiFive
  */
 
-#define GENERATING_ASM_OFFSETS
-
 #include <linux/kbuild.h>
 #include <linux/mm.h>
 #include <linux/sched.h>
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/cpu-hotplug.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/cpu-hotplug.c
@@ -58,7 +58,7 @@
 	if (cpu_ops->cpu_is_stopped)
 		ret = cpu_ops->cpu_is_stopped(cpu);
 	if (ret)
-		pr_warn("CPU%d may not have stopped: %d\n", cpu, ret);
+		pr_warn("CPU%u may not have stopped: %d\n", cpu, ret);
 }
 
 /*
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/cpu.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/cpu.c
@@ -139,6 +139,34 @@
 	return -1;
 }
 
+unsigned long __init riscv_get_marchid(void)
+{
+	struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
+
+#if IS_ENABLED(CONFIG_RISCV_SBI)
+	ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
+#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
+	ci->marchid = csr_read(CSR_MARCHID);
+#else
+	ci->marchid = 0;
+#endif
+	return ci->marchid;
+}
+
+unsigned long __init riscv_get_mvendorid(void)
+{
+	struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
+
+#if IS_ENABLED(CONFIG_RISCV_SBI)
+	ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
+#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
+	ci->mvendorid = csr_read(CSR_MVENDORID);
+#else
+	ci->mvendorid = 0;
+#endif
+	return ci->mvendorid;
+}
+
 DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
 
 unsigned long riscv_cached_mvendorid(unsigned int cpu_id)
@@ -170,12 +198,16 @@
 	struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
 
 #if IS_ENABLED(CONFIG_RISCV_SBI)
-	ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
-	ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
+	if (!ci->mvendorid)
+		ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
+	if (!ci->marchid)
+		ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
 	ci->mimpid = sbi_spec_is_0_1() ? 0 : sbi_get_mimpid();
 #elif IS_ENABLED(CONFIG_RISCV_M_MODE)
-	ci->mvendorid = csr_read(CSR_MVENDORID);
-	ci->marchid = csr_read(CSR_MARCHID);
+	if (!ci->mvendorid)
+		ci->mvendorid = csr_read(CSR_MVENDORID);
+	if (!ci->marchid)
+		ci->marchid = csr_read(CSR_MARCHID);
 	ci->mimpid = csr_read(CSR_MIMPID);
 #else
 	ci->mvendorid = 0;
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/cpu_ops_sbi.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/cpu_ops_sbi.c
@@ -72,7 +72,7 @@
 	/* Make sure tidle is updated */
 	smp_mb();
 	bdata->task_ptr = tidle;
-	bdata->stack_ptr = task_stack_page(tidle) + THREAD_SIZE;
+	bdata->stack_ptr = task_pt_regs(tidle);
 	/* Make sure boot data is updated */
 	smp_mb();
 	hsm_data = __pa(bdata);
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/cpu_ops_spinwait.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/cpu_ops_spinwait.c
@@ -34,8 +34,7 @@
 
 	/* Make sure tidle is updated */
 	smp_mb();
-	WRITE_ONCE(__cpu_spinwait_stack_pointer[hartid],
-		   task_stack_page(tidle) + THREAD_SIZE);
+	WRITE_ONCE(__cpu_spinwait_stack_pointer[hartid], task_pt_regs(tidle));
 	WRITE_ONCE(__cpu_spinwait_task_pointer[hartid], tidle);
 }
 
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/cpufeature.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/cpufeature.c
@@ -503,6 +503,8 @@
 	struct acpi_table_header *rhct;
 	acpi_status status;
 	unsigned int cpu;
+	u64 boot_vendorid;
+	u64 boot_archid;
 
 	if (!acpi_disabled) {
 		status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
@@ -510,6 +512,9 @@
 			return;
 	}
 
+	boot_vendorid = riscv_get_mvendorid();
+	boot_archid = riscv_get_marchid();
+
 	for_each_possible_cpu(cpu) {
 		struct riscv_isainfo *isainfo = &hart_isa[cpu];
 		unsigned long this_hwcap = 0;
@@ -557,8 +562,7 @@
 		 * CPU cores with the ratified spec will contain non-zero
 		 * marchid.
 		 */
-		if (acpi_disabled && riscv_cached_mvendorid(cpu) == THEAD_VENDOR_ID &&
-		    riscv_cached_marchid(cpu) == 0x0) {
+		if (acpi_disabled && boot_vendorid == THEAD_VENDOR_ID && boot_archid == 0x0) {
 			this_hwcap &= ~isa2hwcap[RISCV_ISA_EXT_v];
 			clear_bit(RISCV_ISA_EXT_v, isainfo->isa);
 		}
@@ -612,7 +616,7 @@
 
 			if (ext->subset_ext_size) {
 				for (int j = 0; j < ext->subset_ext_size; j++) {
-					if (riscv_isa_extension_check(ext->subset_ext_ids[i]))
+					if (riscv_isa_extension_check(ext->subset_ext_ids[j]))
 						set_bit(ext->subset_ext_ids[j], isainfo->isa);
 				}
 			}
@@ -899,6 +903,7 @@
 	if (per_cpu(misaligned_access_speed, cpu) != RISCV_HWPROBE_MISALIGNED_UNKNOWN)
 		goto exit;
 
+	check_unaligned_access_emulated(NULL);
 	buf = alloc_pages(GFP_KERNEL, MISALIGNED_BUFFER_ORDER);
 	if (!buf) {
 		pr_warn("Allocation failure, not measuring misaligned performance\n");
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/efi-header.S
+++ linux-qcom-6.8.0/arch/riscv/kernel/efi-header.S
@@ -64,7 +64,7 @@
 	.long	efi_header_end - _start			// SizeOfHeaders
 	.long	0					// CheckSum
 	.short	IMAGE_SUBSYSTEM_EFI_APPLICATION		// Subsystem
-	.short	0					// DllCharacteristics
+	.short	IMAGE_DLL_CHARACTERISTICS_NX_COMPAT	// DllCharacteristics
 	.quad	0					// SizeOfStackReserve
 	.quad	0					// SizeOfStackCommit
 	.quad	0					// SizeOfHeapReserve
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/elf_kexec.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/elf_kexec.c
@@ -445,6 +445,12 @@
 			*(u32 *)loc = CLEAN_IMM(CJTYPE, *(u32 *)loc) |
 				 ENCODE_CJTYPE_IMM(val - addr);
 			break;
+		case R_RISCV_ADD16:
+			*(u16 *)loc += val;
+			break;
+		case R_RISCV_SUB16:
+			*(u16 *)loc -= val;
+			break;
 		case R_RISCV_ADD32:
 			*(u32 *)loc += val;
 			break;
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/entry.S
+++ linux-qcom-6.8.0/arch/riscv/kernel/entry.S
@@ -111,6 +111,7 @@
 1:
 	tail do_trap_unknown
 SYM_CODE_END(handle_exception)
+ASM_NOKPROBE(handle_exception)
 
 /*
  * The ret_from_exception must be called with interrupt disabled. Here is the
@@ -184,6 +185,7 @@
 	sret
 #endif
 SYM_CODE_END(ret_from_exception)
+ASM_NOKPROBE(ret_from_exception)
 
 #ifdef CONFIG_VMAP_STACK
 SYM_CODE_START_LOCAL(handle_kernel_stack_overflow)
@@ -219,6 +221,7 @@
 	move a0, sp
 	tail handle_bad_stack
 SYM_CODE_END(handle_kernel_stack_overflow)
+ASM_NOKPROBE(handle_kernel_stack_overflow)
 #endif
 
 SYM_CODE_START(ret_from_fork)
@@ -229,8 +232,8 @@
 	jalr s0
 1:
 	move a0, sp /* pt_regs */
-	la ra, ret_from_exception
-	tail syscall_exit_to_user_mode
+	call syscall_exit_to_user_mode
+	j ret_from_exception
 SYM_CODE_END(ret_from_fork)
 
 #ifdef CONFIG_IRQ_STACKS
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/ftrace.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/ftrace.c
@@ -8,6 +8,7 @@
 #include <linux/ftrace.h>
 #include <linux/uaccess.h>
 #include <linux/memory.h>
+#include <linux/stop_machine.h>
 #include <asm/cacheflush.h>
 #include <asm/patch.h>
 
@@ -75,8 +76,7 @@
 		make_call_t0(hook_pos, target, call);
 
 	/* Replace the auipc-jalr pair at once. Return -EPERM on write error. */
-	if (patch_text_nosync
-	    ((void *)hook_pos, enable ? call : nops, MCOUNT_INSN_SIZE))
+	if (patch_insn_write((void *)hook_pos, enable ? call : nops, MCOUNT_INSN_SIZE))
 		return -EPERM;
 
 	return 0;
@@ -88,7 +88,7 @@
 
 	make_call_t0(rec->ip, addr, call);
 
-	if (patch_text_nosync((void *)rec->ip, call, MCOUNT_INSN_SIZE))
+	if (patch_insn_write((void *)rec->ip, call, MCOUNT_INSN_SIZE))
 		return -EPERM;
 
 	return 0;
@@ -99,7 +99,7 @@
 {
 	unsigned int nops[2] = {NOP4, NOP4};
 
-	if (patch_text_nosync((void *)rec->ip, nops, MCOUNT_INSN_SIZE))
+	if (patch_insn_write((void *)rec->ip, nops, MCOUNT_INSN_SIZE))
 		return -EPERM;
 
 	return 0;
@@ -120,6 +120,9 @@
 	out = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
 	mutex_unlock(&text_mutex);
 
+	if (!mod)
+		local_flush_icache_range(rec->ip, rec->ip + MCOUNT_INSN_SIZE);
+
 	return out;
 }
 
@@ -134,6 +137,42 @@
 
 	return ret;
 }
+
+struct ftrace_modify_param {
+	int command;
+	atomic_t cpu_count;
+};
+
+static int __ftrace_modify_code(void *data)
+{
+	struct ftrace_modify_param *param = data;
+
+	if (atomic_inc_return(&param->cpu_count) == num_online_cpus()) {
+		ftrace_modify_all_code(param->command);
+		/*
+		 * Make sure the patching store is effective *before* we
+		 * increment the counter which releases all waiting CPUs
+		 * by using the release variant of atomic increment. The
+		 * release pairs with the call to local_flush_icache_all()
+		 * on the waiting CPU.
+		 */
+		atomic_inc_return_release(&param->cpu_count);
+	} else {
+		while (atomic_read(&param->cpu_count) <= num_online_cpus())
+			cpu_relax();
+	}
+
+	local_flush_icache_all();
+
+	return 0;
+}
+
+void arch_ftrace_update_code(int command)
+{
+	struct ftrace_modify_param param = { command, ATOMIC_INIT(0) };
+
+	stop_machine(__ftrace_modify_code, &param, cpu_online_mask);
+}
 #endif
 
 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/head.S
+++ linux-qcom-6.8.0/arch/riscv/kernel/head.S
@@ -165,10 +165,21 @@
 #endif
 	call .Lsetup_trap_vector
 	scs_load_current
-	tail smp_callin
+	call smp_callin
 #endif /* CONFIG_SMP */
 
 .align 2
+.Lsecondary_park:
+	/*
+	 * Park this hart if we:
+	 *  - have too many harts on CONFIG_RISCV_BOOT_SPINWAIT
+	 *  - receive an early trap, before setup_trap_vector finished
+	 *  - fail in smp_callin(), as a successful one wouldn't return
+	 */
+	wfi
+	j .Lsecondary_park
+
+.align 2
 .Lsetup_trap_vector:
 	/* Set trap vector to exception handler */
 	la a0, handle_exception
@@ -181,12 +192,6 @@
 	csrw CSR_SCRATCH, zero
 	ret
 
-.align 2
-.Lsecondary_park:
-	/* We lack SMP support or have too many harts, so park this hart */
-	wfi
-	j .Lsecondary_park
-
 SYM_CODE_END(_start)
 
 SYM_CODE_START(_start_kernel)
@@ -300,6 +305,9 @@
 #else
 	mv a0, a1
 #endif /* CONFIG_BUILTIN_DTB */
+	/* Set trap vector to spin forever to help debug */
+	la a3, .Lsecondary_park
+	csrw CSR_TVEC, a3
 	call setup_vm
 #ifdef CONFIG_MMU
 	la a0, early_pg_dir
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/machine_kexec.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/machine_kexec.c
@@ -121,20 +121,12 @@
 
 	for_each_irq_desc(i, desc) {
 		struct irq_chip *chip;
-		int ret;
 
 		chip = irq_desc_get_chip(desc);
 		if (!chip)
 			continue;
 
-		/*
-		 * First try to remove the active state. If this
-		 * fails, try to EOI the interrupt.
-		 */
-		ret = irq_set_irqchip_state(i, IRQCHIP_STATE_ACTIVE, false);
-
-		if (ret && irqd_irq_inprogress(&desc->irq_data) &&
-		    chip->irq_eoi)
+		if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
 			chip->irq_eoi(&desc->irq_data);
 
 		if (chip->irq_mask)
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/module.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/module.c
@@ -24,7 +24,7 @@
 
 struct relocation_head {
 	struct hlist_node node;
-	struct list_head *rel_entry;
+	struct list_head rel_entry;
 	void *location;
 };
 
@@ -635,7 +635,7 @@
 			location = rel_head_iter->location;
 			list_for_each_entry_safe(rel_entry_iter,
 						 rel_entry_iter_tmp,
-						 rel_head_iter->rel_entry,
+						 &rel_head_iter->rel_entry,
 						 head) {
 				curr_type = rel_entry_iter->type;
 				reloc_handlers[curr_type].reloc_handler(
@@ -705,16 +705,7 @@
 			return -ENOMEM;
 		}
 
-		rel_head->rel_entry =
-			kmalloc(sizeof(struct list_head), GFP_KERNEL);
-
-		if (!rel_head->rel_entry) {
-			kfree(entry);
-			kfree(rel_head);
-			return -ENOMEM;
-		}
-
-		INIT_LIST_HEAD(rel_head->rel_entry);
+		INIT_LIST_HEAD(&rel_head->rel_entry);
 		rel_head->location = location;
 		INIT_HLIST_NODE(&rel_head->node);
 		if (!current_head->first) {
@@ -723,7 +714,6 @@
 
 			if (!bucket) {
 				kfree(entry);
-				kfree(rel_head->rel_entry);
 				kfree(rel_head);
 				return -ENOMEM;
 			}
@@ -736,7 +726,7 @@
 	}
 
 	/* Add relocation to head of discovered rel_head */
-	list_add_tail(&entry->head, rel_head->rel_entry);
+	list_add_tail(&entry->head, &rel_head->rel_entry);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/patch.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/patch.c
@@ -80,6 +80,8 @@
 	 */
 	lockdep_assert_held(&text_mutex);
 
+	preempt_disable();
+
 	if (across_pages)
 		patch_map(addr + PAGE_SIZE, FIX_TEXT_POKE1);
 
@@ -92,6 +94,8 @@
 	if (across_pages)
 		patch_unmap(FIX_TEXT_POKE1);
 
+	preempt_enable();
+
 	return 0;
 }
 NOKPROBE_SYMBOL(__patch_insn_set);
@@ -122,6 +126,8 @@
 	if (!riscv_patch_in_stop_machine)
 		lockdep_assert_held(&text_mutex);
 
+	preempt_disable();
+
 	if (across_pages)
 		patch_map(addr + PAGE_SIZE, FIX_TEXT_POKE1);
 
@@ -134,6 +140,8 @@
 	if (across_pages)
 		patch_unmap(FIX_TEXT_POKE1);
 
+	preempt_enable();
+
 	return ret;
 }
 NOKPROBE_SYMBOL(__patch_insn_write);
@@ -188,7 +196,7 @@
 }
 NOKPROBE_SYMBOL(patch_text_set_nosync);
 
-static int patch_insn_write(void *addr, const void *insn, size_t len)
+int patch_insn_write(void *addr, const void *insn, size_t len)
 {
 	size_t patched = 0;
 	size_t size;
@@ -232,16 +240,24 @@
 	if (atomic_inc_return(&patch->cpu_count) == num_online_cpus()) {
 		for (i = 0; ret == 0 && i < patch->ninsns; i++) {
 			len = GET_INSN_LENGTH(patch->insns[i]);
-			ret = patch_text_nosync(patch->addr + i * len,
-						&patch->insns[i], len);
+			ret = patch_insn_write(patch->addr + i * len, &patch->insns[i], len);
 		}
-		atomic_inc(&patch->cpu_count);
+		/*
+		 * Make sure the patching store is effective *before* we
+		 * increment the counter which releases all waiting CPUs
+		 * by using the release variant of atomic increment. The
+		 * release pairs with the call to local_flush_icache_all()
+		 * on the waiting CPU.
+		 */
+		atomic_inc_return_release(&patch->cpu_count);
 	} else {
 		while (atomic_read(&patch->cpu_count) <= num_online_cpus())
 			cpu_relax();
 		smp_mb();
 	}
 
+	local_flush_icache_all();
+
 	return ret;
 }
 NOKPROBE_SYMBOL(patch_text_cb);
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/perf_callchain.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/perf_callchain.c
@@ -62,7 +62,7 @@
 	perf_callchain_store(entry, regs->epc);
 
 	fp = user_backtrace(entry, fp, regs->ra);
-	while (fp && !(fp & 0x3) && entry->nr < entry->max_stack)
+	while (fp && !(fp & 0x7) && entry->nr < entry->max_stack)
 		fp = user_backtrace(entry, fp, 0);
 }
 
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/probes/ftrace.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/probes/ftrace.c
@@ -11,6 +11,9 @@
 	struct kprobe_ctlblk *kcb;
 	int bit;
 
+	if (unlikely(kprobe_ftrace_disabled))
+		return;
+
 	bit = ftrace_test_recursion_trylock(ip, parent_ip);
 	if (bit < 0)
 		return;
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/probes/kprobes.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/probes/kprobes.c
@@ -28,9 +28,8 @@
 
 	p->ainsn.api.restore = (unsigned long)p->addr + offset;
 
-	patch_text(p->ainsn.api.insn, &p->opcode, 1);
-	patch_text((void *)((unsigned long)(p->ainsn.api.insn) + offset),
-		   &insn, 1);
+	patch_text_nosync(p->ainsn.api.insn, &p->opcode, 1);
+	patch_text_nosync((void *)p->ainsn.api.insn + offset, &insn, 1);
 }
 
 static void __kprobes arch_prepare_simulate(struct kprobe *p)
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/process.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/process.c
@@ -27,8 +27,6 @@
 #include <asm/vector.h>
 #include <asm/cpufeature.h>
 
-register unsigned long gp_in_global __asm__("gp");
-
 #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK)
 #include <linux/stackprotector.h>
 unsigned long __stack_chk_guard __read_mostly;
@@ -37,7 +35,7 @@
 
 extern asmlinkage void ret_from_fork(void);
 
-void arch_cpu_idle(void)
+void noinstr arch_cpu_idle(void)
 {
 	cpu_do_idle();
 }
@@ -207,7 +205,6 @@
 	if (unlikely(args->fn)) {
 		/* Kernel thread */
 		memset(childregs, 0, sizeof(struct pt_regs));
-		childregs->gp = gp_in_global;
 		/* Supervisor/Machine, irqs on: */
 		childregs->status = SR_PP | SR_PIE;
 
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/riscv_ksyms.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/riscv_ksyms.c
@@ -12,9 +12,6 @@
 EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(memmove);
-EXPORT_SYMBOL(strcmp);
-EXPORT_SYMBOL(strlen);
-EXPORT_SYMBOL(strncmp);
 EXPORT_SYMBOL(__memset);
 EXPORT_SYMBOL(__memcpy);
 EXPORT_SYMBOL(__memmove);
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/sbi-ipi.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/sbi-ipi.c
@@ -68,7 +68,7 @@
 	 * the masking/unmasking of virtual IPIs is done
 	 * via generic IPI-Mux
 	 */
-	cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
+	cpuhp_setup_state(CPUHP_AP_IRQ_RISCV_SBI_IPI_STARTING,
 			  "irqchip/sbi-ipi:starting",
 			  sbi_ipi_starting_cpu, NULL);
 
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/sbi.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/sbi.c
@@ -24,51 +24,6 @@
 			   unsigned long start, unsigned long size,
 			   unsigned long arg4, unsigned long arg5) __ro_after_init;
 
-struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
-			unsigned long arg1, unsigned long arg2,
-			unsigned long arg3, unsigned long arg4,
-			unsigned long arg5)
-{
-	struct sbiret ret;
-
-	register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0);
-	register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1);
-	register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2);
-	register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3);
-	register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4);
-	register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5);
-	register uintptr_t a6 asm ("a6") = (uintptr_t)(fid);
-	register uintptr_t a7 asm ("a7") = (uintptr_t)(ext);
-	asm volatile ("ecall"
-		      : "+r" (a0), "+r" (a1)
-		      : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
-		      : "memory");
-	ret.error = a0;
-	ret.value = a1;
-
-	return ret;
-}
-EXPORT_SYMBOL(sbi_ecall);
-
-int sbi_err_map_linux_errno(int err)
-{
-	switch (err) {
-	case SBI_SUCCESS:
-		return 0;
-	case SBI_ERR_DENIED:
-		return -EPERM;
-	case SBI_ERR_INVALID_PARAM:
-		return -EINVAL;
-	case SBI_ERR_INVALID_ADDRESS:
-		return -EFAULT;
-	case SBI_ERR_NOT_SUPPORTED:
-	case SBI_ERR_FAILURE:
-	default:
-		return -ENOTSUPP;
-	};
-}
-EXPORT_SYMBOL(sbi_err_map_linux_errno);
-
 #ifdef CONFIG_RISCV_SBI_V01
 static unsigned long __sbi_v01_cpumask_to_hartmask(const struct cpumask *cpu_mask)
 {
@@ -528,17 +483,6 @@
 }
 EXPORT_SYMBOL(sbi_probe_extension);
 
-static long __sbi_base_ecall(int fid)
-{
-	struct sbiret ret;
-
-	ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0);
-	if (!ret.error)
-		return ret.value;
-	else
-		return sbi_err_map_linux_errno(ret.error);
-}
-
 static inline long sbi_get_spec_version(void)
 {
 	return __sbi_base_ecall(SBI_EXT_BASE_GET_SPEC_VERSION);
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/sbi_ecall.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/sbi_ecall.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2024 Rivos Inc. */
+
+#include <asm/sbi.h>
+#define CREATE_TRACE_POINTS
+#include <asm/trace.h>
+
+long __sbi_base_ecall(int fid)
+{
+	struct sbiret ret;
+
+	ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0);
+	if (!ret.error)
+		return ret.value;
+	else
+		return sbi_err_map_linux_errno(ret.error);
+}
+EXPORT_SYMBOL(__sbi_base_ecall);
+
+struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1,
+			  unsigned long arg2, unsigned long arg3,
+			  unsigned long arg4, unsigned long arg5,
+			  int fid, int ext)
+{
+	struct sbiret ret;
+
+	trace_sbi_call(ext, fid);
+
+	register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0);
+	register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1);
+	register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2);
+	register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3);
+	register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4);
+	register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5);
+	register uintptr_t a6 asm ("a6") = (uintptr_t)(fid);
+	register uintptr_t a7 asm ("a7") = (uintptr_t)(ext);
+	asm volatile ("ecall"
+		       : "+r" (a0), "+r" (a1)
+		       : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
+		       : "memory");
+	ret.error = a0;
+	ret.value = a1;
+
+	trace_sbi_return(ext, ret.error, ret.value);
+
+	return ret;
+}
+EXPORT_SYMBOL(__sbi_ecall);
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/setup.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/setup.c
@@ -227,7 +227,7 @@
 static void __init parse_dtb(void)
 {
 	/* Early scan of device tree from init memory */
-	if (early_init_dt_scan(dtb_early_va)) {
+	if (early_init_dt_scan(dtb_early_va, dtb_early_pa)) {
 		const char *name = of_flat_dt_get_machine_name();
 
 		if (name) {
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/signal.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/signal.c
@@ -119,6 +119,13 @@
 	struct __sc_riscv_v_state __user *state = sc_vec;
 	void __user *datap;
 
+	/*
+	 * Mark the vstate as clean prior performing the actual copy,
+	 * to avoid getting the vstate incorrectly clobbered by the
+	 *  discarded vector state.
+	 */
+	riscv_v_vstate_set_restore(current, regs);
+
 	/* Copy everything of __sc_riscv_v_state except datap. */
 	err = __copy_from_user(&current->thread.vstate, &state->v_state,
 			       offsetof(struct __riscv_v_ext_state, datap));
@@ -133,13 +140,7 @@
 	 * Copy the whole vector content from user space datap. Use
 	 * copy_from_user to prevent information leak.
 	 */
-	err = copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize);
-	if (unlikely(err))
-		return err;
-
-	riscv_v_vstate_set_restore(current, regs);
-
-	return err;
+	return copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize);
 }
 #else
 #define save_v_state(task, regs) (0)
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/smpboot.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/smpboot.c
@@ -26,7 +26,7 @@
 #include <linux/sched/task_stack.h>
 #include <linux/sched/mm.h>
 
-#include <asm/cpufeature.h>
+#include <asm/cacheflush.h>
 #include <asm/cpu_ops.h>
 #include <asm/cpufeature.h>
 #include <asm/irq.h>
@@ -219,6 +219,15 @@
 	struct mm_struct *mm = &init_mm;
 	unsigned int curr_cpuid = smp_processor_id();
 
+	if (has_vector()) {
+		/*
+		 * Return as early as possible so the hart with a mismatching
+		 * vlen won't boot.
+		 */
+		if (riscv_v_setup_vsize())
+			return;
+	}
+
 	/* All kernel threads share the same mm context.  */
 	mmgrab(mm);
 	current->active_mm = mm;
@@ -231,17 +240,13 @@
 	numa_add_cpu(curr_cpuid);
 	set_cpu_online(curr_cpuid, 1);
 
-	if (has_vector()) {
-		if (riscv_v_setup_vsize())
-			elf_hwcap &= ~COMPAT_HWCAP_ISA_V;
-	}
-
 	riscv_user_isa_enable();
 
 	/*
-	 * Remote TLB flushes are ignored while the CPU is offline, so emit
-	 * a local TLB flush right now just in case.
+	 * Remote cache and TLB flushes are ignored while the CPU is offline,
+	 * so flush them both right now just in case.
 	 */
+	local_flush_icache_all();
 	local_flush_tlb_all();
 	complete(&cpu_running);
 	/*
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/stacktrace.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/stacktrace.c
@@ -18,10 +18,21 @@
 
 extern asmlinkage void ret_from_exception(void);
 
+static inline int fp_is_valid(unsigned long fp, unsigned long sp)
+{
+	unsigned long low, high;
+
+	low = sp + sizeof(struct stackframe);
+	high = ALIGN(sp, THREAD_SIZE);
+
+	return !(fp < low || fp > high || fp & 0x07);
+}
+
 void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
 			     bool (*fn)(void *, unsigned long), void *arg)
 {
 	unsigned long fp, sp, pc;
+	int graph_idx = 0;
 	int level = 0;
 
 	if (regs) {
@@ -41,26 +52,24 @@
 	}
 
 	for (;;) {
-		unsigned long low, high;
 		struct stackframe *frame;
 
 		if (unlikely(!__kernel_text_address(pc) || (level++ >= 0 && !fn(arg, pc))))
 			break;
 
-		/* Validate frame pointer */
-		low = sp + sizeof(struct stackframe);
-		high = ALIGN(sp, THREAD_SIZE);
-		if (unlikely(fp < low || fp > high || fp & 0x7))
+		if (unlikely(!fp_is_valid(fp, sp)))
 			break;
+
 		/* Unwind stack frame */
 		frame = (struct stackframe *)fp - 1;
 		sp = fp;
-		if (regs && (regs->epc == pc) && (frame->fp & 0x7)) {
+		if (regs && (regs->epc == pc) && fp_is_valid(frame->ra, sp)) {
+			/* We hit function where ra is not saved on the stack */
 			fp = frame->ra;
 			pc = regs->ra;
 		} else {
 			fp = frame->fp;
-			pc = ftrace_graph_ret_addr(current, NULL, frame->ra,
+			pc = ftrace_graph_ret_addr(current, &graph_idx, frame->ra,
 						   &frame->ra);
 			if (pc == (unsigned long)ret_from_exception) {
 				if (unlikely(!__kernel_text_address(pc) || !fn(arg, pc)))
@@ -148,7 +157,7 @@
 	return pc;
 }
 
-noinline void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
+noinline noinstr void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
 		     struct task_struct *task, struct pt_regs *regs)
 {
 	walk_stackframe(task, regs, consume_entry, cookie);
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/traps.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/traps.c
@@ -34,7 +34,7 @@
 
 int show_unhandled_signals = 1;
 
-static DEFINE_SPINLOCK(die_lock);
+static DEFINE_RAW_SPINLOCK(die_lock);
 
 static int copy_code(struct pt_regs *regs, u16 *val, const u16 *insns)
 {
@@ -80,7 +80,7 @@
 
 	oops_enter();
 
-	spin_lock_irqsave(&die_lock, flags);
+	raw_spin_lock_irqsave(&die_lock, flags);
 	console_verbose();
 	bust_spinlocks(1);
 
@@ -99,7 +99,7 @@
 
 	bust_spinlocks(0);
 	add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
-	spin_unlock_irqrestore(&die_lock, flags);
+	raw_spin_unlock_irqrestore(&die_lock, flags);
 	oops_exit();
 
 	if (in_interrupt())
@@ -121,7 +121,7 @@
 		print_vma_addr(KERN_CONT " in ", instruction_pointer(regs));
 		pr_cont("\n");
 		__show_regs(regs);
-		dump_instr(KERN_EMERG, regs);
+		dump_instr(KERN_INFO, regs);
 	}
 
 	force_sig_fault(signo, code, (void __user *)addr);
@@ -317,6 +317,7 @@
 
 		regs->epc += 4;
 		regs->orig_a0 = regs->a0;
+		regs->a0 = -ENOSYS;
 
 		riscv_v_vstate_discard(regs);
 
@@ -324,8 +325,6 @@
 
 		if (syscall >= 0 && syscall < NR_syscalls)
 			syscall_handler(regs, syscall);
-		else if (syscall != -1)
-			regs->a0 = -ENOSYS;
 
 		syscall_exit_to_user_mode(regs);
 	} else {
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/traps_misaligned.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/traps_misaligned.c
@@ -136,8 +136,6 @@
 #define REG_PTR(insn, pos, regs)	\
 	(ulong *)((ulong)(regs) + REG_OFFSET(insn, pos))
 
-#define GET_RM(insn)			(((insn) >> 12) & 7)
-
 #define GET_RS1(insn, regs)		(*REG_PTR(insn, SH_RS1, regs))
 #define GET_RS2(insn, regs)		(*REG_PTR(insn, SH_RS2, regs))
 #define GET_RS1S(insn, regs)		(*REG_PTR(RVC_RS1S(insn), 0, regs))
@@ -264,86 +262,14 @@
 #define GET_F32_RS2C(insn, regs) (get_f32_rs(insn, 2, regs))
 #define GET_F32_RS2S(insn, regs) (get_f32_rs(RVC_RS2S(insn), 0, regs))
 
-#ifdef CONFIG_RISCV_M_MODE
-static inline int load_u8(struct pt_regs *regs, const u8 *addr, u8 *r_val)
-{
-	u8 val;
-
-	asm volatile("lbu %0, %1" : "=&r" (val) : "m" (*addr));
-	*r_val = val;
-
-	return 0;
-}
-
-static inline int store_u8(struct pt_regs *regs, u8 *addr, u8 val)
-{
-	asm volatile ("sb %0, %1\n" : : "r" (val), "m" (*addr));
-
-	return 0;
-}
-
-static inline int get_insn(struct pt_regs *regs, ulong mepc, ulong *r_insn)
-{
-	register ulong __mepc asm ("a2") = mepc;
-	ulong val, rvc_mask = 3, tmp;
-
-	asm ("and %[tmp], %[addr], 2\n"
-		"bnez %[tmp], 1f\n"
-#if defined(CONFIG_64BIT)
-		__stringify(LWU) " %[insn], (%[addr])\n"
-#else
-		__stringify(LW) " %[insn], (%[addr])\n"
-#endif
-		"and %[tmp], %[insn], %[rvc_mask]\n"
-		"beq %[tmp], %[rvc_mask], 2f\n"
-		"sll %[insn], %[insn], %[xlen_minus_16]\n"
-		"srl %[insn], %[insn], %[xlen_minus_16]\n"
-		"j 2f\n"
-		"1:\n"
-		"lhu %[insn], (%[addr])\n"
-		"and %[tmp], %[insn], %[rvc_mask]\n"
-		"bne %[tmp], %[rvc_mask], 2f\n"
-		"lhu %[tmp], 2(%[addr])\n"
-		"sll %[tmp], %[tmp], 16\n"
-		"add %[insn], %[insn], %[tmp]\n"
-		"2:"
-	: [insn] "=&r" (val), [tmp] "=&r" (tmp)
-	: [addr] "r" (__mepc), [rvc_mask] "r" (rvc_mask),
-	  [xlen_minus_16] "i" (XLEN_MINUS_16));
-
-	*r_insn = val;
-
-	return 0;
-}
-#else
-static inline int load_u8(struct pt_regs *regs, const u8 *addr, u8 *r_val)
-{
-	if (user_mode(regs)) {
-		return __get_user(*r_val, (u8 __user *)addr);
-	} else {
-		*r_val = *addr;
-		return 0;
-	}
-}
-
-static inline int store_u8(struct pt_regs *regs, u8 *addr, u8 val)
-{
-	if (user_mode(regs)) {
-		return __put_user(val, (u8 __user *)addr);
-	} else {
-		*addr = val;
-		return 0;
-	}
-}
-
-#define __read_insn(regs, insn, insn_addr)		\
+#define __read_insn(regs, insn, insn_addr, type)	\
 ({							\
 	int __ret;					\
 							\
 	if (user_mode(regs)) {				\
-		__ret = __get_user(insn, insn_addr);	\
+		__ret = __get_user(insn, (type __user *) insn_addr); \
 	} else {					\
-		insn = *(__force u16 *)insn_addr;	\
+		insn = *(type *)insn_addr;		\
 		__ret = 0;				\
 	}						\
 							\
@@ -356,9 +282,8 @@
 
 	if (epc & 0x2) {
 		ulong tmp = 0;
-		u16 __user *insn_addr = (u16 __user *)epc;
 
-		if (__read_insn(regs, insn, insn_addr))
+		if (__read_insn(regs, insn, epc, u16))
 			return -EFAULT;
 		/* __get_user() uses regular "lw" which sign extend the loaded
 		 * value make sure to clear higher order bits in case we "or" it
@@ -369,16 +294,14 @@
 			*r_insn = insn;
 			return 0;
 		}
-		insn_addr++;
-		if (__read_insn(regs, tmp, insn_addr))
+		epc += sizeof(u16);
+		if (__read_insn(regs, tmp, epc, u16))
 			return -EFAULT;
 		*r_insn = (tmp << 16) | insn;
 
 		return 0;
 	} else {
-		u32 __user *insn_addr = (u32 __user *)epc;
-
-		if (__read_insn(regs, insn, insn_addr))
+		if (__read_insn(regs, insn, epc, u32))
 			return -EFAULT;
 		if ((insn & __INSN_LENGTH_MASK) == __INSN_LENGTH_32) {
 			*r_insn = insn;
@@ -390,7 +313,6 @@
 		return 0;
 	}
 }
-#endif
 
 union reg_data {
 	u8 data_bytes[8];
@@ -409,7 +331,7 @@
 	unsigned long epc = regs->epc;
 	unsigned long insn;
 	unsigned long addr = regs->badaddr;
-	int i, fp = 0, shift = 0, len = 0;
+	int fp = 0, shift = 0, len = 0;
 
 	perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, addr);
 
@@ -490,9 +412,11 @@
 		return -EOPNOTSUPP;
 
 	val.data_u64 = 0;
-	for (i = 0; i < len; i++) {
-		if (load_u8(regs, (void *)(addr + i), &val.data_bytes[i]))
+	if (user_mode(regs)) {
+		if (copy_from_user(&val, (u8 __user *)addr, len))
 			return -1;
+	} else {
+		memcpy(&val, (u8 *)addr, len);
 	}
 
 	if (!fp)
@@ -513,7 +437,7 @@
 	unsigned long epc = regs->epc;
 	unsigned long insn;
 	unsigned long addr = regs->badaddr;
-	int i, len = 0, fp = 0;
+	int len = 0, fp = 0;
 
 	perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, addr);
 
@@ -586,9 +510,11 @@
 	if (!IS_ENABLED(CONFIG_FPU) && fp)
 		return -EOPNOTSUPP;
 
-	for (i = 0; i < len; i++) {
-		if (store_u8(regs, (void *)(addr + i), val.data_bytes[i]))
+	if (user_mode(regs)) {
+		if (copy_to_user((u8 __user *)addr, &val, len))
 			return -1;
+	} else {
+		memcpy((u8 *)addr, &val, len);
 	}
 
 	regs->epc = epc + INSN_LEN(insn);
@@ -632,7 +558,7 @@
 	 * accesses emulated since tasks requesting such control can run on any
 	 * CPU.
 	 */
-	for_each_present_cpu(cpu) {
+	for_each_online_cpu(cpu) {
 		if (per_cpu(misaligned_access_speed, cpu) !=
 					RISCV_HWPROBE_MISALIGNED_EMULATED) {
 			return;
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/vdso/Makefile
+++ linux-qcom-6.8.0/arch/riscv/kernel/vdso/Makefile
@@ -18,6 +18,7 @@
 
 ccflags-y := -fno-stack-protector
 ccflags-y += -DDISABLE_BRANCH_PROFILING
+ccflags-y += -fno-builtin
 
 ifneq ($(c-gettimeofday-y),)
   CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y)
@@ -37,6 +38,7 @@
 
 # Disable -pg to prevent insert call site
 CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS)
+CFLAGS_REMOVE_hwprobe.o = $(CC_FLAGS_FTRACE) $(CC_FLAGS_SCS)
 
 # Disable profiling and instrumentation for VDSO code
 GCOV_PROFILE := n
--- linux-qcom-6.8.0.orig/arch/riscv/kernel/vector.c
+++ linux-qcom-6.8.0/arch/riscv/kernel/vector.c
@@ -306,7 +306,7 @@
 static int __init riscv_v_sysctl_init(void) { return 0; }
 #endif /* ! CONFIG_SYSCTL */
 
-static int riscv_v_init(void)
+static int __init riscv_v_init(void)
 {
 	return riscv_v_sysctl_init();
 }
--- linux-qcom-6.8.0.orig/arch/riscv/kvm/aia_aplic.c
+++ linux-qcom-6.8.0/arch/riscv/kvm/aia_aplic.c
@@ -137,11 +137,22 @@
 	raw_spin_lock_irqsave(&irqd->lock, flags);
 
 	sm = irqd->sourcecfg & APLIC_SOURCECFG_SM_MASK;
-	if (!pending &&
-	    ((sm == APLIC_SOURCECFG_SM_LEVEL_HIGH) ||
-	     (sm == APLIC_SOURCECFG_SM_LEVEL_LOW)))
+	if (sm == APLIC_SOURCECFG_SM_INACTIVE)
 		goto skip_write_pending;
 
+	if (sm == APLIC_SOURCECFG_SM_LEVEL_HIGH ||
+	    sm == APLIC_SOURCECFG_SM_LEVEL_LOW) {
+		if (!pending)
+			goto noskip_write_pending;
+		if ((irqd->state & APLIC_IRQ_STATE_INPUT) &&
+		    sm == APLIC_SOURCECFG_SM_LEVEL_LOW)
+			goto skip_write_pending;
+		if (!(irqd->state & APLIC_IRQ_STATE_INPUT) &&
+		    sm == APLIC_SOURCECFG_SM_LEVEL_HIGH)
+			goto skip_write_pending;
+	}
+
+noskip_write_pending:
 	if (pending)
 		irqd->state |= APLIC_IRQ_STATE_PENDING;
 	else
@@ -187,16 +198,31 @@
 
 static bool aplic_read_input(struct aplic *aplic, u32 irq)
 {
-	bool ret;
-	unsigned long flags;
+	u32 sourcecfg, sm, raw_input, irq_inverted;
 	struct aplic_irq *irqd;
+	unsigned long flags;
+	bool ret = false;
 
 	if (!irq || aplic->nr_irqs <= irq)
 		return false;
 	irqd = &aplic->irqs[irq];
 
 	raw_spin_lock_irqsave(&irqd->lock, flags);
-	ret = (irqd->state & APLIC_IRQ_STATE_INPUT) ? true : false;
+
+	sourcecfg = irqd->sourcecfg;
+	if (sourcecfg & APLIC_SOURCECFG_D)
+		goto skip;
+
+	sm = sourcecfg & APLIC_SOURCECFG_SM_MASK;
+	if (sm == APLIC_SOURCECFG_SM_INACTIVE)
+		goto skip;
+
+	raw_input = (irqd->state & APLIC_IRQ_STATE_INPUT) ? 1 : 0;
+	irq_inverted = (sm == APLIC_SOURCECFG_SM_LEVEL_LOW ||
+			sm == APLIC_SOURCECFG_SM_EDGE_FALL) ? 1 : 0;
+	ret = !!(raw_input ^ irq_inverted);
+
+skip:
 	raw_spin_unlock_irqrestore(&irqd->lock, flags);
 
 	return ret;
--- linux-qcom-6.8.0.orig/arch/riscv/kvm/aia_device.c
+++ linux-qcom-6.8.0/arch/riscv/kvm/aia_device.c
@@ -237,10 +237,11 @@
 
 static u32 aia_imsic_hart_index(struct kvm_aia *aia, gpa_t addr)
 {
-	u32 hart, group = 0;
+	u32 hart = 0, group = 0;
 
-	hart = (addr >> (aia->nr_guest_bits + IMSIC_MMIO_PAGE_SHIFT)) &
-		GENMASK_ULL(aia->nr_hart_bits - 1, 0);
+	if (aia->nr_hart_bits)
+		hart = (addr >> (aia->nr_guest_bits + IMSIC_MMIO_PAGE_SHIFT)) &
+		       GENMASK_ULL(aia->nr_hart_bits - 1, 0);
 	if (aia->nr_group_bits)
 		group = (addr >> aia->nr_group_shift) &
 			GENMASK_ULL(aia->nr_group_bits - 1, 0);
--- linux-qcom-6.8.0.orig/arch/riscv/kvm/aia_imsic.c
+++ linux-qcom-6.8.0/arch/riscv/kvm/aia_imsic.c
@@ -55,7 +55,7 @@
 	/* IMSIC SW-file */
 	struct imsic_mrif *swfile;
 	phys_addr_t swfile_pa;
-	spinlock_t swfile_extirq_lock;
+	raw_spinlock_t swfile_extirq_lock;
 };
 
 #define imsic_vs_csr_read(__c)			\
@@ -622,7 +622,7 @@
 	 * interruptions between reading topei and updating pending status.
 	 */
 
-	spin_lock_irqsave(&imsic->swfile_extirq_lock, flags);
+	raw_spin_lock_irqsave(&imsic->swfile_extirq_lock, flags);
 
 	if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) &&
 	    imsic_mrif_topei(mrif, imsic->nr_eix, imsic->nr_msis))
@@ -630,7 +630,7 @@
 	else
 		kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT);
 
-	spin_unlock_irqrestore(&imsic->swfile_extirq_lock, flags);
+	raw_spin_unlock_irqrestore(&imsic->swfile_extirq_lock, flags);
 }
 
 static void imsic_swfile_read(struct kvm_vcpu *vcpu, bool clear,
@@ -1051,7 +1051,7 @@
 	}
 	imsic->swfile = page_to_virt(swfile_page);
 	imsic->swfile_pa = page_to_phys(swfile_page);
-	spin_lock_init(&imsic->swfile_extirq_lock);
+	raw_spin_lock_init(&imsic->swfile_extirq_lock);
 
 	/* Setup IO device */
 	kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops);
--- linux-qcom-6.8.0.orig/arch/riscv/kvm/vcpu_insn.c
+++ linux-qcom-6.8.0/arch/riscv/kvm/vcpu_insn.c
@@ -7,6 +7,8 @@
 #include <linux/bitops.h>
 #include <linux/kvm_host.h>
 
+#include <asm/cpufeature.h>
+
 #define INSN_OPCODE_MASK	0x007c
 #define INSN_OPCODE_SHIFT	2
 #define INSN_OPCODE_SYSTEM	28
@@ -213,9 +215,20 @@
 		    unsigned long wr_mask);
 };
 
+static int seed_csr_rmw(struct kvm_vcpu *vcpu, unsigned int csr_num,
+			unsigned long *val, unsigned long new_val,
+			unsigned long wr_mask)
+{
+	if (!riscv_isa_extension_available(vcpu->arch.isa, ZKR))
+		return KVM_INSN_ILLEGAL_TRAP;
+
+	return KVM_INSN_EXIT_TO_USER_SPACE;
+}
+
 static const struct csr_func csr_funcs[] = {
 	KVM_RISCV_VCPU_AIA_CSR_FUNCS
 	KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS
+	{ .base = CSR_SEED, .count = 1, .func = seed_csr_rmw },
 };
 
 /**
--- linux-qcom-6.8.0.orig/arch/riscv/kvm/vcpu_onereg.c
+++ linux-qcom-6.8.0/arch/riscv/kvm/vcpu_onereg.c
@@ -714,9 +714,9 @@
 	switch (reg_subtype) {
 	case KVM_REG_RISCV_ISA_SINGLE:
 		return riscv_vcpu_set_isa_ext_single(vcpu, reg_num, reg_val);
-	case KVM_REG_RISCV_SBI_MULTI_EN:
+	case KVM_REG_RISCV_ISA_MULTI_EN:
 		return riscv_vcpu_set_isa_ext_multi(vcpu, reg_num, reg_val, true);
-	case KVM_REG_RISCV_SBI_MULTI_DIS:
+	case KVM_REG_RISCV_ISA_MULTI_DIS:
 		return riscv_vcpu_set_isa_ext_multi(vcpu, reg_num, reg_val, false);
 	default:
 		return -ENOENT;
--- linux-qcom-6.8.0.orig/arch/riscv/kvm/vcpu_pmu.c
+++ linux-qcom-6.8.0/arch/riscv/kvm/vcpu_pmu.c
@@ -39,7 +39,7 @@
 	u64 sample_period;
 
 	if (!pmc->counter_val)
-		sample_period = counter_val_mask + 1;
+		sample_period = counter_val_mask;
 	else
 		sample_period = (-pmc->counter_val) & counter_val_mask;
 
--- linux-qcom-6.8.0.orig/arch/riscv/kvm/vcpu_sbi.c
+++ linux-qcom-6.8.0/arch/riscv/kvm/vcpu_sbi.c
@@ -127,8 +127,8 @@
 	run->riscv_sbi.args[3] = cp->a3;
 	run->riscv_sbi.args[4] = cp->a4;
 	run->riscv_sbi.args[5] = cp->a5;
-	run->riscv_sbi.ret[0] = cp->a0;
-	run->riscv_sbi.ret[1] = cp->a1;
+	run->riscv_sbi.ret[0] = SBI_ERR_NOT_SUPPORTED;
+	run->riscv_sbi.ret[1] = 0;
 }
 
 void kvm_riscv_vcpu_sbi_system_reset(struct kvm_vcpu *vcpu,
@@ -483,19 +483,22 @@
 	struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context;
 	const struct kvm_riscv_sbi_extension_entry *entry;
 	const struct kvm_vcpu_sbi_extension *ext;
-	int i;
+	int idx, i;
 
 	for (i = 0; i < ARRAY_SIZE(sbi_ext); i++) {
 		entry = &sbi_ext[i];
 		ext = entry->ext_ptr;
+		idx = entry->ext_idx;
+
+		if (idx < 0 || idx >= ARRAY_SIZE(scontext->ext_status))
+			continue;
 
 		if (ext->probe && !ext->probe(vcpu)) {
-			scontext->ext_status[entry->ext_idx] =
-				KVM_RISCV_SBI_EXT_STATUS_UNAVAILABLE;
+			scontext->ext_status[idx] = KVM_RISCV_SBI_EXT_STATUS_UNAVAILABLE;
 			continue;
 		}
 
-		scontext->ext_status[entry->ext_idx] = ext->default_disabled ?
+		scontext->ext_status[idx] = ext->default_disabled ?
 					KVM_RISCV_SBI_EXT_STATUS_DISABLED :
 					KVM_RISCV_SBI_EXT_STATUS_ENABLED;
 	}
--- linux-qcom-6.8.0.orig/arch/riscv/lib/Makefile
+++ linux-qcom-6.8.0/arch/riscv/lib/Makefile
@@ -3,9 +3,11 @@
 lib-y			+= memcpy.o
 lib-y			+= memset.o
 lib-y			+= memmove.o
+ifeq ($(CONFIG_KASAN_GENERIC)$(CONFIG_KASAN_SW_TAGS),)
 lib-y			+= strcmp.o
 lib-y			+= strlen.o
 lib-y			+= strncmp.o
+endif
 lib-y			+= csum.o
 ifeq ($(CONFIG_MMU), y)
 lib-$(CONFIG_RISCV_ISA_V)	+= uaccess_vector.o
--- linux-qcom-6.8.0.orig/arch/riscv/lib/strcmp.S
+++ linux-qcom-6.8.0/arch/riscv/lib/strcmp.S
@@ -120,3 +120,4 @@
 .option pop
 #endif
 SYM_FUNC_END(strcmp)
+EXPORT_SYMBOL(strcmp)
--- linux-qcom-6.8.0.orig/arch/riscv/lib/strlen.S
+++ linux-qcom-6.8.0/arch/riscv/lib/strlen.S
@@ -131,3 +131,4 @@
 #endif
 SYM_FUNC_END(strlen)
 SYM_FUNC_ALIAS(__pi_strlen, strlen)
+EXPORT_SYMBOL(strlen)
--- linux-qcom-6.8.0.orig/arch/riscv/lib/strncmp.S
+++ linux-qcom-6.8.0/arch/riscv/lib/strncmp.S
@@ -136,3 +136,4 @@
 .option pop
 #endif
 SYM_FUNC_END(strncmp)
+EXPORT_SYMBOL(strncmp)
--- linux-qcom-6.8.0.orig/arch/riscv/mm/context.c
+++ linux-qcom-6.8.0/arch/riscv/mm/context.c
@@ -323,6 +323,8 @@
 	if (unlikely(prev == next))
 		return;
 
+	membarrier_arch_switch_mm(prev, next, task);
+
 	/*
 	 * Mark the current MM context as inactive, and the next as
 	 * active.  This is at least used by the icache flushing
--- linux-qcom-6.8.0.orig/arch/riscv/mm/fault.c
+++ linux-qcom-6.8.0/arch/riscv/mm/fault.c
@@ -61,26 +61,27 @@
 
 static inline void mm_fault_error(struct pt_regs *regs, unsigned long addr, vm_fault_t fault)
 {
+	if (!user_mode(regs)) {
+		no_context(regs, addr);
+		return;
+	}
+
 	if (fault & VM_FAULT_OOM) {
 		/*
 		 * We ran out of memory, call the OOM killer, and return the userspace
 		 * (which will retry the fault, or kill us if we got oom-killed).
 		 */
-		if (!user_mode(regs)) {
-			no_context(regs, addr);
-			return;
-		}
 		pagefault_out_of_memory();
 		return;
 	} else if (fault & (VM_FAULT_SIGBUS | VM_FAULT_HWPOISON | VM_FAULT_HWPOISON_LARGE)) {
 		/* Kernel mode? Handle exceptions or die */
-		if (!user_mode(regs)) {
-			no_context(regs, addr);
-			return;
-		}
 		do_trap(regs, SIGBUS, BUS_ADRERR, addr);
 		return;
+	} else if (fault & VM_FAULT_SIGSEGV) {
+		do_trap(regs, SIGSEGV, SEGV_MAPERR, addr);
+		return;
 	}
+
 	BUG();
 }
 
--- linux-qcom-6.8.0.orig/arch/riscv/mm/init.c
+++ linux-qcom-6.8.0/arch/riscv/mm/init.c
@@ -32,6 +32,7 @@
 #include <asm/ptdump.h>
 #include <asm/sections.h>
 #include <asm/soc.h>
+#include <asm/sparsemem.h>
 #include <asm/tlbflush.h>
 
 #include "../kernel/head.h"
@@ -59,6 +60,13 @@
 phys_addr_t phys_ram_base __ro_after_init;
 EXPORT_SYMBOL(phys_ram_base);
 
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+#define VMEMMAP_ADDR_ALIGN	(1ULL << SECTION_SIZE_BITS)
+
+unsigned long vmemmap_start_pfn __ro_after_init;
+EXPORT_SYMBOL(vmemmap_start_pfn);
+#endif
+
 unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]
 							__page_aligned_bss;
 EXPORT_SYMBOL(empty_zero_page);
@@ -219,37 +227,51 @@
 	 */
 	memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start);
 
-	phys_ram_end = memblock_end_of_DRAM();
-
 	/*
 	 * Make sure we align the start of the memory on a PMD boundary so that
 	 * at worst, we map the linear mapping with PMD mappings.
 	 */
-	if (!IS_ENABLED(CONFIG_XIP_KERNEL))
+	if (!IS_ENABLED(CONFIG_XIP_KERNEL)) {
 		phys_ram_base = memblock_start_of_DRAM() & PMD_MASK;
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+		vmemmap_start_pfn = round_down(phys_ram_base, VMEMMAP_ADDR_ALIGN) >> PAGE_SHIFT;
+#endif
+	}
 
 	/*
 	 * In 64-bit, any use of __va/__pa before this point is wrong as we
 	 * did not know the start of DRAM before.
 	 */
-	if (IS_ENABLED(CONFIG_64BIT))
+	if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_MMU))
 		kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base;
 
 	/*
-	 * memblock allocator is not aware of the fact that last 4K bytes of
-	 * the addressable memory can not be mapped because of IS_ERR_VALUE
-	 * macro. Make sure that last 4k bytes are not usable by memblock
-	 * if end of dram is equal to maximum addressable memory.  For 64-bit
-	 * kernel, this problem can't happen here as the end of the virtual
-	 * address space is occupied by the kernel mapping then this check must
-	 * be done as soon as the kernel mapping base address is determined.
+	 * The size of the linear page mapping may restrict the amount of
+	 * usable RAM.
+	 */
+	if (IS_ENABLED(CONFIG_64BIT) && IS_ENABLED(CONFIG_MMU)) {
+		max_mapped_addr = __pa(PAGE_OFFSET) + KERN_VIRT_SIZE;
+		memblock_cap_memory_range(phys_ram_base,
+					  max_mapped_addr - phys_ram_base);
+	}
+
+	/*
+	 * Reserve physical address space that would be mapped to virtual
+	 * addresses greater than (void *)(-PAGE_SIZE) because:
+	 *  - This memory would overlap with ERR_PTR
+	 *  - This memory belongs to high memory, which is not supported
+	 *
+	 * This is not applicable to 64-bit kernel, because virtual addresses
+	 * after (void *)(-PAGE_SIZE) are not linearly mapped: they are
+	 * occupied by kernel mapping. Also it is unrealistic for high memory
+	 * to exist on 64-bit platforms.
 	 */
 	if (!IS_ENABLED(CONFIG_64BIT)) {
-		max_mapped_addr = __pa(~(ulong)0);
-		if (max_mapped_addr == (phys_ram_end - 1))
-			memblock_set_current_limit(max_mapped_addr - 4096);
+		max_mapped_addr = __va_to_pa_nodebug(-PAGE_SIZE);
+		memblock_reserve(max_mapped_addr, (phys_addr_t)-max_mapped_addr);
 	}
 
+	phys_ram_end = memblock_end_of_DRAM();
 	min_low_pfn = PFN_UP(phys_ram_base);
 	max_low_pfn = max_pfn = PFN_DOWN(phys_ram_end);
 	high_memory = (void *)(__va(PFN_PHYS(max_low_pfn)));
@@ -669,6 +691,9 @@
 static uintptr_t __init best_map_size(phys_addr_t pa, uintptr_t va,
 				      phys_addr_t size)
 {
+	if (debug_pagealloc_enabled())
+		return PAGE_SIZE;
+
 	if (pgtable_l5_enabled &&
 	    !(pa & (P4D_SIZE - 1)) && !(va & (P4D_SIZE - 1)) && size >= P4D_SIZE)
 		return P4D_SIZE;
@@ -824,6 +849,10 @@
 		disable_pgtable_l4();
 	}
 
+	/* UBUNTU: Force disable sv57 and fallback to sv48 */
+	if (pgtable_l5_enabled)
+		disable_pgtable_l5();
+
 	memset(early_pg_dir, 0, PAGE_SIZE);
 	memset(early_p4d, 0, PAGE_SIZE);
 	memset(early_pud, 0, PAGE_SIZE);
@@ -901,7 +930,7 @@
 				   PMD_SIZE, PAGE_KERNEL_EXEC);
 
 	/* Map the data in RAM */
-	end_va = kernel_map.virt_addr + XIP_OFFSET + kernel_map.size;
+	end_va = kernel_map.virt_addr + kernel_map.size;
 	for (va = kernel_map.virt_addr + XIP_OFFSET; va < end_va; va += PMD_SIZE)
 		create_pgd_mapping(pgdir, va,
 				   kernel_map.phys_addr + (va - (kernel_map.virt_addr + XIP_OFFSET)),
@@ -1069,8 +1098,11 @@
 	kernel_map.xiprom_sz = (uintptr_t)(&_exiprom) - (uintptr_t)(&_xiprom);
 
 	phys_ram_base = CONFIG_PHYS_RAM_BASE;
+#ifdef CONFIG_SPARSEMEM_VMEMMAP
+	vmemmap_start_pfn = round_down(phys_ram_base, VMEMMAP_ADDR_ALIGN) >> PAGE_SHIFT;
+#endif
 	kernel_map.phys_addr = (uintptr_t)CONFIG_PHYS_RAM_BASE;
-	kernel_map.size = (uintptr_t)(&_end) - (uintptr_t)(&_sdata);
+	kernel_map.size = (uintptr_t)(&_end) - (uintptr_t)(&_start);
 
 	kernel_map.va_kernel_xip_pa_offset = kernel_map.virt_addr - kernel_map.xiprom;
 #else
@@ -1267,8 +1299,6 @@
 		if (start <= __pa(PAGE_OFFSET) &&
 		    __pa(PAGE_OFFSET) < end)
 			start = __pa(PAGE_OFFSET);
-		if (end >= __pa(PAGE_OFFSET) + memory_limit)
-			end = __pa(PAGE_OFFSET) + memory_limit;
 
 		create_linear_mapping_range(start, end, 0);
 	}
--- linux-qcom-6.8.0.orig/arch/riscv/mm/pageattr.c
+++ linux-qcom-6.8.0/arch/riscv/mm/pageattr.c
@@ -387,17 +387,33 @@
 }
 
 #ifdef CONFIG_DEBUG_PAGEALLOC
+static int debug_pagealloc_set_page(pte_t *pte, unsigned long addr, void *data)
+{
+	int enable = *(int *)data;
+
+	unsigned long val = pte_val(ptep_get(pte));
+
+	if (enable)
+		val |= _PAGE_PRESENT;
+	else
+		val &= ~_PAGE_PRESENT;
+
+	set_pte(pte, __pte(val));
+
+	return 0;
+}
+
 void __kernel_map_pages(struct page *page, int numpages, int enable)
 {
 	if (!debug_pagealloc_enabled())
 		return;
 
-	if (enable)
-		__set_memory((unsigned long)page_address(page), numpages,
-			     __pgprot(_PAGE_PRESENT), __pgprot(0));
-	else
-		__set_memory((unsigned long)page_address(page), numpages,
-			     __pgprot(0), __pgprot(_PAGE_PRESENT));
+	unsigned long start = (unsigned long)page_address(page);
+	unsigned long size = PAGE_SIZE * numpages;
+
+	apply_to_existing_page_range(&init_mm, start, size, debug_pagealloc_set_page, &enable);
+
+	flush_tlb_kernel_range(start, start + size);
 }
 #endif
 
--- linux-qcom-6.8.0.orig/arch/riscv/mm/tlbflush.c
+++ linux-qcom-6.8.0/arch/riscv/mm/tlbflush.c
@@ -7,29 +7,6 @@
 #include <asm/sbi.h>
 #include <asm/mmu_context.h>
 
-static inline void local_flush_tlb_all_asid(unsigned long asid)
-{
-	if (asid != FLUSH_TLB_NO_ASID)
-		__asm__ __volatile__ ("sfence.vma x0, %0"
-				:
-				: "r" (asid)
-				: "memory");
-	else
-		local_flush_tlb_all();
-}
-
-static inline void local_flush_tlb_page_asid(unsigned long addr,
-		unsigned long asid)
-{
-	if (asid != FLUSH_TLB_NO_ASID)
-		__asm__ __volatile__ ("sfence.vma %0, %1"
-				:
-				: "r" (addr), "r" (asid)
-				: "memory");
-	else
-		local_flush_tlb_page(addr);
-}
-
 /*
  * Flush entire TLB if number of entries to be flushed is greater
  * than the threshold below.
@@ -99,7 +76,7 @@
 	local_flush_tlb_range_asid(d->start, d->size, d->stride, d->asid);
 }
 
-static void __flush_tlb_range(struct cpumask *cmask, unsigned long asid,
+static void __flush_tlb_range(const struct cpumask *cmask, unsigned long asid,
 			      unsigned long start, unsigned long size,
 			      unsigned long stride)
 {
@@ -200,7 +177,7 @@
 
 void flush_tlb_kernel_range(unsigned long start, unsigned long end)
 {
-	__flush_tlb_range((struct cpumask *)cpu_online_mask, FLUSH_TLB_NO_ASID,
+	__flush_tlb_range(cpu_online_mask, FLUSH_TLB_NO_ASID,
 			  start, end - start, PAGE_SIZE);
 }
 
--- linux-qcom-6.8.0.orig/arch/riscv/net/bpf_jit_comp64.c
+++ linux-qcom-6.8.0/arch/riscv/net/bpf_jit_comp64.c
@@ -14,6 +14,8 @@
 #include "bpf_jit.h"
 
 #define RV_FENTRY_NINSNS 2
+/* imm that allows emit_imm to emit max count insns */
+#define RV_MAX_COUNT_IMM 0x7FFF7FF7FF7FF7FF
 
 #define RV_REG_TCC RV_REG_A6
 #define RV_REG_TCC_SAVED RV_REG_S6 /* Store A6 in S6 if program do calls */
@@ -516,33 +518,33 @@
 		break;
 	/* src_reg = atomic_fetch_<op>(dst_reg + off16, src_reg) */
 	case BPF_ADD | BPF_FETCH:
-		emit(is64 ? rv_amoadd_d(rs, rs, rd, 0, 0) :
-		     rv_amoadd_w(rs, rs, rd, 0, 0), ctx);
+		emit(is64 ? rv_amoadd_d(rs, rs, rd, 1, 1) :
+		     rv_amoadd_w(rs, rs, rd, 1, 1), ctx);
 		if (!is64)
 			emit_zext_32(rs, ctx);
 		break;
 	case BPF_AND | BPF_FETCH:
-		emit(is64 ? rv_amoand_d(rs, rs, rd, 0, 0) :
-		     rv_amoand_w(rs, rs, rd, 0, 0), ctx);
+		emit(is64 ? rv_amoand_d(rs, rs, rd, 1, 1) :
+		     rv_amoand_w(rs, rs, rd, 1, 1), ctx);
 		if (!is64)
 			emit_zext_32(rs, ctx);
 		break;
 	case BPF_OR | BPF_FETCH:
-		emit(is64 ? rv_amoor_d(rs, rs, rd, 0, 0) :
-		     rv_amoor_w(rs, rs, rd, 0, 0), ctx);
+		emit(is64 ? rv_amoor_d(rs, rs, rd, 1, 1) :
+		     rv_amoor_w(rs, rs, rd, 1, 1), ctx);
 		if (!is64)
 			emit_zext_32(rs, ctx);
 		break;
 	case BPF_XOR | BPF_FETCH:
-		emit(is64 ? rv_amoxor_d(rs, rs, rd, 0, 0) :
-		     rv_amoxor_w(rs, rs, rd, 0, 0), ctx);
+		emit(is64 ? rv_amoxor_d(rs, rs, rd, 1, 1) :
+		     rv_amoxor_w(rs, rs, rd, 1, 1), ctx);
 		if (!is64)
 			emit_zext_32(rs, ctx);
 		break;
 	/* src_reg = atomic_xchg(dst_reg + off16, src_reg); */
 	case BPF_XCHG:
-		emit(is64 ? rv_amoswap_d(rs, rs, rd, 0, 0) :
-		     rv_amoswap_w(rs, rs, rd, 0, 0), ctx);
+		emit(is64 ? rv_amoswap_d(rs, rs, rd, 1, 1) :
+		     rv_amoswap_w(rs, rs, rd, 1, 1), ctx);
 		if (!is64)
 			emit_zext_32(rs, ctx);
 		break;
@@ -555,8 +557,8 @@
 		     rv_lr_w(r0, 0, rd, 0, 0), ctx);
 		jmp_offset = ninsns_rvoff(8);
 		emit(rv_bne(RV_REG_T2, r0, jmp_offset >> 1), ctx);
-		emit(is64 ? rv_sc_d(RV_REG_T3, rs, rd, 0, 0) :
-		     rv_sc_w(RV_REG_T3, rs, rd, 0, 0), ctx);
+		emit(is64 ? rv_sc_d(RV_REG_T3, rs, rd, 0, 1) :
+		     rv_sc_w(RV_REG_T3, rs, rd, 0, 1), ctx);
 		jmp_offset = ninsns_rvoff(-6);
 		emit(rv_bne(RV_REG_T3, 0, jmp_offset >> 1), ctx);
 		emit(rv_fence(0x3, 0x3), ctx);
@@ -740,6 +742,9 @@
 	if (ret)
 		return ret;
 
+	/* store prog start time */
+	emit_mv(RV_REG_S1, RV_REG_A0, ctx);
+
 	/* if (__bpf_prog_enter(prog) == 0)
 	 *	goto skip_exec_of_prog;
 	 */
@@ -747,9 +752,6 @@
 	/* nop reserved for conditional jump */
 	emit(rv_nop(), ctx);
 
-	/* store prog start time */
-	emit_mv(RV_REG_S1, RV_REG_A0, ctx);
-
 	/* arg1: &args_off */
 	emit_addi(RV_REG_A0, RV_REG_FP, -args_off, ctx);
 	if (!p->jited)
@@ -922,7 +924,7 @@
 		orig_call += RV_FENTRY_NINSNS * 4;
 
 	if (flags & BPF_TRAMP_F_CALL_ORIG) {
-		emit_imm(RV_REG_A0, (const s64)im, ctx);
+		emit_imm(RV_REG_A0, ctx->insns ? (const s64)im : RV_MAX_COUNT_IMM, ctx);
 		ret = emit_call((const u64)__bpf_tramp_enter, true, ctx);
 		if (ret)
 			return ret;
@@ -983,7 +985,7 @@
 
 	if (flags & BPF_TRAMP_F_CALL_ORIG) {
 		im->ip_epilogue = ctx->insns + ctx->ninsns;
-		emit_imm(RV_REG_A0, (const s64)im, ctx);
+		emit_imm(RV_REG_A0, ctx->insns ? (const s64)im : RV_MAX_COUNT_IMM, ctx);
 		ret = emit_call((const u64)__bpf_tramp_exit, true, ctx);
 		if (ret)
 			goto out;
@@ -1052,6 +1054,7 @@
 {
 	int ret;
 	struct rv_jit_context ctx;
+	u32 size = image_end - image;
 
 	ctx.ninsns = 0;
 	/*
@@ -1065,11 +1068,16 @@
 	ctx.ro_insns = image;
 	ret = __arch_prepare_bpf_trampoline(im, m, tlinks, func_addr, flags, &ctx);
 	if (ret < 0)
-		return ret;
+		goto out;
 
-	bpf_flush_icache(ctx.insns, ctx.insns + ctx.ninsns);
+	if (WARN_ON(size < ninsns_rvoff(ctx.ninsns))) {
+		ret = -E2BIG;
+		goto out;
+	}
 
-	return ninsns_rvoff(ret);
+	bpf_flush_icache(image, image_end);
+out:
+	return ret < 0 ? ret : size;
 }
 
 int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
--- linux-qcom-6.8.0.orig/arch/riscv/purgatory/Makefile
+++ linux-qcom-6.8.0/arch/riscv/purgatory/Makefile
@@ -2,7 +2,9 @@
 OBJECT_FILES_NON_STANDARD := y
 
 purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o memcpy.o memset.o
+ifeq ($(CONFIG_KASAN_GENERIC)$(CONFIG_KASAN_SW_TAGS),)
 purgatory-y += strcmp.o strlen.o strncmp.o
+endif
 
 targets += $(purgatory-y)
 PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
--- linux-qcom-6.8.0.orig/arch/riscv/purgatory/entry.S
+++ linux-qcom-6.8.0/arch/riscv/purgatory/entry.S
@@ -7,6 +7,7 @@
  * Author: Li Zhengyu (lizhengyu3@huawei.com)
  *
  */
+#include <asm/asm.h>
 #include <linux/linkage.h>
 
 .text
@@ -34,6 +35,7 @@
 
 .data
 
+.align LGREG
 SYM_DATA(riscv_kernel_entry, .quad 0)
 
 .end
--- linux-qcom-6.8.0.orig/arch/s390/Kconfig
+++ linux-qcom-6.8.0/arch/s390/Kconfig
@@ -82,7 +82,7 @@
 	select ARCH_HAS_STRICT_KERNEL_RWX
 	select ARCH_HAS_STRICT_MODULE_RWX
 	select ARCH_HAS_SYSCALL_WRAPPER
-	select ARCH_HAS_UBSAN_SANITIZE_ALL
+	select ARCH_HAS_UBSAN
 	select ARCH_HAS_VDSO_DATA
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
 	select ARCH_INLINE_READ_LOCK
@@ -113,6 +113,7 @@
 	select ARCH_INLINE_WRITE_UNLOCK_BH
 	select ARCH_INLINE_WRITE_UNLOCK_IRQ
 	select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
+	select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE
 	select ARCH_STACKWALK
 	select ARCH_SUPPORTS_ATOMIC_RMW
 	select ARCH_SUPPORTS_DEBUG_PAGEALLOC
--- linux-qcom-6.8.0.orig/arch/s390/Makefile
+++ linux-qcom-6.8.0/arch/s390/Makefile
@@ -21,7 +21,7 @@
 ifndef CONFIG_AS_IS_LLVM
 KBUILD_AFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),$(aflags_dwarf))
 endif
-KBUILD_CFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -O2 -mpacked-stack
+KBUILD_CFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -O2 -mpacked-stack -std=gnu11
 KBUILD_CFLAGS_DECOMPRESSOR += -DDISABLE_BRANCH_PROFILING -D__NO_FORTIFY
 KBUILD_CFLAGS_DECOMPRESSOR += -fno-delete-null-pointer-checks -msoft-float -mbackchain
 KBUILD_CFLAGS_DECOMPRESSOR += -fno-asynchronous-unwind-tables
--- linux-qcom-6.8.0.orig/arch/s390/boot/startup.c
+++ linux-qcom-6.8.0/arch/s390/boot/startup.c
@@ -32,7 +32,6 @@
 unsigned long __bootdata(ident_map_size);
 
 u64 __bootdata_preserved(stfle_fac_list[16]);
-u64 __bootdata_preserved(alt_stfle_fac_list[16]);
 struct oldmem_data __bootdata_preserved(oldmem_data);
 
 struct machine_info machine;
@@ -385,8 +384,12 @@
 
 	/* vmlinux decompression is done, shrink reserved low memory */
 	physmem_reserve(RR_DECOMPRESSOR, 0, (unsigned long)_decompressor_end);
-	if (kaslr_enabled())
-		amode31_lma = randomize_within_range(vmlinux.amode31_size, PAGE_SIZE, 0, SZ_2G);
+	if (kaslr_enabled()) {
+		unsigned long amode31_min;
+
+		amode31_min = (unsigned long)_decompressor_end;
+		amode31_lma = randomize_within_range(vmlinux.amode31_size, PAGE_SIZE, amode31_min, SZ_2G);
+	}
 	amode31_lma = amode31_lma ?: vmlinux.default_lma - vmlinux.amode31_size;
 	physmem_reserve(RR_AMODE31, amode31_lma, vmlinux.amode31_size);
 
--- linux-qcom-6.8.0.orig/arch/s390/boot/vmem.c
+++ linux-qcom-6.8.0/arch/s390/boot/vmem.c
@@ -366,7 +366,7 @@
 			}
 			pmd = boot_crst_alloc(_SEGMENT_ENTRY_EMPTY);
 			pud_populate(&init_mm, pud, pmd);
-		} else if (pud_large(*pud)) {
+		} else if (pud_leaf(*pud)) {
 			continue;
 		}
 		pgtable_pmd_populate(pud, addr, next, mode);
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/cpacf.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/cpacf.h
@@ -166,28 +166,86 @@
 
 typedef struct { unsigned char bytes[16]; } cpacf_mask_t;
 
-/**
- * cpacf_query() - check if a specific CPACF function is available
- * @opcode: the opcode of the crypto instruction
- * @func: the function code to test for
- *
- * Executes the query function for the given crypto instruction @opcode
- * and checks if @func is available
- *
- * Returns 1 if @func is available for @opcode, 0 otherwise
+/*
+ * Prototype for a not existing function to produce a link
+ * error if __cpacf_query() or __cpacf_check_opcode() is used
+ * with an invalid compile time const opcode.
  */
-static __always_inline void __cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
+void __cpacf_bad_opcode(void);
+
+static __always_inline void __cpacf_query_rre(u32 opc, u8 r1, u8 r2,
+					      cpacf_mask_t *mask)
 {
 	asm volatile(
-		"	lghi	0,0\n" /* query function */
-		"	lgr	1,%[mask]\n"
-		"	spm	0\n" /* pckmo doesn't change the cc */
-		/* Parameter regs are ignored, but must be nonzero and unique */
-		"0:	.insn	rrf,%[opc] << 16,2,4,6,0\n"
-		"	brc	1,0b\n"	/* handle partial completion */
-		: "=m" (*mask)
-		: [mask] "d" ((unsigned long)mask), [opc] "i" (opcode)
-		: "cc", "0", "1");
+		"	la	%%r1,%[mask]\n"
+		"	xgr	%%r0,%%r0\n"
+		"	.insn	rre,%[opc] << 16,%[r1],%[r2]\n"
+		: [mask] "=R" (*mask)
+		: [opc] "i" (opc),
+		  [r1] "i" (r1), [r2] "i" (r2)
+		: "cc", "r0", "r1");
+}
+
+static __always_inline void __cpacf_query_rrf(u32 opc,
+					      u8 r1, u8 r2, u8 r3, u8 m4,
+					      cpacf_mask_t *mask)
+{
+	asm volatile(
+		"	la	%%r1,%[mask]\n"
+		"	xgr	%%r0,%%r0\n"
+		"	.insn	rrf,%[opc] << 16,%[r1],%[r2],%[r3],%[m4]\n"
+		: [mask] "=R" (*mask)
+		: [opc] "i" (opc), [r1] "i" (r1), [r2] "i" (r2),
+		  [r3] "i" (r3), [m4] "i" (m4)
+		: "cc", "r0", "r1");
+}
+
+static __always_inline void __cpacf_query(unsigned int opcode,
+					  cpacf_mask_t *mask)
+{
+	switch (opcode) {
+	case CPACF_KDSA:
+		__cpacf_query_rre(CPACF_KDSA, 0, 2, mask);
+		break;
+	case CPACF_KIMD:
+		__cpacf_query_rre(CPACF_KIMD, 0, 2, mask);
+		break;
+	case CPACF_KLMD:
+		__cpacf_query_rre(CPACF_KLMD, 0, 2, mask);
+		break;
+	case CPACF_KM:
+		__cpacf_query_rre(CPACF_KM, 2, 4, mask);
+		break;
+	case CPACF_KMA:
+		__cpacf_query_rrf(CPACF_KMA, 2, 4, 6, 0, mask);
+		break;
+	case CPACF_KMAC:
+		__cpacf_query_rre(CPACF_KMAC, 0, 2, mask);
+		break;
+	case CPACF_KMC:
+		__cpacf_query_rre(CPACF_KMC, 2, 4, mask);
+		break;
+	case CPACF_KMCTR:
+		__cpacf_query_rrf(CPACF_KMCTR, 2, 4, 6, 0, mask);
+		break;
+	case CPACF_KMF:
+		__cpacf_query_rre(CPACF_KMF, 2, 4, mask);
+		break;
+	case CPACF_KMO:
+		__cpacf_query_rre(CPACF_KMO, 2, 4, mask);
+		break;
+	case CPACF_PCC:
+		__cpacf_query_rre(CPACF_PCC, 0, 0, mask);
+		break;
+	case CPACF_PCKMO:
+		__cpacf_query_rre(CPACF_PCKMO, 0, 0, mask);
+		break;
+	case CPACF_PRNO:
+		__cpacf_query_rre(CPACF_PRNO, 2, 4, mask);
+		break;
+	default:
+		__cpacf_bad_opcode();
+	}
 }
 
 static __always_inline int __cpacf_check_opcode(unsigned int opcode)
@@ -211,10 +269,21 @@
 	case CPACF_KMA:
 		return test_facility(146);	/* check for MSA8 */
 	default:
-		BUG();
+		__cpacf_bad_opcode();
+		return 0;
 	}
 }
 
+/**
+ * cpacf_query() - check if a specific CPACF function is available
+ * @opcode: the opcode of the crypto instruction
+ * @func: the function code to test for
+ *
+ * Executes the query function for the given crypto instruction @opcode
+ * and checks if @func is available
+ *
+ * Returns 1 if @func is available for @opcode, 0 otherwise
+ */
 static __always_inline int cpacf_query(unsigned int opcode, cpacf_mask_t *mask)
 {
 	if (__cpacf_check_opcode(opcode)) {
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/dwarf.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/dwarf.h
@@ -9,6 +9,7 @@
 #define CFI_DEF_CFA_OFFSET	.cfi_def_cfa_offset
 #define CFI_ADJUST_CFA_OFFSET	.cfi_adjust_cfa_offset
 #define CFI_RESTORE		.cfi_restore
+#define CFI_REL_OFFSET		.cfi_rel_offset
 
 #ifdef CONFIG_AS_CFI_VAL_OFFSET
 #define CFI_VAL_OFFSET		.cfi_val_offset
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/entry-common.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/entry-common.h
@@ -55,7 +55,7 @@
 static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
 						  unsigned long ti_work)
 {
-	choose_random_kstack_offset(get_tod_clock_fast() & 0xff);
+	choose_random_kstack_offset(get_tod_clock_fast());
 }
 
 #define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/facility.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/facility.h
@@ -60,13 +60,15 @@
 	unsigned long facilities_als[] = { FACILITIES_ALS };
 
 	if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) {
-		if (__test_facility(nr, &facilities_als))
-			return 1;
+		if (__test_facility(nr, &facilities_als)) {
+			if (!__is_defined(__DECOMPRESSOR))
+				return 1;
+		}
 	}
 	return __test_facility(nr, &stfle_fac_list);
 }
 
-static inline unsigned long __stfle_asm(u64 *stfle_fac_list, int size)
+static inline unsigned long __stfle_asm(u64 *fac_list, int size)
 {
 	unsigned long reg0 = size - 1;
 
@@ -74,7 +76,7 @@
 		"	lgr	0,%[reg0]\n"
 		"	.insn	s,0xb2b00000,%[list]\n" /* stfle */
 		"	lgr	%[reg0],0\n"
-		: [reg0] "+&d" (reg0), [list] "+Q" (*stfle_fac_list)
+		: [reg0] "+&d" (reg0), [list] "+Q" (*fac_list)
 		:
 		: "memory", "cc", "0");
 	return reg0;
@@ -82,10 +84,10 @@
 
 /**
  * stfle - Store facility list extended
- * @stfle_fac_list: array where facility list can be stored
+ * @fac_list: array where facility list can be stored
  * @size: size of passed in array in double words
  */
-static inline void __stfle(u64 *stfle_fac_list, int size)
+static inline void __stfle(u64 *fac_list, int size)
 {
 	unsigned long nr;
 	u32 stfl_fac_list;
@@ -94,20 +96,20 @@
 		"	stfl	0(0)\n"
 		: "=m" (S390_lowcore.stfl_fac_list));
 	stfl_fac_list = S390_lowcore.stfl_fac_list;
-	memcpy(stfle_fac_list, &stfl_fac_list, 4);
+	memcpy(fac_list, &stfl_fac_list, 4);
 	nr = 4; /* bytes stored by stfl */
 	if (stfl_fac_list & 0x01000000) {
 		/* More facility bits available with stfle */
-		nr = __stfle_asm(stfle_fac_list, size);
+		nr = __stfle_asm(fac_list, size);
 		nr = min_t(unsigned long, (nr + 1) * 8, size * 8);
 	}
-	memset((char *) stfle_fac_list + nr, 0, size * 8 - nr);
+	memset((char *)fac_list + nr, 0, size * 8 - nr);
 }
 
-static inline void stfle(u64 *stfle_fac_list, int size)
+static inline void stfle(u64 *fac_list, int size)
 {
 	preempt_disable();
-	__stfle(stfle_fac_list, size);
+	__stfle(fac_list, size);
 	preempt_enable();
 }
 
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/ftrace.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/ftrace.h
@@ -7,13 +7,24 @@
 #define MCOUNT_INSN_SIZE	6
 
 #ifndef __ASSEMBLY__
+#include <asm/stacktrace.h>
 
-#ifdef CONFIG_CC_IS_CLANG
-/* https://bugs.llvm.org/show_bug.cgi?id=41424 */
-#define ftrace_return_address(n) 0UL
-#else
-#define ftrace_return_address(n) __builtin_return_address(n)
-#endif
+static __always_inline unsigned long return_address(unsigned int n)
+{
+	struct stack_frame *sf;
+
+	if (!n)
+		return (unsigned long)__builtin_return_address(0);
+
+	sf = (struct stack_frame *)current_frame_address();
+	do {
+		sf = (struct stack_frame *)sf->back_chain;
+		if (!sf)
+			return 0;
+	} while (--n);
+	return sf->gprs[8];
+}
+#define ftrace_return_address(n) return_address(n)
 
 void ftrace_caller(void);
 
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/futex.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/futex.h
@@ -44,7 +44,7 @@
 		break;
 	case FUTEX_OP_ANDN:
 		__futex_atomic_op("lr %2,%1\nnr %2,%5\n",
-				  ret, oldval, newval, uaddr, oparg);
+				  ret, oldval, newval, uaddr, ~oparg);
 		break;
 	case FUTEX_OP_XOR:
 		__futex_atomic_op("lr %2,%1\nxr %2,%5\n",
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/gmap.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/gmap.h
@@ -146,7 +146,7 @@
 
 void gmap_sync_dirty_log_pmd(struct gmap *gmap, unsigned long dirty_bitmap[4],
 			     unsigned long gaddr, unsigned long vmaddr);
-int gmap_mark_unmergeable(void);
+int s390_disable_cow_sharing(void);
 void s390_unlist_old_asce(struct gmap *gmap);
 int s390_replace_asce(struct gmap *gmap);
 void s390_uv_destroy_pfns(unsigned long count, unsigned long *pfns);
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/io.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/io.h
@@ -16,8 +16,10 @@
 #include <asm/pci_io.h>
 
 #define xlate_dev_mem_ptr xlate_dev_mem_ptr
+#define kc_xlate_dev_mem_ptr xlate_dev_mem_ptr
 void *xlate_dev_mem_ptr(phys_addr_t phys);
 #define unxlate_dev_mem_ptr unxlate_dev_mem_ptr
+#define kc_unxlate_dev_mem_ptr unxlate_dev_mem_ptr
 void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
 
 #define IO_SPACE_LIMIT 0
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/ipl.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/ipl.h
@@ -139,6 +139,7 @@
 			     unsigned char flags, unsigned short cert);
 int ipl_report_add_certificate(struct ipl_report *report, void *key,
 			       unsigned long addr, unsigned long len);
+bool ipl_get_secureboot(void);
 
 /*
  * DIAG 308 support
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/kvm_host.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/kvm_host.h
@@ -427,6 +427,7 @@
 	u64 instruction_io_other;
 	u64 instruction_lpsw;
 	u64 instruction_lpswe;
+	u64 instruction_lpswey;
 	u64 instruction_pfmf;
 	u64 instruction_ptff;
 	u64 instruction_sck;
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/mmu.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/mmu.h
@@ -32,6 +32,11 @@
 	unsigned int uses_skeys:1;
 	/* The mmu context uses CMM. */
 	unsigned int uses_cmm:1;
+	/*
+	 * The mmu context allows COW-sharing of memory pages (KSM, zeropage).
+	 * Note that COW-sharing during fork() is currently always allowed.
+	 */
+	unsigned int allow_cow_sharing:1;
 	/* The gmaps associated with this context are allowed to use huge pages. */
 	unsigned int allow_gmap_hpage_1m:1;
 } mm_context_t;
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/mmu_context.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/mmu_context.h
@@ -35,6 +35,7 @@
 	mm->context.has_pgste = 0;
 	mm->context.uses_skeys = 0;
 	mm->context.uses_cmm = 0;
+	mm->context.allow_cow_sharing = 1;
 	mm->context.allow_gmap_hpage_1m = 0;
 #endif
 	switch (mm->context.asce_limit) {
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/pci.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/pci.h
@@ -96,7 +96,6 @@
 	u8		size;		/* order 2 exponent */
 };
 
-struct s390_domain;
 struct kvm_zdev;
 
 #define ZPCI_FUNCTIONS_PER_BUS 256
@@ -107,9 +106,10 @@
 	struct list_head	resources;
 	struct list_head	bus_next;
 	struct resource		bus_resource;
-	int			pchid;
+	int			topo;		/* TID if topo_is_tid, PCHID otherwise */
 	int			domain_nr;
-	bool			multifunction;
+	u8			multifunction	: 1;
+	u8			topo_is_tid	: 1;
 	enum pci_bus_speed	max_bus_speed;
 };
 
@@ -122,6 +122,7 @@
 	struct rcu_head rcu;
 	struct hotplug_slot hotplug_slot;
 
+	struct mutex state_lock;	/* protect state changes */
 	enum zpci_state state;
 	u32		fid;		/* function ID, used by sclp */
 	u32		fh;		/* function handle, used by insn's */
@@ -129,6 +130,8 @@
 	u16		vfn;		/* virtual function number */
 	u16		pchid;		/* physical channel ID */
 	u16		maxstbl;	/* Maximum store block size */
+	u16		rid;		/* RID as supplied by firmware */
+	u16		tid;		/* Topology for which RID is valid */
 	u8		pfgid;		/* function group ID */
 	u8		pft;		/* pci function type */
 	u8		port;
@@ -139,10 +142,10 @@
 	u8		is_physfn	: 1;
 	u8		util_str_avail	: 1;
 	u8		irqs_registered	: 1;
-	u8		reserved	: 2;
+	u8		tid_avail	: 1;
+	u8		reserved	: 1;
 	unsigned int	devfn;		/* DEVFN part of the RID*/
 
-	struct mutex lock;
 	u8 pfip[CLP_PFIP_NR_SEGMENTS];	/* pci function internal path */
 	u32 uid;			/* user defined id */
 	u8 util_str[CLP_UTIL_STR_LEN];	/* utility string */
@@ -170,6 +173,7 @@
 	u64		dma_mask;	/* DMA address space mask */
 
 	/* Function measurement block */
+	struct mutex fmb_lock;
 	struct zpci_fmb *fmb;
 	u16		fmb_update;	/* update interval */
 	u16		fmb_length;
@@ -180,9 +184,10 @@
 	struct dentry	*debugfs_dev;
 
 	/* IOMMU and passthrough */
-	struct s390_domain *s390_domain; /* s390 IOMMU domain data */
+	struct iommu_domain *s390_domain; /* attached IOMMU domain */
 	struct kvm_zdev *kzdev;
 	struct mutex kzdev_lock;
+	spinlock_t dom_lock;		/* protect s390_domain change */
 };
 
 static inline bool zdev_enabled(struct zpci_dev *zdev)
@@ -202,12 +207,14 @@
 ----------------------------------------------------------------------------- */
 /* Base stuff */
 struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state);
+int zpci_add_device(struct zpci_dev *zdev);
 int zpci_enable_device(struct zpci_dev *);
 int zpci_disable_device(struct zpci_dev *);
 int zpci_scan_configured_device(struct zpci_dev *zdev, u32 fh);
 int zpci_deconfigure_device(struct zpci_dev *zdev);
 void zpci_device_reserved(struct zpci_dev *zdev);
 bool zpci_is_device_configured(struct zpci_dev *zdev);
+int zpci_scan_devices(void);
 
 int zpci_hot_reset_device(struct zpci_dev *zdev);
 int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64, u8 *);
@@ -217,7 +224,7 @@
 
 /* CLP */
 int clp_setup_writeback_mio(void);
-int clp_scan_pci_devices(void);
+int clp_scan_pci_devices(struct list_head *scan_list);
 int clp_query_pci_fn(struct zpci_dev *zdev);
 int clp_enable_fh(struct zpci_dev *zdev, u32 *fh, u8 nr_dma_as);
 int clp_disable_fh(struct zpci_dev *zdev, u32 *fh);
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/pci_clp.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/pci_clp.h
@@ -110,7 +110,8 @@
 struct clp_rsp_query_pci {
 	struct clp_rsp_hdr hdr;
 	u16 vfn;			/* virtual fn number */
-	u16			:  3;
+	u16			:  2;
+	u16 tid_avail		:  1;
 	u16 rid_avail		:  1;
 	u16 is_physfn		:  1;
 	u16 reserved1		:  1;
@@ -130,8 +131,9 @@
 	u64 edma;			/* end dma as */
 #define ZPCI_RID_MASK_DEVFN 0x00ff
 	u16 rid;			/* BUS/DEVFN PCI address */
-	u16 reserved0;
-	u32 reserved[10];
+	u32 reserved0;
+	u16 tid;
+	u32 reserved[9];
 	u32 uid;			/* user defined id */
 	u8 util_str[CLP_UTIL_STR_LEN];	/* utility string */
 	u32 reserved2[16];
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/perf_event.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/perf_event.h
@@ -73,6 +73,7 @@
 #define SAMPLE_FREQ_MODE(hwc)	(SAMPL_FLAGS(hwc) & PERF_CPUM_SF_FREQ_MODE)
 
 #define perf_arch_fetch_caller_regs(regs, __ip) do {			\
+	(regs)->psw.mask = 0;						\
 	(regs)->psw.addr = (__ip);					\
 	(regs)->gprs[15] = (unsigned long)__builtin_frame_address(0) -	\
 		offsetof(struct stack_frame, back_chain);		\
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/pgtable.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/pgtable.h
@@ -566,10 +566,20 @@
 }
 
 /*
- * In the case that a guest uses storage keys
- * faults should no longer be backed by zero pages
+ * As soon as the guest uses storage keys or enables PV, we deduplicate all
+ * mapped shared zeropages and prevent new shared zeropages from getting
+ * mapped.
  */
-#define mm_forbids_zeropage mm_has_pgste
+#define mm_forbids_zeropage mm_forbids_zeropage
+static inline int mm_forbids_zeropage(struct mm_struct *mm)
+{
+#ifdef CONFIG_PGSTE
+	if (!mm->context.allow_cow_sharing)
+		return 1;
+#endif
+	return 0;
+}
+
 static inline int mm_uses_skeys(struct mm_struct *mm)
 {
 #ifdef CONFIG_PGSTE
@@ -730,7 +740,7 @@
 {
 	unsigned long type = pud_val(pud) & _REGION_ENTRY_TYPE_MASK;
 
-	if (type > _REGION_ENTRY_TYPE_R3 || pud_large(pud))
+	if (type > _REGION_ENTRY_TYPE_R3 || pud_leaf(pud))
 		return 1;
 	if (type < _REGION_ENTRY_TYPE_R3)
 		return 0;
@@ -1398,7 +1408,7 @@
 	unsigned long origin_mask;
 
 	origin_mask = _REGION_ENTRY_ORIGIN;
-	if (pud_large(pud))
+	if (pud_leaf(pud))
 		origin_mask = _REGION3_ENTRY_ORIGIN_LARGE;
 	return (unsigned long)__va(pud_val(pud) & origin_mask);
 }
@@ -1766,8 +1776,10 @@
 static inline pmd_t pmdp_invalidate(struct vm_area_struct *vma,
 				   unsigned long addr, pmd_t *pmdp)
 {
-	pmd_t pmd = __pmd(pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID);
+	pmd_t pmd;
 
+	VM_WARN_ON_ONCE(!pmd_present(*pmdp));
+	pmd = __pmd(pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID);
 	return pmdp_xchg_direct(vma->vm_mm, addr, pmdp, pmd);
 }
 
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/processor.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/processor.h
@@ -99,6 +99,7 @@
 
 extern const struct seq_operations cpuinfo_op;
 extern void execve_tail(void);
+unsigned long vdso_text_size(void);
 unsigned long vdso_size(void);
 
 /*
@@ -140,8 +141,7 @@
 		"	la	%[addr],256(%[addr])\n"
 		"	brctg	%[tmp],0b\n"
 		"1:	stg	%[poison],0(%[addr])\n"
-		"	larl	%[tmp],3f\n"
-		"	ex	%[count],0(%[tmp])\n"
+		"	exrl	%[count],3f\n"
 		"	j	4f\n"
 		"2:	stg	%[poison],0(%[addr])\n"
 		"	j	4f\n"
@@ -303,8 +303,8 @@
  */
 static __always_inline void __load_psw_mask(unsigned long mask)
 {
+	psw_t psw __uninitialized;
 	unsigned long addr;
-	psw_t psw;
 
 	psw.mask = mask;
 
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/set_memory.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/set_memory.h
@@ -62,5 +62,6 @@
 
 int set_direct_map_invalid_noflush(struct page *page);
 int set_direct_map_default_noflush(struct page *page);
+bool kernel_page_present(struct page *page);
 
 #endif
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/stacktrace.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/stacktrace.h
@@ -2,6 +2,7 @@
 #ifndef _ASM_S390_STACKTRACE_H
 #define _ASM_S390_STACKTRACE_H
 
+#include <linux/stacktrace.h>
 #include <linux/uaccess.h>
 #include <linux/ptrace.h>
 #include <asm/switch_to.h>
@@ -13,6 +14,17 @@
 	unsigned long empty2[4];
 };
 
+struct stack_frame_vdso_wrapper {
+	struct stack_frame_user sf;
+	unsigned long return_address;
+};
+
+struct perf_callchain_entry_ctx;
+
+void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *cookie,
+				 struct perf_callchain_entry_ctx *entry,
+				 const struct pt_regs *regs, bool perf);
+
 enum stack_type {
 	STACK_TYPE_UNKNOWN,
 	STACK_TYPE_TASK,
--- linux-qcom-6.8.0.orig/arch/s390/include/asm/uv.h
+++ linux-qcom-6.8.0/arch/s390/include/asm/uv.h
@@ -442,7 +442,10 @@
 
 	if (!uv_call(0, (u64)&uvcb))
 		return 0;
-	return -EINVAL;
+	pr_err("%s UVC failed (rc: 0x%x, rrc: 0x%x), possible hypervisor bug.\n",
+	       uvcb.header.cmd == UVC_CMD_SET_SHARED_ACCESS ? "Share" : "Unshare",
+	       uvcb.header.rc, uvcb.header.rrc);
+	panic("System security cannot be guaranteed unless the system panics now.\n");
 }
 
 /*
--- linux-qcom-6.8.0.orig/arch/s390/kernel/Makefile
+++ linux-qcom-6.8.0/arch/s390/kernel/Makefile
@@ -11,6 +11,8 @@
 # Do not trace early setup code
 CFLAGS_REMOVE_early.o		= $(CC_FLAGS_FTRACE)
 CFLAGS_REMOVE_rethook.o		= $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_stacktrace.o	= $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_unwind_bc.o	= $(CC_FLAGS_FTRACE)
 
 endif
 
@@ -34,7 +36,7 @@
 CFLAGS_dumpstack.o	+= -fno-optimize-sibling-calls
 CFLAGS_unwind_bc.o	+= -fno-optimize-sibling-calls
 
-obj-y	:= head64.o traps.o time.o process.o earlypgm.o early.o setup.o idle.o vtime.o
+obj-y	:= head64.o traps.o time.o process.o early.o setup.o idle.o vtime.o
 obj-y	+= processor.o syscall.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o
 obj-y	+= debug.o irq.o ipl.o dis.o diag.o vdso.o cpufeature.o
 obj-y	+= sysinfo.o lgr.o os_info.o ctlreg.o
--- linux-qcom-6.8.0.orig/arch/s390/kernel/asm-offsets.c
+++ linux-qcom-6.8.0/arch/s390/kernel/asm-offsets.c
@@ -66,6 +66,11 @@
 	OFFSET(__SF_SIE_CONTROL_PHYS, stack_frame, sie_control_block_phys);
 	DEFINE(STACK_FRAME_OVERHEAD, sizeof(struct stack_frame));
 	BLANK();
+	OFFSET(__SFUSER_BACKCHAIN, stack_frame_user, back_chain);
+	DEFINE(STACK_FRAME_USER_OVERHEAD, sizeof(struct stack_frame_user));
+	OFFSET(__SFVDSO_RETURN_ADDRESS, stack_frame_vdso_wrapper, return_address);
+	DEFINE(STACK_FRAME_VDSO_OVERHEAD, sizeof(struct stack_frame_vdso_wrapper));
+	BLANK();
 	/* idle data offsets */
 	OFFSET(__CLOCK_IDLE_ENTER, s390_idle_data, clock_idle_enter);
 	OFFSET(__TIMER_IDLE_ENTER, s390_idle_data, timer_idle_enter);
--- linux-qcom-6.8.0.orig/arch/s390/kernel/cache.c
+++ linux-qcom-6.8.0/arch/s390/kernel/cache.c
@@ -166,5 +166,6 @@
 			ci_leaf_init(this_leaf++, pvt, ctype, level, cpu);
 		}
 	}
+	this_cpu_ci->cpu_map_populated = true;
 	return 0;
 }
--- linux-qcom-6.8.0.orig/arch/s390/kernel/entry.S
+++ linux-qcom-6.8.0/arch/s390/kernel/entry.S
@@ -458,9 +458,13 @@
 SYM_CODE_END(\name)
 .endm
 
+	.section .irqentry.text, "ax"
+
 INT_HANDLER ext_int_handler,__LC_EXT_OLD_PSW,do_ext_irq
 INT_HANDLER io_int_handler,__LC_IO_OLD_PSW,do_io_irq
 
+	.section .kprobes.text, "ax"
+
 /*
  * Load idle PSW.
  */
@@ -621,6 +625,21 @@
 3:	j	3b
 SYM_CODE_END(restart_int_handler)
 
+SYM_CODE_START(early_pgm_check_handler)
+	stmg	%r8,%r15,__LC_SAVE_AREA_SYNC
+	aghi	%r15,-(STACK_FRAME_OVERHEAD+__PT_SIZE)
+	la	%r11,STACK_FRAME_OVERHEAD(%r15)
+	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
+	stmg	%r0,%r7,__PT_R0(%r11)
+	mvc	__PT_PSW(16,%r11),__LC_PGM_OLD_PSW
+	mvc	__PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
+	lgr	%r2,%r11
+	brasl	%r14,__do_early_pgm_check
+	mvc	__LC_RETURN_PSW(16),STACK_FRAME_OVERHEAD+__PT_PSW(%r15)
+	lmg	%r0,%r15,STACK_FRAME_OVERHEAD+__PT_R0(%r15)
+	lpswe	__LC_RETURN_PSW
+SYM_CODE_END(early_pgm_check_handler)
+
 	.section .kprobes.text, "ax"
 
 #if defined(CONFIG_CHECK_STACK) || defined(CONFIG_VMAP_STACK)
@@ -653,6 +672,7 @@
 SYM_DATA_END(daton_psw)
 
 	.section .rodata, "a"
+	.balign	8
 #define SYSCALL(esame,emu)	.quad __s390x_ ## esame
 SYM_DATA_START(sys_call_table)
 #include "asm/syscall_table.h"
--- linux-qcom-6.8.0.orig/arch/s390/kernel/ftrace.c
+++ linux-qcom-6.8.0/arch/s390/kernel/ftrace.c
@@ -296,6 +296,9 @@
 	struct kprobe *p;
 	int bit;
 
+	if (unlikely(kprobe_ftrace_disabled))
+		return;
+
 	bit = ftrace_test_recursion_trylock(ip, parent_ip);
 	if (bit < 0)
 		return;
--- linux-qcom-6.8.0.orig/arch/s390/kernel/ipl.c
+++ linux-qcom-6.8.0/arch/s390/kernel/ipl.c
@@ -962,8 +962,8 @@
 		scpdata_len += padding;
 	}
 
-	reipl_block_nvme->hdr.len = IPL_BP_FCP_LEN + scpdata_len;
-	reipl_block_nvme->nvme.len = IPL_BP0_FCP_LEN + scpdata_len;
+	reipl_block_nvme->hdr.len = IPL_BP_NVME_LEN + scpdata_len;
+	reipl_block_nvme->nvme.len = IPL_BP0_NVME_LEN + scpdata_len;
 	reipl_block_nvme->nvme.scp_data_len = scpdata_len;
 
 	return count;
@@ -1858,9 +1858,9 @@
 	}
 	dump_block_nvme->hdr.len = IPL_BP_NVME_LEN;
 	dump_block_nvme->hdr.version = IPL_PARM_BLOCK_VERSION;
-	dump_block_nvme->fcp.len = IPL_BP0_NVME_LEN;
-	dump_block_nvme->fcp.pbt = IPL_PBT_NVME;
-	dump_block_nvme->fcp.opt = IPL_PB0_NVME_OPT_DUMP;
+	dump_block_nvme->nvme.len = IPL_BP0_NVME_LEN;
+	dump_block_nvme->nvme.pbt = IPL_PBT_NVME;
+	dump_block_nvme->nvme.opt = IPL_PB0_NVME_OPT_DUMP;
 	dump_capabilities |= DUMP_TYPE_NVME;
 	return 0;
 }
@@ -2520,3 +2520,8 @@
 }
 
 #endif
+
+bool ipl_get_secureboot(void)
+{
+	return !!ipl_secure_flag;
+}
--- linux-qcom-6.8.0.orig/arch/s390/kernel/kprobes.c
+++ linux-qcom-6.8.0/arch/s390/kernel/kprobes.c
@@ -525,6 +525,12 @@
 	return 0;
 }
 
+int __init arch_populate_kprobe_blacklist(void)
+{
+	return kprobe_add_area_blacklist((unsigned long)__irqentry_text_start,
+					 (unsigned long)__irqentry_text_end);
+}
+
 int arch_trampoline_kprobe(struct kprobe *p)
 {
 	return 0;
--- linux-qcom-6.8.0.orig/arch/s390/kernel/perf_cpum_cf.c
+++ linux-qcom-6.8.0/arch/s390/kernel/perf_cpum_cf.c
@@ -428,7 +428,7 @@
 	case CPUMF_CTR_SET_CRYPTO:
 		if (cpumf_ctr_info.csvn >= 1 && cpumf_ctr_info.csvn <= 5)
 			ctrset_size = 16;
-		else if (cpumf_ctr_info.csvn == 6 || cpumf_ctr_info.csvn == 7)
+		else if (cpumf_ctr_info.csvn >= 6)
 			ctrset_size = 20;
 		break;
 	case CPUMF_CTR_SET_EXT:
@@ -556,25 +556,31 @@
 	struct cf_trailer_entry *trailer_start, *trailer_stop;
 	struct cf_ctrset_entry *ctrstart, *ctrstop;
 	size_t offset = 0;
+	int i;
 
-	auth &= (1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1;
-	do {
+	for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) {
 		ctrstart = (struct cf_ctrset_entry *)(cpuhw->start + offset);
 		ctrstop = (struct cf_ctrset_entry *)(cpuhw->stop + offset);
 
+		/* Counter set not authorized */
+		if (!(auth & cpumf_ctr_ctl[i]))
+			continue;
+		/* Counter set size zero was not saved */
+		if (!cpum_cf_read_setsize(i))
+			continue;
+
 		if (memcmp(ctrstop, ctrstart, sizeof(*ctrstop))) {
 			pr_err_once("cpum_cf_diag counter set compare error "
 				    "in set %i\n", ctrstart->set);
 			return 0;
 		}
-		auth &= ~cpumf_ctr_ctl[ctrstart->set];
 		if (ctrstart->def == CF_DIAG_CTRSET_DEF) {
 			cfdiag_diffctrset((u64 *)(ctrstart + 1),
 					  (u64 *)(ctrstop + 1), ctrstart->ctr);
 			offset += ctrstart->ctr * sizeof(u64) +
 							sizeof(*ctrstart);
 		}
-	} while (ctrstart->def && auth);
+	}
 
 	/* Save time_stamp from start of event in stop's trailer */
 	trailer_start = (struct cf_trailer_entry *)(cpuhw->start + offset);
@@ -971,7 +977,7 @@
 	if (event->attr.sample_type & PERF_SAMPLE_RAW) {
 		raw.frag.size = cpuhw->usedss;
 		raw.frag.data = cpuhw->stop;
-		perf_sample_save_raw_data(&data, &raw);
+		perf_sample_save_raw_data(&data, event, &raw);
 	}
 
 	overflow = perf_event_overflow(event, &data, &regs);
--- linux-qcom-6.8.0.orig/arch/s390/kernel/perf_cpum_cf_events.c
+++ linux-qcom-6.8.0/arch/s390/kernel/perf_cpum_cf_events.c
@@ -855,16 +855,11 @@
 	}
 
 	/* Determine version specific crypto set */
-	switch (ci.csvn) {
-	case 1 ... 5:
+	csvn = none;
+	if (ci.csvn >= 1 && ci.csvn <= 5)
 		csvn = cpumcf_svn_12345_pmu_event_attr;
-		break;
-	case 6 ... 7:
+	else if (ci.csvn >= 6)
 		csvn = cpumcf_svn_67_pmu_event_attr;
-		break;
-	default:
-		csvn = none;
-	}
 
 	/* Determine model-specific counter set(s) */
 	get_cpu_id(&cpu_id);
--- linux-qcom-6.8.0.orig/arch/s390/kernel/perf_cpum_sf.c
+++ linux-qcom-6.8.0/arch/s390/kernel/perf_cpum_sf.c
@@ -1463,7 +1463,7 @@
 	unsigned long range, i, range_scan, idx, head, base, offset;
 	struct hws_trailer_entry *te;
 
-	if (WARN_ON_ONCE(handle->head & ~PAGE_MASK))
+	if (handle->head & ~PAGE_MASK)
 		return -EINVAL;
 
 	aux->head = handle->head >> PAGE_SHIFT;
@@ -1642,7 +1642,7 @@
 	unsigned long num_sdb;
 
 	aux = perf_get_aux(handle);
-	if (WARN_ON_ONCE(!aux))
+	if (!aux)
 		return;
 
 	/* Inform user space new data arrived */
@@ -1661,7 +1661,7 @@
 				num_sdb);
 			break;
 		}
-		if (WARN_ON_ONCE(!aux))
+		if (!aux)
 			return;
 
 		/* Update head and alert_mark to new position */
@@ -1896,12 +1896,8 @@
 {
 	struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf);
 
-	if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED)))
+	if (!(event->hw.state & PERF_HES_STOPPED))
 		return;
-
-	if (flags & PERF_EF_RELOAD)
-		WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
-
 	perf_pmu_disable(event->pmu);
 	event->hw.state = 0;
 	cpuhw->lsctl.cs = 1;
@@ -1926,7 +1922,9 @@
 	event->hw.state |= PERF_HES_STOPPED;
 
 	if ((flags & PERF_EF_UPDATE) && !(event->hw.state & PERF_HES_UPTODATE)) {
-		hw_perf_event_update(event, 1);
+		/* CPU hotplug off removes SDBs. No samples to extract. */
+		if (cpuhw->flags & PMU_F_RESERVED)
+			hw_perf_event_update(event, 1);
 		event->hw.state |= PERF_HES_UPTODATE;
 	}
 	perf_pmu_enable(event->pmu);
--- linux-qcom-6.8.0.orig/arch/s390/kernel/perf_event.c
+++ linux-qcom-6.8.0/arch/s390/kernel/perf_event.c
@@ -218,39 +218,7 @@
 void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 			 struct pt_regs *regs)
 {
-	struct stack_frame_user __user *sf;
-	unsigned long ip, sp;
-	bool first = true;
-
-	if (is_compat_task())
-		return;
-	perf_callchain_store(entry, instruction_pointer(regs));
-	sf = (void __user *)user_stack_pointer(regs);
-	pagefault_disable();
-	while (entry->nr < entry->max_stack) {
-		if (__get_user(sp, &sf->back_chain))
-			break;
-		if (__get_user(ip, &sf->gprs[8]))
-			break;
-		if (ip & 0x1) {
-			/*
-			 * If the instruction address is invalid, and this
-			 * is the first stack frame, assume r14 has not
-			 * been written to the stack yet. Otherwise exit.
-			 */
-			if (first && !(regs->gprs[14] & 0x1))
-				ip = regs->gprs[14];
-			else
-				break;
-		}
-		perf_callchain_store(entry, ip);
-		/* Sanity check: ABI requires SP to be aligned 8 bytes. */
-		if (!sp || sp & 0x7)
-			break;
-		sf = (void __user *)sp;
-		first = false;
-	}
-	pagefault_enable();
+	arch_stack_walk_user_common(NULL, NULL, entry, regs, true);
 }
 
 /* Perf definitions for PMU event attributes in sysfs */
--- linux-qcom-6.8.0.orig/arch/s390/kernel/perf_pai_crypto.c
+++ linux-qcom-6.8.0/arch/s390/kernel/perf_pai_crypto.c
@@ -90,7 +90,6 @@
 						 event->cpu);
 	struct paicrypt_map *cpump = mp->mapptr;
 
-	cpump->event = NULL;
 	static_branch_dec(&pai_key);
 	mutex_lock(&pai_reserve_mutex);
 	debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d"
@@ -348,10 +347,15 @@
 
 static void paicrypt_stop(struct perf_event *event, int flags)
 {
-	if (!event->attr.sample_period)	/* Counting */
+	struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr);
+	struct paicrypt_map *cpump = mp->mapptr;
+
+	if (!event->attr.sample_period) {	/* Counting */
 		paicrypt_read(event);
-	else				/* Sampling */
+	} else {				/* Sampling */
 		perf_sched_cb_dec(event->pmu);
+		cpump->event = NULL;
+	}
 	event->hw.state = PERF_HES_STOPPED;
 }
 
@@ -421,7 +425,7 @@
 	if (event->attr.sample_type & PERF_SAMPLE_RAW) {
 		raw.frag.size = rawsize;
 		raw.frag.data = cpump->save;
-		perf_sample_save_raw_data(&data, &raw);
+		perf_sample_save_raw_data(&data, event, &raw);
 	}
 
 	overflow = perf_event_overflow(event, &data, &regs);
@@ -721,7 +725,7 @@
 	for (i = 0; i < ARRAY_SIZE(paicrypt_ctrnames); i++) {
 		ret = attr_event_init_one(attrs, i);
 		if (ret) {
-			attr_event_free(attrs, i - 1);
+			attr_event_free(attrs, i);
 			return ret;
 		}
 	}
--- linux-qcom-6.8.0.orig/arch/s390/kernel/perf_pai_ext.c
+++ linux-qcom-6.8.0/arch/s390/kernel/perf_pai_ext.c
@@ -121,7 +121,6 @@
 	struct paiext_map *cpump = mp->mapptr;
 
 	mutex_lock(&paiext_reserve_mutex);
-	cpump->event = NULL;
 	if (refcount_dec_and_test(&cpump->refcnt))	/* Last reference gone */
 		paiext_free(mp);
 	paiext_root_free();
@@ -355,10 +354,15 @@
 
 static void paiext_stop(struct perf_event *event, int flags)
 {
-	if (!event->attr.sample_period)	/* Counting */
+	struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
+	struct paiext_map *cpump = mp->mapptr;
+
+	if (!event->attr.sample_period) {	/* Counting */
 		paiext_read(event);
-	else				/* Sampling */
+	} else {				/* Sampling */
 		perf_sched_cb_dec(event->pmu);
+		cpump->event = NULL;
+	}
 	event->hw.state = PERF_HES_STOPPED;
 }
 
@@ -441,7 +445,7 @@
 	if (event->attr.sample_type & PERF_SAMPLE_RAW) {
 		raw.frag.size = rawsize;
 		raw.frag.data = cpump->save;
-		perf_sample_save_raw_data(&data, &raw);
+		perf_sample_save_raw_data(&data, event, &raw);
 	}
 
 	overflow = perf_event_overflow(event, &data, &regs);
@@ -611,7 +615,7 @@
 	for (i = 0; i < ARRAY_SIZE(paiext_ctrnames); i++) {
 		ret = attr_event_init_one(attrs, i);
 		if (ret) {
-			attr_event_free(attrs, i - 1);
+			attr_event_free(attrs, i);
 			return ret;
 		}
 	}
--- linux-qcom-6.8.0.orig/arch/s390/kernel/setup.c
+++ linux-qcom-6.8.0/arch/s390/kernel/setup.c
@@ -51,6 +51,7 @@
 #include <linux/start_kernel.h>
 #include <linux/hugetlb.h>
 #include <linux/kmemleak.h>
+#include <linux/security.h>
 
 #include <asm/archrandom.h>
 #include <asm/boot_data.h>
@@ -155,7 +156,7 @@
 EXPORT_SYMBOL(zlib_dfltcc_support);
 u64 __bootdata_preserved(stfle_fac_list[16]);
 EXPORT_SYMBOL(stfle_fac_list);
-u64 __bootdata_preserved(alt_stfle_fac_list[16]);
+u64 alt_stfle_fac_list[16];
 struct oldmem_data __bootdata_preserved(oldmem_data);
 
 unsigned long VMALLOC_START;
@@ -891,6 +892,9 @@
 
 	log_component_list();
 
+	if (ipl_get_secureboot())
+		security_lock_kernel_down("Secure IPL mode", LOCKDOWN_INTEGRITY_MAX);
+
 	/* Have one command line that is parsed and saved in /proc/cmdline */
 	/* boot_command_line has been already set up in early.c */
 	*cmdline_p = boot_command_line;
--- linux-qcom-6.8.0.orig/arch/s390/kernel/stacktrace.c
+++ linux-qcom-6.8.0/arch/s390/kernel/stacktrace.c
@@ -5,6 +5,7 @@
  *  Copyright IBM Corp. 2006
  */
 
+#include <linux/perf_event.h>
 #include <linux/stacktrace.h>
 #include <linux/uaccess.h>
 #include <linux/compat.h>
@@ -62,42 +63,102 @@
 	return 0;
 }
 
-void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie,
-			  const struct pt_regs *regs)
+static inline bool store_ip(stack_trace_consume_fn consume_entry, void *cookie,
+			    struct perf_callchain_entry_ctx *entry, bool perf,
+			    unsigned long ip)
+{
+#ifdef CONFIG_PERF_EVENTS
+	if (perf) {
+		if (perf_callchain_store(entry, ip))
+			return false;
+		return true;
+	}
+#endif
+	return consume_entry(cookie, ip);
+}
+
+static inline bool ip_invalid(unsigned long ip)
 {
+	/*
+	 * Perform some basic checks if an instruction address taken
+	 * from unreliable source is invalid.
+	 */
+	if (ip & 1)
+		return true;
+	if (ip < mmap_min_addr)
+		return true;
+	if (ip >= current->mm->context.asce_limit)
+		return true;
+	return false;
+}
+
+static inline bool ip_within_vdso(unsigned long ip)
+{
+	return in_range(ip, current->mm->context.vdso_base, vdso_text_size());
+}
+
+void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *cookie,
+				 struct perf_callchain_entry_ctx *entry,
+				 const struct pt_regs *regs, bool perf)
+{
+	struct stack_frame_vdso_wrapper __user *sf_vdso;
 	struct stack_frame_user __user *sf;
 	unsigned long ip, sp;
 	bool first = true;
 
 	if (is_compat_task())
 		return;
-	if (!consume_entry(cookie, instruction_pointer(regs)))
+	if (!current->mm)
+		return;
+	ip = instruction_pointer(regs);
+	if (!store_ip(consume_entry, cookie, entry, perf, ip))
 		return;
 	sf = (void __user *)user_stack_pointer(regs);
 	pagefault_disable();
 	while (1) {
 		if (__get_user(sp, &sf->back_chain))
 			break;
-		if (__get_user(ip, &sf->gprs[8]))
+		/*
+		 * VDSO entry code has a non-standard stack frame layout.
+		 * See VDSO user wrapper code for details.
+		 */
+		if (!sp && ip_within_vdso(ip)) {
+			sf_vdso = (void __user *)sf;
+			if (__get_user(ip, &sf_vdso->return_address))
+				break;
+			sp = (unsigned long)sf + STACK_FRAME_VDSO_OVERHEAD;
+			sf = (void __user *)sp;
+			if (__get_user(sp, &sf->back_chain))
+				break;
+		} else {
+			sf = (void __user *)sp;
+			if (__get_user(ip, &sf->gprs[8]))
+				break;
+		}
+		/* Sanity check: ABI requires SP to be 8 byte aligned. */
+		if (sp & 0x7)
 			break;
-		if (ip & 0x1) {
+		if (ip_invalid(ip)) {
 			/*
 			 * If the instruction address is invalid, and this
 			 * is the first stack frame, assume r14 has not
 			 * been written to the stack yet. Otherwise exit.
 			 */
-			if (first && !(regs->gprs[14] & 0x1))
-				ip = regs->gprs[14];
-			else
+			if (!first)
+				break;
+			ip = regs->gprs[14];
+			if (ip_invalid(ip))
 				break;
 		}
-		if (!consume_entry(cookie, ip))
+		if (!store_ip(consume_entry, cookie, entry, perf, ip))
 			break;
-		/* Sanity check: ABI requires SP to be aligned 8 bytes. */
-		if (!sp || sp & 0x7)
-			break;
-		sf = (void __user *)sp;
 		first = false;
 	}
 	pagefault_enable();
 }
+
+void arch_stack_walk_user(stack_trace_consume_fn consume_entry, void *cookie,
+			  const struct pt_regs *regs)
+{
+	arch_stack_walk_user_common(consume_entry, cookie, NULL, regs, false);
+}
--- linux-qcom-6.8.0.orig/arch/s390/kernel/syscalls/Makefile
+++ linux-qcom-6.8.0/arch/s390/kernel/syscalls/Makefile
@@ -12,7 +12,7 @@
 uapi-hdrs-y := $(uapi)/unistd_32.h
 uapi-hdrs-y += $(uapi)/unistd_64.h
 
-targets += $(addprefix ../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y))
+targets += $(addprefix ../../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y))
 
 PHONY += kapi uapi
 
--- linux-qcom-6.8.0.orig/arch/s390/kernel/syscalls/syscall.tbl
+++ linux-qcom-6.8.0/arch/s390/kernel/syscalls/syscall.tbl
@@ -418,7 +418,7 @@
 412	32	utimensat_time64	-				sys_utimensat
 413	32	pselect6_time64		-				compat_sys_pselect6_time64
 414	32	ppoll_time64		-				compat_sys_ppoll_time64
-416	32	io_pgetevents_time64	-				sys_io_pgetevents
+416	32	io_pgetevents_time64	-				compat_sys_io_pgetevents_time64
 417	32	recvmmsg_time64		-				compat_sys_recvmmsg_time64
 418	32	mq_timedsend_time64	-				sys_mq_timedsend
 419	32	mq_timedreceive_time64	-				sys_mq_timedreceive
--- linux-qcom-6.8.0.orig/arch/s390/kernel/uv.c
+++ linux-qcom-6.8.0/arch/s390/kernel/uv.c
@@ -181,36 +181,36 @@
 }
 
 /*
- * Calculate the expected ref_count for a page that would otherwise have no
+ * Calculate the expected ref_count for a folio that would otherwise have no
  * further pins. This was cribbed from similar functions in other places in
  * the kernel, but with some slight modifications. We know that a secure
- * page can not be a huge page for example.
+ * folio can not be a large folio, for example.
  */
-static int expected_page_refs(struct page *page)
+static int expected_folio_refs(struct folio *folio)
 {
 	int res;
 
-	res = page_mapcount(page);
-	if (PageSwapCache(page)) {
+	res = folio_mapcount(folio);
+	if (folio_test_swapcache(folio)) {
 		res++;
-	} else if (page_mapping(page)) {
+	} else if (folio_mapping(folio)) {
 		res++;
-		if (page_has_private(page))
+		if (folio->private)
 			res++;
 	}
 	return res;
 }
 
-static int make_page_secure(struct page *page, struct uv_cb_header *uvcb)
+static int make_folio_secure(struct folio *folio, struct uv_cb_header *uvcb)
 {
 	int expected, cc = 0;
 
-	if (PageWriteback(page))
+	if (folio_test_writeback(folio))
 		return -EAGAIN;
-	expected = expected_page_refs(page);
-	if (!page_ref_freeze(page, expected))
+	expected = expected_folio_refs(folio);
+	if (!folio_ref_freeze(folio, expected))
 		return -EBUSY;
-	set_bit(PG_arch_1, &page->flags);
+	set_bit(PG_arch_1, &folio->flags);
 	/*
 	 * If the UVC does not succeed or fail immediately, we don't want to
 	 * loop for long, or we might get stall notifications.
@@ -220,9 +220,9 @@
 	 * -EAGAIN and we let the callers deal with it.
 	 */
 	cc = __uv_call(0, (u64)uvcb);
-	page_ref_unfreeze(page, expected);
+	folio_ref_unfreeze(folio, expected);
 	/*
-	 * Return -ENXIO if the page was not mapped, -EINVAL for other errors.
+	 * Return -ENXIO if the folio was not mapped, -EINVAL for other errors.
 	 * If busy or partially completed, return -EAGAIN.
 	 */
 	if (cc == UVC_CC_OK)
@@ -277,7 +277,7 @@
 	bool local_drain = false;
 	spinlock_t *ptelock;
 	unsigned long uaddr;
-	struct page *page;
+	struct folio *folio;
 	pte_t *ptep;
 	int rc;
 
@@ -306,15 +306,26 @@
 	if (!ptep)
 		goto out;
 	if (pte_present(*ptep) && !(pte_val(*ptep) & _PAGE_INVALID) && pte_write(*ptep)) {
-		page = pte_page(*ptep);
+		folio = page_folio(pte_page(*ptep));
+		rc = -EINVAL;
+		if (folio_test_large(folio))
+			goto unlock;
 		rc = -EAGAIN;
-		if (trylock_page(page)) {
+		if (folio_trylock(folio)) {
 			if (should_export_before_import(uvcb, gmap->mm))
-				uv_convert_from_secure(page_to_phys(page));
-			rc = make_page_secure(page, uvcb);
-			unlock_page(page);
+				uv_convert_from_secure(PFN_PHYS(folio_pfn(folio)));
+			rc = make_folio_secure(folio, uvcb);
+			folio_unlock(folio);
 		}
+
+		/*
+		 * Once we drop the PTL, the folio may get unmapped and
+		 * freed immediately. We need a temporary reference.
+		 */
+		if (rc == -EAGAIN)
+			folio_get(folio);
 	}
+unlock:
 	pte_unmap_unlock(ptep, ptelock);
 out:
 	mmap_read_unlock(gmap->mm);
@@ -324,10 +335,11 @@
 		 * If we are here because the UVC returned busy or partial
 		 * completion, this is just a useless check, but it is safe.
 		 */
-		wait_on_page_writeback(page);
+		folio_wait_writeback(folio);
+		folio_put(folio);
 	} else if (rc == -EBUSY) {
 		/*
-		 * If we have tried a local drain and the page refcount
+		 * If we have tried a local drain and the folio refcount
 		 * still does not match our expected safe value, try with a
 		 * system wide drain. This is needed if the pagevecs holding
 		 * the page are on a different CPU.
@@ -338,7 +350,7 @@
 			return -EAGAIN;
 		}
 		/*
-		 * We are here if the page refcount does not match the
+		 * We are here if the folio refcount does not match the
 		 * expected safe value. The main culprits are usually
 		 * pagevecs. With lru_add_drain() we drain the pagevecs
 		 * on the local CPU so that hopefully the refcount will
--- linux-qcom-6.8.0.orig/arch/s390/kernel/vdso.c
+++ linux-qcom-6.8.0/arch/s390/kernel/vdso.c
@@ -213,17 +213,22 @@
 	return addr;
 }
 
-unsigned long vdso_size(void)
+unsigned long vdso_text_size(void)
 {
-	unsigned long size = VVAR_NR_PAGES * PAGE_SIZE;
+	unsigned long size;
 
 	if (is_compat_task())
-		size += vdso32_end - vdso32_start;
+		size = vdso32_end - vdso32_start;
 	else
-		size += vdso64_end - vdso64_start;
+		size = vdso64_end - vdso64_start;
 	return PAGE_ALIGN(size);
 }
 
+unsigned long vdso_size(void)
+{
+	return vdso_text_size() + VVAR_NR_PAGES * PAGE_SIZE;
+}
+
 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 {
 	unsigned long addr = VDSO_BASE;
--- linux-qcom-6.8.0.orig/arch/s390/kernel/vdso32/Makefile
+++ linux-qcom-6.8.0/arch/s390/kernel/vdso32/Makefile
@@ -19,10 +19,12 @@
 KBUILD_AFLAGS_32 += -m31 -s
 
 KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
+KBUILD_CFLAGS_32 := $(filter-out -mpacked-stack,$(KBUILD_CFLAGS))
 KBUILD_CFLAGS_32 := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_32))
-KBUILD_CFLAGS_32 += -m31 -fPIC -shared -fno-common -fno-builtin
+KBUILD_CFLAGS_32 := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_32))
+KBUILD_CFLAGS_32 += -m31 -fPIC -shared -fno-common -fno-builtin -fasynchronous-unwind-tables
 
-LDFLAGS_vdso32.so.dbg += -fPIC -shared -soname=linux-vdso32.so.1 \
+LDFLAGS_vdso32.so.dbg += -shared -soname=linux-vdso32.so.1 \
 	--hash-style=both --build-id=sha1 -melf_s390 -T
 
 $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_32)
--- linux-qcom-6.8.0.orig/arch/s390/kernel/vdso64/Makefile
+++ linux-qcom-6.8.0/arch/s390/kernel/vdso64/Makefile
@@ -24,9 +24,12 @@
 KBUILD_AFLAGS_64 += -m64
 
 KBUILD_CFLAGS_64 := $(filter-out -m64,$(KBUILD_CFLAGS))
+KBUILD_CFLAGS_64 := $(filter-out -mpacked-stack,$(KBUILD_CFLAGS_64))
 KBUILD_CFLAGS_64 := $(filter-out -mno-pic-data-is-text-relative,$(KBUILD_CFLAGS_64))
-KBUILD_CFLAGS_64 += -m64 -fPIC -fno-common -fno-builtin
-ldflags-y := -fPIC -shared -soname=linux-vdso64.so.1 \
+KBUILD_CFLAGS_64 := $(filter-out -munaligned-symbols,$(KBUILD_CFLAGS_64))
+KBUILD_CFLAGS_64 := $(filter-out -fno-asynchronous-unwind-tables,$(KBUILD_CFLAGS_64))
+KBUILD_CFLAGS_64 += -m64 -fPIC -fno-common -fno-builtin -fasynchronous-unwind-tables
+ldflags-y := -shared -soname=linux-vdso64.so.1 \
 	     --hash-style=both --build-id=sha1 -T
 
 $(targets:%=$(obj)/%.dbg): KBUILD_CFLAGS = $(KBUILD_CFLAGS_64)
--- linux-qcom-6.8.0.orig/arch/s390/kernel/vdso64/vdso_user_wrapper.S
+++ linux-qcom-6.8.0/arch/s390/kernel/vdso64/vdso_user_wrapper.S
@@ -6,8 +6,6 @@
 #include <asm/dwarf.h>
 #include <asm/ptrace.h>
 
-#define WRAPPER_FRAME_SIZE (STACK_FRAME_OVERHEAD+8)
-
 /*
  * Older glibc version called vdso without allocating a stackframe. This wrapper
  * is just used to allocate a stackframe. See
@@ -20,14 +18,17 @@
 	__ALIGN
 __kernel_\func:
 	CFI_STARTPROC
-	aghi	%r15,-WRAPPER_FRAME_SIZE
-	CFI_DEF_CFA_OFFSET (STACK_FRAME_OVERHEAD + WRAPPER_FRAME_SIZE)
-	CFI_VAL_OFFSET 15, -STACK_FRAME_OVERHEAD
-	stg	%r14,STACK_FRAME_OVERHEAD(%r15)
+	aghi	%r15,-STACK_FRAME_VDSO_OVERHEAD
+	CFI_DEF_CFA_OFFSET (STACK_FRAME_USER_OVERHEAD + STACK_FRAME_VDSO_OVERHEAD)
+	CFI_VAL_OFFSET 15,-STACK_FRAME_USER_OVERHEAD
+	stg	%r14,__SFVDSO_RETURN_ADDRESS(%r15)
+	CFI_REL_OFFSET 14,__SFVDSO_RETURN_ADDRESS
+	xc	__SFUSER_BACKCHAIN(8,%r15),__SFUSER_BACKCHAIN(%r15)
 	brasl	%r14,__s390_vdso_\func
-	lg	%r14,STACK_FRAME_OVERHEAD(%r15)
-	aghi	%r15,WRAPPER_FRAME_SIZE
-	CFI_DEF_CFA_OFFSET STACK_FRAME_OVERHEAD
+	lg	%r14,__SFVDSO_RETURN_ADDRESS(%r15)
+	CFI_RESTORE 14
+	aghi	%r15,STACK_FRAME_VDSO_OVERHEAD
+	CFI_DEF_CFA_OFFSET STACK_FRAME_USER_OVERHEAD
 	CFI_RESTORE 15
 	br	%r14
 	CFI_ENDPROC
--- linux-qcom-6.8.0.orig/arch/s390/kernel/vmlinux.lds.S
+++ linux-qcom-6.8.0/arch/s390/kernel/vmlinux.lds.S
@@ -72,6 +72,15 @@
 	. = ALIGN(PAGE_SIZE);
 	__end_ro_after_init = .;
 
+	.data.rel.ro : {
+		*(.data.rel.ro .data.rel.ro.*)
+	}
+	.got : {
+		__got_start = .;
+		*(.got)
+		__got_end = .;
+	}
+
 	RW_DATA(0x100, PAGE_SIZE, THREAD_SIZE)
 	BOOT_DATA_PRESERVED
 
--- linux-qcom-6.8.0.orig/arch/s390/kernel/vtime.c
+++ linux-qcom-6.8.0/arch/s390/kernel/vtime.c
@@ -210,13 +210,13 @@
 		virt_timer_expire();
 
 	steal = S390_lowcore.steal_timer;
-	avg_steal = S390_lowcore.avg_steal_timer / 2;
+	avg_steal = S390_lowcore.avg_steal_timer;
 	if ((s64) steal > 0) {
 		S390_lowcore.steal_timer = 0;
 		account_steal_time(cputime_to_nsecs(steal));
 		avg_steal += steal;
 	}
-	S390_lowcore.avg_steal_timer = avg_steal;
+	S390_lowcore.avg_steal_timer = avg_steal / 2;
 }
 
 static u64 vtime_delta(void)
--- linux-qcom-6.8.0.orig/arch/s390/kvm/diag.c
+++ linux-qcom-6.8.0/arch/s390/kvm/diag.c
@@ -77,7 +77,7 @@
 	vcpu->stat.instruction_diagnose_258++;
 	if (vcpu->run->s.regs.gprs[rx] & 7)
 		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
-	rc = read_guest(vcpu, vcpu->run->s.regs.gprs[rx], rx, &parm, sizeof(parm));
+	rc = read_guest_real(vcpu, vcpu->run->s.regs.gprs[rx], &parm, sizeof(parm));
 	if (rc)
 		return kvm_s390_inject_prog_cond(vcpu, rc);
 	if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258)
--- linux-qcom-6.8.0.orig/arch/s390/kvm/gaccess.c
+++ linux-qcom-6.8.0/arch/s390/kvm/gaccess.c
@@ -984,6 +984,8 @@
 	const gfn_t gfn = gpa_to_gfn(gpa);
 	int rc;
 
+	if (!gfn_to_memslot(kvm, gfn))
+		return PGM_ADDRESSING;
 	if (mode == GACC_STORE)
 		rc = kvm_write_guest_page(kvm, gfn, data, offset, len);
 	else
@@ -1141,6 +1143,8 @@
 		gra += fragment_len;
 		data += fragment_len;
 	}
+	if (rc > 0)
+		vcpu->arch.pgm.code = rc;
 	return rc;
 }
 
--- linux-qcom-6.8.0.orig/arch/s390/kvm/gaccess.h
+++ linux-qcom-6.8.0/arch/s390/kvm/gaccess.h
@@ -405,11 +405,12 @@
  * @len: number of bytes to copy
  *
  * Copy @len bytes from @data (kernel space) to @gra (guest real address).
- * It is up to the caller to ensure that the entire guest memory range is
- * valid memory before calling this function.
  * Guest low address and key protection are not checked.
  *
- * Returns zero on success or -EFAULT on error.
+ * Returns zero on success, -EFAULT when copying from @data failed, or
+ * PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info
+ * is also stored to allow injecting into the guest (if applicable) using
+ * kvm_s390_inject_prog_cond().
  *
  * If an error occurs data may have been copied partially to guest memory.
  */
@@ -428,11 +429,12 @@
  * @len: number of bytes to copy
  *
  * Copy @len bytes from @gra (guest real address) to @data (kernel space).
- * It is up to the caller to ensure that the entire guest memory range is
- * valid memory before calling this function.
  * Guest key protection is not checked.
  *
- * Returns zero on success or -EFAULT on error.
+ * Returns zero on success, -EFAULT when copying to @data failed, or
+ * PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info
+ * is also stored to allow injecting into the guest (if applicable) using
+ * kvm_s390_inject_prog_cond().
  *
  * If an error occurs data may have been copied partially to kernel space.
  */
--- linux-qcom-6.8.0.orig/arch/s390/kvm/kvm-s390.c
+++ linux-qcom-6.8.0/arch/s390/kvm/kvm-s390.c
@@ -132,6 +132,7 @@
 	STATS_DESC_COUNTER(VCPU, instruction_io_other),
 	STATS_DESC_COUNTER(VCPU, instruction_lpsw),
 	STATS_DESC_COUNTER(VCPU, instruction_lpswe),
+	STATS_DESC_COUNTER(VCPU, instruction_lpswey),
 	STATS_DESC_COUNTER(VCPU, instruction_pfmf),
 	STATS_DESC_COUNTER(VCPU, instruction_ptff),
 	STATS_DESC_COUNTER(VCPU, instruction_sck),
@@ -2631,9 +2632,7 @@
 		if (r)
 			break;
 
-		mmap_write_lock(current->mm);
-		r = gmap_mark_unmergeable();
-		mmap_write_unlock(current->mm);
+		r = s390_disable_cow_sharing();
 		if (r)
 			break;
 
@@ -5761,6 +5760,9 @@
 {
 	gpa_t size;
 
+	if (kvm_is_ucontrol(kvm))
+		return -EINVAL;
+
 	/* When we are protected, we should not change the memory slots */
 	if (kvm_s390_pv_get_handle(kvm))
 		return -EINVAL;
--- linux-qcom-6.8.0.orig/arch/s390/kvm/kvm-s390.h
+++ linux-qcom-6.8.0/arch/s390/kvm/kvm-s390.h
@@ -120,6 +120,21 @@
 	return (base2 ? vcpu->run->s.regs.gprs[base2] : 0) + disp2;
 }
 
+static inline u64 kvm_s390_get_base_disp_siy(struct kvm_vcpu *vcpu, u8 *ar)
+{
+	u32 base1 = vcpu->arch.sie_block->ipb >> 28;
+	s64 disp1;
+
+	/* The displacement is a 20bit _SIGNED_ value */
+	disp1 = sign_extend64(((vcpu->arch.sie_block->ipb & 0x0fff0000) >> 16) +
+			      ((vcpu->arch.sie_block->ipb & 0xff00) << 4), 19);
+
+	if (ar)
+		*ar = base1;
+
+	return (base1 ? vcpu->run->s.regs.gprs[base1] : 0) + disp1;
+}
+
 static inline void kvm_s390_get_base_disp_sse(struct kvm_vcpu *vcpu,
 					      u64 *address1, u64 *address2,
 					      u8 *ar_b1, u8 *ar_b2)
@@ -234,7 +249,12 @@
 
 static inline u32 kvm_s390_get_gisa_desc(struct kvm *kvm)
 {
-	u32 gd = virt_to_phys(kvm->arch.gisa_int.origin);
+	u32 gd;
+
+	if (!kvm->arch.gisa_int.origin)
+		return 0;
+
+	gd = virt_to_phys(kvm->arch.gisa_int.origin);
 
 	if (gd && sclp.has_gisaf)
 		gd |= GISA_FORMAT1;
--- linux-qcom-6.8.0.orig/arch/s390/kvm/priv.c
+++ linux-qcom-6.8.0/arch/s390/kvm/priv.c
@@ -797,6 +797,36 @@
 	return 0;
 }
 
+static int handle_lpswey(struct kvm_vcpu *vcpu)
+{
+	psw_t new_psw;
+	u64 addr;
+	int rc;
+	u8 ar;
+
+	vcpu->stat.instruction_lpswey++;
+
+	if (!test_kvm_facility(vcpu->kvm, 193))
+		return kvm_s390_inject_program_int(vcpu, PGM_OPERATION);
+
+	if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE)
+		return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP);
+
+	addr = kvm_s390_get_base_disp_siy(vcpu, &ar);
+	if (addr & 7)
+		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
+	rc = read_guest(vcpu, addr, ar, &new_psw, sizeof(new_psw));
+	if (rc)
+		return kvm_s390_inject_prog_cond(vcpu, rc);
+
+	vcpu->arch.sie_block->gpsw = new_psw;
+	if (!is_valid_psw(&vcpu->arch.sie_block->gpsw))
+		return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
+
+	return 0;
+}
+
 static int handle_stidp(struct kvm_vcpu *vcpu)
 {
 	u64 stidp_data = vcpu->kvm->arch.model.cpuid;
@@ -1462,6 +1492,8 @@
 	case 0x61:
 	case 0x62:
 		return handle_ri(vcpu);
+	case 0x71:
+		return handle_lpswey(vcpu);
 	default:
 		return -EOPNOTSUPP;
 	}
--- linux-qcom-6.8.0.orig/arch/s390/kvm/vsie.c
+++ linux-qcom-6.8.0/arch/s390/kvm/vsie.c
@@ -1350,8 +1350,14 @@
 	page = radix_tree_lookup(&kvm->arch.vsie.addr_to_page, addr >> 9);
 	rcu_read_unlock();
 	if (page) {
-		if (page_ref_inc_return(page) == 2)
-			return page_to_virt(page);
+		if (page_ref_inc_return(page) == 2) {
+			if (page->index == addr)
+				return page_to_virt(page);
+			/*
+			 * We raced with someone reusing + putting this vsie
+			 * page before we grabbed it.
+			 */
+		}
 		page_ref_dec(page);
 	}
 
@@ -1381,15 +1387,20 @@
 			kvm->arch.vsie.next++;
 			kvm->arch.vsie.next %= nr_vcpus;
 		}
-		radix_tree_delete(&kvm->arch.vsie.addr_to_page, page->index >> 9);
+		if (page->index != ULONG_MAX)
+			radix_tree_delete(&kvm->arch.vsie.addr_to_page,
+					  page->index >> 9);
 	}
-	page->index = addr;
-	/* double use of the same address */
+	/* Mark it as invalid until it resides in the tree. */
+	page->index = ULONG_MAX;
+
+	/* Double use of the same address or allocation failure. */
 	if (radix_tree_insert(&kvm->arch.vsie.addr_to_page, addr >> 9, page)) {
 		page_ref_dec(page);
 		mutex_unlock(&kvm->arch.vsie.mutex);
 		return NULL;
 	}
+	page->index = addr;
 	mutex_unlock(&kvm->arch.vsie.mutex);
 
 	vsie_page = page_to_virt(page);
@@ -1482,7 +1493,9 @@
 		vsie_page = page_to_virt(page);
 		release_gmap_shadow(vsie_page);
 		/* free the radix tree entry */
-		radix_tree_delete(&kvm->arch.vsie.addr_to_page, page->index >> 9);
+		if (page->index != ULONG_MAX)
+			radix_tree_delete(&kvm->arch.vsie.addr_to_page,
+					  page->index >> 9);
 		__free_page(page);
 	}
 	kvm->arch.vsie.page_count = 0;
--- linux-qcom-6.8.0.orig/arch/s390/mm/cmm.c
+++ linux-qcom-6.8.0/arch/s390/mm/cmm.c
@@ -95,11 +95,12 @@
 		(*counter)++;
 		spin_unlock(&cmm_lock);
 		nr--;
+		cond_resched();
 	}
 	return nr;
 }
 
-static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
+static long __cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
 {
 	struct cmm_page_array *pa;
 	unsigned long addr;
@@ -123,6 +124,21 @@
 	return nr;
 }
 
+static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list)
+{
+	long inc = 0;
+
+	while (nr) {
+		inc = min(256L, nr);
+		nr -= inc;
+		inc = __cmm_free_pages(inc, counter, list);
+		if (inc)
+			break;
+		cond_resched();
+	}
+	return nr + inc;
+}
+
 static int cmm_oom_notify(struct notifier_block *self,
 			  unsigned long dummy, void *parm)
 {
--- linux-qcom-6.8.0.orig/arch/s390/mm/fault.c
+++ linux-qcom-6.8.0/arch/s390/mm/fault.c
@@ -430,12 +430,13 @@
 			handle_fault_error_nolock(regs, 0);
 		else
 			do_sigsegv(regs, SEGV_MAPERR);
-	} else if (fault & VM_FAULT_SIGBUS) {
+	} else if (fault & (VM_FAULT_SIGBUS | VM_FAULT_HWPOISON)) {
 		if (!user_mode(regs))
 			handle_fault_error_nolock(regs, 0);
 		else
 			do_sigbus(regs);
 	} else {
+		pr_emerg("Unexpected fault flags: %08x\n", fault);
 		BUG();
 	}
 }
--- linux-qcom-6.8.0.orig/arch/s390/mm/gmap.c
+++ linux-qcom-6.8.0/arch/s390/mm/gmap.c
@@ -596,7 +596,7 @@
 	pud = pud_offset(p4d, vmaddr);
 	VM_BUG_ON(pud_none(*pud));
 	/* large puds cannot yet be handled */
-	if (pud_large(*pud))
+	if (pud_leaf(*pud))
 		return -EFAULT;
 	pmd = pmd_offset(pud, vmaddr);
 	VM_BUG_ON(pmd_none(*pmd));
@@ -2548,41 +2548,6 @@
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
 /*
- * Remove all empty zero pages from the mapping for lazy refaulting
- * - This must be called after mm->context.has_pgste is set, to avoid
- *   future creation of zero pages
- * - This must be called after THP was disabled.
- *
- * mm contracts with s390, that even if mm were to remove a page table,
- * racing with the loop below and so causing pte_offset_map_lock() to fail,
- * it will never insert a page table containing empty zero pages once
- * mm_forbids_zeropage(mm) i.e. mm->context.has_pgste is set.
- */
-static int __zap_zero_pages(pmd_t *pmd, unsigned long start,
-			   unsigned long end, struct mm_walk *walk)
-{
-	unsigned long addr;
-
-	for (addr = start; addr != end; addr += PAGE_SIZE) {
-		pte_t *ptep;
-		spinlock_t *ptl;
-
-		ptep = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
-		if (!ptep)
-			break;
-		if (is_zero_pfn(pte_pfn(*ptep)))
-			ptep_xchg_direct(walk->mm, addr, ptep, __pte(_PAGE_INVALID));
-		pte_unmap_unlock(ptep, ptl);
-	}
-	return 0;
-}
-
-static const struct mm_walk_ops zap_zero_walk_ops = {
-	.pmd_entry	= __zap_zero_pages,
-	.walk_lock	= PGWALK_WRLOCK,
-};
-
-/*
  * switch on pgstes for its userspace process (for kvm)
  */
 int s390_enable_sie(void)
@@ -2599,22 +2564,142 @@
 	mm->context.has_pgste = 1;
 	/* split thp mappings and disable thp for future mappings */
 	thp_split_mm(mm);
-	walk_page_range(mm, 0, TASK_SIZE, &zap_zero_walk_ops, NULL);
 	mmap_write_unlock(mm);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(s390_enable_sie);
 
-int gmap_mark_unmergeable(void)
+static int find_zeropage_pte_entry(pte_t *pte, unsigned long addr,
+				   unsigned long end, struct mm_walk *walk)
 {
+	unsigned long *found_addr = walk->private;
+
+	/* Return 1 of the page is a zeropage. */
+	if (is_zero_pfn(pte_pfn(*pte))) {
+		/*
+		 * Shared zeropage in e.g., a FS DAX mapping? We cannot do the
+		 * right thing and likely don't care: FAULT_FLAG_UNSHARE
+		 * currently only works in COW mappings, which is also where
+		 * mm_forbids_zeropage() is checked.
+		 */
+		if (!is_cow_mapping(walk->vma->vm_flags))
+			return -EFAULT;
+
+		*found_addr = addr;
+		return 1;
+	}
+	return 0;
+}
+
+static const struct mm_walk_ops find_zeropage_ops = {
+	.pte_entry	= find_zeropage_pte_entry,
+	.walk_lock	= PGWALK_WRLOCK,
+};
+
+/*
+ * Unshare all shared zeropages, replacing them by anonymous pages. Note that
+ * we cannot simply zap all shared zeropages, because this could later
+ * trigger unexpected userfaultfd missing events.
+ *
+ * This must be called after mm->context.allow_cow_sharing was
+ * set to 0, to avoid future mappings of shared zeropages.
+ *
+ * mm contracts with s390, that even if mm were to remove a page table,
+ * and racing with walk_page_range_vma() calling pte_offset_map_lock()
+ * would fail, it will never insert a page table containing empty zero
+ * pages once mm_forbids_zeropage(mm) i.e.
+ * mm->context.allow_cow_sharing is set to 0.
+ */
+static int __s390_unshare_zeropages(struct mm_struct *mm)
+{
+	struct vm_area_struct *vma;
+	VMA_ITERATOR(vmi, mm, 0);
+	unsigned long addr;
+	vm_fault_t fault;
+	int rc;
+
+	for_each_vma(vmi, vma) {
+		/*
+		 * We could only look at COW mappings, but it's more future
+		 * proof to catch unexpected zeropages in other mappings and
+		 * fail.
+		 */
+		if ((vma->vm_flags & VM_PFNMAP) || is_vm_hugetlb_page(vma))
+			continue;
+		addr = vma->vm_start;
+
+retry:
+		rc = walk_page_range_vma(vma, addr, vma->vm_end,
+					 &find_zeropage_ops, &addr);
+		if (rc < 0)
+			return rc;
+		else if (!rc)
+			continue;
+
+		/* addr was updated by find_zeropage_pte_entry() */
+		fault = handle_mm_fault(vma, addr,
+					FAULT_FLAG_UNSHARE | FAULT_FLAG_REMOTE,
+					NULL);
+		if (fault & VM_FAULT_OOM)
+			return -ENOMEM;
+		/*
+		 * See break_ksm(): even after handle_mm_fault() returned 0, we
+		 * must start the lookup from the current address, because
+		 * handle_mm_fault() may back out if there's any difficulty.
+		 *
+		 * VM_FAULT_SIGBUS and VM_FAULT_SIGSEGV are unexpected but
+		 * maybe they could trigger in the future on concurrent
+		 * truncation. In that case, the shared zeropage would be gone
+		 * and we can simply retry and make progress.
+		 */
+		cond_resched();
+		goto retry;
+	}
+
+	return 0;
+}
+
+static int __s390_disable_cow_sharing(struct mm_struct *mm)
+{
+	int rc;
+
+	if (!mm->context.allow_cow_sharing)
+		return 0;
+
+	mm->context.allow_cow_sharing = 0;
+
+	/* Replace all shared zeropages by anonymous pages. */
+	rc = __s390_unshare_zeropages(mm);
 	/*
 	 * Make sure to disable KSM (if enabled for the whole process or
 	 * individual VMAs). Note that nothing currently hinders user space
 	 * from re-enabling it.
 	 */
-	return ksm_disable(current->mm);
+	if (!rc)
+		rc = ksm_disable(mm);
+	if (rc)
+		mm->context.allow_cow_sharing = 1;
+	return rc;
+}
+
+/*
+ * Disable most COW-sharing of memory pages for the whole process:
+ * (1) Disable KSM and unmerge/unshare any KSM pages.
+ * (2) Disallow shared zeropages and unshare any zerpages that are mapped.
+ *
+ * Not that we currently don't bother with COW-shared pages that are shared
+ * with parent/child processes due to fork().
+ */
+int s390_disable_cow_sharing(void)
+{
+	int rc;
+
+	mmap_write_lock(current->mm);
+	rc = __s390_disable_cow_sharing(current->mm);
+	mmap_write_unlock(current->mm);
+	return rc;
 }
-EXPORT_SYMBOL_GPL(gmap_mark_unmergeable);
+EXPORT_SYMBOL_GPL(s390_disable_cow_sharing);
 
 /*
  * Enable storage key handling from now on and initialize the storage
@@ -2659,7 +2744,7 @@
 		return 0;
 
 	start = pmd_val(*pmd) & HPAGE_MASK;
-	end = start + HPAGE_SIZE - 1;
+	end = start + HPAGE_SIZE;
 	__storage_key_init_range(start, end);
 	set_bit(PG_arch_1, &page->flags);
 	cond_resched();
@@ -2683,7 +2768,7 @@
 		goto out_up;
 
 	mm->context.uses_skeys = 1;
-	rc = gmap_mark_unmergeable();
+	rc = __s390_disable_cow_sharing(mm);
 	if (rc) {
 		mm->context.uses_skeys = 0;
 		goto out_up;
--- linux-qcom-6.8.0.orig/arch/s390/mm/hugetlbpage.c
+++ linux-qcom-6.8.0/arch/s390/mm/hugetlbpage.c
@@ -139,7 +139,7 @@
 	}
 
 	if (!test_and_set_bit(PG_arch_1, &page->flags))
-		__storage_key_init_range(paddr, paddr + size - 1);
+		__storage_key_init_range(paddr, paddr + size);
 }
 
 void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
@@ -224,7 +224,7 @@
 		if (p4d_present(*p4dp)) {
 			pudp = pud_offset(p4dp, addr);
 			if (pud_present(*pudp)) {
-				if (pud_large(*pudp))
+				if (pud_leaf(*pudp))
 					return (pte_t *) pudp;
 				pmdp = pmd_offset(pudp, addr);
 			}
@@ -240,7 +240,7 @@
 
 int pud_huge(pud_t pud)
 {
-	return pud_large(pud);
+	return pud_leaf(pud);
 }
 
 bool __init arch_hugetlb_valid_size(unsigned long size)
--- linux-qcom-6.8.0.orig/arch/s390/mm/init.c
+++ linux-qcom-6.8.0/arch/s390/mm/init.c
@@ -281,9 +281,6 @@
 	unsigned long size_pages = PFN_DOWN(size);
 	int rc;
 
-	if (WARN_ON_ONCE(params->altmap))
-		return -EINVAL;
-
 	if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot))
 		return -EINVAL;
 
--- linux-qcom-6.8.0.orig/arch/s390/mm/pageattr.c
+++ linux-qcom-6.8.0/arch/s390/mm/pageattr.c
@@ -274,7 +274,7 @@
 		if (pud_none(*pudp))
 			return -EINVAL;
 		next = pud_addr_end(addr, end);
-		if (pud_large(*pudp)) {
+		if (pud_leaf(*pudp)) {
 			need_split  = !!(flags & SET_MEMORY_4K);
 			need_split |= !!(addr & ~PUD_MASK);
 			need_split |= !!(addr + PUD_SIZE > next);
@@ -406,6 +406,21 @@
 	return __set_memory((unsigned long)page_to_virt(page), 1, SET_MEMORY_DEF);
 }
 
+bool kernel_page_present(struct page *page)
+{
+	unsigned long addr;
+	unsigned int cc;
+
+	addr = (unsigned long)page_address(page);
+	asm volatile(
+		"	lra	%[addr],0(%[addr])\n"
+		"	ipm	%[cc]\n"
+		: [cc] "=d" (cc), [addr] "+a" (addr)
+		:
+		: "cc");
+	return (cc >> 28) == 0;
+}
+
 #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KFENCE)
 
 static void ipte_range(pte_t *pte, unsigned long address, int nr)
--- linux-qcom-6.8.0.orig/arch/s390/mm/pgalloc.c
+++ linux-qcom-6.8.0/arch/s390/mm/pgalloc.c
@@ -55,6 +55,8 @@
 
 void crst_table_free(struct mm_struct *mm, unsigned long *table)
 {
+	if (!table)
+		return;
 	pagetable_free(virt_to_ptdesc(table));
 }
 
@@ -262,6 +264,8 @@
 
 static void base_crst_free(unsigned long *table)
 {
+	if (!table)
+		return;
 	pagetable_free(virt_to_ptdesc(table));
 }
 
--- linux-qcom-6.8.0.orig/arch/s390/mm/pgtable.c
+++ linux-qcom-6.8.0/arch/s390/mm/pgtable.c
@@ -470,7 +470,7 @@
 		return -ENOENT;
 
 	/* Large PUDs are not supported yet. */
-	if (pud_large(*pud))
+	if (pud_leaf(*pud))
 		return -EFAULT;
 
 	*pmdp = pmd_offset(pud, addr);
--- linux-qcom-6.8.0.orig/arch/s390/mm/vmem.c
+++ linux-qcom-6.8.0/arch/s390/mm/vmem.c
@@ -33,8 +33,12 @@
 	return memblock_alloc(size, size);
 }
 
-static void vmem_free_pages(unsigned long addr, int order)
+static void vmem_free_pages(unsigned long addr, int order, struct vmem_altmap *altmap)
 {
+	if (altmap) {
+		vmem_altmap_free(altmap, 1 << order);
+		return;
+	}
 	/* We don't expect boot memory to be removed ever. */
 	if (!slab_is_available() ||
 	    WARN_ON_ONCE(PageReserved(virt_to_page((void *)addr))))
@@ -156,7 +160,8 @@
 
 /* __ref: we'll only call vmemmap_alloc_block() via vmemmap_populate() */
 static int __ref modify_pte_table(pmd_t *pmd, unsigned long addr,
-				  unsigned long end, bool add, bool direct)
+				  unsigned long end, bool add, bool direct,
+				  struct vmem_altmap *altmap)
 {
 	unsigned long prot, pages = 0;
 	int ret = -ENOMEM;
@@ -172,11 +177,11 @@
 			if (pte_none(*pte))
 				continue;
 			if (!direct)
-				vmem_free_pages((unsigned long) pfn_to_virt(pte_pfn(*pte)), 0);
+				vmem_free_pages((unsigned long)pfn_to_virt(pte_pfn(*pte)), get_order(PAGE_SIZE), altmap);
 			pte_clear(&init_mm, addr, pte);
 		} else if (pte_none(*pte)) {
 			if (!direct) {
-				void *new_page = vmemmap_alloc_block(PAGE_SIZE, NUMA_NO_NODE);
+				void *new_page = vmemmap_alloc_block_buf(PAGE_SIZE, NUMA_NO_NODE, altmap);
 
 				if (!new_page)
 					goto out;
@@ -213,7 +218,8 @@
 
 /* __ref: we'll only call vmemmap_alloc_block() via vmemmap_populate() */
 static int __ref modify_pmd_table(pud_t *pud, unsigned long addr,
-				  unsigned long end, bool add, bool direct)
+				  unsigned long end, bool add, bool direct,
+				  struct vmem_altmap *altmap)
 {
 	unsigned long next, prot, pages = 0;
 	int ret = -ENOMEM;
@@ -234,11 +240,11 @@
 				if (IS_ALIGNED(addr, PMD_SIZE) &&
 				    IS_ALIGNED(next, PMD_SIZE)) {
 					if (!direct)
-						vmem_free_pages(pmd_deref(*pmd), get_order(PMD_SIZE));
+						vmem_free_pages(pmd_deref(*pmd), get_order(PMD_SIZE), altmap);
 					pmd_clear(pmd);
 					pages++;
 				} else if (!direct && vmemmap_unuse_sub_pmd(addr, next)) {
-					vmem_free_pages(pmd_deref(*pmd), get_order(PMD_SIZE));
+					vmem_free_pages(pmd_deref(*pmd), get_order(PMD_SIZE), altmap);
 					pmd_clear(pmd);
 				}
 				continue;
@@ -261,7 +267,7 @@
 				 * page tables since vmemmap_populate gets
 				 * called for each section separately.
 				 */
-				new_page = vmemmap_alloc_block(PMD_SIZE, NUMA_NO_NODE);
+				new_page = vmemmap_alloc_block_buf(PMD_SIZE, NUMA_NO_NODE, altmap);
 				if (new_page) {
 					set_pmd(pmd, __pmd(__pa(new_page) | prot));
 					if (!IS_ALIGNED(addr, PMD_SIZE) ||
@@ -280,7 +286,7 @@
 				vmemmap_use_sub_pmd(addr, next);
 			continue;
 		}
-		ret = modify_pte_table(pmd, addr, next, add, direct);
+		ret = modify_pte_table(pmd, addr, next, add, direct, altmap);
 		if (ret)
 			goto out;
 		if (!add)
@@ -302,12 +308,12 @@
 	for (i = 0; i < PTRS_PER_PMD; i++, pmd++)
 		if (!pmd_none(*pmd))
 			return;
-	vmem_free_pages(pud_deref(*pud), CRST_ALLOC_ORDER);
+	vmem_free_pages(pud_deref(*pud), CRST_ALLOC_ORDER, NULL);
 	pud_clear(pud);
 }
 
 static int modify_pud_table(p4d_t *p4d, unsigned long addr, unsigned long end,
-			    bool add, bool direct)
+			    bool add, bool direct, struct vmem_altmap *altmap)
 {
 	unsigned long next, prot, pages = 0;
 	int ret = -ENOMEM;
@@ -323,7 +329,7 @@
 		if (!add) {
 			if (pud_none(*pud))
 				continue;
-			if (pud_large(*pud)) {
+			if (pud_leaf(*pud)) {
 				if (IS_ALIGNED(addr, PUD_SIZE) &&
 				    IS_ALIGNED(next, PUD_SIZE)) {
 					pud_clear(pud);
@@ -344,10 +350,10 @@
 			if (!pmd)
 				goto out;
 			pud_populate(&init_mm, pud, pmd);
-		} else if (pud_large(*pud)) {
+		} else if (pud_leaf(*pud)) {
 			continue;
 		}
-		ret = modify_pmd_table(pud, addr, next, add, direct);
+		ret = modify_pmd_table(pud, addr, next, add, direct, altmap);
 		if (ret)
 			goto out;
 		if (!add)
@@ -370,12 +376,12 @@
 		if (!pud_none(*pud))
 			return;
 	}
-	vmem_free_pages(p4d_deref(*p4d), CRST_ALLOC_ORDER);
+	vmem_free_pages(p4d_deref(*p4d), CRST_ALLOC_ORDER, NULL);
 	p4d_clear(p4d);
 }
 
 static int modify_p4d_table(pgd_t *pgd, unsigned long addr, unsigned long end,
-			    bool add, bool direct)
+			    bool add, bool direct, struct vmem_altmap *altmap)
 {
 	unsigned long next;
 	int ret = -ENOMEM;
@@ -394,7 +400,7 @@
 				goto out;
 			p4d_populate(&init_mm, p4d, pud);
 		}
-		ret = modify_pud_table(p4d, addr, next, add, direct);
+		ret = modify_pud_table(p4d, addr, next, add, direct, altmap);
 		if (ret)
 			goto out;
 		if (!add)
@@ -415,12 +421,12 @@
 		if (!p4d_none(*p4d))
 			return;
 	}
-	vmem_free_pages(pgd_deref(*pgd), CRST_ALLOC_ORDER);
+	vmem_free_pages(pgd_deref(*pgd), CRST_ALLOC_ORDER, NULL);
 	pgd_clear(pgd);
 }
 
 static int modify_pagetable(unsigned long start, unsigned long end, bool add,
-			    bool direct)
+			    bool direct, struct vmem_altmap *altmap)
 {
 	unsigned long addr, next;
 	int ret = -ENOMEM;
@@ -445,7 +451,7 @@
 				goto out;
 			pgd_populate(&init_mm, pgd, p4d);
 		}
-		ret = modify_p4d_table(pgd, addr, next, add, direct);
+		ret = modify_p4d_table(pgd, addr, next, add, direct, altmap);
 		if (ret)
 			goto out;
 		if (!add)
@@ -458,14 +464,16 @@
 	return ret;
 }
 
-static int add_pagetable(unsigned long start, unsigned long end, bool direct)
+static int add_pagetable(unsigned long start, unsigned long end, bool direct,
+			 struct vmem_altmap *altmap)
 {
-	return modify_pagetable(start, end, true, direct);
+	return modify_pagetable(start, end, true, direct, altmap);
 }
 
-static int remove_pagetable(unsigned long start, unsigned long end, bool direct)
+static int remove_pagetable(unsigned long start, unsigned long end, bool direct,
+			    struct vmem_altmap *altmap)
 {
-	return modify_pagetable(start, end, false, direct);
+	return modify_pagetable(start, end, false, direct, altmap);
 }
 
 /*
@@ -474,7 +482,7 @@
 static int vmem_add_range(unsigned long start, unsigned long size)
 {
 	start = (unsigned long)__va(start);
-	return add_pagetable(start, start + size, true);
+	return add_pagetable(start, start + size, true, NULL);
 }
 
 /*
@@ -483,7 +491,7 @@
 static void vmem_remove_range(unsigned long start, unsigned long size)
 {
 	start = (unsigned long)__va(start);
-	remove_pagetable(start, start + size, true);
+	remove_pagetable(start, start + size, true, NULL);
 }
 
 /*
@@ -496,9 +504,9 @@
 
 	mutex_lock(&vmem_mutex);
 	/* We don't care about the node, just use NUMA_NO_NODE on allocations */
-	ret = add_pagetable(start, end, false);
+	ret = add_pagetable(start, end, false, altmap);
 	if (ret)
-		remove_pagetable(start, end, false);
+		remove_pagetable(start, end, false, altmap);
 	mutex_unlock(&vmem_mutex);
 	return ret;
 }
@@ -509,7 +517,7 @@
 		  struct vmem_altmap *altmap)
 {
 	mutex_lock(&vmem_mutex);
-	remove_pagetable(start, end, false);
+	remove_pagetable(start, end, false, altmap);
 	mutex_unlock(&vmem_mutex);
 }
 
@@ -591,7 +599,7 @@
 		if (!pmd)
 			goto out;
 		pud_populate(&init_mm, pud, pmd);
-	} else if (WARN_ON_ONCE(pud_large(*pud))) {
+	} else if (WARN_ON_ONCE(pud_leaf(*pud))) {
 		goto out;
 	}
 	pmd = pmd_offset(pud, addr);
--- linux-qcom-6.8.0.orig/arch/s390/net/bpf_jit_comp.c
+++ linux-qcom-6.8.0/arch/s390/net/bpf_jit_comp.c
@@ -516,11 +516,12 @@
  * PLT for hotpatchable calls. The calling convention is the same as for the
  * ftrace hotpatch trampolines: %r0 is return address, %r1 is clobbered.
  */
-extern const char bpf_plt[];
-extern const char bpf_plt_ret[];
-extern const char bpf_plt_target[];
-extern const char bpf_plt_end[];
-#define BPF_PLT_SIZE 32
+struct bpf_plt {
+	char code[16];
+	void *ret;
+	void *target;
+} __packed;
+extern const struct bpf_plt bpf_plt;
 asm(
 	".pushsection .rodata\n"
 	"	.balign 8\n"
@@ -531,15 +532,14 @@
 	"	.balign 8\n"
 	"bpf_plt_ret: .quad 0\n"
 	"bpf_plt_target: .quad 0\n"
-	"bpf_plt_end:\n"
 	"	.popsection\n"
 );
 
-static void bpf_jit_plt(void *plt, void *ret, void *target)
+static void bpf_jit_plt(struct bpf_plt *plt, void *ret, void *target)
 {
-	memcpy(plt, bpf_plt, BPF_PLT_SIZE);
-	*(void **)((char *)plt + (bpf_plt_ret - bpf_plt)) = ret;
-	*(void **)((char *)plt + (bpf_plt_target - bpf_plt)) = target ?: ret;
+	memcpy(plt, &bpf_plt, sizeof(*plt));
+	plt->ret = ret;
+	plt->target = target;
 }
 
 /*
@@ -662,9 +662,9 @@
 	jit->prg = ALIGN(jit->prg, 8);
 	jit->prologue_plt = jit->prg;
 	if (jit->prg_buf)
-		bpf_jit_plt(jit->prg_buf + jit->prg,
+		bpf_jit_plt((struct bpf_plt *)(jit->prg_buf + jit->prg),
 			    jit->prg_buf + jit->prologue_plt_ret, NULL);
-	jit->prg += BPF_PLT_SIZE;
+	jit->prg += sizeof(struct bpf_plt);
 }
 
 static int get_probe_mem_regno(const u8 *insn)
@@ -1427,8 +1427,12 @@
 	EMIT6_DISP_LH(0xeb000000, is32 ? (op32) : (op64),		\
 		      (insn->imm & BPF_FETCH) ? src_reg : REG_W0,	\
 		      src_reg, dst_reg, off);				\
-	if (is32 && (insn->imm & BPF_FETCH))				\
-		EMIT_ZERO(src_reg);					\
+	if (insn->imm & BPF_FETCH) {					\
+		/* bcr 14,0 - see atomic_fetch_{add,and,or,xor}() */	\
+		_EMIT2(0x07e0);						\
+		if (is32)                                               \
+			EMIT_ZERO(src_reg);				\
+	}								\
 } while (0)
 		case BPF_ADD:
 		case BPF_ADD | BPF_FETCH:
@@ -2040,9 +2044,6 @@
 	struct bpf_jit jit;
 	int pass;
 
-	if (WARN_ON_ONCE(bpf_plt_end - bpf_plt != BPF_PLT_SIZE))
-		return orig_fp;
-
 	if (!fp->jit_requested)
 		return orig_fp;
 
@@ -2111,7 +2112,11 @@
 		print_fn_code(jit.prg_buf, jit.size_prg);
 	}
 	if (!fp->is_func || extra_pass) {
-		bpf_jit_binary_lock_ro(header);
+		if (bpf_jit_binary_lock_ro(header)) {
+			bpf_jit_binary_free(header);
+			fp = orig_fp;
+			goto free_addrs;
+		}
 	} else {
 		jit_data->header = header;
 		jit_data->ctx = jit;
@@ -2148,14 +2153,11 @@
 int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type t,
 		       void *old_addr, void *new_addr)
 {
+	struct bpf_plt expected_plt, current_plt, new_plt, *plt;
 	struct {
 		u16 opc;
 		s32 disp;
 	} __packed insn;
-	char expected_plt[BPF_PLT_SIZE];
-	char current_plt[BPF_PLT_SIZE];
-	char new_plt[BPF_PLT_SIZE];
-	char *plt;
 	char *ret;
 	int err;
 
@@ -2174,18 +2176,18 @@
 		 */
 	} else {
 		/* Verify the PLT. */
-		plt = (char *)ip + (insn.disp << 1);
-		err = copy_from_kernel_nofault(current_plt, plt, BPF_PLT_SIZE);
+		plt = ip + (insn.disp << 1);
+		err = copy_from_kernel_nofault(&current_plt, plt,
+					       sizeof(current_plt));
 		if (err < 0)
 			return err;
 		ret = (char *)ip + 6;
-		bpf_jit_plt(expected_plt, ret, old_addr);
-		if (memcmp(current_plt, expected_plt, BPF_PLT_SIZE))
+		bpf_jit_plt(&expected_plt, ret, old_addr);
+		if (memcmp(&current_plt, &expected_plt, sizeof(current_plt)))
 			return -EINVAL;
 		/* Adjust the call address. */
-		bpf_jit_plt(new_plt, ret, new_addr);
-		s390_kernel_write(plt + (bpf_plt_target - bpf_plt),
-				  new_plt + (bpf_plt_target - bpf_plt),
+		bpf_jit_plt(&new_plt, ret, new_addr);
+		s390_kernel_write(&plt->target, &new_plt.target,
 				  sizeof(void *));
 	}
 
--- linux-qcom-6.8.0.orig/arch/s390/pci/pci.c
+++ linux-qcom-6.8.0/arch/s390/pci/pci.c
@@ -28,6 +28,8 @@
 #include <linux/jump_label.h>
 #include <linux/pci.h>
 #include <linux/printk.h>
+#include <linux/lockdep.h>
+#include <linux/list_sort.h>
 
 #include <asm/isc.h>
 #include <asm/airq.h>
@@ -42,6 +44,7 @@
 /* list of all detected zpci devices */
 static LIST_HEAD(zpci_list);
 static DEFINE_SPINLOCK(zpci_list_lock);
+static DEFINE_MUTEX(zpci_add_remove_lock);
 
 static DECLARE_BITMAP(zpci_domain, ZPCI_DOMAIN_BITMAP_SIZE);
 static DEFINE_SPINLOCK(zpci_domain_lock);
@@ -67,6 +70,15 @@
 struct airq_iv *zpci_aif_sbv;
 EXPORT_SYMBOL_GPL(zpci_aif_sbv);
 
+void zpci_zdev_put(struct zpci_dev *zdev)
+{
+	if (!zdev)
+		return;
+	mutex_lock(&zpci_add_remove_lock);
+	kref_put_lock(&zdev->kref, zpci_release_device, &zpci_list_lock);
+	mutex_unlock(&zpci_add_remove_lock);
+}
+
 struct zpci_dev *get_zdev_by_fid(u32 fid)
 {
 	struct zpci_dev *tmp, *zdev = NULL;
@@ -159,6 +171,7 @@
 	u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_SET_MEASURE);
 	struct zpci_iommu_ctrs *ctrs;
 	struct zpci_fib fib = {0};
+	unsigned long flags;
 	u8 cc, status;
 
 	if (zdev->fmb || sizeof(*zdev->fmb) < zdev->fmb_length)
@@ -170,6 +183,7 @@
 	WARN_ON((u64) zdev->fmb & 0xf);
 
 	/* reset software counters */
+	spin_lock_irqsave(&zdev->dom_lock, flags);
 	ctrs = zpci_get_iommu_ctrs(zdev);
 	if (ctrs) {
 		atomic64_set(&ctrs->mapped_pages, 0);
@@ -178,6 +192,7 @@
 		atomic64_set(&ctrs->sync_map_rpcits, 0);
 		atomic64_set(&ctrs->sync_rpcits, 0);
 	}
+	spin_unlock_irqrestore(&zdev->dom_lock, flags);
 
 
 	fib.fmb_addr = virt_to_phys(zdev->fmb);
@@ -730,12 +745,12 @@
  * equivalent to its state during boot when first probing a driver.
  * Consequently after reset the PCI function requires re-initialization via the
  * common PCI code including re-enabling IRQs via pci_alloc_irq_vectors()
- * and enabling the function via e.g.pci_enablde_device_flags().The caller
+ * and enabling the function via e.g. pci_enable_device_flags(). The caller
  * must guard against concurrent reset attempts.
  *
  * In most cases this function should not be called directly but through
  * pci_reset_function() or pci_reset_bus() which handle the save/restore and
- * locking.
+ * locking - asserted by lockdep.
  *
  * Return: 0 on success and an error value otherwise
  */
@@ -744,6 +759,7 @@
 	u8 status;
 	int rc;
 
+	lockdep_assert_held(&zdev->state_lock);
 	zpci_dbg(3, "rst fid:%x, fh:%x\n", zdev->fid, zdev->fh);
 	if (zdev_enabled(zdev)) {
 		/* Disables device access, DMAs and IRQs (reset state) */
@@ -780,8 +796,9 @@
  * @fh: Current Function Handle of the device to be created
  * @state: Initial state after creation either Standby or Configured
  *
- * Creates a new zpci device and adds it to its, possibly newly created, zbus
- * as well as zpci_list.
+ * Allocates a new struct zpci_dev and queries the platform for its details.
+ * If successful the device can subsequently be added to the zPCI subsystem
+ * using zpci_add_device().
  *
  * Returns: the zdev on success or an error pointer otherwise
  */
@@ -790,7 +807,6 @@
 	struct zpci_dev *zdev;
 	int rc;
 
-	zpci_dbg(1, "add fid:%x, fh:%x, c:%d\n", fid, fh, state);
 	zdev = kzalloc(sizeof(*zdev), GFP_KERNEL);
 	if (!zdev)
 		return ERR_PTR(-ENOMEM);
@@ -805,10 +821,35 @@
 		goto error;
 	zdev->state =  state;
 
-	kref_init(&zdev->kref);
-	mutex_init(&zdev->lock);
+	mutex_init(&zdev->state_lock);
+	mutex_init(&zdev->fmb_lock);
 	mutex_init(&zdev->kzdev_lock);
 
+	return zdev;
+
+error:
+	zpci_dbg(0, "crt fid:%x, rc:%d\n", fid, rc);
+	kfree(zdev);
+	return ERR_PTR(rc);
+}
+
+/**
+ * zpci_add_device() - Add a previously created zPCI device to the zPCI subsystem
+ * @zdev: The zPCI device to be added
+ *
+ * A struct zpci_dev is added to the zPCI subsystem and to a virtual PCI bus creating
+ * a new one as necessary. A hotplug slot is created and events start to be handled.
+ * If successful from this point on zpci_zdev_get() and zpci_zdev_put() must be used.
+ * If adding the struct zpci_dev fails the device was not added and should be freed.
+ *
+ * Return: 0 on success, or an error code otherwise
+ */
+int zpci_add_device(struct zpci_dev *zdev)
+{
+	int rc;
+
+	mutex_lock(&zpci_add_remove_lock);
+	zpci_dbg(1, "add fid:%x, fh:%x, c:%d\n", zdev->fid, zdev->fh, zdev->state);
 	rc = zpci_init_iommu(zdev);
 	if (rc)
 		goto error;
@@ -817,18 +858,19 @@
 	if (rc)
 		goto error_destroy_iommu;
 
+	kref_init(&zdev->kref);
 	spin_lock(&zpci_list_lock);
 	list_add_tail(&zdev->entry, &zpci_list);
 	spin_unlock(&zpci_list_lock);
-
-	return zdev;
+	mutex_unlock(&zpci_add_remove_lock);
+	return 0;
 
 error_destroy_iommu:
 	zpci_destroy_iommu(zdev);
 error:
-	zpci_dbg(0, "add fid:%x, rc:%d\n", fid, rc);
-	kfree(zdev);
-	return ERR_PTR(rc);
+	zpci_dbg(0, "add fid:%x, rc:%d\n", zdev->fid, rc);
+	mutex_unlock(&zpci_add_remove_lock);
+	return rc;
 }
 
 bool zpci_is_device_configured(struct zpci_dev *zdev)
@@ -870,6 +912,10 @@
 {
 	int rc;
 
+	lockdep_assert_held(&zdev->state_lock);
+	if (zdev->state != ZPCI_FN_STATE_CONFIGURED)
+		return 0;
+
 	if (zdev->zbus->bus)
 		zpci_bus_remove_device(zdev, false);
 
@@ -893,59 +939,44 @@
  * @zdev: the zpci_dev that was reserved
  *
  * Handle the case that a given zPCI function was reserved by another system.
- * After a call to this function the zpci_dev can not be found via
- * get_zdev_by_fid() anymore but may still be accessible via existing
- * references though it will not be functional anymore.
  */
 void zpci_device_reserved(struct zpci_dev *zdev)
 {
-	if (zdev->has_hp_slot)
-		zpci_exit_slot(zdev);
-	/*
-	 * Remove device from zpci_list as it is going away. This also
-	 * makes sure we ignore subsequent zPCI events for this device.
-	 */
-	spin_lock(&zpci_list_lock);
-	list_del(&zdev->entry);
-	spin_unlock(&zpci_list_lock);
+	lockdep_assert_held(&zdev->state_lock);
+	/* We may declare the device reserved multiple times */
+	if (zdev->state == ZPCI_FN_STATE_RESERVED)
+		return;
 	zdev->state = ZPCI_FN_STATE_RESERVED;
 	zpci_dbg(3, "rsv fid:%x\n", zdev->fid);
+	/*
+	 * The underlying device is gone. Allow the zdev to be freed
+	 * as soon as all other references are gone by accounting for
+	 * the removal as a dropped reference.
+	 */
 	zpci_zdev_put(zdev);
 }
 
 void zpci_release_device(struct kref *kref)
 {
 	struct zpci_dev *zdev = container_of(kref, struct zpci_dev, kref);
-	int ret;
 
-	if (zdev->zbus->bus)
-		zpci_bus_remove_device(zdev, false);
+	lockdep_assert_held(&zpci_add_remove_lock);
+	WARN_ON(zdev->state != ZPCI_FN_STATE_RESERVED);
+	/*
+	 * We already hold zpci_list_lock thanks to kref_put_lock().
+	 * This makes sure no new reference can be taken from the list.
+	 */
+	list_del(&zdev->entry);
+	spin_unlock(&zpci_list_lock);
 
-	if (zdev_enabled(zdev))
-		zpci_disable_device(zdev);
+	if (zdev->has_hp_slot)
+		zpci_exit_slot(zdev);
 
-	switch (zdev->state) {
-	case ZPCI_FN_STATE_CONFIGURED:
-		ret = sclp_pci_deconfigure(zdev->fid);
-		zpci_dbg(3, "deconf fid:%x, rc:%d\n", zdev->fid, ret);
-		fallthrough;
-	case ZPCI_FN_STATE_STANDBY:
-		if (zdev->has_hp_slot)
-			zpci_exit_slot(zdev);
-		spin_lock(&zpci_list_lock);
-		list_del(&zdev->entry);
-		spin_unlock(&zpci_list_lock);
-		zpci_dbg(3, "rsv fid:%x\n", zdev->fid);
-		fallthrough;
-	case ZPCI_FN_STATE_RESERVED:
-		if (zdev->has_resources)
-			zpci_cleanup_bus_resources(zdev);
-		zpci_bus_device_unregister(zdev);
-		zpci_destroy_iommu(zdev);
-		fallthrough;
-	default:
-		break;
-	}
+	if (zdev->has_resources)
+		zpci_cleanup_bus_resources(zdev);
+
+	zpci_bus_device_unregister(zdev);
+	zpci_destroy_iommu(zdev);
 	zpci_dbg(3, "rem fid:%x\n", zdev->fid);
 	kfree_rcu(zdev, rcu);
 }
@@ -1081,6 +1112,50 @@
 	return s390_pci_initialized;
 }
 
+static int zpci_cmp_rid(void *priv, const struct list_head *a,
+			const struct list_head *b)
+{
+	struct zpci_dev *za = container_of(a, struct zpci_dev, entry);
+	struct zpci_dev *zb = container_of(b, struct zpci_dev, entry);
+
+	/*
+	 * PCI functions without RID available maintain original order
+	 * between themselves but sort before those with RID.
+	 */
+	if (za->rid == zb->rid)
+		return za->rid_available > zb->rid_available;
+	/*
+	 * PCI functions with RID sort by RID ascending.
+	 */
+	return za->rid > zb->rid;
+}
+
+static void zpci_add_devices(struct list_head *scan_list)
+{
+	struct zpci_dev *zdev, *tmp;
+
+	list_sort(NULL, scan_list, &zpci_cmp_rid);
+	list_for_each_entry_safe(zdev, tmp, scan_list, entry) {
+		list_del_init(&zdev->entry);
+		if (zpci_add_device(zdev))
+			kfree(zdev);
+	}
+}
+
+int zpci_scan_devices(void)
+{
+	LIST_HEAD(scan_list);
+	int rc;
+
+	rc = clp_scan_pci_devices(&scan_list);
+	if (rc)
+		return rc;
+
+	zpci_add_devices(&scan_list);
+	zpci_bus_scan_busses();
+	return 0;
+}
+
 static int __init pci_base_init(void)
 {
 	int rc;
@@ -1110,10 +1185,9 @@
 	if (rc)
 		goto out_irq;
 
-	rc = clp_scan_pci_devices();
+	rc = zpci_scan_devices();
 	if (rc)
 		goto out_find;
-	zpci_bus_scan_busses();
 
 	s390_pci_initialized = 1;
 	return 0;
--- linux-qcom-6.8.0.orig/arch/s390/pci/pci_bus.c
+++ linux-qcom-6.8.0/arch/s390/pci/pci_bus.c
@@ -168,9 +168,15 @@
 	mutex_unlock(&zbus_list_lock);
 }
 
+static bool zpci_bus_is_multifunction_root(struct zpci_dev *zdev)
+{
+	return !s390_pci_no_rid && zdev->rid_available &&
+		!zdev->vfn;
+}
+
 /* zpci_bus_create_pci_bus - Create the PCI bus associated with this zbus
  * @zbus: the zbus holding the zdevices
- * @fr: PCI root function that will determine the bus's domain, and bus speeed
+ * @fr: PCI root function that will determine the bus's domain, and bus speed
  * @ops: the pci operations
  *
  * The PCI function @fr determines the domain (its UID), multifunction property
@@ -188,7 +194,7 @@
 		return domain;
 
 	zbus->domain_nr = domain;
-	zbus->multifunction = fr->rid_available;
+	zbus->multifunction = zpci_bus_is_multifunction_root(fr);
 	zbus->max_bus_speed = fr->max_bus_speed;
 
 	/*
@@ -232,13 +238,15 @@
 	kref_put(&zbus->kref, zpci_bus_release);
 }
 
-static struct zpci_bus *zpci_bus_get(int pchid)
+static struct zpci_bus *zpci_bus_get(int topo, bool topo_is_tid)
 {
 	struct zpci_bus *zbus;
 
 	mutex_lock(&zbus_list_lock);
 	list_for_each_entry(zbus, &zbus_list, bus_next) {
-		if (pchid == zbus->pchid) {
+		if (!zbus->multifunction)
+			continue;
+		if (topo_is_tid == zbus->topo_is_tid && topo == zbus->topo) {
 			kref_get(&zbus->kref);
 			goto out_unlock;
 		}
@@ -249,7 +257,7 @@
 	return zbus;
 }
 
-static struct zpci_bus *zpci_bus_alloc(int pchid)
+static struct zpci_bus *zpci_bus_alloc(int topo, bool topo_is_tid)
 {
 	struct zpci_bus *zbus;
 
@@ -257,7 +265,8 @@
 	if (!zbus)
 		return NULL;
 
-	zbus->pchid = pchid;
+	zbus->topo = topo;
+	zbus->topo_is_tid = topo_is_tid;
 	INIT_LIST_HEAD(&zbus->bus_next);
 	mutex_lock(&zbus_list_lock);
 	list_add_tail(&zbus->bus_next, &zbus_list);
@@ -292,19 +301,22 @@
 {
 	int rc = -EINVAL;
 
+	if (zbus->multifunction) {
+		if (!zdev->rid_available) {
+			WARN_ONCE(1, "rid_available not set for multifunction\n");
+			return rc;
+		}
+		zdev->devfn = zdev->rid & ZPCI_RID_MASK_DEVFN;
+	}
+
 	if (zbus->function[zdev->devfn]) {
 		pr_err("devfn %04x is already assigned\n", zdev->devfn);
 		return rc;
 	}
-
 	zdev->zbus = zbus;
 	zbus->function[zdev->devfn] = zdev;
 	zpci_nb_devices++;
 
-	if (zbus->multifunction && !zdev->rid_available) {
-		WARN_ONCE(1, "rid_available not set for multifunction\n");
-		goto error;
-	}
 	rc = zpci_init_slot(zdev);
 	if (rc)
 		goto error;
@@ -319,10 +331,25 @@
 	return rc;
 }
 
+static bool zpci_bus_is_isolated_vf(struct zpci_bus *zbus, struct zpci_dev *zdev)
+{
+	struct pci_dev *pdev;
+
+	if (!zdev->vfn)
+		return false;
+
+	pdev = zpci_iov_find_parent_pf(zbus, zdev);
+	if (!pdev)
+		return true;
+	pci_dev_put(pdev);
+	return false;
+}
+
 int zpci_bus_device_register(struct zpci_dev *zdev, struct pci_ops *ops)
 {
+	bool topo_is_tid = zdev->tid_avail;
 	struct zpci_bus *zbus = NULL;
-	int rc = -EBADF;
+	int topo, rc = -EBADF;
 
 	if (zpci_nb_devices == ZPCI_NR_DEVICES) {
 		pr_warn("Adding PCI function %08x failed because the configured limit of %d is reached\n",
@@ -330,14 +357,19 @@
 		return -ENOSPC;
 	}
 
-	if (zdev->devfn >= ZPCI_FUNCTIONS_PER_BUS)
-		return -EINVAL;
-
-	if (!s390_pci_no_rid && zdev->rid_available)
-		zbus = zpci_bus_get(zdev->pchid);
+	topo = topo_is_tid ? zdev->tid : zdev->pchid;
+	zbus = zpci_bus_get(topo, topo_is_tid);
+	/*
+	 * An isolated VF gets its own domain/bus even if there exists
+	 * a matching domain/bus already
+	 */
+	if (zbus && zpci_bus_is_isolated_vf(zbus, zdev)) {
+		zpci_bus_put(zbus);
+		zbus = NULL;
+	}
 
 	if (!zbus) {
-		zbus = zpci_bus_alloc(zdev->pchid);
+		zbus = zpci_bus_alloc(topo, topo_is_tid);
 		if (!zbus)
 			return -ENOMEM;
 	}
--- linux-qcom-6.8.0.orig/arch/s390/pci/pci_bus.h
+++ linux-qcom-6.8.0/arch/s390/pci/pci_bus.h
@@ -17,11 +17,8 @@
 void zpci_bus_remove_device(struct zpci_dev *zdev, bool set_error);
 
 void zpci_release_device(struct kref *kref);
-static inline void zpci_zdev_put(struct zpci_dev *zdev)
-{
-	if (zdev)
-		kref_put(&zdev->kref, zpci_release_device);
-}
+
+void zpci_zdev_put(struct zpci_dev *zdev);
 
 static inline void zpci_zdev_get(struct zpci_dev *zdev)
 {
--- linux-qcom-6.8.0.orig/arch/s390/pci/pci_clp.c
+++ linux-qcom-6.8.0/arch/s390/pci/pci_clp.c
@@ -164,10 +164,13 @@
 	zdev->port = response->port;
 	zdev->uid = response->uid;
 	zdev->fmb_length = sizeof(u32) * response->fmb_len;
-	zdev->rid_available = response->rid_avail;
 	zdev->is_physfn = response->is_physfn;
-	if (!s390_pci_no_rid && zdev->rid_available)
-		zdev->devfn = response->rid & ZPCI_RID_MASK_DEVFN;
+	zdev->rid_available = response->rid_avail;
+	if (zdev->rid_available)
+		zdev->rid = response->rid;
+	zdev->tid_avail = response->tid_avail;
+	if (zdev->tid_avail)
+		zdev->tid = response->tid;
 
 	memcpy(zdev->pfip, response->pfip, sizeof(zdev->pfip));
 	if (response->util_str_avail) {
@@ -407,6 +410,7 @@
 
 static void __clp_add(struct clp_fh_list_entry *entry, void *data)
 {
+	struct list_head *scan_list = data;
 	struct zpci_dev *zdev;
 
 	if (!entry->vendor_id)
@@ -417,10 +421,13 @@
 		zpci_zdev_put(zdev);
 		return;
 	}
-	zpci_create_device(entry->fid, entry->fh, entry->config_state);
+	zdev = zpci_create_device(entry->fid, entry->fh, entry->config_state);
+	if (IS_ERR(zdev))
+		return;
+	list_add_tail(&zdev->entry, scan_list);
 }
 
-int clp_scan_pci_devices(void)
+int clp_scan_pci_devices(struct list_head *scan_list)
 {
 	struct clp_req_rsp_list_pci *rrb;
 	int rc;
@@ -429,7 +436,7 @@
 	if (!rrb)
 		return -ENOMEM;
 
-	rc = clp_list_pci(rrb, NULL, __clp_add);
+	rc = clp_list_pci(rrb, scan_list, __clp_add);
 
 	clp_free_block(rrb);
 	return rc;
--- linux-qcom-6.8.0.orig/arch/s390/pci/pci_debug.c
+++ linux-qcom-6.8.0/arch/s390/pci/pci_debug.c
@@ -71,17 +71,23 @@
 
 static void pci_sw_counter_show(struct seq_file *m)
 {
-	struct zpci_iommu_ctrs  *ctrs = zpci_get_iommu_ctrs(m->private);
+	struct zpci_dev *zdev = m->private;
+	struct zpci_iommu_ctrs *ctrs;
 	atomic64_t *counter;
+	unsigned long flags;
 	int i;
 
+	spin_lock_irqsave(&zdev->dom_lock, flags);
+	ctrs = zpci_get_iommu_ctrs(m->private);
 	if (!ctrs)
-		return;
+		goto unlock;
 
 	counter = &ctrs->mapped_pages;
 	for (i = 0; i < ARRAY_SIZE(pci_sw_names); i++, counter++)
 		seq_printf(m, "%26s:\t%llu\n", pci_sw_names[i],
 			   atomic64_read(counter));
+unlock:
+	spin_unlock_irqrestore(&zdev->dom_lock, flags);
 }
 
 static int pci_perf_show(struct seq_file *m, void *v)
@@ -91,9 +97,9 @@
 	if (!zdev)
 		return 0;
 
-	mutex_lock(&zdev->lock);
+	mutex_lock(&zdev->fmb_lock);
 	if (!zdev->fmb) {
-		mutex_unlock(&zdev->lock);
+		mutex_unlock(&zdev->fmb_lock);
 		seq_puts(m, "FMB statistics disabled\n");
 		return 0;
 	}
@@ -130,7 +136,7 @@
 	}
 
 	pci_sw_counter_show(m);
-	mutex_unlock(&zdev->lock);
+	mutex_unlock(&zdev->fmb_lock);
 	return 0;
 }
 
@@ -148,7 +154,7 @@
 	if (rc)
 		return rc;
 
-	mutex_lock(&zdev->lock);
+	mutex_lock(&zdev->fmb_lock);
 	switch (val) {
 	case 0:
 		rc = zpci_fmb_disable_device(zdev);
@@ -157,7 +163,7 @@
 		rc = zpci_fmb_enable_device(zdev);
 		break;
 	}
-	mutex_unlock(&zdev->lock);
+	mutex_unlock(&zdev->fmb_lock);
 	return rc ? rc : count;
 }
 
--- linux-qcom-6.8.0.orig/arch/s390/pci/pci_event.c
+++ linux-qcom-6.8.0/arch/s390/pci/pci_event.c
@@ -267,6 +267,7 @@
 	zpci_err_hex(ccdf, sizeof(*ccdf));
 
 	if (zdev) {
+		mutex_lock(&zdev->state_lock);
 		zpci_update_fh(zdev, ccdf->fh);
 		if (zdev->zbus->bus)
 			pdev = pci_get_slot(zdev->zbus->bus, zdev->devfn);
@@ -279,21 +280,24 @@
 		goto no_pdev;
 
 	switch (ccdf->pec) {
-	case 0x003a: /* Service Action or Error Recovery Successful */
+	case 0x002a: /* Error event concerns FMB */
+	case 0x002b:
+	case 0x002c:
+		break;
+	case 0x0040: /* Service Action or Error Recovery Failed */
+	case 0x003b:
+		zpci_event_io_failure(pdev, pci_channel_io_perm_failure);
+		break;
+	default: /* PCI function left in the error state attempt to recover */
 		ers_res = zpci_event_attempt_error_recovery(pdev);
 		if (ers_res != PCI_ERS_RESULT_RECOVERED)
 			zpci_event_io_failure(pdev, pci_channel_io_perm_failure);
 		break;
-	default:
-		/*
-		 * Mark as frozen not permanently failed because the device
-		 * could be subsequently recovered by the platform.
-		 */
-		zpci_event_io_failure(pdev, pci_channel_io_frozen);
-		break;
 	}
 	pci_dev_put(pdev);
 no_pdev:
+	if (zdev)
+		mutex_unlock(&zdev->state_lock);
 	zpci_zdev_put(zdev);
 }
 
@@ -318,6 +322,22 @@
 	zdev->state = ZPCI_FN_STATE_STANDBY;
 }
 
+static void zpci_event_reappear(struct zpci_dev *zdev)
+{
+	lockdep_assert_held(&zdev->state_lock);
+	/*
+	 * The zdev is in the reserved state. This means that it was presumed to
+	 * go away but there are still undropped references. Now, the platform
+	 * announced its availability again. Bring back the lingering zdev
+	 * to standby. This is safe because we hold a temporary reference
+	 * now so that it won't go away. Account for the re-appearance of the
+	 * underlying device by incrementing the reference count.
+	 */
+	zdev->state = ZPCI_FN_STATE_STANDBY;
+	zpci_zdev_get(zdev);
+	zpci_dbg(1, "rea fid:%x, fh:%x\n", zdev->fid, zdev->fh);
+}
+
 static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
 {
 	struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
@@ -326,25 +346,44 @@
 
 	zpci_dbg(3, "avl fid:%x, fh:%x, pec:%x\n",
 		 ccdf->fid, ccdf->fh, ccdf->pec);
+
+	if (existing_zdev)
+		mutex_lock(&zdev->state_lock);
+
 	switch (ccdf->pec) {
 	case 0x0301: /* Reserved|Standby -> Configured */
 		if (!zdev) {
 			zdev = zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_CONFIGURED);
 			if (IS_ERR(zdev))
 				break;
+			if (zpci_add_device(zdev)) {
+				kfree(zdev);
+				break;
+			}
 		} else {
+			if (zdev->state == ZPCI_FN_STATE_RESERVED)
+				zpci_event_reappear(zdev);
 			/* the configuration request may be stale */
-			if (zdev->state != ZPCI_FN_STATE_STANDBY)
+			else if (zdev->state != ZPCI_FN_STATE_STANDBY)
 				break;
 			zdev->state = ZPCI_FN_STATE_CONFIGURED;
 		}
 		zpci_scan_configured_device(zdev, ccdf->fh);
 		break;
 	case 0x0302: /* Reserved -> Standby */
-		if (!zdev)
-			zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_STANDBY);
-		else
+		if (!zdev) {
+			zdev = zpci_create_device(ccdf->fid, ccdf->fh, ZPCI_FN_STATE_STANDBY);
+			if (IS_ERR(zdev))
+				break;
+			if (zpci_add_device(zdev)) {
+				kfree(zdev);
+				break;
+			}
+		} else {
+			if (zdev->state == ZPCI_FN_STATE_RESERVED)
+				zpci_event_reappear(zdev);
 			zpci_update_fh(zdev, ccdf->fh);
+		}
 		break;
 	case 0x0303: /* Deconfiguration requested */
 		if (zdev) {
@@ -373,7 +412,7 @@
 		break;
 	case 0x0306: /* 0x308 or 0x302 for multiple devices */
 		zpci_remove_reserved_devices();
-		clp_scan_pci_devices();
+		zpci_scan_devices();
 		break;
 	case 0x0308: /* Standby -> Reserved */
 		if (!zdev)
@@ -383,8 +422,10 @@
 	default:
 		break;
 	}
-	if (existing_zdev)
+	if (existing_zdev) {
+		mutex_unlock(&zdev->state_lock);
 		zpci_zdev_put(zdev);
+	}
 }
 
 void zpci_event_availability(void *data)
--- linux-qcom-6.8.0.orig/arch/s390/pci/pci_iov.c
+++ linux-qcom-6.8.0/arch/s390/pci/pci_iov.c
@@ -60,18 +60,35 @@
 	return 0;
 }
 
-int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn)
+/**
+ * zpci_iov_find_parent_pf - Find the parent PF, if any, of the given function
+ * @zbus:	The bus that the PCI function is on, or would be added on
+ * @zdev:	The PCI function
+ *
+ * Finds the parent PF, if it exists and is configured, of the given PCI function
+ * and increments its refcount. Th PF is searched for on the provided bus so the
+ * caller has to ensure that this is the correct bus to search. This function may
+ * be used before adding the PCI function to a zbus.
+ *
+ * Return: Pointer to the struct pci_dev of the parent PF or NULL if it not
+ * found. If the function is not a VF or has no RequesterID information,
+ * NULL is returned as well.
+ */
+struct pci_dev *zpci_iov_find_parent_pf(struct zpci_bus *zbus, struct zpci_dev *zdev)
 {
-	int i, cand_devfn;
-	struct zpci_dev *zdev;
+	int i, vfid, devfn, cand_devfn;
 	struct pci_dev *pdev;
-	int vfid = vfn - 1; /* Linux' vfid's start at 0 vfn at 1*/
-	int rc = 0;
 
 	if (!zbus->multifunction)
-		return 0;
-
-	/* If the parent PF for the given VF is also configured in the
+		return NULL;
+	/* Non-VFs and VFs without RID available don't have a parent */
+	if (!zdev->vfn || !zdev->rid_available)
+		return NULL;
+	/* Linux vfid starts at 0 vfn at 1 */
+	vfid = zdev->vfn - 1;
+	devfn = zdev->rid & ZPCI_RID_MASK_DEVFN;
+	/*
+	 * If the parent PF for the given VF is also configured in the
 	 * instance, it must be on the same zbus.
 	 * We can then identify the parent PF by checking what
 	 * devfn the VF would have if it belonged to that PF using the PF's
@@ -85,15 +102,26 @@
 			if (!pdev)
 				continue;
 			cand_devfn = pci_iov_virtfn_devfn(pdev, vfid);
-			if (cand_devfn == virtfn->devfn) {
-				rc = zpci_iov_link_virtfn(pdev, virtfn, vfid);
-				/* balance pci_get_slot() */
-				pci_dev_put(pdev);
-				break;
-			}
+			if (cand_devfn == devfn)
+				return pdev;
 			/* balance pci_get_slot() */
 			pci_dev_put(pdev);
 		}
 	}
+	return NULL;
+}
+
+int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn)
+{
+	struct zpci_dev *zdev = to_zpci(virtfn);
+	struct pci_dev *pdev_pf;
+	int rc = 0;
+
+	pdev_pf = zpci_iov_find_parent_pf(zbus, zdev);
+	if (pdev_pf) {
+		/* Linux' vfids start at 0 while zdev->vfn starts at 1 */
+		rc = zpci_iov_link_virtfn(pdev_pf, virtfn, zdev->vfn - 1);
+		pci_dev_put(pdev_pf);
+	}
 	return rc;
 }
--- linux-qcom-6.8.0.orig/arch/s390/pci/pci_iov.h
+++ linux-qcom-6.8.0/arch/s390/pci/pci_iov.h
@@ -17,6 +17,8 @@
 
 int zpci_iov_setup_virtfn(struct zpci_bus *zbus, struct pci_dev *virtfn, int vfn);
 
+struct pci_dev *zpci_iov_find_parent_pf(struct zpci_bus *zbus, struct zpci_dev *zdev);
+
 #else /* CONFIG_PCI_IOV */
 static inline void zpci_iov_remove_virtfn(struct pci_dev *pdev, int vfn) {}
 
@@ -26,5 +28,10 @@
 {
 	return 0;
 }
+
+static inline struct pci_dev *zpci_iov_find_parent_pf(struct zpci_bus *zbus, struct zpci_dev *zdev)
+{
+	return NULL;
+}
 #endif /* CONFIG_PCI_IOV */
 #endif /* __S390_PCI_IOV_h */
--- linux-qcom-6.8.0.orig/arch/s390/pci/pci_irq.c
+++ linux-qcom-6.8.0/arch/s390/pci/pci_irq.c
@@ -268,33 +268,20 @@
 	}
 }
 
-int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+static int __alloc_airq(struct zpci_dev *zdev, int msi_vecs,
+			unsigned long *bit)
 {
-	struct zpci_dev *zdev = to_zpci(pdev);
-	unsigned int hwirq, msi_vecs, cpu;
-	unsigned long bit;
-	struct msi_desc *msi;
-	struct msi_msg msg;
-	int cpu_addr;
-	int rc, irq;
-
-	zdev->aisb = -1UL;
-	zdev->msi_first_bit = -1U;
-	if (type == PCI_CAP_ID_MSI && nvec > 1)
-		return 1;
-	msi_vecs = min_t(unsigned int, nvec, zdev->max_msi);
-
 	if (irq_delivery == DIRECTED) {
 		/* Allocate cpu vector bits */
-		bit = airq_iv_alloc(zpci_ibv[0], msi_vecs);
-		if (bit == -1UL)
+		*bit = airq_iv_alloc(zpci_ibv[0], msi_vecs);
+		if (*bit == -1UL)
 			return -EIO;
 	} else {
 		/* Allocate adapter summary indicator bit */
-		bit = airq_iv_alloc_bit(zpci_sbv);
-		if (bit == -1UL)
+		*bit = airq_iv_alloc_bit(zpci_sbv);
+		if (*bit == -1UL)
 			return -EIO;
-		zdev->aisb = bit;
+		zdev->aisb = *bit;
 
 		/* Create adapter interrupt vector */
 		zdev->aibv = airq_iv_create(msi_vecs, AIRQ_IV_DATA | AIRQ_IV_BITLOCK, NULL);
@@ -302,27 +289,66 @@
 			return -ENOMEM;
 
 		/* Wire up shortcut pointer */
-		zpci_ibv[bit] = zdev->aibv;
+		zpci_ibv[*bit] = zdev->aibv;
 		/* Each function has its own interrupt vector */
-		bit = 0;
+		*bit = 0;
+	}
+	return 0;
+}
+
+int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+{
+	unsigned int hwirq, msi_vecs, irqs_per_msi, i, cpu;
+	struct zpci_dev *zdev = to_zpci(pdev);
+	struct msi_desc *msi;
+	struct msi_msg msg;
+	unsigned long bit;
+	int cpu_addr;
+	int rc, irq;
+
+	zdev->aisb = -1UL;
+	zdev->msi_first_bit = -1U;
+
+	msi_vecs = min_t(unsigned int, nvec, zdev->max_msi);
+	if (msi_vecs < nvec) {
+		pr_info("%s requested %d irqs, allocate system limit of %d",
+			pci_name(pdev), nvec, zdev->max_msi);
 	}
 
-	/* Request MSI interrupts */
+	rc = __alloc_airq(zdev, msi_vecs, &bit);
+	if (rc < 0)
+		return rc;
+
+	/*
+	 * Request MSI interrupts:
+	 * When using MSI, nvec_used interrupt sources and their irq
+	 * descriptors are controlled through one msi descriptor.
+	 * Thus the outer loop over msi descriptors shall run only once,
+	 * while two inner loops iterate over the interrupt vectors.
+	 * When using MSI-X, each interrupt vector/irq descriptor
+	 * is bound to exactly one msi descriptor (nvec_used is one).
+	 * So the inner loops are executed once, while the outer iterates
+	 * over the MSI-X descriptors.
+	 */
 	hwirq = bit;
 	msi_for_each_desc(msi, &pdev->dev, MSI_DESC_NOTASSOCIATED) {
-		rc = -EIO;
 		if (hwirq - bit >= msi_vecs)
 			break;
-		irq = __irq_alloc_descs(-1, 0, 1, 0, THIS_MODULE,
-				(irq_delivery == DIRECTED) ?
-				msi->affinity : NULL);
+		irqs_per_msi = min_t(unsigned int, msi_vecs, msi->nvec_used);
+		irq = __irq_alloc_descs(-1, 0, irqs_per_msi, 0, THIS_MODULE,
+					(irq_delivery == DIRECTED) ?
+					msi->affinity : NULL);
 		if (irq < 0)
 			return -ENOMEM;
-		rc = irq_set_msi_desc(irq, msi);
-		if (rc)
-			return rc;
-		irq_set_chip_and_handler(irq, &zpci_irq_chip,
-					 handle_percpu_irq);
+
+		for (i = 0; i < irqs_per_msi; i++) {
+			rc = irq_set_msi_desc_off(irq, i, msi);
+			if (rc)
+				return rc;
+			irq_set_chip_and_handler(irq + i, &zpci_irq_chip,
+						 handle_percpu_irq);
+		}
+
 		msg.data = hwirq - bit;
 		if (irq_delivery == DIRECTED) {
 			if (msi->affinity)
@@ -335,31 +361,35 @@
 			msg.address_lo |= (cpu_addr << 8);
 
 			for_each_possible_cpu(cpu) {
-				airq_iv_set_data(zpci_ibv[cpu], hwirq, irq);
+				for (i = 0; i < irqs_per_msi; i++)
+					airq_iv_set_data(zpci_ibv[cpu],
+							 hwirq + i, irq + i);
 			}
 		} else {
 			msg.address_lo = zdev->msi_addr & 0xffffffff;
-			airq_iv_set_data(zdev->aibv, hwirq, irq);
+			for (i = 0; i < irqs_per_msi; i++)
+				airq_iv_set_data(zdev->aibv, hwirq + i, irq + i);
 		}
 		msg.address_hi = zdev->msi_addr >> 32;
 		pci_write_msi_msg(irq, &msg);
-		hwirq++;
+		hwirq += irqs_per_msi;
 	}
 
 	zdev->msi_first_bit = bit;
-	zdev->msi_nr_irqs = msi_vecs;
+	zdev->msi_nr_irqs = hwirq - bit;
 
 	rc = zpci_set_irq(zdev);
 	if (rc)
 		return rc;
 
-	return (msi_vecs == nvec) ? 0 : msi_vecs;
+	return (zdev->msi_nr_irqs == nvec) ? 0 : zdev->msi_nr_irqs;
 }
 
 void arch_teardown_msi_irqs(struct pci_dev *pdev)
 {
 	struct zpci_dev *zdev = to_zpci(pdev);
 	struct msi_desc *msi;
+	unsigned int i;
 	int rc;
 
 	/* Disable interrupts */
@@ -369,8 +399,10 @@
 
 	/* Release MSI interrupts */
 	msi_for_each_desc(msi, &pdev->dev, MSI_DESC_ASSOCIATED) {
-		irq_set_msi_desc(msi->irq, NULL);
-		irq_free_desc(msi->irq);
+		for (i = 0; i < msi->nvec_used; i++) {
+			irq_set_msi_desc(msi->irq + i, NULL);
+			irq_free_desc(msi->irq + i);
+		}
 		msi->msg.address_lo = 0;
 		msi->msg.address_hi = 0;
 		msi->msg.data = 0;
@@ -410,7 +442,7 @@
 	union zpci_sic_iib iib = {{0}};
 	union zpci_sic_iib ziib = {{0}};
 
-	iib.cdiib.dibv_addr = (u64) zpci_ibv[smp_processor_id()]->vector;
+	iib.cdiib.dibv_addr = virt_to_phys(zpci_ibv[smp_processor_id()]->vector);
 
 	zpci_set_irq_ctrl(SIC_IRQ_MODE_SET_CPU, 0, &iib);
 	zpci_set_irq_ctrl(SIC_IRQ_MODE_D_SINGLE, PCI_ISC, &ziib);
--- linux-qcom-6.8.0.orig/arch/s390/pci/pci_sysfs.c
+++ linux-qcom-6.8.0/arch/s390/pci/pci_sysfs.c
@@ -49,6 +49,39 @@
 }
 static DEVICE_ATTR_RO(mio_enabled);
 
+static int _do_recover(struct pci_dev *pdev, struct zpci_dev *zdev)
+{
+	u8 status;
+	int ret;
+
+	pci_stop_and_remove_bus_device(pdev);
+	if (zdev_enabled(zdev)) {
+		ret = zpci_disable_device(zdev);
+		/*
+		 * Due to a z/VM vs LPAR inconsistency in the error
+		 * state the FH may indicate an enabled device but
+		 * disable says the device is already disabled don't
+		 * treat it as an error here.
+		 */
+		if (ret == -EINVAL)
+			ret = 0;
+		if (ret)
+			return ret;
+	}
+
+	ret = zpci_enable_device(zdev);
+	if (ret)
+		return ret;
+
+	if (zdev->dma_table) {
+		ret = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
+					 virt_to_phys(zdev->dma_table), &status);
+		if (ret)
+			zpci_disable_device(zdev);
+	}
+	return ret;
+}
+
 static ssize_t recover_store(struct device *dev, struct device_attribute *attr,
 			     const char *buf, size_t count)
 {
@@ -56,7 +89,6 @@
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct zpci_dev *zdev = to_zpci(pdev);
 	int ret = 0;
-	u8 status;
 
 	/* Can't use device_remove_self() here as that would lead us to lock
 	 * the pci_rescan_remove_lock while holding the device' kernfs lock.
@@ -70,6 +102,12 @@
 	 */
 	kn = sysfs_break_active_protection(&dev->kobj, &attr->attr);
 	WARN_ON_ONCE(!kn);
+
+	/* Device needs to be configured and state must not change */
+	mutex_lock(&zdev->state_lock);
+	if (zdev->state != ZPCI_FN_STATE_CONFIGURED)
+		goto out;
+
 	/* device_remove_file() serializes concurrent calls ignoring all but
 	 * the first
 	 */
@@ -82,35 +120,13 @@
 	 */
 	pci_lock_rescan_remove();
 	if (pci_dev_is_added(pdev)) {
-		pci_stop_and_remove_bus_device(pdev);
-		if (zdev_enabled(zdev)) {
-			ret = zpci_disable_device(zdev);
-			/*
-			 * Due to a z/VM vs LPAR inconsistency in the error
-			 * state the FH may indicate an enabled device but
-			 * disable says the device is already disabled don't
-			 * treat it as an error here.
-			 */
-			if (ret == -EINVAL)
-				ret = 0;
-			if (ret)
-				goto out;
-		}
-
-		ret = zpci_enable_device(zdev);
-		if (ret)
-			goto out;
-
-		if (zdev->dma_table) {
-			ret = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
-						 virt_to_phys(zdev->dma_table), &status);
-			if (ret)
-				zpci_disable_device(zdev);
-		}
+		ret = _do_recover(pdev, zdev);
 	}
-out:
 	pci_rescan_bus(zdev->zbus->bus);
 	pci_unlock_rescan_remove();
+
+out:
+	mutex_unlock(&zdev->state_lock);
 	if (kn)
 		sysfs_unbreak_active_protection(kn);
 	return ret ? ret : count;
--- linux-qcom-6.8.0.orig/arch/s390/purgatory/Makefile
+++ linux-qcom-6.8.0/arch/s390/purgatory/Makefile
@@ -21,7 +21,7 @@
 KASAN_SANITIZE := n
 KCSAN_SANITIZE := n
 
-KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes
+KBUILD_CFLAGS := -std=gnu11 -fno-strict-aliasing -Wall -Wstrict-prototypes
 KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare
 KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding
 KBUILD_CFLAGS += -Os -m64 -msoft-float -fno-common
--- linux-qcom-6.8.0.orig/arch/sh/kernel/cpu/proc.c
+++ linux-qcom-6.8.0/arch/sh/kernel/cpu/proc.c
@@ -132,7 +132,7 @@
 
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
-	return *pos < NR_CPUS ? cpu_data + *pos : NULL;
+	return *pos < nr_cpu_ids ? cpu_data + *pos : NULL;
 }
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
--- linux-qcom-6.8.0.orig/arch/sh/kernel/kprobes.c
+++ linux-qcom-6.8.0/arch/sh/kernel/kprobes.c
@@ -44,17 +44,12 @@
 	if (OPCODE_RTE(opcode))
 		return -EFAULT;	/* Bad breakpoint */
 
+	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
 	p->opcode = opcode;
 
 	return 0;
 }
 
-void __kprobes arch_copy_kprobe(struct kprobe *p)
-{
-	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
-	p->opcode = *p->addr;
-}
-
 void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
 	*p->addr = BREAKPOINT_INSTRUCTION;
--- linux-qcom-6.8.0.orig/arch/sh/kernel/setup.c
+++ linux-qcom-6.8.0/arch/sh/kernel/setup.c
@@ -255,7 +255,7 @@
 	dt_virt = phys_to_virt(dt_phys);
 #endif
 
-	if (!dt_virt || !early_init_dt_scan(dt_virt)) {
+	if (!dt_virt || !early_init_dt_scan(dt_virt, __pa(dt_virt))) {
 		pr_crit("Error: invalid device tree blob"
 			" at physical address %p\n", (void *)dt_phys);
 
--- linux-qcom-6.8.0.orig/arch/sh/kernel/sys_sh32.c
+++ linux-qcom-6.8.0/arch/sh/kernel/sys_sh32.c
@@ -59,3 +59,14 @@
 				 (u64)len0 << 32 | len1, advice);
 #endif
 }
+
+/*
+ * swap the arguments the way that libc wants them instead of
+ * moving flags ahead of the 64-bit nbytes argument
+ */
+SYSCALL_DEFINE6(sh_sync_file_range6, int, fd, SC_ARG64(offset),
+                SC_ARG64(nbytes), unsigned int, flags)
+{
+        return ksys_sync_file_range(fd, SC_VAL64(loff_t, offset),
+                                    SC_VAL64(loff_t, nbytes), flags);
+}
--- linux-qcom-6.8.0.orig/arch/sh/kernel/syscalls/syscall.tbl
+++ linux-qcom-6.8.0/arch/sh/kernel/syscalls/syscall.tbl
@@ -321,7 +321,7 @@
 311	common	set_robust_list			sys_set_robust_list
 312	common	get_robust_list			sys_get_robust_list
 313	common	splice				sys_splice
-314	common	sync_file_range			sys_sync_file_range
+314	common	sync_file_range			sys_sh_sync_file_range6
 315	common	tee				sys_tee
 316	common	vmsplice			sys_vmsplice
 317	common	move_pages			sys_move_pages
@@ -395,6 +395,7 @@
 385	common	pkey_alloc			sys_pkey_alloc
 386	common	pkey_free			sys_pkey_free
 387	common	rseq				sys_rseq
+388	common	sync_file_range2		sys_sync_file_range2
 # room for arch specific syscalls
 393	common	semget				sys_semget
 394	common	semctl				sys_semctl
--- linux-qcom-6.8.0.orig/arch/sh/lib/checksum.S
+++ linux-qcom-6.8.0/arch/sh/lib/checksum.S
@@ -33,7 +33,8 @@
  */
 
 /*	
- * asmlinkage __wsum csum_partial(const void *buf, int len, __wsum sum);
+ * unsigned int csum_partial(const unsigned char *buf, int len,
+ *                           unsigned int sum);
  */
 
 .text
@@ -45,31 +46,11 @@
 	   * Fortunately, it is easy to convert 2-byte alignment to 4-byte
 	   * alignment for the unrolled loop.
 	   */
+	mov	r5, r1
 	mov	r4, r0
-	tst	#3, r0		! Check alignment.
-	bt/s	2f		! Jump if alignment is ok.
-	 mov	r4, r7		! Keep a copy to check for alignment
+	tst	#2, r0		! Check alignment.
+	bt	2f		! Jump if alignment is ok.
 	!
-	tst	#1, r0		! Check alignment.
-	bt	21f		! Jump if alignment is boundary of 2bytes.
-
-	! buf is odd
-	tst	r5, r5
-	add	#-1, r5
-	bt	9f
-	mov.b	@r4+, r0
-	extu.b	r0, r0
-	addc	r0, r6		! t=0 from previous tst
-	mov	r6, r0
-	shll8	r6
-	shlr16	r0
-	shlr8	r0
-	or	r0, r6
-	mov	r4, r0
-	tst	#2, r0
-	bt	2f
-21:
-	! buf is 2 byte aligned (len could be 0)
 	add	#-2, r5		! Alignment uses up two bytes.
 	cmp/pz	r5		!
 	bt/s	1f		! Jump if we had at least two bytes.
@@ -77,17 +58,16 @@
 	bra	6f
 	 add	#2, r5		! r5 was < 2.  Deal with it.
 1:
+	mov	r5, r1		! Save new len for later use.
 	mov.w	@r4+, r0
 	extu.w	r0, r0
 	addc	r0, r6
 	bf	2f
 	add	#1, r6
 2:
-	! buf is 4 byte aligned (len could be 0)
-	mov	r5, r1
 	mov	#-5, r0
-	shld	r0, r1
-	tst	r1, r1
+	shld	r0, r5
+	tst	r5, r5
 	bt/s	4f		! if it's =0, go to 4f
 	 clrt
 	.align	2
@@ -109,31 +89,30 @@
 	addc	r0, r6
 	addc	r2, r6
 	movt	r0
-	dt	r1
+	dt	r5
 	bf/s	3b
 	 cmp/eq	#1, r0
-	! here, we know r1==0
-	addc	r1, r6			! add carry to r6
+	! here, we know r5==0
+	addc	r5, r6			! add carry to r6
 4:
-	mov	r5, r0
+	mov	r1, r0
 	and	#0x1c, r0
 	tst	r0, r0
-	bt	6f
-	! 4 bytes or more remaining
-	mov	r0, r1
-	shlr2	r1
+	bt/s	6f
+	 mov	r0, r5
+	shlr2	r5
 	mov	#0, r2
 5:
 	addc	r2, r6
 	mov.l	@r4+, r2
 	movt	r0
-	dt	r1
+	dt	r5
 	bf/s	5b
 	 cmp/eq	#1, r0
 	addc	r2, r6
-	addc	r1, r6		! r1==0 here, so it means add carry-bit
+	addc	r5, r6		! r5==0 here, so it means add carry-bit
 6:
-	! 3 bytes or less remaining
+	mov	r1, r5
 	mov	#3, r0
 	and	r0, r5
 	tst	r5, r5
@@ -159,16 +138,6 @@
 	mov	#0, r0
 	addc	r0, r6
 9:
-	! Check if the buffer was misaligned, if so realign sum
-	mov	r7, r0
-	tst	#1, r0
-	bt	10f
-	mov	r6, r0
-	shll8	r6
-	shlr16	r0
-	shlr8	r0
-	or	r0, r6
-10:
 	rts
 	 mov	r6, r0
 
--- linux-qcom-6.8.0.orig/arch/sparc/Kconfig
+++ linux-qcom-6.8.0/arch/sparc/Kconfig
@@ -57,6 +57,8 @@
 	select CLZ_TAB
 	select DMA_DIRECT_REMAP
 	select GENERIC_ATOMIC64
+	select GENERIC_LIB_CMPDI2
+	select GENERIC_LIB_UCMPDI2
 	select HAVE_UID16
 	select LOCK_MM_AND_FIND_VMA
 	select OLD_SIGACTION
@@ -140,10 +142,6 @@
 	default y if SPARC32
 	select KMAP_LOCAL
 
-config GENERIC_ISA_DMA
-	bool
-	default y if SPARC32
-
 config PGTABLE_LEVELS
 	default 4 if 64BIT
 	default 3
--- linux-qcom-6.8.0.orig/arch/sparc/include/asm/oplib_64.h
+++ linux-qcom-6.8.0/arch/sparc/include/asm/oplib_64.h
@@ -247,6 +247,7 @@
 int prom_ihandle2path(int handle, char *buffer, int bufsize);
 
 /* Client interface level routines. */
+void prom_cif_init(void *cif_handler);
 void p1275_cmd_direct(unsigned long *);
 
 #endif /* !(__SPARC64_OPLIB_H) */
--- linux-qcom-6.8.0.orig/arch/sparc/include/asm/parport.h
+++ linux-qcom-6.8.0/arch/sparc/include/asm/parport.h
@@ -1,256 +1,11 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-/* parport.h: sparc64 specific parport initialization and dma.
- *
- * Copyright (C) 1999  Eddie C. Dost  (ecd@skynet.be)
- */
+#ifndef ___ASM_SPARC_PARPORT_H
+#define ___ASM_SPARC_PARPORT_H
 
-#ifndef _ASM_SPARC64_PARPORT_H
-#define _ASM_SPARC64_PARPORT_H 1
-
-#include <linux/of.h>
-#include <linux/platform_device.h>
-
-#include <asm/ebus_dma.h>
-#include <asm/ns87303.h>
-#include <asm/prom.h>
-
-#define PARPORT_PC_MAX_PORTS	PARPORT_MAX
-
-/*
- * While sparc64 doesn't have an ISA DMA API, we provide something that looks
- * close enough to make parport_pc happy
- */
-#define HAS_DMA
-
-#ifdef CONFIG_PARPORT_PC_FIFO
-static DEFINE_SPINLOCK(dma_spin_lock);
-
-#define claim_dma_lock() \
-({	unsigned long flags; \
-	spin_lock_irqsave(&dma_spin_lock, flags); \
-	flags; \
-})
-
-#define release_dma_lock(__flags) \
-	spin_unlock_irqrestore(&dma_spin_lock, __flags);
+#if defined(__sparc__) && defined(__arch64__)
+#include <asm/parport_64.h>
+#else
+#include <asm-generic/parport.h>
+#endif
 #endif
 
-static struct sparc_ebus_info {
-	struct ebus_dma_info info;
-	unsigned int addr;
-	unsigned int count;
-	int lock;
-
-	struct parport *port;
-} sparc_ebus_dmas[PARPORT_PC_MAX_PORTS];
-
-static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS);
-
-static inline int request_dma(unsigned int dmanr, const char *device_id)
-{
-	if (dmanr >= PARPORT_PC_MAX_PORTS)
-		return -EINVAL;
-	if (xchg(&sparc_ebus_dmas[dmanr].lock, 1) != 0)
-		return -EBUSY;
-	return 0;
-}
-
-static inline void free_dma(unsigned int dmanr)
-{
-	if (dmanr >= PARPORT_PC_MAX_PORTS) {
-		printk(KERN_WARNING "Trying to free DMA%d\n", dmanr);
-		return;
-	}
-	if (xchg(&sparc_ebus_dmas[dmanr].lock, 0) == 0) {
-		printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr);
-		return;
-	}
-}
-
-static inline void enable_dma(unsigned int dmanr)
-{
-	ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1);
-
-	if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info,
-			     sparc_ebus_dmas[dmanr].addr,
-			     sparc_ebus_dmas[dmanr].count))
-		BUG();
-}
-
-static inline void disable_dma(unsigned int dmanr)
-{
-	ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 0);
-}
-
-static inline void clear_dma_ff(unsigned int dmanr)
-{
-	/* nothing */
-}
-
-static inline void set_dma_mode(unsigned int dmanr, char mode)
-{
-	ebus_dma_prepare(&sparc_ebus_dmas[dmanr].info, (mode != DMA_MODE_WRITE));
-}
-
-static inline void set_dma_addr(unsigned int dmanr, unsigned int addr)
-{
-	sparc_ebus_dmas[dmanr].addr = addr;
-}
-
-static inline void set_dma_count(unsigned int dmanr, unsigned int count)
-{
-	sparc_ebus_dmas[dmanr].count = count;
-}
-
-static inline unsigned int get_dma_residue(unsigned int dmanr)
-{
-	return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info);
-}
-
-static int ecpp_probe(struct platform_device *op)
-{
-	unsigned long base = op->resource[0].start;
-	unsigned long config = op->resource[1].start;
-	unsigned long d_base = op->resource[2].start;
-	unsigned long d_len;
-	struct device_node *parent;
-	struct parport *p;
-	int slot, err;
-
-	parent = op->dev.of_node->parent;
-	if (of_node_name_eq(parent, "dma")) {
-		p = parport_pc_probe_port(base, base + 0x400,
-					  op->archdata.irqs[0], PARPORT_DMA_NOFIFO,
-					  op->dev.parent->parent, 0);
-		if (!p)
-			return -ENOMEM;
-		dev_set_drvdata(&op->dev, p);
-		return 0;
-	}
-
-	for (slot = 0; slot < PARPORT_PC_MAX_PORTS; slot++) {
-		if (!test_and_set_bit(slot, dma_slot_map))
-			break;
-	}
-	err = -ENODEV;
-	if (slot >= PARPORT_PC_MAX_PORTS)
-		goto out_err;
-
-	spin_lock_init(&sparc_ebus_dmas[slot].info.lock);
-
-	d_len = (op->resource[2].end - d_base) + 1UL;
-	sparc_ebus_dmas[slot].info.regs =
-		of_ioremap(&op->resource[2], 0, d_len, "ECPP DMA");
-
-	if (!sparc_ebus_dmas[slot].info.regs)
-		goto out_clear_map;
-
-	sparc_ebus_dmas[slot].info.flags = 0;
-	sparc_ebus_dmas[slot].info.callback = NULL;
-	sparc_ebus_dmas[slot].info.client_cookie = NULL;
-	sparc_ebus_dmas[slot].info.irq = 0xdeadbeef;
-	strcpy(sparc_ebus_dmas[slot].info.name, "parport");
-	if (ebus_dma_register(&sparc_ebus_dmas[slot].info))
-		goto out_unmap_regs;
-
-	ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 1);
-
-	/* Configure IRQ to Push Pull, Level Low */
-	/* Enable ECP, set bit 2 of the CTR first */
-	outb(0x04, base + 0x02);
-	ns87303_modify(config, PCR,
-		       PCR_EPP_ENABLE |
-		       PCR_IRQ_ODRAIN,
-		       PCR_ECP_ENABLE |
-		       PCR_ECP_CLK_ENA |
-		       PCR_IRQ_POLAR);
-
-	/* CTR bit 5 controls direction of port */
-	ns87303_modify(config, PTR,
-		       0, PTR_LPT_REG_DIR);
-
-	p = parport_pc_probe_port(base, base + 0x400,
-				  op->archdata.irqs[0],
-				  slot,
-				  op->dev.parent,
-				  0);
-	err = -ENOMEM;
-	if (!p)
-		goto out_disable_irq;
-
-	dev_set_drvdata(&op->dev, p);
-
-	return 0;
-
-out_disable_irq:
-	ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
-	ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
-
-out_unmap_regs:
-	of_iounmap(&op->resource[2], sparc_ebus_dmas[slot].info.regs, d_len);
-
-out_clear_map:
-	clear_bit(slot, dma_slot_map);
-
-out_err:
-	return err;
-}
-
-static int ecpp_remove(struct platform_device *op)
-{
-	struct parport *p = dev_get_drvdata(&op->dev);
-	int slot = p->dma;
-
-	parport_pc_unregister_port(p);
-
-	if (slot != PARPORT_DMA_NOFIFO) {
-		unsigned long d_base = op->resource[2].start;
-		unsigned long d_len;
-
-		d_len = (op->resource[2].end - d_base) + 1UL;
-
-		ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
-		ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
-		of_iounmap(&op->resource[2],
-			   sparc_ebus_dmas[slot].info.regs,
-			   d_len);
-		clear_bit(slot, dma_slot_map);
-	}
-
-	return 0;
-}
-
-static const struct of_device_id ecpp_match[] = {
-	{
-		.name = "ecpp",
-	},
-	{
-		.name = "parallel",
-		.compatible = "ecpp",
-	},
-	{
-		.name = "parallel",
-		.compatible = "ns87317-ecpp",
-	},
-	{
-		.name = "parallel",
-		.compatible = "pnpALI,1533,3",
-	},
-	{},
-};
-
-static struct platform_driver ecpp_driver = {
-	.driver = {
-		.name = "ecpp",
-		.of_match_table = ecpp_match,
-	},
-	.probe			= ecpp_probe,
-	.remove			= ecpp_remove,
-};
-
-static int parport_pc_find_nonpci_ports(int autoirq, int autodma)
-{
-	return platform_driver_register(&ecpp_driver);
-}
-
-#endif /* !(_ASM_SPARC64_PARPORT_H */
--- linux-qcom-6.8.0.orig/arch/sparc/include/asm/parport_64.h
+++ linux-qcom-6.8.0/arch/sparc/include/asm/parport_64.h
@@ -0,0 +1,256 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* parport.h: sparc64 specific parport initialization and dma.
+ *
+ * Copyright (C) 1999  Eddie C. Dost  (ecd@skynet.be)
+ */
+
+#ifndef _ASM_SPARC64_PARPORT_H
+#define _ASM_SPARC64_PARPORT_H 1
+
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include <asm/ebus_dma.h>
+#include <asm/ns87303.h>
+#include <asm/prom.h>
+
+#define PARPORT_PC_MAX_PORTS	PARPORT_MAX
+
+/*
+ * While sparc64 doesn't have an ISA DMA API, we provide something that looks
+ * close enough to make parport_pc happy
+ */
+#define HAS_DMA
+
+#ifdef CONFIG_PARPORT_PC_FIFO
+static DEFINE_SPINLOCK(dma_spin_lock);
+
+#define claim_dma_lock() \
+({	unsigned long flags; \
+	spin_lock_irqsave(&dma_spin_lock, flags); \
+	flags; \
+})
+
+#define release_dma_lock(__flags) \
+	spin_unlock_irqrestore(&dma_spin_lock, __flags);
+#endif
+
+static struct sparc_ebus_info {
+	struct ebus_dma_info info;
+	unsigned int addr;
+	unsigned int count;
+	int lock;
+
+	struct parport *port;
+} sparc_ebus_dmas[PARPORT_PC_MAX_PORTS];
+
+static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS);
+
+static inline int request_dma(unsigned int dmanr, const char *device_id)
+{
+	if (dmanr >= PARPORT_PC_MAX_PORTS)
+		return -EINVAL;
+	if (xchg(&sparc_ebus_dmas[dmanr].lock, 1) != 0)
+		return -EBUSY;
+	return 0;
+}
+
+static inline void free_dma(unsigned int dmanr)
+{
+	if (dmanr >= PARPORT_PC_MAX_PORTS) {
+		printk(KERN_WARNING "Trying to free DMA%d\n", dmanr);
+		return;
+	}
+	if (xchg(&sparc_ebus_dmas[dmanr].lock, 0) == 0) {
+		printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr);
+		return;
+	}
+}
+
+static inline void enable_dma(unsigned int dmanr)
+{
+	ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1);
+
+	if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info,
+			     sparc_ebus_dmas[dmanr].addr,
+			     sparc_ebus_dmas[dmanr].count))
+		BUG();
+}
+
+static inline void disable_dma(unsigned int dmanr)
+{
+	ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 0);
+}
+
+static inline void clear_dma_ff(unsigned int dmanr)
+{
+	/* nothing */
+}
+
+static inline void set_dma_mode(unsigned int dmanr, char mode)
+{
+	ebus_dma_prepare(&sparc_ebus_dmas[dmanr].info, (mode != DMA_MODE_WRITE));
+}
+
+static inline void set_dma_addr(unsigned int dmanr, unsigned int addr)
+{
+	sparc_ebus_dmas[dmanr].addr = addr;
+}
+
+static inline void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+	sparc_ebus_dmas[dmanr].count = count;
+}
+
+static inline unsigned int get_dma_residue(unsigned int dmanr)
+{
+	return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info);
+}
+
+static int ecpp_probe(struct platform_device *op)
+{
+	unsigned long base = op->resource[0].start;
+	unsigned long config = op->resource[1].start;
+	unsigned long d_base = op->resource[2].start;
+	unsigned long d_len;
+	struct device_node *parent;
+	struct parport *p;
+	int slot, err;
+
+	parent = op->dev.of_node->parent;
+	if (of_node_name_eq(parent, "dma")) {
+		p = parport_pc_probe_port(base, base + 0x400,
+					  op->archdata.irqs[0], PARPORT_DMA_NOFIFO,
+					  op->dev.parent->parent, 0);
+		if (!p)
+			return -ENOMEM;
+		dev_set_drvdata(&op->dev, p);
+		return 0;
+	}
+
+	for (slot = 0; slot < PARPORT_PC_MAX_PORTS; slot++) {
+		if (!test_and_set_bit(slot, dma_slot_map))
+			break;
+	}
+	err = -ENODEV;
+	if (slot >= PARPORT_PC_MAX_PORTS)
+		goto out_err;
+
+	spin_lock_init(&sparc_ebus_dmas[slot].info.lock);
+
+	d_len = (op->resource[2].end - d_base) + 1UL;
+	sparc_ebus_dmas[slot].info.regs =
+		of_ioremap(&op->resource[2], 0, d_len, "ECPP DMA");
+
+	if (!sparc_ebus_dmas[slot].info.regs)
+		goto out_clear_map;
+
+	sparc_ebus_dmas[slot].info.flags = 0;
+	sparc_ebus_dmas[slot].info.callback = NULL;
+	sparc_ebus_dmas[slot].info.client_cookie = NULL;
+	sparc_ebus_dmas[slot].info.irq = 0xdeadbeef;
+	strcpy(sparc_ebus_dmas[slot].info.name, "parport");
+	if (ebus_dma_register(&sparc_ebus_dmas[slot].info))
+		goto out_unmap_regs;
+
+	ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 1);
+
+	/* Configure IRQ to Push Pull, Level Low */
+	/* Enable ECP, set bit 2 of the CTR first */
+	outb(0x04, base + 0x02);
+	ns87303_modify(config, PCR,
+		       PCR_EPP_ENABLE |
+		       PCR_IRQ_ODRAIN,
+		       PCR_ECP_ENABLE |
+		       PCR_ECP_CLK_ENA |
+		       PCR_IRQ_POLAR);
+
+	/* CTR bit 5 controls direction of port */
+	ns87303_modify(config, PTR,
+		       0, PTR_LPT_REG_DIR);
+
+	p = parport_pc_probe_port(base, base + 0x400,
+				  op->archdata.irqs[0],
+				  slot,
+				  op->dev.parent,
+				  0);
+	err = -ENOMEM;
+	if (!p)
+		goto out_disable_irq;
+
+	dev_set_drvdata(&op->dev, p);
+
+	return 0;
+
+out_disable_irq:
+	ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
+	ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
+
+out_unmap_regs:
+	of_iounmap(&op->resource[2], sparc_ebus_dmas[slot].info.regs, d_len);
+
+out_clear_map:
+	clear_bit(slot, dma_slot_map);
+
+out_err:
+	return err;
+}
+
+static int ecpp_remove(struct platform_device *op)
+{
+	struct parport *p = dev_get_drvdata(&op->dev);
+	int slot = p->dma;
+
+	parport_pc_unregister_port(p);
+
+	if (slot != PARPORT_DMA_NOFIFO) {
+		unsigned long d_base = op->resource[2].start;
+		unsigned long d_len;
+
+		d_len = (op->resource[2].end - d_base) + 1UL;
+
+		ebus_dma_irq_enable(&sparc_ebus_dmas[slot].info, 0);
+		ebus_dma_unregister(&sparc_ebus_dmas[slot].info);
+		of_iounmap(&op->resource[2],
+			   sparc_ebus_dmas[slot].info.regs,
+			   d_len);
+		clear_bit(slot, dma_slot_map);
+	}
+
+	return 0;
+}
+
+static const struct of_device_id ecpp_match[] = {
+	{
+		.name = "ecpp",
+	},
+	{
+		.name = "parallel",
+		.compatible = "ecpp",
+	},
+	{
+		.name = "parallel",
+		.compatible = "ns87317-ecpp",
+	},
+	{
+		.name = "parallel",
+		.compatible = "pnpALI,1533,3",
+	},
+	{},
+};
+
+static struct platform_driver ecpp_driver = {
+	.driver = {
+		.name = "ecpp",
+		.of_match_table = ecpp_match,
+	},
+	.probe			= ecpp_probe,
+	.remove			= ecpp_remove,
+};
+
+static int parport_pc_find_nonpci_ports(int autoirq, int autodma)
+{
+	return platform_driver_register(&ecpp_driver);
+}
+
+#endif /* !(_ASM_SPARC64_PARPORT_H */
--- linux-qcom-6.8.0.orig/arch/sparc/include/asm/smp_64.h
+++ linux-qcom-6.8.0/arch/sparc/include/asm/smp_64.h
@@ -47,7 +47,6 @@
 int hard_smp_processor_id(void);
 #define raw_smp_processor_id() (current_thread_info()->cpu)
 
-void smp_fill_in_cpu_possible_map(void);
 void smp_fill_in_sib_core_maps(void);
 void __noreturn cpu_play_dead(void);
 
@@ -77,7 +76,6 @@
 #define smp_fill_in_sib_core_maps() do { } while (0)
 #define smp_fetch_global_regs() do { } while (0)
 #define smp_fetch_global_pmu() do { } while (0)
-#define smp_fill_in_cpu_possible_map() do { } while (0)
 #define smp_init_cpu_poke() do { } while (0)
 #define scheduler_poke() do { } while (0)
 
--- linux-qcom-6.8.0.orig/arch/sparc/include/uapi/asm/termbits.h
+++ linux-qcom-6.8.0/arch/sparc/include/uapi/asm/termbits.h
@@ -10,16 +10,6 @@
 typedef unsigned long	tcflag_t;
 #endif
 
-#define NCC 8
-struct termio {
-	unsigned short c_iflag;		/* input mode flags */
-	unsigned short c_oflag;		/* output mode flags */
-	unsigned short c_cflag;		/* control mode flags */
-	unsigned short c_lflag;		/* local mode flags */
-	unsigned char c_line;		/* line discipline */
-	unsigned char c_cc[NCC];	/* control characters */
-};
-
 #define NCCS 17
 struct termios {
 	tcflag_t c_iflag;		/* input mode flags */
--- linux-qcom-6.8.0.orig/arch/sparc/include/uapi/asm/termios.h
+++ linux-qcom-6.8.0/arch/sparc/include/uapi/asm/termios.h
@@ -40,5 +40,14 @@
 	unsigned short ws_ypixel;
 };
 
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
 
 #endif /* _UAPI_SPARC_TERMIOS_H */
--- linux-qcom-6.8.0.orig/arch/sparc/kernel/leon_pci_grpci1.c
+++ linux-qcom-6.8.0/arch/sparc/kernel/leon_pci_grpci1.c
@@ -697,7 +697,7 @@
 	return err;
 }
 
-static const struct of_device_id grpci1_of_match[] __initconst = {
+static const struct of_device_id grpci1_of_match[] = {
 	{
 	 .name = "GAISLER_PCIFBRG",
 	 },
--- linux-qcom-6.8.0.orig/arch/sparc/kernel/leon_pci_grpci2.c
+++ linux-qcom-6.8.0/arch/sparc/kernel/leon_pci_grpci2.c
@@ -889,7 +889,7 @@
 	return err;
 }
 
-static const struct of_device_id grpci2_of_match[] __initconst = {
+static const struct of_device_id grpci2_of_match[] = {
 	{
 	 .name = "GAISLER_GRPCI2",
 	 },
--- linux-qcom-6.8.0.orig/arch/sparc/kernel/nmi.c
+++ linux-qcom-6.8.0/arch/sparc/kernel/nmi.c
@@ -279,7 +279,7 @@
 	if (!strncmp(str, "panic", 5))
 		panic_on_timeout = 1;
 
-	return 0;
+	return 1;
 }
 __setup("nmi_watchdog=", setup_nmi_watchdog);
 
--- linux-qcom-6.8.0.orig/arch/sparc/kernel/prom_64.c
+++ linux-qcom-6.8.0/arch/sparc/kernel/prom_64.c
@@ -483,7 +483,9 @@
 	ncpus_probed++;
 #ifdef CONFIG_SMP
 	set_cpu_present(cpuid, true);
-	set_cpu_possible(cpuid, true);
+
+	if (num_possible_cpus() < nr_cpu_ids)
+		set_cpu_possible(cpuid, true);
 #endif
 	return NULL;
 }
--- linux-qcom-6.8.0.orig/arch/sparc/kernel/setup_64.c
+++ linux-qcom-6.8.0/arch/sparc/kernel/setup_64.c
@@ -671,7 +671,6 @@
 
 	paging_init();
 	init_sparc64_elf_hwcap();
-	smp_fill_in_cpu_possible_map();
 	/*
 	 * Once the OF device tree and MDESC have been setup and nr_cpus has
 	 * been parsed, we know the list of possible cpus.  Therefore we can
--- linux-qcom-6.8.0.orig/arch/sparc/kernel/smp_64.c
+++ linux-qcom-6.8.0/arch/sparc/kernel/smp_64.c
@@ -1220,20 +1220,6 @@
 		xcall_deliver_impl = hypervisor_xcall_deliver;
 }
 
-void __init smp_fill_in_cpu_possible_map(void)
-{
-	int possible_cpus = num_possible_cpus();
-	int i;
-
-	if (possible_cpus > nr_cpu_ids)
-		possible_cpus = nr_cpu_ids;
-
-	for (i = 0; i < possible_cpus; i++)
-		set_cpu_possible(i, true);
-	for (; i < NR_CPUS; i++)
-		set_cpu_possible(i, false);
-}
-
 void smp_fill_in_sib_core_maps(void)
 {
 	unsigned int i;
--- linux-qcom-6.8.0.orig/arch/sparc/kernel/sys32.S
+++ linux-qcom-6.8.0/arch/sparc/kernel/sys32.S
@@ -18,224 +18,3 @@
 	sethi		%hi(sys_mmap), %g1
 	jmpl		%g1 + %lo(sys_mmap), %g0
 	 sllx		%o5, 12, %o5
-
-	.align		32
-	.globl		sys32_socketcall
-sys32_socketcall:	/* %o0=call, %o1=args */
-	cmp		%o0, 1
-	bl,pn		%xcc, do_einval
-	 cmp		%o0, 18
-	bg,pn		%xcc, do_einval
-	 sub		%o0, 1, %o0
-	sllx		%o0, 5, %o0
-	sethi		%hi(__socketcall_table_begin), %g2
-	or		%g2, %lo(__socketcall_table_begin), %g2
-	jmpl		%g2 + %o0, %g0
-	 nop
-do_einval:
-	retl
-	 mov		-EINVAL, %o0
-
-	.align		32
-__socketcall_table_begin:
-
-	/* Each entry is exactly 32 bytes. */
-do_sys_socket: /* sys_socket(int, int, int) */
-1:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_socket), %g1
-2:	ldswa		[%o1 + 0x8] %asi, %o2
-	jmpl		%g1 + %lo(sys_socket), %g0
-3:	 ldswa		[%o1 + 0x4] %asi, %o1
-	nop
-	nop
-	nop
-do_sys_bind: /* sys_bind(int fd, struct sockaddr *, int) */
-4:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_bind), %g1
-5:	ldswa		[%o1 + 0x8] %asi, %o2
-	jmpl		%g1 + %lo(sys_bind), %g0
-6:	 lduwa		[%o1 + 0x4] %asi, %o1
-	nop
-	nop
-	nop
-do_sys_connect: /* sys_connect(int, struct sockaddr *, int) */
-7:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_connect), %g1
-8:	ldswa		[%o1 + 0x8] %asi, %o2
-	jmpl		%g1 + %lo(sys_connect), %g0
-9:	 lduwa		[%o1 + 0x4] %asi, %o1
-	nop
-	nop
-	nop
-do_sys_listen: /* sys_listen(int, int) */
-10:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_listen), %g1
-	jmpl		%g1 + %lo(sys_listen), %g0
-11:	 ldswa		[%o1 + 0x4] %asi, %o1
-	nop
-	nop
-	nop
-	nop
-do_sys_accept: /* sys_accept(int, struct sockaddr *, int *) */
-12:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_accept), %g1
-13:	lduwa		[%o1 + 0x8] %asi, %o2
-	jmpl		%g1 + %lo(sys_accept), %g0
-14:	 lduwa		[%o1 + 0x4] %asi, %o1
-	nop
-	nop
-	nop
-do_sys_getsockname: /* sys_getsockname(int, struct sockaddr *, int *) */
-15:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_getsockname), %g1
-16:	lduwa		[%o1 + 0x8] %asi, %o2
-	jmpl		%g1 + %lo(sys_getsockname), %g0
-17:	 lduwa		[%o1 + 0x4] %asi, %o1
-	nop
-	nop
-	nop
-do_sys_getpeername: /* sys_getpeername(int, struct sockaddr *, int *) */
-18:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_getpeername), %g1
-19:	lduwa		[%o1 + 0x8] %asi, %o2
-	jmpl		%g1 + %lo(sys_getpeername), %g0
-20:	 lduwa		[%o1 + 0x4] %asi, %o1
-	nop
-	nop
-	nop
-do_sys_socketpair: /* sys_socketpair(int, int, int, int *) */
-21:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_socketpair), %g1
-22:	ldswa		[%o1 + 0x8] %asi, %o2
-23:	lduwa		[%o1 + 0xc] %asi, %o3
-	jmpl		%g1 + %lo(sys_socketpair), %g0
-24:	 ldswa		[%o1 + 0x4] %asi, %o1
-	nop
-	nop
-do_sys_send: /* sys_send(int, void *, size_t, unsigned int) */
-25:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_send), %g1
-26:	lduwa		[%o1 + 0x8] %asi, %o2
-27:	lduwa		[%o1 + 0xc] %asi, %o3
-	jmpl		%g1 + %lo(sys_send), %g0
-28:	 lduwa		[%o1 + 0x4] %asi, %o1
-	nop
-	nop
-do_sys_recv: /* sys_recv(int, void *, size_t, unsigned int) */
-29:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_recv), %g1
-30:	lduwa		[%o1 + 0x8] %asi, %o2
-31:	lduwa		[%o1 + 0xc] %asi, %o3
-	jmpl		%g1 + %lo(sys_recv), %g0
-32:	 lduwa		[%o1 + 0x4] %asi, %o1
-	nop
-	nop
-do_sys_sendto: /* sys_sendto(int, u32, compat_size_t, unsigned int, u32, int) */
-33:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_sendto), %g1
-34:	lduwa		[%o1 + 0x8] %asi, %o2
-35:	lduwa		[%o1 + 0xc] %asi, %o3
-36:	lduwa		[%o1 + 0x10] %asi, %o4
-37:	ldswa		[%o1 + 0x14] %asi, %o5
-	jmpl		%g1 + %lo(sys_sendto), %g0
-38:	 lduwa		[%o1 + 0x4] %asi, %o1
-do_sys_recvfrom: /* sys_recvfrom(int, u32, compat_size_t, unsigned int, u32, u32) */
-39:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_recvfrom), %g1
-40:	lduwa		[%o1 + 0x8] %asi, %o2
-41:	lduwa		[%o1 + 0xc] %asi, %o3
-42:	lduwa		[%o1 + 0x10] %asi, %o4
-43:	lduwa		[%o1 + 0x14] %asi, %o5
-	jmpl		%g1 + %lo(sys_recvfrom), %g0
-44:	 lduwa		[%o1 + 0x4] %asi, %o1
-do_sys_shutdown: /* sys_shutdown(int, int) */
-45:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_shutdown), %g1
-	jmpl		%g1 + %lo(sys_shutdown), %g0
-46:	 ldswa		[%o1 + 0x4] %asi, %o1
-	nop
-	nop
-	nop
-	nop
-do_sys_setsockopt: /* sys_setsockopt(int, int, int, char *, int) */
-47:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_setsockopt), %g1
-48:	ldswa		[%o1 + 0x8] %asi, %o2
-49:	lduwa		[%o1 + 0xc] %asi, %o3
-50:	ldswa		[%o1 + 0x10] %asi, %o4
-	jmpl		%g1 + %lo(sys_setsockopt), %g0
-51:	 ldswa		[%o1 + 0x4] %asi, %o1
-	nop
-do_sys_getsockopt: /* sys_getsockopt(int, int, int, u32, u32) */
-52:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_getsockopt), %g1
-53:	ldswa		[%o1 + 0x8] %asi, %o2
-54:	lduwa		[%o1 + 0xc] %asi, %o3
-55:	lduwa		[%o1 + 0x10] %asi, %o4
-	jmpl		%g1 + %lo(sys_getsockopt), %g0
-56:	 ldswa		[%o1 + 0x4] %asi, %o1
-	nop
-do_sys_sendmsg: /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */
-57:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(compat_sys_sendmsg), %g1
-58:	lduwa		[%o1 + 0x8] %asi, %o2
-	jmpl		%g1 + %lo(compat_sys_sendmsg), %g0
-59:	 lduwa		[%o1 + 0x4] %asi, %o1
-	nop
-	nop
-	nop
-do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) */
-60:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(compat_sys_recvmsg), %g1
-61:	lduwa		[%o1 + 0x8] %asi, %o2
-	jmpl		%g1 + %lo(compat_sys_recvmsg), %g0
-62:	 lduwa		[%o1 + 0x4] %asi, %o1
-	nop
-	nop
-	nop
-do_sys_accept4: /* sys_accept4(int, struct sockaddr *, int *, int) */
-63:	ldswa		[%o1 + 0x0] %asi, %o0
-	sethi		%hi(sys_accept4), %g1
-64:	lduwa		[%o1 + 0x8] %asi, %o2
-65:	ldswa		[%o1 + 0xc] %asi, %o3
-	jmpl		%g1 + %lo(sys_accept4), %g0
-66:	 lduwa		[%o1 + 0x4] %asi, %o1
-	nop
-	nop
-
-	.section	__ex_table,"a"
-	.align		4
-	.word		1b, __retl_efault, 2b, __retl_efault
-	.word		3b, __retl_efault, 4b, __retl_efault
-	.word		5b, __retl_efault, 6b, __retl_efault
-	.word		7b, __retl_efault, 8b, __retl_efault
-	.word		9b, __retl_efault, 10b, __retl_efault
-	.word		11b, __retl_efault, 12b, __retl_efault
-	.word		13b, __retl_efault, 14b, __retl_efault
-	.word		15b, __retl_efault, 16b, __retl_efault
-	.word		17b, __retl_efault, 18b, __retl_efault
-	.word		19b, __retl_efault, 20b, __retl_efault
-	.word		21b, __retl_efault, 22b, __retl_efault
-	.word		23b, __retl_efault, 24b, __retl_efault
-	.word		25b, __retl_efault, 26b, __retl_efault
-	.word		27b, __retl_efault, 28b, __retl_efault
-	.word		29b, __retl_efault, 30b, __retl_efault
-	.word		31b, __retl_efault, 32b, __retl_efault
-	.word		33b, __retl_efault, 34b, __retl_efault
-	.word		35b, __retl_efault, 36b, __retl_efault
-	.word		37b, __retl_efault, 38b, __retl_efault
-	.word		39b, __retl_efault, 40b, __retl_efault
-	.word		41b, __retl_efault, 42b, __retl_efault
-	.word		43b, __retl_efault, 44b, __retl_efault
-	.word		45b, __retl_efault, 46b, __retl_efault
-	.word		47b, __retl_efault, 48b, __retl_efault
-	.word		49b, __retl_efault, 50b, __retl_efault
-	.word		51b, __retl_efault, 52b, __retl_efault
-	.word		53b, __retl_efault, 54b, __retl_efault
-	.word		55b, __retl_efault, 56b, __retl_efault
-	.word		57b, __retl_efault, 58b, __retl_efault
-	.word		59b, __retl_efault, 60b, __retl_efault
-	.word		61b, __retl_efault, 62b, __retl_efault
-	.word		63b, __retl_efault, 64b, __retl_efault
-	.word		65b, __retl_efault, 66b, __retl_efault
-	.previous
--- linux-qcom-6.8.0.orig/arch/sparc/kernel/syscalls/syscall.tbl
+++ linux-qcom-6.8.0/arch/sparc/kernel/syscalls/syscall.tbl
@@ -117,7 +117,7 @@
 90	common	dup2			sys_dup2
 91	32	setfsuid32		sys_setfsuid
 92	common	fcntl			sys_fcntl			compat_sys_fcntl
-93	common	select			sys_select
+93	common	select			sys_select			compat_sys_select
 94	32	setfsgid32		sys_setfsgid
 95	common	fsync			sys_fsync
 96	common	setpriority		sys_setpriority
@@ -155,7 +155,7 @@
 123	32	fchown			sys_fchown16
 123	64	fchown			sys_fchown
 124	common	fchmod			sys_fchmod
-125	common	recvfrom		sys_recvfrom
+125	common	recvfrom		sys_recvfrom			compat_sys_recvfrom
 126	32	setreuid		sys_setreuid16
 126	64	setreuid		sys_setreuid
 127	32	setregid		sys_setregid16
@@ -247,7 +247,7 @@
 204	32	readdir			sys_old_readdir			compat_sys_old_readdir
 204	64	readdir			sys_nis_syscall
 205	common	readahead		sys_readahead			compat_sys_readahead
-206	common	socketcall		sys_socketcall			sys32_socketcall
+206	common	socketcall		sys_socketcall			compat_sys_socketcall
 207	common	syslog			sys_syslog
 208	common	lookup_dcookie		sys_ni_syscall
 209	common	fadvise64		sys_fadvise64			compat_sys_fadvise64
@@ -461,7 +461,7 @@
 412	32	utimensat_time64		sys_utimensat			sys_utimensat
 413	32	pselect6_time64			sys_pselect6			compat_sys_pselect6_time64
 414	32	ppoll_time64			sys_ppoll			compat_sys_ppoll_time64
-416	32	io_pgetevents_time64		sys_io_pgetevents		sys_io_pgetevents
+416	32	io_pgetevents_time64		sys_io_pgetevents		compat_sys_io_pgetevents_time64
 417	32	recvmmsg_time64			sys_recvmmsg			compat_sys_recvmmsg_time64
 418	32	mq_timedsend_time64		sys_mq_timedsend		sys_mq_timedsend
 419	32	mq_timedreceive_time64		sys_mq_timedreceive		sys_mq_timedreceive
--- linux-qcom-6.8.0.orig/arch/sparc/lib/Makefile
+++ linux-qcom-6.8.0/arch/sparc/lib/Makefile
@@ -14,7 +14,7 @@
 lib-$(CONFIG_SPARC32) += copy_user.o locks.o
 lib-$(CONFIG_SPARC64) += atomic_64.o
 lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o
-lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o
+lib-$(CONFIG_SPARC32) += muldi3.o bitext.o
 lib-$(CONFIG_SPARC64) += multi3.o
 lib-$(CONFIG_SPARC64) += fls.o
 lib-$(CONFIG_SPARC64) += fls64.o
@@ -51,5 +51,5 @@
 lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o
 
 obj-$(CONFIG_SPARC64) += iomap.o
-obj-$(CONFIG_SPARC32) += atomic32.o ucmpdi2.o
+obj-$(CONFIG_SPARC32) += atomic32.o
 obj-$(CONFIG_SPARC64) += PeeCeeI.o
--- linux-qcom-6.8.0.orig/arch/sparc/mm/init_64.c
+++ linux-qcom-6.8.0/arch/sparc/mm/init_64.c
@@ -1665,7 +1665,7 @@
 	if (pud_none(*pud))
 		return false;
 
-	if (pud_large(*pud))
+	if (pud_leaf(*pud))
 		return pfn_valid(pud_pfn(*pud));
 
 	pmd = pmd_offset(pud, addr);
--- linux-qcom-6.8.0.orig/arch/sparc/mm/tlb.c
+++ linux-qcom-6.8.0/arch/sparc/mm/tlb.c
@@ -249,6 +249,7 @@
 {
 	pmd_t old, entry;
 
+	VM_WARN_ON_ONCE(!pmd_present(*pmdp));
 	entry = __pmd(pmd_val(*pmdp) & ~_PAGE_VALID);
 	old = pmdp_establish(vma, address, pmdp, entry);
 	flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
--- linux-qcom-6.8.0.orig/arch/sparc/net/bpf_jit_comp_64.c
+++ linux-qcom-6.8.0/arch/sparc/net/bpf_jit_comp_64.c
@@ -1602,7 +1602,11 @@
 	bpf_flush_icache(header, (u8 *)header + header->size);
 
 	if (!prog->is_func || extra_pass) {
-		bpf_jit_binary_lock_ro(header);
+		if (bpf_jit_binary_lock_ro(header)) {
+			bpf_jit_binary_free(header);
+			prog = orig_prog;
+			goto out_off;
+		}
 	} else {
 		jit_data->ctx = ctx;
 		jit_data->image = image_ptr;
--- linux-qcom-6.8.0.orig/arch/sparc/prom/init_64.c
+++ linux-qcom-6.8.0/arch/sparc/prom/init_64.c
@@ -26,9 +26,6 @@
  * routines in the prom library.
  * It gets passed the pointer to the PROM vector.
  */
-
-extern void prom_cif_init(void *);
-
 void __init prom_init(void *cif_handler)
 {
 	phandle node;
--- linux-qcom-6.8.0.orig/arch/sparc/prom/p1275.c
+++ linux-qcom-6.8.0/arch/sparc/prom/p1275.c
@@ -49,7 +49,7 @@
 	local_irq_restore(flags);
 }
 
-void prom_cif_init(void *cif_handler, void *cif_stack)
+void prom_cif_init(void *cif_handler)
 {
 	p1275buf.prom_cif_handler = (void (*)(long *))cif_handler;
 }
--- linux-qcom-6.8.0.orig/arch/sparc/vdso/vma.c
+++ linux-qcom-6.8.0/arch/sparc/vdso/vma.c
@@ -449,9 +449,8 @@
 	unsigned long val;
 
 	err = kstrtoul(s, 10, &val);
-	if (err)
-		return err;
-	vdso_enabled = val;
-	return 0;
+	if (!err)
+		vdso_enabled = val;
+	return 1;
 }
 __setup("vdso=", vdso_setup);
--- linux-qcom-6.8.0.orig/arch/um/drivers/line.c
+++ linux-qcom-6.8.0/arch/um/drivers/line.c
@@ -383,6 +383,7 @@
 			parse_chan_pair(NULL, line, n, opts, error_out);
 			err = 0;
 		}
+		*error_out = "configured as 'none'";
 	} else {
 		char *new = kstrdup(init, GFP_KERNEL);
 		if (!new) {
@@ -406,6 +407,7 @@
 			}
 		}
 		if (err) {
+			*error_out = "failed to parse channel pair";
 			line->init_str = NULL;
 			line->valid = 0;
 			kfree(new);
@@ -676,24 +678,26 @@
 		goto cleanup;
 	}
 
-	*winch = ((struct winch) { .list  	= LIST_HEAD_INIT(winch->list),
-				   .fd  	= fd,
+	*winch = ((struct winch) { .fd  	= fd,
 				   .tty_fd 	= tty_fd,
 				   .pid  	= pid,
 				   .port 	= port,
 				   .stack	= stack });
 
+	spin_lock(&winch_handler_lock);
+	list_add(&winch->list, &winch_handlers);
+	spin_unlock(&winch_handler_lock);
+
 	if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
 			   IRQF_SHARED, "winch", winch) < 0) {
 		printk(KERN_ERR "register_winch_irq - failed to register "
 		       "IRQ\n");
+		spin_lock(&winch_handler_lock);
+		list_del(&winch->list);
+		spin_unlock(&winch_handler_lock);
 		goto out_free;
 	}
 
-	spin_lock(&winch_handler_lock);
-	list_add(&winch->list, &winch_handlers);
-	spin_unlock(&winch_handler_lock);
-
 	return;
 
  out_free:
--- linux-qcom-6.8.0.orig/arch/um/drivers/net_kern.c
+++ linux-qcom-6.8.0/arch/um/drivers/net_kern.c
@@ -336,7 +336,7 @@
 
 static void net_device_release(struct device *dev)
 {
-	struct uml_net *device = dev_get_drvdata(dev);
+	struct uml_net *device = container_of(dev, struct uml_net, pdev.dev);
 	struct net_device *netdev = device->dev;
 	struct uml_net_private *lp = netdev_priv(netdev);
 
--- linux-qcom-6.8.0.orig/arch/um/drivers/ubd_kern.c
+++ linux-qcom-6.8.0/arch/um/drivers/ubd_kern.c
@@ -456,43 +456,31 @@
 	return n;
 }
 
-/* Called without dev->lock held, and only in interrupt context. */
-static void ubd_handler(void)
+static void ubd_end_request(struct io_thread_req *io_req)
 {
-	int n;
-	int count;
-
-	while(1){
-		n = bulk_req_safe_read(
-			thread_fd,
-			irq_req_buffer,
-			&irq_remainder,
-			&irq_remainder_size,
-			UBD_REQ_BUFFER_SIZE
-		);
-		if (n < 0) {
-			if(n == -EAGAIN)
-				break;
-			printk(KERN_ERR "spurious interrupt in ubd_handler, "
-			       "err = %d\n", -n);
-			return;
-		}
-		for (count = 0; count < n/sizeof(struct io_thread_req *); count++) {
-			struct io_thread_req *io_req = (*irq_req_buffer)[count];
-
-			if ((io_req->error == BLK_STS_NOTSUPP) && (req_op(io_req->req) == REQ_OP_DISCARD)) {
-				blk_queue_max_discard_sectors(io_req->req->q, 0);
-				blk_queue_max_write_zeroes_sectors(io_req->req->q, 0);
-			}
-			blk_mq_end_request(io_req->req, io_req->error);
-			kfree(io_req);
-		}
+	if (io_req->error == BLK_STS_NOTSUPP) {
+		if (req_op(io_req->req) == REQ_OP_DISCARD)
+			blk_queue_max_discard_sectors(io_req->req->q, 0);
+		else if (req_op(io_req->req) == REQ_OP_WRITE_ZEROES)
+			blk_queue_max_write_zeroes_sectors(io_req->req->q, 0);
 	}
+	blk_mq_end_request(io_req->req, io_req->error);
+	kfree(io_req);
 }
 
 static irqreturn_t ubd_intr(int irq, void *dev)
 {
-	ubd_handler();
+	int len, i;
+
+	while ((len = bulk_req_safe_read(thread_fd, irq_req_buffer,
+			&irq_remainder, &irq_remainder_size,
+			UBD_REQ_BUFFER_SIZE)) >= 0) {
+		for (i = 0; i < len / sizeof(struct io_thread_req *); i++)
+			ubd_end_request((*irq_req_buffer)[i]);
+	}
+
+	if (len < 0 && len != -EAGAIN)
+		pr_err("spurious interrupt in %s, err = %d\n", __func__, len);
 	return IRQ_HANDLED;
 }
 
@@ -810,7 +798,7 @@
 
 static void ubd_device_release(struct device *dev)
 {
-	struct ubd *ubd_dev = dev_get_drvdata(dev);
+	struct ubd *ubd_dev = container_of(dev, struct ubd, pdev.dev);
 
 	blk_mq_free_tag_set(&ubd_dev->tag_set);
 	*ubd_dev = ((struct ubd) DEFAULT_UBD);
@@ -1098,7 +1086,7 @@
 
 	if (irq_req_buffer == NULL) {
 		printk(KERN_ERR "Failed to initialize ubd buffering\n");
-		return -1;
+		return -ENOMEM;
 	}
 	io_req_buffer = kmalloc_array(UBD_REQ_BUFFER_SIZE,
 				      sizeof(struct io_thread_req *),
@@ -1109,7 +1097,7 @@
 
 	if (io_req_buffer == NULL) {
 		printk(KERN_ERR "Failed to initialize ubd buffering\n");
-		return -1;
+		return -ENOMEM;
 	}
 	platform_driver_register(&ubd_driver);
 	mutex_lock(&ubd_lock);
--- linux-qcom-6.8.0.orig/arch/um/drivers/vector_kern.c
+++ linux-qcom-6.8.0/arch/um/drivers/vector_kern.c
@@ -141,7 +141,7 @@
 
 	if (allow != NULL) {
 		if (kstrtoul(allow, 10, &result) == 0)
-			return (allow > 0);
+			return result > 0;
 	}
 	return false;
 }
@@ -823,7 +823,8 @@
 
 static void vector_device_release(struct device *dev)
 {
-	struct vector_device *device = dev_get_drvdata(dev);
+	struct vector_device *device =
+		container_of(dev, struct vector_device, pdev.dev);
 	struct net_device *netdev = device->dev;
 
 	list_del(&device->list);
--- linux-qcom-6.8.0.orig/arch/um/include/asm/kasan.h
+++ linux-qcom-6.8.0/arch/um/include/asm/kasan.h
@@ -24,7 +24,6 @@
 
 #ifdef CONFIG_KASAN
 void kasan_init(void);
-void kasan_map_memory(void *start, unsigned long len);
 extern int kasan_um_is_ready;
 
 #ifdef CONFIG_STATIC_LINK
--- linux-qcom-6.8.0.orig/arch/um/include/asm/mmu.h
+++ linux-qcom-6.8.0/arch/um/include/asm/mmu.h
@@ -14,8 +14,6 @@
 	struct uml_arch_mm_context arch;
 } mm_context_t;
 
-extern void __switch_mm(struct mm_id * mm_idp);
-
 /* Avoid tangled inclusion with asm/ldt.h */
 extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm);
 extern void free_ldt(struct mm_context *mm);
--- linux-qcom-6.8.0.orig/arch/um/include/asm/processor-generic.h
+++ linux-qcom-6.8.0/arch/um/include/asm/processor-generic.h
@@ -94,7 +94,6 @@
 #define current_cpu_data boot_cpu_data
 #define cache_line_size()	(boot_cpu_data.cache_alignment)
 
-extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
 #define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf)
 extern unsigned long __get_wchan(struct task_struct *p);
 
--- linux-qcom-6.8.0.orig/arch/um/include/shared/kern_util.h
+++ linux-qcom-6.8.0/arch/um/include/shared/kern_util.h
@@ -66,4 +66,6 @@
 
 void um_idle_sleep(void);
 
+void kasan_map_memory(void *start, size_t len);
+
 #endif
--- linux-qcom-6.8.0.orig/arch/um/include/shared/skas/mm_id.h
+++ linux-qcom-6.8.0/arch/um/include/shared/skas/mm_id.h
@@ -15,4 +15,6 @@
 	int kill;
 };
 
+void __switch_mm(struct mm_id *mm_idp);
+
 #endif
--- linux-qcom-6.8.0.orig/arch/um/kernel/dtb.c
+++ linux-qcom-6.8.0/arch/um/kernel/dtb.c
@@ -16,16 +16,16 @@
 	void *area;
 
 	area = uml_load_file(dtb, &size);
-	if (!area)
-		return;
+	if (area) {
+		if (!early_init_dt_scan(area, __pa(area))) {
+			pr_err("invalid DTB %s\n", dtb);
+			memblock_free(area, size);
+			return;
+		}
 
-	if (!early_init_dt_scan(area)) {
-		pr_err("invalid DTB %s\n", dtb);
-		memblock_free(area, size);
-		return;
+		early_init_fdt_scan_reserved_mem();
 	}
 
-	early_init_fdt_scan_reserved_mem();
 	unflatten_device_tree();
 }
 
--- linux-qcom-6.8.0.orig/arch/um/kernel/physmem.c
+++ linux-qcom-6.8.0/arch/um/kernel/physmem.c
@@ -80,10 +80,10 @@
 			  unsigned long len, unsigned long long highmem)
 {
 	unsigned long reserve = reserve_end - start;
-	long map_size = len - reserve;
+	unsigned long map_size = len - reserve;
 	int err;
 
-	if(map_size <= 0) {
+	if (len <= reserve) {
 		os_warn("Too few physical memory! Needed=%lu, given=%lu\n",
 			reserve, len);
 		exit(1);
@@ -94,7 +94,7 @@
 	err = os_map_memory((void *) reserve_end, physmem_fd, reserve,
 			    map_size, 1, 1, 1);
 	if (err < 0) {
-		os_warn("setup_physmem - mapping %ld bytes of memory at 0x%p "
+		os_warn("setup_physmem - mapping %lu bytes of memory at 0x%p "
 			"failed - errno = %d\n", map_size,
 			(void *) reserve_end, err);
 		exit(1);
--- linux-qcom-6.8.0.orig/arch/um/kernel/process.c
+++ linux-qcom-6.8.0/arch/um/kernel/process.c
@@ -389,6 +389,6 @@
 {
 	int cpu = current_thread_info()->cpu;
 
-	return save_i387_registers(userspace_pid[cpu], (unsigned long *) fpu);
+	return save_i387_registers(userspace_pid[cpu], (unsigned long *) fpu) == 0;
 }
 
--- linux-qcom-6.8.0.orig/arch/um/kernel/sysrq.c
+++ linux-qcom-6.8.0/arch/um/kernel/sysrq.c
@@ -53,5 +53,5 @@
 	}
 
 	printk("%sCall Trace:\n", loglvl);
-	dump_trace(current, &stackops, (void *)loglvl);
+	dump_trace(task ?: current, &stackops, (void *)loglvl);
 }
--- linux-qcom-6.8.0.orig/arch/um/kernel/time.c
+++ linux-qcom-6.8.0/arch/um/kernel/time.c
@@ -874,9 +874,9 @@
 	return 1;
 }
 
-__setup("time-travel-start", setup_time_travel_start);
+__setup("time-travel-start=", setup_time_travel_start);
 __uml_help(setup_time_travel_start,
-"time-travel-start=<seconds>\n"
+"time-travel-start=<nanoseconds>\n"
 "Configure the UML instance's wall clock to start at this value rather than\n"
 "the host's wall clock at the time of UML boot.\n");
 #endif
--- linux-qcom-6.8.0.orig/arch/um/os-Linux/mem.c
+++ linux-qcom-6.8.0/arch/um/os-Linux/mem.c
@@ -15,6 +15,7 @@
 #include <sys/vfs.h>
 #include <linux/magic.h>
 #include <init.h>
+#include <kern_util.h>
 #include <os.h>
 
 /*
--- linux-qcom-6.8.0.orig/arch/um/os-Linux/signal.c
+++ linux-qcom-6.8.0/arch/um/os-Linux/signal.c
@@ -8,6 +8,7 @@
 
 #include <stdlib.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include <errno.h>
 #include <signal.h>
 #include <string.h>
@@ -65,9 +66,7 @@
 
 int signals_enabled;
 #ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
-static int signals_blocked;
-#else
-#define signals_blocked 0
+static int signals_blocked, signals_blocked_pending;
 #endif
 static unsigned int signals_pending;
 static unsigned int signals_active = 0;
@@ -76,14 +75,27 @@
 {
 	int enabled = signals_enabled;
 
-	if ((signals_blocked || !enabled) && (sig == SIGIO)) {
+#ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
+	if ((signals_blocked ||
+	     __atomic_load_n(&signals_blocked_pending, __ATOMIC_SEQ_CST)) &&
+	    (sig == SIGIO)) {
+		/* increment so unblock will do another round */
+		__atomic_add_fetch(&signals_blocked_pending, 1,
+				   __ATOMIC_SEQ_CST);
+		return;
+	}
+#endif
+
+	if (!enabled && (sig == SIGIO)) {
 		/*
 		 * In TT_MODE_EXTERNAL, need to still call time-travel
-		 * handlers unless signals are also blocked for the
-		 * external time message processing. This will mark
-		 * signals_pending by itself (only if necessary.)
+		 * handlers. This will mark signals_pending by itself
+		 * (only if necessary.)
+		 * Note we won't get here if signals are hard-blocked
+		 * (which is handled above), in that case the hard-
+		 * unblock will handle things.
 		 */
-		if (!signals_blocked && time_travel_mode == TT_MODE_EXTERNAL)
+		if (time_travel_mode == TT_MODE_EXTERNAL)
 			sigio_run_timetravel_handlers();
 		else
 			signals_pending |= SIGIO_MASK;
@@ -380,33 +392,99 @@
 #ifdef UML_CONFIG_UML_TIME_TRAVEL_SUPPORT
 void mark_sigio_pending(void)
 {
+	/*
+	 * It would seem that this should be atomic so
+	 * it isn't a read-modify-write with a signal
+	 * that could happen in the middle, losing the
+	 * value set by the signal.
+	 *
+	 * However, this function is only called when in
+	 * time-travel=ext simulation mode, in which case
+	 * the only signal ever pending is SIGIO, which
+	 * is blocked while this can be called, and the
+	 * timer signal (SIGALRM) cannot happen.
+	 */
 	signals_pending |= SIGIO_MASK;
 }
 
 void block_signals_hard(void)
 {
-	if (signals_blocked)
-		return;
-	signals_blocked = 1;
+	signals_blocked++;
 	barrier();
 }
 
 void unblock_signals_hard(void)
 {
+	static bool unblocking;
+
 	if (!signals_blocked)
+		panic("unblocking signals while not blocked");
+
+	if (--signals_blocked)
 		return;
-	/* Must be set to 0 before we check the pending bits etc. */
-	signals_blocked = 0;
+	/*
+	 * Must be set to 0 before we check pending so the
+	 * SIGIO handler will run as normal unless we're still
+	 * going to process signals_blocked_pending.
+	 */
 	barrier();
 
-	if (signals_pending && signals_enabled) {
-		/* this is a bit inefficient, but that's not really important */
-		block_signals();
-		unblock_signals();
-	} else if (signals_pending & SIGIO_MASK) {
-		/* we need to run time-travel handlers even if not enabled */
-		sigio_run_timetravel_handlers();
+	/*
+	 * Note that block_signals_hard()/unblock_signals_hard() can be called
+	 * within the unblock_signals()/sigio_run_timetravel_handlers() below.
+	 * This would still be prone to race conditions since it's actually a
+	 * call _within_ e.g. vu_req_read_message(), where we observed this
+	 * issue, which loops. Thus, if the inner call handles the recorded
+	 * pending signals, we can get out of the inner call with the real
+	 * signal hander no longer blocked, and still have a race. Thus don't
+	 * handle unblocking in the inner call, if it happens, but only in
+	 * the outermost call - 'unblocking' serves as an ownership for the
+	 * signals_blocked_pending decrement.
+	 */
+	if (unblocking)
+		return;
+	unblocking = true;
+
+	while (__atomic_load_n(&signals_blocked_pending, __ATOMIC_SEQ_CST)) {
+		if (signals_enabled) {
+			/* signals are enabled so we can touch this */
+			signals_pending |= SIGIO_MASK;
+			/*
+			 * this is a bit inefficient, but that's
+			 * not really important
+			 */
+			block_signals();
+			unblock_signals();
+		} else {
+			/*
+			 * we need to run time-travel handlers even
+			 * if not enabled
+			 */
+			sigio_run_timetravel_handlers();
+		}
+
+		/*
+		 * The decrement of signals_blocked_pending must be atomic so
+		 * that the signal handler will either happen before or after
+		 * the decrement, not during a read-modify-write:
+		 *  - If it happens before, it can increment it and we'll
+		 *    decrement it and do another round in the loop.
+		 *  - If it happens after it'll see 0 for both signals_blocked
+		 *    and signals_blocked_pending and thus run the handler as
+		 *    usual (subject to signals_enabled, but that's unrelated.)
+		 *
+		 * Note that a call to unblock_signals_hard() within the calls
+		 * to unblock_signals() or sigio_run_timetravel_handlers() above
+		 * will do nothing due to the 'unblocking' state, so this cannot
+		 * underflow as the only one decrementing will be the outermost
+		 * one.
+		 */
+		if (__atomic_sub_fetch(&signals_blocked_pending, 1,
+				       __ATOMIC_SEQ_CST) < 0)
+			panic("signals_blocked_pending underflow");
 	}
+
+	unblocking = false;
 }
 #endif
 
--- linux-qcom-6.8.0.orig/arch/x86/Kconfig
+++ linux-qcom-6.8.0/arch/x86/Kconfig
@@ -62,6 +62,7 @@
 	select ACPI_HOTPLUG_CPU			if ACPI_PROCESSOR && HOTPLUG_CPU
 	select ARCH_32BIT_OFF_T			if X86_32
 	select ARCH_CLOCKSOURCE_INIT
+	select ARCH_CONFIGURES_CPU_MITIGATIONS
 	select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
 	select ARCH_ENABLE_HUGEPAGE_MIGRATION if X86_64 && HUGETLB_PAGE && MIGRATION
 	select ARCH_ENABLE_MEMORY_HOTPLUG if X86_64
@@ -100,7 +101,7 @@
 	select ARCH_HAS_STRICT_MODULE_RWX
 	select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
 	select ARCH_HAS_SYSCALL_WRAPPER
-	select ARCH_HAS_UBSAN_SANITIZE_ALL
+	select ARCH_HAS_UBSAN
 	select ARCH_HAS_DEBUG_WX
 	select ARCH_HAS_ZONE_DMA_SET if EXPERT
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
@@ -1539,19 +1540,6 @@
 	  This requires an AMD processor that supports Secure Memory
 	  Encryption (SME).
 
-config AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT
-	bool "Activate AMD Secure Memory Encryption (SME) by default"
-	depends on AMD_MEM_ENCRYPT
-	help
-	  Say yes to have system memory encrypted by default if running on
-	  an AMD processor that supports Secure Memory Encryption (SME).
-
-	  If set to Y, then the encryption of system memory can be
-	  deactivated with the mem_encrypt=off command line option.
-
-	  If set to N, then the encryption of system memory can be
-	  activated with the mem_encrypt=on command line option.
-
 # Common NUMA Features
 config NUMA
 	bool "NUMA Memory Allocation and Scheduler Support"
@@ -2275,6 +2263,7 @@
 config ADDRESS_MASKING
 	bool "Linear Address Masking support"
 	depends on X86_64
+	depends on COMPILE_TEST || !CPU_MITIGATIONS # wait for LASS
 	help
 	  Linear Address Masking (LAM) modifies the checking that is applied
 	  to 64-bit linear addresses, allowing software to use of the
@@ -2480,17 +2469,21 @@
 	def_bool y
 	depends on CALL_PADDING && !CFI_CLANG
 
-menuconfig SPECULATION_MITIGATIONS
-	bool "Mitigations for speculative execution vulnerabilities"
+menuconfig CPU_MITIGATIONS
+	bool "Mitigations for CPU vulnerabilities"
 	default y
 	help
-	  Say Y here to enable options which enable mitigations for
-	  speculative execution hardware vulnerabilities.
+	  Say Y here to enable options which enable mitigations for hardware
+	  vulnerabilities (usually related to speculative execution).
+	  Mitigations can be disabled or restricted to SMT systems at runtime
+	  via the "mitigations" kernel parameter.
 
-	  If you say N, all mitigations will be disabled. You really
-	  should know what you are doing to say so.
+	  If you say N, all mitigations will be disabled.  This CANNOT be
+	  overridden at runtime.
 
-if SPECULATION_MITIGATIONS
+	  Say 'Y', unless you really know what you are doing.
+
+if CPU_MITIGATIONS
 
 config PAGE_TABLE_ISOLATION
 	bool "Remove the kernel mapping in user mode"
@@ -2614,6 +2607,27 @@
 
 	  If in doubt, say N.
 
+config MITIGATION_RFDS
+	bool "RFDS Mitigation"
+	depends on CPU_SUP_INTEL
+	default y
+	help
+	  Enable mitigation for Register File Data Sampling (RFDS) by default.
+	  RFDS is a hardware vulnerability which affects Intel Atom CPUs. It
+	  allows unprivileged speculative access to stale data previously
+	  stored in floating point, vector and integer registers.
+	  See also <file:Documentation/admin-guide/hw-vuln/reg-file-data-sampling.rst>
+
+config MITIGATION_SPECTRE_BHI
+	bool "Mitigate Spectre-BHB (Branch History Injection)"
+	depends on CPU_SUP_INTEL
+	default y
+	help
+	  Enable BHI mitigations. BHI attacks are a form of Spectre V2 attacks
+	  where the branch history buffer is poisoned to speculatively steer
+	  indirect branches.
+	  See <file:Documentation/admin-guide/hw-vuln/spectre.rst>
+
 endif
 
 config ARCH_HAS_ADD_PAGES
--- linux-qcom-6.8.0.orig/arch/x86/Kconfig.assembler
+++ linux-qcom-6.8.0/arch/x86/Kconfig.assembler
@@ -26,6 +26,6 @@
 	  Supported by binutils >= 2.30 and LLVM integrated assembler
 
 config AS_WRUSS
-	def_bool $(as-instr,wrussq %rax$(comma)(%rbx))
+	def_bool $(as-instr64,wrussq %rax$(comma)(%rbx))
 	help
 	  Supported by binutils >= 2.31 and LLVM integrated assembler
--- linux-qcom-6.8.0.orig/arch/x86/Kconfig.debug
+++ linux-qcom-6.8.0/arch/x86/Kconfig.debug
@@ -248,6 +248,7 @@
 
 config UNWINDER_FRAME_POINTER
 	bool "Frame pointer unwinder"
+	select ARCH_WANT_FRAME_POINTERS
 	select FRAME_POINTER
 	help
 	  This option enables the frame pointer unwinder for unwinding kernel
@@ -271,7 +272,3 @@
 	  overhead.
 
 endchoice
-
-config FRAME_POINTER
-	depends on !UNWINDER_ORC && !UNWINDER_GUESS
-	bool
--- linux-qcom-6.8.0.orig/arch/x86/Makefile
+++ linux-qcom-6.8.0/arch/x86/Makefile
@@ -114,9 +114,10 @@
 
     ifeq ($(CONFIG_STACKPROTECTOR),y)
         ifeq ($(CONFIG_SMP),y)
-			KBUILD_CFLAGS += -mstack-protector-guard-reg=fs -mstack-protector-guard-symbol=__stack_chk_guard
+            KBUILD_CFLAGS += -mstack-protector-guard-reg=fs \
+                             -mstack-protector-guard-symbol=__ref_stack_chk_guard
         else
-			KBUILD_CFLAGS += -mstack-protector-guard=global
+            KBUILD_CFLAGS += -mstack-protector-guard=global
         endif
     endif
 else
--- linux-qcom-6.8.0.orig/arch/x86/Makefile.um
+++ linux-qcom-6.8.0/arch/x86/Makefile.um
@@ -9,6 +9,7 @@
 #
 ifeq ($(CONFIG_CC_IS_CLANG),y)
 KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx
+KBUILD_RUSTFLAGS += --target=$(objtree)/scripts/target.json
 KBUILD_RUSTFLAGS += -Ctarget-feature=-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2
 endif
 
--- linux-qcom-6.8.0.orig/arch/x86/boot/compressed/Makefile
+++ linux-qcom-6.8.0/arch/x86/boot/compressed/Makefile
@@ -34,6 +34,7 @@
 # avoid errors with '-march=i386', and future flags may depend on the target to
 # be valid.
 KBUILD_CFLAGS := -m$(BITS) -O2 $(CLANG_FLAGS)
+KBUILD_CFLAGS += -std=gnu11
 KBUILD_CFLAGS += -fno-strict-aliasing -fPIE
 KBUILD_CFLAGS += -Wundef
 KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
@@ -84,7 +85,7 @@
 hostprogs	:= mkpiggy
 HOST_EXTRACFLAGS += -I$(srctree)/tools/include
 
-sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|__bss_start\|_end\)$$/\#define VO_\2 _AC(0x\1,UL)/p'
+sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|__start_rodata\|__bss_start\|_end\)$$/\#define VO_\2 _AC(0x\1,UL)/p'
 
 quiet_cmd_voffset = VOFFSET $@
       cmd_voffset = $(NM) $< | sed -n $(sed-voffset) > $@
@@ -116,9 +117,9 @@
 
 vmlinux-objs-$(CONFIG_EFI) += $(obj)/efi.o
 vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_mixed.o
-vmlinux-objs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
+vmlinux-libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
 
-$(obj)/vmlinux: $(vmlinux-objs-y) FORCE
+$(obj)/vmlinux: $(vmlinux-objs-y) $(vmlinux-libs-y) FORCE
 	$(call if_changed,ld)
 
 OBJCOPYFLAGS_vmlinux.bin :=  -R .comment -S
--- linux-qcom-6.8.0.orig/arch/x86/boot/compressed/efi_mixed.S
+++ linux-qcom-6.8.0/arch/x86/boot/compressed/efi_mixed.S
@@ -15,10 +15,12 @@
  */
 
 #include <linux/linkage.h>
+#include <asm/asm-offsets.h>
 #include <asm/msr.h>
 #include <asm/page_types.h>
 #include <asm/processor-flags.h>
 #include <asm/segment.h>
+#include <asm/setup.h>
 
 	.code64
 	.text
@@ -49,6 +51,11 @@
 	lea	efi32_boot_args(%rip), %rdx
 	mov	0(%rdx), %edi
 	mov	4(%rdx), %esi
+
+	/* Switch to the firmware's stack */
+	movl	efi32_boot_sp(%rip), %esp
+	andl	$~7, %esp
+
 #ifdef CONFIG_EFI_HANDOVER_PROTOCOL
 	mov	8(%rdx), %edx		// saved bootparams pointer
 	test	%edx, %edx
@@ -144,6 +151,7 @@
 SYM_FUNC_START(efi32_stub_entry)
 	call	1f
 1:	popl	%ecx
+	leal	(efi32_boot_args - 1b)(%ecx), %ebx
 
 	/* Clear BSS */
 	xorl	%eax, %eax
@@ -158,6 +166,7 @@
 	popl	%ecx
 	popl	%edx
 	popl	%esi
+	movl	%esi, 8(%ebx)
 	jmp	efi32_entry
 SYM_FUNC_END(efi32_stub_entry)
 #endif
@@ -234,8 +243,6 @@
  *
  * Arguments:	%ecx	image handle
  * 		%edx	EFI system table pointer
- *		%esi	struct bootparams pointer (or NULL when not using
- *			the EFI handover protocol)
  *
  * Since this is the point of no return for ordinary execution, no registers
  * are considered live except for the function parameters. [Note that the EFI
@@ -254,13 +261,25 @@
 	/* Store firmware IDT descriptor */
 	sidtl	(efi32_boot_idt - 1b)(%ebx)
 
+	/* Store firmware stack pointer */
+	movl	%esp, (efi32_boot_sp - 1b)(%ebx)
+
 	/* Store boot arguments */
 	leal	(efi32_boot_args - 1b)(%ebx), %ebx
 	movl	%ecx, 0(%ebx)
 	movl	%edx, 4(%ebx)
-	movl	%esi, 8(%ebx)
 	movb	$0x0, 12(%ebx)          // efi_is64
 
+	/*
+	 * Allocate some memory for a temporary struct boot_params, which only
+	 * needs the minimal pieces that startup_32() relies on.
+	 */
+	subl	$PARAM_SIZE, %esp
+	movl	%esp, %esi
+	movl	$PAGE_SIZE, BP_kernel_alignment(%esi)
+	movl	$_end - 1b, BP_init_size(%esi)
+	subl	$startup_32 - 1b, BP_init_size(%esi)
+
 	/* Disable paging */
 	movl	%cr0, %eax
 	btrl	$X86_CR0_PG_BIT, %eax
@@ -286,8 +305,7 @@
 
 	movl	8(%ebp), %ecx			// image_handle
 	movl	12(%ebp), %edx			// sys_table
-	xorl	%esi, %esi
-	jmp	efi32_entry			// pass %ecx, %edx, %esi
+	jmp	efi32_entry			// pass %ecx, %edx
 						// no other registers remain live
 
 2:	popl	%edi				// restore callee-save registers
@@ -318,5 +336,6 @@
 
 SYM_DATA_LOCAL(efi32_boot_cs, .word 0)
 SYM_DATA_LOCAL(efi32_boot_ds, .word 0)
+SYM_DATA_LOCAL(efi32_boot_sp, .long 0)
 SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0, 0)
 SYM_DATA(efi_is64, .byte 1)
--- linux-qcom-6.8.0.orig/arch/x86/boot/compressed/head_64.S
+++ linux-qcom-6.8.0/arch/x86/boot/compressed/head_64.S
@@ -398,6 +398,11 @@
 	call	sev_enable
 #endif
 
+	/* Preserve only the CR4 bits that must be preserved, and clear the rest */
+	movq	%cr4, %rax
+	andl	$(X86_CR4_PAE | X86_CR4_MCE | X86_CR4_LA57), %eax
+	movq	%rax, %cr4
+
 	/*
 	 * configure_5level_paging() updates the number of paging levels using
 	 * a trampoline in 32-bit addressable memory if the current number does
--- linux-qcom-6.8.0.orig/arch/x86/boot/compressed/misc.c
+++ linux-qcom-6.8.0/arch/x86/boot/compressed/misc.c
@@ -330,6 +330,7 @@
 	return ehdr.e_entry - LOAD_PHYSICAL_ADDR;
 }
 
+const unsigned long kernel_text_size = VO___start_rodata - VO__text;
 const unsigned long kernel_total_size = VO__end - VO__text;
 
 static u8 boot_heap[BOOT_HEAP_SIZE] __aligned(4);
@@ -358,6 +359,19 @@
 }
 
 /*
+ * Set the memory encryption xloadflag based on the mem_encrypt= command line
+ * parameter, if provided.
+ */
+static void parse_mem_encrypt(struct setup_header *hdr)
+{
+	int on = cmdline_find_option_bool("mem_encrypt=on");
+	int off = cmdline_find_option_bool("mem_encrypt=off");
+
+	if (on > off)
+		hdr->xloadflags |= XLF_MEM_ENCRYPTION;
+}
+
+/*
  * The compressed kernel image (ZO), has been moved so that its position
  * is against the end of the buffer used to hold the uncompressed kernel
  * image (VO) and the execution environment (.bss, .brk), which makes sure
@@ -387,6 +401,8 @@
 	/* Clear flags intended for solely in-kernel use. */
 	boot_params_ptr->hdr.loadflags &= ~KASLR_FLAG;
 
+	parse_mem_encrypt(&boot_params_ptr->hdr);
+
 	sanitize_boot_params(boot_params_ptr);
 
 	if (boot_params_ptr->screen_info.orig_video_mode == 7) {
--- linux-qcom-6.8.0.orig/arch/x86/boot/compressed/sev.c
+++ linux-qcom-6.8.0/arch/x86/boot/compressed/sev.c
@@ -116,6 +116,9 @@
 #undef __init
 #define __init
 
+#undef __head
+#define __head
+
 #define __BOOT_COMPRESSED
 
 /* Basic instruction decoding support needed */
@@ -304,6 +307,10 @@
 	if (result != ES_OK)
 		goto finish;
 
+	result = vc_check_opcode_bytes(&ctxt, exit_code);
+	if (result != ES_OK)
+		goto finish;
+
 	switch (exit_code) {
 	case SVM_EXIT_RDTSC:
 	case SVM_EXIT_RDTSCP:
--- linux-qcom-6.8.0.orig/arch/x86/boot/main.c
+++ linux-qcom-6.8.0/arch/x86/boot/main.c
@@ -119,8 +119,8 @@
 	char *stack_end;
 
 	if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
-		asm("leal %P1(%%esp),%0"
-		    : "=r" (stack_end) : "i" (-STACK_SIZE));
+		asm("leal %n1(%%esp),%0"
+		    : "=r" (stack_end) : "i" (STACK_SIZE));
 
 		heap_end = (char *)
 			((size_t)boot_params.hdr.heap_end_ptr + 0x200);
--- linux-qcom-6.8.0.orig/arch/x86/coco/core.c
+++ linux-qcom-6.8.0/arch/x86/coco/core.c
@@ -3,18 +3,22 @@
  * Confidential Computing Platform Capability checks
  *
  * Copyright (C) 2021 Advanced Micro Devices, Inc.
+ * Copyright (C) 2024 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
  *
  * Author: Tom Lendacky <thomas.lendacky@amd.com>
  */
 
 #include <linux/export.h>
 #include <linux/cc_platform.h>
+#include <linux/string.h>
+#include <linux/random.h>
 
+#include <asm/archrandom.h>
 #include <asm/coco.h>
 #include <asm/processor.h>
 
 enum cc_vendor cc_vendor __ro_after_init = CC_VENDOR_NONE;
-static u64 cc_mask __ro_after_init;
+u64 cc_mask __ro_after_init;
 
 static bool noinstr intel_cc_platform_has(enum cc_attr attr)
 {
@@ -149,7 +153,39 @@
 }
 EXPORT_SYMBOL_GPL(cc_mkdec);
 
-__init void cc_set_mask(u64 mask)
+__init void cc_random_init(void)
 {
-	cc_mask = mask;
+	/*
+	 * The seed is 32 bytes (in units of longs), which is 256 bits, which
+	 * is the security level that the RNG is targeting.
+	 */
+	unsigned long rng_seed[32 / sizeof(long)];
+	size_t i, longs;
+
+	if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
+		return;
+
+	/*
+	 * Since the CoCo threat model includes the host, the only reliable
+	 * source of entropy that can be neither observed nor manipulated is
+	 * RDRAND. Usually, RDRAND failure is considered tolerable, but since
+	 * CoCo guests have no other unobservable source of entropy, it's
+	 * important to at least ensure the RNG gets some initial random seeds.
+	 */
+	for (i = 0; i < ARRAY_SIZE(rng_seed); i += longs) {
+		longs = arch_get_random_longs(&rng_seed[i], ARRAY_SIZE(rng_seed) - i);
+
+		/*
+		 * A zero return value means that the guest doesn't have RDRAND
+		 * or the CPU is physically broken, and in both cases that
+		 * means most crypto inside of the CoCo instance will be
+		 * broken, defeating the purpose of CoCo in the first place. So
+		 * just panic here because it's absolutely unsafe to continue
+		 * executing.
+		 */
+		if (longs == 0)
+			panic("RDRAND is defective.");
+	}
+	add_device_randomness(rng_seed, sizeof(rng_seed));
+	memzero_explicit(rng_seed, sizeof(rng_seed));
 }
--- linux-qcom-6.8.0.orig/arch/x86/coco/tdx/tdx.c
+++ linux-qcom-6.8.0/arch/x86/coco/tdx/tdx.c
@@ -7,6 +7,7 @@
 #include <linux/cpufeature.h>
 #include <linux/export.h>
 #include <linux/io.h>
+#include <linux/kexec.h>
 #include <asm/coco.h>
 #include <asm/tdx.h>
 #include <asm/vmx.h>
@@ -14,6 +15,8 @@
 #include <asm/insn.h>
 #include <asm/insn-eval.h>
 #include <asm/pgtable.h>
+#include <asm/set_memory.h>
+#include <asm/traps.h>
 
 /* MMIO direction */
 #define EPT_READ	0
@@ -38,6 +41,8 @@
 
 #define TDREPORT_SUBTYPE_0	0
 
+static atomic_long_t nr_shared;
+
 /* Called from __tdx_hypercall() for unrecoverable failure */
 noinstr void __noreturn __tdx_hypercall_failed(void)
 {
@@ -73,6 +78,32 @@
 		panic("TDCALL %lld failed (Buggy TDX module!)\n", fn);
 }
 
+/* Read TD-scoped metadata */
+static inline u64 tdg_vm_rd(u64 field, u64 *value)
+{
+	struct tdx_module_args args = {
+		.rdx = field,
+	};
+	u64 ret;
+
+	ret = __tdcall_ret(TDG_VM_RD, &args);
+	*value = args.r8;
+
+	return ret;
+}
+
+/* Write TD-scoped metadata */
+static inline u64 tdg_vm_wr(u64 field, u64 value, u64 mask)
+{
+	struct tdx_module_args args = {
+		.rdx = field,
+		.r8 = value,
+		.r9 = mask,
+	};
+
+	return __tdcall(TDG_VM_WR, &args);
+}
+
 /**
  * tdx_mcall_get_report0() - Wrapper to get TDREPORT0 (a.k.a. TDREPORT
  *                           subtype 0) using TDG.MR.REPORT TDCALL.
@@ -163,7 +194,61 @@
 		__tdx_hypercall(&args);
 }
 
-static void tdx_parse_tdinfo(u64 *cc_mask)
+/*
+ * The kernel cannot handle #VEs when accessing normal kernel memory. Ensure
+ * that no #VE will be delivered for accesses to TD-private memory.
+ *
+ * TDX 1.0 does not allow the guest to disable SEPT #VE on its own. The VMM
+ * controls if the guest will receive such #VE with TD attribute
+ * ATTR_SEPT_VE_DISABLE.
+ *
+ * Newer TDX modules allow the guest to control if it wants to receive SEPT
+ * violation #VEs.
+ *
+ * Check if the feature is available and disable SEPT #VE if possible.
+ *
+ * If the TD is allowed to disable/enable SEPT #VEs, the ATTR_SEPT_VE_DISABLE
+ * attribute is no longer reliable. It reflects the initial state of the
+ * control for the TD, but it will not be updated if someone (e.g. bootloader)
+ * changes it before the kernel starts. Kernel must check TDCS_TD_CTLS bit to
+ * determine if SEPT #VEs are enabled or disabled.
+ */
+static void disable_sept_ve(u64 td_attr)
+{
+	const char *msg = "TD misconfiguration: SEPT #VE has to be disabled";
+	bool debug = td_attr & ATTR_DEBUG;
+	u64 config, controls;
+
+	/* Is this TD allowed to disable SEPT #VE */
+	tdg_vm_rd(TDCS_CONFIG_FLAGS, &config);
+	if (!(config & TDCS_CONFIG_FLEXIBLE_PENDING_VE)) {
+		/* No SEPT #VE controls for the guest: check the attribute */
+		if (td_attr & ATTR_SEPT_VE_DISABLE)
+			return;
+
+		/* Relax SEPT_VE_DISABLE check for debug TD for backtraces */
+		if (debug)
+			pr_warn("%s\n", msg);
+		else
+			tdx_panic(msg);
+		return;
+	}
+
+	/* Check if SEPT #VE has been disabled before us */
+	tdg_vm_rd(TDCS_TD_CTLS, &controls);
+	if (controls & TD_CTLS_PENDING_VE_DISABLE)
+		return;
+
+	/* Keep #VEs enabled for splats in debugging environments */
+	if (debug)
+		return;
+
+	/* Disable SEPT #VEs */
+	tdg_vm_wr(TDCS_TD_CTLS, TD_CTLS_PENDING_VE_DISABLE,
+		  TD_CTLS_PENDING_VE_DISABLE);
+}
+
+static void tdx_setup(u64 *cc_mask)
 {
 	struct tdx_module_args args = {};
 	unsigned int gpa_width;
@@ -188,21 +273,12 @@
 	gpa_width = args.rcx & GENMASK(5, 0);
 	*cc_mask = BIT_ULL(gpa_width - 1);
 
-	/*
-	 * The kernel can not handle #VE's when accessing normal kernel
-	 * memory.  Ensure that no #VE will be delivered for accesses to
-	 * TD-private memory.  Only VMM-shared memory (MMIO) will #VE.
-	 */
 	td_attr = args.rdx;
-	if (!(td_attr & ATTR_SEPT_VE_DISABLE)) {
-		const char *msg = "TD misconfiguration: SEPT_VE_DISABLE attribute must be set.";
 
-		/* Relax SEPT_VE_DISABLE check for debug TD. */
-		if (td_attr & ATTR_DEBUG)
-			pr_warn("%s\n", msg);
-		else
-			tdx_panic(msg);
-	}
+	/* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */
+	tdg_vm_wr(TDCS_NOTIFY_ENABLES, 0, -1ULL);
+
+	disable_sept_ve(td_attr);
 }
 
 /*
@@ -385,7 +461,6 @@
 		.r12 = size,
 		.r13 = EPT_READ,
 		.r14 = addr,
-		.r15 = *val,
 	};
 
 	if (__tdx_hypercall(&args))
@@ -430,6 +505,11 @@
 			return -EINVAL;
 	}
 
+	if (!fault_in_kernel_space(ve->gla)) {
+		WARN_ONCE(1, "Access to userspace address is not supported");
+		return -EINVAL;
+	}
+
 	/*
 	 * Reject EPT violation #VEs that split pages.
 	 *
@@ -798,36 +878,128 @@
 	return true;
 }
 
-static bool tdx_enc_status_change_prepare(unsigned long vaddr, int numpages,
-					  bool enc)
+static int tdx_enc_status_change_prepare(unsigned long vaddr, int numpages,
+					 bool enc)
 {
 	/*
 	 * Only handle shared->private conversion here.
 	 * See the comment in tdx_early_init().
 	 */
-	if (enc)
-		return tdx_enc_status_changed(vaddr, numpages, enc);
-	return true;
+	if (enc && !tdx_enc_status_changed(vaddr, numpages, enc))
+		return -EIO;
+
+	return 0;
 }
 
-static bool tdx_enc_status_change_finish(unsigned long vaddr, int numpages,
+static int tdx_enc_status_change_finish(unsigned long vaddr, int numpages,
 					 bool enc)
 {
 	/*
 	 * Only handle private->shared conversion here.
 	 * See the comment in tdx_early_init().
 	 */
-	if (!enc)
-		return tdx_enc_status_changed(vaddr, numpages, enc);
-	return true;
+	if (!enc && !tdx_enc_status_changed(vaddr, numpages, enc))
+		return -EIO;
+
+	if (enc)
+		atomic_long_sub(numpages, &nr_shared);
+	else
+		atomic_long_add(numpages, &nr_shared);
+
+	return 0;
+}
+
+/* Stop new private<->shared conversions */
+static void tdx_kexec_begin(void)
+{
+	if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+		return;
+
+	/*
+	 * Crash kernel reaches here with interrupts disabled: can't wait for
+	 * conversions to finish.
+	 *
+	 * If race happened, just report and proceed.
+	 */
+	if (!set_memory_enc_stop_conversion())
+		pr_warn("Failed to stop shared<->private conversions\n");
+}
+
+/* Walk direct mapping and convert all shared memory back to private */
+static void tdx_kexec_finish(void)
+{
+	unsigned long addr, end;
+	long found = 0, shared;
+
+	if (!IS_ENABLED(CONFIG_KEXEC_CORE))
+		return;
+
+	lockdep_assert_irqs_disabled();
+
+	addr = PAGE_OFFSET;
+	end  = PAGE_OFFSET + get_max_mapped();
+
+	while (addr < end) {
+		unsigned long size;
+		unsigned int level;
+		pte_t *pte;
+
+		pte = lookup_address(addr, &level);
+		size = page_level_size(level);
+
+		if (pte && pte_decrypted(*pte)) {
+			int pages = size / PAGE_SIZE;
+
+			/*
+			 * Touching memory with shared bit set triggers implicit
+			 * conversion to shared.
+			 *
+			 * Make sure nobody touches the shared range from
+			 * now on.
+			 */
+			set_pte(pte, __pte(0));
+
+			/*
+			 * Memory encryption state persists across kexec.
+			 * If tdx_enc_status_changed() fails in the first
+			 * kernel, it leaves memory in an unknown state.
+			 *
+			 * If that memory remains shared, accessing it in the
+			 * *next* kernel through a private mapping will result
+			 * in an unrecoverable guest shutdown.
+			 *
+			 * The kdump kernel boot is not impacted as it uses
+			 * a pre-reserved memory range that is always private.
+			 * However, gathering crash information could lead to
+			 * a crash if it accesses unconverted memory through
+			 * a private mapping which is possible when accessing
+			 * that memory through /proc/vmcore, for example.
+			 *
+			 * In all cases, print error info in order to leave
+			 * enough bread crumbs for debugging.
+			 */
+			if (!tdx_enc_status_changed(addr, pages, true)) {
+				pr_err("Failed to unshare range %#lx-%#lx\n",
+				       addr, addr + size);
+			}
+
+			found += pages;
+		}
+
+		addr += size;
+	}
+
+	__flush_tlb_all();
+
+	shared = atomic_long_read(&nr_shared);
+	if (shared != found) {
+		pr_err("shared page accounting is off\n");
+		pr_err("nr_shared = %ld, nr_found = %ld\n", shared, found);
+	}
 }
 
 void __init tdx_early_init(void)
 {
-	struct tdx_module_args args = {
-		.rdx = TDCS_NOTIFY_ENABLES,
-		.r9 = -1ULL,
-	};
 	u64 cc_mask;
 	u32 eax, sig[3];
 
@@ -842,11 +1014,11 @@
 	setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
 	cc_vendor = CC_VENDOR_INTEL;
-	tdx_parse_tdinfo(&cc_mask);
-	cc_set_mask(cc_mask);
 
-	/* Kernel does not use NOTIFY_ENABLES and does not need random #VEs */
-	tdcall(TDG_VM_WR, &args);
+	/* Configure the TD */
+	tdx_setup(&cc_mask);
+
+	cc_set_mask(cc_mask);
 
 	/*
 	 * All bits above GPA width are reserved and kernel treats shared bit
@@ -881,6 +1053,9 @@
 	x86_platform.guest.enc_cache_flush_required  = tdx_cache_flush_required;
 	x86_platform.guest.enc_tlb_flush_required    = tdx_tlb_flush_required;
 
+	x86_platform.guest.enc_kexec_begin	     = tdx_kexec_begin;
+	x86_platform.guest.enc_kexec_finish	     = tdx_kexec_finish;
+
 	/*
 	 * TDX intercepts the RDMSR to read the X2APIC ID in the parallel
 	 * bringup low level code. That raises #VE which cannot be handled
--- linux-qcom-6.8.0.orig/arch/x86/crypto/aegis128-aesni-asm.S
+++ linux-qcom-6.8.0/arch/x86/crypto/aegis128-aesni-asm.S
@@ -21,7 +21,7 @@
 #define T1	%xmm7
 
 #define STATEP	%rdi
-#define LEN	%rsi
+#define LEN	%esi
 #define SRC	%rdx
 #define DST	%rcx
 
@@ -76,32 +76,32 @@
 	xor %r9d, %r9d
 	pxor MSG, MSG
 
-	mov LEN, %r8
+	mov LEN, %r8d
 	and $0x1, %r8
 	jz .Lld_partial_1
 
-	mov LEN, %r8
+	mov LEN, %r8d
 	and $0x1E, %r8
 	add SRC, %r8
 	mov (%r8), %r9b
 
 .Lld_partial_1:
-	mov LEN, %r8
+	mov LEN, %r8d
 	and $0x2, %r8
 	jz .Lld_partial_2
 
-	mov LEN, %r8
+	mov LEN, %r8d
 	and $0x1C, %r8
 	add SRC, %r8
 	shl $0x10, %r9
 	mov (%r8), %r9w
 
 .Lld_partial_2:
-	mov LEN, %r8
+	mov LEN, %r8d
 	and $0x4, %r8
 	jz .Lld_partial_4
 
-	mov LEN, %r8
+	mov LEN, %r8d
 	and $0x18, %r8
 	add SRC, %r8
 	shl $32, %r9
@@ -111,11 +111,11 @@
 .Lld_partial_4:
 	movq %r9, MSG
 
-	mov LEN, %r8
+	mov LEN, %r8d
 	and $0x8, %r8
 	jz .Lld_partial_8
 
-	mov LEN, %r8
+	mov LEN, %r8d
 	and $0x10, %r8
 	add SRC, %r8
 	pslldq $8, MSG
@@ -139,7 +139,7 @@
  *   %r10
  */
 SYM_FUNC_START_LOCAL(__store_partial)
-	mov LEN, %r8
+	mov LEN, %r8d
 	mov DST, %r9
 
 	movq T0, %r10
@@ -677,7 +677,7 @@
 	call __store_partial
 
 	/* mask with byte count: */
-	movq LEN, T0
+	movd LEN, T0
 	punpcklbw T0, T0
 	punpcklbw T0, T0
 	punpcklbw T0, T0
@@ -702,7 +702,8 @@
 
 /*
  * void crypto_aegis128_aesni_final(void *state, void *tag_xor,
- *                                  u64 assoclen, u64 cryptlen);
+ *                                  unsigned int assoclen,
+ *                                  unsigned int cryptlen);
  */
 SYM_FUNC_START(crypto_aegis128_aesni_final)
 	FRAME_BEGIN
@@ -715,8 +716,8 @@
 	movdqu 0x40(STATEP), STATE4
 
 	/* prepare length block: */
-	movq %rdx, MSG
-	movq %rcx, T0
+	movd %edx, MSG
+	movd %ecx, T0
 	pslldq $8, T0
 	pxor T0, MSG
 	psllq $3, MSG /* multiply by 8 (to get bit count) */
--- linux-qcom-6.8.0.orig/arch/x86/crypto/nh-avx2-x86_64.S
+++ linux-qcom-6.8.0/arch/x86/crypto/nh-avx2-x86_64.S
@@ -154,5 +154,6 @@
 	vpaddq		T1, T0, T0
 	vpaddq		T4, T0, T0
 	vmovdqu		T0, (HASH)
+	vzeroupper
 	RET
 SYM_FUNC_END(nh_avx2)
--- linux-qcom-6.8.0.orig/arch/x86/crypto/sha256-avx2-asm.S
+++ linux-qcom-6.8.0/arch/x86/crypto/sha256-avx2-asm.S
@@ -592,22 +592,22 @@
 	leaq	K256+0*32(%rip), INP		## reuse INP as scratch reg
 	vpaddd	(INP, SRND), X0, XFER
 	vmovdqa XFER, 0*32+_XFER(%rsp, SRND)
-	FOUR_ROUNDS_AND_SCHED	_XFER + 0*32
+	FOUR_ROUNDS_AND_SCHED	(_XFER + 0*32)
 
 	leaq	K256+1*32(%rip), INP
 	vpaddd	(INP, SRND), X0, XFER
 	vmovdqa XFER, 1*32+_XFER(%rsp, SRND)
-	FOUR_ROUNDS_AND_SCHED	_XFER + 1*32
+	FOUR_ROUNDS_AND_SCHED	(_XFER + 1*32)
 
 	leaq	K256+2*32(%rip), INP
 	vpaddd	(INP, SRND), X0, XFER
 	vmovdqa XFER, 2*32+_XFER(%rsp, SRND)
-	FOUR_ROUNDS_AND_SCHED	_XFER + 2*32
+	FOUR_ROUNDS_AND_SCHED	(_XFER + 2*32)
 
 	leaq	K256+3*32(%rip), INP
 	vpaddd	(INP, SRND), X0, XFER
 	vmovdqa XFER, 3*32+_XFER(%rsp, SRND)
-	FOUR_ROUNDS_AND_SCHED	_XFER + 3*32
+	FOUR_ROUNDS_AND_SCHED	(_XFER + 3*32)
 
 	add	$4*32, SRND
 	cmp	$3*4*32, SRND
@@ -618,12 +618,12 @@
 	leaq	K256+0*32(%rip), INP
 	vpaddd	(INP, SRND), X0, XFER
 	vmovdqa XFER, 0*32+_XFER(%rsp, SRND)
-	DO_4ROUNDS	_XFER + 0*32
+	DO_4ROUNDS	(_XFER + 0*32)
 
 	leaq	K256+1*32(%rip), INP
 	vpaddd	(INP, SRND), X1, XFER
 	vmovdqa XFER, 1*32+_XFER(%rsp, SRND)
-	DO_4ROUNDS	_XFER + 1*32
+	DO_4ROUNDS	(_XFER + 1*32)
 	add	$2*32, SRND
 
 	vmovdqa	X2, X0
@@ -651,8 +651,8 @@
 	xor	SRND, SRND
 .align 16
 .Lloop3:
-	DO_4ROUNDS	 _XFER + 0*32 + 16
-	DO_4ROUNDS	 _XFER + 1*32 + 16
+	DO_4ROUNDS	(_XFER + 0*32 + 16)
+	DO_4ROUNDS	(_XFER + 1*32 + 16)
 	add	$2*32, SRND
 	cmp	$4*4*32, SRND
 	jb	.Lloop3
@@ -716,6 +716,7 @@
 	popq	%r13
 	popq	%r12
 	popq	%rbx
+	vzeroupper
 	RET
 SYM_FUNC_END(sha256_transform_rorx)
 
--- linux-qcom-6.8.0.orig/arch/x86/crypto/sha512-avx2-asm.S
+++ linux-qcom-6.8.0/arch/x86/crypto/sha512-avx2-asm.S
@@ -680,6 +680,7 @@
 	pop	%r12
 	pop	%rbx
 
+	vzeroupper
 	RET
 SYM_FUNC_END(sha512_transform_rorx)
 
--- linux-qcom-6.8.0.orig/arch/x86/entry/common.c
+++ linux-qcom-6.8.0/arch/x86/entry/common.c
@@ -49,7 +49,7 @@
 
 	if (likely(unr < NR_syscalls)) {
 		unr = array_index_nospec(unr, NR_syscalls);
-		regs->ax = sys_call_table[unr](regs);
+		regs->ax = x64_sys_call(regs, unr);
 		return true;
 	}
 	return false;
@@ -66,7 +66,7 @@
 
 	if (IS_ENABLED(CONFIG_X86_X32_ABI) && likely(xnr < X32_NR_syscalls)) {
 		xnr = array_index_nospec(xnr, X32_NR_syscalls);
-		regs->ax = x32_sys_call_table[xnr](regs);
+		regs->ax = x32_sys_call(regs, xnr);
 		return true;
 	}
 	return false;
@@ -162,7 +162,7 @@
 
 	if (likely(unr < IA32_NR_syscalls)) {
 		unr = array_index_nospec(unr, IA32_NR_syscalls);
-		regs->ax = ia32_sys_call_table[unr](regs);
+		regs->ax = ia32_sys_call(regs, unr);
 	} else if (nr != -1) {
 		regs->ax = __ia32_sys_ni_syscall(regs);
 	}
@@ -189,7 +189,7 @@
 }
 
 /**
- * int80_emulation - 32-bit legacy syscall entry
+ * do_int80_emulation - 32-bit legacy syscall C entry from asm
  *
  * This entry point can be used by 32-bit and 64-bit programs to perform
  * 32-bit system calls.  Instances of INT $0x80 can be found inline in
@@ -207,7 +207,7 @@
  *   eax:				system call number
  *   ebx, ecx, edx, esi, edi, ebp:	arg1 - arg 6
  */
-DEFINE_IDTENTRY_RAW(int80_emulation)
+__visible noinstr void do_int80_emulation(struct pt_regs *regs)
 {
 	int nr;
 
--- linux-qcom-6.8.0.orig/arch/x86/entry/entry.S
+++ linux-qcom-6.8.0/arch/x86/entry/entry.S
@@ -9,6 +9,8 @@
 #include <asm/unwind_hints.h>
 #include <asm/segment.h>
 #include <asm/cache.h>
+#include <asm/cpufeatures.h>
+#include <asm/nospec-branch.h>
 
 .pushsection .noinstr.text, "ax"
 
@@ -17,6 +19,9 @@
 	movl	$PRED_CMD_IBPB, %eax
 	xorl	%edx, %edx
 	wrmsr
+
+	/* Make sure IBPB clears return stack preductions too. */
+	FILL_RETURN_BUFFER %rax, RSB_CLEAR_LOOPS, X86_BUG_IBPB_NO_RET
 	RET
 SYM_FUNC_END(entry_ibpb)
 /* For KVM */
@@ -43,3 +48,18 @@
 
 .popsection
 
+#ifndef CONFIG_X86_64
+/*
+ * Clang's implementation of TLS stack cookies requires the variable in
+ * question to be a TLS variable. If the variable happens to be defined as an
+ * ordinary variable with external linkage in the same compilation unit (which
+ * amounts to the whole of vmlinux with LTO enabled), Clang will drop the
+ * segment register prefix from the references, resulting in broken code. Work
+ * around this by avoiding the symbol used in -mstack-protector-guard-symbol=
+ * entirely in the C code, and use an alias emitted by the linker script
+ * instead.
+ */
+#ifdef CONFIG_STACKPROTECTOR
+EXPORT_SYMBOL(__ref_stack_chk_guard);
+#endif
+#endif
--- linux-qcom-6.8.0.orig/arch/x86/entry/entry_32.S
+++ linux-qcom-6.8.0/arch/x86/entry/entry_32.S
@@ -875,6 +875,8 @@
 
 	/* Now ready to switch the cr3 */
 	SWITCH_TO_USER_CR3 scratch_reg=%eax
+	/* Clobbers ZF */
+	CLEAR_CPU_BUFFERS
 
 	/*
 	 * Restore all flags except IF. (We restore IF separately because
@@ -885,7 +887,6 @@
 	BUG_IF_WRONG_CR3 no_user_check=1
 	popfl
 	popl	%eax
-	CLEAR_CPU_BUFFERS
 
 	/*
 	 * Return back to the vDSO, which will pop ecx and edx.
@@ -1148,7 +1149,6 @@
 
 	/* Not on SYSENTER stack. */
 	call	exc_nmi
-	CLEAR_CPU_BUFFERS
 	jmp	.Lnmi_return
 
 .Lnmi_from_sysenter_stack:
@@ -1169,6 +1169,7 @@
 
 	CHECK_AND_APPLY_ESPFIX
 	RESTORE_ALL_NMI cr3_reg=%edi pop=4
+	CLEAR_CPU_BUFFERS
 	jmp	.Lirq_return
 
 #ifdef CONFIG_X86_ESPFIX32
@@ -1210,6 +1211,7 @@
 	 *  1 - orig_ax
 	 */
 	lss	(1+5+6)*4(%esp), %esp			# back to espfix stack
+	CLEAR_CPU_BUFFERS
 	jmp	.Lirq_return
 #endif
 SYM_CODE_END(asm_exc_nmi)
--- linux-qcom-6.8.0.orig/arch/x86/entry/entry_64.S
+++ linux-qcom-6.8.0/arch/x86/entry/entry_64.S
@@ -116,6 +116,7 @@
 	/* clobbers %rax, make sure it is after saving the syscall nr */
 	IBRS_ENTER
 	UNTRAIN_RET
+	CLEAR_BRANCH_HISTORY
 
 	call	do_syscall_64		/* returns with IRQs disabled */
 
@@ -1494,3 +1495,63 @@
 	call	make_task_dead
 SYM_CODE_END(rewind_stack_and_make_dead)
 .popsection
+
+/*
+ * This sequence executes branches in order to remove user branch information
+ * from the branch history tracker in the Branch Predictor, therefore removing
+ * user influence on subsequent BTB lookups.
+ *
+ * It should be used on parts prior to Alder Lake. Newer parts should use the
+ * BHI_DIS_S hardware control instead. If a pre-Alder Lake part is being
+ * virtualized on newer hardware the VMM should protect against BHI attacks by
+ * setting BHI_DIS_S for the guests.
+ *
+ * CALLs/RETs are necessary to prevent Loop Stream Detector(LSD) from engaging
+ * and not clearing the branch history. The call tree looks like:
+ *
+ * call 1
+ *    call 2
+ *      call 2
+ *        call 2
+ *          call 2
+ * 	      call 2
+ * 	      ret
+ * 	    ret
+ *        ret
+ *      ret
+ *    ret
+ * ret
+ *
+ * This means that the stack is non-constant and ORC can't unwind it with %rsp
+ * alone.  Therefore we unconditionally set up the frame pointer, which allows
+ * ORC to unwind properly.
+ *
+ * The alignment is for performance and not for safety, and may be safely
+ * refactored in the future if needed.
+ */
+SYM_FUNC_START(clear_bhb_loop)
+	push	%rbp
+	mov	%rsp, %rbp
+	movl	$5, %ecx
+	ANNOTATE_INTRA_FUNCTION_CALL
+	call	1f
+	jmp	5f
+	.align 64, 0xcc
+	ANNOTATE_INTRA_FUNCTION_CALL
+1:	call	2f
+	RET
+	.align 64, 0xcc
+2:	movl	$5, %eax
+3:	jmp	4f
+	nop
+4:	sub	$1, %eax
+	jnz	3b
+	sub	$1, %ecx
+	jnz	1b
+	RET
+5:	lfence
+	pop	%rbp
+	RET
+SYM_FUNC_END(clear_bhb_loop)
+EXPORT_SYMBOL_GPL(clear_bhb_loop)
+STACK_FRAME_NON_STANDARD(clear_bhb_loop)
--- linux-qcom-6.8.0.orig/arch/x86/entry/entry_64_compat.S
+++ linux-qcom-6.8.0/arch/x86/entry/entry_64_compat.S
@@ -90,9 +90,6 @@
 
 	cld
 
-	IBRS_ENTER
-	UNTRAIN_RET
-
 	/*
 	 * SYSENTER doesn't filter flags, so we need to clear NT and AC
 	 * ourselves.  To save a few cycles, we can check whether
@@ -116,6 +113,16 @@
 	jnz	.Lsysenter_fix_flags
 .Lsysenter_flags_fixed:
 
+	/*
+	 * CPU bugs mitigations mechanisms can call other functions. They
+	 * should be invoked after making sure TF is cleared because
+	 * single-step is ignored only for instructions inside the
+	 * entry_SYSENTER_compat function.
+	 */
+	IBRS_ENTER
+	UNTRAIN_RET
+	CLEAR_BRANCH_HISTORY
+
 	movq	%rsp, %rdi
 	call	do_SYSENTER_32
 	jmp	sysret32_from_system_call
@@ -206,6 +213,7 @@
 
 	IBRS_ENTER
 	UNTRAIN_RET
+	CLEAR_BRANCH_HISTORY
 
 	movq	%rsp, %rdi
 	call	do_fast_syscall_32
@@ -276,3 +284,17 @@
 	ANNOTATE_NOENDBR
 	int3
 SYM_CODE_END(entry_SYSCALL_compat)
+
+/*
+ * int 0x80 is used by 32 bit mode as a system call entry. Normally idt entries
+ * point to C routines, however since this is a system call interface the branch
+ * history needs to be scrubbed to protect against BHI attacks, and that
+ * scrubbing needs to take place in assembly code prior to entering any C
+ * routines.
+ */
+SYM_CODE_START(int80_emulation)
+	ANNOTATE_NOENDBR
+	UNWIND_HINT_FUNC
+	CLEAR_BRANCH_HISTORY
+	jmp do_int80_emulation
+SYM_CODE_END(int80_emulation)
--- linux-qcom-6.8.0.orig/arch/x86/entry/syscall_32.c
+++ linux-qcom-6.8.0/arch/x86/entry/syscall_32.c
@@ -14,12 +14,31 @@
 #endif
 
 #define __SYSCALL(nr, sym) extern long __ia32_##sym(const struct pt_regs *);
-
+#define __SYSCALL_NORETURN(nr, sym) extern long __noreturn __ia32_##sym(const struct pt_regs *);
 #include <asm/syscalls_32.h>
-#undef __SYSCALL
+#undef  __SYSCALL
 
-#define __SYSCALL(nr, sym) __ia32_##sym,
+#undef  __SYSCALL_NORETURN
+#define __SYSCALL_NORETURN __SYSCALL
 
-__visible const sys_call_ptr_t ia32_sys_call_table[] = {
+/*
+ * The sys_call_table[] is no longer used for system calls, but
+ * kernel/trace/trace_syscalls.c still wants to know the system
+ * call address.
+ */
+#ifdef CONFIG_X86_32
+#define __SYSCALL(nr, sym) __ia32_##sym,
+const sys_call_ptr_t sys_call_table[] = {
 #include <asm/syscalls_32.h>
 };
+#undef  __SYSCALL
+#endif
+
+#define __SYSCALL(nr, sym) case nr: return __ia32_##sym(regs);
+long ia32_sys_call(const struct pt_regs *regs, unsigned int nr)
+{
+	switch (nr) {
+	#include <asm/syscalls_32.h>
+	default: return __ia32_sys_ni_syscall(regs);
+	}
+};
--- linux-qcom-6.8.0.orig/arch/x86/entry/syscall_64.c
+++ linux-qcom-6.8.0/arch/x86/entry/syscall_64.c
@@ -8,11 +8,29 @@
 #include <asm/syscall.h>
 
 #define __SYSCALL(nr, sym) extern long __x64_##sym(const struct pt_regs *);
+#define __SYSCALL_NORETURN(nr, sym) extern long __noreturn __x64_##sym(const struct pt_regs *);
 #include <asm/syscalls_64.h>
-#undef __SYSCALL
+#undef  __SYSCALL
 
-#define __SYSCALL(nr, sym) __x64_##sym,
+#undef  __SYSCALL_NORETURN
+#define __SYSCALL_NORETURN __SYSCALL
 
-asmlinkage const sys_call_ptr_t sys_call_table[] = {
+/*
+ * The sys_call_table[] is no longer used for system calls, but
+ * kernel/trace/trace_syscalls.c still wants to know the system
+ * call address.
+ */
+#define __SYSCALL(nr, sym) __x64_##sym,
+const sys_call_ptr_t sys_call_table[] = {
 #include <asm/syscalls_64.h>
 };
+#undef  __SYSCALL
+
+#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs);
+long x64_sys_call(const struct pt_regs *regs, unsigned int nr)
+{
+	switch (nr) {
+	#include <asm/syscalls_64.h>
+	default: return __x64_sys_ni_syscall(regs);
+	}
+};
--- linux-qcom-6.8.0.orig/arch/x86/entry/syscall_x32.c
+++ linux-qcom-6.8.0/arch/x86/entry/syscall_x32.c
@@ -8,11 +8,18 @@
 #include <asm/syscall.h>
 
 #define __SYSCALL(nr, sym) extern long __x64_##sym(const struct pt_regs *);
+#define __SYSCALL_NORETURN(nr, sym) extern long __noreturn __x64_##sym(const struct pt_regs *);
 #include <asm/syscalls_x32.h>
-#undef __SYSCALL
+#undef  __SYSCALL
 
-#define __SYSCALL(nr, sym) __x64_##sym,
+#undef  __SYSCALL_NORETURN
+#define __SYSCALL_NORETURN __SYSCALL
 
-asmlinkage const sys_call_ptr_t x32_sys_call_table[] = {
-#include <asm/syscalls_x32.h>
+#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs);
+long x32_sys_call(const struct pt_regs *regs, unsigned int nr)
+{
+	switch (nr) {
+	#include <asm/syscalls_x32.h>
+	default: return __x64_sys_ni_syscall(regs);
+	}
 };
--- linux-qcom-6.8.0.orig/arch/x86/entry/syscalls/syscall_32.tbl
+++ linux-qcom-6.8.0/arch/x86/entry/syscalls/syscall_32.tbl
@@ -2,7 +2,7 @@
 # 32-bit system call numbers and entry vectors
 #
 # The format is:
-# <number> <abi> <name> <entry point> <compat entry point>
+# <number> <abi> <name> <entry point> [<compat entry point> [noreturn]]
 #
 # The __ia32_sys and __ia32_compat_sys stubs are created on-the-fly for
 # sys_*() system calls and compat_sys_*() compat system calls if
@@ -12,7 +12,7 @@
 # The abi is always "i386" for this file.
 #
 0	i386	restart_syscall		sys_restart_syscall
-1	i386	exit			sys_exit
+1	i386	exit			sys_exit			-			noreturn
 2	i386	fork			sys_fork
 3	i386	read			sys_read
 4	i386	write			sys_write
@@ -263,7 +263,7 @@
 249	i386	io_cancel		sys_io_cancel
 250	i386	fadvise64		sys_ia32_fadvise64
 # 251 is available for reuse (was briefly sys_set_zone_reclaim)
-252	i386	exit_group		sys_exit_group
+252	i386	exit_group		sys_exit_group			-			noreturn
 253	i386	lookup_dcookie
 254	i386	epoll_create		sys_epoll_create
 255	i386	epoll_ctl		sys_epoll_ctl
@@ -420,7 +420,7 @@
 412	i386	utimensat_time64	sys_utimensat
 413	i386	pselect6_time64		sys_pselect6			compat_sys_pselect6_time64
 414	i386	ppoll_time64		sys_ppoll			compat_sys_ppoll_time64
-416	i386	io_pgetevents_time64	sys_io_pgetevents
+416	i386	io_pgetevents_time64	sys_io_pgetevents		compat_sys_io_pgetevents_time64
 417	i386	recvmmsg_time64		sys_recvmmsg			compat_sys_recvmmsg_time64
 418	i386	mq_timedsend_time64	sys_mq_timedsend
 419	i386	mq_timedreceive_time64	sys_mq_timedreceive
--- linux-qcom-6.8.0.orig/arch/x86/entry/syscalls/syscall_64.tbl
+++ linux-qcom-6.8.0/arch/x86/entry/syscalls/syscall_64.tbl
@@ -2,7 +2,7 @@
 # 64-bit system call numbers and entry vectors
 #
 # The format is:
-# <number> <abi> <name> <entry point>
+# <number> <abi> <name> <entry point> [<compat entry point> [noreturn]]
 #
 # The __x64_sys_*() stubs are created on-the-fly for sys_*() system calls
 #
@@ -68,7 +68,7 @@
 57	common	fork			sys_fork
 58	common	vfork			sys_vfork
 59	64	execve			sys_execve
-60	common	exit			sys_exit
+60	common	exit			sys_exit			-			noreturn
 61	common	wait4			sys_wait4
 62	common	kill			sys_kill
 63	common	uname			sys_newuname
@@ -239,7 +239,7 @@
 228	common	clock_gettime		sys_clock_gettime
 229	common	clock_getres		sys_clock_getres
 230	common	clock_nanosleep		sys_clock_nanosleep
-231	common	exit_group		sys_exit_group
+231	common	exit_group		sys_exit_group			-			noreturn
 232	common	epoll_wait		sys_epoll_wait
 233	common	epoll_ctl		sys_epoll_ctl
 234	common	tgkill			sys_tgkill
--- linux-qcom-6.8.0.orig/arch/x86/entry/vdso/Makefile
+++ linux-qcom-6.8.0/arch/x86/entry/vdso/Makefile
@@ -34,8 +34,13 @@
 KASAN_SANITIZE_vma.o			:= y
 UBSAN_SANITIZE_vma.o			:= y
 KCSAN_SANITIZE_vma.o			:= y
-OBJECT_FILES_NON_STANDARD_vma.o		:= n
-OBJECT_FILES_NON_STANDARD_extable.o	:= n
+
+OBJECT_FILES_NON_STANDARD_extable.o		:= n
+OBJECT_FILES_NON_STANDARD_vdso-image-32.o 	:= n
+OBJECT_FILES_NON_STANDARD_vdso-image-x32.o	:= n
+OBJECT_FILES_NON_STANDARD_vdso-image-64.o 	:= n
+OBJECT_FILES_NON_STANDARD_vdso32-setup.o	:= n
+OBJECT_FILES_NON_STANDARD_vma.o			:= n
 
 # vDSO images to build
 vdso_img-$(VDSO64-y)		+= 64
@@ -43,7 +48,6 @@
 vdso_img-$(VDSO32-y)		+= 32
 
 obj-$(VDSO32-y)				 += vdso32-setup.o
-OBJECT_FILES_NON_STANDARD_vdso32-setup.o := n
 
 vobjs := $(foreach F,$(vobjs-y),$(obj)/$F)
 vobjs32 := $(foreach F,$(vobjs32-y),$(obj)/$F)
--- linux-qcom-6.8.0.orig/arch/x86/entry/vsyscall/vsyscall_64.c
+++ linux-qcom-6.8.0/arch/x86/entry/vsyscall/vsyscall_64.c
@@ -76,7 +76,7 @@
 	if (!show_unhandled_signals)
 		return;
 
-	printk_ratelimited("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n",
+	printk_ratelimited("%s%s[%d] %s ip:%lx cs:%x sp:%lx ax:%lx si:%lx di:%lx\n",
 			   level, current->comm, task_pid_nr(current),
 			   message, regs->ip, regs->cs,
 			   regs->sp, regs->ax, regs->si, regs->di);
@@ -98,11 +98,6 @@
 
 static bool write_ok_or_segv(unsigned long ptr, size_t size)
 {
-	/*
-	 * XXX: if access_ok, get_user, and put_user handled
-	 * sig_on_uaccess_err, this could go away.
-	 */
-
 	if (!access_ok((void __user *)ptr, size)) {
 		struct thread_struct *thread = &current->thread;
 
@@ -120,10 +115,8 @@
 bool emulate_vsyscall(unsigned long error_code,
 		      struct pt_regs *regs, unsigned long address)
 {
-	struct task_struct *tsk;
 	unsigned long caller;
 	int vsyscall_nr, syscall_nr, tmp;
-	int prev_sig_on_uaccess_err;
 	long ret;
 	unsigned long orig_dx;
 
@@ -172,8 +165,6 @@
 		goto sigsegv;
 	}
 
-	tsk = current;
-
 	/*
 	 * Check for access_ok violations and find the syscall nr.
 	 *
@@ -234,12 +225,8 @@
 		goto do_ret;  /* skip requested */
 
 	/*
-	 * With a real vsyscall, page faults cause SIGSEGV.  We want to
-	 * preserve that behavior to make writing exploits harder.
+	 * With a real vsyscall, page faults cause SIGSEGV.
 	 */
-	prev_sig_on_uaccess_err = current->thread.sig_on_uaccess_err;
-	current->thread.sig_on_uaccess_err = 1;
-
 	ret = -EFAULT;
 	switch (vsyscall_nr) {
 	case 0:
@@ -262,23 +249,12 @@
 		break;
 	}
 
-	current->thread.sig_on_uaccess_err = prev_sig_on_uaccess_err;
-
 check_fault:
 	if (ret == -EFAULT) {
 		/* Bad news -- userspace fed a bad pointer to a vsyscall. */
 		warn_bad_vsyscall(KERN_INFO, regs,
 				  "vsyscall fault (exploit attempt?)");
-
-		/*
-		 * If we failed to generate a signal for any reason,
-		 * generate one here.  (This should be impossible.)
-		 */
-		if (WARN_ON_ONCE(!sigismember(&tsk->pending.signal, SIGBUS) &&
-				 !sigismember(&tsk->pending.signal, SIGSEGV)))
-			goto sigsegv;
-
-		return true;  /* Don't emulate the ret. */
+		goto sigsegv;
 	}
 
 	regs->ax = ret;
--- linux-qcom-6.8.0.orig/arch/x86/events/amd/core.c
+++ linux-qcom-6.8.0/arch/x86/events/amd/core.c
@@ -250,7 +250,7 @@
 /*
  * AMD Performance Monitor Family 17h and later:
  */
-static const u64 amd_f17h_perfmon_event_map[PERF_COUNT_HW_MAX] =
+static const u64 amd_zen1_perfmon_event_map[PERF_COUNT_HW_MAX] =
 {
 	[PERF_COUNT_HW_CPU_CYCLES]		= 0x0076,
 	[PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
@@ -262,10 +262,24 @@
 	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND]	= 0x0187,
 };
 
+static const u64 amd_zen2_perfmon_event_map[PERF_COUNT_HW_MAX] =
+{
+	[PERF_COUNT_HW_CPU_CYCLES]		= 0x0076,
+	[PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
+	[PERF_COUNT_HW_CACHE_REFERENCES]	= 0xff60,
+	[PERF_COUNT_HW_CACHE_MISSES]		= 0x0964,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= 0x00c2,
+	[PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c3,
+	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND]	= 0x00a9,
+};
+
 static u64 amd_pmu_event_map(int hw_event)
 {
-	if (boot_cpu_data.x86 >= 0x17)
-		return amd_f17h_perfmon_event_map[hw_event];
+	if (cpu_feature_enabled(X86_FEATURE_ZEN2) || boot_cpu_data.x86 >= 0x19)
+		return amd_zen2_perfmon_event_map[hw_event];
+
+	if (cpu_feature_enabled(X86_FEATURE_ZEN1))
+		return amd_zen1_perfmon_event_map[hw_event];
 
 	return amd_perfmon_event_map[hw_event];
 }
@@ -403,8 +417,10 @@
 	 * be removed on one CPU at a time AND PMU is disabled
 	 * when we come here
 	 */
-	for (i = 0; i < x86_pmu.num_counters; i++) {
-		if (cmpxchg(nb->owners + i, event, NULL) == event)
+	for_each_set_bit(i, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
+		struct perf_event *tmp = event;
+
+		if (try_cmpxchg(nb->owners + i, &tmp, NULL))
 			break;
 	}
 }
@@ -470,7 +486,7 @@
 	 * because of successive calls to x86_schedule_events() from
 	 * hw_perf_group_sched_in() without hw_perf_enable()
 	 */
-	for_each_set_bit(idx, c->idxmsk, x86_pmu.num_counters) {
+	for_each_set_bit(idx, c->idxmsk, x86_pmu_max_num_counters(NULL)) {
 		if (new == -1 || hwc->idx == idx)
 			/* assign free slot, prefer hwc->idx */
 			old = cmpxchg(nb->owners + idx, NULL, event);
@@ -513,7 +529,7 @@
 	/*
 	 * initialize all possible NB constraints
 	 */
-	for (i = 0; i < x86_pmu.num_counters; i++) {
+	for_each_set_bit(i, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
 		__set_bit(i, nb->event_constraints[i].idxmsk);
 		nb->event_constraints[i].weight = 1;
 	}
@@ -604,7 +620,6 @@
 
 	kfree(cpuhw->lbr_sel);
 	cpuhw->lbr_sel = NULL;
-	amd_pmu_cpu_reset(cpu);
 
 	if (!x86_pmu.amd_nb_constraints)
 		return;
@@ -707,7 +722,7 @@
 	 * counters are always enabled when this function is called and
 	 * ARCH_PERFMON_EVENTSEL_INT is always set.
 	 */
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+	for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
 		if (!test_bit(idx, cpuc->active_mask))
 			continue;
 
@@ -727,7 +742,7 @@
 
 	amd_brs_enable_all();
 
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+	for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
 		/* only activate events which are marked as active */
 		if (!test_bit(idx, cpuc->active_mask))
 			continue;
@@ -882,11 +897,12 @@
 static int amd_pmu_v2_handle_irq(struct pt_regs *regs)
 {
 	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+	static atomic64_t status_warned = ATOMIC64_INIT(0);
+	u64 reserved, status, mask, new_bits, prev_bits;
 	struct perf_sample_data data;
 	struct hw_perf_event *hwc;
 	struct perf_event *event;
 	int handled = 0, idx;
-	u64 reserved, status, mask;
 	bool pmu_enabled;
 
 	/*
@@ -919,7 +935,7 @@
 	/* Clear any reserved bits set by buggy microcode */
 	status &= amd_pmu_global_cntr_mask;
 
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+	for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
 		if (!test_bit(idx, cpuc->active_mask))
 			continue;
 
@@ -951,7 +967,12 @@
 	 * the corresponding PMCs are expected to be inactive according to the
 	 * active_mask
 	 */
-	WARN_ON(status > 0);
+	if (status > 0) {
+		prev_bits = atomic64_fetch_or(status, &status_warned);
+		// A new bit was set for the very first time.
+		new_bits = status & ~prev_bits;
+		WARN(new_bits, "New overflows for inactive PMCs: %llx\n", new_bits);
+	}
 
 	/* Clear overflow and freeze bits */
 	amd_pmu_ack_global_status(~status);
@@ -1254,7 +1275,7 @@
 	.addr_offset            = amd_pmu_addr_offset,
 	.event_map		= amd_pmu_event_map,
 	.max_events		= ARRAY_SIZE(amd_perfmon_event_map),
-	.num_counters		= AMD64_NUM_COUNTERS,
+	.cntr_mask64		= GENMASK_ULL(AMD64_NUM_COUNTERS - 1, 0),
 	.add			= amd_pmu_add_event,
 	.del			= amd_pmu_del_event,
 	.cntval_bits		= 48,
@@ -1353,7 +1374,7 @@
 	 */
 	x86_pmu.eventsel	= MSR_F15H_PERF_CTL;
 	x86_pmu.perfctr		= MSR_F15H_PERF_CTR;
-	x86_pmu.num_counters	= AMD64_NUM_COUNTERS_CORE;
+	x86_pmu.cntr_mask64	= GENMASK_ULL(AMD64_NUM_COUNTERS_CORE - 1, 0);
 
 	/* Check for Performance Monitoring v2 support */
 	if (boot_cpu_has(X86_FEATURE_PERFMON_V2)) {
@@ -1363,9 +1384,9 @@
 		x86_pmu.version = 2;
 
 		/* Find the number of available Core PMCs */
-		x86_pmu.num_counters = ebx.split.num_core_pmc;
+		x86_pmu.cntr_mask64 = GENMASK_ULL(ebx.split.num_core_pmc - 1, 0);
 
-		amd_pmu_global_cntr_mask = (1ULL << x86_pmu.num_counters) - 1;
+		amd_pmu_global_cntr_mask = x86_pmu.cntr_mask64;
 
 		/* Update PMC handling functions */
 		x86_pmu.enable_all = amd_pmu_v2_enable_all;
@@ -1393,12 +1414,12 @@
 		 * even numbered counter that has a consecutive adjacent odd
 		 * numbered counter following it.
 		 */
-		for (i = 0; i < x86_pmu.num_counters - 1; i += 2)
+		for (i = 0; i < x86_pmu_max_num_counters(NULL) - 1; i += 2)
 			even_ctr_mask |= BIT_ULL(i);
 
 		pair_constraint = (struct event_constraint)
 				    __EVENT_CONSTRAINT(0, even_ctr_mask, 0,
-				    x86_pmu.num_counters / 2, 0,
+				    x86_pmu_max_num_counters(NULL) / 2, 0,
 				    PERF_X86_EVENT_PAIR);
 
 		x86_pmu.get_event_constraints = amd_get_event_constraints_f17h;
--- linux-qcom-6.8.0.orig/arch/x86/events/amd/ibs.c
+++ linux-qcom-6.8.0/arch/x86/events/amd/ibs.c
@@ -1118,7 +1118,7 @@
 				.data = ibs_data.data,
 			},
 		};
-		perf_sample_save_raw_data(&data, &raw);
+		perf_sample_save_raw_data(&data, event, &raw);
 	}
 
 	if (perf_ibs == &perf_ibs_op)
--- linux-qcom-6.8.0.orig/arch/x86/events/amd/lbr.c
+++ linux-qcom-6.8.0/arch/x86/events/amd/lbr.c
@@ -173,9 +173,11 @@
 
 		/*
 		 * Check if a branch has been logged; if valid = 0, spec = 0
-		 * then no branch was recorded
+		 * then no branch was recorded; if reserved = 1 then an
+		 * erroneous branch was recorded (see Erratum 1452)
 		 */
-		if (!entry.to.split.valid && !entry.to.split.spec)
+		if ((!entry.to.split.valid && !entry.to.split.spec) ||
+		    entry.to.split.reserved)
 			continue;
 
 		perf_clear_branch_entry_bitfields(br + out);
--- linux-qcom-6.8.0.orig/arch/x86/events/amd/uncore.c
+++ linux-qcom-6.8.0/arch/x86/events/amd/uncore.c
@@ -162,7 +162,9 @@
 	/* if not, take the first available counter */
 	hwc->idx = -1;
 	for (i = 0; i < pmu->num_counters; i++) {
-		if (cmpxchg(&ctx->events[i], NULL, event) == NULL) {
+		struct perf_event *tmp = NULL;
+
+		if (try_cmpxchg(&ctx->events[i], &tmp, event)) {
 			hwc->idx = i;
 			break;
 		}
@@ -196,7 +198,9 @@
 	event->pmu->stop(event, PERF_EF_UPDATE);
 
 	for (i = 0; i < pmu->num_counters; i++) {
-		if (cmpxchg(&ctx->events[i], event, NULL) == event)
+		struct perf_event *tmp = event;
+
+		if (try_cmpxchg(&ctx->events[i], &tmp, NULL))
 			break;
 	}
 
@@ -639,7 +643,7 @@
 	info.split.aux_data = 0;
 	info.split.num_pmcs = NUM_COUNTERS_NB;
 	info.split.gid = 0;
-	info.split.cid = topology_die_id(cpu);
+	info.split.cid = topology_logical_package_id(cpu);
 
 	if (pmu_version >= 2) {
 		ebx.full = cpuid_ebx(EXT_PERFMON_DEBUG_FEATURES);
@@ -654,17 +658,20 @@
 {
 	struct attribute **df_attr = amd_uncore_df_format_attr;
 	struct amd_uncore_pmu *pmu;
+	int num_counters;
 
 	/* Run just once */
 	if (uncore->init_done)
 		return amd_uncore_ctx_init(uncore, cpu);
 
+	num_counters = amd_uncore_ctx_num_pmcs(uncore, cpu);
+	if (!num_counters)
+		goto done;
+
 	/* No grouping, single instance for a system */
 	uncore->pmus = kzalloc(sizeof(*uncore->pmus), GFP_KERNEL);
-	if (!uncore->pmus) {
-		uncore->num_pmus = 0;
+	if (!uncore->pmus)
 		goto done;
-	}
 
 	/*
 	 * For Family 17h and above, the Northbridge counters are repurposed
@@ -674,7 +681,7 @@
 	pmu = &uncore->pmus[0];
 	strscpy(pmu->name, boot_cpu_data.x86 >= 0x17 ? "amd_df" : "amd_nb",
 		sizeof(pmu->name));
-	pmu->num_counters = amd_uncore_ctx_num_pmcs(uncore, cpu);
+	pmu->num_counters = num_counters;
 	pmu->msr_base = MSR_F15H_NB_PERF_CTL;
 	pmu->rdpmc_base = RDPMC_BASE_NB;
 	pmu->group = amd_uncore_ctx_gid(uncore, cpu);
@@ -785,17 +792,20 @@
 {
 	struct attribute **l3_attr = amd_uncore_l3_format_attr;
 	struct amd_uncore_pmu *pmu;
+	int num_counters;
 
 	/* Run just once */
 	if (uncore->init_done)
 		return amd_uncore_ctx_init(uncore, cpu);
 
+	num_counters = amd_uncore_ctx_num_pmcs(uncore, cpu);
+	if (!num_counters)
+		goto done;
+
 	/* No grouping, single instance for a system */
 	uncore->pmus = kzalloc(sizeof(*uncore->pmus), GFP_KERNEL);
-	if (!uncore->pmus) {
-		uncore->num_pmus = 0;
+	if (!uncore->pmus)
 		goto done;
-	}
 
 	/*
 	 * For Family 17h and above, L3 cache counters are available instead
@@ -805,7 +815,7 @@
 	pmu = &uncore->pmus[0];
 	strscpy(pmu->name, boot_cpu_data.x86 >= 0x17 ? "amd_l3" : "amd_l2",
 		sizeof(pmu->name));
-	pmu->num_counters = amd_uncore_ctx_num_pmcs(uncore, cpu);
+	pmu->num_counters = num_counters;
 	pmu->msr_base = MSR_F16H_L2I_PERF_CTL;
 	pmu->rdpmc_base = RDPMC_BASE_LLC;
 	pmu->group = amd_uncore_ctx_gid(uncore, cpu);
@@ -893,8 +903,8 @@
 	cpuid(EXT_PERFMON_DEBUG_FEATURES, &eax, &ebx.full, &ecx, &edx);
 	info.split.aux_data = ecx;	/* stash active mask */
 	info.split.num_pmcs = ebx.split.num_umc_pmc;
-	info.split.gid = topology_die_id(cpu);
-	info.split.cid = topology_die_id(cpu);
+	info.split.gid = topology_logical_package_id(cpu);
+	info.split.cid = topology_logical_package_id(cpu);
 	*per_cpu_ptr(uncore->info, cpu) = info;
 }
 
--- linux-qcom-6.8.0.orig/arch/x86/events/core.c
+++ linux-qcom-6.8.0/arch/x86/events/core.c
@@ -41,6 +41,8 @@
 #include <asm/desc.h>
 #include <asm/ldt.h>
 #include <asm/unwind.h>
+#include <asm/uprobes.h>
+#include <asm/ibt.h>
 
 #include "perf_event.h"
 
@@ -189,29 +191,31 @@
 
 #ifdef CONFIG_X86_LOCAL_APIC
 
-static inline int get_possible_num_counters(void)
+static inline u64 get_possible_counter_mask(void)
 {
-	int i, num_counters = x86_pmu.num_counters;
+	u64 cntr_mask = x86_pmu.cntr_mask64;
+	int i;
 
 	if (!is_hybrid())
-		return num_counters;
+		return cntr_mask;
 
 	for (i = 0; i < x86_pmu.num_hybrid_pmus; i++)
-		num_counters = max_t(int, num_counters, x86_pmu.hybrid_pmu[i].num_counters);
+		cntr_mask |= x86_pmu.hybrid_pmu[i].cntr_mask64;
 
-	return num_counters;
+	return cntr_mask;
 }
 
 static bool reserve_pmc_hardware(void)
 {
-	int i, num_counters = get_possible_num_counters();
+	u64 cntr_mask = get_possible_counter_mask();
+	int i, end;
 
-	for (i = 0; i < num_counters; i++) {
+	for_each_set_bit(i, (unsigned long *)&cntr_mask, X86_PMC_IDX_MAX) {
 		if (!reserve_perfctr_nmi(x86_pmu_event_addr(i)))
 			goto perfctr_fail;
 	}
 
-	for (i = 0; i < num_counters; i++) {
+	for_each_set_bit(i, (unsigned long *)&cntr_mask, X86_PMC_IDX_MAX) {
 		if (!reserve_evntsel_nmi(x86_pmu_config_addr(i)))
 			goto eventsel_fail;
 	}
@@ -219,13 +223,14 @@
 	return true;
 
 eventsel_fail:
-	for (i--; i >= 0; i--)
+	end = i;
+	for_each_set_bit(i, (unsigned long *)&cntr_mask, end)
 		release_evntsel_nmi(x86_pmu_config_addr(i));
-
-	i = num_counters;
+	i = X86_PMC_IDX_MAX;
 
 perfctr_fail:
-	for (i--; i >= 0; i--)
+	end = i;
+	for_each_set_bit(i, (unsigned long *)&cntr_mask, end)
 		release_perfctr_nmi(x86_pmu_event_addr(i));
 
 	return false;
@@ -233,9 +238,10 @@
 
 static void release_pmc_hardware(void)
 {
-	int i, num_counters = get_possible_num_counters();
+	u64 cntr_mask = get_possible_counter_mask();
+	int i;
 
-	for (i = 0; i < num_counters; i++) {
+	for_each_set_bit(i, (unsigned long *)&cntr_mask, X86_PMC_IDX_MAX) {
 		release_perfctr_nmi(x86_pmu_event_addr(i));
 		release_evntsel_nmi(x86_pmu_config_addr(i));
 	}
@@ -248,7 +254,8 @@
 
 #endif
 
-bool check_hw_exists(struct pmu *pmu, int num_counters, int num_counters_fixed)
+bool check_hw_exists(struct pmu *pmu, unsigned long *cntr_mask,
+		     unsigned long *fixed_cntr_mask)
 {
 	u64 val, val_fail = -1, val_new= ~0;
 	int i, reg, reg_fail = -1, ret = 0;
@@ -259,7 +266,7 @@
 	 * Check to see if the BIOS enabled any of the counters, if so
 	 * complain and bail.
 	 */
-	for (i = 0; i < num_counters; i++) {
+	for_each_set_bit(i, cntr_mask, X86_PMC_IDX_MAX) {
 		reg = x86_pmu_config_addr(i);
 		ret = rdmsrl_safe(reg, &val);
 		if (ret)
@@ -273,12 +280,12 @@
 		}
 	}
 
-	if (num_counters_fixed) {
+	if (*(u64 *)fixed_cntr_mask) {
 		reg = MSR_ARCH_PERFMON_FIXED_CTR_CTRL;
 		ret = rdmsrl_safe(reg, &val);
 		if (ret)
 			goto msr_fail;
-		for (i = 0; i < num_counters_fixed; i++) {
+		for_each_set_bit(i, fixed_cntr_mask, X86_PMC_IDX_MAX) {
 			if (fixed_counter_disabled(i, pmu))
 				continue;
 			if (val & (0x03ULL << i*4)) {
@@ -679,7 +686,7 @@
 	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
 	int idx;
 
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+	for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
 		struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
 		u64 val;
 
@@ -736,7 +743,7 @@
 	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
 	int idx;
 
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+	for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
 		struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
 
 		if (!test_bit(idx, cpuc->active_mask))
@@ -975,7 +982,6 @@
 
 int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign)
 {
-	int num_counters = hybrid(cpuc->pmu, num_counters);
 	struct event_constraint *c;
 	struct perf_event *e;
 	int n0, i, wmin, wmax, unsched = 0;
@@ -1051,7 +1057,7 @@
 
 	/* slow path */
 	if (i != n) {
-		int gpmax = num_counters;
+		int gpmax = x86_pmu_max_num_counters(cpuc->pmu);
 
 		/*
 		 * Do not allow scheduling of more than half the available
@@ -1072,7 +1078,7 @@
 		 * the extra Merge events needed by large increment events.
 		 */
 		if (x86_pmu.flags & PMU_FL_PAIR) {
-			gpmax = num_counters - cpuc->n_pair;
+			gpmax -= cpuc->n_pair;
 			WARN_ON(gpmax <= 0);
 		}
 
@@ -1157,12 +1163,10 @@
  */
 static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader, bool dogrp)
 {
-	int num_counters = hybrid(cpuc->pmu, num_counters);
-	int num_counters_fixed = hybrid(cpuc->pmu, num_counters_fixed);
 	struct perf_event *event;
 	int n, max_count;
 
-	max_count = num_counters + num_counters_fixed;
+	max_count = x86_pmu_num_counters(cpuc->pmu) + x86_pmu_num_counters_fixed(cpuc->pmu);
 
 	/* current number of events already accepted */
 	n = cpuc->n_events;
@@ -1519,19 +1523,22 @@
 void perf_event_print_debug(void)
 {
 	u64 ctrl, status, overflow, pmc_ctrl, pmc_count, prev_left, fixed;
+	unsigned long *cntr_mask, *fixed_cntr_mask;
+	struct event_constraint *pebs_constraints;
+	struct cpu_hw_events *cpuc;
 	u64 pebs, debugctl;
-	int cpu = smp_processor_id();
-	struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
-	int num_counters = hybrid(cpuc->pmu, num_counters);
-	int num_counters_fixed = hybrid(cpuc->pmu, num_counters_fixed);
-	struct event_constraint *pebs_constraints = hybrid(cpuc->pmu, pebs_constraints);
-	unsigned long flags;
-	int idx;
+	int cpu, idx;
 
-	if (!num_counters)
-		return;
+	guard(irqsave)();
 
-	local_irq_save(flags);
+	cpu = smp_processor_id();
+	cpuc = &per_cpu(cpu_hw_events, cpu);
+	cntr_mask = hybrid(cpuc->pmu, cntr_mask);
+	fixed_cntr_mask = hybrid(cpuc->pmu, fixed_cntr_mask);
+	pebs_constraints = hybrid(cpuc->pmu, pebs_constraints);
+
+	if (!*(u64 *)cntr_mask)
+		return;
 
 	if (x86_pmu.version >= 2) {
 		rdmsrl(MSR_CORE_PERF_GLOBAL_CTRL, ctrl);
@@ -1555,7 +1562,7 @@
 	}
 	pr_info("CPU#%d: active:     %016llx\n", cpu, *(u64 *)cpuc->active_mask);
 
-	for (idx = 0; idx < num_counters; idx++) {
+	for_each_set_bit(idx, cntr_mask, X86_PMC_IDX_MAX) {
 		rdmsrl(x86_pmu_config_addr(idx), pmc_ctrl);
 		rdmsrl(x86_pmu_event_addr(idx), pmc_count);
 
@@ -1568,7 +1575,7 @@
 		pr_info("CPU#%d:   gen-PMC%d left:  %016llx\n",
 			cpu, idx, prev_left);
 	}
-	for (idx = 0; idx < num_counters_fixed; idx++) {
+	for_each_set_bit(idx, fixed_cntr_mask, X86_PMC_IDX_MAX) {
 		if (fixed_counter_disabled(idx, cpuc->pmu))
 			continue;
 		rdmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, pmc_count);
@@ -1576,7 +1583,6 @@
 		pr_info("CPU#%d: fixed-PMC%d count: %016llx\n",
 			cpu, idx, pmc_count);
 	}
-	local_irq_restore(flags);
 }
 
 void x86_pmu_stop(struct perf_event *event, int flags)
@@ -1644,6 +1650,7 @@
 	while (++i < cpuc->n_events) {
 		cpuc->event_list[i-1] = cpuc->event_list[i];
 		cpuc->event_constraint[i-1] = cpuc->event_constraint[i];
+		cpuc->assign[i-1] = cpuc->assign[i];
 	}
 	cpuc->event_constraint[i-1] = NULL;
 	--cpuc->n_events;
@@ -1681,7 +1688,7 @@
 	 */
 	apic_write(APIC_LVTPC, APIC_DM_NMI);
 
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+	for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
 		if (!test_bit(idx, cpuc->active_mask))
 			continue;
 
@@ -2037,18 +2044,15 @@
 	static_call(x86_pmu_update)(event);
 }
 
-void x86_pmu_show_pmu_cap(int num_counters, int num_counters_fixed,
-			  u64 intel_ctrl)
+void x86_pmu_show_pmu_cap(struct pmu *pmu)
 {
 	pr_info("... version:                %d\n",     x86_pmu.version);
 	pr_info("... bit width:              %d\n",     x86_pmu.cntval_bits);
-	pr_info("... generic registers:      %d\n",     num_counters);
+	pr_info("... generic registers:      %d\n",     x86_pmu_num_counters(pmu));
 	pr_info("... value mask:             %016Lx\n", x86_pmu.cntval_mask);
 	pr_info("... max period:             %016Lx\n", x86_pmu.max_period);
-	pr_info("... fixed-purpose events:   %lu\n",
-			hweight64((((1ULL << num_counters_fixed) - 1)
-					<< INTEL_PMC_IDX_FIXED) & intel_ctrl));
-	pr_info("... event mask:             %016Lx\n", intel_ctrl);
+	pr_info("... fixed-purpose events:   %d\n",     x86_pmu_num_counters_fixed(pmu));
+	pr_info("... event mask:             %016Lx\n", hybrid(pmu, intel_ctrl));
 }
 
 static int __init init_hw_perf_events(void)
@@ -2085,7 +2089,7 @@
 	pmu_check_apic();
 
 	/* sanity check that the hardware exists or is emulated */
-	if (!check_hw_exists(&pmu, x86_pmu.num_counters, x86_pmu.num_counters_fixed))
+	if (!check_hw_exists(&pmu, x86_pmu.cntr_mask, x86_pmu.fixed_cntr_mask))
 		goto out_bad_pmu;
 
 	pr_cont("%s PMU driver.\n", x86_pmu.name);
@@ -2096,14 +2100,14 @@
 		quirk->func();
 
 	if (!x86_pmu.intel_ctrl)
-		x86_pmu.intel_ctrl = (1 << x86_pmu.num_counters) - 1;
+		x86_pmu.intel_ctrl = x86_pmu.cntr_mask64;
 
 	perf_events_lapic_init();
 	register_nmi_handler(NMI_LOCAL, perf_event_nmi_handler, 0, "PMI");
 
 	unconstrained = (struct event_constraint)
-		__EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1,
-				   0, x86_pmu.num_counters, 0, 0);
+		__EVENT_CONSTRAINT(0, x86_pmu.cntr_mask64,
+				   0, x86_pmu_num_counters(NULL), 0, 0);
 
 	x86_pmu_format_group.attrs = x86_pmu.format_attrs;
 
@@ -2112,11 +2116,8 @@
 
 	pmu.attr_update = x86_pmu.attr_update;
 
-	if (!is_hybrid()) {
-		x86_pmu_show_pmu_cap(x86_pmu.num_counters,
-				     x86_pmu.num_counters_fixed,
-				     x86_pmu.intel_ctrl);
-	}
+	if (!is_hybrid())
+		x86_pmu_show_pmu_cap(NULL);
 
 	if (!x86_pmu.read)
 		x86_pmu.read = _x86_pmu_read;
@@ -2480,7 +2481,7 @@
 	for_each_set_bit(i, cpuc->dirty, X86_PMC_IDX_MAX) {
 		if (i >= INTEL_PMC_IDX_FIXED) {
 			/* Metrics and fake events don't have corresponding HW counters. */
-			if ((i - INTEL_PMC_IDX_FIXED) >= hybrid(cpuc->pmu, num_counters_fixed))
+			if (!test_bit(i - INTEL_PMC_IDX_FIXED, hybrid(cpuc->pmu, fixed_cntr_mask)))
 				continue;
 
 			wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + (i - INTEL_PMC_IDX_FIXED), 0);
@@ -2546,6 +2547,7 @@
 			      struct device_attribute *attr,
 			      const char *buf, size_t count)
 {
+	static DEFINE_MUTEX(rdpmc_mutex);
 	unsigned long val;
 	ssize_t ret;
 
@@ -2559,6 +2561,8 @@
 	if (x86_pmu.attr_rdpmc_broken)
 		return -ENOTSUPP;
 
+	guard(mutex)(&rdpmc_mutex);
+
 	if (val != x86_pmu.attr_rdpmc) {
 		/*
 		 * Changing into or out of never available or always available,
@@ -2812,6 +2816,46 @@
 	return get_desc_base(desc);
 }
 
+#ifdef CONFIG_UPROBES
+/*
+ * Heuristic-based check if uprobe is installed at the function entry.
+ *
+ * Under assumption of user code being compiled with frame pointers,
+ * `push %rbp/%ebp` is a good indicator that we indeed are.
+ *
+ * Similarly, `endbr64` (assuming 64-bit mode) is also a common pattern.
+ * If we get this wrong, captured stack trace might have one extra bogus
+ * entry, but the rest of stack trace will still be meaningful.
+ */
+static bool is_uprobe_at_func_entry(struct pt_regs *regs)
+{
+	struct arch_uprobe *auprobe;
+
+	if (!current->utask)
+		return false;
+
+	auprobe = current->utask->auprobe;
+	if (!auprobe)
+		return false;
+
+	/* push %rbp/%ebp */
+	if (auprobe->insn[0] == 0x55)
+		return true;
+
+	/* endbr64 (64-bit only) */
+	if (user_64bit_mode(regs) && is_endbr(*(u32 *)auprobe->insn))
+		return true;
+
+	return false;
+}
+
+#else
+static bool is_uprobe_at_func_entry(struct pt_regs *regs)
+{
+	return false;
+}
+#endif /* CONFIG_UPROBES */
+
 #ifdef CONFIG_IA32_EMULATION
 
 #include <linux/compat.h>
@@ -2823,6 +2867,7 @@
 	unsigned long ss_base, cs_base;
 	struct stack_frame_ia32 frame;
 	const struct stack_frame_ia32 __user *fp;
+	u32 ret_addr;
 
 	if (user_64bit_mode(regs))
 		return 0;
@@ -2832,6 +2877,12 @@
 
 	fp = compat_ptr(ss_base + regs->bp);
 	pagefault_disable();
+
+	/* see perf_callchain_user() below for why we do this */
+	if (is_uprobe_at_func_entry(regs) &&
+	    !get_user(ret_addr, (const u32 __user *)regs->sp))
+		perf_callchain_store(entry, ret_addr);
+
 	while (entry->nr < entry->max_stack) {
 		if (!valid_user_frame(fp, sizeof(frame)))
 			break;
@@ -2860,6 +2911,7 @@
 {
 	struct stack_frame frame;
 	const struct stack_frame __user *fp;
+	unsigned long ret_addr;
 
 	if (perf_guest_state()) {
 		/* TODO: We don't support guest os callchain now */
@@ -2883,6 +2935,19 @@
 		return;
 
 	pagefault_disable();
+
+	/*
+	 * If we are called from uprobe handler, and we are indeed at the very
+	 * entry to user function (which is normally a `push %rbp` instruction,
+	 * under assumption of application being compiled with frame pointers),
+	 * we should read return address from *regs->sp before proceeding
+	 * to follow frame pointers, otherwise we'll skip immediate caller
+	 * as %rbp is not yet setup.
+	 */
+	if (is_uprobe_at_func_entry(regs) &&
+	    !get_user(ret_addr, (const unsigned long __user *)regs->sp))
+		perf_callchain_store(entry, ret_addr);
+
 	while (entry->nr < entry->max_stack) {
 		if (!valid_user_frame(fp, sizeof(frame)))
 			break;
@@ -2982,8 +3047,8 @@
 	 * base PMU holds the correct number of counters for P-cores.
 	 */
 	cap->version		= x86_pmu.version;
-	cap->num_counters_gp	= x86_pmu.num_counters;
-	cap->num_counters_fixed	= x86_pmu.num_counters_fixed;
+	cap->num_counters_gp	= x86_pmu_num_counters(NULL);
+	cap->num_counters_fixed	= x86_pmu_num_counters_fixed(NULL);
 	cap->bit_width_gp	= x86_pmu.cntval_bits;
 	cap->bit_width_fixed	= x86_pmu.cntval_bits;
 	cap->events_mask	= (unsigned int)x86_pmu.events_maskl;
--- linux-qcom-6.8.0.orig/arch/x86/events/intel/core.c
+++ linux-qcom-6.8.0/arch/x86/events/intel/core.c
@@ -2873,23 +2873,23 @@
 {
 	struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
 	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	int num_counters_fixed = hybrid(cpuc->pmu, num_counters_fixed);
-	int num_counters = hybrid(cpuc->pmu, num_counters);
+	unsigned long *cntr_mask = hybrid(cpuc->pmu, cntr_mask);
+	unsigned long *fixed_cntr_mask = hybrid(cpuc->pmu, fixed_cntr_mask);
 	unsigned long flags;
 	int idx;
 
-	if (!num_counters)
+	if (!*(u64 *)cntr_mask)
 		return;
 
 	local_irq_save(flags);
 
 	pr_info("clearing PMU state on CPU#%d\n", smp_processor_id());
 
-	for (idx = 0; idx < num_counters; idx++) {
+	for_each_set_bit(idx, cntr_mask, INTEL_PMC_MAX_GENERIC) {
 		wrmsrl_safe(x86_pmu_config_addr(idx), 0ull);
 		wrmsrl_safe(x86_pmu_event_addr(idx),  0ull);
 	}
-	for (idx = 0; idx < num_counters_fixed; idx++) {
+	for_each_set_bit(idx, fixed_cntr_mask, INTEL_PMC_MAX_FIXED) {
 		if (fixed_counter_disabled(idx, cpuc->pmu))
 			continue;
 		wrmsrl_safe(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
@@ -2939,8 +2939,7 @@
 	    !guest_pebs_idxs)
 		return;
 
-	for_each_set_bit(bit, (unsigned long *)&guest_pebs_idxs,
-			 INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed) {
+	for_each_set_bit(bit, (unsigned long *)&guest_pebs_idxs, X86_PMC_IDX_MAX) {
 		event = cpuc->events[bit];
 		if (!event->attr.precise_ip)
 			continue;
@@ -3912,8 +3911,12 @@
 			x86_pmu.pebs_aliases(event);
 	}
 
-	if (needs_branch_stack(event) && is_sampling_event(event))
-		event->hw.flags  |= PERF_X86_EVENT_NEEDS_BRANCH_STACK;
+	if (needs_branch_stack(event)) {
+		/* Avoid branch stack setup for counting events in SAMPLE READ */
+		if (is_sampling_event(event) ||
+		    !(event->attr.sample_type & PERF_SAMPLE_READ))
+			event->hw.flags |= PERF_X86_EVENT_NEEDS_BRANCH_STACK;
+	}
 
 	if (branch_sample_counters(event)) {
 		struct perf_event *leader, *sibling;
@@ -4198,7 +4201,7 @@
 	struct perf_guest_switch_msr *arr = cpuc->guest_switch_msrs;
 	int idx;
 
-	for (idx = 0; idx < x86_pmu.num_counters; idx++)  {
+	for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
 		struct perf_event *event = cpuc->events[idx];
 
 		arr[idx].msr = x86_pmu_config_addr(idx);
@@ -4216,7 +4219,7 @@
 			arr[idx].guest &= ~ARCH_PERFMON_EVENTSEL_ENABLE;
 	}
 
-	*nr = x86_pmu.num_counters;
+	*nr = x86_pmu_max_num_counters(cpuc->pmu);
 	return arr;
 }
 
@@ -4231,7 +4234,7 @@
 	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
 	int idx;
 
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+	for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
 		struct hw_perf_event *hwc = &cpuc->events[idx]->hw;
 
 		if (!test_bit(idx, cpuc->active_mask) ||
@@ -4529,6 +4532,25 @@
 	return HYBRID_INTEL_CORE;
 }
 
+static inline bool erratum_hsw11(struct perf_event *event)
+{
+	return (event->hw.config & INTEL_ARCH_EVENT_MASK) ==
+		X86_CONFIG(.event=0xc0, .umask=0x01);
+}
+
+/*
+ * The HSW11 requires a period larger than 100 which is the same as the BDM11.
+ * A minimum period of 128 is enforced as well for the INST_RETIRED.ALL.
+ *
+ * The message 'interrupt took too long' can be observed on any counter which
+ * was armed with a period < 32 and two events expired in the same NMI.
+ * A minimum period of 32 is enforced for the rest of the events.
+ */
+static void hsw_limit_period(struct perf_event *event, s64 *left)
+{
+	*left = max(*left, erratum_hsw11(event) ? 128 : 32);
+}
+
 /*
  * Broadwell:
  *
@@ -4546,8 +4568,7 @@
  */
 static void bdw_limit_period(struct perf_event *event, s64 *left)
 {
-	if ((event->hw.config & INTEL_ARCH_EVENT_MASK) ==
-			X86_CONFIG(.event=0xc0, .umask=0x01)) {
+	if (erratum_hsw11(event)) {
 		if (*left < 128)
 			*left = 128;
 		*left &= ~0x3fULL;
@@ -4683,13 +4704,33 @@
 	}
 }
 
-static void intel_pmu_check_num_counters(int *num_counters,
-					 int *num_counters_fixed,
-					 u64 *intel_ctrl, u64 fixed_mask);
+static void intel_pmu_check_counters_mask(u64 *cntr_mask,
+					  u64 *fixed_cntr_mask,
+					  u64 *intel_ctrl)
+{
+	unsigned int bit;
+
+	bit = fls64(*cntr_mask);
+	if (bit > INTEL_PMC_MAX_GENERIC) {
+		WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
+		     bit, INTEL_PMC_MAX_GENERIC);
+		*cntr_mask &= GENMASK_ULL(INTEL_PMC_MAX_GENERIC - 1, 0);
+	}
+	*intel_ctrl = *cntr_mask;
+
+	bit = fls64(*fixed_cntr_mask);
+	if (bit > INTEL_PMC_MAX_FIXED) {
+		WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
+		     bit, INTEL_PMC_MAX_FIXED);
+		*fixed_cntr_mask &= GENMASK_ULL(INTEL_PMC_MAX_FIXED - 1, 0);
+	}
+
+	*intel_ctrl |= *fixed_cntr_mask << INTEL_PMC_IDX_FIXED;
+}
 
 static void intel_pmu_check_event_constraints(struct event_constraint *event_constraints,
-					      int num_counters,
-					      int num_counters_fixed,
+					      u64 cntr_mask,
+					      u64 fixed_cntr_mask,
 					      u64 intel_ctrl);
 
 static void intel_pmu_check_extra_regs(struct extra_reg *extra_regs);
@@ -4697,8 +4738,8 @@
 static inline bool intel_pmu_broken_perf_cap(void)
 {
 	/* The Perf Metric (Bit 15) is always cleared */
-	if ((boot_cpu_data.x86_model == INTEL_FAM6_METEORLAKE) ||
-	    (boot_cpu_data.x86_model == INTEL_FAM6_METEORLAKE_L))
+	if (boot_cpu_data.x86_vfm == INTEL_METEORLAKE ||
+	    boot_cpu_data.x86_vfm == INTEL_METEORLAKE_L)
 		return true;
 
 	return false;
@@ -4712,11 +4753,10 @@
 	if (sub_bitmaps & ARCH_PERFMON_NUM_COUNTER_LEAF_BIT) {
 		cpuid_count(ARCH_PERFMON_EXT_LEAF, ARCH_PERFMON_NUM_COUNTER_LEAF,
 			    &eax, &ebx, &ecx, &edx);
-		pmu->num_counters = fls(eax);
-		pmu->num_counters_fixed = fls(ebx);
+		pmu->cntr_mask64 = eax;
+		pmu->fixed_cntr_mask64 = ebx;
 	}
 
-
 	if (!intel_pmu_broken_perf_cap()) {
 		/* Perf Metric (Bit 15) and PEBS via PT (Bit 16) are hybrid enumeration */
 		rdmsrl(MSR_IA32_PERF_CAPABILITIES, pmu->intel_cap.capabilities);
@@ -4725,12 +4765,12 @@
 
 static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu)
 {
-	intel_pmu_check_num_counters(&pmu->num_counters, &pmu->num_counters_fixed,
-				     &pmu->intel_ctrl, (1ULL << pmu->num_counters_fixed) - 1);
-	pmu->max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, pmu->num_counters);
+	intel_pmu_check_counters_mask(&pmu->cntr_mask64, &pmu->fixed_cntr_mask64,
+				      &pmu->intel_ctrl);
+	pmu->pebs_events_mask = intel_pmu_pebs_mask(pmu->cntr_mask64);
 	pmu->unconstrained = (struct event_constraint)
-			     __EVENT_CONSTRAINT(0, (1ULL << pmu->num_counters) - 1,
-						0, pmu->num_counters, 0, 0);
+			     __EVENT_CONSTRAINT(0, pmu->cntr_mask64,
+						0, x86_pmu_num_counters(&pmu->pmu), 0, 0);
 
 	if (pmu->intel_cap.perf_metrics)
 		pmu->intel_ctrl |= 1ULL << GLOBAL_CTRL_EN_PERF_METRICS;
@@ -4743,8 +4783,8 @@
 		pmu->pmu.capabilities &= ~PERF_PMU_CAP_AUX_OUTPUT;
 
 	intel_pmu_check_event_constraints(pmu->event_constraints,
-					  pmu->num_counters,
-					  pmu->num_counters_fixed,
+					  pmu->cntr_mask64,
+					  pmu->fixed_cntr_mask64,
 					  pmu->intel_ctrl);
 
 	intel_pmu_check_extra_regs(pmu->extra_regs);
@@ -4805,7 +4845,7 @@
 
 	intel_pmu_check_hybrid_pmus(pmu);
 
-	if (!check_hw_exists(&pmu->pmu, pmu->num_counters, pmu->num_counters_fixed))
+	if (!check_hw_exists(&pmu->pmu, pmu->cntr_mask, pmu->fixed_cntr_mask))
 		return false;
 
 	pr_info("%s PMU driver: ", pmu->name);
@@ -4815,8 +4855,7 @@
 
 	pr_cont("\n");
 
-	x86_pmu_show_pmu_cap(pmu->num_counters, pmu->num_counters_fixed,
-			     pmu->intel_ctrl);
+	x86_pmu_show_pmu_cap(&pmu->pmu);
 
 end:
 	cpumask_set_cpu(cpu, &pmu->supported_cpus);
@@ -5704,8 +5743,22 @@
 	return x86_pmu.version >= 2 ? attr->mode : 0;
 }
 
+static umode_t
+td_is_visible(struct kobject *kobj, struct attribute *attr, int i)
+{
+	/*
+	 * Hide the perf metrics topdown events
+	 * if the feature is not enumerated.
+	 */
+	if (x86_pmu.num_topdown_events)
+		return x86_pmu.intel_cap.perf_metrics ? attr->mode : 0;
+
+	return attr->mode;
+}
+
 static struct attribute_group group_events_td  = {
 	.name = "events",
+	.is_visible = td_is_visible,
 };
 
 static struct attribute_group group_events_mem = {
@@ -5907,9 +5960,27 @@
 	return (cpu >= 0) && (pmu->pmu_type & pmu_attr->pmu_type) ? attr->mode : 0;
 }
 
+static umode_t hybrid_td_is_visible(struct kobject *kobj,
+				    struct attribute *attr, int i)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct x86_hybrid_pmu *pmu =
+		 container_of(dev_get_drvdata(dev), struct x86_hybrid_pmu, pmu);
+
+	if (!is_attr_for_this_pmu(kobj, attr))
+		return 0;
+
+
+	/* Only the big core supports perf metrics */
+	if (pmu->pmu_type == hybrid_big)
+		return pmu->intel_cap.perf_metrics ? attr->mode : 0;
+
+	return attr->mode;
+}
+
 static struct attribute_group hybrid_group_events_td  = {
 	.name		= "events",
-	.is_visible	= hybrid_events_is_visible,
+	.is_visible	= hybrid_td_is_visible,
 };
 
 static struct attribute_group hybrid_group_events_mem = {
@@ -5961,29 +6032,9 @@
 
 static struct attribute *empty_attrs;
 
-static void intel_pmu_check_num_counters(int *num_counters,
-					 int *num_counters_fixed,
-					 u64 *intel_ctrl, u64 fixed_mask)
-{
-	if (*num_counters > INTEL_PMC_MAX_GENERIC) {
-		WARN(1, KERN_ERR "hw perf events %d > max(%d), clipping!",
-		     *num_counters, INTEL_PMC_MAX_GENERIC);
-		*num_counters = INTEL_PMC_MAX_GENERIC;
-	}
-	*intel_ctrl = (1ULL << *num_counters) - 1;
-
-	if (*num_counters_fixed > INTEL_PMC_MAX_FIXED) {
-		WARN(1, KERN_ERR "hw perf events fixed %d > max(%d), clipping!",
-		     *num_counters_fixed, INTEL_PMC_MAX_FIXED);
-		*num_counters_fixed = INTEL_PMC_MAX_FIXED;
-	}
-
-	*intel_ctrl |= fixed_mask << INTEL_PMC_IDX_FIXED;
-}
-
 static void intel_pmu_check_event_constraints(struct event_constraint *event_constraints,
-					      int num_counters,
-					      int num_counters_fixed,
+					      u64 cntr_mask,
+					      u64 fixed_cntr_mask,
 					      u64 intel_ctrl)
 {
 	struct event_constraint *c;
@@ -6020,10 +6071,9 @@
 			 * generic counters
 			 */
 			if (!use_fixed_pseudo_encoding(c->code))
-				c->idxmsk64 |= (1ULL << num_counters) - 1;
+				c->idxmsk64 |= cntr_mask;
 		}
-		c->idxmsk64 &=
-			~(~0ULL << (INTEL_PMC_IDX_FIXED + num_counters_fixed));
+		c->idxmsk64 &= cntr_mask | (fixed_cntr_mask << INTEL_PMC_IDX_FIXED);
 		c->weight = hweight64(c->idxmsk64);
 	}
 }
@@ -6074,12 +6124,12 @@
 		pmu->pmu_type = intel_hybrid_pmu_type_map[bit].id;
 		pmu->name = intel_hybrid_pmu_type_map[bit].name;
 
-		pmu->num_counters = x86_pmu.num_counters;
-		pmu->num_counters_fixed = x86_pmu.num_counters_fixed;
-		pmu->max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, pmu->num_counters);
+		pmu->cntr_mask64 = x86_pmu.cntr_mask64;
+		pmu->fixed_cntr_mask64 = x86_pmu.fixed_cntr_mask64;
+		pmu->pebs_events_mask = intel_pmu_pebs_mask(pmu->cntr_mask64);
 		pmu->unconstrained = (struct event_constraint)
-				     __EVENT_CONSTRAINT(0, (1ULL << pmu->num_counters) - 1,
-							0, pmu->num_counters, 0, 0);
+				     __EVENT_CONSTRAINT(0, pmu->cntr_mask64,
+							0, x86_pmu_num_counters(&pmu->pmu), 0, 0);
 
 		pmu->intel_cap.capabilities = x86_pmu.intel_cap.capabilities;
 		if (pmu->pmu_type & hybrid_small) {
@@ -6192,14 +6242,14 @@
 		x86_pmu = intel_pmu;
 
 	x86_pmu.version			= version;
-	x86_pmu.num_counters		= eax.split.num_counters;
+	x86_pmu.cntr_mask64		= GENMASK_ULL(eax.split.num_counters - 1, 0);
 	x86_pmu.cntval_bits		= eax.split.bit_width;
 	x86_pmu.cntval_mask		= (1ULL << eax.split.bit_width) - 1;
 
 	x86_pmu.events_maskl		= ebx.full;
 	x86_pmu.events_mask_len		= eax.split.mask_length;
 
-	x86_pmu.max_pebs_events		= min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters);
+	x86_pmu.pebs_events_mask	= intel_pmu_pebs_mask(x86_pmu.cntr_mask64);
 	x86_pmu.pebs_capable		= PEBS_COUNTER_MASK;
 
 	/*
@@ -6209,12 +6259,10 @@
 	if (version > 1 && version < 5) {
 		int assume = 3 * !boot_cpu_has(X86_FEATURE_HYPERVISOR);
 
-		x86_pmu.num_counters_fixed =
-			max((int)edx.split.num_counters_fixed, assume);
-
-		fixed_mask = (1L << x86_pmu.num_counters_fixed) - 1;
+		x86_pmu.fixed_cntr_mask64 =
+			GENMASK_ULL(max((int)edx.split.num_counters_fixed, assume) - 1, 0);
 	} else if (version >= 5)
-		x86_pmu.num_counters_fixed = fls(fixed_mask);
+		x86_pmu.fixed_cntr_mask64 = fixed_mask;
 
 	if (boot_cpu_has(X86_FEATURE_PDCM)) {
 		u64 capabilities;
@@ -6244,19 +6292,19 @@
 	/*
 	 * Install the hw-cache-events table:
 	 */
-	switch (boot_cpu_data.x86_model) {
-	case INTEL_FAM6_CORE_YONAH:
+	switch (boot_cpu_data.x86_vfm) {
+	case INTEL_CORE_YONAH:
 		pr_cont("Core events, ");
 		name = "core";
 		break;
 
-	case INTEL_FAM6_CORE2_MEROM:
+	case INTEL_CORE2_MEROM:
 		x86_add_quirk(intel_clovertown_quirk);
 		fallthrough;
 
-	case INTEL_FAM6_CORE2_MEROM_L:
-	case INTEL_FAM6_CORE2_PENRYN:
-	case INTEL_FAM6_CORE2_DUNNINGTON:
+	case INTEL_CORE2_MEROM_L:
+	case INTEL_CORE2_PENRYN:
+	case INTEL_CORE2_DUNNINGTON:
 		memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
 		       sizeof(hw_cache_event_ids));
 
@@ -6268,9 +6316,9 @@
 		name = "core2";
 		break;
 
-	case INTEL_FAM6_NEHALEM:
-	case INTEL_FAM6_NEHALEM_EP:
-	case INTEL_FAM6_NEHALEM_EX:
+	case INTEL_NEHALEM:
+	case INTEL_NEHALEM_EP:
+	case INTEL_NEHALEM_EX:
 		memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
 		       sizeof(hw_cache_event_ids));
 		memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
@@ -6302,11 +6350,11 @@
 		name = "nehalem";
 		break;
 
-	case INTEL_FAM6_ATOM_BONNELL:
-	case INTEL_FAM6_ATOM_BONNELL_MID:
-	case INTEL_FAM6_ATOM_SALTWELL:
-	case INTEL_FAM6_ATOM_SALTWELL_MID:
-	case INTEL_FAM6_ATOM_SALTWELL_TABLET:
+	case INTEL_ATOM_BONNELL:
+	case INTEL_ATOM_BONNELL_MID:
+	case INTEL_ATOM_SALTWELL:
+	case INTEL_ATOM_SALTWELL_MID:
+	case INTEL_ATOM_SALTWELL_TABLET:
 		memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
 		       sizeof(hw_cache_event_ids));
 
@@ -6319,11 +6367,11 @@
 		name = "bonnell";
 		break;
 
-	case INTEL_FAM6_ATOM_SILVERMONT:
-	case INTEL_FAM6_ATOM_SILVERMONT_D:
-	case INTEL_FAM6_ATOM_SILVERMONT_MID:
-	case INTEL_FAM6_ATOM_AIRMONT:
-	case INTEL_FAM6_ATOM_AIRMONT_MID:
+	case INTEL_ATOM_SILVERMONT:
+	case INTEL_ATOM_SILVERMONT_D:
+	case INTEL_ATOM_SILVERMONT_MID:
+	case INTEL_ATOM_AIRMONT:
+	case INTEL_ATOM_AIRMONT_MID:
 		memcpy(hw_cache_event_ids, slm_hw_cache_event_ids,
 			sizeof(hw_cache_event_ids));
 		memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
@@ -6341,8 +6389,8 @@
 		name = "silvermont";
 		break;
 
-	case INTEL_FAM6_ATOM_GOLDMONT:
-	case INTEL_FAM6_ATOM_GOLDMONT_D:
+	case INTEL_ATOM_GOLDMONT:
+	case INTEL_ATOM_GOLDMONT_D:
 		memcpy(hw_cache_event_ids, glm_hw_cache_event_ids,
 		       sizeof(hw_cache_event_ids));
 		memcpy(hw_cache_extra_regs, glm_hw_cache_extra_regs,
@@ -6368,7 +6416,7 @@
 		name = "goldmont";
 		break;
 
-	case INTEL_FAM6_ATOM_GOLDMONT_PLUS:
+	case INTEL_ATOM_GOLDMONT_PLUS:
 		memcpy(hw_cache_event_ids, glp_hw_cache_event_ids,
 		       sizeof(hw_cache_event_ids));
 		memcpy(hw_cache_extra_regs, glp_hw_cache_extra_regs,
@@ -6397,9 +6445,9 @@
 		name = "goldmont_plus";
 		break;
 
-	case INTEL_FAM6_ATOM_TREMONT_D:
-	case INTEL_FAM6_ATOM_TREMONT:
-	case INTEL_FAM6_ATOM_TREMONT_L:
+	case INTEL_ATOM_TREMONT_D:
+	case INTEL_ATOM_TREMONT:
+	case INTEL_ATOM_TREMONT_L:
 		x86_pmu.late_ack = true;
 		memcpy(hw_cache_event_ids, glp_hw_cache_event_ids,
 		       sizeof(hw_cache_event_ids));
@@ -6426,7 +6474,7 @@
 		name = "Tremont";
 		break;
 
-	case INTEL_FAM6_ATOM_GRACEMONT:
+	case INTEL_ATOM_GRACEMONT:
 		intel_pmu_init_grt(NULL);
 		intel_pmu_pebs_data_source_grt();
 		x86_pmu.pebs_latency_data = adl_latency_data_small;
@@ -6438,8 +6486,8 @@
 		name = "gracemont";
 		break;
 
-	case INTEL_FAM6_ATOM_CRESTMONT:
-	case INTEL_FAM6_ATOM_CRESTMONT_X:
+	case INTEL_ATOM_CRESTMONT:
+	case INTEL_ATOM_CRESTMONT_X:
 		intel_pmu_init_grt(NULL);
 		x86_pmu.extra_regs = intel_cmt_extra_regs;
 		intel_pmu_pebs_data_source_cmt();
@@ -6452,9 +6500,9 @@
 		name = "crestmont";
 		break;
 
-	case INTEL_FAM6_WESTMERE:
-	case INTEL_FAM6_WESTMERE_EP:
-	case INTEL_FAM6_WESTMERE_EX:
+	case INTEL_WESTMERE:
+	case INTEL_WESTMERE_EP:
+	case INTEL_WESTMERE_EX:
 		memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids,
 		       sizeof(hw_cache_event_ids));
 		memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
@@ -6483,8 +6531,8 @@
 		name = "westmere";
 		break;
 
-	case INTEL_FAM6_SANDYBRIDGE:
-	case INTEL_FAM6_SANDYBRIDGE_X:
+	case INTEL_SANDYBRIDGE:
+	case INTEL_SANDYBRIDGE_X:
 		x86_add_quirk(intel_sandybridge_quirk);
 		x86_add_quirk(intel_ht_bug);
 		memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
@@ -6497,7 +6545,7 @@
 		x86_pmu.event_constraints = intel_snb_event_constraints;
 		x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints;
 		x86_pmu.pebs_aliases = intel_pebs_aliases_snb;
-		if (boot_cpu_data.x86_model == INTEL_FAM6_SANDYBRIDGE_X)
+		if (boot_cpu_data.x86_vfm == INTEL_SANDYBRIDGE_X)
 			x86_pmu.extra_regs = intel_snbep_extra_regs;
 		else
 			x86_pmu.extra_regs = intel_snb_extra_regs;
@@ -6523,8 +6571,8 @@
 		name = "sandybridge";
 		break;
 
-	case INTEL_FAM6_IVYBRIDGE:
-	case INTEL_FAM6_IVYBRIDGE_X:
+	case INTEL_IVYBRIDGE:
+	case INTEL_IVYBRIDGE_X:
 		x86_add_quirk(intel_ht_bug);
 		memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
 		       sizeof(hw_cache_event_ids));
@@ -6540,7 +6588,7 @@
 		x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints;
 		x86_pmu.pebs_aliases = intel_pebs_aliases_ivb;
 		x86_pmu.pebs_prec_dist = true;
-		if (boot_cpu_data.x86_model == INTEL_FAM6_IVYBRIDGE_X)
+		if (boot_cpu_data.x86_vfm == INTEL_IVYBRIDGE_X)
 			x86_pmu.extra_regs = intel_snbep_extra_regs;
 		else
 			x86_pmu.extra_regs = intel_snb_extra_regs;
@@ -6562,10 +6610,10 @@
 		break;
 
 
-	case INTEL_FAM6_HASWELL:
-	case INTEL_FAM6_HASWELL_X:
-	case INTEL_FAM6_HASWELL_L:
-	case INTEL_FAM6_HASWELL_G:
+	case INTEL_HASWELL:
+	case INTEL_HASWELL_X:
+	case INTEL_HASWELL_L:
+	case INTEL_HASWELL_G:
 		x86_add_quirk(intel_ht_bug);
 		x86_add_quirk(intel_pebs_isolation_quirk);
 		x86_pmu.late_ack = true;
@@ -6585,6 +6633,7 @@
 
 		x86_pmu.hw_config = hsw_hw_config;
 		x86_pmu.get_event_constraints = hsw_get_event_constraints;
+		x86_pmu.limit_period = hsw_limit_period;
 		x86_pmu.lbr_double_abort = true;
 		extra_attr = boot_cpu_has(X86_FEATURE_RTM) ?
 			hsw_format_attr : nhm_format_attr;
@@ -6595,10 +6644,10 @@
 		name = "haswell";
 		break;
 
-	case INTEL_FAM6_BROADWELL:
-	case INTEL_FAM6_BROADWELL_D:
-	case INTEL_FAM6_BROADWELL_G:
-	case INTEL_FAM6_BROADWELL_X:
+	case INTEL_BROADWELL:
+	case INTEL_BROADWELL_D:
+	case INTEL_BROADWELL_G:
+	case INTEL_BROADWELL_X:
 		x86_add_quirk(intel_pebs_isolation_quirk);
 		x86_pmu.late_ack = true;
 		memcpy(hw_cache_event_ids, hsw_hw_cache_event_ids, sizeof(hw_cache_event_ids));
@@ -6637,8 +6686,8 @@
 		name = "broadwell";
 		break;
 
-	case INTEL_FAM6_XEON_PHI_KNL:
-	case INTEL_FAM6_XEON_PHI_KNM:
+	case INTEL_XEON_PHI_KNL:
+	case INTEL_XEON_PHI_KNM:
 		memcpy(hw_cache_event_ids,
 		       slm_hw_cache_event_ids, sizeof(hw_cache_event_ids));
 		memcpy(hw_cache_extra_regs,
@@ -6657,15 +6706,15 @@
 		name = "knights-landing";
 		break;
 
-	case INTEL_FAM6_SKYLAKE_X:
+	case INTEL_SKYLAKE_X:
 		pmem = true;
 		fallthrough;
-	case INTEL_FAM6_SKYLAKE_L:
-	case INTEL_FAM6_SKYLAKE:
-	case INTEL_FAM6_KABYLAKE_L:
-	case INTEL_FAM6_KABYLAKE:
-	case INTEL_FAM6_COMETLAKE_L:
-	case INTEL_FAM6_COMETLAKE:
+	case INTEL_SKYLAKE_L:
+	case INTEL_SKYLAKE:
+	case INTEL_KABYLAKE_L:
+	case INTEL_KABYLAKE:
+	case INTEL_COMETLAKE_L:
+	case INTEL_COMETLAKE:
 		x86_add_quirk(intel_pebs_isolation_quirk);
 		x86_pmu.late_ack = true;
 		memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
@@ -6714,16 +6763,16 @@
 		name = "skylake";
 		break;
 
-	case INTEL_FAM6_ICELAKE_X:
-	case INTEL_FAM6_ICELAKE_D:
+	case INTEL_ICELAKE_X:
+	case INTEL_ICELAKE_D:
 		x86_pmu.pebs_ept = 1;
 		pmem = true;
 		fallthrough;
-	case INTEL_FAM6_ICELAKE_L:
-	case INTEL_FAM6_ICELAKE:
-	case INTEL_FAM6_TIGERLAKE_L:
-	case INTEL_FAM6_TIGERLAKE:
-	case INTEL_FAM6_ROCKETLAKE:
+	case INTEL_ICELAKE_L:
+	case INTEL_ICELAKE:
+	case INTEL_TIGERLAKE_L:
+	case INTEL_TIGERLAKE:
+	case INTEL_ROCKETLAKE:
 		x86_pmu.late_ack = true;
 		memcpy(hw_cache_event_ids, skl_hw_cache_event_ids, sizeof(hw_cache_event_ids));
 		memcpy(hw_cache_extra_regs, skl_hw_cache_extra_regs, sizeof(hw_cache_extra_regs));
@@ -6758,16 +6807,22 @@
 		name = "icelake";
 		break;
 
-	case INTEL_FAM6_SAPPHIRERAPIDS_X:
-	case INTEL_FAM6_EMERALDRAPIDS_X:
+	case INTEL_SAPPHIRERAPIDS_X:
+	case INTEL_EMERALDRAPIDS_X:
 		x86_pmu.flags |= PMU_FL_MEM_LOADS_AUX;
 		x86_pmu.extra_regs = intel_glc_extra_regs;
-		fallthrough;
-	case INTEL_FAM6_GRANITERAPIDS_X:
-	case INTEL_FAM6_GRANITERAPIDS_D:
+		pr_cont("Sapphire Rapids events, ");
+		name = "sapphire_rapids";
+		goto glc_common;
+
+	case INTEL_GRANITERAPIDS_X:
+	case INTEL_GRANITERAPIDS_D:
+		x86_pmu.extra_regs = intel_rwc_extra_regs;
+		pr_cont("Granite Rapids events, ");
+		name = "granite_rapids";
+
+	glc_common:
 		intel_pmu_init_glc(NULL);
-		if (!x86_pmu.extra_regs)
-			x86_pmu.extra_regs = intel_rwc_extra_regs;
 		x86_pmu.pebs_ept = 1;
 		x86_pmu.hw_config = hsw_hw_config;
 		x86_pmu.get_event_constraints = glc_get_event_constraints;
@@ -6778,15 +6833,13 @@
 		td_attr = glc_td_events_attrs;
 		tsx_attr = glc_tsx_events_attrs;
 		intel_pmu_pebs_data_source_skl(true);
-		pr_cont("Sapphire Rapids events, ");
-		name = "sapphire_rapids";
 		break;
 
-	case INTEL_FAM6_ALDERLAKE:
-	case INTEL_FAM6_ALDERLAKE_L:
-	case INTEL_FAM6_RAPTORLAKE:
-	case INTEL_FAM6_RAPTORLAKE_P:
-	case INTEL_FAM6_RAPTORLAKE_S:
+	case INTEL_ALDERLAKE:
+	case INTEL_ALDERLAKE_L:
+	case INTEL_RAPTORLAKE:
+	case INTEL_RAPTORLAKE_P:
+	case INTEL_RAPTORLAKE_S:
 		/*
 		 * Alder Lake has 2 types of CPU, core and atom.
 		 *
@@ -6809,11 +6862,13 @@
 		pmu = &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX];
 		intel_pmu_init_glc(&pmu->pmu);
 		if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU)) {
-			pmu->num_counters = x86_pmu.num_counters + 2;
-			pmu->num_counters_fixed = x86_pmu.num_counters_fixed + 1;
+			pmu->cntr_mask64 <<= 2;
+			pmu->cntr_mask64 |= 0x3;
+			pmu->fixed_cntr_mask64 <<= 1;
+			pmu->fixed_cntr_mask64 |= 0x1;
 		} else {
-			pmu->num_counters = x86_pmu.num_counters;
-			pmu->num_counters_fixed = x86_pmu.num_counters_fixed;
+			pmu->cntr_mask64 = x86_pmu.cntr_mask64;
+			pmu->fixed_cntr_mask64 = x86_pmu.fixed_cntr_mask64;
 		}
 
 		/*
@@ -6823,15 +6878,16 @@
 		 * mistakenly add extra counters for P-cores. Correct the number of
 		 * counters here.
 		 */
-		if ((pmu->num_counters > 8) || (pmu->num_counters_fixed > 4)) {
-			pmu->num_counters = x86_pmu.num_counters;
-			pmu->num_counters_fixed = x86_pmu.num_counters_fixed;
+		if ((x86_pmu_num_counters(&pmu->pmu) > 8) || (x86_pmu_num_counters_fixed(&pmu->pmu) > 4)) {
+			pmu->cntr_mask64 = x86_pmu.cntr_mask64;
+			pmu->fixed_cntr_mask64 = x86_pmu.fixed_cntr_mask64;
 		}
 
-		pmu->max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, pmu->num_counters);
+		pmu->pebs_events_mask = intel_pmu_pebs_mask(pmu->cntr_mask64);
 		pmu->unconstrained = (struct event_constraint)
-					__EVENT_CONSTRAINT(0, (1ULL << pmu->num_counters) - 1,
-							   0, pmu->num_counters, 0, 0);
+				     __EVENT_CONSTRAINT(0, pmu->cntr_mask64,
+				     0, x86_pmu_num_counters(&pmu->pmu), 0, 0);
+
 		pmu->extra_regs = intel_glc_extra_regs;
 
 		/* Initialize Atom core specific PerfMon capabilities.*/
@@ -6844,8 +6900,9 @@
 		name = "alderlake_hybrid";
 		break;
 
-	case INTEL_FAM6_METEORLAKE:
-	case INTEL_FAM6_METEORLAKE_L:
+	case INTEL_METEORLAKE:
+	case INTEL_METEORLAKE_L:
+	case INTEL_ARROWLAKE_U:
 		intel_pmu_init_hybrid(hybrid_big_small);
 
 		x86_pmu.pebs_latency_data = mtl_latency_data_small;
@@ -6898,9 +6955,9 @@
 			 * The constraints may be cut according to the CPUID enumeration
 			 * by inserting the EVENT_CONSTRAINT_END.
 			 */
-			if (x86_pmu.num_counters_fixed > INTEL_PMC_MAX_FIXED)
-				x86_pmu.num_counters_fixed = INTEL_PMC_MAX_FIXED;
-			intel_v5_gen_event_constraints[x86_pmu.num_counters_fixed].weight = -1;
+			if (fls64(x86_pmu.fixed_cntr_mask64) > INTEL_PMC_MAX_FIXED)
+				x86_pmu.fixed_cntr_mask64 &= GENMASK_ULL(INTEL_PMC_MAX_FIXED - 1, 0);
+			intel_v5_gen_event_constraints[fls64(x86_pmu.fixed_cntr_mask64)].weight = -1;
 			x86_pmu.event_constraints = intel_v5_gen_event_constraints;
 			pr_cont("generic architected perfmon, ");
 			name = "generic_arch_v5+";
@@ -6927,18 +6984,17 @@
 		x86_pmu.attr_update = hybrid_attr_update;
 	}
 
-	intel_pmu_check_num_counters(&x86_pmu.num_counters,
-				     &x86_pmu.num_counters_fixed,
-				     &x86_pmu.intel_ctrl,
-				     (u64)fixed_mask);
+	intel_pmu_check_counters_mask(&x86_pmu.cntr_mask64,
+				      &x86_pmu.fixed_cntr_mask64,
+				      &x86_pmu.intel_ctrl);
 
 	/* AnyThread may be deprecated on arch perfmon v5 or later */
 	if (x86_pmu.intel_cap.anythread_deprecated)
 		x86_pmu.format_attrs = intel_arch_formats_attr;
 
 	intel_pmu_check_event_constraints(x86_pmu.event_constraints,
-					  x86_pmu.num_counters,
-					  x86_pmu.num_counters_fixed,
+					  x86_pmu.cntr_mask64,
+					  x86_pmu.fixed_cntr_mask64,
 					  x86_pmu.intel_ctrl);
 	/*
 	 * Access LBR MSR may cause #GP under certain circumstances.
--- linux-qcom-6.8.0.orig/arch/x86/events/intel/cstate.c
+++ linux-qcom-6.8.0/arch/x86/events/intel/cstate.c
@@ -41,7 +41,7 @@
  *	MSR_CORE_C1_RES: CORE C1 Residency Counter
  *			 perf code: 0x00
  *			 Available model: SLM,AMT,GLM,CNL,ICX,TNT,ADL,RPL
- *					  MTL,SRF,GRR
+ *					  MTL,SRF,GRR,ARL,LNL
  *			 Scope: Core (each processor core has a MSR)
  *	MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter
  *			       perf code: 0x01
@@ -53,50 +53,50 @@
  *			       Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,
  *						SKL,KNL,GLM,CNL,KBL,CML,ICL,ICX,
  *						TGL,TNT,RKL,ADL,RPL,SPR,MTL,SRF,
- *						GRR
+ *						GRR,ARL,LNL
  *			       Scope: Core
  *	MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter
  *			       perf code: 0x03
  *			       Available model: SNB,IVB,HSW,BDW,SKL,CNL,KBL,CML,
- *						ICL,TGL,RKL,ADL,RPL,MTL
+ *						ICL,TGL,RKL,ADL,RPL,MTL,ARL,LNL
  *			       Scope: Core
  *	MSR_PKG_C2_RESIDENCY:  Package C2 Residency Counter.
  *			       perf code: 0x00
  *			       Available model: SNB,IVB,HSW,BDW,SKL,KNL,GLM,CNL,
  *						KBL,CML,ICL,ICX,TGL,TNT,RKL,ADL,
- *						RPL,SPR,MTL
+ *						RPL,SPR,MTL,ARL,LNL,SRF
  *			       Scope: Package (physical package)
  *	MSR_PKG_C3_RESIDENCY:  Package C3 Residency Counter.
  *			       perf code: 0x01
  *			       Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL,
  *						GLM,CNL,KBL,CML,ICL,TGL,TNT,RKL,
- *						ADL,RPL,MTL
+ *						ADL,RPL,MTL,ARL,LNL
  *			       Scope: Package (physical package)
  *	MSR_PKG_C6_RESIDENCY:  Package C6 Residency Counter.
  *			       perf code: 0x02
  *			       Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,
  *						SKL,KNL,GLM,CNL,KBL,CML,ICL,ICX,
- *						TGL,TNT,RKL,ADL,RPL,SPR,MTL,SRF
+ *						TGL,TNT,RKL,ADL,RPL,SPR,MTL,SRF,
+ *						ARL,LNL
  *			       Scope: Package (physical package)
  *	MSR_PKG_C7_RESIDENCY:  Package C7 Residency Counter.
  *			       perf code: 0x03
  *			       Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,CNL,
- *						KBL,CML,ICL,TGL,RKL,ADL,RPL,MTL
+ *						KBL,CML,ICL,TGL,RKL
  *			       Scope: Package (physical package)
  *	MSR_PKG_C8_RESIDENCY:  Package C8 Residency Counter.
  *			       perf code: 0x04
  *			       Available model: HSW ULT,KBL,CNL,CML,ICL,TGL,RKL,
- *						ADL,RPL,MTL
+ *						ADL,RPL,MTL,ARL
  *			       Scope: Package (physical package)
  *	MSR_PKG_C9_RESIDENCY:  Package C9 Residency Counter.
  *			       perf code: 0x05
- *			       Available model: HSW ULT,KBL,CNL,CML,ICL,TGL,RKL,
- *						ADL,RPL,MTL
+ *			       Available model: HSW ULT,KBL,CNL,CML,ICL,TGL,RKL
  *			       Scope: Package (physical package)
  *	MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter.
  *			       perf code: 0x06
  *			       Available model: HSW ULT,KBL,GLM,CNL,CML,ICL,TGL,
- *						TNT,RKL,ADL,RPL,MTL
+ *						TNT,RKL,ADL,RPL,MTL,ARL,LNL
  *			       Scope: Package (physical package)
  *	MSR_MODULE_C6_RES_MS:  Module C6 Residency Counter.
  *			       perf code: 0x00
@@ -592,9 +592,7 @@
 	.pkg_events		= BIT(PERF_CSTATE_PKG_C2_RES) |
 				  BIT(PERF_CSTATE_PKG_C3_RES) |
 				  BIT(PERF_CSTATE_PKG_C6_RES) |
-				  BIT(PERF_CSTATE_PKG_C7_RES) |
 				  BIT(PERF_CSTATE_PKG_C8_RES) |
-				  BIT(PERF_CSTATE_PKG_C9_RES) |
 				  BIT(PERF_CSTATE_PKG_C10_RES),
 };
 
@@ -648,6 +646,17 @@
 				  BIT(PERF_CSTATE_PKG_C10_RES),
 };
 
+static const struct cstate_model lnl_cstates __initconst = {
+	.core_events		= BIT(PERF_CSTATE_CORE_C1_RES) |
+				  BIT(PERF_CSTATE_CORE_C6_RES) |
+				  BIT(PERF_CSTATE_CORE_C7_RES),
+
+	.pkg_events		= BIT(PERF_CSTATE_PKG_C2_RES) |
+				  BIT(PERF_CSTATE_PKG_C3_RES) |
+				  BIT(PERF_CSTATE_PKG_C6_RES) |
+				  BIT(PERF_CSTATE_PKG_C10_RES),
+};
+
 static const struct cstate_model slm_cstates __initconst = {
 	.core_events		= BIT(PERF_CSTATE_CORE_C1_RES) |
 				  BIT(PERF_CSTATE_CORE_C6_RES),
@@ -689,85 +698,90 @@
 	.core_events		= BIT(PERF_CSTATE_CORE_C1_RES) |
 				  BIT(PERF_CSTATE_CORE_C6_RES),
 
-	.pkg_events		= BIT(PERF_CSTATE_PKG_C6_RES),
+	.pkg_events		= BIT(PERF_CSTATE_PKG_C2_RES) |
+				  BIT(PERF_CSTATE_PKG_C6_RES),
 
 	.module_events		= BIT(PERF_CSTATE_MODULE_C6_RES),
 };
 
 
 static const struct x86_cpu_id intel_cstates_match[] __initconst = {
-	X86_MATCH_INTEL_FAM6_MODEL(NEHALEM,		&nhm_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EP,		&nhm_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(NEHALEM_EX,		&nhm_cstates),
-
-	X86_MATCH_INTEL_FAM6_MODEL(WESTMERE,		&nhm_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EP,		&nhm_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(WESTMERE_EX,		&nhm_cstates),
-
-	X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE,		&snb_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(SANDYBRIDGE_X,	&snb_cstates),
-
-	X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE,		&snb_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(IVYBRIDGE_X,		&snb_cstates),
-
-	X86_MATCH_INTEL_FAM6_MODEL(HASWELL,		&snb_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(HASWELL_X,		&snb_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(HASWELL_G,		&snb_cstates),
-
-	X86_MATCH_INTEL_FAM6_MODEL(HASWELL_L,		&hswult_cstates),
-
-	X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT,	&slm_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ATOM_SILVERMONT_D,	&slm_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ATOM_AIRMONT,	&slm_cstates),
-
-	X86_MATCH_INTEL_FAM6_MODEL(BROADWELL,		&snb_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_D,		&snb_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_G,		&snb_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(BROADWELL_X,		&snb_cstates),
-
-	X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_L,		&snb_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE,		&snb_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(SKYLAKE_X,		&snb_cstates),
-
-	X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE_L,		&hswult_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(KABYLAKE,		&hswult_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE_L,		&hswult_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE,		&hswult_cstates),
-
-	X86_MATCH_INTEL_FAM6_MODEL(CANNONLAKE_L,	&cnl_cstates),
-
-	X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL,	&knl_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM,	&knl_cstates),
-
-	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT,	&glm_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D,	&glm_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS,	&glm_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D,	&glm_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT,	&glm_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L,	&glm_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GRACEMONT,	&adl_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ATOM_CRESTMONT_X,	&srf_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ATOM_CRESTMONT,	&grr_cstates),
-
-	X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L,		&icl_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ICELAKE,		&icl_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X,		&icx_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D,		&icx_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X,	&icx_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X,	&icx_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(GRANITERAPIDS_X,	&icx_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(GRANITERAPIDS_D,	&icx_cstates),
-
-	X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L,		&icl_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE,		&icl_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ROCKETLAKE,		&icl_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE,		&adl_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L,		&adl_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE,		&adl_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P,	&adl_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S,	&adl_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE,		&adl_cstates),
-	X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE_L,	&adl_cstates),
+	X86_MATCH_VFM(INTEL_NEHALEM,		&nhm_cstates),
+	X86_MATCH_VFM(INTEL_NEHALEM_EP,		&nhm_cstates),
+	X86_MATCH_VFM(INTEL_NEHALEM_EX,		&nhm_cstates),
+
+	X86_MATCH_VFM(INTEL_WESTMERE,		&nhm_cstates),
+	X86_MATCH_VFM(INTEL_WESTMERE_EP,	&nhm_cstates),
+	X86_MATCH_VFM(INTEL_WESTMERE_EX,	&nhm_cstates),
+
+	X86_MATCH_VFM(INTEL_SANDYBRIDGE,	&snb_cstates),
+	X86_MATCH_VFM(INTEL_SANDYBRIDGE_X,	&snb_cstates),
+
+	X86_MATCH_VFM(INTEL_IVYBRIDGE,		&snb_cstates),
+	X86_MATCH_VFM(INTEL_IVYBRIDGE_X,	&snb_cstates),
+
+	X86_MATCH_VFM(INTEL_HASWELL,		&snb_cstates),
+	X86_MATCH_VFM(INTEL_HASWELL_X,		&snb_cstates),
+	X86_MATCH_VFM(INTEL_HASWELL_G,		&snb_cstates),
+
+	X86_MATCH_VFM(INTEL_HASWELL_L,		&hswult_cstates),
+
+	X86_MATCH_VFM(INTEL_ATOM_SILVERMONT,	&slm_cstates),
+	X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_D,	&slm_cstates),
+	X86_MATCH_VFM(INTEL_ATOM_AIRMONT,	&slm_cstates),
+
+	X86_MATCH_VFM(INTEL_BROADWELL,		&snb_cstates),
+	X86_MATCH_VFM(INTEL_BROADWELL_D,	&snb_cstates),
+	X86_MATCH_VFM(INTEL_BROADWELL_G,	&snb_cstates),
+	X86_MATCH_VFM(INTEL_BROADWELL_X,	&snb_cstates),
+
+	X86_MATCH_VFM(INTEL_SKYLAKE_L,		&snb_cstates),
+	X86_MATCH_VFM(INTEL_SKYLAKE,		&snb_cstates),
+	X86_MATCH_VFM(INTEL_SKYLAKE_X,		&snb_cstates),
+
+	X86_MATCH_VFM(INTEL_KABYLAKE_L,		&hswult_cstates),
+	X86_MATCH_VFM(INTEL_KABYLAKE,		&hswult_cstates),
+	X86_MATCH_VFM(INTEL_COMETLAKE_L,	&hswult_cstates),
+	X86_MATCH_VFM(INTEL_COMETLAKE,		&hswult_cstates),
+
+	X86_MATCH_VFM(INTEL_CANNONLAKE_L,	&cnl_cstates),
+
+	X86_MATCH_VFM(INTEL_XEON_PHI_KNL,	&knl_cstates),
+	X86_MATCH_VFM(INTEL_XEON_PHI_KNM,	&knl_cstates),
+
+	X86_MATCH_VFM(INTEL_ATOM_GOLDMONT,	&glm_cstates),
+	X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_D,	&glm_cstates),
+	X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_PLUS,	&glm_cstates),
+	X86_MATCH_VFM(INTEL_ATOM_TREMONT_D,	&glm_cstates),
+	X86_MATCH_VFM(INTEL_ATOM_TREMONT,	&glm_cstates),
+	X86_MATCH_VFM(INTEL_ATOM_TREMONT_L,	&glm_cstates),
+	X86_MATCH_VFM(INTEL_ATOM_GRACEMONT,	&adl_cstates),
+	X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X,	&srf_cstates),
+	X86_MATCH_VFM(INTEL_ATOM_CRESTMONT,	&grr_cstates),
+
+	X86_MATCH_VFM(INTEL_ICELAKE_L,		&icl_cstates),
+	X86_MATCH_VFM(INTEL_ICELAKE,		&icl_cstates),
+	X86_MATCH_VFM(INTEL_ICELAKE_X,		&icx_cstates),
+	X86_MATCH_VFM(INTEL_ICELAKE_D,		&icx_cstates),
+	X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X,	&icx_cstates),
+	X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X,	&icx_cstates),
+	X86_MATCH_VFM(INTEL_GRANITERAPIDS_X,	&icx_cstates),
+	X86_MATCH_VFM(INTEL_GRANITERAPIDS_D,	&icx_cstates),
+
+	X86_MATCH_VFM(INTEL_TIGERLAKE_L,	&icl_cstates),
+	X86_MATCH_VFM(INTEL_TIGERLAKE,		&icl_cstates),
+	X86_MATCH_VFM(INTEL_ROCKETLAKE,		&icl_cstates),
+	X86_MATCH_VFM(INTEL_ALDERLAKE,		&adl_cstates),
+	X86_MATCH_VFM(INTEL_ALDERLAKE_L,	&adl_cstates),
+	X86_MATCH_VFM(INTEL_RAPTORLAKE,		&adl_cstates),
+	X86_MATCH_VFM(INTEL_RAPTORLAKE_P,	&adl_cstates),
+	X86_MATCH_VFM(INTEL_RAPTORLAKE_S,	&adl_cstates),
+	X86_MATCH_VFM(INTEL_METEORLAKE,		&adl_cstates),
+	X86_MATCH_VFM(INTEL_METEORLAKE_L,	&adl_cstates),
+	X86_MATCH_VFM(INTEL_ARROWLAKE,		&adl_cstates),
+	X86_MATCH_VFM(INTEL_ARROWLAKE_H,	&adl_cstates),
+	X86_MATCH_VFM(INTEL_ARROWLAKE_U,	&adl_cstates),
+	X86_MATCH_VFM(INTEL_LUNARLAKE_M,	&lnl_cstates),
 	{ },
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match);
--- linux-qcom-6.8.0.orig/arch/x86/events/intel/ds.c
+++ linux-qcom-6.8.0/arch/x86/events/intel/ds.c
@@ -1136,8 +1136,7 @@
 static inline void pebs_update_threshold(struct cpu_hw_events *cpuc)
 {
 	struct debug_store *ds = cpuc->ds;
-	int max_pebs_events = hybrid(cpuc->pmu, max_pebs_events);
-	int num_counters_fixed = hybrid(cpuc->pmu, num_counters_fixed);
+	int max_pebs_events = intel_pmu_max_num_pebs(cpuc->pmu);
 	u64 threshold;
 	int reserved;
 
@@ -1145,7 +1144,7 @@
 		return;
 
 	if (x86_pmu.flags & PMU_FL_PEBS_ALL)
-		reserved = max_pebs_events + num_counters_fixed;
+		reserved = max_pebs_events + x86_pmu_max_num_counters_fixed(cpuc->pmu);
 	else
 		reserved = max_pebs_events;
 
@@ -1236,11 +1235,11 @@
 	struct pmu *pmu = event->pmu;
 
 	/*
-	 * Make sure we get updated with the first PEBS
-	 * event. It will trigger also during removal, but
-	 * that does not hurt:
+	 * Make sure we get updated with the first PEBS event.
+	 * During removal, ->pebs_data_cfg is still valid for
+	 * the last PEBS event. Don't clear it.
 	 */
-	if (cpuc->n_pebs == 1)
+	if ((cpuc->n_pebs == 1) && add)
 		cpuc->pebs_data_cfg = PEBS_UPDATE_DS_SW;
 
 	if (needed_cb != pebs_needs_sched_cb(cpuc)) {
@@ -1354,7 +1353,7 @@
 			 * hence we need to drain when changing said
 			 * size.
 			 */
-			intel_pmu_drain_large_pebs(cpuc);
+			intel_pmu_drain_pebs_buffer();
 			adaptive_pebs_record_size_update();
 			wrmsrl(MSR_PEBS_DATA_CFG, pebs_data_cfg);
 			cpuc->active_pebs_data_cfg = pebs_data_cfg;
@@ -1830,8 +1829,12 @@
 	set_linear_ip(regs, basic->ip);
 	regs->flags = PERF_EFLAGS_EXACT;
 
-	if ((sample_type & PERF_SAMPLE_WEIGHT_STRUCT) && (x86_pmu.flags & PMU_FL_RETIRE_LATENCY))
-		data->weight.var3_w = format_size >> PEBS_RETIRE_LATENCY_OFFSET & PEBS_LATENCY_MASK;
+	if (sample_type & PERF_SAMPLE_WEIGHT_STRUCT) {
+		if (x86_pmu.flags & PMU_FL_RETIRE_LATENCY)
+			data->weight.var3_w = format_size >> PEBS_RETIRE_LATENCY_OFFSET & PEBS_LATENCY_MASK;
+		else
+			data->weight.var3_w = 0;
+	}
 
 	/*
 	 * The record for MEMINFO is in front of GP
@@ -2156,6 +2159,7 @@
 	void *base, *at, *top;
 	short counts[INTEL_PMC_IDX_FIXED + MAX_FIXED_PEBS_EVENTS] = {};
 	short error[INTEL_PMC_IDX_FIXED + MAX_FIXED_PEBS_EVENTS] = {};
+	int max_pebs_events = intel_pmu_max_num_pebs(NULL);
 	int bit, i, size;
 	u64 mask;
 
@@ -2167,11 +2171,11 @@
 
 	ds->pebs_index = ds->pebs_buffer_base;
 
-	mask = (1ULL << x86_pmu.max_pebs_events) - 1;
-	size = x86_pmu.max_pebs_events;
+	mask = x86_pmu.pebs_events_mask;
+	size = max_pebs_events;
 	if (x86_pmu.flags & PMU_FL_PEBS_ALL) {
-		mask |= ((1ULL << x86_pmu.num_counters_fixed) - 1) << INTEL_PMC_IDX_FIXED;
-		size = INTEL_PMC_IDX_FIXED + x86_pmu.num_counters_fixed;
+		mask |= x86_pmu.fixed_cntr_mask64 << INTEL_PMC_IDX_FIXED;
+		size = INTEL_PMC_IDX_FIXED + x86_pmu_max_num_counters_fixed(NULL);
 	}
 
 	if (unlikely(base >= top)) {
@@ -2207,8 +2211,9 @@
 			pebs_status = p->status = cpuc->pebs_enabled;
 
 		bit = find_first_bit((unsigned long *)&pebs_status,
-					x86_pmu.max_pebs_events);
-		if (bit >= x86_pmu.max_pebs_events)
+				     max_pebs_events);
+
+		if (!(x86_pmu.pebs_events_mask & (1 << bit)))
 			continue;
 
 		/*
@@ -2266,12 +2271,10 @@
 {
 	short counts[INTEL_PMC_IDX_FIXED + MAX_FIXED_PEBS_EVENTS] = {};
 	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
-	int max_pebs_events = hybrid(cpuc->pmu, max_pebs_events);
-	int num_counters_fixed = hybrid(cpuc->pmu, num_counters_fixed);
 	struct debug_store *ds = cpuc->ds;
 	struct perf_event *event;
 	void *base, *at, *top;
-	int bit, size;
+	int bit;
 	u64 mask;
 
 	if (!x86_pmu.pebs_active)
@@ -2282,12 +2285,11 @@
 
 	ds->pebs_index = ds->pebs_buffer_base;
 
-	mask = ((1ULL << max_pebs_events) - 1) |
-	       (((1ULL << num_counters_fixed) - 1) << INTEL_PMC_IDX_FIXED);
-	size = INTEL_PMC_IDX_FIXED + num_counters_fixed;
+	mask = hybrid(cpuc->pmu, pebs_events_mask) |
+	       (hybrid(cpuc->pmu, fixed_cntr_mask64) << INTEL_PMC_IDX_FIXED);
 
 	if (unlikely(base >= top)) {
-		intel_pmu_pebs_event_update_no_drain(cpuc, size);
+		intel_pmu_pebs_event_update_no_drain(cpuc, X86_PMC_IDX_MAX);
 		return;
 	}
 
@@ -2297,11 +2299,11 @@
 		pebs_status = get_pebs_status(at) & cpuc->pebs_enabled;
 		pebs_status &= mask;
 
-		for_each_set_bit(bit, (unsigned long *)&pebs_status, size)
+		for_each_set_bit(bit, (unsigned long *)&pebs_status, X86_PMC_IDX_MAX)
 			counts[bit]++;
 	}
 
-	for_each_set_bit(bit, (unsigned long *)&mask, size) {
+	for_each_set_bit(bit, (unsigned long *)&mask, X86_PMC_IDX_MAX) {
 		if (counts[bit] == 0)
 			continue;
 
@@ -2379,6 +2381,7 @@
 			x86_pmu.large_pebs_flags |= PERF_SAMPLE_TIME;
 			break;
 
+		case 6:
 		case 5:
 			x86_pmu.pebs_ept = 1;
 			fallthrough;
--- linux-qcom-6.8.0.orig/arch/x86/events/intel/knc.c
+++ linux-qcom-6.8.0/arch/x86/events/intel/knc.c
@@ -303,7 +303,7 @@
 	.apic			= 1,
 	.max_period		= (1ULL << 39) - 1,
 	.version		= 0,
-	.num_counters		= 2,
+	.cntr_mask64		= 0x3,
 	.cntval_bits		= 40,
 	.cntval_mask		= (1ULL << 40) - 1,
 	.get_event_constraints	= x86_get_event_constraints,
--- linux-qcom-6.8.0.orig/arch/x86/events/intel/p4.c
+++ linux-qcom-6.8.0/arch/x86/events/intel/p4.c
@@ -919,7 +919,7 @@
 	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
 	int idx;
 
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+	for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
 		struct perf_event *event = cpuc->events[idx];
 		if (!test_bit(idx, cpuc->active_mask))
 			continue;
@@ -998,7 +998,7 @@
 	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
 	int idx;
 
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+	for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
 		struct perf_event *event = cpuc->events[idx];
 		if (!test_bit(idx, cpuc->active_mask))
 			continue;
@@ -1040,7 +1040,7 @@
 
 	cpuc = this_cpu_ptr(&cpu_hw_events);
 
-	for (idx = 0; idx < x86_pmu.num_counters; idx++) {
+	for_each_set_bit(idx, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
 		int overflow;
 
 		if (!test_bit(idx, cpuc->active_mask)) {
@@ -1353,7 +1353,7 @@
 	 * though leave it restricted at moment assuming
 	 * HT is on
 	 */
-	.num_counters		= ARCH_P4_MAX_CCCR,
+	.cntr_mask64		= GENMASK_ULL(ARCH_P4_MAX_CCCR - 1, 0),
 	.apic			= 1,
 	.cntval_bits		= ARCH_P4_CNTRVAL_BITS,
 	.cntval_mask		= ARCH_P4_CNTRVAL_MASK,
@@ -1395,7 +1395,7 @@
 	 *
 	 * Solve this by zero'ing out the registers to mimic a reset.
 	 */
-	for (i = 0; i < x86_pmu.num_counters; i++) {
+	for_each_set_bit(i, x86_pmu.cntr_mask, X86_PMC_IDX_MAX) {
 		reg = x86_pmu_config_addr(i);
 		wrmsrl_safe(reg, 0ULL);
 	}
--- linux-qcom-6.8.0.orig/arch/x86/events/intel/p6.c
+++ linux-qcom-6.8.0/arch/x86/events/intel/p6.c
@@ -214,7 +214,7 @@
 	.apic			= 1,
 	.max_period		= (1ULL << 31) - 1,
 	.version		= 0,
-	.num_counters		= 2,
+	.cntr_mask64		= 0x3,
 	/*
 	 * Events have 40 bits implemented. However they are designed such
 	 * that bits [32-39] are sign extensions of bit 31. As such the
--- linux-qcom-6.8.0.orig/arch/x86/events/intel/pt.c
+++ linux-qcom-6.8.0/arch/x86/events/intel/pt.c
@@ -828,11 +828,13 @@
 	buf->cur_idx++;
 
 	if (buf->cur_idx == buf->cur->last) {
-		if (buf->cur == buf->last)
+		if (buf->cur == buf->last) {
 			buf->cur = buf->first;
-		else
+			buf->wrapped = true;
+		} else {
 			buf->cur = list_entry(buf->cur->list.next, struct topa,
 					      list);
+		}
 		buf->cur_idx = 0;
 	}
 }
@@ -846,8 +848,11 @@
 static void pt_update_head(struct pt *pt)
 {
 	struct pt_buffer *buf = perf_get_aux(&pt->handle);
+	bool wrapped = buf->wrapped;
 	u64 topa_idx, base, old;
 
+	buf->wrapped = false;
+
 	if (buf->single) {
 		local_set(&buf->data_size, buf->output_off);
 		return;
@@ -865,7 +870,7 @@
 	} else {
 		old = (local64_xchg(&buf->head, base) &
 		       ((buf->nr_pages << PAGE_SHIFT) - 1));
-		if (base < old)
+		if (base < old || (base == old && wrapped))
 			base += buf->nr_pages << PAGE_SHIFT;
 
 		local_add(base - old, &buf->data_size);
@@ -878,7 +883,7 @@
  */
 static void *pt_buffer_region(struct pt_buffer *buf)
 {
-	return phys_to_virt(TOPA_ENTRY(buf->cur, buf->cur_idx)->base << TOPA_SHIFT);
+	return phys_to_virt((phys_addr_t)TOPA_ENTRY(buf->cur, buf->cur_idx)->base << TOPA_SHIFT);
 }
 
 /**
@@ -990,7 +995,7 @@
 	 * order allocations, there shouldn't be many of these.
 	 */
 	list_for_each_entry(topa, &buf->tables, list) {
-		if (topa->offset + topa->size > pg << PAGE_SHIFT)
+		if (topa->offset + topa->size > (unsigned long)pg << PAGE_SHIFT)
 			goto found;
 	}
 
@@ -1606,6 +1611,7 @@
 	 * see comment in intel_pt_interrupt().
 	 */
 	WRITE_ONCE(pt->handle_nmi, 0);
+	barrier();
 
 	pt_config_stop(event);
 
@@ -1657,11 +1663,10 @@
 		return 0;
 
 	/*
-	 * Here, handle_nmi tells us if the tracing is on
+	 * There is no PT interrupt in this mode, so stop the trace and it will
+	 * remain stopped while the buffer is copied.
 	 */
-	if (READ_ONCE(pt->handle_nmi))
-		pt_config_stop(event);
-
+	pt_config_stop(event);
 	pt_read_offset(buf);
 	pt_update_head(pt);
 
@@ -1673,11 +1678,10 @@
 	ret = perf_output_copy_aux(&pt->handle, handle, from, to);
 
 	/*
-	 * If the tracing was on when we turned up, restart it.
-	 * Compiler barrier not needed as we couldn't have been
-	 * preempted by anything that touches pt->handle_nmi.
+	 * Here, handle_nmi tells us if the tracing was on.
+	 * If the tracing was on, restart it.
 	 */
-	if (pt->handle_nmi)
+	if (READ_ONCE(pt->handle_nmi))
 		pt_config_start(event);
 
 	return ret;
--- linux-qcom-6.8.0.orig/arch/x86/events/intel/pt.h
+++ linux-qcom-6.8.0/arch/x86/events/intel/pt.h
@@ -33,8 +33,8 @@
 	u64	rsvd2	: 1;
 	u64	size	: 4;
 	u64	rsvd3	: 2;
-	u64	base	: 36;
-	u64	rsvd4	: 16;
+	u64	base	: 40;
+	u64	rsvd4	: 12;
 };
 
 /* TSC to Core Crystal Clock Ratio */
@@ -65,6 +65,7 @@
  * @head:	logical write offset inside the buffer
  * @snapshot:	if this is for a snapshot/overwrite counter
  * @single:	use Single Range Output instead of ToPA
+ * @wrapped:	buffer advance wrapped back to the first topa table
  * @stop_pos:	STOP topa entry index
  * @intr_pos:	INT topa entry index
  * @stop_te:	STOP topa entry pointer
@@ -82,6 +83,7 @@
 	local64_t		head;
 	bool			snapshot;
 	bool			single;
+	bool			wrapped;
 	long			stop_pos, intr_pos;
 	struct topa_entry	*stop_te, *intr_te;
 	void			**data_pages;
--- linux-qcom-6.8.0.orig/arch/x86/events/intel/uncore.c
+++ linux-qcom-6.8.0/arch/x86/events/intel/uncore.c
@@ -263,6 +263,9 @@
 		return;
 	}
 
+	if (intel_generic_uncore_assign_hw_event(event, box))
+		return;
+
 	hwc->config_base = uncore_event_ctl(box, hwc->idx);
 	hwc->event_base  = uncore_perf_ctr(box, hwc->idx);
 }
@@ -843,7 +846,9 @@
 static ssize_t uncore_get_attr_cpumask(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
-	return cpumap_print_to_pagebuf(true, buf, &uncore_cpu_mask);
+	struct intel_uncore_pmu *pmu = container_of(dev_get_drvdata(dev), struct intel_uncore_pmu, pmu);
+
+	return cpumap_print_to_pagebuf(true, buf, &pmu->cpu_mask);
 }
 
 static DEVICE_ATTR(cpumask, S_IRUGO, uncore_get_attr_cpumask, NULL);
@@ -860,7 +865,10 @@
 static inline int uncore_get_box_id(struct intel_uncore_type *type,
 				    struct intel_uncore_pmu *pmu)
 {
-	return type->box_ids ? type->box_ids[pmu->pmu_idx] : pmu->pmu_idx;
+	if (type->boxes)
+		return intel_uncore_find_discovery_unit_id(type->boxes, -1, pmu->pmu_idx);
+
+	return pmu->pmu_idx;
 }
 
 void uncore_get_alias_name(char *pmu_name, struct intel_uncore_pmu *pmu)
@@ -961,6 +969,9 @@
 	if (type->cleanup_mapping)
 		type->cleanup_mapping(type);
 
+	if (type->cleanup_extra_boxes)
+		type->cleanup_extra_boxes(type);
+
 	if (pmu) {
 		for (i = 0; i < type->num_boxes; i++, pmu++) {
 			uncore_pmu_unregister(pmu);
@@ -969,10 +980,7 @@
 		kfree(type->pmus);
 		type->pmus = NULL;
 	}
-	if (type->box_ids) {
-		kfree(type->box_ids);
-		type->box_ids = NULL;
-	}
+
 	kfree(type->events_group);
 	type->events_group = NULL;
 }
@@ -1076,22 +1084,19 @@
 uncore_pci_find_dev_pmu_from_types(struct pci_dev *pdev)
 {
 	struct intel_uncore_type **types = uncore_pci_uncores;
+	struct intel_uncore_discovery_unit *unit;
 	struct intel_uncore_type *type;
-	u64 box_ctl;
-	int i, die;
+	struct rb_node *node;
 
 	for (; *types; types++) {
 		type = *types;
-		for (die = 0; die < __uncore_max_dies; die++) {
-			for (i = 0; i < type->num_boxes; i++) {
-				if (!type->box_ctls[die])
-					continue;
-				box_ctl = type->box_ctls[die] + type->pci_offsets[i];
-				if (pdev->devfn == UNCORE_DISCOVERY_PCI_DEVFN(box_ctl) &&
-				    pdev->bus->number == UNCORE_DISCOVERY_PCI_BUS(box_ctl) &&
-				    pci_domain_nr(pdev->bus) == UNCORE_DISCOVERY_PCI_DOMAIN(box_ctl))
-					return &type->pmus[i];
-			}
+
+		for (node = rb_first(type->boxes); node; node = rb_next(node)) {
+			unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
+			if (pdev->devfn == UNCORE_DISCOVERY_PCI_DEVFN(unit->addr) &&
+			    pdev->bus->number == UNCORE_DISCOVERY_PCI_BUS(unit->addr) &&
+			    pci_domain_nr(pdev->bus) == UNCORE_DISCOVERY_PCI_DOMAIN(unit->addr))
+				return &type->pmus[unit->pmu_idx];
 		}
 	}
 
@@ -1367,28 +1372,25 @@
 static void uncore_pci_pmus_register(void)
 {
 	struct intel_uncore_type **types = uncore_pci_uncores;
+	struct intel_uncore_discovery_unit *unit;
 	struct intel_uncore_type *type;
 	struct intel_uncore_pmu *pmu;
+	struct rb_node *node;
 	struct pci_dev *pdev;
-	u64 box_ctl;
-	int i, die;
 
 	for (; *types; types++) {
 		type = *types;
-		for (die = 0; die < __uncore_max_dies; die++) {
-			for (i = 0; i < type->num_boxes; i++) {
-				if (!type->box_ctls[die])
-					continue;
-				box_ctl = type->box_ctls[die] + type->pci_offsets[i];
-				pdev = pci_get_domain_bus_and_slot(UNCORE_DISCOVERY_PCI_DOMAIN(box_ctl),
-								   UNCORE_DISCOVERY_PCI_BUS(box_ctl),
-								   UNCORE_DISCOVERY_PCI_DEVFN(box_ctl));
-				if (!pdev)
-					continue;
-				pmu = &type->pmus[i];
 
-				uncore_pci_pmu_register(pdev, type, pmu, die);
-			}
+		for (node = rb_first(type->boxes); node; node = rb_next(node)) {
+			unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
+			pdev = pci_get_domain_bus_and_slot(UNCORE_DISCOVERY_PCI_DOMAIN(unit->addr),
+							   UNCORE_DISCOVERY_PCI_BUS(unit->addr),
+							   UNCORE_DISCOVERY_PCI_DEVFN(unit->addr));
+
+			if (!pdev)
+				continue;
+			pmu = &type->pmus[unit->pmu_idx];
+			uncore_pci_pmu_register(pdev, type, pmu, unit->die);
 		}
 	}
 
@@ -1453,6 +1455,18 @@
 	}
 }
 
+static bool uncore_die_has_box(struct intel_uncore_type *type,
+			       int die, unsigned int pmu_idx)
+{
+	if (!type->boxes)
+		return true;
+
+	if (intel_uncore_find_discovery_unit_id(type->boxes, die, pmu_idx) < 0)
+		return false;
+
+	return true;
+}
+
 static void uncore_change_type_ctx(struct intel_uncore_type *type, int old_cpu,
 				   int new_cpu)
 {
@@ -1468,18 +1482,25 @@
 
 		if (old_cpu < 0) {
 			WARN_ON_ONCE(box->cpu != -1);
-			box->cpu = new_cpu;
+			if (uncore_die_has_box(type, die, pmu->pmu_idx)) {
+				box->cpu = new_cpu;
+				cpumask_set_cpu(new_cpu, &pmu->cpu_mask);
+			}
 			continue;
 		}
 
-		WARN_ON_ONCE(box->cpu != old_cpu);
+		WARN_ON_ONCE(box->cpu != -1 && box->cpu != old_cpu);
 		box->cpu = -1;
+		cpumask_clear_cpu(old_cpu, &pmu->cpu_mask);
 		if (new_cpu < 0)
 			continue;
 
+		if (!uncore_die_has_box(type, die, pmu->pmu_idx))
+			continue;
 		uncore_pmu_cancel_hrtimer(box);
 		perf_pmu_migrate_context(&pmu->pmu, old_cpu, new_cpu);
 		box->cpu = new_cpu;
+		cpumask_set_cpu(new_cpu, &pmu->cpu_mask);
 	}
 }
 
@@ -1502,7 +1523,7 @@
 		pmu = type->pmus;
 		for (i = 0; i < type->num_boxes; i++, pmu++) {
 			box = pmu->boxes[id];
-			if (box && atomic_dec_return(&box->refcnt) == 0)
+			if (box && box->cpu >= 0 && atomic_dec_return(&box->refcnt) == 0)
 				uncore_box_exit(box);
 		}
 	}
@@ -1592,7 +1613,7 @@
 		pmu = type->pmus;
 		for (i = 0; i < type->num_boxes; i++, pmu++) {
 			box = pmu->boxes[id];
-			if (box && atomic_inc_return(&box->refcnt) == 1)
+			if (box && box->cpu >= 0 && atomic_inc_return(&box->refcnt) == 1)
 				uncore_box_init(box);
 		}
 	}
--- linux-qcom-6.8.0.orig/arch/x86/events/intel/uncore.h
+++ linux-qcom-6.8.0/arch/x86/events/intel/uncore.h
@@ -62,7 +62,6 @@
 	unsigned fixed_ctr;
 	unsigned fixed_ctl;
 	unsigned box_ctl;
-	u64 *box_ctls;	/* Unit ctrl addr of the first box of each die */
 	union {
 		unsigned msr_offset;
 		unsigned mmio_offset;
@@ -76,7 +75,6 @@
 		u64 *pci_offsets;
 		u64 *mmio_offsets;
 	};
-	unsigned *box_ids;
 	struct event_constraint unconstrainted;
 	struct event_constraint *constraints;
 	struct intel_uncore_pmu *pmus;
@@ -86,6 +84,7 @@
 	const struct attribute_group *attr_groups[4];
 	const struct attribute_group **attr_update;
 	struct pmu *pmu; /* for custom pmu ops */
+	struct rb_root *boxes;
 	/*
 	 * Uncore PMU would store relevant platform topology configuration here
 	 * to identify which platform component each PMON block of that type is
@@ -98,6 +97,10 @@
 	int (*get_topology)(struct intel_uncore_type *type);
 	void (*set_mapping)(struct intel_uncore_type *type);
 	void (*cleanup_mapping)(struct intel_uncore_type *type);
+	/*
+	 * Optional callbacks for extra uncore units cleanup
+	 */
+	void (*cleanup_extra_boxes)(struct intel_uncore_type *type);
 };
 
 #define pmu_group attr_groups[0]
@@ -125,6 +128,7 @@
 	int				func_id;
 	bool				registered;
 	atomic_t			activeboxes;
+	cpumask_t			cpu_mask;
 	struct intel_uncore_type	*type;
 	struct intel_uncore_box		**boxes;
 };
--- linux-qcom-6.8.0.orig/arch/x86/events/intel/uncore_discovery.c
+++ linux-qcom-6.8.0/arch/x86/events/intel/uncore_discovery.c
@@ -89,9 +89,7 @@
 	if (!type)
 		return NULL;
 
-	type->box_ctrl_die = kcalloc(__uncore_max_dies, sizeof(u64), GFP_KERNEL);
-	if (!type->box_ctrl_die)
-		goto free_type;
+	type->units = RB_ROOT;
 
 	type->access_type = unit->access_type;
 	num_discovered_types[type->access_type]++;
@@ -100,12 +98,6 @@
 	rb_add(&type->node, &discovery_tables, __type_less);
 
 	return type;
-
-free_type:
-	kfree(type);
-
-	return NULL;
-
 }
 
 static struct intel_uncore_discovery_type *
@@ -120,14 +112,118 @@
 	return add_uncore_discovery_type(unit);
 }
 
+static inline int pmu_idx_cmp(const void *key, const struct rb_node *b)
+{
+	struct intel_uncore_discovery_unit *unit;
+	const unsigned int *id = key;
+
+	unit = rb_entry(b, struct intel_uncore_discovery_unit, node);
+
+	if (unit->pmu_idx > *id)
+		return -1;
+	else if (unit->pmu_idx < *id)
+		return 1;
+
+	return 0;
+}
+
+static struct intel_uncore_discovery_unit *
+intel_uncore_find_discovery_unit(struct rb_root *units, int die,
+				 unsigned int pmu_idx)
+{
+	struct intel_uncore_discovery_unit *unit;
+	struct rb_node *pos;
+
+	if (!units)
+		return NULL;
+
+	pos = rb_find_first(&pmu_idx, units, pmu_idx_cmp);
+	if (!pos)
+		return NULL;
+	unit = rb_entry(pos, struct intel_uncore_discovery_unit, node);
+
+	if (die < 0)
+		return unit;
+
+	for (; pos; pos = rb_next(pos)) {
+		unit = rb_entry(pos, struct intel_uncore_discovery_unit, node);
+
+		if (unit->pmu_idx != pmu_idx)
+			break;
+
+		if (unit->die == die)
+			return unit;
+	}
+
+	return NULL;
+}
+
+int intel_uncore_find_discovery_unit_id(struct rb_root *units, int die,
+					unsigned int pmu_idx)
+{
+	struct intel_uncore_discovery_unit *unit;
+
+	unit = intel_uncore_find_discovery_unit(units, die, pmu_idx);
+	if (unit)
+		return unit->id;
+
+	return -1;
+}
+
+static inline bool unit_less(struct rb_node *a, const struct rb_node *b)
+{
+	struct intel_uncore_discovery_unit *a_node, *b_node;
+
+	a_node = rb_entry(a, struct intel_uncore_discovery_unit, node);
+	b_node = rb_entry(b, struct intel_uncore_discovery_unit, node);
+
+	if (a_node->pmu_idx < b_node->pmu_idx)
+		return true;
+	if (a_node->pmu_idx > b_node->pmu_idx)
+		return false;
+
+	if (a_node->die < b_node->die)
+		return true;
+	if (a_node->die > b_node->die)
+		return false;
+
+	return 0;
+}
+
+static inline struct intel_uncore_discovery_unit *
+uncore_find_unit(struct rb_root *root, unsigned int id)
+{
+	struct intel_uncore_discovery_unit *unit;
+	struct rb_node *node;
+
+	for (node = rb_first(root); node; node = rb_next(node)) {
+		unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
+		if (unit->id == id)
+			return unit;
+	}
+
+	return NULL;
+}
+
+void uncore_find_add_unit(struct intel_uncore_discovery_unit *node,
+			  struct rb_root *root, u16 *num_units)
+{
+	struct intel_uncore_discovery_unit *unit = uncore_find_unit(root, node->id);
+
+	if (unit)
+		node->pmu_idx = unit->pmu_idx;
+	else if (num_units)
+		node->pmu_idx = (*num_units)++;
+
+	rb_add(&node->node, root, unit_less);
+}
+
 static void
 uncore_insert_box_info(struct uncore_unit_discovery *unit,
-		       int die, bool parsed)
+		       int die)
 {
+	struct intel_uncore_discovery_unit *node;
 	struct intel_uncore_discovery_type *type;
-	unsigned int *ids;
-	u64 *box_offset;
-	int i;
 
 	if (!unit->ctl || !unit->ctl_offset || !unit->ctr_offset) {
 		pr_info("Invalid address is detected for uncore type %d box %d, "
@@ -136,71 +232,29 @@
 		return;
 	}
 
-	if (parsed) {
-		type = search_uncore_discovery_type(unit->box_type);
-		if (!type) {
-			pr_info("A spurious uncore type %d is detected, "
-				"Disable the uncore type.\n",
-				unit->box_type);
-			return;
-		}
-		/* Store the first box of each die */
-		if (!type->box_ctrl_die[die])
-			type->box_ctrl_die[die] = unit->ctl;
+	node = kzalloc(sizeof(*node), GFP_KERNEL);
+	if (!node)
 		return;
-	}
 
-	type = get_uncore_discovery_type(unit);
-	if (!type)
-		return;
+	node->die = die;
+	node->id = unit->box_id;
+	node->addr = unit->ctl;
 
-	box_offset = kcalloc(type->num_boxes + 1, sizeof(u64), GFP_KERNEL);
-	if (!box_offset)
+	type = get_uncore_discovery_type(unit);
+	if (!type) {
+		kfree(node);
 		return;
+	}
 
-	ids = kcalloc(type->num_boxes + 1, sizeof(unsigned int), GFP_KERNEL);
-	if (!ids)
-		goto free_box_offset;
+	uncore_find_add_unit(node, &type->units, &type->num_units);
 
 	/* Store generic information for the first box */
-	if (!type->num_boxes) {
-		type->box_ctrl = unit->ctl;
-		type->box_ctrl_die[die] = unit->ctl;
+	if (type->num_units == 1) {
 		type->num_counters = unit->num_regs;
 		type->counter_width = unit->bit_width;
 		type->ctl_offset = unit->ctl_offset;
 		type->ctr_offset = unit->ctr_offset;
-		*ids = unit->box_id;
-		goto end;
-	}
-
-	for (i = 0; i < type->num_boxes; i++) {
-		ids[i] = type->ids[i];
-		box_offset[i] = type->box_offset[i];
-
-		if (unit->box_id == ids[i]) {
-			pr_info("Duplicate uncore type %d box ID %d is detected, "
-				"Drop the duplicate uncore unit.\n",
-				unit->box_type, unit->box_id);
-			goto free_ids;
-		}
 	}
-	ids[i] = unit->box_id;
-	box_offset[i] = unit->ctl - type->box_ctrl;
-	kfree(type->ids);
-	kfree(type->box_offset);
-end:
-	type->ids = ids;
-	type->box_offset = box_offset;
-	type->num_boxes++;
-	return;
-
-free_ids:
-	kfree(ids);
-
-free_box_offset:
-	kfree(box_offset);
-
 }
 
 static bool
@@ -279,7 +333,7 @@
 		if (uncore_ignore_unit(&unit, ignore))
 			continue;
 
-		uncore_insert_box_info(&unit, die, *parsed);
+		uncore_insert_box_info(&unit, die);
 	}
 
 	*parsed = true;
@@ -339,9 +393,16 @@
 void intel_uncore_clear_discovery_tables(void)
 {
 	struct intel_uncore_discovery_type *type, *next;
+	struct intel_uncore_discovery_unit *pos;
+	struct rb_node *node;
 
 	rbtree_postorder_for_each_entry_safe(type, next, &discovery_tables, node) {
-		kfree(type->box_ctrl_die);
+		while (!RB_EMPTY_ROOT(&type->units)) {
+			node = rb_first(&type->units);
+			pos = rb_entry(node, struct intel_uncore_discovery_unit, node);
+			rb_erase(node, &type->units);
+			kfree(pos);
+		}
 		kfree(type);
 	}
 }
@@ -366,19 +427,31 @@
 	.attrs = generic_uncore_formats_attr,
 };
 
+static u64 intel_generic_uncore_box_ctl(struct intel_uncore_box *box)
+{
+	struct intel_uncore_discovery_unit *unit;
+
+	unit = intel_uncore_find_discovery_unit(box->pmu->type->boxes,
+						-1, box->pmu->pmu_idx);
+	if (WARN_ON_ONCE(!unit))
+		return 0;
+
+	return unit->addr;
+}
+
 void intel_generic_uncore_msr_init_box(struct intel_uncore_box *box)
 {
-	wrmsrl(uncore_msr_box_ctl(box), GENERIC_PMON_BOX_CTL_INT);
+	wrmsrl(intel_generic_uncore_box_ctl(box), GENERIC_PMON_BOX_CTL_INT);
 }
 
 void intel_generic_uncore_msr_disable_box(struct intel_uncore_box *box)
 {
-	wrmsrl(uncore_msr_box_ctl(box), GENERIC_PMON_BOX_CTL_FRZ);
+	wrmsrl(intel_generic_uncore_box_ctl(box), GENERIC_PMON_BOX_CTL_FRZ);
 }
 
 void intel_generic_uncore_msr_enable_box(struct intel_uncore_box *box)
 {
-	wrmsrl(uncore_msr_box_ctl(box), 0);
+	wrmsrl(intel_generic_uncore_box_ctl(box), 0);
 }
 
 static void intel_generic_uncore_msr_enable_event(struct intel_uncore_box *box,
@@ -406,10 +479,47 @@
 	.read_counter		= uncore_msr_read_counter,
 };
 
+bool intel_generic_uncore_assign_hw_event(struct perf_event *event,
+					  struct intel_uncore_box *box)
+{
+	struct hw_perf_event *hwc = &event->hw;
+	u64 box_ctl;
+
+	if (!box->pmu->type->boxes)
+		return false;
+
+	if (box->io_addr) {
+		hwc->config_base = uncore_pci_event_ctl(box, hwc->idx);
+		hwc->event_base  = uncore_pci_perf_ctr(box, hwc->idx);
+		return true;
+	}
+
+	box_ctl = intel_generic_uncore_box_ctl(box);
+	if (!box_ctl)
+		return false;
+
+	if (box->pci_dev) {
+		box_ctl = UNCORE_DISCOVERY_PCI_BOX_CTRL(box_ctl);
+		hwc->config_base = box_ctl + uncore_pci_event_ctl(box, hwc->idx);
+		hwc->event_base  = box_ctl + uncore_pci_perf_ctr(box, hwc->idx);
+		return true;
+	}
+
+	hwc->config_base = box_ctl + box->pmu->type->event_ctl + hwc->idx;
+	hwc->event_base  = box_ctl + box->pmu->type->perf_ctr + hwc->idx;
+
+	return true;
+}
+
+static inline int intel_pci_uncore_box_ctl(struct intel_uncore_box *box)
+{
+	return UNCORE_DISCOVERY_PCI_BOX_CTRL(intel_generic_uncore_box_ctl(box));
+}
+
 void intel_generic_uncore_pci_init_box(struct intel_uncore_box *box)
 {
 	struct pci_dev *pdev = box->pci_dev;
-	int box_ctl = uncore_pci_box_ctl(box);
+	int box_ctl = intel_pci_uncore_box_ctl(box);
 
 	__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
 	pci_write_config_dword(pdev, box_ctl, GENERIC_PMON_BOX_CTL_INT);
@@ -418,7 +528,7 @@
 void intel_generic_uncore_pci_disable_box(struct intel_uncore_box *box)
 {
 	struct pci_dev *pdev = box->pci_dev;
-	int box_ctl = uncore_pci_box_ctl(box);
+	int box_ctl = intel_pci_uncore_box_ctl(box);
 
 	pci_write_config_dword(pdev, box_ctl, GENERIC_PMON_BOX_CTL_FRZ);
 }
@@ -426,7 +536,7 @@
 void intel_generic_uncore_pci_enable_box(struct intel_uncore_box *box)
 {
 	struct pci_dev *pdev = box->pci_dev;
-	int box_ctl = uncore_pci_box_ctl(box);
+	int box_ctl = intel_pci_uncore_box_ctl(box);
 
 	pci_write_config_dword(pdev, box_ctl, 0);
 }
@@ -473,34 +583,30 @@
 
 #define UNCORE_GENERIC_MMIO_SIZE		0x4000
 
-static u64 generic_uncore_mmio_box_ctl(struct intel_uncore_box *box)
-{
-	struct intel_uncore_type *type = box->pmu->type;
-
-	if (!type->box_ctls || !type->box_ctls[box->dieid] || !type->mmio_offsets)
-		return 0;
-
-	return type->box_ctls[box->dieid] + type->mmio_offsets[box->pmu->pmu_idx];
-}
-
 void intel_generic_uncore_mmio_init_box(struct intel_uncore_box *box)
 {
-	u64 box_ctl = generic_uncore_mmio_box_ctl(box);
+	static struct intel_uncore_discovery_unit *unit;
 	struct intel_uncore_type *type = box->pmu->type;
 	resource_size_t addr;
 
-	if (!box_ctl) {
+	unit = intel_uncore_find_discovery_unit(type->boxes, box->dieid, box->pmu->pmu_idx);
+	if (!unit) {
+		pr_warn("Uncore type %d id %d: Cannot find box control address.\n",
+			type->type_id, box->pmu->pmu_idx);
+		return;
+	}
+
+	if (!unit->addr) {
 		pr_warn("Uncore type %d box %d: Invalid box control address.\n",
-			type->type_id, type->box_ids[box->pmu->pmu_idx]);
+			type->type_id, unit->id);
 		return;
 	}
 
-	addr = box_ctl;
+	addr = unit->addr;
 	box->io_addr = ioremap(addr, UNCORE_GENERIC_MMIO_SIZE);
 	if (!box->io_addr) {
 		pr_warn("Uncore type %d box %d: ioremap error for 0x%llx.\n",
-			type->type_id, type->box_ids[box->pmu->pmu_idx],
-			(unsigned long long)addr);
+			type->type_id, unit->id, (unsigned long long)addr);
 		return;
 	}
 
@@ -560,34 +666,22 @@
 				      struct intel_uncore_discovery_type *type)
 {
 	uncore->type_id = type->type;
-	uncore->num_boxes = type->num_boxes;
 	uncore->num_counters = type->num_counters;
 	uncore->perf_ctr_bits = type->counter_width;
-	uncore->box_ids = type->ids;
+	uncore->perf_ctr = (unsigned int)type->ctr_offset;
+	uncore->event_ctl = (unsigned int)type->ctl_offset;
+	uncore->boxes = &type->units;
+	uncore->num_boxes = type->num_units;
 
 	switch (type_id) {
 	case UNCORE_ACCESS_MSR:
 		uncore->ops = &generic_uncore_msr_ops;
-		uncore->perf_ctr = (unsigned int)type->box_ctrl + type->ctr_offset;
-		uncore->event_ctl = (unsigned int)type->box_ctrl + type->ctl_offset;
-		uncore->box_ctl = (unsigned int)type->box_ctrl;
-		uncore->msr_offsets = type->box_offset;
 		break;
 	case UNCORE_ACCESS_PCI:
 		uncore->ops = &generic_uncore_pci_ops;
-		uncore->perf_ctr = (unsigned int)UNCORE_DISCOVERY_PCI_BOX_CTRL(type->box_ctrl) + type->ctr_offset;
-		uncore->event_ctl = (unsigned int)UNCORE_DISCOVERY_PCI_BOX_CTRL(type->box_ctrl) + type->ctl_offset;
-		uncore->box_ctl = (unsigned int)UNCORE_DISCOVERY_PCI_BOX_CTRL(type->box_ctrl);
-		uncore->box_ctls = type->box_ctrl_die;
-		uncore->pci_offsets = type->box_offset;
 		break;
 	case UNCORE_ACCESS_MMIO:
 		uncore->ops = &generic_uncore_mmio_ops;
-		uncore->perf_ctr = (unsigned int)type->ctr_offset;
-		uncore->event_ctl = (unsigned int)type->ctl_offset;
-		uncore->box_ctl = (unsigned int)type->box_ctrl;
-		uncore->box_ctls = type->box_ctrl_die;
-		uncore->mmio_offsets = type->box_offset;
 		uncore->mmio_map_size = UNCORE_GENERIC_MMIO_SIZE;
 		break;
 	default:
--- linux-qcom-6.8.0.orig/arch/x86/events/intel/uncore_discovery.h
+++ linux-qcom-6.8.0/arch/x86/events/intel/uncore_discovery.h
@@ -113,19 +113,24 @@
 	};
 };
 
+struct intel_uncore_discovery_unit {
+	struct rb_node	node;
+	unsigned int	pmu_idx;	/* The idx of the corresponding PMU */
+	unsigned int	id;		/* Unit ID */
+	unsigned int	die;		/* Die ID */
+	u64		addr;		/* Unit Control Address */
+};
+
 struct intel_uncore_discovery_type {
 	struct rb_node	node;
 	enum uncore_access_type	access_type;
-	u64		box_ctrl;	/* Unit ctrl addr of the first box */
-	u64		*box_ctrl_die;	/* Unit ctrl addr of the first box of each die */
+	struct rb_root	units;		/* Unit ctrl addr for all units */
 	u16		type;		/* Type ID of the uncore block */
 	u8		num_counters;
 	u8		counter_width;
 	u8		ctl_offset;	/* Counter Control 0 offset */
 	u8		ctr_offset;	/* Counter 0 offset */
-	u16		num_boxes;	/* number of boxes for the uncore block */
-	unsigned int	*ids;		/* Box IDs */
-	u64		*box_offset;	/* Box offset */
+	u16		num_units;	/* number of units */
 };
 
 bool intel_uncore_has_discovery_tables(int *ignore);
@@ -156,3 +161,10 @@
 
 struct intel_uncore_type **
 intel_uncore_generic_init_uncores(enum uncore_access_type type_id, int num_extra);
+
+int intel_uncore_find_discovery_unit_id(struct rb_root *units, int die,
+					unsigned int pmu_idx);
+bool intel_generic_uncore_assign_hw_event(struct perf_event *event,
+					  struct intel_uncore_box *box);
+void uncore_find_add_unit(struct intel_uncore_discovery_unit *node,
+			  struct rb_root *root, u16 *num_units);
--- linux-qcom-6.8.0.orig/arch/x86/events/intel/uncore_snbep.c
+++ linux-qcom-6.8.0/arch/x86/events/intel/uncore_snbep.c
@@ -461,6 +461,7 @@
 #define SPR_UBOX_DID				0x3250
 
 /* SPR CHA */
+#define SPR_CHA_EVENT_MASK_EXT			0xffffffff
 #define SPR_CHA_PMON_CTL_TID_EN			(1 << 16)
 #define SPR_CHA_PMON_EVENT_MASK			(SNBEP_PMON_RAW_EVENT_MASK | \
 						 SPR_CHA_PMON_CTL_TID_EN)
@@ -477,6 +478,7 @@
 DEFINE_UNCORE_FORMAT_ATTR(umask_ext2, umask, "config:8-15,32-57");
 DEFINE_UNCORE_FORMAT_ATTR(umask_ext3, umask, "config:8-15,32-39");
 DEFINE_UNCORE_FORMAT_ATTR(umask_ext4, umask, "config:8-15,32-55");
+DEFINE_UNCORE_FORMAT_ATTR(umask_ext5, umask, "config:8-15,32-63");
 DEFINE_UNCORE_FORMAT_ATTR(qor, qor, "config:16");
 DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
 DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
@@ -5932,10 +5934,11 @@
 	struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
 	bool tie_en = !!(event->hw.config & SPR_CHA_PMON_CTL_TID_EN);
 	struct intel_uncore_type *type = box->pmu->type;
+	int id = intel_uncore_find_discovery_unit_id(type->boxes, -1, box->pmu->pmu_idx);
 
 	if (tie_en) {
 		reg1->reg = SPR_C0_MSR_PMON_BOX_FILTER0 +
-			    HSWEP_CBO_MSR_OFFSET * type->box_ids[box->pmu->pmu_idx];
+			    HSWEP_CBO_MSR_OFFSET * id;
 		reg1->config = event->attr.config1 & SPR_CHA_PMON_BOX_FILTER_TID;
 		reg1->idx = 0;
 	}
@@ -5957,7 +5960,7 @@
 
 static struct attribute *spr_uncore_cha_formats_attr[] = {
 	&format_attr_event.attr,
-	&format_attr_umask_ext4.attr,
+	&format_attr_umask_ext5.attr,
 	&format_attr_tid_en2.attr,
 	&format_attr_edge.attr,
 	&format_attr_inv.attr,
@@ -5993,7 +5996,7 @@
 static struct intel_uncore_type spr_uncore_chabox = {
 	.name			= "cha",
 	.event_mask		= SPR_CHA_PMON_EVENT_MASK,
-	.event_mask_ext		= SPR_RAW_EVENT_MASK_EXT,
+	.event_mask_ext		= SPR_CHA_EVENT_MASK_EXT,
 	.num_shared_regs	= 1,
 	.constraints		= skx_uncore_chabox_constraints,
 	.ops			= &spr_uncore_chabox_ops,
@@ -6161,7 +6164,55 @@
 	.name			= "mdf",
 };
 
-#define UNCORE_SPR_NUM_UNCORE_TYPES		12
+static void spr_uncore_mmio_offs8_init_box(struct intel_uncore_box *box)
+{
+	__set_bit(UNCORE_BOX_FLAG_CTL_OFFS8, &box->flags);
+	intel_generic_uncore_mmio_init_box(box);
+}
+
+static struct intel_uncore_ops spr_uncore_mmio_offs8_ops = {
+	.init_box		= spr_uncore_mmio_offs8_init_box,
+	.exit_box		= uncore_mmio_exit_box,
+	.disable_box		= intel_generic_uncore_mmio_disable_box,
+	.enable_box		= intel_generic_uncore_mmio_enable_box,
+	.disable_event		= intel_generic_uncore_mmio_disable_event,
+	.enable_event		= spr_uncore_mmio_enable_event,
+	.read_counter		= uncore_mmio_read_counter,
+};
+
+#define SPR_UNCORE_MMIO_OFFS8_COMMON_FORMAT()			\
+	SPR_UNCORE_COMMON_FORMAT(),				\
+	.ops			= &spr_uncore_mmio_offs8_ops
+
+static struct event_constraint spr_uncore_cxlcm_constraints[] = {
+	UNCORE_EVENT_CONSTRAINT(0x02, 0x0f),
+	UNCORE_EVENT_CONSTRAINT(0x05, 0x0f),
+	UNCORE_EVENT_CONSTRAINT(0x40, 0xf0),
+	UNCORE_EVENT_CONSTRAINT(0x41, 0xf0),
+	UNCORE_EVENT_CONSTRAINT(0x42, 0xf0),
+	UNCORE_EVENT_CONSTRAINT(0x43, 0xf0),
+	UNCORE_EVENT_CONSTRAINT(0x4b, 0xf0),
+	UNCORE_EVENT_CONSTRAINT(0x52, 0xf0),
+	EVENT_CONSTRAINT_END
+};
+
+static struct intel_uncore_type spr_uncore_cxlcm = {
+	SPR_UNCORE_MMIO_OFFS8_COMMON_FORMAT(),
+	.name			= "cxlcm",
+	.constraints		= spr_uncore_cxlcm_constraints,
+};
+
+static struct intel_uncore_type spr_uncore_cxldp = {
+	SPR_UNCORE_MMIO_OFFS8_COMMON_FORMAT(),
+	.name			= "cxldp",
+};
+
+static struct intel_uncore_type spr_uncore_hbm = {
+	SPR_UNCORE_COMMON_FORMAT(),
+	.name			= "hbm",
+};
+
+#define UNCORE_SPR_NUM_UNCORE_TYPES		15
 #define UNCORE_SPR_CHA				0
 #define UNCORE_SPR_IIO				1
 #define UNCORE_SPR_IMC				6
@@ -6185,6 +6236,9 @@
 	NULL,
 	NULL,
 	&spr_uncore_mdf,
+	&spr_uncore_cxlcm,
+	&spr_uncore_cxldp,
+	&spr_uncore_hbm,
 };
 
 /*
@@ -6197,6 +6251,24 @@
 	0, 0x8000, 0x10000, 0x18000
 };
 
+static void spr_extra_boxes_cleanup(struct intel_uncore_type *type)
+{
+	struct intel_uncore_discovery_unit *pos;
+	struct rb_node *node;
+
+	if (!type->boxes)
+		return;
+
+	while (!RB_EMPTY_ROOT(type->boxes)) {
+		node = rb_first(type->boxes);
+		pos = rb_entry(node, struct intel_uncore_discovery_unit, node);
+		rb_erase(node, type->boxes);
+		kfree(pos);
+	}
+	kfree(type->boxes);
+	type->boxes = NULL;
+}
+
 static struct intel_uncore_type spr_uncore_upi = {
 	.event_mask		= SNBEP_PMON_RAW_EVENT_MASK,
 	.event_mask_ext		= SPR_RAW_EVENT_MASK_EXT,
@@ -6211,10 +6283,11 @@
 	.num_counters		= 4,
 	.num_boxes		= SPR_UNCORE_UPI_NUM_BOXES,
 	.perf_ctr_bits		= 48,
-	.perf_ctr		= ICX_UPI_PCI_PMON_CTR0,
-	.event_ctl		= ICX_UPI_PCI_PMON_CTL0,
+	.perf_ctr		= ICX_UPI_PCI_PMON_CTR0 - ICX_UPI_PCI_PMON_BOX_CTL,
+	.event_ctl		= ICX_UPI_PCI_PMON_CTL0 - ICX_UPI_PCI_PMON_BOX_CTL,
 	.box_ctl		= ICX_UPI_PCI_PMON_BOX_CTL,
 	.pci_offsets		= spr_upi_pci_offsets,
+	.cleanup_extra_boxes	= spr_extra_boxes_cleanup,
 };
 
 static struct intel_uncore_type spr_uncore_m3upi = {
@@ -6224,11 +6297,12 @@
 	.num_counters		= 4,
 	.num_boxes		= SPR_UNCORE_UPI_NUM_BOXES,
 	.perf_ctr_bits		= 48,
-	.perf_ctr		= ICX_M3UPI_PCI_PMON_CTR0,
-	.event_ctl		= ICX_M3UPI_PCI_PMON_CTL0,
+	.perf_ctr		= ICX_M3UPI_PCI_PMON_CTR0 - ICX_M3UPI_PCI_PMON_BOX_CTL,
+	.event_ctl		= ICX_M3UPI_PCI_PMON_CTL0 - ICX_M3UPI_PCI_PMON_BOX_CTL,
 	.box_ctl		= ICX_M3UPI_PCI_PMON_BOX_CTL,
 	.pci_offsets		= spr_upi_pci_offsets,
 	.constraints		= icx_uncore_m3upi_constraints,
+	.cleanup_extra_boxes	= spr_extra_boxes_cleanup,
 };
 
 enum perf_uncore_spr_iio_freerunning_type_id {
@@ -6459,18 +6533,21 @@
 static int uncore_type_max_boxes(struct intel_uncore_type **types,
 				 int type_id)
 {
+	struct intel_uncore_discovery_unit *unit;
 	struct intel_uncore_type *type;
-	int i, max = 0;
+	struct rb_node *node;
+	int max = 0;
 
 	type = uncore_find_type_by_id(types, type_id);
 	if (!type)
 		return 0;
 
-	for (i = 0; i < type->num_boxes; i++) {
-		if (type->box_ids[i] > max)
-			max = type->box_ids[i];
-	}
+	for (node = rb_first(type->boxes); node; node = rb_next(node)) {
+		unit = rb_entry(node, struct intel_uncore_discovery_unit, node);
 
+		if (unit->id > max)
+			max = unit->id;
+	}
 	return max + 1;
 }
 
@@ -6512,10 +6589,11 @@
 
 static void spr_update_device_location(int type_id)
 {
+	struct intel_uncore_discovery_unit *unit;
 	struct intel_uncore_type *type;
 	struct pci_dev *dev = NULL;
+	struct rb_root *root;
 	u32 device, devfn;
-	u64 *ctls;
 	int die;
 
 	if (type_id == UNCORE_SPR_UPI) {
@@ -6529,27 +6607,35 @@
 	} else
 		return;
 
-	ctls = kcalloc(__uncore_max_dies, sizeof(u64), GFP_KERNEL);
-	if (!ctls) {
+	root = kzalloc(sizeof(struct rb_root), GFP_KERNEL);
+	if (!root) {
 		type->num_boxes = 0;
 		return;
 	}
+	*root = RB_ROOT;
 
 	while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, dev)) != NULL) {
-		if (devfn != dev->devfn)
-			continue;
 
 		die = uncore_device_to_die(dev);
 		if (die < 0)
 			continue;
 
-		ctls[die] = pci_domain_nr(dev->bus) << UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET |
-			    dev->bus->number << UNCORE_DISCOVERY_PCI_BUS_OFFSET |
-			    devfn << UNCORE_DISCOVERY_PCI_DEVFN_OFFSET |
-			    type->box_ctl;
+		unit = kzalloc(sizeof(*unit), GFP_KERNEL);
+		if (!unit)
+			continue;
+		unit->die = die;
+		unit->id = PCI_SLOT(dev->devfn) - PCI_SLOT(devfn);
+		unit->addr = pci_domain_nr(dev->bus) << UNCORE_DISCOVERY_PCI_DOMAIN_OFFSET |
+			     dev->bus->number << UNCORE_DISCOVERY_PCI_BUS_OFFSET |
+			     devfn << UNCORE_DISCOVERY_PCI_DEVFN_OFFSET |
+			     type->box_ctl;
+
+		unit->pmu_idx = unit->id;
+
+		uncore_find_add_unit(unit, root, NULL);
 	}
 
-	type->box_ctls = ctls;
+	type->boxes = root;
 }
 
 int spr_uncore_pci_init(void)
@@ -6622,7 +6708,7 @@
 };
 
 static struct intel_uncore_type gnr_uncore_b2cxl = {
-	SPR_UNCORE_MMIO_COMMON_FORMAT(),
+	SPR_UNCORE_MMIO_OFFS8_COMMON_FORMAT(),
 	.name			= "b2cxl",
 };
 
--- linux-qcom-6.8.0.orig/arch/x86/events/perf_event.h
+++ linux-qcom-6.8.0/arch/x86/events/perf_event.h
@@ -684,9 +684,15 @@
 	cpumask_t			supported_cpus;
 	union perf_capabilities		intel_cap;
 	u64				intel_ctrl;
-	int				max_pebs_events;
-	int				num_counters;
-	int				num_counters_fixed;
+	u64				pebs_events_mask;
+	union {
+			u64		cntr_mask64;
+			unsigned long	cntr_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+	};
+	union {
+			u64		fixed_cntr_mask64;
+			unsigned long	fixed_cntr_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+	};
 	struct event_constraint		unconstrained;
 
 	u64				hw_cache_event_ids
@@ -774,8 +780,14 @@
 	int		(*rdpmc_index)(int index);
 	u64		(*event_map)(int);
 	int		max_events;
-	int		num_counters;
-	int		num_counters_fixed;
+	union {
+			u64		cntr_mask64;
+			unsigned long	cntr_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+	};
+	union {
+			u64		fixed_cntr_mask64;
+			unsigned long	fixed_cntr_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)];
+	};
 	int		cntval_bits;
 	u64		cntval_mask;
 	union {
@@ -852,7 +864,7 @@
 			pebs_ept		:1;
 	int		pebs_record_size;
 	int		pebs_buffer_size;
-	int		max_pebs_events;
+	u64		pebs_events_mask;
 	void		(*drain_pebs)(struct pt_regs *regs, struct perf_sample_data *data);
 	struct event_constraint *pebs_constraints;
 	void		(*pebs_aliases)(struct perf_event *event);
@@ -1125,8 +1137,8 @@
 	return x86_pmu.rdpmc_index ? x86_pmu.rdpmc_index(index) : index;
 }
 
-bool check_hw_exists(struct pmu *pmu, int num_counters,
-		     int num_counters_fixed);
+bool check_hw_exists(struct pmu *pmu, unsigned long *cntr_mask,
+		     unsigned long *fixed_cntr_mask);
 
 int x86_add_exclusive(unsigned int what);
 
@@ -1197,8 +1209,27 @@
 
 int x86_pmu_handle_irq(struct pt_regs *regs);
 
-void x86_pmu_show_pmu_cap(int num_counters, int num_counters_fixed,
-			  u64 intel_ctrl);
+void x86_pmu_show_pmu_cap(struct pmu *pmu);
+
+static inline int x86_pmu_num_counters(struct pmu *pmu)
+{
+	return hweight64(hybrid(pmu, cntr_mask64));
+}
+
+static inline int x86_pmu_max_num_counters(struct pmu *pmu)
+{
+	return fls64(hybrid(pmu, cntr_mask64));
+}
+
+static inline int x86_pmu_num_counters_fixed(struct pmu *pmu)
+{
+	return hweight64(hybrid(pmu, fixed_cntr_mask64));
+}
+
+static inline int x86_pmu_max_num_counters_fixed(struct pmu *pmu)
+{
+	return fls64(hybrid(pmu, fixed_cntr_mask64));
+}
 
 extern struct event_constraint emptyconstraint;
 
@@ -1648,6 +1679,17 @@
 	return !!(x86_pmu.flags & PMU_FL_EXCL_ENABLED);
 }
 
+static inline u64 intel_pmu_pebs_mask(u64 cntr_mask)
+{
+	return MAX_PEBS_EVENTS_MASK & cntr_mask;
+}
+
+static inline int intel_pmu_max_num_pebs(struct pmu *pmu)
+{
+	static_assert(MAX_PEBS_EVENTS == 32);
+	return fls((u32)hybrid(pmu, pebs_events_mask));
+}
+
 #else /* CONFIG_CPU_SUP_INTEL */
 
 static inline void reserve_ds_buffers(void)
--- linux-qcom-6.8.0.orig/arch/x86/events/zhaoxin/core.c
+++ linux-qcom-6.8.0/arch/x86/events/zhaoxin/core.c
@@ -530,13 +530,13 @@
 	pr_info("Version check pass!\n");
 
 	x86_pmu.version			= version;
-	x86_pmu.num_counters		= eax.split.num_counters;
+	x86_pmu.cntr_mask64		= GENMASK_ULL(eax.split.num_counters - 1, 0);
 	x86_pmu.cntval_bits		= eax.split.bit_width;
 	x86_pmu.cntval_mask		= (1ULL << eax.split.bit_width) - 1;
 	x86_pmu.events_maskl		= ebx.full;
 	x86_pmu.events_mask_len		= eax.split.mask_length;
 
-	x86_pmu.num_counters_fixed = edx.split.num_counters_fixed;
+	x86_pmu.fixed_cntr_mask64	= GENMASK_ULL(edx.split.num_counters_fixed - 1, 0);
 	x86_add_quirk(zhaoxin_arch_events_quirk);
 
 	switch (boot_cpu_data.x86) {
@@ -604,13 +604,13 @@
 		return -ENODEV;
 	}
 
-	x86_pmu.intel_ctrl = (1 << (x86_pmu.num_counters)) - 1;
-	x86_pmu.intel_ctrl |= ((1LL << x86_pmu.num_counters_fixed)-1) << INTEL_PMC_IDX_FIXED;
+	x86_pmu.intel_ctrl = x86_pmu.cntr_mask64;
+	x86_pmu.intel_ctrl |= x86_pmu.fixed_cntr_mask64 << INTEL_PMC_IDX_FIXED;
 
 	if (x86_pmu.event_constraints) {
 		for_each_event_constraint(c, x86_pmu.event_constraints) {
-			c->idxmsk64 |= (1ULL << x86_pmu.num_counters) - 1;
-			c->weight += x86_pmu.num_counters;
+			c->idxmsk64 |= x86_pmu.cntr_mask64;
+			c->weight += x86_pmu_num_counters(NULL);
 		}
 	}
 
--- linux-qcom-6.8.0.orig/arch/x86/hyperv/hv_init.c
+++ linux-qcom-6.8.0/arch/x86/hyperv/hv_init.c
@@ -35,7 +35,6 @@
 #include <clocksource/hyperv_timer.h>
 #include <linux/highmem.h>
 
-int hyperv_init_cpuhp;
 u64 hv_current_partition_id = ~0ull;
 EXPORT_SYMBOL_GPL(hv_current_partition_id);
 
@@ -607,8 +606,6 @@
 
 	register_syscore_ops(&hv_syscore_ops);
 
-	hyperv_init_cpuhp = cpuhp;
-
 	if (cpuid_ebx(HYPERV_CPUID_FEATURES) & HV_ACCESS_PARTITION_ID)
 		hv_get_partition_id();
 
@@ -637,7 +634,7 @@
 clean_guest_os_id:
 	wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
 	hv_ivm_msr_write(HV_X64_MSR_GUEST_OS_ID, 0);
-	cpuhp_remove_state(cpuhp);
+	cpuhp_remove_state(CPUHP_AP_HYPERV_ONLINE);
 free_ghcb_page:
 	free_percpu(hv_ghcb_pg);
 free_vp_assist_page:
--- linux-qcom-6.8.0.orig/arch/x86/hyperv/hv_vtl.c
+++ linux-qcom-6.8.0/arch/x86/hyperv/hv_vtl.c
@@ -12,6 +12,7 @@
 #include <asm/i8259.h>
 #include <asm/mshyperv.h>
 #include <asm/realmode.h>
+#include <../kernel/smpboot.h>
 
 extern struct boot_params boot_params;
 static struct real_mode_header hv_vtl_real_mode_header;
@@ -64,7 +65,7 @@
 	((secondary_startup_64_fn)secondary_startup_64)(&boot_params, &boot_params);
 }
 
-static int hv_vtl_bringup_vcpu(u32 target_vp_index, u64 eip_ignored)
+static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored)
 {
 	u64 status;
 	int ret = 0;
@@ -78,7 +79,9 @@
 	struct ldttss_desc *ldt;
 	struct desc_struct *gdt;
 
-	u64 rsp = current->thread.sp;
+	struct task_struct *idle = idle_thread_get(cpu);
+	u64 rsp = (unsigned long)idle->thread.sp;
+
 	u64 rip = (u64)&hv_vtl_ap_entry;
 
 	native_store_gdt(&gdt_ptr);
@@ -205,7 +208,15 @@
 
 static int hv_vtl_wakeup_secondary_cpu(u32 apicid, unsigned long start_eip)
 {
-	int vp_id;
+	int vp_id, cpu;
+
+	/* Find the logical CPU for the APIC ID */
+	for_each_present_cpu(cpu) {
+		if (arch_match_cpu_phys_id(cpu, apicid))
+			break;
+	}
+	if (cpu >= nr_cpu_ids)
+		return -EINVAL;
 
 	pr_debug("Bringing up CPU with APIC ID %d in VTL2...\n", apicid);
 	vp_id = hv_vtl_apicid_to_vp_id(apicid);
@@ -219,7 +230,7 @@
 		return -EINVAL;
 	}
 
-	return hv_vtl_bringup_vcpu(vp_id, start_eip);
+	return hv_vtl_bringup_vcpu(vp_id, cpu, start_eip);
 }
 
 int __init hv_vtl_early_init(void)
--- linux-qcom-6.8.0.orig/arch/x86/hyperv/ivm.c
+++ linux-qcom-6.8.0/arch/x86/hyperv/ivm.c
@@ -523,9 +523,9 @@
  * transition is complete, hv_vtom_set_host_visibility() marks the pages
  * as "present" again.
  */
-static bool hv_vtom_clear_present(unsigned long kbuffer, int pagecount, bool enc)
+static int hv_vtom_clear_present(unsigned long kbuffer, int pagecount, bool enc)
 {
-	return !set_memory_np(kbuffer, pagecount);
+	return set_memory_np(kbuffer, pagecount);
 }
 
 /*
@@ -536,20 +536,19 @@
  * with host. This function works as wrap of hv_mark_gpa_visibility()
  * with memory base and size.
  */
-static bool hv_vtom_set_host_visibility(unsigned long kbuffer, int pagecount, bool enc)
+static int hv_vtom_set_host_visibility(unsigned long kbuffer, int pagecount, bool enc)
 {
 	enum hv_mem_host_visibility visibility = enc ?
 			VMBUS_PAGE_NOT_VISIBLE : VMBUS_PAGE_VISIBLE_READ_WRITE;
 	u64 *pfn_array;
 	phys_addr_t paddr;
+	int i, pfn, err;
 	void *vaddr;
 	int ret = 0;
-	bool result = true;
-	int i, pfn;
 
 	pfn_array = kmalloc(HV_HYP_PAGE_SIZE, GFP_KERNEL);
 	if (!pfn_array) {
-		result = false;
+		ret = -ENOMEM;
 		goto err_set_memory_p;
 	}
 
@@ -568,10 +567,8 @@
 		if (pfn == HV_MAX_MODIFY_GPA_REP_COUNT || i == pagecount - 1) {
 			ret = hv_mark_gpa_visibility(pfn, pfn_array,
 						     visibility);
-			if (ret) {
-				result = false;
+			if (ret)
 				goto err_free_pfn_array;
-			}
 			pfn = 0;
 		}
 	}
@@ -586,10 +583,11 @@
 	 * order to avoid leaving the memory range in a "broken" state. Setting
 	 * the PRESENT bits shouldn't fail, but return an error if it does.
 	 */
-	if (set_memory_p(kbuffer, pagecount))
-		result = false;
+	err = set_memory_p(kbuffer, pagecount);
+	if (err && !ret)
+		ret = err;
 
-	return result;
+	return ret;
 }
 
 static bool hv_vtom_tlb_flush_required(bool private)
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/acpi.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/acpi.h
@@ -165,6 +165,14 @@
 void x86_default_set_root_pointer(u64 addr);
 u64 x86_default_get_root_pointer(void);
 
+#ifdef CONFIG_XEN_PV
+/* A Xen PV domain needs a special acpi_os_ioremap() handling. */
+extern void __iomem * (*acpi_os_ioremap)(acpi_physical_address phys,
+					 acpi_size size);
+void __iomem *x86_acpi_os_ioremap(acpi_physical_address phys, acpi_size size);
+#define acpi_os_ioremap acpi_os_ioremap
+#endif
+
 #else /* !CONFIG_ACPI */
 
 #define acpi_lapic 0
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/alternative.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/alternative.h
@@ -294,10 +294,10 @@
  * Otherwise, if CPU has feature1, newinstr1 is used.
  * Otherwise, oldinstr is used.
  */
-#define alternative_input_2(oldinstr, newinstr1, ft_flags1, newinstr2,	     \
-			   ft_flags2, input...)				     \
-	asm_inline volatile(ALTERNATIVE_2(oldinstr, newinstr1, ft_flags1,     \
-		newinstr2, ft_flags2)					     \
+#define alternative_input_2(oldinstr, newinstr1, ft_flags1, newinstr2,	\
+			   ft_flags2, input...)				\
+	asm_inline volatile(ALTERNATIVE_2(oldinstr, newinstr1, ft_flags1, \
+		newinstr2, ft_flags2)					\
 		: : "i" (0), ## input)
 
 /* Like alternative_input, but with a single output argument */
@@ -307,7 +307,7 @@
 
 /* Like alternative_io, but for replacing a direct call with another one. */
 #define alternative_call(oldfunc, newfunc, ft_flags, output, input...)	\
-	asm_inline volatile (ALTERNATIVE("call %P[old]", "call %P[new]", ft_flags) \
+	asm_inline volatile (ALTERNATIVE("call %c[old]", "call %c[new]", ft_flags) \
 		: output : [old] "i" (oldfunc), [new] "i" (newfunc), ## input)
 
 /*
@@ -316,12 +316,12 @@
  * Otherwise, if CPU has feature1, function1 is used.
  * Otherwise, old function is used.
  */
-#define alternative_call_2(oldfunc, newfunc1, ft_flags1, newfunc2, ft_flags2,   \
-			   output, input...)				      \
-	asm_inline volatile (ALTERNATIVE_2("call %P[old]", "call %P[new1]", ft_flags1,\
-		"call %P[new2]", ft_flags2)				      \
-		: output, ASM_CALL_CONSTRAINT				      \
-		: [old] "i" (oldfunc), [new1] "i" (newfunc1),		      \
+#define alternative_call_2(oldfunc, newfunc1, ft_flags1, newfunc2, ft_flags2, \
+			   output, input...)				\
+	asm_inline volatile (ALTERNATIVE_2("call %c[old]", "call %c[new1]", ft_flags1, \
+		"call %c[new2]", ft_flags2)				\
+		: output, ASM_CALL_CONSTRAINT				\
+		: [old] "i" (oldfunc), [new1] "i" (newfunc1),		\
 		  [new2] "i" (newfunc2), ## input)
 
 /*
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/amd_nb.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/amd_nb.h
@@ -116,7 +116,10 @@
 
 #define amd_nb_num(x)		0
 #define amd_nb_has_feature(x)	false
-#define node_to_amd_nb(x)	NULL
+static inline struct amd_northbridge *node_to_amd_nb(int node)
+{
+	return NULL;
+}
 #define amd_gart_present(x)	false
 
 #endif
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/apic.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/apic.h
@@ -13,6 +13,7 @@
 #include <asm/mpspec.h>
 #include <asm/msr.h>
 #include <asm/hardirq.h>
+#include <asm/io.h>
 
 #define ARCH_APICTIMER_STOPS_ON_C3	1
 
@@ -96,7 +97,7 @@
 
 static inline u32 native_apic_mem_read(u32 reg)
 {
-	return *((volatile u32 *)(APIC_BASE + reg));
+	return readl((void __iomem *)(APIC_BASE + reg));
 }
 
 static inline void native_apic_mem_eoi(void)
@@ -336,20 +337,12 @@
  * APIC drivers are probed based on how they are listed in the .apicdrivers
  * section. So the order is important and enforced by the ordering
  * of different apic driver files in the Makefile.
- *
- * For the files having two apic drivers, we use apic_drivers()
- * to enforce the order with in them.
  */
 #define apic_driver(sym)					\
 	static const struct apic *__apicdrivers_##sym __used		\
 	__aligned(sizeof(struct apic *))			\
 	__section(".apicdrivers") = { &sym }
 
-#define apic_drivers(sym1, sym2)					\
-	static struct apic *__apicdrivers_##sym1##sym2[2] __used	\
-	__aligned(sizeof(struct apic *))				\
-	__section(".apicdrivers") = { &sym1, &sym2 }
-
 extern struct apic *__apicdrivers[], *__apicdrivers_end[];
 
 /*
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/asm-prototypes.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/asm-prototypes.h
@@ -13,8 +13,12 @@
 #include <asm/preempt.h>
 #include <asm/asm.h>
 #include <asm/gsseg.h>
+#include <asm/nospec-branch.h>
 
 #ifndef CONFIG_X86_CMPXCHG64
 extern void cmpxchg8b_emu(void);
 #endif
 
+#if defined(__GENKSYMS__) && defined(CONFIG_STACKPROTECTOR)
+extern unsigned long __ref_stack_chk_guard;
+#endif
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/asm.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/asm.h
@@ -113,6 +113,20 @@
 
 #endif
 
+#ifndef __ASSEMBLY__
+#ifndef __pic__
+static __always_inline __pure void *rip_rel_ptr(void *p)
+{
+	asm("leaq %c1(%%rip), %0" : "=r"(p) : "i"(p));
+
+	return p;
+}
+#define RIP_REL_REF(var)	(*(typeof(&(var)))rip_rel_ptr(&(var)))
+#else
+#define RIP_REL_REF(var)	(var)
+#endif
+#endif
+
 /*
  * Macros to generate condition code outputs from inline assembly,
  * The output operand must be type "bool".
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/atomic64_32.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/atomic64_32.h
@@ -24,7 +24,7 @@
 
 #ifdef CONFIG_X86_CMPXCHG64
 #define __alternative_atomic64(f, g, out, in...) \
-	asm volatile("call %P[func]" \
+	asm volatile("call %c[func]" \
 		     : out : [func] "i" (atomic64_##g##_cx8), ## in)
 
 #define ATOMIC64_DECL(sym) ATOMIC64_DECL_ONE(sym##_cx8)
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/barrier.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/barrier.h
@@ -79,6 +79,9 @@
 #define __smp_mb__before_atomic()	do { } while (0)
 #define __smp_mb__after_atomic()	do { } while (0)
 
+/* Writing to CR3 provides a full memory barrier in switch_mm(). */
+#define smp_mb__after_switch_mm()	do { } while (0)
+
 #include <asm-generic/barrier.h>
 
 #endif /* _ASM_X86_BARRIER_H */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/boot.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/boot.h
@@ -81,6 +81,7 @@
 
 #ifndef __ASSEMBLY__
 extern unsigned int output_len;
+extern const unsigned long kernel_text_size;
 extern const unsigned long kernel_total_size;
 
 unsigned long decompress_kernel(unsigned char *outbuf, unsigned long virt_addr,
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/bug.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/bug.h
@@ -13,6 +13,18 @@
 #define INSN_UD2	0x0b0f
 #define LEN_UD2		2
 
+/*
+ * In clang we have UD1s reporting UBSAN failures on X86, 64 and 32bit.
+ */
+#define INSN_ASOP		0x67
+#define OPCODE_ESCAPE		0x0f
+#define SECOND_BYTE_OPCODE_UD1	0xb9
+#define SECOND_BYTE_OPCODE_UD2	0x0b
+
+#define BUG_NONE		0xffff
+#define BUG_UD1			0xfffe
+#define BUG_UD2			0xfffd
+
 #ifdef CONFIG_GENERIC_BUG
 
 #ifdef CONFIG_X86_32
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/cmpxchg_64.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/cmpxchg_64.h
@@ -62,7 +62,7 @@
 	asm volatile(_lock "cmpxchg16b %[ptr]"				\
 		     CC_SET(e)						\
 		     : CC_OUT(e) (ret),					\
-		       [ptr] "+m" (*ptr),				\
+		       [ptr] "+m" (*(_ptr)),				\
 		       "+a" (o.low), "+d" (o.high)			\
 		     : "b" (n.low), "c" (n.high)			\
 		     : "memory");					\
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/coco.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/coco.h
@@ -2,6 +2,7 @@
 #ifndef _ASM_X86_COCO_H
 #define _ASM_X86_COCO_H
 
+#include <asm/asm.h>
 #include <asm/types.h>
 
 enum cc_vendor {
@@ -12,11 +13,18 @@
 
 #ifdef CONFIG_ARCH_HAS_CC_PLATFORM
 extern enum cc_vendor cc_vendor;
-void cc_set_mask(u64 mask);
+extern u64 cc_mask;
+static inline void cc_set_mask(u64 mask)
+{
+	RIP_REL_REF(cc_mask) = mask;
+}
+
 u64 cc_mkenc(u64 val);
 u64 cc_mkdec(u64 val);
+void cc_random_init(void);
 #else
 #define cc_vendor (CC_VENDOR_NONE)
+static const u64 cc_mask = 0;
 
 static inline u64 cc_mkenc(u64 val)
 {
@@ -27,6 +35,7 @@
 {
 	return val;
 }
+static inline void cc_random_init(void) { }
 #endif
 
 #endif /* _ASM_X86_COCO_H */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/cpu_device_id.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/cpu_device_id.h
@@ -3,6 +3,39 @@
 #define _ASM_X86_CPU_DEVICE_ID
 
 /*
+ * Can't use <linux/bitfield.h> because it generates expressions that
+ * cannot be used in structure initializers. Bitfield construction
+ * here must match the union in struct cpuinfo_86:
+ *	union {
+ *		struct {
+ *			__u8	x86_model;
+ *			__u8	x86;
+ *			__u8	x86_vendor;
+ *			__u8	x86_reserved;
+ *		};
+ *		__u32		x86_vfm;
+ *	};
+ */
+#define VFM_MODEL_BIT	0
+#define VFM_FAMILY_BIT	8
+#define VFM_VENDOR_BIT	16
+#define VFM_RSVD_BIT	24
+
+#define	VFM_MODEL_MASK	GENMASK(VFM_FAMILY_BIT - 1, VFM_MODEL_BIT)
+#define	VFM_FAMILY_MASK	GENMASK(VFM_VENDOR_BIT - 1, VFM_FAMILY_BIT)
+#define	VFM_VENDOR_MASK	GENMASK(VFM_RSVD_BIT - 1, VFM_VENDOR_BIT)
+
+#define VFM_MODEL(vfm)	(((vfm) & VFM_MODEL_MASK) >> VFM_MODEL_BIT)
+#define VFM_FAMILY(vfm)	(((vfm) & VFM_FAMILY_MASK) >> VFM_FAMILY_BIT)
+#define VFM_VENDOR(vfm)	(((vfm) & VFM_VENDOR_MASK) >> VFM_VENDOR_BIT)
+
+#define	VFM_MAKE(_vendor, _family, _model) (	\
+	((_model) << VFM_MODEL_BIT) |		\
+	((_family) << VFM_FAMILY_BIT) |		\
+	((_vendor) << VFM_VENDOR_BIT)		\
+)
+
+/*
  * Declare drivers belonging to specific x86 CPUs
  * Similar in spirit to pci_device_id and related PCI functions
  *
@@ -20,6 +53,9 @@
 #define X86_CENTAUR_FAM6_C7_D		0xd
 #define X86_CENTAUR_FAM6_NANO		0xf
 
+/* x86_cpu_id::flags */
+#define X86_CPU_ID_FLAG_ENTRY_VALID	BIT(0)
+
 #define X86_STEPPINGS(mins, maxs)    GENMASK(maxs, mins)
 /**
  * X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching
@@ -46,6 +82,18 @@
 	.model		= _model,					\
 	.steppings	= _steppings,					\
 	.feature	= _feature,					\
+	.flags		= X86_CPU_ID_FLAG_ENTRY_VALID,			\
+	.driver_data	= (unsigned long) _data				\
+}
+
+#define X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE(_vendor, _family, _model, \
+						    _steppings, _feature, _data) { \
+	.vendor		= _vendor,					\
+	.family		= _family,					\
+	.model		= _model,					\
+	.steppings	= _steppings,					\
+	.feature	= _feature,					\
+	.flags		= X86_CPU_ID_FLAG_ENTRY_VALID,			\
 	.driver_data	= (unsigned long) _data				\
 }
 
@@ -164,6 +212,56 @@
 	X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(INTEL, 6, INTEL_FAM6_##model, \
 						     steppings, X86_FEATURE_ANY, data)
 
+/**
+ * X86_MATCH_VFM - Match encoded vendor/family/model
+ * @vfm:	Encoded 8-bits each for vendor, family, model
+ * @data:	Driver specific data or NULL. The internal storage
+ *		format is unsigned long. The supplied value, pointer
+ *		etc. is cast to unsigned long internally.
+ *
+ * Stepping and feature are set to wildcards
+ */
+#define X86_MATCH_VFM(vfm, data)			\
+	X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE(	\
+		VFM_VENDOR(vfm),			\
+		VFM_FAMILY(vfm),			\
+		VFM_MODEL(vfm),				\
+		X86_STEPPING_ANY, X86_FEATURE_ANY, data)
+
+/**
+ * X86_MATCH_VFM_STEPPINGS - Match encoded vendor/family/model/stepping
+ * @vfm:	Encoded 8-bits each for vendor, family, model
+ * @steppings:	Bitmask of steppings to match
+ * @data:	Driver specific data or NULL. The internal storage
+ *		format is unsigned long. The supplied value, pointer
+ *		etc. is cast to unsigned long internally.
+ *
+ * feature is set to wildcard
+ */
+#define X86_MATCH_VFM_STEPPINGS(vfm, steppings, data)	\
+	X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE(	\
+		VFM_VENDOR(vfm),			\
+		VFM_FAMILY(vfm),			\
+		VFM_MODEL(vfm),				\
+		steppings, X86_FEATURE_ANY, data)
+
+/**
+ * X86_MATCH_VFM_FEATURE - Match encoded vendor/family/model/feature
+ * @vfm:	Encoded 8-bits each for vendor, family, model
+ * @feature:	A X86_FEATURE bit
+ * @data:	Driver specific data or NULL. The internal storage
+ *		format is unsigned long. The supplied value, pointer
+ *		etc. is cast to unsigned long internally.
+ *
+ * Steppings is set to wildcard
+ */
+#define X86_MATCH_VFM_FEATURE(vfm, feature, data)	\
+	X86_MATCH_VENDORID_FAM_MODEL_STEPPINGS_FEATURE(	\
+		VFM_VENDOR(vfm),			\
+		VFM_FAMILY(vfm),			\
+		VFM_MODEL(vfm),				\
+		X86_STEPPING_ANY, feature, data)
+
 /*
  * Match specific microcode revisions.
  *
@@ -188,6 +286,14 @@
 	.x86_model		= (model),			\
 	.x86_stepping		= (stepping),			\
 	.x86_microcode_rev	= (revision),			\
+}
+
+#define AMD_CPU_DESC(fam, model, stepping, revision) {		\
+	.x86_family		= (fam),			\
+	.x86_vendor		= X86_VENDOR_AMD,		\
+	.x86_model		= (model),			\
+	.x86_stepping		= (stepping),			\
+	.x86_microcode_rev	= (revision),			\
 }
 
 extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match);
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/cpufeature.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/cpufeature.h
@@ -33,6 +33,8 @@
 	CPUID_7_EDX,
 	CPUID_8000_001F_EAX,
 	CPUID_8000_0021_EAX,
+	CPUID_LNX_5,
+	NR_CPUID_WORDS,
 };
 
 #define X86_CAP_FMT_NUM "%d:%d"
@@ -91,8 +93,9 @@
 	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 18, feature_bit) ||	\
 	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 19, feature_bit) ||	\
 	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 20, feature_bit) ||	\
+	   CHECK_BIT_IN_MASK_WORD(REQUIRED_MASK, 21, feature_bit) ||	\
 	   REQUIRED_MASK_CHECK					  ||	\
-	   BUILD_BUG_ON_ZERO(NCAPINTS != 21))
+	   BUILD_BUG_ON_ZERO(NCAPINTS != 22))
 
 #define DISABLED_MASK_BIT_SET(feature_bit)				\
 	 ( CHECK_BIT_IN_MASK_WORD(DISABLED_MASK,  0, feature_bit) ||	\
@@ -116,8 +119,9 @@
 	   CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 18, feature_bit) ||	\
 	   CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 19, feature_bit) ||	\
 	   CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 20, feature_bit) ||	\
+	   CHECK_BIT_IN_MASK_WORD(DISABLED_MASK, 21, feature_bit) ||	\
 	   DISABLED_MASK_CHECK					  ||	\
-	   BUILD_BUG_ON_ZERO(NCAPINTS != 21))
+	   BUILD_BUG_ON_ZERO(NCAPINTS != 22))
 
 #define cpu_has(c, bit)							\
 	(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 :	\
@@ -169,7 +173,7 @@
 static __always_inline bool _static_cpu_has(u16 bit)
 {
 	asm goto(
-		ALTERNATIVE_TERNARY("jmp 6f", %P[feature], "", "jmp %l[t_no]")
+		ALTERNATIVE_TERNARY("jmp 6f", %c[feature], "", "jmp %l[t_no]")
 		".pushsection .altinstr_aux,\"ax\"\n"
 		"6:\n"
 		" testb %[bitnum]," _ASM_RIP(%P[cap_byte]) "\n"
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/cpufeatures.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/cpufeatures.h
@@ -13,7 +13,7 @@
 /*
  * Defines x86 CPU feature bits
  */
-#define NCAPINTS			21	   /* N 32-bit words worth of info */
+#define NCAPINTS			22	   /* N 32-bit words worth of info */
 #define NBUGINTS			2	   /* N 32-bit bug flags */
 
 /*
@@ -215,7 +215,7 @@
 #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE	( 7*32+23) /* "" Disable Speculative Store Bypass. */
 #define X86_FEATURE_LS_CFG_SSBD		( 7*32+24)  /* "" AMD SSBD implementation via LS_CFG MSR */
 #define X86_FEATURE_IBRS		( 7*32+25) /* Indirect Branch Restricted Speculation */
-#define X86_FEATURE_IBPB		( 7*32+26) /* Indirect Branch Prediction Barrier */
+#define X86_FEATURE_IBPB		( 7*32+26) /* Indirect Branch Prediction Barrier without a guaranteed RSB flush */
 #define X86_FEATURE_STIBP		( 7*32+27) /* Single Thread Indirect Branch Predictors */
 #define X86_FEATURE_ZEN			( 7*32+28) /* "" Generic flag for all Zen and newer */
 #define X86_FEATURE_L1TF_PTEINV		( 7*32+29) /* "" L1TF workaround PTE inversion */
@@ -346,6 +346,7 @@
 #define X86_FEATURE_CPPC		(13*32+27) /* Collaborative Processor Performance Control */
 #define X86_FEATURE_AMD_PSFD            (13*32+28) /* "" Predictive Store Forwarding Disable */
 #define X86_FEATURE_BTC_NO		(13*32+29) /* "" Not vulnerable to Branch Type Confusion */
+#define X86_FEATURE_AMD_IBPB_RET	(13*32+30) /* IBPB clears return address predictor */
 #define X86_FEATURE_BRS			(13*32+31) /* Branch Sampling available */
 
 /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */
@@ -359,6 +360,7 @@
 #define X86_FEATURE_HWP_ACT_WINDOW	(14*32+ 9) /* HWP Activity Window */
 #define X86_FEATURE_HWP_EPP		(14*32+10) /* HWP Energy Perf. Preference */
 #define X86_FEATURE_HWP_PKG_REQ		(14*32+11) /* HWP Package Level Request */
+#define X86_FEATURE_HWP_HIGHEST_PERF_CHANGE (14*32+15) /* "" HWP Highest perf change */
 #define X86_FEATURE_HFI			(14*32+19) /* Hardware Feedback Interface */
 
 /* AMD SVM Feature Identification, CPUID level 0x8000000a (EDX), word 15 */
@@ -457,6 +459,17 @@
 #define X86_FEATURE_SRSO_NO		(20*32+29) /* "" CPU is not affected by SRSO */
 
 /*
+ * Extended auxiliary flags: Linux defined - for features scattered in various
+ * CPUID levels like 0x80000022, etc and Linux defined features.
+ *
+ * Reuse free bits when adding new feature flags!
+ */
+#define X86_FEATURE_CLEAR_BHB_LOOP	(21*32+ 1) /* "" Clear branch history at syscall entry using SW loop */
+#define X86_FEATURE_BHI_CTRL		(21*32+ 2) /* "" BHI_DIS_S HW control available */
+#define X86_FEATURE_CLEAR_BHB_HW	(21*32+ 3) /* "" BHI_DIS_S HW control enabled */
+#define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* "" Clear branch history at vmexit using SW loop */
+
+/*
  * BUG word(s)
  */
 #define X86_BUG(x)			(NCAPINTS*32 + (x))
@@ -503,4 +516,7 @@
 /* BUG word 2 */
 #define X86_BUG_SRSO			X86_BUG(1*32 + 0) /* AMD SRSO bug */
 #define X86_BUG_DIV0			X86_BUG(1*32 + 1) /* AMD DIV0 speculation bug */
+#define X86_BUG_RFDS			X86_BUG(1*32 + 2) /* CPU is vulnerable to Register File Data Sampling */
+#define X86_BUG_BHI			X86_BUG(1*32 + 3) /* CPU is affected by Branch History Injection */
+#define X86_BUG_IBPB_NO_RET	   	X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */
 #endif /* _ASM_X86_CPUFEATURES_H */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/crash_core.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/crash_core.h
@@ -39,4 +39,6 @@
 #endif
 }
 
+#define HAVE_ARCH_ADD_CRASH_RES_TO_IOMEM_EARLY
+
 #endif /* _X86_CRASH_CORE_H */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/disabled-features.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/disabled-features.h
@@ -143,6 +143,7 @@
 #define DISABLED_MASK18	(DISABLE_IBT)
 #define DISABLED_MASK19	0
 #define DISABLED_MASK20	0
-#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21)
+#define DISABLED_MASK21	0
+#define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22)
 
 #endif /* _ASM_X86_DISABLED_FEATURES_H */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/efi.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/efi.h
@@ -410,7 +410,6 @@
 				   struct efi_memory_map_data *data);
 extern void __efi_memmap_free(u64 phys, unsigned long size,
 			      unsigned long flags);
-#define __efi_memmap_free __efi_memmap_free
 
 extern int __init efi_memmap_install(struct efi_memory_map_data *data);
 extern int __init efi_memmap_split_count(efi_memory_desc_t *md,
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/entry-common.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/entry-common.h
@@ -73,19 +73,16 @@
 #endif
 
 	/*
-	 * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(),
-	 * but not enough for x86 stack utilization comfort. To keep
-	 * reasonable stack head room, reduce the maximum offset to 8 bits.
-	 *
-	 * The actual entropy will be further reduced by the compiler when
-	 * applying stack alignment constraints (see cc_stack_align4/8 in
+	 * This value will get limited by KSTACK_OFFSET_MAX(), which is 10
+	 * bits. The actual entropy will be further reduced by the compiler
+	 * when applying stack alignment constraints (see cc_stack_align4/8 in
 	 * arch/x86/Makefile), which will remove the 3 (x86_64) or 2 (ia32)
 	 * low bits from any entropy chosen here.
 	 *
-	 * Therefore, final stack offset entropy will be 5 (x86_64) or
-	 * 6 (ia32) bits.
+	 * Therefore, final stack offset entropy will be 7 (x86_64) or
+	 * 8 (ia32) bits.
 	 */
-	choose_random_kstack_offset(rdtsc() & 0xFF);
+	choose_random_kstack_offset(rdtsc());
 }
 #define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare
 
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/fpu/signal.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/fpu/signal.h
@@ -29,7 +29,7 @@
 
 unsigned long fpu__get_fpstate_size(void);
 
-extern bool copy_fpstate_to_sigframe(void __user *buf, void __user *fp, int size);
+extern bool copy_fpstate_to_sigframe(void __user *buf, void __user *fp, int size, u32 pkru);
 extern void fpu__clear_user_states(struct fpu *fpu);
 extern bool fpu__restore_sig(void __user *buf, int ia32_frame);
 
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/fpu/types.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/fpu/types.h
@@ -591,6 +591,13 @@
 	 * even without XSAVE support, i.e. legacy features FP + SSE
 	 */
 	u64 legacy_features;
+	/*
+	 * @independent_features:
+	 *
+	 * Features that are supported by XSAVES, but not managed as part of
+	 * the FPU core, such as LBR
+	 */
+	u64 independent_features;
 };
 
 /* FPU state configuration information */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/hardirq.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/hardirq.h
@@ -63,7 +63,11 @@
 #define local_softirq_pending_ref       pcpu_hot.softirq_pending
 
 #if IS_ENABLED(CONFIG_KVM_INTEL)
-static inline void kvm_set_cpu_l1tf_flush_l1d(void)
+/*
+ * This function is called from noinstr interrupt contexts
+ * and must be inlined to not get instrumentation.
+ */
+static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void)
 {
 	__this_cpu_write(irq_stat.kvm_cpu_l1tf_flush_l1d, 1);
 }
@@ -78,7 +82,7 @@
 	return __this_cpu_read(irq_stat.kvm_cpu_l1tf_flush_l1d);
 }
 #else /* !IS_ENABLED(CONFIG_KVM_INTEL) */
-static inline void kvm_set_cpu_l1tf_flush_l1d(void) { }
+static __always_inline void kvm_set_cpu_l1tf_flush_l1d(void) { }
 #endif /* IS_ENABLED(CONFIG_KVM_INTEL) */
 
 #endif /* _ASM_X86_HARDIRQ_H */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/idtentry.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/idtentry.h
@@ -13,15 +13,18 @@
 
 #include <asm/irq_stack.h>
 
+typedef void (*idtentry_t)(struct pt_regs *regs);
+
 /**
  * DECLARE_IDTENTRY - Declare functions for simple IDT entry points
  *		      No error code pushed by hardware
  * @vector:	Vector number (ignored for C)
  * @func:	Function name of the entry point
  *
- * Declares three functions:
+ * Declares four functions:
  * - The ASM entry point: asm_##func
  * - The XEN PV trap entry point: xen_##func (maybe unused)
+ * - The C handler called from the FRED event dispatcher (maybe unused)
  * - The C handler called from the ASM entry point
  *
  * Note: This is the C variant of DECLARE_IDTENTRY(). As the name says it
@@ -31,6 +34,7 @@
 #define DECLARE_IDTENTRY(vector, func)					\
 	asmlinkage void asm_##func(void);				\
 	asmlinkage void xen_asm_##func(void);				\
+	void fred_##func(struct pt_regs *regs);				\
 	__visible void func(struct pt_regs *regs)
 
 /**
@@ -138,6 +142,17 @@
 __visible noinstr void func(struct pt_regs *regs)
 
 /**
+ * DEFINE_FREDENTRY_RAW - Emit code for raw FRED entry points
+ * @func:	Function name of the entry point
+ *
+ * @func is called from the FRED event dispatcher with interrupts disabled.
+ *
+ * See @DEFINE_IDTENTRY_RAW for further details.
+ */
+#define DEFINE_FREDENTRY_RAW(func)					\
+noinstr void fred_##func(struct pt_regs *regs)
+
+/**
  * DECLARE_IDTENTRY_RAW_ERRORCODE - Declare functions for raw IDT entry points
  *				    Error code pushed by hardware
  * @vector:	Vector number (ignored for C)
@@ -197,8 +212,8 @@
 	irqentry_state_t state = irqentry_enter(regs);			\
 	u32 vector = (u32)(u8)error_code;				\
 									\
+	kvm_set_cpu_l1tf_flush_l1d();                                   \
 	instrumentation_begin();					\
-	kvm_set_cpu_l1tf_flush_l1d();					\
 	run_irq_on_irqstack_cond(__##func, regs, vector);		\
 	instrumentation_end();						\
 	irqentry_exit(regs, state);					\
@@ -233,17 +248,27 @@
 #define DEFINE_IDTENTRY_SYSVEC(func)					\
 static void __##func(struct pt_regs *regs);				\
 									\
+static __always_inline void instr_##func(struct pt_regs *regs)		\
+{									\
+	run_sysvec_on_irqstack_cond(__##func, regs);			\
+}									\
+									\
 __visible noinstr void func(struct pt_regs *regs)			\
 {									\
 	irqentry_state_t state = irqentry_enter(regs);			\
 									\
+	kvm_set_cpu_l1tf_flush_l1d();                                   \
 	instrumentation_begin();					\
-	kvm_set_cpu_l1tf_flush_l1d();					\
-	run_sysvec_on_irqstack_cond(__##func, regs);			\
+	instr_##func (regs);						\
 	instrumentation_end();						\
 	irqentry_exit(regs, state);					\
 }									\
 									\
+void fred_##func(struct pt_regs *regs)					\
+{									\
+	instr_##func (regs);						\
+}									\
+									\
 static noinline void __##func(struct pt_regs *regs)
 
 /**
@@ -260,19 +285,29 @@
 #define DEFINE_IDTENTRY_SYSVEC_SIMPLE(func)				\
 static __always_inline void __##func(struct pt_regs *regs);		\
 									\
+static __always_inline void instr_##func(struct pt_regs *regs)		\
+{									\
+	__irq_enter_raw();						\
+	__##func (regs);						\
+	__irq_exit_raw();						\
+}									\
+									\
 __visible noinstr void func(struct pt_regs *regs)			\
 {									\
 	irqentry_state_t state = irqentry_enter(regs);			\
 									\
+	kvm_set_cpu_l1tf_flush_l1d();                                   \
 	instrumentation_begin();					\
-	__irq_enter_raw();						\
-	kvm_set_cpu_l1tf_flush_l1d();					\
-	__##func (regs);						\
-	__irq_exit_raw();						\
+	instr_##func (regs);						\
 	instrumentation_end();						\
 	irqentry_exit(regs, state);					\
 }									\
 									\
+void fred_##func(struct pt_regs *regs)					\
+{									\
+	instr_##func (regs);						\
+}									\
+									\
 static __always_inline void __##func(struct pt_regs *regs)
 
 /**
@@ -410,15 +445,18 @@
 /* C-Code mapping */
 #define DECLARE_IDTENTRY_NMI		DECLARE_IDTENTRY_RAW
 #define DEFINE_IDTENTRY_NMI		DEFINE_IDTENTRY_RAW
+#define DEFINE_FREDENTRY_NMI		DEFINE_FREDENTRY_RAW
 
 #ifdef CONFIG_X86_64
 #define DECLARE_IDTENTRY_MCE		DECLARE_IDTENTRY_IST
 #define DEFINE_IDTENTRY_MCE		DEFINE_IDTENTRY_IST
 #define DEFINE_IDTENTRY_MCE_USER	DEFINE_IDTENTRY_NOIST
+#define DEFINE_FREDENTRY_MCE		DEFINE_FREDENTRY_RAW
 
 #define DECLARE_IDTENTRY_DEBUG		DECLARE_IDTENTRY_IST
 #define DEFINE_IDTENTRY_DEBUG		DEFINE_IDTENTRY_IST
 #define DEFINE_IDTENTRY_DEBUG_USER	DEFINE_IDTENTRY_NOIST
+#define DEFINE_FREDENTRY_DEBUG		DEFINE_FREDENTRY_RAW
 #endif
 
 #else /* !__ASSEMBLY__ */
@@ -655,23 +693,36 @@
 DECLARE_IDTENTRY_SYSVEC(REBOOT_VECTOR,			sysvec_reboot);
 DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_SINGLE_VECTOR,	sysvec_call_function_single);
 DECLARE_IDTENTRY_SYSVEC(CALL_FUNCTION_VECTOR,		sysvec_call_function);
+#else
+# define fred_sysvec_reschedule_ipi			NULL
+# define fred_sysvec_reboot				NULL
+# define fred_sysvec_call_function_single		NULL
+# define fred_sysvec_call_function			NULL
 #endif
 
 #ifdef CONFIG_X86_LOCAL_APIC
 # ifdef CONFIG_X86_MCE_THRESHOLD
 DECLARE_IDTENTRY_SYSVEC(THRESHOLD_APIC_VECTOR,		sysvec_threshold);
+# else
+# define fred_sysvec_threshold				NULL
 # endif
 
 # ifdef CONFIG_X86_MCE_AMD
 DECLARE_IDTENTRY_SYSVEC(DEFERRED_ERROR_VECTOR,		sysvec_deferred_error);
+# else
+# define fred_sysvec_deferred_error			NULL
 # endif
 
 # ifdef CONFIG_X86_THERMAL_VECTOR
 DECLARE_IDTENTRY_SYSVEC(THERMAL_APIC_VECTOR,		sysvec_thermal);
+# else
+# define fred_sysvec_thermal				NULL
 # endif
 
 # ifdef CONFIG_IRQ_WORK
 DECLARE_IDTENTRY_SYSVEC(IRQ_WORK_VECTOR,		sysvec_irq_work);
+# else
+# define fred_sysvec_irq_work				NULL
 # endif
 #endif
 
@@ -679,12 +730,16 @@
 DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_VECTOR,		sysvec_kvm_posted_intr_ipi);
 DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_WAKEUP_VECTOR,	sysvec_kvm_posted_intr_wakeup_ipi);
 DECLARE_IDTENTRY_SYSVEC(POSTED_INTR_NESTED_VECTOR,	sysvec_kvm_posted_intr_nested_ipi);
+#else
+# define fred_sysvec_kvm_posted_intr_ipi		NULL
+# define fred_sysvec_kvm_posted_intr_wakeup_ipi		NULL
+# define fred_sysvec_kvm_posted_intr_nested_ipi		NULL
 #endif
 
 #if IS_ENABLED(CONFIG_HYPERV)
 DECLARE_IDTENTRY_SYSVEC(HYPERVISOR_CALLBACK_VECTOR,	sysvec_hyperv_callback);
 DECLARE_IDTENTRY_SYSVEC(HYPERV_REENLIGHTENMENT_VECTOR,	sysvec_hyperv_reenlightenment);
-DECLARE_IDTENTRY_SYSVEC(HYPERV_STIMER0_VECTOR,	sysvec_hyperv_stimer0);
+DECLARE_IDTENTRY_SYSVEC(HYPERV_STIMER0_VECTOR,		sysvec_hyperv_stimer0);
 #endif
 
 #if IS_ENABLED(CONFIG_ACRN_GUEST)
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/intel-family.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/intel-family.h
@@ -40,136 +40,221 @@
  * their own names :-(
  */
 
+#define IFM(_fam, _model)	VFM_MAKE(X86_VENDOR_INTEL, _fam, _model)
+
 /* Wildcard match for FAM6 so X86_MATCH_INTEL_FAM6_MODEL(ANY) works */
 #define INTEL_FAM6_ANY			X86_MODEL_ANY
+/* Wildcard match for FAM6 so X86_MATCH_VFM(ANY) works */
+#define INTEL_ANY			IFM(X86_FAMILY_ANY, X86_MODEL_ANY)
 
 #define INTEL_FAM6_CORE_YONAH		0x0E
+#define INTEL_CORE_YONAH		IFM(6, 0x0E)
 
 #define INTEL_FAM6_CORE2_MEROM		0x0F
+#define INTEL_CORE2_MEROM		IFM(6, 0x0F)
 #define INTEL_FAM6_CORE2_MEROM_L	0x16
+#define INTEL_CORE2_MEROM_L		IFM(6, 0x16)
 #define INTEL_FAM6_CORE2_PENRYN		0x17
+#define INTEL_CORE2_PENRYN		IFM(6, 0x17)
 #define INTEL_FAM6_CORE2_DUNNINGTON	0x1D
+#define INTEL_CORE2_DUNNINGTON		IFM(6, 0x1D)
 
 #define INTEL_FAM6_NEHALEM		0x1E
+#define INTEL_NEHALEM			IFM(6, 0x1E)
 #define INTEL_FAM6_NEHALEM_G		0x1F /* Auburndale / Havendale */
+#define INTEL_NEHALEM_G			IFM(6, 0x1F) /* Auburndale / Havendale */
 #define INTEL_FAM6_NEHALEM_EP		0x1A
+#define INTEL_NEHALEM_EP		IFM(6, 0x1A)
 #define INTEL_FAM6_NEHALEM_EX		0x2E
+#define INTEL_NEHALEM_EX		IFM(6, 0x2E)
 
 #define INTEL_FAM6_WESTMERE		0x25
+#define INTEL_WESTMERE			IFM(6, 0x25)
 #define INTEL_FAM6_WESTMERE_EP		0x2C
+#define INTEL_WESTMERE_EP		IFM(6, 0x2C)
 #define INTEL_FAM6_WESTMERE_EX		0x2F
+#define INTEL_WESTMERE_EX		IFM(6, 0x2F)
 
 #define INTEL_FAM6_SANDYBRIDGE		0x2A
+#define INTEL_SANDYBRIDGE		IFM(6, 0x2A)
 #define INTEL_FAM6_SANDYBRIDGE_X	0x2D
+#define INTEL_SANDYBRIDGE_X		IFM(6, 0x2D)
 #define INTEL_FAM6_IVYBRIDGE		0x3A
+#define INTEL_IVYBRIDGE			IFM(6, 0x3A)
 #define INTEL_FAM6_IVYBRIDGE_X		0x3E
+#define INTEL_IVYBRIDGE_X		IFM(6, 0x3E)
 
 #define INTEL_FAM6_HASWELL		0x3C
+#define INTEL_HASWELL			IFM(6, 0x3C)
 #define INTEL_FAM6_HASWELL_X		0x3F
+#define INTEL_HASWELL_X			IFM(6, 0x3F)
 #define INTEL_FAM6_HASWELL_L		0x45
+#define INTEL_HASWELL_L			IFM(6, 0x45)
 #define INTEL_FAM6_HASWELL_G		0x46
+#define INTEL_HASWELL_G			IFM(6, 0x46)
 
 #define INTEL_FAM6_BROADWELL		0x3D
+#define INTEL_BROADWELL			IFM(6, 0x3D)
 #define INTEL_FAM6_BROADWELL_G		0x47
+#define INTEL_BROADWELL_G		IFM(6, 0x47)
 #define INTEL_FAM6_BROADWELL_X		0x4F
+#define INTEL_BROADWELL_X		IFM(6, 0x4F)
 #define INTEL_FAM6_BROADWELL_D		0x56
+#define INTEL_BROADWELL_D		IFM(6, 0x56)
 
 #define INTEL_FAM6_SKYLAKE_L		0x4E	/* Sky Lake             */
+#define INTEL_SKYLAKE_L			IFM(6, 0x4E) /* Sky Lake */
 #define INTEL_FAM6_SKYLAKE		0x5E	/* Sky Lake             */
+#define INTEL_SKYLAKE			IFM(6, 0x5E) /* Sky Lake */
 #define INTEL_FAM6_SKYLAKE_X		0x55	/* Sky Lake             */
+#define INTEL_SKYLAKE_X			IFM(6, 0x55) /* Sky Lake */
 /*                 CASCADELAKE_X	0x55	   Sky Lake -- s: 7     */
 /*                 COOPERLAKE_X		0x55	   Sky Lake -- s: 11    */
 
 #define INTEL_FAM6_KABYLAKE_L		0x8E	/* Sky Lake             */
+#define INTEL_KABYLAKE_L		IFM(6, 0x8E) /* Sky Lake */
 /*                 AMBERLAKE_L		0x8E	   Sky Lake -- s: 9     */
 /*                 COFFEELAKE_L		0x8E	   Sky Lake -- s: 10    */
 /*                 WHISKEYLAKE_L	0x8E       Sky Lake -- s: 11,12 */
 
 #define INTEL_FAM6_KABYLAKE		0x9E	/* Sky Lake             */
+#define INTEL_KABYLAKE			IFM(6, 0x9E) /* Sky Lake */
 /*                 COFFEELAKE		0x9E	   Sky Lake -- s: 10-13 */
 
 #define INTEL_FAM6_COMETLAKE		0xA5	/* Sky Lake             */
+#define INTEL_COMETLAKE			IFM(6, 0xA5) /* Sky Lake */
 #define INTEL_FAM6_COMETLAKE_L		0xA6	/* Sky Lake             */
+#define INTEL_COMETLAKE_L		IFM(6, 0xA6) /* Sky Lake */
 
 #define INTEL_FAM6_CANNONLAKE_L		0x66	/* Palm Cove */
+#define INTEL_CANNONLAKE_L		IFM(6, 0x66) /* Palm Cove */
 
 #define INTEL_FAM6_ICELAKE_X		0x6A	/* Sunny Cove */
+#define INTEL_ICELAKE_X			IFM(6, 0x6A) /* Sunny Cove */
 #define INTEL_FAM6_ICELAKE_D		0x6C	/* Sunny Cove */
+#define INTEL_ICELAKE_D			IFM(6, 0x6C) /* Sunny Cove */
 #define INTEL_FAM6_ICELAKE		0x7D	/* Sunny Cove */
+#define INTEL_ICELAKE			IFM(6, 0x7D) /* Sunny Cove */
 #define INTEL_FAM6_ICELAKE_L		0x7E	/* Sunny Cove */
+#define INTEL_ICELAKE_L			IFM(6, 0x7E) /* Sunny Cove */
 #define INTEL_FAM6_ICELAKE_NNPI		0x9D	/* Sunny Cove */
+#define INTEL_ICELAKE_NNPI		IFM(6, 0x9D) /* Sunny Cove */
 
 #define INTEL_FAM6_ROCKETLAKE		0xA7	/* Cypress Cove */
+#define INTEL_ROCKETLAKE		IFM(6, 0xA7) /* Cypress Cove */
 
 #define INTEL_FAM6_TIGERLAKE_L		0x8C	/* Willow Cove */
+#define INTEL_TIGERLAKE_L		IFM(6, 0x8C) /* Willow Cove */
 #define INTEL_FAM6_TIGERLAKE		0x8D	/* Willow Cove */
+#define INTEL_TIGERLAKE			IFM(6, 0x8D) /* Willow Cove */
 
 #define INTEL_FAM6_SAPPHIRERAPIDS_X	0x8F	/* Golden Cove */
+#define INTEL_SAPPHIRERAPIDS_X		IFM(6, 0x8F) /* Golden Cove */
 
 #define INTEL_FAM6_EMERALDRAPIDS_X	0xCF
+#define INTEL_EMERALDRAPIDS_X		IFM(6, 0xCF)
 
 #define INTEL_FAM6_GRANITERAPIDS_X	0xAD
+#define INTEL_GRANITERAPIDS_X		IFM(6, 0xAD)
 #define INTEL_FAM6_GRANITERAPIDS_D	0xAE
+#define INTEL_GRANITERAPIDS_D		IFM(6, 0xAE)
 
 /* "Hybrid" Processors (P-Core/E-Core) */
 
 #define INTEL_FAM6_LAKEFIELD		0x8A	/* Sunny Cove / Tremont */
+#define INTEL_LAKEFIELD			IFM(6, 0x8A) /* Sunny Cove / Tremont */
 
 #define INTEL_FAM6_ALDERLAKE		0x97	/* Golden Cove / Gracemont */
+#define INTEL_ALDERLAKE			IFM(6, 0x97) /* Golden Cove / Gracemont */
 #define INTEL_FAM6_ALDERLAKE_L		0x9A	/* Golden Cove / Gracemont */
+#define INTEL_ALDERLAKE_L		IFM(6, 0x9A) /* Golden Cove / Gracemont */
 
 #define INTEL_FAM6_RAPTORLAKE		0xB7	/* Raptor Cove / Enhanced Gracemont */
+#define INTEL_RAPTORLAKE		IFM(6, 0xB7) /* Raptor Cove / Enhanced Gracemont */
 #define INTEL_FAM6_RAPTORLAKE_P		0xBA
+#define INTEL_RAPTORLAKE_P		IFM(6, 0xBA)
 #define INTEL_FAM6_RAPTORLAKE_S		0xBF
+#define INTEL_RAPTORLAKE_S		IFM(6, 0xBF)
 
 #define INTEL_FAM6_METEORLAKE		0xAC
+#define INTEL_METEORLAKE		IFM(6, 0xAC)
 #define INTEL_FAM6_METEORLAKE_L		0xAA
+#define INTEL_METEORLAKE_L		IFM(6, 0xAA)
 
 #define INTEL_FAM6_ARROWLAKE_H		0xC5
+#define INTEL_ARROWLAKE_H		IFM(6, 0xC5)
 #define INTEL_FAM6_ARROWLAKE		0xC6
+#define INTEL_ARROWLAKE			IFM(6, 0xC6)
+#define INTEL_FAM6_ARROWLAKE_U		0xB5
+#define INTEL_ARROWLAKE_U		IFM(6, 0xB5)
 
 #define INTEL_FAM6_LUNARLAKE_M		0xBD
+#define INTEL_LUNARLAKE_M		IFM(6, 0xBD)
 
 /* "Small Core" Processors (Atom/E-Core) */
 
 #define INTEL_FAM6_ATOM_BONNELL		0x1C /* Diamondville, Pineview */
+#define INTEL_ATOM_BONNELL		IFM(6, 0x1C) /* Diamondville, Pineview */
 #define INTEL_FAM6_ATOM_BONNELL_MID	0x26 /* Silverthorne, Lincroft */
+#define INTEL_ATOM_BONNELL_MID		IFM(6, 0x26) /* Silverthorne, Lincroft */
 
 #define INTEL_FAM6_ATOM_SALTWELL	0x36 /* Cedarview */
+#define INTEL_ATOM_SALTWELL		IFM(6, 0x36) /* Cedarview */
 #define INTEL_FAM6_ATOM_SALTWELL_MID	0x27 /* Penwell */
+#define INTEL_ATOM_SALTWELL_MID		IFM(6, 0x27) /* Penwell */
 #define INTEL_FAM6_ATOM_SALTWELL_TABLET	0x35 /* Cloverview */
+#define INTEL_ATOM_SALTWELL_TABLET	IFM(6, 0x35) /* Cloverview */
 
 #define INTEL_FAM6_ATOM_SILVERMONT	0x37 /* Bay Trail, Valleyview */
+#define INTEL_ATOM_SILVERMONT		IFM(6, 0x37) /* Bay Trail, Valleyview */
 #define INTEL_FAM6_ATOM_SILVERMONT_D	0x4D /* Avaton, Rangely */
+#define INTEL_ATOM_SILVERMONT_D		IFM(6, 0x4D) /* Avaton, Rangely */
 #define INTEL_FAM6_ATOM_SILVERMONT_MID	0x4A /* Merriefield */
+#define INTEL_ATOM_SILVERMONT_MID	IFM(6, 0x4A) /* Merriefield */
 
 #define INTEL_FAM6_ATOM_AIRMONT		0x4C /* Cherry Trail, Braswell */
+#define INTEL_ATOM_AIRMONT		IFM(6, 0x4C) /* Cherry Trail, Braswell */
 #define INTEL_FAM6_ATOM_AIRMONT_MID	0x5A /* Moorefield */
+#define INTEL_ATOM_AIRMONT_MID		IFM(6, 0x5A) /* Moorefield */
 #define INTEL_FAM6_ATOM_AIRMONT_NP	0x75 /* Lightning Mountain */
+#define INTEL_ATOM_AIRMONT_NP		IFM(6, 0x75) /* Lightning Mountain */
 
 #define INTEL_FAM6_ATOM_GOLDMONT	0x5C /* Apollo Lake */
+#define INTEL_ATOM_GOLDMONT		IFM(6, 0x5C) /* Apollo Lake */
 #define INTEL_FAM6_ATOM_GOLDMONT_D	0x5F /* Denverton */
+#define INTEL_ATOM_GOLDMONT_D		IFM(6, 0x5F) /* Denverton */
 
 /* Note: the micro-architecture is "Goldmont Plus" */
 #define INTEL_FAM6_ATOM_GOLDMONT_PLUS	0x7A /* Gemini Lake */
+#define INTEL_ATOM_GOLDMONT_PLUS	IFM(6, 0x7A) /* Gemini Lake */
 
 #define INTEL_FAM6_ATOM_TREMONT_D	0x86 /* Jacobsville */
+#define INTEL_ATOM_TREMONT_D		IFM(6, 0x86) /* Jacobsville */
 #define INTEL_FAM6_ATOM_TREMONT		0x96 /* Elkhart Lake */
+#define INTEL_ATOM_TREMONT		IFM(6, 0x96) /* Elkhart Lake */
 #define INTEL_FAM6_ATOM_TREMONT_L	0x9C /* Jasper Lake */
+#define INTEL_ATOM_TREMONT_L		IFM(6, 0x9C) /* Jasper Lake */
 
 #define INTEL_FAM6_ATOM_GRACEMONT	0xBE /* Alderlake N */
+#define INTEL_ATOM_GRACEMONT		IFM(6, 0xBE) /* Alderlake N */
 
 #define INTEL_FAM6_ATOM_CRESTMONT_X	0xAF /* Sierra Forest */
+#define INTEL_ATOM_CRESTMONT_X		IFM(6, 0xAF) /* Sierra Forest */
 #define INTEL_FAM6_ATOM_CRESTMONT	0xB6 /* Grand Ridge */
+#define INTEL_ATOM_CRESTMONT		IFM(6, 0xB6) /* Grand Ridge */
 
 #define INTEL_FAM6_ATOM_DARKMONT_X	0xDD /* Clearwater Forest */
+#define INTEL_ATOM_DARKMONT_X		IFM(6, 0xDD) /* Clearwater Forest */
 
 /* Xeon Phi */
 
 #define INTEL_FAM6_XEON_PHI_KNL		0x57 /* Knights Landing */
+#define INTEL_XEON_PHI_KNL		IFM(6, 0x57) /* Knights Landing */
 #define INTEL_FAM6_XEON_PHI_KNM		0x85 /* Knights Mill */
+#define INTEL_XEON_PHI_KNM		IFM(6, 0x85) /* Knights Mill */
 
 /* Family 5 */
 #define INTEL_FAM5_QUARK_X1000		0x09 /* Quark X1000 SoC */
+#define INTEL_QUARK_X1000		IFM(5, 0x09) /* Quark X1000 SoC */
 
 #endif /* _ASM_X86_INTEL_FAMILY_H */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/intel_ds.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/intel_ds.h
@@ -9,6 +9,7 @@
 /* The maximal number of PEBS events: */
 #define MAX_PEBS_EVENTS_FMT4	8
 #define MAX_PEBS_EVENTS		32
+#define MAX_PEBS_EVENTS_MASK	GENMASK_ULL(MAX_PEBS_EVENTS - 1, 0)
 #define MAX_FIXED_PEBS_EVENTS	16
 
 /*
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/io.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/io.h
@@ -379,7 +379,7 @@
 	const u8 *end = from + count * 64;
 
 	while (from < end) {
-		movdir64b(dst, from);
+		movdir64b_io(dst, from);
 		from += 64;
 	}
 }
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/irq_stack.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/irq_stack.h
@@ -100,7 +100,7 @@
 }
 
 #define ASM_CALL_ARG0							\
-	"call %P[__func]				\n"		\
+	"call %c[__func]				\n"		\
 	ASM_REACHABLE
 
 #define ASM_CALL_ARG1							\
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/kexec.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/kexec.h
@@ -16,6 +16,7 @@
 # define PAGES_NR		4
 #endif
 
+# define KEXEC_CONTROL_PAGE_SIZE	4096
 # define KEXEC_CONTROL_CODE_MAX_SIZE	2048
 
 #ifndef __ASSEMBLY__
@@ -44,7 +45,6 @@
 /* Maximum address we can use for the control code buffer */
 # define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
 
-# define KEXEC_CONTROL_PAGE_SIZE	4096
 
 /* The native architecture */
 # define KEXEC_ARCH KEXEC_ARCH_386
@@ -59,9 +59,6 @@
 /* Maximum address we can use for the control pages */
 # define KEXEC_CONTROL_MEMORY_LIMIT     (MAXMEM-1)
 
-/* Allocate one page for the pdp and the second for the code */
-# define KEXEC_CONTROL_PAGE_SIZE  (4096UL + 4096UL)
-
 /* The native architecture */
 # define KEXEC_ARCH KEXEC_ARCH_X86_64
 #endif
@@ -146,6 +143,19 @@
 };
 #else
 struct kimage_arch {
+	/*
+	 * This is a kimage control page, as it must not overlap with either
+	 * source or destination address ranges.
+	 */
+	pgd_t *pgd;
+	/*
+	 * The virtual mapping of the control code page itself is used only
+	 * during the transition, while the current kernel's pages are all
+	 * in place. Thus the intermediate page table pages used to map it
+	 * are not control pages, but instead just normal pages obtained
+	 * with get_zeroed_page(). And have to be tracked (below) so that
+	 * they can be freed.
+	 */
 	p4d_t *p4d;
 	pud_t *pud;
 	pmd_t *pmd;
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/kvm_host.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/kvm_host.h
@@ -26,6 +26,8 @@
 #include <linux/irqbypass.h>
 #include <linux/hyperv.h>
 #include <linux/kfifo.h>
+#include <linux/sched/vhost_task.h>
+#include <linux/call_once.h>
 
 #include <asm/apic.h>
 #include <asm/pvclock-abi.h>
@@ -854,6 +856,7 @@
 	int cpuid_nent;
 	struct kvm_cpuid_entry2 *cpuid_entries;
 	struct kvm_hypervisor_cpuid kvm_cpuid;
+	bool is_amd_compatible;
 
 	/*
 	 * FIXME: Drop this macro and use KVM_NR_GOVERNED_FEATURES directly
@@ -1420,7 +1423,9 @@
 	bool sgx_provisioning_allowed;
 
 	struct kvm_x86_pmu_event_filter __rcu *pmu_event_filter;
-	struct task_struct *nx_huge_page_recovery_thread;
+	struct vhost_task *nx_huge_page_recovery_thread;
+	u64 nx_huge_page_last;
+	struct once nx_once;
 
 #ifdef CONFIG_X86_64
 	/* The number of TDP MMU pages across all roots. */
@@ -1693,11 +1698,13 @@
 	void (*enable_irq_window)(struct kvm_vcpu *vcpu);
 	void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr);
 	bool (*check_apicv_inhibit_reasons)(enum kvm_apicv_inhibit reason);
+
+	const bool x2apic_icr_is_split;
 	const unsigned long required_apicv_inhibits;
 	bool allow_apicv_in_x2apic_without_x2apic_virtualization;
 	void (*refresh_apicv_exec_ctrl)(struct kvm_vcpu *vcpu);
 	void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr);
-	void (*hwapic_isr_update)(int isr);
+	void (*hwapic_isr_update)(struct kvm_vcpu *vcpu, int isr);
 	bool (*guest_apic_has_interrupt)(struct kvm_vcpu *vcpu);
 	void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
 	void (*set_virtual_apic_mode)(struct kvm_vcpu *vcpu);
@@ -1803,7 +1810,7 @@
 	bool (*is_exception_vmexit)(struct kvm_vcpu *vcpu, u8 vector,
 				    u32 error_code);
 	int (*check_events)(struct kvm_vcpu *vcpu);
-	bool (*has_events)(struct kvm_vcpu *vcpu);
+	bool (*has_events)(struct kvm_vcpu *vcpu, bool for_injection);
 	void (*triple_fault)(struct kvm_vcpu *vcpu);
 	int (*get_state)(struct kvm_vcpu *vcpu,
 			 struct kvm_nested_state __user *user_kvm_nested_state,
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/mem_encrypt.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/mem_encrypt.h
@@ -15,7 +15,8 @@
 #include <linux/init.h>
 #include <linux/cc_platform.h>
 
-#include <asm/bootparam.h>
+#include <asm/asm.h>
+struct boot_params;
 
 #ifdef CONFIG_X86_MEM_ENCRYPT
 void __init mem_encrypt_init(void);
@@ -46,8 +47,8 @@
 
 void __init sme_early_init(void);
 
-void __init sme_encrypt_kernel(struct boot_params *bp);
-void __init sme_enable(struct boot_params *bp);
+void sme_encrypt_kernel(struct boot_params *bp);
+void sme_enable(struct boot_params *bp);
 
 int __init early_set_memory_decrypted(unsigned long vaddr, unsigned long size);
 int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size);
@@ -58,6 +59,11 @@
 
 void __init sev_es_init_vc_handling(void);
 
+static inline u64 sme_get_me_mask(void)
+{
+	return RIP_REL_REF(sme_me_mask);
+}
+
 #define __bss_decrypted __section(".bss..decrypted")
 
 #else	/* !CONFIG_AMD_MEM_ENCRYPT */
@@ -75,8 +81,8 @@
 
 static inline void __init sme_early_init(void) { }
 
-static inline void __init sme_encrypt_kernel(struct boot_params *bp) { }
-static inline void __init sme_enable(struct boot_params *bp) { }
+static inline void sme_encrypt_kernel(struct boot_params *bp) { }
+static inline void sme_enable(struct boot_params *bp) { }
 
 static inline void sev_es_init_vc_handling(void) { }
 
@@ -89,6 +95,8 @@
 
 static inline void mem_encrypt_free_decrypted_mem(void) { }
 
+static inline u64 sme_get_me_mask(void) { return 0; }
+
 #define __bss_decrypted
 
 #endif	/* CONFIG_AMD_MEM_ENCRYPT */
@@ -106,11 +114,6 @@
 
 extern char __start_bss_decrypted[], __end_bss_decrypted[], __start_bss_decrypted_unused[];
 
-static inline u64 sme_get_me_mask(void)
-{
-	return sme_me_mask;
-}
-
 #endif	/* __ASSEMBLY__ */
 
 #endif	/* __X86_MEM_ENCRYPT_H__ */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/mshyperv.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/mshyperv.h
@@ -40,7 +40,6 @@
 }
 
 #if IS_ENABLED(CONFIG_HYPERV)
-extern int hyperv_init_cpuhp;
 extern bool hyperv_paravisor_present;
 
 extern void *hv_hypercall_pg;
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/msr-index.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/msr-index.h
@@ -50,10 +50,13 @@
 #define SPEC_CTRL_SSBD			BIT(SPEC_CTRL_SSBD_SHIFT)	/* Speculative Store Bypass Disable */
 #define SPEC_CTRL_RRSBA_DIS_S_SHIFT	6	   /* Disable RRSBA behavior */
 #define SPEC_CTRL_RRSBA_DIS_S		BIT(SPEC_CTRL_RRSBA_DIS_S_SHIFT)
+#define SPEC_CTRL_BHI_DIS_S_SHIFT	10	   /* Disable Branch History Injection behavior */
+#define SPEC_CTRL_BHI_DIS_S		BIT(SPEC_CTRL_BHI_DIS_S_SHIFT)
 
 /* A mask for bits which the kernel toggles when controlling mitigations */
 #define SPEC_CTRL_MITIGATIONS_MASK	(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | SPEC_CTRL_SSBD \
-							| SPEC_CTRL_RRSBA_DIS_S)
+							| SPEC_CTRL_RRSBA_DIS_S \
+							| SPEC_CTRL_BHI_DIS_S)
 
 #define MSR_IA32_PRED_CMD		0x00000049 /* Prediction Command */
 #define PRED_CMD_IBPB			BIT(0)	   /* Indirect Branch Prediction Barrier */
@@ -152,6 +155,10 @@
 						 * are restricted to targets in
 						 * kernel.
 						 */
+#define ARCH_CAP_BHI_NO			BIT(20)	/*
+						 * CPU is not affected by Branch
+						 * History Injection.
+						 */
 #define ARCH_CAP_PBRSB_NO		BIT(24)	/*
 						 * Not susceptible to Post-Barrier
 						 * Return Stack Buffer Predictions.
@@ -165,6 +172,14 @@
 						 * CPU is not vulnerable to Gather
 						 * Data Sampling (GDS).
 						 */
+#define ARCH_CAP_RFDS_NO		BIT(27)	/*
+						 * Not susceptible to Register
+						 * File Data Sampling.
+						 */
+#define ARCH_CAP_RFDS_CLEAR		BIT(28)	/*
+						 * VERW clears CPU Register
+						 * File.
+						 */
 
 #define ARCH_CAP_XAPIC_DISABLE		BIT(21)	/*
 						 * IA32_XAPIC_DISABLE_STATUS MSR
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/nospec-branch.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/nospec-branch.h
@@ -271,11 +271,20 @@
 .Lskip_rsb_\@:
 .endm
 
+/*
+ * The CALL to srso_alias_untrain_ret() must be patched in directly at
+ * the spot where untraining must be done, ie., srso_alias_untrain_ret()
+ * must be the target of a CALL instruction instead of indirectly
+ * jumping to a wrapper which then calls it. Therefore, this macro is
+ * called outside of __UNTRAIN_RET below, for the time being, before the
+ * kernel can support nested alternatives with arbitrary nesting.
+ */
+.macro CALL_UNTRAIN_RET
 #if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO)
-#define CALL_UNTRAIN_RET	"call entry_untrain_ret"
-#else
-#define CALL_UNTRAIN_RET	""
+	ALTERNATIVE_2 "", "call entry_untrain_ret", X86_FEATURE_UNRET, \
+		          "call srso_alias_untrain_ret", X86_FEATURE_SRSO_ALIAS
 #endif
+.endm
 
 /*
  * Mitigate RETBleed for AMD/Hygon Zen uarch. Requires KERNEL CR3 because the
@@ -291,8 +300,8 @@
 .macro __UNTRAIN_RET ibpb_feature, call_depth_insns
 #if defined(CONFIG_RETHUNK) || defined(CONFIG_CPU_IBPB_ENTRY)
 	VALIDATE_UNRET_END
-	ALTERNATIVE_3 "",						\
-		      CALL_UNTRAIN_RET, X86_FEATURE_UNRET,		\
+	CALL_UNTRAIN_RET
+	ALTERNATIVE_2 "",						\
 		      "call entry_ibpb", \ibpb_feature,			\
 		     __stringify(\call_depth_insns), X86_FEATURE_CALL_DEPTH
 #endif
@@ -323,9 +332,31 @@
  * Note: Only the memory operand variant of VERW clears the CPU buffers.
  */
 .macro CLEAR_CPU_BUFFERS
-	ALTERNATIVE "", __stringify(verw _ASM_RIP(mds_verw_sel)), X86_FEATURE_CLEAR_CPU_BUF
+#ifdef CONFIG_X86_64
+	ALTERNATIVE "", "verw mds_verw_sel(%rip)", X86_FEATURE_CLEAR_CPU_BUF
+#else
+	/*
+	 * In 32bit mode, the memory operand must be a %cs reference. The data
+	 * segments may not be usable (vm86 mode), and the stack segment may not
+	 * be flat (ESPFIX32).
+	 */
+	ALTERNATIVE "", "verw %cs:mds_verw_sel", X86_FEATURE_CLEAR_CPU_BUF
+#endif
+.endm
+
+#ifdef CONFIG_X86_64
+.macro CLEAR_BRANCH_HISTORY
+	ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP
 .endm
 
+.macro CLEAR_BRANCH_HISTORY_VMEXIT
+	ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT
+.endm
+#else
+#define CLEAR_BRANCH_HISTORY
+#define CLEAR_BRANCH_HISTORY_VMEXIT
+#endif
+
 #else /* __ASSEMBLY__ */
 
 #define ANNOTATE_RETPOLINE_SAFE					\
@@ -351,6 +382,8 @@
 static inline void retbleed_return_thunk(void) {}
 #endif
 
+extern void srso_alias_untrain_ret(void);
+
 #ifdef CONFIG_CPU_SRSO
 extern void srso_return_thunk(void);
 extern void srso_alias_return_thunk(void);
@@ -366,6 +399,10 @@
 extern void entry_untrain_ret(void);
 extern void entry_ibpb(void);
 
+#ifdef CONFIG_X86_64
+extern void clear_bhb_loop(void);
+#endif
+
 extern void (*x86_return_thunk)(void);
 
 #ifdef CONFIG_CALL_DEPTH_TRACKING
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/page.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/page.h
@@ -66,10 +66,14 @@
  * virt_addr_valid(kaddr) returns true.
  */
 #define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-#define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
 extern bool __virt_addr_valid(unsigned long kaddr);
 #define virt_addr_valid(kaddr)	__virt_addr_valid((unsigned long) (kaddr))
 
+static __always_inline void *pfn_to_kaddr(unsigned long pfn)
+{
+	return __va(pfn << PAGE_SHIFT);
+}
+
 static __always_inline u64 __canonical_address(u64 vaddr, u8 vaddr_bits)
 {
 	return ((s64)vaddr << (64 - vaddr_bits)) >> (64 - vaddr_bits);
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/page_64.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/page_64.h
@@ -17,6 +17,7 @@
 extern unsigned long page_offset_base;
 extern unsigned long vmalloc_base;
 extern unsigned long vmemmap_base;
+extern unsigned long physmem_end;
 
 static __always_inline unsigned long __phys_addr_nodebug(unsigned long x)
 {
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/pci-direct.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/pci-direct.h
@@ -10,9 +10,11 @@
 extern u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset);
 extern u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset);
 extern u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset);
+extern u32 pci_early_find_cap(int bus, int slot, int func, int cap);
 extern void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, u32 val);
 extern void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val);
 extern void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val);
 
+extern unsigned int pci_early_clear_msi;
 extern int early_pci_allowed(void);
 #endif /* _ASM_X86_PCI_DIRECT_H */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/pgtable.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/pgtable.h
@@ -141,6 +141,11 @@
 	return pte_flags(pte) & _PAGE_ACCESSED;
 }
 
+static inline bool pte_decrypted(pte_t pte)
+{
+	return cc_mkdec(pte_val(pte)) == pte_val(pte);
+}
+
 #define pmd_dirty pmd_dirty
 static inline bool pmd_dirty(pmd_t pmd)
 {
@@ -388,23 +393,7 @@
 #ifdef CONFIG_HAVE_ARCH_USERFAULTFD_WP
 static inline int pte_uffd_wp(pte_t pte)
 {
-	bool wp = pte_flags(pte) & _PAGE_UFFD_WP;
-
-#ifdef CONFIG_DEBUG_VM
-	/*
-	 * Having write bit for wr-protect-marked present ptes is fatal,
-	 * because it means the uffd-wp bit will be ignored and write will
-	 * just go through.
-	 *
-	 * Use any chance of pgtable walking to verify this (e.g., when
-	 * page swapped out or being migrated for all purposes). It means
-	 * something is already wrong.  Tell the admin even before the
-	 * process crashes. We also nail it with wrong pgtable setup.
-	 */
-	WARN_ON_ONCE(wp && pte_write(pte));
-#endif
-
-	return wp;
+	return pte_flags(pte) & _PAGE_UFFD_WP;
 }
 
 static inline pte_t pte_mkuffd_wp(pte_t pte)
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/pgtable_64_types.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/pgtable_64_types.h
@@ -140,6 +140,10 @@
 # define VMEMMAP_START		__VMEMMAP_BASE_L4
 #endif /* CONFIG_DYNAMIC_MEMORY_LAYOUT */
 
+#ifdef CONFIG_RANDOMIZE_MEMORY
+# define PHYSMEM_END		physmem_end
+#endif
+
 /*
  * End of the region for which vmalloc page tables are pre-allocated.
  * For non-KMSAN builds, this is the same as VMALLOC_END.
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/pgtable_types.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/pgtable_types.h
@@ -36,10 +36,12 @@
 #define _PAGE_BIT_DEVMAP	_PAGE_BIT_SOFTW4
 
 #ifdef CONFIG_X86_64
-#define _PAGE_BIT_SAVED_DIRTY	_PAGE_BIT_SOFTW5 /* Saved Dirty bit */
+#define _PAGE_BIT_SAVED_DIRTY	_PAGE_BIT_SOFTW5 /* Saved Dirty bit (leaf) */
+#define _PAGE_BIT_NOPTISHADOW	_PAGE_BIT_SOFTW5 /* No PTI shadow (root PGD) */
 #else
 /* Shared with _PAGE_BIT_UFFD_WP which is not supported on 32 bit */
-#define _PAGE_BIT_SAVED_DIRTY	_PAGE_BIT_SOFTW2 /* Saved Dirty bit */
+#define _PAGE_BIT_SAVED_DIRTY	_PAGE_BIT_SOFTW2 /* Saved Dirty bit (leaf) */
+#define _PAGE_BIT_NOPTISHADOW	_PAGE_BIT_SOFTW2 /* No PTI shadow (root PGD) */
 #endif
 
 /* If _PAGE_BIT_PRESENT is clear, we use these: */
@@ -139,6 +141,8 @@
 
 #define _PAGE_PROTNONE	(_AT(pteval_t, 1) << _PAGE_BIT_PROTNONE)
 
+#define _PAGE_NOPTISHADOW (_AT(pteval_t, 1) << _PAGE_BIT_NOPTISHADOW)
+
 /*
  * Set of bits not changed in pte_modify.  The pte's
  * protection key is treated like _PAGE_RW, for
@@ -148,7 +152,7 @@
 #define _COMMON_PAGE_CHG_MASK	(PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT |	\
 				 _PAGE_SPECIAL | _PAGE_ACCESSED |	\
 				 _PAGE_DIRTY_BITS | _PAGE_SOFT_DIRTY |	\
-				 _PAGE_DEVMAP | _PAGE_ENC | _PAGE_UFFD_WP)
+				 _PAGE_DEVMAP | _PAGE_CC | _PAGE_UFFD_WP)
 #define _PAGE_CHG_MASK	(_COMMON_PAGE_CHG_MASK | _PAGE_PAT)
 #define _HPAGE_CHG_MASK (_COMMON_PAGE_CHG_MASK | _PAGE_PSE | _PAGE_PAT_LARGE)
 
@@ -173,6 +177,7 @@
 };
 #endif
 
+#define _PAGE_CC		(_AT(pteval_t, cc_mask))
 #define _PAGE_ENC		(_AT(pteval_t, sme_me_mask))
 
 #define _PAGE_CACHE_MASK	(_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)
@@ -566,6 +571,8 @@
 extern pte_t *lookup_address(unsigned long address, unsigned int *level);
 extern pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
 				    unsigned int *level);
+pte_t *lookup_address_in_pgd_attr(pgd_t *pgd, unsigned long address,
+				  unsigned int *level, bool *nx, bool *rw);
 extern pmd_t *lookup_pmd_address(unsigned long address);
 extern phys_addr_t slow_virt_to_phys(void *__address);
 extern int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn,
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/posted_intr.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/posted_intr.h
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _X86_POSTED_INTR_H
+#define _X86_POSTED_INTR_H
+
+#define POSTED_INTR_ON  0
+#define POSTED_INTR_SN  1
+
+#define PID_TABLE_ENTRY_VALID 1
+
+/* Posted-Interrupt Descriptor */
+struct pi_desc {
+	u32 pir[8];     /* Posted interrupt requested */
+	union {
+		struct {
+				/* bit 256 - Outstanding Notification */
+			u16	on	: 1,
+				/* bit 257 - Suppress Notification */
+				sn	: 1,
+				/* bit 271:258 - Reserved */
+				rsvd_1	: 14;
+				/* bit 279:272 - Notification Vector */
+			u8	nv;
+				/* bit 287:280 - Reserved */
+			u8	rsvd_2;
+				/* bit 319:288 - Notification Destination */
+			u32	ndst;
+		};
+		u64 control;
+	};
+	u32 rsvd[6];
+} __aligned(64);
+
+static inline bool pi_test_and_set_on(struct pi_desc *pi_desc)
+{
+	return test_and_set_bit(POSTED_INTR_ON, (unsigned long *)&pi_desc->control);
+}
+
+static inline bool pi_test_and_clear_on(struct pi_desc *pi_desc)
+{
+	return test_and_clear_bit(POSTED_INTR_ON, (unsigned long *)&pi_desc->control);
+}
+
+static inline bool pi_test_and_clear_sn(struct pi_desc *pi_desc)
+{
+	return test_and_clear_bit(POSTED_INTR_SN, (unsigned long *)&pi_desc->control);
+}
+
+static inline bool pi_test_and_set_pir(int vector, struct pi_desc *pi_desc)
+{
+	return test_and_set_bit(vector, (unsigned long *)pi_desc->pir);
+}
+
+static inline bool pi_is_pir_empty(struct pi_desc *pi_desc)
+{
+	return bitmap_empty((unsigned long *)pi_desc->pir, NR_VECTORS);
+}
+
+static inline void pi_set_sn(struct pi_desc *pi_desc)
+{
+	set_bit(POSTED_INTR_SN, (unsigned long *)&pi_desc->control);
+}
+
+static inline void pi_set_on(struct pi_desc *pi_desc)
+{
+	set_bit(POSTED_INTR_ON, (unsigned long *)&pi_desc->control);
+}
+
+static inline void pi_clear_on(struct pi_desc *pi_desc)
+{
+	clear_bit(POSTED_INTR_ON, (unsigned long *)&pi_desc->control);
+}
+
+static inline void pi_clear_sn(struct pi_desc *pi_desc)
+{
+	clear_bit(POSTED_INTR_SN, (unsigned long *)&pi_desc->control);
+}
+
+static inline bool pi_test_on(struct pi_desc *pi_desc)
+{
+	return test_bit(POSTED_INTR_ON, (unsigned long *)&pi_desc->control);
+}
+
+static inline bool pi_test_sn(struct pi_desc *pi_desc)
+{
+	return test_bit(POSTED_INTR_SN, (unsigned long *)&pi_desc->control);
+}
+
+#endif /* _X86_POSTED_INTR_H */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/processor.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/processor.h
@@ -106,9 +106,23 @@
 };
 
 struct cpuinfo_x86 {
-	__u8			x86;		/* CPU family */
-	__u8			x86_vendor;	/* CPU vendor */
-	__u8			x86_model;
+	union {
+		/*
+		 * The particular ordering (low-to-high) of (vendor,
+		 * family, model) is done in case range of models, like
+		 * it is usually done on AMD, need to be compared.
+		 */
+		struct {
+			__u8	x86_model;
+			/* CPU family */
+			__u8	x86;
+			/* CPU vendor */
+			__u8	x86_vendor;
+			__u8	x86_reserved;
+		};
+		/* combined vendor, family, model */
+		__u32		x86_vfm;
+	};
 	__u8			x86_stepping;
 #ifdef CONFIG_X86_64
 	/* Number of 4K pages in DTLB/ITLB combined(in pages): */
@@ -205,6 +219,8 @@
 	return BIT_ULL(boot_cpu_data.x86_cache_bits - 1 - PAGE_SHIFT);
 }
 
+void init_cpu_devs(void);
+void get_cpu_vendor(struct cpuinfo_x86 *c);
 extern void early_cpu_init(void);
 extern void identify_secondary_cpu(struct cpuinfo_x86 *);
 extern void print_cpu_info(struct cpuinfo_x86 *);
@@ -479,7 +495,6 @@
 	unsigned long		iopl_emul;
 
 	unsigned int		iopl_warn:1;
-	unsigned int		sig_on_uaccess_err:1;
 
 	/*
 	 * Protection Keys Register for Userspace.  Loaded immediately on
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/ptrace.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/ptrace.h
@@ -56,18 +56,64 @@
 
 #else /* __i386__ */
 
+struct fred_cs {
+		/* CS selector */
+	u64	cs	: 16,
+		/* Stack level at event time */
+		sl	:  2,
+		/* IBT in WAIT_FOR_ENDBRANCH state */
+		wfe	:  1,
+			: 45;
+};
+
+struct fred_ss {
+		/* SS selector */
+	u64	ss	: 16,
+		/* STI state */
+		sti	:  1,
+		/* Set if syscall, sysenter or INT n */
+		swevent	:  1,
+		/* Event is NMI type */
+		nmi	:  1,
+			: 13,
+		/* Event vector */
+		vector	:  8,
+			:  8,
+		/* Event type */
+		type	:  4,
+			:  4,
+		/* Event was incident to enclave execution */
+		enclave	:  1,
+		/* CPU was in long mode */
+		lm	:  1,
+		/*
+		 * Nested exception during FRED delivery, not set
+		 * for #DF.
+		 */
+		nested	:  1,
+			:  1,
+		/*
+		 * The length of the instruction causing the event.
+		 * Only set for INTO, INT1, INT3, INT n, SYSCALL
+		 * and SYSENTER.  0 otherwise.
+		 */
+		insnlen	:  4;
+};
+
 struct pt_regs {
-/*
- * C ABI says these regs are callee-preserved. They aren't saved on kernel entry
- * unless syscall needs a complete, fully filled "struct pt_regs".
- */
+	/*
+	 * C ABI says these regs are callee-preserved. They aren't saved on
+	 * kernel entry unless syscall needs a complete, fully filled
+	 * "struct pt_regs".
+	 */
 	unsigned long r15;
 	unsigned long r14;
 	unsigned long r13;
 	unsigned long r12;
 	unsigned long bp;
 	unsigned long bx;
-/* These regs are callee-clobbered. Always saved on kernel entry. */
+
+	/* These regs are callee-clobbered. Always saved on kernel entry. */
 	unsigned long r11;
 	unsigned long r10;
 	unsigned long r9;
@@ -77,18 +123,50 @@
 	unsigned long dx;
 	unsigned long si;
 	unsigned long di;
-/*
- * On syscall entry, this is syscall#. On CPU exception, this is error code.
- * On hw interrupt, it's IRQ number:
- */
+
+	/*
+	 * orig_ax is used on entry for:
+	 * - the syscall number (syscall, sysenter, int80)
+	 * - error_code stored by the CPU on traps and exceptions
+	 * - the interrupt number for device interrupts
+	 *
+	 * A FRED stack frame starts here:
+	 *   1) It _always_ includes an error code;
+	 *
+	 *   2) The return frame for ERET[US] starts here, but
+	 *      the content of orig_ax is ignored.
+	 */
 	unsigned long orig_ax;
-/* Return frame for iretq */
+
+	/* The IRETQ return frame starts here */
 	unsigned long ip;
-	unsigned long cs;
+
+	union {
+		/* CS selector */
+		u16		cs;
+		/* The extended 64-bit data slot containing CS */
+		u64		csx;
+		/* The FRED CS extension */
+		struct fred_cs	fred_cs;
+	};
+
 	unsigned long flags;
 	unsigned long sp;
-	unsigned long ss;
-/* top of stack page */
+
+	union {
+		/* SS selector */
+		u16		ss;
+		/* The extended 64-bit data slot containing SS */
+		u64		ssx;
+		/* The FRED SS extension */
+		struct fred_ss	fred_ss;
+	};
+
+	/*
+	 * Top of stack on IDT systems, while FRED systems have extra fields
+	 * defined above for storing exception related information, e.g. CR2 or
+	 * DR6.
+	 */
 };
 
 #endif /* !__i386__ */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/qspinlock.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/qspinlock.h
@@ -66,13 +66,15 @@
 
 #ifdef CONFIG_PARAVIRT
 /*
- * virt_spin_lock_key - enables (by default) the virt_spin_lock() hijack.
+ * virt_spin_lock_key - disables by default the virt_spin_lock() hijack.
  *
- * Native (and PV wanting native due to vCPU pinning) should disable this key.
- * It is done in this backwards fashion to only have a single direction change,
- * which removes ordering between native_pv_spin_init() and HV setup.
+ * Native (and PV wanting native due to vCPU pinning) should keep this key
+ * disabled. Native does not touch the key.
+ *
+ * When in a guest then native_pv_lock_init() enables the key first and
+ * KVM/XEN might conditionally disable it later in the boot process again.
  */
-DECLARE_STATIC_KEY_TRUE(virt_spin_lock_key);
+DECLARE_STATIC_KEY_FALSE(virt_spin_lock_key);
 
 /*
  * Shortcut for the queued_spin_lock_slowpath() function that allows
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/required-features.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/required-features.h
@@ -99,6 +99,7 @@
 #define REQUIRED_MASK18	0
 #define REQUIRED_MASK19	0
 #define REQUIRED_MASK20	0
-#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 21)
+#define REQUIRED_MASK21	0
+#define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 22)
 
 #endif /* _ASM_X86_REQUIRED_FEATURES_H */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/set_memory.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/set_memory.h
@@ -49,8 +49,11 @@
 int set_memory_np(unsigned long addr, int numpages);
 int set_memory_p(unsigned long addr, int numpages);
 int set_memory_4k(unsigned long addr, int numpages);
+
+bool set_memory_enc_stop_conversion(void);
 int set_memory_encrypted(unsigned long addr, int numpages);
 int set_memory_decrypted(unsigned long addr, int numpages);
+
 int set_memory_np_noalias(unsigned long addr, int numpages);
 int set_memory_nonglobal(unsigned long addr, int numpages);
 int set_memory_global(unsigned long addr, int numpages);
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/sev.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/sev.h
@@ -199,16 +199,16 @@
 struct snp_guest_request_ioctl;
 
 void setup_ghcb(void);
-void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr,
-					 unsigned long npages);
-void __init early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr,
-					unsigned long npages);
-void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op);
+void early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr,
+				  unsigned long npages);
+void early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr,
+				 unsigned long npages);
 void snp_set_memory_shared(unsigned long vaddr, unsigned long npages);
 void snp_set_memory_private(unsigned long vaddr, unsigned long npages);
 void snp_set_wakeup_secondary_cpu(void);
 bool snp_init(struct boot_params *bp);
-void __init __noreturn snp_abort(void);
+void __noreturn snp_abort(void);
+void snp_dmi_setup(void);
 int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio);
 void snp_accept_memory(phys_addr_t start, phys_addr_t end);
 u64 snp_get_unsupported_features(u64 status);
@@ -227,12 +227,12 @@
 early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, unsigned long npages) { }
 static inline void __init
 early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, unsigned long npages) { }
-static inline void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op) { }
 static inline void snp_set_memory_shared(unsigned long vaddr, unsigned long npages) { }
 static inline void snp_set_memory_private(unsigned long vaddr, unsigned long npages) { }
 static inline void snp_set_wakeup_secondary_cpu(void) { }
 static inline bool snp_init(struct boot_params *bp) { return false; }
 static inline void snp_abort(void) { }
+static inline void snp_dmi_setup(void) { }
 static inline int snp_issue_guest_request(u64 exit_code, struct snp_req_data *input, struct snp_guest_request_ioctl *rio)
 {
 	return -ENOTTY;
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/shared/tdx.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/shared/tdx.h
@@ -16,11 +16,20 @@
 #define TDG_VP_VEINFO_GET		3
 #define TDG_MR_REPORT			4
 #define TDG_MEM_PAGE_ACCEPT		6
+#define TDG_VM_RD			7
 #define TDG_VM_WR			8
 
-/* TDCS fields. To be used by TDG.VM.WR and TDG.VM.RD module calls */
+/* TDX TD-Scope Metadata. To be used by TDG.VM.WR and TDG.VM.RD */
+#define TDCS_CONFIG_FLAGS		0x1110000300000016
+#define TDCS_TD_CTLS			0x1110000300000017
 #define TDCS_NOTIFY_ENABLES		0x9100000000000010
 
+/* TDCS_CONFIG_FLAGS bits */
+#define TDCS_CONFIG_FLEXIBLE_PENDING_VE	BIT_ULL(1)
+
+/* TDCS_TD_CTLS bits */
+#define TD_CTLS_PENDING_VE_DISABLE	BIT_ULL(0)
+
 /* TDX hypercall Leaf IDs */
 #define TDVMCALL_MAP_GPA		0x10001
 #define TDVMCALL_GET_QUOTE		0x10002
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/shstk.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/shstk.h
@@ -21,6 +21,7 @@
 void shstk_free(struct task_struct *p);
 int setup_signal_shadow_stack(struct ksignal *ksig);
 int restore_signal_shadow_stack(void);
+int shstk_update_last_frame(unsigned long val);
 #else
 static inline long shstk_prctl(struct task_struct *task, int option,
 			       unsigned long arg2) { return -EINVAL; }
@@ -31,6 +32,7 @@
 static inline void shstk_free(struct task_struct *p) {}
 static inline int setup_signal_shadow_stack(struct ksignal *ksig) { return 0; }
 static inline int restore_signal_shadow_stack(void) { return 0; }
+static inline int shstk_update_last_frame(unsigned long val) { return 0; }
 #endif /* CONFIG_X86_USER_SHADOW_STACK */
 
 #endif /* __ASSEMBLY__ */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/sparsemem.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/sparsemem.h
@@ -37,8 +37,6 @@
 #define phys_to_target_node phys_to_target_node
 extern int memory_add_physaddr_to_nid(u64 start);
 #define memory_add_physaddr_to_nid memory_add_physaddr_to_nid
-extern int numa_fill_memblks(u64 start, u64 end);
-#define numa_fill_memblks numa_fill_memblks
 #endif
 #endif /* __ASSEMBLY__ */
 
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/special_insns.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/special_insns.h
@@ -217,17 +217,17 @@
 
 #define nop() asm volatile ("nop")
 
-static inline void serialize(void)
+static __always_inline void serialize(void)
 {
 	/* Instruction opcode for SERIALIZE; supported in binutils >= 2.35. */
 	asm volatile(".byte 0xf, 0x1, 0xe8" ::: "memory");
 }
 
 /* The dst parameter must be 64-bytes aligned */
-static inline void movdir64b(void __iomem *dst, const void *src)
+static inline void movdir64b(void *dst, const void *src)
 {
 	const struct { char _[64]; } *__src = src;
-	struct { char _[64]; } __iomem *__dst = dst;
+	struct { char _[64]; } *__dst = dst;
 
 	/*
 	 * MOVDIR64B %(rdx), rax.
@@ -245,6 +245,11 @@
 		     :  "m" (*__src), "a" (__dst), "d" (__src));
 }
 
+static inline void movdir64b_io(void __iomem *dst, const void *src)
+{
+	movdir64b((void __force *)dst, src);
+}
+
 /**
  * enqcmds - Enqueue a command in supervisor (CPL0) mode
  * @dst: destination, in MMIO space (must be 512-bit aligned)
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/static_call.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/static_call.h
@@ -65,4 +65,19 @@
 
 extern bool __static_call_fixup(void *tramp, u8 op, void *dest);
 
+extern void __static_call_update_early(void *tramp, void *func);
+
+#define static_call_update_early(name, _func)				\
+({									\
+	typeof(&STATIC_CALL_TRAMP(name)) __F = (_func);			\
+	if (static_call_initialized) {					\
+		__static_call_update(&STATIC_CALL_KEY(name),		\
+				     STATIC_CALL_TRAMP_ADDR(name), __F);\
+	} else {							\
+		WRITE_ONCE(STATIC_CALL_KEY(name).func, _func);		\
+		__static_call_update_early(STATIC_CALL_TRAMP_ADDR(name),\
+					   __F);			\
+	}								\
+})
+
 #endif /* _ASM_STATIC_CALL_H */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/suspend_32.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/suspend_32.h
@@ -12,11 +12,6 @@
 
 /* image of the saved processor state */
 struct saved_context {
-	/*
-	 * On x86_32, all segment registers except gs are saved at kernel
-	 * entry in pt_regs.
-	 */
-	u16 gs;
 	unsigned long cr0, cr2, cr3, cr4;
 	u64 misc_enable;
 	struct saved_msrs saved_msrs;
@@ -27,6 +22,11 @@
 	unsigned long tr;
 	unsigned long safety;
 	unsigned long return_address;
+	/*
+	 * On x86_32, all segment registers except gs are saved at kernel
+	 * entry in pt_regs.
+	 */
+	u16 gs;
 	bool misc_enable_saved;
 } __attribute__((packed));
 
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/sync_core.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/sync_core.h
@@ -8,7 +8,7 @@
 #include <asm/special_insns.h>
 
 #ifdef CONFIG_X86_32
-static inline void iret_to_self(void)
+static __always_inline void iret_to_self(void)
 {
 	asm volatile (
 		"pushfl\n\t"
@@ -19,7 +19,7 @@
 		: ASM_CALL_CONSTRAINT : : "memory");
 }
 #else
-static inline void iret_to_self(void)
+static __always_inline void iret_to_self(void)
 {
 	unsigned int tmp;
 
@@ -55,7 +55,7 @@
  * Like all of Linux's memory ordering operations, this is a
  * compiler barrier as well.
  */
-static inline void sync_core(void)
+static __always_inline void sync_core(void)
 {
 	/*
 	 * The SERIALIZE instruction is the most straightforward way to
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/syscall.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/syscall.h
@@ -16,19 +16,17 @@
 #include <asm/thread_info.h>	/* for TS_COMPAT */
 #include <asm/unistd.h>
 
+/* This is used purely for kernel/trace/trace_syscalls.c */
 typedef long (*sys_call_ptr_t)(const struct pt_regs *);
 extern const sys_call_ptr_t sys_call_table[];
 
-#if defined(CONFIG_X86_32)
-#define ia32_sys_call_table sys_call_table
-#else
 /*
  * These may not exist, but still put the prototypes in so we
  * can use IS_ENABLED().
  */
-extern const sys_call_ptr_t ia32_sys_call_table[];
-extern const sys_call_ptr_t x32_sys_call_table[];
-#endif
+extern long ia32_sys_call(const struct pt_regs *, unsigned int nr);
+extern long x32_sys_call(const struct pt_regs *, unsigned int nr);
+extern long x64_sys_call(const struct pt_regs *, unsigned int nr);
 
 /*
  * Only the low 32 bits of orig_ax are meaningful, so we return int.
@@ -84,7 +82,12 @@
 					 struct pt_regs *regs,
 					 unsigned long *args)
 {
-	memcpy(args, &regs->bx, 6 * sizeof(args[0]));
+	args[0] = regs->bx;
+	args[1] = regs->cx;
+	args[2] = regs->dx;
+	args[3] = regs->si;
+	args[4] = regs->di;
+	args[5] = regs->bp;
 }
 
 static inline int syscall_get_arch(struct task_struct *task)
@@ -127,6 +130,7 @@
 }
 
 bool do_syscall_64(struct pt_regs *regs, int nr);
+void do_int80_emulation(struct pt_regs *regs);
 
 #endif	/* CONFIG_X86_32 */
 
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/tlb.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/tlb.h
@@ -34,4 +34,8 @@
 	free_page_and_swap_cache(table);
 }
 
+static inline void invlpg(unsigned long addr)
+{
+	asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
+}
 #endif /* _ASM_X86_TLB_H */
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/uaccess.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/uaccess.h
@@ -78,10 +78,10 @@
 	int __ret_gu;							\
 	register __inttype(*(ptr)) __val_gu asm("%"_ASM_DX);		\
 	__chk_user_ptr(ptr);						\
-	asm volatile("call __" #fn "_%P4"				\
+	asm volatile("call __" #fn "_%c[size]"				\
 		     : "=a" (__ret_gu), "=r" (__val_gu),		\
 			ASM_CALL_CONSTRAINT				\
-		     : "0" (ptr), "i" (sizeof(*(ptr))));		\
+		     : "0" (ptr), [size] "i" (sizeof(*(ptr))));		\
 	instrument_get_user(__val_gu);					\
 	(x) = (__force __typeof__(*(ptr))) __val_gu;			\
 	__builtin_expect(__ret_gu, 0);					\
@@ -177,7 +177,7 @@
 	__chk_user_ptr(__ptr);						\
 	__ptr_pu = __ptr;						\
 	__val_pu = __x;							\
-	asm volatile("call __" #fn "_%P[size]"				\
+	asm volatile("call __" #fn "_%c[size]"				\
 		     : "=c" (__ret_pu),					\
 			ASM_CALL_CONSTRAINT				\
 		     : "0" (__ptr_pu),					\
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/uaccess_64.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/uaccess_64.h
@@ -57,6 +57,14 @@
 #define valid_user_address(x) ((long)(x) >= 0)
 
 /*
+ * Masking the user address is an alternative to a conditional
+ * user_access_begin that can avoid the fencing. This only works
+ * for dense accesses starting at the address.
+ */
+#define mask_user_address(x) ((typeof(x))((long)(x)|((long)(x)>>63)))
+#define masked_user_access_begin(x) ({ __uaccess_begin(); mask_user_address(x); })
+
+/*
  * User pointers can have tag bits on x86-64.  This scheme tolerates
  * arbitrary values in those bits rather then masking them off.
  *
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/vmware.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/vmware.h
@@ -7,51 +7,321 @@
 #include <linux/stringify.h>
 
 /*
- * The hypercall definitions differ in the low word of the %edx argument
- * in the following way: the old port base interface uses the port
- * number to distinguish between high- and low bandwidth versions.
+ * VMware hypercall ABI.
+ *
+ * - Low bandwidth (LB) hypercalls (I/O port based, vmcall and vmmcall)
+ * have up to 6 input and 6 output arguments passed and returned using
+ * registers: %eax (arg0), %ebx (arg1), %ecx (arg2), %edx (arg3),
+ * %esi (arg4), %edi (arg5).
+ * The following input arguments must be initialized by the caller:
+ * arg0 - VMWARE_HYPERVISOR_MAGIC
+ * arg2 - Hypercall command
+ * arg3 bits [15:0] - Port number, LB and direction flags
+ *
+ * - Low bandwidth TDX hypercalls (x86_64 only) are similar to LB
+ * hypercalls. They also have up to 6 input and 6 output on registers
+ * arguments, with different argument to register mapping:
+ * %r12 (arg0), %rbx (arg1), %r13 (arg2), %rdx (arg3),
+ * %rsi (arg4), %rdi (arg5).
+ *
+ * - High bandwidth (HB) hypercalls are I/O port based only. They have
+ * up to 7 input and 7 output arguments passed and returned using
+ * registers: %eax (arg0), %ebx (arg1), %ecx (arg2), %edx (arg3),
+ * %esi (arg4), %edi (arg5), %ebp (arg6).
+ * The following input arguments must be initialized by the caller:
+ * arg0 - VMWARE_HYPERVISOR_MAGIC
+ * arg1 - Hypercall command
+ * arg3 bits [15:0] - Port number, HB and direction flags
+ *
+ * For compatibility purposes, x86_64 systems use only lower 32 bits
+ * for input and output arguments.
+ *
+ * The hypercall definitions differ in the low word of the %edx (arg3)
+ * in the following way: the old I/O port based interface uses the port
+ * number to distinguish between high- and low bandwidth versions, and
+ * uses IN/OUT instructions to define transfer direction.
  *
  * The new vmcall interface instead uses a set of flags to select
  * bandwidth mode and transfer direction. The flags should be loaded
- * into %dx by any user and are automatically replaced by the port
- * number if the VMWARE_HYPERVISOR_PORT method is used.
- *
- * In short, new driver code should strictly use the new definition of
- * %dx content.
+ * into arg3 by any user and are automatically replaced by the port
+ * number if the I/O port method is used.
  */
 
-/* Old port-based version */
-#define VMWARE_HYPERVISOR_PORT    0x5658
-#define VMWARE_HYPERVISOR_PORT_HB 0x5659
-
-/* Current vmcall / vmmcall version */
-#define VMWARE_HYPERVISOR_HB   BIT(0)
-#define VMWARE_HYPERVISOR_OUT  BIT(1)
-
-/* The low bandwidth call. The low word of edx is presumed clear. */
-#define VMWARE_HYPERCALL						\
-	ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT) ", %%dx; " \
-		      "inl (%%dx), %%eax",				\
-		      "vmcall", X86_FEATURE_VMCALL,			\
-		      "vmmcall", X86_FEATURE_VMW_VMMCALL)
+#define VMWARE_HYPERVISOR_HB		BIT(0)
+#define VMWARE_HYPERVISOR_OUT		BIT(1)
+
+#define VMWARE_HYPERVISOR_PORT		0x5658
+#define VMWARE_HYPERVISOR_PORT_HB	(VMWARE_HYPERVISOR_PORT | \
+					 VMWARE_HYPERVISOR_HB)
+
+#define VMWARE_HYPERVISOR_MAGIC		0x564d5868U
 
+#define VMWARE_CMD_GETVERSION		10
+#define VMWARE_CMD_GETHZ		45
+#define VMWARE_CMD_GETVCPU_INFO		68
+#define VMWARE_CMD_STEALCLOCK		91
 /*
- * The high bandwidth out call. The low word of edx is presumed to have the
- * HB and OUT bits set.
+ * Hypercall command mask:
+ *   bits [6:0] command, range [0, 127]
+ *   bits [19:16] sub-command, range [0, 15]
  */
-#define VMWARE_HYPERCALL_HB_OUT						\
-	ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; " \
-		      "rep outsb",					\
-		      "vmcall", X86_FEATURE_VMCALL,			\
-		      "vmmcall", X86_FEATURE_VMW_VMMCALL)
+#define VMWARE_CMD_MASK			0xf007fU
+
+#define CPUID_VMWARE_FEATURES_ECX_VMMCALL	BIT(0)
+#define CPUID_VMWARE_FEATURES_ECX_VMCALL	BIT(1)
+
+extern unsigned long vmware_hypercall_slow(unsigned long cmd,
+					   unsigned long in1, unsigned long in3,
+					   unsigned long in4, unsigned long in5,
+					   u32 *out1, u32 *out2, u32 *out3,
+					   u32 *out4, u32 *out5);
+
+#define VMWARE_TDX_VENDOR_LEAF 0x1af7e4909ULL
+#define VMWARE_TDX_HCALL_FUNC  1
+
+extern unsigned long vmware_tdx_hypercall(unsigned long cmd,
+					  unsigned long in1, unsigned long in3,
+					  unsigned long in4, unsigned long in5,
+					  u32 *out1, u32 *out2, u32 *out3,
+					  u32 *out4, u32 *out5);
 
 /*
- * The high bandwidth in call. The low word of edx is presumed to have the
- * HB bit set.
+ * The low bandwidth call. The low word of %edx is presumed to have OUT bit
+ * set. The high word of %edx may contain input data from the caller.
  */
-#define VMWARE_HYPERCALL_HB_IN						\
-	ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; " \
-		      "rep insb",					\
-		      "vmcall", X86_FEATURE_VMCALL,			\
+#define VMWARE_HYPERCALL					\
+	ALTERNATIVE_2("movw %[port], %%dx\n\t"			\
+		      "inl (%%dx), %%eax",			\
+		      "vmcall", X86_FEATURE_VMCALL,		\
 		      "vmmcall", X86_FEATURE_VMW_VMMCALL)
+
+static inline
+unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)
+{
+	unsigned long out0;
+
+	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+		return vmware_tdx_hypercall(cmd, in1, 0, 0, 0,
+					    NULL, NULL, NULL, NULL, NULL);
+
+	if (unlikely(!alternatives_patched) && !__is_defined(MODULE))
+		return vmware_hypercall_slow(cmd, in1, 0, 0, 0,
+					     NULL, NULL, NULL, NULL, NULL);
+
+	asm_inline volatile (VMWARE_HYPERCALL
+		: "=a" (out0)
+		: [port] "i" (VMWARE_HYPERVISOR_PORT),
+		  "a" (VMWARE_HYPERVISOR_MAGIC),
+		  "b" (in1),
+		  "c" (cmd),
+		  "d" (0)
+		: "cc", "memory");
+	return out0;
+}
+
+static inline
+unsigned long vmware_hypercall3(unsigned long cmd, unsigned long in1,
+				u32 *out1, u32 *out2)
+{
+	unsigned long out0;
+
+	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+		return vmware_tdx_hypercall(cmd, in1, 0, 0, 0,
+					    out1, out2, NULL, NULL, NULL);
+
+	if (unlikely(!alternatives_patched) && !__is_defined(MODULE))
+		return vmware_hypercall_slow(cmd, in1, 0, 0, 0,
+					     out1, out2, NULL, NULL, NULL);
+
+	asm_inline volatile (VMWARE_HYPERCALL
+		: "=a" (out0), "=b" (*out1), "=c" (*out2)
+		: [port] "i" (VMWARE_HYPERVISOR_PORT),
+		  "a" (VMWARE_HYPERVISOR_MAGIC),
+		  "b" (in1),
+		  "c" (cmd),
+		  "d" (0)
+		: "cc", "memory");
+	return out0;
+}
+
+static inline
+unsigned long vmware_hypercall4(unsigned long cmd, unsigned long in1,
+				u32 *out1, u32 *out2, u32 *out3)
+{
+	unsigned long out0;
+
+	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+		return vmware_tdx_hypercall(cmd, in1, 0, 0, 0,
+					    out1, out2, out3, NULL, NULL);
+
+	if (unlikely(!alternatives_patched) && !__is_defined(MODULE))
+		return vmware_hypercall_slow(cmd, in1, 0, 0, 0,
+					     out1, out2, out3, NULL, NULL);
+
+	asm_inline volatile (VMWARE_HYPERCALL
+		: "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3)
+		: [port] "i" (VMWARE_HYPERVISOR_PORT),
+		  "a" (VMWARE_HYPERVISOR_MAGIC),
+		  "b" (in1),
+		  "c" (cmd),
+		  "d" (0)
+		: "cc", "memory");
+	return out0;
+}
+
+static inline
+unsigned long vmware_hypercall5(unsigned long cmd, unsigned long in1,
+				unsigned long in3, unsigned long in4,
+				unsigned long in5, u32 *out2)
+{
+	unsigned long out0;
+
+	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+		return vmware_tdx_hypercall(cmd, in1, in3, in4, in5,
+					    NULL, out2, NULL, NULL, NULL);
+
+	if (unlikely(!alternatives_patched) && !__is_defined(MODULE))
+		return vmware_hypercall_slow(cmd, in1, in3, in4, in5,
+					     NULL, out2, NULL, NULL, NULL);
+
+	asm_inline volatile (VMWARE_HYPERCALL
+		: "=a" (out0), "=c" (*out2)
+		: [port] "i" (VMWARE_HYPERVISOR_PORT),
+		  "a" (VMWARE_HYPERVISOR_MAGIC),
+		  "b" (in1),
+		  "c" (cmd),
+		  "d" (in3),
+		  "S" (in4),
+		  "D" (in5)
+		: "cc", "memory");
+	return out0;
+}
+
+static inline
+unsigned long vmware_hypercall6(unsigned long cmd, unsigned long in1,
+				unsigned long in3, u32 *out2,
+				u32 *out3, u32 *out4, u32 *out5)
+{
+	unsigned long out0;
+
+	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+		return vmware_tdx_hypercall(cmd, in1, in3, 0, 0,
+					    NULL, out2, out3, out4, out5);
+
+	if (unlikely(!alternatives_patched) && !__is_defined(MODULE))
+		return vmware_hypercall_slow(cmd, in1, in3, 0, 0,
+					     NULL, out2, out3, out4, out5);
+
+	asm_inline volatile (VMWARE_HYPERCALL
+		: "=a" (out0), "=c" (*out2), "=d" (*out3), "=S" (*out4),
+		  "=D" (*out5)
+		: [port] "i" (VMWARE_HYPERVISOR_PORT),
+		  "a" (VMWARE_HYPERVISOR_MAGIC),
+		  "b" (in1),
+		  "c" (cmd),
+		  "d" (in3)
+		: "cc", "memory");
+	return out0;
+}
+
+static inline
+unsigned long vmware_hypercall7(unsigned long cmd, unsigned long in1,
+				unsigned long in3, unsigned long in4,
+				unsigned long in5, u32 *out1,
+				u32 *out2, u32 *out3)
+{
+	unsigned long out0;
+
+	if (cpu_feature_enabled(X86_FEATURE_TDX_GUEST))
+		return vmware_tdx_hypercall(cmd, in1, in3, in4, in5,
+					    out1, out2, out3, NULL, NULL);
+
+	if (unlikely(!alternatives_patched) && !__is_defined(MODULE))
+		return vmware_hypercall_slow(cmd, in1, in3, in4, in5,
+					     out1, out2, out3, NULL, NULL);
+
+	asm_inline volatile (VMWARE_HYPERCALL
+		: "=a" (out0), "=b" (*out1), "=c" (*out2), "=d" (*out3)
+		: [port] "i" (VMWARE_HYPERVISOR_PORT),
+		  "a" (VMWARE_HYPERVISOR_MAGIC),
+		  "b" (in1),
+		  "c" (cmd),
+		  "d" (in3),
+		  "S" (in4),
+		  "D" (in5)
+		: "cc", "memory");
+	return out0;
+}
+
+#ifdef CONFIG_X86_64
+#define VMW_BP_CONSTRAINT "r"
+#else
+#define VMW_BP_CONSTRAINT "m"
+#endif
+
+/*
+ * High bandwidth calls are not supported on encrypted memory guests.
+ * The caller should check cc_platform_has(CC_ATTR_MEM_ENCRYPT) and use
+ * low bandwidth hypercall if memory encryption is set.
+ * This assumption simplifies HB hypercall implementation to just I/O port
+ * based approach without alternative patching.
+ */
+static inline
+unsigned long vmware_hypercall_hb_out(unsigned long cmd, unsigned long in2,
+				      unsigned long in3, unsigned long in4,
+				      unsigned long in5, unsigned long in6,
+				      u32 *out1)
+{
+	unsigned long out0;
+
+	asm_inline volatile (
+		UNWIND_HINT_SAVE
+		"push %%" _ASM_BP "\n\t"
+		UNWIND_HINT_UNDEFINED
+		"mov %[in6], %%" _ASM_BP "\n\t"
+		"rep outsb\n\t"
+		"pop %%" _ASM_BP "\n\t"
+		UNWIND_HINT_RESTORE
+		: "=a" (out0), "=b" (*out1)
+		: "a" (VMWARE_HYPERVISOR_MAGIC),
+		  "b" (cmd),
+		  "c" (in2),
+		  "d" (in3 | VMWARE_HYPERVISOR_PORT_HB),
+		  "S" (in4),
+		  "D" (in5),
+		  [in6] VMW_BP_CONSTRAINT (in6)
+		: "cc", "memory");
+	return out0;
+}
+
+static inline
+unsigned long vmware_hypercall_hb_in(unsigned long cmd, unsigned long in2,
+				     unsigned long in3, unsigned long in4,
+				     unsigned long in5, unsigned long in6,
+				     u32 *out1)
+{
+	unsigned long out0;
+
+	asm_inline volatile (
+		UNWIND_HINT_SAVE
+		"push %%" _ASM_BP "\n\t"
+		UNWIND_HINT_UNDEFINED
+		"mov %[in6], %%" _ASM_BP "\n\t"
+		"rep insb\n\t"
+		"pop %%" _ASM_BP "\n\t"
+		UNWIND_HINT_RESTORE
+		: "=a" (out0), "=b" (*out1)
+		: "a" (VMWARE_HYPERVISOR_MAGIC),
+		  "b" (cmd),
+		  "c" (in2),
+		  "d" (in3 | VMWARE_HYPERVISOR_PORT_HB),
+		  "S" (in4),
+		  "D" (in5),
+		  [in6] VMW_BP_CONSTRAINT (in6)
+		: "cc", "memory");
+	return out0;
+}
+#undef VMW_BP_CONSTRAINT
+#undef VMWARE_HYPERCALL
+
 #endif
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/x86_init.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/x86_init.h
@@ -30,12 +30,13 @@
  * @reserve_resources:		reserve the standard resources for the
  *				platform
  * @memory_setup:		platform specific memory setup
- *
+ * @dmi_setup:			platform specific DMI setup
  */
 struct x86_init_resources {
 	void (*probe_roms)(void);
 	void (*reserve_resources)(void);
 	char *(*memory_setup)(void);
+	void (*dmi_setup)(void);
 };
 
 /**
@@ -148,12 +149,22 @@
  * @enc_status_change_finish	Notify HV after the encryption status of a range is changed
  * @enc_tlb_flush_required	Returns true if a TLB flush is needed before changing page encryption status
  * @enc_cache_flush_required	Returns true if a cache flush is needed before changing page encryption status
+ * @enc_kexec_begin		Begin the two-step process of converting shared memory back
+ *				to private. It stops the new conversions from being started
+ *				and waits in-flight conversions to finish, if possible.
+ * @enc_kexec_finish		Finish the two-step process of converting shared memory to
+ *				private. All memory is private after the call when
+ *				the function returns.
+ *				It is called on only one CPU while the others are shut down
+ *				and with interrupts disabled.
  */
 struct x86_guest {
-	bool (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
-	bool (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc);
+	int (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
+	int (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc);
 	bool (*enc_tlb_flush_required)(bool enc);
 	bool (*enc_cache_flush_required)(void);
+	void (*enc_kexec_begin)(void);
+	void (*enc_kexec_finish)(void);
 };
 
 /**
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/xen/hypercall.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/xen/hypercall.h
@@ -39,9 +39,11 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/pgtable.h>
+#include <linux/instrumentation.h>
 
 #include <trace/events/xen.h>
 
+#include <asm/alternative.h>
 #include <asm/page.h>
 #include <asm/smap.h>
 #include <asm/nospec-branch.h>
@@ -86,11 +88,20 @@
  * there aren't more than 5 arguments...)
  */
 
-extern struct { char _entry[32]; } hypercall_page[];
+void xen_hypercall_func(void);
+DECLARE_STATIC_CALL(xen_hypercall, xen_hypercall_func);
 
-#define __HYPERCALL		"call hypercall_page+%c[offset]"
-#define __HYPERCALL_ENTRY(x)						\
-	[offset] "i" (__HYPERVISOR_##x * sizeof(hypercall_page[0]))
+#ifdef MODULE
+#define __ADDRESSABLE_xen_hypercall
+#else
+#define __ADDRESSABLE_xen_hypercall __ADDRESSABLE_ASM_STR(__SCK__xen_hypercall)
+#endif
+
+#define __HYPERCALL					\
+	__ADDRESSABLE_xen_hypercall			\
+	"call __SCT__xen_hypercall"
+
+#define __HYPERCALL_ENTRY(x)	"a" (x)
 
 #ifdef CONFIG_X86_32
 #define __HYPERCALL_RETREG	"eax"
@@ -148,7 +159,7 @@
 	__HYPERCALL_0ARG();						\
 	asm volatile (__HYPERCALL					\
 		      : __HYPERCALL_0PARAM				\
-		      : __HYPERCALL_ENTRY(name)				\
+		      : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name)	\
 		      : __HYPERCALL_CLOBBER0);				\
 	(type)__res;							\
 })
@@ -159,7 +170,7 @@
 	__HYPERCALL_1ARG(a1);						\
 	asm volatile (__HYPERCALL					\
 		      : __HYPERCALL_1PARAM				\
-		      : __HYPERCALL_ENTRY(name)				\
+		      : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name)	\
 		      : __HYPERCALL_CLOBBER1);				\
 	(type)__res;							\
 })
@@ -170,7 +181,7 @@
 	__HYPERCALL_2ARG(a1, a2);					\
 	asm volatile (__HYPERCALL					\
 		      : __HYPERCALL_2PARAM				\
-		      : __HYPERCALL_ENTRY(name)				\
+		      : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name)	\
 		      : __HYPERCALL_CLOBBER2);				\
 	(type)__res;							\
 })
@@ -181,7 +192,7 @@
 	__HYPERCALL_3ARG(a1, a2, a3);					\
 	asm volatile (__HYPERCALL					\
 		      : __HYPERCALL_3PARAM				\
-		      : __HYPERCALL_ENTRY(name)				\
+		      : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name)	\
 		      : __HYPERCALL_CLOBBER3);				\
 	(type)__res;							\
 })
@@ -192,7 +203,7 @@
 	__HYPERCALL_4ARG(a1, a2, a3, a4);				\
 	asm volatile (__HYPERCALL					\
 		      : __HYPERCALL_4PARAM				\
-		      : __HYPERCALL_ENTRY(name)				\
+		      : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name)	\
 		      : __HYPERCALL_CLOBBER4);				\
 	(type)__res;							\
 })
@@ -206,12 +217,9 @@
 	__HYPERCALL_DECLS;
 	__HYPERCALL_5ARG(a1, a2, a3, a4, a5);
 
-	if (call >= PAGE_SIZE / sizeof(hypercall_page[0]))
-		return -EINVAL;
-
-	asm volatile(CALL_NOSPEC
+	asm volatile(__HYPERCALL
 		     : __HYPERCALL_5PARAM
-		     : [thunk_target] "a" (&hypercall_page[call])
+		     : __HYPERCALL_ENTRY(call)
 		     : __HYPERCALL_CLOBBER5);
 
 	return (long)__res;
--- linux-qcom-6.8.0.orig/arch/x86/include/asm/xen/hypervisor.h
+++ linux-qcom-6.8.0/arch/x86/include/asm/xen/hypervisor.h
@@ -62,6 +62,11 @@
 #ifdef CONFIG_PVH
 void __init xen_pvh_init(struct boot_params *boot_params);
 void __init mem_map_via_hcall(struct boot_params *boot_params_p);
+#ifdef CONFIG_XEN_PVH
+void __init xen_reserve_extra_memory(struct boot_params *bootp);
+#else
+static inline void xen_reserve_extra_memory(struct boot_params *bootp) { }
+#endif
 #endif
 
 /* Lazy mode for batching updates / context switch */
--- linux-qcom-6.8.0.orig/arch/x86/include/uapi/asm/bootparam.h
+++ linux-qcom-6.8.0/arch/x86/include/uapi/asm/bootparam.h
@@ -38,6 +38,7 @@
 #define XLF_EFI_KEXEC			(1<<4)
 #define XLF_5LEVEL			(1<<5)
 #define XLF_5LEVEL_ENABLED		(1<<6)
+#define XLF_MEM_ENCRYPTION		(1<<7)
 
 #ifndef __ASSEMBLY__
 
--- linux-qcom-6.8.0.orig/arch/x86/kernel/acpi/boot.c
+++ linux-qcom-6.8.0/arch/x86/kernel/acpi/boot.c
@@ -263,6 +263,28 @@
 }
 
 static int __init
+acpi_check_lapic(union acpi_subtable_headers *header, const unsigned long end)
+{
+	struct acpi_madt_local_apic *processor = NULL;
+
+	processor = (struct acpi_madt_local_apic *)header;
+
+	if (BAD_MADT_ENTRY(processor, end))
+		return -EINVAL;
+
+	/* Ignore invalid ID */
+	if (processor->id == 0xff)
+		return 0;
+
+	/* Ignore processors that can not be onlined */
+	if (!acpi_is_processor_usable(processor->lapic_flags))
+		return 0;
+
+	has_lapic_cpus = true;
+	return 0;
+}
+
+static int __init
 acpi_parse_lapic(union acpi_subtable_headers * header, const unsigned long end)
 {
 	struct acpi_madt_local_apic *processor = NULL;
@@ -293,7 +315,6 @@
 			    processor->processor_id, /* ACPI ID */
 			    processor->lapic_flags & ACPI_MADT_ENABLED);
 
-	has_lapic_cpus = true;
 	return 0;
 }
 
@@ -1125,6 +1146,8 @@
 static int __init acpi_parse_madt_lapic_entries(void)
 {
 	int count, x2count = 0;
+	struct acpi_subtable_proc madt_proc[2];
+	int ret;
 
 	if (!boot_cpu_has(X86_FEATURE_APIC))
 		return -ENODEV;
@@ -1133,10 +1156,27 @@
 				      acpi_parse_sapic, MAX_LOCAL_APIC);
 
 	if (!count) {
-		count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC,
-					acpi_parse_lapic, MAX_LOCAL_APIC);
-		x2count = acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_X2APIC,
-					acpi_parse_x2apic, MAX_LOCAL_APIC);
+		/* Check if there are valid LAPIC entries */
+		acpi_table_parse_madt(ACPI_MADT_TYPE_LOCAL_APIC, acpi_check_lapic, MAX_LOCAL_APIC);
+
+		/*
+		 * Enumerate the APIC IDs in the order that they appear in the
+		 * MADT, no matter LAPIC entry or x2APIC entry is used.
+		 */
+		memset(madt_proc, 0, sizeof(madt_proc));
+		madt_proc[0].id = ACPI_MADT_TYPE_LOCAL_APIC;
+		madt_proc[0].handler = acpi_parse_lapic;
+		madt_proc[1].id = ACPI_MADT_TYPE_LOCAL_X2APIC;
+		madt_proc[1].handler = acpi_parse_x2apic;
+		ret = acpi_table_parse_entries_array(ACPI_SIG_MADT,
+				sizeof(struct acpi_table_madt),
+				madt_proc, ARRAY_SIZE(madt_proc), MAX_LOCAL_APIC);
+		if (ret < 0) {
+			pr_err("Error parsing LAPIC/X2APIC entries\n");
+			return ret;
+		}
+		count = madt_proc[0].count;
+		x2count = madt_proc[1].count;
 	}
 	if (!count && !x2count) {
 		pr_err("No LAPIC entries present\n");
@@ -1897,3 +1937,14 @@
 {
 	return boot_params.acpi_rsdp_addr;
 }
+
+#ifdef CONFIG_XEN_PV
+void __iomem *x86_acpi_os_ioremap(acpi_physical_address phys, acpi_size size)
+{
+	return ioremap_cache(phys, size);
+}
+
+void __iomem * (*acpi_os_ioremap)(acpi_physical_address phys, acpi_size size) =
+	x86_acpi_os_ioremap;
+EXPORT_SYMBOL_GPL(acpi_os_ioremap);
+#endif
--- linux-qcom-6.8.0.orig/arch/x86/kernel/acpi/cppc.c
+++ linux-qcom-6.8.0/arch/x86/kernel/acpi/cppc.c
@@ -20,7 +20,7 @@
 		    (boot_cpu_data.x86_model >= 0x20 && boot_cpu_data.x86_model <= 0x2f)))
 			return true;
 		else if (boot_cpu_data.x86 == 0x17 &&
-			 boot_cpu_data.x86_model >= 0x70 && boot_cpu_data.x86_model <= 0x7f)
+			 boot_cpu_data.x86_model >= 0x30 && boot_cpu_data.x86_model <= 0x7f)
 			return true;
 		return boot_cpu_has(X86_FEATURE_CPPC);
 	}
--- linux-qcom-6.8.0.orig/arch/x86/kernel/amd_nb.c
+++ linux-qcom-6.8.0/arch/x86/kernel/amd_nb.c
@@ -26,6 +26,7 @@
 #define PCI_DEVICE_ID_AMD_19H_M70H_ROOT		0x14e8
 #define PCI_DEVICE_ID_AMD_1AH_M00H_ROOT		0x153a
 #define PCI_DEVICE_ID_AMD_1AH_M20H_ROOT		0x1507
+#define PCI_DEVICE_ID_AMD_1AH_M60H_ROOT		0x1122
 #define PCI_DEVICE_ID_AMD_MI200_ROOT		0x14bb
 #define PCI_DEVICE_ID_AMD_MI300_ROOT		0x14f8
 
@@ -43,6 +44,9 @@
 #define PCI_DEVICE_ID_AMD_19H_M70H_DF_F4	0x14f4
 #define PCI_DEVICE_ID_AMD_19H_M78H_DF_F4	0x12fc
 #define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4	0x12c4
+#define PCI_DEVICE_ID_AMD_1AH_M20H_DF_F4	0x16fc
+#define PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4	0x124c
+#define PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4	0x12bc
 #define PCI_DEVICE_ID_AMD_MI200_DF_F4		0x14d4
 #define PCI_DEVICE_ID_AMD_MI300_DF_F4		0x152c
 
@@ -63,6 +67,7 @@
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M70H_ROOT) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_ROOT) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_ROOT) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_ROOT) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_ROOT) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_ROOT) },
 	{}
@@ -95,6 +100,8 @@
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F3) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F3) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F3) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_DF_F3) },
 	{}
@@ -121,6 +128,9 @@
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F4) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F4) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F4) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI300_DF_F4) },
 	{}
@@ -214,7 +224,14 @@
 
 int amd_smn_read(u16 node, u32 address, u32 *value)
 {
-	return __amd_smn_rw(node, address, value, false);
+	int err = __amd_smn_rw(node, address, value, false);
+
+	if (PCI_POSSIBLE_ERROR(*value)) {
+		err = -ENODEV;
+		*value = 0;
+	}
+
+	return err;
 }
 EXPORT_SYMBOL_GPL(amd_smn_read);
 
@@ -531,6 +548,10 @@
 
 static __init int init_amd_nbs(void)
 {
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
+	    boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
+		return 0;
+
 	amd_cache_northbridges();
 	amd_cache_gart();
 
--- linux-qcom-6.8.0.orig/arch/x86/kernel/aperture_64.c
+++ linux-qcom-6.8.0/arch/x86/kernel/aperture_64.c
@@ -136,32 +136,6 @@
 }
 
 
-/* Find a PCI capability */
-static u32 __init find_cap(int bus, int slot, int func, int cap)
-{
-	int bytes;
-	u8 pos;
-
-	if (!(read_pci_config_16(bus, slot, func, PCI_STATUS) &
-						PCI_STATUS_CAP_LIST))
-		return 0;
-
-	pos = read_pci_config_byte(bus, slot, func, PCI_CAPABILITY_LIST);
-	for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
-		u8 id;
-
-		pos &= ~3;
-		id = read_pci_config_byte(bus, slot, func, pos+PCI_CAP_LIST_ID);
-		if (id == 0xff)
-			break;
-		if (id == cap)
-			return pos;
-		pos = read_pci_config_byte(bus, slot, func,
-						pos+PCI_CAP_LIST_NEXT);
-	}
-	return 0;
-}
-
 /* Read a standard AGPv3 bridge header */
 static u32 __init read_agp(int bus, int slot, int func, int cap, u32 *order)
 {
@@ -250,8 +224,8 @@
 				case PCI_CLASS_BRIDGE_HOST:
 				case PCI_CLASS_BRIDGE_OTHER: /* needed? */
 					/* AGP bridge? */
-					cap = find_cap(bus, slot, func,
-							PCI_CAP_ID_AGP);
+					cap = pci_early_find_cap(bus, slot,
+						 func, PCI_CAP_ID_AGP);
 					if (!cap)
 						break;
 					*valid_agp = 1;
--- linux-qcom-6.8.0.orig/arch/x86/kernel/apic/apic.c
+++ linux-qcom-6.8.0/arch/x86/kernel/apic/apic.c
@@ -473,7 +473,19 @@
 	v = apic_read(APIC_LVTT);
 	v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
 	apic_write(APIC_LVTT, v);
-	apic_write(APIC_TMICT, 0);
+
+	/*
+	 * Setting APIC_LVT_MASKED (above) should be enough to tell
+	 * the hardware that this timer will never fire. But AMD
+	 * erratum 411 and some Intel CPU behavior circa 2024 say
+	 * otherwise.  Time for belt and suspenders programming: mask
+	 * the timer _and_ zero the counter registers:
+	 */
+	if (v & APIC_LVT_TIMER_TSCDEADLINE)
+		wrmsrl(MSR_IA32_TSC_DEADLINE, 0);
+	else
+		apic_write(APIC_TMICT, 0);
+
 	return 0;
 }
 
@@ -1724,11 +1736,11 @@
 
 static bool x2apic_hw_locked(void)
 {
-	u64 ia32_cap;
+	u64 x86_arch_cap_msr;
 	u64 msr;
 
-	ia32_cap = x86_read_arch_cap_msr();
-	if (ia32_cap & ARCH_CAP_XAPIC_DISABLE) {
+	x86_arch_cap_msr = x86_read_arch_cap_msr();
+	if (x86_arch_cap_msr & ARCH_CAP_XAPIC_DISABLE) {
 		rdmsrl(MSR_IA32_XAPIC_DISABLE_STATUS, msr);
 		return (msr & LEGACY_XAPIC_DISABLED);
 	}
@@ -1808,16 +1820,13 @@
 	__x2apic_enable();
 }
 
-static __init void apic_set_fixmap(void);
+static __init void apic_set_fixmap(bool read_apic);
 
 static __init void x2apic_disable(void)
 {
-	u32 x2apic_id, state = x2apic_state;
-
-	x2apic_mode = 0;
-	x2apic_state = X2APIC_DISABLED;
+	u32 x2apic_id;
 
-	if (state != X2APIC_ON)
+	if (x2apic_state < X2APIC_ON)
 		return;
 
 	x2apic_id = read_apic_id();
@@ -1830,7 +1839,16 @@
 	}
 
 	__x2apic_disable();
-	apic_set_fixmap();
+
+	x2apic_mode = 0;
+	x2apic_state = X2APIC_DISABLED;
+
+	/*
+	 * Don't reread the APIC ID as it was already done from
+	 * check_x2apic() and the APIC driver still is a x2APIC variant,
+	 * which fails to do the read after x2APIC was disabled.
+	 */
+	apic_set_fixmap(false);
 }
 
 static __init void x2apic_enable(void)
@@ -2095,13 +2113,14 @@
 	}
 }
 
-static __init void apic_set_fixmap(void)
+static __init void apic_set_fixmap(bool read_apic)
 {
 	set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
 	apic_mmio_base = APIC_BASE;
 	apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
 		    apic_mmio_base, mp_lapic_addr);
-	apic_read_boot_cpu_id(false);
+	if (read_apic)
+		apic_read_boot_cpu_id(false);
 }
 
 void __init register_lapic_address(unsigned long address)
@@ -2111,7 +2130,7 @@
 	mp_lapic_addr = address;
 
 	if (!x2apic_mode)
-		apic_set_fixmap();
+		apic_set_fixmap(true);
 }
 
 /*
--- linux-qcom-6.8.0.orig/arch/x86/kernel/apic/apic_flat_64.c
+++ linux-qcom-6.8.0/arch/x86/kernel/apic/apic_flat_64.c
@@ -8,55 +8,13 @@
  * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
  * James Cleverdon.
  */
-#include <linux/cpumask.h>
 #include <linux/export.h>
-#include <linux/acpi.h>
 
-#include <asm/jailhouse_para.h>
 #include <asm/apic.h>
 
 #include "local.h"
 
-static struct apic apic_physflat;
-static struct apic apic_flat;
-
-struct apic *apic __ro_after_init = &apic_flat;
-EXPORT_SYMBOL_GPL(apic);
-
-static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
-{
-	return 1;
-}
-
-static void _flat_send_IPI_mask(unsigned long mask, int vector)
-{
-	unsigned long flags;
-
-	local_irq_save(flags);
-	__default_send_IPI_dest_field(mask, vector, APIC_DEST_LOGICAL);
-	local_irq_restore(flags);
-}
-
-static void flat_send_IPI_mask(const struct cpumask *cpumask, int vector)
-{
-	unsigned long mask = cpumask_bits(cpumask)[0];
-
-	_flat_send_IPI_mask(mask, vector);
-}
-
-static void
-flat_send_IPI_mask_allbutself(const struct cpumask *cpumask, int vector)
-{
-	unsigned long mask = cpumask_bits(cpumask)[0];
-	int cpu = smp_processor_id();
-
-	if (cpu < BITS_PER_LONG)
-		__clear_bit(cpu, &mask);
-
-	_flat_send_IPI_mask(mask, vector);
-}
-
-static u32 flat_get_apic_id(u32 x)
+static u32 physflat_get_apic_id(u32 x)
 {
 	return (x >> 24) & 0xFF;
 }
@@ -71,79 +29,14 @@
 	return initial_apic_id >> index_msb;
 }
 
-static int flat_probe(void)
+static int physflat_probe(void)
 {
 	return 1;
 }
 
-static struct apic apic_flat __ro_after_init = {
-	.name				= "flat",
-	.probe				= flat_probe,
-	.acpi_madt_oem_check		= flat_acpi_madt_oem_check,
-	.apic_id_registered		= default_apic_id_registered,
-
-	.dest_mode_logical		= true,
-
-	.disable_esr			= 0,
-
-	.init_apic_ldr			= default_init_apic_ldr,
-	.cpu_present_to_apicid		= default_cpu_present_to_apicid,
-	.phys_pkg_id			= flat_phys_pkg_id,
-
-	.max_apic_id			= 0xFE,
-	.get_apic_id			= flat_get_apic_id,
-	.set_apic_id			= set_apic_id,
-
-	.calc_dest_apicid		= apic_flat_calc_apicid,
-
-	.send_IPI			= default_send_IPI_single,
-	.send_IPI_mask			= flat_send_IPI_mask,
-	.send_IPI_mask_allbutself	= flat_send_IPI_mask_allbutself,
-	.send_IPI_allbutself		= default_send_IPI_allbutself,
-	.send_IPI_all			= default_send_IPI_all,
-	.send_IPI_self			= default_send_IPI_self,
-	.nmi_to_offline_cpu		= true,
-
-	.read				= native_apic_mem_read,
-	.write				= native_apic_mem_write,
-	.eoi				= native_apic_mem_eoi,
-	.icr_read			= native_apic_icr_read,
-	.icr_write			= native_apic_icr_write,
-	.wait_icr_idle			= apic_mem_wait_icr_idle,
-	.safe_wait_icr_idle		= apic_mem_wait_icr_idle_timeout,
-};
-
-/*
- * Physflat mode is used when there are more than 8 CPUs on a system.
- * We cannot use logical delivery in this case because the mask
- * overflows, so use physical mode.
- */
 static int physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
-#ifdef CONFIG_ACPI
-	/*
-	 * Quirk: some x86_64 machines can only use physical APIC mode
-	 * regardless of how many processors are present (x86_64 ES7000
-	 * is an example).
-	 */
-	if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID &&
-		(acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) {
-		printk(KERN_DEBUG "system APIC only can use physical flat");
-		return 1;
-	}
-
-	if (!strncmp(oem_id, "IBM", 3) && !strncmp(oem_table_id, "EXA", 3)) {
-		printk(KERN_DEBUG "IBM Summit detected, will use apic physical");
-		return 1;
-	}
-#endif
-
-	return 0;
-}
-
-static int physflat_probe(void)
-{
-	return apic == &apic_physflat || num_possible_cpus() > 8 || jailhouse_paravirt();
+	return 1;
 }
 
 static struct apic apic_physflat __ro_after_init = {
@@ -161,7 +54,7 @@
 	.phys_pkg_id			= flat_phys_pkg_id,
 
 	.max_apic_id			= 0xFE,
-	.get_apic_id			= flat_get_apic_id,
+	.get_apic_id			= physflat_get_apic_id,
 	.set_apic_id			= set_apic_id,
 
 	.calc_dest_apicid		= apic_default_calc_apicid,
@@ -182,8 +75,7 @@
 	.wait_icr_idle			= apic_mem_wait_icr_idle,
 	.safe_wait_icr_idle		= apic_mem_wait_icr_idle_timeout,
 };
+apic_driver(apic_physflat);
 
-/*
- * We need to check for physflat first, so this order is important.
- */
-apic_drivers(apic_physflat, apic_flat);
+struct apic *apic __ro_after_init = &apic_physflat;
+EXPORT_SYMBOL_GPL(apic);
--- linux-qcom-6.8.0.orig/arch/x86/kernel/apic/io_apic.c
+++ linux-qcom-6.8.0/arch/x86/kernel/apic/io_apic.c
@@ -352,27 +352,26 @@
  * shared ISA-space IRQs, so we have to support them. We are super
  * fast in the common case, and fast for shared ISA-space IRQs.
  */
-static int __add_pin_to_irq_node(struct mp_chip_data *data,
-				 int node, int apic, int pin)
+static bool add_pin_to_irq_node(struct mp_chip_data *data, int node, int apic, int pin)
 {
 	struct irq_pin_list *entry;
 
-	/* don't allow duplicates */
-	for_each_irq_pin(entry, data->irq_2_pin)
+	/* Don't allow duplicates */
+	for_each_irq_pin(entry, data->irq_2_pin) {
 		if (entry->apic == apic && entry->pin == pin)
-			return 0;
+			return true;
+	}
 
 	entry = kzalloc_node(sizeof(struct irq_pin_list), GFP_ATOMIC, node);
 	if (!entry) {
-		pr_err("can not alloc irq_pin_list (%d,%d,%d)\n",
-		       node, apic, pin);
-		return -ENOMEM;
+		pr_err("Cannot allocate irq_pin_list (%d,%d,%d)\n", node, apic, pin);
+		return false;
 	}
+
 	entry->apic = apic;
 	entry->pin = pin;
 	list_add_tail(&entry->list, &data->irq_2_pin);
-
-	return 0;
+	return true;
 }
 
 static void __remove_pin_from_irq(struct mp_chip_data *data, int apic, int pin)
@@ -387,13 +386,6 @@
 		}
 }
 
-static void add_pin_to_irq_node(struct mp_chip_data *data,
-				int node, int apic, int pin)
-{
-	if (__add_pin_to_irq_node(data, node, apic, pin))
-		panic("IO-APIC: failed to add irq-pin. Can not proceed\n");
-}
-
 /*
  * Reroute an IRQ to a different pin.
  */
@@ -1002,8 +994,7 @@
 	if (irq_data && irq_data->parent_data) {
 		if (!mp_check_pin_attr(irq, info))
 			return -EBUSY;
-		if (__add_pin_to_irq_node(irq_data->chip_data, node, ioapic,
-					  info->ioapic.pin))
+		if (!add_pin_to_irq_node(irq_data->chip_data, node, ioapic, info->ioapic.pin))
 			return -ENOMEM;
 	} else {
 		info->flags |= X86_IRQ_ALLOC_LEGACY;
@@ -3037,10 +3028,8 @@
 		return -ENOMEM;
 
 	ret = irq_domain_alloc_irqs_parent(domain, virq, nr_irqs, info);
-	if (ret < 0) {
-		kfree(data);
-		return ret;
-	}
+	if (ret < 0)
+		goto free_data;
 
 	INIT_LIST_HEAD(&data->irq_2_pin);
 	irq_data->hwirq = info->ioapic.pin;
@@ -3049,7 +3038,10 @@
 	irq_data->chip_data = data;
 	mp_irqdomain_get_attr(mp_pin_to_gsi(ioapic, pin), data, info);
 
-	add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin);
+	if (!add_pin_to_irq_node(data, ioapic_alloc_attr_node(info), ioapic, pin)) {
+		ret = -ENOMEM;
+		goto free_irqs;
+	}
 
 	mp_preconfigure_entry(data);
 	mp_register_handler(virq, data->is_level);
@@ -3064,6 +3056,12 @@
 		    ioapic, mpc_ioapic_id(ioapic), pin, virq,
 		    data->is_level, data->active_low);
 	return 0;
+
+free_irqs:
+	irq_domain_free_irqs_parent(domain, virq, nr_irqs);
+free_data:
+	kfree(data);
+	return ret;
 }
 
 void mp_irqdomain_free(struct irq_domain *domain, unsigned int virq,
--- linux-qcom-6.8.0.orig/arch/x86/kernel/apic/vector.c
+++ linux-qcom-6.8.0/arch/x86/kernel/apic/vector.c
@@ -1036,7 +1036,8 @@
 			add_timer_on(&cl->timer, cpu);
 		}
 	} else {
-		apicd->prev_vector = 0;
+		pr_warn("IRQ %u schedule cleanup for offline CPU %u\n", apicd->irq, cpu);
+		free_moved_vector(apicd);
 	}
 	raw_spin_unlock(&vector_lock);
 }
@@ -1073,6 +1074,7 @@
  */
 void irq_force_complete_move(struct irq_desc *desc)
 {
+	unsigned int cpu = smp_processor_id();
 	struct apic_chip_data *apicd;
 	struct irq_data *irqd;
 	unsigned int vector;
@@ -1097,10 +1099,11 @@
 		goto unlock;
 
 	/*
-	 * If prev_vector is empty, no action required.
+	 * If prev_vector is empty or the descriptor is neither currently
+	 * nor previously on the outgoing CPU no action required.
 	 */
 	vector = apicd->prev_vector;
-	if (!vector)
+	if (!vector || (apicd->cpu != cpu && apicd->prev_cpu != cpu))
 		goto unlock;
 
 	/*
--- linux-qcom-6.8.0.orig/arch/x86/kernel/callthunks.c
+++ linux-qcom-6.8.0/arch/x86/kernel/callthunks.c
@@ -141,11 +141,6 @@
 	    dest < (void*)relocate_kernel + KEXEC_CONTROL_CODE_MAX_SIZE)
 		return true;
 #endif
-#ifdef CONFIG_XEN
-	if (dest >= (void *)hypercall_page &&
-	    dest < (void*)hypercall_page + PAGE_SIZE)
-		return true;
-#endif
 	return false;
 }
 
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cet.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cet.c
@@ -81,6 +81,34 @@
 
 static __ro_after_init bool ibt_fatal = true;
 
+/*
+ * By definition, all missing-ENDBRANCH #CPs are a result of WFE && !ENDBR.
+ *
+ * For the kernel IBT no ENDBR selftest where #CPs are deliberately triggered,
+ * the WFE state of the interrupted context needs to be cleared to let execution
+ * continue.  Otherwise when the CPU resumes from the instruction that just
+ * caused the previous #CP, another missing-ENDBRANCH #CP is raised and the CPU
+ * enters a dead loop.
+ *
+ * This is not a problem with IDT because it doesn't preserve WFE and IRET doesn't
+ * set WFE.  But FRED provides space on the entry stack (in an expanded CS area)
+ * to save and restore the WFE state, thus the WFE state is no longer clobbered,
+ * so software must clear it.
+ */
+static void ibt_clear_fred_wfe(struct pt_regs *regs)
+{
+	/*
+	 * No need to do any FRED checks.
+	 *
+	 * For IDT event delivery, the high-order 48 bits of CS are pushed
+	 * as 0s into the stack, and later IRET ignores these bits.
+	 *
+	 * For FRED, a test to check if fred_cs.wfe is set would be dropped
+	 * by compilers.
+	 */
+	regs->fred_cs.wfe = 0;
+}
+
 static void do_kernel_cp_fault(struct pt_regs *regs, unsigned long error_code)
 {
 	if ((error_code & CP_EC) != CP_ENDBR) {
@@ -90,6 +118,7 @@
 
 	if (unlikely(regs->ip == (unsigned long)&ibt_selftest_noendbr)) {
 		regs->ax = 0;
+		ibt_clear_fred_wfe(regs);
 		return;
 	}
 
@@ -97,6 +126,7 @@
 	if (!ibt_fatal) {
 		printk(KERN_DEFAULT CUT_HERE);
 		__warn(__FILE__, __LINE__, (void *)regs->ip, TAINT_WARN, regs, NULL);
+		ibt_clear_fred_wfe(regs);
 		return;
 	}
 	BUG();
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/amd.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/amd.c
@@ -13,6 +13,7 @@
 #include <asm/apic.h>
 #include <asm/cacheinfo.h>
 #include <asm/cpu.h>
+#include <asm/cpu_device_id.h>
 #include <asm/spec-ctrl.h>
 #include <asm/smp.h>
 #include <asm/numa.h>
@@ -572,10 +573,9 @@
 
 	case 0x1a:
 		switch (c->x86_model) {
-		case 0x00 ... 0x0f:
-		case 0x20 ... 0x2f:
+		case 0x00 ... 0x2f:
 		case 0x40 ... 0x4f:
-		case 0x70 ... 0x7f:
+		case 0x60 ... 0x7f:
 			setup_force_cpu_cap(X86_FEATURE_ZEN5);
 			break;
 		default:
@@ -926,6 +926,12 @@
 	clear_rdrand_cpuid_bit(c);
 }
 
+static const struct x86_cpu_desc erratum_1386_microcode[] = {
+	AMD_CPU_DESC(0x17,  0x1, 0x2, 0x0800126e),
+	AMD_CPU_DESC(0x17, 0x31, 0x0, 0x08301052),
+	{},
+};
+
 static void fix_erratum_1386(struct cpuinfo_x86 *c)
 {
 	/*
@@ -935,7 +941,13 @@
 	 *
 	 * Affected parts all have no supervisor XSAVE states, meaning that
 	 * the XSAVEC instruction (which works fine) is equivalent.
+	 *
+	 * Clear the feature flag only on microcode revisions which
+	 * don't have the fix.
 	 */
+	if (x86_cpu_has_min_microcode_rev(erratum_1386_microcode))
+		return;
+
 	clear_cpu_cap(c, X86_FEATURE_XSAVES);
 }
 
@@ -989,11 +1001,11 @@
 	u32 good_rev = 0;
 
 	switch (boot_cpu_data.x86_model) {
-	case 0x30 ... 0x3f: good_rev = 0x0830107a; break;
-	case 0x60 ... 0x67: good_rev = 0x0860010b; break;
-	case 0x68 ... 0x6f: good_rev = 0x08608105; break;
-	case 0x70 ... 0x7f: good_rev = 0x08701032; break;
-	case 0xa0 ... 0xaf: good_rev = 0x08a00008; break;
+	case 0x30 ... 0x3f: good_rev = 0x0830107b; break;
+	case 0x60 ... 0x67: good_rev = 0x0860010c; break;
+	case 0x68 ... 0x6f: good_rev = 0x08608107; break;
+	case 0x70 ... 0x7f: good_rev = 0x08701033; break;
+	case 0xa0 ... 0xaf: good_rev = 0x08a00009; break;
 
 	default:
 		return false;
@@ -1050,6 +1062,17 @@
 
 	if (!cpu_has(c, X86_FEATURE_HYPERVISOR))
 		msr_set_bit(MSR_ZEN4_BP_CFG, MSR_ZEN4_BP_CFG_SHARED_BTB_FIX_BIT);
+
+	/*
+	 * These Zen4 SoCs advertise support for virtualized VMLOAD/VMSAVE
+	 * in some BIOS versions but they can lead to random host reboots.
+	 */
+	switch (c->x86_model) {
+	case 0x18 ... 0x1f:
+	case 0x60 ... 0x7f:
+		clear_cpu_cap(c, X86_FEATURE_V_VMSAVE_VMLOAD);
+		break;
+	}
 }
 
 static void init_amd_zen5(struct cpuinfo_x86 *c)
@@ -1178,7 +1201,7 @@
 	 */
 	if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) &&
 	    cpu_has(c, X86_FEATURE_AUTOIBRS))
-		WARN_ON_ONCE(msr_set_bit(MSR_EFER, _EFER_AUTOIBRS));
+		WARN_ON_ONCE(msr_set_bit(MSR_EFER, _EFER_AUTOIBRS) < 0);
 
 	/* AMD CPUs don't need fencing after x2APIC/TSC_DEADLINE MSR writes. */
 	clear_cpu_cap(c, X86_FEATURE_APIC_MSRS_FENCE);
@@ -1343,7 +1366,8 @@
 	if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
 		return;
 
-	on_each_cpu(zenbleed_check_cpu, NULL, 1);
+	if (cpu_feature_enabled(X86_FEATURE_ZEN2))
+		on_each_cpu(zenbleed_check_cpu, NULL, 1);
 }
 
 /*
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/bugs.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/bugs.c
@@ -61,6 +61,8 @@
 u64 x86_pred_cmd __ro_after_init = PRED_CMD_IBPB;
 EXPORT_SYMBOL_GPL(x86_pred_cmd);
 
+static u64 __ro_after_init x86_arch_cap_msr;
+
 static DEFINE_MUTEX(spec_ctrl_mutex);
 
 void (*x86_return_thunk)(void) __ro_after_init = __x86_return_thunk;
@@ -144,6 +146,8 @@
 		x86_spec_ctrl_base &= ~SPEC_CTRL_MITIGATIONS_MASK;
 	}
 
+	x86_arch_cap_msr = x86_read_arch_cap_msr();
+
 	/* Select the proper CPU mitigations before patching alternatives: */
 	spectre_v1_select_mitigation();
 	spectre_v2_select_mitigation();
@@ -301,8 +305,6 @@
 
 static void __init taa_select_mitigation(void)
 {
-	u64 ia32_cap;
-
 	if (!boot_cpu_has_bug(X86_BUG_TAA)) {
 		taa_mitigation = TAA_MITIGATION_OFF;
 		return;
@@ -341,9 +343,8 @@
 	 * On MDS_NO=1 CPUs if ARCH_CAP_TSX_CTRL_MSR is not set, microcode
 	 * update is required.
 	 */
-	ia32_cap = x86_read_arch_cap_msr();
-	if ( (ia32_cap & ARCH_CAP_MDS_NO) &&
-	    !(ia32_cap & ARCH_CAP_TSX_CTRL_MSR))
+	if ( (x86_arch_cap_msr & ARCH_CAP_MDS_NO) &&
+	    !(x86_arch_cap_msr & ARCH_CAP_TSX_CTRL_MSR))
 		taa_mitigation = TAA_MITIGATION_UCODE_NEEDED;
 
 	/*
@@ -401,8 +402,6 @@
 
 static void __init mmio_select_mitigation(void)
 {
-	u64 ia32_cap;
-
 	if (!boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA) ||
 	     boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN) ||
 	     cpu_mitigations_off()) {
@@ -413,8 +412,6 @@
 	if (mmio_mitigation == MMIO_MITIGATION_OFF)
 		return;
 
-	ia32_cap = x86_read_arch_cap_msr();
-
 	/*
 	 * Enable CPU buffer clear mitigation for host and VMM, if also affected
 	 * by MDS or TAA. Otherwise, enable mitigation for VMM only.
@@ -422,6 +419,13 @@
 	if (boot_cpu_has_bug(X86_BUG_MDS) || (boot_cpu_has_bug(X86_BUG_TAA) &&
 					      boot_cpu_has(X86_FEATURE_RTM)))
 		setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
+
+	/*
+	 * X86_FEATURE_CLEAR_CPU_BUF could be enabled by other VERW based
+	 * mitigations, disable KVM-only mitigation in that case.
+	 */
+	if (boot_cpu_has(X86_FEATURE_CLEAR_CPU_BUF))
+		static_branch_disable(&mmio_stale_data_clear);
 	else
 		static_branch_enable(&mmio_stale_data_clear);
 
@@ -430,7 +434,7 @@
 	 * be propagated to uncore buffers, clearing the Fill buffers on idle
 	 * is required irrespective of SMT state.
 	 */
-	if (!(ia32_cap & ARCH_CAP_FBSDP_NO))
+	if (!(x86_arch_cap_msr & ARCH_CAP_FBSDP_NO))
 		static_branch_enable(&mds_idle_clear);
 
 	/*
@@ -440,10 +444,10 @@
 	 * FB_CLEAR or by the presence of both MD_CLEAR and L1D_FLUSH on MDS
 	 * affected systems.
 	 */
-	if ((ia32_cap & ARCH_CAP_FB_CLEAR) ||
+	if ((x86_arch_cap_msr & ARCH_CAP_FB_CLEAR) ||
 	    (boot_cpu_has(X86_FEATURE_MD_CLEAR) &&
 	     boot_cpu_has(X86_FEATURE_FLUSH_L1D) &&
-	     !(ia32_cap & ARCH_CAP_MDS_NO)))
+	     !(x86_arch_cap_msr & ARCH_CAP_MDS_NO)))
 		mmio_mitigation = MMIO_MITIGATION_VERW;
 	else
 		mmio_mitigation = MMIO_MITIGATION_UCODE_NEEDED;
@@ -474,6 +478,57 @@
 early_param("mmio_stale_data", mmio_stale_data_parse_cmdline);
 
 #undef pr_fmt
+#define pr_fmt(fmt)	"Register File Data Sampling: " fmt
+
+enum rfds_mitigations {
+	RFDS_MITIGATION_OFF,
+	RFDS_MITIGATION_VERW,
+	RFDS_MITIGATION_UCODE_NEEDED,
+};
+
+/* Default mitigation for Register File Data Sampling */
+static enum rfds_mitigations rfds_mitigation __ro_after_init =
+	IS_ENABLED(CONFIG_MITIGATION_RFDS) ? RFDS_MITIGATION_VERW : RFDS_MITIGATION_OFF;
+
+static const char * const rfds_strings[] = {
+	[RFDS_MITIGATION_OFF]			= "Vulnerable",
+	[RFDS_MITIGATION_VERW]			= "Mitigation: Clear Register File",
+	[RFDS_MITIGATION_UCODE_NEEDED]		= "Vulnerable: No microcode",
+};
+
+static void __init rfds_select_mitigation(void)
+{
+	if (!boot_cpu_has_bug(X86_BUG_RFDS) || cpu_mitigations_off()) {
+		rfds_mitigation = RFDS_MITIGATION_OFF;
+		return;
+	}
+	if (rfds_mitigation == RFDS_MITIGATION_OFF)
+		return;
+
+	if (x86_arch_cap_msr & ARCH_CAP_RFDS_CLEAR)
+		setup_force_cpu_cap(X86_FEATURE_CLEAR_CPU_BUF);
+	else
+		rfds_mitigation = RFDS_MITIGATION_UCODE_NEEDED;
+}
+
+static __init int rfds_parse_cmdline(char *str)
+{
+	if (!str)
+		return -EINVAL;
+
+	if (!boot_cpu_has_bug(X86_BUG_RFDS))
+		return 0;
+
+	if (!strcmp(str, "off"))
+		rfds_mitigation = RFDS_MITIGATION_OFF;
+	else if (!strcmp(str, "on"))
+		rfds_mitigation = RFDS_MITIGATION_VERW;
+
+	return 0;
+}
+early_param("reg_file_data_sampling", rfds_parse_cmdline);
+
+#undef pr_fmt
 #define pr_fmt(fmt)     "" fmt
 
 static void __init md_clear_update_mitigation(void)
@@ -498,11 +553,19 @@
 		taa_mitigation = TAA_MITIGATION_VERW;
 		taa_select_mitigation();
 	}
-	if (mmio_mitigation == MMIO_MITIGATION_OFF &&
-	    boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) {
+	/*
+	 * MMIO_MITIGATION_OFF is not checked here so that mmio_stale_data_clear
+	 * gets updated correctly as per X86_FEATURE_CLEAR_CPU_BUF state.
+	 */
+	if (boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA)) {
 		mmio_mitigation = MMIO_MITIGATION_VERW;
 		mmio_select_mitigation();
 	}
+	if (rfds_mitigation == RFDS_MITIGATION_OFF &&
+	    boot_cpu_has_bug(X86_BUG_RFDS)) {
+		rfds_mitigation = RFDS_MITIGATION_VERW;
+		rfds_select_mitigation();
+	}
 out:
 	if (boot_cpu_has_bug(X86_BUG_MDS))
 		pr_info("MDS: %s\n", mds_strings[mds_mitigation]);
@@ -512,6 +575,8 @@
 		pr_info("MMIO Stale Data: %s\n", mmio_strings[mmio_mitigation]);
 	else if (boot_cpu_has_bug(X86_BUG_MMIO_UNKNOWN))
 		pr_info("MMIO Stale Data: Unknown: No mitigations\n");
+	if (boot_cpu_has_bug(X86_BUG_RFDS))
+		pr_info("Register File Data Sampling: %s\n", rfds_strings[rfds_mitigation]);
 }
 
 static void __init md_clear_select_mitigation(void)
@@ -519,11 +584,12 @@
 	mds_select_mitigation();
 	taa_select_mitigation();
 	mmio_select_mitigation();
+	rfds_select_mitigation();
 
 	/*
-	 * As MDS, TAA and MMIO Stale Data mitigations are inter-related, update
-	 * and print their mitigation after MDS, TAA and MMIO Stale Data
-	 * mitigation selection is done.
+	 * As these mitigations are inter-related and rely on VERW instruction
+	 * to clear the microarchitural buffers, update and print their status
+	 * after mitigation selection is done for each of these vulnerabilities.
 	 */
 	md_clear_update_mitigation();
 }
@@ -590,8 +656,6 @@
 
 static void __init srbds_select_mitigation(void)
 {
-	u64 ia32_cap;
-
 	if (!boot_cpu_has_bug(X86_BUG_SRBDS))
 		return;
 
@@ -600,8 +664,7 @@
 	 * are only exposed to SRBDS when TSX is enabled or when CPU is affected
 	 * by Processor MMIO Stale Data vulnerability.
 	 */
-	ia32_cap = x86_read_arch_cap_msr();
-	if ((ia32_cap & ARCH_CAP_MDS_NO) && !boot_cpu_has(X86_FEATURE_RTM) &&
+	if ((x86_arch_cap_msr & ARCH_CAP_MDS_NO) && !boot_cpu_has(X86_FEATURE_RTM) &&
 	    !boot_cpu_has_bug(X86_BUG_MMIO_STALE_DATA))
 		srbds_mitigation = SRBDS_MITIGATION_TSX_OFF;
 	else if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
@@ -744,7 +807,7 @@
 	/* Will verify below that mitigation _can_ be disabled */
 
 	/* No microcode */
-	if (!(x86_read_arch_cap_msr() & ARCH_CAP_GDS_CTRL)) {
+	if (!(x86_arch_cap_msr & ARCH_CAP_GDS_CTRL)) {
 		if (gds_mitigation == GDS_MITIGATION_FORCE) {
 			/*
 			 * This only needs to be done on the boot CPU so do it
@@ -1049,8 +1112,25 @@
 
 	case RETBLEED_MITIGATION_IBPB:
 		setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB);
+
+		/*
+		 * IBPB on entry already obviates the need for
+		 * software-based untraining so clear those in case some
+		 * other mitigation like SRSO has selected them.
+		 */
+		setup_clear_cpu_cap(X86_FEATURE_UNRET);
+		setup_clear_cpu_cap(X86_FEATURE_RETHUNK);
+
 		setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT);
 		mitigate_smt = true;
+
+		/*
+		 * There is no need for RSB filling: entry_ibpb() ensures
+		 * all predictions, including the RSB, are invalidated,
+		 * regardless of IBPB implementation.
+		 */
+		setup_clear_cpu_cap(X86_FEATURE_RSB_VMEXIT);
+
 		break;
 
 	case RETBLEED_MITIGATION_STUFF:
@@ -1474,20 +1554,25 @@
 	return SPECTRE_V2_RETPOLINE;
 }
 
+static bool __ro_after_init rrsba_disabled;
+
 /* Disable in-kernel use of non-RSB RET predictors */
 static void __init spec_ctrl_disable_kernel_rrsba(void)
 {
-	u64 ia32_cap;
+	if (rrsba_disabled)
+		return;
 
-	if (!boot_cpu_has(X86_FEATURE_RRSBA_CTRL))
+	if (!(x86_arch_cap_msr & ARCH_CAP_RRSBA)) {
+		rrsba_disabled = true;
 		return;
+	}
 
-	ia32_cap = x86_read_arch_cap_msr();
+	if (!boot_cpu_has(X86_FEATURE_RRSBA_CTRL))
+		return;
 
-	if (ia32_cap & ARCH_CAP_RRSBA) {
-		x86_spec_ctrl_base |= SPEC_CTRL_RRSBA_DIS_S;
-		update_spec_ctrl(x86_spec_ctrl_base);
-	}
+	x86_spec_ctrl_base |= SPEC_CTRL_RRSBA_DIS_S;
+	update_spec_ctrl(x86_spec_ctrl_base);
+	rrsba_disabled = true;
 }
 
 static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_mitigation mode)
@@ -1537,6 +1622,74 @@
 	dump_stack();
 }
 
+/*
+ * Set BHI_DIS_S to prevent indirect branches in kernel to be influenced by
+ * branch history in userspace. Not needed if BHI_NO is set.
+ */
+static bool __init spec_ctrl_bhi_dis(void)
+{
+	if (!boot_cpu_has(X86_FEATURE_BHI_CTRL))
+		return false;
+
+	x86_spec_ctrl_base |= SPEC_CTRL_BHI_DIS_S;
+	update_spec_ctrl(x86_spec_ctrl_base);
+	setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_HW);
+
+	return true;
+}
+
+enum bhi_mitigations {
+	BHI_MITIGATION_OFF,
+	BHI_MITIGATION_ON,
+};
+
+static enum bhi_mitigations bhi_mitigation __ro_after_init =
+	IS_ENABLED(CONFIG_MITIGATION_SPECTRE_BHI) ? BHI_MITIGATION_ON : BHI_MITIGATION_OFF;
+
+static int __init spectre_bhi_parse_cmdline(char *str)
+{
+	if (!str)
+		return -EINVAL;
+
+	if (!strcmp(str, "off"))
+		bhi_mitigation = BHI_MITIGATION_OFF;
+	else if (!strcmp(str, "on"))
+		bhi_mitigation = BHI_MITIGATION_ON;
+	else
+		pr_err("Ignoring unknown spectre_bhi option (%s)", str);
+
+	return 0;
+}
+early_param("spectre_bhi", spectre_bhi_parse_cmdline);
+
+static void __init bhi_select_mitigation(void)
+{
+	if (bhi_mitigation == BHI_MITIGATION_OFF)
+		return;
+
+	/* Retpoline mitigates against BHI unless the CPU has RRSBA behavior */
+	if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
+	    !boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE)) {
+		spec_ctrl_disable_kernel_rrsba();
+		if (rrsba_disabled)
+			return;
+	}
+
+	if (spec_ctrl_bhi_dis())
+		return;
+
+	if (!IS_ENABLED(CONFIG_X86_64))
+		return;
+
+	/* Mitigate KVM by default */
+	setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT);
+	pr_info("Spectre BHI mitigation: SW BHB clearing on vm exit\n");
+
+	/* Mitigate syscalls when the mitigation is forced =on */
+	setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP);
+	pr_info("Spectre BHI mitigation: SW BHB clearing on syscall\n");
+}
+
 static void __init spectre_v2_select_mitigation(void)
 {
 	enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline();
@@ -1648,6 +1801,9 @@
 	    mode == SPECTRE_V2_RETPOLINE)
 		spec_ctrl_disable_kernel_rrsba();
 
+	if (boot_cpu_has(X86_BUG_BHI))
+		bhi_select_mitigation();
+
 	spectre_v2_enabled = mode;
 	pr_info("%s\n", spectre_v2_strings[mode]);
 
@@ -1762,8 +1918,6 @@
 /* Update the static key controlling the MDS CPU buffer clear in idle */
 static void update_mds_branch_idle(void)
 {
-	u64 ia32_cap = x86_read_arch_cap_msr();
-
 	/*
 	 * Enable the idle clearing if SMT is active on CPUs which are
 	 * affected only by MSBDS and not any other MDS variant.
@@ -1778,7 +1932,7 @@
 	if (sched_smt_active()) {
 		static_branch_enable(&mds_idle_clear);
 	} else if (mmio_mitigation == MMIO_MITIGATION_OFF ||
-		   (ia32_cap & ARCH_CAP_FBSDP_NO)) {
+		   (x86_arch_cap_msr & ARCH_CAP_FBSDP_NO)) {
 		static_branch_disable(&mds_idle_clear);
 	}
 }
@@ -2407,10 +2561,9 @@
 {
 	bool has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE);
 
-	if (cpu_mitigations_off())
-		return;
-
-	if (!boot_cpu_has_bug(X86_BUG_SRSO)) {
+	if (!boot_cpu_has_bug(X86_BUG_SRSO) ||
+	    cpu_mitigations_off() ||
+	    srso_cmd == SRSO_CMD_OFF) {
 		if (boot_cpu_has(X86_FEATURE_SBPB))
 			x86_pred_cmd = PRED_CMD_SBPB;
 		return;
@@ -2441,11 +2594,6 @@
 	}
 
 	switch (srso_cmd) {
-	case SRSO_CMD_OFF:
-		if (boot_cpu_has(X86_FEATURE_SBPB))
-			x86_pred_cmd = PRED_CMD_SBPB;
-		return;
-
 	case SRSO_CMD_MICROCODE:
 		if (has_microcode) {
 			srso_mitigation = SRSO_MITIGATION_MICROCODE;
@@ -2483,6 +2631,14 @@
 			if (has_microcode) {
 				setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB);
 				srso_mitigation = SRSO_MITIGATION_IBPB;
+
+				/*
+				 * IBPB on entry already obviates the need for
+				 * software-based untraining so clear those in case some
+				 * other mitigation like Retbleed has selected them.
+				 */
+				setup_clear_cpu_cap(X86_FEATURE_UNRET);
+				setup_clear_cpu_cap(X86_FEATURE_RETHUNK);
 			}
 		} else {
 			pr_err("WARNING: kernel not compiled with CPU_IBPB_ENTRY.\n");
@@ -2494,11 +2650,20 @@
 			if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) {
 				setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT);
 				srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT;
+
+				/*
+				 * There is no need for RSB filling: entry_ibpb() ensures
+				 * all predictions, including the RSB, are invalidated,
+				 * regardless of IBPB implementation.
+				 */
+				setup_clear_cpu_cap(X86_FEATURE_RSB_VMEXIT);
 			}
 		} else {
 			pr_err("WARNING: kernel not compiled with CPU_SRSO.\n");
                 }
 		break;
+	default:
+		break;
 	}
 
 out:
@@ -2612,6 +2777,11 @@
 			  sched_smt_active() ? "vulnerable" : "disabled");
 }
 
+static ssize_t rfds_show_state(char *buf)
+{
+	return sysfs_emit(buf, "%s\n", rfds_strings[rfds_mitigation]);
+}
+
 static char *stibp_state(void)
 {
 	if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) &&
@@ -2620,15 +2790,15 @@
 
 	switch (spectre_v2_user_stibp) {
 	case SPECTRE_V2_USER_NONE:
-		return ", STIBP: disabled";
+		return "; STIBP: disabled";
 	case SPECTRE_V2_USER_STRICT:
-		return ", STIBP: forced";
+		return "; STIBP: forced";
 	case SPECTRE_V2_USER_STRICT_PREFERRED:
-		return ", STIBP: always-on";
+		return "; STIBP: always-on";
 	case SPECTRE_V2_USER_PRCTL:
 	case SPECTRE_V2_USER_SECCOMP:
 		if (static_key_enabled(&switch_to_cond_stibp))
-			return ", STIBP: conditional";
+			return "; STIBP: conditional";
 	}
 	return "";
 }
@@ -2637,10 +2807,10 @@
 {
 	if (boot_cpu_has(X86_FEATURE_IBPB)) {
 		if (static_key_enabled(&switch_mm_always_ibpb))
-			return ", IBPB: always-on";
+			return "; IBPB: always-on";
 		if (static_key_enabled(&switch_mm_cond_ibpb))
-			return ", IBPB: conditional";
-		return ", IBPB: disabled";
+			return "; IBPB: conditional";
+		return "; IBPB: disabled";
 	}
 	return "";
 }
@@ -2650,14 +2820,32 @@
 	if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) {
 		if (boot_cpu_has(X86_FEATURE_RSB_VMEXIT_LITE) ||
 		    boot_cpu_has(X86_FEATURE_RSB_VMEXIT))
-			return ", PBRSB-eIBRS: SW sequence";
+			return "; PBRSB-eIBRS: SW sequence";
 		else
-			return ", PBRSB-eIBRS: Vulnerable";
+			return "; PBRSB-eIBRS: Vulnerable";
 	} else {
-		return ", PBRSB-eIBRS: Not affected";
+		return "; PBRSB-eIBRS: Not affected";
 	}
 }
 
+static const char *spectre_bhi_state(void)
+{
+	if (!boot_cpu_has_bug(X86_BUG_BHI))
+		return "; BHI: Not affected";
+	else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_HW))
+		return "; BHI: BHI_DIS_S";
+	else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP))
+		return "; BHI: SW loop, KVM: SW loop";
+	else if (boot_cpu_has(X86_FEATURE_RETPOLINE) &&
+		 !boot_cpu_has(X86_FEATURE_RETPOLINE_LFENCE) &&
+		 rrsba_disabled)
+		return "; BHI: Retpoline";
+	else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT))
+		return "; BHI: Vulnerable, KVM: SW loop";
+
+	return "; BHI: Vulnerable";
+}
+
 static ssize_t spectre_v2_show_state(char *buf)
 {
 	if (spectre_v2_enabled == SPECTRE_V2_LFENCE)
@@ -2670,13 +2858,15 @@
 	    spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE)
 		return sysfs_emit(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n");
 
-	return sysfs_emit(buf, "%s%s%s%s%s%s%s\n",
+	return sysfs_emit(buf, "%s%s%s%s%s%s%s%s\n",
 			  spectre_v2_strings[spectre_v2_enabled],
 			  ibpb_state(),
-			  boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "",
+			  boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? "; IBRS_FW" : "",
 			  stibp_state(),
-			  boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "",
+			  boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? "; RSB filling" : "",
 			  pbrsb_eibrs_state(),
+			  spectre_bhi_state(),
+			  /* this should always be at the end */
 			  spectre_v2_module_string());
 }
 
@@ -2771,6 +2961,9 @@
 	case X86_BUG_GDS:
 		return gds_show_state(buf);
 
+	case X86_BUG_RFDS:
+		return rfds_show_state(buf);
+
 	default:
 		break;
 	}
@@ -2845,4 +3038,9 @@
 {
 	return cpu_show_common(dev, attr, buf, X86_BUG_GDS);
 }
+
+ssize_t cpu_show_reg_file_data_sampling(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return cpu_show_common(dev, attr, buf, X86_BUG_RFDS);
+}
 #endif
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/cacheinfo.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/cacheinfo.c
@@ -178,7 +178,16 @@
 	struct amd_northbridge *nb;
 };
 
-static unsigned short num_cache_leaves;
+static inline unsigned int get_num_cache_leaves(unsigned int cpu)
+{
+	return get_cpu_cacheinfo(cpu)->num_leaves;
+}
+
+static inline void
+set_num_cache_leaves(unsigned int nr_leaves, unsigned int cpu)
+{
+	get_cpu_cacheinfo(cpu)->num_leaves = nr_leaves;
+}
 
 /* AMD doesn't have CPUID4. Emulate it here to report the same
    information to the user.  This makes some assumptions about the machine:
@@ -718,19 +727,21 @@
 void init_amd_cacheinfo(struct cpuinfo_x86 *c)
 {
 
+	unsigned int cpu = c->cpu_index;
+
 	if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
-		num_cache_leaves = find_num_cache_leaves(c);
+		set_num_cache_leaves(find_num_cache_leaves(c), cpu);
 	} else if (c->extended_cpuid_level >= 0x80000006) {
 		if (cpuid_edx(0x80000006) & 0xf000)
-			num_cache_leaves = 4;
+			set_num_cache_leaves(4, cpu);
 		else
-			num_cache_leaves = 3;
+			set_num_cache_leaves(3, cpu);
 	}
 }
 
 void init_hygon_cacheinfo(struct cpuinfo_x86 *c)
 {
-	num_cache_leaves = find_num_cache_leaves(c);
+	set_num_cache_leaves(find_num_cache_leaves(c), c->cpu_index);
 }
 
 void init_intel_cacheinfo(struct cpuinfo_x86 *c)
@@ -742,19 +753,19 @@
 	unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb;
 
 	if (c->cpuid_level > 3) {
-		static int is_initialized;
-
-		if (is_initialized == 0) {
-			/* Init num_cache_leaves from boot CPU */
-			num_cache_leaves = find_num_cache_leaves(c);
-			is_initialized++;
-		}
+		/*
+		 * There should be at least one leaf. A non-zero value means
+		 * that the number of leaves has been initialized.
+		 */
+		if (!get_num_cache_leaves(c->cpu_index))
+			set_num_cache_leaves(find_num_cache_leaves(c),
+					     c->cpu_index);
 
 		/*
 		 * Whenever possible use cpuid(4), deterministic cache
 		 * parameters cpuid leaf to find the cache details
 		 */
-		for (i = 0; i < num_cache_leaves; i++) {
+		for (i = 0; i < get_num_cache_leaves(c->cpu_index); i++) {
 			struct _cpuid4_info_regs this_leaf = {};
 			int retval;
 
@@ -790,14 +801,14 @@
 	 * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
 	 * trace cache
 	 */
-	if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
+	if ((!get_num_cache_leaves(c->cpu_index) || c->x86 == 15) && c->cpuid_level > 1) {
 		/* supports eax=2  call */
 		int j, n;
 		unsigned int regs[4];
 		unsigned char *dp = (unsigned char *)regs;
 		int only_trace = 0;
 
-		if (num_cache_leaves != 0 && c->x86 == 15)
+		if (get_num_cache_leaves(c->cpu_index) && c->x86 == 15)
 			only_trace = 1;
 
 		/* Number of times to iterate */
@@ -991,14 +1002,6 @@
 
 int init_cache_level(unsigned int cpu)
 {
-	struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
-
-	if (!num_cache_leaves)
-		return -ENOENT;
-	if (!this_cpu_ci)
-		return -EINVAL;
-	this_cpu_ci->num_levels = 3;
-	this_cpu_ci->num_leaves = num_cache_leaves;
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/common.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/common.c
@@ -909,7 +909,7 @@
 #endif
 }
 
-static void get_cpu_vendor(struct cpuinfo_x86 *c)
+void get_cpu_vendor(struct cpuinfo_x86 *c)
 {
 	char *v = c->x86_vendor_id;
 	int i;
@@ -1096,18 +1096,9 @@
 void get_cpu_address_sizes(struct cpuinfo_x86 *c)
 {
 	u32 eax, ebx, ecx, edx;
-	bool vp_bits_from_cpuid = true;
 
 	if (!cpu_has(c, X86_FEATURE_CPUID) ||
-	    (c->extended_cpuid_level < 0x80000008))
-		vp_bits_from_cpuid = false;
-
-	if (vp_bits_from_cpuid) {
-		cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
-
-		c->x86_virt_bits = (eax >> 8) & 0xff;
-		c->x86_phys_bits = eax & 0xff;
-	} else {
+	    (c->extended_cpuid_level < 0x80000008)) {
 		if (IS_ENABLED(CONFIG_X86_64)) {
 			c->x86_clflush_size = 64;
 			c->x86_phys_bits = 36;
@@ -1121,7 +1112,17 @@
 			    cpu_has(c, X86_FEATURE_PSE36))
 				c->x86_phys_bits = 36;
 		}
+	} else {
+		cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
+
+		c->x86_virt_bits = (eax >> 8) & 0xff;
+		c->x86_phys_bits = eax & 0xff;
+
+		/* Provide a sane default if not enumerated: */
+		if (!c->x86_clflush_size)
+			c->x86_clflush_size = 32;
 	}
+
 	c->x86_cache_bits = c->x86_phys_bits;
 	c->x86_cache_alignment = c->x86_clflush_size;
 }
@@ -1163,6 +1164,7 @@
 #define NO_SPECTRE_V2		BIT(8)
 #define NO_MMIO			BIT(9)
 #define NO_EIBRS_PBRSB		BIT(10)
+#define NO_BHI			BIT(11)
 
 #define VULNWL(vendor, family, model, whitelist)	\
 	X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, whitelist)
@@ -1205,8 +1207,8 @@
 
 	VULNWL_INTEL(CORE_YONAH,		NO_SSB),
 
-	VULNWL_INTEL(ATOM_AIRMONT_MID,		NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT),
-	VULNWL_INTEL(ATOM_AIRMONT_NP,		NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
+	VULNWL_INTEL(ATOM_AIRMONT_MID,		NO_SSB | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | MSBDS_ONLY),
+	VULNWL_INTEL(ATOM_AIRMONT_NP,		NO_SSB | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
 
 	VULNWL_INTEL(ATOM_GOLDMONT,		NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
 	VULNWL_INTEL(ATOM_GOLDMONT_D,		NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
@@ -1225,18 +1227,18 @@
 	VULNWL_INTEL(ATOM_TREMONT_D,		NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB),
 
 	/* AMD Family 0xf - 0x12 */
-	VULNWL_AMD(0x0f,	NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
-	VULNWL_AMD(0x10,	NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
-	VULNWL_AMD(0x11,	NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
-	VULNWL_AMD(0x12,	NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
+	VULNWL_AMD(0x0f,	NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI),
+	VULNWL_AMD(0x10,	NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI),
+	VULNWL_AMD(0x11,	NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI),
+	VULNWL_AMD(0x12,	NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI),
 
 	/* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
-	VULNWL_AMD(X86_FAMILY_ANY,	NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB),
-	VULNWL_HYGON(X86_FAMILY_ANY,	NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB),
+	VULNWL_AMD(X86_FAMILY_ANY,	NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB | NO_BHI),
+	VULNWL_HYGON(X86_FAMILY_ANY,	NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB | NO_BHI),
 
 	/* Zhaoxin Family 7 */
-	VULNWL(CENTAUR,	7, X86_MODEL_ANY,	NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO),
-	VULNWL(ZHAOXIN,	7, X86_MODEL_ANY,	NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO),
+	VULNWL(CENTAUR,	7, X86_MODEL_ANY,	NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO | NO_BHI),
+	VULNWL(ZHAOXIN,	7, X86_MODEL_ANY,	NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO | NO_BHI),
 	{}
 };
 
@@ -1267,6 +1269,8 @@
 #define SRSO		BIT(5)
 /* CPU is affected by GDS */
 #define GDS		BIT(6)
+/* CPU is affected by Register File Data Sampling */
+#define RFDS		BIT(7)
 
 static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = {
 	VULNBL_INTEL_STEPPINGS(IVYBRIDGE,	X86_STEPPING_ANY,		SRBDS),
@@ -1294,9 +1298,18 @@
 	VULNBL_INTEL_STEPPINGS(TIGERLAKE,	X86_STEPPING_ANY,		GDS),
 	VULNBL_INTEL_STEPPINGS(LAKEFIELD,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RETBLEED),
 	VULNBL_INTEL_STEPPINGS(ROCKETLAKE,	X86_STEPPING_ANY,		MMIO | RETBLEED | GDS),
-	VULNBL_INTEL_STEPPINGS(ATOM_TREMONT,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS),
-	VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D,	X86_STEPPING_ANY,		MMIO),
-	VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS),
+	VULNBL_INTEL_STEPPINGS(ALDERLAKE,	X86_STEPPING_ANY,		RFDS),
+	VULNBL_INTEL_STEPPINGS(ALDERLAKE_L,	X86_STEPPING_ANY,		RFDS),
+	VULNBL_INTEL_STEPPINGS(RAPTORLAKE,	X86_STEPPING_ANY,		RFDS),
+	VULNBL_INTEL_STEPPINGS(RAPTORLAKE_P,	X86_STEPPING_ANY,		RFDS),
+	VULNBL_INTEL_STEPPINGS(RAPTORLAKE_S,	X86_STEPPING_ANY,		RFDS),
+	VULNBL_INTEL_STEPPINGS(ATOM_GRACEMONT,	X86_STEPPING_ANY,		RFDS),
+	VULNBL_INTEL_STEPPINGS(ATOM_TREMONT,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RFDS),
+	VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D,	X86_STEPPING_ANY,		MMIO | RFDS),
+	VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L,	X86_STEPPING_ANY,		MMIO | MMIO_SBDS | RFDS),
+	VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT,	X86_STEPPING_ANY,		RFDS),
+	VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT_D,	X86_STEPPING_ANY,		RFDS),
+	VULNBL_INTEL_STEPPINGS(ATOM_GOLDMONT_PLUS, X86_STEPPING_ANY,		RFDS),
 
 	VULNBL_AMD(0x15, RETBLEED),
 	VULNBL_AMD(0x16, RETBLEED),
@@ -1315,28 +1328,46 @@
 
 u64 x86_read_arch_cap_msr(void)
 {
-	u64 ia32_cap = 0;
+	u64 x86_arch_cap_msr = 0;
 
 	if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES))
-		rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap);
+		rdmsrl(MSR_IA32_ARCH_CAPABILITIES, x86_arch_cap_msr);
 
-	return ia32_cap;
+	return x86_arch_cap_msr;
 }
 
-static bool arch_cap_mmio_immune(u64 ia32_cap)
+static bool arch_cap_mmio_immune(u64 x86_arch_cap_msr)
 {
-	return (ia32_cap & ARCH_CAP_FBSDP_NO &&
-		ia32_cap & ARCH_CAP_PSDP_NO &&
-		ia32_cap & ARCH_CAP_SBDR_SSDP_NO);
+	return (x86_arch_cap_msr & ARCH_CAP_FBSDP_NO &&
+		x86_arch_cap_msr & ARCH_CAP_PSDP_NO &&
+		x86_arch_cap_msr & ARCH_CAP_SBDR_SSDP_NO);
+}
+
+static bool __init vulnerable_to_rfds(u64 x86_arch_cap_msr)
+{
+	/* The "immunity" bit trumps everything else: */
+	if (x86_arch_cap_msr & ARCH_CAP_RFDS_NO)
+		return false;
+
+	/*
+	 * VMMs set ARCH_CAP_RFDS_CLEAR for processors not in the blacklist to
+	 * indicate that mitigation is needed because guest is running on a
+	 * vulnerable hardware or may migrate to such hardware:
+	 */
+	if (x86_arch_cap_msr & ARCH_CAP_RFDS_CLEAR)
+		return true;
+
+	/* Only consult the blacklist when there is no enumeration: */
+	return cpu_matches(cpu_vuln_blacklist, RFDS);
 }
 
 static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
 {
-	u64 ia32_cap = x86_read_arch_cap_msr();
+	u64 x86_arch_cap_msr = x86_read_arch_cap_msr();
 
 	/* Set ITLB_MULTIHIT bug if cpu is not in the whitelist and not mitigated */
 	if (!cpu_matches(cpu_vuln_whitelist, NO_ITLB_MULTIHIT) &&
-	    !(ia32_cap & ARCH_CAP_PSCHANGE_MC_NO))
+	    !(x86_arch_cap_msr & ARCH_CAP_PSCHANGE_MC_NO))
 		setup_force_cpu_bug(X86_BUG_ITLB_MULTIHIT);
 
 	if (cpu_matches(cpu_vuln_whitelist, NO_SPECULATION))
@@ -1348,7 +1379,7 @@
 		setup_force_cpu_bug(X86_BUG_SPECTRE_V2);
 
 	if (!cpu_matches(cpu_vuln_whitelist, NO_SSB) &&
-	    !(ia32_cap & ARCH_CAP_SSB_NO) &&
+	    !(x86_arch_cap_msr & ARCH_CAP_SSB_NO) &&
 	   !cpu_has(c, X86_FEATURE_AMD_SSB_NO))
 		setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS);
 
@@ -1356,15 +1387,15 @@
 	 * AMD's AutoIBRS is equivalent to Intel's eIBRS - use the Intel feature
 	 * flag and protect from vendor-specific bugs via the whitelist.
 	 */
-	if ((ia32_cap & ARCH_CAP_IBRS_ALL) || cpu_has(c, X86_FEATURE_AUTOIBRS)) {
+	if ((x86_arch_cap_msr & ARCH_CAP_IBRS_ALL) || cpu_has(c, X86_FEATURE_AUTOIBRS)) {
 		setup_force_cpu_cap(X86_FEATURE_IBRS_ENHANCED);
 		if (!cpu_matches(cpu_vuln_whitelist, NO_EIBRS_PBRSB) &&
-		    !(ia32_cap & ARCH_CAP_PBRSB_NO))
+		    !(x86_arch_cap_msr & ARCH_CAP_PBRSB_NO))
 			setup_force_cpu_bug(X86_BUG_EIBRS_PBRSB);
 	}
 
 	if (!cpu_matches(cpu_vuln_whitelist, NO_MDS) &&
-	    !(ia32_cap & ARCH_CAP_MDS_NO)) {
+	    !(x86_arch_cap_msr & ARCH_CAP_MDS_NO)) {
 		setup_force_cpu_bug(X86_BUG_MDS);
 		if (cpu_matches(cpu_vuln_whitelist, MSBDS_ONLY))
 			setup_force_cpu_bug(X86_BUG_MSBDS_ONLY);
@@ -1383,9 +1414,9 @@
 	 * TSX_CTRL check alone is not sufficient for cases when the microcode
 	 * update is not present or running as guest that don't get TSX_CTRL.
 	 */
-	if (!(ia32_cap & ARCH_CAP_TAA_NO) &&
+	if (!(x86_arch_cap_msr & ARCH_CAP_TAA_NO) &&
 	    (cpu_has(c, X86_FEATURE_RTM) ||
-	     (ia32_cap & ARCH_CAP_TSX_CTRL_MSR)))
+	     (x86_arch_cap_msr & ARCH_CAP_TSX_CTRL_MSR)))
 		setup_force_cpu_bug(X86_BUG_TAA);
 
 	/*
@@ -1411,7 +1442,7 @@
 	 * Set X86_BUG_MMIO_UNKNOWN for CPUs that are neither in the blacklist,
 	 * nor in the whitelist and also don't enumerate MSR ARCH_CAP MMIO bits.
 	 */
-	if (!arch_cap_mmio_immune(ia32_cap)) {
+	if (!arch_cap_mmio_immune(x86_arch_cap_msr)) {
 		if (cpu_matches(cpu_vuln_blacklist, MMIO))
 			setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA);
 		else if (!cpu_matches(cpu_vuln_whitelist, NO_MMIO))
@@ -1419,7 +1450,7 @@
 	}
 
 	if (!cpu_has(c, X86_FEATURE_BTC_NO)) {
-		if (cpu_matches(cpu_vuln_blacklist, RETBLEED) || (ia32_cap & ARCH_CAP_RSBA))
+		if (cpu_matches(cpu_vuln_blacklist, RETBLEED) || (x86_arch_cap_msr & ARCH_CAP_RSBA))
 			setup_force_cpu_bug(X86_BUG_RETBLEED);
 	}
 
@@ -1437,15 +1468,28 @@
 	 * disabling AVX2. The only way to do this in HW is to clear XCR0[2],
 	 * which means that AVX will be disabled.
 	 */
-	if (cpu_matches(cpu_vuln_blacklist, GDS) && !(ia32_cap & ARCH_CAP_GDS_NO) &&
+	if (cpu_matches(cpu_vuln_blacklist, GDS) && !(x86_arch_cap_msr & ARCH_CAP_GDS_NO) &&
 	    boot_cpu_has(X86_FEATURE_AVX))
 		setup_force_cpu_bug(X86_BUG_GDS);
 
+	if (vulnerable_to_rfds(x86_arch_cap_msr))
+		setup_force_cpu_bug(X86_BUG_RFDS);
+
+	/* When virtualized, eIBRS could be hidden, assume vulnerable */
+	if (!(x86_arch_cap_msr & ARCH_CAP_BHI_NO) &&
+	    !cpu_matches(cpu_vuln_whitelist, NO_BHI) &&
+	    (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED) ||
+	     boot_cpu_has(X86_FEATURE_HYPERVISOR)))
+		setup_force_cpu_bug(X86_BUG_BHI);
+
+	if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, X86_FEATURE_AMD_IBPB_RET))
+		setup_force_cpu_bug(X86_BUG_IBPB_NO_RET);
+
 	if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN))
 		return;
 
 	/* Rogue Data Cache Load? No! */
-	if (ia32_cap & ARCH_CAP_RDCL_NO)
+	if (x86_arch_cap_msr & ARCH_CAP_RDCL_NO)
 		return;
 
 	setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN);
@@ -1587,6 +1631,7 @@
 	if (have_cpuid_p()) {
 		cpu_detect(c);
 		get_cpu_vendor(c);
+		intel_unlock_cpuid_leafs(c);
 		get_cpu_cap(c);
 		setup_force_cpu_cap(X86_FEATURE_CPUID);
 		get_cpu_address_sizes(c);
@@ -1637,15 +1682,11 @@
 	detect_nopl();
 }
 
-void __init early_cpu_init(void)
+void __init init_cpu_devs(void)
 {
 	const struct cpu_dev *const *cdev;
 	int count = 0;
 
-#ifdef CONFIG_PROCESSOR_SELECT
-	pr_info("KERNEL supported cpus:\n");
-#endif
-
 	for (cdev = __x86_cpu_dev_start; cdev < __x86_cpu_dev_end; cdev++) {
 		const struct cpu_dev *cpudev = *cdev;
 
@@ -1653,20 +1694,30 @@
 			break;
 		cpu_devs[count] = cpudev;
 		count++;
+	}
+}
 
+void __init early_cpu_init(void)
+{
 #ifdef CONFIG_PROCESSOR_SELECT
-		{
-			unsigned int j;
+	unsigned int i, j;
 
-			for (j = 0; j < 2; j++) {
-				if (!cpudev->c_ident[j])
-					continue;
-				pr_info("  %s %s\n", cpudev->c_vendor,
-					cpudev->c_ident[j]);
-			}
-		}
+	pr_info("KERNEL supported cpus:\n");
 #endif
+
+	init_cpu_devs();
+
+#ifdef CONFIG_PROCESSOR_SELECT
+	for (i = 0; i < X86_VENDOR_NUM && cpu_devs[i]; i++) {
+		for (j = 0; j < 2; j++) {
+			if (!cpu_devs[i]->c_ident[j])
+				continue;
+			pr_info("  %s %s\n", cpu_devs[i]->c_vendor,
+				cpu_devs[i]->c_ident[j]);
+		}
 	}
+#endif
+
 	early_identify_cpu(&boot_cpu_data);
 }
 
@@ -1743,7 +1794,7 @@
 	cpu_detect(c);
 
 	get_cpu_vendor(c);
-
+	intel_unlock_cpuid_leafs(c);
 	get_cpu_cap(c);
 
 	get_cpu_address_sizes(c);
@@ -2108,8 +2159,10 @@
 
 #ifdef CONFIG_STACKPROTECTOR
 DEFINE_PER_CPU(unsigned long, __stack_chk_guard);
+#ifndef CONFIG_SMP
 EXPORT_PER_CPU_SYMBOL(__stack_chk_guard);
 #endif
+#endif
 
 #endif	/* CONFIG_X86_64 */
 
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/cpu.h
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/cpu.h
@@ -56,9 +56,11 @@
 
 extern void __init tsx_init(void);
 void tsx_ap_init(void);
+void intel_unlock_cpuid_leafs(struct cpuinfo_x86 *c);
 #else
 static inline void tsx_init(void) { }
 static inline void tsx_ap_init(void) { }
+static inline void intel_unlock_cpuid_leafs(struct cpuinfo_x86 *c) { }
 #endif /* CONFIG_CPU_SUP_INTEL */
 
 extern void init_spectral_chicken(struct cpuinfo_x86 *c);
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/cpuid-deps.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/cpuid-deps.c
@@ -44,7 +44,10 @@
 	{ X86_FEATURE_F16C,			X86_FEATURE_XMM2,     },
 	{ X86_FEATURE_AES,			X86_FEATURE_XMM2      },
 	{ X86_FEATURE_SHA_NI,			X86_FEATURE_XMM2      },
+	{ X86_FEATURE_GFNI,			X86_FEATURE_XMM2      },
 	{ X86_FEATURE_FMA,			X86_FEATURE_AVX       },
+	{ X86_FEATURE_VAES,			X86_FEATURE_AVX       },
+	{ X86_FEATURE_VPCLMULQDQ,		X86_FEATURE_AVX       },
 	{ X86_FEATURE_AVX2,			X86_FEATURE_AVX,      },
 	{ X86_FEATURE_AVX512F,			X86_FEATURE_AVX,      },
 	{ X86_FEATURE_AVX512IFMA,		X86_FEATURE_AVX512F   },
@@ -56,9 +59,6 @@
 	{ X86_FEATURE_AVX512VL,			X86_FEATURE_AVX512F   },
 	{ X86_FEATURE_AVX512VBMI,		X86_FEATURE_AVX512F   },
 	{ X86_FEATURE_AVX512_VBMI2,		X86_FEATURE_AVX512VL  },
-	{ X86_FEATURE_GFNI,			X86_FEATURE_AVX512VL  },
-	{ X86_FEATURE_VAES,			X86_FEATURE_AVX512VL  },
-	{ X86_FEATURE_VPCLMULQDQ,		X86_FEATURE_AVX512VL  },
 	{ X86_FEATURE_AVX512_VNNI,		X86_FEATURE_AVX512VL  },
 	{ X86_FEATURE_AVX512_BITALG,		X86_FEATURE_AVX512VL  },
 	{ X86_FEATURE_AVX512_4VNNIW,		X86_FEATURE_AVX512F   },
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/intel.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/intel.c
@@ -72,19 +72,19 @@
  */
 static void check_memory_type_self_snoop_errata(struct cpuinfo_x86 *c)
 {
-	switch (c->x86_model) {
-	case INTEL_FAM6_CORE_YONAH:
-	case INTEL_FAM6_CORE2_MEROM:
-	case INTEL_FAM6_CORE2_MEROM_L:
-	case INTEL_FAM6_CORE2_PENRYN:
-	case INTEL_FAM6_CORE2_DUNNINGTON:
-	case INTEL_FAM6_NEHALEM:
-	case INTEL_FAM6_NEHALEM_G:
-	case INTEL_FAM6_NEHALEM_EP:
-	case INTEL_FAM6_NEHALEM_EX:
-	case INTEL_FAM6_WESTMERE:
-	case INTEL_FAM6_WESTMERE_EP:
-	case INTEL_FAM6_SANDYBRIDGE:
+	switch (c->x86_vfm) {
+	case INTEL_CORE_YONAH:
+	case INTEL_CORE2_MEROM:
+	case INTEL_CORE2_MEROM_L:
+	case INTEL_CORE2_PENRYN:
+	case INTEL_CORE2_DUNNINGTON:
+	case INTEL_NEHALEM:
+	case INTEL_NEHALEM_G:
+	case INTEL_NEHALEM_EP:
+	case INTEL_NEHALEM_EX:
+	case INTEL_WESTMERE:
+	case INTEL_WESTMERE_EP:
+	case INTEL_SANDYBRIDGE:
 		setup_clear_cpu_cap(X86_FEATURE_SELFSNOOP);
 	}
 }
@@ -106,9 +106,9 @@
 	 */
 	if (c->x86 != 6)
 		return;
-	switch (c->x86_model) {
-	case INTEL_FAM6_XEON_PHI_KNL:
-	case INTEL_FAM6_XEON_PHI_KNM:
+	switch (c->x86_vfm) {
+	case INTEL_XEON_PHI_KNL:
+	case INTEL_XEON_PHI_KNM:
 		break;
 	default:
 		return;
@@ -134,32 +134,32 @@
  * - Release note from 20180108 microcode release
  */
 struct sku_microcode {
-	u8 model;
+	u32 vfm;
 	u8 stepping;
 	u32 microcode;
 };
 static const struct sku_microcode spectre_bad_microcodes[] = {
-	{ INTEL_FAM6_KABYLAKE,		0x0B,	0x80 },
-	{ INTEL_FAM6_KABYLAKE,		0x0A,	0x80 },
-	{ INTEL_FAM6_KABYLAKE,		0x09,	0x80 },
-	{ INTEL_FAM6_KABYLAKE_L,	0x0A,	0x80 },
-	{ INTEL_FAM6_KABYLAKE_L,	0x09,	0x80 },
-	{ INTEL_FAM6_SKYLAKE_X,		0x03,	0x0100013e },
-	{ INTEL_FAM6_SKYLAKE_X,		0x04,	0x0200003c },
-	{ INTEL_FAM6_BROADWELL,		0x04,	0x28 },
-	{ INTEL_FAM6_BROADWELL_G,	0x01,	0x1b },
-	{ INTEL_FAM6_BROADWELL_D,	0x02,	0x14 },
-	{ INTEL_FAM6_BROADWELL_D,	0x03,	0x07000011 },
-	{ INTEL_FAM6_BROADWELL_X,	0x01,	0x0b000025 },
-	{ INTEL_FAM6_HASWELL_L,		0x01,	0x21 },
-	{ INTEL_FAM6_HASWELL_G,		0x01,	0x18 },
-	{ INTEL_FAM6_HASWELL,		0x03,	0x23 },
-	{ INTEL_FAM6_HASWELL_X,		0x02,	0x3b },
-	{ INTEL_FAM6_HASWELL_X,		0x04,	0x10 },
-	{ INTEL_FAM6_IVYBRIDGE_X,	0x04,	0x42a },
+	{ INTEL_KABYLAKE,	0x0B,	0x80 },
+	{ INTEL_KABYLAKE,	0x0A,	0x80 },
+	{ INTEL_KABYLAKE,	0x09,	0x80 },
+	{ INTEL_KABYLAKE_L,	0x0A,	0x80 },
+	{ INTEL_KABYLAKE_L,	0x09,	0x80 },
+	{ INTEL_SKYLAKE_X,	0x03,	0x0100013e },
+	{ INTEL_SKYLAKE_X,	0x04,	0x0200003c },
+	{ INTEL_BROADWELL,	0x04,	0x28 },
+	{ INTEL_BROADWELL_G,	0x01,	0x1b },
+	{ INTEL_BROADWELL_D,	0x02,	0x14 },
+	{ INTEL_BROADWELL_D,	0x03,	0x07000011 },
+	{ INTEL_BROADWELL_X,	0x01,	0x0b000025 },
+	{ INTEL_HASWELL_L,	0x01,	0x21 },
+	{ INTEL_HASWELL_G,	0x01,	0x18 },
+	{ INTEL_HASWELL,	0x03,	0x23 },
+	{ INTEL_HASWELL_X,	0x02,	0x3b },
+	{ INTEL_HASWELL_X,	0x04,	0x10 },
+	{ INTEL_IVYBRIDGE_X,	0x04,	0x42a },
 	/* Observed in the wild */
-	{ INTEL_FAM6_SANDYBRIDGE_X,	0x06,	0x61b },
-	{ INTEL_FAM6_SANDYBRIDGE_X,	0x07,	0x712 },
+	{ INTEL_SANDYBRIDGE_X,	0x06,	0x61b },
+	{ INTEL_SANDYBRIDGE_X,	0x07,	0x712 },
 };
 
 static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
@@ -173,11 +173,8 @@
 	if (cpu_has(c, X86_FEATURE_HYPERVISOR))
 		return false;
 
-	if (c->x86 != 6)
-		return false;
-
 	for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) {
-		if (c->x86_model == spectre_bad_microcodes[i].model &&
+		if (c->x86_vfm == spectre_bad_microcodes[i].vfm &&
 		    c->x86_stepping == spectre_bad_microcodes[i].stepping)
 			return (c->microcode <= spectre_bad_microcodes[i].microcode);
 	}
@@ -268,19 +265,26 @@
 	c->x86_phys_bits -= keyid_bits;
 }
 
+void intel_unlock_cpuid_leafs(struct cpuinfo_x86 *c)
+{
+	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+		return;
+
+	if (c->x86 < 6 || (c->x86 == 6 && c->x86_model < 0xd))
+		return;
+
+	/*
+	 * The BIOS can have limited CPUID to leaf 2, which breaks feature
+	 * enumeration. Unlock it and update the maximum leaf info.
+	 */
+	if (msr_clear_bit(MSR_IA32_MISC_ENABLE, MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT) > 0)
+		c->cpuid_level = cpuid_eax(0);
+}
+
 static void early_init_intel(struct cpuinfo_x86 *c)
 {
 	u64 misc_enable;
 
-	/* Unmask CPUID levels if masked: */
-	if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) {
-		if (msr_clear_bit(MSR_IA32_MISC_ENABLE,
-				  MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT) > 0) {
-			c->cpuid_level = cpuid_eax(0);
-			get_cpu_cap(c);
-		}
-	}
-
 	if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
 		(c->x86 == 0x6 && c->x86_model >= 0x0e))
 		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
@@ -312,7 +316,7 @@
 	 * need the microcode to have already been loaded... so if it is
 	 * not, recommend a BIOS update and disable large pages.
 	 */
-	if (c->x86 == 6 && c->x86_model == 0x1c && c->x86_stepping <= 2 &&
+	if (c->x86_vfm == INTEL_ATOM_BONNELL && c->x86_stepping <= 2 &&
 	    c->microcode < 0x20e) {
 		pr_warn("Atom PSE erratum detected, BIOS microcode update recommended\n");
 		clear_cpu_cap(c, X86_FEATURE_PSE);
@@ -344,17 +348,13 @@
 	}
 
 	/* Penwell and Cloverview have the TSC which doesn't sleep on S3 */
-	if (c->x86 == 6) {
-		switch (c->x86_model) {
-		case INTEL_FAM6_ATOM_SALTWELL_MID:
-		case INTEL_FAM6_ATOM_SALTWELL_TABLET:
-		case INTEL_FAM6_ATOM_SILVERMONT_MID:
-		case INTEL_FAM6_ATOM_AIRMONT_NP:
-			set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC_S3);
-			break;
-		default:
-			break;
-		}
+	switch (c->x86_vfm) {
+	case INTEL_ATOM_SALTWELL_MID:
+	case INTEL_ATOM_SALTWELL_TABLET:
+	case INTEL_ATOM_SILVERMONT_MID:
+	case INTEL_ATOM_AIRMONT_NP:
+		set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC_S3);
+		break;
 	}
 
 	/*
@@ -393,7 +393,7 @@
 	 * should be false so that __flush_tlb_all() causes CR3 instead of CR4.PGE
 	 * to be modified.
 	 */
-	if (c->x86 == 5 && c->x86_model == 9) {
+	if (c->x86_vfm == INTEL_QUARK_X1000) {
 		pr_info("Disabling PGE capability bit\n");
 		setup_clear_cpu_cap(X86_FEATURE_PGE);
 	}
@@ -650,12 +650,15 @@
 			set_cpu_cap(c, X86_FEATURE_PEBS);
 	}
 
-	if (c->x86 == 6 && boot_cpu_has(X86_FEATURE_CLFLUSH) &&
-	    (c->x86_model == 29 || c->x86_model == 46 || c->x86_model == 47))
+	if (boot_cpu_has(X86_FEATURE_CLFLUSH) &&
+	    (c->x86_vfm == INTEL_CORE2_DUNNINGTON ||
+	     c->x86_vfm == INTEL_NEHALEM_EX ||
+	     c->x86_vfm == INTEL_WESTMERE_EX))
 		set_cpu_bug(c, X86_BUG_CLFLUSH_MONITOR);
 
-	if (c->x86 == 6 && boot_cpu_has(X86_FEATURE_MWAIT) &&
-		((c->x86_model == INTEL_FAM6_ATOM_GOLDMONT)))
+	if (boot_cpu_has(X86_FEATURE_MWAIT) &&
+	    (c->x86_vfm == INTEL_ATOM_GOLDMONT ||
+	     c->x86_vfm == INTEL_LUNARLAKE_M))
 		set_cpu_bug(c, X86_BUG_MONITOR);
 
 #ifdef CONFIG_X86_64
@@ -1271,9 +1274,9 @@
  * feature even though they do not enumerate IA32_CORE_CAPABILITIES.
  */
 static const struct x86_cpu_id split_lock_cpu_ids[] __initconst = {
-	X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X,	0),
-	X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L,	0),
-	X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_D,	0),
+	X86_MATCH_VFM(INTEL_ICELAKE_X,	0),
+	X86_MATCH_VFM(INTEL_ICELAKE_L,	0),
+	X86_MATCH_VFM(INTEL_ICELAKE_D,	0),
 	{}
 };
 
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/match.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/match.c
@@ -17,8 +17,7 @@
  *
  * A typical table entry would be to match a specific CPU
  *
- * X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, INTEL_FAM6_BROADWELL,
- *				      X86_FEATURE_ANY, NULL);
+ * X86_MATCH_VFM_FEATURE(INTEL_BROADWELL, X86_FEATURE_ANY, NULL);
  *
  * Fields can be wildcarded with %X86_VENDOR_ANY, %X86_FAMILY_ANY,
  * %X86_MODEL_ANY, %X86_FEATURE_ANY (except for vendor)
@@ -39,9 +38,7 @@
 	const struct x86_cpu_id *m;
 	struct cpuinfo_x86 *c = &boot_cpu_data;
 
-	for (m = match;
-	     m->vendor | m->family | m->model | m->steppings | m->feature;
-	     m++) {
+	for (m = match; m->flags & X86_CPU_ID_FLAG_ENTRY_VALID; m++) {
 		if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor)
 			continue;
 		if (m->family != X86_FAMILY_ANY && c->x86 != m->family)
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/mce/core.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/mce/core.c
@@ -2474,12 +2474,14 @@
 		return -EINVAL;
 
 	b = &per_cpu(mce_banks_array, s->id)[bank];
-
 	if (!b->init)
 		return -ENODEV;
 
 	b->ctl = new;
+
+	mutex_lock(&mce_sysfs_mutex);
 	mce_restart();
+	mutex_unlock(&mce_sysfs_mutex);
 
 	return size;
 }
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/microcode/amd.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/microcode/amd.c
@@ -465,7 +465,7 @@
 	return !__apply_microcode_amd(mc);
 }
 
-static bool get_builtin_microcode(struct cpio_data *cp, unsigned int family)
+static bool get_builtin_microcode(struct cpio_data *cp, u8 family)
 {
 	char fw_name[36] = "amd-ucode/microcode_amd.bin";
 	struct firmware fw;
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/mshyperv.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/mshyperv.c
@@ -199,8 +199,8 @@
 	 * Call hv_cpu_die() on all the CPUs, otherwise later the hypervisor
 	 * corrupts the old VP Assist Pages and can crash the kexec kernel.
 	 */
-	if (kexec_in_progress && hyperv_init_cpuhp > 0)
-		cpuhp_remove_state(hyperv_init_cpuhp);
+	if (kexec_in_progress)
+		cpuhp_remove_state(CPUHP_AP_HYPERV_ONLINE);
 
 	/* The function calls stop_other_cpus(). */
 	native_machine_shutdown();
@@ -222,6 +222,63 @@
 	hyperv_cleanup();
 }
 #endif /* CONFIG_KEXEC_CORE */
+
+static u64 hv_ref_counter_at_suspend;
+static void (*old_save_sched_clock_state)(void);
+static void (*old_restore_sched_clock_state)(void);
+
+/*
+ * Hyper-V clock counter resets during hibernation. Save and restore clock
+ * offset during suspend/resume, while also considering the time passed
+ * before suspend. This is to make sure that sched_clock using hv tsc page
+ * based clocksource, proceeds from where it left off during suspend and
+ * it shows correct time for the timestamps of kernel messages after resume.
+ */
+static void save_hv_clock_tsc_state(void)
+{
+	hv_ref_counter_at_suspend = hv_read_reference_counter();
+}
+
+static void restore_hv_clock_tsc_state(void)
+{
+	/*
+	 * Adjust the offsets used by hv tsc clocksource to
+	 * account for the time spent before hibernation.
+	 * adjusted value = reference counter (time) at suspend
+	 *                - reference counter (time) now.
+	 */
+	hv_adj_sched_clock_offset(hv_ref_counter_at_suspend - hv_read_reference_counter());
+}
+
+/*
+ * Functions to override save_sched_clock_state and restore_sched_clock_state
+ * functions of x86_platform. The Hyper-V clock counter is reset during
+ * suspend-resume and the offset used to measure time needs to be
+ * corrected, post resume.
+ */
+static void hv_save_sched_clock_state(void)
+{
+	old_save_sched_clock_state();
+	save_hv_clock_tsc_state();
+}
+
+static void hv_restore_sched_clock_state(void)
+{
+	restore_hv_clock_tsc_state();
+	old_restore_sched_clock_state();
+}
+
+static void __init x86_setup_ops_for_tsc_pg_clock(void)
+{
+	if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE))
+		return;
+
+	old_save_sched_clock_state = x86_platform.save_sched_clock_state;
+	x86_platform.save_sched_clock_state = hv_save_sched_clock_state;
+
+	old_restore_sched_clock_state = x86_platform.restore_sched_clock_state;
+	x86_platform.restore_sched_clock_state = hv_restore_sched_clock_state;
+}
 #endif /* CONFIG_HYPERV */
 
 static uint32_t  __init ms_hyperv_platform(void)
@@ -426,6 +483,7 @@
 	    ms_hyperv.misc_features & HV_FEATURE_FREQUENCY_MSRS_AVAILABLE) {
 		x86_platform.calibrate_tsc = hv_get_tsc_khz;
 		x86_platform.calibrate_cpu = hv_get_tsc_khz;
+		setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
 	}
 
 	if (ms_hyperv.priv_high & HV_ISOLATION) {
@@ -451,9 +509,23 @@
 			ms_hyperv.hints &= ~HV_X64_APIC_ACCESS_RECOMMENDED;
 
 			if (!ms_hyperv.paravisor_present) {
-				/* To be supported: more work is required.  */
+				/*
+				 * Mark the Hyper-V TSC page feature as disabled
+				 * in a TDX VM without paravisor so that the
+				 * Invariant TSC, which is a better clocksource
+				 * anyway, is used instead.
+				 */
 				ms_hyperv.features &= ~HV_MSR_REFERENCE_TSC_AVAILABLE;
 
+				/*
+				 * The Invariant TSC is expected to be available
+				 * in a TDX VM without paravisor, but if not,
+				 * print a warning message. The slower Hyper-V MSR-based
+				 * Ref Counter should end up being the clocksource.
+				 */
+				if (!(ms_hyperv.features & HV_ACCESS_TSC_INVARIANT))
+					pr_warn("Hyper-V: Invariant TSC is unavailable\n");
+
 				/* HV_REGISTER_CRASH_CTL is unsupported. */
 				ms_hyperv.misc_features &= ~HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE;
 
@@ -574,6 +646,7 @@
 
 	/* Register Hyper-V specific clocksource */
 	hv_init_clocksource();
+	x86_setup_ops_for_tsc_pg_clock();
 	hv_vtl_init_platform();
 #endif
 	/*
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/mtrr/mtrr.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/mtrr/mtrr.c
@@ -609,7 +609,7 @@
 {
 	int first_cpu;
 
-	if (!mtrr_enabled())
+	if (!mtrr_enabled() || !mtrr_state.have_fixed)
 		return;
 
 	first_cpu = cpumask_first(cpu_online_mask);
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/resctrl/core.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/resctrl/core.c
@@ -194,7 +194,7 @@
 	return false;
 }
 
-static bool __get_mem_config_intel(struct rdt_resource *r)
+static __init bool __get_mem_config_intel(struct rdt_resource *r)
 {
 	struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
 	union cpuid_0x10_3_eax eax;
@@ -228,12 +228,10 @@
 	return true;
 }
 
-static bool __rdt_get_mem_config_amd(struct rdt_resource *r)
+static __init bool __rdt_get_mem_config_amd(struct rdt_resource *r)
 {
 	struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
-	union cpuid_0x10_3_eax eax;
-	union cpuid_0x10_x_edx edx;
-	u32 ebx, ecx, subleaf;
+	u32 eax, ebx, ecx, edx, subleaf;
 
 	/*
 	 * Query CPUID_Fn80000020_EDX_x01 for MBA and
@@ -241,9 +239,9 @@
 	 */
 	subleaf = (r->rid == RDT_RESOURCE_SMBA) ? 2 :  1;
 
-	cpuid_count(0x80000020, subleaf, &eax.full, &ebx, &ecx, &edx.full);
-	hw_res->num_closid = edx.split.cos_max + 1;
-	r->default_ctrl = MAX_MBA_BW_AMD;
+	cpuid_count(0x80000020, subleaf, &eax, &ebx, &ecx, &edx);
+	hw_res->num_closid = edx + 1;
+	r->default_ctrl = 1 << eax;
 
 	/* AMD does not use delay */
 	r->membw.delay_linear = false;
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/resctrl/ctrlmondata.c
@@ -27,10 +27,10 @@
  * hardware. The allocated bandwidth percentage is rounded to the next
  * control step available on the hardware.
  */
-static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r)
+static bool bw_validate(char *buf, u32 *data, struct rdt_resource *r)
 {
-	unsigned long bw;
 	int ret;
+	u32 bw;
 
 	/*
 	 * Only linear delay values is supported for current Intel SKUs.
@@ -40,16 +40,21 @@
 		return false;
 	}
 
-	ret = kstrtoul(buf, 10, &bw);
+	ret = kstrtou32(buf, 10, &bw);
 	if (ret) {
-		rdt_last_cmd_printf("Non-decimal digit in MB value %s\n", buf);
+		rdt_last_cmd_printf("Invalid MB value %s\n", buf);
 		return false;
 	}
 
-	if ((bw < r->membw.min_bw || bw > r->default_ctrl) &&
-	    !is_mba_sc(r)) {
-		rdt_last_cmd_printf("MB value %ld out of range [%d,%d]\n", bw,
-				    r->membw.min_bw, r->default_ctrl);
+	/* Nothing else to do if software controller is enabled. */
+	if (is_mba_sc(r)) {
+		*data = bw;
+		return true;
+	}
+
+	if (bw < r->membw.min_bw || bw > r->default_ctrl) {
+		rdt_last_cmd_printf("MB value %u out of range [%d,%d]\n",
+				    bw, r->membw.min_bw, r->default_ctrl);
 		return false;
 	}
 
@@ -63,7 +68,7 @@
 	struct resctrl_staged_config *cfg;
 	u32 closid = data->rdtgrp->closid;
 	struct rdt_resource *r = s->res;
-	unsigned long bw_val;
+	u32 bw_val;
 
 	cfg = &d->staged_config[s->conf_type];
 	if (cfg->have_new_ctrl) {
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/resctrl/internal.h
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/resctrl/internal.h
@@ -18,7 +18,6 @@
 #define MBM_OVERFLOW_INTERVAL		1000
 #define MAX_MBA_BW			100u
 #define MBA_IS_LINEAR			0x4
-#define MAX_MBA_BW_AMD			0x800
 #define MBM_CNTR_WIDTH_OFFSET_AMD	20
 
 #define RMID_VAL_ERROR			BIT_ULL(63)
@@ -296,14 +295,10 @@
  * struct mbm_state - status for each MBM counter in each domain
  * @prev_bw_bytes: Previous bytes value read for bandwidth calculation
  * @prev_bw:	The most recent bandwidth in MBps
- * @delta_bw:	Difference between the current and previous bandwidth
- * @delta_comp:	Indicates whether to compute the delta_bw
  */
 struct mbm_state {
 	u64	prev_bw_bytes;
 	u32	prev_bw;
-	u32	delta_bw;
-	bool	delta_comp;
 };
 
 /**
@@ -395,6 +390,8 @@
  * @msr_update:		Function pointer to update QOS MSRs
  * @mon_scale:		cqm counter * mon_scale = occupancy in bytes
  * @mbm_width:		Monitor width, to detect and correct for overflow.
+ * @mbm_cfg_mask:	Bandwidth sources that can be tracked when Bandwidth
+ *			Monitoring Event Configuration (BMEC) is supported.
  * @cdp_enabled:	CDP state of this resource
  *
  * Members of this structure are either private to the architecture
@@ -409,6 +406,7 @@
 				 struct rdt_resource *r);
 	unsigned int		mon_scale;
 	unsigned int		mbm_width;
+	unsigned int		mbm_cfg_mask;
 	bool			cdp_enabled;
 };
 
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/resctrl/monitor.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -440,9 +440,6 @@
 
 	cur_bw = bytes / SZ_1M;
 
-	if (m->delta_comp)
-		m->delta_bw = abs(cur_bw - m->prev_bw);
-	m->delta_comp = false;
 	m->prev_bw = cur_bw;
 }
 
@@ -520,11 +517,11 @@
 {
 	u32 closid, rmid, cur_msr_val, new_msr_val;
 	struct mbm_state *pmbm_data, *cmbm_data;
-	u32 cur_bw, delta_bw, user_bw;
 	struct rdt_resource *r_mba;
 	struct rdt_domain *dom_mba;
 	struct list_head *head;
 	struct rdtgroup *entry;
+	u32 cur_bw, user_bw;
 
 	if (!is_mbm_local_enabled())
 		return;
@@ -543,7 +540,6 @@
 
 	cur_bw = pmbm_data->prev_bw;
 	user_bw = dom_mba->mbps_val[closid];
-	delta_bw = pmbm_data->delta_bw;
 
 	/* MBA resource doesn't support CDP */
 	cur_msr_val = resctrl_arch_get_config(r_mba, dom_mba, closid, CDP_NONE);
@@ -555,49 +551,31 @@
 	list_for_each_entry(entry, head, mon.crdtgrp_list) {
 		cmbm_data = &dom_mbm->mbm_local[entry->mon.rmid];
 		cur_bw += cmbm_data->prev_bw;
-		delta_bw += cmbm_data->delta_bw;
 	}
 
 	/*
 	 * Scale up/down the bandwidth linearly for the ctrl group.  The
 	 * bandwidth step is the bandwidth granularity specified by the
 	 * hardware.
-	 *
-	 * The delta_bw is used when increasing the bandwidth so that we
-	 * dont alternately increase and decrease the control values
-	 * continuously.
-	 *
-	 * For ex: consider cur_bw = 90MBps, user_bw = 100MBps and if
-	 * bandwidth step is 20MBps(> user_bw - cur_bw), we would keep
-	 * switching between 90 and 110 continuously if we only check
-	 * cur_bw < user_bw.
+	 * Always increase throttling if current bandwidth is above the
+	 * target set by user.
+	 * But avoid thrashing up and down on every poll by checking
+	 * whether a decrease in throttling is likely to push the group
+	 * back over target. E.g. if currently throttling to 30% of bandwidth
+	 * on a system with 10% granularity steps, check whether moving to
+	 * 40% would go past the limit by multiplying current bandwidth by
+	 * "(30 + 10) / 30".
 	 */
 	if (cur_msr_val > r_mba->membw.min_bw && user_bw < cur_bw) {
 		new_msr_val = cur_msr_val - r_mba->membw.bw_gran;
 	} else if (cur_msr_val < MAX_MBA_BW &&
-		   (user_bw > (cur_bw + delta_bw))) {
+		   (user_bw > (cur_bw * (cur_msr_val + r_mba->membw.min_bw) / cur_msr_val))) {
 		new_msr_val = cur_msr_val + r_mba->membw.bw_gran;
 	} else {
 		return;
 	}
 
 	resctrl_arch_update_one(r_mba, dom_mba, closid, CDP_NONE, new_msr_val);
-
-	/*
-	 * Delta values are updated dynamically package wise for each
-	 * rdtgrp every time the throttle MSR changes value.
-	 *
-	 * This is because (1)the increase in bandwidth is not perfectly
-	 * linear and only "approximately" linear even when the hardware
-	 * says it is linear.(2)Also since MBA is a core specific
-	 * mechanism, the delta values vary based on number of cores used
-	 * by the rdtgrp.
-	 */
-	pmbm_data->delta_comp = true;
-	list_for_each_entry(entry, head, mon.crdtgrp_list) {
-		cmbm_data = &dom_mbm->mbm_local[entry->mon.rmid];
-		cmbm_data->delta_comp = true;
-	}
 }
 
 static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, int rmid)
@@ -813,6 +791,12 @@
 		return ret;
 
 	if (rdt_cpu_has(X86_FEATURE_BMEC)) {
+		u32 eax, ebx, ecx, edx;
+
+		/* Detect list of bandwidth sources that can be tracked */
+		cpuid_count(0x80000020, 3, &eax, &ebx, &ecx, &edx);
+		hw_res->mbm_cfg_mask = ecx & MAX_EVT_CONFIG_BITS;
+
 		if (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) {
 			mbm_total_event.configurable = true;
 			mbm_config_rftype_init("mbm_total_bytes_config");
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/resctrl/rdtgroup.c
@@ -1620,12 +1620,6 @@
 	struct mon_config_info mon_info = {0};
 	int ret = 0;
 
-	/* mon_config cannot be more than the supported set of events */
-	if (val > MAX_EVT_CONFIG_BITS) {
-		rdt_last_cmd_puts("Invalid event configuration\n");
-		return -EINVAL;
-	}
-
 	/*
 	 * Read the current config value first. If both are the same then
 	 * no need to write it again.
@@ -1663,6 +1657,7 @@
 
 static int mon_config_write(struct rdt_resource *r, char *tok, u32 evtid)
 {
+	struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
 	char *dom_str = NULL, *id_str;
 	unsigned long dom_id, val;
 	struct rdt_domain *d;
@@ -1686,6 +1681,13 @@
 		return -EINVAL;
 	}
 
+	/* Value from user cannot be more than the supported set of events */
+	if ((val & hw_res->mbm_cfg_mask) != val) {
+		rdt_last_cmd_printf("Invalid event configuration: max valid mask is 0x%02x\n",
+				    hw_res->mbm_cfg_mask);
+		return -EINVAL;
+	}
+
 	list_for_each_entry(d, &r->domains, list) {
 		if (d->id == dom_id) {
 			ret = mbm_config_write_domain(r, d, evtid, val);
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/scattered.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/scattered.c
@@ -28,6 +28,7 @@
 	{ X86_FEATURE_EPB,		CPUID_ECX,  3, 0x00000006, 0 },
 	{ X86_FEATURE_INTEL_PPIN,	CPUID_EBX,  0, 0x00000007, 1 },
 	{ X86_FEATURE_RRSBA_CTRL,	CPUID_EDX,  2, 0x00000007, 2 },
+	{ X86_FEATURE_BHI_CTRL,		CPUID_EDX,  4, 0x00000007, 2 },
 	{ X86_FEATURE_CQM_LLC,		CPUID_EDX,  1, 0x0000000f, 0 },
 	{ X86_FEATURE_CQM_OCCUP_LLC,	CPUID_EDX,  0, 0x0000000f, 1 },
 	{ X86_FEATURE_CQM_MBM_TOTAL,	CPUID_EDX,  1, 0x0000000f, 1 },
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/sgx/main.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/sgx/main.c
@@ -474,24 +474,25 @@
 {
 	struct sgx_epc_page *page;
 	int nid_of_current = numa_node_id();
-	int nid = nid_of_current;
+	int nid_start, nid;
 
-	if (node_isset(nid_of_current, sgx_numa_mask)) {
-		page = __sgx_alloc_epc_page_from_node(nid_of_current);
-		if (page)
-			return page;
-	}
-
-	/* Fall back to the non-local NUMA nodes: */
-	while (true) {
-		nid = next_node_in(nid, sgx_numa_mask);
-		if (nid == nid_of_current)
-			break;
+	/*
+	 * Try local node first. If it doesn't have an EPC section,
+	 * fall back to the non-local NUMA nodes.
+	 */
+	if (node_isset(nid_of_current, sgx_numa_mask))
+		nid_start = nid_of_current;
+	else
+		nid_start = next_node_in(nid_of_current, sgx_numa_mask);
 
+	nid = nid_start;
+	do {
 		page = __sgx_alloc_epc_page_from_node(nid);
 		if (page)
 			return page;
-	}
+
+		nid = next_node_in(nid, sgx_numa_mask);
+	} while (nid != nid_start);
 
 	return ERR_PTR(-ENOMEM);
 }
--- linux-qcom-6.8.0.orig/arch/x86/kernel/cpu/vmware.c
+++ linux-qcom-6.8.0/arch/x86/kernel/cpu/vmware.c
@@ -41,80 +41,97 @@
 
 #define CPUID_VMWARE_INFO_LEAF               0x40000000
 #define CPUID_VMWARE_FEATURES_LEAF           0x40000010
-#define CPUID_VMWARE_FEATURES_ECX_VMMCALL    BIT(0)
-#define CPUID_VMWARE_FEATURES_ECX_VMCALL     BIT(1)
 
-#define VMWARE_HYPERVISOR_MAGIC	0x564D5868
-
-#define VMWARE_CMD_GETVERSION    10
-#define VMWARE_CMD_GETHZ         45
-#define VMWARE_CMD_GETVCPU_INFO  68
-#define VMWARE_CMD_LEGACY_X2APIC  3
-#define VMWARE_CMD_VCPU_RESERVED 31
-#define VMWARE_CMD_STEALCLOCK    91
+#define GETVCPU_INFO_LEGACY_X2APIC           BIT(3)
+#define GETVCPU_INFO_VCPU_RESERVED           BIT(31)
 
 #define STEALCLOCK_NOT_AVAILABLE (-1)
 #define STEALCLOCK_DISABLED        0
 #define STEALCLOCK_ENABLED         1
 
-#define VMWARE_PORT(cmd, eax, ebx, ecx, edx)				\
-	__asm__("inl (%%dx), %%eax" :					\
-		"=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :		\
-		"a"(VMWARE_HYPERVISOR_MAGIC),				\
-		"c"(VMWARE_CMD_##cmd),					\
-		"d"(VMWARE_HYPERVISOR_PORT), "b"(UINT_MAX) :		\
-		"memory")
-
-#define VMWARE_VMCALL(cmd, eax, ebx, ecx, edx)				\
-	__asm__("vmcall" :						\
-		"=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :		\
-		"a"(VMWARE_HYPERVISOR_MAGIC),				\
-		"c"(VMWARE_CMD_##cmd),					\
-		"d"(0), "b"(UINT_MAX) :					\
-		"memory")
-
-#define VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx)                         \
-	__asm__("vmmcall" :						\
-		"=a"(eax), "=c"(ecx), "=d"(edx), "=b"(ebx) :		\
-		"a"(VMWARE_HYPERVISOR_MAGIC),				\
-		"c"(VMWARE_CMD_##cmd),					\
-		"d"(0), "b"(UINT_MAX) :					\
-		"memory")
-
-#define VMWARE_CMD(cmd, eax, ebx, ecx, edx) do {		\
-	switch (vmware_hypercall_mode) {			\
-	case CPUID_VMWARE_FEATURES_ECX_VMCALL:			\
-		VMWARE_VMCALL(cmd, eax, ebx, ecx, edx);		\
-		break;						\
-	case CPUID_VMWARE_FEATURES_ECX_VMMCALL:			\
-		VMWARE_VMMCALL(cmd, eax, ebx, ecx, edx);	\
-		break;						\
-	default:						\
-		VMWARE_PORT(cmd, eax, ebx, ecx, edx);		\
-		break;						\
-	}							\
-	} while (0)
-
 struct vmware_steal_time {
 	union {
-		uint64_t clock;	/* stolen time counter in units of vtsc */
+		u64 clock;	/* stolen time counter in units of vtsc */
 		struct {
 			/* only for little-endian */
-			uint32_t clock_low;
-			uint32_t clock_high;
+			u32 clock_low;
+			u32 clock_high;
 		};
 	};
-	uint64_t reserved[7];
+	u64 reserved[7];
 };
 
 static unsigned long vmware_tsc_khz __ro_after_init;
 static u8 vmware_hypercall_mode     __ro_after_init;
 
+unsigned long vmware_hypercall_slow(unsigned long cmd,
+				    unsigned long in1, unsigned long in3,
+				    unsigned long in4, unsigned long in5,
+				    u32 *out1, u32 *out2, u32 *out3,
+				    u32 *out4, u32 *out5)
+{
+	unsigned long out0, rbx, rcx, rdx, rsi, rdi;
+
+	switch (vmware_hypercall_mode) {
+	case CPUID_VMWARE_FEATURES_ECX_VMCALL:
+		asm_inline volatile ("vmcall"
+				: "=a" (out0), "=b" (rbx), "=c" (rcx),
+				"=d" (rdx), "=S" (rsi), "=D" (rdi)
+				: "a" (VMWARE_HYPERVISOR_MAGIC),
+				"b" (in1),
+				"c" (cmd),
+				"d" (in3),
+				"S" (in4),
+				"D" (in5)
+				: "cc", "memory");
+		break;
+	case CPUID_VMWARE_FEATURES_ECX_VMMCALL:
+		asm_inline volatile ("vmmcall"
+				: "=a" (out0), "=b" (rbx), "=c" (rcx),
+				"=d" (rdx), "=S" (rsi), "=D" (rdi)
+				: "a" (VMWARE_HYPERVISOR_MAGIC),
+				"b" (in1),
+				"c" (cmd),
+				"d" (in3),
+				"S" (in4),
+				"D" (in5)
+				: "cc", "memory");
+		break;
+	default:
+		asm_inline volatile ("movw %[port], %%dx; inl (%%dx), %%eax"
+				: "=a" (out0), "=b" (rbx), "=c" (rcx),
+				"=d" (rdx), "=S" (rsi), "=D" (rdi)
+				: [port] "i" (VMWARE_HYPERVISOR_PORT),
+				"a" (VMWARE_HYPERVISOR_MAGIC),
+				"b" (in1),
+				"c" (cmd),
+				"d" (in3),
+				"S" (in4),
+				"D" (in5)
+				: "cc", "memory");
+		break;
+	}
+
+	if (out1)
+		*out1 = rbx;
+	if (out2)
+		*out2 = rcx;
+	if (out3)
+		*out3 = rdx;
+	if (out4)
+		*out4 = rsi;
+	if (out5)
+		*out5 = rdi;
+
+	return out0;
+}
+
 static inline int __vmware_platform(void)
 {
-	uint32_t eax, ebx, ecx, edx;
-	VMWARE_CMD(GETVERSION, eax, ebx, ecx, edx);
-	return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC;
+	u32 eax, ebx, ecx;
+
+	eax = vmware_hypercall3(VMWARE_CMD_GETVERSION, 0, &ebx, &ecx);
+	return eax != UINT_MAX && ebx == VMWARE_HYPERVISOR_MAGIC;
 }
 
 static unsigned long vmware_get_tsc_khz(void)
@@ -166,21 +183,12 @@
 	pr_info("using clock offset of %llu ns\n", d->cyc2ns_offset);
 }
 
-static int vmware_cmd_stealclock(uint32_t arg1, uint32_t arg2)
+static int vmware_cmd_stealclock(u32 addr_hi, u32 addr_lo)
 {
-	uint32_t result, info;
+	u32 info;
 
-	asm volatile (VMWARE_HYPERCALL :
-		"=a"(result),
-		"=c"(info) :
-		"a"(VMWARE_HYPERVISOR_MAGIC),
-		"b"(0),
-		"c"(VMWARE_CMD_STEALCLOCK),
-		"d"(0),
-		"S"(arg1),
-		"D"(arg2) :
-		"memory");
-	return result;
+	return vmware_hypercall5(VMWARE_CMD_STEALCLOCK, 0, 0, addr_hi, addr_lo,
+				 &info);
 }
 
 static bool stealclock_enable(phys_addr_t pa)
@@ -215,15 +223,15 @@
  * Return:
  *      The steal clock reading in ns.
  */
-static uint64_t vmware_steal_clock(int cpu)
+static u64 vmware_steal_clock(int cpu)
 {
 	struct vmware_steal_time *steal = &per_cpu(vmw_steal_time, cpu);
-	uint64_t clock;
+	u64 clock;
 
 	if (IS_ENABLED(CONFIG_64BIT))
 		clock = READ_ONCE(steal->clock);
 	else {
-		uint32_t initial_high, low, high;
+		u32 initial_high, low, high;
 
 		do {
 			initial_high = READ_ONCE(steal->clock_high);
@@ -235,7 +243,7 @@
 			high = READ_ONCE(steal->clock_high);
 		} while (initial_high != high);
 
-		clock = ((uint64_t)high << 32) | low;
+		clock = ((u64)high << 32) | low;
 	}
 
 	return mul_u64_u32_shr(clock, vmware_cyc2ns.cyc2ns_mul,
@@ -389,13 +397,13 @@
 
 static void __init vmware_platform_setup(void)
 {
-	uint32_t eax, ebx, ecx, edx;
-	uint64_t lpj, tsc_khz;
+	u32 eax, ebx, ecx;
+	u64 lpj, tsc_khz;
 
-	VMWARE_CMD(GETHZ, eax, ebx, ecx, edx);
+	eax = vmware_hypercall3(VMWARE_CMD_GETHZ, UINT_MAX, &ebx, &ecx);
 
 	if (ebx != UINT_MAX) {
-		lpj = tsc_khz = eax | (((uint64_t)ebx) << 32);
+		lpj = tsc_khz = eax | (((u64)ebx) << 32);
 		do_div(tsc_khz, 1000);
 		WARN_ON(tsc_khz >> 32);
 		pr_info("TSC freq read from hypervisor : %lu.%03lu MHz\n",
@@ -446,7 +454,7 @@
  * If !boot_cpu_has(X86_FEATURE_HYPERVISOR), vmware_hypercall_mode
  * intentionally defaults to 0.
  */
-static uint32_t __init vmware_platform(void)
+static u32 __init vmware_platform(void)
 {
 	if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) {
 		unsigned int eax;
@@ -474,12 +482,65 @@
 /* Checks if hypervisor supports x2apic without VT-D interrupt remapping. */
 static bool __init vmware_legacy_x2apic_available(void)
 {
-	uint32_t eax, ebx, ecx, edx;
-	VMWARE_CMD(GETVCPU_INFO, eax, ebx, ecx, edx);
-	return !(eax & BIT(VMWARE_CMD_VCPU_RESERVED)) &&
-		(eax & BIT(VMWARE_CMD_LEGACY_X2APIC));
+	u32 eax;
+
+	eax = vmware_hypercall1(VMWARE_CMD_GETVCPU_INFO, 0);
+	return !(eax & GETVCPU_INFO_VCPU_RESERVED) &&
+		(eax & GETVCPU_INFO_LEGACY_X2APIC);
 }
 
+#ifdef CONFIG_INTEL_TDX_GUEST
+/*
+ * TDCALL[TDG.VP.VMCALL] uses %rax (arg0) and %rcx (arg2). Therefore,
+ * we remap those registers to %r12 and %r13, respectively.
+ */
+unsigned long vmware_tdx_hypercall(unsigned long cmd,
+				   unsigned long in1, unsigned long in3,
+				   unsigned long in4, unsigned long in5,
+				   u32 *out1, u32 *out2, u32 *out3,
+				   u32 *out4, u32 *out5)
+{
+	struct tdx_module_args args = {};
+
+	if (!hypervisor_is_type(X86_HYPER_VMWARE)) {
+		pr_warn_once("Incorrect usage\n");
+		return ULONG_MAX;
+	}
+
+	if (cmd & ~VMWARE_CMD_MASK) {
+		pr_warn_once("Out of range command %lx\n", cmd);
+		return ULONG_MAX;
+	}
+
+	args.rbx = in1;
+	args.rdx = in3;
+	args.rsi = in4;
+	args.rdi = in5;
+	args.r10 = VMWARE_TDX_VENDOR_LEAF;
+	args.r11 = VMWARE_TDX_HCALL_FUNC;
+	args.r12 = VMWARE_HYPERVISOR_MAGIC;
+	args.r13 = cmd;
+	/* CPL */
+	args.r15 = 0;
+
+	__tdx_hypercall(&args);
+
+	if (out1)
+		*out1 = args.rbx;
+	if (out2)
+		*out2 = args.r13;
+	if (out3)
+		*out3 = args.rdx;
+	if (out4)
+		*out4 = args.rsi;
+	if (out5)
+		*out5 = args.rdi;
+
+	return args.r12;
+}
+EXPORT_SYMBOL_GPL(vmware_tdx_hypercall);
+#endif
+
 #ifdef CONFIG_AMD_MEM_ENCRYPT
 static void vmware_sev_es_hcall_prepare(struct ghcb *ghcb,
 					struct pt_regs *regs)
--- linux-qcom-6.8.0.orig/arch/x86/kernel/crash.c
+++ linux-qcom-6.8.0/arch/x86/kernel/crash.c
@@ -124,6 +124,18 @@
 #ifdef CONFIG_HPET_TIMER
 	hpet_disable();
 #endif
+
+	/*
+	 * Non-crash kexec calls enc_kexec_begin() while scheduling is still
+	 * active. This allows the callback to wait until all in-flight
+	 * shared<->private conversions are complete. In a crash scenario,
+	 * enc_kexec_begin() gets called after all but one CPU have been shut
+	 * down and interrupts have been disabled. This allows the callback to
+	 * detect a race with the conversion and report it.
+	 */
+	x86_platform.guest.enc_kexec_begin();
+	x86_platform.guest.enc_kexec_finish();
+
 	crash_save_cpu(regs, safe_smp_processor_id());
 }
 
--- linux-qcom-6.8.0.orig/arch/x86/kernel/devicetree.c
+++ linux-qcom-6.8.0/arch/x86/kernel/devicetree.c
@@ -82,7 +82,7 @@
 
 	ret = pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 	if (ret)
-		return ret;
+		return pcibios_err_to_errno(ret);
 	if (!pin)
 		return 0;
 
@@ -283,22 +283,24 @@
 	u32 size, map_len;
 	void *dt;
 
-	if (!initial_dtb)
-		return;
+	if (initial_dtb) {
+		map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
 
-	map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
+		dt = early_memremap(initial_dtb, map_len);
+		size = fdt_totalsize(dt);
+		if (map_len < size) {
+			early_memunmap(dt, map_len);
+			dt = early_memremap(initial_dtb, size);
+			map_len = size;
+		}
 
-	dt = early_memremap(initial_dtb, map_len);
-	size = fdt_totalsize(dt);
-	if (map_len < size) {
-		early_memunmap(dt, map_len);
-		dt = early_memremap(initial_dtb, size);
-		map_len = size;
+		early_init_dt_verify(dt, __pa(dt));
 	}
 
-	early_init_dt_verify(dt);
 	unflatten_and_copy_device_tree();
-	early_memunmap(dt, map_len);
+
+	if (initial_dtb)
+		early_memunmap(dt, map_len);
 }
 #endif
 
--- linux-qcom-6.8.0.orig/arch/x86/kernel/early-quirks.c
+++ linux-qcom-6.8.0/arch/x86/kernel/early-quirks.c
@@ -29,6 +29,37 @@
 #include <asm/irq_remapping.h>
 #include <asm/early_ioremap.h>
 
+static void __init early_pci_clear_msi(int bus, int slot, int func)
+{
+	int pos;
+	u16 ctrl;
+
+	if (likely(!pci_early_clear_msi))
+		return;
+
+	pr_info_once("Clearing MSI/MSI-X enable bits early in boot (quirk)\n");
+
+	pos = pci_early_find_cap(bus, slot, func, PCI_CAP_ID_MSI);
+	if (pos) {
+		ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSI_FLAGS);
+		ctrl &= ~PCI_MSI_FLAGS_ENABLE;
+		write_pci_config_16(bus, slot, func, pos + PCI_MSI_FLAGS, ctrl);
+
+		/* Read again to flush previous write */
+		ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSI_FLAGS);
+	}
+
+	pos = pci_early_find_cap(bus, slot, func, PCI_CAP_ID_MSIX);
+	if (pos) {
+		ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSIX_FLAGS);
+		ctrl &= ~PCI_MSIX_FLAGS_ENABLE;
+		write_pci_config_16(bus, slot, func, pos + PCI_MSIX_FLAGS, ctrl);
+
+		/* Read again to flush previous write */
+		ctrl = read_pci_config_16(bus, slot, func, pos + PCI_MSIX_FLAGS);
+	}
+}
+
 static void __init fix_hypertransport_config(int num, int slot, int func)
 {
 	u32 htcfg;
@@ -728,6 +759,7 @@
 		PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
 	{ PCI_VENDOR_ID_BROADCOM, 0x4331,
 	  PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset},
+	{ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, early_pci_clear_msi},
 	{}
 };
 
@@ -780,6 +812,10 @@
 				    PCI_HEADER_TYPE);
 
 	if ((type & PCI_HEADER_TYPE_MASK) == PCI_HEADER_TYPE_BRIDGE) {
+		/* pci_early_clear_msi scans the buses differently. */
+		if (pci_early_clear_msi)
+			return -1;
+
 		sec = read_pci_config_byte(num, slot, func, PCI_SECONDARY_BUS);
 		if (sec > num)
 			early_pci_scan_bus(sec);
@@ -806,8 +842,13 @@
 
 void __init early_quirks(void)
 {
+	int bus;
+
 	if (!early_pci_allowed())
 		return;
 
 	early_pci_scan_bus(0);
+	/* pci_early_clear_msi scans more buses. */
+	for (bus = 1; pci_early_clear_msi && bus < 256; bus++)
+		early_pci_scan_bus(bus);
 }
--- linux-qcom-6.8.0.orig/arch/x86/kernel/eisa.c
+++ linux-qcom-6.8.0/arch/x86/kernel/eisa.c
@@ -2,6 +2,7 @@
 /*
  * EISA specific code
  */
+#include <linux/cc_platform.h>
 #include <linux/ioport.h>
 #include <linux/eisa.h>
 #include <linux/io.h>
@@ -12,7 +13,7 @@
 {
 	void __iomem *p;
 
-	if (xen_pv_domain() && !xen_initial_domain())
+	if ((xen_pv_domain() && !xen_initial_domain()) || cc_platform_has(CC_ATTR_GUEST_SEV_SNP))
 		return 0;
 
 	p = ioremap(0x0FFFD9, 4);
--- linux-qcom-6.8.0.orig/arch/x86/kernel/fpu/core.c
+++ linux-qcom-6.8.0/arch/x86/kernel/fpu/core.c
@@ -145,8 +145,8 @@
 		asm volatile(
 			"fnclex\n\t"
 			"emms\n\t"
-			"fildl %P[addr]"	/* set F?P to defined value */
-			: : [addr] "m" (fpstate));
+			"fildl %[addr]"	/* set F?P to defined value */
+			: : [addr] "m" (*fpstate));
 	}
 
 	if (use_xsave()) {
--- linux-qcom-6.8.0.orig/arch/x86/kernel/fpu/regset.c
+++ linux-qcom-6.8.0/arch/x86/kernel/fpu/regset.c
@@ -190,7 +190,8 @@
 	struct fpu *fpu = &target->thread.fpu;
 	struct cet_user_state *cetregs;
 
-	if (!cpu_feature_enabled(X86_FEATURE_USER_SHSTK))
+	if (!cpu_feature_enabled(X86_FEATURE_USER_SHSTK) ||
+	    !ssp_active(target, regset))
 		return -ENODEV;
 
 	sync_fpstate(fpu);
--- linux-qcom-6.8.0.orig/arch/x86/kernel/fpu/signal.c
+++ linux-qcom-6.8.0/arch/x86/kernel/fpu/signal.c
@@ -156,7 +156,7 @@
 	return !err;
 }
 
-static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf)
+static inline int copy_fpregs_to_sigframe(struct xregs_state __user *buf, u32 pkru)
 {
 	if (use_xsave())
 		return xsave_to_user_sigframe(buf);
@@ -185,7 +185,7 @@
  * For [f]xsave state, update the SW reserved fields in the [f]xsave frame
  * indicating the absence/presence of the extended state to the user.
  */
-bool copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
+bool copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size, u32 pkru)
 {
 	struct task_struct *tsk = current;
 	struct fpstate *fpstate = tsk->thread.fpu.fpstate;
@@ -228,7 +228,7 @@
 		fpregs_restore_userregs();
 
 	pagefault_disable();
-	ret = copy_fpregs_to_sigframe(buf_fx);
+	ret = copy_fpregs_to_sigframe(buf_fx, pkru);
 	pagefault_enable();
 	fpregs_unlock();
 
--- linux-qcom-6.8.0.orig/arch/x86/kernel/fpu/xstate.c
+++ linux-qcom-6.8.0/arch/x86/kernel/fpu/xstate.c
@@ -178,10 +178,11 @@
 	 * Must happen after CR4 setup and before xsetbv() to allow KVM
 	 * lazy passthrough.  Write independent of the dynamic state static
 	 * key as that does not work on the boot CPU. This also ensures
-	 * that any stale state is wiped out from XFD.
+	 * that any stale state is wiped out from XFD. Reset the per CPU
+	 * xfd cache too.
 	 */
 	if (cpu_feature_enabled(X86_FEATURE_XFD))
-		wrmsrl(MSR_IA32_XFD, init_fpstate.xfd);
+		xfd_set_state(init_fpstate.xfd);
 
 	/*
 	 * XCR_XFEATURE_ENABLED_MASK (aka. XCR0) sets user features
@@ -787,6 +788,9 @@
 		goto out_disable;
 	}
 
+	fpu_kernel_cfg.independent_features = fpu_kernel_cfg.max_features &
+					      XFEATURE_MASK_INDEPENDENT;
+
 	/*
 	 * Clear XSAVE features that are disabled in the normal CPUID.
 	 */
--- linux-qcom-6.8.0.orig/arch/x86/kernel/fpu/xstate.h
+++ linux-qcom-6.8.0/arch/x86/kernel/fpu/xstate.h
@@ -64,9 +64,9 @@
 static inline u64 xfeatures_mask_independent(void)
 {
 	if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR))
-		return XFEATURE_MASK_INDEPENDENT & ~XFEATURE_MASK_LBR;
+		return fpu_kernel_cfg.independent_features & ~XFEATURE_MASK_LBR;
 
-	return XFEATURE_MASK_INDEPENDENT;
+	return fpu_kernel_cfg.independent_features;
 }
 
 /* XSAVE/XRSTOR wrapper functions */
@@ -148,20 +148,26 @@
 #endif
 
 #ifdef CONFIG_X86_64
+static inline void xfd_set_state(u64 xfd)
+{
+	wrmsrl(MSR_IA32_XFD, xfd);
+	__this_cpu_write(xfd_state, xfd);
+}
+
 static inline void xfd_update_state(struct fpstate *fpstate)
 {
 	if (fpu_state_size_dynamic()) {
 		u64 xfd = fpstate->xfd;
 
-		if (__this_cpu_read(xfd_state) != xfd) {
-			wrmsrl(MSR_IA32_XFD, xfd);
-			__this_cpu_write(xfd_state, xfd);
-		}
+		if (__this_cpu_read(xfd_state) != xfd)
+			xfd_set_state(xfd);
 	}
 }
 
 extern int __xfd_enable_feature(u64 which, struct fpu_guest *guest_fpu);
 #else
+static inline void xfd_set_state(u64 xfd) { }
+
 static inline void xfd_update_state(struct fpstate *fpstate) { }
 
 static inline int __xfd_enable_feature(u64 which, struct fpu_guest *guest_fpu) {
--- linux-qcom-6.8.0.orig/arch/x86/kernel/jailhouse.c
+++ linux-qcom-6.8.0/arch/x86/kernel/jailhouse.c
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/reboot.h>
 #include <linux/serial_8250.h>
+#include <linux/acpi.h>
 #include <asm/apic.h>
 #include <asm/io_apic.h>
 #include <asm/acpi.h>
--- linux-qcom-6.8.0.orig/arch/x86/kernel/kprobes/core.c
+++ linux-qcom-6.8.0/arch/x86/kernel/kprobes/core.c
@@ -335,7 +335,16 @@
 kprobe_opcode_t *arch_adjust_kprobe_addr(unsigned long addr, unsigned long offset,
 					 bool *on_func_entry)
 {
-	if (is_endbr(*(u32 *)addr)) {
+	u32 insn;
+
+	/*
+	 * Since 'addr' is not guaranteed to be safe to access, use
+	 * copy_from_kernel_nofault() to read the instruction:
+	 */
+	if (copy_from_kernel_nofault(&insn, (void *)addr, sizeof(u32)))
+		return NULL;
+
+	if (is_endbr(insn)) {
 		*on_func_entry = !offset || offset == 4;
 		if (*on_func_entry)
 			offset = 4;
--- linux-qcom-6.8.0.orig/arch/x86/kernel/kprobes/ftrace.c
+++ linux-qcom-6.8.0/arch/x86/kernel/kprobes/ftrace.c
@@ -21,6 +21,9 @@
 	struct kprobe_ctlblk *kcb;
 	int bit;
 
+	if (unlikely(kprobe_ftrace_disabled))
+		return;
+
 	bit = ftrace_test_recursion_trylock(ip, parent_ip);
 	if (bit < 0)
 		return;
--- linux-qcom-6.8.0.orig/arch/x86/kernel/machine_kexec_64.c
+++ linux-qcom-6.8.0/arch/x86/kernel/machine_kexec_64.c
@@ -28,6 +28,7 @@
 #include <asm/setup.h>
 #include <asm/set_memory.h>
 #include <asm/cpu.h>
+#include <asm/efi.h>
 
 #ifdef CONFIG_ACPI
 /*
@@ -87,6 +88,8 @@
 {
 #ifdef CONFIG_EFI
 	unsigned long mstart, mend;
+	void *kaddr;
+	int ret;
 
 	if (!efi_enabled(EFI_BOOT))
 		return 0;
@@ -102,6 +105,30 @@
 	if (!mstart)
 		return 0;
 
+	ret = kernel_ident_mapping_init(info, level4p, mstart, mend);
+	if (ret)
+		return ret;
+
+	kaddr = memremap(mstart, mend - mstart, MEMREMAP_WB);
+	if (!kaddr) {
+		pr_err("Could not map UEFI system table\n");
+		return -ENOMEM;
+	}
+
+	mstart = efi_config_table;
+
+	if (efi_enabled(EFI_64BIT)) {
+		efi_system_table_64_t *stbl = (efi_system_table_64_t *)kaddr;
+
+		mend = mstart + sizeof(efi_config_table_64_t) * stbl->nr_tables;
+	} else {
+		efi_system_table_32_t *stbl = (efi_system_table_32_t *)kaddr;
+
+		mend = mstart + sizeof(efi_config_table_32_t) * stbl->nr_tables;
+	}
+
+	memunmap(kaddr);
+
 	return kernel_ident_mapping_init(info, level4p, mstart, mend);
 #endif
 	return 0;
@@ -119,7 +146,8 @@
 	image->arch.pte = NULL;
 }
 
-static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
+static int init_transition_pgtable(struct kimage *image, pgd_t *pgd,
+				   unsigned long control_page)
 {
 	pgprot_t prot = PAGE_KERNEL_EXEC_NOENC;
 	unsigned long vaddr, paddr;
@@ -130,7 +158,7 @@
 	pte_t *pte;
 
 	vaddr = (unsigned long)relocate_kernel;
-	paddr = __pa(page_address(image->control_code_page)+PAGE_SIZE);
+	paddr = control_page;
 	pgd += pgd_index(vaddr);
 	if (!pgd_present(*pgd)) {
 		p4d = (p4d_t *)get_zeroed_page(GFP_KERNEL);
@@ -189,7 +217,7 @@
 	return p;
 }
 
-static int init_pgtable(struct kimage *image, unsigned long start_pgtable)
+static int init_pgtable(struct kimage *image, unsigned long control_page)
 {
 	struct x86_mapping_info info = {
 		.alloc_pgt_page	= alloc_pgt_page,
@@ -198,12 +226,12 @@
 		.kernpg_flag	= _KERNPG_TABLE_NOENC,
 	};
 	unsigned long mstart, mend;
-	pgd_t *level4p;
 	int result;
 	int i;
 
-	level4p = (pgd_t *)__va(start_pgtable);
-	clear_page(level4p);
+	image->arch.pgd = alloc_pgt_page(image);
+	if (!image->arch.pgd)
+		return -ENOMEM;
 
 	if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) {
 		info.page_flag   |= _PAGE_ENC;
@@ -217,8 +245,8 @@
 		mstart = pfn_mapped[i].start << PAGE_SHIFT;
 		mend   = pfn_mapped[i].end << PAGE_SHIFT;
 
-		result = kernel_ident_mapping_init(&info,
-						 level4p, mstart, mend);
+		result = kernel_ident_mapping_init(&info, image->arch.pgd,
+						   mstart, mend);
 		if (result)
 			return result;
 	}
@@ -233,8 +261,8 @@
 		mstart = image->segment[i].mem;
 		mend   = mstart + image->segment[i].memsz;
 
-		result = kernel_ident_mapping_init(&info,
-						 level4p, mstart, mend);
+		result = kernel_ident_mapping_init(&info, image->arch.pgd,
+						   mstart, mend);
 
 		if (result)
 			return result;
@@ -244,15 +272,19 @@
 	 * Prepare EFI systab and ACPI tables for kexec kernel since they are
 	 * not covered by pfn_mapped.
 	 */
-	result = map_efi_systab(&info, level4p);
+	result = map_efi_systab(&info, image->arch.pgd);
 	if (result)
 		return result;
 
-	result = map_acpi_tables(&info, level4p);
+	result = map_acpi_tables(&info, image->arch.pgd);
 	if (result)
 		return result;
 
-	return init_transition_pgtable(image, level4p);
+	/*
+	 * This must be last because the intermediate page table pages it
+	 * allocates will not be control pages and may overlap the image.
+	 */
+	return init_transition_pgtable(image, image->arch.pgd, control_page);
 }
 
 static void load_segments(void)
@@ -269,14 +301,14 @@
 
 int machine_kexec_prepare(struct kimage *image)
 {
-	unsigned long start_pgtable;
+	unsigned long control_page;
 	int result;
 
 	/* Calculate the offsets */
-	start_pgtable = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
+	control_page = page_to_pfn(image->control_code_page) << PAGE_SHIFT;
 
 	/* Setup the identity mapped 64bit page table */
-	result = init_pgtable(image, start_pgtable);
+	result = init_pgtable(image, control_page);
 	if (result)
 		return result;
 
@@ -295,8 +327,15 @@
 void machine_kexec(struct kimage *image)
 {
 	unsigned long page_list[PAGES_NR];
-	void *control_page;
+	unsigned int host_mem_enc_active;
 	int save_ftrace_enabled;
+	void *control_page;
+
+	/*
+	 * This must be done before load_segments() since if call depth tracking
+	 * is used then GS must be valid to make any function calls.
+	 */
+	host_mem_enc_active = cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT);
 
 #ifdef CONFIG_KEXEC_JUMP
 	if (image->preserve_context)
@@ -323,13 +362,12 @@
 #endif
 	}
 
-	control_page = page_address(image->control_code_page) + PAGE_SIZE;
+	control_page = page_address(image->control_code_page);
 	__memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
 
 	page_list[PA_CONTROL_PAGE] = virt_to_phys(control_page);
 	page_list[VA_CONTROL_PAGE] = (unsigned long)control_page;
-	page_list[PA_TABLE_PAGE] =
-	  (unsigned long)__pa(page_address(image->control_code_page));
+	page_list[PA_TABLE_PAGE] = (unsigned long)__pa(image->arch.pgd);
 
 	if (image->type == KEXEC_TYPE_DEFAULT)
 		page_list[PA_SWAP_PAGE] = (page_to_pfn(image->swap_page)
@@ -358,7 +396,7 @@
 				       (unsigned long)page_list,
 				       image->start,
 				       image->preserve_context,
-				       cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT));
+				       host_mem_enc_active);
 
 #ifdef CONFIG_KEXEC_JUMP
 	if (image->preserve_context)
@@ -537,8 +575,7 @@
 
 	/* Don't touch the control code page used in crash_kexec().*/
 	control = PFN_PHYS(page_to_pfn(kexec_crash_image->control_code_page));
-	/* Control code page is located in the 2nd page. */
-	kexec_mark_range(crashk_res.start, control + PAGE_SIZE - 1, protect);
+	kexec_mark_range(crashk_res.start, control - 1, protect);
 	control += KEXEC_CONTROL_PAGE_SIZE;
 	kexec_mark_range(control, crashk_res.end, protect);
 }
--- linux-qcom-6.8.0.orig/arch/x86/kernel/mmconf-fam10h_64.c
+++ linux-qcom-6.8.0/arch/x86/kernel/mmconf-fam10h_64.c
@@ -9,6 +9,7 @@
 #include <linux/pci.h>
 #include <linux/dmi.h>
 #include <linux/range.h>
+#include <linux/acpi.h>
 
 #include <asm/pci-direct.h>
 #include <linux/sort.h>
--- linux-qcom-6.8.0.orig/arch/x86/kernel/nmi.c
+++ linux-qcom-6.8.0/arch/x86/kernel/nmi.c
@@ -636,7 +636,7 @@
 			msgp = nmi_check_stall_msg[idx];
 			if (nsp->idt_ignored_snap != READ_ONCE(nsp->idt_ignored) && (idx & 0x1))
 				modp = ", but OK because ignore_nmis was set";
-			if (nmi_seq & ~0x1)
+			if (nmi_seq & 0x1)
 				msghp = " (CPU currently in NMI handler function)";
 			else if (nsp->idt_nmi_seq_snap + 1 == nmi_seq)
 				msghp = " (CPU exited one NMI handler function)";
--- linux-qcom-6.8.0.orig/arch/x86/kernel/paravirt.c
+++ linux-qcom-6.8.0/arch/x86/kernel/paravirt.c
@@ -51,13 +51,12 @@
 DEFINE_ASM_FUNC(pv_native_read_cr2, "mov %cr2, %rax", .noinstr.text);
 #endif
 
-DEFINE_STATIC_KEY_TRUE(virt_spin_lock_key);
+DEFINE_STATIC_KEY_FALSE(virt_spin_lock_key);
 
 void __init native_pv_lock_init(void)
 {
-	if (IS_ENABLED(CONFIG_PARAVIRT_SPINLOCKS) &&
-	    !boot_cpu_has(X86_FEATURE_HYPERVISOR))
-		static_branch_disable(&virt_spin_lock_key);
+	if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
+		static_branch_enable(&virt_spin_lock_key);
 }
 
 static void native_tlb_remove_table(struct mmu_gather *tlb, void *table)
--- linux-qcom-6.8.0.orig/arch/x86/kernel/probe_roms.c
+++ linux-qcom-6.8.0/arch/x86/kernel/probe_roms.c
@@ -203,16 +203,6 @@
 	unsigned char c;
 	int i;
 
-	/*
-	 * The ROM memory range is not part of the e820 table and is therefore not
-	 * pre-validated by BIOS. The kernel page table maps the ROM region as encrypted
-	 * memory, and SNP requires encrypted memory to be validated before access.
-	 * Do that here.
-	 */
-	snp_prep_memory(video_rom_resource.start,
-			((system_rom_resource.end + 1) - video_rom_resource.start),
-			SNP_PAGE_STATE_PRIVATE);
-
 	/* video rom */
 	upper = adapter_rom_resources[0].start;
 	for (start = video_rom_resource.start; start < upper; start += 2048) {
--- linux-qcom-6.8.0.orig/arch/x86/kernel/process.c
+++ linux-qcom-6.8.0/arch/x86/kernel/process.c
@@ -1030,7 +1030,10 @@
 
 unsigned long arch_randomize_brk(struct mm_struct *mm)
 {
-	return randomize_page(mm->brk, 0x02000000);
+	if (mmap_is_ia32())
+		return randomize_page(mm->brk, SZ_32M);
+
+	return randomize_page(mm->brk, SZ_1G);
 }
 
 /*
--- linux-qcom-6.8.0.orig/arch/x86/kernel/process_64.c
+++ linux-qcom-6.8.0/arch/x86/kernel/process_64.c
@@ -117,7 +117,7 @@
 
 	printk("%sFS:  %016lx(%04x) GS:%016lx(%04x) knlGS:%016lx\n",
 	       log_lvl, fs, fsindex, gs, gsindex, shadowgs);
-	printk("%sCS:  %04lx DS: %04x ES: %04x CR0: %016lx\n",
+	printk("%sCS:  %04x DS: %04x ES: %04x CR0: %016lx\n",
 		log_lvl, regs->cs, ds, es, cr0);
 	printk("%sCR2: %016lx CR3: %016lx CR4: %016lx\n",
 		log_lvl, cr2, cr3, cr4);
@@ -138,7 +138,7 @@
 		       log_lvl, d3, d6, d7);
 	}
 
-	if (cpu_feature_enabled(X86_FEATURE_OSPKE))
+	if (cr4 & X86_CR4_PKE)
 		printk("%sPKRU: %08x\n", log_lvl, read_pkru());
 }
 
@@ -750,6 +750,27 @@
 
 #define LAM_U57_BITS 6
 
+static void enable_lam_func(void *__mm)
+{
+	struct mm_struct *mm = __mm;
+
+	if (this_cpu_read(cpu_tlbstate.loaded_mm) == mm) {
+		write_cr3(__read_cr3() | mm->context.lam_cr3_mask);
+		set_tlbstate_lam_mode(mm);
+	}
+}
+
+static void mm_enable_lam(struct mm_struct *mm)
+{
+	/*
+	 * Even though the process must still be single-threaded at this
+	 * point, kernel threads may be using the mm.  IPI those kernel
+	 * threads if they exist.
+	 */
+	on_each_cpu_mask(mm_cpumask(mm), enable_lam_func, mm, true);
+	set_bit(MM_CONTEXT_LOCK_LAM, &mm->context.flags);
+}
+
 static int prctl_enable_tagged_addr(struct mm_struct *mm, unsigned long nr_bits)
 {
 	if (!cpu_feature_enabled(X86_FEATURE_LAM))
@@ -766,6 +787,10 @@
 	if (mmap_write_lock_killable(mm))
 		return -EINTR;
 
+	/*
+	 * MM_CONTEXT_LOCK_LAM is set on clone.  Prevent LAM from
+	 * being enabled unless the process is single threaded:
+	 */
 	if (test_bit(MM_CONTEXT_LOCK_LAM, &mm->context.flags)) {
 		mmap_write_unlock(mm);
 		return -EBUSY;
@@ -782,9 +807,7 @@
 		return -EINVAL;
 	}
 
-	write_cr3(__read_cr3() | mm->context.lam_cr3_mask);
-	set_tlbstate_lam_mode(mm);
-	set_bit(MM_CONTEXT_LOCK_LAM, &mm->context.flags);
+	mm_enable_lam(mm);
 
 	mmap_write_unlock(mm);
 
--- linux-qcom-6.8.0.orig/arch/x86/kernel/reboot.c
+++ linux-qcom-6.8.0/arch/x86/kernel/reboot.c
@@ -12,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/objtool.h>
 #include <linux/pgtable.h>
+#include <linux/kexec.h>
 #include <acpi/reboot.h>
 #include <asm/io.h>
 #include <asm/apic.h>
@@ -487,7 +488,46 @@
 			DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"),
 		},
 	},
-
+	{	/* Handle problems with rebooting on the Latitude E6520. */
+		.callback = set_pci_reboot,
+		.ident = "Dell Latitude E6520",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6520"),
+		},
+	},
+	{       /* Handle problems with rebooting on the OptiPlex 790. */
+		.callback = set_pci_reboot,
+		.ident = "Dell OptiPlex 790",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 790"),
+		},
+	},
+	{	/* Handle problems with rebooting on the OptiPlex 990. */
+		.callback = set_pci_reboot,
+		.ident = "Dell OptiPlex 990",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"),
+		},
+	},
+	{       /* Handle problems with rebooting on the Latitude E6220. */
+		.callback = set_pci_reboot,
+		.ident = "Dell Latitude E6220",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6220"),
+		},
+	},
+	{	/* Handle problems with rebooting on the OptiPlex 390. */
+		.callback = set_pci_reboot,
+		.ident = "Dell OptiPlex 390",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 390"),
+		},
+	},
 	{ }
 };
 
@@ -716,6 +756,14 @@
 
 void native_machine_shutdown(void)
 {
+	/*
+	 * Call enc_kexec_begin() while all CPUs are still active and
+	 * interrupts are enabled. This will allow all in-flight memory
+	 * conversions to finish cleanly.
+	 */
+	if (kexec_in_progress)
+		x86_platform.guest.enc_kexec_begin();
+
 	/* Stop the cpus and apics */
 #ifdef CONFIG_X86_IO_APIC
 	/*
@@ -752,6 +800,9 @@
 #ifdef CONFIG_X86_64
 	x86_platform.iommu_shutdown();
 #endif
+
+	if (kexec_in_progress)
+		x86_platform.guest.enc_kexec_finish();
 }
 
 static void __machine_emergency_restart(int emergency)
--- linux-qcom-6.8.0.orig/arch/x86/kernel/relocate_kernel_64.S
+++ linux-qcom-6.8.0/arch/x86/kernel/relocate_kernel_64.S
@@ -11,6 +11,7 @@
 #include <asm/pgtable_types.h>
 #include <asm/nospec-branch.h>
 #include <asm/unwind_hints.h>
+#include <asm/asm-offsets.h>
 
 /*
  * Must be relocatable PIC code callable as a C function, in particular
@@ -240,6 +241,13 @@
 	movq	CR0(%r8), %r8
 	movq	%rax, %cr3
 	movq	%r8, %cr0
+
+#ifdef CONFIG_KEXEC_JUMP
+	/* Saved in save_processor_state. */
+	movq    $saved_context, %rax
+	lgdt    saved_context_gdt_desc(%rax)
+#endif
+
 	movq	%rbp, %rax
 
 	popf
--- linux-qcom-6.8.0.orig/arch/x86/kernel/setup.c
+++ linux-qcom-6.8.0/arch/x86/kernel/setup.c
@@ -9,7 +9,6 @@
 #include <linux/console.h>
 #include <linux/crash_dump.h>
 #include <linux/dma-map-ops.h>
-#include <linux/dmi.h>
 #include <linux/efi.h>
 #include <linux/ima.h>
 #include <linux/init_ohci1394_dma.h>
@@ -21,6 +20,7 @@
 #include <linux/root_dev.h>
 #include <linux/hugetlb.h>
 #include <linux/tboot.h>
+#include <linux/security.h>
 #include <linux/usb/xhci-dbgp.h>
 #include <linux/static_call.h>
 #include <linux/swiotlb.h>
@@ -36,6 +36,7 @@
 #include <asm/bios_ebda.h>
 #include <asm/bugs.h>
 #include <asm/cacheinfo.h>
+#include <asm/coco.h>
 #include <asm/cpu.h>
 #include <asm/efi.h>
 #include <asm/gart.h>
@@ -902,7 +903,15 @@
 		efi_init();
 
 	reserve_ibft_region();
-	dmi_setup();
+
+	efi_set_secure_boot(boot_params.secure_boot);
+
+#ifdef CONFIG_LOCK_DOWN_IN_SECURE_BOOT
+	if (efi_enabled(EFI_SECURE_BOOT))
+		security_lock_kernel_down("EFI Secure Boot mode", LOCKDOWN_INTEGRITY_MAX);
+#endif
+
+	x86_init.resources.dmi_setup();
 
 	/*
 	 * VMware detection requires dmi to be available, so this
@@ -994,6 +1003,7 @@
 	 * memory size.
 	 */
 	mem_encrypt_setup_arch();
+	cc_random_init();
 
 	efi_fake_memmap();
 	efi_find_mirror();
@@ -1064,19 +1074,7 @@
 	/* Allocate bigger log buffer */
 	setup_log_buf(1);
 
-	if (efi_enabled(EFI_BOOT)) {
-		switch (boot_params.secure_boot) {
-		case efi_secureboot_mode_disabled:
-			pr_info("Secure boot disabled\n");
-			break;
-		case efi_secureboot_mode_enabled:
-			pr_info("Secure boot enabled\n");
-			break;
-		default:
-			pr_info("Secure boot could not be determined\n");
-			break;
-		}
-	}
+	efi_set_secure_boot(boot_params.secure_boot);
 
 	reserve_initrd();
 
--- linux-qcom-6.8.0.orig/arch/x86/kernel/sev-shared.c
+++ linux-qcom-6.8.0/arch/x86/kernel/sev-shared.c
@@ -10,11 +10,15 @@
  */
 
 #ifndef __BOOT_COMPRESSED
-#define error(v)	pr_err(v)
-#define has_cpuflag(f)	boot_cpu_has(f)
+#define error(v)			pr_err(v)
+#define has_cpuflag(f)			boot_cpu_has(f)
+#define sev_printk(fmt, ...)		printk(fmt, ##__VA_ARGS__)
+#define sev_printk_rtl(fmt, ...)	printk_ratelimited(fmt, ##__VA_ARGS__)
 #else
 #undef WARN
 #define WARN(condition, format...) (!!(condition))
+#define sev_printk(fmt, ...)
+#define sev_printk_rtl(fmt, ...)
 #endif
 
 /* I/O parameters for CPUID-related helpers */
@@ -89,7 +93,8 @@
 	return true;
 }
 
-static void __noreturn sev_es_terminate(unsigned int set, unsigned int reason)
+static void __head __noreturn
+sev_es_terminate(unsigned int set, unsigned int reason)
 {
 	u64 val = GHCB_MSR_TERM_REQ;
 
@@ -326,13 +331,7 @@
  */
 static const struct snp_cpuid_table *snp_cpuid_get_table(void)
 {
-	void *ptr;
-
-	asm ("lea cpuid_table_copy(%%rip), %0"
-	     : "=r" (ptr)
-	     : "p" (&cpuid_table_copy));
-
-	return ptr;
+	return &RIP_REL_REF(cpuid_table_copy);
 }
 
 /*
@@ -391,7 +390,7 @@
 	return xsave_size;
 }
 
-static bool
+static bool __head
 snp_cpuid_get_validated_func(struct cpuid_leaf *leaf)
 {
 	const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table();
@@ -528,7 +527,8 @@
  * Returns -EOPNOTSUPP if feature not enabled. Any other non-zero return value
  * should be treated as fatal by caller.
  */
-static int snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf)
+static int __head
+snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf)
 {
 	const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table();
 
@@ -556,9 +556,9 @@
 		leaf->eax = leaf->ebx = leaf->ecx = leaf->edx = 0;
 
 		/* Skip post-processing for out-of-range zero leafs. */
-		if (!(leaf->fn <= cpuid_std_range_max ||
-		      (leaf->fn >= 0x40000000 && leaf->fn <= cpuid_hyp_range_max) ||
-		      (leaf->fn >= 0x80000000 && leaf->fn <= cpuid_ext_range_max)))
+		if (!(leaf->fn <= RIP_REL_REF(cpuid_std_range_max) ||
+		      (leaf->fn >= 0x40000000 && leaf->fn <= RIP_REL_REF(cpuid_hyp_range_max)) ||
+		      (leaf->fn >= 0x80000000 && leaf->fn <= RIP_REL_REF(cpuid_ext_range_max))))
 			return 0;
 	}
 
@@ -570,10 +570,11 @@
  * page yet, so it only supports the MSR based communication with the
  * hypervisor and only the CPUID exit-code.
  */
-void __init do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
+void __head do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
 {
 	unsigned int subfn = lower_bits(regs->cx, 32);
 	unsigned int fn = lower_bits(regs->ax, 32);
+	u16 opcode = *(unsigned short *)regs->ip;
 	struct cpuid_leaf leaf;
 	int ret;
 
@@ -581,6 +582,10 @@
 	if (exit_code != SVM_EXIT_CPUID)
 		goto fail;
 
+	/* Is it really a CPUID insn? */
+	if (opcode != 0xa20f)
+		goto fail;
+
 	leaf.fn = fn;
 	leaf.subfn = subfn;
 
@@ -1016,7 +1021,8 @@
  * Search for a Confidential Computing blob passed in as a setup_data entry
  * via the Linux Boot Protocol.
  */
-static struct cc_blob_sev_info *find_cc_blob_setup_data(struct boot_params *bp)
+static __head
+struct cc_blob_sev_info *find_cc_blob_setup_data(struct boot_params *bp)
 {
 	struct cc_setup_data *sd = NULL;
 	struct setup_data *hdr;
@@ -1043,7 +1049,7 @@
  * mapping needs to be updated in sync with all the changes to virtual memory
  * layout and related mapping facilities throughout the boot process.
  */
-static void __init setup_cpuid_table(const struct cc_blob_sev_info *cc_info)
+static void __head setup_cpuid_table(const struct cc_blob_sev_info *cc_info)
 {
 	const struct snp_cpuid_table *cpuid_table_fw, *cpuid_table;
 	int i;
@@ -1063,11 +1069,11 @@
 		const struct snp_cpuid_fn *fn = &cpuid_table->fn[i];
 
 		if (fn->eax_in == 0x0)
-			cpuid_std_range_max = fn->eax;
+			RIP_REL_REF(cpuid_std_range_max) = fn->eax;
 		else if (fn->eax_in == 0x40000000)
-			cpuid_hyp_range_max = fn->eax;
+			RIP_REL_REF(cpuid_hyp_range_max) = fn->eax;
 		else if (fn->eax_in == 0x80000000)
-			cpuid_ext_range_max = fn->eax;
+			RIP_REL_REF(cpuid_ext_range_max) = fn->eax;
 	}
 }
 
@@ -1170,3 +1176,94 @@
 out:
 	return ret;
 }
+
+static enum es_result vc_check_opcode_bytes(struct es_em_ctxt *ctxt,
+					    unsigned long exit_code)
+{
+	unsigned int opcode = (unsigned int)ctxt->insn.opcode.value;
+	u8 modrm = ctxt->insn.modrm.value;
+
+	switch (exit_code) {
+
+	case SVM_EXIT_IOIO:
+	case SVM_EXIT_NPF:
+		/* handled separately */
+		return ES_OK;
+
+	case SVM_EXIT_CPUID:
+		if (opcode == 0xa20f)
+			return ES_OK;
+		break;
+
+	case SVM_EXIT_INVD:
+		if (opcode == 0x080f)
+			return ES_OK;
+		break;
+
+	case SVM_EXIT_MONITOR:
+		/* MONITOR and MONITORX instructions generate the same error code */
+		if (opcode == 0x010f && (modrm == 0xc8 || modrm == 0xfa))
+			return ES_OK;
+		break;
+
+	case SVM_EXIT_MWAIT:
+		/* MWAIT and MWAITX instructions generate the same error code */
+		if (opcode == 0x010f && (modrm == 0xc9 || modrm == 0xfb))
+			return ES_OK;
+		break;
+
+	case SVM_EXIT_MSR:
+		/* RDMSR */
+		if (opcode == 0x320f ||
+		/* WRMSR */
+		    opcode == 0x300f)
+			return ES_OK;
+		break;
+
+	case SVM_EXIT_RDPMC:
+		if (opcode == 0x330f)
+			return ES_OK;
+		break;
+
+	case SVM_EXIT_RDTSC:
+		if (opcode == 0x310f)
+			return ES_OK;
+		break;
+
+	case SVM_EXIT_RDTSCP:
+		if (opcode == 0x010f && modrm == 0xf9)
+			return ES_OK;
+		break;
+
+	case SVM_EXIT_READ_DR7:
+		if (opcode == 0x210f &&
+		    X86_MODRM_REG(ctxt->insn.modrm.value) == 7)
+			return ES_OK;
+		break;
+
+	case SVM_EXIT_VMMCALL:
+		if (opcode == 0x010f && modrm == 0xd9)
+			return ES_OK;
+
+		break;
+
+	case SVM_EXIT_WRITE_DR7:
+		if (opcode == 0x230f &&
+		    X86_MODRM_REG(ctxt->insn.modrm.value) == 7)
+			return ES_OK;
+		break;
+
+	case SVM_EXIT_WBINVD:
+		if (opcode == 0x90f)
+			return ES_OK;
+		break;
+
+	default:
+		break;
+	}
+
+	sev_printk(KERN_ERR "Wrong/unhandled opcode bytes: 0x%x, exit_code: 0x%lx, rIP: 0x%lx\n",
+		   opcode, exit_code, ctxt->regs->ip);
+
+	return ES_UNSUPPORTED;
+}
--- linux-qcom-6.8.0.orig/arch/x86/kernel/sev.c
+++ linux-qcom-6.8.0/arch/x86/kernel/sev.c
@@ -23,8 +23,10 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/psp-sev.h>
+#include <linux/dmi.h>
 #include <uapi/linux/sev-guest.h>
 
+#include <asm/init.h>
 #include <asm/cpu_entry_area.h>
 #include <asm/stacktrace.h>
 #include <asm/sev.h>
@@ -682,8 +684,9 @@
 	return ret;
 }
 
-static void early_set_pages_state(unsigned long vaddr, unsigned long paddr,
-				  unsigned long npages, enum psc_op op)
+static void __head
+early_set_pages_state(unsigned long vaddr, unsigned long paddr,
+		      unsigned long npages, enum psc_op op)
 {
 	unsigned long paddr_end;
 	u64 val;
@@ -739,7 +742,7 @@
 	sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);
 }
 
-void __init early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr,
+void __head early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr,
 					 unsigned long npages)
 {
 	/*
@@ -748,7 +751,7 @@
 	 * This eliminates worries about jump tables or checking boot_cpu_data
 	 * in the cc_platform_has() function.
 	 */
-	if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
+	if (!(RIP_REL_REF(sev_status) & MSR_AMD64_SEV_SNP_ENABLED))
 		return;
 
 	 /*
@@ -767,28 +770,13 @@
 	 * This eliminates worries about jump tables or checking boot_cpu_data
 	 * in the cc_platform_has() function.
 	 */
-	if (!(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
+	if (!(RIP_REL_REF(sev_status) & MSR_AMD64_SEV_SNP_ENABLED))
 		return;
 
 	 /* Ask hypervisor to mark the memory pages shared in the RMP table. */
 	early_set_pages_state(vaddr, paddr, npages, SNP_PAGE_STATE_SHARED);
 }
 
-void __init snp_prep_memory(unsigned long paddr, unsigned int sz, enum psc_op op)
-{
-	unsigned long vaddr, npages;
-
-	vaddr = (unsigned long)__va(paddr);
-	npages = PAGE_ALIGN(sz) >> PAGE_SHIFT;
-
-	if (op == SNP_PAGE_STATE_PRIVATE)
-		early_snp_set_memory_private(vaddr, paddr, npages);
-	else if (op == SNP_PAGE_STATE_SHARED)
-		early_snp_set_memory_shared(vaddr, paddr, npages);
-	else
-		WARN(1, "invalid memory op %d\n", op);
-}
-
 static unsigned long __set_pages_state(struct snp_psc_desc *data, unsigned long vaddr,
 				       unsigned long vaddr_end, int op)
 {
@@ -1752,7 +1740,10 @@
 					 struct ghcb *ghcb,
 					 unsigned long exit_code)
 {
-	enum es_result result;
+	enum es_result result = vc_check_opcode_bytes(ctxt, exit_code);
+
+	if (result != ES_OK)
+		return result;
 
 	switch (exit_code) {
 	case SVM_EXIT_READ_DR7:
@@ -2059,7 +2050,7 @@
  *
  * Scan for the blob in that order.
  */
-static __init struct cc_blob_sev_info *find_cc_blob(struct boot_params *bp)
+static __head struct cc_blob_sev_info *find_cc_blob(struct boot_params *bp)
 {
 	struct cc_blob_sev_info *cc_info;
 
@@ -2085,7 +2076,7 @@
 	return cc_info;
 }
 
-bool __init snp_init(struct boot_params *bp)
+bool __head snp_init(struct boot_params *bp)
 {
 	struct cc_blob_sev_info *cc_info;
 
@@ -2107,11 +2098,22 @@
 	return true;
 }
 
-void __init __noreturn snp_abort(void)
+void __head __noreturn snp_abort(void)
 {
 	sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
 }
 
+/*
+ * SEV-SNP guests should only execute dmi_setup() if EFI_CONFIG_TABLES are
+ * enabled, as the alternative (fallback) logic for DMI probing in the legacy
+ * ROM region can cause a crash since this region is not pre-validated.
+ */
+void __init snp_dmi_setup(void)
+{
+	if (efi_enabled(EFI_CONFIG_TABLES))
+		dmi_setup();
+}
+
 static void dump_cpuid_table(void)
 {
 	const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table();
--- linux-qcom-6.8.0.orig/arch/x86/kernel/shstk.c
+++ linux-qcom-6.8.0/arch/x86/kernel/shstk.c
@@ -577,3 +577,14 @@
 		return wrss_control(true);
 	return -EINVAL;
 }
+
+int shstk_update_last_frame(unsigned long val)
+{
+	unsigned long ssp;
+
+	if (!features_enabled(ARCH_SHSTK_SHSTK))
+		return 0;
+
+	ssp = get_user_shstk_addr();
+	return write_user_shstk_64((u64 __user *)ssp, (u64)val);
+}
--- linux-qcom-6.8.0.orig/arch/x86/kernel/signal.c
+++ linux-qcom-6.8.0/arch/x86/kernel/signal.c
@@ -84,6 +84,7 @@
 	unsigned long math_size = 0;
 	unsigned long sp = regs->sp;
 	unsigned long buf_fx = 0;
+	u32 pkru = read_pkru();
 
 	/* redzone */
 	if (!ia32_frame)
@@ -139,7 +140,7 @@
 	}
 
 	/* save i387 and extended state */
-	if (!copy_fpstate_to_sigframe(*fpstate, (void __user *)buf_fx, math_size))
+	if (!copy_fpstate_to_sigframe(*fpstate, (void __user *)buf_fx, math_size, pkru))
 		return (void __user *)-1L;
 
 	return (void __user *)sp;
--- linux-qcom-6.8.0.orig/arch/x86/kernel/signal_64.c
+++ linux-qcom-6.8.0/arch/x86/kernel/signal_64.c
@@ -260,13 +260,13 @@
 
 	set_current_blocked(&set);
 
-	if (!restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags))
+	if (restore_altstack(&frame->uc.uc_stack))
 		goto badframe;
 
-	if (restore_signal_shadow_stack())
+	if (!restore_sigcontext(regs, &frame->uc.uc_mcontext, uc_flags))
 		goto badframe;
 
-	if (restore_altstack(&frame->uc.uc_stack))
+	if (restore_signal_shadow_stack())
 		goto badframe;
 
 	return regs->ax;
--- linux-qcom-6.8.0.orig/arch/x86/kernel/smpboot.c
+++ linux-qcom-6.8.0/arch/x86/kernel/smpboot.c
@@ -60,6 +60,7 @@
 #include <linux/stackprotector.h>
 #include <linux/cpuhotplug.h>
 #include <linux/mc146818rtc.h>
+#include <linux/acpi.h>
 
 #include <asm/acpi.h>
 #include <asm/cacheinfo.h>
@@ -613,14 +614,6 @@
 }
 #endif
 
-static int x86_die_flags(void)
-{
-	if (cpu_feature_enabled(X86_FEATURE_HYBRID_CPU))
-	       return x86_sched_itmt_flags();
-
-	return 0;
-}
-
 /*
  * Set if a package/die has multiple NUMA nodes inside.
  * AMD Magny-Cours, Intel Cluster-on-Die, and Intel
@@ -656,7 +649,7 @@
 	 */
 	if (!x86_has_numa_in_package) {
 		x86_topology[i++] = (struct sched_domain_topology_level){
-			cpu_cpu_mask, x86_die_flags, SD_INIT_NAME(PKG)
+			cpu_cpu_mask, x86_sched_itmt_flags, SD_INIT_NAME(PKG)
 		};
 	}
 
--- linux-qcom-6.8.0.orig/arch/x86/kernel/static_call.c
+++ linux-qcom-6.8.0/arch/x86/kernel/static_call.c
@@ -172,6 +172,14 @@
 }
 EXPORT_SYMBOL_GPL(arch_static_call_transform);
 
+noinstr void __static_call_update_early(void *tramp, void *func)
+{
+	BUG_ON(system_state != SYSTEM_BOOTING);
+	BUG_ON(static_call_initialized);
+	__text_gen_insn(tramp, JMP32_INSN_OPCODE, tramp, func, JMP32_INSN_SIZE);
+	sync_core();
+}
+
 #ifdef CONFIG_RETHUNK
 /*
  * This is called by apply_returns() to fix up static call trampolines,
--- linux-qcom-6.8.0.orig/arch/x86/kernel/time.c
+++ linux-qcom-6.8.0/arch/x86/kernel/time.c
@@ -27,25 +27,7 @@
 
 unsigned long profile_pc(struct pt_regs *regs)
 {
-	unsigned long pc = instruction_pointer(regs);
-
-	if (!user_mode(regs) && in_lock_functions(pc)) {
-#ifdef CONFIG_FRAME_POINTER
-		return *(unsigned long *)(regs->bp + sizeof(long));
-#else
-		unsigned long *sp = (unsigned long *)regs->sp;
-		/*
-		 * Return address is either directly at stack pointer
-		 * or above a saved flags. Eflags has bits 22-31 zero,
-		 * kernel addresses don't.
-		 */
-		if (sp[0] >> 22)
-			return sp[0];
-		if (sp[1] >> 22)
-			return sp[1];
-#endif
-	}
-	return pc;
+	return instruction_pointer(regs);
 }
 EXPORT_SYMBOL(profile_pc);
 
--- linux-qcom-6.8.0.orig/arch/x86/kernel/traps.c
+++ linux-qcom-6.8.0/arch/x86/kernel/traps.c
@@ -42,6 +42,7 @@
 #include <linux/hardirq.h>
 #include <linux/atomic.h>
 #include <linux/iommu.h>
+#include <linux/ubsan.h>
 
 #include <asm/stacktrace.h>
 #include <asm/processor.h>
@@ -90,6 +91,47 @@
 	return *(unsigned short *)addr == INSN_UD2;
 }
 
+/*
+ * Check for UD1 or UD2, accounting for Address Size Override Prefixes.
+ * If it's a UD1, get the ModRM byte to pass along to UBSan.
+ */
+__always_inline int decode_bug(unsigned long addr, u32 *imm)
+{
+	u8 v;
+
+	if (addr < TASK_SIZE_MAX)
+		return BUG_NONE;
+
+	v = *(u8 *)(addr++);
+	if (v == INSN_ASOP)
+		v = *(u8 *)(addr++);
+	if (v != OPCODE_ESCAPE)
+		return BUG_NONE;
+
+	v = *(u8 *)(addr++);
+	if (v == SECOND_BYTE_OPCODE_UD2)
+		return BUG_UD2;
+
+	if (!IS_ENABLED(CONFIG_UBSAN_TRAP) || v != SECOND_BYTE_OPCODE_UD1)
+		return BUG_NONE;
+
+	/* Retrieve the immediate (type value) for the UBSAN UD1 */
+	v = *(u8 *)(addr++);
+	if (X86_MODRM_RM(v) == 4)
+		addr++;
+
+	*imm = 0;
+	if (X86_MODRM_MOD(v) == 1)
+		*imm = *(u8 *)addr;
+	else if (X86_MODRM_MOD(v) == 2)
+		*imm = *(u32 *)addr;
+	else
+		WARN_ONCE(1, "Unexpected MODRM_MOD: %u\n", X86_MODRM_MOD(v));
+
+	return BUG_UD1;
+}
+
+
 static nokprobe_inline int
 do_trap_no_signal(struct task_struct *tsk, int trapnr, const char *str,
 		  struct pt_regs *regs,	long error_code)
@@ -215,14 +257,11 @@
 static noinstr bool handle_bug(struct pt_regs *regs)
 {
 	bool handled = false;
+	int ud_type;
+	u32 imm;
 
-	/*
-	 * Normally @regs are unpoisoned by irqentry_enter(), but handle_bug()
-	 * is a rare case that uses @regs without passing them to
-	 * irqentry_enter().
-	 */
-	kmsan_unpoison_entry_regs(regs);
-	if (!is_valid_bugaddr(regs->ip))
+	ud_type = decode_bug(regs->ip, &imm);
+	if (ud_type == BUG_NONE)
 		return handled;
 
 	/*
@@ -230,15 +269,25 @@
 	 */
 	instrumentation_begin();
 	/*
+	 * Normally @regs are unpoisoned by irqentry_enter(), but handle_bug()
+	 * is a rare case that uses @regs without passing them to
+	 * irqentry_enter().
+	 */
+	kmsan_unpoison_entry_regs(regs);
+	/*
 	 * Since we're emulating a CALL with exceptions, restore the interrupt
 	 * state to what it was at the exception site.
 	 */
 	if (regs->flags & X86_EFLAGS_IF)
 		raw_local_irq_enable();
-	if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN ||
-	    handle_cfi_failure(regs) == BUG_TRAP_TYPE_WARN) {
-		regs->ip += LEN_UD2;
-		handled = true;
+	if (ud_type == BUG_UD2) {
+		if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN ||
+		    handle_cfi_failure(regs) == BUG_TRAP_TYPE_WARN) {
+			regs->ip += LEN_UD2;
+			handled = true;
+		}
+	} else if (IS_ENABLED(CONFIG_UBSAN_TRAP)) {
+		pr_crit("%s at %pS\n", report_ubsan_failure(regs, imm), (void *)regs->ip);
 	}
 	if (regs->flags & X86_EFLAGS_IF)
 		raw_local_irq_disable();
--- linux-qcom-6.8.0.orig/arch/x86/kernel/tsc_sync.c
+++ linux-qcom-6.8.0/arch/x86/kernel/tsc_sync.c
@@ -193,11 +193,9 @@
 	cur->warned = false;
 
 	/*
-	 * If a non-zero TSC value for socket 0 may be valid then the default
-	 * adjusted value cannot assumed to be zero either.
+	 * The default adjust value cannot be assumed to be zero on any socket.
 	 */
-	if (tsc_async_resets)
-		cur->adjusted = bootval;
+	cur->adjusted = bootval;
 
 	/*
 	 * Check whether this CPU is the first in a package to come up. In
--- linux-qcom-6.8.0.orig/arch/x86/kernel/unwind_orc.c
+++ linux-qcom-6.8.0/arch/x86/kernel/unwind_orc.c
@@ -723,7 +723,7 @@
 		state->sp = task->thread.sp + sizeof(*frame);
 		state->bp = READ_ONCE_NOCHECK(frame->bp);
 		state->ip = READ_ONCE_NOCHECK(frame->ret_addr);
-		state->signal = (void *)state->ip == ret_from_fork;
+		state->signal = (void *)state->ip == ret_from_fork_asm;
 	}
 
 	if (get_stack_info((unsigned long *)state->sp, state->task,
--- linux-qcom-6.8.0.orig/arch/x86/kernel/uprobes.c
+++ linux-qcom-6.8.0/arch/x86/kernel/uprobes.c
@@ -1076,8 +1076,13 @@
 		return orig_ret_vaddr;
 
 	nleft = copy_to_user((void __user *)regs->sp, &trampoline_vaddr, rasize);
-	if (likely(!nleft))
+	if (likely(!nleft)) {
+		if (shstk_update_last_frame(trampoline_vaddr)) {
+			force_sig(SIGSEGV);
+			return -1;
+		}
 		return orig_ret_vaddr;
+	}
 
 	if (nleft != rasize) {
 		pr_err("return address clobbered: pid=%d, %%sp=%#lx, %%ip=%#lx\n",
--- linux-qcom-6.8.0.orig/arch/x86/kernel/vmlinux.lds.S
+++ linux-qcom-6.8.0/arch/x86/kernel/vmlinux.lds.S
@@ -489,6 +489,9 @@
 . = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),
 	   "kernel image bigger than KERNEL_IMAGE_SIZE");
 
+/* needed for Clang - see arch/x86/entry/entry.S */
+PROVIDE(__ref_stack_chk_guard = __stack_chk_guard);
+
 #ifdef CONFIG_X86_64
 /*
  * Per-cpu symbols which need to be offset from __per_cpu_load
--- linux-qcom-6.8.0.orig/arch/x86/kernel/x86_init.c
+++ linux-qcom-6.8.0/arch/x86/kernel/x86_init.c
@@ -3,10 +3,12 @@
  *
  *  For licencing details see kernel-base/COPYING
  */
+#include <linux/dmi.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/export.h>
 #include <linux/pci.h>
+#include <linux/acpi.h>
 
 #include <asm/acpi.h>
 #include <asm/bios_ebda.h>
@@ -66,6 +68,7 @@
 		.probe_roms		= probe_roms,
 		.reserve_resources	= reserve_standard_io_resources,
 		.memory_setup		= e820__memory_setup_default,
+		.dmi_setup		= dmi_setup,
 	},
 
 	.mpparse = {
@@ -131,10 +134,12 @@
 
 static void default_nmi_init(void) { };
 
-static bool enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool enc) { return true; }
-static bool enc_status_change_finish_noop(unsigned long vaddr, int npages, bool enc) { return true; }
+static int enc_status_change_prepare_noop(unsigned long vaddr, int npages, bool enc) { return 0; }
+static int enc_status_change_finish_noop(unsigned long vaddr, int npages, bool enc) { return 0; }
 static bool enc_tlb_flush_required_noop(bool enc) { return false; }
 static bool enc_cache_flush_required_noop(void) { return false; }
+static void enc_kexec_begin_noop(void) {}
+static void enc_kexec_finish_noop(void) {}
 static bool is_private_mmio_noop(u64 addr) {return false; }
 
 struct x86_platform_ops x86_platform __ro_after_init = {
@@ -158,6 +163,8 @@
 		.enc_status_change_finish  = enc_status_change_finish_noop,
 		.enc_tlb_flush_required	   = enc_tlb_flush_required_noop,
 		.enc_cache_flush_required  = enc_cache_flush_required_noop,
+		.enc_kexec_begin	   = enc_kexec_begin_noop,
+		.enc_kexec_finish	   = enc_kexec_finish_noop,
 	},
 };
 
--- linux-qcom-6.8.0.orig/arch/x86/kvm/Kconfig
+++ linux-qcom-6.8.0/arch/x86/kvm/Kconfig
@@ -32,6 +32,7 @@
 	select IRQ_BYPASS_MANAGER
 	select HAVE_KVM_IRQ_BYPASS
 	select HAVE_KVM_IRQ_ROUTING
+	select VHOST_TASK
 	select KVM_ASYNC_PF
 	select USER_RETURN_NOTIFIER
 	select KVM_MMIO
--- linux-qcom-6.8.0.orig/arch/x86/kvm/cpuid.c
+++ linux-qcom-6.8.0/arch/x86/kvm/cpuid.c
@@ -36,6 +36,26 @@
 u32 kvm_cpu_caps[NR_KVM_CPU_CAPS] __read_mostly;
 EXPORT_SYMBOL_GPL(kvm_cpu_caps);
 
+struct cpuid_xstate_sizes {
+	u32 eax;
+	u32 ebx;
+	u32 ecx;
+};
+
+static struct cpuid_xstate_sizes xstate_sizes[XFEATURE_MAX] __ro_after_init;
+
+void __init kvm_init_xstate_sizes(void)
+{
+	u32 ign;
+	int i;
+
+	for (i = XFEATURE_YMM; i < ARRAY_SIZE(xstate_sizes); i++) {
+		struct cpuid_xstate_sizes *xs = &xstate_sizes[i];
+
+		cpuid_count(0xD, i, &xs->eax, &xs->ebx, &xs->ecx, &ign);
+	}
+}
+
 u32 xstate_required_size(u64 xstate_bv, bool compacted)
 {
 	int feature_bit = 0;
@@ -44,14 +64,15 @@
 	xstate_bv &= XFEATURE_MASK_EXTEND;
 	while (xstate_bv) {
 		if (xstate_bv & 0x1) {
-		        u32 eax, ebx, ecx, edx, offset;
-		        cpuid_count(0xD, feature_bit, &eax, &ebx, &ecx, &edx);
+			struct cpuid_xstate_sizes *xs = &xstate_sizes[feature_bit];
+			u32 offset;
+
 			/* ECX[1]: 64B alignment in compacted form */
 			if (compacted)
-				offset = (ecx & 0x2) ? ALIGN(ret, 64) : ret;
+				offset = (xs->ecx & 0x2) ? ALIGN(ret, 64) : ret;
 			else
-				offset = ebx;
-			ret = max(ret, offset + eax);
+				offset = xs->ebx;
+			ret = max(ret, offset + xs->eax);
 		}
 
 		xstate_bv >>= 1;
@@ -366,6 +387,7 @@
 
 	kvm_update_pv_runtime(vcpu);
 
+	vcpu->arch.is_amd_compatible = guest_cpuid_is_amd_or_hygon(vcpu);
 	vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu);
 	vcpu->arch.reserved_gpa_bits = kvm_vcpu_reserved_gpa_bits_raw(vcpu);
 
@@ -1221,9 +1243,8 @@
 		entry->eax = entry->ebx = entry->ecx = 0;
 		break;
 	case 0x80000008: {
-		unsigned g_phys_as = (entry->eax >> 16) & 0xff;
-		unsigned virt_as = max((entry->eax >> 8) & 0xff, 48U);
-		unsigned phys_as = entry->eax & 0xff;
+		unsigned int virt_as = max((entry->eax >> 8) & 0xff, 48U);
+		unsigned int phys_as;
 
 		/*
 		 * If TDP (NPT) is disabled use the adjusted host MAXPHYADDR as
@@ -1231,16 +1252,16 @@
 		 * reductions in MAXPHYADDR for memory encryption affect shadow
 		 * paging, too.
 		 *
-		 * If TDP is enabled but an explicit guest MAXPHYADDR is not
-		 * provided, use the raw bare metal MAXPHYADDR as reductions to
-		 * the HPAs do not affect GPAs.
+		 * If TDP is enabled, use the raw bare metal MAXPHYADDR as
+		 * reductions to the HPAs do not affect GPAs.
 		 */
-		if (!tdp_enabled)
-			g_phys_as = boot_cpu_data.x86_phys_bits;
-		else if (!g_phys_as)
-			g_phys_as = phys_as;
+		if (!tdp_enabled) {
+			phys_as = boot_cpu_data.x86_phys_bits;
+		} else {
+			phys_as = entry->eax & 0xff;
+		}
 
-		entry->eax = g_phys_as | (virt_as << 8);
+		entry->eax = phys_as | (virt_as << 8);
 		entry->ecx &= ~(GENMASK(31, 16) | GENMASK(11, 8));
 		entry->edx = 0;
 		cpuid_entry_override(entry, CPUID_8000_0008_EBX);
--- linux-qcom-6.8.0.orig/arch/x86/kvm/cpuid.h
+++ linux-qcom-6.8.0/arch/x86/kvm/cpuid.h
@@ -32,6 +32,7 @@
 bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
 	       u32 *ecx, u32 *edx, bool exact_only);
 
+void __init kvm_init_xstate_sizes(void);
 u32 xstate_required_size(u64 xstate_bv, bool compacted);
 
 int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu);
@@ -120,6 +121,16 @@
 	return best && is_guest_vendor_intel(best->ebx, best->ecx, best->edx);
 }
 
+static inline bool guest_cpuid_is_amd_compatible(struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.is_amd_compatible;
+}
+
+static inline bool guest_cpuid_is_intel_compatible(struct kvm_vcpu *vcpu)
+{
+	return !guest_cpuid_is_amd_compatible(vcpu);
+}
+
 static inline int guest_cpuid_family(struct kvm_vcpu *vcpu)
 {
 	struct kvm_cpuid_entry2 *best;
--- linux-qcom-6.8.0.orig/arch/x86/kvm/lapic.c
+++ linux-qcom-6.8.0/arch/x86/kvm/lapic.c
@@ -41,6 +41,7 @@
 #include "ioapic.h"
 #include "trace.h"
 #include "x86.h"
+#include "xen.h"
 #include "cpuid.h"
 #include "hyperv.h"
 #include "smm.h"
@@ -337,10 +338,8 @@
 	 * reversing the LDR calculation to get cluster of APICs, i.e. no
 	 * additional work is required.
 	 */
-	if (apic_x2apic_mode(apic)) {
-		WARN_ON_ONCE(ldr != kvm_apic_calc_x2apic_ldr(kvm_x2apic_id(apic)));
+	if (apic_x2apic_mode(apic))
 		return;
-	}
 
 	if (WARN_ON_ONCE(!kvm_apic_map_get_logical_dest(new, ldr,
 							&cluster, &mask))) {
@@ -499,8 +498,10 @@
 	}
 
 	/* Check if there are APF page ready requests pending */
-	if (enabled)
+	if (enabled) {
 		kvm_make_request(KVM_REQ_APF_READY, apic->vcpu);
+		kvm_xen_sw_enable_lapic(apic->vcpu);
+	}
 }
 
 static inline void kvm_apic_set_xapic_id(struct kvm_lapic *apic, u8 id)
@@ -749,7 +750,7 @@
 	 * just set SVI.
 	 */
 	if (unlikely(apic->apicv_active))
-		static_call_cond(kvm_x86_hwapic_isr_update)(vec);
+		static_call_cond(kvm_x86_hwapic_isr_update)(apic->vcpu, vec);
 	else {
 		++apic->isr_count;
 		BUG_ON(apic->isr_count > MAX_APIC_VECTOR);
@@ -794,7 +795,7 @@
 	 * and must be left alone.
 	 */
 	if (unlikely(apic->apicv_active))
-		static_call_cond(kvm_x86_hwapic_isr_update)(apic_find_highest_isr(apic));
+		static_call_cond(kvm_x86_hwapic_isr_update)(apic->vcpu, apic_find_highest_isr(apic));
 	else {
 		--apic->isr_count;
 		BUG_ON(apic->isr_count < 0);
@@ -2439,6 +2440,43 @@
 }
 EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi);
 
+#define X2APIC_ICR_RESERVED_BITS (GENMASK_ULL(31, 20) | GENMASK_ULL(17, 16) | BIT(13))
+
+int kvm_x2apic_icr_write(struct kvm_lapic *apic, u64 data)
+{
+	if (data & X2APIC_ICR_RESERVED_BITS)
+		return 1;
+
+	/*
+	 * The BUSY bit is reserved on both Intel and AMD in x2APIC mode, but
+	 * only AMD requires it to be zero, Intel essentially just ignores the
+	 * bit.  And if IPI virtualization (Intel) or x2AVIC (AMD) is enabled,
+	 * the CPU performs the reserved bits checks, i.e. the underlying CPU
+	 * behavior will "win".  Arbitrarily clear the BUSY bit, as there is no
+	 * sane way to provide consistent behavior with respect to hardware.
+	 */
+	data &= ~APIC_ICR_BUSY;
+
+	kvm_apic_send_ipi(apic, (u32)data, (u32)(data >> 32));
+	if (kvm_x86_ops.x2apic_icr_is_split) {
+		kvm_lapic_set_reg(apic, APIC_ICR, data);
+		kvm_lapic_set_reg(apic, APIC_ICR2, data >> 32);
+	} else {
+		kvm_lapic_set_reg64(apic, APIC_ICR, data);
+	}
+	trace_kvm_apic_write(APIC_ICR, data);
+	return 0;
+}
+
+static u64 kvm_x2apic_icr_read(struct kvm_lapic *apic)
+{
+	if (kvm_x86_ops.x2apic_icr_is_split)
+		return (u64)kvm_lapic_get_reg(apic, APIC_ICR) |
+		       (u64)kvm_lapic_get_reg(apic, APIC_ICR2) << 32;
+
+	return kvm_lapic_get_reg64(apic, APIC_ICR);
+}
+
 /* emulate APIC access in a trap manner */
 void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset)
 {
@@ -2456,7 +2494,7 @@
 	 * maybe-unecessary write, and both are in the noise anyways.
 	 */
 	if (apic_x2apic_mode(apic) && offset == APIC_ICR)
-		kvm_x2apic_icr_write(apic, kvm_lapic_get_reg64(apic, APIC_ICR));
+		WARN_ON_ONCE(kvm_x2apic_icr_write(apic, kvm_x2apic_icr_read(apic)));
 	else
 		kvm_lapic_reg_write(apic, offset, kvm_lapic_get_reg(apic, offset));
 }
@@ -2576,19 +2614,26 @@
 {
 	struct kvm_lapic *apic = vcpu->arch.apic;
 
-	if (apic->apicv_active) {
-		/* irr_pending is always true when apicv is activated. */
-		apic->irr_pending = true;
+	/*
+	 * When APICv is enabled, KVM must always search the IRR for a pending
+	 * IRQ, as other vCPUs and devices can set IRR bits even if the vCPU
+	 * isn't running.  If APICv is disabled, KVM _should_ search the IRR
+	 * for a pending IRQ.  But KVM currently doesn't ensure *all* hardware,
+	 * e.g. CPUs and IOMMUs, has seen the change in state, i.e. searching
+	 * the IRR at this time could race with IRQ delivery from hardware that
+	 * still sees APICv as being enabled.
+	 *
+	 * FIXME: Ensure other vCPUs and devices observe the change in APICv
+	 *        state prior to updating KVM's metadata caches, so that KVM
+	 *        can safely search the IRR and set irr_pending accordingly.
+	 */
+	apic->irr_pending = true;
+
+	if (apic->apicv_active)
 		apic->isr_count = 1;
-	} else {
-		/*
-		 * Don't clear irr_pending, searching the IRR can race with
-		 * updates from the CPU as APICv is still active from hardware's
-		 * perspective.  The flag will be cleared as appropriate when
-		 * KVM injects the interrupt.
-		 */
+	else
 		apic->isr_count = count_vectors(apic->regs + APIC_ISR);
-	}
+
 	apic->highest_isr_cache = -1;
 }
 
@@ -2726,7 +2771,7 @@
 	if (apic->apicv_active) {
 		static_call_cond(kvm_x86_apicv_post_state_restore)(vcpu);
 		static_call_cond(kvm_x86_hwapic_irr_update)(vcpu, -1);
-		static_call_cond(kvm_x86_hwapic_isr_update)(-1);
+		static_call_cond(kvm_x86_hwapic_isr_update)(vcpu, -1);
 	}
 
 	vcpu->arch.apic_arb_prio = 0;
@@ -2768,7 +2813,8 @@
 		trig_mode = reg & APIC_LVT_LEVEL_TRIGGER;
 
 		r = __apic_accept_irq(apic, mode, vector, 1, trig_mode, NULL);
-		if (r && lvt_type == APIC_LVTPC)
+		if (r && lvt_type == APIC_LVTPC &&
+		    guest_cpuid_is_intel_compatible(apic->vcpu))
 			kvm_lapic_set_reg(apic, APIC_LVTPC, reg | APIC_LVT_MASKED);
 		return r;
 	}
@@ -2929,34 +2975,48 @@
 		struct kvm_lapic_state *s, bool set)
 {
 	if (apic_x2apic_mode(vcpu->arch.apic)) {
+		u32 x2apic_id = kvm_x2apic_id(vcpu->arch.apic);
 		u32 *id = (u32 *)(s->regs + APIC_ID);
 		u32 *ldr = (u32 *)(s->regs + APIC_LDR);
 		u64 icr;
 
 		if (vcpu->kvm->arch.x2apic_format) {
-			if (*id != vcpu->vcpu_id)
+			if (*id != x2apic_id)
 				return -EINVAL;
 		} else {
+			/*
+			 * Ignore the userspace value when setting APIC state.
+			 * KVM's model is that the x2APIC ID is readonly, e.g.
+			 * KVM only supports delivering interrupts to KVM's
+			 * version of the x2APIC ID.  However, for backwards
+			 * compatibility, don't reject attempts to set a
+			 * mismatched ID for userspace that hasn't opted into
+			 * x2apic_format.
+			 */
 			if (set)
-				*id >>= 24;
+				*id = x2apic_id;
 			else
-				*id <<= 24;
+				*id = x2apic_id << 24;
 		}
 
 		/*
 		 * In x2APIC mode, the LDR is fixed and based on the id.  And
-		 * ICR is internally a single 64-bit register, but needs to be
-		 * split to ICR+ICR2 in userspace for backwards compatibility.
+		 * if the ICR is _not_ split, ICR is internally a single 64-bit
+		 * register, but needs to be split to ICR+ICR2 in userspace for
+		 * backwards compatibility.
 		 */
-		if (set) {
-			*ldr = kvm_apic_calc_x2apic_ldr(*id);
+		if (set)
+			*ldr = kvm_apic_calc_x2apic_ldr(x2apic_id);
 
-			icr = __kvm_lapic_get_reg(s->regs, APIC_ICR) |
-			      (u64)__kvm_lapic_get_reg(s->regs, APIC_ICR2) << 32;
-			__kvm_lapic_set_reg64(s->regs, APIC_ICR, icr);
-		} else {
-			icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR);
-			__kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32);
+		if (!kvm_x86_ops.x2apic_icr_is_split) {
+			if (set) {
+				icr = __kvm_lapic_get_reg(s->regs, APIC_ICR) |
+				      (u64)__kvm_lapic_get_reg(s->regs, APIC_ICR2) << 32;
+				__kvm_lapic_set_reg64(s->regs, APIC_ICR, icr);
+			} else {
+				icr = __kvm_lapic_get_reg64(s->regs, APIC_ICR);
+				__kvm_lapic_set_reg(s->regs, APIC_ICR2, icr >> 32);
+			}
 		}
 	}
 
@@ -3011,7 +3071,7 @@
 	if (apic->apicv_active) {
 		static_call_cond(kvm_x86_apicv_post_state_restore)(vcpu);
 		static_call_cond(kvm_x86_hwapic_irr_update)(vcpu, apic_find_highest_irr(apic));
-		static_call_cond(kvm_x86_hwapic_isr_update)(apic_find_highest_isr(apic));
+		static_call_cond(kvm_x86_hwapic_isr_update)(vcpu, apic_find_highest_isr(apic));
 	}
 	kvm_make_request(KVM_REQ_EVENT, vcpu);
 	if (ioapic_in_kernel(vcpu->kvm))
@@ -3148,22 +3208,12 @@
 	return 0;
 }
 
-int kvm_x2apic_icr_write(struct kvm_lapic *apic, u64 data)
-{
-	data &= ~APIC_ICR_BUSY;
-
-	kvm_apic_send_ipi(apic, (u32)data, (u32)(data >> 32));
-	kvm_lapic_set_reg64(apic, APIC_ICR, data);
-	trace_kvm_apic_write(APIC_ICR, data);
-	return 0;
-}
-
 static int kvm_lapic_msr_read(struct kvm_lapic *apic, u32 reg, u64 *data)
 {
 	u32 low;
 
 	if (reg == APIC_ICR) {
-		*data = kvm_lapic_get_reg64(apic, APIC_ICR);
+		*data = kvm_x2apic_icr_read(apic);
 		return 0;
 	}
 
--- linux-qcom-6.8.0.orig/arch/x86/kvm/mmu/mmu.c
+++ linux-qcom-6.8.0/arch/x86/kvm/mmu/mmu.c
@@ -3126,7 +3126,7 @@
 	if (pud_none(pud) || !pud_present(pud))
 		goto out;
 
-	if (pud_large(pud)) {
+	if (pud_leaf(pud)) {
 		level = PG_LEVEL_1G;
 		goto out;
 	}
@@ -4490,6 +4490,7 @@
 
 static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
 {
+	kvm_pfn_t orig_pfn;
 	int r;
 
 	/* Dummy roots are used only for shadowing bad guest roots. */
@@ -4511,6 +4512,8 @@
 	if (r != RET_PF_CONTINUE)
 		return r;
 
+	orig_pfn = fault->pfn;
+
 	r = RET_PF_RETRY;
 	write_lock(&vcpu->kvm->mmu_lock);
 
@@ -4525,7 +4528,7 @@
 
 out_unlock:
 	write_unlock(&vcpu->kvm->mmu_lock);
-	kvm_release_pfn_clean(fault->pfn);
+	kvm_release_pfn_clean(orig_pfn);
 	return r;
 }
 
@@ -4574,6 +4577,7 @@
 static int kvm_tdp_mmu_page_fault(struct kvm_vcpu *vcpu,
 				  struct kvm_page_fault *fault)
 {
+	kvm_pfn_t orig_pfn;
 	int r;
 
 	if (page_fault_handle_page_track(vcpu, fault))
@@ -4591,6 +4595,8 @@
 	if (r != RET_PF_CONTINUE)
 		return r;
 
+	orig_pfn = fault->pfn;
+
 	r = RET_PF_RETRY;
 	read_lock(&vcpu->kvm->mmu_lock);
 
@@ -4601,7 +4607,7 @@
 
 out_unlock:
 	read_unlock(&vcpu->kvm->mmu_lock);
-	kvm_release_pfn_clean(fault->pfn);
+	kvm_release_pfn_clean(orig_pfn);
 	return r;
 }
 #endif
@@ -4922,7 +4928,7 @@
 				context->cpu_role.base.level, is_efer_nx(context),
 				guest_can_use(vcpu, X86_FEATURE_GBPAGES),
 				is_cr4_pse(context),
-				guest_cpuid_is_amd_or_hygon(vcpu));
+				guest_cpuid_is_amd_compatible(vcpu));
 }
 
 static void __reset_rsvds_bits_mask_ept(struct rsvd_bits_validate *rsvd_check,
@@ -6929,6 +6935,19 @@
 	kmem_cache_destroy(mmu_page_header_cache);
 }
 
+static void kvm_wake_nx_recovery_thread(struct kvm *kvm)
+{
+	/*
+	 * The NX recovery thread is spawned on-demand at the first KVM_RUN and
+	 * may not be valid even though the VM is globally visible.  Do nothing,
+	 * as such a VM can't have any possible NX huge pages.
+	 */
+	struct vhost_task *nx_thread = READ_ONCE(kvm->arch.nx_huge_page_recovery_thread);
+
+	if (nx_thread)
+		vhost_task_wake(nx_thread);
+}
+
 static int get_nx_huge_pages(char *buffer, const struct kernel_param *kp)
 {
 	if (nx_hugepage_mitigation_hard_disabled)
@@ -6989,7 +7008,7 @@
 			kvm_mmu_zap_all_fast(kvm);
 			mutex_unlock(&kvm->slots_lock);
 
-			wake_up_process(kvm->arch.nx_huge_page_recovery_thread);
+			kvm_wake_nx_recovery_thread(kvm);
 		}
 		mutex_unlock(&kvm_lock);
 	}
@@ -7137,7 +7156,7 @@
 		mutex_lock(&kvm_lock);
 
 		list_for_each_entry(kvm, &vm_list, vm_list)
-			wake_up_process(kvm->arch.nx_huge_page_recovery_thread);
+			kvm_wake_nx_recovery_thread(kvm);
 
 		mutex_unlock(&kvm_lock);
 	}
@@ -7240,62 +7259,68 @@
 	srcu_read_unlock(&kvm->srcu, rcu_idx);
 }
 
-static long get_nx_huge_page_recovery_timeout(u64 start_time)
+static void kvm_nx_huge_page_recovery_worker_kill(void *data)
+{
+}
+
+static bool kvm_nx_huge_page_recovery_worker(void *data)
 {
+	struct kvm *kvm = data;
 	bool enabled;
 	uint period;
+	long remaining_time;
 
 	enabled = calc_nx_huge_pages_recovery_period(&period);
+	if (!enabled)
+		return false;
 
-	return enabled ? start_time + msecs_to_jiffies(period) - get_jiffies_64()
-		       : MAX_SCHEDULE_TIMEOUT;
+	remaining_time = kvm->arch.nx_huge_page_last + msecs_to_jiffies(period)
+		- get_jiffies_64();
+	if (remaining_time > 0) {
+		schedule_timeout(remaining_time);
+		/* check for signals and come back */
+		return true;
+	}
+
+	__set_current_state(TASK_RUNNING);
+	kvm_recover_nx_huge_pages(kvm);
+	kvm->arch.nx_huge_page_last = get_jiffies_64();
+	return true;
 }
 
-static int kvm_nx_huge_page_recovery_worker(struct kvm *kvm, uintptr_t data)
+static int kvm_mmu_start_lpage_recovery(struct once *once)
 {
-	u64 start_time;
-	long remaining_time;
+	struct kvm_arch *ka = container_of(once, struct kvm_arch, nx_once);
+	struct kvm *kvm = container_of(ka, struct kvm, arch);
+	struct vhost_task *nx_thread;
 
-	while (true) {
-		start_time = get_jiffies_64();
-		remaining_time = get_nx_huge_page_recovery_timeout(start_time);
-
-		set_current_state(TASK_INTERRUPTIBLE);
-		while (!kthread_should_stop() && remaining_time > 0) {
-			schedule_timeout(remaining_time);
-			remaining_time = get_nx_huge_page_recovery_timeout(start_time);
-			set_current_state(TASK_INTERRUPTIBLE);
-		}
+	kvm->arch.nx_huge_page_last = get_jiffies_64();
+	nx_thread = vhost_task_create(kvm_nx_huge_page_recovery_worker,
+				      kvm_nx_huge_page_recovery_worker_kill,
+				      kvm, "kvm-nx-lpage-recovery");
 
-		set_current_state(TASK_RUNNING);
+	if (IS_ERR(nx_thread))
+		return PTR_ERR(nx_thread);
 
-		if (kthread_should_stop())
-			return 0;
+	vhost_task_start(nx_thread);
 
-		kvm_recover_nx_huge_pages(kvm);
-	}
+	/* Make the task visible only once it is fully started. */
+	WRITE_ONCE(kvm->arch.nx_huge_page_recovery_thread, nx_thread);
+	return 0;
 }
 
 int kvm_mmu_post_init_vm(struct kvm *kvm)
 {
-	int err;
-
 	if (nx_hugepage_mitigation_hard_disabled)
 		return 0;
 
-	err = kvm_vm_create_worker_thread(kvm, kvm_nx_huge_page_recovery_worker, 0,
-					  "kvm-nx-lpage-recovery",
-					  &kvm->arch.nx_huge_page_recovery_thread);
-	if (!err)
-		kthread_unpark(kvm->arch.nx_huge_page_recovery_thread);
-
-	return err;
+	return call_once(&kvm->arch.nx_once, kvm_mmu_start_lpage_recovery);
 }
 
 void kvm_mmu_pre_destroy_vm(struct kvm *kvm)
 {
 	if (kvm->arch.nx_huge_page_recovery_thread)
-		kthread_stop(kvm->arch.nx_huge_page_recovery_thread);
+		vhost_task_stop(kvm->arch.nx_huge_page_recovery_thread);
 }
 
 #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
@@ -7388,7 +7413,8 @@
 			 * by the memslot, KVM can't use a hugepage due to the
 			 * misaligned address regardless of memory attributes.
 			 */
-			if (gfn >= slot->base_gfn) {
+			if (gfn >= slot->base_gfn &&
+			    gfn + nr_pages <= slot->base_gfn + slot->npages) {
 				if (hugepage_has_attrs(kvm, slot, gfn, level, attrs))
 					hugepage_clear_mixed(slot, gfn, level);
 				else
--- linux-qcom-6.8.0.orig/arch/x86/kvm/mmu/paging_tmpl.h
+++ linux-qcom-6.8.0/arch/x86/kvm/mmu/paging_tmpl.h
@@ -777,6 +777,7 @@
 static int FNAME(page_fault)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
 {
 	struct guest_walker walker;
+	kvm_pfn_t orig_pfn;
 	int r;
 
 	WARN_ON_ONCE(fault->is_tdp);
@@ -835,6 +836,8 @@
 			walker.pte_access &= ~ACC_EXEC_MASK;
 	}
 
+	orig_pfn = fault->pfn;
+
 	r = RET_PF_RETRY;
 	write_lock(&vcpu->kvm->mmu_lock);
 
@@ -848,7 +851,7 @@
 
 out_unlock:
 	write_unlock(&vcpu->kvm->mmu_lock);
-	kvm_release_pfn_clean(fault->pfn);
+	kvm_release_pfn_clean(orig_pfn);
 	return r;
 }
 
--- linux-qcom-6.8.0.orig/arch/x86/kvm/mmu/spte.c
+++ linux-qcom-6.8.0/arch/x86/kvm/mmu/spte.c
@@ -206,12 +206,20 @@
 		spte |= PT_WRITABLE_MASK | shadow_mmu_writable_mask;
 
 		/*
-		 * Optimization: for pte sync, if spte was writable the hash
-		 * lookup is unnecessary (and expensive). Write protection
-		 * is responsibility of kvm_mmu_get_page / kvm_mmu_sync_roots.
-		 * Same reasoning can be applied to dirty page accounting.
+		 * When overwriting an existing leaf SPTE, and the old SPTE was
+		 * writable, skip trying to unsync shadow pages as any relevant
+		 * shadow pages must already be unsync, i.e. the hash lookup is
+		 * unnecessary (and expensive).
+		 *
+		 * The same reasoning applies to dirty page/folio accounting;
+		 * KVM will mark the folio dirty using the old SPTE, thus
+		 * there's no need to immediately mark the new SPTE as dirty.
+		 *
+		 * Note, both cases rely on KVM not changing PFNs without first
+		 * zapping the old SPTE, which is guaranteed by both the shadow
+		 * MMU and the TDP MMU.
 		 */
-		if (is_writable_pte(old_spte))
+		if (is_last_spte(old_spte, level) && is_writable_pte(old_spte))
 			goto out;
 
 		/*
--- linux-qcom-6.8.0.orig/arch/x86/kvm/mmu/tdp_mmu.c
+++ linux-qcom-6.8.0/arch/x86/kvm/mmu/tdp_mmu.c
@@ -1498,6 +1498,16 @@
 	}
 }
 
+static bool tdp_mmu_need_write_protect(struct kvm_mmu_page *sp)
+{
+	/*
+	 * All TDP MMU shadow pages share the same role as their root, aside
+	 * from level, so it is valid to key off any shadow page to determine if
+	 * write protection is needed for an entire tree.
+	 */
+	return kvm_mmu_page_ad_need_write_protect(sp) || !kvm_ad_enabled();
+}
+
 /*
  * Clear the dirty status of all the SPTEs mapping GFNs in the memslot. If
  * AD bits are enabled, this will involve clearing the dirty bit on each SPTE.
@@ -1508,7 +1518,8 @@
 static bool clear_dirty_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,
 			   gfn_t start, gfn_t end)
 {
-	u64 dbit = kvm_ad_enabled() ? shadow_dirty_mask : PT_WRITABLE_MASK;
+	const u64 dbit = tdp_mmu_need_write_protect(root) ? PT_WRITABLE_MASK :
+							    shadow_dirty_mask;
 	struct tdp_iter iter;
 	bool spte_set = false;
 
@@ -1523,7 +1534,7 @@
 		if (tdp_mmu_iter_cond_resched(kvm, &iter, false, true))
 			continue;
 
-		KVM_MMU_WARN_ON(kvm_ad_enabled() &&
+		KVM_MMU_WARN_ON(dbit == shadow_dirty_mask &&
 				spte_ad_need_write_protect(iter.old_spte));
 
 		if (!(iter.old_spte & dbit))
@@ -1570,8 +1581,8 @@
 static void clear_dirty_pt_masked(struct kvm *kvm, struct kvm_mmu_page *root,
 				  gfn_t gfn, unsigned long mask, bool wrprot)
 {
-	u64 dbit = (wrprot || !kvm_ad_enabled()) ? PT_WRITABLE_MASK :
-						   shadow_dirty_mask;
+	const u64 dbit = (wrprot || tdp_mmu_need_write_protect(root)) ? PT_WRITABLE_MASK :
+									shadow_dirty_mask;
 	struct tdp_iter iter;
 
 	lockdep_assert_held_write(&kvm->mmu_lock);
@@ -1583,7 +1594,7 @@
 		if (!mask)
 			break;
 
-		KVM_MMU_WARN_ON(kvm_ad_enabled() &&
+		KVM_MMU_WARN_ON(dbit == shadow_dirty_mask &&
 				spte_ad_need_write_protect(iter.old_spte));
 
 		if (iter.level > PG_LEVEL_4K ||
--- linux-qcom-6.8.0.orig/arch/x86/kvm/pmu.c
+++ linux-qcom-6.8.0/arch/x86/kvm/pmu.c
@@ -741,6 +741,8 @@
  */
 void kvm_pmu_refresh(struct kvm_vcpu *vcpu)
 {
+	struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+
 	if (KVM_BUG_ON(kvm_vcpu_has_run(vcpu), vcpu->kvm))
 		return;
 
@@ -750,8 +752,34 @@
 	 */
 	kvm_pmu_reset(vcpu);
 
-	bitmap_zero(vcpu_to_pmu(vcpu)->all_valid_pmc_idx, X86_PMC_IDX_MAX);
+	pmu->version = 0;
+	pmu->nr_arch_gp_counters = 0;
+	pmu->nr_arch_fixed_counters = 0;
+	pmu->counter_bitmask[KVM_PMC_GP] = 0;
+	pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
+	pmu->reserved_bits = 0xffffffff00200000ull;
+	pmu->raw_event_mask = X86_RAW_EVENT_MASK;
+	pmu->global_ctrl_mask = ~0ull;
+	pmu->global_status_mask = ~0ull;
+	pmu->fixed_ctr_ctrl_mask = ~0ull;
+	pmu->pebs_enable_mask = ~0ull;
+	pmu->pebs_data_cfg_mask = ~0ull;
+	bitmap_zero(pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX);
+
+	if (!vcpu->kvm->arch.enable_pmu)
+		return;
+
 	static_call(kvm_x86_pmu_refresh)(vcpu);
+
+	/*
+	 * At RESET, both Intel and AMD CPUs set all enable bits for general
+	 * purpose counters in IA32_PERF_GLOBAL_CTRL (so that software that
+	 * was written for v1 PMUs don't unknowingly leave GP counters disabled
+	 * in the global controls).  Emulate that behavior when refreshing the
+	 * PMU so that userspace doesn't need to manually set PERF_GLOBAL_CTRL.
+	 */
+	if (kvm_pmu_has_perf_global_ctrl(pmu) && pmu->nr_arch_gp_counters)
+		pmu->global_ctrl = GENMASK_ULL(pmu->nr_arch_gp_counters - 1, 0);
 }
 
 void kvm_pmu_init(struct kvm_vcpu *vcpu)
--- linux-qcom-6.8.0.orig/arch/x86/kvm/reverse_cpuid.h
+++ linux-qcom-6.8.0/arch/x86/kvm/reverse_cpuid.h
@@ -52,7 +52,7 @@
 #define X86_FEATURE_IPRED_CTRL		KVM_X86_FEATURE(CPUID_7_2_EDX, 1)
 #define KVM_X86_FEATURE_RRSBA_CTRL	KVM_X86_FEATURE(CPUID_7_2_EDX, 2)
 #define X86_FEATURE_DDPD_U		KVM_X86_FEATURE(CPUID_7_2_EDX, 3)
-#define X86_FEATURE_BHI_CTRL		KVM_X86_FEATURE(CPUID_7_2_EDX, 4)
+#define KVM_X86_FEATURE_BHI_CTRL	KVM_X86_FEATURE(CPUID_7_2_EDX, 4)
 #define X86_FEATURE_MCDT_NO		KVM_X86_FEATURE(CPUID_7_2_EDX, 5)
 
 /* CPUID level 0x80000007 (EDX). */
@@ -102,10 +102,12 @@
  */
 static __always_inline void reverse_cpuid_check(unsigned int x86_leaf)
 {
+	BUILD_BUG_ON(NR_CPUID_WORDS != NCAPINTS);
 	BUILD_BUG_ON(x86_leaf == CPUID_LNX_1);
 	BUILD_BUG_ON(x86_leaf == CPUID_LNX_2);
 	BUILD_BUG_ON(x86_leaf == CPUID_LNX_3);
 	BUILD_BUG_ON(x86_leaf == CPUID_LNX_4);
+	BUILD_BUG_ON(x86_leaf == CPUID_LNX_5);
 	BUILD_BUG_ON(x86_leaf >= ARRAY_SIZE(reverse_cpuid));
 	BUILD_BUG_ON(reverse_cpuid[x86_leaf].function == 0);
 }
@@ -126,6 +128,7 @@
 	KVM_X86_TRANSLATE_FEATURE(CONSTANT_TSC);
 	KVM_X86_TRANSLATE_FEATURE(PERFMON_V2);
 	KVM_X86_TRANSLATE_FEATURE(RRSBA_CTRL);
+	KVM_X86_TRANSLATE_FEATURE(BHI_CTRL);
 	default:
 		return x86_feature;
 	}
--- linux-qcom-6.8.0.orig/arch/x86/kvm/svm/nested.c
+++ linux-qcom-6.8.0/arch/x86/kvm/svm/nested.c
@@ -63,8 +63,12 @@
 	u64 pdpte;
 	int ret;
 
+	/*
+	 * Note, nCR3 is "assumed" to be 32-byte aligned, i.e. the CPU ignores
+	 * nCR3[4:0] when loading PDPTEs from memory.
+	 */
 	ret = kvm_vcpu_read_guest_page(vcpu, gpa_to_gfn(cr3), &pdpte,
-				       offset_in_page(cr3) + index * 8, 8);
+				       (cr3 & GENMASK(11, 5)) + index * 8, 8);
 	if (ret)
 		return 0;
 	return pdpte;
--- linux-qcom-6.8.0.orig/arch/x86/kvm/svm/sev.c
+++ linux-qcom-6.8.0/arch/x86/kvm/svm/sev.c
@@ -84,9 +84,10 @@
 };
 
 /* Called with the sev_bitmap_lock held, or on shutdown  */
-static int sev_flush_asids(int min_asid, int max_asid)
+static int sev_flush_asids(unsigned int min_asid, unsigned int max_asid)
 {
-	int ret, asid, error = 0;
+	int ret, error = 0;
+	unsigned int asid;
 
 	/* Check if there are any ASIDs to reclaim before performing a flush */
 	asid = find_next_bit(sev_reclaim_asid_bitmap, nr_asids, min_asid);
@@ -116,7 +117,7 @@
 }
 
 /* Must be called with the sev_bitmap_lock held */
-static bool __sev_recycle_asids(int min_asid, int max_asid)
+static bool __sev_recycle_asids(unsigned int min_asid, unsigned int max_asid)
 {
 	if (sev_flush_asids(min_asid, max_asid))
 		return false;
@@ -143,8 +144,20 @@
 
 static int sev_asid_new(struct kvm_sev_info *sev)
 {
-	int asid, min_asid, max_asid, ret;
+	/*
+	 * SEV-enabled guests must use asid from min_sev_asid to max_sev_asid.
+	 * SEV-ES-enabled guest can use from 1 to min_sev_asid - 1.
+	 * Note: min ASID can end up larger than the max if basic SEV support is
+	 * effectively disabled by disallowing use of ASIDs for SEV guests.
+	 */
+	unsigned int min_asid = sev->es_active ? 1 : min_sev_asid;
+	unsigned int max_asid = sev->es_active ? min_sev_asid - 1 : max_sev_asid;
+	unsigned int asid;
 	bool retry = true;
+	int ret;
+
+	if (min_asid > max_asid)
+		return -ENOTTY;
 
 	WARN_ON(sev->misc_cg);
 	sev->misc_cg = get_current_misc_cg();
@@ -157,12 +170,6 @@
 
 	mutex_lock(&sev_bitmap_lock);
 
-	/*
-	 * SEV-enabled guests must use asid from min_sev_asid to max_sev_asid.
-	 * SEV-ES-enabled guest can use from 1 to min_sev_asid - 1.
-	 */
-	min_asid = sev->es_active ? 1 : min_sev_asid;
-	max_asid = sev->es_active ? min_sev_asid - 1 : max_sev_asid;
 again:
 	asid = find_next_zero_bit(sev_asid_bitmap, max_asid + 1, min_asid);
 	if (asid > max_asid) {
@@ -187,7 +194,7 @@
 	return ret;
 }
 
-static int sev_get_asid(struct kvm *kvm)
+static unsigned int sev_get_asid(struct kvm *kvm)
 {
 	struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info;
 
@@ -284,8 +291,8 @@
 
 static int sev_bind_asid(struct kvm *kvm, unsigned int handle, int *error)
 {
+	unsigned int asid = sev_get_asid(kvm);
 	struct sev_data_activate activate;
-	int asid = sev_get_asid(kvm);
 	int ret;
 
 	/* activate ASID on the given handle */
@@ -657,6 +664,14 @@
 	  return ret;
 
 	vcpu->arch.guest_state_protected = true;
+
+	/*
+	 * SEV-ES guest mandates LBR Virtualization to be _always_ ON. Enable it
+	 * only after setting guest_state_protected because KVM_SET_MSRS allows
+	 * dynamic toggling of LBRV (for performance reason) on write access to
+	 * MSR_IA32_DEBUGCTLMSR when guest_state_protected is not set.
+	 */
+	svm_enable_lbrv(vcpu);
 	return 0;
 }
 
@@ -2237,8 +2252,10 @@
 		goto out;
 	}
 
-	sev_asid_count = max_sev_asid - min_sev_asid + 1;
-	WARN_ON_ONCE(misc_cg_set_capacity(MISC_CG_RES_SEV, sev_asid_count));
+	if (min_sev_asid <= max_sev_asid) {
+		sev_asid_count = max_sev_asid - min_sev_asid + 1;
+		WARN_ON_ONCE(misc_cg_set_capacity(MISC_CG_RES_SEV, sev_asid_count));
+	}
 	sev_supported = true;
 
 	/* SEV-ES support requested? */
@@ -2258,6 +2275,12 @@
 	if (!boot_cpu_has(X86_FEATURE_SEV_ES))
 		goto out;
 
+	if (!lbrv) {
+		WARN_ONCE(!boot_cpu_has(X86_FEATURE_LBRV),
+			  "LBRV must be present for SEV-ES support");
+		goto out;
+	}
+
 	/* Has the system been allocated ASIDs for SEV-ES? */
 	if (min_sev_asid == 1)
 		goto out;
@@ -2269,7 +2292,9 @@
 out:
 	if (boot_cpu_has(X86_FEATURE_SEV))
 		pr_info("SEV %s (ASIDs %u - %u)\n",
-			sev_supported ? "enabled" : "disabled",
+			sev_supported ? min_sev_asid <= max_sev_asid ? "enabled" :
+								       "unusable" :
+								       "disabled",
 			min_sev_asid, max_sev_asid);
 	if (boot_cpu_has(X86_FEATURE_SEV_ES))
 		pr_info("SEV-ES %s (ASIDs %u - %u)\n",
@@ -2317,7 +2342,7 @@
  */
 static void sev_flush_encrypted_page(struct kvm_vcpu *vcpu, void *va)
 {
-	int asid = to_kvm_svm(vcpu->kvm)->sev_info.asid;
+	unsigned int asid = sev_get_asid(vcpu->kvm);
 
 	/*
 	 * Note!  The address must be a kernel address, as regular page walk
@@ -2635,7 +2660,7 @@
 void pre_sev_run(struct vcpu_svm *svm, int cpu)
 {
 	struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
-	int asid = sev_get_asid(svm->vcpu.kvm);
+	unsigned int asid = sev_get_asid(svm->vcpu.kvm);
 
 	/* Assign the asid allocated with this SEV guest */
 	svm->asid = asid;
@@ -3021,7 +3046,6 @@
 	struct kvm_vcpu *vcpu = &svm->vcpu;
 
 	svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ES_ENABLE;
-	svm->vmcb->control.virt_ext |= LBR_CTL_ENABLE_MASK;
 
 	/*
 	 * An SEV-ES guest requires a VMSA area that is a separate from the
@@ -3073,10 +3097,6 @@
 	/* Clear intercepts on selected MSRs */
 	set_msr_interception(vcpu, svm->msrpm, MSR_EFER, 1, 1);
 	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_CR_PAT, 1, 1);
-	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, 1, 1);
-	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1);
-	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1);
-	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1);
 }
 
 void sev_init_vmcb(struct vcpu_svm *svm)
--- linux-qcom-6.8.0.orig/arch/x86/kvm/svm/svm.c
+++ linux-qcom-6.8.0/arch/x86/kvm/svm/svm.c
@@ -99,6 +99,7 @@
 	{ .index = MSR_IA32_SPEC_CTRL,			.always = false },
 	{ .index = MSR_IA32_PRED_CMD,			.always = false },
 	{ .index = MSR_IA32_FLUSH_CMD,			.always = false },
+	{ .index = MSR_IA32_DEBUGCTLMSR,		.always = false },
 	{ .index = MSR_IA32_LASTBRANCHFROMIP,		.always = false },
 	{ .index = MSR_IA32_LASTBRANCHTOIP,		.always = false },
 	{ .index = MSR_IA32_LASTINTFROMIP,		.always = false },
@@ -215,7 +216,7 @@
 module_param(vgif, int, 0444);
 
 /* enable/disable LBR virtualization */
-static int lbrv = true;
+int lbrv = true;
 module_param(lbrv, int, 0444);
 
 static int tsc_scaling = true;
@@ -990,7 +991,7 @@
 	vmcb_mark_dirty(to_vmcb, VMCB_LBR);
 }
 
-static void svm_enable_lbrv(struct kvm_vcpu *vcpu)
+void svm_enable_lbrv(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
@@ -1000,6 +1001,9 @@
 	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1);
 	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1);
 
+	if (sev_es_guest(vcpu->kvm))
+		set_msr_interception(vcpu, svm->msrpm, MSR_IA32_DEBUGCTLMSR, 1, 1);
+
 	/* Move the LBR msrs to the vmcb02 so that the guest can see them. */
 	if (is_guest_mode(vcpu))
 		svm_copy_lbrs(svm->vmcb, svm->vmcb01.ptr);
@@ -1009,6 +1013,8 @@
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
+	KVM_BUG_ON(sev_es_guest(vcpu->kvm), vcpu->kvm);
+
 	svm->vmcb->control.virt_ext &= ~LBR_CTL_ENABLE_MASK;
 	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHFROMIP, 0, 0);
 	set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 0, 0);
@@ -2844,6 +2850,12 @@
 	case MSR_CSTAR:
 		msr_info->data = svm->vmcb01.ptr->save.cstar;
 		break;
+	case MSR_GS_BASE:
+		msr_info->data = svm->vmcb01.ptr->save.gs.base;
+		break;
+	case MSR_FS_BASE:
+		msr_info->data = svm->vmcb01.ptr->save.fs.base;
+		break;
 	case MSR_KERNEL_GS_BASE:
 		msr_info->data = svm->vmcb01.ptr->save.kernel_gs_base;
 		break;
@@ -3065,6 +3077,12 @@
 	case MSR_CSTAR:
 		svm->vmcb01.ptr->save.cstar = data;
 		break;
+	case MSR_GS_BASE:
+		svm->vmcb01.ptr->save.gs.base = data;
+		break;
+	case MSR_FS_BASE:
+		svm->vmcb01.ptr->save.fs.base = data;
+		break;
 	case MSR_KERNEL_GS_BASE:
 		svm->vmcb01.ptr->save.kernel_gs_base = data;
 		break;
@@ -3845,16 +3863,27 @@
 	struct vcpu_svm *svm = to_svm(vcpu);
 
 	/*
-	 * KVM should never request an NMI window when vNMI is enabled, as KVM
-	 * allows at most one to-be-injected NMI and one pending NMI, i.e. if
-	 * two NMIs arrive simultaneously, KVM will inject one and set
-	 * V_NMI_PENDING for the other.  WARN, but continue with the standard
-	 * single-step approach to try and salvage the pending NMI.
+	 * If NMIs are outright masked, i.e. the vCPU is already handling an
+	 * NMI, and KVM has not yet intercepted an IRET, then there is nothing
+	 * more to do at this time as KVM has already enabled IRET intercepts.
+	 * If KVM has already intercepted IRET, then single-step over the IRET,
+	 * as NMIs aren't architecturally unmasked until the IRET completes.
+	 *
+	 * If vNMI is enabled, KVM should never request an NMI window if NMIs
+	 * are masked, as KVM allows at most one to-be-injected NMI and one
+	 * pending NMI.  If two NMIs arrive simultaneously, KVM will inject one
+	 * NMI and set V_NMI_PENDING for the other, but if and only if NMIs are
+	 * unmasked.  KVM _will_ request an NMI window in some situations, e.g.
+	 * if the vCPU is in an STI shadow or if GIF=0, KVM can't immediately
+	 * inject the NMI.  In those situations, KVM needs to single-step over
+	 * the STI shadow or intercept STGI.
 	 */
-	WARN_ON_ONCE(is_vnmi_enabled(svm));
+	if (svm_get_nmi_mask(vcpu)) {
+		WARN_ON_ONCE(is_vnmi_enabled(svm));
 
-	if (svm_get_nmi_mask(vcpu) && !svm->awaiting_iret_completion)
-		return; /* IRET will cause a vm exit */
+		if (!svm->awaiting_iret_completion)
+			return; /* IRET will cause a vm exit */
+	}
 
 	/*
 	 * SEV-ES guests are responsible for signaling when a vCPU is ready to
@@ -4976,6 +5005,8 @@
 	.enable_nmi_window = svm_enable_nmi_window,
 	.enable_irq_window = svm_enable_irq_window,
 	.update_cr8_intercept = svm_update_cr8_intercept,
+
+	.x2apic_icr_is_split = true,
 	.set_virtual_apic_mode = avic_refresh_virtual_apic_mode,
 	.refresh_apicv_exec_ctrl = avic_refresh_apicv_exec_ctrl,
 	.apicv_post_state_restore = avic_apicv_post_state_restore,
@@ -5147,6 +5178,9 @@
 
 	/* CPUID 0x8000001F (SME/SEV features) */
 	sev_set_cpu_caps();
+
+	/* Don't advertise Bus Lock Detect to guest if SVM support is absent */
+	kvm_cpu_cap_clear(X86_FEATURE_BUS_LOCK_DETECT);
 }
 
 static __init int svm_hardware_setup(void)
@@ -5236,6 +5270,12 @@
 
 	nrips = nrips && boot_cpu_has(X86_FEATURE_NRIPS);
 
+	if (lbrv) {
+		if (!boot_cpu_has(X86_FEATURE_LBRV))
+			lbrv = false;
+		else
+			pr_info("LBR virtualization supported\n");
+	}
 	/*
 	 * Note, SEV setup consumes npt_enabled and enable_mmio_caching (which
 	 * may be modified by svm_adjust_mmio_mask()), as well as nrips.
@@ -5289,14 +5329,6 @@
 		svm_x86_ops.set_vnmi_pending = NULL;
 	}
 
-
-	if (lbrv) {
-		if (!boot_cpu_has(X86_FEATURE_LBRV))
-			lbrv = false;
-		else
-			pr_info("LBR virtualization supported\n");
-	}
-
 	if (!enable_pmu)
 		pr_info("PMU virtualization is disabled\n");
 
--- linux-qcom-6.8.0.orig/arch/x86/kvm/svm/svm.h
+++ linux-qcom-6.8.0/arch/x86/kvm/svm/svm.h
@@ -30,7 +30,7 @@
 #define	IOPM_SIZE PAGE_SIZE * 3
 #define	MSRPM_SIZE PAGE_SIZE * 2
 
-#define MAX_DIRECT_ACCESS_MSRS	47
+#define MAX_DIRECT_ACCESS_MSRS	48
 #define MSRPM_OFFSETS	32
 extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly;
 extern bool npt_enabled;
@@ -39,6 +39,7 @@
 extern bool intercept_smi;
 extern bool x2avic_enabled;
 extern bool vnmi;
+extern int lbrv;
 
 /*
  * Clean bits in VMCB.
@@ -543,6 +544,7 @@
 void svm_vcpu_init_msrpm(struct kvm_vcpu *vcpu, u32 *msrpm);
 void svm_vcpu_free_msrpm(u32 *msrpm);
 void svm_copy_lbrs(struct vmcb *to_vmcb, struct vmcb *from_vmcb);
+void svm_enable_lbrv(struct kvm_vcpu *vcpu);
 void svm_update_lbrv(struct kvm_vcpu *vcpu);
 
 int svm_set_efer(struct kvm_vcpu *vcpu, u64 efer);
--- linux-qcom-6.8.0.orig/arch/x86/kvm/trace.h
+++ linux-qcom-6.8.0/arch/x86/kvm/trace.h
@@ -732,13 +732,13 @@
  * Tracepoint for nested #vmexit because of interrupt pending
  */
 TRACE_EVENT(kvm_invlpga,
-	    TP_PROTO(__u64 rip, int asid, u64 address),
+	    TP_PROTO(__u64 rip, unsigned int asid, u64 address),
 	    TP_ARGS(rip, asid, address),
 
 	TP_STRUCT__entry(
-		__field(	__u64,	rip	)
-		__field(	int,	asid	)
-		__field(	__u64,	address	)
+		__field(	__u64,		rip	)
+		__field(	unsigned int,	asid	)
+		__field(	__u64,		address	)
 	),
 
 	TP_fast_assign(
@@ -747,7 +747,7 @@
 		__entry->address	=	address;
 	),
 
-	TP_printk("rip: 0x%016llx asid: %d address: 0x%016llx",
+	TP_printk("rip: 0x%016llx asid: %u address: 0x%016llx",
 		  __entry->rip, __entry->asid, __entry->address)
 );
 
--- linux-qcom-6.8.0.orig/arch/x86/kvm/vmx/nested.c
+++ linux-qcom-6.8.0/arch/x86/kvm/vmx/nested.c
@@ -12,6 +12,7 @@
 #include "mmu.h"
 #include "nested.h"
 #include "pmu.h"
+#include "posted_intr.h"
 #include "sgx.h"
 #include "trace.h"
 #include "vmx.h"
@@ -1174,11 +1175,14 @@
 	kvm_hv_nested_transtion_tlb_flush(vcpu, enable_ept);
 
 	/*
-	 * If vmcs12 doesn't use VPID, L1 expects linear and combined mappings
-	 * for *all* contexts to be flushed on VM-Enter/VM-Exit, i.e. it's a
-	 * full TLB flush from the guest's perspective.  This is required even
-	 * if VPID is disabled in the host as KVM may need to synchronize the
-	 * MMU in response to the guest TLB flush.
+	 * If VPID is disabled, then guest TLB accesses use VPID=0, i.e. the
+	 * same VPID as the host, and so architecturally, linear and combined
+	 * mappings for VPID=0 must be flushed at VM-Enter and VM-Exit.  KVM
+	 * emulates L2 sharing L1's VPID=0 by using vpid01 while running L2,
+	 * and so KVM must also emulate TLB flush of VPID=0, i.e. vpid01.  This
+	 * is required if VPID is disabled in KVM, as a TLB flush (there are no
+	 * VPIDs) still occurs from L1's perspective, and KVM may need to
+	 * synchronize the MMU in response to the guest TLB flush.
 	 *
 	 * Note, using TLB_FLUSH_GUEST is correct even if nested EPT is in use.
 	 * EPT is a special snowflake, as guest-physical mappings aren't
@@ -2265,6 +2269,17 @@
 
 	vmcs_write64(VMCS_LINK_POINTER, INVALID_GPA);
 
+	/*
+	 * If VPID is disabled, then guest TLB accesses use VPID=0, i.e. the
+	 * same VPID as the host.  Emulate this behavior by using vpid01 for L2
+	 * if VPID is disabled in vmcs12.  Note, if VPID is disabled, VM-Enter
+	 * and VM-Exit are architecturally required to flush VPID=0, but *only*
+	 * VPID=0.  I.e. using vpid02 would be ok (so long as KVM emulates the
+	 * required flushes), but doing so would cause KVM to over-flush.  E.g.
+	 * if L1 runs L2 X with VPID12=1, then runs L2 Y with VPID12 disabled,
+	 * and then runs L2 X again, then KVM can and should retain TLB entries
+	 * for VPID12=1.
+	 */
 	if (enable_vpid) {
 		if (nested_cpu_has_vpid(vmcs12) && vmx->nested.vpid02)
 			vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->nested.vpid02);
@@ -3874,8 +3889,8 @@
 	if (!pi_test_and_clear_on(vmx->nested.pi_desc))
 		return 0;
 
-	max_irr = find_last_bit((unsigned long *)vmx->nested.pi_desc->pir, 256);
-	if (max_irr != 256) {
+	max_irr = pi_find_highest_vector(vmx->nested.pi_desc);
+	if (max_irr > 0) {
 		vapic_page = vmx->nested.virtual_apic_map.hva;
 		if (!vapic_page)
 			goto mmio_needed;
@@ -4006,10 +4021,42 @@
 	       to_vmx(vcpu)->nested.preemption_timer_expired;
 }
 
-static bool vmx_has_nested_events(struct kvm_vcpu *vcpu)
+static bool vmx_has_nested_events(struct kvm_vcpu *vcpu, bool for_injection)
 {
-	return nested_vmx_preemption_timer_pending(vcpu) ||
-	       to_vmx(vcpu)->nested.mtf_pending;
+	struct vcpu_vmx *vmx = to_vmx(vcpu);
+	void *vapic = vmx->nested.virtual_apic_map.hva;
+	int max_irr, vppr;
+
+	if (nested_vmx_preemption_timer_pending(vcpu) ||
+	    vmx->nested.mtf_pending)
+		return true;
+
+	/*
+	 * Virtual Interrupt Delivery doesn't require manual injection.  Either
+	 * the interrupt is already in GUEST_RVI and will be recognized by CPU
+	 * at VM-Entry, or there is a KVM_REQ_EVENT pending and KVM will move
+	 * the interrupt from the PIR to RVI prior to entering the guest.
+	 */
+	if (for_injection)
+		return false;
+
+	if (!nested_cpu_has_vid(get_vmcs12(vcpu)) ||
+	    __vmx_interrupt_blocked(vcpu))
+		return false;
+
+	if (!vapic)
+		return false;
+
+	vppr = *((u32 *)(vapic + APIC_PROCPRI));
+
+	if (vmx->nested.pi_pending && vmx->nested.pi_desc &&
+	    pi_test_on(vmx->nested.pi_desc)) {
+		max_irr = pi_find_highest_vector(vmx->nested.pi_desc);
+		if (max_irr > 0 && (max_irr & 0xf0) > (vppr & 0xf0))
+			return true;
+	}
+
+	return false;
 }
 
 /*
@@ -5828,6 +5875,12 @@
 		return nested_vmx_fail(vcpu,
 			VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
 
+	/*
+	 * Always flush the effective vpid02, i.e. never flush the current VPID
+	 * and never explicitly flush vpid01.  INVVPID targets a VPID, not a
+	 * VMCS, and so whether or not the current vmcs12 has VPID enabled is
+	 * irrelevant (and there may not be a loaded vmcs12).
+	 */
 	vpid02 = nested_get_vpid02(vcpu);
 	switch (type) {
 	case VMX_VPID_EXTENT_INDIVIDUAL_ADDR:
--- linux-qcom-6.8.0.orig/arch/x86/kvm/vmx/pmu_intel.c
+++ linux-qcom-6.8.0/arch/x86/kvm/vmx/pmu_intel.c
@@ -491,19 +491,6 @@
 	u64 counter_mask;
 	int i;
 
-	pmu->nr_arch_gp_counters = 0;
-	pmu->nr_arch_fixed_counters = 0;
-	pmu->counter_bitmask[KVM_PMC_GP] = 0;
-	pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
-	pmu->version = 0;
-	pmu->reserved_bits = 0xffffffff00200000ull;
-	pmu->raw_event_mask = X86_RAW_EVENT_MASK;
-	pmu->global_ctrl_mask = ~0ull;
-	pmu->global_status_mask = ~0ull;
-	pmu->fixed_ctr_ctrl_mask = ~0ull;
-	pmu->pebs_enable_mask = ~0ull;
-	pmu->pebs_data_cfg_mask = ~0ull;
-
 	memset(&lbr_desc->records, 0, sizeof(lbr_desc->records));
 
 	/*
@@ -515,8 +502,9 @@
 		return;
 
 	entry = kvm_find_cpuid_entry(vcpu, 0xa);
-	if (!entry || !vcpu->kvm->arch.enable_pmu)
+	if (!entry)
 		return;
+
 	eax.full = entry->eax;
 	edx.full = entry->edx;
 
--- linux-qcom-6.8.0.orig/arch/x86/kvm/vmx/posted_intr.h
+++ linux-qcom-6.8.0/arch/x86/kvm/vmx/posted_intr.h
@@ -2,97 +2,8 @@
 #ifndef __KVM_X86_VMX_POSTED_INTR_H
 #define __KVM_X86_VMX_POSTED_INTR_H
 
-#define POSTED_INTR_ON  0
-#define POSTED_INTR_SN  1
-
-#define PID_TABLE_ENTRY_VALID 1
-
-/* Posted-Interrupt Descriptor */
-struct pi_desc {
-	u32 pir[8];     /* Posted interrupt requested */
-	union {
-		struct {
-				/* bit 256 - Outstanding Notification */
-			u16	on	: 1,
-				/* bit 257 - Suppress Notification */
-				sn	: 1,
-				/* bit 271:258 - Reserved */
-				rsvd_1	: 14;
-				/* bit 279:272 - Notification Vector */
-			u8	nv;
-				/* bit 287:280 - Reserved */
-			u8	rsvd_2;
-				/* bit 319:288 - Notification Destination */
-			u32	ndst;
-		};
-		u64 control;
-	};
-	u32 rsvd[6];
-} __aligned(64);
-
-static inline bool pi_test_and_set_on(struct pi_desc *pi_desc)
-{
-	return test_and_set_bit(POSTED_INTR_ON,
-			(unsigned long *)&pi_desc->control);
-}
-
-static inline bool pi_test_and_clear_on(struct pi_desc *pi_desc)
-{
-	return test_and_clear_bit(POSTED_INTR_ON,
-			(unsigned long *)&pi_desc->control);
-}
-
-static inline bool pi_test_and_clear_sn(struct pi_desc *pi_desc)
-{
-	return test_and_clear_bit(POSTED_INTR_SN,
-			(unsigned long *)&pi_desc->control);
-}
-
-static inline bool pi_test_and_set_pir(int vector, struct pi_desc *pi_desc)
-{
-	return test_and_set_bit(vector, (unsigned long *)pi_desc->pir);
-}
-
-static inline bool pi_is_pir_empty(struct pi_desc *pi_desc)
-{
-	return bitmap_empty((unsigned long *)pi_desc->pir, NR_VECTORS);
-}
-
-static inline void pi_set_sn(struct pi_desc *pi_desc)
-{
-	set_bit(POSTED_INTR_SN,
-		(unsigned long *)&pi_desc->control);
-}
-
-static inline void pi_set_on(struct pi_desc *pi_desc)
-{
-	set_bit(POSTED_INTR_ON,
-		(unsigned long *)&pi_desc->control);
-}
-
-static inline void pi_clear_on(struct pi_desc *pi_desc)
-{
-	clear_bit(POSTED_INTR_ON,
-		(unsigned long *)&pi_desc->control);
-}
-
-static inline void pi_clear_sn(struct pi_desc *pi_desc)
-{
-	clear_bit(POSTED_INTR_SN,
-		(unsigned long *)&pi_desc->control);
-}
-
-static inline bool pi_test_on(struct pi_desc *pi_desc)
-{
-	return test_bit(POSTED_INTR_ON,
-			(unsigned long *)&pi_desc->control);
-}
-
-static inline bool pi_test_sn(struct pi_desc *pi_desc)
-{
-	return test_bit(POSTED_INTR_SN,
-			(unsigned long *)&pi_desc->control);
-}
+#include <linux/find.h>
+#include <asm/posted_intr.h>
 
 void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu);
 void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu);
@@ -103,4 +14,12 @@
 		       uint32_t guest_irq, bool set);
 void vmx_pi_start_assignment(struct kvm *kvm);
 
+static inline int pi_find_highest_vector(struct pi_desc *pi_desc)
+{
+	int vec;
+
+	vec = find_last_bit((unsigned long *)pi_desc->pir, 256);
+	return vec < 256 ? vec : -1;
+}
+
 #endif /* __KVM_X86_VMX_POSTED_INTR_H */
--- linux-qcom-6.8.0.orig/arch/x86/kvm/vmx/vmenter.S
+++ linux-qcom-6.8.0/arch/x86/kvm/vmx/vmenter.S
@@ -275,6 +275,8 @@
 
 	call vmx_spec_ctrl_restore_host
 
+	CLEAR_BRANCH_HISTORY_VMEXIT
+
 	/* Put return value in AX */
 	mov %_ASM_BX, %_ASM_AX
 
--- linux-qcom-6.8.0.orig/arch/x86/kvm/vmx/vmx.c
+++ linux-qcom-6.8.0/arch/x86/kvm/vmx/vmx.c
@@ -67,6 +67,7 @@
 #include "x86.h"
 #include "smm.h"
 #include "vmx_onhyperv.h"
+#include "posted_intr.h"
 
 MODULE_AUTHOR("Qumranet");
 MODULE_LICENSE("GPL");
@@ -211,9 +212,11 @@
 static unsigned int ple_window_max        = KVM_VMX_DEFAULT_PLE_WINDOW_MAX;
 module_param(ple_window_max, uint, 0444);
 
-/* Default is SYSTEM mode, 1 for host-guest mode */
+/* Default is SYSTEM mode, 1 for host-guest mode (which is BROKEN) */
 int __read_mostly pt_mode = PT_MODE_SYSTEM;
+#ifdef CONFIG_BROKEN
 module_param(pt_mode, int, S_IRUGO);
+#endif
 
 static DEFINE_STATIC_KEY_FALSE(vmx_l1d_should_flush);
 static DEFINE_STATIC_KEY_FALSE(vmx_l1d_flush_cond);
@@ -2518,30 +2521,6 @@
 	return cpuid_eax(0) >= 0x12 && (cpuid_eax(0x12) & BIT(0));
 }
 
-/*
- * Some cpus support VM_{ENTRY,EXIT}_IA32_PERF_GLOBAL_CTRL but they
- * can't be used due to errata where VM Exit may incorrectly clear
- * IA32_PERF_GLOBAL_CTRL[34:32]. Work around the errata by using the
- * MSR load mechanism to switch IA32_PERF_GLOBAL_CTRL.
- */
-static bool cpu_has_perf_global_ctrl_bug(void)
-{
-	if (boot_cpu_data.x86 == 0x6) {
-		switch (boot_cpu_data.x86_model) {
-		case INTEL_FAM6_NEHALEM_EP:	/* AAK155 */
-		case INTEL_FAM6_NEHALEM:	/* AAP115 */
-		case INTEL_FAM6_WESTMERE:	/* AAT100 */
-		case INTEL_FAM6_WESTMERE_EP:	/* BC86,AAY89,BD102 */
-		case INTEL_FAM6_NEHALEM_EX:	/* BA97 */
-			return true;
-		default:
-			break;
-		}
-	}
-
-	return false;
-}
-
 static int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, u32 msr, u32 *result)
 {
 	u32 vmx_msr_low, vmx_msr_high;
@@ -2697,6 +2676,27 @@
 		_vmexit_control &= ~x_ctrl;
 	}
 
+	/*
+	 * Some cpus support VM_{ENTRY,EXIT}_IA32_PERF_GLOBAL_CTRL but they
+	 * can't be used due to an errata where VM Exit may incorrectly clear
+	 * IA32_PERF_GLOBAL_CTRL[34:32].  Workaround the errata by using the
+	 * MSR load mechanism to switch IA32_PERF_GLOBAL_CTRL.
+	 */
+	switch (boot_cpu_data.x86_vfm) {
+	case INTEL_NEHALEM_EP:	/* AAK155 */
+	case INTEL_NEHALEM:	/* AAP115 */
+	case INTEL_WESTMERE:	/* AAT100 */
+	case INTEL_WESTMERE_EP:	/* BC86,AAY89,BD102 */
+	case INTEL_NEHALEM_EX:	/* BA97 */
+		_vmentry_control &= ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL;
+		_vmexit_control &= ~VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL;
+		pr_warn_once("VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL "
+			     "does not work properly. Using workaround\n");
+		break;
+	default:
+		break;
+	}
+
 	rdmsr(MSR_IA32_VMX_BASIC, vmx_msr_low, vmx_msr_high);
 
 	/* IA-32 SDM Vol 3B: VMCS size is never greater than 4kB. */
@@ -3186,7 +3186,7 @@
 
 static inline int vmx_get_current_vpid(struct kvm_vcpu *vcpu)
 {
-	if (is_guest_mode(vcpu))
+	if (is_guest_mode(vcpu) && nested_cpu_has_vpid(get_vmcs12(vcpu)))
 		return nested_get_vpid02(vcpu);
 	return to_vmx(vcpu)->vpid;
 }
@@ -4406,9 +4406,6 @@
 			  VM_ENTRY_LOAD_IA32_EFER |
 			  VM_ENTRY_IA32E_MODE);
 
-	if (cpu_has_perf_global_ctrl_bug())
-		vmentry_ctrl &= ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL;
-
 	return vmentry_ctrl;
 }
 
@@ -4426,10 +4423,6 @@
 	if (vmx_pt_mode_is_system())
 		vmexit_ctrl &= ~(VM_EXIT_PT_CONCEAL_PIP |
 				 VM_EXIT_CLEAR_IA32_RTIT_CTL);
-
-	if (cpu_has_perf_global_ctrl_bug())
-		vmexit_ctrl &= ~VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL;
-
 	/* Loading of EFER and PERF_GLOBAL_CTRL are toggled dynamically */
 	return vmexit_ctrl &
 		~(VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | VM_EXIT_LOAD_IA32_EFER);
@@ -5047,14 +5040,19 @@
 	return !vmx_nmi_blocked(vcpu);
 }
 
+bool __vmx_interrupt_blocked(struct kvm_vcpu *vcpu)
+{
+	return !(vmx_get_rflags(vcpu) & X86_EFLAGS_IF) ||
+	       (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
+		(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS));
+}
+
 bool vmx_interrupt_blocked(struct kvm_vcpu *vcpu)
 {
 	if (is_guest_mode(vcpu) && nested_exit_on_intr(vcpu))
 		return false;
 
-	return !(vmx_get_rflags(vcpu) & X86_EFLAGS_IF) ||
-	       (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
-		(GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS));
+	return __vmx_interrupt_blocked(vcpu);
 }
 
 static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu, bool for_injection)
@@ -6814,7 +6812,7 @@
 	kvm_release_pfn_clean(pfn);
 }
 
-static void vmx_hwapic_isr_update(int max_isr)
+static void vmx_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr)
 {
 	u16 status;
 	u8 old;
@@ -7857,8 +7855,28 @@
 
 	if (vmx_pebs_supported()) {
 		perf_cap |= host_perf_cap & PERF_CAP_PEBS_MASK;
-		if ((perf_cap & PERF_CAP_PEBS_FORMAT) < 4)
-			perf_cap &= ~PERF_CAP_PEBS_BASELINE;
+
+		/*
+		 * Disallow adaptive PEBS as it is functionally broken, can be
+		 * used by the guest to read *host* LBRs, and can be used to
+		 * bypass userspace event filters.  To correctly and safely
+		 * support adaptive PEBS, KVM needs to:
+		 *
+		 * 1. Account for the ADAPTIVE flag when (re)programming fixed
+		 *    counters.
+		 *
+		 * 2. Gain support from perf (or take direct control of counter
+		 *    programming) to support events without adaptive PEBS
+		 *    enabled for the hardware counter.
+		 *
+		 * 3. Ensure LBR MSRs cannot hold host data on VM-Entry with
+		 *    adaptive PEBS enabled and MSR_PEBS_DATA_CFG.LBRS=1.
+		 *
+		 * 4. Document which PMU events are effectively exposed to the
+		 *    guest via adaptive PEBS, and make adaptive PEBS mutually
+		 *    exclusive with KVM_SET_PMU_EVENT_FILTER if necessary.
+		 */
+		perf_cap &= ~PERF_CAP_PEBS_BASELINE;
 	}
 
 	return perf_cap;
@@ -8337,6 +8355,8 @@
 	.enable_nmi_window = vmx_enable_nmi_window,
 	.enable_irq_window = vmx_enable_irq_window,
 	.update_cr8_intercept = vmx_update_cr8_intercept,
+
+	.x2apic_icr_is_split = false,
 	.set_virtual_apic_mode = vmx_set_virtual_apic_mode,
 	.set_apic_access_page_addr = vmx_set_apic_access_page_addr,
 	.refresh_apicv_exec_ctrl = vmx_refresh_apicv_exec_ctrl,
@@ -8489,10 +8509,6 @@
 	if (setup_vmcs_config(&vmcs_config, &vmx_capability) < 0)
 		return -EIO;
 
-	if (cpu_has_perf_global_ctrl_bug())
-		pr_warn_once("VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL "
-			     "does not work properly. Using workaround\n");
-
 	if (boot_cpu_has(X86_FEATURE_NX))
 		kvm_enable_efer_bits(EFER_NX);
 
--- linux-qcom-6.8.0.orig/arch/x86/kvm/vmx/vmx.h
+++ linux-qcom-6.8.0/arch/x86/kvm/vmx/vmx.h
@@ -7,10 +7,10 @@
 #include <asm/kvm.h>
 #include <asm/intel_pt.h>
 #include <asm/perf_event.h>
+#include <asm/posted_intr.h>
 
 #include "capabilities.h"
 #include "../kvm_cache_regs.h"
-#include "posted_intr.h"
 #include "vmcs.h"
 #include "vmx_ops.h"
 #include "../cpuid.h"
@@ -402,6 +402,7 @@
 bool vmx_guest_inject_ac(struct kvm_vcpu *vcpu);
 void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu);
 bool vmx_nmi_blocked(struct kvm_vcpu *vcpu);
+bool __vmx_interrupt_blocked(struct kvm_vcpu *vcpu);
 bool vmx_interrupt_blocked(struct kvm_vcpu *vcpu);
 bool vmx_get_nmi_mask(struct kvm_vcpu *vcpu);
 void vmx_set_nmi_mask(struct kvm_vcpu *vcpu, bool masked);
--- linux-qcom-6.8.0.orig/arch/x86/kvm/x86.c
+++ linux-qcom-6.8.0/arch/x86/kvm/x86.c
@@ -1623,7 +1623,8 @@
 	 ARCH_CAP_SKIP_VMENTRY_L1DFLUSH | ARCH_CAP_SSB_NO | ARCH_CAP_MDS_NO | \
 	 ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \
 	 ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \
-	 ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO)
+	 ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO | \
+	 ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO)
 
 static u64 kvm_get_arch_capabilities(void)
 {
@@ -1655,6 +1656,8 @@
 		data |= ARCH_CAP_SSB_NO;
 	if (!boot_cpu_has_bug(X86_BUG_MDS))
 		data |= ARCH_CAP_MDS_NO;
+	if (!boot_cpu_has_bug(X86_BUG_RFDS))
+		data |= ARCH_CAP_RFDS_NO;
 
 	if (!boot_cpu_has(X86_FEATURE_RTM)) {
 		/*
@@ -3419,7 +3422,7 @@
 static bool can_set_mci_status(struct kvm_vcpu *vcpu)
 {
 	/* McStatusWrEn enabled? */
-	if (guest_cpuid_is_amd_or_hygon(vcpu))
+	if (guest_cpuid_is_amd_compatible(vcpu))
 		return !!(vcpu->arch.msr_hwcr & BIT_ULL(18));
 
 	return false;
@@ -5984,7 +5987,9 @@
 		if (copy_from_user(&events, argp, sizeof(struct kvm_vcpu_events)))
 			break;
 
+		kvm_vcpu_srcu_read_lock(vcpu);
 		r = kvm_vcpu_ioctl_x86_set_vcpu_events(vcpu, &events);
+		kvm_vcpu_srcu_read_unlock(vcpu);
 		break;
 	}
 	case KVM_GET_DEBUGREGS: {
@@ -10006,7 +10011,7 @@
 {
 	u64 ret = vcpu->run->hypercall.ret;
 
-	if (!is_64_bit_mode(vcpu))
+	if (!is_64_bit_hypercall(vcpu))
 		ret = (u32)ret;
 	kvm_rax_write(vcpu, ret);
 	++vcpu->stat.hypercalls;
@@ -10437,7 +10442,7 @@
 
 	if (is_guest_mode(vcpu) &&
 	    kvm_x86_ops.nested_ops->has_events &&
-	    kvm_x86_ops.nested_ops->has_events(vcpu))
+	    kvm_x86_ops.nested_ops->has_events(vcpu, true))
 		*req_immediate_exit = true;
 
 	/*
@@ -10639,13 +10644,12 @@
 
 	bitmap_zero(vcpu->arch.ioapic_handled_vectors, 256);
 
+	static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu);
+
 	if (irqchip_split(vcpu->kvm))
 		kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors);
-	else {
-		static_call_cond(kvm_x86_sync_pir_to_irr)(vcpu);
-		if (ioapic_in_kernel(vcpu->kvm))
-			kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
-	}
+	else if (ioapic_in_kernel(vcpu->kvm))
+		kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
 
 	if (is_guest_mode(vcpu))
 		vcpu->arch.load_eoi_exitmap_pending = true;
@@ -11310,6 +11314,10 @@
 	struct kvm_run *kvm_run = vcpu->run;
 	int r;
 
+	r = kvm_mmu_post_init_vm(vcpu->kvm);
+	if (r)
+		return r;
+
 	vcpu_load(vcpu);
 	kvm_sigset_activate(vcpu);
 	kvm_run->flags = 0;
@@ -12581,7 +12589,8 @@
 
 int kvm_arch_post_init_vm(struct kvm *kvm)
 {
-	return kvm_mmu_post_init_vm(kvm);
+	once_init(&kvm->arch.nx_once);
+	return 0;
 }
 
 static void kvm_unload_vcpu_mmu(struct kvm_vcpu *vcpu)
@@ -13081,7 +13090,7 @@
 
 	if (is_guest_mode(vcpu) &&
 	    kvm_x86_ops.nested_ops->has_events &&
-	    kvm_x86_ops.nested_ops->has_events(vcpu))
+	    kvm_x86_ops.nested_ops->has_events(vcpu, false))
 		return true;
 
 	if (kvm_xen_has_pending_events(vcpu))
@@ -13913,6 +13922,8 @@
 
 static int __init kvm_x86_init(void)
 {
+	kvm_init_xstate_sizes();
+
 	kvm_mmu_x86_module_init();
 	mitigate_smt_rsb &= boot_cpu_has_bug(X86_BUG_SMT_RSB) && cpu_smt_possible();
 	return 0;
--- linux-qcom-6.8.0.orig/arch/x86/kvm/xen.c
+++ linux-qcom-6.8.0/arch/x86/kvm/xen.c
@@ -493,7 +493,7 @@
 		kvm_xen_update_runstate_guest(v, state == RUNSTATE_runnable);
 }
 
-static void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *v)
+void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *v)
 {
 	struct kvm_lapic_irq irq = { };
 	int r;
--- linux-qcom-6.8.0.orig/arch/x86/kvm/xen.h
+++ linux-qcom-6.8.0/arch/x86/kvm/xen.h
@@ -18,6 +18,7 @@
 
 int __kvm_xen_has_interrupt(struct kvm_vcpu *vcpu);
 void kvm_xen_inject_pending_events(struct kvm_vcpu *vcpu);
+void kvm_xen_inject_vcpu_vector(struct kvm_vcpu *vcpu);
 int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data);
 int kvm_xen_vcpu_get_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data);
 int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data);
@@ -36,6 +37,19 @@
 			 const struct kvm_irq_routing_entry *ue);
 void kvm_xen_update_tsc_info(struct kvm_vcpu *vcpu);
 
+static inline void kvm_xen_sw_enable_lapic(struct kvm_vcpu *vcpu)
+{
+	/*
+	 * The local APIC is being enabled. If the per-vCPU upcall vector is
+	 * set and the vCPU's evtchn_upcall_pending flag is set, inject the
+	 * interrupt.
+	 */
+	if (static_branch_unlikely(&kvm_xen_enabled.key) &&
+	    vcpu->arch.xen.vcpu_info_cache.active &&
+	    vcpu->arch.xen.upcall_vector && __kvm_xen_has_interrupt(vcpu))
+		kvm_xen_inject_vcpu_vector(vcpu);
+}
+
 static inline bool kvm_xen_msr_enabled(struct kvm *kvm)
 {
 	return static_branch_unlikely(&kvm_xen_enabled.key) &&
@@ -101,6 +115,10 @@
 {
 }
 
+static inline void kvm_xen_sw_enable_lapic(struct kvm_vcpu *vcpu)
+{
+}
+
 static inline bool kvm_xen_msr_enabled(struct kvm *kvm)
 {
 	return false;
--- linux-qcom-6.8.0.orig/arch/x86/lib/Makefile
+++ linux-qcom-6.8.0/arch/x86/lib/Makefile
@@ -14,19 +14,6 @@
 CFLAGS_REMOVE_delay.o = $(CC_FLAGS_FTRACE)
 endif
 
-# Early boot use of cmdline; don't instrument it
-ifdef CONFIG_AMD_MEM_ENCRYPT
-KCOV_INSTRUMENT_cmdline.o := n
-KASAN_SANITIZE_cmdline.o  := n
-KCSAN_SANITIZE_cmdline.o  := n
-
-ifdef CONFIG_FUNCTION_TRACER
-CFLAGS_REMOVE_cmdline.o = -pg
-endif
-
-CFLAGS_cmdline.o := -fno-stack-protector -fno-jump-tables
-endif
-
 inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk
 inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt
 quiet_cmd_inat_tables = GEN     $@
--- linux-qcom-6.8.0.orig/arch/x86/lib/getuser.S
+++ linux-qcom-6.8.0/arch/x86/lib/getuser.S
@@ -44,7 +44,11 @@
 	or %rdx, %rax
 .else
 	cmp $TASK_SIZE_MAX-\size+1, %eax
+.if \size != 8
 	jae .Lbad_get_user
+.else
+	jae .Lbad_get_user_8
+.endif
 	sbb %edx, %edx		/* array_index_mask_nospec() */
 	and %edx, %eax
 .endif
@@ -154,7 +158,7 @@
 #ifdef CONFIG_X86_32
 SYM_CODE_START_LOCAL(__get_user_8_handle_exception)
 	ASM_CLAC
-bad_get_user_8:
+.Lbad_get_user_8:
 	xor %edx,%edx
 	xor %ecx,%ecx
 	mov $(-EFAULT),%_ASM_AX
--- linux-qcom-6.8.0.orig/arch/x86/lib/iomem.c
+++ linux-qcom-6.8.0/arch/x86/lib/iomem.c
@@ -25,6 +25,9 @@
 
 static void string_memcpy_fromio(void *to, const volatile void __iomem *from, size_t n)
 {
+	const void *orig_to = to;
+	const size_t orig_n = n;
+
 	if (unlikely(!n))
 		return;
 
@@ -39,7 +42,7 @@
 	}
 	rep_movs(to, (const void *)from, n);
 	/* KMSAN must treat values read from devices as initialized. */
-	kmsan_unpoison_memory(to, n);
+	kmsan_unpoison_memory(orig_to, orig_n);
 }
 
 static void string_memcpy_toio(volatile void __iomem *to, const void *from, size_t n)
--- linux-qcom-6.8.0.orig/arch/x86/lib/retpoline.S
+++ linux-qcom-6.8.0/arch/x86/lib/retpoline.S
@@ -163,6 +163,7 @@
 	lfence
 	jmp srso_alias_return_thunk
 SYM_FUNC_END(srso_alias_untrain_ret)
+__EXPORT_THUNK(srso_alias_untrain_ret)
 	.popsection
 
 	.pushsection .text..__x86.rethunk_safe
@@ -224,10 +225,16 @@
 SYM_CODE_END(srso_return_thunk)
 
 #define JMP_SRSO_UNTRAIN_RET "jmp srso_untrain_ret"
-#define JMP_SRSO_ALIAS_UNTRAIN_RET "jmp srso_alias_untrain_ret"
 #else /* !CONFIG_CPU_SRSO */
 #define JMP_SRSO_UNTRAIN_RET "ud2"
-#define JMP_SRSO_ALIAS_UNTRAIN_RET "ud2"
+/* Dummy for the alternative in CALL_UNTRAIN_RET. */
+SYM_CODE_START(srso_alias_untrain_ret)
+	ANNOTATE_UNRET_SAFE
+	ANNOTATE_NOENDBR
+	ret
+	int3
+SYM_FUNC_END(srso_alias_untrain_ret)
+__EXPORT_THUNK(srso_alias_untrain_ret)
 #endif /* CONFIG_CPU_SRSO */
 
 #ifdef CONFIG_CPU_UNRET_ENTRY
@@ -319,9 +326,7 @@
 #if defined(CONFIG_CPU_UNRET_ENTRY) || defined(CONFIG_CPU_SRSO)
 
 SYM_FUNC_START(entry_untrain_ret)
-	ALTERNATIVE_2 JMP_RETBLEED_UNTRAIN_RET,				\
-		      JMP_SRSO_UNTRAIN_RET, X86_FEATURE_SRSO,		\
-		      JMP_SRSO_ALIAS_UNTRAIN_RET, X86_FEATURE_SRSO_ALIAS
+	ALTERNATIVE JMP_RETBLEED_UNTRAIN_RET, JMP_SRSO_UNTRAIN_RET, X86_FEATURE_SRSO
 SYM_FUNC_END(entry_untrain_ret)
 __EXPORT_THUNK(entry_untrain_ret)
 
--- linux-qcom-6.8.0.orig/arch/x86/lib/x86-opcode-map.txt
+++ linux-qcom-6.8.0/arch/x86/lib/x86-opcode-map.txt
@@ -148,7 +148,7 @@
 65: SEG=GS (Prefix)
 66: Operand-Size (Prefix)
 67: Address-Size (Prefix)
-68: PUSH Iz (d64)
+68: PUSH Iz
 69: IMUL Gv,Ev,Iz
 6a: PUSH Ib (d64)
 6b: IMUL Gv,Ev,Ib
@@ -698,10 +698,10 @@
 4d: vrcp14ss/d Vsd,Hpd,Wsd (66),(ev)
 4e: vrsqrt14ps/d Vpd,Wpd (66),(ev)
 4f: vrsqrt14ss/d Vsd,Hsd,Wsd (66),(ev)
-50: vpdpbusd Vx,Hx,Wx (66),(ev)
-51: vpdpbusds Vx,Hx,Wx (66),(ev)
-52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66),(ev) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev)
-53: vpdpwssds Vx,Hx,Wx (66),(ev) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev)
+50: vpdpbusd Vx,Hx,Wx (66)
+51: vpdpbusds Vx,Hx,Wx (66)
+52: vdpbf16ps Vx,Hx,Wx (F3),(ev) | vpdpwssd Vx,Hx,Wx (66) | vp4dpwssd Vdqq,Hdqq,Wdq (F2),(ev)
+53: vpdpwssds Vx,Hx,Wx (66) | vp4dpwssds Vdqq,Hdqq,Wdq (F2),(ev)
 54: vpopcntb/w Vx,Wx (66),(ev)
 55: vpopcntd/q Vx,Wx (66),(ev)
 58: vpbroadcastd Vx,Wx (66),(v)
--- linux-qcom-6.8.0.orig/arch/x86/mm/fault.c
+++ linux-qcom-6.8.0/arch/x86/mm/fault.c
@@ -376,7 +376,7 @@
 		goto bad;
 
 	pr_cont("PUD %lx ", pud_val(*pud));
-	if (!pud_present(*pud) || pud_large(*pud))
+	if (!pud_present(*pud) || pud_leaf(*pud))
 		goto out;
 
 	pmd = pmd_offset(pud, address);
@@ -717,39 +717,8 @@
 	WARN_ON_ONCE(user_mode(regs));
 
 	/* Are we prepared to handle this kernel fault? */
-	if (fixup_exception(regs, X86_TRAP_PF, error_code, address)) {
-		/*
-		 * Any interrupt that takes a fault gets the fixup. This makes
-		 * the below recursive fault logic only apply to a faults from
-		 * task context.
-		 */
-		if (in_interrupt())
-			return;
-
-		/*
-		 * Per the above we're !in_interrupt(), aka. task context.
-		 *
-		 * In this case we need to make sure we're not recursively
-		 * faulting through the emulate_vsyscall() logic.
-		 */
-		if (current->thread.sig_on_uaccess_err && signal) {
-			sanitize_error_code(address, &error_code);
-
-			set_signal_archinfo(address, error_code);
-
-			if (si_code == SEGV_PKUERR) {
-				force_sig_pkuerr((void __user *)address, pkey);
-			} else {
-				/* XXX: hwpoison faults will set the wrong code. */
-				force_sig_fault(signal, si_code, (void __user *)address);
-			}
-		}
-
-		/*
-		 * Barring that, we can do the fixup and be happy.
-		 */
+	if (fixup_exception(regs, X86_TRAP_PF, error_code, address))
 		return;
-	}
 
 	/*
 	 * AMD erratum #91 manifests as a spurious page fault on a PREFETCH
@@ -1037,7 +1006,7 @@
 	if (!pud_present(*pud))
 		return 0;
 
-	if (pud_large(*pud))
+	if (pud_leaf(*pud))
 		return spurious_kernel_fault_check(error_code, (pte_t *) pud);
 
 	pmd = pmd_offset(pud, address);
--- linux-qcom-6.8.0.orig/arch/x86/mm/ident_map.c
+++ linux-qcom-6.8.0/arch/x86/mm/ident_map.c
@@ -33,7 +33,7 @@
 			next = end;
 
 		/* if this is already a gbpage, this portion is already mapped */
-		if (pud_large(*pud))
+		if (pud_leaf(*pud))
 			continue;
 
 		/* Is using a gbpage allowed? */
@@ -101,7 +101,7 @@
 		if (result)
 			return result;
 
-		set_p4d(p4d, __p4d(__pa(pud) | info->kernpg_flag));
+		set_p4d(p4d, __p4d(__pa(pud) | info->kernpg_flag | _PAGE_NOPTISHADOW));
 	}
 
 	return 0;
@@ -145,14 +145,14 @@
 		if (result)
 			return result;
 		if (pgtable_l5_enabled()) {
-			set_pgd(pgd, __pgd(__pa(p4d) | info->kernpg_flag));
+			set_pgd(pgd, __pgd(__pa(p4d) | info->kernpg_flag | _PAGE_NOPTISHADOW));
 		} else {
 			/*
 			 * With p4d folded, pgd is equal to p4d.
 			 * The pgd entry has to point to the pud page table in this case.
 			 */
 			pud_t *pud = pud_offset(p4d, 0);
-			set_pgd(pgd, __pgd(__pa(pud) | info->kernpg_flag));
+			set_pgd(pgd, __pgd(__pa(pud) | info->kernpg_flag | _PAGE_NOPTISHADOW));
 		}
 	}
 
--- linux-qcom-6.8.0.orig/arch/x86/mm/init.c
+++ linux-qcom-6.8.0/arch/x86/mm/init.c
@@ -261,21 +261,17 @@
 	}
 }
 
-#define INTEL_MATCH(_model) { .vendor  = X86_VENDOR_INTEL,	\
-			      .family  = 6,			\
-			      .model = _model,			\
-			    }
 /*
  * INVLPG may not properly flush Global entries
  * on these CPUs when PCIDs are enabled.
  */
 static const struct x86_cpu_id invlpg_miss_ids[] = {
-	INTEL_MATCH(INTEL_FAM6_ALDERLAKE   ),
-	INTEL_MATCH(INTEL_FAM6_ALDERLAKE_L ),
-	INTEL_MATCH(INTEL_FAM6_ATOM_GRACEMONT ),
-	INTEL_MATCH(INTEL_FAM6_RAPTORLAKE  ),
-	INTEL_MATCH(INTEL_FAM6_RAPTORLAKE_P),
-	INTEL_MATCH(INTEL_FAM6_RAPTORLAKE_S),
+	X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE,      0),
+	X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L,    0),
+	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GRACEMONT, 0),
+	X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE,     0),
+	X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P,   0),
+	X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S,   0),
 	{}
 };
 
--- linux-qcom-6.8.0.orig/arch/x86/mm/init_64.c
+++ linux-qcom-6.8.0/arch/x86/mm/init_64.c
@@ -617,7 +617,7 @@
 		}
 
 		if (!pud_none(*pud)) {
-			if (!pud_large(*pud)) {
+			if (!pud_leaf(*pud)) {
 				pmd = pmd_offset(pud, 0);
 				paddr_last = phys_pmd_init(pmd, paddr,
 							   paddr_end,
@@ -950,8 +950,12 @@
 int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages,
 	      struct mhp_params *params)
 {
+	unsigned long end = ((start_pfn + nr_pages) << PAGE_SHIFT) - 1;
 	int ret;
 
+	if (WARN_ON_ONCE(end > PHYSMEM_END))
+		return -ERANGE;
+
 	ret = __add_pages(nid, start_pfn, nr_pages, params);
 	WARN_ON_ONCE(ret);
 
@@ -1163,7 +1167,7 @@
 		if (!pud_present(*pud))
 			continue;
 
-		if (pud_large(*pud) &&
+		if (pud_leaf(*pud) &&
 		    IS_ALIGNED(addr, PUD_SIZE) &&
 		    IS_ALIGNED(next, PUD_SIZE)) {
 			spin_lock(&init_mm.page_table_lock);
--- linux-qcom-6.8.0.orig/arch/x86/mm/ioremap.c
+++ linux-qcom-6.8.0/arch/x86/mm/ioremap.c
@@ -655,7 +655,8 @@
 		paddr_next = data->next;
 		len = data->len;
 
-		if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
+		if ((phys_addr > paddr) &&
+		    (phys_addr < (paddr + sizeof(struct setup_data) + len))) {
 			memunmap(data);
 			return true;
 		}
@@ -717,7 +718,8 @@
 		paddr_next = data->next;
 		len = data->len;
 
-		if ((phys_addr > paddr) && (phys_addr < (paddr + len))) {
+		if ((phys_addr > paddr) &&
+		    (phys_addr < (paddr + sizeof(struct setup_data) + len))) {
 			early_memunmap(data, sizeof(*data));
 			return true;
 		}
--- linux-qcom-6.8.0.orig/arch/x86/mm/kasan_init_64.c
+++ linux-qcom-6.8.0/arch/x86/mm/kasan_init_64.c
@@ -115,7 +115,7 @@
 	pud = pud_offset(p4d, addr);
 	do {
 		next = pud_addr_end(addr, end);
-		if (!pud_large(*pud))
+		if (!pud_leaf(*pud))
 			kasan_populate_pud(pud, addr, next, nid);
 	} while (pud++, addr = next, addr != end);
 }
--- linux-qcom-6.8.0.orig/arch/x86/mm/kaslr.c
+++ linux-qcom-6.8.0/arch/x86/mm/kaslr.c
@@ -47,13 +47,24 @@
  */
 static __initdata struct kaslr_memory_region {
 	unsigned long *base;
+	unsigned long *end;
 	unsigned long size_tb;
 } kaslr_regions[] = {
-	{ &page_offset_base, 0 },
-	{ &vmalloc_base, 0 },
-	{ &vmemmap_base, 0 },
+	{
+		.base	= &page_offset_base,
+		.end	= &physmem_end,
+	},
+	{
+		.base	= &vmalloc_base,
+	},
+	{
+		.base	= &vmemmap_base,
+	},
 };
 
+/* The end of the possible address space for physical memory */
+unsigned long physmem_end __ro_after_init;
+
 /* Get size in bytes used by the memory region */
 static inline unsigned long get_padding(struct kaslr_memory_region *region)
 {
@@ -82,6 +93,8 @@
 	BUILD_BUG_ON(vaddr_end != CPU_ENTRY_AREA_BASE);
 	BUILD_BUG_ON(vaddr_end > __START_KERNEL_map);
 
+	/* Preset the end of the possible address space for physical memory */
+	physmem_end = ((1ULL << MAX_PHYSMEM_BITS) - 1);
 	if (!kaslr_memory_enabled())
 		return;
 
@@ -128,11 +141,18 @@
 		vaddr += entropy;
 		*kaslr_regions[i].base = vaddr;
 
+		/* Calculate the end of the region */
+		vaddr += get_padding(&kaslr_regions[i]);
 		/*
-		 * Jump the region and add a minimum padding based on
-		 * randomization alignment.
+		 * KASLR trims the maximum possible size of the
+		 * direct-map. Update the physmem_end boundary.
+		 * No rounding required as the region starts
+		 * PUD aligned and size is in units of TB.
 		 */
-		vaddr += get_padding(&kaslr_regions[i]);
+		if (kaslr_regions[i].end)
+			*kaslr_regions[i].end = __pa_nodebug(vaddr - 1);
+
+		/* Add a minimum padding based on randomization alignment. */
 		vaddr = round_up(vaddr + 1, PUD_SIZE);
 		remain_entropy -= entropy;
 	}
--- linux-qcom-6.8.0.orig/arch/x86/mm/mem_encrypt_amd.c
+++ linux-qcom-6.8.0/arch/x86/mm/mem_encrypt_amd.c
@@ -283,7 +283,7 @@
 #endif
 }
 
-static bool amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc)
+static int amd_enc_status_change_prepare(unsigned long vaddr, int npages, bool enc)
 {
 	/*
 	 * To maintain the security guarantees of SEV-SNP guests, make sure
@@ -292,11 +292,11 @@
 	if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP) && !enc)
 		snp_set_memory_shared(vaddr, npages);
 
-	return true;
+	return 0;
 }
 
 /* Return true unconditionally: return value doesn't matter for the SEV side */
-static bool amd_enc_status_change_finish(unsigned long vaddr, int npages, bool enc)
+static int amd_enc_status_change_finish(unsigned long vaddr, int npages, bool enc)
 {
 	/*
 	 * After memory is mapped encrypted in the page table, validate it
@@ -308,7 +308,7 @@
 	if (!cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
 		enc_dec_hypercall(vaddr, npages << PAGE_SHIFT, enc);
 
-	return true;
+	return 0;
 }
 
 static void __init __set_clr_pte_enc(pte_t *kpte, int level, bool enc)
@@ -492,6 +492,24 @@
 	 */
 	if (sev_status & MSR_AMD64_SEV_ENABLED)
 		ia32_disable();
+
+	/*
+	 * Override init functions that scan the ROM region in SEV-SNP guests,
+	 * as this memory is not pre-validated and would thus cause a crash.
+	 */
+	if (sev_status & MSR_AMD64_SEV_SNP_ENABLED) {
+		x86_init.mpparse.find_smp_config = x86_init_noop;
+		x86_init.pci.init_irq = x86_init_noop;
+		x86_init.resources.probe_roms = x86_init_noop;
+
+		/*
+		 * DMI setup behavior for SEV-SNP guests depends on
+		 * efi_enabled(EFI_CONFIG_TABLES), which hasn't been
+		 * parsed yet. snp_dmi_setup() will run after that
+		 * parsing has happened.
+		 */
+		x86_init.resources.dmi_setup = snp_dmi_setup;
+	}
 }
 
 void __init mem_encrypt_free_decrypted_mem(void)
--- linux-qcom-6.8.0.orig/arch/x86/mm/mem_encrypt_identity.c
+++ linux-qcom-6.8.0/arch/x86/mm/mem_encrypt_identity.c
@@ -41,9 +41,9 @@
 #include <linux/mem_encrypt.h>
 #include <linux/cc_platform.h>
 
+#include <asm/init.h>
 #include <asm/setup.h>
 #include <asm/sections.h>
-#include <asm/cmdline.h>
 #include <asm/coco.h>
 #include <asm/sev.h>
 
@@ -95,11 +95,7 @@
  */
 static char sme_workarea[2 * PMD_SIZE] __section(".init.scratch");
 
-static char sme_cmdline_arg[] __initdata = "mem_encrypt";
-static char sme_cmdline_on[]  __initdata = "on";
-static char sme_cmdline_off[] __initdata = "off";
-
-static void __init sme_clear_pgd(struct sme_populate_pgd_data *ppd)
+static void __head sme_clear_pgd(struct sme_populate_pgd_data *ppd)
 {
 	unsigned long pgd_start, pgd_end, pgd_size;
 	pgd_t *pgd_p;
@@ -114,7 +110,7 @@
 	memset(pgd_p, 0, pgd_size);
 }
 
-static pud_t __init *sme_prepare_pgd(struct sme_populate_pgd_data *ppd)
+static pud_t __head *sme_prepare_pgd(struct sme_populate_pgd_data *ppd)
 {
 	pgd_t *pgd;
 	p4d_t *p4d;
@@ -145,13 +141,13 @@
 		set_pud(pud, __pud(PUD_FLAGS | __pa(pmd)));
 	}
 
-	if (pud_large(*pud))
+	if (pud_leaf(*pud))
 		return NULL;
 
 	return pud;
 }
 
-static void __init sme_populate_pgd_large(struct sme_populate_pgd_data *ppd)
+static void __head sme_populate_pgd_large(struct sme_populate_pgd_data *ppd)
 {
 	pud_t *pud;
 	pmd_t *pmd;
@@ -167,7 +163,7 @@
 	set_pmd(pmd, __pmd(ppd->paddr | ppd->pmd_flags));
 }
 
-static void __init sme_populate_pgd(struct sme_populate_pgd_data *ppd)
+static void __head sme_populate_pgd(struct sme_populate_pgd_data *ppd)
 {
 	pud_t *pud;
 	pmd_t *pmd;
@@ -193,7 +189,7 @@
 		set_pte(pte, __pte(ppd->paddr | ppd->pte_flags));
 }
 
-static void __init __sme_map_range_pmd(struct sme_populate_pgd_data *ppd)
+static void __head __sme_map_range_pmd(struct sme_populate_pgd_data *ppd)
 {
 	while (ppd->vaddr < ppd->vaddr_end) {
 		sme_populate_pgd_large(ppd);
@@ -203,7 +199,7 @@
 	}
 }
 
-static void __init __sme_map_range_pte(struct sme_populate_pgd_data *ppd)
+static void __head __sme_map_range_pte(struct sme_populate_pgd_data *ppd)
 {
 	while (ppd->vaddr < ppd->vaddr_end) {
 		sme_populate_pgd(ppd);
@@ -213,7 +209,7 @@
 	}
 }
 
-static void __init __sme_map_range(struct sme_populate_pgd_data *ppd,
+static void __head __sme_map_range(struct sme_populate_pgd_data *ppd,
 				   pmdval_t pmd_flags, pteval_t pte_flags)
 {
 	unsigned long vaddr_end;
@@ -237,22 +233,22 @@
 	__sme_map_range_pte(ppd);
 }
 
-static void __init sme_map_range_encrypted(struct sme_populate_pgd_data *ppd)
+static void __head sme_map_range_encrypted(struct sme_populate_pgd_data *ppd)
 {
 	__sme_map_range(ppd, PMD_FLAGS_ENC, PTE_FLAGS_ENC);
 }
 
-static void __init sme_map_range_decrypted(struct sme_populate_pgd_data *ppd)
+static void __head sme_map_range_decrypted(struct sme_populate_pgd_data *ppd)
 {
 	__sme_map_range(ppd, PMD_FLAGS_DEC, PTE_FLAGS_DEC);
 }
 
-static void __init sme_map_range_decrypted_wp(struct sme_populate_pgd_data *ppd)
+static void __head sme_map_range_decrypted_wp(struct sme_populate_pgd_data *ppd)
 {
 	__sme_map_range(ppd, PMD_FLAGS_DEC_WP, PTE_FLAGS_DEC_WP);
 }
 
-static unsigned long __init sme_pgtable_calc(unsigned long len)
+static unsigned long __head sme_pgtable_calc(unsigned long len)
 {
 	unsigned long entries = 0, tables = 0;
 
@@ -289,7 +285,7 @@
 	return entries + tables;
 }
 
-void __init sme_encrypt_kernel(struct boot_params *bp)
+void __head sme_encrypt_kernel(struct boot_params *bp)
 {
 	unsigned long workarea_start, workarea_end, workarea_len;
 	unsigned long execute_start, execute_end, execute_len;
@@ -305,7 +301,8 @@
 	 * instrumentation or checking boot_cpu_data in the cc_platform_has()
 	 * function.
 	 */
-	if (!sme_get_me_mask() || sev_status & MSR_AMD64_SEV_ENABLED)
+	if (!sme_get_me_mask() ||
+	    RIP_REL_REF(sev_status) & MSR_AMD64_SEV_ENABLED)
 		return;
 
 	/*
@@ -323,9 +320,8 @@
 	 *     memory from being cached.
 	 */
 
-	/* Physical addresses gives us the identity mapped virtual addresses */
-	kernel_start = __pa_symbol(_text);
-	kernel_end = ALIGN(__pa_symbol(_end), PMD_SIZE);
+	kernel_start = (unsigned long)RIP_REL_REF(_text);
+	kernel_end = ALIGN((unsigned long)RIP_REL_REF(_end), PMD_SIZE);
 	kernel_len = kernel_end - kernel_start;
 
 	initrd_start = 0;
@@ -343,14 +339,6 @@
 #endif
 
 	/*
-	 * We're running identity mapped, so we must obtain the address to the
-	 * SME encryption workarea using rip-relative addressing.
-	 */
-	asm ("lea sme_workarea(%%rip), %0"
-	     : "=r" (workarea_start)
-	     : "p" (sme_workarea));
-
-	/*
 	 * Calculate required number of workarea bytes needed:
 	 *   executable encryption area size:
 	 *     stack page (PAGE_SIZE)
@@ -359,7 +347,7 @@
 	 *   pagetable structures for the encryption of the kernel
 	 *   pagetable structures for workarea (in case not currently mapped)
 	 */
-	execute_start = workarea_start;
+	execute_start = workarea_start = (unsigned long)RIP_REL_REF(sme_workarea);
 	execute_end = execute_start + (PAGE_SIZE * 2) + PMD_SIZE;
 	execute_len = execute_end - execute_start;
 
@@ -502,14 +490,11 @@
 	native_write_cr3(__native_read_cr3());
 }
 
-void __init sme_enable(struct boot_params *bp)
+void __head sme_enable(struct boot_params *bp)
 {
-	const char *cmdline_ptr, *cmdline_arg, *cmdline_on, *cmdline_off;
 	unsigned int eax, ebx, ecx, edx;
 	unsigned long feature_mask;
-	bool active_by_default;
 	unsigned long me_mask;
-	char buffer[16];
 	bool snp;
 	u64 msr;
 
@@ -543,15 +528,18 @@
 	me_mask = 1UL << (ebx & 0x3f);
 
 	/* Check the SEV MSR whether SEV or SME is enabled */
-	sev_status   = __rdmsr(MSR_AMD64_SEV);
-	feature_mask = (sev_status & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT;
+	RIP_REL_REF(sev_status) = msr = __rdmsr(MSR_AMD64_SEV);
+	feature_mask = (msr & MSR_AMD64_SEV_ENABLED) ? AMD_SEV_BIT : AMD_SME_BIT;
 
 	/* The SEV-SNP CC blob should never be present unless SEV-SNP is enabled. */
-	if (snp && !(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
+	if (snp && !(msr & MSR_AMD64_SEV_SNP_ENABLED))
 		snp_abort();
 
 	/* Check if memory encryption is enabled */
 	if (feature_mask == AMD_SME_BIT) {
+		if (!(bp->hdr.xloadflags & XLF_MEM_ENCRYPTION))
+			return;
+
 		/*
 		 * No SME if Hypervisor bit is set. This check is here to
 		 * prevent a guest from trying to enable SME. For running as a
@@ -571,48 +559,10 @@
 		msr = __rdmsr(MSR_AMD64_SYSCFG);
 		if (!(msr & MSR_AMD64_SYSCFG_MEM_ENCRYPT))
 			return;
-	} else {
-		/* SEV state cannot be controlled by a command line option */
-		sme_me_mask = me_mask;
-		goto out;
 	}
 
-	/*
-	 * Fixups have not been applied to phys_base yet and we're running
-	 * identity mapped, so we must obtain the address to the SME command
-	 * line argument data using rip-relative addressing.
-	 */
-	asm ("lea sme_cmdline_arg(%%rip), %0"
-	     : "=r" (cmdline_arg)
-	     : "p" (sme_cmdline_arg));
-	asm ("lea sme_cmdline_on(%%rip), %0"
-	     : "=r" (cmdline_on)
-	     : "p" (sme_cmdline_on));
-	asm ("lea sme_cmdline_off(%%rip), %0"
-	     : "=r" (cmdline_off)
-	     : "p" (sme_cmdline_off));
-
-	if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT))
-		active_by_default = true;
-	else
-		active_by_default = false;
-
-	cmdline_ptr = (const char *)((u64)bp->hdr.cmd_line_ptr |
-				     ((u64)bp->ext_cmd_line_ptr << 32));
-
-	if (cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)) < 0)
-		return;
-
-	if (!strncmp(buffer, cmdline_on, sizeof(buffer)))
-		sme_me_mask = me_mask;
-	else if (!strncmp(buffer, cmdline_off, sizeof(buffer)))
-		sme_me_mask = 0;
-	else
-		sme_me_mask = active_by_default ? me_mask : 0;
-out:
-	if (sme_me_mask) {
-		physical_mask &= ~sme_me_mask;
-		cc_vendor = CC_VENDOR_AMD;
-		cc_set_mask(sme_me_mask);
-	}
+	RIP_REL_REF(sme_me_mask) = me_mask;
+	physical_mask &= ~me_mask;
+	cc_vendor = CC_VENDOR_AMD;
+	cc_set_mask(me_mask);
 }
--- linux-qcom-6.8.0.orig/arch/x86/mm/numa.c
+++ linux-qcom-6.8.0/arch/x86/mm/numa.c
@@ -493,7 +493,7 @@
 	for_each_reserved_mem_region(mb_region) {
 		int nid = memblock_get_region_node(mb_region);
 
-		if (nid != MAX_NUMNODES)
+		if (nid != NUMA_NO_NODE)
 			node_set(nid, reserved_nodemask);
 	}
 
@@ -614,9 +614,9 @@
 	nodes_clear(node_online_map);
 	memset(&numa_meminfo, 0, sizeof(numa_meminfo));
 	WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.memory,
-				  MAX_NUMNODES));
+				  NUMA_NO_NODE));
 	WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.reserved,
-				  MAX_NUMNODES));
+				  NUMA_NO_NODE));
 	/* In case that parsing SRAT failed. */
 	WARN_ON(memblock_clear_hotplug(0, ULLONG_MAX));
 	numa_reset_distance();
@@ -929,6 +929,8 @@
 }
 EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
 
+#endif
+
 static int __init cmp_memblk(const void *a, const void *b)
 {
 	const struct numa_memblk *ma = *(const struct numa_memblk **)a;
@@ -1001,5 +1003,3 @@
 	}
 	return 0;
 }
-
-#endif
--- linux-qcom-6.8.0.orig/arch/x86/mm/pat/memtype.c
+++ linux-qcom-6.8.0/arch/x86/mm/pat/memtype.c
@@ -950,6 +950,38 @@
 		memtype_free(paddr, paddr + size);
 }
 
+static int get_pat_info(struct vm_area_struct *vma, resource_size_t *paddr,
+		pgprot_t *pgprot)
+{
+	unsigned long prot;
+
+	VM_WARN_ON_ONCE(!(vma->vm_flags & VM_PAT));
+
+	/*
+	 * We need the starting PFN and cachemode used for track_pfn_remap()
+	 * that covered the whole VMA. For most mappings, we can obtain that
+	 * information from the page tables. For COW mappings, we might now
+	 * suddenly have anon folios mapped and follow_phys() will fail.
+	 *
+	 * Fallback to using vma->vm_pgoff, see remap_pfn_range_notrack(), to
+	 * detect the PFN. If we need the cachemode as well, we're out of luck
+	 * for now and have to fail fork().
+	 */
+	if (!follow_phys(vma, vma->vm_start, 0, &prot, paddr)) {
+		if (pgprot)
+			*pgprot = __pgprot(prot);
+		return 0;
+	}
+	if (is_cow_mapping(vma->vm_flags)) {
+		if (pgprot)
+			return -EINVAL;
+		*paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT;
+		return 0;
+	}
+	WARN_ON_ONCE(1);
+	return -EINVAL;
+}
+
 /*
  * track_pfn_copy is called when vma that is covering the pfnmap gets
  * copied through copy_page_range().
@@ -960,20 +992,13 @@
 int track_pfn_copy(struct vm_area_struct *vma)
 {
 	resource_size_t paddr;
-	unsigned long prot;
 	unsigned long vma_size = vma->vm_end - vma->vm_start;
 	pgprot_t pgprot;
 
 	if (vma->vm_flags & VM_PAT) {
-		/*
-		 * reserve the whole chunk covered by vma. We need the
-		 * starting address and protection from pte.
-		 */
-		if (follow_phys(vma, vma->vm_start, 0, &prot, &paddr)) {
-			WARN_ON_ONCE(1);
+		if (get_pat_info(vma, &paddr, &pgprot))
 			return -EINVAL;
-		}
-		pgprot = __pgprot(prot);
+		/* reserve the whole chunk covered by vma. */
 		return reserve_pfn_range(paddr, vma_size, &pgprot, 1);
 	}
 
@@ -1048,7 +1073,6 @@
 		 unsigned long size, bool mm_wr_locked)
 {
 	resource_size_t paddr;
-	unsigned long prot;
 
 	if (vma && !(vma->vm_flags & VM_PAT))
 		return;
@@ -1056,11 +1080,8 @@
 	/* free the chunk starting from pfn or the whole chunk */
 	paddr = (resource_size_t)pfn << PAGE_SHIFT;
 	if (!paddr && !size) {
-		if (follow_phys(vma, vma->vm_start, 0, &prot, &paddr)) {
-			WARN_ON_ONCE(1);
+		if (get_pat_info(vma, &paddr, NULL))
 			return;
-		}
-
 		size = vma->vm_end - vma->vm_start;
 	}
 	free_pfn_range(paddr, size);
--- linux-qcom-6.8.0.orig/arch/x86/mm/pat/set_memory.c
+++ linux-qcom-6.8.0/arch/x86/mm/pat/set_memory.c
@@ -619,7 +619,8 @@
  * Validate strict W^X semantics.
  */
 static inline pgprot_t verify_rwx(pgprot_t old, pgprot_t new, unsigned long start,
-				  unsigned long pfn, unsigned long npg)
+				  unsigned long pfn, unsigned long npg,
+				  bool nx, bool rw)
 {
 	unsigned long end;
 
@@ -641,6 +642,10 @@
 	if ((pgprot_val(new) & (_PAGE_RW | _PAGE_NX)) != _PAGE_RW)
 		return new;
 
+	/* Non-leaf translation entries can disable writing or execution. */
+	if (!rw || nx)
+		return new;
+
 	end = start + npg * PAGE_SIZE - 1;
 	WARN_ONCE(1, "CPA detected W^X violation: %016llx -> %016llx range: 0x%016lx - 0x%016lx PFN %lx\n",
 		  (unsigned long long)pgprot_val(old),
@@ -657,20 +662,26 @@
 
 /*
  * Lookup the page table entry for a virtual address in a specific pgd.
- * Return a pointer to the entry and the level of the mapping.
+ * Return a pointer to the entry, the level of the mapping, and the effective
+ * NX and RW bits of all page table levels.
  */
-pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
-			     unsigned int *level)
+pte_t *lookup_address_in_pgd_attr(pgd_t *pgd, unsigned long address,
+				  unsigned int *level, bool *nx, bool *rw)
 {
 	p4d_t *p4d;
 	pud_t *pud;
 	pmd_t *pmd;
 
 	*level = PG_LEVEL_NONE;
+	*nx = false;
+	*rw = true;
 
 	if (pgd_none(*pgd))
 		return NULL;
 
+	*nx |= pgd_flags(*pgd) & _PAGE_NX;
+	*rw &= pgd_flags(*pgd) & _PAGE_RW;
+
 	p4d = p4d_offset(pgd, address);
 	if (p4d_none(*p4d))
 		return NULL;
@@ -679,14 +690,20 @@
 	if (p4d_large(*p4d) || !p4d_present(*p4d))
 		return (pte_t *)p4d;
 
+	*nx |= p4d_flags(*p4d) & _PAGE_NX;
+	*rw &= p4d_flags(*p4d) & _PAGE_RW;
+
 	pud = pud_offset(p4d, address);
 	if (pud_none(*pud))
 		return NULL;
 
 	*level = PG_LEVEL_1G;
-	if (pud_large(*pud) || !pud_present(*pud))
+	if (pud_leaf(*pud) || !pud_present(*pud))
 		return (pte_t *)pud;
 
+	*nx |= pud_flags(*pud) & _PAGE_NX;
+	*rw &= pud_flags(*pud) & _PAGE_RW;
+
 	pmd = pmd_offset(pud, address);
 	if (pmd_none(*pmd))
 		return NULL;
@@ -695,12 +712,27 @@
 	if (pmd_large(*pmd) || !pmd_present(*pmd))
 		return (pte_t *)pmd;
 
+	*nx |= pmd_flags(*pmd) & _PAGE_NX;
+	*rw &= pmd_flags(*pmd) & _PAGE_RW;
+
 	*level = PG_LEVEL_4K;
 
 	return pte_offset_kernel(pmd, address);
 }
 
 /*
+ * Lookup the page table entry for a virtual address in a specific pgd.
+ * Return a pointer to the entry and the level of the mapping.
+ */
+pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
+			     unsigned int *level)
+{
+	bool nx, rw;
+
+	return lookup_address_in_pgd_attr(pgd, address, level, &nx, &rw);
+}
+
+/*
  * Lookup the page table entry for a virtual address. Return a pointer
  * to the entry and the level of the mapping.
  *
@@ -715,13 +747,16 @@
 EXPORT_SYMBOL_GPL(lookup_address);
 
 static pte_t *_lookup_address_cpa(struct cpa_data *cpa, unsigned long address,
-				  unsigned int *level)
+				  unsigned int *level, bool *nx, bool *rw)
 {
-	if (cpa->pgd)
-		return lookup_address_in_pgd(cpa->pgd + pgd_index(address),
-					       address, level);
+	pgd_t *pgd;
 
-	return lookup_address(address, level);
+	if (!cpa->pgd)
+		pgd = pgd_offset_k(address);
+	else
+		pgd = cpa->pgd + pgd_index(address);
+
+	return lookup_address_in_pgd_attr(pgd, address, level, nx, rw);
 }
 
 /*
@@ -743,7 +778,7 @@
 		return NULL;
 
 	pud = pud_offset(p4d, address);
-	if (pud_none(*pud) || pud_large(*pud) || !pud_present(*pud))
+	if (pud_none(*pud) || pud_leaf(*pud) || !pud_present(*pud))
 		return NULL;
 
 	return pmd_offset(pud, address);
@@ -849,12 +884,13 @@
 	pgprot_t old_prot, new_prot, req_prot, chk_prot;
 	pte_t new_pte, *tmp;
 	enum pg_level level;
+	bool nx, rw;
 
 	/*
 	 * Check for races, another CPU might have split this page
 	 * up already:
 	 */
-	tmp = _lookup_address_cpa(cpa, address, &level);
+	tmp = _lookup_address_cpa(cpa, address, &level, &nx, &rw);
 	if (tmp != kpte)
 		return 1;
 
@@ -965,7 +1001,8 @@
 	new_prot = static_protections(req_prot, lpaddr, old_pfn, numpages,
 				      psize, CPA_DETECT);
 
-	new_prot = verify_rwx(old_prot, new_prot, lpaddr, old_pfn, numpages);
+	new_prot = verify_rwx(old_prot, new_prot, lpaddr, old_pfn, numpages,
+			      nx, rw);
 
 	/*
 	 * If there is a conflict, split the large page.
@@ -1046,6 +1083,7 @@
 	pte_t *pbase = (pte_t *)page_address(base);
 	unsigned int i, level;
 	pgprot_t ref_prot;
+	bool nx, rw;
 	pte_t *tmp;
 
 	spin_lock(&pgd_lock);
@@ -1053,7 +1091,7 @@
 	 * Check for races, another CPU might have split this page
 	 * up for us already:
 	 */
-	tmp = _lookup_address_cpa(cpa, address, &level);
+	tmp = _lookup_address_cpa(cpa, address, &level, &nx, &rw);
 	if (tmp != kpte) {
 		spin_unlock(&pgd_lock);
 		return 1;
@@ -1278,7 +1316,7 @@
 	 */
 	while (end - start >= PUD_SIZE) {
 
-		if (pud_large(*pud))
+		if (pud_leaf(*pud))
 			pud_clear(pud);
 		else
 			unmap_pmd_range(pud, start, start + PUD_SIZE);
@@ -1594,10 +1632,11 @@
 	int do_split, err;
 	unsigned int level;
 	pte_t *kpte, old_pte;
+	bool nx, rw;
 
 	address = __cpa_addr(cpa, cpa->curpage);
 repeat:
-	kpte = _lookup_address_cpa(cpa, address, &level);
+	kpte = _lookup_address_cpa(cpa, address, &level, &nx, &rw);
 	if (!kpte)
 		return __cpa_process_fault(cpa, address, primary);
 
@@ -1619,7 +1658,8 @@
 		new_prot = static_protections(new_prot, address, pfn, 1, 0,
 					      CPA_PROTECT);
 
-		new_prot = verify_rwx(old_prot, new_prot, address, pfn, 1);
+		new_prot = verify_rwx(old_prot, new_prot, address, pfn, 1,
+				      nx, rw);
 
 		new_prot = pgprot_clear_protnone_bits(new_prot);
 
@@ -2156,8 +2196,9 @@
 		cpa_flush(&cpa, x86_platform.guest.enc_cache_flush_required());
 
 	/* Notify hypervisor that we are about to set/clr encryption attribute. */
-	if (!x86_platform.guest.enc_status_change_prepare(addr, numpages, enc))
-		return -EIO;
+	ret = x86_platform.guest.enc_status_change_prepare(addr, numpages, enc);
+	if (ret)
+		goto vmm_fail;
 
 	ret = __change_page_attr_set_clr(&cpa, 1);
 
@@ -2170,21 +2211,65 @@
 	 */
 	cpa_flush(&cpa, 0);
 
+	if (ret)
+		return ret;
+
 	/* Notify hypervisor that we have successfully set/clr encryption attribute. */
-	if (!ret) {
-		if (!x86_platform.guest.enc_status_change_finish(addr, numpages, enc))
-			ret = -EIO;
-	}
+	ret = x86_platform.guest.enc_status_change_finish(addr, numpages, enc);
+	if (ret)
+		goto vmm_fail;
+
+	return 0;
+
+vmm_fail:
+	WARN_ONCE(1, "CPA VMM failure to convert memory (addr=%p, numpages=%d) to %s: %d\n",
+		  (void *)addr, numpages, enc ? "private" : "shared", ret);
 
 	return ret;
 }
 
+/*
+ * The lock serializes conversions between private and shared memory.
+ *
+ * It is taken for read on conversion. A write lock guarantees that no
+ * concurrent conversions are in progress.
+ */
+static DECLARE_RWSEM(mem_enc_lock);
+
+/*
+ * Stop new private<->shared conversions.
+ *
+ * Taking the exclusive mem_enc_lock waits for in-flight conversions to complete.
+ * The lock is not released to prevent new conversions from being started.
+ */
+bool set_memory_enc_stop_conversion(void)
+{
+	/*
+	 * In a crash scenario, sleep is not allowed. Try to take the lock.
+	 * Failure indicates that there is a race with the conversion.
+	 */
+	if (oops_in_progress)
+		return down_write_trylock(&mem_enc_lock);
+
+	down_write(&mem_enc_lock);
+
+	return true;
+}
+
 static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)
 {
-	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
-		return __set_memory_enc_pgtable(addr, numpages, enc);
+	int ret = 0;
 
-	return 0;
+	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
+		if (!down_read_trylock(&mem_enc_lock))
+			return -EBUSY;
+
+		ret = __set_memory_enc_pgtable(addr, numpages, enc);
+
+		up_read(&mem_enc_lock);
+	}
+
+	return ret;
 }
 
 int set_memory_encrypted(unsigned long addr, int numpages)
--- linux-qcom-6.8.0.orig/arch/x86/mm/pgtable.c
+++ linux-qcom-6.8.0/arch/x86/mm/pgtable.c
@@ -631,6 +631,8 @@
 pmd_t pmdp_invalidate_ad(struct vm_area_struct *vma, unsigned long address,
 			 pmd_t *pmdp)
 {
+	VM_WARN_ON_ONCE(!pmd_present(*pmdp));
+
 	/*
 	 * No flush is necessary. Once an invalid PTE is established, the PTE's
 	 * access and dirty bits cannot be updated.
@@ -777,7 +779,7 @@
  */
 int pud_clear_huge(pud_t *pud)
 {
-	if (pud_large(*pud)) {
+	if (pud_leaf(*pud)) {
 		pud_clear(pud);
 		return 1;
 	}
--- linux-qcom-6.8.0.orig/arch/x86/mm/pti.c
+++ linux-qcom-6.8.0/arch/x86/mm/pti.c
@@ -132,7 +132,7 @@
 	 * Top-level entries added to init_mm's usermode pgd after boot
 	 * will not be automatically propagated to other mms.
 	 */
-	if (!pgdp_maps_userspace(pgdp))
+	if (!pgdp_maps_userspace(pgdp) || (pgd.pgd & _PAGE_NOPTISHADOW))
 		return pgd;
 
 	/*
@@ -217,7 +217,7 @@
 
 	pud = pud_offset(p4d, address);
 	/* The user page tables do not use large mappings: */
-	if (pud_large(*pud)) {
+	if (pud_leaf(*pud)) {
 		WARN_ON(1);
 		return NULL;
 	}
@@ -241,7 +241,7 @@
  *
  * Returns a pointer to a PTE on success, or NULL on failure.
  */
-static pte_t *pti_user_pagetable_walk_pte(unsigned long address)
+static pte_t *pti_user_pagetable_walk_pte(unsigned long address, bool late_text)
 {
 	gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO);
 	pmd_t *pmd;
@@ -251,10 +251,15 @@
 	if (!pmd)
 		return NULL;
 
-	/* We can't do anything sensible if we hit a large mapping. */
+	/* Large PMD mapping found */
 	if (pmd_large(*pmd)) {
-		WARN_ON(1);
-		return NULL;
+		/* Clear the PMD if we hit a large mapping from the first round */
+		if (late_text) {
+			set_pmd(pmd, __pmd(0));
+		} else {
+			WARN_ON_ONCE(1);
+			return NULL;
+		}
 	}
 
 	if (pmd_none(*pmd)) {
@@ -283,7 +288,7 @@
 	if (!pte || WARN_ON(level != PG_LEVEL_4K) || pte_none(*pte))
 		return;
 
-	target_pte = pti_user_pagetable_walk_pte(VSYSCALL_ADDR);
+	target_pte = pti_user_pagetable_walk_pte(VSYSCALL_ADDR, false);
 	if (WARN_ON(!target_pte))
 		return;
 
@@ -301,7 +306,7 @@
 
 static void
 pti_clone_pgtable(unsigned long start, unsigned long end,
-		  enum pti_clone_level level)
+		  enum pti_clone_level level, bool late_text)
 {
 	unsigned long addr;
 
@@ -374,14 +379,14 @@
 			 */
 			*target_pmd = *pmd;
 
-			addr += PMD_SIZE;
+			addr = round_up(addr + 1, PMD_SIZE);
 
 		} else if (level == PTI_CLONE_PTE) {
 
 			/* Walk the page-table down to the pte level */
 			pte = pte_offset_kernel(pmd, addr);
 			if (pte_none(*pte)) {
-				addr += PAGE_SIZE;
+				addr = round_up(addr + 1, PAGE_SIZE);
 				continue;
 			}
 
@@ -390,7 +395,7 @@
 				return;
 
 			/* Allocate PTE in the user page-table */
-			target_pte = pti_user_pagetable_walk_pte(addr);
+			target_pte = pti_user_pagetable_walk_pte(addr, late_text);
 			if (WARN_ON(!target_pte))
 				return;
 
@@ -401,7 +406,7 @@
 			/* Clone the PTE */
 			*target_pte = *pte;
 
-			addr += PAGE_SIZE;
+			addr = round_up(addr + 1, PAGE_SIZE);
 
 		} else {
 			BUG();
@@ -452,7 +457,7 @@
 		phys_addr_t pa = per_cpu_ptr_to_phys((void *)va);
 		pte_t *target_pte;
 
-		target_pte = pti_user_pagetable_walk_pte(va);
+		target_pte = pti_user_pagetable_walk_pte(va, false);
 		if (WARN_ON(!target_pte))
 			return;
 
@@ -475,7 +480,7 @@
 	start = CPU_ENTRY_AREA_BASE;
 	end   = start + (PAGE_SIZE * CPU_ENTRY_AREA_PAGES);
 
-	pti_clone_pgtable(start, end, PTI_CLONE_PMD);
+	pti_clone_pgtable(start, end, PTI_CLONE_PMD, false);
 }
 #endif /* CONFIG_X86_64 */
 
@@ -492,11 +497,11 @@
 /*
  * Clone the populated PMDs of the entry text and force it RO.
  */
-static void pti_clone_entry_text(void)
+static void pti_clone_entry_text(bool late)
 {
 	pti_clone_pgtable((unsigned long) __entry_text_start,
 			  (unsigned long) __entry_text_end,
-			  PTI_CLONE_PMD);
+			  PTI_LEVEL_KERNEL_IMAGE, late);
 }
 
 /*
@@ -571,7 +576,7 @@
 	 * pti_set_kernel_image_nonglobal() did to clear the
 	 * global bit.
 	 */
-	pti_clone_pgtable(start, end_clone, PTI_LEVEL_KERNEL_IMAGE);
+	pti_clone_pgtable(start, end_clone, PTI_LEVEL_KERNEL_IMAGE, false);
 
 	/*
 	 * pti_clone_pgtable() will set the global bit in any PMDs
@@ -638,8 +643,15 @@
 
 	/* Undo all global bits from the init pagetables in head_64.S: */
 	pti_set_kernel_image_nonglobal();
+
 	/* Replace some of the global bits just for shared entry text: */
-	pti_clone_entry_text();
+	/*
+	 * This is very early in boot. Device and Late initcalls can do
+	 * modprobe before free_initmem() and mark_readonly(). This
+	 * pti_clone_entry_text() allows those user-mode-helpers to function,
+	 * but notably the text is still RW.
+	 */
+	pti_clone_entry_text(false);
 	pti_setup_espfix64();
 	pti_setup_vsyscall();
 }
@@ -656,10 +668,11 @@
 	if (!boot_cpu_has(X86_FEATURE_PTI))
 		return;
 	/*
-	 * We need to clone everything (again) that maps parts of the
-	 * kernel image.
+	 * This is after free_initmem() (all initcalls are done) and we've done
+	 * mark_readonly(). Text is now NX which might've split some PMDs
+	 * relative to the early clone.
 	 */
-	pti_clone_entry_text();
+	pti_clone_entry_text(true);
 	pti_clone_kernel_text();
 
 	debug_checkwx_user();
--- linux-qcom-6.8.0.orig/arch/x86/mm/tlb.c
+++ linux-qcom-6.8.0/arch/x86/mm/tlb.c
@@ -19,6 +19,7 @@
 #include <asm/cacheflush.h>
 #include <asm/apic.h>
 #include <asm/perf_event.h>
+#include <asm/tlb.h>
 
 #include "mm_internal.h"
 
@@ -497,9 +498,9 @@
 {
 	struct mm_struct *real_prev = this_cpu_read(cpu_tlbstate.loaded_mm);
 	u16 prev_asid = this_cpu_read(cpu_tlbstate.loaded_mm_asid);
-	unsigned long new_lam = mm_lam_cr3_mask(next);
 	bool was_lazy = this_cpu_read(cpu_tlbstate_shared.is_lazy);
 	unsigned cpu = smp_processor_id();
+	unsigned long new_lam;
 	u64 next_tlb_gen;
 	bool need_flush;
 	u16 new_asid;
@@ -622,9 +623,7 @@
 			cpumask_clear_cpu(cpu, mm_cpumask(real_prev));
 		}
 
-		/*
-		 * Start remote flushes and then read tlb_gen.
-		 */
+		/* Start receiving IPIs and then read tlb_gen (and LAM below) */
 		if (next != &init_mm)
 			cpumask_set_cpu(cpu, mm_cpumask(next));
 		next_tlb_gen = atomic64_read(&next->context.tlb_gen);
@@ -636,6 +635,7 @@
 		barrier();
 	}
 
+	new_lam = mm_lam_cr3_mask(next);
 	set_tlbstate_lam_mode(next);
 	if (need_flush) {
 		this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id);
@@ -1146,7 +1146,7 @@
 	bool cpu_pcide;
 
 	/* Flush 'addr' from the kernel PCID: */
-	asm volatile("invlpg (%0)" ::"r" (addr) : "memory");
+	invlpg(addr);
 
 	/* If PTI is off there is no user PCID and nothing to flush. */
 	if (!static_cpu_has(X86_FEATURE_PTI))
--- linux-qcom-6.8.0.orig/arch/x86/net/bpf_jit_comp.c
+++ linux-qcom-6.8.0/arch/x86/net/bpf_jit_comp.c
@@ -64,6 +64,56 @@
 	return value <= 127 && value >= -128;
 }
 
+/*
+ * Let us limit the positive offset to be <= 123.
+ * This is to ensure eventual jit convergence For the following patterns:
+ * ...
+ * pass4, final_proglen=4391:
+ *   ...
+ *   20e:    48 85 ff                test   rdi,rdi
+ *   211:    74 7d                   je     0x290
+ *   213:    48 8b 77 00             mov    rsi,QWORD PTR [rdi+0x0]
+ *   ...
+ *   289:    48 85 ff                test   rdi,rdi
+ *   28c:    74 17                   je     0x2a5
+ *   28e:    e9 7f ff ff ff          jmp    0x212
+ *   293:    bf 03 00 00 00          mov    edi,0x3
+ * Note that insn at 0x211 is 2-byte cond jump insn for offset 0x7d (-125)
+ * and insn at 0x28e is 5-byte jmp insn with offset -129.
+ *
+ * pass5, final_proglen=4392:
+ *   ...
+ *   20e:    48 85 ff                test   rdi,rdi
+ *   211:    0f 84 80 00 00 00       je     0x297
+ *   217:    48 8b 77 00             mov    rsi,QWORD PTR [rdi+0x0]
+ *   ...
+ *   28d:    48 85 ff                test   rdi,rdi
+ *   290:    74 1a                   je     0x2ac
+ *   292:    eb 84                   jmp    0x218
+ *   294:    bf 03 00 00 00          mov    edi,0x3
+ * Note that insn at 0x211 is 6-byte cond jump insn now since its offset
+ * becomes 0x80 based on previous round (0x293 - 0x213 = 0x80).
+ * At the same time, insn at 0x292 is a 2-byte insn since its offset is
+ * -124.
+ *
+ * pass6 will repeat the same code as in pass4 and this will prevent
+ * eventual convergence.
+ *
+ * To fix this issue, we need to break je (2->6 bytes) <-> jmp (5->2 bytes)
+ * cycle in the above. In the above example je offset <= 0x7c should work.
+ *
+ * For other cases, je <-> je needs offset <= 0x7b to avoid no convergence
+ * issue. For jmp <-> je and jmp <-> jmp cases, jmp offset <= 0x7c should
+ * avoid no convergence issue.
+ *
+ * Overall, let us limit the positive offset for 8bit cond/uncond jmp insn
+ * to maximum 123 (0x7b). This way, the jit pass can eventually converge.
+ */
+static bool is_imm8_jmp_offset(int value)
+{
+	return value <= 123 && value >= -128;
+}
+
 static bool is_simm32(s64 value)
 {
 	return value == (s64)(s32)value;
@@ -259,7 +309,7 @@
 /* Number of bytes emit_patch() needs to generate instructions */
 #define X86_PATCH_SIZE		5
 /* Number of bytes that will be skipped on tailcall */
-#define X86_TAIL_CALL_OFFSET	(11 + ENDBR_INSN_SIZE)
+#define X86_TAIL_CALL_OFFSET	(12 + ENDBR_INSN_SIZE)
 
 static void push_r12(u8 **pprog)
 {
@@ -389,6 +439,37 @@
 	*pprog = prog;
 }
 
+static void emit_prologue_tail_call(u8 **pprog, bool is_subprog)
+{
+	u8 *prog = *pprog;
+
+	if (!is_subprog) {
+		/* cmp rax, MAX_TAIL_CALL_CNT */
+		EMIT4(0x48, 0x83, 0xF8, MAX_TAIL_CALL_CNT);
+		EMIT2(X86_JA, 6);        /* ja 6 */
+		/* rax is tail_call_cnt if <= MAX_TAIL_CALL_CNT.
+		 * case1: entry of main prog.
+		 * case2: tail callee of main prog.
+		 */
+		EMIT1(0x50);             /* push rax */
+		/* Make rax as tail_call_cnt_ptr. */
+		EMIT3(0x48, 0x89, 0xE0); /* mov rax, rsp */
+		EMIT2(0xEB, 1);          /* jmp 1 */
+		/* rax is tail_call_cnt_ptr if > MAX_TAIL_CALL_CNT.
+		 * case: tail callee of subprog.
+		 */
+		EMIT1(0x50);             /* push rax */
+		/* push tail_call_cnt_ptr */
+		EMIT1(0x50);             /* push rax */
+	} else { /* is_subprog */
+		/* rax is tail_call_cnt_ptr. */
+		EMIT1(0x50);             /* push rax */
+		EMIT1(0x50);             /* push rax */
+	}
+
+	*pprog = prog;
+}
+
 /*
  * Emit x86-64 prologue code for BPF program.
  * bpf_tail_call helper will skip the first X86_TAIL_CALL_OFFSET bytes
@@ -410,10 +491,10 @@
 			/* When it's the entry of the whole tailcall context,
 			 * zeroing rax means initialising tail_call_cnt.
 			 */
-			EMIT2(0x31, 0xC0); /* xor eax, eax */
+			EMIT3(0x48, 0x31, 0xC0); /* xor rax, rax */
 		else
 			/* Keep the same instruction layout. */
-			EMIT2(0x66, 0x90); /* nop2 */
+			emit_nops(&prog, 3);     /* nop3 */
 	}
 	/* Exception callback receives FP as third parameter */
 	if (is_exception_cb) {
@@ -439,7 +520,7 @@
 	if (stack_depth)
 		EMIT3_off32(0x48, 0x81, 0xEC, round_up(stack_depth, 8));
 	if (tail_call_reachable)
-		EMIT1(0x50);         /* push rax */
+		emit_prologue_tail_call(&prog, is_subprog);
 	*pprog = prog;
 }
 
@@ -466,7 +547,7 @@
 static int emit_rsb_call(u8 **pprog, void *func, void *ip)
 {
 	OPTIMIZER_HIDE_VAR(func);
-	x86_call_depth_emit_accounting(pprog, func);
+	ip += x86_call_depth_emit_accounting(pprog, func);
 	return emit_patch(pprog, func, ip, 0xE8);
 }
 
@@ -575,13 +656,15 @@
 	*pprog = prog;
 }
 
+#define BPF_TAIL_CALL_CNT_PTR_STACK_OFF(stack)	(-16 - round_up(stack, 8))
+
 /*
  * Generate the following code:
  *
  * ... bpf_tail_call(void *ctx, struct bpf_array *array, u64 index) ...
  *   if (index >= array->map.max_entries)
  *     goto out;
- *   if (tail_call_cnt++ >= MAX_TAIL_CALL_CNT)
+ *   if ((*tcc_ptr)++ >= MAX_TAIL_CALL_CNT)
  *     goto out;
  *   prog = array->ptrs[index];
  *   if (prog == NULL)
@@ -594,7 +677,7 @@
 					u32 stack_depth, u8 *ip,
 					struct jit_context *ctx)
 {
-	int tcc_off = -4 - round_up(stack_depth, 8);
+	int tcc_ptr_off = BPF_TAIL_CALL_CNT_PTR_STACK_OFF(stack_depth);
 	u8 *prog = *pprog, *start = *pprog;
 	int offset;
 
@@ -616,16 +699,14 @@
 	EMIT2(X86_JBE, offset);                   /* jbe out */
 
 	/*
-	 * if (tail_call_cnt++ >= MAX_TAIL_CALL_CNT)
+	 * if ((*tcc_ptr)++ >= MAX_TAIL_CALL_CNT)
 	 *	goto out;
 	 */
-	EMIT2_off32(0x8B, 0x85, tcc_off);         /* mov eax, dword ptr [rbp - tcc_off] */
-	EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT);     /* cmp eax, MAX_TAIL_CALL_CNT */
+	EMIT3_off32(0x48, 0x8B, 0x85, tcc_ptr_off); /* mov rax, qword ptr [rbp - tcc_ptr_off] */
+	EMIT4(0x48, 0x83, 0x38, MAX_TAIL_CALL_CNT); /* cmp qword ptr [rax], MAX_TAIL_CALL_CNT */
 
 	offset = ctx->tail_call_indirect_label - (prog + 2 - start);
 	EMIT2(X86_JAE, offset);                   /* jae out */
-	EMIT3(0x83, 0xC0, 0x01);                  /* add eax, 1 */
-	EMIT2_off32(0x89, 0x85, tcc_off);         /* mov dword ptr [rbp - tcc_off], eax */
 
 	/* prog = array->ptrs[index]; */
 	EMIT4_off32(0x48, 0x8B, 0x8C, 0xD6,       /* mov rcx, [rsi + rdx * 8 + offsetof(...)] */
@@ -640,6 +721,9 @@
 	offset = ctx->tail_call_indirect_label - (prog + 2 - start);
 	EMIT2(X86_JE, offset);                    /* je out */
 
+	/* Inc tail_call_cnt if the slot is populated. */
+	EMIT4(0x48, 0x83, 0x00, 0x01);            /* add qword ptr [rax], 1 */
+
 	if (bpf_prog->aux->exception_boundary) {
 		pop_callee_regs(&prog, all_callee_regs_used);
 		pop_r12(&prog);
@@ -647,6 +731,11 @@
 		pop_callee_regs(&prog, callee_regs_used);
 	}
 
+	/* Pop tail_call_cnt_ptr. */
+	EMIT1(0x58);                              /* pop rax */
+	/* Pop tail_call_cnt, if it's main prog.
+	 * Pop tail_call_cnt_ptr, if it's subprog.
+	 */
 	EMIT1(0x58);                              /* pop rax */
 	if (stack_depth)
 		EMIT3_off32(0x48, 0x81, 0xC4,     /* add rsp, sd */
@@ -675,21 +764,19 @@
 				      bool *callee_regs_used, u32 stack_depth,
 				      struct jit_context *ctx)
 {
-	int tcc_off = -4 - round_up(stack_depth, 8);
+	int tcc_ptr_off = BPF_TAIL_CALL_CNT_PTR_STACK_OFF(stack_depth);
 	u8 *prog = *pprog, *start = *pprog;
 	int offset;
 
 	/*
-	 * if (tail_call_cnt++ >= MAX_TAIL_CALL_CNT)
+	 * if ((*tcc_ptr)++ >= MAX_TAIL_CALL_CNT)
 	 *	goto out;
 	 */
-	EMIT2_off32(0x8B, 0x85, tcc_off);             /* mov eax, dword ptr [rbp - tcc_off] */
-	EMIT3(0x83, 0xF8, MAX_TAIL_CALL_CNT);         /* cmp eax, MAX_TAIL_CALL_CNT */
+	EMIT3_off32(0x48, 0x8B, 0x85, tcc_ptr_off);   /* mov rax, qword ptr [rbp - tcc_ptr_off] */
+	EMIT4(0x48, 0x83, 0x38, MAX_TAIL_CALL_CNT);   /* cmp qword ptr [rax], MAX_TAIL_CALL_CNT */
 
 	offset = ctx->tail_call_direct_label - (prog + 2 - start);
 	EMIT2(X86_JAE, offset);                       /* jae out */
-	EMIT3(0x83, 0xC0, 0x01);                      /* add eax, 1 */
-	EMIT2_off32(0x89, 0x85, tcc_off);             /* mov dword ptr [rbp - tcc_off], eax */
 
 	poke->tailcall_bypass = ip + (prog - start);
 	poke->adj_off = X86_TAIL_CALL_OFFSET;
@@ -699,6 +786,9 @@
 	emit_jump(&prog, (u8 *)poke->tailcall_target + X86_PATCH_SIZE,
 		  poke->tailcall_bypass);
 
+	/* Inc tail_call_cnt if the slot is populated. */
+	EMIT4(0x48, 0x83, 0x00, 0x01);                /* add qword ptr [rax], 1 */
+
 	if (bpf_prog->aux->exception_boundary) {
 		pop_callee_regs(&prog, all_callee_regs_used);
 		pop_r12(&prog);
@@ -706,6 +796,11 @@
 		pop_callee_regs(&prog, callee_regs_used);
 	}
 
+	/* Pop tail_call_cnt_ptr. */
+	EMIT1(0x58);                                  /* pop rax */
+	/* Pop tail_call_cnt, if it's main prog.
+	 * Pop tail_call_cnt_ptr, if it's subprog.
+	 */
 	EMIT1(0x58);                                  /* pop rax */
 	if (stack_depth)
 		EMIT3_off32(0x48, 0x81, 0xC4, round_up(stack_depth, 8));
@@ -1133,9 +1228,11 @@
 
 #define INSN_SZ_DIFF (((addrs[i] - addrs[i - 1]) - (prog - temp)))
 
-/* mov rax, qword ptr [rbp - rounded_stack_depth - 8] */
-#define RESTORE_TAIL_CALL_CNT(stack)				\
-	EMIT3_off32(0x48, 0x8B, 0x85, -round_up(stack, 8) - 8)
+#define __LOAD_TCC_PTR(off)			\
+	EMIT3_off32(0x48, 0x8B, 0x85, off)
+/* mov rax, qword ptr [rbp - rounded_stack_depth - 16] */
+#define LOAD_TAIL_CALL_CNT_PTR(stack)				\
+	__LOAD_TCC_PTR(BPF_TAIL_CALL_CNT_PTR_STACK_OFF(stack))
 
 static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image,
 		  int oldproglen, struct jit_context *ctx, bool jmp_padding)
@@ -1585,36 +1682,41 @@
 			if (BPF_MODE(insn->code) == BPF_PROBE_MEM ||
 			    BPF_MODE(insn->code) == BPF_PROBE_MEMSX) {
 				/* Conservatively check that src_reg + insn->off is a kernel address:
-				 *   src_reg + insn->off >= TASK_SIZE_MAX + PAGE_SIZE
-				 * src_reg is used as scratch for src_reg += insn->off and restored
-				 * after emit_ldx if necessary
+				 *   src_reg + insn->off > TASK_SIZE_MAX + PAGE_SIZE
+				 *   and
+				 *   src_reg + insn->off < VSYSCALL_ADDR
 				 */
 
-				u64 limit = TASK_SIZE_MAX + PAGE_SIZE;
+				u64 limit = TASK_SIZE_MAX + PAGE_SIZE - VSYSCALL_ADDR;
 				u8 *end_of_jmp;
 
-				/* At end of these emitted checks, insn->off will have been added
-				 * to src_reg, so no need to do relative load with insn->off offset
-				 */
-				insn_off = 0;
+				/* movabsq r10, VSYSCALL_ADDR */
+				emit_mov_imm64(&prog, BPF_REG_AX, (long)VSYSCALL_ADDR >> 32,
+					       (u32)(long)VSYSCALL_ADDR);
 
-				/* movabsq r11, limit */
-				EMIT2(add_1mod(0x48, AUX_REG), add_1reg(0xB8, AUX_REG));
-				EMIT((u32)limit, 4);
-				EMIT(limit >> 32, 4);
+				/* mov src_reg, r11 */
+				EMIT_mov(AUX_REG, src_reg);
 
 				if (insn->off) {
-					/* add src_reg, insn->off */
-					maybe_emit_1mod(&prog, src_reg, true);
-					EMIT2_off32(0x81, add_1reg(0xC0, src_reg), insn->off);
+					/* add r11, insn->off */
+					maybe_emit_1mod(&prog, AUX_REG, true);
+					EMIT2_off32(0x81, add_1reg(0xC0, AUX_REG), insn->off);
 				}
 
-				/* cmp src_reg, r11 */
-				maybe_emit_mod(&prog, src_reg, AUX_REG, true);
-				EMIT2(0x39, add_2reg(0xC0, src_reg, AUX_REG));
+				/* sub r11, r10 */
+				maybe_emit_mod(&prog, AUX_REG, BPF_REG_AX, true);
+				EMIT2(0x29, add_2reg(0xC0, AUX_REG, BPF_REG_AX));
+
+				/* movabsq r10, limit */
+				emit_mov_imm64(&prog, BPF_REG_AX, (long)limit >> 32,
+					       (u32)(long)limit);
+
+				/* cmp r10, r11 */
+				maybe_emit_mod(&prog, AUX_REG, BPF_REG_AX, true);
+				EMIT2(0x39, add_2reg(0xC0, AUX_REG, BPF_REG_AX));
 
-				/* if unsigned '>=', goto load */
-				EMIT2(X86_JAE, 0);
+				/* if unsigned '>', goto load */
+				EMIT2(X86_JA, 0);
 				end_of_jmp = prog;
 
 				/* xor dst_reg, dst_reg */
@@ -1640,18 +1742,6 @@
 				/* populate jmp_offset for JMP above */
 				start_of_ldx[-1] = prog - start_of_ldx;
 
-				if (insn->off && src_reg != dst_reg) {
-					/* sub src_reg, insn->off
-					 * Restore src_reg after "add src_reg, insn->off" in prev
-					 * if statement. But if src_reg == dst_reg, emit_ldx
-					 * above already clobbered src_reg, so no need to restore.
-					 * If add src_reg, insn->off was unnecessary, no need to
-					 * restore either.
-					 */
-					maybe_emit_1mod(&prog, src_reg, true);
-					EMIT2_off32(0x81, add_1reg(0xE8, src_reg), insn->off);
-				}
-
 				if (!bpf_prog->aux->extable)
 					break;
 
@@ -1754,7 +1844,7 @@
 
 			func = (u8 *) __bpf_call_base + imm32;
 			if (tail_call_reachable) {
-				RESTORE_TAIL_CALL_CNT(bpf_prog->aux->stack_depth);
+				LOAD_TAIL_CALL_CNT_PTR(bpf_prog->aux->stack_depth);
 				if (!imm32)
 					return -EINVAL;
 				offs = 7 + x86_call_depth_emit_accounting(&prog, func);
@@ -1910,7 +2000,7 @@
 				return -EFAULT;
 			}
 			jmp_offset = addrs[i + insn->off] - addrs[i];
-			if (is_imm8(jmp_offset)) {
+			if (is_imm8_jmp_offset(jmp_offset)) {
 				if (jmp_padding) {
 					/* To keep the jmp_offset valid, the extra bytes are
 					 * padded before the jump insn, so we subtract the
@@ -1992,7 +2082,7 @@
 				break;
 			}
 emit_jmp:
-			if (is_imm8(jmp_offset)) {
+			if (is_imm8_jmp_offset(jmp_offset)) {
 				if (jmp_padding) {
 					/* To avoid breaking jmp_offset, the extra bytes
 					 * are padded before the actual jmp insn, so
@@ -2430,6 +2520,10 @@
 	return 0;
 }
 
+/* mov rax, qword ptr [rbp - rounded_stack_depth - 8] */
+#define LOAD_TRAMP_TAIL_CALL_CNT_PTR(stack)	\
+	__LOAD_TCC_PTR(-round_up(stack, 8) - 8)
+
 /* Example:
  * __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev);
  * its 'struct btf_func_model' will be nr_args=2
@@ -2550,7 +2644,7 @@
 	 *                     [ ...        ]
 	 *                     [ stack_arg2 ]
 	 * RBP - arg_stack_off [ stack_arg1 ]
-	 * RSP                 [ tail_call_cnt ] BPF_TRAMP_F_TAIL_CALL_CTX
+	 * RSP                 [ tail_call_cnt_ptr ] BPF_TRAMP_F_TAIL_CALL_CTX
 	 */
 
 	/* room for return value of orig_call or fentry prog */
@@ -2679,10 +2773,10 @@
 		save_args(m, &prog, arg_stack_off, true);
 
 		if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) {
-			/* Before calling the original function, restore the
-			 * tail_call_cnt from stack to rax.
+			/* Before calling the original function, load the
+			 * tail_call_cnt_ptr from stack to rax.
 			 */
-			RESTORE_TAIL_CALL_CNT(stack_size);
+			LOAD_TRAMP_TAIL_CALL_CNT_PTR(stack_size);
 		}
 
 		if (flags & BPF_TRAMP_F_ORIG_STACK) {
@@ -2741,10 +2835,10 @@
 			goto cleanup;
 		}
 	} else if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) {
-		/* Before running the original function, restore the
-		 * tail_call_cnt from stack to rax.
+		/* Before running the original function, load the
+		 * tail_call_cnt_ptr from stack to rax.
 		 */
-		RESTORE_TAIL_CALL_CNT(stack_size);
+		LOAD_TRAMP_TAIL_CALL_CNT_PTR(stack_size);
 	}
 
 	/* restore return value of orig_call or fentry prog back into RAX */
--- linux-qcom-6.8.0.orig/arch/x86/net/bpf_jit_comp32.c
+++ linux-qcom-6.8.0/arch/x86/net/bpf_jit_comp32.c
@@ -2600,8 +2600,7 @@
 	if (bpf_jit_enable > 1)
 		bpf_jit_dump(prog->len, proglen, pass + 1, image);
 
-	if (image) {
-		bpf_jit_binary_lock_ro(header);
+	if (image && !bpf_jit_binary_lock_ro(header)) {
 		prog->bpf_func = (void *)image;
 		prog->jited = 1;
 		prog->jited_len = proglen;
--- linux-qcom-6.8.0.orig/arch/x86/pci/acpi.c
+++ linux-qcom-6.8.0/arch/x86/pci/acpi.c
@@ -250,6 +250,125 @@
 		pr_info("Please notify linux-pci@vger.kernel.org so future kernels can do this automatically\n");
 }
 
+/*
+ * Check if pdev is part of a PCIe switch that is directly below the
+ * specified bridge.
+ */
+static bool pcie_switch_directly_under(struct pci_dev *bridge,
+				       struct pci_dev *pdev)
+{
+	struct pci_dev *parent = pci_upstream_bridge(pdev);
+
+	/* If the device doesn't have a parent, it's not under anything */
+	if (!parent)
+		return false;
+
+	/*
+	 * If the device has a PCIe type, check if it is below the
+	 * corresponding PCIe switch components (if applicable). Then check
+	 * if its upstream port is directly beneath the specified bridge.
+	 */
+	switch (pci_pcie_type(pdev)) {
+	case PCI_EXP_TYPE_UPSTREAM:
+		return parent == bridge;
+
+	case PCI_EXP_TYPE_DOWNSTREAM:
+		if (pci_pcie_type(parent) != PCI_EXP_TYPE_UPSTREAM)
+			return false;
+		parent = pci_upstream_bridge(parent);
+		return parent == bridge;
+
+	case PCI_EXP_TYPE_ENDPOINT:
+		if (pci_pcie_type(parent) != PCI_EXP_TYPE_DOWNSTREAM)
+			return false;
+		parent = pci_upstream_bridge(parent);
+		if (!parent || pci_pcie_type(parent) != PCI_EXP_TYPE_UPSTREAM)
+			return false;
+		parent = pci_upstream_bridge(parent);
+		return parent == bridge;
+	}
+
+	return false;
+}
+
+static bool pcie_has_usb4_host_interface(struct pci_dev *pdev)
+{
+	struct fwnode_handle *fwnode;
+
+	/*
+	 * For USB4, the tunneled PCIe Root or Downstream Ports are marked
+	 * with the "usb4-host-interface" ACPI property, so we look for
+	 * that first. This should cover most cases.
+	 */
+	fwnode = fwnode_find_reference(dev_fwnode(&pdev->dev),
+				       "usb4-host-interface", 0);
+	if (!IS_ERR(fwnode)) {
+		fwnode_handle_put(fwnode);
+		return true;
+	}
+
+	/*
+	 * Any integrated Thunderbolt 3/4 PCIe Root Ports from Intel
+	 * before Alder Lake do not have the "usb4-host-interface"
+	 * property so we use their PCI IDs instead. All these are
+	 * tunneled. This list is not expected to grow.
+	 */
+	if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
+		switch (pdev->device) {
+		/* Ice Lake Thunderbolt 3 PCIe Root Ports */
+		case 0x8a1d:
+		case 0x8a1f:
+		case 0x8a21:
+		case 0x8a23:
+		/* Tiger Lake-LP Thunderbolt 4 PCIe Root Ports */
+		case 0x9a23:
+		case 0x9a25:
+		case 0x9a27:
+		case 0x9a29:
+		/* Tiger Lake-H Thunderbolt 4 PCIe Root Ports */
+		case 0x9a2b:
+		case 0x9a2d:
+		case 0x9a2f:
+		case 0x9a31:
+			return true;
+		}
+	}
+
+	return false;
+}
+
+bool arch_pci_dev_is_removable(struct pci_dev *pdev)
+{
+	struct pci_dev *parent, *root;
+
+	/* pdev without a parent or Root Port is never tunneled */
+	parent = pci_upstream_bridge(pdev);
+	if (!parent)
+		return false;
+	root = pcie_find_root_port(pdev);
+	if (!root)
+		return false;
+
+	/* Internal PCIe devices are not tunneled */
+	if (!root->external_facing)
+		return false;
+
+	/* Anything directly behind a "usb4-host-interface" is tunneled */
+	if (pcie_has_usb4_host_interface(parent))
+		return true;
+
+	/*
+	 * Check if this is a discrete Thunderbolt/USB4 controller that is
+	 * directly behind the non-USB4 PCIe Root Port marked as
+	 * "ExternalFacingPort". Those are not behind a PCIe tunnel.
+	 */
+	if (pcie_switch_directly_under(root, pdev))
+		return false;
+
+	/* PCIe devices after the discrete chip are tunneled */
+	return true;
+}
+
 #ifdef	CONFIG_PCI_MMCONFIG
 static int check_segment(u16 seg, struct device *dev, char *estr)
 {
--- linux-qcom-6.8.0.orig/arch/x86/pci/common.c
+++ linux-qcom-6.8.0/arch/x86/pci/common.c
@@ -34,6 +34,7 @@
 #endif
 int pcibios_last_bus = -1;
 unsigned long pirq_table_addr;
+unsigned int pci_early_clear_msi;
 const struct pci_raw_ops *__read_mostly raw_pci_ops;
 const struct pci_raw_ops *__read_mostly raw_pci_ext_ops;
 
@@ -614,6 +615,9 @@
 	} else if (!strcmp(str, "skip_isa_align")) {
 		pci_probe |= PCI_CAN_SKIP_ISA_ALIGN;
 		return NULL;
+	} else if (!strcmp(str, "clearmsi")) {
+		pci_early_clear_msi = 1;
+		return NULL;
 	} else if (!strcmp(str, "noioapicquirk")) {
 		noioapicquirk = 1;
 		return NULL;
--- linux-qcom-6.8.0.orig/arch/x86/pci/early.c
+++ linux-qcom-6.8.0/arch/x86/pci/early.c
@@ -51,6 +51,31 @@
 	outw(val, 0xcfc + (offset&2));
 }
 
+u32 pci_early_find_cap(int bus, int slot, int func, int cap)
+{
+	int bytes;
+	u8 pos;
+
+	if (!(read_pci_config_16(bus, slot, func, PCI_STATUS) &
+						PCI_STATUS_CAP_LIST))
+		return 0;
+
+	pos = read_pci_config_byte(bus, slot, func, PCI_CAPABILITY_LIST);
+	for (bytes = 0; bytes < 48 && pos >= 0x40; bytes++) {
+		u8 id;
+
+		pos &= ~3;
+		id = read_pci_config_byte(bus, slot, func, pos+PCI_CAP_LIST_ID);
+		if (id == 0xff)
+			break;
+		if (id == cap)
+			return pos;
+		pos = read_pci_config_byte(bus, slot, func,
+						pos+PCI_CAP_LIST_NEXT);
+	}
+	return 0;
+}
+
 int early_pci_allowed(void)
 {
 	return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) ==
--- linux-qcom-6.8.0.orig/arch/x86/pci/fixup.c
+++ linux-qcom-6.8.0/arch/x86/pci/fixup.c
@@ -907,6 +907,54 @@
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x5ad6, chromeos_save_apl_pci_l1ss_capability);
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, 0x5ad6, chromeos_fixup_apl_pci_l1ss_capability);
 
+/*
+ * Disable D3cold on Asus B1400 PCI-NVMe bridge
+ *
+ * On this platform with VMD off, the NVMe device cannot successfully power
+ * back on from D3cold. This appears to be an untested transition by the
+ * vendor: Windows leaves the NVMe and parent bridge in D0 during suspend.
+ *
+ * We disable D3cold on the parent bridge for simplicity, and the fact that
+ * both parent bridge and NVMe device share the same power resource.
+ *
+ * This is only needed on BIOS versions before 308; the newer versions flip
+ * StorageD3Enable from 1 to 0.
+ */
+static const struct dmi_system_id asus_nvme_broken_d3cold_table[] = {
+	{
+		.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+				DMI_MATCH(DMI_BIOS_VERSION, "B1400CEAE.304"),
+		},
+	},
+	{
+		.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+				DMI_MATCH(DMI_BIOS_VERSION, "B1400CEAE.305"),
+		},
+	},
+	{
+		.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+				DMI_MATCH(DMI_BIOS_VERSION, "B1400CEAE.306"),
+		},
+	},
+	{
+		.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+				DMI_MATCH(DMI_BIOS_VERSION, "B1400CEAE.307"),
+		},
+	},
+	{}
+};
+
+static void asus_disable_nvme_d3cold(struct pci_dev *pdev)
+{
+	if (dmi_check_system(asus_nvme_broken_d3cold_table) > 0)
+		pci_d3cold_disable(pdev);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x9a09, asus_disable_nvme_d3cold);
+
 #ifdef CONFIG_SUSPEND
 /*
  * Root Ports on some AMD SoCs advertise PME_Support for D3hot and D3cold, but
@@ -932,7 +980,7 @@
 		return;
 
 	rp = pcie_find_root_port(dev);
-	if (!rp->pm_cap)
+	if (!rp || !rp->pm_cap)
 		return;
 
 	rp->pme_support &= ~((PCI_PM_CAP_PME_D3hot|PCI_PM_CAP_PME_D3cold) >>
@@ -946,7 +994,7 @@
 	u16 pmc;
 
 	rp = pcie_find_root_port(dev);
-	if (!rp->pm_cap)
+	if (!rp || !rp->pm_cap)
 		return;
 
 	pci_read_config_word(rp, rp->pm_cap + PCI_PM_PMC, &pmc);
@@ -962,4 +1010,34 @@
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1668, amd_rp_pme_resume);
 DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x1669, amd_rp_pme_suspend);
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1669, amd_rp_pme_resume);
+
+/*
+ * Putting PCIe root ports on Ryzen SoCs with USB4 controllers into D3hot
+ * may cause problems when the system attempts wake up from s2idle.
+ *
+ * On the TUXEDO Sirius 16 Gen 1 with a specific old BIOS this manifests as
+ * a system hang.
+ */
+static const struct dmi_system_id quirk_tuxeo_rp_d3_dmi_table[] = {
+	{
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
+			DMI_EXACT_MATCH(DMI_BOARD_NAME, "APX958"),
+			DMI_EXACT_MATCH(DMI_BIOS_VERSION, "V1.00A00_20240108"),
+		},
+	},
+	{}
+};
+
+static void quirk_tuxeo_rp_d3(struct pci_dev *pdev)
+{
+	struct pci_dev *root_pdev;
+
+	if (dmi_check_system(quirk_tuxeo_rp_d3_dmi_table)) {
+		root_pdev = pcie_find_root_port(pdev);
+		if (root_pdev)
+			root_pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3;
+	}
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1502, quirk_tuxeo_rp_d3);
 #endif /* CONFIG_SUSPEND */
--- linux-qcom-6.8.0.orig/arch/x86/pci/intel_mid_pci.c
+++ linux-qcom-6.8.0/arch/x86/pci/intel_mid_pci.c
@@ -233,9 +233,9 @@
 		return 0;
 
 	ret = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &gsi);
-	if (ret < 0) {
+	if (ret) {
 		dev_warn(&dev->dev, "Failed to read interrupt line: %d\n", ret);
-		return ret;
+		return pcibios_err_to_errno(ret);
 	}
 
 	id = x86_match_cpu(intel_mid_cpu_ids);
--- linux-qcom-6.8.0.orig/arch/x86/pci/mmconfig-shared.c
+++ linux-qcom-6.8.0/arch/x86/pci/mmconfig-shared.c
@@ -518,7 +518,34 @@
 {
 	struct resource *conflict;
 
-	if (!early && !acpi_disabled) {
+	if (early) {
+
+		/*
+		 * Don't try to do this check unless configuration type 1
+		 * is available.  How about type 2?
+		 */
+
+		/*
+		 * 946f2ee5c731 ("Check that MCFG points to an e820
+		 * reserved area") added this E820 check in 2006 to work
+		 * around BIOS defects.
+		 *
+		 * Per PCI Firmware r3.3, sec 4.1.2, ECAM space must be
+		 * reserved by a PNP0C02 resource, but it need not be
+		 * mentioned in E820.  Before the ACPI interpreter is
+		 * available, we can't check for PNP0C02 resources, so
+		 * there's no reliable way to verify the region in this
+		 * early check.  Keep it only for the old machines that
+		 * motivated 946f2ee5c731.
+		 */
+		if (dmi_get_bios_year() < 2016 && raw_pci_ops)
+			return is_mmconf_reserved(e820__mapped_all, cfg, dev,
+						  "E820 entry");
+
+		return true;
+	}
+
+	if (!acpi_disabled) {
 		if (is_mmconf_reserved(is_acpi_reserved, cfg, dev,
 				       "ACPI motherboard resource"))
 			return true;
@@ -551,16 +578,7 @@
 	 * For MCFG information constructed from hotpluggable host bridge's
 	 * _CBA method, just assume it's reserved.
 	 */
-	if (pci_mmcfg_running_state)
-		return true;
-
-	/* Don't try to do this check unless configuration
-	   type 1 is available. how about type 2 ?*/
-	if (raw_pci_ops)
-		return is_mmconf_reserved(e820__mapped_all, cfg, dev,
-					  "E820 entry");
-
-	return false;
+	return pci_mmcfg_running_state;
 }
 
 static void __init pci_mmcfg_reject_broken(int early)
--- linux-qcom-6.8.0.orig/arch/x86/pci/xen.c
+++ linux-qcom-6.8.0/arch/x86/pci/xen.c
@@ -38,10 +38,10 @@
 	u8 gsi;
 
 	rc = pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &gsi);
-	if (rc < 0) {
+	if (rc) {
 		dev_warn(&dev->dev, "Xen PCI: failed to read interrupt line: %d\n",
 			 rc);
-		return rc;
+		return pcibios_err_to_errno(rc);
 	}
 	/* In PV DomU the Xen PCI backend puts the PIRQ in the interrupt line.*/
 	pirq = gsi;
--- linux-qcom-6.8.0.orig/arch/x86/platform/efi/memmap.c
+++ linux-qcom-6.8.0/arch/x86/platform/efi/memmap.c
@@ -92,12 +92,22 @@
  */
 int __init efi_memmap_install(struct efi_memory_map_data *data)
 {
+	unsigned long size = efi.memmap.desc_size * efi.memmap.nr_map;
+	unsigned long flags = efi.memmap.flags;
+	u64 phys = efi.memmap.phys_map;
+	int ret;
+
 	efi_memmap_unmap();
 
 	if (efi_enabled(EFI_PARAVIRT))
 		return 0;
 
-	return __efi_memmap_init(data);
+	ret = __efi_memmap_init(data);
+	if (ret)
+		return ret;
+
+	__efi_memmap_free(phys, size, flags);
+	return 0;
 }
 
 /**
--- linux-qcom-6.8.0.orig/arch/x86/platform/intel/iosf_mbi.c
+++ linux-qcom-6.8.0/arch/x86/platform/intel/iosf_mbi.c
@@ -62,7 +62,7 @@
 
 fail_read:
 	dev_err(&mbi_pdev->dev, "PCI config access failed with %d\n", result);
-	return result;
+	return pcibios_err_to_errno(result);
 }
 
 static int iosf_mbi_pci_write_mdr(u32 mcrx, u32 mcr, u32 mdr)
@@ -91,7 +91,7 @@
 
 fail_write:
 	dev_err(&mbi_pdev->dev, "PCI config access failed with %d\n", result);
-	return result;
+	return pcibios_err_to_errno(result);
 }
 
 int iosf_mbi_read(u8 port, u8 opcode, u32 offset, u32 *mdr)
--- linux-qcom-6.8.0.orig/arch/x86/platform/pvh/enlighten.c
+++ linux-qcom-6.8.0/arch/x86/platform/pvh/enlighten.c
@@ -74,6 +74,9 @@
 	} else
 		xen_raw_printk("Warning: Can fit ISA range into e820\n");
 
+	if (xen_guest)
+		xen_reserve_extra_memory(&pvh_bootparams);
+
 	pvh_bootparams.hdr.cmd_line_ptr =
 		pvh_start_info.cmdline_paddr;
 
--- linux-qcom-6.8.0.orig/arch/x86/power/hibernate.c
+++ linux-qcom-6.8.0/arch/x86/power/hibernate.c
@@ -170,7 +170,7 @@
 		goto out;
 	}
 	pud = pud_offset(p4d, relocated_restore_code);
-	if (pud_large(*pud)) {
+	if (pud_leaf(*pud)) {
 		set_pud(pud, __pud(pud_val(*pud) & ~_PAGE_NX));
 		goto out;
 	}
--- linux-qcom-6.8.0.orig/arch/x86/purgatory/Makefile
+++ linux-qcom-6.8.0/arch/x86/purgatory/Makefile
@@ -42,7 +42,8 @@
 # make up the standalone purgatory.ro
 
 PURGATORY_CFLAGS_REMOVE := -mcmodel=kernel
-PURGATORY_CFLAGS := -mcmodel=large -ffreestanding -fno-zero-initialized-in-bss -g0
+PURGATORY_CFLAGS := -mcmodel=small -ffreestanding -fno-zero-initialized-in-bss -g0
+PURGATORY_CFLAGS += -fpic -fvisibility=hidden
 PURGATORY_CFLAGS += $(DISABLE_STACKLEAK_PLUGIN) -DDISABLE_BRANCH_PROFILING
 PURGATORY_CFLAGS += -fno-stack-protector
 
--- linux-qcom-6.8.0.orig/arch/x86/tools/relocs.c
+++ linux-qcom-6.8.0/arch/x86/tools/relocs.c
@@ -653,6 +653,14 @@
 		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
 			continue;
 		}
+		/*
+		 * Do not perform relocations in .notes section; any
+		 * values there are meant for pre-boot consumption (e.g.
+		 * startup_xen).
+		 */
+		if (sec_applies->shdr.sh_type == SHT_NOTE) {
+			continue;
+		}
 		sh_symtab  = sec_symtab->symtab;
 		sym_strtab = sec_symtab->link->strtab;
 		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
@@ -738,6 +746,15 @@
 		if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) {
 			continue;
 		}
+
+		/*
+		 * Do not perform relocations in .notes sections; any
+		 * values there are meant for pre-boot consumption (e.g.
+		 * startup_xen).
+		 */
+		if (sec_applies->shdr.sh_type == SHT_NOTE)
+			continue;
+
 		sh_symtab = sec_symtab->symtab;
 		sym_strtab = sec_symtab->link->strtab;
 		for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
--- linux-qcom-6.8.0.orig/arch/x86/um/shared/sysdep/archsetjmp.h
+++ linux-qcom-6.8.0/arch/x86/um/shared/sysdep/archsetjmp.h
@@ -1,6 +1,13 @@
 /* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __X86_UM_SYSDEP_ARCHSETJMP_H
+#define __X86_UM_SYSDEP_ARCHSETJMP_H
+
 #ifdef __i386__
 #include "archsetjmp_32.h"
 #else
 #include "archsetjmp_64.h"
 #endif
+
+unsigned long get_thread_reg(int reg, jmp_buf *buf);
+
+#endif /* __X86_UM_SYSDEP_ARCHSETJMP_H */
--- linux-qcom-6.8.0.orig/arch/x86/um/sys_call_table_32.c
+++ linux-qcom-6.8.0/arch/x86/um/sys_call_table_32.c
@@ -9,6 +9,10 @@
 #include <linux/cache.h>
 #include <asm/syscall.h>
 
+extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long,
+				      unsigned long, unsigned long,
+				      unsigned long, unsigned long);
+
 /*
  * Below you can see, in terms of #define's, the differences between the x86-64
  * and the UML syscall table.
@@ -22,15 +26,13 @@
 #define sys_vm86 sys_ni_syscall
 
 #define __SYSCALL_WITH_COMPAT(nr, native, compat)	__SYSCALL(nr, native)
+#define __SYSCALL_NORETURN __SYSCALL
 
 #define __SYSCALL(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
 #include <asm/syscalls_32.h>
+#undef  __SYSCALL
 
-#undef __SYSCALL
 #define __SYSCALL(nr, sym) sym,
-
-extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
-
 const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
 #include <asm/syscalls_32.h>
 };
--- linux-qcom-6.8.0.orig/arch/x86/um/sys_call_table_64.c
+++ linux-qcom-6.8.0/arch/x86/um/sys_call_table_64.c
@@ -9,6 +9,10 @@
 #include <linux/cache.h>
 #include <asm/syscall.h>
 
+extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long,
+				      unsigned long, unsigned long,
+				      unsigned long, unsigned long);
+
 /*
  * Below you can see, in terms of #define's, the differences between the x86-64
  * and the UML syscall table.
@@ -18,14 +22,13 @@
 #define sys_iopl sys_ni_syscall
 #define sys_ioperm sys_ni_syscall
 
+#define __SYSCALL_NORETURN __SYSCALL
+
 #define __SYSCALL(nr, sym) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
 #include <asm/syscalls_64.h>
+#undef  __SYSCALL
 
-#undef __SYSCALL
 #define __SYSCALL(nr, sym) sym,
-
-extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
-
 const sys_call_ptr_t sys_call_table[] ____cacheline_aligned = {
 #include <asm/syscalls_64.h>
 };
--- linux-qcom-6.8.0.orig/arch/x86/xen/enlighten.c
+++ linux-qcom-6.8.0/arch/x86/xen/enlighten.c
@@ -5,7 +5,9 @@
 #endif
 #include <linux/console.h>
 #include <linux/cpu.h>
+#include <linux/instrumentation.h>
 #include <linux/kexec.h>
+#include <linux/memblock.h>
 #include <linux/slab.h>
 #include <linux/panic_notifier.h>
 
@@ -25,7 +27,8 @@
 #include "smp.h"
 #include "pmu.h"
 
-EXPORT_SYMBOL_GPL(hypercall_page);
+DEFINE_STATIC_CALL(xen_hypercall, xen_hypercall_hvm);
+EXPORT_STATIC_CALL_TRAMP(xen_hypercall);
 
 /*
  * Pointer to the xen_vcpu_info structure or
@@ -72,6 +75,67 @@
  */
 struct shared_info *HYPERVISOR_shared_info = &xen_dummy_shared_info;
 
+static __ref void xen_get_vendor(void)
+{
+	init_cpu_devs();
+	cpu_detect(&boot_cpu_data);
+	get_cpu_vendor(&boot_cpu_data);
+}
+
+void xen_hypercall_setfunc(void)
+{
+	if (static_call_query(xen_hypercall) != xen_hypercall_hvm)
+		return;
+
+	if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
+	     boot_cpu_data.x86_vendor == X86_VENDOR_HYGON))
+		static_call_update(xen_hypercall, xen_hypercall_amd);
+	else
+		static_call_update(xen_hypercall, xen_hypercall_intel);
+}
+
+/*
+ * Evaluate processor vendor in order to select the correct hypercall
+ * function for HVM/PVH guests.
+ * Might be called very early in boot before vendor has been set by
+ * early_cpu_init().
+ */
+noinstr void *__xen_hypercall_setfunc(void)
+{
+	void (*func)(void);
+
+	/*
+	 * Xen is supported only on CPUs with CPUID, so testing for
+	 * X86_FEATURE_CPUID is a test for early_cpu_init() having been
+	 * run.
+	 *
+	 * Note that __xen_hypercall_setfunc() is noinstr only due to a nasty
+	 * dependency chain: it is being called via the xen_hypercall static
+	 * call when running as a PVH or HVM guest. Hypercalls need to be
+	 * noinstr due to PV guests using hypercalls in noinstr code. So we
+	 * can safely tag the function body as "instrumentation ok", since
+	 * the PV guest requirement is not of interest here (xen_get_vendor()
+	 * calls noinstr functions, and static_call_update_early() might do
+	 * so, too).
+	 */
+	instrumentation_begin();
+
+	if (!boot_cpu_has(X86_FEATURE_CPUID))
+		xen_get_vendor();
+
+	if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
+	     boot_cpu_data.x86_vendor == X86_VENDOR_HYGON))
+		func = xen_hypercall_amd;
+	else
+		func = xen_hypercall_intel;
+
+	static_call_update_early(xen_hypercall, func);
+
+	instrumentation_end();
+
+	return func;
+}
+
 static int xen_cpu_up_online(unsigned int cpu)
 {
 	xen_init_lock_cpu(cpu);
@@ -350,3 +414,67 @@
 }
 EXPORT_SYMBOL(xen_arch_unregister_cpu);
 #endif
+
+/* Amount of extra memory space we add to the e820 ranges */
+struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
+
+void __init xen_add_extra_mem(unsigned long start_pfn, unsigned long n_pfns)
+{
+	unsigned int i;
+
+	/*
+	 * No need to check for zero size, should happen rarely and will only
+	 * write a new entry regarded to be unused due to zero size.
+	 */
+	for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
+		/* Add new region. */
+		if (xen_extra_mem[i].n_pfns == 0) {
+			xen_extra_mem[i].start_pfn = start_pfn;
+			xen_extra_mem[i].n_pfns = n_pfns;
+			break;
+		}
+		/* Append to existing region. */
+		if (xen_extra_mem[i].start_pfn + xen_extra_mem[i].n_pfns ==
+		    start_pfn) {
+			xen_extra_mem[i].n_pfns += n_pfns;
+			break;
+		}
+	}
+	if (i == XEN_EXTRA_MEM_MAX_REGIONS)
+		printk(KERN_WARNING "Warning: not enough extra memory regions\n");
+
+	memblock_reserve(PFN_PHYS(start_pfn), PFN_PHYS(n_pfns));
+}
+
+#ifdef CONFIG_XEN_UNPOPULATED_ALLOC
+int __init arch_xen_unpopulated_init(struct resource **res)
+{
+	unsigned int i;
+
+	if (!xen_domain())
+		return -ENODEV;
+
+	/* Must be set strictly before calling xen_free_unpopulated_pages(). */
+	*res = &iomem_resource;
+
+	/*
+	 * Initialize with pages from the extra memory regions (see
+	 * arch/x86/xen/setup.c).
+	 */
+	for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
+		unsigned int j;
+
+		for (j = 0; j < xen_extra_mem[i].n_pfns; j++) {
+			struct page *pg =
+				pfn_to_page(xen_extra_mem[i].start_pfn + j);
+
+			xen_free_unpopulated_pages(1, &pg);
+		}
+
+		/* Zero so region is not also added to the balloon driver. */
+		xen_extra_mem[i].n_pfns = 0;
+	}
+
+	return 0;
+}
+#endif
--- linux-qcom-6.8.0.orig/arch/x86/xen/enlighten_hvm.c
+++ linux-qcom-6.8.0/arch/x86/xen/enlighten_hvm.c
@@ -108,15 +108,8 @@
 	/* PVH set up hypercall page in xen_prepare_pvh(). */
 	if (xen_pvh_domain())
 		pv_info.name = "Xen PVH";
-	else {
-		u64 pfn;
-		uint32_t msr;
-
+	else
 		pv_info.name = "Xen HVM";
-		msr = cpuid_ebx(base + 2);
-		pfn = __pa(hypercall_page);
-		wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32));
-	}
 
 	xen_setup_features();
 
@@ -298,6 +291,10 @@
 	if (xen_pv_domain())
 		return 0;
 
+	/* Set correct hypercall function. */
+	if (xen_domain)
+		xen_hypercall_setfunc();
+
 	if (xen_pvh_domain() && nopv) {
 		/* Guest booting via the Xen-PVH boot entry goes here */
 		pr_info("\"nopv\" parameter is ignored in PVH guest\n");
--- linux-qcom-6.8.0.orig/arch/x86/xen/enlighten_pv.c
+++ linux-qcom-6.8.0/arch/x86/xen/enlighten_pv.c
@@ -1329,6 +1329,9 @@
 
 	xen_domain_type = XEN_PV_DOMAIN;
 	xen_start_flags = xen_start_info->flags;
+	/* Interrupts are guaranteed to be off initially. */
+	early_boot_irqs_disabled = true;
+	static_call_update_early(xen_hypercall, xen_hypercall_pv);
 
 	xen_setup_features();
 
@@ -1419,7 +1422,6 @@
 	WARN_ON(xen_cpuhp_setup(xen_cpu_up_prepare_pv, xen_cpu_dead_pv));
 
 	local_irq_disable();
-	early_boot_irqs_disabled = true;
 
 	xen_raw_console_write("mapping kernel into physical memory\n");
 	xen_setup_kernel_pagetable((pgd_t *)xen_start_info->pt_base,
--- linux-qcom-6.8.0.orig/arch/x86/xen/enlighten_pvh.c
+++ linux-qcom-6.8.0/arch/x86/xen/enlighten_pvh.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/acpi.h>
 #include <linux/export.h>
+#include <linux/mm.h>
 
 #include <xen/hvc-console.h>
 
@@ -27,17 +28,10 @@
 
 void __init xen_pvh_init(struct boot_params *boot_params)
 {
-	u32 msr;
-	u64 pfn;
-
 	xen_pvh = 1;
 	xen_domain_type = XEN_HVM_DOMAIN;
 	xen_start_flags = pvh_start_info.flags;
 
-	msr = cpuid_ebx(xen_cpuid_base() + 2);
-	pfn = __pa(hypercall_page);
-	wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32));
-
 	if (xen_initial_domain())
 		x86_init.oem.arch_setup = xen_add_preferred_consoles;
 	x86_init.oem.banner = xen_banner;
@@ -72,3 +66,70 @@
 	}
 	boot_params_p->e820_entries = memmap.nr_entries;
 }
+
+/*
+ * Reserve e820 UNUSABLE regions to inflate the memory balloon.
+ *
+ * On PVH dom0 the host memory map is used, RAM regions available to dom0 are
+ * located as the same place as in the native memory map, but since dom0 gets
+ * less memory than the total amount of host RAM the ranges that can't be
+ * populated are converted from RAM -> UNUSABLE.  Use such regions (up to the
+ * ratio signaled in EXTRA_MEM_RATIO) in order to inflate the balloon driver at
+ * boot.  Doing so prevents the guest (even if just temporary) from using holes
+ * in the memory map in order to map grants or foreign addresses, and
+ * hopefully limits the risk of a clash with a device MMIO region.  Ideally the
+ * hypervisor should notify us which memory ranges are suitable for creating
+ * foreign mappings, but that's not yet implemented.
+ */
+void __init xen_reserve_extra_memory(struct boot_params *bootp)
+{
+	unsigned int i, ram_pages = 0, extra_pages;
+
+	for (i = 0; i < bootp->e820_entries; i++) {
+		struct boot_e820_entry *e = &bootp->e820_table[i];
+
+		if (e->type != E820_TYPE_RAM)
+			continue;
+		ram_pages += PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr);
+	}
+
+	/* Max amount of extra memory. */
+	extra_pages = EXTRA_MEM_RATIO * ram_pages;
+
+	/*
+	 * Convert UNUSABLE ranges to RAM and reserve them for foreign mapping
+	 * purposes.
+	 */
+	for (i = 0; i < bootp->e820_entries && extra_pages; i++) {
+		struct boot_e820_entry *e = &bootp->e820_table[i];
+		unsigned long pages;
+
+		if (e->type != E820_TYPE_UNUSABLE)
+			continue;
+
+		pages = min(extra_pages,
+			PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr));
+
+		if (pages != (PFN_DOWN(e->addr + e->size) - PFN_UP(e->addr))) {
+			struct boot_e820_entry *next;
+
+			if (bootp->e820_entries ==
+			    ARRAY_SIZE(bootp->e820_table))
+				/* No space left to split - skip region. */
+				continue;
+
+			/* Split entry. */
+			next = e + 1;
+			memmove(next, e,
+				(bootp->e820_entries - i) * sizeof(*e));
+			bootp->e820_entries++;
+			next->addr = PAGE_ALIGN(e->addr) + PFN_PHYS(pages);
+			e->size = next->addr - e->addr;
+			next->size -= e->size;
+		}
+		e->type = E820_TYPE_RAM;
+		extra_pages -= pages;
+
+		xen_add_extra_mem(PFN_UP(e->addr), pages);
+	}
+}
--- linux-qcom-6.8.0.orig/arch/x86/xen/mmu_pv.c
+++ linux-qcom-6.8.0/arch/x86/xen/mmu_pv.c
@@ -1082,7 +1082,7 @@
 	pmd_t *pmd_tbl;
 	int i;
 
-	if (pud_large(*pud)) {
+	if (pud_leaf(*pud)) {
 		pa = pud_val(*pud) & PHYSICAL_PAGE_MASK;
 		xen_free_ro_pages(pa, PUD_SIZE);
 		return;
@@ -1863,7 +1863,7 @@
 	if (!pud_present(pud))
 		return 0;
 	pa = pud_val(pud) & PTE_PFN_MASK;
-	if (pud_large(pud))
+	if (pud_leaf(pud))
 		return pa + (vaddr & ~PUD_MASK);
 
 	pmd = native_make_pmd(xen_read_phys_ulong(pa + pmd_index(vaddr) *
@@ -2019,10 +2019,7 @@
 
 void __init xen_pt_check_e820(void)
 {
-	if (xen_is_e820_reserved(xen_pt_base, xen_pt_size)) {
-		xen_raw_console_write("Xen hypervisor allocated page table memory conflicts with E820 map\n");
-		BUG();
-	}
+	xen_chk_is_e820_usable(xen_pt_base, xen_pt_size, "page table");
 }
 
 static unsigned char dummy_mapping[PAGE_SIZE] __page_aligned_bss;
--- linux-qcom-6.8.0.orig/arch/x86/xen/p2m.c
+++ linux-qcom-6.8.0/arch/x86/xen/p2m.c
@@ -70,6 +70,7 @@
 #include <linux/memblock.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <linux/acpi.h>
 
 #include <asm/cache.h>
 #include <asm/setup.h>
@@ -80,6 +81,7 @@
 #include <asm/xen/hypervisor.h>
 #include <xen/balloon.h>
 #include <xen/grant_table.h>
+#include <xen/hvc-console.h>
 
 #include "multicalls.h"
 #include "xen-ops.h"
@@ -731,7 +733,7 @@
 		 * immediate unmapping.
 		 */
 		map_ops[i].status = GNTST_general_error;
-		unmap[0].host_addr = map_ops[i].host_addr,
+		unmap[0].host_addr = map_ops[i].host_addr;
 		unmap[0].handle = map_ops[i].handle;
 		map_ops[i].handle = INVALID_GRANT_HANDLE;
 		if (map_ops[i].flags & GNTMAP_device_map)
@@ -741,7 +743,7 @@
 
 		if (kmap_ops) {
 			kmap_ops[i].status = GNTST_general_error;
-			unmap[1].host_addr = kmap_ops[i].host_addr,
+			unmap[1].host_addr = kmap_ops[i].host_addr;
 			unmap[1].handle = kmap_ops[i].handle;
 			kmap_ops[i].handle = INVALID_GRANT_HANDLE;
 			if (kmap_ops[i].flags & GNTMAP_device_map)
@@ -794,6 +796,102 @@
 	return ret;
 }
 
+/* Remapped non-RAM areas */
+#define NR_NONRAM_REMAP 4
+static struct nonram_remap {
+	phys_addr_t maddr;
+	phys_addr_t paddr;
+	size_t size;
+} xen_nonram_remap[NR_NONRAM_REMAP] __ro_after_init;
+static unsigned int nr_nonram_remap __ro_after_init;
+
+/*
+ * Do the real remapping of non-RAM regions as specified in the
+ * xen_nonram_remap[] array.
+ * In case of an error just crash the system.
+ */
+void __init xen_do_remap_nonram(void)
+{
+	unsigned int i;
+	unsigned int remapped = 0;
+	const struct nonram_remap *remap = xen_nonram_remap;
+	unsigned long pfn, mfn, end_pfn;
+
+	for (i = 0; i < nr_nonram_remap; i++) {
+		end_pfn = PFN_UP(remap->paddr + remap->size);
+		pfn = PFN_DOWN(remap->paddr);
+		mfn = PFN_DOWN(remap->maddr);
+		while (pfn < end_pfn) {
+			if (!set_phys_to_machine(pfn, mfn))
+				panic("Failed to set p2m mapping for pfn=%lx mfn=%lx\n",
+				       pfn, mfn);
+
+			pfn++;
+			mfn++;
+			remapped++;
+		}
+
+		remap++;
+	}
+
+	pr_info("Remapped %u non-RAM page(s)\n", remapped);
+}
+
+#ifdef CONFIG_ACPI
+/*
+ * Xen variant of acpi_os_ioremap() taking potentially remapped non-RAM
+ * regions into account.
+ * Any attempt to map an area crossing a remap boundary will produce a
+ * WARN() splat.
+ * phys is related to remap->maddr on input and will be rebased to remap->paddr.
+ */
+static void __iomem *xen_acpi_os_ioremap(acpi_physical_address phys,
+					 acpi_size size)
+{
+	unsigned int i;
+	const struct nonram_remap *remap = xen_nonram_remap;
+
+	for (i = 0; i < nr_nonram_remap; i++) {
+		if (phys + size > remap->maddr &&
+		    phys < remap->maddr + remap->size) {
+			WARN_ON(phys < remap->maddr ||
+				phys + size > remap->maddr + remap->size);
+			phys += remap->paddr - remap->maddr;
+			break;
+		}
+	}
+
+	return x86_acpi_os_ioremap(phys, size);
+}
+#endif /* CONFIG_ACPI */
+
+/*
+ * Add a new non-RAM remap entry.
+ * In case of no free entry found, just crash the system.
+ */
+void __init xen_add_remap_nonram(phys_addr_t maddr, phys_addr_t paddr,
+				 unsigned long size)
+{
+	BUG_ON((maddr & ~PAGE_MASK) != (paddr & ~PAGE_MASK));
+
+	if (nr_nonram_remap == NR_NONRAM_REMAP) {
+		xen_raw_console_write("Number of required E820 entry remapping actions exceed maximum value\n");
+		BUG();
+	}
+
+#ifdef CONFIG_ACPI
+	/* Switch to the Xen acpi_os_ioremap() variant. */
+	if (nr_nonram_remap == 0)
+		acpi_os_ioremap = xen_acpi_os_ioremap;
+#endif
+
+	xen_nonram_remap[nr_nonram_remap].maddr = maddr;
+	xen_nonram_remap[nr_nonram_remap].paddr = paddr;
+	xen_nonram_remap[nr_nonram_remap].size = size;
+
+	nr_nonram_remap++;
+}
+
 #ifdef CONFIG_XEN_DEBUG_FS
 #include <linux/debugfs.h>
 #include "debugfs.h"
--- linux-qcom-6.8.0.orig/arch/x86/xen/setup.c
+++ linux-qcom-6.8.0/arch/x86/xen/setup.c
@@ -15,12 +15,12 @@
 #include <linux/cpuidle.h>
 #include <linux/cpufreq.h>
 #include <linux/memory_hotplug.h>
+#include <linux/acpi.h>
 
 #include <asm/elf.h>
 #include <asm/vdso.h>
 #include <asm/e820/api.h>
 #include <asm/setup.h>
-#include <asm/acpi.h>
 #include <asm/numa.h>
 #include <asm/idtentry.h>
 #include <asm/xen/hypervisor.h>
@@ -38,9 +38,6 @@
 
 #define GB(x) ((uint64_t)(x) * 1024 * 1024 * 1024)
 
-/* Amount of extra memory space we add to the e820 ranges */
-struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
-
 /* Number of pages released from the initial allocation. */
 unsigned long xen_released_pages;
 
@@ -50,6 +47,9 @@
 /* E820 map used during setting up memory. */
 static struct e820_table xen_e820_table __initdata;
 
+/* Number of initially usable memory pages. */
+static unsigned long ini_nr_pages __initdata;
+
 /*
  * Buffer used to remap identity mapped pages. We only need the virtual space.
  * The physical page behind this address is remapped as needed to different
@@ -64,18 +64,6 @@
 } xen_remap_buf __initdata __aligned(PAGE_SIZE);
 static unsigned long xen_remap_mfn __initdata = INVALID_P2M_ENTRY;
 
-/*
- * The maximum amount of extra memory compared to the base size.  The
- * main scaling factor is the size of struct page.  At extreme ratios
- * of base:extra, all the base memory can be filled with page
- * structures for the extra memory, leaving no space for anything
- * else.
- *
- * 10x seems like a reasonable balance between scaling flexibility and
- * leaving a practically usable system.
- */
-#define EXTRA_MEM_RATIO		(10)
-
 static bool xen_512gb_limit __initdata = IS_ENABLED(CONFIG_XEN_512GB);
 
 static void __init xen_parse_512gb(void)
@@ -96,35 +84,6 @@
 	xen_512gb_limit = val;
 }
 
-static void __init xen_add_extra_mem(unsigned long start_pfn,
-				     unsigned long n_pfns)
-{
-	int i;
-
-	/*
-	 * No need to check for zero size, should happen rarely and will only
-	 * write a new entry regarded to be unused due to zero size.
-	 */
-	for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) {
-		/* Add new region. */
-		if (xen_extra_mem[i].n_pfns == 0) {
-			xen_extra_mem[i].start_pfn = start_pfn;
-			xen_extra_mem[i].n_pfns = n_pfns;
-			break;
-		}
-		/* Append to existing region. */
-		if (xen_extra_mem[i].start_pfn + xen_extra_mem[i].n_pfns ==
-		    start_pfn) {
-			xen_extra_mem[i].n_pfns += n_pfns;
-			break;
-		}
-	}
-	if (i == XEN_EXTRA_MEM_MAX_REGIONS)
-		printk(KERN_WARNING "Warning: not enough extra memory regions\n");
-
-	memblock_reserve(PFN_PHYS(start_pfn), PFN_PHYS(n_pfns));
-}
-
 static void __init xen_del_extra_mem(unsigned long start_pfn,
 				     unsigned long n_pfns)
 {
@@ -257,7 +216,7 @@
  * as a fallback if the remapping fails.
  */
 static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn,
-			unsigned long end_pfn, unsigned long nr_pages)
+						      unsigned long end_pfn)
 {
 	unsigned long pfn, end;
 	int ret;
@@ -265,7 +224,7 @@
 	WARN_ON(start_pfn > end_pfn);
 
 	/* Release pages first. */
-	end = min(end_pfn, nr_pages);
+	end = min(end_pfn, ini_nr_pages);
 	for (pfn = start_pfn; pfn < end; pfn++) {
 		unsigned long mfn = pfn_to_mfn(pfn);
 
@@ -386,15 +345,14 @@
  * to Xen and not remapped.
  */
 static unsigned long __init xen_set_identity_and_remap_chunk(
-	unsigned long start_pfn, unsigned long end_pfn, unsigned long nr_pages,
-	unsigned long remap_pfn)
+	unsigned long start_pfn, unsigned long end_pfn, unsigned long remap_pfn)
 {
 	unsigned long pfn;
 	unsigned long i = 0;
 	unsigned long n = end_pfn - start_pfn;
 
 	if (remap_pfn == 0)
-		remap_pfn = nr_pages;
+		remap_pfn = ini_nr_pages;
 
 	while (i < n) {
 		unsigned long cur_pfn = start_pfn + i;
@@ -403,19 +361,19 @@
 		unsigned long remap_range_size;
 
 		/* Do not remap pages beyond the current allocation */
-		if (cur_pfn >= nr_pages) {
+		if (cur_pfn >= ini_nr_pages) {
 			/* Identity map remaining pages */
 			set_phys_range_identity(cur_pfn, cur_pfn + size);
 			break;
 		}
-		if (cur_pfn + size > nr_pages)
-			size = nr_pages - cur_pfn;
+		if (cur_pfn + size > ini_nr_pages)
+			size = ini_nr_pages - cur_pfn;
 
 		remap_range_size = xen_find_pfn_range(&remap_pfn);
 		if (!remap_range_size) {
 			pr_warn("Unable to find available pfn range, not remapping identity pages\n");
 			xen_set_identity_and_release_chunk(cur_pfn,
-						cur_pfn + left, nr_pages);
+							   cur_pfn + left);
 			break;
 		}
 		/* Adjust size to fit in current e820 RAM region */
@@ -442,18 +400,18 @@
 }
 
 static unsigned long __init xen_count_remap_pages(
-	unsigned long start_pfn, unsigned long end_pfn, unsigned long nr_pages,
+	unsigned long start_pfn, unsigned long end_pfn,
 	unsigned long remap_pages)
 {
-	if (start_pfn >= nr_pages)
+	if (start_pfn >= ini_nr_pages)
 		return remap_pages;
 
-	return remap_pages + min(end_pfn, nr_pages) - start_pfn;
+	return remap_pages + min(end_pfn, ini_nr_pages) - start_pfn;
 }
 
-static unsigned long __init xen_foreach_remap_area(unsigned long nr_pages,
+static unsigned long __init xen_foreach_remap_area(
 	unsigned long (*func)(unsigned long start_pfn, unsigned long end_pfn,
-			      unsigned long nr_pages, unsigned long last_val))
+			      unsigned long last_val))
 {
 	phys_addr_t start = 0;
 	unsigned long ret_val = 0;
@@ -481,8 +439,7 @@
 				end_pfn = PFN_UP(entry->addr);
 
 			if (start_pfn < end_pfn)
-				ret_val = func(start_pfn, end_pfn, nr_pages,
-					       ret_val);
+				ret_val = func(start_pfn, end_pfn, ret_val);
 			start = end;
 		}
 	}
@@ -539,6 +496,8 @@
 	set_pte_mfn(buf, mfn_save, PAGE_KERNEL);
 
 	pr_info("Remapped %ld page(s)\n", remapped);
+
+	xen_do_remap_nonram();
 }
 
 static unsigned long __init xen_get_pages_limit(void)
@@ -612,7 +571,7 @@
 	}
 }
 
-bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size)
+static bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size)
 {
 	struct e820_entry *entry;
 	unsigned mapcnt;
@@ -670,6 +629,111 @@
 }
 
 /*
+ * Swap a non-RAM E820 map entry with RAM above ini_nr_pages.
+ * Note that the E820 map is modified accordingly, but the P2M map isn't yet.
+ * The adaption of the P2M must be deferred until page allocation is possible.
+ */
+static void __init xen_e820_swap_entry_with_ram(struct e820_entry *swap_entry)
+{
+	struct e820_entry *entry;
+	unsigned int mapcnt;
+	phys_addr_t mem_end = PFN_PHYS(ini_nr_pages);
+	phys_addr_t swap_addr, swap_size, entry_end;
+
+	swap_addr = PAGE_ALIGN_DOWN(swap_entry->addr);
+	swap_size = PAGE_ALIGN(swap_entry->addr - swap_addr + swap_entry->size);
+	entry = xen_e820_table.entries;
+
+	for (mapcnt = 0; mapcnt < xen_e820_table.nr_entries; mapcnt++) {
+		entry_end = entry->addr + entry->size;
+		if (entry->type == E820_TYPE_RAM && entry->size >= swap_size &&
+		    entry_end - swap_size >= mem_end) {
+			/* Reduce RAM entry by needed space (whole pages). */
+			entry->size -= swap_size;
+
+			/* Add new entry at the end of E820 map. */
+			entry = xen_e820_table.entries +
+				xen_e820_table.nr_entries;
+			xen_e820_table.nr_entries++;
+
+			/* Fill new entry (keep size and page offset). */
+			entry->type = swap_entry->type;
+			entry->addr = entry_end - swap_size +
+				      swap_addr - swap_entry->addr;
+			entry->size = swap_entry->size;
+
+			/* Convert old entry to RAM, align to pages. */
+			swap_entry->type = E820_TYPE_RAM;
+			swap_entry->addr = swap_addr;
+			swap_entry->size = swap_size;
+
+			/* Remember PFN<->MFN relation for P2M update. */
+			xen_add_remap_nonram(swap_addr, entry_end - swap_size,
+					     swap_size);
+
+			/* Order E820 table and merge entries. */
+			e820__update_table(&xen_e820_table);
+
+			return;
+		}
+
+		entry++;
+	}
+
+	xen_raw_console_write("No suitable area found for required E820 entry remapping action\n");
+	BUG();
+}
+
+/*
+ * Look for non-RAM memory types in a specific guest physical area and move
+ * those away if possible (ACPI NVS only for now).
+ */
+static void __init xen_e820_resolve_conflicts(phys_addr_t start,
+					      phys_addr_t size)
+{
+	struct e820_entry *entry;
+	unsigned int mapcnt;
+	phys_addr_t end;
+
+	if (!size)
+		return;
+
+	end = start + size;
+	entry = xen_e820_table.entries;
+
+	for (mapcnt = 0; mapcnt < xen_e820_table.nr_entries; mapcnt++) {
+		if (entry->addr >= end)
+			return;
+
+		if (entry->addr + entry->size > start &&
+		    entry->type == E820_TYPE_NVS)
+			xen_e820_swap_entry_with_ram(entry);
+
+		entry++;
+	}
+}
+
+/*
+ * Check for an area in physical memory to be usable for non-movable purposes.
+ * An area is considered to usable if the used E820 map lists it to be RAM or
+ * some other type which can be moved to higher PFNs while keeping the MFNs.
+ * In case the area is not usable, crash the system with an error message.
+ */
+void __init xen_chk_is_e820_usable(phys_addr_t start, phys_addr_t size,
+				   const char *component)
+{
+	xen_e820_resolve_conflicts(start, size);
+
+	if (!xen_is_e820_reserved(start, size))
+		return;
+
+	xen_raw_console_write("Xen hypervisor allocated ");
+	xen_raw_console_write(component);
+	xen_raw_console_write(" memory conflicts with E820 map\n");
+	BUG();
+}
+
+/*
  * Like memcpy, but with physical addresses for dest and src.
  */
 static void __init xen_phys_memcpy(phys_addr_t dest, phys_addr_t src,
@@ -728,20 +792,20 @@
  **/
 char * __init xen_memory_setup(void)
 {
-	unsigned long max_pfn, pfn_s, n_pfns;
+	unsigned long pfn_s, n_pfns;
 	phys_addr_t mem_end, addr, size, chunk_size;
 	u32 type;
 	int rc;
 	struct xen_memory_map memmap;
 	unsigned long max_pages;
 	unsigned long extra_pages = 0;
+	unsigned long maxmem_pages;
 	int i;
 	int op;
 
 	xen_parse_512gb();
-	max_pfn = xen_get_pages_limit();
-	max_pfn = min(max_pfn, xen_start_info->nr_pages);
-	mem_end = PFN_PHYS(max_pfn);
+	ini_nr_pages = min(xen_get_pages_limit(), xen_start_info->nr_pages);
+	mem_end = PFN_PHYS(ini_nr_pages);
 
 	memmap.nr_entries = ARRAY_SIZE(xen_e820_table.entries);
 	set_xen_guest_handle(memmap.buffer, xen_e820_table.entries);
@@ -791,13 +855,35 @@
 	/* Make sure the Xen-supplied memory map is well-ordered. */
 	e820__update_table(&xen_e820_table);
 
+	/*
+	 * Check whether the kernel itself conflicts with the target E820 map.
+	 * Failing now is better than running into weird problems later due
+	 * to relocating (and even reusing) pages with kernel text or data.
+	 */
+	xen_chk_is_e820_usable(__pa_symbol(_text),
+			       __pa_symbol(_end) - __pa_symbol(_text),
+			       "kernel");
+
+	/*
+	 * Check for a conflict of the xen_start_info memory with the target
+	 * E820 map.
+	 */
+	xen_chk_is_e820_usable(__pa(xen_start_info), sizeof(*xen_start_info),
+			       "xen_start_info");
+
+	/*
+	 * Check for a conflict of the hypervisor supplied page tables with
+	 * the target E820 map.
+	 */
+	xen_pt_check_e820();
+
 	max_pages = xen_get_max_pages();
 
 	/* How many extra pages do we need due to remapping? */
-	max_pages += xen_foreach_remap_area(max_pfn, xen_count_remap_pages);
+	max_pages += xen_foreach_remap_area(xen_count_remap_pages);
 
-	if (max_pages > max_pfn)
-		extra_pages += max_pages - max_pfn;
+	if (max_pages > ini_nr_pages)
+		extra_pages += max_pages - ini_nr_pages;
 
 	/*
 	 * Clamp the amount of extra memory to a EXTRA_MEM_RATIO
@@ -806,8 +892,8 @@
 	 * Make sure we have no memory above max_pages, as this area
 	 * isn't handled by the p2m management.
 	 */
-	extra_pages = min3(EXTRA_MEM_RATIO * min(max_pfn, PFN_DOWN(MAXMEM)),
-			   extra_pages, max_pages - max_pfn);
+	maxmem_pages = EXTRA_MEM_RATIO * min(ini_nr_pages, PFN_DOWN(MAXMEM));
+	extra_pages = min3(maxmem_pages, extra_pages, max_pages - ini_nr_pages);
 	i = 0;
 	addr = xen_e820_table.entries[0].addr;
 	size = xen_e820_table.entries[0].size;
@@ -863,23 +949,6 @@
 
 	e820__update_table(e820_table);
 
-	/*
-	 * Check whether the kernel itself conflicts with the target E820 map.
-	 * Failing now is better than running into weird problems later due
-	 * to relocating (and even reusing) pages with kernel text or data.
-	 */
-	if (xen_is_e820_reserved(__pa_symbol(_text),
-			__pa_symbol(__bss_stop) - __pa_symbol(_text))) {
-		xen_raw_console_write("Xen hypervisor allocated kernel memory conflicts with E820 map\n");
-		BUG();
-	}
-
-	/*
-	 * Check for a conflict of the hypervisor supplied page tables with
-	 * the target E820 map.
-	 */
-	xen_pt_check_e820();
-
 	xen_reserve_xen_mfnlist();
 
 	/* Check for a conflict of the initrd with the target E820 map. */
@@ -907,7 +976,7 @@
 	 * Set identity map on non-RAM pages and prepare remapping the
 	 * underlying RAM.
 	 */
-	xen_foreach_remap_area(max_pfn, xen_set_identity_and_remap_chunk);
+	xen_foreach_remap_area(xen_set_identity_and_remap_chunk);
 
 	pr_info("Released %ld page(s)\n", xen_released_pages);
 
--- linux-qcom-6.8.0.orig/arch/x86/xen/xen-asm.S
+++ linux-qcom-6.8.0/arch/x86/xen/xen-asm.S
@@ -20,10 +20,33 @@
 
 #include <linux/init.h>
 #include <linux/linkage.h>
+#include <linux/objtool.h>
 #include <../entry/calling.h>
 
 .pushsection .noinstr.text, "ax"
 /*
+ * PV hypercall interface to the hypervisor.
+ *
+ * Called via inline asm(), so better preserve %rcx and %r11.
+ *
+ * Input:
+ *	%eax: hypercall number
+ *	%rdi, %rsi, %rdx, %r10, %r8: args 1..5 for the hypercall
+ * Output: %rax
+ */
+SYM_FUNC_START(xen_hypercall_pv)
+	ANNOTATE_NOENDBR
+	push %rcx
+	push %r11
+	UNWIND_HINT_SAVE
+	syscall
+	UNWIND_HINT_RESTORE
+	pop %r11
+	pop %rcx
+	RET
+SYM_FUNC_END(xen_hypercall_pv)
+
+/*
  * Disabling events is simply a matter of making the event mask
  * non-zero.
  */
@@ -176,7 +199,6 @@
 SYM_CODE_END(xen_early_idt_handler_array)
 	__FINIT
 
-hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32
 /*
  * Xen64 iret frame:
  *
@@ -186,17 +208,28 @@
  *	cs
  *	rip		<-- standard iret frame
  *
- *	flags
+ *	flags		<-- xen_iret must push from here on
  *
- *	rcx		}
- *	r11		}<-- pushed by hypercall page
- * rsp->rax		}
+ *	rcx
+ *	r11
+ * rsp->rax
  */
+.macro xen_hypercall_iret
+	pushq $0	/* Flags */
+	push %rcx
+	push %r11
+	push %rax
+	mov  $__HYPERVISOR_iret, %eax
+	syscall		/* Do the IRET. */
+#ifdef CONFIG_SLS
+	int3
+#endif
+.endm
+
 SYM_CODE_START(xen_iret)
 	UNWIND_HINT_UNDEFINED
 	ANNOTATE_NOENDBR
-	pushq $0
-	jmp hypercall_iret
+	xen_hypercall_iret
 SYM_CODE_END(xen_iret)
 
 /*
@@ -301,8 +334,7 @@
 	ENDBR
 	lea 16(%rsp), %rsp	/* strip %rcx, %r11 */
 	mov $-ENOSYS, %rax
-	pushq $0
-	jmp hypercall_iret
+	xen_hypercall_iret
 SYM_CODE_END(xen_entry_SYSENTER_compat)
 SYM_CODE_END(xen_entry_SYSCALL_compat)
 
--- linux-qcom-6.8.0.orig/arch/x86/xen/xen-head.S
+++ linux-qcom-6.8.0/arch/x86/xen/xen-head.S
@@ -6,9 +6,11 @@
 
 #include <linux/elfnote.h>
 #include <linux/init.h>
+#include <linux/instrumentation.h>
 
 #include <asm/boot.h>
 #include <asm/asm.h>
+#include <asm/frame.h>
 #include <asm/msr.h>
 #include <asm/page_types.h>
 #include <asm/percpu.h>
@@ -20,28 +22,6 @@
 #include <xen/interface/xen-mca.h>
 #include <asm/xen/interface.h>
 
-.pushsection .noinstr.text, "ax"
-	.balign PAGE_SIZE
-SYM_CODE_START(hypercall_page)
-	.rept (PAGE_SIZE / 32)
-		UNWIND_HINT_FUNC
-		ANNOTATE_NOENDBR
-		ANNOTATE_UNRET_SAFE
-		ret
-		/*
-		 * Xen will write the hypercall page, and sort out ENDBR.
-		 */
-		.skip 31, 0xcc
-	.endr
-
-#define HYPERCALL(n) \
-	.equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \
-	.type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32
-#include <asm/xen-hypercalls.h>
-#undef HYPERCALL
-SYM_CODE_END(hypercall_page)
-.popsection
-
 #ifdef CONFIG_XEN_PV
 	__INIT
 SYM_CODE_START(startup_xen)
@@ -87,6 +67,88 @@
 #endif
 #endif
 
+	.pushsection .noinstr.text, "ax"
+/*
+ * Xen hypercall interface to the hypervisor.
+ *
+ * Input:
+ *     %eax: hypercall number
+ *   32-bit:
+ *     %ebx, %ecx, %edx, %esi, %edi: args 1..5 for the hypercall
+ *   64-bit:
+ *     %rdi, %rsi, %rdx, %r10, %r8: args 1..5 for the hypercall
+ * Output: %[er]ax
+ */
+SYM_FUNC_START(xen_hypercall_hvm)
+	ENDBR
+	FRAME_BEGIN
+	/* Save all relevant registers (caller save and arguments). */
+#ifdef CONFIG_X86_32
+	push %eax
+	push %ebx
+	push %ecx
+	push %edx
+	push %esi
+	push %edi
+#else
+	push %rax
+	push %rcx
+	push %rdx
+	push %rdi
+	push %rsi
+	push %r11
+	push %r10
+	push %r9
+	push %r8
+#ifdef CONFIG_FRAME_POINTER
+	pushq $0	/* Dummy push for stack alignment. */
+#endif
+#endif
+	/* Set the vendor specific function. */
+	call __xen_hypercall_setfunc
+	/* Set ZF = 1 if AMD, Restore saved registers. */
+#ifdef CONFIG_X86_32
+	lea xen_hypercall_amd, %ebx
+	cmp %eax, %ebx
+	pop %edi
+	pop %esi
+	pop %edx
+	pop %ecx
+	pop %ebx
+	pop %eax
+#else
+	lea xen_hypercall_amd(%rip), %rcx
+	cmp %rax, %rcx
+#ifdef CONFIG_FRAME_POINTER
+	pop %rax	/* Dummy pop. */
+#endif
+	pop %r8
+	pop %r9
+	pop %r10
+	pop %r11
+	pop %rsi
+	pop %rdi
+	pop %rdx
+	pop %rcx
+	pop %rax
+#endif
+	FRAME_END
+	/* Use correct hypercall function. */
+	jz xen_hypercall_amd
+	jmp xen_hypercall_intel
+SYM_FUNC_END(xen_hypercall_hvm)
+
+SYM_FUNC_START(xen_hypercall_amd)
+	vmmcall
+	RET
+SYM_FUNC_END(xen_hypercall_amd)
+
+SYM_FUNC_START(xen_hypercall_intel)
+	vmcall
+	RET
+SYM_FUNC_END(xen_hypercall_intel)
+	.popsection
+
 	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS,       .asciz "linux")
 	ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION,  .asciz "2.6")
 	ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION,    .asciz "xen-3.0")
@@ -115,7 +177,6 @@
 #else
 # define FEATURES_DOM0 0
 #endif
-	ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, _ASM_PTR hypercall_page)
 	ELFNOTE(Xen, XEN_ELFNOTE_SUPPORTED_FEATURES,
 		.long FEATURES_PV | FEATURES_PVH | FEATURES_DOM0)
 	ELFNOTE(Xen, XEN_ELFNOTE_LOADER,         .asciz "generic")
--- linux-qcom-6.8.0.orig/arch/x86/xen/xen-ops.h
+++ linux-qcom-6.8.0/arch/x86/xen/xen-ops.h
@@ -43,8 +43,12 @@
 #ifdef CONFIG_X86_64
 void __init xen_relocate_p2m(void);
 #endif
+void __init xen_do_remap_nonram(void);
+void __init xen_add_remap_nonram(phys_addr_t maddr, phys_addr_t paddr,
+				 unsigned long size);
 
-bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size);
+void __init xen_chk_is_e820_usable(phys_addr_t start, phys_addr_t size,
+				   const char *component);
 unsigned long __ref xen_chk_extra_mem(unsigned long pfn);
 void __init xen_inv_extra_mem(void);
 void __init xen_remap_memory(void);
@@ -163,4 +167,27 @@
 static inline void xen_hvm_post_suspend(int suspend_cancelled) {}
 #endif
 
+/*
+ * The maximum amount of extra memory compared to the base size.  The
+ * main scaling factor is the size of struct page.  At extreme ratios
+ * of base:extra, all the base memory can be filled with page
+ * structures for the extra memory, leaving no space for anything
+ * else.
+ *
+ * 10x seems like a reasonable balance between scaling flexibility and
+ * leaving a practically usable system.
+ */
+#define EXTRA_MEM_RATIO		(10)
+
+void xen_add_extra_mem(unsigned long start_pfn, unsigned long n_pfns);
+
+#ifdef CONFIG_XEN_PV
+void xen_hypercall_pv(void);
+#endif
+void xen_hypercall_hvm(void);
+void xen_hypercall_amd(void);
+void xen_hypercall_intel(void);
+void xen_hypercall_setfunc(void);
+void *__xen_hypercall_setfunc(void);
+
 #endif /* XEN_OPS_H */
--- linux-qcom-6.8.0.orig/arch/xtensa/Kconfig
+++ linux-qcom-6.8.0/arch/xtensa/Kconfig
@@ -13,6 +13,7 @@
 	select ARCH_HAS_DMA_SET_UNCACHED if MMU
 	select ARCH_HAS_STRNCPY_FROM_USER if !KASAN
 	select ARCH_HAS_STRNLEN_USER
+	select ARCH_NEED_CMPXCHG_1_EMU
 	select ARCH_USE_MEMTEST
 	select ARCH_USE_QUEUED_RWLOCKS
 	select ARCH_USE_QUEUED_SPINLOCKS
--- linux-qcom-6.8.0.orig/arch/xtensa/include/asm/cmpxchg.h
+++ linux-qcom-6.8.0/arch/xtensa/include/asm/cmpxchg.h
@@ -15,6 +15,7 @@
 
 #include <linux/bits.h>
 #include <linux/stringify.h>
+#include <linux/cmpxchg-emu.h>
 
 /*
  * cmpxchg
@@ -74,6 +75,7 @@
 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 {
 	switch (size) {
+	case 1:  return cmpxchg_emu_u8(ptr, old, new);
 	case 4:  return __cmpxchg_u32(ptr, old, new);
 	default: __cmpxchg_called_with_bad_pointer();
 		 return old;
--- linux-qcom-6.8.0.orig/arch/xtensa/include/asm/processor.h
+++ linux-qcom-6.8.0/arch/xtensa/include/asm/processor.h
@@ -115,9 +115,9 @@
 #define MAKE_RA_FOR_CALL(ra,ws)   (((ra) & 0x3fffffff) | (ws) << 30)
 
 /* Convert return address to a valid pc
- * Note: We assume that the stack pointer is in the same 1GB ranges as the ra
+ * Note: 'text' is the address within the same 1GB range as the ra
  */
-#define MAKE_PC_FROM_RA(ra,sp)    (((ra) & 0x3fffffff) | ((sp) & 0xc0000000))
+#define MAKE_PC_FROM_RA(ra, text) (((ra) & 0x3fffffff) | ((unsigned long)(text) & 0xc0000000))
 
 #elif defined(__XTENSA_CALL0_ABI__)
 
@@ -127,9 +127,9 @@
 #define MAKE_RA_FOR_CALL(ra, ws)   (ra)
 
 /* Convert return address to a valid pc
- * Note: We assume that the stack pointer is in the same 1GB ranges as the ra
+ * Note: 'text' is not used as 'ra' is always the full address
  */
-#define MAKE_PC_FROM_RA(ra, sp)    (ra)
+#define MAKE_PC_FROM_RA(ra, text)  (ra)
 
 #else
 #error Unsupported Xtensa ABI
--- linux-qcom-6.8.0.orig/arch/xtensa/include/asm/ptrace.h
+++ linux-qcom-6.8.0/arch/xtensa/include/asm/ptrace.h
@@ -87,7 +87,7 @@
 # define user_mode(regs) (((regs)->ps & 0x00000020)!=0)
 # define instruction_pointer(regs) ((regs)->pc)
 # define return_pointer(regs) (MAKE_PC_FROM_RA((regs)->areg[0], \
-					       (regs)->areg[1]))
+					       (regs)->pc))
 
 # ifndef CONFIG_SMP
 #  define profile_pc(regs) instruction_pointer(regs)
--- linux-qcom-6.8.0.orig/arch/xtensa/kernel/process.c
+++ linux-qcom-6.8.0/arch/xtensa/kernel/process.c
@@ -47,6 +47,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/regs.h>
 #include <asm/hw_breakpoint.h>
+#include <asm/sections.h>
 #include <asm/traps.h>
 
 extern void ret_from_fork(void);
@@ -380,7 +381,7 @@
 	int count = 0;
 
 	sp = p->thread.sp;
-	pc = MAKE_PC_FROM_RA(p->thread.ra, p->thread.sp);
+	pc = MAKE_PC_FROM_RA(p->thread.ra, _text);
 
 	do {
 		if (sp < stack_page + sizeof(struct task_struct) ||
@@ -392,7 +393,7 @@
 
 		/* Stack layout: sp-4: ra, sp-3: sp' */
 
-		pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), sp);
+		pc = MAKE_PC_FROM_RA(SPILL_SLOT(sp, 0), _text);
 		sp = SPILL_SLOT(sp, 1);
 	} while (count++ < 16);
 	return 0;
--- linux-qcom-6.8.0.orig/arch/xtensa/kernel/setup.c
+++ linux-qcom-6.8.0/arch/xtensa/kernel/setup.c
@@ -216,7 +216,7 @@
 
 void __init early_init_devtree(void *params)
 {
-	early_init_dt_scan(params);
+	early_init_dt_scan(params, __pa(params));
 	of_scan_flat_dt(xtensa_dt_io_area, NULL);
 
 	if (!command_line[0])
--- linux-qcom-6.8.0.orig/arch/xtensa/kernel/stacktrace.c
+++ linux-qcom-6.8.0/arch/xtensa/kernel/stacktrace.c
@@ -13,6 +13,7 @@
 #include <linux/stacktrace.h>
 
 #include <asm/ftrace.h>
+#include <asm/sections.h>
 #include <asm/stacktrace.h>
 #include <asm/traps.h>
 #include <linux/uaccess.h>
@@ -189,7 +190,7 @@
 		if (a1 <= (unsigned long)sp)
 			break;
 
-		frame.pc = MAKE_PC_FROM_RA(a0, a1);
+		frame.pc = MAKE_PC_FROM_RA(a0, _text);
 		frame.sp = a1;
 
 		if (fn(&frame, data))
--- linux-qcom-6.8.0.orig/block/bdev.c
+++ linux-qcom-6.8.0/block/bdev.c
@@ -639,6 +639,14 @@
 	bdev_write_inode(bdev);
 }
 
+static void blkdev_put_whole(struct block_device *bdev)
+{
+	if (atomic_dec_and_test(&bdev->bd_openers))
+		blkdev_flush_mapping(bdev);
+	if (bdev->bd_disk->fops->release)
+		bdev->bd_disk->fops->release(bdev->bd_disk);
+}
+
 static int blkdev_get_whole(struct block_device *bdev, blk_mode_t mode)
 {
 	struct gendisk *disk = bdev->bd_disk;
@@ -657,20 +665,21 @@
 
 	if (!atomic_read(&bdev->bd_openers))
 		set_init_blocksize(bdev);
-	if (test_bit(GD_NEED_PART_SCAN, &disk->state))
-		bdev_disk_changed(disk, false);
 	atomic_inc(&bdev->bd_openers);
+	if (test_bit(GD_NEED_PART_SCAN, &disk->state)) {
+		/*
+		 * Only return scanning errors if we are called from contexts
+		 * that explicitly want them, e.g. the BLKRRPART ioctl.
+		 */
+		ret = bdev_disk_changed(disk, false);
+		if (ret && (mode & BLK_OPEN_STRICT_SCAN)) {
+			blkdev_put_whole(bdev);
+			return ret;
+		}
+	}
 	return 0;
 }
 
-static void blkdev_put_whole(struct block_device *bdev)
-{
-	if (atomic_dec_and_test(&bdev->bd_openers))
-		blkdev_flush_mapping(bdev);
-	if (bdev->bd_disk->fops->release)
-		bdev->bd_disk->fops->release(bdev->bd_disk);
-}
-
 static int blkdev_get_part(struct block_device *part, blk_mode_t mode)
 {
 	struct gendisk *disk = part->bd_disk;
@@ -738,17 +747,17 @@
 
 static bool bdev_writes_blocked(struct block_device *bdev)
 {
-	return bdev->bd_writers == -1;
+	return bdev->bd_writers < 0;
 }
 
 static void bdev_block_writes(struct block_device *bdev)
 {
-	bdev->bd_writers = -1;
+	bdev->bd_writers--;
 }
 
 static void bdev_unblock_writes(struct block_device *bdev)
 {
-	bdev->bd_writers = 0;
+	bdev->bd_writers++;
 }
 
 static bool bdev_may_open(struct block_device *bdev, blk_mode_t mode)
@@ -864,7 +873,7 @@
 		goto abort_claiming;
 	ret = -EBUSY;
 	if (!bdev_may_open(bdev, mode))
-		goto abort_claiming;
+		goto put_module;
 	if (bdev_is_partition(bdev))
 		ret = blkdev_get_part(bdev, mode);
 	else
--- linux-qcom-6.8.0.orig/block/bfq-iosched.c
+++ linux-qcom-6.8.0/block/bfq-iosched.c
@@ -582,23 +582,31 @@
 #define BFQ_LIMIT_INLINE_DEPTH 16
 
 #ifdef CONFIG_BFQ_GROUP_IOSCHED
-static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit)
+static bool bfqq_request_over_limit(struct bfq_data *bfqd,
+				    struct bfq_io_cq *bic, blk_opf_t opf,
+				    unsigned int act_idx, int limit)
 {
-	struct bfq_data *bfqd = bfqq->bfqd;
-	struct bfq_entity *entity = &bfqq->entity;
 	struct bfq_entity *inline_entities[BFQ_LIMIT_INLINE_DEPTH];
 	struct bfq_entity **entities = inline_entities;
-	int depth, level, alloc_depth = BFQ_LIMIT_INLINE_DEPTH;
-	int class_idx = bfqq->ioprio_class - 1;
+	int alloc_depth = BFQ_LIMIT_INLINE_DEPTH;
 	struct bfq_sched_data *sched_data;
+	struct bfq_entity *entity;
+	struct bfq_queue *bfqq;
 	unsigned long wsum;
 	bool ret = false;
-
-	if (!entity->on_st_or_in_serv)
-		return false;
+	int depth;
+	int level;
 
 retry:
 	spin_lock_irq(&bfqd->lock);
+	bfqq = bic_to_bfqq(bic, op_is_sync(opf), act_idx);
+	if (!bfqq)
+		goto out;
+
+	entity = &bfqq->entity;
+	if (!entity->on_st_or_in_serv)
+		goto out;
+
 	/* +1 for bfqq entity, root cgroup not included */
 	depth = bfqg_to_blkg(bfqq_group(bfqq))->blkcg->css.cgroup->level + 1;
 	if (depth > alloc_depth) {
@@ -643,7 +651,7 @@
 			 * class.
 			 */
 			wsum = 0;
-			for (i = 0; i <= class_idx; i++) {
+			for (i = 0; i <= bfqq->ioprio_class - 1; i++) {
 				wsum = wsum * IOPRIO_BE_NR +
 					sched_data->service_tree[i].wsum;
 			}
@@ -666,7 +674,9 @@
 	return ret;
 }
 #else
-static bool bfqq_request_over_limit(struct bfq_queue *bfqq, int limit)
+static bool bfqq_request_over_limit(struct bfq_data *bfqd,
+				    struct bfq_io_cq *bic, blk_opf_t opf,
+				    unsigned int act_idx, int limit)
 {
 	return false;
 }
@@ -704,8 +714,9 @@
 	}
 
 	for (act_idx = 0; bic && act_idx < bfqd->num_actuators; act_idx++) {
-		struct bfq_queue *bfqq =
-			bic_to_bfqq(bic, op_is_sync(opf), act_idx);
+		/* Fast path to check if bfqq is already allocated. */
+		if (!bic_to_bfqq(bic, op_is_sync(opf), act_idx))
+			continue;
 
 		/*
 		 * Does queue (or any parent entity) exceed number of
@@ -713,7 +724,7 @@
 		 * limit depth so that it cannot consume more
 		 * available requests and thus starve other entities.
 		 */
-		if (bfqq && bfqq_request_over_limit(bfqq, limit)) {
+		if (bfqq_request_over_limit(bfqd, bic, opf, act_idx, limit)) {
 			depth = 1;
 			break;
 		}
@@ -2911,8 +2922,12 @@
 	struct bfq_iocq_bfqq_data *bfqq_data = &bic->bfqq_data[a_idx];
 
 	/* if a merge has already been setup, then proceed with that first */
-	if (bfqq->new_bfqq)
-		return bfqq->new_bfqq;
+	new_bfqq = bfqq->new_bfqq;
+	if (new_bfqq) {
+		while (new_bfqq->new_bfqq)
+			new_bfqq = new_bfqq->new_bfqq;
+		return new_bfqq;
+	}
 
 	/*
 	 * Check delayed stable merge for rotational or non-queueing
@@ -3125,10 +3140,12 @@
 	bfq_put_queue(bfqq);
 }
 
-static void
-bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
-		struct bfq_queue *bfqq, struct bfq_queue *new_bfqq)
+static struct bfq_queue *bfq_merge_bfqqs(struct bfq_data *bfqd,
+					 struct bfq_io_cq *bic,
+					 struct bfq_queue *bfqq)
 {
+	struct bfq_queue *new_bfqq = bfqq->new_bfqq;
+
 	bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu",
 		(unsigned long)new_bfqq->pid);
 	/* Save weight raising and idle window of the merged queues */
@@ -3222,6 +3239,8 @@
 	bfq_reassign_last_bfqq(bfqq, new_bfqq);
 
 	bfq_release_process_ref(bfqd, bfqq);
+
+	return new_bfqq;
 }
 
 static bool bfq_allow_bio_merge(struct request_queue *q, struct request *rq,
@@ -3257,14 +3276,8 @@
 		 * fulfilled, i.e., bic can be redirected to new_bfqq
 		 * and bfqq can be put.
 		 */
-		bfq_merge_bfqqs(bfqd, bfqd->bio_bic, bfqq,
-				new_bfqq);
-		/*
-		 * If we get here, bio will be queued into new_queue,
-		 * so use new_bfqq to decide whether bio and rq can be
-		 * merged.
-		 */
-		bfqq = new_bfqq;
+		while (bfqq != new_bfqq)
+			bfqq = bfq_merge_bfqqs(bfqd, bfqd->bio_bic, bfqq);
 
 		/*
 		 * Change also bqfd->bio_bfqq, as
@@ -5699,9 +5712,7 @@
 	 * state before killing it.
 	 */
 	bfqq->bic = bic;
-	bfq_merge_bfqqs(bfqd, bic, bfqq, new_bfqq);
-
-	return new_bfqq;
+	return bfq_merge_bfqqs(bfqd, bic, bfqq);
 }
 
 /*
@@ -6156,6 +6167,7 @@
 	bool waiting, idle_timer_disabled = false;
 
 	if (new_bfqq) {
+		struct bfq_queue *old_bfqq = bfqq;
 		/*
 		 * Release the request's reference to the old bfqq
 		 * and make sure one is taken to the shared queue.
@@ -6172,18 +6184,18 @@
 		 * new_bfqq.
 		 */
 		if (bic_to_bfqq(RQ_BIC(rq), true,
-				bfq_actuator_index(bfqd, rq->bio)) == bfqq)
-			bfq_merge_bfqqs(bfqd, RQ_BIC(rq),
-					bfqq, new_bfqq);
+				bfq_actuator_index(bfqd, rq->bio)) == bfqq) {
+			while (bfqq != new_bfqq)
+				bfqq = bfq_merge_bfqqs(bfqd, RQ_BIC(rq), bfqq);
+		}
 
-		bfq_clear_bfqq_just_created(bfqq);
+		bfq_clear_bfqq_just_created(old_bfqq);
 		/*
 		 * rq is about to be enqueued into new_bfqq,
 		 * release rq reference on bfqq
 		 */
-		bfq_put_queue(bfqq);
+		bfq_put_queue(old_bfqq);
 		rq->elv.priv[1] = new_bfqq;
-		bfqq = new_bfqq;
 	}
 
 	bfq_update_io_thinktime(bfqd, bfqq);
@@ -6721,7 +6733,7 @@
 {
 	bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue");
 
-	if (bfqq_process_refs(bfqq) == 1) {
+	if (bfqq_process_refs(bfqq) == 1 && !bfqq->new_bfqq) {
 		bfqq->pid = current->pid;
 		bfq_clear_bfqq_coop(bfqq);
 		bfq_clear_bfqq_split_coop(bfqq);
@@ -6819,6 +6831,39 @@
 	rq->elv.priv[0] = rq->elv.priv[1] = NULL;
 }
 
+static struct bfq_queue *bfq_waker_bfqq(struct bfq_queue *bfqq)
+{
+	struct bfq_queue *new_bfqq = bfqq->new_bfqq;
+	struct bfq_queue *waker_bfqq = bfqq->waker_bfqq;
+
+	if (!waker_bfqq)
+		return NULL;
+
+	while (new_bfqq) {
+		if (new_bfqq == waker_bfqq) {
+			/*
+			 * If waker_bfqq is in the merge chain, and current
+			 * is the only process, waker_bfqq can be freed.
+			 */
+			if (bfqq_process_refs(waker_bfqq) == 1)
+				return NULL;
+
+			return waker_bfqq;
+		}
+
+		new_bfqq = new_bfqq->new_bfqq;
+	}
+
+	/*
+	 * If waker_bfqq is not in the merge chain, and it's procress reference
+	 * is 0, waker_bfqq can be freed.
+	 */
+	if (bfqq_process_refs(waker_bfqq) == 0)
+		return NULL;
+
+	return waker_bfqq;
+}
+
 /*
  * If needed, init rq, allocate bfq data structures associated with
  * rq, and increment reference counters in the destination bfq_queue
@@ -6880,7 +6925,7 @@
 		/* If the queue was seeky for too long, break it apart. */
 		if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq) &&
 			!bic->bfqq_data[a_idx].stably_merged) {
-			struct bfq_queue *old_bfqq = bfqq;
+			struct bfq_queue *waker_bfqq = bfq_waker_bfqq(bfqq);
 
 			/* Update bic before losing reference to bfqq */
 			if (bfq_bfqq_in_large_burst(bfqq))
@@ -6900,7 +6945,7 @@
 				bfqq_already_existing = true;
 
 			if (!bfqq_already_existing) {
-				bfqq->waker_bfqq = old_bfqq->waker_bfqq;
+				bfqq->waker_bfqq = waker_bfqq;
 				bfqq->tentative_waker_bfqq = NULL;
 
 				/*
@@ -6910,7 +6955,7 @@
 				 * woken_list of the waker. See
 				 * bfq_check_waker for details.
 				 */
-				if (bfqq->waker_bfqq)
+				if (waker_bfqq)
 					hlist_add_head(&bfqq->woken_list_node,
 						       &bfqq->waker_bfqq->woken_list);
 			}
@@ -6932,7 +6977,8 @@
 	 * addition, if the queue has also just been split, we have to
 	 * resume its state.
 	 */
-	if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) {
+	if (likely(bfqq != &bfqd->oom_bfqq) && !bfqq->new_bfqq &&
+	    bfqq_process_refs(bfqq) == 1) {
 		bfqq->bic = bic;
 		if (split) {
 			/*
--- linux-qcom-6.8.0.orig/block/bio-integrity.c
+++ linux-qcom-6.8.0/block/bio-integrity.c
@@ -105,17 +105,18 @@
 
 static void bio_integrity_uncopy_user(struct bio_integrity_payload *bip)
 {
-	unsigned short nr_vecs = bip->bip_max_vcnt - 1;
-	struct bio_vec *copy = &bip->bip_vec[1];
-	size_t bytes = bip->bip_iter.bi_size;
-	struct iov_iter iter;
+	unsigned short orig_nr_vecs = bip->bip_max_vcnt - 1;
+	struct bio_vec *orig_bvecs = &bip->bip_vec[1];
+	struct bio_vec *bounce_bvec = &bip->bip_vec[0];
+	size_t bytes = bounce_bvec->bv_len;
+	struct iov_iter orig_iter;
 	int ret;
 
-	iov_iter_bvec(&iter, ITER_DEST, copy, nr_vecs, bytes);
-	ret = copy_to_iter(bvec_virt(bip->bip_vec), bytes, &iter);
+	iov_iter_bvec(&orig_iter, ITER_DEST, orig_bvecs, orig_nr_vecs, bytes);
+	ret = copy_to_iter(bvec_virt(bounce_bvec), bytes, &orig_iter);
 	WARN_ON_ONCE(ret != bytes);
 
-	bio_integrity_unpin_bvec(copy, nr_vecs, true);
+	bio_integrity_unpin_bvec(orig_bvecs, orig_nr_vecs, true);
 }
 
 static void bio_integrity_unmap_user(struct bio_integrity_payload *bip)
@@ -431,6 +432,7 @@
 	unsigned long start, end;
 	unsigned int len, nr_pages;
 	unsigned int bytes, offset, i;
+	gfp_t gfp = GFP_NOIO;
 
 	if (!bi)
 		return true;
@@ -453,11 +455,19 @@
 		if (!bi->profile->generate_fn ||
 		    !(bi->flags & BLK_INTEGRITY_GENERATE))
 			return true;
+
+		/*
+		 * Zero the memory allocated to not leak uninitialized kernel
+		 * memory to disk.  For PI this only affects the app tag, but
+		 * for non-integrity metadata it affects the entire metadata
+		 * buffer.
+		 */
+		gfp |= __GFP_ZERO;
 	}
 
 	/* Allocate kernel buffer for protection data */
 	len = bio_integrity_bytes(bi, bio_sectors(bio));
-	buf = kmalloc(len, GFP_NOIO);
+	buf = kmalloc(len, gfp);
 	if (unlikely(buf == NULL)) {
 		printk(KERN_ERR "could not allocate integrity buffer\n");
 		goto err_end_io;
--- linux-qcom-6.8.0.orig/block/bio.c
+++ linux-qcom-6.8.0/block/bio.c
@@ -1152,7 +1152,7 @@
 
 	bio_for_each_folio_all(fi, bio) {
 		struct page *page;
-		size_t done = 0;
+		size_t nr_pages;
 
 		if (mark_dirty) {
 			folio_lock(fi.folio);
@@ -1160,10 +1160,11 @@
 			folio_unlock(fi.folio);
 		}
 		page = folio_page(fi.folio, fi.offset / PAGE_SIZE);
+		nr_pages = (fi.offset + fi.length - 1) / PAGE_SIZE -
+			   fi.offset / PAGE_SIZE + 1;
 		do {
 			bio_release_page(bio, page++);
-			done += PAGE_SIZE;
-		} while (done < fi.length);
+		} while (--nr_pages != 0);
 	}
 }
 EXPORT_SYMBOL_GPL(__bio_release_pages);
@@ -1602,8 +1603,18 @@
 	}
 
 	blk_throtl_bio_endio(bio);
-	/* release cgroup info */
-	bio_uninit(bio);
+#ifdef CONFIG_BLK_CGROUP
+	/*
+	 * Release cgroup info.  We shouldn't have to do this here, but quite
+	 * a few callers of bio_init fail to call bio_uninit, so we cover up
+	 * for that here at least for now.
+	 */
+	if (bio->bi_blkg) {
+		blkg_put(bio->bi_blkg);
+		bio->bi_blkg = NULL;
+	}
+#endif
+
 	if (bio->bi_end_io)
 		bio->bi_end_io(bio);
 }
--- linux-qcom-6.8.0.orig/block/blk-cgroup.c
+++ linux-qcom-6.8.0/block/blk-cgroup.c
@@ -323,6 +323,7 @@
 	blkg->q = disk->queue;
 	INIT_LIST_HEAD(&blkg->q_node);
 	blkg->blkcg = blkcg;
+	blkg->iostat.blkg = blkg;
 #ifdef CONFIG_BLK_CGROUP_PUNT_BIO
 	spin_lock_init(&blkg->async_bio_lock);
 	bio_list_init(&blkg->async_bios);
@@ -619,12 +620,45 @@
 	spin_unlock_irq(&q->queue_lock);
 }
 
+static void blkg_iostat_set(struct blkg_iostat *dst, struct blkg_iostat *src)
+{
+	int i;
+
+	for (i = 0; i < BLKG_IOSTAT_NR; i++) {
+		dst->bytes[i] = src->bytes[i];
+		dst->ios[i] = src->ios[i];
+	}
+}
+
+static void __blkg_clear_stat(struct blkg_iostat_set *bis)
+{
+	struct blkg_iostat cur = {0};
+	unsigned long flags;
+
+	flags = u64_stats_update_begin_irqsave(&bis->sync);
+	blkg_iostat_set(&bis->cur, &cur);
+	blkg_iostat_set(&bis->last, &cur);
+	u64_stats_update_end_irqrestore(&bis->sync, flags);
+}
+
+static void blkg_clear_stat(struct blkcg_gq *blkg)
+{
+	int cpu;
+
+	for_each_possible_cpu(cpu) {
+		struct blkg_iostat_set *s = per_cpu_ptr(blkg->iostat_cpu, cpu);
+
+		__blkg_clear_stat(s);
+	}
+	__blkg_clear_stat(&blkg->iostat);
+}
+
 static int blkcg_reset_stats(struct cgroup_subsys_state *css,
 			     struct cftype *cftype, u64 val)
 {
 	struct blkcg *blkcg = css_to_blkcg(css);
 	struct blkcg_gq *blkg;
-	int i, cpu;
+	int i;
 
 	mutex_lock(&blkcg_pol_mutex);
 	spin_lock_irq(&blkcg->lock);
@@ -635,18 +669,7 @@
 	 * anyway.  If you get hit by a race, retry.
 	 */
 	hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node) {
-		for_each_possible_cpu(cpu) {
-			struct blkg_iostat_set *bis =
-				per_cpu_ptr(blkg->iostat_cpu, cpu);
-			memset(bis, 0, sizeof(*bis));
-
-			/* Re-initialize the cleared blkg_iostat_set */
-			u64_stats_init(&bis->sync);
-			bis->blkg = blkg;
-		}
-		memset(&blkg->iostat, 0, sizeof(blkg->iostat));
-		u64_stats_init(&blkg->iostat.sync);
-
+		blkg_clear_stat(blkg);
 		for (i = 0; i < BLKCG_MAX_POLS; i++) {
 			struct blkcg_policy *pol = blkcg_policy[i];
 
@@ -949,16 +972,6 @@
 }
 EXPORT_SYMBOL_GPL(blkg_conf_exit);
 
-static void blkg_iostat_set(struct blkg_iostat *dst, struct blkg_iostat *src)
-{
-	int i;
-
-	for (i = 0; i < BLKG_IOSTAT_NR; i++) {
-		dst->bytes[i] = src->bytes[i];
-		dst->ios[i] = src->ios[i];
-	}
-}
-
 static void blkg_iostat_add(struct blkg_iostat *dst, struct blkg_iostat *src)
 {
 	int i;
@@ -1024,7 +1037,19 @@
 		struct blkg_iostat cur;
 		unsigned int seq;
 
+		/*
+		 * Order assignment of `next_bisc` from `bisc->lnode.next` in
+		 * llist_for_each_entry_safe and clearing `bisc->lqueued` for
+		 * avoiding to assign `next_bisc` with new next pointer added
+		 * in blk_cgroup_bio_start() in case of re-ordering.
+		 *
+		 * The pair barrier is implied in llist_add() in blk_cgroup_bio_start().
+		 */
+		smp_mb();
+
 		WRITE_ONCE(bisc->lqueued, false);
+		if (bisc == &blkg->iostat)
+			goto propagate_up; /* propagate up to parent only */
 
 		/* fetch the current per-cpu values */
 		do {
@@ -1034,10 +1059,24 @@
 
 		blkcg_iostat_update(blkg, &cur, &bisc->last);
 
+propagate_up:
 		/* propagate global delta to parent (unless that's root) */
-		if (parent && parent->parent)
+		if (parent && parent->parent) {
 			blkcg_iostat_update(parent, &blkg->iostat.cur,
 					    &blkg->iostat.last);
+			/*
+			 * Queue parent->iostat to its blkcg's lockless
+			 * list to propagate up to the grandparent if the
+			 * iostat hasn't been queued yet.
+			 */
+			if (!parent->iostat.lqueued) {
+				struct llist_head *plhead;
+
+				plhead = per_cpu_ptr(parent->blkcg->lhead, cpu);
+				llist_add(&parent->iostat.lnode, plhead);
+				parent->iostat.lqueued = true;
+			}
+		}
 	}
 	raw_spin_unlock_irqrestore(&blkg_stat_lock, flags);
 out:
@@ -1100,6 +1139,7 @@
 		blkg_iostat_set(&blkg->iostat.cur, &tmp);
 		u64_stats_update_end_irqrestore(&blkg->iostat.sync, flags);
 	}
+	class_dev_iter_exit(&iter);
 }
 
 static void blkcg_print_one_stat(struct blkcg_gq *blkg, struct seq_file *s)
@@ -1286,10 +1326,14 @@
 	struct blkcg *blkcg = css_to_blkcg(blkcg_css);
 
 	do {
+		struct blkcg *parent;
+
 		if (!refcount_dec_and_test(&blkcg->online_pin))
 			break;
+
+		parent = blkcg_parent(blkcg);
 		blkcg_destroy_blkgs(blkcg);
-		blkcg = blkcg_parent(blkcg);
+		blkcg = parent;
 	} while (blkcg);
 }
 
@@ -1409,6 +1453,12 @@
 	return 0;
 }
 
+void blkg_init_queue(struct request_queue *q)
+{
+	INIT_LIST_HEAD(&q->blkg_list);
+	mutex_init(&q->blkcg_mutex);
+}
+
 int blkcg_init_disk(struct gendisk *disk)
 {
 	struct request_queue *q = disk->queue;
@@ -1416,9 +1466,6 @@
 	bool preloaded;
 	int ret;
 
-	INIT_LIST_HEAD(&q->blkg_list);
-	mutex_init(&q->blkcg_mutex);
-
 	new_blkg = blkg_alloc(&blkcg_root, disk, GFP_KERNEL);
 	if (!new_blkg)
 		return -ENOMEM;
--- linux-qcom-6.8.0.orig/block/blk-cgroup.h
+++ linux-qcom-6.8.0/block/blk-cgroup.h
@@ -188,6 +188,7 @@
 extern struct blkcg blkcg_root;
 extern bool blkcg_debug_stats;
 
+void blkg_init_queue(struct request_queue *q);
 int blkcg_init_disk(struct gendisk *disk);
 void blkcg_exit_disk(struct gendisk *disk);
 
@@ -481,6 +482,7 @@
 };
 
 static inline struct blkcg_gq *blkg_lookup(struct blkcg *blkcg, void *key) { return NULL; }
+static inline void blkg_init_queue(struct request_queue *q) { }
 static inline int blkcg_init_disk(struct gendisk *disk) { return 0; }
 static inline void blkcg_exit_disk(struct gendisk *disk) { }
 static inline int blkcg_policy_register(struct blkcg_policy *pol) { return 0; }
--- linux-qcom-6.8.0.orig/block/blk-core.c
+++ linux-qcom-6.8.0/block/blk-core.c
@@ -273,6 +273,8 @@
 		blk_mq_release(q);
 
 	ida_free(&blk_queue_ida, q->id);
+	lockdep_unregister_key(&q->io_lock_cls_key);
+	lockdep_unregister_key(&q->q_lock_cls_key);
 	call_rcu(&q->rcu_head, blk_free_queue_rcu);
 }
 
@@ -290,18 +292,20 @@
 }
 EXPORT_SYMBOL(blk_put_queue);
 
-void blk_queue_start_drain(struct request_queue *q)
+bool blk_queue_start_drain(struct request_queue *q)
 {
 	/*
 	 * When queue DYING flag is set, we need to block new req
 	 * entering queue, so we call blk_freeze_queue_start() to
 	 * prevent I/O from crossing blk_queue_enter().
 	 */
-	blk_freeze_queue_start(q);
+	bool freeze = __blk_freeze_queue_start(q, current);
 	if (queue_is_mq(q))
 		blk_mq_wake_waiters(q);
 	/* Make blk_queue_enter() reexamine the DYING flag. */
 	wake_up_all(&q->mq_freeze_wq);
+
+	return freeze;
 }
 
 /**
@@ -333,6 +337,8 @@
 			return -ENODEV;
 	}
 
+	rwsem_acquire_read(&q->q_lockdep_map, 0, 0, _RET_IP_);
+	rwsem_release(&q->q_lockdep_map, _RET_IP_);
 	return 0;
 }
 
@@ -364,6 +370,8 @@
 			goto dead;
 	}
 
+	rwsem_acquire_read(&q->io_lockdep_map, 0, 0, _RET_IP_);
+	rwsem_release(&q->io_lockdep_map, _RET_IP_);
 	return 0;
 dead:
 	bio_io_error(bio);
@@ -431,6 +439,8 @@
 	init_waitqueue_head(&q->mq_freeze_wq);
 	mutex_init(&q->mq_freeze_lock);
 
+	blkg_init_queue(q);
+
 	/*
 	 * Init percpu_ref in atomic mode so that it's faster to shutdown.
 	 * See blk_register_queue() for details.
@@ -439,6 +449,12 @@
 				blk_queue_usage_counter_release,
 				PERCPU_REF_INIT_ATOMIC, GFP_KERNEL))
 		goto fail_stats;
+	lockdep_register_key(&q->io_lock_cls_key);
+	lockdep_register_key(&q->q_lock_cls_key);
+	lockdep_init_map(&q->io_lockdep_map, "&q->q_usage_counter(io)",
+			 &q->io_lock_cls_key, 0);
+	lockdep_init_map(&q->q_lockdep_map, "&q->q_usage_counter(queue)",
+			 &q->q_lock_cls_key, 0);
 
 	blk_set_default_limits(&q->limits);
 	q->nr_requests = BLKDEV_DEFAULT_RQ;
@@ -974,10 +990,11 @@
 	unsigned long stamp;
 again:
 	stamp = READ_ONCE(part->bd_stamp);
-	if (unlikely(time_after(now, stamp))) {
-		if (likely(try_cmpxchg(&part->bd_stamp, &stamp, now)))
-			__part_stat_add(part, io_ticks, end ? now - stamp : 1);
-	}
+	if (unlikely(time_after(now, stamp)) &&
+	    likely(try_cmpxchg(&part->bd_stamp, &stamp, now)) &&
+	    (end || part_in_flight(part)))
+		__part_stat_add(part, io_ticks, now - stamp);
+
 	if (part->bd_partno) {
 		part = bdev_whole(part);
 		goto again;
--- linux-qcom-6.8.0.orig/block/blk-crypto-fallback.c
+++ linux-qcom-6.8.0/block/blk-crypto-fallback.c
@@ -87,7 +87,7 @@
  * This is the key we set when evicting a keyslot. This *should* be the all 0's
  * key, but AES-XTS rejects that key, so we use some random bytes instead.
  */
-static u8 blank_key[BLK_CRYPTO_MAX_KEY_SIZE];
+static u8 blank_key[BLK_CRYPTO_MAX_STANDARD_KEY_SIZE];
 
 static void blk_crypto_fallback_evict_keyslot(unsigned int slot)
 {
@@ -538,7 +538,7 @@
 	if (blk_crypto_fallback_inited)
 		return 0;
 
-	get_random_bytes(blank_key, BLK_CRYPTO_MAX_KEY_SIZE);
+	get_random_bytes(blank_key, sizeof(blank_key));
 
 	err = bioset_init(&crypto_bio_split, 64, 0, 0);
 	if (err)
@@ -560,6 +560,7 @@
 
 	blk_crypto_fallback_profile->ll_ops = blk_crypto_fallback_ll_ops;
 	blk_crypto_fallback_profile->max_dun_bytes_supported = BLK_CRYPTO_MAX_IV_SIZE;
+	blk_crypto_fallback_profile->key_types_supported = BLK_CRYPTO_KEY_TYPE_STANDARD;
 
 	/* All blk-crypto modes have a crypto API fallback. */
 	for (i = 0; i < BLK_ENCRYPTION_MODE_MAX; i++)
--- linux-qcom-6.8.0.orig/block/blk-crypto-internal.h
+++ linux-qcom-6.8.0/block/blk-crypto-internal.h
@@ -14,6 +14,7 @@
 	const char *name; /* name of this mode, shown in sysfs */
 	const char *cipher_str; /* crypto API name (for fallback case) */
 	unsigned int keysize; /* key size in bytes */
+	unsigned int security_strength; /* security strength in bytes */
 	unsigned int ivsize; /* iv size in bytes */
 };
 
@@ -82,6 +83,9 @@
 bool __blk_crypto_cfg_supported(struct blk_crypto_profile *profile,
 				const struct blk_crypto_config *cfg);
 
+int blk_crypto_ioctl(struct block_device *bdev, unsigned int cmd,
+		     void __user *argp);
+
 #else /* CONFIG_BLK_INLINE_ENCRYPTION */
 
 static inline int blk_crypto_sysfs_register(struct gendisk *disk)
@@ -129,6 +133,12 @@
 	return false;
 }
 
+static inline int blk_crypto_ioctl(struct block_device *bdev, unsigned int cmd,
+				   void __user *argp)
+{
+	return -ENOTTY;
+}
+
 #endif /* CONFIG_BLK_INLINE_ENCRYPTION */
 
 void __bio_crypt_advance(struct bio *bio, unsigned int bytes);
--- linux-qcom-6.8.0.orig/block/blk-crypto-profile.c
+++ linux-qcom-6.8.0/block/blk-crypto-profile.c
@@ -352,6 +352,8 @@
 		return false;
 	if (profile->max_dun_bytes_supported < cfg->dun_bytes)
 		return false;
+	if (!(profile->key_types_supported & cfg->key_type))
+		return false;
 	return true;
 }
 
@@ -463,6 +465,117 @@
 EXPORT_SYMBOL_GPL(blk_crypto_register);
 
 /**
+ * blk_crypto_derive_sw_secret() - Derive software secret from wrapped key
+ * @bdev: a block device whose hardware-wrapped keys implementation is
+ *	  compatible (blk_crypto_hw_wrapped_keys_compatible()) with all block
+ *	  devices on which the key will be used.
+ * @eph_key: the hardware-wrapped key in ephemerally-wrapped form
+ * @eph_key_size: size of @eph_key in bytes
+ * @sw_secret: (output) the software secret
+ *
+ * Given a hardware-wrapped key in ephemerally-wrapped form (the same form that
+ * it is used for I/O), ask the hardware to derive the secret which software can
+ * use for cryptographic tasks other than inline encryption.  This secret is
+ * guaranteed to be cryptographically isolated from the inline encryption key,
+ * i.e. derived with a different KDF context.
+ *
+ * Return: 0 on success, -EOPNOTSUPP if the block device doesn't support
+ *	   hardware-wrapped keys, -EBADMSG if the key isn't a valid
+ *	   hardware-wrapped key, or another -errno code.
+ */
+int blk_crypto_derive_sw_secret(struct block_device *bdev,
+				const u8 *eph_key, size_t eph_key_size,
+				u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE])
+{
+	struct blk_crypto_profile *profile =
+		bdev_get_queue(bdev)->crypto_profile;
+	int err;
+
+	if (!profile)
+		return -EOPNOTSUPP;
+	if (!(profile->key_types_supported & BLK_CRYPTO_KEY_TYPE_HW_WRAPPED))
+		return -EOPNOTSUPP;
+	if (!profile->ll_ops.derive_sw_secret)
+		return -EOPNOTSUPP;
+	blk_crypto_hw_enter(profile);
+	err = profile->ll_ops.derive_sw_secret(profile, eph_key, eph_key_size,
+					       sw_secret);
+	blk_crypto_hw_exit(profile);
+	return err;
+}
+
+/**
+ * blk_crypto_hw_wrapped_keys_compatible() - Check HW-wrapped key compatibility
+ * @bdev1: the first block device
+ * @bdev2: the second block device
+ *
+ * Return: true if HW-wrapped keys used on @bdev1 can also be used on @bdev2.
+ */
+bool blk_crypto_hw_wrapped_keys_compatible(struct block_device *bdev1,
+					   struct block_device *bdev2)
+{
+	return bdev_get_queue(bdev1)->crypto_profile ==
+		bdev_get_queue(bdev2)->crypto_profile;
+}
+
+int blk_crypto_import_key(struct blk_crypto_profile *profile,
+			  const u8 *raw_key, size_t raw_key_size,
+			  u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE])
+{
+	int ret;
+
+	if (!profile)
+		return -EOPNOTSUPP;
+	if (!(profile->key_types_supported & BLK_CRYPTO_KEY_TYPE_HW_WRAPPED))
+		return -EOPNOTSUPP;
+	if (!profile->ll_ops.import_key)
+		return -EOPNOTSUPP;
+	blk_crypto_hw_enter(profile);
+	ret = profile->ll_ops.import_key(profile, raw_key, raw_key_size,
+					 lt_key);
+	blk_crypto_hw_exit(profile);
+	return ret;
+}
+
+int blk_crypto_generate_key(struct blk_crypto_profile *profile,
+			    u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE])
+{
+	int ret;
+
+	if (!profile)
+		return -EOPNOTSUPP;
+	if (!(profile->key_types_supported & BLK_CRYPTO_KEY_TYPE_HW_WRAPPED))
+		return -EOPNOTSUPP;
+	if (!profile->ll_ops.generate_key)
+		return -EOPNOTSUPP;
+
+	blk_crypto_hw_enter(profile);
+	ret = profile->ll_ops.generate_key(profile, lt_key);
+	blk_crypto_hw_exit(profile);
+	return ret;
+}
+
+int blk_crypto_prepare_key(struct blk_crypto_profile *profile,
+			   const u8 *lt_key, size_t lt_key_size,
+			   u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE])
+{
+	int ret;
+
+	if (!profile)
+		return -EOPNOTSUPP;
+	if (!(profile->key_types_supported & BLK_CRYPTO_KEY_TYPE_HW_WRAPPED))
+		return -EOPNOTSUPP;
+	if (!profile->ll_ops.prepare_key)
+		return -EOPNOTSUPP;
+
+	blk_crypto_hw_enter(profile);
+	ret = profile->ll_ops.prepare_key(profile, lt_key, lt_key_size,
+					  eph_key);
+	blk_crypto_hw_exit(profile);
+	return ret;
+}
+
+/**
  * blk_crypto_intersect_capabilities() - restrict supported crypto capabilities
  *					 by child device
  * @parent: the crypto profile for the parent device
@@ -485,10 +598,12 @@
 			    child->max_dun_bytes_supported);
 		for (i = 0; i < ARRAY_SIZE(child->modes_supported); i++)
 			parent->modes_supported[i] &= child->modes_supported[i];
+		parent->key_types_supported &= child->key_types_supported;
 	} else {
 		parent->max_dun_bytes_supported = 0;
 		memset(parent->modes_supported, 0,
 		       sizeof(parent->modes_supported));
+		parent->key_types_supported = 0;
 	}
 }
 EXPORT_SYMBOL_GPL(blk_crypto_intersect_capabilities);
@@ -521,6 +636,9 @@
 	    target->max_dun_bytes_supported)
 		return false;
 
+	if (reference->key_types_supported & ~target->key_types_supported)
+		return false;
+
 	return true;
 }
 EXPORT_SYMBOL_GPL(blk_crypto_has_capabilities);
@@ -555,5 +673,6 @@
 	       sizeof(dst->modes_supported));
 
 	dst->max_dun_bytes_supported = src->max_dun_bytes_supported;
+	dst->key_types_supported = src->key_types_supported;
 }
 EXPORT_SYMBOL_GPL(blk_crypto_update_capabilities);
--- linux-qcom-6.8.0.orig/block/blk-crypto-sysfs.c
+++ linux-qcom-6.8.0/block/blk-crypto-sysfs.c
@@ -31,6 +31,13 @@
 	return container_of(attr, struct blk_crypto_attr, attr);
 }
 
+static ssize_t hw_wrapped_keys_show(struct blk_crypto_profile *profile,
+				    struct blk_crypto_attr *attr, char *page)
+{
+	/* Always show supported, since the file doesn't exist otherwise. */
+	return sysfs_emit(page, "supported\n");
+}
+
 static ssize_t max_dun_bits_show(struct blk_crypto_profile *profile,
 				 struct blk_crypto_attr *attr, char *page)
 {
@@ -43,20 +50,48 @@
 	return sysfs_emit(page, "%u\n", profile->num_slots);
 }
 
+static ssize_t standard_keys_show(struct blk_crypto_profile *profile,
+				  struct blk_crypto_attr *attr, char *page)
+{
+	/* Always show supported, since the file doesn't exist otherwise. */
+	return sysfs_emit(page, "supported\n");
+}
+
 #define BLK_CRYPTO_RO_ATTR(_name) \
 	static struct blk_crypto_attr _name##_attr = __ATTR_RO(_name)
 
+BLK_CRYPTO_RO_ATTR(hw_wrapped_keys);
 BLK_CRYPTO_RO_ATTR(max_dun_bits);
 BLK_CRYPTO_RO_ATTR(num_keyslots);
+BLK_CRYPTO_RO_ATTR(standard_keys);
+
+static umode_t blk_crypto_is_visible(struct kobject *kobj,
+				     struct attribute *attr, int n)
+{
+	struct blk_crypto_profile *profile = kobj_to_crypto_profile(kobj);
+	struct blk_crypto_attr *a = attr_to_crypto_attr(attr);
+
+	if (a == &hw_wrapped_keys_attr &&
+	    !(profile->key_types_supported & BLK_CRYPTO_KEY_TYPE_HW_WRAPPED))
+		return 0;
+	if (a == &standard_keys_attr &&
+	    !(profile->key_types_supported & BLK_CRYPTO_KEY_TYPE_STANDARD))
+		return 0;
+
+	return 0444;
+}
 
 static struct attribute *blk_crypto_attrs[] = {
+	&hw_wrapped_keys_attr.attr,
 	&max_dun_bits_attr.attr,
 	&num_keyslots_attr.attr,
+	&standard_keys_attr.attr,
 	NULL,
 };
 
 static const struct attribute_group blk_crypto_attr_group = {
 	.attrs = blk_crypto_attrs,
+	.is_visible = blk_crypto_is_visible,
 };
 
 /*
--- linux-qcom-6.8.0.orig/block/blk-crypto.c
+++ linux-qcom-6.8.0/block/blk-crypto.c
@@ -23,24 +23,28 @@
 		.name = "AES-256-XTS",
 		.cipher_str = "xts(aes)",
 		.keysize = 64,
+		.security_strength = 32,
 		.ivsize = 16,
 	},
 	[BLK_ENCRYPTION_MODE_AES_128_CBC_ESSIV] = {
 		.name = "AES-128-CBC-ESSIV",
 		.cipher_str = "essiv(cbc(aes),sha256)",
 		.keysize = 16,
+		.security_strength = 16,
 		.ivsize = 16,
 	},
 	[BLK_ENCRYPTION_MODE_ADIANTUM] = {
 		.name = "Adiantum",
 		.cipher_str = "adiantum(xchacha12,aes)",
 		.keysize = 32,
+		.security_strength = 32,
 		.ivsize = 32,
 	},
 	[BLK_ENCRYPTION_MODE_SM4_XTS] = {
 		.name = "SM4-XTS",
 		.cipher_str = "xts(sm4)",
 		.keysize = 32,
+		.security_strength = 16,
 		.ivsize = 16,
 	},
 };
@@ -76,9 +80,15 @@
 	/* This is assumed in various places. */
 	BUILD_BUG_ON(BLK_ENCRYPTION_MODE_INVALID != 0);
 
-	/* Sanity check that no algorithm exceeds the defined limits. */
+	/*
+	 * Validate the crypto mode properties.  This ideally would be done with
+	 * static assertions, but boot-time checks are the next best thing.
+	 */
 	for (i = 0; i < BLK_ENCRYPTION_MODE_MAX; i++) {
-		BUG_ON(blk_crypto_modes[i].keysize > BLK_CRYPTO_MAX_KEY_SIZE);
+		BUG_ON(blk_crypto_modes[i].keysize >
+		       BLK_CRYPTO_MAX_STANDARD_KEY_SIZE);
+		BUG_ON(blk_crypto_modes[i].security_strength >
+		       blk_crypto_modes[i].keysize);
 		BUG_ON(blk_crypto_modes[i].ivsize > BLK_CRYPTO_MAX_IV_SIZE);
 	}
 
@@ -315,8 +325,9 @@
 /**
  * blk_crypto_init_key() - Prepare a key for use with blk-crypto
  * @blk_key: Pointer to the blk_crypto_key to initialize.
- * @raw_key: Pointer to the raw key. Must be the correct length for the chosen
- *	     @crypto_mode; see blk_crypto_modes[].
+ * @raw_key: the raw bytes of the key
+ * @raw_key_size: size of the raw key in bytes
+ * @key_type: type of the key -- either standard or hardware-wrapped
  * @crypto_mode: identifier for the encryption algorithm to use
  * @dun_bytes: number of bytes that will be used to specify the DUN when this
  *	       key is used
@@ -325,7 +336,9 @@
  * Return: 0 on success, -errno on failure.  The caller is responsible for
  *	   zeroizing both blk_key and raw_key when done with them.
  */
-int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key,
+int blk_crypto_init_key(struct blk_crypto_key *blk_key,
+			const u8 *raw_key, size_t raw_key_size,
+			enum blk_crypto_key_type key_type,
 			enum blk_crypto_mode_num crypto_mode,
 			unsigned int dun_bytes,
 			unsigned int data_unit_size)
@@ -338,8 +351,19 @@
 		return -EINVAL;
 
 	mode = &blk_crypto_modes[crypto_mode];
-	if (mode->keysize == 0)
+	switch (key_type) {
+	case BLK_CRYPTO_KEY_TYPE_STANDARD:
+		if (raw_key_size != mode->keysize)
+			return -EINVAL;
+		break;
+	case BLK_CRYPTO_KEY_TYPE_HW_WRAPPED:
+		if (raw_key_size < mode->security_strength ||
+		    raw_key_size > BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE)
+			return -EINVAL;
+		break;
+	default:
 		return -EINVAL;
+	}
 
 	if (dun_bytes == 0 || dun_bytes > mode->ivsize)
 		return -EINVAL;
@@ -350,9 +374,10 @@
 	blk_key->crypto_cfg.crypto_mode = crypto_mode;
 	blk_key->crypto_cfg.dun_bytes = dun_bytes;
 	blk_key->crypto_cfg.data_unit_size = data_unit_size;
+	blk_key->crypto_cfg.key_type = key_type;
 	blk_key->data_unit_size_bits = ilog2(data_unit_size);
-	blk_key->size = mode->keysize;
-	memcpy(blk_key->raw, raw_key, mode->keysize);
+	blk_key->size = raw_key_size;
+	memcpy(blk_key->raw, raw_key, raw_key_size);
 
 	return 0;
 }
@@ -372,8 +397,10 @@
 bool blk_crypto_config_supported(struct block_device *bdev,
 				 const struct blk_crypto_config *cfg)
 {
-	return IS_ENABLED(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) ||
-	       blk_crypto_config_supported_natively(bdev, cfg);
+	if (IS_ENABLED(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) &&
+	    cfg->key_type == BLK_CRYPTO_KEY_TYPE_STANDARD)
+		return true;
+	return blk_crypto_config_supported_natively(bdev, cfg);
 }
 
 /**
@@ -396,6 +423,10 @@
 {
 	if (blk_crypto_config_supported_natively(bdev, &key->crypto_cfg))
 		return 0;
+	if (key->crypto_cfg.key_type != BLK_CRYPTO_KEY_TYPE_STANDARD) {
+		pr_warn_once("tried to use wrapped key, but hardware doesn't support it\n");
+		return -EOPNOTSUPP;
+	}
 	return blk_crypto_fallback_start_using_mode(key->crypto_cfg.crypto_mode);
 }
 
@@ -436,3 +467,146 @@
 		pr_warn_ratelimited("%pg: error %d evicting key\n", bdev, err);
 }
 EXPORT_SYMBOL_GPL(blk_crypto_evict_key);
+
+static int blk_crypto_ioctl_import_key(struct blk_crypto_profile *profile,
+				       void __user *argp)
+{
+	struct blk_crypto_import_key_arg arg;
+	u8 raw_key[BLK_CRYPTO_MAX_STANDARD_KEY_SIZE];
+	u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE];
+	int ret;
+
+	if (copy_from_user(&arg, argp, sizeof(arg)))
+		return -EFAULT;
+
+	if (memchr_inv(arg.reserved, 0, sizeof(arg.reserved)))
+		return -EINVAL;
+
+	if (arg.raw_key_size < 16 || arg.raw_key_size > sizeof(raw_key))
+		return -EINVAL;
+
+	if (copy_from_user(raw_key, u64_to_user_ptr(arg.raw_key_ptr),
+			   arg.raw_key_size)) {
+		ret = -EFAULT;
+		goto out;
+	}
+	ret = blk_crypto_import_key(profile, raw_key, arg.raw_key_size, lt_key);
+	if (ret < 0)
+		goto out;
+	if (ret > arg.lt_key_size) {
+		ret = -EOVERFLOW;
+		goto out;
+	}
+	arg.lt_key_size = ret;
+	if (copy_to_user(u64_to_user_ptr(arg.lt_key_ptr), lt_key,
+			 arg.lt_key_size) ||
+	    copy_to_user(argp, &arg, sizeof(arg))) {
+		ret = -EFAULT;
+		goto out;
+	}
+	ret = 0;
+
+out:
+	memzero_explicit(raw_key, sizeof(raw_key));
+	memzero_explicit(lt_key, sizeof(lt_key));
+	return ret;
+}
+
+static int blk_crypto_ioctl_generate_key(struct blk_crypto_profile *profile,
+					 void __user *argp)
+{
+	struct blk_crypto_generate_key_arg arg;
+	u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE];
+	int ret;
+
+	if (copy_from_user(&arg, argp, sizeof(arg)))
+		return -EFAULT;
+
+	if (memchr_inv(arg.reserved, 0, sizeof(arg.reserved)))
+		return -EINVAL;
+
+	ret = blk_crypto_generate_key(profile, lt_key);
+	if (ret < 0)
+		goto out;
+	if (ret > arg.lt_key_size) {
+		ret = -EOVERFLOW;
+		goto out;
+	}
+	arg.lt_key_size = ret;
+	if (copy_to_user(u64_to_user_ptr(arg.lt_key_ptr), lt_key,
+			 arg.lt_key_size) ||
+	    copy_to_user(argp, &arg, sizeof(arg))) {
+		ret = -EFAULT;
+		goto out;
+	}
+	ret = 0;
+
+out:
+	memzero_explicit(lt_key, sizeof(lt_key));
+	return ret;
+}
+
+static int blk_crypto_ioctl_prepare_key(struct blk_crypto_profile *profile,
+					void __user *argp)
+{
+	struct blk_crypto_prepare_key_arg arg;
+	u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE];
+	u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE];
+	int ret;
+
+	if (copy_from_user(&arg, argp, sizeof(arg)))
+		return -EFAULT;
+
+	if (memchr_inv(arg.reserved, 0, sizeof(arg.reserved)))
+		return -EINVAL;
+
+	if (arg.lt_key_size > sizeof(lt_key))
+		return -EINVAL;
+
+	if (copy_from_user(lt_key, u64_to_user_ptr(arg.lt_key_ptr),
+			   arg.lt_key_size)) {
+		ret = -EFAULT;
+		goto out;
+	}
+	ret = blk_crypto_prepare_key(profile, lt_key, arg.lt_key_size, eph_key);
+	if (ret < 0)
+		goto out;
+	if (ret > arg.eph_key_size) {
+		ret = -EOVERFLOW;
+		goto out;
+	}
+	arg.eph_key_size = ret;
+	if (copy_to_user(u64_to_user_ptr(arg.eph_key_ptr), eph_key,
+			 arg.eph_key_size) ||
+	    copy_to_user(argp, &arg, sizeof(arg))) {
+		ret = -EFAULT;
+		goto out;
+	}
+	ret = 0;
+
+out:
+	memzero_explicit(lt_key, sizeof(lt_key));
+	memzero_explicit(eph_key, sizeof(eph_key));
+	return ret;
+}
+
+int blk_crypto_ioctl(struct block_device *bdev, unsigned int cmd,
+		     void __user *argp)
+{
+	struct blk_crypto_profile *profile =
+		bdev_get_queue(bdev)->crypto_profile;
+
+	if (!profile)
+		return -EOPNOTSUPP;
+
+	switch (cmd) {
+	case BLKCRYPTOIMPORTKEY:
+		return blk_crypto_ioctl_import_key(profile, argp);
+	case BLKCRYPTOGENERATEKEY:
+		return blk_crypto_ioctl_generate_key(profile, argp);
+	case BLKCRYPTOPREPAREKEY:
+		return blk_crypto_ioctl_prepare_key(profile, argp);
+	default:
+		return -ENOTTY;
+	}
+}
--- linux-qcom-6.8.0.orig/block/blk-flush.c
+++ linux-qcom-6.8.0/block/blk-flush.c
@@ -183,7 +183,7 @@
 		/* queue for flush */
 		if (list_empty(pending))
 			fq->flush_pending_since = jiffies;
-		list_move_tail(&rq->queuelist, pending);
+		list_add_tail(&rq->queuelist, pending);
 		break;
 
 	case REQ_FSEQ_DATA:
@@ -261,6 +261,7 @@
 		unsigned int seq = blk_flush_cur_seq(rq);
 
 		BUG_ON(seq != REQ_FSEQ_PREFLUSH && seq != REQ_FSEQ_POSTFLUSH);
+		list_del_init(&rq->queuelist);
 		blk_flush_complete_seq(rq, fq, seq, error);
 	}
 
--- linux-qcom-6.8.0.orig/block/blk-integrity.c
+++ linux-qcom-6.8.0/block/blk-integrity.c
@@ -396,8 +396,6 @@
 	if (!bi->profile)
 		return;
 
-	/* ensure all bios are off the integrity workqueue */
-	blk_flush_integrity();
 	blk_queue_flag_clear(QUEUE_FLAG_STABLE_WRITES, disk->queue);
 	memset(bi, 0, sizeof(*bi));
 }
--- linux-qcom-6.8.0.orig/block/blk-iocost.c
+++ linux-qcom-6.8.0/block/blk-iocost.c
@@ -1098,7 +1098,14 @@
 		inuse = DIV64_U64_ROUND_UP(active * iocg->child_inuse_sum,
 					   iocg->child_active_sum);
 	} else {
-		inuse = clamp_t(u32, inuse, 1, active);
+		/*
+		 * It may be tempting to turn this into a clamp expression with
+		 * a lower limit of 1 but active may be 0, which cannot be used
+		 * as an upper limit in that situation. This expression allows
+		 * active to clamp inuse unless it is 0, in which case inuse
+		 * becomes 1.
+		 */
+		inuse = min(inuse, active) ?: 1;
 	}
 
 	iocg->last_inuse = iocg->inuse;
@@ -1347,7 +1354,7 @@
 {
 	struct ioc *ioc = iocg->ioc;
 	struct blkcg_gq *blkg = iocg_to_blkg(iocg);
-	u64 tdelta, delay, new_delay;
+	u64 tdelta, delay, new_delay, shift;
 	s64 vover, vover_pct;
 	u32 hwa;
 
@@ -1362,8 +1369,9 @@
 
 	/* calculate the current delay in effect - 1/2 every second */
 	tdelta = now->now - iocg->delay_at;
-	if (iocg->delay)
-		delay = iocg->delay >> div64_u64(tdelta, USEC_PER_SEC);
+	shift = div64_u64(tdelta, USEC_PER_SEC);
+	if (iocg->delay && shift < BITS_PER_LONG)
+		delay = iocg->delay >> shift;
 	else
 		delay = 0;
 
@@ -1438,8 +1446,11 @@
 	lockdep_assert_held(&iocg->ioc->lock);
 	lockdep_assert_held(&iocg->waitq.lock);
 
-	/* make sure that nobody messed with @iocg */
-	WARN_ON_ONCE(list_empty(&iocg->active_list));
+	/*
+	 * make sure that nobody messed with @iocg. Check iocg->pd.online
+	 * to avoid warn when removing blkcg or disk.
+	 */
+	WARN_ON_ONCE(list_empty(&iocg->active_list) && iocg->pd.online);
 	WARN_ON_ONCE(iocg->inuse > 1);
 
 	iocg->abs_vdebt -= min(abs_vpay, iocg->abs_vdebt);
@@ -2072,7 +2083,7 @@
 			      struct ioc_now *now)
 {
 	struct ioc_gq *iocg;
-	u64 dur, usage_pct, nr_cycles;
+	u64 dur, usage_pct, nr_cycles, nr_cycles_shift;
 
 	/* if no debtor, reset the cycle */
 	if (!nr_debtors) {
@@ -2134,10 +2145,12 @@
 		old_debt = iocg->abs_vdebt;
 		old_delay = iocg->delay;
 
+		nr_cycles_shift = min_t(u64, nr_cycles, BITS_PER_LONG - 1);
 		if (iocg->abs_vdebt)
-			iocg->abs_vdebt = iocg->abs_vdebt >> nr_cycles ?: 1;
+			iocg->abs_vdebt = iocg->abs_vdebt >> nr_cycles_shift ?: 1;
+
 		if (iocg->delay)
-			iocg->delay = iocg->delay >> nr_cycles ?: 1;
+			iocg->delay = iocg->delay >> nr_cycles_shift ?: 1;
 
 		iocg_kick_waitq(iocg, true, now);
 
--- linux-qcom-6.8.0.orig/block/blk-map.c
+++ linux-qcom-6.8.0/block/blk-map.c
@@ -600,9 +600,7 @@
 		if (nsegs >= nr_segs || bytes > UINT_MAX - bv->bv_len)
 			goto put_bio;
 		if (bytes + bv->bv_len > nr_iter)
-			goto put_bio;
-		if (bv->bv_offset + bv->bv_len > PAGE_SIZE)
-			goto put_bio;
+			break;
 
 		nsegs++;
 		bytes += bv->bv_len;
--- linux-qcom-6.8.0.orig/block/blk-merge.c
+++ linux-qcom-6.8.0/block/blk-merge.c
@@ -252,6 +252,14 @@
 	return len > 0 || bv->bv_len > max_len;
 }
 
+static unsigned int bio_split_alignment(struct bio *bio,
+		const struct queue_limits *lim)
+{
+	if (op_is_write(bio_op(bio)) && lim->zone_write_granularity)
+		return lim->zone_write_granularity;
+	return lim->logical_block_size;
+}
+
 /**
  * bio_split_rw - split a bio in two bios
  * @bio:  [in] bio to be split
@@ -322,7 +330,7 @@
 	 * split size so that each bio is properly block size aligned, even if
 	 * we do not use the full hardware limits.
 	 */
-	bytes = ALIGN_DOWN(bytes, lim->logical_block_size);
+	bytes = ALIGN_DOWN(bytes, bio_split_alignment(bio, lim));
 
 	/*
 	 * Bio splitting may cause subtle trouble such as hang when doing sync
@@ -779,6 +787,8 @@
 	if (blk_do_io_stat(req)) {
 		part_stat_lock();
 		part_stat_inc(req->part, merges[op_stat_group(req_op(req))]);
+		part_stat_local_dec(req->part,
+				    in_flight[op_is_write(req_op(req))]);
 		part_stat_unlock();
 	}
 }
--- linux-qcom-6.8.0.orig/block/blk-mq-tag.c
+++ linux-qcom-6.8.0/block/blk-mq-tag.c
@@ -38,6 +38,7 @@
 void __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx)
 {
 	unsigned int users;
+	unsigned long flags;
 	struct blk_mq_tags *tags = hctx->tags;
 
 	/*
@@ -56,11 +57,11 @@
 			return;
 	}
 
-	spin_lock_irq(&tags->lock);
+	spin_lock_irqsave(&tags->lock, flags);
 	users = tags->active_queues + 1;
 	WRITE_ONCE(tags->active_queues, users);
 	blk_mq_update_wake_batch(tags, users);
-	spin_unlock_irq(&tags->lock);
+	spin_unlock_irqrestore(&tags->lock, flags);
 }
 
 /*
--- linux-qcom-6.8.0.orig/block/blk-mq.c
+++ linux-qcom-6.8.0/block/blk-mq.c
@@ -43,6 +43,7 @@
 
 static DEFINE_PER_CPU(struct llist_head, blk_cpu_done);
 static DEFINE_PER_CPU(call_single_data_t, blk_cpu_csd);
+static DEFINE_MUTEX(blk_mq_cpuhp_lock);
 
 static void blk_mq_insert_request(struct request *rq, blk_insert_t flags);
 static void blk_mq_request_bypass_insert(struct request *rq,
@@ -120,9 +121,59 @@
 	inflight[1] = mi.inflight[1];
 }
 
-void blk_freeze_queue_start(struct request_queue *q)
+#ifdef CONFIG_LOCKDEP
+static bool blk_freeze_set_owner(struct request_queue *q,
+				 struct task_struct *owner)
+{
+	if (!owner)
+		return false;
+
+	if (!q->mq_freeze_depth) {
+		q->mq_freeze_owner = owner;
+		q->mq_freeze_owner_depth = 1;
+		return true;
+	}
+
+	if (owner == q->mq_freeze_owner)
+		q->mq_freeze_owner_depth += 1;
+	return false;
+}
+
+/* verify the last unfreeze in owner context */
+static bool blk_unfreeze_check_owner(struct request_queue *q)
+{
+	if (!q->mq_freeze_owner)
+		return false;
+	if (q->mq_freeze_owner != current)
+		return false;
+	if (--q->mq_freeze_owner_depth == 0) {
+		q->mq_freeze_owner = NULL;
+		return true;
+	}
+	return false;
+}
+
+#else
+
+static bool blk_freeze_set_owner(struct request_queue *q,
+				 struct task_struct *owner)
+{
+	return false;
+}
+
+static bool blk_unfreeze_check_owner(struct request_queue *q)
 {
+	return false;
+}
+#endif
+
+bool __blk_freeze_queue_start(struct request_queue *q,
+			      struct task_struct *owner)
+{
+	bool freeze;
+
 	mutex_lock(&q->mq_freeze_lock);
+	freeze = blk_freeze_set_owner(q, owner);
 	if (++q->mq_freeze_depth == 1) {
 		percpu_ref_kill(&q->q_usage_counter);
 		mutex_unlock(&q->mq_freeze_lock);
@@ -131,6 +182,14 @@
 	} else {
 		mutex_unlock(&q->mq_freeze_lock);
 	}
+
+	return freeze;
+}
+
+void blk_freeze_queue_start(struct request_queue *q)
+{
+	if (__blk_freeze_queue_start(q, current))
+		blk_freeze_acquire_lock(q, false, false);
 }
 EXPORT_SYMBOL_GPL(blk_freeze_queue_start);
 
@@ -176,8 +235,10 @@
 }
 EXPORT_SYMBOL_GPL(blk_mq_freeze_queue);
 
-void __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic)
+bool __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic)
 {
+	bool unfreeze;
+
 	mutex_lock(&q->mq_freeze_lock);
 	if (force_atomic)
 		q->q_usage_counter.data->force_atomic = true;
@@ -187,16 +248,40 @@
 		percpu_ref_resurrect(&q->q_usage_counter);
 		wake_up_all(&q->mq_freeze_wq);
 	}
+	unfreeze = blk_unfreeze_check_owner(q);
 	mutex_unlock(&q->mq_freeze_lock);
+
+	return unfreeze;
 }
 
 void blk_mq_unfreeze_queue(struct request_queue *q)
 {
-	__blk_mq_unfreeze_queue(q, false);
+	if (__blk_mq_unfreeze_queue(q, false))
+		blk_unfreeze_release_lock(q, false, false);
 }
 EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue);
 
 /*
+ * non_owner variant of blk_freeze_queue_start
+ *
+ * Unlike blk_freeze_queue_start, the queue doesn't need to be unfrozen
+ * by the same task.  This is fragile and should not be used if at all
+ * possible.
+ */
+void blk_freeze_queue_start_non_owner(struct request_queue *q)
+{
+	__blk_freeze_queue_start(q, NULL);
+}
+EXPORT_SYMBOL_GPL(blk_freeze_queue_start_non_owner);
+
+/* non_owner variant of blk_mq_unfreeze_queue */
+void blk_mq_unfreeze_queue_non_owner(struct request_queue *q)
+{
+	__blk_mq_unfreeze_queue(q, false);
+}
+EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue_non_owner);
+
+/*
  * FIXME: replace the scsi_internal_device_*block_nowait() calls in the
  * mpt3sas driver such that this function can be removed.
  */
@@ -283,8 +368,9 @@
 		if (!blk_queue_skip_tagset_quiesce(q))
 			blk_mq_quiesce_queue_nowait(q);
 	}
-	blk_mq_wait_quiesce_done(set);
 	mutex_unlock(&set->tag_list_lock);
+
+	blk_mq_wait_quiesce_done(set);
 }
 EXPORT_SYMBOL_GPL(blk_mq_quiesce_tagset);
 
@@ -448,6 +534,10 @@
 	if (data->cmd_flags & REQ_NOWAIT)
 		data->flags |= BLK_MQ_REQ_NOWAIT;
 
+retry:
+	data->ctx = blk_mq_get_ctx(q);
+	data->hctx = blk_mq_map_queue(q, data->cmd_flags, data->ctx);
+
 	if (q->elevator) {
 		/*
 		 * All requests use scheduler tags when an I/O scheduler is
@@ -469,13 +559,9 @@
 			if (ops->limit_depth)
 				ops->limit_depth(data->cmd_flags, data);
 		}
-	}
-
-retry:
-	data->ctx = blk_mq_get_ctx(q);
-	data->hctx = blk_mq_map_queue(q, data->cmd_flags, data->ctx);
-	if (!(data->rq_flags & RQF_SCHED_TAGS))
+	} else {
 		blk_mq_tag_busy(data->hctx);
+	}
 
 	if (data->flags & BLK_MQ_REQ_RESERVED)
 		data->rq_flags |= RQF_RESV;
@@ -771,16 +857,11 @@
 		/*
 		 * Partial zone append completions cannot be supported as the
 		 * BIO fragments may end up not being written sequentially.
-		 * For such case, force the completed nbytes to be equal to
-		 * the BIO size so that bio_advance() sets the BIO remaining
-		 * size to 0 and we end up calling bio_endio() before returning.
 		 */
-		if (bio->bi_iter.bi_size != nbytes) {
+		if (bio->bi_iter.bi_size != nbytes)
 			bio->bi_status = BLK_STS_IOERR;
-			nbytes = bio->bi_iter.bi_size;
-		} else {
+		else
 			bio->bi_iter.bi_sector = rq->__sector;
-		}
 	}
 
 	bio_advance(bio, nbytes);
@@ -1003,6 +1084,8 @@
 		update_io_ticks(req->part, jiffies, true);
 		part_stat_inc(req->part, ios[sgrp]);
 		part_stat_add(req->part, nsecs[sgrp], now - req->start_time_ns);
+		part_stat_local_dec(req->part,
+				    in_flight[op_is_write(req_op(req))]);
 		part_stat_unlock();
 	}
 }
@@ -1025,6 +1108,8 @@
 
 		part_stat_lock();
 		update_io_ticks(req->part, jiffies, false);
+		part_stat_local_inc(req->part,
+				    in_flight[op_is_write(req_op(req))]);
 		part_stat_unlock();
 	}
 }
@@ -2242,6 +2327,24 @@
 }
 EXPORT_SYMBOL(blk_mq_delay_run_hw_queue);
 
+static inline bool blk_mq_hw_queue_need_run(struct blk_mq_hw_ctx *hctx)
+{
+	bool need_run;
+
+	/*
+	 * When queue is quiesced, we may be switching io scheduler, or
+	 * updating nr_hw_queues, or other things, and we can't run queue
+	 * any more, even blk_mq_hctx_has_pending() can't be called safely.
+	 *
+	 * And queue will be rerun in blk_mq_unquiesce_queue() if it is
+	 * quiesced.
+	 */
+	__blk_mq_run_dispatch_ops(hctx->queue, false,
+		need_run = !blk_queue_quiesced(hctx->queue) &&
+		blk_mq_hctx_has_pending(hctx));
+	return need_run;
+}
+
 /**
  * blk_mq_run_hw_queue - Start to run a hardware queue.
  * @hctx: Pointer to the hardware queue to run.
@@ -2262,20 +2365,23 @@
 
 	might_sleep_if(!async && hctx->flags & BLK_MQ_F_BLOCKING);
 
-	/*
-	 * When queue is quiesced, we may be switching io scheduler, or
-	 * updating nr_hw_queues, or other things, and we can't run queue
-	 * any more, even __blk_mq_hctx_has_pending() can't be called safely.
-	 *
-	 * And queue will be rerun in blk_mq_unquiesce_queue() if it is
-	 * quiesced.
-	 */
-	__blk_mq_run_dispatch_ops(hctx->queue, false,
-		need_run = !blk_queue_quiesced(hctx->queue) &&
-		blk_mq_hctx_has_pending(hctx));
+	need_run = blk_mq_hw_queue_need_run(hctx);
+	if (!need_run) {
+		unsigned long flags;
 
-	if (!need_run)
-		return;
+		/*
+		 * Synchronize with blk_mq_unquiesce_queue(), because we check
+		 * if hw queue is quiesced locklessly above, we need the use
+		 * ->queue_lock to make sure we see the up-to-date status to
+		 * not miss rerunning the hw queue.
+		 */
+		spin_lock_irqsave(&hctx->queue->queue_lock, flags);
+		need_run = blk_mq_hw_queue_need_run(hctx);
+		spin_unlock_irqrestore(&hctx->queue->queue_lock, flags);
+
+		if (!need_run)
+			return;
+	}
 
 	if (async || !cpumask_test_cpu(raw_smp_processor_id(), hctx->cpumask)) {
 		blk_mq_delay_run_hw_queue(hctx, 0);
@@ -2432,6 +2538,12 @@
 		return;
 
 	clear_bit(BLK_MQ_S_STOPPED, &hctx->state);
+	/*
+	 * Pairs with the smp_mb() in blk_mq_hctx_stopped() to order the
+	 * clearing of BLK_MQ_S_STOPPED above and the checking of dispatch
+	 * list in the subsequent routine.
+	 */
+	smp_mb__after_atomic();
 	blk_mq_run_hw_queue(hctx, async);
 }
 EXPORT_SYMBOL_GPL(blk_mq_start_stopped_hw_queue);
@@ -2658,6 +2770,7 @@
 
 	if (blk_mq_hctx_stopped(hctx) || blk_queue_quiesced(rq->q)) {
 		blk_mq_insert_request(rq, 0);
+		blk_mq_run_hw_queue(hctx, false);
 		return;
 	}
 
@@ -2688,6 +2801,7 @@
 
 	if (blk_mq_hctx_stopped(hctx) || blk_queue_quiesced(rq->q)) {
 		blk_mq_insert_request(rq, 0);
+		blk_mq_run_hw_queue(hctx, false);
 		return BLK_STS_OK;
 	}
 
@@ -3581,13 +3695,91 @@
 	return 0;
 }
 
-static void blk_mq_remove_cpuhp(struct blk_mq_hw_ctx *hctx)
+static void __blk_mq_remove_cpuhp(struct blk_mq_hw_ctx *hctx)
 {
-	if (!(hctx->flags & BLK_MQ_F_STACKING))
+	lockdep_assert_held(&blk_mq_cpuhp_lock);
+
+	if (!(hctx->flags & BLK_MQ_F_STACKING) &&
+	    !hlist_unhashed(&hctx->cpuhp_online)) {
 		cpuhp_state_remove_instance_nocalls(CPUHP_AP_BLK_MQ_ONLINE,
 						    &hctx->cpuhp_online);
-	cpuhp_state_remove_instance_nocalls(CPUHP_BLK_MQ_DEAD,
-					    &hctx->cpuhp_dead);
+		INIT_HLIST_NODE(&hctx->cpuhp_online);
+	}
+
+	if (!hlist_unhashed(&hctx->cpuhp_dead)) {
+		cpuhp_state_remove_instance_nocalls(CPUHP_BLK_MQ_DEAD,
+						    &hctx->cpuhp_dead);
+		INIT_HLIST_NODE(&hctx->cpuhp_dead);
+	}
+}
+
+static void blk_mq_remove_cpuhp(struct blk_mq_hw_ctx *hctx)
+{
+	mutex_lock(&blk_mq_cpuhp_lock);
+	__blk_mq_remove_cpuhp(hctx);
+	mutex_unlock(&blk_mq_cpuhp_lock);
+}
+
+static void __blk_mq_add_cpuhp(struct blk_mq_hw_ctx *hctx)
+{
+	lockdep_assert_held(&blk_mq_cpuhp_lock);
+
+	if (!(hctx->flags & BLK_MQ_F_STACKING) &&
+	    hlist_unhashed(&hctx->cpuhp_online))
+		cpuhp_state_add_instance_nocalls(CPUHP_AP_BLK_MQ_ONLINE,
+				&hctx->cpuhp_online);
+
+	if (hlist_unhashed(&hctx->cpuhp_dead))
+		cpuhp_state_add_instance_nocalls(CPUHP_BLK_MQ_DEAD,
+				&hctx->cpuhp_dead);
+}
+
+static void __blk_mq_remove_cpuhp_list(struct list_head *head)
+{
+	struct blk_mq_hw_ctx *hctx;
+
+	lockdep_assert_held(&blk_mq_cpuhp_lock);
+
+	list_for_each_entry(hctx, head, hctx_list)
+		__blk_mq_remove_cpuhp(hctx);
+}
+
+/*
+ * Unregister cpuhp callbacks from exited hw queues
+ *
+ * Safe to call if this `request_queue` is live
+ */
+static void blk_mq_remove_hw_queues_cpuhp(struct request_queue *q)
+{
+	LIST_HEAD(hctx_list);
+
+	spin_lock(&q->unused_hctx_lock);
+	list_splice_init(&q->unused_hctx_list, &hctx_list);
+	spin_unlock(&q->unused_hctx_lock);
+
+	mutex_lock(&blk_mq_cpuhp_lock);
+	__blk_mq_remove_cpuhp_list(&hctx_list);
+	mutex_unlock(&blk_mq_cpuhp_lock);
+
+	spin_lock(&q->unused_hctx_lock);
+	list_splice(&hctx_list, &q->unused_hctx_list);
+	spin_unlock(&q->unused_hctx_lock);
+}
+
+/*
+ * Register cpuhp callbacks from all hw queues
+ *
+ * Safe to call if this `request_queue` is live
+ */
+static void blk_mq_add_hw_queues_cpuhp(struct request_queue *q)
+{
+	struct blk_mq_hw_ctx *hctx;
+	unsigned long i;
+
+	mutex_lock(&blk_mq_cpuhp_lock);
+	queue_for_each_hw_ctx(q, hctx, i)
+		__blk_mq_add_cpuhp(hctx);
+	mutex_unlock(&blk_mq_cpuhp_lock);
 }
 
 /*
@@ -3638,8 +3830,6 @@
 	if (set->ops->exit_hctx)
 		set->ops->exit_hctx(hctx, hctx_idx);
 
-	blk_mq_remove_cpuhp(hctx);
-
 	xa_erase(&q->hctx_table, hctx_idx);
 
 	spin_lock(&q->unused_hctx_lock);
@@ -3656,6 +3846,7 @@
 	queue_for_each_hw_ctx(q, hctx, i) {
 		if (i == nr_queue)
 			break;
+		blk_mq_remove_cpuhp(hctx);
 		blk_mq_exit_hctx(q, set, hctx, i);
 	}
 }
@@ -3666,16 +3857,11 @@
 {
 	hctx->queue_num = hctx_idx;
 
-	if (!(hctx->flags & BLK_MQ_F_STACKING))
-		cpuhp_state_add_instance_nocalls(CPUHP_AP_BLK_MQ_ONLINE,
-				&hctx->cpuhp_online);
-	cpuhp_state_add_instance_nocalls(CPUHP_BLK_MQ_DEAD, &hctx->cpuhp_dead);
-
 	hctx->tags = set->tags[hctx_idx];
 
 	if (set->ops->init_hctx &&
 	    set->ops->init_hctx(hctx, set->driver_data, hctx_idx))
-		goto unregister_cpu_notifier;
+		goto fail;
 
 	if (blk_mq_init_request(set, hctx->fq->flush_rq, hctx_idx,
 				hctx->numa_node))
@@ -3692,8 +3878,7 @@
  exit_hctx:
 	if (set->ops->exit_hctx)
 		set->ops->exit_hctx(hctx, hctx_idx);
- unregister_cpu_notifier:
-	blk_mq_remove_cpuhp(hctx);
+ fail:
 	return -1;
 }
 
@@ -3719,6 +3904,8 @@
 	INIT_DELAYED_WORK(&hctx->run_work, blk_mq_run_work_fn);
 	spin_lock_init(&hctx->lock);
 	INIT_LIST_HEAD(&hctx->dispatch);
+	INIT_HLIST_NODE(&hctx->cpuhp_dead);
+	INIT_HLIST_NODE(&hctx->cpuhp_online);
 	hctx->queue = q;
 	hctx->flags = set->flags & ~BLK_MQ_F_TAG_QUEUE_SHARED;
 
@@ -4162,6 +4349,15 @@
 }
 EXPORT_SYMBOL(blk_mq_alloc_disk_for_queue);
 
+/*
+ * Only hctx removed from cpuhp list can be reused
+ */
+static bool blk_mq_hctx_is_reusable(struct blk_mq_hw_ctx *hctx)
+{
+	return hlist_unhashed(&hctx->cpuhp_online) &&
+		hlist_unhashed(&hctx->cpuhp_dead);
+}
+
 static struct blk_mq_hw_ctx *blk_mq_alloc_and_init_hctx(
 		struct blk_mq_tag_set *set, struct request_queue *q,
 		int hctx_idx, int node)
@@ -4171,7 +4367,7 @@
 	/* reuse dead hctx first */
 	spin_lock(&q->unused_hctx_lock);
 	list_for_each_entry(tmp, &q->unused_hctx_list, hctx_list) {
-		if (tmp->numa_node == node) {
+		if (tmp->numa_node == node && blk_mq_hctx_is_reusable(tmp)) {
 			hctx = tmp;
 			break;
 		}
@@ -4237,6 +4433,12 @@
 	xa_for_each_start(&q->hctx_table, j, hctx, j)
 		blk_mq_exit_hctx(q, set, hctx, j);
 	mutex_unlock(&q->sysfs_lock);
+
+	/* unregister cpuhp callbacks for exited hctxs */
+	blk_mq_remove_hw_queues_cpuhp(q);
+
+	/* register cpuhp for new initialized hctxs */
+	blk_mq_add_hw_queues_cpuhp(q);
 }
 
 static void blk_mq_update_poll_flag(struct request_queue *q)
@@ -4256,6 +4458,12 @@
 	/* mark the queue as mq asap */
 	q->mq_ops = set->ops;
 
+	/*
+	 * ->tag_set has to be setup before initialize hctx, which cpuphp
+	 * handler needs it for checking queue mapping
+	 */
+	q->tag_set = set;
+
 	if (blk_mq_alloc_ctxs(q))
 		goto err_exit;
 
@@ -4274,8 +4482,6 @@
 	INIT_WORK(&q->timeout_work, blk_mq_timeout_work);
 	blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ);
 
-	q->tag_set = set;
-
 	q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT;
 	blk_mq_update_poll_flag(q);
 
--- linux-qcom-6.8.0.orig/block/blk-mq.h
+++ linux-qcom-6.8.0/block/blk-mq.h
@@ -228,6 +228,19 @@
 
 static inline bool blk_mq_hctx_stopped(struct blk_mq_hw_ctx *hctx)
 {
+	/* Fast path: hardware queue is not stopped most of the time. */
+	if (likely(!test_bit(BLK_MQ_S_STOPPED, &hctx->state)))
+		return false;
+
+	/*
+	 * This barrier is used to order adding of dispatch list before and
+	 * the test of BLK_MQ_S_STOPPED below. Pairs with the memory barrier
+	 * in blk_mq_start_stopped_hw_queue() so that dispatch code could
+	 * either see BLK_MQ_S_STOPPED is cleared or dispatch list is not
+	 * empty to avoid missing dispatching requests.
+	 */
+	smp_mb();
+
 	return test_bit(BLK_MQ_S_STOPPED, &hctx->state);
 }
 
--- linux-qcom-6.8.0.orig/block/blk-rq-qos.c
+++ linux-qcom-6.8.0/block/blk-rq-qos.c
@@ -219,8 +219,8 @@
 
 	data->got_token = true;
 	smp_wmb();
-	list_del_init(&curr->entry);
 	wake_up_process(data->task);
+	list_del_init_careful(&curr->entry);
 	return 1;
 }
 
--- linux-qcom-6.8.0.orig/block/blk-settings.c
+++ linux-qcom-6.8.0/block/blk-settings.c
@@ -559,6 +559,8 @@
 	unsigned int top, bottom, alignment, ret = 0;
 
 	t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
+	t->max_user_sectors = min_not_zero(t->max_user_sectors,
+			b->max_user_sectors);
 	t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors);
 	t->max_dev_sectors = min_not_zero(t->max_dev_sectors, b->max_dev_sectors);
 	t->max_write_zeroes_sectors = min(t->max_write_zeroes_sectors,
@@ -689,6 +691,10 @@
 	t->zone_write_granularity = max(t->zone_write_granularity,
 					b->zone_write_granularity);
 	t->zoned = max(t->zoned, b->zoned);
+	if (!t->zoned) {
+		t->zone_write_granularity = 0;
+		t->max_zone_append_sectors = 0;
+	}
 	return ret;
 }
 EXPORT_SYMBOL(blk_stack_limits);
--- linux-qcom-6.8.0.orig/block/blk-stat.c
+++ linux-qcom-6.8.0/block/blk-stat.c
@@ -27,7 +27,7 @@
 /* src is a per-cpu stat, mean isn't initialized */
 void blk_rq_stat_sum(struct blk_rq_stat *dst, struct blk_rq_stat *src)
 {
-	if (!src->nr_samples)
+	if (dst->nr_samples + src->nr_samples <= dst->nr_samples)
 		return;
 
 	dst->min = min(dst->min, src->min);
--- linux-qcom-6.8.0.orig/block/blk-sysfs.c
+++ linux-qcom-6.8.0/block/blk-sysfs.c
@@ -839,10 +839,8 @@
 	 * faster to shut down and is made fully functional here as
 	 * request_queues for non-existent devices never get registered.
 	 */
-	if (!blk_queue_init_done(q)) {
-		blk_queue_flag_set(QUEUE_FLAG_INIT_DONE, q);
-		percpu_ref_switch_to_percpu(&q->q_usage_counter);
-	}
+	blk_queue_flag_set(QUEUE_FLAG_INIT_DONE, q);
+	percpu_ref_switch_to_percpu(&q->q_usage_counter);
 
 	return ret;
 
--- linux-qcom-6.8.0.orig/block/blk.h
+++ linux-qcom-6.8.0/block/blk.h
@@ -3,6 +3,7 @@
 #define BLK_INTERNAL_H
 
 #include <linux/blk-crypto.h>
+#include <linux/lockdep.h>
 #include <linux/memblock.h>	/* for max_pfn/max_low_pfn */
 #include <xen/xen.h>
 #include "blk-crypto-internal.h"
@@ -32,8 +33,10 @@
 void blk_free_flush_queue(struct blk_flush_queue *q);
 
 void blk_freeze_queue(struct request_queue *q);
-void __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic);
-void blk_queue_start_drain(struct request_queue *q);
+bool __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic);
+bool blk_queue_start_drain(struct request_queue *q);
+bool __blk_freeze_queue_start(struct request_queue *q,
+			      struct task_struct *owner);
 int __bio_queue_enter(struct request_queue *q, struct bio *bio);
 void submit_bio_noacct_nocheck(struct bio *bio);
 
@@ -65,8 +68,11 @@
 {
 	struct request_queue *q = bdev_get_queue(bio->bi_bdev);
 
-	if (blk_try_enter_queue(q, false))
+	if (blk_try_enter_queue(q, false)) {
+		rwsem_acquire_read(&q->io_lockdep_map, 0, 0, _RET_IP_);
+		rwsem_release(&q->io_lockdep_map, _RET_IP_);
 		return 0;
+	}
 	return __bio_queue_enter(q, bio);
 }
 
@@ -344,6 +350,7 @@
 }
 
 void update_io_ticks(struct block_device *part, unsigned long now, bool end);
+unsigned int part_in_flight(struct block_device *part);
 
 static inline void req_set_nomerge(struct request_queue *q, struct request *req)
 {
@@ -516,4 +523,22 @@
 	return atomic_read(&req->ref);
 }
 
+static inline void blk_freeze_acquire_lock(struct request_queue *q, bool
+		disk_dead, bool queue_dying)
+{
+	if (!disk_dead)
+		rwsem_acquire(&q->io_lockdep_map, 0, 1, _RET_IP_);
+	if (!queue_dying)
+		rwsem_acquire(&q->q_lockdep_map, 0, 1, _RET_IP_);
+}
+
+static inline void blk_unfreeze_release_lock(struct request_queue *q, bool
+		disk_dead, bool queue_dying)
+{
+	if (!queue_dying)
+		rwsem_release(&q->q_lockdep_map, _RET_IP_);
+	if (!disk_dead)
+		rwsem_release(&q->io_lockdep_map, _RET_IP_);
+}
+
 #endif /* BLK_INTERNAL_H */
--- linux-qcom-6.8.0.orig/block/elevator.c
+++ linux-qcom-6.8.0/block/elevator.c
@@ -558,7 +558,7 @@
 static inline bool elv_support_iosched(struct request_queue *q)
 {
 	if (!queue_is_mq(q) ||
-	    (q->tag_set && (q->tag_set->flags & BLK_MQ_F_NO_SCHED)))
+	    (q->tag_set->flags & BLK_MQ_F_NO_SCHED))
 		return false;
 	return true;
 }
@@ -569,7 +569,7 @@
  */
 static struct elevator_type *elevator_get_default(struct request_queue *q)
 {
-	if (q->tag_set && q->tag_set->flags & BLK_MQ_F_NO_SCHED_BY_DEFAULT)
+	if (q->tag_set->flags & BLK_MQ_F_NO_SCHED_BY_DEFAULT)
 		return NULL;
 
 	if (q->nr_hw_queues != 1 &&
@@ -635,13 +635,19 @@
 	 * drain any dispatch activities originated from passthrough
 	 * requests, then no need to quiesce queue which may add long boot
 	 * latency, especially when lots of disks are involved.
+	 *
+	 * Disk isn't added yet, so verifying queue lock only manually.
 	 */
-	blk_mq_freeze_queue(q);
+	blk_freeze_queue_start_non_owner(q);
+	blk_freeze_acquire_lock(q, true, false);
+	blk_mq_freeze_queue_wait(q);
+
 	blk_mq_cancel_work_sync(q);
 
 	err = blk_mq_init_sched(q, e);
 
-	blk_mq_unfreeze_queue(q);
+	blk_unfreeze_release_lock(q, true, false);
+	blk_mq_unfreeze_queue_non_owner(q);
 
 	if (err) {
 		pr_warn("\"%s\" elevator initialization failed, "
--- linux-qcom-6.8.0.orig/block/fops.c
+++ linux-qcom-6.8.0/block/fops.c
@@ -387,7 +387,7 @@
 
 	iomap->bdev = bdev;
 	iomap->offset = ALIGN_DOWN(offset, bdev_logical_block_size(bdev));
-	if (iomap->offset >= isize)
+	if (offset >= isize)
 		return -EIO;
 	iomap->type = IOMAP_MAPPED;
 	iomap->addr = iomap->offset;
@@ -745,11 +745,12 @@
 		file_accessed(iocb->ki_filp);
 
 		ret = blkdev_direct_IO(iocb, to);
-		if (ret >= 0) {
+		if (ret > 0) {
 			iocb->ki_pos += ret;
 			count -= ret;
 		}
-		iov_iter_revert(to, count - iov_iter_count(to));
+		if (ret != -EIOCBQUEUED)
+			iov_iter_revert(to, count - iov_iter_count(to));
 		if (ret < 0 || !count)
 			goto reexpand;
 	}
--- linux-qcom-6.8.0.orig/block/genhd.c
+++ linux-qcom-6.8.0/block/genhd.c
@@ -118,7 +118,7 @@
 	}
 }
 
-static unsigned int part_in_flight(struct block_device *part)
+unsigned int part_in_flight(struct block_device *part)
 {
 	unsigned int inflight = 0;
 	int cpu;
@@ -345,9 +345,7 @@
 	struct bdev_handle *handle;
 	int ret = 0;
 
-	if (disk->flags & (GENHD_FL_NO_PART | GENHD_FL_HIDDEN))
-		return -EINVAL;
-	if (test_bit(GD_SUPPRESS_PART_SCAN, &disk->state))
+	if (!disk_has_partscan(disk))
 		return -EINVAL;
 	if (disk->open_partitions)
 		return -EBUSY;
@@ -503,8 +501,7 @@
 			goto out_unregister_bdi;
 
 		/* Make sure the first partition scan will be proceed */
-		if (get_capacity(disk) && !(disk->flags & GENHD_FL_NO_PART) &&
-		    !test_bit(GD_SUPPRESS_PART_SCAN, &disk->state))
+		if (get_capacity(disk) && disk_has_partscan(disk))
 			set_bit(GD_NEED_PART_SCAN, &disk->state);
 
 		bdev_add(disk->part0, ddev->devt);
@@ -583,13 +580,13 @@
 	rcu_read_unlock();
 }
 
-static void __blk_mark_disk_dead(struct gendisk *disk)
+static bool __blk_mark_disk_dead(struct gendisk *disk)
 {
 	/*
 	 * Fail any new I/O.
 	 */
 	if (test_and_set_bit(GD_DEAD, &disk->state))
-		return;
+		return false;
 
 	if (test_bit(GD_OWNS_QUEUE, &disk->state))
 		blk_queue_flag_set(QUEUE_FLAG_DYING, disk->queue);
@@ -602,7 +599,7 @@
 	/*
 	 * Prevent new I/O from crossing bio_queue_enter().
 	 */
-	blk_queue_start_drain(disk->queue);
+	return blk_queue_start_drain(disk->queue);
 }
 
 /**
@@ -643,6 +640,7 @@
 	struct request_queue *q = disk->queue;
 	struct block_device *part;
 	unsigned long idx;
+	bool start_drain, queue_dying;
 
 	might_sleep();
 
@@ -665,12 +663,15 @@
 	 */
 	if (!test_bit(GD_DEAD, &disk->state))
 		blk_report_disk_dead(disk, false);
-	__blk_mark_disk_dead(disk);
 
 	/*
 	 * Drop all partitions now that the disk is marked dead.
 	 */
 	mutex_lock(&disk->open_mutex);
+	start_drain = __blk_mark_disk_dead(disk);
+	queue_dying = blk_queue_dying(q);
+	if (start_drain)
+		blk_freeze_acquire_lock(q, true, queue_dying);
 	xa_for_each_start(&disk->part_tbl, idx, part, 1)
 		drop_partition(part);
 	mutex_unlock(&disk->open_mutex);
@@ -720,13 +721,13 @@
 	 * If the disk does not own the queue, allow using passthrough requests
 	 * again.  Else leave the queue frozen to fail all I/O.
 	 */
-	if (!test_bit(GD_OWNS_QUEUE, &disk->state)) {
-		blk_queue_flag_clear(QUEUE_FLAG_INIT_DONE, q);
+	if (!test_bit(GD_OWNS_QUEUE, &disk->state))
 		__blk_mq_unfreeze_queue(q, true);
-	} else {
-		if (queue_is_mq(q))
-			blk_mq_exit_queue(q);
-	}
+	else if (queue_is_mq(q))
+		blk_mq_exit_queue(q);
+
+	if (start_drain)
+		blk_unfreeze_release_lock(q, true, queue_dying);
 }
 EXPORT_SYMBOL(del_gendisk);
 
@@ -776,7 +777,7 @@
 }
 
 #ifdef CONFIG_BLOCK_LEGACY_AUTOLOAD
-void blk_request_module(dev_t devt)
+static bool blk_probe_dev(dev_t devt)
 {
 	unsigned int major = MAJOR(devt);
 	struct blk_major_name **n;
@@ -786,14 +787,26 @@
 		if ((*n)->major == major && (*n)->probe) {
 			(*n)->probe(devt);
 			mutex_unlock(&major_names_lock);
-			return;
+			return true;
 		}
 	}
 	mutex_unlock(&major_names_lock);
+	return false;
+}
 
-	if (request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt)) > 0)
-		/* Make old-style 2.4 aliases work */
-		request_module("block-major-%d", MAJOR(devt));
+void blk_request_module(dev_t devt)
+{
+	int error;
+
+	if (blk_probe_dev(devt))
+		return;
+
+	error = request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt));
+	/* Make old-style 2.4 aliases work */
+	if (error > 0)
+		error = request_module("block-major-%d", MAJOR(devt));
+	if (!error)
+		blk_probe_dev(devt);
 }
 #endif /* CONFIG_BLOCK_LEGACY_AUTOLOAD */
 
@@ -1047,6 +1060,12 @@
 	return sprintf(buf, "%llu\n", disk->diskseq);
 }
 
+static ssize_t partscan_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%u\n", disk_has_partscan(dev_to_disk(dev)));
+}
+
 static DEVICE_ATTR(range, 0444, disk_range_show, NULL);
 static DEVICE_ATTR(ext_range, 0444, disk_ext_range_show, NULL);
 static DEVICE_ATTR(removable, 0444, disk_removable_show, NULL);
@@ -1060,6 +1079,7 @@
 static DEVICE_ATTR(inflight, 0444, part_inflight_show, NULL);
 static DEVICE_ATTR(badblocks, 0644, disk_badblocks_show, disk_badblocks_store);
 static DEVICE_ATTR(diskseq, 0444, diskseq_show, NULL);
+static DEVICE_ATTR(partscan, 0444, partscan_show, NULL);
 
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 ssize_t part_fail_show(struct device *dev,
@@ -1106,6 +1126,7 @@
 	&dev_attr_events_async.attr,
 	&dev_attr_events_poll_msecs.attr,
 	&dev_attr_diskseq.attr,
+	&dev_attr_partscan.attr,
 #ifdef CONFIG_FAIL_MAKE_REQUEST
 	&dev_attr_fail.attr,
 #endif
--- linux-qcom-6.8.0.orig/block/holder.c
+++ linux-qcom-6.8.0/block/holder.c
@@ -8,6 +8,8 @@
 	int			refcnt;
 };
 
+static DEFINE_MUTEX(blk_holder_mutex);
+
 static struct bd_holder_disk *bd_find_holder_disk(struct block_device *bdev,
 						  struct gendisk *disk)
 {
@@ -80,7 +82,7 @@
 	kobject_get(bdev->bd_holder_dir);
 	mutex_unlock(&bdev->bd_disk->open_mutex);
 
-	mutex_lock(&disk->open_mutex);
+	mutex_lock(&blk_holder_mutex);
 	WARN_ON_ONCE(!bdev->bd_holder);
 
 	holder = bd_find_holder_disk(bdev, disk);
@@ -108,7 +110,7 @@
 		goto out_del_symlink;
 	list_add(&holder->list, &disk->slave_bdevs);
 
-	mutex_unlock(&disk->open_mutex);
+	mutex_unlock(&blk_holder_mutex);
 	return 0;
 
 out_del_symlink:
@@ -116,7 +118,7 @@
 out_free_holder:
 	kfree(holder);
 out_unlock:
-	mutex_unlock(&disk->open_mutex);
+	mutex_unlock(&blk_holder_mutex);
 	if (ret)
 		kobject_put(bdev->bd_holder_dir);
 	return ret;
@@ -140,7 +142,7 @@
 	if (WARN_ON_ONCE(!disk->slave_dir))
 		return;
 
-	mutex_lock(&disk->open_mutex);
+	mutex_lock(&blk_holder_mutex);
 	holder = bd_find_holder_disk(bdev, disk);
 	if (!WARN_ON_ONCE(holder == NULL) && !--holder->refcnt) {
 		del_symlink(disk->slave_dir, bdev_kobj(bdev));
@@ -149,6 +151,6 @@
 		list_del_init(&holder->list);
 		kfree(holder);
 	}
-	mutex_unlock(&disk->open_mutex);
+	mutex_unlock(&blk_holder_mutex);
 }
 EXPORT_SYMBOL_GPL(bd_unlink_disk_holder);
--- linux-qcom-6.8.0.orig/block/ioctl.c
+++ linux-qcom-6.8.0/block/ioctl.c
@@ -12,6 +12,7 @@
 #include <linux/pr.h>
 #include <linux/uaccess.h>
 #include "blk.h"
+#include "blk-crypto-internal.h"
 
 static int blkpg_do_ioctl(struct block_device *bdev,
 			  struct blkpg_partition __user *upart, int op)
@@ -33,7 +34,7 @@
 	if (op == BLKPG_DEL_PARTITION)
 		return bdev_del_partition(disk, p.pno);
 
-	if (p.start < 0 || p.length <= 0 || p.start + p.length < 0)
+	if (p.start < 0 || p.length <= 0 || LLONG_MAX - p.length < p.start)
 		return -EINVAL;
 	/* Check that the partition is aligned to the block size */
 	if (!IS_ALIGNED(p.start | p.length, bdev_logical_block_size(bdev)))
@@ -89,7 +90,7 @@
 		unsigned long arg)
 {
 	uint64_t range[2];
-	uint64_t start, len;
+	uint64_t start, len, end;
 	struct inode *inode = bdev->bd_inode;
 	int err;
 
@@ -110,11 +111,12 @@
 	if (len & 511)
 		return -EINVAL;
 
-	if (start + len > bdev_nr_bytes(bdev))
+	if (check_add_overflow(start, len, &end) ||
+	    end > bdev_nr_bytes(bdev))
 		return -EINVAL;
 
 	filemap_invalidate_lock(inode->i_mapping);
-	err = truncate_bdev_range(bdev, mode, start, start + len - 1);
+	err = truncate_bdev_range(bdev, mode, start, end - 1);
 	if (err)
 		goto fail;
 	err = blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL);
@@ -126,7 +128,7 @@
 static int blk_ioctl_secure_erase(struct block_device *bdev, blk_mode_t mode,
 		void __user *argp)
 {
-	uint64_t start, len;
+	uint64_t start, len, end;
 	uint64_t range[2];
 	int err;
 
@@ -141,11 +143,12 @@
 	len = range[1];
 	if ((start & 511) || (len & 511))
 		return -EINVAL;
-	if (start + len > bdev_nr_bytes(bdev))
+	if (check_add_overflow(start, len, &end) ||
+	    end > bdev_nr_bytes(bdev))
 		return -EINVAL;
 
 	filemap_invalidate_lock(bdev->bd_inode->i_mapping);
-	err = truncate_bdev_range(bdev, mode, start, start + len - 1);
+	err = truncate_bdev_range(bdev, mode, start, end - 1);
 	if (!err)
 		err = blkdev_issue_secure_erase(bdev, start >> 9, len >> 9,
 						GFP_KERNEL);
@@ -556,11 +559,16 @@
 			return -EACCES;
 		if (bdev_is_partition(bdev))
 			return -EINVAL;
-		return disk_scan_partitions(bdev->bd_disk, mode);
+		return disk_scan_partitions(bdev->bd_disk,
+				mode | BLK_OPEN_STRICT_SCAN);
 	case BLKTRACESTART:
 	case BLKTRACESTOP:
 	case BLKTRACETEARDOWN:
 		return blk_trace_ioctl(bdev, cmd, argp);
+	case BLKCRYPTOIMPORTKEY:
+	case BLKCRYPTOGENERATEKEY:
+	case BLKCRYPTOPREPAREKEY:
+		return blk_crypto_ioctl(bdev, cmd, argp);
 	case IOC_PR_REGISTER:
 		return blkdev_pr_register(bdev, mode, argp);
 	case IOC_PR_RESERVE:
--- linux-qcom-6.8.0.orig/block/mq-deadline.c
+++ linux-qcom-6.8.0/block/mq-deadline.c
@@ -622,6 +622,20 @@
 }
 
 /*
+ * 'depth' is a number in the range 1..INT_MAX representing a number of
+ * requests. Scale it with a factor (1 << bt->sb.shift) / q->nr_requests since
+ * 1..(1 << bt->sb.shift) is the range expected by sbitmap_get_shallow().
+ * Values larger than q->nr_requests have the same effect as q->nr_requests.
+ */
+static int dd_to_word_depth(struct blk_mq_hw_ctx *hctx, unsigned int qdepth)
+{
+	struct sbitmap_queue *bt = &hctx->sched_tags->bitmap_tags;
+	const unsigned int nrr = hctx->queue->nr_requests;
+
+	return ((qdepth << bt->sb.shift) + nrr - 1) / nrr;
+}
+
+/*
  * Called by __blk_mq_alloc_request(). The shallow_depth value set by this
  * function is used by __blk_mq_get_tag().
  */
@@ -637,7 +651,7 @@
 	 * Throttle asynchronous requests and writes such that these requests
 	 * do not block the allocation of synchronous requests.
 	 */
-	data->shallow_depth = dd->async_depth;
+	data->shallow_depth = dd_to_word_depth(data->hctx, dd->async_depth);
 }
 
 /* Called by blk_mq_update_nr_requests(). */
@@ -646,11 +660,10 @@
 	struct request_queue *q = hctx->queue;
 	struct deadline_data *dd = q->elevator->elevator_data;
 	struct blk_mq_tags *tags = hctx->sched_tags;
-	unsigned int shift = tags->bitmap_tags.sb.shift;
 
-	dd->async_depth = max(1U, 3 * (1U << shift)  / 4);
+	dd->async_depth = q->nr_requests;
 
-	sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, dd->async_depth);
+	sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, 1);
 }
 
 /* Called by blk_mq_init_hctx() and blk_mq_init_sched(). */
--- linux-qcom-6.8.0.orig/block/partitions/cmdline.c
+++ linux-qcom-6.8.0/block/partitions/cmdline.c
@@ -70,8 +70,8 @@
 	}
 
 	if (*partdef == '(') {
-		int length;
-		char *next = strchr(++partdef, ')');
+		partdef++;
+		char *next = strsep(&partdef, ")");
 
 		if (!next) {
 			pr_warn("cmdline partition format is invalid.");
@@ -79,11 +79,7 @@
 			goto fail;
 		}
 
-		length = min_t(int, next - partdef,
-			       sizeof(new_subpart->name) - 1);
-		strscpy(new_subpart->name, partdef, length);
-
-		partdef = ++next;
+		strscpy(new_subpart->name, next, sizeof(new_subpart->name));
 	} else
 		new_subpart->name[0] = '\0';
 
@@ -117,14 +113,12 @@
 	}
 }
 
-static int parse_parts(struct cmdline_parts **parts, const char *bdevdef)
+static int parse_parts(struct cmdline_parts **parts, char *bdevdef)
 {
 	int ret = -EINVAL;
 	char *next;
-	int length;
 	struct cmdline_subpart **next_subpart;
 	struct cmdline_parts *newparts;
-	char buf[BDEVNAME_SIZE + 32 + 4];
 
 	*parts = NULL;
 
@@ -132,28 +126,19 @@
 	if (!newparts)
 		return -ENOMEM;
 
-	next = strchr(bdevdef, ':');
+	next = strsep(&bdevdef, ":");
 	if (!next) {
 		pr_warn("cmdline partition has no block device.");
 		goto fail;
 	}
 
-	length = min_t(int, next - bdevdef, sizeof(newparts->name) - 1);
-	strscpy(newparts->name, bdevdef, length);
+	strscpy(newparts->name, next, sizeof(newparts->name));
 	newparts->nr_subparts = 0;
 
 	next_subpart = &newparts->subpart;
 
-	while (next && *(++next)) {
-		bdevdef = next;
-		next = strchr(bdevdef, ',');
-
-		length = (!next) ? (sizeof(buf) - 1) :
-			min_t(int, next - bdevdef, sizeof(buf) - 1);
-
-		strscpy(buf, bdevdef, length);
-
-		ret = parse_subpart(next_subpart, buf);
+	while ((next = strsep(&bdevdef, ","))) {
+		ret = parse_subpart(next_subpart, next);
 		if (ret)
 			goto fail;
 
@@ -199,24 +184,17 @@
 
 	*parts = NULL;
 
-	next = pbuf = buf = kstrdup(cmdline, GFP_KERNEL);
+	pbuf = buf = kstrdup(cmdline, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
 
 	next_parts = parts;
 
-	while (next && *pbuf) {
-		next = strchr(pbuf, ';');
-		if (next)
-			*next = '\0';
-
-		ret = parse_parts(next_parts, pbuf);
+	while ((next = strsep(&pbuf, ";"))) {
+		ret = parse_parts(next_parts, next);
 		if (ret)
 			goto fail;
 
-		if (next)
-			pbuf = ++next;
-
 		next_parts = &(*next_parts)->next_parts;
 	}
 
@@ -250,7 +228,6 @@
 static int add_part(int slot, struct cmdline_subpart *subpart,
 		struct parsed_partitions *state)
 {
-	int label_min;
 	struct partition_meta_info *info;
 	char tmp[sizeof(info->volname) + 4];
 
@@ -262,9 +239,7 @@
 
 	info = &state->parts[slot].info;
 
-	label_min = min_t(int, sizeof(info->volname) - 1,
-			  sizeof(subpart->name));
-	strscpy(info->volname, subpart->name, label_min);
+	strscpy(info->volname, subpart->name, sizeof(info->volname));
 
 	snprintf(tmp, sizeof(tmp), "(%s)", info->volname);
 	strlcat(state->pp_buf, tmp, PAGE_SIZE);
--- linux-qcom-6.8.0.orig/block/partitions/core.c
+++ linux-qcom-6.8.0/block/partitions/core.c
@@ -566,9 +566,11 @@
 
 	part = add_partition(disk, p, from, size, state->parts[p].flags,
 			     &state->parts[p].info);
-	if (IS_ERR(part) && PTR_ERR(part) != -ENXIO) {
-		printk(KERN_ERR " %s: p%d could not be added: %pe\n",
-		       disk->disk_name, p, part);
+	if (IS_ERR(part)) {
+		if (PTR_ERR(part) != -ENXIO) {
+			printk(KERN_ERR " %s: p%d could not be added: %pe\n",
+			       disk->disk_name, p, part);
+		}
 		return true;
 	}
 
@@ -584,10 +586,7 @@
 	struct parsed_partitions *state;
 	int ret = -EAGAIN, p;
 
-	if (disk->flags & GENHD_FL_NO_PART)
-		return 0;
-
-	if (test_bit(GD_SUPPRESS_PART_SCAN, &disk->state))
+	if (!disk_has_partscan(disk))
 		return 0;
 
 	state = check_partition(disk);
--- linux-qcom-6.8.0.orig/block/partitions/ldm.h
+++ linux-qcom-6.8.0/block/partitions/ldm.h
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
-/**
+/*
  * ldm - Part of the Linux-NTFS project.
  *
  * Copyright (C) 2001,2002 Richard Russon <ldm@flatcap.org>
--- linux-qcom-6.8.0.orig/block/sed-opal.c
+++ linux-qcom-6.8.0/block/sed-opal.c
@@ -314,7 +314,7 @@
 			      &key_type_user, key_name, true);
 
 	if (IS_ERR(kref))
-		ret = PTR_ERR(kref);
+		return PTR_ERR(kref);
 
 	key = key_ref_to_ptr(kref);
 	down_read(&key->sem);
--- linux-qcom-6.8.0.orig/certs/blacklist.c
+++ linux-qcom-6.8.0/certs/blacklist.c
@@ -276,6 +276,9 @@
 	if (IS_ERR(key)) {
 		pr_err("Problem with revocation key (%ld)\n", PTR_ERR(key));
 		return PTR_ERR(key);
+	} else {
+		pr_notice("Revoked X.509 cert '%s'\n",
+			  key_ref_to_ptr(key)->description);
 	}
 
 	return 0;
--- linux-qcom-6.8.0.orig/crypto/Kconfig
+++ linux-qcom-6.8.0/crypto/Kconfig
@@ -1269,10 +1269,11 @@
 
 	  A non-physical non-deterministic ("true") RNG (e.g., an entropy source
 	  compliant with NIST SP800-90B) intended to provide a seed to a
-	  deterministic RNG (e.g.  per NIST SP800-90C).
+	  deterministic RNG (e.g., per NIST SP800-90C).
 	  This RNG does not perform any cryptographic whitening of the generated
+	  random numbers.
 
-	  See https://www.chronox.de/jent.html
+	  See https://www.chronox.de/jent/
 
 if CRYPTO_JITTERENTROPY
 if CRYPTO_FIPS && EXPERT
--- linux-qcom-6.8.0.orig/crypto/aead.c
+++ linux-qcom-6.8.0/crypto/aead.c
@@ -45,8 +45,7 @@
 	alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
 	memcpy(alignbuffer, key, keylen);
 	ret = crypto_aead_alg(tfm)->setkey(tfm, alignbuffer, keylen);
-	memset(alignbuffer, 0, keylen);
-	kfree(buffer);
+	kfree_sensitive(buffer);
 	return ret;
 }
 
--- linux-qcom-6.8.0.orig/crypto/aegis128-neon-inner.c
+++ linux-qcom-6.8.0/crypto/aegis128-neon-inner.c
@@ -148,8 +148,8 @@
 		kiv,
 		vld1q_u8(const1),
 		vld1q_u8(const0),
-		k ^ vld1q_u8(const0),
-		k ^ vld1q_u8(const1),
+		(uint8x16_t) (k ^ vld1q_u8(const0)),
+		(uint8x16_t) (k ^ vld1q_u8(const1)),
 	}};
 	int i;
 
--- linux-qcom-6.8.0.orig/crypto/algapi.c
+++ linux-qcom-6.8.0/crypto/algapi.c
@@ -396,7 +396,7 @@
 	q->cra_flags |= CRYPTO_ALG_DEAD;
 	alg = test->adult;
 
-	if (list_empty(&alg->cra_list))
+	if (crypto_is_dead(alg))
 		goto complete;
 
 	if (err == -ECANCELED)
@@ -1059,6 +1059,8 @@
 	if (IS_ENABLED(CONFIG_CRYPTO_MANAGER_DISABLE_TESTS))
 		return;
 
+	set_crypto_boot_test_finished();
+
 	for (;;) {
 		struct crypto_larval *larval = NULL;
 		struct crypto_alg *q;
@@ -1091,8 +1093,6 @@
 
 		crypto_wait_for_test(larval);
 	}
-
-	set_crypto_boot_test_finished();
 }
 
 static int __init crypto_algapi_init(void)
--- linux-qcom-6.8.0.orig/crypto/asymmetric_keys/Kconfig
+++ linux-qcom-6.8.0/crypto/asymmetric_keys/Kconfig
@@ -15,6 +15,7 @@
 	select MPILIB
 	select CRYPTO_HASH_INFO
 	select CRYPTO_AKCIPHER
+	select CRYPTO_SIG
 	select CRYPTO_HASH
 	help
 	  This option provides support for asymmetric public key type handling.
@@ -85,5 +86,7 @@
 	depends on ASYMMETRIC_KEY_TYPE
 	depends on PKCS7_MESSAGE_PARSER=X509_CERTIFICATE_PARSER
 	depends on X509_CERTIFICATE_PARSER
+	depends on CRYPTO_RSA
+	depends on CRYPTO_SHA256
 
 endif # ASYMMETRIC_KEY_TYPE
--- linux-qcom-6.8.0.orig/crypto/asymmetric_keys/asymmetric_type.c
+++ linux-qcom-6.8.0/crypto/asymmetric_keys/asymmetric_type.c
@@ -60,17 +60,18 @@
 	char *req, *p;
 	int len;
 
-	WARN_ON(!id_0 && !id_1 && !id_2);
-
 	if (id_0) {
 		lookup = id_0->data;
 		len = id_0->len;
 	} else if (id_1) {
 		lookup = id_1->data;
 		len = id_1->len;
-	} else {
+	} else if (id_2) {
 		lookup = id_2->data;
 		len = id_2->len;
+	} else {
+		WARN_ON(1);
+		return ERR_PTR(-EINVAL);
 	}
 
 	/* Construct an identifier "id:<keyid>". */
--- linux-qcom-6.8.0.orig/crypto/asymmetric_keys/mscode_parser.c
+++ linux-qcom-6.8.0/crypto/asymmetric_keys/mscode_parser.c
@@ -75,6 +75,9 @@
 
 	oid = look_up_OID(value, vlen);
 	switch (oid) {
+	case OID_sha1:
+		ctx->digest_algo = "sha1";
+		break;
 	case OID_sha256:
 		ctx->digest_algo = "sha256";
 		break;
--- linux-qcom-6.8.0.orig/crypto/asymmetric_keys/pkcs7_parser.c
+++ linux-qcom-6.8.0/crypto/asymmetric_keys/pkcs7_parser.c
@@ -227,6 +227,9 @@
 	struct pkcs7_parse_context *ctx = context;
 
 	switch (ctx->last_oid) {
+	case OID_sha1:
+		ctx->sinfo->sig->hash_algo = "sha1";
+		break;
 	case OID_sha256:
 		ctx->sinfo->sig->hash_algo = "sha256";
 		break;
@@ -278,6 +281,7 @@
 		ctx->sinfo->sig->pkey_algo = "rsa";
 		ctx->sinfo->sig->encoding = "pkcs1";
 		break;
+	case OID_id_ecdsa_with_sha1:
 	case OID_id_ecdsa_with_sha224:
 	case OID_id_ecdsa_with_sha256:
 	case OID_id_ecdsa_with_sha384:
--- linux-qcom-6.8.0.orig/crypto/asymmetric_keys/public_key.c
+++ linux-qcom-6.8.0/crypto/asymmetric_keys/public_key.c
@@ -115,7 +115,8 @@
 		 */
 		if (!hash_algo)
 			return -EINVAL;
-		if (strcmp(hash_algo, "sha224") != 0 &&
+		if (strcmp(hash_algo, "sha1") != 0 &&
+		    strcmp(hash_algo, "sha224") != 0 &&
 		    strcmp(hash_algo, "sha256") != 0 &&
 		    strcmp(hash_algo, "sha384") != 0 &&
 		    strcmp(hash_algo, "sha512") != 0 &&
--- linux-qcom-6.8.0.orig/crypto/asymmetric_keys/signature.c
+++ linux-qcom-6.8.0/crypto/asymmetric_keys/signature.c
@@ -115,7 +115,7 @@
  * Sign the specified data blob using the private key specified by params->key.
  * The signature is wrapped in an encoding if params->encoding is specified
  * (eg. "pkcs1").  If the encoding needs to know the digest type, this can be
- * passed through params->hash_algo (eg. "sha512").
+ * passed through params->hash_algo (eg. "sha1").
  *
  * Returns the length of the data placed in the signature buffer or an error.
  */
--- linux-qcom-6.8.0.orig/crypto/asymmetric_keys/x509_cert_parser.c
+++ linux-qcom-6.8.0/crypto/asymmetric_keys/x509_cert_parser.c
@@ -198,6 +198,10 @@
 	default:
 		return -ENOPKG; /* Unsupported combination */
 
+	case OID_sha1WithRSAEncryption:
+		ctx->cert->sig->hash_algo = "sha1";
+		goto rsa_pkcs1;
+
 	case OID_sha256WithRSAEncryption:
 		ctx->cert->sig->hash_algo = "sha256";
 		goto rsa_pkcs1;
@@ -214,6 +218,10 @@
 		ctx->cert->sig->hash_algo = "sha224";
 		goto rsa_pkcs1;
 
+	case OID_id_ecdsa_with_sha1:
+		ctx->cert->sig->hash_algo = "sha1";
+		goto ecdsa;
+
 	case OID_id_rsassa_pkcs1_v1_5_with_sha3_256:
 		ctx->cert->sig->hash_algo = "sha3-256";
 		goto rsa_pkcs1;
--- linux-qcom-6.8.0.orig/crypto/asymmetric_keys/x509_loader.c
+++ linux-qcom-6.8.0/crypto/asymmetric_keys/x509_loader.c
@@ -41,6 +41,7 @@
 		if (IS_ERR(key)) {
 			pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
 			       PTR_ERR(key));
+			WARN_ON_ONCE(1);
 		} else {
 			pr_notice("Loaded X.509 cert '%s'\n",
 				  key_ref_to_ptr(key)->description);
--- linux-qcom-6.8.0.orig/crypto/cipher.c
+++ linux-qcom-6.8.0/crypto/cipher.c
@@ -34,8 +34,7 @@
 	alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
 	memcpy(alignbuffer, key, keylen);
 	ret = cia->cia_setkey(crypto_cipher_tfm(tfm), alignbuffer, keylen);
-	memset(alignbuffer, 0, keylen);
-	kfree(buffer);
+	kfree_sensitive(buffer);
 	return ret;
 
 }
--- linux-qcom-6.8.0.orig/crypto/ecc.c
+++ linux-qcom-6.8.0/crypto/ecc.c
@@ -66,6 +66,28 @@
 }
 EXPORT_SYMBOL(ecc_get_curve);
 
+void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes,
+			   u64 *out, unsigned int ndigits)
+{
+	int diff = ndigits - DIV_ROUND_UP(nbytes, sizeof(u64));
+	unsigned int o = nbytes & 7;
+	__be64 msd = 0;
+
+	/* diff > 0: not enough input bytes: set most significant digits to 0 */
+	if (diff > 0) {
+		ndigits -= diff;
+		memset(&out[ndigits - 1], 0, diff * sizeof(u64));
+	}
+
+	if (o) {
+		memcpy((u8 *)&msd + sizeof(msd) - o, in, o);
+		out[--ndigits] = be64_to_cpu(msd);
+		in += o;
+	}
+	ecc_swap_digits(in, out, ndigits);
+}
+EXPORT_SYMBOL(ecc_digits_from_bytes);
+
 static u64 *ecc_alloc_digits_space(unsigned int ndigits)
 {
 	size_t len = ndigits * sizeof(u64);
--- linux-qcom-6.8.0.orig/crypto/ecdh.c
+++ linux-qcom-6.8.0/crypto/ecdh.c
@@ -33,6 +33,8 @@
 	    params.key_size > sizeof(u64) * ctx->ndigits)
 		return -EINVAL;
 
+	memset(ctx->private_key, 0, sizeof(ctx->private_key));
+
 	if (!params.key || !params.key_size)
 		return ecc_gen_privkey(ctx->curve_id, ctx->ndigits,
 				       ctx->private_key);
--- linux-qcom-6.8.0.orig/crypto/ecdsa.c
+++ linux-qcom-6.8.0/crypto/ecdsa.c
@@ -35,40 +35,27 @@
 static int ecdsa_get_signature_rs(u64 *dest, size_t hdrlen, unsigned char tag,
 				  const void *value, size_t vlen, unsigned int ndigits)
 {
-	size_t keylen = ndigits * sizeof(u64);
-	ssize_t diff = vlen - keylen;
+	size_t bufsize = ndigits * sizeof(u64);
 	const char *d = value;
-	u8 rs[ECC_MAX_BYTES];
 
-	if (!value || !vlen)
+	if (!value || !vlen || vlen > bufsize + 1)
 		return -EINVAL;
 
-	/* diff = 0: 'value' has exacly the right size
-	 * diff > 0: 'value' has too many bytes; one leading zero is allowed that
-	 *           makes the value a positive integer; error on more
-	 * diff < 0: 'value' is missing leading zeros, which we add
+	/*
+	 * vlen may be 1 byte larger than bufsize due to a leading zero byte
+	 * (necessary if the most significant bit of the integer is set).
 	 */
-	if (diff > 0) {
+	if (vlen > bufsize) {
 		/* skip over leading zeros that make 'value' a positive int */
 		if (*d == 0) {
 			vlen -= 1;
-			diff--;
 			d++;
-		}
-		if (diff)
+		} else {
 			return -EINVAL;
+		}
 	}
-	if (-diff >= keylen)
-		return -EINVAL;
-
-	if (diff) {
-		/* leading zeros not given in 'value' */
-		memset(rs, 0, -diff);
-	}
-
-	memcpy(&rs[-diff], d, vlen);
 
-	ecc_swap_digits((u64 *)rs, dest, ndigits);
+	ecc_digits_from_bytes(d, vlen, dest, ndigits);
 
 	return 0;
 }
@@ -138,7 +125,7 @@
 {
 	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
 	struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
-	size_t keylen = ctx->curve->g.ndigits * sizeof(u64);
+	size_t bufsize = ctx->curve->g.ndigits * sizeof(u64);
 	struct ecdsa_signature_ctx sig_ctx = {
 		.curve = ctx->curve,
 	};
@@ -165,14 +152,14 @@
 		goto error;
 
 	/* if the hash is shorter then we will add leading zeros to fit to ndigits */
-	diff = keylen - req->dst_len;
+	diff = bufsize - req->dst_len;
 	if (diff >= 0) {
 		if (diff)
 			memset(rawhash, 0, diff);
 		memcpy(&rawhash[diff], buffer + req->src_len, req->dst_len);
 	} else if (diff < 0) {
 		/* given hash is longer, we take the left-most bytes */
-		memcpy(&rawhash, buffer + req->src_len, keylen);
+		memcpy(&rawhash, buffer + req->src_len, bufsize);
 	}
 
 	ecc_swap_digits((u64 *)rawhash, hash, ctx->curve->g.ndigits);
@@ -222,9 +209,8 @@
 static int ecdsa_set_pub_key(struct crypto_akcipher *tfm, const void *key, unsigned int keylen)
 {
 	struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm);
+	unsigned int digitlen, ndigits;
 	const unsigned char *d = key;
-	const u64 *digits = (const u64 *)&d[1];
-	unsigned int ndigits;
 	int ret;
 
 	ret = ecdsa_ecc_ctx_reset(ctx);
@@ -238,12 +224,17 @@
 		return -EINVAL;
 
 	keylen--;
-	ndigits = (keylen >> 1) / sizeof(u64);
+	digitlen = keylen >> 1;
+
+	ndigits = DIV_ROUND_UP(digitlen, sizeof(u64));
 	if (ndigits != ctx->curve->g.ndigits)
 		return -EINVAL;
 
-	ecc_swap_digits(digits, ctx->pub_key.x, ndigits);
-	ecc_swap_digits(&digits[ndigits], ctx->pub_key.y, ndigits);
+	d++;
+
+	ecc_digits_from_bytes(d, digitlen, ctx->pub_key.x, ndigits);
+	ecc_digits_from_bytes(&d[digitlen], digitlen, ctx->pub_key.y, ndigits);
+
 	ret = ecc_is_pubkey_valid_full(ctx->curve, &ctx->pub_key);
 
 	ctx->pub_key_set = ret == 0;
@@ -373,4 +364,7 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Stefan Berger <stefanb@linux.ibm.com>");
 MODULE_DESCRIPTION("ECDSA generic algorithm");
+MODULE_ALIAS_CRYPTO("ecdsa-nist-p192");
+MODULE_ALIAS_CRYPTO("ecdsa-nist-p256");
+MODULE_ALIAS_CRYPTO("ecdsa-nist-p384");
 MODULE_ALIAS_CRYPTO("ecdsa-generic");
--- linux-qcom-6.8.0.orig/crypto/ecrdsa.c
+++ linux-qcom-6.8.0/crypto/ecrdsa.c
@@ -294,4 +294,5 @@
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Vitaly Chikunov <vt@altlinux.org>");
 MODULE_DESCRIPTION("EC-RDSA generic algorithm");
+MODULE_ALIAS_CRYPTO("ecrdsa");
 MODULE_ALIAS_CRYPTO("ecrdsa-generic");
--- linux-qcom-6.8.0.orig/crypto/fips.c
+++ linux-qcom-6.8.0/crypto/fips.c
@@ -14,7 +14,8 @@
 #include <linux/notifier.h>
 #include <generated/utsrelease.h>
 
-int fips_enabled;
+/* LP: #2049082 UBUNTU: SAUCE: FIPS kernels default to FIPS mode */
+int fips_enabled = 1;
 EXPORT_SYMBOL_GPL(fips_enabled);
 
 ATOMIC_NOTIFIER_HEAD(fips_fail_notif_chain);
--- linux-qcom-6.8.0.orig/crypto/pcrypt.c
+++ linux-qcom-6.8.0/crypto/pcrypt.c
@@ -117,8 +117,10 @@
 	err = padata_do_parallel(ictx->psenc, padata, &ctx->cb_cpu);
 	if (!err)
 		return -EINPROGRESS;
-	if (err == -EBUSY)
-		return -EAGAIN;
+	if (err == -EBUSY) {
+		/* try non-parallel mode */
+		return crypto_aead_encrypt(creq);
+	}
 
 	return err;
 }
@@ -166,8 +168,10 @@
 	err = padata_do_parallel(ictx->psdec, padata, &ctx->cb_cpu);
 	if (!err)
 		return -EINPROGRESS;
-	if (err == -EBUSY)
-		return -EAGAIN;
+	if (err == -EBUSY) {
+		/* try non-parallel mode */
+		return crypto_aead_decrypt(creq);
+	}
 
 	return err;
 }
--- linux-qcom-6.8.0.orig/crypto/simd.c
+++ linux-qcom-6.8.0/crypto/simd.c
@@ -136,27 +136,19 @@
 	return 0;
 }
 
-struct simd_skcipher_alg *simd_skcipher_create_compat(const char *algname,
+struct simd_skcipher_alg *simd_skcipher_create_compat(struct skcipher_alg *ialg,
+						      const char *algname,
 						      const char *drvname,
 						      const char *basename)
 {
 	struct simd_skcipher_alg *salg;
-	struct crypto_skcipher *tfm;
-	struct skcipher_alg *ialg;
 	struct skcipher_alg *alg;
 	int err;
 
-	tfm = crypto_alloc_skcipher(basename, CRYPTO_ALG_INTERNAL,
-				    CRYPTO_ALG_INTERNAL | CRYPTO_ALG_ASYNC);
-	if (IS_ERR(tfm))
-		return ERR_CAST(tfm);
-
-	ialg = crypto_skcipher_alg(tfm);
-
 	salg = kzalloc(sizeof(*salg), GFP_KERNEL);
 	if (!salg) {
 		salg = ERR_PTR(-ENOMEM);
-		goto out_put_tfm;
+		goto out;
 	}
 
 	salg->ialg_name = basename;
@@ -195,30 +187,16 @@
 	if (err)
 		goto out_free_salg;
 
-out_put_tfm:
-	crypto_free_skcipher(tfm);
+out:
 	return salg;
 
 out_free_salg:
 	kfree(salg);
 	salg = ERR_PTR(err);
-	goto out_put_tfm;
+	goto out;
 }
 EXPORT_SYMBOL_GPL(simd_skcipher_create_compat);
 
-struct simd_skcipher_alg *simd_skcipher_create(const char *algname,
-					       const char *basename)
-{
-	char drvname[CRYPTO_MAX_ALG_NAME];
-
-	if (snprintf(drvname, CRYPTO_MAX_ALG_NAME, "simd-%s", basename) >=
-	    CRYPTO_MAX_ALG_NAME)
-		return ERR_PTR(-ENAMETOOLONG);
-
-	return simd_skcipher_create_compat(algname, drvname, basename);
-}
-EXPORT_SYMBOL_GPL(simd_skcipher_create);
-
 void simd_skcipher_free(struct simd_skcipher_alg *salg)
 {
 	crypto_unregister_skcipher(&salg->alg);
@@ -246,7 +224,7 @@
 		algname = algs[i].base.cra_name + 2;
 		drvname = algs[i].base.cra_driver_name + 2;
 		basename = algs[i].base.cra_driver_name;
-		simd = simd_skcipher_create_compat(algname, drvname, basename);
+		simd = simd_skcipher_create_compat(algs + i, algname, drvname, basename);
 		err = PTR_ERR(simd);
 		if (IS_ERR(simd))
 			goto err_unregister;
@@ -383,27 +361,19 @@
 	return 0;
 }
 
-struct simd_aead_alg *simd_aead_create_compat(const char *algname,
-					      const char *drvname,
-					      const char *basename)
+static struct simd_aead_alg *simd_aead_create_compat(struct aead_alg *ialg,
+						     const char *algname,
+						     const char *drvname,
+						     const char *basename)
 {
 	struct simd_aead_alg *salg;
-	struct crypto_aead *tfm;
-	struct aead_alg *ialg;
 	struct aead_alg *alg;
 	int err;
 
-	tfm = crypto_alloc_aead(basename, CRYPTO_ALG_INTERNAL,
-				CRYPTO_ALG_INTERNAL | CRYPTO_ALG_ASYNC);
-	if (IS_ERR(tfm))
-		return ERR_CAST(tfm);
-
-	ialg = crypto_aead_alg(tfm);
-
 	salg = kzalloc(sizeof(*salg), GFP_KERNEL);
 	if (!salg) {
 		salg = ERR_PTR(-ENOMEM);
-		goto out_put_tfm;
+		goto out;
 	}
 
 	salg->ialg_name = basename;
@@ -442,36 +412,20 @@
 	if (err)
 		goto out_free_salg;
 
-out_put_tfm:
-	crypto_free_aead(tfm);
+out:
 	return salg;
 
 out_free_salg:
 	kfree(salg);
 	salg = ERR_PTR(err);
-	goto out_put_tfm;
-}
-EXPORT_SYMBOL_GPL(simd_aead_create_compat);
-
-struct simd_aead_alg *simd_aead_create(const char *algname,
-				       const char *basename)
-{
-	char drvname[CRYPTO_MAX_ALG_NAME];
-
-	if (snprintf(drvname, CRYPTO_MAX_ALG_NAME, "simd-%s", basename) >=
-	    CRYPTO_MAX_ALG_NAME)
-		return ERR_PTR(-ENAMETOOLONG);
-
-	return simd_aead_create_compat(algname, drvname, basename);
+	goto out;
 }
-EXPORT_SYMBOL_GPL(simd_aead_create);
 
-void simd_aead_free(struct simd_aead_alg *salg)
+static void simd_aead_free(struct simd_aead_alg *salg)
 {
 	crypto_unregister_aead(&salg->alg);
 	kfree(salg);
 }
-EXPORT_SYMBOL_GPL(simd_aead_free);
 
 int simd_register_aeads_compat(struct aead_alg *algs, int count,
 			       struct simd_aead_alg **simd_algs)
@@ -493,7 +447,7 @@
 		algname = algs[i].base.cra_name + 2;
 		drvname = algs[i].base.cra_driver_name + 2;
 		basename = algs[i].base.cra_driver_name;
-		simd = simd_aead_create_compat(algname, drvname, basename);
+		simd = simd_aead_create_compat(algs + i, algname, drvname, basename);
 		err = PTR_ERR(simd);
 		if (IS_ERR(simd))
 			goto err_unregister;
--- linux-qcom-6.8.0.orig/crypto/testmgr.h
+++ linux-qcom-6.8.0/crypto/testmgr.h
@@ -653,6 +653,30 @@
 static const struct akcipher_testvec ecdsa_nist_p192_tv_template[] = {
 	{
 	.key =
+	"\x04\xf7\x46\xf8\x2f\x15\xf6\x22\x8e\xd7\x57\x4f\xcc\xe7\xbb\xc1"
+	"\xd4\x09\x73\xcf\xea\xd0\x15\x07\x3d\xa5\x8a\x8a\x95\x43\xe4\x68"
+	"\xea\xc6\x25\xc1\xc1\x01\x25\x4c\x7e\xc3\x3c\xa6\x04\x0a\xe7\x08"
+	"\x98",
+	.key_len = 49,
+	.params =
+	"\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
+	"\xce\x3d\x03\x01\x01",
+	.param_len = 21,
+	.m =
+	"\xcd\xb9\xd2\x1c\xb7\x6f\xcd\x44\xb3\xfd\x63\xea\xa3\x66\x7f\xae"
+	"\x63\x85\xe7\x82",
+	.m_size = 20,
+	.algo = OID_id_ecdsa_with_sha1,
+	.c =
+	"\x30\x35\x02\x19\x00\xba\xe5\x93\x83\x6e\xb6\x3b\x63\xa0\x27\x91"
+	"\xc6\xf6\x7f\xc3\x09\xad\x59\xad\x88\x27\xd6\x92\x6b\x02\x18\x10"
+	"\x68\x01\x9d\xba\xce\x83\x08\xef\x95\x52\x7b\xa0\x0f\xe4\x18\x86"
+	"\x80\x6f\xa5\x79\x77\xda\xd0",
+	.c_size = 55,
+	.public_key_vec = true,
+	.siggen_sigver_test = true,
+	}, {
+	.key =
 	"\x04\xb6\x4b\xb1\xd1\xac\xba\x24\x8f\x65\xb2\x60\x00\x90\xbf\xbd"
 	"\x78\x05\x73\xe9\x79\x1d\x6f\x7c\x0b\xd2\xc3\x93\xa7\x28\xe1\x75"
 	"\xf7\xd5\x95\x1d\x28\x10\xc0\x75\x50\x5c\x1a\x4f\x3f\x8f\xa5\xee"
@@ -756,6 +780,32 @@
 static const struct akcipher_testvec ecdsa_nist_p256_tv_template[] = {
 	{
 	.key =
+	"\x04\xb9\x7b\xbb\xd7\x17\x64\xd2\x7e\xfc\x81\x5d\x87\x06\x83\x41"
+	"\x22\xd6\x9a\xaa\x87\x17\xec\x4f\x63\x55\x2f\x94\xba\xdd\x83\xe9"
+	"\x34\x4b\xf3\xe9\x91\x13\x50\xb6\xcb\xca\x62\x08\xe7\x3b\x09\xdc"
+	"\xc3\x63\x4b\x2d\xb9\x73\x53\xe4\x45\xe6\x7c\xad\xe7\x6b\xb0\xe8"
+	"\xaf",
+	.key_len = 65,
+	.params =
+	"\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
+	"\xce\x3d\x03\x01\x07",
+	.param_len = 21,
+	.m =
+	"\xc2\x2b\x5f\x91\x78\x34\x26\x09\x42\x8d\x6f\x51\xb2\xc5\xaf\x4c"
+	"\x0b\xde\x6a\x42",
+	.m_size = 20,
+	.algo = OID_id_ecdsa_with_sha1,
+	.c =
+	"\x30\x46\x02\x21\x00\xf9\x25\xce\x9f\x3a\xa6\x35\x81\xcf\xd4\xe7"
+	"\xb7\xf0\x82\x56\x41\xf7\xd4\xad\x8d\x94\x5a\x69\x89\xee\xca\x6a"
+	"\x52\x0e\x48\x4d\xcc\x02\x21\x00\xd7\xe4\xef\x52\x66\xd3\x5b\x9d"
+	"\x8a\xfa\x54\x93\x29\xa7\x70\x86\xf1\x03\x03\xf3\x3b\xe2\x73\xf7"
+	"\xfb\x9d\x8b\xde\xd4\x8d\x6f\xad",
+	.c_size = 72,
+	.public_key_vec = true,
+	.siggen_sigver_test = true,
+	}, {
+	.key =
 	"\x04\x8b\x6d\xc0\x33\x8e\x2d\x8b\x67\xf5\xeb\xc4\x7f\xa0\xf5\xd9"
 	"\x7b\x03\xa5\x78\x9a\xb5\xea\x14\xe4\x23\xd0\xaf\xd7\x0e\x2e\xa0"
 	"\xc9\x8b\xdb\x95\xf8\xb3\xaf\xac\x00\x2c\x2c\x1f\x7a\xfd\x95\x88"
@@ -866,6 +916,36 @@
 
 static const struct akcipher_testvec ecdsa_nist_p384_tv_template[] = {
 	{
+	.key = /* secp384r1(sha1) */
+	"\x04\x89\x25\xf3\x97\x88\xcb\xb0\x78\xc5\x72\x9a\x14\x6e\x7a\xb1"
+	"\x5a\xa5\x24\xf1\x95\x06\x9e\x28\xfb\xc4\xb9\xbe\x5a\x0d\xd9\x9f"
+	"\xf3\xd1\x4d\x2d\x07\x99\xbd\xda\xa7\x66\xec\xbb\xea\xba\x79\x42"
+	"\xc9\x34\x89\x6a\xe7\x0b\xc3\xf2\xfe\x32\x30\xbe\xba\xf9\xdf\x7e"
+	"\x4b\x6a\x07\x8e\x26\x66\x3f\x1d\xec\xa2\x57\x91\x51\xdd\x17\x0e"
+	"\x0b\x25\xd6\x80\x5c\x3b\xe6\x1a\x98\x48\x91\x45\x7a\x73\xb0\xc3"
+	"\xf1",
+	.key_len = 97,
+	.params =
+	"\x30\x10\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x05\x2b\x81\x04"
+	"\x00\x22",
+	.param_len = 18,
+	.m =
+	"\x12\x55\x28\xf0\x77\xd5\xb6\x21\x71\x32\x48\xcd\x28\xa8\x25\x22"
+	"\x3a\x69\xc1\x93",
+	.m_size = 20,
+	.algo = OID_id_ecdsa_with_sha1,
+	.c =
+	"\x30\x66\x02\x31\x00\xf5\x0f\x24\x4c\x07\x93\x6f\x21\x57\x55\x07"
+	"\x20\x43\x30\xde\xa0\x8d\x26\x8e\xae\x63\x3f\xbc\x20\x3a\xc6\xf1"
+	"\x32\x3c\xce\x70\x2b\x78\xf1\x4c\x26\xe6\x5b\x86\xcf\xec\x7c\x7e"
+	"\xd0\x87\xd7\xd7\x6e\x02\x31\x00\xcd\xbb\x7e\x81\x5d\x8f\x63\xc0"
+	"\x5f\x63\xb1\xbe\x5e\x4c\x0e\xa1\xdf\x28\x8c\x1b\xfa\xf9\x95\x88"
+	"\x74\xa0\x0f\xbf\xaf\xc3\x36\x76\x4a\xa1\x59\xf1\x1c\xa4\x58\x26"
+	"\x79\x12\x2a\xb7\xc5\x15\x92\xc5",
+	.c_size = 104,
+	.public_key_vec = true,
+	.siggen_sigver_test = true,
+	}, {
 	.key = /* secp384r1(sha224) */
 	"\x04\x69\x6c\xcf\x62\xee\xd0\x0d\xe5\xb5\x2f\x70\x54\xcf\x26\xa0"
 	"\xd9\x98\x8d\x92\x2a\xab\x9b\x11\xcb\x48\x18\xa1\xa9\x0d\xd5\x18"
--- linux-qcom-6.8.0.orig/crypto/xor.c
+++ linux-qcom-6.8.0/crypto/xor.c
@@ -83,33 +83,30 @@
 do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2)
 {
 	int speed;
-	int i, j;
-	ktime_t min, start, diff;
+	unsigned long reps;
+	ktime_t min, start, t0;
 
 	tmpl->next = template_list;
 	template_list = tmpl;
 
 	preempt_disable();
 
-	min = (ktime_t)S64_MAX;
-	for (i = 0; i < 3; i++) {
-		start = ktime_get();
-		for (j = 0; j < REPS; j++) {
-			mb(); /* prevent loop optimization */
-			tmpl->do_2(BENCH_SIZE, b1, b2);
-			mb();
-		}
-		diff = ktime_sub(ktime_get(), start);
-		if (diff < min)
-			min = diff;
-	}
+	reps = 0;
+	t0 = ktime_get();
+	/* delay start until time has advanced */
+	while ((start = ktime_get()) == t0)
+		cpu_relax();
+	do {
+		mb(); /* prevent loop optimization */
+		tmpl->do_2(BENCH_SIZE, b1, b2);
+		mb();
+	} while (reps++ < REPS || (t0 = ktime_get()) == start);
+	min = ktime_sub(t0, start);
 
 	preempt_enable();
 
 	// bytes/ns == GB/s, multiply by 1000 to get MB/s [not MiB/s]
-	if (!min)
-		min = 1;
-	speed = (1000 * REPS * BENCH_SIZE) / (unsigned int)ktime_to_ns(min);
+	speed = (1000 * reps * BENCH_SIZE) / (unsigned int)ktime_to_ns(min);
 	tmpl->speed = speed;
 
 	pr_info("   %-16s: %5d MB/sec\n", tmpl->name, speed);
--- linux-qcom-6.8.0.orig/debian.master/changelog
+++ linux-qcom-6.8.0/debian.master/changelog
@@ -0,0 +1,37623 @@
+linux (6.8.0-64.67) noble; urgency=medium
+
+  * noble/linux: 6.8.0-64.67 -proposed tracker (LP: #2114668)
+
+  * Unexpected system reboot at loading GUI session on some AMD platforms
+    (LP: #2112462)
+    - drm/amdgpu/hdp4: use memcfg register to post the write for HDP flush
+    - drm/amdgpu/hdp5: use memcfg register to post the write for HDP flush
+    - drm/amdgpu/hdp5.2: use memcfg register to post the write for HDP flush
+    - drm/amdgpu/hdp6: use memcfg register to post the write for HDP flush
+
+  * [UBUNTU 24.04] s390/pci: Fix immediate re-add of PCI function after remove
+    (LP: #2114174)
+    - s390/pci: rename lock member in struct zpci_dev
+    - s390/pci: introduce lock to synchronize state of zpci_dev's
+    - s390/pci: remove hotplug slot when releasing the device
+    - s390/pci: Remove redundant bus removal and disable from
+      zpci_release_device()
+    - s390/pci: Prevent self deletion in disable_slot()
+    - s390/pci: Allow re-add of a reserved but not yet removed device
+    - s390/pci: Serialize device addition and removal
+
+  * [UBUNTU 24.04] s390/pci: Fix immediate re-add of PCI function after remove
+    (LP: #2114174) // CVE-2025-37946
+    - s390/pci: Fix duplicate pci_dev_put() in disable_slot() when PF has
+      child VFs
+
+  * [UBUNTU 24.04] s390/pci: Fix immediate re-add of PCI function after remove
+    (LP: #2114174) // CVE-2025-37974
+    - s390/pci: Fix missing check for zpci_create_device() error return
+
+  * [UBUNTU 24.04] s390/pci: Fix immediate re-add of PCI function after remove
+    (LP: #2114174) // CVE-2024-56699
+    - s390/pci: Fix potential double remove of hotplug slot
+
+  * System will restart while resuming with SATA HDD or nvme installed with
+    password set (LP: #2110090)
+    - PCI: Explicitly put devices into D0 when initializing
+
+  * Noble update: upstream stable patchset 2025-06-12 (LP: #2114239)
+    - btrfs: fix assertion failure when splitting ordered extent after
+      transaction abort
+    - btrfs: fix use-after-free when attempting to join an aborted transaction
+    - arm64/mm: Ensure adequate HUGE_MAX_HSTATE
+    - exec: fix up /proc/pid/comm in the execveat(AT_EMPTY_PATH) case
+    - s390/stackleak: Use exrl instead of ex in __stackleak_poison()
+    - btrfs: fix data race when accessing the inode's disk_i_size at
+      btrfs_drop_extents()
+    - btrfs: convert BUG_ON in btrfs_reloc_cow_block() to proper error
+      handling
+    - sched: Don't try to catch up excess steal time.
+    - locking/ww_mutex/test: Use swap() macro
+    - lockdep: Fix upper limit for LOCKDEP_*_BITS configs
+    - x86/amd_nb: Restrict init function to AMD-based systems
+    - drm/virtio: New fence for every plane update
+    - drm: Add panel backlight quirks
+    - drm: panel-backlight-quirks: Add Framework 13 matte panel
+    - drm: panel-backlight-quirks: Add Framework 13 glossy and 2.8k panels
+    - nvkm/gsp: correctly advance the read pointer of GSP message queue
+    - nvkm: correctly calculate the available space of the GSP cmdq buffer
+    - drm/amd/display: Populate chroma prefetch parameters, DET buffer fix
+    - drm/amd/display: Overwriting dualDPP UBF values before usage
+    - printk: Fix signed integer overflow when defining LOG_BUF_LEN_MAX
+    - drm/connector: add mutex to protect ELD from concurrent access
+    - drm/bridge: anx7625: use eld_mutex to protect access to connector->eld
+    - drm/bridge: ite-it66121: use eld_mutex to protect access to
+      connector->eld
+    - drm/amd/display: use eld_mutex to protect access to connector->eld
+    - drm/exynos: hdmi: use eld_mutex to protect access to connector->eld
+    - drm/radeon: use eld_mutex to protect access to connector->eld
+    - drm/sti: hdmi: use eld_mutex to protect access to connector->eld
+    - drm/vc4: hdmi: use eld_mutex to protect access to connector->eld
+    - drm/amd/display: Fix Mode Cutoff in DSC Passthrough to DP2.1 Monitor
+    - drm/amdgpu: Don't enable sdma 4.4.5 CTXEMPTY interrupt
+    - drm/amdkfd: Queue interrupt work to different CPU
+    - drm/bridge: it6505: Change definition MAX_HDCP_DOWN_STREAM_COUNT
+    - drm/bridge: it6505: fix HDCP Bstatus check
+    - drm/bridge: it6505: fix HDCP encryption when R0 ready
+    - drm/bridge: it6505: fix HDCP CTS compare V matching
+    - drm/bridge: it6505: fix HDCP V match check is not performed correctly
+    - drm/bridge: it6505: fix HDCP CTS KSV list wait timer
+    - safesetid: check size of policy writes
+    - drm/amd/display: Increase sanitizer frame larger than limit when compile
+      testing with clang
+    - drm/amd/display: Limit Scaling Ratio on DCN3.01
+    - wifi: rtw89: add crystal_cap check to avoid setting as overflow value
+    - tun: fix group permission check
+    - mmc: core: Respect quirk_max_rate for non-UHS SDIO card
+    - mmc: sdhci-esdhc-imx: enable 'SDHCI_QUIRK_NO_LED' quirk for S32G
+    - wifi: brcmsmac: add gain range check to wlc_phy_iqcal_gainparams_nphy()
+    - tomoyo: don't emit warning in tomoyo_write_control()
+    - mfd: lpc_ich: Add another Gemini Lake ISA bridge PCI device-id
+    - wifi: rtw88: add __packed attribute to efuse layout struct
+    - clk: qcom: Make GCC_8150 depend on QCOM_GDSC
+    - HID: multitouch: Add quirk for Hantick 5288 touchpad
+    - HID: Wacom: Add PCI Wacom device support
+    - net/mlx5: use do_aux_work for PHC overflow checks
+    - wifi: brcmfmac: Check the return value of
+      of_property_read_string_index()
+    - wifi: iwlwifi: pcie: Add support for new device ids
+    - wifi: iwlwifi: avoid memory leak
+    - i2c: Force ELAN06FA touchpad I2C bus freq to 100KHz
+    - APEI: GHES: Have GHES honor the panic= setting
+    - Bluetooth: btusb: Add new VID/PID 13d3/3610 for MT7922
+    - Bluetooth: btusb: Add new VID/PID 13d3/3628 for MT7925
+    - Bluetooth: MGMT: Fix slab-use-after-free Read in
+      mgmt_remove_adv_monitor_sync
+    - net: wwan: iosm: Fix hibernation by re-binding the driver around it
+    - mmc: sdhci-msm: Correctly set the load for the regulator
+    - octeon_ep: update tx/rx stats locally for persistence
+    - tipc: re-order conditions in tipc_crypto_key_rcv()
+    - selftests/net/ipsec: Fix Null pointer dereference in rtattr_pack()
+    - x86/kexec: Allocate PGD for x86_64 transition page tables separately
+    - iommu/arm-smmu-qcom: add sdm670 adreno iommu compatible
+    - iommu/arm-smmu-v3: Clean up more on probe failure
+    - platform/x86: int3472: Check for adev == NULL
+    - platform/x86: acer-wmi: Add support for Acer PH14-51
+    - ASoC: soc-pcm: don't use soc_pcm_ret() on .prepare callback
+    - platform/x86: acer-wmi: Add support for Acer Predator PH16-72
+    - ASoC: amd: Add ACPI dependency to fix build error
+    - Input: allocate keycode for phone linking
+    - platform/x86: acer-wmi: add support for Acer Nitro AN515-58
+    - platform/x86: acer-wmi: Ignore AC events
+    - xfs: report realtime block quota limits on realtime directories
+    - xfs: don't over-report free space or inodes in statvfs
+    - tty: xilinx_uartps: split sysrq handling
+    - tty: vt: pass proper pointers from tioclinux()
+    - tty: Permit some TIOCL_SETSEL modes without CAP_SYS_ADMIN
+    - tty: Require CAP_SYS_ADMIN for all usages of TIOCL_SELMOUSEREPORT
+    - platform/x86: serdev_helpers: Check for serial_ctrl_uid == NULL
+    - nvme: handle connectivity loss in nvme_set_queue_count
+    - firmware: iscsi_ibft: fix ISCSI_IBFT Kconfig entry
+    - gpu: drm_dp_cec: fix broken CEC adapter properties check
+    - ice: put Rx buffers after being done with current frame
+    - ice: gather page_count()'s of each frag right before XDP prog call
+    - ice: stop storing XDP verdict within ice_rx_buf
+    - nvme-fc: use ctrl state getter
+    - net: bcmgenet: Correct overlaying of PHY and MAC Wake-on-LAN
+    - vmxnet3: Fix tx queue race condition with XDP
+    - tg3: Disable tg3 PCIe AER on system reboot
+    - udp: gso: do not drop small packets when PMTU reduces
+    - rxrpc: Fix the rxrpc_connection attend queue handling
+    - gpio: pca953x: Improve interrupt support
+    - net: atlantic: fix warning during hot unplug
+    - net: rose: lock the socket in rose_bind()
+    - ACPI: property: Fix return value for nval == 0 in acpi_data_prop_read()
+    - tun: revert fix group permission check
+    - net: sched: Fix truncation of offloaded action statistics
+    - rxrpc: Fix call state set to not include the SERVER_SECURING state
+    - cpufreq: s3c64xx: Fix compilation warning
+    - leds: lp8860: Write full EEPROM, not only half of it
+    - ALSA: hda/realtek: Enable Mute LED on HP Laptop 14s-fq1xxx
+    - drm/modeset: Handle tiled displays in pan_display_atomic.
+    - drm/client: Handle tiled displays better
+    - smb: client: fix order of arguments of tracepoints
+    - smb: client: change lease epoch type from unsigned int to __u16
+    - s390/futex: Fix FUTEX_OP_ANDN implementation
+    - arm64: Filter out SVE hwcaps when FEAT_SVE isn't implemented
+    - m68k: vga: Fix I/O defines
+    - fs/proc: do_task_stat: Fix ESP not readable during coredump
+    - binfmt_flat: Fix integer overflow bug on 32 bit systems
+    - accel/ivpu: Fix Qemu crash when running in passthrough
+    - arm64/kvm: Configure HYP TCR.PS/DS based on host stage1
+    - arm64/sme: Move storage of reg_smidr to __cpuinfo_store_cpu()
+    - KVM: arm64: timer: Always evaluate the need for a soft timer
+    - drm/rockchip: cdn-dp: Use drm_connector_helper_hpd_irq_event()
+    - arm64: dts: rockchip: increase gmac rx_delay on rk3399-puma
+    - remoteproc: omap: Handle ARM dma_iommu_mapping
+    - KVM: Explicitly verify target vCPU is online in kvm_get_vcpu()
+    - KVM: s390: vsie: fix some corner-cases when grabbing vsie pages
+    - ksmbd: fix integer overflows on 32 bit systems
+    - drm/amd/display: Optimize cursor position updates
+    - drm/amd/pm: Mark MM activity as unsupported
+    - drm/amdkfd: only flush the validate MES contex
+    - drm/i915/guc: Debug print LRC state entries only if the context is
+      pinned
+    - drm/i915: Fix page cleanup on DMA remap failure
+    - drm/komeda: Add check for komeda_get_layer_fourcc_list()
+    - drm/i915/dp: Iterate DSC BPP from high to low on all platforms
+    - drm/i915: Drop 64bpp YUV formats from ICL+ SDR planes
+    - drm/amd/display: Fix seamless boot sequence
+    - Bluetooth: L2CAP: accept zero as a special value for MTU auto-selection
+    - clk: sunxi-ng: a100: enable MMC clock reparenting
+    - clk: mmp2: call pm_genpd_init() only after genpd.name is set
+    - media: i2c: ds90ub960: Fix UB9702 refclk register access
+    - clk: qcom: clk-alpha-pll: fix alpha mode configuration
+    - clk: qcom: gcc-sm8550: Do not turn off PCIe GDSCs during gdsc_disable()
+    - clk: qcom: gcc-sm8650: Do not turn off PCIe GDSCs during gdsc_disable()
+    - clk: qcom: gcc-sm6350: Add missing parent_map for two clocks
+    - clk: qcom: dispcc-sm6350: Add missing parent_map for a clock
+    - clk: qcom: gcc-mdm9607: Fix cmd_rcgr offset for blsp1_uart6 rcg
+    - clk: qcom: clk-rpmh: prevent integer overflow in recalc_rate
+    - clk: mediatek: mt2701-vdec: fix conversion to mtk_clk_simple_probe
+    - clk: mediatek: mt2701-aud: fix conversion to mtk_clk_simple_probe
+    - clk: mediatek: mt2701-bdp: add missing dummy clk
+    - clk: mediatek: mt2701-img: add missing dummy clk
+    - clk: mediatek: mt2701-mm: add missing dummy clk
+    - blk-cgroup: Fix class @block_class's subsystem refcount leakage
+    - efi: libstub: Use '-std=gnu11' to fix build with GCC 15
+    - perf bench: Fix undefined behavior in cmpworker()
+    - scsi: ufs: core: Fix the HIGH/LOW_TEMP Bit Definitions
+    - of: Correct child specifier used as input of the 2nd nexus node
+    - of: Fix of_find_node_opts_by_path() handling of alias+path+options
+    - Input: bbnsm_pwrkey - add remove hook
+    - HID: hid-sensor-hub: don't use stale platform-data on remove
+    - ring-buffer: Do not allow events in NMI with generic atomic64 cmpxchg()
+    - atomic64: Use arch_spin_locks instead of raw_spin_locks
+    - wifi: rtlwifi: rtl8821ae: Fix media status report
+    - wifi: brcmfmac: fix NULL pointer dereference in brcmf_txfinalize()
+    - wifi: mt76: mt7921u: Add VID/PID for TP-Link TXE50UH
+    - wifi: rtw88: sdio: Fix disconnection after beacon loss
+    - wifi: mt76: mt7915: add module param to select 5 GHz or 6 GHz on MT7916
+    - usb: gadget: f_tcm: Translate error to sense
+    - usb: gadget: f_tcm: Decrement command ref count on cleanup
+    - usb: gadget: f_tcm: ep_autoconfig with fullspeed endpoint
+    - usb: gadget: f_tcm: Don't prepare BOT write request twice
+    - usbnet: ipheth: fix possible overflow in DPE length check
+    - usbnet: ipheth: use static NDP16 location in URB
+    - usbnet: ipheth: check that DPE points past NCM header
+    - usbnet: ipheth: refactor NCM datagram loop
+    - usbnet: ipheth: break up NCM header size computation
+    - usbnet: ipheth: fix DPE OoB read
+    - usbnet: ipheth: document scope of NCM implementation
+    - ASoC: acp: Support microphone from Lenovo Go S
+    - soc: qcom: socinfo: Avoid out of bounds read of serial number
+    - serial: sh-sci: Drop __initdata macro for port_cfg
+    - serial: sh-sci: Do not probe the serial port if its slot in sci_ports[]
+      is in use
+    - MIPS: Loongson64: remove ROM Size unit in boardinfo
+    - LoongArch: Extend the maximum number of watchpoints
+    - powerpc/pseries/eeh: Fix get PE state translation
+    - dm-crypt: don't update io->sector after kcryptd_crypt_write_io_submit()
+    - dm-crypt: track tag_offset in convert_context
+    - mips/math-emu: fix emulation of the prefx instruction
+    - MIPS: pci-legacy: Override pci_address_to_pio
+    - block: don't revert iter for -EIOCBQUEUED
+    - firmware: qcom: scm: Fix missing read barrier in qcom_scm_is_available()
+    - ALSA: hda/realtek: Enable headset mic on Positivo C6400
+    - ALSA: hda: Fix headset detection failure due to unstable sort
+    - ALSA: hda/realtek: Fix built-in mic on another ASUS VivoBook model
+    - ALSA: hda/realtek: Fix built-in mic breakage on ASUS VivoBook X515JA
+    - arm64: tegra: Fix Tegra234 PCIe interrupt-map
+    - PCI: endpoint: Finish virtual EP removal in pci_epf_remove_vepf()
+    - PCI: dwc: ep: Write BAR_MASK before iATU registers in pci_epc_set_bar()
+    - PCI: dwc: ep: Prevent changing BAR size/flags in pci_epc_set_bar()
+    - scsi: st: Don't set pos_unknown just after device recognition
+    - scsi: qla2xxx: Move FCE Trace buffer allocation to user control
+    - scsi: ufs: qcom: Fix crypto key eviction
+    - scsi: ufs: core: Fix use-after free in init error and remove paths
+    - scsi: storvsc: Set correct data length for sending SCSI command without
+      payload
+    - scsi: core: Do not retry I/Os during depopulation
+    - kbuild: Move -Wenum-enum-conversion to W=2
+    - rust: init: use explicit ABI to clean warning in future compilers
+    - x86/boot: Use '-std=gnu11' to fix build with GCC 15
+    - ubi: Add a check for ubi_num
+    - ARM: dts: dra7: Add bus_dma_limit for l4 cfg bus
+    - ARM: dts: ti/omap: gta04: fix pm issues caused by spi module
+    - arm64: dts: qcom: sm6115: Fix MPSS memory length
+    - arm64: dts: qcom: sm6115: Fix CDSP memory length
+    - arm64: dts: qcom: sm6115: Fix ADSP memory base and length
+    - arm64: dts: qcom: sm6350: Fix ADSP memory length
+    - arm64: dts: qcom: sm6350: Fix MPSS memory length
+    - arm64: dts: qcom: sm6350: Fix uart1 interconnect path
+    - arm64: dts: qcom: sm6375: Fix ADSP memory length
+    - arm64: dts: qcom: sm6375: Fix CDSP memory base and length
+    - arm64: dts: qcom: sm6375: Fix MPSS memory base and length
+    - arm64: dts: qcom: sm8350: Fix ADSP memory base and length
+    - arm64: dts: qcom: sm8350: Fix CDSP memory base and length
+    - arm64: dts: qcom: sm8350: Fix MPSS memory length
+    - arm64: dts: qcom: sm8450: Fix CDSP memory length
+    - arm64: dts: qcom: sm8450: Fix MPSS memory length
+    - arm64: dts: qcom: sm8550: Fix CDSP memory length
+    - arm64: dts: qcom: sm8550: Fix MPSS memory length
+    - arm64: dts: qcom: sm8450: add missing qcom,non-secure-domain property
+    - arm64: dts: qcom: sm8450: Fix ADSP memory base and length
+    - arm64: dts: qcom: sm8550: add missing qcom,non-secure-domain property
+    - arm64: dts: qcom: sm8550: Add dma-coherent property
+    - arm64: dts: qcom: sm8550: Fix ADSP memory base and length
+    - arm64: dts: qcom: sm8650: Fix CDSP memory length
+    - arm64: dts: qcom: sm8650: Fix MPSS memory length
+    - arm64: dts: qcom: sm8550: correct MDSS interconnects
+    - arm64: dts: qcom: sm8650: correct MDSS interconnects
+    - crypto: qce - fix priority to be less than ARMv8 CE
+    - arm64: tegra: Fix typo in Tegra234 dce-fabric compatible
+    - arm64: tegra: Disable Tegra234 sce-fabric node
+    - parisc: Temporarily disable jump label support
+    - pwm: microchip-core: fix incorrect comparison with max period
+    - xfs: Propagate errors from xfs_reflink_cancel_cow_range in
+      xfs_dax_write_iomap_end
+    - xfs: Add error handling for xfs_reflink_cancel_cow_range
+    - ACPI: PRM: Remove unnecessary strict handler address checks
+    - tpm: Change to kvalloc() in eventlog/acpi.c
+    - rv: Reset per-task monitors also for idle tasks
+    - hrtimers: Force migrate away hrtimers queued after
+      CPUHP_AP_HRTIMERS_DYING
+    - kfence: skip __GFP_THISNODE allocations on NUMA systems
+    - media: ccs: Clean up parsed CCS static data on parse failure
+    - mm/hugetlb: fix avoid_reserve to allow taking folio from subpool
+    - iio: light: as73211: fix channel handling in only-color triggered buffer
+    - soc: mediatek: mtk-devapc: Fix leaking IO map on error paths
+    - soc: mediatek: mtk-devapc: Fix leaking IO map on driver remove
+    - soc: qcom: smem_state: fix missing of_node_put in error path
+    - media: mmp: Bring back registration of the device
+    - media: mc: fix endpoint iteration
+    - media: nuvoton: Fix an error check in npcm_video_ece_init()
+    - media: imx296: Add standby delay during probe
+    - media: ov5640: fix get_light_freq on auto
+    - media: stm32: dcmipp: correct dma_set_mask_and_coherent mask value
+    - media: ccs: Fix CCS static data parsing for large block sizes
+    - media: ccs: Fix cleanup order in ccs_probe()
+    - media: i2c: ds90ub9x3: Fix extra fwnode_handle_put()
+    - media: i2c: ds90ub960: Fix use of non-existing registers on UB9702
+    - media: i2c: ds90ub960: Fix UB9702 VC map
+    - media: i2c: ds90ub960: Fix logging SP & EQ status only for UB9702
+    - media: uvcvideo: Fix crash during unbind if gpio unit is in use
+    - media: uvcvideo: Fix event flags in uvc_ctrl_send_events
+    - media: uvcvideo: Support partial control reads
+    - media: uvcvideo: Remove redundant NULL assignment
+    - media: uvcvideo: Refactor iterators
+    - media: uvcvideo: Only save async fh if success
+    - media: uvcvideo: Remove dangling pointers
+    - mm: kmemleak: fix upper boundary check for physical address objects
+    - mm/compaction: fix UBSAN shift-out-of-bounds warning
+    - ata: libata-sff: Ensure that we cannot write outside the allocated
+      buffer
+    - crypto: qce - fix goto jump in error path
+    - crypto: qce - unregister previously registered algos in error path
+    - nvmem: qcom-spmi-sdam: Set size in struct nvmem_config
+    - nvmem: core: improve range check for nvmem_cell_write()
+    - nvmem: imx-ocotp-ele: simplify read beyond device check
+    - nvmem: imx-ocotp-ele: fix MAC address byte order
+    - nvmem: imx-ocotp-ele: fix reading from non zero offset
+    - nvmem: imx-ocotp-ele: set word length to 1
+    - io_uring: fix multishots with selected buffers
+    - io_uring/net: don't retry connect operation on EPOLLERR
+    - selftests: mptcp: connect: -f: no reconnect
+    - pnfs/flexfiles: retry getting layout segment for reads
+    - ocfs2: fix incorrect CPU endianness conversion causing mount failure
+    - ocfs2: handle a symlink read error correctly
+    - nilfs2: fix possible int overflows in nilfs_fiemap()
+    - nfs: Make NFS_FSCACHE select NETFS_SUPPORT instead of depending on it
+    - NFSD: Encode COMPOUND operation status on page boundaries
+    - mailbox: tegra-hsp: Clear mailbox before using message
+    - NFC: nci: Add bounds checking in nci_hci_create_pipe()
+    - irqchip/apple-aic: Only handle PMC interrupt as FIQ when configured so
+    - mtd: onenand: Fix uninitialized retlen in do_otp_read()
+    - misc: misc_minor_alloc to use ida for all dynamic/misc dynamic minors
+    - char: misc: deallocate static minor in error path
+    - misc: fastrpc: Deregister device nodes properly in error scenarios
+    - misc: fastrpc: Fix registered buffer page address
+    - misc: fastrpc: Fix copy buffer page size
+    - net/ncsi: wait for the last response to Deselect Package before
+      configuring channel
+    - net: phy: c45-tjaxx: add delay between MDIO write and read in soft_reset
+    - maple_tree: simplify split calculation
+    - scripts/gdb: fix aarch64 userspace detection in get_current_task
+    - tracing/osnoise: Fix resetting of tracepoints
+    - rtla/osnoise: Distinguish missing workload option
+    - rtla: Add trace_instance_stop
+    - rtla/timerlat_hist: Stop timerlat tracer on signal
+    - rtla/timerlat_top: Stop timerlat tracer on signal
+    - pinctrl: samsung: fix fwnode refcount cleanup if
+      platform_get_irq_optional() fails
+    - ptp: Ensure info->enable callback is always set
+    - RDMA/mlx5: Fix a race for an ODP MR which leads to CQE with error
+    - rtc: zynqmp: Fix optional clock name property
+    - MIPS: ftrace: Declare ftrace_get_parent_ra_addr() as static
+    - xfs: avoid nested calls to __xfs_trans_commit
+    - xfs: don't lose solo superblock counter update transactions
+    - spi: atmel-quadspi: Create `atmel_qspi_ops` to support newer SoC
+      families
+    - spi: atmel-qspi: Memory barriers after memory-mapped I/O
+    - btrfs: avoid monopolizing a core when activating a swap file
+    - mptcp: prevent excessive coalescing on receive
+    - Revert "drm/amd/display: Fix green screen issue after suspend"
+    - statmount: let unset strings be empty
+    - arm64: dts: rockchip: add reset-names for combphy on rk3568
+    - ocfs2: check dir i_size in ocfs2_find_entry
+    - Upstream stable to v6.6.77, v6.12.14
+
+  * kvmppc_set_passthru_irq_hv: Could not assign IRQ map traces are seen when
+    pci device is attached to kvm guest when "xive=off" is set (LP: #2109951)
+    - KVM: PPC: Book3S HV: Fix IRQ map warnings with XICS on pSeries KVM Guest
+
+  * Latitude 5450 is experiencing packet loss on Ethernet in Ubuntu 22.04
+    (LP: #2106558)
+    - e1000e: change k1 configuration on MTP and later platforms
+
+  * cpufreq amd-pstate: cpuinfo_max_freq reports incorrect value
+    (LP: #2109609)
+    - SAUCE: Revert "Revert "cpufreq: amd-pstate: Fix the inconsistency in max
+      frequency units""
+
+  * Backport pci=config_acs parameter with fix commit (LP: #2100340)
+    - PCI: Extend ACS configurability
+    - PCI: Fix pci_enable_acs() support for the ACS quirks
+    - PCI/ACS: Fix 'pci=config_acs=' parameter
+
+  * [UBUNTU 24.04] s390/pci: Fix zpci_bus_is_isolated_vf() for non-VF
+    (LP: #2111599)
+    - s390/pci: Fix zpci_bus_is_isolated_vf() for non-VFs
+
+  * nvme/tcp hangs IO on arm (LP: #2106381)
+    - nvmet-tcp: Fix a possible sporadic response drops in weakly ordered arch
+
+  * CVE-2025-37750
+    - smb: client: fix UAF in decryption with multichannel
+
+  * CVE-2025-40364
+    - io_uring: fix io_req_prep_async with provided buffers
+
+  * CVE-2024-49887
+    - f2fs: fix to handle segment allocation failure correctly
+    - f2fs: fix to don't panic system for no free segment fault injection
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953)
+    - powerpc/book3s64/hugetlb: Fix disabling hugetlb when fadump is active
+    - dlm: fix srcu_read_lock() return type to int
+    - afs: Fix EEXIST error returned from afs_rmdir() to be ENOTEMPTY
+    - afs: Fix directory format encoding struct
+    - afs: Fix cleanup of immediately failed async calls
+    - fs: fix proc_handler for sysctl_nr_open
+    - block: retry call probe after request_module in blk_request_module
+    - pstore/blk: trivial typo fixes
+    - nvme: Add error check for xa_store in nvme_get_effects_log
+    - selftests/powerpc: Fix argument order to timer_sub()
+    - nvme: Add error path for xa_store in nvme_init_effects
+    - partitions: ldm: remove the initial kernel-doc notation
+    - select: Fix unbalanced user_access_end()
+    - nvme: fix bogus kzalloc() return check in nvme_init_effects_log()
+    - afs: Fix the fallback handling for the YFS.RemoveFile2 RPC call
+    - perf/core: Save raw sample data conditionally based on sample type
+    - sched/fair: Fix value reported by hot tasks pulled in /proc/schedstat
+    - x86/cpu: Enable SD_ASYM_PACKING for PKG domain on AMD
+    - x86/topology: Use x86_sched_itmt_flags for PKG domain unconditionally
+    - drm/msm/dp: set safe_to_exit_level before printing it
+    - drm/etnaviv: Fix page property being used for non writecombine buffers
+    - drm/amd/pm: Fix an error handling path in
+      vega10_enable_se_edc_force_stall_config()
+    - drm/rockchip: vop2: Fix cluster windows alpha ctrl regsiters offset
+    - drm/rockchip: vop2: Fix the mixer alpha setup for layer 0
+    - drm/rockchip: vop2: Fix the windows switch between different layers
+    - drm/rockchip: vop2: Check linear format for Cluster windows on rk3566/8
+    - drm/rockchip: vop2: include rockchip_drm_drv.h
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8150
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SC8180X
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8250
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8350
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8550
+    - drm/msm: Check return value of of_dma_configure()
+    - drm/bridge: it6505: Change definition of AUX_FIFO_MAX_SIZE
+    - drm/amdgpu: tear down ttm range manager for doorbell in
+      amdgpu_ttm_fini()
+    - genirq: Make handle_enforce_irqctx() unconditionally available
+    - wifi: ath11k: Fix unexpected return buffer manager error for
+      WCN6750/WCN6855
+    - wifi: rtlwifi: do not complete firmware loading needlessly
+    - wifi: rtlwifi: rtl8192se: rise completion of firmware loading as last
+      step
+    - wifi: rtlwifi: wait for firmware loading before releasing memory
+    - wifi: rtlwifi: fix init_sw_vars leak when probe fails
+    - wifi: rtlwifi: usb: fix workqueue leak when probe fails
+    - net_sched: sch_sfq: annotate data-races around q->perturb_period
+    - net_sched: sch_sfq: handle bigger packets
+    - spi: zynq-qspi: Add check for clk_enable()
+    - dt-bindings: mmc: controller: clarify the address-cells description
+    - of: remove internal arguments from of_property_for_each_u32()
+    - clk: fix an OF node reference leak in of_clk_get_parent_name()
+    - dt-bindings: leds: class-multicolor: Fix path to color definitions
+    - wifi: rtlwifi: destroy workqueue at rtl_deinit_core
+    - wifi: rtlwifi: pci: wait for firmware loading before releasing memory
+    - HID: multitouch: fix support for Goodix PID 0x01e9
+    - regulator: dt-bindings: mt6315: Drop regulator-compatible property
+    - wifi: brcmfmac: add missing header include for brcmf_dbg
+    - ACPI: fan: cleanup resources in the error path of .probe()
+    - cpupower: fix TSC MHz calculation
+    - dt-bindings: mfd: bd71815: Fix rsense and typos
+    - leds: netxbig: Fix an OF node reference leak in
+      netxbig_leds_get_of_pdata()
+    - inetpeer: remove create argument of inet_getpeer_v[46]()
+    - inetpeer: remove create argument of inet_getpeer()
+    - inetpeer: update inetpeer timestamp in inet_getpeer()
+    - inetpeer: do not get a refcount in inet_getpeer()
+    - pwm: stm32-lp: Add check for clk_enable()
+    - cpufreq: schedutil: Fix superfluous updates caused by need_freq_update
+    - gpio: pca953x: log an error when failing to get the reset GPIO
+    - cpufreq: qcom: Fix qcom_cpufreq_hw_recalc_rate() to query LUT if LMh IRQ
+      is not available
+    - cpufreq: qcom: Implement clk_ops::determine_rate() for qcom_cpufreq*
+      clocks
+    - clk: imx8mp: Fix clkout1/2 support
+    - dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and PLL_MIPI
+    - clk: sunxi-ng: a64: drop redundant CLK_PLL_VIDEO0_2X and CLK_PLL_MIPI
+    - clk: sunxi-ng: a64: stop force-selecting PLL-MIPI as TCON0 parent
+    - regulator: of: Implement the unwind path of of_regulator_match()
+    - OPP: OF: Fix an OF node leak in _opp_add_static_v2()
+    - ipmi: ssif_bmc: Fix new request loss when bmc ready for a response
+    - wifi: ath12k: fix tx power, max reg power update to firmware
+    - clk: qcom: gcc-sdm845: Do not use shared clk_ops for QUPs
+    - HID: fix generic desktop D-Pad controls
+    - leds: cht-wcove: Use devm_led_classdev_register() to avoid memory leak
+    - mfd: syscon: Remove extern from function prototypes
+    - mfd: syscon: Add of_syscon_register_regmap() API
+    - mfd: syscon: Use scoped variables with memory allocators to simplify
+      error paths
+    - mfd: syscon: Fix race in device_node_get_regmap()
+    - samples/landlock: Fix possible NULL dereference in parse_path()
+    - wifi: wlcore: fix unbalanced pm_runtime calls
+    - wifi: mt76: mt7915: Fix mesh scan on MT7916 DBDC
+    - wifi: mac80211: fix tid removal during mesh forwarding
+    - wifi: mac80211: Fix common size calculation for ML element
+    - net/smc: fix data error when recvmsg with MSG_PEEK flag
+    - wifi: mt76: mt76u_vendor_request: Do not print error messages when
+      -EPROTO
+    - wifi: mt76: mt7921: fix using incorrect group cipher after
+      disconnection.
+    - wifi: mt76: mt7915: fix overflows seen when writing limit attributes
+    - wifi: mt76: mt7996: fix rx filter setting for bfee functionality
+    - wifi: mt76: mt7915: firmware restart on devices with a second pcie link
+    - wifi: mt76: connac: move mt7615_mcu_del_wtbl_all to connac
+    - wifi: mt76: mt7915: improve hardware restart reliability
+    - wifi: mt76: mt7915: fix omac index assignment after hardware reset
+    - wifi: mt76: mt7915: fix register mapping
+    - wifi: mt76: mt7996: fix register mapping
+    - wifi: mt76: mt7996: add max mpdu len capability
+    - wifi: mt76: mt7996: fix the capability of reception of EHT MU PPDU
+    - wifi: mt76: mt7996: fix HE Phy capability
+    - wifi: mt76: mt7996: fix incorrect indexing of MIB FW event
+    - wifi: mt76: mt7996: fix ldpc setting
+    - cpufreq: ACPI: Fix max-frequency computation
+    - selftests: timers: clocksource-switch: Adapt progress to kselftest
+      framework
+    - selftests: harness: fix printing of mismatch values in __EXPECT()
+    - wifi: cfg80211: adjust allocation of colocated AP data
+    - inet: ipmr: fix data-races
+    - clk: analogbits: Fix incorrect calculation of vco rate delta
+    - pwm: stm32: Add check for clk_enable()
+    - selftests/landlock: Fix error message
+    - net/mlxfw: Drop hard coded max FW flash image size
+    - octeon_ep: remove firmware stats fetch in ndo_get_stats64
+    - netfilter: nf_tables: fix set size with rbtree backend
+    - netfilter: nft_flow_offload: update tcp state flags under lock
+    - tcp_cubic: fix incorrect HyStart round start detection
+    - libbpf: don't adjust USDT semaphore address if .stapsdt.base addr is
+      missing
+    - tools/testing/selftests/bpf/test_tc_tunnel.sh: Fix wait for server bind
+    - libbpf: Fix segfault due to libelf functions not setting errno
+    - ASoC: sun4i-spdif: Add clock multiplier settings
+    - selftests/bpf: Fix fill_link_info selftest on powerpc
+    - crypto: caam - use JobR's space to access page 0 regs
+    - perf header: Fix one memory leakage in process_bpf_btf()
+    - perf header: Fix one memory leakage in process_bpf_prog_info()
+    - perf bpf: Fix two memory leakages when calling
+      perf_env__insert_bpf_prog_info()
+    - ASoC: renesas: rz-ssi: Use only the proper amount of dividers
+    - perf expr: Initialize is_test value in expr__ctx_new()
+    - ktest.pl: Remove unused declarations in run_bisect_test function
+    - crypto: hisilicon/sec2 - fix for aead icv error
+    - crypto: hisilicon/sec2 - fix for aead invalid authsize
+    - crypto: ixp4xx - fix OF node reference leaks in init_ixp_crypto()
+    - ALSA: seq: remove redundant 'tristate' for SND_SEQ_UMP_CLIENT
+    - ALSA: seq: Make dependency on UMP clearer
+    - padata: fix sysfs store callback check
+    - perf top: Don't complain about lack of vmlinux when not resolving some
+      kernel samples
+    - perf machine: Don't ignore _etext when not a text symbol
+    - perf namespaces: Introduce nsinfo__set_in_pidns()
+    - perf namespaces: Fixup the nsinfo__in_pidns() return type, its bool
+    - ASoC: Intel: avs: Prefix SKL/APL-specific members
+    - ASoC: Intel: avs: Abstract IPC handling
+    - ASoC: Intel: avs: Do not readq() u32 registers
+    - ASoC: Intel: avs: Fix theoretical infinite loop
+    - perf report: Fix misleading help message about --demangle
+    - pinctrl: stm32: Add check for clk_enable()
+    - pinctrl: amd: Take suspend type into consideration which pins are non-
+      wake
+    - bpf: tcp: Mark bpf_load_hdr_opt() arg2 as read-write
+    - ALSA: hda/realtek - Fixed headphone distorted sound on Acer Aspire
+      A115-31 laptop
+    - perf lock: Fix parse_lock_type which only retrieve one lock flag
+    - padata: add pd get/put refcnt helper
+    - cifs: Use cifs_autodisable_serverino() for disabling
+      CIFS_MOUNT_SERVER_INUM in readdir.c
+    - soc: atmel: fix device_node release in atmel_soc_device_init()
+    - ARM: at91: pm: change BU Power Switch to automatic mode
+    - arm64: dts: mediatek: mt8186: Move wakeup to MTU3 to get working suspend
+    - arm64: dts: mt8183: set DMIC one-wire mode on Damu
+    - arm64: dts: mediatek: mt8516: fix GICv2 range
+    - arm64: dts: mediatek: mt8516: fix wdt irq type
+    - arm64: dts: mediatek: mt8516: add i2c clock-div property
+    - arm64: dts: mediatek: mt8516: reserve 192 KiB for TF-A
+    - ARM: dts: stm32: Fix IPCC EXTI declaration on stm32mp151
+    - RDMA/mlx4: Avoid false error about access to uninitialized gids array
+    - arm64: dts: mediatek: mt8173-evb: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8173-elm: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8192-asurada: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8195-cherry: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8195-demo: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8173-elm: Fix MT6397 PMIC sub-node names
+    - arm64: dts: mediatek: mt8173-evb: Fix MT6397 PMIC sub-node names
+    - ARM: dts: aspeed: yosemite4: correct the compatible string of adm1272
+    - ARM: dts: aspeed: yosemite4: Add required properties for IOE on fan
+      boards
+    - ARM: dts: aspeed: yosemite4: correct the compatible string for max31790
+    - arm: dts: socfpga: use reset-name "stmmaceth-ocp" instead of "ahb"
+    - RDMA/rxe: Improve newline in printing messages
+    - RDMA/rxe: Fix mismatched max_msg_sz
+    - arm64: dts: mediatek: mt8183: kenzo: Support second source touchscreen
+    - arm64: dts: mediatek: mt8183: willow: Support second source touchscreen
+    - RDMA/srp: Fix error handling in srp_add_port
+    - arm64: dts: mediatek: mt8195: Remove suspend-breaking reset from pcie1
+    - ARM: dts: stm32: Deduplicate serial aliases and chosen node for
+      STM32MP15xx DHCOM SoM
+    - ARM: dts: stm32: Swap USART3 and UART8 alias on STM32MP15xx DHCOM SoM
+    - arm64: dts: mediatek: mt8183-kukui-jacuzzi: Drop pp3300_panel voltage
+      settings
+    - arm64: dts: qcom: msm8996-xiaomi-gemini: Fix LP5562 LED1 reg property
+    - arm64: dts: qcom: move common parts for sa8775p-ride variants into a
+      .dtsi
+    - arm64: dts: qcom: sa8775p: Update sleep_clk frequency
+    - arm64: dts: qcom: msm8996: Fix up USB3 interrupts
+    - arm64: dts: qcom: msm8994: Describe USB interrupts
+    - arm64: dts: qcom: sm7225-fairphone-fp4: Drop extra qcom,msm-id value
+    - arm64: dts: qcom: msm8916: correct sleep clock frequency
+    - arm64: dts: qcom: msm8939: correct sleep clock frequency
+    - arm64: dts: qcom: msm8994: correct sleep clock frequency
+    - arm64: dts: qcom: qcs404: correct sleep clock frequency
+    - arm64: dts: qcom: q[dr]u1000: correct sleep clock frequency
+    - arm64: dts: qcom: qrb4210-rb2: correct sleep clock frequency
+    - arm64: dts: qcom: sc7280: correct sleep clock frequency
+    - arm64: dts: qcom: sdx75: correct sleep clock frequency
+    - arm64: dts: qcom: sm4450: correct sleep clock frequency
+    - arm64: dts: qcom: sm6125: correct sleep clock frequency
+    - arm64: dts: qcom: sm6375: correct sleep clock frequency
+    - arm64: dts: qcom: sm8250: correct sleep clock frequency
+    - arm64: dts: qcom: sm8350: correct sleep clock frequency
+    - arm64: dts: qcom: sm8450: correct sleep clock frequency
+    - ARM: dts: microchip: sama5d27_wlsom1_ek: Add no-1-8-v property to sdmmc0
+      node
+    - arm64: dts: ti: k3-am62: Remove duplicate GICR reg
+    - arm64: dts: ti: k3-am62a: Remove duplicate GICR reg
+    - arm64: dts: allwinner: a64: explicitly assign clock parent for TCON0
+    - RDMA/bnxt_re: Fix to drop reference to the mmap entry in case of error
+    - ARM: omap1: Fix up the Retu IRQ on Nokia 770
+    - arm64: dts: qcom: sdm845-db845c-navigation-mezzanine: Convert mezzanine
+      riser to dtso
+    - arm64: dts: qcom: sdm845-db845c-navigation-mezzanine: remove disabled
+      ov7251 camera
+    - arm64: dts: qcom: sc7180-trogdor-quackingstick: add missing avee-supply
+    - arm64: dts: qcom: sc7180-*: Remove thermal zone polling delays
+    - arm64: dts: qcom: sc7180-trogdor-pompom: rename 5v-choke thermal zone
+    - arm64: dts: qcom: sc7180: change labels to lower-case
+    - arm64: dts: qcom: sc7180: fix psci power domain node names
+    - arm64: dts: qcom: sm8150-microsoft-surface-duo: fix typos in da7280
+      properties
+    - arm64: dts: qcom: sc8280xp: Fix up remoteproc register space sizes
+    - dts: arm64: mediatek: mt8195: Remove MT8183 compatible for OVL
+    - arm64: dts: mediatek: add per-SoC compatibles for keypad nodes
+    - arm64: dts: qcom: sdm845: Fix interrupt types of camss interrupts
+    - arm64: dts: qcom: sm8250: Fix interrupt types of camss interrupts
+    - ARM: dts: mediatek: mt7623: fix IR nodename
+    - fbdev: omapfb: Fix an OF node leak in dss_of_port_get_parent_device()
+    - arm64: tegra: Fix DMA ID for SPI2
+    - i3c: dw: Add hot-join support.
+    - RDMA/mlx5: Fix indirect mkey ODP page count
+    - of: reserved-memory: Do not make kmemleak ignore freed address
+    - efi: sysfb_efi: fix W=1 warnings when EFI is not set
+    - spi: omap2-mcspi: Correctly handle devm_clk_get_optional() errors
+    - media: rc: iguanair: handle timeouts
+    - media: lmedm04: Handle errors for lme2510_int_read
+    - PCI: endpoint: Destroy the EPC device in devm_pci_epc_destroy()
+    - media: marvell: Add check for clk_enable()
+    - media: i2c: imx290: Register 0x3011 varies between imx327 and imx290
+    - media: i2c: imx412: Add missing newline to prints
+    - media: i2c: ov9282: Correct the exposure offset
+    - media: mipi-csis: Add check for clk_enable()
+    - media: camif-core: Add check for clk_enable()
+    - media: uvcvideo: Propagate buf->error to userspace
+    - mtd: rawnand: brcmnand: fix status read of brcmnand_waitfunc
+    - mtd: hyperbus: hbmc-am654: fix an OF node reference leak
+    - media: nxp: imx8-isi: fix v4l2-compliance test errors
+    - watchdog: rti_wdt: Fix an OF node leak in rti_wdt_probe()
+    - staging: media: imx: fix OF node leak in imx_media_add_of_subdevs()
+    - media: dvb-usb-v2: af9035: fix ISO C90 compilation error on
+      af9035_i2c_master_xfer
+    - PCI: endpoint: pci-epf-test: Set dma_chan_rx pointer to NULL on error
+    - PCI: endpoint: pci-epf-test: Fix check for DMA MEMCPY test
+    - scsi: mpt3sas: Set ioc->manu_pg11.EEDPTagMode directly to 1
+    - scsi: ufs: bsg: Delete bsg_dev when setting up bsg fails
+    - ocfs2: mark dquot as inactive if failed to start trans while releasing
+      dquot
+    - module: Extend the preempt disabled section in
+      dereference_symbol_descriptor().
+    - serial: 8250: Adjust the timeout for FIFO mode
+    - NFSv4.2: fix COPY_NOTIFY xdr buf size calculation
+    - NFSv4.2: mark OFFLOAD_CANCEL MOVEABLE
+    - tools/bootconfig: Fix the wrong format specifier
+    - xfrm: replay: Fix the update of replay_esn->oseq_hi for GSO
+    - dmaengine: ti: edma: fix OF node reference leaks in edma_driver
+    - rtc: loongson: clear TOY_MATCH0_REG in loongson_rtc_isr()
+    - regulator: core: Add missing newline character
+    - gpio: mxc: remove dead code after switch to DT-only
+    - net: fec: implement TSO descriptor cleanup
+    - PM: hibernate: Add error handling for syscore_suspend()
+    - iavf: allow changing VLAN state without calling PF
+    - net: netdevsim: try to close UDP port harness races
+    - ptp: Properly handle compat ioctls
+    - net: stmmac: Limit the number of MTL queues to hardware capability
+    - net: stmmac: Limit FIFO size by hardware capability
+    - perf trace: Fix runtime error of index out of bounds
+    - Bluetooth: btnxpuart: Fix glitches seen in dual A2DP streaming
+    - vsock: Allow retrying on connect() failure
+    - bgmac: reduce max frame size to support just MTU 1500
+    - net: sh_eth: Fix missing rtnl lock in suspend/resume path
+    - genksyms: fix memory leak when the same symbol is added from source
+    - genksyms: fix memory leak when the same symbol is read from *.symref
+      file
+    - RISC-V: Mark riscv_v_init() as __init
+    - ASoC: rockchip: i2s_tdm: Re-add the set_sysclk callback
+    - io_uring/uring_cmd: use cached cmd_op in io_uring_cmd_sock()
+    - cifs: Fix getting and setting SACLs over SMB1
+    - kconfig: fix file name in warnings when loading KCONFIG_DEFCONFIG_LIST
+    - kconfig: fix memory leak in sym_warn_unmet_dep()
+    - hexagon: fix using plain integer as NULL pointer warning in cmpxchg
+    - hexagon: Fix unbalanced spinlock in die()
+    - f2fs: Introduce linear search for dentries
+    - Revert "SUNRPC: Reduce thread wake-up rate when receiving large RPC
+      messages"
+    - kbuild: switch from lz4c to lz4 for compression
+    - selftests/rseq: Fix handling of glibc without rseq support
+    - ktest.pl: Check kernelrelease return in get_version
+    - ALSA: usb-audio: Add delay quirk for iBasso DC07 Pro
+    - usb: gadget: f_tcm: Fix Get/SetInterface return value
+    - usb: dwc3-am62: Fix an OF node leak in phy_syscon_pll_refclk()
+    - usb: dwc3: core: Defer the probe until USB power supply ready
+    - usb: typec: tcpm: set SRC_SEND_CAPABILITIES timeout to
+      PD_T_SENDER_RESPONSE
+    - usb: typec: tcpci: Prevent Sink disconnection before vPpsShutdown in SPR
+      PPS
+    - btrfs: output the reason for open_ctree() failure
+    - s390: Add '-std=gnu11' to decompressor and purgatory CFLAGS
+    - LoongArch: Change 8 to 14 for LOONGARCH_MAX_{BRP,WRP}
+    - block: copy back bounce buffer to user-space correctly in case of split
+    - nvme-tcp: Fix I/O queue cpu spreading for multiple controllers
+    - sched/fair: Untangle NEXT_BUDDY and pick_next_task()
+    - sched: Fix race between yield_to() and try_to_wake_up()
+    - drm/v3d: Fix performance counter source settings on V3D 7.x
+    - drm/rockchip: vop2: fix rk3588 dp+dsi maxclk verification
+    - drm/rockchip: vop2: Set AXI id for rk3588
+    - drm/rockchip: vop2: Setup delay cycle for Esmart2/3
+    - drm/rockchip: vop2: Add check for 32 bpp format for rk3588
+    - drm/msm/dpu: provide DSPP and correct LM config for SDM670
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8650
+    - drm/msm: don't clean up priv->kms prematurely
+    - drm/msm/mdp4: correct LCDC regulator name
+    - wifi: rtlwifi: rtl8821ae: phy: restore removed code to fix infinite loop
+    - selftests/bpf: Actuate tx_metadata_len in xdp_hw_metadata
+    - selftests: ktap_helpers: Fix uninitialized variable
+    - inet: constify inet_sk_bound_dev_eq() net parameter
+    - inet: constify 'struct net' parameter of various lookup helpers
+    - udp: constify 'struct net' parameter of socket lookups
+    - inet6: constify 'struct net' parameter of various lookup helpers
+    - ipv6: udp: constify 'struct net' parameter of socket lookups
+    - dt-bindings: clock: imx93: Drop IMX93_CLK_END macro definition
+    - dt-bindings: clock: Add i.MX91 clock support
+    - dt-bindings: clock: imx93: Add SPDIF IPG clk
+    - clk: imx93: Move IMX93_CLK_END macro to clk driver
+    - clk: imx: add i.MX91 clk
+    - clk: imx93: Add IMX93_CLK_SPDIF_IPG clock
+    - arm64: dts: imx93: Use IMX93_CLK_SPDIF_IPG as SPDIF IPG clock
+    - clk: imx: Apply some clks only for i.MX93
+    - wifi: rtw89: mcc: consider time limits not divisible by 1024
+    - wifi: iwlwifi: cleanup uefi variables loading
+    - wifi: iwlwifi: fw: read STEP table from correct UEFI var
+    - wifi: mt76: mt7996: fix overflows seen when writing limit attributes
+    - wifi: mt76: mt7996: fix definition of tx descriptor
+    - Bluetooth: btbcm: Fix NULL deref in btbcm_get_board_name()
+    - platform/mellanox: mlxbf-pmc: incorrect type in assignment
+    - platform/x86: x86-android-tablets: make platform data be static
+    - crypto: api - Fix boot-up self-test race
+    - pinctrl: nomadik: Add check for clk_enable()
+    - rhashtable: Fix potential deadlock by moving schedule_work outside lock
+    - crypto: iaa - Fix IAA disabling that occurs when sync_mode is set to
+      'async'
+    - perf maps: Fix display of kernel symbols
+    - perf MANIFEST: Add arch/*/include/uapi/asm/bpf_perf_event.h to the perf
+      tarball
+    - ALSA: hda: Fix compilation of snd_hdac_adsp_xxx() helpers
+    - tools: Sync if_xdp.h uapi tooling header
+    - rhashtable: Fix rhashtable_try_insert test
+    - ARM: dts: imx7-tqma7: add missing vs-supply for LM75A (rev. 01xxx)
+    - arm64: dts: renesas: rzg3s-smarc: Fix the debug serial alias
+    - arm64: dts: mediatek: mt8395-genio-1200-evk: Drop regulator-compatible
+      property
+    - arm64: dts: qcom: sm8550: correct sleep clock frequency
+    - arm64: dts: qcom: sm8650: correct sleep clock frequency
+    - arm64: dts: qcom: x1e80100: correct sleep clock frequency
+    - ARM: dts: microchip: sama5d29_curiosity: Add no-1-8-v property to sdmmc0
+      node
+    - RDMA/hns: Clean up the legacy CONFIG_INFINIBAND_HNS
+    - [Config] updateconfigs for INFINIBAND_HNS
+    - RDMA/cxgb4: Notify rdma stack for IB_EVENT_QP_LAST_WQE_REACHED event
+    - iommu: iommufd: fix WARNING in iommufd_device_unbind
+    - remoteproc: mtk_scp: Only populate devices for SCP cores
+    - PCI: imx6: Deassert apps_reset in imx_pcie_deassert_core_reset()
+    - PCI: dwc: Always stop link in the dw_pcie_suspend_noirq
+    - PCI: microchip: Add support for using either Root Port 1 or 2
+    - PCI: microchip: Set inbound address translation for coherent or non-
+      coherent mode
+    - erofs: get rid of erofs_{find,insert}_workgroup
+    - erofs: move erofs_workgroup operations into zdata.c
+    - erofs: sunset `struct erofs_workgroup`
+    - erofs: fix potential return value overflow of z_erofs_shrink_scan()
+    - tty: mips_ejtag_fdc: fix one more u8 warning
+    - xfrm: Add support for per cpu xfrm state handling.
+    - xfrm: Cache used outbound xfrm states at the policy.
+    - xfrm: Add an inbound percpu state cache.
+    - xfrm: Don't disable preemption while looking up cache state.
+    - idpf: add read memory barrier when checking descriptor done bit
+    - net/ncsi: use dev_set_mac_address() for Get MC MAC Address handling
+    - tools: ynl: c: correct reverse decode of empty attrs
+    - selftests: mptcp: extend CFLAGS to keep options from environment
+    - selftests: net/{lib,openvswitch}: extend CFLAGS to keep options from
+      environment
+    - net: ethtool: only allow set_rxnfc with rss + ring_cookie if driver opts
+      in
+    - ethtool: Fix set RXNFC command with symmetric RSS hash
+    - tools/power turbostat: Fix forked child affinity regression
+    - md: add a new callback pers->bitmap_sector()
+    - md/raid5: implement pers->bitmap_sector()
+    - xfs: check for dead buffers in xfs_buf_find_insert
+    - xfs: don't shut down the filesystem for media failures beyond end of log
+    - usb: dwc3: Skip resume if pm_runtime_set_active() fails
+    - clk: qcom: gcc-x1e80100: Do not turn off usb_2 controller GDSC
+    - xfrm: Add error handling when nla_put_u32() returns an error
+    - xfrm: Fix acquire state insertion.
+    - ethtool: Fix access to uninitialized fields in set RXNFC command
+    - ASoC: da7213: Initialize the mutex
+    - drm/amd/display: Add hubp cache reset when powergating
+    - KVM: x86: Plumb in the vCPU to kvm_x86_ops.hwapic_isr_update()
+    - ethtool: ntuple: fix rss + ring_cookie check
+    - Upstream stable to v6.6.76, v6.12.13
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57975
+    - btrfs: do proper folio cleanup when run_delalloc_nocow() failed
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21714
+    - RDMA/mlx5: Fix implicit ODP use after free
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21801
+    - net: ravb: Fix missing rtnl lock in suspend/resume path
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21809
+    - rxrpc, afs: Fix peer hash locking vs RCU callback
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58057
+    - idpf: convert workqueues to unbound
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57953
+    - rtc: tps6594: Fix integer overflow on 32bit systems
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57982
+    - xfrm: state: fix out-of-bounds read during lookup
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21721
+    - nilfs2: handle errors that nilfs_prepare_chunk() may return
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21722
+    - nilfs2: do not force clear folio if buffer is referenced
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21798
+    - firewire: test: Fix potential null dereference in firewire kunit test
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21723
+    - scsi: mpi3mr: Fix possible crash when setting up bsg fails
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21724
+    - iommufd/iova_bitmap: Fix shift-out-of-bounds in
+      iova_bitmap_offset_to_index()
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21825
+    - bpf: Cancel the running bpf_timer through kworker for PREEMPT_RT
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57990
+    - wifi: mt76: mt7925: fix off by one in mt7925_load_clc()
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57974
+    - udp: Deal with race between UDP socket address change and rehash
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57994
+    - ptr_ring: do not block hard interrupts in ptr_ring_resize_multiple()
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57999
+    - powerpc/pseries/iommu: IOMMU incorrectly marks MMIO range in DDW
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58054
+    - staging: media: max96712: fix kernel oops when removing module
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58055
+    - usb: gadget: f_tcm: Don't free command immediately
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57979
+    - pps: Fix a use-after-free
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57980
+    - media: uvcvideo: Fix double free in error path
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58056
+    - remoteproc: core: Fix ida_free call while not allocated
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21705
+    - mptcp: handle fastopen disconnect correctly
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21707
+    - mptcp: consolidate suboption status
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57981
+    - usb: xhci: Fix NULL pointer dereference on certain command aborts
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21708
+    - net: usb: rtl8150: enable basic endpoint checking
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21826
+    - netfilter: nf_tables: reject mismatching sum of field_len with set key
+      length
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21808
+    - net: xdp: Disallow attaching device-bound programs in generic mode
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21710
+    - tcp: correct handling of extreme memory squeeze
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21715
+    - net: davicom: fix UAF in dm9000_drv_remove
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21716
+    - vxlan: Fix uninit-value in vxlan_vnifilter_dump()
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21718
+    - net: rose: fix timer races against user threads
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21719
+    - ipmr: do not call mr_mfc_uses_dev() for unres entries
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21802
+    - net: hns3: fix oops when unload drivers paralleling
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58058
+    - ubifs: skip dumping tnc tree when zroot is null
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58069
+    - rtc: pcf85063: fix potential OOB write in PCF85063 NVMEM read
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21720
+    - xfrm: delete intermediate secpath entry in packet offload mode
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21803
+    - LoongArch: Fix warnings during S3 suspend
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21810
+    - driver core: class: Fix wild pointer dereferences in API
+      class_dev_iter_next()
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21811
+    - nilfs2: protect access to buffers with no active references
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21804
+    - PCI: rcar-ep: Fix incorrect variable used when calling
+      devm_request_mem_region()
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21829
+    - RDMA/rxe: Fix the warning "__rxe_cleanup+0x12c/0x170 [rdma_rxe]"
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57984
+    - i3c: dw: Fix use-after-free in dw_i3c_master driver due to race
+      condition
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58034
+    - memory: tegra20-emc: fix an OF node reference bug in
+      tegra_emc_find_node_by_ram_code()
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57973
+    - rdma/cxgb4: Prevent potential integer overflow on 32bit
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21725
+    - smb: client: fix oops due to unset link speed
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21726
+    - padata: avoid UAF for reorder_work
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21727
+    - padata: fix UAF in padata_reorder
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21728
+    - bpf: Send signals asynchronously if !preemptible
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58070
+    - bpf: bpf_local_storage: Always use bpf_mem_alloc in PREEMPT_RT
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21711
+    - net/rose: prevent integer overflows in rose_setsockopt()
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21799
+    - net: ethernet: ti: am65-cpsw: fix freeing IRQ in
+      am65_cpsw_nuss_remove_tx_chns()
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21806
+    - net: let net.core.dev_weight always be non-zero
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21830
+    - landlock: Handle weird files
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21828
+    - wifi: mac80211: don't flush non-uploaded STAs
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58061
+    - wifi: mac80211: prohibit deactivating all links
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57993
+    - HID: hid-thrustmaster: Fix warning in thrustmaster_probe by adding
+      endpoint check
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21812
+    - ax25: rcu protect dev->ax25_ptr
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58071
+    - team: prevent adding a device which is already a team device lower
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58063
+    - wifi: rtlwifi: fix memory leaks and invalid access at probe error path
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58072
+    - wifi: rtlwifi: remove unused check_buddy_priv
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58053
+    - rxrpc: Fix handling of received connection abort
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57996
+    - net_sched: sch_sfq: don't allow 1 packet limit
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57997
+    - wifi: wcn36xx: fix channel survey memory allocation size
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58051
+    - ipmi: ipmb: Add check devm_kasprintf() returned value
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58068
+    - OPP: fix dev_pm_opp_find_bw_*() when bandwidth table not initialized
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57998
+    - OPP: add index check to assert to avoid buffer overflow in _read_freq()
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58052
+    - drm/amdgpu: Fix potential NULL pointer dereference in
+      atomctrl_get_smc_sclk_range_table
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57986
+    - HID: core: Fix assumption that Resolution Multipliers must be in Logical
+      Collections
+
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21731
+    - nbd: don't allow reconnect after disconnect
+
+  * CVE-2025-37798
+    - sch_htb: make htb_qlen_notify() idempotent
+    - sch_htb: make htb_deactivate() idempotent
+    - sch_drr: make drr_qlen_notify() idempotent
+    - sch_hfsc: make hfsc_qlen_notify() idempotent
+    - sch_qfq: make qfq_qlen_notify() idempotent
+    - sch_ets: make est_qlen_notify() idempotent
+    - codel: remove sch->q.qlen check before qdisc_tree_reduce_backlog()
+
+  * CVE-2025-37997
+    - netfilter: ipset: fix region locking in hash types
+
+  * CVE-2025-22088
+    - RDMA/erdma: Prevent use-after-free in erdma_accept_newconn()
+
+  * CVE-2025-37890
+    - net_sched: hfsc: Fix a UAF vulnerability in class with netem as child
+      qdisc
+    - sch_hfsc: Fix qlen accounting bug when using peek in hfsc_enqueue()
+    - net_sched: hfsc: Address reentrant enqueue adding class to eltree twice
+
+  * raid1: Fix NULL pointer dereference in process_checks() (LP: #2112519)
+    - md/raid1: Add check for missing source disk in process_checks()
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - [Packaging] update annotations scripts
+
+ -- Mehmet Basaran <mehmet.basaran@canonical.com>  Sun, 15 Jun 2025 10:53:51 +0300
+
+linux (6.8.0-62.65) noble; urgency=medium
+
+  * noble/linux: 6.8.0-62.65 -proposed tracker (LP: #2110737)
+
+  * Rotate the Canonical Livepatch key (LP: #2111244)
+    - [Config] Prepare for Canonical Livepatch key rotation
+
+  * KVM bug causes Firecracker crash when it runs the vCPU for the first time
+    (LP: #2109859)
+    - vhost: return task creation error instead of NULL
+    - kvm: retry nx_huge_page_recovery_thread creation
+
+  * CVE-2025-2312 cifs.upcall could access incorrect kerberos credentials cache
+    (LP: #2099914) // CVE-2025-2312
+    - CIFS: New mount option for cifs.upcall namespace resolution
+
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640)
+    - ASoC: wm8994: Add depends on MFD core
+    - ASoC: samsung: Add missing selects for MFD_WM8994
+    - seccomp: Stub for !CONFIG_SECCOMP
+    - scsi: iscsi: Fix redundant response for ISCSI_UEVENT_GET_HOST_STATS request
+    - of/unittest: Add test that of_address_to_resource() fails on non-
+      translatable address
+    - irqchip/sunxi-nmi: Add missing SKIP_WAKE flag
+    - hwmon: (drivetemp) Set scsi command timeout to 10s
+    - ASoC: samsung: Add missing depends on I2C
+    - ata: libata-core: Set ATA_QCFLAG_RTF_FILLED in fill_result_tf()
+    - Revert "libfs: fix infinite directory reads for offset dir"
+    - libfs: Replace simple_offset end-of-directory detection
+    - Revert "HID: multitouch: Add support for lenovo Y9000P Touchpad"
+    - ALSA: usb-audio: Add delay quirk for USB Audio Device
+    - Input: xpad - add support for Nacon Pro Compact
+    - Input: atkbd - map F23 key to support default copilot shortcut
+    - Input: xpad - add unofficial Xbox 360 wireless receiver clone
+    - Input: xpad - add QH Electronics VID/PID
+    - Input: xpad - improve name of 8BitDo controller 2dc8:3106
+    - Input: xpad - add support for Nacon Evol-X Xbox One Controller
+    - Input: xpad - add support for wooting two he (arm)
+    - ASoC: codecs: es8316: Fix HW rate calculation for 48Mhz MCLK
+    - ASoC: cs42l43: Add codec force suspend/resume ops
+    - ALSA: hda/realtek: Fix volume adjustment issue on Lenovo ThinkBook 16P Gen5
+    - libfs: Return ENOSPC when the directory offset range is exhausted
+    - Revert "libfs: Add simple_offset_empty()"
+    - libfs: Use d_children list to iterate simple_offset directories
+    - wifi: rtl8xxxu: add more missing rtl8192cu USB IDs
+    - HID: wacom: Initialize brightness of LED trigger
+    - Upstream stable to v6.6.75, v6.12.12
+
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21689
+    - USB: serial: quatech2: fix null-ptr-deref in qt2_process_read_urb()
+
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21690
+    - scsi: storvsc: Ratelimit warning logs to prevent VM denial of service
+
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21691
+    - cachestat: fix page cache statistics permission checking
+
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21692
+    - net: sched: fix ets qdisc OOB Indexing
+
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21699
+    - gfs2: Truncate address space when flipping GFS2_DIF_JDATA flag
+
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2024-50157
+    - RDMA/bnxt_re: Avoid CPU lockups due fifo occupancy check loop
+
+  * rtw89: Support hardware rfkill (LP: #2077384)
+    - wifi: rtw89: add support for hardware rfkill
+
+  * Introduce configfs-based interface for gpio-aggregator (LP: #2103496)
+    - gpio: introduce utilities for synchronous fake device creation
+    - bitmap: Define a cleanup function for bitmaps
+    - gpio: aggregator: simplify aggr_parse() with scoped bitmap
+    - gpio: aggregator: protect driver attr handlers against module unload
+    - gpio: aggregator: reorder functions to prepare for configfs introduction
+    - gpio: aggregator: unify function naming
+    - gpio: aggregator: add gpio_aggregator_{alloc, free}()
+    - gpio: aggregator: introduce basic configfs interface
+    - [Config] Enable DEV_SYNC_PROBE as module
+    - SAUCE: gpio: aggregator: Fix error code in gpio_aggregator_activate()
+    - gpio: aggregator: rename 'name' to 'key' in gpio_aggregator_parse()
+    - gpio: aggregator: expose aggregator created via legacy sysfs to configfs
+    - SAUCE: gpio: aggregator: fix "_sysfs" prefix check in
+      gpio_aggregator_make_group()
+    - SAUCE: gpio: aggregator: Fix gpio_aggregator_line_alloc() checking
+    - SAUCE: gpio: aggregator: Return an error if there are no GPIOs in
+      gpio_aggregator_parse()
+    - SAUCE: gpio: aggregator: Fix leak in gpio_aggregator_parse()
+    - gpio: aggregator: cancel deferred probe for devices created via configfs
+    - Documentation: gpio: document configfs interface for gpio-aggregator
+    - selftests: gpio: add test cases for gpio-aggregator
+    - SAUCE: selftests: gpio: gpio-aggregator: add a test case for _sysfs prefix
+      reservation
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449)
+    - net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()
+    - net: add exit_batch_rtnl() method
+    - gtp: use exit_batch_rtnl() method
+    - gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp().
+    - gtp: Suppress list corruption splat in gtp_net_exit_batch_rtnl().
+    - nfp: bpf: prevent integer overflow in nfp_bpf_event_output()
+    - net: xilinx: axienet: Fix IRQ coalescing packet count overflow
+    - net/mlx5: Fix RDMA TX steering prio
+    - net/mlx5e: Rely on reqid in IPsec tunnel mode
+    - net/mlx5e: Always start IPsec sequence number from 1
+    - drm/vmwgfx: Add new keep_resv BO param
+    - drm/v3d: Assign job pointer to NULL before signaling the fence
+    - soc: ti: pruss: Fix pruss APIs
+    - hwmon: (tmp513) Fix division of negative numbers
+    - i2c: mux: demux-pinctrl: check initial mux selection, too
+    - i2c: rcar: fix NACK handling when being a target
+    - hfs: Sanity check the root record
+    - fs: fix missing declaration of init_files
+    - kheaders: Ignore silly-rename files
+    - cachefiles: Parse the "secctx" immediately
+    - scsi: ufs: core: Honor runtime/system PM levels if set by host controller
+      drivers
+    - selftests: tc-testing: reduce rshift value
+    - ACPI: resource: acpi_dev_irq_override(): Check DMI match last
+    - poll_wait: add mb() to fix theoretical race between waitqueue_active() and
+      .poll()
+    - RDMA/bnxt_re: Fix to export port num to ib_query_qp
+    - nvmet: propagate npwg topology
+    - ALSA: hda/realtek: Add support for Ayaneo System using CS35L41 HDA
+    - i2c: atr: Fix client detach
+    - mptcp: be sure to send ack when mptcp-level window re-opens
+    - mptcp: fix spurious wake-up on under memory pressure
+    - selftests: mptcp: avoid spurious errors on disconnect
+    - net: ethernet: xgbe: re-add aneg to supported features in PHY quirks
+    - vsock/virtio: cancel close work in the destructor
+    - vsock: reset socket state when de-assigning the transport
+    - nouveau/fence: handle cross device fences properly
+    - irqchip: Plug a OF node reference leak in platform_irqchip_probe()
+    - irqchip/gic-v3: Handle CPU_PM_ENTER_FAILED correctly
+    - drm/i915/fb: Relax clear color alignment to 64 bytes
+    - drm/amdgpu: always sync the GFX pipe on ctx switch
+    - ocfs2: fix deadlock in ocfs2_get_system_file_inode
+    - nfsd: add list_head nf_gc to struct nfsd_file
+    - x86/xen: fix SLS mitigation in xen_hypercall_iret()
+    - efi/zboot: Limit compression options to GZIP and ZSTD
+    - [Config] updateconfigs for HAVE_KERNEL_(LZ4|LZMA|LZO|XZ)
+    - net: ravb: Fix max TX frame size for RZ/V2M
+    - net/mlx5: SF, Fix add port error handling
+    - drm/vmwgfx: Unreserve BO on error
+    - i2c: testunit: on errors, repeat NACK until STOP
+    - hwmon: (ltc2991) Fix mixed signed/unsigned in DIV_ROUND_CLOSEST
+    - fs/qnx6: Fix building with GCC 15
+    - gpio: sim: lock up configfs that an instantiated device depends on
+    - gpio: sim: lock hog configfs items if present
+    - platform/x86: ISST: Add Clearwater Forest to support list
+    - drm/nouveau/disp: Fix missing backlight control on Macbook 5,1
+    - net/ncsi: fix locking in Get MAC Address handling
+    - drm/amd/display: Do not elevate mem_type change to full update
+    - drm/xe: Mark ComputeCS read mode as UC on iGPU
+    - drm/amdgpu/smu13: update powersave optimizations
+    - drm/amdgpu: fix fw attestation for MP0_14_0_{2/3}
+    - drm/amdgpu: disable gfxoff with the compute workload on gfx12
+    - drm/amd/display: Fix PSR-SU not support but still call the
+      amdgpu_dm_psr_enable
+    - Upstream stable to v6.6.73, v6.6.74, v6.12.11
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21672
+    - afs: Fix merge preference rule failure condition
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21682
+    - eth: bnxt: always recalculate features after XDP clearing, fix null-deref
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-53124
+    - net: fix data-races around sk->sk_forward_alloc
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-57924
+    - fs: relax assertions on failure to encode file handles
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-57951
+    - hrtimers: Handle CPU state correctly on hotplug
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-57949
+    - irqchip/gic-v3-its: Don't enable interrupts in its_irq_set_vcpu_affinity()
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21668
+    - pmdomain: imx8mp-blk-ctrl: add missing loop break condition
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21684
+    - gpio: xilinx: Convert gpio_lock to raw spinlock
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21694
+    - fs/proc: fix softlockup in __read_vmcore (part 2)
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21665
+    - filemap: avoid truncating 64-bit offset to 32 bits
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21666
+    - vsock: prevent null-ptr-deref in vsock_*[has_data|has_space]
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21669
+    - vsock/virtio: discard packets if the transport changes
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21670
+    - vsock/bpf: return early if transport is not assigned
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21667
+    - iomap: avoid avoid truncating 64-bit offset to 32 bits
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-57948
+    - mac802154: check local interfaces before deleting sdata list
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21673
+    - smb: client: fix double free of TCP_Server_Info::hostname
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21697
+    - drm/v3d: Ensure job pointer is set to NULL after job completion
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21674
+    - net/mlx5e: Fix inversion dependency warning while enabling IPsec tunnel
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21675
+    - net/mlx5: Clear port select structure when fail to create
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21676
+    - net: fec: handle page_pool_dev_alloc_pages error
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21678
+    - gtp: Destroy device along with udp socket's netns dismantle.
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21680
+    - pktgen: Avoid out-of-bounds access in get_imix_entries
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21681
+    - openvswitch: fix lockup on tx to unregistering netdev with carrier
+
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21683
+    - bpf: Fix bpf_sk_select_reuseport() memory leak
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update annotations scripts
+
+ -- Stefan Bader <stefan.bader@canonical.com>  Mon, 19 May 2025 12:55:33 +0200
+
+linux (6.8.0-60.63) noble; urgency=medium
+
+  * noble/linux: 6.8.0-60.63 -proposed tracker (LP: #2107138)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2025.04.14)
+
+  * Missing upstream commits for LP: #2102181 (LP: #2107336)
+    - libperf cpumap: Add any, empty and min helpers
+    - libperf cpumap: Ensure empty cpumap is NULL from alloc
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770)
+    - memblock: use numa_valid_node() helper to check for invalid node ID
+    - jbd2: increase IO priority for writing revoke records
+    - jbd2: flush filesystem device before updating tail sequence
+    - dm array: fix unreleased btree blocks on closing a faulty array cursor
+    - dm array: fix cursor index when skipping across block boundaries
+    - exfat: fix the infinite loop in __exfat_free_cluster()
+    - erofs: fix PSI memstall accounting
+    - ASoC: rt722: add delay time to wait for the calibration procedure
+    - ASoC: mediatek: disable buffer pre-allocation
+    - selftests/alsa: Fix circular dependency involving global-timer
+    - ieee802154: ca8210: Add missing check for kfifo_alloc() in ca8210_probe()
+    - net: 802: LLC+SNAP OID:PID lookup on start of skb data
+    - tcp/dccp: complete lockless accesses to sk->sk_max_ack_backlog
+    - tcp/dccp: allow a connection when sk_max_ack_backlog is zero
+    - net: libwx: fix firmware mailbox abnormal return
+    - pds_core: limit loop over fw name list
+    - bnxt_en: Fix possible memory leak when hwrm_req_replace fails
+    - cxgb4: Avoid removal of uninserted tid
+    - ice: fix incorrect PHY settings for 100 GB/s
+    - igc: return early when failing to read EECD register
+    - tls: Fix tls_sw_sendmsg error handling
+    - eth: gve: use appropriate helper to set xdp_features
+    - Bluetooth: hci_sync: Fix not setting Random Address when required
+    - Bluetooth: MGMT: Fix Add Device to responding before completing
+    - Bluetooth: btnxpuart: Fix driver sending truncated data
+    - tcp: Annotate data-race around sk->sk_mark in tcp_v4_send_reset
+    - riscv: Fix early ftrace nop patching
+    - memblock tests: fix implicit declaration of function 'numa_valid_node'
+    - iio: imu: inv_icm42600: fix timestamps after suspend if sensor is on
+    - netfilter: nf_tables: imbalance in flowtable binding
+    - drm/mediatek: stop selecting foreign drivers
+    - [Config] updateconfigs for MTK_SMI
+    - drm/mediatek: Fix YCbCr422 color format issue for DP
+    - drm/mediatek: Fix mode valid issue for dp
+    - drm/mediatek: Add return value check when reading DPCD
+    - cpuidle: riscv-sbi: fix device node release in early exit of
+      for_each_possible_cpu
+    - scsi: ufs: qcom: Power off the PHY if it was already powered on in
+      ufs_qcom_power_up_sequence()
+    - dm-ebs: don't set the flag DM_TARGET_PASSES_INTEGRITY
+    - ksmbd: Implement new SMB3 POSIX type
+    - thermal: of: fix OF node leak in of_thermal_zone_find()
+    - smb: client: sync the root session and superblock context passwords before
+      automounting
+    - ACPI: resource: Add TongFang GM5HG0A to irq1_edge_low_force_override[]
+    - ACPI: resource: Add Asus Vivobook X1504VAP to irq1_level_low_skip_override[]
+    - drm/amd/display: increase MAX_SURFACES to the value supported by hw
+    - io_uring/timeout: fix multishot updates
+    - dm-verity FEC: Fix RS FEC repair for roots unaligned to block size (take 2)
+    - USB: serial: option: add MeiG Smart SRM815
+    - USB: serial: option: add Neoway N723-EA support
+    - staging: iio: ad9834: Correct phase range check
+    - staging: iio: ad9832: Correct phase range check
+    - usb-storage: Add max sectors quirk for Nokia 208
+    - USB: serial: cp210x: add Phoenix Contact UPS Device
+    - usb: dwc3: gadget: fix writing NYET threshold
+    - misc: microchip: pci1xxxx: Resolve return code mismatch during GPIO set
+      config
+    - tty: serial: 8250: Fix another runtime PM usage counter underflow
+    - usb: dwc3-am62: Disable autosuspend during remove
+    - USB: usblp: return error when setting unsupported protocol
+    - USB: core: Disable LPM only for non-suspended ports
+    - usb: fix reference leak in usb_new_device()
+    - usb: gadget: midi2: Reverse-select at the right place
+    - usb: chipidea: ci_hdrc_imx: decrement device's refcount in .remove() and in
+      the error path of .probe()
+    - usb: gadget: f_uac2: Fix incorrect setting of bNumEndpoints
+    - usb: typec: tcpm/tcpci_maxim: fix error code in
+      max_contaminant_read_resistance_kohm()
+    - usb: gadget: configfs: Ignore trailing LF for user strings to cdev
+    - iio: gyro: fxas21002c: Fix missing data update in trigger handler
+    - iio: adc: ti-ads124s08: Use gpiod_set_value_cansleep()
+    - iio: inkern: call iio_device_put() only on mapped devices
+    - iio: adc: ad7124: Disable all channels at probe time
+    - riscv: kprobes: Fix incorrect address calculation
+    - ARM: dts: imxrt1050: Fix clocks for mmc
+    - arm64: dts: rockchip: add hevc power domain clock to rk3328
+    - pmdomain: imx: gpcv2: Simplify with scoped for each OF child loop
+    - pmdomain: imx: gpcv2: fix an OF node reference leak in imx_gpcv2_probe()
+    - workqueue: Add rcu lock check at the end of work item execution
+    - workqueue: Update lock debugging code
+    - mm/hugetlb: enforce that PMD PT sharing has split PMD PT locks
+    - riscv: Fix text patching when IPI are used
+    - drm/mediatek: Only touch DISP_REG_OVL_PITCH_MSB if AFBC is supported
+    - ovl: pass realinode to ovl_encode_real_fh() instead of realdentry
+    - net: don't dump Tx and uninitialized NAPIs
+    - ice: fix max values for dpll pin phase adjust
+    - net: hns3: fixed reset failure issues caused by the incorrect reset type
+    - net: hns3: fix missing features due to dev->features configuration too early
+    - net: hns3: Resolved the issue that the debugfs query result is inconsistent.
+    - net: hns3: initialize reset_timer before hclgevf_misc_irq_init()
+    - mctp i3c: fix MCTP I3C driver multi-thread issue
+    - drm/mediatek: Move mtk_crtc_finish_page_flip() to ddp_cmdq_cb()
+    - drm/mediatek: Add support for 180-degree rotation in the display driver
+    - drm/mediatek: mtk_dsi: Add registers to pdata to fix MT8186/MT8188
+    - platform/x86: intel/pmc: Fix ioremap() of bad address
+    - riscv: module: remove relocation_head rel_entry member allocation
+    - cgroup/cpuset: Prevent leakage of isolated CPUs into sched domains
+    - fs: kill MNT_ONRB
+    - gpio: loongson: Fix Loongson-2K2000 ACPI GPIO register offset
+    - drm/amd/pm: fix BUG: scheduling while atomic
+    - drm/amdkfd: wq_release signals dma_fence only when available
+    - drm/amd/display: fix divide error in DM plane scale calcs
+    - drm/amd/display: fix page fault due to max surface definition mismatch
+    - serial: stm32: use port lock wrappers for break control
+    - usb: host: xhci-plat: set skip_phy_initialization if software node has
+      XHCI_SKIP_PHY_INIT property
+    - iio: imu: inv_icm42600: add register caching in the regmap
+    - iio: imu: inv_icm42600: fix spi burst write not supported
+    - Upstream stable to v6.6.71, v6.6.72, v6.12.10
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21659
+    - netdev: prevent accessing NAPI instances from another namespace
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21634
+    - cgroup/cpuset: remove kernfs active break
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21635
+    - rds: sysctl: rds_tcp_{rcv,snd}buf: avoid using current->nsproxy
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21643
+    - netfs: Fix kernel async DIO
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21649
+    - net: hns3: fix kernel crash when 1588 is sent on HIP08 devices
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21650
+    - net: hns3: fixed hclge_fetch_pf_reg accesses bar space out of bounds issue
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21651
+    - net: hns3: don't auto enable misc vector
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21654
+    - ovl: support encoding fid from inode with no alias
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57883
+    - mm: hugetlb: independent PMD page table shared count
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57888
+    - workqueue: Do not warn when cancelling WQ_MEM_RECLAIM work from
+      !WQ_MEM_RECLAIM worker
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21631
+    - block, bfq: fix waker_bfqq UAF after bfq_split_bfqq()
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21656
+    - hwmon: (drivetemp) Fix driver producing garbage data when SCSI errors occur
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21655
+    - io_uring/eventfd: ensure io_eventfd_signal() defers another RCU period
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57904
+    - iio: adc: at91: call input_free_device() on allocated iio_dev
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57906
+    - iio: adc: ti-ads8688: fix information leak in triggered buffer
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57907
+    - iio: adc: rockchip_saradc: fix information leak in triggered buffer
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57908
+    - iio: imu: kmx61: fix information leak in triggered buffer
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57910
+    - iio: light: vcnl4035: fix information leak in triggered buffer
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57911
+    - iio: dummy: iio_simply_dummy_buffer: fix information leak in triggered
+      buffer
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57912
+    - iio: pressure: zpa2326: fix information leak in triggered buffer
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57913
+    - usb: gadget: f_fs: Remove WARN_ON in functionfs_bind
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21632
+    - x86/fpu: Ensure shadow stack is active before "getting" registers
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57916
+    - misc: microchip: pci1xxxx: Resolve kernel panic during GPIO IRQ handling
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57917
+    - topology: Keep the cpumask unchanged when printing cpumap
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57939
+    - riscv: Fix sleeping in invalid context in die()
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21636
+    - sctp: sysctl: plpmtud_probe_interval: avoid using current->nsproxy
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21637
+    - sctp: sysctl: udp_port: avoid using current->nsproxy
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21638
+    - sctp: sysctl: auth_enable: avoid using current->nsproxy
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21639
+    - sctp: sysctl: rto_min/max: avoid using current->nsproxy
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21640
+    - sctp: sysctl: cookie_hmac_alg: avoid using current->nsproxy
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21642
+    - mptcp: sysctl: sched: avoid using current->nsproxy
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21664
+    - dm thin: make get_first_thin use rcu-safe list first function
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57945
+    - riscv: mm: Fix the out of bound issue of vmemmap address
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21660
+    - ksmbd: fix unexpectedly changed path in ksmbd_vfs_kern_path_locked
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21645
+    - platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled
+      it
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21646
+    - afs: Fix the maximum cell name length
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57925
+    - ksmbd: fix a missing return value check bug
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57926
+    - drm/mediatek: Set private->all_drm_private[i]->drm to NULL if mtk_drm_bind
+      returns err
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21662
+    - net/mlx5: Fix variable not being completed when function returns
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21663
+    - net: stmmac: dwmac-tegra: Read iommu stream id from device tree
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21647
+    - sched: sch_cake: add bounds checks to host bulk flow fairness counts
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21648
+    - netfilter: conntrack: clamp maximum hashtable size to INT_MAX
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21652
+    - ipvlan: Fix use-after-free in ipvlan_get_iflink().
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21658
+    - btrfs: avoid NULL pointer dereference if no valid extent tree
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21653
+    - net_sched: cls_flow: validate TCA_FLOW_RSHIFT attribute
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-47736
+    - erofs: handle overlapped pclusters out of crafted images properly
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57940
+    - exfat: fix the infinite loop in exfat_readdir()
+
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57929
+    - dm array: fix releasing a faulty array block twice in dm_array_cursor_end
+
+  * intel_idle: add Granite Rapids Xeon (D) support (LP: #2106638)
+    - intel_idle: add Granite Rapids Xeon support
+    - intel_idle: add Granite Rapids Xeon D support
+
+  * [SRU] Enable speaker/mic mute LEDs on Lenovo ideapad and thinkbook
+    (LP: #2106449)
+    - ALSA: hda: Support for Ideapad hotkey mute LEDs
+    - platform/x86:lenovo-wmi-hotkey-utilities.c: Support for mic and audio mute
+      LEDs
+    - [Config] Enable Lenovo wmi hotkey driver
+
+  * Backport "PCI: Wait for device readiness with Configuration RRS" to N/O
+    (LP: #2106251)
+    - PCI: Wait for device readiness with Configuration RRS
+    - PCI: Avoid FLR for Mediatek MT7922 WiFi
+
+  * Enable OOB P-state control for Intel Sierra Forest/Granite Rapids
+    (LP: #2106275)
+    - cpufreq: intel_pstate: Support Granite Rapids and Sierra Forest OOB mode
+
+  * mptcp BUG 'scheduling while atomic' in mptcp_pm_nl_append_new_local_addr
+    (LP: #2101120)
+    - mptcp: fix 'scheduling while atomic' in mptcp_pm_nl_append_new_local_addr
+
+  * CVE-2025-21971
+    - net_sched: Prevent creation of classes with TC_H_ROOT
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632)
+    - smb/client: rename cifs_ntsd to smb_ntsd
+    - smb/client: rename cifs_sid to smb_sid
+    - smb/client: rename cifs_acl to smb_acl
+    - smb/client: rename cifs_ace to smb_ace
+    - fs/smb/client: implement chmod() for SMB3 POSIX Extensions
+    - smb: client: stop flooding dmesg in smb2_calc_signature()
+    - media: uvcvideo: Force UVC version to 1.0a for 0408:4033
+    - Bluetooth: btusb: Add new VID/PID 13d3/3602 for MT7925
+    - watchdog: rzg2l_wdt: Remove reset de-assert from probe
+    - watchdog: rzg2l_wdt: Rely on the reset driver for doing proper reset
+    - watchdog: rzg2l_wdt: Power on the watchdog domain in the restart handler
+    - ALSA: ump: Use guard() for locking
+    - ALSA: ump: Don't open legacy substream for an inactive group
+    - scsi: mpi3mr: Use ida to manage mrioc ID
+    - scsi: mpi3mr: Start controller indexing from 0
+    - ACPI/IORT: Add PMCG platform information for HiSilicon HIP10/11
+    - ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A
+    - x86/ptrace: Cleanup the definition of the pt_regs structure
+    - x86/ptrace: Add FRED additional information to the pt_regs structure
+    - Bluetooth: btusb: add callback function in btusb suspend/resume
+    - Bluetooth: btusb: mediatek: add callback function in btusb_disconnect
+    - platform/x86: mlx-platform: call pci_dev_put() to balance the refcount
+    - mmc: sdhci-msm: fix crypto key eviction
+    - tracing: Handle old buffer mappings for event strings and functions
+    - tracing: Fix trace_check_vprintf() when tp_printk is used
+    - tracing: Check "%s" dereference via the field and not the TP_printk format
+    - RDMA/bnxt_re: Allow MSN table capability check
+    - RDMA/bnxt_re: Remove always true dattr validity check
+    - RDMA/mlx5: Enforce same type port association for multiport RoCE
+    - RDMA/bnxt_re: Avoid initializing the software queue for user queues
+    - RDMA/bnxt_re: Avoid sending the modify QP workaround for latest adapters
+    - nvme-pci: 512 byte aligned dma pool segment quirk
+    - RDMA/bnxt_re: Fix the check for 9060 condition
+    - RDMA/bnxt_re: Add check for path mtu in modify_qp
+    - RDMA/bnxt_re: Fix reporting hw_ver in query_device
+    - RDMA/bnxt_re: Fix max_qp_wrs reported
+    - RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters
+    - RDMA/bnxt_re: Disable use of reserved wqes
+    - RDMA/bnxt_re: Add send queue size check for variable wqe
+    - RDMA/bnxt_re: Fix MSN table size for variable wqe mode
+    - drm/bridge: adv7511_audio: Update Audio InfoFrame properly
+    - net: dsa: microchip: Fix KSZ9477 set_ageing_time function
+    - net: dsa: microchip: Fix LAN937X set_ageing_time function
+    - RDMA/hns: Refactor mtr find
+    - RDMA/hns: Remove unused parameters and variables
+    - RDMA/hns: Fix mapping error of zero-hop WQE buffer
+    - RDMA/hns: Fix warning storm caused by invalid input in IO path
+    - RDMA/hns: Fix missing flush CQE for DWQE
+    - ip_tunnel: annotate data-races around t->parms.link
+    - ipv4: ip_tunnel: Unmask upper DSCP bits in ip_tunnel_bind_dev()
+    - ipv4: ip_tunnel: Unmask upper DSCP bits in ip_md_tunnel_xmit()
+    - ipv4: ip_tunnel: Unmask upper DSCP bits in ip_tunnel_xmit()
+    - net: Fix netns for ip_tunnel_init_flow()
+    - net/mlx5: DR, select MSIX vector 0 for completion queue creation
+    - net/mlx5e: macsec: Maintain TX SA from encoding_sa
+    - drm/i915/dg1: Fix power gate sequence.
+    - net: llc: reset skb->transport_header
+    - ALSA: usb-audio: US16x08: Initialize array before use
+    - eth: bcmsysport: fix call balance of priv->clk handling routines
+    - net: mv643xx_eth: fix an OF node reference leak
+    - net: sfc: Correct key_len for efx_tc_ct_zone_ht_params
+    - net: wwan: iosm: Properly check for valid exec stage in ipc_mmio_init()
+    - net: ti: icssg-prueth: Fix clearing of IEP_CMP_CFG registers during iep_init
+    - wifi: mac80211: wake the queues in case of failure in resume
+    - ALSA: hda/ca0132: Use standard HD-audio quirk matching helpers
+    - ALSA: hda/realtek: Add new alc2xx-fixup-headset-mic model
+    - sound: usb: enable DSD output for ddHiFi TC44C
+    - sound: usb: format: don't warn that raw DSD is unsupported
+    - bpf: fix potential error return
+    - ksmbd: retry iterate_dir in smb2_query_dir
+    - smb: client: destroy cfid_put_wq on module exit
+    - net: usb: qmi_wwan: add Telit FE910C04 compositions
+    - irqchip/gic: Correct declaration of *percpu_base pointer in union gic_base
+    - ARC: build: Try to guess GCC variant of cross compiler
+    - RDMA/bnxt_re: Fix the max WQE size for static WQE support
+    - modpost: fix input MODULE_DEVICE_TABLE() built for 64-bit on 32-bit host
+    - modpost: fix the missed iteration for the max bit in do_input()
+    - ALSA: seq: Check UMP support for midi_version change
+    - ALSA hda/realtek: Add quirk for Framework F111:000C
+    - kcov: mark in_softirq_really() as __always_inline
+    - scripts/sorttable: fix orc_sort_cmp() to maintain symmetry and transitivity
+    - sky2: Add device ID 11ab:4373 for Marvell 88E8075
+    - drm: adv7511: Drop dsi single lane support
+    - dt-bindings: display: adi,adv7533: Drop single lane support
+    - fs/proc/task_mmu: fix pagemap flags with PMD THP entries on 32bit
+    - mm/readahead: fix large folio support in async readahead
+    - mptcp: fix recvbuffer adjust on sleeping rcvmsg
+    - mptcp: don't always assume copied data in mptcp_cleanup_rbuf()
+    - RDMA/bnxt_re: Fix max SGEs for the Work Request
+    - scsi: hisi_sas: Remove redundant checks for automatic debugfs dump
+    - platform/x86: hp-wmi: Add thermal profile support for 8BAD boards
+    - platform/x86: hp-wmi: Fix platform profile option switch bug on Omen and
+      Victus laptops
+    - platform/x86: hp-wmi: Fix implementation of the platform_profile_omen_get
+      function
+    - platform/x86: hp-wmi: mark 8A15 board for timed OMEN thermal profile
+    - RDMA/core: Fix ENODEV error for iWARP test over vlan
+    - net: phy: micrel: Dynamically control external clock of KSZ PHY
+    - netdev-genl: avoid empty messages in napi get
+    - net: stmmac: restructure the error path of stmmac_probe_config_dt()
+    - net/mlx5e: Fix netif state handling
+    - net/mlx5e: Keep netdev when leave switchdev for devlink set legacy only
+    - drm/i915/cx0_phy: Fix C10 pll programming sequence
+    - RDMA/bnxt_re: Fix error recovery sequence
+    - btrfs: allow swap activation to be interruptible
+    - perf/x86/intel: Add Arrow Lake U support
+    - ALSA: hda: cs35l56: Remove calls to
+      cs35l56_force_sync_asp1_registers_from_cache()
+    - ALSA: hda/realtek - Add support for ASUS Zen AIO 27 Z272SD_A272SD audio
+    - spi: spi-cadence-qspi: Disable STIG mode for Altera SoCFPGA.
+    - ARC: build: disallow invalid PAE40 + 4K page config
+    - bpf: refactor bpf_helper_changes_pkt_data to use helper number
+    - bpf: consider that tail calls invalidate packet pointers
+    - maple_tree: reload mas before the second call for mas_empty_area
+    - io_uring/rw: fix downgraded mshot read
+    - wifi: iwlwifi: mvm: Fix __counted_by usage in cfg80211_wowlan_nd_*
+    - net: ethernet: ti: am65-cpsw: default to round-robin for host port receive
+    - gve: process XSK TX descriptors as part of RX NAPI
+    - gve: trigger RX NAPI instead of TX NAPI in gve_xsk_wakeup
+    - mm: reinstate ability to map write-sealed memfd mappings read-only
+    - Upstream stable to v6.6.70, v6.12.9
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57898
+    - wifi: cfg80211: clear link ID from bitmap during link delete after clean up
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57882
+    - mptcp: fix TCP options overflow.
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57884
+    - mm: vmscan: account for free pages to prevent infinite Loop in
+      throttle_direct_reclaim()
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57885
+    - mm/kmemleak: fix sleeping function called from invalid context at print
+      message
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57932
+    - gve: guard XDP xmit NDO on existence of xdp queues
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57933
+    - gve: guard XSK operations on the existence of queues
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57887
+    - drm: adv7511: Fix use-after-free in adv7533_attach_dsi()
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57938
+    - net/sctp: Prevent autoclose integer overflow in sctp_association_init()
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57889
+    - pinctrl: mcp23s08: Fix sleeping in atomic context due to regmap locking
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57890
+    - RDMA/uverbs: Prevent integer overflow issue
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57892
+    - ocfs2: fix slab-use-after-free due to dangling pointer dqi_priv
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57893
+    - ALSA: seq: oss: Fix races at processing SysEx messages
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57895
+    - ksmbd: set ATTR_CTIME flags when setting mtime
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57896
+    - btrfs: flush delalloc workers queue before stopping cleaner kthread during
+      unmount
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57897
+    - drm/amdkfd: Correct the migration DMA map direction
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57899
+    - wifi: mac80211: fix mbss changed flags corruption on 32 bit systems
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57900
+    - ila: serialize calls to nf_register_net_hooks()
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57901
+    - af_packet: fix vlan_get_protocol_dgram() vs MSG_PEEK
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57902
+    - af_packet: fix vlan_get_tci() vs MSG_PEEK
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57903
+    - net: restrict SO_REUSEPORT to inet sockets
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-36476
+    - RDMA/rtrs: Ensure 'ib_sge list' is accessible
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-39282
+    - net: wwan: t7xx: Fix FSM command timeout issue
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57801
+    - net/mlx5e: Skip restore TC rules for vport rep without loaded flag
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57802
+    - netrom: check buffer length before accessing it
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57841
+    - net: fix memory leak in tcp_conn_request()
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57931
+    - selinux: ignore unknown extended permissions
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-56761
+    - x86/fred: Clear WFE in missing-ENDBRANCH #CPs
+
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-53179
+    - smb: client: fix use-after-free of signing key
+
+  * uprobe-related panics during profiling (LP: #2104210)
+    - uprobes: Fix race in uprobe_free_utask
+
+  * ubuntu_bpf failed to build on Noble / Oracular (LP: #2069407)
+    - selftests/bpf: Fix compilation failure when CONFIG_NET_FOU!=y
+
+  * nfsd hangs and never recovers after NFS4ERR_DELAY and a connection loss
+    (LP: #2103564)
+    - NFSD: Reset cb_seq_status after NFS4ERR_DELAY
+
+  * thermal: Fix temperature readings on intel hardware (LP: #2103427)
+    - thermal: intel: intel_tcc: Add model checks for temperature registers
+    - thermal: intel: intel_tcc_cooling: Use a model-specific bitmask for TCC
+      offset
+    - hwmon: (coretemp) Extend the bitmask to read temperature to 0xff
+
+  * [SRU] Fix Lenovo M70/90 gen6 micmute key and led (LP: #2101811)
+    - ALSA: hda/realtek - add supported Mic Mute LED for Lenovo platform
+    - ALSA: hda: realtek: fix incorrect IS_REACHABLE() usage
+
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869)
+    - ceph: allocate sparse_ext map only for sparse reads
+    - mm/vmstat: fix a W=1 clang compiler warning
+    - tcp_bpf: Charge receive socket buffer in bpf_tcp_ingress()
+    - tcp_bpf: Add sk_rmem_alloc related logic for tcp_bpf ingress redirection
+    - bpf: Check negative offsets in __bpf_skb_min_len()
+    - mtd: diskonchip: Cast an operand to prevent potential overflow
+    - mtd: rawnand: arasan: Fix double assertion of chip-select
+    - mtd: rawnand: arasan: Fix missing de-registration of NAND
+    - phy: qcom-qmp: Fix register name in RX Lane config of SC8280XP
+    - phy: core: Fix an OF node refcount leakage in _of_phy_get()
+    - phy: core: Fix an OF node refcount leakage in of_phy_provider_lookup()
+    - phy: core: Fix that API devm_phy_put() fails to release the phy
+    - phy: core: Fix that API devm_of_phy_provider_unregister() fails to
+      unregister the phy provider
+    - phy: core: Fix that API devm_phy_destroy() fails to destroy the phy
+    - phy: usb: Toggle the PHY power during init
+    - phy: rockchip: naneng-combphy: fix phy reset
+    - dmaengine: mv_xor: fix child node refcount handling in early exit
+    - dmaengine: dw: Select only supported masters for ACPI devices
+    - dmaengine: tegra: Return correct DMA status when paused
+    - dmaengine: fsl-edma: implement the cleanup path of fsl_edma3_attach_pd()
+    - dmaengine: apple-admac: Avoid accessing registers in probe
+    - stddef: make __struct_group() UAPI C++-friendly
+    - tracing/kprobe: Make trace_kprobe's module callback called after jump_label
+      update
+    - watchdog: it87_wdt: add PWRGD enable quirk for Qotom QCML04
+    - watchdog: mediatek: Add support for MT6735 TOPRGU/WDT
+    - scsi: qla1280: Fix hw revision numbering for ISP1020/1040
+    - udf: Skip parent dir link count update if corrupted
+    - ALSA: hda/conexant: fix Z60MR100 startup pop issue
+    - ALSA: sh: Use standard helper for buffer accesses
+    - smb: server: Fix building with GCC 15
+    - regmap: Use correct format specifier for logging range errors
+    - LoongArch: Fix reserving screen info memory for above-4G firmware
+    - LoongArch: BPF: Adjust the parameter of emit_jirl()
+    - platform/x86: asus-nb-wmi: Ignore unknown event 0xCF
+    - spi: intel: Add Panther Lake SPI controller support
+    - scsi: mpt3sas: Diag-Reset when Doorbell-In-Use bit is set during driver load
+      time
+    - scsi: storvsc: Do not flag MAINTENANCE_IN return of SRB_STATUS_DATA_OVERRUN
+      as an error
+    - spi: omap2-mcspi: Fix the IS_ERR() bug for devm_clk_get_optional_enabled()
+    - blk-mq: register cpuhp callback after hctx is added to xarray table
+    - blk-mq: move cpuhp callback registering out of q->sysfs_lock
+    - MIPS: Probe toolchain support of -msym32
+    - MIPS: mipsregs: Set proper ISA level for virt extensions
+    - freezer, sched: Report frozen tasks as 'D' instead of 'R'
+    - tracing: Constify string literal data member in struct trace_event_call
+    - io_uring/sqpoll: fix sqpoll error handling races
+    - i2c: microchip-core: actually use repeated sends
+    - i2c: imx: add imx7d compatible string for applying erratum ERR007805
+    - i2c: microchip-core: fix "ghost" detections
+    - btrfs: sysfs: fix direct super block member reads
+    - ALSA: sh: Fix wrong argument order for copy_from_iter()
+    - block: avoid to reuse `hctx` not removed from cpuhp callback list
+    - fork: avoid inappropriate uprobe access to invalid mm
+    - ASoC: SOF: Intel: hda-dai: Do not release the link DMA on STOP
+    - power: supply: bq24190: Fix BQ24296 Vbus regulator support
+    - udf: Verify inode link counts before performing rename
+    - ALSA: ump: Indicate the inactive group in legacy substream names
+    - ALSA: ump: Update legacy substream names upon FB info update
+    - scsi: mpi3mr: Synchronize access to ioctl data buffer
+    - scsi: mpi3mr: Handling of fault code for insufficient power
+    - objtool: Add bch2_trans_unlocked_error() to bcachefs noreturns
+    - dmaengine: loongson2-apb: Change GENMASK to GENMASK_ULL
+    - perf/x86/intel/ds: Add PEBS format 6
+    - btrfs: add and use helper to verify the calling task has locked the inode
+    - btrfs: fix race with memory mapped writes when activating swap file
+    - btrfs: fix swap file activation failure due to extents that used to be
+      shared
+    - ALSA: ump: Shut up truncated string warning
+    - Upstream stable to v6.6.69, v6.12.8
+
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56758
+    - btrfs: check folio mapping after unlock in relocate_one_folio()
+
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56759
+    - btrfs: fix use-after-free when COWing tree bock and tracing is enabled
+
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57806
+    - btrfs: fix transaction atomicity bug when enabling simple quotas
+
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57793
+    - virt: tdx-guest: Just leak decrypted memory on unrecoverable errors
+
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56764
+    - ublk: detach gendisk from ublk device if add_disk() fails
+
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57804
+    - scsi: mpi3mr: Fix corrupt config pages PHY state is switched in sysfs
+
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57792
+    - power: supply: gpio-charger: Fix set charge current limits
+
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56760
+    - PCI/MSI: Handle lack of irqdomain gracefully
+
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56763
+    - tracing: Prevent bad count for tracing_cpumask_write
+
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57946
+    - virtio-blk: don't keep queue frozen during system suspend
+
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57807
+    - scsi: megaraid_sas: Fix for a potential deadlock
+
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56767
+    - dmaengine: at_xdmac: avoid null_prt_deref in at_xdmac_prep_dma_memset
+
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56769
+    - media: dvb-frontends: dib3000mb: fix uninit-value in dib3000_write_reg
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266)
+    - usb: dwc2: gadget: Don't write invalid mapped sg entries into dma_desc with
+      iommu enabled
+    - PCI: vmd: Create domain symlink before pci_bus_add_devices()
+    - PCI: Add ACS quirk for Broadcom BCM5760X NIC
+    - usb: cdns3-ti: Add workaround for Errata i2409
+    - MIPS: Loongson64: DTS: Fix msi node for ls7a
+    - ASoC: Intel: sof_sdw: fix jack detection on ADL-N variant RVP
+    - ASoC: Intel: sof_sdw: add quirk for Dell SKU 0B8C
+    - usb: cdns3: Add quirk flag to enable suspend residency
+    - platform/x86: p2sb: Make p2sb_get_devfn() return void
+    - p2sb: Factor out p2sb_read_from_cache()
+    - p2sb: Introduce the global flag p2sb_hidden_by_bios
+    - p2sb: Move P2SB hide and unhide code to p2sb_scan_and_cache()
+    - p2sb: Do not scan and remove the P2SB device when it is unhidden
+    - i2c: pnx: Fix timeout in wait functions
+    - xfs: fix the contact address for the sysfs ABI documentation
+    - xfs: verify buffer, inode, and dquot items every tx commit
+    - xfs: use consistent uid/gid when grabbing dquots for inodes
+    - xfs: declare xfs_file.c symbols in xfs_file.h
+    - xfs: create a new helper to return a file's allocation unit
+    - xfs: Fix xfs_flush_unmap_range() range for RT
+    - xfs: Fix xfs_prepare_shift() range for RT
+    - xfs: convert comma to semicolon
+    - xfs: fix file_path handling in tracepoints
+    - xfs: remove unused parameter in macro XFS_DQUOT_LOGRES
+    - xfs: attr forks require attr, not attr2
+    - xfs: conditionally allow FS_XFLAG_REALTIME changes if S_DAX is set
+    - xfs: Fix the owner setting issue for rmap query in xfs fsmap
+    - xfs: use XFS_BUF_DADDR_NULL for daddrs in getfsmap code
+    - xfs: take m_growlock when running growfsrt
+    - xfs: reset rootdir extent size hint after growfsrt
+    - tools: hv: change permissions of NetworkManager configuration file
+    - cxl/pci: Fix potential bogus return value upon successful probing
+    - cxl/region: Fix region creation for greater than x2 switches
+    - net/smc: check sndbuf_space again after NOSPACE flag is set in smc_poll
+    - ionic: use ee->offset when returning sprom data
+    - net: renesas: rswitch: rework ts tags management
+    - net: hinic: Fix cleanup in create_rxqs/txqs()
+    - net: ethernet: bgmac-platform: fix an OF node reference leak
+    - ipvs: Fix clamp() of ip_vs_conn_tab on small memory systems
+    - netfilter: ipset: Fix for recursive locking warning
+    - selftests: openvswitch: fix tcpdump execution
+    - net: mdiobus: fix an OF node reference leak
+    - mmc: sdhci-tegra: Remove SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC quirk
+    - mmc: mtk-sd: disable wakeup in .remove() and in the error path of .probe()
+    - EDAC/amd64: Simplify ECC check on unified memory controllers
+    - chelsio/chtls: prevent potential integer overflow on 32bit
+    - i2c: riic: Always round-up when calculating bus period
+    - efivarfs: Fix error on non-existent file
+    - hexagon: Disable constant extender optimization for LLVM prior to 19.1.0
+    - USB: serial: option: add TCL IK512 MBIM & ECM
+    - USB: serial: option: add MeiG Smart SLM770A
+    - USB: serial: option: add Netprisma LCUK54 modules for WWAN Ready
+    - USB: serial: option: add MediaTek T7XX compositions
+    - USB: serial: option: add Telit FE910C04 rmnet compositions
+    - thunderbolt: Improve redrive mode handling
+    - drm/panel: novatek-nt35950: fix return value check in nt35950_probe()
+    - i915/guc: Reset engine utilization buffer before registration
+    - i915/guc: Ensure busyness counter increases motonically
+    - i915/guc: Accumulate active runtime on gt reset
+    - hwmon: (tmp513) Fix interpretation of values of Shunt Voltage and Limit
+      Registers
+    - hwmon: (tmp513) Fix Current Register value interpretation
+    - hwmon: (tmp513) Fix interpretation of values of Temperature Result and Limit
+      Registers
+    - zram: refuse to use zero sized block device as backing device
+    - zram: fix uninitialized ZRAM not releasing backing device
+    - zram: fix potential UAF of zram table
+    - vmalloc: fix accounting with i915
+    - btrfs: tree-checker: reject inline extent items with 0 ref count
+    - smb: client: fix TCP timers deadlock after rmmod
+    - tracing: Fix test_event_printk() to process entire print argument
+    - tracing: Add missing helper functions in event pointer dereference check
+    - tracing: Add "%s" check in test_event_printk()
+    - tracing: Have process_string() also allow arrays
+    - selftests/memfd: run sysctl tests when PID namespace support is enabled
+    - selftests/bpf: Use asm constraint "m" for LoongArch
+    - io_uring: Fix registered ring file refcount leak
+    - NFS/pnfs: Fix a live lock between recalled layouts and layoutget
+    - of/irq: Fix interrupt-map cell length check in of_irq_parse_imap_parent()
+    - of/irq: Fix using uninitialized variable @addr_len in API of_irq_parse_one()
+    - nilfs2: fix buffer head leaks in calls to truncate_inode_pages()
+    - udmabuf: also check for F_SEAL_FUTURE_WRITE
+    - of: Fix error path in of_parse_phandle_with_args_map()
+    - of: Fix refcount leakage for OF node returned by __of_get_dma_parent()
+    - ceph: validate snapdirname option length when mounting
+    - ceph: improve error handling and short/overflow-read logic in
+      __ceph_sync_read()
+    - ceph: fix memory leaks in __ceph_sync_read()
+    - epoll: Add synchronous wakeup support for ep_poll_callback
+    - io_uring/rw: avoid punting to io-wq directly
+    - drm/amdgpu: Handle NULL bo->tbo.resource (again) in amdgpu_vm_bo_update
+    - xfs: sb_spino_align is not verified
+    - xfs: fix sparse inode limits on runt AG
+    - xfs: fix sb_spino_align checks for large fsblock sizes
+    - xfs: fix zero byte checking in the superblock scrubber
+    - netdev: fix repeated netlink messages in queue dump
+    - team: Fix feature exposure when no ports are present
+    - can: m_can: fix missed interrupts with m_can_pci
+    - netdev-genl: avoid empty messages in queue dump
+    - KVM: arm64: Do not allow ID_AA64MMFR0_EL1.ASIDbits to be overridden
+    - KVM: arm64: Fix set_id_regs selftest for ASIDBITS becoming unwritable
+    - net: mctp: handle skb cleanup on sock_queue failures
+    - xhci: retry Stop Endpoint on buggy NEC controllers
+    - usb: xhci: Limit Stop Endpoint retries
+    - usb: xhci: Avoid queuing redundant Stop Endpoint commands
+    - xhci: Turn NEC specific quirk for handling Stop Endpoint errors generic
+    - thunderbolt: Add support for Intel Panther Lake-M/P
+    - thunderbolt: Don't display nvm_version unless upgrade supported
+    - drm/panel: st7701: Add prepare_prev_first flag to drm_panel
+    - drm/panel: synaptics-r63353: Fix regulator unbalance
+    - drm/amdgpu/nbio7.11: fix IP version check
+    - drm/amdgpu/nbio7.7: fix IP version check
+    - fgraph: Still initialize idle shadow stacks when starting
+    - x86/hyperv: Fix hv tsc page based sched_clock for hibernation
+    - ocfs2: fix the space leak in LA when releasing LA
+    - of: property: fw_devlink: Do not use interrupt-parent directly
+    - of: address: Preserve the flags portion on 1:1 dma-ranges mapping
+    - Upstream stable to v6.6.68, v6.12.7
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56710
+    - ceph: fix memory leak in ceph_direct_read_write()
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-53685
+    - ceph: give up on paths longer than PATH_MAX
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-54193
+    - accel/ivpu: Fix WARN in ivpu_ipc_send_receive_internal()
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-54455
+    - accel/ivpu: Fix general protection fault in ivpu_bo_list()
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-53690
+    - nilfs2: prevent use of deleted inode
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56709
+    - io_uring: check if iowq is killed before queuing
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-55881
+    - KVM: x86: Play nice with protected guests in complete_hypercall_exit()
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-55916
+    - Drivers: hv: util: Avoid accessing a ringbuffer not initialized yet
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56369
+    - drm/modes: Avoid divide by zero harder in drm_mode_vrefresh()
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56372
+    - net: tun: fix tun_napi_alloc_frags()
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56715
+    - ionic: Fix netdev notifier unregister on failure
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56716
+    - netdevsim: prevent bad user input in nsim_dev_health_break_write()
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56717
+    - net: mscc: ocelot: fix incorrect IFH SRC_PORT field in
+      ocelot_ifh_set_basic()
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-57791
+    - net/smc: check return value of sock_recvmsg when draining clc data
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-47408
+    - net/smc: check smcd_v2_ext_offset when receiving proposal msg
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-49568
+    - net/smc: check v2_ext_offset/eid_cnt/ism_gid_cnt when receiving proposal msg
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-49571
+    - net/smc: check iparea_offset and ipv6_prefixes_cnt when receiving proposal
+      msg
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56718
+    - net/smc: protect link down work from execute after lgr freed
+
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-41013
+    - xfs: don't walk off the end of a directory data block
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181)
+    - perf/x86/intel/ds: Unconditionally drain PEBS DS when changing PEBS_DATA_CFG
+    - ksmbd: fix racy issue from session lookup and expire
+    - splice: do not checksum AF_UNIX sockets
+    - tcp: check space before adding MPTCP SYN options
+    - ALSA: usb-audio: Add implicit feedback quirk for Yamaha THR5
+    - usb: host: max3421-hcd: Correctly abort a USB request.
+    - ata: sata_highbank: fix OF node reference leak in highbank_initialize_phys()
+    - usb: dwc2: Fix HCD resume
+    - usb: dwc2: hcd: Fix GetPortStatus & SetPortFeature
+    - usb: dwc2: Fix HCD port connection race
+    - scsi: ufs: core: Update compl_time_stamp_local_clock after completing a cqe
+    - usb: gadget: midi2: Fix interpretation of is_midi1 bits
+    - usb: ehci-hcd: fix call balance of clocks handling routines
+    - usb: typec: anx7411: fix fwnode_handle reference leak
+    - usb: typec: anx7411: fix OF node reference leaks in
+      anx7411_typec_switch_probe()
+    - usb: dwc3: xilinx: make sure pipe clock is deselected in usb2 only mode
+    - drm/i915: Fix memory leak by correcting cache object name in error handler
+    - xfs: update btree keys correctly when _insrec splits an inode root block
+    - xfs: don't drop errno values when we fail to ficlone the entire range
+    - xfs: return from xfs_symlink_verify early on V4 filesystems
+    - xfs: fix scrub tracepoints when inode-rooted btrees are involved
+    - xfs: only run precommits once per transaction object
+    - bpf: Check size for BTF-based ctx access of pointer members
+    - bpf: Fix theoretical prog_array UAF in __uprobe_perf_func()
+    - bpf,perf: Fix invalid prog_array access in perf_event_detach_bpf_prog
+    - bpf, sockmap: Fix update element with same
+    - wifi: mac80211: init cnt before accessing elem in
+      ieee80211_copy_mbssid_beacon
+    - wifi: mac80211: clean up 'ret' in sta_link_apply_parameters()
+    - wifi: mac80211: fix station NSS capability initialization order
+    - batman-adv: Do not send uninitialized TT changes
+    - batman-adv: Remove uninitialized data in full table TT response
+    - batman-adv: Do not let TT changes list grows indefinitely
+    - wifi: cfg80211: sme: init n_channels before channels[] access
+    - selftests: mlxsw: sharedbuffer: Remove h1 ingress test case
+    - selftests: mlxsw: sharedbuffer: Remove duplicate test cases
+    - selftests: mlxsw: sharedbuffer: Ensure no extra packets are counted
+    - ptp: kvm: x86: Return EOPNOTSUPP instead of ENODEV from kvm_arch_ptp_init()
+    - net: mscc: ocelot: fix memory leak on ocelot_port_add_txtstamp_skb()
+    - net: mscc: ocelot: improve handling of TX timestamp for unknown skb
+    - net: mscc: ocelot: ocelot->ts_id_lock and ocelot_port->tx_skbs.lock are IRQ-
+      safe
+    - net: mscc: ocelot: be resilient to loss of PTP packets during transmission
+    - net: mscc: ocelot: perform error cleanup in ocelot_hwstamp_set()
+    - spi: aspeed: Fix an error handling path in aspeed_spi_[read|write]_user()
+    - net: sparx5: fix FDMA performance issue
+    - net: sparx5: fix the maximum frame length register
+    - ACPI: resource: Fix memory resource type union access
+    - cxgb4: use port number to set mac addr
+    - qca_spi: Fix clock speed for multiple QCA7000
+    - qca_spi: Make driver probing reliable
+    - ASoC: amd: yc: Fix the wrong return value
+    - Documentation: PM: Clarify pm_runtime_resume_and_get() return value
+    - net: renesas: rswitch: fix race window between tx start and complete
+    - net: renesas: rswitch: fix leaked pointer on error path
+    - net: renesas: rswitch: handle stop vs interrupt race
+    - net: dsa: felix: fix stuck CPU-injected packets with short taprio windows
+    - netem: Update sch->q.qlen before qdisc_tree_reduce_backlog()
+    - bonding: Fix feature propagation of NETIF_F_GSO_ENCAP_ALL
+    - team: Fix feature propagation of NETIF_F_GSO_ENCAP_ALL
+    - ACPICA: events/evxfregn: don't release the ContextMutex that was never
+      acquired
+    - Bluetooth: iso: Fix recursive locking warning
+    - Bluetooth: SCO: Add support for 16 bits transparent voice setting
+    - net: renesas: rswitch: fix initial MPIC register setting
+    - net: dsa: microchip: KSZ9896 register regmap alignment to 32 bit boundaries
+    - blk-iocost: Avoid using clamp() on inuse in __propagate_weights()
+    - kselftest/arm64: abi: fix SVCR detection
+    - KVM: arm64: Disable MPAM visibility by default and ignore VMM writes
+    - selftests/bpf: remove use of __xlated()
+    - xen/netfront: fix crash when removing device
+    - x86: make get_cpu_vendor() accessible from Xen code
+    - objtool/x86: allow syscall instruction
+    - x86/static-call: provide a way to do very early static-call updates
+    - x86/xen: don't do PV iret hypercall through hypercall page
+    - x86/xen: add central hypercall functions
+    - x86/xen: fix xen_hypercall_hvm() to not clobber %rbx
+    - x86/xen: add FRAME_END to xen_hypercall_hvm()
+    - x86/xen: use new hypercall functions instead of hypercall page
+    - x86/xen: remove hypercall page
+    - x86/static-call: fix 32-bit build
+    - x86/asm: Make serialize() always_inline
+    - x86/static-call: Remove early_boot_irqs_disabled check to fix Xen PVH dom0
+    - serial: sh-sci: Check if TX data was written to device in .tx_empty()
+    - gpio: ljca: Initialize num before accessing item in ljca_gpio_config
+    - ALSA: hda/realtek: Fix headset mic on Acer Nitro 5
+    - drm/amdkfd: Use device based logging for errors
+    - drm/amdkfd: pause autosuspend when creating pdd
+    - drm/amdkfd: fixed page fault when enable MES shader debugger
+    - drm/i915/color: Stop using non-posted DSB writes for legacy LUT
+    - drm/amd/pm: Set SMU v13.0.7 default workload type
+    - xfs: return a 64-bit block count from xfs_btree_count_blocks
+    - perf machine: Initialize machine->env to address a segfault
+    - bnxt_en: Fix GSO type for HW GRO packets on 5750X chips
+    - net: renesas: rswitch: fix possible early skb release
+    - Bluetooth: Improve setsockopt() handling of malformed user input
+    - libperf: evlist: Fix --cpu argument on hybrid platform
+    - selftests: netfilter: Stabilize rpath.sh
+    - net, team, bonding: Add netdev_base_features helper
+    - bonding: Fix initial {vlan,mpls}_feature set in bond_compute_features
+    - team: Fix initial vlan_feature set in __team_compute_features
+    - drm/xe: fix the ERR_PTR() returned on failure to allocate tiny pt
+    - Upstream stable to v6.6.67, v6.12.6
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56652
+    - drm/xe/reg_sr: Remove register pool
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-54460
+    - Bluetooth: iso: Fix circular lock in iso_listen_bis
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-57879
+    - Bluetooth: iso: Always release hdev at the end of iso_listen_bis
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56656
+    - bnxt_en: Fix aggregation ID mask to prevent oops on 5760X chips
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-53125
+    - bpf: sync_linked_regs() must preserve subreg_def
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56654
+    - Bluetooth: hci_event: Fix using rcu_read_(un)lock while iterating
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56770
+    - net/sched: netem: account for backlog updates from child qdisc
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-54683
+    - netfilter: IDLETIMER: Fix for possible ABBA deadlock
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-55639
+    - net: renesas: rswitch: avoid use-after-put for a device tree node
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56657
+    - ALSA: control: Avoid WARN() for symlink errors
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56659
+    - net: lapb: increase LAPB_HEADER_LEN
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56660
+    - net/mlx5: DR, prevent potential error pointer dereference
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56662
+    - acpi: nfit: vmalloc-out-of-bounds Read in acpi_nfit_ctl
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56664
+    - bpf, sockmap: Fix race between element replace and close()
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56667
+    - drm/i915: Fix NULL pointer dereference in capture_engine
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56670
+    - usb: gadget: u_serial: Fix the issue that gs_start_io crashed due to
+      accessing null pointer
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-53687
+    - riscv: Fix IPIs usage in kfence_protect_page()
+
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56675
+    - bpf: Fix UAF via mismatching bpf_prog/attachment RCU flavors
+
+  * Noble update: upstream stable patchset 2025-02-04 (LP: #2097393)
+    - selftests: net: Remove executable bits from library scripts
+
+  * CVE-2024-56653
+    - Bluetooth: btmtk: avoid UAF in btmtk_process_coredump
+
+ -- Mehmet Basaran <mehmet.basaran@canonical.com>  Tue, 15 Apr 2025 20:24:36 +0300
+
+linux (6.8.0-58.60) noble; urgency=medium
+
+  * noble/linux: 6.8.0-58.60 -proposed tracker (LP: #2102529)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2025.03.17)
+
+  * wdat_wdt.ko should be pulled in by linux-image-virtual (LP: #2098554)
+    - [Packaging]: wdat_wdt.ko is moved from "linux-modules-extra-*-generic" to
+      "linux-modules-*-generic"
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118)
+    - openrisc: Use asm-generic's version of fix_to_virt() & virt_to_fix()
+    - iTCO_wdt: mask NMI_NOW bit for update_no_reboot_bit() call
+    - watchdog: xilinx_wwdt: Calculate max_hw_heartbeat_ms using clock frequency
+    - watchdog: apple: Actually flush writes after requesting watchdog restart
+    - watchdog: mediatek: Make sure system reset gets asserted in
+      mtk_wdt_restart()
+    - can: gs_usb: add VID/PID for Xylanta SAINT3 product family
+    - can: gs_usb: add usb endpoint address detection at driver probe step
+    - can: sun4i_can: sun4i_can_err(): call can_change_state() even if cf is NULL
+    - can: m_can: m_can_handle_lec_err(): fix {rx,tx}_errors statistics
+    - can: ifi_canfd: ifi_canfd_handle_lec_err(): fix {rx,tx}_errors statistics
+    - can: hi311x: hi3110_can_ist(): fix {rx,tx}_errors statistics
+    - can: sja1000: sja1000_err(): fix {rx,tx}_errors statistics
+    - can: sun4i_can: sun4i_can_err(): fix {rx,tx}_errors statistics
+    - can: ems_usb: ems_usb_rx_err(): fix {rx,tx}_errors statistics
+    - can: f81604: f81604_handle_can_bus_errors(): fix {rx,tx}_errors statistics
+    - ipvs: fix UB due to uninitialized stack access in ip_vs_protocol_init()
+    - selftests: hid: fix typo and exit code
+    - ptp: Add error handling for adjfine callback in ptp_clock_adjtime
+    - net/sched: tbf: correct backlog statistic for GSO packets
+    - net: hsr: fix fill_frame_info() regression vs VLAN packets
+    - platform/x86: asus-wmi: add support for vivobook fan profiles
+    - platform/x86: asus-wmi: Fix inconsistent use of thermal policies
+    - platform/x86: asus-wmi: Ignore return value when writing thermal policy
+    - net/smc: mark optional smcd_ops and check for support when called
+    - net/smc: add operations to merge sndbuf with peer DMB
+    - net/smc: {at|de}tach sndbuf to peer DMB if supported
+    - net/smc: refactoring initialization of smc sock
+    - net/qed: allow old cards not supporting "num_images" to work
+    - ixgbevf: stop attempting IPSEC offload on Mailbox API 1.5
+    - ixgbe: downgrade logging of unsupported VF API version to debug
+    - net: sched: fix erspan_opt settings in cls_flower
+    - netfilter: nft_set_hash: skip duplicated elements pending gc run
+    - netfilter: nft_set_hash: unaligned atomic read on struct nft_set_ext
+    - ethtool: Fix wrong mod state in case of verbose and no_mask bitset
+    - mlxsw: spectrum_acl_flex_keys: Constify struct mlxsw_afk_element_inst
+    - mlxsw: spectrum_acl_flex_keys: Use correct key block on Spectrum-4
+    - net/mlx5e: Remove workaround to avoid syndrome for internal port
+    - xhci: Allow RPM on the USB controller (1022:43f7) by default
+    - gpio: grgpio: use a helper variable to store the address of ofdev->dev
+    - usb: dwc3: gadget: Rewrite endpoint allocation flow
+    - usb: dwc3: ep0: Don't reset resource alloc flag (including ep0)
+    - usb: dwc3: ep0: Don't clear ep0 DWC3_EP_TRANSFER_STARTED
+    - mmc: mtk-sd: use devm_mmc_alloc_host
+    - mmc: mtk-sd: Fix error handle of probe function
+    - mmc: mtk-sd: fix devm_clk_get_optional usage
+    - mmc: mtk-sd: Fix MMC_CAP2_CRYPTO flag setting
+    - zram: do not mark idle slots that cannot be idle
+    - zram: clear IDLE flag in mark_idle()
+    - powerpc/vdso: Refactor CFLAGS for CVDSO build
+    - powerpc/vdso: Drop -mstack-protector-guard flags in 32-bit files with clang
+    - ntp: Remove invalid cast in time offset math
+    - driver core: Add FWLINK_FLAG_IGNORE to completely ignore a fwnode link
+    - driver core: fw_devlink: Stop trying to optimize cycle detection logic
+    - drivers: core: fix device leak in __fw_devlink_relax_cycles()
+    - i3c: master: support to adjust first broadcast address speed
+    - i3c: master: svc: use slow speed for first broadcast address
+    - i3c: master: svc: Modify enabled_events bit 7:0 to act as IBI enable counter
+    - i3c: master: Replace hard code 2 with macro I3C_ADDR_SLOT_STATUS_BITS
+    - i3c: master: Extend address status bit to 4 and add
+      I3C_ADDR_SLOT_EXT_DESIRED
+    - i3c: master: Fix dynamic address leak when 'assigned-address' is present
+    - i3c: master: Fix missing 'ret' assignment in set_speed()
+    - drm/bridge: it6505: update usleep_range for RC circuit charge time
+    - drm/bridge: it6505: Fix inverted reset polarity
+    - scsi: ufs: core: Always initialize the UIC done completion
+    - scsi: ufs: core: Add ufshcd_send_bsg_uic_cmd() for UFS BSG
+    - bpf, vsock: Fix poll() missing a queue
+    - bpf, vsock: Invoke proto::close on close()
+    - xsk: always clear DMA mapping information when unmapping the pool
+    - bpftool: fix potential NULL pointer dereferencing in prog_dump()
+    - drm/sti: Add __iomem for mixer_dbg_mxn's parameter
+    - ALSA: seq: ump: Use automatic cleanup of kfree()
+    - ALSA: ump: Update substream name from assigned FB names
+    - ALSA: seq: ump: Fix seq port updates per FB info notify
+    - ALSA: usb-audio: Notify xrun for low-latency mode
+    - tools: Override makefile ARCH variable if defined, but empty
+    - ASoC: SOF: ipc3-topology: Convert the topology pin index to ALH dai index
+    - ASoC: SOF: ipc3-topology: fix resource leaks in
+      sof_ipc3_widget_setup_comp_dai()
+    - bpf: Fix narrow scalar spill onto 64-bit spilled scalar slots
+    - scsi: scsi_debug: Fix hrtimer support for ndelay
+    - ASoC: mediatek: mt8188-mt6359: Remove hardcoded dmic codec
+    - drm/v3d: Enable Performance Counters before clearing them
+    - scatterlist: fix incorrect func name in kernel-doc
+    - iio: magnetometer: yas530: use signed integer type for clamp limits
+    - bpf: Handle BPF_EXIST and BPF_NOEXIST for LPM trie
+    - bpf: Remove unnecessary kfree(im_node) in lpm_trie_update_elem
+    - bpf: Handle in-place update for full LPM trie correctly
+    - bpf: Fix exact match conditions in trie_get_next_key()
+    - x86/CPU/AMD: WARN when setting EFER.AUTOIBRS if and only if the WRMSR fails
+    - watchdog: rti: of: honor timeout-sec property
+    - can: mcp251xfd: mcp251xfd_get_tef_len(): work around erratum DS80000789E 6.
+    - tracing: Fix cmp_entries_dup() to respect sort() comparison rules
+    - arm64: Ensure bits ASID[15:8] are masked out when the kernel uses 8-bit
+      ASIDs
+    - ALSA: usb-audio: add mixer mapping for Corsair HS80
+    - ALSA: hda/realtek: Enable mute and micmute LED on HP ProBook 430 G8
+    - ALSA: hda/realtek: Add support for Samsung Galaxy Book3 360 (NP730QFG)
+    - scsi: qla2xxx: Fix abort in bsg timeout
+    - scsi: qla2xxx: Fix NVMe and NPIV connect issue
+    - scsi: qla2xxx: Supported speed displayed incorrectly for VPorts
+    - scsi: qla2xxx: Remove check req_sg_cnt should be equal to rsp_sg_cnt
+    - scsi: ufs: core: Add missing post notify for power mode change
+    - fs/smb/client: cifs_prime_dcache() for SMB3 POSIX reparse points
+    - drm/dp_mst: Verify request type in the corresponding down message reply
+    - drm/amdgpu/hdp5.2: do a posting read when flushing HDP
+    - modpost: Add .irqentry.text to OTHER_SECTIONS
+    - x86/kexec: Restore GDT on return from ::preserve_context kexec
+    - dma-buf: fix dma_fence_array_signaled v4
+    - dma-fence: Fix reference leak on fence merge failure path
+    - dma-fence: Use kernel's sort for merging fences
+    - regmap: detach regmap from dev on regmap_exit
+    - mmc: sdhci-pci: Add DMI quirk for missing CD GPIO on Vexia Edu Atla 10
+      tablet
+    - mmc: core: Further prevent card detect during shutdown
+    - ocfs2: update seq_file index in ocfs2_dlm_seq_next
+    - lib: stackinit: hide never-taken branch from compiler
+    - kasan: make report_lock a raw spinlock
+    - x86/mm: Add _PAGE_NOPTISHADOW bit to avoid updating userspace page tables
+    - epoll: annotate racy check
+    - kselftest/arm64: Log fp-stress child startup errors to stdout
+    - btrfs: avoid unnecessary device path update for the same device
+    - btrfs: do not clear read-only when adding sprout device
+    - kselftest/arm64: Don't leak pipe fds in pac.exec_sign_all()
+    - hwmon: (nct6775) Add 665-ACE/600M-CL to ASUS WMI monitoring list
+    - ACPI: x86: Make UART skip quirks work on PCI UARTs without an UID
+    - perf/x86/amd: Warn only on new bits set
+    - spi: spi-fsl-lpspi: Adjust type of scldiv
+    - HID: add per device quirk to force bind to hid-generic
+    - media: uvcvideo: RealSense D421 Depth module metadata
+    - media: uvcvideo: Add a quirk for the Kaiweets KTI-W02 infrared camera
+    - media: cx231xx: Add support for Dexatek USB Video Grabber 1d19:6108
+    - mmc: core: Add SD card quirk for broken poweroff notification
+    - mmc: sdhci-esdhc-imx: enable quirks SDHCI_QUIRK_NO_LED
+    - regmap: maple: Provide lockdep (sub)class for maple tree's internal lock
+    - selftests/resctrl: Protect against array overflow when reading strings
+    - drm/vc4: hdmi: Avoid log spam for audio start failure
+    - drm/vc4: hvs: Set AXI panic modes for the HVS
+    - drm: panel-orientation-quirks: Add quirk for AYA NEO 2 model
+    - drm: panel-orientation-quirks: Add quirk for AYA NEO Founder edition
+    - drm: panel-orientation-quirks: Add quirk for AYA NEO GEEK
+    - drm/bridge: it6505: Enable module autoloading
+    - drm/mcde: Enable module autoloading
+    - drm/radeon/r600_cs: Fix possible int overflow in r600_packet3_check()
+    - drm/display: Fix building with GCC 15
+    - ALSA: hda: Use own quirk lookup helper
+    - ALSA: hda/conexant: Use the new codec SSID matching
+    - r8169: don't apply UDP padding quirk on RTL8126A
+    - samples/bpf: Fix a resource leak
+    - net: fec_mpc52xx_phy: Use %pa to format resource_size_t
+    - net: ethernet: fs_enet: Use %pa to format resource_size_t
+    - net/sched: cbs: Fix integer overflow in cbs_set_port_rate()
+    - Bluetooth: L2CAP: handle NULL sock pointer in l2cap_sock_alloc
+    - wifi: ath5k: add PCI ID for SX76X
+    - wifi: ath5k: add PCI ID for Arcadyan devices
+    - fanotify: allow reporting errors on failure to open fd
+    - drm/panel: simple: Add Microchip AC69T88A LVDS Display panel
+    - net: sfp: change quirks for Alcatel Lucent G-010S-P
+    - net: stmmac: Programming sequence for VLAN packets with split header
+    - drm/sched: memset() 'job' in drm_sched_job_init()
+    - amdgpu/uvd: get ring reference from rq scheduler
+    - drm/amdgpu: don't access invalid sched
+    - drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts for vega20_ih
+    - drm/amdgpu: Dereference the ATCS ACPI buffer
+    - netlink: specs: Add missing bitset attrs to ethtool spec
+    - drm/amdgpu: refine error handling in amdgpu_ttm_tt_pin_userptr
+    - fsl/fman: Validate cell-index value obtained from Device Tree
+    - drm/amdgpu: skip amdgpu_device_cache_pci_state under sriov
+    - ALSA: usb-audio: Make mic volume workarounds globally applicable
+    - wifi: ipw2x00: libipw_rx_any(): fix bad alignment
+    - dsa: qca8k: Use nested lock to avoid splat
+    - Bluetooth: btusb: Add RTL8852BE device 0489:e123 to device tables
+    - Bluetooth: Add new quirks for ATS2851
+    - Bluetooth: Support new quirks for ATS2851
+    - Bluetooth: Set quirks for ATS2851
+    - ASoC: hdmi-codec: reorder channel allocation list
+    - rocker: fix link status detection in rocker_carrier_init()
+    - net/neighbor: clear error in case strict check is not set
+    - netpoll: Use rcu_access_pointer() in __netpoll_setup
+    - pinctrl: freescale: fix COMPILE_TEST error with PINCTRL_IMX_SCU
+    - tracing/ftrace: disable preemption in syscall probe
+    - tracing: Use atomic64_inc_return() in trace_clock_counter()
+    - tools/rtla: fix collision with glibc sched_attr/sched_set_attr
+    - rtla/timerlat: Make timerlat_top_cpu->*_count unsigned long long
+    - scsi: ufs: core: Make DMA mask configuration more flexible
+    - scsi: lpfc: Call lpfc_sli4_queue_unset() in restart and rmmod paths
+    - clk: qcom: rcg2: add clk_rcg2_shared_floor_ops
+    - clk: qcom: rpmh: add support for SAR2130P
+    - clk: qcom: tcsrcc-sm8550: add SAR2130P support
+    - scsi: st: Don't modify unknown block number in MTIOCGET
+    - scsi: st: Add MTIOCGET and MTLOAD to ioctls allowed after device reset
+    - pinctrl: qcom-pmic-gpio: add support for PM8937
+    - pinctrl: qcom: spmi-mpp: Add PM8937 compatible
+    - thermal/drivers/qcom/tsens-v1: Add support for MSM8937 tsens
+    - nvdimm: rectify the illogical code within nd_dax_probe()
+    - smb: client: memcpy() with surrounding object base address
+    - verification/dot2: Improve dot parser robustness
+    - KMSAN: uninit-value in inode_go_dump (5)
+    - PCI: qcom: Add support for IPQ9574
+    - PCI: vmd: Add DID 8086:B06F and 8086:B60B for Intel client SKUs
+    - PCI: vmd: Set devices to D0 before enabling PM L1 Substates
+    - PCI: Detect and trust built-in Thunderbolt chips
+    - PCI: Add 'reset_subordinate' to reset hierarchy below bridge
+    - PCI: Add ACS quirk for Wangxun FF5xxx NICs
+    - f2fs: print message if fscorrupted was found in f2fs_new_node_page()
+    - ACPI: x86: Add skip i2c clients quirk for Acer Iconia One 8 A1-840
+    - ACPI: x86: Clean up Asus entries in acpi_quirk_skip_dmi_ids[]
+    - fs/ntfs3: Fix case when unmarked clusters intersect with zone
+    - usb: chipidea: udc: handle USB Error Interrupt if IOC not set
+    - iio: light: ltr501: Add LTER0303 to the supported devices
+    - ASoC: amd: yc: fix internal mic on Redmi G 2022
+    - drm/amdgpu/vcn: reset fw_shared when VCPU buffers corrupted on vcn v4.0.3
+    - drm/amdgpu/vcn: reset fw_shared under SRIOV
+    - ASoC: amd: yc: Add quirk for microphone on Lenovo Thinkpad T14s Gen 6
+      21M1CTO1WW
+    - misc: eeprom: eeprom_93cx6: Add quirk for extra read clock cycle
+    - rtc: cmos: avoid taking rtc_lock for extended period of time
+    - serial: 8250_dw: Add Sophgo SG2044 quirk
+    - smb: client: don't try following DFS links in cifs_tree_connect()
+    - setlocalversion: work around "git describe" performance
+    - sched/core: Remove the unnecessary need_resched() check in nohz_csd_func()
+    - sched/fair: Check idle_cpu() before need_resched() to detect ilb CPU turning
+      busy
+    - sched/core: Prevent wakeup of ksoftirqd during idle load balance
+    - btrfs: fix missing snapshot drew unlock when root is dead during swap
+      activation
+    - clk: en7523: Initialize num before accessing hws in en7523_register_clocks()
+    - tracing/eprobe: Fix to release eprobe when failed to add dyn_event
+    - x86: Fix build regression with CONFIG_KEXEC_JUMP enabled
+    - Revert "unicode: Don't special case ignorable code points"
+    - vfio/mlx5: Align the page tracking max message size with the device
+      capability
+    - selftests/ftrace: adjust offset for kprobe syntax error test
+    - KVM: x86/mmu: Ensure that kvm_release_pfn_clean() takes exact pfn from
+      kvm_faultin_pfn()
+    - jffs2: Fix rtime decompressor
+    - mm/damon/vaddr: fix issue in damon_va_evenly_split_region()
+    - iio: invensense: fix multiple odr switch when FIFO is off
+    - ocfs2: Revert "ocfs2: fix the la space leak when unmounting an ocfs2 volume"
+    - ALSA: hda: Fix build error without CONFIG_SND_DEBUG
+    - usb: dwc3: ep0: Don't reset resource alloc flag
+    - ALSA: usb-audio: Update UMP group attributes for GTB blocks, too
+    - platform/x86: asus-wmi: Fix thermal profile initialization
+    - i3c: master: svc: fix possible assignment of the same address to two devices
+    - btrfs: drop unused parameter file_offset from
+      btrfs_encoded_read_regular_fill_pages()
+    - md/raid5: Wait sync io to finish before changing group cnt
+    - media: platform: rga: fix 32-bit DMA limitation
+    - net: phy: dp83869: fix status reporting for 1000base-x autonegotiation
+    - remoteproc: qcom_q6v5_pas: disable auto boot for wpss
+    - mtd: spinand: winbond: Fix 512GW and 02JW OOB layout
+    - PCI: Pass domain number to pci_bus_release_domain_nr() explicitly
+    - dt-bindings: net: fec: add pps channel property
+    - net: fec: refactor PPS channel configuration
+    - net: fec: make PPS channel configurable
+    - drm/xe/xe_guc_ads: save/restore OA registers and allowlist regs
+    - drm/xe/migrate: use XE_BO_FLAG_PAGETABLE
+    - drm/amd: Add some missing straps from NBIO 7.11.0
+    - drm/amd: Fix initialization mistake for NBIO 7.11 devices
+    - drm/amdgpu/pm: Don't use OD table on Arcturus
+    - drm/amd/pm: Remove arcturus min power limit
+    - drm/amd/display: update pipe selection policy to check head pipe
+    - drm/amd/display: Remove PIPE_DTO_SRC_SEL programming from set_dtbclk_dto
+    - Revert "drm/xe/xe_guc_ads: save/restore OA registers and allowlist regs"
+    - ipv6: avoid possible NULL deref in modify_prefix_route()
+    - net: phy: microchip: Reset LAN88xx PHY to ensure clean link state on
+      LAN7800/7850
+    - ice: fix PHY Clock Recovery availability check
+    - vsock/test: fix failures due to wrong SO_RCVLOWAT parameter
+    - vsock/test: fix parameter types in SO_VM_SOCKETS_* calls
+    - mmc: core Convert UNSTUFF_BITS macro to inline function
+    - mmc: sd: SDUC Support Recognition
+    - mmc: core: Adjust ACMD22 to SDUC
+    - mmc: core: Use GFP_NOIO in ACMD22
+    - f2fs: clean up w/ F2FS_{BLK_TO_BYTES,BTYES_TO_BLK}
+    - f2fs: fix to adjust appropriate length for fiemap
+    - f2fs: fix to requery extent which cross boundary of inquiry
+    - drm/amd/display: calculate final viewport before TAP optimization
+    - drm/amd/display: Ignore scalar validation failure if pipe is phantom
+    - pmdomain: core: Add missing put_device()
+    - pmdomain: core: Fix error path in pm_genpd_init() when ida alloc fails
+    - pmdomain: core: add dummy release function to genpd device
+    - bpf: Ensure reg is PTR_TO_STACK in process_iter_arg
+    - bpf: Don't mark STACK_INVALID as STACK_MISC in mark_stack_slot_misc
+    - LoongArch: KVM: Protect kvm_check_requests() with SRCU
+    - net :mana :Request a V2 response version for MANA_QUERY_GF_STAT
+    - ALSA: usb-audio: Add extra PID for RME Digiface USB
+    - ALSA: hda/realtek: fix micmute LEDs don't work on HP Laptops
+    - scsi: ufs: pltfrm: Disable runtime PM during removal of glue drivers
+    - io_uring/cmd: document some uring_cmd related helpers
+    - io_uring: Change res2 parameter type in io_uring_cmd_done
+    - selftests/damon: add _damon_sysfs.py to TEST_FILES
+    - drm/amd/display: Correct prefetch calculation
+    - drm/amd/amdgpu: allow use kiq to do hdp flush under sriov
+    - drm/amdgpu/hdp6.0: do a posting read when flushing HDP
+    - drm/amdgpu/hdp4.0: do a posting read when flushing HDP
+    - drm/amdgpu/hdp5.0: do a posting read when flushing HDP
+    - x86/cpu/intel: Switch to new Intel CPU model defines
+    - x86/cpu/intel: Drop stray FAM6 check with new Intel CPU model defines
+    - x86/cpu: Add Lunar Lake to list of CPUs with a broken MONITOR implementation
+    - mm/damon: fix order of arguments in damos_before_apply tracepoint
+    - mm: respect mmap hint address when aligning for THP
+    - scsi: ufs: pltfrm: Drop PM runtime reference count after ufshcd_remove()
+    - memblock: allow zero threshold in validate_numa_converage()
+    - s390/pci: Sort PCI functions prior to creating virtual busses
+    - s390/pci: Use topology ID for multi-function devices
+    - s390/pci: Ignore RID for isolated VFs
+    - s390/pci: Fix SR-IOV for PFs initially in standby
+    - s390/pci: Pull search for parent PF out of zpci_iov_setup_virtfn()
+    - s390/pci: Fix handling of isolated VFs
+    - ext4: partial zero eof block on unaligned inode size extension
+    - crypto: ecdsa - Convert byte arrays with key coordinates to digits
+    - crypto: ecc - Prevent ecc_digits_from_bytes from reading too many bytes
+    - crypto: ecdsa - Rename keylen to bufsize where necessary
+    - crypto: ecdsa - Use ecc_digits_from_bytes to convert signature
+    - crypto: ecdsa - Avoid signed integer overflow on signature decoding
+    - ACPI: video: force native for Apple MacbookPro11,2 and Air7,2
+    - cleanup: Adjust scoped_guard() macros to avoid potential warning
+    - gpio: free irqs that are still requested when the chip is being removed
+    - media: uvcvideo: Force UVC version to 1.0a for 0408:4035
+    - media: uvcvideo: Force UVC version to 1.0a for 0408:4033
+    - wifi: mac80211: export ieee80211_purge_tx_queue() for drivers
+    - drm/amd/display: skip disable CRTC in seemless bootup case
+    - drm/amd/display: disable SG displays on cyan skillfish
+    - wifi: mac80211: Add non-atomic station iterator
+    - accel/qaic: Add AIC080 support
+    - mptcp: annotate data-races around subflow->fully_established
+    - net/tcp: Add missing lockdep annotations for TCP-AO hlist traversals
+    - drm/amd/display: Prune Invalid Modes For HDMI Output
+    - i2c: i801: Add support for Intel Arrow Lake-H
+    - i2c: i801: Add support for Intel Panther Lake
+    - Bluetooth: hci_conn: Reduce hci_conn_drop() calls in two functions
+    - Bluetooth: btusb: Add new VID/PID 13d3/3602 for MT7925
+    - Bluetooth: btusb: Add USB HW IDs for MT7921/MT7922/MT7925
+    - Bluetooth: btusb: Add new VID/PID 0489/e111 for MT7925
+    - Bluetooth: btusb: Add new VID/PID 0489/e124 for MT7925
+    - Bluetooth: btusb: Add 3 HWIDs for MT7925
+    - rtla/timerlat: Make timerlat_hist_cpu->*_count unsigned long long
+    - ring-buffer: Correct stale comments related to non-consuming readers
+    - ring-buffer: Limit time with disabled interrupts in rb_check_pages()
+    - scsi: lpfc: Check SLI_ACTIVE flag in FDMI cmpl before submitting follow up
+      FDMI
+    - scsi: lpfc: Prevent NDLP reference count underflow in dev_loss_tmo callback
+    - clk: qcom: clk-alpha-pll: Add support for zonda ole pll configure
+    - clk: qcom: clk-alpha-pll: Add NSS HUAYRA ALPHA PLL support for ipq9574
+    - mailbox: pcc: Check before sending MCTP PCC response ACK
+    - remoteproc: qcom: pas: Add support for SA8775p ADSP, CDSP and GPDSP
+    - remoteproc: qcom: pas: enable SAR2130P audio DSP support
+    - fs/ntfs3: Implement fallocate for compressed files
+    - fs/ntfs3: Fix warning in ni_fiemap
+    - regulator: qcom-rpmh: Update ranges for FTSMPS525
+    - usb: chipidea: add CI_HDRC_HAS_SHORT_PKT_LIMIT flag
+    - usb: chipidea: udc: limit usb request length to max 16KB
+    - usb: chipidea: udc: create bounce buffer for problem sglist entries if
+      possible
+    - iio: adc: ad7192: Convert from of specific to fwnode property handling
+    - iio: adc: ad7192: properly check spi_get_device_match_data()
+    - usb: typec: ucsi: add callback for connector status updates
+    - usb: typec: ucsi: glink: move GPIO reading into connector_status callback
+    - usb: typec: ucsi: add update_connector callback
+    - usb: typec: ucsi: glink: set orientation aware if supported
+    - usb: typec: ucsi: glink: be more precise on orientation-aware ports
+    - usb: typec: ucsi: glink: fix off-by-one in connector_status
+    - usb: typec: ucsi: Set orientation as none when connector is unplugged
+    - nvme: use helper nvme_ctrl_state in nvme_keep_alive_finish function
+    - Revert "nvme: make keep-alive synchronous operation"
+    - irqchip/gic-v3-its: Avoid explicit cpumask allocation on stack
+    - irqchip/gicv3-its: Add workaround for hip09 ITS erratum 162100801
+    - [Config] updateconfigs for HISILICON_ERRATUM_162100801
+    - drm/amd/display: Add option to retrieve detile buffer size
+    - btrfs: drop unused parameter options from open_ctree()
+    - btrfs: drop unused parameter data from btrfs_fill_super()
+    - btrfs: fix mount failure due to remount races
+    - net/mlx5: unique names for per device caches
+    - s390/pci: Fix leak of struct zpci_dev when zpci_add_device() fails
+    - ALSA: hda/realtek: Fix spelling mistake "Firelfy" -> "Firefly"
+    - softirq: Allow raising SCHED_SOFTIRQ from SMP-call-function on RT kernel
+    - Upstream stable to v6.6.65, v6.6.66, v6.12.4, v6.12.5
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-41932
+    - sched: fix warning in sched_setaffinity
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57872
+    - scsi: ufs: pltfrm: Dellocate HBA during ufshcd_pltfrm_remove()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56588
+    - scsi: hisi_sas: Create all dump files during debugfs initialization
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-47794
+    - bpf: Prevent tailcall infinite loop caused by freplace
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56599
+    - wifi: ath10k: avoid NULL pointer error during sdio remove
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56607
+    - wifi: ath12k: fix atomic calls in ath12k_mac_op_set_bitrate_mask()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56608
+    - drm/amd/display: Fix out-of-bounds access in 'dcn21_link_encoder_create'
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56609
+    - wifi: rtw88: use ieee80211_purge_tx_queue() to purge TX skb
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56782
+    - ACPI: x86: Add adev NULL check to acpi_quirk_skip_serdev_enumeration()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-48876
+    - stackdepot: fix stack_depot_save_flags() in NMI context
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56620
+    - scsi: ufs: qcom: Only free platform MSIs when ESI is enabled
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56621
+    - scsi: ufs: core: Cancel RTC work during ufshcd_remove()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-49569
+    - nvme-rdma: unquiesce admin_q before destroy it
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56632
+    - nvme-tcp: fix the memleak while create new ctrl failed
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56647
+    - net: Fix icmp host relookup triggering ip_rt_bug
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56775
+    - drm/amd/display: Fix handling of plane refcount
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56561
+    - PCI: endpoint: Fix PCI domain ID release in pci_epc_destroy()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56550
+    - s390/stacktrace: Use break instead of return statement
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56771
+    - mtd: spinand: winbond: Fix 512GW, 01GW, 01JW and 02JW ECC information
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56568
+    - iommu/arm-smmu: Defer probe of clients after smmu device bound
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56772
+    - kunit: string-stream: Fix a UAF bug in kunit_init_suite()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56773
+    - kunit: Fix potential null dereference in kunit_device_driver_test()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56580
+    - media: qcom: camss: fix error path on configuration of power domains
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57850
+    - jffs2: Prevent rtime decompress memory corruption
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56583
+    - sched/deadline: Fix warning in migrate_enable for boosted tasks
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56611
+    - mm/mempolicy: fix migrate_to_node() assuming there is at least one VMA in a
+      MM
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56613
+    - sched/numa: fix memory leak due to the overwritten vma->numab_state
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56584
+    - io_uring/tctx: work around xa_store() allocation error issue
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56781
+    - powerpc/prom_init: Fixup missing powermac #size-cells
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56785
+    - MIPS: Loongson64: DTS: Really fix PCIe port nodes for ls7a
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56585
+    - LoongArch: Fix sleeping in atomic context for PREEMPT_RT
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-41935
+    - f2fs: fix to shrink read extent node in batches
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-43098
+    - i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to
+      avoid deadlock
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-45828
+    - i3c: mipi-i3c-hci: Mask ring interrupts before ring stop request
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56586
+    - f2fs: fix f2fs_bug_on when uninstalling filesystem call f2fs_evict_inode.
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56587
+    - leds: class: Protect brightness_show() with led_cdev->led_access mutex
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56786
+    - bpf: put bpf_link's program when link is safe to be deallocated
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-47141
+    - pinmux: Use sequential access to access desc->pinmux data
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56589
+    - scsi: hisi_sas: Add cond_resched() for no forced preemption model
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56590
+    - Bluetooth: hci_core: Fix not checking skb length on hci_acldata_packet
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56592
+    - bpf: Call free_htab_elem() after htab_unlock_bucket()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56593
+    - wifi: brcmfmac: Fix oops due to NULL pointer dereference in
+      brcmf_sdiod_sglist_rw()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56594
+    - drm/amdgpu: set the right AMDGPU sg segment limitation
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57843
+    - virtio-net: fix overflow inside virtnet_rq_alloc
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56596
+    - jfs: fix array-index-out-of-bounds in jfs_readdir
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56597
+    - jfs: fix shift-out-of-bounds in dbSplit
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-47143
+    - dma-debug: fix a possible deadlock on radix_lock
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56601
+    - net: inet: do not leave a dangling sk pointer in inet_create()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56602
+    - net: ieee802154: do not leave a dangling sk pointer in ieee802154_create()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56603
+    - net: af_can: do not leave a dangling sk pointer in can_create()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56604
+    - Bluetooth: RFCOMM: avoid leaving dangling sk pointer in rfcomm_sock_alloc()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56605
+    - Bluetooth: L2CAP: do not leave dangling sk pointer on error in
+      l2cap_sock_create()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56606
+    - af_packet: avoid erroring out after sock_init_data() in packet_create()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-47809
+    - dlm: fix possible lkb_resource null dereference
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-48873
+    - wifi: rtw89: check return value of ieee80211_probereq_get() for RNR
+
+  * Missing support for USB-C Apple Magic Trackpad (LP: #2098063) // Noble
+    update: upstream stable patchset 2025-03-12 (LP: #2102118)
+    - HID: magicmouse: Apple Magic Trackpad 2 USB-C driver support
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56787
+    - soc: imx8m: Probe the SoC driver as platform driver
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56610
+    - kcsan: Turn report_filterlist_lock into a raw_spinlock
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-48875
+    - btrfs: don't take dev_replace rwsem on task already holding it
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57849
+    - s390/cpum_sf: Handle CPU hotplug remove during sampling
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57876
+    - drm/dp_mst: Fix resetting msg rx state after topology removal
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56616
+    - drm/dp_mst: Fix MST sideband message body length check
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-48881
+    - bcache: revert replacing IS_ERR_OR_NULL with IS_ERR again
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56619
+    - nilfs2: fix potential out-of-bounds memory access in nilfs_find_entry()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56622
+    - scsi: ufs: core: sysfs: Prevent div by zero
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56623
+    - scsi: qla2xxx: Fix use after free on unload
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57874
+    - arm64: ptrace: fix partial SETREGSET for NT_ARM_TAGGED_ADDR_CTRL
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56625
+    - can: dev: can_set_termination(): allow sleeping GPIOs
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56626
+    - ksmbd: fix Out-of-Bounds Write in ksmbd_vfs_stream_write
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56628
+    - LoongArch: Add architecture specific huge_pte_clear()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56629
+    - HID: wacom: fix when get product name maybe null pointer
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56630
+    - ocfs2: free inode when ocfs2_get_init_inode() fails
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56631
+    - scsi: sg: Fix slab-use-after-free read in sg_release()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-50051
+    - spi: mpc52xx: Add cancel_work_sync before module remove
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56633
+    - tcp_bpf: Fix the sk_mem_uncharge logic in tcp_bpf_sendmsg
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56565
+    - f2fs: fix to drop all discards after creating snapshot on lvm device
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56634
+    - gpio: grgpio: Add NULL check in grgpio_probe
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56635
+    - net: avoid potential UAF in default_operstate()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56636
+    - geneve: do not assume mac header is set in geneve_xmit_skb()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56637
+    - netfilter: ipset: Hold module reference while requesting a module
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56638
+    - netfilter: nft_inner: incorrect percpu area handling under softirq
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-52332
+    - igb: Fix potential invalid memory access in igb_init_module()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56640
+    - net/smc: fix LGR and link use-after-free issue
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56641
+    - net/smc: initialize close_work early to avoid warning
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56643
+    - dccp: Fix memory leak in dccp_feat_change_recv
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56644
+    - net/ipv6: release expired exception dst cached in socket
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56645
+    - can: j1939: j1939_session_new(): fix skb reference counting
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56648
+    - net: hsr: avoid potential out-of-bound access in fill_frame_info()
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56649
+    - net: enetc: Do not configure preemptible TCs if SIs do not support
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56783
+    - netfilter: nft_socket: remove WARN_ON_ONCE on maximum cgroup level
+
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56650
+    - netfilter: x_tables: fix LED ID check in led_tg_check()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915)
+    - wifi: radiotap: Avoid -Wflex-array-member-not-at-end warnings
+    - ASoC: codecs: rt5640: Always disable IRQs from rt5640_cancel_work()
+    - ASoC: Intel: bytcr_rt5640: Add support for non ACPI instantiated codec
+    - ASoC: Intel: bytcr_rt5640: Add DMI quirk for Vexia Edu Atla 10 tablet
+    - ASoC: Intel: sst: Support LPE0F28 ACPI HID
+    - wifi: iwlwifi: mvm: Use the sync timepoint API in suspend
+    - mac80211: fix user-power when emulating chanctx
+    - usb: add support for new USB device ID 0x17EF:0x3098 for the r8152 driver
+    - selftests/watchdog-test: Fix system accidentally reset after watchdog-test
+    - ALSA: hda/realtek: Add subwoofer quirk for Infinix ZERO BOOK 13
+    - x86/amd_nb: Fix compile-testing without CONFIG_AMD_NB
+    - bpf: fix filed access without lock
+    - net: usb: qmi_wwan: add Quectel RG650V
+    - soc: qcom: Add check devm_kasprintf() returned value
+    - firmware: arm_scmi: Reject clear channel request on A2P
+    - regulator: rk808: Add apply_bit for BUCK3 on RK809
+    - platform/x86: dell-smbios-base: Extends support to Alienware products
+    - platform/x86: dell-wmi-base: Handle META key Lock/Unlock events
+    - ASoC: tas2781: Add new driver version for tas2563 & tas2781 qfn chip
+    - tools/lib/thermal: Remove the thermal.h soft link when doing make clean
+    - can: j1939: fix error in J1939 documentation.
+    - platform/x86: thinkpad_acpi: Fix for ThinkPad's with ECFW showing incorrect
+      fan speed
+    - ASoC: amd: yc: Support dmic on another model of Lenovo Thinkpad E14 Gen 6
+    - ASoC: stm: Prevent potential division by zero in stm32_sai_mclk_round_rate()
+    - ASoC: stm: Prevent potential division by zero in stm32_sai_get_clk_div()
+    - drm: panel-orientation-quirks: Make Lenovo Yoga Tab 3 X90F DMI match less
+      strict
+    - proc/softirqs: replace seq_printf with seq_put_decimal_ull_width
+    - ASoC: audio-graph-card2: Purge absent supplies for device tree nodes
+    - LoongArch: Define a default value for VM_DATA_DEFAULT_FLAGS
+    - ALSA: usb-audio: Fix Yamaha P-125 Quirk Entry
+    - ARM: 9420/1: smp: Fix SMP for xip kernels
+    - ipmr: Fix access to mfc_cache_list without lock held
+    - mptcp: fix possible integer overflow in mptcp_reset_tout_timer
+    - arm64: probes: Disable kprobes/uprobes on MOPS instructions
+    - kselftest/arm64: mte: fix printf type warnings about __u64
+    - kselftest/arm64: mte: fix printf type warnings about longs
+    - s390/cio: Do not unregister the subchannel based on DNV
+    - s390/pageattr: Implement missing kernel_page_present()
+    - ext4: avoid remount errors with 'abort' mount option
+    - mips: asm: fix warning when disabling MIPS_FP_SUPPORT
+    - m68k: mvme147: Fix SCSI controller IRQ numbers
+    - m68k: mvme147: Reinstate early console
+    - arm64: fix .data.rel.ro size assertion when CONFIG_LTO_CLANG
+    - acpi/arm64: Adjust error handling procedure in gtdt_parse_timer_block()
+    - cachefiles: Fix missing pos updates in cachefiles_ondemand_fd_write_iter()
+    - block: fix bio_split_rw_at to take zone_write_granularity into account
+    - s390/syscalls: Avoid creation of arch/arch/ directory
+    - ext4: remove calls to to set/clear the folio error flag
+    - ext4: pipeline buffer reads in mext_page_mkuptodate()
+    - ext4: remove array of buffer_heads from mext_page_mkuptodate()
+    - ext4: fix race in buffer_head read fault injection
+    - nvme-pci: reverse request order in nvme_queue_rqs
+    - virtio_blk: reverse request order in virtio_queue_rqs
+    - crypto: qat - remove check after debugfs_create_dir()
+    - firmware: google: Unregister driver_info on failure
+    - crypto: qat - remove faulty arbiter config reset
+    - thermal: core: Initialize thermal zones before registering them
+    - EDAC/fsl_ddr: Fix bad bit shift operations
+    - EDAC/skx_common: Differentiate memory error sources
+    - EDAC/{skx_common,i10nm}: Fix incorrect far-memory error source indicator
+    - crypto: cavium - Fix the if condition to exit loop after timeout
+    - amd-pstate: Set min_perf to nominal_perf for active mode performance gov
+    - crypto: hisilicon/qm - disable same error report before resetting
+    - crypto: inside-secure - Fix the return value of safexcel_xcbcmac_cra_init()
+    - doc: rcu: update printed dynticks counter bits
+    - hwmon: (pmbus_core) Allow to hook PMBUS_SMBALERT_MASK
+    - hwmon: (pmbus/core) clear faults after setting smbalert mask
+    - hwmon: (nct6775-core) Fix overflows seen when writing limit attributes
+    - ACPI: CPPC: Fix _CPC register setting issue
+    - crypto: caam - add error check to caam_rsa_set_priv_key_form
+    - crypto: cavium - Fix an error handling path in cpt_ucode_load_fw()
+    - rcuscale: Do a proper cleanup if kfree_scale_init() fails
+    - tools/lib/thermal: Make more generic the command encoding function
+    - thermal/lib: Fix memory leak on error in thermal_genl_auto()
+    - x86/unwind/orc: Fix unwind for newly forked tasks
+    - time: Partially revert cleanup on msecs_to_jiffies() documentation
+    - time: Fix references to _msecs_to_jiffies() handling of values
+    - kcsan, seqlock: Support seqcount_latch_t
+    - kcsan, seqlock: Fix incorrect assumption in read_seqbegin()
+    - clocksource/drivers:sp804: Make user selectable
+    - clocksource/drivers/timer-ti-dm: Fix child node refcount handling
+    - spi: spi-fsl-lpspi: Use IRQF_NO_AUTOEN flag in request_irq()
+    - microblaze: Export xmb_manager functions
+    - arm64: dts: mt8195: Fix dtbs_check error for mutex node
+    - arm64: dts: mt8195: Fix dtbs_check error for infracfg_ao node
+    - soc: ti: smartreflex: Use IRQF_NO_AUTOEN flag in request_irq()
+    - arm64: dts: qcom: sm6350: Fix GPU frequencies missing on some speedbins
+    - ARM: dts: microchip: sam9x60: Add missing property atmel,usart-mode
+    - mmc: mmc_spi: drop buggy snprintf()
+    - openrisc: Implement fixmap to fix earlycon
+    - efi/libstub: fix efi_parse_options() ignoring the default command line
+    - tpm: fix signed/unsigned bug when checking event logs
+    - media: i2c: ds90ub960: Fix missing return check on ub960_rxport_read call
+    - arm64: dts: mt8183: krane: Fix the address of eeprom at i2c4
+    - arm64: dts: mt8183: kukui: Fix the address of eeprom at i2c4
+    - arm64: dts: mediatek: mt8173-elm-hana: Add vdd-supply to second source
+      trackpad
+    - Revert "cgroup: Fix memory leak caused by missing cgroup_bpf_offline"
+    - cgroup/bpf: only cgroup v2 can be attached by bpf programs
+    - regulator: rk808: Restrict DVS GPIOs to the RK808 variant only
+    - arm64: dts: mt8183: fennel: add i2c2's i2c-scl-internal-delay-ns
+    - arm64: dts: mt8183: burnet: add i2c2's i2c-scl-internal-delay-ns
+    - arm64: dts: mt8183: cozmo: add i2c2's i2c-scl-internal-delay-ns
+    - arm64: dts: mt8183: Damu: add i2c2's i2c-scl-internal-delay-ns
+    - pwm: imx27: Workaround of the pwm output bug when decrease the duty cycle
+    - ARM: dts: cubieboard4: Fix DCDC5 regulator constraints
+    - arm64: dts: ti: k3-j7200: use ti,j7200-padconf compatible
+    - arm64: dts: ti: k3-j7200: Fix register map for main domain pmx
+    - arm64: dts: ti: k3-j7200: Fix clock ids for MCSPI instances
+    - arm64: dts: ti: k3-j721e: Fix clock IDs for MCSPI instances
+    - arm64: dts: ti: k3-j721s2: Fix clock IDs for MCSPI instances
+    - um: Unconditionally call unflatten_device_tree()
+    - x86/of: Unconditionally call unflatten_and_copy_device_tree()
+    - of/fdt: add dt_phys arg to early_init_dt_scan and early_init_dt_verify
+    - riscv: Fix wrong usage of __pa() on a fixmap address
+    - pmdomain: ti-sci: Add missing of_node_put() for args.np
+    - spi: tegra210-quad: Avoid shift-out-of-bounds
+    - spi: zynqmp-gqspi: Undo runtime PM changes at driver exit time​
+    - regmap: irq: Set lockdep class for hierarchical IRQ domains
+    - arm64: dts: renesas: hihope: Drop #sound-dai-cells
+    - arm64: dts: mediatek: Add ADC node on MT6357, MT6358, MT6359 PMICs
+    - arm64: dts: mediatek: mt6358: fix dtbs_check error
+    - arm64: dts: mediatek: mt8183-kukui-jacuzzi: Fix DP bridge supply names
+    - arm64: dts: mediatek: mt8183-kukui-jacuzzi: Add supplies for fixed
+      regulators
+    - selftests/resctrl: Split fill_buf to allow tests finer-grained control
+    - selftests/resctrl: Refactor fill_buf functions
+    - selftests/resctrl: Fix memory overflow due to unhandled wraparound
+    - selftests/resctrl: Protect against array overrun during iMC config parsing
+    - arm64: dts: rockchip: correct analog audio name on Indiedroid Nova
+    - platform/x86: panasonic-laptop: Return errno correctly in show callback
+    - drm/mm: Mark drm_mm_interval_tree*() functions with __maybe_unused
+    - drm/vc4: hvs: Don't write gamma luts on 2711
+    - drm/vc4: hvs: Fix dlist debug not resetting the next entry pointer
+    - drm/vc4: hvs: Remove incorrect limit from hvs_dlist debugfs function
+    - drm/vc4: hvs: Correct logic on stopping an HVS channel
+    - drm/omap: Fix possible NULL dereference
+    - drm/omap: Fix locking in omap_gem_new_dmabuf()
+    - wifi: p54: Use IRQF_NO_AUTOEN flag in request_irq()
+    - wifi: mwifiex: Use IRQF_NO_AUTOEN flag in request_irq()
+    - drm/imx/dcss: Use IRQF_NO_AUTOEN flag in request_irq()
+    - drm/imx/ipuv3: Use IRQF_NO_AUTOEN flag in request_irq()
+    - drm/v3d: Address race-condition in MMU flush
+    - wifi: ath10k: fix invalid VHT parameters in supported_vht_mcs_rate_nss1
+    - wifi: ath10k: fix invalid VHT parameters in supported_vht_mcs_rate_nss2
+    - dt-bindings: vendor-prefixes: Add NeoFidelity, Inc
+    - ASoC: fsl_micfil: fix regmap_write_bits usage
+    - ASoC: dt-bindings: mt6359: Update generic node name and dmic-mode
+    - drm/bridge: anx7625: Drop EDID cache on bridge power off
+    - drm/bridge: it6505: Drop EDID cache on bridge power off
+    - libbpf: Fix expected_attach_type set handling in program load callback
+    - libbpf: Fix output .symtab byte-order during linking
+    - bpf: Fix the xdp_adjust_tail sample prog issue
+    - wifi: ath11k: Fix CE offset address calculation for WCN6750 in SSR
+    - ice: consistently use q_idx in ice_vc_cfg_qs_msg()
+    - drm/vc4: Match drm_dev_enter and exit calls in vc4_hvs_atomic_flush
+    - libbpf: fix sym_is_subprog() logic for weak global subprogs
+    - ASoC: rt722-sdca: Remove logically deadcode in rt722-sdca.c
+    - libbpf: never interpret subprogs in .text as entry programs
+    - netdevsim: copy addresses for both in and out paths
+    - drm/bridge: tc358767: Fix link properties discovery
+    - selftests/bpf: Fix msg_verify_data in test_sockmap
+    - selftests/bpf: Fix txmsg_redir of test_txmsg_pull in test_sockmap
+    - drm: fsl-dcu: enable PIXCLK on LS1021A
+    - drm/msm/dpu: on SDM845 move DSPP_3 to LM_5 block
+    - drm/msm/dpu: drop LM_3 / LM_4 on SDM845
+    - drm/msm/dpu: drop LM_3 / LM_4 on MSM8998
+    - selftests/bpf: fix test_spin_lock_fail.c's global vars usage
+    - drm/panfrost: Remove unused id_mask from struct panfrost_model
+    - bpf, arm64: Remove garbage frame for struct_ops trampoline
+    - drm/msm/adreno: Use IRQF_NO_AUTOEN flag in request_irq()
+    - drm/msm/gpu: Check the status of registration to PM QoS
+    - drm/etnaviv: Request pages from DMA32 zone on addressing_limited
+    - drm/etnaviv: hold GPU lock across perfmon sampling
+    - wifi: wfx: Fix error handling in wfx_core_init()
+    - drm/msm/dpu: cast crtc_clk calculation to u64 in _dpu_core_perf_calc_clk()
+    - bpf, bpftool: Fix incorrect disasm pc
+    - drm/vkms: Drop unnecessary call to drm_crtc_cleanup()
+    - drm: use ATOMIC64_INIT() for atomic64_t
+    - netfilter: nf_tables: avoid false-positive lockdep splat on rule deletion
+    - netfilter: nf_tables: must hold rcu read lock while iterating expression
+      type list
+    - netfilter: nf_tables: skip transaction if update object is not implemented
+    - netfilter: nf_tables: must hold rcu read lock while iterating object type
+      list
+    - netlink: typographical error in nlmsg_type constants definition
+    - selftests/bpf: Add txmsg_pass to pull/push/pop in test_sockmap
+    - selftests/bpf: Fix SENDPAGE data logic in test_sockmap
+    - selftests/bpf: Fix total_bytes in msg_loop_rx in test_sockmap
+    - selftests/bpf: Add push/pop checking for msg_verify_data in test_sockmap
+    - bpf, sockmap: Several fixes to bpf_msg_push_data
+    - bpf, sockmap: Fix sk_msg_reset_curr
+    - sock_diag: add module pointer to "struct sock_diag_handler"
+    - sock_diag: allow concurrent operations
+    - sock_diag: allow concurrent operation in sock_diag_rcv_msg()
+    - net: use unrcu_pointer() helper
+    - selftests: net: really check for bg process completion
+    - drm/amdkfd: Fix wrong usage of INIT_WORK()
+    - bpf: Force uprobe bpf program to always return 0
+    - net: rfkill: gpio: Add check for clk_enable()
+    - netpoll: Use rcu_access_pointer() in netpoll_poll_lock
+    - wireguard: selftests: load nf_conntrack if not present
+    - cppc_cpufreq: Use desired perf if feedback ctrs are 0 or unchanged
+    - clk: mediatek: drop two dead config options
+    - [Config] drop COMMON_CLK_MT8195_AUDSYS and COMMON_CLK_MT8195_MSDC
+    - trace/trace_event_perf: remove duplicate samples on the first tracepoint
+      event
+    - pinctrl: zynqmp: drop excess struct member description
+    - scsi: hisi_sas: Enable all PHYs that are not disabled by user during
+      controller reset
+    - mfd: tps65010: Use IRQF_NO_AUTOEN flag in request_irq() to fix race
+    - mfd: da9052-spi: Change read-mask to write-mask
+    - cpufreq: loongson2: Unregister platform_driver on failure
+    - powerpc/fadump: Refactor and prepare fadump_cma_init for late init
+    - mtd: hyperbus: rpc-if: Add missing MODULE_DEVICE_TABLE
+    - mtd: rawnand: atmel: Fix possible memory leak
+    - mtd: rawnand: fix double free in atmel_pmecc_create_user()
+    - mtd: spi-nor: spansion: Use nor->addr_nbytes in octal DTR mode in
+      RD_ANY_REG_OP
+    - RDMA/hns: Fix an AEQE overflow error caused by untimely update of eq_db_ci
+    - RDMA/hns: Use dev_* printings in hem code instead of ibdev_*
+    - RDMA/bnxt_re: Check cqe flags to know imm_data vs inv_irkey
+    - clk: sunxi-ng: d1: Fix PLL_AUDIO0 preset
+    - clk: renesas: rzg2l: Fix FOUTPOSTDIV clk
+    - RDMA/rxe: Set queue pair cur_qp_state when being queried
+    - RISC-V: KVM: Fix APLIC in_clrip and clripnum write emulation
+    - clk: imx: lpcg-scu: SW workaround for errata (e10858)
+    - clk: imx: fracn-gppll: correct PLL initialization flow
+    - clk: imx: fracn-gppll: fix pll power up
+    - clk: imx: clk-scu: fix clk enable state save and restore
+    - clk: imx: imx8-acm: Fix return value check in
+      clk_imx_acm_attach_pm_domains()
+    - iommu/vt-d: Fix checks and print in dmar_fault_dump_ptes()
+    - iommu/vt-d: Fix checks and print in pgtable_walk()
+    - checkpatch: check for missing Fixes tags
+    - checkpatch: always parse orig_commit in fixes tag
+    - mfd: rt5033: Fix missing regmap_del_irq_chip()
+    - fs/proc/kcore.c: fix coccinelle reported ERROR instances
+    - scsi: fusion: Remove unused variable 'rc'
+    - scsi: sg: Enable runtime power management
+    - x86/tdx: Introduce wrappers to read and write TD metadata
+    - x86/tdx: Rename tdx_parse_tdinfo() to tdx_setup()
+    - x86/tdx: Dynamically disable SEPT violations from causing #VEs
+    - RDMA/hns: Fix out-of-order issue of requester when setting FENCE
+    - cpufreq: CPPC: Fix wrong return value in cppc_get_cpu_cost()
+    - cpufreq: CPPC: Fix wrong return value in cppc_get_cpu_power()
+    - dax: delete a stale directory pmem
+    - KVM: PPC: Book3S HV: Stop using vc->dpdes for nested KVM guests
+    - KVM: PPC: Book3S HV: Avoid returning to nested hypervisor on pending
+      doorbells
+    - powerpc/sstep: make emulate_vsx_load and emulate_vsx_store static
+    - powerpc/kexec: Fix return of uninitialized variable
+    - IB/mlx5: Allocate resources just before first QP/SRQ is created
+    - clk: ralink: mtmips: fix clock plan for Ralink SoC RT3883
+    - clk: ralink: mtmips: remove duplicated 'xtal' clock for Ralink SoC RT3883
+    - dt-bindings: clock: axi-clkgen: include AXI clk
+    - clk: clk-axi-clkgen: make sure to enable the AXI bus clock
+    - arm64: dts: qcom: sc8180x: Add a SoC-specific compatible to cpufreq-hw
+    - pinctrl: k210: Undef K210_PC_DEFAULT
+    - smb: cached directories can be more than root file handle
+    - mailbox: arm_mhuv2: clean up loop in get_irq_chan_comb()
+    - perf cs-etm: Don't flush when packet_queue fills up
+    - gfs2: Get rid of gfs2_glock_queue_put in signal_our_withdraw
+    - gfs2: Replace gfs2_glock_queue_put with gfs2_glock_put_async
+    - gfs2: Rename GLF_VERIFY_EVICT to GLF_VERIFY_DELETE
+    - gfs2: Allow immediate GLF_VERIFY_DELETE work
+    - gfs2: Fix unlinked inode cleanup
+    - perf stat: Close cork_fd when create_perf_stat_counter() failed
+    - perf stat: Fix affinity memory leaks on error path
+    - perf trace: Keep exited threads for summary
+    - perf test attr: Add back missing topdown events
+    - f2fs: compress: fix inconsistent update of i_blocks in
+      release_compress_blocks and reserve_compress_blocks
+    - perf probe: Fix libdw memory leak
+    - perf probe: Correct demangled symbols in C++ program
+    - rust: macros: fix documentation of the paste! macro
+    - PCI: cpqphp: Use PCI_POSSIBLE_ERROR() to check config reads
+    - PCI: cpqphp: Fix PCIBIOS_* return value confusion
+    - perf ftrace latency: Fix unit on histogram first entry when using --use-nsec
+    - f2fs: fix the wrong f2fs_bug_on condition in f2fs_do_replace_block
+    - f2fs: check curseg->inited before write_sum_page in change_curseg
+    - f2fs: fix to avoid use GC_AT when setting gc_mode as GC_URGENT_LOW or
+      GC_URGENT_MID
+    - PCI: cadence: Extract link setup sequence from cdns_pcie_host_setup()
+    - PCI: cadence: Set cdns_pcie_host_init() global
+    - PCI: j721e: Add reset GPIO to struct j721e_pcie
+    - PCI: j721e: Use T_PERST_CLK_US macro
+    - PCI: j721e: Add suspend and resume support
+    - PCI: j721e: Deassert PERST# after a delay of PCIE_T_PVPERL_MS milliseconds
+    - f2fs: fix to avoid forcing direct write to use buffered IO on inline_data
+      inode
+    - perf trace: avoid garbage when not printing a trace event's arguments
+    - m68k: mcfgpio: Fix incorrect register offset for CONFIG_M5441x
+    - m68k: coldfire/device.c: only build FEC when HW macros are defined
+    - perf list: Fix topic and pmu_name argument order
+    - perf trace: Fix tracing itself, creating feedback loops
+    - perf trace: Do not lose last events in a race
+    - perf trace: Avoid garbage when not printing a syscall's arguments
+    - remoteproc: qcom: pas: add minidump_id to SM8350 resources
+    - rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name length
+    - remoteproc: qcom_q6v5_mss: Re-order writes to the IMEM region
+    - nfsd: restore callback functionality for NFSv4.0
+    - NFSD: Cap the number of bytes copied by nfs4_reset_recoverydir()
+    - NFSD: Fix nfsd4_shutdown_copy()
+    - hwmon: (tps23861) Fix reporting of negative temperatures
+    - vdpa/mlx5: Fix suboptimal range on iotlb iteration
+    - selftests/mount_setattr: Fix failures on 64K PAGE_SIZE kernels
+    - gpio: zevio: Add missed label initialisation
+    - fs_parser: update mount_api doc to match function signature
+    - LoongArch: Fix build failure with GCC 15 (-std=gnu23)
+    - LoongArch: BPF: Sign-extend return values
+    - power: supply: core: Remove might_sleep() from power_supply_put()
+    - power: supply: bq27xxx: Fix registers of bq27426
+    - power: supply: rt9471: Fix wrong WDT function regfield declaration
+    - power: supply: rt9471: Use IC status regfield to report real charger status
+    - net: usb: lan78xx: Fix memory leak on device unplug by freeing PHY device
+    - tg3: Set coherent DMA mask bits to 31 for BCM57766 chipsets
+    - net: usb: lan78xx: Fix refcounting and autosuspend on invalid WoL
+      configuration
+    - net: microchip: vcap: Add typegroup table terminators in kunit tests
+    - net/ipv6: delete temporary address if mngtmpaddr is removed or unmanaged
+    - net: mdio-ipq4019: add missing error check
+    - marvell: pxa168_eth: fix call balance of pep->clk handling routines
+    - net: stmmac: dwmac-socfpga: Set RX watchdog interrupt as broken
+    - octeontx2-af: RPM: Fix mismatch in lmac type
+    - octeontx2-af: RPM: Fix low network performance
+    - octeontx2-pf: Reset MAC stats during probe
+    - octeontx2-af: RPM: fix stale RSFEC counters
+    - octeontx2-af: RPM: fix stale FCFEC counters
+    - octeontx2-af: Quiesce traffic before NIX block reset
+    - spi: atmel-quadspi: Fix register name in verbose logging function
+    - net: hsr: fix hsr_init_sk() vs network/transport headers.
+    - bnxt_en: Reserve rings after PCIe AER recovery if NIC interface is down
+    - bnxt_en: Refactor bnxt_ptp_init()
+    - bnxt_en: Unregister PTP during PCI shutdown and suspend
+    - llc: Improve setsockopt() handling of malformed user input
+    - rxrpc: Improve setsockopt() handling of malformed user input
+    - tcp: Fix use-after-free of nreq in reqsk_timer_handler().
+    - ip6mr: fix tables suspicious RCU usage
+    - ipmr: fix tables suspicious RCU usage
+    - iio: light: al3010: Fix an error handling path in al3010_probe()
+    - usb: using mutex lock and supporting O_NONBLOCK flag in iowarrior_read()
+    - usb: yurex: make waiting on yurex_write interruptible
+    - USB: chaoskey: fail open after removal
+    - USB: chaoskey: Fix possible deadlock chaoskey_list_lock
+    - misc: apds990x: Fix missing pm_runtime_disable()
+    - counter: stm32-timer-cnt: Add check for clk_enable()
+    - counter: ti-ecap-capture: Add check for clk_enable()
+    - ALSA: hda/realtek: Update ALC256 depop procedure
+    - drm/radeon: add helper rdev_to_drm(rdev)
+    - drm/radeon: change rdev->ddev to rdev_to_drm(rdev)
+    - drm/radeon: Fix spurious unplug event on radeon HDMI
+    - apparmor: fix 'Do simple duplicate message elimination'
+    - ASoC: amd: yc: Fix for enabling DMIC on acp6x via _DSD entry
+    - gfs2: Don't set GLF_LOCK in gfs2_dispose_glock_lru
+    - gfs2: Remove and replace gfs2_glock_queue_work
+    - f2fs: fix fiemap failure issue when page size is 16KB
+    - usb: ehci-spear: fix call balance of sehci clk handling routines
+    - ALSA: usb-audio: Fix a DMA to stack memory bug
+    - ASoC: Intel: sst: Fix used of uninitialized ctx to log an error
+    - soc: qcom: socinfo: fix revision check in qcom_socinfo_probe()
+    - ext4: supress data-race warnings in ext4_free_inodes_{count,set}()
+    - ext4: fix FS_IOC_GETFSMAP handling
+    - jfs: xattr: check invalid xattr size more strictly
+    - ASoC: amd: yc: Add a quirk for microfone on Lenovo ThinkPad P14s Gen 5
+      21MES00B00
+    - ASoC: codecs: Fix atomicity violation in snd_soc_component_get_drvdata()
+    - perf/x86/intel/pt: Fix buffer full but size is 0 case
+    - crypto: x86/aegis128 - access 32-bit arguments as 32-bit
+    - KVM: x86/mmu: Skip the "try unsync" path iff the old SPTE was a leaf SPTE
+    - powerpc/pseries: Fix KVM guest detection for disabling hardlockup detector
+    - KVM: arm64: vgic-v3: Sanitise guest writes to GICR_INVLPIR
+    - KVM: arm64: Ignore PMCNTENSET_EL0 while checking for overflow status
+    - KVM: arm64: vgic-its: Clear ITE when DISCARD frees an ITE
+    - KVM: arm64: vgic-its: Add a data length check in vgic_its_save_*
+    - KVM: arm64: vgic-its: Clear DTE when MAPD unmaps a device
+    - fsnotify: fix sending inotify event with unexpected filename
+    - tty: ldsic: fix tty_ldisc_autoload sysctl's proc_handler
+    - locking/lockdep: Avoid creating new name string literals in
+      lockdep_set_subclass()
+    - tools/nolibc: s390: include std.h
+    - pinctrl: qcom: spmi: fix debugfs drive strength
+    - dt-bindings: iio: dac: ad3552r: fix maximum spi speed
+    - exfat: fix uninit-value in __exfat_get_dentry_set
+    - Bluetooth: Fix type of len in rfcomm_sock_getsockopt{,_old}()
+    - Compiler Attributes: disable __counted_by for clang < 19.1.3
+    - usb: xhci: Fix TD invalidation under pending Set TR Dequeue
+    - ARM: dts: omap36xx: declare 1GHz OPP as turbo again
+    - wifi: brcmfmac: release 'root' node in all execution paths
+    - Revert "usb: gadget: composite: fix OS descriptors w_value logic"
+    - gpio: exar: set value when external pull-up or pull-down is present
+    - spi: Fix acpi deferred irq probe
+    - cpufreq: mediatek-hw: Fix wrong return value in mtk_cpufreq_get_cpu_power()
+    - cifs: support mounting with alternate password to allow password rotation
+    - parisc/ftrace: Fix function graph tracing disablement
+    - platform/chrome: cros_ec_typec: fix missing fwnode reference decrement
+    - ubi: wl: Put source PEB into correct list if trying locking LEB failed
+    - dt-bindings: serial: rs485: Fix rs485-rts-delay property
+    - serial: 8250_fintek: Add support for F81216E
+    - serial: 8250: omap: Move pm_runtime_get_sync
+    - iio: gts: Fix uninitialized symbol 'ret'
+    - ublk: fix ublk_ch_mmap() for 64K page size
+    - arm64: tls: Fix context-switching of tpidrro_el0 when kpti is enabled
+    - block: fix missing dispatching request when queue is started or unquiesced
+    - block: fix ordering between checking QUEUE_FLAG_QUIESCED request adding
+    - block: fix ordering between checking BLK_MQ_S_STOPPED request adding
+    - blk-mq: Make blk_mq_quiesce_tagset() hold the tag list mutex less long
+    - HID: wacom: Interpret tilt data from Intuos Pro BT as signed values
+    - soc: fsl: rcpm: fix missing of_node_put() in copy_ippdexpcr1_setting()
+    - media: v4l2-core: v4l2-dv-timings: check cvt/gtf result
+    - ALSA: ump: Fix evaluation of MIDI 1.0 FB info
+    - ALSA: hda/realtek: Update ALC225 depop procedure
+    - ALSA: hda/realtek: Fixup ALC225 depop procedure
+    - ALSA: hda/realtek: Set PCBeep to default value for ALC274
+    - ALSA: hda/realtek: Fix Internal Speaker and Mic boost of Infinix Y4 Max
+    - ALSA: hda/realtek: Apply quirk for Medion E15433
+    - smb3: request handle caching when caching directories
+    - smb: client: handle max length for SMB symlinks
+    - cifs: Add tracing for the cifs_tcon struct refcounting
+    - usb: dwc3: gadget: Fix checking for number of TRBs left
+    - ublk: fix error code for unsupported command
+    - lib: string_helpers: silence snprintf() output truncation warning
+    - um: Fix the return value of elf_core_copy_task_fpregs
+    - um: Always dump trace for specified task in show_stack
+    - rtc: st-lpc: Use IRQF_NO_AUTOEN flag in request_irq()
+    - rtc: abx80x: Fix WDT bit position of the status register
+    - ubi: fastmap: wl: Schedule fm_work if wear-leveling pool is empty
+    - ubifs: Correct the total block count by deducting journal reservation
+    - jffs2: fix use of uninitialized variable
+    - rtc: rzn1: fix BCD to rtc_time conversion errors
+    - nvme-multipath: prepare for "queue-depth" iopolicy
+    - nvme-multipath: implement "queue-depth" iopolicy
+    - nvme-multipath: avoid hang on inaccessible namespaces
+    - nvme/multipath: Fix RCU list traversal to use SRCU primitive
+    - block: return unsigned int from bdev_io_min
+    - 9p/xen: fix init sequence
+    - perf/arm-smmuv3: Fix lockdep assert in ->event_init()
+    - perf/arm-cmn: Ensure port and device id bits are set properly
+    - smb: client: disable directory caching when dir_cache_timeout is zero
+    - cifs: Fix parsing native symlinks relative to the export
+    - cifs: Fix parsing reparse point with native symlink in SMB1 non-UNICODE
+      session
+    - rtc: ab-eoz9: don't fail temperature reads on undervoltage notification
+    - init/modpost: conditionally check section mismatch to __meminit*
+    - Rename .data.unlikely to .data..unlikely
+    - Rename .data.once to .data..once to fix resetting WARN*_ONCE
+    - modpost: remove incorrect code in do_eisa_entry()
+    - cifs: during remount, make sure passwords are in sync
+    - cifs: unlock on error in smb3_reconfigure()
+    - nfs: ignore SB_RDONLY when mounting nfs
+    - SUNRPC: timeout and cancel TLS handshake with -ETIMEDOUT
+    - xfs: remove unknown compat feature check in superblock write validation
+    - btrfs: don't loop for nowait writes when checking for cross references
+    - md/md-bitmap: Add missing destroy_work_on_stack()
+    - arm64: dts: allwinner: pinephone: Add mount matrix to accelerometer
+    - arm64: dts: freescale: imx8mm-verdin: Fix SD regulator startup delay
+    - arm64: dts: ti: k3-am62-verdin: Fix SD regulator startup delay
+    - media: i2c: dw9768: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - arm64: dts: freescale: imx8mp-verdin: Fix SD regulator startup delay
+    - media: imx-jpeg: Fix potential error pointer dereference in detach_pm()
+    - media: verisilicon: av1: Fix reference video buffer pointer assignment
+    - media: platform: exynos4-is: Fix an OF node reference leak in
+      fimc_md_is_isp_available
+    - media: amphion: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - media: venus: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - media: gspca: ov534-ov772x: Fix off-by-one error in set_frame_rate()
+    - media: uvcvideo: Stop stream during unregister
+    - maple_tree: refine mas_store_root() on storing NULL
+    - vmstat: call fold_vm_zone_numa_events() before show per zone NUMA event
+    - zram: clear IDLE flag after recompression
+    - iommu/io-pgtable-arm: Fix stage-2 map/unmap for concatenated tables
+    - leds: lp55xx: Remove redundant test for invalid channel number
+    - clk: qcom: gcc-qcs404: fix initial rate of GPLL3
+    - ARM: 9429/1: ioremap: Sync PGDs for VMALLOC shadow
+    - ARM: 9430/1: entry: Do a dummy read from VMAP shadow
+    - ARM: 9431/1: mm: Pair atomic_set_release() with _read_acquire()
+    - ceph: extract entity name from device id
+    - util_macros.h: fix/rework find_closest() macros
+    - scsi: ufs: exynos: Fix hibern8 notify callbacks
+    - i3c: master: svc: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - PCI: keystone: Set mode as Root Complex for "ti,keystone-pcie" compatible
+    - PCI: keystone: Add link up check to ks_pcie_other_map_bus()
+    - PCI: endpoint: Clear secondary (not primary) EPC in pci_epc_remove_epf()
+    - fs/proc/kcore.c: Clear ret value in read_kcore_iter after successful
+      iov_iter_zero
+    - thermal: int3400: Fix reading of current_uuid for active policy
+    - leds: flash: mt6360: Fix device_for_each_child_node() refcounting in error
+      paths
+    - ovl: properly handle large files in ovl_security_fileattr
+    - dm: Fix typo in error message
+    - dm thin: Add missing destroy_work_on_stack()
+    - PCI: of_property: Assign PCI instead of CPU bus address to dynamic PCI nodes
+    - PCI: rockchip-ep: Fix address translation unit programming
+    - iio: accel: kx022a: Fix raw read format
+    - iio: Fix fwnode_handle in __fwnode_iio_channel_get_by_name()
+    - iio: gts: fix infinite loop for gain_to_scaletables()
+    - powerpc: Fix stack protector Kconfig test for clang
+    - powerpc: Adjust adding stack protector flags to KBUILD_CLAGS for clang
+    - udmabuf: use vmf_insert_pfn and VM_PFNMAP for handling mmap
+    - drm/mediatek: Fix child node refcount handling in early exit
+    - drm/etnaviv: flush shader L1 cache after user commandstream
+    - drm: xlnx: zynqmp_dpsub: fix hotplug detection
+    - drm/amdkfd: Use the correct wptr size
+    - drm/amd/pm: update current_socclk and current_uclk in gpu_metrics on smu
+      v13.0.7
+    - posix-timers: Target group sigqueue to current task only if not exiting
+    - wifi: cfg80211: Add wiphy_delayed_work_pending()
+    - wifi: mac80211: Convert color collision detection to wiphy work
+    - spi: stm32: fix missing device mode capability in stm32mp25
+    - usb: typec: use cleanup facility for 'altmodes_node'
+    - platform/x86: ideapad-laptop: add missing Ideapad Pro 5 fn keys
+    - integrity: Avoid -Wflex-array-member-not-at-end warnings
+    - integrity: Use static_assert() to check struct sizes
+    - ASoC: max9768: Fix event generation for playback mute
+    - ARM: 9434/1: cfi: Fix compilation corner case
+    - drm/amd/display: Skip Invalid Streams from DSC Policy
+    - drm/amd/display: Fix DSC-re-computing
+    - drm/amd/display: Fix incorrect DSC recompute trigger
+    - s390/facilities: Fix warning about shadow of global variable
+    - cachefiles: Fix incorrect length return value in
+      cachefiles_ondemand_fd_write_iter()
+    - thermal: core: Drop thermal_zone_device_is_enabled()
+    - thermal: core: Synchronize suspend-prepare and post-suspend actions
+    - thermal: core: Rearrange PM notification code
+    - thermal: core: Represent suspend-related thermal zone flags as bits
+    - thermal: core: Mark thermal zones as initializing to start with
+    - thermal: core: Fix race between zone registration and system suspend
+    - crypto: qat - Fix missing destroy_workqueue in adf_init_aer()
+    - sched/cpufreq: Ensure sd is rebuilt for EAS check
+    - cleanup: Remove address space of returned pointer
+    - ARM: dts: renesas: genmai: Fix partition size for QSPI NOR Flash
+    - arm64: dts: mediatek: mt8395-genio-1200-evk: Fix dtbs_check error for phy
+    - scripts/kernel-doc: Do not track section counter across processed files
+    - arm64: dts: qcom: x1e80100: Resize GIC Redistributor register region
+    - scripts/kernel-doc: add modeline for vim users
+    - scripts/kernel-doc: simplify function printing
+    - scripts/kernel-doc: separate out function signature
+    - scripts/kernel-doc: simplify signature printing
+    - doc: kerneldoc.py: fix indentation
+    - kernel-doc: allow object-like macros in ReST output
+    - arm64: dts: mediatek: mt8188: Fix USB3 PHY port default status
+    - arm64: dts: rockchip: Remove 'enable-active-low' from two boards
+    - arm64: dts: qcom: x1e80100: Update C4/C5 residency/exit numbers
+    - dt-bindings: cache: qcom,llcc: Fix X1E80100 reg entries
+    - pwm: Assume a disabled PWM to emit a constant inactive output
+    - drm/imagination: Convert to use time_before macro
+    - drm/imagination: Use pvr_vm_context_get()
+    - drm/v3d: Flush the MMU before we supply more memory to the binner
+    - drm/amdgpu: Fix JPEG v4.0.3 register write
+    - ASoC: fsl-asoc-card: Add missing handling of {hp,mic}-dt-gpios
+    - wifi: rtl8xxxu: Perform update_beacon_work when beaconing is enabled
+    - selftests/bpf: netns_new() and netns_free() helpers.
+    - selftests/bpf: Fix backtrace printing for selftests crashes
+    - selftests/bpf: add missing header include for htons
+    - drm/vc4: hdmi: Increase audio MAI fifo dreq threshold
+    - drm/vc4: Introduce generation number enum
+    - drm/vc4: Match drm_dev_enter and exit calls in vc4_hvs_lut_load
+    - drm/vc4: Correct generation check in vc4_hvs_lut_load
+    - bpf: Tighten tail call checks for lingering locks, RCU, preempt_disable
+    - drm/panfrost: Add missing OPP table refcnt decremental
+    - selftests: netfilter: Fix missing return values in conntrack_dump_flush
+    - Bluetooth: btintel: Do no pass vendor events to stack
+    - Bluetooth: btbcm: fix missing of_node_put() in btbcm_get_board_name()
+    - Bluetooth: ISO: Use kref to track lifetime of iso_conn
+    - Bluetooth: ISO: Do not emit LE PA Create Sync if previous is pending
+    - Bluetooth: hci_conn: Use __counted_by() to avoid -Wfamnae warning
+    - Bluetooth: hci_conn: Use struct_size() in hci_le_big_create_sync()
+    - Bluetooth: ISO: Do not emit LE BIG Create Sync if previous is pending
+    - Bluetooth: ISO: Send BIG Create Sync via hci_sync
+    - Bluetooth: iso: Fix circular lock in iso_conn_big_sync
+    - net: txgbe: remove GPIO interrupt controller
+    - net: txgbe: fix null pointer to pcs
+    - RDMA/core: Provide rdma_user_mmap_disassociate() to disassociate mmap pages
+    - RDMA/hns: Disassociate mmap pages for all uctx when HW is being reset
+    - iommu/amd: Remove amd_iommu_domain_update() from page table freeing
+    - iommu/amd/pgtbl_v2: Take protection domain lock before invalidating TLB
+    - RDMA/hns: Fix flush cqe error when racing with destroy qp
+    - RDMA/hns: Modify debugfs name
+    - leds: max5970: Fix unreleased fwnode_handle in probe function
+    - kasan: move checks to do_strncpy_from_user
+    - kunit: skb: use "gfp" variable instead of hardcoding GFP_KERNEL
+    - RDMA/hns: Fix different dgids mapping to the same dip_idx
+    - RDMA/hns: Fix accessing invalid dip_ctx during destroying QP
+    - rust: kernel: add srctree-relative doclinks
+    - rust: kernel: fix THIS_MODULE header path in ThisModule doc comment
+    - i3c: master: Remove i3c_dev_disable_ibi_locked(olddev) on device hotjoin
+    - remoteproc: qcom: pas: Remove subdevs on the error path of adsp_probe()
+    - remoteproc: qcom: adsp: Remove subdevs on the error path of adsp_probe()
+    - nfsd: Revert "nfsd: release svc_expkey/svc_export with rcu_work"
+    - f2fs: clean up val{>>,<<}F2FS_BLKSIZE_BITS
+    - f2fs: fix to do cast in F2FS_{BLK_TO_BYTES, BTYES_TO_BLK} to avoid overflow
+    - vfio/mlx5: Fix unwind flows in mlx5vf_pci_save/resume_device_data()
+    - exfat: fix file being changed by unaligned direct write
+    - bnxt_en: Set backplane link modes correctly for ethtool
+    - devres: Fix page faults when tracing devres from unloaded modules
+    - usb: gadget: uvc: wake pump everytime we update the free list
+    - drm/xe/ufence: Wake up waiters after setting ufence->signalled
+    - net_sched: sch_fq: don't follow the fast path if Tx is behind now
+    - ASoC: da7213: Populate max_register to regmap_config
+    - KVM: x86: switch hugepage recovery thread to vhost_task
+    - kvm: defer huge page recovery vhost task to later
+    - KVM: x86/mmu: Ensure NX huge page recovery thread is alive before waking
+    - KVM: arm64: Change kvm_handle_mmio_return() return polarity
+    - dt-bindings: pinctrl: samsung: Fix interrupt constraint for variants with
+      fallbacks
+    - xhci: Fix control transfer error on Etron xHCI host
+    - xhci: Combine two if statements for Etron xHCI host
+    - xhci: Don't perform Soft Retry for Etron xHCI host
+    - xhci: Don't issue Reset Device command to Etron xHCI host
+    - mtd: spi-nor: core: replace dummy buswidth from addr to data
+    - Revert "mtd: spi-nor: core: replace dummy buswidth from addr to data"
+    - RISC-V: Scalar unaligned access emulated on hotplug CPUs
+    - serial: amba-pl011: Fix RX stall when DMA is used
+    - serial: amba-pl011: fix build regression
+    - i40e: Fix handling changed priv flags
+    - netdev-genl: Hold rcu_read_lock in napi_get
+    - usb: misc: ljca: set small runtime autosuspend delay
+    - usb: misc: ljca: move usb_autopm_put_interface() after wait for response
+    - blk-mq: add non_owner variant of start_freeze/unfreeze queue APIs
+    - block: model freeze & enter queue as lock for supporting lockdep
+    - block: always verify unfreeze lock on the owner task
+    - x86/Documentation: Update algo in init_size description of boot protocol
+    - kbuild: deb-pkg: Don't fail if modules.order is missing
+    - tools/power turbostat: Fix trailing '\n' parsing
+    - block: don't verify IO lock for freeze/unfreeze in elevator_init_mq()
+    - zram: permit only one post-processing operation at a time
+    - perf jevents: Don't stop at the first matched pmu when searching a events
+      table
+    - docs: media: update location of the media patches
+    - Revert "KVM: VMX: Move LOAD_IA32_PERF_GLOBAL_CTRL errata handling out of
+      setup_vmcs_config()"
+    - soc: fsl: cpm1: qmc: Fix blank line and spaces
+    - soc: fsl: cpm1: qmc: Re-order probe() operations
+    - soc: fsl: cpm1: qmc: Introduce qmc_init_resource() and its CPM1 version
+    - soc: fsl: cpm1: qmc: Introduce qmc_{init,exit}_xcc() and their CPM1 version
+    - soc: fsl: cpm1: qmc: Set the ret error code on platform_get_irq() failure
+    - x86/mm: Carve out INVLPG inline asm for use by others
+    - ALSA: hda/realtek: Enable mic on Vaio VJFH52
+    - ALSA: hda/realtek: Enable speaker pins for Medion E15443 platform
+    - ALSA: hda/realtek: fix mute/micmute LEDs don't work for EliteBook X G1i
+    - usb: dwc3: gadget: Add missing check for single port RAM in TxFIFO resizing
+      logic
+    - sched: Initialize idle tasks only once
+    - Upstream stable to v6.6.64, v6.11.11, v6.12.1, v6.12.2, v6.12.3
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53222
+    - zram: fix NULL pointer in comp_algorithm_show()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53169
+    - nvme-fabrics: fix kernel crash while shutting down controller
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56721
+    - x86/CPU/AMD: Terminate the erratum_1386_microcode array
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53187
+    - io_uring: check for overflows in io_pin_pages
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53147
+    - exfat: fix out-of-bounds access of directory entries
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53196
+    - KVM: arm64: Don't retire aborted MMIO instruction
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56685
+    - ASoC: mediatek: Check num_codecs is not zero to avoid panic during probe
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53201
+    - drm/amd/display: Fix null check for pipe_ctx->plane_state in
+      dcn20_program_pipe
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53203
+    - usb: typec: fix potential array underflow in ucsi_ccg_sync_control()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53209
+    - bnxt_en: Fix receive ring space parameters when XDP is active
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56742
+    - vfio/mlx5: Fix an unwind issue in mlx5vf_add_migration_pages()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53216
+    - nfsd: release svc_expkey/svc_export with rcu_work
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53219
+    - virtiofs: use pages instead of pointer for kernel direct IO
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53221
+    - f2fs: fix null-ptr-deref in f2fs_submit_page_bio()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53228
+    - riscv: kvm: Fix out-of-bounds array access
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53232
+    - iommu/s390: Implement blocking domain
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53236
+    - xsk: Free skb when TX metadata options are invalid
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56703
+    - ipv6: Fix soft lockups in fib6_select_path under high next hop churn
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56540
+    - accel/ivpu: Prevent recovery invocation during probe and resume
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53163
+    - crypto: qat/qat_420xx - fix off by one in uof_get_name()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56755
+    - netfs/fscache: Add a memory barrier for FSCACHE_VOLUME_CREATING
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56549
+    - cachefiles: Fix NULL pointer dereference in object->file
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56551
+    - drm/amdgpu: fix usage slab after free
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56776
+    - drm/sti: avoid potential dereference of error pointers
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56777
+    - drm/sti: avoid potential dereference of error pointers in
+      sti_gdp_atomic_check
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56778
+    - drm/sti: avoid potential dereference of error pointers in
+      sti_hqvdp_atomic_check
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56557
+    - iio: adc: ad7923: Fix buffer overflow for tx_buf and ring_xfer
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56779
+    - nfsd: fix nfs4_openowner leak when concurrent nfsd4_open occur
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56558
+    - nfsd: make sure exp active before svc_export_show
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56562
+    - i3c: master: Fix miss free init_dyn_addr at i3c_master_put_i3c_addrs()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56566
+    - mm/slub: Avoid list corruption when removing a slab from the full list
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-57838
+    - s390/entry: Mark IRQ entries to fix stack depot warnings
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56567
+    - ad7780: fix division by zero in ad7780_write_raw()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56569
+    - ftrace: Fix regression with module command in stack_trace_filter
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56570
+    - ovl: Filter invalid inodes with missing lookup function
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56572
+    - media: platform: allegro-dvt: Fix possible memory leak in
+      allocate_buffers_internal()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56573
+    - efi/libstub: Free correct pointer on failure
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56574
+    - media: ts2020: fix null-ptr-deref in ts2020_probe()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56575
+    - media: imx-jpeg: Ensure power suppliers be suspended before detach them
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56576
+    - media: i2c: tc358743: Fix crash in the probe error path when using polling
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56577
+    - media: mtk-jpeg: Fix null-ptr-deref during unload module
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56578
+    - media: imx-jpeg: Set video drvdata before register video device
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56579
+    - media: amphion: Set video drvdata before register video device
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56581
+    - btrfs: ref-verify: fix use-after-free after invalid ref action
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56774
+    - btrfs: add a sanity check for btrfs root in btrfs_search_slot()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56780
+    - quota: flush quota_release_work upon quota writeback
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53168
+    - sunrpc: fix one UAF issue caused by sunrpc kernel tcp socket
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56688
+    - sunrpc: clear XPRT_SOCK_UPD_TIMEOUT when reset transport
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56729
+    - smb: Initialize cfid->tcon before performing network ops
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56704
+    - 9p/xen: fix release of IRQ
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53171
+    - ubifs: authentication: Fix use-after-free in ubifs_tnc_end_commit
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53172
+    - ubi: fastmap: Fix duplicate slab cache names while attaching
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56739
+    - rtc: check if __rtc_read_time was successful in rtc_timer_do_work()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53173
+    - NFSv4.0: Fix a use-after-free problem in the asynchronous open()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53145
+    - um: Fix potential integer overflow during physmem setup
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53174
+    - SUNRPC: make sure cache entry active before cache_show
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53146
+    - NFSD: Prevent a potential integer overflow
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53175
+    - ipc: fix memleak if msg_init_ns failed in create_ipc_ns
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56692
+    - f2fs: fix to do sanity check on node blkaddr in truncate_node()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56698
+    - usb: dwc3: gadget: Fix looping of queued SG entries
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56687
+    - usb: musb: Fix hardware lockup on first Rx endpoint request
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53176
+    - smb: During unmount, ensure all cached dir instances drop their dentry
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53177
+    - smb: prevent use-after-free due to open_cached_dir error paths
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53178
+    - smb: Don't leak cfid when reconnect races with open_cached_dir
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53180
+    - ALSA: pcm: Add sanity NULL check for the default mmap fault handler
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56700
+    - media: wl128x: Fix atomicity violation in fmc_send_cmd()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2022-49034
+    - sh: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53181
+    - um: vector: Do not use drvdata in release
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53183
+    - um: net: Do not use drvdata in release
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53184
+    - um: ubd: Do not use drvdata in release
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53185
+    - smb: client: fix NULL ptr deref in crypto_aead_setkey()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53188
+    - wifi: ath12k: fix crash when unbinding
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53190
+    - wifi: rtlwifi: Drastically reduce the attempts to read efuse in case of
+      failures
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53191
+    - wifi: ath12k: fix warning when unbinding
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56741
+    - apparmor: test: Fix memory leak for aa_unpack_strdup()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53148
+    - comedi: Flush partial mappings in error case
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53194
+    - PCI: Fix use-after-free of slot->bus on hot remove
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53195
+    - KVM: arm64: Get rid of userspace_irqchip_in_use
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53197
+    - ALSA: usb-audio: Fix potential out-of-bound accesses for Extigy and Mbox
+      devices
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-42122
+    - drm/amd/display: Add NULL pointer check for kzalloc
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-49906
+    - drm/amd/display: Check null pointer before try to access it
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53150
+    - ALSA: usb-audio: Fix out of bounds reads when finding clock sources
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53198
+    - xen: Fix the issue of resource not being properly released in
+      xenbus_dev_probe()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-41014
+    - xfs: add bounds checking to xlog_recover_process_data
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53200
+    - drm/amd/display: Fix null check for pipe_ctx->plane_state in hwss_setup_dpp
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53202
+    - firmware_loader: Fix possible resource leak in fw_log_firmware_info()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53208
+    - Bluetooth: MGMT: Fix slab-use-after-free Read in set_powered_sync
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53210
+    - s390/iucv: MSG_PEEK causes memory leak in iucv_sock_destruct()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53213
+    - net: usb: lan78xx: Fix double free issue with interrupt buffer allocation
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53214
+    - vfio/pci: Properly hide first-in-list PCIe extended capability
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53215
+    - svcrdma: fix miss destroy percpu_counter in svc_rdma_proc_init()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53217
+    - NFSD: Prevent NULL dereference in nfsd4_process_cb_update()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56689
+    - PCI: endpoint: epf-mhi: Avoid NULL dereference if DT lacks 'mmio'
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53151
+    - svcrdma: Address an integer overflow
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53218
+    - f2fs: fix race in concurrent f2fs_stop_gc_thread
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56744
+    - f2fs: fix to avoid potential deadlock in f2fs_record_stop_reason()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53220
+    - f2fs: fix to account dirty data in __get_secs_required()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56745
+    - PCI: Fix reset_method_store() memory leak
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53223
+    - clk: ralink: mtmips: fix clocks probe order in oldest ralink SoCs
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53154
+    - clk: clk-apple-nco: Add NULL check in applnco_probe
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53224
+    - RDMA/mlx5: Move events notifier registration to be after device registration
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56746
+    - fbdev: sh7760fb: Fix a possible memory leak in sh7760fb_alloc_mem()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53155
+    - ocfs2: fix uninitialized value in ocfs2_file_read_iter()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53226
+    - RDMA/hns: Fix NULL pointer derefernce in hns_roce_map_mr_sg()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56747
+    - scsi: qedi: Fix a possible memory leak in qedi_alloc_and_init_sb()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56748
+    - scsi: qedf: Fix a possible memory leak in qedf_alloc_and_init_sb()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53229
+    - RDMA/rxe: Fix the qp flush warnings in req
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56722
+    - RDMA/hns: Fix cpu stuck caused by printings during reset
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53230
+    - cpufreq: CPPC: Fix possible null-ptr-deref for cppc_get_cpu_cost()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53231
+    - cpufreq: CPPC: Fix possible null-ptr-deref for cpufreq_cpu_get_raw()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56701
+    - powerpc/pseries: Fix dtl_access_lock to be a rw_semaphore
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56678
+    - powerpc/mm/fault: Fix kfence page fault reporting
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56677
+    - powerpc/fadump: Move fadump_cma_init to setup_arch() after initmem_init()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56723
+    - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for PMIC devices
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56724
+    - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for TMU device
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56691
+    - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for USB Type-C device
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53233
+    - unicode: Fix utf8_load() error path
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56694
+    - bpf: fix recursive lock when verdict program return SK_PASS
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53234
+    - erofs: handle NONHEAD !delta[1] lclusters gracefully
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53239
+    - ALSA: 6fire: Release resources at card release
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56531
+    - ALSA: caiaq: Use snd_card_free_when_closed() at disconnection
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56532
+    - ALSA: us122l: Use snd_card_free_when_closed() at disconnection
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56533
+    - ALSA: usx2y: Use snd_card_free_when_closed() at disconnection
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56751
+    - ipv6: release nexthop on device removal
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56720
+    - bpf, sockmap: Several fixes to bpf_msg_pop_data
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56538
+    - drm: zynqmp_kms: Unplug DRM device before removal
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56752
+    - drm/nouveau/gr/gf100: Fix missing unlock in gf100_gr_chan_new()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56725
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_dcbnl.c
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56707
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_dmac_flt.c
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56726
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in cn10k.c
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56727
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_flows.c
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56728
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56679
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_common.c
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56539
+    - wifi: mwifiex: Fix memcpy() field-spanning write warning in
+      mwifiex_config_scan()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56543
+    - wifi: ath12k: Skip Rx TID cleanup for self peer
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56683
+    - drm/vc4: hdmi: Avoid hang with debug registers when suspended
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56545
+    - HID: hyperv: streamline driver probe to avoid devres issues
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56705
+    - media: atomisp: Add check for rgby_data memory allocation failure
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53157
+    - firmware: arm_scpi: Check the DVFS OPP count returned by the firmware
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53158
+    - soc: qcom: geni-se: fix array underflow in geni_se_clk_tbl_get()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56546
+    - drivers: soc: xilinx: add the missing kfree in xlnx_add_cb_for_suspend()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56681
+    - crypto: bcm - add error check in the ahash_hmac_init function
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53160
+    - rcu/kvfree: Fix data-race in __mod_timer / kvfree_call_rcu
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56708
+    - EDAC/igen6: Avoid segmentation fault on module unload
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56690
+    - crypto: pcrypt - Call crypto layer directly when padata_do_parallel() return
+      -EBUSY
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53161
+    - EDAC/bluefield: Fix potential integer overflow
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53162
+    - crypto: qat/qat_4xxx - fix off by one in uof_get_name()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56754
+    - crypto: caam - Fix the pointer passed to caam_qi_shutdown()
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56548
+    - hfsplus: don't query the device logical block size multiple times
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56756
+    - nvme-pci: fix freeing of the HMB descriptor table
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53142
+    - initramfs: avoid filename buffer overrun
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56693
+    - brd: defer automatic disk creation until module initialization succeeds
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-44955
+    - drm/amd/display: Don't refer to dc_sink in is_dsc_need_re_compute
+
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-49899
+    - drm/amd/display: Initialize denominators' default to 1
+
+  * Noble update: upstream stable patchset 2025-03-06 (LP: #2101042)
+    - sctp: fix possible UAF in sctp_v6_available()
+    - net: vertexcom: mse102x: Fix tx_bytes calculation
+    - drm/rockchip: vop: Fix a dereferenced before check warning
+    - mptcp: error out earlier on disconnect
+    - mptcp: cope racing subflow creation in mptcp_rcv_space_adjust
+    - net/mlx5: fs, lock FTE when checking if active
+    - net/mlx5e: kTLS, Fix incorrect page refcounting
+    - net/mlx5e: clear xdp features on non-uplink representors
+    - net/mlx5e: CT: Fix null-ptr-deref in add rule err flow
+    - virtio/vsock: Fix accept_queue memory leak
+    - Bluetooth: btintel: Direct exception event to bluetooth stack
+    - net: sched: cls_u32: Fix u32's systematic failure to free IDR entries for
+      hnodes.
+    - samples: pktgen: correct dev to DEV
+    - net: stmmac: dwmac-mediatek: Fix inverted handling of mediatek,mac-wol
+    - net: Make copy_safe_from_sockptr() match documentation
+    - stmmac: dwmac-intel-plat: fix call balance of tx_clk handling routines
+    - net: ti: icssg-prueth: Fix 1 PPS sync
+    - bonding: add ns target multicast address to slave device
+    - ARM: 9419/1: mm: Fix kernel memory mapping for xip kernels
+    - x86/mm: Fix a kdump kernel failure on SME system when CONFIG_IMA_KEXEC=y
+    - mm: fix NULL pointer dereference in alloc_pages_bulk_noprof
+    - ocfs2: uncache inode which has failed entering the group
+    - vdpa: solidrun: Fix UB bug with devres
+    - vdpa/mlx5: Fix PA offset with unaligned starting iotlb map
+    - vp_vdpa: fix id_table array not null terminated error
+    - ima: fix buffer overrun in ima_eventdigest_init_common
+    - KVM: nVMX: Treat vpid01 as current if L2 is active, but with VPID disabled
+    - KVM: x86: Unconditionally set irr_pending when updating APICv state
+    - KVM: VMX: Bury Intel PT virtualization (guest/host mode) behind
+      CONFIG_BROKEN
+    - nilfs2: fix null-ptr-deref in block_touch_buffer tracepoint
+    - nommu: pass NULL argument to vma_iter_prealloc()
+    - ALSA: hda/realtek - Fixed Clevo platform headset Mic issue
+    - ocfs2: fix UBSAN warning in ocfs2_verify_volume()
+    - nilfs2: fix null-ptr-deref in block_dirty_buffer tracepoint
+    - LoongArch: Fix early_numa_add_cpu() usage for FDT systems
+    - LoongArch: Disable KASAN if PGDIR_SIZE is too large for cpu_vabits
+    - LoongArch: Make KASAN work with 5-level page-tables
+    - Revert "mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K"
+    - mmc: sunxi-mmc: Fix A100 compatible description
+    - drm/bridge: tc358768: Fix DSI command tx
+    - pmdomain: imx93-blk-ctrl: correct remove path
+    - nouveau: fw: sync dma after setup is called.
+    - drm/amd: Fix initialization mistake for NBIO 7.7.0
+    - drm/amd/display: Adjust VSDB parser for replay feature
+    - lib/buildid: Fix build ID parsing logic
+    - media: dvbdev: fix the logic when DVB_DYNAMIC_MINORS is not set
+    - mptcp: add userspace_pm_lookup_addr_by_id helper
+    - mptcp: update local address flags when setting it
+    - mptcp: hold pm lock when deleting entry
+    - mptcp: drop lookup_by_id in lookup_addr
+    - mptcp: pm: use _rcu variant under rcu_read_lock
+    - mm: avoid unsafe VMA hook invocation when error arises on mmap hook
+    - mm: unconditionally close VMAs on error
+    - mm: refactor map_deny_write_exec()
+    - mm: refactor arch_calc_vm_flag_bits() and arm64 MTE handling
+    - mm: resolve faulty mmap_region() error path behaviour
+    - net/mlx5: Fix msix vectors to respect platform limit
+    - vsock: Fix sk_error_queue memory leak
+    - virtio/vsock: Improve MSG_ZEROCOPY error handling
+    - net: phylink: ensure PHY momentary link-fails are handled
+    - drm/vmwgfx: avoid null_ptr_deref in vmw_framebuffer_surface_create_handle
+    - ARM: fix cacheflush with PAN
+    - drm/amd/display: Run idle optimizations at end of vblank handler
+    - drm/amd/display: Change some variable name of psr
+    - x86/CPU/AMD: Clear virtualized VMLOAD/VMSAVE on Zen4 client
+    - x86/stackprotector: Work around strict Clang TLS symbol requirements
+    - sched/task_stack: fix object_is_on_stack() for KASAN tagged pointers
+    - fs/proc/task_mmu: prevent integer overflow in pagemap_scan_get_args()
+    - mm/mremap: fix address wraparound in move_page_tables()
+    - KVM: selftests: Disable strict aliasing
+    - mm: page_alloc: move mlocked flag clearance into free_pages_prepare()
+    - LoongArch: Add WriteCombine shadow mapping in KASAN
+    - drm/xe: handle flat ccs during hibernation on igpu
+    - pmdomain: arm: Use FLAG_DEV_NAME_FW to ensure unique names
+    - pmdomain: core: Add GENPD_FLAG_DEV_NAME_FW flag
+    - nouveau: handle EBUSY and EAGAIN for GSP aux errors.
+    - nouveau/dp: handle retries for AUX CH transfers with GSP.
+    - drm/amdgpu: fix check in gmc_v9_0_get_vm_pte()
+    - drm/amdgpu: Fix video caps for H264 and HEVC encode maximum size
+    - drm/amd/pm: print pp_dpm_mclk in ascending order on SMU v14.0.0
+    - drm/amd/display: Handle dml allocation failure to avoid crash
+    - drm/amd/display: Fix failure to read vram info due to static BP_RESULT
+    - drm/xe: Restore system memory GGTT mappings
+    - drm/xe: improve hibernation on igpu
+    - net: sched: u32: Add test case for systematic hnode IDR leaks
+    - Upstream stable to v6.6.63, v6.11.10
+
+  * Noble update: upstream stable patchset 2025-03-04 (LP: #2100894)
+    - 9p: v9fs_fid_find: also lookup by inode if not found dentry
+    - 9p: Avoid creating multiple slab caches with the same name
+    - selftests/bpf: Verify that sync_linked_regs preserves subreg_def
+    - irqchip/ocelot: Fix trigger register address
+    - nvme: tcp: avoid race between queue_lock lock and destroy
+    - block: Fix elevator_get_default() checking for NULL q->tag_set
+    - HID: multitouch: Add support for B2402FVA track point
+    - HID: multitouch: Add quirk for HONOR MagicBook Art 14 touchpad
+    - iommu/arm-smmu: Clarify MMU-500 CPRE workaround
+    - nvme: disable CC.CRIME (NVME_CC_CRIME)
+    - bpf: use kvzmalloc to allocate BPF verifier environment
+    - crypto: api - Fix liveliness check in crypto_alg_tested
+    - crypto: marvell/cesa - Disable hash algorithms
+    - sound: Make CONFIG_SND depend on INDIRECT_IOMEM instead of UML
+    - drm/vmwgfx: Limit display layout ioctl array size to
+      VMWGFX_NUM_DISPLAY_UNITS
+    - RDMA/siw: Add sendpage_ok() check to disable MSG_SPLICE_PAGES
+    - nvme-multipath: defer partition scanning
+    - drm/amdkfd: Accounting pdd vram_usage for svm
+    - powerpc/powernv: Free name on error in opal_event_init()
+    - net: phy: mdio-bcm-unimac: Add BCM6846 support
+    - nvme-loop: flush off pending I/O while shutting down loop controller
+    - smb: client: Fix use-after-free of network namespace.
+    - nvme/host: Fix RCU list traversal to use SRCU primitive
+    - vDPA/ifcvf: Fix pci_read_config_byte() return code handling
+    - bpf: Add sk_is_inet and IS_ICSK check in tls_sw_has_ctx_tx/rx
+    - bpf: Fix mismatched RCU unlock flavour in bpf_out_neigh_v6
+    - ASoC: amd: yc: Add quirk for ASUS Vivobook S15 M3502RA
+    - ASoC: amd: yc: Fix non-functional mic on ASUS E1404FA
+    - fs: Fix uninitialized value issue in from_kuid and from_kgid
+    - HID: multitouch: Add quirk for Logitech Bolt receiver w/ Casa touchpad
+    - HID: lenovo: Add support for Thinkpad X1 Tablet Gen 3 keyboard
+    - RISCV: KVM: use raw_spinlock for critical section in imsic
+    - ASoC: rt722-sdca: increase clk_stop_timeout to fix clock stop issue
+    - LoongArch: Use "Exception return address" to comment ERA
+    - ASoC: fsl_micfil: Add sample rate constraint
+    - net: usb: qmi_wwan: add Fibocom FG132 0x0112 composition
+    - bpf: Check validity of link->type in bpf_link_show_fdinfo()
+    - mm: support order-1 folios in the page cache
+    - mm: always initialise folio->_deferred_list
+    - mm: refactor folio_undo_large_rmappable()
+    - mm/thp: fix deferred split unqueue naming and locking
+    - 9p: fix slab cache name creation for real
+    - nvmet-passthru: clear EUID/NGUID/UUID while using loop target
+    - pinctrl: intel: platform: Add Panther Lake to the list of supported
+    - s390/ap: Fix CCA crypto card behavior within protected execution environment
+    - selftests/bpf: Assert link info uprobe_multi count & path_size if unset
+    - ALSA: hda/tas2781: Add new quirk for Lenovo, ASUS, Dell projects
+    - drm/xe/query: Increase timestamp width
+    - nvme: make keep-alive synchronous operation
+    - samples/landlock: Fix port parsing in sandboxer
+    - ASoC: Intel: avs: Update stream status in a separate thread
+    - ASoC: codecs: Fix error handling in aw_dev_get_dsp_status function
+    - netfs: Downgrade i_rwsem for a buffered write
+    - afs: Fix lock recursion
+    - HID: i2c-hid: Delayed i2c resume wakeup for 0x0d42 Goodix touchpad
+    - LoongArch: KVM: Mark hrtimer to expire in hard interrupt context
+    - drm/xe: Don't restart parallel queues multiple times on GT reset
+    - Upstream stable to v6.6.62, v6.11.9
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292)
+    - arm64: dts: rockchip: Fix rt5651 compatible value on rk3399-eaidk-610
+    - arm64: dts: rockchip: Fix rt5651 compatible value on rk3399-sapphire-
+      excavator
+    - arm64: dts: rockchip: Remove hdmi's 2nd interrupt on rk3328
+    - arm64: dts: rockchip: Fix wakeup prop names on PineNote BT node
+    - arm64: dts: rockchip: Fix reset-gpios property on brcm BT nodes
+    - arm64: dts: rockchip: fix i2c2 pinctrl-names property on anbernic-rg353p/v
+    - arm64: dts: rockchip: Fix bluetooth properties on rk3566 box demo
+    - arm64: dts: rockchip: Fix bluetooth properties on Rock960 boards
+    - arm64: dts: rockchip: Add DTS for FriendlyARM NanoPi R2S Plus
+    - arm64: dts: rockchip: Remove undocumented supports-emmc property
+    - arm64: dts: rockchip: Remove #cooling-cells from fan on Theobroma lion
+    - arm64: dts: rockchip: Fix LED triggers on rk3308-roc-cc
+    - arm64: dts: rockchip: remove num-slots property from rk3328-nanopi-r2s-plus
+    - arm64: dts: imx8-ss-vpu: Fix imx8qm VPU IRQs
+    - arm64: dts: imx8mp: correct sdhc ipg clk
+    - arm64: dts: rockchip: remove orphaned pinctrl-names from pinephone pro
+    - ARM: dts: rockchip: fix rk3036 acodec node
+    - ARM: dts: rockchip: drop grf reference from rk3036 hdmi
+    - ARM: dts: rockchip: Fix the spi controller on rk3036
+    - ARM: dts: rockchip: Fix the realtek audio codec on rk3036-kylin
+    - arm64: dts: rockchip: Correct GPIO polarity on brcm BT nodes
+    - sunrpc: handle -ENOTCONN in xs_tcp_setup_socket()
+    - NFSv3: only use NFS timeout for MOUNT when protocols are compatible
+    - nfs: avoid i_lock contention in nfs_clear_invalid_mapping
+    - net: enetc: set MAC address to the VF net_device
+    - dt-bindings: net: xlnx,axi-ethernet: Correct phy-mode property value
+    - can: c_can: fix {rx,tx}_errors statistics
+    - can: c_can: c_can_handle_bus_err(): update statistics if skb allocation
+      fails
+    - ice: change q_index variable type to s16 to store -1 value
+    - e1000e: Remove Meteor Lake SMBUS workarounds
+    - net: phy: ti: add PHY_RST_AFTER_CLK_EN flag
+    - net: stmmac: Fix unbalanced IRQ wake disable warning on single irq case
+    - netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx
+    - netfilter: nf_tables: wait for rcu grace period on net_device removal
+    - netfilter: nf_tables: do not defer rule destruction via call_rcu
+    - net: arc: rockchip: fix emac mdio node support
+    - drivers: net: ionic: add missed debugfs cleanup to ionic_probe() error path
+    - Revert "ALSA: hda/conexant: Mute speakers at suspend / shutdown"
+    - media: stb0899_algo: initialize cfr before using it
+    - media: dvb_frontend: don't play tricks with underflow values
+    - media: adv7604: prevent underflow condition when reporting colorspace
+    - scsi: sd_zbc: Use kvzalloc() to allocate REPORT ZONES buffer
+    - ALSA: firewire-lib: fix return value on fail in amdtp_tscm_init()
+    - tools/lib/thermal: Fix sampling handler context ptr
+    - thermal/of: support thermal zones w/o trips subnode
+    - ASoC: SOF: sof-client-probes-ipc4: Set param_size extension bits
+    - media: pulse8-cec: fix data timestamp at pulse8_setup()
+    - media: v4l2-ctrls-api: fix error handling for v4l2_g_ctrl()
+    - can: m_can: m_can_close(): don't call free_irq() for IRQ-less devices
+    - can: mcp251xfd: mcp251xfd_get_tef_len(): fix length calculation
+    - can: mcp251xfd: mcp251xfd_ring_alloc(): fix coalescing configuration when
+      switching CAN modes
+    - ksmbd: count all requests in req_running counter
+    - ksmbd: fix broken transfers when exceeding max simultaneous operations
+    - pwm: imx-tpm: Use correct MODULO value for EPWM mode
+    - rpmsg: glink: Handle rejected intent request better
+    - drm/amdgpu: Adjust debugfs eviction and IB access permissions
+    - drm/amdgpu: Adjust debugfs register access permissions
+    - drm/amdgpu: Fix DPX valid mode check on GC 9.4.3
+    - thermal/drivers/qcom/lmh: Remove false lockdep backtrace
+    - dm cache: correct the number of origin blocks to match the target length
+    - dm cache: optimize dirty bit checking with find_next_bit when resizing
+    - dm-unstriped: cast an operand to sector_t to prevent potential uint32_t
+      overflow
+    - ALSA: usb-audio: Add quirk for HP 320 FHD Webcam
+    - net: wwan: t7xx: Fix off-by-one error in t7xx_dpmaif_rx_buf_alloc()
+    - mptcp: use sock_kfree_s instead of kfree
+    - arm64: Kconfig: Make SME depend on BROKEN for now
+    - [Config] updateconfigs for ARM64_SME
+    - arm64: smccc: Remove broken support for SMCCCv1.3 SVE discard hint
+    - Revert "wifi: mac80211: fix RCU list iterations"
+    - i2c: designware: do not hold SCL low when I2C_DYNAMIC_TAR_UPDATE is not set
+    - fs/proc: fix compile warning about variable 'vmcore_mmap_ops'
+    - usb: dwc3: fix fault at system suspend if device was already runtime
+      suspended
+    - USB: serial: qcserial: add support for Sierra Wireless EM86xx
+    - USB: serial: option: add Fibocom FG132 0x0112 composition
+    - USB: serial: option: add Quectel RG650V
+    - irqchip/gic-v3: Force propagation of the active state with a read-back
+    - ucounts: fix counter leak in inc_rlimit_get_ucounts()
+    - ASoC: amd: yc: fix internal mic on Xiaomi Book Pro 14 2022
+    - arm64: dts: rockchip: Designate Turing RK1's system power controller
+    - EDAC/qcom: Make irq configuration optional
+    - arm64: dts: rockchip: Drop regulator-init-microvolt from two boards
+    - net: dpaa_eth: print FD status in CPU endianness in dpaa_eth_fd tracepoint
+    - virtio_net: Sync rss config to device when virtnet_probe
+    - drm/xe: Set mask bits for CCS_MODE register
+    - drm/amd/display: Fix brightness level not retained over reboot
+    - drm/imagination: Add a per-file PVR context list
+    - mptcp: no admin perm to list endpoints
+    - btrfs: fix the length of reserved qgroup to free
+    - btrfs: fix per-subvolume RO/RW flags with new mount API
+    - clk: qcom: gcc-x1e80100: Fix USB MP SS1 PHY GDSC pwrsts flags
+    - clk: qcom: clk-alpha-pll: Fix pll post div mask when width is not set
+    - objpool: fix to make percpu slot allocation more robust
+    - mm/damon/core: handle zero {aggregation,ops_update} intervals
+    - mm/damon/core: handle zero schemes apply interval
+    - mm/mlock: set the correct prev on failure
+    - clk: qcom: gcc-x1e80100: Fix halt_check for pipediv2 clocks
+    - staging: vchiq_arm: Get the rid off struct vchiq_2835_state
+    - staging: vchiq_arm: Use devm_kzalloc() for vchiq_arm_state allocation
+    - drm/xe/guc/ct: Flush g2h worker in case of g2h response timeout
+    - drm/xe: Move LNL scheduling WA to xe_device.h
+    - drm/xe/ufence: Flush xe ordered_wq in case of ufence timeout
+    - drm/xe/guc/tlb: Flush g2h worker in case of tlb timeout
+    - xtensa: Emulate one-byte cmpxchg
+    - Upstream stable to v6.6.61, v6.11.8
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50270
+    - mm/damon/core: avoid overflow in damon_feed_loop_next_input()
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50274
+    - idpf: avoid vport access in idpf_get_link_ksettings
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53067
+    - scsi: ufs: core: Start the RTC update work later
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53084
+    - drm/imagination: Break an object reference loop
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53085
+    - tpm: Lock TPM chip in tpm_pm_suspend() first
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53086
+    - drm/xe: Drop VM dma-resv lock on xe_sync_in_fence_get failure in exec IOCTL
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53087
+    - drm/xe: Fix possible exec queue leak in exec IOCTL
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50288
+    - media: vivid: fix buffer overwrite when using > 32 buffers
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50289
+    - media: av7110: fix a spectre vulnerability
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53062
+    - media: mgb4: protect driver against spectre
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50291
+    - media: dvb-core: add missing buffer index check
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50297
+    - net: xilinx: axienet: Enqueue Tx packets in dql before dmaengine starts
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50267
+    - USB: serial: io_edgeport: fix use after free in debug printk
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50268
+    - usb: typec: fix potential out of bounds in ucsi_ccg_update_set_new_cam_cmd()
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53083
+    - usb: typec: qcom-pmic: init value of hdr_len/txbuf_len earlier
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50269
+    - usb: musb: sunxi: Fix accessing an released usb phy
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50271
+    - signal: restore the override_rlimit logic
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50272
+    - filemap: Fix bounds checking in filemap_read()
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50273
+    - btrfs: reinitialize delayed ref list after deleting it from the list
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50275
+    - arm64/sve: Discard stale CPU state when handling SVE traps
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50276
+    - net: vertexcom: mse102x: Fix possible double free of TX skb
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53066
+    - nfs: Fix KMSAN warning in decode_getfattr_attrs()
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50278
+    - dm cache: fix potential out-of-bounds access on the first resume
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50279
+    - dm cache: fix out-of-bounds access to the dirty bitset when resizing
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50280
+    - dm cache: fix flushing uninitialized delayed_work on cache_ctr error
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53060
+    - drm/amdgpu: prevent NULL pointer dereference if ATIF is not supported
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50282
+    - drm/amdgpu: add missing size check in amdgpu_debugfs_gprwave_read()
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50283
+    - ksmbd: fix slab-use-after-free in smb3_preauth_hash_rsp
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50284
+    - ksmbd: Fix the missing xa_store error check
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50285
+    - ksmbd: check outstanding simultaneous SMB operations
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50286
+    - ksmbd: fix slab-use-after-free in ksmbd_smb2_session_create
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50287
+    - media: v4l2-tpg: prevent the risk of a division by zero
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50290
+    - media: cx24116: prevent overflows on SNR calculus
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53061
+    - media: s5p-jpeg: prevent buffer overflows
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53081
+    - media: ar0521: don't overflow when checking PLL values
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50292
+    - ASoC: stm32: spdifrx: fix dma channel release in stm32_spdifrx_remove
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50294
+    - rxrpc: Fix missing locking causing hanging calls
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50295
+    - net: arc: fix the device for dma_map_single/dma_unmap_single
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53082
+    - virtio_net: Add hash_key_length check
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50296
+    - net: hns3: fix kernel crash when uninstalling driver
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53088
+    - i40e: fix race condition by adding filter's intermediate sync state
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50298
+    - net: enetc: allocate vf_state during PF probes
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50299
+    - sctp: properly validate chunk size in sctp_sf_ootb()
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50300
+    - regulator: rtq2208: Fix uninitialized use of regulator_config
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50301
+    - security/keys: fix slab-out-of-bounds in key_task_permission
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53072
+    - platform/x86/amd/pmc: Detect when STB is not available
+
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53068
+    - firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier()
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996)
+    - Input: xpad - sort xpad_device by vendor and product ID
+    - Input: xpad - add support for 8BitDo Ultimate 2C Wireless Controller
+    - cgroup: Fix potential overflow issue when checking max_depth
+    - spi: geni-qcom: Fix boot warning related to pm_runtime and devres
+    - wifi: iwlegacy: Fix "field-spanning write" warning in il_enqueue_hcmd()
+    - mac80211: MAC80211_MESSAGE_TRACING should depend on TRACING
+    - wifi: mac80211: skip non-uploaded keys in ieee80211_iter_keys
+    - wifi: ath11k: Fix invalid ring usage in full monitor mode
+    - wifi: brcm80211: BRCM_TRACING should depend on TRACING
+    - RDMA/cxgb4: Dump vendor specific QP details
+    - RDMA/mlx5: Round max_rd_atomic/max_dest_rd_atomic up instead of down
+    - RDMA/bnxt_re: Fix the usage of control path spin locks
+    - RDMA/bnxt_re: synchronize the qp-handle table array
+    - RDMA/bnxt_re: Fix the locking while accessing the QP table
+    - wifi: iwlwifi: mvm: disconnect station vifs if recovery failed
+    - wifi: iwlwifi: mvm: don't add default link in fw restart flow
+    - ASoC: cs42l51: Fix some error handling paths in cs42l51_probe()
+    - net: stmmac: dwmac4: Fix high address display by updating reg_space[] from
+      register values
+    - net: stmmac: fix TSO DMA API usage causing oops
+    - gtp: allow -1 to be specified as file description from userspace
+    - bpf: Force checkpoint when jmp history is too long
+    - net: skip offload for NETIF_F_IPV6_CSUM if ipv6 header contains extension
+    - net: reenable NETIF_F_IPV6_CSUM offload for BIG TCP packets
+    - mlxsw: spectrum_ptp: Add missing verification before pushing Tx header
+    - bpf, test_run: Fix LIVE_FRAME frame update after a page has been recycled
+    - iomap: improve shared block detection in iomap_unshare_iter
+    - iomap: don't bother unsharing delalloc extents
+    - iomap: share iomap_unshare_iter predicate code with fsdax
+    - fsdax: remove zeroing code from dax_unshare_iter
+    - iomap: turn iomap_want_unshare_iter into an inline function
+    - kasan: Fix Software Tag-Based KASAN with GCC
+    - firmware: arm_sdei: Fix the input parameter of cpuhp_remove_state()
+    - afs: Fix missing subdir edit when renamed between parent dirs
+    - smb: client: set correct device number on nfs reparse points
+    - cxl/events: Fix Trace DRAM Event Record
+    - fs/ntfs3: Fix warning possible deadlock in ntfs_set_state
+    - fs/ntfs3: Stale inode instead of bad
+    - scsi: scsi_transport_fc: Allow setting rport state to current state
+    - cifs: Fix creating native symlinks pointing to current or parent directory
+    - thermal: intel: int340x: processor: Remove MMIO RAPL CPU hotplug support
+    - thermal: intel: int340x: processor: Add MMIO RAPL PL4 support
+    - net: amd: mvme147: Fix probe banner message
+    - NFS: remove revoked delegation from server's delegation list
+    - misc: sgi-gru: Don't disable preemption in GRU driver
+    - usb: gadget: dummy_hcd: Switch to hrtimer transfer scheduler
+    - usb: gadget: dummy_hcd: Set transfer interval to 1 microframe
+    - usb: gadget: dummy_hcd: execute hrtimer callback in softirq context
+    - USB: gadget: dummy-hcd: Fix "task hung" problem
+    - ALSA: usb-audio: Add quirks for Dell WD19 dock
+    - usbip: tools: Fix detach_port() invalid port error path
+    - usb: phy: Fix API devm_usb_put_phy() can not release the phy
+    - usb: typec: fix unreleased fwnode_handle in typec_port_register_altmodes()
+    - usb: typec: qcom-pmic-typec: use fwnode_handle_put() to release fwnodes
+    - xhci: Fix Link TRB DMA in command ring stopped completion event
+    - xhci: Use pm_runtime_get to prevent RPM on unsupported systems
+    - Revert "driver core: Fix uevent_show() vs driver detach race"
+    - iio: light: veml6030: fix microlux value calculation
+    - RISC-V: ACPI: fix early_ioremap to early_memremap
+    - tools/mm: -Werror fixes in page-types/slabinfo
+    - tools/mm: fix compile error
+    - thunderbolt: Honor TMU requirements in the domain when setting TMU mode
+    - mmc: sdhci-pci-gli: GL9767: Fix low power mode on the set clock function
+    - mmc: sdhci-pci-gli: GL9767: Fix low power mode in the SD Express process
+    - block: fix sanity checks in blk_rq_map_user_bvec
+    - cgroup/bpf: use a dedicated workqueue for cgroup bpf destruction
+    - phy: freescale: imx8m-pcie: Do CMN_RST just before PHY PLL lock check
+    - riscv: vdso: Prevent the compiler from inserting calls to memset()
+    - Input: edt-ft5x06 - fix regmap leak when probe fails
+    - ALSA: hda/realtek: Limit internal Mic boost on Dell platform
+    - riscv: efi: Set NX compat flag in PE/COFF header
+    - riscv: Use '%u' to format the output of 'cpu'
+    - riscv: Remove unused GENERATING_ASM_OFFSETS
+    - riscv: Remove duplicated GET_RM
+    - cxl/port: Fix cxl_bus_rescan() vs bus_rescan_devices()
+    - cxl/acpi: Ensure ports ready at cxl_acpi_probe() return
+    - mei: use kvmalloc for read buffer
+    - mm/page_alloc: let GFP_ATOMIC order-0 allocs access highatomic reserves
+    - x86/traps: Enable UBSAN traps on x86
+    - x86/traps: move kmsan check after instrumentation_begin
+    - kasan: remove vmalloc_percpu test
+    - vmscan,migrate: fix page count imbalance on node stats when demoting pages
+    - io_uring: always lock __io_cqring_overflow_flush
+    - mm: huge_memory: add vma_thp_disabled() and thp_disabled_by_hw()
+    - mm: don't install PMD mappings when THPs are disabled by the hw/process/vma
+    - perf trace: Fix non-listed archs in the syscalltbl routines
+    - dpll: add Embedded SYNC feature for a pin
+    - ice: add callbacks for Embedded SYNC enablement on dpll pins
+    - bpf: Add bpf_mem_alloc_check_size() helper
+    - net: ethernet: mtk_wed: fix path of MT7988 WO firmware
+    - drm/mediatek: ovl: Remove the color format comment for ovl_fmt_convert()
+    - drm/mediatek: Fix get efuse issue for MT8188 DPTX
+    - ACPI: resource: Fold Asus Vivobook Pro N6506M* DMI quirks together
+    - powercap: intel_rapl_msr: Add PL4 support for Arrowlake-U
+    - usb: typec: qcom-pmic-typec: fix missing fwnode removal in error path
+    - mm: shrinker: avoid memleak in alloc_shrinker_info
+    - firmware: microchip: auto-update: fix poll_complete() to not report spurious
+      timeout errors
+    - soc: qcom: pmic_glink: Handle GLINK intent allocation rejections
+    - cxl/port: Fix CXL port initialization order when the subsystem is built-in
+    - btrfs: merge btrfs_orig_bbio_end_io() into btrfs_bio_end_io()
+    - posix-cpu-timers: Clear TICK_DEP_BIT_POSIX_TIMER on clone
+    - mm/ksm: remove redundant code in ksm_fork
+    - nvme: re-fix error-handling for io_uring nvme-passthrough
+    - btrfs: fix extent map merging not happening for adjacent extents
+    - btrfs: fix defrag not merging contiguous extents due to merged extent maps
+    - mm, mmap: limit THP alignment of anonymous mappings to PMD-aligned sizes
+    - mm: multi-gen LRU: ignore non-leaf pmd_young for force_scan=true
+    - mm: multi-gen LRU: remove MM_LEAF_OLD and MM_NONLEAF_TOTAL stats
+    - mm: shrink skip folio mapped by an exiting process
+    - mm: multi-gen LRU: use {ptep,pmdp}_clear_young_notify()
+    - drm/i915: Skip programming FIA link enable bits for MTL+
+    - drm/i915/display: WA for Re-initialize dispcnlunitt1 xosc clock
+    - drm/i915/dp: Clear VSC SDP during post ddi disable routine
+    - drm/i915/pps: Disable DPLS_GATING around pps sequence
+    - drm/i915: move rawclk from runtime to display runtime info
+    - drm/xe/display: drop unused rawclk_freq and RUNTIME_INFO()
+    - drm/xe: Support 'nomodeset' kernel command-line option
+    - drm/xe/xe2hpg: Introduce performance tuning changes for Xe2_HPG
+    - drm/amdgpu/swsmu: fix ordering for setting workload_mask
+    - drm/amdgpu/swsmu: default to fullscreen 3D profile for dGPUs
+    - drm/amdgpu: handle default profile on on devices without fullscreen 3D
+    - MIPS: export __cmpxchg_small()
+    - rcu/kvfree: Add kvfree_rcu_barrier() API
+    - rcu/kvfree: Refactor kvfree_rcu_queue_batch()
+    - Upstream stable to v6.6.60, v6.11.7
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53050
+    - drm/i915/hdcp: Add encoder check in hdcp2_get_capability
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53051
+    - drm/i915/hdcp: Add encoder check in intel_hdcp_get_capability
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50303
+    - resource,kexec: walk_system_ram_res_rev must retain resource flags
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50263
+    - fork: only invoke khugepaged, ksm hooks if no error
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50220
+    - fork: do not invoke uffd on fork if error occurs
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50221
+    - drm/amd/pm: Vangogh: Fix kernel memory out of bounds write
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53053
+    - scsi: ufs: core: Fix another deadlock during RTC update
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50225
+    - btrfs: fix error propagation of split bios
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50230
+    - nilfs2: fix kernel bug due to missing clearing of checked flag
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50238
+    - phy: qcom: qmp-usbc: fix NULL-deref on runtime suspend
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53044
+    - net/sched: sch_api: fix xa_insert() error path in tcf_block_get_ext()
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50304
+    - ipv4: ip_tunnel: Fix suspicious RCU usage warning in ip_tunnel_find()
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53048
+    - ice: fix crash on probe for DPLL enabled E810 LOM
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53045
+    - ASoC: dapm: fix bounds checker error in dapm_widget_list_create
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53055
+    - wifi: iwlwifi: mvm: fix 6 GHz scan construction
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53046
+    - arm64: dts: imx8ulp: correct the flexspi compatible string
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53052
+    - io_uring/rw: fix missing NOWAIT check for O_DIRECT start write
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50215
+    - nvmet-auth: assign dh_key to NULL after kfree_sensitive
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50216
+    - xfs: fix finding a last resort AG in xfs_filestream_pick_ag
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53043
+    - mctp i2c: handle NULL header address
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50218
+    - ocfs2: pass u64 to ocfs2_truncate_inline maybe overflow
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53047
+    - mptcp: init: protect sched with rcu_read_lock
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50222
+    - iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50223
+    - sched/numa: Fix the potential null pointer dereference in task_numa_work()
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50224
+    - spi: spi-fsl-dspi: Fix crash when not using GPIO chip select
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50226
+    - cxl/port: Fix use-after-free, permit out-of-order decoder shutdown
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50231
+    - iio: gts-helper: Fix memory leaks in iio_gts_build_avail_scale_table()
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53076
+    - iio: gts-helper: Fix memory leaks for the error path of
+      iio_gts_build_avail_scale_table()
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50232
+    - iio: adc: ad7124: fix division by zero in ad7124_set_channel_odr()
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50234
+    - wifi: iwlegacy: Clear stale interrupts before resuming device
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50235
+    - wifi: cfg80211: clear wdev->cqm_config pointer on free
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50236
+    - wifi: ath10k: Fix memory leak in management tx
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50237
+    - wifi: mac80211: do not pass a stopped vif to the driver in .get_txpower
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50239
+    - phy: qcom: qmp-usb-legacy: fix NULL-deref on runtime suspend
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50240
+    - phy: qcom: qmp-usb: fix NULL-deref on runtime suspend
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50242
+    - fs/ntfs3: Additional check in ntfs_file_release
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50243
+    - fs/ntfs3: Fix general protection fault in run_is_mapped_full
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50244
+    - fs/ntfs3: Additional check in ni_clear()
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50245
+    - fs/ntfs3: Fix possible deadlock in mi_read
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50246
+    - fs/ntfs3: Add rough attr alloc_size check
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50247
+    - fs/ntfs3: Check if more than chunk-size bytes are written
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50250
+    - fsdax: dax_unshare_iter needs to copy entire blocks
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50251
+    - netfilter: nft_payload: sanitize offset and length before calling
+      skb_checksum()
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50252
+    - mlxsw: spectrum_ipip: Fix memory leak when changing remote IPv6 address
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50255
+    - Bluetooth: hci: fix null-ptr-deref in hci_read_supported_codecs
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50257
+    - netfilter: Fix use-after-free in get_info()
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50258
+    - net: fix crash when config small gso_max_size/gso_ipv4_max_size
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50262
+    - bpf: Fix out-of-bounds write in trie_get_next_key()
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50259
+    - netdevsim: Add trailing zero to terminate the string in
+      nsim_nexthop_bucket_activity_write()
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53042
+    - ipv4: ip_tunnel: Fix suspicious RCU usage warning in ip_tunnel_init_flow()
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53058
+    - net: stmmac: TSO: Fix unbalanced DMA map/unmap for non-paged SKB data
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50261
+    - macsec: Fix use-after-free while sending the offloading packet
+
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53059
+    - wifi: iwlwifi: mvm: Fix response handling in iwl_mvm_send_recovery_cmd()
+
+  * Noble update: upstream stable patchset 2025-02-07 (LP: #2097575)
+    - irqchip/gic-v3-its: Fix VSYNC referencing an unmapped VPE on GIC v4.1
+    - xfs: fix error returns from xfs_bmapi_write
+    - xfs: fix xfs_bmap_add_extent_delay_real for partial conversions
+    - xfs: remove a racy if_bytes check in xfs_reflink_end_cow_extent
+    - xfs: require XFS_SB_FEAT_INCOMPAT_LOG_XATTRS for attr log intent item
+      recovery
+    - xfs: check opcode and iovec count match in xlog_recover_attri_commit_pass2
+    - xfs: fix missing check for invalid attr flags
+    - xfs: check shortform attr entry flags specifically
+    - xfs: validate recovered name buffers when recovering xattr items
+    - xfs: enforce one namespace per attribute
+    - xfs: revert commit 44af6c7e59b12
+    - xfs: use dontcache for grabbing inodes during scrub
+    - xfs: match lock mode in xfs_buffered_write_iomap_begin()
+    - xfs: make the seq argument to xfs_bmapi_convert_delalloc() optional
+    - xfs: make xfs_bmapi_convert_delalloc() to allocate the target offset
+    - xfs: convert delayed extents to unwritten when zeroing post eof blocks
+    - xfs: allow symlinks with short remote targets
+    - xfs: make sure sb_fdblocks is non-negative
+    - xfs: fix unlink vs cluster buffer instantiation race
+    - xfs: fix freeing speculative preallocations for preallocated files
+    - xfs: allow unlinked symlinks and dirs with zero size
+    - xfs: restrict when we try to align cow fork delalloc to cowextsz hints
+    - selftests: mptcp: join: change capture/checksum as bool
+    - selftests: mptcp: join: test for prohibited MPC to port-based endp
+    - selftests: mptcp: remove duplicated variables
+    - iio: accel: bma400: Fix uninitialized variable field_value in tap event
+      handling.
+    - bpf: Make sure internal and UAPI bpf_redirect flags don't overlap
+    - bpf: devmap: provide rxq after redirect
+    - cpufreq/amd-pstate: Fix amd_pstate mode switch on shared memory systems
+    - lib/Kconfig.debug: fix grammar in RUST_BUILD_ASSERT_ALLOW
+    - bpf: Fix memory leak in bpf_core_apply
+    - RDMA/bnxt_re: Fix a possible memory leak
+    - RDMA/bnxt_re: Fix incorrect AVID type in WQE structure
+    - RDMA/bnxt_re: Add a check for memory allocation
+    - x86/resctrl: Avoid overflow in MB settings in bw_validate()
+    - ARM: dts: bcm2837-rpi-cm3-io3: Fix HDMI hpd-gpio pin
+    - bpf: Add cookie to perf_event bpf_link_info records
+    - bpf: fix unpopulated name_len field in perf_event link info
+    - selftests/bpf: Add cookies check for perf_event fill_link_info test
+    - selftests/bpf: fix perf_event link info name_len assertion
+    - s390/pci: Handle PCI error codes other than 0x3a
+    - bpf: fix kfunc btf caching for modules
+    - iio: frequency: {admv4420,adrf6780}: format Kconfig entries
+    - iio: frequency: admv4420: fix missing select REMAP_SPI in Kconfig
+    - drm/vmwgfx: Handle possible ENOMEM in vmw_stdu_connector_atomic_check
+    - selftests/bpf: Fix cross-compiling urandom_read
+    - task_work: Add TWA_NMI_CURRENT as an additional notify mode.
+    - sched/core: Disable page allocation in task_tick_mm_cid()
+    - ALSA: hda/cs8409: Fix possible NULL dereference
+    - firmware: arm_scmi: Fix the double free in scmi_debugfs_common_setup()
+    - RDMA/cxgb4: Fix RDMA_CM_EVENT_UNREACHABLE error for iWARP
+    - RDMA/irdma: Fix misspelling of "accept*"
+    - RDMA/srpt: Make slab cache names unique
+    - ipv4: give an IPv4 dev to blackhole_netdev
+    - RDMA/bnxt_re: Fix the max CQ WQEs for older adapters
+    - RDMA/bnxt_re: Fix out of bound check
+    - RDMA/bnxt_re: Return more meaningful error
+    - RDMA/bnxt_re: Fix a bug while setting up Level-2 PBL pages
+    - RDMA/bnxt_re: Fix the GID table length
+    - accel/qaic: Fix the for loop used to walk SG table
+    - drm/msm/dpu: make sure phys resources are properly initialized
+    - drm/msm/dpu: check for overflow in _dpu_crtc_setup_lm_bounds()
+    - drm/msm/dsi: improve/fix dsc pclk calculation
+    - drm/msm/dsi: fix 32-bit signed integer extension in pclk_rate calculation
+    - drm/msm: Avoid NULL dereference in msm_disp_state_print_regs()
+    - drm/msm: Allocate memory for disp snapshot with kvzalloc()
+    - firmware: arm_scmi: Queue in scmi layer for mailbox implementation
+    - net/smc: Fix memory leak when using percpu refs
+    - net: usb: usbnet: fix race in probe failure
+    - net: stmmac: dwmac-tegra: Fix link bring-up sequence
+    - octeontx2-af: Fix potential integer overflows on integer shifts
+    - drm/amd/amdgpu: Fix double unlock in amdgpu_mes_add_ring
+    - macsec: don't increment counters for an unrelated SA
+    - netdevsim: use cond_resched() in nsim_dev_trap_report_work()
+    - net: ethernet: aeroflex: fix potential memory leak in
+      greth_start_xmit_gbit()
+    - net/smc: Fix searching in list of known pnetids in smc_pnet_add_pnetid
+    - net: xilinx: axienet: fix potential memory leak in axienet_start_xmit()
+    - bpf: Fix truncation bug in coerce_reg_to_size_sx()
+    - irqchip/renesas-rzg2l: Fix missing put_device
+    - drm/msm/dpu: don't always program merge_3d block
+    - net: bcmasp: fix potential memory leak in bcmasp_xmit()
+    - tcp/dccp: Don't use timer_pending() in reqsk_queue_unlink().
+    - net: dsa: mv88e6xxx: Fix the max_vid definition for the MV88E6361
+    - genetlink: hold RCU in genlmsg_mcast()
+    - ravb: Remove setting of RX software timestamp
+    - net: ravb: Only advertise Rx/Tx timestamps if hardware supports it
+    - scsi: target: core: Fix null-ptr-deref in target_alloc_device()
+    - smb: client: fix possible double free in smb2_set_ea()
+    - smb: client: fix OOBs when building SMB2_IOCTL request
+    - usb: typec: altmode should keep reference to parent
+    - s390: Initialize psw mask in perf_arch_fetch_caller_regs()
+    - bpf: Fix link info netfilter flags to populate defrag flag
+    - vmxnet3: Fix packet corruption in vmxnet3_xdp_xmit_frame
+    - net/mlx5: Check for invalid vector index on EQ creation
+    - net/mlx5: Fix command bitmask initialization
+    - net/mlx5: Unregister notifier on eswitch init failure
+    - bpf, sockmap: SK_DROP on attempted redirects of unsupported af_vsock
+    - vsock: Update rx_bytes on read_skb()
+    - vsock: Update msg_count on read_skb()
+    - bpf, vsock: Drop static vsock_bpf_prot initialization
+    - riscv, bpf: Make BPF_CMPXCHG fully ordered
+    - nvme-pci: fix race condition between reset and nvme_dev_disable()
+    - bpf: Fix iter/task tid filtering
+    - cdrom: Avoid barrier_nospec() in cdrom_ioctl_media_changed()
+    - khugepaged: inline hpage_collapse_alloc_folio()
+    - khugepaged: convert alloc_charge_hpage to alloc_charge_folio
+    - khugepaged: remove hpage from collapse_file()
+    - mm: khugepaged: fix the arguments order in khugepaged_collapse_file trace
+      point
+    - iio: adc: ti-lmp92064: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - xhci: dbgtty: remove kfifo_out() wrapper
+    - xhci: dbgtty: use kfifo from tty_port struct
+    - xhci: dbc: honor usb transfer size boundaries.
+    - usb: gadget: f_uac2: fix non-newline-terminated function name
+    - usb: gadget: f_uac2: fix return value for UAC2_ATTRIBUTE_STRING store
+    - XHCI: Separate PORT and CAPs macros into dedicated file
+    - usb: dwc3: core: Fix system suspend on TI AM62 platforms
+    - tracing/fprobe-event: cleanup: Fix a wrong comment in fprobe event
+    - tracing/probes: cleanup: Set trace_probe::nr_args at trace_probe_init
+    - tracing/probes: Support $argN in return probe (kprobe and fprobe)
+    - uprobes: encapsulate preparation of uprobe args buffer
+    - uprobes: prepare uprobe args buffer lazily
+    - uprobes: prevent mutex_lock() under rcu_read_lock()
+    - uprobe: avoid out-of-bounds memory access of fetching args
+    - exec: don't WARN for racy path_noexec check
+    - ASoC: amd: yc: Add quirk for HP Dragonfly pro one
+    - ASoC: codecs: lpass-rx-macro: add missing CDC_RX_BCL_VBAT_RF_PROC2 to
+      default regs values
+    - ASoC: fsl_sai: Enable 'FIFO continue on error' FCONT bit
+    - arm64: Force position-independent veneers
+    - udf: refactor udf_current_aext() to handle error
+    - udf: refactor udf_next_aext() to handle error
+    - udf: refactor inode_bmap() to handle error
+    - udf: fix uninit-value use in udf_get_fileshortad
+    - ASoC: qcom: sm8250: add qrb4210-rb2-sndcard compatible string
+    - cifs: Validate content of NFS reparse point buffer
+    - platform/x86: dell-sysman: add support for alienware products
+    - LoongArch: Don't crash in stack_top() for tasks without vDSO
+    - jfs: Fix sanity check in dbMount
+    - tracing/probes: Fix MAX_TRACE_ARGS limit handling
+    - tracing: Consider the NULL character when validating the event length
+    - xfrm: extract dst lookup parameters into a struct
+    - xfrm: respect ip protocols rules criteria when performing dst lookups
+    - netfilter: bpf: must hold reference on net namespace
+    - net/sun3_82586: fix potential memory leak in sun3_82586_send_packet()
+    - net: plip: fix break; causing plip to never transmit
+    - octeon_ep: Implement helper for iterating packets in Rx queue
+    - octeon_ep: Add SKB allocation failures handling in __octep_oq_process_rx()
+    - net: dsa: mv88e6xxx: Fix error when setting port policy on mv88e6393x
+    - fsl/fman: Save device references taken in mac_probe()
+    - fsl/fman: Fix refcount handling of fman-related devices
+    - netfilter: xtables: fix typo causing some targets not to load on IPv6
+    - net: wwan: fix global oob in wwan_rtnl_policy
+    - net/sched: adjust device watchdog timer to detect stopped queue at right
+      time
+    - net: fix races in netdev_tx_sent_queue()/dev_watchdog()
+    - net: usb: usbnet: fix name regression
+    - bpf: Add MEM_WRITE attribute
+    - bpf: Fix overloading of MEM_UNINIT's meaning
+    - bpf: Remove MEM_UNINIT from skb/xdp MTU helpers
+    - net/sched: act_api: deny mismatched skip_sw/skip_hw flags for actions
+      created by classifiers
+    - net: sched: fix use-after-free in taprio_change()
+    - net: sched: use RCU read-side critical section in taprio_dump()
+    - posix-clock: posix-clock: Fix unbalanced locking in pc_clock_settime()
+    - Bluetooth: SCO: Fix UAF on sco_sock_timeout
+    - Bluetooth: ISO: Fix UAF on iso_sock_timeout
+    - bpf,perf: Fix perf_event_detach_bpf_prog error handling
+    - net: dsa: mv88e6xxx: group cycle counter coefficients
+    - net: dsa: mv88e6xxx: read cycle counter period from hardware
+    - net: dsa: mv88e6xxx: support 4000ps cycle counter period
+    - ASoC: dt-bindings: davinci-mcasp: Fix interrupts property
+    - ASoC: dt-bindings: davinci-mcasp: Fix interrupt properties
+    - ASoC: loongson: Fix component check failed on FDT systems
+    - ASoC: max98388: Fix missing increment of variable slot_found
+    - ASoC: rsnd: Fix probe failure on HiHope boards due to endpoint parsing
+    - ASoC: fsl_micfil: Add a flag to distinguish with different volume control
+      types
+    - ALSA: firewire-lib: Avoid division by zero in apply_constraint_to_size()
+    - powercap: dtpm_devfreq: Fix error check against dev_pm_qos_add_request()
+    - nfsd: cancel nfsd_shrinker_work using sync mode in nfs4_state_shutdown_net
+    - ALSA: hda/realtek: Update default depop procedure
+    - smb: client: Handle kstrdup failures for passwords
+    - cpufreq: CPPC: fix perf_to_khz/khz_to_perf conversion exception
+    - btrfs: fix passing 0 to ERR_PTR in btrfs_search_dir_index_item()
+    - btrfs: zoned: fix zone unusable accounting for freed reserved extent
+    - ACPI: resource: Add LG 16T90SP to irq1_level_low_skip_override[]
+    - ACPI: PRM: Find EFI_MEMORY_RUNTIME block for PRM handler and context
+    - ACPI: button: Add DMI quirk for Samsung Galaxy Book2 to fix initial lid
+      detection issue
+    - nilfs2: fix kernel bug due to missing clearing of buffer delay flag
+    - openat2: explicitly return -E2BIG for (usize > PAGE_SIZE)
+    - KVM: nSVM: Ignore nCR3[4:0] when loading PDPTEs from memory
+    - KVM: arm64: Fix shift-out-of-bounds bug
+    - KVM: arm64: Don't eagerly teardown the vgic on init error
+    - x86/lam: Disable ADDRESS_MASKING in most cases
+    - [Config] disable ADDRESS_MASKING
+    - ALSA: hda/tas2781: select CRC32 instead of CRC32_SARWATE
+    - ALSA: hda/realtek: Add subwoofer quirk for Acer Predator G9-593
+    - LoongArch: Get correct cores_per_package for SMT systems
+    - LoongArch: Enable IRQ if do_ale() triggered in irq-enabled context
+    - LoongArch: Make KASAN usable for variable cpu_vabits
+    - xfrm: fix one more kernel-infoleak in algo dumping
+    - hv_netvsc: Fix VF namespace also in synthetic NIC NETDEV_REGISTER event
+    - drm/amd/display: Disable PSR-SU on Parade 08-01 TCON too
+    - selinux: improve error checking in sel_write_load()
+    - net: phy: dp83822: Fix reset pin definitions
+    - ata: libata: Set DID_TIME_OUT for commands that actually timed out
+    - ASoC: qcom: Fix NULL Dereference in asoc_qcom_lpass_cpu_platform_probe()
+    - platform/x86: dell-wmi: Ignore suspend notifications
+    - ACPI: PRM: Clean up guid type in struct prm_handler_info
+    - tracing: probes: Fix to zero initialize a local variable
+    - task_work: make TWA_NMI_CURRENT handling conditional on IRQ_WORK
+    - xfrm: validate new SA's prefixlen using SA family when sel.family is unset
+    - bpf: Use raw_spinlock_t in ringbuf
+    - reset: starfive: jh71x0: Fix accessing the empty member on JH7110 SoC
+    - bpf: Fix unpopulated path_size when uprobe_multi fields unset
+    - RDMA/bnxt_re: Fix incorrect dereference of srq in async event
+    - RDMA/bnxt_re: Get the toggle bits from SRQ events
+    - RDMA/bnxt_re: Change the sequence of updating the CQ toggle value
+    - drm/msm/dpu: move CRTC resource assignment to dpu_encoder_virt_atomic_check
+    - ring-buffer: Fix reader locking when changing the sub buffer order
+    - drm/msm/dpu: Don't always set merge_3d pending flush
+    - drm/msm/a6xx+: Insert a fence wait before SMMU table update
+    - drm/xe: Take job list lock in xe_sched_add_pending_job
+    - drm/xe: Use bookkeep slots for external BO's in exec IOCTL
+    - net: ethernet: mtk_eth_soc: fix memory corruption during fq dma init
+    - net/mlx5e: Don't call cleanup on profile rollback failure
+    - bpf: Fix print_reg_state's constant scalar dump
+    - fsnotify: optimize the case of no parent watcher
+    - fsnotify: Avoid data race between fsnotify_recalc_mask() and
+      fsnotify_object_watched()
+    - drm/xe/mcr: Use Xe2_LPM steering tables for Xe2_HPM
+    - objpool: fix choosing allocation for percpu slots
+    - bnxt_en: replace ptp_lock with irqsave variant
+    - bpf, arm64: Fix address emission with tag-based KASAN enabled
+    - net: dsa: microchip: disable EEE for KSZ879x/KSZ877x/KSZ876x
+    - ASoC: topology: Bump minimal topology ABI version
+    - fbdev: wm8505fb: select CONFIG_FB_IOMEM_FOPS
+    - btrfs: qgroup: set a more sane default value for subtree drop threshold
+    - btrfs: clear force-compress on remount when compress mount option is given
+    - x86/amd_nb: Add new PCI IDs for AMD family 1Ah model 60h-70h
+    - x86/amd_nb: Add new PCI ID for AMD family 1Ah model 20h
+    - btrfs: reject ro->rw reconfiguration if there are hard ro requirements
+    - xfs: don't fail repairs on metadata files with no attr fork
+    - drm/bridge: Fix assignment of the of_node of the parent to aux bridge
+    - platform/x86/intel/pmc: Fix pmc_core_iounmap to call iounmap for valid
+      addresses
+    - fgraph: Fix missing unlock in register_ftrace_graph()
+    - fgraph: Change the name of cpuhp state to "fgraph:online"
+    - ASoC: SOF: Intel: hda: Always clean up link DMA during stop
+    - ASoC: dapm: avoid container_of() to get component
+    - ASoC: qcom: sc7280: Fix missing Soundwire runtime stream alloc
+    - ASoC: qcom: sdm845: add missing soundwire runtime stream alloc
+    - soundwire: intel_ace2x: Send PDI stream number during prepare
+    - x86: support user address masking instead of non-speculative conditional
+    - ASoC: qcom: Select missing common Soundwire module code on SDM845
+    - SAUCE: Revert "iio: adc: ti-lmp92064: add missing select
+      IIO_(TRIGGERED_)BUFFER in Kconfig"
+    - Upstream stable to v6.6.58, v6.6.59, v6.11.6
+
+  * CVE-2025-21756
+    - vsock: Keep the binding until socket destruction
+    - vsock: Orphan socket after transport release
+
+  * Fix NIC name changes for ice (LP: #2100264)
+    - ice: Remove ndo_get_phys_port_name
+
+  * CVE-2024-50256
+    - netfilter: nf_reject_ipv6: fix potential crash in nf_send_reset6()
+
+  * CVE-2025-21702
+    - pfifo_tail_enqueue: Drop new packet when sch->limit == 0
+
+  * CVE-2024-50167
+    - be2net: fix potential memory leak in be_xmit()
+
+  * Fix line-out playback on some platforms with Cirrus Logic “Dolphin” hardware
+    (LP: #2099880)
+    - ALSA: hda/cirrus: Correct the full scale volume set logic
+
+  * Enable Large Language Model (LLM) workloads using Intel NPU (LP: #2098972)
+    - accel/ivpu: Increase DMA address range
+
+  * Patchset for TUXEDO devices (LP: #2098104)
+    - wifi: ath12k: add fallback board name without variant while searching
+      board-2.bin
+    - wifi: ath12k: remove unused ATH12K_BD_IE_BOARD_EXT
+    - wifi: ath12k: add support to search regdb data in board-2.bin for WCN7850
+    - wifi: ath12k: support default regdb while searching board-2.bin for WCN7850
+    - ACPI: resource: Use IRQ override on Maibenben X565
+    - ACPI: resource: Do IRQ override on TongFang GXxHRXx and GMxHGxx
+    - ALSA: hda/realtek: Fix headset mic on TUXEDO Gemini 17 Gen3
+    - ALSA: hda/realtek: Fix headset mic on TUXEDO Stellaris 16 Gen6 mb1
+    - PCI: Avoid putting some root ports into D3 on TUXEDO Sirius Gen1
+    - nvme-pci: Add TUXEDO InfinityFlex to Samsung sleep quirk
+    - nvme-pci: Add TUXEDO IBP Gen9 to Samsung sleep quirk
+
+  * Introduce and use sendpages_ok() instead of sendpage_ok() in nvme-tcp and
+    drbd (LP: #2093871)
+    - net: introduce helper sendpages_ok()
+    - nvme-tcp: use sendpages_ok() instead of sendpage_ok()
+    - drbd: use sendpages_ok() instead of sendpage_ok()
+
+  * CVE-2024-56765
+    - powerpc/pseries/vas: Add close() callback in vas_vm_ops struct
+
+  * CVE-2025-21700
+    - net: sched: Disallow replacing of child qdisc from one parent to another
+
+  * CVE-2024-56615
+    - bpf: fix OOB devmap writes when deleting elements
+
+  * CVE-2024-56651
+    - can: hi311x: hi3110_can_ist(): fix potential use-after-free
+
+  * CVE-2024-56627
+    - ksmbd: fix Out-of-Bounds Read in ksmbd_vfs_stream_read
+
+  * CVE-2024-56600
+    - net: inet6: do not leave a dangling sk pointer in inet6_create()
+
+  * CVE-2024-56661
+    - tipc: fix NULL deref in cleanup_bearer()
+
+  * CVE-2024-56642
+    - tipc: Fix use-after-free of kernel socket in cleanup_bearer().
+
+  * CVE-2024-53227
+    - scsi: bfa: Fix use-after-free in bfad_im_module_exit()
+
+  * CVE-2024-53237
+    - Bluetooth: fix use-after-free in device_for_each_child()
+
+  * CVE-2024-53166
+    - block, bfq: fix bfqq uaf in bfq_limit_depth()
+
+  * CVE-2024-50265
+    - ocfs2: remove entry once instead of null-ptr-dereference in
+      ocfs2_xa_remove()
+
+  * CVE-2024-50249
+    - ACPI: CPPC: Make rmw_lock a raw_spin_lock
+
+  * iBFT iSCSI out-of-bounds shift UBSAN warning (LP: #2097824)
+    - iscsi_ibft: Fix UBSAN shift-out-of-bounds warning in ibft_attr_show_nic()
+
+  * [Ubuntu 24.04] MultiVM - L2 guest(s) running stress-ng getting stuck at
+    booting after triggering crash (LP: #2077722)
+    - KVM: PPC: Book3S HV: Mask off LPCR_MER for a vCPU before running it to avoid
+      spurious interrupts
+
+  * btrfs will WARN_ON() in btrfs_remove_qgroup() unnecessarily (LP: #2091719)
+    - btrfs: improve the warning and error message for btrfs_remove_qgroup()
+
+  * CVE-2024-50248
+    - ntfs3: Add bounds checking to mi_enum_attr()
+    - fs/ntfs3: Sequential field availability check in mi_enum_attr()
+
+  * CVE-2025-21701
+    - net: avoid race between device unregistration and ethnl ops
+
+  * CVE-2024-57798
+    - drm/dp_mst: Ensure mst_primary pointer is valid in
+      drm_dp_mst_handle_up_req()
+
+  * CVE-2024-56672
+    - blk-cgroup: Fix UAF in blkcg_unpin_online()
+
+  * CVE-2024-56658
+    - net: defer final 'struct net' free in netns dismantle
+
+  * CVE-2024-56598
+    - jfs: array-index-out-of-bounds fix in dtReadFirst
+
+  * CVE-2024-56595
+    - jfs: add a check to prevent array-index-out-of-bounds in dbAdjTree
+
+  * CVE-2024-53140
+    - netlink: terminate outstanding dump on socket close
+
+  * CVE-2024-53063
+    - media: dvbdev: prevent the risk of out of memory access
+
+  * CVE-2024-50302
+    - HID: core: zero-initialize the report buffer
+
+ -- Stefan Bader <stefan.bader@canonical.com>  Fri, 14 Mar 2025 15:25:38 +0100
+
+linux (6.8.0-56.58) noble; urgency=medium
+
+  * noble/linux: 6.8.0-56.58 -proposed tracker (LP: #2098244)
+
+  * Noble update: upstream stable patchset 2024-07-19 (LP: #2073603)
+    - Revert "drm: Make drivers depends on DRM_DW_HDMI"
+    - Revert "UBUNTU: [Config] Drivers now depend on DRM_DW_HDMI"
+
+  * drm/amd/display: Add check for granularity in dml ceil/floor helpers
+    (LP: #2098080)
+    - drm/amd/display: Add check for granularity in dml ceil/floor helpers
+
+  * optimized default EPP for GNR family (LP: #2097554)
+    - cpufreq: intel_pstate: Update Balance-performance EPP for Granite Rapids
+
+  * Incorrect LAPIC/x2APIC parsing order (LP: #2097455)
+    - x86/acpi: Fix LAPIC/x2APIC parsing order
+
+  * MGLRU: page allocation failure on NUMA-enabled systems (LP: #2097214)
+    - mm/vmscan: wake up flushers conditionally to avoid cgroup OOM
+
+  * Upstream commit 65357e2c164a: "RDMA/mana_ib: set node_guid" applied
+    incorrectly (LP: #2096885)
+    - Revert "RDMA/mana_ib: set node_guid"
+
+  * AppArmor early policy load not funcitoning (LP: #2095370)
+    - SAUCE: Revert "UBUNTU: SAUCE: apparmor4.0.0 [67/90]: userns - add the
+      ability to reference a global variable for a feature value"
+
+  * apparmor unconfined profile blocks pivot_root (LP: #2067900)
+    - SAUCE: Revert "UBUNTU: SAUCE: apparmor4.0.0 [81/90]: apparmor: convert easy
+      uses of unconfined() to label_mediates()"
+
+  * CVE-2024-50117
+    - drm/amd: Guard against bad data for ATIF ACPI method
+
+  * CVE-2024-56582
+    - btrfs: fix use-after-free in btrfs_encoded_read_endio()
+
+  * CVE-2024-53165
+    - sh: intc: Fix use-after-free bug in register_intc_controller()
+
+  * CVE-2024-53156
+    - wifi: ath9k: add range check for conn_rsp_epid in htc_connect_service()
+
+  * CVE-2024-56663
+    - wifi: nl80211: fix NL80211_ATTR_MLO_LINK_ID off-by-one
+
+  * CVE-2024-56614
+    - xsk: fix OOB map writes when deleting elements
+
+  * VM boots slowly with large-BAR GPU Passthrough due to pci/probe.c redundancy
+    (LP: #2097389)
+    - PCI: Batch BAR sizing operations
+
+  * Noble update: upstream stable patchset 2025-02-04 (LP: #2097393)
+    - Revert "PCI/MSI: Provide stubs for IMS functions"
+    - gfs2: Revert "introduce qd_bh_get_or_undo"
+    - gfs2: qd_check_sync cleanups
+    - gfs2: Revert "ignore negated quota changes"
+    - Revert "powerpc/ps3_defconfig: Disable PPC64_BIG_ENDIAN_ELF_ABI_V2"
+    - tracing: Have saved_cmdlines arrays all in one allocation
+    - spi: spi-fsl-lpspi: remove redundant spi_controller_put call
+    - ata: ahci: Add mask_port_map module parameter
+    - ASoC: tas2781: mark dvc_tlv with __maybe_unused
+    - scsi: sd: Do not repeat the starting disk message
+    - bootconfig: Fix the kerneldoc of _xbc_exit()
+    - perf sched: Move start_work_mutex and work_done_wait_mutex initialization to
+      perf_sched__replay()
+    - perf sched: Fix memory leak in perf_sched__map()
+    - perf sched: Move curr_thread initialization to perf_sched__map()
+    - perf sched: Move curr_pid and cpu_last_switched initialization to
+      perf_sched__{lat|map|replay}()
+    - libsubcmd: Don't free the usage string
+    - selftests: Introduce Makefile variable to list shared bash scripts
+    - jbd2: fix kernel-doc for j_transaction_overhead_buffers
+    - lib/build_OID_registry: avoid non-destructive substitution for Perl < 5.13.2
+      compat
+    - drm/amd/display: Remove a redundant check in authenticated_dp
+    - drm/amd/display: Revert "Check HDCP returned status"
+    - zram: don't free statically defined names
+    - x86/amd_nb: Add new PCI IDs for AMD family 0x1a
+    - rtnetlink: change nlk->cb_mutex role
+    - rtnetlink: add RTNL_FLAG_DUMP_UNLOCKED flag
+    - mpls: no longer hold RTNL in mpls_netconf_dump_devconf()
+    - phonet: no longer hold RTNL in route_dumpit()
+    - rcu/nocb: Make IRQs disablement symmetric
+    - HID: asus: add ROG Ally N-Key ID and keycodes
+    - HID: asus: add ROG Z13 lightbar
+    - hid-asus: add ROG Ally X prod ID to quirk list
+    - scsi: Revert "scsi: sd: Do not repeat the starting disk message"
+    - btrfs: fix uninitialized pointer free in add_inode_ref()
+    - btrfs: fix uninitialized pointer free on read_alloc_one_name() error
+    - ksmbd: fix user-after-free from session log off
+    - ALSA: hda/conexant - Fix audio routing for HP EliteOne 1000 G2
+    - mptcp: pm: fix UaF read in mptcp_pm_nl_rm_addr_or_subflow
+    - net: enetc: remove xdp_drops statistic from enetc_xdp_drop()
+    - net: enetc: block concurrent XDP transmissions during ring reconfiguration
+    - net: enetc: disable Tx BD rings after they are empty
+    - net: enetc: disable NAPI after all rings are disabled
+    - net: enetc: add missing static descriptor and inline keyword
+    - posix-clock: Fix missing timespec64 check in pc_clock_settime()
+    - udp: Compute L4 checksum as usual when not segmenting the skb
+    - arm64: probes: Remove broken LDR (literal) uprobe support
+    - arm64: probes: Fix simulate_ldr*_literal()
+    - arm64: probes: Fix uprobes for big-endian kernels
+    - net: macb: Avoid 20s boot delay by skipping MDIO bus registration for fixed-
+      link PHY
+    - net: microchip: vcap api: Fix memory leaks in vcap_api_encode_rule_test()
+    - maple_tree: correct tree corruption on spanning store
+    - nilfs2: propagate directory read errors from nilfs_find_entry()
+    - fat: fix uninitialized variable
+    - mm/mremap: fix move_normal_pmd/retract_page_tables race
+    - mm/swapfile: skip HugeTLB pages for unuse_vma
+    - mm/damon/tests/sysfs-kunit.h: fix memory leak in
+      damon_sysfs_test_add_targets()
+    - tcp: fix mptcp DSS corruption due to large pmtu xmit
+    - net: fec: Move `fec_ptp_read()` to the top of the file
+    - net: fec: Remove duplicated code
+    - mptcp: prevent MPC handshake on port-based signal endpoints
+    - iommu/vt-d: Fix incorrect pci_for_each_dma_alias() for non-PCI devices
+    - s390/sclp: Deactivate sclp after all its users
+    - s390/sclp_vt220: Convert newlines to CRLF instead of LFCR
+    - KVM: s390: gaccess: Check if guest address is in memslot
+    - KVM: s390: Change virtual to physical address access in diag 0x258 handler
+    - x86/cpufeatures: Define X86_FEATURE_AMD_IBPB_RET
+    - x86/cpufeatures: Add a IBPB_NO_RET BUG flag
+    - x86/entry: Have entry_ibpb() invalidate return predictions
+    - x86/bugs: Skip RSB fill at VMEXIT
+    - x86/bugs: Do not use UNTRAIN_RET with IBPB on entry
+    - fgraph: Use CPU hotplug mechanism to initialize idle shadow stacks
+    - blk-rq-qos: fix crash on rq_qos_wait vs. rq_qos_wake_function race
+    - io_uring/sqpoll: close race on waiting for sqring entries
+    - blk-mq: setup queue ->tag_set before initializing hctx
+    - ublk: don't allow user copy for unprivileged device
+    - selftest: hid: add the missing tests directory
+    - Input: xpad - add support for MSI Claw A1M
+    - scsi: mpi3mr: Correct a test in mpi3mr_sas_port_add()
+    - scsi: mpi3mr: Validate SAS port assignments
+    - scsi: ufs: core: Set SDEV_OFFLINE when UFS is shut down
+    - scsi: ufs: core: Fix the issue of ICU failure
+    - scsi: ufs: core: Requeue aborted request
+    - drm/radeon: Fix encoder->possible_clones
+    - drm/i915/dp_mst: Handle error during DSC BW overhead/slice calculation
+    - drm/i915/dp_mst: Don't require DSC hblank quirk for a non-DSC compatible
+      mode
+    - drm/xe/xe_sync: initialise ufence.signalled
+    - drm/xe/ufence: ufence can be signaled right after wait_woken
+    - drm/vmwgfx: Cleanup kms setup without 3d
+    - drm/vmwgfx: Handle surface check failure correctly
+    - drm/amdgpu/pm: Fix code alignment issue
+    - drm/amdgpu/smu13: always apply the powersave optimization
+    - drm/amdgpu/swsmu: Only force workload setup on init
+    - iio: dac: ad5770r: add missing select REGMAP_SPI in Kconfig
+    - iio: dac: ltc1660: add missing select REGMAP_SPI in Kconfig
+    - iio: dac: stm32-dac-core: add missing select REGMAP_MMIO in Kconfig
+    - iio: adc: ti-ads8688: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: hid-sensors: Fix an error handling path in
+      _hid_sensor_set_report_latency()
+    - iio: light: veml6030: fix ALS sensor resolution
+    - iio: light: veml6030: fix IIO device retrieval from embedded device
+    - iio: light: opt3001: add missing full-scale range value
+    - iio: amplifiers: ada4250: add missing select REGMAP_SPI in Kconfig
+    - iio: frequency: adf4377: add missing select REMAP_SPI in Kconfig
+    - iio: light: bu27008: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: resolver: ad2s1210 add missing select REGMAP in Kconfig
+    - iio: pressure: bm1390: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: dac: ad5766: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: proximity: mb1232: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: dac: ad3552r: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: adc: ti-lmp92064: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: adc: ti-lmp92064: add missing select REGMAP_SPI in Kconfig
+    - iio: adc: ti-ads124s08: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: resolver: ad2s1210: add missing select (TRIGGERED_)BUFFER in Kconfig
+    - iio: accel: kx022a: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - Bluetooth: Call iso_exit() on module unload
+    - Bluetooth: Remove debugfs directory on module init failure
+    - Bluetooth: ISO: Fix multiple init when debugfs is disabled
+    - Bluetooth: btusb: Fix not being able to reconnect after suspend
+    - Bluetooth: btusb: Fix regression with fake CSR controllers 0a12:0001
+    - vt: prevent kernel-infoleak in con_font_get()
+    - xhci: tegra: fix checked USB2 port number
+    - xhci: Fix incorrect stream context type macro
+    - xhci: Mitigate failed set dequeue pointer commands
+    - USB: serial: option: add support for Quectel EG916Q-GL
+    - USB: serial: option: add Telit FN920C04 MBIM compositions
+    - usb: typec: qcom-pmic-typec: fix sink status being overwritten with RP_DEF
+    - usb: dwc3: Wait for EndXfer completion before restoring GUSB2PHYCFG
+    - misc: microchip: pci1xxxx: add support for NVMEM_DEVID_AUTO for EEPROM
+      device
+    - misc: microchip: pci1xxxx: add support for NVMEM_DEVID_AUTO for OTP device
+    - serial: imx: Update mctrl old_status on RTSD interrupt
+    - parport: Proper fix for array out-of-bounds access
+    - x86/resctrl: Annotate get_mem_config() functions as __init
+    - x86/apic: Always explicitly disarm TSC-deadline timer
+    - x86/CPU/AMD: Only apply Zenbleed fix for Zen2 during late microcode load
+    - x86/entry_32: Do not clobber user EFLAGS.ZF
+    - x86/entry_32: Clear CPU buffers after register restore in NMI return
+    - tty: n_gsm: Fix use-after-free in gsm_cleanup_mux
+    - x86/bugs: Use code segment selector for VERW operand
+    - pinctrl: intel: platform: fix error path in device_for_each_child_node()
+    - pinctrl: ocelot: fix system hang on level based interrupts
+    - pinctrl: stm32: check devm_kasprintf() returned value
+    - pinctrl: apple: check devm_kasprintf() returned value
+    - irqchip/gic-v4: Don't allow a VMOVP on a dying VPE
+    - irqchip/sifive-plic: Unmask interrupt in plic_irq_enable()
+    - serial: qcom-geni: fix polled console initialisation
+    - serial: qcom-geni: revert broken hibernation support
+    - serial: qcom-geni: fix shutdown race
+    - serial: qcom-geni: fix dma rx cancellation
+    - serial: qcom-geni: fix receiver enable
+    - mm: vmscan.c: fix OOM on swap stress test
+    - ALSA: hda/conexant - Use cached pin control for Node 0x1d on HP EliteOne
+      1000 G2
+    - Upstream stable to v6.6.57, v6.11.5
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301)
+    - Revert "perf callchain: Fix stitch LBR memory leaks"
+    - ASoC: amd: acp: add ZSC control register programming sequence
+    - virtio: rename virtio_config_enabled to virtio_config_core_enabled
+    - virtio: allow driver to disable the configure change notification
+    - virtio-net: synchronize operstate with admin state on up/down
+    - virtio-net: synchronize probe with ndo_set_features
+    - wifi: rtw89: limit the PPDU length for VHT rate to 0x40000
+    - af_unix: Don't call skb_get() for OOB skb.
+    - af_unix: Remove single nest in manage_oob().
+    - af_unix: Rename unlinked_skb in manage_oob().
+    - af_unix: Move spin_lock() in manage_oob().
+    - iommu/amd: Move allocation of the top table into v1_alloc_pgtable
+    - iommu/amd: Set the pgsize_bitmap correctly
+    - drm/xe: Move and export xe_hw_engine lookup.
+    - drm/msm/dp: rename wide_bus_en to wide_bus_supported
+    - drm/msm/dp: enable widebus on all relevant chipsets
+    - bpf, arm64: Fix tailcall hierarchy
+    - libbpf: Don't take direct pointers into BTF data from st_ops
+    - s390/entry: Move early program check handler to entry.S
+    - selftests/bpf: fix to avoid __msg tag de-duplication by clang
+    - libbpf: Ensure new BTF objects inherit input endianness
+    - PCI: dwc: ep: Rename dw_pcie_ep_exit() to dw_pcie_ep_deinit()
+    - PCI: qcom-ep: Enable controller resources like PHY only after refclk is
+      available
+    - net: ravb: Fix maximum TX frame size for GbEth devices
+    - ravb: Make it clear the information relates to maximum frame size
+    - net: ravb: Fix R-Car RX frame size limit
+    - netfilter: nf_tables: missing objects with no memcg accounting
+    - PCI: dra7xx: Fix error handling when IRQ request fails in probe
+    - KVM: x86: Re-split x2APIC ICR into ICR+ICR2 for AMD (x2AVIC)
+    - intel_idle: fix ACPI _CST matching for newer Xeon platforms
+    - wifi: mt76: mt7925: fix a potential association failure upon resuming
+    - cifs: Remove intermediate object of failed create reparse call
+    - drm/amd/display: Disable replay if VRR capability is false
+    - drm/amd/display: Fix VRR cannot enable
+    - l2tp: free sessions using rcu
+    - net: skbuff: sprinkle more __GFP_NOWARN on ingress allocs
+    - nvme: fix metadata handling in nvme-passthrough
+    - wifi: wilc1000: Do not operate uninitialized hardware during suspend/resume
+    - x86/apic: Remove logical destination mode for 64-bit
+    - pmdomain: core: Use dev_name() instead of kobject_get_path() in debugfs
+    - drm/xe: Name and document Wa_14019789679
+    - drm/xe: Add timeout to preempt fences
+    - drm/amd/display: Fix possible overflow in integer multiplication
+    - ext4: fix error message when rejecting the default hash
+    - power: supply: Drop use_cnt check from power_supply_property_is_writeable()
+    - ALSA: hda/realtek: fix mute/micmute LED for HP mt645 G8
+    - drm/xe: Generate oob before compiling anything
+    - clk: qcom: gcc-sc8180x: Register QUPv3 RCGs for DFS on sc8180x
+    - drm/amd/display: Restore Optimized pbn Value if Failed to Disable DSC
+    - Revert "drm/amd/display: Skip Recompute DSC Params if no Stream on Link"
+    - pmdomain: core: Reduce debug summary table width
+    - fs/ntfs3: Do not call file_modified if collapse range failed
+    - fs/ntfs3: Optimize large writes into sparse file
+    - fs/ntfs3: Fix sparse warning in ni_fiemap
+    - fs/ntfs3: Refactor enum_rstbl to suppress static checker
+    - virtio_console: fix misc probe bugs
+    - ntfs3: Change to non-blocking allocation in ntfs_d_hash
+    - bpf: Call the missed btf_record_free() when map creation fails
+    - selftests/bpf: Fix ARG_PTR_TO_LONG {half-,}uninitialized test
+    - bpf: Check percpu map value size first
+    - s390/facility: Disable compile time optimization for decompressor code
+    - s390/mm: Add cond_resched() to cmm_alloc/free_pages()
+    - bpf, x64: Fix a jit convergence issue
+    - ext4: nested locking for xattr inode
+    - s390/cpum_sf: Remove WARN_ON_ONCE statements
+    - ktest.pl: Avoid false positives with grub2 skip regex
+    - soundwire: intel_bus_common: enable interrupts before exiting reset
+    - PCI: Add function 0 DMA alias quirk for Glenfly Arise chip
+    - clk: bcm: bcm53573: fix OF node leak in init
+    - PCI: Add ACS quirk for Qualcomm SA8775P
+    - i2c: i801: Use a different adapter-name for IDF adapters
+    - PCI: Mark Creative Labs EMU20k2 INTx masking as broken
+    - RISC-V: Don't have MAX_PHYSMEM_BITS exceed phys_addr_t
+    - mfd: intel_soc_pmic_chtwc: Make Lenovo Yoga Tab 3 X90F DMI match less strict
+    - mfd: intel-lpss: Add Intel Arrow Lake-H LPSS PCI IDs
+    - mfd: intel-lpss: Rename SPI intel_lpss_platform_info structs
+    - mfd: intel-lpss: Add Intel Panther Lake LPSS PCI IDs
+    - riscv: Omit optimized string routines when using KASAN
+    - riscv: avoid Imbalance in RAS
+    - RDMA/mlx5: Enforce umem boundaries for explicit ODP page faults
+    - PCI: qcom: Disable mirroring of DBI and iATU register space in BAR region
+    - PCI: endpoint: Assign PCI domain number for endpoint controllers
+    - soundwire: cadence: re-check Peripheral status with delayed_work
+    - riscv/kexec_file: Fix relocation type R_RISCV_ADD16 and R_RISCV_SUB16
+      unknown
+    - media: videobuf2-core: clear memory related fields in
+      __vb2_plane_dmabuf_put()
+    - remoteproc: imx_rproc: Use imx specific hook for find_loaded_rsc_table
+    - usb: chipidea: udc: enable suspend interrupt after usb reset
+    - usb: dwc2: Adjust the timing of USB Driver Interrupt Registration in the
+      Crashkernel Scenario
+    - xhci: dbc: Fix STALL transfer event handling
+    - usb: host: xhci-plat: Parse xhci-missing_cas_quirk and apply quirk
+    - comedi: ni_routing: tools: Check when the file could not be opened
+    - LoongArch: Fix memleak in pci_acpi_scan_root()
+    - netfilter: nf_nat: don't try nat source port reallocation for reverse dir
+      clash
+    - netfilter: nf_reject: Fix build warning when CONFIG_BRIDGE_NETFILTER=n
+    - tools/iio: Add memory allocation failure check for trigger_name
+    - staging: vme_user: added bound check to geoid
+    - driver core: bus: Return -EIO instead of 0 when show/store invalid bus
+      attribute
+    - scsi: lpfc: Add ELS_RSP cmd to the list of WQEs to flush in
+      lpfc_els_flush_cmd()
+    - scsi: lpfc: Revise TRACE_EVENT log flag severities from KERN_ERR to
+      KERN_WARNING
+    - NFSD: Mark filecache "down" if init fails
+    - nfsd: nfsd_destroy_serv() must call svc_destroy() even if nfsd_startup_net()
+      failed
+    - ice: set correct dst VSI in only LAN filters
+    - ice: clear port vlan config during reset
+    - ice: disallow DPLL_PIN_STATE_SELECTABLE for dpll output pins
+    - ice: fix VLAN replay after reset
+    - SUNRPC: Fix integer overflow in decode_rc_list()
+    - tcp: fix to allow timestamp undo if no retransmits were sent
+    - tcp: fix tcp_enter_recovery() to zero retrans_stamp when it's safe
+    - tcp: fix TFO SYN_RECV to not zero retrans_stamp with retransmits out
+    - rxrpc: Fix uninitialised variable in rxrpc_send_data()
+    - selftests: net: no_forwarding: fix VID for $swp2 in one_bridge_two_pvids()
+      test
+    - Bluetooth: btusb: Don't fail external suspend requests
+    - net: phy: bcm84881: Fix some error handling paths
+    - Revert "net: stmmac: set PP_FLAG_DMA_SYNC_DEV only if XDP is enabled"
+    - net: ethernet: adi: adin1110: Fix some error handling path in
+      adin1110_read_fifo()
+    - net: dsa: b53: fix jumbo frame mtu check
+    - net: dsa: b53: fix max MTU for 1g switches
+    - net: dsa: b53: fix max MTU for BCM5325/BCM5365
+    - net: dsa: b53: allow lower MTUs on BCM5325/5365
+    - net: dsa: b53: fix jumbo frames on 10/100 ports
+    - drm/nouveau: pass cli to nouveau_channel_new() instead of drm+device
+    - nouveau/dmem: Fix privileged error in copy engine channel
+    - gpio: aspeed: Add the flush write to ensure the write complete.
+    - gpio: aspeed: Use devm_clk api to manage clock source
+    - powercap: intel_rapl_tpmi: Ignore minor version change
+    - ice: Fix netif_is_ice() in Safe Mode
+    - ice: Flush FDB entries before reset
+    - e1000e: change I219 (19) devices to ADP
+    - net: ibm: emac: mal: fix wrong goto
+    - btrfs: zoned: fix missing RCU locking in error message when loading zone
+      info
+    - sctp: ensure sk_state is set to CLOSED if hashing fails in sctp_listen_start
+    - netfilter: fib: check correct rtable in vrf setups
+    - net: ibm: emac: mal: add dcr_unmap to _remove
+    - net: dsa: refuse cross-chip mirroring operations
+    - rtnetlink: Add bulk registration helpers for rtnetlink message handlers.
+    - vxlan: Handle error of rtnl_register_module().
+    - bridge: Handle error of rtnl_register_module().
+    - mctp: Handle error of rtnl_register_module().
+    - mpls: Handle error of rtnl_register_module().
+    - phonet: Handle error of rtnl_register_module().
+    - rcu/nocb: Fix rcuog wake-up from offline softirq
+    - x86/amd_nb: Add new PCI IDs for AMD family 1Ah model 60h
+    - HID: multitouch: Add support for lenovo Y9000P Touchpad
+    - hwmon: intel-m10-bmc-hwmon: relabel Columbiaville to CVL Die Temperature
+    - hwmon: (tmp513) Add missing dependency on REGMAP_I2C
+    - hwmon: (mc34vr500) Add missing dependency on REGMAP_I2C
+    - hwmon: (adm9240) Add missing dependency on REGMAP_I2C
+    - hwmon: (adt7470) Add missing dependency on REGMAP_I2C
+    - hwmon: (ltc2991) Add missing dependency on REGMAP_I2C
+    - HID: plantronics: Workaround for an unexcepted opposite volume key
+    - Revert "usb: yurex: Replace snprintf() with the safer scnprintf() variant"
+    - usb: dwc3: core: Stop processing of pending events if controller is halted
+    - usb: xhci: Fix problem with xhci resume from suspend
+    - usb: storage: ignore bogus device raised by JieLi BR21 USB sound chip
+    - usb: dwc3: re-enable runtime PM after failed resume
+    - usb: gadget: core: force synchronous registration
+    - hid: intel-ish-hid: Fix uninitialized variable 'rv' in
+      ish_fw_xfer_direct_dma
+    - ACPI: resource: Make Asus ExpertBook B2402 matches cover more models
+    - ACPI: resource: Make Asus ExpertBook B2502 matches cover more models
+    - drm/amdkfd: Fix an eviction fence leak
+    - drm/amd/display: fix hibernate entry for DCN35+
+    - drm/xe/guc_submit: fix xa_store() error checking
+    - drm/i915/hdcp: fix connector refcounting
+    - drm/xe/ct: fix xa_store() error checking
+    - scsi: ufs: Use pre-calculated offsets in ufshcd_init_lrb()
+    - mmc: sdhci-of-dwcmshc: Prevent stale command interrupt handling
+    - mptcp: fallback when MPTCP opts are dropped after 1st data
+    - ata: libata: avoid superfluous disk spin down + spin up during hibernation
+    - OPP: fix error code in dev_pm_opp_set_config()
+    - net: dsa: lan9303: ensure chip reset and wait for READY status
+    - mptcp: pm: do not remove closing subflows
+    - powercap: intel_rapl_tpmi: Fix bogus register reading
+    - selftests/mm: fix incorrect buffer->mirror size in hmm2 double_map test
+    - selftests/rseq: Fix mm_cid test failure
+    - btrfs: split remaining space to discard in chunks
+    - btrfs: add cancellation points to trim loops
+    - fs/proc/kcore.c: allow translation of physical memory addresses
+    - io_uring/rw: fix cflags posting for single issue multishot read
+    - Upstream stable to v6.6.56, v6.11.1, v6.11.2, v6.11.3, v6.11.4
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50182
+    - secretmem: disable memfd_secret() if arch cannot set direct map
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50019
+    - kthread: unpark only parked kthread
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50096
+    - nouveau/dmem: Fix vulnerability in migrate_to_ram upon copy error
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50020
+    - ice: Fix improper handling of refcount in ice_sriov_set_msix_vec_count()
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50021
+    - ice: Fix improper handling of refcount in ice_dpll_init_rclk_pins()
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50022
+    - device-dax: correct pgoff align in dax_set_mapping()
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50185
+    - mptcp: handle consistently DSS corruption
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50023
+    - net: phy: Remove LED entry from LEDs list on unregister
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50024
+    - net: Fix an unsafe loop on the list
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50186
+    - net: explicitly clear the sk pointer, when pf->create fails
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50025
+    - scsi: fnic: Move flush_work initialization out of if block
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50026
+    - scsi: wd33c93: Don't use stale scsi_pointer value
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50027
+    - thermal: core: Free tzp copy along with the thermal zone
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50028
+    - thermal: core: Reference count the zone in thermal_zone_get_by_id()
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50029
+    - Bluetooth: hci_conn: Fix UAF in hci_enhanced_setup_sync
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50030
+    - drm/xe/ct: prevent UAF in send_recv()
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50187
+    - drm/vc4: Stop the active perfmon before being destroyed
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50031
+    - drm/v3d: Stop the active perfmon before being destroyed
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50189
+    - HID: amd_sfh: Switch to device-managed dmam_alloc_coherent()
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50033
+    - slip: make slhc_remember() more robust against malicious packets
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50035
+    - ppp: fix ppp_async_encode() illegal access
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50036
+    - net: do not delay dst_entries_add() in dst_release()
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50038
+    - netfilter: xtables: avoid NFPROTO_UNSPEC where needed
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50039
+    - net/sched: accept TCA_STAB only for root qdisc
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50040
+    - igb: Do not bring the device up after non-fatal error
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50041
+    - i40e: Fix macvlan leak by synchronizing access to mac_filter_hash
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50042
+    - ice: Fix increasing MSI-X on VF
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50093
+    - thermal: intel: int340x: processor: Fix warning during module unload
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50044
+    - Bluetooth: RFCOMM: FIX possible deadlock in rfcomm_sk_state_change
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50045
+    - netfilter: br_netfilter: fix panic with metadata_dst skb
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50188
+    - net: phy: dp83869: fix memory corruption when enabling fiber
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50046
+    - NFSv4: Prevent NULL-pointer dereference in nfs42_complete_copies()
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50180
+    - fbdev: sisfb: Fix strbuf array overflow
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50047
+    - smb: client: fix UAF in async decryption
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50048
+    - fbcon: Fix a NULL pointer dereference issue in fbcon_putcs
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50049
+    - drm/amd/display: Check null pointer before dereferencing se
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50090
+    - drm/xe/oa: Fix overflow in oa batch buffer
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50183
+    - scsi: lpfc: Ensure DA_ID handling completion before deleting an NPIV
+      instance
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50055
+    - driver core: bus: Fix double free in driver API bus_register()
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50056
+    - usb: gadget: uvc: Fix ERR_PTR dereference in uvc_v4l2.c
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50184
+    - virtio_pmem: Check device status before requesting flush
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50057
+    - usb: typec: tipd: Free IRQ only if it was requested before
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50058
+    - serial: protect uart_port_dtr_rts() in uart_shutdown() too
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50181
+    - clk: imx: Remove CLK_SET_PARENT_GATE for DRAM mux for i.MX7D
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50059
+    - ntb: ntb_hw_switchtec: Fix use after free vulnerability in
+      switchtec_ntb_remove due to race condition
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50060
+    - io_uring: check if we need to reschedule during overflow flush
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50061
+    - i3c: master: cdns: Fix use after free vulnerability in cdns_i3c_master
+      Driver Due to Race Condition
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50062
+    - RDMA/rtrs-srv: Avoid null pointer deref during path establishment
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50095
+    - RDMA/mad: Improve handling of timed out WRs of mad agent
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50063
+    - bpf: Prevent tail call between progs attached to different hooks
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50191
+    - ext4: don't set SB_RDONLY after filesystem errors
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50064
+    - zram: free secondary algorithms names
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50089
+    - unicode: Don't special case ignorable code points
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49865
+    - drm/xe/vm: move xa_alloc to prevent UAF
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49968
+    - ext4: filesystems without casefold feature cannot be mounted with siphash
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49893
+    - drm/amd/display: Check stream_status before it is used
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49972
+    - drm/amd/display: Deallocate DML memory if allocation fails
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49914
+    - drm/amd/display: Add null check for pipe_ctx->plane_state in
+      dcn20_program_pipe
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49920
+    - drm/amd/display: Check null pointers before multiple uses
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49921
+    - drm/amd/display: Check null pointers before used
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50009
+    - cpufreq: amd-pstate: add check for cpufreq_cpu_get's return value
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-47726
+    - f2fs: fix to wait dio completion
+
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-47711
+    - af_unix: Don't return OOB skb in manage_oob().
+
+  * CVE-2024-53170
+    - block: fix uaf for flush rq while iterating tags
+
+  * CVE-2024-50148
+    - Bluetooth: bnep: fix wild-memory-access in proto_unregister
+
+  * CVE-2024-50134
+    - drm/vboxvideo: Replace fake VLA at end of vbva_mouse_pointer_shape with real
+      VLA
+
+  * CVE-2024-50171
+    - net: systemport: fix potential memory leak in bcm_sysport_xmit()
+
+  * CVE-2024-50229
+    - nilfs2: fix potential deadlock with newly created symlinks
+
+  * CVE-2024-50233
+    - staging: iio: frequency: ad9832: fix division by zero in
+      ad9832_calc_freqreg()
+
+  * [Lenovo Ubuntu 24.04 Bug] dmesg show "spi-nor: probe of spi0.0 failed with
+    error -95" (LP: #2070339)
+    - mtd: core: Don't fail mtd_otp_nvmem_add() if OTP is unsupported
+    - mtd: core: Align comment with an action in mtd_otp_nvmem_add()
+
+  * python perf module missing in realtime kernel (LP: #2089411)
+    - [Packaging] linux-tools: Add missing python perf symlink
+    - [Packaging] linux-tools: Fix python perf library packaging
+    - [Packaging] linux-tools: Fall back to old python perf path
+
+  * CVE-2024-53104
+    - media: uvcvideo: Skip parsing frames of type UVC_VS_UNDEFINED in
+      uvc_parse_format
+
+ -- Mehmet Basaran <mehmet.basaran@canonical.com>  Fri, 14 Feb 2025 16:04:25 +0300
+
+linux (6.8.0-54.56) noble; urgency=medium
+
+  * CVE-2025-0927
+    - SAUCE: fs: hfs/hfsplus: add key_len boundary check to hfs_bnode_read_key
+
+ -- Manuel Diewald <manuel.diewald@canonical.com>  Fri, 07 Feb 2025 22:09:50 +0100
+
+linux (6.8.0-53.55) noble; urgency=medium
+
+  * noble/linux: 6.8.0-53.55 -proposed tracker (LP: #2093677)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2025.01.13)
+
+  * generate and ship vmlinux.h to allow packages to build BPF CO-RE
+    (LP: #2050083)
+    - [Packaging] add linux-bpf-dev package
+    - [Packaging] do not attempt to generate BTF header on armhf
+
+  * Unable to boot as a guest on VMware ESX (LP: #2091941)
+    - ptp/vmware: Use VMware hypercall API
+    - input/vmmouse: Use VMware hypercall API
+    - drm/vmwgfx: Use VMware hypercall API
+    - x86/vmware: Use VMware hypercall API
+    - x86/vmware: Correct macro names
+    - x86/vmware: Remove legacy VMWARE_HYPERCALL* macros
+
+  * When /dev/vmbus/hv_kvp is not present, disable hv-kvp-daemon (LP: #2091744)
+    - [Packaging] disable hv-kvp-daemon if needed
+
+  * Backport "netkit: Add option for scrubbing skb meta data" to 6.8
+    (LP: #2091184)
+    - netkit: Add option for scrubbing skb meta data
+
+  * KVM: Cache CPUID at KVM.ko module init to reduce latency of VM-Enter and VM-
+    Exit (LP: #2093146)
+    - KVM: x86: Cache CPUID.0xD XSTATE offsets+sizes during module init
+
+  * [SRU] add support of QCA BT 0489:e0fc (LP: #2085406)
+    - Bluetooth: btusb: add Foxconn 0xe0fc for Qualcomm WCN785x
+
+  * ice driver RTNL assertion failed warning on shutdown/reboot (LP: #2091107)
+    - ice: Remove and readd netdev during devlink reload
+
+  * vfio_pci soft lockup on VM start while using PCIe passthrough (LP: #2089306)
+    - SAUCE: Revert "vfio/pci: Insert full vma on mmap'd MMIO fault"
+    - SAUCE: Revert "vfio/pci: Use unmap_mapping_range()"
+
+  * [SRU] Fix error of resume on rtl8168fp (LP: #2087507)
+    - r8169: avoid unsolicited interrupts
+
+  * [SRU] power: intel_pstate: HWP interrupt support for maximum ratio changed
+    (LP: #2090852)
+    - x86/cpufeatures: Add HWP highest perf change feature flag
+    - cpufreq: intel_pstate: Support highest performance change interrupt
+
+  * Noble update: upstream stable patchset 2024-11-29 (LP: #2089884)
+    - static_call: Handle module init failure correctly in
+      static_call_del_module()
+    - static_call: Replace pointless WARN_ON() in static_call_module_notify()
+    - jump_label: Simplify and clarify static_key_fast_inc_cpus_locked()
+    - jump_label: Fix static_key_slow_dec() yet again
+    - scsi: st: Fix input/output error on empty drive reset
+    - scsi: pm8001: Do not overwrite PCI queue mapping
+    - drm/amdgpu: Fix get each xcp macro
+    - mailbox: rockchip: fix a typo in module autoloading
+    - mailbox: bcm2835: Fix timeout during suspend mode
+    - ceph: remove the incorrect Fw reference check when dirtying pages
+    - ieee802154: Fix build error
+    - net: sparx5: Fix invalid timestamps
+    - net/mlx5: Fix error path in multi-packet WQE transmit
+    - net/mlx5: Added cond_resched() to crdump collection
+    - net/mlx5e: Fix NULL deref in mlx5e_tir_builder_alloc()
+    - net/mlx5e: Fix crash caused by calling __xfrm_state_delete() twice
+    - netfilter: uapi: NFTA_FLOWTABLE_HOOK is NLA_NESTED
+    - net: ieee802154: mcr20a: Use IRQF_NO_AUTOEN flag in request_irq()
+    - net: wwan: qcom_bam_dmux: Fix missing pm_runtime_disable()
+    - selftests: netfilter: Fix nft_audit.sh for newer nft binaries
+    - netfilter: nf_tables: prevent nf_skb_duplicated corruption
+    - Bluetooth: MGMT: Fix possible crash on mgmt_index_removed
+    - Bluetooth: MGMT: Fix possible deadlocks
+    - Bluetooth: L2CAP: Fix uaf in l2cap_connect
+    - Bluetooth: hci_core: Fix calling mgmt_device_connected
+    - Bluetooth: btmrvl: Use IRQF_NO_AUTOEN flag in request_irq()
+    - net: Add netif_get_gro_max_size helper for GRO
+    - net: Fix gso_features_check to check for both dev->gso_{ipv4_,}max_size
+    - net: ethernet: lantiq_etop: fix memory disclosure
+    - net: fec: Restart PPS after link state change
+    - net: fec: Reload PTP registers after link-state change
+    - net: avoid potential underflow in qdisc_pkt_len_init() with UFO
+    - net: add more sanity checks to qdisc_pkt_len_init()
+    - net: stmmac: dwmac4: extend timeout for VLAN Tag register busy bit check
+    - ipv4: ip_gre: Fix drops of small packets in ipgre_xmit
+    - net: test for not too small csum_start in virtio_net_hdr_to_skb()
+    - ppp: do not assume bh is held in ppp_channel_bridge_input()
+    - iomap: constrain the file range passed to iomap_file_unshare
+    - dt-bindings: net: xlnx,axi-ethernet: Add missing reg minItems
+    - sctp: set sk_state back to CLOSED if autobind fails in sctp_listen_start
+    - i2c: xiic: improve error message when transfer fails to start
+    - i2c: xiic: Try re-initialization on bus busy timeout
+    - loop: don't set QUEUE_FLAG_NOMERGES
+    - ASoC: atmel: mchp-pdmc: Skip ALSA restoration if substream runtime is
+      uninitialized
+    - ALSA: mixer_oss: Remove some incorrect kfree_const() usages
+    - ALSA: hda/realtek: Fix the push button function for the ALC257
+    - ALSA: hda/generic: Unconditionally prefer preferred_dacs pairs
+    - ASoC: imx-card: Set card.owner to avoid a warning calltrace if SND=m
+    - cifs: Fix buffer overflow when parsing NFS reparse points
+    - cifs: Do not convert delimiter when parsing NFS-style symlinks
+    - ALSA: gus: Fix some error handling paths related to get_bpos() usage
+    - ALSA: hda/conexant: Fix conflicting quirk for System76 Pangolin
+    - wifi: ath9k: fix possible integer overflow in ath9k_get_et_stats()
+    - wifi: rtw89: avoid to add interface to list twice when SER
+    - wifi: ath9k_htc: Use __skb_set_length() for resetting urb before resubmit
+    - crypto: x86/sha256 - Add parentheses around macros' single arguments
+    - crypto: octeontx - Fix authenc setkey
+    - crypto: octeontx2 - Fix authenc setkey
+    - ice: Adjust over allocation of memory in ice_sched_add_root_node() and
+      ice_sched_add_node()
+    - wifi: iwlwifi: mvm: Fix a race in scan abort flow
+    - wifi: iwlwifi: mvm: drop wrong STA selection in TX
+    - wifi: cfg80211: Set correct chandef when starting CAC
+    - net/xen-netback: prevent UAF in xenvif_flush_hash()
+    - net: hisilicon: hip04: fix OF node leak in probe()
+    - net: hisilicon: hns_dsaf_mac: fix OF node leak in hns_mac_get_info()
+    - net: hisilicon: hns_mdio: fix OF node leak in probe()
+    - ACPI: PAD: fix crash in exit_round_robin()
+    - ACPICA: Fix memory leak if acpi_ps_get_next_namepath() fails
+    - ACPICA: Fix memory leak if acpi_ps_get_next_field() fails
+    - e1000e: avoid failing the system during pm_suspend
+    - wifi: mt76: mt7915: disable tx worker during tx BA session enable/disable
+    - net: sched: consistently use rcu_replace_pointer() in taprio_change()
+    - Bluetooth: btusb: Add Realtek RTL8852C support ID 0x0489:0xe122
+    - Bluetooth: btrtl: Set msft ext address filter quirk for RTL8852B
+    - ACPI: video: Add force_vendor quirk for Panasonic Toughbook CF-18
+    - ACPI: CPPC: Add support for setting EPP register in FFH
+    - blk_iocost: fix more out of bound shifts
+    - wifi: ath12k: fix array out-of-bound access in SoC stats
+    - wifi: ath11k: fix array out-of-bound access in SoC stats
+    - wifi: rtw88: select WANT_DEV_COREDUMP
+    - ACPI: EC: Do not release locks during operation region accesses
+    - ACPICA: check null return of ACPI_ALLOCATE_ZEROED() in
+      acpi_db_convert_to_package()
+    - tipc: guard against string buffer overrun
+    - net: mvpp2: Increase size of queue_name buffer
+    - bnxt_en: Extend maximum length of version string by 1 byte
+    - ipv4: Check !in_dev earlier for ioctl(SIOCSIFADDR).
+    - wifi: rtw89: correct base HT rate mask for firmware
+    - ipv4: Mask upper DSCP bits and ECN bits in NETLINK_FIB_LOOKUP family
+    - net: atlantic: Avoid warning about potential string truncation
+    - crypto: simd - Do not call crypto_alloc_tfm during registration
+    - netpoll: Ensure clean state on setup failures
+    - tcp: avoid reusing FIN_WAIT2 when trying to find port in connect() process
+    - wifi: iwlwifi: mvm: use correct key iteration
+    - wifi: iwlwifi: mvm: avoid NULL pointer dereference
+    - ACPICA: iasl: handle empty connection_node
+    - proc: add config & param to block forcing mem writes
+    - [Config] updateconfigs to select PROC_MEM_ALWAYS_FORCE
+    - drivers/perf: arm_spe: Use perf_allow_kernel() for permissions
+    - can: netlink: avoid call to do_set_data_bittiming callback with stale
+      can_priv::ctrlmode
+    - wifi: mt76: mt7915: add dummy HW offload of IEEE 802.11 fragmentation
+    - wifi: mt76: mt7915: hold dev->mt76.mutex while disabling tx worker
+    - wifi: mwifiex: Fix memcpy() field-spanning write warning in
+      mwifiex_cmd_802_11_scan_ext()
+    - nfp: Use IRQF_NO_AUTOEN flag in request_irq()
+    - ALSA: usb-audio: Add input value sanity checks for standard types
+    - x86/ioapic: Handle allocation failures gracefully
+    - ALSA: usb-audio: Define macros for quirk table entries
+    - ALSA: usb-audio: Replace complex quirk lines with macros
+    - ALSA: usb-audio: Add logitech Audio profile quirk
+    - ASoC: codecs: wsa883x: Handle reading version failure
+    - tools/x86/kcpuid: Protect against faulty "max subleaf" values
+    - x86/pkeys: Add PKRU as a parameter in signal handling functions
+    - x86/pkeys: Restore altstack access in sigreturn()
+    - x86/kexec: Add EFI config table identity mapping for kexec kernel
+    - ALSA: asihpi: Fix potential OOB array access
+    - ALSA: hdsp: Break infinite MIDI input flush loop
+    - tools/nolibc: powerpc: limit stack-protector workaround to GCC
+    - selftests/nolibc: avoid passing NULL to printf("%s")
+    - x86/syscall: Avoid memcpy() for ia32 syscall_get_arguments()
+    - hwmon: (nct6775) add G15CF to ASUS WMI monitoring list
+    - fbdev: efifb: Register sysfs groups through driver core
+    - fbdev: pxafb: Fix possible use after free in pxafb_task()
+    - rcuscale: Provide clear error when async specified without primitives
+    - power: reset: brcmstb: Do not go into infinite loop if reset fails
+    - iommu/vt-d: Always reserve a domain ID for identity setup
+    - iommu/vt-d: Fix potential lockup if qi_submit_sync called with 0 count
+    - drm/stm: Avoid use-after-free issues with crtc and plane
+    - drm/amdgpu: disallow multiple BO_HANDLES chunks in one submit
+    - drm/amdgpu: prevent BO_HANDLES error from being overwritten
+    - drm/amdkfd: amdkfd_free_gtt_mem clear the correct pointer
+    - drm/amd/display: Add null check for top_pipe_to_program in
+      commit_planes_for_stream
+    - ata: pata_serverworks: Do not use the term blacklist
+    - ata: sata_sil: Rename sil_blacklist to sil_quirks
+    - HID: Ignore battery for all ELAN I2C-HID devices
+    - drm/amd/display: Handle null 'stream_status' in
+      'planes_changed_for_existing_stream'
+    - drm/amd/display: Check null pointers before using dc->clk_mgr
+    - drm/amd/display: Add null check for 'afb' in
+      amdgpu_dm_plane_handle_cursor_update (v2)
+    - drm/amd/display: fix double free issue during amdgpu module unload
+    - jfs: UBSAN: shift-out-of-bounds in dbFindBits
+    - jfs: Fix uaf in dbFreeBits
+    - jfs: check if leafidx greater than num leaves per dmap tree
+    - scsi: smartpqi: correct stream detection
+    - drm/msm/adreno: Assign msm_gpu->pdev earlier to avoid nullptrs
+    - jfs: Fix uninit-value access of new_ea in ea_buffer
+    - drm/amdgpu: add raven1 gfxoff quirk
+    - drm/amdgpu: enable gfxoff quirk on HP 705G4
+    - drm/amdkfd: Fix resource leak in criu restore queue
+    - HID: multitouch: Add support for Thinkpad X12 Gen 2 Kbd Portfolio
+    - platform/x86: touchscreen_dmi: add nanote-next quirk
+    - drm/stm: ltdc: reset plane transparency after plane disable
+    - drm/amd/display: Check stream before comparing them
+    - drm/amd/display: Check link_res->hpo_dp_link_enc before using it
+    - drm/amd/display: Fix index out of bounds in DCN30 degamma hardware format
+      translation
+    - drm/amd/display: Fix index out of bounds in degamma hardware format
+      translation
+    - drm/amd/display: Fix index out of bounds in DCN30 color transformation
+    - drm/amd/display: Avoid overflow assignment in link_dp_cts
+    - drm/amd/display: Initialize get_bytes_per_element's default to 1
+    - drm/printer: Allow NULL data in devcoredump printer
+    - perf,x86: avoid missing caller address in stack traces captured in uprobe
+    - scsi: lpfc: Update PRLO handling in direct attached topology
+    - drm/amdgpu: fix unchecked return value warning for amdgpu_gfx
+    - perf: Fix event_function_call() locking
+    - scsi: NCR5380: Initialize buffer for MSG IN and STATUS transfers
+    - drm/radeon/r100: Handle unknown family in r100_cp_init_microcode()
+    - drm/amdgpu: Block MMR_READ IOCTL in reset
+    - drm/amdgpu/gfx9: use rlc safe mode for soft recovery
+    - drm/amd/pm: ensure the fw_info is not null before using it
+    - of/irq: Refer to actual buffer size in of_irq_parse_one()
+    - powerpc/pseries: Use correct data types from pseries_hp_errorlog struct
+    - drm/amdgpu/gfx11: use rlc safe mode for soft recovery
+    - drm/amdgpu/gfx10: use rlc safe mode for soft recovery
+    - platform/x86: lenovo-ymc: Ignore the 0x0 state
+    - ksmbd: add refcnt to ksmbd_conn struct
+    - ksmbd: fix use-after-free in SMB request handling
+    - bpf: Make the pointer returned by iter next method valid
+    - ext4: ext4_search_dir should return a proper error
+    - ext4: avoid use-after-free in ext4_ext_show_leaf()
+    - ext4: fix i_data_sem unlock order in ext4_ind_migrate()
+    - bpftool: Fix undefined behavior caused by shifting into the sign bit
+    - iomap: handle a post-direct I/O invalidate race in
+      iomap_write_delalloc_release
+    - bpftool: Fix undefined behavior in qsort(NULL, 0, ...)
+    - spi: spi-imx: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - spi: spi-cadence: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - spi: spi-cadence: Fix missing spi_controller_is_target() check
+    - selftest: hid: add missing run-hid-tools-tests.sh
+    - spi: s3c64xx: fix timeout counters in flush_fifo
+    - selftests: breakpoints: use remaining time to check if suspend succeed
+    - accel/ivpu: Add missing MODULE_FIRMWARE metadata
+    - spi: rpc-if: Add missing MODULE_DEVICE_TABLE
+    - perf: Really fix event_function_call() locking
+    - selftests: vDSO: fix vDSO name for powerpc
+    - selftests: vDSO: fix vdso_config for powerpc
+    - selftests: vDSO: fix vDSO symbols lookup for powerpc64
+    - powerpc/vdso: Flag VDSO64 entry points as functions
+    - selftests/mm: fix charge_reserved_hugetlb.sh test
+    - powerpc/vdso: Fix VDSO data access when running in a non-root time namespace
+    - selftests: vDSO: fix ELF hash table entry size for s390x
+    - selftests: vDSO: fix vdso_config for s390
+    - Revert "ALSA: hda: Conditionally use snooping for AMD HDMI"
+    - platform/x86: ISST: Fix the KASAN report slab-out-of-bounds bug
+    - i2c: stm32f7: Do not prepare/unprepare clock during runtime suspend/resume
+    - i2c: qcom-geni: Use IRQF_NO_AUTOEN flag in request_irq()
+    - i2c: xiic: Wait for TX empty to avoid missed TX NAKs
+    - media: i2c: ar0521: Use cansleep version of gpiod_set_value()
+    - i2c: xiic: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - i2c: designware: fix controller is holding SCL low while ENABLE bit is
+      disabled
+    - rust: sync: require `T: Sync` for `LockedBy::access`
+    - ovl: fail if trusted xattrs are needed but caller lacks permission
+    - firmware: tegra: bpmp: Drop unused mbox_client_to_bpmp()
+    - memory: tegra186-emc: drop unused to_tegra186_emc()
+    - dt-bindings: clock: exynos7885: Fix duplicated binding
+    - spi: bcm63xx: Fix module autoloading
+    - spi: bcm63xx: Fix missing pm_runtime_disable()
+    - power: supply: hwmon: Fix missing temp1_max_alarm attribute
+    - perf/core: Fix small negative period being ignored
+    - parisc: Fix itlb miss handler for 64-bit programs
+    - drm/mediatek: ovl_adaptor: Add missing of_node_put()
+    - drm: Consistently use struct drm_mode_rect for FB_DAMAGE_CLIPS
+    - ALSA: hda/tas2781: Add new quirk for Lenovo Y990 Laptop
+    - ALSA: core: add isascii() check to card ID generator
+    - ALSA: usb-audio: Add delay quirk for VIVO USB-C HEADSET
+    - ALSA: usb-audio: Add native DSD support for Luxman D-08u
+    - ALSA: line6: add hw monitor volume control to POD HD500X
+    - ALSA: hda/realtek: Add quirk for Huawei MateBook 13 KLV-WX9
+    - ALSA: hda/realtek: Add a quirk for HP Pavilion 15z-ec200
+    - ext4: correct encrypted dentry name hash when not casefolded
+    - ext4: fix slab-use-after-free in ext4_split_extent_at()
+    - ext4: propagate errors from ext4_find_extent() in ext4_insert_range()
+    - ext4: fix incorrect tid assumption in ext4_fc_mark_ineligible()
+    - ext4: dax: fix overflowing extents beyond inode size when partially writing
+    - ext4: fix incorrect tid assumption in __jbd2_log_wait_for_space()
+    - ext4: drop ppath from ext4_ext_replay_update_ex() to avoid double-free
+    - ext4: aovid use-after-free in ext4_ext_insert_extent()
+    - ext4: fix double brelse() the buffer of the extents path
+    - ext4: fix timer use-after-free on failed mount
+    - ext4: update orig_path in ext4_find_extent()
+    - ext4: fix incorrect tid assumption in ext4_wait_for_tail_page_commit()
+    - ext4: fix incorrect tid assumption in jbd2_journal_shrink_checkpoint_list()
+    - ext4: fix fast commit inode enqueueing during a full journal commit
+    - ext4: use handle to mark fc as ineligible in __track_dentry_update()
+    - ext4: mark fc as ineligible using an handle in ext4_xattr_set()
+    - parisc: Fix 64-bit userspace syscall path
+    - parisc: Allow mmap(MAP_STACK) memory to automatically expand upwards
+    - parisc: Fix stack start for ADDR_NO_RANDOMIZE personality
+    - drm/rockchip: vop: clear DMA stop bit on RK3066
+    - of: address: Report error on resource bounds overflow
+    - of/irq: Support #msi-cells=<0> in of_msi_get_domain
+    - drm: omapdrm: Add missing check for alloc_ordered_workqueue
+    - resource: fix region_intersects() vs add_memory_driver_managed()
+    - jbd2: stop waiting for space when jbd2_cleanup_journal_tail() returns error
+    - jbd2: correctly compare tids with tid_geq function in jbd2_fc_begin_commit
+    - mm: krealloc: consider spare memory for __GFP_ZERO
+    - mm: krealloc: Fix MTE false alarm in __do_krealloc
+    - ocfs2: fix the la space leak when unmounting an ocfs2 volume
+    - ocfs2: fix uninit-value in ocfs2_get_block()
+    - ocfs2: reserve space for inline xattr before attaching reflink tree
+    - ocfs2: cancel dqi_sync_work before freeing oinfo
+    - ocfs2: remove unreasonable unlock in ocfs2_read_blocks
+    - ocfs2: fix null-ptr-deref when journal load failed.
+    - ocfs2: fix possible null-ptr-deref in ocfs2_set_buffer_uptodate
+    - arm64: fix selection of HAVE_DYNAMIC_FTRACE_WITH_ARGS
+    - arm64: Subscribe Microsoft Azure Cobalt 100 to erratum 3194386
+    - riscv: define ILLEGAL_POINTER_VALUE for 64bit
+    - [Config] updateconfigs to set ILLEGAL_POINTER_VALUE for riscv64
+    - exfat: fix memory leak in exfat_load_bitmap()
+    - perf python: Disable -Wno-cast-function-type-mismatch if present on clang
+    - perf hist: Update hist symbol when updating maps
+    - nfsd: fix delegation_blocked() to block correctly for at least 30 seconds
+    - nfsd: map the EBADMSG to nfserr_io to avoid warning
+    - NFSD: Fix NFSv4's PUTPUBFH operation
+    - i3c: master: svc: Fix use after free vulnerability in svc_i3c_master Driver
+      Due to Race Condition
+    - RDMA/mana_ib: use the correct page size for mapping user-mode doorbell page
+    - riscv: Fix kernel stack size when KASAN is enabled
+    - aoe: fix the potential use-after-free problem in more places
+    - media: ov5675: Fix power on/off delay timings
+    - clk: rockchip: fix error for unknown clocks
+    - remoteproc: k3-r5: Fix error handling when power-up failed
+    - clk: qcom: dispcc-sm8250: use CLK_SET_RATE_PARENT for branch clocks
+    - media: sun4i_csi: Implement link validate for sun4i_csi subdev
+    - clk: qcom: gcc-sm8450: Do not turn off PCIe GDSCs during gdsc_disable()
+    - media: uapi/linux/cec.h: cec_msg_set_reply_to: zero flags
+    - clk: qcom: clk-rpmh: Fix overflow in BCM vote
+    - clk: samsung: exynos7885: Update CLKS_NR_FSYS after bindings fix
+    - clk: qcom: gcc-sm8150: De-register gcc_cpuss_ahb_clk_src
+    - media: venus: fix use after free bug in venus_remove due to race condition
+    - clk: qcom: gcc-sm8250: Do not turn off PCIe GDSCs during gdsc_disable()
+    - media: qcom: camss: Remove use_count guard in stop_streaming
+    - media: qcom: camss: Fix ordering of pm_runtime_enable
+    - clk: qcom: gcc-sc8180x: Fix the sdcc2 and sdcc4 clocks freq table
+    - clk: qcom: clk-alpha-pll: Fix CAL_L_VAL override for LUCID EVO PLL
+    - smb: client: use actual path when queryfs
+    - smb3: fix incorrect mode displayed for read-only files
+    - iio: magnetometer: ak8975: Fix reading for ak099xx sensors
+    - vrf: revert "vrf: Remove unnecessary RCU-bh critical section"
+    - gso: fix udp gso fraglist segmentation after pull from frag_list
+    - tomoyo: fallback to realpath if symlink's pathname does not exist
+    - net: stmmac: Fix zero-division error when disabling tc cbs
+    - rtc: at91sam9: fix OF node leak in probe() error path
+    - Input: adp5589-keys - fix NULL pointer dereference
+    - Input: adp5589-keys - fix adp5589_gpio_get_value()
+    - cachefiles: fix dentry leak in cachefiles_open_file()
+    - btrfs: fix a NULL pointer dereference when failed to start a new trasacntion
+    - btrfs: send: fix invalid clone operation for file that got its size
+      decreased
+    - btrfs: wait for fixup workers before stopping cleaner kthread during umount
+    - cpufreq: Avoid a bad reference count on CPU node
+    - gpio: davinci: fix lazy disable
+    - net: pcs: xpcs: fix the wrong register that was written back
+    - Bluetooth: hci_event: Align BR/EDR JUST_WORKS paring with LE
+    - mac802154: Fix potential RCU dereference issue in mac802154_scan_worker
+    - ceph: fix cap ref leak via netfs init_request
+    - tracing/hwlat: Fix a race during cpuhp processing
+    - tracing/timerlat: Drop interface_lock in stop_kthread()
+    - tracing/timerlat: Fix a race during cpuhp processing
+    - tracing/timerlat: Fix duplicated kthread creation due to CPU online/offline
+    - rtla: Fix the help text in osnoise and timerlat top tools
+    - drm/i915/gem: fix bitwise and logical AND mixup
+    - drm/sched: Add locking to drm_sched_entity_modify_sched
+    - drm/amd/display: Add HDR workaround for specific eDP
+    - cpufreq: intel_pstate: Make hwp_notify_lock a raw spinlock
+    - kconfig: qconf: fix buffer overflow in debug links
+    - platform/x86: x86-android-tablets: Fix use after free on
+      platform_device_register() errors
+    - i2c: core: Lock address during client device instantiation
+    - i2c: synquacer: Remove a clk reference from struct synquacer_i2c
+    - i2c: synquacer: Deal with optional PCLK correctly
+    - arm64: cputype: Add Neoverse-N3 definitions
+    - arm64: errata: Expand speculative SSBS workaround once more
+    - io_uring/net: harden multishot termination case for recv
+    - uprobes: fix kernel info leak via "[uprobes]" vma
+    - mm: z3fold: deprecate CONFIG_Z3FOLD
+    - [Config] updateconfigs for deprecated CONFIG_Z3FOLD
+    - drm/amd/display: Allow backlight to go below
+      `AMDGPU_DM_DEFAULT_MIN_BACKLIGHT`
+    - build-id: require program headers to be right after ELF header
+    - lib/buildid: harden build ID parsing logic
+    - sched: psi: fix bogus pressure spikes from aggregation race
+    - net: mana: Enable MANA driver on ARM64 with 4K page size
+    - net: mana: Add support for page sizes other than 4KB on ARM64
+    - [Config] updateconfigs for MICROSOFT_MANA
+    - RDMA/mana_ib: use the correct page table index based on hardware page size
+    - media: imx335: Fix reset-gpio handling
+    - remoteproc: k3-r5: Acquire mailbox handle during probe routine
+    - remoteproc: k3-r5: Delay notification of wakeup event
+    - dt-bindings: clock: qcom: Add missing UFS QREF clocks
+    - dt-bindings: clock: qcom: Add GPLL9 support on gcc-sc8180x
+    - iio: pressure: bmp280: Improve indentation and line wrapping
+    - iio: pressure: bmp280: Use BME prefix for BME280 specifics
+    - iio: pressure: bmp280: Fix regmap for BMP280 device
+    - iio: pressure: bmp280: Fix waiting time for BMP3xx configuration
+    - r8169: Fix spelling mistake: "tx_underun" -> "tx_underrun"
+    - r8169: add tally counter fields added with RTL8125
+    - clk: qcom: gcc-sc8180x: Add GPLL9 support
+    - ACPI: battery: Simplify battery hook locking
+    - ACPI: battery: Fix possible crash when unregistering a battery hook
+    - btrfs: drop the backref cache during relocation if we commit
+    - drm/rockchip: vop: enable VOP_FEATURE_INTERNAL_RGB on RK3066
+    - rxrpc: Fix a race between socket set up and I/O thread creation
+    - vhost/scsi: null-ptr-dereference in vhost_scsi_get_req()
+    - crypto: octeontx* - Select CRYPTO_AUTHENC
+    - drm/amd/display: Revert Avoid overflow assignment
+    - perf report: Fix segfault when 'sym' sort key is not used
+    - drm/amd/display: enable_hpo_dp_link_output: Check link_res->hpo_dp_link_enc
+      before using it
+    - Revert "ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path"
+    - perf python: Allow checking for the existence of warning options in clang
+    - drm/i915/dp: Fix AUX IO power enabling for eDP PSR
+    - drm/amd/display: handle nulled pipe context in DCE110's set_drr()
+    - selftests: netfilter: Add missing return value
+    - afs: Fix the setting of the server responding flag
+    - net: dsa: improve shutdown sequence
+    - bridge: mcast: Fail MDB get request on empty entry
+    - net/ncsi: Disable the ncsi work before freeing the associated structure
+    - drm/xe: Restore pci state upon resume
+    - drm/xe: Resume TDR after GT reset
+    - drm/xe: Prevent null pointer access in xe_migrate_copy
+    - fs/inode: Prevent dump_mapping() accessing invalid dentry.d_name.name
+    - ACPI: resource: Skip IRQ override on Asus Vivobook Go E1404GAB
+    - nvme-keyring: restrict match length for version '1' identifiers
+    - nvme-tcp: sanitize TLS key handling
+    - nvme-fabrics: typo in nvmf_parse_key()
+    - nvme-tcp: check for invalidated or revoked key
+    - net: fec: don't save PTP state if PTP is unsupported
+    - wifi: mac80211: fix RCU list iterations
+    - netdev-genl: Set extack and fix error on napi-get
+    - block: fix integer overflow in BLKSECDISCARD
+    - arm64: trans_pgd: mark PTEs entries as valid to avoid dead kexec()
+    - net: phy: Check for read errors in SIOCGMIIREG
+    - wifi: rtw89: avoid reading out of bounds when loading TX power FW elements
+    - x86/bugs: Add missing NO_SSB flag
+    - x86/bugs: Fix handling when SRSO mitigation is disabled
+    - net: napi: Prevent overflow of napi_defer_hard_irqs
+    - crypto: hisilicon - fix missed error branch
+    - ALSA: usb-audio: Add quirk for RME Digiface USB
+    - ALSA: usb-audio: Add mixer quirk for RME Digiface USB
+    - ALSA: control: Use automatic cleanup of kfree()
+    - ALSA: control: Fix unannotated kfree() cleanup
+    - ALSA: control: Use guard() for locking
+    - ALSA: control: Take power_ref lock primarily
+    - x86/mm/ident_map: Use gbpages only where full GB page should be mapped.
+    - ASoC: Intel: boards: always check the result of
+      acpi_dev_get_first_match_dev()
+    - rcu-tasks: Add data to eliminate RCU-tasks/do_exit() deadlocks
+    - rcu-tasks: Initialize data to eliminate RCU-tasks/do_exit() deadlocks
+    - rcu-tasks: Fix access non-existent percpu rtpcp variable in
+      rcu_tasks_need_gpcb()
+    - pmdomain: core: Don't hold the genpd-lock when calling dev_pm_domain_set()
+    - iommu/vt-d: Unconditionally flush device TLB for pasid table updates
+    - iommu/arm-smmu-v3: Do not use devm for the cd table allocations
+    - drm/amd/display: Pass non-null to dcn20_validate_apply_pipe_split_flags
+    - drm/amd/display: Check null pointers before using them
+    - drm/amd/display: Add null check for head_pipe in
+      dcn201_acquire_free_pipe_for_layer
+    - drm/amd/display: Add null check for head_pipe in
+      dcn32_acquire_idle_pipe_for_head_pipe_in_layer
+    - drm/amd/display: Add NULL check for clk_mgr and clk_mgr->funcs in
+      dcn30_init_hw
+    - drm/amd/display: Add NULL check for clk_mgr in dcn32_init_hw
+    - drm/amd/display: Use gpuvm_min_page_size_kbytes for DML2 surfaces
+    - scsi: smartpqi: Add new controller PCI IDs
+    - drm/amd/display: Add NULL check for function pointer in
+      dcn20_set_output_transfer_func
+    - drm/amd/display: Add NULL check for function pointer in
+      dcn32_set_output_transfer_func
+    - scsi: smartpqi: add new controller PCI IDs
+    - drm/amd/display: Check null-initialized variables
+    - drm/amd/display: Check phantom_stream before it is used
+    - drm/amdgpu/gfx9: properly handle error ints on all pipes
+    - scsi: lpfc: Validate hdwq pointers before dereferencing in reset/errata
+      paths
+    - scsi: lpfc: Fix unsolicited FLOGI kref imbalance when in direct attached
+      topology
+    - drm/amdgpu: check PS, WS index
+    - drm/amdgpu: fix wrong sizeof argument
+    - drm/amdgpu: fix unchecked return value warning for amdgpu_atombios
+    - drm/amdgpu/gfx11: enter safe mode before touching CP_INT_CNTL
+    - drm/xe: Invert page fault queue head / tail
+    - drm/xe: Add helper macro to loop each DSS
+    - drm/xe: fix multicast support for Xe_LP platforms
+    - drm/xe: Use topology to determine page fault queue size
+    - drm/xe: Drop warn on xe_guc_pc_gucrc_disable in guc pc fini
+    - ovl: fsync after metadata copy-up
+    - HID: i2c-hid: ensure various commands do not interfere with each other
+    - platform/mellanox: mlxbf-pmc: Replace uintN_t with kernel-style types
+    - platform/mellanox: mlxbf-pmc: Cleanup signed/unsigned mix-up
+    - platform/mellanox: mlxbf-pmc: fix signedness bugs
+    - platform/mellanox: mlxbf-pmc: fix lockdep warning
+    - bpf: Fix a sdiv overflow issue
+    - ALSA: control: Fix power_ref lock order for compat code, too
+    - perf callchain: Fix stitch LBR memory leaks
+    - drm/xe: fixup xe_alloc_pf_queue
+    - drm/xe: Fix memory leak on xe_alloc_pf_queue failure
+    - nvme-tcp: fix link failure for TCP auth
+    - f2fs: fix zoned block device information initialization
+    - f2fs: add write priority option based on zone UFS
+    - f2fs: make BG GC more aggressive for zoned devices
+    - f2fs: introduce migration_window_granularity
+    - f2fs: increase BG GC migration window granularity when boosted for zoned
+      devices
+    - f2fs: do FG_GC when GC boosting is required for zoned devices
+    - f2fs: forcibly migrate to secure space for zoned device file pinning
+    - mm, slub: avoid zeroing kmalloc redzone
+    - drm/v3d: Prevent out of bounds access in performance query extensions
+    - ext4: fix access to uninitialised lock in fc replay path
+    - ext4: fix off by one issue in alloc_flex_gd()
+    - scripts/gdb: add iteration function for rbtree
+    - scripts/gdb: fix lx-mounts command error
+    - sched/deadline: Comment sched_dl_entity::dl_server variable
+    - sched/core: Add clearing of ->dl_server in put_prev_task_balance()
+    - sched/core: Clear prev->dl_server in CFS pick fast path
+    - drivers/perf: riscv: Align errno for unsupported perf event
+    - ACPI: resource: Remove duplicate Asus E1504GAB IRQ override
+    - ACPI: resource: Loosen the Asus E1404GAB DMI match to also cover the E1404GA
+    - ACPI: resource: Add Asus Vivobook X1704VAP to irq1_level_low_skip_override[]
+    - ACPI: resource: Add Asus ExpertBook B2502CVA to
+      irq1_level_low_skip_override[]
+    - firmware/sysfb: Disable sysfb for firmware buffers with unknown parent
+    - close_range(): fix the logics in descriptor table trimming
+    - drm/sched: Fix dynamic job-flow control race
+    - drm/sched: Always wake up correct scheduler in drm_sched_entity_push_job
+    - drm/sched: Always increment correct scheduler score
+    - drm/xe: Delete unused GuC submission_state.suspend
+    - drm/xe: Use ordered wq for preempt fence waiting
+    - drm/xe: fix UAF around queue destruction
+    - sunrpc: change sp_nrthreads from atomic_t to unsigned int.
+    - NFSD: Async COPY result needs to return a write verifier
+    - NFSD: Limit the number of concurrent async COPY operations
+    - NFSD: Initialize struct nfsd4_copy earlier
+    - NFSD: Never decrement pending_async_copies on error
+    - drm/sched: revert "Always increment correct scheduler score"
+    - ALSA: control: Fix leftover snd_power_unref()
+    - Upstream stable to v6.6.55, v6.10.14
+
+  * By always inlining _compound_head(), clone() sees 3%+ performance increase
+    (LP: #2089327)
+    - mm: always inline _compound_head() with
+      CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y
+
+  * Random flickering with Intel i915 (Comet Lake and Kaby Lake) on Linux 6.8+
+    (LP: #2086587)
+    - SAUCE: iommu/intel: disable DMAR for KBL and CML integrated gfx
+
+  * Add list of source files to linux-buildinfo (LP: #2086606)
+    - [Packaging] Sort build dependencies alphabetically
+    - [Packaging] Add list of used source files to buildinfo package
+
+  * UFS: uspi->s_3apb UBSAN: shift-out-of-bounds (LP: #2087853)
+    - ufs: ufs_sb_private_info: remove unused s_{2, 3}apb fields
+
+  * Mute/mic LEDs don't function on HP EliteBook 645 G10 (LP: #2087983)
+    - ALSA: hda/realtek: fix mute/micmute LEDs for a HP EliteBook 645 G10
+
+  * Noble update: upstream stable patchset 2024-11-22 (LP: #2089340)
+    - EDAC/synopsys: Fix ECC status and IRQ control race condition
+    - EDAC/synopsys: Fix error injection on Zynq UltraScale+
+    - wifi: rtw88: always wait for both firmware loading attempts
+    - crypto: xor - fix template benchmarking
+    - ACPI: PMIC: Remove unneeded check in tps68470_pmic_opregion_probe()
+    - wifi: brcmfmac: export firmware interface functions
+    - wifi: brcmfmac: introducing fwil query functions
+    - wifi: ath9k: Remove error checks when creating debugfs entries
+    - wifi: ath12k: fix BSS chan info request WMI command
+    - wifi: ath12k: match WMI BSS chan info structure with firmware definition
+    - wifi: ath12k: fix invalid AMPDU factor calculation in
+      ath12k_peer_assoc_h_he()
+    - net: stmmac: dwmac-loongson: Init ref and PTP clocks rate
+    - arm64: signal: Fix some under-bracketed UAPI macros
+    - wifi: rtw88: remove CPT execution branch never used
+    - RISC-V: KVM: Fix sbiret init before forwarding to userspace
+    - RISC-V: KVM: Allow legacy PMU access from guest
+    - RISC-V: KVM: Fix to allow hpmcounter31 from the guest
+    - mount: handle OOM on mnt_warn_timestamp_expiry
+    - ARM: 9410/1: vfp: Use asm volatile in fmrx/fmxr macros
+    - powercap: intel_rapl: Fix off by one in get_rpi()
+    - kselftest/arm64: signal: fix/refactor SVE vector length enumeration
+    - drivers/perf: Fix ali_drw_pmu driver interrupt status clearing
+    - wifi: mac80211: don't use rate mask for offchannel TX either
+    - wifi: iwlwifi: remove AX101, AX201 and AX203 support from LNL
+    - wifi: iwlwifi: config: label 'gl' devices as discrete
+    - wifi: iwlwifi: mvm: increase the time between ranging measurements
+    - padata: Honor the caller's alignment in case of chunk_size 0
+    - drivers/perf: hisi_pcie: Record hardware counts correctly
+    - drivers/perf: hisi_pcie: Fix TLP headers bandwidth counting
+    - kselftest/arm64: Actually test SME vector length changes via sigreturn
+    - can: j1939: use correct function name in comment
+    - ACPI: CPPC: Fix MASK_VAL() usage
+    - netfilter: nf_tables: elements with timeout below CONFIG_HZ never expire
+    - netfilter: nf_tables: reject element expiration with no timeout
+    - netfilter: nf_tables: reject expiration higher than timeout
+    - netfilter: nf_tables: remove annotation to access set timeout while holding
+      lock
+    - perf/arm-cmn: Improve debugfs pretty-printing for large configs
+    - perf/arm-cmn: Refactor node ID handling. Again.
+    - perf/arm-cmn: Fix CCLA register offset
+    - perf/arm-cmn: Ensure dtm_idx is big enough
+    - cpufreq: ti-cpufreq: Introduce quirks to handle syscon fails appropriately
+    - wifi: mt76: mt7915: fix oops on non-dbdc mt7986
+    - wifi: mt76: mt7996: use hweight16 to get correct tx antenna
+    - wifi: mt76: mt7996: fix traffic delay when switching back to working channel
+    - wifi: mt76: mt7996: fix wmm set of station interface to 3
+    - wifi: mt76: mt7996: fix HE and EHT beamforming capabilities
+    - wifi: mt76: mt7996: fix EHT beamforming capability check
+    - x86/sgx: Fix deadlock in SGX NUMA node search
+    - pm:cpupower: Add missing powercap_set_enabled() stub function
+    - crypto: hisilicon/hpre - mask cluster timeout error
+    - crypto: hisilicon/qm - reset device before enabling it
+    - crypto: hisilicon/qm - inject error before stopping queue
+    - wifi: mt76: mt7603: fix mixed declarations and code
+    - wifi: cfg80211: fix UBSAN noise in cfg80211_wext_siwscan()
+    - wifi: mt76: mt7915: fix rx filter setting for bfee functionality
+    - wifi: mt76: mt7996: ensure 4-byte alignment for beacon commands
+    - wifi: mt76: mt7996: fix uninitialized TLV data
+    - wifi: cfg80211: fix two more possible UBSAN-detected off-by-one errors
+    - wifi: mac80211: use two-phase skb reclamation in ieee80211_do_stop()
+    - wifi: wilc1000: fix potential RCU dereference issue in
+      wilc_parse_join_bss_param
+    - Bluetooth: hci_core: Fix sending MGMT_EV_CONNECT_FAILED
+    - Bluetooth: hci_sync: Ignore errors from HCI_OP_REMOTE_NAME_REQ_CANCEL
+    - sock_map: Add a cond_resched() in sock_hash_free()
+    - can: bcm: Clear bo->bcm_proc_read after remove_proc_entry().
+    - can: m_can: enable NAPI before enabling interrupts
+    - can: m_can: m_can_close(): stop clocks after device has been shut down
+    - Bluetooth: btusb: Fix not handling ZPL/short-transfer
+    - bareudp: Pull inner IP header in bareudp_udp_encap_recv().
+    - bareudp: Pull inner IP header on xmit.
+    - net: enetc: Use IRQF_NO_AUTOEN flag in request_irq()
+    - net: ipv6: rpl_iptunnel: Fix memory leak in rpl_input
+    - net: tipc: avoid possible garbage value
+    - ipv6: avoid possible NULL deref in rt6_uncached_list_flush_dev()
+    - ublk: move zone report data out of request pdu
+    - nbd: fix race between timeout and normal completion
+    - block, bfq: fix possible UAF for bfqq->bic with merge chain
+    - block, bfq: choose the last bfqq from merge chain in bfq_setup_cooperator()
+    - block, bfq: don't break merge chain in bfq_split_bfqq()
+    - cachefiles: Fix non-taking of sb_writers around set/removexattr
+    - erofs: fix incorrect symlink detection in fast symlink
+    - block, bfq: fix uaf for accessing waker_bfqq after splitting
+    - block, bfq: fix procress reference leakage for bfqq in merge chain
+    - io_uring/io-wq: do not allow pinning outside of cpuset
+    - io_uring/io-wq: inherit cpuset of cgroup in io worker
+    - block: fix potential invalid pointer dereference in blk_add_partition
+    - spi: ppc4xx: handle irq_of_parse_and_map() errors
+    - arm64: dts: exynos: exynos7885-jackpotlte: Correct RAM amount to 4GB
+    - arm64: dts: mediatek: mt8186: Fix supported-hw mask for GPU OPPs
+    - firmware: arm_scmi: Fix double free in OPTEE transport
+    - spi: ppc4xx: Avoid returning 0 when failed to parse and map IRQ
+    - regulator: Return actual error in of_regulator_bulk_get_all()
+    - arm64: dts: renesas: r9a07g043u: Correct GICD and GICR sizes
+    - arm64: dts: renesas: r9a07g054: Correct GICD and GICR sizes
+    - arm64: dts: renesas: r9a07g044: Correct GICD and GICR sizes
+    - ARM: dts: microchip: sam9x60: Fix rtc/rtt clocks
+    - arm64: dts: rockchip: Correct vendor prefix for Hardkernel ODROID-M1
+    - arm64: dts: ti: k3-j721e-sk: Fix reversed C6x carveout locations
+    - arm64: dts: ti: k3-j721e-beagleboneai64: Fix reversed C6x carveout locations
+    - spi: bcmbca-hsspi: Fix missing pm_runtime_disable()
+    - ARM: dts: microchip: sama7g5: Fix RTT clock
+    - ARM: dts: imx7d-zii-rmu2: fix Ethernet PHY pinctrl property
+    - ARM: versatile: fix OF node leak in CPUs prepare
+    - reset: berlin: fix OF node leak in probe() error path
+    - reset: k210: fix OF node leak in probe() error path
+    - clocksource/drivers/qcom: Add missing iounmap() on errors in
+      msm_dt_timer_init()
+    - arm64: dts: mediatek: mt8195: Correct clock order for dp_intf*
+    - x86/mm: Use IPIs to synchronize LAM enablement
+    - ASoC: rt5682s: Return devm_of_clk_add_hw_provider to transfer the error
+    - ASoC: tas2781: remove unused acpi_subysystem_id
+    - ASoC: tas2781: Use of_property_read_reg()
+    - ASoC: tas2781-i2c: Drop weird GPIO code
+    - ASoC: tas2781-i2c: Get the right GPIO line
+    - selftests/ftrace: Add required dependency for kprobe tests
+    - ALSA: hda: cs35l41: fix module autoloading
+    - m68k: Fix kernel_clone_args.flags in m68k_clone()
+    - ASoC: loongson: fix error release
+    - hwmon: (max16065) Fix overflows seen when writing limits
+    - hwmon: (max16065) Remove use of i2c_match_id()
+    - hwmon: (max16065) Fix alarm attributes
+    - mtd: slram: insert break after errors in parsing the map
+    - hwmon: (ntc_thermistor) fix module autoloading
+    - power: supply: axp20x_battery: Remove design from min and max voltage
+    - power: supply: max17042_battery: Fix SOC threshold calc w/ no current sense
+    - fbdev: hpfb: Fix an error handling path in hpfb_dio_probe()
+    - iommu/amd: Do not set the D bit on AMD v2 table entries
+    - mtd: powernv: Add check devm_kasprintf() returned value
+    - rcu/nocb: Fix RT throttling hrtimer armed from offline CPU
+    - mtd: rawnand: mtk: Use for_each_child_of_node_scoped()
+    - mtd: rawnand: mtk: Factorize out the logic cleaning mtk chips
+    - mtd: rawnand: mtk: Fix init error path
+    - iommu/arm-smmu-qcom: hide last LPASS SMMU context bank from linux
+    - iommu/arm-smmu-qcom: Work around SDM845 Adreno SMMU w/ 16K pages
+    - iommu/arm-smmu-qcom: apply num_context_bank fixes for SDM630 / SDM660
+    - pmdomain: core: Harden inter-column space in debug summary
+    - drm/stm: Fix an error handling path in stm_drm_platform_probe()
+    - drm/stm: ltdc: check memory returned by devm_kzalloc()
+    - drm/amd/display: Add null check for set_output_gamma in
+      dcn30_set_output_transfer_func
+    - drm/amdgpu: properly handle vbios fake edid sizing
+    - drm/radeon: properly handle vbios fake edid sizing
+    - scsi: smartpqi: revert propagate-the-multipath-failure-to-SML-quickly
+    - scsi: NCR5380: Check for phase match during PDMA fixup
+    - drm/amd/amdgpu: Properly tune the size of struct
+    - drm/rockchip: vop: Allow 4096px width scaling
+    - drm/rockchip: dw_hdmi: Fix reading EDID when using a forced mode
+    - drm/radeon/evergreen_cs: fix int overflow errors in cs track offsets
+    - drm/bridge: lontium-lt8912b: Validate mode in drm_bridge_funcs::mode_valid()
+    - drm/vc4: hdmi: Handle error case of pm_runtime_resume_and_get
+    - scsi: elx: libefc: Fix potential use after free in efc_nport_vport_del()
+    - jfs: fix out-of-bounds in dbNextAG() and diAlloc()
+    - drm/mediatek: Fix missing configuration flags in mtk_crtc_ddp_config()
+    - drm/mediatek: Use spin_lock_irqsave() for CRTC event lock
+    - powerpc/8xx: Fix initial memory mapping
+    - powerpc/8xx: Fix kernel vs user address comparison
+    - powerpc/vdso: Inconditionally use CFUNC macro
+    - drm/msm: Fix incorrect file name output in adreno_request_fw()
+    - drm/msm/a5xx: disable preemption in submits by default
+    - drm/msm/a5xx: properly clear preemption records on resume
+    - drm/msm/a5xx: fix races in preemption evaluation stage
+    - drm/msm/a5xx: workaround early ring-buffer emptiness check
+    - ipmi: docs: don't advertise deprecated sysfs entries
+    - drm/msm/dsi: correct programming sequence for SM8350 / SM8450
+    - drm/msm: fix %s null argument error
+    - drivers:drm:exynos_drm_gsc:Fix wrong assignment in gsc_bind()
+    - xen: use correct end address of kernel for conflict checking
+    - HID: wacom: Support sequence numbers smaller than 16-bit
+    - HID: wacom: Do not warn about dropped packets for first packet
+    - ata: libata: Clear DID_TIME_OUT for ATA PT commands with sense data
+    - minmax: avoid overly complex min()/max() macro arguments in xen
+    - xen: introduce generic helper checking for memory map conflicts
+    - xen: move max_pfn in xen_memory_setup() out of function scope
+    - xen: add capability to remap non-RAM pages to different PFNs
+    - xen: tolerate ACPI NVS memory overlapping with Xen allocated memory
+    - xen/swiotlb: add alignment check for dma buffers
+    - xen/swiotlb: fix allocated size
+    - tpm: Clean up TPM space after command failure
+    - sched/fair: Make SCHED_IDLE entity be preempted in strict hierarchy
+    - selftests/bpf: Workaround strict bpf_lsm return value check.
+    - selftests/bpf: Fix error linking uprobe_multi on mips
+    - bpf: Use -Wno-error in certain tests when building with GCC
+    - bpf: Disable some `attribute ignored' warnings in GCC
+    - bpf: Temporarily define BPF_NO_PRESEVE_ACCESS_INDEX for GCC
+    - selftests/bpf: Add CFLAGS per source file and runner
+    - selftests/bpf: Fix wrong binary in Makefile log output
+    - tools/runqslower: Fix LDFLAGS and add LDLIBS support
+    - selftests/bpf: Use pid_t consistently in test_progs.c
+    - selftests/bpf: Fix compile error from rlim_t in sk_storage_map.c
+    - selftests/bpf: Fix error compiling bpf_iter_setsockopt.c with musl libc
+    - selftests/bpf: Drop unneeded error.h includes
+    - selftests/bpf: Fix missing ARRAY_SIZE() definition in bench.c
+    - selftests/bpf: Fix missing UINT_MAX definitions in benchmarks
+    - selftests/bpf: Fix missing BUILD_BUG_ON() declaration
+    - selftests/bpf: Replace CHECK with ASSERT_* in ns_current_pid_tgid test
+    - selftests/bpf: Refactor out some functions in ns_current_pid_tgid test
+    - selftests/bpf: Add a cgroup prog bpf_get_ns_current_pid_tgid() test
+    - selftests/bpf: Fix include of <sys/fcntl.h>
+    - selftests/bpf: Fix compiling parse_tcp_hdr_opt.c with musl-libc
+    - selftests/bpf: Fix compiling kfree_skb.c with musl-libc
+    - selftests/bpf: Fix compiling flow_dissector.c with musl-libc
+    - selftests/bpf: Fix compiling tcp_rtt.c with musl-libc
+    - selftests/bpf: Fix compiling core_reloc.c with musl-libc
+    - selftests/bpf: Fix errors compiling lwt_redirect.c with musl libc
+    - selftests/bpf: Fix errors compiling decap_sanity.c with musl libc
+    - selftests/bpf: Fix errors compiling cg_storage_multi.h with musl libc
+    - selftests/bpf: Fix arg parsing in veristat, test_progs
+    - selftests/bpf: Fix error compiling test_lru_map.c
+    - selftests/bpf: Fix C++ compile error from missing _Bool type
+    - selftests/bpf: Fix flaky selftest lwt_redirect/lwt_reroute
+    - selftests/bpf: Fix redefinition errors compiling lwt_reroute.c
+    - selftests/bpf: Fix compile if backtrace support missing in libc
+    - selftests/bpf: Fix error compiling tc_redirect.c with musl libc
+    - samples/bpf: Fix compilation errors with cf-protection option
+    - bpf: correctly handle malformed BPF_CORE_TYPE_ID_LOCAL relos
+    - xz: cleanup CRC32 edits from 2018
+    - kthread: fix task state in kthread worker if being frozen
+    - ext4: clear EXT4_GROUP_INFO_WAS_TRIMMED_BIT even mount with discard
+    - smackfs: Use rcu_assign_pointer() to ensure safe assignment in smk_set_cipso
+    - ext4: avoid buffer_head leak in ext4_mark_inode_used()
+    - ext4: avoid potential buffer_head leak in __ext4_new_inode()
+    - ext4: avoid negative min_clusters in find_group_orlov()
+    - ext4: return error on ext4_find_inline_entry
+    - ext4: avoid OOB when system.data xattr changes underneath the filesystem
+    - ext4: check stripe size compatibility on remount as well
+    - sched/numa: Fix the vma scan starving issue
+    - nilfs2: fix potential null-ptr-deref in nilfs_btree_insert()
+    - nilfs2: determine empty node blocks as corrupted
+    - nilfs2: fix potential oob read in nilfs_btree_check_delete()
+    - bpf: Fix bpf_strtol and bpf_strtoul helpers for 32bit
+    - bpf: Fix helper writes to read-only maps
+    - bpf: Improve check_raw_mode_ok test for MEM_UNINIT-tagged types
+    - bpf: Zero former ARG_PTR_TO_{LONG,INT} args in case of error
+    - perf mem: Free the allocated sort string, fixing a leak
+    - perf inject: Fix leader sampling inserting additional samples
+    - perf report: Fix --total-cycles --stdio output error
+    - perf sched timehist: Fix missing free of session in perf_sched__timehist()
+    - perf stat: Display iostat headers correctly
+    - perf sched timehist: Fixed timestamp error when unable to confirm event
+      sched_in time
+    - perf time-utils: Fix 32-bit nsec parsing
+    - clk: imx: clk-audiomix: Correct parent clock for earc_phy and audpll
+    - clk: imx: imx6ul: fix default parent for enet*_ref_sel
+    - clk: imx: composite-8m: Less function calls in __imx8m_clk_hw_composite()
+      after error detection
+    - clk: imx: composite-8m: Enable gate clk with mcore_booted
+    - clk: imx: composite-93: keep root clock on when mcore enabled
+    - clk: imx: composite-7ulp: Check the PCC present bit
+    - clk: imx: fracn-gppll: fix fractional part of PLL getting lost
+    - clk: imx: imx8mp: fix clock tree update of TF-A managed clocks
+    - clk: imx: imx8qxp: Register dc0_bypass0_clk before disp clk
+    - clk: imx: imx8qxp: Parent should be initialized earlier than the clock
+    - remoteproc: imx_rproc: Correct ddr alias for i.MX8M
+    - remoteproc: imx_rproc: Initialize workqueue earlier
+    - clk: rockchip: Set parent rate for DCLK_VOP clock on RK3228
+    - clk: qcom: dispcc-sm8550: fix several supposed typos
+    - clk: qcom: dispcc-sm8550: use rcg2_ops for mdss_dptx1_aux_clk_src
+    - clk: qcom: dispcc-sm8650: Update the GDSC flags
+    - clk: qcom: dispcc-sm8550: use rcg2_shared_ops for ESC RCGs
+    - leds: bd2606mvv: Fix device child node usage in bd2606mvv_probe()
+    - pinctrl: ti: iodelay: Use scope based of_node_put() cleanups
+    - pinctrl: ti: ti-iodelay: Fix some error handling paths
+    - Input: ilitek_ts_i2c - avoid wrong input subsystem sync
+    - Input: ilitek_ts_i2c - add report id message validation
+    - drivers: media: dvb-frontends/rtl2832: fix an out-of-bounds write error
+    - drivers: media: dvb-frontends/rtl2830: fix an out-of-bounds write error
+    - PCI: Wait for Link before restoring Downstream Buses
+    - firewire: core: correct range of block for case of switch statement
+    - PCI: keystone: Fix if-statement expression in ks_pcie_quirk()
+    - clk: qcom: ipq5332: Register gcc_qdss_tsctr_clk_src
+    - clk: qcom: dispcc-sm8250: use special function for Lucid 5LPE PLL
+    - leds: leds-pca995x: Add support for NXP PCA9956B
+    - leds: pca995x: Use device_for_each_child_node() to access device child nodes
+    - leds: pca995x: Fix device child node usage in pca995x_probe()
+    - x86/PCI: Check pcie_find_root_port() return for NULL
+    - nvdimm: Fix devs leaks in scan_labels()
+    - PCI: xilinx-nwl: Fix register misspelling
+    - PCI: xilinx-nwl: Clean up clock on probe failure/removal
+    - media: platform: rzg2l-cru: rzg2l-csi2: Add missing MODULE_DEVICE_TABLE
+    - RDMA/iwcm: Fix WARNING:at_kernel/workqueue.c:#check_flush_dependency
+    - pinctrl: single: fix missing error code in pcs_probe()
+    - clk: at91: sama7g5: Allocate only the needed amount of memory for PLLs
+    - media: mediatek: vcodec: Fix H264 multi stateless decoder smatch warning
+    - media: mediatek: vcodec: Fix VP8 stateless decoder smatch warning
+    - media: mediatek: vcodec: Fix H264 stateless decoder smatch warning
+    - RDMA/rtrs: Reset hb_missed_cnt after receiving other traffic from peer
+    - RDMA/rtrs-clt: Reset cid to con_num - 1 to stay in bounds
+    - clk: ti: dra7-atl: Fix leak of of_nodes
+    - clk: starfive: Use pm_runtime_resume_and_get to fix pm_runtime_get_sync()
+      usage
+    - clk: rockchip: rk3588: Fix 32k clock name for pmu_24m_32k_100m_src_p
+    - nfsd: remove unneeded EEXIST error check in nfsd_do_file_acquire
+    - nfsd: fix refcount leak when file is unhashed after being found
+    - pinctrl: mvebu: Fix devinit_dove_pinctrl_probe function
+    - IB/core: Fix ib_cache_setup_one error flow cleanup
+    - PCI: kirin: Fix buffer overflow in kirin_pcie_parse_port()
+    - RDMA/erdma: Return QP state in erdma_query_qp
+    - RDMA/mlx5: Limit usage of over-sized mkeys from the MR cache
+    - watchdog: imx_sc_wdt: Don't disable WDT in suspend
+    - RDMA/hns: Don't modify rq next block addr in HIP09 QPC
+    - RDMA/hns: Fix Use-After-Free of rsv_qp on HIP08
+    - RDMA/hns: Fix the overflow risk of hem_list_calc_ba_range()
+    - RDMA/hns: Fix spin_unlock_irqrestore() called with IRQs enabled
+    - RDMA/hns: Fix VF triggering PF reset in abnormal interrupt handler
+    - RDMA/hns: Fix 1bit-ECC recovery address in non-4K OS
+    - RDMA/hns: Optimize hem allocation performance
+    - RDMA/hns: Fix restricted __le16 degrades to integer issue
+    - RDMA/mlx5: Obtain upper net device only when needed
+    - riscv: Fix fp alignment bug in perf_callchain_user()
+    - RDMA/cxgb4: Added NULL check for lookup_atid
+    - RDMA/irdma: fix error message in irdma_modify_qp_roce()
+    - ntb: intel: Fix the NULL vs IS_ERR() bug for debugfs_create_dir()
+    - ntb_perf: Fix printk format
+    - ntb: Force physically contiguous allocation of rx ring buffers
+    - nfsd: call cache_put if xdr_reserve_space returns NULL
+    - nfsd: return -EINVAL when namelen is 0
+    - crypto: caam - Pad SG length when allocating hash edesc
+    - crypto: powerpc/p10-aes-gcm - Disable CRYPTO_AES_GCM_P10
+    - f2fs: atomic: fix to avoid racing w/ GC
+    - f2fs: reduce expensive checkpoint trigger frequency
+    - f2fs: fix to avoid racing in between read and OPU dio write
+    - f2fs: Create COW inode from parent dentry for atomic write
+    - f2fs: fix to wait page writeback before setting gcing flag
+    - f2fs: atomic: fix to truncate pagecache before on-disk metadata truncation
+    - f2fs: support .shutdown in f2fs_sops
+    - f2fs: fix to avoid use-after-free in f2fs_stop_gc_thread()
+    - f2fs: compress: don't redirty sparse cluster during {,de}compress
+    - f2fs: prevent atomic file from being dirtied before commit
+    - f2fs: get rid of online repaire on corrupted directory
+    - f2fs: fix to don't set SB_RDONLY in f2fs_handle_critical_error()
+    - spi: atmel-quadspi: Undo runtime PM changes at driver exit time
+    - spi: spi-fsl-lpspi: Undo runtime PM changes at driver exit time
+    - lib/sbitmap: define swap_lock as raw_spinlock_t
+    - spi: atmel-quadspi: Avoid overwriting delay register settings
+    - nvme-multipath: system fails to create generic nvme device
+    - iio: adc: ad7606: fix oversampling gpio array
+    - iio: adc: ad7606: fix standby gpio state to match the documentation
+    - driver core: Fix error handling in driver API device_rename()
+    - ABI: testing: fix admv8818 attr description
+    - iio: chemical: bme680: Fix read/write ops to device by adding mutexes
+    - iio: magnetometer: ak8975: drop incorrect AK09116 compatible
+    - dt-bindings: iio: asahi-kasei,ak8975: drop incorrect AK09116 compatible
+    - driver core: Fix a potential null-ptr-deref in module_add_driver()
+    - serial: 8250: omap: Cleanup on error in request_irq
+    - coresight: tmc: sg: Do not leak sg_table
+    - interconnect: icc-clk: Add missed num_nodes initialization
+    - cxl/pci: Fix to record only non-zero ranges
+    - vhost_vdpa: assign irq bypass producer token correctly
+    - ep93xx: clock: Fix off by one in ep93xx_div_recalc_rate()
+    - Revert "dm: requeue IO if mapping table not yet available"
+    - net: xilinx: axienet: Schedule NAPI in two steps
+    - net: xilinx: axienet: Fix packet counting
+    - netfilter: nf_reject_ipv6: fix nf_reject_ip6_tcphdr_put()
+    - net: seeq: Fix use after free vulnerability in ether3 Driver Due to Race
+      Condition
+    - net: ipv6: select DST_CACHE from IPV6_RPL_LWTUNNEL
+    - tcp: check skb is non-NULL in tcp_rto_delta_us()
+    - net: qrtr: Update packets cloning when broadcasting
+    - bonding: Fix unnecessary warnings and logs from bond_xdp_get_xmit_slave()
+    - virtio_net: Fix mismatched buf address when unmapping for small packets
+    - netfilter: nf_tables: Keep deleted flowtable hooks until after RCU
+    - netfilter: ctnetlink: compile ctnetlink_label_size with
+      CONFIG_NF_CONNTRACK_EVENTS
+    - netfilter: nf_tables: use rcu chain hook list iterator from netlink dump
+      path
+    - io_uring/sqpoll: do not allow pinning outside of cpuset
+    - io_uring: check for presence of task_work rather than TIF_NOTIFY_SIGNAL
+    - mm: call the security_mmap_file() LSM hook in remap_file_pages()
+    - drm/amd/display: Fix Synaptics Cascaded Panamera DSC Determination
+    - Revert "net: libwx: fix alloc msix vectors failed"
+    - xen: move checks for e820 conflicts further up
+    - xen: allow mapping ACPI data using a different physical address
+    - io_uring/sqpoll: retain test for whether the CPU is valid
+    - io_uring/sqpoll: do not put cpumask on stack
+    - Remove *.orig pattern from .gitignore
+    - PCI: Revert to the original speed after PCIe failed link retraining
+    - PCI: Clear the LBMS bit after a link retrain
+    - PCI: dra7xx: Fix threaded IRQ request for "dra7xx-pcie-main" IRQ
+    - PCI: imx6: Fix missing call to phy_power_off() in error handling
+    - PCI: Correct error reporting with PCIe failed link retraining
+    - PCI: Use an error code with PCIe failed link retraining
+    - PCI: xilinx-nwl: Fix off-by-one in INTx IRQ handler
+    - Revert "soc: qcom: smd-rpm: Match rpmsg channel instead of compatible"
+    - ASoC: rt5682: Return devm_of_clk_add_hw_provider to transfer the error
+    - soc: fsl: cpm1: tsa: Fix tsa_write8()
+    - soc: versatile: integrator: fix OF node leak in probe() error path
+    - Revert "media: tuners: fix error return code of
+      hybrid_tuner_request_state()"
+    - iommufd: Protect against overflow of ALIGN() during iova allocation
+    - Input: adp5588-keys - fix check on return code
+    - Input: i8042 - add TUXEDO Stellaris 16 Gen5 AMD to i8042 quirk table
+    - Input: i8042 - add TUXEDO Stellaris 15 Slim Gen6 AMD to i8042 quirk table
+    - Input: i8042 - add another board name for TUXEDO Stellaris Gen5 AMD line
+    - KVM: arm64: Add memory length checks and remove inline in do_ffa_mem_xfer
+    - KVM: x86: Enforce x2APIC's must-be-zero reserved ICR bits
+    - KVM: x86: Move x2APIC ICR helper above kvm_apic_write_nodecode()
+    - KVM: Use dedicated mutex to protect kvm_usage_count to avoid deadlock
+    - drm/amd/display: Add HDMI DSC native YCbCr422 support
+    - drm/amd/display: Round calculated vtotal
+    - drm/amd/display: Validate backlight caps are sane
+    - KEYS: prevent NULL pointer dereference in find_asymmetric_key()
+    - powerpc/atomic: Use YZ constraints for DS-form instructions
+    - fs: Create a generic is_dot_dotdot() utility
+    - ksmbd: make __dir_empty() compatible with POSIX
+    - ksmbd: allow write with FILE_APPEND_DATA
+    - ksmbd: handle caseless file creation
+    - ata: libata-scsi: Fix ata_msense_control() CDL page reporting
+    - scsi: sd: Fix off-by-one error in sd_read_block_characteristics()
+    - scsi: ufs: qcom: Update MODE_MAX cfg_bw value
+    - scsi: mac_scsi: Revise printk(KERN_DEBUG ...) messages
+    - scsi: mac_scsi: Refactor polling loop
+    - scsi: mac_scsi: Disallow bus errors during PDMA send
+    - can: esd_usb: Remove CAN_CTRLMODE_3_SAMPLES for CAN-USB/3-FD
+    - wifi: rtw88: Fix USB/SDIO devices not transmitting beacons
+    - usbnet: fix cyclical race on disconnect with work queue
+    - USB: appledisplay: close race between probe and completion handler
+    - USB: misc: cypress_cy7c63: check for short transfer
+    - USB: class: CDC-ACM: fix race between get_serial and set_serial
+    - usb: cdnsp: Fix incorrect usb_request status
+    - usb: dwc2: drd: fix clock gating on USB role switch
+    - bus: integrator-lm: fix OF node leak in probe()
+    - bus: mhi: host: pci_generic: Fix the name for the Telit FE990A
+    - firmware_loader: Block path traversal
+    - tty: rp2: Fix reset with non forgiving PCIe host bridges
+    - xhci: Set quirky xHC PCI hosts to D3 _after_ stopping and freeing them.
+    - serial: qcom-geni: fix fifo polling timeout
+    - crypto: ccp - Properly unregister /dev/sev on sev PLATFORM_STATUS failure
+    - drbd: Fix atomicity violation in drbd_uuid_set_bm()
+    - drbd: Add NULL check for net_conf to prevent dereference in state validation
+    - ACPI: sysfs: validate return type of _STR method
+    - ACPI: resource: Add another DMI match for the TongFang GMxXGxx
+    - efistub/tpm: Use ACPI reclaim memory for event log to avoid corruption
+    - perf/x86/intel/pt: Fix sampling synchronization
+    - wifi: mt76: mt7921: Check devm_kasprintf() returned value
+    - wifi: mt76: mt7915: check devm_kasprintf() returned value
+    - wifi: mt76: mt7996: fix NULL pointer dereference in mt7996_mcu_sta_bfer_he
+    - wifi: rtw88: 8821cu: Remove VID/PID 0bda:c82c
+    - wifi: rtw88: 8822c: Fix reported RX band width
+    - wifi: mt76: mt7615: check devm_kasprintf() returned value
+    - debugobjects: Fix conditions in fill_pool()
+    - btrfs: tree-checker: fix the wrong output of data backref objectid
+    - btrfs: always update fstrim_range on failure in FITRIM ioctl
+    - f2fs: fix several potential integer overflows in file offsets
+    - f2fs: prevent possible int overflow in dir_block_index()
+    - f2fs: avoid potential int overflow in sanity_check_area_boundary()
+    - f2fs: Require FMODE_WRITE for atomic write ioctls
+    - f2fs: fix to check atomic_file in f2fs ioctl interfaces
+    - hwrng: mtk - Use devm_pm_runtime_enable
+    - hwrng: bcm2835 - Add missing clk_disable_unprepare in bcm2835_rng_init
+    - hwrng: cctrng - Add missing clk_disable_unprepare in cctrng_resume
+    - arm64: esr: Define ESR_ELx_EC_* constants as UL
+    - arm64: errata: Enable the AC03_CPU_38 workaround for ampere1a
+    - arm64: dts: rockchip: Raise Pinebook Pro's panel backlight PWM frequency
+    - arm64: dts: qcom: sa8775p: Mark APPS and PCIe SMMUs as DMA coherent
+    - arm64: dts: rockchip: Correct the Pinebook Pro battery design capacity
+    - vfs: fix race between evice_inodes() and find_inode()&iput()
+    - fs: Fix file_set_fowner LSM hook inconsistencies
+    - nfs: fix memory leak in error path of nfs4_do_reclaim
+    - EDAC/igen6: Fix conversion of system address to physical memory address
+    - icmp: change the order of rate limits
+    - cpuidle: riscv-sbi: Use scoped device node handling to fix missing
+      of_node_put
+    - padata: use integer wrap around to prevent deadlock on seq_nr overflow
+    - spi: fspi: involve lut_num for struct nxp_fspi_devtype_data
+    - ARM: dts: imx6ul-geam: fix fsl,pins property in tscgrp pinctrl
+    - soc: versatile: realview: fix memory leak during device remove
+    - soc: versatile: realview: fix soc_dev leak during device remove
+    - USB: misc: yurex: fix race between read and write
+    - xhci: Add a quirk for writing ERST in high-low order
+    - usb: xhci: fix loss of data on Cadence xHC
+    - pps: remove usage of the deprecated ida_simple_xx() API
+    - pps: add an error check in parport_attach
+    - serial: don't use uninitialized value in uart_poll_init()
+    - x86/idtentry: Incorporate definitions/declarations of the FRED entries
+    - x86/entry: Remove unwanted instrumentation in common_interrupt()
+    - lib/bitmap: add bitmap_{read,write}()
+    - btrfs: subpage: fix the bitmap dump which can cause bitmap corruption
+    - btrfs: fix race setting file private on concurrent lseek using same fd
+    - dt-bindings: spi: nxp-fspi: support i.MX93 and i.MX95
+    - dt-bindings: spi: nxp-fspi: add imx8ulp support
+    - thunderbolt: Improve DisplayPort tunnel setup process to be more robust
+    - bpf: lsm: Set bpf_lsm_blob_sizes.lbs_task to 0
+    - dm-verity: restart or panic on an I/O error
+    - lockdep: fix deadlock issue between lockdep and rcu
+    - mm: only enforce minimum stack gap size if it's sensible
+    - spi: fspi: add support for imx8ulp
+    - module: Fix KCOV-ignored file name
+    - mm/damon/vaddr: protect vma traversal in __damon_va_thre_regions() with rcu
+      read lock
+    - i2c: aspeed: Update the stop sw state when the bus recovery occurs
+    - i2c: isch: Add missed 'else'
+    - Documentation: KVM: fix warning in "make htmldocs"
+    - bpf: Fix use-after-free in bpf_uprobe_multi_link_attach()
+    - wifi: brcmfmac: add linefeed at end of file
+    - x86/tdx: Fix "in-kernel MMIO" check
+    - spi: atmel-quadspi: Fix wrong register value written to MR
+    - Revert: "dm-verity: restart or panic on an I/O error"
+    - wifi: ath11k: use work queue to process beacon tx event
+    - crypto: qat - disable IOV in adf_dev_stop()
+    - crypto: qat - fix recovery flow for VFs
+    - crypto: qat - ensure correct order in VF restarting handler
+    - crypto: iaa - Fix potential use after free bug
+    - autofs: fix missing fput for FSCONFIG_SET_FD
+    - arm64: smp: smp_send_stop() and crash_smp_send_stop() should try non-NMI
+      first
+    - thermal: core: Fold two functions into their respective callers
+    - thermal: core: Fix rounding of delay jiffies
+    - perf/dwc_pcie: Fix registration issue in multi PCIe controller instances
+    - perf/dwc_pcie: Always register for PCIe bus notifier
+    - ACPI: video: force native for some T2 macbooks
+    - ACPI: video: force native for Apple MacbookPro9,2
+    - wifi: cfg80211: fix bug of mapping AF3x to incorrect User Priority
+    - wifi: mac80211: fix the comeback long retry times
+    - ACPICA: Implement ACPI_WARNING_ONCE and ACPI_ERROR_ONCE
+    - ACPICA: executer/exsystem: Don't nag user about every Stall() violating the
+      spec
+    - netfilter: nft_dynset: annotate data-races around set timeout
+    - wifi: mt76: mt7921: fix wrong UNII-4 freq range check for the channel usage
+    - crypto: ccp - do not request interrupt on cmd completion when irqs disabled
+    - wifi: mt76: connac: fix checksum offload fields of connac3 RXD
+    - net: hsr: Use the seqnr lock for frames received via interlink port.
+    - crypto: n2 - Set err to EINVAL if snprintf fails for hmac
+    - firmware: qcom: scm: Disable SDI and write no dump to dump mode
+    - arm64: dts: renesas: r9a08g045: Correct GICD and GICR sizes
+    - arm64: tegra: Correct location of power-sensors for IGX Orin
+    - arm64: dts: ti: k3-am654-idk: Fix dtbs_check warning in ICSSG dmas
+    - selftests/ftrace: Fix eventfs ownership testcase to find mount point
+    - iommu/amd: Introduce struct protection_domain.pd_mode
+    - iommu/amd: Allocate the page table root using GFP_KERNEL
+    - iommu/amd: Convert comma to semicolon
+    - platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
+    - kselftest: dt: Ignore nodes that have ancestors disabled
+    - bpf, x64: Fix tailcall hierarchy
+    - bpf, lsm: Add check for BPF LSM return value
+    - bpf: Fix compare error in function retval_range_within
+    - bpf: Fail verification for sign-extension of packet data/data_end/data_meta
+    - selftests/bpf: Support checks against a regular expression
+    - selftests/bpf: no need to track next_match_pos in struct test_loader
+    - selftests/bpf: extract test_loader->expect_msgs as a data structure
+    - selftests/bpf: allow checking xlated programs in verifier_* tests
+    - selftests/bpf: __arch_* macro to limit test cases to specific archs
+    - libbpf: Fix bpf_object__open_skeleton()'s mishandling of options
+    - s390/ap: Fix deadlock caused by recursive lock of the AP bus scan mutex
+    - sched/deadline: Fix schedstats vs deadline servers
+    - perf scripts python cs-etm: Restore first sample log in verbose mode
+    - perf lock contention: Change stack_id type to s32
+    - quota: avoid missing put_quota_format when DQUOT_SUSPENDED is passed
+    - media: staging: media: starfive: camss: Drop obsolete return value
+      documentation
+    - leds: gpio: Set num_leds after allocation
+    - iommufd/selftest: Fix buffer read overrrun in the dirty test
+    - iommufd: Check the domain owner of the parent before creating a nesting
+      domain
+    - RDMA/mlx5: Fix counter update on MR cache mkey creation
+    - RDMA/mlx5: Drop redundant work canceling from clean_keys()
+    - RDMA/mlx5: Fix MR cache temp entries cleanup
+    - RDMA/hns: Fix ah error counter in sw stat not increasing
+    - Coresight: Set correct cs_mode for TPDM to fix disable issue
+    - Coresight: Set correct cs_mode for dummy source to fix disable issue
+    - interconnect: qcom: sm8250: Enable sync_state
+    - vdpa/mlx5: Fix invalid mr resource destroy
+    - net: stmmac: set PP_FLAG_DMA_SYNC_DEV only if XDP is enabled
+    - selftests: netfilter: Avoid hanging ipvs.sh
+    - io_uring/rw: treat -EOPNOTSUPP for IOCB_NOWAIT like -EAGAIN
+    - mm: migrate: annotate data-race in migrate_folio_unmap()
+    - selftests/bpf: correctly move 'log' upon successful match
+    - soc: fsl: cpm1: qmc: Update TRNSYNC only in transparent mode
+    - drm/amdgpu/vcn: enable AV1 on both instances
+    - drm/amd/display: Clean up dsc blocks in accelerated mode
+    - drm/amd/display: Skip to enable dsc if it has been off
+    - arm64: dts: mediatek: mt8195-cherry: Mark USB 3.0 on xhci1 as disabled
+    - usb: xHCI: add XHCI_RESET_ON_RESUME quirk for Phytium xHCI host
+    - serial: qcom-geni: fix false console tx restart
+    - crypto: qcom-rng - fix support for ACPI-based systems
+    - ACPI: resource: Do IRQ override on MECHREV GM7XG0M
+    - perf/x86/intel: Allow to setup LBR for counting event for BPF
+    - f2fs: check discard support for conventional zones
+    - netfs: Delete subtree of 'fs/netfs' when netfs module exits
+    - md: Don't flush sync_work in md_write_start()
+    - tools/nolibc: include arch.h from string.h
+    - KVM: x86: Make x2APIC ID 100% readonly
+    - x86/mm/cpa: Warn for set_memory_XXcrypted() VMM fails
+    - x86/mm: Make x86_platform.guest.enc_status_change_*() return an error
+    - x86/tdx: Account shared memory
+    - x86/mm: Add callbacks to prepare encrypted memory for kexec
+    - x86/tdx: Convert shared memory back to private on kexec
+    - soc: qcom: geni-se: add GP_LENGTH/IRQ_EN_SET/IRQ_EN_CLEAR registers
+    - serial: qcom-geni: fix arg types for qcom_geni_serial_poll_bit()
+    - serial: qcom-geni: introduce qcom_geni_serial_poll_bitfield()
+    - idpf: stop using macros for accessing queue descriptors
+    - fs_parse: add uid & gid option option parsing helpers
+    - compiler.h: specify correct attribute for .rodata..c_jump_table
+    - exfat: resolve memory leak from exfat_create_upcase_table()
+    - s390/ftrace: Avoid calling unwinder in ftrace_return_address()
+    - fbdev: xen-fbfront: Assign fb_info->device
+    - [Config] update configs for CONFIG_CRYPTO_AES_GCM_P10
+    - Upstream stable to v6.6.54, v6.10.13
+
+  * Backport some AppArmor complain-mode profile bugfixes from Oracular
+    (LP: #2086210)
+    - SAUCE: apparmor4.0.0 [94/99]: apparmor: allocate xmatch for nullpdf inside
+      aa_alloc_null
+    - SAUCE: apparmor4.0.0 [95/99]: apparmor: properly handle cx/px lookup failure
+      for complain mode profiles
+
+  * Noble update: upstream stable patchset 2024-11-08 (LP: #2087519)
+    - ASoC: SOF: mediatek: Add missing board compatible
+    - ASoC: mediatek: mt8188: Mark AFE_DAC_CON0 register as volatile
+    - ASoC: allow module autoloading for table db1200_pids
+    - ASoC: allow module autoloading for table board_ids
+    - scsi: lpfc: Fix overflow build issue
+    - pinctrl: at91: make it work with current gpiolib
+    - hwmon: (asus-ec-sensors) remove VRM temp X570-E GAMING
+    - microblaze: don't treat zero reserved memory regions as error
+    - platform/x86: x86-android-tablets: Make Lenovo Yoga Tab 3 X90F DMI match
+      less strict
+    - net: ftgmac100: Ensure tx descriptor updates are visible
+    - LoongArch: Define ARCH_IRQ_INIT_FLAGS as IRQ_NOPROBE
+    - wifi: iwlwifi: lower message level for FW buffer destination
+    - wifi: iwlwifi: mvm: fix iwl_mvm_scan_fits() calculation
+    - wifi: iwlwifi: mvm: fix iwl_mvm_max_scan_ie_fw_cmd_room()
+    - wifi: iwlwifi: mvm: pause TCM when the firmware is stopped
+    - wifi: iwlwifi: mvm: don't wait for tx queues if firmware is dead
+    - wifi: mac80211: free skb on error path in ieee80211_beacon_get_ap()
+    - wifi: iwlwifi: clear trans->state earlier upon error
+    - can: mcp251xfd: mcp251xfd_ring_init(): check TX-coalescing configuration
+    - ASoC: Intel: soc-acpi-cht: Make Lenovo Yoga Tab 3 X90F DMI match less strict
+    - ASoC: intel: fix module autoloading
+    - ASoC: google: fix module autoloading
+    - ASoC: tda7419: fix module autoloading
+    - ASoC: fix module autoloading
+    - spi: spidev: Add an entry for elgin,jg10309-01
+    - ASoC: amd: yc: Add a quirk for MSI Bravo 17 (D7VEK)
+    - ALSA: hda: add HDMI codec ID for Intel PTL
+    - drm: komeda: Fix an issue related to normalized zpos
+    - spi: bcm63xx: Enable module autoloading
+    - smb: client: fix hang in wait_for_response() for negproto
+    - x86/hyperv: Set X86_FEATURE_TSC_KNOWN_FREQ when Hyper-V provides frequency
+    - tools: hv: rm .*.cmd when make clean
+    - spi: spidev: Add missing spi_device_id for jg10309-01
+    - ocfs2: add bounds checking to ocfs2_xattr_find_entry()
+    - ocfs2: strict bound check before memcmp in ocfs2_xattr_find_entry()
+    - drm: Use XArray instead of IDR for minors
+    - accel: Use XArray instead of IDR for minors
+    - drm: Expand max DRM device number to full MINORBITS
+    - powercap/intel_rapl: Add support for AMD family 1Ah
+    - netfilter: nft_socket: make cgroupsv2 matching work with namespaces
+    - netfilter: nft_socket: Fix a NULL vs IS_ERR() bug in
+      nft_socket_cgroup_subtree_level()
+    - nvme-pci: qdepth 1 quirk
+    - x86/mm: Switch to new Intel CPU model defines
+    - can: mcp251xfd: properly indent labels
+    - can: mcp251xfd: move mcp251xfd_timestamp_start()/stop() into
+      mcp251xfd_chip_start/stop()
+    - USB: serial: pl2303: add device id for Macrosilicon MS3020
+    - USB: usbtmc: prevent kernel-usb-infoleak
+    - platform/x86: asus-wmi: Fix spurious rfkill on UX8406MA
+    - ASoC: mediatek: mt8188-mt6359: Modify key
+    - clk: qcom: gcc-sm8650: Don't use shared clk_ops for QUPs
+    - ice: check for XDP rings instead of bpf program when unconfiguring
+    - powercap/intel_rapl: Fix the energy-pkg event for AMD CPUs
+    - powercap: intel_rapl: Change an error pointer to NULL
+    - Upstream stable to v6.6.53, v6.10.12
+
+ -- Mehmet Basaran <mehmet.basaran@canonical.com>  Fri, 17 Jan 2025 15:05:44 +0300
+
+linux (6.8.0-52.53) noble; urgency=medium
+
+  * noble/linux: 6.8.0-52.53 -proposed tracker (LP: #2093521)
+
+  * CVE-2024-53164
+    - net: sched: fix ordering of qlen adjustment
+
+  * CVE-2024-53141
+    - netfilter: ipset: add missing range check in bitmap_ip_uadt
+
+  * CVE-2024-53103
+    - hv_sock: Initializing vsk->trans to NULL to prevent a dangling pointer
+
+ -- Manuel Diewald <manuel.diewald@canonical.com>  Fri, 10 Jan 2025 18:18:33 +0100
+
+linux (6.8.0-51.52) noble; urgency=medium
+
+  * noble/linux: 6.8.0-51.52 -proposed tracker (LP: #2090369)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+    - [Packaging] update variants
+
+  * MGLRU: kswapd uses 100% CPU when MGLRU is enabled and under memory pressure
+    (LP: #2087886)
+    - mm/mglru: only clear kswapd_failures if reclaimable
+
+  * CVE-2024-50264
+    - vsock/virtio: Initialization of the dangling pointer occurring in vsk->trans
+
+  * CVE-2024-53057
+    - net/sched: stop qdisc_tree_reduce_backlog on TC_H_ROOT
+
+  * CVE-2024-49967
+    - ext4: no need to continue when the number of entries is 1
+
+ -- Manuel Diewald <manuel.diewald@canonical.com>  Sat, 30 Nov 2024 19:21:46 +0100
+
+linux (6.8.0-50.51) noble; urgency=medium
+
+  * noble/linux: 6.8.0-50.51 -proposed tracker (LP: #2086301)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2024.10.28)
+
+  * Noble update: upstream stable patchset 2024-10-31 (LP: #2086138)
+    - device property: Add cleanup.h based fwnode_handle_put() scope based
+      cleanup.
+    - device property: Introduce device_for_each_child_node_scoped()
+    - iio: adc: ad7124: Switch from of specific to fwnode based property handling
+    - ksmbd: override fsids for share path check
+    - ksmbd: override fsids for smb2_query_info()
+    - usbnet: ipheth: remove extraneous rx URB length check
+    - usbnet: ipheth: drop RX URBs with no payload
+    - usbnet: ipheth: do not stop RX on failing RX callback
+    - usbnet: ipheth: fix carrier detection in modes 1 and 4
+    - net: ethernet: use ip_hdrlen() instead of bit shift
+    - drm: panel-orientation-quirks: Add quirk for Ayn Loki Zero
+    - drm: panel-orientation-quirks: Add quirk for Ayn Loki Max
+    - net: phy: vitesse: repair vsc73xx autonegotiation
+    - powerpc/mm: Fix boot warning with hugepages and CONFIG_DEBUG_VIRTUAL
+    - wifi: mt76: mt7921: fix NULL pointer access in mt7921_ipv6_addr_change
+    - net: hns3: use correct release function during uninitialization
+    - btrfs: update target inode's ctime on unlink
+    - Input: ads7846 - ratelimit the spi_sync error message
+    - Input: synaptics - enable SMBus for HP Elitebook 840 G2
+    - HID: multitouch: Add support for GT7868Q
+    - scripts: kconfig: merge_config: config files: add a trailing newline
+    - platform/surface: aggregator_registry: Add Support for Surface Pro 10
+    - platform/surface: aggregator_registry: Add support for Surface Laptop Go 3
+    - drm/msm/adreno: Fix error return if missing firmware-name
+    - Input: i8042 - add Fujitsu Lifebook E756 to i8042 quirk table
+    - smb/server: fix return value of smb2_open()
+    - NFSv4: Fix clearing of layout segments in layoutreturn
+    - NFS: Avoid unnecessary rescanning of the per-server delegation list
+    - platform/x86: panasonic-laptop: Fix SINF array out of bounds accesses
+    - platform/x86: panasonic-laptop: Allocate 1 entry extra in the sinf array
+    - mptcp: pm: Fix uaf in __timer_delete_sync
+    - arm64: dts: rockchip: fix eMMC/SPI corruption when audio has been used on
+      RK3399 Puma
+    - arm64: dts: rockchip: override BIOS_DISABLE signal via GPIO hog on RK3399
+      Puma
+    - minmax: reduce min/max macro expansion in atomisp driver
+    - net: tighten bad gso csum offset check in virtio_net_hdr
+    - dm-integrity: fix a race condition when accessing recalc_sector
+    - x86/hyperv: fix kexec crash due to VP assist page corruption
+    - mm: avoid leaving partial pfn mappings around in error case
+    - arm64: dts: rockchip: fix PMIC interrupt pin in pinctrl for ROCK Pi E
+    - drm/amd/display: Disable error correction if it's not supported
+    - drm/amd/display: Fix FEC_READY write on DP LT
+    - eeprom: digsy_mtc: Fix 93xx46 driver probe failure
+    - cxl/core: Fix incorrect vendor debug UUID define
+    - selftests/bpf: Support SOCK_STREAM in unix_inet_redir_to_connected()
+    - hwmon: (pmbus) Conditionally clear individual status bits for pmbus rev >=
+      1.2
+    - ice: Fix lldp packets dropping after changing the number of channels
+    - ice: fix accounting for filters shared by multiple VSIs
+    - ice: fix VSI lists confusion when adding VLANs
+    - igb: Always call igb_xdp_ring_update_tail() under Tx lock
+    - net/mlx5: Update the list of the PCI supported devices
+    - net/mlx5e: Add missing link modes to ptys2ethtool_map
+    - net/mlx5e: Add missing link mode to ptys2ext_ethtool_map
+    - net/mlx5: Explicitly set scheduling element and TSAR type
+    - net/mlx5: Add missing masks and QoS bit masks for scheduling elements
+    - net/mlx5: Correct TASR typo into TSAR
+    - net/mlx5: Verify support for scheduling element and TSAR type
+    - net/mlx5: Fix bridge mode operations when there are no VFs
+    - fou: fix initialization of grc
+    - octeontx2-af: Modify SMQ flush sequence to drop packets
+    - net: ftgmac100: Enable TX interrupt to avoid TX timeout
+    - selftests: net: csum: Fix checksums for packets with non-zero padding
+    - netfilter: nft_socket: fix sk refcount leaks
+    - net: dsa: felix: ignore pending status of TAS module when it's disabled
+    - net: dpaa: Pad packets to ETH_ZLEN
+    - tracing/osnoise: Fix build when timerlat is not enabled
+    - spi: nxp-fspi: fix the KASAN report out-of-bounds bug
+    - drm/syncobj: Fix syncobj leak in drm_syncobj_eventfd_ioctl
+    - dma-buf: heaps: Fix off-by-one in CMA heap fault handler
+    - drm/nouveau/fb: restore init() for ramgp102
+    - drm/amdgpu/atomfirmware: Silence UBSAN warning
+    - drm/amd/amdgpu: apply command submission parser for JPEG v1
+    - spi: geni-qcom: Undo runtime PM changes at driver exit time
+    - spi: geni-qcom: Fix incorrect free_irq() sequence
+    - drm/i915/guc: prevent a possible int overflow in wq offsets
+    - ASoC: codecs: avoid possible garbage value in peb2466_reg_read()
+    - cifs: Fix signature miscalculation
+    - pinctrl: meteorlake: Add Arrow Lake-H/U ACPI ID
+    - ASoC: meson: axg-card: fix 'use-after-free'
+    - drm/mediatek: Set sensible cursor width/height values to fix crash
+    - Input: edt-ft5x06 - add support for FocalTech FT5452 and FT8719
+    - Input: edt-ft5x06 - add support for FocalTech FT8201
+    - cgroup/cpuset: Eliminate unncessary sched domains rebuilds in hotplug
+    - spi: zynqmp-gqspi: Scale timeout by data size
+    - drm/xe: use devm instead of drmm for managed bo
+    - net: libwx: fix number of Rx and Tx descriptors
+    - clocksource: hyper-v: Use lapic timer in a TDX VM without paravisor
+    - bcachefs: Fix bch2_extents_match() false positive
+    - bcachefs: Don't delete open files in online fsck
+    - firmware: qcom: uefisecapp: Fix deadlock in qcuefi_acquire()
+    - riscv: dts: starfive: jh7110-common: Fix lower rate of CPUfreq by setting
+      PLL0 rate to 1.5GHz
+    - cxl: Restore XOR'd position bits during address translation
+    - netlink: specs: mptcp: fix port endianness
+    - drm/amd/display: Avoid race between dcn10_set_drr() and dc_state_destruct()
+    - drm/amd/display: Avoid race between dcn35_set_drr() and dc_state_destruct()
+    - drm/amd/amdgpu: apply command submission parser for JPEG v2+
+    - drm/xe/client: fix deadlock in show_meminfo()
+    - drm/xe/client: remove bogus rcu list usage
+    - drm/xe/client: add missing bo locking in show_meminfo()
+    - tracing/kprobes: Fix build error when find_module() is not available
+    - drm/xe/display: fix compat IS_DISPLAY_STEP() range end
+    - Upstream stable to v6.6.52, v6.10.11
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849)
+    - KVM: SVM: fix emulation of msr reads/writes of MSR_FS_BASE and MSR_GS_BASE
+    - KVM: SVM: Don't advertise Bus Lock Detect to guest if SVM support is missing
+    - ALSA: hda/conexant: Add pincfg quirk to enable top speakers on Sirius
+      devices
+    - ALSA: hda/realtek: add patch for internal mic in Lenovo V145
+    - ALSA: hda/realtek: Support mute LED on HP Laptop 14-dq2xxx
+    - ksmbd: Unlock on in ksmbd_tcp_set_interfaces()
+    - ata: libata: Fix memory leak for error path in ata_host_alloc()
+    - irqchip/gic-v2m: Fix refcount leak in gicv2m_of_init()
+    - x86/kaslr: Expose and use the end of the physical memory address space
+    - nvme-pci: Add sleep quirk for Samsung 990 Evo
+    - rust: types: Make Opaque::get const
+    - rust: macros: provide correct provenance when constructing THIS_MODULE
+    - Revert "Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE"
+    - Bluetooth: MGMT: Ignore keys being loaded with invalid type
+    - mmc: core: apply SD quirks earlier during probe
+    - mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K
+    - mmc: sdhci-of-aspeed: fix module autoloading
+    - mmc: cqhci: Fix checking of CQHCI_HALT state
+    - fuse: update stats for pages in dropped aux writeback list
+    - fuse: use unsigned type for getxattr/listxattr size truncation
+    - fuse: fix memory leak in fuse_create_open
+    - clk: starfive: jh7110-sys: Add notifier for PLL0 clock
+    - clk: qcom: clk-alpha-pll: Fix the pll post div mask
+    - clk: qcom: clk-alpha-pll: Fix the trion pll postdiv set rate API
+    - kexec_file: fix elfcorehdr digest exclusion when CONFIG_CRASH_HOTPLUG=y
+    - tracing: Avoid possible softlockup in tracing_iter_reset()
+    - tracing/timerlat: Add interface_lock around clearing of kthread in
+      stop_kthread()
+    - net: mctp-serial: Fix missing escapes on transmit
+    - x86/fpu: Avoid writing LBR bit to IA32_XSS unless supported
+    - x86/apic: Make x2apic_disable() work correctly
+    - drm/i915: Do not attempt to load the GSC multiple times
+    - ALSA: control: Apply sanity check of input values for user elements
+    - ALSA: hda: Add input value sanity checks to HDMI channel map controls
+    - wifi: ath12k: fix uninitialize symbol error on ath12k_peer_assoc_h_he()
+    - smack: unix sockets: fix accept()ed socket label
+    - bpf, verifier: Correct tail_call_reachable for bpf prog
+    - accel/habanalabs/gaudi2: unsecure edma max outstanding register
+    - irqchip/armada-370-xp: Do not allow mapping IRQ 0 and 1
+    - af_unix: Remove put_pid()/put_cred() in copy_peercred().
+    - x86/kmsan: Fix hook for unaligned accesses
+    - iommu: sun50i: clear bypass register
+    - netfilter: nf_conncount: fix wrong variable type
+    - fs/ntfs3: One more reason to mark inode bad
+    - riscv: kprobes: Use patch_text_nosync() for insn slots
+    - media: vivid: fix wrong sizeimage value for mplane
+    - leds: spi-byte: Call of_node_put() on error path
+    - wifi: brcmsmac: advertise MFP_CAPABLE to enable WPA3
+    - usb: uas: set host status byte on data completion error
+    - drm/amd/display: Check HDCP returned status
+    - drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts
+    - media: vivid: don't set HDMI TX controls if there are no HDMI outputs
+    - vfio/spapr: Always clear TCEs before unsetting the window
+    - ice: Check all ice_vsi_rebuild() errors in function
+    - Input: ili210x - use kvmalloc() to allocate buffer for firmware update
+    - media: qcom: camss: Add check for v4l2_fwnode_endpoint_parse
+    - pcmcia: Use resource_size function on resource object
+    - drm/amdgpu: check for LINEAR_ALIGNED correctly in check_tiling_flags_gfx6
+    - can: m_can: Release irq on error in m_can_open
+    - can: mcp251xfd: fix ring configuration when switching from CAN-CC to CAN-FD
+      mode
+    - rust: kbuild: fix export of bss symbols
+    - cifs: Fix FALLOC_FL_ZERO_RANGE to preflush buffered part of target region
+    - igb: Fix not clearing TimeSync interrupts for 82580
+    - platform/x86: dell-smbios: Fix error path in dell_smbios_init()
+    - regulator: core: Stub devm_regulator_bulk_get_const() if !CONFIG_REGULATOR
+    - can: kvaser_pciefd: Skip redundant NULL pointer check in ISR
+    - can: kvaser_pciefd: Remove unnecessary comment
+    - can: kvaser_pciefd: Rename board_irq to pci_irq
+    - can: kvaser_pciefd: Move reset of DMA RX buffers to the end of the ISR
+    - can: kvaser_pciefd: Use a single write when releasing RX buffers
+    - Bluetooth: qca: If memdump doesn't work, re-enable IBS
+    - Bluetooth: hci_sync: Introduce hci_cmd_sync_run/hci_cmd_sync_run_once
+    - Bluetooth: MGMT: Fix not generating command complete for MGMT_OP_DISCONNECT
+    - igc: Unlock on error in igc_io_resume()
+    - ice: do not bring the VSI up, if it was down before the XDP setup
+    - usbnet: modern method to get random MAC
+    - bpf, net: Fix a potential race in do_sock_getsockopt()
+    - bareudp: Fix device stats updates.
+    - r8152: fix the firmware doesn't work
+    - net: bridge: br_fdb_external_learn_add(): always set EXT_LEARN
+    - net: dsa: vsc73xx: fix possible subblocks range of CAPT block
+    - selftests: net: enable bind tests
+    - firmware: cs_dsp: Don't allow writes to read-only controls
+    - phy: zynqmp: Take the phy mutex in xlate
+    - ASoC: topology: Properly initialize soc_enum values
+    - dm init: Handle minors larger than 255
+    - iommu/vt-d: Handle volatile descriptor status read
+    - cgroup: Protect css->cgroup write under css_set_lock
+    - devres: Initialize an uninitialized struct member
+    - virtio_ring: fix KMSAN error for premapped mode
+    - crypto: qat - fix unintentional re-enabling of error interrupts
+    - ASoc: TAS2781: replace beXX_to_cpup with get_unaligned_beXX for potentially
+      broken alignment
+    - libbpf: Add NULL checks to bpf_object__{prev_map,next_map}
+    - drm/amdgpu: Set no_hw_access when VF request full GPU fails
+    - ext4: fix possible tid_t sequence overflows
+    - jbd2: avoid mount failed when commit block is partial submitted
+    - dma-mapping: benchmark: Don't starve others when doing the test
+    - drm/amdgpu: reject gang submit on reserved VMIDs
+    - smp: Add missing destroy_work_on_stack() call in smp_call_on_cpu()
+    - fs/ntfs3: Check more cases when directory is corrupted
+    - btrfs: replace BUG_ON with ASSERT in walk_down_proc()
+    - cxl/region: Verify target positions using the ordered target list
+    - riscv: set trap vector earlier
+    - tcp: Don't drop SYN+ACK for simultaneous connect().
+    - net: dpaa: avoid on-stack arrays of NR_CPUS elements
+    - LoongArch: Use correct API to map cmdline in relocate_kernel()
+    - regmap: maple: work around gcc-14.1 false-positive warning
+    - vfs: Fix potential circular locking through setxattr() and removexattr()
+    - i3c: master: svc: resend target address when get NACK
+    - kselftests: dmabuf-heaps: Ensure the driver name is null-terminated
+    - btrfs: initialize location to fix -Wmaybe-uninitialized in
+      btrfs_lookup_dentry()
+    - s390/vmlinux.lds.S: Move ro_after_init section behind rodata section
+    - usbnet: ipheth: race between ipheth_close and error handling
+    - spi: spi-fsl-lpspi: limit PRESCALE bit in TCR register
+    - ata: pata_macio: Use WARN instead of BUG
+    - NFSv4: Add missing rescheduling points in
+      nfs_client_return_marked_delegations
+    - ACPI: CPPC: Add helper to get the highest performance value
+    - cpufreq: amd-pstate: Enable amd-pstate preferred core support
+    - cpufreq: amd-pstate: fix the highest frequency issue which limits
+      performance
+    - tcp: process the 3rd ACK with sk_socket for TFO/MPTCP
+    - iio: buffer-dmaengine: fix releasing dma channel on error
+    - iio: fix scale application in iio_convert_raw_to_processed_unlocked
+    - iio: adc: ad7124: fix config comparison
+    - iio: adc: ad7606: remove frstdata check for serial mode
+    - iio: adc: ad7124: fix chip ID mismatch
+    - usb: dwc3: core: update LC timer as per USB Spec V3.2
+    - usb: cdns2: Fix controller reset issue
+    - usb: dwc3: Avoid waking up gadget during startxfer
+    - nvmem: Fix return type of devm_nvmem_device_get() in kerneldoc
+    - Drivers: hv: vmbus: Fix rescind handling in uio_hv_generic
+    - clocksource/drivers/imx-tpm: Fix return -ETIME when delta exceeds INT_MAX
+    - clocksource/drivers/imx-tpm: Fix next event not taking effect sometime
+    - clocksource/drivers/timer-of: Remove percpu irq related code
+    - uprobes: Use kzalloc to allocate xol area
+    - Revert "mm: skip CMA pages when they are not available"
+    - workqueue: wq_watchdog_touch is always called with valid CPU
+    - workqueue: Improve scalability of workqueue watchdog touch
+    - ACPI: processor: Return an error if acpi_processor_get_info() fails in
+      processor_add()
+    - ACPI: processor: Fix memory leaks in error paths of processor_add()
+    - arm64: acpi: Move get_cpu_for_acpi_id() to a header
+    - can: mcp251xfd: mcp251xfd_handle_rxif_ring_uinc(): factor out in separate
+      function
+    - can: mcp251xfd: rx: prepare to workaround broken RX FIFO head index erratum
+    - can: mcp251xfd: clarify the meaning of timestamp
+    - can: mcp251xfd: rx: add workaround for erratum DS80000789E 6 of mcp2518fd
+    - drm/amd: Add gfx12 swizzle mode defs
+    - drm/amdgpu: handle gfx12 in amdgpu_display_verify_sizes
+    - ata: libata-scsi: Remove redundant sense_buffer memsets
+    - ata: libata-scsi: Check ATA_QCFLAG_RTF_FILLED before using result_tf
+    - crypto: starfive - Align rsa input data to 32-bit
+    - crypto: starfive - Fix nent assignment in rsa dec
+    - clk: qcom: ipq9574: Update the alpha PLL type for GPLLs
+    - powerpc/64e: remove unused IBM HTW code
+    - powerpc/64e: split out nohash Book3E 64-bit code
+    - powerpc/64e: Define mmu_pte_psize static
+    - powerpc/vdso: Don't discard rela sections
+    - ASoC: tegra: Fix CBB error during probe()
+    - nvme-pci: allocate tagset on reset if necessary
+    - ASoc: SOF: topology: Clear SOF link platform name upon unload
+    - ASoC: sunxi: sun4i-i2s: fix LRCLK polarity in i2s mode
+    - clk: qcom: gcc-sm8550: Don't use parking clk_ops for QUPs
+    - clk: qcom: gcc-sm8550: Don't park the USB RCG at registration time
+    - drm/i915/fence: Mark debug_fence_init_onstack() with __maybe_unused
+    - drm/i915/fence: Mark debug_fence_free() with __maybe_unused
+    - gpio: rockchip: fix OF node leak in probe()
+    - gpio: modepin: Enable module autoloading
+    - riscv: Fix toolchain vector detection
+    - riscv: Do not restrict memory size because of linear mapping on nommu
+    - membarrier: riscv: Add full memory barrier in switch_mm()
+    - [Config] updateconfigs for ARCH_HAS_MEMBARRIER_CALLBACKS
+    - x86/mm: Fix PTI for i386 some more
+    - btrfs: fix race between direct IO write and fsync when using same fd
+    - spi: spi-fsl-lpspi: Fix off-by-one in prescale max
+    - ALSA: hda/realtek: Enable Mute Led for HP Victus 15-fb1xxx
+    - ALSA: hda/realtek - Fix inactive headset mic jack for ASUS Vivobook 15
+      X1504VAP
+    - fuse: clear PG_uptodate when using a stolen page
+    - riscv: misaligned: remove CONFIG_RISCV_M_MODE specific code
+    - parisc: Delay write-protection until mark_rodata_ro() call
+    - pinctrl: qcom: x1e80100: Bypass PDC wakeup parent for now
+    - maple_tree: remove rcu_read_lock() from mt_validate()
+    - Revert "wifi: ath11k: restore country code during resume"
+    - btrfs: qgroup: don't use extent changeset when not needed
+    - btrfs: zoned: handle broken write pointer on zones
+    - drm/xe/gsc: Do not attempt to load the GSC multiple times
+    - drm/amdgpu: always allocate cleared VRAM for GEM allocations
+    - drm/amd/display: Lock DC and exit IPS when changing backlight
+    - ALSA: hda/realtek: extend quirks for Clevo V5[46]0
+    - cgroup/cpuset: Delay setting of CS_CPU_EXCLUSIVE until valid partition
+    - virt: sev-guest: Mark driver struct with __refdata to prevent section
+      mismatch
+    - media: b2c2: flexcop-usb: fix flexcop_usb_memory_req
+    - gve: Add adminq mutex lock
+    - wifi: rtw89: wow: prevent to send unexpected H2C during download Firmware
+    - drm/amdgpu: add missing error handling in function
+      amdgpu_gmc_flush_gpu_tlb_pasid
+    - crypto: qat - initialize user_input.lock for rate_limiting
+    - locking: Add rwsem_assert_held() and rwsem_assert_held_write()
+    - fs: don't copy to userspace under namespace semaphore
+    - fs: relax permissions for statmount()
+    - seccomp: release task filters when the task exits
+    - drm/amdgpu/display: handle gfx12 in amdgpu_dm_plane_format_mod_supported
+    - can: m_can: Remove m_can_rx_peripheral indirection
+    - can: m_can: Do not cancel timer from within timer
+    - mm: Provide a means of invalidation without using launder_folio
+    - cifs: Fix copy offload to flush destination region
+    - hwmon: ltc2991: fix register bits defines
+    - scripts: fix gfp-translate after ___GFP_*_BITS conversion to an enum
+    - ptp: ocp: convert serial ports to array
+    - ptp: ocp: adjust sysfs entries to expose tty information
+    - ice: check ICE_VSI_DOWN under rtnl_lock when preparing for reset
+    - ice: remove ICE_CFG_BUSY locking from AF_XDP code
+    - net: xilinx: axienet: Fix race in axienet_stop
+    - iommu/vt-d: Remove control over Execute-Requested requests
+    - block: don't call bio_uninit from bio_endio
+    - tracing/kprobes: Add symbol counting check when module loads
+    - perf/x86/intel: Hide Topdown metrics events if the feature is not enumerated
+    - PCI: qcom: Override NO_SNOOP attribute for SA8775P RC
+    - staging: vchiq_core: Bubble up wait_event_interruptible() return value
+    - watchdog: imx7ulp_wdt: keep already running watchdog enabled
+    - btrfs: slightly loosen the requirement for qgroup removal
+    - drm/amdgpu: add PSP RAS address query command
+    - drm/amdgpu: add mutex to protect ras shared memory
+    - s390/boot: Do not assume the decompressor range is reserved
+    - drm/amdgpu: Fix two reset triggered in a row
+    - drm/amdgpu: Add reset_context flag for host FLR
+    - drm/amdgpu: Fix amdgpu_device_reset_sriov retry logic
+    - fs: only copy to userspace on success in listmount()
+    - iio: adc: ad7124: fix DT configuration parsing
+    - nvmem: u-boot-env: error if NVMEM device is too small
+    - mm: zswap: rename is_zswap_enabled() to zswap_is_enabled()
+    - mm/memcontrol: respect zswap.writeback setting from parent cg too
+    - path: add cleanup helper
+    - fs: simplify error handling
+    - fs: relax permissions for listmount()
+    - hid: bpf: add BPF_JIT dependency
+    - net/mlx5e: SHAMPO, Use KSMs instead of KLMs
+    - net/mlx5e: SHAMPO, Fix page leak
+    - drm/xe/xe2: Add workaround 14021402888
+    - drm/xe/xe2lpg: Extend workaround 14021402888
+    - clk: qcom: gcc-x1e80100: Fix USB 0 and 1 PHY GDSC pwrsts flags
+    - clk: qcom: gcc-x1e80100: Don't use parking clk_ops for QUPs
+    - nouveau: fix the fwsec sb verification register.
+    - riscv: Add tracepoints for SBI calls and returns
+    - riscv: Improve sbi_ecall() code generation by reordering arguments
+    - riscv: Fix RISCV_ALTERNATIVE_EARLY
+    - cifs: Fix zero_point init on inode initialisation
+    - nvme: rename nvme_sc_to_pr_err to nvme_status_to_pr_err
+    - nvme: fix status magic numbers
+    - nvme: rename CDR/MORE/DNR to NVME_STATUS_*
+    - nvmet: Identify-Active Namespace ID List command should reject invalid nsid
+    - drm/i915/display: Add mechanism to use sink model when applying quirk
+    - drm/i915/display: Increase Fast Wake Sync length as a quirk
+    - LoongArch: Use accessors to page table entries instead of direct dereference
+    - Upstream stable to v6.6.51, v6.10.10
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46823
+    - kunit/overflow: Fix UB in overflow_allocation_test
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46834
+    - ethtool: fail closed if we can't get max channel used in indirection tables
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46751
+    - btrfs: don't BUG_ON() when 0 reference count at btrfs_lookup_extent_info()
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46753
+    - btrfs: handle errors from btrfs_dec_ref() properly
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46841
+    - btrfs: don't BUG_ON on ENOMEM from btrfs_lookup_extent_info() in
+      walk_down_proc()
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46754
+    - bpf: Remove tst_run from lwt_seg6local_prog_ops.
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46824
+    - iommufd: Require drivers to supply the cache_invalidate_user ops
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46842
+    - scsi: lpfc: Handle mailbox timeouts in lpfc_get_sfp_info
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46766
+    - ice: move netif_queue_set_napi to rtnl-protected sections
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46772
+    - drm/amd/display: Check denominator crb_pipes before used
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46774
+    - powerpc/rtas: Prevent Spectre v1 gadget construction in sys_rtas()
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46775
+    - drm/amd/display: Validate function returns
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46778
+    - drm/amd/display: Check UnboundedRequestEnabled's value
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46779
+    - drm/imagination: Free pvr_vm_gpuva after unlink
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46792
+    - riscv: misaligned: Restrict user access to kernel memory
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46793
+    - ASoC: Intel: Boards: Fix NULL pointer deref in BYT/CHT boards harder
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46735
+    - ublk_drv: fix NULL pointer dereference in ublk_ctrl_start_recovery()
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46737
+    - nvmet-tcp: fix kernel crash if commands allocation fails
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46822
+    - arm64: acpi: Harden get_cpu_for_acpi_id() against missing CPU entry
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46713
+    - perf/aux: Fix AUX buffer serialization
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46739
+    - uio_hv_generic: Fix kernel NULL pointer dereference in hv_uio_rescind
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46740
+    - binder: fix UAF caused by offsets overwrite
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46741
+    - misc: fastrpc: Fix double free of 'buf' in error path
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47663
+    - staging: iio: frequency: ad9834: Validate frequency parameter value
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46832
+    - MIPS: cevt-r4k: Don't call get_c0_compare_int if timer irq is installed
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47668
+    - lib/generic-radix-tree.c: Fix rare race in __genradix_ptr_alloc()
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46744
+    - Squashfs: sanity check symbolic link size
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46745
+    - Input: uinput - reject requests with unreasonable number of slots
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46746
+    - HID: amd_sfh: free driver_data after destroying hid device
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47664
+    - spi: hisi-kunpeng: Add verification for the max_frequency provided by the
+      firmware
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47665
+    - i3c: mipi-i3c-hci: Error out instead on BUG_ON() in IBI DMA setup
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46749
+    - Bluetooth: btnxpuart: Fix Null pointer dereference in btnxpuart_flush()
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46750
+    - PCI: Add missing bridge lock to pci_bus_lock()
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46752
+    - btrfs: replace BUG_ON() with error handling at update_ref_for_cow()
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46840
+    - btrfs: clean up our handling of refs == 0 in snapshot delete
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46755
+    - wifi: mwifiex: Do not return unused priv in mwifiex_get_priv_by_id()
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47666
+    - scsi: pm80xx: Set phy->enable_completion only when we wait for it
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46843
+    - scsi: ufs: core: Remove SCSI host only if added
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46760
+    - wifi: rtw88: usb: schedule rx work after everything is set up
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46761
+    - pci/hotplug/pnv_php: Fix hotplug driver crash on Powernv
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46844
+    - um: line: always fill *error_out in setup_one_line()
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46762
+    - xen: privcmd: Fix possible access to a freed kirqfd instance
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46763
+    - fou: Fix null-ptr-deref in GRO.
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46765
+    - ice: protect XDP configuration with a mutex
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46767
+    - net: phy: Fix missing of_node_put() for leds
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46768
+    - hwmon: (hp-wmi-sensors) Check if WMI event data exists
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46770
+    - ice: Add netif_device_attach/detach into PF reset flow
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46771
+    - can: bcm: Remove proc entry when dev is unregistered.
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46773
+    - drm/amd/display: Check denominator pbn_div before used
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47667
+    - PCI: keystone: Add workaround for Errata #i2037 (AM65x SR 1.0)
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46835
+    - drm/amdgpu: Fix smatch static checker warning
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46776
+    - drm/amd/display: Run DC_LOG_DC after checking link->link_enc
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46836
+    - usb: gadget: aspeed_udc: validate endpoint index for ast udc
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46777
+    - udf: Avoid excessive partition lengths
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46825
+    - wifi: iwlwifi: mvm: use IWL_FW_CHECK for link ID check
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46826
+    - ELF: fix kernel.randomize_va_space double read
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46827
+    - wifi: ath12k: fix firmware crash due to invalid peer nss
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47669
+    - nilfs2: fix state management in error path of log writing function
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46780
+    - nilfs2: protect references to superblock parameters exposed in sysfs
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46781
+    - nilfs2: fix missing cleanup on rollforward recovery error
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46828
+    - sched: sch_cake: fix bulk flow accounting logic for host fairness
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46782
+    - ila: call nf_unregister_net_hooks() sooner
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46783
+    - tcp_bpf: fix return value of tcp_bpf_sendmsg()
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46784
+    - net: mana: Fix error handling in mana_create_txq/rxq's NAPI cleanup
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46785
+    - eventfs: Use list_del_rcu() for SRCU protected list variable
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46786
+    - fscache: delete fscache_cookie_lru_timer when fscache exits to avoid UAF
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46787
+    - userfaultfd: fix checks for huge PMDs
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46838
+    - userfaultfd: don't BUG_ON() if khugepaged yanks our page table
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46845
+    - tracing/timerlat: Only clear timer if a kthread exists
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46788
+    - tracing/osnoise: Use a cpumask to know what threads are kthreads
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46846
+    - spi: rockchip: Resolve unbalanced runtime PM / system PM handling
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46847
+    - mm: vmalloc: ensure vmap_block is initialised before adding to queue
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46791
+    - can: mcp251x: fix deadlock if an interrupt occurs during mcp251x_open
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46829
+    - rtmutex: Drop rt_mutex::wait_lock before scheduling
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46848
+    - perf/x86/intel: Limit the period on Haswell
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46794
+    - x86/tdx: Fix data leak in mmio_read()
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46795
+    - ksmbd: unset the binding mark of a reused connection
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46797
+    - powerpc/qspinlock: Fix deadlock in MCS queue
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46830
+    - KVM: x86: Acquire kvm->srcu when handling KVM_SET_VCPU_EVENTS
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46798
+    - ASoC: dapm: Fix UAF for snd_soc_pcm_runtime object
+
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46831
+    - net: microchip: vcap: Fix use-after-free error in kunit test
+
+  * Navi24 RX6300 light up issue on 6.8 kernel (LP: #2084513)
+    - drm/amd/display: Ensure populate uclk in bb construction
+
+  * Noble update: upstream stable patchset 2024-10-18 (LP: #2084941)
+    - 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
+    - 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
+    - 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)
+    - 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/amdkfd: Check debug trap enable before write dbg_ev_file
+    - 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
+    - btrfs: factor out stripe length calculation into a helper
+    - btrfs: scrub: update last_physical after scrubbing one stripe
+    - btrfs: fix qgroup reserve leaks in cow_file_range
+    - virtio-net: check feature before configuring the vq coalescing command
+    - drm/amd/display: Handle the case which quad_part is equal 0
+    - drm/amdgpu: Handle sg size limit for contiguous allocation
+    - drm/amd/pm: fix uninitialized variable warning for smu_v13
+    - drm/amdgpu: fix uninitialized scalar variable warning
+    - drm/amd/display: Ensure array index tg_inst won't be -1
+    - drm/amd/display: handle invalid connector indices
+    - drm/amd/display: Increase MAX_LINKS by 2
+    - drm/amd/display: Stop amdgpu_dm initialize when link nums greater than
+      max_links
+    - drm/amd/display: Fix incorrect size calculation for loop
+    - drm/amd/display: Use kcalloc() instead of kzalloc()
+    - drm/amd/display: Add missing NULL pointer check within
+      dpcd_extend_address_range
+    - drm/amd/display: Release state memory if amdgpu_dm_create_color_properties
+      fail
+    - drm/amd/display: Check link_index before accessing dc->links[]
+    - drm/amd/display: Add otg_master NULL check within
+      resource_log_pipe_topology_update
+    - drm/amd/display: Release clck_src memory if clk_src_construct fails
+    - drm/amd/display: Fix writeback job lock evasion within dm_crtc_high_irq
+    - drm/xe: Demote CCS_MODE info to debug only
+    - drm/drm-bridge: Drop conditionals around of_node pointers
+    - drm/amdgpu: fix uninitialized variable warning for amdgpu_xgmi
+    - drm/amdgpu: fix uninitialized variable warning for jpeg_v4
+    - drm/amdgpu: Fix uninitialized variable warning in amdgpu_info_ioctl
+    - wifi: ath12k: initialize 'ret' in ath12k_dp_rxdma_ring_sel_config_wcn7850()
+    - drm/amdgpu/pm: Check input value for power profile setting on smu11, smu13
+      and smu14
+    - drm/xe: Fix the warning conditions
+    - drm/amd/display: Fix pipe addition logic in calc_blocks_to_ungate DCN35
+    - wifi: cfg80211: restrict operation during radar detection
+    - remoteproc: qcom_q6v5_pas: Add hwspinlock bust on stop
+    - tcp: annotate data-races around tw->tw_ts_recent and tw->tw_ts_recent_stamp
+    - drm/xe: Don't overmap identity VRAM mapping
+    - net: tcp/dccp: prepare for tw_timer un-pinning
+    - drm/xe: Ensure caller uses sole domain for xe_force_wake_assert_held
+    - drm/xe: Check valid domain is passed in xe_force_wake_ref
+    - thermal: trip: Use READ_ONCE() for lockless access to trip properties
+    - drm/xe: Add GuC state asserts to deregister_exec_queue
+    - drm/amdgpu: fix overflowed constant warning in mmhub_set_clockgating()
+    - drm/amd/display: Remove register from DCN35 DMCUB diagnostic collection
+    - drm/amd/display: Disable DMCUB timeout for DCN35
+    - drm/amd/display: Avoid overflow from uint32_t to uint8_t
+    - pinctrl: core: reset gpio_device in loop in pinctrl_pins_show()
+    - Upstream stable to v6.6.50, v6.10.9
+
+  * CVE-2024-46747
+    - HID: cougar: fix slab-out-of-bounds Read in cougar_report_fixup
+
+  * CVE-2024-46725
+    - drm/amdgpu: Fix out-of-bounds write warning
+
+  * CVE-2024-46724
+    - drm/amdgpu: Fix out-of-bounds read of df_v1_7_channel_number
+
+  * [SRU] Fix AST DP output after resume (LP: #2083022)
+    - drm/ast: Inline drm_simple_encoder_init()
+    - drm/ast: Implement atomic enable/disable for encoders
+    - drm/ast: Program mode for AST DP in atomic_mode_set
+    - drm/ast: Move mode-setting code into mode_set_nofb CRTC helper
+    - drm/ast: Handle primary-plane format setup in atomic_update
+    - drm/ast: Remove gamma LUT updates from DPMS code
+    - drm/ast: Only set VGA SCREEN_DISABLE bit in CRTC code
+    - drm/ast: Inline ast_crtc_dpms() into callers
+    - drm/ast: Use drm_atomic_helper_commit_tail() helper
+
+  * UBSAN array-index-out-of-bounds reported with N-6.8 on P9 node baltar
+    (LP: #2078038)
+    - scripts/kernel-doc: reindent
+    - compiler_types: add Endianness-dependent __counted_by_{le, be}
+    - scsi: aacraid: union aac_init: Replace 1-element array with flexible array
+    - scsi: aacraid: struct aac_ciss_phys_luns_resp: Replace 1-element array with
+      flexible array
+    - scsi: aacraid: Rearrange order of struct aac_srb_unit
+    - scsi: aacraid: struct {user, }sgmap{, 64, raw}: Replace 1-element arrays
+      with flexible arrays
+
+  * r8169: transmit queue 0 timed out error when re-plugging the Ethernet cable
+    (LP: #2084526)
+    - r8169: disable ALDPS per default for RTL8125
+
+  * [SRU] cpufreq: intel_pstate: Support Emerald Rapids OOB mode (LP: #2084834)
+    - cpufreq: intel_pstate: Support Emerald Rapids OOB mode
+
+  * CVE-2024-46723
+    - drm/amdgpu: fix ucode out-of-bounds read warning
+
+  * CVE-2024-46743
+    - of/irq: Prevent device address out-of-bounds read in interrupt map walk
+
+  * CVE-2024-46757
+    - hwmon: (nct6775-core) Fix underflows seen when writing limit attributes
+
+  * [SRU] Ubuntu 24.04 - GPU cannot be installed with DL380a Gen12 (2P, SRF-SP)
+    (LP: #2081079)
+    - perf/x86/uncore: Save the unit control address of all units
+    - perf/x86/uncore: Support per PMU cpumask
+    - perf/x86/uncore: Retrieve the unit ID from the unit control RB tree
+    - perf/x86/uncore: Apply the unit control RB tree to MMIO uncore units
+    - perf/x86/uncore: Apply the unit control RB tree to MSR uncore units
+    - perf/x86/uncore: Apply the unit control RB tree to PCI uncore units
+    - perf/x86/uncore: Cleanup unused unit structure
+    - perf/x86/intel/uncore: Support HBM and CXL PMON counters
+
+  * Noble update: upstream stable patchset 2024-10-11 (LP: #2084225)
+    - ALSA: seq: Skip event type filtering for UMP events
+    - LoongArch: Remove the unused dma-direct.h
+    - btrfs: fix a use-after-free when hitting errors inside btrfs_submit_chunk()
+    - btrfs: run delayed iputs when flushing delalloc
+    - smb/client: avoid dereferencing rdata=NULL in smb2_new_read_req()
+    - pinctrl: rockchip: correct RK3328 iomux width flag for GPIO2-B pins
+    - pinctrl: single: fix potential NULL dereference in pcs_get_function()
+    - wifi: wfx: repair open network AP mode
+    - wifi: mwifiex: duplicate static structs used in driver instances
+    - net: mana: Fix race of mana_hwc_post_rx_wqe and new hwc response
+    - mptcp: close subflow when receiving TCP+FIN
+    - mptcp: sched: check both backup in retrans
+    - mptcp: pm: reuse ID 0 after delete and re-add
+    - mptcp: pm: skip connecting to already established sf
+    - mptcp: pm: reset MPC endp ID when re-added
+    - mptcp: pm: send ACK on an active subflow
+    - mptcp: pm: do not remove already closed subflows
+    - mptcp: pm: fix ID 0 endp usage after multiple re-creations
+    - mptcp: pm: ADD_ADDR 0 is not a new address
+    - selftests: mptcp: join: check removing ID 0 endpoint
+    - selftests: mptcp: join: no extra msg if no counter
+    - selftests: mptcp: join: check re-re-adding ID 0 endp
+    - drm/amdgpu/swsmu: always force a state reprogram on init
+    - drm/vmwgfx: Fix prime with external buffers
+    - usb: typec: fix up incorrectly backported "usb: typec: tcpm: unregister
+      existing source caps before re-registration"
+    - ASoC: amd: acp: fix module autoloading
+    - ASoC: SOF: amd: Fix for acp init sequence
+    - pinctrl: mediatek: common-v2: Fix broken bias-disable for
+      PULL_PU_PD_RSEL_TYPE
+    - pinctrl: starfive: jh7110: Correct the level trigger configuration of iev
+      register
+    - ovl: pass string to ovl_parse_layer()
+    - ovl: fix wrong lowerdir number check for parameter Opt_lowerdir
+    - ovl: ovl_parse_param_lowerdir: Add missed '\n' for pr_err
+    - mm: Fix missing folio invalidation calls during truncation
+    - cifs: Fix FALLOC_FL_PUNCH_HOLE support
+    - selinux,smack: don't bypass permissions check in inode_setsecctx hook
+    - iommufd: Do not allow creating areas without READ or WRITE
+    - phy: fsl-imx8mq-usb: fix tuning parameter name
+    - dmaengine: dw-edma: Fix unmasking STOP and ABORT interrupts for HDMA
+    - dmaengine: dw-edma: Do not enable watermark interrupts for HDMA
+    - phy: xilinx: phy-zynqmp: Fix SGMII linkup failure on resume
+    - dmaengine: dw: Add peripheral bus width verification
+    - dmaengine: dw: Add memory bus width verification
+    - Bluetooth: btnxpuart: Resolve TX timeout error in power save stress test
+    - Bluetooth: btnxpuart: Handle FW Download Abort scenario
+    - Bluetooth: btnxpuart: Fix random crash seen while removing driver
+    - Bluetooth: hci_core: Fix not handling hibernation actions
+    - iommu: Do not return 0 from map_pages if it doesn't do anything
+    - netfilter: nf_tables: restore IP sanity checks for netdev/egress
+    - wifi: iwlwifi: fw: fix wgds rev 3 exact size
+    - ethtool: check device is present when getting link settings
+    - netfilter: nf_tables_ipv6: consider network offset in netdev/egress
+      validation
+    - selftests: forwarding: no_forwarding: Down ports on cleanup
+    - selftests: forwarding: local_termination: Down ports on cleanup
+    - bonding: implement xdo_dev_state_free and call it after deletion
+    - bonding: extract the use of real_device into local variable
+    - bonding: change ipsec_lock from spin lock to mutex
+    - gtp: fix a potential NULL pointer dereference
+    - sctp: fix association labeling in the duplicate COOKIE-ECHO case
+    - drm/amd/display: avoid using null object of framebuffer
+    - net: busy-poll: use ktime_get_ns() instead of local_clock()
+    - nfc: pn533: Add poll mod list filling check
+    - soc: qcom: cmd-db: Map shared memory as WC, not WB
+    - soc: qcom: pmic_glink: Actually communicate when remote goes down
+    - soc: qcom: pmic_glink: Fix race during initialization
+    - cdc-acm: Add DISABLE_ECHO quirk for GE HealthCare UI Controller
+    - scsi: sd: Ignore command SYNCHRONIZE CACHE error if format in progress
+    - USB: serial: option: add MeiG Smart SRM825L
+    - ARM: dts: imx6dl-yapp43: Increase LED current to match the yapp4 HW design
+    - usb: dwc3: omap: add missing depopulate in probe error path
+    - usb: dwc3: core: Prevent USB core invalid event buffer address access
+    - usb: dwc3: st: fix probed platform device ref count on probe error path
+    - usb: dwc3: st: add missing depopulate in probe error path
+    - usb: core: sysfs: Unmerge @usb3_hardware_lpm_attr_group in
+      remove_power_attributes()
+    - usb: cdnsp: fix incorrect index in cdnsp_get_hw_deq function
+    - usb: cdnsp: fix for Link TRB with TC
+    - ARM: dts: omap3-n900: correct the accelerometer orientation
+    - arm64: dts: imx8mp-beacon-kit: Fix Stereo Audio on WM8962
+    - arm64: dts: imx93: add nvmem property for fec1
+    - arm64: dts: imx93: add nvmem property for eqos
+    - arm64: dts: imx93: update default value for snps,clk-csr
+    - arm64: dts: freescale: imx93-tqma9352: fix CMA alloc-ranges
+    - arm64: dts: freescale: imx93-tqma9352-mba93xxla: fix typo
+    - scsi: aacraid: Fix double-free on probe failure
+    - apparmor: fix policy_unpack_test on big endian systems
+    - mptcp: pr_debug: add missing \n at the end
+    - mptcp: make pm_remove_addrs_and_subflows static
+    - mptcp: pm: fix RM_ADDR ID for the initial subflow
+    - mptcp: avoid duplicated SUB_CLOSED events
+    - drm/i915/dsi: Make Lenovo Yoga Tab 3 X90F DMI match less strict
+    - drm/vmwgfx: Prevent unmapping active read buffers
+    - drm/vmwgfx: Disable coherent dumb buffers without 3d
+    - firmware/sysfb: Set firmware-framebuffer parent device
+    - firmware/sysfb: Create firmware device only for enabled PCI devices
+    - video/aperture: optionally match the device in sysfb_disable()
+    - drm/xe: Prepare display for D3Cold
+    - drm/xe/display: Make display suspend/resume work on discrete
+    - drm/xe/vm: Simplify if condition
+    - drm/xe/exec_queue: Rename xe_exec_queue::compute to xe_exec_queue::lr
+    - drm/xe: prevent UAF around preempt fence
+    - pinctrl: qcom: x1e80100: Update PDC hwirq map
+    - ASoC: SOF: amd: move iram-dram fence register programming sequence
+    - nfsd: ensure that nfsd4_fattr_args.context is zeroed out
+    - backing-file: convert to using fops->splice_write
+    - pinctrl: qcom: x1e80100: Fix special pin offsets
+    - afs: Fix post-setattr file edit to do truncation correctly
+    - netfs: Fix netfs_release_folio() to say no if folio dirty
+    - netfs: Fix missing iterator reset on retry of short read
+    - dmaengine: ti: omap-dma: Initialize sglen after allocation
+    - pktgen: use cpus_read_lock() in pg_net_init()
+    - net_sched: sch_fq: fix incorrect behavior for small weights
+    - tcp: fix forever orphan socket caused by tcp_abort
+    - drm/xe/hwmon: Fix WRITE_I1 param from u32 to u16
+    - usb: typec: fsa4480: Relax CHIP_ID check
+    - firmware: qcom: scm: Mark get_wq_ctx() as atomic call
+    - usb: gadget: uvc: queue pump work in uvcg_video_enable()
+    - usb: dwc3: xilinx: add missing depopulate in probe error path
+    - usb: typec: ucsi: Move unregister out of atomic section
+    - firmware: microchip: fix incorrect error report of programming:timeout on
+      success
+    - Upstream stable to v6.6.49, v6.10.8
+
+  * Fix blank screen on external display after reconnecting the USB type-C
+    (LP: #2081786) // Noble update: upstream stable patchset 2024-10-11
+    (LP: #2084225)
+    - drm/i915/display: add intel_display -> drm_device backpointer
+    - drm/i915/display: add generic to_intel_display() macro
+    - drm/i915/dp_mst: Fix MST state after a sink reset
+
+  * Noble update: upstream stable patchset 2024-10-09 (LP: #2084005)
+    - tty: serial: fsl_lpuart: mark last busy before uart_add_one_port
+    - tty: atmel_serial: use the correct RTS flag.
+    - Revert "ACPI: EC: Evaluate orphan _REG under EC device"
+    - Revert "misc: fastrpc: Restrict untrusted app to attach to privileged PD"
+    - Revert "usb: typec: tcpm: clear pd_event queue in PORT_RESET"
+    - selinux: revert our use of vma_is_initial_heap()
+    - fuse: Initialize beyond-EOF page contents before setting uptodate
+    - char: xillybus: Don't destroy workqueue from work item running on it
+    - char: xillybus: Refine workqueue handling
+    - char: xillybus: Check USB endpoints when probing device
+    - ALSA: usb-audio: Add delay quirk for VIVO USB-C-XE710 HEADSET
+    - ALSA: usb-audio: Support Yamaha P-125 quirk entry
+    - xhci: Fix Panther point NULL pointer deref at full-speed re-enumeration
+    - thunderbolt: Mark XDomain as unplugged when router is removed
+    - ALSA: hda/tas2781: fix wrong calibrated data order
+    - s390/dasd: fix error recovery leading to data corruption on ESE devices
+    - KVM: s390: fix validity interception issue when gisa is switched off
+    - riscv: change XIP's kernel_map.size to be size of the entire kernel
+    - i2c: tegra: Do not mark ACPI devices as irq safe
+    - ACPICA: Add a depth argument to acpi_execute_reg_methods()
+    - ACPI: EC: Evaluate _REG outside the EC scope more carefully
+    - arm64: ACPI: NUMA: initialize all values of acpi_early_node_map to
+      NUMA_NO_NODE
+    - dm resume: don't return EINVAL when signalled
+    - dm persistent data: fix memory allocation failure
+    - fs/ntfs3: add prefix to bitmap_size() and use BITS_TO_U64()
+    - s390/cio: rename bitmap_size() -> idset_bitmap_size()
+    - btrfs: rename bitmap_set_bits() -> btrfs_bitmap_set_bits()
+    - bitmap: introduce generic optimized bitmap_size()
+    - fix bitmap corruption on close_range() with CLOSE_RANGE_UNSHARE
+    - i2c: qcom-geni: Add missing geni_icc_disable in geni_i2c_runtime_resume
+    - rtla/osnoise: Prevent NULL dereference in error handling
+    - net: mana: Fix RX buf alloc_size alignment and atomic op panic
+    - net: mana: Fix doorbell out of order violation and avoid unnecessary
+      doorbell rings
+    - wifi: brcmfmac: cfg80211: Handle SSID based pmksa deletion
+    - selinux: fix potential counting error in avc_add_xperms_decision()
+    - selinux: add the processing of the failure of avc_add_xperms_decision()
+    - mm/memory-failure: use raw_spinlock_t in struct memory_failure_cpu
+    - btrfs: tree-checker: reject BTRFS_FT_UNKNOWN dir type
+    - btrfs: zoned: properly take lock to read/update block group's zoned
+      variables
+    - btrfs: tree-checker: add dev extent item checks
+    - drm/amdgpu: Actually check flags for all context ops.
+    - memcg_write_event_control(): fix a user-triggerable oops
+    - drm/amdgpu/jpeg2: properly set atomics vmid field
+    - drm/amdgpu/jpeg4: properly set atomics vmid field
+    - s390/uv: Panic for set and remove shared access UVC errors
+    - bpf: Fix updating attached freplace prog in prog_array map
+    - igc: Fix packet still tx after gate close by reducing i226 MAC retry buffer
+    - igc: Fix qbv_config_change_errors logics
+    - igc: Fix reset adapter logics when tx mode change
+    - net/mlx5e: Take state lock during tx timeout reporter
+    - net/mlx5e: Correctly report errors for ethtool rx flows
+    - net: axienet: Fix register defines comment description
+    - net: dsa: vsc73xx: pass value in phy_write operation
+    - net: dsa: vsc73xx: use read_poll_timeout instead delay loop
+    - net: dsa: vsc73xx: check busy flag in MDIO operations
+    - net: ethernet: mtk_wed: fix use-after-free panic in
+      mtk_wed_setup_tc_block_cb()
+    - mlxbf_gige: disable RX filters until RX path initialized
+    - mptcp: correct MPTCP_SUBFLOW_ATTR_SSN_OFFSET reserved size
+    - tcp: Update window clamping condition
+    - netfilter: allow ipv6 fragments to arrive on different devices
+    - netfilter: flowtable: initialise extack before use
+    - netfilter: nf_queue: drop packets with cloned unconfirmed conntracks
+    - netfilter: nf_tables: Audit log dump reset after the fact
+    - netfilter: nf_tables: Introduce nf_tables_getobj_single
+    - netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests
+    - vsock: fix recursive ->recvmsg calls
+    - selftests: net: lib: ignore possible errors
+    - selftests: net: lib: kill PIDs before del netns
+    - net: hns3: fix wrong use of semaphore up
+    - net: hns3: use the user's cfg after reset
+    - net: hns3: fix a deadlock problem when config TC during resetting
+    - gpio: mlxbf3: Support shutdown() function
+    - ALSA: hda/realtek: Fix noise from speakers on Lenovo IdeaPad 3 15IAU7
+    - rust: work around `bindgen` 0.69.0 issue
+    - rust: suppress error messages from CONFIG_{RUSTC,BINDGEN}_VERSION_TEXT
+    - rust: fix the default format for CONFIG_{RUSTC,BINDGEN}_VERSION_TEXT
+    - cpu/SMT: Enable SMT only if a core is online
+    - powerpc/topology: Check if a core is online
+    - arm64: Fix KASAN random tag seed initialization
+    - block: Fix lockdep warning in blk_mq_mark_tag_wait
+    - wifi: ath12k: Add missing qmi_txn_cancel() calls
+    - quota: Remove BUG_ON from dqget()
+    - riscv: blacklist assembly symbols for kprobe
+    - kernfs: fix false-positive WARN(nr_mmapped) in kernfs_drain_open_files
+    - media: pci: cx23885: check cx23885_vdev_init() return
+    - fs: binfmt_elf_efpic: don't use missing interpreter's properties
+    - scsi: lpfc: Initialize status local variable in lpfc_sli4_repost_sgl_list()
+    - media: drivers/media/dvb-core: copy user arrays safely
+    - wifi: iwlwifi: mvm: avoid garbage iPN
+    - net/sun3_82586: Avoid reading past buffer in debug output
+    - drm/lima: set gp bus_stop bit before hard reset
+    - gpio: sysfs: extend the critical section for unregistering sysfs devices
+    - hrtimer: Select housekeeping CPU during migration
+    - virtiofs: forbid newlines in tags
+    - accel/habanalabs: fix debugfs files permissions
+    - clocksource/drivers/arm_global_timer: Guard against division by zero
+    - tick: Move got_idle_tick away from common flags
+    - netlink: hold nlk->cb_mutex longer in __netlink_dump_start()
+    - md: clean up invalid BUG_ON in md_ioctl
+    - x86: Increase brk randomness entropy for 64-bit systems
+    - memory: stm32-fmc2-ebi: check regmap_read return value
+    - parisc: Use irq_enter_rcu() to fix warning at kernel/context_tracking.c:367
+    - rxrpc: Don't pick values out of the wire header when setting up security
+    - f2fs: stop checkpoint when get a out-of-bounds segment
+    - powerpc/boot: Handle allocation failure in simple_realloc()
+    - powerpc/boot: Only free if realloc() succeeds
+    - btrfs: delayed-inode: drop pointless BUG_ON in __btrfs_remove_delayed_item()
+    - btrfs: defrag: change BUG_ON to assertion in btrfs_defrag_leaves()
+    - btrfs: change BUG_ON to assertion when checking for delayed_node root
+    - btrfs: push errors up from add_async_extent()
+    - btrfs: handle invalid root reference found in may_destroy_subvol()
+    - btrfs: send: handle unexpected data in header buffer in begin_cmd()
+    - btrfs: send: handle unexpected inode in header process_recorded_refs()
+    - btrfs: change BUG_ON to assertion in tree_move_down()
+    - btrfs: delete pointless BUG_ON check on quota root in
+      btrfs_qgroup_account_extent()
+    - f2fs: fix to do sanity check in update_sit_entry
+    - usb: gadget: fsl: Increase size of name buffer for endpoints
+    - nvme: clear caller pointer on identify failure
+    - Bluetooth: bnep: Fix out-of-bound access
+    - firmware: cirrus: cs_dsp: Initialize debugfs_root to invalid
+    - rtc: nct3018y: fix possible NULL dereference
+    - net: hns3: add checking for vf id of mailbox
+    - nvmet-tcp: do not continue for invalid icreq
+    - NFS: avoid infinite loop in pnfs_update_layout.
+    - openrisc: Call setup_memory() earlier in the init sequence
+    - s390/iucv: fix receive buffer virtual vs physical address confusion
+    - irqchip/renesas-rzg2l: Do not set TIEN and TINT source at the same time
+    - platform/x86: lg-laptop: fix %s null argument warning
+    - usb: dwc3: core: Skip setting event buffers for host only controllers
+    - irqchip/gic-v3-its: Remove BUG_ON in its_vpe_irq_domain_alloc
+    - ext4: set the type of max_zeroout to unsigned int to avoid overflow
+    - nvmet-rdma: fix possible bad dereference when freeing rsps
+    - selftests/bpf: Fix a few tests for GCC related warnings.
+    - Revert "bpf, sockmap: Prevent lock inversion deadlock in map delete elem"
+    - nvme: use srcu for iterating namespace list
+    - drm/amdgpu: fix dereference null return value for the function
+      amdgpu_vm_pt_parent
+    - hrtimer: Prevent queuing of hrtimer without a function callback
+    - nvme: fix namespace removal list
+    - gtp: pull network headers in gtp_dev_xmit()
+    - riscv: entry: always initialize regs->a0 to -ENOSYS
+    - smb3: fix lock breakage for cached writes
+    - dm suspend: return -ERESTARTSYS instead of -EINTR
+    - selftests: memfd_secret: don't build memfd_secret test on unsupported arches
+    - mm/vmalloc: fix page mapping if vm_area_alloc_pages() with high order
+      fallback to order 0
+    - btrfs: send: allow cloning non-aligned extent if it ends at i_size
+    - drm/amd/amdgpu: command submission parser for JPEG
+    - platform/surface: aggregator: Fix warning when controller is destroyed in
+      probe
+    - ALSA: hda/tas2781: Use correct endian conversion
+    - Bluetooth: hci_core: Fix LE quote calculation
+    - Bluetooth: SMP: Fix assumption of Central always being Initiator
+    - net: mscc: ocelot: use ocelot_xmit_get_vlan_info() also for FDMA and
+      register injection
+    - net: mscc: ocelot: fix QoS class for injected packets with "ocelot-8021q"
+    - net: mscc: ocelot: serialize access to the injection/extraction groups
+    - tc-testing: don't access non-existent variable on exception
+    - selftests: udpgro: report error when receive failed
+    - tcp/dccp: bypass empty buckets in inet_twsk_purge()
+    - tcp/dccp: do not care about families in inet_twsk_purge()
+    - tcp: prevent concurrent execution of tcp_sk_exit_batch
+    - net: mctp: test: Use correct skb for route input check
+    - kcm: Serialise kcm_sendmsg() for the same socket.
+    - netfilter: nft_counter: Disable BH in nft_counter_offload_stats().
+    - netfilter: nft_counter: Synchronize nft_counter_reset() against reader.
+    - ip6_tunnel: Fix broken GRO
+    - bonding: fix bond_ipsec_offload_ok return type
+    - bonding: fix null pointer deref in bond_ipsec_offload_ok
+    - bonding: fix xfrm real_dev null pointer dereference
+    - bonding: fix xfrm state handling when clearing active slave
+    - ice: fix page reuse when PAGE_SIZE is over 8k
+    - ice: fix ICE_LAST_OFFSET formula
+    - ice: fix truesize operations for PAGE_SIZE >= 8192
+    - dpaa2-switch: Fix error checking in dpaa2_switch_seed_bp()
+    - igb: cope with large MAX_SKB_FRAGS
+    - net: dsa: mv88e6xxx: Fix out-of-bound access
+    - udp: fix receiving fraglist GSO packets
+    - ipv6: fix possible UAF in ip6_finish_output2()
+    - ipv6: prevent possible UAF in ip6_xmit()
+    - bnxt_en: Fix double DMA unmapping for XDP_REDIRECT
+    - netfilter: flowtable: validate vlan header
+    - octeontx2-af: Fix CPT AF register offset calculation
+    - net: xilinx: axienet: Always disable promiscuous mode
+    - net: xilinx: axienet: Fix dangling multicast addresses
+    - net: ovs: fix ovs_drop_reasons error
+    - drm/msm/dpu: don't play tricks with debug macros
+    - drm/msm/dp: fix the max supported bpp logic
+    - drm/msm/dpu: split dpu_encoder_wait_for_event into two functions
+    - drm/msm/dpu: capture snapshot on the first commit_done timeout
+    - drm/msm/dpu: move dpu_encoder's connector assignment to atomic_enable()
+    - drm/msm/dp: reset the link phy params before link training
+    - drm/msm/dpu: cleanup FB if dpu_format_populate_layout fails
+    - drm/msm/dpu: take plane rotation into account for wide planes
+    - drm/msm: fix the highest_bank_bit for sc7180
+    - mmc: mmc_test: Fix NULL dereference on allocation failure
+    - Bluetooth: MGMT: Add error handling to pair_device()
+    - scsi: core: Fix the return value of scsi_logical_block_count()
+    - ksmbd: the buffer of smb2 query dir response has at least 1 byte
+    - drm/amdgpu: Validate TA binary size
+    - net: dsa: microchip: fix PTP config failure when using multiple ports
+    - MIPS: Loongson64: Set timer mode in cpu-probe
+    - HID: wacom: Defer calculation of resolution until resolution_code is known
+    - Input: i8042 - add forcenorestore quirk to leave controller untouched even
+      on s3
+    - Input: i8042 - use new forcenorestore quirk to replace old buggy quirk
+      combination
+    - cxgb4: add forgotten u64 ivlan cast before shift
+    - KVM: arm64: Make ICC_*SGI*_EL1 undef in the absence of a vGICv3
+    - mmc: mtk-sd: receive cmd8 data when hs400 tuning fail
+    - mmc: dw_mmc: allow biu and ciu clocks to defer
+    - smb3: fix broken cached reads when posix locks
+    - pmdomain: imx: scu-pd: Remove duplicated clocks
+    - pmdomain: imx: wait SSAR when i.MX93 power domain on
+    - nouveau/firmware: use dma non-coherent allocator
+    - mptcp: pm: re-using ID of unused removed ADD_ADDR
+    - mptcp: pm: re-using ID of unused removed subflows
+    - mptcp: pm: re-using ID of unused flushed subflows
+    - mptcp: pm: remove mptcp_pm_remove_subflow()
+    - mptcp: pm: only mark 'subflow' endp as available
+    - mptcp: pm: only decrement add_addr_accepted for MPJ req
+    - mptcp: pm: check add_addr_accept_max before accepting new ADD_ADDR
+    - mptcp: pm: only in-kernel cannot have entries with ID 0
+    - mptcp: pm: fullmesh: select the right ID later
+    - mptcp: pm: avoid possible UaF when selecting endp
+    - selftests: mptcp: join: validate fullmesh endp on 1st sf
+    - selftests: mptcp: join: restrict fullmesh endp on 1st sf
+    - selftests: mptcp: join: check re-using ID of closed subflow
+    - tcp: do not export tcp_twsk_purge()
+    - drm/msm/mdss: specify cfg bandwidth for SDM670
+    - drm/panel: nt36523: Set 120Hz fps for xiaomi,elish panels
+    - igc: Fix qbv tx latency by setting gtxoffset
+    - ALSA: timer: Relax start tick time check for slave timer elements
+    - bpf: Fix a kernel verifier crash in stacksafe()
+    - selftests/bpf: Add a test to verify previous stacksafe() fix
+    - Revert "s390/dasd: Establish DMA alignment"
+    - Input: MT - limit max slots
+    - tools: move alignment-related macros to new <linux/align.h>
+    - Revert "serial: 8250_omap: Set the console genpd always on if no console
+      suspend"
+    - usb: misc: ljca: Add Lunar Lake ljca GPIO HID to ljca_gpio_hids[]
+    - usb: xhci: Check for xhci->interrupters being allocated in
+      xhci_mem_clearup()
+    - vfs: Don't evict inode under the inode lru traversing context
+    - tracing: Return from tracing_buffers_read() if the file has been closed
+    - mm: fix endless reclaim on machines with unaccepted memory
+    - fs/netfs/fscache_cookie: add missing "n_accesses" check
+    - mm/numa: no task_numa_fault() call if PMD is changed
+    - mm/numa: no task_numa_fault() call if PTE is changed
+    - btrfs: check delayed refs when we're checking if a ref exists
+    - drm/amd/display: Adjust cursor position
+    - drm/amd/display: fix s2idle entry for DCN3.5+
+    - drm/amd/display: Enable otg synchronization logic for DCN321
+    - drm/amd/display: fix cursor offset on rotation 180
+    - netfs: Fault in smaller chunks for non-large folio mappings
+    - libfs: fix infinite directory reads for offset dir
+    - kallsyms: Avoid weak references for kallsyms symbols
+    - kbuild: avoid unneeded kallsyms step 3
+    - kbuild: refactor variables in scripts/link-vmlinux.sh
+    - kbuild: remove PROVIDE() for kallsyms symbols
+    - kallsyms: get rid of code for absolute kallsyms
+    - [Config] Remove CONFIG_KALLSYMS_BASE_RELATIVE
+    - kallsyms: Do not cleanup .llvm.<hash> suffix before sorting symbols
+    - bpf: Replace deprecated strncpy with strscpy
+    - kallsyms: replace deprecated strncpy with strscpy
+    - kallsyms: rework symbol lookup return codes
+    - kallsyms: Match symbols exactly with CONFIG_LTO_CLANG
+    - drm/v3d: Fix out-of-bounds read in `v3d_csd_job_run()`
+    - drm/amd/display: Don't register panel_power_savings on OLED panels
+    - wifi: ath12k: use 128 bytes aligned iova in transmit path for WCN7850
+    - kbuild: merge temporary vmlinux for BTF and kallsyms
+    - kbuild: avoid scripts/kallsyms parsing /dev/null
+    - Bluetooth: HCI: Invert LE State quirk to be opt-out rather then opt-in
+    - net/mlx5: Fix IPsec RoCE MPV trace call
+    - selftests: udpgro: no need to load xdp for gro
+    - ice: use internal pf id instead of function number
+    - drm/msm/dpu: limit QCM2290 to RGB formats only
+    - drm/msm/dpu: relax YUV requirements
+    - spi: spi-cadence-quadspi: Fix OSPI NOR failures during system resume
+    - drm/xe/display: stop calling domains_driver_remove twice
+    - drm/xe: Fix opregion leak
+    - drm/xe/mmio: move mmio_fini over to devm
+    - drm/xe: reset mmio mappings with devm
+    - drm/xe: Fix tile fini sequence
+    - drm/xe: Fix missing workqueue destroy in xe_gt_pagefault
+    - drm/xe: Free job before xe_exec_queue_put
+    - thermal/debugfs: Fix the NULL vs IS_ERR() confusion in debugfs_create_dir()
+    - nvme: move stopping keep-alive into nvme_uninit_ctrl()
+    - drm/amdgpu/sdma5.2: limit wptr workaround to sdma 5.2.1
+    - s390/ap: Refine AP bus bindings complete processing
+    - net: ngbe: Fix phy mode set to external phy
+    - iommufd/device: Fix hwpt at err_unresv in iommufd_device_do_replace()
+    - cgroup/cpuset: fix panic caused by partcmd_update
+    - cgroup/cpuset: Clear effective_xcpus on cpus_allowed clearing only if
+      cpus.exclusive not set
+    - of: Introduce for_each_*_child_of_node_scoped() to automate of_node_put()
+      handling
+    - thermal: of: Fix OF node leak in thermal_of_trips_init() error path
+    - thermal: of: Fix OF node leak in thermal_of_zone_register()
+    - thermal: of: Fix OF node leak in of_thermal_zone_find() error paths
+    - Upstream stable to v6.6.48, v6.10.7
+
+  * Unable to list directories using CIFS on 6.8 kernel (LP: #2082423) // Noble
+    update: upstream stable patchset 2024-10-09 (LP: #2084005)
+    - smb: client: ignore unhandled reparse tags
+
+  * CVE-2024-46759
+    - hwmon: (adc128d818) Fix underflows seen when writing limit attributes
+
+  * CVE-2024-46758
+    - hwmon: (lm95234) Fix underflows seen when writing limit attributes
+
+  * CVE-2024-46756
+    - hwmon: (w83627ehf) Fix underflows seen when writing limit attributes
+
+  * CVE-2024-46738
+    - VMCI: Fix use-after-free when removing resource in vmci_resource_remove()
+
+  * CVE-2024-46722
+    - drm/amdgpu: fix mc_data out-of-bounds read warning
+
+  * LXD fan bridge causes blocked tasks (LP: #2064176)
+    - SAUCE: fan: release rcu_read_lock on skb discard path
+    - SAUCE: fan: fix racy device stat update
+
+  * x86/CPU/AMD: Add models 0x10-0x1f to the Zen5 range (LP: #2081863)
+    - x86/CPU/AMD: Add models 0x60-0x6f to the Zen5 range
+
+  * UBSAN: array-index-out-of-bounds in module mt76 (LP: #2081785)
+    - wifi: mt76: mt7925: fix a potential array-index-out-of-bounds issue for clc
+
+  * The system hangs after resume with thunderbolt monitor(AMD GPU [1002:1900])
+    (LP: #2083182)
+    - SAUCE: drm/amd/display: Fix system hang while resume with TBT monitor
+
+  * [SRU] GPU: support additional device ids for DG2 driver (LP: #2083701)
+    - drm/i915: Add new PCI IDs to DG2 platform in driver
+
+  * [SRU]Intel Arrow Lake IBECC feature backport request for ubuntu 22.04.5 and
+    24.04.1 server (LP: #2077861)
+    - EDAC/igen6: Add Intel Arrow Lake-U/H SoCs support
+
+  * Noble update: upstream stable patchset 2024-10-07 (LP: #2083794)
+    - ASoC: topology: Clean up route loading
+    - ASoC: topology: Fix route memory corruption
+    - LoongArch: Define __ARCH_WANT_NEW_STAT in unistd.h
+    - sunrpc: don't change ->sv_stats if it doesn't exist
+    - nfsd: stop setting ->pg_stats for unused stats
+    - sunrpc: pass in the sv_stats struct through svc_create_pooled
+    - sunrpc: remove ->pg_stats from svc_program
+    - nfsd: remove nfsd_stats, make th_cnt a global counter
+    - nfsd: make svc_stat per-network namespace instead of global
+    - mm: gup: stop abusing try_grab_folio
+    - nvme/pci: Add APST quirk for Lenovo N60z laptop
+    - genirq/cpuhotplug: Skip suspended interrupts when restoring affinity
+    - genirq/cpuhotplug: Retry with cpu_online_mask when migration fails
+    - quota: Detect loops in quota tree
+    - bpf: Replace bpf_lpm_trie_key 0-length array with flexible array
+    - fs: Annotate struct file_handle with __counted_by() and use struct_size()
+    - mISDN: fix MISDN_TIME_STAMP handling
+    - mm/page_table_check: support userfault wr-protect entries
+    - bpf, net: Use DEV_STAT_INC()
+    - f2fs: fix to do sanity check on F2FS_INLINE_DATA flag in inode during GC
+    - f2fs: fix to cover read extent cache access with lock
+    - fou: remove warn in gue_gro_receive on unsupported protocol
+    - jfs: fix null ptr deref in dtInsertEntry
+    - jfs: Fix shift-out-of-bounds in dbDiscardAG
+    - fs/ntfs3: Do copy_to_user out of run_lock
+    - ALSA: usb: Fix UBSAN warning in parse_audio_unit()
+    - binfmt_flat: Fix corruption when not offsetting data start
+    - mm/debug_vm_pgtable: drop RANDOM_ORVALUE trick
+    - KVM: arm64: Don't defer TLB invalidation when zapping table entries
+    - KVM: arm64: Don't pass a TLBI level hint when zapping table entries
+    - drm/amd/display: Defer handling mst up request in resume
+    - drm/amd/display: Guard cursor idle reallow by DC debug option
+    - drm/amd/display: Separate setting and programming of cursor
+    - drm/amd/display: Prevent IPX From Link Detect and Set Mode
+    - ASoC: cs35l56: Patch CS35L56_IRQ1_MASK_18 to the default value
+    - platform/x86/amd/pmf: Fix to Update HPD Data When ALS is Disabled
+    - platform/x86: ideapad-laptop: introduce a generic notification chain
+    - platform/x86: ideapad-laptop: move ymc_trigger_ec from lenovo-ymc
+    - platform/x86: ideapad-laptop: add a mutex to synchronize VPC commands
+    - drm/amd/display: Solve mst monitors blank out problem after resume
+    - drm/amdgpu/display: Fix null pointer dereference in
+      dc_stream_program_cursor_position
+    - Upstream stable to v6.6.47, v6.10.6
+
+  * Noble update: upstream stable patchset 2024-10-04 (LP: #2083656)
+    - irqchip/mbigen: Fix mbigen node address layout
+    - platform/x86/intel/ifs: Initialize union ifs_status to zero
+    - jump_label: Fix the fix, brown paper bags galore
+    - x86/mm: Fix pti_clone_pgtable() alignment assumption
+    - x86/mm: Fix pti_clone_entry_text() for i386
+    - smb: client: move most of reparse point handling code to common file
+    - smb: client: set correct d_type for reparse DFS/DFSR and mount point
+    - smb: client: handle lack of FSCTL_GET_REPARSE_POINT support
+    - sctp: Fix null-ptr-deref in reuseport_add_sock().
+    - net: usb: qmi_wwan: fix memory leak for not ip packets
+    - net: bridge: mcast: wait for previous gc cycles when removing port
+    - net: linkwatch: use system_unbound_wq
+    - ice: Fix reset handler
+    - Bluetooth: l2cap: always unlock channel in l2cap_conless_channel()
+    - Bluetooth: hci_sync: avoid dup filtering when passive scanning with adv
+      monitor
+    - net/smc: add the max value of fallback reason count
+    - net: dsa: bcm_sf2: Fix a possible memory leak in bcm_sf2_mdio_register()
+    - l2tp: fix lockdep splat
+    - net: bcmgenet: Properly overlay PHY and MAC Wake-on-LAN capabilities
+    - net: fec: Stop PPS on driver remove
+    - gpio: prevent potential speculation leaks in gpio_device_get_desc()
+    - hwmon: corsair-psu: add USB id of HX1200i Series 2023 psu
+    - rcutorture: Fix rcu_torture_fwd_cb_cr() data race
+    - md: do not delete safemode_timer in mddev_suspend
+    - md/raid5: avoid BUG_ON() while continue reshape after reassembling
+    - block: change rq_integrity_vec to respect the iterator
+    - rcu: Fix rcu_barrier() VS post CPUHP_TEARDOWN_CPU invocation
+    - clocksource/drivers/sh_cmt: Address race condition for clock events
+    - ACPI: battery: create alarm sysfs attribute atomically
+    - ACPI: SBS: manage alarm sysfs attribute through psy core
+    - xen: privcmd: Switch from mutex to spinlock for irqfds
+    - wifi: nl80211: disallow setting special AP channel widths
+    - wifi: ath12k: fix memory leak in ath12k_dp_rx_peer_frag_setup()
+    - net/mlx5e: SHAMPO, Fix invalid WQ linked list unlink
+    - selftests/bpf: Fix send_signal test with nested CONFIG_PARAVIRT
+    - af_unix: Don't retry after unix_state_lock_nested() in
+      unix_stream_connect().
+    - PCI: Add Edimax Vendor ID to pci_ids.h
+    - udf: prevent integer overflow in udf_bitmap_free_blocks()
+    - wifi: nl80211: don't give key data to userspace
+    - can: mcp251xfd: tef: prepare to workaround broken TEF FIFO tail index
+      erratum
+    - can: mcp251xfd: tef: update workaround for erratum DS80000789E 6 of
+      mcp2518fd
+    - net: stmmac: qcom-ethqos: enable SGMII loopback during DMA reset on
+      sa8775p-ride-r3
+    - btrfs: do not clear page dirty inside extent_write_locked_range()
+    - btrfs: fix invalid mapping of extent xarray state
+    - btrfs: fix bitmap leak when loading free space cache on duplicate entry
+    - Bluetooth: btnxpuart: Shutdown timer and prevent rearming when driver
+      unloading
+    - drm/amd/display: Add delay to improve LTTPR UHBR interop
+    - drm/amdgpu: fix potential resource leak warning
+    - drm/amdgpu/pm: Fix the param type of set_power_profile_mode
+    - drm/amdgpu/pm: Fix the null pointer dereference for smu7
+    - drm/amdgpu: Fix the null pointer dereference to ras_manager
+    - drm/amdgpu/pm: Fix the null pointer dereference in apply_state_adjust_rules
+    - drm/admgpu: fix dereferencing null pointer context
+    - drm/amdgpu: Add lock around VF RLCG interface
+    - drm/amd/pm: Fix the null pointer dereference for vega10_hwmgr
+    - media: amphion: Remove lock in s_ctrl callback
+    - drm/amd/display: Add null checker before passing variables
+    - media: uvcvideo: Ignore empty TS packets
+    - media: uvcvideo: Fix the bandwdith quirk on USB 3.x
+    - media: xc2028: avoid use-after-free in load_firmware_cb()
+    - ext4: fix uninitialized variable in ext4_inlinedir_to_tree
+    - jbd2: avoid memleak in jbd2_journal_write_metadata_buffer
+    - s390/sclp: Prevent release of buffer in I/O
+    - SUNRPC: Fix a race to wake a sync task
+    - profiling: remove profile=sleep support
+    - scsi: mpt3sas: Avoid IOMMU page faults on REPORT ZONES
+    - irqchip/meson-gpio: Convert meson_gpio_irq_controller::lock to
+      'raw_spinlock_t'
+    - irqchip/loongarch-cpu: Fix return value of lpic_gsi_to_irq()
+    - sched/cputime: Fix mul_u64_u64_div_u64() precision for cputime
+    - net: drop bad gso csum_start and offset in virtio_net_hdr
+    - arm64: Add Neoverse-V2 part
+    - arm64: barrier: Restore spec_bar() macro
+    - arm64: cputype: Add Cortex-X4 definitions
+    - arm64: cputype: Add Neoverse-V3 definitions
+    - arm64: errata: Add workaround for Arm errata 3194386 and 3312417
+    - arm64: cputype: Add Cortex-X3 definitions
+    - arm64: cputype: Add Cortex-A720 definitions
+    - arm64: cputype: Add Cortex-X925 definitions
+    - arm64: errata: Unify speculative SSBS errata logic
+    - [Config] Set ARM64_ERRATUM_3194386=y
+    - arm64: errata: Expand speculative SSBS workaround
+    - arm64: cputype: Add Cortex-X1C definitions
+    - arm64: cputype: Add Cortex-A725 definitions
+    - arm64: errata: Expand speculative SSBS workaround (again)
+    - i2c: smbus: Improve handling of stuck alerts
+    - ASoC: codecs: wcd938x-sdw: Correct Soundwire ports mask
+    - ASoC: codecs: wsa881x: Correct Soundwire ports mask
+    - ASoC: codecs: wsa883x: parse port-mapping information
+    - ASoC: codecs: wsa883x: Correct Soundwire ports mask
+    - ASoC: codecs: wsa884x: parse port-mapping information
+    - ASoC: codecs: wsa884x: Correct Soundwire ports mask
+    - ASoC: sti: add missing probe entry for player and reader
+    - spi: spidev: Add missing spi_device_id for bh2228fv
+    - ASoC: SOF: Remove libraries from topology lookups
+    - i2c: smbus: Send alert notifications to all devices if source not found
+    - bpf: kprobe: remove unused declaring of bpf_kprobe_override
+    - kprobes: Fix to check symbol prefixes correctly
+    - i2c: qcom-geni: Add missing clk_disable_unprepare in geni_i2c_runtime_resume
+    - i2c: qcom-geni: Add missing geni_icc_disable in geni_i2c_runtime_resume
+    - spi: spi-fsl-lpspi: Fix scldiv calculation
+    - ALSA: usb-audio: Re-add ScratchAmp quirk entries
+    - ASoC: meson: axg-fifo: fix irq scheduling issue with PREEMPT_RT
+    - cifs: cifs_inval_name_dfs_link_error: correct the check for fullpath
+    - module: warn about excessively long module waits
+    - module: make waiting for a concurrent module loader interruptible
+    - drm/i915/gem: Fix Virtual Memory mapping boundaries calculation
+    - drm/amd/display: Skip Recompute DSC Params if no Stream on Link
+    - drm/amdgpu: Forward soft recovery errors to userspace
+    - drm/i915/gem: Adjust vma offset for framebuffer mmap offset
+    - drm/client: fix null pointer dereference in drm_client_modeset_probe
+    - ALSA: line6: Fix racy access to midibuf
+    - ALSA: hda: Add HP MP9 G4 Retail System AMS to force connect list
+    - ALSA: hda/realtek: Add Framework Laptop 13 (Intel Core Ultra) to quirks
+    - ALSA: hda/hdmi: Yet more pin fix for HP EliteDesk 800 G4
+    - usb: vhci-hcd: Do not drop references before new references are gained
+    - USB: serial: debug: do not echo input by default
+    - usb: gadget: core: Check for unset descriptor
+    - usb: gadget: midi2: Fix the response for FB info with block 0xff
+    - usb: gadget: u_serial: Set start_delayed during suspend
+    - usb: gadget: u_audio: Check return codes from usb_ep_enable and
+      config_ep_by_speed.
+    - scsi: mpi3mr: Avoid IOMMU page faults on REPORT ZONES
+    - scsi: ufs: core: Do not set link to OFF state while waking up from
+      hibernation
+    - scsi: ufs: core: Fix hba->last_dme_cmd_tstamp timestamp updating logic
+    - tick/broadcast: Move per CPU pointer access into the atomic section
+    - vhost-vdpa: switch to use vmf_insert_pfn() in the fault handler
+    - ntp: Clamp maxerror and esterror to operating range
+    - clocksource: Scale the watchdog read retries automatically
+    - clocksource: Fix brown-bag boolean thinko in cs_watchdog_read()
+    - driver core: Fix uevent_show() vs driver detach race
+    - tracefs: Fix inode allocation
+    - tracefs: Use generic inode RCU for synchronizing freeing
+    - ntp: Safeguard against time_constant overflow
+    - timekeeping: Fix bogus clock_was_set() invocation in do_adjtimex()
+    - serial: core: check uartclk for zero to avoid divide by zero
+    - memcg: protect concurrent access to mem_cgroup_idr
+    - parisc: fix unaligned accesses in BPF
+    - parisc: fix a possible DMA corruption
+    - ASoC: amd: yc: Add quirk entry for OMEN by HP Gaming Laptop 16-n0xxx
+    - kcov: properly check for softirq context
+    - irqchip/xilinx: Fix shift out of bounds
+    - genirq/irqdesc: Honor caller provided affinity in alloc_desc()
+    - LoongArch: Enable general EFI poweroff method
+    - power: supply: qcom_battmgr: return EAGAIN when firmware service is not up
+    - power: supply: axp288_charger: Fix constant_charge_voltage writes
+    - power: supply: axp288_charger: Round constant_charge_voltage writes down
+    - tracing: Fix overflow in get_free_elt()
+    - padata: Fix possible divide-by-0 panic in padata_mt_helper()
+    - smb3: fix setting SecurityFlags when encryption is required
+    - eventfs: Don't return NULL in eventfs_create_dir()
+    - eventfs: Use SRCU for freeing eventfs_inodes
+    - selftests: mm: add s390 to ARCH check
+    - btrfs: avoid using fixed char array size for tree names
+    - x86/paravirt: Fix incorrect virt spinlock setting on bare metal
+    - x86/mtrr: Check if fixed MTRRs exist before saving them
+    - sched/smt: Introduce sched_smt_present_inc/dec() helper
+    - sched/smt: Fix unbalance sched_smt_present dec/inc
+    - sched/core: Introduce sched_set_rq_on/offline() helper
+    - sched/core: Fix unbalance set_rq_online/offline() in sched_cpu_deactivate()
+    - drm/bridge: analogix_dp: properly handle zero sized AUX transactions
+    - drm/dp_mst: Skip CSN if topology probing is not done yet
+    - drm/lima: Mark simple_ondemand governor as softdep
+    - drm/mgag200: Set DDC timeout in milliseconds
+    - drm/mgag200: Bind I2C lifetime to DRM device
+    - drm/radeon: Remove __counted_by from StateArray.states[]
+    - mptcp: fully established after ADD_ADDR echo on MPJ
+    - mptcp: pm: deny endp with signal + subflow + port
+    - block: use the right type for stub rq_integrity_vec()
+    - btrfs: fix corruption after buffer fault in during direct IO append write
+    - tools headers arm64: Sync arm64's cputype.h with the kernel sources
+    - mm/hugetlb: fix potential race in __update_and_free_hugetlb_folio()
+    - xfs: fix log recovery buffer allocation for the legacy h_size fixup
+    - mptcp: pm: reduce indentation blocks
+    - mptcp: pm: don't try to create sf if alloc failed
+    - mptcp: pm: do not ignore 'subflow' if 'signal' flag is also set
+    - selftests: mptcp: join: ability to invert ADD_ADDR check
+    - selftests: mptcp: join: test both signal & subflow
+    - Revert "selftests: mptcp: simult flows: mark 'unbalanced' tests as flaky"
+    - btrfs: fix double inode unlock for direct IO sync writes
+    - perf/x86/intel/cstate: Switch to new Intel CPU model defines
+    - perf/x86/intel/cstate: Add Arrowlake support
+    - perf/x86/intel/cstate: Add Lunarlake support
+    - perf/x86/intel/cstate: Add pkg C2 residency counter for Sierra Forest
+    - platform/x86: intel-vbtn: Protect ACPI notify handler against recursion
+    - perf/x86/amd: Use try_cmpxchg() in events/amd/{un,}core.c
+    - perf/x86/intel: Support the PEBS event mask
+    - perf/x86: Support counter mask
+    - perf/x86: Fix smp_processor_id()-in-preemptible warnings
+    - virtio-net: unbreak vq resizing when coalescing is not negotiated
+    - net: dsa: microchip: Fix Wake-on-LAN check to not return an error
+    - net: dsa: microchip: disable EEE for KSZ8567/KSZ9567/KSZ9896/KSZ9897.
+    - regmap: kunit: Use a KUnit action to call regmap_exit()
+    - regmap: kunit: Replace a kmalloc/kfree() pair with KUnit-managed alloc
+    - regmap: kunit: Fix memory leaks in gen_regmap() and gen_raw_regmap()
+    - debugobjects: Annotate racy debug variables
+    - nvme: apple: fix device reference counting
+    - cpufreq: amd-pstate: Allow users to write 'default' EPP string
+    - cpufreq: amd-pstate: auto-load pstate driver by default
+    - soc: qcom: icc-bwmon: Allow for interrupts to be shared across instances
+    - ACPI: resource: Skip IRQ override on Asus Vivobook Pro N6506MU
+    - ACPI: resource: Skip IRQ override on Asus Vivobook Pro N6506MJ
+    - thermal: intel: hfi: Give HFI instances package scope
+    - wifi: ath12k: fix race due to setting ATH12K_FLAG_EXT_IRQ_ENABLED too early
+    - wifi: rtlwifi: handle return value of usb init TX/RX
+    - wifi: rtw89: pci: fix RX tag race condition resulting in wrong RX length
+    - wifi: mac80211: fix NULL dereference at band check in starting tx ba session
+    - bpf: add missing check_func_arg_reg_off() to prevent out-of-bounds memory
+      accesses
+    - mlxsw: pci: Lock configuration space of upstream bridge during reset
+    - btrfs: do not BUG_ON() when freeing tree block after error
+    - btrfs: reduce nesting for extent processing at btrfs_lookup_extent_info()
+    - btrfs: fix data race when accessing the last_trans field of a root
+    - drm/xe/preempt_fence: enlarge the fence critical section
+    - drm/amd/display: Handle HPD_IRQ for internal link
+    - drm/amd/amdkfd: Fix a resource leak in svm_range_validate_and_map()
+    - drm/xe/xe_guc_submit: Fix exec queue stop race condition
+    - drm/amd/display: Add null checks for 'stream' and 'plane' before
+      dereferencing
+    - drm/amd/display: Wake DMCUB before sending a command for replay feature
+    - drm/amd/display: reduce ODM slice count to initial new dc state only when
+      needed
+    - of: Add cleanup.h based auto release via __free(device_node) markings
+    - media: i2c: ov5647: replacing of_node_put with __free(device_node)
+    - drm/amd/display: Fix null pointer deref in dcn20_resource.c
+    - ext4: sanity check for NULL pointer after ext4_force_shutdown
+    - mm, slub: do not call do_slab_free for kfence object
+    - ASoC: cs35l56: Revert support for dual-ownership of ASP registers
+    - drm/atomic: allow no-op FB_ID updates for async flips
+    - drm/amd/display: Replace dm_execute_dmub_cmd with
+      dc_wake_and_execute_dmub_cmd
+    - drm/xe/rtp: Fix off-by-one when processing rules
+    - drm/xe: Use dma_fence_chain_free in chain fence unused as a sync
+    - drm/xe/hwmon: Fix PL1 disable flow in xe_hwmon_power_max_write
+    - drm/xe: Move lrc snapshot capturing to xe_lrc.c
+    - drm/xe: Minor cleanup in LRC handling
+    - drm/test: fix the gem shmem test to map the sg table.
+    - usb: typec: pd: no opencoding of FIELD_GET
+    - usb: typec: fsa4480: Check if the chip is really there
+    - PM: runtime: Simplify pm_runtime_get_if_active() usage
+    - scsi: ufs: core: Fix deadlock during RTC update
+    - serial: sc16is7xx: fix invalid FIFO access with special register set
+    - tracing: Have format file honor EVENT_FILE_FL_FREED
+    - mm: list_lru: fix UAF for memory cgroup
+    - net/tcp: Disable TCP-AO static key after RCU grace period
+    - Revert "drm/amd/display: Handle HPD_IRQ for internal link"
+    - idpf: fix memleak in vport interrupt configuration
+    - drm/amd/display: Add null check in resource_log_pipe_topology_update
+    - Upstream stable to v6.6.46, v6.10.5
+
+  * Noble update: upstream stable patchset 2024-10-02 (LP: #2083488)
+    - sysctl: allow change system v ipc sysctls inside ipc namespace
+    - sysctl: allow to change limits for posix messages queues
+    - sysctl: treewide: drop unused argument ctl_table_root::set_ownership(table)
+    - ext4: factor out a common helper to query extent map
+    - ext4: check the extent status again before inserting delalloc block
+    - leds: trigger: Store brightness set by led_trigger_event()
+    - leds: trigger: Call synchronize_rcu() before calling trig->activate()
+    - KVM: VMX: Move posted interrupt descriptor out of VMX code
+    - fbdev/vesafb: Replace references to global screen_info by local pointer
+    - video: Add helpers for decoding screen_info
+    - [Config] Update CONFIG_SCREEN_INFO
+    - video: Provide screen_info_get_pci_dev() to find screen_info's PCI device
+    - firmware/sysfb: Update screen_info for relocated EFI framebuffers
+    - mm: page_alloc: control latency caused by zone PCP draining
+    - mm/page_alloc: fix pcp->count race between drain_pages_zone() vs
+      __rmqueue_pcplist()
+    - f2fs: fix to avoid use SSR allocate when do defragment
+    - f2fs: assign CURSEG_ALL_DATA_ATGC if blkaddr is valid
+    - dmaengine: fsl-edma: add address for channel mux register in fsl_edma_chan
+    - dmaengine: fsl-edma: add i.MX8ULP edma support
+    - perf: imx_perf: fix counter start and config sequence
+    - MIPS: Loongson64: DTS: Fix PCIe port nodes for ls7a
+    - MIPS: dts: loongson: Fix liointc IRQ polarity
+    - MIPS: dts: loongson: Fix ls2k1000-rtc interrupt
+    - ARM: 9406/1: Fix callchain_trace() return value
+    - HID: amd_sfh: Move sensor discovery before HID device initialization
+    - perf tool: fix dereferencing NULL al->maps
+    - drm/nouveau: prime: fix refcount underflow
+    - drm/vmwgfx: Fix overlay when using Screen Targets
+    - drm/vmwgfx: Trigger a modeset when the screen moves
+    - sched: act_ct: take care of padding in struct zones_ht_key
+    - wifi: cfg80211: fix reporting failed MLO links status with
+      cfg80211_connect_done
+    - net: phy: realtek: add support for RTL8366S Gigabit PHY
+    - ALSA: hda: conexant: Fix headset auto detect fail in the polling mode
+    - Bluetooth: btintel: Fail setup on error
+    - Bluetooth: hci_sync: Fix suspending with wrong filter policy
+    - tcp: annotate data-races around tp->window_clamp
+    - tcp: Adjust clamping window for applications specifying SO_RCVBUF
+    - net: axienet: start napi before enabling Rx/Tx
+    - rtnetlink: Don't ignore IFLA_TARGET_NETNSID when ifname is specified in
+      rtnl_dellink().
+    - i915/perf: Remove code to update PWR_CLK_STATE for gen12
+    - ice: respect netif readiness in AF_XDP ZC related ndo's
+    - ice: don't busy wait for Rx queue disable in ice_qp_dis()
+    - ice: replace synchronize_rcu with synchronize_net
+    - ice: add missing WRITE_ONCE when clearing ice_rx_ring::xdp_prog
+    - drm/i915/hdcp: Fix HDCP2_STREAM_STATUS macro
+    - net: mvpp2: Don't re-use loop iterator
+    - net: phy: micrel: Fix the KSZ9131 MDI-X status issue
+    - ALSA: hda: Conditionally use snooping for AMD HDMI
+    - netfilter: iptables: Fix null-ptr-deref in iptable_nat_table_init().
+    - netfilter: iptables: Fix potential null-ptr-deref in
+      ip6table_nat_table_init().
+    - net/mlx5: Always drain health in shutdown callback
+    - net/mlx5: Fix error handling in irq_pool_request_irq
+    - net/mlx5: Lag, don't use the hardcoded value of the first port
+    - net/mlx5: Fix missing lock on sync reset reload
+    - net/mlx5e: Require mlx5 tc classifier action support for IPsec prio
+      capability
+    - net/mlx5e: Fix CT entry update leaks of modify header context
+    - net/mlx5e: Add a check for the return value from mlx5_port_set_eth_ptys
+    - igc: Fix double reset adapter triggered from a single taprio cmd
+    - ipv6: fix ndisc_is_useropt() handling for PIO
+    - perf: riscv: Fix selecting counters in legacy mode
+    - riscv/mm: Add handling for VM_FAULT_SIGSEGV in mm_fault_error()
+    - riscv: Fix linear mapping checks for non-contiguous memory regions
+    - arm64: jump_label: Ensure patched jump_labels are visible to all CPUs
+    - rust: SHADOW_CALL_STACK is incompatible with Rust
+    - platform/chrome: cros_ec_proto: Lock device when updating MKBP version
+    - HID: wacom: Modify pen IDs
+    - btrfs: zoned: fix zone_unusable accounting on making block group read-write
+      again
+    - btrfs: do not subtract delalloc from avail bytes
+    - protect the fetch of ->fd[fd] in do_dup2() from mispredictions
+    - mptcp: sched: check both directions for backup
+    - ALSA: usb-audio: Correct surround channels in UAC1 channel map
+    - ALSA: hda/realtek: Add quirk for Acer Aspire E5-574G
+    - ALSA: seq: ump: Optimize conversions from SysEx to UMP
+    - Revert "ALSA: firewire-lib: obsolete workqueue for period update"
+    - Revert "ALSA: firewire-lib: operate for period elapse event in process
+      context"
+    - drm/vmwgfx: Fix a deadlock in dma buf fence polling
+    - drm/virtio: Fix type of dma-fence context variable
+    - drm/i915: Fix possible int overflow in skl_ddi_calculate_wrpll()
+    - net: usb: sr9700: fix uninitialized variable use in sr_mdio_read
+    - r8169: don't increment tx_dropped in case of NETDEV_TX_BUSY
+    - mptcp: fix user-space PM announced address accounting
+    - mptcp: distinguish rcv vs sent backup flag in requests
+    - mptcp: fix NL PM announced address accounting
+    - mptcp: mib: count MPJ with backup flag
+    - mptcp: fix bad RCVPRUNED mib accounting
+    - mptcp: pm: only set request_bkup flag when sending MP_PRIO
+    - mptcp: fix duplicate data handling
+    - selftests: mptcp: always close input's FD if opened
+    - selftests: mptcp: join: validate backup in MPJ
+    - selftests: mptcp: join: check backup support in signal endp
+    - mm/huge_memory: mark racy access onhuge_anon_orders_always
+    - mm: fix khugepaged activation policy
+    - x86/cpu/vfm: Add/initialize x86_vfm field to struct cpuinfo_x86
+    - perf/x86/intel: Switch to new Intel CPU model defines
+    - perf/x86/intel: Add a distinct name for Granite Rapids
+    - drm/gpuvm: fix missing dependency to DRM_EXEC
+    - netlink: specs: correct the spec of ethtool
+    - ethtool: rss: echo the context number back
+    - wifi: cfg80211: correct S1G beacon length calculation
+    - ethtool: fix setting key and resetting indir at once
+    - ice: modify error handling when setting XSK pool in ndo_bpf
+    - ice: toggle netif_carrier when setting up XSK pool
+    - ice: improve updating ice_{t,r}x_ring::xsk_pool
+    - ice: xsk: fix txq interrupt mapping
+    - drm/atomic: Allow userspace to use explicit sync with atomic async flips
+    - drm/atomic: Allow userspace to use damage clips with async flips
+    - riscv/purgatory: align riscv_kernel_entry
+    - perf arch events: Fix duplicate RISC-V SBI firmware event name
+    - RISC-V: Enable the IPI before workqueue_online_cpu()
+    - ceph: force sending a cap update msg back to MDS for revoke op
+    - drm/vmwgfx: Remove unused code
+    - drm/vmwgfx: Fix handling of dumb buffers
+    - drm/v3d: Prevent out of bounds access in performance query extensions
+    - drm/v3d: Fix potential memory leak in the timestamp extension
+    - drm/v3d: Fix potential memory leak in the performance extension
+    - drm/v3d: Validate passed in drm syncobj handles in the timestamp extension
+    - drm/v3d: Validate passed in drm syncobj handles in the performance extension
+    - nouveau: set placement to original placement on uvmm validate.
+    - wifi: ath12k: fix soft lockup on suspend
+    - mptcp: pm: fix backup support in signal endpoints
+    - selftests: mptcp: fix error path
+    - Upstream stable to v6.6.45, v6.10.4
+
+  * [SRU] Fix AST DP output after resume (LP: #2083022) // Noble update:
+    upstream stable patchset 2024-10-02 (LP: #2083488)
+    - drm/ast: astdp: Wake up during connector status detection
+    - drm/ast: Fix black screen after resume
+
+  * [SRU]Fail to locate the LED of NVME disk behind  Intel VMD (LP: #2077287) //
+    Noble update: upstream stable patchset 2024-10-02 (LP: #2083488)
+    - PCI: pciehp: Retain Power Indicator bits for userspace indicators
+
+  * Noble update: upstream stable patchset 2024-09-30 (LP: #2083196)
+    - powerpc/configs: Update defconfig with now user-visible CONFIG_FSL_IFC
+    - spi: spi-microchip-core: Fix the number of chip selects supported
+    - spi: atmel-quadspi: Add missing check for clk_prepare
+    - EDAC, i10nm: make skx_common.o a separate module
+    - rcu/tasks: Fix stale task snaphot for Tasks Trace
+    - platform/chrome: cros_ec_debugfs: fix wrong EC message version
+    - ubd: refactor the interrupt handler
+    - ubd: untagle discard vs write zeroes not support handling
+    - block: initialize integrity buffer to zero before writing it to media
+    - x86/kconfig: Add as-instr64 macro to properly evaluate AS_WRUSS
+    - hfsplus: fix to avoid false alarm of circular locking
+    - x86/of: Return consistent error type from x86_of_pci_irq_enable()
+    - x86/pci/intel_mid_pci: Fix PCIBIOS_* return code handling
+    - x86/pci/xen: Fix PCIBIOS_* return code handling
+    - x86/platform/iosf_mbi: Convert PCIBIOS_* return codes to errnos
+    - cgroup/cpuset: Prevent UAF in proc_cpuset_show()
+    - hwmon: (adt7475) Fix default duty on fan is disabled
+    - block: Call .limit_depth() after .hctx has been set
+    - block/mq-deadline: Fix the tag reservation code
+    - md: Don't wait for MD_RECOVERY_NEEDED for HOT_REMOVE_DISK ioctl
+    - pwm: stm32: Always do lazy disabling
+    - nvmet-auth: fix nvmet_auth hash error handling
+    - drm/meson: fix canvas release in bind function
+    - pwm: atmel-tcb: Fix race condition and convert to guards
+    - hwmon: (max6697) Fix underflow when writing limit attributes
+    - hwmon: (max6697) Fix swapped temp{1,8} critical alarms
+    - arm64: dts: qcom: sc8180x: Correct PCIe slave ports
+    - arm64: dts: qcom: sc8180x: add power-domain to UFS PHY
+    - arm64: dts: qcom: sdm845: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm6115: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm6350: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm8250: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm8350: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm8450: add power-domain to UFS PHY
+    - arm64: dts: qcom: msm8996-xiaomi-common: drop excton from the USB PHY
+    - arm64: dts: qcom: sdm850-lenovo-yoga-c630: fix IPA firmware path
+    - arm64: dts: qcom: msm8998: enable adreno_smmu by default
+    - soc: qcom: pmic_glink: Handle the return value of pmic_glink_init
+    - soc: qcom: rpmh-rsc: Ensure irqs aren't disabled by rpmh_rsc_send_data()
+      callers
+    - arm64: dts: rockchip: Add sdmmc related properties on rk3308-rock-pi-s
+    - arm64: dts: rockchip: Add pinctrl for UART0 to rk3308-rock-pi-s
+    - arm64: dts: rockchip: Add mdio and ethernet-phy nodes to rk3308-rock-pi-s
+    - arm64: dts: rockchip: Update WIFi/BT related nodes on rk3308-rock-pi-s
+    - arm64: dts: qcom: msm8996: specify UFS core_clk frequencies
+    - arm64: dts: qcom: sa8775p: mark ethernet devices as DMA-coherent
+    - soc: xilinx: rename cpu_number1 to dummy_cpu_number
+    - ARM: dts: sunxi: remove duplicated entries in makefile
+    - ARM: dts: stm32: Add arm,no-tick-in-suspend to STM32MP15xx STGEN timer
+    - arm64: dts: qcom: qrb4210-rb2: make L9A always-on
+    - cpufreq: ti-cpufreq: Handle deferred probe with dev_err_probe()
+    - OPP: ti: Fix ti_opp_supply_probe wrong return values
+    - memory: fsl_ifc: Make FSL_IFC config visible and selectable
+    - arm64: dts: ti: k3-am62x: Drop McASP AFIFOs
+    - arm64: dts: ti: k3-am625-beagleplay: Drop McASP AFIFOs
+    - arm64: dts: ti: k3-am62-verdin: Drop McASP AFIFOs
+    - arm64: dts: qcom: qdu1000: Add secure qfprom node
+    - soc: qcom: icc-bwmon: Fix refcount imbalance seen during bwmon_remove
+    - soc: qcom: pdr: protect locator_addr with the main mutex
+    - soc: qcom: pdr: fix parsing of domains lists
+    - arm64: dts: rockchip: Increase VOP clk rate on RK3328
+    - arm64: dts: amlogic: sm1: fix spdif compatibles
+    - ARM: dts: imx6qdl-kontron-samx6i: fix phy-mode
+    - ARM: dts: imx6qdl-kontron-samx6i: fix PHY reset
+    - ARM: dts: imx6qdl-kontron-samx6i: fix board reset
+    - ARM: dts: imx6qdl-kontron-samx6i: fix SPI0 chip selects
+    - ARM: dts: imx6qdl-kontron-samx6i: fix PCIe reset polarity
+    - arm64: dts: mediatek: mt8195: Fix GPU thermal zone name for SVS
+    - arm64: dts: mediatek: mt8183-kukui: Drop bogus output-enable property
+    - arm64: dts: mediatek: mt8192-asurada: Add off-on-delay-us for
+      pp3300_mipibrdg
+    - arm64: dts: mediatek: mt7622: fix "emmc" pinctrl mux
+    - arm64: dts: mediatek: mt8183-kukui: Fix the value of `dlg,jack-det-rate`
+      mismatch
+    - arm64: dts: mediatek: mt8183-kukui-jacuzzi: Add ports node for anx7625
+    - arm64: dts: amlogic: gx: correct hdmi clocks
+    - arm64: dts: amlogic: add power domain to hdmitx
+    - arm64: dts: amlogic: setup hdmi system clock
+    - arm64: dts: rockchip: Drop invalid mic-in-differential on rk3568-rock-3a
+    - arm64: dts: rockchip: Fix mic-in-differential usage on rk3566-roc-pc
+    - arm64: dts: rockchip: Fix mic-in-differential usage on rk3568-evb1-v10
+    - arm64: dts: renesas: r8a779a0: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r8a779f0: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r8a779g0: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r9a07g043u: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r9a07g044: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r9a07g054: Add missing hypervisor virtual timer IRQ
+    - m68k: atari: Fix TT bootup freeze / unexpected (SCU) interrupt messages
+    - arm64: dts: imx8mp: Fix pgc_mlmix location
+    - arm64: dts: imx8mp: add HDMI power-domains
+    - arm64: dts: imx8mp: Fix pgc vpu locations
+    - x86/xen: Convert comma to semicolon
+    - arm64: dts: rockchip: Add missing power-domains for rk356x vop_mmu
+    - arm64: dts: rockchip: fix regulator name for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: fix usb regulator for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: fix pmu_io supply for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: remove unused usb2 nodes for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: disable display subsystem for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: fixes PHY reset for Lunzn Fastrhino R68S
+    - arm64: dts: qcom: sm6350: Add missing qcom,non-secure-domain property
+    - cpufreq/amd-pstate: Fix the scaling_max_freq setting on shared memory CPPC
+      systems
+    - m68k: cmpxchg: Fix return value for default case in __arch_xchg()
+    - ARM: spitz: fix GPIO assignment for backlight
+    - vmlinux.lds.h: catch .bss..L* sections into BSS")
+    - firmware: turris-mox-rwtm: Do not complete if there are no waiters
+    - firmware: turris-mox-rwtm: Fix checking return value of
+      wait_for_completion_timeout()
+    - firmware: turris-mox-rwtm: Initialize completion before mailbox
+    - wifi: brcmsmac: LCN PHY code is used for BCM4313 2G-only device
+    - wifi: ath12k: Correct 6 GHz frequency value in rx status
+    - wifi: ath12k: Fix tx completion ring (WBM2SW) setup failure
+    - bpftool: Un-const bpf_func_info to fix it for llvm 17 and newer
+    - selftests/bpf: Fix prog numbers in test_sockmap
+    - net: esp: cleanup esp_output_tail_tcp() in case of unsupported ESPINTCP
+    - wifi: ath12k: change DMA direction while mapping reinjected packets
+    - wifi: ath12k: fix invalid memory access while processing fragmented packets
+    - wifi: ath12k: fix firmware crash during reo reinject
+    - wifi: ath11k: fix wrong definition of CE ring's base address
+    - wifi: ath12k: fix wrong definition of CE ring's base address
+    - tcp: add tcp_done_with_error() helper
+    - tcp: fix race in tcp_write_err()
+    - tcp: fix races in tcp_v[46]_err()
+    - net/smc: set rmb's SG_MAX_SINGLE_ALLOC limitation only when
+      CONFIG_ARCH_NO_SG_CHAIN is defined
+    - selftests/bpf: Check length of recv in test_sockmap
+    - udf: Fix lock ordering in udf_evict_inode()
+    - lib: objagg: Fix general protection fault
+    - mlxsw: spectrum_acl_erp: Fix object nesting warning
+    - mlxsw: spectrum_acl: Fix ACL scale regression and firmware errors
+    - perf/x86: Serialize set_attr_rdpmc()
+    - jump_label: Fix concurrency issues in static_key_slow_dec()
+    - wifi: ath11k: fix wrong handling of CCMP256 and GCMP ciphers
+    - wifi: cfg80211: fix typo in cfg80211_calculate_bitrate_he()
+    - wifi: cfg80211: handle 2x996 RU allocation in
+      cfg80211_calculate_bitrate_he()
+    - udf: Fix bogus checksum computation in udf_rename()
+    - net: fec: Refactor: #define magic constants
+    - net: fec: Fix FEC_ECR_EN1588 being cleared on link-down
+    - libbpf: Checking the btf_type kind when fixing variable offsets
+    - xfrm: Fix unregister netdevice hang on hardware offload.
+    - ipvs: Avoid unnecessary calls to skb_is_gso_sctp
+    - netfilter: nf_tables: rise cap on SELinux secmark context
+    - wifi: rtw89: 8852b: fix definition of KIP register number
+    - wifi: rtl8xxxu: 8188f: Limit TX power index
+    - xfrm: Export symbol xfrm_dev_state_delete.
+    - bpftool: Mount bpffs when pinmaps path not under the bpffs
+    - perf/x86/intel/pt: Fix pt_topa_entry_for_page() address calculation
+    - perf: Fix perf_aux_size() for greater-than 32-bit size
+    - perf: Prevent passing zero nr_pages to rb_alloc_aux()
+    - perf: Fix default aux_watermark calculation
+    - perf/x86/intel/cstate: Fix Alderlake/Raptorlake/Meteorlake
+    - wifi: rtw89: Fix array index mistake in rtw89_sta_info_get_iter()
+    - xfrm: fix netdev reference count imbalance
+    - xfrm: call xfrm_dev_policy_delete when kill policy
+    - wifi: virt_wifi: avoid reporting connection success with wrong SSID
+    - gss_krb5: Fix the error handling path for crypto_sync_skcipher_setkey
+    - wifi: virt_wifi: don't use strlen() in const context
+    - locking/rwsem: Add __always_inline annotation to __down_write_common() and
+      inlined callers
+    - selftests/bpf: Close fd in error path in drop_on_reuseport
+    - selftests/bpf: Null checks for links in bpf_tcp_ca
+    - selftests/bpf: Close obj in error path in xdp_adjust_tail
+    - selftests/resctrl: Convert perror() to ksft_perror() or ksft_print_msg()
+    - selftests/resctrl: Fix closing IMC fds on error and open-code R+W instead of
+      loops
+    - bpf: annotate BTF show functions with __printf
+    - bna: adjust 'name' buf size of bna_tcb and bna_ccb structures
+    - bpf: Eliminate remaining "make W=1" warnings in kernel/bpf/btf.o
+    - bpf: Fix null pointer dereference in resolve_prog_type() for
+      BPF_PROG_TYPE_EXT
+    - selftests: forwarding: devlink_lib: Wait for udev events after reloading
+    - Bluetooth: hci_bcm4377: Use correct unit for timeouts
+    - Bluetooth: btintel: Refactor btintel_set_ppag()
+    - Bluetooth: btnxpuart: Add handling for boot-signature timeout errors
+    - xdp: fix invalid wait context of page_pool_destroy()
+    - net: bridge: mst: Check vlan state for egress decision
+    - drm/rockchip: vop2: Fix the port mux of VP2
+    - drm/arm/komeda: Fix komeda probe failing if there are no links in the
+      secondary pipeline
+    - drm/amdkfd: Fix CU Masking for GFX 9.4.3
+    - drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq()
+    - drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_generic_write_seq()
+    - drm/amd/pm: Fix aldebaran pcie speed reporting
+    - drm/amdgpu: Fix memory range calculation
+    - drm/amdgpu: Check if NBIO funcs are NULL in amdgpu_device_baco_exit
+    - drm/amdgpu: Remove GC HW IP 9.3.0 from noretry=1
+    - drm/panel: himax-hx8394: Handle errors from mipi_dsi_dcs_set_display_on()
+      better
+    - drm/panel: boe-tv101wum-nl6: If prepare fails, disable GPIO before
+      regulators
+    - drm/panel: boe-tv101wum-nl6: Check for errors on the NOP in prepare()
+    - drm/bridge: Fixed a DP link training bug
+    - drm/bridge: it6505: fix hibernate to resume no display issue
+    - media: pci: ivtv: Add check for DMA map result
+    - media: imon: Fix race getting ictx->lock
+    - media: i2c: Fix imx412 exposure control
+    - media: v4l: async: Fix NULL pointer dereference in adding ancillary links
+    - s390/mm: Convert make_page_secure to use a folio
+    - s390/mm: Convert gmap_make_secure to use a folio
+    - s390/uv: Don't call folio_wait_writeback() without a folio reference
+    - media: mediatek: vcodec: Handle invalid decoder vsi
+    - x86/shstk: Make return uprobe work with shadow stack
+    - ipmi: ssif_bmc: prevent integer overflow on 32bit systems
+    - saa7134: Unchecked i2c_transfer function result fixed
+    - media: i2c: imx219: fix msr access command sequence
+    - media: uvcvideo: Disable autosuspend for Insta360 Link
+    - media: uvcvideo: Quirk for invalid dev_sof in Logitech C922
+    - media: uvcvideo: Add quirk for invalid dev_sof in Logitech C920
+    - media: uvcvideo: Override default flags
+    - drm: zynqmp_dpsub: Fix an error handling path in zynqmp_dpsub_probe()
+    - drm: zynqmp_kms: Fix AUX bus not getting unregistered
+    - media: rcar-vin: Fix YUYV8_1X16 handling for CSI-2
+    - media: rcar-csi2: Disable runtime_pm in probe error
+    - media: rcar-csi2: Cleanup subdevice in remove()
+    - media: renesas: vsp1: Fix _irqsave and _irq mix
+    - media: renesas: vsp1: Store RPF partition configuration per RPF instance
+    - drm/mediatek: Add missing plane settings when async update
+    - drm/mediatek: Use 8-bit alpha in ETHDR
+    - drm/mediatek: Fix XRGB setting error in OVL
+    - drm/mediatek: Fix XRGB setting error in Mixer
+    - drm/mediatek: Fix destination alpha error in OVL
+    - drm/mediatek: Turn off the layers with zero width or height
+    - drm/mediatek: Add OVL compatible name for MT8195
+    - media: imx-jpeg: Drop initial source change event if capture has been setup
+    - leds: trigger: Unregister sysfs attributes before calling deactivate()
+    - drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC
+    - drm/msm/dpu: drop validity checks for clear_pending_flush() ctl op
+    - perf test: Make test_arm_callgraph_fp.sh more robust
+    - perf pmus: Fixes always false when compare duplicates aliases
+    - perf report: Fix condition in sort__sym_cmp()
+    - drm/etnaviv: fix DMA direction handling for cached RW buffers
+    - drm/qxl: Add check for drm_cvt_mode
+    - Revert "leds: led-core: Fix refcount leak in of_led_get()"
+    - drm/mediatek: Remove less-than-zero comparison of an unsigned value
+    - ext4: fix infinite loop when replaying fast_commit
+    - drm/mediatek/dp: switch to ->edid_read callback
+    - drm/mediatek/dp: Fix spurious kfree()
+    - media: venus: flush all buffers in output plane streamoff
+    - perf intel-pt: Fix aux_watermark calculation for 64-bit size
+    - perf intel-pt: Fix exclude_guest setting
+    - mfd: rsmu: Split core code into separate module
+    - mfd: omap-usb-tll: Use struct_size to allocate tll
+    - xprtrdma: Fix rpcrdma_reqs_reset()
+    - SUNRPC: avoid soft lockup when transmitting UDP to reachable server.
+    - NFSv4.1 another fix for EXCHGID4_FLAG_USE_PNFS_DS for DS server
+    - ext4: don't track ranges in fast_commit if inode has inlined data
+    - ext4: avoid writing unitialized memory to disk in EA inodes
+    - leds: flash: leds-qcom-flash: Test the correct variable in init
+    - sparc64: Fix incorrect function signature and add prototype for
+      prom_cif_init
+    - SUNRPC: Fixup gss_status tracepoint error output
+    - iio: Fix the sorting functionality in iio_gts_build_avail_time_table
+    - PCI: Fix resource double counting on remove & rescan
+    - PCI: keystone: Relocate ks_pcie_set/clear_dbi_mode()
+    - PCI: keystone: Don't enable BAR 0 for AM654x
+    - PCI: keystone: Fix NULL pointer dereference in case of DT error in
+      ks_pcie_setup_rc_app_regs()
+    - PCI: rcar: Demote WARN() to dev_warn_ratelimited() in rcar_pcie_wakeup()
+    - scsi: ufs: mcq: Fix missing argument 'hba' in MCQ_OPR_OFFSET_n
+    - clk: qcom: gcc-sc7280: Update force mem core bit for UFS ICE clock
+    - clk: qcom: camcc-sc7280: Add parent dependency to all camera GDSCs
+    - iio: frequency: adrf6780: rm clk provider include
+    - coresight: Fix ref leak when of_coresight_parse_endpoint() fails
+    - RDMA/mlx5: Set mkeys for dmabuf at PAGE_SIZE
+    - ASoc: tas2781: Enable RCA-based playback without DSP firmware download
+    - ASoC: cs35l56: Accept values greater than 0 as IRQ numbers
+    - usb: typec-mux: nb7vpq904m: unregister typec switch on probe error and
+      remove
+    - RDMA/cache: Release GID table even if leak is detected
+    - clk: qcom: gpucc-sm8350: Park RCG's clk source at XO during disable
+    - clk: qcom: gcc-sa8775p: Update the GDSC wait_val fields and flags
+    - clk: qcom: gpucc-sa8775p: Remove the CLK_IS_CRITICAL and ALWAYS_ON flags
+    - clk: qcom: gpucc-sa8775p: Park RCG's clk source at XO during disable
+    - clk: qcom: gpucc-sa8775p: Update wait_val fields for GPU GDSC's
+    - interconnect: qcom: qcm2290: Fix mas_snoc_bimc RPM master ID
+    - Input: qt1050 - handle CHIP_ID reading error
+    - RDMA/mlx4: Fix truncated output warning in mad.c
+    - RDMA/mlx4: Fix truncated output warning in alias_GUID.c
+    - RDMA/mlx5: Use sq timestamp as QP timestamp when RoCE is disabled
+    - RDMA/rxe: Don't set BTH_ACK_MASK for UC or UD QPs
+    - ASoC: qcom: Adjust issues in case of DT error in
+      asoc_qcom_lpass_cpu_platform_probe()
+    - scsi: lpfc: Fix a possible null pointer dereference
+    - hwrng: core - Fix wrong quality calculation at hw rng registration
+    - powerpc/prom: Add CPU info to hardware description string later
+    - ASoC: max98088: Check for clk_prepare_enable() error
+    - mtd: make mtd_test.c a separate module
+    - RDMA/device: Return error earlier if port in not valid
+    - Input: elan_i2c - do not leave interrupt disabled on suspend failure
+    - ASoC: amd: Adjust error handling in case of absent codec device
+    - PCI: endpoint: Clean up error handling in vpci_scan_bus()
+    - PCI: endpoint: Fix error handling in epf_ntb_epc_cleanup()
+    - vhost/vsock: always initialize seqpacket_allow
+    - net: missing check virtio
+    - nvmem: rockchip-otp: set add_legacy_fixed_of_cells config option
+    - crypto: qat - extend scope of lock in adf_cfg_add_key_value_param()
+    - clk: qcom: kpss-xcc: Return of_clk_add_hw_provider to transfer the error
+    - clk: qcom: Park shared RCGs upon registration
+    - clk: en7523: fix rate divider for slic and spi clocks
+    - MIPS: Octeron: remove source file executable bit
+    - PCI: qcom-ep: Disable resources unconditionally during PERST# assert
+    - PCI: dwc: Fix index 0 incorrectly being interpreted as a free ATU slot
+    - powerpc/xmon: Fix disassembly CPU feature checks
+    - macintosh/therm_windtunnel: fix module unload.
+    - RDMA/hns: Check atomic wr length
+    - RDMA/hns: Fix unmatch exception handling when init eq table fails
+    - RDMA/hns: Fix missing pagesize and alignment check in FRMR
+    - RDMA/hns: Fix shift-out-bounds when max_inline_data is 0
+    - RDMA/hns: Fix undifined behavior caused by invalid max_sge
+    - RDMA/hns: Fix insufficient extend DB for VFs.
+    - iommu/vt-d: Fix identity map bounds in si_domain_init()
+    - RDMA/core: Remove NULL check before dev_{put, hold}
+    - RDMA: Fix netdev tracker in ib_device_set_netdev
+    - bnxt_re: Fix imm_data endianness
+    - netfilter: ctnetlink: use helper function to calculate expect ID
+    - netfilter: nf_set_pipapo: fix initial map fill
+    - ipvs: properly dereference pe in ip_vs_add_service
+    - gve: Fix XDP TX completion handling when counters overflow
+    - net: flow_dissector: use DEBUG_NET_WARN_ON_ONCE
+    - ipv4: Fix incorrect TOS in route get reply
+    - ipv4: Fix incorrect TOS in fibmatch route get reply
+    - net: dsa: mv88e6xxx: Limit chip-wide frame size config to CPU ports
+    - net: dsa: b53: Limit chip-wide jumbo frame config to CPU ports
+    - fs/ntfs3: Merge synonym COMPRESSION_UNIT and NTFS_LZNT_CUNIT
+    - fs/ntfs3: Fix transform resident to nonresident for compressed files
+    - fs/ntfs3: Deny getting attr data block in compressed frame
+    - fs/ntfs3: Missed NI_FLAG_UPDATE_PARENT setting
+    - fs/ntfs3: Fix getting file type
+    - fs/ntfs3: Add missing .dirty_folio in address_space_operations
+    - pinctrl: rockchip: update rk3308 iomux routes
+    - pinctrl: core: fix possible memory leak when pinctrl_enable() fails
+    - pinctrl: single: fix possible memory leak when pinctrl_enable() fails
+    - pinctrl: ti: ti-iodelay: fix possible memory leak when pinctrl_enable()
+      fails
+    - pinctrl: freescale: mxs: Fix refcount of child
+    - fs/ntfs3: Replace inode_trylock with inode_lock
+    - fs/ntfs3: Correct undo if ntfs_create_inode failed
+    - fs/ntfs3: Drop stray '\' (backslash) in formatting string
+    - fs/ntfs3: Fix field-spanning write in INDEX_HDR
+    - pinctrl: renesas: r8a779g0: Fix CANFD5 suffix
+    - pinctrl: renesas: r8a779g0: Fix FXR_TXEN[AB] suffixes
+    - pinctrl: renesas: r8a779g0: Fix (H)SCIF1 suffixes
+    - pinctrl: renesas: r8a779g0: Fix (H)SCIF3 suffixes
+    - pinctrl: renesas: r8a779g0: Fix IRQ suffixes
+    - pinctrl: renesas: r8a779g0: FIX PWM suffixes
+    - pinctrl: renesas: r8a779g0: Fix TCLK suffixes
+    - pinctrl: renesas: r8a779g0: Fix TPU suffixes
+    - fs/proc/task_mmu: indicate PM_FILE for PMD-mapped file THP
+    - fs/proc/task_mmu.c: add_to_pagemap: remove useless parameter addr
+    - fs/proc/task_mmu: don't indicate PM_MMAP_EXCLUSIVE without PM_PRESENT
+    - fs/proc/task_mmu: properly detect PM_MMAP_EXCLUSIVE per page of PMD-mapped
+      THPs
+    - nilfs2: avoid undefined behavior in nilfs_cnt32_ge macro
+    - rtc: interface: Add RTC offset to alarm after fix-up
+    - fs/ntfs3: Fix the format of the "nocase" mount option
+    - fs/ntfs3: Missed error return
+    - fs/ntfs3: Keep runs for $MFT::$ATTR_DATA and $MFT::$ATTR_BITMAP
+    - powerpc/8xx: fix size given to set_huge_pte_at()
+    - s390/dasd: fix error checks in dasd_copy_pair_store()
+    - sbitmap: use READ_ONCE to access map->word
+    - sbitmap: fix io hung due to race on sbitmap_word::cleared
+    - LoongArch: Check TIF_LOAD_WATCH to enable user space watchpoint
+    - landlock: Don't lose track of restrictions on cred_transfer
+    - hugetlb: force allocating surplus hugepages on mempolicy allowed nodes
+    - mm/hugetlb: fix possible recursive locking detected warning
+    - mm/mglru: fix div-by-zero in vmpressure_calc_level()
+    - mm: mmap_lock: replace get_memcg_path_buf() with on-stack buffer
+    - mm/mglru: fix overshooting shrinker memory
+    - x86/efistub: Avoid returning EFI_SUCCESS on error
+    - x86/efistub: Revert to heap allocated boot_params for PE entrypoint
+    - exfat: fix potential deadlock on __exfat_get_dentry_set
+    - dt-bindings: thermal: correct thermal zone node name limit
+    - tick/broadcast: Make takeover of broadcast hrtimer reliable
+    - net: netconsole: Disable target before netpoll cleanup
+    - af_packet: Handle outgoing VLAN packets without hardware offloading
+    - btrfs: fix extent map use-after-free when adding pages to compressed bio
+    - kernel: rerun task_work while freezing in get_signal()
+    - ipv4: fix source address selection with route leak
+    - ipv6: take care of scope when choosing the src addr
+    - NFSD: Support write delegations in LAYOUTGET
+    - sched/fair: set_load_weight() must also call reweight_task() for SCHED_IDLE
+      tasks
+    - fuse: verify {g,u}id mount options correctly
+    - ata: libata-scsi: Fix offsets for the fixed format sense data
+    - char: tpm: Fix possible memory leak in tpm_bios_measurements_open()
+    - media: venus: fix use after free in vdec_close
+    - ata: libata-scsi: Do not overwrite valid sense data when CK_COND=1
+    - hfs: fix to initialize fields of hfs_inode_info after hfs_alloc_inode()
+    - ext2: Verify bitmap and itable block numbers before using them
+    - io_uring/io-wq: limit retrying worker initialisation
+    - drm/gma500: fix null pointer dereference in cdv_intel_lvds_get_modes
+    - drm/gma500: fix null pointer dereference in psb_intel_lvds_get_modes
+    - scsi: qla2xxx: Fix optrom version displayed in FDMI
+    - drm/amd/display: Check for NULL pointer
+    - apparmor: use kvfree_sensitive to free data->data
+    - cifs: fix potential null pointer use in destroy_workqueue in init_cifs error
+      path
+    - cifs: fix reconnect with SMB1 UNIX Extensions
+    - cifs: mount with "unix" mount option for SMB1 incorrectly handled
+    - task_work: s/task_work_cancel()/task_work_cancel_func()/
+    - task_work: Introduce task_work_cancel() again
+    - udf: Avoid using corrupted block bitmap buffer
+    - m68k: amiga: Turn off Warp1260 interrupts during boot
+    - ext4: check dot and dotdot of dx_root before making dir indexed
+    - ext4: make sure the first directory block is not a hole
+    - io_uring: tighten task exit cancellations
+    - trace/pid_list: Change gfp flags in pid_list_fill_irq()
+    - selftests/landlock: Add cred_transfer test
+    - wifi: mwifiex: Fix interface type change
+    - wifi: rtw88: usb: Fix disconnection after beacon loss
+    - drivers: soc: xilinx: check return status of get_api_version()
+    - leds: ss4200: Convert PCIBIOS_* return codes to errnos
+    - leds: mt6360: Fix memory leak in mt6360_init_isnk_properties()
+    - media: imx-pxp: Fix ERR_PTR dereference in pxp_probe()
+    - jbd2: make jbd2_journal_get_max_txn_bufs() internal
+    - jbd2: precompute number of transaction descriptor blocks
+    - jbd2: avoid infinite transaction commit loop
+    - media: uvcvideo: Fix integer overflow calculating timestamp
+    - KVM: VMX: Split out the non-virtualization part of vmx_interrupt_blocked()
+    - KVM: nVMX: Request immediate exit iff pending nested event needs injection
+    - ALSA: ump: Don't update FB name for static blocks
+    - ALSA: ump: Force 1 Group for MIDI1 FBs
+    - ALSA: usb-audio: Fix microphone sound on HD webcam.
+    - ALSA: usb-audio: Move HD Webcam quirk to the right place
+    - ALSA: usb-audio: Add a quirk for Sonix HD USB Camera
+    - tools/memory-model: Fix bug in lock.cat
+    - hwrng: amd - Convert PCIBIOS_* return codes to errnos
+    - parisc: Fix warning at drivers/pci/msi/msi.h:121
+    - PCI: hv: Return zero, not garbage, when reading PCI_INTERRUPT_PIN
+    - PCI: dw-rockchip: Fix initial PERST# GPIO value
+    - PCI: rockchip: Use GPIOD_OUT_LOW flag while requesting ep_gpio
+    - PCI: loongson: Enable MSI in LS7A Root Complex
+    - binder: fix hang of unregistered readers
+    - hostfs: fix dev_t handling
+    - efi/libstub: Zero initialize heap allocated struct screen_info
+    - fs/ntfs3: Update log->page_{mask,bits} if log->page_size changed
+    - scsi: qla2xxx: Return ENOBUFS if sg_cnt is more than one for ELS cmds
+    - ASoC: fsl: fsl_qmc_audio: Check devm_kasprintf() returned value
+    - f2fs: fix to force buffered IO on inline_data inode
+    - f2fs: fix to don't dirty inode for readonly filesystem
+    - f2fs: fix return value of f2fs_convert_inline_inode()
+    - f2fs: use meta inode for GC of atomic file
+    - f2fs: use meta inode for GC of COW file
+    - clk: davinci: da8xx-cfgchip: Initialize clk_init_data before use
+    - ubi: eba: properly rollback inside self_check_eba
+    - block: fix deadlock between sd_remove & sd_release
+    - mm: fix old/young bit handling in the faulting path
+    - decompress_bunzip2: fix rare decompression failure
+    - kbuild: Fix '-S -c' in x86 stack protector scripts
+    - ASoC: SOF: ipc4-topology: Preserve the DMA Link ID for ChainDMA on unprepare
+    - ASoC: amd: yc: Support mic on Lenovo Thinkpad E16 Gen 2
+    - kobject_uevent: Fix OOB access within zap_modalias_env()
+    - gve: Fix an edge case for TSO skb validity check
+    - ice: Add a per-VF limit on number of FDIR filters
+    - devres: Fix devm_krealloc() wasting memory
+    - devres: Fix memory leakage caused by driver API devm_free_percpu()
+    - irqdomain: Fixed unbalanced fwnode get and put
+    - irqchip/imx-irqsteer: Handle runtime power management correctly
+    - mm/numa_balancing: teach mpol_to_str about the balancing mode
+    - rtc: cmos: Fix return value of nvmem callbacks
+    - scsi: lpfc: Allow DEVICE_RECOVERY mode after RSCN receipt if in PRLI_ISSUE
+      state
+    - scsi: qla2xxx: During vport delete send async logout explicitly
+    - scsi: qla2xxx: Unable to act on RSCN for port online
+    - scsi: qla2xxx: Fix for possible memory corruption
+    - scsi: qla2xxx: Use QP lock to search for bsg
+    - scsi: qla2xxx: Reduce fabric scan duplicate code
+    - scsi: qla2xxx: Fix flash read failure
+    - scsi: qla2xxx: Complete command early within lock
+    - scsi: qla2xxx: validate nvme_local_port correctly
+    - perf: Fix event leak upon exit
+    - perf: Fix event leak upon exec and file release
+    - perf stat: Fix the hard-coded metrics calculation on the hybrid
+    - perf/x86/intel/uncore: Fix the bits of the CHA extended umask for SPR
+    - perf/x86/intel/ds: Fix non 0 retire latency on Raptorlake
+    - perf/x86/intel/pt: Fix topa_entry base length
+    - perf/x86/intel/pt: Fix a topa_entry base address calculation
+    - drm/i915/gt: Do not consider preemption during execlists_dequeue for gen8
+    - drm/amdgpu/sdma5.2: Update wptr registers as well as doorbell
+    - drm/udl: Remove DRM_CONNECTOR_POLL_HPD
+    - drm/dp_mst: Fix all mstb marked as not probed after suspend/resume
+    - drm/amdgpu: reset vm state machine after gpu reset(vram lost)
+    - drm/amd/amdgpu: Fix uninitialized variable warnings
+    - drm/i915/dp: Reset intel_dp->link_trained before retraining the link
+    - drm/i915/dp: Don't switch the LTTPR mode on an active link
+    - rtc: isl1208: Fix return value of nvmem callbacks
+    - rtc: abx80x: Fix return value of nvmem callback on read
+    - watchdog/perf: properly initialize the turbo mode timestamp and rearm
+      counter
+    - platform: mips: cpu_hwmon: Disable driver on unsupported hardware
+    - RDMA/iwcm: Fix a use-after-free related to destroying CM IDs
+    - selftests/sigaltstack: Fix ppc64 GCC build
+    - dm-verity: fix dm_is_verity_target() when dm-verity is builtin
+    - rbd: don't assume rbd_is_lock_owner() for exclusive mappings
+    - remoteproc: stm32_rproc: Fix mailbox interrupts queuing
+    - remoteproc: imx_rproc: Skip over memory region when node value is NULL
+    - remoteproc: imx_rproc: Fix refcount mistake in imx_rproc_addr_init
+    - MIPS: dts: loongson: Add ISA node
+    - MIPS: ip30: ip30-console: Add missing include
+    - MIPS: dts: loongson: Fix GMAC phy node
+    - MIPS: Loongson64: env: Hook up Loongsson-2K
+    - MIPS: Loongson64: Remove memory node for builtin-dtb
+    - MIPS: Loongson64: reset: Prioritise firmware service
+    - MIPS: Loongson64: Test register availability before use
+    - drm/etnaviv: don't block scheduler when GPU is still active
+    - drm/panfrost: Mark simple_ondemand governor as softdep
+    - rbd: rename RBD_LOCK_STATE_RELEASING and releasing_wait
+    - rbd: don't assume RBD_LOCK_STATE_LOCKED for exclusive mappings
+    - lib/build_OID_registry: don't mention the full path of the script in output
+    - video: logo: Drop full path of the input filename in generated file
+    - Bluetooth: btusb: Add RTL8852BE device 0489:e125 to device tables
+    - Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x13d3:0x3591
+    - minmax: scsi: fix mis-use of 'clamp()' in sr.c
+    - mm/mglru: fix ineffective protection calculation
+    - PCI/DPC: Fix use-after-free on concurrent DPC and hot-removal
+    - f2fs: fix to truncate preallocated blocks in f2fs_file_open()
+    - kdb: address -Wformat-security warnings
+    - kdb: Use the passed prompt in kdb_position_cursor()
+    - dmaengine: ti: k3-udma: Fix BCHAN count with UHC and HC channels
+    - phy: cadence-torrent: Check return value on register read
+    - phy: zynqmp: Enable reference clock correctly
+    - um: time-travel: fix time-travel-start option
+    - um: time-travel: fix signal blocking race/hang
+    - f2fs: fix start segno of large section
+    - watchdog: rzg2l_wdt: Use pm_runtime_resume_and_get()
+    - watchdog: rzg2l_wdt: Check return status of pm_runtime_put()
+    - f2fs: fix to update user block counts in block_operations()
+    - kbuild: avoid build error when single DTB is turned into composite DTB
+    - selftests/bpf: fexit_sleep: Fix stack allocation for arm64
+    - libbpf: Fix no-args func prototype BTF dumping syntax
+    - af_unix: Disable MSG_OOB handling for sockets in sockmap/sockhash
+    - dma: fix call order in dmam_free_coherent
+    - bpf, events: Use prog to emit ksymbol event for main program
+    - tools/resolve_btfids: Fix comparison of distinct pointer types warning in
+      resolve_btfids
+    - MIPS: SMP-CPS: Fix address for GCR_ACCESS register for CM3 and later
+    - ipv4: Fix incorrect source address in Record Route option
+    - net: bonding: correctly annotate RCU in bond_should_notify_peers()
+    - ice: Fix recipe read procedure
+    - netfilter: nft_set_pipapo_avx2: disable softinterrupts
+    - net: stmmac: Correct byte order of perfect_match
+    - net: nexthop: Initialize all fields in dumped nexthops
+    - bpf: Fix a segment issue when downgrading gso_size
+    - apparmor: Fix null pointer deref when receiving skb during sock creation
+    - powerpc: fix a file leak in kvm_vcpu_ioctl_enable_cap()
+    - lirc: rc_dev_get_from_fd(): fix file leak
+    - auxdisplay: ht16k33: Drop reference after LED registration
+    - ASoC: SOF: imx8m: Fix DSP control regmap retrieval
+    - spi: microchip-core: fix the issues in the isr
+    - spi: microchip-core: defer asserting chip select until just before write to
+      TX FIFO
+    - spi: microchip-core: only disable SPI controller when register value change
+      requires it
+    - spi: microchip-core: fix init function not setting the master and motorola
+      modes
+    - spi: microchip-core: ensure TX and RX FIFOs are empty at start of a transfer
+    - nvme-pci: Fix the instructions for disabling power management
+    - ASoC: sof: amd: fix for firmware reload failure in Vangogh platform
+    - spi: spidev: add correct compatible for Rohm BH2228FV
+    - ASoC: Intel: use soc_intel_is_byt_cr() only when IOSF_MBI is reachable
+    - ASoC: TAS2781: Fix tasdev_load_calibrated_data()
+    - ceph: fix incorrect kmalloc size of pagevec mempool
+    - s390/pci: Refactor arch_setup_msi_irqs()
+    - s390/pci: Allow allocation of more than 1 MSI interrupt
+    - s390/cpum_cf: Fix endless loop in CF_DIAG event stop
+    - iommu: sprd: Avoid NULL deref in sprd_iommu_hw_en
+    - io_uring: fix io_match_task must_hold
+    - nvme-pci: add missing condition check for existence of mapped data
+    - fs: don't allow non-init s_user_ns for filesystems without FS_USERNS_MOUNT
+    - md/raid0: don't free conf on raid0_run failure
+    - md/raid1: don't free conf on raid0_run failure
+    - io_uring: Fix probe of disabled operations
+    - cgroup/cpuset: Optimize isolated partition only generate_sched_domains()
+      calls
+    - cgroup/cpuset: Fix remote root partition creation problem
+    - x86/syscall: Mark exit[_group] syscall handlers __noreturn
+    - perf: arm_pmuv3: Avoid assigning fixed cycle counter with threshold
+    - md/raid5: recheck if reshape has finished with device_lock held
+    - hwmon: (ltc2991) re-order conditions to fix off by one bug
+    - arm64: smp: Fix missing IPI statistics
+    - arm64: dts: qcom: sc7280: Remove CTS/RTS configuration
+    - ARM: dts: qcom: msm8226-microsoft-common: Enable smbb explicitly
+    - OPP: Fix missing cleanup on error in _opp_attach_genpd()
+    - arm64: dts: qcom: sc8280xp-*: Remove thermal zone polling delays
+    - arm64: dts: ti: k3-am62-main: Fix the reg-range for main_pktdma
+    - arm64: dts: ti: k3-am62a-main: Fix the reg-range for main_pktdma
+    - arm64: dts: ti: k3-am62p-main: Fix the reg-range for main_pktdma
+    - arm64: dts: ti: k3-am62a7: Drop McASP AFIFOs
+    - arm64: dts: ti: k3-am62p5: Drop McASP AFIFOs
+    - arm64: dts: ti: k3-am62p5-sk: Fix pinmux for McASP1 TX
+    - arm64: dts: qcom: sc7180-trogdor: Disable pwmleds node where unused
+    - arm64: dts: mediatek: mt8192: Fix GPU thermal zone name for SVS
+    - arm64: dts: mediatek: mt8183-pico6: Fix wake-on-X event node names
+    - arm64: dts: renesas: r9a08g045: Add missing hypervisor virtual timer IRQ
+    - cpufreq/amd-pstate-ut: Convert nominal_freq to khz during comparisons
+    - wifi: mac80211: cancel multi-link reconf work on disconnect
+    - wifi: ath11k: refactor setting country code logic
+    - wifi: ath11k: restore country code during resume
+    - net: ethernet: cortina: Restore TSO support
+    - tcp: fix races in tcp_abort()
+    - hns3: avoid linking objects into multiple modules
+    - sched/core: Move preempt_model_*() helpers from sched.h to preempt.h
+    - sched/core: Drop spinlocks on contention iff kernel is preemptible
+    - net: dsa: ksz_common: Allow only up to two HSR HW offloaded ports for
+      KSZ9477
+    - libbpf: Skip base btf sanity checks
+    - wifi: mac80211: add ieee80211_tdls_sta_link_id()
+    - wifi: iwlwifi: fix iwl_mvm_get_valid_rx_ant()
+    - wifi: ath12k: advertise driver capabilities for MBSSID and EMA
+    - riscv, bpf: Fix out-of-bounds issue when preparing trampoline image
+    - perf/x86/amd/uncore: Avoid PMU registration if counters are unavailable
+    - perf/x86/amd/uncore: Fix DF and UMC domain identification
+    - NFSD: Fix nfsdcld warning
+    - net: page_pool: fix warning code
+    - bpf, arm64: Fix trampoline for BPF_TRAMP_F_CALL_ORIG
+    - Bluetooth: hci_event: Set QoS encryption from BIGInfo report
+    - Bluetooth: hci_core, hci_sync: cleanup struct discovery_state
+    - Bluetooth: Fix usage of __hci_cmd_sync_status
+    - tcp: Don't access uninit tcp_rsk(req)->ao_keyid in
+      tcp_create_openreq_child().
+    - drm/panel: ilitek-ili9882t: If prepare fails, disable GPIO before regulators
+    - drm/panel: ilitek-ili9882t: Check for errors on the NOP in prepare()
+    - drm/amd/display: Move 'struct scaler_data' off stack
+    - media: i2c: hi846: Fix V4L2_SUBDEV_FORMAT_TRY get_selection()
+    - drm/msm/dpu: fix encoder irq wait skip
+    - drm/msm/dpu: drop duplicate drm formats from wb2_formats arrays
+    - drm/msm/dp: fix runtime_pm handling in dp_wait_hpd_asserted
+    - perf maps: Switch from rbtree to lazily sorted array for addresses
+    - perf maps: Fix use after free in __maps__fixup_overlap_and_insert
+    - drm/bridge: samsung-dsim: Set P divider based on min/max of fin pll
+    - drm/i915/psr: Print Panel Replay status instead of frame lock status
+    - drm/mediatek: Set DRM mode configs accordingly
+    - drm/msm/dsi: set video mode widebus enable bit when widebus is enabled
+    - tools/perf: Fix the string match for "/tmp/perf-$PID.map" files in dso__load
+    - drm/amd/display: Add null check before access structs
+    - nfs: pass explicit offset/count to trace events
+    - PCI: endpoint: pci-epf-test: Make use of cached 'epc_features' in
+      pci_epf_test_core_init()
+    - PCI: tegra194: Set EP alignment restriction for inbound ATU
+    - riscv: smp: fail booting up smp if inconsistent vlen is detected
+    - clk: meson: s4: fix fixed_pll_dco clock
+    - clk: meson: s4: fix pwm_j_div parent clock
+    - usb: typec-mux: ptn36502: unregister typec switch on probe error and remove
+    - mtd: spi-nor: winbond: fix w25q128 regression
+    - iommufd/selftest: Fix dirty bitmap tests with u8 bitmaps
+    - iommufd/selftest: Fix iommufd_test_dirty() to handle <u8 bitmaps
+    - iommufd/selftest: Add tests for <= u8 bitmap sizes
+    - iommufd/selftest: Fix tests to use MOCK_PAGE_SIZE based buffer sizes
+    - iommufd/iova_bitmap: Check iova_bitmap_done() after set ahead
+    - clk: qcom: gcc-x1e80100: Fix halt_check for all pipe clocks
+    - dm-raid: Fix WARN_ON_ONCE check for sync_thread in raid_resume
+    - kvm: s390: Reject memory region operations for ucontrol VMs
+    - eeprom: ee1004: Call i2c_new_scanned_device to instantiate thermal sensor
+    - clk: qcom: gcc-x1e80100: Set parent rate for USB3 sec and tert PHY pipe clks
+    - workqueue: Introduce from_work() helper for cleaner callback declarations
+    - RDMA/hns: Fix mbx timing out before CMD execution is completed
+    - crypto: mxs-dcp - Ensure payload is zero when using key slot
+    - RDMA/mana_ib: Enable RoCE on port 1
+    - RDMA/mana_ib: set node_guid
+    - rtc: tps6594: Fix memleak in probe
+    - selftests/damon/access_memory: use user-defined region size
+    - md-cluster: fix hanging issue while a new disk adding
+    - power: supply: ab8500: Fix error handling when calling
+      iio_read_channel_processed()
+    - power: supply: ingenic: Fix some error handling paths in
+      ingenic_battery_get_property()
+    - remoteproc: mediatek: Don't attempt to remap l1tcm memory if missing
+    - remoteproc: k3-r5: Fix IPC-only mode detection
+    - mailbox: imx: fix TXDB_V2 channel race condition
+    - mailbox: mtk-cmdq: Move devm_mbox_controller_register() after
+      devm_pm_runtime_enable()
+    - mm: huge_memory: use !CONFIG_64BIT to relax huge page alignment on 32 bit
+      machines
+    - mm/huge_memory: avoid PMD-size page cache if needed
+    - thermal/drivers/broadcom: Fix race between removal and clock disable
+    - workqueue: Always queue work items to the newest PWQ for order workqueues
+    - ipv6: fix source address selection with route leak
+    - drm/xe: Use write-back caching mode for system memory on DGFX
+    - md/raid5: fix spares errors about rcu usage
+    - media: stm32: dcmipp: correct error handling in dcmipp_create_subdevs
+    - tpm_tis_spi: add missing attpm20p SPI device ID entry
+    - sysctl: always initialize i_uid/i_gid
+    - media: i2c: Kconfig: Fix missing firmware upload config select
+    - genirq: Set IRQF_COND_ONESHOT in request_irq()
+    - cpufreq: qcom-nvmem: fix memory leaks in probe error paths
+    - leds: triggers: Flush pending brightness before activating trigger
+    - media: i2c: alvium: Move V4L2_CID_GAIN to V4L2_CID_ANALOG_GAIN
+    - KVM: nVMX: Add a helper to get highest pending from Posted Interrupt vector
+    - KVM: nVMX: Check for pending posted interrupts when looking for nested
+      events
+    - ALSA: hda/realtek: cs35l41: Fixup remaining asus strix models
+    - fbdev: vesafb: Detect VGA compatibility from screen info's VESA attributes
+    - drm/fbdev-dma: Fix framebuffer mode for big endian devices
+    - xhci: Apply XHCI_RESET_TO_DEFAULT quirk to TGL
+    - dmaengine: fsl-edma: clean up unused "fsl,imx8qm-adma" compatible string
+    - dmaengine: fsl-edma: change the memory access from local into remote mode in
+      i.MX 8QM
+    - clk: samsung: fix getting Exynos4 fin_pll rate from external clocks
+    - bus: mhi: ep: Do not allocate memory for MHI objects from DMA zone
+    - ASoC: SOF: ipc4-topology: Use correct queue_id for requesting input pin
+      format
+    - arch: um: rust: Use the generated target.json again
+    - f2fs: fix null reference error when checking end of zone
+    - selftests: forwarding: skip if kernel not support setting bridge fdb
+      learning limit
+    - xsk: Require XDP_UMEM_TX_METADATA_LEN to actuate tx_metadata_len
+    - drm/xe/exec: Fix minor bug related to xe_sync_entry_cleanup
+    - thermal: trip: Split thermal_zone_device_set_mode()
+    - apparmor: unpack transition table if dfa is not present
+    - i3c: mipi-i3c-hci: Fix number of DAT/DCT entries for HCI versions < 1.1
+    - selinux,smack: remove the capability checks in the removexattr hooks
+    - selftests/bpf: DENYLIST.aarch64: Skip fexit_sleep again
+    - nilfs2: handle inconsistent state in nilfs_btnode_create_block()
+    - Upstream stable to v6.6.44, v6.10.3
+
+  * Noble update: upstream stable patchset 2024-09-30 (LP: #2083196) //
+    CVE-2024-42284
+    - tipc: Return non-zero value from tipc_udp_addr2str() on error
+
+  * CVE-2024-44987
+    - ipv6: prevent UAF in ip6_send_skb()
+
+  * CVE-2024-42301
+    - dev/parport: fix the array out-of-bounds risk
+
+  * CVE-2024-44998
+    - atm: idt77252: prevent use after free in dequeue_rx()
+
+ -- Mehmet Basaran <mehmet.basaran@canonical.com>  Sat, 09 Nov 2024 18:54:16 +0300
+
+linux (6.8.0-49.49) noble; urgency=medium
+
+  * noble/linux: 6.8.0-49.49 -proposed tracker (LP: #2085942)
+
+  * CVE-2024-46800
+    - sch/netem: fix use after free in netem_dequeue
+
+  * mm/folios: xfs hangs with hung task timeouts with corrupted folio pointer
+    lists (LP: #2085495)
+    - lib/xarray: introduce a new helper xas_get_order
+    - mm/filemap: return early if failed to allocate memory for split
+    - mm/filemap: optimize filemap folio adding
+
+  * CVE-2024-43882
+    - exec: Fix ToCToU between perm check and set-uid/gid usage
+
+ -- Manuel Diewald <manuel.diewald@canonical.com>  Fri, 01 Nov 2024 11:56:32 +0100
+
+linux (6.8.0-48.48) noble; urgency=medium
+
+  * noble/linux: 6.8.0-48.48 -proposed tracker (LP: #2082437)
+
+  * [SRU][Noble] Bad EPP defaults cause performance regressions on select Intel
+    CPUs (LP: #2077470)
+    - x86/cpu/vfm: Update arch/x86/include/asm/intel-family.h
+    - cpufreq: intel_pstate: Allow model specific EPPs
+    - cpufreq: intel_pstate: Update default EPPs for Meteor Lake
+    - cpufreq: intel_pstate: Switch to new Intel CPU model defines
+    - cpufreq: intel_pstate: Update Meteor Lake EPPs
+    - cpufreq: intel_pstate: Use Meteor Lake EPPs for Arrow Lake
+    - cpufreq: intel_pstate: Update Balance performance EPP for Emerald Rapids
+
+  * power: Enable intel_rapl driver (LP: #2078834)
+    - powercap: intel_rapl: Add support for ArrowLake-H platform
+
+  * x86/vmware: Add TDX hypercall support (LP: #2077729)
+    - x86/vmware: Introduce VMware hypercall API
+    - x86/vmware: Add TDX hypercall support
+
+  * Guest crashes post migration with migrate_misplaced_folio+0x4cc/0x5d0
+    (LP: #2076866)
+    - mm/mempolicy: use numa_node_id() instead of cpu_to_node()
+    - mm/numa_balancing: allow migrate on protnone reference with
+      MPOL_PREFERRED_MANY policy
+    - mm: convert folio_estimated_sharers() to folio_likely_mapped_shared()
+    - mm: factor out the numa mapping rebuilding into a new helper
+    - mm: support multi-size THP numa balancing
+    - mm/migrate: make migrate_misplaced_folio() return 0 on success
+    - mm/migrate: move NUMA hinting fault folio isolation + checks under PTL
+    - mm: fix possible OOB in numa_rebuild_large_mapping()
+
+  * Add 'mm: hold PTL from the first PTE while reclaiming a large folio' to fix
+    L2 Guest hang during LTP Test (LP: #2076147)
+    - mm: hold PTL from the first PTE while reclaiming a large folio
+
+  * KOP L2 guest fails to boot with 1 core - SMT8 topology (LP: #2070329)
+    - KVM: PPC: Book3S HV nestedv2: Add DPDES support in helper library for Guest
+      state buffer
+    - KVM: PPC: Book3S HV nestedv2: Fix doorbell emulation
+
+  * L2 Guest migration: continuously dumping while running NFS guest migration
+    (LP: #2076406)
+    - KVM: PPC: Book3S HV: Fix the set_one_reg for MMCR3
+    - KVM: PPC: Book3S HV: Fix the get_one_reg of SDAR
+    - KVM: PPC: Book3S HV: Add one-reg interface for DEXCR register
+    - KVM: PPC: Book3S HV nestedv2: Keep nested guest DEXCR in sync
+    - KVM: PPC: Book3S HV: Add one-reg interface for HASHKEYR register
+    - KVM: PPC: Book3S HV nestedv2: Keep nested guest HASHKEYR in sync
+    - KVM: PPC: Book3S HV: Add one-reg interface for HASHPKEYR register
+    - KVM: PPC: Book3S HV nestedv2: Keep nested guest HASHPKEYR in sync
+
+  * perf build disables tracepoint support (LP: #2076190)
+    - [Packaging] perf: reenable libtraceevent
+
+  * Please backport the more restrictive XSAVES deactivation for  Zen1/2 arch
+    (LP: #2077321)
+    - x86/CPU/AMD: Improve the erratum 1386 workaround
+
+  * Fix alsa scarlett2 driver in 6.8  (LP: #2076402)
+    - ALSA: scarlett2: Move initialisation code lower in the source
+    - ALSA: scarlett2: Implement handling of the ACK notification
+
+  * rtw89: reset IDMEM mode to prevent download firmware failure (LP: #2077396)
+    - wifi: rtw89: 885xb: reset IDMEM mode to prevent download firmware failure
+
+  * CVE-2024-43858
+    - jfs: Fix array-index-out-of-bounds in diFree
+
+  * CVE-2024-42280
+    - mISDN: Fix a use after free in hfcmulti_tx()
+
+  * CVE-2024-42271
+    - net/iucv: fix use after free in iucv_sock_close()
+
+  * [Ubuntu-24.04] FADump with recommended crash size is making the L1 hang
+    (LP: #2060039)
+    - powerpc/64s/radix/kfence: map __kfence_pool at page granularity
+
+  * Noble update: upstream stable patchset 2024-09-09 (LP: #2079945)
+    - ocfs2: add bounds checking to ocfs2_check_dir_entry()
+    - jfs: don't walk off the end of ealist
+    - fs/ntfs3: Add a check for attr_names and oatbl
+    - fs/ntfs3: Validate ff offset
+    - usb: gadget: midi2: Fix incorrect default MIDI2 protocol setup
+    - ALSA: hda/realtek: Enable headset mic on Positivo SU C1400
+    - ALSA: hda/realtek: Fix the speaker output on Samsung Galaxy Book Pro 360
+    - arm64: dts: qcom: qrb4210-rb2: switch I2C2 to i2c-gpio
+    - arm64: dts: qcom: msm8996: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: sm6350: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: ipq6018: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: sdm630: Disable SS instance in Parkmode for USB
+    - ALSA: pcm_dmaengine: Don't synchronize DMA channel when DMA is paused
+    - ALSA: seq: ump: Skip useless ports for static blocks
+    - filelock: Fix fcntl/close race recovery compat path
+    - tun: add missing verification for short frame
+    - tap: add missing verification for short frame
+    - s390/mm: Fix VM_FAULT_HWPOISON handling in do_exception()
+    - ALSA: hda/tas2781: Add new quirk for Lenovo Hera2 Laptop
+    - arm64: dts: qcom: sc7180: Disable SuperSpeed instances in park mode
+    - arm64: dts: qcom: sc7280: Disable SuperSpeed instances in park mode
+    - arm64: dts: qcom: qrb2210-rb1: switch I2C2 to i2c-gpio
+    - arm64: dts: qcom: msm8998: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: ipq8074: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: sdm845: Disable SS instance in Parkmode for USB
+    - Upstream stable to v6.6.43, v6.9.12
+
+  * Noble update: upstream stable patchset 2024-09-02 (LP: #2078304)
+    - filelock: Remove locks reliably when fcntl/close race is detected
+    - scsi: core: alua: I/O errors for ALUA state transitions
+    - scsi: sr: Fix unintentional arithmetic wraparound
+    - scsi: qedf: Don't process stag work during unload and recovery
+    - scsi: qedf: Wait for stag work during unload
+    - scsi: qedf: Set qed_slowpath_params to zero before use
+    - efi/libstub: zboot.lds: Discard .discard sections
+    - ACPI: EC: Abort address space access upon error
+    - ACPI: EC: Avoid returning AE_OK on errors in address space handler
+    - tools/power/cpupower: Fix Pstate frequency reporting on AMD Family 1Ah CPUs
+    - wifi: mac80211: mesh: init nonpeer_pm to active by default in mesh sdata
+    - wifi: mac80211: apply mcast rate only if interface is up
+    - wifi: mac80211: handle tasklet frames before stopping
+    - wifi: cfg80211: fix 6 GHz scan request building
+    - wifi: iwlwifi: mvm: d3: fix WoWLAN command version lookup
+    - wifi: iwlwifi: mvm: remove stale STA link data during restart
+    - wifi: iwlwifi: mvm: Handle BIGTK cipher in kek_kck cmd
+    - wifi: iwlwifi: mvm: handle BA session teardown in RF-kill
+    - wifi: iwlwifi: mvm: properly set 6 GHz channel direct probe option
+    - wifi: iwlwifi: mvm: Fix scan abort handling with HW rfkill
+    - wifi: mac80211: fix UBSAN noise in ieee80211_prep_hw_scan()
+    - selftests: cachestat: Fix build warnings on ppc64
+    - selftests/openat2: Fix build warnings on ppc64
+    - selftests/futex: pass _GNU_SOURCE without a value to the compiler
+    - of/irq: Factor out parsing of interrupt-map parent phandle+args from
+      of_irq_parse_raw()
+    - Input: silead - Always support 10 fingers
+    - net: ipv6: rpl_iptunnel: block BH in rpl_output() and rpl_input()
+    - ila: block BH in ila_output()
+    - arm64: armv8_deprecated: Fix warning in isndep cpuhp starting process
+    - null_blk: fix validation of block size
+    - kconfig: gconf: give a proper initial state to the Save button
+    - kconfig: remove wrong expr_trans_bool()
+    - input: Add event code for accessibility key
+    - input: Add support for "Do Not Disturb"
+    - HID: Ignore battery for ELAN touchscreens 2F2C and 4116
+    - NFSv4: Fix memory leak in nfs4_set_security_label
+    - nfs: propagate readlink errors in nfs_symlink_filler
+    - nfs: Avoid flushing many pages with NFS_FILE_SYNC
+    - nfs: don't invalidate dentries on transient errors
+    - cachefiles: add consistency check for copen/cread
+    - cachefiles: Set object to close if ondemand_id < 0 in copen
+    - cachefiles: make on-demand read killable
+    - fs/file: fix the check in find_next_fd()
+    - mei: demote client disconnect warning on suspend to debug
+    - iomap: Fix iomap_adjust_read_range for plen calculation
+    - drm/exynos: dp: drop driver owner initialization
+    - drm: panel-orientation-quirks: Add quirk for Aya Neo KUN
+    - drm/mediatek: Call drm_atomic_helper_shutdown() at shutdown time
+    - nvme: avoid double free special payload
+    - nvmet: always initialize cqe.result
+    - ALSA: hda: cs35l56: Fix lifecycle of codec pointer
+    - wifi: cfg80211: wext: add extra SIOCSIWSCAN data check
+    - ALSA: hda/realtek: Support Lenovo Thinkbook 16P Gen 5
+    - KVM: PPC: Book3S HV: Prevent UAF in kvm_spapr_tce_attach_iommu_group()
+    - drm/vmwgfx: Fix missing HYPERVISOR_GUEST dependency
+    - ALSA: hda/realtek: Add more codec ID to no shutup pins list
+    - spi: Fix OCTAL mode support
+    - cpumask: limit FORCE_NR_CPUS to just the UP case
+    - [Config] Remove FORCE_NR_CPUS
+    - selftests: openvswitch: Set value to nla flags.
+    - drm/amdgpu: Indicate CU havest info to CP
+    - ALSA: hda: cs35l56: Select SERIAL_MULTI_INSTANTIATE
+    - mips: fix compat_sys_lseek syscall
+    - Input: elantech - fix touchpad state on resume for Lenovo N24
+    - Input: i8042 - add Ayaneo Kun to i8042 quirk table
+    - ASoC: rt722-sdca-sdw: add silence detection register as volatile
+    - Input: xpad - add support for ASUS ROG RAIKIRI PRO
+    - ASoC: topology: Fix references to freed memory
+    - ASoC: topology: Do not assign fields that are already set
+    - bytcr_rt5640 : inverse jack detect for Archos 101 cesium
+    - ALSA: dmaengine: Synchronize dma channel after drop()
+    - ASoC: ti: davinci-mcasp: Set min period size using FIFO config
+    - ASoC: ti: omap-hdmi: Fix too long driver name
+    - ASoC: SOF: sof-audio: Skip unprepare for in-use widgets on error rollback
+    - ASoC: rt722-sdca-sdw: add debounce time for type detection
+    - nvme: fix NVME_NS_DEAC may incorrectly identifying the disk as EXT_LBA.
+    - Input: ads7846 - use spi_device_id table
+    - can: kvaser_usb: fix return value for hif_usb_send_regout
+    - gpio: pca953x: fix pca953x_irq_bus_sync_unlock race
+    - octeontx2-pf: Fix coverity and klockwork issues in octeon PF driver
+    - s390/sclp: Fix sclp_init() cleanup on failure
+    - platform/mellanox: nvsw-sn2201: Add check for platform_device_add_resources
+    - platform/x86: wireless-hotkey: Add support for LG Airplane Button
+    - platform/x86: lg-laptop: Remove LGEX0815 hotkey handling
+    - platform/x86: lg-laptop: Change ACPI device id
+    - platform/x86: lg-laptop: Use ACPI device handle when evaluating WMAB/WMBB
+    - btrfs: qgroup: fix quota root leak after quota disable failure
+    - ibmvnic: Add tx check to prevent skb leak
+    - ALSA: PCM: Allow resume only for suspended streams
+    - ALSA: hda/relatek: Enable Mute LED on HP Laptop 15-gw0xxx
+    - ALSA: dmaengine_pcm: terminate dmaengine before synchronize
+    - ASoC: amd: yc: Fix non-functional mic on ASUS M5602RA
+    - net: usb: qmi_wwan: add Telit FN912 compositions
+    - net: mac802154: Fix racy device stats updates by DEV_STATS_INC() and
+      DEV_STATS_ADD()
+    - powerpc/pseries: Whitelist dtl slub object for copying to userspace
+    - powerpc/eeh: avoid possible crash when edev->pdev changes
+    - scsi: libsas: Fix exp-attached device scan after probe failure scanned in
+      again after probe failed
+    - tee: optee: ffa: Fix missing-field-initializers warning
+    - Bluetooth: hci_core: cancel all works upon hci_unregister_dev()
+    - Bluetooth: btnxpuart: Enable Power Save feature on startup
+    - bluetooth/l2cap: sync sock recv cb and release
+    - erofs: ensure m_llen is reset to 0 if metadata is invalid
+    - drm/amd/display: Add refresh rate range check
+    - drm/amd/display: Account for cursor prefetch BW in DML1 mode support
+    - drm/amd/display: Fix refresh rate range for some panel
+    - drm/radeon: check bo_va->bo is non-NULL before using it
+    - fs: better handle deep ancestor chains in is_subdir()
+    - wifi: iwlwifi: properly set WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK
+    - drivers/perf: riscv: Reset the counter to hpmevent mapping while starting
+      cpus
+    - riscv: stacktrace: fix usage of ftrace_graph_ret_addr()
+    - spi: imx: Don't expect DMA for i.MX{25,35,50,51,53} cspi devices
+    - ksmbd: return FILE_DEVICE_DISK instead of super magic
+    - ASoC: SOF: Intel: hda-pcm: Limit the maximum number of periods by
+      MAX_BDL_ENTRIES
+    - selftest/timerns: fix clang build failures for abs() calls
+    - selftests/vDSO: fix clang build errors and warnings
+    - hfsplus: fix uninit-value in copy_name
+    - selftests/bpf: Extend tcx tests to cover late tcx_entry release
+    - spi: mux: set ctlr->bits_per_word_mask
+    - ALSA: hda: Use imply for suggesting CONFIG_SERIAL_MULTI_INSTANTIATE
+    - [Config] Update CONFIG_SERIAL_MULTI_INSTANTIATE
+    - cifs: fix noisy message on copy_file_range
+    - Bluetooth: L2CAP: Fix deadlock
+    - of/irq: Disable "interrupt-map" parsing for PASEMI Nemo
+    - wifi: cfg80211: wext: set ssids=NULL for passive scans
+    - wifi: mac80211: disable softirqs for queued frame handling
+    - wifi: iwlwifi: mvm: don't wake up rx_sync_waitq upon RFKILL
+    - cachefiles: fix slab-use-after-free in fscache_withdraw_volume()
+    - cachefiles: fix slab-use-after-free in cachefiles_withdraw_cookie()
+    - btrfs: ensure fast fsync waits for ordered extents after a write failure
+    - PNP: Hide pnp_bus_type from the non-PNP code
+    - ACPI: AC: Properly notify powermanagement core about changes
+    - selftests/overlayfs: Fix build error on ppc64
+    - nvme-fabrics: use reserved tag for reg read/write command
+    - LoongArch: Fix GMAC's phy-mode definitions in dts
+    - io_uring: fix possible deadlock in io_register_iowq_max_workers()
+    - vfio: Create vfio_fs_type with inode per device
+    - vfio/pci: Use unmap_mapping_range()
+    - parport: amiga: Mark driver struct with __refdata to prevent section
+      mismatch
+    - drm: renesas: shmobile: Call drm_atomic_helper_shutdown() at shutdown time
+    - vfio/pci: Insert full vma on mmap'd MMIO fault
+    - ALSA: hda: cs35l41: Support Lenovo Thinkbook 16P Gen 5
+    - ALSA: hda: cs35l41: Support Lenovo Thinkbook 13x Gen 4
+    - ALSA: hda/realtek: Support Lenovo Thinkbook 13x Gen 4
+    - wifi: mac80211: Avoid address calculations via out of bounds array indexing
+    - drm/amd/display: change dram_clock_latency to 34us for dcn35
+    - closures: Change BUG_ON() to WARN_ON()
+    - ASoC: codecs: ES8326: Solve headphone detection issue
+    - ASoC: Intel: avs: Fix route override
+    - net: mvpp2: fill-in dev_port attribute
+    - btrfs: scrub: handle RST lookup error correctly
+    - clk: qcom: apss-ipq-pll: remove 'config_ctl_hi_val' from Stromer pll configs
+    - drm/amd/display: Update efficiency bandwidth for dcn351
+    - drm/amd/display: Fix array-index-out-of-bounds in dml2/FCLKChangeSupport
+    - btrfs: fix uninitialized return value in the ref-verify tool
+    - spi: davinci: Unset POWERDOWN bit when releasing resources
+    - mm: page_ref: remove folio_try_get_rcu()
+    - ALSA: hda: cs35l41: Fix swapped l/r audio channels for Lenovo ThinBook 13x
+      Gen4
+    - netfs, fscache: export fscache_put_volume() and add fscache_try_get_volume()
+    - Upstream stable to v6.6.42, v6.9.11
+
+  * CVE-2024-27022
+    - Revert "Revert "fork: defer linking file vma until vma is fully
+      initialized""
+
+  * UBSAN: array-index-out-of-bounds in /build/linux-Z1RxaK/linux-
+    6.8.0/drivers/gpu/drm/amd/amdgpu/../pm/powerplay/hwmgr/processpptables.c:124
+    9:61 (LP: #2078041)
+    - drm/amdgpu/pptable: convert some variable sized arrays to [] style
+    - drm/amdgpu: convert some variable sized arrays to [] style
+    - drm/amdgpu/pptable: Fix UBSAN array-index-out-of-bounds
+
+  * alsa: Headphone and Speaker couldn't output sound intermittently
+    (LP: #2077690)
+    - ALSA: hda/realtek - Fixed ALC256 headphone no sound
+    - ALSA: hda/realtek - FIxed ALC285 headphone no sound
+
+  * Fix ethernet performance on JSL and EHL (LP: #2077858)
+    - intel_idle: Disable promotion to C1E on Jasper Lake and Elkhart Lake
+
+  * Noble update: upstream stable patchset 2024-08-29 (LP: #2078289)
+    - Revert "usb: xhci: prevent potential failure in handle_tx_event() for
+      Transfer events without TRB"
+    - Compiler Attributes: Add __uninitialized macro
+    - mm: prevent derefencing NULL ptr in pfn_section_valid()
+    - scsi: ufs: core: Fix ufshcd_clear_cmd racing issue
+    - scsi: ufs: core: Fix ufshcd_abort_one racing issue
+    - vfio/pci: Init the count variable in collecting hot-reset devices
+    - cachefiles: propagate errors from vfs_getxattr() to avoid infinite loop
+    - cachefiles: stop sending new request when dropping object
+    - cachefiles: cancel all requests for the object that is being dropped
+    - cachefiles: wait for ondemand_object_worker to finish when dropping object
+    - cachefiles: cyclic allocation of msg_id to avoid reuse
+    - cachefiles: add missing lock protection when polling
+    - dsa: lan9303: Fix mapping between DSA port number and PHY address
+    - filelock: fix potential use-after-free in posix_lock_inode
+    - fs/dcache: Re-use value stored to dentry->d_flags instead of re-reading
+    - vfs: don't mod negative dentry count when on shrinker list
+    - net: bcmasp: Fix error code in probe()
+    - tcp: fix incorrect undo caused by DSACK of TLP retransmit
+    - bpf: Fix too early release of tcx_entry
+    - net: phy: microchip: lan87xx: reinit PHY after cable test
+    - skmsg: Skip zero length skb in sk_msg_recvmsg
+    - octeontx2-af: Fix incorrect value output on error path in
+      rvu_check_rsrc_availability()
+    - net: fix rc7's __skb_datagram_iter()
+    - i40e: Fix XDP program unloading while removing the driver
+    - net: ethernet: lantiq_etop: fix double free in detach
+    - bpf: fix order of args in call to bpf_map_kvcalloc
+    - bpf: make timer data struct more generic
+    - bpf: replace bpf_timer_init with a generic helper
+    - bpf: Fail bpf_timer_cancel when callback is being cancelled
+    - net: ethernet: mtk-star-emac: set mac_managed_pm when probing
+    - ppp: reject claimed-as-LCP but actually malformed packets
+    - ethtool: netlink: do not return SQI value if link is down
+    - udp: Set SOCK_RCU_FREE earlier in udp_lib_get_port().
+    - net, sunrpc: Remap EPERM in case of connection failure in
+      xs_tcp_setup_socket
+    - s390: Mark psw in __load_psw_mask() as __unitialized
+    - arm64: dts: qcom: sc8180x: Fix LLCC reg property again
+    - firmware: cs_dsp: Fix overflow checking of wmfw header
+    - firmware: cs_dsp: Return error if block header overflows file
+    - firmware: cs_dsp: Validate payload length before processing block
+    - firmware: cs_dsp: Prevent buffer overrun when processing V2 alg headers
+    - ASoC: SOF: Intel: hda: fix null deref on system suspend entry
+    - firmware: cs_dsp: Use strnlen() on name fields in V1 wmfw files
+    - ARM: davinci: Convert comma to semicolon
+    - octeontx2-af: replace cpt slot with lf id on reg write
+    - octeontx2-af: fix a issue with cpt_lf_alloc mailbox
+    - octeontx2-af: fix detection of IP layer
+    - octeontx2-af: fix issue with IPv6 ext match for RSS
+    - octeontx2-af: fix issue with IPv4 match for RSS
+    - cifs: fix setting SecurityFlags to true
+    - Revert "sched/fair: Make sure to try to detach at least one movable task"
+    - tcp: avoid too many retransmit packets
+    - net: ks8851: Fix deadlock with the SPI chip variant
+    - net: ks8851: Fix potential TX stall after interface reopen
+    - USB: serial: option: add Telit generic core-dump composition
+    - USB: serial: option: add Telit FN912 rmnet compositions
+    - USB: serial: option: add Fibocom FM350-GL
+    - USB: serial: option: add support for Foxconn T99W651
+    - USB: serial: option: add Netprisma LCUK54 series modules
+    - USB: serial: option: add Rolling RW350-GL variants
+    - USB: serial: mos7840: fix crash on resume
+    - USB: Add USB_QUIRK_NO_SET_INTF quirk for START BP-850k
+    - usb: dwc3: pci: add support for the Intel Panther Lake
+    - usb: gadget: configfs: Prevent OOB read/write in usb_string_copy()
+    - USB: core: Fix duplicate endpoint bug by clearing reserved bits in the
+      descriptor
+    - misc: microchip: pci1xxxx: Fix return value of nvmem callbacks
+    - hpet: Support 32-bit userspace
+    - xhci: always resume roothubs if xHC was reset during resume
+    - s390/mm: Add NULL pointer check to crst_table_free() base_crst_free()
+    - mm: vmalloc: check if a hash-index is in cpu_possible_mask
+    - mm/filemap: skip to create PMD-sized page cache if needed
+    - mm/filemap: make MAX_PAGECACHE_ORDER acceptable to xarray
+    - ksmbd: discard write access to the directory open
+    - iio: trigger: Fix condition for own trigger
+    - arm64: dts: qcom: sa8775p: Correct IRQ number of EL2 non-secure physical
+      timer
+    - arm64: dts: qcom: sc8280xp-x13s: fix touchscreen power on
+    - nvmem: rmem: Fix return value of rmem_read()
+    - nvmem: meson-efuse: Fix return value of nvmem callbacks
+    - nvmem: core: only change name to fram for current attribute
+    - platform/x86: toshiba_acpi: Fix array out-of-bounds access
+    - tty: serial: ma35d1: Add a NULL check for of_node
+    - ALSA: hda/realtek: add quirk for Clevo V5[46]0TU
+    - ALSA: hda/realtek: Enable Mute LED on HP 250 G7
+    - ALSA: hda/realtek: Limit mic boost on VAIO PRO PX
+    - Fix userfaultfd_api to return EINVAL as expected
+    - pmdomain: qcom: rpmhpd: Skip retention level for Power Domains
+    - libceph: fix race between delayed_work() and ceph_monc_stop()
+    - ACPI: processor_idle: Fix invalid comparison with insertion sort for latency
+    - cpufreq: ACPI: Mark boost policy as enabled when setting boost
+    - cpufreq: Allow drivers to advertise boost enabled
+    - wireguard: selftests: use acpi=off instead of -no-acpi for recent QEMU
+    - wireguard: allowedips: avoid unaligned 64-bit memory accesses
+    - wireguard: queueing: annotate intentional data race in cpu round robin
+    - wireguard: send: annotate intentional data race in checking empty queue
+    - misc: fastrpc: Fix DSP capabilities request
+    - misc: fastrpc: Avoid updating PD type for capability request
+    - misc: fastrpc: Copy the complete capability structure to user
+    - misc: fastrpc: Fix memory leak in audio daemon attach operation
+    - misc: fastrpc: Fix ownership reassignment of remote heap
+    - misc: fastrpc: Restrict untrusted app to attach to privileged PD
+    - mm/shmem: disable PMD-sized page cache if needed
+    - mm/damon/core: merge regions aggressively when max_nr_regions is unmet
+    - selftests/net: fix gro.c compilation failure due to non-existent
+      opt_ipproto_off
+    - ext4: avoid ptr null pointer dereference
+    - sched: Move psi_account_irqtime() out of update_rq_clock_task() hotpath
+    - i2c: rcar: bring hardware to known state when probing
+    - i2c: mark HostNotify target address as used
+    - i2c: rcar: ensure Gen3+ reset does not disturb local targets
+    - i2c: testunit: avoid re-issued work after read message
+    - i2c: rcar: clear NO_RXDMA flag after resetting
+    - x86/bhi: Avoid warning in #DB handler due to BHI mitigation
+    - kbuild: Make ld-version.sh more robust against version string changes
+    - spi: axi-spi-engine: fix sleep calculation
+    - minixfs: Fix minixfs_rename with HIGHMEM
+    - bpf: Defer work in bpf_timer_cancel_and_free
+    - netfilter: nf_tables: prefer nft_chain_validate
+    - arm64: dts: qcom: x1e80100-*: Allocate some CMA buffers
+    - arm64: dts: qcom: sm6115: add iommu for sdhc_1
+    - arm64: dts: qcom: qdu1000: Fix LLCC reg property
+    - net: ethtool: Fix RSS setting
+    - nilfs2: fix kernel bug on rename operation of broken directory
+    - cachestat: do not flush stats in recency check
+    - mm: fix crashes from deferred split racing folio migration
+    - nvmem: core: limit cell sysfs permissions to main attribute ones
+    - serial: imx: ensure RTS signal is not left active after shutdown
+    - mmc: sdhci: Fix max_seg_size for 64KiB PAGE_SIZE
+    - mmc: davinci_mmc: Prevent transmitted data size from exceeding sgm's length
+    - mm/readahead: limit page cache size in page_cache_ra_order()
+    - Revert "dt-bindings: cache: qcom,llcc: correct QDU1000 reg entries"
+    - sched/deadline: Fix task_struct reference leak
+    - Upstream stable to v6.6.40, v6.6.41, v6.9.10
+
+  * [SRU][HPE 24.04] Intel FVL NIC FW flash fails with inbox driver, causing
+    driver not detected (LP: #2076675) // Noble update: upstream stable patchset
+    2024-08-29 (LP: #2078289)
+    - i40e: fix: remove needless retries of NVM update
+
+  * CVE-2024-41022
+    - drm/amdgpu: Fix signedness bug in sdma_v4_0_process_trap_irq()
+
+  *  Deadlock occurs while suspending md raid  (LP: #2073695)
+    - md: change the return value type of md_write_start to void
+    - md: fix deadlock between mddev_suspend and flush bio
+
+  * Lenovo X12 Detachable Gen 2 unresponsive under light load (LP: #2076361)
+    - drm/i915: Enable Wa_16019325821
+    - drm/i915/guc: Add support for w/a KLVs
+    - drm/i915/guc: Enable Wa_14019159160
+
+  * Regression: unable to reach low idle states on Tiger Lake (LP: #2072679)
+    - SAUCE: PCI: ASPM: Allow OS to configure ASPM where BIOS is incapable of
+    - SAUCE: PCI: vmd: Let OS control ASPM for devices under VMD domain
+
+  * Noble update: upstream stable patchset 2024-08-22 (LP: #2077600)
+    - locking/mutex: Introduce devm_mutex_init()
+    - leds: an30259a: Use devm_mutex_init() for mutex initialization
+    - crypto: hisilicon/debugfs - Fix debugfs uninit process issue
+    - drm/lima: fix shared irq handling on driver remove
+    - powerpc: Avoid nmi_enter/nmi_exit in real mode interrupt.
+    - media: dvb: as102-fe: Fix as10x_register_addr packing
+    - media: dvb-usb: dib0700_devices: Add missing release_firmware()
+    - IB/core: Implement a limit on UMAD receive List
+    - scsi: qedf: Make qedf_execute_tmf() non-preemptible
+    - selftests/bpf: adjust dummy_st_ops_success to detect additional error
+    - selftests/bpf: do not pass NULL for non-nullable params in dummy_st_ops
+    - selftests/bpf: dummy_st_ops should reject 0 for non-nullable params
+    - RISC-V: KVM: Fix the initial sample period value
+    - crypto: aead,cipher - zeroize key buffer after use
+    - media: mediatek: vcodec: Only free buffer VA that is not NULL
+    - drm/amdgpu: Fix uninitialized variable warnings
+    - drm/amdgpu: Initialize timestamp for some legacy SOCs
+    - drm/amd/display: Check index msg_id before read or write
+    - drm/amd/display: Check pipe offset before setting vblank
+    - drm/amd/display: Skip finding free audio for unknown engine_id
+    - drm/amd/display: Fix uninitialized variables in DM
+    - drm/amdgpu: fix uninitialized scalar variable warning
+    - drm/amdgpu: fix the warning about the expression (int)size - len
+    - media: dw2102: Don't translate i2c read into write
+    - riscv: Apply SiFive CIP-1200 workaround to single-ASID sfence.vma
+    - sctp: prefer struct_size over open coded arithmetic
+    - firmware: dmi: Stop decoding on broken entry
+    - Input: ff-core - prefer struct_size over open coded arithmetic
+    - wifi: mt76: replace skb_put with skb_put_zero
+    - wifi: mt76: mt7996: add sanity checks for background radar trigger
+    - thermal/drivers/mediatek/lvts_thermal: Check NULL ptr on lvts_data
+    - media: dvb-frontends: tda18271c2dd: Remove casting during div
+    - media: s2255: Use refcount_t instead of atomic_t for num_channels
+    - media: dvb-frontends: tda10048: Fix integer overflow
+    - i2c: i801: Annotate apanel_addr as __ro_after_init
+    - powerpc/64: Set _IO_BASE to POISON_POINTER_DELTA not 0 for CONFIG_PCI=n
+    - orangefs: fix out-of-bounds fsid access
+    - kunit: Fix timeout message
+    - powerpc/xmon: Check cpu id in commands "c#", "dp#" and "dx#"
+    - selftests/net: fix uninitialized variables
+    - igc: fix a log entry using uninitialized netdev
+    - bpf: Avoid uninitialized value in BPF_CORE_READ_BITFIELD
+    - serial: imx: Raise TX trigger level to 8
+    - jffs2: Fix potential illegal address access in jffs2_free_inode
+    - s390/pkey: Wipe sensitive data on failure
+    - btrfs: scrub: initialize ret in scrub_simple_mirror() to fix compilation
+      warning
+    - cdrom: rearrange last_media_change check to avoid unintentional overflow
+    - tools/power turbostat: Remember global max_die_id
+    - vhost: Use virtqueue mutex for swapping worker
+    - vhost: Release worker mutex during flushes
+    - vhost_task: Handle SIGKILL by flushing work and exiting
+    - mac802154: fix time calculation in ieee802154_configure_durations()
+    - net: phy: phy_device: Fix PHY LED blinking code comment
+    - UPSTREAM: tcp: fix DSACK undo in fast recovery to call tcp_try_to_open()
+    - net/mlx5: E-switch, Create ingress ACL when needed
+    - net/mlx5e: Add mqprio_rl cleanup and free in mlx5e_priv_cleanup()
+    - Bluetooth: hci_event: Fix setting of unicast qos interval
+    - Bluetooth: Ignore too large handle values in BIG
+    - Bluetooth: ISO: Check socket flag instead of hcon
+    - bluetooth/hci: disallow setting handle bigger than HCI_CONN_HANDLE_MAX
+    - KVM: s390: fix LPSWEY handling
+    - e1000e: Fix S0ix residency on corporate systems
+    - gpiolib: of: fix lookup quirk for MIPS Lantiq
+    - net: allow skb_datagram_iter to be called from any context
+    - net: txgbe: initialize num_q_vectors for MSI/INTx interrupts
+    - net: ntb_netdev: Move ntb_netdev_rx_handler() to call netif_rx() from
+      __netif_rx()
+    - gpio: mmio: do not calculate bgpio_bits via "ngpios"
+    - wifi: wilc1000: fix ies_len type in connect path
+    - riscv: kexec: Avoid deadlock in kexec crash path
+    - netfilter: nf_tables: unconditionally flush pending work before notifier
+    - bonding: Fix out-of-bounds read in bond_option_arp_ip_targets_set()
+    - selftests: fix OOM in msg_zerocopy selftest
+    - selftests: make order checking verbose in msg_zerocopy selftest
+    - inet_diag: Initialize pad field in struct inet_diag_req_v2
+    - mlxsw: core_linecards: Fix double memory deallocation in case of invalid INI
+      file
+    - gpiolib: of: add polarity quirk for TSC2005
+    - cpu: Fix broken cmdline "nosmp" and "maxcpus=0"
+    - platform/x86: toshiba_acpi: Fix quickstart quirk handling
+    - Revert "igc: fix a log entry using uninitialized netdev"
+    - nilfs2: fix inode number range checks
+    - nilfs2: add missing check for inode numbers on directory entries
+    - mm: optimize the redundant loop of mm_update_owner_next()
+    - mm: avoid overflows in dirty throttling logic
+    - btrfs: fix adding block group to a reclaim list and the unused list during
+      reclaim
+    - scsi: mpi3mr: Use proper format specifier in mpi3mr_sas_port_add()
+    - Bluetooth: hci_bcm4377: Fix msgid release
+    - Bluetooth: qca: Fix BT enable failure again for QCA6390 after warm reboot
+    - can: kvaser_usb: Explicitly initialize family in leafimx driver_info struct
+    - fsnotify: Do not generate events for O_PATH file descriptors
+    - Revert "mm/writeback: fix possible divide-by-zero in wb_dirty_limits(),
+      again"
+    - drm/nouveau: fix null pointer dereference in nouveau_connector_get_modes
+    - drm/amdgpu/atomfirmware: silence UBSAN warning
+    - drm: panel-orientation-quirks: Add quirk for Valve Galileo
+    - clk: qcom: gcc-ipq9574: Add BRANCH_HALT_VOTED flag
+    - clk: sunxi-ng: common: Don't call hw_to_ccu_common on hw without common
+    - powerpc/pseries: Fix scv instruction crash with kexec
+    - powerpc/64s: Fix unnecessary copy to 0 when kernel is booted at address 0
+    - mtd: rawnand: Ensure ECC configuration is propagated to upper layers
+    - mtd: rawnand: Fix the nand_read_data_op() early check
+    - mtd: rawnand: Bypass a couple of sanity checks during NAND identification
+    - mtd: rawnand: rockchip: ensure NVDDR timings are rejected
+    - net: stmmac: dwmac-qcom-ethqos: fix error array size
+    - arm64: dts: rockchip: Fix the DCDC_REG2 minimum voltage on Quartz64 Model B
+    - media: dw2102: fix a potential buffer overflow
+    - clk: qcom: gcc-sm6350: Fix gpll6* & gpll7 parents
+    - clk: qcom: clk-alpha-pll: set ALPHA_EN bit for Stromer Plus PLLs
+    - clk: mediatek: mt8183: Only enable runtime PM on mt8183-mfgcfg
+    - i2c: pnx: Fix potential deadlock warning from del_timer_sync() call in isr
+    - fs/ntfs3: Mark volume as dirty if xattr is broken
+    - ALSA: hda/realtek: Enable headset mic of JP-IK LEAP W502 with ALC897
+    - vhost-scsi: Handle vhost_vq_work_queue failures for events
+    - nvme-multipath: find NUMA path only for online numa-node
+    - dma-mapping: benchmark: avoid needless copy_to_user if benchmark fails
+    - connector: Fix invalid conversion in cn_proc.h
+    - nvme: adjust multiples of NVME_CTRL_PAGE_SIZE in offset
+    - regmap-i2c: Subtract reg size from max_write
+    - platform/x86: touchscreen_dmi: Add info for GlobalSpace SolT IVW 11.6"
+      tablet
+    - platform/x86: touchscreen_dmi: Add info for the EZpad 6s Pro
+    - nvmet: fix a possible leak when destroy a ctrl during qp establishment
+    - kbuild: fix short log for AS in link-vmlinux.sh
+    - nfc/nci: Add the inconsistency check between the input data length and count
+    - spi: cadence: Ensure data lines set to low during dummy-cycle period
+    - ALSA: ump: Set default protocol when not given explicitly
+    - drm/amdgpu: silence UBSAN warning
+    - null_blk: Do not allow runt zone with zone capacity smaller then zone size
+    - nilfs2: fix incorrect inode allocation from reserved inodes
+    - leds: mlxreg: Use devm_mutex_init() for mutex initialization
+    - net: dql: Avoid calling BUG() when WARN() is enough
+    - drm/xe: Add outer runtime_pm protection to xe_live_ktest@xe_dma_buf
+    - bpf: mark bpf_dummy_struct_ops.test_1 parameter as nullable
+    - drm/amdgpu: fix double free err_addr pointer warnings
+    - drm/amd/display: Fix overlapping copy within dml_core_mode_programming
+    - drm/amd/display: update pipe topology log to support subvp
+    - drm/amd/display: Do not return negative stream id for array
+    - drm/amd/display: ASSERT when failing to find index by plane/stream id
+    - usb: xhci: prevent potential failure in handle_tx_event() for Transfer
+      events without TRB
+    - media: i2c: st-mipid02: Use the correct div function
+    - media: tc358746: Use the correct div_ function
+    - crypto: hisilicon/sec2 - fix for register offset
+    - s390/pkey: Use kfree_sensitive() to fix Coccinelle warnings
+    - s390/pkey: Wipe copies of clear-key structures on failure
+    - s390/pkey: Wipe copies of protected- and secure-keys
+    - wifi: cfg80211: restrict NL80211_ATTR_TXQ_QUANTUM values
+    - wifi: mac80211: fix BSS_CHANGED_UNSOL_BCAST_PROBE_RESP
+    - net: txgbe: remove separate irq request for MSI and INTx
+    - net: txgbe: add extra handle for MSI/INTx into thread irq handle
+    - net: txgbe: free isb resources at the right time
+    - btrfs: always do the basic checks for btrfs_qgroup_inherit structure
+    - net: phy: aquantia: add missing include guards
+    - drm/fbdev-generic: Fix framebuffer on big endian devices
+    - net: stmmac: enable HW-accelerated VLAN stripping for gmac4 only
+    - net: rswitch: Avoid use-after-free in rswitch_poll()
+    - ice: use proper macro for testing bit
+    - drm/xe/mcr: Avoid clobbering DSS steering
+    - tcp: Don't flag tcp_sk(sk)->rx_opt.saw_unknown for TCP AO.
+    - btrfs: zoned: fix calc_available_free_space() for zoned mode
+    - btrfs: fix folio refcount in __alloc_dummy_extent_buffer()
+    - Bluetooth: Add quirk to ignore reserved PHY bits in LE Extended Adv Report
+    - drm/xe: fix error handling in xe_migrate_update_pgtables
+    - drm/ttm: Always take the bo delayed cleanup path for imported bos
+    - fs: don't misleadingly warn during thaw operations
+    - drm/amdkfd: Let VRAM allocations go to GTT domain on small APUs
+    - drm/amdgpu: correct hbm field in boot status
+    - Upstream stable to v6.6.38, v6.6.39, v6.9.9
+
+  * Panels show garbage or flickering when i915.psr2 enabled (LP: #2069993)
+    - SAUCE: drm/i915/display/psr: add a psr2 disable quirk table
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x4d_0x10_0x93_0x15
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x30_0xe4_0x8b_0x07
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x30_0xe4_0x78_0x07
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x30_0xe4_0x8c_0x07
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x06_0xaf_0x9a_0xf9
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x4d_0x10_0x8f_0x15
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x06_0xaf_0xa3_0xc3
+
+  * Random flickering with Intel i915 (Gen9 GPUs in 6th-8th gen CPUs) on Linux
+    6.8 (LP: #2062951)
+    - SAUCE: iommu/intel: disable DMAR for SKL integrated gfx
+
+  * [SRU][22.04.5]: mpi3mr driver update (LP: #2073583)
+    - scsi: mpi3mr: HDB allocation and posting for hardware and firmware buffers
+    - scsi: mpi3mr: Trigger support
+    - scsi: mpi3mr: Add ioctl support for HDB
+    - scsi: mpi3mr: Support PCI Error Recovery callback handlers
+    - scsi: mpi3mr: Prevent PCI writes from driver during PCI error recovery
+    - scsi: mpi3mr: Driver version update
+
+  * Fix power consumption while using HW accelerated video decode on AMD
+    platforms (LP: #2073282)
+    - drm/amdgpu/vcn: identify unified queue in sw init
+    - drm/amdgpu/vcn: not pause dpg for unified queue
+
+  * Noble update: upstream stable patchset 2024-08-09 (LP: #2076435)
+    - usb: typec: ucsi: Never send a lone connector change ack
+    - usb: typec: ucsi: Ack also failed Get Error commands
+    - Input: ili210x - fix ili251x_read_touch_data() return value
+    - pinctrl: fix deadlock in create_pinctrl() when handling -EPROBE_DEFER
+    - pinctrl: rockchip: fix pinmux bits for RK3328 GPIO2-B pins
+    - pinctrl: rockchip: fix pinmux bits for RK3328 GPIO3-B pins
+    - pinctrl: rockchip: use dedicated pinctrl type for RK3328
+    - pinctrl: rockchip: fix pinmux reset in rockchip_pmx_set
+    - MIPS: pci: lantiq: restore reset gpio polarity
+    - ASoC: rockchip: i2s-tdm: Fix trcm mode by setting clock on right mclk
+    - ASoC: mediatek: mt8183-da7219-max98357: Fix kcontrol name collision
+    - ASoC: atmel: atmel-classd: Re-add dai_link->platform to fix card init
+    - workqueue: Increase worker desc's length to 32
+    - ASoC: q6apm-lpass-dai: close graph on prepare errors
+    - bpf: Add missed var_off setting in set_sext32_default_val()
+    - bpf: Add missed var_off setting in coerce_subreg_to_size_sx()
+    - s390/pci: Add missing virt_to_phys() for directed DIBV
+    - ASoC: amd: acp: add a null check for chip_pdev structure
+    - ASoC: amd: acp: remove i2s configuration check in acp_i2s_probe()
+    - ASoC: fsl-asoc-card: set priv->pdev before using it
+    - net: dsa: microchip: fix initial port flush problem
+    - openvswitch: get related ct labels from its master if it is not confirmed
+    - mlxsw: spectrum_buffers: Fix memory corruptions on Spectrum-4 systems
+    - ibmvnic: Free any outstanding tx skbs during scrq reset
+    - net: phy: micrel: add Microchip KSZ 9477 to the device table
+    - net: dsa: microchip: use collision based back pressure mode
+    - ice: Rebuild TC queues on VSI queue reconfiguration
+    - xdp: Remove WARN() from __xdp_reg_mem_model()
+    - netfilter: fix undefined reference to 'netfilter_lwtunnel_*' when
+      CONFIG_SYSCTL=n
+    - btrfs: use NOFS context when getting inodes during logging and log replay
+    - Fix race for duplicate reqsk on identical SYN
+    - ALSA: seq: Fix missing channel at encoding RPN/NRPN MIDI2 messages
+    - net: dsa: microchip: fix wrong register write when masking interrupt
+    - sparc: fix old compat_sys_select()
+    - sparc: fix compat recv/recvfrom syscalls
+    - parisc: use correct compat recv/recvfrom syscalls
+    - powerpc: restore some missing spu syscalls
+    - tcp: fix tcp_rcv_fastopen_synack() to enter TCP_CA_Loss for failed TFO
+    - ALSA: seq: Fix missing MSB in MIDI2 SPP conversion
+    - netfilter: nf_tables: fully validate NFT_DATA_VALUE on store to data
+      registers
+    - net: mana: Fix possible double free in error handling path
+    - drm/panel: ilitek-ili9881c: Fix warning with GPIO controllers that sleep
+    - vduse: validate block features only with block devices
+    - vduse: Temporarily fail if control queue feature requested
+    - x86/fpu: Fix AMD X86_BUG_FXSAVE_LEAK fixup
+    - mtd: partitions: redboot: Added conversion of operands to a larger type
+    - wifi: ieee80211: check for NULL in ieee80211_mle_size_ok()
+    - bpf: Mark bpf prog stack with kmsan_unposion_memory in interpreter mode
+    - RDMA/restrack: Fix potential invalid address access
+    - net/iucv: Avoid explicit cpumask var allocation on stack
+    - net/dpaa2: Avoid explicit cpumask var allocation on stack
+    - crypto: ecdh - explicitly zeroize private_key
+    - ALSA: emux: improve patch ioctl data validation
+    - media: dvbdev: Initialize sbuf
+    - irqchip/loongson: Select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP for
+      IRQ_LOONGARCH_CPU
+    - soc: ti: wkup_m3_ipc: Send NULL dummy message instead of pointer message
+    - gfs2: Fix NULL pointer dereference in gfs2_log_flush
+    - drm/radeon/radeon_display: Decrease the size of allocated memory
+    - nvme: fixup comment for nvme RDMA Provider Type
+    - drm/panel: simple: Add missing display timing flags for KOE TX26D202VM0BWA
+    - gpio: davinci: Validate the obtained number of IRQs
+    - RISC-V: fix vector insn load/store width mask
+    - drm/amdgpu: Fix pci state save during mode-1 reset
+    - riscv: stacktrace: convert arch_stack_walk() to noinstr
+    - gpiolib: cdev: Disallow reconfiguration without direction (uAPI v1)
+    - randomize_kstack: Remove non-functional per-arch entropy filtering
+    - x86: stop playing stack games in profile_pc()
+    - parisc: use generic sys_fanotify_mark implementation
+    - Revert "MIPS: pci: lantiq: restore reset gpio polarity"
+    - pinctrl: qcom: spmi-gpio: drop broken pm8008 support
+    - ocfs2: fix DIO failure due to insufficient transaction credits
+    - nfs: drop the incorrect assertion in nfs_swap_rw()
+    - mm: fix incorrect vbq reference in purge_fragmented_block
+    - mmc: sdhci-pci-o2micro: Convert PCIBIOS_* return codes to errnos
+    - mmc: sdhci-brcmstb: check R1_STATUS for erase/trim/discard
+    - mmc: sdhci-pci: Convert PCIBIOS_* return codes to errnos
+    - mmc: sdhci: Do not invert write-protect twice
+    - mmc: sdhci: Do not lock spinlock around mmc_gpio_get_ro()
+    - iio: xilinx-ams: Don't include ams_ctrl_channels in scan_mask
+    - counter: ti-eqep: enable clock at probe
+    - kbuild: doc: Update default INSTALL_MOD_DIR from extra to updates
+    - kbuild: Fix build target deb-pkg: ln: failed to create hard link
+    - i2c: testunit: don't erase registers after STOP
+    - i2c: testunit: discard write requests while old command is running
+    - ata: libata-core: Fix null pointer dereference on error
+    - ata,scsi: libata-core: Do not leak memory for ata_port struct members
+    - iio: adc: ad7266: Fix variable checking bug
+    - iio: accel: fxls8962af: select IIO_BUFFER & IIO_KFIFO_BUF
+    - iio: chemical: bme680: Fix pressure value output
+    - iio: chemical: bme680: Fix calibration data variable
+    - iio: chemical: bme680: Fix overflows in compensate() functions
+    - iio: chemical: bme680: Fix sensor data read operation
+    - net: usb: ax88179_178a: improve link status logs
+    - usb: gadget: printer: SS+ support
+    - usb: gadget: printer: fix races against disable
+    - usb: musb: da8xx: fix a resource leak in probe()
+    - usb: atm: cxacru: fix endpoint checking in cxacru_bind()
+    - usb: dwc3: core: remove lock of otg mode during gadget suspend/resume to
+      avoid deadlock
+    - usb: gadget: aspeed_udc: fix device address configuration
+    - usb: typec: ucsi: glink: fix child node release in probe function
+    - usb: ucsi: stm32: fix command completion handling
+    - usb: dwc3: core: Add DWC31 version 2.00a controller
+    - usb: dwc3: core: Workaround for CSR read timeout
+    - Revert "serial: core: only stop transmit when HW fifo is empty"
+    - serial: 8250_omap: Implementation of Errata i2310
+    - serial: imx: set receiver level before starting uart
+    - serial: core: introduce uart_port_tx_limited_flags()
+    - serial: bcm63xx-uart: fix tx after conversion to uart_port_tx_limited()
+    - tty: mcf: MCF54418 has 10 UARTS
+    - net: can: j1939: Initialize unused data in j1939_send_one()
+    - net: can: j1939: recover socket queue on CAN bus error during BAM
+      transmission
+    - net: can: j1939: enhanced error handling for tightly received RTS messages
+      in xtp_rx_rts_session_new
+    - PCI/MSI: Fix UAF in msi_capability_init
+    - cpufreq: intel_pstate: Use HWP to initialize ITMT if CPPC is missing
+    - irqchip/loongson-eiointc: Use early_cpu_to_node() instead of cpu_to_node()
+    - cpu/hotplug: Fix dynstate assignment in __cpuhp_setup_state_cpuslocked()
+    - irqchip/loongson-liointc: Set different ISRs for different cores
+    - kbuild: Install dtb files as 0644 in Makefile.dtbinst
+    - sh: rework sync_file_range ABI
+    - btrfs: zoned: fix initial free space detection
+    - csky, hexagon: fix broken sys_sync_file_range
+    - hexagon: fix fadvise64_64 calling conventions
+    - drm/drm_file: Fix pid refcounting race
+    - drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_ld_modes
+    - drm/fbdev-dma: Only set smem_start is enable per module option
+    - drm/amdgpu: avoid using null object of framebuffer
+    - drm/i915/gt: Fix potential UAF by revoke of fence registers
+    - drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_hd_modes
+    - drm/amd/display: Send DP_TOTAL_LTTPR_CNT during detection if LTTPR is
+      present
+    - drm/amdgpu/atomfirmware: fix parsing of vram_info
+    - batman-adv: Don't accept TT entries for out-of-spec VIDs
+    - can: mcp251xfd: fix infinite loop when xmit fails
+    - ata: ahci: Clean up sysfs file on error
+    - ata: libata-core: Fix double free on error
+    - ftruncate: pass a signed offset
+    - syscalls: fix compat_sys_io_pgetevents_time64 usage
+    - syscalls: fix sys_fanotify_mark prototype
+    - Revert "cpufreq: amd-pstate: Fix the inconsistency in max frequency units"
+    - mm/page_alloc: Separate THP PCP into movable and non-movable categories
+    - arm64: dts: rockchip: Fix SD NAND and eMMC init on rk3308-rock-pi-s
+    - arm64: dts: rockchip: Rename LED related pinctrl nodes on rk3308-rock-pi-s
+    - arm64: dts: rockchip: Fix the value of `dlg,jack-det-rate` mismatch on
+      rk3399-gru
+    - ARM: dts: rockchip: rk3066a: add #sound-dai-cells to hdmi node
+    - arm64: dts: rockchip: make poweroff(8) work on Radxa ROCK 5A
+    - arm64: dts: rockchip: fix PMIC interrupt pin on ROCK Pi E
+    - arm64: dts: rockchip: Add sound-dai-cells for RK3368
+    - cxl/region: Move cxl_dpa_to_region() work to the region driver
+    - cxl/region: Avoid null pointer dereference in region lookup
+    - cxl/region: check interleave capability
+    - serial: imx: only set receiver level if it is zero
+    - serial: 8250_omap: Fix Errata i2310 with RX FIFO level check
+    - tracing/net_sched: NULL pointer dereference in perf_trace_qdisc_reset()
+    - pwm: stm32: Improve precision of calculation in .apply()
+    - pwm: stm32: Fix for settings using period > UINT32_MAX
+    - pwm: stm32: Calculate prescaler with a division instead of a loop
+    - pwm: stm32: Refuse too small period requests
+    - ASoC: cs42l43: Increase default type detect time and button delay
+    - ASoC: amd: acp: move chip->flag variable assignment
+    - bonding: fix incorrect software timestamping report
+    - mlxsw: pci: Fix driver initialization with Spectrum-4
+    - vxlan: Pull inner IP header in vxlan_xmit_one().
+    - ASoC: mediatek: mt8195: Add platform entry for ETDM1_OUT_BE dai link
+    - af_unix: Stop recv(MSG_PEEK) at consumed OOB skb.
+    - af_unix: Don't stop recv(MSG_DONTWAIT) if consumed OOB skb is at the head.
+    - af_unix: Don't stop recv() at consumed ex-OOB skb.
+    - af_unix: Fix wrong ioctl(SIOCATMARK) when consumed OOB skb is at the head.
+    - bpf: Take return from set_memory_ro() into account with bpf_prog_lock_ro()
+    - bpf: Take return from set_memory_rox() into account with
+      bpf_jit_binary_lock_ro()
+    - drm/xe: Fix potential integer overflow in page size calculation
+    - drm/xe: Add a NULL check in xe_ttm_stolen_mgr_init
+    - drm/amd/display: correct hostvm flag
+    - drm/amd/display: Skip pipe if the pipe idx not set properly
+    - bpf: Add a check for struct bpf_fib_lookup size
+    - drm/xe/xe_devcoredump: Check NULL before assignments
+    - iommu/arm-smmu-v3: Do not allow a SVA domain to be set on the wrong PASID
+    - evm: Enforce signatures on unsupported filesystem for EVM_INIT_X509
+    - drm/xe: Check pat.ops before dumping PAT settings
+    - nvmet: do not return 'reserved' for empty TSAS values
+    - nvmet: make 'tsas' attribute idempotent for RDMA
+    - iommu/amd: Fix GT feature enablement again
+    - gpiolib: cdev: Ignore reconfiguration without direction
+    - kasan: fix bad call to unpoison_slab_object
+    - mm/memory: don't require head page for do_set_pmd()
+    - SUNRPC: Fix backchannel reply, again
+    - Revert "usb: gadget: u_ether: Re-attach netif device to mirror detachment"
+    - Revert "usb: gadget: u_ether: Replace netif_stop_queue with
+      netif_device_detach"
+    - tty: serial: 8250: Fix port count mismatch with the device
+    - tty: mxser: Remove __counted_by from mxser_board.ports[]
+    - nvmet-fc: Remove __counted_by from nvmet_fc_tgt_queue.fod[]
+    - ata: libata-core: Add ATA_HORKAGE_NOLPM for all Crucial BX SSD1 models
+    - bcachefs: Fix sb_field_downgrade validation
+    - bcachefs: Fix sb-downgrade validation
+    - bcachefs: Fix bch2_sb_downgrade_update()
+    - bcachefs: Fix setting of downgrade recovery passes/errors
+    - bcachefs: btree_gc can now handle unknown btrees
+    - pwm: stm32: Fix calculation of prescaler
+    - pwm: stm32: Fix error message to not describe the previous error path
+    - cxl/region: Convert cxl_pmem_region_alloc to scope-based resource management
+    - cxl/mem: Fix no cxl_nvd during pmem region auto-assembling
+    - arm64: dts: rockchip: Fix the i2c address of es8316 on Cool Pi 4B
+    - netfs: Fix netfs_page_mkwrite() to check folio->mapping is valid
+    - netfs: Fix netfs_page_mkwrite() to flush conflicting data, not wait
+    - Upstream stable to v6.6.37, v6.9.8
+
+  * [UBUNTU 22.04] s390/cpum_cf: make crypto counters upward compatible
+    (LP: #2074380)
+    - s390/cpum_cf: make crypto counters upward compatible across machine types
+
+  * CVE-2024-45016
+    - netem: fix return value if duplicate enqueue fails
+
+ -- Stefan Bader <stefan.bader@canonical.com>  Fri, 27 Sep 2024 14:22:35 +0200
+
+linux (6.8.0-45.45) noble; urgency=medium
+
+  * noble/linux: 6.8.0-45.45 -proposed tracker (LP: #2078100)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/s2024.08.05)
+
+  * Noble update: upstream stable patchset 2024-08-09 (LP: #2076435) //
+    CVE-2024-41009
+    - bpf: Fix overrunning reservations in ringbuf
+
+  * CVE-2024-42160
+    - f2fs: check validation of fault attrs in f2fs_build_fault_attr()
+    - f2fs: Add inline to f2fs_build_fault_attr() stub
+
+  * Noble update: upstream stable patchset 2024-08-22 (LP: #2077600) //
+    CVE-2024-42224
+    - net: dsa: mv88e6xxx: Correct check for empty list
+
+  * Noble update: upstream stable patchset 2024-08-22 (LP: #2077600) //
+    CVE-2024-42154
+    - tcp_metrics: validate source addr length
+
+  * CVE-2024-42228
+    - drm/amdgpu: Using uninitialized value *size when calling amdgpu_vce_cs_reloc
+
+  * CVE-2024-42159
+    - scsi: mpi3mr: Sanitise num_phys
+
+ -- Manuel Diewald <manuel.diewald@canonical.com>  Fri, 30 Aug 2024 10:32:37 +0200
+
+linux (6.8.0-44.44) noble; urgency=medium
+
+  * noble/linux: 6.8.0-44.44 -proposed tracker (LP: #2076647)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2024.08.05)
+
+  * Disable PCI_DYNAMIC_OF_NODES in Ubuntu (LP: #2074376)
+    - [Config] Disable PCI_DYNAMIC_OF_NODES
+
+  * [SRU] Turbostat support for Arrow Lake H (LP: #2074372)
+    - tools/power turbostat: Enhance ARL/LNL support
+    - x86/cpu: Add model number for another Intel Arrow Lake mobile processor
+    - tools/power turbostat: Add ARL-H support
+
+  * Noble update: upstream stable patchset 2024-07-30 (LP: #2075154)
+    - fs/writeback: bail out if there is no more inodes for IO and queued once
+    - padata: Disable BH when taking works lock on MT path
+    - crypto: hisilicon/sec - Fix memory leak for sec resource release
+    - crypto: hisilicon/qm - Add the err memory release process to qm uninit
+    - io_uring/sqpoll: work around a potential audit memory leak
+    - rcutorture: Fix rcu_torture_one_read() pipe_count overflow comment
+    - rcutorture: Make stall-tasks directly exit when rcutorture tests end
+    - rcutorture: Fix invalid context warning when enable srcu barrier testing
+    - block/ioctl: prefer different overflow check
+    - ssb: Fix potential NULL pointer dereference in ssb_device_uevent()
+    - selftests/bpf: Prevent client connect before server bind in
+      test_tc_tunnel.sh
+    - selftests/bpf: Fix flaky test btf_map_in_map/lookup_update
+    - batman-adv: bypass empty buckets in batadv_purge_orig_ref()
+    - wifi: ath9k: work around memset overflow warning
+    - af_packet: avoid a false positive warning in packet_setsockopt()
+    - ACPI: x86: Add PNP_UART1_SKIP quirk for Lenovo Blade2 tablets
+    - drop_monitor: replace spin_lock by raw_spin_lock
+    - scsi: qedi: Fix crash while reading debugfs attribute
+    - net: sfp: add quirk for ATS SFP-GE-T 1000Base-TX module
+    - net/sched: fix false lockdep warning on qdisc root lock
+    - kselftest: arm64: Add a null pointer check
+    - net: dsa: realtek: keep default LED state in rtl8366rb
+    - netpoll: Fix race condition in netpoll_owner_active
+    - wifi: mt76: mt7921s: fix potential hung tasks during chip recovery
+    - HID: Add quirk for Logitech Casa touchpad
+    - HID: asus: fix more n-key report descriptors if n-key quirked
+    - ACPI: video: Add backlight=native quirk for Lenovo Slim 7 16ARH7
+    - Bluetooth: ath3k: Fix multiple issues reported by checkpatch.pl
+    - drm/amd/display: Exit idle optimizations before HDCP execution
+    - platform/x86: toshiba_acpi: Add quirk for buttons on Z830
+    - ASoC: Intel: sof_sdw: add JD2 quirk for HP Omen 14
+    - ASoC: Intel: sof_sdw: add quirk for Dell SKU 0C0F
+    - drm/lima: add mask irq callback to gp and pp
+    - drm/lima: mask irqs in timeout path before hard reset
+    - ALSA: hda/realtek: Add quirks for Lenovo 13X
+    - powerpc/pseries: Enforce hcall result buffer validity and size
+    - media: intel/ipu6: Fix build with !ACPI
+    - media: mtk-vcodec: potential null pointer deference in SCP
+    - powerpc/io: Avoid clang null pointer arithmetic warnings
+    - platform/x86: p2sb: Don't init until unassigned resources have been assigned
+    - power: supply: cros_usbpd: provide ID table for avoiding fallback match
+    - iommu/arm-smmu-v3: Free MSIs in case of ENOMEM
+    - ext4: fix uninitialized ratelimit_state->lock access in __ext4_fill_super()
+    - kprobe/ftrace: bail out if ftrace was killed
+    - usb: gadget: uvc: configfs: ensure guid to be valid before set
+    - f2fs: remove clear SB_INLINECRYPT flag in default_options
+    - usb: misc: uss720: check for incompatible versions of the Belkin F5U002
+    - Avoid hw_desc array overrun in dw-axi-dmac
+    - usb: dwc3: pci: Don't set "linux,phy_charger_detect" property on Lenovo Yoga
+      Tab2 1380
+    - usb: typec: ucsi_glink: drop special handling for CCI_BUSY
+    - udf: udftime: prevent overflow in udf_disk_stamp_to_time()
+    - PCI/PM: Avoid D3cold for HP Pavilion 17 PC/1972 PCIe Ports
+    - f2fs: don't set RO when shutting down f2fs
+    - MIPS: Octeon: Add PCIe link status check
+    - serial: imx: Introduce timeout when waiting on transmitter empty
+    - serial: exar: adding missing CTI and Exar PCI ids
+    - usb: gadget: function: Remove usage of the deprecated ida_simple_xx() API
+    - tty: add the option to have a tty reject a new ldisc
+    - vfio/pci: Collect hot-reset devices to local buffer
+    - cpufreq: amd-pstate: fix memory leak on CPU EPP exit
+    - ACPI: EC: Install address space handler at the namespace root
+    - PCI: Do not wait for disconnected devices when resuming
+    - ALSA: hda: cs35l41: Possible null pointer dereference in
+      cs35l41_hda_unbind()
+    - ALSA: seq: ump: Fix missing System Reset message handling
+    - MIPS: Routerboard 532: Fix vendor retry check code
+    - mips: bmips: BCM6358: make sure CBR is correctly set
+    - tracing: Build event generation tests only as modules
+    - ALSA: hda/realtek: Remove Framework Laptop 16 from quirks
+    - ALSA/hda: intel-dsp-config: Document AVS as dsp_driver option
+    - ice: avoid IRQ collision to fix init failure on ACPI S3 resume
+    - btrfs: zoned: allocate dummy checksums for zoned NODATASUM writes
+    - net: mvpp2: use slab_build_skb for oversized frames
+    - cipso: fix total option length computation
+    - ALSA: hda: cs35l56: Component should be unbound before deconstruction
+    - ALSA: hda: tas2781: Component should be unbound before deconstruction
+    - bpf: Avoid splat in pskb_pull_reason
+    - ALSA: hda/realtek: Enable headset mic on IdeaPad 330-17IKB 81DM
+    - netrom: Fix a memory leak in nr_heartbeat_expiry()
+    - ipv6: prevent possible NULL deref in fib6_nh_init()
+    - ipv6: prevent possible NULL dereference in rt6_probe()
+    - xfrm6: check ip6_dst_idev() return value in xfrm6_get_saddr()
+    - netns: Make get_net_ns() handle zero refcount net
+    - qca_spi: Make interrupt remembering atomic
+    - net: lan743x: disable WOL upon resume to restore full data path operation
+    - net: lan743x: Support WOL at both the PHY and MAC appropriately
+    - net: phy: mxl-gpy: Remove interrupt mask clearing from config_init
+    - net/sched: act_api: fix possible infinite loop in tcf_idr_check_alloc()
+    - tipc: force a dst refcount before doing decryption
+    - sched: act_ct: add netns into the key of tcf_ct_flow_table
+    - ptp: fix integer overflow in max_vclocks_store
+    - selftests: openvswitch: Use bash as interpreter
+    - net: stmmac: No need to calculate speed divider when offload is disabled
+    - virtio_net: checksum offloading handling fix
+    - virtio_net: fixing XDP for fully checksummed packets handling
+    - octeontx2-pf: Add error handling to VLAN unoffload handling
+    - octeontx2-pf: Fix linking objects into multiple modules
+    - netfilter: ipset: Fix suspicious rcu_dereference_protected()
+    - seg6: fix parameter passing when calling NF_HOOK() in End.DX4 and End.DX6
+      behaviors
+    - netfilter: move the sysctl nf_hooks_lwtunnel into the netfilter core
+    - ice: Fix VSI list rule with ICE_SW_LKUP_LAST type
+    - bnxt_en: Restore PTP tx_avail count in case of skb_pad() error
+    - net: usb: rtl8150 fix unintiatilzed variables in rtl8150_get_link_ksettings
+    - RDMA/bnxt_re: Fix the max msix vectors macro
+    - spi: cs42l43: Correct SPI root clock speed
+    - RDMA/rxe: Fix responder length checking for UD request packets
+    - regulator: core: Fix modpost error "regulator_get_regmap" undefined
+    - dmaengine: idxd: Fix possible Use-After-Free in irq_process_work_list
+    - dmaengine: ioatdma: Fix leaking on version mismatch
+    - dmaengine: ioatdma: Fix error path in ioat3_dma_probe()
+    - dmaengine: ioatdma: Fix kmemleak in ioat_pci_probe()
+    - dmaengine: fsl-edma: avoid linking both modules
+    - dmaengine: ioatdma: Fix missing kmem_cache_destroy()
+    - regulator: bd71815: fix ramp values
+    - thermal/drivers/mediatek/lvts_thermal: Return error in case of invalid efuse
+      data
+    - arm64: dts: imx8mp: Fix TC9595 input clock on DH i.MX8M Plus DHCOM SoM
+    - arm64: dts: freescale: imx8mp-venice-gw73xx-2x: fix BT shutdown GPIO
+    - arm64: dts: imx93-11x11-evk: Remove the 'no-sdio' property
+    - arm64: dts: freescale: imx8mm-verdin: enable hysteresis on slow input pin
+    - ACPICA: Revert "ACPICA: avoid Info: mapping multiple BARs. Your kernel is
+      fine."
+    - spi: spi-imx: imx51: revert burst length calculation back to bits_per_word
+    - io_uring/rsrc: fix incorrect assignment of iter->nr_segs in io_import_fixed
+    - firmware: psci: Fix return value from psci_system_suspend()
+    - RDMA/mlx5: Fix unwind flow as part of mlx5_ib_stage_init_init
+    - RDMA/mlx5: Add check for srq max_sge attribute
+    - RDMA/mana_ib: Ignore optional access flags for MRs
+    - ACPI: EC: Evaluate orphan _REG under EC device
+    - arm64: defconfig: enable the vf610 gpio driver
+    - ext4: avoid overflow when setting values via sysfs
+    - ext4: fix slab-out-of-bounds in ext4_mb_find_good_group_avg_frag_lists()
+    - net: stmmac: Assign configured channel value to EXTTS event
+    - net: usb: ax88179_178a: improve reset check
+    - net: do not leave a dangling sk pointer, when socket creation fails
+    - btrfs: retry block group reclaim without infinite loop
+    - scsi: ufs: core: Free memory allocated for model before reinit
+    - cifs: fix typo in module parameter enable_gcm_256
+    - LoongArch: Fix watchpoint setting error
+    - LoongArch: Trigger user-space watchpoints correctly
+    - LoongArch: Fix multiple hardware watchpoint issues
+    - KVM: Fix a data race on last_boosted_vcpu in kvm_vcpu_on_spin()
+    - KVM: arm64: Disassociate vcpus from redistributor region on teardown
+    - KVM: x86: Always sync PIR to IRR prior to scanning I/O APIC routes
+    - RDMA/rxe: Fix data copy for IB_SEND_INLINE
+    - RDMA/mlx5: Remove extra unlock on error path
+    - RDMA/mlx5: Follow rb_key.ats when creating new mkeys
+    - ovl: fix encoding fid for lower only root
+    - ALSA: hda/realtek: Limit mic boost on N14AP7
+    - ALSA: hda/realtek: Add quirk for Lenovo Yoga Pro 7 14AHP9
+    - drm/i915/mso: using joiner is not possible with eDP MSO
+    - drm/radeon: fix UBSAN warning in kv_dpm.c
+    - drm/amdgpu: fix UBSAN warning in kv_dpm.c
+    - dt-bindings: dma: fsl-edma: fix dma-channels constraints
+    - ocfs2: fix NULL pointer dereference in ocfs2_journal_dirty()
+    - ocfs2: fix NULL pointer dereference in ocfs2_abort_trigger()
+    - gcov: add support for GCC 14
+    - kcov: don't lose track of remote references during softirqs
+    - efi/x86: Free EFI memory map only when installing a new one.
+    - serial: 8250_dw: Revert "Move definitions to the shared header"
+    - mm: mmap: allow for the maximum number of bits for randomizing mmap_base by
+      default
+    - tcp: clear tp->retrans_stamp in tcp_rcv_fastopen_synack()
+    - mm/page_table_check: fix crash on ZONE_DEVICE
+    - i2c: ocores: set IACK bit after core is enabled
+    - dt-bindings: i2c: atmel,at91sam: correct path to i2c-controller schema
+    - dt-bindings: i2c: google,cros-ec-i2c-tunnel: correct path to i2c-controller
+      schema
+    - spi: stm32: qspi: Fix dual flash mode sanity test in stm32_qspi_setup()
+    - arm64: dts: imx8qm-mek: fix gpio number for reg_usdhc2_vmmc
+    - spi: stm32: qspi: Clamp stm32_qspi_get_mode() output to CCR_BUSWIDTH_4
+    - perf: script: add raw|disasm arguments to --insn-trace option
+    - nbd: Improve the documentation of the locking assumptions
+    - nbd: Fix signal handling
+    - tracing: Add MODULE_DESCRIPTION() to preemptirq_delay_test
+    - x86/cpu/vfm: Add new macros to work with (vendor/family/model) values
+    - x86/cpu: Fix x86_match_cpu() to match just X86_VENDOR_INTEL
+    - drm/amd/display: revert Exit idle optimizations before HDCP execution
+    - ASoC: Intel: sof-sdw: really remove FOUR_SPEAKER quirk
+    - net/sched: unregister lockdep keys in qdisc_create/qdisc_alloc error path
+    - kprobe/ftrace: fix build error due to bad function definition
+    - hid: asus: asus_report_fixup: fix potential read out of bounds
+    - Revert "mm: mmap: allow for the maximum number of bits for randomizing
+      mmap_base by default"
+    - platform/chrome: cros_usbpd_logger: provide ID table for avoiding fallback
+      match
+    - platform/chrome: cros_usbpd_notify: provide ID table for avoiding fallback
+      match
+    - ubsan: Avoid i386 UBSAN handler crashes with Clang
+    - arm64: defconfig: select INTERCONNECT_QCOM_SM6115 as built-in
+    - bpf: Avoid kfree_rcu() under lock in bpf_lpm_trie.
+    - devlink: use kvzalloc() to allocate devlink instance resources
+    - wifi: rtw89: 8852c: add quirk to set PCI BER for certain platforms
+    - clocksource: Make watchdog and suspend-timing multiplication overflow safe
+    - ACPI: resource: Do IRQ override on GMxBGxx (XMG APEX 17 M23)
+    - wifi: ath12k: add string type to search board data in board-2.bin for
+      WCN7850
+    - wifi: ath12k: add firmware-2.bin support
+    - wifi: ath12k: fix kernel crash during resume
+    - arm64/sysreg: Update PIE permission encodings
+    - ACPI: resource: Skip IRQ override on Asus Vivobook Pro N6506MV
+    - wifi: ath12k: fix the problem that down grade phy mode operation
+    - bpf: avoid uninitialized warnings in verifier_global_subprogs.c
+    - selftests: net: fix timestamp not arriving in cmsg_time.sh
+    - net: ena: Add validation for completion descriptors consistency
+    - drm/amd/display: Workaround register access in idle race with cursor
+    - cgroup/cpuset: Make cpuset hotplug processing synchronous
+    - platform/x86: x86-android-tablets: Unregister devices in reverse order
+    - platform/x86: x86-android-tablets: Add Lenovo Yoga Tablet 2 Pro 1380F/L data
+    - ALSA: hda/realtek: Add quirks for HP Omen models using CS35L41
+    - ext4: fold quota accounting into ext4_xattr_inode_lookup_create()
+    - ext4: do not create EA inode under buffer lock
+    - f2fs: fix to detect inconsistent nat entry during truncation
+    - usb: typec: ucsi_glink: rework quirks implementation
+    - xhci: remove XHCI_TRUST_TX_LENGTH quirk
+    - clk: Add a devm variant of clk_rate_exclusive_get()
+    - clk: Provide !COMMON_CLK dummy for devm_clk_rate_exclusive_get()
+    - i2c: lpi2c: Avoid calling clk_get_rate during transfer
+    - cxl: Add post-reset warning if reset results in loss of previously committed
+      HDM decoders
+    - OPP: Fix required_opp_tables for multiple genpds using same table
+    - wifi: iwlwifi: mvm: fix ROC version check
+    - wifi: mac80211: Recalc offload when monitor stop
+    - ice: fix 200G link speed message log
+    - ice: implement AQ download pkg retry
+    - bpf: Fix reg_set_min_max corruption of fake_reg
+    - ALSA: hda: cs35l41: Component should be unbound before deconstruction
+    - netdev-genl: fix error codes when outputting XDP features
+    - arm64: dts: freescale: imx8mm-verdin: Fix GPU speed
+    - phy: qcom-qmp: qserdes-txrx: Add missing registers offsets
+    - phy: qcom-qmp: pcs: Add missing v6 N4 register offsets
+    - phy: qcom: qmp-combo: Switch from V6 to V6 N4 register offsets
+    - powerpc/crypto: Add generated P8 asm to .gitignore
+    - spi: Exctract spi_dev_check_cs() helper
+    - spi: Fix SPI slave probe failure
+    - net: phy: dp83tg720: wake up PHYs in managed mode
+    - net: phy: dp83tg720: get master/slave configuration in link down state
+    - RDMA/mlx5: Ensure created mkeys always have a populated rb_key
+    - drm/amdgpu: fix locking scope when flushing tlb
+    - drm/amd/display: Remove redundant idle optimization check
+    - drm/amd/display: Attempt to avoid empty TUs when endpoint is DPIA
+    - ata: ahci: Do not enable LPM if no LPM states are supported by the HBA
+    - dmaengine: xilinx: xdma: Fix data synchronisation in xdma_channel_isr()
+    - net/tcp_ao: Don't leak ao_info on error-path
+    - mm: shmem: fix getting incorrect lruvec when replacing a shmem folio
+    - selftests: mptcp: print_test out of verify_listener_events
+    - selftests: mptcp: userspace_pm: fixed subtest names
+    - ima: Avoid blocking in RCU read-side critical section
+    - virt: guest_memfd: fix reference leak on hwpoisoned page
+    - thermal: int340x: processor_thermal: Support shared interrupts
+    - thermal: core: Change PM notifier priority to the minimum
+    - wifi: ath12k: check M3 buffer size as well whey trying to reuse it
+    - Upstream stable to v6.6.36, v6.9.7
+
+  * [SRU] Add Dynamic Tuning Technology (DTT)  support for Lunar Lake
+    (LP: #2073961)
+    - thermal: int340x: processor_thermal: Add Lunar Lake-M PCI ID
+
+  * Kubuntu 24.04 freezes after plugging in ethernet cable (LP: #2073358)
+    - e1000e: move force SMBUS near the end of enable_ulp function
+    - e1000e: fix force smbus during suspend flow
+
+  * Noble update: upstream stable patchset 2024-07-25 (LP: #2074091)
+    - wifi: mac80211: mesh: Fix leak of mesh_preq_queue objects
+    - wifi: mac80211: Fix deadlock in ieee80211_sta_ps_deliver_wakeup()
+    - wifi: cfg80211: fully move wiphy work to unbound workqueue
+    - wifi: cfg80211: Lock wiphy in cfg80211_get_station
+    - wifi: cfg80211: pmsr: use correct nla_get_uX functions
+    - wifi: iwlwifi: mvm: don't initialize csa_work twice
+    - wifi: iwlwifi: mvm: revert gen2 TX A-MPDU size to 64
+    - wifi: iwlwifi: mvm: set properly mac header
+    - wifi: iwlwifi: dbg_ini: move iwl_dbg_tlv_free outside of debugfs ifdef
+    - wifi: iwlwifi: mvm: check n_ssids before accessing the ssids
+    - wifi: iwlwifi: mvm: don't read past the mfuart notifcation
+    - wifi: mac80211: correctly parse Spatial Reuse Parameter Set element
+    - scsi: ufs: mcq: Fix error output and clean up ufshcd_mcq_abort()
+    - RISC-V: KVM: No need to use mask when hart-index-bit is 0
+    - RISC-V: KVM: Fix incorrect reg_subtype labels in
+      kvm_riscv_vcpu_set_reg_isa_ext function
+    - ax25: Fix refcount imbalance on inbound connections
+    - ax25: Replace kfree() in ax25_dev_free() with ax25_dev_put()
+    - net/ncsi: Fix the multi thread manner of NCSI driver
+    - net: phy: micrel: fix KSZ9477 PHY issues after suspend/resume
+    - bpf: Fix a potential use-after-free in bpf_link_free()
+    - KVM: SEV-ES: Disallow SEV-ES guests when X86_FEATURE_LBRV is absent
+    - KVM: SEV-ES: Delegate LBR virtualization to the processor
+    - vmxnet3: disable rx data ring on dma allocation failure
+    - ipv6: ioam: block BH from ioam6_output()
+    - ipv6: sr: block BH in seg6_output_core() and seg6_input_core()
+    - net: tls: fix marking packets as decrypted
+    - bpf: Set run context for rawtp test_run callback
+    - octeontx2-af: Always allocate PF entries from low prioriy zone
+    - net/smc: avoid overwriting when adjusting sock bufsizes
+    - net: phy: Micrel KSZ8061: fix errata solution not taking effect problem
+    - net: sched: sch_multiq: fix possible OOB write in multiq_tune()
+    - vxlan: Fix regression when dropping packets due to invalid src addresses
+    - tcp: count CLOSE-WAIT sockets for TCP_MIB_CURRESTAB
+    - mptcp: count CLOSE-WAIT sockets for MPTCP_MIB_CURRESTAB
+    - net/mlx5: Stop waiting for PCI if pci channel is offline
+    - net/mlx5: Always stop health timer during driver removal
+    - net/mlx5: Fix tainted pointer delete is case of flow rules creation fail
+    - net/sched: taprio: always validate TCA_TAPRIO_ATTR_PRIOMAP
+    - ptp: Fix error message on failed pin verification
+    - ice: fix iteration of TLVs in Preserved Fields Area
+    - ice: remove af_xdp_zc_qps bitmap
+    - ice: add flag to distinguish reset from .ndo_bpf in XDP rings config
+    - net: wwan: iosm: Fix tainted pointer delete is case of region creation fail
+    - af_unix: Set sk->sk_state under unix_state_lock() for truly disconencted
+      peer.
+    - af_unix: Annodate data-races around sk->sk_state for writers.
+    - af_unix: Annotate data-race of sk->sk_state in unix_inq_len().
+    - af_unix: Annotate data-races around sk->sk_state in unix_write_space() and
+      poll().
+    - af_unix: Annotate data-race of sk->sk_state in unix_stream_connect().
+    - af_unix: Annotate data-races around sk->sk_state in sendmsg() and recvmsg().
+    - af_unix: Annotate data-race of sk->sk_state in unix_stream_read_skb().
+    - af_unix: Annotate data-races around sk->sk_state in UNIX_DIAG.
+    - af_unix: Annotate data-races around sk->sk_sndbuf.
+    - af_unix: Annotate data-race of net->unx.sysctl_max_dgram_qlen.
+    - af_unix: Use unix_recvq_full_lockless() in unix_stream_connect().
+    - af_unix: Use skb_queue_empty_lockless() in unix_release_sock().
+    - af_unix: Use skb_queue_len_lockless() in sk_diag_show_rqlen().
+    - af_unix: Annotate data-race of sk->sk_shutdown in sk_diag_fill().
+    - ipv6: fix possible race in __fib6_drop_pcpu_from()
+    - net: ethtool: fix the error condition in ethtool_get_phy_stats_ethtool()
+    - selftests/mm: log a consistent test name for check_compaction
+    - irqchip/riscv-intc: Allow large non-standard interrupt number
+    - irqchip/riscv-intc: Introduce Andes hart-level interrupt controller
+    - eventfs: Update all the eventfs_inodes from the events descriptor
+    - io_uring/rsrc: don't lock while !TASK_RUNNING
+    - io_uring: check for non-NULL file pointer in io_file_can_poll()
+    - USB: class: cdc-wdm: Fix CPU lockup caused by excessive log messages
+    - USB: xen-hcd: Traverse host/ when CONFIG_USB_XEN_HCD is selected
+    - usb: typec: tcpm: fix use-after-free case in tcpm_register_source_caps
+    - usb: typec: tcpm: Ignore received Hard Reset in TOGGLING state
+    - mei: me: release irq in mei_me_pci_resume error path
+    - tty: n_tty: Fix buffer offsets when lookahead is used
+    - serial: port: Don't block system suspend even if bytes are left to xmit
+    - landlock: Fix d_parent walk
+    - jfs: xattr: fix buffer overflow for invalid xattr
+    - xhci: Set correct transferred length for cancelled bulk transfers
+    - xhci: Apply reset resume quirk to Etron EJ188 xHCI host
+    - xhci: Handle TD clearing for multiple streams case
+    - xhci: Apply broken streams quirk to Etron EJ188 xHCI host
+    - thunderbolt: debugfs: Fix margin debugfs node creation condition
+    - scsi: core: Disable CDL by default
+    - scsi: mpi3mr: Fix ATA NCQ priority support
+    - scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory
+    - scsi: sd: Use READ(16) when reading block zero on large capacity disks
+    - gve: Clear napi->skb before dev_kfree_skb_any()
+    - powerpc/uaccess: Fix build errors seen with GCC 13/14
+    - HID: nvidia-shield: Add missing check for input_ff_create_memless
+    - cxl/test: Add missing vmalloc.h for tools/testing/cxl/test/mem.c
+    - cxl/region: Fix memregion leaks in devm_cxl_add_region()
+    - cachefiles: add output string to cachefiles_obj_[get|put]_ondemand_fd
+    - cachefiles: remove requests from xarray during flushing requests
+    - cachefiles: add spin_lock for cachefiles_ondemand_info
+    - cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd()
+    - cachefiles: fix slab-use-after-free in cachefiles_ondemand_daemon_read()
+    - cachefiles: remove err_put_fd label in cachefiles_ondemand_daemon_read()
+    - cachefiles: never get a new anonymous fd if ondemand_id is valid
+    - cachefiles: defer exposing anon_fd until after copy_to_user() succeeds
+    - cachefiles: flush all requests after setting CACHEFILES_DEAD
+    - selftests/ftrace: Fix to check required event file
+    - clk: sifive: Do not register clkdevs for PRCI clocks
+    - NFSv4.1 enforce rootpath check in fs_location query
+    - SUNRPC: return proper error from gss_wrap_req_priv
+    - NFS: add barriers when testing for NFS_FSDATA_BLOCKED
+    - selftests/tracing: Fix event filter test to retry up to 10 times
+    - nvme: fix nvme_pr_* status code parsing
+    - drm/panel: sitronix-st7789v: Add check for of_drm_get_panel_orientation
+    - platform/x86: dell-smbios: Fix wrong token data in sysfs
+    - gpio: tqmx86: fix typo in Kconfig label
+    - gpio: tqmx86: introduce shadow register for GPIO output value
+    - gpio: tqmx86: store IRQ trigger type and unmask status separately
+    - gpio: tqmx86: fix broken IRQ_TYPE_EDGE_BOTH interrupt type
+    - HID: core: remove unnecessary WARN_ON() in implement()
+    - iommu/amd: Fix sysfs leak in iommu init
+    - iommu: Return right value in iommu_sva_bind_device()
+    - io_uring/io-wq: Use set_bit() and test_bit() at worker->flags
+    - io_uring/io-wq: avoid garbage value of 'match' in io_wq_enqueue()
+    - HID: logitech-dj: Fix memory leak in logi_dj_recv_switch_to_dj_mode()
+    - drm/vmwgfx: Refactor drm connector probing for display modes
+    - drm/vmwgfx: Filter modes which exceed graphics memory
+    - drm/vmwgfx: 3D disabled should not effect STDU memory limits
+    - drm/vmwgfx: Remove STDU logic from generic mode_valid function
+    - drm/vmwgfx: Don't memcmp equivalent pointers
+    - af_unix: Annotate data-race of sk->sk_state in unix_accept().
+    - modpost: do not warn about missing MODULE_DESCRIPTION() for vmlinux.o
+    - net: sfp: Always call `sfp_sm_mod_remove()` on remove
+    - net: hns3: fix kernel crash problem in concurrent scenario
+    - net: hns3: add cond_resched() to hns3 ring buffer init process
+    - liquidio: Adjust a NULL pointer handling path in lio_vf_rep_copy_packet
+    - net: stmmac: dwmac-qcom-ethqos: Configure host DMA width
+    - drm/komeda: check for error-valued pointer
+    - drm/bridge/panel: Fix runtime warning on panel bridge release
+    - tcp: fix race in tcp_v6_syn_recv_sock()
+    - net dsa: qca8k: fix usages of device_get_named_child_node()
+    - geneve: Fix incorrect inner network header offset when innerprotoinherit is
+      set
+    - net/mlx5e: Fix features validation check for tunneled UDP (non-VXLAN)
+      packets
+    - Bluetooth: fix connection setup in l2cap_connect
+    - netfilter: nft_inner: validate mandatory meta and payload
+    - netfilter: ipset: Fix race between namespace cleanup and gc in the list:set
+      type
+    - x86/asm: Use %c/%n instead of %P operand modifier in asm templates
+    - x86/uaccess: Fix missed zeroing of ia32 u64 get_user() range checking
+    - scsi: ufs: core: Quiesce request queues before checking pending cmds
+    - net: pse-pd: Use EOPNOTSUPP error code instead of ENOTSUPP
+    - gve: ignore nonrelevant GSO type bits when processing TSO headers
+    - net: stmmac: replace priv->speed with the portTransmitRate from the tc-cbs
+      parameters
+    - block: sed-opal: avoid possible wrong address reference in
+      read_sed_opal_key()
+    - block: fix request.queuelist usage in flush
+    - nvmet-passthru: propagate status from id override functions
+    - net/ipv6: Fix the RT cache flush via sysctl using a previous delay
+    - net: bridge: mst: pass vlan group directly to br_mst_vlan_set_state
+    - net: bridge: mst: fix suspicious rcu usage in br_mst_set_state
+    - ionic: fix use after netif_napi_del()
+    - af_unix: Read with MSG_PEEK loops if the first unread byte is OOB
+    - bnxt_en: Adjust logging of firmware messages in case of released token in
+      __hwrm_send()
+    - misc: microchip: pci1xxxx: fix double free in the error handling of
+      gp_aux_bus_probe()
+    - ksmbd: move leading slash check to smb2_get_name()
+    - ksmbd: fix missing use of get_write in in smb2_set_ea()
+    - x86/boot: Don't add the EFI stub to targets, again
+    - iio: adc: ad9467: fix scan type sign
+    - iio: dac: ad5592r: fix temperature channel scaling value
+    - iio: invensense: fix odr switching to same value
+    - iio: imu: inv_icm42600: delete unneeded update watermark call
+    - drivers: core: synchronize really_probe() and dev_uevent()
+    - parisc: Try to fix random segmentation faults in package builds
+    - ACPI: x86: Force StorageD3Enable on more products
+    - drm/exynos/vidi: fix memory leak in .get_modes()
+    - drm/exynos: hdmi: report safe 640x480 mode as a fallback when no EDID found
+    - mptcp: ensure snd_una is properly initialized on connect
+    - mptcp: pm: inc RmAddr MIB counter once per RM_ADDR ID
+    - mptcp: pm: update add_addr counters after connect
+    - clkdev: Update clkdev id usage to allow for longer names
+    - irqchip/gic-v3-its: Fix potential race condition in its_vlpi_prop_update()
+    - x86/kexec: Fix bug with call depth tracking
+    - x86/amd_nb: Check for invalid SMN reads
+    - perf/core: Fix missing wakeup when waiting for context reference
+    - perf auxtrace: Fix multiple use of --itrace option
+    - riscv: fix overlap of allocated page and PTR_ERR
+    - tracing/selftests: Fix kprobe event name test for .isra. functions
+    - kheaders: explicitly define file modes for archived headers
+    - null_blk: Print correct max open zones limit in null_init_zoned_dev()
+    - sock_map: avoid race between sock_map_close and sk_psock_put
+    - dma-buf: handle testing kthreads creation failure
+    - vmci: prevent speculation leaks by sanitizing event in event_deliver()
+    - spmi: hisi-spmi-controller: Do not override device identifier
+    - knfsd: LOOKUP can return an illegal error value
+    - fs/proc: fix softlockup in __read_vmcore
+    - ocfs2: use coarse time for new created files
+    - ocfs2: fix races between hole punching and AIO+DIO
+    - PCI: rockchip-ep: Remove wrong mask on subsys_vendor_id
+    - dmaengine: axi-dmac: fix possible race in remove()
+    - remoteproc: k3-r5: Wait for core0 power-up before powering up core1
+    - remoteproc: k3-r5: Do not allow core1 to power up before core0 via sysfs
+    - iio: adc: axi-adc: make sure AXI clock is enabled
+    - iio: invensense: fix interrupt timestamp alignment
+    - riscv: rewrite __kernel_map_pages() to fix sleeping in invalid context
+    - rtla/timerlat: Simplify "no value" printing on top
+    - rtla/auto-analysis: Replace \t with spaces
+    - drm/i915/gt: Disarm breadcrumbs if engines are already idle
+    - drm/shmem-helper: Fix BUG_ON() on mmap(PROT_WRITE, MAP_PRIVATE)
+    - drm/i915/dpt: Make DPT object unshrinkable
+    - drm/i915: Fix audio component initialization
+    - intel_th: pci: Add Meteor Lake-S support
+    - pmdomain: ti-sci: Fix duplicate PD referrals
+    - btrfs: zoned: fix use-after-free due to race with dev replace
+    - xfs: fix imprecise logic in xchk_btree_check_block_owner
+    - xfs: fix scrub stats file permissions
+    - xfs: fix SEEK_HOLE/DATA for regions with active COW extents
+    - xfs: shrink failure needs to hold AGI buffer
+    - xfs: ensure submit buffers on LSN boundaries in error handlers
+    - xfs: allow sunit mount option to repair bad primary sb stripe values
+    - xfs: don't use current->journal_info
+    - xfs: allow cross-linking special files without project quota
+    - swiotlb: Enforce page alignment in swiotlb_alloc()
+    - swiotlb: Reinstate page-alignment for mappings >= PAGE_SIZE
+    - swiotlb: extend buffer pre-padding to alloc_align_mask if necessary
+    - tick/nohz_full: Don't abuse smp_call_function_single() in
+      tick_setup_device()
+    - mm/huge_memory: don't unpoison huge_zero_folio
+    - serial: 8250_pxa: Configure tx_loadsz to match FIFO IRQ level
+    - Revert "fork: defer linking file vma until vma is fully initialized"
+    - remoteproc: k3-r5: Jump to error handling labels in start/stop errors
+    - greybus: Fix use-after-free bug in gb_interface_release due to race
+      condition.
+    - ima: Fix use-after-free on a dentry's dname.name
+    - serial: core: Add UPIO_UNKNOWN constant for unknown port type
+    - serial: port: Introduce a common helper to read properties
+    - serial: 8250_dw: Switch to use uart_read_port_properties()
+    - serial: 8250_dw: Replace ACPI device check by a quirk
+    - serial: 8250_dw: Don't use struct dw8250_data outside of 8250_dw
+    - usb-storage: alauda: Check whether the media is initialized
+    - misc: microchip: pci1xxxx: Fix a memory leak in the error handling of
+      gp_aux_bus_probe()
+    - i2c: at91: Fix the functionality flags of the slave-only interface
+    - i2c: designware: Fix the functionality flags of the slave-only interface
+    - zap_pid_ns_processes: clear TIF_NOTIFY_SIGNAL along with TIF_SIGPENDING
+    - wifi: ath11k: fix WCN6750 firmware crash caused by 17 num_vdevs
+    - cpufreq: amd-pstate: Unify computation of
+      {max,min,nominal,lowest_nonlinear}_freq
+    - cpufreq: amd-pstate: Add quirk for the pstate CPPC capabilities missing
+    - cpufreq: amd-pstate: remove global header file
+    - virtio_net: fix possible dim status unrecoverable
+    - net: ethernet: mtk_eth_soc: handle dma buffer size soc specific
+    - ice: fix reads from NVM Shadow RAM on E830 and E825-C devices
+    - ice: map XDP queues to vectors in ice_vsi_map_rings_to_vectors()
+    - x86/cpu: Get rid of an unnecessary local variable in get_cpu_address_sizes()
+    - x86/cpu: Provide default cache line size if not enumerated
+    - selftests/mm: ksft_exit functions do not return
+    - selftests/mm: compaction_test: fix bogus test success and reduce probability
+      of OOM-killer invocation
+    - .editorconfig: remove trim_trailing_whitespace option
+    - kcov, usb: disable interrupts in kcov_remote_start_usb_softirq
+    - ata: libata-scsi: Set the RMB bit only for removable media devices
+    - powerpc/85xx: fix compile error without CONFIG_CRASH_DUMP
+    - kselftest/alsa: Ensure _GNU_SOURCE is defined
+    - thermal: core: Do not fail cdev registration because of invalid initial
+      state
+    - Bluetooth: hci_sync: Fix not using correct handle
+    - net/sched: initialize noop_qdisc owner
+    - tcp: use signed arithmetic in tcp_rtx_probe0_timed_out()
+    - drm/nouveau: don't attempt to schedule hpd_work on headless cards
+    - drm/xe/xe_gt_idle: use GT forcewake domain assertion
+    - drm/xe: flush engine buffers before signalling user fence on all engines
+    - drm/xe: Remove mem_access from guc_pc calls
+    - drm/xe: move disable_c6 call
+    - bnxt_en: Cap the size of HWRM_PORT_PHY_QCFG forwarded response
+    - iio: imu: bmi323: Fix trigger notification in case of error
+    - iio: pressure: bmp280: Fix BMP580 temperature reading
+    - iio: temperature: mlx90635: Fix ERR_PTR dereference in mlx90635_probe()
+    - thermal: ACPI: Invalidate trip points with temperature of 0 or below
+    - x86/mm/numa: Use NUMA_NO_NODE when calling memblock_set_node()
+    - memblock: make memblock_set_node() also warn about use of MAX_NUMNODES
+    - perf script: Show also errors for --insn-trace option
+    - wifi: cfg80211: validate HE operation element parsing
+    - wifi: rtlwifi: Ignore IEEE80211_CONF_CHANGE_RETRY_LIMITS
+    - locking/atomic: scripts: fix ${atomic}_sub_and_test() kerneldoc
+    - ata: ahci: Do not apply Intel PCS quirk on Intel Alder Lake
+    - ata: libata-core: Add ATA_HORKAGE_NOLPM for Apacer AS340
+    - ata: libata-core: Add ATA_HORKAGE_NOLPM for Crucial CT240BX500SSD1
+    - ata: libata-core: Add ATA_HORKAGE_NOLPM for AMD Radeon S3 SSD
+    - kexec: fix the unexpected kexec_dprintk() macro
+    - ocfs2: update inode fsync transaction id in ocfs2_unlink and ocfs2_link
+    - dm-integrity: set discard_granularity to logical block size
+    - drm/bridge: aux-hpd-bridge: correct devm_drm_dp_hpd_bridge_add() stub
+    - iio: temperature: mcp9600: Fix temperature reading for negative values
+    - drm/mst: Fix NULL pointer dereference at drm_dp_add_payload_part2
+    - riscv: force PAGE_SIZE linear mapping if debug_pagealloc is enabled
+    - drm/xe: Properly handle alloc_guc_id() failure
+    - wifi: iwlwifi: mvm: support iwl_dev_tx_power_cmd_v8
+    - wifi: iwlwifi: mvm: fix a crash on 7265
+    - mei: vsc: Fix wrong invocation of ACPI SID method
+    - Upstream stable to v6.6.35, v6.9.6
+
+  * [SRU] Add support for intel trace hub for last platforms (LP: #2073926) //
+    Noble update: upstream stable patchset 2024-07-25 (LP: #2074091)
+    - intel_th: pci: Add Granite Rapids support
+    - intel_th: pci: Add Granite Rapids SOC support
+    - intel_th: pci: Add Sapphire Rapids SOC support
+    - intel_th: pci: Add Lunar Lake support
+
+  * Fix L2CAP/LE/CPU/BV-02-C bluetooth certification failure (LP: #2072858) //
+    Noble update: upstream stable patchset 2024-07-25 (LP: #2074091)
+    - Bluetooth: L2CAP: Fix rejecting L2CAP_CONN_PARAM_UPDATE_REQ
+
+  * Noble update: upstream stable patchset 2024-07-22 (LP: #2073788)
+    - drm/i915/hwmon: Get rid of devm
+    - afs: Don't cross .backup mountpoint from backup volume
+    - erofs: avoid allocating DEFLATE streams before mounting
+    - vxlan: Fix regression when dropping packets due to invalid src addresses
+    - drm/sun4i: hdmi: Convert encoder to atomic
+    - drm/sun4i: hdmi: Move mode_set into enable
+    - f2fs: fix to do sanity check on i_xattr_nid in sanity_check_inode()
+    - media: lgdt3306a: Add a check against null-pointer-def
+    - drm/amdgpu: add error handle to avoid out-of-bounds
+    - wifi: rtw89: correct aSIFSTime for 6GHz band
+    - ata: pata_legacy: make legacy_exit() work again
+    - fsverity: use register_sysctl_init() to avoid kmemleak warning
+    - proc: Move fdinfo PTRACE_MODE_READ check into the inode .permission
+      operation
+    - platform/chrome: cros_ec: Handle events during suspend after resume
+      completion
+    - thermal/drivers/qcom/lmh: Check for SCM availability at probe
+    - soc: qcom: rpmh-rsc: Enhance check for VRM in-flight request
+    - ACPI: resource: Do IRQ override on TongFang GXxHRXx and GMxHGxx
+    - arm64: tegra: Correct Tegra132 I2C alias
+    - arm64: dts: qcom: qcs404: fix bluetooth device address
+    - md/raid5: fix deadlock that raid5d() wait for itself to clear
+      MD_SB_CHANGE_PENDING
+    - wifi: rtl8xxxu: Fix the TX power of RTL8192CU, RTL8723AU
+    - wifi: rtlwifi: rtl8192de: Fix 5 GHz TX power
+    - wifi: rtlwifi: rtl8192de: Fix low speed with WPA3-SAE
+    - wifi: rtlwifi: rtl8192de: Fix endianness issue in RX path
+    - arm64: dts: qcom: sc8280xp: add missing PCIe minimum OPP
+    - arm64: dts: hi3798cv200: fix the size of GICR
+    - arm64: dts: ti: verdin-am62: Set memory size to 2gb
+    - media: mc: Fix graph walk in media_pipeline_start
+    - media: mc: mark the media devnode as registered from the, start
+    - media: mxl5xx: Move xpt structures off stack
+    - media: v4l2-core: hold videodev_lock until dev reg, finishes
+    - media: v4l: async: Properly re-initialise notifier entry in unregister
+    - media: v4l: async: Don't set notifier's V4L2 device if registering fails
+    - media: v4l: async: Fix notifier list entry init
+    - mmc: core: Add mmc_gpiod_set_cd_config() function
+    - mmc: sdhci: Add support for "Tuning Error" interrupts
+    - mmc: sdhci-acpi: Sort DMI quirks alphabetically
+    - mmc: sdhci-acpi: Fix Lenovo Yoga Tablet 2 Pro 1380 sdcard slot not working
+    - mmc: sdhci-acpi: Disable write protect detection on Toshiba WT10-A
+    - mmc: sdhci-acpi: Add quirk to enable pull-up on the card-detect GPIO on Asus
+      T100TA
+    - drm/fbdev-generic: Do not set physical framebuffer address
+    - fbdev: savage: Handle err return when savagefb_check_var failed
+    - drm/amdgpu/atomfirmware: add intergrated info v2.3 table
+    - 9p: add missing locking around taking dentry fid list
+    - drm/amd: Fix shutdown (again) on some SMU v13.0.4/11 platforms
+    - Revert "drm/amdkfd: fix gfx_target_version for certain 11.0.3 devices"
+    - KVM: SVM: WARN on vNMI + NMI window iff NMIs are outright masked
+    - KVM: arm64: Fix AArch32 register narrowing on userspace write
+    - KVM: arm64: Allow AArch32 PSTATE.M to be restored as System mode
+    - KVM: arm64: AArch32: Fix spurious trapping of conditional instructions
+    - LoongArch: Add all CPUs enabled by fdt to NUMA node 0
+    - LoongArch: Override higher address bits in JUMP_VIRT_ADDR
+    - clk: bcm: dvp: Assign ->num before accessing ->hws
+    - clk: bcm: rpi: Assign ->num before accessing ->hws
+    - clk: qcom: clk-alpha-pll: fix rate setting for Stromer PLLs
+    - crypto: ecdsa - Fix module auto-load on add-key
+    - crypto: ecrdsa - Fix module auto-load on add_key
+    - crypto: qat - Fix ADF_DEV_RESET_SYNC memory leak
+    - kbuild: Remove support for Clang's ThinLTO caching
+    - mm: fix race between __split_huge_pmd_locked() and GUP-fast
+    - filemap: add helper mapping_max_folio_size()
+    - iomap: fault in smaller chunks for non-large folio mappings
+    - i2c: acpi: Unbind mux adapters before delete
+    - HID: i2c-hid: elan: fix reset suspend current leakage
+    - scsi: core: Handle devices which return an unusually large VPD page count
+    - net/ipv6: Fix route deleting failure when metric equals 0
+    - net/9p: fix uninit-value in p9_client_rpc()
+    - mm/ksm: fix ksm_pages_scanned accounting
+    - mm/ksm: fix ksm_zero_pages accounting
+    - kmsan: do not wipe out origin when doing partial unpoisoning
+    - tpm_tis: Do *not* flush uninitialized work
+    - intel_th: pci: Add Meteor Lake-S CPU support
+    - rtla/timerlat: Fix histogram report when a cpu count is 0
+    - sparc64: Fix number of online CPUs
+    - mm/cma: drop incorrect alignment check in cma_init_reserved_mem
+    - mm/hugetlb: pass correct order_per_bit to cma_declare_contiguous_nid
+    - mm: /proc/pid/smaps_rollup: avoid skipping vma after getting mmap_lock again
+    - mm/vmalloc: fix vmalloc which may return null if called with __GFP_NOFAIL
+    - selftests/mm: compaction_test: fix incorrect write of zero to nr_hugepages
+    - selftests/mm: fix build warnings on ppc64
+    - watchdog: rti_wdt: Set min_hw_heartbeat_ms to accommodate a safety margin
+    - bonding: fix oops during rmmod
+    - wifi: ath10k: fix QCOM_RPROC_COMMON dependency
+    - kdb: Fix buffer overflow during tab-complete
+    - kdb: Use format-strings rather than '\0' injection in kdb_read()
+    - kdb: Fix console handling when editing and tab-completing commands
+    - kdb: Merge identical case statements in kdb_read()
+    - kdb: Use format-specifiers rather than memset() for padding in kdb_read()
+    - sparc: move struct termio to asm/termios.h
+    - drm/amdkfd: handle duplicate BOs in reserve_bo_and_cond_vms
+    - ext4: Fixes len calculation in mpage_journal_page_buffers
+    - ext4: set type of ac_groups_linear_remaining to __u32 to avoid overflow
+    - ext4: fix mb_cache_entry's e_refcnt leak in ext4_xattr_block_cache_find()
+    - riscv: dts: starfive: Remove PMIC interrupt info for Visionfive 2 board
+    - ARM: dts: samsung: smdkv310: fix keypad no-autorepeat
+    - ARM: dts: samsung: smdk4412: fix keypad no-autorepeat
+    - ARM: dts: samsung: exynos4412-origen: fix keypad no-autorepeat
+    - parisc: Define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+    - parisc: Define sigset_t in parisc uapi header
+    - s390/ap: Fix crash in AP internal function modify_bitmap()
+    - s390/cpacf: Split and rework cpacf query functions
+    - s390/cpacf: Make use of invalid opcode produce a link error
+    - i3c: master: svc: fix invalidate IBI type and miss call client IBI handler
+    - genirq/irqdesc: Prevent use-after-free in irq_find_at_or_after()
+    - ASoC: SOF: ipc4-topology: Fix input format query of process modules without
+      base extension
+    - ALSA: ump: Don't clear bank selection after sending a program change
+    - ALSA: ump: Don't accept an invalid UMP protocol number
+    - EDAC/amd64: Convert PCIBIOS_* return codes to errnos
+    - EDAC/igen6: Convert PCIBIOS_* return codes to errnos
+    - nfs: fix undefined behavior in nfs_block_bits()
+    - NFS: Fix READ_PLUS when server doesn't support OP_READ_PLUS
+    - eventfs: Fix a possible null pointer dereference in eventfs_find_events()
+    - eventfs: Keep the directories from having the same inode number as files
+    - tracefs: Clear EVENT_INODE flag in tracefs_drop_inode()
+    - btrfs: fix crash on racing fsync and size-extending write into prealloc
+    - btrfs: fix leak of qgroup extent records after transaction abort
+    - ALSA: seq: Fix incorrect UMP type for system messages
+    - powerpc/bpf: enforce full ordering for ATOMIC operations with BPF_FETCH
+    - smb: client: fix deadlock in smb2_find_smb_tcon()
+    - smp: Provide 'setup_max_cpus' definition on UP too
+    - drm/xe/bb: assert width in xe_bb_create_job()
+    - crypto: starfive - Do not free stack buffer
+    - btrfs: qgroup: fix initialization of auto inherit array
+    - wifi: rtl8xxxu: enable MFP support with security flag of RX descriptor
+    - media: mgb4: Fix double debugfs remove
+    - media: ov2740: Fix LINK_FREQ and PIXEL_RATE control value reporting
+    - firmware: qcom_scm: disable clocks if qcom_scm_bw_enable() fails
+    - LoongArch: Fix built-in DTB detection
+    - LoongArch: Fix entry point in kernel image header
+    - clk: qcom: apss-ipq-pll: use stromer ops for IPQ5018 to fix boot failure
+    - net/tcp: Don't consider TCP_CLOSE in TCP_AO_ESTABLISHED
+    - selftests: net: lib: support errexit with busywait
+    - selftests: net: lib: avoid error removing empty netns name
+    - cpufreq: amd-pstate: Fix the inconsistency in max frequency units
+    - mm/memory-failure: fix handling of dissolved but not taken off from buddy
+      pages
+    - selftests/mm: compaction_test: fix bogus test success on Aarch64
+    - irqchip/riscv-intc: Prevent memory leak when riscv_intc_init_common() fails
+    - Revert "perf record: Reduce memory for recording PERF_RECORD_LOST_SAMPLES
+      event"
+    - hwmon: (ltc2992) Fix memory leak in ltc2992_parse_dt()
+    - riscv: enable HAVE_ARCH_HUGE_VMAP for XIP kernel
+    - btrfs: qgroup: update rescan message levels and error codes
+    - btrfs: qgroup: fix qgroup id collision across mounts
+    - btrfs: cache folio size and shift in extent_buffer
+    - btrfs: protect folio::private when attaching extent buffer folios
+    - bpf: fix multi-uprobe PID filtering logic
+    - powerpc/64/bpf: fix tail calls for PCREL addressing
+    - nilfs2: fix potential kernel bug due to lack of writeback flag waiting
+    - nilfs2: fix nilfs_empty_dir() misjudgment and long loop on I/O errors
+    - Upstream stable to v6.6.34, v6.9.5
+
+  * Noble update: upstream stable patchset 2024-07-19 (LP: #2073603)
+    - perf record: Delete session after stopping sideband thread
+    - perf probe: Add missing libgen.h header needed for using basename()
+    - iio: core: Leave private pointer NULL when no private data supplied
+    - greybus: lights: check return of get_channel_from_mode
+    - phy: qcom: qmp-combo: fix duplicate return in qmp_v4_configure_dp_phy
+    - f2fs: multidev: fix to recognize valid zero block address
+    - f2fs: fix to wait on page writeback in __clone_blkaddrs()
+    - fpga: manager: add owner module and take its refcount
+    - fpga: bridge: add owner module and take its refcount
+    - counter: linux/counter.h: fix Excess kernel-doc description warning
+    - perf annotate: Get rid of duplicate --group option item
+    - usb: typec: ucsi: always register a link to USB PD device
+    - usb: typec: ucsi: simplify partner's PD caps registration
+    - perf stat: Do not fail on metrics on s390 z/VM systems
+    - soundwire: cadence: fix invalid PDI offset
+    - dmaengine: idma64: Add check for dma_set_max_seg_size
+    - firmware: dmi-id: add a release callback function
+    - perf annotate: Fix annotation_calc_lines() to pass correct address to
+      get_srcline()
+    - serial: max3100: Lock port->lock when calling uart_handle_cts_change()
+    - serial: max3100: Update uart_driver_registered on driver removal
+    - serial: max3100: Fix bitwise types
+    - greybus: arche-ctrl: move device table to its right location
+    - PCI: tegra194: Fix probe path for Endpoint mode
+    - serial: sc16is7xx: add proper sched.h include for sched_set_fifo()
+    - module: don't ignore sysfs_create_link() failures
+    - interconnect: qcom: qcm2290: Fix mas_snoc_bimc QoS port assignment
+    - arm64: dts: meson: fix S4 power-controller node
+    - perf tests: Make "test data symbol" more robust on Neoverse N1
+    - perf tests: Apply attributes to all events in object code reading test
+    - perf record: Fix debug message placement for test consumption
+    - dt-bindings: PCI: rcar-pci-host: Add missing IOMMU properties
+    - perf bench uprobe: Remove lib64 from libc.so.6 binary path
+    - f2fs: compress: fix to relocate check condition in
+      f2fs_{release,reserve}_compress_blocks()
+    - f2fs: compress: fix to relocate check condition in
+      f2fs_ioc_{,de}compress_file()
+    - f2fs: fix to relocate check condition in f2fs_fallocate()
+    - f2fs: fix to check pinfile flag in f2fs_move_file_range()
+    - iio: adc: stm32: Fixing err code to not indicate success
+    - riscv: dts: starfive: visionfive 2: Remove non-existing TDM hardware
+    - coresight: etm4x: Fix unbalanced pm_runtime_enable()
+    - perf docs: Document bpf event modifier
+    - perf test shell arm_coresight: Increase buffer size for Coresight basic
+      tests
+    - iio: pressure: dps310: support negative temperature values
+    - iio: buffer-dmaengine: export buffer alloc and free functions
+    - iio: add the IIO backend framework
+    - [CONFIG] Update CONFIG_IIO_BACKEND
+    - iio: adc: ad9467: convert to backend framework
+    - [Config] Update CONFIG_AD9467
+    - iio: adc: adi-axi-adc: move to backend framework
+    - [Config] Update CONFIG_ADI_AXI_ADC
+    - iio: adc: adi-axi-adc: only error out in major version mismatch
+    - coresight: etm4x: Do not hardcode IOMEM access for register restore
+    - coresight: etm4x: Do not save/restore Data trace control registers
+    - coresight: etm4x: Safe access for TRCQCLTR
+    - coresight: etm4x: Fix access to resource selector registers
+    - vfio/pci: fix potential memory leak in vfio_intx_enable()
+    - fpga: region: add owner module and take its refcount
+    - udf: Remove GFP_NOFS allocation in udf_expand_file_adinicb()
+    - udf: Convert udf_expand_file_adinicb() to use a folio
+    - microblaze: Remove gcc flag for non existing early_printk.c file
+    - microblaze: Remove early printk call from cpuinfo-static.c
+    - PCI: Wait for Link Training==0 before starting Link retrain
+    - perf intel-pt: Fix unassigned instruction op (discovered by MemorySanitizer)
+    - leds: pwm: Disable PWM when going to suspend
+    - ovl: remove upper umask handling from ovl_create_upper()
+    - PCI: of_property: Return error for int_map allocation failure
+    - VMCI: Fix an error handling path in vmci_guest_probe_device()
+    - dt-bindings: pinctrl: mediatek: mt7622: fix array properties
+    - pinctrl: qcom: pinctrl-sm7150: Fix sdc1 and ufs special pins regs
+    - watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger
+    - watchdog: bd9576: Drop "always-running" property
+    - watchdog: sa1100: Fix PTR_ERR_OR_ZERO() vs NULL check in sa1100dog_probe()
+    - dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: fix msm899[68] power-domains
+    - dt-bindings: phy: qcom,usb-snps-femto-v2: use correct fallback for sc8180x
+    - dmaengine: idxd: Avoid unnecessary destruction of file_ida
+    - usb: gadget: u_audio: Fix race condition use of controls after free during
+      gadget unbind.
+    - usb: gadget: u_audio: Clear uac pointer when freed.
+    - stm class: Fix a double free in stm_register_device()
+    - ppdev: Add an error check in register_device
+    - i2c: cadence: Avoid fifo clear after start
+    - i2c: synquacer: Fix an error handling path in synquacer_i2c_probe()
+    - perf bench internals inject-build-id: Fix trap divide when collecting just
+      one DSO
+    - perf ui browser: Don't save pointer to stack memory
+    - extcon: max8997: select IRQ_DOMAIN instead of depending on it
+    - dt-bindings: spmi: hisilicon,hisi-spmi-controller: fix binding references
+    - PCI/EDR: Align EDR_PORT_DPC_ENABLE_DSM with PCI Firmware r3.3
+    - PCI/EDR: Align EDR_PORT_LOCATE_DSM with PCI Firmware r3.3
+    - f2fs: support printk_ratelimited() in f2fs_printk()
+    - f2fs: use BLKS_PER_SEG, BLKS_PER_SEC, and SEGS_PER_SEC
+    - f2fs: separate f2fs_gc_range() to use GC for a range
+    - f2fs: kill heap-based allocation
+    - f2fs: support file pinning for zoned devices
+    - f2fs: fix block migration when section is not aligned to pow2
+    - perf ui browser: Avoid SEGV on title
+    - perf report: Avoid SEGV in report__setup_sample_type()
+    - perf thread: Fixes to thread__new() related to initializing comm
+    - perf symbols: Fix ownership of string in dso__load_vmlinux()
+    - f2fs: compress: fix to update i_compr_blocks correctly
+    - f2fs: deprecate io_bits
+    - f2fs: introduce get_available_block_count() for cleanup
+    - f2fs: compress: fix error path of inc_valid_block_count()
+    - f2fs: compress: fix to cover {reserve,release}_compress_blocks() w/ cp_rwsem
+      lock
+    - f2fs: fix to release node block count in error path of f2fs_new_node_page()
+    - f2fs: compress: don't allow unaligned truncation on released compress inode
+    - serial: sh-sci: protect invalidating RXDMA on shutdown
+    - libsubcmd: Fix parse-options memory leak
+    - perf daemon: Fix file leak in daemon_session__control
+    - f2fs: fix to add missing iput() in gc_data_segment()
+    - usb: fotg210: Add missing kernel doc description
+    - perf stat: Don't display metric header for non-leader uncore events
+    - perf tools: Use pmus to describe type from attribute
+    - perf tools: Add/use PMU reverse lookup from config to name
+    - perf pmu: Assume sysfs events are always the same case
+    - perf pmu: Count sys and cpuid JSON events separately
+    - LoongArch: Fix callchain parse error with kernel tracepoint events again
+    - s390/vdso64: filter out munaligned-symbols flag for vdso
+    - s390/vdso: Generate unwind information for C modules
+    - s390/vdso: Create .build-id links for unstripped vdso files
+    - s390/vdso: Use standard stack frame layout
+    - s390/ipl: Fix incorrect initialization of len fields in nvme reipl block
+    - s390/ipl: Fix incorrect initialization of nvme dump block
+    - s390/boot: Remove alt_stfle_fac_list from decompressor
+    - dt-bindings: PCI: rockchip,rk3399-pcie: Add missing maxItems to ep-gpios
+    - gpiolib: acpi: Fix failed in acpi_gpiochip_find() by adding parent node
+      match
+    - eventfs: Do not differentiate the toplevel events directory
+    - eventfs: Create eventfs_root_inode to store dentry
+    - eventfs/tracing: Add callback for release of an eventfs_inode
+    - eventfs: Free all of the eventfs_inode after RCU
+    - eventfs: Have "events" directory get permissions from its parent
+    - dt-bindings: adc: axi-adc: update bindings for backend framework
+    - dt-bindings: adc: axi-adc: add clocks property
+    - Input: ims-pcu - fix printf string overflow
+    - mmc: sdhci_am654: Add tuning algorithm for delay chain
+    - mmc: sdhci_am654: Write ITAPDLY for DDR52 timing
+    - mmc: sdhci_am654: Add OTAP/ITAP delay enable
+    - mmc: sdhci_am654: Add ITAPDLYSEL in sdhci_j721e_4bit_set_clock
+    - mmc: sdhci_am654: Fix ITAPDLY for HS400 timing
+    - Input: pm8xxx-vibrator - correct VIB_MAX_LEVELS calculation
+    - media: v4l: Don't turn on privacy LED if streamon fails
+    - media: ov2680: Clear the 'ret' variable on success
+    - media: ov2680: Allow probing if link-frequencies is absent
+    - media: ov2680: Do not fail if data-lanes property is absent
+    - drm/msm/dsi: Print dual-DSI-adjusted pclk instead of original mode pclk
+    - drm/msm/dpu: Always flush the slave INTF on the CTL
+    - drm/mediatek: dp: Fix mtk_dp_aux_transfer return value
+    - drm/meson: gate px_clk when setting rate
+    - um: Fix return value in ubd_init()
+    - um: vector: fix bpfflash parameter evaluation
+    - fs/ntfs3: Check 'folio' pointer for NULL
+    - fs/ntfs3: Use 64 bit variable to avoid 32 bit overflow
+    - fs/ntfs3: Use variable length array instead of fixed size
+    - drm/msm/dpu: Add callback function pointer check before its call
+    - drm/bridge: tc358775: fix support for jeida-18 and jeida-24
+    - media: stk1160: fix bounds checking in stk1160_copy_video()
+    - Input: cyapa - add missing input core locking to suspend/resume functions
+    - drm/amdgpu: init microcode chip name from ip versions
+    - drm/amdgpu: Fix buffer size in gfx_v9_4_3_init_ cp_compute_microcode() and
+      rlc_microcode()
+    - media: mediatek: vcodec: fix possible unbalanced PM counter
+    - tools/arch/x86/intel_sdsi: Fix maximum meter bundle length
+    - tools/arch/x86/intel_sdsi: Fix meter_show display
+    - tools/arch/x86/intel_sdsi: Fix meter_certificate decoding
+    - platform/x86: thinkpad_acpi: Take hotkey_mutex during hotkey_exit()
+    - media: flexcop-usb: fix sanity check of bNumEndpoints
+    - powerpc/pseries: Add failure related checks for h_get_mpp and h_get_ppp
+    - um: Fix the -Wmissing-prototypes warning for __switch_mm
+    - um: Fix the -Wmissing-prototypes warning for get_thread_reg
+    - um: Fix the declaration of kasan_map_memory
+    - cxl/trace: Correct DPA field masks for general_media & dram events
+    - cxl/region: Fix cxlr_pmem leaks
+    - media: sunxi: a83-mips-csi2: also select GENERIC_PHY
+    - media: cec: cec-adap: always cancel work in cec_transmit_msg_fh
+    - media: cec: cec-api: add locking in cec_release()
+    - media: cec: core: avoid recursive cec_claim_log_addrs
+    - media: cec: core: avoid confusing "transmit timed out" message
+    - Revert "drm/bridge: ti-sn65dsi83: Fix enable error path"
+    - drm: zynqmp_dpsub: Always register bridge
+    - selftests/powerpc/dexcr: Add -no-pie to hashchk tests
+    - drm/msm/a6xx: Avoid a nullptr dereference when speedbin setting fails
+    - ASoC: tas2781: Fix a warning reported by robot kernel test
+    - null_blk: Fix the WARNING: modpost: missing MODULE_DESCRIPTION()
+    - ALSA: hda/cs_dsp_ctl: Use private_free for control cleanup
+    - ALSA: hda: cs35l56: Fix lifetime of cs_dsp instance
+    - ASoC: mediatek: mt8192: fix register configuration for tdm
+    - drm/nouveau: use tile_mode and pte_kind for VM_BIND bo allocations
+    - blk-cgroup: fix list corruption from resetting io stat
+    - blk-cgroup: fix list corruption from reorder of WRITE ->lqueued
+    - blk-cgroup: Properly propagate the iostat update up the hierarchy
+    - regulator: bd71828: Don't overwrite runtime voltages
+    - xen/x86: add extra pages to unpopulated-alloc if available
+    - perf/arm-dmc620: Fix lockdep assert in ->event_init()
+    - x86/kconfig: Select ARCH_WANT_FRAME_POINTERS again when
+      UNWINDER_FRAME_POINTER=y
+    - [Config] Update CONFIG_ARCH_WANT_FRAME_POINTERS
+    - net: Always descend into dsa/ folder with CONFIG_NET_DSA enabled
+    - ipv6: sr: fix missing sk_buff release in seg6_input_core
+    - selftests: net: kill smcrouted in the cleanup logic in amt.sh
+    - nfc: nci: Fix uninit-value in nci_rx_work
+    - ASoC: tas2552: Add TX path for capturing AUDIO-OUT data
+    - ASoC: tas2781: Fix wrong loading calibrated data sequence
+    - NFSv4: Fixup smatch warning for ambiguous return
+    - nfs: keep server info for remounts
+    - sunrpc: fix NFSACL RPC retry on soft mount
+    - rpcrdma: fix handling for RDMA_CM_EVENT_DEVICE_REMOVAL
+    - regulator: pickable ranges: don't always cache vsel
+    - regulator: tps6287x: Force writing VSEL bit
+    - af_unix: Update unix_sk(sk)->oob_skb under sk_receive_queue lock.
+    - ipv6: sr: fix memleak in seg6_hmac_init_algo
+    - regulator: tps6594-regulator: Correct multi-phase configuration
+    - tcp: Fix shift-out-of-bounds in dctcp_update_alpha().
+    - pNFS/filelayout: fixup pNfs allocation modes
+    - openvswitch: Set the skbuff pkt_type for proper pmtud support.
+    - arm64: asm-bug: Add .align 2 to the end of __BUG_ENTRY
+    - rv: Update rv_en(dis)able_monitor doc to match kernel-doc
+    - net: lan966x: Remove ptp traps in case the ptp is not enabled.
+    - virtio: delete vq in vp_find_vqs_msix() when request_irq() fails
+    - i3c: master: svc: change ENXIO to EAGAIN when IBI occurs during start frame
+    - Revert "ixgbe: Manual AN-37 for troublesome link partners for X550 SFI"
+    - net: fec: avoid lock evasion when reading pps_enable
+    - tls: fix missing memory barrier in tls_init
+    - net: relax socket state check at accept time.
+    - nfc: nci: Fix handling of zero-length payload packets in nci_rx_work()
+    - drivers/xen: Improve the late XenStore init protocol
+    - ice: Interpret .set_channels() input differently
+    - kasan, fortify: properly rename memintrinsics
+    - tracing/probes: fix error check in parse_btf_field()
+    - tpm_tis_spi: Account for SPI header when allocating TPM SPI xfer buffer
+    - netfilter: nfnetlink_queue: acquire rcu_read_lock() in
+      instance_destroy_rcu()
+    - netfilter: ipset: Add list flush to cancel_gc
+    - netfilter: nft_payload: restore vlan q-in-q match support
+    - spi: Don't mark message DMA mapped when no transfer in it is
+    - dma-mapping: benchmark: fix up kthread-related error handling
+    - dma-mapping: benchmark: fix node id validation
+    - dma-mapping: benchmark: handle NUMA_NO_NODE correctly
+    - nvme-multipath: fix io accounting on failover
+    - nvmet: fix ns enable/disable possible hang
+    - drm/amd/display: Enable colorspace property for MST connectors
+    - net: phy: micrel: set soft_reset callback to genphy_soft_reset for KSZ8061
+    - net/mlx5: Lag, do bond only if slaves agree on roce state
+    - net/mlx5: Fix MTMP register capability offset in MCAM register
+    - net/mlx5: Use mlx5_ipsec_rx_status_destroy to correctly delete status rules
+    - net/mlx5e: Fix IPsec tunnel mode offload feature check
+    - net/mlx5e: Use rx_missed_errors instead of rx_dropped for reporting buffer
+      exhaustion
+    - net/mlx5e: Fix UDP GSO for encapsulated packets
+    - dma-buf/sw-sync: don't enable IRQ from sync_print_obj()
+    - bpf: Fix potential integer overflow in resolve_btfids
+    - ALSA: jack: Use guard() for locking
+    - ALSA: core: Remove debugfs at disconnection
+    - ALSA: hda/realtek: Adjust G814JZR to use SPI init for amp
+    - enic: Validate length of nl attributes in enic_set_vf_port
+    - af_unix: Annotate data-race around unix_sk(sk)->addr.
+    - af_unix: Read sk->sk_hash under bindlock during bind().
+    - Octeontx2-pf: Free send queue buffers incase of leaf to inner
+    - net: usb: smsc95xx: fix changing LED_SEL bit value updated from EEPROM
+    - ASoC: cs42l43: Only restrict 44.1kHz for the ASP
+    - bpf: Allow delete from sockmap/sockhash only if update is allowed
+    - net:fec: Add fec_enet_deinit()
+    - net: micrel: Fix lan8841_config_intr after getting out of sleep mode
+    - ice: fix accounting if a VLAN already exists
+    - selftests: mptcp: simult flows: mark 'unbalanced' tests as flaky
+    - selftests: mptcp: add ms units for tc-netem delay
+    - selftests: mptcp: join: mark 'fail' tests as flaky
+    - ALSA: seq: Fix missing bank setup between MIDI1/MIDI2 UMP conversion
+    - ALSA: seq: Don't clear bank selection at event -> UMP MIDI2 conversion
+    - net: ti: icssg-prueth: Fix start counter for ft1 filter
+    - netfilter: nft_payload: skbuff vlan metadata mangle support
+    - netfilter: tproxy: bail out if IP has been disabled on the device
+    - netfilter: nft_fib: allow from forward/input without iif selector
+    - net/sched: taprio: make q->picos_per_byte available to fill_sched_entry()
+    - net/sched: taprio: extend minimum interval restriction to entire cycle too
+    - kconfig: fix comparison to constant symbols, 'm', 'n'
+    - drm/i915/guc: avoid FIELD_PREP warning
+    - kheaders: use `command -v` to test for existence of `cpio`
+    - spi: stm32: Don't warn about spurious interrupts
+    - net: dsa: microchip: fix RGMII error in KSZ DSA driver
+    - net: ena: Reduce lines with longer column width boundary
+    - net: ena: Fix redundant device NUMA node override
+    - ipvlan: Dont Use skb->sk in ipvlan_process_v{4,6}_outbound
+    - ALSA: seq: Fix yet another spot for system message conversion
+    - powerpc/pseries/lparcfg: drop error message from guest name lookup
+    - drm/panel: sitronix-st7789v: fix timing for jt240mhqs_hwt_ek_e3 panel
+    - drm/panel: sitronix-st7789v: tweak timing for jt240mhqs_hwt_ek_e3 panel
+    - drm/panel: sitronix-st7789v: fix display size for jt240mhqs_hwt_ek_e3 panel
+    - hwmon: (intel-m10-bmc-hwmon) Fix multiplier for N6000 board power sensor
+    - hwmon: (shtc1) Fix property misspelling
+    - ALSA: seq: ump: Fix swapped song position pointer data
+    - ALSA: timer: Set lower bound of start tick time
+    - x86/efistub: Omit physical KASLR when memory reservations exist
+    - efi: libstub: only free priv.runtime_map when allocated
+    - x86/pci: Skip early E820 check for ECAM region
+    - KVM: x86: Don't advertise guest.MAXPHYADDR as host.MAXPHYADDR in CPUID
+    - genirq/cpuhotplug, x86/vector: Prevent vector leak during CPU offline
+    - platform/x86/intel/tpmi: Handle error from tpmi_process_info()
+    - platform/x86/intel-uncore-freq: Don't present root domain on error
+    - perf sched timehist: Fix -g/--call-graph option failure
+    - f2fs: write missing last sum blk of file pinning section
+    - f2fs: use f2fs_{err,info}_ratelimited() for cleanup
+    - SUNRPC: Fix loop termination condition in gss_free_in_token_pages()
+    - riscv: prevent pt_regs corruption for secondary idle threads
+    - riscv: stacktrace: fixed walk_stackframe()
+    - perf build: Fix out of tree build related to installation of sysreg-defs
+    - dt-bindings: pinctrl: qcom: update functions to match with driver
+    - usb: typec: ucsi: allow non-partner GET_PDOS for Qualcomm devices
+    - perf report: Fix PAI counter names for s390 virtual machines
+    - PCI: dwc: ep: Fix DBI access failure for drivers requiring refclk from host
+    - perf map: Remove kernel map before updating start and end addresses
+    - riscv: dts: starfive: visionfive 2: Remove non-existing I2S hardware
+    - pinctrl: renesas: rzg2l: Limit 2.5V power supply to Ethernet interfaces
+    - riscv: Flush the instruction cache during SMP bringup
+    - usb: xhci: check if 'requested segments' exceeds ERST capacity
+    - spmi: pmic-arb: Replace three IS_ERR() calls by null pointer checks in
+      spmi_pmic_arb_probe()
+    - perf symbols: Remove map from list before updating addresses
+    - perf symbols: Update kcore map before merging in remaining symbols
+    - s390/ftrace: Use unwinder instead of __builtin_return_address()
+    - s390/stacktrace: Merge perf_callchain_user() and arch_stack_walk_user()
+    - s390/stacktrace: Skip first user stack frame
+    - s390/stacktrace: Improve detection of invalid instruction pointers
+    - s390/vdso: Introduce and use struct stack_frame_vdso_wrapper
+    - s390/stackstrace: Detect vdso stack frames
+    - s390/ap: Fix bind complete udev event sent after each AP bus scan
+    - ocfs2: correctly use ocfs2_find_next_zero_bit()
+    - mailbox: mtk-cmdq: Fix pm_runtime_get_sync() warning in mbox shutdown
+    - Input: ioc3kbd - add device table
+    - phy: qcom: qmp-combo: fix sm8650 voltage swing table
+    - media: ti: j721e-csi2rx: Fix races while restarting DMA
+    - drm/msm/dpu: Allow configuring multiple active DSC blocks
+    - drm: Make drivers depends on DRM_DW_HDMI
+    - [Config] Drivers now depend on DRM_DW_HDMI
+    - string: Prepare to merge strscpy_kunit.c into string_kunit.c
+    - string: Prepare to merge strcat KUnit tests into string_kunit.c
+    - drm/msm/adreno: fix CP cycles stat retrieval on a7xx
+    - printk: Fix LOG_CPU_MAX_BUF_SHIFT when BASE_SMALL is enabled
+    - powerpc/bpf/32: Fix failing test_bpf tests
+    - KVM: PPC: Book3S HV nestedv2: Cancel pending DEC exception
+    - KVM: PPC: Book3S HV nestedv2: Fix an error handling path in
+      gs_msg_ops_kvmhv_nestedv2_config_fill_info()
+    - KVM: arm64: Destroy mpidr_data for 'late' vCPU creation
+    - Bluetooth: ISO: Handle PA sync when no BIGInfo reports are generated
+    - Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init()
+    - ubsan: Restore dependency on ARCH_HAS_UBSAN
+    - selftests: forwarding: Have RET track kselftest framework constants
+    - selftests: forwarding: Convert log_test() to recognize RET values
+    - selftests: net: Unify code of busywait() and slowwait()
+    - selftests/net: use tc rule to filter the na packet
+    - virtio_balloon: Give the balloon its own wakeup source
+    - riscv: cpufeature: Fix thead vector hwcap removal
+    - riscv: cpufeature: Fix extension subset checking
+    - riscv: selftests: Add hwprobe binaries to .gitignore
+    - idpf: Interpret .set_channels() input differently
+    - null_blk: fix null-ptr-dereference while configuring 'power' and
+      'submit_queues'
+    - netfs: Fix setting of BDP_ASYNC from iocb flags
+    - cifs: Set zero_point in the copy_file_range() and remap_file_range()
+    - cifs: Fix missing set of remote_i_size
+    - selftests: net: lib: set 'i' as local
+    - nvme: fix multipath batched completion accounting
+    - netkit: Fix setting mac address in l2 mode
+    - netkit: Fix pkt_type override upon netkit pass verdict
+    - null_blk: Fix return value of nullb_device_power_store()
+    - idpf: don't enable NAPI and interrupts prior to allocating Rx buffers
+    - selftests: mptcp: join: mark 'fastclose' tests as flaky
+    - drm/xe: Add dbg messages on the suspend resume functions.
+    - drm/xe: check pcode init status only on root gt of root tile
+    - drm/xe: Change pcode timeout to 50msec while polling again
+    - drm/xe: Only use reserved BCS instances for usm migrate exec queue
+    - sd: also set max_user_sectors when setting max_sectors
+    - block: stack max_user_sectors
+    - ipv6: introduce dst_rt6_info() helper
+    - inet: introduce dst_rtable() helper
+    - net: fix __dst_negative_advice() race
+    - ice: fix 200G PHY types to link speed mapping
+    - x86/topology/intel: Unlock CPUID before evaluating anything
+    - Upstream stable to v6.6.33, v6.9.4
+
+  * Reenable CONFIG_UBSAN for noble (LP: #2076650)
+    - ubsan: Remove CONFIG_UBSAN_SANITIZE_ALL
+    - [Config] Remove CONFIG_UBSAN_SANITIZE_ALL
+
+  * Dangling symlink to linux-lib-rust when Rust is disabled (LP: #2072592)
+    - [Packaging] Check do_lib_rust before linking Rust lib files
+
+  * kdump doesn't work with UEFI secure boot and kernel lockdown enabled on
+    ARM64 (LP: #2033007)
+    - [Config]: Enable CONFIG_KEXEC_IMAGE_VERIFY_SIG on arm64
+
+  * net/sched: Fix conntrack use-after-free (LP: #2073092)
+    - net/sched: Fix UAF when resolving a clash
+
+  * No sound on Huawei Matebook D14  AMD since Linux 6.8.0-38 [regression]
+    (LP: #2073049)
+    - ASoC: amd: acp: fix for acp platform device creation failure
+
+  * i915: Fixup regressions introduced with enabling single CCS engine
+    (LP: #2072755)
+    - drm/i915/gt: Fix CCS id's calculation for CCS mode setting
+
+  * [Ubuntu 24.04] FW1060.00 (NH1060_026) sosreport is running to Kernel OOPS
+    crash (LP: #2070358)
+    - nfsd: initialise nfsd_info.mutex early.
+
+  * 6.8 generic & amdpgu / polaris (LP: #2072428)
+    - drm/amdgpu: Adjust logic in amdgpu_device_partner_bandwidth()
+
+  * md: nvme over tcp with a striped underlying md raid device leads to data
+    corruption (LP: #2075110)
+    - md/md-bitmap: fix writing non bitmap pages
+
+  * Linux 6.8 fails to boot on ARM64 if any param is more than 146 chars
+    (LP: #2069534)
+    - SAUCE: arm64: v6.8: cmdline param >= 146 chars kills kernel
+
+  * CVE-2024-39484
+    - mmc: davinci: Don't strip remove function when driver is builtin
+
+  * CVE-2024-39292
+    - um: Add winch to winch_handlers before registering winch IRQ
+
+  * Miscellaneous upstream changes
+    - bnx2x: Fix multiple UBSAN array-index-out-of-bounds
+
+ -- Roxana Nicolescu <roxana.nicolescu@canonical.com>  Tue, 13 Aug 2024 12:20:36 +0200
+
+linux (6.8.0-40.40) noble; urgency=medium
+
+  * noble/linux: 6.8.0-40.40 -proposed tracker (LP: #2072201)
+
+  * FPS of glxgear with fullscreen is too low on MTL platform (LP: #2069380)
+    - drm/i915: Bypass LMEMBAR/GTTMMADR for MTL stolen memory access
+
+  * a critical typo in the code managing the ASPM  settings for PCI Express
+    devices (LP: #2071889)
+    - PCI/ASPM: Restore parent state to parent, child state to child
+
+  * [UBUNTU 24.04] IOMMU DMA mode changed in kernel config causes massive
+    throughput degradation for PCI-related network workloads (LP: #2071471)
+    - [Config] Set IOMMU_DEFAULT_DMA_STRICT=n and IOMMU_DEFAULT_DMA_LAZY=yes for
+      s390x
+
+  * UBSAN: array-index-out-of-bounds in
+    /build/linux-D15vQj/linux-6.5.0/drivers/md/bcache/bset.c:1098:3
+    (LP: #2039368)
+    - bcache: fix variable length array abuse in btree_iter
+
+  * Mute/mic LEDs and speaker no function on EliteBook 645/665 G11
+    (LP: #2071296)
+    - ALSA: hda/realtek: fix mute/micmute LEDs don't work for EliteBook 645/665
+      G11.
+
+  * failed to enable IPU6 camera sensor on kernel >= 6.8: ivsc_ace
+    intel_vsc-5db76cf6-0a68-4ed6-9b78-0361635e2447: switch camera to host
+    failed: -110 (LP: #2067364)
+    - mei: vsc: Don't stop/restart mei device during system suspend/resume
+    - SAUCE: media: ivsc: csi: don't count privacy on as error
+    - SAUCE: media: ivsc: csi: add separate lock for v4l2 control handler
+    - SAUCE: media: ivsc: csi: remove privacy status in struct mei_csi
+    - SAUCE: mei: vsc: Enhance IVSC chipset stability during warm reboot
+    - SAUCE: mei: vsc: Enhance SPI transfer of IVSC rom
+    - SAUCE: mei: vsc: Utilize the appropriate byte order swap function
+    - SAUCE: mei: vsc: Prevent timeout error with added delay post-firmware
+      download
+
+  * failed to probe camera sensor on Dell XPS 9315: ov01a10 i2c-OVTI01A0:00:
+    failed to check hwcfg: -22 (LP: #2070251)
+    - ACPI: utils: Make acpi_handle_path() not static
+    - ACPI: property: Ignore bad graph port nodes on Dell XPS 9315
+    - ACPI: property: Polish ignoring bad data nodes
+    - ACPI: scan: Ignore camera graph port nodes on all Dell Tiger, Alder and
+      Raptor Lake models
+
+  * Update amd_sfh for AMD strix series (LP: #2058331)
+    - HID: amd_sfh: Increase sensor command timeout
+    - HID: amd_sfh: Improve boot time when SFH is available
+    - HID: amd_sfh: Extend MP2 register access to SFH
+    - HID: amd_sfh: Set the AMD SFH driver to depend on x86
+
+  * RFIM and SAGV Linux Support for G10 models (LP: #2070158)
+    - drm/i915/display: Add meaningful traces for QGV point info error handling
+    - drm/i915/display: Extract code required to calculate max qgv/psf gv point
+    - drm/i915/display: extract code to prepare qgv points mask
+    - drm/i915/display: Disable SAGV on bw init, to force QGV point recalculation
+    - drm/i915/display: handle systems with duplicate psf gv points
+    - drm/i915/display: force qgv check after the hw state readout
+
+  * Update amd-pmf for AMD strix series (LP: #2058330)
+    - platform/x86/amd/pmf: Differentiate PMF ACPI versions
+    - platform/x86/amd/pmf: Disable debugfs support for querying power thermals
+    - platform/x86/amd/pmf: Add support to get sbios requests in PMF driver
+    - platform/x86/amd/pmf: Add support to notify sbios heart beat event
+    - platform/x86/amd/pmf: Add support to get APTS index numbers for static
+      slider
+    - platform/x86/amd/pmf: Add support to get sps default APTS index values
+    - platform/x86/amd/pmf: Update sps power thermals according to the platform-
+      profiles
+
+  * noble:linux: ADT ubuntu-regression-suite misses fakeroot dependency
+    (LP: #2070042)
+    - [DEP-8] Add missing fakeroot dependency
+
+  * Noble update: v6.8.12 upstream stable release (LP: #2071621)
+    - sunrpc: use the struct net as the svc proc private
+    - x86/tsc: Trust initial offset in architectural TSC-adjust MSRs
+    - selftests/ftrace: Fix BTFARG testcase to check fprobe is enabled correctly
+    - ftrace: Fix possible use-after-free issue in ftrace_location()
+    - Revert "arm64: fpsimd: Implement lazy restore for kernel mode FPSIMD"
+    - arm64/fpsimd: Avoid erroneous elide of user state reload
+    - Reapply "arm64: fpsimd: Implement lazy restore for kernel mode FPSIMD"
+    - tty: n_gsm: fix missing receive state reset after mode switch
+    - speakup: Fix sizeof() vs ARRAY_SIZE() bug
+    - serial: sc16is7xx: fix bug in sc16is7xx_set_baud() when using prescaler
+    - serial: 8250_bcm7271: use default_mux_rate if possible
+    - serial: 8520_mtk: Set RTS on shutdown for Rx in-band wakeup
+    - Input: try trimming too long modalias strings
+    - io_uring: fail NOP if non-zero op flags is passed in
+    - Revert "r8169: don't try to disable interrupts if NAPI is, scheduled
+      already"
+    - r8169: Fix possible ring buffer corruption on fragmented Tx packets.
+    - ring-buffer: Fix a race between readers and resize checks
+    - net: mana: Fix the extra HZ in mana_hwc_send_request
+    - tools/latency-collector: Fix -Wformat-security compile warns
+    - tools/nolibc/stdlib: fix memory error in realloc()
+    - net: ti: icssg_prueth: Fix NULL pointer dereference in prueth_probe()
+    - net: lan966x: remove debugfs directory in probe() error path
+    - net: smc91x: Fix m68k kernel compilation for ColdFire CPU
+    - nilfs2: fix use-after-free of timer for log writer thread
+    - nilfs2: fix unexpected freezing of nilfs_segctor_sync()
+    - nilfs2: fix potential hang in nilfs_detach_log_writer()
+    - fs/ntfs3: Remove max link count info display during driver init
+    - fs/ntfs3: Taking DOS names into account during link counting
+    - fs/ntfs3: Fix case when index is reused during tree transformation
+    - fs/ntfs3: Break dir enumeration if directory contents error
+    - ksmbd: avoid to send duplicate oplock break notifications
+    - ksmbd: ignore trailing slashes in share paths
+    - ALSA: core: Fix NULL module pointer assignment at card init
+    - ALSA: Fix deadlocks with kctl removals at disconnection
+    - KEYS: asymmetric: Add missing dependency on CRYPTO_SIG
+    - [Config] updateconfigs for CRYPTO_SIG
+    - KEYS: asymmetric: Add missing dependencies of FIPS_SIGNATURE_SELFTEST
+    - HID: nintendo: Fix N64 controller being identified as mouse
+    - dmaengine: xilinx: xdma: Clarify kdoc in XDMA driver
+    - wifi: mac80211: don't use rate mask for scanning
+    - wifi: mac80211: ensure beacon is non-S1G prior to extracting the beacon
+      timestamp field
+    - wifi: cfg80211: fix the order of arguments for trace events of the tx_rx_evt
+      class
+    - dt-bindings: rockchip: grf: Add missing type to 'pcie-phy' node
+    - HID: mcp-2221: cancel delayed_work only when CONFIG_IIO is enabled
+    - net: usb: qmi_wwan: add Telit FN920C04 compositions
+    - drm/amd/display: Set color_mgmt_changed to true on unsuspend
+    - drm/amdgpu: Update BO eviction priorities
+    - drm/amd/pm: Restore config space after reset
+    - drm/amdkfd: Add VRAM accounting for SVM migration
+    - drm/amdgpu: Fix the ring buffer size for queue VM flush
+    - Revert "net: txgbe: fix i2c dev name cannot match clkdev"
+    - Revert "net: txgbe: fix clk_name exceed MAX_DEV_ID limits"
+    - cpu: Ignore "mitigations" kernel parameter if CPU_MITIGATIONS=n
+    - LoongArch: Lately init pmu after smp is online
+    - drm/etnaviv: fix tx clock gating on some GC7000 variants
+    - selftests: sud_test: return correct emulated syscall value on RISC-V
+    - riscv: thead: Rename T-Head PBMT to MAE
+    - [Config] updateconfigs for ERRATA_THEAD_MAE
+    - riscv: T-Head: Test availability bit before enabling MAE errata
+    - sched/isolation: Fix boot crash when maxcpus < first housekeeping CPU
+    - ASoC: Intel: bytcr_rt5640: Apply Asus T100TA quirk to Asus T100TAM too
+    - regulator: irq_helpers: duplicate IRQ name
+    - ALSA: hda: cs35l56: Exit cache-only after cs35l56_wait_for_firmware_boot()
+    - ASoC: SOF: ipc4-pcm: Use consistent name for snd_sof_pcm_stream pointer
+    - ASoC: SOF: ipc4-pcm: Use consistent name for sof_ipc4_timestamp_info pointer
+    - ASoC: SOF: ipc4-pcm: Introduce generic sof_ipc4_pcm_stream_priv
+    - ASoC: SOF: pcm: Restrict DSP D0i3 during S0ix to IPC3
+    - ASoC: acp: Support microphone from device Acer 315-24p
+    - ASoC: rt5645: Fix the electric noise due to the CBJ contacts floating
+    - ASoC: dt-bindings: rt5645: add cbj sleeve gpio property
+    - ASoC: rt722-sdca: modify channel number to support 4 channels
+    - ASoC: rt722-sdca: add headset microphone vrefo setting
+    - regulator: qcom-refgen: fix module autoloading
+    - regulator: vqmmc-ipq4019: fix module autoloading
+    - ASoC: cs35l41: Update DSP1RX5/6 Sources for DSP config
+    - ASoC: rt715: add vendor clear control register
+    - ASoC: rt715-sdca: volume step modification
+    - KVM: selftests: Add test for uaccesses to non-existent vgic-v2 CPUIF
+    - Input: xpad - add support for ASUS ROG RAIKIRI
+    - btrfs: take the cleaner_mutex earlier in qgroup disable
+    - EDAC/versal: Do not register for NOC errors
+    - fpga: dfl-pci: add PCI subdevice ID for Intel D5005 card
+    - bpf, x86: Fix PROBE_MEM runtime load check
+    - ALSA: emu10k1: make E-MU FPGA writes potentially more reliable
+    - softirq: Fix suspicious RCU usage in __do_softirq()
+    - platform/x86: ISST: Add Grand Ridge to HPM CPU list
+    - ASoC: da7219-aad: fix usage of device_get_named_child_node()
+    - ASoC: cs35l56: fix usages of device_get_named_child_node()
+    - ALSA: hda: intel-dsp-config: harden I2C/I2S codec detection
+    - Input: amimouse - mark driver struct with __refdata to prevent section
+      mismatch
+    - drm/amdgpu: Fix VRAM memory accounting
+    - drm/amd/display: Ensure that dmcub support flag is set for DCN20
+    - drm/amd/display: Add dtbclk access to dcn315
+    - drm/amd/display: Allocate zero bw after bw alloc enable
+    - drm/amd/display: Add VCO speed parameter for DCN31 FPU
+    - drm/amd/display: Fix DC mode screen flickering on DCN321
+    - drm/amd/display: Disable seamless boot on 128b/132b encoding
+    - drm/amdkfd: Flush the process wq before creating a kfd_process
+    - x86/mm: Remove broken vsyscall emulation code from the page fault code
+    - nvme: find numa distance only if controller has valid numa id
+    - nvmet-auth: return the error code to the nvmet_auth_host_hash() callers
+    - nvmet-auth: replace pr_debug() with pr_err() to report an error.
+    - nvme: cancel pending I/O if nvme controller is in terminal state
+    - nvmet-tcp: fix possible memory leak when tearing down a controller
+    - nvmet: fix nvme status code when namespace is disabled
+    - nvme-tcp: strict pdu pacing to avoid send stalls on TLS
+    - epoll: be better about file lifetimes
+    - nvmet: prevent sprintf() overflow in nvmet_subsys_nsid_exists()
+    - openpromfs: finish conversion to the new mount API
+    - crypto: bcm - Fix pointer arithmetic
+    - firmware: qcom: qcm: fix unused qcom_scm_qseecom_allowlist
+    - mm/slub, kunit: Use inverted data to corrupt kmem cache
+    - firmware: raspberrypi: Use correct device for DMA mappings
+    - ecryptfs: Fix buffer size for tag 66 packet
+    - nilfs2: fix out-of-range warning
+    - parisc: add missing export of __cmpxchg_u8()
+    - crypto: ccp - drop platform ifdef checks
+    - crypto: x86/nh-avx2 - add missing vzeroupper
+    - crypto: x86/sha256-avx2 - add missing vzeroupper
+    - crypto: x86/sha512-avx2 - add missing vzeroupper
+    - s390/cio: fix tracepoint subchannel type field
+    - io_uring: use the right type for work_llist empty check
+    - rcu-tasks: Fix show_rcu_tasks_trace_gp_kthread buffer overflow
+    - rcu: Fix buffer overflow in print_cpu_stall_info()
+    - ARM: configs: sunxi: Enable DRM_DW_HDMI
+    - jffs2: prevent xattr node from overflowing the eraseblock
+    - libfs: Re-arrange locking in offset_iterate_dir()
+    - libfs: Define a minimum directory offset
+    - libfs: Add simple_offset_empty()
+    - maple_tree: Add mtree_alloc_cyclic()
+    - libfs: Convert simple directory offsets to use a Maple Tree
+    - libfs: Fix simple_offset_rename_exchange()
+    - libfs: Add simple_offset_rename() API
+    - shmem: Fix shmem_rename2()
+    - io-wq: write next_work before dropping acct_lock
+    - mm/userfaultfd: Do not place zeropages when zeropages are disallowed
+    - s390/mm: Re-enable the shared zeropage for !PV and !skeys KVM guests
+    - crypto: octeontx2 - add missing check for dma_map_single
+    - crypto: qat - improve error message in adf_get_arbiter_mapping()
+    - crypto: qat - improve error logging to be consistent across features
+    - soc: qcom: pmic_glink: don't traverse clients list without a lock
+    - soc: qcom: pmic_glink: notify clients about the current state
+    - firmware: qcom: scm: Fix __scm and waitq completion variable initialization
+    - soc: mediatek: cmdq: Fix typo of CMDQ_JUMP_RELATIVE
+    - null_blk: Fix missing mutex_destroy() at module removal
+    - crypto: qat - validate slices count returned by FW
+    - hwrng: stm32 - use logical OR in conditional
+    - hwrng: stm32 - put IP into RPM suspend on failure
+    - hwrng: stm32 - repair clock handling
+    - kunit/fortify: Fix mismatched kvalloc()/vfree() usage
+    - io_uring/net: remove dependency on REQ_F_PARTIAL_IO for sr->done_io
+    - io_uring/net: fix sendzc lazy wake polling
+    - soc: qcom: pmic_glink: Make client-lock non-sleeping
+    - lkdtm: Disable CFI checking for perms functions
+    - md: fix resync softlockup when bitmap size is less than array size
+    - crypto: qat - specify firmware files for 402xx
+    - block: refine the EOF check in blkdev_iomap_begin
+    - block: fix and simplify blkdevparts= cmdline parsing
+    - block: support to account io_ticks precisely
+    - wifi: ath10k: poll service ready message before failing
+    - wifi: brcmfmac: pcie: handle randbuf allocation failure
+    - wifi: ath11k: don't force enable power save on non-running vdevs
+    - bpftool: Fix missing pids during link show
+    - libbpf: Prevent null-pointer dereference when prog to load has no BTF
+    - wifi: ath12k: use correct flag field for 320 MHz channels
+    - wifi: mt76: mt7915: workaround too long expansion sparse warnings
+    - x86/boot: Ignore relocations in .notes sections in walk_relocs() too
+    - wifi: ieee80211: fix ieee80211_mle_basic_sta_prof_size_ok()
+    - wifi: iwlwifi: mvm: Do not warn on invalid link on scan complete
+    - wifi: iwlwifi: mvm: allocate STA links only for active links
+    - wifi: mac80211: don't select link ID if not provided in scan request
+    - wifi: iwlwifi: implement can_activate_links callback
+    - wifi: iwlwifi: mvm: fix active link counting during recovery
+    - wifi: iwlwifi: mvm: select STA mask only for active links
+    - wifi: iwlwifi: reconfigure TLC during HW restart
+    - wifi: iwlwifi: mvm: fix check in iwl_mvm_sta_fw_id_mask
+    - sched/fair: Add EAS checks before updating root_domain::overutilized
+    - ACPI: bus: Indicate support for _TFP thru _OSC
+    - ACPI: bus: Indicate support for more than 16 p-states thru _OSC
+    - ACPI: bus: Indicate support for the Generic Event Device thru _OSC
+    - ACPI: Fix Generic Initiator Affinity _OSC bit
+    - ACPI: bus: Indicate support for IRQ ResourceSource thru _OSC
+    - enetc: avoid truncating error message
+    - qed: avoid truncating work queue length
+    - mlx5: avoid truncating error message
+    - mlx5: stop warning for 64KB pages
+    - bitops: add missing prototype check
+    - dlm: fix user space lock decision to copy lvb
+    - wifi: carl9170: re-fix fortified-memset warning
+    - bpftool: Mount bpffs on provided dir instead of parent dir
+    - bpf: Pack struct bpf_fib_lookup
+    - bpf: prevent r10 register from being marked as precise
+    - x86/microcode/AMD: Avoid -Wformat warning with clang-15
+    - scsi: ufs: qcom: Perform read back after writing reset bit
+    - scsi: ufs: qcom: Perform read back after writing REG_UFS_SYS1CLK_1US
+    - scsi: ufs: qcom: Perform read back after writing unipro mode
+    - scsi: ufs: qcom: Perform read back after writing CGC enable
+    - scsi: ufs: cdns-pltfrm: Perform read back after writing HCLKDIV
+    - scsi: ufs: core: Perform read back after writing UTP_TASK_REQ_LIST_BASE_H
+    - scsi: ufs: core: Perform read back after disabling interrupts
+    - scsi: ufs: core: Perform read back after disabling UIC_COMMAND_COMPL
+    - ACPI: LPSS: Advertise number of chip selects via property
+    - EDAC/skx_common: Allow decoding of SGX addresses
+    - locking/atomic/x86: Correct the definition of __arch_try_cmpxchg128()
+    - irqchip/alpine-msi: Fix off-by-one in allocation error path
+    - irqchip/loongson-pch-msi: Fix off-by-one on allocation error path
+    - ACPI: disable -Wstringop-truncation
+    - gfs2: Don't forget to complete delayed withdraw
+    - gfs2: Fix "ignore unlock failures after withdraw"
+    - arm64: Remove unnecessary irqflags alternative.h include
+    - x86/boot/64: Clear most of CR4 in startup_64(), except PAE, MCE and LA57
+    - selftests/bpf: Fix umount cgroup2 error in test_sockmap
+    - tcp: increase the default TCP scaling ratio
+    - cpufreq: exit() callback is optional
+    - x86/pat: Introduce lookup_address_in_pgd_attr()
+    - x86/pat: Restructure _lookup_address_cpa()
+    - x86/pat: Fix W^X violation false-positives when running as Xen PV guest
+    - udp: Avoid call to compute_score on multiple sites
+    - openrisc: traps: Don't send signals to kernel mode threads
+    - cppc_cpufreq: Fix possible null pointer dereference
+    - wifi: iwlwifi: mvm: init vif works only once
+    - scsi: libsas: Fix the failure of adding phy with zero-address to port
+    - scsi: hpsa: Fix allocation size for Scsi_Host private data
+    - x86/purgatory: Switch to the position-independent small code model
+    - wifi: ath12k: fix out-of-bound access of qmi_invoke_handler()
+    - thermal/drivers/mediatek/lvts_thermal: Add coeff for mt8192
+    - thermal/drivers/tsens: Fix null pointer dereference
+    - dt-bindings: thermal: loongson,ls2k-thermal: Add Loongson-2K0500 compatible
+    - dt-bindings: thermal: loongson,ls2k-thermal: Fix incorrect compatible
+      definition
+    - wifi: ath10k: Fix an error code problem in
+      ath10k_dbg_sta_write_peer_debug_trigger()
+    - gfs2: Remove ill-placed consistency check
+    - gfs2: Fix potential glock use-after-free on unmount
+    - gfs2: finish_xmote cleanup
+    - gfs2: do_xmote fixes
+    - thermal/debugfs: Avoid excessive updates of trip point statistics
+    - selftests/bpf: Fix a fd leak in error paths in open_netns
+    - scsi: ufs: core: mcq: Fix ufshcd_mcq_sqe_search()
+    - cpufreq: brcmstb-avs-cpufreq: ISO C90 forbids mixed declarations
+    - wifi: ath10k: populate board data for WCN3990
+    - net: dsa: mv88e6xxx: Add support for model-specific pre- and post-reset
+      handlers
+    - net: dsa: mv88e6xxx: Avoid EEPROM timeout without EEPROM on 88E6250-family
+      switches
+    - tcp: avoid premature drops in tcp_add_backlog()
+    - thermal/debugfs: Create records for cdev states as they get used
+    - thermal/debugfs: Pass cooling device state to thermal_debug_cdev_add()
+    - pwm: sti: Prepare removing pwm_chip from driver data
+    - pwm: sti: Simplify probe function using devm functions
+    - drivers/perf: hisi_pcie: Fix out-of-bound access when valid event group
+    - drivers/perf: hisi: hns3: Fix out-of-bound access when valid event group
+    - drivers/perf: hisi: hns3: Actually use devm_add_action_or_reset()
+    - net: give more chances to rcu in netdev_wait_allrefs_any()
+    - macintosh/via-macii: Fix "BUG: sleeping function called from invalid
+      context"
+    - wifi: carl9170: add a proper sanity check for endpoints
+    - bpf: Fix verifier assumptions about socket->sk
+    - selftests/bpf: Run cgroup1_hierarchy test in own mount namespace
+    - wifi: ar5523: enable proper endpoint verification
+    - pwm: Drop useless member .of_pwm_n_cells of struct pwm_chip
+    - pwm: Let the of_xlate callbacks accept references without period
+    - pwm: Drop duplicate check against chip->npwm in of_pwm_xlate_with_flags()
+    - pwm: Reorder symbols in core.c
+    - pwm: Provide an inline function to get the parent device of a given chip
+    - pwm: meson: Change prototype of a few helpers to prepare further changes
+    - pwm: meson: Make use of pwmchip_parent() accessor
+    - pwm: meson: Add check for error from clk_round_rate()
+    - pwm: meson: Use mul_u64_u64_div_u64() for frequency calculating
+    - bpf: Add BPF_PROG_TYPE_CGROUP_SKB attach type enforcement in BPF_LINK_CREATE
+    - sh: kprobes: Merge arch_copy_kprobe() into arch_prepare_kprobe()
+    - Revert "sh: Handle calling csum_partial with misaligned data"
+    - wifi: mt76: mt7603: fix tx queue of loopback packets
+    - wifi: mt76: mt7603: add wpdma tx eof flag for PSE client reset
+    - wifi: mt76: mt7996: fix size of txpower MCU command
+    - wifi: mt76: mt7925: ensure 4-byte alignment for suspend & wow command
+    - wifi: mt76: mt7996: fix uninitialized variable in mt7996_irq_tasklet()
+    - wifi: mt76: mt7996: fix potential memory leakage when reading chip
+      temperature
+    - libbpf: Fix error message in attach_kprobe_multi
+    - wifi: nl80211: Avoid address calculations via out of bounds array indexing
+    - wifi: rtw89: wow: refine WoWLAN flows of HCI interrupts and low power mode
+    - selftests/binderfs: use the Makefile's rules, not Make's implicit rules
+    - selftests/resctrl: fix clang build failure: use LOCAL_HDRS
+    - selftests: default to host arch for LLVM builds
+    - kunit: Fix kthread reference
+    - kunit: unregister the device on error
+    - kunit: bail out early in __kunit_test_suites_init() if there are no suites
+      to test
+    - selftests/bpf: Fix pointer arithmetic in test_xdp_do_redirect
+    - HID: intel-ish-hid: ipc: Add check for pci_alloc_irq_vectors
+    - scsi: bfa: Ensure the copied buf is NUL terminated
+    - scsi: qedf: Ensure the copied buf is NUL terminated
+    - scsi: qla2xxx: Fix debugfs output for fw_resource_count
+    - gpio: nuvoton: Fix sgpio irq handle error
+    - x86/numa: Fix SRAT lookup of CFMWS ranges with numa_fill_memblks()
+    - wifi: mwl8k: initialize cmd->addr[] properly
+    - HID: amd_sfh: Handle "no sensors" in PM operations
+    - usb: aqc111: stop lying about skb->truesize
+    - net: usb: sr9700: stop lying about skb->truesize
+    - m68k: Fix spinlock race in kernel thread creation
+    - m68k: mac: Fix reboot hang on Mac IIci
+    - dm-delay: fix workqueue delay_timer race
+    - dm-delay: fix hung task introduced by kthread mode
+    - dm-delay: fix max_delay calculations
+    - ptp: ocp: fix DPLL functions
+    - net: ipv6: fix wrong start position when receive hop-by-hop fragment
+    - eth: sungem: remove .ndo_poll_controller to avoid deadlocks
+    - selftests: net: add missing config for amt.sh
+    - selftests: net: move amt to socat for better compatibility
+    - net: ethernet: mediatek: split tx and rx fields in mtk_soc_data struct
+    - net: ethernet: mediatek: use ADMAv1 instead of ADMAv2.0 on MT7981 and MT7986
+    - ice: Fix package download algorithm
+    - net: ethernet: cortina: Locking fixes
+    - af_unix: Fix data races in unix_release_sock/unix_stream_sendmsg
+    - net: usb: smsc95xx: stop lying about skb->truesize
+    - net: openvswitch: fix overwriting ct original tuple for ICMPv6
+    - ipv6: sr: add missing seg6_local_exit
+    - ipv6: sr: fix incorrect unregister order
+    - ipv6: sr: fix invalid unregister error path
+    - net/mlx5: Fix peer devlink set for SF representor devlink port
+    - net/mlx5: Reload only IB representors upon lag disable/enable
+    - net/mlx5: Add a timeout to acquire the command queue semaphore
+    - net/mlx5: Discard command completions in internal error
+    - s390/bpf: Emit a barrier for BPF_FETCH instructions
+    - riscv, bpf: make some atomic operations fully ordered
+    - ax25: Use kernel universal linked list to implement ax25_dev_list
+    - ax25: Fix reference count leak issues of ax25_dev
+    - ax25: Fix reference count leak issue of net_device
+    - dpll: fix return value check for kmemdup
+    - net: fec: remove .ndo_poll_controller to avoid deadlocks
+    - mptcp: SO_KEEPALIVE: fix getsockopt support
+    - mptcp: cleanup writer wake-up
+    - mptcp: avoid some duplicate code in socket option handling
+    - mptcp: implement TCP_NOTSENT_LOWAT support
+    - mptcp: cleanup SOL_TCP handling
+    - mptcp: fix full TCP keep-alive support
+    - net: stmmac: Offload queueMaxSDU from tc-taprio
+    - net: stmmac: est: Per Tx-queue error count for HLBF
+    - net: stmmac: Report taprio offload status
+    - net: stmmac: move the EST lock to struct stmmac_priv
+    - net: micrel: Fix receiving the timestamp in the frame for lan8841
+    - Bluetooth: compute LE flow credits based on recvbuf space
+    - Bluetooth: qca: Fix error code in qca_read_fw_build_info()
+    - Bluetooth: ISO: Add hcon for listening bis sk
+    - Bluetooth: ISO: Clean up returns values in iso_connect_ind()
+    - Bluetooth: ISO: Make iso_get_sock_listen generic
+    - Bluetooth: Remove usage of the deprecated ida_simple_xx() API
+    - Bluetooth: hci_event: Remove code to removed CONFIG_BT_HS
+    - Bluetooth: HCI: Remove HCI_AMP support
+    - ice: make ice_vsi_cfg_rxq() static
+    - ice: make ice_vsi_cfg_txq() static
+    - overflow: Change DEFINE_FLEX to take __counted_by member
+    - Bluetooth: hci_conn, hci_sync: Use __counted_by() to avoid -Wfamnae warnings
+    - Bluetooth: hci_core: Fix not handling hdev->le_num_of_adv_sets=1
+    - drm/bridge: Fix improper bridge init order with pre_enable_prev_first
+    - drm/ci: update device type for volteer devices
+    - drm/nouveau/dp: Fix incorrect return code in r535_dp_aux_xfer()
+    - drm/omapdrm: Fix console by implementing fb_dirty
+    - drm/omapdrm: Fix console with deferred ops
+    - printk: Let no_printk() use _printk()
+    - dev_printk: Add and use dev_no_printk()
+    - drm/lcdif: Do not disable clocks on already suspended hardware
+    - drm/dp: Don't attempt AUX transfers when eDP panels are not powered
+    - drm/panel: atna33xc20: Fix unbalanced regulator in the case HPD doesn't
+      assert
+    - drm/amd/display: Fix potential index out of bounds in color transformation
+      function
+    - drm/amd/display: Remove redundant condition in dcn35_calc_blocks_to_gate()
+    - ASoC: Intel: Disable route checks for Skylake boards
+    - ASoC: Intel: avs: ssm4567: Do not ignore route checks
+    - mtd: core: Report error if first mtd_otp_size() call fails in
+      mtd_otp_nvmem_add()
+    - mtd: rawnand: hynix: fixed typo
+    - drm/imagination: avoid -Woverflow warning
+    - ASoC: mediatek: Assign dummy when codec not specified for a DAI link
+    - drm/panel: ltk050h3146w: add MIPI_DSI_MODE_VIDEO to LTK050H3148W flags
+    - drm/panel: ltk050h3146w: drop duplicate commands from LTK050H3148W init
+    - fbdev: shmobile: fix snprintf truncation
+    - ASoC: kirkwood: Fix potential NULL dereference
+    - drm/meson: vclk: fix calculation of 59.94 fractional rates
+    - drm/mediatek: Add 0 size check to mtk_drm_gem_obj
+    - drm/mediatek: Init `ddp_comp` with devm_kcalloc()
+    - ASoC: SOF: Intel: hda-dai: fix channel map configuration for aggregated
+      dailink
+    - powerpc/fsl-soc: hide unused const variable
+    - ASoC: SOF: Intel: mtl: Correct rom_status_reg
+    - ASoC: SOF: Intel: lnl: Correct rom_status_reg
+    - ASoC: SOF: Intel: mtl: Disable interrupts when firmware boot failed
+    - ASoC: SOF: Intel: mtl: Implement firmware boot state check
+    - fbdev: sisfb: hide unused variables
+    - selftests: cgroup: skip test_cgcore_lesser_ns_open when cgroup2 mounted
+      without nsdelegate
+    - ASoC: Intel: avs: Restore stream decoupling on prepare
+    - ASoC: Intel: avs: Fix ASRC module initialization
+    - ASoC: Intel: avs: Fix potential integer overflow
+    - ASoC: Intel: avs: Test result of avs_get_module_entry()
+    - media: ngene: Add dvb_ca_en50221_init return value check
+    - staging: media: starfive: Remove links when unregistering devices
+    - media: rcar-vin: work around -Wenum-compare-conditional warning
+    - media: radio-shark2: Avoid led_names truncations
+    - drm: bridge: cdns-mhdp8546: Fix possible null pointer dereference
+    - platform/x86: xiaomi-wmi: Fix race condition when reporting key events
+    - drm/msm/dp: allow voltage swing / pre emphasis of 3
+    - drm/msm/dp: Avoid a long timeout for AUX transfer if nothing connected
+    - media: ipu3-cio2: Request IRQ earlier
+    - media: dt-bindings: ovti,ov2680: Fix the power supply names
+    - media: i2c: et8ek8: Don't strip remove function when driver is builtin
+    - media: v4l2-subdev: Fix stream handling for crop API
+    - fbdev: sh7760fb: allow modular build
+    - media: atomisp: ssh_css: Fix a null-pointer dereference in
+      load_video_binaries
+    - drm/arm/malidp: fix a possible null pointer dereference
+    - drm: vc4: Fix possible null pointer dereference
+    - ASoC: tracing: Export SND_SOC_DAPM_DIR_OUT to its value
+    - drm/bridge: anx7625: Don't log an error when DSI host can't be found
+    - drm/bridge: icn6211: Don't log an error when DSI host can't be found
+    - drm/bridge: lt8912b: Don't log an error when DSI host can't be found
+    - drm/bridge: lt9611: Don't log an error when DSI host can't be found
+    - drm/bridge: lt9611uxc: Don't log an error when DSI host can't be found
+    - drm/bridge: tc358775: Don't log an error when DSI host can't be found
+    - drm/bridge: dpc3433: Don't log an error when DSI host can't be found
+    - drm/panel: novatek-nt35950: Don't log an error when DSI host can't be found
+    - drm/bridge: anx7625: Update audio status while detecting
+    - drm/panel: simple: Add missing Innolux G121X1-L03 format, flags, connector
+    - ALSA: hda: cs35l41: Remove Speaker ID for Lenovo Legion slim 7 16ARHA7
+    - drm/mipi-dsi: use correct return type for the DSC functions
+    - media: uvcvideo: Add quirk for Logitech Rally Bar
+    - drm/rockchip: vop2: Do not divide height twice for YUV
+    - drm/edid: Parse topology block for all DispID structure v1.x
+    - media: cadence: csi2rx: configure DPHY before starting source stream
+    - clk: samsung: exynosautov9: fix wrong pll clock id value
+    - RDMA/mlx5: Uncacheable mkey has neither rb_key or cache_ent
+    - RDMA/mlx5: Change check for cacheable mkeys
+    - RDMA/mlx5: Adding remote atomic access flag to updatable flags
+    - clk: mediatek: pllfh: Don't log error for missing fhctl node
+    - iommu: Undo pasid attachment only for the devices that have succeeded
+    - RDMA/hns: Fix return value in hns_roce_map_mr_sg
+    - RDMA/hns: Fix deadlock on SRQ async events.
+    - RDMA/hns: Fix UAF for cq async event
+    - RDMA/hns: Fix GMV table pagesize
+    - RDMA/hns: Use complete parentheses in macros
+    - RDMA/hns: Modify the print level of CQE error
+    - clk: mediatek: mt8365-mm: fix DPI0 parent
+    - clk: rs9: fix wrong default value for clock amplitude
+    - clk: qcom: clk-alpha-pll: remove invalid Stromer register offset
+    - RDMA/rxe: Fix seg fault in rxe_comp_queue_pkt
+    - RDMA/rxe: Allow good work requests to be executed
+    - RDMA/rxe: Fix incorrect rxe_put in error path
+    - IB/mlx5: Use __iowrite64_copy() for write combining stores
+    - clk: renesas: r8a779a0: Fix CANFD parent clock
+    - clk: renesas: r9a07g043: Add clock and reset entry for PLIC
+    - lib/test_hmm.c: handle src_pfns and dst_pfns allocation failure
+    - mm/ksm: fix ksm exec support for prctl
+    - clk: qcom: dispcc-sm8450: fix DisplayPort clocks
+    - clk: qcom: dispcc-sm6350: fix DisplayPort clocks
+    - clk: qcom: dispcc-sm8550: fix DisplayPort clocks
+    - clk: qcom: dispcc-sm8650: fix DisplayPort clocks
+    - clk: qcom: mmcc-msm8998: fix venus clock issue
+    - x86/insn: Fix PUSH instruction in x86 instruction decoder opcode map
+    - x86/insn: Add VEX versions of VPDPBUSD, VPDPBUSDS, VPDPWSSD and VPDPWSSDS
+    - ext4: avoid excessive credit estimate in ext4_tmpfile()
+    - RDMA/mana_ib: Introduce helpers to create and destroy mana queues
+    - RDMA/mana_ib: Use struct mana_ib_queue for CQs
+    - RDMA/mana_ib: boundary check before installing cq callbacks
+    - virt: acrn: stop using follow_pfn
+    - drivers/virt/acrn: fix PFNMAP PTE checks in acrn_vm_ram_map()
+    - sunrpc: removed redundant procp check
+    - nfsd: don't create nfsv4recoverydir in nfsdfs when not used.
+    - ext4: fix potential unnitialized variable
+    - ext4: remove the redundant folio_wait_stable()
+    - clk: qcom: Fix SC_CAMCC_8280XP dependencies
+    - [Config] updateconfigs for SC_CAMCC_8280XP
+    - clk: qcom: Fix SM_GPUCC_8650 dependencies
+    - [Config] updateconfigs for SM_GPUCC_8650
+    - clk: qcom: apss-ipq-pll: fix PLL rate for IPQ5018
+    - of: module: add buffer overflow check in of_modalias()
+    - bnxt_re: avoid shift undefined behavior in bnxt_qplib_alloc_init_hwq
+    - SUNRPC: Fix gss_free_in_token_pages()
+    - selftests/damon/_damon_sysfs: check errors from nr_schemes file reads
+    - selftests/kcmp: remove unused open mode
+    - RDMA/IPoIB: Fix format truncation compilation errors
+    - RDMA/cma: Fix kmemleak in rdma_core observed during blktests nvme/rdma use
+      siw
+    - samples/landlock: Fix incorrect free in populate_ruleset_net
+    - tracing/user_events: Prepare find/delete for same name events
+    - tracing/user_events: Fix non-spaced field matching
+    - modules: Drop the .export_symbol section from the final modules
+    - net: bridge: xmit: make sure we have at least eth header len bytes
+    - selftests: net: bridge: increase IGMP/MLD exclude timeout membership
+      interval
+    - net: bridge: mst: fix vlan use-after-free
+    - net: qrtr: ns: Fix module refcnt
+    - selftests/net/lib: no need to record ns name if it already exist
+    - idpf: don't skip over ethtool tcp-data-split setting
+    - netrom: fix possible dead-lock in nr_rt_ioctl()
+    - af_packet: do not call packet_read_pending() from tpacket_destruct_skb()
+    - sched/fair: Allow disabling sched_balance_newidle with
+      sched_relax_domain_level
+    - sched/core: Fix incorrect initialization of the 'burst' parameter in
+      cpu_max_write()
+    - net: wangxun: fix to change Rx features
+    - net: wangxun: match VLAN CTAG and STAG features
+    - net: txgbe: move interrupt codes to a separate file
+    - net: txgbe: use irq_domain for interrupt controller
+    - net: txgbe: fix to control VLAN strip
+    - l2tp: fix ICMP error handling for UDP-encap sockets
+    - io_uring/net: ensure async prep handlers always initialize ->done_io
+    - pwm: Fix setting period with #pwm-cells = <1> and of_pwm_single_xlate()
+    - net: txgbe: fix to clear interrupt status after handling IRQ
+    - net: txgbe: fix GPIO interrupt blocking
+    - Linux 6.8.12
+
+  * Noble update: v6.8.11 upstream stable release (LP: #2070355)
+    - drm/amd/display: Fix division by zero in setup_dsc_config
+    - net: ks8851: Fix another TX stall caused by wrong ISR flag handling
+    - ice: pass VSI pointer into ice_vc_isvalid_q_id
+    - ice: remove unnecessary duplicate checks for VF VSI ID
+    - Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_connect()
+    - Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init()
+    - KEYS: trusted: Fix memory leak in tpm2_key_encode()
+    - erofs: get rid of erofs_fs_context
+    - erofs: reliably distinguish block based and fscache mode
+    - binder: fix max_thread type inconsistency
+    - usb: dwc3: Wait unconditionally after issuing EndXfer command
+    - net: usb: ax88179_178a: fix link status when link is set to down/up
+    - usb: typec: ucsi: displayport: Fix potential deadlock
+    - usb: typec: tipd: fix event checking for tps25750
+    - usb: typec: tipd: fix event checking for tps6598x
+    - serial: kgdboc: Fix NMI-safety problems from keyboard reset code
+    - remoteproc: mediatek: Make sure IPI buffer fits in L2TCM
+    - KEYS: trusted: Do not use WARN when encode fails
+    - admin-guide/hw-vuln/core-scheduling: fix return type of PR_SCHED_CORE_GET
+    - docs: kernel_include.py: Cope with docutils 0.21
+    - Docs/admin-guide/mm/damon/usage: fix wrong example of DAMOS filter matching
+      sysfs file
+    - block: add a disk_has_partscan helper
+    - block: add a partscan sysfs attribute for disks
+    - Linux 6.8.11
+
+  * Noble update: v6.8.10 upstream stable release (LP: #2070349)
+    - rust: module: place generated init_module() function in .init.text
+    - rust: macros: fix soundness issue in `module!` macro
+    - wifi: nl80211: don't free NULL coalescing rule
+    - pinctrl: pinctrl-aspeed-g6: Fix register offset for pinconf of GPIOR-T
+    - pinctrl/meson: fix typo in PDM's pin name
+    - pinctrl: core: delete incorrect free in pinctrl_enable()
+    - pinctrl: mediatek: paris: Fix PIN_CONFIG_INPUT_SCHMITT_ENABLE readback
+    - pinctrl: mediatek: paris: Rework support for
+      PIN_CONFIG_{INPUT,OUTPUT}_ENABLE
+    - sunrpc: add a struct rpc_stats arg to rpc_create_args
+    - nfs: expose /proc/net/sunrpc/nfs in net namespaces
+    - nfs: make the rpc_stat per net namespace
+    - nfs: Handle error of rpc_proc_register() in nfs_net_init().
+    - pinctrl: baytrail: Fix selecting gpio pinctrl state
+    - power: rt9455: hide unused rt9455_boost_voltage_values
+    - power: supply: mt6360_charger: Fix of_match for usb-otg-vbus regulator
+    - pinctrl: devicetree: fix refcount leak in pinctrl_dt_to_map()
+    - nfsd: rename NFSD_NET_* to NFSD_STATS_*
+    - nfsd: expose /proc/net/sunrpc/nfsd in net namespaces
+    - nfsd: make all of the nfsd stats per-network namespace
+    - NFSD: add support for CB_GETATTR callback
+    - NFSD: Fix nfsd4_encode_fattr4() crasher
+    - regulator: mt6360: De-capitalize devicetree regulator subnodes
+    - regulator: change stubbed devm_regulator_get_enable to return Ok
+    - regulator: change devm_regulator_get_enable_optional() stub to return Ok
+    - bpf, kconfig: Fix DEBUG_INFO_BTF_MODULES Kconfig definition
+    - bpf, skmsg: Fix NULL pointer dereference in sk_psock_skb_ingress_enqueue
+    - regmap: Add regmap_read_bypassed()
+    - ASoC: SOF: Intel: add default firmware library path for LNL
+    - nvme: fix warn output about shared namespaces without CONFIG_NVME_MULTIPATH
+    - bpf: Fix a verifier verbose message
+    - spi: axi-spi-engine: use common AXI macros
+    - spi: axi-spi-engine: fix version format string
+    - spi: hisi-kunpeng: Delete the dump interface of data registers in debugfs
+    - bpf, arm64: Fix incorrect runtime stats
+    - riscv, bpf: Fix incorrect runtime stats
+    - ASoC: Intel: avs: Set name of control as in topology
+    - ASoC: codecs: wsa881x: set clk_stop_mode1 flag
+    - s390/mm: Fix storage key clearing for guest huge pages
+    - s390/mm: Fix clearing storage keys for huge pages
+    - arm32, bpf: Reimplement sign-extension mov instruction
+    - xdp: use flags field to disambiguate broadcast redirect
+    - efi/unaccepted: touch soft lockup during memory accept
+    - ice: ensure the copied buf is NUL terminated
+    - bna: ensure the copied buf is NUL terminated
+    - octeontx2-af: avoid off-by-one read from userspace
+    - thermal/debugfs: Free all thermal zone debug memory on zone removal
+    - thermal/debugfs: Fix two locking issues with thermal zone debug
+    - nsh: Restore skb->{protocol,data,mac_header} for outer header in
+      nsh_gso_segment().
+    - net l2tp: drop flow hash on forward
+    - thermal/debugfs: Prevent use-after-free from occurring after cdev removal
+    - s390/vdso: Add CFI for RA register to asm macro vdso_func
+    - Fix a potential infinite loop in extract_user_to_sg()
+    - ALSA: emu10k1: fix E-MU card dock presence monitoring
+    - ALSA: emu10k1: factor out snd_emu1010_load_dock_firmware()
+    - ALSA: emu10k1: move the whole GPIO event handling to the workqueue
+    - ALSA: emu10k1: fix E-MU dock initialization
+    - net: qede: sanitize 'rc' in qede_add_tc_flower_fltr()
+    - net: qede: use return from qede_parse_flow_attr() for flower
+    - net: qede: use return from qede_parse_flow_attr() for flow_spec
+    - net: qede: use return from qede_parse_actions()
+    - vxlan: Fix racy device stats updates.
+    - vxlan: Add missing VNI filter counter update in arp_reduce().
+    - ASoC: meson: axg-fifo: use FIELD helpers
+    - ASoC: meson: axg-fifo: use threaded irq to check periods
+    - ASoC: meson: axg-card: make links nonatomic
+    - ASoC: meson: axg-tdm-interface: manage formatters in trigger
+    - ASoC: meson: cards: select SND_DYNAMIC_MINORS
+    - ALSA: hda: intel-sdw-acpi: fix usage of device_get_named_child_node()
+    - s390/cio: Ensure the copied buf is NUL terminated
+    - cxgb4: Properly lock TX queue for the selftest.
+    - net: dsa: mv88e6xxx: Fix number of databases for 88E6141 / 88E6341
+    - drm/amdgpu: fix doorbell regression
+    - spi: fix null pointer dereference within spi_sync
+    - net: bridge: fix multicast-to-unicast with fraglist GSO
+    - net: core: reject skb_copy(_expand) for fraglist GSO skbs
+    - rxrpc: Clients must accept conn from any address
+    - tipc: fix a possible memleak in tipc_buf_append
+    - vxlan: Pull inner IP header in vxlan_rcv().
+    - s390/qeth: Fix kernel panic after setting hsuid
+    - drm/panel: ili9341: Correct use of device property APIs
+    - [Config] updateconfigs for DRM_PANEL_ILITEK_ILI9341
+    - drm/panel: ili9341: Respect deferred probe
+    - drm/panel: ili9341: Use predefined error codes
+    - ipv4: Fix uninit-value access in __ip_make_skb()
+    - net: gro: fix udp bad offset in socket lookup by adding
+      {inner_}network_offset to napi_gro_cb
+    - net: gro: add flush check in udp_gro_receive_segment
+    - drm/xe/display: Fix ADL-N detection
+    - clk: qcom: smd-rpm: Restore msm8976 num_clk
+    - clk: sunxi-ng: h6: Reparent CPUX during PLL CPUX rate change
+    - powerpc/pseries: make max polling consistent for longer H_CALLs
+    - powerpc/pseries/iommu: LPAR panics during boot up with a frozen PE
+    - EDAC/versal: Do not log total error counts
+    - swiotlb: initialise restricted pool list_head when SWIOTLB_DYNAMIC=y
+    - KVM: arm64: vgic-v2: Check for non-NULL vCPU in vgic_v2_parse_attr()
+    - exfat: fix timing of synchronizing bitmap and inode
+    - firmware: microchip: don't unconditionally print validation success
+    - scsi: ufs: core: Fix MCQ MAC configuration
+    - scsi: lpfc: Move NPIV's transport unregistration to after resource clean up
+    - scsi: lpfc: Remove IRQF_ONESHOT flag from threaded IRQ handling
+    - scsi: lpfc: Update lpfc_ramp_down_queue_handler() logic
+    - scsi: lpfc: Replace hbalock with ndlp lock in lpfc_nvme_unregister_port()
+    - scsi: lpfc: Release hbalock before calling lpfc_worker_wake_up()
+    - scsi: lpfc: Use a dedicated lock for ras_fwlog state
+    - gfs2: Fix invalid metadata access in punch_hole
+    - fs/9p: fix uninitialized values during inode evict
+    - wifi: mac80211: fix ieee80211_bss_*_flags kernel-doc
+    - wifi: cfg80211: fix rdev_dump_mpp() arguments order
+    - wifi: mac80211: fix prep_connection error path
+    - wifi: iwlwifi: read txq->read_ptr under lock
+    - wifi: iwlwifi: mvm: guard against invalid STA ID on removal
+    - net: mark racy access on sk->sk_rcvbuf
+    - drm/xe: Fix END redefinition
+    - scsi: mpi3mr: Avoid memcpy field-spanning write WARNING
+    - scsi: bnx2fc: Remove spin_lock_bh while releasing resources after upload
+    - btrfs: return accurate error code on open failure in open_fs_devices()
+    - drm/amdkfd: Check cgroup when returning DMABuf info
+    - drm/amdkfd: range check cp bad op exception interrupts
+    - bpf: Check bloom filter map value size
+    - selftests/ftrace: Fix event filter target_func selection
+    - kbuild: Disable KCSAN for autogenerated *.mod.c intermediaries
+    - ASoC: SOF: Intel: hda-dsp: Skip IMR boot on ACE platforms in case of S3
+      suspend
+    - regulator: tps65132: Add of_match table
+    - OSS: dmasound/paula: Mark driver struct with __refdata to prevent section
+      mismatch
+    - scsi: ufs: core: WLUN suspend dev/link state error recovery
+    - scsi: libsas: Align SMP request allocation to ARCH_DMA_MINALIGN
+    - scsi: ufs: core: Fix MCQ mode dev command timeout
+    - ALSA: line6: Zero-initialize message buffers
+    - block: fix overflow in blk_ioctl_discard()
+    - ASoC: codecs: ES8326: Solve error interruption issue
+    - ASoC: codecs: ES8326: modify clock table
+    - net: bcmgenet: Reset RBUF on first open
+    - vboxsf: explicitly deny setlease attempts
+    - ata: sata_gemini: Check clk_enable() result
+    - firewire: ohci: mask bus reset interrupts between ISR and bottom half
+    - tools/power turbostat: Fix added raw MSR output
+    - tools/power turbostat: Increase the limit for fd opened
+    - tools/power turbostat: Fix Bzy_MHz documentation typo
+    - tools/power turbostat: Do not print negative LPI residency
+    - tools/power turbostat: Expand probe_intel_uncore_frequency()
+    - tools/power turbostat: Print ucode revision only if valid
+    - tools/power turbostat: Fix warning upon failed /dev/cpu_dma_latency read
+    - btrfs: make btrfs_clear_delalloc_extent() free delalloc reserve
+    - btrfs: always clear PERTRANS metadata during commit
+    - memblock tests: fix undefined reference to `early_pfn_to_nid'
+    - memblock tests: fix undefined reference to `panic'
+    - memblock tests: fix undefined reference to `BIT'
+    - nouveau/gsp: Avoid addressing beyond end of rpc->entries
+    - scsi: target: Fix SELinux error when systemd-modules loads the target module
+    - scsi: hisi_sas: Handle the NCQ error returned by D2H frame
+    - blk-iocost: avoid out of bounds shift
+    - accel/ivpu: Remove d3hot_after_power_off WA
+    - accel/ivpu: Improve clarity of MMU error messages
+    - accel/ivpu: Fix missed error message after VPU rename
+    - platform/x86: acer-wmi: Add support for Acer PH18-71
+    - gpu: host1x: Do not setup DMA for virtual devices
+    - MIPS: scall: Save thread_info.syscall unconditionally on entry
+    - tools/power/turbostat: Fix uncore frequency file string
+    - net: add copy_safe_from_sockptr() helper
+    - nfc: llcp: fix nfc_llcp_setsockopt() unsafe copies
+    - drm/amdgpu: Refine IB schedule error logging
+    - drm/amd/display: add DCN 351 version for microcode load
+    - drm/amdgpu: add smu 14.0.1 discovery support
+    - drm/amdgpu: implement IRQ_STATE_ENABLE for SDMA v4.4.2
+    - drm/amd/display: Skip on writeback when it's not applicable
+    - drm/amd/pm: fix the high voltage issue after unload
+    - drm/amdgpu: Fix VCN allocation in CPX partition
+    - amd/amdkfd: sync all devices to wait all processes being evicted
+    - selftests: timers: Fix valid-adjtimex signed left-shift undefined behavior
+    - Drivers: hv: vmbus: Leak pages if set_memory_encrypted() fails
+    - Drivers: hv: vmbus: Track decrypted status in vmbus_gpadl
+    - hv_netvsc: Don't free decrypted memory
+    - uio_hv_generic: Don't free decrypted memory
+    - Drivers: hv: vmbus: Don't free ring buffers that couldn't be re-encrypted
+    - drm/xe/xe_migrate: Cast to output precision before multiplying operands
+    - drm/xe: Label RING_CONTEXT_CONTROL as masked
+    - smb3: fix broken reconnect when password changing on the server by allowing
+      password rotation
+    - iommu: mtk: fix module autoloading
+    - fs/9p: only translate RWX permissions for plain 9P2000
+    - fs/9p: translate O_TRUNC into OTRUNC
+    - fs/9p: fix the cache always being enabled on files with qid flags
+    - 9p: explicitly deny setlease attempts
+    - powerpc/crypto/chacha-p10: Fix failure on non Power10
+    - gpio: wcove: Use -ENOTSUPP consistently
+    - gpio: crystalcove: Use -ENOTSUPP consistently
+    - clk: Don't hold prepare_lock when calling kref_put()
+    - fs/9p: remove erroneous nlink init from legacy stat2inode
+    - fs/9p: drop inodes immediately on non-.L too
+    - gpio: lpc32xx: fix module autoloading
+    - drm/nouveau/dp: Don't probe eDP ports twice harder
+    - platform/x86/amd: pmf: Decrease error message to debug
+    - platform/x86: ISST: Add Granite Rapids-D to HPM CPU list
+    - drm/radeon: silence UBSAN warning (v3)
+    - net:usb:qmi_wwan: support Rolling modules
+    - blk-iocost: do not WARN if iocg was already offlined
+    - SUNRPC: add a missing rpc_stat for TCP TLS
+    - qibfs: fix dentry leak
+    - xfrm: Preserve vlan tags for transport mode software GRO
+    - ARM: 9381/1: kasan: clear stale stack poison
+    - tcp: defer shutdown(SEND_SHUTDOWN) for TCP_SYN_RECV sockets
+    - tcp: Use refcount_inc_not_zero() in tcp_twsk_unique().
+    - Bluetooth: Fix use-after-free bugs caused by sco_sock_timeout
+    - Bluetooth: msft: fix slab-use-after-free in msft_do_close()
+    - arm64: dts: mediatek: mt8183-pico6: Fix bluetooth node
+    - Bluetooth: HCI: Fix potential null-ptr-deref
+    - Bluetooth: l2cap: fix null-ptr-deref in l2cap_chan_timeout
+    - net: ks8851: Queue RX packets in IRQ handler instead of disabling BHs
+    - rtnetlink: Correct nested IFLA_VF_VLAN_LIST attribute validation
+    - hwmon: (corsair-cpro) Use a separate buffer for sending commands
+    - hwmon: (corsair-cpro) Use complete_all() instead of complete() in
+      ccp_raw_event()
+    - hwmon: (corsair-cpro) Protect ccp->wait_input_report with a spinlock
+    - phonet: fix rtm_phonet_notify() skb allocation
+    - netlink: specs: Add missing bridge linkinfo attrs
+    - nfc: nci: Fix kcov check in nci_rx_work()
+    - net: bridge: fix corrupted ethernet header on multicast-to-unicast
+    - ipv6: Fix potential uninit-value access in __ip6_make_skb()
+    - selftests: test_bridge_neigh_suppress.sh: Fix failures due to duplicate MAC
+    - rxrpc: Fix the names of the fields in the ACK trailer struct
+    - rxrpc: Fix congestion control algorithm
+    - rxrpc: Only transmit one ACK per jumbo packet received
+    - dt-bindings: net: mediatek: remove wrongly added clocks and SerDes
+    - ipv6: fib6_rules: avoid possible NULL dereference in fib6_rule_action()
+    - net-sysfs: convert dev->operstate reads to lockless ones
+    - hsr: Simplify code for announcing HSR nodes timer setup
+    - ipv6: annotate data-races around cnf.disable_ipv6
+    - ipv6: prevent NULL dereference in ip6_output()
+    - net/smc: fix neighbour and rtable leak in smc_ib_find_route()
+    - net: hns3: using user configure after hardware reset
+    - net: hns3: direct return when receive a unknown mailbox message
+    - net: hns3: change type of numa_node_mask as nodemask_t
+    - net: hns3: release PTP resources if pf initialization failed
+    - net: hns3: use appropriate barrier function after setting a bit value
+    - net: hns3: fix port vlan filter not disabled issue
+    - net: hns3: fix kernel crash when devlink reload during initialization
+    - net: dsa: mv88e6xxx: add phylink_get_caps for the mv88e6320/21 family
+    - drm/meson: dw-hdmi: power up phy on device init
+    - drm/meson: dw-hdmi: add bandgap setting for g12
+    - drm/connector: Add \n to message about demoting connector force-probes
+    - dm/amd/pm: Fix problems with reboot/shutdown for some SMU 13.0.4/13.0.11
+      users
+    - gpiolib: cdev: Fix use after free in lineinfo_changed_notify
+    - gpiolib: cdev: fix uninitialised kfifo
+    - drm/amdgpu: Fix comparison in amdgpu_res_cpu_visible
+    - drm/amdgpu: once more fix the call oder in amdgpu_ttm_move() v2
+    - firewire: nosy: ensure user_length is taken into account when fetching
+      packet contents
+    - Reapply "drm/qxl: simplify qxl_fence_wait"
+    - usb: typec: ucsi: Check for notifications after init
+    - usb: typec: ucsi: Fix connector check on init
+    - usb: Fix regression caused by invalid ep0 maxpacket in virtual SuperSpeed
+      device
+    - usb: ohci: Prevent missed ohci interrupts
+    - USB: core: Fix access violation during port device removal
+    - usb: gadget: composite: fix OS descriptors w_value logic
+    - usb: gadget: uvc: use correct buffer size when parsing configfs lists
+    - usb: gadget: f_fs: Fix race between aio_cancel() and AIO request complete
+    - usb: gadget: f_fs: Fix a race condition when processing setup packets.
+    - usb: xhci-plat: Don't include xhci.h
+    - usb: dwc3: core: Prevent phy suspend during init
+    - usb: typec: tcpm: clear pd_event queue in PORT_RESET
+    - usb: typec: tcpm: unregister existing source caps before re-registration
+    - usb: typec: tcpm: Check for port partner validity before consuming it
+    - ALSA: hda/realtek: Fix mute led of HP Laptop 15-da3001TU
+    - ALSA: hda/realtek: Fix conflicting PCI SSID 17aa:386f for Lenovo Legion
+      models
+    - firewire: ohci: fulfill timestamp for some local asynchronous transaction
+    - mm/slub: avoid zeroing outside-object freepointer for single free
+    - btrfs: add missing mutex_unlock in btrfs_relocate_sys_chunks()
+    - btrfs: set correct ram_bytes when splitting ordered extent
+    - btrfs: qgroup: do not check qgroup inherit if qgroup is disabled
+    - btrfs: make sure that WRITTEN is set on all metadata blocks
+    - maple_tree: fix mas_empty_area_rev() null pointer dereference
+    - mm/slab: make __free(kfree) accept error pointers
+    - mptcp: ensure snd_nxt is properly initialized on connect
+    - mptcp: only allow set existing scheduler for net.mptcp.scheduler
+    - workqueue: Fix selection of wake_cpu in kick_pool()
+    - dt-bindings: iio: health: maxim,max30102: fix compatible check
+    - iio:imu: adis16475: Fix sync mode setting
+    - iio: pressure: Fixes BME280 SPI driver data
+    - iio: pressure: Fixes SPI support for BMP3xx devices
+    - iio: accel: mxc4005: Interrupt handling fixes
+    - iio: accel: mxc4005: Reset chip on probe() and resume()
+    - kmsan: compiler_types: declare __no_sanitize_or_inline
+    - e1000e: change usleep_range to udelay in PHY mdic access
+    - tipc: fix UAF in error path
+    - xtensa: fix MAKE_PC_FROM_RA second argument
+    - net: bcmgenet: synchronize EXT_RGMII_OOB_CTRL access
+    - net: bcmgenet: synchronize use of bcmgenet_set_rx_mode()
+    - net: bcmgenet: synchronize UMAC_CMD access
+    - ASoC: tegra: Fix DSPK 16-bit playback
+    - ASoC: ti: davinci-mcasp: Fix race condition during probe
+    - dyndbg: fix old BUG_ON in >control parser
+    - slimbus: qcom-ngd-ctrl: Add timeout for wait operation
+    - clk: samsung: Revert "clk: Use device_get_match_data()"
+    - clk: sunxi-ng: common: Support minimum and maximum rate
+    - clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI
+    - mei: me: add lunar lake point M DID
+    - drm/nouveau/firmware: Fix SG_DEBUG error with nvkm_firmware_ctor()
+    - Revert "drm/nouveau/firmware: Fix SG_DEBUG error with nvkm_firmware_ctor()"
+    - drm/amdkfd: don't allow mapping the MMIO HDP page with large pages
+    - drm/ttm: Print the memory decryption status just once
+    - drm/vmwgfx: Fix Legacy Display Unit
+    - drm/vmwgfx: Fix invalid reads in fence signaled events
+    - drm/imagination: Ensure PVR_MIPS_PT_PAGE_COUNT is never zero
+    - drm/amd/display: Fix idle optimization checks for multi-display and dual eDP
+    - drm/nouveau/gsp: Use the sg allocator for level 2 of radix3
+    - drm/i915/gt: Automate CCS Mode setting during engine resets
+    - drm/i915/bios: Fix parsing backlight BDB data
+    - drm/amd/display: Handle Y carry-over in VCP X.Y calculation
+    - drm/amd/display: Fix incorrect DSC instance for MST
+    - arm64: dts: qcom: sa8155p-adp: fix SDHC2 CD pin configuration
+    - iommu/arm-smmu: Use the correct type in nvidia_smmu_context_fault()
+    - net: fix out-of-bounds access in ops_init
+    - hwmon: (pmbus/ucd9000) Increase delay from 250 to 500us
+    - misc/pvpanic-pci: register attributes via pci_driver
+    - x86/apic: Don't access the APIC when disabling x2APIC
+    - selftests/mm: fix powerpc ARCH check
+    - mm: use memalloc_nofs_save() in page_cache_ra_order()
+    - mm/userfaultfd: reset ptes when close() for wr-protected ones
+    - iommu/amd: Enhance def_domain_type to handle untrusted device
+    - fs/proc/task_mmu: fix loss of young/dirty bits during pagemap scan
+    - fs/proc/task_mmu: fix uffd-wp confusion in pagemap_scan_pmd_entry()
+    - nvme-pci: Add quirk for broken MSIs
+    - regulator: core: fix debugfs creation regression
+    - spi: microchip-core-qspi: fix setting spi bus clock rate
+    - ksmbd: off ipv6only for both ipv4/ipv6 binding
+    - ksmbd: avoid to send duplicate lease break notifications
+    - ksmbd: do not grant v2 lease if parent lease key and epoch are not set
+    - tracefs: Reset permissions on remount if permissions are options
+    - tracefs: Still use mount point as default permissions for instances
+    - eventfs: Do not treat events directory different than other directories
+    - Bluetooth: qca: fix invalid device address check
+    - Bluetooth: qca: fix wcn3991 device address check
+    - Bluetooth: qca: add missing firmware sanity checks
+    - Bluetooth: qca: fix NVM configuration parsing
+    - Bluetooth: qca: generalise device address check
+    - Bluetooth: qca: fix info leak when fetching board id
+    - Bluetooth: qca: fix info leak when fetching fw build id
+    - Bluetooth: qca: fix firmware check error path
+    - keys: Fix overwrite of key expiration on instantiation
+    - Linux 6.8.10
+
+  * Noble update: v6.8.9 upstream stable release (LP: #2070337)
+    - cifs: Fix reacquisition of volume cookie on still-live connection
+    - smb: client: fix rename(2) regression against samba
+    - cifs: reinstate original behavior again for forceuid/forcegid
+    - HID: intel-ish-hid: ipc: Fix dev_err usage with uninitialized dev->devc
+    - HID: logitech-dj: allow mice to use all types of reports
+    - arm64: dts: rockchip: set PHY address of MT7531 switch to 0x1f
+    - arm64: dts: rockchip: enable internal pull-up on Q7_USB_ID for RK3399 Puma
+    - arm64: dts: rockchip: fix alphabetical ordering RK3399 puma
+    - arm64: dts: rockchip: enable internal pull-up on PCIE_WAKE# for RK3399 Puma
+    - arm64: dts: rockchip: Fix the i2c address of es8316 on Cool Pi CM5
+    - arm64: dts: rockchip: Remove unsupported node from the Pinebook Pro dts
+    - arm64: dts: mediatek: mt8183: Add power-domains properity to mfgcfg
+    - arm64: dts: mediatek: mt8192: Add missing gce-client-reg to mutex
+    - arm64: dts: mediatek: mt8195: Add missing gce-client-reg to vpp/vdosys
+    - arm64: dts: mediatek: mt8195: Add missing gce-client-reg to mutex
+    - arm64: dts: mediatek: mt8195: Add missing gce-client-reg to mutex1
+    - arm64: dts: mediatek: cherry: Describe CPU supplies
+    - arm64: dts: mediatek: mt8192-asurada: Update min voltage constraint for
+      MT6315
+    - arm64: dts: mediatek: mt8195-cherry: Update min voltage constraint for
+      MT6315
+    - arm64: dts: mediatek: mt8183-kukui: Use default min voltage for MT6358
+    - arm64: dts: mediatek: mt7622: fix clock controllers
+    - arm64: dts: mediatek: mt7622: fix IR nodename
+    - arm64: dts: mediatek: mt7622: fix ethernet controller "compatible"
+    - arm64: dts: mediatek: mt7622: drop "reset-names" from thermal block
+    - arm64: dts: mediatek: mt7986: reorder properties
+    - arm64: dts: mediatek: mt7986: drop invalid properties from ethsys
+    - arm64: dts: mediatek: mt7986: drop "#reset-cells" from Ethernet controller
+    - arm64: dts: mediatek: mt7986: reorder nodes
+    - arm64: dts: mediatek: mt7986: drop invalid thermal block clock
+    - arm64: dts: mediatek: mt7986: prefix BPI-R3 cooling maps with "map-"
+    - arm64: dts: mediatek: mt2712: fix validation errors
+    - arm64: dts: rockchip: mark system power controller and fix typo on
+      orangepi-5-plus
+    - arm64: dts: rockchip: regulator for sd needs to be always on for BPI-R2Pro
+    - block: fix module reference leakage from bdev_open_by_dev error path
+    - arm64: dts: qcom: Fix type of "wdog" IRQs for remoteprocs
+    - arm64: dts: qcom: x1e80100: Fix the compatible for cluster idle states
+    - arm64: dts: qcom: sc8180x: Fix ss_phy_irq for secondary USB controller
+    - gpio: tangier: Use correct type for the IRQ chip data
+    - ARC: [plat-hsdk]: Remove misplaced interrupt-cells property
+    - wifi: mac80211: clean up assignments to pointer cache.
+    - wifi: mac80211: split mesh fast tx cache into local/proxied/forwarded
+    - wifi: iwlwifi: mvm: remove old PASN station when adding a new one
+    - wifi: iwlwifi: mvm: return uid from iwl_mvm_build_scan_cmd
+    - drm/gma500: Remove lid code
+    - wifi: mac80211_hwsim: init peer measurement result
+    - wifi: mac80211: remove link before AP
+    - wifi: mac80211: fix unaligned le16 access
+    - net: libwx: fix alloc msix vectors failed
+    - vxlan: drop packets from invalid src-address
+    - net: bcmasp: fix memory leak when bringing down interface
+    - mlxsw: core: Unregister EMAD trap using FORWARD action
+    - mlxsw: core_env: Fix driver initialization with old firmware
+    - mlxsw: pci: Fix driver initialization with old firmware
+    - ARM: dts: microchip: at91-sama7g5ek: Replace regulator-suspend-voltage with
+      the valid property
+    - icmp: prevent possible NULL dereferences from icmp_build_probe()
+    - bridge/br_netlink.c: no need to return void function
+    - bnxt_en: refactor reset close code
+    - bnxt_en: Fix the PCI-AER routines
+    - bnxt_en: Fix error recovery for 5760X (P7) chips
+    - cxl/core: Fix potential payload size confusion in cxl_mem_get_poison()
+    - net: dsa: mv88e6xx: fix supported_interfaces setup in
+      mv88e6250_phylink_get_caps()
+    - NFC: trf7970a: disable all regulators on removal
+    - netfs: Fix writethrough-mode error handling
+    - ax25: Fix netdev refcount issue
+    - soc: mediatek: mtk-svs: Append "-thermal" to thermal zone names
+    - tools: ynl: don't ignore errors in NLMSG_DONE messages
+    - net: usb: ax88179_178a: stop lying about skb->truesize
+    - tcp: Fix Use-After-Free in tcp_ao_connect_init
+    - net: gtp: Fix Use-After-Free in gtp_dellink
+    - net: phy: mediatek-ge-soc: follow netdev LED trigger semantics
+    - gpio: tegra186: Fix tegra186_gpio_is_accessible() check
+    - drm/xe: Remove sysfs only once on action add failure
+    - drm/xe: call free_gsc_pkt only once on action add failure
+    - Bluetooth: hci_event: Use HCI error defines instead of magic values
+    - Bluetooth: hci_conn: Only do ACL connections sequentially
+    - Bluetooth: Remove pending ACL connection attempts
+    - Bluetooth: hci_conn: Always use sk_timeo as conn_timeout
+    - Bluetooth: hci_conn: Fix UAF Write in __hci_acl_create_connection_sync
+    - Bluetooth: hci_sync: Add helper functions to manipulate cmd_sync queue
+    - Bluetooth: hci_sync: Attempt to dequeue connection attempt
+    - Bluetooth: ISO: Reassemble PA data for bcast sink
+    - Bluetooth: hci_sync: Use advertised PHYs on hci_le_ext_create_conn_sync
+    - Bluetooth: btusb: Fix triggering coredump implementation for QCA
+    - Bluetooth: hci_event: Fix sending HCI_OP_READ_ENC_KEY_SIZE
+    - Bluetooth: MGMT: Fix failing to MGMT_OP_ADD_UUID/MGMT_OP_REMOVE_UUID
+    - Bluetooth: btusb: mediatek: Fix double free of skb in coredump
+    - Bluetooth: hci_sync: Using hci_cmd_sync_submit when removing Adv Monitor
+    - Bluetooth: qca: set power_ctrl_enabled on NULL returned by
+      gpiod_get_optional()
+    - ipvs: Fix checksumming on GSO of SCTP packets
+    - net: openvswitch: Fix Use-After-Free in ovs_ct_exit
+    - mlxsw: Use refcount_t for reference counting
+    - mlxsw: spectrum_acl_tcam: Fix race in region ID allocation
+    - mlxsw: spectrum_acl_tcam: Fix race during rehash delayed work
+    - mlxsw: spectrum_acl_tcam: Fix possible use-after-free during activity update
+    - mlxsw: spectrum_acl_tcam: Fix possible use-after-free during rehash
+    - mlxsw: spectrum_acl_tcam: Rate limit error message
+    - mlxsw: spectrum_acl_tcam: Fix memory leak during rehash
+    - mlxsw: spectrum_acl_tcam: Fix warning during rehash
+    - mlxsw: spectrum_acl_tcam: Fix incorrect list API usage
+    - mlxsw: spectrum_acl_tcam: Fix memory leak when canceling rehash work
+    - eth: bnxt: fix counting packets discarded due to OOM and netpoll
+    - ARM: dts: imx6ull-tarragon: fix USB over-current polarity
+    - netfilter: nf_tables: honor table dormant flag from netdev release event
+      path
+    - net: phy: dp83869: Fix MII mode failure
+    - net: ti: icssg-prueth: Fix signedness bug in prueth_init_rx_chns()
+    - i40e: Do not use WQ_MEM_RECLAIM flag for workqueue
+    - i40e: Report MFS in decimal base instead of hex
+    - iavf: Fix TC config comparison with existing adapter TC config
+    - ice: fix LAG and VF lock dependency in ice_reset_vf()
+    - net: ethernet: ti: am65-cpts: Fix PTPv1 message type on TX packets
+    - octeontx2-af: fix the double free in rvu_npc_freemem()
+    - dpll: check that pin is registered in __dpll_pin_unregister()
+    - dpll: fix dpll_pin_on_pin_register() for multiple parent pins
+    - tls: fix lockless read of strp->msg_ready in ->poll
+    - af_unix: Suppress false-positive lockdep splat for spin_lock() in
+      __unix_gc().
+    - netfs: Fix the pre-flush when appending to a file in writethrough mode
+    - drm/amd/display: Check DP Alt mode DPCS state via DMUB
+    - Revert "drm/amd/display: fix USB-C flag update after enc10 feature init"
+    - xhci: move event processing for one interrupter to a separate function
+    - usb: xhci: correct return value in case of STS_HCE
+    - KVM: x86/pmu: Zero out PMU metadata on AMD if PMU is disabled
+    - KVM: x86/pmu: Set enable bits for GP counters in PERF_GLOBAL_CTRL at "RESET"
+    - drm: add drm_gem_object_is_shared_for_memory_stats() helper
+    - drm/amdgpu: add shared fdinfo stats
+    - drm/amdgpu: fix visible VRAM handling during faults
+    - Revert "UBUNTU: SAUCE: selftests/seccomp: fix check of fds being assigned"
+    - selftests/seccomp: user_notification_addfd check nextfd is available
+    - selftests/seccomp: Change the syscall used in KILL_THREAD test
+    - selftests/seccomp: Handle EINVAL on unshare(CLONE_NEWPID)
+    - x86/CPU/AMD: Add models 0x10-0x1f to the Zen5 range
+    - x86/cpu: Fix check for RDPKRU in __show_regs()
+    - rust: phy: implement `Send` for `Registration`
+    - rust: kernel: require `Send` for `Module` implementations
+    - rust: don't select CONSTRUCTORS
+    - [Config] updateconfigs to drop CONSTRUCTORS for rust
+    - rust: init: remove impl Zeroable for Infallible
+    - rust: make mutually exclusive with CFI_CLANG
+    - kbuild: rust: remove unneeded `@rustc_cfg` to avoid ICE
+    - kbuild: rust: force `alloc` extern to allow "empty" Rust files
+    - rust: remove `params` from `module` macro example
+    - Bluetooth: Fix type of len in {l2cap,sco}_sock_getsockopt_old()
+    - Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x0bda:0x4853
+    - Bluetooth: qca: fix NULL-deref on non-serdev suspend
+    - Bluetooth: qca: fix NULL-deref on non-serdev setup
+    - mtd: rawnand: qcom: Fix broken OP_RESET_DEVICE command in
+      qcom_misc_cmd_type_exec()
+    - mm/hugetlb: fix missing hugetlb_lock for resv uncharge
+    - mmc: sdhci-msm: pervent access to suspended controller
+    - mmc: sdhci-of-dwcmshc: th1520: Increase tuning loop count to 128
+    - mm: create FOLIO_FLAG_FALSE and FOLIO_TYPE_OPS macros
+    - mm: support page_mapcount() on page_has_type() pages
+    - mm/hugetlb: fix DEBUG_LOCKS_WARN_ON(1) when dissolve_free_hugetlb_folio()
+    - smb: client: Fix struct_group() usage in __packed structs
+    - smb3: missing lock when picking channel
+    - smb3: fix lock ordering potential deadlock in cifs_sync_mid_result
+    - btrfs: fallback if compressed IO fails for ENOSPC
+    - btrfs: fix wrong block_start calculation for btrfs_drop_extent_map_range()
+    - btrfs: scrub: run relocation repair when/only needed
+    - btrfs: fix information leak in btrfs_ioctl_logical_to_ino()
+    - x86/tdx: Preserve shared bit on mprotect()
+    - cpu: Re-enable CPU mitigations by default for !X86 architectures
+    - [Config] updateconfigs for CPU_MITIGATIONS
+    - eeprom: at24: fix memory corruption race condition
+    - LoongArch: Fix callchain parse error with kernel tracepoint events
+    - LoongArch: Fix access error when read fault on a write-only VMA
+    - arm64: dts: qcom: sc8280xp: add missing PCIe minimum OPP
+    - arm64: dts: qcom: sm8450: Fix the msi-map entries
+    - arm64: dts: rockchip: enable internal pull-up for Q7_THRM# on RK3399 Puma
+    - dmaengine: Revert "dmaengine: pl330: issue_pending waits until WFP state"
+    - dmaengine: xilinx: xdma: Fix wrong offsets in the buffers addresses in dma
+      descriptor
+    - dmaengine: xilinx: xdma: Fix synchronization issue
+    - drm/amdgpu/sdma5.2: use legacy HDP flush for SDMA2/3
+    - drm/amdgpu: Assign correct bits for SDMA HDP flush
+    - drm/atomic-helper: fix parameter order in drm_format_conv_state_copy() call
+    - drm/amdgpu/pm: Remove gpu_od if it's an empty directory
+    - drm/amdgpu/umsch: don't execute umsch test when GPU is in reset/suspend
+    - drm/amdgpu: Fix leak when GPU memory allocation fails
+    - drm/amdkfd: Fix rescheduling of restore worker
+    - drm/amdkfd: Fix eviction fence handling
+    - irqchip/gic-v3-its: Prevent double free on error
+    - ACPI: CPPC: Use access_width over bit_width for system memory accesses
+    - ACPI: CPPC: Fix bit_offset shift in MASK_VAL() macro
+    - ACPI: CPPC: Fix access width used for PCC registers
+    - net/mlx5e: Advertise mlx5 ethernet driver updates sk_buff md_dst for MACsec
+    - ethernet: Add helper for assigning packet type when dest address does not
+      match device address
+    - net: b44: set pause params only when interface is up
+    - macsec: Enable devices to advertise whether they update sk_buff md_dst
+      during offloads
+    - macsec: Detect if Rx skb is macsec-related for offloading devices that
+      update md_dst
+    - stackdepot: respect __GFP_NOLOCKDEP allocation flag
+    - fbdev: fix incorrect address computation in deferred IO
+    - udp: preserve the connected status if only UDP cmsg
+    - mtd: limit OTP NVMEM cell parse to non-NAND devices
+    - mtd: diskonchip: work around ubsan link failure
+    - firmware: qcom: uefisecapp: Fix memory related IO errors and crashes
+    - phy: qcom: qmp-combo: Fix register base for QSERDES_DP_PHY_MODE
+    - phy: qcom: qmp-combo: Fix VCO div offset on v3
+    - mm: turn folio_test_hugetlb into a PageType
+    - mm: zswap: fix shrinker NULL crash with cgroup_disable=memory
+    - dmaengine: owl: fix register access functions
+    - dmaengine: tegra186: Fix residual calculation
+    - idma64: Don't try to serve interrupts when device is powered off
+    - soundwire: amd: fix for wake interrupt handling for clockstop mode
+    - phy: marvell: a3700-comphy: Fix hardcoded array size
+    - phy: freescale: imx8m-pcie: fix pcie link-up instability
+    - phy: rockchip-snps-pcie3: fix bifurcation on rk3588
+    - phy: rockchip-snps-pcie3: fix clearing PHP_GRF_PCIESEL_CON bits
+    - phy: rockchip: naneng-combphy: Fix mux on rk3588
+    - phy: qcom: m31: match requested regulator name with dt schema
+    - dmaengine: idxd: Convert spinlock to mutex to lock evl workqueue
+    - dmaengine: idxd: Fix oops during rmmod on single-CPU platforms
+    - riscv: Fix TASK_SIZE on 64-bit NOMMU
+    - riscv: Fix loading 64-bit NOMMU kernels past the start of RAM
+    - phy: ti: tusb1210: Resolve charger-det crash if charger psy is unregistered
+    - dt-bindings: eeprom: at24: Fix ST M24C64-D compatible schema
+    - sched/eevdf: Always update V if se->on_rq when reweighting
+    - sched/eevdf: Fix miscalculation in reweight_entity() when se is not curr
+    - riscv: hwprobe: fix invalid sign extension for RISCV_HWPROBE_EXT_ZVFHMIN
+    - RISC-V: selftests: cbo: Ensure asm operands match constraints, take 2
+    - phy: qcom: qmp-combo: fix VCO div offset on v5_5nm and v6
+    - bounds: Use the right number of bits for power-of-two CONFIG_NR_CPUS
+    - Bluetooth: hci_sync: Fix UAF in hci_acl_create_conn_sync
+    - Bluetooth: hci_sync: Fix UAF on create_le_conn_complete
+    - Bluetooth: hci_sync: Fix UAF on hci_abort_conn_sync
+    - Linux 6.8.9
+
+  * amdgpu hangs on DCN 3.5 at bootup: RIP:
+    0010:dcn35_clk_mgr_construct+0x183/0x2210 [amdgpu] (LP: #2066233)
+    - drm/amd/display: Atom Integrated System Info v2_2 for DCN35
+
+  * [MTL] ACPI: PM: s2idle: Backport Linux ACPI s2idle patches to fix
+    suspend/resume issue (LP: #2069231)
+    - ACPI: PM: s2idle: Enable Low-Power S0 Idle MSFT UUID for non-AMD systems
+    - ACPI: PM: s2idle: Evaluate all Low-Power S0 Idle _DSM functions
+
+  * Removing legacy virtio-pci devices causes kernel panic (LP: #2067862)
+    - virtio-pci: Check if is_avq is NULL
+
+  * Mute/mic LEDs no function on ProBook 445/465 G11 (LP: #2069664)
+    - ALSA: hda/realtek: fix mute/micmute LEDs don't work for ProBook 445/465 G11.
+
+  * Mute/mic LEDs no function on  ProBook 440/460 G11 (LP: #2067669)
+    - ALSA: hda/realtek: fix mute/micmute LEDs don't work for ProBook 440/460 G11.
+
+  * rtw89_8852ce - Lost WIFI connection after suspend  (LP: #2065128)
+    - wifi: rtw89: reset AFEDIG register in power off sequence
+    - wifi: rtw89: 8852c: refine power sequence to imporve power consumption
+
+  * CVE-2024-25742
+    - x86/sev: Harden #VC instruction emulation somewhat
+    - x86/sev: Check for MWAITX and MONITORX opcodes in the #VC handler
+
+  * Noble update: v6.8.9 upstream stable release (LP: #2070337) //
+    CVE-2024-35984
+    - i2c: smbus: fix NULL function pointer dereference
+
+  * Noble update: v6.8.9 upstream stable release (LP: #2070337) //
+    CVE-2024-35990
+    - dma: xilinx_dpdma: Fix locking
+
+  * Noble update: v6.8.9 upstream stable release (LP: #2070337) //
+    CVE-2024-35997
+    - HID: i2c-hid: remove I2C_HID_READ_PENDING flag to prevent lock-up
+
+  * CVE-2024-36016
+    - tty: n_gsm: fix possible out-of-bounds in gsm0_receive()
+
+  * CVE-2024-36008
+    - ipv4: check for NULL idev in ip_route_use_hint()
+
+  * CVE-2024-35992
+    - phy: marvell: a3700-comphy: Fix out of bounds read
+
+ -- Stefan Bader <stefan.bader@canonical.com>  Fri, 05 Jul 2024 10:31:38 +0200
+
+linux (6.8.0-38.38) noble; urgency=medium
+
+  * noble/linux: 6.8.0-38.38 -proposed tracker (LP: #2068318)
+
+  * race_sched in ubuntu_stress_smoke_test will cause kernel panic on 6.8 with
+    Azure Standard_A2_v2 instance (LP: #2068024)
+    - sched/eevdf: Prevent vlag from going out of bounds in reweight_eevdf()
+
+  * Noble: btrfs: re-introduce 'norecovery' mount option (LP: #2068591)
+    - btrfs: re-introduce 'norecovery' mount option
+
+  * Fix system hang while entering suspend with AMD Navi3x graphics
+    (LP: #2063417)
+    - drm/amdgpu/mes: fix use-after-free issue
+
+  * Noble update: v6.8.8 upstream stable release (LP: #2068087)
+    - io_uring: Fix io_cqring_wait() not restoring sigmask on get_timespec64()
+      failure
+    - drm/i915/cdclk: Fix voltage_level programming edge case
+    - Revert "vmgenid: emit uevent when VMGENID updates"
+    - SUNRPC: Fix rpcgss_context trace event acceptor field
+    - selftests/ftrace: Limit length in subsystem-enable tests
+    - random: handle creditable entropy from atomic process context
+    - scsi: core: Fix handling of SCMD_FAIL_IF_RECOVERING
+    - net: usb: ax88179_178a: avoid writing the mac address before first reading
+    - btrfs: do not wait for short bulk allocation
+    - btrfs: zoned: do not flag ZEROOUT on non-dirty extent buffer
+    - r8169: fix LED-related deadlock on module removal
+    - r8169: add missing conditional compiling for call to r8169_remove_leds
+    - scsi: ufs: qcom: Add missing interconnect bandwidth values for Gear 5
+    - netfilter: nf_tables: Fix potential data-race in __nft_expr_type_get()
+    - netfilter: nf_tables: Fix potential data-race in __nft_obj_type_get()
+    - netfilter: br_netfilter: skip conntrack input hook for promisc packets
+    - netfilter: nft_set_pipapo: constify lookup fn args where possible
+    - netfilter: nft_set_pipapo: walk over current view on netlink dump
+    - netfilter: flowtable: validate pppoe header
+    - netfilter: flowtable: incorrect pppoe tuple
+    - af_unix: Call manage_oob() for every skb in unix_stream_read_generic().
+    - af_unix: Don't peek OOB data without MSG_OOB.
+    - net: sparx5: flower: fix fragment flags handling
+    - net/mlx5: Lag, restore buckets number to default after hash LAG deactivation
+    - net/mlx5: Restore mistakenly dropped parts in register devlink flow
+    - net/mlx5e: Prevent deadlock while disabling aRFS
+    - net: change maximum number of UDP segments to 128
+    - octeontx2-pf: fix FLOW_DIS_IS_FRAGMENT implementation
+    - selftests/tcp_ao: Make RST tests less flaky
+    - selftests/tcp_ao: Zero-init tcp_ao_info_opt
+    - selftests/tcp_ao: Fix fscanf() call for format-security
+    - selftests/tcp_ao: Printing fixes to confirm with format-security
+    - net: stmmac: Apply half-duplex-less constraint for DW QoS Eth only
+    - net: stmmac: Fix max-speed being ignored on queue re-init
+    - net: stmmac: Fix IP-cores specific MAC capabilities
+    - ice: tc: check src_vsi in case of traffic from VF
+    - ice: tc: allow zero flags in parsing tc flower
+    - ice: Fix checking for unsupported keys on non-tunnel device
+    - tun: limit printing rate when illegal packet received by tun dev
+    - net: dsa: mt7530: fix mirroring frames received on local port
+    - net: dsa: mt7530: fix port mirroring for MT7988 SoC switch
+    - s390/ism: Properly fix receive message buffer allocation
+    - netfilter: nf_tables: missing iterator type in lookup walk
+    - netfilter: nf_tables: restore set elements when delete set fails
+    - gpiolib: swnode: Remove wrong header inclusion
+    - netfilter: nf_tables: fix memleak in map from abort path
+    - net/sched: Fix mirred deadlock on device recursion
+    - net: ethernet: mtk_eth_soc: fix WED + wifi reset
+    - ravb: Group descriptor types used in Rx ring
+    - net: ravb: Count packets instead of descriptors in R-Car RX path
+    - net: ravb: Allow RX loop to move past DMA mapping errors
+    - net: ethernet: ti: am65-cpsw-nuss: cleanup DMA Channels before using them
+    - NFSD: fix endianness issue in nfsd4_encode_fattr4
+    - RDMA/rxe: Fix the problem "mutex_destroy missing"
+    - RDMA/cm: Print the old state when cm_destroy_id gets timeout
+    - RDMA/mlx5: Fix port number for counter query in multi-port configuration
+    - perf annotate: Make sure to call symbol__annotate2() in TUI
+    - perf lock contention: Add a missing NULL check
+    - s390/qdio: handle deferred cc1
+    - s390/cio: fix race condition during online processing
+    - iommufd: Add missing IOMMUFD_DRIVER kconfig for the selftest
+    - iommufd: Add config needed for iommufd_fail_nth
+    - drm: nv04: Fix out of bounds access
+    - drm/v3d: Don't increment `enabled_ns` twice
+    - userfaultfd: change src_folio after ensuring it's unpinned in UFFDIO_MOVE
+    - thunderbolt: Introduce tb_port_reset()
+    - thunderbolt: Introduce tb_path_deactivate_hop()
+    - thunderbolt: Make tb_switch_reset() support Thunderbolt 2, 3 and USB4
+      routers
+    - thunderbolt: Reset topology created by the boot firmware
+    - drm/panel: visionox-rm69299: don't unregister DSI device
+    - drm/radeon: make -fstrict-flex-arrays=3 happy
+    - ALSA: hda/realtek: Fix volumn control of ThinkBook 16P Gen4
+    - thermal/debugfs: Add missing count increment to thermal_debug_tz_trip_up()
+    - platform/x86/amd/pmc: Extend Framework 13 quirk to more BIOSes
+    - interconnect: qcom: x1e80100: Remove inexistent ACV_PERF BCM
+    - interconnect: Don't access req_list while it's being manipulated
+    - clk: Remove prepare_lock hold assertion in __clk_release()
+    - clk: Initialize struct clk_core kref earlier
+    - clk: Get runtime PM before walking tree during disable_unused
+    - clk: Get runtime PM before walking tree for clk_summary
+    - clk: mediatek: Do a runtime PM get on controllers during probe
+    - clk: mediatek: mt7988-infracfg: fix clocks for 2nd PCIe port
+    - selftests/powerpc/papr-vpd: Fix missing variable initialization
+    - x86/bugs: Fix BHI retpoline check
+    - x86/cpufeatures: Fix dependencies for GFNI, VAES, and VPCLMULQDQ
+    - block: propagate partition scanning errors to the BLKRRPART ioctl
+    - net/mlx5: E-switch, store eswitch pointer before registering devlink_param
+    - ALSA: seq: ump: Fix conversion from MIDI2 to MIDI1 UMP messages
+    - ALSA: hda/tas2781: correct the register for pow calibrated data
+    - ALSA: hda/realtek: Add quirks for Huawei Matebook D14 NBLB-WAX9N
+    - ALSA: hda/realtek - Enable audio jacks of Haier Boyue G42 with ALC269VC
+    - usb: misc: onboard_usb_hub: Disable the USB hub clock on failure
+    - misc: rtsx: Fix rts5264 driver status incorrect when card removed
+    - thunderbolt: Avoid notify PM core about runtime PM resume
+    - thunderbolt: Fix wake configurations after device unplug
+    - thunderbolt: Do not create DisplayPort tunnels on adapters of the same
+      router
+    - comedi: vmk80xx: fix incomplete endpoint checking
+    - serial: mxs-auart: add spinlock around changing cts state
+    - serial/pmac_zilog: Remove flawed mitigation for rx irq flood
+    - serial: 8250_dw: Revert: Do not reclock if already at correct rate
+    - serial: stm32: Return IRQ_NONE in the ISR if no handling happend
+    - serial: stm32: Reset .throttled state in .startup()
+    - serial: core: Fix regression when runtime PM is not enabled
+    - serial: core: Clearing the circular buffer before NULLifying it
+    - serial: core: Fix missing shutdown and startup for serial base port
+    - USB: serial: option: add Fibocom FM135-GL variants
+    - USB: serial: option: add support for Fibocom FM650/FG650
+    - USB: serial: option: add Lonsung U8300/U9300 product
+    - USB: serial: option: support Quectel EM060K sub-models
+    - USB: serial: option: add Rolling RW101-GL and RW135-GL support
+    - USB: serial: option: add Telit FN920C04 rmnet compositions
+    - Revert "usb: cdc-wdm: close race between read and workqueue"
+    - usb: dwc2: host: Fix dereference issue in DDMA completion flow.
+    - usb: Disable USB3 LPM at shutdown
+    - usb: gadget: f_ncm: Fix UAF ncm object at re-bind after usb ep transport
+      error
+    - usb: typec: tcpm: Correct the PDO counting in pd_set
+    - mei: me: disable RPL-S on SPS and IGN firmwares
+    - speakup: Avoid crash on very long word
+    - fs: sysfs: Fix reference leak in sysfs_break_active_protection()
+    - sched: Add missing memory barrier in switch_mm_cid
+    - KVM: x86: Snapshot if a vCPU's vendor model is AMD vs. Intel compatible
+    - KVM: x86/pmu: Disable support for adaptive PEBS
+    - KVM: x86/pmu: Do not mask LVTPC when handling a PMI on AMD platforms
+    - KVM: x86/mmu: x86: Don't overflow lpage_info when checking attributes
+    - KVM: x86/mmu: Write-protect L2 SPTEs in TDP MMU when clearing dirty status
+    - arm64/head: Disable MMU at EL2 before clearing HCR_EL2.E2H
+    - arm64: hibernate: Fix level3 translation fault in swsusp_save()
+    - init/main.c: Fix potential static_command_line memory overflow
+    - mm/madvise: make MADV_POPULATE_(READ|WRITE) handle VM_FAULT_RETRY properly
+    - mm/userfaultfd: allow hugetlb change protection upon poison entry
+    - mm,swapops: update check in is_pfn_swap_entry for hwpoison entries
+    - mm/memory-failure: fix deadlock when hugetlb_optimize_vmemmap is enabled
+    - mm/shmem: inline shmem_is_huge() for disabled transparent hugepages
+    - fuse: fix leaked ENOSYS error on first statx call
+    - drm/amdkfd: Fix memory leak in create_process failure
+    - drm/amdgpu: remove invalid resource->start check v2
+    - drm/ttm: stop pooling cached NUMA pages v2
+    - drm/xe: Fix bo leak in intel_fb_bo_framebuffer_init
+    - drm/vmwgfx: Fix prime import/export
+    - drm/vmwgfx: Sort primary plane formats by order of preference
+    - drm/vmwgfx: Fix crtc's atomic check conditional
+    - nouveau: fix instmem race condition around ptr stores
+    - bootconfig: use memblock_free_late to free xbc memory to buddy
+    - Squashfs: check the inode number is not the invalid value of zero
+    - nilfs2: fix OOB in nilfs_set_de_type
+    - fork: defer linking file vma until vma is fully initialized
+    - net: dsa: mt7530: fix improper frames on all 25MHz and 40MHz XTAL MT7530
+    - net: dsa: mt7530: fix enabling EEE on MT7531 switch on all boards
+    - ksmbd: fix slab-out-of-bounds in smb2_allocate_rsp_buf
+    - ksmbd: validate request buffer size in smb2_allocate_rsp_buf()
+    - ksmbd: clear RENAME_NOREPLACE before calling vfs_rename
+    - ksmbd: common: use struct_group_attr instead of struct_group for
+      network_open_info
+    - thunderbolt: Reset only non-USB4 host routers in resume
+    - Linux 6.8.8
+
+  * Fix inaudible HDMI/DP audio on USB-C MST dock (LP: #2064689)
+    - drm/i915/audio: Fix audio time stamp programming for DP
+
+  * Add Cirrus Logic CS35L56 amplifier support (LP: #2062135)
+    - ALSA: hda: realtek: Re-work CS35L41 fixups to re-use for other amps
+    - ALSA: hda/realtek: Add quirks for HP G11 Laptops using CS35L56
+
+  * net:fib_rule_tests.sh in ubuntu_kselftests_net fails on Noble (LP: #2066332)
+    - Revert "UBUNTU: SAUCE: selftests: net: fix "from" match test in
+      fib_rule_tests.sh"
+
+  * mtk_t7xx WWAN module fails to probe with: Invalid device status 0x1
+    (LP: #2049358)
+    - Revert "UBUNTU: SAUCE: net: wwan: t7xx: PCIe reset rescan"
+    - Revert "UBUNTU: SAUCE: net: wwan: t7xx: Add AP CLDMA"
+    - net: wwan: t7xx: Add AP CLDMA
+    - wwan: core: Add WWAN fastboot port type
+    - net: wwan: t7xx: Add sysfs attribute for device state machine
+    - net: wwan: t7xx: Infrastructure for early port configuration
+    - net: wwan: t7xx: Add fastboot WWAN port
+
+  * Pull-request to address TPM bypass issue (LP: #2037688)
+    - [Config]: Configure TPM drivers as builtins for arm64 in annotations
+
+  * re-enable Ubuntu FAN in the Noble kernel (LP: #2064508)
+    - SAUCE: fan: add VXLAN implementation
+    - SAUCE: fan: Fix NULL pointer dereference
+    - SAUCE: fan: support vxlan strict length validation
+
+  * update for V3 kernel bits and improved multiple fan slice support
+    (LP: #1470091) // re-enable Ubuntu FAN in the Noble kernel (LP: #2064508)
+    - SAUCE: fan: tunnel multiple mapping mode (v3)
+
+  * TCP memory  leak, slow network (arm64) (LP: #2045560)
+    - net: make SK_MEMORY_PCPU_RESERV tunable
+    - net: fix sk_memory_allocated_{add|sub} vs softirqs
+
+  * panel flickering after the i915.psr2 is enabled (LP: #2046315)
+    - drm/i915/alpm: Add ALPM register definitions
+    - drm/i915/psr: Add alpm_parameters struct
+    - drm/i915/alpm: Calculate ALPM Entry check
+    - drm/i915/alpm: Alpm aux wake configuration for lnl
+    - drm/i915/display: Make intel_dp_aux_fw_sync_len available for PSR code
+    - drm/i915/psr: Improve fast and IO wake lines calculation
+    - drm/i915/psr: Calculate IO wake and fast wake lines for DISPLAY_VER < 12
+    - drm/i915/display: Increase number of fast wake precharge pulses
+
+  * I2C HID device sometimes fails to initialize causing touchpad to not work
+    (LP: #2061040)
+    - HID: i2c-hid: Revert to await reset ACK before reading report descriptor
+
+  * Fix the RTL8852CE BT FW Crash based on SER false alarm (LP: #2060904)
+    - wifi: rtw89: disable txptctrl IMR to avoid flase alarm
+    - wifi: rtw89: pci: correct TX resource checking for PCI DMA channel of
+      firmware command
+
+  * [X13s] Fingerprint reader is not working (LP: #2065376)
+    - SAUCE: arm64: dts: qcom: sc8280xp: Add USB DWC3 Multiport controller
+    - SAUCE: arm64: dts: qcom: sc8280xp-x13s: enable USB MP and fingerprint reader
+
+  * Fix random HuC/GuC initialization failure of Intel i915 driver
+    (LP: #2061049)
+    - drm/i915/huc: Allow for very slow HuC loading
+
+  * Add support of TAS2781 amp of audio (LP: #2064064)
+    - ALSA: hda/tas2781: Add new vendor_id and subsystem_id to support ThinkPad
+      ICE-1
+
+  * Noble update: v6.8.7 upstream stable release (LP: #2065912)
+    - smb3: fix Open files on server counter going negative
+    - ata: libata-core: Allow command duration limits detection for ACS-4 drives
+    - ata: libata-scsi: Fix ata_scsi_dev_rescan() error path
+    - drm/amdgpu/vpe: power on vpe when hw_init
+    - batman-adv: Avoid infinite loop trying to resize local TT
+    - ceph: redirty page before returning AOP_WRITEPAGE_ACTIVATE
+    - ceph: switch to use cap_delay_lock for the unlink delay list
+    - virtio_net: Do not send RSS key if it is not supported
+    - arm64: tlb: Fix TLBI RANGE operand
+    - ARM: dts: imx7s-warp: Pass OV2680 link-frequencies
+    - raid1: fix use-after-free for original bio in raid1_write_request()
+    - ring-buffer: Only update pages_touched when a new page is touched
+    - Bluetooth: Fix memory leak in hci_req_sync_complete()
+    - drm/amd/pm: fixes a random hang in S4 for SMU v13.0.4/11
+    - platform/chrome: cros_ec_uart: properly fix race condition
+    - ACPI: scan: Do not increase dep_unmet for already met dependencies
+    - PM: s2idle: Make sure CPUs will wakeup directly on resume
+    - media: cec: core: remove length check of Timer Status
+    - btrfs: tests: allocate dummy fs_info and root in test_find_delalloc()
+    - ARM: OMAP2+: fix bogus MMC GPIO labels on Nokia N8x0
+    - ARM: OMAP2+: fix N810 MMC gpiod table
+    - mmc: omap: fix broken slot switch lookup
+    - mmc: omap: fix deferred probe
+    - mmc: omap: restore original power up/down steps
+    - ARM: OMAP2+: fix USB regression on Nokia N8x0
+    - firmware: arm_ffa: Fix the partition ID check in ffa_notification_info_get()
+    - firmware: arm_scmi: Make raw debugfs entries non-seekable
+    - cxl/mem: Fix for the index of Clear Event Record Handle
+    - cxl/core/regs: Fix usage of map->reg_type in cxl_decode_regblock() before
+      assigned
+    - arm64: dts: freescale: imx8mp-venice-gw72xx-2x: fix USB vbus regulator
+    - arm64: dts: freescale: imx8mp-venice-gw73xx-2x: fix USB vbus regulator
+    - drm/msm: Add newlines to some debug prints
+    - drm/msm/dpu: don't allow overriding data from catalog
+    - drm/msm/dpu: make error messages at dpu_core_irq_register_callback() more
+      sensible
+    - dt-bindings: display/msm: sm8150-mdss: add DP node
+    - arm64: dts: imx8-ss-conn: fix usdhc wrong lpcg clock order
+    - cxl/core: Fix initialization of mbox_cmd.size_out in get event
+    - Revert "drm/qxl: simplify qxl_fence_wait"
+    - nouveau: fix function cast warning
+    - drm/msm/adreno: Set highest_bank_bit for A619
+    - scsi: hisi_sas: Modify the deadline for ata_wait_after_reset()
+    - scsi: qla2xxx: Fix off by one in qla_edif_app_getstats()
+    - net: openvswitch: fix unwanted error log on timeout policy probing
+    - u64_stats: fix u64_stats_init() for lockdep when used repeatedly in one file
+    - xsk: validate user input for XDP_{UMEM|COMPLETION}_FILL_RING
+    - octeontx2-pf: Fix transmit scheduler resource leak
+    - block: fix q->blkg_list corruption during disk rebind
+    - lib: checksum: hide unused expected_csum_ipv6_magic[]
+    - geneve: fix header validation in geneve[6]_xmit_skb
+    - s390/ism: fix receive message buffer allocation
+    - bnxt_en: Fix possible memory leak in bnxt_rdma_aux_device_init()
+    - bnxt_en: Fix error recovery for RoCE ulp client
+    - bnxt_en: Reset PTP tx_avail after possible firmware reset
+    - ACPI: bus: allow _UID matching for integer zero
+    - base/node / ACPI: Enumerate node access class for 'struct access_coordinate'
+    - ACPI: HMAT: Introduce 2 levels of generic port access class
+    - ACPI: HMAT / cxl: Add retrieval of generic port coordinates for both access
+      classes
+    - cxl: Split out combine_coordinates() for common shared usage
+    - cxl: Split out host bridge access coordinates
+    - cxl: Remove checking of iter in cxl_endpoint_get_perf_coordinates()
+    - cxl: Fix retrieving of access_coordinates in PCIe path
+    - net: ks8851: Inline ks8851_rx_skb()
+    - net: ks8851: Handle softirqs at the end of IRQ thread to fix hang
+    - af_unix: Clear stale u->oob_skb.
+    - octeontx2-af: Fix NIX SQ mode and BP config
+    - ipv6: fib: hide unused 'pn' variable
+    - ipv4/route: avoid unused-but-set-variable warning
+    - ipv6: fix race condition between ipv6_get_ifaddr and ipv6_del_addr
+    - pds_core: use pci_reset_function for health reset
+    - pds_core: Fix pdsc_check_pci_health function to use work thread
+    - Bluetooth: ISO: Align broadcast sync_timeout with connection timeout
+    - Bluetooth: ISO: Don't reject BT_ISO_QOS if parameters are unset
+    - Bluetooth: hci_sync: Use QoS to determine which PHY to scan
+    - Bluetooth: hci_sync: Fix using the same interval and window for Coded PHY
+    - Bluetooth: SCO: Fix not validating setsockopt user input
+    - Bluetooth: RFCOMM: Fix not validating setsockopt user input
+    - Bluetooth: L2CAP: Fix not validating setsockopt user input
+    - Bluetooth: ISO: Fix not validating setsockopt user input
+    - Bluetooth: hci_sock: Fix not validating setsockopt user input
+    - Bluetooth: l2cap: Don't double set the HCI_CONN_MGMT_CONNECTED bit
+    - netfilter: complete validation of user input
+    - net/mlx5: SF, Stop waiting for FW as teardown was called
+    - net/mlx5: Register devlink first under devlink lock
+    - net/mlx5: offset comp irq index in name by one
+    - net/mlx5: Properly link new fs rules into the tree
+    - net/mlx5: Correctly compare pkt reformat ids
+    - net/mlx5e: RSS, Block changing channels number when RXFH is configured
+    - net/mlx5e: Fix mlx5e_priv_init() cleanup flow
+    - net/mlx5e: HTB, Fix inconsistencies with QoS SQs number
+    - net/mlx5e: Do not produce metadata freelist entries in Tx port ts WQE xmit
+    - net: sparx5: fix wrong config being used when reconfiguring PCS
+    - Revert "s390/ism: fix receive message buffer allocation"
+    - net: dsa: mt7530: trap link-local frames regardless of ST Port State
+    - af_unix: Do not use atomic ops for unix_sk(sk)->inflight.
+    - af_unix: Fix garbage collector racing against connect()
+    - net: ena: Fix potential sign extension issue
+    - net: ena: Wrong missing IO completions check order
+    - net: ena: Fix incorrect descriptor free behavior
+    - net: ena: Set tx_info->xdpf value to NULL
+    - drm/xe/display: Fix double mutex initialization
+    - drm/xe/hwmon: Cast result to output precision on left shift of operand
+    - tracing: hide unused ftrace_event_id_fops
+    - iommu/vt-d: Fix wrong use of pasid config
+    - iommu/vt-d: Allocate local memory for page request queue
+    - iommu/vt-d: Fix WARN_ON in iommu probe path
+    - io_uring: refactor DEFER_TASKRUN multishot checks
+    - io_uring: disable io-wq execution of multishot NOWAIT requests
+    - btrfs: qgroup: correctly model root qgroup rsv in convert
+    - btrfs: qgroup: fix qgroup prealloc rsv leak in subvolume operations
+    - btrfs: record delayed inode root in transaction
+    - btrfs: qgroup: convert PREALLOC to PERTRANS after record_root_in_trans
+    - io_uring/net: restore msg_control on sendzc retry
+    - kprobes: Fix possible use-after-free issue on kprobe registration
+    - fs/proc: remove redundant comments from /proc/bootconfig
+    - fs/proc: Skip bootloader comment if no embedded kernel parameters
+    - scsi: sg: Avoid sg device teardown race
+    - scsi: sg: Avoid race in error handling & drop bogus warn
+    - accel/ivpu: Check return code of ipc->lock init
+    - accel/ivpu: Fix PCI D0 state entry in resume
+    - accel/ivpu: Put NPU back to D3hot after failed resume
+    - accel/ivpu: Return max freq for DRM_IVPU_PARAM_CORE_CLOCK_RATE
+    - accel/ivpu: Fix deadlock in context_xa
+    - drm/vmwgfx: Enable DMA mappings with SEV
+    - drm/i915/vrr: Disable VRR when using bigjoiner
+    - drm/amdkfd: Reset GPU on queue preemption failure
+    - drm/ast: Fix soft lockup
+    - drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr()
+    - drm/client: Fully protect modes[] with dev->mode_config.mutex
+    - drm/msm/dp: fix runtime PM leak on disconnect
+    - drm/msm/dp: fix runtime PM leak on connect failure
+    - drm/amdgpu/umsch: reinitialize write pointer in hw init
+    - arm64: dts: imx8qm-ss-dma: fix can lpcg indices
+    - arm64: dts: imx8-ss-dma: fix can lpcg indices
+    - arm64: dts: imx8-ss-dma: fix adc lpcg indices
+    - arm64: dts: imx8-ss-conn: fix usb lpcg indices
+    - arm64: dts: imx8-ss-dma: fix pwm lpcg indices
+    - arm64: dts: imx8-ss-lsio: fix pwm lpcg indices
+    - arm64: dts: imx8-ss-dma: fix spi lpcg indices
+    - vhost: Add smp_rmb() in vhost_vq_avail_empty()
+    - vhost: Add smp_rmb() in vhost_enable_notify()
+    - perf/x86: Fix out of range data
+    - x86/cpu: Actually turn off mitigations by default for
+      SPECULATION_MITIGATIONS=n
+    - selftests/timers/posix_timers: Reimplement check_timer_distribution()
+    - selftests: timers: Fix posix_timers ksft_print_msg() warning
+    - selftests: timers: Fix abs() warning in posix_timers test
+    - selftests: kselftest: Mark functions that unconditionally call exit() as
+      __noreturn
+    - x86/apic: Force native_apic_mem_read() to use the MOV instruction
+    - irqflags: Explicitly ignore lockdep_hrtimer_exit() argument
+    - selftests: kselftest: Fix build failure with NOLIBC
+    - kernfs: annotate different lockdep class for of->mutex of writable files
+    - x86/bugs: Fix return type of spectre_bhi_state()
+    - x86/bugs: Fix BHI documentation
+    - x86/bugs: Cache the value of MSR_IA32_ARCH_CAPABILITIES
+    - x86/bugs: Rename various 'ia32_cap' variables to 'x86_arch_cap_msr'
+    - x86/bugs: Fix BHI handling of RRSBA
+    - x86/bugs: Clarify that syscall hardening isn't a BHI mitigation
+    - x86/bugs: Remove CONFIG_BHI_MITIGATION_AUTO and spectre_bhi=auto
+    - [Config] updateconfigs to remove obsolete SPECTRE_BHI_AUTO
+    - x86/bugs: Replace CONFIG_SPECTRE_BHI_{ON,OFF} with
+      CONFIG_MITIGATION_SPECTRE_BHI
+    - [Config] updateconfigs to enable new MITIGATION_SPECTRE_BHI
+    - drm/i915/cdclk: Fix CDCLK programming order when pipes are active
+    - drm/i915/psr: Disable PSR when bigjoiner is used
+    - drm/i915: Disable port sync when bigjoiner is used
+    - drm/i915: Disable live M/N updates when using bigjoiner
+    - drm/amdgpu: Reset dGPU if suspend got aborted
+    - drm/amdgpu: always force full reset for SOC21
+    - drm/amdgpu: fix incorrect number of active RBs for gfx11
+    - drm/amdgpu: differentiate external rev id for gfx 11.5.0
+    - drm/amd/display: Program VSC SDP colorimetry for all DP sinks >= 1.4
+    - drm/amd/display: Set VSC SDP Colorimetry same way for MST and SST
+    - drm/amd/display: Do not recursively call manual trigger programming
+    - drm/amd/display: Return max resolution supported by DWB
+    - drm/amd/display: always reset ODM mode in context when adding first plane
+    - drm/amd/display: fix disable otg wa logic in DCN316
+    - Linux 6.8.7
+
+  * Noble update: v6.8.6 upstream stable release (LP: #2065899)
+    - amdkfd: use calloc instead of kzalloc to avoid integer overflow
+    - wifi: ath9k: fix LNA selection in ath_ant_try_scan()
+    - wifi: rtw89: fix null pointer access when abort scan
+    - bnx2x: Fix firmware version string character counts
+    - net: stmmac: dwmac-starfive: Add support for JH7100 SoC
+    - net: phy: phy_device: Prevent nullptr exceptions on ISR
+    - wifi: rtw89: pci: validate RX tag for RXQ and RPQ
+    - wifi: rtw89: pci: enlarge RX DMA buffer to consider size of RX descriptor
+    - VMCI: Fix memcpy() run-time warning in dg_dispatch_as_host()
+    - wifi: iwlwifi: pcie: Add the PCI device id for new hardware
+    - arm64: dts: qcom: qcm6490-idp: Add definition for three LEDs
+    - net: dsa: qca8k: put MDIO controller OF node if unavailable
+    - arm64: dts: qcom: qrb2210-rb1: disable cluster power domains
+    - printk: For @suppress_panic_printk check for other CPU in panic
+    - panic: Flush kernel log buffer at the end
+    - dump_stack: Do not get cpu_sync for panic CPU
+    - wifi: iwlwifi: pcie: Add new PCI device id and CNVI
+    - cpuidle: Avoid potential overflow in integer multiplication
+    - ARM: dts: rockchip: fix rk3288 hdmi ports node
+    - ARM: dts: rockchip: fix rk322x hdmi ports node
+    - arm64: dts: rockchip: fix rk3328 hdmi ports node
+    - arm64: dts: rockchip: fix rk3399 hdmi ports node
+    - net: add netdev_lockdep_set_classes() to virtual drivers
+    - arm64: dts: qcom: qcs6490-rb3gen2: Declare GCC clocks protected
+    - pmdomain: ti: Add a null pointer check to the omap_prm_domain_init
+    - pmdomain: imx8mp-blk-ctrl: imx8mp_blk: Add fdcc clock to hdmimix domain
+    - ACPI: resource: Add IRQ override quirk for ASUS ExpertBook B2502FBA
+    - ionic: set adminq irq affinity
+    - net: skbuff: add overflow debug check to pull/push helpers
+    - firmware: tegra: bpmp: Return directly after a failed kzalloc() in
+      get_filename()
+    - wifi: brcmfmac: Add DMI nvram filename quirk for ACEPC W5 Pro
+    - wifi: mt76: mt7915: add locking for accessing mapped registers
+    - wifi: mt76: mt7996: disable AMSDU for non-data frames
+    - wifi: mt76: mt7996: add locking for accessing mapped registers
+    - ACPI: x86: Move acpi_quirk_skip_serdev_enumeration() out of
+      CONFIG_X86_ANDROID_TABLETS
+    - ACPI: x86: Add DELL0501 handling to acpi_quirk_skip_serdev_enumeration()
+    - pstore/zone: Add a null pointer check to the psz_kmsg_read
+    - tools/power x86_energy_perf_policy: Fix file leak in get_pkg_num()
+    - net: pcs: xpcs: Return EINVAL in the internal methods
+    - dma-direct: Leak pages on dma_set_decrypted() failure
+    - wifi: ath11k: decrease MHI channel buffer length to 8KB
+    - iommu/arm-smmu-v3: Hold arm_smmu_asid_lock during all of attach_dev
+    - cpufreq: Don't unregister cpufreq cooling on CPU hotplug
+    - overflow: Allow non-type arg to type_max() and type_min()
+    - wifi: iwlwifi: Add missing MODULE_FIRMWARE() for *.pnvm
+    - wifi: cfg80211: check A-MSDU format more carefully
+    - btrfs: handle chunk tree lookup error in btrfs_relocate_sys_chunks()
+    - btrfs: export: handle invalid inode or root reference in btrfs_get_parent()
+    - btrfs: send: handle path ref underflow in header iterate_inode_ref()
+    - ice: use relative VSI index for VFs instead of PF VSI number
+    - net/smc: reduce rtnl pressure in smc_pnet_create_pnetids_list()
+    - netdev: let netlink core handle -EMSGSIZE errors
+    - Bluetooth: btintel: Fix null ptr deref in btintel_read_version
+    - Bluetooth: btmtk: Add MODULE_FIRMWARE() for MT7922
+    - Bluetooth: Add new quirk for broken read key length on ATS2851
+    - drm/vc4: don't check if plane->state->fb == state->fb
+    - drm/ci: uprev mesa version: fix kdl commit fetch
+    - drm/amdgpu: Skip do PCI error slot reset during RAS recovery
+    - Input: synaptics-rmi4 - fail probing if memory allocation for "phys" fails
+    - drm: panel-orientation-quirks: Add quirk for GPD Win Mini
+    - ASoC: SOF: amd: Optimize quirk for Valve Galileo
+    - drm/ttm: return ENOSPC from ttm_bo_mem_space v3
+    - scsi: ufs: qcom: Avoid re-init quirk when gears match
+    - drm/amd/display: increased min_dcfclk_mhz and min_fclk_mhz
+    - pinctrl: renesas: checker: Limit cfg reg enum checks to provided IDs
+    - sysv: don't call sb_bread() with pointers_lock held
+    - scsi: lpfc: Fix possible memory leak in lpfc_rcv_padisc()
+    - drm/amd/display: Disable idle reallow as part of command/gpint execution
+    - isofs: handle CDs with bad root inode but good Joliet root directory
+    - ASoC: Intel: sof_rt5682: dmi quirk cleanup for mtl boards
+    - ASoC: Intel: common: DMI remap for rebranded Intel NUC M15 (LAPRC710)
+      laptops
+    - rcu/nocb: Fix WARN_ON_ONCE() in the rcu_nocb_bypass_lock()
+    - rcu-tasks: Repair RCU Tasks Trace quiescence check
+    - Julia Lawall reported this null pointer dereference, this should fix it.
+    - media: sta2x11: fix irq handler cast
+    - ALSA: firewire-lib: handle quirk to calculate payload quadlets as data block
+      counter
+    - drm/panel: simple: Add BOE BP082WX1-100 8.2" panel
+    - x86/vdso: Fix rethunk patching for vdso-image-{32,64}.o
+    - ASoC: Intel: avs: Populate board selection with new I2S entries
+    - ext4: add a hint for block bitmap corrupt state in mb_groups
+    - ext4: forbid commit inconsistent quota data when errors=remount-ro
+    - drm/amd/display: Fix nanosec stat overflow
+    - accel/habanalabs: increase HL_MAX_STR to 64 bytes to avoid warnings
+    - i2c: designware: Fix RX FIFO depth define on Wangxun 10Gb NIC
+    - HID: input: avoid polling stylus battery on Chromebook Pompom
+    - drm/amd/amdgpu: Fix potential ioremap() memory leaks in amdgpu_device_init()
+    - drm: Check output polling initialized before disabling
+    - drm: Check polling initialized before enabling in
+      drm_helper_probe_single_connector_modes
+    - SUNRPC: increase size of rpc_wait_queue.qlen from unsigned short to unsigned
+      int
+    - PCI: Disable D3cold on Asus B1400 PCI-NVMe bridge
+    - Revert "ACPI: PM: Block ASUS B1400CEAE from suspend to idle by default"
+    - libperf evlist: Avoid out-of-bounds access
+    - crypto: iaa - Fix async_disable descriptor leak
+    - input/touchscreen: imagis: Correct the maximum touch area value
+    - drivers/perf: hisi: Enable HiSilicon Erratum 162700402 quirk for HIP09
+    - block: prevent division by zero in blk_rq_stat_sum()
+    - RDMA/cm: add timeout to cm_destroy_id wait
+    - Input: imagis - use FIELD_GET where applicable
+    - Input: allocate keycode for Display refresh rate toggle
+    - platform/x86: acer-wmi: Add support for Acer PH16-71
+    - platform/x86: acer-wmi: Add predator_v4 module parameter
+    - platform/x86: touchscreen_dmi: Add an extra entry for a variant of the Chuwi
+      Vi8 tablet
+    - perf/x86/amd/lbr: Discard erroneous branch entries
+    - ALSA: hda/realtek: Add quirk for Lenovo Yoga 9 14IMH9
+    - ktest: force $buildonly = 1 for 'make_warnings_file' test type
+    - Input: xpad - add support for Snakebyte GAMEPADs
+    - ring-buffer: use READ_ONCE() to read cpu_buffer->commit_page in concurrent
+      environment
+    - tools: iio: replace seekdir() in iio_generic_buffer
+    - bus: mhi: host: Add MHI_PM_SYS_ERR_FAIL state
+    - kernfs: RCU protect kernfs_nodes and avoid kernfs_idr_lock in
+      kernfs_find_and_get_node_by_id()
+    - usb: typec: ucsi: Add qcm6490-pmic-glink as needing PDOS quirk
+    - thunderbolt: Calculate DisplayPort tunnel bandwidth after DPRX capabilities
+      read
+    - usb: gadget: uvc: refactor the check for a valid buffer in the pump worker
+    - usb: gadget: uvc: mark incomplete frames with UVC_STREAM_ERR
+    - usb: typec: ucsi: Limit read size on v1.2
+    - serial: 8250_of: Drop quirk fot NPCM from 8250_port
+    - thunderbolt: Keep the domain powered when USB4 port is in redrive mode
+    - usb: typec: tcpci: add generic tcpci fallback compatible
+    - usb: sl811-hcd: only defined function checkdone if QUIRK2 is defined
+    - ASoC: amd: yc: Fix non-functional mic on ASUS M7600RE
+    - thermal/of: Assume polling-delay(-passive) 0 when absent
+    - ASoC: soc-core.c: Skip dummy codec when adding platforms
+    - x86/xen: attempt to inflate the memory balloon on PVH
+    - fbdev: viafb: fix typo in hw_bitblt_1 and hw_bitblt_2
+    - io_uring: clear opcode specific data for an early failure
+    - modpost: fix null pointer dereference
+    - drivers/nvme: Add quirks for device 126f:2262
+    - fbmon: prevent division by zero in fb_videomode_from_videomode()
+    - ALSA: hda/realtek: Add quirks for some Clevo laptops
+    - drm/amdgpu: Init zone device and drm client after mode-1 reset on reload
+    - gcc-plugins/stackleak: Avoid .head.text section
+    - media: mediatek: vcodec: Fix oops when HEVC init fails
+    - media: mediatek: vcodec: adding lock to protect decoder context list
+    - media: mediatek: vcodec: adding lock to protect encoder context list
+    - randomize_kstack: Improve entropy diffusion
+    - platform/x86/intel/hid: Don't wake on 5-button releases
+    - platform/x86: intel-vbtn: Update tablet mode switch at end of probe
+    - nouveau: fix devinit paths to only handle display on GSP.
+    - Bluetooth: btintel: Fixe build regression
+    - net: mpls: error out if inner headers are not set
+    - VMCI: Fix possible memcpy() run-time warning in
+      vmci_datagram_invoke_guest_handler()
+    - x86/vdso: Fix rethunk patching for vdso-image-x32.o too
+    - Revert "drm/amd/amdgpu: Fix potential ioremap() memory leaks in
+      amdgpu_device_init()"
+    - Linux 6.8.6
+
+  * Noble update: v6.8.5 upstream stable release (LP: #2065400)
+    - scripts/bpf_doc: Use silent mode when exec make cmd
+    - xsk: Don't assume metadata is always requested in TX completion
+    - s390/bpf: Fix bpf_plt pointer arithmetic
+    - bpf, arm64: fix bug in BPF_LDX_MEMSX
+    - dma-buf: Fix NULL pointer dereference in sanitycheck()
+    - arm64: bpf: fix 32bit unconditional bswap
+    - nfc: nci: Fix uninit-value in nci_dev_up and nci_ntf_packet
+    - nfsd: Fix error cleanup path in nfsd_rename()
+    - tools: ynl: fix setting presence bits in simple nests
+    - mlxbf_gige: stop PHY during open() error paths
+    - wifi: iwlwifi: mvm: pick the version of SESSION_PROTECTION_NOTIF
+    - wifi: iwlwifi: mvm: rfi: fix potential response leaks
+    - wifi: iwlwifi: mvm: include link ID when releasing frames
+    - ALSA: hda: cs35l56: Set the init_done flag before component_add()
+    - ice: Refactor FW data type and fix bitmap casting issue
+    - ice: fix memory corruption bug with suspend and rebuild
+    - ixgbe: avoid sleeping allocation in ixgbe_ipsec_vf_add_sa()
+    - igc: Remove stale comment about Tx timestamping
+    - drm/xe: Remove unused xe_bo->props struct
+    - drm/xe: Add exec_queue.sched_props.job_timeout_ms
+    - drm/xe/guc_submit: use jiffies for job timeout
+    - drm/xe/queue: fix engine_class bounds check
+    - drm/xe/device: fix XE_MAX_GT_PER_TILE check
+    - drm/xe/device: fix XE_MAX_TILES_PER_DEVICE check
+    - dpll: indent DPLL option type by a tab
+    - s390/qeth: handle deferred cc1
+    - net: hsr: hsr_slave: Fix the promiscuous mode in offload mode
+    - tcp: properly terminate timers for kernel sockets
+    - net: wwan: t7xx: Split 64bit accesses to fix alignment issues
+    - drm/rockchip: vop2: Remove AR30 and AB30 format support
+    - selftests: vxlan_mdb: Fix failures with old libnet
+    - gpiolib: Fix debug messaging in gpiod_find_and_request()
+    - ACPICA: debugger: check status of acpi_evaluate_object() in
+      acpi_db_walk_for_fields()
+    - net: hns3: fix index limit to support all queue stats
+    - net: hns3: fix kernel crash when devlink reload during pf initialization
+    - net: hns3: mark unexcuted loopback test result as UNEXECUTED
+    - tls: recv: process_rx_list shouldn't use an offset with kvec
+    - tls: adjust recv return with async crypto and failed copy to userspace
+    - tls: get psock ref after taking rxlock to avoid leak
+    - mlxbf_gige: call request_irq() after NAPI initialized
+    - drm/amd/display: Update P010 scaling cap
+    - drm/amd/display: Send DTBCLK disable message on first commit
+    - bpf: Protect against int overflow for stack access size
+    - cifs: Fix duplicate fscache cookie warnings
+    - netfilter: nf_tables: reject destroy command to remove basechain hooks
+    - netfilter: nf_tables: reject table flag and netdev basechain updates
+    - netfilter: nf_tables: skip netdev hook unregistration if table is dormant
+    - iommu: Validate the PASID in iommu_attach_device_pasid()
+    - net: bcmasp: Bring up unimac after PHY link up
+    - net: lan743x: Add set RFE read fifo threshold for PCI1x1x chips
+    - Octeontx2-af: fix pause frame configuration in GMP mode
+    - inet: inet_defrag: prevent sk release while still in use
+    - drm/i915: Stop doing double audio enable/disable on SDVO and g4x+ DP
+    - drm/i915/display: Disable AuxCCS framebuffers if built for Xe
+    - drm/i915/xelpg: Extend some workarounds/tuning to gfx version 12.74
+    - drm/i915/mtl: Update workaround 14018575942
+    - drm/i915: Do not print 'pxp init failed with 0' when it succeed
+    - dm integrity: fix out-of-range warning
+    - modpost: do not make find_tosym() return NULL
+    - kbuild: make -Woverride-init warnings more consistent
+    - mm/treewide: replace pud_large() with pud_leaf()
+    - Revert "x86/mm/ident_map: Use gbpages only where full GB page should be
+      mapped."
+    - gpio: cdev: sanitize the label before requesting the interrupt
+    - RISC-V: KVM: Fix APLIC setipnum_le/be write emulation
+    - RISC-V: KVM: Fix APLIC in_clrip[x] read emulation
+    - KVM: arm64: Fix host-programmed guest events in nVHE
+    - KVM: arm64: Fix out-of-IPA space translation fault handling
+    - selinux: avoid dereference of garbage after mount failure
+    - r8169: fix issue caused by buggy BIOS on certain boards with RTL8168d
+    - x86/cpufeatures: Add CPUID_LNX_5 to track recently added Linux-defined word
+    - x86/bpf: Fix IP after emitting call depth accounting
+    - Revert "Bluetooth: hci_qca: Set BDA quirk bit if fwnode exists in DT"
+    - arm64: dts: qcom: sc7180-trogdor: mark bluetooth address as broken
+    - Bluetooth: qca: fix device-address endianness
+    - Bluetooth: add quirk for broken address properties
+    - Bluetooth: hci_event: set the conn encrypted before conn establishes
+    - Bluetooth: Fix TOCTOU in HCI debugfs implementation
+    - netfilter: nf_tables: release batch on table validation from abort path
+    - netfilter: nf_tables: release mutex after nft_gc_seq_end from abort path
+    - selftests: mptcp: join: fix dev in check_endpoint
+    - net/rds: fix possible cp null dereference
+    - net: usb: ax88179_178a: avoid the interface always configured as random
+      address
+    - net: mana: Fix Rx DMA datasize and skb_over_panic
+    - vsock/virtio: fix packet delivery to tap device
+    - netfilter: nf_tables: reject new basechain after table flag update
+    - netfilter: nf_tables: flush pending destroy work before exit_net release
+    - netfilter: nf_tables: Fix potential data-race in __nft_flowtable_type_get()
+    - netfilter: nf_tables: discard table flag update with pending basechain
+      deletion
+    - netfilter: validate user input for expected length
+    - vboxsf: Avoid an spurious warning if load_nls_xxx() fails
+    - bpf, sockmap: Prevent lock inversion deadlock in map delete elem
+    - mptcp: prevent BPF accessing lowat from a subflow socket.
+    - x86/retpoline: Do the necessary fixup to the Zen3/4 srso return thunk for
+      !SRSO
+    - KVM: arm64: Use TLBI_TTL_UNKNOWN in __kvm_tlb_flush_vmid_range()
+    - KVM: arm64: Ensure target address is granule-aligned for range TLBI
+    - net/sched: act_skbmod: prevent kernel-infoleak
+    - net: dsa: sja1105: Fix parameters order in sja1110_pcs_mdio_write_c45()
+    - net/sched: fix lockdep splat in qdisc_tree_reduce_backlog()
+    - net: stmmac: fix rx queue priority assignment
+    - net: phy: micrel: lan8814: Fix when enabling/disabling 1-step timestamping
+    - net: txgbe: fix i2c dev name cannot match clkdev
+    - net: fec: Set mac_managed_pm during probe
+    - net: phy: micrel: Fix potential null pointer dereference
+    - net: dsa: mv88e6xxx: fix usable ports on 88e6020
+    - selftests: net: gro fwd: update vxlan GRO test expectations
+    - gro: fix ownership transfer
+    - idpf: fix kernel panic on unknown packet types
+    - ice: fix enabling RX VLAN filtering
+    - i40e: Fix VF MAC filter removal
+    - tcp: Fix bind() regression for v6-only wildcard and v4-mapped-v6 non-
+      wildcard addresses.
+    - erspan: make sure erspan_base_hdr is present in skb->head
+    - selftests: reuseaddr_conflict: add missing new line at the end of the output
+    - tcp: Fix bind() regression for v6-only wildcard and v4(-mapped-v6) non-
+      wildcard addresses.
+    - ax25: fix use-after-free bugs caused by ax25_ds_del_timer
+    - e1000e: Workaround for sporadic MDI error on Meteor Lake systems
+    - ipv6: Fix infinite recursion in fib6_dump_done().
+    - mlxbf_gige: stop interface during shutdown
+    - r8169: skip DASH fw status checks when DASH is disabled
+    - udp: do not accept non-tunnel GSO skbs landing in a tunnel
+    - udp: do not transition UDP GRO fraglist partial checksums to unnecessary
+    - udp: prevent local UDP tunnel packets from being GROed
+    - octeontx2-af: Fix issue with loading coalesced KPU profiles
+    - octeontx2-pf: check negative error code in otx2_open()
+    - octeontx2-af: Add array index check
+    - i40e: fix i40e_count_filters() to count only active/new filters
+    - i40e: fix vf may be used uninitialized in this function warning
+    - i40e: Enforce software interrupt during busy-poll exit
+    - drm/amd: Flush GFXOFF requests in prepare stage
+    - e1000e: Minor flow correction in e1000_shutdown function
+    - e1000e: move force SMBUS from enable ulp function to avoid PHY loss issue
+    - mean_and_variance: Drop always failing tests
+    - net: ravb: Let IP-specific receive function to interrogate descriptors
+    - net: ravb: Always process TX descriptor ring
+    - net: ravb: Always update error counters
+    - KVM: SVM: Use unsigned integers when dealing with ASIDs
+    - KVM: SVM: Add support for allowing zero SEV ASIDs
+    - selftests: mptcp: connect: fix shellcheck warnings
+    - selftests: mptcp: use += operator to append strings
+    - mptcp: don't account accept() of non-MPC client as fallback to TCP
+    - 9p: Fix read/write debug statements to report server reply
+    - ASoC: wm_adsp: Fix missing mutex_lock in wm_adsp_write_ctl()
+    - ASoC: cs42l43: Correct extraction of data pointer in suspend/resume
+    - riscv: mm: Fix prototype to avoid discarding const
+    - riscv: hwprobe: do not produce frtace relocation
+    - drivers/perf: riscv: Disable PERF_SAMPLE_BRANCH_* while not supported
+    - block: count BLK_OPEN_RESTRICT_WRITES openers
+    - RISC-V: Update AT_VECTOR_SIZE_ARCH for new AT_MINSIGSTKSZ
+    - ASoC: amd: acp: fix for acp pdm configuration check
+    - regmap: maple: Fix cache corruption in regcache_maple_drop()
+    - ALSA: hda: cs35l56: Add ACPI device match tables
+    - drm/panfrost: fix power transition timeout warnings
+    - nouveau/uvmm: fix addr/range calcs for remap operations
+    - drm/prime: Unbreak virtgpu dma-buf export
+    - ASoC: rt5682-sdw: fix locking sequence
+    - ASoC: rt711-sdca: fix locking sequence
+    - ASoC: rt711-sdw: fix locking sequence
+    - ASoC: rt712-sdca-sdw: fix locking sequence
+    - ASoC: rt722-sdca-sdw: fix locking sequence
+    - ASoC: ops: Fix wraparound for mask in snd_soc_get_volsw
+    - spi: s3c64xx: Extract FIFO depth calculation to a dedicated macro
+    - spi: s3c64xx: sort headers alphabetically
+    - spi: s3c64xx: explicitly include <linux/bits.h>
+    - spi: s3c64xx: remove else after return
+    - spi: s3c64xx: define a magic value
+    - spi: s3c64xx: allow full FIFO masks
+    - spi: s3c64xx: determine the fifo depth only once
+    - spi: s3c64xx: Use DMA mode from fifo size
+    - ASoC: amd: acp: fix for acp_init function error handling
+    - regmap: maple: Fix uninitialized symbol 'ret' warnings
+    - ata: sata_sx4: fix pdc20621_get_from_dimm() on 64-bit
+    - scsi: mylex: Fix sysfs buffer lengths
+    - scsi: sd: Unregister device if device_add_disk() failed in sd_probe()
+    - Revert "ALSA: emu10k1: fix synthesizer sample playback position and caching"
+    - drm/i915/dp: Fix DSC state HW readout for SST connectors
+    - cifs: Fix caching to try to do open O_WRONLY as rdwr on server
+    - spi: mchp-pci1xxx: Fix a possible null pointer dereference in
+      pci1xxx_spi_probe
+    - s390/pai: fix sampling event removal for PMU device driver
+    - thermal: gov_power_allocator: Allow binding without cooling devices
+    - thermal: gov_power_allocator: Allow binding without trip points
+    - drm/i915/gt: Limit the reserved VM space to only the platforms that need it
+    - ata: sata_mv: Fix PCI device ID table declaration compilation warning
+    - ASoC: SOF: amd: fix for false dsp interrupts
+    - SUNRPC: Fix a slow server-side memory leak with RPC-over-TCP
+    - riscv: use KERN_INFO in do_trap
+    - riscv: Fix warning by declaring arch_cpu_idle() as noinstr
+    - riscv: Disable preemption when using patch_map()
+    - nfsd: hold a lighter-weight client reference over CB_RECALL_ANY
+    - lib/stackdepot: move stack_record struct definition into the header
+    - stackdepot: rename pool_index to pool_index_plus_1
+    - x86/retpoline: Add NOENDBR annotation to the SRSO dummy return thunk
+    - Revert "drm/amd/display: Send DTBCLK disable message on first commit"
+    - gpio: cdev: check for NULL labels when sanitizing them for irqs
+    - gpio: cdev: fix missed label sanitizing in debounce_setup()
+    - ksmbd: don't send oplock break if rename fails
+    - ksmbd: validate payload size in ipc response
+    - ksmbd: do not set SMB2_GLOBAL_CAP_ENCRYPTION for SMB 3.1.1
+    - ALSA: hda: Add pplcllpl/u members to hdac_ext_stream
+    - ALSA: hda/realtek - Fix inactive headset mic jack
+    - ALSA: hda/realtek: Add sound quirks for Lenovo Legion slim 7 16ARHA7 models
+    - ALSA: hda/realtek: cs35l41: Support ASUS ROG G634JYR
+    - ALSA: hda/realtek: Update Panasonic CF-SZ6 quirk to support headset with
+      microphone
+    - io_uring/kbuf: get rid of lower BGID lists
+    - io_uring/kbuf: get rid of bl->is_ready
+    - io_uring/kbuf: protect io_buffer_list teardown with a reference
+    - io_uring/rw: don't allow multishot reads without NOWAIT support
+    - io_uring: use private workqueue for exit work
+    - io_uring/kbuf: hold io_buffer_list reference over mmap
+    - ASoC: SOF: Add dsp_max_burst_size_in_ms member to snd_sof_pcm_stream
+    - ASoC: SOF: ipc4-topology: Save the DMA maximum burst size for PCMs
+    - ASoC: SOF: Intel: hda-pcm: Use dsp_max_burst_size_in_ms to place constraint
+    - ASoC: SOF: Intel: hda: Implement get_stream_position (Linear Link Position)
+    - ASoC: SOF: Intel: mtl/lnl: Use the generic get_stream_position callback
+    - ASoC: SOF: Introduce a new callback pair to be used for PCM delay reporting
+    - ASoC: SOF: Intel: Set the dai/host get frame/byte counter callbacks
+    - ASoC: SOF: Intel: hda-common-ops: Do not set the get_stream_position
+      callback
+    - ASoC: SOF: ipc4-pcm: Use the snd_sof_pcm_get_dai_frame_counter() for
+      pcm_delay
+    - ASoC: SOF: Remove the get_stream_position callback
+    - ASoC: SOF: ipc4-pcm: Move struct sof_ipc4_timestamp_info definition locally
+    - ASoC: SOF: ipc4-pcm: Combine the SOF_IPC4_PIPE_PAUSED cases in pcm_trigger
+    - ASoC: SOF: ipc4-pcm: Invalidate the stream_start_offset in PAUSED state
+    - ASoC: SOF: sof-pcm: Add pointer callback to sof_ipc_pcm_ops
+    - ASoC: SOF: ipc4-pcm: Correct the delay calculation
+    - ASoC: SOF: Intel: hda: Compensate LLP in case it is not reset
+    - driver core: Introduce device_link_wait_removal()
+    - of: dynamic: Synchronize of_changeset_destroy() with the devlink removals
+    - of: module: prevent NULL pointer dereference in vsnprintf()
+    - x86/mm/pat: fix VM_PAT handling in COW mappings
+    - x86/mce: Make sure to grab mce_sysfs_mutex in set_bank()
+    - x86/coco: Require seeding RNG with RDRAND on CoCo systems
+    - perf/x86/intel/ds: Don't clear ->pebs_data_cfg for the last PEBS event
+    - riscv: Fix vector state restore in rt_sigreturn()
+    - arm64/ptrace: Use saved floating point state type to determine SVE layout
+    - mm/secretmem: fix GUP-fast succeeding on secretmem folios
+    - selftests/mm: include strings.h for ffsl
+    - s390/entry: align system call table on 8 bytes
+    - riscv: Fix spurious errors from __get/put_kernel_nofault
+    - riscv: process: Fix kernel gp leakage
+    - smb: client: fix UAF in smb2_reconnect_server()
+    - smb: client: guarantee refcounted children from parent session
+    - smb: client: refresh referral without acquiring refpath_lock
+    - smb: client: handle DFS tcons in cifs_construct_tcon()
+    - smb: client: serialise cifs_construct_tcon() with cifs_mount_mutex
+    - smb3: retrying on failed server close
+    - smb: client: fix potential UAF in cifs_debug_files_proc_show()
+    - smb: client: fix potential UAF in cifs_stats_proc_write()
+    - smb: client: fix potential UAF in cifs_stats_proc_show()
+    - smb: client: fix potential UAF in cifs_dump_full_key()
+    - smb: client: fix potential UAF in smb2_is_valid_oplock_break()
+    - smb: client: fix potential UAF in smb2_is_valid_lease_break()
+    - smb: client: fix potential UAF in is_valid_oplock_break()
+    - smb: client: fix potential UAF in smb2_is_network_name_deleted()
+    - smb: client: fix potential UAF in cifs_signal_cifsd_for_reconnect()
+    - drm/i915/mst: Limit MST+DSC to TGL+
+    - drm/i915/mst: Reject FEC+MST on ICL
+    - drm/i915/dp: Fix the computation for compressed_bpp for DISPLAY < 13
+    - drm/i915/gt: Disable HW load balancing for CCS
+    - drm/i915/gt: Do not generate the command streamer for all the CCS
+    - drm/i915/gt: Enable only one CCS for compute workload
+    - drm/xe: Use ring ops TLB invalidation for rebinds
+    - drm/xe: Rework rebinding
+    - Revert "x86/mpparse: Register APIC address only once"
+    - bpf: put uprobe link's path and task in release callback
+    - bpf: support deferring bpf_link dealloc to after RCU grace period
+    - efi/libstub: Add generic support for parsing mem_encrypt=
+    - x86/boot: Move mem_encrypt= parsing to the decompressor
+    - x86/sme: Move early SME kernel encryption handling into .head.text
+    - x86/sev: Move early startup code into .head.text section
+    - Linux 6.8.5
+
+  * CVE-2024-26926
+    - binder: check offset alignment in binder_get_object()
+
+  * CVE-2024-26922
+    - drm/amdgpu: validate the parameters of bo mapping operations more clearly
+
+  * CVE-2024-26924
+    - netfilter: nft_set_pipapo: do not free live element
+
+ -- Stefan Bader <stefan.bader@canonical.com>  Fri, 07 Jun 2024 14:51:17 +0200
+
+linux (6.8.0-35.35) noble; urgency=medium
+
+  * noble/linux: 6.8.0-35.35 -proposed tracker (LP: #2065886)
+
+  * CVE-2024-21823
+    - VFIO: Add the SPR_DSA and SPR_IAX devices to the denylist
+    - dmaengine: idxd: add a new security check to deal with a hardware erratum
+    - dmaengine: idxd: add a write() method for applications to submit work
+
+ -- Roxana Nicolescu <roxana.nicolescu@canonical.com>  Mon, 20 May 2024 16:26:15 +0200
+
+linux (6.8.0-34.34) noble; urgency=medium
+
+  * noble/linux: 6.8.0-34.34 -proposed tracker (LP: #2065167)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2024.04.29)
+
+ -- Roxana Nicolescu <roxana.nicolescu@canonical.com>  Wed, 08 May 2024 13:14:41 +0200
+
+linux (6.8.0-32.32) noble; urgency=medium
+
+  * noble/linux: 6.8.0-32.32 -proposed tracker (LP: #2064344)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] drop getabis data
+    - [Packaging] update variants
+    - [Packaging] update annotations scripts
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2024.04.29)
+
+  * Enable Nezha board (LP: #1975592)
+    - [Config] Enable CONFIG_REGULATOR_FIXED_VOLTAGE on riscv64
+
+  * Enable Nezha board (LP: #1975592) // Enable StarFive VisionFive 2 board
+    (LP: #2013232)
+    - [Config] Enable CONFIG_SERIAL_8250_DW on riscv64
+
+  * RISC-V kernel config is out of sync with other archs (LP: #1981437)
+    - [Config] Sync riscv64 config with other architectures
+
+  * obsolete out-of-tree ivsc dkms in favor of in-tree one (LP: #2061747)
+    - ACPI: scan: Defer enumeration of devices with a _DEP pointing to IVSC device
+    - Revert "mei: vsc: Call wake_up() in the threaded IRQ handler"
+    - mei: vsc: Unregister interrupt handler for system suspend
+    - media: ipu-bridge: Add ov01a10 in Dell XPS 9315
+    - SAUCE: media: ipu-bridge: Support more sensors
+
+  * Fix after-suspend-mediacard/sdhc-insert test failed (LP: #2042500)
+    - PCI/ASPM: Move pci_configure_ltr() to aspm.c
+    - PCI/ASPM: Always build aspm.c
+    - PCI/ASPM: Move pci_save_ltr_state() to aspm.c
+    - PCI/ASPM: Save L1 PM Substates Capability for suspend/resume
+    - PCI/ASPM: Call pci_save_ltr_state() from pci_save_pcie_state()
+    - PCI/ASPM: Disable L1 before configuring L1 Substates
+    - PCI/ASPM: Update save_state when configuration changes
+
+  * RTL8852BE fw security fail then lost WIFI function during suspend/resume
+    cycle (LP: #2063096)
+    - wifi: rtw89: download firmware with five times retry
+
+  * intel_rapl_common: Add support for ARL and LNL (LP: #2061953)
+    - powercap: intel_rapl: Add support for Lunar Lake-M paltform
+    - powercap: intel_rapl: Add support for Arrow Lake
+
+  * Kernel panic during checkbox stress_ng_test on Grace running noble 6.8
+    (arm64+largemem) kernel (LP: #2058557)
+    - aio: Fix null ptr deref in aio_complete() wakeup
+
+  * Avoid creating non-working backlight sysfs knob from ASUS board
+    (LP: #2060422)
+    - platform/x86: asus-wmi: Consider device is absent when the read is ~0
+
+  * Include cifs.ko in linux-modules package (LP: #2042546)
+    - [Packaging] Replace fs/cifs with fs/smb/client in inclusion list
+
+  * Add Real-time Linux Analysis tool (rtla) to linux-tools (LP: #2059080)
+    - SAUCE: rtla: fix deb build
+    - [Packaging] add Real-time Linux Analysis tool (rtla) to linux-tools
+    - [Packaging] update dependencies for rtla
+
+  * Noble update: v6.8.4 upstream stable release (LP: #2060533)
+    - Revert "workqueue: Shorten events_freezable_power_efficient name"
+    - Revert "workqueue: Don't call cpumask_test_cpu() with -1 CPU in
+      wq_update_node_max_active()"
+    - Revert "workqueue: Implement system-wide nr_active enforcement for unbound
+      workqueues"
+    - Revert "workqueue: Introduce struct wq_node_nr_active"
+    - Revert "workqueue: RCU protect wq->dfl_pwq and implement accessors for it"
+    - Revert "workqueue: Make wq_adjust_max_active() round-robin pwqs while
+      activating"
+    - Revert "workqueue: Move nr_active handling into helpers"
+    - Revert "workqueue: Replace pwq_activate_inactive_work() with
+      [__]pwq_activate_work()"
+    - Revert "workqueue: Factor out pwq_is_empty()"
+    - Revert "workqueue: Move pwq->max_active to wq->max_active"
+    - Revert "workqueue.c: Increase workqueue name length"
+    - Linux 6.8.4
+
+  * Noble update: v6.8.3 upstream stable release (LP: #2060531)
+    - drm/vmwgfx: Unmap the surface before resetting it on a plane state
+    - wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach
+    - wifi: brcmfmac: avoid invalid list operation when vendor attach fails
+    - media: staging: ipu3-imgu: Set fields before media_entity_pads_init()
+    - arm64: dts: qcom: sc7280: Add additional MSI interrupts
+    - remoteproc: virtio: Fix wdg cannot recovery remote processor
+    - clk: qcom: gcc-sdm845: Add soft dependency on rpmhpd
+    - smack: Set SMACK64TRANSMUTE only for dirs in smack_inode_setxattr()
+    - smack: Handle SMACK64TRANSMUTE in smack_inode_setsecurity()
+    - arm: dts: marvell: Fix maxium->maxim typo in brownstone dts
+    - drm/vmwgfx: Fix possible null pointer derefence with invalid contexts
+    - arm64: dts: qcom: sm8450-hdk: correct AMIC4 and AMIC5 microphones
+    - serial: max310x: fix NULL pointer dereference in I2C instantiation
+    - drm/vmwgfx: Fix the lifetime of the bo cursor memory
+    - pci_iounmap(): Fix MMIO mapping leak
+    - media: xc4000: Fix atomicity violation in xc4000_get_frequency
+    - media: mc: Add local pad to pipeline regardless of the link state
+    - media: mc: Fix flags handling when creating pad links
+    - media: nxp: imx8-isi: Check whether crossbar pad is non-NULL before access
+    - media: mc: Add num_links flag to media_pad
+    - media: mc: Rename pad variable to clarify intent
+    - media: mc: Expand MUST_CONNECT flag to always require an enabled link
+    - media: nxp: imx8-isi: Mark all crossbar sink pads as MUST_CONNECT
+    - md: use RCU lock to protect traversal in md_spares_need_change()
+    - KVM: Always flush async #PF workqueue when vCPU is being destroyed
+    - arm64: dts: qcom: sm8550-qrd: correct WCD9385 TX port mapping
+    - arm64: dts: qcom: sm8550-mtp: correct WCD9385 TX port mapping
+    - cpufreq: amd-pstate: Fix min_perf assignment in amd_pstate_adjust_perf()
+    - thermal/intel: Fix intel_tcc_get_temp() to support negative CPU temperature
+    - powercap: intel_rapl: Fix a NULL pointer dereference
+    - powercap: intel_rapl: Fix locking in TPMI RAPL
+    - powercap: intel_rapl_tpmi: Fix a register bug
+    - powercap: intel_rapl_tpmi: Fix System Domain probing
+    - powerpc/smp: Adjust nr_cpu_ids to cover all threads of a core
+    - powerpc/smp: Increase nr_cpu_ids to include the boot CPU
+    - sparc64: NMI watchdog: fix return value of __setup handler
+    - sparc: vDSO: fix return value of __setup handler
+    - selftests/mqueue: Set timeout to 180 seconds
+    - pinctrl: qcom: sm8650-lpass-lpi: correct Kconfig name
+    - ext4: correct best extent lstart adjustment logic
+    - drm/amdgpu/display: Address kdoc for 'is_psr_su' in 'fill_dc_dirty_rects'
+    - block: Clear zone limits for a non-zoned stacked queue
+    - kasan/test: avoid gcc warning for intentional overflow
+    - bounds: support non-power-of-two CONFIG_NR_CPUS
+    - fat: fix uninitialized field in nostale filehandles
+    - fuse: fix VM_MAYSHARE and direct_io_allow_mmap
+    - mfd: twl: Select MFD_CORE
+    - ubifs: Set page uptodate in the correct place
+    - ubi: Check for too small LEB size in VTBL code
+    - ubi: correct the calculation of fastmap size
+    - ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path
+    - mtd: rawnand: meson: fix scrambling mode value in command macro
+    - md/md-bitmap: fix incorrect usage for sb_index
+    - x86/nmi: Fix the inverse "in NMI handler" check
+    - parisc/unaligned: Rewrite 64-bit inline assembly of emulate_ldd()
+    - parisc: Avoid clobbering the C/B bits in the PSW with tophys and tovirt
+      macros
+    - parisc: Fix ip_fast_csum
+    - parisc: Fix csum_ipv6_magic on 32-bit systems
+    - parisc: Fix csum_ipv6_magic on 64-bit systems
+    - parisc: Strip upper 32 bit of sum in csum_ipv6_magic for 64-bit builds
+    - md/raid5: fix atomicity violation in raid5_cache_count
+    - iio: adc: rockchip_saradc: fix bitmask for channels on SARADCv2
+    - iio: adc: rockchip_saradc: use mask for write_enable bitfield
+    - docs: Restore "smart quotes" for quotes
+    - cpufreq: Limit resolving a frequency to policy min/max
+    - PM: suspend: Set mem_sleep_current during kernel command line setup
+    - vfio/pds: Always clear the save/restore FDs on reset
+    - clk: qcom: gcc-ipq5018: fix terminating of frequency table arrays
+    - clk: qcom: gcc-ipq6018: fix terminating of frequency table arrays
+    - clk: qcom: gcc-ipq8074: fix terminating of frequency table arrays
+    - clk: qcom: gcc-ipq9574: fix terminating of frequency table arrays
+    - clk: qcom: camcc-sc8280xp: fix terminating of frequency table arrays
+    - clk: qcom: mmcc-apq8084: fix terminating of frequency table arrays
+    - clk: qcom: mmcc-msm8974: fix terminating of frequency table arrays
+    - usb: xhci: Add error handling in xhci_map_urb_for_dma
+    - powerpc/fsl: Fix mfpmr build errors with newer binutils
+    - USB: serial: ftdi_sio: add support for GMC Z216C Adapter IR-USB
+    - USB: serial: add device ID for VeriFone adapter
+    - USB: serial: cp210x: add ID for MGP Instruments PDS100
+    - wifi: mac80211: track capability/opmode NSS separately
+    - USB: serial: option: add MeiG Smart SLM320 product
+    - KVM: x86/xen: inject vCPU upcall vector when local APIC is enabled
+    - USB: serial: cp210x: add pid/vid for TDK NC0110013M and MM0110113M
+    - PM: sleep: wakeirq: fix wake irq warning in system suspend
+    - mmc: tmio: avoid concurrent runs of mmc_request_done()
+    - fuse: replace remaining make_bad_inode() with fuse_make_bad()
+    - fuse: fix root lookup with nonzero generation
+    - fuse: don't unhash root
+    - usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros
+    - usb: dwc3-am62: fix module unload/reload behavior
+    - usb: dwc3-am62: Disable wakeup at remove
+    - serial: core: only stop transmit when HW fifo is empty
+    - serial: Lock console when calling into driver before registration
+    - btrfs: qgroup: always free reserved space for extent records
+    - btrfs: fix off-by-one chunk length calculation at contains_pending_extent()
+    - wifi: rtw88: Add missing VID/PIDs for 8811CU and 8821CU
+    - docs: Makefile: Add dependency to $(YNL_INDEX) for targets other than
+      htmldocs
+    - PCI/PM: Drain runtime-idle callbacks before driver removal
+    - PCI/DPC: Quirk PIO log size for Intel Raptor Lake Root Ports
+    - Revert "Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d""
+    - md: don't clear MD_RECOVERY_FROZEN for new dm-raid until resume
+    - md: export helpers to stop sync_thread
+    - md: export helper md_is_rdwr()
+    - md: add a new helper reshape_interrupted()
+    - dm-raid: really frozen sync_thread during suspend
+    - md/dm-raid: don't call md_reap_sync_thread() directly
+    - dm-raid: add a new helper prepare_suspend() in md_personality
+    - dm-raid456, md/raid456: fix a deadlock for dm-raid456 while io concurrent
+      with reshape
+    - dm-raid: fix lockdep waring in "pers->hot_add_disk"
+    - powerpc: xor_vmx: Add '-mhard-float' to CFLAGS
+    - mac802154: fix llsec key resources release in mac802154_llsec_key_del
+    - mm: swap: fix race between free_swap_and_cache() and swapoff()
+    - mmc: core: Fix switch on gp3 partition
+    - Bluetooth: btnxpuart: Fix btnxpuart_close
+    - leds: trigger: netdev: Fix kernel panic on interface rename trig notify
+    - drm/etnaviv: Restore some id values
+    - landlock: Warn once if a Landlock action is requested while disabled
+    - io_uring: fix mshot read defer taskrun cqe posting
+    - hwmon: (amc6821) add of_match table
+    - io_uring: fix io_queue_proc modifying req->flags
+    - ext4: fix corruption during on-line resize
+    - nvmem: meson-efuse: fix function pointer type mismatch
+    - slimbus: core: Remove usage of the deprecated ida_simple_xx() API
+    - phy: tegra: xusb: Add API to retrieve the port number of phy
+    - usb: gadget: tegra-xudc: Fix USB3 PHY retrieval logic
+    - speakup: Fix 8bit characters from direct synth
+    - debugfs: fix wait/cancellation handling during remove
+    - PCI/AER: Block runtime suspend when handling errors
+    - io_uring/net: correctly handle multishot recvmsg retry setup
+    - io_uring: fix mshot io-wq checks
+    - PCI: qcom: Disable ASPM L0s for sc8280xp, sa8540p and sa8295p
+    - sparc32: Fix parport build with sparc32
+    - nfs: fix UAF in direct writes
+    - NFS: Read unlock folio on nfs_page_create_from_folio() error
+    - kbuild: Move -Wenum-{compare-conditional,enum-conversion} into W=1
+    - PCI: qcom: Enable BDF to SID translation properly
+    - PCI: dwc: endpoint: Fix advertised resizable BAR size
+    - PCI: hv: Fix ring buffer size calculation
+    - cifs: prevent updating file size from server if we have a read/write lease
+    - cifs: allow changing password during remount
+    - thermal/drivers/mediatek: Fix control buffer enablement on MT7896
+    - vfio/pci: Disable auto-enable of exclusive INTx IRQ
+    - vfio/pci: Lock external INTx masking ops
+    - vfio/platform: Disable virqfds on cleanup
+    - vfio/platform: Create persistent IRQ handlers
+    - vfio/fsl-mc: Block calling interrupt handler without trigger
+    - tpm,tpm_tis: Avoid warning splat at shutdown
+    - ksmbd: replace generic_fillattr with vfs_getattr
+    - ksmbd: retrieve number of blocks using vfs_getattr in
+      set_file_allocation_info
+    - platform/x86/intel/tpmi: Change vsec offset to u64
+    - io_uring/rw: return IOU_ISSUE_SKIP_COMPLETE for multishot retry
+    - io_uring: clean rings on NO_MMAP alloc fail
+    - ring-buffer: Do not set shortest_full when full target is hit
+    - ring-buffer: Fix full_waiters_pending in poll
+    - ring-buffer: Use wait_event_interruptible() in ring_buffer_wait()
+    - tracing/ring-buffer: Fix wait_on_pipe() race
+    - dlm: fix user space lkb refcounting
+    - soc: fsl: qbman: Always disable interrupts when taking cgr_lock
+    - soc: fsl: qbman: Use raw spinlock for cgr_lock
+    - s390/zcrypt: fix reference counting on zcrypt card objects
+    - drm/probe-helper: warn about negative .get_modes()
+    - drm/panel: do not return negative error codes from drm_panel_get_modes()
+    - drm/exynos: do not return negative values from .get_modes()
+    - drm/imx/ipuv3: do not return negative values from .get_modes()
+    - drm/vc4: hdmi: do not return negative values from .get_modes()
+    - clocksource/drivers/timer-riscv: Clear timer interrupt on timer
+      initialization
+    - memtest: use {READ,WRITE}_ONCE in memory scanning
+    - Revert "block/mq-deadline: use correct way to throttling write requests"
+    - lsm: use 32-bit compatible data types in LSM syscalls
+    - lsm: handle the NULL buffer case in lsm_fill_user_ctx()
+    - f2fs: mark inode dirty for FI_ATOMIC_COMMITTED flag
+    - f2fs: truncate page cache before clearing flags when aborting atomic write
+    - nilfs2: fix failure to detect DAT corruption in btree and direct mappings
+    - nilfs2: prevent kernel bug at submit_bh_wbc()
+    - cifs: make sure server interfaces are requested only for SMB3+
+    - cifs: reduce warning log level for server not advertising interfaces
+    - cifs: open_cached_dir(): add FILE_READ_EA to desired access
+    - mtd: rawnand: Fix and simplify again the continuous read derivations
+    - mtd: rawnand: Add a helper for calculating a page index
+    - mtd: rawnand: Ensure all continuous terms are always in sync
+    - mtd: rawnand: Constrain even more when continuous reads are enabled
+    - cpufreq: dt: always allocate zeroed cpumask
+    - io_uring/futex: always remove futex entry for cancel all
+    - io_uring/waitid: always remove waitid entry for cancel all
+    - x86/CPU/AMD: Update the Zenbleed microcode revisions
+    - ksmbd: fix slab-out-of-bounds in smb_strndup_from_utf16()
+    - net: esp: fix bad handling of pages from page_pool
+    - NFSD: Fix nfsd_clid_class use of __string_len() macro
+    - drm/i915: Add missing ; to __assign_str() macros in tracepoint code
+    - net: hns3: tracing: fix hclgevf trace event strings
+    - cxl/trace: Properly initialize cxl_poison region name
+    - ksmbd: fix potencial out-of-bounds when buffer offset is invalid
+    - virtio: reenable config if freezing device failed
+    - LoongArch: Change __my_cpu_offset definition to avoid mis-optimization
+    - LoongArch: Define the __io_aw() hook as mmiowb()
+    - LoongArch/crypto: Clean up useless assignment operations
+    - wireguard: netlink: check for dangling peer via is_dead instead of empty
+      list
+    - wireguard: netlink: access device through ctx instead of peer
+    - wireguard: selftests: set RISCV_ISA_FALLBACK on riscv{32,64}
+    - ahci: asm1064: asm1166: don't limit reported ports
+    - drm/amd/display: Change default size for dummy plane in DML2
+    - drm/amdgpu: amdgpu_ttm_gart_bind set gtt bound flag
+    - drm/amdgpu/pm: Fix NULL pointer dereference when get power limit
+    - drm/amdgpu/pm: Check the validity of overdiver power limit
+    - drm/amd/display: Override min required DCFCLK in dml1_validate
+    - drm/amd/display: Allow dirty rects to be sent to dmub when abm is active
+    - drm/amd/display: Init DPPCLK from SMU on dcn32
+    - drm/amd/display: Update odm when ODM combine is changed on an otg master
+      pipe with no plane
+    - drm/amd/display: Fix idle check for shared firmware state
+    - drm/amd/display: Amend coasting vtotal for replay low hz
+    - drm/amd/display: Lock all enabled otg pipes even with no planes
+    - drm/amd/display: Implement wait_for_odm_update_pending_complete
+    - drm/amd/display: Return the correct HDCP error code
+    - drm/amd/display: Add a dc_state NULL check in dc_state_release
+    - drm/amd/display: Fix noise issue on HDMI AV mute
+    - dm snapshot: fix lockup in dm_exception_table_exit
+    - x86/pm: Work around false positive kmemleak report in msr_build_context()
+    - wifi: brcmfmac: add per-vendor feature detection callback
+    - wifi: brcmfmac: cfg80211: Use WSEC to set SAE password
+    - wifi: brcmfmac: Demote vendor-specific attach/detach messages to info
+    - drm/ttm: Make sure the mapped tt pages are decrypted when needed
+    - drm/amd/display: Unify optimize_required flags and VRR adjustments
+    - drm/amd/display: Add more checks for exiting idle in DC
+    - btrfs: add set_folio_extent_mapped() helper
+    - btrfs: replace sb::s_blocksize by fs_info::sectorsize
+    - btrfs: add helpers to get inode from page/folio pointers
+    - btrfs: add helpers to get fs_info from page/folio pointers
+    - btrfs: add helper to get fs_info from struct inode pointer
+    - btrfs: qgroup: validate btrfs_qgroup_inherit parameter
+    - vfio: Introduce interface to flush virqfd inject workqueue
+    - vfio/pci: Create persistent INTx handler
+    - drm/bridge: add ->edid_read hook and drm_bridge_edid_read()
+    - drm/bridge: lt8912b: use drm_bridge_edid_read()
+    - drm/bridge: lt8912b: clear the EDID property on failures
+    - drm/bridge: lt8912b: do not return negative values from .get_modes()
+    - drm/amd/display: Remove pixle rate limit for subvp
+    - drm/amd/display: Revert Remove pixle rate limit for subvp
+    - workqueue: Shorten events_freezable_power_efficient name
+    - drm/amd/display: Use freesync when `DRM_EDID_FEATURE_CONTINUOUS_FREQ` found
+    - netfilter: nf_tables: reject constant set with timeout
+    - Revert "crypto: pkcs7 - remove sha1 support"
+    - x86/efistub: Call mixed mode boot services on the firmware's stack
+    - ASoC: amd: yc: Revert "Fix non-functional mic on Lenovo 21J2"
+    - ASoC: amd: yc: Revert "add new YC platform variant (0x63) support"
+    - Fix memory leak in posix_clock_open()
+    - wifi: rtw88: 8821cu: Fix connection failure
+    - x86/Kconfig: Remove CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT
+    - x86/sev: Fix position dependent variable references in startup code
+    - clocksource/drivers/arm_global_timer: Fix maximum prescaler value
+    - ARM: 9352/1: iwmmxt: Remove support for PJ4/PJ4B cores
+    - ARM: 9359/1: flush: check if the folio is reserved for no-mapping addresses
+    - entry: Respect changes to system call number by trace_sys_enter()
+    - swiotlb: Fix double-allocation of slots due to broken alignment handling
+    - swiotlb: Honour dma_alloc_coherent() alignment in swiotlb_alloc()
+    - swiotlb: Fix alignment checks when both allocation and DMA masks are present
+    - iommu/dma: Force swiotlb_max_mapping_size on an untrusted device
+    - printk: Update @console_may_schedule in console_trylock_spinning()
+    - irqchip/renesas-rzg2l: Flush posted write in irq_eoi()
+    - irqchip/renesas-rzg2l: Rename rzg2l_tint_eoi()
+    - irqchip/renesas-rzg2l: Rename rzg2l_irq_eoi()
+    - irqchip/renesas-rzg2l: Prevent spurious interrupts when setting trigger type
+    - kprobes/x86: Use copy_from_kernel_nofault() to read from unsafe address
+    - efi/libstub: fix efi_random_alloc() to allocate memory at alloc_min or
+      higher address
+    - x86/mpparse: Register APIC address only once
+    - x86/fpu: Keep xfd_state in sync with MSR_IA32_XFD
+    - efi: fix panic in kdump kernel
+    - pwm: img: fix pwm clock lookup
+    - selftests/mm: Fix build with _FORTIFY_SOURCE
+    - btrfs: handle errors returned from unpin_extent_cache()
+    - btrfs: fix warning messages not printing interval at unpin_extent_range()
+    - btrfs: do not skip re-registration for the mounted device
+    - mfd: intel-lpss: Switch to generalized quirk table
+    - mfd: intel-lpss: Introduce QUIRK_CLOCK_DIVIDER_UNITY for XPS 9530
+    - drm/i915: Replace a memset() with zero initialization
+    - drm/i915: Try to preserve the current shared_dpll for fastset on type-c
+      ports
+    - drm/i915: Include the PLL name in the debug messages
+    - drm/i915: Suppress old PLL pipe_mask checks for MG/TC/TBT PLLs
+    - crypto: iaa - Fix nr_cpus < nr_iaa case
+    - drm/amd/display: Prevent crash when disable stream
+    - ALSA: hda/tas2781: remove digital gain kcontrol
+    - ALSA: hda/tas2781: add locks to kcontrols
+    - mm: zswap: fix writeback shinker GFP_NOIO/GFP_NOFS recursion
+    - init: open /initrd.image with O_LARGEFILE
+    - x86/efistub: Add missing boot_params for mixed mode compat entry
+    - efi/libstub: Cast away type warning in use of max()
+    - x86/efistub: Reinstate soft limit for initrd loading
+    - prctl: generalize PR_SET_MDWE support check to be per-arch
+    - ARM: prctl: reject PR_SET_MDWE on pre-ARMv6
+    - tmpfs: fix race on handling dquot rbtree
+    - btrfs: validate device maj:min during open
+    - btrfs: fix race in read_extent_buffer_pages()
+    - btrfs: zoned: don't skip block groups with 100% zone unusable
+    - btrfs: zoned: use zone aware sb location for scrub
+    - btrfs: zoned: fix use-after-free in do_zone_finish()
+    - wifi: mac80211: check/clear fast rx for non-4addr sta VLAN changes
+    - wifi: cfg80211: add a flag to disable wireless extensions
+    - wifi: iwlwifi: mvm: disable MLO for the time being
+    - wifi: iwlwifi: fw: don't always use FW dump trig
+    - wifi: iwlwifi: mvm: handle debugfs names more carefully
+    - Revert "drm/amd/display: Fix sending VSC (+ colorimetry) packets for DP/eDP
+      displays without PSR"
+    - fbdev: Select I/O-memory framebuffer ops for SBus
+    - exec: Fix NOMMU linux_binprm::exec in transfer_args_to_stack()
+    - hexagon: vmlinux.lds.S: handle attributes section
+    - mm: cachestat: fix two shmem bugs
+    - selftests/mm: sigbus-wp test requires UFFD_FEATURE_WP_HUGETLBFS_SHMEM
+    - selftests/mm: fix ARM related issue with fork after pthread_create
+    - mmc: sdhci-omap: re-tuning is needed after a pm transition to support emmc
+      HS200 mode
+    - mmc: core: Initialize mmc_blk_ioc_data
+    - mmc: core: Avoid negative index with array access
+    - sdhci-of-dwcmshc: disable PM runtime in dwcmshc_remove()
+    - block: Do not force full zone append completion in req_bio_endio()
+    - thermal: devfreq_cooling: Fix perf state when calculate dfc res_util
+    - Revert "thermal: core: Don't update trip points inside the hysteresis range"
+    - nouveau/dmem: handle kcalloc() allocation failure
+    - net: ll_temac: platform_get_resource replaced by wrong function
+    - net: wan: framer: Add missing static inline qualifiers
+    - net: phy: qcom: at803x: fix kernel panic with at8031_probe
+    - drm/xe/query: fix gt_id bounds check
+    - drm/dp: Fix divide-by-zero regression on DP MST unplug with nouveau
+    - drm/vmwgfx: Create debugfs ttm_resource_manager entry only if needed
+    - drm/amdkfd: fix TLB flush after unmap for GFX9.4.2
+    - drm/amdgpu: fix deadlock while reading mqd from debugfs
+    - drm/amd/display: Remove MPC rate control logic from DCN30 and above
+    - drm/amd/display: Set DCN351 BB and IP the same as DCN35
+    - drm/i915/hwmon: Fix locking inversion in sysfs getter
+    - drm/i915/vma: Fix UAF on destroy against retire race
+    - drm/i915/bios: Tolerate devdata==NULL in
+      intel_bios_encoder_supports_dp_dual_mode()
+    - drm/i915/vrr: Generate VRR "safe window" for DSB
+    - drm/i915/dsi: Go back to the previous INIT_OTP/DISPLAY_ON order, mostly
+    - drm/i915/dsb: Fix DSB vblank waits when using VRR
+    - drm/i915: Do not match JSL in ehl_combo_pll_div_frac_wa_needed()
+    - drm/i915: Pre-populate the cursor physical dma address
+    - drm/i915/gt: Reset queue_priority_hint on parking
+    - drm/amd/display: Fix bounds check for dcn35 DcfClocks
+    - Bluetooth: hci_sync: Fix not checking error on hci_cmd_sync_cancel_sync
+    - mtd: spinand: Add support for 5-byte IDs
+    - Revert "usb: phy: generic: Get the vbus supply"
+    - usb: cdc-wdm: close race between read and workqueue
+    - usb: misc: ljca: Fix double free in error handling path
+    - USB: UAS: return ENODEV when submit urbs fail with device not attached
+    - vfio/pds: Make sure migration file isn't accessed after reset
+    - ring-buffer: Make wake once of ring_buffer_wait() more robust
+    - btrfs: fix extent map leak in unexpected scenario at unpin_extent_cache()
+    - ALSA: sh: aica: reorder cleanup operations to avoid UAF bugs
+    - scsi: ufs: qcom: Provide default cycles_in_1us value
+    - scsi: sd: Fix TCG OPAL unlock on system resume
+    - scsi: core: Fix unremoved procfs host directory regression
+    - staging: vc04_services: changen strncpy() to strscpy_pad()
+    - staging: vc04_services: fix information leak in create_component()
+    - genirq: Introduce IRQF_COND_ONESHOT and use it in pinctrl-amd
+    - usb: dwc3: Properly set system wakeup
+    - USB: core: Fix deadlock in usb_deauthorize_interface()
+    - USB: core: Add hub_get() and hub_put() routines
+    - USB: core: Fix deadlock in port "disable" sysfs attribute
+    - usb: dwc2: host: Fix remote wakeup from hibernation
+    - usb: dwc2: host: Fix hibernation flow
+    - usb: dwc2: host: Fix ISOC flow in DDMA mode
+    - usb: dwc2: gadget: Fix exiting from clock gating
+    - usb: dwc2: gadget: LPM flow fix
+    - usb: udc: remove warning when queue disabled ep
+    - usb: typec: ucsi: Fix race between typec_switch and role_switch
+    - usb: typec: tcpm: fix double-free issue in tcpm_port_unregister_pd()
+    - usb: typec: tcpm: Correct port source pdo array in pd_set callback
+    - usb: typec: tcpm: Update PD of Type-C port upon pd_set
+    - usb: typec: Return size of buffer if pd_set operation succeeds
+    - usb: typec: ucsi: Clear EVENT_PENDING under PPM lock
+    - usb: typec: ucsi: Ack unsupported commands
+    - usb: typec: ucsi_acpi: Refactor and fix DELL quirk
+    - usb: typec: ucsi: Clear UCSI_CCI_RESET_COMPLETE before reset
+    - scsi: qla2xxx: Prevent command send on chip reset
+    - scsi: qla2xxx: Fix N2N stuck connection
+    - scsi: qla2xxx: Split FCE|EFT trace control
+    - scsi: qla2xxx: Update manufacturer detail
+    - scsi: qla2xxx: NVME|FCP prefer flag not being honored
+    - scsi: qla2xxx: Fix command flush on cable pull
+    - scsi: qla2xxx: Fix double free of the ha->vp_map pointer
+    - scsi: qla2xxx: Fix double free of fcport
+    - scsi: qla2xxx: Change debug message during driver unload
+    - scsi: qla2xxx: Delay I/O Abort on PCI error
+    - x86/bugs: Fix the SRSO mitigation on Zen3/4
+    - crash: use macro to add crashk_res into iomem early for specific arch
+    - drm/amd/display: fix IPX enablement
+    - x86/bugs: Use fixed addressing for VERW operand
+    - Revert "x86/bugs: Use fixed addressing for VERW operand"
+    - usb: dwc3: pci: Drop duplicate ID
+    - scsi: lpfc: Correct size for cmdwqe/rspwqe for memset()
+    - scsi: lpfc: Correct size for wqe for memset()
+    - scsi: libsas: Add a helper sas_get_sas_addr_and_dev_type()
+    - scsi: libsas: Fix disk not being scanned in after being removed
+    - perf/x86/amd/core: Update and fix stalled-cycles-* events for Zen 2 and
+      later
+    - x86/sev: Skip ROM range scans and validation for SEV-SNP guests
+    - tools/resolve_btfids: fix build with musl libc
+    - drm/amdgpu: fix use-after-free bug
+    - drm/sched: fix null-ptr-deref in init entity
+    - Linux 6.8.3
+    - [Config] updateconfigs following v6.8.3 import
+
+  * Noble update: v6.8.3 upstream stable release (LP: #2060531) //
+    [Ubuntu-24.04] Hugepage memory is not getting released even after destroying
+    the guest! (LP: #2062556)
+    - block: Fix page refcounts for unaligned buffers in __bio_release_pages()
+
+  *  [SPR][EMR][GNR] TDX: efi: TD Measurement support for kernel cmdline/initrd
+    sections from EFI stub  (LP: #2060130)
+    - efi/libstub: Use TPM event typedefs from the TCG PC Client spec
+    - efi/tpm: Use symbolic GUID name from spec for final events table
+    - efi/libstub: Add Confidential Computing (CC) measurement typedefs
+    - efi/libstub: Measure into CC protocol if TCG2 protocol is absent
+    - efi/libstub: Add get_event_log() support for CC platforms
+    - x86/efistub: Remap kernel text read-only before dropping NX attribute
+
+  * Fix acpi_power_meter accessing IPMI region before it's ready (LP: #2059263)
+    - ACPI: IPMI: Add helper to wait for when SMI is selected
+    - hwmon: (acpi_power_meter) Ensure IPMI space handler is ready on Dell systems
+
+  * Drop fips-checks script from trees (LP: #2055083)
+    - [Packaging] Remove fips-checks script
+
+  * alsa/realtek: adjust max output valume for headphone on 2 LG machines
+    (LP: #2058573)
+    - ALSA: hda/realtek: fix the hp playback volume issue for LG machines
+
+  * Noble update: v6.8.2 upstream stable release (LP: #2060097)
+    - do_sys_name_to_handle(): use kzalloc() to fix kernel-infoleak
+    - workqueue.c: Increase workqueue name length
+    - workqueue: Move pwq->max_active to wq->max_active
+    - workqueue: Factor out pwq_is_empty()
+    - workqueue: Replace pwq_activate_inactive_work() with [__]pwq_activate_work()
+    - workqueue: Move nr_active handling into helpers
+    - workqueue: Make wq_adjust_max_active() round-robin pwqs while activating
+    - workqueue: RCU protect wq->dfl_pwq and implement accessors for it
+    - workqueue: Introduce struct wq_node_nr_active
+    - workqueue: Implement system-wide nr_active enforcement for unbound
+      workqueues
+    - workqueue: Don't call cpumask_test_cpu() with -1 CPU in
+      wq_update_node_max_active()
+    - iomap: clear the per-folio dirty bits on all writeback failures
+    - fs: Fix rw_hint validation
+    - io_uring: remove looping around handling traditional task_work
+    - io_uring: remove unconditional looping in local task_work handling
+    - s390/dasd: Use dev_*() for device log messages
+    - s390/dasd: fix double module refcount decrement
+    - fs/hfsplus: use better @opf description
+    - md: fix kmemleak of rdev->serial
+    - rcu/exp: Fix RCU expedited parallel grace period kworker allocation failure
+      recovery
+    - rcu/exp: Handle RCU expedited grace period kworker allocation failure
+    - fs/select: rework stack allocation hack for clang
+    - block: fix deadlock between bd_link_disk_holder and partition scan
+    - md: Don't clear MD_CLOSING when the raid is about to stop
+    - kunit: Setup DMA masks on the kunit device
+    - ovl: Always reject mounting over case-insensitive directories
+    - kunit: test: Log the correct filter string in executor_test
+    - lib/cmdline: Fix an invalid format specifier in an assertion msg
+    - lib: memcpy_kunit: Fix an invalid format specifier in an assertion msg
+    - time: test: Fix incorrect format specifier
+    - rtc: test: Fix invalid format specifier.
+    - net: test: Fix printf format specifier in skb_segment kunit test
+    - drm/xe/tests: Fix printf format specifiers in xe_migrate test
+    - drm: tests: Fix invalid printf format specifiers in KUnit tests
+    - md/raid1: factor out helpers to add rdev to conf
+    - md/raid1: record nonrot rdevs while adding/removing rdevs to conf
+    - md/raid1: fix choose next idle in read_balance()
+    - io_uring/net: unify how recvmsg and sendmsg copy in the msghdr
+    - io_uring/net: move receive multishot out of the generic msghdr path
+    - io_uring/net: fix overflow check in io_recvmsg_mshot_prep()
+    - nvme: host: fix double-free of struct nvme_id_ns in ns_update_nuse()
+    - aoe: fix the potential use-after-free problem in aoecmd_cfg_pkts
+    - x86/mm: Ensure input to pfn_to_kaddr() is treated as a 64-bit type
+    - x86/resctrl: Remove hard-coded memory bandwidth limit
+    - x86/resctrl: Read supported bandwidth sources from CPUID
+    - x86/resctrl: Implement new mba_MBps throttling heuristic
+    - x86/sme: Fix memory encryption setting if enabled by default and not
+      overridden
+    - timekeeping: Fix cross-timestamp interpolation on counter wrap
+    - timekeeping: Fix cross-timestamp interpolation corner case decision
+    - timekeeping: Fix cross-timestamp interpolation for non-x86
+    - x86/asm: Remove the __iomem annotation of movdir64b()'s dst argument
+    - sched/fair: Take the scheduling domain into account in select_idle_smt()
+    - sched/fair: Take the scheduling domain into account in select_idle_core()
+    - wifi: ath10k: fix NULL pointer dereference in
+      ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev()
+    - wifi: b43: Stop/wake correct queue in DMA Tx path when QoS is disabled
+    - wifi: b43: Stop/wake correct queue in PIO Tx path when QoS is disabled
+    - wifi: b43: Stop correct queue in DMA worker when QoS is disabled
+    - wifi: b43: Disable QoS for bcm4331
+    - wifi: wilc1000: fix declarations ordering
+    - wifi: wilc1000: fix RCU usage in connect path
+    - wifi: ath11k: add support to select 6 GHz regulatory type
+    - wifi: ath11k: store cur_regulatory_info for each radio
+    - wifi: ath11k: fix a possible dead lock caused by ab->base_lock
+    - wifi: rtl8xxxu: add cancel_work_sync() for c2hcmd_work
+    - wifi: wilc1000: do not realloc workqueue everytime an interface is added
+    - wifi: wilc1000: fix multi-vif management when deleting a vif
+    - wifi: mwifiex: debugfs: Drop unnecessary error check for
+      debugfs_create_dir()
+    - ARM: dts: renesas: r8a73a4: Fix external clocks and clock rate
+    - arm64: dts: qcom: x1e80100: drop qcom,drv-count
+    - arm64: dts: qcom: sc8180x: Hook up VDD_CX as GCC parent domain
+    - arm64: dts: qcom: sc8180x: Fix up big CPU idle state entry latency
+    - arm64: dts: qcom: sc8180x: Add missing CPU off state
+    - arm64: dts: qcom: sc8180x: Fix eDP PHY power-domains
+    - arm64: dts: qcom: sc8180x: Don't hold MDP core clock at FMAX
+    - arm64: dts: qcom: sc8180x: Require LOW_SVS vote for MMCX if DISPCC is on
+    - arm64: dts: qcom: sc8180x: Add missing CPU<->MDP_CFG path
+    - arm64: dts: qcom: sc8180x: Shrink aoss_qmp register space size
+    - cpufreq: brcmstb-avs-cpufreq: add check for cpufreq_cpu_get's return value
+    - cpufreq: mediatek-hw: Wait for CPU supplies before probing
+    - sock_diag: annotate data-races around sock_diag_handlers[family]
+    - inet_diag: annotate data-races around inet_diag_table[]
+    - bpftool: Silence build warning about calloc()
+    - selftests/bpf: Fix potential premature unload in bpf_testmod
+    - libbpf: Apply map_set_def_max_entries() for inner_maps on creation
+    - selftest/bpf: Add map_in_maps with BPF_MAP_TYPE_PERF_EVENT_ARRAY values
+    - bpftool: Fix wrong free call in do_show_link
+    - wifi: ath12k: Fix issues in channel list update
+    - selftests/bpf: Fix the flaky tc_redirect_dtime test
+    - selftests/bpf: Wait for the netstamp_needed_key static key to be turned on
+    - wifi: cfg80211: add RNR with reporting AP information
+    - wifi: mac80211: use deflink and fix typo in link ID check
+    - wifi: iwlwifi: change link id in time event to s8
+    - af_unix: Annotate data-race of gc_in_progress in wait_for_unix_gc().
+    - arm64: dts: qcom: sm8450: Add missing interconnects to serial
+    - soc: qcom: socinfo: rename PM2250 to PM4125
+    - arm64: dts: qcom: sc7280: Add static properties to cryptobam
+    - arm64: dts: qcom: qcm6490-fairphone-fp5: Add missing reserved-memory
+    - arm64: dts: qcom: sdm845-oneplus-common: improve DAI node naming
+    - arm64: dts: qcom: rename PM2250 to PM4125
+    - cpufreq: mediatek-hw: Don't error out if supply is not found
+    - libbpf: Fix faccessat() usage on Android
+    - libbpf: fix __arg_ctx type enforcement for perf_event programs
+    - pmdomain: qcom: rpmhpd: Drop SA8540P gfx.lvl
+    - arm64: dts: qcom: sa8540p: Drop gfx.lvl as power-domain for gpucc
+    - arm64: dts: renesas: r8a779g0: Restore sort order
+    - arm64: dts: renesas: r8a779g0: Add missing SCIF_CLK2
+    - selftests/bpf: Disable IPv6 for lwt_redirect test
+    - arm64: dts: imx8mm-kontron: Disable pullups for I2C signals on OSM-S i.MX8MM
+    - arm64: dts: imx8mm-kontron: Disable pullups for I2C signals on SL/BL i.MX8MM
+    - arm64: dts: imx8mm-kontron: Disable pullups for onboard UART signals on BL
+      OSM-S board
+    - arm64: dts: imx8mm-kontron: Disable pullups for onboard UART signals on BL
+      board
+    - arm64: dts: imx8mm-kontron: Disable pull resistors for SD card signals on BL
+      OSM-S board
+    - arm64: dts: imx8mm-kontron: Disable pull resistors for SD card signals on BL
+      board
+    - arm64: dts: imx8mm-kontron: Fix interrupt for RTC on OSM-S i.MX8MM module
+    - arm64: dts: imx8qm: Align edma3 power-domains resources indentation
+    - arm64: dts: imx8qm: Correct edma3 power-domains and interrupt numbers
+    - libbpf: Add missing LIBBPF_API annotation to libbpf_set_memlock_rlim API
+    - wifi: ath9k: delay all of ath9k_wmi_event_tasklet() until init is complete
+    - wifi: ath11k: change to move WMI_VDEV_PARAM_SET_HEMU_MODE before
+      WMI_PEER_ASSOC_CMDID
+    - wifi: ath12k: fix fetching MCBC flag for QCN9274
+    - wifi: iwlwifi: mvm: report beacon protection failures
+    - wifi: iwlwifi: dbg-tlv: ensure NUL termination
+    - wifi: iwlwifi: acpi: fix WPFC reading
+    - wifi: iwlwifi: mvm: initialize rates in FW earlier
+    - wifi: iwlwifi: fix EWRD table validity check
+    - wifi: iwlwifi: mvm: d3: fix IPN byte order
+    - wifi: iwlwifi: always have 'uats_enabled'
+    - wifi: iwlwifi: mvm: fix the TLC command after ADD_STA
+    - wifi: iwlwifi: read BIOS PNVM only for non-Intel SKU
+    - gpio: vf610: allow disabling the vf610 driver
+    - selftests/bpf: trace_helpers.c: do not use poisoned type
+    - bpf: make sure scalar args don't accept __arg_nonnull tag
+    - bpf: don't emit warnings intended for global subprogs for static subprogs
+    - arm64: dts: imx8mm-venice-gw71xx: fix USB OTG VBUS
+    - pwm: atmel-hlcdc: Fix clock imbalance related to suspend support
+    - net: blackhole_dev: fix build warning for ethh set but not used
+    - spi: consolidate setting message->spi
+    - spi: move split xfers for CS_WORD emulation
+    - arm64: dts: ti: k3-am62p5-sk: Enable CPSW MDIO node
+    - arm64: dts: ti: k3-j721s2: Fix power domain for VTM node
+    - arm64: dts: ti: k3-j784s4: Fix power domain for VTM node
+    - wifi: ath11k: initialize rx_mcs_80 and rx_mcs_160 before use
+    - wifi: libertas: fix some memleaks in lbs_allocate_cmd_buffer()
+    - arm64: dts: ti: k3-am69-sk: remove assigned-clock-parents for unused VP
+    - libbpf: fix return value for PERF_EVENT __arg_ctx type fix up check
+    - arm64: dts: ti: k3-am62p-mcu/wakeup: Disable MCU and wakeup R5FSS nodes
+    - arm64: dts: qcom: x1e80100-qcp: Fix supplies for LDOs 3E and 2J
+    - libbpf: Use OPTS_SET() macro in bpf_xdp_query()
+    - wifi: wfx: fix memory leak when starting AP
+    - arm64: dts: qcom: qcm2290: declare VLS CLAMP register for USB3 PHY
+    - arm64: dts: qcom: sm6115: declare VLS CLAMP register for USB3 PHY
+    - arm64: dts: qcom: sm8650: Fix UFS PHY clocks
+    - wifi: ath12k: fix incorrect logic of calculating vdev_stats_id
+    - printk: nbcon: Relocate 32bit seq macros
+    - printk: ringbuffer: Do not skip non-finalized records with prb_next_seq()
+    - printk: Wait for all reserved records with pr_flush()
+    - printk: Add this_cpu_in_panic()
+    - printk: ringbuffer: Cleanup reader terminology
+    - printk: ringbuffer: Skip non-finalized records in panic
+    - printk: Disable passing console lock owner completely during panic()
+    - pwm: sti: Fix capture for st,pwm-num-chan < st,capture-num-chan
+    - tools/resolve_btfids: Refactor set sorting with types from btf_ids.h
+    - tools/resolve_btfids: Fix cross-compilation to non-host endianness
+    - wifi: iwlwifi: support EHT for WH
+    - wifi: iwlwifi: properly check if link is active
+    - wifi: iwlwifi: mvm: fix erroneous queue index mask
+    - wifi: iwlwifi: mvm: don't set the MFP flag for the GTK
+    - wifi: iwlwifi: mvm: don't set replay counters to 0xff
+    - s390/pai: fix attr_event_free upper limit for pai device drivers
+    - s390/vdso: drop '-fPIC' from LDFLAGS
+    - arm64: dts: qcom: qcm6490-idp: Correct the voltage setting for vph_pwr
+    - arm64: dts: qcom: qcs6490-rb3gen2: Correct the voltage setting for vph_pwr
+    - selftests: forwarding: Add missing config entries
+    - selftests: forwarding: Add missing multicast routing config entries
+    - arm64: dts: qcom: sm6115: drop pipe clock selection
+    - ipv6: mcast: remove one synchronize_net() barrier in ipv6_mc_down()
+    - arm64: dts: mt8183: Move CrosEC base detection node to kukui-based DTs
+    - arm64: dts: mediatek: mt7986: fix reference to PWM in fan node
+    - arm64: dts: mediatek: mt7986: drop crypto's unneeded/invalid clock name
+    - arm64: dts: mediatek: mt7986: fix SPI bus width properties
+    - arm64: dts: mediatek: mt7986: fix SPI nodename
+    - arm64: dts: mediatek: mt7986: drop "#clock-cells" from PWM
+    - arm64: dts: mediatek: mt7986: add "#reset-cells" to infracfg
+    - arm64: dts: mediatek: mt8192-asurada: Remove CrosEC base detection node
+    - arm64: dts: mediatek: mt8192: fix vencoder clock name
+    - arm64: dts: mediatek: mt8186: fix VENC power domain clocks
+    - arm64: dts: mediatek: mt7622: add missing "device_type" to memory nodes
+    - can: m_can: Start/Cancel polling timer together with interrupts
+    - wifi: iwlwifi: mvm: Fix the listener MAC filter flags
+    - bpf: Mark bpf_spin_{lock,unlock}() helpers with notrace correctly
+    - arm64: dts: qcom: sdm845: Use the Low Power Island CX/MX for SLPI
+    - soc: qcom: llcc: Check return value on Broadcast_OR reg read
+    - ARM: dts: qcom: msm8974: correct qfprom node size
+    - arm64: dts: mediatek: mt8186: Add missing clocks to ssusb power domains
+    - arm64: dts: mediatek: mt8186: Add missing xhci clock to usb controllers
+    - arm64: dts: ti: am65x: Fix dtbs_install for Rocktech OLDI overlay
+    - cpufreq: qcom-hw: add CONFIG_COMMON_CLK dependency
+    - wifi: wilc1000: prevent use-after-free on vif when cleaning up all
+      interfaces
+    - pwm: dwc: use pm_sleep_ptr() macro
+    - arm64: dts: ti: k3-am69-sk: fix PMIC interrupt number
+    - arm64: dts: ti: k3-j721e-sk: fix PMIC interrupt number
+    - arm64: dts: ti: k3-am62-main: disable usb lpm
+    - ACPI: processor_idle: Fix memory leak in acpi_processor_power_exit()
+    - bus: tegra-aconnect: Update dependency to ARCH_TEGRA
+    - iommu/amd: Mark interrupt as managed
+    - wifi: brcmsmac: avoid function pointer casts
+    - arm64: dts: qcom: sdm845-db845c: correct PCIe wake-gpios
+    - arm64: dts: qcom: sm8150: correct PCIe wake-gpios
+    - powercap: dtpm_cpu: Fix error check against freq_qos_add_request()
+    - net: ena: Remove ena_select_queue
+    - arm64: dts: ti: k3-j7200-common-proc-board: Modify Pinmux for wkup_uart0 and
+      mcu_uart0
+    - arm64: dts: ti: k3-j7200-common-proc-board: Remove clock-frequency from
+      mcu_uart0
+    - arm64: dts: ti: k3-j721s2-common-proc-board: Remove Pinmux for CTS and RTS
+      in wkup_uart0
+    - arm64: dts: ti: k3-j784s4-evm: Remove Pinmux for CTS and RTS in wkup_uart0
+    - arm64: dts: ti: k3-am64-main: Fix ITAP/OTAP values for MMC
+    - arm64: dts: mt8195-cherry-tomato: change watchdog reset boot flow
+    - arm64: dts: ti: Add common1 register space for AM65x SoC
+    - arm64: dts: ti: Add common1 register space for AM62x SoC
+    - firmware: arm_scmi: Fix double free in SMC transport cleanup path
+    - wifi: cfg80211: set correct param change count in ML element
+    - arm64: dts: ti: k3-j721e: Fix mux-reg-masks in hbmc_mux
+    - arm64: dts: ti: k3-j784s4-main: Fix mux-reg-masks in serdes_ln_ctrl
+    - arm64: dts: ti: k3-am62p: Fix memory ranges for DMSS
+    - wifi: wilc1000: revert reset line logic flip
+    - ARM: dts: arm: realview: Fix development chip ROM compatible value
+    - memory: tegra: Correct DLA client names
+    - wifi: mt76: mt7996: fix fw loading timeout
+    - wifi: mt76: mt7925: fix connect to 80211b mode fail in 2Ghz band
+    - wifi: mt76: mt7925: fix SAP no beacon issue in 5Ghz and 6Ghz band
+    - wifi: mt76: mt7925: fix mcu query command fail
+    - wifi: mt76: mt7925: fix wmm queue mapping
+    - wifi: mt76: mt7925: fix fw download fail
+    - wifi: mt76: mt7925: fix WoW failed in encrypted mode
+    - wifi: mt76: mt7925: fix the wrong header translation config
+    - wifi: mt76: mt7925: add flow to avoid chip bt function fail
+    - wifi: mt76: mt7925: add support to set ifs time by mcu command
+    - wifi: mt76: mt7925: update PCIe DMA settings
+    - wifi: mt76: mt7996: check txs format before getting skb by pid
+    - wifi: mt76: mt7996: fix TWT issues
+    - wifi: mt76: mt7996: fix incorrect interpretation of EHT MCS caps
+    - wifi: mt76: mt7996: fix HE beamformer phy cap for station vif
+    - wifi: mt76: mt7996: fix efuse reading issue
+    - wifi: mt76: mt7996: fix HIF_TXD_V2_1 value
+    - wifi: mt76: mt792x: fix ethtool warning
+    - wifi: mt76: mt7921e: fix use-after-free in free_irq()
+    - wifi: mt76: mt7925e: fix use-after-free in free_irq()
+    - wifi: mt76: mt7921: fix incorrect type conversion for CLC command
+    - wifi: mt76: mt792x: fix a potential loading failure of the 6Ghz channel
+      config from ACPI
+    - wifi: mt76: fix the issue of missing txpwr settings from ch153 to ch177
+    - arm64: dts: renesas: rzg2l: Add missing interrupts to IRQC nodes
+    - arm64: dts: renesas: r9a08g045: Add missing interrupts to IRQC node
+    - arm64: dts: renesas: rzg3s-smarc-som: Guard Ethernet IRQ GPIO hogs
+    - arm64: dts: renesas: r8a779a0: Correct avb[01] reg sizes
+    - arm64: dts: renesas: r8a779g0: Correct avb[01] reg sizes
+    - net: mctp: copy skb ext data when fragmenting
+    - pstore: inode: Only d_invalidate() is needed
+    - arm64: dts: allwinner: h6: Add RX DMA channel for SPDIF
+    - ARM: dts: imx6dl-yapp4: Fix typo in the QCA switch register address
+    - ARM: dts: imx6dl-yapp4: Move the internal switch PHYs under the switch node
+    - arm64: dts: imx8mp: Set SPI NOR to max 40 MHz on Data Modul i.MX8M Plus eDM
+      SBC
+    - arm64: dts: imx8mp-evk: Fix hdmi@3d node
+    - regulator: userspace-consumer: add module device table
+    - gpiolib: Pass consumer device through to core in
+      devm_fwnode_gpiod_get_index()
+    - arm64: dts: marvell: reorder crypto interrupts on Armada SoCs
+    - ACPI: resource: Do IRQ override on Lunnen Ground laptops
+    - ACPI: resource: Add MAIBENBEN X577 to irq1_edge_low_force_override
+    - ACPI: scan: Fix device check notification handling
+    - arm64: dts: rockchip: add missing interrupt-names for rk356x vdpu
+    - arm64: dts: rockchip: fix reset-names for rk356x i2s2 controller
+    - arm64: dts: rockchip: drop rockchip,trcm-sync-tx-only from rk3588 i2s
+    - objtool: Fix UNWIND_HINT_{SAVE,RESTORE} across basic blocks
+    - x86, relocs: Ignore relocations in .notes section
+    - SUNRPC: fix a memleak in gss_import_v2_context
+    - SUNRPC: fix some memleaks in gssx_dec_option_array
+    - arm64: dts: qcom: sm8550: Fix SPMI channels size
+    - arm64: dts: qcom: sm8650: Fix SPMI channels size
+    - mmc: wmt-sdmmc: remove an incorrect release_mem_region() call in the .remove
+      function
+    - ACPI: CPPC: enable AMD CPPC V2 support for family 17h processors
+    - btrfs: fix race when detecting delalloc ranges during fiemap
+    - wifi: rtw88: 8821cu: Fix firmware upload fail
+    - wifi: rtw88: 8821c: Fix beacon loss and disconnect
+    - wifi: rtw88: 8821c: Fix false alarm count
+    - wifi: brcm80211: handle pmk_op allocation failure
+    - riscv: dts: starfive: jh7100: fix root clock names
+    - PCI: Make pci_dev_is_disconnected() helper public for other drivers
+    - iommu/vt-d: Don't issue ATS Invalidation request when device is disconnected
+    - iommu/vt-d: Use rbtree to track iommu probed devices
+    - iommu/vt-d: Improve ITE fault handling if target device isn't present
+    - iommu/vt-d: Use device rbtree in iopf reporting path
+    - iommu: Add static iommu_ops->release_domain
+    - iommu/vt-d: Fix NULL domain on device release
+    - igc: Fix missing time sync events
+    - igb: Fix missing time sync events
+    - ice: fix stats being updated by way too large values
+    - Bluetooth: Remove HCI_POWER_OFF_TIMEOUT
+    - Bluetooth: mgmt: Remove leftover queuing of power_off work
+    - Bluetooth: Remove superfluous call to hci_conn_check_pending()
+    - Bluetooth: Remove BT_HS
+    - Bluetooth: hci_event: Fix not indicating new connection for BIG Sync
+    - Bluetooth: hci_qca: don't use IS_ERR_OR_NULL() with gpiod_get_optional()
+    - Bluetooth: hci_core: Cancel request on command timeout
+    - Bluetooth: hci_sync: Fix overwriting request callback
+    - Bluetooth: hci_h5: Add ability to allocate memory for private data
+    - Bluetooth: btrtl: fix out of bounds memory access
+    - Bluetooth: hci_core: Fix possible buffer overflow
+    - Bluetooth: msft: Fix memory leak
+    - Bluetooth: btusb: Fix memory leak
+    - Bluetooth: af_bluetooth: Fix deadlock
+    - Bluetooth: fix use-after-free in accessing skb after sending it
+    - sr9800: Add check for usbnet_get_endpoints
+    - s390/cache: prevent rebuild of shared_cpu_list
+    - bpf: Fix DEVMAP_HASH overflow check on 32-bit arches
+    - bpf: Fix hashtab overflow check on 32-bit arches
+    - bpf: Fix stackmap overflow check on 32-bit arches
+    - net: dsa: microchip: make sure drive strength configuration is not lost by
+      soft reset
+    - dpll: spec: use proper enum for pin capabilities attribute
+    - iommu: Fix compilation without CONFIG_IOMMU_INTEL
+    - ipv6: fib6_rules: flush route cache when rule is changed
+    - net: ip_tunnel: make sure to pull inner header in ip_tunnel_rcv()
+    - octeontx2-af: Fix devlink params
+    - net: phy: fix phy_get_internal_delay accessing an empty array
+    - dpll: fix dpll_xa_ref_*_del() for multiple registrations
+    - net: hns3: fix wrong judgment condition issue
+    - net: hns3: fix kernel crash when 1588 is received on HIP08 devices
+    - net: hns3: fix port duplex configure error in IMP reset
+    - Bluetooth: Fix eir name length
+    - net: phy: dp83822: Fix RGMII TX delay configuration
+    - erofs: fix lockdep false positives on initializing erofs_pseudo_mnt
+    - OPP: debugfs: Fix warning around icc_get_name()
+    - tcp: fix incorrect parameter validation in the do_tcp_getsockopt() function
+    - ipmr: fix incorrect parameter validation in the ip_mroute_getsockopt()
+      function
+    - l2tp: fix incorrect parameter validation in the pppol2tp_getsockopt()
+      function
+    - udp: fix incorrect parameter validation in the udp_lib_getsockopt() function
+    - net: kcm: fix incorrect parameter validation in the kcm_getsockopt) function
+    - net/x25: fix incorrect parameter validation in the x25_getsockopt() function
+    - devlink: Fix length of eswitch inline-mode
+    - r8152: fix unknown device for choose_configuration
+    - nfp: flower: handle acti_netdevs allocation failure
+    - bpf: hardcode BPF_PROG_PACK_SIZE to 2MB * num_possible_nodes()
+    - dm raid: fix false positive for requeue needed during reshape
+    - dm: call the resume method on internal suspend
+    - fbdev/simplefb: change loglevel when the power domains cannot be parsed
+    - drm/tegra: dsi: Add missing check for of_find_device_by_node
+    - drm/tegra: dpaux: Fix PM disable depth imbalance in tegra_dpaux_probe
+    - drm/tegra: dsi: Fix some error handling paths in tegra_dsi_probe()
+    - drm/tegra: dsi: Fix missing pm_runtime_disable() in the error handling path
+      of tegra_dsi_probe()
+    - drm/tegra: hdmi: Fix some error handling paths in tegra_hdmi_probe()
+    - drm/tegra: rgb: Fix some error handling paths in tegra_dc_rgb_probe()
+    - drm/tegra: rgb: Fix missing clk_put() in the error handling paths of
+      tegra_dc_rgb_probe()
+    - drm/tegra: output: Fix missing i2c_put_adapter() in the error handling paths
+      of tegra_output_probe()
+    - drm/rockchip: inno_hdmi: Fix video timing
+    - drm: Don't treat 0 as -1 in drm_fixp2int_ceil
+    - drm/vkms: Avoid reading beyond LUT array
+    - drm/vmwgfx: fix a memleak in vmw_gmrid_man_get_node
+    - drm/rockchip: lvds: do not overwrite error code
+    - drm/rockchip: lvds: do not print scary message when probing defer
+    - drm/panel-edp: use put_sync in unprepare
+    - drm/lima: fix a memleak in lima_heap_alloc
+    - ASoC: amd: acp: Add missing error handling in sof-mach
+    - ASoC: SOF: amd: Fix memory leak in amd_sof_acp_probe()
+    - ASoC: SOF: core: Skip firmware test for custom loaders
+    - ASoC: SOF: amd: Compute file paths on firmware load
+    - soundwire: stream: add missing const to Documentation
+    - dmaengine: tegra210-adma: Update dependency to ARCH_TEGRA
+    - media: tc358743: register v4l2 async device only after successful setup
+    - media: cadence: csi2rx: use match fwnode for media link
+    - PCI/DPC: Print all TLP Prefixes, not just the first
+    - perf record: Fix possible incorrect free in record__switch_output()
+    - perf record: Check conflict between '--timestamp-filename' option and pipe
+      mode before recording
+    - HID: lenovo: Add middleclick_workaround sysfs knob for cptkbd
+    - drm/amd/display: Fix a potential buffer overflow in 'dp_dsc_clock_en_read()'
+    - perf pmu: Treat the msr pmu as software
+    - crypto: qat - avoid memcpy() overflow warning
+    - ALSA: hda: cs35l41: Set Channel Index correctly when system is missing _DSD
+    - drm/amd/display: Fix potential NULL pointer dereferences in
+      'dcn10_set_output_transfer_func()'
+    - ASoC: sh: rz-ssi: Fix error message print
+    - drm/vmwgfx: Fix vmw_du_get_cursor_mob fencing of newly-created MOBs
+    - clk: renesas: r8a779g0: Fix PCIe clock name
+    - pinctrl: renesas: rzg2l: Fix locking in rzg2l_dt_subnode_to_map()
+    - pinctrl: renesas: r8a779g0: Add missing SCIF_CLK2 pin group/function
+    - clk: samsung: exynos850: Propagate SPI IPCLK rate change
+    - media: v4l2: cci: print leading 0 on error
+    - perf evsel: Fix duplicate initialization of data->id in
+      evsel__parse_sample()
+    - perf bpf: Clean up the generated/copied vmlinux.h
+    - clk: meson: Add missing clocks to axg_clk_regmaps
+    - media: em28xx: annotate unchecked call to media_device_register()
+    - media: v4l2-tpg: fix some memleaks in tpg_alloc
+    - media: v4l2-mem2mem: fix a memleak in v4l2_m2m_register_entity
+    - media: dt-bindings: techwell,tw9900: Fix port schema ref
+    - mtd: spinand: esmt: Extend IDs to 5 bytes
+    - media: edia: dvbdev: fix a use-after-free
+    - pinctrl: mediatek: Drop bogus slew rate register range for MT8186
+    - pinctrl: mediatek: Drop bogus slew rate register range for MT8192
+    - drm/amdgpu: Fix potential out-of-bounds access in
+      'amdgpu_discovery_reg_base_init()'
+    - clk: qcom: reset: Commonize the de/assert functions
+    - clk: qcom: reset: Ensure write completion on reset de/assertion
+    - quota: Fix potential NULL pointer dereference
+    - quota: Fix rcu annotations of inode dquot pointers
+    - quota: Properly annotate i_dquot arrays with __rcu
+    - ASoC: Intel: ssp-common: Add stub for sof_ssp_get_codec_name
+    - PCI/P2PDMA: Fix a sleeping issue in a RCU read section
+    - PCI: switchtec: Fix an error handling path in switchtec_pci_probe()
+    - crypto: xilinx - call finalize with bh disabled
+    - drivers/ps3: select VIDEO to provide cmdline functions
+    - perf thread_map: Free strlist on normal path in thread_map__new_by_tid_str()
+    - perf srcline: Add missed addr2line closes
+    - dt-bindings: msm: qcom, mdss: Include ommited fam-b compatible
+    - drm/msm/dpu: fix the programming of INTF_CFG2_DATA_HCTL_EN
+    - drm/msm/dpu: Only enable DSC_MODE_MULTIPLEX if dsc_merge is enabled
+    - drm/radeon/ni: Fix wrong firmware size logging in ni_init_microcode()
+    - drm/amd/display: fix NULL checks for adev->dm.dc in amdgpu_dm_fini()
+    - clk: renesas: r8a779g0: Correct PFC/GPIO parent clocks
+    - clk: renesas: r8a779f0: Correct PFC/GPIO parent clock
+    - clk: renesas: r9a07g04[34]: Use SEL_SDHI1_STS status configuration for SD1
+      mux
+    - ALSA: seq: fix function cast warnings
+    - perf expr: Fix "has_event" function for metric style events
+    - perf stat: Avoid metric-only segv
+    - perf metric: Don't remove scale from counts
+    - ASoC: meson: aiu: fix function pointer type mismatch
+    - ASoC: meson: t9015: fix function pointer type mismatch
+    - powerpc: Force inlining of arch_vmap_p{u/m}d_supported()
+    - ASoC: SOF: Add some bounds checking to firmware data
+    - drm: ci: use clk_ignore_unused for apq8016
+    - NTB: fix possible name leak in ntb_register_device()
+    - media: cedrus: h265: Fix configuring bitstream size
+    - media: sun8i-di: Fix coefficient writes
+    - media: sun8i-di: Fix power on/off sequences
+    - media: sun8i-di: Fix chroma difference threshold
+    - staging: media: starfive: Set 16 bpp for capture_raw device
+    - media: imx: csc/scaler: fix v4l2_ctrl_handler memory leak
+    - media: go7007: add check of return value of go7007_read_addr()
+    - media: pvrusb2: remove redundant NULL check
+    - media: videobuf2: Add missing doc comment for waiting_in_dqbuf
+    - media: pvrusb2: fix pvr2_stream_callback casts
+    - clk: qcom: dispcc-sdm845: Adjust internal GDSC wait times
+    - drm/amd/display: Add 'replay' NULL check in 'edp_set_replay_allow_active()'
+    - drm/panel: boe-tv101wum-nl6: make use of prepare_prev_first
+    - drm/msm/dpu: finalise global state object
+    - drm/mediatek: dsi: Fix DSI RGB666 formats and definitions
+    - PCI: Mark 3ware-9650SE Root Port Extended Tags as broken
+    - drm/bridge: adv7511: fix crash on irq during probe
+    - pinctrl: renesas: Allow the compiler to optimize away sh_pfc_pm
+    - clk: hisilicon: hi3519: Release the correct number of gates in
+      hi3519_clk_unregister()
+    - clk: hisilicon: hi3559a: Fix an erroneous devm_kfree()
+    - clk: mediatek: mt8135: Fix an error handling path in
+      clk_mt8135_apmixed_probe()
+    - clk: mediatek: mt7622-apmixedsys: Fix an error handling path in
+      clk_mt8135_apmixed_probe()
+    - clk: mediatek: mt8183: Correct parent of CLK_INFRA_SSPM_32K_SELF
+    - clk: mediatek: mt7981-topckgen: flag SGM_REG_SEL as critical
+    - drm/tegra: put drm_gem_object ref on error in tegra_fb_create
+    - tty: mips_ejtag_fdc: Fix passing incompatible pointer type warning
+    - media: ivsc: csi: Swap SINK and SOURCE pads
+    - media: i2c: imx290: Fix IMX920 typo
+    - mfd: syscon: Call of_node_put() only when of_parse_phandle() takes a ref
+    - mfd: altera-sysmgr: Call of_node_put() only when of_parse_phandle() takes a
+      ref
+    - perf print-events: make is_event_supported() more robust
+    - crypto: arm/sha - fix function cast warnings
+    - crypto: ccp - Avoid discarding errors in psp_send_platform_access_msg()
+    - crypto: qat - remove unused macros in qat_comp_alg.c
+    - crypto: qat - removed unused macro in adf_cnv_dbgfs.c
+    - crypto: qat - avoid division by zero
+    - crypto: qat - remove double initialization of value
+    - crypto: qat - fix ring to service map for dcc in 4xxx
+    - crypto: qat - fix ring to service map for dcc in 420xx
+    - crypto: jitter - fix CRYPTO_JITTERENTROPY help text
+    - drm/tidss: Fix initial plane zpos values
+    - drm/tidss: Fix sync-lost issue with two displays
+    - clk: imx: imx8mp: Fix SAI_MCLK_SEL definition
+    - mtd: maps: physmap-core: fix flash size larger than 32-bit
+    - mtd: rawnand: lpc32xx_mlc: fix irq handler prototype
+    - mtd: rawnand: brcmnand: exec_op helper functions return type fixes
+    - ASoC: meson: axg-tdm-interface: fix mclk setup without mclk-fs
+    - ASoC: meson: axg-tdm-interface: add frame rate constraint
+    - drm/msm/a6xx: specify UBWC config for sc7180
+    - drm/msm/a7xx: Fix LLC typo
+    - dt-bindings: arm-smmu: fix SM8[45]50 GPU SMMU if condition
+    - perf pmu: Fix a potential memory leak in perf_pmu__lookup()
+    - HID: amd_sfh: Update HPD sensor structure elements
+    - HID: amd_sfh: Avoid disabling the interrupt
+    - drm/amdgpu: Fix missing break in ATOM_ARG_IMM Case of atom_get_src_int()
+    - media: pvrusb2: fix uaf in pvr2_context_set_notify
+    - media: dvb-frontends: avoid stack overflow warnings with clang
+    - media: go7007: fix a memleak in go7007_load_encoder
+    - media: ttpci: fix two memleaks in budget_av_attach
+    - media: mediatek: vcodec: avoid -Wcast-function-type-strict warning
+    - arm64: ftrace: Don't forbid CALL_OPS+CC_OPTIMIZE_FOR_SIZE with Clang
+    - drm/tests: helpers: Include missing drm_drv header
+    - drm/amd/pm: Fix esm reg mask use to get pcie speed
+    - gpio: nomadik: fix offset bug in nmk_pmx_set()
+    - drm/mediatek: Fix a null pointer crash in mtk_drm_crtc_finish_page_flip
+    - mfd: cs42l43: Fix wrong register defaults
+    - powerpc/32: fix ADB_CUDA kconfig warning
+    - powerpc/pseries: Fix potential memleak in papr_get_attr()
+    - powerpc/hv-gpci: Fix the H_GET_PERF_COUNTER_INFO hcall return value checks
+    - clk: qcom: gcc-ipq5018: fix 'enable_reg' offset of 'gcc_gmac0_sys_clk'
+    - clk: qcom: gcc-ipq5018: fix 'halt_reg' offset of 'gcc_pcie1_pipe_clk'
+    - clk: qcom: gcc-ipq5018: fix register offset for GCC_UBI0_AXI_ARES reset
+    - perf vendor events amd: Fix Zen 4 cache latency events
+    - drm/msm/dpu: allow certain formats for CDM for DP
+    - drm/msm/dpu: add division of drm_display_mode's hskew parameter
+    - media: usbtv: Remove useless locks in usbtv_video_free()
+    - drm/xe: Fix ref counting leak on page fault
+    - drm/xe: Replace 'grouped target' in Makefile with pattern rule
+    - lib/stackdepot: fix first entry having a 0-handle
+    - lib/stackdepot: off by one in depot_fetch_stack()
+    - modules: wait do_free_init correctly
+    - mfd: cs42l43: Fix wrong GPIO_FN_SEL and SPI_CLK_CONFIG1 defaults
+    - power: supply: mm8013: fix "not charging" detection
+    - powerpc/embedded6xx: Fix no previous prototype for avr_uart_send() etc.
+    - powerpc/4xx: Fix warp_gpio_leds build failure
+    - RISC-V: KVM: Forward SEED CSR access to user space
+    - leds: aw2013: Unlock mutex before destroying it
+    - leds: sgm3140: Add missing timer cleanup and flash gpio control
+    - backlight: hx8357: Fix potential NULL pointer dereference
+    - backlight: ktz8866: Correct the check for of_property_read_u32
+    - backlight: lm3630a: Initialize backlight_properties on init
+    - backlight: lm3630a: Don't set bl->props.brightness in get_brightness
+    - backlight: da9052: Fully initialize backlight_properties during probe
+    - backlight: lm3639: Fully initialize backlight_properties during probe
+    - backlight: lp8788: Fully initialize backlight_properties during probe
+    - sparc32: Use generic cmpdi2/ucmpdi2 variants
+    - mtd: maps: sun_uflash: Declare uflash_devinit static
+    - sparc32: Do not select GENERIC_ISA_DMA
+    - sparc32: Fix section mismatch in leon_pci_grpci
+    - clk: Fix clk_core_get NULL dereference
+    - clk: zynq: Prevent null pointer dereference caused by kmalloc failure
+    - PCI: brcmstb: Fix broken brcm_pcie_mdio_write() polling
+    - cifs: Fix writeback data corruption
+    - ALSA: hda/realtek: fix ALC285 issues on HP Envy x360 laptops
+    - ALSA: hda/tas2781: use dev_dbg in system_resume
+    - ALSA: hda/tas2781: add lock to system_suspend
+    - ALSA: hda/tas2781: do not reset cur_* values in runtime_suspend
+    - ALSA: hda/tas2781: do not call pm_runtime_force_* in system_resume/suspend
+    - ALSA: hda/tas2781: restore power state after system_resume
+    - ALSA: scarlett2: Fix Scarlett 4th Gen 4i4 low-voltage detection
+    - ALSA: scarlett2: Fix Scarlett 4th Gen autogain status values
+    - ALSA: scarlett2: Fix Scarlett 4th Gen input gain range
+    - ALSA: scarlett2: Fix Scarlett 4th Gen input gain range again
+    - mips: cm: Convert __mips_cm_l2sync_phys_base() to weak function
+    - platform/x86/intel/pmc/lnl: Remove SSRAM support
+    - platform/x86/intel/pmc/arl: Put GNA device in D3
+    - platform/x86/amd/pmf: Do not use readl() for policy buffer access
+    - ALSA: usb-audio: Stop parsing channels bits when all channels are found.
+    - phy: qcom: qmp-usb: split USB-C PHY driver
+    - phy: qcom: qmp-usbc: add support for the Type-C handling
+    - phy: qcom: qmp-usbc: handle CLAMP register in a correct way
+    - scsi: hisi_sas: Fix a deadlock issue related to automatic dump
+    - RDMA/irdma: Remove duplicate assignment
+    - RDMA/srpt: Do not register event handler until srpt device is fully setup
+    - f2fs: compress: fix to guarantee persisting compressed blocks by CP
+    - f2fs: compress: fix to cover normal cluster write with cp_rwsem
+    - f2fs: compress: fix to check unreleased compressed cluster
+    - f2fs: compress: fix to avoid inconsistence bewteen i_blocks and dnode
+    - f2fs: fix to remove unnecessary f2fs_bug_on() to avoid panic
+    - f2fs: zone: fix to wait completion of last bio in zone correctly
+    - f2fs: fix NULL pointer dereference in f2fs_submit_page_write()
+    - f2fs: compress: fix to cover f2fs_disable_compressed_file() w/ i_sem
+    - f2fs: fix to avoid potential panic during recovery
+    - scsi: csiostor: Avoid function pointer casts
+    - i3c: dw: Disable IBI IRQ depends on hot-join and SIR enabling
+    - RDMA/hns: Fix mis-modifying default congestion control algorithm
+    - RDMA/device: Fix a race between mad_client and cm_client init
+    - RDMA/rtrs-clt: Check strnlen return len in sysfs mpath_policy_store()
+    - scsi: bfa: Fix function pointer type mismatch for hcb_qe->cbfn
+    - f2fs: fix to create selinux label during whiteout initialization
+    - f2fs: compress: fix to check zstd compress level correctly in mount option
+    - net: sunrpc: Fix an off by one in rpc_sockaddr2uaddr()
+    - NFSv4.2: fix nfs4_listxattr kernel BUG at mm/usercopy.c:102
+    - NFSv4.2: fix listxattr maximum XDR buffer size
+    - f2fs: compress: fix to check compress flag w/ .i_sem lock
+    - f2fs: check number of blocks in a current section
+    - watchdog: starfive: Check pm_runtime_enabled() before decrementing usage
+      counter
+    - watchdog: stm32_iwdg: initialize default timeout
+    - f2fs: fix to use correct segment type in f2fs_allocate_data_block()
+    - f2fs: ro: compress: fix to avoid caching unaligned extent
+    - RDMA/mana_ib: Fix bug in creation of dma regions
+    - RDMA/mana_ib: Introduce mdev_to_gc helper function
+    - RDMA/mana_ib: Introduce mana_ib_get_netdev helper function
+    - RDMA/mana_ib: Introduce mana_ib_install_cq_cb helper function
+    - RDMA/mana_ib: Use virtual address in dma regions for MRs
+    - Input: iqs7222 - add support for IQS7222D v1.1 and v1.2
+    - NFS: Fix nfs_netfs_issue_read() xarray locking for writeback interrupt
+    - NFS: Fix an off by one in root_nfs_cat()
+    - NFSv4.1/pnfs: fix NFS with TLS in pnfs
+    - ACPI: HMAT: Remove register of memory node for generic target
+    - f2fs: compress: relocate some judgments in f2fs_reserve_compress_blocks
+    - f2fs: compress: fix reserve_cblocks counting error when out of space
+    - f2fs: fix to truncate meta inode pages forcely
+    - f2fs: zone: fix to remove pow2 check condition for zoned block device
+    - cxl: Fix the incorrect assignment of SSLBIS entry pointer initial location
+    - perf/x86/amd/core: Avoid register reset when CPU is dead
+    - afs: Revert "afs: Hide silly-rename files from userspace"
+    - afs: Don't cache preferred address
+    - afs: Fix occasional rmdir-then-VNOVNODE with generic/011
+    - f2fs: fix to avoid use-after-free issue in f2fs_filemap_fault
+    - nfs: fix panic when nfs4_ff_layout_prepare_ds() fails
+    - ovl: relax WARN_ON in ovl_verify_area()
+    - io_uring/net: correct the type of variable
+    - remoteproc: stm32: Fix incorrect type in assignment for va
+    - remoteproc: stm32: Fix incorrect type assignment returned by
+      stm32_rproc_get_loaded_rsc_tablef
+    - iio: pressure: mprls0025pa fix off-by-one enum
+    - usb: phy: generic: Get the vbus supply
+    - tty: vt: fix 20 vs 0x20 typo in EScsiignore
+    - serial: max310x: fix syntax error in IRQ error message
+    - tty: serial: samsung: fix tx_empty() to return TIOCSER_TEMT
+    - arm64: dts: broadcom: bcmbca: bcm4908: drop invalid switch cells
+    - coresight: Fix issue where a source device's helpers aren't disabled
+    - coresight: etm4x: Set skip_power_up in etm4_init_arch_data function
+    - xhci: Add interrupt pending autoclear flag to each interrupter
+    - xhci: make isoc_bei_interval variable interrupter specific.
+    - xhci: remove unnecessary event_ring_deq parameter from xhci_handle_event()
+    - xhci: update event ring dequeue pointer position to controller correctly
+    - coccinelle: device_attr_show: Remove useless expression STR
+    - kconfig: fix infinite loop when expanding a macro at the end of file
+    - iio: gts-helper: Fix division loop
+    - bus: mhi: ep: check the correct variable in mhi_ep_register_controller()
+    - hwtracing: hisi_ptt: Move type check to the beginning of
+      hisi_ptt_pmu_event_init()
+    - rtc: mt6397: select IRQ_DOMAIN instead of depending on it
+    - rtc: max31335: fix interrupt status reg
+    - serial: 8250_exar: Don't remove GPIO device on suspend
+    - staging: greybus: fix get_channel_from_mode() failure path
+    - mei: vsc: Call wake_up() in the threaded IRQ handler
+    - mei: vsc: Don't use sleeping condition in wait_event_timeout()
+    - usb: gadget: net2272: Use irqflags in the call to net2272_probe_fin
+    - char: xilinx_hwicap: Fix NULL vs IS_ERR() bug
+    - x86/hyperv: Use per cpu initial stack for vtl context
+    - ASoC: tlv320adc3xxx: Don't strip remove function when driver is builtin
+    - thermal/drivers/mediatek/lvts_thermal: Fix a memory leak in an error
+      handling path
+    - thermal/drivers/qoriq: Fix getting tmu range
+    - io_uring: don't save/restore iowait state
+    - spi: lpspi: Avoid potential use-after-free in probe()
+    - spi: Restore delays for non-GPIO chip select
+    - ASoC: rockchip: i2s-tdm: Fix inaccurate sampling rates
+    - nouveau: reset the bo resource bus info after an eviction
+    - tcp: Fix NEW_SYN_RECV handling in inet_twsk_purge()
+    - rds: tcp: Fix use-after-free of net in reqsk_timer_handler().
+    - octeontx2-af: Use matching wake_up API variant in CGX command interface
+    - s390/vtime: fix average steal time calculation
+    - net/sched: taprio: proper TCA_TAPRIO_TC_ENTRY_INDEX check
+    - devlink: Fix devlink parallel commands processing
+    - riscv: Only check online cpus for emulated accesses
+    - soc: fsl: dpio: fix kcalloc() argument order
+    - cpufreq: Fix per-policy boost behavior on SoCs using cpufreq_boost_set_sw()
+    - io_uring: Fix release of pinned pages when __io_uaddr_map fails
+    - tcp: Fix refcnt handling in __inet_hash_connect().
+    - vmxnet3: Fix missing reserved tailroom
+    - hsr: Fix uninit-value access in hsr_get_node()
+    - net: txgbe: fix clk_name exceed MAX_DEV_ID limits
+    - spi: spi-mem: add statistics support to ->exec_op() calls
+    - spi: Fix error code checking in spi_mem_exec_op()
+    - nvme: fix reconnection fail due to reserved tag allocation
+    - drm/xe: Invalidate userptr VMA on page pin fault
+    - drm/xe: Skip VMAs pin when requesting signal to the last XE_EXEC
+    - net: mediatek: mtk_eth_soc: clear MAC_MCR_FORCE_LINK only when MAC is up
+    - net: ethernet: mtk_eth_soc: fix PPE hanging issue
+    - io_uring: fix poll_remove stalled req completion
+    - ASoC: SOF: amd: Move signed_fw_image to struct acp_quirk_entry
+    - ASoC: SOF: amd: Skip IRAM/DRAM size modification for Steam Deck OLED
+    - riscv: Fix compilation error with FAST_GUP and rv32
+    - xen/evtchn: avoid WARN() when unbinding an event channel
+    - xen/events: increment refcnt only if event channel is refcounted
+    - packet: annotate data-races around ignore_outgoing
+    - xfrm: Allow UDP encapsulation only in offload modes
+    - net: veth: do not manipulate GRO when using XDP
+    - net: dsa: mt7530: prevent possible incorrect XTAL frequency selection
+    - spi: spi-imx: fix off-by-one in mx51 CPU mode burst length
+    - drm: Fix drm_fixp2int_round() making it add 0.5
+    - virtio: uapi: Drop __packed attribute in linux/virtio_pci.h
+    - vdpa_sim: reset must not run
+    - vdpa/mlx5: Allow CVQ size changes
+    - virtio: packed: fix unmap leak for indirect desc table
+    - net: move dev->state into net_device_read_txrx group
+    - wireguard: receive: annotate data-race around receiving_counter.counter
+    - rds: introduce acquire/release ordering in acquire/release_in_xmit()
+    - hsr: Handle failures in module init
+    - ipv4: raw: Fix sending packets from raw sockets via IPsec tunnels
+    - nouveau/gsp: don't check devinit disable on GSP.
+    - ceph: stop copying to iter at EOF on sync reads
+    - net: phy: fix phy_read_poll_timeout argument type in genphy_loopback
+    - dm-integrity: fix a memory leak when rechecking the data
+    - net/bnx2x: Prevent access to a freed page in page_pool
+    - devlink: fix port new reply cmd type
+    - octeontx2: Detect the mbox up or down message via register
+    - octeontx2-pf: Wait till detach_resources msg is complete
+    - octeontx2-pf: Use default max_active works instead of one
+    - octeontx2-pf: Send UP messages to VF only when VF is up.
+    - octeontx2-af: Use separate handlers for interrupts
+    - drm/amdgpu: add MMHUB 3.3.1 support
+    - drm/amdgpu: fix mmhub client id out-of-bounds access
+    - drm/amdgpu: drop setting buffer funcs in sdma442
+    - netfilter: nft_set_pipapo: release elements in clone only from destroy path
+    - netfilter: nf_tables: do not compare internal table flags on updates
+    - rcu: add a helper to report consolidated flavor QS
+    - net: report RCU QS on threaded NAPI repolling
+    - bpf: report RCU QS in cpumap kthread
+    - net: dsa: mt7530: fix link-local frames that ingress vlan filtering ports
+    - net: dsa: mt7530: fix handling of all link-local frames
+    - netfilter: nf_tables: Fix a memory leak in nf_tables_updchain
+    - spi: spi-mt65xx: Fix NULL pointer access in interrupt handler
+    - selftests: forwarding: Fix ping failure due to short timeout
+    - dm io: Support IO priority
+    - dm-integrity: align the outgoing bio in integrity_recheck
+    - x86/efistub: Clear decompressor BSS in native EFI entrypoint
+    - x86/efistub: Don't clear BSS twice in mixed mode
+    - printk: Adjust mapping for 32bit seq macros
+    - printk: Use prb_first_seq() as base for 32bit seq macros
+    - Linux 6.8.2
+    - [Config] updateconfig following v6.8.2 import
+
+  * Provide python perf module (LP: #2051560)
+    - [Packaging] enable perf python module
+    - [Packaging] provide a wrapper module for python-perf
+
+  * To support AMD Adaptive Backlight Management (ABM) for power profiles daemon
+    >= 2.0 (LP: #2056716)
+    - drm/amd/display: add panel_power_savings sysfs entry to eDP connectors
+    - drm/amdgpu: respect the abmlevel module parameter value if it is set
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Disable StarFive JH7100 support
+    - [Config] Disable Renesas RZ/Five support
+    - [Config] Disable BINFMT_FLAT for riscv64
+
+ -- Roxana Nicolescu <roxana.nicolescu@canonical.com>  Wed, 01 May 2024 16:02:05 +0200
+
+linux (6.8.0-31.31) noble; urgency=medium
+
+  * noble/linux: 6.8.0-31.31 -proposed tracker (LP: #2062933)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.04.04)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 19 Apr 2024 23:46:38 +0200
+
+linux (6.8.0-30.30) noble; urgency=medium
+
+  * noble/linux: 6.8.0-30.30 -proposed tracker (LP: #2061893)
+
+  * System unstable, kernel ring buffer flooded with "BUG: Bad page state in
+    process swapper/0" (LP: #2056706)
+    - xen-netfront: Add missing skb_mark_for_recycle
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 16 Apr 2024 21:17:11 +0200
+
+linux (6.8.0-29.29) noble; urgency=medium
+
+  * noble/linux: 6.8.0-29.29 -proposed tracker (LP: #2061888)
+
+  * [24.04 FEAT] [SEC2353] zcrypt: extend error recovery to deal with device
+    scans (LP: #2050019)
+    - s390/zcrypt: harmonize debug feature calls and defines
+    - s390/zcrypt: introduce dynamic debugging for AP and zcrypt code
+    - s390/pkey: harmonize pkey s390 debug feature calls
+    - s390/pkey: introduce dynamic debugging for pkey
+    - s390/ap: add debug possibility for AP messages
+    - s390/zcrypt: add debug possibility for CCA and EP11 messages
+    - s390/ap: rearm APQNs bindings complete completion
+    - s390/ap: clarify AP scan bus related functions and variables
+    - s390/ap: rework ap_scan_bus() to return true on config change
+    - s390/ap: introduce mutex to lock the AP bus scan
+    - s390/zcrypt: introduce retries on in-kernel send CPRB functions
+    - s390/zcrypt: improve zcrypt retry behavior
+    - s390/pkey: improve pkey retry behavior
+
+  * [24.04 FEAT] Memory hotplug vmem pages (s390x) (LP: #2051835)
+    - mm/memory_hotplug: introduce MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers
+    - s390/mm: allocate vmemmap pages from self-contained memory range
+    - s390/sclp: remove unhandled memory notifier type
+    - s390/mm: implement MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers
+    - s390: enable MHP_MEMMAP_ON_MEMORY
+    - [Config] enable CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE and
+      CONFIG_MHP_MEMMAP_ON_MEMORY for s390x
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 16 Apr 2024 20:32:09 +0200
+
+linux (6.8.0-28.28) noble; urgency=medium
+
+  * noble/linux: 6.8.0-28.28 -proposed tracker (LP: #2061867)
+
+  * linux-gcp 6.8.0-1005.5 (+ others) Noble kernel regression iwth new apparmor
+    profiles/features (LP: #2061851)
+    - SAUCE: apparmor4.0.0 [92/90]: fix address mapping for recvfrom
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 16 Apr 2024 18:29:17 +0200
+
+linux (6.8.0-25.25) noble; urgency=medium
+
+  * noble/linux: 6.8.0-25.25 -proposed tracker (LP: #2061083)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.04.04)
+
+  * Apply mitigations for the native BHI hardware vulnerabilty (LP: #2060909)
+    - x86/cpufeatures: Add new word for scattered features
+    - x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file
+    - x86/syscall: Don't force use of indirect calls for system calls
+    - x86/bhi: Add support for clearing branch history at syscall entry
+    - x86/bhi: Define SPEC_CTRL_BHI_DIS_S
+    - x86/bhi: Enumerate Branch History Injection (BHI) bug
+    - x86/bhi: Add BHI mitigation knob
+    - x86/bhi: Mitigate KVM by default
+    - KVM: x86: Add BHI_NO
+    - x86: set SPECTRE_BHI_ON as default
+    - [Config] enable spectre_bhi=auto by default
+
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [01/90]: LSM stacking v39: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [02/90]: LSM stacking v39: SM: Infrastructure
+      management of the sock security
+    - SAUCE: apparmor4.0.0 [03/90]: LSM stacking v39: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [04/90]: LSM stacking v39: IMA: avoid label collisions
+      with stacked LSMs
+    - SAUCE: apparmor4.0.0 [05/90]: LSM stacking v39: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [06/90]: LSM stacking v39: LSM: Add lsmblob_to_secctx
+      hook
+    - SAUCE: apparmor4.0.0 [07/90]: LSM stacking v39: Audit: maintain an lsmblob
+      in audit_context
+    - SAUCE: apparmor4.0.0 [08/90]: LSM stacking v39: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [09/90]: LSM stacking v39: Audit: Update shutdown LSM
+      data
+    - SAUCE: apparmor4.0.0 [10/90]: LSM stacking v39: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [11/90]: LSM stacking v39: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [12/90]: LSM stacking v39: Audit: use an lsmblob in
+      audit_names
+    - SAUCE: apparmor4.0.0 [13/90]: LSM stacking v39: LSM: Create new
+      security_cred_getlsmblob LSM hook
+    - SAUCE: apparmor4.0.0 [14/90]: LSM stacking v39: Audit: Change context data
+      from secid to lsmblob
+    - SAUCE: apparmor4.0.0 [15/90]: LSM stacking v39: Netlabel: Use lsmblob for
+      audit data
+    - SAUCE: apparmor4.0.0 [16/90]: LSM stacking v39: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [17/90]: LSM stacking v39: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [18/90]: LSM stacking v39: LSM: Use lsmcontext in
+      security_lsmblob_to_secctx
+    - SAUCE: apparmor4.0.0 [19/90]: LSM stacking v39: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [20/90]: LSM stacking v39: LSM: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [21/90]: LSM stacking v39: LSM:
+      security_lsmblob_to_secctx module selection
+    - SAUCE: apparmor4.0.0 [22/90]: LSM stacking v39: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [23/90]: LSM stacking v39: Audit: Allow multiple
+      records in an audit_buffer
+    - SAUCE: apparmor4.0.0 [24/90]: LSM stacking v39: Audit: Add record for
+      multiple task security contexts
+    - SAUCE: apparmor4.0.0 [25/90]: LSM stacking v39: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [26/90]: LSM stacking v39: Audit: Add record for
+      multiple object contexts
+    - SAUCE: apparmor4.0.0 [27/90]: LSM stacking v39: LSM: Remove unused
+      lsmcontext_init()
+    - SAUCE: apparmor4.0.0 [28/90]: LSM stacking v39: LSM: Improve logic in
+      security_getprocattr
+    - SAUCE: apparmor4.0.0 [29/90]: LSM stacking v39: LSM: secctx provider check
+      on release
+    - SAUCE: apparmor4.0.0 [31/90]: LSM stacking v39: LSM: Exclusive secmark usage
+    - SAUCE: apparmor4.0.0 [32/90]: LSM stacking v39: LSM: Identify which LSM
+      handles the context string
+    - SAUCE: apparmor4.0.0 [33/90]: LSM stacking v39: AppArmor: Remove the
+      exclusive flag
+    - SAUCE: apparmor4.0.0 [34/90]: LSM stacking v39: LSM: Add mount opts blob
+      size tracking
+    - SAUCE: apparmor4.0.0 [35/90]: LSM stacking v39: LSM: allocate mnt_opts blobs
+      instead of module specific data
+    - SAUCE: apparmor4.0.0 [36/90]: LSM stacking v39: LSM: Infrastructure
+      management of the key security blob
+    - SAUCE: apparmor4.0.0 [37/90]: LSM stacking v39: LSM: Infrastructure
+      management of the mnt_opts security blob
+    - SAUCE: apparmor4.0.0 [38/90]: LSM stacking v39: LSM: Correct handling of
+      ENOSYS in inode_setxattr
+    - SAUCE: apparmor4.0.0 [39/90]: LSM stacking v39: LSM: Remove lsmblob
+      scaffolding
+    - SAUCE: apparmor4.0.0 [40/90]: LSM stacking v39: LSM: Allow reservation of
+      netlabel
+    - SAUCE: apparmor4.0.0 [41/90]: LSM stacking v39: LSM: restrict
+      security_cred_getsecid() to a single LSM
+    - SAUCE: apparmor4.0.0 [42/90]: LSM stacking v39: Smack: Remove
+      LSM_FLAG_EXCLUSIVE
+    - SAUCE: apparmor4.0.0 [43/90]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0
+      [12/95]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [44/90]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [45/90]: add unpriviled user ns mediation
+    - SAUCE: apparmor4.0.0 [46/90]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [47/90]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [48/90]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [49/90]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [50/90]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/90]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/90]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/90]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [54/90]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [55/90]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [56/90]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [57/90]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [58/90]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [59/90]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [60/90]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [61/90]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [62/90]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [63/90]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [64/90]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [65/90] v6.8 prompt:fixup interruptible
+    - SAUCE: apparmor4.0.0 [69/90]: add io_uring mediation
+    - SAUCE: apparmor4.0.0 [70/90]: apparmor: fix oops when racing to retrieve
+      notification
+    - SAUCE: apparmor4.0.0 [71/90]: apparmor: fix notification header size
+    - SAUCE: apparmor4.0.0 [72/90]: apparmor: fix request field from a prompt
+      reply that denies all access
+    - SAUCE: apparmor4.0.0 [73/90]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+    - SAUCE: apparmor4.0.0 [74/90]: apparmor: cleanup attachment perm lookup to
+      use lookup_perms()
+    - SAUCE: apparmor4.0.0 [75/90]: apparmor: remove redundant unconfined check.
+    - SAUCE: apparmor4.0.0 [76/90]: apparmor: switch signal mediation to using
+      RULE_MEDIATES
+    - SAUCE: apparmor4.0.0 [77/90]: apparmor: ensure labels with more than one
+      entry have correct flags
+    - SAUCE: apparmor4.0.0 [78/90]: apparmor: remove explicit restriction that
+      unconfined cannot use change_hat
+    - SAUCE: apparmor4.0.0 [79/90]: apparmor: cleanup: refactor file_perm() to
+      provide semantics of some checks
+    - SAUCE: apparmor4.0.0 [80/90]: apparmor: carry mediation check on label
+    - SAUCE: apparmor4.0.0 [81/90]: apparmor: convert easy uses of unconfined() to
+      label_mediates()
+    - SAUCE: apparmor4.0.0 [82/90]: apparmor: add additional flags to extended
+      permission.
+    - SAUCE: apparmor4.0.0 [83/90]: apparmor: add support for profiles to define
+      the kill signal
+    - SAUCE: apparmor4.0.0 [84/90]: apparmor: fix x_table_lookup when stacking is
+      not the first entry
+    - SAUCE: apparmor4.0.0 [85/90]: apparmor: allow profile to be transitioned
+      when a user ns is created
+    - SAUCE: apparmor4.0.0 [86/90]: apparmor: add ability to mediate caps with
+      policy state machine
+    - SAUCE: apparmor4.0.0 [87/90]: fixup notify
+    - SAUCE: apparmor4.0.0 [88/90]: apparmor: add fine grained ipv4/ipv6 mediation
+    - SAUCE: apparmor4.0.0 [89/90]:apparmor: disable tailglob responses for now
+    - SAUCE: apparmor4.0.0 [90/90]: apparmor: Fix notify build warnings
+    - SAUCE: apparmor4.0.0: fix reserved mem for when we save ipv6 addresses
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [66/90]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [67/90]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [68/90]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+
+  * [MTL] x86: Fix Cache info sysfs is not populated (LP: #2049793)
+    - SAUCE: cacheinfo: Check for null last-level cache info
+    - SAUCE: cacheinfo: Allocate memory for memory if not done from the primary
+      CPU
+    - SAUCE: x86/cacheinfo: Delete global num_cache_leaves
+    - SAUCE: x86/cacheinfo: Clean out init_cache_level()
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor4.0.0: LSM stacking v39: fix build error with
+      CONFIG_SECURITY=n
+    - [Config] toolchain version update
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 12 Apr 2024 10:42:33 +0200
+
+linux (6.8.0-22.22) noble; urgency=medium
+
+  * noble/linux: 6.8.0-22.22 -proposed tracker (LP: #2060238)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 04 Apr 2024 23:00:49 +0200
+
+linux (6.8.0-21.21) noble; urgency=medium
+
+  * noble/linux: 6.8.0-21.21 -proposed tracker (LP: #2060225)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update toolchain version in annotations
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 04 Apr 2024 22:20:27 +0200
+
+linux (6.8.0-20.20) noble; urgency=medium
+
+  * noble/linux: 6.8.0-20.20 -proposed tracker (LP: #2058221)
+
+  * Noble update: v6.8.1 upstream stable release (LP: #2058224)
+    - x86/mmio: Disable KVM mitigation when X86_FEATURE_CLEAR_CPU_BUF is set
+    - Documentation/hw-vuln: Add documentation for RFDS
+    - x86/rfds: Mitigate Register File Data Sampling (RFDS)
+    - KVM/x86: Export RFDS_NO and RFDS_CLEAR to guests
+    - Linux 6.8.1
+
+  * Autopkgtest failures on amd64 (LP: #2048768)
+    - [Packaging] update to clang-18
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor4.0.0: LSM stacking v39: fix build error with
+      CONFIG_SECURITY=n
+    - [Config] amd64: MITIGATION_RFDS=y
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 18 Mar 2024 11:08:14 +0100
+
+linux (6.8.0-19.19) noble; urgency=medium
+
+  * noble/linux: 6.8.0-19.19 -proposed tracker (LP: #2057910)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] re-introduce linux-doc as an empty package
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 14 Mar 2024 14:36:14 +0100
+
+linux (6.8.0-18.18) noble; urgency=medium
+
+  * noble/linux: 6.8.0-18.18 -proposed tracker (LP: #2057456)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] drop dependency on libclang-17
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 12 Mar 2024 14:44:13 +0100
+
+linux (6.8.0-17.17) noble; urgency=medium
+
+  * noble/linux: 6.8.0-17.17 -proposed tracker (LP: #2056745)
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] Add debian/control sanity check"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 11 Mar 2024 12:46:38 +0100
+
+linux (6.8.0-16.16) noble; urgency=medium
+
+  * noble/linux: 6.8.0-16.16 -proposed tracker (LP: #2056738)
+
+  * left-over ceph debugging printks (LP: #2056616)
+    - Revert "UBUNTU: SAUCE: ceph: make sure all the files successfully put before
+      unmounting"
+
+  * qat: Improve error recovery flows (LP: #2056354)
+    - crypto: qat - add heartbeat error simulator
+    - crypto: qat - disable arbitration before reset
+    - crypto: qat - update PFVF protocol for recovery
+    - crypto: qat - re-enable sriov after pf reset
+    - crypto: qat - add fatal error notification
+    - crypto: qat - add auto reset on error
+    - crypto: qat - limit heartbeat notifications
+    - crypto: qat - improve aer error reset handling
+    - crypto: qat - change SLAs cleanup flow at shutdown
+    - crypto: qat - resolve race condition during AER recovery
+    - Documentation: qat: fix auto_reset section
+
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [01/87]: LSM stacking v39: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [02/87]: LSM stacking v39: SM: Infrastructure
+      management of the sock security
+    - SAUCE: apparmor4.0.0 [03/87]: LSM stacking v39: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [04/87]: LSM stacking v39: IMA: avoid label collisions
+      with stacked LSMs
+    - SAUCE: apparmor4.0.0 [05/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [06/87]: LSM stacking v39: LSM: Add lsmblob_to_secctx
+      hook
+    - SAUCE: apparmor4.0.0 [07/87]: LSM stacking v39: Audit: maintain an lsmblob
+      in audit_context
+    - SAUCE: apparmor4.0.0 [08/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [09/87]: LSM stacking v39: Audit: Update shutdown LSM
+      data
+    - SAUCE: apparmor4.0.0 [10/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [11/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [12/87]: LSM stacking v39: Audit: use an lsmblob in
+      audit_names
+    - SAUCE: apparmor4.0.0 [13/87]: LSM stacking v39: LSM: Create new
+      security_cred_getlsmblob LSM hook
+    - SAUCE: apparmor4.0.0 [14/87]: LSM stacking v39: Audit: Change context data
+      from secid to lsmblob
+    - SAUCE: apparmor4.0.0 [15/87]: LSM stacking v39: Netlabel: Use lsmblob for
+      audit data
+    - SAUCE: apparmor4.0.0 [16/87]: LSM stacking v39: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [17/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [18/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_lsmblob_to_secctx
+    - SAUCE: apparmor4.0.0 [19/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [20/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [21/87]: LSM stacking v39: LSM:
+      security_lsmblob_to_secctx module selection
+    - SAUCE: apparmor4.0.0 [22/87]: LSM stacking v39: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [23/87]: LSM stacking v39: Audit: Allow multiple
+      records in an audit_buffer
+    - SAUCE: apparmor4.0.0 [24/87]: LSM stacking v39: Audit: Add record for
+      multiple task security contexts
+    - SAUCE: apparmor4.0.0 [25/87]: LSM stacking v39: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [26/87]: LSM stacking v39: Audit: Add record for
+      multiple object contexts
+    - SAUCE: apparmor4.0.0 [27/87]: LSM stacking v39: LSM: Remove unused
+      lsmcontext_init()
+    - SAUCE: apparmor4.0.0 [28/87]: LSM stacking v39: LSM: Improve logic in
+      security_getprocattr
+    - SAUCE: apparmor4.0.0 [29/87]: LSM stacking v39: LSM: secctx provider check
+      on release
+    - SAUCE: apparmor4.0.0 [31/87]: LSM stacking v39: LSM: Exclusive secmark usage
+    - SAUCE: apparmor4.0.0 [32/87]: LSM stacking v39: LSM: Identify which LSM
+      handles the context string
+    - SAUCE: apparmor4.0.0 [33/87]: LSM stacking v39: AppArmor: Remove the
+      exclusive flag
+    - SAUCE: apparmor4.0.0 [34/87]: LSM stacking v39: LSM: Add mount opts blob
+      size tracking
+    - SAUCE: apparmor4.0.0 [35/87]: LSM stacking v39: LSM: allocate mnt_opts blobs
+      instead of module specific data
+    - SAUCE: apparmor4.0.0 [36/87]: LSM stacking v39: LSM: Infrastructure
+      management of the key security blob
+    - SAUCE: apparmor4.0.0 [37/87]: LSM stacking v39: LSM: Infrastructure
+      management of the mnt_opts security blob
+    - SAUCE: apparmor4.0.0 [38/87]: LSM stacking v39: LSM: Correct handling of
+      ENOSYS in inode_setxattr
+    - SAUCE: apparmor4.0.0 [39/87]: LSM stacking v39: LSM: Remove lsmblob
+      scaffolding
+    - SAUCE: apparmor4.0.0 [40/87]: LSM stacking v39: LSM: Allow reservation of
+      netlabel
+    - SAUCE: apparmor4.0.0 [41/87]: LSM stacking v39: LSM: restrict
+      security_cred_getsecid() to a single LSM
+    - SAUCE: apparmor4.0.0 [42/87]: LSM stacking v39: Smack: Remove
+      LSM_FLAG_EXCLUSIVE
+    - SAUCE: apparmor4.0.0 [43/87]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0
+      [12/95]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [44/87]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [45/87]: add unpriviled user ns mediation
+    - SAUCE: apparmor4.0.0 [46/87]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [47/87]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [48/87]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [49/87]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [50/87]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/87]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/87]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/87]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [54/87]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [55/87]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [56/87]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [57/87]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [58/87]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [59/87]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [60/87]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [61/87]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [62/87]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [63/87]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [64/87]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [65/87] v6.8 prompt:fixup interruptible
+    - SAUCE: apparmor4.0.0 [69/87]: add io_uring mediation
+    - SAUCE: apparmor4.0.0 [70/87]: apparmor: fix oops when racing to retrieve
+      notification
+    - SAUCE: apparmor4.0.0 [71/87]: apparmor: fix notification header size
+    - SAUCE: apparmor4.0.0 [72/87]: apparmor: fix request field from a prompt
+      reply that denies all access
+    - SAUCE: apparmor4.0.0 [73/87]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+    - SAUCE: apparmor4.0.0 [74/87]: apparmor: cleanup attachment perm lookup to
+      use lookup_perms()
+    - SAUCE: apparmor4.0.0 [75/87]: apparmor: remove redundant unconfined check.
+    - SAUCE: apparmor4.0.0 [76/87]: apparmor: switch signal mediation to using
+      RULE_MEDIATES
+    - SAUCE: apparmor4.0.0 [77/87]: apparmor: ensure labels with more than one
+      entry have correct flags
+    - SAUCE: apparmor4.0.0 [78/87]: apparmor: remove explicit restriction that
+      unconfined cannot use change_hat
+    - SAUCE: apparmor4.0.0 [79/87]: apparmor: cleanup: refactor file_perm() to
+      provide semantics of some checks
+    - SAUCE: apparmor4.0.0 [80/87]: apparmor: carry mediation check on label
+    - SAUCE: apparmor4.0.0 [81/87]: apparmor: convert easy uses of unconfined() to
+      label_mediates()
+    - SAUCE: apparmor4.0.0 [82/87]: apparmor: add additional flags to extended
+      permission.
+    - SAUCE: apparmor4.0.0 [83/87]: apparmor: add support for profiles to define
+      the kill signal
+    - SAUCE: apparmor4.0.0 [84/87]: apparmor: fix x_table_lookup when stacking is
+      not the first entry
+    - SAUCE: apparmor4.0.0 [85/87]: apparmor: allow profile to be transitioned
+      when a user ns is created
+    - SAUCE: apparmor4.0.0 [86/87]: apparmor: add ability to mediate caps with
+      policy state machine
+    - SAUCE: apparmor4.0.0 [87/87]: fixup notify
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [66/87]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [67/87]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [68/87]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+
+  * Enable lowlatency settings in the generic kernel (LP: #2051342)
+    - [Config] enable low-latency settings
+
+  * hwmon: (coretemp) Fix core count limitation (LP: #2056126)
+    - hwmon: (coretemp) Introduce enum for attr index
+    - hwmon: (coretemp) Remove unnecessary dependency of array index
+    - hwmon: (coretemp) Replace sensor_device_attribute with device_attribute
+    - hwmon: (coretemp) Remove redundant pdata->cpu_map[]
+    - hwmon: (coretemp) Abstract core_temp helpers
+    - hwmon: (coretemp) Split package temp_data and core temp_data
+    - hwmon: (coretemp) Remove redundant temp_data->is_pkg_data
+    - hwmon: (coretemp) Use dynamic allocated memory for core temp_data
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Disable CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION
+    - [Packaging] remove debian/scripts/misc/arch-has-odm-enabled.sh
+    - rebase on v6.8
+    - [Config] toolchain version update
+
+  * Miscellaneous upstream changes
+    - crypto: qat - add fatal error notify method
+
+  * Rebase on v6.8
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 11 Mar 2024 10:14:10 +0100
+
+linux (6.8.0-15.15) noble; urgency=medium
+
+  * noble/linux: 6.8.0-15.15 -proposed tracker (LP: #2055871)
+
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.8-rc7
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] Transition laptop-23.10 to generic"
+
+  * Rebase on v6.8-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 04 Mar 2024 11:50:51 +0100
+
+linux (6.8.0-14.14) noble; urgency=medium
+
+  * noble/linux: 6.8.0-14.14 -proposed tracker (LP: #2055551)
+
+  * Please change CONFIG_CONSOLE_LOGLEVEL_QUIET to 3 (LP: #2049390)
+    - [Config] reduce verbosity when booting in quiet mode
+
+  * linux: please move erofs.ko (CONFIG_EROFS for EROFS support) from linux-
+    modules-extra to linux-modules (LP: #2054809)
+    - UBUNTU [Packaging]: Include erofs in linux-modules instead of linux-modules-
+      extra
+
+  * linux: please move dmi-sysfs.ko (CONFIG_DMI_SYSFS for SMBIOS support) from
+    linux-modules-extra to linux-modules (LP: #2045561)
+    - [Packaging] Move dmi-sysfs.ko into linux-modules
+
+  * Enable CONFIG_INTEL_IOMMU_DEFAULT_ON and
+    CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON (LP: #1951440)
+    - [Config] enable Intel DMA remapping by default
+
+  * disable Intel DMA remapping by default (LP: #1971699)
+    - [Config] update tracking bug for CONFIG_INTEL_IOMMU_DEFAULT_ON
+
+  * Packaging resync (LP: #1786013)
+    - debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.02.29)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: modpost: Replace 0-length array with flex-array member
+    - [packaging] do not include debian/ directory in a binary package
+    - [packaging] remove debian/stamps/keep-dir
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 01 Mar 2024 11:45:12 +0100
+
+linux (6.8.0-13.13) noble; urgency=medium
+
+  * noble/linux: 6.8.0-13.13 -proposed tracker (LP: #2055421)
+
+  * Packaging resync (LP: #1786013)
+    - debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.02.29)
+
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.8-rc6
+    - [Config] updateconfifs following v6.8-rc6 rebase
+
+  * Rebase on v6.8-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 29 Feb 2024 15:02:24 +0100
+
+linux (6.8.0-12.12) noble; urgency=medium
+
+  * linux-tools-common: man page of usbip[d] is misplaced (LP: #2054094)
+    - [Packaging] rules: Put usbip manpages in the correct directory
+
+  * Validate connection interval to pass Bluetooth Test Suite (LP: #2052005)
+    - Bluetooth: Enforce validation on max value of connection interval
+
+  * Turning COMPAT_32BIT_TIME off on s390x (LP: #2038583)
+    - [Config] Turn off 31-bit COMPAT on s390x
+
+  * Don't produce linux-source binary package (LP: #2043994)
+    - [Packaging] Add debian/control sanity check
+
+  * Don't produce linux-*-source-<version> package (LP: #2052439)
+    - [Packaging] Move linux-source package stub to debian/control.d
+    - [Packaging] Build linux-source package only for the main kernel
+
+  * Don't produce linux-*-cloud-tools-common, linux-*-tools-common and
+    linux-*-tools-host binary packages (LP: #2048183)
+    - [Packaging] Move indep tools package stubs to debian/control.d
+    - [Packaging] Build indep tools packages only for the main kernel
+
+  * Enable CONFIG_INTEL_IOMMU_DEFAULT_ON and
+    CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON (LP: #1951440)
+    - [Config] enable Intel DMA remapping by default
+
+  * disable Intel DMA remapping by default (LP: #1971699)
+    - [Config] update tracking bug for CONFIG_INTEL_IOMMU_DEFAULT_ON
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Transition laptop-23.10 to generic
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 22 Feb 2024 14:31:00 +0100
+
+linux (6.8.0-11.11) noble; urgency=medium
+
+  * noble/linux: 6.8.0-11.11 -proposed tracker (LP: #2053094)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] riscv64: disable building unnecessary binary debs
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 14 Feb 2024 00:04:31 +0100
+
+linux (6.8.0-10.10) noble; urgency=medium
+
+  * noble/linux: 6.8.0-10.10 -proposed tracker (LP: #2053015)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] add Rust build-deps for riscv64
+
+  * Miscellaneous upstream changes
+    - Revert "Revert "UBUNTU: [Packaging] temporarily disable Rust dependencies on
+      riscv64""
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 13 Feb 2024 13:23:47 +0100
+
+linux (6.8.0-9.9) noble; urgency=medium
+
+  * noble/linux: 6.8.0-9.9 -proposed tracker (LP: #2052945)
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] temporarily disable Rust dependencies on
+      riscv64"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 12 Feb 2024 15:49:20 +0100
+
+linux (6.8.0-8.8) noble; urgency=medium
+
+  * noble/linux: 6.8.0-8.8 -proposed tracker (LP: #2052918)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] riscv64: enable linux-libc-dev build
+    - v6.8-rc4 rebase
+
+  * Rebase on v6.8-rc4
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 12 Feb 2024 10:13:34 +0100
+
+linux (6.8.0-7.7) noble; urgency=medium
+
+  * noble/linux: 6.8.0-7.7 -proposed tracker (LP: #2052691)
+
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [01/87]: LSM stacking v39: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [02/87]: LSM stacking v39: SM: Infrastructure
+      management of the sock security
+    - SAUCE: apparmor4.0.0 [03/87]: LSM stacking v39: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [04/87]: LSM stacking v39: IMA: avoid label collisions
+      with stacked LSMs
+    - SAUCE: apparmor4.0.0 [05/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [06/87]: LSM stacking v39: LSM: Add lsmblob_to_secctx
+      hook
+    - SAUCE: apparmor4.0.0 [07/87]: LSM stacking v39: Audit: maintain an lsmblob
+      in audit_context
+    - SAUCE: apparmor4.0.0 [08/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [09/87]: LSM stacking v39: Audit: Update shutdown LSM
+      data
+    - SAUCE: apparmor4.0.0 [10/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [11/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [12/87]: LSM stacking v39: Audit: use an lsmblob in
+      audit_names
+    - SAUCE: apparmor4.0.0 [13/87]: LSM stacking v39: LSM: Create new
+      security_cred_getlsmblob LSM hook
+    - SAUCE: apparmor4.0.0 [14/87]: LSM stacking v39: Audit: Change context data
+      from secid to lsmblob
+    - SAUCE: apparmor4.0.0 [15/87]: LSM stacking v39: Netlabel: Use lsmblob for
+      audit data
+    - SAUCE: apparmor4.0.0 [16/87]: LSM stacking v39: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [17/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [18/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_lsmblob_to_secctx
+    - SAUCE: apparmor4.0.0 [19/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [20/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [21/87]: LSM stacking v39: LSM:
+      security_lsmblob_to_secctx module selection
+    - SAUCE: apparmor4.0.0 [22/87]: LSM stacking v39: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [23/87]: LSM stacking v39: Audit: Allow multiple
+      records in an audit_buffer
+    - SAUCE: apparmor4.0.0 [24/87]: LSM stacking v39: Audit: Add record for
+      multiple task security contexts
+    - SAUCE: apparmor4.0.0 [25/87]: LSM stacking v39: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [26/87]: LSM stacking v39: Audit: Add record for
+      multiple object contexts
+    - SAUCE: apparmor4.0.0 [27/87]: LSM stacking v39: LSM: Remove unused
+      lsmcontext_init()
+    - SAUCE: apparmor4.0.0 [28/87]: LSM stacking v39: LSM: Improve logic in
+      security_getprocattr
+    - SAUCE: apparmor4.0.0 [29/87]: LSM stacking v39: LSM: secctx provider check
+      on release
+    - SAUCE: apparmor4.0.0 [31/87]: LSM stacking v39: LSM: Exclusive secmark usage
+    - SAUCE: apparmor4.0.0 [32/87]: LSM stacking v39: LSM: Identify which LSM
+      handles the context string
+    - SAUCE: apparmor4.0.0 [33/87]: LSM stacking v39: AppArmor: Remove the
+      exclusive flag
+    - SAUCE: apparmor4.0.0 [34/87]: LSM stacking v39: LSM: Add mount opts blob
+      size tracking
+    - SAUCE: apparmor4.0.0 [35/87]: LSM stacking v39: LSM: allocate mnt_opts blobs
+      instead of module specific data
+    - SAUCE: apparmor4.0.0 [36/87]: LSM stacking v39: LSM: Infrastructure
+      management of the key security blob
+    - SAUCE: apparmor4.0.0 [37/87]: LSM stacking v39: LSM: Infrastructure
+      management of the mnt_opts security blob
+    - SAUCE: apparmor4.0.0 [38/87]: LSM stacking v39: LSM: Correct handling of
+      ENOSYS in inode_setxattr
+    - SAUCE: apparmor4.0.0 [39/87]: LSM stacking v39: LSM: Remove lsmblob
+      scaffolding
+    - SAUCE: apparmor4.0.0 [40/87]: LSM stacking v39: LSM: Allow reservation of
+      netlabel
+    - SAUCE: apparmor4.0.0 [41/87]: LSM stacking v39: LSM: restrict
+      security_cred_getsecid() to a single LSM
+    - SAUCE: apparmor4.0.0 [42/87]: LSM stacking v39: Smack: Remove
+      LSM_FLAG_EXCLUSIVE
+    - SAUCE: apparmor4.0.0 [43/87]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0
+      [12/95]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [44/87]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [45/87]: add unpriviled user ns mediation
+    - SAUCE: apparmor4.0.0 [46/87]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [47/87]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [48/87]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [49/87]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [50/87]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/87]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/87]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/87]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [54/87]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [55/87]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [56/87]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [57/87]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [58/87]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [59/87]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [60/87]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [61/87]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [62/87]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [63/87]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [64/87]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [65/87] v6.8 prompt:fixup interruptible
+    - SAUCE: apparmor4.0.0 [69/87]: add io_uring mediation
+    - SAUCE: apparmor4.0.0 [70/87]: apparmor: fix oops when racing to retrieve
+      notification
+    - SAUCE: apparmor4.0.0 [71/87]: apparmor: fix notification header size
+    - SAUCE: apparmor4.0.0 [72/87]: apparmor: fix request field from a prompt
+      reply that denies all access
+    - SAUCE: apparmor4.0.0 [73/87]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+    - SAUCE: apparmor4.0.0 [74/87]: apparmor: cleanup attachment perm lookup to
+      use lookup_perms()
+    - SAUCE: apparmor4.0.0 [75/87]: apparmor: remove redundant unconfined check.
+    - SAUCE: apparmor4.0.0 [76/87]: apparmor: switch signal mediation to using
+      RULE_MEDIATES
+    - SAUCE: apparmor4.0.0 [77/87]: apparmor: ensure labels with more than one
+      entry have correct flags
+    - SAUCE: apparmor4.0.0 [78/87]: apparmor: remove explicit restriction that
+      unconfined cannot use change_hat
+    - SAUCE: apparmor4.0.0 [79/87]: apparmor: cleanup: refactor file_perm() to
+      provide semantics of some checks
+    - SAUCE: apparmor4.0.0 [80/87]: apparmor: carry mediation check on label
+    - SAUCE: apparmor4.0.0 [81/87]: apparmor: convert easy uses of unconfined() to
+      label_mediates()
+    - SAUCE: apparmor4.0.0 [82/87]: apparmor: add additional flags to extended
+      permission.
+    - SAUCE: apparmor4.0.0 [83/87]: apparmor: add support for profiles to define
+      the kill signal
+    - SAUCE: apparmor4.0.0 [84/87]: apparmor: fix x_table_lookup when stacking is
+      not the first entry
+    - SAUCE: apparmor4.0.0 [85/87]: apparmor: allow profile to be transitioned
+      when a user ns is created
+    - SAUCE: apparmor4.0.0 [86/87]: apparmor: add ability to mediate caps with
+      policy state machine
+    - SAUCE: apparmor4.0.0 [87/87]: fixup notify
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [66/87]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [67/87]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [68/87]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 08 Feb 2024 12:05:44 +0100
+
+linux (6.8.0-6.6) noble; urgency=medium
+
+  * noble/linux: 6.8.0-6.6 -proposed tracker (LP: #2052592)
+
+  * Packaging resync (LP: #1786013)
+    - debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.02.07)
+    - [Packaging] update variants
+
+  * FIPS kernels should default to fips mode (LP: #2049082)
+    - SAUCE: Enable fips mode by default, in FIPS kernels only
+
+  * Fix snapcraftyaml.yaml for jammy:linux-raspi (LP: #2051468)
+    - [Packaging] Remove old snapcraft.yaml
+
+  * Azure: Fix regression introduced in LP: #2045069 (LP: #2052453)
+    - hv_netvsc: Register VF in netvsc_probe if NET_DEVICE_REGISTER missed
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Remove in-tree abi checks
+    - [Packaging] drop abi files with clean
+    - [Packaging] Remove do_full_source variable (fixup)
+    - [Packaging] Remove update-dkms-versions and move dkms-versions
+    - [Config] updateconfigs following v6.8-rc3 rebase
+    - [packaging] rename to linux
+    - [packaging] rebase on v6.8-rc3
+    - [packaging] disable signing for ppc64el
+
+  * Rebase on v6.8-rc3
+ 
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 07 Feb 2024 15:13:52 +0100
+
+linux (6.8.0-5.5) noble; urgency=medium
+
+  * noble/linux-unstable: 6.8.0-5.5 -proposed tracker (LP: #2052136)
+
+  * Miscellaneous upstream changes
+    - Revert "mm/sparsemem: fix race in accessing memory_section->usage"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 02 Feb 2024 12:59:09 +0100
+
+linux-unstable (6.8.0-4.4) noble; urgency=medium
+
+  * noble/linux-unstable: 6.8.0-4.4 -proposed tracker (LP: #2051502)
+
+  * Migrate from fbdev drivers to simpledrm and DRM fbdev emulation layer
+    (LP: #1965303)
+    - [Config] enable simpledrm and DRM fbdev emulation layer
+
+  * Miscellaneous Ubuntu changes
+    - [Config] toolchain update
+
+  * Miscellaneous upstream changes
+    - rust: upgrade to Rust 1.75.0
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 29 Jan 2024 14:49:49 +0100
+
+linux-unstable (6.8.0-3.3) noble; urgency=medium
+
+  * noble/linux-unstable: 6.8.0-3.3 -proposed tracker (LP: #2051488)
+
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [43/87]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0
+      [12/95]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [44/87]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [45/87]: add unpriviled user ns mediation
+    - SAUCE: apparmor4.0.0 [46/87]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [47/87]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [48/87]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [49/87]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [50/87]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/87]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/87]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/87]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [54/87]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [55/87]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [56/87]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [57/87]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [58/87]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [59/87]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [60/87]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [61/87]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [62/87]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [63/87]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [64/87]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [69/87]: add io_uring mediation
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+
+  * apparmor restricts read access of user namespace mediation sysctls to root
+    (LP: #2040194)
+    - SAUCE: apparmor4.0.0 [73/87]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+
+  * AppArmor spams kernel log with assert when auditing (LP: #2040192)
+    - SAUCE: apparmor4.0.0 [72/87]: apparmor: fix request field from a prompt
+      reply that denies all access
+
+  * apparmor notification files verification (LP: #2040250)
+    - SAUCE: apparmor4.0.0 [71/87]: apparmor: fix notification header size
+
+  * apparmor oops when racing to retrieve a notification (LP: #2040245)
+    - SAUCE: apparmor4.0.0 [70/87]: apparmor: fix oops when racing to retrieve
+      notification
+
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [66/87]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [67/87]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [68/87]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor4.0.0 [01/87]: LSM stacking v39: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [02/87]: LSM stacking v39: SM: Infrastructure
+      management of the sock security
+    - SAUCE: apparmor4.0.0 [03/87]: LSM stacking v39: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [04/87]: LSM stacking v39: IMA: avoid label collisions
+      with stacked LSMs
+    - SAUCE: apparmor4.0.0 [05/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [06/87]: LSM stacking v39: LSM: Add lsmblob_to_secctx
+      hook
+    - SAUCE: apparmor4.0.0 [07/87]: LSM stacking v39: Audit: maintain an lsmblob
+      in audit_context
+    - SAUCE: apparmor4.0.0 [08/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [09/87]: LSM stacking v39: Audit: Update shutdown LSM
+      data
+    - SAUCE: apparmor4.0.0 [10/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [11/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [12/87]: LSM stacking v39: Audit: use an lsmblob in
+      audit_names
+    - SAUCE: apparmor4.0.0 [13/87]: LSM stacking v39: LSM: Create new
+      security_cred_getlsmblob LSM hook
+    - SAUCE: apparmor4.0.0 [14/87]: LSM stacking v39: Audit: Change context data
+      from secid to lsmblob
+    - SAUCE: apparmor4.0.0 [15/87]: LSM stacking v39: Netlabel: Use lsmblob for
+      audit data
+    - SAUCE: apparmor4.0.0 [16/87]: LSM stacking v39: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [17/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [18/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_lsmblob_to_secctx
+    - SAUCE: apparmor4.0.0 [19/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [20/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [21/87]: LSM stacking v39: LSM:
+      security_lsmblob_to_secctx module selection
+    - SAUCE: apparmor4.0.0 [22/87]: LSM stacking v39: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [23/87]: LSM stacking v39: Audit: Allow multiple
+      records in an audit_buffer
+    - SAUCE: apparmor4.0.0 [24/87]: LSM stacking v39: Audit: Add record for
+      multiple task security contexts
+    - SAUCE: apparmor4.0.0 [25/87]: LSM stacking v39: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [26/87]: LSM stacking v39: Audit: Add record for
+      multiple object contexts
+    - SAUCE: apparmor4.0.0 [27/87]: LSM stacking v39: LSM: Remove unused
+      lsmcontext_init()
+    - SAUCE: apparmor4.0.0 [28/87]: LSM stacking v39: LSM: Improve logic in
+      security_getprocattr
+    - SAUCE: apparmor4.0.0 [29/87]: LSM stacking v39: LSM: secctx provider check
+      on release
+    - SAUCE: apparmor4.0.0 [30/87]: LSM stacking v39: LSM: Single calls in
+      socket_getpeersec hooks
+    - SAUCE: apparmor4.0.0 [31/87]: LSM stacking v39: LSM: Exclusive secmark usage
+    - SAUCE: apparmor4.0.0 [32/87]: LSM stacking v39: LSM: Identify which LSM
+      handles the context string
+    - SAUCE: apparmor4.0.0 [33/87]: LSM stacking v39: AppArmor: Remove the
+      exclusive flag
+    - SAUCE: apparmor4.0.0 [34/87]: LSM stacking v39: LSM: Add mount opts blob
+      size tracking
+    - SAUCE: apparmor4.0.0 [35/87]: LSM stacking v39: LSM: allocate mnt_opts blobs
+      instead of module specific data
+    - SAUCE: apparmor4.0.0 [36/87]: LSM stacking v39: LSM: Infrastructure
+      management of the key security blob
+    - SAUCE: apparmor4.0.0 [37/87]: LSM stacking v39: LSM: Infrastructure
+      management of the mnt_opts security blob
+    - SAUCE: apparmor4.0.0 [38/87]: LSM stacking v39: LSM: Correct handling of
+      ENOSYS in inode_setxattr
+    - SAUCE: apparmor4.0.0 [39/87]: LSM stacking v39: LSM: Remove lsmblob
+      scaffolding
+    - SAUCE: apparmor4.0.0 [40/87]: LSM stacking v39: LSM: Allow reservation of
+      netlabel
+    - SAUCE: apparmor4.0.0 [41/87]: LSM stacking v39: LSM: restrict
+      security_cred_getsecid() to a single LSM
+    - SAUCE: apparmor4.0.0 [42/87]: LSM stacking v39: Smack: Remove
+      LSM_FLAG_EXCLUSIVE
+    - SAUCE: apparmor4.0.0 [65/87] v6.8 prompt:fixup interruptible
+    - SAUCE: apparmor4.0.0 [74/87]: apparmor: cleanup attachment perm lookup to
+      use lookup_perms()
+    - SAUCE: apparmor4.0.0 [75/87]: apparmor: remove redundant unconfined check.
+    - SAUCE: apparmor4.0.0 [76/87]: apparmor: switch signal mediation to using
+      RULE_MEDIATES
+    - SAUCE: apparmor4.0.0 [77/87]: apparmor: ensure labels with more than one
+      entry have correct flags
+    - SAUCE: apparmor4.0.0 [78/87]: apparmor: remove explicit restriction that
+      unconfined cannot use change_hat
+    - SAUCE: apparmor4.0.0 [79/87]: apparmor: cleanup: refactor file_perm() to
+      provide semantics of some checks
+    - SAUCE: apparmor4.0.0 [80/87]: apparmor: carry mediation check on label
+    - SAUCE: apparmor4.0.0 [81/87]: apparmor: convert easy uses of unconfined() to
+      label_mediates()
+    - SAUCE: apparmor4.0.0 [82/87]: apparmor: add additional flags to extended
+      permission.
+    - SAUCE: apparmor4.0.0 [83/87]: apparmor: add support for profiles to define
+      the kill signal
+    - SAUCE: apparmor4.0.0 [84/87]: apparmor: fix x_table_lookup when stacking is
+      not the first entry
+    - SAUCE: apparmor4.0.0 [85/87]: apparmor: allow profile to be transitioned
+      when a user ns is created
+    - SAUCE: apparmor4.0.0 [86/87]: apparmor: add ability to mediate caps with
+      policy state machine
+    - SAUCE: apparmor4.0.0 [87/87]: fixup notify
+    - [Config] updateconfigs following v6.8-rc2 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 29 Jan 2024 08:59:32 +0100
+
+linux-unstable (6.8.0-2.2) noble; urgency=medium
+
+  * noble/linux-unstable: 6.8.0-2.2 -proposed tracker (LP: #2051110)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] toolchain update
+    - [Config] enable Rust
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 24 Jan 2024 13:10:07 +0100
+
+linux-unstable (6.8.0-1.1) noble; urgency=medium
+
+  * noble/linux-unstable: 6.8.0-1.1 -proposed tracker (LP: #2051102)
+
+  * Miscellaneous Ubuntu changes
+    - [packaging] move to v6.8-rc1
+    - [Config] updateconfigs following v6.8-rc1 rebase
+    - SAUCE: export file_close_fd() instead of close_fd_get_file()
+    - SAUCE: cpufreq: s/strlcpy/strscpy/
+    - debian/dkms-versions -- temporarily disable zfs dkms
+    - debian/dkms-versions -- temporarily disable ipu6 and isvsc dkms
+    - debian/dkms-versions -- temporarily disable v4l2loopback
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 24 Jan 2024 10:48:37 +0100
+
+linux-unstable (6.8.0-0.0) noble; urgency=medium
+
+  * Empty entry.
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 23 Jan 2024 11:36:40 +0100
+
+linux-unstable (6.7.0-7.7) noble; urgency=medium
+
+  * noble/linux-unstable: 6.7.0-7.7 -proposed tracker (LP: #2049357)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] re-enable signing for s390x and ppc64el
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 15 Jan 2024 08:41:11 +0100
+
+linux-unstable (6.7.0-6.6) noble; urgency=medium
+
+  * Empty entry.
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 15 Jan 2024 08:30:50 +0100
+
+linux (6.7.0-2.2) noble; urgency=medium
+
+  * noble/linux: 6.7.0-2.2 -proposed tracker (LP: #2049182)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+
+  * Enforce RETPOLINE and SLS mitigrations (LP: #2046440)
+    - SAUCE: objtool: Make objtool check actually fatal upon fatal errors
+    - SAUCE: objtool: make objtool SLS validation fatal when building with
+      CONFIG_SLS=y
+    - SAUCE: objtool: make objtool RETPOLINE validation fatal when building with
+      CONFIG_RETPOLINE=y
+    - SAUCE: scripts: remove generating .o-ur objects
+    - [Packaging] Remove all custom retpoline-extract code
+    - Revert "UBUNTU: SAUCE: vga_set_mode -- avoid jump tables"
+    - Revert "UBUNTU: SAUCE: early/late -- annotate indirect calls in early/late
+      initialisation code"
+    - Revert "UBUNTU: SAUCE: apm -- annotate indirect calls within
+      firmware_restrict_branch_speculation_{start,end}"
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] temporarily disable riscv64 builds
+    - [Packaging] temporarily disable Rust dependencies on riscv64
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 12 Jan 2024 09:21:57 +0100
+
+linux (6.7.0-1.1) noble; urgency=medium
+
+  * noble/linux: 6.7.0-1.1 -proposed tracker (LP: #2048859)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - debian/dkms-versions -- update from kernel-versions (main/d2024.01.02)
+
+  * [UBUNTU 23.04] Regression: Ubuntu 23.04/23.10 do not include uvdevice
+    anymore (LP: #2048919)
+    - [Config] Enable S390_UV_UAPI (built-in)
+
+  * Support mipi camera on Intel Meteor Lake platform (LP: #2031412)
+    - SAUCE: iommu: intel-ipu: use IOMMU passthrough mode for Intel IPUs on Meteor
+      Lake
+    - SAUCE: platform/x86: int3472: Add handshake GPIO function
+
+  * [SRU][J/L/M] UBUNTU: [Packaging] Make WWAN driver a loadable module
+    (LP: #2033406)
+    - [Packaging] Make WWAN driver loadable modules
+
+  * usbip: error: failed to open /usr/share/hwdata//usb.ids (LP: #2039439)
+    - [Packaging] Make linux-tools-common depend on hwdata
+
+  * [Mediatek] mt8195-demo: enable CONFIG_MTK_IOMMU as module for multimedia and
+    PCIE peripherals (LP: #2036587)
+    - [Config] Enable CONFIG_MTK_IOMMU on arm64
+
+  * linux-*: please enable dm-verity kconfigs to allow MoK/db verified root
+    images (LP: #2019040)
+    - [Config] CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING=y
+
+  * kexec enable to load/kdump zstd compressed zimg (LP: #2037398)
+    - [Packaging] Revert arm64 image format to Image.gz
+
+  * Mantic minimized/minimal cloud images do not receive IP address during
+    provisioning; systemd regression with wait-online (LP: #2036968)
+    - [Config] Enable virtio-net as built-in to avoid race
+
+  * Make backlight module auto detect dell_uart_backlight (LP: #2008882)
+    - SAUCE: ACPI: video: Dell AIO UART backlight detection
+
+  * Linux 6.2 fails to reboot with current u-boot-nezha (LP: #2021364)
+    - [Config] Default to performance CPUFreq governor on riscv64
+
+  * Enable Nezha board (LP: #1975592)
+    - [Config] Build in D1 clock drivers on riscv64
+    - [Config] Enable CONFIG_SUN6I_RTC_CCU on riscv64
+    - [Config] Enable CONFIG_SUNXI_WATCHDOG on riscv64
+    - [Config] Disable SUN50I_DE2_BUS on riscv64
+    - [Config] Disable unneeded sunxi pinctrl drivers on riscv64
+
+  * Enable StarFive VisionFive 2 board (LP: #2013232)
+    - [Config] Enable CONFIG_PINCTRL_STARFIVE_JH7110_SYS on riscv64
+    - [Config] Enable CONFIG_STARFIVE_WATCHDOG on riscv64
+
+  * rcu_sched detected stalls on CPUs/tasks (LP: #1967130)
+    - [Config] Enable virtually mapped stacks on riscv64
+
+  * Check for changes relevant for security certifications (LP: #1945989)
+    - [Packaging] Add a new fips-checks script
+
+  * Installation support for SMARC RZ/G2L platform (LP: #2030525)
+    - [Config] build Renesas RZ/G2L USBPHY control driver statically
+
+  * Add support for kernels compiled with CONFIG_EFI_ZBOOT (LP: #2002226)
+    - [Config]: Turn on CONFIG_EFI_ZBOOT on ARM64
+
+  * Default module signing algo should be accelerated (LP: #2034061)
+    - [Config] Default module signing algo should be accelerated
+
+  * Miscellaneous Ubuntu changes
+    - [Config] annotations clean-up
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 11 Jan 2024 11:49:07 +0100
+
+linux (6.7.0-0.0) noble; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 09 Jan 2024 09:27:23 +0100
+
+linux-unstable (6.7.0-5.5) noble; urgency=medium
+
+  * noble/linux-unstable: 6.7.0-5.5 -proposed tracker (LP: #2048118)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/d2024.01.02)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] re-enable Rust support
+    - [Packaging] temporarily disable riscv64 builds
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 05 Jan 2024 12:33:10 +0100
+
+linux-unstable (6.7.0-4.4) noble; urgency=medium
+
+  * noble/linux-unstable: 6.7.0-4.4 -proposed tracker (LP: #2047807)
+
+  * unconfined profile denies userns_create for chromium based processes
+    (LP: #1990064)
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+
+  * apparmor restricts read access of user namespace mediation sysctls to root
+    (LP: #2040194)
+    - SAUCE: apparmor4.0.0 [69/69]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+
+  * AppArmor spams kernel log with assert when auditing (LP: #2040192)
+    - SAUCE: apparmor4.0.0 [68/69]: apparmor: fix request field from a prompt
+      reply that denies all access
+
+  * apparmor notification files verification (LP: #2040250)
+    - SAUCE: apparmor4.0.0 [67/69]: apparmor: fix notification header size
+
+  * apparmor oops when racing to retrieve a notification (LP: #2040245)
+    - SAUCE: apparmor4.0.0 [66/69]: apparmor: fix oops when racing to retrieve
+      notification
+
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [01/69]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [02/69]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [03/69]: add unpriviled user ns mediation
+    - SAUCE: apparmor4.0.0 [04/69]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [05/69]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [06/69]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [07/69]: Stacking v38: LSM: Identify modules by more
+      than name
+    - SAUCE: apparmor4.0.0 [08/69]: Stacking v38: LSM: Add an LSM identifier for
+      external use
+    - SAUCE: apparmor4.0.0 [09/69]: Stacking v38: LSM: Identify the process
+      attributes for each module
+    - SAUCE: apparmor4.0.0 [10/69]: Stacking v38: LSM: Maintain a table of LSM
+      attribute data
+    - SAUCE: apparmor4.0.0 [11/69]: Stacking v38: proc: Use lsmids instead of lsm
+      names for attrs
+    - SAUCE: apparmor4.0.0 [12/69]: Stacking v38: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [13/69]: Stacking v38: LSM: Infrastructure management
+      of the sock security
+    - SAUCE: apparmor4.0.0 [14/69]: Stacking v38: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [15/69]: Stacking v38: LSM: provide lsm name and id
+      slot mappings
+    - SAUCE: apparmor4.0.0 [16/69]: Stacking v38: IMA: avoid label collisions with
+      stacked LSMs
+    - SAUCE: apparmor4.0.0 [17/69]: Stacking v38: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [18/69]: Stacking v38: LSM: Use lsmblob in
+      security_kernel_act_as
+    - SAUCE: apparmor4.0.0 [19/69]: Stacking v38: LSM: Use lsmblob in
+      security_secctx_to_secid
+    - SAUCE: apparmor4.0.0 [20/69]: Stacking v38: LSM: Use lsmblob in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [21/69]: Stacking v38: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [22/69]: Stacking v38: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [23/69]: Stacking v38: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [24/69]: Stacking v38: LSM: Use lsmblob in
+      security_cred_getsecid
+    - SAUCE: apparmor4.0.0 [25/69]: Stacking v38: LSM: Specify which LSM to
+      display
+    - SAUCE: apparmor4.0.0 [27/69]: Stacking v38: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [28/69]: Stacking v38: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [29/69]: Stacking v38: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [30/69]: Stacking v38: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [31/69]: Stacking v38: LSM: security_secid_to_secctx in
+      netlink netfilter
+    - SAUCE: apparmor4.0.0 [32/69]: Stacking v38: NET: Store LSM netlabel data in
+      a lsmblob
+    - SAUCE: apparmor4.0.0 [33/69]: Stacking v38: binder: Pass LSM identifier for
+      confirmation
+    - SAUCE: apparmor4.0.0 [34/69]: Stacking v38: LSM: security_secid_to_secctx
+      module selection
+    - SAUCE: apparmor4.0.0 [35/69]: Stacking v38: Audit: Keep multiple LSM data in
+      audit_names
+    - SAUCE: apparmor4.0.0 [36/69]: Stacking v38: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [37/69]: Stacking v38: LSM: Add a function to report
+      multiple LSMs
+    - SAUCE: apparmor4.0.0 [38/69]: Stacking v38: Audit: Allow multiple records in
+      an audit_buffer
+    - SAUCE: apparmor4.0.0 [39/69]: Stacking v38: Audit: Add record for multiple
+      task security contexts
+    - SAUCE: apparmor4.0.0 [40/69]: Stacking v38: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [41/69]: Stacking v38: Audit: Add record for multiple
+      object contexts
+    - SAUCE: apparmor4.0.0 [42/69]: Stacking v38: netlabel: Use a struct lsmblob
+      in audit data
+    - SAUCE: apparmor4.0.0 [43/69]: Stacking v38: LSM: Removed scaffolding
+      function lsmcontext_init
+    - SAUCE: apparmor4.0.0 [44/69]: Stacking v38: AppArmor: Remove the exclusive
+      flag
+    - SAUCE: apparmor4.0.0 [45/69]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [46/69]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [47/69]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [48/69]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [49/69]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [50/69]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [51/69]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [52/69]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [53/69]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [54/69]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [55/69]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [56/69]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [57/69]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [58/69]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [59/69]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [60/69]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [64/69]: advertise disconnected.path is available
+    - SAUCE: apparmor4.0.0 [65/69]: add io_uring mediation
+
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [61/69]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [62/69]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [63/69]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+
+  * udev fails to make prctl() syscall with apparmor=0 (as used by maas by
+    default) (LP: #2016908) // update apparmor and LSM stacking patch set
+    (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [26/69]: Stacking v38: Fix prctl() syscall with
+      apparmor=0
+
+  * Fix RPL-U CPU C-state always keep at C3 when system run PHM with idle screen
+    on (LP: #2042385)
+    - SAUCE: r8169: Add quirks to enable ASPM on Dell platforms
+
+  * [Debian] autoreconstruct - Do not generate chmod -x for deleted  files
+    (LP: #2045562)
+    - [Debian] autoreconstruct - Do not generate chmod -x for deleted files
+
+  * Disable Legacy TIOCSTI (LP: #2046192)
+    - [Config]: disable CONFIG_LEGACY_TIOCSTI
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - [Packaging] remove helper scripts
+    - [Packaging] update annotations scripts
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] rules: Remove unused dkms make variables
+    - [Config] update annotations after rebase to v6.7-rc8
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.7-rc8
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 02 Jan 2024 14:57:21 +0100
+
+linux-unstable (6.7.0-3.3) noble; urgency=medium
+
+  * noble/linux-unstable: 6.7.0-3.3 -proposed tracker (LP: #2046060)
+
+  * enable CONFIG_INTEL_TDX_HOST in linux >= 6.7 for noble (LP: #2046040)
+    - [Config] enable CONFIG_INTEL_TDX_HOST
+
+  * linux tools packages for derived kernels refuse to install simultaneously
+    due to libcpupower name collision (LP: #2035971)
+    - [Packaging] Statically link libcpupower into cpupower tool
+
+  * make lazy RCU a boot time option (LP: #2045492)
+    - SAUCE: rcu: Provide a boot time parameter to control lazy RCU
+
+  * Build failure if run in a console (LP: #2044512)
+    - [Packaging] Fix kernel module compression failures
+
+  * Turning COMPAT_32BIT_TIME off on arm64 (64k & derivatives) (LP: #2038582)
+    - [Config] y2038: Turn off COMPAT and COMPAT_32BIT_TIME on arm64 64k
+
+  * Turning COMPAT_32BIT_TIME off on riscv64 (LP: #2038584)
+    - [Config] y2038: Disable COMPAT_32BIT_TIME on riscv64
+
+  * Turning COMPAT_32BIT_TIME off on ppc64el (LP: #2038587)
+    - [Config] y2038: Disable COMPAT and COMPAT_32BIT_TIME on ppc64le
+
+  * [UBUNTU 23.04] Kernel config option missing for s390x PCI passthrough
+    (LP: #2042853)
+    - [Config] CONFIG_VFIO_PCI_ZDEV_KVM=y
+
+  * back-out zstd module compression automatic for backports (LP: #2045593)
+    - [Packaging] make ZSTD module compression conditional
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Remove do_full_source variable
+    - [Packaging] Remove obsolete config handling
+    - [Packaging] Remove support for sub-flavors
+    - [Packaging] Remove old linux-libc-dev version hack
+    - [Packaging] Remove obsolete scripts
+    - [Packaging] Remove README.inclusion-list
+    - [Packaging] make $(stampdir)/stamp-build-perarch depend on build-arch
+    - [Packaging] Enable rootless builds
+    - [Packaging] Allow to run debian/rules without (fake)root
+    - [Packaging] remove unneeded trailing slash for INSTALL_MOD_PATH
+    - [Packaging] override KERNELRELEASE instead of KERNELVERSION
+    - [Config] update toolchain versions in annotations
+    - [Packaging] drop useless linux-doc
+    - [Packaging] scripts: Rewrite insert-ubuntu-changes in Python
+    - [Packaging] enable riscv64 builds
+    - [Packaging] remove the last sub-flavours bit
+    - [Packaging] check debian.env to determine do_libc_dev_package
+    - [Packaging] remove debian.*/variants
+    - [Packaging] remove do_libc_dev_package variable
+    - [Packaging] move linux-libc-dev.stub to debian/control.d/
+    - [Packaging] Update check to build linux-libc-dev to the source package name
+    - [Packaging] rules: Remove startnewrelease target
+    - [Packaging] Remove debian/commit-templates
+    - [Config] update annotations after rebase to v6.7-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.7-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 11 Dec 2023 15:56:11 +0100
+
+linux-unstable (6.7.0-2.2) noble; urgency=medium
+
+  * noble/linux-unstable: 6.7.0-2.2 -proposed tracker (LP: #2045107)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] re-enable Rust
+    - [Config] enable Rust in annotations
+    - [Packaging] Remove do_enforce_all variable
+    - [Config] disable Softlogic 6x10 capture card driver on armhf
+    - [Packaging] disable Rust support
+    - [Config] update annotations after rebase to v6.7-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.7-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 29 Nov 2023 07:51:17 +0100
+
+linux-unstable (6.7.0-1.1) noble; urgency=medium
+
+  * noble/linux-unstable: 6.7.0-1.1 -proposed tracker (LP: #2044069)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update annotations scripts
+    - [Packaging] update helper scripts
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations after rebase to v6.7-rc2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.7-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 21 Nov 2023 10:45:24 +0100
+
+linux-unstable (6.7.0-0.0) noble; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 21 Nov 2023 07:26:46 +0100
+
+linux-unstable (6.6.0-12.12) noble; urgency=medium
+
+  * noble/linux-unstable: 6.6.0-12.12 -proposed tracker (LP: #2043664)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] temporarily disable zfs dkms
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 16 Nov 2023 10:20:26 +0100
+
+linux-unstable (6.6.0-11.11) noble; urgency=medium
+
+  * noble/linux-unstable: 6.6.0-11.11 -proposed tracker (LP: #2043480)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+    - [Packaging] resync update-dkms-versions helper
+    - [Packaging] update variants
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.11.14)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move to Noble
+    - [Config] toolchain version update
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 15 Nov 2023 14:50:40 +0100
+
+linux-unstable (6.6.0-10.10) noble; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-10.10 -proposed tracker (LP: #2043088)
+
+  * Bump arm64's CONFIG_NR_CPUS to 512 (LP: #2042897)
+    - [Config] Bump CONFIG_NR_CPUS to 512 for arm64
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Include a note for the NR_CPUS setting on riscv64
+    - SAUCE: apparmor4.0.0 [83/83]: Fix inode_init for changed prototype
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 09 Nov 2023 12:05:11 +0200
+
+linux-unstable (6.6.0-9.9) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-9.9 -proposed tracker (LP: #2041852)
+
+  * Switch IMA default hash to sha256 (LP: #2041735)
+    - [Config] Switch IMA_DEFAULT_HASH from sha1 to sha256
+
+  * apparmor restricts read access of user namespace mediation sysctls to root
+    (LP: #2040194)
+    - SAUCE: apparmor4.0.0 [82/82]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+
+  * AppArmor spams kernel log with assert when auditing (LP: #2040192)
+    - SAUCE: apparmor4.0.0 [81/82]: apparmor: fix request field from a prompt
+      reply that denies all access
+
+  * apparmor notification files verification (LP: #2040250)
+    - SAUCE: apparmor4.0.0 [80/82]: apparmor: fix notification header size
+
+  * apparmor oops when racing to retrieve a notification (LP: #2040245)
+    - SAUCE: apparmor4.0.0 [79/82]: apparmor: fix oops when racing to retrieve
+      notification
+
+  * Disable restricting unprivileged change_profile by default, due to LXD
+    latest/stable not yet compatible with this new apparmor feature
+    (LP: #2038567)
+    - SAUCE: apparmor4.0.0 [78/82]: apparmor: Make
+      apparmor_restrict_unprivileged_unconfined opt-in
+
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [01/82]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [02/82]: rename SK_CTX() to aa_sock and make it an
+      inline fn
+    - SAUCE: apparmor4.0.0 [03/82]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [04/82]: add user namespace creation mediation
+    - SAUCE: apparmor4.0.0 [05/82]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [06/82]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [07/82]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [08/82]: Stacking v38: LSM: Identify modules by more
+      than name
+    - SAUCE: apparmor4.0.0 [09/82]: Stacking v38: LSM: Add an LSM identifier for
+      external use
+    - SAUCE: apparmor4.0.0 [10/82]: Stacking v38: LSM: Identify the process
+      attributes for each module
+    - SAUCE: apparmor4.0.0 [11/82]: Stacking v38: LSM: Maintain a table of LSM
+      attribute data
+    - SAUCE: apparmor4.0.0 [12/82]: Stacking v38: proc: Use lsmids instead of lsm
+      names for attrs
+    - SAUCE: apparmor4.0.0 [13/82]: Stacking v38: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [14/82]: Stacking v38: LSM: Infrastructure management
+      of the sock security
+    - SAUCE: apparmor4.0.0 [15/82]: Stacking v38: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [16/82]: Stacking v38: LSM: provide lsm name and id
+      slot mappings
+    - SAUCE: apparmor4.0.0 [17/82]: Stacking v38: IMA: avoid label collisions with
+      stacked LSMs
+    - SAUCE: apparmor4.0.0 [18/82]: Stacking v38: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [19/82]: Stacking v38: LSM: Use lsmblob in
+      security_kernel_act_as
+    - SAUCE: apparmor4.0.0 [20/82]: Stacking v38: LSM: Use lsmblob in
+      security_secctx_to_secid
+    - SAUCE: apparmor4.0.0 [21/82]: Stacking v38: LSM: Use lsmblob in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [22/82]: Stacking v38: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [23/82]: Stacking v38: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [24/82]: Stacking v38: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [25/82]: Stacking v38: LSM: Use lsmblob in
+      security_cred_getsecid
+    - SAUCE: apparmor4.0.0 [26/82]: Stacking v38: LSM: Specify which LSM to
+      display
+    - SAUCE: apparmor4.0.0 [28/82]: Stacking v38: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [29/82]: Stacking v38: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [30/82]: Stacking v38: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [31/82]: Stacking v38: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [32/82]: Stacking v38: LSM: security_secid_to_secctx in
+      netlink netfilter
+    - SAUCE: apparmor4.0.0 [33/82]: Stacking v38: NET: Store LSM netlabel data in
+      a lsmblob
+    - SAUCE: apparmor4.0.0 [34/82]: Stacking v38: binder: Pass LSM identifier for
+      confirmation
+    - SAUCE: apparmor4.0.0 [35/82]: Stacking v38: LSM: security_secid_to_secctx
+      module selection
+    - SAUCE: apparmor4.0.0 [36/82]: Stacking v38: Audit: Keep multiple LSM data in
+      audit_names
+    - SAUCE: apparmor4.0.0 [37/82]: Stacking v38: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [38/82]: Stacking v38: LSM: Add a function to report
+      multiple LSMs
+    - SAUCE: apparmor4.0.0 [39/82]: Stacking v38: Audit: Allow multiple records in
+      an audit_buffer
+    - SAUCE: apparmor4.0.0 [40/82]: Stacking v38: Audit: Add record for multiple
+      task security contexts
+    - SAUCE: apparmor4.0.0 [41/82]: Stacking v38: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [42/82]: Stacking v38: Audit: Add record for multiple
+      object contexts
+    - SAUCE: apparmor4.0.0 [43/82]: Stacking v38: netlabel: Use a struct lsmblob
+      in audit data
+    - SAUCE: apparmor4.0.0 [44/82]: Stacking v38: LSM: Removed scaffolding
+      function lsmcontext_init
+    - SAUCE: apparmor4.0.0 [45/82]: Stacking v38: AppArmor: Remove the exclusive
+      flag
+    - SAUCE: apparmor4.0.0 [46/82]: combine common_audit_data and
+      apparmor_audit_data
+    - SAUCE: apparmor4.0.0 [47/82]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [48/82]: rename audit_data->label to
+      audit_data->subj_label
+    - SAUCE: apparmor4.0.0 [49/82]: pass cred through to audit info.
+    - SAUCE: apparmor4.0.0 [50/82]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/82]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/82]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/82]: cache buffers on percpu list if there is lock
+      contention
+    - SAUCE: apparmor4.0.0 [54/82]: advertise availability of exended perms
+    - SAUCE: apparmor4.0.0 [56/82]: cleanup: provide separate audit messages for
+      file and policy checks
+    - SAUCE: apparmor4.0.0 [57/82]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [58/82]: prompt - ref count pdb
+    - SAUCE: apparmor4.0.0 [59/82]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [60/82]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [61/82]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [62/82]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [63/82]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [64/82]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [65/82]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [66/82]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [67/82]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [68/82]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [69/82]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [74/82]: advertise disconnected.path is available
+    - SAUCE: apparmor4.0.0 [75/82]: fix invalid reference on profile->disconnected
+    - SAUCE: apparmor4.0.0 [76/82]: add io_uring mediation
+    - SAUCE: apparmor4.0.0 [77/82]: apparmor: Fix regression in mount mediation
+
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [70/82]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [71/82]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [72/82]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+    - SAUCE: apparmor4.0.0 [73/82]: userns - allow restricting unprivileged
+      change_profile
+
+  * LSM stacking and AppArmor for 6.2: additional fixes (LP: #2017903) // update
+    apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [55/82]: fix profile verification and enable it
+
+  * udev fails to make prctl() syscall with apparmor=0 (as used by maas by
+    default) (LP: #2016908) // update apparmor and LSM stacking patch set
+    (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [27/82]: Stacking v38: Fix prctl() syscall with
+      apparmor=0
+
+  * Miscellaneous Ubuntu changes
+    - [Config] SECURITY_APPARMOR_RESTRICT_USERNS=y
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 03 Nov 2023 11:59:12 +0100
+
+linux-unstable (6.6.0-8.8) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-8.8 -proposed tracker (LP: #2040243)
+
+  * Miscellaneous Ubuntu changes
+    - abi: gc reference to phy-rtk-usb2/phy-rtk-usb3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 24 Oct 2023 10:55:34 +0200
+
+linux-unstable (6.6.0-7.7) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-7.7 -proposed tracker (LP: #2040147)
+
+  * test_021_aslr_dapper_libs from ubuntu_qrt_kernel_security failed on K-5.19 /
+    J-OEM-6.1 / J-6.2 AMD64 (LP: #1983357)
+    - [Config]: set ARCH_MMAP_RND_{COMPAT_, }BITS to the maximum
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs following v6.6-rc7 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 23 Oct 2023 11:51:14 +0200
+
+linux-unstable (6.6.0-6.6) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-6.6 -proposed tracker (LP: #2039780)
+
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.6-rc6
+    - [Config] updateconfigs following v6.6-rc6 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.6-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 19 Oct 2023 12:09:16 +0200
+
+linux-unstable (6.6.0-5.5) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-5.5 -proposed tracker (LP: #2038899)
+
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.6-rc5
+    - [Config] updateconfigs following v6.6-rc5 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.6-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 10 Oct 2023 11:18:41 +0200
+
+linux-unstable (6.6.0-4.4) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-4.4 -proposed tracker (LP: #2038423)
+
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.6-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.6-rc4
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 04 Oct 2023 11:16:25 +0200
+
+linux-unstable (6.6.0-3.3) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-3.3 -proposed tracker (LP: #2037622)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs following v6.6-rc3 rebase
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: enforce rust availability only on x86_64"
+    - arm64: rust: Enable Rust support for AArch64
+    - arm64: rust: Enable PAC support for Rust.
+    - arm64: Restrict Rust support to little endian only.
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 28 Sep 2023 10:45:38 +0200
+
+linux-unstable (6.6.0-2.2) mantic; urgency=medium
+
+  * Miscellaneous upstream changes
+    - UBUBNTU: [Config] build all COMEDI drivers as modules
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 18 Sep 2023 14:42:56 +0200
+
+linux-unstable (6.6.0-1.1) mantic; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move linux to linux-unstable
+    - [Packaging] rebase on v6.6-rc1
+    - [Config] updateconfigs following v6.6-rc1 rebase
+    - [packaging] skip ABI, modules and retpoline checks
+    - update dropped.txt
+    - [Config] SHIFT_FS FTBFS with Linux 6.6, disable it
+    - [Config] DELL_UART_BACKLIGHT FTBFS with Linux 6.6, disable it
+    - [Packaging] debian/dkms-versions: temporarily disable dkms
+    - [Packaging] temporarily disable signing for s390x
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.6-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 15 Sep 2023 14:42:18 +0200
+
+linux-unstable (6.6.0-0.0) mantic; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 14 Sep 2023 15:03:19 +0200
+
+linux (6.5.0-5.5) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-5.5 -proposed tracker (LP: #2034546)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.08.23)
+
+
+linux (6.5.0-4.4) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-4.4 -proposed tracker (LP: #2034042)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.08.23)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 04 Sep 2023 16:55:44 +0200
+
+linux (6.5.0-3.3) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-3.3 -proposed tracker (LP: #2033904)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.08.23)
+
+  * [23.10] Please test secure-boot and lockdown on the early 6.5 kernel (s390x)
+    (LP: #2026833)
+    - [Packaging] re-enable signing for s390x
+
+  * Miscellaneous upstream changes
+    - module/decompress: use vmalloc() for zstd decompression workspace
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 01 Sep 2023 16:15:33 +0200
+
+linux (6.5.0-2.2) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-2.2 -proposed tracker (LP: #2033240)
+
+  * Soundwire support for Dell SKU0C87 devices (LP: #2029281)
+    - SAUCE: ASoC: Intel: soc-acpi: add support for Dell SKU0C87 devices
+
+  * Fix numerous AER related issues (LP: #2033025)
+    - SAUCE: PCI/AER: Disable AER service during suspend, again
+    - SAUCE: PCI/DPC: Disable DPC service during suspend, again
+
+  * Support Realtek RTL8852CE WiFi 6E/BT Combo (LP: #2025672)
+    - wifi: rtw89: debug: Fix error handling in rtw89_debug_priv_btc_manual_set()
+    - Bluetooth: btrtl: Load FW v2 otherwise FW v1 for RTL8852C
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Aug 2023 08:53:19 +0200
+
+linux (6.5.0-1.1) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-1.1 -proposed tracker (LP: #2032750)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync update-dkms-versions helper
+    - [Packaging] update variants
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.07.26)
+
+  * ceph: support idmapped mounts (LP: #2032959)
+    - SAUCE: libceph: add spinlock around osd->o_requests
+    - SAUCE: libceph: define struct ceph_sparse_extent and add some helpers
+    - SAUCE: libceph: new sparse_read op, support sparse reads on msgr2 crc
+      codepath
+    - SAUCE: libceph: support sparse reads on msgr2 secure codepath
+    - SAUCE: libceph: add sparse read support to msgr1
+    - SAUCE: libceph: add sparse read support to OSD client
+    - SAUCE: ceph: add new mount option to enable sparse reads
+    - SAUCE: ceph: preallocate inode for ops that may create one
+    - SAUCE: ceph: make ceph_msdc_build_path use ref-walk
+    - SAUCE: libceph: add new iov_iter-based ceph_msg_data_type and
+      ceph_osd_data_type
+    - SAUCE: ceph: use osd_req_op_extent_osd_iter for netfs reads
+    - SAUCE: ceph: fscrypt_auth handling for ceph
+    - SAUCE: ceph: implement -o test_dummy_encryption mount option
+    - SAUCE: ceph: add fscrypt ioctls and ceph.fscrypt.auth vxattr
+    - SAUCE: ceph: make ioctl cmds more readable in debug log
+    - SAUCE: ceph: add base64 endcoding routines for encrypted names
+    - SAUCE: ceph: encode encrypted name in ceph_mdsc_build_path and dentry
+      release
+    - SAUCE: ceph: send alternate_name in MClientRequest
+    - SAUCE: ceph: decode alternate_name in lease info
+    - SAUCE: ceph: set DCACHE_NOKEY_NAME flag in ceph_lookup/atomic_open()
+    - SAUCE: ceph: make d_revalidate call fscrypt revalidator for encrypted
+      dentries
+    - SAUCE: ceph: add helpers for converting names for userland presentation
+    - SAUCE: ceph: make ceph_fill_trace and ceph_get_name decrypt names
+    - SAUCE: ceph: pass the request to parse_reply_info_readdir()
+    - SAUCE: ceph: add support to readdir for encrypted names
+    - SAUCE: ceph: create symlinks with encrypted and base64-encoded targets
+    - SAUCE: ceph: add some fscrypt guardrails
+    - SAUCE: ceph: allow encrypting a directory while not having Ax caps
+    - SAUCE: ceph: mark directory as non-complete after loading key
+    - SAUCE: ceph: size handling in MClientRequest, cap updates and inode traces
+    - SAUCE: ceph: handle fscrypt fields in cap messages from MDS
+    - SAUCE: ceph: add infrastructure for file encryption and decryption
+    - SAUCE: libceph: add CEPH_OSD_OP_ASSERT_VER support
+    - SAUCE: libceph: allow ceph_osdc_new_request to accept a multi-op read
+    - SAUCE: ceph: add object version support for sync read
+    - SAUCE: ceph: add truncate size handling support for fscrypt
+    - SAUCE: ceph: don't use special DIO path for encrypted inodes
+    - SAUCE: ceph: align data in pages in ceph_sync_write
+    - SAUCE: ceph: add read/modify/write to ceph_sync_write
+    - SAUCE: ceph: add encryption support to writepage and writepages
+    - SAUCE: ceph: plumb in decryption during reads
+    - SAUCE: ceph: invalidate pages when doing direct/sync writes
+    - SAUCE: ceph: add support for encrypted snapshot names
+    - SAUCE: ceph: prevent snapshot creation in encrypted locked directories
+    - SAUCE: ceph: update documentation regarding snapshot naming limitations
+    - SAUCE: ceph: drop messages from MDS when unmounting
+    - SAUCE: ceph: wait for OSD requests' callbacks to finish when unmounting
+    - SAUCE: ceph: fix updating i_truncate_pagecache_size for fscrypt
+    - SAUCE: ceph: switch ceph_lookup/atomic_open() to use new fscrypt helper
+    - SAUCE: libceph: do not include crypto/algapi.h
+    - SAUCE: rbd: bump RBD_MAX_PARENT_CHAIN_LEN to 128
+    - SAUCE: ceph: dump info about cap flushes when we're waiting too long for
+      them
+    - SAUCE: mm: BUG if filemap_alloc_folio gives us a folio with a non-NULL
+      ->private
+    - SAUCE: ceph: make sure all the files successfully put before unmounting
+    - SAUCE: ceph: BUG if MDS changed truncate_seq with client caps still
+      outstanding
+    - SAUCE: ceph: add the *_client debug macros support
+    - SAUCE: ceph: pass the mdsc to several helpers
+    - SAUCE: ceph: rename _to_client() to _to_fs_client()
+    - SAUCE: ceph: move mdsmap.h to fs/ceph/
+    - SAUCE: ceph: add ceph_inode_to_client() helper support
+    - SAUCE: ceph: print the client global_id in all the debug logs
+    - SAUCE: ceph: make the members in struct ceph_mds_request_args_ext an union
+    - SAUCE: ceph: make num_fwd and num_retry to __u32
+    - SAUCE: fs: export mnt_idmap_get/mnt_idmap_put
+    - SAUCE: ceph: stash idmapping in mdsc request
+    - SAUCE: ceph: handle idmapped mounts in create_request_message()
+    - SAUCE: ceph: add enable_unsafe_idmap module parameter
+    - SAUCE: ceph: pass an idmapping to mknod/symlink/mkdir
+    - SAUCE: ceph: allow idmapped getattr inode op
+    - SAUCE: ceph: allow idmapped permission inode op
+    - SAUCE: ceph: pass idmap to __ceph_setattr
+    - SAUCE: ceph: allow idmapped setattr inode op
+    - SAUCE: ceph/acl: allow idmapped set_acl inode op
+    - SAUCE: ceph/file: allow idmapped atomic_open inode op
+    - SAUCE: ceph: allow idmapped mounts
+
+  * Got soft lockup CPU if dell_uart_backlight is probed (LP: #2032174)
+    - SAUCE: platform/x86: dell-uart-backlight: replace chars_in_buffer() with
+      flush_chars()
+
+  * Fix ACPI TAD  on some Intel based systems (LP: #2032767)
+    - ACPI: TAD: Install SystemCMOS address space handler for ACPI000E
+
+  * Fix unreliable ethernet cable detection on I219 NIC (LP: #2028122)
+    - e1000e: Use PME poll to circumvent unreliable ACPI wake
+
+  * Fix panel brightness issues on HP laptops (LP: #2032704)
+    - ACPI: video: Put ACPI video and its child devices into D0 on boot
+
+  * FATAL:credentials.cc(127)] Check failed: . : Permission denied (13)
+    (LP: #2017980)
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+
+  * Support initrdless boot on default qemu virt models and openstack
+    (LP: #2030745)
+    - [Config] set VIRTIO_BLK=y for default qemu/openstack boot
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] rust: use Rust 1.68.2
+    - [Packaging] depend on clang/libclang-15 for Rust
+    - [Config] update toolchain versions in annotations
+    - [Config] update annotations after rebase to v6.5-rc6
+    - [Config] update toolchain version in annotations
+    - [Packaging] temporarily disable Rust support
+    - [Packaging] temporarily disable signing for ppc64el
+    - [Packaging] temporarily disable signing for s390x
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 24 Aug 2023 17:47:10 +0200
+
+linux (6.5.0-0.0) mantic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 23 Aug 2023 08:14:48 +0200
+
+linux-unstable (6.5.0-4.4) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.5.0-4.4 -proposed tracker (LP: #2029086)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Add .NOTPARALLEL
+    - [Packaging] Remove meaningless $(header_arch)
+    - [Packaging] Fix File exists error in install-arch-headers
+    - [Packaging] clean debian/linux-* directories
+    - [Packaging] remove hmake
+    - [Packaging] install headers to debian/linux-libc-dev directly
+    - [Config] define CONFIG options for arm64 instead of arm64-generic
+    - [Config] update annotations after rebase to v6.5-rc4
+    - [Packaging] temporarily disable Rust support
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 31 Jul 2023 08:41:59 +0200
+
+linux-unstable (6.5.0-3.3) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.5.0-3.3 -proposed tracker (LP: #2028779)
+
+  * enable Rust support in the kernel (LP: #2007654)
+    - SAUCE: rust: support rustc-1.69.0
+    - [Packaging] depend on rustc-1.69.0
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync update-dkms-versions helper
+    - [Packaging] resync getabis
+
+  * Fix UBSAN in Intel EDAC driver (LP: #2028746)
+    - EDAC/i10nm: Skip the absent memory controllers
+
+  * Ship kernel modules Zstd compressed (LP: #2028568)
+    - SAUCE: Support but do not require compressed modules
+    - [Config] Enable support for ZSTD compressed modules
+    - [Packaging] ZSTD compress modules
+
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor3.2.0 [02/60]: rename SK_CTX() to aa_sock and make it an
+      inline fn
+    - SAUCE: apparmor3.2.0 [05/60]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor3.2.0 [08/60]: Stacking v38: LSM: Identify modules by more
+      than name
+    - SAUCE: apparmor3.2.0 [09/60]: Stacking v38: LSM: Add an LSM identifier for
+      external use
+    - SAUCE: apparmor3.2.0 [10/60]: Stacking v38: LSM: Identify the process
+      attributes for each module
+    - SAUCE: apparmor3.2.0 [11/60]: Stacking v38: LSM: Maintain a table of LSM
+      attribute data
+    - SAUCE: apparmor3.2.0 [12/60]: Stacking v38: proc: Use lsmids instead of lsm
+      names for attrs
+    - SAUCE: apparmor3.2.0 [13/60]: Stacking v38: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor3.2.0 [14/60]: Stacking v38: LSM: Infrastructure management
+      of the sock security
+    - SAUCE: apparmor3.2.0 [15/60]: Stacking v38: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor3.2.0 [16/60]: Stacking v38: LSM: provide lsm name and id
+      slot mappings
+    - SAUCE: apparmor3.2.0 [17/60]: Stacking v38: IMA: avoid label collisions with
+      stacked LSMs
+    - SAUCE: apparmor3.2.0 [18/60]: Stacking v38: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor3.2.0 [19/60]: Stacking v38: LSM: Use lsmblob in
+      security_kernel_act_as
+    - SAUCE: apparmor3.2.0 [20/60]: Stacking v38: LSM: Use lsmblob in
+      security_secctx_to_secid
+    - SAUCE: apparmor3.2.0 [21/60]: Stacking v38: LSM: Use lsmblob in
+      security_secid_to_secctx
+    - SAUCE: apparmor3.2.0 [22/60]: Stacking v38: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor3.2.0 [23/60]: Stacking v38: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor3.2.0 [24/60]: Stacking v38: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor3.2.0 [25/60]: Stacking v38: LSM: Use lsmblob in
+      security_cred_getsecid
+    - SAUCE: apparmor3.2.0 [26/60]: Stacking v38: LSM: Specify which LSM to
+      display
+    - SAUCE: apparmor3.2.0 [28/60]: Stacking v38: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor3.2.0 [29/60]: Stacking v38: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor3.2.0 [30/60]: Stacking v38: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor3.2.0 [31/60]: Stacking v38: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor3.2.0 [32/60]: Stacking v38: LSM: security_secid_to_secctx in
+      netlink netfilter
+    - SAUCE: apparmor3.2.0 [33/60]: Stacking v38: NET: Store LSM netlabel data in
+      a lsmblob
+    - SAUCE: apparmor3.2.0 [34/60]: Stacking v38: binder: Pass LSM identifier for
+      confirmation
+    - SAUCE: apparmor3.2.0 [35/60]: Stacking v38: LSM: security_secid_to_secctx
+      module selection
+    - SAUCE: apparmor3.2.0 [36/60]: Stacking v38: Audit: Keep multiple LSM data in
+      audit_names
+    - SAUCE: apparmor3.2.0 [37/60]: Stacking v38: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor3.2.0 [38/60]: Stacking v38: LSM: Add a function to report
+      multiple LSMs
+    - SAUCE: apparmor3.2.0 [39/60]: Stacking v38: Audit: Allow multiple records in
+      an audit_buffer
+    - SAUCE: apparmor3.2.0 [40/60]: Stacking v38: Audit: Add record for multiple
+      task security contexts
+    - SAUCE: apparmor3.2.0 [41/60]: Stacking v38: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor3.2.0 [42/60]: Stacking v38: Audit: Add record for multiple
+      object contexts
+    - SAUCE: apparmor3.2.0 [43/60]: Stacking v38: netlabel: Use a struct lsmblob
+      in audit data
+    - SAUCE: apparmor3.2.0 [44/60]: Stacking v38: LSM: Removed scaffolding
+      function lsmcontext_init
+    - SAUCE: apparmor3.2.0 [45/60]: Stacking v38: AppArmor: Remove the exclusive
+      flag
+    - SAUCE: apparmor3.2.0 [46/60]: combine common_audit_data and
+      apparmor_audit_data
+    - SAUCE: apparmor3.2.0 [47/60]: setup slab cache for audit data
+    - SAUCE: apparmor3.2.0 [48/60]: rename audit_data->label to
+      audit_data->subj_label
+    - SAUCE: apparmor3.2.0 [49/60]: pass cred through to audit info.
+    - SAUCE: apparmor3.2.0 [50/60]: Improve debug print infrastructure
+    - SAUCE: apparmor3.2.0 [51/60]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor3.2.0 [52/60]: enable userspace upcall for mediation
+    - SAUCE: apparmor3.2.0 [53/60]: cache buffers on percpu list if there is lock
+      contention
+    - SAUCE: apparmor3.2.0 [55/60]: advertise availability of exended perms
+    - SAUCE: apparmor3.2.0 [60/60]: [Config] enable
+      CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+
+  * LSM stacking and AppArmor for 6.2: additional fixes (LP: #2017903) // update
+    apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor3.2.0 [57/60]: fix profile verification and enable it
+
+  * udev fails to make prctl() syscall with apparmor=0 (as used by maas by
+    default) (LP: #2016908) // update apparmor and LSM stacking patch set
+    (LP: #2028253)
+    - SAUCE: apparmor3.2.0 [27/60]: Stacking v38: Fix prctl() syscall with
+      apparmor=0
+
+  * kinetic: apply new apparmor and LSM stacking patch set (LP: #1989983) //
+    update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor3.2.0 [01/60]: add/use fns to print hash string hex value
+    - SAUCE: apparmor3.2.0 [03/60]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor3.2.0 [04/60]: add user namespace creation mediation
+    - SAUCE: apparmor3.2.0 [06/60]: af_unix mediation
+    - SAUCE: apparmor3.2.0 [07/60]: Add fine grained mediation of posix mqueues
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Use consistent llvm/clang for rust
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 28 Jul 2023 07:44:20 +0200
+
+linux-unstable (6.5.0-2.2) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.5.0-2.2 -proposed tracker (LP: #2027953)
+
+  * Remove non-LPAE kernel flavor (LP: #2025265)
+    - [Packaging] Rename armhf generic-lpae flavor to generic
+
+  * Please enable Renesas RZ platform serial installer (LP: #2022361)
+    - [Config] enable hihope RZ/G2M serial console
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] snap: Remove old configs handling
+    - [Packaging] checks/final-checks: Remove old configs handling
+    - [Packaging] checks/final-checks: check existance of Makefile first
+    - [Packaging] checks/final-checks: Fix shellcheck issues
+    - [Packaging] add libstdc++-dev to the build dependencies
+    - [Config] update annotations after rebase to v6.5-rc2
+
+  * Miscellaneous upstream changes
+    - kbuild: rust: avoid creating temporary files
+    - rust: fix bindgen build error with UBSAN_BOUNDS_STRICT
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 18 Jul 2023 10:14:14 +0200
+
+linux-unstable (6.5.0-1.1) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.5.0-1.1 -proposed tracker (LP: #2026689)
+
+  * CVE-2023-31248
+    - netfilter: nf_tables: do not ignore genmask when looking up chain by id
+
+  * CVE-2023-35001
+    - netfilter: nf_tables: prevent OOB access in nft_byteorder_eval
+
+  * HDMI output with More than one child device for port B in VBT error
+    (LP: #2025195)
+    - SAUCE: drm/i915/quirks: Add multiple VBT quirk for HP ZBook Power G10
+
+  * CVE-2023-2640 // CVE-2023-32629
+    - SAUCE: overlayfs: default to userxattr when mounted from non initial user
+      namespace
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync update-dkms-versions helper
+
+  * enable Rust support in the kernel (LP: #2007654)
+    - SAUCE: btf, scripts: rust: drop is_rust_module.sh
+    - [Packaging] add rust dependencies
+
+  * CVE-2023-2612
+    - SAUCE: shiftfs: prevent lock unbalance in shiftfs_create_object()
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: shiftfs: support linux 6.5
+    - [Config] update annotations after rebase to v6.5-rc1
+    - [Config] temporarily disable Rust
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 10 Jul 2023 09:15:26 +0200
+
+linux-unstable (6.5.0-0.0) mantic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 05 Jul 2023 12:48:39 +0200
+
+linux-unstable (6.4.0-8.8) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-8.8 -proposed tracker (LP: #2025018)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update toolchain version (gcc) in annotations
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 26 Jun 2023 09:14:02 +0200
+
+linux-unstable (6.4.0-7.7) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-7.7 -proposed tracker (LP: #2024338)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 19 Jun 2023 08:51:27 +0200
+
+linux-unstable (6.4.0-6.6) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-6.6 -proposed tracker (LP: #2023966)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update annotations scripts
+
+  * enable multi-gen LRU by default (LP: #2023629)
+    - [Config] enable multi-gen LRU by default
+
+  * Fix Monitor lost after replug WD19TBS to SUT port with VGA/DVI to type-C
+    dongle (LP: #2021949)
+    - thunderbolt: Do not touch CL state configuration during discovery
+    - thunderbolt: Increase DisplayPort Connection Manager handshake timeout
+
+  * Neuter signing tarballs (LP: #2012776)
+    - [Packaging] remove the signing tarball support
+
+  * Enable Tracing Configs for OSNOISE and TIMERLAT (LP: #2018591)
+    - [Config] Enable OSNOISE_TRACER and TIMERLAT_TRACER configs
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Add CONFIG_AS_HAS_NON_CONST_LEB128 on riscv64
+    - [Packaging] introduce do_lib_rust and enable it only on generic amd64
+    - [Config] update annotations after rebase to v6.4-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 15 Jun 2023 20:11:07 +0200
+
+linux-unstable (6.4.0-5.5) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-5.5 -proposed tracker (LP: #2022886)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] update getabis to support linux-unstable
+    - UBUNTU [Config]: disable hibernation on riscv64
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 06 Jun 2023 08:18:01 +0200
+
+linux-unstable (6.4.0-4.4) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-4.4 -proposed tracker (LP: #2021597)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] udpate annotations after rebase to v6.4-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 30 May 2023 11:55:41 +0200
+
+linux-unstable (6.4.0-3.3) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-3.3 -proposed tracker (LP: #2021497)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+    - [Packaging] resync getabis
+
+  * support python < 3.9 with annotations (LP: #2020531)
+    - [Packaging] kconfig/annotations.py: support older way of merging dicts
+
+  * generate linux-lib-rust only on amd64 (LP: #2020356)
+    - [Packaging] generate linux-lib-rust only on amd64
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: never drop configs that have notes different than
+      the parent
+    - [Config] drop CONFIG_SMBFS_COMMON from annotations
+    - [Packaging] perf: build without libtraceevent
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 30 May 2023 08:38:10 +0200
+
+linux-unstable (6.4.0-2.2) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-2.2 -proposed tracker (LP: #2020330)
+
+  * Computer with Intel Atom CPU will  not boot with Kernel 6.2.0-20
+    (LP: #2017444)
+    - [Config]: Disable CONFIG_INTEL_ATOMISP
+
+  * Fix NVME storage with RAID ON disappeared under Dell factory WINPE
+    environment (LP: #2011768)
+    - SAUCE: PCI: vmd: Reset VMD config register between soft reboots
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Drop support of old config handling
+    - [Config] update annotations after rebase to v6.4-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 22 May 2023 11:22:14 +0200
+
+linux-unstable (6.4.0-1.1) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-1.1 -proposed tracker (LP: #2019965)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - [Packaging] update helper scripts
+
+  * Kernel 6.1 bumped the disk consumption on default images by 15%
+    (LP: #2015867)
+    - [Packaging] introduce a separate linux-lib-rust package
+
+  * Miscellaneous Ubuntu changes
+    - [Config] enable CONFIG_BLK_DEV_UBLK on amd64
+    - [Packaging] annotations: use python3 in the shebang
+    - SAUCE: blk-throttle: Fix io statistics for cgroup v1
+    - [Packaging] move to v6.4 and rename to linux-unstable
+    - [Config] update annotations after rebase to v6.4-rc1
+    - [Packaging] temporarily disable perf
+    - [Packaging] temporarily disable bpftool
+    - [Config] ppc64el: reduce CONFIG_ARCH_FORCE_MAX_ORDER from 9 to 8
+    - SAUCE: perf: explicitly disable libtraceevent
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 18 May 2023 07:34:09 +0200
+
+linux-unstable (6.4.0-0.0) mantic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 17 May 2023 15:29:25 +0200
+
+linux-unstable (6.3.0-2.2) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.3.0-2.2 -proposed tracker (LP: #2017788)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move python3-dev to build-depends
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 26 Apr 2023 21:52:12 +0200
+
+linux-unstable (6.3.0-1.1) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.3.0-1.1 -proposed tracker (LP: #2017776)
+
+  * RFC: virtio and virtio-scsi should be built in (LP: #1685291)
+    - [Config] Mark CONFIG_SCSI_VIRTIO built-in
+
+  * Debian autoreconstruct Fix restoration of execute permissions (LP: #2015498)
+    - [Debian] autoreconstruct - fix restoration of execute permissions
+
+  * [SRU][Jammy] CONFIG_PCI_MESON is not enabled (LP: #2007745)
+    - [Config] arm64: Enable PCI_MESON module
+
+  * vmd may fail to create sysfs entry while `pci_rescan_bus()` called in some
+    other drivers like wwan (LP: #2011389)
+    - SAUCE: PCI: vmd: guard device addition and removal
+
+  * Lunar update: v6.2.9 upstream stable release (LP: #2016877)
+    - [Config] ppc64: updateconfigs following v6.2.9 stable updates
+
+  * Lunar update: v6.2.8 upstream stable release (LP: #2016876)
+    - [Config] ppc64: updateconfigs following v6.2.8 stable updates
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Move final-checks script to debian/scripts/checks
+    - [Packaging] checks/final-checks: Honor 'do_skip_checks'
+    - [Packaging] Drop wireguard DKMS
+    - [Packaging] Remove update-version-dkms
+    - [Packaging] debian/rules: Add DKMS info to 'printenv' output
+    - [Packaging] ignore KBUILD_VERBOSE in arch-has-odm-enabled.sh
+    - SAUCE: shiftfs: support linux 6.3
+    - [Packaging] move to v6.3 and rename to linux-unstable
+    - [Config] latency-related optimizations
+    - [Config] update annotations after rebase to v6.3
+    - [Packaging] temporarily disable dkms
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 26 Apr 2023 14:53:52 +0200
+
+linux-unstable (6.3.0-0.0) lunar; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 25 Apr 2023 10:24:12 +0200
+
+linux (6.2.0-21.21) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-21.21 -proposed tracker (LP: #2016249)
+
+  * efivarfs:efivarfs.sh in ubuntu_kernel_selftests crash L-6.2 ARM64 node
+    dazzle (rcu_preempt detected stalls) (LP: #2015741)
+    - efi/libstub: smbios: Use length member instead of record struct size
+    - arm64: efi: Use SMBIOS processor version to key off Ampere quirk
+    - efi/libstub: smbios: Drop unused 'recsize' parameter
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/bpf: ignore pointer types check with clang
+    - SAUCE: selftests/bpf: avoid conflicting data types in profiler.inc.h
+    - [Packaging] get rid of unnecessary artifacts in linux-headers
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: Revert "efi: random: refresh non-volatile random seed
+      when RNG is initialized""
+    - Revert "UBUNTU: SAUCE: Revert "efi: random: fix NULL-deref when refreshing
+      seed""
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 14 Apr 2023 12:11:49 +0200
+
+linux (6.2.0-20.20) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-20.20 -proposed tracker (LP: #2015429)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * FTBFS with different dkms or when makeflags are set (LP: #2015361)
+    - [Packaging] FTBFS with different dkms or when makeflags are set
+
+  * expoline.o is packaged unconditionally for s390x (LP: #2013209)
+    - [Packaging] Copy expoline.o only when produced by the build
+
+  * net:l2tp.sh failure with lunar:linux 6.2 (LP: #2013014)
+    - SAUCE: l2tp: generate correct module alias strings
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: prevent duplicate include lines
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 06 Apr 2023 08:33:14 +0200
+
+linux (6.2.0-19.19) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-19.19 -proposed tracker (LP: #2012488)
+
+  * Neuter signing tarballs (LP: #2012776)
+    - [Packaging] neuter the signing tarball
+
+  * LSM stacking and AppArmor refresh for 6.2 kernel (LP: #2012136)
+    - Revert "UBUNTU: [Config] define CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS"
+    - Revert "UBUNTU: SAUCE: apparmor: add user namespace creation mediation"
+    - Revert "UBUNTU: SAUCE: apparmor: Add fine grained mediation of posix
+      mqueues"
+    - Revert "UBUNTU: SAUCE: Revert "apparmor: make __aa_path_perm() static""
+    - Revert "UBUNTU: SAUCE: LSM: Specify which LSM to display (using struct cred
+      as input)"
+    - Revert "UBUNTU: SAUCE: apparmor: Fix build error, make sk parameter const"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in smk_netlbl_mls()"
+    - Revert "UBUNTU: SAUCE: LSM: change ima_read_file() to use lsmblob"
+    - Revert "UBUNTU: SAUCE: apparmor: rename kzfree() to kfree_sensitive()"
+    - Revert "UBUNTU: SAUCE: AppArmor: Remove the exclusive flag"
+    - Revert "UBUNTU: SAUCE: LSM: Add /proc attr entry for full LSM context"
+    - Revert "UBUNTU: SAUCE: Audit: Fix incorrect static inline function
+      declration."
+    - Revert "UBUNTU: SAUCE: Audit: Fix for missing NULL check"
+    - Revert "UBUNTU: SAUCE: Audit: Add a new record for multiple object LSM
+      attributes"
+    - Revert "UBUNTU: SAUCE: Audit: Add new record for multiple process LSM
+      attributes"
+    - Revert "UBUNTU: SAUCE: NET: Store LSM netlabel data in a lsmblob"
+    - Revert "UBUNTU: SAUCE: LSM: security_secid_to_secctx in netlink netfilter"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmcontext in security_inode_getsecctx"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmcontext in security_secid_to_secctx"
+    - Revert "UBUNTU: SAUCE: LSM: Ensure the correct LSM context releaser"
+    - Revert "UBUNTU: SAUCE: LSM: Specify which LSM to display"
+    - Revert "UBUNTU: SAUCE: IMA: Change internal interfaces to use lsmblobs"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_cred_getsecid"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_inode_getsecid"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_task_getsecid"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_ipc_getsecid"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_secid_to_secctx"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_secctx_to_secid"
+    - Revert "UBUNTU: SAUCE: net: Prepare UDS for security module stacking"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_kernel_act_as"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_audit_rule_match"
+    - Revert "UBUNTU: SAUCE: LSM: Create and manage the lsmblob data structure."
+    - Revert "UBUNTU: SAUCE: LSM: Infrastructure management of the sock security"
+    - Revert "UBUNTU: SAUCE: apparmor: LSM stacking: switch from SK_CTX() to
+      aa_sock()"
+    - Revert "UBUNTU: SAUCE: apparmor: rename aa_sock() to aa_unix_sk()"
+    - Revert "UBUNTU: SAUCE: apparmor: disable showing the mode as part of a secid
+      to secctx"
+    - Revert "UBUNTU: SAUCE: apparmor: fix use after free in sk_peer_label"
+    - Revert "UBUNTU: SAUCE: apparmor: af_unix mediation"
+    - Revert "UBUNTU: SAUCE: apparmor: patch to provide compatibility with v2.x
+      net rules"
+    - Revert "UBUNTU: SAUCE: apparmor: add/use fns to print hash string hex value"
+    - SAUCE: apparmor: rename SK_CTX() to aa_sock and make it an inline fn
+    - SAUCE: apparmor: Add sysctls for additional controls of unpriv userns
+      restrictions
+    - SAUCE: Stacking v38: LSM: Identify modules by more than name
+    - SAUCE: Stacking v38: LSM: Add an LSM identifier for external use
+    - SAUCE: Stacking v38: LSM: Identify the process attributes for each module
+    - SAUCE: Stacking v38: LSM: Maintain a table of LSM attribute data
+    - SAUCE: Stacking v38: proc: Use lsmids instead of lsm names for attrs
+    - SAUCE: Stacking v38: integrity: disassociate ima_filter_rule from
+      security_audit_rule
+    - SAUCE: Stacking v38: LSM: Infrastructure management of the sock security
+    - SAUCE: Stacking v38: LSM: Add the lsmblob data structure.
+    - SAUCE: Stacking v38: LSM: provide lsm name and id slot mappings
+    - SAUCE: Stacking v38: IMA: avoid label collisions with stacked LSMs
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_audit_rule_match
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_kernel_act_as
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_secctx_to_secid
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_secid_to_secctx
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_ipc_getsecid
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_current_getsecid
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_inode_getsecid
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_cred_getsecid
+    - SAUCE: Stacking v38: LSM: Specify which LSM to display
+    - SAUCE: Stacking v38: LSM: Ensure the correct LSM context releaser
+    - SAUCE: Stacking v38: LSM: Use lsmcontext in security_secid_to_secctx
+    - SAUCE: Stacking v38: LSM: Use lsmcontext in security_inode_getsecctx
+    - SAUCE: Stacking v38: Use lsmcontext in security_dentry_init_security
+    - SAUCE: Stacking v38: LSM: security_secid_to_secctx in netlink netfilter
+    - SAUCE: Stacking v38: NET: Store LSM netlabel data in a lsmblob
+    - SAUCE: Stacking v38: binder: Pass LSM identifier for confirmation
+    - SAUCE: Stacking v38: LSM: security_secid_to_secctx module selection
+    - SAUCE: Stacking v38: Audit: Keep multiple LSM data in audit_names
+    - SAUCE: Stacking v38: Audit: Create audit_stamp structure
+    - SAUCE: Stacking v38: LSM: Add a function to report multiple LSMs
+    - SAUCE: Stacking v38: Audit: Allow multiple records in an audit_buffer
+    - SAUCE: Stacking v38: Audit: Add record for multiple task security contexts
+    - SAUCE: Stacking v38: audit: multiple subject lsm values for netlabel
+    - SAUCE: Stacking v38: Audit: Add record for multiple object contexts
+    - SAUCE: Stacking v38: netlabel: Use a struct lsmblob in audit data
+    - SAUCE: Stacking v38: LSM: Removed scaffolding function lsmcontext_init
+    - SAUCE: Stacking v38: AppArmor: Remove the exclusive flag
+    - SAUCE: apparmor: combine common_audit_data and apparmor_audit_data
+    - SAUCE: apparmor: setup slab cache for audit data
+    - SAUCE: apparmor: rename audit_data->label to audit_data->subj_label
+    - SAUCE: apparmor: pass cred through to audit info.
+    - SAUCE: apparmor: Improve debug print infrastructure
+    - SAUCE: apparmor: add the ability for profiles to have a learning cache
+    - SAUCE: apparmor: enable userspace upcall for mediation
+    - SAUCE: apparmor: cache buffers on percpu list if there is lock contention
+    - SAUCE: apparmor: fix policy_compat permission remap with extended
+      permissions
+    - SAUCE: apparmor: advertise availability of exended perms
+    - [Config] define CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+
+  * kinetic: apply new apparmor and LSM stacking patch set (LP: #1989983) // LSM
+    stacking and AppArmor refresh for 6.2 kernel (LP: #2012136)
+    - SAUCE: apparmor: add/use fns to print hash string hex value
+    - SAUCE: apparmor: patch to provide compatibility with v2.x net rules
+    - SAUCE: apparmor: add user namespace creation mediation
+    - SAUCE: apparmor: af_unix mediation
+    - SAUCE: apparmor: Add fine grained mediation of posix mqueues
+
+  * devlink_port_split from ubuntu_kernel_selftests.net fails on hirsute
+    (KeyError: 'flavour') (LP: #1937133)
+    - selftests: net: devlink_port_split.py: skip test if no suitable device
+      available
+
+  * NFS deathlock with last Kernel 5.4.0-144.161 and 5.15.0-67.74 (LP: #2009325)
+    - NFS: Correct timing for assigning access cache timestamp
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Sat, 25 Mar 2023 07:37:30 +0100
+
+linux (6.2.0-18.18) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-18.18 -proposed tracker (LP: #2011750)
+
+  * lunar/linux 6.2 fails to boot on arm64 (LP: #2011748)
+    - SAUCE: Revert "efi: random: fix NULL-deref when refreshing seed"
+    - SAUCE: Revert "efi: random: refresh non-volatile random seed when RNG is
+      initialized"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 15 Mar 2023 23:54:18 +0100
+
+linux (6.2.0-17.17) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-17.17 -proposed tracker (LP: #2011593)
+
+  * lunar/linux 6.2 fails to boot on ppc64el (LP: #2011413)
+    - SAUCE: Revert "powerpc: remove STACK_FRAME_OVERHEAD"
+    - SAUCE: Revert "powerpc/pseries: hvcall stack frame overhead"
+
+  * Speaker / Audio/Mic mute LED don't work on a HP platform (LP: #2011379)
+    - SAUCE: ALSA: hda/realtek: fix speaker, mute/micmute LEDs not work on a HP
+      platform
+
+  * Some QHD panels fail to refresh when PSR2 enabled (LP: #2009014)
+    - SAUCE: drm/i915/psr: Use calculated io and fast wake lines
+
+  * Lunar update: v6.2.6 upstream stable release (LP: #2011431)
+    - tpm: disable hwrng for fTPM on some AMD designs
+    - wifi: cfg80211: Partial revert "wifi: cfg80211: Fix use after free for wext"
+    - staging: rtl8192e: Remove function ..dm_check_ac_dc_power calling a script
+    - staging: rtl8192e: Remove call_usermodehelper starting RadioPower.sh
+    - Linux 6.2.6
+
+  * Lunar update: v6.2.5 upstream stable release (LP: #2011430)
+    - net/sched: Retire tcindex classifier
+    - auxdisplay: hd44780: Fix potential memory leak in hd44780_remove()
+    - fs/jfs: fix shift exponent db_agl2size negative
+    - driver: soc: xilinx: fix memory leak in xlnx_add_cb_for_notify_event()
+    - f2fs: don't rely on F2FS_MAP_* in f2fs_iomap_begin
+    - f2fs: fix to avoid potential deadlock
+    - objtool: Fix memory leak in create_static_call_sections()
+    - soc: mediatek: mtk-pm-domains: Allow mt8186 ADSP default power on
+    - soc: qcom: socinfo: Fix soc_id order
+    - memory: renesas-rpc-if: Split-off private data from struct rpcif
+    - memory: renesas-rpc-if: Move resource acquisition to .probe()
+    - soc: mediatek: mtk-svs: Enable the IRQ later
+    - pwm: sifive: Always let the first pwm_apply_state succeed
+    - pwm: stm32-lp: fix the check on arr and cmp registers update
+    - f2fs: introduce trace_f2fs_replace_atomic_write_block
+    - f2fs: clear atomic_write_task in f2fs_abort_atomic_write()
+    - soc: mediatek: mtk-svs: restore default voltages when svs_init02() fail
+    - soc: mediatek: mtk-svs: reset svs when svs_resume() fail
+    - soc: mediatek: mtk-svs: Use pm_runtime_resume_and_get() in svs_init01()
+    - f2fs: fix to do sanity check on extent cache correctly
+    - fs: f2fs: initialize fsdata in pagecache_write()
+    - f2fs: allow set compression option of files without blocks
+    - f2fs: fix to abort atomic write only during do_exist()
+    - um: vector: Fix memory leak in vector_config
+    - ubi: ensure that VID header offset + VID header size <= alloc, size
+    - ubifs: Fix build errors as symbol undefined
+    - ubifs: Fix memory leak in ubifs_sysfs_init()
+    - ubifs: Rectify space budget for ubifs_symlink() if symlink is encrypted
+    - ubifs: Rectify space budget for ubifs_xrename()
+    - ubifs: Fix wrong dirty space budget for dirty inode
+    - ubifs: do_rename: Fix wrong space budget when target inode's nlink > 1
+    - ubifs: Reserve one leb for each journal head while doing budget
+    - ubi: Fix use-after-free when volume resizing failed
+    - ubi: Fix unreferenced object reported by kmemleak in ubi_resize_volume()
+    - ubifs: Fix memory leak in alloc_wbufs()
+    - ubi: Fix possible null-ptr-deref in ubi_free_volume()
+    - ubifs: Re-statistic cleaned znode count if commit failed
+    - ubifs: dirty_cow_znode: Fix memleak in error handling path
+    - ubifs: ubifs_writepage: Mark page dirty after writing inode failed
+    - ubifs: ubifs_releasepage: Remove ubifs_assert(0) to valid this process
+    - ubi: fastmap: Fix missed fm_anchor PEB in wear-leveling after disabling
+      fastmap
+    - ubi: Fix UAF wear-leveling entry in eraseblk_count_seq_show()
+    - ubi: ubi_wl_put_peb: Fix infinite loop when wear-leveling work failed
+    - f2fs: fix to handle F2FS_IOC_START_ATOMIC_REPLACE in f2fs_compat_ioctl()
+    - f2fs: fix to avoid potential memory corruption in __update_iostat_latency()
+    - f2fs: fix to update age extent correctly during truncation
+    - f2fs: fix to update age extent in f2fs_do_zero_range()
+    - soc: qcom: stats: Populate all subsystem debugfs files
+    - f2fs: introduce IS_F2FS_IPU_* macro
+    - f2fs: fix to set ipu policy
+    - ext4: use ext4_fc_tl_mem in fast-commit replay path
+    - ext4: don't show commit interval if it is zero
+    - netfilter: nf_tables: allow to fetch set elements when table has an owner
+    - x86: um: vdso: Add '%rcx' and '%r11' to the syscall clobber list
+    - um: virtio_uml: free command if adding to virtqueue failed
+    - um: virtio_uml: mark device as unregistered when breaking it
+    - um: virtio_uml: move device breaking into workqueue
+    - um: virt-pci: properly remove PCI device from bus
+    - f2fs: synchronize atomic write aborts
+    - watchdog: rzg2l_wdt: Issue a reset before we put the PM clocks
+    - watchdog: rzg2l_wdt: Handle TYPE-B reset for RZ/V2M
+    - watchdog: at91sam9_wdt: use devm_request_irq to avoid missing free_irq() in
+      error path
+    - watchdog: Fix kmemleak in watchdog_cdev_register
+    - watchdog: pcwd_usb: Fix attempting to access uninitialized memory
+    - watchdog: sbsa_wdog: Make sure the timeout programming is within the limits
+    - netfilter: ctnetlink: fix possible refcount leak in
+      ctnetlink_create_conntrack()
+    - netfilter: conntrack: fix rmmod double-free race
+    - netfilter: ip6t_rpfilter: Fix regression with VRF interfaces
+    - netfilter: ebtables: fix table blob use-after-free
+    - netfilter: xt_length: use skb len to match in length_mt6
+    - netfilter: ctnetlink: make event listener tracking global
+    - netfilter: x_tables: fix percpu counter block leak on error path when
+      creating new netns
+    - swiotlb: mark swiotlb_memblock_alloc() as __init
+    - ptp: vclock: use mutex to fix "sleep on atomic" bug
+    - drm/i915: move a Kconfig symbol to unbreak the menu presentation
+    - ipv6: Add lwtunnel encap size of all siblings in nexthop calculation
+    - drm/i915/xelpmp: Consider GSI offset when doing MCR lookups
+    - octeontx2-pf: Recalculate UDP checksum for ptp 1-step sync packet
+    - net: sunhme: Fix region request
+    - sctp: add a refcnt in sctp_stream_priorities to avoid a nested loop
+    - octeontx2-pf: Use correct struct reference in test condition
+    - net: fix __dev_kfree_skb_any() vs drop monitor
+    - 9p/xen: fix version parsing
+    - 9p/xen: fix connection sequence
+    - 9p/rdma: unmap receive dma buffer in rdma_request()/post_recv()
+    - spi: tegra210-quad: Fix validate combined sequence
+    - mlx5: fix skb leak while fifo resync and push
+    - mlx5: fix possible ptp queue fifo use-after-free
+    - net/mlx5: ECPF, wait for VF pages only after disabling host PFs
+    - net/mlx5e: Verify flow_source cap before using it
+    - net/mlx5: Geneve, Fix handling of Geneve object id as error code
+    - ext4: fix incorrect options show of original mount_opt and extend mount_opt2
+    - nfc: fix memory leak of se_io context in nfc_genl_se_io
+    - net/sched: transition act_pedit to rcu and percpu stats
+    - net/sched: act_pedit: fix action bind logic
+    - net/sched: act_mpls: fix action bind logic
+    - net/sched: act_sample: fix action bind logic
+    - net: dsa: seville: ignore mscc-miim read errors from Lynx PCS
+    - net: dsa: felix: fix internal MDIO controller resource length
+    - ARM: dts: aspeed: p10bmc: Update battery node name
+    - ARM: dts: spear320-hmi: correct STMPE GPIO compatible
+    - tcp: tcp_check_req() can be called from process context
+    - vc_screen: modify vcs_size() handling in vcs_read()
+    - spi: tegra210-quad: Fix iterator outside loop
+    - rtc: sun6i: Always export the internal oscillator
+    - genirq/ipi: Fix NULL pointer deref in irq_data_get_affinity_mask()
+    - scsi: ipr: Work around fortify-string warning
+    - scsi: mpi3mr: Fix an issue found by KASAN
+    - scsi: mpi3mr: Use number of bits to manage bitmap sizes
+    - rtc: allow rtc_read_alarm without read_alarm callback
+    - io_uring: fix size calculation when registering buf ring
+    - loop: loop_set_status_from_info() check before assignment
+    - ASoC: adau7118: don't disable regulators on device unbind
+    - ASoC: apple: mca: Fix final status read on SERDES reset
+    - ASoC: apple: mca: Fix SERDES reset sequence
+    - ASoC: apple: mca: Improve handling of unavailable DMA channels
+    - nvme: bring back auto-removal of deleted namespaces during sequential scan
+    - nvme-tcp: don't access released socket during error recovery
+    - nvme-fabrics: show well known discovery name
+    - ASoC: zl38060 add gpiolib dependency
+    - ASoC: mediatek: mt8195: add missing initialization
+    - thermal: intel: quark_dts: fix error pointer dereference
+    - thermal: intel: BXT_PMIC: select REGMAP instead of depending on it
+    - cpufreq: apple-soc: Fix an IS_ERR() vs NULL check
+    - tracing: Add NULL checks for buffer in ring_buffer_free_read_page()
+    - kernel/printk/index.c: fix memory leak with using debugfs_lookup()
+    - firmware/efi sysfb_efi: Add quirk for Lenovo IdeaPad Duet 3
+    - bootconfig: Increase max nodes of bootconfig from 1024 to 8192 for DCC
+      support
+    - mfd: arizona: Use pm_runtime_resume_and_get() to prevent refcnt leak
+    - IB/hfi1: Update RMT size calculation
+    - iommu: Remove deferred attach check from __iommu_detach_device()
+    - PCI/ACPI: Account for _S0W of the target bridge in acpi_pci_bridge_d3()
+    - media: uvcvideo: Remove format descriptions
+    - media: uvcvideo: Handle cameras with invalid descriptors
+    - media: uvcvideo: Handle errors from calls to usb_string
+    - media: uvcvideo: Quirk for autosuspend in Logitech B910 and C910
+    - media: uvcvideo: Silence memcpy() run-time false positive warnings
+    - USB: fix memory leak with using debugfs_lookup()
+    - cacheinfo: Fix shared_cpu_map to handle shared caches at different levels
+    - usb: fotg210: List different variants
+    - dt-bindings: usb: Add device id for Genesys Logic hub controller
+    - staging: emxx_udc: Add checks for dma_alloc_coherent()
+    - tty: fix out-of-bounds access in tty_driver_lookup_tty()
+    - tty: serial: fsl_lpuart: disable the CTS when send break signal
+    - serial: sc16is7xx: setup GPIO controller later in probe
+    - mei: bus-fixup:upon error print return values of send and receive
+    - tools/iio/iio_utils:fix memory leak
+    - bus: mhi: ep: Fix the debug message for MHI_PKT_TYPE_RESET_CHAN_CMD cmd
+    - iio: accel: mma9551_core: Prevent uninitialized variable in
+      mma9551_read_status_word()
+    - iio: accel: mma9551_core: Prevent uninitialized variable in
+      mma9551_read_config_word()
+    - media: uvcvideo: Add GUID for BGRA/X 8:8:8:8
+    - soundwire: bus_type: Avoid lockdep assert in sdw_drv_probe()
+    - PCI/portdrv: Prevent LS7A Bus Master clearing on shutdown
+    - PCI: loongson: Prevent LS7A MRRS increases
+    - staging: pi433: fix memory leak with using debugfs_lookup()
+    - USB: dwc3: fix memory leak with using debugfs_lookup()
+    - USB: chipidea: fix memory leak with using debugfs_lookup()
+    - USB: ULPI: fix memory leak with using debugfs_lookup()
+    - USB: uhci: fix memory leak with using debugfs_lookup()
+    - USB: sl811: fix memory leak with using debugfs_lookup()
+    - USB: fotg210: fix memory leak with using debugfs_lookup()
+    - USB: isp116x: fix memory leak with using debugfs_lookup()
+    - USB: isp1362: fix memory leak with using debugfs_lookup()
+    - USB: gadget: gr_udc: fix memory leak with using debugfs_lookup()
+    - USB: gadget: bcm63xx_udc: fix memory leak with using debugfs_lookup()
+    - USB: gadget: lpc32xx_udc: fix memory leak with using debugfs_lookup()
+    - USB: gadget: pxa25x_udc: fix memory leak with using debugfs_lookup()
+    - USB: gadget: pxa27x_udc: fix memory leak with using debugfs_lookup()
+    - usb: host: xhci: mvebu: Iterate over array indexes instead of using pointer
+      math
+    - USB: ene_usb6250: Allocate enough memory for full object
+    - usb: uvc: Enumerate valid values for color matching
+    - usb: gadget: uvc: Make bSourceID read/write
+    - PCI: Align extra resources for hotplug bridges properly
+    - PCI: Take other bus devices into account when distributing resources
+    - PCI: Distribute available resources for root buses, too
+    - tty: pcn_uart: fix memory leak with using debugfs_lookup()
+    - misc: vmw_balloon: fix memory leak with using debugfs_lookup()
+    - drivers: base: component: fix memory leak with using debugfs_lookup()
+    - drivers: base: dd: fix memory leak with using debugfs_lookup()
+    - kernel/fail_function: fix memory leak with using debugfs_lookup()
+    - PCI: loongson: Add more devices that need MRRS quirk
+    - PCI: Add ACS quirk for Wangxun NICs
+    - PCI: pciehp: Add Qualcomm quirk for Command Completed erratum
+    - phy: rockchip-typec: Fix unsigned comparison with less than zero
+    - RDMA/cma: Distinguish between sockaddr_in and sockaddr_in6 by size
+    - soundwire: cadence: Remove wasted space in response_buf
+    - soundwire: cadence: Drain the RX FIFO after an IO timeout
+    - eth: fealnx: bring back this old driver
+    - net: tls: avoid hanging tasks on the tx_lock
+    - x86/resctl: fix scheduler confusion with 'current'
+    - vDPA/ifcvf: decouple hw features manipulators from the adapter
+    - vDPA/ifcvf: decouple config space ops from the adapter
+    - vDPA/ifcvf: alloc the mgmt_dev before the adapter
+    - vDPA/ifcvf: decouple vq IRQ releasers from the adapter
+    - vDPA/ifcvf: decouple config IRQ releaser from the adapter
+    - vDPA/ifcvf: decouple vq irq requester from the adapter
+    - vDPA/ifcvf: decouple config/dev IRQ requester and vectors allocator from the
+      adapter
+    - vDPA/ifcvf: ifcvf_request_irq works on ifcvf_hw
+    - vDPA/ifcvf: manage ifcvf_hw in the mgmt_dev
+    - vDPA/ifcvf: allocate the adapter in dev_add()
+    - drm/display/dp_mst: Add drm_atomic_get_old_mst_topology_state()
+    - drm/display/dp_mst: Fix down/up message handling after sink disconnect
+    - drm/display/dp_mst: Fix down message handling after a packet reception error
+    - drm/display/dp_mst: Fix payload addition on a disconnected sink
+    - drm/i915/dp_mst: Add the MST topology state for modesetted CRTCs
+    - drm/display/dp_mst: Handle old/new payload states in drm_dp_remove_payload()
+    - drm/i915/dp_mst: Fix payload removal during output disabling
+    - drm/i915: Fix system suspend without fbdev being initialized
+    - media: uvcvideo: Fix race condition with usb_kill_urb
+    - arm64: efi: Make efi_rt_lock a raw_spinlock
+    - usb: gadget: uvc: fix missing mutex_unlock() if kstrtou8() fails
+    - Linux 6.2.5
+
+  * Lunar update: v6.2.4 upstream stable release (LP: #2011428)
+    - Revert "blk-cgroup: synchronize pd_free_fn() from blkg_free_workfn() and
+      blkcg_deactivate_policy()"
+    - Revert "blk-cgroup: dropping parent refcount after pd_free_fn() is done"
+    - Linux 6.2.4
+
+  * Lunar update: v6.2.3 upstream stable release (LP: #2011425)
+    - HID: asus: use spinlock to protect concurrent accesses
+    - HID: asus: use spinlock to safely schedule workers
+    - iommu/amd: Fix error handling for pdev_pri_ats_enable()
+    - iommu/amd: Skip attach device domain is same as new domain
+    - iommu/amd: Improve page fault error reporting
+    - iommu: Attach device group to old domain in error path
+    - powerpc/mm: Rearrange if-else block to avoid clang warning
+    - ata: ahci: Revert "ata: ahci: Add Tiger Lake UP{3,4} AHCI controller"
+    - ARM: OMAP2+: Fix memory leak in realtime_counter_init()
+    - arm64: dts: qcom: qcs404: use symbol names for PCIe resets
+    - arm64: dts: qcom: msm8996-tone: Fix USB taking 6 minutes to wake up
+    - arm64: dts: qcom: sm6115: Fix UFS node
+    - arm64: dts: qcom: sm6115: Provide xo clk to rpmcc
+    - arm64: dts: qcom: sm8150-kumano: Panel framebuffer is 2.5k instead of 4k
+    - arm64: dts: qcom: pmi8950: Correct rev_1250v channel label to mv
+    - arm64: dts: qcom: sm6350: Fix up the ramoops node
+    - arm64: dts: qcom: sdm670-google-sargo: keep pm660 ldo8 on
+    - arm64: dts: qcom: Re-enable resin on MSM8998 and SDM845 boards
+    - arm64: dts: qcom: sm8350-sagami: Configure SLG51000 PMIC on PDX215
+    - arm64: dts: qcom: sm8350-sagami: Add GPIO line names for PMIC GPIOs
+    - arm64: dts: qcom: sm8350-sagami: Rectify GPIO keys
+    - arm64: dts: qcom: sm6350-lena: Flatten gpio-keys pinctrl state
+    - arm64: dts: qcom: sm6125: Reorder HSUSB PHY clocks to match bindings
+    - arm64: dts: qcom: sm6125-seine: Clean up gpio-keys (volume down)
+    - arm64: dts: imx8m: Align SoC unique ID node unit address
+    - ARM: zynq: Fix refcount leak in zynq_early_slcr_init
+    - fs: dlm: fix return value check in dlm_memory_init()
+    - arm64: dts: mediatek: mt8195: Add power domain to U3PHY1 T-PHY
+    - arm64: dts: mediatek: mt8183: Fix systimer 13 MHz clock description
+    - arm64: dts: mediatek: mt8192: Fix systimer 13 MHz clock description
+    - arm64: dts: mediatek: mt8195: Fix systimer 13 MHz clock description
+    - arm64: dts: mediatek: mt8186: Fix systimer 13 MHz clock description
+    - arm64: dts: qcom: sdm845-db845c: fix audio codec interrupt pin name
+    - arm64: dts: qcom: sdm845-xiaomi-beryllium: fix audio codec interrupt pin
+      name
+    - x86/acpi/boot: Do not register processors that cannot be onlined for x2APIC
+    - arm64: dts: qcom: sc7180: correct SPMI bus address cells
+    - arm64: dts: qcom: sc7280: correct SPMI bus address cells
+    - arm64: dts: qcom: sc8280xp: correct SPMI bus address cells
+    - arm64: dts: qcom: sm8450: correct Soundwire wakeup interrupt name
+    - arm64: dts: qcom: sdm845: make DP node follow the schema
+    - arm64: dts: qcom: msm8996-oneplus-common: drop vdda-supply from DSI PHY
+    - arm64: dts: qcom: sc8280xp: Vote for CX in USB controllers
+    - arm64: dts: meson-gxl: jethub-j80: Fix WiFi MAC address node
+    - arm64: dts: meson-gxl: jethub-j80: Fix Bluetooth MAC node name
+    - arm64: dts: meson-axg: jethub-j1xx: Fix MAC address node names
+    - arm64: dts: meson-gx: Fix Ethernet MAC address unit name
+    - arm64: dts: meson-g12a: Fix internal Ethernet PHY unit name
+    - arm64: dts: meson-gx: Fix the SCPI DVFS node name and unit address
+    - cpuidle, intel_idle: Fix CPUIDLE_FLAG_IRQ_ENABLE *again*
+    - arm64: dts: ti: k3-am62-main: Fix clocks for McSPI
+    - arm64: tegra: Fix duplicate regulator on Jetson TX1
+    - arm64: dts: qcom: msm8992-bullhead: Fix cont_splash_mem size
+    - arm64: dts: qcom: msm8992-bullhead: Disable dfps_data_mem
+    - arm64: dts: qcom: msm8956: use SoC-specific compat for tsens
+    - arm64: dts: qcom: ipq8074: correct USB3 QMP PHY-s clock output names
+    - arm64: dts: qcom: ipq8074: fix Gen2 PCIe QMP PHY
+    - arm64: dts: qcom: ipq8074: fix Gen3 PCIe QMP PHY
+    - arm64: dts: qcom: ipq8074: correct Gen2 PCIe ranges
+    - arm64: dts: qcom: ipq8074: fix Gen3 PCIe node
+    - arm64: dts: qcom: ipq8074: correct PCIe QMP PHY output clock names
+    - arm64: dts: meson: remove CPU opps below 1GHz for G12A boards
+    - ARM: OMAP1: call platform_device_put() in error case in
+      omap1_dm_timer_init()
+    - arm64: dts: mediatek: mt8192: Mark scp_adsp clock as broken
+    - ARM: bcm2835_defconfig: Enable the framebuffer
+    - ARM: s3c: fix s3c64xx_set_timer_source prototype
+    - arm64: dts: ti: k3-j7200: Fix wakeup pinmux range
+    - ARM: dts: exynos: correct wr-active property in Exynos3250 Rinato
+    - ARM: imx: Call ida_simple_remove() for ida_simple_get
+    - arm64: dts: amlogic: meson-gx: fix SCPI clock dvfs node name
+    - arm64: dts: amlogic: meson-axg: fix SCPI clock dvfs node name
+    - arm64: dts: amlogic: meson-gx: add missing SCPI sensors compatible
+    - arm64: dts: amlogic: meson-axg-jethome-jethub-j1xx: fix supply name of USB
+      controller node
+    - arm64: dts: amlogic: meson-gxl-s905d-sml5442tw: drop invalid clock-names
+      property
+    - arm64: dts: amlogic: meson-gx: add missing unit address to rng node name
+    - arm64: dts: amlogic: meson-gxl-s905w-jethome-jethub-j80: fix invalid rtc
+      node name
+    - arm64: dts: amlogic: meson-axg-jethome-jethub-j1xx: fix invalid rtc node
+      name
+    - arm64: dts: amlogic: meson-gxl: add missing unit address to eth-phy-mux node
+      name
+    - arm64: dts: amlogic: meson-gx-libretech-pc: fix update button name
+    - arm64: dts: amlogic: meson-sm1-bananapi-m5: fix adc keys node names
+    - arm64: dts: amlogic: meson-gxl-s905d-phicomm-n1: fix led node name
+    - arm64: dts: amlogic: meson-gxbb-kii-pro: fix led node name
+    - arm64: dts: amlogic: meson-g12b-odroid-go-ultra: fix rk818 pmic properties
+    - arm64: dts: amlogic: meson-sm1-odroid-hc4: fix active fan thermal trip
+    - locking/rwsem: Disable preemption in all down_read*() and up_read() code
+      paths
+    - arm64: tegra: Mark host1x as dma-coherent on Tegra194/234
+    - arm64: dts: renesas: beacon-renesom: Fix gpio expander reference
+    - arm64: dts: meson: radxa-zero: allow usb otg mode
+    - arm64: dts: meson: bananapi-m5: switch VDDIO_C pin to OPEN_DRAIN
+    - ARM: dts: sun8i: nanopi-duo2: Fix regulator GPIO reference
+    - ublk_drv: remove nr_aborted_queues from ublk_device
+    - ublk_drv: don't probe partitions if the ubq daemon isn't trusted
+    - ARM: dts: imx7s: correct iomuxc gpr mux controller cells
+    - sbitmap: remove redundant check in __sbitmap_queue_get_batch
+    - sbitmap: correct wake_batch recalculation to avoid potential IO hung
+    - arm64: dts: mt8195: Fix CPU map for single-cluster SoC
+    - arm64: dts: mt8192: Fix CPU map for single-cluster SoC
+    - arm64: dts: mt8186: Fix CPU map for single-cluster SoC
+    - arm64: dts: mediatek: mt7622: Add missing pwm-cells to pwm node
+    - arm64: dts: mediatek: mt8186: Fix watchdog compatible
+    - arm64: dts: mediatek: mt8195: Fix watchdog compatible
+    - arm64: dts: mediatek: mt7986: Fix watchdog compatible
+    - ARM: dts: stm32: Update part number NVMEM description on stm32mp131
+    - arm64: dts: qcom: sm8450-nagara: Correct firmware paths
+    - blk-mq: avoid sleep in blk_mq_alloc_request_hctx
+    - blk-mq: remove stale comment for blk_mq_sched_mark_restart_hctx
+    - blk-mq: wait on correct sbitmap_queue in blk_mq_mark_tag_wait
+    - blk-mq: Fix potential io hung for shared sbitmap per tagset
+    - blk-mq: correct stale comment of .get_budget
+    - arm64: dts: qcom: msm8996: support using GPLL0 as kryocc input
+    - arm64: dts: qcom: msm8996 switch from RPM_SMD_BB_CLK1 to RPM_SMD_XO_CLK_SRC
+    - arm64: dts: qcom: sm8350: drop incorrect cells from serial
+    - arm64: dts: qcom: sm8450: drop incorrect cells from serial
+    - arm64: dts: qcom: msm8992-lg-bullhead: Correct memory overlaps with the SMEM
+      and MPSS memory regions
+    - arm64: dts: qcom: msm8953: correct TLMM gpio-ranges
+    - arm64: dts: qcom: sm6115: correct TLMM gpio-ranges
+    - arm64: dts: qcom: msm8992-lg-bullhead: Enable regulators
+    - s390/dasd: Fix potential memleak in dasd_eckd_init()
+    - io_uring,audit: don't log IORING_OP_MADVISE
+    - sched/rt: pick_next_rt_entity(): check list_entry
+    - perf/x86/intel/ds: Fix the conversion from TSC to perf time
+    - x86/perf/zhaoxin: Add stepping check for ZXC
+    - KEYS: asymmetric: Fix ECDSA use via keyctl uapi
+    - block: ublk: check IO buffer based on flag need_get_data
+    - arm64: dts: qcom: pmk8350: Use the correct PON compatible
+    - erofs: relinquish volume with mutex held
+    - block: sync mixed merged request's failfast with 1st bio's
+    - block: Fix io statistics for cgroup in throttle path
+    - block: bio-integrity: Copy flags when bio_integrity_payload is cloned
+    - block: use proper return value from bio_failfast()
+    - wifi: mt76: mt7915: add missing of_node_put()
+    - wifi: mt76: mt7921s: fix slab-out-of-bounds access in sdio host
+    - wifi: mt76: mt7915: fix mt7915_rate_txpower_get() resource leaks
+    - wifi: mt76: mt7996: fix insecure data handling of mt7996_mcu_ie_countdown()
+    - wifi: mt76: mt7996: fix insecure data handling of
+      mt7996_mcu_rx_radar_detected()
+    - wifi: mt76: mt7996: fix integer handling issue of mt7996_rf_regval_set()
+    - wifi: mt76: mt7915: check return value before accessing free_block_num
+    - wifi: mt76: mt7996: check return value before accessing free_block_num
+    - wifi: mt76: mt7915: drop always true condition of __mt7915_reg_addr()
+    - wifi: mt76: mt7996: drop always true condition of __mt7996_reg_addr()
+    - wifi: mt76: mt7996: fix endianness warning in mt7996_mcu_sta_he_tlv
+    - wifi: mt76: mt76x0: fix oob access in mt76x0_phy_get_target_power
+    - wifi: mt76: mt7996: fix unintended sign extension of mt7996_hw_queue_read()
+    - wifi: mt76: mt7915: fix unintended sign extension of mt7915_hw_queue_read()
+    - wifi: mt76: fix coverity uninit_use_in_call in
+      mt76_connac2_reverse_frag0_hdr_trans()
+    - wifi: mt76: mt7921: resource leaks at mt7921_check_offload_capability()
+    - wifi: rsi: Fix memory leak in rsi_coex_attach()
+    - wifi: rtlwifi: rtl8821ae: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: rtlwifi: rtl8188ee: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: rtlwifi: rtl8723be: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: iwlegacy: common: don't call dev_kfree_skb() under spin_lock_irqsave()
+    - wifi: libertas: fix memory leak in lbs_init_adapter()
+    - wifi: rtl8xxxu: Fix assignment to bit field priv->pi_enabled
+    - wifi: rtl8xxxu: Fix assignment to bit field priv->cck_agc_report_type
+    - wifi: rtl8xxxu: don't call dev_kfree_skb() under spin_lock_irqsave()
+    - wifi: rtw89: 8852c: rfk: correct DACK setting
+    - wifi: rtw89: 8852c: rfk: correct DPK settings
+    - wifi: rtlwifi: Fix global-out-of-bounds bug in
+      _rtl8812ae_phy_set_txpower_limit()
+    - libbpf: Fix single-line struct definition output in btf_dump
+    - libbpf: Fix btf__align_of() by taking into account field offsets
+    - wifi: ipw2x00: don't call dev_kfree_skb() under spin_lock_irqsave()
+    - wifi: ipw2200: fix memory leak in ipw_wdev_init()
+    - wifi: wilc1000: fix potential memory leak in wilc_mac_xmit()
+    - wifi: wilc1000: add missing unregister_netdev() in wilc_netdev_ifc_init()
+    - wifi: brcmfmac: fix potential memory leak in brcmf_netdev_start_xmit()
+    - wifi: brcmfmac: unmap dma buffer in brcmf_msgbuf_alloc_pktid()
+    - wifi: libertas_tf: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: libertas: if_usb: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: libertas: main: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: libertas: cmdresp: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: wl3501_cs: don't call kfree_skb() under spin_lock_irqsave()
+    - libbpf: Fix invalid return address register in s390
+    - crypto: x86/ghash - fix unaligned access in ghash_setkey()
+    - crypto: ux500 - update debug config after ux500 cryp driver removal
+    - ACPICA: Drop port I/O validation for some regions
+    - genirq: Fix the return type of kstat_cpu_irqs_sum()
+    - rcu-tasks: Improve comments explaining tasks_rcu_exit_srcu purpose
+    - rcu-tasks: Remove preemption disablement around srcu_read_[un]lock() calls
+    - rcu-tasks: Fix synchronize_rcu_tasks() VS zap_pid_ns_processes()
+    - lib/mpi: Fix buffer overrun when SG is too long
+    - crypto: ccp - Avoid page allocation failure warning for SEV_GET_ID2
+    - platform/chrome: cros_ec_typec: Update port DP VDO
+    - ACPICA: nsrepair: handle cases without a return value correctly
+    - libbpf: Fix map creation flags sanitization
+    - bpf_doc: Fix build error with older python versions
+    - selftests/xsk: print correct payload for packet dump
+    - selftests/xsk: print correct error codes when exiting
+    - arm64/cpufeature: Fix field sign for DIT hwcap detection
+    - arm64/sysreg: Fix errors in 32 bit enumeration values
+    - kselftest/arm64: Fix syscall-abi for systems without 128 bit SME
+    - workqueue: Protects wq_unbound_cpumask with wq_pool_attach_mutex
+    - s390/early: fix sclp_early_sccb variable lifetime
+    - s390/vfio-ap: fix an error handling path in vfio_ap_mdev_probe_queue()
+    - x86/signal: Fix the value returned by strict_sas_size()
+    - thermal/drivers/tsens: Drop msm8976-specific defines
+    - thermal/drivers/tsens: Sort out msm8976 vs msm8956 data
+    - thermal/drivers/tsens: fix slope values for msm8939
+    - thermal/drivers/tsens: limit num_sensors to 9 for msm8939
+    - wifi: rtw89: fix potential leak in rtw89_append_probe_req_ie()
+    - wifi: rtw89: Add missing check for alloc_workqueue
+    - wifi: rtl8xxxu: Fix memory leaks with RTL8723BU, RTL8192EU
+    - wifi: orinoco: check return value of hermes_write_wordrec()
+    - wifi: rtw88: Use rtw_iterate_vifs() for rtw_vif_watch_dog_iter()
+    - wifi: rtw88: Use non-atomic sta iterator in rtw_ra_mask_info_update()
+    - thermal/drivers/imx_sc_thermal: Fix the loop condition
+    - wifi: ath9k: htc_hst: free skb in ath9k_htc_rx_msg() if there is no callback
+      function
+    - wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
+    - wifi: ath9k: Fix potential stack-out-of-bounds write in
+      ath9k_wmi_rsp_callback()
+    - wifi: ath11k: Fix memory leak in ath11k_peer_rx_frag_setup
+    - wifi: cfg80211: Fix extended KCK key length check in
+      nl80211_set_rekey_data()
+    - ACPI: battery: Fix missing NUL-termination with large strings
+    - selftests/bpf: Fix build errors if CONFIG_NF_CONNTRACK=m
+    - crypto: ccp - Failure on re-initialization due to duplicate sysfs filename
+    - crypto: essiv - Handle EBUSY correctly
+    - crypto: seqiv - Handle EBUSY correctly
+    - powercap: fix possible name leak in powercap_register_zone()
+    - bpf: Fix state pruning for STACK_DYNPTR stack slots
+    - bpf: Fix missing var_off check for ARG_PTR_TO_DYNPTR
+    - bpf: Fix partial dynptr stack slot reads/writes
+    - x86/microcode: Add a parameter to microcode_check() to store CPU
+      capabilities
+    - x86/microcode: Check CPU capabilities after late microcode update correctly
+    - x86/microcode: Adjust late loading result reporting message
+    - net: ethernet: ti: am65-cpsw/cpts: Fix CPTS release action
+    - selftests/bpf: Fix vmtest static compilation error
+    - crypto: xts - Handle EBUSY correctly
+    - leds: led-class: Add missing put_device() to led_put()
+    - drm/nouveau/disp: Fix nvif_outp_acquire_dp() argument size
+    - s390/bpf: Add expoline to tail calls
+    - wifi: iwlwifi: mei: fix compilation errors in rfkill()
+    - kselftest/arm64: Fix enumeration of systems without 128 bit SME
+    - can: rcar_canfd: Fix R-Car V3U CAN mode selection
+    - can: rcar_canfd: Fix R-Car V3U GAFLCFG field accesses
+    - selftests/bpf: Initialize tc in xdp_synproxy
+    - crypto: ccp - Flush the SEV-ES TMR memory before giving it to firmware
+    - bpftool: profile online CPUs instead of possible
+    - wifi: mt76: mt7921: fix deadlock in mt7921_abort_roc
+    - wifi: mt76: mt7915: call mt7915_mcu_set_thermal_throttling() only after
+      init_work
+    - wifi: mt76: mt7915: rework mt7915_mcu_set_thermal_throttling
+    - wifi: mt76: mt7915: rework mt7915_thermal_temp_store()
+    - wifi: mt76: mt7921: fix channel switch fail in monitor mode
+    - wifi: mt76: mt7996: fix chainmask calculation in mt7996_set_antenna()
+    - wifi: mt76: mt7996: update register for CFEND_RATE
+    - wifi: mt76: connac: fix POWER_CTRL command name typo
+    - wifi: mt76: mt7921: fix invalid remain_on_channel duration
+    - wifi: mt76: mt7915: fix memory leak in mt7915_mcu_exit
+    - wifi: mt76: mt7996: fix memory leak in mt7996_mcu_exit
+    - wifi: mt76: dma: fix memory leak running mt76_dma_tx_cleanup
+    - wifi: mt76: fix switch default case in mt7996_reverse_frag0_hdr_trans
+    - wifi: mt76: mt7915: fix WED TxS reporting
+    - wifi: mt76: add memory barrier to SDIO queue kick
+    - wifi: mt76: mt7996: rely on mt76_connac2_mac_tx_rate_val
+    - net/mlx5: Enhance debug print in page allocation failure
+    - irqchip: Fix refcount leak in platform_irqchip_probe
+    - irqchip/alpine-msi: Fix refcount leak in alpine_msix_init_domains
+    - irqchip/irq-mvebu-gicp: Fix refcount leak in mvebu_gicp_probe
+    - irqchip/ti-sci: Fix refcount leak in ti_sci_intr_irq_domain_probe
+    - s390/mem_detect: fix detect_memory() error handling
+    - s390/vmem: fix empty page tables cleanup under KASAN
+    - s390/boot: cleanup decompressor header files
+    - s390/mem_detect: rely on diag260() if sclp_early_get_memsize() fails
+    - s390/boot: fix mem_detect extended area allocation
+    - net: add sock_init_data_uid()
+    - tun: tun_chr_open(): correctly initialize socket uid
+    - tap: tap_open(): correctly initialize socket uid
+    - rxrpc: Fix overwaking on call poking
+    - OPP: fix error checking in opp_migrate_dentry()
+    - cpufreq: davinci: Fix clk use after free
+    - Bluetooth: hci_conn: Refactor hci_bind_bis() since it always succeeds
+    - Bluetooth: L2CAP: Fix potential user-after-free
+    - Bluetooth: hci_qca: get wakeup status from serdev device handle
+    - net: ipa: generic command param fix
+    - s390: vfio-ap: tighten the NIB validity check
+    - s390/ap: fix status returned by ap_aqic()
+    - s390/ap: fix status returned by ap_qact()
+    - libbpf: Fix alen calculation in libbpf_nla_dump_errormsg()
+    - xen/grant-dma-iommu: Implement a dummy probe_device() callback
+    - rds: rds_rm_zerocopy_callback() correct order for list_add_tail()
+    - crypto: rsa-pkcs1pad - Use akcipher_request_complete
+    - m68k: /proc/hardware should depend on PROC_FS
+    - RISC-V: time: initialize hrtimer based broadcast clock event device
+    - clocksource/drivers/riscv: Patch riscv_clock_next_event() jump before first
+      use
+    - wifi: iwl3945: Add missing check for create_singlethread_workqueue
+    - wifi: iwl4965: Add missing check for create_singlethread_workqueue()
+    - wifi: brcmfmac: Rename Cypress 89459 to BCM4355
+    - wifi: brcmfmac: pcie: Add IDs/properties for BCM4355
+    - wifi: brcmfmac: pcie: Add IDs/properties for BCM4377
+    - wifi: brcmfmac: pcie: Perform correct BCM4364 firmware selection
+    - wifi: mwifiex: fix loop iterator in mwifiex_update_ampdu_txwinsize()
+    - wifi: rtw89: fix parsing offset for MCC C2H
+    - selftests/bpf: Fix out-of-srctree build
+    - ACPI: resource: Add IRQ overrides for MAINGEAR Vector Pro 2 models
+    - ACPI: resource: Do IRQ override on all TongFang GMxRGxx
+    - crypto: octeontx2 - Fix objects shared between several modules
+    - crypto: crypto4xx - Call dma_unmap_page when done
+    - vfio/ccw: remove WARN_ON during shutdown
+    - wifi: mac80211: move color collision detection report in a delayed work
+    - wifi: mac80211: make rate u32 in sta_set_rate_info_rx()
+    - wifi: mac80211: fix non-MLO station association
+    - wifi: mac80211: Don't translate MLD addresses for multicast
+    - wifi: mac80211: avoid u32_encode_bits() warning
+    - wifi: mac80211: fix off-by-one link setting
+    - tools/lib/thermal: Fix thermal_sampling_exit()
+    - thermal/drivers/hisi: Drop second sensor hi3660
+    - selftests/bpf: Fix map_kptr test.
+    - wifi: mac80211: pass 'sta' to ieee80211_rx_data_set_sta()
+    - bpf: Zeroing allocated object from slab in bpf memory allocator
+    - selftests/bpf: Fix xdp_do_redirect on s390x
+    - can: esd_usb: Move mislocated storage of SJA1000_ECC_SEG bits in case of a
+      bus error
+    - can: esd_usb: Make use of can_change_state() and relocate checking skb for
+      NULL
+    - xsk: check IFF_UP earlier in Tx path
+    - LoongArch, bpf: Use 4 instructions for function address in JIT
+    - bpf: Fix global subprog context argument resolution logic
+    - irqchip/irq-brcmstb-l2: Set IRQ_LEVEL for level triggered interrupts
+    - irqchip/irq-bcm7120-l2: Set IRQ_LEVEL for level triggered interrupts
+    - net/smc: fix potential panic dues to unprotected smc_llc_srv_add_link()
+    - net/smc: fix application data exception
+    - selftests/net: Interpret UDP_GRO cmsg data as an int value
+    - l2tp: Avoid possible recursive deadlock in l2tp_tunnel_register()
+    - net: bcmgenet: fix MoCA LED control
+    - net: lan966x: Fix possible deadlock inside PTP
+    - net/mlx4_en: Introduce flexible array to silence overflow warning
+    - net/mlx5e: Align IPsec ASO result memory to be as required by hardware
+    - selftest: fib_tests: Always cleanup before exit
+    - sefltests: netdevsim: wait for devlink instance after netns removal
+    - drm: Fix potential null-ptr-deref due to drmm_mode_config_init()
+    - drm/fourcc: Add missing big-endian XRGB1555 and RGB565 formats
+    - drm/bridge: ti-sn65dsi83: Fix delay after reset deassert to match spec
+    - drm: mxsfb: DRM_IMX_LCDIF should depend on ARCH_MXC
+    - drm: mxsfb: DRM_MXSFB should depend on ARCH_MXS || ARCH_MXC
+    - drm/bridge: megachips: Fix error handling in i2c_register_driver()
+    - drm/vkms: Fix memory leak in vkms_init()
+    - drm/vkms: Fix null-ptr-deref in vkms_release()
+    - drm/modes: Use strscpy() to copy command-line mode name
+    - drm/vc4: dpi: Fix format mapping for RGB565
+    - drm/bridge: it6505: Guard bridge power in IRQ handler
+    - drm: tidss: Fix pixel format definition
+    - gpu: ipu-v3: common: Add of_node_put() for reference returned by
+      of_graph_get_port_by_id()
+    - drm/ast: Init iosys_map pointer as I/O memory for damage handling
+    - drm/vc4: drop all currently held locks if deadlock happens
+    - hwmon: (ftsteutates) Fix scaling of measurements
+    - drm/msm/dpu: check for null return of devm_kzalloc() in dpu_writeback_init()
+    - drm/msm/hdmi: Add missing check for alloc_ordered_workqueue
+    - pinctrl: qcom: pinctrl-msm8976: Correct function names for wcss pins
+    - pinctrl: stm32: Fix refcount leak in stm32_pctrl_get_irq_domain
+    - pinctrl: rockchip: Fix refcount leak in rockchip_pinctrl_parse_groups
+    - drm/vc4: hvs: Configure the HVS COB allocations
+    - drm/vc4: hvs: Set AXI panic modes
+    - drm/vc4: hvs: SCALER_DISPBKGND_AUTOHS is only valid on HVS4
+    - drm/vc4: hvs: Correct interrupt masking bit assignment for HVS5
+    - drm/vc4: hvs: Fix colour order for xRGB1555 on HVS5
+    - drm/vc4: hdmi: Correct interlaced timings again
+    - drm/msm: clean event_thread->worker in case of an error
+    - drm/panel-edp: fix name for IVO product id 854b
+    - scsi: qla2xxx: Fix exchange oversubscription
+    - scsi: qla2xxx: Fix exchange oversubscription for management commands
+    - scsi: qla2xxx: edif: Fix clang warning
+    - ASoC: fsl_sai: initialize is_dsp_mode flag
+    - drm/bridge: tc358767: Set default CLRSIPO count
+    - drm/msm/adreno: Fix null ptr access in adreno_gpu_cleanup()
+    - ALSA: hda/ca0132: minor fix for allocation size
+    - drm/amdgpu: Use the sched from entity for amdgpu_cs trace
+    - drm/msm/gem: Add check for kmalloc
+    - drm/msm/dpu: Disallow unallocated resources to be returned
+    - drm/bridge: lt9611: fix sleep mode setup
+    - drm/bridge: lt9611: fix HPD reenablement
+    - drm/bridge: lt9611: fix polarity programming
+    - drm/bridge: lt9611: fix programming of video modes
+    - drm/bridge: lt9611: fix clock calculation
+    - drm/bridge: lt9611: pass a pointer to the of node
+    - regulator: tps65219: use IS_ERR() to detect an error pointer
+    - drm/mipi-dsi: Fix byte order of 16-bit DCS set/get brightness
+    - drm: exynos: dsi: Fix MIPI_DSI*_NO_* mode flags
+    - drm/msm/dsi: Allow 2 CTRLs on v2.5.0
+    - scsi: ufs: exynos: Fix DMA alignment for PAGE_SIZE != 4096
+    - drm/msm/dpu: sc7180: add missing WB2 clock control
+    - drm/msm: use strscpy instead of strncpy
+    - drm/msm/dpu: Add check for cstate
+    - drm/msm/dpu: Add check for pstates
+    - drm/msm/mdp5: Add check for kzalloc
+    - habanalabs: bugs fixes in timestamps buff alloc
+    - pinctrl: bcm2835: Remove of_node_put() in bcm2835_of_gpio_ranges_fallback()
+    - pinctrl: mediatek: Initialize variable pullen and pullup to zero
+    - pinctrl: mediatek: Initialize variable *buf to zero
+    - gpu: host1x: Fix mask for syncpoint increment register
+    - gpu: host1x: Don't skip assigning syncpoints to channels
+    - drm/tegra: firewall: Check for is_addr_reg existence in IMM check
+    - drm/i915/mtl: Add initial gt workarounds
+    - drm/i915/xehp: GAM registers don't need to be re-applied on engine resets
+    - pinctrl: renesas: rzg2l: Fix configuring the GPIO pins as interrupts
+    - drm/i915/xehp: Annotate a couple more workaround registers as MCR
+    - drm/msm/dpu: set pdpu->is_rt_pipe early in dpu_plane_sspp_atomic_update()
+    - drm/mediatek: dsi: Reduce the time of dsi from LP11 to sending cmd
+    - drm/mediatek: Use NULL instead of 0 for NULL pointer
+    - drm/mediatek: Drop unbalanced obj unref
+    - drm/mediatek: mtk_drm_crtc: Add checks for devm_kcalloc
+    - drm/mediatek: Clean dangling pointer on bind error path
+    - ASoC: soc-compress.c: fixup private_data on snd_soc_new_compress()
+    - dt-bindings: display: mediatek: Fix the fallback for mediatek,mt8186-disp-
+      ccorr
+    - gpio: pca9570: rename platform_data to chip_data
+    - gpio: vf610: connect GPIO label to dev name
+    - ASoC: topology: Properly access value coming from topology file
+    - spi: dw_bt1: fix MUX_MMIO dependencies
+    - ASoC: mchp-spdifrx: fix controls which rely on rsr register
+    - ASoC: mchp-spdifrx: fix return value in case completion times out
+    - ASoC: mchp-spdifrx: fix controls that works with completion mechanism
+    - ASoC: mchp-spdifrx: disable all interrupts in mchp_spdifrx_dai_remove()
+    - dm: improve shrinker debug names
+    - regmap: apply reg_base and reg_downshift for single register ops
+    - accel: fix CONFIG_DRM dependencies
+    - ASoC: rsnd: fixup #endif position
+    - ASoC: mchp-spdifrx: Fix uninitialized use of mr in mchp_spdifrx_hw_params()
+    - ASoC: dt-bindings: meson: fix gx-card codec node regex
+    - regulator: tps65219: use generic set_bypass()
+    - hwmon: (asus-ec-sensors) add missing mutex path
+    - hwmon: (ltc2945) Handle error case in ltc2945_value_store
+    - ALSA: hda: Fix the control element identification for multiple codecs
+    - drm/amdgpu: fix enum odm_combine_mode mismatch
+    - scsi: mpt3sas: Fix a memory leak
+    - scsi: aic94xx: Add missing check for dma_map_single()
+    - HID: multitouch: Add quirks for flipped axes
+    - HID: retain initial quirks set up when creating HID devices
+    - ASoC: qcom: q6apm-lpass-dai: unprepare stream if its already prepared
+    - ASoC: qcom: q6apm-dai: fix race condition while updating the position
+      pointer
+    - ASoC: qcom: q6apm-dai: Add SNDRV_PCM_INFO_BATCH flag
+    - ASoC: codecs: lpass: register mclk after runtime pm
+    - ASoC: codecs: lpass: fix incorrect mclk rate
+    - drm/amd/display: don't call dc_interrupt_set() for disabled crtcs
+    - HID: logitech-hidpp: Hard-code HID++ 1.0 fast scroll support
+    - spi: bcm63xx-hsspi: Fix multi-bit mode setting
+    - hwmon: (mlxreg-fan) Return zero speed for broken fan
+    - ASoC: tlv320adcx140: fix 'ti,gpio-config' DT property init
+    - dm: remove flush_scheduled_work() during local_exit()
+    - nfs4trace: fix state manager flag printing
+    - NFS: fix disabling of swap
+    - drm/i915/pvc: Implement recommended caching policy
+    - drm/i915/pvc: Annotate two more workaround/tuning registers as MCR
+    - drm/i915: Fix GEN8_MISCCPCTL
+    - spi: synquacer: Fix timeout handling in synquacer_spi_transfer_one()
+    - ASoC: soc-dapm.h: fixup warning struct snd_pcm_substream not declared
+    - HID: bigben: use spinlock to protect concurrent accesses
+    - HID: bigben_worker() remove unneeded check on report_field
+    - HID: bigben: use spinlock to safely schedule workers
+    - hid: bigben_probe(): validate report count
+    - ALSA: hda/hdmi: Register with vga_switcheroo on Dual GPU Macbooks
+    - drm/shmem-helper: Fix locking for drm_gem_shmem_get_pages_sgt()
+    - NFSD: enhance inter-server copy cleanup
+    - NFSD: fix leaked reference count of nfsd4_ssc_umount_item
+    - nfsd: fix race to check ls_layouts
+    - nfsd: clean up potential nfsd_file refcount leaks in COPY codepath
+    - NFSD: fix problems with cleanup on errors in nfsd4_copy
+    - nfsd: fix courtesy client with deny mode handling in nfs4_upgrade_open
+    - nfsd: don't fsync nfsd_files on last close
+    - NFSD: copy the whole verifier in nfsd_copy_write_verifier
+    - cifs: Fix lost destroy smbd connection when MR allocate failed
+    - cifs: Fix warning and UAF when destroy the MR list
+    - cifs: use tcon allocation functions even for dummy tcon
+    - gfs2: jdata writepage fix
+    - perf llvm: Fix inadvertent file creation
+    - leds: led-core: Fix refcount leak in of_led_get()
+    - leds: is31fl319x: Wrap mutex_destroy() for devm_add_action_or_rest()
+    - leds: simatic-ipc-leds-gpio: Make sure we have the GPIO providing driver
+    - tools/tracing/rtla: osnoise_hist: use total duration for average calculation
+    - perf inject: Use perf_data__read() for auxtrace
+    - perf intel-pt: Do not try to queue auxtrace data on pipe
+    - perf stat: Hide invalid uncore event output for aggr mode
+    - perf jevents: Correct bad character encoding
+    - perf test bpf: Skip test if kernel-debuginfo is not present
+    - perf tools: Fix auto-complete on aarch64
+    - perf stat: Avoid merging/aggregating metric counts twice
+    - sparc: allow PM configs for sparc32 COMPILE_TEST
+    - selftests: find echo binary to use -ne options
+    - selftests/ftrace: Fix bash specific "==" operator
+    - selftests: use printf instead of echo -ne
+    - perf record: Fix segfault with --overwrite and --max-size
+    - printf: fix errname.c list
+    - perf tests stat_all_metrics: Change true workload to sleep workload for
+      system wide check
+    - objtool: add UACCESS exceptions for __tsan_volatile_read/write
+    - selftests/ftrace: Fix probepoint testcase to ignore __pfx_* symbols
+    - sysctl: fix proc_dobool() usability
+    - mfd: rk808: Re-add rk808-clkout to RK818
+    - mfd: cs5535: Don't build on UML
+    - mfd: pcf50633-adc: Fix potential memleak in pcf50633_adc_async_read()
+    - dmaengine: idxd: Set traffic class values in GRPCFG on DSA 2.0
+    - RDMA/erdma: Fix refcount leak in erdma_mmap
+    - dmaengine: HISI_DMA should depend on ARCH_HISI
+    - RDMA/hns: Fix refcount leak in hns_roce_mmap
+    - iio: light: tsl2563: Do not hardcode interrupt trigger type
+    - usb: gadget: fusb300_udc: free irq on the error path in fusb300_probe()
+    - i2c: designware: fix i2c_dw_clk_rate() return size to be u32
+    - i2c: qcom-geni: change i2c_master_hub to static
+    - soundwire: cadence: Don't overflow the command FIFOs
+    - driver core: fix potential null-ptr-deref in device_add()
+    - kobject: Fix slab-out-of-bounds in fill_kobj_path()
+    - alpha/boot/tools/objstrip: fix the check for ELF header
+    - media: uvcvideo: Check for INACTIVE in uvc_ctrl_is_accessible()
+    - media: uvcvideo: Implement mask for V4L2_CTRL_TYPE_MENU
+    - media: uvcvideo: Refactor uvc_ctrl_mappings_uvcXX
+    - media: uvcvideo: Refactor power_line_frequency_controls_limited
+    - coresight: etm4x: Fix accesses to TRCSEQRSTEVR and TRCSEQSTR
+    - coresight: cti: Prevent negative values of enable count
+    - coresight: cti: Add PM runtime call in enable_store
+    - usb: typec: intel_pmc_mux: Don't leak the ACPI device reference count
+    - PCI/IOV: Enlarge virtfn sysfs name buffer
+    - PCI: switchtec: Return -EFAULT for copy_to_user() errors
+    - PCI: endpoint: pci-epf-vntb: Add epf_ntb_mw_bar_clear() num_mws kernel-doc
+    - hwtracing: hisi_ptt: Only add the supported devices to the filters list
+    - tty: serial: fsl_lpuart: disable Rx/Tx DMA in lpuart32_shutdown()
+    - tty: serial: fsl_lpuart: clear LPUART Status Register in lpuart32_shutdown()
+    - serial: tegra: Add missing clk_disable_unprepare() in tegra_uart_hw_init()
+    - Revert "char: pcmcia: cm4000_cs: Replace mdelay with usleep_range in
+      set_protocol"
+    - eeprom: idt_89hpesx: Fix error handling in idt_init()
+    - applicom: Fix PCI device refcount leak in applicom_init()
+    - firmware: stratix10-svc: add missing gen_pool_destroy() in
+      stratix10_svc_drv_probe()
+    - firmware: stratix10-svc: fix error handle while alloc/add device failed
+    - VMCI: check context->notify_page after call to get_user_pages_fast() to
+      avoid GPF
+    - mei: pxp: Use correct macros to initialize uuid_le
+    - misc/mei/hdcp: Use correct macros to initialize uuid_le
+    - misc: fastrpc: Fix an error handling path in fastrpc_rpmsg_probe()
+    - iommu/exynos: Fix error handling in exynos_iommu_init()
+    - driver core: fix resource leak in device_add()
+    - driver core: location: Free struct acpi_pld_info *pld before return false
+    - drivers: base: transport_class: fix possible memory leak
+    - drivers: base: transport_class: fix resource leak when
+      transport_add_device() fails
+    - firmware: dmi-sysfs: Fix null-ptr-deref in dmi_sysfs_register_handle
+    - selftests: iommu: Fix test_cmd_destroy_access() call in user_copy
+    - iommufd: Add three missing structures in ucmd_buffer
+    - fotg210-udc: Add missing completion handler
+    - dmaengine: dw-edma: Fix missing src/dst address of interleaved xfers
+    - fpga: microchip-spi: move SPI I/O buffers out of stack
+    - fpga: microchip-spi: rewrite status polling in a time measurable way
+    - usb: early: xhci-dbc: Fix a potential out-of-bound memory access
+    - tty: serial: fsl_lpuart: Fix the wrong RXWATER setting for rx dma case
+    - RDMA/cxgb4: add null-ptr-check after ip_dev_find()
+    - usb: musb: mediatek: don't unregister something that wasn't registered
+    - usb: gadget: configfs: Restrict symlink creation is UDC already binded
+    - phy: mediatek: remove temporary variable @mask_
+    - PCI: mt7621: Delay phy ports initialization
+    - iommu/vt-d: Set No Execute Enable bit in PASID table entry
+    - power: supply: remove faulty cooling logic
+    - RDMA/siw: Fix user page pinning accounting
+    - RDMA/cxgb4: Fix potential null-ptr-deref in pass_establish()
+    - usb: max-3421: Fix setting of I/O pins
+    - RDMA/irdma: Cap MSIX used to online CPUs + 1
+    - serial: fsl_lpuart: fix RS485 RTS polariy inverse issue
+    - tty: serial: imx: disable Ageing Timer interrupt request irq
+    - driver core: fw_devlink: Add DL_FLAG_CYCLE support to device links
+    - driver core: fw_devlink: Don't purge child fwnode's consumer links
+    - driver core: fw_devlink: Allow marking a fwnode link as being part of a
+      cycle
+    - driver core: fw_devlink: Consolidate device link flag computation
+    - driver core: fw_devlink: Improve check for fwnode with no device/driver
+    - driver core: fw_devlink: Make cycle detection more robust
+    - mtd: mtdpart: Don't create platform device that'll never probe
+    - usb: host: fsl-mph-dr-of: reuse device_set_of_node_from_dev
+    - dmaengine: dw-edma: Fix readq_ch() return value truncation
+    - PCI: Fix dropping valid root bus resources with .end = zero
+    - phy: rockchip-typec: fix tcphy_get_mode error case
+    - PCI: qcom: Fix host-init error handling
+    - iw_cxgb4: Fix potential NULL dereference in c4iw_fill_res_cm_id_entry()
+    - iommu: Fix error unwind in iommu_group_alloc()
+    - iommu/amd: Do not identity map v2 capable device when snp is enabled
+    - dmaengine: sf-pdma: pdma_desc memory leak fix
+    - dmaengine: dw-axi-dmac: Do not dereference NULL structure
+    - dmaengine: ptdma: check for null desc before calling pt_cmd_callback
+    - iommu/vt-d: Fix error handling in sva enable/disable paths
+    - iommu/vt-d: Allow to use flush-queue when first level is default
+    - RDMA/rxe: Cleanup mr_check_range
+    - RDMA/rxe: Move rxe_map_mr_sg to rxe_mr.c
+    - RDMA-rxe: Isolate mr code from atomic_reply()
+    - RDMA-rxe: Isolate mr code from atomic_write_reply()
+    - RDMA/rxe: Cleanup page variables in rxe_mr.c
+    - RDMA/rxe: Replace rxe_map and rxe_phys_buf by xarray
+    - Subject: RDMA/rxe: Handle zero length rdma
+    - RDMA/mana_ib: Fix a bug when the PF indicates more entries for registering
+      memory on first packet
+    - RDMA/rxe: Fix missing memory barriers in rxe_queue.h
+    - IB/hfi1: Fix math bugs in hfi1_can_pin_pages()
+    - IB/hfi1: Fix sdma.h tx->num_descs off-by-one errors
+    - Revert "remoteproc: qcom_q6v5_mss: map/unmap metadata region before/after
+      use"
+    - remoteproc: qcom_q6v5_mss: Use a carveout to authenticate modem headers
+    - media: ti: cal: fix possible memory leak in cal_ctx_create()
+    - media: platform: ti: Add missing check for devm_regulator_get
+    - media: imx: imx7-media-csi: fix missing clk_disable_unprepare() in
+      imx7_csi_init()
+    - powerpc: Remove linker flag from KBUILD_AFLAGS
+    - s390/vdso: Drop '-shared' from KBUILD_CFLAGS_64
+    - builddeb: clean generated package content
+    - media: max9286: Fix memleak in max9286_v4l2_register()
+    - media: ov2740: Fix memleak in ov2740_init_controls()
+    - media: ov5675: Fix memleak in ov5675_init_controls()
+    - media: i2c: tc358746: fix missing return assignment
+    - media: i2c: tc358746: fix ignoring read error in g_register callback
+    - media: i2c: tc358746: fix possible endianness issue
+    - media: ov5640: Fix soft reset sequence and timings
+    - media: ov5640: Handle delays when no reset_gpio set
+    - media: mc: Get media_device directly from pad
+    - media: i2c: ov772x: Fix memleak in ov772x_probe()
+    - media: i2c: imx219: Split common registers from mode tables
+    - media: i2c: imx219: Fix binning for RAW8 capture
+    - media: platform: mtk-mdp3: Fix return value check in mdp_probe()
+    - media: camss: csiphy-3ph: avoid undefined behavior
+    - media: platform: mtk-mdp3: fix Kconfig dependencies
+    - media: v4l2-jpeg: correct the skip count in jpeg_parse_app14_data
+    - media: v4l2-jpeg: ignore the unknown APP14 marker
+    - media: hantro: Fix JPEG encoder ENUM_FRMSIZE on RK3399
+    - media: imx-jpeg: Apply clk_bulk api instead of operating specific clk
+    - media: amphion: correct the unspecified color space
+    - media: drivers/media/v4l2-core/v4l2-h264 : add detection of null pointers
+    - media: rc: Fix use-after-free bugs caused by ene_tx_irqsim()
+    - media: atomisp: fix videobuf2 Kconfig depenendency
+    - media: atomisp: Only set default_run_mode on first open of a stream/asd
+    - media: i2c: ov7670: 0 instead of -EINVAL was returned
+    - media: usb: siano: Fix use after free bugs caused by do_submit_urb
+    - media: saa7134: Use video_unregister_device for radio_dev
+    - rpmsg: glink: Avoid infinite loop on intent for missing channel
+    - rpmsg: glink: Release driver_override
+    - ARM: OMAP2+: omap4-common: Fix refcount leak bug
+    - arm64: dts: qcom: msm8996: Add additional A2NoC clocks
+    - udf: Define EFSCORRUPTED error code
+    - context_tracking: Fix noinstr vs KASAN
+    - exit: Detect and fix irq disabled state in oops
+    - ARM: dts: exynos: Use Exynos5420 compatible for the MIPI video phy
+    - fs: Use CHECK_DATA_CORRUPTION() when kernel bugs are detected
+    - blk-iocost: fix divide by 0 error in calc_lcoefs()
+    - blk-cgroup: dropping parent refcount after pd_free_fn() is done
+    - blk-cgroup: synchronize pd_free_fn() from blkg_free_workfn() and
+      blkcg_deactivate_policy()
+    - trace/blktrace: fix memory leak with using debugfs_lookup()
+    - btrfs: scrub: improve tree block error reporting
+    - arm64: zynqmp: Enable hs termination flag for USB dwc3 controller
+    - cpuidle, intel_idle: Fix CPUIDLE_FLAG_INIT_XSTATE
+    - x86/fpu: Don't set TIF_NEED_FPU_LOAD for PF_IO_WORKER threads
+    - cpuidle: drivers: firmware: psci: Dont instrument suspend code
+    - cpuidle: lib/bug: Disable rcu_is_watching() during WARN/BUG
+    - perf/x86/intel/uncore: Add Meteor Lake support
+    - wifi: ath9k: Fix use-after-free in ath9k_hif_usb_disconnect()
+    - wifi: ath11k: fix monitor mode bringup crash
+    - wifi: brcmfmac: Fix potential stack-out-of-bounds in brcmf_c_preinit_dcmds()
+    - rcu: Make RCU_LOCKDEP_WARN() avoid early lockdep checks
+    - rcu: Suppress smp_processor_id() complaint in
+      synchronize_rcu_expedited_wait()
+    - srcu: Delegate work to the boot cpu if using SRCU_SIZE_SMALL
+    - rcu-tasks: Make rude RCU-Tasks work well with CPU hotplug
+    - rcu-tasks: Handle queue-shrink/callback-enqueue race condition
+    - wifi: ath11k: debugfs: fix to work with multiple PCI devices
+    - thermal: intel: Fix unsigned comparison with less than zero
+    - timers: Prevent union confusion from unexpected restart_syscall()
+    - x86/bugs: Reset speculation control settings on init
+    - bpftool: Always disable stack protection for BPF objects
+    - wifi: brcmfmac: ensure CLM version is null-terminated to prevent stack-out-
+      of-bounds
+    - wifi: rtw89: fix assignation of TX BD RAM table
+    - wifi: mt7601u: fix an integer underflow
+    - inet: fix fast path in __inet_hash_connect()
+    - ice: restrict PTP HW clock freq adjustments to 100, 000, 000 PPB
+    - ice: add missing checks for PF vsi type
+    - Compiler attributes: GCC cold function alignment workarounds
+    - ACPI: Don't build ACPICA with '-Os'
+    - bpf, docs: Fix modulo zero, division by zero, overflow, and underflow
+    - thermal: intel: intel_pch: Add support for Wellsburg PCH
+    - clocksource: Suspend the watchdog temporarily when high read latency
+      detected
+    - crypto: hisilicon: Wipe entire pool on error
+    - net: bcmgenet: Add a check for oversized packets
+    - m68k: Check syscall_trace_enter() return code
+    - s390/mm,ptdump: avoid Kasan vs Memcpy Real markers swapping
+    - netfilter: nf_tables: NULL pointer dereference in nf_tables_updobj()
+    - can: isotp: check CAN address family in isotp_bind()
+    - gcc-plugins: drop -std=gnu++11 to fix GCC 13 build
+    - tools/power/x86/intel-speed-select: Add Emerald Rapid quirk
+    - platform/x86: dell-ddv: Add support for interface version 3
+    - wifi: mt76: dma: free rx_head in mt76_dma_rx_cleanup
+    - ACPI: video: Fix Lenovo Ideapad Z570 DMI match
+    - net/mlx5: fw_tracer: Fix debug print
+    - coda: Avoid partial allocation of sig_inputArgs
+    - uaccess: Add minimum bounds check on kernel buffer size
+    - s390/idle: mark arch_cpu_idle() noinstr
+    - time/debug: Fix memory leak with using debugfs_lookup()
+    - PM: domains: fix memory leak with using debugfs_lookup()
+    - PM: EM: fix memory leak with using debugfs_lookup()
+    - Bluetooth: Fix issue with Actions Semi ATS2851 based devices
+    - Bluetooth: btusb: Add new PID/VID 0489:e0f2 for MT7921
+    - Bluetooth: btusb: Add VID:PID 13d3:3529 for Realtek RTL8821CE
+    - wifi: rtw89: debug: avoid invalid access on RTW89_DBG_SEL_MAC_30
+    - hv_netvsc: Check status in SEND_RNDIS_PKT completion message
+    - s390/kfence: fix page fault reporting
+    - devlink: Fix TP_STRUCT_entry in trace of devlink health report
+    - scm: add user copy checks to put_cmsg()
+    - drm: panel-orientation-quirks: Add quirk for Lenovo Yoga Tab 3 X90F
+    - drm: panel-orientation-quirks: Add quirk for DynaBook K50
+    - drm/amd/display: Reduce expected sdp bandwidth for dcn321
+    - drm/amd/display: Revert Reduce delay when sink device not able to ACK 00340h
+      write
+    - drm/amd/display: Fix potential null-deref in dm_resume
+    - drm/omap: dsi: Fix excessive stack usage
+    - HID: Add Mapping for System Microphone Mute
+    - drm/tiny: ili9486: Do not assume 8-bit only SPI controllers
+    - drm/amd/display: Defer DIG FIFO disable after VID stream enable
+    - drm/radeon: free iio for atombios when driver shutdown
+    - drm/amd: Avoid BUG() for case of SRIOV missing IP version
+    - drm/amdkfd: Page aligned memory reserve size
+    - scsi: lpfc: Fix use-after-free KFENCE violation during sysfs firmware write
+    - Revert "fbcon: don't lose the console font across generic->chip driver
+      switch"
+    - drm/amd: Avoid ASSERT for some message failures
+    - drm: amd: display: Fix memory leakage
+    - drm/amd/display: fix mapping to non-allocated address
+    - HID: uclogic: Add frame type quirk
+    - HID: uclogic: Add battery quirk
+    - HID: uclogic: Add support for XP-PEN Deco Pro SW
+    - HID: uclogic: Add support for XP-PEN Deco Pro MW
+    - drm/msm/dsi: Add missing check for alloc_ordered_workqueue
+    - drm: rcar-du: Add quirk for H3 ES1.x pclk workaround
+    - drm: rcar-du: Fix setting a reserved bit in DPLLCR
+    - drm/drm_print: correct format problem
+    - drm/amd/display: Set hvm_enabled flag for S/G mode
+    - drm/client: Test for connectors before sending hotplug event
+    - habanalabs: extend fatal messages to contain PCI info
+    - habanalabs: fix bug in timestamps registration code
+    - docs/scripts/gdb: add necessary make scripts_gdb step
+    - drm/msm/dpu: Add DSC hardware blocks to register snapshot
+    - ASoC: soc-compress: Reposition and add pcm_mutex
+    - ASoC: kirkwood: Iterate over array indexes instead of using pointer math
+    - regulator: max77802: Bounds check regulator id against opmode
+    - regulator: s5m8767: Bounds check id indexing into arrays
+    - Revert "drm/amdgpu: TA unload messages are not actually sent to psp when
+      amdgpu is uninstalled"
+    - drm/amd/display: fix FCLK pstate change underflow
+    - gfs2: Improve gfs2_make_fs_rw error handling
+    - hwmon: (coretemp) Simplify platform device handling
+    - hwmon: (nct6775) Directly call ASUS ACPI WMI method
+    - hwmon: (nct6775) B650/B660/X670 ASUS boards support
+    - pinctrl: at91: use devm_kasprintf() to avoid potential leaks
+    - drm/amd/display: Do not commit pipe when updating DRR
+    - scsi: snic: Fix memory leak with using debugfs_lookup()
+    - scsi: ufs: core: Fix device management cmd timeout flow
+    - HID: logitech-hidpp: Don't restart communication if not necessary
+    - drm/amd/display: Enable P-state validation checks for DCN314
+    - drm: panel-orientation-quirks: Add quirk for Lenovo IdeaPad Duet 3 10IGL5
+    - drm/amd/display: Disable HUBP/DPP PG on DCN314 for now
+    - drm/amd/display: disable SubVP + DRR to prevent underflow
+    - dm thin: add cond_resched() to various workqueue loops
+    - dm cache: add cond_resched() to various workqueue loops
+    - nfsd: zero out pointers after putting nfsd_files on COPY setup error
+    - nfsd: don't hand out delegation on setuid files being opened for write
+    - cifs: prevent data race in smb2_reconnect()
+    - drm/i915/mtl: Correct implementation of Wa_18018781329
+    - drm/shmem-helper: Revert accidental non-GPL export
+    - driver core: fw_devlink: Avoid spurious error message
+    - wifi: rtl8xxxu: fixing transmisison failure for rtl8192eu
+    - firmware: coreboot: framebuffer: Ignore reserved pixel color bits
+    - block: don't allow multiple bios for IOCB_NOWAIT issue
+    - block: clear bio->bi_bdev when putting a bio back in the cache
+    - block: be a bit more careful in checking for NULL bdev while polling
+    - rtc: pm8xxx: fix set-alarm race
+    - ipmi: ipmb: Fix the MODULE_PARM_DESC associated to 'retry_time_ms'
+    - ipmi:ssif: resend_msg() cannot fail
+    - ipmi_ssif: Rename idle state and check
+    - ipmi:ssif: Add a timer between request retries
+    - io_uring: Replace 0-length array with flexible array
+    - io_uring: use user visible tail in io_uring_poll()
+    - io_uring: handle TIF_NOTIFY_RESUME when checking for task_work
+    - io_uring: add a conditional reschedule to the IOPOLL cancelation loop
+    - io_uring: add reschedule point to handle_tw_list()
+    - io_uring/rsrc: disallow multi-source reg buffers
+    - io_uring: remove MSG_NOSIGNAL from recvmsg
+    - io_uring/poll: allow some retries for poll triggering spuriously
+    - io_uring: fix fget leak when fs don't support nowait buffered read
+    - s390/extmem: return correct segment type in __segment_load()
+    - s390: discard .interp section
+    - s390/kprobes: fix irq mask clobbering on kprobe reenter from post_handler
+    - s390/kprobes: fix current_kprobe never cleared after kprobes reenter
+    - KVM: s390: disable migration mode when dirty tracking is disabled
+    - cifs: improve checking of DFS links over STATUS_OBJECT_NAME_INVALID
+    - cifs: Fix uninitialized memory read in smb3_qfs_tcon()
+    - cifs: Fix uninitialized memory reads for oparms.mode
+    - cifs: fix mount on old smb servers
+    - cifs: introduce cifs_io_parms in smb2_async_writev()
+    - cifs: split out smb3_use_rdma_offload() helper
+    - cifs: don't try to use rdma offload on encrypted connections
+    - cifs: Check the lease context if we actually got a lease
+    - cifs: return a single-use cfid if we did not get a lease
+    - scsi: mpi3mr: Fix missing mrioc->evtack_cmds initialization
+    - scsi: mpi3mr: Fix issues in mpi3mr_get_all_tgt_info()
+    - scsi: mpi3mr: Remove unnecessary memcpy() to alltgt_info->dmi
+    - btrfs: hold block group refcount during async discard
+    - btrfs: sysfs: update fs features directory asynchronously
+    - locking/rwsem: Prevent non-first waiter from spinning in down_write()
+      slowpath
+    - ksmbd: fix wrong data area length for smb2 lock request
+    - ksmbd: do not allow the actual frame length to be smaller than the rfc1002
+      length
+    - ksmbd: fix possible memory leak in smb2_lock()
+    - torture: Fix hang during kthread shutdown phase
+    - ARM: dts: exynos: correct HDMI phy compatible in Exynos4
+    - io_uring: mark task TASK_RUNNING before handling resume/task work
+    - hfs: fix missing hfs_bnode_get() in __hfs_bnode_create
+    - fs: hfsplus: fix UAF issue in hfsplus_put_super
+    - exfat: fix reporting fs error when reading dir beyond EOF
+    - exfat: fix unexpected EOF while reading dir
+    - exfat: redefine DIR_DELETED as the bad cluster number
+    - exfat: fix inode->i_blocks for non-512 byte sector size device
+    - fs: dlm: start midcomms before scand
+    - fs: dlm: fix use after free in midcomms commit
+    - fs: dlm: be sure to call dlm_send_queue_flush()
+    - fs: dlm: fix race setting stop tx flag
+    - fs: dlm: don't set stop rx flag after node reset
+    - fs: dlm: move sending fin message into state change handling
+    - fs: dlm: send FIN ack back in right cases
+    - f2fs: fix information leak in f2fs_move_inline_dirents()
+    - f2fs: retry to update the inode page given data corruption
+    - f2fs: fix cgroup writeback accounting with fs-layer encryption
+    - f2fs: fix kernel crash due to null io->bio
+    - f2fs: Revert "f2fs: truncate blocks in batch in __complete_revoke_list()"
+    - ocfs2: fix defrag path triggering jbd2 ASSERT
+    - ocfs2: fix non-auto defrag path not working issue
+    - fs/cramfs/inode.c: initialize file_ra_state
+    - selftests/landlock: Skip overlayfs tests when not supported
+    - selftests/landlock: Test ptrace as much as possible with Yama
+    - udf: Truncate added extents on failed expansion
+    - udf: Do not bother merging very long extents
+    - udf: Do not update file length for failed writes to inline files
+    - udf: Preserve link count of system files
+    - udf: Detect system inodes linked into directory hierarchy
+    - udf: Fix file corruption when appending just after end of preallocated
+      extent
+    - md: don't update recovery_cp when curr_resync is ACTIVE
+    - KVM: Destroy target device if coalesced MMIO unregistration fails
+    - KVM: VMX: Fix crash due to uninitialized current_vmcs
+    - KVM: Register /dev/kvm as the _very_ last thing during initialization
+    - KVM: x86: Purge "highest ISR" cache when updating APICv state
+    - KVM: x86: Blindly get current x2APIC reg value on "nodecode write" traps
+    - KVM: x86: Don't inhibit APICv/AVIC on xAPIC ID "change" if APIC is disabled
+    - KVM: x86: Don't inhibit APICv/AVIC if xAPIC ID mismatch is due to 32-bit ID
+    - KVM: SVM: Flush the "current" TLB when activating AVIC
+    - KVM: SVM: Process ICR on AVIC IPI delivery failure due to invalid target
+    - KVM: SVM: Don't put/load AVIC when setting virtual APIC mode
+    - KVM: x86: Inject #GP if WRMSR sets reserved bits in APIC Self-IPI
+    - KVM: x86: Inject #GP on x2APIC WRMSR that sets reserved bits 63:32
+    - KVM: SVM: Fix potential overflow in SEV's send|receive_update_data()
+    - KVM: SVM: hyper-v: placate modpost section mismatch error
+    - selftests: x86: Fix incorrect kernel headers search path
+    - x86/virt: Force GIF=1 prior to disabling SVM (for reboot flows)
+    - x86/crash: Disable virt in core NMI crash handler to avoid double shootdown
+    - x86/reboot: Disable virtualization in an emergency if SVM is supported
+    - x86/reboot: Disable SVM, not just VMX, when stopping CPUs
+    - x86/kprobes: Fix __recover_optprobed_insn check optimizing logic
+    - x86/kprobes: Fix arch_check_optimized_kprobe check within optimized_kprobe
+      range
+    - x86/microcode/amd: Remove load_microcode_amd()'s bsp parameter
+    - x86/microcode/AMD: Add a @cpu parameter to the reloading functions
+    - x86/microcode/AMD: Fix mixed steppings support
+    - x86/speculation: Allow enabling STIBP with legacy IBRS
+    - Documentation/hw-vuln: Document the interaction between IBRS and STIBP
+    - virt/sev-guest: Return -EIO if certificate buffer is not large enough
+    - brd: mark as nowait compatible
+    - brd: return 0/-error from brd_insert_page()
+    - brd: check for REQ_NOWAIT and set correct page allocation mask
+    - ima: fix error handling logic when file measurement failed
+    - ima: Align ima_file_mmap() parameters with mmap_file LSM hook
+    - selftests/powerpc: Fix incorrect kernel headers search path
+    - selftests/ftrace: Fix eprobe syntax test case to check filter support
+    - selftests: sched: Fix incorrect kernel headers search path
+    - selftests: core: Fix incorrect kernel headers search path
+    - selftests: pid_namespace: Fix incorrect kernel headers search path
+    - selftests: arm64: Fix incorrect kernel headers search path
+    - selftests: clone3: Fix incorrect kernel headers search path
+    - selftests: pidfd: Fix incorrect kernel headers search path
+    - selftests: membarrier: Fix incorrect kernel headers search path
+    - selftests: kcmp: Fix incorrect kernel headers search path
+    - selftests: media_tests: Fix incorrect kernel headers search path
+    - selftests: gpio: Fix incorrect kernel headers search path
+    - selftests: filesystems: Fix incorrect kernel headers search path
+    - selftests: user_events: Fix incorrect kernel headers search path
+    - selftests: ptp: Fix incorrect kernel headers search path
+    - selftests: sync: Fix incorrect kernel headers search path
+    - selftests: rseq: Fix incorrect kernel headers search path
+    - selftests: move_mount_set_group: Fix incorrect kernel headers search path
+    - selftests: mount_setattr: Fix incorrect kernel headers search path
+    - selftests: perf_events: Fix incorrect kernel headers search path
+    - selftests: ipc: Fix incorrect kernel headers search path
+    - selftests: futex: Fix incorrect kernel headers search path
+    - selftests: drivers: Fix incorrect kernel headers search path
+    - selftests: dmabuf-heaps: Fix incorrect kernel headers search path
+    - selftests: vm: Fix incorrect kernel headers search path
+    - selftests: seccomp: Fix incorrect kernel headers search path
+    - irqdomain: Fix association race
+    - irqdomain: Fix disassociation race
+    - irqdomain: Look for existing mapping only once
+    - irqdomain: Drop bogus fwspec-mapping error handling
+    - irqdomain: Refactor __irq_domain_alloc_irqs()
+    - irqdomain: Fix mapping-creation race
+    - irqdomain: Fix domain registration race
+    - crypto: qat - fix out-of-bounds read
+    - mm/damon/paddr: fix missing folio_put()
+    - ALSA: ice1712: Do not left ice->gpio_mutex locked in aureon_add_controls()
+    - ALSA: hda/realtek: Add quirk for HP EliteDesk 800 G6 Tower PC
+    - jbd2: fix data missing when reusing bh which is ready to be checkpointed
+    - ext4: optimize ea_inode block expansion
+    - ext4: refuse to create ea block when umounted
+    - cxl/pmem: Fix nvdimm registration races
+    - Input: exc3000 - properly stop timer on shutdown
+    - mtd: spi-nor: sfdp: Fix index value for SCCR dwords
+    - mtd: spi-nor: spansion: Consider reserved bits in CFR5 register
+    - dm: send just one event on resize, not two
+    - dm: add cond_resched() to dm_wq_work()
+    - dm: add cond_resched() to dm_wq_requeue_work()
+    - wifi: rtw88: use RTW_FLAG_POWERON flag to prevent to power on/off twice
+    - wifi: rtl8xxxu: Use a longer retry limit of 48
+    - wifi: ath11k: allow system suspend to survive ath11k
+    - wifi: cfg80211: Fix use after free for wext
+    - wifi: cfg80211: Set SSID if it is not already set
+    - cpuidle: add ARCH_SUSPEND_POSSIBLE dependencies
+    - qede: fix interrupt coalescing configuration
+    - thermal: intel: powerclamp: Fix cur_state for multi package system
+    - dm flakey: fix logic when corrupting a bio
+    - dm cache: free background tracker's queued work in btracker_destroy
+    - dm flakey: don't corrupt the zero page
+    - dm flakey: fix a bug with 32-bit highmem systems
+    - hwmon: (peci/cputemp) Fix off-by-one in coretemp_label allocation
+    - hwmon: (nct6775) Fix incorrect parenthesization in nct6775_write_fan_div()
+    - spi: intel: Check number of chip selects after reading the descriptor
+    - ARM: dts: qcom: sdx65: Add Qcom SMMU-500 as the fallback for IOMMU node
+    - ARM: dts: qcom: sdx55: Add Qcom SMMU-500 as the fallback for IOMMU node
+    - ARM: dts: exynos: correct TMU phandle in Exynos4210
+    - ARM: dts: exynos: correct TMU phandle in Exynos4
+    - ARM: dts: exynos: correct TMU phandle in Odroid XU3 family
+    - ARM: dts: exynos: correct TMU phandle in Exynos5250
+    - ARM: dts: exynos: correct TMU phandle in Odroid XU
+    - ARM: dts: exynos: correct TMU phandle in Odroid HC1
+    - arm64: acpi: Fix possible memory leak of ffh_ctxt
+    - arm64: mm: hugetlb: Disable HUGETLB_PAGE_OPTIMIZE_VMEMMAP
+    - arm64: Reset KASAN tag in copy_highpage with HW tags only
+    - fuse: add inode/permission checks to fileattr_get/fileattr_set
+    - rbd: avoid use-after-free in do_rbd_add() when rbd_dev_create() fails
+    - ceph: update the time stamps and try to drop the suid/sgid
+    - regulator: core: Use ktime_get_boottime() to determine how long a regulator
+      was off
+    - panic: fix the panic_print NMI backtrace setting
+    - mm/hwpoison: convert TTU_IGNORE_HWPOISON to TTU_HWPOISON
+    - genirq/msi, platform-msi: Ensure that MSI descriptors are unreferenced
+    - genirq/msi: Take the per-device MSI lock before validating the control
+      structure
+    - spi: spi-sn-f-ospi: fix duplicate flag while assigning to mode_bits
+    - alpha: fix FEN fault handling
+    - dax/kmem: Fix leak of memory-hotplug resources
+    - mips: fix syscall_get_nr
+    - media: ipu3-cio2: Fix PM runtime usage_count in driver unbind
+    - remoteproc/mtk_scp: Move clk ops outside send_lock
+    - vfio: Fix NULL pointer dereference caused by uninitialized group->iommufd
+    - docs: gdbmacros: print newest record
+    - mm: memcontrol: deprecate charge moving
+    - mm/thp: check and bail out if page in deferred queue already
+    - ktest.pl: Give back console on Ctrt^C on monitor
+    - kprobes: Fix to handle forcibly unoptimized kprobes on freeing_list
+    - ktest.pl: Fix missing "end_monitor" when machine check fails
+    - ktest.pl: Add RUN_TIMEOUT option with default unlimited
+    - memory tier: release the new_memtier in find_create_memory_tier()
+    - ring-buffer: Handle race between rb_move_tail and rb_check_pages
+    - tools/bootconfig: fix single & used for logical condition
+    - tracing/eprobe: Fix to add filter on eprobe description in README file
+    - iommu/amd: Add a length limitation for the ivrs_acpihid command-line
+      parameter
+    - scsi: aacraid: Allocate cmd_priv with scsicmd
+    - scsi: qla2xxx: Fix link failure in NPIV environment
+    - scsi: qla2xxx: Check if port is online before sending ELS
+    - scsi: qla2xxx: Fix DMA-API call trace on NVMe LS requests
+    - scsi: qla2xxx: Remove unintended flag clearing
+    - scsi: qla2xxx: Fix erroneous link down
+    - scsi: qla2xxx: Remove increment of interface err cnt
+    - scsi: ses: Don't attach if enclosure has no components
+    - scsi: ses: Fix slab-out-of-bounds in ses_enclosure_data_process()
+    - scsi: ses: Fix possible addl_desc_ptr out-of-bounds accesses
+    - scsi: ses: Fix possible desc_ptr out-of-bounds accesses
+    - scsi: ses: Fix slab-out-of-bounds in ses_intf_remove()
+    - RISC-V: add a spin_shadow_stack declaration
+    - riscv: Avoid enabling interrupts in die()
+    - riscv: mm: fix regression due to update_mmu_cache change
+    - riscv: jump_label: Fixup unaligned arch_static_branch function
+    - riscv: ftrace: Fixup panic by disabling preemption
+    - riscv, mm: Perform BPF exhandler fixup on page fault
+    - riscv: ftrace: Remove wasted nops for !RISCV_ISA_C
+    - riscv: ftrace: Reduce the detour code size to half
+    - MIPS: DTS: CI20: fix otg power gpio
+    - PCI/PM: Observe reset delay irrespective of bridge_d3
+    - PCI: Unify delay handling for reset and resume
+    - PCI: hotplug: Allow marking devices as disconnected during bind/unbind
+    - PCI: Avoid FLR for AMD FCH AHCI adapters
+    - PCI/DPC: Await readiness of secondary bus after reset
+    - bus: mhi: ep: Only send -ENOTCONN status if client driver is available
+    - bus: mhi: ep: Move chan->lock to the start of processing queued ch ring
+    - bus: mhi: ep: Save channel state locally during suspend and resume
+    - iommufd: Make sure to zero vfio_iommu_type1_info before copying to user
+    - iommufd: Do not add the same hwpt to the ioas->hwpt_list twice
+    - iommu/vt-d: Avoid superfluous IOTLB tracking in lazy mode
+    - iommu/vt-d: Fix PASID directory pointer coherency
+    - vfio/type1: exclude mdevs from VFIO_UPDATE_VADDR
+    - vfio/type1: prevent underflow of locked_vm via exec()
+    - vfio/type1: track locked_vm per dma
+    - vfio/type1: restore locked_vm
+    - drm/amd: Fix initialization for nbio 7.5.1
+    - drm/i915/quirks: Add inverted backlight quirk for HP 14-r206nv
+    - drm/radeon: Fix eDP for single-display iMac11,2
+    - drm/i915: Don't use stolen memory for ring buffers with LLC
+    - drm/i915: Don't use BAR mappings for ring buffers with LLC
+    - drm/gud: Fix UBSAN warning
+    - drm/edid: fix AVI infoframe aspect ratio handling
+    - drm/edid: fix parsing of 3D modes from HDMI VSDB
+    - qede: avoid uninitialized entries in coal_entry array
+    - brd: use radix_tree_maybe_preload instead of radix_tree_preload
+    - net: avoid double iput when sock_alloc_file fails
+    - Linux 6.2.3
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations after applying 6.2.3 stable patches
+    - [Config] update annotations after applying 6.2.6 stable patches
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 14 Mar 2023 16:43:44 +0100
+
+linux (6.2.0-16.16) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-16.16 -proposed tracker (LP: #2009914)
+
+  * linux-libc-dev is no longer multi-arch safe (LP: #2009355)
+    - Revert "UBUNTU: [Packaging] install headers to debian/linux-libc-dev
+      directly"
+
+  * linux: CONFIG_SERIAL_8250_MID=y (LP: #2009283)
+    - [Config] enable CONFIG_SERIAL_8250_MID=y
+
+  * cpufreq: intel_pstate: Update Balance performance EPP for Sapphire Rapids
+    (LP: #2008519)
+    - cpufreq: intel_pstate: Adjust balance_performance EPP for Sapphire Rapids
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 10 Mar 2023 18:34:28 +0100
+
+linux (6.2.0-15.15) lunar; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: document annotations headers
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 10 Mar 2023 07:36:59 +0100
+
+linux (6.2.0-14.14) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-14.14 -proposed tracker (LP: #2009856)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] rust: add rust build dependencies to all arches
+    - [Packaging] Support skipped dkms modules
+    - [Packaging] actually enforce set -e in dkms-build--nvidia-N
+    - [Packaging] Preserve the correct log file variable value
+    - [Packaging] update getabis
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 09 Mar 2023 16:40:36 +0100
+
+linux (6.2.0-13.13) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-13.13 -proposed tracker (LP: #2009704)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * mt7921: add support of MTFG table (LP: #2009642)
+    - wifi: mt76: mt7921: add support to update fw capability with MTFG table
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Mar 2023 14:40:25 +0100
+
+linux (6.2.0-12.12) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-12.12 -proposed tracker (LP: #2009698)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: enforce rust availability only on x86_64
+    - [Config] update CONFIG_RUST_IS_AVAILABLE
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Mar 2023 12:50:15 +0100
+
+linux (6.2.0-11.11) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-11.11 -proposed tracker (LP: #2009697)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] do not stop the build if rust is not available
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Mar 2023 12:24:55 +0100
+
+linux (6.2.0-10.10) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-10.10 -proposed tracker (LP: #2009673)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * enable Rust support in the kernel (LP: #2007654)
+    - [Packaging] propagate makefile variables to kernelconfig
+    - SAUCE: rust: fix regexp in scripts/is_rust_module.sh
+    - SAUCE: scripts: rust: drop is_rust_module.sh
+    - SAUCE: rust: allow to use INIT_STACK_ALL_ZERO
+    - SAUCE: scripts: Exclude Rust CUs with pahole
+    - SAUCE: modpost: support arbitrary symbol length in modversion
+    - SAUCE: allows to enable Rust with modversions
+    - SAUCE: rust: properly detect the version of libclang used by bindgen
+    - [Packaging] rust: add the proper make flags to enable rust support
+    - [Packaging] add rust dependencies
+    - [Packaging] bpftool: always use vmlinux to generate headers
+    - [Packaging] run rustavailable target as debugging before build
+    - [Config] enable Rust support
+
+  * Fail to output sound to external monitor which connects via docking station
+    (LP: #2009024)
+    - [Config] Enable CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Makefile: replace rsync with tar
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Mar 2023 12:01:56 +0100
+
+linux (6.2.0-1.1) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-1.1 -proposed tracker (LP: #2009621)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * kinetic: apply new apparmor and LSM stacking patch set (LP: #1989983)
+    - SAUCE: apparmor: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor: add user namespace creation mediation
+
+  * Lunar update: v6.2.2 upstream stable release (LP: #2009358)
+    - ALSA: hda: cs35l41: Correct error condition handling
+    - crypto: arm64/sm4-gcm - Fix possible crash in GCM cryption
+    - bpf: bpf_fib_lookup should not return neigh in NUD_FAILED state
+    - vc_screen: don't clobber return value in vcs_read
+    - drm/amd/display: Move DCN314 DOMAIN power control to DMCUB
+    - drm/amd/display: Properly reuse completion structure
+    - scripts/tags.sh: fix incompatibility with PCRE2
+    - wifi: rtw88: usb: Set qsel correctly
+    - wifi: rtw88: usb: send Zero length packets if necessary
+    - wifi: rtw88: usb: drop now unnecessary URB size check
+    - usb: dwc3: pci: add support for the Intel Meteor Lake-M
+    - USB: serial: option: add support for VW/Skoda "Carstick LTE"
+    - usb: gadget: u_serial: Add null pointer check in gserial_resume
+    - arm64: dts: uniphier: Fix property name in PXs3 USB node
+    - usb: typec: pd: Remove usb_suspend_supported sysfs from sink PDO
+    - USB: core: Don't hold device lock while reading the "descriptors" sysfs file
+    - Linux 6.2.2
+
+  * Lunar update: v6.2.1 upstream stable release (LP: #2009127)
+    - uaccess: Add speculation barrier to copy_from_user()
+    - x86/alternatives: Introduce int3_emulate_jcc()
+    - x86/alternatives: Teach text_poke_bp() to patch Jcc.d32 instructions
+    - x86/static_call: Add support for Jcc tail-calls
+    - HID: mcp-2221: prevent UAF in delayed work
+    - wifi: mwifiex: Add missing compatible string for SD8787
+    - audit: update the mailing list in MAINTAINERS
+    - platform/x86/amd/pmf: Add depends on CONFIG_POWER_SUPPLY
+    - platform/x86: nvidia-wmi-ec-backlight: Add force module parameter
+    - ext4: Fix function prototype mismatch for ext4_feat_ktype
+    - randstruct: disable Clang 15 support
+    - bpf: add missing header file include
+    - Linux 6.2.1
+
+  * Fix mediatek wifi driver crash when loading wrong SAR table (LP: #2009118)
+    - wifi: mt76: mt7921: fix error code of return in mt7921_acpi_read
+
+  * overlayfs mounts as R/O over idmapped mount (LP: #2009065)
+    - SAUCE: overlayfs: handle idmapped mounts in ovl_do_(set|remove)xattr
+
+  * RaptorLake: Fix the Screen is shaking by onboard HDMI port in mirror mode
+    (LP: #1993561)
+    - drm/i915/display: Drop check for doublescan mode in modevalid
+    - drm/i915/display: Prune Interlace modes for Display >=12
+
+  * screen flicker after PSR2 enabled (LP: #2007516)
+    - SAUCE: drm/i915/display/psr: Disable PSR2 sel fetch on panel SHP 5457
+
+  * [23.04 FEAT] Support for new IBM Z Hardware (IBM z16) - Reset DAT-Protection
+    facility support (LP: #1982378)
+    - s390/mm: add support for RDP (Reset DAT-Protection)
+
+  * [23.04 FEAT] zcrypt DD: AP command filtering (LP: #2003637)
+    - s390/zcrypt: introduce ctfm field in struct CPRBX
+
+  * rtcpie in timers from ubuntu_kernel_selftests randomly failing
+    (LP: #1814234)
+    - SAUCE: selftest: rtcpie: Force passing unreliable subtest
+
+  * [23.04 FEAT] Support for List-Directed IPL and re-IPL from ECKD DASD
+    (LP: #2003394)
+    - s390/ipl: add DEFINE_GENERIC_LOADPARM()
+    - s390/ipl: add loadparm parameter to eckd ipl/reipl data
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: drm/i915/sseu: fix max_subslices array-index-out-of-bounds access
+    - SAUCE: mtd: spi-nor: Fix shift-out-of-bounds in spi_nor_set_erase_type
+    - SAUCE: Revert "fbdev: Make registered_fb[] private to fbmem.c"
+    - [Packaging] disable signing for ppc64el
+    - [Config] define CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+    - SAUCE: Revert "arm64/fpsimd: Make kernel_neon_ API _GPL"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 07 Mar 2023 18:45:31 +0100
+
+linux (6.2.0-0.0) lunar; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 03 Mar 2023 08:42:43 +0100
+
+linux-unstable (6.2.0-10.10) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-10.10 -proposed tracker (LP: #2007818)
+
+  * Built-in camera device dies after runtime suspended (LP: #2007530)
+    - SAUCE: usb: xhci: Workaround for runpm issue on AMD xHC
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations after rebase to v6.2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 20 Feb 2023 10:36:20 +0100
+
+linux-unstable (6.2.0-9.9) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-9.9 -proposed tracker (LP: #2007069)
+
+  * Move kernel ADT tests to python3 (LP: #2004429)
+    - [Debian] Use a python3 compatable kernel-testing repo
+
+  * Mediatek FM350-GL wwan module failed to init: Invalid device status 0x1
+    (LP: #2002089)
+    - SAUCE: Revert "net: wwan: t7xx: Add AP CLDMA"
+    - SAUCE: net: wwan: t7xx: Add AP CLDMA
+    - SAUCE: net: wwan: t7xx: Infrastructure for early port configuration
+    - SAUCE: net: wwan: t7xx: PCIe reset rescan
+    - SAUCE: net: wwan: t7xx: Enable devlink based fw flashing and coredump
+      collection
+    - SAUCE: net: wwan: t7xx: Devlink documentation
+
+  * LXD containers using shiftfs on ZFS or TMPFS broken on 5.15.0-48.54
+    (LP: #1990849)
+    - SAUCE: shiftfs: fix -EOVERFLOW inside the container
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: do not drop undefined configs in derivatives
+    - [Packaging]: annotations: fix _remove_entry() logic
+    - [Packaging] rsync no longer available on lunar
+    - [Packaging] annotations: Handle single-line annoation rules
+    - [Packaging] annotations: Preserve single-line annotation rules
+    - [Packaging] annotations: Fix linter errors
+    - [Packaging] annotations: Clean up policy writes
+    - [Packaging] annotations: Handle tabs in annotations file
+    - [Packaging] annotations: Fail on invalid lines
+    - [Packaging] annotations: Write out annotations with notes first
+    - [Packaging] annotations: Check validity of FLAVOUR_DEP
+    - [Config] update annotations to split configs with/without notes
+    - [Packaging] annotations: various code cleanups
+    - [Config] update annotations after rebase to v6.2-rc8
+
+  * Miscellaneous upstream changes
+    - selftests/net: mv bpf/nat6to4.c to net folder
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc8
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 13 Feb 2023 09:32:18 +0100
+
+linux-unstable (6.2.0-8.8) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-8.8 -proposed tracker (LP: #2004229)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] re-enable signing for ppc64el and s390x
+    - SAUCE: s390/decompressor: specify __decompress() buf len to avoid overflow
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 31 Jan 2023 08:21:21 +0100
+
+linux-unstable (6.2.0-7.7) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-7.7 -proposed tracker (LP: #2004142)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 30 Jan 2023 10:23:15 +0100
+
+linux-unstable (6.2.0-6.6) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-6.6 -proposed tracker (LP: #2004138)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] debian/rules: Bring back 'editconfigs'
+    - [Packaging] debian/rules: 1-maintainer.mk -- Use make's if-else
+    - [Packaging] annotations: make sure to always drop undefined configs
+    - [Config] update annotations after rebase to v6.2-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 30 Jan 2023 09:20:26 +0100
+
+linux-unstable (6.2.0-5.5) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-5.5 -proposed tracker (LP: #2003682)
+
+  * [23.04] Kernel 6.2 does not boot on s390x (LP: #2003348)
+    - SAUCE Revert "zstd: import usptream v1.5.2"
+    - SAUCE: Revert "zstd: Move zstd-common module exports to
+      zstd_common_module.c"
+
+  * Revoke & rotate to new signing key (LP: #2002812)
+    - [Packaging] Revoke and rotate to new signing key
+
+  * CVE-2023-0179
+    - netfilter: nft_payload: incorrect arithmetics when fetching VLAN header bits
+
+  * [23.04] net/smc: Alibaba patches about tunable buffer sizes may cause errors
+    and need to be removed (kernel 6.2) (LP: #2003547)
+    - SAUCE: Revert "net/smc: Unbind r/w buffer size from clcsock and make them
+      tunable"
+    - SAUCE: Revert "net/smc: Introduce a specific sysctl for TEST_LINK time"
+
+  * 5.15 stuck at boot on c4.large (LP: #1956780)
+    - SAUCE: Revert "PCI/MSI: Mask MSI-X vectors only on success"
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] scripts/misc/kernelconfig: Disable config checks for mainline
+      builds
+    - [Packaging] annotations: add CONFIG_GCC_VERSION to the list of ignored
+      configs
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 23 Jan 2023 08:20:26 +0100
+
+linux-unstable (6.2.0-4.4) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-4.4 -proposed tracker (LP: #2003051)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] add python3 as a build dependency
+    - [Packaging] scripts/misc/kernelconfig: Rewrite
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 17 Jan 2023 09:18:54 +0100
+
+linux-unstable (6.2.0-3.3) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-3.3 -proposed tracker (LP: #2002939)
+
+  * Enable kernel config for P2PDMA (LP: #1987394)
+    - [Config] Enable CONFIG_HSA_AMD_P2P
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (no-up) Remove obj- += foo.o hack
+    - SAUCE: (no-up) re-add ubuntu/ directory
+    - [Config] enable EFI handover protocol
+    - [Packaging] Fix module-check error when modules are compressed
+    - SAUCE: (no-up) do not remove debian directory by 'make mrproper'
+    - [Packaging] debian/rules: Drop AUTOBUILD
+    - [Packaging] debian/rules: Drop NOKERNLOG and PRINTSHAS env variables
+    - [Packaging] debian/rules: Replace skip<foo> variables with skip_checks
+    - [Packaging] checks/retpoline-check: Make 'skipretpoline' argument optional
+    - [Packaging] checks/module-signature-check: Add 'skip_checks' argument
+    - [Packaging] debian/rules: Rename 'skip_dbg' to 'do_dbgsym_package'
+    - [Packaging] debian/rules: Rename 'skip_checks' to 'do_skip_checks'
+    - [Packaging] debian/rules: Rename 'full_build' to 'do_full_build'
+    - [Packaging] debian/rules: Fix PPA debug package builds
+    - [Packaging] debian/rules: Remove debug package install directory earlier
+    - [Packaging] debian/rules: Remove unnecessary 'lockme_<foo>' variables
+    - [Packaging] debian/rules: Remove unused target 'diffupstream'
+    - [Packaging] debian/rules: Mark PHONY targets individually
+    - [Packaging] debian/rules: Clean up 'help' target output
+    - [Packaging] debian/rules: Clean up 'printenv' target output
+    - [Packaging] debian/rules: Add missing 'do_<foo>' variables to 'printenv'
+    - [Config] update annotations after rebase to v6.2-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 16 Jan 2023 16:01:40 +0100
+
+linux-unstable (6.2.0-2.2) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-2.2 -proposed tracker (LP: #2001892)
+
+  * Soundwire support for the Intel RPL Gen 0C40/0C11 platforms (LP: #2000030)
+    - SAUCE: ASoC: Intel: soc-acpi: add configuration for variant of 0C40 product
+    - SAUCE: ASoC: Intel: soc-acpi: add configuration for variant of 0C11 product
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update toolchain version in annotations
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] Support skipped dkms modules"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 05 Jan 2023 09:19:55 +0100
+
+linux-unstable (6.2.0-1.1) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-1.1 -proposed tracker (LP: #2000904)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: remove configs that are undefined across all
+      arches/flavours
+    - SAUCE: Revert "apparmor: make __aa_path_perm() static"
+    - [Packaging] abi-check: ignore failures when abi check is skipped
+    - [Packaging] temporarily disable zfs dkms
+    - [Config] update annotations after rebase to 6.2-rc1
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 04 Jan 2023 12:08:32 +0100
+
+linux-unstable (6.2.0-0.0) lunar; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Sun, 01 Jan 2023 10:16:00 +0100
+
+linux (6.1.0-11.11) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-11.11 -proposed tracker (LP: #2000704)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Lunar update: v6.1.1 upstream stable release (LP: #2000706)
+    - x86/vdso: Conditionally export __vdso_sgx_enter_enclave()
+    - libbpf: Fix uninitialized warning in btf_dump_dump_type_data
+    - PCI: mt7621: Add sentinel to quirks table
+    - mips: ralink: mt7621: define MT7621_SYSC_BASE with __iomem
+    - mips: ralink: mt7621: soc queries and tests as functions
+    - mips: ralink: mt7621: do not use kzalloc too early
+    - irqchip/ls-extirq: Fix endianness detection
+    - udf: Discard preallocation before extending file with a hole
+    - udf: Fix preallocation discarding at indirect extent boundary
+    - udf: Do not bother looking for prealloc extents if i_lenExtents matches
+      i_size
+    - udf: Fix extending file within last block
+    - usb: gadget: uvc: Prevent buffer overflow in setup handler
+    - USB: serial: option: add Quectel EM05-G modem
+    - USB: serial: cp210x: add Kamstrup RF sniffer PIDs
+    - USB: serial: f81232: fix division by zero on line-speed change
+    - USB: serial: f81534: fix division by zero on line-speed change
+    - xhci: Apply XHCI_RESET_TO_DEFAULT quirk to ADL-N
+    - staging: r8188eu: fix led register settings
+    - igb: Initialize mailbox message for VF reset
+    - usb: typec: ucsi: Resume in separate work
+    - usb: dwc3: pci: Update PCIe device ID for USB3 controller on CPU sub-system
+      for Raptor Lake
+    - cifs: fix oops during encryption
+    - KEYS: encrypted: fix key instantiation with user-provided data
+    - Linux 6.1.1
+
+  * Expose built-in trusted and revoked certificates (LP: #1996892)
+    - [Packaging] Expose built-in trusted and revoked certificates
+
+  * Fix System cannot detect bluetooth after running suspend stress test
+    (LP: #1998727)
+    - wifi: rtw88: 8821c: enable BT device recovery mechanism
+
+  * Gnome doesn't run smooth when performing normal usage with RPL-P CPU
+    (LP: #1998419)
+    - drm/i915/rpl-p: Add stepping info
+
+  * Mute/mic LEDs no function on a HP platfrom (LP: #1998882)
+    - ALSA: hda/realtek: fix mute/micmute LEDs for a HP ProBook
+
+  * Add additional Mediatek MT7922 BT device ID (LP: #1998885)
+    - Bluetooth: btusb: Add a new VID/PID 0489/e0f2 for MT7922
+
+  * Support Icicle Kit reference design v2022.10 (LP: #1993148)
+    - SAUCE: riscv: dts: microchip: Disable PCIe on the Icicle Kit
+
+  * Add iommu passthrough quirk for Intel IPU6 on RaptorLake (LP: #1989041)
+    - SAUCE: iommu: intel-ipu: use IOMMU passthrough mode for Intel IPUs on Raptor
+      Lake
+
+  * Enable Intel FM350 wwan CCCI driver port logging (LP: #1997686)
+    - net: wwan: t7xx: use union to group port type specific data
+    - net: wwan: t7xx: Add port for modem logging
+
+  * TEE Support for CCP driver (LP: #1991608)
+    - crypto: ccp - Add support for TEE for PCI ID 0x14CA
+
+  * Kinetic update: v5.19.17 upstream stable release (LP: #1994179)
+    - Revert "fs: check FMODE_LSEEK to control internal pipe splicing"
+    - kbuild: Add skip_encoding_btf_enum64 option to pahole
+
+  * Kinetic update: v5.19.15 upstream stable release (LP: #1994078)
+    - Revert "clk: ti: Stop using legacy clkctrl names for omap4 and 5"
+
+  * support independent clock and LED GPIOs for Intel IPU6 platforms
+    (LP: #1989046)
+    - SAUCE: platform/x86: int3472: support independent clock and LED GPIOs
+
+  * Kernel livepatch support for for s390x (LP: #1639924)
+    - [Config] Enable EXPOLINE_EXTERN on s390x
+
+  * Kinetic update: v5.19.7 upstream stable release (LP: #1988733)
+    - Revert "PCI/portdrv: Don't disable AER reporting in
+      get_port_device_capability()"
+
+  * Kinetic update: v5.19.3 upstream stable release (LP: #1987345)
+    - Revert "mm: kfence: apply kmemleak_ignore_phys on early allocated pool"
+
+  * Fix non-working e1000e device after resume (LP: #1951861)
+    - SAUCE: Revert "e1000e: Add polling mechanism to indicate CSME DPG exit"
+
+  * Add additional Mediatek MT7921 WiFi/BT device IDs (LP: #1937004)
+    - SAUCE: Bluetooth: btusb: Add support for Foxconn Mediatek Chip
+
+  * Fix system sleep on TGL systems with Intel ME (LP: #1919321)
+    - SAUCE: PCI: Serialize TGL e1000e PM ops
+
+  * Fix broken e1000e device after S3 (LP: #1897755)
+    - SAUCE: e1000e: Increase polling timeout on MDIC ready bit
+
+  * Fix unusable USB hub on Dell TB16 after S3 (LP: #1855312)
+    - SAUCE: USB: core: Make port power cycle a seperate helper function
+    - SAUCE: USB: core: Attempt power cycle port when it's in eSS.Disabled state
+
+  * Set explicit CC in the headers package (LP: #1999750)
+    - [Packaging] Set explicit CC in the headers package
+
+  * commit cf58599cded35cf4affed1e659c0e2c742d3fda7 seems to be missing in
+    kinetic master to remove "hio" reference from Makefile (LP: #1999556)
+    - SAUCE: remove leftover reference to ubuntu/hio driver
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] kernelconfig: always complete all config checks
+    - [Packaging] annotations: unify same rule across all flavour within the same
+      arch
+    - [Config] annotations: compact annotations file
+    - [Config] disable EFI_ZBOOT
+    - SAUCE: input: i8042: fix section mismatch warning
+    - debian/dkms-versions -- re-enable zfs
+    - [Packaging] old-kernelconfig: update config-check path
+    - [Packaging] update getabis
+    - [Packaging] update Ubuntu.md
+
+  * Miscellaneous upstream changes
+    - Revert "drm/i915/opregion: check port number bounds for SWSCI display power
+      state"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 30 Dec 2022 11:23:16 +0100
+
+linux (6.1.0-10.10) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-10.10 -proposed tracker (LP: #1999569)
+
+  * Soundwire support for the Intel RPL Gen platforms (LP: #1997944)
+    - ASoC: Intel: sof_sdw: Add support for SKU 0C10 product
+    - ASoC: Intel: soc-acpi: add SKU 0C10 SoundWire configuration
+    - ASoC: Intel: sof_sdw: Add support for SKU 0C40 product
+    - ASoC: Intel: soc-acpi: add SKU 0C40 SoundWire configuration
+    - ASoC: Intel: sof_sdw: Add support for SKU 0C4F product
+    - ASoC: rt1318: Add RT1318 SDCA vendor-specific driver
+    - ASoC: intel: sof_sdw: add rt1318 codec support.
+    - ASoC: Intel: sof_sdw: Add support for SKU 0C11 product
+    - ASoC: Intel: soc-acpi: add SKU 0C11 SoundWire configuration
+    - SAUCE: ASoC: Intel: soc-acpi: update codec addr on 0C11/0C4F product
+    - [Config] enable CONFIG_SND_SOC_RT1318_SDW
+
+  * Virtual GPU driver packaging regression (LP: #1996112)
+    - [Packaging] Reintroduce VM DRM drivers into modules
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 13 Dec 2022 22:14:08 +0100
+
+linux (6.1.0-9.9) lunar; urgency=medium
+
+  * Empty entry (ABI bump)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 13 Dec 2022 21:31:08 +0100
+
+linux (6.1.0-3.3) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-3.3 -proposed tracker (LP: #1999534)
+
+  * [DEP-8] Run ADT regression suite for lowlatency kernels Jammy and later
+    (LP: #1999528)
+    - [DEP-8] Fix regression suite to run on lowlatency
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: do not add constraints on toolchain versions
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 13 Dec 2022 16:45:59 +0100
+
+linux (6.1.0-2.2) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-2.2 -proposed tracker (LP: #1999411)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: do not enforce toolchain versions
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 12 Dec 2022 17:05:59 +0100
+
+linux (6.1.0-1.1) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-1.1 -proposed tracker (LP: #1999373)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: set and delete configs from command line
+    - [Packaging] migrateconfigs: ignore README.rst if it doesn't exist
+    - [Packaging] migrate-annotations: properly determine arches in derivatives
+    - [Packaging] annotations: allow to set note to config options directly
+    - [Packaging] annotations: assume --query as default command
+    - [Packaging] annotations: allow to query using CONFIG_<option> or <option>
+    - [Packaging] annotations: support flavour inheritance
+    - [Packaging] annotations: properly merge configs with includes
+    - [Packaging] annotations: accept config options with or without CONFIG_
+      prefix
+    - [Packaging] annotations: clarify error message with --import
+    - [Packaging] annotations: properly support multiple levels of inclusion
+    - [Packaging] annotations: catch syntax errors in annotations
+    - [Packaging] kernelconfig: report arch and flavour in config-check log
+    - [Packaging] annotations: prevent generating .pyc files on import
+    - [Packaging] annotations: prevent python broken pipe errors
+    - [Packaging] annotations: allow to specify --write and --note at the same
+      time
+    - [Packaging] annotations: add an option to enable config autocompletion in
+      bash
+    - [Packaging] annotations: introduce --source
+    - [Packaging] annotations: add missing CONFIG_ prefix in main()
+    - [Packaging] Remove obsolete etc/kernelconfig
+    - [Packaging] Rewrite debian/scripts/abi-check in Python
+    - [Packaging] Simplify debian/scripts/module-check
+    - [Packaging] Clean up debian/scripts/module-check
+    - [Packaging] Move checker scripts to debian/scripts/checks
+    - [Packaging] mark phony targets
+    - [Packaging] Make the compiler for fix-filenames explicit
+    - [Packaging] add -rR MAKEFLAGS to clear implicit rules
+    - [Packaging] use dpkg-parsechangelog to get package name and series
+    - [Packaging] simplify revision/release
+    - [Packaging] simplify custom_override
+    - [Packaging] Remove meaningless code in install-arch-headers
+    - [Packaging] use olddefconfig in stamp-prepare-tree
+    - [Packaging] use parralel builds in more places
+    - [Packaging] install headers to debian/linux-libc-dev directly
+    - [Packaging] simplify abinum and uploadnum definitions
+    - [Packaging] Remove unused INSTALL_FW_PATH
+    - [Packaging] Merge install commands
+    - [Config] clean up deprecated notes in annotations
+    - [Packaging] automatically apply changes to annotations and drop
+      importconfigs
+    - [Packaging] kernelconfig: drop listnewconfigs
+    - [Packaging] annotations: do not hijack CONFIGS/* to update annotations
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 12 Dec 2022 10:05:03 +0100
+
+linux (6.1.0-0.0) lunar; urgency=medium
+
+  * Empty entry
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 12 Dec 2022 09:42:01 +0100
+
+linux-unstable (6.1.0-9.9) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-9.9 -proposed tracker (LP: #1998078)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Set ARM64_ERRATUM_2077057=y
+    - SAUCE: add python cached bytecode to .gitignore
+    - [Packaging] config-check: ignore values that are not defined in annotations
+    - [Packaging] config-check: do not strictly enforce CONFIG_CC_VERSION_TEXT
+    - [Packaging] config-check: support annotations format 4
+    - [Packaging] introduce annotations script
+    - [Packaging] add a README.rst to document the new annotations schema
+    - [Packaging] kernelconfig: automatically generate configs from annotations
+    - [Packaging] drop deprecated script tristate.sh
+    - [Packaging] use annotations to generate initial configs check them
+    - [Packaging] simplify kernelconfig
+    - [Packaging] kernelconfig: always keep configs
+    - [Packaging] kernelconfig: provide listnewconfigs
+    - [Packaging] kernelconfig: introduce importconfigs
+    - [Packaging] snap: support new annotations with snapcraft
+    - [Packaging] final-checks: support new annotations
+    - [Packaging] introduce migrate-annotations
+    - [Packaging] re-introduce previous kernelconfig as old-kernelconfig
+    - [Packaging] provide migrateconfigs debian/rules target
+    - [Packaging] correctly propagate errors during updateconfigs
+    - [Packaging] annotations: report failed config checks in alphabetic order
+    - [Config] merge configs into annotations
+    - [Config] udpate annotations after rebase to v6.1-rc7
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Nov 2022 11:25:44 +0100
+
+linux-unstable (6.1.0-8.8) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-8.8 -proposed tracker (LP: #1997357)
+
+  *  Fibocom WWAN FM350-GL suspend error (notebook not suspend) (LP: #1990700)
+    - net: wwan: t7xx: Add AP CLDMA
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v6.1-rc6
+    - [Config] update configs following v6.1-rc6 rebase
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs following v6.1-rc6 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 22 Nov 2022 11:56:26 +0100
+
+linux-unstable (6.1.0-7.7) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-7.7 -proposed tracker (LP: #1996731)
+
+  * Miscellaneous Ubuntu changes
+    - ppc64el: remove missing module
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 16 Nov 2022 11:37:05 +0100
+
+linux-unstable (6.1.0-6.6) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-6.6 -proposed tracker (LP: #1996616)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs following v6.1-rc5 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 15 Nov 2022 15:55:33 +0100
+
+linux-unstable (6.1.0-5.5) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-5.5 -proposed tracker (LP: #1995875)
+
+  * Please have linux-tools-common Provide: bpftool (LP: #1981089)
+    - [Packaging] let linux-tools-common provides bpftool
+
+  * Miscellaneous Ubuntu changes
+    - packaging: switch to lunar series
+    - Rebase to v6.1-rc4
+    - [Config] toolchian update
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc4
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 07 Nov 2022 16:43:21 +0100
+
+linux-unstable (6.1.0-4.4) lunar; urgency=medium
+
+  * kinetic/linux-unstable: 6.1.0-4.4 -proposed tracker (LP: #1995500)
+
+  * Fix ath11k deadlock on WCN6855 (LP: #1995041)
+    - SAUCE: wifi: ath11k: avoid deadlock during regulatory update in
+      ath11k_regd_update()
+
+  * Bump (kernel) '-mtune' to z16 / arch14 with 23.04 (LP: #1982833)
+    - [Config] Enable mtune z16
+
+  * armhf kernel compiled with gcc-12 fails to boot on pi 3/2 (LP: #1993120)
+    - [Packaging] Support arch-specific compilers in updateconfigs
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs after rebase to 6.1-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 03 Nov 2022 14:00:41 +0100
+
+linux-unstable (6.1.0-3.3) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.1.0-3.3 -proposed tracker (LP: #1994037)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Support skipped dkms modules
+    - [Config] update configs after rebase to 6.1-rc2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 24 Oct 2022 15:53:11 +0200
+
+linux-unstable (6.1.0-2.2) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.1.0-2.2 -proposed tracker (LP: #1993350)
+
+  * Populating Hyper-V MSR for Ubuntu 13.10 (LP: #1193172)
+    - SAUCE: (no-up) hv: Supply vendor ID and package ABI
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: perf tools: Fix man page build wrt perf-arm-coresight.txt
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 18 Oct 2022 23:02:31 +0200
+
+linux-unstable (6.1.0-1.1) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.1.0-1.1 -proposed tracker (LP: #1993118)
+
+  * Raise CONFIG_NR_CPUS (LP: #1967889)
+    - [Config] Raise riscv64 CONFIG_NR_CPUS to 32
+
+  * rcu_sched detected stalls on CPUs/tasks (LP: #1967130)
+    - [Config] Disable VMAP_STACK on riscv64
+
+  * Disable sv57 as the userspace is not ready (LP: #1991790)
+    - SAUCE: riscv: mm: Force disable sv57
+
+  * earlyconsole prints question marks on 5.19.0-1002-generic (LP: #1988984)
+    - [Config] Set CONFIG_PWM_SIFIVE=m for riscv64
+
+  * RCU stalls (LP: #1991951)
+    - [Config] Harmonize RCU_CPU_STALL_TIMEOUT
+
+  * backport dkms fixes to build modules correctly for hwe-5.19+ kernels with
+    custom compiler (LP: #1991664)
+    - [Packaging] use versioned gcc-12
+    - [Packaging] Update configs with versioned compiler version
+
+  * FTBFS on kinetic (LP: #1990964)
+    - SAUCE: uapi: Fixup strace compile error
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] sameport -- add support for sameport versioning
+    - [Packaging] move to kernel 6.1
+    - SAUCE: platform/x86: dell-uart-backlight: remove
+      acpi_video_set_dmi_backlight_type()
+    - SAUCE: shiftfs: support kernel 6.1
+    - [Config] update configs and annotations after rebase to 6.1-rc1
+    - debian/dkms-versions -- temporarily disable dkms builds
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 18 Oct 2022 17:21:43 +0200
+
+linux-unstable (6.1.0-0.0) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 17 Oct 2022 08:57:58 +0200
+
+linux-unstable (6.0.0-9.9) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-9.9 -proposed tracker (LP: #1991521)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update toolchain configs after rebase to 6.0
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 03 Oct 2022 15:51:57 +0200
+
+linux-unstable (6.0.0-8.8) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-8.8 -proposed tracker (LP: #1990101)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 20 Sep 2022 10:22:14 +0200
+
+linux-unstable (6.0.0-7.7) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-7.7 -proposed tracker (LP: #1989331)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+    - [Packaging] resync getabis
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Please enable CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU (LP: #1980861)
+    - [Config] Switch from DECOMP_SINGLE to DECOMP_MULTI_PERCPU
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Pass kernel build_arch to dkms
+    - [Packaging[ get rid of unnecessary 'set -x'
+    - [Config] update configs and annotations after rebase to 6.0-rc5
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 12 Sep 2022 14:03:55 +0200
+
+linux-unstable (6.0.0-6.6) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-6.6 -proposed tracker (LP: #1988706)
+
+  * Support Intel TDX guest attestation driver (LP: #1988120)
+    - SAUCE: x86/tdx: Add TDX Guest attestation interface driver
+    - SAUCE: selftests: tdx: Test GetReport TDX attestation feature
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] temporarily disable signing for ppc64el and s390x
+    - [Config] enable security-related configs
+    - [Config] update toolchain versions
+    - [Packaging] fix URLs used to retrieve kernel ABI
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 05 Sep 2022 16:59:40 +0200
+
+linux-unstable (6.0.0-5.5) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-5.5 -proposed tracker (LP: #1988019)
+
+  * LSM: Configuring Too Many LSMs Causes Kernel Panic on Boot (LP: #1987998)
+    - SAUCE: LSM: Change Landlock from LSMBLOB_NEEDED to LSMBLOB_NOT_NEEDED
+
+  * RISC-V kernel config is out of sync with other archs (LP: #1981437)
+    - [Config] Align riscv64 CONFIG_LSM with other architectures
+    - [Config] Enable CONFIG_DRM_RCAR_USE_LVDS for riscv64
+    - [Config] Enable CONFIG_DTPM for riscv64
+    - [Config] Set CONFIG_MTD_RAW_NAND=m for riscv64
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging]: always use fully qualified <triplet>-gcc-VER toolchain
+    - [Packaging] use unversioned default gcc
+    - [Packaging] Remove circular dependency between image & modules
+    - [Config] update configs after rebase to 6.0-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 29 Aug 2022 09:18:39 +0200
+
+linux-unstable (6.0.0-4.4) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-4.4 -proposed tracker (LP: #1987517)
+
+  * Fix invalid MAC address after hotplug tbt dock (LP: #1942999)
+    - SAUCE: igc: wait for the MAC copy when enabled MAC passthrough
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] getabis: Add modules.builtin to the ABI
+
+  * Miscellaneous upstream changes
+    - perf tools: Fix compile error for x86
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 24 Aug 2022 15:10:24 +0200
+
+linux-unstable (6.0.0-3.3) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-3.3 -proposed tracker (LP: #1987241)
+
+  * [22.04 FEAT] Deactivitate  CONFIG_QETH_OSX kernel config option
+    (LP: #1959890)
+    - [Config] disable CONFIG_QETH_OSX on s390x
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Make stamp-install-<flavor> target reentrant
+    - [Config] update toolchain version
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 22 Aug 2022 09:09:26 +0200
+
+linux-unstable (6.0.0-2.2) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-2.2 -proposed tracker (LP: #1986844)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "perf tools: Use Python devtools for version autodetection
+      rather than runtime"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 17 Aug 2022 19:40:07 +0200
+
+linux-unstable (6.0.0-1.1) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-1.1 -proposed tracker (LP: #1986784)
+
+  * refactoring of overlayfs fix to properly support shiftfs (LP: #1983640)
+    - SAUCE: for aufs mmap: print the virtual file path
+    - SAUCE: overlayfs: fix incorrect mnt_id of files opened from map_files
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move to kernel 6.0
+    - [Config] update configs and annotations after rebase to 6.0-rc1
+    - [Packaging] temporarily disable dkms
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 17 Aug 2022 16:56:18 +0200
+
+linux-unstable (6.0.0-0.0) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 17 Aug 2022 10:23:42 +0200
+
+linux (5.19.0-15.15) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-15.15 -proposed tracker (LP: #1983335)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations to support both gcc-11 and gcc-12
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 02 Aug 2022 09:23:01 +0200
+
+linux (5.19.0-14.14) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-14.14 -proposed tracker (LP: #1983273)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] module-signature-check: Check debian.<foo>/signature-inclusion
+    - [Packaging] Introduce debian/scripts/sign-module
+    - SAUCE: Switch to using debian/scripts/sign-module
+    - [Config] update configs/annotations after rebase to 5.19
+    - [Config] update configs after moving to gcc-12
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging]: always use fully qualified <triplet>-gcc-VER
+      toolchain"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 01 Aug 2022 17:19:01 +0200
+
+linux (5.19.0-13.13) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-13.13 -proposed tracker (LP: #1983033)
+
+  * network-manager/1.36.4-2ubuntu1 ADT test failure with linux/5.15.0-28.29
+    (LP: #1971418)
+    - Revert "rfkill: make new event layout opt-in"
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Tighten up LP bug links in annotations
+    - [Config] Use mark<ENFORCED> for CONFIG_DEVTMPFS
+    - [Config] Use flag<DEPRECATED> for CONFIG_HIPPI
+    - [Config] Use note<> for CONFIG_XEN_ACPI_PROCESSOR
+    - [Config] Fix DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING annotation
+    - [Config] Fix CONFIG_CPU_LITTLE_ENDIAN annotation
+    - SAUCE: x86/bugs: Do not enable IBPB at firmware entry when IBPB is not
+      available
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 28 Jul 2022 17:04:33 +0200
+
+linux (5.19.0-12.12) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-12.12 -proposed tracker (LP: #1982741)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging]: always use fully qualified <triplet>-gcc-VER toolchain
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 26 Jul 2022 15:07:13 +0200
+
+linux (5.19.0-11.11) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-11.11 -proposed tracker (LP: #1982726)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * GPIO character device v1 API not enabled in kernel (LP: #1953613)
+    - [Config] Enable CONFIG_GPIO_CDEV_V1
+
+  * Use kernel-testing repo from launchpad for ADT tests (LP: #1968016)
+    - [Debian] Use kernel-testing repo from launchpad
+
+  * Support AMD P-State cpufreq control mechanism (LP: #1956509)
+    - [Config] enable X86_AMD_PSTATE as built-in on amd64
+
+  * PCIE LnkCtl ASPM not enabled under VMD mode for Alder Lake platforms
+    (LP: #1942160)
+    - SAUCE: PCI/ASPM: Enable ASPM for links under VMD domain
+    - SAUCE: PCI/ASPM: Enable LTR for endpoints behind VMD
+    - SAUCE: vmd: fixup bridge ASPM by driver name instead
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Double the speed of updateconfigs
+    - Remove ubuntu/hio driver
+    - [Config] update config after rebase to 5.19-rc8
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc8
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 25 Jul 2022 08:54:21 +0200
+
+linux (5.19.0-10.10) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-10.10 -proposed tracker (LP: #1982013)
+
+  * enable config for fixing 5.17 kernel won't load mok (LP: #1972802)
+    - [Config] enable configs for fixing kernel won't load mok
+
+  * RISC-V kernel config is out of sync with other archs (LP: #1981437)
+    - [Config] Disable CONFIG_CXL_MEM_RAW_COMMANDS on riscv64
+    - [Config] Disable CONFIG_EROFS_FS_ZIP_LZMA on riscv64
+    - [Config] Disable CONFIG_FONT_6x8 on riscv64
+    - [Config] Disable CONFIG_NTFS3_64BIT_CLUSTER on riscv64
+    - [Config] Disable CONFIG_SCSI_IZIP_EPP16 on riscv64
+    - [Config] Disable CONFIG_SCSI_UFS_HWMON on riscv64
+    - [Config] Disable CONFIG_SPI_AX88796C_COMPRESSION on riscv64
+    - [Config] Disable CONFIG_VIDEO_ZORAN on riscv64
+    - [Config] Enable CONFIG_BPF_KPROBE_OVERRIDE on riscv64
+    - [Config] Enable CONFIG_CACHEFILES_ERROR_INJECTION on riscv64
+    - [Config] Enable CONFIG_DRM_AMD_DC_SI on riscv64
+    - [Config] Enable CONFIG_NUMA_BALANCING on riscv64
+    - [Config] Enable CONFIG_PROC_VMCORE_DEVICE_DUMP on riscv64
+    - [Config] Enable CONFIG_WLAN_VENDOR_MICROCHIP on riscv64
+    - [Config] Set CONFIG_MHI_WWAN_CTRL=m on riscv64
+    - [Config] Set CONFIG_NFC_S3FWRN82_UART=m on riscv64
+    - [Config] Enable CONFIG_EFIVAR_FS on riscv64
+    - [Config] Enable CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES on riscv64
+    - [Config] Enable CONFIG_STRICT_DEVMEM on riscv64
+    - [Config] Enable CONFIG_VMAP_STACK on riscv64
+    - [Config] Enable CONFIG_KEXEC_FILE on riscv64
+    - [Config] Set CONFIG_MTD_PSTORE=m on riscv64
+    - [Config] Set CONFIG_KFENCE_SAMPLE_INTERVAL=0 on riscv64
+    - [Config] Enable CONFIG_KEXEC_FILE on s390x
+
+  * Ubuntu 22.04 and 20.04 DPC Fixes for Failure Cases of DownPort Containment
+    events (LP: #1965241)
+    - Enable config option CONFIG_PCIE_EDR
+    - Correct CONFIG_PCIE_EDR annotation on arm64
+
+  * config CONFIG_HISI_PMU for  kunpeng920 (LP: #1956086)
+    - [Config] CONFIG_HISI_PMU=m
+
+  * Skip setting ethernet LED on Dell EMC board (LP: #1971667)
+    - SAUCE: net: phy: marvell: Skip setting LED on Dell EMC board
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] ignore warnings from the output of ld.bfd
+    - [Packaging] Fix bashism in dkms-build script
+    - [Packaging] Always catch errors in dkms-build scripts
+    - [Packaging] Fix dkms builds with linker @module.mod files
+    - [Packaging] mark dkms-build-configure--zfs executable
+    - [Config] update configs and annotations after rebase to 5.19-rc7
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 18 Jul 2022 23:45:28 +0200
+
+linux (5.19.0-9.9) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-9.9 -proposed tracker (LP: #1980622)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update config after rebase to 5.19-rc5
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 04 Jul 2022 12:05:04 +0200
+
+linux (5.19.0-8.8) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-8.8 -proposed tracker (LP: #1980482)
+
+  * temporarily disable CONFIG_X86_KERNEL_IBT (LP: #1980484)
+    - [Config] temporarily disable CONFIG_X86_KERNEL_IBT
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 01 Jul 2022 11:58:56 +0200
+
+linux (5.19.0-7.7) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-7.7 -proposed tracker (LP: #1980056)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * RISC-V enables CONFIG_COMPAT in the unstable branch (LP: #1980061)
+    - [Config] Disable CONFIG_COMPAT on RISC-V
+
+  * No RISC-V configuration in the unstable tree (LP: #1979647)
+    - [Config] Merge riscv64 config and annotations
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 28 Jun 2022 12:25:48 +0200
+
+linux (5.19.0-6.6) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 28 Jun 2022 07:50:17 +0200
+
+linux-unstable (5.19.0-6.6) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-6.6 -proposed tracker (LP: #1979948)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Remove 'family=ubuntu' concept
+    - [Packaging] final-checks: Remove useless sourcing of kernelconfig
+    - [Config] update config after rebase to 5.19-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 27 Jun 2022 09:16:40 +0200
+
+linux-unstable (5.19.0-5.5) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-5.5 -proposed tracker (LP: #1979611)
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] temporarily disable signing for ppc64el and
+      s390x"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 23 Jun 2022 11:13:32 +0200
+
+linux-unstable (5.19.0-4.4) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-4.4 -proposed tracker (LP: #1979177)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs after rebase to 5.19-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 20 Jun 2022 09:02:58 +0200
+
+linux-unstable (5.19.0-3.3) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-3.3 -proposed tracker (LP: #1978439)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations for 5.19
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 13 Jun 2022 07:16:32 +0200
+
+linux-unstable (5.19.0-2.2) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-2.2 -proposed tracker (LP: #1978313)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 10 Jun 2022 15:17:20 +0200
+
+linux-unstable (5.19.0-1.1) kinetic; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * linux: Staging modules should be unsigned (LP: #1642368)
+    - [Packaging] Move and update signature inclusion list
+    - [Packaging] Strip signatures from untrusted staging modules
+    - [Packaging] Add module-signature-check
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to 5.19-rc1
+    - [Packaging] move to kernel 5.19
+    - [Packaging] workaround missing python3-dev dependency
+    - SAUCE: Revert "perf tools: Use Python devtools for version autodetection
+      rather than runtime"
+    - SAUCE: watchdog: gxp: Add missing MODULE_LICENSE
+    - [Packaging] add python3-dev as build dependency
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 10 Jun 2022 14:43:46 +0200
+
+linux-unstable (5.19.0-0.0) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 09 Jun 2022 12:13:06 +0200
+
+linux (5.18.0-6.6) kinetic; urgency=medium
+
+  * kinetic/linux: 5.18.0-6.6 -proposed tracker (LP: #1976327)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] temporarily disable signing for ppc64el and s390x
+    - [Config] update toolchain versions
+    - [Config] enable CONFIG_X86_KERNEL_IBT
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 31 May 2022 11:05:51 +0200
+
+linux (5.18.0-5.5) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 23 May 2022 16:59:47 +0200
+
+linux-unstable (5.18.0-5.5) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-5.5 -proposed tracker (LP: #1975458)
+
+  * enable CONFIG_DEVTMPFS_SAFE (LP: #1974442)
+    - [Config] enable CONFIG_DEVTMPFS_SAFE
+
+  * build backport-iwlwifi-dkms as linux-modules-iwlwifi-ABI (LP: #1969434)
+    - [Packaging] drop do_<mod> arch specific configs
+
+  * prevent kernel panic with overlayfs + shiftfs (LP: #1973620)
+    - SAUCE: overlayfs: prevent dereferencing struct file in ovl_vm_prfile_set()
+
+  * linux-image-5.0.0-35-generic breaks checkpointing of container
+    (LP: #1857257) // re-apply missing overlayfs SAUCE patch (LP: #1967924)
+    - SAUCE: overlayfs: fix incorrect mnt_id of files opened from map_files
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 23 May 2022 11:21:38 +0200
+
+linux-unstable (5.18.0-4.4) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-4.4 -proposed tracker (LP: #1973587)
+
+  * build backport-iwlwifi-dkms as linux-modules-iwlwifi-ABI (LP: #1969434)
+    - [Packaging] support standalone dkms module builds
+
+  * Enable speakup kernel modules to allow the speakup screen reader to function
+    (LP: #1967702)
+    - [Config] CONFIG_SPEAKUP=m for all but s390x
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] temporarily disable v4l2loopback"
+    - Revert "UBUNTU: [Packaging] temporarily disable zfs"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 16 May 2022 14:15:35 +0200
+
+linux-unstable (5.18.0-3.3) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-3.3 -proposed tracker (LP: #1972162)
+
+  * disable Intel DMA remapping by default (LP: #1971699)
+    - Revert "UBUNTU: [Config] enable Intel DMA remapping options by default"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 May 2022 12:15:39 +0200
+
+linux-unstable (5.18.0-2.2) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-2.2 -proposed tracker (LP: #1971340)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs after rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 03 May 2022 12:24:49 +0200
+
+linux-unstable (5.18.0-1.1) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 03 May 2022 09:38:06 +0200
+
+linux-unstable (5.18.0-1.1) jammy; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-1.1 -proposed tracker (LP: #1969476)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to 5.18
+    - [Packaging] temporarily disable zfs
+    - [Packaging] temporarily disable v4l2loopback
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 27 Apr 2022 20:26:42 +0200
+
+linux-unstable (5.18.0-0.0) jammy; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 19 Apr 2022 16:20:00 +0200
+
+linux-unstable (5.17.0-8.8) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-8.8 -proposed tracker (LP: #1969016)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 14 Apr 2022 10:30:39 +0200
+
+linux-unstable (5.17.0-7.7) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-7.7 -proposed tracker (LP: #1968988)
+
+  * zfcpdump-kernel update to v5.15 (LP: #1965766)
+    - SAUCE: Audit: Fix incorrect static inline function declration.
+
+  * intel_iommu breaks Intel IPU6 camera: isys port open ready failed -16
+    (LP: #1958004)
+    - SAUCE: iommu: intel-ipu: use IOMMU passthrough mode for Intel IPUs
+
+  * Jammy update: v5.17.3 upstream stable release (LP: #1968986)
+    - lib/logic_iomem: correct fallback config references
+    - um: fix and optimize xor select template for CONFIG64 and timetravel mode
+    - rtc: wm8350: Handle error for wm8350_register_irq
+    - net: dsa: felix: fix possible NULL pointer dereference
+    - mm: kfence: fix objcgs vector allocation
+    - KVM: x86/pmu: Use different raw event masks for AMD and Intel
+    - KVM: SVM: Fix kvm_cache_regs.h inclusions for is_guest_mode()
+    - KVM: x86/svm: Clear reserved bits written to PerfEvtSeln MSRs
+    - KVM: x86/pmu: Fix and isolate TSX-specific performance event logic
+    - KVM: x86/emulator: Emulate RDPID only if it is enabled in guest
+    - drm: Add orientation quirk for GPD Win Max
+    - Bluetooth: hci_sync: Fix compilation warning
+    - ath5k: fix OOB in ath5k_eeprom_read_pcal_info_5111
+    - Bluetooth: fix null ptr deref on hci_sync_conn_complete_evt
+    - drm/amd/display: Add signal type check when verify stream backends same
+    - drm/amdkfd: enable heavy-weight TLB flush on Arcturus
+    - drm/edid: remove non_desktop quirk for HPN-3515 and LEN-B800.
+    - drm/edid: improve non-desktop quirk logging
+    - Bluetooth: hci_event: Ignore multiple conn complete events
+    - drm/amd/amdgpu/amdgpu_cs: fix refcount leak of a dma_fence obj
+    - drm/amd/display: Fix memory leak
+    - drm/amd/display: Use PSR version selected during set_psr_caps
+    - usb: gadget: tegra-xudc: Do not program SPARAM
+    - usb: gadget: tegra-xudc: Fix control endpoint's definitions
+    - usb: cdnsp: fix cdnsp_decode_trb function to properly handle ret value
+    - ptp: replace snprintf with sysfs_emit
+    - Bluetooth: hci_sync: Fix queuing commands when HCI_UNREGISTER is set
+    - selftests, xsk: Fix bpf_res cleanup test
+    - net/mlx5e: TC, Hold sample_attr on stack instead of pointer
+    - drm/amdkfd: Don't take process mutex for svm ioctls
+    - drm/amdkfd: Ensure mm remain valid in svm deferred_list work
+    - drm/amdkfd: svm range restore work deadlock when process exit
+    - drm/amdgpu: Fix an error message in rmmod
+    - mlxsw: spectrum: Guard against invalid local ports
+    - RDMA/rtrs-clt: Do stop and failover outside reconnect work.
+    - powerpc/xive: Export XIVE IPI information for online-only processors.
+    - powerpc: dts: t104xrdb: fix phy type for FMAN 4/5
+    - ath11k: fix kernel panic during unload/load ath11k modules
+    - ath11k: pci: fix crash on suspend if board file is not found
+    - ath11k: mhi: use mhi_sync_power_up()
+    - net/smc: Send directly when TCP_CORK is cleared
+    - drm/bridge: Add missing pm_runtime_put_sync
+    - bpf: Make dst_port field in struct bpf_sock 16-bit wide
+    - scsi: mvsas: Replace snprintf() with sysfs_emit()
+    - scsi: bfa: Replace snprintf() with sysfs_emit()
+    - drm/v3d: fix missing unlock
+    - power: supply: axp20x_battery: properly report current when discharging
+    - mt76: mt7921: fix crash when startup fails.
+    - mt76: dma: initialize skip_unmap in mt76_dma_rx_fill
+    - i40e: Add sending commands in atomic context
+    - cfg80211: don't add non transmitted BSS to 6GHz scanned channels
+    - libbpf: Fix build issue with llvm-readelf
+    - ipv6: make mc_forwarding atomic
+    - ref_tracker: implement use-after-free detection
+    - net: initialize init_net earlier
+    - powerpc: Set crashkernel offset to mid of RMA region
+    - drm/amdgpu: Fix recursive locking warning
+    - scsi: smartpqi: Fix rmmod stack trace
+    - scsi: smartpqi: Fix kdump issue when controller is locked up
+    - PCI: aardvark: Fix support for MSI interrupts
+    - kvm: selftests: aarch64: fix assert in gicv3_access_reg
+    - kvm: selftests: aarch64: pass vgic_irq guest args as a pointer
+    - kvm: selftests: aarch64: fix the failure check in
+      kvm_set_gsi_routing_irqchip_check
+    - kvm: selftests: aarch64: fix some vgic related comments
+    - kvm: selftests: aarch64: use a tighter assert in vgic_poke_irq()
+    - iommu/arm-smmu-v3: fix event handling soft lockup
+    - usb: ehci: add pci device support for Aspeed platforms
+    - KVM: arm64: Do not change the PMU event filter after a VCPU has run
+    - libbpf: Fix accessing syscall arguments on powerpc
+    - libbpf: Fix accessing the first syscall argument on arm64
+    - libbpf: Fix accessing the first syscall argument on s390
+    - PCI: endpoint: Fix alignment fault error in copy tests
+    - tcp: Don't acquire inet_listen_hashbucket::lock with disabled BH.
+    - PCI: pciehp: Add Qualcomm quirk for Command Completed erratum
+    - scsi: mpi3mr: Fix deadlock while canceling the fw event
+    - scsi: mpi3mr: Fix reporting of actual data transfer size
+    - scsi: mpi3mr: Fix memory leaks
+    - powerpc/set_memory: Avoid spinlock recursion in change_page_attr()
+    - power: supply: axp288-charger: Set Vhold to 4.4V
+    - drm/sprd: fix potential NULL dereference
+    - drm/sprd: check the platform_get_resource() return value
+    - drm/amd/display: reset lane settings after each PHY repeater LT
+    - net/mlx5e: Disable TX queues before registering the netdev
+    - HID: apple: Report Magic Keyboard 2021 battery over USB
+    - HID: apple: Report Magic Keyboard 2021 with fingerprint reader battery over
+      USB
+    - usb: dwc3: pci: Set the swnode from inside dwc3_pci_quirks()
+    - iwlwifi: mvm: Correctly set fragmented EBS
+    - iwlwifi: fix small doc mistake for iwl_fw_ini_addr_val
+    - iwlwifi: mvm: move only to an enabled channel
+    - ipv6: annotate some data-races around sk->sk_prot
+    - drm/msm/dsi: Remove spurious IRQF_ONESHOT flag
+    - x86/mce: Work around an erratum on fast string copy instructions
+    - rtw89: fix RCU usage in rtw89_core_txq_push()
+    - ath11k: Fix frames flush failure caused by deadlock
+    - ipv4: Invalidate neighbour for broadcast address upon address addition
+    - rtw88: change rtw_info() to proper message level
+    - dm ioctl: prevent potential spectre v1 gadget
+    - dm: requeue IO if mapping table not yet available
+    - drm/amdkfd: make CRAT table missing message informational only
+    - vfio/pci: Stub vfio_pci_vga_rw when !CONFIG_VFIO_PCI_VGA
+    - scsi: pm8001: Fix pm80xx_pci_mem_copy() interface
+    - scsi: pm8001: Fix pm8001_mpi_task_abort_resp()
+    - scsi: pm8001: Fix tag values handling
+    - scsi: pm8001: Fix task leak in pm8001_send_abort_all()
+    - scsi: pm8001: Fix tag leaks on error
+    - scsi: pm8001: Fix memory leak in pm8001_chip_fw_flash_update_req()
+    - mt76: mt7915: fix injected MPDU transmission to not use HW A-MSDU
+    - mctp: make __mctp_dev_get() take a refcount hold
+    - powerpc/64s/hash: Make hash faults work in NMI context
+    - mt76: mt7615: Fix assigning negative values to unsigned variable
+    - power: supply: axp288_charger: Use acpi_quirk_skip_acpi_ac_and_battery()
+    - power: supply: axp288_fuel_gauge: Use acpi_quirk_skip_acpi_ac_and_battery()
+    - scsi: aha152x: Fix aha152x_setup() __setup handler return value
+    - scsi: hisi_sas: Free irq vectors in order for v3 HW
+    - scsi: hisi_sas: Limit users changing debugfs BIST count value
+    - net/smc: correct settings of RMB window update limit
+    - mips: ralink: fix a refcount leak in ill_acc_of_setup()
+    - iavf: stop leaking iavf_status as "errno" values
+    - macvtap: advertise link netns via netlink
+    - platform/x86: thinkpad_acpi: Add dual fan probe
+    - tuntap: add sanity checks about msg_controllen in sendmsg
+    - Bluetooth: mediatek: fix the conflict between mtk and msft vendor event
+    - Bluetooth: Fix not checking for valid hdev on bt_dev_{info,warn,err,dbg}
+    - Bluetooth: use memset avoid memory leaks
+    - bnxt_en: Eliminate unintended link toggle during FW reset
+    - PCI: endpoint: Fix misused goto label
+    - MIPS: fix fortify panic when copying asm exception handlers
+    - powerpc/code-patching: Pre-map patch area
+    - powerpc/64e: Tie PPC_BOOK3E_64 to PPC_FSL_BOOK3E
+    - powerpc/secvar: fix refcount leak in format_show()
+    - scsi: libfc: Fix use after free in fc_exch_abts_resp()
+    - platform/x86: x86-android-tablets: Depend on EFI and SPI
+    - can: isotp: set default value for N_As to 50 micro seconds
+    - can: etas_es58x: es58x_fd_rx_event_msg(): initialize rx_event_msg before
+      calling es58x_check_msg_len()
+    - riscv: Fixed misaligned memory access. Fixed pointer comparison.
+    - net: account alternate interface name memory
+    - net: limit altnames to 64k total
+    - net/mlx5e: Remove overzealous validations in netlink EEPROM query
+    - platform/x86: hp-wmi: Fix SW_TABLET_MODE detection method
+    - platform/x86: hp-wmi: Fix 0x05 error code reported by several WMI calls
+    - net: sfp: add 2500base-X quirk for Lantech SFP module
+    - usb: dwc3: omap: fix "unbalanced disables for smps10_out1" on omap5evm
+    - xen/usb: harden xen_hcd against malicious backends
+    - mt76: fix monitor mode crash with sdio driver
+    - xtensa: fix DTC warning unit_address_format
+    - iwlwifi: mei: fix building iwlmei
+    - MIPS: ingenic: correct unit node address
+    - Bluetooth: Fix use after free in hci_send_acl
+    - netfilter: conntrack: revisit gc autotuning
+    - netlabel: fix out-of-bounds memory accesses
+    - ceph: fix inode reference leakage in ceph_get_snapdir()
+    - ceph: fix memory leak in ceph_readdir when note_last_dentry returns error
+    - lib/Kconfig.debug: add ARCH dependency for FUNCTION_ALIGN option
+    - init/main.c: return 1 from handled __setup() functions
+    - minix: fix bug when opening a file with O_DIRECT
+    - clk: si5341: fix reported clk_rate when output divider is 2
+    - clk: mediatek: Fix memory leaks on probe
+    - staging: vchiq_arm: Avoid NULL ptr deref in vchiq_dump_platform_instances
+    - staging: vchiq_core: handle NULL result of find_service_by_handle
+    - phy: amlogic: phy-meson-gxl-usb2: fix shared reset controller use
+    - phy: amlogic: meson8b-usb2: Use dev_err_probe()
+    - phy: amlogic: meson8b-usb2: fix shared reset control use
+    - clk: rockchip: drop CLK_SET_RATE_PARENT from dclk_vop* on rk3568
+    - cpufreq: CPPC: Fix performance/frequency conversion
+    - opp: Expose of-node's name in debugfs
+    - staging: wfx: apply the necessary SDIO quirks for the Silabs WF200
+    - staging: wfx: fix an error handling in wfx_init_common()
+    - w1: w1_therm: fixes w1_seq for ds28ea00 sensors
+    - NFSv4.2: fix reference count leaks in _nfs42_proc_copy_notify()
+    - NFSv4: Protect the state recovery thread against direct reclaim
+    - habanalabs: fix possible memory leak in MMU DR fini
+    - habanalabs: reject host map with mmu disabled
+    - habanalabs/gaudi: handle axi errors from NIC engines
+    - xen: delay xen_hvm_init_time_ops() if kdump is boot on vcpu>=32
+    - clk: ti: Preserve node in ti_dt_clocks_register()
+    - clk: Enforce that disjoints limits are invalid
+    - SUNRPC/xprt: async tasks mustn't block waiting for memory
+    - SUNRPC: remove scheduling boost for "SWAPPER" tasks.
+    - NFS: swap IO handling is slightly different for O_DIRECT IO
+    - NFS: swap-out must always use STABLE writes.
+    - x86: Annotate call_on_stack()
+    - x86/Kconfig: Do not allow CONFIG_X86_X32_ABI=y with llvm-objcopy
+    - serial: samsung_tty: do not unlock port->lock for uart_write_wakeup()
+    - virtio_console: eliminate anonymous module_init & module_exit
+    - jfs: prevent NULL deref in diFree
+    - SUNRPC: Fix socket waits for write buffer space
+    - NFS: nfsiod should not block forever in mempool_alloc()
+    - NFS: Avoid writeback threads getting stuck in mempool_alloc()
+    - selftests: net: Add tls config dependency for tls selftests
+    - parisc: Fix CPU affinity for Lasi, WAX and Dino chips
+    - parisc: Fix patch code locking and flushing
+    - mm: fix race between MADV_FREE reclaim and blkdev direct IO read
+    - drm/amdgpu: fix off by one in amdgpu_gfx_kiq_acquire()
+    - Drivers: hv: vmbus: Fix initialization of device object in
+      vmbus_device_register()
+    - Drivers: hv: vmbus: Fix potential crash on module unload
+    - netfilter: bitwise: fix reduce comparisons
+    - Revert "NFSv4: Handle the special Linux file open access mode"
+    - NFSv4: fix open failure with O_ACCMODE flag
+    - scsi: core: scsi_logging: Fix a BUG
+    - scsi: sr: Fix typo in CDROM(CLOSETRAY|EJECT) handling
+    - scsi: core: Fix sbitmap depth in scsi_realloc_sdev_budget_map()
+    - scsi: zorro7xx: Fix a resource leak in zorro7xx_remove_one()
+    - vdpa: mlx5: prevent cvq work from hogging CPU
+    - net: sfc: add missing xdp queue reinitialization
+    - net/tls: fix slab-out-of-bounds bug in decrypt_internal
+    - vrf: fix packet sniffing for traffic originating from ip tunnels
+    - skbuff: fix coalescing for page_pool fragment recycling
+    - Revert "net: dsa: stop updating master MTU from master.c"
+    - ice: Clear default forwarding VSI during VSI release
+    - ice: Fix MAC address setting
+    - mctp: Fix check for dev_hard_header() result
+    - mctp: Use output netdev to allocate skb headroom
+    - net: ipv4: fix route with nexthop object delete warning
+    - net: stmmac: Fix unset max_speed difference between DT and non-DT platforms
+    - drm/imx: imx-ldb: Check for null pointer after calling kmemdup
+    - drm/imx: Fix memory leak in imx_pd_connector_get_modes
+    - drm/imx: dw_hdmi-imx: Fix bailout in error cases of probe
+    - regulator: rtq2134: Fix missing active_discharge_on setting
+    - spi: rpc-if: Fix RPM imbalance in probe error path
+    - regulator: atc260x: Fix missing active_discharge_on setting
+    - arch/arm64: Fix topology initialization for core scheduling
+    - bnxt_en: Synchronize tx when xdp redirects happen on same ring
+    - bnxt_en: reserve space inside receive page for skb_shared_info
+    - bnxt_en: Prevent XDP redirect from running when stopping TX queue
+    - sfc: Do not free an empty page_ring
+    - RDMA/mlx5: Don't remove cache MRs when a delay is needed
+    - RDMA/mlx5: Add a missing update of cache->last_add
+    - IB/cm: Cancel mad on the DREQ event when the state is MRA_REP_RCVD
+    - cifs: fix potential race with cifsd thread
+    - IB/rdmavt: add lock to call to rvt_error_qp to prevent a race condition
+    - sctp: count singleton chunks in assoc user stats
+    - dpaa2-ptp: Fix refcount leak in dpaa2_ptp_probe
+    - ice: Set txq_teid to ICE_INVAL_TEID on ring creation
+    - ice: Do not skip not enabled queues in ice_vc_dis_qs_msg
+    - ipv6: Fix stats accounting in ip6_pkt_drop
+    - ice: synchronize_rcu() when terminating rings
+    - ice: xsk: fix VSI state check in ice_xsk_wakeup()
+    - ice: clear cmd_type_offset_bsz for TX rings
+    - net: openvswitch: don't send internal clone attribute to the userspace.
+    - net: ethernet: mv643xx: Fix over zealous checking of_get_mac_address()
+    - net: openvswitch: fix leak of nested actions
+    - rxrpc: fix a race in rxrpc_exit_net()
+    - net: sfc: fix using uninitialized xdp tx_queue
+    - net: phy: mscc-miim: reject clause 45 register accesses
+    - qede: confirm skb is allocated before using
+    - spi: bcm-qspi: fix MSPI only access with bcm_qspi_exec_mem_op()
+    - drm/amd/display: Fix for dmub outbox notification enable
+    - drm/amd/display: Remove redundant dsc power gating from init_hw
+    - bpf: Support dual-stack sockets in bpf_tcp_check_syncookie
+    - drbd: Fix five use after free bugs in get_initial_state
+    - scsi: sd: sd_read_cpr() requires VPD pages
+    - scsi: ufs: ufshpb: Fix a NULL check on list iterator
+    - io_uring: nospec index for tags on files update
+    - io_uring: don't touch scm_fp_list after queueing skb
+    - SUNRPC: Handle ENOMEM in call_transmit_status()
+    - SUNRPC: Handle low memory situations in call_status()
+    - SUNRPC: svc_tcp_sendmsg() should handle errors from xdr_alloc_bvec()
+    - iommu/omap: Fix regression in probe for NULL pointer dereference
+    - perf unwind: Don't show unwind error messages when augmenting frame pointer
+      stack
+    - perf: arm-spe: Fix perf report --mem-mode
+    - perf tools: Fix perf's libperf_print callback
+    - perf session: Remap buf if there is no space for event
+    - arm64: Add part number for Arm Cortex-A78AE
+    - scsi: mpt3sas: Fix use after free in _scsih_expander_node_remove()
+    - scsi: ufs: ufs-pci: Add support for Intel MTL
+    - Revert "mmc: sdhci-xenon: fix annoying 1.8V regulator warning"
+    - mmc: block: Check for errors after write on SPI
+    - mmc: mmci: stm32: correctly check all elements of sg list
+    - mmc: renesas_sdhi: special 4tap settings only apply to HS400
+    - mmc: renesas_sdhi: don't overwrite TAP settings when HS400 tuning is
+      complete
+    - mmc: core: Fixup support for writeback-cache for eMMC and SD
+    - lz4: fix LZ4_decompress_safe_partial read out of bound
+    - highmem: fix checks in __kmap_local_sched_{in,out}
+    - mmmremap.c: avoid pointless invalidate_range_start/end on mremap(old_size=0)
+    - mm/mempolicy: fix mpol_new leak in shared_policy_replace
+    - io_uring: don't check req->file in io_fsync_prep()
+    - io_uring: defer splice/tee file validity check until command issue
+    - io_uring: implement compat handling for IORING_REGISTER_IOWQ_AFF
+    - io_uring: fix race between timeout flush and removal
+    - x86/pm: Save the MSR validity status at context setup
+    - x86/speculation: Restore speculation related MSRs during S3 resume
+    - perf/x86/intel: Update the FRONTEND MSR mask on Sapphire Rapids
+    - btrfs: fix qgroup reserve overflow the qgroup limit
+    - btrfs: zoned: traverse devices under chunk_mutex in btrfs_can_activate_zone
+    - btrfs: remove device item and update super block in the same transaction
+    - btrfs: avoid defragging extents whose next extents are not targets
+    - btrfs: prevent subvol with swapfile from being deleted
+    - spi: core: add dma_map_dev for __spi_unmap_msg()
+    - cifs: force new session setup and tcon for dfs
+    - qed: fix ethtool register dump
+    - arm64: patch_text: Fixup last cpu should be master
+    - RDMA/hfi1: Fix use-after-free bug for mm struct
+    - drbd: fix an invalid memory access caused by incorrect use of list iterator
+    - gpio: Restrict usage of GPIO chip irq members before initialization
+    - x86/msi: Fix msi message data shadow struct
+    - x86/mm/tlb: Revert retpoline avoidance approach
+    - perf/x86/intel: Don't extend the pseudo-encoding to GP counters
+    - ata: sata_dwc_460ex: Fix crash due to OOB write
+    - perf: qcom_l2_pmu: fix an incorrect NULL check on list iterator
+    - perf/core: Inherit event_caps
+    - irqchip/gic-v3: Fix GICR_CTLR.RWP polling
+    - fbdev: Fix unregistering of framebuffers without device
+    - amd/display: set backlight only if required
+    - drm/panel: ili9341: fix optional regulator handling
+    - drm/amd/display: Fix by adding FPU protection for dcn30_internal_validate_bw
+    - drm/amdgpu/display: change pipe policy for DCN 2.1
+    - drm/amdgpu/smu10: fix SoC/fclk units in auto mode
+    - drm/amdgpu/vcn: Fix the register setting for vcn1
+    - drm/nouveau/pmu: Add missing callbacks for Tegra devices
+    - drm/amdkfd: Create file descriptor after client is added to smi_clients list
+    - drm/amdgpu: don't use BACO for reset in S3
+    - SUNRPC: Ensure we flush any closed sockets before xs_xprt_free()
+    - Revert "ACPI: processor: idle: Only flush cache on entering C3"
+    - drm/amdkfd: Fix variable set but not used warning
+    - net/smc: send directly on setting TCP_NODELAY
+    - Revert "selftests: net: Add tls config dependency for tls selftests"
+    - bpf: Make remote_port field in struct bpf_sk_lookup 16-bit wide
+    - selftests/bpf: Fix u8 narrow load checks for bpf_sk_lookup remote_port
+    - bpf: Treat bpf_sk_lookup remote_port as a 2-byte field
+    - perf build: Don't use -ffat-lto-objects in the python feature test when
+      building with clang-13
+    - perf python: Fix probing for some clang command line options
+    - tools build: Filter out options and warnings not supported by clang
+    - tools build: Use $(shell ) instead of `` to get embedded libperl's ccopts
+    - dmaengine: Revert "dmaengine: shdma: Fix runtime PM imbalance on error"
+    - KVM: avoid NULL pointer dereference in kvm_dirty_ring_push
+    - Drivers: hv: vmbus: Replace smp_store_mb() with virt_store_mb()
+    - powerpc: Fix virt_addr_valid() for 64-bit Book3E & 32-bit
+    - Revert "powerpc: Set max_mapnr correctly"
+    - x86/bug: Prevent shadowing in __WARN_FLAGS
+    - objtool: Fix SLS validation for kcov tail-call replacement
+    - sched/core: Fix forceidle balancing
+    - sched: Teach the forced-newidle balancer about CPU affinity limitation.
+    - x86,static_call: Fix __static_call_return0 for i386
+    - x86/extable: Prefer local labels in .set directives
+    - irqchip/gic-v4: Wait for GICR_VPENDBASER.Dirty to clear before descheduling
+    - powerpc/64: Fix build failure with allyesconfig in book3s_64_entry.S
+    - irqchip/gic, gic-v3: Prevent GSI to SGI translations
+    - mm/sparsemem: fix 'mem_section' will never be NULL gcc 12 warning
+    - static_call: Don't make __static_call_return0 static
+    - io_uring: move read/write file prep state into actual opcode handler
+    - io_uring: propagate issue_flags state down to file assignment
+    - io_uring: defer file assignment
+    - io_uring: drop the old style inflight file tracking
+    - Linux 5.17.3
+
+  * Jammy update: v5.17.2 upstream stable release Edit (LP: #1968984)
+    - Revert "swiotlb: rework "fix info leak with DMA_FROM_DEVICE""
+    - USB: serial: pl2303: add IBM device IDs
+    - dt-bindings: usb: hcd: correct usb-device path
+    - USB: serial: pl2303: fix GS type detection
+    - USB: serial: simple: add Nokia phone driver
+    - mm: kfence: fix missing objcg housekeeping for SLAB
+    - locking/lockdep: Avoid potential access of invalid memory in lock_class
+    - drm/amdgpu: move PX checking into amdgpu_device_ip_early_init
+    - drm/amdgpu: only check for _PR3 on dGPUs
+    - iommu/iova: Improve 32-bit free space estimate
+    - block: flush plug based on hardware and software queue order
+    - block: ensure plug merging checks the correct queue at least once
+    - usb: typec: tipd: Forward plug orientation to typec subsystem
+    - USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c
+    - xhci: fix garbage USBSTS being logged in some cases
+    - xhci: fix runtime PM imbalance in USB2 resume
+    - xhci: make xhci_handshake timeout for xhci_reset() adjustable
+    - xhci: fix uninitialized string returned by xhci_decode_ctrl_ctx()
+    - mei: me: disable driver on the ign firmware
+    - mei: me: add Alder Lake N device id.
+    - mei: avoid iterator usage outside of list_for_each_entry
+    - bus: mhi: pci_generic: Add mru_default for Quectel EM1xx series
+    - bus: mhi: Fix pm_state conversion to string
+    - bus: mhi: Fix MHI DMA structure endianness
+    - docs: sphinx/requirements: Limit jinja2<3.1
+    - coresight: Fix TRCCONFIGR.QE sysfs interface
+    - coresight: syscfg: Fix memleak on registration failure in
+      cscfg_create_device
+    - dt-bindings: iio: adc: zynqmp_ams: Add clock entry
+    - iio: adc: xilinx-ams: Fix single channel switching sequence
+    - iio: accel: mma8452: use the correct logic to get mma8452_data
+    - iio: adc: aspeed: Add divider flag to fix incorrect voltage reading.
+    - iio: imu: st_lsm6dsx: use dev_to_iio_dev() to get iio_dev struct
+    - iio: afe: rescale: use s64 for temporary scale calculations
+    - iio: adc: xilinx-ams: Fixed missing PS channels
+    - iio: adc: xilinx-ams: Fixed wrong sequencer register settings
+    - iio: inkern: apply consumer scale on IIO_VAL_INT cases
+    - iio: inkern: apply consumer scale when no channel scale is available
+    - iio: inkern: make a best effort on offset calculation
+    - greybus: svc: fix an error handling bug in gb_svc_hello()
+    - clk: rockchip: re-add rational best approximation algorithm to the
+      fractional divider
+    - clk: uniphier: Fix fixed-rate initialization
+    - ptrace: Check PTRACE_O_SUSPEND_SECCOMP permission on PTRACE_SEIZE
+    - cifs: truncate the inode and mapping when we simulate fcollapse
+    - cifs: fix handlecache and multiuser
+    - cifs: we do not need a spinlock around the tree access during umount
+    - KEYS: fix length validation in keyctl_pkey_params_get_2()
+    - KEYS: asymmetric: enforce that sig algo matches key algo
+    - KEYS: asymmetric: properly validate hash_algo and encoding
+    - Documentation: add link to stable release candidate tree
+    - Documentation: update stable tree link
+    - firmware: stratix10-svc: add missing callback parameter on RSU
+    - firmware: sysfb: fix platform-device leak in error path
+    - HID: intel-ish-hid: Use dma_alloc_coherent for firmware update
+    - SUNRPC: avoid race between mod_timer() and del_timer_sync()
+    - SUNRPC: Do not dereference non-socket transports in sysfs
+    - NFS: NFSv2/v3 clients should never be setting NFS_CAP_XATTR
+    - NFSD: prevent underflow in nfssvc_decode_writeargs()
+    - NFSD: prevent integer overflow on 32 bit systems
+    - f2fs: fix to unlock page correctly in error path of is_alive()
+    - f2fs: quota: fix loop condition at f2fs_quota_sync()
+    - f2fs: fix to do sanity check on .cp_pack_total_block_count
+    - remoteproc: Fix count check in rproc_coredump_write()
+    - mm/mlock: fix two bugs in user_shm_lock()
+    - pinctrl: ingenic: Fix regmap on X series SoCs
+    - pinctrl: samsung: drop pin banks references on error paths
+    - net: bnxt_ptp: fix compilation error
+    - spi: mxic: Fix the transmit path
+    - mtd: spi-nor: Skip erase logic when SPI_NOR_NO_ERASE is set
+    - mtd: rawnand: protect access to rawnand devices while in suspend
+    - can: ems_usb: ems_usb_start_xmit(): fix double dev_kfree_skb() in error path
+    - can: m_can: m_can_tx_handler(): fix use after free of skb
+    - can: usb_8dev: usb_8dev_start_xmit(): fix double dev_kfree_skb() in error
+      path
+    - jffs2: fix use-after-free in jffs2_clear_xattr_subsystem
+    - jffs2: fix memory leak in jffs2_do_mount_fs
+    - jffs2: fix memory leak in jffs2_scan_medium
+    - mm: fs: fix lru_cache_disabled race in bh_lru
+    - mm: don't skip swap entry even if zap_details specified
+    - mm/pages_alloc.c: don't create ZONE_MOVABLE beyond the end of a node
+    - mm: invalidate hwpoison page cache page in fault path
+    - mempolicy: mbind_range() set_policy() after vma_merge()
+    - scsi: core: sd: Add silence_suspend flag to suppress some PM messages
+    - scsi: ufs: Fix runtime PM messages never-ending cycle
+    - scsi: scsi_transport_fc: Fix FPIN Link Integrity statistics counters
+    - scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands
+    - qed: display VF trust config
+    - qed: validate and restrict untrusted VFs vlan promisc mode
+    - riscv: dts: canaan: Fix SPI3 bus width
+    - riscv: Fix fill_callchain return value
+    - riscv: Increase stack size under KASAN
+    - RISC-V: Declare per cpu boot data as static
+    - Revert "Input: clear BTN_RIGHT/MIDDLE on buttonpads"
+    - cifs: do not skip link targets when an I/O fails
+    - cifs: fix incorrect use of list iterator after the loop
+    - cifs: prevent bad output lengths in smb2_ioctl_query_info()
+    - cifs: fix NULL ptr dereference in smb2_ioctl_query_info()
+    - ALSA: cs4236: fix an incorrect NULL check on list iterator
+    - ALSA: hda: Avoid unsol event during RPM suspending
+    - ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock
+    - ALSA: hda/realtek: Fix audio regression on Mi Notebook Pro 2020
+    - rtc: mc146818-lib: fix locking in mc146818_set_time
+    - rtc: pl031: fix rtc features null pointer dereference
+    - io_uring: ensure that fsnotify is always called
+    - ocfs2: fix crash when mount with quota enabled
+    - drm/simpledrm: Add "panel orientation" property on non-upright mounted LCD
+      panels
+    - mm: madvise: skip unmapped vma holes passed to process_madvise
+    - mm: madvise: return correct bytes advised with process_madvise
+    - Revert "mm: madvise: skip unmapped vma holes passed to process_madvise"
+    - mm,hwpoison: unmap poisoned page before invalidation
+    - mm: only re-generate demotion targets when a numa node changes its N_CPU
+      state
+    - mm/kmemleak: reset tag when compare object pointer
+    - dm stats: fix too short end duration_ns when using precise_timestamps
+    - dm: fix use-after-free in dm_cleanup_zoned_dev()
+    - dm: interlock pending dm_io and dm_wait_for_bios_completion
+    - dm: fix double accounting of flush with data
+    - dm integrity: set journal entry unused when shrinking device
+    - tracing: Have trace event string test handle zero length strings
+    - drbd: fix potential silent data corruption
+    - can: isotp: sanitize CAN ID checks in isotp_bind()
+    - PCI: fu740: Force 2.5GT/s for initial device probe
+    - arm64: signal: nofpsimd: Do not allocate fp/simd context when not available
+    - arm64: Do not defer reserve_crashkernel() for platforms with no DMA memory
+      zones
+    - arm64: dts: qcom: sm8250: Fix MSI IRQ for PCIe1 and PCIe2
+    - arm64: dts: ti: k3-am65: Fix gic-v3 compatible regs
+    - arm64: dts: ti: k3-j721e: Fix gic-v3 compatible regs
+    - arm64: dts: ti: k3-j7200: Fix gic-v3 compatible regs
+    - arm64: dts: ti: k3-am64: Fix gic-v3 compatible regs
+    - arm64: dts: ti: k3-j721s2: Fix gic-v3 compatible regs
+    - ASoC: SOF: Intel: Fix NULL ptr dereference when ENOMEM
+    - mmc: core: use sysfs_emit() instead of sprintf()
+    - Revert "ACPI: Pass the same capabilities to the _OSC regardless of the query
+      flag"
+    - ACPI: properties: Consistently return -ENOENT if there are no more
+      references
+    - coredump: Also dump first pages of non-executable ELF libraries
+    - ext4: fix ext4_fc_stats trace point
+    - ext4: fix fs corruption when tring to remove a non-empty directory with IO
+      error
+    - ext4: make mb_optimize_scan option work with set/unset mount cmd
+    - ext4: make mb_optimize_scan performance mount option work with extents
+    - samples/landlock: Fix path_list memory leak
+    - landlock: Use square brackets around "landlock-ruleset"
+    - mailbox: tegra-hsp: Flush whole channel
+    - btrfs: zoned: put block group after final usage
+    - block: fix rq-qos breakage from skipping rq_qos_done_bio()
+    - block: limit request dispatch loop duration
+    - block: don't merge across cgroup boundaries if blkcg is enabled
+    - drm/edid: check basic audio support on CEA extension block
+    - fbdev: Hot-unplug firmware fb devices on forced removal
+    - video: fbdev: sm712fb: Fix crash in smtcfb_read()
+    - video: fbdev: atari: Atari 2 bpp (STe) palette bugfix
+    - rfkill: make new event layout opt-in
+    - ARM: dts: at91: sama7g5: Remove unused properties in i2c nodes
+    - ARM: dts: at91: sama5d2: Fix PMERRLOC resource size
+    - ARM: dts: exynos: fix UART3 pins configuration in Exynos5250
+    - ARM: dts: exynos: add missing HDMI supplies on SMDK5250
+    - ARM: dts: exynos: add missing HDMI supplies on SMDK5420
+    - mgag200 fix memmapsl configuration in GCTL6 register
+    - carl9170: fix missing bit-wise or operator for tx_params
+    - pstore: Don't use semaphores in always-atomic-context code
+    - thermal: int340x: Increase bitmap size
+    - lib/raid6/test: fix multiple definition linking error
+    - exec: Force single empty string when argv is empty
+    - crypto: rsa-pkcs1pad - only allow with rsa
+    - crypto: rsa-pkcs1pad - correctly get hash from source scatterlist
+    - crypto: rsa-pkcs1pad - restore signature length check
+    - crypto: rsa-pkcs1pad - fix buffer overread in pkcs1pad_verify_complete()
+    - bcache: fixup multiple threads crash
+    - PM: domains: Fix sleep-in-atomic bug caused by genpd_debug_remove()
+    - DEC: Limit PMAX memory probing to R3k systems
+    - media: gpio-ir-tx: fix transmit with long spaces on Orange Pi PC
+    - media: omap3isp: Use struct_group() for memcpy() region
+    - media: venus: vdec: fixed possible memory leak issue
+    - media: venus: hfi_cmds: List HDR10 property as unsupported for v1 and v3
+    - media: venus: venc: Fix h264 8x8 transform control
+    - media: davinci: vpif: fix unbalanced runtime PM get
+    - media: davinci: vpif: fix unbalanced runtime PM enable
+    - media: davinci: vpif: fix use-after-free on driver unbind
+    - mips: Always permit to build u-boot images
+    - btrfs: zoned: mark relocation as writing
+    - btrfs: extend locking to all space_info members accesses
+    - btrfs: verify the tranisd of the to-be-written dirty extent buffer
+    - xtensa: define update_mmu_tlb function
+    - xtensa: fix stop_machine_cpuslocked call in patch_text
+    - xtensa: fix xtensa_wsr always writing 0
+    - KVM: s390x: fix SCK locking
+    - drm/syncobj: flatten dma_fence_chains on transfer
+    - drm/nouveau/backlight: Fix LVDS backlight detection on some laptops
+    - drm/nouveau/backlight: Just set all backlight types as RAW
+    - drm/fb-helper: Mark screen buffers in system memory with FBINFO_VIRTFB
+    - brcmfmac: firmware: Allocate space for default boardrev in nvram
+    - brcmfmac: pcie: Release firmwares in the brcmf_pcie_setup error path
+    - brcmfmac: pcie: Declare missing firmware files in pcie.c
+    - brcmfmac: pcie: Replace brcmf_pcie_copy_mem_todev with memcpy_toio
+    - brcmfmac: pcie: Fix crashes due to early IRQs
+    - drm/i915/opregion: check port number bounds for SWSCI display power state
+    - drm/i915/gem: add missing boundary check in vm_access
+    - PCI: imx6: Allow to probe when dw_pcie_wait_for_link() fails
+    - PCI: pciehp: Clear cmd_busy bit in polling mode
+    - PCI: xgene: Revert "PCI: xgene: Use inbound resources for setup"
+    - PCI: xgene: Revert "PCI: xgene: Fix IB window setup"
+    - regulator: qcom_smd: fix for_each_child.cocci warnings
+    - selinux: access superblock_security_struct in LSM blob way
+    - selinux: check return value of sel_make_avc_files
+    - crypto: ccp - Ensure psp_ret is always init'd in
+      __sev_platform_init_locked()
+    - crypto: qat - fix a signedness bug in get_service_enabled()
+    - hwrng: cavium - HW_RANDOM_CAVIUM should depend on ARCH_THUNDER
+    - crypto: sun8i-ss - really disable hash on A80
+    - crypto: kdf - Select hmac in addition to sha256
+    - crypto: qat - fix access to PFVF interrupt registers for GEN4
+    - crypto: authenc - Fix sleep in atomic context in decrypt_tail
+    - crypto: octeontx2 - select CONFIG_NET_DEVLINK
+    - crypto: mxs-dcp - Fix scatterlist processing
+    - selinux: Fix selinux_sb_mnt_opts_compat()
+    - thermal: int340x: Check for NULL after calling kmemdup()
+    - crypto: octeontx2 - remove CONFIG_DM_CRYPT check
+    - spi: tegra114: Add missing IRQ check in tegra_spi_probe
+    - spi: tegra210-quad: Fix missin IRQ check in tegra_qspi_probe
+    - perf: MARVELL_CN10K_TAD_PMU should depend on ARCH_THUNDER
+    - selftests/sgx: Fix NULL-pointer-dereference upon early test failure
+    - selftests/sgx: Do not attempt enclave build without valid enclave
+    - selftests/sgx: Ensure enclave data available during debug print
+    - stack: Constrain and fix stack offset randomization with Clang builds
+    - arm64/mm: avoid fixmap race condition when create pud mapping
+    - security: add sctp_assoc_established hook
+    - blk-cgroup: set blkg iostat after percpu stat aggregation
+    - selftests/x86: Add validity check and allow field splitting
+    - selftests/sgx: Treat CC as one argument
+    - crypto: rockchip - ECB does not need IV
+    - block: update io_ticks when io hang
+    - audit: log AUDIT_TIME_* records only from rules
+    - EVM: fix the evm= __setup handler return value
+    - crypto: ccree - don't attempt 0 len DMA mappings
+    - crypto: hisilicon/sec - fix the aead software fallback for engine
+    - spi: pxa2xx-pci: Balance reference count for PCI DMA device
+    - hwmon: (pmbus) Add mutex to regulator ops
+    - hwmon: (sch56xx-common) Replace WDOG_ACTIVE with WDOG_HW_RUNNING
+    - nvme: cleanup __nvme_check_ids
+    - nvme: fix the check for duplicate unique identifiers
+    - block: don't delete queue kobject before its children
+    - PM: hibernate: fix __setup handler error handling
+    - PM: suspend: fix return value of __setup handler
+    - spi: spi-zynqmp-gqspi: Handle error for dma_set_mask
+    - hwrng: atmel - disable trng on failure path
+    - crypto: sun8i-ss - call finalize with bh disabled
+    - crypto: sun8i-ce - call finalize with bh disabled
+    - crypto: amlogic - call finalize with bh disabled
+    - crypto: gemini - call finalize with bh disabled
+    - crypto: vmx - add missing dependencies
+    - clocksource/drivers/timer-ti-dm: Fix regression from errata i940 fix
+    - clocksource/drivers/exynos_mct: Handle DTS with higher number of interrupts
+    - clocksource/drivers/timer-microchip-pit64b: Use notrace
+    - clocksource/drivers/timer-of: Check return value of of_iomap in
+      timer_of_base_init()
+    - arm64: prevent instrumentation of bp hardening callbacks
+    - perf/arm-cmn: Hide XP PUB events for CMN-600
+    - perf/arm-cmn: Update watchpoint format
+    - KEYS: trusted: Fix trusted key backends when building as module
+    - KEYS: trusted: Avoid calling null function trusted_key_exit
+    - ACPI: APEI: fix return value of __setup handlers
+    - crypto: ccp - ccp_dmaengine_unregister release dma channels
+    - crypto: ccree - Fix use after free in cc_cipher_exit()
+    - crypto: qat - fix initialization of pfvf cap_msg structures
+    - crypto: qat - fix initialization of pfvf rts_map_msg structures
+    - hwrng: nomadik - Change clk_disable to clk_disable_unprepare
+    - hwmon: (pmbus) Add Vin unit off handling
+    - clocksource: acpi_pm: fix return value of __setup handler
+    - io_uring: don't check unrelated req->open.how in accept request
+    - io_uring: terminate manual loop iterator loop correctly for non-vecs
+    - watch_queue: Fix NULL dereference in error cleanup
+    - watch_queue: Actually free the watch
+    - f2fs: fix to enable ATGC correctly via gc_idle sysfs interface
+    - sched/debug: Remove mpol_get/put and task_lock/unlock from sched_show_numa
+    - sched/core: Export pelt_thermal_tp
+    - sched/sugov: Ignore 'busy' filter when rq is capped by uclamp_max
+    - sched/uclamp: Fix iowait boost escaping uclamp restriction
+    - rseq: Remove broken uapi field layout on 32-bit little endian
+    - perf/core: Fix address filter parser for multiple filters
+    - perf/x86/intel/pt: Fix address filter config for 32-bit kernel
+    - sched/fair: Improve consistency of allowed NUMA balance calculations
+    - f2fs: fix missing free nid in f2fs_handle_failed_inode
+    - ext4: fix remount with 'abort' option
+    - nfsd: more robust allocation failure handling in nfsd_file_cache_init
+    - sched/cpuacct: Fix charge percpu cpuusage
+    - sched/rt: Plug rt_mutex_setprio() vs push_rt_task() race
+    - f2fs: fix to avoid potential deadlock
+    - btrfs: fix unexpected error path when reflinking an inline extent
+    - iomap: Fix iomap_invalidatepage tracepoint
+    - fs: erofs: add sanity check for kobject in erofs_unregister_sysfs
+    - f2fs: fix compressed file start atomic write may cause data corruption
+    - cifs: use a different reconnect helper for non-cifsd threads
+    - selftests, x86: fix how check_cc.sh is being invoked
+    - drivers/base/memory: add memory block to memory group after registration
+      succeeded
+    - kunit: make kunit_test_timeout compatible with comment
+    - pinctrl: samsung: Remove EINT handler for Exynos850 ALIVE and CMGP gpios
+    - media: staging: media: zoran: fix usage of vb2_dma_contig_set_max_seg_size
+    - media: camss: csid-170: fix non-10bit formats
+    - media: camss: csid-170: don't enable unused irqs
+    - media: camss: csid-170: set the right HALT_CMD when disabled
+    - media: camss: vfe-170: fix "VFE halt timeout" error
+    - media: staging: media: imx: imx7-mipi-csis: Make subdev name unique
+    - media: v4l2-mem2mem: Apply DST_QUEUE_OFF_BASE on MMAP buffers across ioctls
+    - media: mtk-vcodec: potential dereference of null pointer
+    - media: imx: imx8mq-mipi-csi2: remove wrong irq config write operation
+    - media: imx: imx8mq-mipi_csi2: fix system resume
+    - media: bttv: fix WARNING regression on tunerless devices
+    - media: atmel: atmel-sama7g5-isc: fix ispck leftover
+    - ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively
+    - ASoC: codecs: Check for error pointer after calling devm_regmap_init_mmio
+    - ASoC: xilinx: xlnx_formatter_pcm: Handle sysclk setting
+    - ASoC: simple-card-utils: Set sysclk on all components
+    - memory: tegra20-emc: Correct memory device mask
+    - media: coda: Fix missing put_device() call in coda_get_vdoa_data
+    - media: meson: vdec: potential dereference of null pointer
+    - media: hantro: Fix overfill bottom register field name
+    - media: ov6650: Fix set format try processing path
+    - media: v4l: Avoid unaligned access warnings when printing 4cc modifiers
+    - media: ov5648: Don't pack controls struct
+    - media: ov2740: identify module after subdev initialisation
+    - media: aspeed: Correct value for h-total-pixels
+    - video: fbdev: matroxfb: set maxvram of vbG200eW to the same as vbG200 to
+      avoid black screen
+    - video: fbdev: controlfb: Fix COMPILE_TEST build
+    - video: fbdev: smscufx: Fix null-ptr-deref in ufx_usb_probe()
+    - video: fbdev: atmel_lcdfb: fix an error code in atmel_lcdfb_probe()
+    - video: fbdev: fbcvt.c: fix printing in fb_cvt_print_name()
+    - ARM: dts: Fix OpenBMC flash layout label addresses
+    - ASoC: max98927: add missing header file
+    - arm64: dts: qcom: sc7280: Fix gmu unit address
+    - firmware: qcom: scm: Remove reassignment to desc following initializer
+    - ARM: dts: qcom: ipq4019: fix sleep clock
+    - soc: qcom: rpmpd: Check for null return of devm_kcalloc
+    - soc: qcom: ocmem: Fix missing put_device() call in of_get_ocmem
+    - soc: qcom: aoss: Fix missing put_device call in qmp_get
+    - soc: qcom: aoss: remove spurious IRQF_ONESHOT flags
+    - arm64: dts: qcom: sdm845: fix microphone bias properties and values
+    - arm64: dts: qcom: sm8250: fix PCIe bindings to follow schema
+    - arm64: dts: qcom: msm8916-j5: Fix typo
+    - arm64: dts: broadcom: bcm4908: use proper TWD binding
+    - arm64: dts: qcom: sm8150: Correct TCS configuration for apps rsc
+    - arm64: dts: qcom: sm8350: Correct TCS configuration for apps rsc
+    - arm64: dts: qcom: sm8450: Update cpuidle states parameters
+    - arm64: dts: qcom: msm8994: Provide missing "xo_board" and "sleep_clk" to GCC
+    - arm64: dts: qcom: ipq6018: fix usb reference period
+    - firmware: ti_sci: Fix compilation failure when CONFIG_TI_SCI_PROTOCOL is not
+      defined
+    - soc: ti: wkup_m3_ipc: Fix IRQ check in wkup_m3_ipc_probe
+    - cpuidle: qcom-spm: Check if any CPU is managed by SPM
+    - ARM: dts: sun8i: v3s: Move the csi1 block to follow address order
+    - ARM: dts: stm32: fix AV96 board SAI2 pin muxing on stm32mp15
+    - vsprintf: Fix potential unaligned access
+    - ARM: dts: qcom: sdx55: Fix the address used for PCIe EP local addr space
+    - ARM: dts: imx: Add missing LVDS decoder on M53Menlo
+    - media: mexon-ge2d: fixup frames size in registers
+    - media: video/hdmi: handle short reads of hdmi info frame.
+    - media: ti-vpe: cal: Fix a NULL pointer dereference in
+      cal_ctx_v4l2_init_formats()
+    - media: em28xx: initialize refcount before kref_get
+    - media: uapi: Init VP9 stateless decode params
+    - media: usb: go7007: s2250-board: fix leak in probe()
+    - media: cedrus: H265: Fix neighbour info buffer size
+    - media: cedrus: h264: Fix neighbour info buffer size
+    - arm64: dts: ti: k3-j721s2-mcu-wakeup: Fix the interrupt-parent for
+      wkup_gpioX instances
+    - ASoC: codecs: rx-macro: fix accessing compander for aux
+    - ASoC: codecs: rx-macro: fix accessing array out of bounds for enum type
+    - ASoC: codecs: va-macro: fix accessing array out of bounds for enum type
+    - ASoC: codecs: wc938x: fix accessing array out of bounds for enum type
+    - ASoC: codecs: wcd938x: fix kcontrol max values
+    - ASoC: codecs: wcd934x: fix kcontrol max values
+    - ASoC: codecs: wcd934x: fix return value of wcd934x_rx_hph_mode_put
+    - media: v4l2-core: Initialize h264 scaling matrix
+    - media: hantro: sunxi: Fix VP9 steps
+    - media: ov5640: Fix set format, v4l2_mbus_pixelcode not updated
+    - selftests: vm: remove dependecy from internal kernel macros
+    - selftests/lkdtm: Add UBSAN config
+    - vsprintf: Fix %pK with kptr_restrict == 0
+    - uaccess: fix nios2 and microblaze get_user_8()
+    - ASoC: rt5663: check the return value of devm_kzalloc() in rt5663_parse_dp()
+    - ASoC: acp: check the return value of devm_kzalloc() in
+      acp_legacy_dai_links_create()
+    - soc: mediatek: pm-domains: Add wakeup capacity support in power domain
+    - mmc: sdhci_am654: Fix the driver data of AM64 SoC
+    - ASoC: ti: davinci-i2s: Add check for clk_enable()
+    - ALSA: spi: Add check for clk_enable()
+    - arm64: dts: ns2: Fix spi-cpol and spi-cpha property
+    - arm64: dts: broadcom: Fix sata nodename
+    - printk: fix return value of printk.devkmsg __setup handler
+    - ASoC: mxs-saif: Handle errors for clk_enable
+    - ASoC: atmel_ssc_dai: Handle errors for clk_enable
+    - ASoC: dwc-i2s: Handle errors for clk_enable
+    - ASoC: soc-compress: prevent the potentially use of null pointer
+    - media: i2c: Fix pixel array positions in ov8865
+    - memory: emif: Add check for setup_interrupts
+    - memory: emif: check the pointer temp in get_device_details()
+    - ALSA: firewire-lib: fix uninitialized flag for AV/C deferred transaction
+    - arm64: dts: rockchip: Fix SDIO regulator supply properties on rk3399-firefly
+    - m68k: coldfire/device.c: only build for MCF_EDMA when h/w macros are defined
+    - media: stk1160: If start stream fails, return buffers with
+      VB2_BUF_STATE_QUEUED
+    - media: vidtv: Check for null return of vzalloc
+    - ASoC: cs35l41: Fix GPIO2 configuration
+    - ASoC: cs35l41: Fix max number of TX channels
+    - ASoC: atmel: Add missing of_node_put() in at91sam9g20ek_audio_probe
+    - ASoC: wm8350: Handle error for wm8350_register_irq
+    - ASoC: fsi: Add check for clk_enable
+    - video: fbdev: omapfb: Add missing of_node_put() in dvic_probe_of
+    - media: saa7134: fix incorrect use to determine if list is empty
+    - ivtv: fix incorrect device_caps for ivtvfb
+    - ASoC: atmel: Fix error handling in snd_proto_probe
+    - ASoC: rockchip: i2s: Fix missing clk_disable_unprepare() in
+      rockchip_i2s_probe
+    - ASoC: SOF: Add missing of_node_put() in imx8m_probe
+    - ASoC: mediatek: mt8192-mt6359: Fix error handling in mt8192_mt6359_dev_probe
+    - ASoC: rk817: Fix missing clk_disable_unprepare() in rk817_platform_probe
+    - ASoC: dmaengine: do not use a NULL prepare_slave_config() callback
+    - ASoC: mxs: Fix error handling in mxs_sgtl5000_probe
+    - ASoC: fsl_spdif: Disable TX clock when stop
+    - ASoC: imx-es8328: Fix error return code in imx_es8328_probe()
+    - ASoC: SOF: Intel: enable DMI L1 for playback streams
+    - ASoC: msm8916-wcd-digital: Fix missing clk_disable_unprepare() in
+      msm8916_wcd_digital_probe
+    - mmc: davinci_mmc: Handle error for clk_enable
+    - rtla/osnoise: Fix osnoise hist stop tracing message
+    - ASoC: rockchip: Fix PM usage reference of rockchip_i2s_tdm_resume
+    - ASoC: atmel: Fix error handling in sam9x5_wm8731_driver_probe
+    - ASoC: msm8916-wcd-analog: Fix error handling in pm8916_wcd_analog_spmi_probe
+    - ASoC: mediatek: mt8195: Fix error handling in
+      mt8195_mt6359_rt1019_rt5682_dev_probe
+    - ASoC: codecs: wcd934x: Add missing of_node_put() in wcd934x_codec_parse_data
+    - ASoC: amd: Fix reference to PCM buffer address
+    - ARM: configs: multi_v5_defconfig: re-enable CONFIG_V4L_PLATFORM_DRIVERS
+    - ARM: configs: multi_v5_defconfig: re-enable DRM_PANEL and FB_xxx
+    - drm/bridge: sn65dsi83: Fix an error handling path in sn65dsi83_probe()
+    - drm/meson: osd_afbcd: Add an exit callback to struct meson_afbcd_ops
+    - drm/meson: Fix error handling when afbcd.ops->init fails
+    - drm/bridge: Fix free wrong object in sii8620_init_rcp_input_dev
+    - drm/bridge: Add missing pm_runtime_disable() in __dw_mipi_dsi_probe
+    - drm/bridge: nwl-dsi: Fix PM disable depth imbalance in nwl_dsi_probe
+    - drm: bridge: adv7511: Fix ADV7535 HPD enablement
+    - ath11k: add missing of_node_put() to avoid leak
+    - ath10k: fix memory overwrite of the WoWLAN wakeup packet pattern
+    - drm/v3d/v3d_drv: Check for error num after setting mask
+    - Bluetooth: hci_sync: unlock on error in hci_inquiry_result_with_rssi_evt()
+    - ath11k: free peer for station when disconnect from AP for QCA6390/WCN6855
+    - drm/panfrost: Check for error num after setting mask
+    - bpftool: Fix error check when calling hashmap__new()
+    - libbpf: Fix possible NULL pointer dereference when destroying skeleton
+    - bpftool: Only set obj->skeleton on complete success
+    - ath11k: fix error code in ath11k_qmi_assign_target_mem_chunk()
+    - udmabuf: validate ubuf->pagecount
+    - bpf: Fix UAF due to race between btf_try_get_module and load_module
+    - drm/selftests/test-drm_dp_mst_helper: Fix memory leak in
+      sideband_msg_req_encode_decode
+    - drm/locking: fix drm_modeset_acquire_ctx kernel-doc
+    - selftests: bpf: Fix bind on used port
+    - Bluetooth: btintel: Fix WBS setting for Intel legacy ROM products
+    - Bluetooth: hci_serdev: call init_rwsem() before p->open()
+    - Bluetooth: mt7921s: fix firmware coredump retrieve
+    - Bluetooth: mt7921s: fix bus hang with wrong privilege
+    - Bluetooth: btmtksdio: refactor btmtksdio_runtime_[suspend|resume]()
+    - Bluetooth: mt7921s: fix btmtksdio_[drv|fw]_pmctrl()
+    - Bluetooth: btmtksdio: mask out interrupt status
+    - mtd: onenand: Check for error irq
+    - mtd: rawnand: gpmi: fix controller timings setting
+    - selftests, xsk: Fix rx_full stats test
+    - drm/edid: Don't clear formats if using deep color
+    - drm/edid: Split deep color modes between RGB and YUV444
+    - ionic: fix type complaint in ionic_dev_cmd_clean()
+    - ionic: start watchdog after all is setup
+    - ionic: Don't send reset commands if FW isn't running
+    - ionic: fix up printing of timeout error
+    - ionic: Correctly print AQ errors if completions aren't received
+    - net: dsa: Move VLAN filtering syncing out of dsa_switch_bridge_leave
+    - net: dsa: Avoid cross-chip syncing of VLAN filtering
+    - Bluetooth: hci_event: Fix HCI_EV_VENDOR max_len
+    - drm/nouveau/acr: Fix undefined behavior in nvkm_acr_hsfw_load_bl()
+    - drm/amd/display: Call dc_stream_release for remove link enc assignment
+    - drm/amd/display: Fix a NULL pointer dereference in
+      amdgpu_dm_connector_add_common_modes()
+    - drm/amd/pm: return -ENOTSUPP if there is no get_dpm_ultimate_freq function
+    - net: phy: at803x: move page selection fix to config_init
+    - selftests/bpf/test_xdp_redirect_multi: use temp netns for testing
+    - ath9k_htc: fix uninit value bugs
+    - ath11k: set WMI_PEER_40MHZ while peer assoc for 6 GHz
+    - RDMA/core: Set MR type in ib_reg_user_mr
+    - KVM: PPC: Fix vmx/vsx mixup in mmio emulation
+    - selftests/net: timestamping: Fix bind_phc check
+    - rtw88: check for validity before using a pointer
+    - rtw88: fix idle mode flow for hw scan
+    - rtw88: fix memory overrun and memory leak during hw_scan
+    - drm/bridge: lt9611: Fix an error handling path in lt9611_probe()
+    - i40e: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
+    - i40e: respect metadata on XSK Rx to skb
+    - ice: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
+    - ice: respect metadata on XSK Rx to skb
+    - igc: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
+    - ixgbe: pass bi->xdp to ixgbe_construct_skb_zc() directly
+    - ixgbe: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
+    - ixgbe: respect metadata on XSK Rx to skb
+    - power: reset: gemini-poweroff: Fix IRQ check in gemini_poweroff_probe
+    - ray_cs: Check ioremap return value
+    - powerpc: dts: t1040rdb: fix ports names for Seville Ethernet switch
+    - KVM: PPC: Book3S HV: Check return value of kvmppc_radix_init
+    - powerpc/perf: Don't use perf_hw_context for trace IMC PMU
+    - mt76: connac: fix sta_rec_wtbl tag len
+    - mt76: mt7915: use proper aid value in mt7915_mcu_wtbl_generic_tlv in sta
+      mode
+    - mt76: mt7915: use proper aid value in mt7915_mcu_sta_basic_tlv
+    - mt76: mt76_connac: fix MCU_CE_CMD_SET_ROC definition error
+    - mt76: mt7921: set EDCA parameters with the MCU CE command
+    - mt76: mt7921: do not always disable fw runtime-pm
+    - mt76: mt7921: fix a leftover race in runtime-pm
+    - mt76: mt7615: fix a leftover race in runtime-pm
+    - mt76: mt7915: fix ht mcs in mt7915_mac_add_txs_skb()
+    - mt76: mt7921: fix ht mcs in mt7921_mac_add_txs_skb()
+    - mt76: mt7921s: fix mt7921s_mcu_[fw|drv]_pmctrl
+    - mt76: mt7921e: fix possible probe failure after reboot
+    - mt76: mt7603: check sta_rates pointer in mt7603_sta_rate_tbl_update
+    - mt76: mt7615: check sta_rates pointer in mt7615_sta_rate_tbl_update
+    - mt76: mt7915: fix possible memory leak in mt7915_mcu_add_sta
+    - mt76: mt7921s: fix a possible memory leak in mt7921_load_patch
+    - mt76: mt7915: fix mcs_map in mt7915_mcu_set_sta_he_mcs()
+    - mt76: mt7915: fix the nss setting in bitrates
+    - ptp: unregister virtual clocks when unregistering physical clock.
+    - net: dsa: mv88e6xxx: Enable port policy support on 6097
+    - bpf: Fix a btf decl_tag bug when tagging a function
+    - mac80211: limit bandwidth in HE capabilities
+    - scripts/dtc: Call pkg-config POSIXly correct
+    - livepatch: Fix build failure on 32 bits processors
+    - net: asix: add proper error handling of usb read errors
+    - i2c: bcm2835: Fix the error handling in 'bcm2835_i2c_probe()'
+    - mtd: mchp23k256: Add SPI ID table
+    - mtd: mchp48l640: Add SPI ID table
+    - selftests/bpf: Extract syscall wrapper
+    - selftests/bpf: Use "__se_" prefix on architectures without syscall wrapper
+    - igc: avoid kernel warning when changing RX ring parameters
+    - igb: refactor XDP registration
+    - drm/amdgpu: Don't offset by 2 in FRU EEPROM
+    - PCI: aardvark: Fix reading MSI interrupt number
+    - PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on emulated bridge
+    - RDMA/rxe: Check the last packet by RXE_END_MASK
+    - libbpf: Fix signedness bug in btf_dump_array_data()
+    - libbpf: Fix riscv register names
+    - cxl/core: Fix cxl_probe_component_regs() error message
+    - tools/testing/cxl: Fix root port to host bridge assignment
+    - cxl/regs: Fix size of CXL Capability Header Register
+    - Netvsc: Call hv_unmap_memory() in the netvsc_device_remove()
+    - net:enetc: allocate CBD ring data memory using DMA coherent methods
+    - libbpf: Fix compilation warning due to mismatched printf format
+    - rtw88: fix use after free in rtw_hw_scan_update_probe_req()
+    - drm/bridge: dw-hdmi: use safe format when first in bridge chain
+    - power: supply: ab8500: Swap max and overvoltage
+    - libbpf: Fix libbpf.map inheritance chain for LIBBPF_0.7.0
+    - libbpf: Use dynamically allocated buffer when receiving netlink messages
+    - power: supply: ab8500: Fix memory leak in ab8500_fg_sysfs_init
+    - HID: i2c-hid: fix GET/SET_REPORT for unnumbered reports
+    - iommu/ipmmu-vmsa: Check for error num after setting mask
+    - drm/bridge: anx7625: Fix overflow issue on reading EDID
+    - ath11k: fix uninitialized rate_idx in ath11k_dp_tx_update_txcompl()
+    - i2c: pasemi: Drop I2C classes from platform driver variant
+    - bpftool: Fix the error when lookup in no-btf maps
+    - drm/amd/pm: enable pm sysfs write for one VF mode
+    - drm/amd/display: Add affected crtcs to atomic state for dsc mst unplug
+    - bpftool: Fix pretty print dump for maps without BTF loaded
+    - libbpf: Fix memleak in libbpf_netlink_recv()
+    - IB/cma: Allow XRC INI QPs to set their local ACK timeout
+    - cxl/core/port: Rename bus.c to port.c
+    - cxl/port: Hold port reference until decoder release
+    - dax: make sure inodes are flushed before destroy cache
+    - selftests: mptcp: add csum mib check for mptcp_connect
+    - iwlwifi: mvm: Don't call iwl_mvm_sta_from_mac80211() with NULL sta
+    - iwlwifi: mvm: don't iterate unadded vifs when handling FW SMPS req
+    - iwlwifi: mvm: align locking in D3 test debugfs
+    - iwlwifi: yoyo: remove DBGI_SRAM address reset writing
+    - iwlwifi: yoyo: Avoid using dram data if allocation failed
+    - iwlwifi: mvm: fix off by one in iwl_mvm_stat_iterator_all_macs()
+    - iwlwifi: Fix -EIO error code that is never returned
+    - iwlwifi: mvm: Fix an error code in iwl_mvm_up()
+    - mtd: rawnand: pl353: Set the nand chip node as the flash node
+    - drm/msm/dp: do not initialize phy until plugin interrupt received
+    - drm/msm/dp: populate connector of struct dp_panel
+    - drm/msm/dp: stop link training after link training 2 failed
+    - drm/msm/dp: always add fail-safe mode into connector mode list
+    - drm/msm/dsi: Use "ref" fw clock instead of global name for VCO parent
+    - drm/msm/dsi/phy: fix 7nm v4.0 settings for C-PHY mode
+    - drm/msm/dpu: add DSPP blocks teardown
+    - drm/msm/dpu: fix dp audio condition
+    - drm/msm/dpu: remove msm_dp cached in dpu_encoder_virt
+    - drm/msm/dp: fix panel bridge attachment
+    - i40e: remove dead stores on XSK hotpath
+    - ath11k: Invalidate cached reo ring entry before accessing it
+    - mips: Enable KCSAN
+    - dm crypt: fix get_key_size compiler warning if !CONFIG_KEYS
+    - vfio/pci: fix memory leak during D3hot to D0 transition
+    - vfio/pci: wake-up devices around reset functions
+    - scsi: fnic: Fix a tracing statement
+    - scsi: pm8001: Fix command initialization in pm80XX_send_read_log()
+    - scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req()
+    - scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config()
+    - scsi: pm8001: Fix le32 values handling in
+      pm80xx_set_sas_protocol_timer_config()
+    - scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update()
+    - scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req()
+    - scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req()
+    - scsi: pm8001: Fix NCQ NON DATA command task initialization
+    - scsi: pm8001: Fix NCQ NON DATA command completion handling
+    - scsi: pm8001: Fix abort all task initialization
+    - mt76: do not always copy ethhdr in reverse_frag0_hdr_trans
+    - mt76: fix endianness errors in reverse_frag0_hdr_trans
+    - mt76: mt7921s: fix missing fc type/sub-type for 802.11 pkts
+    - net: dsa: realtek-smi: fix kdoc warnings
+    - net: dsa: realtek-smi: move to subdirectory
+    - RDMA/mlx5: Fix the flow of a miss in the allocation of a cache ODP MR
+    - drm/amd/display: Remove vupdate_int_entry definition
+    - TOMOYO: fix __setup handlers return values
+    - power: supply: sbs-charger: Don't cancel work that is not initialized
+    - mt76: mt7915: enlarge wcid size to 544
+    - mt76: mt7915: fix the muru tlv issue
+    - drm/dp: Fix OOB read when handling Post Cursor2 register
+    - ext2: correct max file size computing
+    - drm/tegra: Fix reference leak in tegra_dsi_ganged_probe
+    - power: supply: bq24190_charger: Fix bq24190_vbus_is_enabled() wrong false
+      return
+    - scsi: hisi_sas: Change permission of parameter prot_mask
+    - drm/bridge: cdns-dsi: Make sure to to create proper aliases for dt
+    - bpf, arm64: Call build_prologue() first in first JIT pass
+    - bpf, arm64: Feed byte-offset into bpf line info
+    - xsk: Fix race at socket teardown
+    - RDMA/irdma: Fix netdev notifications for vlan's
+    - RDMA/irdma: Fix Passthrough mode in VM
+    - RDMA/irdma: Remove incorrect masking of PD
+    - libbpf: Fix BPF_MAP_TYPE_PERF_EVENT_ARRAY auto-pinning
+    - gpu: host1x: Fix an error handling path in 'host1x_probe()'
+    - gpu: host1x: Fix a memory leak in 'host1x_remove()'
+    - libbpf: Skip forward declaration when counting duplicated type names
+    - powerpc/mm/numa: skip NUMA_NO_NODE onlining in parse_numa_properties()
+    - powerpc/Makefile: Don't pass -mcpu=powerpc64 when building 32-bit
+    - KVM: x86: Fix emulation in writing cr8
+    - KVM: x86/emulator: Defer not-present segment check in
+      __load_segment_descriptor()
+    - KVM: SVM: Exit to userspace on ENOMEM/EFAULT GHCB errors
+    - hv_balloon: rate-limit "Unhandled message" warning
+    - KVM: arm64: Enable Cortex-A510 erratum 2077057 by default
+    - i2c: xiic: Make bus names unique
+    - net: phy: micrel: Fix concurrent register access
+    - Bluetooth: hci_sync: fix undefined return of hci_disconnect_all_sync()
+    - Bluetooth: Fix skb allocation in mgmt_remote_name() &
+      mgmt_device_connected()
+    - power: supply: wm8350-power: Handle error for wm8350_register_irq
+    - power: supply: wm8350-power: Add missing free in free_charger_irq
+    - IB/hfi1: Allow larger MTU without AIP
+    - RDMA/core: Fix ib_qp_usecnt_dec() called when error
+    - PCI: Reduce warnings on possible RW1C corruption
+    - net: axienet: fix RX ring refill allocation failure handling
+    - drm/msm/a6xx: Fix missing ARRAY_SIZE() check
+    - mips: DEC: honor CONFIG_MIPS_FP_SUPPORT=n
+    - MIPS: Sanitise Cavium switch cases in TLB handler synthesizers
+    - powerpc/sysdev: fix incorrect use to determine if list is empty
+    - powerpc/64s: Don't use DSISR for SLB faults
+    - mfd: mc13xxx: Add check for mc13xxx_irq_request
+    - libbpf: Unmap rings when umem deleted
+    - selftests/bpf: Make test_lwt_ip_encap more stable and faster
+    - platform/x86: huawei-wmi: check the return value of device_create_file()
+    - scsi: mpt3sas: Fix incorrect 4GB boundary check
+    - powerpc: 8xx: fix a return value error in mpc8xx_pic_init
+    - xtensa: add missing XCHAL_HAVE_WINDOWED check
+    - iwlwifi: pcie: fix SW error MSI-X mapping
+    - vxcan: enable local echo for sent CAN frames
+    - ath10k: Fix error handling in ath10k_setup_msa_resources
+    - mips: cdmm: Fix refcount leak in mips_cdmm_phys_base
+    - MIPS: RB532: fix return value of __setup handler
+    - MIPS: pgalloc: fix memory leak caused by pgd_free()
+    - mtd: rawnand: atmel: fix refcount issue in atmel_nand_controller_init
+    - power: ab8500_chargalg: Use CLOCK_MONOTONIC
+    - RDMA/irdma: Prevent some integer underflows
+    - Revert "RDMA/core: Fix ib_qp_usecnt_dec() called when error"
+    - RDMA/mlx5: Fix memory leak in error flow for subscribe event routine
+    - bpf, sockmap: Fix memleak in sk_psock_queue_msg
+    - bpf, sockmap: Fix memleak in tcp_bpf_sendmsg while sk msg is full
+    - bpf, sockmap: Fix more uncharged while msg has more_data
+    - bpf, sockmap: Fix double uncharge the mem of sk_msg
+    - samples/bpf, xdpsock: Fix race when running for fix duration of time
+    - USB: storage: ums-realtek: fix error code in rts51x_read_mem()
+    - drm/amd/display: Fix double free during GPU reset on DC streams
+    - RDMA/rxe: Change variable and function argument to proper type
+    - RDMA/rxe: Fix ref error in rxe_av.c
+    - powerpc/xive: fix return value of __setup handler
+    - powerpc/time: Fix KVM host re-arming a timer beyond decrementer range
+    - drm/i915/display: Fix HPD short pulse handling for eDP
+    - drm/i915/display: Do not re-enable PSR after it was marked as not reliable
+    - netfilter: flowtable: Fix QinQ and pppoe support for inet table
+    - mt76: mt7921: fix mt7921_queues_acq implementation
+    - can: isotp: return -EADDRNOTAVAIL when reading from unbound socket
+    - can: isotp: support MSG_TRUNC flag when reading from socket
+    - bareudp: use ipv6_mod_enabled to check if IPv6 enabled
+    - PCI: imx6: Invoke the PHY exit function after PHY power off
+    - PCI: imx6: Assert i.MX8MM CLKREQ# even if no device present
+    - ibmvnic: fix race between xmit and reset
+    - af_unix: Fix some data-races around unix_sk(sk)->oob_skb.
+    - selftests/bpf: Fix error reporting from sock_fields programs
+    - Bluetooth: hci_uart: add missing NULL check in h5_enqueue
+    - Bluetooth: call hci_le_conn_failed with hdev lock in hci_le_conn_failed
+    - Bluetooth: btmtksdio: Fix kernel oops in btmtksdio_interrupt
+    - RDMA/nldev: Prevent underflow in nldev_stat_set_counter_dynamic_doit()
+    - ipv4: Fix route lookups when handling ICMP redirects and PMTU updates
+    - mptcp: Fix crash due to tcp_tsorted_anchor was initialized before release
+      skb
+    - af_netlink: Fix shift out of bounds in group mask calculation
+    - i2c: meson: Fix wrong speed use from probe
+    - netfilter: conntrack: Add and use nf_ct_set_auto_assign_helper_warned()
+    - i2c: mux: demux-pinctrl: do not deactivate a master that is not active
+    - powerpc/pseries: Fix use after free in remove_phb_dynamic()
+    - ax25: Fix refcount leaks caused by ax25_cb_del()
+    - ax25: Fix NULL pointer dereferences in ax25 timers
+    - drm/i915: Fix renamed struct field
+    - selftests/bpf/test_lirc_mode2.sh: Exit with proper code
+    - bpftool: Fix print error when show bpf map
+    - PCI: Avoid broken MSI on SB600 USB devices
+    - net: bcmgenet: Use stronger register read/writes to assure ordering
+    - tcp: ensure PMTU updates are processed during fastopen
+    - openvswitch: always update flow key after nat
+    - net: dsa: fix panic on shutdown if multi-chip tree failed to probe
+    - net: wwan: qcom_bam_dmux: fix wrong pointer passed to IS_ERR()
+    - tipc: fix the timer expires after interval 100ms
+    - mfd: asic3: Add missing iounmap() on error asic3_mfd_probe
+    - ice: fix 'scheduling while atomic' on aux critical err interrupt
+    - ice: don't allow to run ice_send_event_to_aux() in atomic ctx
+    - drivers: ethernet: cpsw: fix panic when interrupt coaleceing is set via
+      ethtool
+    - kernel/resource: fix kfree() of bootmem memory again
+    - clk: renesas: r9a07g044: Update multiplier and divider values for PLL2/3
+    - staging: r8188eu: release_firmware is not called if allocation fails
+    - mxser: fix xmit_buf leak in activate when LSR == 0xff
+    - fsi: scom: Fix error handling
+    - fsi: scom: Remove retries in indirect scoms
+    - pwm: lpc18xx-sct: Initialize driver data and hardware before pwmchip_add()
+    - pps: clients: gpio: Propagate return value from pps_gpio_probe
+    - fsi: Aspeed: Fix a potential double free
+    - misc: alcor_pci: Fix an error handling path
+    - cpufreq: qcom-cpufreq-nvmem: fix reading of PVS Valid fuse
+    - soundwire: intel: fix wrong register name in intel_shim_wake
+    - clk: qcom: ipq8074: fix PCI-E clock oops
+    - dmaengine: idxd: restore traffic class defaults after wq reset
+    - iio: mma8452: Fix probe failing when an i2c_device_id is used
+    - staging: qlge: add unregister_netdev in qlge_probe
+    - serial: 8250_aspeed_vuart: add PORT_ASPEED_VUART port type
+    - staging:iio:adc:ad7280a: Fix handing of device address bit reversing.
+    - clk: renesas: r8a779f0: Fix RSW2 clock divider
+    - pinctrl: renesas: r8a77470: Reduce size for narrow VIN1 channel
+    - pinctrl: renesas: checker: Fix miscalculation of number of states
+    - clk: qcom: ipq8074: Use floor ops for SDCC1 clock
+    - phy: dphy: Correct lpx parameter and its derivatives(ta_{get,go,sure})
+    - phy: phy-brcm-usb: fixup BCM4908 support
+    - serial: 8250_mid: Balance reference count for PCI DMA device
+    - serial: 8250_lpss: Balance reference count for PCI DMA device
+    - NFS: Use of mapping_set_error() results in spurious errors
+    - serial: 8250: Fix race condition in RTS-after-send handling
+    - iio: adc: Add check for devm_request_threaded_irq
+    - habanalabs: Add check for pci_enable_device
+    - NFS: Return valid errors from nfs2/3_decode_dirent()
+    - staging: r8188eu: fix endless loop in recv_func
+    - dma-debug: fix return value of __setup handlers
+    - clk: imx7d: Remove audio_mclk_root_clk
+    - clk: imx: off by one in imx_lpcg_parse_clks_from_dt()
+    - clk: at91: sama7g5: fix parents of PDMCs' GCLK
+    - clk: qcom: clk-rcg2: Update logic to calculate D value for RCG
+    - clk: qcom: clk-rcg2: Update the frac table for pixel clock
+    - clk: starfive: jh7100: Don't round divisor up twice
+    - clk: starfive: jh7100: Handle audio_div clock properly
+    - dmaengine: hisi_dma: fix MSI allocate fail when reload hisi_dma
+    - remoteproc: qcom: Fix missing of_node_put in adsp_alloc_memory_region
+    - remoteproc: qcom_wcnss: Add missing of_node_put() in
+      wcnss_alloc_memory_region
+    - remoteproc: qcom_q6v5_mss: Fix some leaks in q6v5_alloc_memory_region
+    - nvdimm/region: Fix default alignment for small regions
+    - clk: actions: Terminate clk_div_table with sentinel element
+    - clk: loongson1: Terminate clk_div_table with sentinel element
+    - clk: hisilicon: Terminate clk_div_table with sentinel element
+    - clk: clps711x: Terminate clk_div_table with sentinel element
+    - clk: Fix clk_hw_get_clk() when dev is NULL
+    - clk: tegra: tegra124-emc: Fix missing put_device() call in
+      emc_ensure_emc_driver
+    - mailbox: imx: fix crash in resume on i.mx8ulp
+    - NFS: remove unneeded check in decode_devicenotify_args()
+    - staging: mt7621-dts: fix LEDs and pinctrl on GB-PC1 devicetree
+    - staging: mt7621-dts: fix formatting
+    - staging: mt7621-dts: fix pinctrl properties for ethernet
+    - staging: mt7621-dts: fix GB-PC2 devicetree
+    - pinctrl: ocelot: fix confops resource index
+    - pinctrl: ocelot: fix duplicate debugfs entry
+    - pinctrl: mediatek: Fix missing of_node_put() in mtk_pctrl_init
+    - pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_* readback
+    - pinctrl: mediatek: paris: Fix "argument" argument type for mtk_pinconf_get()
+    - pinctrl: mediatek: paris: Fix pingroup pin config state readback
+    - pinctrl: mediatek: paris: Skip custom extra pin config dump for virtual
+      GPIOs
+    - pinctrl: ocelot: Fix interrupt parsing
+    - pinctrl: microchip-sgpio: lock RMW access
+    - pinctrl: nomadik: Add missing of_node_put() in nmk_pinctrl_probe
+    - pinctrl/rockchip: Add missing of_node_put() in rockchip_pinctrl_probe
+    - clk: visconti: prevent array overflow in visconti_clk_register_gates()
+    - tty: hvc: fix return value of __setup handler
+    - kgdboc: fix return value of __setup handler
+    - serial: 8250: fix XOFF/XON sending when DMA is used
+    - virt: acrn: obtain pa from VMA with PFNMAP flag
+    - virt: acrn: fix a memory leak in acrn_dev_ioctl()
+    - kgdbts: fix return value of __setup handler
+    - firmware: google: Properly state IOMEM dependency
+    - driver core: dd: fix return value of __setup handler
+    - perf test arm64: Test unwinding using fame-pointer (fp) mode
+    - jfs: fix divide error in dbNextAG
+    - SUNRPC/call_alloc: async tasks mustn't block waiting for memory
+    - SUNRPC: improve 'swap' handling: scheduling and PF_MEMALLOC
+    - SUNRPC: Don't call connect() more than once on a TCP socket
+    - perf parse-events: Move slots only with topdown
+    - netfilter: egress: Report interface as outgoing
+    - netfilter: nf_conntrack_tcp: preserve liberal flag in tcp options
+    - SUNRPC don't resend a task on an offlined transport
+    - NFSv4.1: don't retry BIND_CONN_TO_SESSION on session error
+    - kdb: Fix the putarea helper function
+    - perf stat: Fix forked applications enablement of counters
+    - net: stmmac: dwmac-qcom-ethqos: Enable RGMII functional clock on resume
+    - clk: qcom: gcc-msm8994: Fix gpll4 width
+    - vsock/virtio: initialize vdev->priv before using VQs
+    - vsock/virtio: read the negotiated features before using VQs
+    - vsock/virtio: enable VQs early on probe
+    - clk: Initialize orphan req_rate
+    - xen: fix is_xen_pmu()
+    - net: enetc: report software timestamping via SO_TIMESTAMPING
+    - net: hns3: fix bug when PF set the duplicate MAC address for VFs
+    - net: hns3: fix port base vlan add fail when concurrent with reset
+    - net: hns3: add vlan list lock to protect vlan list
+    - net: hns3: refine the process when PF set VF VLAN
+    - net: phy: broadcom: Fix brcm_fet_config_init()
+    - selftests: test_vxlan_under_vrf: Fix broken test case
+    - NFS: Don't loop forever in nfs_do_recoalesce()
+    - libperf tests: Fix typo in perf_evlist__open() failure error messages
+    - net: hns3: fix ethtool tx copybreak buf size indicating not aligned issue
+    - net: hns3: add max order judgement for tx spare buffer
+    - net: hns3: clean residual vf config after disable sriov
+    - net: hns3: add netdev reset check for hns3_set_tunable()
+    - net: hns3: add NULL pointer check for hns3_set/get_ringparam()
+    - net: hns3: fix phy can not link up when autoneg off and reset
+    - net: sparx5: depends on PTP_1588_CLOCK_OPTIONAL
+    - qlcnic: dcb: default to returning -EOPNOTSUPP
+    - net/x25: Fix null-ptr-deref caused by x25_disconnect
+    - net: sparx5: switchdev: fix possible NULL pointer dereference
+    - octeontx2-af: initialize action variable
+    - selftests: tls: skip cmsg_to_pipe tests with TLS=n
+    - net/sched: act_ct: fix ref leak when switching zones
+    - NFSv4/pNFS: Fix another issue with a list iterator pointing to the head
+    - net: dsa: bcm_sf2_cfp: fix an incorrect NULL check on list iterator
+    - fs: fd tables have to be multiples of BITS_PER_LONG
+    - lib/test: use after free in register_test_dev_kmod()
+    - fs: fix fd table size alignment properly
+    - LSM: general protection fault in legacy_parse_param
+    - regulator: rpi-panel: Handle I2C errors/timing to the Atmel
+    - crypto: hisilicon/qm - cleanup warning in qm_vf_read_qos
+    - crypto: octeontx2 - CN10K CPT to RNM workaround
+    - gcc-plugins/stackleak: Exactly match strings instead of prefixes
+    - rcu: Kill rnp->ofl_seq and use only rcu_state.ofl_lock for exclusion
+    - pinctrl: npcm: Fix broken references to chip->parent_device
+    - rcu: Mark writes to the rcu_segcblist structure's ->flags field
+    - block: throttle split bio in case of iops limit
+    - memstick/mspro_block: fix handling of read-only devices
+    - block/bfq_wf2q: correct weight to ioprio
+    - crypto: xts - Add softdep on ecb
+    - crypto: hisilicon/sec - not need to enable sm4 extra mode at HW V3
+    - block, bfq: don't move oom_bfqq
+    - selinux: use correct type for context length
+    - powercap/dtpm_cpu: Reset per_cpu variable in the release function
+    - arm64: module: remove (NOLOAD) from linker script
+    - selinux: allow FIOCLEX and FIONCLEX with policy capability
+    - loop: use sysfs_emit() in the sysfs xxx show()
+    - Fix incorrect type in assignment of ipv6 port for audit
+    - irqchip/qcom-pdc: Fix broken locking
+    - irqchip/nvic: Release nvic_base upon failure
+    - fs/binfmt_elf: Fix AT_PHDR for unusual ELF files
+    - hwrng: cavium - fix NULL but dereferenced coccicheck error
+    - bfq: fix use-after-free in bfq_dispatch_request
+    - ACPICA: Avoid walking the ACPI Namespace if it is not there
+    - ACPI / x86: Add skip i2c clients quirk for Nextbook Ares 8
+    - ACPI / x86: Add skip i2c clients quirk for Lenovo Yoga Tablet 1050F/L
+    - lib/raid6/test/Makefile: Use $(pound) instead of \# for Make 4.3
+    - Revert "Revert "block, bfq: honor already-setup queue merges""
+    - ACPI/APEI: Limit printable size of BERT table data
+    - PM: core: keep irq flags in device_pm_check_callbacks()
+    - parisc: Fix non-access data TLB cache flush faults
+    - parisc: Fix handling off probe non-access faults
+    - nvme-tcp: lockdep: annotate in-kernel sockets
+    - spi: tegra20: Use of_device_get_match_data()
+    - spi: fsi: Implement a timeout for polling status
+    - atomics: Fix atomic64_{read_acquire,set_release} fallbacks
+    - locking/lockdep: Iterate lock_classes directly when reading lockdep files
+    - ext4: correct cluster len and clusters changed accounting in ext4_mb_mark_bb
+    - ext4: fix ext4_mb_mark_bb() with flex_bg with fast_commit
+    - sched/tracing: Report TASK_RTLOCK_WAIT tasks as TASK_UNINTERRUPTIBLE
+    - ext4: don't BUG if someone dirty pages without asking ext4 first
+    - f2fs: fix to do sanity check on curseg->alloc_type
+    - NFSD: Fix nfsd_breaker_owns_lease() return values
+    - f2fs: don't get FREEZE lock in f2fs_evict_inode in frozen fs
+    - btrfs: harden identification of a stale device
+    - btrfs: make search_csum_tree return 0 if we get -EFBIG
+    - btrfs: handle csum lookup errors properly on reads
+    - btrfs: do not double complete bio on errors during compressed reads
+    - btrfs: do not clean up repair bio if submit fails
+    - f2fs: use spin_lock to avoid hang
+    - f2fs: compress: fix to print raw data size in error path of lz4
+      decompression
+    - Adjust cifssb maximum read size
+    - ntfs: add sanity check on allocation size
+    - media: staging: media: zoran: move videodev alloc
+    - media: staging: media: zoran: calculate the right buffer number for
+      zoran_reap_stat_com
+    - media: staging: media: zoran: fix various V4L2 compliance errors
+    - media: atmel: atmel-isc-base: report frame sizes as full supported range
+    - media: ir_toy: free before error exiting
+    - ASoC: sh: rz-ssi: Make the data structures available before registering the
+      handlers
+    - ASoC: cs42l42: Report full jack status when plug is detected
+    - ASoC: SOF: Intel: match sdw version on link_slaves_found
+    - media: imx-jpeg: Prevent decoding NV12M jpegs into single-planar buffers
+    - ASoC: SOF: Intel: hda: Remove link assignment limitation
+    - media: iommu/mediatek-v1: Free the existed fwspec if the master dev already
+      has
+    - media: iommu/mediatek: Return ENODEV if the device is NULL
+    - media: iommu/mediatek: Add device_link between the consumer and the larb
+      devices
+    - video: fbdev: nvidiafb: Use strscpy() to prevent buffer overflow
+    - video: fbdev: w100fb: Reset global state
+    - video: fbdev: cirrusfb: check pixclock to avoid divide by zero
+    - video: fbdev: omapfb: acx565akm: replace snprintf with sysfs_emit
+    - ARM: dts: qcom: fix gic_irq_domain_translate warnings for msm8960
+    - ARM: dts: bcm2837: Add the missing L1/L2 cache information
+    - ASoC: madera: Add dependencies on MFD
+    - media: atomisp_gmin_platform: Add DMI quirk to not turn AXP ELDO2 regulator
+      off on some boards
+    - media: atomisp: fix dummy_ptr check to avoid duplicate active_bo
+    - ARM: ftrace: avoid redundant loads or clobbering IP
+    - ALSA: hda: Fix driver index handling at re-binding
+    - ARM: dts: imx7: Use audio_mclk_post_div instead audio_mclk_root_clk
+    - arm64: defconfig: build imx-sdma as a module
+    - video: fbdev: omapfb: panel-dsi-cm: Use sysfs_emit() instead of snprintf()
+    - video: fbdev: omapfb: panel-tpo-td043mtea1: Use sysfs_emit() instead of
+      snprintf()
+    - video: fbdev: udlfb: replace snprintf in show functions with sysfs_emit
+    - ARM: dts: bcm2711: Add the missing L1/L2 cache information
+    - ASoC: soc-core: skip zero num_dai component in searching dai name
+    - ASoC: Intel: sof_es8336: add quirk for Huawei D15 2021
+    - media: imx-jpeg: fix a bug of accessing array out of bounds
+    - media: cx88-mpeg: clear interrupt status register before streaming video
+    - ASoC: rt5682s: Fix the wrong jack type detected
+    - ARM: tegra: transformer: Drop reg-shift for Tegra HS UART
+    - uaccess: fix type mismatch warnings from access_ok()
+    - lib/test_lockup: fix kernel pointer check for separate address spaces
+    - ARM: tegra: tamonten: Fix I2C3 pad setting
+    - ARM: mmp: Fix failure to remove sram device
+    - ASoC: amd: vg: fix for pm resume callback sequence
+    - ASoC: amd: vangogh: fix uninitialized symbol warning in machine driver
+    - video: fbdev: sm712fb: Fix crash in smtcfb_write()
+    - media: i2c: ov5648: Fix lockdep error
+    - media: Revert "media: em28xx: add missing em28xx_close_extension"
+    - media: hdpvr: initialize dev->worker at hdpvr_register_videodev
+    - ASoC: SOF: debug: clarify operator precedence
+    - ASoC: Intel: sof_sdw: fix quirks for 2022 HP Spectre x360 13"
+    - ASoC: SOF: Intel: hda: retrieve DMIC number for I2S boards
+    - ALSA: intel-nhlt: add helper to detect SSP link mask
+    - ALSA: intel-dsp-config: add more ACPI HIDs for ES83x6 devices
+    - ASoC: Intel: soc-acpi: add more ACPI HIDs for ES83x6 devices
+    - ALSA: intel-dspconfig: add ES8336 support for CNL
+    - ASoC: Intel: Revert "ASoC: Intel: sof_es8336: add quirk for Huawei D15 2021"
+    - ASoC: Intel: sof_es8336: log all quirks
+    - tracing: Have TRACE_DEFINE_ENUM affect trace event types as well
+    - mmc: host: Return an error when ->enable_sdio_irq() ops is missing
+    - ASoC: mediatek: Fix error handling in mt8183_da7219_max98357_dev_probe
+    - media: atomisp: fix bad usage at error handling logic
+    - ALSA: hda/realtek: Add alc256-samsung-headphone fixup
+    - KVM: SVM: Allow AVIC support on system w/ physical APIC ID > 255
+    - KVM: x86: Reinitialize context if host userspace toggles EFER.LME
+    - KVM: x86/mmu: Use common TDP MMU zap helper for MMU notifier unmap hook
+    - KVM: x86/mmu: Move "invalid" check out of kvm_tdp_mmu_get_root()
+    - KVM: x86/mmu: Zap _all_ roots when unmapping gfn range in TDP MMU
+    - KVM: x86/mmu: Check for present SPTE when clearing dirty bit in TDP MMU
+    - KVM: x86: hyper-v: Drop redundant 'ex' parameter from kvm_hv_send_ipi()
+    - KVM: x86: hyper-v: Drop redundant 'ex' parameter from kvm_hv_flush_tlb()
+    - KVM: x86: hyper-v: Fix the maximum number of sparse banks for XMM fast TLB
+      flush hypercalls
+    - KVM: x86: hyper-v: HVCALL_SEND_IPI_EX is an XMM fast hypercall
+    - powerpc/kasan: Fix early region not updated correctly
+    - powerpc/tm: Fix more userspace r13 corruption
+    - powerpc/lib/sstep: Fix 'sthcx' instruction
+    - powerpc/lib/sstep: Fix build errors with newer binutils
+    - powerpc: Add set_memory_{p/np}() and remove set_memory_attr()
+    - powerpc: Fix build errors with newer binutils
+    - drm/dp: Fix off-by-one in register cache size
+    - drm/i915: Treat SAGV block time 0 as SAGV disabled
+    - drm/i915: Fix PSF GV point mask when SAGV is not possible
+    - drm/i915: Reject unsupported TMDS rates on ICL+
+    - scsi: qla2xxx: Refactor asynchronous command initialization
+    - scsi: qla2xxx: Implement ref count for SRB
+    - scsi: qla2xxx: Fix stuck session in gpdb
+    - scsi: qla2xxx: Fix warning message due to adisc being flushed
+    - scsi: qla2xxx: Fix scheduling while atomic
+    - scsi: qla2xxx: Fix premature hw access after PCI error
+    - scsi: qla2xxx: Fix wrong FDMI data for 64G adapter
+    - scsi: qla2xxx: Fix warning for missing error code
+    - scsi: qla2xxx: Fix device reconnect in loop topology
+    - scsi: qla2xxx: edif: Fix clang warning
+    - scsi: qla2xxx: Fix T10 PI tag escape and IP guard options for 28XX adapters
+    - scsi: qla2xxx: Add devids and conditionals for 28xx
+    - scsi: qla2xxx: Check for firmware dump already collected
+    - scsi: qla2xxx: Suppress a kernel complaint in qla_create_qpair()
+    - scsi: qla2xxx: Fix disk failure to rediscover
+    - scsi: qla2xxx: Fix incorrect reporting of task management failure
+    - scsi: qla2xxx: Fix hang due to session stuck
+    - scsi: qla2xxx: Fix laggy FC remote port session recovery
+    - scsi: qla2xxx: Fix missed DMA unmap for NVMe ls requests
+    - scsi: qla2xxx: Fix crash during module load unload test
+    - scsi: qla2xxx: Fix N2N inconsistent PLOGI
+    - scsi: qla2xxx: Fix stuck session of PRLI reject
+    - scsi: qla2xxx: Reduce false trigger to login
+    - scsi: qla2xxx: Use correct feature type field during RFF_ID processing
+    - platform: chrome: Split trace include file
+    - MIPS: crypto: Fix CRC32 code
+    - KVM: x86: Check lapic_in_kernel() before attempting to set a SynIC irq
+    - KVM: x86: Avoid theoretical NULL pointer dereference in
+      kvm_irq_delivery_to_apic_fast()
+    - KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC wasn't activated
+    - KVM: x86/mmu: do compare-and-exchange of gPTE via the user address
+    - KVM: Prevent module exit until all VMs are freed
+    - KVM: x86: fix sending PV IPI
+    - KVM: SVM: fix panic on out-of-bounds guest IRQ
+    - KVM: avoid double put_page with gfn-to-pfn cache
+    - ubifs: rename_whiteout: Fix double free for whiteout_ui->data
+    - ubifs: Fix deadlock in concurrent rename whiteout and inode writeback
+    - ubifs: Add missing iput if do_tmpfile() failed in rename whiteout
+    - ubifs: Rename whiteout atomically
+    - ubifs: Fix 'ui->dirty' race between do_tmpfile() and writeback work
+    - ubifs: Rectify space amount budget for mkdir/tmpfile operations
+    - ubifs: setflags: Make dirtied_ino_d 8 bytes aligned
+    - ubifs: Fix read out-of-bounds in ubifs_wbuf_write_nolock()
+    - ubifs: Fix to add refcount once page is set private
+    - ubifs: rename_whiteout: correct old_dir size computing
+    - nvme: allow duplicate NSIDs for private namespaces
+    - nvme: fix the read-only state for zoned namespaces with unsupposed features
+    - wireguard: queueing: use CFI-safe ptr_ring cleanup function
+    - wireguard: socket: free skb in send6 when ipv6 is disabled
+    - wireguard: socket: ignore v6 endpoints when ipv6 is disabled
+    - XArray: Fix xas_create_range() when multi-order entry present
+    - can: mcba_usb: mcba_usb_start_xmit(): fix double dev_kfree_skb in error path
+    - can: mcba_usb: properly check endpoint type
+    - can: mcp251xfd: mcp251xfd_register_get_dev_id(): fix return of error value
+    - XArray: Include bitmap.h from xarray.h
+    - XArray: Update the LRU list in xas_split()
+    - modpost: restore the warning message for missing symbol versions
+    - rtc: gamecube: Fix refcount leak in gamecube_rtc_read_offset_from_sram
+    - rtc: check if __rtc_read_time was successful
+    - loop: fix ioctl calls using compat_loop_info
+    - gfs2: gfs2_setattr_size error path fix
+    - gfs2: Fix gfs2_file_buffered_write endless loop workaround
+    - gfs2: Make sure FITRIM minlen is rounded up to fs block size
+    - net: hns3: fix the concurrency between functions reading debugfs
+    - net: hns3: fix software vlan talbe of vlan 0 inconsistent with hardware
+    - rxrpc: fix some null-ptr-deref bugs in server_key.c
+    - rxrpc: Fix call timer start racing with call destruction
+    - mailbox: imx: fix wakeup failure from freeze mode
+    - crypto: x86/poly1305 - Fixup SLS
+    - crypto: arm/aes-neonbs-cbc - Select generic cbc and aes
+    - watch_queue: Free the page array when watch_queue is dismantled
+    - pinctrl: pinconf-generic: Print arguments for bias-pull-*
+    - watchdog: rti-wdt: Add missing pm_runtime_disable() in probe function
+    - net: sparx5: uses, depends on BRIDGE or !BRIDGE
+    - pinctrl: nuvoton: npcm7xx: Rename DS() macro to DSTR()
+    - pinctrl: nuvoton: npcm7xx: Use %zu printk format for ARRAY_SIZE()
+    - ASoC: rockchip: i2s_tdm: Fixup config for SND_SOC_DAIFMT_DSP_A/B
+    - ASoC: mediatek: mt6358: add missing EXPORT_SYMBOLs
+    - ubi: Fix race condition between ctrl_cdev_ioctl and ubi_cdev_ioctl
+    - ARM: iop32x: offset IRQ numbers by 1
+    - block: Fix the maximum minor value is blk_alloc_ext_minor()
+    - block: restore the old set_task_ioprio() behaviour wrt PF_EXITING
+    - Revert "virtio-pci: harden INTX interrupts"
+    - Revert "virtio_pci: harden MSI-X interrupts"
+    - virtio: use virtio_device_ready() in virtio_device_restore()
+    - io_uring: remove poll entry from list when canceling all
+    - io_uring: bump poll refs to full 31-bits
+    - io_uring: fix memory leak of uid in files registration
+    - riscv module: remove (NOLOAD)
+    - ACPI: CPPC: Avoid out of bounds access when parsing _CPC data
+    - vhost: handle error while adding split ranges to iotlb
+    - spi: Fix Tegra QSPI example
+    - platform/chrome: cros_ec_typec: Check for EC device
+    - platform/x86: asus-wmi: Fix regression when probing for fan curve control
+    - can: isotp: restore accidentally removed MSG_PEEK feature
+    - proc: bootconfig: Add null pointer check
+    - x86/fpu/xstate: Fix the ARCH_REQ_XCOMP_PERM implementation
+    - x86/sev: Unroll string mmio with CC_ATTR_GUEST_UNROLL_STRING_IO
+    - drm/connector: Fix typo in documentation
+    - scsi: qla2xxx: Add qla2x00_async_done() for async routines
+    - staging: mt7621-dts: fix pinctrl-0 items to be size-1 items on ethernet
+    - docs: fix 'make htmldocs' warning in SCTP.rst
+    - arm64: mm: Drop 'const' from conditional arm64_dma_phys_limit definition
+    - ASoC: soc-compress: Change the check for codec_dai
+    - KVM: x86: SVM: fix avic spec based definitions again
+    - ax25: fix UAF bug in ax25_send_control()
+    - Reinstate some of "swiotlb: rework "fix info leak with DMA_FROM_DEVICE""
+    - tracing: Have type enum modifications copy the strings
+    - mips: Enable KCSAN - take 2
+    - net: add skb_set_end_offset() helper
+    - mm/mmap: return 1 from stack_guard_gap __setup() handler
+    - ARM: 9187/1: JIVE: fix return value of __setup handler
+    - mm/memcontrol: return 1 from cgroup.memory __setup() handler
+    - mm/usercopy: return 1 from hardened_usercopy __setup() handler
+    - af_unix: Support POLLPRI for OOB.
+    - libbpf: Define BTF_KIND_* constants in btf.h to avoid compilation errors
+    - bpf: Adjust BPF stack helper functions to accommodate skip > 0
+    - bpf: Fix comment for helper bpf_current_task_under_cgroup()
+    - nbd: fix possible overflow on 'first_minor' in nbd_dev_add()
+    - mmc: rtsx: Use pm_runtime_{get,put}() to handle runtime PM
+    - dt-bindings: mtd: nand-controller: Fix the reg property description
+    - dt-bindings: mtd: nand-controller: Fix a comment in the examples
+    - dt-bindings: spi: mxic: The interrupt property is not mandatory
+    - media: dt-binding: media: hynix,hi846: use $defs/port-base port description
+    - media: dt-bindings: media: hynix,hi846: add link-frequencies description
+    - dt-bindings: memory: mtk-smi: Rename clock to clocks
+    - dt-bindings: memory: mtk-smi: No need mediatek,larb-id for mt8167
+    - dt-bindings: memory: mtk-smi: Correct minItems to 2 for the gals clocks
+    - dt-bindings: pinctrl: mt8195: fix bias-pull-{up,down} checks
+    - dt-bindings: pinctrl: pinctrl-microchip-sgpio: Fix example
+    - ubi: fastmap: Return error code if memory allocation fails in add_aeb()
+    - net: preserve skb_end_offset() in skb_unclone_keeptruesize()
+    - ASoC: SOF: Intel: Fix build error without SND_SOC_SOF_PCI_DEV
+    - ASoC: topology: Allow TLV control to be either read or write
+    - perf vendor events: Update metrics for SkyLake Server
+    - media: ov6650: Add try support to selection API operations
+    - media: ov6650: Fix crop rectangle affected by set format
+    - pinctrl: canonical rsel resistance selection property
+    - spi: mediatek: support tick_delay without enhance_timing
+    - ARM: dts: spear1340: Update serial node properties
+    - ARM: dts: spear13xx: Update SPI dma properties
+    - arm64: dts: ls1043a: Update i2c dma properties
+    - arm64: dts: ls1046a: Update i2c node dma properties
+    - um: Fix uml_mconsole stop/go
+    - docs: sysctl/kernel: add missing bit to panic_print
+    - xsk: Do not write NULL in SW ring at allocation failure
+    - ice: xsk: Fix indexing in ice_tx_xsk_pool()
+    - vdpa/mlx5: Avoid processing works if workqueue was destroyed
+    - openvswitch: Fixed nd target mask field in the flow dump.
+    - torture: Make torture.sh help message match reality
+    - n64cart: convert bi_disk to bi_bdev->bd_disk fix build
+    - Revert "nbd: fix possible overflow on 'first_minor' in nbd_dev_add()"
+    - mmc: rtsx: Let MMC core handle runtime PM
+    - mmc: rtsx: Fix build errors/warnings for unused variable
+    - coredump: Snapshot the vmas in do_coredump
+    - coredump: Remove the WARN_ON in dump_vma_snapshot
+    - coredump/elf: Pass coredump_params into fill_note_info
+    - coredump: Use the vma snapshot in fill_files_note
+    - Linux 5.17.2
+
+  * Jammy update: v5.17.1 upstream stable release (LP: #1968982)
+    - tpm: Fix error handling in async work
+    - Bluetooth: btusb: Add another Realtek 8761BU
+    - llc: fix netdevice reference leaks in llc_ui_bind()
+    - ASoC: sti: Fix deadlock via snd_pcm_stop_xrun() call
+    - ALSA: oss: Fix PCM OSS buffer allocation overflow
+    - ALSA: usb-audio: add mapping for new Corsair Virtuoso SE
+    - ALSA: hda/realtek: Add quirk for Clevo NP70PNJ
+    - ALSA: hda/realtek: Add quirk for Clevo NP50PNJ
+    - ALSA: hda/realtek - Fix headset mic problem for a HP machine with alc671
+    - ALSA: hda/realtek: Add quirk for ASUS GA402
+    - ALSA: pcm: Fix races among concurrent hw_params and hw_free calls
+    - ALSA: pcm: Fix races among concurrent read/write and buffer changes
+    - ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls
+    - ALSA: pcm: Fix races among concurrent prealloc proc writes
+    - ALSA: pcm: Add stream lock during PCM reset ioctl operations
+    - ALSA: usb-audio: Add mute TLV for playback volumes on RODE NT-USB
+    - ALSA: cmipci: Restore aux vol on suspend/resume
+    - ALSA: pci: fix reading of swapped values from pcmreg in AC97 codec
+    - drivers: net: xgene: Fix regression in CRC stripping
+    - netfilter: nf_tables: initialize registers in nft_do_chain()
+    - netfilter: nf_tables: validate registers coming from userspace.
+    - ACPI / x86: Work around broken XSDT on Advantech DAC-BJ01 board
+    - ACPI: battery: Add device HID and quirk for Microsoft Surface Go 3
+    - ACPI: video: Force backlight native for Clevo NL5xRU and NL5xNU
+    - crypto: qat - disable registration of algorithms
+    - Bluetooth: btusb: Add one more Bluetooth part for the Realtek RTL8852AE
+    - Bluetooth: hci_sync: Add a new quirk to skip HCI_FLT_CLEAR_ALL
+    - Bluetooth: btusb: Use quirk to skip HCI_FLT_CLEAR_ALL on fake CSR
+      controllers
+    - Revert "ath: add support for special 0x0 regulatory domain"
+    - drm/virtio: Ensure that objs is not NULL in virtio_gpu_array_put_free()
+    - jbd2: fix use-after-free of transaction_t race
+    - rcu: Don't deboost before reporting expedited quiescent state
+    - uaccess: fix integer overflow on access_ok()
+    - mac80211: fix potential double free on mesh join
+    - tpm: fix reference counting for struct tpm_chip
+    - tpm: use try_get_ops() in tpm-space.c
+    - wcn36xx: Differentiate wcn3660 from wcn3620
+    - m68k: fix access_ok for coldfire
+    - nds32: fix access_ok() checks in get/put_user
+    - drm/msm/gpu: Fix crash on devices without devfreq support (v2)
+    - llc: only change llc->dev when bind() succeeds
+    - Linux 5.17.1
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: shiftfs: always rely on init_user_ns
+    - [Config] update configs and annotations after stable updates
+    - SAUCE: sfc: The size of the RX recycle ring should be more flexible
+    - [Packaging] remove references to lowlatency flavor
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 14 Apr 2022 08:45:40 +0200
+
+linux-unstable (5.17.0-6.6) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-6.6 -proposed tracker (LP: #1965731)
+
+  * dependency on crda obsolete according to Debian (LP: #1958918)
+    - [Packaging] switch dependency from crda to wireless-regdb
+
+  * Miscellaneous Ubuntu changes
+    - [Config] disable CONFIG_SYSFB_SIMPLEFB on amd64
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.17
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 21 Mar 2022 09:46:03 +0100
+
+linux-unstable (5.17.0-5.5) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-5.5 -proposed tracker (LP: #1964766)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync dkms-build{,--nvidia-N} from LRMv5
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to v5.17-rc8
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.17-rc8
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 14 Mar 2022 13:15:50 +0100
+
+linux-unstable (5.17.0-4.4) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-4.4 -proposed tracker (LP: #1963880)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.17-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 07 Mar 2022 10:20:48 +0100
+
+linux-unstable (5.17.0-3.3) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-3.3 -proposed tracker (LP: #1962450)
+
+  * 5.15 stuck at boot on c4.large (LP: #1956780)
+    - Revert "PCI/MSI: Mask MSI-X vectors only on success"
+
+  * [22.04 FEAT] KVM: Enable storage key checking for intercepted instruction
+    handled by userspace (LP: #1933179)
+    - s390/uaccess: Add copy_from/to_user_key functions
+    - KVM: s390: Honor storage keys when accessing guest memory
+    - KVM: s390: handle_tprot: Honor storage keys
+    - KVM: s390: Add optional storage key checking to MEMOP IOCTL
+    - KVM: s390: Add vm IOCTL for key checked guest absolute memory access
+    - KVM: s390: Rename existing vcpu memop functions
+    - KVM: s390: Update api documentation for memop ioctl
+    - KVM: s390: Clarify key argument for MEM_OP in api docs
+    - KVM: s390: Add missing vm MEM_OP size check
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.17-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Feb 2022 09:42:32 +0100
+
+linux-unstable (5.17.0-2.2) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-2.2 -proposed tracker (LP: #1962137)
+
+  * CVE-2022-25636
+    - netfilter: nf_tables_offload: incorrect flow offload action array size
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+    - [Packaging] update Ubuntu.md
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Jammy update: v5.15.22 upstream stable release (LP: #1960516)
+    - Revert "ASoC: mediatek: Check for error clk pointer"
+    - [Config] disable FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
+
+  * Jammy update: v5.15.20 upstream stable release (LP: #1960509)
+    - Revert "UBUNTU: SAUCE: Revert "e1000e: Additional PHY power saving in S0ix""
+
+  * Jammy update: v5.15.19 upstream stable release (LP: #1959879)
+    - drm/etnaviv: relax submit size limits
+
+  * Jammy update: v5.15.17 upstream stable release (LP: #1959376)
+    - net: dsa: hellcreek: Allow PTP P2P measurements on blocked ports
+    - rtw88: add quirk to disable pci caps on HP 250 G7 Notebook PC
+    - ASoC: mediatek: Check for error clk pointer
+    - regulator: da9121: Prevent current limit change when enabled
+    - ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream
+    - drm/etnaviv: limit submit sizes
+    - Bluetooth: hci_sync: Fix not setting adv set duration
+    - net: axienet: Wait for PhyRstCmplt after core reset
+
+  * rtw88_8821ce causes freeze (LP: #1927808) // Jammy update: v5.15.17 upstream
+    stable release (LP: #1959376)
+    - rtw88: Disable PCIe ASPM while doing NAPI poll on 8821CE
+
+  * Jammy update: v5.15.15 upstream stable release (LP: #1958418)
+    - Bluetooth: btusb: Add support for Foxconn MT7922A
+    - Bluetooth: btbcm: disable read tx power for MacBook Air 8,1 and 8,2
+    - platform/x86/intel: hid: add quirk to support Surface Go 3
+
+  * Support USB4 DP alt mode for AMD Yellow Carp graphics card (LP: #1953008)
+    - SAUCE: drm/amd/display: Fixup previous PSR policy commit
+
+  * alsa/sdw: add sdw audio machine driver for several ADL machines
+    (LP: #1951563)
+    - ASoC: Intel: sof_sdw: Add support for SKU 0B11 product
+    - ASoC: Intel: sof_sdw: Add support for SKU 0B13 product
+    - ASoC: Intel: sof_sdw: Add support for SKU 0B29 product
+    - ASoC: Intel: sof_sdw: Add support for SKU 0B12 product
+
+  * Improve performance and idle power consumption (LP: #1941893)
+    - x86: ACPI: cstate: Optimize C3 entry on AMD CPUs
+
+  * Fix spurious wakeup caused by Intel 7560 WWAN (LP: #1956443)
+    - net: wwan: iosm: Keep device at D0 for s2idle case
+
+  * Jammy update: v5.15.13 upstream stable release (LP: #1956926)
+    - scsi: lpfc: Terminate string in lpfc_debugfs_nvmeio_trc_write()
+    - net/mlx5: Fix tc max supported prio for nic mode
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Update dependency of pahole / dwarves
+    - [packaging] unhook lowlatency flavours from the build
+    - [Packaging] use default zstd compression
+    - [Packaging] do not use compression for image packages
+    - [Packaging] use xz compression for ddebs
+    - SAUCE: Makefile: Remove inclusion of lbm header files
+    - SAUCE: Makefile: Fix compiler warnings
+    - [Config] drop unused lowlatency configs
+    - [Config] update configs and annotations after rebase to v5.17-rc5
+
+  * Miscellaneous upstream changes
+    - Revert "rtw88: Disable PCIe ASPM while doing NAPI poll on 8821CE"
+    - MAINTAINERS: Add scripts/pahole-flags.sh to BPF section
+    - kbuild: Add CONFIG_PAHOLE_VERSION
+    - lib/Kconfig.debug: Use CONFIG_PAHOLE_VERSION
+    - lib/Kconfig.debug: Allow BTF + DWARF5 with pahole 1.21+
+    - Revert "UBUNTU: [Packaging] temporarily disable zfs"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 24 Feb 2022 09:41:40 +0100
+
+linux-unstable (5.17.0-1.1) jammy; urgency=medium
+
+  * Rebase to 5.17-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 21 Feb 2022 08:22:18 +0100
+
+linux-unstable (5.17.0-0.0) jammy; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 28 Jan 2022 17:14:13 +0100
+
+linux (5.15.0-18.18) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-18.18 -proposed tracker (LP: #1958638)
+
+  * CVE-2021-4155
+    - xfs: map unwritten blocks in XFS_IOC_{ALLOC, FREE}SP just like fallocate
+
+  * CVE-2022-0185
+    - SAUCE: vfs: test that one given mount param is not larger than PAGE_SIZE
+
+  * [UBUNTU 20.04] KVM hardware diagnose data improvements for guest kernel -
+    kernel part (LP: #1953334)
+    - KVM: s390: add debug statement for diag 318 CPNC data
+
+  * OOB write on BPF_RINGBUF (LP: #1956585)
+    - SAUCE: bpf: prevent helper argument PTR_TO_ALLOC_MEM to have offset other
+      than 0
+
+  * Miscellaneous Ubuntu changes
+    - [Config] re-enable shiftfs
+    - [SAUCE] shiftfs: support kernel 5.15
+    - [Config] update toolchain versions
+
+  * Miscellaneous upstream changes
+    - vfs: fs_context: fix up param length parsing in legacy_parse_param
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 21 Jan 2022 13:32:27 +0100
+
+linux (5.15.0-17.17) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-17.17 -proposed tracker (LP: #1957809)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 13 Jan 2022 17:11:21 +0100
+
+linux (5.15.0-16.16) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-16.16 -proposed tracker (LP: #1956820)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * 5.15 stuck at boot on c4.large (LP: #1956780)
+    - Revert "PCI/MSI: Mask MSI-X vectors only on success"
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] temporarily disable signed v4l2loopback"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Sat, 08 Jan 2022 10:57:58 +0100
+
+linux (5.15.0-15.15) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-15.15 -proposed tracker (LP: #1956314)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * rtw88_8821ce causes freeze (LP: #1927808)
+    - rtw88: Disable PCIe ASPM while doing NAPI poll on 8821CE
+
+  * alsa/sdw: fix the  audio sdw codec parsing logic in the acpi table
+    (LP: #1955686)
+    - ALSA: hda: intel-sdw-acpi: go through HDAS ACPI at max depth of 2
+    - ALSA: hda: intel-sdw-acpi: harden detection of controller
+
+  * Got black screen when resume from s2idle with AMD dGPU (LP: #1955790)
+    - SAUCE: drm/amdgpu: put SMU into proper state on runpm suspending for BOCO
+      capable platform
+    - SAUCE: drm/amdgpu: always reset the asic in suspend (v2)
+
+  *  Fix USB3 detection on HP dock (LP: #1955443)
+    - usb: hub: Add delay for SuperSpeed hub resume to let links transit to U0
+
+  * support signed v4l2loopback dkms build (LP: #1938531)
+    - enable v4l2loopback builds on amd64 kernels
+    - support v4l2loopback dkms build
+
+  * Jammy update: v5.15.12 upstream stable release (LP: #1956305)
+    - arm64: vdso32: require CROSS_COMPILE_COMPAT for gcc+bfd
+    - net: usb: lan78xx: add Allied Telesis AT29M2-AF
+    - ext4: prevent partial update of the extent blocks
+    - ext4: check for out-of-order index extents in ext4_valid_extent_entries()
+    - ext4: check for inconsistent extents between index and leaf block
+    - selftests: KVM: Fix non-x86 compiling
+    - HID: holtek: fix mouse probing
+    - HID: potential dereference of null pointer
+    - NFSD: Fix READDIR buffer overflow
+    - PM: sleep: Fix error handling in dpm_prepare()
+    - arm64: dts: allwinner: orangepi-zero-plus: fix PHY mode
+    - bus: sunxi-rsb: Fix shutdown
+    - spi: change clk_disable_unprepare to clk_unprepare
+    - ucounts: Fix rlimit max values check
+    - drm/mediatek: hdmi: Perform NULL pointer check for mtk_hdmi_conf
+    - ASoC: meson: aiu: fifo: Add missing dma_coerce_mask_and_coherent()
+    - RDMA/hns: Fix RNR retransmission issue for HIP08
+    - IB/qib: Fix memory leak in qib_user_sdma_queue_pkts()
+    - RDMA/hns: Replace kfree() with kvfree()
+    - netfilter: nf_tables: fix use-after-free in nft_set_catchall_destroy()
+    - netfilter: fix regression in looped (broad|multi)cast's MAC handling
+    - ARM: dts: imx6qdl-wandboard: Fix Ethernet support
+    - ice: Use xdp_buf instead of rx_buf for xsk zero-copy
+    - ice: xsk: return xsk buffers back to pool when cleaning the ring
+    - net: marvell: prestera: fix incorrect return of port_find
+    - net: marvell: prestera: fix incorrect structure access
+    - qlcnic: potential dereference null pointer of rx_queue->page_ring
+    - tcp: move inet->rx_dst_ifindex to sk->sk_rx_dst_ifindex
+    - ipv6: move inet6_sk(sk)->rx_dst_cookie to sk->sk_rx_dst_cookie
+    - inet: fully convert sk->sk_rx_dst to RCU rules
+    - net: accept UFOv6 packages in virtio_net_hdr_to_skb
+    - net: skip virtio_net_hdr_set_proto if protocol already set
+    - igb: fix deadlock caused by taking RTNL in RPM resume path
+    - ipmi: Fix UAF when uninstall ipmi_si and ipmi_msghandler module
+    - gpio: virtio: remove timeout
+    - bonding: fix ad_actor_system option setting to default
+    - fjes: Check for error irq
+    - drivers: net: smc911x: Check for error irq
+    - net: ks8851: Check for error irq
+    - sfc: Check null pointer of rx_queue->page_ring
+    - sfc: falcon: Check null pointer of rx_queue->page_ring
+    - asix: fix uninit-value in asix_mdio_read()
+    - asix: fix wrong return value in asix_check_host_enable()
+    - io_uring: zero iocb->ki_pos for stream file types
+    - veth: ensure skb entering GRO are not cloned.
+    - net: stmmac: ptp: fix potentially overflowing expression
+    - net: bridge: Use array_size() helper in copy_to_user()
+    - net: bridge: fix ioctl old_deviceless bridge argument
+    - r8152: fix the force speed doesn't work for RTL8156
+    - net: stmmac: dwmac-visconti: Fix value of ETHER_CLK_SEL_FREQ_SEL_2P5M
+    - pinctrl: bcm2835: Change init order for gpio hogs
+    - hwmon: (lm90) Fix usage of CONFIG2 register in detect function
+    - hwmon: (lm90) Prevent integer overflow/underflow in hysteresis calculations
+    - hwmon: (lm90) Introduce flag indicating extended temperature support
+    - hwmon: (lm90) Add basic support for TI TMP461
+    - hwmon: (lm90) Drop critical attribute support for MAX6654
+    - ARM: 9160/1: NOMMU: Reload __secondary_data after PROCINFO_INITFUNC
+    - uapi: Fix undefined __always_inline on non-glibc systems
+    - compiler.h: Fix annotation macro misplacement with Clang
+    - platform/x86/intel: Remove X86_PLATFORM_DRIVERS_INTEL
+    - kernel/crash_core: suppress unknown crashkernel parameter warning
+    - Revert "x86/boot: Pull up cmdline preparation and early param parsing"
+    - x86/boot: Move EFI range reservation after cmdline parsing
+    - ALSA: jack: Check the return value of kstrdup()
+    - ALSA: drivers: opl3: Fix incorrect use of vp->state
+    - ALSA: rawmidi - fix the uninitalized user_pversion
+    - ALSA: hda/hdmi: Disable silent stream on GLK
+    - ALSA: hda/realtek: Amp init fixup for HP ZBook 15 G6
+    - ALSA: hda/realtek: Add new alc285-hp-amp-init model
+    - ALSA: hda/realtek: fix mute/micmute LEDs for a HP ProBook
+    - ALSA: hda/realtek: Fix quirk for Clevo NJ51CU
+    - ASoC: meson: aiu: Move AIU_I2S_MISC hold setting to aiu-fifo-i2s
+    - ASoC: tegra: Add DAPM switches for headphones and mic jack
+    - ASoC: tegra: Restore headphones jack name on Nyan Big
+    - Input: atmel_mxt_ts - fix double free in mxt_read_info_block
+    - ipmi: bail out if init_srcu_struct fails
+    - ipmi: ssif: initialize ssif_info->client early
+    - ipmi: fix initialization when workqueue allocation fails
+    - parisc: Correct completer in lws start
+    - parisc: Fix mask used to select futex spinlock
+    - tee: handle lookup of shm with reference count 0
+    - x86/pkey: Fix undefined behaviour with PKRU_WD_BIT
+    - platform/x86: amd-pmc: only use callbacks for suspend
+    - platform/x86: intel_pmc_core: fix memleak on registration failure
+    - KVM: x86: Always set kvm_run->if_flag
+    - KVM: x86/mmu: Don't advance iterator after restart due to yielding
+    - KVM: nVMX: Synthesize TRIPLE_FAULT for L2 if emulation is required
+    - KVM: VMX: Always clear vmx->fail on emulation_required
+    - KVM: VMX: Wake vCPU when delivering posted IRQ even if vCPU == this vCPU
+    - pinctrl: stm32: consider the GPIO offset to expose all the GPIO lines
+    - gpio: dln2: Fix interrupts when replugging the device
+    - mmc: sdhci-tegra: Fix switch to HS400ES mode
+    - mmc: meson-mx-sdhc: Set MANUAL_STOP for multi-block SDIO commands
+    - mmc: core: Disable card detect during shutdown
+    - mmc: mmci: stm32: clear DLYB_CR after sending tuning command
+    - ARM: 9169/1: entry: fix Thumb2 bug in iWMMXt exception handling
+    - ksmbd: fix error code in ndr_read_int32()
+    - ksmbd: fix uninitialized symbol 'pntsd_size'
+    - ksmbd: disable SMB2_GLOBAL_CAP_ENCRYPTION for SMB 3.1.1
+    - mac80211: fix locking in ieee80211_start_ap error path
+    - mm: mempolicy: fix THP allocations escaping mempolicy restrictions
+    - mm, hwpoison: fix condition in free hugetlb page path
+    - mm/hwpoison: clear MF_COUNT_INCREASED before retrying get_any_page()
+    - mm/damon/dbgfs: protect targets destructions with kdamond_lock
+    - tee: optee: Fix incorrect page free bug
+    - f2fs: fix to do sanity check on last xattr entry in __f2fs_setxattr()
+    - netfs: fix parameter of cleanup()
+    - KVM: VMX: Fix stale docs for kvm-intel.emulate_invalid_guest_state
+    - arm64: dts: lx2160a: fix scl-gpios property name
+    - kfence: fix memory leak when cat kfence objects
+    - Input: iqs626a - prohibit inlining of channel parsing functions
+    - Input: elants_i2c - do not check Remark ID on eKTH3900/eKTH5312
+    - Input: goodix - add id->model mapping for the "9111" model
+    - ASoC: tas2770: Fix setting of high sample rates
+    - ASoC: SOF: Intel: pci-tgl: add new ADL-P variant
+    - ASoC: SOF: Intel: pci-tgl: add ADL-N support
+    - ASoC: rt5682: fix the wrong jack type detected
+    - pinctrl: mediatek: fix global-out-of-bounds issue
+    - hwmom: (lm90) Fix citical alarm status for MAX6680/MAX6681
+    - hwmon: (lm90) Do not report 'busy' status bit as alarm
+    - r8152: sync ocp base
+    - ax25: NPD bug when detaching AX25 device
+    - hamradio: defer ax25 kfree after unregister_netdev
+    - hamradio: improve the incomplete fix to avoid NPD
+    - tun: avoid double free in tun_free_netdev
+    - phonet/pep: refuse to enable an unbound pipe
+    - Linux 5.15.12
+
+  * Thinkpad E14 Gen2: Kernel panic with trackpad and trackpoint enabled
+    (LP: #1945590) // Jammy update: v5.15.12 upstream stable release
+    (LP: #1956305)
+    - Input: elantech - fix stack out of bound access in
+      elantech_change_report_id()
+
+  * Jammy update: v5.15.11 upstream stable release (LP: #1956302)
+    - reset: tegra-bpmp: Revert Handle errors in BPMP response
+    - KVM: VMX: clear vmx_x86_ops.sync_pir_to_irr if APICv is disabled
+    - KVM: selftests: Make sure kvm_create_max_vcpus test won't hit RLIMIT_NOFILE
+    - KVM: downgrade two BUG_ONs to WARN_ON_ONCE
+    - x86/kvm: remove unused ack_notifier callbacks
+    - KVM: X86: Fix tlb flush for tdp in kvm_invalidate_pcid()
+    - mac80211: fix rate control for retransmitted frames
+    - mac80211: fix regression in SSN handling of addba tx
+    - mac80211: mark TX-during-stop for TX in in_reconfig
+    - mac80211: send ADDBA requests using the tid/queue of the aggregation session
+    - mac80211: validate extended element ID is present
+    - firmware: arm_scpi: Fix string overflow in SCPI genpd driver
+    - bpf: Fix kernel address leakage in atomic fetch
+    - bpf, selftests: Add test case for atomic fetch on spilled pointer
+    - bpf: Fix signed bounds propagation after mov32
+    - bpf: Make 32->64 bounds propagation slightly more robust
+    - bpf, selftests: Add test case trying to taint map value pointer
+    - bpf: Fix kernel address leakage in atomic cmpxchg's r0 aux reg
+    - bpf, selftests: Update test case for atomic cmpxchg on r0 with pointer
+    - vduse: fix memory corruption in vduse_dev_ioctl()
+    - vduse: check that offset is within bounds in get_config()
+    - virtio_ring: Fix querying of maximum DMA mapping size for virtio device
+    - vdpa: check that offsets are within bounds
+    - s390/entry: fix duplicate tracking of irq nesting level
+    - recordmcount.pl: look for jgnop instruction as well as bcrl on s390
+    - arm64: dts: ten64: remove redundant interrupt declaration for gpio-keys
+    - ceph: fix up non-directory creation in SGID directories
+    - dm btree remove: fix use after free in rebalance_children()
+    - audit: improve robustness of the audit queue handling
+    - btrfs: convert latest_bdev type to btrfs_device and rename
+    - btrfs: use latest_dev in btrfs_show_devname
+    - btrfs: update latest_dev when we create a sprout device
+    - btrfs: remove stale comment about the btrfs_show_devname
+    - scsi: ufs: core: Retry START_STOP on UNIT_ATTENTION
+    - arm64: dts: rockchip: remove mmc-hs400-enhanced-strobe from rk3399-khadas-
+      edge
+    - arm64: dts: rockchip: fix rk3308-roc-cc vcc-sd supply
+    - arm64: dts: rockchip: fix rk3399-leez-p710 vcc3v3-lan supply
+    - arm64: dts: rockchip: fix audio-supply for Rock Pi 4
+    - arm64: dts: rockchip: fix poweroff on helios64
+    - dmaengine: idxd: add halt interrupt support
+    - dmaengine: idxd: fix calling wq quiesce inside spinlock
+    - mac80211: track only QoS data frames for admission control
+    - tee: amdtee: fix an IS_ERR() vs NULL bug
+    - ceph: fix duplicate increment of opened_inodes metric
+    - ceph: initialize pathlen variable in reconnect_caps_cb
+    - ARM: socfpga: dts: fix qspi node compatible
+    - arm64: dts: imx8mq: remove interconnect property from lcdif
+    - clk: Don't parent clks until the parent is fully registered
+    - soc: imx: Register SoC device only on i.MX boards
+    - iwlwifi: mvm: don't crash on invalid rate w/o STA
+    - virtio: always enter drivers/virtio/
+    - virtio/vsock: fix the transport to work with VMADDR_CID_ANY
+    - vdpa: Consider device id larger than 31
+    - Revert "drm/fb-helper: improve DRM fbdev emulation device names"
+    - selftests: net: Correct ping6 expected rc from 2 to 1
+    - s390/kexec_file: fix error handling when applying relocations
+    - sch_cake: do not call cake_destroy() from cake_init()
+    - inet_diag: fix kernel-infoleak for UDP sockets
+    - netdevsim: don't overwrite read only ethtool parms
+    - selftests: icmp_redirect: pass xfail=0 to log_test()
+    - net: hns3: fix use-after-free bug in hclgevf_send_mbx_msg
+    - net: hns3: fix race condition in debugfs
+    - selftests: Add duplicate config only for MD5 VRF tests
+    - selftests: Fix raw socket bind tests with VRF
+    - selftests: Fix IPv6 address bind tests
+    - dmaengine: idxd: fix missed completion on abort path
+    - dmaengine: st_fdma: fix MODULE_ALIAS
+    - drm: simpledrm: fix wrong unit with pixel clock
+    - net/sched: sch_ets: don't remove idle classes from the round-robin list
+    - selftests/net: toeplitz: fix udp option
+    - net: dsa: mv88e6xxx: Unforce speed & duplex in mac_link_down()
+    - selftest/net/forwarding: declare NETIFS p9 p10
+    - mptcp: never allow the PM to close a listener subflow
+    - drm/ast: potential dereference of null pointer
+    - drm/i915/display: Fix an unsigned subtraction which can never be negative.
+    - mac80211: agg-tx: don't schedule_and_wake_txq() under sta->lock
+    - cfg80211: Acquire wiphy mutex on regulatory work
+    - mac80211: fix lookup when adding AddBA extension element
+    - net: stmmac: fix tc flower deletion for VLAN priority Rx steering
+    - flow_offload: return EOPNOTSUPP for the unsupported mpls action type
+    - rds: memory leak in __rds_conn_create()
+    - ice: Use div64_u64 instead of div_u64 in adjfine
+    - ice: Don't put stale timestamps in the skb
+    - drm/amd/display: Set exit_optimized_pwr_state for DCN31
+    - drm/amd/pm: fix a potential gpu_metrics_table memory leak
+    - mptcp: remove tcp ulp setsockopt support
+    - mptcp: clear 'kern' flag from fallback sockets
+    - mptcp: fix deadlock in __mptcp_push_pending()
+    - soc/tegra: fuse: Fix bitwise vs. logical OR warning
+    - igb: Fix removal of unicast MAC filters of VFs
+    - igbvf: fix double free in `igbvf_probe`
+    - igc: Fix typo in i225 LTR functions
+    - ixgbe: Document how to enable NBASE-T support
+    - ixgbe: set X550 MDIO speed before talking to PHY
+    - netdevsim: Zero-initialize memory for new map's value in function
+      nsim_bpf_map_alloc
+    - net/packet: rx_owner_map depends on pg_vec
+    - net: stmmac: dwmac-rk: fix oob read in rk_gmac_setup
+    - sfc_ef100: potential dereference of null pointer
+    - dsa: mv88e6xxx: fix debug print for SPEED_UNFORCED
+    - net: Fix double 0x prefix print in SKB dump
+    - net/smc: Prevent smc_release() from long blocking
+    - net: systemport: Add global locking for descriptor lifecycle
+    - sit: do not call ipip6_dev_free() from sit_init_net()
+    - afs: Fix mmap
+    - arm64: kexec: Fix missing error code 'ret' warning in load_other_segments()
+    - bpf: Fix extable fixup offset.
+    - bpf, selftests: Fix racing issue in btf_skc_cls_ingress test
+    - powerpc/85xx: Fix oops when CONFIG_FSL_PMC=n
+    - USB: gadget: bRequestType is a bitfield, not a enum
+    - Revert "usb: early: convert to readl_poll_timeout_atomic()"
+    - KVM: x86: Drop guest CPUID check for host initiated writes to
+      MSR_IA32_PERF_CAPABILITIES
+    - tty: n_hdlc: make n_hdlc_tty_wakeup() asynchronous
+    - USB: NO_LPM quirk Lenovo USB-C to Ethernet Adapher(RTL8153-04)
+    - usb: dwc2: fix STM ID/VBUS detection startup delay in dwc2_driver_probe
+    - PCI/MSI: Clear PCI_MSIX_FLAGS_MASKALL on error
+    - PCI/MSI: Mask MSI-X vectors only on success
+    - usb: xhci-mtk: fix list_del warning when enable list debug
+    - usb: xhci: Extend support for runtime power management for AMD's Yellow
+      carp.
+    - usb: cdnsp: Fix incorrect status for control request
+    - usb: cdnsp: Fix incorrect calling of cdnsp_died function
+    - usb: cdnsp: Fix issue in cdnsp_log_ep trace event
+    - usb: cdnsp: Fix lack of spin_lock_irqsave/spin_lock_restore
+    - usb: typec: tcpm: fix tcpm unregister port but leave a pending timer
+    - usb: gadget: u_ether: fix race in setting MAC address in setup phase
+    - USB: serial: cp210x: fix CP2105 GPIO registration
+    - USB: serial: option: add Telit FN990 compositions
+    - selinux: fix sleeping function called from invalid context
+    - btrfs: fix memory leak in __add_inode_ref()
+    - btrfs: fix double free of anon_dev after failure to create subvolume
+    - btrfs: check WRITE_ERR when trying to read an extent buffer
+    - btrfs: fix missing blkdev_put() call in btrfs_scan_one_device()
+    - zonefs: add MODULE_ALIAS_FS
+    - iocost: Fix divide-by-zero on donation from low hweight cgroup
+    - serial: 8250_fintek: Fix garbled text for console
+    - timekeeping: Really make sure wall_to_monotonic isn't positive
+    - cifs: sanitize multiple delimiters in prepath
+    - locking/rtmutex: Fix incorrect condition in rtmutex_spin_on_owner()
+    - riscv: dts: unleashed: Add gpio card detect to mmc-spi-slot
+    - riscv: dts: unmatched: Add gpio card detect to mmc-spi-slot
+    - perf inject: Fix segfault due to close without open
+    - perf inject: Fix segfault due to perf_data__fd() without open
+    - libata: if T_LENGTH is zero, dma direction should be DMA_NONE
+    - powerpc/module_64: Fix livepatching for RO modules
+    - drm/amdgpu: correct register access for RLC_JUMP_TABLE_RESTORE
+    - drm/amdgpu: don't override default ECO_BITs setting
+    - drm/amd/pm: fix reading SMU FW version from amdgpu_firmware_info on YC
+    - Revert "can: m_can: remove support for custom bit timing"
+    - can: m_can: make custom bittiming fields const
+    - can: m_can: pci: use custom bit timings for Elkhart Lake
+    - ARM: dts: imx6ull-pinfunc: Fix CSI_DATA07__ESAI_TX0 pad name
+    - xsk: Do not sleep in poll() when need_wakeup set
+    - mptcp: add missing documented NL params
+    - bpf, x64: Factor out emission of REX byte in more cases
+    - bpf: Fix extable address check.
+    - USB: core: Make do_proc_control() and do_proc_bulk() killable
+    - media: mxl111sf: change mutex_init() location
+    - fuse: annotate lock in fuse_reverse_inval_entry()
+    - ovl: fix warning in ovl_create_real()
+    - scsi: scsi_debug: Don't call kcalloc() if size arg is zero
+    - scsi: scsi_debug: Fix type in min_t to avoid stack OOB
+    - scsi: scsi_debug: Sanity check block descriptor length in resp_mode_select()
+    - io-wq: remove spurious bit clear on task_work addition
+    - io-wq: check for wq exit after adding new worker task_work
+    - rcu: Mark accesses to rcu_state.n_force_qs
+    - io-wq: drop wqe lock before creating new worker
+    - bus: ti-sysc: Fix variable set but not used warning for reinit_modules
+    - selftests/damon: test debugfs file reads/writes with huge count
+    - Revert "xsk: Do not sleep in poll() when need_wakeup set"
+    - xen/blkfront: harden blkfront against event channel storms
+    - xen/netfront: harden netfront against event channel storms
+    - xen/console: harden hvc_xen against event channel storms
+    - xen/netback: fix rx queue stall detection
+    - xen/netback: don't queue unlimited number of packages
+    - Linux 5.15.11
+
+  * Jammy update: v5.15.10 upstream stable release (LP: #1956301)
+    - nfc: fix segfault in nfc_genl_dump_devices_done
+    - hwmon: (corsair-psu) fix plain integer used as NULL pointer
+    - RDMA: Fix use-after-free in rxe_queue_cleanup
+    - RDMA/mlx5: Fix releasing unallocated memory in dereg MR flow
+    - mtd: rawnand: Fix nand_erase_op delay
+    - mtd: rawnand: Fix nand_choose_best_timings() on unsupported interface
+    - inet: use #ifdef CONFIG_SOCK_RX_QUEUE_MAPPING consistently
+    - dt-bindings: media: nxp,imx7-mipi-csi2: Drop bad if/then schema
+    - clk: qcom: sm6125-gcc: Swap ops of ice and apps on sdcc1
+    - perf bpf_skel: Do not use typedef to avoid error on old clang
+    - netfs: Fix lockdep warning from taking sb_writers whilst holding mmap_lock
+    - RDMA/irdma: Fix a user-after-free in add_pble_prm
+    - RDMA/irdma: Fix a potential memory allocation issue in
+      'irdma_prm_add_pble_mem()'
+    - RDMA/irdma: Report correct WC errors
+    - RDMA/irdma: Don't arm the CQ more than two times if no CE for this CQ
+    - ice: fix FDIR init missing when reset VF
+    - vmxnet3: fix minimum vectors alloc issue
+    - i2c: virtio: fix completion handling
+    - drm/msm: Fix null ptr access msm_ioctl_gem_submit()
+    - drm/msm/a6xx: Fix uinitialized use of gpu_scid
+    - drm/msm/dsi: set default num_data_lanes
+    - drm/msm/dp: Avoid unpowered AUX xfers that caused crashes
+    - KVM: arm64: Save PSTATE early on exit
+    - s390/test_unwind: use raw opcode instead of invalid instruction
+    - Revert "tty: serial: fsl_lpuart: drop earlycon entry for i.MX8QXP"
+    - net/mlx4_en: Update reported link modes for 1/10G
+    - loop: Use pr_warn_once() for loop_control_remove() warning
+    - ALSA: hda: Add Intel DG2 PCI ID and HDMI codec vid
+    - ALSA: hda/hdmi: fix HDA codec entry table order for ADL-P
+    - parisc/agp: Annotate parisc agp init functions with __init
+    - i2c: rk3x: Handle a spurious start completion interrupt flag
+    - net: netlink: af_netlink: Prevent empty skb by adding a check on len.
+    - drm/amdgpu: cancel the correct hrtimer on exit
+    - drm/amdgpu: check atomic flag to differeniate with legacy path
+    - drm/amd/display: Fix for the no Audio bug with Tiled Displays
+    - drm/amdkfd: fix double free mem structure
+    - drm/amd/display: add connector type check for CRC source set
+    - drm/amdkfd: process_info lock not needed for svm
+    - tracing: Fix a kmemleak false positive in tracing_map
+    - staging: most: dim2: use device release method
+    - fuse: make sure reclaim doesn't write the inode
+    - perf inject: Fix itrace space allowed for new attributes
+    - Linux 5.15.10
+
+  * Jammy update: v5.15.9 upstream stable release (LP: #1955161)
+    - netfilter: selftest: conntrack_vrf.sh: fix file permission
+    - Linux 5.15.9
+
+  * [SRU][I/J/OEM-5.13/OEM-5.14] Fix pci port lost when hotplug dock
+    (LP: #1954646)
+    - PCI: Re-enable Downstream Port LTR after reset or hotplug
+
+  * Add support for NVIDIA EC backlight (LP: #1953286)
+    - platform/x86: Add driver for ACPI WMAA EC-based backlight control
+    - platform/x86: Remove "WMAA" from identifier names in wmaa-backlight-wmi.c
+    - platform/x86: Rename wmaa-backlight-wmi to nvidia-wmi-ec-backlight
+    - [Config] NVIDIA_WMI_EC_BACKLIGHT=m
+
+  * Improve USB Type-C support (LP: #1950974)
+    - usb: typec: ucsi: Always cancel the command if PPM reports BUSY condition
+    - usb: typec: ucsi: Don't stop alt mode registration on busy condition
+    - usb: typec: ucsi: Add polling mechanism for partner tasks like alt mode
+      checking
+    - usb: typec: ucsi: acpi: Reduce the command completion timeout
+    - usb: typec: ucsi: Check the partner alt modes always if there is PD contract
+    - usb: typec: ucsi: Read the PDOs in separate work
+    - usb: typec: ucsi: Better fix for missing unplug events issue
+
+  *  Fix power button wakeup with shared IRQs on AMD platforms (LP: #1953540)
+    - pinctrl: amd: Fix wakeups when IRQ is shared with SCI
+
+  * AMD: Suspend not working when some cores are disabled through cpufreq
+    (LP: #1954930)
+    - ACPI: processor idle: Allow playing dead in C3 state
+
+  * Jammy update: v5.15.8 upstream stable release (LP: #1954931)
+    - Revert "UBUNTU: SAUCE: selftests: fib_tests: assign address to dummy1 for
+      rp_filter tests"
+    - usb: gadget: uvc: fix multiple opens
+    - HID: quirks: Add quirk for the Microsoft Surface 3 type-cover
+    - HID: google: add eel USB id
+    - HID: intel-ish-hid: ipc: only enable IRQ wakeup when requested
+    - HID: add hid_is_usb() function to make it simpler for USB detection
+    - HID: add USB_HID dependancy to hid-prodikeys
+    - HID: add USB_HID dependancy to hid-chicony
+    - HID: add USB_HID dependancy on some USB HID drivers
+    - HID: bigbenff: prevent null pointer dereference
+    - HID: wacom: fix problems when device is not a valid USB device
+    - HID: check for valid USB device for many HID drivers
+    - mtd: dataflash: Add device-tree SPI IDs
+    - mmc: spi: Add device-tree SPI IDs
+    - HID: sony: fix error path in probe
+    - HID: Ignore battery for Elan touchscreen on Asus UX550VE
+    - platform/x86/intel: hid: add quirk to support Surface Go 3
+    - nft_set_pipapo: Fix bucket load in AVX2 lookup routine for six 8-bit groups
+    - IB/hfi1: Insure use of smp_processor_id() is preempt disabled
+    - IB/hfi1: Fix early init panic
+    - IB/hfi1: Fix leak of rcvhdrtail_dummy_kvaddr
+    - can: kvaser_usb: get CAN clock frequency from device
+    - can: kvaser_pciefd: kvaser_pciefd_rx_error_frame(): increase correct
+      stats->{rx,tx}_errors counter
+    - can: sja1000: fix use after free in ems_pcmcia_add_card()
+    - can: pch_can: pch_can_rx_normal: fix use after free
+    - can: m_can: m_can_read_fifo: fix memory leak in error branch
+    - can: m_can: pci: fix incorrect reference clock rate
+    - can: m_can: pci: fix iomap_read_fifo() and iomap_write_fifo()
+    - can: m_can: Disable and ignore ELO interrupt
+    - net: dsa: mv88e6xxx: fix "don't use PHY_DETECT on internal PHY's"
+    - net: dsa: mv88e6xxx: allow use of PHYs on CPU and DSA ports
+    - x86/sme: Explicitly map new EFI memmap table as encrypted
+    - platform/x86: amd-pmc: Fix s2idle failures on certain AMD laptops
+    - nfc: fix potential NULL pointer deref in nfc_genl_dump_ses_done
+    - selftests: netfilter: add a vrf+conntrack testcase
+    - vrf: don't run conntrack on vrf with !dflt qdisc
+    - bpf, x86: Fix "no previous prototype" warning
+    - bpf, sockmap: Attach map progs to psock early for feature probes
+    - bpf: Make sure bpf_disable_instrumentation() is safe vs preemption.
+    - bpf: Fix the off-by-two error in range markings
+    - ice: ignore dropped packets during init
+    - ethtool: do not perform operations on net devices being unregistered
+    - bonding: make tx_rebalance_counter an atomic
+    - nfp: Fix memory leak in nfp_cpp_area_cache_add()
+    - udp: using datalen to cap max gso segments
+    - netfilter: nft_exthdr: break evaluation if setting TCP option fails
+    - netfilter: conntrack: annotate data-races around ct->timeout
+    - iavf: restore MSI state on reset
+    - iavf: Fix reporting when setting descriptor count
+    - IB/hfi1: Correct guard on eager buffer deallocation
+    - devlink: fix netns refcount leak in devlink_nl_cmd_reload()
+    - net: bcm4908: Handle dma_set_coherent_mask error codes
+    - net: dsa: mv88e6xxx: error handling for serdes_power functions
+    - net: dsa: felix: Fix memory leak in felix_setup_mmio_filtering
+    - net/sched: fq_pie: prevent dismantle issue
+    - net: mvpp2: fix XDP rx queues registering
+    - KVM: x86: Don't WARN if userspace mucks with RCX during string I/O exit
+    - KVM: x86: Ignore sparse banks size for an "all CPUs", non-sparse IPI req
+    - KVM: x86: Wait for IPIs to be delivered when handling Hyper-V TLB flush
+      hypercall
+    - timers: implement usleep_idle_range()
+    - mm/damon/core: fix fake load reports due to uninterruptible sleeps
+    - mm/slub: fix endianness bug for alloc/free_traces attributes
+    - mm: bdi: initialize bdi_min_ratio when bdi is unregistered
+    - ALSA: ctl: Fix copy of updated id with element read/write
+    - ALSA: hda/realtek - Add headset Mic support for Lenovo ALC897 platform
+    - ALSA: hda/realtek: Fix quirk for TongFang PHxTxX1
+    - ALSA: pcm: oss: Fix negative period/buffer sizes
+    - ALSA: pcm: oss: Limit the period size to 16MB
+    - ALSA: pcm: oss: Handle missing errors in snd_pcm_oss_change_params*()
+    - cifs: Fix crash on unload of cifs_arc4.ko
+    - scsi: qla2xxx: Format log strings only if needed
+    - btrfs: clear extent buffer uptodate when we fail to write it
+    - btrfs: fix re-dirty process of tree-log nodes
+    - btrfs: replace the BUG_ON in btrfs_del_root_ref with proper error handling
+    - btrfs: free exchange changeset on failures
+    - perf intel-pt: Fix some PGE (packet generation enable/control flow packets)
+      usage
+    - perf intel-pt: Fix sync state when a PSB (synchronization) packet is found
+    - perf intel-pt: Fix intel_pt_fup_event() assumptions about setting state type
+    - perf intel-pt: Fix state setting when receiving overflow (OVF) packet
+    - perf intel-pt: Fix next 'err' value, walking trace
+    - perf intel-pt: Fix missing 'instruction' events with 'q' option
+    - perf intel-pt: Fix error timestamp setting on the decoder error path
+    - md: fix update super 1.0 on rdev size change
+    - nfsd: fix use-after-free due to delegation race
+    - nfsd: Fix nsfd startup race (again)
+    - tracefs: Have new files inherit the ownership of their parent
+    - selftests: KVM: avoid failures due to reserved HyperTransport region
+    - hwmon: (pwm-fan) Ensure the fan going on in .probe()
+    - mmc: renesas_sdhi: initialize variable properly when tuning
+    - clk: qcom: regmap-mux: fix parent clock lookup
+    - thermal: int340x: Fix VCoRefLow MMIO bit offset for TGL
+    - drm/syncobj: Deal with signalled fences in drm_syncobj_find_fence.
+    - libata: add horkage for ASMedia 1092
+    - io_uring: ensure task_work gets run as part of cancelations
+    - wait: add wake_up_pollfree()
+    - binder: use wake_up_pollfree()
+    - signalfd: use wake_up_pollfree()
+    - aio: keep poll requests on waitqueue until completed
+    - aio: fix use-after-free due to missing POLLFREE handling
+    - tracefs: Set all files to the same group ownership as the mount option
+    - i2c: mpc: Use atomic read and fix break condition
+    - block: fix ioprio_get(IOPRIO_WHO_PGRP) vs setuid(2)
+    - scsi: pm80xx: Do not call scsi_remove_host() in pm8001_alloc()
+    - scsi: scsi_debug: Fix buffer size of REPORT ZONES command
+    - ALSA: usb-audio: Reorder snd_djm_devices[] entries
+    - qede: validate non LSO skb length
+    - PM: runtime: Fix pm_runtime_active() kerneldoc comment
+    - ASoC: rt5682: Fix crash due to out of scope stack vars
+    - ASoC: qdsp6: q6routing: Fix return value from msm_routing_put_audio_mixer
+    - ASoC: codecs: wsa881x: fix return values from kcontrol put
+    - ASoC: codecs: wcd934x: handle channel mappping list correctly
+    - ASoC: codecs: wcd934x: return correct value from mixer put
+    - RDMA/hns: Do not halt commands during reset until later
+    - RDMA/hns: Do not destroy QP resources in the hw resetting phase
+    - hwmon: (dell-smm) Fix warning on /proc/i8k creation error
+    - clk: imx: use module_platform_driver
+    - clk: qcom: clk-alpha-pll: Don't reconfigure running Trion
+    - i40e: Fix failed opcode appearing if handling messages from VF
+    - i40e: Fix pre-set max number of queues for VF
+    - mtd: rawnand: fsmc: Take instruction delay into account
+    - mtd: rawnand: fsmc: Fix timing computation
+    - bpf, sockmap: Re-evaluate proto ops when psock is removed from sockmap
+    - i40e: Fix NULL pointer dereference in i40e_dbg_dump_desc
+    - Revert "PCI: aardvark: Fix support for PCI_ROM_ADDRESS1 on emulated bridge"
+    - drm/amd/display: Fix DPIA outbox timeout after S3/S4/reset
+    - perf tools: Fix SMT detection fast read path
+    - Documentation/locking/locktypes: Update migrate_disable() bits.
+    - dt-bindings: net: Reintroduce PHY no lane swap binding
+    - tools build: Remove needless libpython-version feature check that breaks
+      test-all fast path
+    - net: cdc_ncm: Allow for dwNtbOutMaxSize to be unset or zero
+    - net: altera: set a couple error code in probe()
+    - net: fec: only clear interrupt of handling queue in fec_enet_rx_queue()
+    - net, neigh: clear whole pneigh_entry at alloc time
+    - net/qla3xxx: fix an error code in ql_adapter_up()
+    - selftests/fib_tests: Rework fib_rp_filter_test()
+    - USB: gadget: detect too-big endpoint 0 requests
+    - USB: gadget: zero allocate endpoint 0 buffers
+    - Revert "usb: dwc3: dwc3-qcom: Enable tx-fifo-resize property by default"
+    - usb: core: config: fix validation of wMaxPacketValue entries
+    - usb: core: config: using bit mask instead of individual bits
+    - xhci: avoid race between disable slot command and host runtime suspend
+    - iio: gyro: adxrs290: fix data signedness
+    - iio: trigger: Fix reference counting
+    - iio: trigger: stm32-timer: fix MODULE_ALIAS
+    - iio: stk3310: Don't return error code in interrupt handler
+    - iio: mma8452: Fix trigger reference couting
+    - iio: ltr501: Don't return error code in trigger handler
+    - iio: kxsd9: Don't return error code in trigger handler
+    - iio: itg3200: Call iio_trigger_notify_done() on error
+    - iio: dln2-adc: Fix lockdep complaint
+    - iio: dln2: Check return value of devm_iio_trigger_register()
+    - iio: at91-sama5d2: Fix incorrect sign extension
+    - iio: adc: stm32: fix a current leak by resetting pcsel before disabling vdda
+    - iio: adc: axp20x_adc: fix charging current reporting on AXP22x
+    - iio: ad7768-1: Call iio_trigger_notify_done() on error
+    - iio: accel: kxcjk-1013: Fix possible memory leak in probe and remove
+    - nvmem: eeprom: at25: fix FRAM byte_len
+    - bus: mhi: pci_generic: Fix device recovery failed issue
+    - bus: mhi: core: Add support for forced PM resume
+    - csky: fix typo of fpu config macro
+    - irqchip/aspeed-scu: Replace update_bits with write_bits.
+    - irqchip/armada-370-xp: Fix return value of armada_370_xp_msi_alloc()
+    - irqchip/armada-370-xp: Fix support for Multi-MSI interrupts
+    - aio: Fix incorrect usage of eventfd_signal_allowed()
+    - irqchip/irq-gic-v3-its.c: Force synchronisation when issuing INVALL
+    - irqchip: nvic: Fix offset for Interrupt Priority Offsets
+    - misc: fastrpc: fix improper packet size calculation
+    - clocksource/drivers/dw_apb_timer_of: Fix probe failure
+    - bpf: Add selftests to cover packet access corner cases
+    - Linux 5.15.8
+
+  * Can't read/write SD card after running CPU offline test in 5.11.0 and 5.13.0
+    (LP: #1951784) // Jammy update: v5.15.8 upstream stable release
+    (LP: #1954931)
+    - misc: rtsx: Avoid mangling IRQ during runtime PM
+
+  * Enable Landlock by default (LP: #1953192)
+    - [Config] Enable Landlock by default
+
+  * Add s0i3 RTC wake up for AMD systems (LP: #1950013)
+    - platform/x86: amd-pmc: Export Idlemask values based on the APU
+    - platform/x86: amd-pmc: adjust arguments for `amd_pmc_send_cmd`
+    - platform/x86: amd-pmc: Add special handling for timer based S0i3 wakeup
+
+  * Fix runtime power management on USB controller with XHCI_RESET_ON_RESUME
+    flag (LP: #1954369)
+    - SAUCE: xhci: Remove CONFIG_USB_DEFAULT_PERSIST to prevent xHCI from runtime
+      suspending
+
+  * Fix System hangs on black screen when reboot (LP: #1949321)
+    - drm/i915/hdmi: convert intel_hdmi_to_dev to intel_hdmi_to_i915
+    - drm/i915: Don't request GMBUS to generate irqs when called while irqs are
+      off
+    - drm/i915/hdmi: Turn DP++ TMDS output buffers back on in encoder->shutdown()
+
+  * require CAP_NET_ADMIN to attach N_HCI ldisc (LP: #1949516)
+    - Bluetooth: hci_ldisc: require CAP_NET_ADMIN to attach N_HCI ldisc
+
+  * mt7921e: Failed to start WM firmware (LP: #1954300)
+    - SAUCE: Bluetooth: btusb: Handle download_firmware failure cases
+    - SAUCE: Bluetooth: btusb: Return error code when getting patch status failed
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Add list of built-in modules to the ABI
+    - [Packaging] abi-check: Process modules.builtin
+    - SAUCE: allow to use __wake_up_pollfree() from GPL modules
+    - [Packaging] enforce xz compression for debs
+    - [Config] update config after v5.15.12
+    - [Packaging] temporarily disable signed v4l2loopback
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 04 Jan 2022 11:22:10 +0100
+
+linux (5.15.0-14.14) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-14.14 -proposed tracker (LP: #1954627)
+
+  * Jammy update: v5.15.7 upstream stable release (LP: #1953731)
+    - ALSA: usb-audio: Restrict rates for the shared clocks
+    - ALSA: usb-audio: Rename early_playback_start flag with lowlatency_playback
+    - ALSA: usb-audio: Disable low-latency playback for free-wheel mode
+    - ALSA: usb-audio: Disable low-latency mode for implicit feedback sync
+    - ALSA: usb-audio: Check available frames for the next packet size
+    - ALSA: usb-audio: Add spinlock to stop_urbs()
+    - ALSA: usb-audio: Improved lowlatency playback support
+    - ALSA: usb-audio: Avoid killing in-flight URBs during draining
+    - ALSA: usb-audio: Fix packet size calculation regression
+    - ALSA: usb-audio: Less restriction for low-latency playback mode
+    - ALSA: usb-audio: Switch back to non-latency mode at a later point
+    - ALSA: usb-audio: Don't start stream for capture at prepare
+    - gfs2: release iopen glock early in evict
+    - gfs2: Fix length of holes reported at end-of-file
+    - powerpc/pseries/ddw: Revert "Extend upper limit for huge DMA window for
+      persistent memory"
+    - powerpc/pseries/ddw: Do not try direct mapping with persistent memory and
+      one window
+    - drm/sun4i: fix unmet dependency on RESET_CONTROLLER for PHY_SUN6I_MIPI_DPHY
+    - mac80211: do not access the IV when it was stripped
+    - mac80211: fix throughput LED trigger
+    - x86/hyperv: Move required MSRs check to initial platform probing
+    - net/smc: Transfer remaining wait queue entries during fallback
+    - atlantic: Fix OOB read and write in hw_atl_utils_fw_rpc_wait
+    - net: return correct error code
+    - pinctrl: qcom: fix unmet dependencies on GPIOLIB for GPIOLIB_IRQCHIP
+    - platform/x86: dell-wmi-descriptor: disable by default
+    - platform/x86: thinkpad_acpi: Add support for dual fan control
+    - platform/x86: thinkpad_acpi: Fix WWAN device disabled issue after S3 deep
+    - s390/setup: avoid using memblock_enforce_memory_limit
+    - btrfs: silence lockdep when reading chunk tree during mount
+    - btrfs: check-integrity: fix a warning on write caching disabled disk
+    - thermal: core: Reset previous low and high trip during thermal zone init
+    - scsi: iscsi: Unblock session then wake up error handler
+    - drm/amd/pm: Remove artificial freq level on Navi1x
+    - drm/amd/amdkfd: Fix kernel panic when reset failed and been triggered again
+    - drm/amd/amdgpu: fix potential memleak
+    - ata: ahci: Add Green Sardine vendor ID as board_ahci_mobile
+    - ata: libahci: Adjust behavior when StorageD3Enable _DSD is set
+    - ethernet: hisilicon: hns: hns_dsaf_misc: fix a possible array overflow in
+      hns_dsaf_ge_srst_by_port()
+    - ipv6: check return value of ipv6_skip_exthdr
+    - net: tulip: de4x5: fix the problem that the array 'lp->phy[8]' may be out of
+      bound
+    - net: ethernet: dec: tulip: de4x5: fix possible array overflows in
+      type3_infoblock()
+    - perf sort: Fix the 'weight' sort key behavior
+    - perf sort: Fix the 'ins_lat' sort key behavior
+    - perf sort: Fix the 'p_stage_cyc' sort key behavior
+    - perf inject: Fix ARM SPE handling
+    - perf hist: Fix memory leak of a perf_hpp_fmt
+    - perf report: Fix memory leaks around perf_tip()
+    - tracing: Don't use out-of-sync va_list in event printing
+    - net/smc: Avoid warning of possible recursive locking
+    - ACPI: Add stubs for wakeup handler functions
+    - net/tls: Fix authentication failure in CCM mode
+    - vrf: Reset IPCB/IP6CB when processing outbound pkts in vrf dev xmit
+    - kprobes: Limit max data_size of the kretprobe instances
+    - ALSA: hda/cs8409: Set PMSG_ON earlier inside cs8409 driver
+    - rt2x00: do not mark device gone on EPROTO errors during start
+    - ipmi: Move remove_work to dedicated workqueue
+    - cpufreq: Fix get_cpu_device() failure in add_cpu_dev_symlink()
+    - iwlwifi: mvm: retry init flow if failed
+    - dma-buf: system_heap: Use 'for_each_sgtable_sg' in pages free flow
+    - s390/pci: move pseudo-MMIO to prevent MIO overlap
+    - fget: check that the fd still exists after getting a ref to it
+    - sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl
+    - sata_fsl: fix warning in remove_proc_entry when rmmod sata_fsl
+    - scsi: lpfc: Fix non-recovery of remote ports following an unsolicited LOGO
+    - scsi: ufs: ufs-pci: Add support for Intel ADL
+    - ipv6: fix memory leak in fib6_rule_suppress
+    - drm/amd/display: Allow DSC on supported MST branch devices
+    - drm/i915/dp: Perform 30ms delay after source OUI write
+    - KVM: fix avic_set_running for preemptable kernels
+    - KVM: Disallow user memslot with size that exceeds "unsigned long"
+    - KVM: x86/mmu: Fix TLB flush range when handling disconnected pt
+    - KVM: Ensure local memslot copies operate on up-to-date arch-specific data
+    - KVM: x86: ignore APICv if LAPIC is not enabled
+    - KVM: nVMX: Emulate guest TLB flush on nested VM-Enter with new vpid12
+    - KVM: nVMX: Flush current VPID (L1 vs. L2) for KVM_REQ_TLB_FLUSH_GUEST
+    - KVM: nVMX: Abide to KVM_REQ_TLB_FLUSH_GUEST request on nested vmentry/vmexit
+    - KVM: VMX: prepare sync_pir_to_irr for running with APICv disabled
+    - KVM: x86: Use a stable condition around all VT-d PI paths
+    - KVM: MMU: shadow nested paging does not have PKU
+    - KVM: arm64: Avoid setting the upper 32 bits of TCR_EL2 and CPTR_EL2 to 1
+    - KVM: X86: Use vcpu->arch.walk_mmu for kvm_mmu_invlpg()
+    - KVM: x86: check PIR even for vCPUs with disabled APICv
+    - tracing/histograms: String compares should not care about signed values
+    - net: dsa: mv88e6xxx: Fix application of erratum 4.8 for 88E6393X
+    - net: dsa: mv88e6xxx: Drop unnecessary check in
+      mv88e6393x_serdes_erratum_4_6()
+    - net: dsa: mv88e6xxx: Save power by disabling SerDes trasmitter and receiver
+    - net: dsa: mv88e6xxx: Add fix for erratum 5.2 of 88E6393X family
+    - net: dsa: mv88e6xxx: Fix inband AN for 2500base-x on 88E6393X family
+    - net: dsa: mv88e6xxx: Link in pcs_get_state() if AN is bypassed
+    - wireguard: selftests: increase default dmesg log size
+    - wireguard: allowedips: add missing __rcu annotation to satisfy sparse
+    - wireguard: selftests: actually test for routing loops
+    - wireguard: selftests: rename DEBUG_PI_LIST to DEBUG_PLIST
+    - wireguard: device: reset peer src endpoint when netns exits
+    - wireguard: receive: use ring buffer for incoming handshakes
+    - wireguard: receive: drop handshakes if queue lock is contended
+    - wireguard: ratelimiter: use kvcalloc() instead of kvzalloc()
+    - i2c: stm32f7: flush TX FIFO upon transfer errors
+    - i2c: stm32f7: recover the bus on access timeout
+    - i2c: stm32f7: stop dma transfer in case of NACK
+    - i2c: cbus-gpio: set atomic transfer callback
+    - natsemi: xtensa: fix section mismatch warnings
+    - tcp: fix page frag corruption on page fault
+    - net: qlogic: qlcnic: Fix a NULL pointer dereference in
+      qlcnic_83xx_add_rings()
+    - net: mpls: Fix notifications when deleting a device
+    - siphash: use _unaligned version by default
+    - arm64: ftrace: add missing BTIs
+    - iwlwifi: fix warnings produced by kernel debug options
+    - net/mlx5e: IPsec: Fix Software parser inner l3 type setting in case of
+      encapsulation
+    - net/mlx4_en: Fix an use-after-free bug in mlx4_en_try_alloc_resources()
+    - selftests: net: Correct case name
+    - net: dsa: b53: Add SPI ID table
+    - mt76: mt7915: fix NULL pointer dereference in mt7915_get_phy_mode
+    - ASoC: tegra: Fix wrong value type in ADMAIF
+    - ASoC: tegra: Fix wrong value type in I2S
+    - ASoC: tegra: Fix wrong value type in DMIC
+    - ASoC: tegra: Fix wrong value type in DSPK
+    - ASoC: tegra: Fix kcontrol put callback in ADMAIF
+    - ASoC: tegra: Fix kcontrol put callback in I2S
+    - ASoC: tegra: Fix kcontrol put callback in DMIC
+    - ASoC: tegra: Fix kcontrol put callback in DSPK
+    - ASoC: tegra: Fix kcontrol put callback in AHUB
+    - rxrpc: Fix rxrpc_peer leak in rxrpc_look_up_bundle()
+    - rxrpc: Fix rxrpc_local leak in rxrpc_lookup_peer()
+    - ALSA: intel-dsp-config: add quirk for CML devices based on ES8336 codec
+    - net: stmmac: Avoid DMA_CHAN_CONTROL write if no Split Header support
+    - net: usb: lan78xx: lan78xx_phy_init(): use PHY_POLL instead of "0" if no IRQ
+      is available
+    - net: marvell: mvpp2: Fix the computation of shared CPUs
+    - dpaa2-eth: destroy workqueue at the end of remove function
+    - octeontx2-af: Fix a memleak bug in rvu_mbox_init()
+    - net: annotate data-races on txq->xmit_lock_owner
+    - ipv4: convert fib_num_tclassid_users to atomic_t
+    - net/smc: fix wrong list_del in smc_lgr_cleanup_early
+    - net/rds: correct socket tunable error in rds_tcp_tune()
+    - net/smc: Keep smc_close_final rc during active close
+    - drm/msm/a6xx: Allocate enough space for GMU registers
+    - drm/msm: Do hw_init() before capturing GPU state
+    - drm/vc4: kms: Wait for the commit before increasing our clock rate
+    - drm/vc4: kms: Fix return code check
+    - drm/vc4: kms: Add missing drm_crtc_commit_put
+    - drm/vc4: kms: Clear the HVS FIFO commit pointer once done
+    - drm/vc4: kms: Don't duplicate pending commit
+    - drm/vc4: kms: Fix previous HVS commit wait
+    - atlantic: Increase delay for fw transactions
+    - atlatnic: enable Nbase-t speeds with base-t
+    - atlantic: Fix to display FW bundle version instead of FW mac version.
+    - atlantic: Add missing DIDs and fix 115c.
+    - Remove Half duplex mode speed capabilities.
+    - atlantic: Fix statistics logic for production hardware
+    - atlantic: Remove warn trace message.
+    - KVM: x86/mmu: Skip tlb flush if it has been done in zap_gfn_range()
+    - KVM: x86/mmu: Pass parameter flush as false in
+      kvm_tdp_mmu_zap_collapsible_sptes()
+    - drm/msm/devfreq: Fix OPP refcnt leak
+    - drm/msm: Fix mmap to include VM_IO and VM_DONTDUMP
+    - drm/msm: Fix wait_fence submitqueue leak
+    - drm/msm: Restore error return on invalid fence
+    - ASoC: rk817: Add module alias for rk817-codec
+    - iwlwifi: Fix memory leaks in error handling path
+    - KVM: X86: Fix when shadow_root_level=5 && guest root_level<4
+    - KVM: SEV: initialize regions_list of a mirror VM
+    - net/mlx5e: Fix missing IPsec statistics on uplink representor
+    - net/mlx5: Move MODIFY_RQT command to ignore list in internal error state
+    - net/mlx5: E-switch, Respect BW share of the new group
+    - net/mlx5: E-Switch, fix single FDB creation on BlueField
+    - net/mlx5: E-Switch, Check group pointer before reading bw_share value
+    - KVM: x86/pmu: Fix reserved bits for AMD PerfEvtSeln register
+    - KVM: VMX: Set failure code in prepare_vmcs02()
+    - mctp: Don't let RTM_DELROUTE delete local routes
+    - Revert "drm/i915: Implement Wa_1508744258"
+    - io-wq: don't retry task_work creation failure on fatal conditions
+    - x86/sev: Fix SEV-ES INS/OUTS instructions for word, dword, and qword
+    - x86/entry: Add a fence for kernel entry SWAPGS in paranoid_entry()
+    - x86/entry: Use the correct fence macro after swapgs in kernel CR3
+    - x86/xen: Add xenpv_restore_regs_and_return_to_usermode()
+    - preempt/dynamic: Fix setup_preempt_mode() return value
+    - sched/uclamp: Fix rq->uclamp_max not set on first enqueue
+    - KVM: SEV: Return appropriate error codes if SEV-ES scratch setup fails
+    - KVM: x86/mmu: Rename slot_handle_leaf to slot_handle_level_4k
+    - KVM: x86/mmu: Remove spurious TLB flushes in TDP MMU zap collapsible path
+    - net/mlx5e: Rename lro_timeout to packet_merge_timeout
+    - net/mlx5e: Rename TIR lro functions to TIR packet merge functions
+    - net/mlx5e: Sync TIR params updates against concurrent create/modify
+    - serial: 8250_bcm7271: UART errors after resuming from S2
+    - parisc: Fix KBUILD_IMAGE for self-extracting kernel
+    - parisc: Fix "make install" on newer debian releases
+    - parisc: Mark cr16 CPU clocksource unstable on all SMP machines
+    - vgacon: Propagate console boot parameters before calling `vc_resize'
+    - xhci: Fix commad ring abort, write all 64 bits to CRCR register.
+    - USB: NO_LPM quirk Lenovo Powered USB-C Travel Hub
+    - usb: typec: tcpm: Wait in SNK_DEBOUNCED until disconnect
+    - usb: cdns3: gadget: fix new urb never complete if ep cancel previous
+      requests
+    - usb: cdnsp: Fix a NULL pointer dereference in cdnsp_endpoint_init()
+    - x86/tsc: Add a timer to make sure TSC_adjust is always checked
+    - x86/tsc: Disable clocksource watchdog for TSC on qualified platorms
+    - x86/64/mm: Map all kernel memory into trampoline_pgd
+    - tty: serial: msm_serial: Deactivate RX DMA for polling support
+    - serial: pl011: Add ACPI SBSA UART match id
+    - serial: tegra: Change lower tolerance baud rate limit for tegra20 and
+      tegra30
+    - serial: core: fix transmit-buffer reset and memleak
+    - serial: 8250_pci: Fix ACCES entries in pci_serial_quirks array
+    - serial: 8250_pci: rewrite pericom_do_set_divisor()
+    - serial: 8250: Fix RTS modem control while in rs485 mode
+    - serial: liteuart: Fix NULL pointer dereference in ->remove()
+    - serial: liteuart: fix use-after-free and memleak on unbind
+    - serial: liteuart: fix minor-number leak on probe errors
+    - ipmi: msghandler: Make symbol 'remove_work_wq' static
+    - Linux 5.15.7
+
+  * Updates to ib_peer_memory requested by Nvidia (LP: #1947206)
+    - SAUCE: RDMA/core: Updated ib_peer_memory
+    - SAUCE: RDMA/core: ib_peer_memory fix build errors
+
+  * Jammy update: v5.15.6 upstream stable release (LP: #1953370)
+    - scsi: sd: Fix sd_do_mode_sense() buffer length handling
+    - ACPI: Get acpi_device's parent from the parent field
+    - ACPI: CPPC: Add NULL pointer check to cppc_get_perf()
+    - USB: serial: pl2303: fix GC type detection
+    - USB: serial: option: add Telit LE910S1 0x9200 composition
+    - USB: serial: option: add Fibocom FM101-GL variants
+    - usb: dwc2: gadget: Fix ISOC flow for elapsed frames
+    - usb: dwc2: hcd_queue: Fix use of floating point literal
+    - usb: dwc3: leave default DMA for PCI devices
+    - usb: dwc3: core: Revise GHWPARAMS9 offset
+    - usb: dwc3: gadget: Ignore NoStream after End Transfer
+    - usb: dwc3: gadget: Check for L1/L2/U3 for Start Transfer
+    - usb: dwc3: gadget: Fix null pointer exception
+    - net: usb: Correct PHY handling of smsc95xx
+    - net: nexthop: fix null pointer dereference when IPv6 is not enabled
+    - usb: chipidea: ci_hdrc_imx: fix potential error pointer dereference in probe
+    - usb: typec: fusb302: Fix masking of comparator and bc_lvl interrupts
+    - usb: xhci: tegra: Check padctrl interrupt presence in device tree
+    - usb: hub: Fix usb enumeration issue due to address0 race
+    - usb: hub: Fix locking issues with address0_mutex
+    - binder: fix test regression due to sender_euid change
+    - ALSA: ctxfi: Fix out-of-range access
+    - ALSA: hda/realtek: Add quirk for ASRock NUC Box 1100
+    - ALSA: hda/realtek: Fix LED on HP ProBook 435 G7
+    - media: cec: copy sequence field for the reply
+    - Revert "parisc: Fix backtrace to always include init funtion names"
+    - HID: wacom: Use "Confidence" flag to prevent reporting invalid contacts
+    - staging/fbtft: Fix backlight
+    - staging: greybus: Add missing rwsem around snd_ctl_remove() calls
+    - staging: rtl8192e: Fix use after free in _rtl92e_pci_disconnect()
+    - staging: r8188eu: Use kzalloc() with GFP_ATOMIC in atomic context
+    - staging: r8188eu: Fix breakage introduced when 5G code was removed
+    - staging: r8188eu: use GFP_ATOMIC under spinlock
+    - staging: r8188eu: fix a memory leak in rtw_wx_read32()
+    - fuse: release pipe buf after last use
+    - xen: don't continue xenstore initialization in case of errors
+    - xen: detect uninitialized xenbus in xenbus_init
+    - io_uring: correct link-list traversal locking
+    - io_uring: fail cancellation for EXITING tasks
+    - io_uring: fix link traversal locking
+    - drm/amdgpu: IH process reset count when restart
+    - drm/amdgpu/pm: fix powerplay OD interface
+    - drm/nouveau: recognise GA106
+    - ksmbd: downgrade addition info error msg to debug in smb2_get_info_sec()
+    - ksmbd: contain default data stream even if xattr is empty
+    - ksmbd: fix memleak in get_file_stream_info()
+    - KVM: PPC: Book3S HV: Prevent POWER7/8 TLB flush flushing SLB
+    - tracing/uprobe: Fix uprobe_perf_open probes iteration
+    - tracing: Fix pid filtering when triggers are attached
+    - mmc: sdhci-esdhc-imx: disable CMDQ support
+    - mmc: sdhci: Fix ADMA for PAGE_SIZE >= 64KiB
+    - mdio: aspeed: Fix "Link is Down" issue
+    - arm64: mm: Fix VM_BUG_ON(mm != &init_mm) for trans_pgd
+    - cpufreq: intel_pstate: Fix active mode offline/online EPP handling
+    - powerpc/32: Fix hardlockup on vmap stack overflow
+    - iomap: Fix inline extent handling in iomap_readpage
+    - NFSv42: Fix pagecache invalidation after COPY/CLONE
+    - PCI: aardvark: Deduplicate code in advk_pcie_rd_conf()
+    - PCI: aardvark: Implement re-issuing config requests on CRS response
+    - PCI: aardvark: Simplify initialization of rootcap on virtual bridge
+    - PCI: aardvark: Fix link training
+    - drm/amd/display: Fix OLED brightness control on eDP
+    - proc/vmcore: fix clearing user buffer by properly using clear_user()
+    - ASoC: SOF: Intel: hda: fix hotplug when only codec is suspended
+    - netfilter: ctnetlink: fix filtering with CTA_TUPLE_REPLY
+    - netfilter: ctnetlink: do not erase error code with EINVAL
+    - netfilter: ipvs: Fix reuse connection if RS weight is 0
+    - netfilter: flowtable: fix IPv6 tunnel addr match
+    - media: v4l2-core: fix VIDIOC_DQEVENT handling on non-x86
+    - firmware: arm_scmi: Fix null de-reference on error path
+    - ARM: dts: BCM5301X: Fix I2C controller interrupt
+    - ARM: dts: BCM5301X: Add interrupt properties to GPIO node
+    - ARM: dts: bcm2711: Fix PCIe interrupts
+    - ASoC: qdsp6: q6routing: Conditionally reset FrontEnd Mixer
+    - ASoC: qdsp6: q6asm: fix q6asm_dai_prepare error handling
+    - ASoC: topology: Add missing rwsem around snd_ctl_remove() calls
+    - ASoC: codecs: wcd938x: fix volatile register range
+    - ASoC: codecs: wcd934x: return error code correctly from hw_params
+    - ASoC: codecs: lpass-rx-macro: fix HPHR setting CLSH mask
+    - net: ieee802154: handle iftypes as u32
+    - firmware: arm_scmi: Fix base agent discover response
+    - firmware: arm_scmi: pm: Propagate return value to caller
+    - ASoC: stm32: i2s: fix 32 bits channel length without mclk
+    - NFSv42: Don't fail clone() unless the OP_CLONE operation failed
+    - ARM: socfpga: Fix crash with CONFIG_FORTIRY_SOURCE
+    - drm/nouveau/acr: fix a couple NULL vs IS_ERR() checks
+    - scsi: qla2xxx: edif: Fix off by one bug in qla_edif_app_getfcinfo()
+    - scsi: mpt3sas: Fix kernel panic during drive powercycle test
+    - scsi: mpt3sas: Fix system going into read-only mode
+    - scsi: mpt3sas: Fix incorrect system timestamp
+    - drm/vc4: fix error code in vc4_create_object()
+    - drm/aspeed: Fix vga_pw sysfs output
+    - net: marvell: prestera: fix brige port operation
+    - net: marvell: prestera: fix double free issue on err path
+    - HID: input: Fix parsing of HID_CP_CONSUMER_CONTROL fields
+    - HID: input: set usage type to key on keycode remap
+    - HID: magicmouse: prevent division by 0 on scroll
+    - iavf: Prevent changing static ITR values if adaptive moderation is on
+    - iavf: Fix refreshing iavf adapter stats on ethtool request
+    - iavf: Fix VLAN feature flags after VFR
+    - x86/pvh: add prototype for xen_pvh_init()
+    - xen/pvh: add missing prototype to header
+    - ALSA: intel-dsp-config: add quirk for JSL devices based on ES8336 codec
+    - mptcp: fix delack timer
+    - mptcp: use delegate action to schedule 3rd ack retrans
+    - af_unix: fix regression in read after shutdown
+    - firmware: smccc: Fix check for ARCH_SOC_ID not implemented
+    - ipv6: fix typos in __ip6_finish_output()
+    - nfp: checking parameter process for rx-usecs/tx-usecs is invalid
+    - net: stmmac: retain PTP clock time during SIOCSHWTSTAMP ioctls
+    - net: ipv6: add fib6_nh_release_dsts stub
+    - net: nexthop: release IPv6 per-cpu dsts when replacing a nexthop group
+    - ice: fix vsi->txq_map sizing
+    - ice: avoid bpf_prog refcount underflow
+    - scsi: core: sysfs: Fix setting device state to SDEV_RUNNING
+    - scsi: scsi_debug: Zero clear zones at reset write pointer
+    - erofs: fix deadlock when shrink erofs slab
+    - i2c: virtio: disable timeout handling
+    - net/smc: Ensure the active closing peer first closes clcsock
+    - mlxsw: spectrum: Protect driver from buggy firmware
+    - net: ipa: directly disable ipa-setup-ready interrupt
+    - net: ipa: separate disabling setup from modem stop
+    - net: ipa: kill ipa_cmd_pipeline_clear()
+    - net: marvell: mvpp2: increase MTU limit when XDP enabled
+    - cpufreq: intel_pstate: Add Ice Lake server to out-of-band IDs
+    - nvmet-tcp: fix incomplete data digest send
+    - drm/hyperv: Fix device removal on Gen1 VMs
+    - arm64: uaccess: avoid blocking within critical sections
+    - net/ncsi : Add payload to be 32-bit aligned to fix dropped packets
+    - PM: hibernate: use correct mode for swsusp_close()
+    - drm/amd/display: Fix DPIA outbox timeout after GPU reset
+    - drm/amd/display: Set plane update flags for all planes in reset
+    - tcp_cubic: fix spurious Hystart ACK train detections for not-cwnd-limited
+      flows
+    - lan743x: fix deadlock in lan743x_phy_link_status_change()
+    - net: phylink: Force link down and retrigger resolve on interface change
+    - net: phylink: Force retrigger in case of latched link-fail indicator
+    - net/smc: Fix NULL pointer dereferencing in smc_vlan_by_tcpsk()
+    - net/smc: Fix loop in smc_listen
+    - nvmet: use IOCB_NOWAIT only if the filesystem supports it
+    - igb: fix netpoll exit with traffic
+    - MIPS: loongson64: fix FTLB configuration
+    - MIPS: use 3-level pgtable for 64KB page size on MIPS_VA_BITS_48
+    - tls: splice_read: fix record type check
+    - tls: splice_read: fix accessing pre-processed records
+    - tls: fix replacing proto_ops
+    - net: stmmac: Disable Tx queues when reconfiguring the interface
+    - net/sched: sch_ets: don't peek at classes beyond 'nbands'
+    - ethtool: ioctl: fix potential NULL deref in ethtool_set_coalesce()
+    - net: vlan: fix underflow for the real_dev refcnt
+    - net/smc: Don't call clcsock shutdown twice when smc shutdown
+    - net: hns3: fix VF RSS failed problem after PF enable multi-TCs
+    - net: hns3: fix incorrect components info of ethtool --reset command
+    - net: mscc: ocelot: don't downgrade timestamping RX filters in SIOCSHWTSTAMP
+    - net: mscc: ocelot: correctly report the timestamping RX filters in ethtool
+    - locking/rwsem: Make handoff bit handling more consistent
+    - perf: Ignore sigtrap for tracepoints destined for other tasks
+    - sched/scs: Reset task stack state in bringup_cpu()
+    - iommu/rockchip: Fix PAGE_DESC_HI_MASKs for RK3568
+    - iommu/vt-d: Fix unmap_pages support
+    - f2fs: quota: fix potential deadlock
+    - f2fs: set SBI_NEED_FSCK flag when inconsistent node block found
+    - riscv: dts: microchip: fix board compatible
+    - riscv: dts: microchip: drop duplicated MMC/SDHC node
+    - cifs: nosharesock should not share socket with future sessions
+    - ceph: properly handle statfs on multifs setups
+    - iommu/amd: Clarify AMD IOMMUv2 initialization messages
+    - vdpa_sim: avoid putting an uninitialized iova_domain
+    - vhost/vsock: fix incorrect used length reported to the guest
+    - ksmbd: Fix an error handling path in 'smb2_sess_setup()'
+    - tracing: Check pid filtering when creating events
+    - cifs: nosharesock should be set on new server
+    - io_uring: fix soft lockup when call __io_remove_buffers
+    - firmware: arm_scmi: Fix type error assignment in voltage protocol
+    - firmware: arm_scmi: Fix type error in sensor protocol
+    - docs: accounting: update delay-accounting.rst reference
+    - blk-mq: cancel blk-mq dispatch work in both blk_cleanup_queue and
+      disk_release()
+    - block: avoid to quiesce queue in elevator_init_mq
+    - drm/amdgpu/gfx10: add wraparound gpu counter check for APUs as well
+    - drm/amdgpu/gfx9: switch to golden tsc registers for renoir+
+    - Linux 5.15.6
+
+  * Fix bogus HDMI audio interface  (LP: #1953208)
+    - ALSA: hda/hdmi: Consider ELD is invalid when no SAD is present
+
+  * Miscellaneous Ubuntu changes
+    - [Config] re-enabled UBSAN without TRAP
+    - SAUCE: ipv6: fix NULL pointer dereference in ip6_output()
+    - SAUCE: RDMA/core: Introduce peer memory interface
+    - [Config] toolchain version update
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] Temporarily disable signing for ppc64el and s390x"
+    - Revert "UBUNTU: SAUCE: vt -- maintain bootloader screen mode and content
+      until vt switch"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 13 Dec 2021 12:13:17 +0100
+
+linux (5.15.0-13.13) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-13.13 -proposed tracker (LP: #1952583)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync update-dkms-versions helper
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Jammy update: v5.15.5 upstream stable release (LP: #1952579)
+    - arm64: zynqmp: Do not duplicate flash partition label property
+    - arm64: zynqmp: Fix serial compatible string
+    - clk: sunxi-ng: Unregister clocks/resets when unbinding
+    - ARM: dts: sunxi: Fix OPPs node name
+    - arm64: dts: allwinner: h5: Fix GPU thermal zone node name
+    - arm64: dts: allwinner: a100: Fix thermal zone node name
+    - staging: wfx: ensure IRQ is ready before enabling it
+    - ARM: dts: BCM5301X: Fix nodes names
+    - ARM: dts: BCM5301X: Fix MDIO mux binding
+    - ARM: dts: NSP: Fix mpcore, mmc node names
+    - arm64: dts: broadcom: bcm4908: Move reboot syscon out of bus
+    - scsi: pm80xx: Fix memory leak during rmmod
+    - scsi: lpfc: Fix list_add() corruption in lpfc_drain_txq()
+    - ASoC: mediatek: mt8195: Add missing of_node_put()
+    - arm64: dts: rockchip: Disable CDN DP on Pinebook Pro
+    - arm64: dts: hisilicon: fix arm,sp805 compatible string
+    - RDMA/bnxt_re: Check if the vlan is valid before reporting
+    - bus: ti-sysc: Add quirk handling for reinit on context lost
+    - bus: ti-sysc: Use context lost quirk for otg
+    - usb: musb: tusb6010: check return value after calling
+      platform_get_resource()
+    - usb: typec: tipd: Remove WARN_ON in tps6598x_block_read
+    - ARM: dts: ux500: Skomer regulator fixes
+    - staging: rtl8723bs: remove possible deadlock when disconnect (v2)
+    - staging: rtl8723bs: remove a second possible deadlock
+    - staging: rtl8723bs: remove a third possible deadlock
+    - ARM: BCM53016: Specify switch ports for Meraki MR32
+    - arm64: dts: qcom: msm8998: Fix CPU/L2 idle state latency and residency
+    - arm64: dts: qcom: ipq6018: Fix qcom,controlled-remotely property
+    - arm64: dts: qcom: ipq8074: Fix qcom,controlled-remotely property
+    - arm64: dts: qcom: sdm845: Fix qcom,controlled-remotely property
+    - arm64: dts: freescale: fix arm,sp805 compatible string
+    - arm64: dts: ls1012a: Add serial alias for ls1012a-rdb
+    - RDMA/rxe: Separate HW and SW l/rkeys
+    - ASoC: SOF: Intel: hda-dai: fix potential locking issue
+    - scsi: core: Fix scsi_mode_sense() buffer length handling
+    - ALSA: usb-audio: disable implicit feedback sync for Behringer UFX1204 and
+      UFX1604
+    - clk: imx: imx6ul: Move csi_sel mux to correct base register
+    - ASoC: es8316: Use IRQF_NO_AUTOEN when requesting the IRQ
+    - ASoC: rt5651: Use IRQF_NO_AUTOEN when requesting the IRQ
+    - ASoC: nau8824: Add DMI quirk mechanism for active-high jack-detect
+    - scsi: advansys: Fix kernel pointer leak
+    - scsi: smartpqi: Add controller handshake during kdump
+    - arm64: dts: imx8mm-kontron: Fix reset delays for ethernet PHY
+    - ALSA: intel-dsp-config: add quirk for APL/GLK/TGL devices based on ES8336
+      codec
+    - ASoC: Intel: soc-acpi: add missing quirk for TGL SDCA single amp
+    - ASoC: Intel: sof_sdw: add missing quirk for Dell SKU 0A45
+    - firmware_loader: fix pre-allocated buf built-in firmware use
+    - HID: multitouch: disable sticky fingers for UPERFECT Y
+    - ALSA: usb-audio: Add support for the Pioneer DJM 750MK2 Mixer/Soundcard
+    - ARM: dts: omap: fix gpmc,mux-add-data type
+    - usb: host: ohci-tmio: check return value after calling
+      platform_get_resource()
+    - ASoC: rt5682: fix a little pop while playback
+    - ARM: dts: ls1021a: move thermal-zones node out of soc/
+    - ARM: dts: ls1021a-tsn: use generic "jedec,spi-nor" compatible for flash
+    - ALSA: ISA: not for M68K
+    - iommu/vt-d: Do not falsely log intel_iommu is unsupported kernel option
+    - tty: tty_buffer: Fix the softlockup issue in flush_to_ldisc
+    - MIPS: sni: Fix the build
+    - scsi: scsi_debug: Fix out-of-bound read in resp_readcap16()
+    - scsi: scsi_debug: Fix out-of-bound read in resp_report_tgtpgs()
+    - scsi: target: Fix ordered tag handling
+    - scsi: target: Fix alua_tg_pt_gps_count tracking
+    - iio: imu: st_lsm6dsx: Avoid potential array overflow in st_lsm6dsx_set_odr()
+    - RDMA/core: Use kvzalloc when allocating the struct ib_port
+    - scsi: lpfc: Fix use-after-free in lpfc_unreg_rpi() routine
+    - scsi: lpfc: Fix link down processing to address NULL pointer dereference
+    - scsi: lpfc: Allow fabric node recovery if recovery is in progress before
+      devloss
+    - memory: tegra20-emc: Add runtime dependency on devfreq governor module
+    - powerpc/5200: dts: fix memory node unit name
+    - ARM: dts: qcom: fix memory and mdio nodes naming for RB3011
+    - arm64: dts: qcom: Fix node name of rpm-msg-ram device nodes
+    - ALSA: gus: fix null pointer dereference on pointer block
+    - ALSA: usb-audio: fix null pointer dereference on pointer cs_desc
+    - clk: at91: sama7g5: remove prescaler part of master clock
+    - iommu/dart: Initialize DART_STREAMS_ENABLE
+    - powerpc/dcr: Use cmplwi instead of 3-argument cmpli
+    - powerpc/8xx: Fix Oops with STRICT_KERNEL_RWX without DEBUG_RODATA_TEST
+    - sh: check return code of request_irq
+    - maple: fix wrong return value of maple_bus_init().
+    - f2fs: fix up f2fs_lookup tracepoints
+    - f2fs: fix to use WHINT_MODE
+    - f2fs: fix wrong condition to trigger background checkpoint correctly
+    - sh: fix kconfig unmet dependency warning for FRAME_POINTER
+    - sh: math-emu: drop unused functions
+    - sh: define __BIG_ENDIAN for math-emu
+    - f2fs: compress: disallow disabling compress on non-empty compressed file
+    - f2fs: fix incorrect return value in f2fs_sanity_check_ckpt()
+    - clk: ingenic: Fix bugs with divided dividers
+    - clk/ast2600: Fix soc revision for AHB
+    - clk: qcom: gcc-msm8996: Drop (again) gcc_aggre1_pnoc_ahb_clk
+    - KVM: arm64: Fix host stage-2 finalization
+    - mips: BCM63XX: ensure that CPU_SUPPORTS_32BIT_KERNEL is set
+    - MIPS: boot/compressed/: add __bswapdi2() to target for ZSTD decompression
+    - sched/core: Mitigate race cpus_share_cache()/update_top_cache_domain()
+    - sched/fair: Prevent dead task groups from regaining cfs_rq's
+    - perf/x86/vlbr: Add c->flags to vlbr event constraints
+    - blkcg: Remove extra blkcg_bio_issue_init
+    - tracing/histogram: Do not copy the fixed-size char array field over the
+      field size
+    - perf bpf: Avoid memory leak from perf_env__insert_btf()
+    - perf bench futex: Fix memory leak of perf_cpu_map__new()
+    - perf tests: Remove bash construct from record+zstd_comp_decomp.sh
+    - drm/nouveau: hdmigv100.c: fix corrupted HDMI Vendor InfoFrame
+    - bpf: Fix inner map state pruning regression.
+    - samples/bpf: Fix summary per-sec stats in xdp_sample_user
+    - samples/bpf: Fix incorrect use of strlen in xdp_redirect_cpu
+    - selftests: net: switch to socat in the GSO GRE test
+    - net/ipa: ipa_resource: Fix wrong for loop range
+    - tcp: Fix uninitialized access in skb frags array for Rx 0cp.
+    - tracing: Add length protection to histogram string copies
+    - nl80211: fix radio statistics in survey dump
+    - mac80211: fix monitor_sdata RCU/locking assertions
+    - net: ipa: HOLB register sometimes must be written twice
+    - net: ipa: disable HOLB drop when updating timer
+    - selftests: gpio: fix gpio compiling error
+    - net: bnx2x: fix variable dereferenced before check
+    - bnxt_en: reject indirect blk offload when hw-tc-offload is off
+    - tipc: only accept encrypted MSG_CRYPTO msgs
+    - sock: fix /proc/net/sockstat underflow in sk_clone_lock()
+    - net/smc: Make sure the link_id is unique
+    - NFSD: Fix exposure in nfsd4_decode_bitmap()
+    - iavf: Fix return of set the new channel count
+    - iavf: check for null in iavf_fix_features
+    - iavf: free q_vectors before queues in iavf_disable_vf
+    - iavf: don't clear a lock we don't hold
+    - iavf: Fix failure to exit out from last all-multicast mode
+    - iavf: prevent accidental free of filter structure
+    - iavf: validate pointers
+    - iavf: Fix for the false positive ASQ/ARQ errors while issuing VF reset
+    - iavf: Fix for setting queues to 0
+    - iavf: Restore VLAN filters after link down
+    - bpf: Fix toctou on read-only map's constant scalar tracking
+    - MIPS: generic/yamon-dt: fix uninitialized variable error
+    - mips: bcm63xx: add support for clk_get_parent()
+    - mips: lantiq: add support for clk_get_parent()
+    - gpio: rockchip: needs GENERIC_IRQ_CHIP to fix build errors
+    - platform/x86: hp_accel: Fix an error handling path in 'lis3lv02d_probe()'
+    - platform/x86: think-lmi: Abort probe on analyze failure
+    - udp: Validate checksum in udp_read_sock()
+    - btrfs: make 1-bit bit-fields of scrub_page unsigned int
+    - RDMA/core: Set send and receive CQ before forwarding to the driver
+    - net/mlx5e: kTLS, Fix crash in RX resync flow
+    - net/mlx5e: Wait for concurrent flow deletion during neigh/fib events
+    - net/mlx5: E-Switch, Fix resetting of encap mode when entering switchdev
+    - net/mlx5e: nullify cq->dbg pointer in mlx5_debug_cq_remove()
+    - net/mlx5: Update error handler for UCTX and UMEM
+    - net/mlx5: E-Switch, rebuild lag only when needed
+    - net/mlx5e: CT, Fix multiple allocations and memleak of mod acts
+    - net/mlx5: Lag, update tracker when state change event received
+    - net/mlx5: E-Switch, return error if encap isn't supported
+    - scsi: ufs: core: Improve SCSI abort handling
+    - scsi: core: sysfs: Fix hang when device state is set via sysfs
+    - scsi: ufs: core: Fix task management completion timeout race
+    - scsi: ufs: core: Fix another task management completion race
+    - net: mvmdio: fix compilation warning
+    - net: sched: act_mirred: drop dst for the direction from egress to ingress
+    - net: dpaa2-eth: fix use-after-free in dpaa2_eth_remove
+    - net: virtio_net_hdr_to_skb: count transport header in UFO
+    - i40e: Fix correct max_pkt_size on VF RX queue
+    - i40e: Fix NULL ptr dereference on VSI filter sync
+    - i40e: Fix changing previously set num_queue_pairs for PFs
+    - i40e: Fix ping is lost after configuring ADq on VF
+    - RDMA/mlx4: Do not fail the registration on port stats
+    - i40e: Fix warning message and call stack during rmmod i40e driver
+    - i40e: Fix creation of first queue by omitting it if is not power of two
+    - i40e: Fix display error code in dmesg
+    - NFC: reorganize the functions in nci_request
+    - NFC: reorder the logic in nfc_{un,}register_device
+    - NFC: add NCI_UNREG flag to eliminate the race
+    - e100: fix device suspend/resume
+    - ptp: ocp: Fix a couple NULL vs IS_ERR() checks
+    - tools build: Fix removal of feature-sync-compare-and-swap feature detection
+    - riscv: fix building external modules
+    - KVM: PPC: Book3S HV: Use GLOBAL_TOC for kvmppc_h_set_dabr/xdabr()
+    - powerpc: clean vdso32 and vdso64 directories
+    - powerpc/pseries: rename numa_dist_table to form2_distances
+    - powerpc/pseries: Fix numa FORM2 parsing fallback code
+    - pinctrl: qcom: sdm845: Enable dual edge errata
+    - pinctrl: qcom: sm8350: Correct UFS and SDC offsets
+    - perf/x86/intel/uncore: Fix filter_tid mask for CHA events on Skylake Server
+    - perf/x86/intel/uncore: Fix IIO event constraints for Skylake Server
+    - perf/x86/intel/uncore: Fix IIO event constraints for Snowridge
+    - s390/kexec: fix return code handling
+    - blk-cgroup: fix missing put device in error path from blkg_conf_pref()
+    - dmaengine: remove debugfs #ifdef
+    - tun: fix bonding active backup with arp monitoring
+    - Revert "mark pstore-blk as broken"
+    - pstore/blk: Use "%lu" to format unsigned long
+    - hexagon: export raw I/O routines for modules
+    - hexagon: clean up timer-regs.h
+    - tipc: check for null after calling kmemdup
+    - ipc: WARN if trying to remove ipc object which is absent
+    - shm: extend forced shm destroy to support objects from several IPC nses
+    - mm: kmemleak: slob: respect SLAB_NOLEAKTRACE flag
+    - hugetlb, userfaultfd: fix reservation restore on userfaultfd error
+    - kmap_local: don't assume kmap PTEs are linear arrays in memory
+    - mm/damon/dbgfs: use '__GFP_NOWARN' for user-specified size buffer allocation
+    - mm/damon/dbgfs: fix missed use of damon_dbgfs_lock
+    - x86/boot: Pull up cmdline preparation and early param parsing
+    - x86/sgx: Fix free page accounting
+    - x86/hyperv: Fix NULL deref in set_hv_tscchange_cb() if Hyper-V setup fails
+    - KVM: x86: Assume a 64-bit hypercall for guests with protected state
+    - KVM: x86: Fix uninitialized eoi_exit_bitmap usage in vcpu_load_eoi_exitmap()
+    - KVM: x86/mmu: include EFER.LMA in extended mmu role
+    - KVM: x86/xen: Fix get_attr of KVM_XEN_ATTR_TYPE_SHARED_INFO
+    - powerpc/signal32: Fix sigset_t copy
+    - powerpc/xive: Change IRQ domain to a tree domain
+    - powerpc/8xx: Fix pinned TLBs with CONFIG_STRICT_KERNEL_RWX
+    - Revert "drm/i915/tgl/dsi: Gate the ddi clocks after pll mapping"
+    - Revert "parisc: Reduce sigreturn trampoline to 3 instructions"
+    - ata: libata: improve ata_read_log_page() error message
+    - ata: libata: add missing ata_identify_page_supported() calls
+    - scsi: qla2xxx: Fix mailbox direction flags in qla2xxx_get_adapter_id()
+    - pinctrl: ralink: include 'ralink_regs.h' in 'pinctrl-mt7620.c'
+    - s390/setup: avoid reserving memory above identity mapping
+    - s390/boot: simplify and fix kernel memory layout setup
+    - s390/vdso: filter out -mstack-guard and -mstack-size
+    - s390/kexec: fix memory leak of ipl report buffer
+    - s390/dump: fix copying to user-space of swapped kdump oldmem
+    - block: Check ADMIN before NICE for IOPRIO_CLASS_RT
+    - fbdev: Prevent probing generic drivers if a FB is already registered
+    - KVM: SEV: Disallow COPY_ENC_CONTEXT_FROM if target has created vCPUs
+    - KVM: nVMX: don't use vcpu->arch.efer when checking host state on nested
+      state load
+    - drm/cma-helper: Release non-coherent memory with dma_free_noncoherent()
+    - printk: restore flushing of NMI buffers on remote CPUs after NMI backtraces
+    - udf: Fix crash after seekdir
+    - spi: fix use-after-free of the add_lock mutex
+    - net: stmmac: socfpga: add runtime suspend/resume callback for stratix10
+      platform
+    - Drivers: hv: balloon: Use VMBUS_RING_SIZE() wrapper for dm_ring_size
+    - btrfs: fix memory ordering between normal and ordered work functions
+    - fs: handle circular mappings correctly
+    - net: stmmac: Fix signed/unsigned wreckage
+    - parisc/sticon: fix reverse colors
+    - cfg80211: call cfg80211_stop_ap when switch from P2P_GO type
+    - mac80211: fix radiotap header generation
+    - mac80211: drop check for DONT_REORDER in __ieee80211_select_queue
+    - drm/amd/display: Update swizzle mode enums
+    - drm/amd/display: Limit max DSC target bpp for specific monitors
+    - drm/i915/guc: Fix outstanding G2H accounting
+    - drm/i915/guc: Don't enable scheduling on a banned context, guc_id invalid,
+      not registered
+    - drm/i915/guc: Workaround reset G2H is received after schedule done G2H
+    - drm/i915/guc: Don't drop ce->guc_active.lock when unwinding context
+    - drm/i915/guc: Unwind context requests in reverse order
+    - drm/udl: fix control-message timeout
+    - drm/prime: Fix use after free in mmap with drm_gem_ttm_mmap
+    - drm/nouveau: Add a dedicated mutex for the clients list
+    - drm/nouveau: use drm_dev_unplug() during device removal
+    - drm/nouveau: clean up all clients on device removal
+    - drm/i915/dp: Ensure sink rate values are always valid
+    - drm/i915/dp: Ensure max link params are always valid
+    - drm/i915: Fix type1 DVI DP dual mode adapter heuristic for modern platforms
+    - drm/amdgpu: fix set scaling mode Full/Full aspect/Center not works on vga
+      and dvi connectors
+    - drm/amd/pm: avoid duplicate powergate/ungate setting
+    - signal: Implement force_fatal_sig
+    - exit/syscall_user_dispatch: Send ordinary signals on failure
+    - signal/powerpc: On swapcontext failure force SIGSEGV
+    - signal/s390: Use force_sigsegv in default_trap_handler
+    - signal/sparc32: Exit with a fatal signal when try_to_clear_window_buffer
+      fails
+    - signal/sparc32: In setup_rt_frame and setup_fram use force_fatal_sig
+    - signal/vm86_32: Properly send SIGSEGV when the vm86 state cannot be saved.
+    - signal/x86: In emulate_vsyscall force a signal instead of calling do_exit
+    - signal: Replace force_sigsegv(SIGSEGV) with force_fatal_sig(SIGSEGV)
+    - signal: Don't always set SA_IMMUTABLE for forced signals
+    - signal: Replace force_fatal_sig with force_exit_sig when in doubt
+    - hugetlbfs: flush TLBs correctly after huge_pmd_unshare
+    - RDMA/netlink: Add __maybe_unused to static inline in C file
+    - bpf: Forbid bpf_ktime_get_coarse_ns and bpf_timer_* in tracing progs
+    - selinux: fix NULL-pointer dereference when hashtab allocation fails
+    - ASoC: DAPM: Cover regression by kctl change notification fix
+    - ASoC: rsnd: fixup DMAEngine API
+    - usb: max-3421: Use driver data instead of maintaining a list of bound
+      devices
+    - ice: Fix VF true promiscuous mode
+    - ice: Delete always true check of PF pointer
+    - fs: export an inode_update_time helper
+    - btrfs: update device path inode time instead of bd_inode
+    - net: add and use skb_unclone_keeptruesize() helper
+    - x86/Kconfig: Fix an unused variable error in dell-smm-hwmon
+    - ALSA: hda: hdac_ext_stream: fix potential locking issues
+    - ALSA: hda: hdac_stream: fix potential locking issue in
+      snd_hdac_stream_assign()
+    - Linux 5.15.5
+
+  * Fix non-working e1000e device after resume (LP: #1951861)
+    - SAUCE: Revert "e1000e: Additional PHY power saving in S0ix"
+    - SAUCE: Revert "e1000e: Add polling mechanism to indicate CSME DPG exit"
+    - SAUCE: Revert "e1000e: Add handshake with the CSME to support S0ix"
+
+  * [SRU][I/OEM-5.13/OEM-5.14] Add MAC passthrough support for more Lenovo docks
+    (LP: #1951767)
+    - net: usb: r8152: Add MAC passthrough support for more Lenovo Docks
+
+  * [amdgpu] USB4 support for DP tunneling (LP: #1951868)
+    - drm/amd/display: Support for DMUB HPD interrupt handling
+    - drm/amd/display: Update link encoder object creation.
+    - drm/amd/display: USB4 DPIA enumeration and AUX Tunneling
+    - drm/amd/display: Support for DMUB HPD and HPD RX interrupt handling
+    - drm/amd/display: Set DPIA link endpoint type
+    - drm/amd/display: Stub out DPIA link training call
+    - drm/amd/display: Add stub to get DPIA tunneling device data
+    - drm/amd/display: Skip DPCD read for DPTX-to-DPIA hop
+    - drm/amd/display: Train DPIA links with fallback
+    - drm/amd/display: Implement DPIA training loop
+    - drm/amd/display: Implement DPIA link configuration
+    - drm/amd/display: Implement DPIA clock recovery phase
+    - drm/amd/display: Implement DPIA equalisation phase
+    - drm/amd/display: Implement end of training for hop in DPIA display path
+    - drm/amd/display: Support for SET_CONFIG processing with DMUB
+    - drm/amd/display: isolate link training setting override to its own function
+    - drm/amd/display: Read USB4 DP tunneling data from DPCD.
+    - drm/amd/display: Add dpia debug options
+    - drm/amd/display: Support for SET_CONFIG processing with DMUB
+    - drm/amd/display: Add DPCD writes at key points
+    - drm/amd/display: Fix DIG_HPD_SELECT for USB4 display endpoints.
+    - drm/amd/display: Add helper for blanking all dp displays
+    - drm/amd/display: Fix link training fallback logic
+    - drm/amd/display: Add debug flags for USB4 DP link training.
+    - drm/amd/display: Fix dynamic link encoder access.
+    - drm/amd/display: Fix concurrent dynamic encoder assignment
+    - drm/amd/display: Fix dynamic encoder reassignment
+    - drm/amd/display: Fix for access for ddc pin and aux engine.
+    - drm/amd/display: Deadlock/HPD Status/Crash Bug Fix
+    - drm/amd/display: Fix USB4 Aux via DMUB terminate unexpectedly
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Rewrite debian/scripts/module-check in Python
+    - [Config] update config and annotations after applying v5.15.5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 29 Nov 2021 09:25:37 +0100
+
+linux (5.15.0-12.12) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-12.12 -proposed tracker (LP: #1951810)
+
+  * Jammy update: v5.15.4 upstream stable release (LP: #1951820)
+    - string: uninline memcpy_and_pad
+    - Revert "drm: fb_helper: improve CONFIG_FB dependency"
+    - Revert "drm: fb_helper: fix CONFIG_FB dependency"
+    - KVM: Fix steal time asm constraints
+    - btrfs: introduce btrfs_is_data_reloc_root
+    - btrfs: zoned: add a dedicated data relocation block group
+    - btrfs: zoned: only allow one process to add pages to a relocation inode
+    - btrfs: zoned: use regular writes for relocation
+    - btrfs: check for relocation inodes on zoned btrfs in should_nocow
+    - btrfs: zoned: allow preallocation for relocation inodes
+    - fortify: Explicitly disable Clang support
+    - block: Add a helper to validate the block size
+    - loop: Use blk_validate_block_size() to validate block size
+    - Bluetooth: btusb: Add support for TP-Link UB500 Adapter
+    - parisc/entry: fix trace test in syscall exit path
+    - PCI/MSI: Deal with devices lying about their MSI mask capability
+    - PCI: Add MSI masking quirk for Nvidia ION AHCI
+    - perf/core: Avoid put_page() when GUP fails
+    - thermal: Fix NULL pointer dereferences in of_thermal_ functions
+    - Revert "ACPI: scan: Release PM resources blocked by unused objects"
+    - Linux 5.15.4
+
+  * Jammy update: v5.15.3 upstream stable release (LP: #1951822)
+    - xhci: Fix USB 3.1 enumeration issues by increasing roothub power-on-good
+      delay
+    - usb: xhci: Enable runtime-pm by default on AMD Yellow Carp platform
+    - Input: iforce - fix control-message timeout
+    - Input: elantench - fix misreporting trackpoint coordinates
+    - Input: i8042 - Add quirk for Fujitsu Lifebook T725
+    - libata: fix read log timeout value
+    - ocfs2: fix data corruption on truncate
+    - scsi: scsi_ioctl: Validate command size
+    - scsi: core: Avoid leaving shost->last_reset with stale value if EH does not
+      run
+    - scsi: core: Remove command size deduction from scsi_setup_scsi_cmnd()
+    - scsi: lpfc: Don't release final kref on Fport node while ABTS outstanding
+    - scsi: lpfc: Fix FCP I/O flush functionality for TMF routines
+    - scsi: qla2xxx: Fix crash in NVMe abort path
+    - scsi: qla2xxx: Fix kernel crash when accessing port_speed sysfs file
+    - scsi: qla2xxx: Fix use after free in eh_abort path
+    - ce/gf100: fix incorrect CE0 address calculation on some GPUs
+    - char: xillybus: fix msg_ep UAF in xillyusb_probe()
+    - mmc: mtk-sd: Add wait dma stop done flow
+    - mmc: dw_mmc: Dont wait for DRTO on Write RSP error
+    - exfat: fix incorrect loading of i_blocks for large files
+    - io-wq: remove worker to owner tw dependency
+    - parisc: Fix set_fixmap() on PA1.x CPUs
+    - parisc: Fix ptrace check on syscall return
+    - tpm: Check for integer overflow in tpm2_map_response_body()
+    - firmware/psci: fix application of sizeof to pointer
+    - crypto: s5p-sss - Add error handling in s5p_aes_probe()
+    - media: rkvdec: Do not override sizeimage for output format
+    - media: ite-cir: IR receiver stop working after receive overflow
+    - media: rkvdec: Support dynamic resolution changes
+    - media: ir-kbd-i2c: improve responsiveness of hauppauge zilog receivers
+    - media: v4l2-ioctl: Fix check_ext_ctrls
+    - ALSA: hda/realtek: Fix mic mute LED for the HP Spectre x360 14
+    - ALSA: hda/realtek: Add a quirk for HP OMEN 15 mute LED
+    - ALSA: hda/realtek: Add quirk for Clevo PC70HS
+    - ALSA: hda/realtek: Headset fixup for Clevo NH77HJQ
+    - ALSA: hda/realtek: Add a quirk for Acer Spin SP513-54N
+    - ALSA: hda/realtek: Add quirk for ASUS UX550VE
+    - ALSA: hda/realtek: Add quirk for HP EliteBook 840 G7 mute LED
+    - ALSA: ua101: fix division by zero at probe
+    - ALSA: 6fire: fix control and bulk message timeouts
+    - ALSA: line6: fix control and interrupt message timeouts
+    - ALSA: mixer: oss: Fix racy access to slots
+    - ALSA: mixer: fix deadlock in snd_mixer_oss_set_volume
+    - ALSA: usb-audio: Line6 HX-Stomp XL USB_ID for 48k-fixed quirk
+    - ALSA: usb-audio: Add registration quirk for JBL Quantum 400
+    - ALSA: hda: Free card instance properly at probe errors
+    - ALSA: synth: missing check for possible NULL after the call to kstrdup
+    - ALSA: pci: rme: Fix unaligned buffer addresses
+    - ALSA: PCM: Fix NULL dereference at mmap checks
+    - ALSA: timer: Fix use-after-free problem
+    - ALSA: timer: Unconditionally unlink slave instances, too
+    - Revert "ext4: enforce buffer head state assertion in ext4_da_map_blocks"
+    - ext4: fix lazy initialization next schedule time computation in more
+      granular unit
+    - ext4: ensure enough credits in ext4_ext_shift_path_extents
+    - ext4: refresh the ext4_ext_path struct after dropping i_data_sem.
+    - fuse: fix page stealing
+    - x86/sme: Use #define USE_EARLY_PGTABLE_L5 in mem_encrypt_identity.c
+    - x86/cpu: Fix migration safety with X86_BUG_NULL_SEL
+    - x86/irq: Ensure PI wakeup handler is unregistered before module unload
+    - x86/iopl: Fake iopl(3) CLI/STI usage
+    - btrfs: clear MISSING device status bit in btrfs_close_one_device
+    - btrfs: fix lost error handling when replaying directory deletes
+    - btrfs: call btrfs_check_rw_degradable only if there is a missing device
+    - KVM: x86/mmu: Drop a redundant, broken remote TLB flush
+    - KVM: VMX: Unregister posted interrupt wakeup handler on hardware unsetup
+    - KVM: PPC: Tick accounting should defer vtime accounting 'til after IRQ
+      handling
+    - ia64: kprobes: Fix to pass correct trampoline address to the handler
+    - selinux: fix race condition when computing ocontext SIDs
+    - ipmi:watchdog: Set panic count to proper value on a panic
+    - md/raid1: only allocate write behind bio for WriteMostly device
+    - hwmon: (pmbus/lm25066) Add offset coefficients
+    - regulator: s5m8767: do not use reset value as DVS voltage if GPIO DVS is
+      disabled
+    - regulator: dt-bindings: samsung,s5m8767: correct s5m8767,pmic-buck-default-
+      dvs-idx property
+    - EDAC/sb_edac: Fix top-of-high-memory value for Broadwell/Haswell
+    - mwifiex: fix division by zero in fw download path
+    - ath6kl: fix division by zero in send path
+    - ath6kl: fix control-message timeout
+    - ath10k: fix control-message timeout
+    - ath10k: fix division by zero in send path
+    - PCI: Mark Atheros QCA6174 to avoid bus reset
+    - rtl8187: fix control-message timeouts
+    - evm: mark evm_fixmode as __ro_after_init
+    - ifb: Depend on netfilter alternatively to tc
+    - platform/surface: aggregator_registry: Add support for Surface Laptop Studio
+    - mt76: mt7615: fix skb use-after-free on mac reset
+    - HID: surface-hid: Use correct event registry for managing HID events
+    - HID: surface-hid: Allow driver matching for target ID 1 devices
+    - wcn36xx: Fix HT40 capability for 2Ghz band
+    - wcn36xx: Fix tx_status mechanism
+    - wcn36xx: Fix (QoS) null data frame bitrate/modulation
+    - PM: sleep: Do not let "syscore" devices runtime-suspend during system
+      transitions
+    - mwifiex: Read a PCI register after writing the TX ring write pointer
+    - mwifiex: Try waking the firmware until we get an interrupt
+    - libata: fix checking of DMA state
+    - dma-buf: fix and rework dma_buf_poll v7
+    - wcn36xx: handle connection loss indication
+    - rsi: fix occasional initialisation failure with BT coex
+    - rsi: fix key enabled check causing unwanted encryption for vap_id > 0
+    - rsi: fix rate mask set leading to P2P failure
+    - rsi: Fix module dev_oper_mode parameter description
+    - perf/x86/intel/uncore: Support extra IMC channel on Ice Lake server
+    - perf/x86/intel/uncore: Fix invalid unit check
+    - perf/x86/intel/uncore: Fix Intel ICX IIO event constraints
+    - RDMA/qedr: Fix NULL deref for query_qp on the GSI QP
+    - ASoC: tegra: Set default card name for Trimslice
+    - ASoC: tegra: Restore AC97 support
+    - signal: Remove the bogus sigkill_pending in ptrace_stop
+    - memory: renesas-rpc-if: Correct QSPI data transfer in Manual mode
+    - signal/mips: Update (_save|_restore)_fp_context to fail with -EFAULT
+    - soc: samsung: exynos-pmu: Fix compilation when nothing selects
+      CONFIG_MFD_CORE
+    - soc: fsl: dpio: replace smp_processor_id with raw_smp_processor_id
+    - soc: fsl: dpio: use the combined functions to protect critical zone
+    - mtd: rawnand: socrates: Keep the driver compatible with on-die ECC engines
+    - mctp: handle the struct sockaddr_mctp padding fields
+    - power: supply: max17042_battery: Prevent int underflow in set_soc_threshold
+    - power: supply: max17042_battery: use VFSOC for capacity when no rsns
+    - iio: core: fix double free in iio_device_unregister_sysfs()
+    - iio: core: check return value when calling dev_set_name()
+    - KVM: arm64: Extract ESR_ELx.EC only
+    - KVM: x86: Fix recording of guest steal time / preempted status
+    - KVM: x86: Add helper to consolidate core logic of SET_CPUID{2} flows
+    - KVM: nVMX: Query current VMCS when determining if MSR bitmaps are in use
+    - KVM: nVMX: Handle dynamic MSR intercept toggling
+    - can: peak_usb: always ask for BERR reporting for PCAN-USB devices
+    - can: mcp251xfd: mcp251xfd_irq(): add missing
+      can_rx_offload_threaded_irq_finish() in case of bus off
+    - can: j1939: j1939_tp_cmd_recv(): ignore abort message in the BAM transport
+    - can: j1939: j1939_can_recv(): ignore messages with invalid source address
+    - can: j1939: j1939_tp_cmd_recv(): check the dst address of TP.CM_BAM
+    - iio: adc: tsc2046: fix scan interval warning
+    - powerpc/85xx: Fix oops when mpc85xx_smp_guts_ids node cannot be found
+    - io_uring: honour zeroes as io-wq worker limits
+    - ring-buffer: Protect ring_buffer_reset() from reentrancy
+    - serial: core: Fix initializing and restoring termios speed
+    - ifb: fix building without CONFIG_NET_CLS_ACT
+    - xen/balloon: add late_initcall_sync() for initial ballooning done
+    - ovl: fix use after free in struct ovl_aio_req
+    - ovl: fix filattr copy-up failure
+    - PCI: pci-bridge-emul: Fix emulation of W1C bits
+    - PCI: cadence: Add cdns_plat_pcie_probe() missing return
+    - cxl/pci: Fix NULL vs ERR_PTR confusion
+    - PCI: aardvark: Do not clear status bits of masked interrupts
+    - PCI: aardvark: Fix checking for link up via LTSSM state
+    - PCI: aardvark: Do not unmask unused interrupts
+    - PCI: aardvark: Fix reporting Data Link Layer Link Active
+    - PCI: aardvark: Fix configuring Reference clock
+    - PCI: aardvark: Fix return value of MSI domain .alloc() method
+    - PCI: aardvark: Read all 16-bits from PCIE_MSI_PAYLOAD_REG
+    - PCI: aardvark: Fix support for bus mastering and PCI_COMMAND on emulated
+      bridge
+    - PCI: aardvark: Fix support for PCI_BRIDGE_CTL_BUS_RESET on emulated bridge
+    - PCI: aardvark: Set PCI Bridge Class Code to PCI Bridge
+    - PCI: aardvark: Fix support for PCI_ROM_ADDRESS1 on emulated bridge
+    - quota: check block number when reading the block in quota file
+    - quota: correct error number in free_dqentry()
+    - cifs: To match file servers, make sure the server hostname matches
+    - cifs: set a minimum of 120s for next dns resolution
+    - mfd: simple-mfd-i2c: Select MFD_CORE to fix build error
+    - pinctrl: core: fix possible memory leak in pinctrl_enable()
+    - coresight: cti: Correct the parameter for pm_runtime_put
+    - coresight: trbe: Fix incorrect access of the sink specific data
+    - coresight: trbe: Defer the probe on offline CPUs
+    - iio: buffer: check return value of kstrdup_const()
+    - iio: buffer: Fix memory leak in iio_buffers_alloc_sysfs_and_mask()
+    - iio: buffer: Fix memory leak in __iio_buffer_alloc_sysfs_and_mask()
+    - iio: buffer: Fix memory leak in iio_buffer_register_legacy_sysfs_groups()
+    - drivers: iio: dac: ad5766: Fix dt property name
+    - iio: dac: ad5446: Fix ad5622_write() return value
+    - iio: ad5770r: make devicetree property reading consistent
+    - Documentation:devicetree:bindings:iio:dac: Fix val
+    - USB: serial: keyspan: fix memleak on probe errors
+    - serial: 8250: fix racy uartclk update
+    - ksmbd: set unique value to volume serial field in FS_VOLUME_INFORMATION
+    - io-wq: serialize hash clear with wakeup
+    - serial: 8250: Fix reporting real baudrate value in c_ospeed field
+    - Revert "serial: 8250: Fix reporting real baudrate value in c_ospeed field"
+    - most: fix control-message timeouts
+    - USB: iowarrior: fix control-message timeouts
+    - USB: chipidea: fix interrupt deadlock
+    - power: supply: max17042_battery: Clear status bits in interrupt handler
+    - component: do not leave master devres group open after bind
+    - dma-buf: WARN on dmabuf release with pending attachments
+    - drm: panel-orientation-quirks: Update the Lenovo Ideapad D330 quirk (v2)
+    - drm: panel-orientation-quirks: Add quirk for KD Kurio Smart C15200 2-in-1
+    - drm: panel-orientation-quirks: Add quirk for the Samsung Galaxy Book 10.6
+    - Bluetooth: sco: Fix lock_sock() blockage by memcpy_from_msg()
+    - Bluetooth: fix use-after-free error in lock_sock_nested()
+    - Bluetooth: call sock_hold earlier in sco_conn_del
+    - drm/panel-orientation-quirks: add Valve Steam Deck
+    - rcutorture: Avoid problematic critical section nesting on PREEMPT_RT
+    - platform/x86: wmi: do not fail if disabling fails
+    - drm/amdgpu: move iommu_resume before ip init/resume
+    - MIPS: lantiq: dma: add small delay after reset
+    - MIPS: lantiq: dma: reset correct number of channel
+    - locking/lockdep: Avoid RCU-induced noinstr fail
+    - net: sched: update default qdisc visibility after Tx queue cnt changes
+    - rcu-tasks: Move RTGS_WAIT_CBS to beginning of rcu_tasks_kthread() loop
+    - smackfs: Fix use-after-free in netlbl_catmap_walk()
+    - ath11k: Align bss_chan_info structure with firmware
+    - crypto: aesni - check walk.nbytes instead of err
+    - x86/mm/64: Improve stack overflow warnings
+    - x86: Increase exception stack sizes
+    - mwifiex: Run SET_BSS_MODE when changing from P2P to STATION vif-type
+    - mwifiex: Properly initialize private structure on interface type changes
+    - spi: Check we have a spi_device_id for each DT compatible
+    - fscrypt: allow 256-bit master keys with AES-256-XTS
+    - drm/amdgpu: Fix MMIO access page fault
+    - drm/amd/display: Fix null pointer dereference for encoders
+    - selftests: net: fib_nexthops: Wait before checking reported idle time
+    - ath11k: Avoid reg rules update during firmware recovery
+    - ath11k: add handler for scan event WMI_SCAN_EVENT_DEQUEUED
+    - ath11k: Change DMA_FROM_DEVICE to DMA_TO_DEVICE when map reinjected packets
+    - ath10k: high latency fixes for beacon buffer
+    - octeontx2-pf: Enable promisc/allmulti match MCAM entries.
+    - media: mt9p031: Fix corrupted frame after restarting stream
+    - media: netup_unidvb: handle interrupt properly according to the firmware
+    - media: atomisp: Fix error handling in probe
+    - media: stm32: Potential NULL pointer dereference in dcmi_irq_thread()
+    - media: uvcvideo: Set capability in s_param
+    - media: uvcvideo: Return -EIO for control errors
+    - media: uvcvideo: Set unique vdev name based in type
+    - media: vidtv: Fix memory leak in remove
+    - media: s5p-mfc: fix possible null-pointer dereference in s5p_mfc_probe()
+    - media: s5p-mfc: Add checking to s5p_mfc_probe().
+    - media: videobuf2: rework vb2_mem_ops API
+    - media: imx: set a media_device bus_info string
+    - media: rcar-vin: Use user provided buffers when starting
+    - media: mceusb: return without resubmitting URB in case of -EPROTO error.
+    - ia64: don't do IA64_CMPXCHG_DEBUG without CONFIG_PRINTK
+    - rtw88: fix RX clock gate setting while fifo dump
+    - brcmfmac: Add DMI nvram filename quirk for Cyberbook T116 tablet
+    - media: rcar-csi2: Add checking to rcsi2_start_receiver()
+    - ipmi: Disable some operations during a panic
+    - fs/proc/uptime.c: Fix idle time reporting in /proc/uptime
+    - kselftests/sched: cleanup the child processes
+    - ACPICA: Avoid evaluating methods too early during system resume
+    - cpufreq: Make policy min/max hard requirements
+    - ice: Move devlink port to PF/VF struct
+    - media: imx-jpeg: Fix possible null pointer dereference
+    - media: ipu3-imgu: imgu_fmt: Handle properly try
+    - media: ipu3-imgu: VIDIOC_QUERYCAP: Fix bus_info
+    - media: usb: dvd-usb: fix uninit-value bug in dibusb_read_eeprom_byte()
+    - net-sysfs: try not to restart the syscall if it will fail eventually
+    - drm/amdkfd: rm BO resv on validation to avoid deadlock
+    - tracefs: Have tracefs directories not set OTH permission bits by default
+    - tracing: Disable "other" permission bits in the tracefs files
+    - ath: dfs_pattern_detector: Fix possible null-pointer dereference in
+      channel_detector_create()
+    - KVM: arm64: Propagate errors from __pkvm_prot_finalize hypercall
+    - mmc: moxart: Fix reference count leaks in moxart_probe
+    - iov_iter: Fix iov_iter_get_pages{,_alloc} page fault return value
+    - ACPI: battery: Accept charges over the design capacity as full
+    - ACPI: scan: Release PM resources blocked by unused objects
+    - drm/amd/display: fix null pointer deref when plugging in display
+    - drm/amdkfd: fix resume error when iommu disabled in Picasso
+    - net: phy: micrel: make *-skew-ps check more lenient
+    - leaking_addresses: Always print a trailing newline
+    - thermal/core: Fix null pointer dereference in thermal_release()
+    - drm/msm: prevent NULL dereference in msm_gpu_crashstate_capture()
+    - thermal/drivers/tsens: Add timeout to get_temp_tsens_valid
+    - block: bump max plugged deferred size from 16 to 32
+    - floppy: fix calling platform_device_unregister() on invalid drives
+    - md: update superblock after changing rdev flags in state_store
+    - memstick: r592: Fix a UAF bug when removing the driver
+    - locking/rwsem: Disable preemption for spinning region
+    - lib/xz: Avoid overlapping memcpy() with invalid input with in-place
+      decompression
+    - lib/xz: Validate the value before assigning it to an enum variable
+    - workqueue: make sysfs of unbound kworker cpumask more clever
+    - tracing/cfi: Fix cmp_entries_* functions signature mismatch
+    - mt76: mt7915: fix an off-by-one bound check
+    - mwl8k: Fix use-after-free in mwl8k_fw_state_machine()
+    - iwlwifi: change all JnP to NO-160 configuration
+    - block: remove inaccurate requeue check
+    - media: allegro: ignore interrupt if mailbox is not initialized
+    - drm/amdgpu/pm: properly handle sclk for profiling modes on vangogh
+    - nvmet: fix use-after-free when a port is removed
+    - nvmet-rdma: fix use-after-free when a port is removed
+    - nvmet-tcp: fix use-after-free when a port is removed
+    - nvme: drop scan_lock and always kick requeue list when removing namespaces
+    - samples/bpf: Fix application of sizeof to pointer
+    - arm64: vdso32: suppress error message for 'make mrproper'
+    - PM: hibernate: Get block device exclusively in swsusp_check()
+    - selftests: kvm: fix mismatched fclose() after popen()
+    - selftests/bpf: Fix perf_buffer test on system with offline cpus
+    - iwlwifi: mvm: disable RX-diversity in powersave
+    - smackfs: use __GFP_NOFAIL for smk_cipso_doi()
+    - ARM: clang: Do not rely on lr register for stacktrace
+    - gre/sit: Don't generate link-local addr if addr_gen_mode is
+      IN6_ADDR_GEN_MODE_NONE
+    - can: bittiming: can_fixup_bittiming(): change type of tseg1 and alltseg to
+      unsigned int
+    - gfs2: Cancel remote delete work asynchronously
+    - gfs2: Fix glock_hash_walk bugs
+    - ARM: 9136/1: ARMv7-M uses BE-8, not BE-32
+    - tools/latency-collector: Use correct size when writing queue_full_warning
+    - vrf: run conntrack only in context of lower/physdev for locally generated
+      packets
+    - net: annotate data-race in neigh_output()
+    - ACPI: AC: Quirk GK45 to skip reading _PSR
+    - ACPI: resources: Add one more Medion model in IRQ override quirk
+    - btrfs: reflink: initialize return value to 0 in btrfs_extent_same()
+    - btrfs: do not take the uuid_mutex in btrfs_rm_device
+    - spi: bcm-qspi: Fix missing clk_disable_unprepare() on error in
+      bcm_qspi_probe()
+    - wcn36xx: Correct band/freq reporting on RX
+    - wcn36xx: Fix packet drop on resume
+    - Revert "wcn36xx: Enable firmware link monitoring"
+    - ftrace: do CPU checking after preemption disabled
+    - inet: remove races in inet{6}_getname()
+    - x86/hyperv: Protect set_hv_tscchange_cb() against getting preempted
+    - drm/amd/display: dcn20_resource_construct reduce scope of FPU enabled
+    - perf/x86/intel: Fix ICL/SPR INST_RETIRED.PREC_DIST encodings
+    - parisc: fix warning in flush_tlb_all
+    - task_stack: Fix end_of_stack() for architectures with upwards-growing stack
+    - erofs: don't trigger WARN() when decompression fails
+    - parisc/unwind: fix unwinder when CONFIG_64BIT is enabled
+    - parisc/kgdb: add kgdb_roundup() to make kgdb work with idle polling
+    - netfilter: conntrack: set on IPS_ASSURED if flows enters internal stream
+      state
+    - selftests/bpf: Fix strobemeta selftest regression
+    - fbdev/efifb: Release PCI device's runtime PM ref during FB destroy
+    - drm/bridge: anx7625: Propagate errors from sp_tx_rst_aux()
+    - perf/x86/intel/uncore: Fix Intel SPR CHA event constraints
+    - perf/x86/intel/uncore: Fix Intel SPR IIO event constraints
+    - perf/x86/intel/uncore: Fix Intel SPR M2PCIE event constraints
+    - perf/x86/intel/uncore: Fix Intel SPR M3UPI event constraints
+    - drm/bridge: it66121: Initialize {device,vendor}_ids
+    - drm/bridge: it66121: Wait for next bridge to be probed
+    - Bluetooth: fix init and cleanup of sco_conn.timeout_work
+    - libbpf: Don't crash on object files with no symbol tables
+    - Bluetooth: hci_uart: fix GPF in h5_recv
+    - rcu: Fix existing exp request check in sync_sched_exp_online_cleanup()
+    - MIPS: lantiq: dma: fix burst length for DEU
+    - x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
+    - objtool: Handle __sanitize_cov*() tail calls
+    - net/mlx5: Publish and unpublish all devlink parameters at once
+    - drm/v3d: fix wait for TMU write combiner flush
+    - crypto: sm4 - Do not change section of ck and sbox
+    - virtio-gpu: fix possible memory allocation failure
+    - lockdep: Let lock_is_held_type() detect recursive read as read
+    - net: net_namespace: Fix undefined member in key_remove_domain()
+    - net: phylink: don't call netif_carrier_off() with NULL netdev
+    - drm: bridge: it66121: Fix return value it66121_probe
+    - spi: Fixed division by zero warning
+    - cgroup: Make rebind_subsystems() disable v2 controllers all at once
+    - wcn36xx: Fix Antenna Diversity Switching
+    - wilc1000: fix possible memory leak in cfg_scan_result()
+    - Bluetooth: btmtkuart: fix a memleak in mtk_hci_wmt_sync
+    - drm/amdgpu: Fix crash on device remove/driver unload
+    - drm/amd/display: Pass display_pipe_params_st as const in DML
+    - drm/amdgpu: move amdgpu_virt_release_full_gpu to fini_early stage
+    - crypto: caam - disable pkc for non-E SoCs
+    - crypto: qat - power up 4xxx device
+    - Bluetooth: hci_h5: Fix (runtime)suspend issues on RTL8723BS HCIs
+    - bnxt_en: Check devlink allocation and registration status
+    - qed: Don't ignore devlink allocation failures
+    - rxrpc: Fix _usecs_to_jiffies() by using usecs_to_jiffies()
+    - mptcp: do not shrink snd_nxt when recovering
+    - fortify: Fix dropped strcpy() compile-time write overflow check
+    - mac80211: twt: don't use potentially unaligned pointer
+    - cfg80211: always free wiphy specific regdomain
+    - net/mlx5: Accept devlink user input after driver initialization complete
+    - net: dsa: rtl8366rb: Fix off-by-one bug
+    - net: dsa: rtl8366: Fix a bug in deleting VLANs
+    - bpf/tests: Fix error in tail call limit tests
+    - ath11k: fix some sleeping in atomic bugs
+    - ath11k: Avoid race during regd updates
+    - ath11k: fix packet drops due to incorrect 6 GHz freq value in rx status
+    - ath11k: Fix memory leak in ath11k_qmi_driver_event_work
+    - gve: DQO: avoid unused variable warnings
+    - ath10k: Fix missing frame timestamp for beacon/probe-resp
+    - ath10k: sdio: Add missing BH locking around napi_schdule()
+    - drm/ttm: stop calling tt_swapin in vm_access
+    - arm64: mm: update max_pfn after memory hotplug
+    - drm/amdgpu: fix warning for overflow check
+    - libbpf: Fix skel_internal.h to set errno on loader retval < 0
+    - media: em28xx: add missing em28xx_close_extension
+    - media: meson-ge2d: Fix rotation parameter changes detection in
+      'ge2d_s_ctrl()'
+    - media: cxd2880-spi: Fix a null pointer dereference on error handling path
+    - media: ttusb-dec: avoid release of non-acquired mutex
+    - media: dvb-usb: fix ununit-value in az6027_rc_query
+    - media: imx258: Fix getting clock frequency
+    - media: v4l2-ioctl: S_CTRL output the right value
+    - media: mtk-vcodec: venc: fix return value when start_streaming fails
+    - media: TDA1997x: handle short reads of hdmi info frame.
+    - media: mtk-vpu: Fix a resource leak in the error handling path of
+      'mtk_vpu_probe()'
+    - media: imx-jpeg: Fix the error handling path of 'mxc_jpeg_probe()'
+    - media: i2c: ths8200 needs V4L2_ASYNC
+    - media: sun6i-csi: Allow the video device to be open multiple times
+    - media: radio-wl1273: Avoid card name truncation
+    - media: si470x: Avoid card name truncation
+    - media: tm6000: Avoid card name truncation
+    - media: cx23885: Fix snd_card_free call on null card pointer
+    - media: atmel: fix the ispck initialization
+    - scs: Release kasan vmalloc poison in scs_free process
+    - kprobes: Do not use local variable when creating debugfs file
+    - crypto: ecc - fix CRYPTO_DEFAULT_RNG dependency
+    - drm: fb_helper: fix CONFIG_FB dependency
+    - cpuidle: Fix kobject memory leaks in error paths
+    - media: em28xx: Don't use ops->suspend if it is NULL
+    - ath10k: Don't always treat modem stop events as crashes
+    - ath9k: Fix potential interrupt storm on queue reset
+    - PM: EM: Fix inefficient states detection
+    - x86/insn: Use get_unaligned() instead of memcpy()
+    - EDAC/amd64: Handle three rank interleaving mode
+    - rcu: Always inline rcu_dynticks_task*_{enter,exit}()
+    - rcu: Fix rcu_dynticks_curr_cpu_in_eqs() vs noinstr
+    - netfilter: nft_dynset: relax superfluous check on set updates
+    - media: venus: fix vpp frequency calculation for decoder
+    - media: dvb-frontends: mn88443x: Handle errors of clk_prepare_enable()
+    - crypto: ccree - avoid out-of-range warnings from clang
+    - crypto: qat - detect PFVF collision after ACK
+    - crypto: qat - disregard spurious PFVF interrupts
+    - hwrng: mtk - Force runtime pm ops for sleep ops
+    - ima: fix deadlock when traversing "ima_default_rules".
+    - b43legacy: fix a lower bounds test
+    - b43: fix a lower bounds test
+    - gve: Recover from queue stall due to missed IRQ
+    - gve: Track RX buffer allocation failures
+    - mmc: sdhci-omap: Fix NULL pointer exception if regulator is not configured
+    - mmc: sdhci-omap: Fix context restore
+    - memstick: avoid out-of-range warning
+    - memstick: jmb38x_ms: use appropriate free function in jmb38x_ms_alloc_host()
+    - net, neigh: Fix NTF_EXT_LEARNED in combination with NTF_USE
+    - hwmon: Fix possible memleak in __hwmon_device_register()
+    - hwmon: (pmbus/lm25066) Let compiler determine outer dimension of
+      lm25066_coeff
+    - ath10k: fix max antenna gain unit
+    - kernel/sched: Fix sched_fork() access an invalid sched_task_group
+    - net: fealnx: fix build for UML
+    - net: intel: igc_ptp: fix build for UML
+    - net: tulip: winbond-840: fix build for UML
+    - tcp: switch orphan_count to bare per-cpu counters
+    - crypto: octeontx2 - set assoclen in aead_do_fallback()
+    - thermal/core: fix a UAF bug in __thermal_cooling_device_register()
+    - drm/msm/dsi: do not enable irq handler before powering up the host
+    - drm/msm: Fix potential Oops in a6xx_gmu_rpmh_init()
+    - drm/msm: potential error pointer dereference in init()
+    - drm/msm: unlock on error in get_sched_entity()
+    - drm/msm: fix potential NULL dereference in cleanup
+    - drm/msm: uninitialized variable in msm_gem_import()
+    - net: stream: don't purge sk_error_queue in sk_stream_kill_queues()
+    - thermal/drivers/qcom/lmh: make QCOM_LMH depends on QCOM_SCM
+    - mailbox: Remove WARN_ON for async_cb.cb in cmdq_exec_done
+    - media: ivtv: fix build for UML
+    - media: ir_toy: assignment to be16 should be of correct type
+    - mmc: mxs-mmc: disable regulator on error and in the remove function
+    - io-wq: Remove duplicate code in io_workqueue_create()
+    - block: ataflop: fix breakage introduced at blk-mq refactoring
+    - platform/x86: thinkpad_acpi: Fix bitwise vs. logical warning
+    - mailbox: mtk-cmdq: Validate alias_id on probe
+    - mailbox: mtk-cmdq: Fix local clock ID usage
+    - ACPI: PM: Turn off unused wakeup power resources
+    - ACPI: PM: Fix sharing of wakeup power resources
+    - drm/amdkfd: Fix an inappropriate error handling in allloc memory of gpu
+    - mt76: mt7921: fix endianness in mt7921_mcu_tx_done_event
+    - mt76: mt7915: fix endianness warning in mt7915_mac_add_txs_skb
+    - mt76: mt7921: fix endianness warning in mt7921_update_txs
+    - mt76: mt7615: fix endianness warning in mt7615_mac_write_txwi
+    - mt76: mt7915: fix info leak in mt7915_mcu_set_pre_cal()
+    - mt76: connac: fix mt76_connac_gtk_rekey_tlv usage
+    - mt76: fix build error implicit enumeration conversion
+    - mt76: mt7921: fix survey-dump reporting
+    - mt76: mt76x02: fix endianness warnings in mt76x02_mac.c
+    - mt76: mt7921: Fix out of order process by invalid event pkt
+    - mt76: mt7915: fix potential overflow of eeprom page index
+    - mt76: mt7915: fix bit fields for HT rate idx
+    - mt76: mt7921: fix dma hang in rmmod
+    - mt76: connac: fix GTK rekey offload failure on WPA mixed mode
+    - mt76: overwrite default reg_ops if necessary
+    - mt76: mt7921: report HE MU radiotap
+    - mt76: mt7921: fix firmware usage of RA info using legacy rates
+    - mt76: mt7921: fix kernel warning from cfg80211_calculate_bitrate
+    - mt76: mt7921: always wake device if necessary in debugfs
+    - mt76: mt7915: fix hwmon temp sensor mem use-after-free
+    - mt76: mt7615: fix hwmon temp sensor mem use-after-free
+    - mt76: mt7915: fix possible infinite loop release semaphore
+    - mt76: mt7921: fix retrying release semaphore without end
+    - mt76: mt7615: fix monitor mode tear down crash
+    - mt76: connac: fix possible NULL pointer dereference in
+      mt76_connac_get_phy_mode_v2
+    - mt76: mt7915: fix sta_rec_wtbl tag len
+    - mt76: mt7915: fix muar_idx in mt7915_mcu_alloc_sta_req()
+    - rsi: stop thread firstly in rsi_91x_init() error handling
+    - mwifiex: Send DELBA requests according to spec
+    - iwlwifi: mvm: reset PM state on unsuccessful resume
+    - iwlwifi: pnvm: don't kmemdup() more than we have
+    - iwlwifi: pnvm: read EFI data only if long enough
+    - net: enetc: unmap DMA in enetc_send_cmd()
+    - phy: micrel: ksz8041nl: do not use power down mode
+    - nbd: Fix use-after-free in pid_show
+    - nvme-rdma: fix error code in nvme_rdma_setup_ctrl
+    - PM: hibernate: fix sparse warnings
+    - clocksource/drivers/timer-ti-dm: Select TIMER_OF
+    - x86/sev: Fix stack type check in vc_switch_off_ist()
+    - drm/msm: Fix potential NULL dereference in DPU SSPP
+    - drm/msm/dsi: fix wrong type in msm_dsi_host
+    - crypto: tcrypt - fix skcipher multi-buffer tests for 1420B blocks
+    - smackfs: use netlbl_cfg_cipsov4_del() for deleting cipso_v4_doi
+    - KVM: selftests: Fix nested SVM tests when built with clang
+    - libbpf: Fix memory leak in btf__dedup()
+    - bpftool: Avoid leaking the JSON writer prepared for program metadata
+    - libbpf: Fix overflow in BTF sanity checks
+    - libbpf: Fix BTF header parsing checks
+    - mt76: mt7615: mt7622: fix ibss and meshpoint
+    - s390/gmap: validate VMA in __gmap_zap()
+    - s390/gmap: don't unconditionally call pte_unmap_unlock() in __gmap_zap()
+    - s390/mm: validate VMA in PGSTE manipulation functions
+    - s390/mm: fix VMA and page table handling code in storage key handling
+      functions
+    - s390/uv: fully validate the VMA before calling follow_page()
+    - KVM: s390: pv: avoid double free of sida page
+    - KVM: s390: pv: avoid stalls for kvm_s390_pv_init_vm
+    - irq: mips: avoid nested irq_enter()
+    - net: dsa: avoid refcount warnings when ->port_{fdb,mdb}_del returns error
+    - ARM: 9142/1: kasan: work around LPAE build warning
+    - ath10k: fix module load regression with iram-recovery feature
+    - block: ataflop: more blk-mq refactoring fixes
+    - blk-cgroup: synchronize blkg creation against policy deactivation
+    - libbpf: Fix off-by-one bug in bpf_core_apply_relo()
+    - tpm: fix Atmel TPM crash caused by too frequent queries
+    - tpm_tis_spi: Add missing SPI ID
+    - libbpf: Fix endianness detection in BPF_CORE_READ_BITFIELD_PROBED()
+    - tcp: don't free a FIN sk_buff in tcp_remove_empty_skb()
+    - tracing: Fix missing trace_boot_init_histograms kstrdup NULL checks
+    - cpufreq: intel_pstate: Fix cpu->pstate.turbo_freq initialization
+    - spi: spi-rpc-if: Check return value of rpcif_sw_init()
+    - samples/kretprobes: Fix return value if register_kretprobe() failed
+    - KVM: s390: Fix handle_sske page fault handling
+    - libertas_tf: Fix possible memory leak in probe and disconnect
+    - libertas: Fix possible memory leak in probe and disconnect
+    - wcn36xx: add proper DMA memory barriers in rx path
+    - wcn36xx: Fix discarded frames due to wrong sequence number
+    - bpf: Avoid races in __bpf_prog_run() for 32bit arches
+    - bpf: Fixes possible race in update_prog_stats() for 32bit arches
+    - wcn36xx: Channel list update before hardware scan
+    - drm/amdgpu: fix a potential memory leak in amdgpu_device_fini_sw()
+    - drm/amdgpu/gmc6: fix DMA mask from 44 to 40 bits
+    - selftests/bpf: Fix fd cleanup in sk_lookup test
+    - selftests/bpf: Fix memory leak in test_ima
+    - sctp: allow IP fragmentation when PLPMTUD enters Error state
+    - sctp: reset probe_timer in sctp_transport_pl_update
+    - sctp: subtract sctphdr len in sctp_transport_pl_hlen
+    - sctp: return true only for pathmtu update in sctp_transport_pl_toobig
+    - net: amd-xgbe: Toggle PLL settings during rate change
+    - ipmi: kcs_bmc: Fix a memory leak in the error handling path of
+      'kcs_bmc_serio_add_device()'
+    - nfp: fix NULL pointer access when scheduling dim work
+    - nfp: fix potential deadlock when canceling dim work
+    - net: phylink: avoid mvneta warning when setting pause parameters
+    - net: bridge: fix uninitialized variables when BRIDGE_CFM is disabled
+    - selftests: net: bridge: update IGMP/MLD membership interval value
+    - crypto: pcrypt - Delay write to padata->info
+    - selftests/bpf: Fix fclose/pclose mismatch in test_progs
+    - udp6: allow SO_MARK ctrl msg to affect routing
+    - ibmvnic: don't stop queue in xmit
+    - ibmvnic: Process crqs after enabling interrupts
+    - ibmvnic: delay complete()
+    - selftests: mptcp: fix proto type in link_failure tests
+    - skmsg: Lose offset info in sk_psock_skb_ingress
+    - cgroup: Fix rootcg cpu.stat guest double counting
+    - bpf: Fix propagation of bounds from 64-bit min/max into 32-bit and var_off.
+    - bpf: Fix propagation of signed bounds from 64-bit min/max into 32-bit.
+    - of: unittest: fix EXPECT text for gpio hog errors
+    - cpufreq: Fix parameter in parse_perf_domain()
+    - staging: r8188eu: fix memory leak in rtw_set_key
+    - arm64: dts: meson: sm1: add Ethernet PHY reset line for ODROID-C4/HC4
+    - iio: st_sensors: disable regulators after device unregistration
+    - RDMA/rxe: Fix wrong port_cap_flags
+    - ARM: dts: BCM5301X: Fix memory nodes names
+    - arm64: dts: broadcom: bcm4908: Fix UART clock name
+    - clk: mvebu: ap-cpu-clk: Fix a memory leak in error handling paths
+    - scsi: pm80xx: Fix lockup in outbound queue management
+    - scsi: qla2xxx: edif: Use link event to wake up app
+    - scsi: lpfc: Fix NVMe I/O failover to non-optimized path
+    - ARM: s3c: irq-s3c24xx: Fix return value check for s3c24xx_init_intc()
+    - arm64: dts: rockchip: Fix GPU register width for RK3328
+    - ARM: dts: qcom: msm8974: Add xo_board reference clock to DSI0 PHY
+    - RDMA/bnxt_re: Fix query SRQ failure
+    - arm64: dts: ti: k3-j721e-main: Fix "max-virtual-functions" in PCIe EP nodes
+    - arm64: dts: ti: k3-j721e-main: Fix "bus-range" upto 256 bus number for PCIe
+    - arm64: dts: ti: j7200-main: Fix "vendor-id"/"device-id" properties of pcie
+      node
+    - arm64: dts: ti: j7200-main: Fix "bus-range" upto 256 bus number for PCIe
+    - arm64: dts: meson-g12a: Fix the pwm regulator supply properties
+    - arm64: dts: meson-g12b: Fix the pwm regulator supply properties
+    - arm64: dts: meson-sm1: Fix the pwm regulator supply properties
+    - bus: ti-sysc: Fix timekeeping_suspended warning on resume
+    - ARM: dts: at91: tse850: the emac<->phy interface is rmii
+    - arm64: dts: qcom: sc7180: Base dynamic CPU power coefficients in reality
+    - soc: qcom: llcc: Disable MMUHWT retention
+    - arm64: dts: qcom: sc7280: fix display port phy reg property
+    - scsi: dc395: Fix error case unwinding
+    - MIPS: loongson64: make CPU_LOONGSON64 depends on MIPS_FP_SUPPORT
+    - JFS: fix memleak in jfs_mount
+    - pinctrl: renesas: rzg2l: Fix missing port register 21h
+    - ASoC: wcd9335: Use correct version to initialize Class H
+    - arm64: dts: qcom: msm8916: Fix Secondary MI2S bit clock
+    - arm64: dts: renesas: beacon: Fix Ethernet PHY mode
+    - iommu/mediatek: Fix out-of-range warning with clang
+    - arm64: dts: qcom: pm8916: Remove wrong reg-names for rtc@6000
+    - iommu/dma: Fix sync_sg with swiotlb
+    - iommu/dma: Fix arch_sync_dma for map
+    - ALSA: hda: Reduce udelay() at SKL+ position reporting
+    - ALSA: hda: Use position buffer for SKL+ again
+    - ALSA: usb-audio: Fix possible race at sync of urb completions
+    - soundwire: debugfs: use controller id and link_id for debugfs
+    - power: reset: at91-reset: check properly the return value of devm_of_iomap
+    - scsi: ufs: core: Fix ufshcd_probe_hba() prototype to match the definition
+    - scsi: ufs: core: Stop clearing UNIT ATTENTIONS
+    - scsi: megaraid_sas: Fix concurrent access to ISR between IRQ polling and
+      real interrupt
+    - scsi: pm80xx: Fix misleading log statement in pm8001_mpi_get_nvmd_resp()
+    - driver core: Fix possible memory leak in device_link_add()
+    - arm: dts: omap3-gta04a4: accelerometer irq fix
+    - ASoC: SOF: topology: do not power down primary core during topology removal
+    - iio: st_pressure_spi: Add missing entries SPI to device ID table
+    - soc/tegra: Fix an error handling path in tegra_powergate_power_up()
+    - memory: fsl_ifc: fix leak of irq and nand_irq in fsl_ifc_ctrl_probe
+    - clk: at91: check pmc node status before registering syscore ops
+    - powerpc/mem: Fix arch/powerpc/mm/mem.c:53:12: error: no previous prototype
+      for 'create_section_mapping'
+    - video: fbdev: chipsfb: use memset_io() instead of memset()
+    - powerpc: fix unbalanced node refcount in check_kvm_guest()
+    - powerpc/paravirt: correct preempt debug splat in vcpu_is_preempted()
+    - serial: 8250_dw: Drop wrong use of ACPI_PTR()
+    - usb: gadget: hid: fix error code in do_config()
+    - power: supply: rt5033_battery: Change voltage values to µV
+    - power: supply: max17040: fix null-ptr-deref in max17040_probe()
+    - scsi: csiostor: Uninitialized data in csio_ln_vnp_read_cbfn()
+    - RDMA/mlx4: Return missed an error if device doesn't support steering
+    - usb: musb: select GENERIC_PHY instead of depending on it
+    - staging: most: dim2: do not double-register the same device
+    - staging: ks7010: select CRYPTO_HASH/CRYPTO_MICHAEL_MIC
+    - RDMA/core: Set sgtable nents when using ib_dma_virt_map_sg()
+    - dyndbg: make dyndbg a known cli param
+    - powerpc/perf: Fix cycles/instructions as PM_CYC/PM_INST_CMPL in power10
+    - pinctrl: renesas: checker: Fix off-by-one bug in drive register check
+    - ARM: dts: stm32: Reduce DHCOR SPI NOR frequency to 50 MHz
+    - ARM: dts: stm32: fix STUSB1600 Type-C irq level on stm32mp15xx-dkx
+    - ARM: dts: stm32: fix SAI sub nodes register range
+    - ARM: dts: stm32: fix AV96 board SAI2 pin muxing on stm32mp15
+    - ASoC: cs42l42: Always configure both ASP TX channels
+    - ASoC: cs42l42: Correct some register default values
+    - ASoC: cs42l42: Defer probe if request_threaded_irq() returns EPROBE_DEFER
+    - soc: qcom: rpmhpd: Make power_on actually enable the domain
+    - soc: qcom: socinfo: add two missing PMIC IDs
+    - iio: buffer: Fix double-free in iio_buffers_alloc_sysfs_and_mask()
+    - usb: typec: STUSB160X should select REGMAP_I2C
+    - iio: adis: do not disabe IRQs in 'adis_init()'
+    - soundwire: bus: stop dereferencing invalid slave pointer
+    - scsi: ufs: ufshcd-pltfrm: Fix memory leak due to probe defer
+    - scsi: lpfc: Wait for successful restart of SLI3 adapter during host sg_reset
+    - serial: imx: fix detach/attach of serial console
+    - usb: dwc2: drd: fix dwc2_force_mode call in dwc2_ovr_init
+    - usb: dwc2: drd: fix dwc2_drd_role_sw_set when clock could be disabled
+    - usb: dwc2: drd: reset current session before setting the new one
+    - powerpc/booke: Disable STRICT_KERNEL_RWX, DEBUG_PAGEALLOC and KFENCE
+    - usb: dwc3: gadget: Skip resizing EP's TX FIFO if already resized
+    - firmware: qcom_scm: Fix error retval in __qcom_scm_is_call_available()
+    - soc: qcom: rpmhpd: fix sm8350_mxc's peer domain
+    - soc: qcom: apr: Add of_node_put() before return
+    - arm64: dts: qcom: pmi8994: Fix "eternal"->"external" typo in WLED node
+    - arm64: dts: qcom: sdm845: Use RPMH_CE_CLK macro directly
+    - arm64: dts: qcom: sdm845: Fix Qualcomm crypto engine bus clock
+    - pinctrl: equilibrium: Fix function addition in multiple groups
+    - ASoC: topology: Fix stub for snd_soc_tplg_component_remove()
+    - phy: qcom-qusb2: Fix a memory leak on probe
+    - phy: ti: gmii-sel: check of_get_address() for failure
+    - phy: qcom-qmp: another fix for the sc8180x PCIe definition
+    - phy: qcom-snps: Correct the FSEL_MASK
+    - phy: Sparx5 Eth SerDes: Fix return value check in sparx5_serdes_probe()
+    - serial: xilinx_uartps: Fix race condition causing stuck TX
+    - clk: at91: sam9x60-pll: use DIV_ROUND_CLOSEST_ULL
+    - clk: at91: clk-master: check if div or pres is zero
+    - clk: at91: clk-master: fix prescaler logic
+    - HID: u2fzero: clarify error check and length calculations
+    - HID: u2fzero: properly handle timeouts in usb_submit_urb
+    - powerpc/nohash: Fix __ptep_set_access_flags() and ptep_set_wrprotect()
+    - powerpc/book3e: Fix set_memory_x() and set_memory_nx()
+    - powerpc/44x/fsp2: add missing of_node_put
+    - powerpc/xmon: fix task state output
+    - ALSA: oxfw: fix functional regression for Mackie Onyx 1640i in v5.14 or
+      later
+    - iommu/dma: Fix incorrect error return on iommu deferred attach
+    - powerpc: Don't provide __kernel_map_pages() without
+      ARCH_SUPPORTS_DEBUG_PAGEALLOC
+    - ASoC: cs42l42: Correct configuring of switch inversion from ts-inv
+    - RDMA/hns: Fix initial arm_st of CQ
+    - RDMA/hns: Modify the value of MAX_LP_MSG_LEN to meet hardware compatibility
+    - ASoC: rsnd: Fix an error handling path in 'rsnd_node_count()'
+    - serial: cpm_uart: Protect udbg definitions by CONFIG_SERIAL_CPM_CONSOLE
+    - virtio_ring: check desc == NULL when using indirect with packed
+    - vdpa/mlx5: Fix clearing of VIRTIO_NET_F_MAC feature bit
+    - mips: cm: Convert to bitfield API to fix out-of-bounds access
+    - power: supply: bq27xxx: Fix kernel crash on IRQ handler register error
+    - RDMA/core: Require the driver to set the IOVA correctly during rereg_mr
+    - apparmor: fix error check
+    - rpmsg: Fix rpmsg_create_ept return when RPMSG config is not defined
+    - mtd: rawnand: intel: Fix potential buffer overflow in probe
+    - nfsd: don't alloc under spinlock in rpc_parse_scope_id
+    - rtc: ds1302: Add SPI ID table
+    - rtc: ds1390: Add SPI ID table
+    - rtc: pcf2123: Add SPI ID table
+    - remoteproc: imx_rproc: Fix TCM io memory type
+    - i2c: i801: Use PCI bus rescan mutex to protect P2SB access
+    - dmaengine: idxd: move out percpu_ref_exit() to ensure it's outside
+      submission
+    - rtc: mcp795: Add SPI ID table
+    - Input: ariel-pwrbutton - add SPI device ID table
+    - i2c: mediatek: fixing the incorrect register offset
+    - NFS: Default change_attr_type to NFS4_CHANGE_TYPE_IS_UNDEFINED
+    - NFS: Don't set NFS_INO_DATA_INVAL_DEFER and NFS_INO_INVALID_DATA
+    - NFS: Ignore the directory size when marking for revalidation
+    - NFS: Fix dentry verifier races
+    - pnfs/flexfiles: Fix misplaced barrier in nfs4_ff_layout_prepare_ds
+    - drm/bridge/lontium-lt9611uxc: fix provided connector suport
+    - drm/plane-helper: fix uninitialized variable reference
+    - PCI: aardvark: Don't spam about PIO Response Status
+    - PCI: aardvark: Fix preserving PCI_EXP_RTCTL_CRSSVE flag on emulated bridge
+    - opp: Fix return in _opp_add_static_v2()
+    - NFS: Fix deadlocks in nfs_scan_commit_list()
+    - sparc: Add missing "FORCE" target when using if_changed
+    - fs: orangefs: fix error return code of orangefs_revalidate_lookup()
+    - Input: st1232 - increase "wait ready" timeout
+    - drm/bridge: nwl-dsi: Add atomic_get_input_bus_fmts
+    - mtd: spi-nor: hisi-sfc: Remove excessive clk_disable_unprepare()
+    - PCI: uniphier: Serialize INTx masking/unmasking and fix the bit operation
+    - mtd: rawnand: arasan: Prevent an unsupported configuration
+    - mtd: core: don't remove debugfs directory if device is in use
+    - remoteproc: Fix a memory leak in an error handling path in
+      'rproc_handle_vdev()'
+    - rtc: rv3032: fix error handling in rv3032_clkout_set_rate()
+    - dmaengine: at_xdmac: call at_xdmac_axi_config() on resume path
+    - dmaengine: at_xdmac: fix AT_XDMAC_CC_PERID() macro
+    - dmaengine: stm32-dma: fix stm32_dma_get_max_width
+    - NFS: Fix up commit deadlocks
+    - NFS: Fix an Oops in pnfs_mark_request_commit()
+    - Fix user namespace leak
+    - auxdisplay: img-ascii-lcd: Fix lock-up when displaying empty string
+    - auxdisplay: ht16k33: Connect backlight to fbdev
+    - auxdisplay: ht16k33: Fix frame buffer device blanking
+    - soc: fsl: dpaa2-console: free buffer before returning from
+      dpaa2_console_read
+    - netfilter: nfnetlink_queue: fix OOB when mac header was cleared
+    - dmaengine: dmaengine_desc_callback_valid(): Check for `callback_result`
+    - dmaengine: tegra210-adma: fix pm runtime unbalance
+    - dmanegine: idxd: fix resource free ordering on driver removal
+    - dmaengine: idxd: reconfig device after device reset command
+    - signal/sh: Use force_sig(SIGKILL) instead of do_group_exit(SIGKILL)
+    - m68k: set a default value for MEMORY_RESERVE
+    - watchdog: f71808e_wdt: fix inaccurate report in WDIOC_GETTIMEOUT
+    - ar7: fix kernel builds for compiler test
+    - scsi: target: core: Remove from tmr_list during LUN unlink
+    - scsi: qla2xxx: Relogin during fabric disturbance
+    - scsi: qla2xxx: Fix gnl list corruption
+    - scsi: qla2xxx: Turn off target reset during issue_lip
+    - scsi: qla2xxx: edif: Fix app start fail
+    - scsi: qla2xxx: edif: Fix app start delay
+    - scsi: qla2xxx: edif: Flush stale events and msgs on session down
+    - scsi: qla2xxx: edif: Increase ELS payload
+    - scsi: qla2xxx: edif: Fix EDIF bsg
+    - NFSv4: Fix a regression in nfs_set_open_stateid_locked()
+    - dmaengine: idxd: fix resource leak on dmaengine driver disable
+    - i2c: xlr: Fix a resource leak in the error handling path of
+      'xlr_i2c_probe()'
+    - gpio: realtek-otto: fix GPIO line IRQ offset
+    - xen-pciback: Fix return in pm_ctrl_init()
+    - nbd: fix max value for 'first_minor'
+    - nbd: fix possible overflow for 'first_minor' in nbd_dev_add()
+    - io-wq: fix max-workers not correctly set on multi-node system
+    - net: davinci_emac: Fix interrupt pacing disable
+    - kselftests/net: add missed icmp.sh test to Makefile
+    - kselftests/net: add missed setup_loopback.sh/setup_veth.sh to Makefile
+    - kselftests/net: add missed SRv6 tests
+    - kselftests/net: add missed vrf_strict_mode_test.sh test to Makefile
+    - kselftests/net: add missed toeplitz.sh/toeplitz_client.sh to Makefile
+    - ethtool: fix ethtool msg len calculation for pause stats
+    - openrisc: fix SMP tlb flush NULL pointer dereference
+    - net: vlan: fix a UAF in vlan_dev_real_dev()
+    - net: dsa: felix: fix broken VLAN-tagged PTP under VLAN-aware bridge
+    - ice: Fix replacing VF hardware MAC to existing MAC filter
+    - ice: Fix not stopping Tx queues for VFs
+    - kdb: Adopt scheduler's task classification
+    - ACPI: PMIC: Fix intel_pmic_regs_handler() read accesses
+    - PCI: j721e: Fix j721e_pcie_probe() error path
+    - nvdimm/btt: do not call del_gendisk() if not needed
+    - scsi: bsg: Fix errno when scsi_bsg_register_queue() fails
+    - scsi: ufs: ufshpb: Use proper power management API
+    - scsi: ufs: core: Fix NULL pointer dereference
+    - scsi: ufs: ufshpb: Properly handle max-single-cmd
+    - drm/nouveau/svm: Fix refcount leak bug and missing check against null bug
+    - nvdimm/pmem: cleanup the disk if pmem_release_disk() is yet assigned
+    - block/ataflop: use the blk_cleanup_disk() helper
+    - block/ataflop: add registration bool before calling del_gendisk()
+    - block/ataflop: provide a helper for cleanup up an atari disk
+    - ataflop: remove ataflop_probe_lock mutex
+    - PCI: Do not enable AtomicOps on VFs
+    - cpufreq: intel_pstate: Clear HWP desired on suspend/shutdown and offline
+    - net: phy: fix duplex out of sync problem while changing settings
+    - block: fix device_add_disk() kobject_create_and_add() error handling
+    - drm/ttm: remove ttm_bo_vm_insert_huge()
+    - bonding: Fix a use-after-free problem when bond_sysfs_slave_add() failed
+    - octeontx2-pf: select CONFIG_NET_DEVLINK
+    - ALSA: memalloc: Catch call with NULL snd_dma_buffer pointer
+    - mfd: core: Add missing of_node_put for loop iteration
+    - mfd: cpcap: Add SPI device ID table
+    - mfd: sprd: Add SPI device ID table
+    - mfd: altera-sysmgr: Fix a mistake caused by resource_size conversion
+    - ACPI: PM: Fix device wakeup power reference counting error
+    - libbpf: Fix lookup_and_delete_elem_flags error reporting
+    - selftests/bpf/xdp_redirect_multi: Put the logs to tmp folder
+    - selftests/bpf/xdp_redirect_multi: Use arping to accurate the arp number
+    - selftests/bpf/xdp_redirect_multi: Give tcpdump a chance to terminate cleanly
+    - selftests/bpf/xdp_redirect_multi: Limit the tests in netns
+    - drm: fb_helper: improve CONFIG_FB dependency
+    - Revert "drm/imx: Annotate dma-fence critical section in commit path"
+    - drm/amdgpu/powerplay: fix sysfs_emit/sysfs_emit_at handling
+    - can: etas_es58x: es58x_rx_err_msg(): fix memory leak in error path
+    - can: mcp251xfd: mcp251xfd_chip_start(): fix error handling for
+      mcp251xfd_chip_rx_int_enable()
+    - mm/zsmalloc.c: close race window between zs_pool_dec_isolated() and
+      zs_unregister_migration()
+    - zram: off by one in read_block_state()
+    - perf bpf: Add missing free to bpf_event__print_bpf_prog_info()
+    - llc: fix out-of-bound array index in llc_sk_dev_hash()
+    - nfc: pn533: Fix double free when pn533_fill_fragment_skbs() fails
+    - litex_liteeth: Fix a double free in the remove function
+    - arm64: arm64_ftr_reg->name may not be a human-readable string
+    - arm64: pgtable: make __pte_to_phys/__phys_to_pte_val inline functions
+    - bpf, sockmap: Remove unhash handler for BPF sockmap usage
+    - bpf, sockmap: Fix race in ingress receive verdict with redirect to self
+    - bpf: sockmap, strparser, and tls are reusing qdisc_skb_cb and colliding
+    - bpf, sockmap: sk_skb data_end access incorrect when src_reg = dst_reg
+    - dmaengine: stm32-dma: fix burst in case of unaligned memory address
+    - dmaengine: stm32-dma: avoid 64-bit division in stm32_dma_get_max_width
+    - gve: Fix off by one in gve_tx_timeout()
+    - drm/i915/fb: Fix rounding error in subsampled plane size calculation
+    - init: make unknown command line param message clearer
+    - seq_file: fix passing wrong private data
+    - drm/amdgpu: fix uvd crash on Polaris12 during driver unloading
+    - net: dsa: mv88e6xxx: Don't support >1G speeds on 6191X on ports other than
+      10
+    - net/sched: sch_taprio: fix undefined behavior in ktime_mono_to_any
+    - net: hns3: fix ROCE base interrupt vector initialization bug
+    - net: hns3: fix pfc packet number incorrect after querying pfc parameters
+    - net: hns3: fix kernel crash when unload VF while it is being reset
+    - net: hns3: allow configure ETS bandwidth of all TCs
+    - net: stmmac: allow a tc-taprio base-time of zero
+    - net: ethernet: ti: cpsw_ale: Fix access to un-initialized memory
+    - net: marvell: mvpp2: Fix wrong SerDes reconfiguration order
+    - vsock: prevent unnecessary refcnt inc for nonblocking connect
+    - net/smc: fix sk_refcnt underflow on linkdown and fallback
+    - cxgb4: fix eeprom len when diagnostics not implemented
+    - selftests/net: udpgso_bench_rx: fix port argument
+    - thermal: int340x: fix build on 32-bit targets
+    - smb3: do not error on fsync when readonly
+    - ARM: 9155/1: fix early early_iounmap()
+    - ARM: 9156/1: drop cc-option fallbacks for architecture selection
+    - parisc: Fix backtrace to always include init funtion names
+    - parisc: Flush kernel data mapping in set_pte_at() when installing pte for
+      user page
+    - MIPS: fix duplicated slashes for Platform file path
+    - MIPS: fix *-pkg builds for loongson2ef platform
+    - MIPS: Fix assembly error from MIPSr2 code used within MIPS_ISA_ARCH_LEVEL
+    - x86/mce: Add errata workaround for Skylake SKX37
+    - PCI/MSI: Move non-mask check back into low level accessors
+    - PCI/MSI: Destroy sysfs before freeing entries
+    - KVM: x86: move guest_pv_has out of user_access section
+    - posix-cpu-timers: Clear task::posix_cputimers_work in copy_process()
+    - irqchip/sifive-plic: Fixup EOI failed when masked
+    - f2fs: should use GFP_NOFS for directory inodes
+    - f2fs: include non-compressed blocks in compr_written_block
+    - f2fs: fix UAF in f2fs_available_free_memory
+    - ceph: fix mdsmap decode when there are MDS's beyond max_mds
+    - erofs: fix unsafe pagevec reuse of hooked pclusters
+    - drm/i915/guc: Fix blocked context accounting
+    - block: Hold invalidate_lock in BLKDISCARD ioctl
+    - block: Hold invalidate_lock in BLKZEROOUT ioctl
+    - block: Hold invalidate_lock in BLKRESETZONE ioctl
+    - ksmbd: Fix buffer length check in fsctl_validate_negotiate_info()
+    - ksmbd: don't need 8byte alignment for request length in ksmbd_check_message
+    - dmaengine: ti: k3-udma: Set bchan to NULL if a channel request fail
+    - dmaengine: ti: k3-udma: Set r/tchan or rflow to NULL if request fail
+    - dmaengine: bestcomm: fix system boot lockups
+    - net, neigh: Enable state migration between NUD_PERMANENT and NTF_USE
+    - 9p/net: fix missing error check in p9_check_errors
+    - mm/filemap.c: remove bogus VM_BUG_ON
+    - memcg: prohibit unconditional exceeding the limit of dying tasks
+    - mm, oom: pagefault_out_of_memory: don't force global OOM for dying tasks
+    - mm, oom: do not trigger out_of_memory from the #PF
+    - mm, thp: lock filemap when truncating page cache
+    - mm, thp: fix incorrect unmap behavior for private pages
+    - mfd: dln2: Add cell for initializing DLN2 ADC
+    - video: backlight: Drop maximum brightness override for brightness zero
+    - bcache: fix use-after-free problem in bcache_device_free()
+    - bcache: Revert "bcache: use bvec_virt"
+    - PM: sleep: Avoid calling put_device() under dpm_list_mtx
+    - s390/cpumf: cpum_cf PMU displays invalid value after hotplug remove
+    - s390/cio: check the subchannel validity for dev_busid
+    - s390/tape: fix timer initialization in tape_std_assign()
+    - s390/ap: Fix hanging ioctl caused by orphaned replies
+    - s390/cio: make ccw_device_dma_* more robust
+    - remoteproc: elf_loader: Fix loading segment when is_iomem true
+    - remoteproc: Fix the wrong default value of is_iomem
+    - remoteproc: imx_rproc: Fix ignoring mapping vdev regions
+    - remoteproc: imx_rproc: Fix rsc-table name
+    - mtd: rawnand: fsmc: Fix use of SM ORDER
+    - mtd: rawnand: ams-delta: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: xway: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: mpc5121: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: gpio: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: pasemi: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: orion: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: plat_nand: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: au1550nd: Keep the driver compatible with on-die ECC engines
+    - powerpc/vas: Fix potential NULL pointer dereference
+    - powerpc/bpf: Fix write protecting JIT code
+    - powerpc/32e: Ignore ESR in instruction storage interrupt handler
+    - powerpc/powernv/prd: Unregister OPAL_MSG_PRD2 notifier during module unload
+    - powerpc/security: Use a mutex for interrupt exit code patching
+    - powerpc/64s/interrupt: Fix check_return_regs_valid() false positive
+    - powerpc/pseries/mobility: ignore ibm, platform-facilities updates
+    - powerpc/85xx: fix timebase sync issue when CONFIG_HOTPLUG_CPU=n
+    - drm/sun4i: Fix macros in sun8i_csc.h
+    - PCI: Add PCI_EXP_DEVCTL_PAYLOAD_* macros
+    - PCI: aardvark: Fix PCIe Max Payload Size setting
+    - SUNRPC: Partial revert of commit 6f9f17287e78
+    - drm/amd/display: Look at firmware version to determine using dmub on dcn21
+    - media: vidtv: move kfree(dvb) to vidtv_bridge_dev_release()
+    - cifs: fix memory leak of smb3_fs_context_dup::server_hostname
+    - ath10k: fix invalid dma_addr_t token assignment
+    - mmc: moxart: Fix null pointer dereference on pointer host
+    - selftests/x86/iopl: Adjust to the faked iopl CLI/STI usage
+    - selftests/bpf: Fix also no-alu32 strobemeta selftest
+    - arch/cc: Introduce a function to check for confidential computing features
+    - x86/sev: Add an x86 version of cc_platform_has()
+    - x86/sev: Make the #VC exception stacks part of the default stacks storage
+    - media: videobuf2: always set buffer vb2 pointer
+    - media: videobuf2-dma-sg: Fix buf->vb NULL pointer dereference
+    - Linux 5.15.3
+
+  * kernel panic: NULL pointer dereference in wb_timer_f() (LP: #1947557) //
+    Jammy update: v5.15.3 upstream stable release (LP: #1951822)
+    - blk-wbt: prevent NULL pointer dereference in wb_timer_fn
+
+  * Medion Notebook Keyboard not working (LP: #1909814) // Jammy update: v5.15.3
+    upstream stable release (LP: #1951822)
+    - ACPI: resources: Add DMI-based legacy IRQ override quirk
+
+  * Enable CONFIG_INTEL_IOMMU_DEFAULT_ON and
+    CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON on jammy 5.15 (LP: #1951440)
+    - [Config] enable Intel DMA remapping options by default
+
+  * Thinkpad E14 Gen2: Kernel panic with trackpad and trackpoint enabled
+    (LP: #1945590)
+    - SAUCE: Input: elantech - Fix stack out of bound access in
+      elantech_change_report_id()
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: LSM: Specify which LSM to display (using struct cred as input)
+    - SAUCE: selftests/seccomp: fix check of fds being assigned
+    - [Config] enable SUNRPC_DISABLE_INSECURE_ENCTYPES
+    - [Config] updateconfigs following v5.15.3, v5.15.4 import
+
+  * Miscellaneous upstream changes
+    - binder: use cred instead of task for selinux checks
+    - binder: use cred instead of task for getsecid
+    - Revert "UBUNTU: SAUCE: storvsc: use small sg_tablesize on x86"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 22 Nov 2021 13:14:15 +0100
+
+linux (5.15.0-11.11) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-11.11 -proposed tracker (LP: #1950948)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * OOPs on boot: invalid opcode: 0000 [#1] SMP NOPTI (LP: #1942215)
+    - SAUCE: ACPICA: prevent out-of-bound access with buggy DSDT
+    - [Config] disable UBSAN
+    - SAUCE: ACPICA: avoid accessing operands out-of-bounds
+
+  * Jammy update: v5.15.2 upstream stable release (LP: #1950949)
+    - KVM: x86: avoid warning with -Wbitwise-instead-of-logical
+    - Revert "x86/kvm: fix vcpu-id indexed array sizes"
+    - usb: ehci: handshake CMD_RUN instead of STS_HALT
+    - usb: gadget: Mark USB_FSL_QE broken on 64-bit
+    - usb: musb: Balance list entry in musb_gadget_queue
+    - usb-storage: Add compatibility quirk flags for iODD 2531/2541
+    - Revert "proc/wchan: use printk format instead of lookup_symbol_name()"
+    - binder: use euid from cred instead of using task
+    - binder: don't detect sender/target during buffer cleanup
+    - kfence: always use static branches to guard kfence_alloc()
+    - kfence: default to dynamic branch instead of static keys mode
+    - btrfs: fix lzo_decompress_bio() kmap leakage
+    - staging: rtl8712: fix use-after-free in rtl8712_dl_fw
+    - isofs: Fix out of bound access for corrupted isofs image
+    - comedi: dt9812: fix DMA buffers on stack
+    - comedi: ni_usb6501: fix NULL-deref in command paths
+    - comedi: vmk80xx: fix transfer-buffer overflows
+    - comedi: vmk80xx: fix bulk-buffer overflow
+    - comedi: vmk80xx: fix bulk and interrupt message timeouts
+    - staging: r8712u: fix control-message timeout
+    - staging: rtl8192u: fix control-message timeouts
+    - staging: r8188eu: fix memleak in rtw_wx_set_enc_ext
+    - media: staging/intel-ipu3: css: Fix wrong size comparison imgu_css_fw_init
+    - rsi: fix control-message timeout
+    - Linux 5.15.2
+
+  * reuseport_bpf_numa in net from ubuntu_kernel_selftests fails on ppc64le
+    (LP: #1867570)
+    - selftests/net: Fix reuseport_bpf_numa by skipping unavailable nodes
+
+  * Miscellaneous Ubuntu changes
+    - packaging: switch getabis to the linux package name
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (no-up) rename the adv7511 drm driver to adv7511_drm"
+    - Revert "UBUNTU: SAUCE: drm/i915/dp: Use max params for older panels"
+    - Revert "UBUNTU: SAUCE: i915: Fix build error due to missing struct
+      definition"
+    - selftests/core: fix conflicting types compile error for close_range()
+    - selftests: net: test_vxlan_under_vrf: fix HV connectivity test
+    - Revert "UBUNTU: SAUCE: ACPICA: prevent out-of-bound access with buggy DSDT"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 15 Nov 2021 10:12:47 +0100
+
+linux (5.15.0-10.10) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-10.10 -proposed tracker (LP: #1950133)
+
+  * Jammy update: v5.15.1 upstream stable release (LP: #1950131)
+    - sfc: Fix reading non-legacy supported link modes
+    - media: firewire: firedtv-avc: fix a buffer overflow in avc_ca_pmt()
+    - Revert "xhci: Set HCD flag to defer primary roothub registration"
+    - Revert "usb: core: hcd: Add support for deferring roothub registration"
+    - drm/amdkfd: fix boot failure when iommu is disabled in Picasso.
+    - Revert "soc: imx: gpcv2: move reset assert after requesting domain power up"
+    - ARM: 9120/1: Revert "amba: make use of -1 IRQs warn"
+    - Revert "wcn36xx: Disable bmps when encryption is disabled"
+    - drm/amdgpu: revert "Add autodump debugfs node for gpu reset v8"
+    - drm/amd/display: Revert "Directly retrain link from debugfs"
+    - Revert "drm/i915/gt: Propagate change in error status to children on unhold"
+    - ALSA: usb-audio: Add quirk for Audient iD14
+    - Linux 5.15.1
+
+  * Miscellaneous Ubuntu changes
+    - packaging: fixup previous ABI/spin to -9.9
+    - [Packaging] Drop unused d-i build-deps and packaging
+    - [Packaging] Drop now unsupported d-i/ input files
+
+  * Miscellaneous upstream changes
+    - selftests: net: properly support IPv6 in GSO GRE test
+    - signal: Add SA_IMMUTABLE to ensure forced siganls do not get changed
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 08 Nov 2021 14:43:24 +0100
+
+linux (5.15.0-9.9) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-1.1 -proposed tracker (LP: #1949876)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - [Packaging] update Ubuntu.md
+
+  * Add F81966 watchdog support (LP: #1949063)
+    - SAUCE: ODM: watchdog: f71808e_wdt: Add F81966 support
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Rewrite debian/scripts/misc/insert-changes.pl in Python
+    - [Packaging] change source package name to linux
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 04 Nov 2021 18:47:19 +0100
+
+linux (5.15.0-0.0) jammy; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 04 Nov 2021 16:47:16 +0100
+
+linux-unstable (5.15.0-8.8) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.15.0-8.8 -proposed tracker (LP: #1949436)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Drop "UBUNTU: SAUCE: cachefiles: Page leaking in
+    cachefiles_read_backing_file while vmscan is active" (LP: #1947709)
+    - Revert "UBUNTU: SAUCE: cachefiles: Page leaking in
+      cachefiles_read_backing_file while vmscan is active"
+
+  * Add l2tp.sh in net from ubuntu_kernel_selftests back (LP: #1934293)
+    - Revert "UBUNTU: SAUCE: selftests/net -- disable l2tp.sh test"
+
+  * Check for changes relevant for security certifications (LP: #1945989)
+    - [Packaging] Add fips-checks as part of finalchecks
+
+  * Add final-checks to check certificates (LP: #1947174)
+    - [Packaging] Add system trusted and revocation keys final check
+
+  * Can only reach PC3 when ethernet is plugged r8169 (LP: #1946433)
+    - r8169: Enable chip-specific ASPM regardless of PCIe ASPM status
+    - PCI/ASPM: Introduce a new helper to report ASPM capability
+    - r8169: Implement dynamic ASPM mechanism
+
+  * rtw89 kernel module for Realtek 8852 wifi is missing (LP: #1945967)
+    - rtw89: add Realtek 802.11ax driver
+    - rtw89: Remove redundant check of ret after call to rtw89_mac_enable_bb_rf
+    - rtw89: fix return value check in rtw89_cam_send_sec_key_cmd()
+    - rtw89: remove unneeded semicolon
+    - [Config] RTW89=m
+
+  * Fix A yellow screen pops up in an instant (< 1 second) and then disappears
+    before loading the system (LP: #1945932)
+    - drm/i915: Stop force enabling pipe bottom color gammma/csc
+
+  * disable CONFIG_KFENCE_STATIC_KEYS in linux 5.15 (LP: #1948038)
+    - [Config] disable CONFIG_KFENCE_STATIC_KEYS
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Remove old and unused firmware helper scripts
+    - [Packaging] Replace Perl oneliner with Bash statements
+    - rebase to v5.15
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 02 Nov 2021 08:29:45 +0100
+
+linux-unstable (5.15.0-7.7) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.15.0-7.7 -proposed tracker (LP: #1948770)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Temporarily disable signing for ppc64el and s390x
+    - packaging: switch release to Jammy
+    - rebase to v5.15-rc7
+    - [Config] GCC version update
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 26 Oct 2021 11:38:14 +0200
+
+linux-unstable (5.15.0-6.6) jammy; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-6.6 -proposed tracker (LP: #1947565)
+
+  * [impish] Remove the downstream xr-usb-uart driver (LP: #1945938)
+    - SAUCE: xr-usb-serial: remove driver
+    - [Config] update modules list
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.15-rc6
+    - [Config] update config & annotations following v5.15-rc6 rebase
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: xr-usb-serial: switch to tty_alloc_driver() and
+      tty_driver_kref_put()"
+    - Revert "UBUNTU: SAUCE: xr-usb-serial: update return code for
+      xr_usb_serial_tty_write_room() and xr_usb_serial_tty_chars_in_buffer()"
+    - Revert "UBUNTU: [Packaging] FTBFS: disable zfs"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 18 Oct 2021 12:24:45 +0200
+
+linux-unstable (5.15.0-5.5) impish; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-5.5 -proposed tracker (LP: #1946338)
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.15-rc5
+    - [Config] FB_SIMPLE=m
+    - [Config] update annotations
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 11 Oct 2021 12:14:02 +0200
+
+linux-unstable (5.15.0-4.4) impish; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-4.4 -proposed tracker (LP: #1945953)
+
+  * Fix missing HDMI audio on Intel RKL (LP: #1945556)
+    - drm/i915/audio: Use BIOS provided value for RKL HDA link
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: media: atomisp: add missing return type (fix -Werror=return-type)
+    - SAUCE: xr-usb-serial: switch to tty_alloc_driver() and tty_driver_kref_put()
+    - rebase to v5.15-rc4
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] FTBFS: disable INTEL_ATOMISP"
+    - Revert "UBUNTU: [Config] FTBFS: disable xr-usb-serial"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc4
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 04 Oct 2021 10:52:41 +0200
+
+linux-unstable (5.15.0-3.3) impish; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-3.3 -proposed tracker (LP: #1944944)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.15-rc3
+    - [Config] updateconfigs following v5.15-rc3 rebase
+    - [Packaging] correctly evaluate release in update-dkms-versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 27 Sep 2021 16:48:03 +0200
+
+linux-unstable (5.15.0-2.2) impish; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-2.2 -proposed tracker (LP: #1944423)
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.15-rc2
+    - [Config] updateconfigs following v5.15-rc2 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc2
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 21 Sep 2021 11:46:59 +0200
+
+linux-unstable (5.15.0-1.1) impish; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  *  LRMv5: switch primary version handling to kernel-versions data set
+    (LP: #1928921)
+    - [Packaging] switch to kernel-versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] remove remaining references to ports
+    - [Packaging] drop x32 architecture configs
+    - [Config] mark CONFIG_BPF_UNPRIV_DEFAULT_OFF enforced
+    - [Packaging] bump kernel version to 5.15
+    - rebase to v5.15-rc1
+    - [Config] updateconfigs following v5.15-rc1 rebase
+    - [Config] FTBFS: disable INTEL_ATOMISP
+    - [Config] FTBFS: disable xr-usb-serial
+    - [Packaging] FTBFS: disable zfs
+
+  * Miscellaneous upstream changes
+    - Revert "r8169: avoid link-up interrupt issue on RTL8106e if user enables
+      ASPM"
+    - Revert "UBUNTU: SAUCE: RDMA/core: Introduce peer memory interface"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 17 Sep 2021 11:42:25 +0200
+
+linux-unstable (5.15.0-0.0) impish; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 15 Sep 2021 11:54:10 +0200
+
+linux-unstable (5.14.0-9.9) impish; urgency=medium
+
+  * impish/linux-unstable: 5.14.0-9.9 -proposed tracker (LP: #1943022)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] NVIDIA -- Add the NVIDIA 470 driver
+    - [Packaging] NVIDIA: transition -460 and -465 to -470, transition -460-server
+      to -470-server
+
+  * Miscellaneous upstream changes
+    - vt_kdsetmode: extend console locking
+    - Bluetooth: btusb: check conditions before enabling USB ALT 3 for WBS
+    - net: dsa: mt7530: fix VLAN traffic leaks again
+    - btrfs: fix NULL pointer dereference when deleting device by invalid id
+    - Revert "floppy: reintroduce O_NDELAY fix"
+    - fscrypt: add fscrypt_symlink_getattr() for computing st_size
+    - ext4: report correct st_size for encrypted symlinks
+    - f2fs: report correct st_size for encrypted symlinks
+    - ubifs: report correct st_size for encrypted symlinks
+    - net: don't unconditionally copy_from_user a struct ifreq for socket ioctls
+    - audit: move put_tree() to avoid trim_trees refcount underflow and UAF
+    - Linux 5.14.1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 08 Sep 2021 12:20:18 +0200
+
+linux-unstable (5.14.0-8.8) impish; urgency=medium
+
+  * impish/linux-unstable: 5.14.0-8.8 -proposed tracker (LP: #1941887)
+
+  * Fix  Intel AC9560 BT function cannot turn on if BT turn off before S3 entry
+    (LP: #1941696)
+    - SAUCE: Bluetooth: btusb: add a reject table to disable msft
+
+  *  Add USB4 support for AMD SoC (LP: #1941036)
+    - thunderbolt: Add vendor specific NHI quirk for auto-clearing interrupt
+      status
+    - thunderbolt: Handle ring interrupt by reading interrupt status register
+    - thunderbolt: Do not read control adapter config space
+    - thunderbolt: Fix port linking by checking all adapters
+
+  * Support builtin revoked certificates (LP: #1932029)
+    - [Config] Enforce SYSTEM_TRUSTED_KEYS and SYSTEM_REVOCATION_KEYS
+
+  * GPIO error logs in start and dmesg after update of kernel (LP: #1937897)
+    - ODM: mfd: Check AAEON BFPI version before adding device
+
+  * initramfs-tools & kernel: use zstd as the default compression method
+    (LP: #1931725)
+    - [Config] enforce ZSTD compression
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.14
+    - [Config] RESET_MCHP_SPARX5 depends on ARCH_SPARX5
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] FTBFS: disable zfs"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 30 Aug 2021 12:57:19 +0200
+
+linux-unstable (5.14.0-7.7) impish; urgency=medium
+
+  * Please enable CONFIG_UBSAN_BOUNDS (LP: #1914685)
+    - [Config] Enable CONFIG_UBSAN_BOUNDS
+
+  * CONFIG_HARDENED_USERCOPY_FALLBACK should be disabled (LP: #1855340)
+    - [Config] Disable CONFIG_HARDENED_USERCOPY_FALLBACK
+
+  * fs: removing mandatory locks (LP: #1940392)
+    - [Config] Disable CONFIG_MANDATORY_FILE_LOCKING
+
+  * Fix kernel panic caused by legacy devices on AMD platforms (LP: #1936682)
+    - SAUCE: iommu/amd: Keep swiotlb enabled to ensure devices with 32bit DMA
+      still work
+
+  * ALSA: hda/cs8409: Add support for dolphin (LP: #1939541)
+    - ALSA: hda/cirrus: Move CS8409 HDA bridge to separate module
+    - ALSA: hda/cs8409: Move arrays of configuration to a new file
+    - ALSA: hda/cs8409: Use enums for register names and coefficients
+    - ALSA: hda/cs8409: Mask all CS42L42 interrupts on initialization
+    - ALSA: hda/cs8409: Reduce HS pops/clicks for Cyborg
+    - ALSA: hda/cs8409: Disable unnecessary Ring Sense for Cyborg/Warlock/Bullseye
+    - ALSA: hda/cs8409: Disable unsolicited responses during suspend
+    - ALSA: hda/cs8409: Disable unsolicited response for the first boot
+    - ALSA: hda/cs8409: Mask CS42L42 wake events
+    - ALSA: hda/cs8409: Simplify CS42L42 jack detect.
+    - ALSA: hda/cs8409: Prevent I2C access during suspend time
+    - ALSA: hda/cs8409: Generalize volume controls
+    - ALSA: hda/cs8409: Dont disable I2C clock between consecutive accesses
+    - ALSA: hda/cs8409: Avoid setting the same I2C address for every access
+    - ALSA: hda/cs8409: Avoid re-setting the same page as the last access
+    - ALSA: hda/cs8409: Support i2c bulk read/write functions
+    - ALSA: hda/cs8409: Separate CS8409, CS42L42 and project functions
+    - ALSA: hda/cs8409: Move codec properties to its own struct
+    - ALSA: hda/cs8409: Support multiple sub_codecs for Suspend/Resume/Unsol
+      events
+    - ALSA: hda/cs8409: Add Support to disable jack type detection for CS42L42
+    - ALSA: hda/cs8409: Add support for dolphin
+    - ALSA: hda/cs8409: Enable Full Scale Volume for Line Out Codec on Dolphin
+    - ALSA: hda/cs8409: Set fixed sample rate of 48kHz for CS42L42
+    - ALSA: hda/cs8409: Use timeout rather than retries for I2C transaction waits
+    - ALSA: hda/cs8409: Remove unnecessary delays
+    - ALSA: hda/cs8409: Follow correct CS42L42 power down sequence for suspend
+    - ALSA: hda/cs8409: Unmute/Mute codec when stream starts/stops
+    - ALSA: hda/cs8409: Prevent pops and clicks during suspend
+    - SAUCE: ALSA: hda/cs8409: Prevent pops and clicks during reboot
+    - [Config] Enable Cirrus Logic HDA bridge support
+
+  * e1000e: add handshake with the Intel CSME to support S0ix (LP: #1937252)
+    - SAUCE: e1000e: Add handshake with the CSME to support S0ix
+    - SAUCE: e1000e: Add polling mechanism to indicate CSME DPG exit
+    - SAUCE: e1000e: Additional PHY power saving in S0ix
+
+  * AMDGPU: Fix System hang after resume from suspend (LP: #1940204)
+    - SAUCE: drm/amdgpu: disable BACO support for 699F:C7 polaris12 SKU
+      temporarily
+
+  * [Regression] Audio card [8086:9d71] not detected after upgrade from linux
+    5.4 to 5.8 (LP: #1915117)
+    - [Config] set CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to y
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.14-rc7
+    - [Config] updateconfigs following 5.14-rc7 rebase
+    - [Config] Enable CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT
+    - [Config] annotations: set CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT to y
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] annotations: set
+      CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to y"
+    - Revert "UBUNTU: [Config] set CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to
+      y"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 24 Aug 2021 10:32:31 +0200
+
+linux-unstable (5.14.0-6.6) impish; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - no changes upload (to avoid picking up libc6 from -proposed)
+
+  * No changes upload (to avoid picking up libc6 from -proposed)
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 18 Aug 2021 13:41:16 +0200
+
+linux-unstable (5.14.0-5.5) impish; urgency=medium
+
+  * disable “CONFIG_HISI_DMA” config for ubuntu version (LP: #1936771)
+    - [Config] Disable CONFIG_HISI_DMA
+
+  * Dell XPS 17 (9710) PCI/internal sound card not detected  (LP: #1935850)
+    - ASoC: Intel: sof_sdw: include rt711.h for RT711 JD mode
+    - ASoC: Intel: sof_sdw: add quirk for Dell XPS 9710
+
+  * [regression] USB device is not detected during boot (LP: #1939638)
+    - SAUCE: Revert "usb: core: reduce power-on-good delay time of root hub"
+
+  * armhf build failure (LP: #1939308)
+    - SAUCE: arm: Fix instruction set selection for GCC 11
+
+  * REGRESSION: shiftfs lets sendfile fail with EINVAL (LP: #1939301)
+    - SAUCE: shiftfs: fix sendfile() invocations
+
+  * Wobbly graphics on built-in display since linux-image-5.11.0-22-generic
+    (LP: #1936708)
+    - SAUCE: drm/i915/dp: Use max params for older panels
+
+  * [SRU][H/OEM-5.10/OEM-5.13/U] Fix system hang after unplug tbt dock
+    (LP: #1938689)
+    - SAUCE: igc: fix page fault when thunderbolt is unplugged
+
+  * e1000e blocks the boot process when it tried to write checksum to its NVM
+    (LP: #1936998)
+    - SAUCE: e1000e: Do not take care about recovery NVM checksum
+
+  * [Regression] Audio card [8086:9d71] not detected after upgrade from linux
+    5.4 to 5.8 (LP: #1915117)
+    - [Config] set CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to y
+    - [Config] annotations: set CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to y
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs following 5.14-rc6 rebase
+    - rebase to v5.14-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 17 Aug 2021 17:49:15 +0200
+
+linux-unstable (5.14.0-4.4) impish; urgency=medium
+
+  * impish/linux-unstable: 5.14.0-4.4 -proposed tracker (LP: #1938566)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous upstream changes
+    - Revert "riscv: Get CPU manufacturer information"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 03 Aug 2021 14:50:27 +0200
+
+linux-unstable (5.14.0-3.3) impish; urgency=medium
+
+  * Add additional Mediatek MT7921 WiFi/BT device IDs (LP: #1937004)
+    - SAUCE: Bluetooth: btusb: Add Mediatek MT7921 support for Foxconn
+    - SAUCE: Bluetooth: btusb: Add Mediatek MT7921 support for IMC Network
+    - SAUCE: Bluetooth: btusb: Add support for Foxconn Mediatek Chip
+
+  * Fix display output on HP hybrid GFX laptops (LP: #1936296)
+    - drm/i915: Invoke another _DSM to enable MUX on HP Workstation laptops
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.14-rc3
+    - [Config] updateconfigs following 5.14-rc3 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 26 Jul 2021 12:52:38 +0200
+
+linux-unstable (5.14.0-2.2) impish; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: xr-usb-serial: update return code for xr_usb_serial_tty_write_room()
+      and xr_usb_serial_tty_chars_in_buffer()
+    - SAUCE: platform/x86: dell-uart-backlight: update return code for
+      uart_chars_in_buffer(()
+    - [Config] updateconfigs following 5.14-rc2 rebase
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] FTBFS: disable ubuntu/xr-usb-serial"
+    - Revert "UBUNTU: [Config] FTBFS: disable DELL_UART_BACKLIGHT"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc2
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 22 Jul 2021 11:03:28 +0200
+
+linux-unstable (5.14.0-1.1) impish; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] bump kernel version to 5.14
+    - [Config] updateconfigs following 5.14-rc1 rebase
+    - [Config] update annotations
+    - [Packaging] FTBFS: disable zfs
+    - [Config] FTBFS: disable DELL_UART_BACKLIGHT
+    - [Config] FTBFS: disable ubuntu/xr-usb-serial
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] update variants"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 16 Jul 2021 15:20:04 +0200
+
+linux-unstable (5.14.0-0.0) impish; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 13 Jul 2021 12:15:35 +0200
+
+linux (5.13.0-11.11) impish; urgency=medium
+
+  * impish/linux: 5.13.0-11.11 -proposed tracker (LP: #1933854)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Support builtin revoked certificates (LP: #1932029)
+    - [Packaging] build canonical-revoked-certs.pem from branch/arch certs
+    - [Packaging] Revoke 2012 UEFI signing certificate as built-in
+    - [Config] Configure CONFIG_SYSTEM_REVOCATION_KEYS with revoked keys
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Change source package name to linux
+
+  * Miscellaneous upstream changes
+    - mm/page_alloc: Correct return value of populated elements if bulk array is
+      populated
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 29 Jun 2021 07:50:25 +0200
+
+linux (5.13.0-10.10) impish; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Jun 2021 08:40:05 +0200
+
+linux-unstable (5.13.0-10.10) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-10.10 -proposed tracker (LP: #1933795)
+
+  * Pixel format change broken for Elgato Cam Link 4K (LP: #1932367)
+    - media: uvcvideo: Fix pixel format change for Elgato Cam Link 4K
+
+  * initramfs-tools & kernel: use zstd as the default compression method
+    (LP: #1931725)
+    - s390/decompressor: correct BOOT_HEAP_SIZE condition
+    - s390/boot: add zstd support
+    - [Packaging] use ZSTD to compress s390 kernels
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: tls: fix chacha+bidir tests
+    - SAUCE: selftests: icmp_redirect: support expected failures
+    - [Config] update configs and annotations after rebase to 5.13
+
+  * Miscellaneous upstream changes
+    - tls: prevent oversized sendfile() hangs by ignoring MSG_MORE
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Jun 2021 08:40:05 +0200
+
+linux-unstable (5.13.0-9.9) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-9.9 -proposed tracker (LP: #1933070)
+
+  * Add support for selective build of special drivers (LP: #1912789)
+    - [Packaging] Add support for ODM drivers
+    - [Packaging] Turn on ODM support for amd64
+    - [Packaging] Fix ODM support in actual build
+    - [Packaging] Fix ODM DRIVERS Kconfig
+
+  * Add support for IO functions of AAEON devices (LP: #1929504)
+    - ODM: [Config] update config for AAEON devices
+    - ODM: hwmon: add driver for AAEON devices
+    - ODM: leds: add driver for AAEON devices
+    - ODM: watchdog: add driver for AAEON devices
+    - ODM: gpio: add driver for AAEON devices
+    - ODM: mfd: Add support for IO functions of AAEON devices
+
+  * Disable hv-kvp-daemon.service on certain instance types (LP: #1932081)
+    - [Packaging]: Add kernel command line condition to hv-kvp-daemon service
+
+  * Fix non-working GPU on Some HP desktops (LP: #1931147)
+    - PCI: Coalesce host bridge contiguous apertures
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: seccomp: bump up timeout to 5min
+    - SAUCE: Revert "net/tls(TLS_SW): Add selftest for 'chunked' sendfile test"
+    - [Config] update annotations after rebase to 5.13-rc7
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 21 Jun 2021 10:55:36 +0200
+
+linux-unstable (5.13.0-8.8) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-8.8 -proposed tracker (LP: #1932018)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * initramfs-tools & kernel: use zstd as the default compression method
+    (LP: #1931725)
+    - [Config] use ZSTD to compress amd64 kernels
+
+  * Miscellaneous Ubuntu changes
+    - [Config] enable signing for ppc64el
+    - SAUCE: powerpc: Fix initrd corruption with relative jump labels
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 15 Jun 2021 15:07:34 +0200
+
+linux-unstable (5.13.0-7.7) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-7.7 -proposed tracker (LP: #1931840)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+    - [Packaging] resync getabis
+    - [Packaging] update helper scripts
+    - update dkms package versions
+
+  * Intel ADL-S graphics feature enabling (LP: #1931240)
+    - SAUCE: drm/i915/adl_s: ADL-S platform Update PCI ids for Mobile BGA
+
+  * Kernel package builds running out of space on builders (LP: #1930713)
+    - [Config] CONFIG_DEBUG_INFO_COMPRESSED=n
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] remove nvidia dkms build support
+    - [Config] remove now unsued do_dkms_nvidia* build variables
+    - [Config] enable signing for s390x
+    - [Config] update annotations after configs review
+    - [Config] update toolchain versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 14 Jun 2021 11:53:08 +0200
+
+linux-unstable (5.13.0-6.6) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-6.6 -proposed tracker (LP: #1931071)
+
+  * Kernel package builds running out of space on builders (LP: #1930713)
+    - [Debian] use stamps for flavour install targets
+    - [Debian] run install-$(flavour) targets during build phase
+    - [Debian] remove dh_testroot from install targets
+    - [Debian] dkms-build -- use fakeroot if not running as root
+    - [Debian] exclude $(DEBIAN)/__abi.current from linux-source
+
+  * [UBUNTU 21.04] tools/kvm_stat: Add restart delay (LP: #1921870)
+    - [Debian] install kvm_stat systemd service
+
+  * Debugging symbols (dbgsym) packages are missing GDB kernel scripts
+    (LP: #1928715)
+    - [Packaging] Build and include GDB Python scripts into debug packages
+
+  * Can't detect intel wifi 6235 (LP: #1920180)
+    - SAUCE: iwlwifi: add new pci id for 6235
+
+  * Select correct boot VGA when BIOS doesn't do it properly (LP: #1929217)
+    - vgaarb: Use ACPI HID name to find integrated GPU
+
+  * Fix kernel panic on Intel Bluetooth (LP: #1928838)
+    - Bluetooth: Shutdown controller after workqueues are flushed or cancelled
+
+  * build module CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH=m for 5.11,  5.13-rc2
+    and later (LP: #1921632)
+    - [Config] enable soundwire audio mach driver
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_SND_SOC_RT1308 can only be enabled on amd64
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 07 Jun 2021 10:45:13 +0200
+
+linux-unstable (5.13.0-5.5) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-5.5 -proposed tracker (LP: #1930205)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Config] set CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 31 May 2021 12:32:38 +0200
+
+linux-unstable (5.13.0-4.4) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-4.4 -proposed tracker (LP: #1929404)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Support importing mokx keys into revocation list from the mok table
+    (LP: #1928679)
+    - SAUCE: integrity: add informational messages when revoking certs
+
+  * Support importing mokx keys into revocation list from the mok table
+    (LP: #1928679) // CVE-2020-26541 when certificates are revoked via
+    MokListXRT.
+    - SAUCE: integrity: Load mokx certs from the EFI MOK config table
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Temporarily disable signing for ppc64el and s390x
+    - SAUCE: Revert "UBUNTU: SAUCE: overlayfs: Be more careful about copying up
+      sxid files"
+    - SAUCE: Revert "UBUNTU: SAUCE: overlayfs: Propogate nosuid from lower and
+      upper mounts"
+    - SAUCE: Revert "UBUNTU: SAUCE: overlayfs: Enable user namespace mounts"
+    - SAUCE: Revert "UBUNTU: SAUCE: overlayfs: ensure mounter privileges when
+      reading directories"
+    - SAUCE: Revert "UBUNTU: SAUCE: fs: Move SB_I_NOSUID to the top of s_iflags"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 24 May 2021 13:06:17 +0200
+
+linux-unstable (5.13.0-3.3) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-3.3 -proposed tracker (LP: #1928655)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 17 May 2021 11:55:02 +0200
+
+linux-unstable (5.13.0-2.2) impish; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] enable CONFIG_DEBUG_INFO_COMPRESSED
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] temporarily disable BPF JIT"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 14 May 2021 09:19:02 +0200
+
+linux-unstable (5.13.0-1.1) impish; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 12 May 2021 11:35:23 +0200
+
+linux-unstable (5.13.0-0.0) impish; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 11 May 2021 08:40:09 +0200
+
+linux-unstable (5.12.0-11.11) impish; urgency=medium
+
+  * Impish update: v5.12.1 upstream stable release (LP: #1927094)
+    - net: hso: fix NULL-deref on disconnect regression
+    - USB: CDC-ACM: fix poison/unpoison imbalance
+    - iwlwifi: Fix softirq/hardirq disabling in iwl_pcie_gen2_enqueue_hcmd()
+    - cfg80211: fix locking in netlink owner interface destruction
+    - mei: me: add Alder Lake P device id.
+    - Linux 5.12.1
+
+  * Packaging resync (LP: #1786013) // Impish update: v5.12.1 upstream stable
+    release (LP: #1927094)
+    - update dkms package versions
+
+  * Gigabyte R120-T33 (ARM ThunderX SoC) fails to boot in ACPI mode
+    (LP: #1925075) // Impish update: v5.12.1 upstream stable release
+    (LP: #1927094)
+    - ACPI: GTDT: Don't corrupt interrupt mappings on watchdow probe failure
+
+  * Fix kernel panic at boot on dual GFX systems (LP: #1926792) // Impish
+    update: v5.12.1 upstream stable release (LP: #1927094)
+    - drm/amdgpu: Register VGA clients after init can no longer fail
+
+  * On TGL platforms screen shows garbage when browsing website by scrolling
+    mouse (LP: #1926579) // Impish update: v5.12.1 upstream stable release
+    (LP: #1927094)
+    - SAUCE: drm/i915/display: Disable PSR2 if TGL Display stepping is B1 from A0
+
+  * CirrusLogic: Cracking noises appears in built-in speaker when output volume
+    is set >80% (LP: #1924997) // Impish update: v5.12.1 upstream stable release
+    (LP: #1927094)
+    - SAUCE: ALSA: hda/cirrus: Use CS8409 Equalizer to fix abnormal sounds on
+      Bullseye
+
+  * Enable mute/micmute LEDs and limit mic boost on EliteBook 845 G8
+    (LP: #1925415) // Impish update: v5.12.1 upstream stable release
+    (LP: #1927094)
+    - ALSA: hda/realtek: Enable mute/micmute LEDs and limit mic boost on EliteBook
+      845 G8
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: PCI: Disable broken RTIT_BAR of Intel TH"
+    - Revert "UBUNTU: [Config] temporarily disable ZFS"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 04 May 2021 18:35:54 +0200
+
+linux-unstable (5.12.0-10.10) impish; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Drop versioned ABI directory names
+    - [Packaging] getabis: Download ABIs into an unversioned directory
+    - [Packaging] final-checks: Handle unversioned ABI directories
+    - bump to impish
+    - [Config] GCC version update
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 29 Apr 2021 12:27:20 +0200
+
+linux-unstable (5.12.0-9.9) impish; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 26 Apr 2021 11:14:16 -0500
+
+linux-unstable (5.12.0-8.8) hirsute; urgency=medium
+
+  * CVE-2021-3492
+    - SAUCE: shiftfs: free allocated memory in shiftfs_btrfs_ioctl_fd_replace()
+      error paths
+    - SAUCE: shiftfs: handle copy_to_user() return values correctly
+
+  * Fix no picture from HDMI when it's plugged after boot (LP: #1924238)
+    - drm/i915/display: Handle lane polarity for DDI port
+
+  * hirsute beta desktop AMD64 ISO kernel panic on boot when booting using UEFI
+    (LP: #1922403)
+    - SAUCE: efifb: Check efifb_pci_dev before using it
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v5.12-rc8
+    - [Config] updateconfigs following 5.12-rc8 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc8
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 19 Apr 2021 11:37:27 +0200
+
+linux-unstable (5.12.0-7.7) hirsute; urgency=medium
+
+  * drm/i915: Drop force_probe requirement for Rocket Lake (LP: #1905466)
+    - drm/i915/rkl: Remove require_force_probe protection
+
+  * HP m400 cartridges fail to find NIC when deploying hirsute (LP: #1918793)
+    - PCI: xgene: Fix cfg resource mapping
+
+  * Update - Fix no screen show on display after S3 on CML-R  (LP: #1922768)
+    - drm/i915/gen9bc: Handle TGP PCH during suspend/resume
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: RDMA/core: Introduce peer memory interface
+    - Rebase to v5.12-rc7
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 12 Apr 2021 11:48:07 +0200
+
+linux-unstable (5.12.0-6.6) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * i915 doesn't support some high pixel clock 4k * 60Hz monitors (LP: #1922372)
+    - drm/i915/vbt: update DP max link rate table
+
+  * Tegra "mmc0: Timeout waiting for hardware interrupt" (LP: #1921140)
+    - SAUCE: mmc: host: Add required callbacks to set/clear CQE_EN bit
+
+  * Enable ath11k debugfs/tracing (LP: #1922033)
+    - [Config] enable ath11k debugfs/tracing
+
+  * Fix mic on P620 after S3 resume (LP: #1921757)
+    - ALSA: usb-audio: Carve out connector value checking into a helper
+    - ALSA: usb-audio: Check connector value on resume
+
+  * Miscellaneous Ubuntu changes
+    - [Config] amd64,arm64: build KFENCE support but disable it by default
+      (KFENCE_SAMPLE_INTERVAL=0)
+    - Rebase to v5.12-rc6
+
+  * Miscellaneous upstream changes
+    - drm/dp: add MSO related DPCD registers
+    - drm/i915/edp: reject modes with dimensions other than fixed mode
+    - drm/i915/edp: always add fixed mode to probed modes in ->get_modes()
+    - drm/i915/edp: read sink MSO configuration for eDP 1.4+
+    - drm/i915/reg: add stream splitter configuration definitions
+    - drm/i915/mso: add splitter state readout for platforms that support it
+    - drm/i915/mso: add splitter state check
+    - drm/i915/edp: modify fixed and downclock modes for MSO
+    - drm/i915/edp: enable eDP MSO during link training
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 07 Apr 2021 11:42:55 +0200
+
+linux-unstable (5.12.0-5.5) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * alsa/realtek: extend the delay time in the  determine_headset_type for a
+    Dell AIO (LP: #1920747)
+    - SAUCE: ALSA: hda/realtek: fix a determine_headset_type issue for a Dell AIO
+
+  * power off stress test will hang on the TGL machines (LP: #1919930)
+    - SAUCE: ASoC: SOF: Intel: TGL: set shutdown callback to hda_dsp_shutdown
+    - [Config] set SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1 to n
+
+  * lockdown on power (LP: #1855668)
+    - SAUCE: (lockdown) powerpc: lock down kernel in secure boot mode
+
+  * Miscellaneous Ubuntu changes
+    - [Config] arm64 -- unify build_image and kernel_file values
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - SAUCE: xr-usb-serial: clean up indentation
+    - SAUCE: xr-usb-serial: clean up build warnings
+    - SAUCE: apparmor: Fix build error, make sk parameter const
+    - Rebase to v5.12-rc5
+    - [Config] updateconfigs following v5.12-rc5 rebase
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (lockdown) s390: Lock down the kernel when the IPL
+      secure flag is set"
+    - Revert "UBUNTU: SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to
+      indicate secure boot mode"
+    - Revert "UBUNTU: SAUCE: (lockdown) powerpc: lock down kernel in secure boot
+      mode"
+    - Revert "UBUNTU: SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic"
+    - Revert "UBUNTU: SAUCE: (lockdown) arm64: Allow locking down the kernel under
+      EFI secure boot"
+    - Revert "UBUNTU: SAUCE: (lockdown) KEYS: Make use of platform keyring for
+      module signature verify"
+    - Revert "UBUNTU: SAUCE: (lockdown) efi: Lock down the kernel if booted in
+      secure boot mode"
+    - Revert "UBUNTU: SAUCE: (lockdown) security: lockdown: expose a hook to lock
+      the kernel down"
+    - Revert "UBUNTU: SAUCE: (lockdown) Make get_cert_list() use
+      efi_status_to_str() to print error messages."
+    - Revert "UBUNTU: SAUCE: (lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err()."
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 29 Mar 2021 12:59:38 +0200
+
+linux-unstable (5.12.0-4.4) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Fix broken efifb on graphics device without driver (LP: #1914411)
+    - SAUCE: efifb: Ensure graphics device for efifb stays at PCI D0
+
+  * Fix system sleep on TGL systems with Intel ME (LP: #1919321)
+    - SAUCE: PCI: Serialize TGL e1000e PM ops
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v5.12-rc4
+    - [Config] updateconfigs following v5.12-rc4 rebase
+
+  * Miscellaneous upstream changes
+    - riscv: dts: fu740: fix cache-controller interrupts
+    - riscv: sifive: fu740: cpu{1, 2, 3, 4} set compatible to sifive, u74-mc
+    - riscv: sifive: unmatched: update for 16GB rev3
+    - riscv: Add 3 SBI wrapper functions to get cpu manufacturer information
+    - riscv: Get CPU manufacturer information
+    - riscv: Introduce alternative mechanism to apply errata solution
+    - riscv: sifive: apply errata "cip-453" patch
+    - clk: sifive: Add pcie_aux clock in prci driver for PCIe driver
+    - clk: sifive: Use reset-simple in prci driver for PCIe driver
+    - MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver
+    - dt-bindings: PCI: Add SiFive FU740 PCIe host controller
+    - PCI: designware: Add SiFive FU740 PCIe host controller driver
+    - riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc4
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 22 Mar 2021 12:43:14 +0100
+
+linux-unstable (5.12.0-3.3) hirsute; urgency=medium
+
+  *  riscv: revert SiFive Unleashed CPUFreq (LP: #1917433)
+    - SAUCE: Revert "SiFive Unleashed CPUFreq"
+
+  * Dell Precision 5550 takes up to 10 seconds to respond when coming out of
+    sleep (LP: #1919123)
+    - SAUCE: Input: i8042 - add dmi quirk
+
+  * LRMv4: switch to signing nvidia modules via the Ubuntu Modules signing key
+    (LP: #1918134)
+    - [Packaging] sync dkms-build et al from LRMv4
+
+  * curtin: install flash-kernel in arm64 UEFI unexpected (LP: #1918427)
+    - [Packaging] Allow grub-efi-arm* to satisfy recommends on ARM
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Enable Tegra support in arm64 for NVIDIA Jetson (LP: #1918471)
+    - [Config] enable ARCH_TEGRA and all Tegra SOC's
+    - [Packaging] include modern Tegra modules
+
+  * Cirrus Audio Codec CS8409/CS42L42: Input Device does not switch to headset
+    Mic when a headset is inserted (LP: #1918378)
+    - SAUCE: ALSA: hda/cirrus: Fix Headset Mic volume control name
+
+  * Cirrus Audio Codec CS8409/CS42L42 support (LP: #1916554)
+    - ALSA: hda/cirrus: Increase AUTO_CFG_MAX_INS from 8 to 18
+    - ALSA: hda/cirrus: Add support for CS8409 HDA bridge and CS42L42 companion
+      codec.
+    - ALSA: hda/cirrus: Add jack detect interrupt support from CS42L42 companion
+      codec.
+    - ALSA: hda/cirrus: Add Headphone and Headset MIC Volume Control
+
+  * drm/i915: Drop force_probe requirement for JSL (LP: #1917843)
+    - SAUCE: drm/i915: Drop require_force_probe from JSL
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Skip d-i code if udebs are disabled
+    - [Packaging] Disable udebs if $DEBIAN/d-i doesn't exist
+    - [Packaging] remove dh-systemd build dependency
+    - [Config] fix several annotaions with enforcement typos
+    - [Config] refresh annotations
+    - [Config] updateconfigs following v5.12-rc3 rebase
+    - annotations: fixup after v5.12-rc3 rebase
+    - Rebase to v5.12-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 16 Mar 2021 18:43:03 +0100
+
+linux-unstable (5.12.0-2.2) hirsute; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v5.12-rc2
+    - [Config] updateconfigs following v5.12-rc2 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc2
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 08 Mar 2021 11:22:04 +0100
+
+linux-unstable (5.12.0-1.1) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Support no udeb profile (LP: #1916095)
+    - [Packaging] replace custom filter script with dctrl-tools
+    - [Packaging] correctly implement noudeb build profiles.
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] dkms-versions -- remove nvidia-graphics-drivers-440-server
+    - [Debian] run ubuntu-regression-suite for linux-unstable
+    - [Packaging] remove Provides: aufs-dkms
+    - [Config] update config and annotations following v5.12-rc1 rebase
+    - [Config] disable nvidia and nvidia_server builds
+    - [Config] temporarily disable ZFS
+    - temporarily disable modules check
+    - annotations: s390: temporarily remove CONFIG_KMSG_IDS
+    - [Config] amd64: FTBFS: disable HIO
+    - [Config] FTBFS: disable SHIFT_FS
+    - [Config] s390: temporarily remove CONFIG_KMSG_IDS
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] disable nvidia and nvidia_server builds"
+    - Revert "UBUNTU: SAUCE: s390: kernel message catalog"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 04 Mar 2021 18:26:12 +0100
+
+linux-unstable (5.12.0-0.0) hirsute; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 04 Mar 2021 18:17:32 +0100
+
+linux-unstable (5.11.0-10.11) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Support CML-S CPU + TGP PCH (LP: #1909457)
+    - drm/i915/rkl: new rkl ddc map for different PCH
+    - SAUCE: drm/i915/gen9_bc : Add TGP PCH support
+
+  * Use DCPD to control HP DreamColor panel (LP: #1911001)
+    - SAUCE: drm/dp: Another HP DreamColor panel brigntness fix
+
+  * Update nvidia dkms build for module linker script changes
+    - [Packaging] build-dkms--nvidia-N -- Update for preprocessed module linker
+      script
+
+  * Please trust Canonical Livepatch Service kmod signing key (LP: #1898716)
+    - [Config] enable CONFIG_MODVERSIONS=y
+    - [Packaging] build canonical-certs.pem from branch/arch certs
+    - [Config] add Canonical Livepatch Service key to SYSTEM_TRUSTED_KEYS
+    - [Config] add ubuntu-drivers key to SYSTEM_TRUSTED_KEYS
+
+  * Miscellaneous Ubuntu changes
+    - [Config] re-enable nvidia dkms
+    - SAUCE: selftests: memory-hotplug: bump timeout to 10min
+    - [Debian] update-aufs.sh -- Don't apply tmpfs-idr.patch
+    - [Config] Update configs
+    - [Config] disable nvidia and nvidia_server builds
+    - SAUCE: Import aufs driver
+    - [Config] CONFIG_AUFS_FS=n
+    - [Config] refresh annotations file
+    - [Config] set CONFIG_MIPI_I3C_HCI=m consistently
+    - [Config] set CONFIG_PINCTRL_MSM8953=m on armhf generic-lpae
+    - [Packaging] Change source package name to linux-unstable
+    - [Config] update LD_VERSION in config due to toolchain update
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: tmpfs: Don't use 64-bit inodes by defulat with 32-bit
+      ino_t"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 22 Feb 2021 07:18:07 +0100
+
+linux-unstable (5.11.0-9.10) hirsute; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 22 Feb 2021 07:02:45 +0100
+
+linux (5.11.0-9.10) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs/annotations after rebase to 5.11
+    - zfs-modules.ignore: add zzstd
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 15 Feb 2021 16:29:36 +0100
+
+linux (5.11.0-8.9) hirsute; urgency=medium
+
+  * Missing device id for Intel TGL-H ISH [8086:43fc] in intel-ish-hid driver
+    (LP: #1914543)
+    - SAUCE: HID: intel-ish-hid: ipc: Add Tiger Lake H PCI device ID
+
+  *  Add support for new Realtek ethernet NIC (LP: #1914604)
+    - r8169: Add support for another RTL8168FP
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: tmpfs: Don't use 64-bit inodes by defulat with 32-bit ino_t
+    - [Config] Set CONFIG_TMPFS_INODE64=n for s390x
+    - [Config] re-enable ZFS
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 08 Feb 2021 11:56:23 +0100
+
+linux (5.11.0-7.8) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  *  Boot fails: failed to validate module [nls_iso8859_1] BTF: -22
+    (LP: #1911359)
+    - SAUCE: x86/entry: build thunk_$(BITS) only if CONFIG_PREEMPTION=y
+
+  * Remove scary stack trace from Realtek WiFi driver (LP: #1913263)
+    - rtw88: reduce the log level for failure of tx report
+
+  * Fix unexpected AER/DPC on PCH400 and PCH500 (LP: #1913691)
+    - Revert "UBUNTU: SAUCE: PCI: Enable ACS quirk on all CML root ports"
+    - Revert "UBUNTU: SAUCE: PCI: Enable ACS quirk on CML root port"
+    - SAUCE: PCI/AER: Disable AER interrupt during suspend
+    - SAUCE: PCI/DPC: Disable DPC interrupt during suspend
+
+  * switch to an autogenerated nvidia series based core via dkms-versions
+    (LP: #1912803)
+    - [Packaging] nvidia -- use dkms-versions to define versions built
+    - [Packaging] update-version-dkms -- maintain flags fields
+
+  * Introduce the new NVIDIA 460-server series and update the 460 series
+    (LP: #1913200)
+    - [Config] dkms-versions -- add the 460-server nvidia driver
+
+  * Fix the video can't output through WD19TB connected with TGL platform during
+    cold-boot (LP: #1910211)
+    - SAUCE: drm/i915/dp: Prevent setting LTTPR mode if no LTTPR is detected
+
+  * Stop using get_scalar_status command in Dell AIO uart backlight driver
+    (LP: #1865402)
+    - SAUCE: platform/x86: dell-uart-backlight: add get_display_mode command
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/seccomp: Accept any valid fd in user_notification_addfd
+    - [Packaging] Don't disable CONFIG_DEBUG_INFO in headers packages
+    - [Config] update configs/annotations after rebase to 5.11-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 01 Feb 2021 10:27:52 +0100
+
+linux (5.11.0-6.7) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Prevent thermal shutdown during boot process (LP: #1906168)
+    - thermal/drivers/acpi: Use hot and critical ops
+    - thermal/core: Remove notify ops
+    - thermal: int340x: Fix unexpected shutdown at critical temperature
+    - thermal: intel: pch: Fix unexpected shutdown at critical temperature
+
+  * riscv: backport support for SiFive Unmatched (LP: #1910965)
+    - RISC-V: Update l2 cache DT documentation to add support for SiFive FU740
+    - RISC-V: sifive_l2_cache: Update L2 cache driver to support SiFive FU740
+    - dt-bindings: riscv: Update DT binding docs to support SiFive FU740 SoC
+    - riscv: dts: add initial support for the SiFive FU740-C000 SoC
+    - dt-bindings: riscv: Update YAML doc to support SiFive HiFive Unmatched board
+    - riscv: dts: add initial board data for the SiFive HiFive Unmatched
+    - PCI: microsemi: Add host driver for Microsemi PCIe controller
+    - Microsemi PCIe expansion board DT entry.
+    - SiFive Unleashed CPUFreq
+    - SiFive HiFive Unleashed: Add PWM LEDs (D1, D2, D3, D4)
+
+  * initramfs unpacking failed (LP: #1835660)
+    - lib/decompress_unlz4.c: correctly handle zero-padding around initrds.
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to 5.11-rc5
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 25 Jan 2021 09:31:31 +0100
+
+linux (5.11.0-5.6) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update config and annotations after rebase to 5.11-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 18 Jan 2021 10:46:10 +0100
+
+linux (5.11.0-4.5) hirsute; urgency=medium
+
+  *  Boot fails: failed to validate module [nls_iso8859_1] BTF: -22
+    (LP: #1911359)
+    - SAUCE: x86/entry: build thunk_$(BITS) only if CONFIG_PREEMPTION=y
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 14 Jan 2021 12:53:26 +0100
+
+linux (5.11.0-3.4) hirsute; urgency=medium
+
+  *  Boot fails: failed to validate module [nls_iso8859_1] BTF: -22
+    (LP: #1911359)
+    - bpf: Allow empty module BTFs
+    - libbpf: Allow loading empty BTFs
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 14 Jan 2021 07:43:45 +0100
+
+linux (5.11.0-2.3) hirsute; urgency=medium
+
+  * DMI entry syntax fix for Pegatron / ByteSpeed C15B (LP: #1910639)
+    - Input: i8042 - unbreak Pegatron C15B
+
+  * SYNA30B4:00 06CB:CE09 Mouse  on HP EliteBook 850 G7 not working at all
+    (LP: #1908992)
+    - HID: multitouch: Enable multi-input for Synaptics pointstick/touchpad device
+
+  * debian/scripts/file-downloader does not handle positive failures correctly
+    (LP: #1878897)
+    - [Packaging] file-downloader not handling positive failures correctly
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * CVE-2021-1052 // CVE-2021-1053
+    - [Packaging] NVIDIA -- Add the NVIDIA 460 driver
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Remove nvidia-455 dkms build
+    - SAUCE: ALSA: hda/realtek: fix right sounds and mute/micmute LEDs for HP
+      machines
+    - [Config] update configs and annotations after rebase to 5.11-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 11 Jan 2021 09:52:27 +0100
+
+linux (5.11.0-1.2) hirsute; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 07 Jan 2021 16:57:01 +0100
+
+linux (5.11.0-0.1) hirsute; urgency=medium
+
+  * dep-8 ubuntu-regression-suite tests are not run for all linux-hwe-* kernels
+    (LP: #1908529)
+    - [dep-8] Allow all hwe kernels
+
+  * Fix reading speed and duplex sysfs on igc device (LP: #1906851)
+    - igc: Report speed and duplex as unknown when device is runtime suspended
+
+  * rtwpci driver blocks the system to enter PC10, stuck at PC3 (LP: #1907200)
+    - SAUCE: rtw88: 8723de: let cpu enter c10
+
+  * [21.04 FEAT] Deactivate CONFIG_QETH_OSN kernel config option (LP: #1906370)
+    - [Config] Deactivate CONFIG_QETH_OSN kernel config option
+
+  * Add dpcd backlight control for 0x4c83 0x4f41 (LP: #1905663)
+    - SAUCE: drm/dp: Add dpcd backlight control for 0x4c83 0x4f41
+
+  * disable building bpf selftests (LP: #1908144)
+    - SAUCE: selftests/bpf: Clarify build error if no vmlinux
+    - SAUCE: selftests: Skip BPF selftests by default
+    - disable building bpf selftests (no VMLINUX_BTF)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - [Config] update configs and annotations after rebase to v5.11-rc1
+    - hio: fix build error with kernel 5.11
+    - SAUCE: shiftfs: fix build error with 5.11
+    - [Config] temporarily disable ZFS
+    - check-aliases: do not error if modules.alias does not exist
+    - ppc64el: don't build stripped vdso
+
+  * Miscellaneous upstream changes
+    - irq: export irq_check_status_bit
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 04 Jan 2021 09:17:48 +0100
+
+linux (5.11.0-0.0) hirsute; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 30 Dec 2020 09:04:41 +0100
+
+linux (5.10.0-9.10) hirsute; urgency=medium
+
+  * Use INTx for Pericom USB controllers (LP: #1906839)
+    - PCI: Disable MSI for Pericom PCIe-USB adapter
+
+  * disable building bpf selftests (LP: #1908144)
+    - SAUCE: selftests/bpf: clarify build error if no vmlinux
+    - SAUCE: selftests: Skip BPF seftests by default
+    - disable building bpf selftests (no VMLINUX_BTF)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Enable CONFIG_BPF_LSM
+
+  * Miscellaneous upstream changes
+    - Revert "md: change mddev 'chunk_sectors' from int to unsigned"
+    - Revert "dm raid: fix discard limits for raid1 and raid10"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 15 Dec 2020 10:16:14 +0100
+
+linux (5.10.0-8.9) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Fix bpf selftest compilation with clang 11
+    - bpf: Fix selftest compilation on clang 11
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to v5.10
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 14 Dec 2020 08:57:57 +0100
+
+linux (5.10.0-7.8) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Fix linux-libc-dev build for hirsute forward port kernels (LP: #1904067)
+    - [Debian] Build linux-libc-dev for debian.master* branches
+
+  * Update kernel packaging to support forward porting kernels (LP: #1902957)
+    - [Debian] Update for leader included in BACKPORT_SUFFIX
+
+  * Introduce the new NVIDIA 455 series (LP: #1897751)
+    - [Packaging] NVIDIA -- Add signed modules for the 455 driver
+
+  * 5.10 kernel fails to boot with secure boot disabled (LP: #1904906)
+    - [Config] CONFIG_RCU_SCALE_TEST=n
+
+  * Miscellaneous Ubuntu changes
+    - [Config] s390x: disable GPIO_CDEV
+    - [Config] ARM_CMN=m
+    - [Config] disable GPIO_CDEV_V1
+    - [Config] Reorder annotations after 5.10-rc6 rebase
+    - [Packaging] Remove nvidia-435 dkms build
+    - [Packaging] Change source package name to linux
+    - [Config] Update configs and annotations after rebase to v5.10-rc7
+    - SAUCE: Revert "mm/filemap: add static for function
+      __add_to_page_cache_locked"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 07 Dec 2020 00:15:20 -0600
+
+linux (5.10.0-6.7) hirsute; urgency=medium
+
+  * Empty entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 06 Dec 2020 22:13:46 -0600
+
+linux-5.10 (5.10.0-6.7) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Avoid double newline when running insertchanges (LP: #1903293)
+    - [Packaging] insertchanges: avoid double newline
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging]: linux-modules should depend on linux-image
+    - [Packaging]: linux-image should suggest linux-modules-extra
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 30 Nov 2020 07:47:34 +0100
+
+linux-5.10 (5.10.0-5.6) hirsute; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] add CONFIG_INFINIBAND_VIRT_DMA
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 23 Nov 2020 13:17:44 +0100
+
+linux-5.10 (5.10.0-4.5) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] reduce the size required to build packages
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 16 Nov 2020 08:33:54 +0100
+
+linux-5.10 (5.10.0-3.4) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * e1000e: fix issues with S0ix (LP: #1902687)
+    - SAUCE: e1000e: fix S0ix flow to allow S0i3.2 subset entry
+    - SAUCE: e1000e: allow turning s0ix flows on for systems with ME
+    - SAUCE: e1000e: Add Dell's Comet Lake systems into s0ix heuristics
+    - SAUCE: e1000e: Add more Dell CML systems into s0ix heuristics
+    - [Config] Update CONFIG_E1000E for ppc64el in annotations
+
+  * perf: Add support for Rocket Lake (LP: #1902004)
+    - SAUCE: perf/x86/intel: Add Rocket Lake CPU support
+    - SAUCE: perf/x86/cstate: Add Rocket Lake CPU support
+    - SAUCE: perf/x86/msr: Add Rocket Lake CPU support
+    - SAUCE: perf/x86/intel/uncore: Add Rocket Lake support
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Disable CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE
+    - [Config] update CONFIG_MST_IRQ after rebase to 5.10-rc3
+    - [Config] drop obsolete SND_SST_IPC options
+    - [Config] re-enable ZFS
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 Nov 2020 09:37:08 +0100
+
+linux-5.10 (5.10.0-2.3) hirsute; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Switch arm64 default cpufreq governor to ondemand
+    - [Debian] Include scripts/module.lds from builddir in headers package
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 03 Nov 2020 21:01:52 -0600
+
+linux-5.10 (5.10.0-1.2) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Fix non-working Intel NVMe after S3 (LP: #1900847)
+    - SAUCE: PCI: Enable ACS quirk on all CML root ports
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move to hirsute
+    - [Config] Update configs and annotations after rebase to 5.10-rc2
+    - [Config] Update numerous configs to conform with policy
+    - [Config] Switch default CPUFreq governer for arm64/armhf to schedultil
+    - [Config] Temporarily disable DEBUG_INFO_BTF for armhf
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 02 Nov 2020 13:18:27 -0600
+
+linux-5.10 (5.10.0-0.1) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Update configs and annotations for v5.10-rc1
+    - SAUCE: platform/x86: dell-uart-backlight: rename kzfree() to
+      kfree_sensitive()
+    - SAUCE: apparmor: rename kzfree() to kfree_sensitive()
+    - SAUCE: LSM: change ima_read_file() to use lsmblob
+    - SAUCE: LSM: Use lsmblob in smk_netlbl_mls()
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] Change source package name to linux-5.10"
+    - s390: correct __bootdata / __bootdata_preserved macros
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 27 Oct 2020 16:57:07 +0100
+
+linux-5.10 (5.10.0-0.0) groovy; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 26 Oct 2020 14:55:48 +0100
+
+linux-5.9 (5.9.0-2.3) groovy; urgency=medium
+
+  * Fix system reboot when disconnecting WiFi (LP: #1899726)
+    - iwlwifi: msix: limit max RX queues for 9000 family
+
+  * booting linux-generic-lpae armhf kernel under qemu results in relocation out
+    of range, and thus no modules can be loaded (LP: #1899519)
+    - [Config] armhf: ARM_MODULE_PLTS=y
+
+  * Fix broken MSI interrupt after HDA controller was suspended (LP: #1899586)
+    - ALSA: hda: fix jack detection with Realtek codecs when in D3
+
+  * CVE-2020-16119
+    - SAUCE: dccp: avoid double free of ccid on child socket
+
+  * python3-venv is gone (LP: #1896801)
+    - SAUCE: doc: remove python3-venv dependency
+
+  * *-tools-common packages descriptions have typo "PGKVER" (LP: #1898903)
+    - [Packaging] Fix typo in -tools template s/PGKVER/PKGVER/
+
+  * Enable brightness control on HP DreamColor panel (LP: #1898865)
+    - SAUCE: drm/i915/dpcd_bl: Skip testing control capability with force DPCD
+      quirk
+    - SAUCE: drm/dp: HP DreamColor panel brigntness fix
+
+  * HP Zbook Studio G7 boots into corrupted screen with PSR featured panel
+    (LP: #1897501)
+    - SAUCE: drm/i915/psr: allow overriding PSR disable param by quirk
+    - SAUCE: drm/dp: add DP_QUIRK_FORCE_PSR_CHIP_DEFAULT quirk to CMN prod-ID
+      19-15
+
+  * Fix broken e1000e device after S3 (LP: #1897755)
+    - SAUCE: e1000e: Increase polling timeout on MDIC ready bit
+
+  * Wakeup the system by touching the touchpad (LP: #1888331)
+    - HID: i2c-hid: Enable wakeup capability from Suspend-to-Idle
+
+  * Enable LTR for endpoints behind VMD (LP: #1896598)
+    - SAUCE: PCI/ASPM: Enable LTR for endpoints behind VMD
+
+  * [SRU] [Focal/OEM-5.6/Groovy]Fix AMD usb host controller lost after stress S3
+    (LP: #1893914)
+    - SAUCE: xhci: workaround for S3 issue on AMD SNPS 3.0 xHC
+
+  * debian/rules editconfigs does not work on s390x to change s390x only configs
+    (LP: #1863116)
+    - [Packaging] kernelconfig -- only update/edit configurations on architectures
+      we have compiler support
+
+  * Fix non-working NVMe after S3 (LP: #1895718)
+    - SAUCE: PCI: Enable ACS quirk on CML root port
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: bpf: Check CONFIG_BPF option for resolve_btfids
+    - SAUCE: tools resolve_btfids: Always force HOSTARCH
+    - packaging: arm64: add a 64KB mem pages flavour called 'generic-64k'
+    - packaging: arm64: generic-64k: skip ABI, modules and retpoline checks
+    - SAUCE: drm/i915/display: Fix null deref in intel_psr_atomic_check()
+    - [Config] Update toolchain versions
+    - [Config] Refresh annotations
+    - Add ubuntu-host module
+    - CONFIG_UBUNTU_HOST=m
+    - SAUCE: apparmor: drop prefixing abs root labels with '='
+    - SAUCE: apparmor: disable showing the mode as part of a secid to secctx
+    - SAUCE: apparmor: rename aa_sock() to aa_unix_sk()
+    - SAUCE: apparmor: LSM stacking: switch from SK_CTX() to aa_sock()
+    - SAUCE: LSM: Infrastructure management of the sock security
+    - SAUCE: LSM: Create and manage the lsmblob data structure.
+    - SAUCE: LSM: Use lsmblob in security_audit_rule_match
+    - SAUCE: LSM: Use lsmblob in security_kernel_act_as
+    - SAUCE: net: Prepare UDS for security module stacking
+    - SAUCE: LSM: Use lsmblob in security_secctx_to_secid
+    - SAUCE: LSM: Use lsmblob in security_secid_to_secctx
+    - SAUCE: LSM: Use lsmblob in security_ipc_getsecid
+    - SAUCE: LSM: Use lsmblob in security_task_getsecid
+    - SAUCE: LSM: Use lsmblob in security_inode_getsecid
+    - SAUCE: LSM: Use lsmblob in security_cred_getsecid
+    - SAUCE: IMA: Change internal interfaces to use lsmblobs
+    - SAUCE: LSM: Specify which LSM to display
+    - SAUCE: LSM: Ensure the correct LSM context releaser
+    - SAUCE: LSM: Use lsmcontext in security_secid_to_secctx
+    - SAUCE: LSM: Use lsmcontext in security_inode_getsecctx
+    - SAUCE: LSM: security_secid_to_secctx in netlink netfilter
+    - SAUCE: NET: Store LSM netlabel data in a lsmblob
+    - SAUCE: LSM: Verify LSM display sanity in binder
+    - SAUCE: Audit: Add new record for multiple process LSM attributes
+    - SAUCE: Audit: Add a new record for multiple object LSM
+    - SAUCE: LSM: Add /proc attr entry for full LSM context
+    - SAUCE: AppArmor: Remove the exclusive flag
+    - SAUCE: Audit: Fix for missing NULL check
+
+  * Miscellaneous upstream changes
+    - tty: hvcs: Don't NULL tty->driver_data until hvcs_cleanup()
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.9
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 14 Oct 2020 13:31:18 -0500
+
+linux-5.9 (5.9.0-1.2) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Update configs after rebase to 5.9-rc6
+    - SAUCE: dax: Fix compilation for CONFIG_DAX && !CONFIG_FS_DAX
+    - SAUCE: bpf: Use --no-fail option if CONFIG_BPF is not enabled
+    - SAUCE: tools resolve_btfids: Always force HOSTARCH
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.9-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 21 Sep 2020 14:39:34 -0500
+
+linux-5.9 (5.9.0-0.1) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Update configs and annotations for v5.9-rc1
+    - SAUCE: i915: Fix build error due to missing struct definition
+    - hio -- Update blk_queue_split() calls for changes in 5.9-rc1
+    - hio -- Updates for move of make_request_fn to struct block_device_operations
+    - [Config] Disable zfs dkms build
+    - [Config] Disable nvidia dkms build
+    - [Config] Disable nvidia server dkms builds
+    - SAUCE: remoteproc: qcom: Use div_u64() for 64-bit division
+    - SAUCE: PCI/ASPM: Enable ASPM for links under VMD domain
+    - [Packaging] Bind hv_vss_daemon startup to hv_vss device
+    - [Packaging] bind hv_fcopy_daemon startup to hv_fcopy device
+    - [Config] Re-enable UEFI signing for arm64
+    - SAUCE: Revert "UBUNTU: SAUCE: export __get_vm_area_caller() and map_kernel_range()"
+    - [Config] Set the default CPU governor to ONDEMAND
+    - [Packaging] update variants
+    - [Packaging] update helper scripts
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.9-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 17 Sep 2020 15:01:21 -0500
+
+linux-5.9 (5.9.0-0.0) groovy; urgency=medium
+
+  * Empty entry
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 18 Aug 2020 16:48:03 -0500
+
+linux (5.8.0-16.17) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-16.17 -proposed tracker (LP: #1891233)
+
+  * Miscellaneous Ubuntu changes
+    - hio -- Update to use bio_{start,end}_io_acct with 5.8+
+    - Enable hio driver
+    - [Packaging] Temporarily disable building doc package contents
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 11 Aug 2020 15:32:58 -0500
+
+linux (5.8.0-15.16) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-15.16 -proposed tracker (LP: #1891177)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Documentation: import error c_funcptr_sig_re, c_sig_re (sphinx-
+      doc/sphinx@0f49e30c)
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 11 Aug 2020 09:29:58 -0500
+
+linux (5.8.0-14.15) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-14.15 -proposed tracker (LP: #1891085)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * msg_zerocopy.sh in net from ubuntu_kernel_selftests failed (LP: #1812620)
+    - selftests/net: relax cpu affinity requirement in msg_zerocopy test
+
+  * Fix missing HDMI/DP Audio on an HP Desktop (LP: #1890441)
+    - ALSA: hda/hdmi: Add quirk to force connectivity
+
+  * Add initial audio support for Lenovo ThinkStation P620 (LP: #1890317)
+    - ALSA: usb-audio: Add support for Lenovo ThinkStation P620
+
+  * Fix IOMMU error on AMD Radeon Pro W5700 (LP: #1890306)
+    - PCI: Mark AMD Navi10 GPU rev 0x00 ATS as broken
+
+  * Enlarge hisi_sec2 capability (LP: #1890222)
+    - crypto: hisilicon - update SEC driver module parameter
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Re-enable signing for ppc64el
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 10 Aug 2020 15:26:46 -0500
+
+linux (5.8.0-13.14) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Remove i386 configs
+    - SAUCE: apply a workaround to re-enable CONFIG_CRYPTO_AEGIS128_SIMD
+    - SAUCE: export __get_vm_area_caller() and map_kernel_range()
+    - [Config] drop CONFIG_BINFMT_AOUT enforcement
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] disable CONFIG_CRYPTO_AEGIS128_SIMD"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 04 Aug 2020 09:51:50 +0200
+
+linux (5.8.0-12.13) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-12.13 -proposed tracker (LP: #1889481)
+
+  * Fix right speaker of HP laptop (LP: #1889375)
+    - SAUCE: hda/realtek: Fix right speaker of HP laptop
+
+  * blk_update_request error when mount nvme partition (LP: #1872383)
+    - SAUCE: nvme-pci: prevent SK hynix PC400 from using Write Zeroes command
+
+  * Add support for Atlantic NIC firmware v4 (LP: #1886908)
+    - Revert "UBUNTU: SAUCE: net: atlantic: Add support for firmware v4"
+    - net: atlantic: align return value of ver_match function with function name
+    - net: atlantic: add support for FW 4.x
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Fix debian/tests for linux-5.8 -> linux rename
+    - SAUCE: selftests/powerpc: return skip code for spectre_v2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 29 Jul 2020 16:58:47 -0500
+
+linux (5.8.0-11.12) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-11.12 -proposed tracker (LP: #1889336)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] dwarves is not required for linux-libc-dev or stage1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 Jul 2020 22:33:24 -0500
+
+linux (5.8.0-10.11) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-10.11 -proposed tracker (LP: #1889316)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Add more packages to Build-Depends-Indep for docs
+    - [Debian] Specify python executable in kmake
+    - [Debian] Don't treat warnings as errors during perf builds
+    - [Config] Disable signing for ppc64el
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 Jul 2020 17:09:52 -0500
+
+linux (5.8.0-9.10) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-9.10 -proposed tracker (LP: #1889140)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Fix s390x compile error on F32 utils/stat-display.c
+    - [Packaging] Add python3-venv to Build-Depends-Indep
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Jul 2020 21:01:46 -0500
+
+linux (5.8.0-8.9) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-8.9 -proposed tracker (LP: #1889104)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - update dkms package versions
+    - [Packaging] update variants
+
+  * Introduce the new NVIDIA 450-server and the 450 UDA series (LP: #1887674)
+    - [Packaging] NVIDIA -- Add signed modules for 450 450-server
+
+  * Introduce the new NVIDIA 418-server and 440-server series, and update the
+    current NVIDIA drivers (LP: #1881137)
+    - [packaging] add signed modules for the 418-server and the 440-server
+      flavours
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "radix-tree: Use local_lock for protection"
+    - [Config] CONFIG_DEBUG_INFO_COMPRESSED=n
+    - [Config] disable CONFIG_CRYPTO_AEGIS128_SIMD
+    - [Config] Enable nvidia dkms build
+
+  * Miscellaneous upstream changes
+    - usbip: tools: fix build error for multiple definition
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Jul 2020 11:18:12 -0500
+
+linux (5.8.0-7.8) groovy; urgency=medium
+
+  * Empty entry
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Jul 2020 09:22:19 +0200
+
+linux-5.8 (5.8.0-7.8) groovy; urgency=medium
+
+  * soc/amd/renoir: detect dmic from acpi table (LP: #1887734)
+    - ASoC: amd: add logic to check dmic hardware runtime
+    - ASoC: amd: add ACPI dependency check
+    - ASoC: amd: fixed kernel warnings
+
+  * linux 4.15.0-109-generic network DoS regression vs -108 (LP: #1886668)
+    - SAUCE: Revert "netprio_cgroup: Fix unlimited memory leak of v2 cgroups"
+
+  * Add support for Atlantic NIC firmware v4 (LP: #1886908)
+    - SAUCE: net: atlantic: Add support for firmware v4
+
+  * MGA G200e doesn't work under GDM Wayland (LP: #1886140)
+    - drm/mgag200: Remove HW cursor
+    - drm/mgag200: Clean up mga_set_start_address()
+    - drm/mgag200: Clean up mga_crtc_do_set_base()
+    - drm/mgag200: Move mode-setting code into separate helper function
+    - drm/mgag200: Split MISC register update into PLL selection, SYNC and I/O
+    - drm/mgag200: Update mode registers after plane registers
+    - drm/mgag200: Set pitch in a separate helper function
+    - drm/mgag200: Set primary plane's format in separate helper function
+    - drm/mgag200: Move TAGFIFO reset into separate function
+    - drm/mgag200: Move hiprilvl setting into separate functions
+    - drm/mgag200: Move register initialization into separate function
+    - drm/mgag200: Remove out-commented suspend/resume helpers
+    - drm/mgag200: Use simple-display data structures
+    - drm/mgag200: Convert to simple KMS helper
+    - drm/mgag200: Replace VRAM helpers with SHMEM helpers
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: s390/bpf: fix sign extension in branch_ku
+    - SAUCE: selftests: net: ip_defrag: modprobe missing nf_defrag_ipv6 support
+    - SAUCE: selftests: fib_nexthop_multiprefix: fix cleanup() netns deletion
+    - [packaging] debhelper-compat (= 10) (and retire debian/compat)
+    - [Config] Update configs after rebase to 5.8-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 20 Jul 2020 09:55:47 +0200
+
+linux-5.8 (5.8.0-6.7) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * perf build broken after updating to bintuils 2.34.90.20200706-1ubuntu1
+    (LP: #1887397)
+    - SAUCE: libtraceevent: Strip symbol version from nm output
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 13 Jul 2020 14:07:53 -0500
+
+linux-5.8 (5.8.0-5.6) groovy; urgency=medium
+
+  * linux-libc-dev broken for crossbuilding, Multi-Arch:same violation
+    (LP: #1886188)
+    - [Packaging] Produce linux-libc-deb package for riscv64
+    - [Debian] Disallow building linux-libc-dev from linux-riscv
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "UBUNTU: SAUCE: test_bpf: remove expected fail for Ctx heavy
+      transformations test on s390"
+    - SAUCE: Revert "test_bpf: flag tests that cannot be jited on s390"
+    - [Config] Update configs (gcc update)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 13 Jul 2020 08:42:14 +0200
+
+linux-5.8 (5.8.0-4.5) groovy; urgency=medium
+
+  * Add generic LED class support for audio LED (LP: #1885896)
+    - ALSA: hda: generic: Always call led-trigger for mic mute LED
+    - ALSA: hda: generic: Add a helper for mic-mute LED with LED classdev
+    - ALSA: hda/realtek: Convert to cdev-variant of mic-mute LED controls
+    - ALSA: hda/conexant: Convert to cdev-variant of mic-mute LED controls
+    - ALSA: hda/sigmatel: Convert to cdev-variant of mic-mute LED controls
+    - ALSA: hda: generic: Drop unused snd_hda_gen_fixup_micmute_led()
+    - ALSA: hda: generic: Drop the old mic-mute LED hook
+    - ALSA: hda: generic: Add vmaster mute LED helper
+    - ALSA: hda/realtek: Use the new vmaster mute LED helper
+    - ALSA: hda/conexant: Use the new vmaster mute LED helper
+    - ALSA: hda/sigmatel: Use the new vmaster mute LED helper
+    - ALSA: hda/realtek: Unify LED helper code
+    - ALSA: hda: Let LED cdev handling suspend/resume
+
+  * seccomp_bpf fails on powerpc (LP: #1885757)
+    - SAUCE: selftests/seccomp: fix ptrace tests on powerpc
+
+  * CVE-2020-11935
+    - SAUCE: aufs: do not call i_readcount_inc()
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Update aufs to 5.x-rcN 20200622
+    - [Config] Update configs to set CONFIG_SND_HDA_GENERIC_LEDS value
+    - [Config] CONFIG_SECURITY_DMESG_RESTRICT=y
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 06 Jul 2020 08:14:28 -0500
+
+linux-5.8 (5.8.0-3.4) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - update dkms package versions
+
+  * lxc 1:4.0.2-0ubuntu1 ADT test failure with linux-5.8 5.8.0-1.2
+    (LP: #1884635)
+    - SAUCE: overlayfs: fix faulty rebase
+
+  * shiftfs: O_TMPFILE reports ESTALE (LP: #1872757)
+    - SAUCE: shiftfs: prevent ESTALE for LOOKUP_JUMP lookups
+
+  * shiftfs: fix btrfs regression (LP: #1884767)
+    - SAUCE: Revert "UBUNTU: SAUCE: shiftfs: fix dentry revalidation"
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_DEBUG_INFO_COMPRESSED=y
+    - SAUCE: regulator: rename da903x to da903x-regulator
+    - [Config] Add da903x to modules.ignore
+    - [Config] Update configs for rebase to 5.8-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 29 Jun 2020 08:48:25 -0500
+
+linux-5.8 (5.8.0-2.3) groovy; urgency=medium
+
+  * Support Audio Mute LED for two new HP laptops (LP: #1884251)
+    - ALSA: hda/realtek: Add mute LED and micmute LED support for HP systems
+
+  * CVE-2019-16089
+    - SAUCE: nbd_genl_status: null check for nla_nest_start
+
+  * tpm: fix TIS locality timeout problems (LP: #1881710)
+    - SAUCE: tpm: fix TIS locality timeout problems
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: security,perf: Allow further restriction of perf_event_open
+    - [Config] CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
+    - [Config] Update configs and annotations for 5.8-rc2
+    - [Config] Enable zfs
+    - [Config] Enable CONFIG_DEBUG_INFO_BTF
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 22 Jun 2020 15:05:54 -0500
+
+linux-5.8 (5.8.0-1.2) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Support linux-x.y in udeb package names
+    - [Packaging] Use SRCPKGNAME for udeb packages
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 17 Jun 2020 19:34:32 -0500
+
+linux-5.8 (5.8.0-0.1) groovy; urgency=medium
+
+  * Docker registry doesn't stay up and keeps restarting (LP: #1879690)
+    - Revert "UBUNTU: SAUCE: overlayfs: use shiftfs hacks only with shiftfs as underlay"
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Update source package name to linux-5.8
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - SAUCE: (lockdown) powerpc: lock down kernel in secure boot mode
+    - SAUCE: Import aufs driver
+    - [Config] Update configs for v5.8-rc1
+    - [Config] Update annotations for v5.8-rc1 config changes
+    - SAUCE: shiftfs -- Fix build errors from missing fiemap definitions
+    - Disable hio driver
+
+  * Miscellaneous upstream changes
+    - acpi: disallow loading configfs acpi tables when locked down
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 17 Jun 2020 11:54:24 -0500
+
+linux-5.8 (5.8.0-0.0) groovy; urgency=medium
+
+  * Empty entry
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 14 Jun 2020 22:40:35 -0500
+
+linux-5.7 (5.7.0-8.9) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Enforce all config annotations (LP: #1879327)
+    - [Config]: do not enforce CONFIG_VERSION_SIGNATURE
+    - [Config]: prepare to enforce all
+    - [Config]: enforce all config options
+
+  * Miscellaneous Ubuntu changes
+    - [Config]: annotations review after 5.7 rebase
+    - [Config] annotations: IXP4XX* depends on ARCH_IXP4XX
+    - [Config] THERMAL_GOV_POWER_ALLOCATOR=y
+    - [Config] annotations: SOC_CAMERA is marked as BROKEN
+    - [Config] annotations: NFSD_V4_2_INTER_SSC depends on NFS_FS=y
+    - [Config] annotations: CRYPTO_DEV_CHELSIO_TLS depends on legacy (and largely
+      unmantained) TLS_TOE
+    - [Config] annotations: SERIO_OLPC_APSP depends on ARCH_MMP
+    - [Config] RTW88_DEBUG=y
+    - [Config] annotations: ISDN_CAPI is a bool, and BT_CMTP depends on  it
+    - [Config] annotations SND_SOC_SOF_DEVELOPER_SUPPORT depends on
+      SND_SOC_SOF_DEVELOPER_SUPPORT
+    - [Config] annotations: SND_SOC_SOF_BAYTRAIL_SUPPORT is mutually exclusive
+      with SND_SST_ATOM_HIFI2_PLATFORM_ACPI
+    - [Config] annotations: DEBUG_IMX_UART_PORT is defined only any
+      DEBUG_IMX*_UART is enabled
+    - [Config] annotations: HW_RANDOM_IMX_RNGC depends on SOC_IMX25
+    - [Config] annotations: armhf: VIRTUALIZATION support was removed for arm32
+    - [Config] annotations: arm64: remove DEBUG_ALIGN_RODATA
+    - [Config] annotations: ppc64: DATA_SHIFT defaults to PPC_PAGE_SHIFT
+    - [Config] arm64: enforce ARM64_USE_LSE_ATOMICS
+    - [Config] s390x: MOST is not set
+    - [Config] s390x: BCM84881_PHY is not set
+    - [Config] s390x: XILINX_LL_TEMAC is not set
+    - [Config] s390x: PHY_INTEL_EMMC requires GENERIC_PHY (off by default on
+      s390x)
+    - [Config] s390x: CHECK_STACK conflicts with VMAP_STACK
+    - [Config] annotations: s390x: NODES_SHIFT=1
+    - [Config] annotations: import new symbols
+    - [Config] annotations: remove unmatched menu and options
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 12 Jun 2020 12:03:01 +0200
+
+linux-5.7 (5.7.0-7.8) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+    - [Packaging] update helper scripts
+
+  * [UBUNTU 20.04] s390x/pci: fix linking between PF and VF for multifunction
+    devices (LP: #1879704)
+    - PCI/IOV: Introduce pci_iov_sysfs_link() function
+    - s390/pci: create links between PFs and VFs
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Disable UEFI signing for arm64
+    - Rebase to v5.7.1
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7.1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 08 Jun 2020 11:16:58 +0200
+
+linux-5.7 (5.7.0-6.7) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - update dkms package versions
+
+  * shiftfs: fix btrfs snapshot deletion (LP: #1879688)
+    - SAUCE: shiftfs: let userns root destroy subvolumes from other users
+
+  * seccomp_benchmark times out on eoan (LP: #1881576)
+    - SAUCE: selftests/seccomp: use 90s as timeout
+
+  * Realtek 8723DE [10ec:d723] subsystem [10ec:d738]  disconnects unsolicitedly
+    when Bluetooth is paired: Reason: 23=IEEE8021X_FAILED (LP: #1878147)
+    - SAUCE: Revert "UBUNTU: SAUCE: rtw88: Move driver IQK to set channel before
+      association for 11N chip"
+    - SAUCE: Revert "UBUNTU: SAUCE: rtw88: fix rate for a while after being
+      connected"
+    - SAUCE: Revert "UBUNTU: SAUCE: rtw88: No retry and report for auth and assoc"
+    - SAUCE: Revert "UBUNTU: SAUCE: rtw88: 8723d: Add coex support"
+    - rtw88: 8723d: Add coex support
+    - SAUCE: rtw88: coex: 8723d: set antanna control owner
+    - SAUCE: rtw88: coex: 8723d: handle BT inquiry cases
+    - SAUCE: rtw88: fix EAPOL 4-way failure by finish IQK earlier
+
+  * ASoC/amd: add audio driver for amd renoir (LP: #1881046)
+    - ASoC: amd: add Renoir ACP3x IP register header
+    - ASoC: amd: add Renoir ACP PCI driver
+    - ASoC: amd: add acp init/de-init functions
+    - ASoC: amd: create acp3x pdm platform device
+    - ASoC: amd: add ACP3x PDM platform driver
+    - ASoC: amd: irq handler changes for ACP3x PDM dma driver
+    - ASoC: amd: add acp3x pdm driver dma ops
+    - ASoC: amd: add ACP PDM DMA driver dai ops
+    - ASoC: amd: add Renoir ACP PCI driver PM ops
+    - ASoC: amd: add ACP PDM DMA driver pm ops
+    - ASoC: amd: enable Renoir acp3x drivers build
+    - ASoC: amd: create platform devices for Renoir
+    - ASoC: amd: RN machine driver using dmic
+    - ASoC: amd: enable build for RN machine driver
+    - ASoC: amd: fix kernel warning
+    - ASoC: amd: refactoring dai_hw_params() callback
+    - ASoC: amd: return error when acp de-init fails
+    - [Config]: enable amd renoir ASoC audio
+
+  * Slow send speed with Intel I219-V on Ubuntu 18.04.1 (LP: #1802691)
+    - e1000e: Disable TSO for buffer overrun workaround
+
+  * Fix incorrect speed/duplex when I210 device is runtime suspended
+    (LP: #1880656)
+    - igb: Report speed and duplex as unknown when device is runtime suspended
+
+  * Fix Pericom USB controller OHCI/EHCI PME# defect (LP: #1879321)
+    - serial: 8250_pci: Move Pericom IDs to pci_ids.h
+    - PCI: Avoid Pericom USB controller OHCI/EHCI PME# defect
+
+  * [UBUNTU 20.04] s390x/pci: enumerate pci functions per physical adapter
+    (LP: #1874056)
+    - s390/pci: Expose new port attribute for PCIe functions
+    - s390/pci: adaptation of iommu to multifunction
+    - s390/pci: define kernel parameters for PCI multifunction
+    - s390/pci: define RID and RID available
+    - s390/pci: create zPCI bus
+    - s390/pci: adapt events for zbus
+    - s390/pci: Handling multifunctions
+    - s390/pci: Do not disable PF when VFs exist
+    - s390/pci: Documentation for zPCI
+    - s390/pci: removes wrong PCI multifunction assignment
+
+  * add 16-bit width registers support for EEPROM at24 device (LP: #1876699)
+    - regmap-i2c: add 16-bit width registers support
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Enable virtualbox guest and shared-folder modules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 01 Jun 2020 16:11:24 -0500
+
+linux-5.7 (5.7.0-5.6) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * [UBUNTU 20.04] PSI generates overhead on s390x (LP: #1876044)
+    - Ubuntu: [Config] CONFIG_PSI is enabled by default, but creates additional
+      overhead on s390x, hence should be disabled by default on s390x only.
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v5.7-rc7
+    - [Config] ppc64el: disable STRICT_KERNEL_RWX
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 25 May 2020 11:44:09 +0200
+
+linux-5.7 (5.7.0-4.5) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * update-initramfs complains of missing amdgpu firmware files (LP: #1873325)
+    - SAUCE: drm/amdgpu: Remove unreleased arcturus and navi12 firmware from
+      modinfo
+
+  * Support DMIC micmute LED on HP platforms (LP: #1876859)
+    - ALSA: hda/realtek - Introduce polarity for micmute LED GPIO
+    - ALSA: hda/realtek - Enable micmute LED on and HP system
+    - ALSA: hda/realtek - Add LED class support for micmute LED
+    - ALSA: hda/realtek - Fix unused variable warning w/o
+      CONFIG_LEDS_TRIGGER_AUDIO
+    - ASoC: SOF: Update correct LED status at the first time usage of
+      update_mute_led()
+
+  * Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW),
+    REV=0x354 [8086:a0f0] subsystem id [1a56:1651] wireless adapter not found
+    due to firmware crash (LP: #1874685)
+    - SAUCE: iwlwifi: pcie: handle QuZ configs with killer NICs as well
+
+  * rtkit-daemon[*]: Failed to make ourselves RT: Operation not permitted after
+    upgrade to 20.04 (LP: #1875665)
+    - [Config] Turn off CONFIG_RT_GROUP_SCHED everywhere
+
+  * Unable to handle kernel pointer dereference in virtual kernel address space
+    on Eoan (LP: #1876645)
+    - SAUCE: overlayfs: fix shitfs special-casing
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: skip building selftest 'runqslower' if kernel not built
+    - Rebase to v5.7-rc6
+    - [Config] updateconfigs after 5.7-rc6 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 18 May 2020 11:27:25 +0200
+
+linux-5.7 (5.7.0-3.4) groovy; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7-rc5
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * getitimer returns it_value=0 erroneously (LP: #1349028)
+    - [Config] CONTEXT_TRACKING_FORCE policy should be unset
+
+  * lockdown on power (LP: #1855668) // Ubuntu Kernel Support for OpenPOWER NV
+    Secure & Trusted Boot (LP: #1866909)
+    - [Config] Enable configs for OpenPOWER NV Secure & Trusted Boot
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Import aufs driver
+    - [Config] Enable aufs
+    - [Config] annotations: remove SND_SOC_SOF_HDA_COMMON_HDMI_CODEC
+    - [Config] Remove CONFIG_SND_HDA_INTEL_DETECT_DMIC from annotations
+    - [Debian] final-checks -- Do not remove ~* from abi
+    - [Config] Enable 5-level page table support for x86
+    - [Config] updateconfigs after 5.7-rc5 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 11 May 2020 10:25:42 +0200
+
+linux-5.7 (5.7.0-2.3) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - update dkms package versions
+    - [Packaging] update helper scripts
+
+  * ASUS T100HAN boots to a blank screen with a cursor [i965: Failed to submit
+    batchbuffer: Input/output error] (LP: #1860754)
+    - [Config] CONFIG_PMIC_OPREGION=y and CONFIG_GPIO_CRYSTAL_COVE=y for amd64
+
+  * ubuntu/focal64 fails to mount Vagrant shared folders  (LP: #1873506)
+    - [Packaging] Move virtualbox modules to linux-modules
+    - [Packaging] Remove vbox and zfs modules from generic.inclusion-list
+
+  * built-using constraints preventing uploads (LP: #1875601)
+    - temporarily drop Built-Using data
+
+  * dkms artifacts may expire from the pool (LP: #1850958)
+    - [Packaging] autoreconstruct -- manage executable debian files
+    - [packaging] handle downloads from the librarian better
+
+  * Add signed modules for the 435 NVIDIA driver (LP: #1875888)
+    - [Packaging] NVIDIA -- add signed modules for the 435 NVIDIA driver
+
+  * [Selftests] Apply various fixes and improvements (LP: #1870543)
+    - SAUCE: selftests/seccomp -- Disable timeout for seccomp tests
+
+  * [17.04 FEAT] Integrate kernel message catalogue for s390x into Ubuntu
+    distribution (LP: #1628889)
+    - SAUCE: s390: kernel message catalog
+
+  * Overlayfs in user namespace leaks directory content of inaccessible
+    directories (LP: #1793458) // CVE-2018-6559
+    - SAUCE: overlayfs: ensure mounter privileges when reading directories
+
+  * suspend only works once on ThinkPad X1 Carbon gen 7 (LP: #1865570)
+    - SAUCE: e1000e: Disable s0ix flow for X1 Carbon 7th
+
+  * [ICL] TC port in legacy/static mode can't be detected due TCCOLD
+    (LP: #1868936)
+    - drm/i915/display: Move out code to return the digital_port of the aux ch
+    - drm/i915/display: Add intel_legacy_aux_to_power_domain()
+    - drm/i915/display: Split hsw_power_well_enable() into two
+    - drm/i915/tc/icl: Implement TC cold sequences
+    - drm/i915/tc: Skip ref held check for TC legacy aux power wells
+    - drm/i915/tc/tgl: Implement TC cold sequences
+    - drm/i915/tc: Catch TC users accessing FIA registers without enable aux
+    - drm/i915/tc: Do not warn when aux power well of static TC ports timeout
+
+  * Touchpad doesn't work on Dell Inspiron 7000 2-in-1 (LP: #1851901)
+    - Revert "UBUNTU: SAUCE: mfd: intel-lpss: add quirk for Dell XPS 13 7390
+      2-in-1"
+
+  * 'Elan touchpad' not detected on 'Lenovo ThinkBook 15 IIL' (LP: #1861610)
+    - SAUCE: Input: elan_i2c - add more hardware ID for Lenovo laptop
+
+  * linux-image-5.0.0-35-generic breaks checkpointing of container
+    (LP: #1857257)
+    - SAUCE: overlayfs: use shiftfs hacks only with shiftfs as underlay
+
+  * alsa/sof: kernel oops on the machine without Intel hdmi audio codec (a
+    regression in the  asoc machine driver) (LP: #1874359)
+    - ASoC: intel/skl/hda - fix oops on systems without i915 audio codec
+
+  * Add debian/rules targets to compile/run kernel selftests (LP: #1874286)
+    - [Packaging] add support to compile/run selftests
+
+  * 5.4.0-24.28 does not seem to apply rtprio, whereas -21 does. (LP: #1873315)
+    - [Config] lowlatency: turn off RT_GROUP_SCHED
+
+  * alsa/sof: external mic can't be deteced on Lenovo and HP laptops
+    (LP: #1872569)
+    - SAUCE: ASoC: intel/skl/hda - set autosuspend timeout for hda codecs
+
+  * shiftfs: O_TMPFILE reports ESTALE (LP: #1872757)
+    - SAUCE: shiftfs: fix dentry revalidation
+
+  * shiftfs: broken shiftfs nesting (LP: #1872094)
+    - SAUCE: shiftfs: record correct creator credentials
+
+  * lockdown on power (LP: #1855668)
+    - SAUCE: (lockdown) powerpc: lock down kernel in secure boot mode
+
+  * Add support for Realtek 8723DE wireless adapter (LP: #1780590)
+    - SAUCE: rtw88: add adaptivity support for EU/JP regulatory
+    - SAUCE: rtw88: update tx descriptor of mgmt and rsvd page packets
+    - SAUCE: rtw88: sar: dump sar information via debugfs
+    - SAUCE: rtw88: 8723d: add IQ calibration
+    - SAUCE: rtw88: 8723d: Add power tracking
+    - SAUCE: rtw88: 8723d: implement flush queue
+    - SAUCE: rtw88: 8723d: set ltecoex register address in chip_info
+    - SAUCE: rtw88: 8723d: Add coex support
+    - SAUCE: rtw88: 8723d: Add shutdown callback to disable BT USB suspend
+
+  * Fix authentication fail on Realtek WiFi 8723de (LP: #1871300)
+    - SAUCE: rtw88: No retry and report for auth and assoc
+    - SAUCE: rtw88: fix rate for a while after being connected
+    - SAUCE: rtw88: Move driver IQK to set channel before association for 11N chip
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: rtw88: fix 'const' mismatch in power suequence hooks
+    - SAUCE: rtw88: fix 'const' mismatch in
+      __priority_queue_cfg_legacy()/__priority_queue_cfg()
+    - [Config] RTW88=m
+    - SAUCE: (lockdown) Revert carried-forward lockdown patches
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - [Config] Add back CONFIG_LOCK_DOWN_IN_SECURE_BOOT annotation for ppc64el
+    - [Config] CONFIG_RT_GROUP_SCHED=y
+    - [Packaging] Include modules.builtin.modinfo in linux-modules
+    - SAUCE: LSM: Infrastructure management of the sock security
+    - SAUCE: Fix-up af_unix mediation for sock infrastructure management
+    - SAUCE: Revert "apparmor: Allow filtering based on secmark policy"
+    - SAUCE: Revert "apparmor: Parse secmark policy"
+    - SAUCE: Revert "apparmor: Add a wildcard secid"
+    - SAUCE: Revert "apparmor: fixup secid map conversion to using IDR"
+    - SAUCE: Revert "apparmor: Use an IDR to allocate apparmor secids"
+    - SAUCE: Revert "apparmor: add support for mapping secids and using secctxes"
+    - Update dropped.txt for restored apparmor patches
+    - Remove lockdown patches from dropped.txt
+    - SAUCE: powerpc/ima: require IMA module signatures only if MODULE_SIG is not
+      enabled
+    - SAUCE: selftests/ftrace: Use printf instead of echo in kprobe syntax error
+      tests
+    - SAUCE: selftests/net -- disable l2tp.sh test
+    - SAUCE: selftests/net -- disable timeout
+    - SAUCE: tools: hv: Update shebang to use python3 instead of python
+    - Remove dropped.txt
+    - [Packaging] move linux-doc and linux-libc-dev stubs to debian.master
+    - [Debian] Support generating configs for riscv64
+    - [Config] CONFIG_KMSG_IDS=y for s390x
+    - [Packaging] add libcap-dev dependency
+    - [Config] CONFIG_AD5770R=m
+    - [Config] CONFIG_AL3010=m
+    - [Config] CONFIG_APPLE_MFI_FASTCHARGE=m
+    - [Config] CONFIG_BAREUDP=m
+    - [Config] CONFIG_CRYPTO_DEV_OCTEONTX_CPT=m
+    - [Config] CONFIG_CRYPTO_DEV_ZYNQMP_AES=m
+    - [Config] CONFIG_DRM_DISPLAY_CONNECTOR=m
+    - [Config] CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
+    - [Config] CONFIG_DRM_PANEL_ELIDA_KD35T133=m
+    - [Config] CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02=m
+    - [Config] CONFIG_DRM_PANEL_NOVATEK_NT35510=m
+    - [Config] CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01=m
+    - [Config] CONFIG_DRM_PARADE_PS8640=m
+    - [Config] CONFIG_DRM_SIMPLE_BRIDGE=m
+    - [Config] CONFIG_DRM_TIDSS=m
+    - [Config] CONFIG_DRM_TI_TPD12S015=m
+    - [Config] CONFIG_DRM_TOSHIBA_TC358768=m
+    - [Config] CONFIG_EDAC_DMC520=m
+    - [Config] CONFIG_EXFAT_FS=m
+    - [Config] CONFIG_GP2AP002=m
+    - [Config] CONFIG_GPIO_MLXBF2=m
+    - [Config] CONFIG_HID_GLORIOUS=m
+    - [Config] CONFIG_HID_MCP2221=m
+    - [Config] CONFIG_HMC425=m
+    - [Config] CONFIG_ICP10100=m
+    - [Config] CONFIG_IMX8MM_THERMAL=m
+    - [Config] CONFIG_IMX_SC_THERMAL=m
+    - [Config] CONFIG_INTERCONNECT_QCOM_OSM_L3=m
+    - [Config] CONFIG_INTERCONNECT_QCOM_SC7180=m
+    - [Config] CONFIG_K3_RTI_WATCHDOG=m
+    - [Config] CONFIG_MDIO_IPQ8064=m
+    - [Config] CONFIG_MDIO_MVUSB=m
+    - [Config] CONFIG_MHI_BUS=m
+    - [Config] CONFIG_OCTEONTX2_VF=m
+    - [Config] CONFIG_PHY_CADENCE_TORRENT=m
+    - [Config] CONFIG_PHY_QCOM_USB_HS_28NM=m
+    - [Config] CONFIG_PHY_QCOM_USB_SS=m
+    - [Config] CONFIG_PINCTRL_DA9062=m
+    - [Config] CONFIG_PINCTRL_IPQ6018=m
+    - [Config] CONFIG_PTP_1588_CLOCK_IDT82P33=m
+    - [Config] CONFIG_PTP_1588_CLOCK_VMW=m
+    - [Config] CONFIG_QCOM_IPA=m
+    - [Config] CONFIG_REGULATOR_MP5416=m
+    - [Config] CONFIG_REGULATOR_MP886X=m
+    - [Config] CONFIG_RN5T618_ADC=m
+    - [Config] CONFIG_RTC_DRV_MT2712=m
+    - [Config] CONFIG_RTC_DRV_RC5T619=m
+    - [Config] CONFIG_SC_MSS_7180=m
+    - [Config] CONFIG_SENSORS_AXI_FAN_CONTROL=m
+    - [Config] CONFIG_SM_GCC_8250=m
+    - [Config] CONFIG_SND_BCM63XX_I2S_WHISTLER=m
+    - [Config] CONFIG_SND_MESON_AIU=m
+    - [Config] CONFIG_SND_MESON_G12A_TOACODEC=m
+    - [Config] CONFIG_SND_MESON_GX_SOUND_CARD=m
+    - [Config] CONFIG_SND_SOC_AMD_RV_RT5682_MACH=m
+    - [Config] CONFIG_SND_SOC_INTEL_SOF_PCM512x_MACH=m
+    - [Config] CONFIG_SND_SOC_MESON_T9015=m
+    - [Config] CONFIG_SND_SOC_RT5682_SDW=m
+    - [Config] CONFIG_SND_SOC_TLV320ADCX140=m
+    - [Config] CONFIG_SPI_FSI=m
+    - [Config] CONFIG_SPI_MTK_NOR=m
+    - [Config] CONFIG_SPI_MUX=m
+    - [Config] CONFIG_SPRD_THERMAL=m
+    - [Config] CONFIG_SURFACE_3_POWER_OPREGION=m
+    - [Config] CONFIG_TINYDRM_ILI9486=m
+    - [Config] CONFIG_TI_K3_AM65_CPSW_NUSS=m
+    - [Config] CONFIG_TYPEC_MUX_INTEL_PMC=m
+    - [Config] CONFIG_UACCE=m
+    - [Config] CONFIG_UNIPHIER_XDMAC=m
+    - [Config] CONFIG_USB_MAX3420_UDC=m
+    - [Config] CONFIG_USB_RAW_GADGET=m
+    - [Config] CONFIG_VHOST_VDPA=m
+    - [Config] CONFIG_VIDEO_IMX219=m
+    - [Config] CONFIG_VIDEO_SUN8I_ROTATE=m
+    - [Config] CONFIG_VIRTIO_VDPA=m
+    - [Config] CONFIG_MOST_COMPONENTS=m
+    - [Config] CONFIG_MFD_IQS62X=m
+    - packaging: getabis: switch to ckt-ppa:bootstrap/linux-5.7
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: rtw88: add rtw_read8_mask and rtw_read16_mask"
+    - Revert "UBUNTU: SAUCE: drm/i915/fbc: disable framebuffer compression on
+      IceLake"
+    - Revert "UBUNTU: SAUCE: platform/x86: dell-uart-backlight: move retry block"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 04 May 2020 10:48:48 +0200
+
+linux-5.7 (5.7.0-1.2) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: hio: pass make_request ptr directly to blk_alloc_queue()
+    - SAUCE: hio: locally define disk_map_sector_rcu()
+    - SAUCE: hio: Revert "block: unexport disk_map_sector_rcu"
+    - SAUCE: hio: include <linux/part_stat.h>
+    - [Config] amd64: i386: HIO=m
+    - [Config] updateconfigs after 5.7-rc3 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 27 Apr 2020 11:31:38 +0200
+
+linux-5.7 (5.7.0-0.1) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after rebase to 5.7-rc1
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7-rc1
+  * Rebase to v5.7-rc2
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 16 Apr 2020 11:53:58 +0200
+
+linux-5.7 (5.7.0-0.0) focal; urgency=medium
+
+  * Dummy entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 16 Apr 2020 11:53:58 +0200
+
+linux-5.6 (5.6.0-7.7) focal; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Kernel Oops - general protection fault: 0000 [#1] SMP PTI after
+    disconnecting thunderbolt docking station (LP: #1864754)
+    - SAUCE: ptp: free ptp clock properly
+
+  * swap storms kills interactive use (LP: #1861359)
+    - SAUCE: mm/page_alloc.c: disable memory reclaim watermark boosting by default
+
+  * sysfs: incorrect network device permissions on network namespace change
+    (LP: #1865359)
+    - sysfs: add sysfs_file_change_owner()
+    - sysfs: add sysfs_link_change_owner()
+    - sysfs: add sysfs_group{s}_change_owner()
+    - sysfs: add sysfs_change_owner()
+    - device: add device_change_owner()
+    - drivers/base/power: add dpm_sysfs_change_owner()
+    - net-sysfs: add netdev_change_owner()
+    - net-sysfs: add queue_change_owner()
+    - net: fix sysfs permssions when device changes network namespace
+    - sysfs: fix static inline declaration of sysfs_groups_change_owner()
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after rebase to 5.6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 31 Mar 2020 10:45:09 +0200
+
+linux-5.6 (5.6.0-6.6) focal; urgency=medium
+
+  * suspend only works once on ThinkPad X1 Carbon gen 7 (LP: #1865570)
+    - SAUCE: e1000e: Disable s0ix flow for X1 Carbon 7th
+
+  *  Make Dell WD19 dock more reliable after suspend (LP: #1868217)
+    - xhci: Ensure link state is U3 after setting USB_SS_PORT_LS_U3
+    - xhci: Wait until link state trainsits to U0 after setting USB_SS_PORT_LS_U0
+    - xhci: Finetune host initiated USB3 rootport link suspend and resume
+
+  * update-version-dkms doesn't add a BugLink (LP: #1867790)
+    - [Packaging] Add BugLink to update-version-dkms commit
+
+  * Add support for Realtek 8723DE wireless adapter (LP: #1780590)
+    - SAUCE: rtw88: add regulatory process strategy for different chipset
+    - SAUCE: rtw88: support dynamic user regulatory setting
+    - SAUCE: rtw88: Use secondary channel offset enumeration
+    - SAUCE: rtw88: 8822c: modify rf protection setting
+    - SAUCE: rtw88: disable TX-AMSDU on 2.4G band
+    - SAUCE: Revert "rtw88: disable TX-AMSDU on 2.4G band"
+    - SAUCE: rtw88: disable TX-AMSDU on 2.4G band
+    - SAUCE: rtw88: remove unused parameter vif in rtw_lps_pg_info_get()
+    - SAUCE: rtw88: add rtw_read8_mask and rtw_read16_mask
+    - SAUCE: rtw88: pci: 8822c should set clock delay to zero
+    - SAUCE: rtw88: move rtw_enter_ips() to the last when config
+    - SAUCE: rtw88: avoid holding mutex for cancel_delayed_work_sync()
+    - SAUCE: rtw88: add ciphers to suppress error message
+    - SAUCE: rtw88: 8822c: update power sequence to v16
+    - SAUCE: rtw88: Fix incorrect beamformee role setting
+    - SAUCE: rtw88: don't hold all IRQs disabled for PS operations
+    - SAUCE: rtw88: extract alloc rsvd_page and h2c skb routines
+    - SAUCE: rtw88: associate reserved pages with each vif
+    - SAUCE: rtw88: add adaptivity support for EU/JP regulatory
+    - SAUCE: rtw88: 8723d: Add basic chip capabilities
+    - SAUCE: rtw88: 8723d: add beamform wrapper functions
+    - SAUCE: rtw88: 8723d: Add power sequence
+    - SAUCE: rtw88: 8723d: Add RF read/write ops
+    - SAUCE: rtw88: 8723d: Add mac/bb/rf/agc/power_limit tables
+    - SAUCE: rtw88: 8723d: Add cfg_ldo25 to control LDO25
+    - SAUCE: rtw88: 8723d: Add new chip op efuse_grant() to control efuse access
+    - SAUCE: rtw88: 8723d: Add read_efuse to recognize efuse info from map
+    - SAUCE: rtw88: add legacy firmware download for 8723D devices
+    - SAUCE: rtw88: no need to send additional information to legacy firmware
+    - SAUCE: rtw88: 8723d: Add mac power-on/-off function
+    - SAUCE: rtw88: decompose while(1) loop of power sequence polling command
+    - SAUCE: rtw88: 8723d: 11N chips don't support H2C queue
+    - SAUCE: rtw88: 8723d: implement set_tx_power_index ops
+    - SAUCE: rtw88: 8723d: Organize chip TX/RX FIFO
+    - SAUCE: rtw88: 8723d: initialize mac/bb/rf basic functions
+    - SAUCE: rtw88: 8723d: Add DIG parameter
+    - SAUCE: rtw88: 8723d: Add query_rx_desc
+    - SAUCE: rtw88: 8723d: Add set_channel
+    - SAUCE: rtw88: handle C2H_CCX_TX_RPT to know if packet TX'ed successfully
+    - SAUCE: rtw88: 8723d: 11N chips don't support LDPC
+    - SAUCE: rtw88: set default port to firmware
+    - SAUCE: rtw88: update tx descriptor of mgmt and rsvd page packets
+    - SAUCE: rtw88: sar: add SAR of TX power limit
+    - SAUCE: rtw88: sar: Load static SAR table from ACPI WRDS method
+    - SAUCE: rtw88: sar: Load dynamic SAR table from ACPI methods
+    - SAUCE: rtw88: sar: apply dynamic SAR table to tx power limit
+    - SAUCE: rtw88: sar: add sar_work to poll if dynamic SAR table is changed
+    - SAUCE: rtw88: sar: dump sar information via debugfs
+    - SAUCE: rtw88: 8723d: Add chip_ops::false_alarm_statistics
+    - SAUCE: rtw88: 8723d: Set IG register for CCK rate
+    - SAUCE: rtw88: 8723d: add interface configurations table
+    - SAUCE: rtw88: 8723d: Add LC calibration
+    - SAUCE: rtw88: 8723d: add IQ calibration
+    - SAUCE: rtw88: 8723d: Add power tracking
+    - SAUCE: rtw88: 8723d: Add shutdown callback to disable BT USB suspend
+    - SAUCE: rtw88: 8723d: implement flush queue
+    - SAUCE: rtw88: 8723d: set ltecoex register address in chip_info
+    - SAUCE: rtw88: 8723d: Add coex support
+    - SAUCE: rtw88: fill zeros to words 0x06 and 0x07 of security cam entry
+    - SAUCE: rtw88: 8723d: Add 8723DE to Kconfig and Makefile
+    - [Config] CONFIG_RTW88_8723DE=y
+
+  * [Ubuntu 20.04] Unset HIBERNATION and PM kernel config options for focal
+    (LP: #1867753)
+    - [Config] CONFIG_HIBERNATION=n and CONFIG_PM=n for s390x
+
+  * [20.04 FEAT] Base KVM setup for secure guests - kernel part (LP: #1835531)
+    - s390/protvirt: introduce host side setup
+    - s390/protvirt: add ultravisor initialization
+    - s390/mm: provide memory management functions for protected KVM guests
+    - s390/mm: add (non)secure page access exceptions handlers
+    - s390/protvirt: Add sysfs firmware interface for Ultravisor information
+    - KVM: s390/interrupt: do not pin adapter interrupt pages
+    - KVM: s390: protvirt: Add UV debug trace
+    - KVM: s390: add new variants of UV CALL
+    - KVM: s390: protvirt: Add initial vm and cpu lifecycle handling
+    - KVM: s390: protvirt: Secure memory is not mergeable
+    - KVM: s390/mm: Make pages accessible before destroying the guest
+    - KVM: s390: protvirt: Handle SE notification interceptions
+    - KVM: s390: protvirt: Instruction emulation
+    - KVM: s390: protvirt: Implement interrupt injection
+    - KVM: s390: protvirt: Add SCLP interrupt handling
+    - KVM: s390: protvirt: Handle spec exception loops
+    - KVM: s390: protvirt: Add new gprs location handling
+    - KVM: S390: protvirt: Introduce instruction data area bounce buffer
+    - KVM: s390: protvirt: handle secure guest prefix pages
+    - KVM: s390/mm: handle guest unpin events
+    - KVM: s390: protvirt: Write sthyi data to instruction data area
+    - KVM: s390: protvirt: STSI handling
+    - KVM: s390: protvirt: disallow one_reg
+    - KVM: s390: protvirt: Do only reset registers that are accessible
+    - KVM: s390: protvirt: Only sync fmt4 registers
+    - KVM: s390: protvirt: Add program exception injection
+    - KVM: s390: protvirt: UV calls in support of diag308 0, 1
+    - KVM: s390: protvirt: Report CPU state to Ultravisor
+    - KVM: s390: protvirt: Support cmd 5 operation state
+    - KVM: s390: protvirt: Mask PSW interrupt bits for interception 104 and 112
+    - KVM: s390: protvirt: do not inject interrupts after start
+    - KVM: s390: protvirt: Add UV cpu reset calls
+    - DOCUMENTATION: Protected virtual machine introduction and IPL
+    - KVM: s390: protvirt: introduce and enable KVM_CAP_S390_PROTECTED
+    - KVM: s390: protvirt: Add KVM api documentation
+    - mm/gup/writeback: add callbacks for inaccessible pages
+
+  * All PS/2 ports on PS/2 Serial add-in bracket are not working after S3
+    (LP: #1866734)
+    - SAUCE: Input: i8042 - fix the selftest retry logic
+
+  * Sys oopsed with sysfs test in ubuntu_stress_smoke_test on X-hwe ARM64
+    (LP: #1866772)
+    - ACPI: sysfs: copy ACPI data using io memory copying
+
+  * Miscellaneous Ubuntu changes
+    - hio -- remove duplicated MODULE_DEVICE_TABLE declaration
+    - SAUCE: r8169: disable ASPM L1.1
+    - [Config] update annotations from configs
+    - [Config] update configs after annotation file review
+    - SAUCE: Revert "tools/power turbostat: Fix 32-bit capabilities warning"
+
+  * Miscellaneous upstream changes
+    - drm/i915: Fix eDP DPCD aux max backlight calculations
+    - drm/dp: Introduce EDID-based quirks
+    - drm/i915: Force DPCD backlight mode on X1 Extreme 2nd Gen 4K AMOLED panel
+    - drm/i915: Force DPCD backlight mode for some Dell CML 2020 panels
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 25 Mar 2020 18:09:13 +0100
+
+linux-5.6 (5.6.0-5.5) focal; urgency=medium
+
+  * please help enable CONFIG_EROFS_FS_ZIP (LP: #1867099)
+    - [Config] CONFIG_EROFS_FS_ZIP=y
+    - [Config] CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT=1
+
+  * Miscellaneous Ubuntu changes
+    - Config: Fix SND_HDA_PREALLOC_SIZE annotations
+    - Config: Fix DATA_SHIFT annotations
+    - Config: remove ANDROID_VSOC from annotations
+    - Config: remove arm arch from annotations
+    - Config: Update SOC_R8A7796X annotations
+    - Config: Update CLK_R8A7796X annotations
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.6-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 18 Mar 2020 17:25:30 +0100
+
+linux-5.6 (5.6.0-4.4) focal; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+    - [Packaging] update helper scripts
+
+  * Add sysfs attribute to show remapped NVMe (LP: #1863621)
+    - SAUCE: ata: ahci: Add sysfs attribute to show remapped NVMe device count
+
+  * [20.04 FEAT] Compression improvements in Linux kernel (LP: #1830208)
+    - [Config] Introducing s390x specific kernel config option CONFIG_ZLIB_DFLTCC
+
+  * [UBUNTU 20.04] s390x/pci: increase CONFIG_PCI_NR_FUNCTIONS to 512 in kernel
+    config (LP: #1866056)
+    - [Config] Increase CONFIG_PCI_NR_FUNCTIONS from 64 to 512 starting with focal
+      on s390x
+
+  * CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set (LP: #1865332)
+    - [Config] CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+
+  * [UBUNTU 20.04] Enable CONFIG_NET_SWITCHDEV in kernel config for s390x
+    starting with focal (LP: #1865452)
+    - [Config] Enable CONFIG_NET_SWITCHDEV in kernel config for s390x starting
+      with focal
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "UBUNTU: SAUCE: blk/core: Gracefully handle unset
+      make_request_fn"
+    - [Packaging] prevent duplicated entries in modules.ignore
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.6-rc5
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 Mar 2020 09:42:06 +0100
+
+linux-5.6 (5.6.0-3.3) focal; urgency=medium
+
+  * nsleep-lat / set-timer-lat / inconsistency-check / raw_skew from timer in
+    ubuntu_kernel_selftests timeout on 5.3 / 5.4 (LP: #1864626)
+    - selftests/timers: Turn off timeout setting
+
+  * Update kernel options CONFIG_NR_CPUS and CONFIG_NUMA_EMU for focal
+    (LP: #1864198)
+    - Ubuntu: [Config] Update kernel options CONFIG_NR_CPUS and CONFIG_NUMA_EMU
+
+  * alsa/hda/realtek: fix a mute led regression on Lenovo X1 Carbon
+    (LP: #1864576)
+    - SAUCE: ALSA: hda/realtek - Fix a regression for mute led on Lenovo Carbon X1
+
+  * r8152 init may take up to 40 seconds at initialization with Dell WD19/WD19DC
+    during hotplug (LP: #1864284)
+    - UBUNTU SAUCE: r8151: check disconnect status after long sleep
+
+  * Another Dell AIO backlight issue (LP: #1863880)
+    - SAUCE: platform/x86: dell-uart-backlight: move retry block
+
+  * Backport GetFB2 ioctl (LP: #1863874)
+    - SAUCE: drm: Add getfb2 ioctl
+
+  * Focal Fossa (20.04) feature request - Enable CONFIG_X86_UV (LP: #1863810)
+    - [Config] CONFIG_X86_UV=y
+
+  * Miscellaneous Ubuntu changes
+    - debian: remove snapdragon config, rules and flavour
+    - remove snapdragon abi files
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.6-rc4
+
+  * Miscellaneous upstream changes
+    - updateconfigs following snapdragon removal
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 04 Mar 2020 08:21:10 +0100
+
+linux-5.6 (5.6.0-2.2) focal; urgency=medium
+
+  * Sometimes can't adjust brightness on Dell AIO (LP: #1862885)
+    - SAUCE: platform/x86: dell-uart-backlight: increase retry times
+
+  * Dell XPS 13 (7390) Display Flickering - 19.10  (LP: #1849947)
+    - SAUCE: drm/i915: Disable PSR by default on all platforms
+
+  * Miscellaneous Ubuntu changes
+    - [debian] ignore missing wireguard module
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - [Config] CONFIG_LOCK_DOWN_IN_SECURE_BOOT=y
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.6-rc3
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (lockdown) s390/ipl: lockdown kernel when booted
+      secure"
+    - Revert "UBUNTU: SAUCE: (lockdown) KEYS: Make use of platform keyring for
+      module signature verify"
+    - Revert "UBUNTU: SAUCE: (lockdown) Add a SysRq option to lift kernel
+      lockdown"
+    - Revert "UBUNTU: SAUCE: (lockdown) security: lockdown: expose a hook to lock
+      the kernel down"
+    - Revert "UBUNTU: SAUCE: (lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err()."
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 24 Feb 2020 18:57:22 +0100
+
+linux-5.6 (5.6.0-1.1) focal; urgency=medium
+
+  *  Integrate Intel SGX driver into linux-azure (LP: #1844245)
+    - [Packaging] Add systemd service to load intel_sgx
+
+  * QAT drivers for C3XXX and C62X not included as modules (LP: #1845959)
+    - [Config] CRYPTO_DEV_QAT_C3XXX=m, CRYPTO_DEV_QAT_C62X=m and
+      CRYPTO_DEV_QAT_DH895xCC=m
+
+  * 5.4.0-11 crash on cryptsetup open (LP: #1860231)
+    - SAUCE: blk/core: Gracefully handle unset make_request_fn
+
+  * multi-zone raid0 corruption (LP: #1850540)
+    - SAUCE: md/raid0: Use kernel specific layout
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - update dropped.txt after rebase to v5.6-rc1
+    - [Config] updateconfigs after rebase to 5.6-rc1
+    - hio -- proc_create() requires a "struct proc_ops" in 5.6
+    - SAUCE: arm: fix build error in kvm tracepoint
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] Disable the uselib system call"
+    - Revert "UBUNTU: [Config] Disable legacy PTY naming"
+    - Revert "UBUNTU: [Config] Enforce filtered access to iomem"
+    - Revert "UBUNTU: [Config] Enable notifier call chain validations"
+    - Revert "UBUNTU: [Config] Enable scatterlist validation"
+    - Revert "UBUNTU: [Config] Enable cred sanity checks"
+    - Revert "UBUNTU: [Config] Enable linked list manipulation checks"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 13 Feb 2020 17:20:27 +0100
+
+linux-5.6 (5.6.0-0.0) focal; urgency=medium
+
+  * Dummy entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 10 Feb 2020 11:06:18 +0100
+
+linux-5.5 (5.5.0-7.8) focal; urgency=medium
+
+  * CONFIG_USELIB should be disabled (LP: #1855341)
+    - [Config] Disable the uselib system call
+
+  * CONFIG_LEGACY_PTYS should be disabled (LP: #1855339)
+    - [Config] Disable legacy PTY naming
+
+  * CONFIG_IO_STRICT_DEVMEM should be enabled (LP: #1855338)
+    - [Config] Enforce filtered access to iomem
+
+  * CONFIG_DEBUG_NOTIFIERS should be enabled (LP: #1855337)
+    - [Config] Enable notifier call chain validations
+
+  * CONFIG_DEBUG_SG should be enabled (LP: #1855336)
+    - [Config] Enable scatterlist validation
+
+  * CONFIG_DEBUG_CREDENTIALS should be enabled (LP: #1855335)
+    - [Config] Enable cred sanity checks
+
+  * CONFIG_DEBUG_LIST should be enabled (LP: #1855334)
+    - [Config] Enable linked list manipulation checks
+
+  * shiftfs: prevent lower dentries from going negative during unlink
+    (LP: #1860041)
+    - SAUCE: shiftfs: prevent lower dentries from going negative during unlink
+
+  * [SRU][B/OEM-B/OEM-OSP1/D/E/Unstable] UBUNTU: SAUCE: Use native backlight on
+    Lenovo E41-25/45 (LP: #1859561)
+    - SAUCE: ACPI: video: Use native backlight on Lenovo E41-25/45
+
+  * USB key cannot be detected by hotplug on Sunix USB Type-A 3.1 Gen 2 card
+    [1b21:2142]  (LP: #1858988)
+    - SAUCE: PCI: Avoid ASMedia XHCI USB PME# from D0 defect
+
+  * Dell AIO can't adjust brightness (LP: #1858761)
+    - SAUCE: platform/x86: dell-uart-backlight: add retry for get scalar status
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Fix typo in annotations file
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 27 Jan 2020 11:39:38 +0100
+
+linux-5.5 (5.5.0-6.7) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Update ubuntu-regression-suite dependency to python2
+    - [Packaging] Fix ubuntu-regression-suite python dependency for hwe kernel
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.5-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 20 Jan 2020 10:16:01 +0100
+
+linux-5.5 (5.5.0-5.6) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.5-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 13 Jan 2020 15:50:12 +0100
+
+linux-5.5 (5.5.0-4.5) focal; urgency=medium
+
+  * linux build and autopkg tests need to use python2 instead of python
+    (LP: #1858487)
+    - [Packaging] Remove python-dev build dependency
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Jan 2020 16:00:26 +0100
+
+linux-5.5 (5.5.0-3.4) focal; urgency=medium
+
+  * [SRU][B/OEM-B/OEM-OSP1/D/E/F] Add LG I2C touchscreen multitouch support
+    (LP: #1857541)
+    - SAUCE: HID: multitouch: Add LG MELF0410 I2C touchscreen support
+
+  * Make vfio-pci built-in or xhci_hcd optional (LP: #1770845)
+    - [Config]: built-in VFIO_PCI for amd64
+
+  * multi-zone raid0 corruption (LP: #1850540)
+    - SAUCE: md/raid0: Link to wiki with guidance on multi-zone RAID0 layout
+      migration
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Change source package to linux-5.5
+    - [Packaging] Don't use SRCPKGNAME for linux-libc-dev
+    - [Packaging] Remove linux-source-3 Provides: from linux-source
+    - [Packaging] Fix linux-doc in linux-image Suggests:
+    - [Debian] Read variants list into a variable
+    - [Packaging] Generate linux-libc-dev package only for primary variant
+    - [Packaging] Generate linux-doc for only the primary variant
+    - [Debian] Update linux source package name in debian/tests/*
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.5-rc3
+    - [Config] disable PCI_MESON
+    - [Config] Add pinctrl-equilibrium to modules.ignore
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.5-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Jan 2020 11:28:43 +0100
+
+linux-5.5 (5.5.0-2.3) focal; urgency=medium
+
+  * Empty entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 17 Dec 2019 22:33:59 -0600
+
+linux (5.5.0-2.3) focal; urgency=medium
+
+  * Support DPCD aux brightness control (LP: #1856134)
+    - SAUCE: drm/i915: Fix eDP DPCD aux max backlight calculations
+    - SAUCE: drm/i915: Assume 100% brightness when not in DPCD control mode
+    - SAUCE: drm/i915: Fix DPCD register order in intel_dp_aux_enable_backlight()
+    - SAUCE: drm/i915: Auto detect DPCD backlight support by default
+    - SAUCE: drm/i915: Force DPCD backlight mode on X1 Extreme 2nd Gen 4K AMOLED
+      panel
+    - USUNTU: SAUCE: drm/i915: Force DPCD backlight mode on Dell Precision 4K sku
+
+  * change kconfig of the soundwire bus driver from y to m (LP: #1855685)
+    - [Config]: SOUNDWIRE=m
+
+  * Fix unusable USB hub on Dell TB16 after S3 (LP: #1855312)
+    - SAUCE: USB: core: Make port power cycle a seperate helper function
+    - SAUCE: USB: core: Attempt power cycle port when it's in eSS.Disabled state
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] add python depends to ubuntu-regression-suite
+    - SAUCE: selftests: net: tls: remove recv_rcvbuf test
+    - update dkms package versions
+
+  * Miscellaneous upstream changes
+    - [Config] updateconfigs after rebase to 5.5-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 17 Dec 2019 16:02:43 +0100
+
+linux (5.5.0-1.2) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] disable nvidia dkms build
+    - [Config] disable virtualbox dkms build
+    - [Config] disable zfs dkms build
+    - update dropped.txt after rebase to v5.5-rc1
+    - SAUCE: (lockdown) Make get_cert_list() not complain about cert lists that
+      aren't present.
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - SAUCE: (lockdown) s390/ipl: lockdown kernel when booted secure
+    - [Config] Enable lockdown under secure boot
+    - update dkms package versions
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 12 Dec 2019 16:54:41 +0100
+
+linux (5.5.0-0.1) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after rebase to 5.5-rc1
+
+   [ Upstream Kernel Changes ]
+
+   * Rebase to v5.5-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 Dec 2019 19:03:35 +0100
+
+linux (5.5.0-0.0) focal; urgency=medium
+
+  * Dummy entry.
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 Dec 2019 15:14:37 +0100
+
+linux (5.4.0-8.11) focal; urgency=medium
+
+  * focal/linux: 5.4.0-8.9 -proposed tracker (LP: #1855448)
+
+  * update ENA driver for DIMLIB dynamic interrupt moderation (LP: #1853180)
+    - SAUCE: net: ena: fix issues in setting interrupt moderation params in
+      ethtool
+    - SAUCE: net: ena: fix too long default tx interrupt moderation interval
+
+  * Kernel build log filled with "/bin/bash: line 5: warning: command
+    substitution: ignored null byte in input" (LP: #1853843)
+    - [Debian] Fix warnings when checking for modules signatures
+
+  * hwe-edge kernel 5.3.0-23.25 kernel does not boot on Precision 5720 AIO
+    (LP: #1852581)
+    - [Packaging] Fix module signing with older modinfo
+
+  * Fix MST support on Ice Lake (LP: #1854432)
+    - drm/i915: fix port checks for MST support on gen >= 11
+
+  * headphone has noise as not mute on dell machines with alc236/256
+    (LP: #1854401)
+    - SAUCE: ALSA: hda/realtek - Dell headphone has noise on unmute for ALC236
+
+  * [CML-S62] Need enable intel_pmc_core driver patch for Comet lake- S 6+2
+    (LP: #1847450)
+    - SAUCE: platform/x86: intel_pmc_core: Add Comet Lake (CML) platform support
+      to intel_pmc_core driver
+
+  * CVE-2019-14901
+    - SAUCE: mwifiex: Fix heap overflow in mmwifiex_process_tdls_action_frame()
+
+  * CVE-2019-14896 // CVE-2019-14897
+    - SAUCE: libertas: Fix two buffer overflows at parsing bss descriptor
+
+  * CVE-2019-14895
+    - SAUCE: mwifiex: fix possible heap overflow in mwifiex_process_country_ie()
+
+  * [CML-S62] Need enable intel_rapl patch support for Comet lake- S 6+2
+    (LP: #1847454)
+    - powercap/intel_rapl: add support for CometLake Mobile
+    - powercap/intel_rapl: add support for Cometlake desktop
+
+  * External microphone can't work on some dell machines with the codec alc256
+    or alc236 (LP: #1853791)
+    - SAUCE: ALSA: hda/realtek - Move some alc256 pintbls to fallback table
+    - SAUCE: ALSA: hda/realtek - Move some alc236 pintbls to fallback table
+
+  * remount of multilower moved pivoted-root overlayfs root, results in I/O
+    errors on some modified files (LP: #1824407)
+    - SAUCE: ovl: fix lookup failure on multi lower squashfs
+
+  * [CML-S62] Need enable turbostat patch support for Comet lake- S 6+2
+    (LP: #1847451)
+    - SAUCE: tools/power turbostat: Add Cometlake support
+
+  * CONFIG_ARCH_ROCKCHIP is not set in ubuntu 18.04 aarch64,arm64 (LP: #1825222)
+    - [Config] Enable ROCKCHIP support for arm64
+
+  * [broadwell-rt286, playback] Since Linux 5.2rc2 audio playback no longer
+    works on Dell Venue 11 Pro 7140 (LP: #1846539)
+    - SAUCE: ASoC: SOF: Intel: Broadwell: clarify mutual exclusion with legacy
+      driver
+
+  * i40e: general protection fault in i40e_config_vf_promiscuous_mode
+    (LP: #1852663)
+    - SAUCE: i40e Fix GPF when deleting VMs
+
+  * libbpf check_abi fails on ppc64el (LP: #1854974)
+    - libbpf: Fix readelf output parsing on powerpc with recent binutils
+
+  * CVE-2019-19050
+    - crypto: user - fix memory leak in crypto_reportstat
+
+  * Make hotplugging docking station to Thunderbolt port more reliable
+    (LP: #1853991)
+    - PCI/PM: Add pcie_wait_for_link_delay()
+    - PCI/PM: Add missing link delays required by the PCIe spec
+
+  * i915: Display flickers (monitor loses signal briefly) during "flickerfree"
+    boot, while showing the BIOS logo on a black background (LP: #1836858)
+    - [Config] FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y
+
+  * [CML] New device id's for CMP-H (LP: #1846335)
+    - i2c: i801: Add support for Intel Comet Lake PCH-H
+    - mtd: spi-nor: intel-spi: Add support for Intel Comet Lake-H SPI serial flash
+    - mfd: intel-lpss: Add Intel Comet Lake PCH-H PCI IDs
+
+  * Focal update: v5.4.2 upstream stable release (LP: #1855326)
+    - io_uring: async workers should inherit the user creds
+    - net: separate out the msghdr copy from ___sys_{send,recv}msg()
+    - net: disallow ancillary data for __sys_{send,recv}msg_file()
+    - crypto: inside-secure - Fix stability issue with Macchiatobin
+    - driver core: platform: use the correct callback type for bus_find_device
+    - usb: dwc2: use a longer core rest timeout in dwc2_core_reset()
+    - staging: wilc1000: fix illegal memory access in wilc_parse_join_bss_param()
+    - staging: rtl8192e: fix potential use after free
+    - staging: rtl8723bs: Drop ACPI device ids
+    - staging: rtl8723bs: Add 024c:0525 to the list of SDIO device-ids
+    - USB: serial: ftdi_sio: add device IDs for U-Blox C099-F9P
+    - mei: bus: prefix device names on bus with the bus name
+    - mei: me: add comet point V device id
+    - thunderbolt: Power cycle the router if NVM authentication fails
+    - x86/fpu: Don't cache access to fpu_fpregs_owner_ctx
+    - gve: Fix the queue page list allocated pages count
+    - macvlan: schedule bc_work even if error
+    - mdio_bus: don't use managed reset-controller
+    - net: dsa: sja1105: fix sja1105_parse_rgmii_delays()
+    - net: macb: add missed tasklet_kill
+    - net: psample: fix skb_over_panic
+    - net: sched: fix `tc -s class show` no bstats on class with nolock subqueues
+    - openvswitch: fix flow command message size
+    - sctp: Fix memory leak in sctp_sf_do_5_2_4_dupcook
+    - slip: Fix use-after-free Read in slip_open
+    - sctp: cache netns in sctp_ep_common
+    - openvswitch: drop unneeded BUG_ON() in ovs_flow_cmd_build_info()
+    - openvswitch: remove another BUG_ON()
+    - net/tls: take into account that bpf_exec_tx_verdict() may free the record
+    - net/tls: free the record on encryption error
+    - net: skmsg: fix TLS 1.3 crash with full sk_msg
+    - selftests/tls: add a test for fragmented messages
+    - net/tls: remove the dead inplace_crypto code
+    - net/tls: use sg_next() to walk sg entries
+    - selftests: bpf: test_sockmap: handle file creation failures gracefully
+    - selftests: bpf: correct perror strings
+    - tipc: fix link name length check
+    - selftests: pmtu: use -oneline for ip route list cache
+    - r8169: fix jumbo configuration for RTL8168evl
+    - r8169: fix resume on cable plug-in
+    - ext4: add more paranoia checking in ext4_expand_extra_isize handling
+    - Revert "jffs2: Fix possible null-pointer dereferences in
+      jffs2_add_frag_to_fragtree()"
+    - crypto: talitos - Fix build error by selecting LIB_DES
+    - HID: core: check whether Usage Page item is after Usage ID items
+    - platform/x86: hp-wmi: Fix ACPI errors caused by too small buffer
+    - platform/x86: hp-wmi: Fix ACPI errors caused by passing 0 as input size
+    - Linux 5.4.2
+
+  * no HDMI video output since GDM greeter after linux-oem-osp1 version
+    5.0.0-1026 (LP: #1852386)
+    - drm/i915: Add new CNL PCH ID seen on a CML platform
+    - SAUCE: drm/i915: Fix detection for a CMP-V PCH
+
+  * Please add patch fixing RK818 ID detection (LP: #1853192)
+    - SAUCE: mfd: rk808: Fix RK818 ID template
+
+  * Raydium Touchscreen on ThinkPad L390 does not work (LP: #1849721)
+    - HID: i2c-hid: fix no irq after reset on raydium 3118
+
+  * Touchpad doesn't work on Dell Inspiron 7000 2-in-1 (LP: #1851901)
+    - Revert "UBUNTU: SAUCE: mfd: intel-lpss: add quirk for Dell XPS 13 7390
+      2-in-1"
+    - lib: devres: add a helper function for ioremap_uc
+    - mfd: intel-lpss: Use devm_ioremap_uc for MMIO
+
+  * Lenovo dock MAC Address pass through doesn't work in Ubuntu  (LP: #1827961)
+    - r8152: Add macpassthru support for ThinkPad Thunderbolt 3 Dock Gen 2
+
+  * Disable unreliable HPET on CFL-H system (LP: #1852216)
+    - SAUCE: x86/intel: Disable HPET on Intel Coffe Lake H platforms
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] Enable virtualbox dkms build
+    - [Config] update annotations to match current configs
+    - SAUCE: Add exfat module to signature inclusion list
+
+  * Miscellaneous upstream changes
+    - Bluetooth: Fix invalid-free in bcsp_close()
+    - ath9k_hw: fix uninitialized variable data
+    - ath10k: Fix a NULL-ptr-deref bug in ath10k_usb_alloc_urb_from_pipe
+    - ath10k: Fix HOST capability QMI incompatibility
+    - ath10k: restore QCA9880-AR1A (v1) detection
+    - Revert "Bluetooth: hci_ll: set operational frequency earlier"
+    - Revert "dm crypt: use WQ_HIGHPRI for the IO and crypt workqueues"
+    - md/raid10: prevent access of uninitialized resync_pages offset
+    - x86/insn: Fix awk regexp warnings
+    - x86/speculation: Fix incorrect MDS/TAA mitigation status
+    - x86/speculation: Fix redundant MDS mitigation message
+    - nbd: prevent memory leak
+    - x86/stackframe/32: Repair 32-bit Xen PV
+    - x86/xen/32: Make xen_iret_crit_fixup() independent of frame layout
+    - x86/xen/32: Simplify ring check in xen_iret_crit_fixup()
+    - x86/doublefault/32: Fix stack canaries in the double fault handler
+    - x86/pti/32: Size initial_page_table correctly
+    - x86/cpu_entry_area: Add guard page for entry stack on 32bit
+    - x86/entry/32: Fix IRET exception
+    - x86/entry/32: Use %ss segment where required
+    - x86/entry/32: Move FIXUP_FRAME after pushing %fs in SAVE_ALL
+    - x86/entry/32: Unwind the ESPFIX stack earlier on exception entry
+    - x86/entry/32: Fix NMI vs ESPFIX
+    - selftests/x86/mov_ss_trap: Fix the SYSENTER test
+    - selftests/x86/sigreturn/32: Invalidate DS and ES when abusing the kernel
+    - x86/pti/32: Calculate the various PTI cpu_entry_area sizes correctly, make
+      the CPU_ENTRY_AREA_PAGES assert precise
+    - x86/entry/32: Fix FIXUP_ESPFIX_STACK with user CR3
+    - futex: Prevent robust futex exit race
+    - ALSA: usb-audio: Fix NULL dereference at parsing BADD
+    - ALSA: usb-audio: Fix Scarlett 6i6 Gen 2 port data
+    - media: vivid: Set vid_cap_streaming and vid_out_streaming to true
+    - media: vivid: Fix wrong locking that causes race conditions on streaming
+      stop
+    - media: usbvision: Fix invalid accesses after device disconnect
+    - media: usbvision: Fix races among open, close, and disconnect
+    - cpufreq: Add NULL checks to show() and store() methods of cpufreq
+    - futex: Move futex exit handling into futex code
+    - futex: Replace PF_EXITPIDONE with a state
+    - exit/exec: Seperate mm_release()
+    - futex: Split futex_mm_release() for exit/exec
+    - futex: Set task::futex_state to DEAD right after handling futex exit
+    - futex: Mark the begin of futex exit explicitly
+    - futex: Sanitize exit state handling
+    - futex: Provide state handling for exec() as well
+    - futex: Add mutex around futex exit
+    - futex: Provide distinct return value when owner is exiting
+    - futex: Prevent exit livelock
+    - media: uvcvideo: Fix error path in control parsing failure
+    - media: b2c2-flexcop-usb: add sanity checking
+    - media: cxusb: detect cxusb_ctrl_msg error in query
+    - media: imon: invalid dereference in imon_touch_event
+    - media: mceusb: fix out of bounds read in MCE receiver buffer
+    - ALSA: hda - Disable audio component for legacy Nvidia HDMI codecs
+    - USBIP: add config dependency for SGL_ALLOC
+    - usbip: tools: fix fd leakage in the function of read_attr_usbip_status
+    - usbip: Fix uninitialized symbol 'nents' in stub_recv_cmd_submit()
+    - usb-serial: cp201x: support Mark-10 digital force gauge
+    - USB: chaoskey: fix error case of a timeout
+    - appledisplay: fix error handling in the scheduled work
+    - USB: serial: mos7840: add USB ID to support Moxa UPort 2210
+    - USB: serial: mos7720: fix remote wakeup
+    - USB: serial: mos7840: fix remote wakeup
+    - USB: serial: option: add support for DW5821e with eSIM support
+    - USB: serial: option: add support for Foxconn T77W968 LTE modules
+    - staging: comedi: usbduxfast: usbduxfast_ai_cmdtest rounding error
+    - powerpc/book3s64: Fix link stack flush on context switch
+    - KVM: PPC: Book3S HV: Flush link stack on guest exit to host kernel
+    - Linux 5.4.1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 06 Dec 2019 15:53:53 -0600
+
+linux (5.4.0-7.8) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/bpf: Comment out BPF_CORE_READ's which cause clang to
+      segfault
+    - Update nvidia-430 to nvidia-440
+    - [Config] Enable nvidia dkms build
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 25 Nov 2019 15:02:30 +0100
+
+linux (5.4.0-6.7) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.4-rc8
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 18 Nov 2019 12:08:01 +0100
+
+linux (5.4.0-5.6) focal; urgency=medium
+
+  * refcount underflow and type confusion in shiftfs (LP: #1850867) //
+    CVE-2019-15793
+    - SAUCE: shiftfs: Correct id translation for lower fs operations
+
+  * refcount underflow and type confusion in shiftfs (LP: #1850867) //
+    CVE-2019-15792
+    - SAUCE: shiftfs: prevent type confusion
+
+  * refcount underflow and type confusion in shiftfs (LP: #1850867) //
+    CVE-2019-15791
+    - SAUCE: shiftfs: Fix refcount underflow in btrfs ioctl handling
+
+  * Some EFI systems fail to boot in efi_init() when booted via maas
+    (LP: #1851810)
+    - SAUCE: efi: efi_get_memory_map -- increase map headroom
+
+  * seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test (LP: #1849281)
+    - SAUCE: seccomp: rework define for SECCOMP_USER_NOTIF_FLAG_CONTINUE
+    - SAUCE: seccomp: avoid overflow in implicit constant conversion
+
+  * dkms artifacts may expire from the pool (LP: #1850958)
+    - [Packaging] dkms -- try launchpad librarian for pool downloads
+    - [Packaging] dkms -- dkms-build quieten wget verbiage
+
+  * tsc marked unstable after entered PC10 on Intel CoffeeLake (LP: #1840239)
+    - SAUCE: x86/intel: Disable HPET on Intel Coffe Lake platforms
+    - SAUCE: x86/intel: Disable HPET on Intel Ice Lake platforms
+
+  * shiftfs: prevent exceeding project quotas (LP: #1849483)
+    - SAUCE: shiftfs: drop CAP_SYS_RESOURCE from effective capabilities
+
+  * shiftfs: fix fallocate() (LP: #1849482)
+    - SAUCE: shiftfs: setup correct s_maxbytes limit
+
+  * The alsa hda driver is not loaded due to the missing of PCIID for Comet
+    Lake-S [8086:a3f0] (LP: #1852070)
+    - SAUCE: ALSA: hda: Add Cometlake-S PCI ID
+
+  * Can't adjust brightness on DELL UHD dGPU AIO (LP: #1813877)
+    - SAUCE: platform/x86: dell-uart-backlight: add missing status command
+    - SAUCE: platform/x86: dell-uart-backlight: load driver by scalar status
+    - SAUCE: platform/x86: dell-uart-backlight: add force parameter
+    - SAUCE: platform/x86: dell-uart-backlight: add quirk for old platforms
+
+  * s_iflags overlap prevents unprivileged overlayfs mounts (LP: #1851677)
+    - SAUCE: fs: Move SB_I_NOSUID to the top of s_iflags
+
+  * ubuntu-aufs-modified mmap_region() breaks refcounting in overlayfs/shiftfs
+    error path (LP: #1850994) // CVE-2019-15794
+    - SAUCE: shiftfs: Restore vm_file value when lower fs mmap fails
+    - SAUCE: ovl: Restore vm_file value when lower fs mmap fails
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Convert update-aufs.sh to use aufs5
+    - SAUCE: import aufs driver
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 13 Nov 2019 11:56:35 -0800
+
+linux (5.4.0-4.5) focal; urgency=medium
+
+  * High power consumption using 5.0.0-25-generic (LP: #1840835)
+    - PCI: Add a helper to check Power Resource Requirements _PR3 existence
+    - ALSA: hda: Allow HDA to be runtime suspended when dGPU is not bound to a
+      driver
+    - PCI: Fix missing inline for pci_pr3_present()
+
+  * Fix signing of staging modules in eoan (LP: #1850234)
+    - [Packaging] Leave unsigned modules unsigned after adding .gnu_debuglink
+
+  * [20.04 FEAT] Set Architecture Level (ALS) to z13 (LP: #1837525)
+    - [Config] s390x bump march to z13, with tune to z15
+
+  * Miscellaneous Ubuntu changes
+    - [Debian]: do not skip tests for linux-hwe-edge
+    - update dkms package versions
+    - [Config] re-enable zfs
+    - [Config] rename module virtio_fs to virtiofs
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 04 Nov 2019 15:12:02 +0100
+
+linux (5.4.0-3.4) focal; urgency=medium
+
+  * seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test (LP: #1849281)
+    - SAUCE: seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test
+
+  * cloudimg: no iavf/i40evf module so no network available with SR-IOV enabled
+    cloud (LP: #1848481)
+    - [Packaging] include iavf/i40evf in generic
+
+  * CVE-2019-17666
+    - SAUCE: rtlwifi: Fix potential overflow on P2P code
+
+  * Change Config Option CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE for s390x from yes
+    to no (LP: #1848492)
+    - [Config] Change Config Option CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE for s390x
+      from yes to no
+
+  * Add Intel Comet Lake ethernet support (LP: #1848555)
+    - SAUCE: e1000e: Add support for Comet Lake
+
+  * seccomp: add SECCOMP_USER_NOTIF_FLAG_CONTINUE    (LP: #1847744)
+    - SAUCE: seccomp: add SECCOMP_USER_NOTIF_FLAG_CONTINUE
+    - SAUCE: seccomp: test SECCOMP_USER_NOTIF_FLAG_CONTINUE
+
+  * drm/i915: Fix the issue of "azx_get_response timeout" for hdmi audio on ICL
+    platforms (LP: #1847192)
+    - SAUCE: drm/i915: Fix audio power up sequence for gen10+ display
+    - SAUCE: drm/i915: extend audio CDCLK>=2*BCLK constraint to more platforms
+
+  * PM / hibernate: fix potential memory corruption (LP: #1847118)
+    - SAUCE: PM / hibernate: memory_bm_find_bit -- tighten node optimisation
+
+  * [regression] NoNewPrivileges incompatible with Apparmor (LP: #1844186)
+    - SAUCE: apparmor: fix nnp subset test for unconfined
+
+  * overlayfs: allow with shiftfs as underlay (LP: #1846272)
+    - SAUCE: overlayfs: allow with shiftfs as underlay
+
+  * eoan: alsa/sof: Enable SOF_HDA link and codec (LP: #1848490)
+    - [Config] Fix SOF Kconfig options
+
+  * linux won't build when new virtualbox version is present on the archive
+    (LP: #1848788)
+    - [Packaging]: download virtualbox from sources
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations from configs
+    - [Config] updateconfigs after rebase to 5.4-rc5
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 29 Oct 2019 12:01:27 -0500
+
+linux (5.4.0-2.3) eoan; urgency=medium
+
+  * Add installer support for iwlmvm adapters (LP: #1848236)
+    - d-i: Add iwlmvm to nic-modules
+
+  * shiftfs: rework how shiftfs opens files (LP: #1846265)
+    - SAUCE: shiftfs: rework how shiftfs opens files
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.4-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 21 Oct 2019 17:31:26 +0200
+
+linux (5.4.0-1.2) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.4-rc3
+    - [Config] add flexfb, fbtft_device and rio500 to modules.ignore
+    - [Config] amd64: ignore fbtft and all dependent modules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 14 Oct 2019 19:48:52 +0200
+
+linux (5.4.0-0.1) eoan; urgency=medium
+
+  * Enable the Dragonboards out of Eoan/master arm64 kernel (LP: #1846704)
+    - [Packaging] arm64: snapdragon: introduce a snapdragon flavour
+    - [Packaging] arm64: snapdragon: switch kernel format to Image
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8916=y
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8994=y
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8996=y
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8998=y
+    - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_RPMH=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_BAM_DMA=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_HIDMA_MGMT=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_HIDMA=y
+    - [Config] arm64: snapdragon: CONFIG_COMMON_CLK_QCOM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_RPMH=y
+    - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8916=y
+    - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8994=y
+    - [Config] arm64: snapdragon: CONFIG_MSM_MMCC_8996=y
+    - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8998=y
+    - [Config] arm64: snapdragon: CONFIG_HWSPINLOCK_QCOM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_APCS_IPC=y
+    - [Config] arm64: snapdragon: CONFIG_RPMSG_QCOM_GLINK_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_GENI_SE=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_SMEM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_SMD_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_SMP2P=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_SMSM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_QFPROM=y
+    - [Config] arm64: snapdragon: CONFIG_SERIAL_QCOM_GENI=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_TSENS=y
+    - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_SMD_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_SMD_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_RPMSG_QCOM_SMD=y
+    - [Config] arm64: snapdragon: CONFIG_MFD_QCOM_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_SCSI_UFSHCD=y
+    - [Config] arm64: snapdragon: CONFIG_SCSI_UFSHCD_PLATFORM=y
+    - [Config] arm64: snapdragon: CONFIG_SCSI_UFS_HISI=y
+    - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI=y
+    - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI_PLTFM=y
+    - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI_MSM=y
+    - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_SPMI=y
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+    - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_USB_HS=y
+    - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_QMP=y
+    - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_UFS=y
+    - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_USB_HSIC=y
+    - [Config] arm64: snapdragon: CONFIG_USB_CHIPIDEA_OF=y
+    - [Config] arm64: snapdragon: CONFIG_USB_EHCI_HCD_PLATFORM=y
+    - [Config] arm64: snapdragon: CONFIG_EXTCON_USB_GPIO=y
+    - [Config] arm64: snapdragon: CONFIG_REGULATOR_FIXED_VOLTAGE=y
+    - [Config] arm64: snapdragon: CONFIG_LEDS_GPIO=y
+    - [Config] arm64: snapdragon: CONFIG_USB_HSIC_USB3503=y
+    - [Config] arm64: snapdragon: CONFIG_USB_NET_DRIVERS=y
+    - [Config] arm64: snapdragon: CONFIG_USB_OTG=y
+    - [Config] arm64: snapdragon: CONFIG_USB_XHCI_PLATFORM=y
+    - [Config] arm64: snapdragon: CONFIG_USB_OHCI_HCD_PLATFORM=y
+    - [Config] arm64: snapdragon: CONFIG_USB_MUSB_HDRC=y
+    - [Config] arm64: snapdragon: CONFIG_USB_DWC3=y
+    - [Config] arm64: snapdragon: CONFIG_USB_DWC3_PCI=y
+    - [Config] arm64: snapdragon: CONFIG_USB_DWC3_OF_SIMPLE=y
+    - [Config] arm64: snapdragon: CONFIG_USB_DWC3_QCOM=y
+    - [Config] arm64: snapdragon: CONFIG_LEDS_PWM=y
+    - [Config] arm64: snapdragon: CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+    - [Config] arm64: snapdragon: CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_A53PLL=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_APCS_MSM8916=y
+    - [Config] arm64: snapdragon: CONFIG_NLS_ISO8859_1=y
+    - [Config] arm64: snapdragon: CONFIG_USB_USBNET=y
+    - [Config] arm64: snapdragon: CONFIG_CRYPTO_DEV_QCOM_RNG=y
+    - [Config] arm64: snapdragon: CONFIG_POWER_RESET_QCOM_PON=y
+    - [Config] arm64: snapdragon: CONFIG_INPUT_PM8941_PWRKEY=y
+    - [Config] arm64: snapdragon: CONFIG_KEYBOARD_GPIO=y
+    - [Config] arm64: snapdragon: CONFIG_RTC_DRV_PM8XXX=y
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after rebase to 5.4-rc2
+    - SAUCE: (lockdown) Make get_cert_list() not complain about cert lists that
+      aren't present.
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - SAUCE: (lockdown) s390/ipl: lockdown kernel when booted secure
+    - [Config] Enable lockdown under secure boot
+    - SAUCE: import aufs driver
+    - SAUCE: aufs: rwsem owner changed to atmoic_long_t in 5.3
+    - SAUCE: aufs: add "WITH Linux-syscall-note" to SPDX tag of uapi headers
+    - [Config] enable aufs
+    - update dkms package versions
+    - [Config] disable zfs
+    - [Config] disable nvidia dkms build
+    - [Config] disable virtualbox dkms build
+    - [Debian] Generate stub reconstruct for -rc kernels
+    - Revert "UBUNTU: SAUCE: (namespace) block_dev: Forbid unprivileged mounting
+      when device is opened for writing"
+    - Revert "UBUNTU: SAUCE: (namespace) ext4: Add module parameter to enable user
+      namespace mounts"
+    - Revert "UBUNTU: SAUCE: (namespace) ext4: Add support for unprivileged mounts
+      from user namespaces"
+    - Revert "UBUNTU: SAUCE: (namespace) mtd: Check permissions towards mtd block
+      device inode when mounting"
+    - Revert "UBUNTU: SAUCE: (namespace) block_dev: Check permissions towards
+      block device inode when mounting"
+    - Revert "UBUNTU: SAUCE: (namespace) block_dev: Support checking inode
+      permissions in lookup_bdev()"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 11 Oct 2019 16:42:41 -0500
+
+linux (5.4.0-0.0) eoan; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 08 Oct 2019 09:59:00 -0500
+
+linux (5.3.0-17.18) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-17.18 -proposed tracker (LP: #1846641)
+
+  * CVE-2019-17056
+    - nfc: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-17055
+    - mISDN: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-17054
+    - appletalk: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-17053
+    - ieee802154: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-17052
+    - ax25: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-15098
+    - ath6kl: fix a NULL-ptr-deref bug in ath6kl_usb_alloc_urb_from_pipe()
+
+  * xHCI on AMD Stoney Ridge cannot detect USB 2.0 or 1.1 devices.
+    (LP: #1846470)
+    - x86/PCI: Avoid AMD FCH XHCI USB PME# from D0 defect
+
+  * Re-enable linux-libc-dev build on i386 (LP: #1846508)
+    - [Packaging] Build only linux-libc-dev for i386
+    - [Debian] final-checks -- ignore archtictures with no binaries
+
+  * arm64: loop on boot after installing linux-generic-hwe-18.04-edge/bionic-
+    proposed (LP: #1845820)
+    - [Config] Disable CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
+
+  * Revert ESE DASD discard support (LP: #1846219)
+    - SAUCE: Revert "s390/dasd: Add discard support for ESE volumes"
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 03 Oct 2019 16:57:05 -0500
+
+linux (5.3.0-16.17) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-16.17 -proposed tracker (LP: #1846204)
+
+  * zfs fails to build on s390x  with debug symbols enabled (LP: #1846143)
+    - SAUCE: s390: Mark atomic const ops always inline
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 01 Oct 2019 07:46:43 -0500
+
+linux (5.3.0-15.16) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-15.16 -proposed tracker (LP: #1845987)
+
+  * Drop i386 build for 19.10 (LP: #1845714)
+    - [Packaging] Remove x32 arch references from control files
+    - [Debian] final-checks -- Get arch list from debian/control
+
+  * ZFS kernel modules lack debug symbols (LP: #1840704)
+    - [Debian] Fix conditional for setting zfs debug package path
+
+  * Use pyhon3-sphinx instead of python-sphinx for building html docs
+    (LP: #1845808)
+    - [Packaging] Update sphinx build dependencies to python3 packages
+
+  * Kernel panic with 19.10 beta image (LP: #1845454)
+    - efi/tpm: Don't access event->count when it isn't mapped.
+    - efi/tpm: don't traverse an event log with no events
+    - efi/tpm: only set efi_tpm_final_log_size after successful event log parsing
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 30 Sep 2019 11:57:20 -0500
+
+linux (5.3.0-14.15) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-14.15 -proposed tracker (LP: #1845728)
+
+  * Drop i386 build for 19.10 (LP: #1845714)
+    - [Debian] Remove support for producing i386 kernels
+    - [Debian] Don't use CROSS_COMPILE for i386 configs
+
+  * udevadm trigger will fail when trying to add /sys/devices/vio/
+    (LP: #1845572)
+    - SAUCE: powerpc/vio: drop bus_type from parent device
+
+  * Trying to online dasd drive results in invalid input/output from the kernel
+    on z/VM (LP: #1845323)
+    - SAUCE: s390/dasd: Fix error handling during online processing
+
+  * intel-lpss driver conflicts with write-combining MTRR region (LP: #1845584)
+    - SAUCE: mfd: intel-lpss: add quirk for Dell XPS 13 7390 2-in-1
+
+  * Support Hi1620 zip hw accelerator (LP: #1845355)
+    - [Config] Enable HiSilicon QM/ZIP as modules
+    - crypto: hisilicon - add queue management driver for HiSilicon QM module
+    - crypto: hisilicon - add hardware SGL support
+    - crypto: hisilicon - add HiSilicon ZIP accelerator support
+    - crypto: hisilicon - add SRIOV support for ZIP
+    - Documentation: Add debugfs doc for hisi_zip
+    - crypto: hisilicon - add debugfs for ZIP and QM
+    - MAINTAINERS: add maintainer for HiSilicon QM and ZIP controller driver
+    - crypto: hisilicon - fix kbuild warnings
+    - crypto: hisilicon - add dependency for CRYPTO_DEV_HISI_ZIP
+    - crypto: hisilicon - init curr_sgl_dma to fix compile warning
+    - crypto: hisilicon - add missing single_release
+    - crypto: hisilicon - fix error handle in hisi_zip_create_req_q
+    - crypto: hisilicon - Fix warning on printing %p with dma_addr_t
+    - crypto: hisilicon - Fix return value check in hisi_zip_acompress()
+    - crypto: hisilicon - avoid unused function warning
+
+  * SafeSetID LSM should be built but disabled by default (LP: #1845391)
+    - LSM: SafeSetID: Stop releasing uninitialized ruleset
+    - [Config] Build SafeSetID LSM but don't enable it by default
+
+  * CONFIG_LSM should not specify loadpin since it is not built (LP: #1845383)
+    - [Config] loadpin shouldn't be in CONFIG_LSM
+
+  * Add new pci-id's for CML-S, ICL (LP: #1845317)
+    - drm/i915/icl: Add missing device ID
+    - drm/i915/cml: Add Missing PCI IDs
+
+  * Thunderbolt support for ICL (LP: #1844680)
+    - thunderbolt: Correct path indices for PCIe tunnel
+    - thunderbolt: Move NVM upgrade support flag to struct icm
+    - thunderbolt: Use 32-bit writes when writing ring producer/consumer
+    - thunderbolt: Do not fail adding switch if some port is not implemented
+    - thunderbolt: Hide switch attributes that are not set
+    - thunderbolt: Expose active parts of NVM even if upgrade is not supported
+    - thunderbolt: Add support for Intel Ice Lake
+    - ACPI / property: Add two new Thunderbolt property GUIDs to the list
+
+  * Ubuntu 19.10 -  Additional PCI patch and fix (LP: #1844668)
+    - s390/pci: fix MSI message data
+
+  * Enhanced Hardware Support - Finalize Naming (LP: #1842774)
+    - s390: add support for IBM z15 machines
+    - [Config] CONFIG_MARCH_Z15=n, CONFIG_TUNE_Z15=n
+
+  * Eoan update: v5.3.1 upstream stable release (LP: #1845642)
+    - USB: usbcore: Fix slab-out-of-bounds bug during device reset
+    - media: tm6000: double free if usb disconnect while streaming
+    - phy: renesas: rcar-gen3-usb2: Disable clearing VBUS in over-current
+    - ip6_gre: fix a dst leak in ip6erspan_tunnel_xmit
+    - net/sched: fix race between deactivation and dequeue for NOLOCK qdisc
+    - net_sched: let qdisc_put() accept NULL pointer
+    - udp: correct reuseport selection with connected sockets
+    - xen-netfront: do not assume sk_buff_head list is empty in error handling
+    - net: dsa: Fix load order between DSA drivers and taggers
+    - net: stmmac: Hold rtnl lock in suspend/resume callbacks
+    - KVM: coalesced_mmio: add bounds checking
+    - Documentation: sphinx: Add missing comma to list of strings
+    - firmware: google: check if size is valid when decoding VPD data
+    - serial: sprd: correct the wrong sequence of arguments
+    - tty/serial: atmel: reschedule TX after RX was started
+    - nl80211: Fix possible Spectre-v1 for CQM RSSI thresholds
+    - Revert "arm64: Remove unnecessary ISBs from set_{pte,pmd,pud}"
+    - ovl: fix regression caused by overlapping layers detection
+    - phy: qcom-qmp: Correct ready status, again
+    - floppy: fix usercopy direction
+    - media: technisat-usb2: break out of loop at end of buffer
+    - Linux 5.3.1
+
+  * ZFS kernel modules lack debug symbols (LP: #1840704)
+    - [Debian]: Remove hardcoded $(pkgdir) in debug symbols handling
+    - [Debian]: Handle debug symbols for modules in extras too
+    - [Debian]: Check/link modules with debug symbols after DKMS modules
+    - [Debian]: Warn about modules without debug symbols
+    - [Debian]: dkms-build: new parameter for debug package directory
+    - [Debian]: dkms-build: zfs: support for debug symbols
+    - [Debian]: dkms-build: Avoid executing post-processor scripts twice
+    - [Debian]: dkms-build: Move zfs special-casing into configure script
+
+  * /proc/self/maps paths missing on live session (was vlc won't start; eoan
+    19.10 & bionic 18.04 ubuntu/lubuntu/kubuntu/xubuntu/ubuntu-mate dailies)
+    (LP: #1842382)
+    - SAUCE: Revert "UBUNTU: SAUCE: shiftfs: enable overlayfs on shiftfs"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 27 Sep 2019 16:08:06 -0500
+
+linux (5.3.0-13.14) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-13.14 -proposed tracker (LP: #1845105)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Remove binutils-dev build dependency
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 23 Sep 2019 19:26:43 -0500
+
+linux (5.3.0-12.13) eoan; urgency=medium
+
+  * Change kernel compression method to improve boot speed (LP: #1840934)
+    - [Packaging] Add lz4 build dependency for s390x
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Remove spl and zfs source
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 17 Sep 2019 13:36:26 +0200
+
+linux (5.3.0-11.12) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-11.12 -proposed tracker (LP: #1844144)
+
+  *  Suspend to RAM(S3) does not wake up for latest megaraid and mpt3sas
+    adapters(SAS3.5 onwards) (LP: #1838751)
+    - PCI: Restore Resizable BAR size bits correctly for 1MB BARs
+
+  * s390/setup: Actually init kernel lock down (LP: #1843961)
+    - SAUCE: (lockdown) s390/setup: Actually init kernel lock down
+
+  * cherrypick has_sipl fix (LP: #1843960)
+    - SAUCE: s390/sclp: Fix bit checked for has_sipl
+
+  * Change kernel compression method to improve boot speed (LP: #1840934)
+    - [Config]: Switch kernel compression from LZO to LZ4 on s390x
+
+  * Installation fails on eoan/PowerVM : missing /dev/nvram (LP: #1837726)
+    - [Config] CONFIG_NVRAM=y for ppc64el
+
+  * Miscellaneous Ubuntu changes
+    - [Config]: remove nvram from ppc64el modules ABI
+    - [Config] Update annotations for recent config changes
+    - SAUCE: sched: Add __ASSEMBLY__ guards around struct clone_args
+    - SAUCE: i2c: qcom-geni: Disable DMA processing on the Lenovo Yoga C630
+    - SAUCE: arm64: dts: qcom: Add Lenovo Yoga C630
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 16 Sep 2019 16:18:27 +0200
+
+linux (5.3.0-10.11) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-10.11 -proposed tracker (LP: #1843232)
+
+  * No sound inputs from the external microphone and headset on a Dell machine
+    (LP: #1842265)
+    - SAUCE: ALSA: hda - Expand pin_match function to match upcoming new tbls
+    - SAUCE: ALSA: hda - Define a fallback_pin_fixup_tbl for alc269 family
+
+  * Horizontal corrupted line at top of screen caused by framebuffer compression
+    (LP: #1840236)
+    - SAUCE: drm/i915/fbc: disable framebuffer compression on IceLake
+
+  * Add bpftool to linux-tools-common (LP: #1774815)
+    - [Debian] package bpftool in linux-tools-common
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc8
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 09 Sep 2019 10:00:41 +0200
+
+linux (5.3.0-9.10) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-9.10 -proposed tracker (LP: #1842393)
+
+  * shiftfs: mark kmem_cache as reclaimable (LP: #1842059)
+    - SAUCE: shiftfs: mark slab objects SLAB_RECLAIM_ACCOUNT
+
+  * shiftfs: drop entries from cache on unlink (LP: #1841977)
+    - SAUCE: shiftfs: fix buggy unlink logic
+
+  * Fix touchpad IRQ storm after S3 (LP: #1841396)
+    - pinctrl: intel: remap the pin number to gpio offset for irq enabled pin
+
+  * Please include DTBs for arm64 laptops (LP: #1842050)
+    - arm64: dts: qcom: Add Lenovo Miix 630
+    - arm64: dts: qcom: Add HP Envy x2
+    - arm64: dts: qcom: Add Asus NovaGo TP370QL
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: import aufs driver
+    - [Packaging]: ignore vbox modules when vbox is disabled
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 03 Sep 2019 10:27:33 +0200
+
+linux (5.3.0-8.9) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+
+  * Change kernel compression method to improve boot speed (LP: #1840934)
+    - [Config] change kernel compression method to improve boot speed
+    - [Packaging] add build dependencies for compression algorithms
+
+  * realtek r8822be kernel module fails after update to linux kernel-headers
+    5.0.0-21 (LP: #1838133)
+    - rtw88: Fix misuse of GENMASK macro
+    - rtw88: pci: Rearrange the memory usage for skb in RX ISR
+    - rtw88: pci: Use DMA sync instead of remapping in RX ISR
+    - rtw88: debug: dump tx power indexes in use
+    - rtw88: use txpwr_lmt_cfg_pair struct, not arrays
+    - rtw88: pci: remove set but not used variable 'ip_sel'
+    - rtw88: allow c2h operation in irq context
+    - rtw88: enclose c2h cmd handle with mutex
+    - rtw88: add BT co-existence support
+    - SAUCE: rtw88: pci: enable MSI interrupt
+
+  * VIMC module not available (CONFIG_VIDEO_VIMC not set) (LP: #1831482)
+    - [Config] Enable VIMC module
+
+  * Goodix touchpad may drop first input event (LP: #1840075)
+    - Revert "UBUNTU: SAUCE: i2c: designware: add G3 3590 into i2c quirk"
+    - Revert "UBUNTU: SAUCE: i2c: designware: add Inpiron 7591 into i2c quirk"
+    - Revert "UBUNTU: SAUCE: i2c: designware: add Inpiron/Vostro 7590 into i2c
+      quirk"
+    - Revert "UBUNTU: SAUCE: i2c: designware: Add disable runtime pm quirk"
+    - mfd: intel-lpss: Remove D3cold delay
+
+  * Include Sunix serial/parallel driver (LP: #1826716)
+    - serial: 8250_pci: Add support for Sunix serial boards
+    - parport: parport_serial: Add support for Sunix Multi I/O boards
+
+  * enable lockdown on s390x when Secure IPL is performed (LP: #1839622)
+    - SAUCE: (lockdown) s390/ipl: lockdown kernel when booted secure
+    - Ubuntu: [Config] Enable CONFIG_LOCK_DOWN_KERNEL on s390x.
+
+  * UBUNTU: SAUCE: shiftfs: pass correct point down (LP: #1837231)
+    - SAUCE: shiftfs: pass correct point down
+
+  * shiftfs: add O_DIRECT support (LP: #1837223)
+    - SAUCE: shiftfs: add O_DIRECT support
+
+  * Miscellaneous Ubuntu changes
+    - [Config] enable secureboot signing on s390x
+    - [Config] CONFIG_TEST_BLACKHOLE_DEV=m
+    - SAUCE: selftests: fib_tests: assign address to dummy1 for rp_filter tests
+    - [Debian] disable dkms builds for autopktest rebuilds
+    - update dkms package versions
+    - [Config] updateconfigs after v5.3-rc6 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 26 Aug 2019 10:09:42 +0200
+
+linux (5.3.0-7.8) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after v5.3-rc5 rebase
+    - remove missing module after updateconfigs
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 19 Aug 2019 15:31:24 +0200
+
+linux (5.3.0-6.7) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/bpf: prevent headers to be compiled as C code
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 14 Aug 2019 13:25:01 -0500
+
+linux (5.3.0-5.6) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] enable zfs build
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 13 Aug 2019 09:16:06 -0500
+
+linux (5.3.0-4.5) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+    - [Packaging] update helper scripts
+
+  * bcache: bch_allocator_thread(): hung task timeout (LP: #1784665) // Tight
+    timeout for bcache removal causes spurious failures (LP: #1796292)
+    - SAUCE: bcache: fix deadlock in bcache_allocator
+
+  * shiftfs: allow overlayfs (LP: #1838677)
+    - SAUCE: shiftfs: enable overlayfs on shiftfs
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "kbuild: modpost: do not parse unnecessary rules for vmlinux
+      modpost"
+    - update dkms package versions
+    - enable nvidia dkms build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 12 Aug 2019 10:41:27 -0500
+
+linux (5.3.0-3.4) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - SAUCE: aufs: add "WITH Linux-syscall-note" to SPDX tag of uapi headers
+    - [Config] add mux-* to modules.ignore
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 05 Aug 2019 18:17:09 +0200
+
+linux (5.3.0-2.3) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] add build dependincy on fontconfig
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 29 Jul 2019 12:18:46 -0400
+
+linux (5.3.0-1.2) eoan; urgency=medium
+
+  * System does not auto detect disconnection of external monitor (LP: #1835001)
+    - SAUCE: drm/i915: Add support for retrying hotplug
+    - SAUCE: drm/i915: Enable hotplug retry
+
+  * Please enable CONFIG_SCSI_UFS_QCOM as a module on arm64 (LP: #1837332)
+    - [Config] Enable CONFIG_SCSI_UFS_QCOM as a module on arm64.
+
+  * Add arm64 CONFIG_ARCH_MESON=y and related configs Edit (LP: #1820530)
+    - [Config] enable ARCH_MESON
+    - remove missing module
+    - [Config] update annotations after enabling ARCH_MESON for arm64
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: KVM: PPC: comment implicit fallthrough
+    - update dkms package versions
+    - [Config] enable vbox dkms build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 28 Jul 2019 23:10:16 -0400
+
+linux (5.3.0-0.1) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and
+      KEXEC_SIG_FORCE
+    - SAUCE: (efi-lockdown) kexec_file: Restrict at runtime if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) lockdown: Print current->comm in restriction messages
+    - SAUCE: (efi-lockdown) kexec: Allow kexec_file() with appropriate IMA policy
+      when locked down
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation
+      defined
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) KEYS: Make use of platform keyring for module
+      signature verify
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) furter KEXEC_VERIFY_SIG -> KEXEC_SIG updates
+    - SAUCE: (efi-lockdown) arm64: add kernel config option to lock down when in
+      Secure Boot mode
+    - SAUCE: import aufs driver
+    - SAUCE: aufs: rwsem owner changed to atmoic_long_t in 5.3
+    - [Config] disable zfs dkms build
+    - [Config] disable nvidia dkms build
+    - [Config] disable vbox dkms build
+    - SAUCE: perf diff: use llabs for s64 vaules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 23 Jul 2019 21:45:44 -0500
+
+linux (5.3.0-0.0) eoan; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 22 Jul 2019 10:19:04 -0500
+
+linux (5.2.0-9.10) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * input/mouse: alps trackpoint-only device doesn't work (LP: #1836752)
+    - SAUCE: Input: alps - don't handle ALPS cs19 trackpoint-only device
+    - SAUCE: Input: alps - fix a mismatch between a condition check and its
+      comment
+
+  * System does not auto detect disconnection of external monitor (LP: #1835001)
+    - SAUCE: drm/i915: Add support for retrying hotplug
+    - SAUCE: drm/i915: Enable hotplug retry
+
+  * alsa/hdmi: add icelake hdmi audio support for a Dell machine (LP: #1836916)
+    - SAUCE: ALSA: hda/hdmi - Remove duplicated define
+    - SAUCE: ALSA: hda/hdmi - Fix i915 reverse port/pin mapping
+
+  * First click on Goodix touchpad doesn't be recognized after runtime suspended
+    (LP: #1836836)
+    - SAUCE: i2c: designware: add G3 3590 into i2c quirk
+
+  * ixgbe{vf} - Physical Function gets IRQ when VF checks link state
+    (LP: #1836760)
+    - ixgbevf: Use cached link state instead of re-reading the value for ethtool
+
+  * Doing multiple squashfs (and other loop?) mounts in parallel breaks
+    (LP: #1836914)
+    - SAUCE: Revert "loop: Don't change loop device under exclusive opener"
+
+  * hibmc-drm Causes Unreadable Display for Huawei amd64 Servers (LP: #1762940)
+    - SAUCE: Make CONFIG_DRM_HISI_HIBMC depend on ARM64
+    - [Config] Set CONFIG_DRM_HISI_HIBMC to arm64 only
+    - [Config] add hibmc-drm to modules.ignore
+
+  * hda/realtek: can't detect external mic on a Dell machine (LP: #1836755)
+    - ALSA: hda/realtek: apply ALC891 headset fixup to one Dell machine
+
+  * Enable Armada SOCs and MVPP2 NIC driver for disco/generic arm64
+    (LP: #1835054)
+    - [Config] Enable Armada SOCs and MVPP2 NIC driver for disco/generic arm64
+
+  * Unhide Nvidia HDA audio controller (LP: #1836308)
+    - PCI: Enable NVIDIA HDA controllers
+
+  * Intel ethernet I219 may wrongly detect connection speed as 10Mbps
+    (LP: #1836177)
+    - e1000e: Make watchdog use delayed work
+
+  * Sometimes touchpad(goodix) can't use tap function (LP: #1836020)
+    - SAUCE: i2c: designware: add Inpiron/Vostro 7590 into i2c quirk
+    - SAUCE: i2c: designware: add Inpiron 7591 into i2c quirk
+
+  * Intel ethernet I219 has slow RX speed (LP: #1836152)
+    - e1000e: add workaround for possible stalled packet
+    - e1000e: disable force K1-off feature
+
+  * bcache: risk of data loss on I/O errors in backing or caching devices
+    (LP: #1829563)
+    - Revert "bcache: set CACHE_SET_IO_DISABLE in bch_cached_dev_error()"
+
+  * bnx2x driver causes 100% CPU load (LP: #1832082)
+    - bnx2x: Prevent ptp_task to be rescheduled indefinitely
+
+  * fcf-protection=none patch with new version
+    - Revert "UBUNTU: SAUCE: kbuild: add -fcf-protection=none to retpoline flags"
+    - SAUCE: kbuild: add -fcf-protection=none when using retpoline flags
+
+  * CVE-2019-12614
+    - powerpc/pseries/dlpar: Fix a missing check in dlpar_parse_cc_property()
+
+  * Eoan update: v5.2.1 upstream stable release (LP: #1836622)
+    - crypto: lrw - use correct alignmask
+    - crypto: talitos - rename alternative AEAD algos.
+    - fscrypt: don't set policy for a dead directory
+    - udf: Fix incorrect final NOT_ALLOCATED (hole) extent length
+    - media: stv0297: fix frequency range limit
+    - ALSA: usb-audio: Fix parse of UAC2 Extension Units
+    - ALSA: hda/realtek - Headphone Mic can't record after S3
+    - tpm: Actually fail on TPM errors during "get random"
+    - tpm: Fix TPM 1.2 Shutdown sequence to prevent future TPM operations
+    - block: fix .bi_size overflow
+    - block, bfq: NULL out the bic when it's no longer valid
+    - perf intel-pt: Fix itrace defaults for perf script
+    - perf auxtrace: Fix itrace defaults for perf script
+    - perf intel-pt: Fix itrace defaults for perf script intel-pt documentation
+    - perf pmu: Fix uncore PMU alias list for ARM64
+    - perf thread-stack: Fix thread stack return from kernel for kernel-only case
+    - perf header: Assign proper ff->ph in perf_event__synthesize_features()
+    - x86/ptrace: Fix possible spectre-v1 in ptrace_get_debugreg()
+    - x86/tls: Fix possible spectre-v1 in do_get_thread_area()
+    - Documentation: Add section about CPU vulnerabilities for Spectre
+    - Documentation/admin: Remove the vsyscall=native documentation
+    - mwifiex: Don't abort on small, spec-compliant vendor IEs
+    - USB: serial: ftdi_sio: add ID for isodebug v1
+    - USB: serial: option: add support for GosunCn ME3630 RNDIS mode
+    - Revert "serial: 8250: Don't service RX FIFO if interrupts are disabled"
+    - p54usb: Fix race between disconnect and firmware loading
+    - usb: gadget: f_fs: data_len used before properly set
+    - usb: gadget: ether: Fix race between gether_disconnect and rx_submit
+    - usb: dwc2: use a longer AHB idle timeout in dwc2_core_reset()
+    - usb: renesas_usbhs: add a workaround for a race condition of workqueue
+    - drivers/usb/typec/tps6598x.c: fix portinfo width
+    - drivers/usb/typec/tps6598x.c: fix 4CC cmd write
+    - p54: fix crash during initialization
+    - staging: comedi: dt282x: fix a null pointer deref on interrupt
+    - staging: wilc1000: fix error path cleanup in wilc_wlan_initialize()
+    - staging: bcm2835-camera: Restore return behavior of ctrl_set_bitrate()
+    - staging: comedi: amplc_pci230: fix null pointer deref on interrupt
+    - staging: mt7621-pci: fix PCIE_FTS_NUM_LO macro
+    - HID: Add another Primax PIXART OEM mouse quirk
+    - lkdtm: support llvm-objcopy
+    - binder: fix memory leak in error path
+    - binder: return errors from buffer copy functions
+    - iio: adc: stm32-adc: add missing vdda-supply
+    - coresight: Potential uninitialized variable in probe()
+    - coresight: etb10: Do not call smp_processor_id from preemptible
+    - coresight: tmc-etr: Do not call smp_processor_id() from preemptible
+    - coresight: tmc-etr: alloc_perf_buf: Do not call smp_processor_id from
+      preemptible
+    - coresight: tmc-etf: Do not call smp_processor_id from preemptible
+    - carl9170: fix misuse of device driver API
+    - Revert "x86/build: Move _etext to actual end of .text"
+    - VMCI: Fix integer overflow in VMCI handle arrays
+    - staging: vchiq_2835_arm: revert "quit using custom down_interruptible()"
+    - staging: vchiq: make wait events interruptible
+    - staging: vchiq: revert "switch to wait_for_completion_killable"
+    - staging: fsl-dpaa2/ethsw: fix memory leak of switchdev_work
+    - staging: bcm2835-camera: Replace spinlock protecting context_map with mutex
+    - staging: bcm2835-camera: Ensure all buffers are returned on disable
+    - staging: bcm2835-camera: Remove check of the number of buffers supplied
+    - staging: bcm2835-camera: Handle empty EOS buffers whilst streaming
+    - staging: rtl8712: reduce stack usage, again
+    - Linux 5.2.1
+    - [Config] updateconfigs after v5.2.1 stable update
+
+  * fcf-protection=none patch with upstream version
+    - Revert "UBUNTU: SAUCE: add -fcf-protection=none to retpoline flags"
+    - SAUCE: kbuild: add -fcf-protection=none to retpoline flags
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/ftrace: avoid failure when trying to probe a notrace
+      function
+    - SAUCE: selftests/powerpc/ptrace: fix build failure
+    - update dkms package versions
+    - [Packaging] add zlua to zfs-modules.ignore
+    - update dkms package versions
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 19 Jul 2019 15:04:45 -0500
+
+linux (5.2.0-8.9) eoan; urgency=medium
+
+  * linux: 5.2.0-8.9 -proposed tracker (LP: #1835700)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] replace zfs and spl build with zfs 0.8.1-1ubuntu1
+    - SAUCE: test_bpf: remove expected fail for Ctx heavy transformations test on
+      s390
+    - SAUCE: add -fcf-protection=none to retpoline flags
+    - SAUCE: usbip: ensure strings copied using strncpy are null-terminated
+    - SAUCE: usbip: add -Wno-address-of-packed-member to EXTRA_CFLAGS
+    - SAUCE: perf jvmti: ensure strncpy result is null-terminated
+    - update dkms package versions
+    - add removed zfs modules to modules.ignore
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 08 Jul 2019 07:13:41 -0500
+
+linux (5.2.0-7.8) eoan; urgency=medium
+
+  * Kernel panic upon resetting ixgbe SR-IOV VFIO virtual function using 5.0
+    kernel (LP: #1829652)
+    - SAUCE: ixgbe: Avoid NULL pointer dereference with VF on non-IPsec hw
+
+  * Hi1620 driver updates from upstream 5.2 merge window (LP: #1830815)
+    - net: hns3: initialize CPU reverse mapping
+    - net: hns3: refine the flow director handle
+    - net: hns3: add aRFS support for PF
+    - net: hns3: fix for FEC configuration
+    - RDMA/hns: Remove unnecessary print message in aeq
+    - RDMA/hns: Update CQE specifications
+    - RDMA/hns: Move spin_lock_irqsave to the correct place
+    - RDMA/hns: Remove jiffies operation in disable interrupt context
+    - RDMA/hns: Replace magic numbers with #defines
+    - net: hns3: fix compile warning without CONFIG_RFS_ACCEL
+    - net: hns3: fix for HNS3_RXD_GRO_SIZE_M macro
+    - net: hns3: add support for dump firmware statistics by debugfs
+    - net: hns3: use HCLGE_STATE_NIC_REGISTERED to indicate PF NIC client has
+      registered
+    - net: hns3: use HCLGE_STATE_ROCE_REGISTERED to indicate PF ROCE client has
+      registered
+    - net: hns3: use HCLGEVF_STATE_NIC_REGISTERED to indicate VF NIC client has
+      registered
+    - net: hns3: modify hclge_init_client_instance()
+    - net: hns3: modify hclgevf_init_client_instance()
+    - net: hns3: add handshake with hardware while doing reset
+    - net: hns3: stop schedule reset service while unloading driver
+    - net: hns3: adjust hns3_uninit_phy()'s location in the hns3_client_uninit()
+    - net: hns3: fix a memory leak issue for hclge_map_unmap_ring_to_vf_vector
+    - RDMA/hns: Bugfix for posting multiple srq work request
+    - net: hns3: remove redundant core reset
+    - net: hns3: don't configure new VLAN ID into VF VLAN table when it's full
+    - net: hns3: fix VLAN filter restore issue after reset
+    - net: hns3: set the port shaper according to MAC speed
+    - net: hns3: add a check to pointer in error_detected and slot_reset
+    - net: hns3: set ops to null when unregister ad_dev
+    - net: hns3: add handling of two bits in MAC tunnel interrupts
+    - net: hns3: remove setting bit of reset_requests when handling mac tunnel
+      interrupts
+    - net: hns3: add opcode about query and clear RAS & MSI-X to special opcode
+    - net: hns3: delay and separate enabling of NIC and ROCE HW errors
+    - RDMA/hns: fix inverted logic of readl read and shift
+    - RDMA/hns: Bugfix for filling the sge of srq
+    - net: hns3: log detail error info of ROCEE ECC and AXI errors
+    - net: hns3: fix wrong size of mailbox responding data
+    - net: hns3: make HW GRO handling compliant with SW GRO
+    - net: hns3: replace numa_node_id with numa_mem_id for buffer reusing
+    - net: hns3: refactor hns3_get_new_int_gl function
+    - net: hns3: trigger VF reset if a VF has an over_8bd_nfe_err
+    - net: hns3: delete the redundant user NIC codes
+    - net: hns3: small changes for magic numbers
+    - net: hns3: use macros instead of magic numbers
+    - net: hns3: refactor PF/VF RSS hash key configuration
+    - net: hns3: some modifications to simplify and optimize code
+    - net: hns3: fix some coding style issues
+    - net: hns3: delay setting of reset level for hw errors until slot_reset is
+      called
+    - net: hns3: fix avoid unnecessary resetting for the H/W errors which do not
+      require reset
+    - net: hns3: process H/W errors occurred before HNS dev initialization
+    - net: hns3: add recovery for the H/W errors occurred before the HNS dev
+      initialization
+    - net: hns3: some changes of MSI-X bits in PPU(RCB)
+    - net: hns3: extract handling of mpf/pf msi-x errors into functions
+    - net: hns3: clear restting state when initializing HW device
+    - net: hns3: free irq when exit from abnormal branch
+    - net: hns3: fix for dereferencing before null checking
+    - net: hns3: fix for skb leak when doing selftest
+    - net: hns3: delay ring buffer clearing during reset
+    - net: hns3: some variable modification
+    - net: hns3: fix dereference of ae_dev before it is null checked
+    - scsi: hisi_sas: Delete PHY timers when rmmod or probe failed
+    - scsi: hisi_sas: Fix the issue of argument mismatch of printing ecc errors
+    - scsi: hisi_sas: Reduce HISI_SAS_SGE_PAGE_CNT in size
+    - scsi: hisi_sas: Change the type of some numbers to unsigned
+    - scsi: hisi_sas: Ignore the error code between phy down to phy up
+    - scsi: hisi_sas: Disable stash for v3 hw
+    - net: hns3: Add missing newline at end of file
+    - RDMa/hns: Don't stuck in endless timeout loop
+
+  * Sometimes touchpad automatically trigger double click (LP: #1833484)
+    - SAUCE: i2c: designware: Add disable runtime pm quirk
+
+  * Add pointstick support on HP ZBook 17 G5 (LP: #1833387)
+    - Revert "HID: multitouch: Support ALPS PTP stick with pid 0x120A"
+
+  * depmod may prefer unsigned l-r-m nvidia modules to signed modules
+    (LP: #1834479)
+    - [Packaging] dkms-build--nvidia-N -- clean up unsigned ko files
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/powerpc: disable signal_fuzzer test
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 01 Jul 2019 07:22:18 -0500
+
+linux (5.2.0-6.7) eoan; urgency=medium
+
+  * hinic: fix oops due to race in set_rx_mode (LP: #1832048)
+    - hinic: fix a bug in set rx mode
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.2-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 23 Jun 2019 23:36:11 -0500
+
+linux (5.2.0-5.6) eoan; urgency=medium
+
+  * QCA9377 isn't being recognized sometimes (LP: #1757218)
+    - SAUCE: USB: Disable USB2 LPM at shutdown
+
+  * shiftfs: allow changing ro/rw for subvolumes (LP: #1832316)
+    - SAUCE: shiftfs: allow changing ro/rw for subvolumes
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Packaging] replace nvidia-418 dkms build with nvidia-430
+    - SAUCE: import aufs driver
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 17 Jun 2019 15:04:12 -0500
+
+linux (5.2.0-4.5) eoan; urgency=medium
+
+  * arm64: cma_alloc errors at boot (LP: #1823753)
+    - [Config] Bump CMA_SIZE_MBYTES to 32 on arm64
+    - dma-contiguous: add dma_{alloc,free}_contiguous() helpers
+    - dma-contiguous: use fallback alloc_pages for single pages
+    - dma-contiguous: fix !CONFIG_DMA_CMA version of dma_{alloc,
+      free}_contiguous()
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_MFD_TQMX86=n for s390x
+    - [Config] CONFIG_GPIO_AMD_FCH=n for s390x
+    - [Config] CONFIG_BACKLIGHT_CLASS_DEVICE=n on s390x
+    - [Config] CONFIG_LCD_CLASS_DEVICE=n for s390x
+    - [Config] CONFIG_DRM_ETNAVIV=m for armhf generic-lpae
+    - [Config] CONFIG_DRM_NOUVEAU_SVM=n
+    - [Config] CONFIG_HWMON=n for s390x
+    - [Config] CONFIG_NEW_LEDS=n for s390x
+    - [Config] CONFIG_MTD_NAND_OMAP2=y for armhf
+    - [Config] CONFIG_VOP_BUS=n for non-amd64 arches
+    - [Config] CONFIG_TI_CPSW_PHY_SEL=n
+    - [Config] CONFIG_INTERCONNECT=n for s390x
+    - [Config] CONFIG_SCSI_GDTH=n for s390x
+    - [Config] CONFIG_PACKING=n for s390x
+    - [Config] CONFIG_ARCH_MILBEAUT=y for armhf
+    - [Config] update annotations following config review
+    - update dkms package versions
+    - [Config] enable nvidia dkms build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 10 Jun 2019 07:00:11 -0500
+
+linux (5.2.0-3.4) eoan; urgency=medium
+
+  * [18.04/18.10] File libperf-jvmti.so is missing in linux-tools-common deb on
+    Ubuntu (LP: #1761379)
+    - [Packaging] Support building libperf-jvmti.so
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "bpf, selftest: test global data/bss/rodata sections"
+    - update dkms package versions
+    - [Config] enable zfs
+    - rebase to v5.2-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 02 Jun 2019 21:48:50 -0500
+
+linux (5.2.0-2.3) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: perf arm64: Fix mksyscalltbl when system kernel headers are ahead of
+      the kernel
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 May 2019 07:12:39 -0500
+
+linux (5.2.0-1.2) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_INTEGRITY_PLATFORM_KEYRING=y
+    - update dkms package versions
+    - [Config] enable vbox dkms build
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 May 2019 21:11:27 -0500
+
+linux (5.2.0-0.1) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: import aufs driver
+    - [Packaging] disable ZFS
+    - [Packaging] disable nvidia
+    - [Packaging] dkms-build -- expand paths searched for make.log files
+    - add virtualbox-guest-dkms dkms package build
+    - enable vbox dkms build for amd64 and i386
+    - update dkms package versions
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and
+      KEXEC_SIG_FORCE
+    - SAUCE: (efi-lockdown) kexec_file: Restrict at runtime if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) lockdown: Print current->comm in restriction messages
+    - SAUCE: (efi-lockdown) kexec: Allow kexec_file() with appropriate IMA policy
+      when locked down
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) KEYS: Make use of platform keyring for module
+      signature verify
+    - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation
+      defined
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) furter KEXEC_VERIFY_SIG -> KEXEC_SIG updates
+    - SAUCE: (efi-lockdown) arm64: add kernel config option to lock down when in
+      Secure Boot mode
+    - update dkms package versions
+    - [Config] disable vbox build
+    - SAUCE: s390: mark __cpacf_check_opcode() and cpacf_query_func() as
+      __always_inline
+    - SAUCE: IB/mlx5: use size_t instead of u64 when dividing
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 21 May 2019 11:18:43 -0500
+
+linux (5.2.0-0.0) eoan; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 21 May 2019 07:34:43 -0500
+
+linux (5.1.0-2.2) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+
+  * Eoan update: v5.1.2 upstream stable release (LP: #1829050)
+    - x86/msr-index: Cleanup bit defines
+    - x86/speculation: Consolidate CPU whitelists
+    - x86/speculation/mds: Add basic bug infrastructure for MDS
+    - x86/speculation/mds: Add BUG_MSBDS_ONLY
+    - x86/kvm: Expose X86_FEATURE_MD_CLEAR to guests
+    - x86/speculation/mds: Add mds_clear_cpu_buffers()
+    - x86/speculation/mds: Clear CPU buffers on exit to user
+    - x86/kvm/vmx: Add MDS protection when L1D Flush is not active
+    - x86/speculation/mds: Conditionally clear CPU buffers on idle entry
+    - x86/speculation/mds: Add mitigation control for MDS
+    - x86/speculation/mds: Add sysfs reporting for MDS
+    - x86/speculation/mds: Add mitigation mode VMWERV
+    - Documentation: Move L1TF to separate directory
+    - Documentation: Add MDS vulnerability documentation
+    - x86/speculation/mds: Add mds=full,nosmt cmdline option
+    - x86/speculation: Move arch_smt_update() call to after mitigation decisions
+    - x86/speculation/mds: Add SMT warning message
+    - x86/speculation/mds: Fix comment
+    - x86/speculation/mds: Print SMT vulnerable on MSBDS with mitigations off
+    - cpu/speculation: Add 'mitigations=' cmdline option
+    - x86/speculation: Support 'mitigations=' cmdline option
+    - powerpc/speculation: Support 'mitigations=' cmdline option
+    - s390/speculation: Support 'mitigations=' cmdline option
+    - x86/speculation/mds: Add 'mitigations=' support for MDS
+    - x86/mds: Add MDSUM variant to the MDS documentation
+    - Documentation: Correct the possible MDS sysfs values
+    - x86/speculation/mds: Fix documentation typo
+    - Linux 5.1.2
+
+  * Eoan update: v5.1.1 upstream stable release (LP: #1829046)
+    - Drivers: hv: vmbus: Remove the undesired put_cpu_ptr() in hv_synic_cleanup()
+    - ubsan: Fix nasty -Wbuiltin-declaration-mismatch GCC-9 warnings
+    - staging: greybus: power_supply: fix prop-descriptor request size
+    - staging: wilc1000: Avoid GFP_KERNEL allocation from atomic context.
+    - staging: most: cdev: fix chrdev_region leak in mod_exit
+    - staging: most: sound: pass correct device when creating a sound card
+    - usb: dwc3: Allow building USB_DWC3_QCOM without EXTCON
+    - usb: dwc3: Fix default lpm_nyet_threshold value
+    - USB: serial: f81232: fix interrupt worker not stop
+    - USB: cdc-acm: fix unthrottle races
+    - usb-storage: Set virt_boundary_mask to avoid SG overflows
+    - genirq: Prevent use-after-free and work list corruption
+    - intel_th: pci: Add Comet Lake support
+    - iio: adc: qcom-spmi-adc5: Fix of-based module autoloading
+    - cpufreq: armada-37xx: fix frequency calculation for opp
+    - ACPI / LPSS: Use acpi_lpss_* instead of acpi_subsys_* functions for
+      hibernate
+    - soc: sunxi: Fix missing dependency on REGMAP_MMIO
+    - scsi: lpfc: change snprintf to scnprintf for possible overflow
+    - scsi: qla2xxx: Fix incorrect region-size setting in optrom SYSFS routines
+    - scsi: qla2xxx: Set remote port devloss timeout to 0
+    - scsi: qla2xxx: Fix device staying in blocked state
+    - Bluetooth: hidp: fix buffer overflow
+    - Bluetooth: Align minimum encryption key size for LE and BR/EDR connections
+    - Bluetooth: Fix not initializing L2CAP tx_credits
+    - Bluetooth: hci_bcm: Fix empty regulator supplies for Intel Macs
+    - UAS: fix alignment of scatter/gather segments
+    - ASoC: Intel: avoid Oops if DMA setup fails
+    - i3c: Fix a shift wrap bug in i3c_bus_set_addr_slot_status()
+    - locking/futex: Allow low-level atomic operations to return -EAGAIN
+    - arm64: futex: Bound number of LDXR/STXR loops in FUTEX_WAKE_OP
+    - Linux 5.1.1
+
+  * shiftfs: lock security sensitive superblock flags (LP: #1827122)
+    - SAUCE: shiftfs: lock down certain superblock flags
+
+  * Please package libbpf (which is done out of the kernel src) in Debian [for
+    19.10] (LP: #1826410)
+    - SAUCE: tools -- fix add ability to disable libbfd
+
+  * ratelimit cma_alloc messages (LP: #1828092)
+    - SAUCE: cma: ratelimit cma_alloc error messages
+
+  * Headphone jack switch sense is inverted: plugging in headphones disables
+    headphone output (LP: #1824259)
+    - ASoC: rt5645: Headphone Jack sense inverts on the LattePanda board
+
+  * There are 4 HDMI/Displayport audio output listed in sound setting without
+    attach any HDMI/DP monitor (LP: #1827967)
+    - ALSA: hda/hdmi - Read the pin sense from register when repolling
+    - ALSA: hda/hdmi - Consider eld_valid when reporting jack event
+
+  * CONFIG_LOG_BUF_SHIFT set to 14 is too low on arm64 (LP: #1824864)
+    - [Config] CONFIG_LOG_BUF_SHIFT=18 on all 64bit arches
+
+  * CTAUTO:DevOps:860.50:devops4fp1:Error occurred during LINUX Dmesg error
+    Checking for all LINUX clients for devops4p10 (LP: #1766201)
+    - SAUCE: integrity: downgrade error to warning
+
+  * linux-buildinfo: pull out ABI information into its own package
+    (LP: #1806380)
+    - [Packaging] autoreconstruct -- base tag is always primary mainline version
+
+  * [SRU] Please sync vbox modules from virtualbox 6.0.6 on next kernel update
+    (LP: #1825210)
+    - vbox-update: updates for renamed makefiles
+    - ubuntu: vbox -- update to 6.0.6-dfsg-1
+
+  * autofs kernel module missing (LP: #1824333)
+    - [Config] Update autofs4 path in inclusion list
+
+  * The Realtek card reader does not enter PCIe 1.1/1.2 (LP: #1825487)
+    - SAUCE: misc: rtsx: Fixed rts5260 power saving parameter and sd glitch
+
+  * CVE-2019-3874
+    - sctp: implement memory accounting on tx path
+    - sctp: implement memory accounting on rx path
+
+  * apparmor does not start in Disco LXD containers (LP: #1824812)
+    - SAUCE: shiftfs: use separate llseek method for directories
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] autoreconstruct -- remove for -rc kernels
+    - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation
+      defined
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) furter KEXEC_VERIFY_SIG -> KEXEC_SIG updates
+    - [Config] (efi-lockdown): update configs after efi lockdown patch refresh
+    - [Packaging] don't delete efi_parser.c
+    - vbox-update -- do not fix up KERN_DIR or KBUILD_EXTMOD
+    - ubuntu: vbox -- update to 6.0.6-dfsg-2
+    - add nvidia-418 dkms build
+    - remove virtualbox guest drivers
+    - [Packaging] dkms-build -- expand paths searched for make.log files
+    - add virtualbox-guest-dkms dkms package build
+    - enable vbox dkms build for amd64 and i386
+    - [Config] update configs for v5.1(-rc7)? rebase
+    - update dkms package versions
+    - Add the ability to lock down access to the running kernel image
+    - Enforce module signatures if the kernel is locked down
+    - Restrict /dev/{mem,kmem,port} when the kernel is locked down
+    - kexec_load: Disable at runtime if the kernel is locked down
+    - Copy secure_boot flag in boot params across kexec reboot
+    - kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE
+    - kexec_file: Restrict at runtime if the kernel is locked down
+    - hibernate: Disable when the kernel is locked down
+    - uswsusp: Disable when the kernel is locked down
+    - PCI: Lock down BAR access when the kernel is locked down
+    - x86: Lock down IO port access when the kernel is locked down
+    - x86/msr: Restrict MSR access when the kernel is locked down
+    - ACPI: Limit access to custom_method when the kernel is locked down
+    - acpi: Ignore acpi_rsdp kernel param when the kernel has been locked down
+    - acpi: Disable ACPI table override if the kernel is locked down
+    - acpi: Disable APEI error injection if the kernel is locked down
+    - Prohibit PCMCIA CIS storage when the kernel is locked down
+    - Lock down TIOCSSERIAL
+    - Lock down module params that specify hardware parameters (eg. ioport)
+    - x86/mmiotrace: Lock down the testmmiotrace module
+    - Lock down /proc/kcore
+    - Lock down kprobes
+    - bpf: Restrict kernel image access functions when the kernel is locked down
+    - Lock down perf
+    - debugfs: Restrict debugfs when the kernel is locked down
+    - lockdown: Print current->comm in restriction messages
+    - kexec: Allow kexec_file() with appropriate IMA policy when locked down
+    - Make get_cert_list() not complain about cert lists that aren't present.
+    - Add efi_status_to_str() and rework efi_status_to_err().
+    - Make get_cert_list() use efi_status_to_str() to print error messages.
+    - efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode
+    - efi: Lock down the kernel if booted in secure boot mode
+    - KEYS: Make use of platform keyring for module signature verify
+
+  * Miscellaneous upstream changes
+    - ALSA: hdea/realtek - Headset fixup for System76 Gazelle (gaze14)
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 14 May 2019 12:32:56 -0500
+
+linux (5.1.0-1.1) eoan; urgency=medium
+
+  * bionic: fork out linux-snapdragon into its own topic kernel (LP: #1820868)
+    - [Packaging]: really drop snapdragon
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: fix vbox use of MAP_SHARED
+    - SAUCE: fix vbox use of vm_fault_t
+    - [Packaging] disable ZFS
+    - [Packaging] disable nvidia
+    - SAUCE: perf annotate: Fix build on 32 bit for BPF annotation
+    - [Config]: updateconfig after rebase to v5.1-rc
+    - [Config]: build ETNAVIV only on arm platforms
+    - [Config]: Disable CMA on non-arm platforms
+    - [Config]: MMC_CQHCI is needed by some built-in drivers
+    - [Config]: a.out support has been deprecated
+    - [Config]: R3964 was marked as BROKEN
+    - [Config]: Add SENSIRION_SGP30 module
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: tools: lib/bpf -- add generated headers to search
+      path"
+    - Revert "UBUNTU: SAUCE: btqcomsmd: introduce BT_QCOMSMD_HACK"
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Thu, 25 Apr 2019 10:03:25 -0300
+
+linux (5.1.0-0.0) eoan; urgency=medium
+
+  * Dummy entry.
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Thu, 25 Apr 2019 09:49:47 -0300
+
+linux (5.0.0-13.14) disco; urgency=medium
+
+  * linux: 5.0.0-13.14 -proposed tracker (LP: #1824819)
+
+  * Display only has 640x480 (LP: #1824677)
+    - Revert "UBUNTU: SAUCE: drm/nouveau: Disable nouveau driver by default"
+
+  * shiftfs: use after free when checking mount options (LP: #1824735)
+    - SAUCE: shiftfs: prevent use-after-free when verifying mount options
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 15 Apr 2019 09:11:23 -0500
+
+linux (5.0.0-12.13) disco; urgency=medium
+
+  * linux: 5.0.0-12.13 -proposed tracker (LP: #1824726)
+
+  * Linux 5.0 black screen on boot, display flickers (i915 regression with
+    certain laptop panels) (LP: #1824216)
+    - drm/i915/dp: revert back to max link rate and lane count on eDP
+
+  * kernel BUG at fs/attr.c:287 when using shiftfs (LP: #1824717)
+    - SAUCE: shiftfs: fix passing of attrs to underaly for setattr
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 14 Apr 2019 13:38:05 -0500
+
+linux (5.0.0-11.12) disco; urgency=medium
+
+  * linux: 5.0.0-11.12 -proposed tracker (LP: #1824383)
+
+  * hns3: PPU_PF_ABNORMAL_INT_ST over_8bd_no_fe found [error status=0x1]
+    (LP: #1824194)
+    - net: hns3: fix for not calculating tx bd num correctly
+
+  * disco: unable to use iptables/enable ufw under -virtual kernel
+    (LP: #1823862)
+    - [Packaging] add bpfilter to linux-modules
+
+  * Make shiftfs a module rather than built-in (LP: #1824354)
+    - [Config] CONFIG_SHIFT_FS=m
+
+  * shiftfs: chown sets untranslated ids in lower fs (LP: #1824350)
+    - SAUCE: shiftfs: use translated ids when chaning lower fs attrs
+
+  * [Hyper-V] KVP daemon fails to start on first boot of disco VM (LP: #1820063)
+    - [Packaging] bind hv_kvp_daemon startup to hv_kvp device
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 11 Apr 2019 10:17:19 -0500
+
+linux (5.0.0-10.11) disco; urgency=medium
+
+  * linux: 5.0.0-10.11 -proposed tracker (LP: #1823936)
+
+  * Apparmor enforcement failure in lxc selftests (LP: #1823379)
+    - SAUCE: apparmor: Restore Y/N in /sys for apparmor's "enabled"
+
+  * systemd cause kernel trace "BUG: unable to handle kernel paging request at
+    6db23a14" on Cosmic i386 (LP: #1813244)
+    - openvswitch: fix flow actions reallocation
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 09 Apr 2019 08:30:38 -0500
+
+linux (5.0.0-9.10) disco; urgency=medium
+
+  * linux: 5.0.0-9.10 -proposed tracker (LP: #1823228)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+    - [Packaging] update helper scripts
+    - [Packaging] resync retpoline extraction
+
+  * Huawei Hi1822 NIC has poor performance (LP: #1820187)
+    - net-next/hinic: replace disable_irq_nosync/enable_irq
+
+  * Add uid shifting overlay filesystem (shiftfs) (LP: #1823186)
+    - shiftfs: uid/gid shifting bind mount
+    - shiftfs: rework and extend
+    - shiftfs: support some btrfs ioctls
+    - [Config] enable shiftfs
+
+  * Cannot boot or install - have to use nomodeset (LP: #1821820)
+    - Revert "drm/i915/fbdev: Actually configure untiled displays"
+
+  * Disco update: v5.0.6 upstream stable release (LP: #1823060)
+    - netfilter: nf_tables: fix set double-free in abort path
+    - dccp: do not use ipv6 header for ipv4 flow
+    - genetlink: Fix a memory leak on error path
+    - gtp: change NET_UDP_TUNNEL dependency to select
+    - ipv6: make ip6_create_rt_rcu return ip6_null_entry instead of NULL
+    - mac8390: Fix mmio access size probe
+    - mISDN: hfcpci: Test both vendor & device ID for Digium HFC4S
+    - net: aquantia: fix rx checksum offload for UDP/TCP over IPv6
+    - net: datagram: fix unbounded loop in __skb_try_recv_datagram()
+    - net/packet: Set __GFP_NOWARN upon allocation in alloc_pg_vec
+    - net: phy: meson-gxl: fix interrupt support
+    - net: rose: fix a possible stack overflow
+    - net: stmmac: fix memory corruption with large MTUs
+    - net-sysfs: call dev_hold if kobject_init_and_add success
+    - net: usb: aqc111: Extend HWID table by QNAP device
+    - packets: Always register packet sk in the same order
+    - rhashtable: Still do rehash when we get EEXIST
+    - sctp: get sctphdr by offset in sctp_compute_cksum
+    - sctp: use memdup_user instead of vmemdup_user
+    - tcp: do not use ipv6 header for ipv4 flow
+    - tipc: allow service ranges to be connect()'ed on RDM/DGRAM
+    - tipc: change to check tipc_own_id to return in tipc_net_stop
+    - tipc: fix cancellation of topology subscriptions
+    - tun: properly test for IFF_UP
+    - vrf: prevent adding upper devices
+    - vxlan: Don't call gro_cells_destroy() before device is unregistered
+    - thunderx: enable page recycling for non-XDP case
+    - thunderx: eliminate extra calls to put_page() for pages held for recycling
+    - net: dsa: mv88e6xxx: fix few issues in mv88e6390x_port_set_cmode
+    - net: mii: Fix PAUSE cap advertisement from linkmode_adv_to_lcl_adv_t()
+      helper
+    - net: phy: don't clear BMCR in genphy_soft_reset
+    - r8169: fix cable re-plugging issue
+    - ila: Fix rhashtable walker list corruption
+    - tun: add a missing rcu_read_unlock() in error path
+    - powerpc/fsl: Fix the flush of branch predictor.
+    - Btrfs: fix incorrect file size after shrinking truncate and fsync
+    - btrfs: remove WARN_ON in log_dir_items
+    - btrfs: don't report readahead errors and don't update statistics
+    - btrfs: Fix bound checking in qgroup_trace_new_subtree_blocks
+    - btrfs: Avoid possible qgroup_rsv_size overflow in
+      btrfs_calculate_inode_block_rsv_size
+    - Btrfs: fix assertion failure on fsync with NO_HOLES enabled
+    - locks: wake any locks blocked on request before deadlock check
+    - tracing: initialize variable in create_dyn_event()
+    - ARM: imx6q: cpuidle: fix bug that CPU might not wake up at expected time
+    - powerpc: bpf: Fix generation of load/store DW instructions
+    - vfio: ccw: only free cp on final interrupt
+    - NFS: Fix nfs4_lock_state refcounting in nfs4_alloc_{lock,unlock}data()
+    - NFS: fix mount/umount race in nlmclnt.
+    - NFSv4.1 don't free interrupted slot on open
+    - net: dsa: qca8k: remove leftover phy accessors
+    - ALSA: rawmidi: Fix potential Spectre v1 vulnerability
+    - ALSA: seq: oss: Fix Spectre v1 vulnerability
+    - ALSA: pcm: Fix possible OOB access in PCM oss plugins
+    - ALSA: pcm: Don't suspend stream in unrecoverable PCM state
+    - ALSA: hda/realtek - Fixed Headset Mic JD not stable
+    - ALSA: hda/realtek: merge alc_fixup_headset_jack to alc295_fixup_chromebook
+    - ALSA: hda/realtek - Add support headset mode for DELL WYSE AIO
+    - ALSA: hda/realtek - Add support headset mode for New DELL WYSE NB
+    - ALSA: hda/realtek: Enable headset MIC of Acer AIO with ALC286
+    - ALSA: hda/realtek: Enable headset MIC of Acer Aspire Z24-890 with ALC286
+    - ALSA: hda/realtek - Add support for Acer Aspire E5-523G/ES1-432 headset mic
+    - ALSA: hda/realtek: Enable ASUS X441MB and X705FD headset MIC with ALC256
+    - ALSA: hda/realtek: Enable headset mic of ASUS P5440FF with ALC256
+    - ALSA: hda/realtek: Enable headset MIC of ASUS X430UN and X512DK with ALC256
+    - ALSA: hda/realtek - Fix speakers on Acer Predator Helios 500 Ryzen laptops
+    - kbuild: modversions: Fix relative CRC byte order interpretation
+    - fs/open.c: allow opening only regular files during execve()
+    - ocfs2: fix inode bh swapping mixup in ocfs2_reflink_inodes_lock
+    - scsi: sd: Fix a race between closing an sd device and sd I/O
+    - scsi: sd: Quiesce warning if device does not report optimal I/O size
+    - scsi: zfcp: fix rport unblock if deleted SCSI devices on Scsi_Host
+    - scsi: zfcp: fix scsi_eh host reset with port_forced ERP for non-NPIV FCP
+      devices
+    - drm/rockchip: vop: reset scale mode when win is disabled
+    - tty/serial: atmel: Add is_half_duplex helper
+    - tty/serial: atmel: RS485 HD w/DMA: enable RX after TX is stopped
+    - tty: mxs-auart: fix a potential NULL pointer dereference
+    - tty: atmel_serial: fix a potential NULL pointer dereference
+    - tty: serial: qcom_geni_serial: Initialize baud in qcom_geni_console_setup
+    - staging: comedi: ni_mio_common: Fix divide-by-zero for DIO cmdtest
+    - staging: olpc_dcon_xo_1: add missing 'const' qualifier
+    - staging: speakup_soft: Fix alternate speech with other synths
+    - staging: vt6655: Remove vif check from vnt_interrupt
+    - staging: vt6655: Fix interrupt race condition on device start up.
+    - staging: erofs: fix to handle error path of erofs_vmap()
+    - staging: erofs: fix error handling when failed to read compresssed data
+    - staging: erofs: keep corrupted fs from crashing kernel in erofs_readdir()
+    - serial: max310x: Fix to avoid potential NULL pointer dereference
+    - serial: mvebu-uart: Fix to avoid a potential NULL pointer dereference
+    - serial: sh-sci: Fix setting SCSCR_TIE while transferring data
+    - USB: serial: cp210x: add new device id
+    - USB: serial: ftdi_sio: add additional NovaTech products
+    - USB: serial: mos7720: fix mos_parport refcount imbalance on error path
+    - USB: serial: option: set driver_info for SIM5218 and compatibles
+    - USB: serial: option: add support for Quectel EM12
+    - USB: serial: option: add Olicard 600
+    - ACPI / CPPC: Fix guaranteed performance handling
+    - Disable kgdboc failed by echo space to /sys/module/kgdboc/parameters/kgdboc
+    - fs/proc/proc_sysctl.c: fix NULL pointer dereference in put_links
+    - drivers/block/zram/zram_drv.c: fix idle/writeback string compare
+    - blk-mq: fix sbitmap ws_active for shared tags
+    - cpufreq: intel_pstate: Also use CPPC nominal_perf for base_frequency
+    - cpufreq: scpi: Fix use after free
+    - drm/vgem: fix use-after-free when drm_gem_handle_create() fails
+    - drm/vkms: fix use-after-free when drm_gem_handle_create() fails
+    - drm/i915: Mark AML 0x87CA as ULX
+    - drm/i915/gvt: Fix MI_FLUSH_DW parsing with correct index check
+    - drm/i915/icl: Fix the TRANS_DDI_FUNC_CTL2 bitfield macro
+    - gpio: exar: add a check for the return value of ida_simple_get fails
+    - gpio: adnp: Fix testing wrong value in adnp_gpio_direction_input
+    - phy: sun4i-usb: Support set_mode to USB_HOST for non-OTG PHYs
+    - usb: mtu3: fix EXTCON dependency
+    - USB: gadget: f_hid: fix deadlock in f_hidg_write()
+    - usb: common: Consider only available nodes for dr_mode
+    - mm/memory.c: fix modifying of page protection by insert_pfn()
+    - usb: host: xhci-rcar: Add XHCI_TRUST_TX_LENGTH quirk
+    - xhci: Fix port resume done detection for SS ports with LPM enabled
+    - usb: xhci: dbc: Don't free all memory with spinlock held
+    - xhci: Don't let USB3 ports stuck in polling state prevent suspend
+    - usb: cdc-acm: fix race during wakeup blocking TX traffic
+    - usb: typec: tcpm: Try PD-2.0 if sink does not respond to 3.0 source-caps
+    - usb: typec: Fix unchecked return value
+    - mm/hotplug: fix offline undo_isolate_page_range()
+    - mm: add support for kmem caches in DMA32 zone
+    - iommu/io-pgtable-arm-v7s: request DMA32 memory, and improve debugging
+    - mm: mempolicy: make mbind() return -EIO when MPOL_MF_STRICT is specified
+    - mm/debug.c: fix __dump_page when mapping->host is not set
+    - mm/memory_hotplug.c: fix notification in offline error path
+    - mm/page_isolation.c: fix a wrong flag in set_migratetype_isolate()
+    - mm/migrate.c: add missing flush_dcache_page for non-mapped page migrate
+    - perf pmu: Fix parser error for uncore event alias
+    - perf intel-pt: Fix TSC slip
+    - objtool: Query pkg-config for libelf location
+    - powerpc/pseries/energy: Use OF accessor functions to read ibm,drc-indexes
+    - powerpc/64: Fix memcmp reading past the end of src/dest
+    - powerpc/pseries/mce: Fix misleading print for TLB mutlihit
+    - watchdog: Respect watchdog cpumask on CPU hotplug
+    - cpu/hotplug: Prevent crash when CPU bringup fails on CONFIG_HOTPLUG_CPU=n
+    - x86/smp: Enforce CONFIG_HOTPLUG_CPU when SMP=y
+    - KVM: Reject device ioctls from processes other than the VM's creator
+    - KVM: x86: Emulate MSR_IA32_ARCH_CAPABILITIES on AMD hosts
+    - KVM: x86: update %rip after emulating IO
+    - bpf: do not restore dst_reg when cur_state is freed
+    - mt76x02u: use usb_bulk_msg to upload firmware
+    - Linux 5.0.6
+
+  * RDMA/hns updates for disco (LP: #1822897)
+    - RDMA/hns: Fix the bug with updating rq head pointer when flush cqe
+    - RDMA/hns: Bugfix for the scene without receiver queue
+    - RDMA/hns: Add constraint on the setting of local ACK timeout
+    - RDMA/hns: Modify the pbl ba page size for hip08
+    - RDMA/hns: RDMA/hns: Assign rq head pointer when enable rq record db
+    - RDMA/hns: Add the process of AEQ overflow for hip08
+    - RDMA/hns: Add SCC context allocation support for hip08
+    - RDMA/hns: Add SCC context clr support for hip08
+    - RDMA/hns: Add timer allocation support for hip08
+    - RDMA/hns: Remove set but not used variable 'rst'
+    - RDMA/hns: Make some function static
+    - RDMA/hns: Fix the Oops during rmmod or insmod ko when reset occurs
+    - RDMA/hns: Fix the chip hanging caused by sending mailbox&CMQ during reset
+    - RDMA/hns: Fix the chip hanging caused by sending doorbell during reset
+    - RDMA/hns: Limit minimum ROCE CQ depth to 64
+    - RDMA/hns: Fix the state of rereg mr
+    - RDMA/hns: Set allocated memory to zero for wrid
+    - RDMA/hns: Delete useful prints for aeq subtype event
+    - RDMA/hns: Configure capacity of hns device
+    - RDMA/hns: Modify qp&cq&pd specification according to UM
+    - RDMA/hns: Bugfix for set hem of SCC
+    - RDMA/hns: Use GFP_ATOMIC in hns_roce_v2_modify_qp
+
+  * autopkgtests run too often, too much and don't skip enough (LP: #1823056)
+    - Set +x on rebuild testcase.
+    - Skip rebuild test, for regression-suite deps.
+    - Make ubuntu-regression-suite skippable on unbootable kernels.
+    - make rebuild use skippable error codes when skipping.
+    - Only run regression-suite, if requested to.
+
+  * touchpad not working on lenovo yoga 530 (LP: #1787775)
+    - Revert "UBUNTU: SAUCE: i2c:amd Depends on ACPI"
+    - Revert "UBUNTU: SAUCE: i2c:amd move out pointer in union i2c_event_base"
+    - i2c: add extra check to safe DMA buffer helper
+    - i2c: Add drivers for the AMD PCIe MP2 I2C controller
+    - [Config] Update config for AMD MP2 I2C driver
+
+  * Detect SMP PHY control command errors (LP: #1822680)
+    - scsi: libsas: Check SMP PHY control function result
+
+  * disable a.out support (LP: #1818552)
+    - [Config] Disable a.out support
+    - [Config] remove binfmt_aout from abi for i386 lowlatency
+
+  * bionic: fork out linux-snapdragon into its own topic kernel (LP: #1820868)
+    - [Packaging] remove snapdragon flavour support
+    - Revert "UBUNTU: SAUCE: (snapdragon) drm/msm/adv7511: wrap hacks under
+      CONFIG_ADV7511_SNAPDRAGON_HACKS #ifdefs"
+    - Revert "UBUNTU: SAUCE: (snapdragon) media: ov5645: skip address change if dt
+      addr == default addr"
+    - Revert "UBUNTU: SAUCE: (snapdragon) DT: leds: Add Qualcomm Light Pulse
+      Generator binding"
+    - Revert "UBUNTU: SAUCE: (snapdragon) MAINTAINERS: Add Qualcomm Camera Control
+      Interface driver"
+    - Revert "UBUNTU: SAUCE: (snapdragon) dt-bindings: media: Binding document for
+      Qualcomm Camera Control Interface driver"
+    - Revert "UBUNTU: SAUCE: (snapdragon) leds: Add driver for Qualcomm LPG"
+    - Revert "UBUNTU: SAUCE: (snapdragon) HACK: drm/msm/adv7511: Don't rely on
+      interrupts for EDID parsing"
+    - Revert "UBUNTU: SAUCE: (snapdragon) drm/bridge/adv7511: Delay clearing of
+      HPD interrupt status"
+    - Revert "UBUNTU: SAUCE: (snapdragon) media: ov5645: Fix I2C address"
+    - Revert "UBUNTU: SAUCE: (snapdragon) i2c-qcom-cci: Fix I2C address bug"
+    - Revert "UBUNTU: SAUCE: (snapdragon) i2c-qcom-cci: Fix run queue completion
+      timeout"
+    - Revert "UBUNTU: SAUCE: (snapdragon) camss: Do not register if no cameras are
+      present"
+    - Revert "UBUNTU: SAUCE: (snapdragon) i2c: Add Qualcomm Camera Control
+      Interface driver"
+    - Revert "UBUNTU: SAUCE: (snapdragon) ov5645: I2C address change"
+    - Revert "UBUNTU: SAUCE: (snapdragon) regulator: smd: Allow
+      REGULATOR_QCOM_SMD_RPM=m"
+    - Revert "UBUNTU: SAUCE: (snapdragon) cpufreq: Add apq8016 to cpufreq-dt-
+      platdev blacklist"
+    - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: Add a helper to get an opp
+      regulator for device"
+    - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: HACK: Allow to set regulator
+      without opp_list"
+    - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: Drop RCU usage in
+      dev_pm_opp_adjust_voltage()"
+    - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: Support adjusting OPP voltages
+      at runtime"
+    - Revert "UBUNTU: SAUCE: (snapdragon) regulator: smd: Add floor and corner
+      operations"
+    - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: cpr: Register with cpufreq-
+      dt"
+    - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: cpr: fix with new
+      reg_sequence structures"
+    - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: cpr: Use raw mem access for
+      qfprom"
+    - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: Add support for CPR (Core
+      Power Reduction)"
+    - Revert "UBUNTU: SAUCE: (snapdragon) HACK: drm/msm/iommu: Remove runtime_put
+      calls in map/unmap"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable LEDS_QCOM_LPG"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable 'BBR' TCP
+      congestion algorithm"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable 'fq' and
+      'fq_codel' qdiscs"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable
+      'schedutil' CPUfreq governor"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: set USB_CONFIG_F_FS in
+      distro.config"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable
+      CONFIG_USB_CONFIGFS_F_FS by default"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: add freq stat to sysfs"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: Enable camera drivers"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: disable ANALOG_TV and
+      DIGITAL_TV"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: add more USB net
+      drivers"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: enable BT_QCOMSMD"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable
+      CFG80211_DEFAULT_PS by default"
+    - Revert "UBUNTU: SAUCE: (snapdragon) Force the SMD regulator driver to be
+      compiled-in"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: enable dm_mod and
+      dm_crypt"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: Enable a53/apcs and
+      avs"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: enable QCOM Venus"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable debug
+      friendly USB network adpater"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: enable WCN36xx"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs; add distro.config"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable QCOM audio
+      drivers for APQ8016 and DB410c"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable REMOTEPROC"
+    - [Config] fix abi for remove i2c-qcom-cci module
+    - [Config] update annotations
+    - [Config] update configs following snapdragon removal
+
+  * Disco update: v5.0.5 upstream stable release (LP: #1822671)
+    - Revert "ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec"
+    - ALSA: hda - add Lenovo IdeaCentre B550 to the power_save_blacklist
+    - ALSA: firewire-motu: use 'version' field of unit directory to identify model
+    - mmc: pxamci: fix enum type confusion
+    - mmc: alcor: fix DMA reads
+    - mmc: mxcmmc: "Revert mmc: mxcmmc: handle highmem pages"
+    - mmc: renesas_sdhi: limit block count to 16 bit for old revisions
+    - drm/amdgpu: fix invalid use of change_bit
+    - drm/vmwgfx: Don't double-free the mode stored in par->set_mode
+    - drm/vmwgfx: Return 0 when gmrid::get_node runs out of ID's
+    - iommu/amd: fix sg->dma_address for sg->offset bigger than PAGE_SIZE
+    - iommu/iova: Fix tracking of recently failed iova address
+    - libceph: wait for latest osdmap in ceph_monc_blacklist_add()
+    - udf: Fix crash on IO error during truncate
+    - mips: loongson64: lemote-2f: Add IRQF_NO_SUSPEND to "cascade" irqaction.
+    - MIPS: Ensure ELF appended dtb is relocated
+    - MIPS: Fix kernel crash for R6 in jump label branch function
+    - powerpc/vdso64: Fix CLOCK_MONOTONIC inconsistencies across Y2038
+    - powerpc/security: Fix spectre_v2 reporting
+    - net/mlx5: Fix DCT creation bad flow
+    - scsi: core: Avoid that a kernel warning appears during system resume
+    - scsi: qla2xxx: Fix FC-AL connection target discovery
+    - scsi: ibmvscsi: Protect ibmvscsi_head from concurrent modificaiton
+    - scsi: ibmvscsi: Fix empty event pool access during host removal
+    - futex: Ensure that futex address is aligned in handle_futex_death()
+    - perf probe: Fix getting the kernel map
+    - objtool: Move objtool_file struct off the stack
+    - irqchip/gic-v3-its: Fix comparison logic in lpi_range_cmp
+    - clocksource/drivers/riscv: Fix clocksource mask
+    - ALSA: ac97: Fix of-node refcount unbalance
+    - ext4: fix NULL pointer dereference while journal is aborted
+    - ext4: fix data corruption caused by unaligned direct AIO
+    - ext4: brelse all indirect buffer in ext4_ind_remove_space()
+    - media: v4l2-ctrls.c/uvc: zero v4l2_event
+    - Bluetooth: hci_uart: Check if socket buffer is ERR_PTR in h4_recv_buf()
+    - Bluetooth: Fix decrementing reference count twice in releasing socket
+    - Bluetooth: hci_ldisc: Initialize hci_dev before open()
+    - Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in
+      hci_uart_set_proto()
+    - drm/vkms: Fix flush_work() without INIT_WORK().
+    - RDMA/cma: Rollback source IP address if failing to acquire device
+    - f2fs: fix to avoid deadlock of atomic file operations
+    - aio: simplify - and fix - fget/fput for io_submit()
+    - netfilter: ebtables: remove BUGPRINT messages
+    - loop: access lo_backing_file only when the loop device is Lo_bound
+    - x86/unwind: Handle NULL pointer calls better in frame unwinder
+    - x86/unwind: Add hardcoded ORC entry for NULL
+    - locking/lockdep: Add debug_locks check in __lock_downgrade()
+    - ALSA: hda - Record the current power state before suspend/resume calls
+    - ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec
+    - Linux 5.0.5
+
+  * hisi_sas updates for disco (LP: #1822385)
+    - scsi: hisi_sas: send primitive NOTIFY to SSP situation only
+    - scsi: hisi_sas: shutdown axi bus to avoid exception CQ returned
+    - scsi: hisi_sas: remove the check of sas_dev status in
+      hisi_sas_I_T_nexus_reset()
+    - scsi: hisi_sas: Remove unused parameter of function hisi_sas_alloc()
+    - scsi: hisi_sas: Reject setting programmed minimum linkrate > 1.5G
+    - scsi: hisi_sas: Fix losing directly attached disk when hot-plug
+    - scsi: hisi_sas: Correct memory allocation size for DQ debugfs
+    - scsi: hisi_sas: Some misc tidy-up
+    - scsi: hisi_sas: Fix to only call scsi_get_prot_op() for non-NULL scsi_cmnd
+    - scsi: hisi_sas: Add missing seq_printf() call in hisi_sas_show_row_32()
+    - scsi: hisi_sas: Add support for DIX feature for v3 hw
+    - scsi: hisi_sas: Add manual trigger for debugfs dump
+    - scsi: hisi_sas: change queue depth from 512 to 4096
+    - scsi: hisi_sas: Issue internal abort on all relevant queues
+    - scsi: hisi_sas: Use pci_irq_get_affinity() for v3 hw as experimental
+    - scsi: hisi_sas: Do some more tidy-up
+    - scsi: hisi_sas: Change return variable type in phy_up_v3_hw()
+    - scsi: hisi_sas: Fix a timeout race of driver internal and SMP IO
+    - scsi: hisi_sas: print PHY RX errors count for later revision of v3 hw
+    - scsi: hisi_sas: Set PHY linkrate when disconnected
+    - scsi: hisi_sas: Send HARD RESET to clear the previous affiliation of STP
+      target port
+    - scsi: hisi_sas: Change SERDES_CFG init value to increase reliability of
+      HiLink
+    - scsi: hisi_sas: Add softreset in hisi_sas_I_T_nexus_reset()
+
+  * [Patch][Raven 2] kernel 5.0.0 cannot boot because of psp response
+    (LP: #1822267)
+    - drm/amdgpu/psp: Fix can't detect psp INVOKE command failed
+    - drm/amdgpu/psp: ignore psp response status
+
+  * 3b080b2564287be91605bfd1d5ee985696e61d3c in ubuntu_btrfs_kernel_fixes
+    triggers system hang on i386 (LP: #1812845)
+    - btrfs: raid56: properly unmap parity page in finish_parity_scrub()
+
+  * enable CONFIG_DRM_BOCHS (LP: #1795857)
+    - [Config] Reenable DRM_BOCHS as module
+
+  * [Dell Precision 7530/5530 with Nvidia Quadro P1000] Live USB freezes or
+    cannot complete install when nouveau driver is loaded (crashing in GP100
+    code) (LP: #1822026)
+    - SAUCE: drm/nouveau: Disable nouveau driver by default
+
+  * Need to add Intel CML related pci-id's (LP: #1821863)
+    - drm/i915/cml: Add CML PCI IDS
+    - drm/i915/cml: Introduce Comet Lake PCH
+
+  * ARM: Add support for the SDEI interface (LP: #1822005)
+    - ACPI / APEI: Don't wait to serialise with oops messages when panic()ing
+    - ACPI / APEI: Remove silent flag from ghes_read_estatus()
+    - ACPI / APEI: Switch estatus pool to use vmalloc memory
+    - ACPI / APEI: Make hest.c manage the estatus memory pool
+    - ACPI / APEI: Make estatus pool allocation a static size
+    - ACPI / APEI: Don't store CPER records physical address in struct ghes
+    - ACPI / APEI: Remove spurious GHES_TO_CLEAR check
+    - ACPI / APEI: Don't update struct ghes' flags in read/clear estatus
+    - ACPI / APEI: Generalise the estatus queue's notify code
+    - ACPI / APEI: Don't allow ghes_ack_error() to mask earlier errors
+    - ACPI / APEI: Move NOTIFY_SEA between the estatus-queue and NOTIFY_NMI
+    - ACPI / APEI: Switch NOTIFY_SEA to use the estatus queue
+    - KVM: arm/arm64: Add kvm_ras.h to collect kvm specific RAS plumbing
+    - arm64: KVM/mm: Move SEA handling behind a single 'claim' interface
+    - ACPI / APEI: Move locking to the notification helper
+    - ACPI / APEI: Let the notification helper specify the fixmap slot
+    - ACPI / APEI: Pass ghes and estatus separately to avoid a later copy
+    - ACPI / APEI: Make GHES estatus header validation more user friendly
+    - ACPI / APEI: Split ghes_read_estatus() to allow a peek at the CPER length
+    - ACPI / APEI: Only use queued estatus entry during in_nmi_queue_one_entry()
+    - ACPI / APEI: Use separate fixmap pages for arm64 NMI-like notifications
+    - firmware: arm_sdei: Add ACPI GHES registration helper
+    - ACPI / APEI: Add support for the SDEI GHES Notification type
+
+  * CVE-2019-9857
+    - inotify: Fix fsnotify_mark refcount leak in inotify_update_existing_watch()
+
+  * scsi: libsas: Support SATA PHY connection rate unmatch fixing during
+    discovery (LP: #1821408)
+    - scsi: libsas: Support SATA PHY connection rate unmatch fixing during
+      discovery
+
+  * Qualcomm Atheros QCA9377 wireless does not work (LP: #1818204)
+    - platform/x86: ideapad-laptop: Add Ideapad 530S-14ARR to no_hw_rfkill list
+
+  * Lenovo ideapad 330-15ICH Wifi rfkill hard blocked (LP: #1811815)
+    - platform/x86: ideapad: Add ideapad 330-15ICH to no_hw_rfkill
+
+  * hid-sensor-hub spamming dmesg in 4.20 (LP: #1818547)
+    - HID: Increase maximum report size allowed by hid_field_extract()
+
+  * [disco] [5.0.0-7.8] can't mount guest cifs share (LP: #1821053)
+    - cifs: allow guest mounts to work for smb3.11
+    - SMB3: Fix SMB3.1.1 guest mounts to Samba
+
+  * Add HiSilicon SoC quirk for cpufreq (LP: #1821620)
+    - ACPI / CPPC: Add a helper to get desired performance
+    - cpufreq / cppc: Work around for Hisilicon CPPC cpufreq
+
+  * Disco update: v5.0.4 upstream stable release (LP: #1821607)
+    - 9p: use inode->i_lock to protect i_size_write() under 32-bit
+    - 9p/net: fix memory leak in p9_client_create
+    - ASoC: fsl_esai: fix register setting issue in RIGHT_J mode
+    - ASoC: codecs: pcm186x: fix wrong usage of DECLARE_TLV_DB_SCALE()
+    - ASoC: codecs: pcm186x: Fix energysense SLEEP bit
+    - iio: adc: exynos-adc: Fix NULL pointer exception on unbind
+    - iio: adc: exynos-adc: Use proper number of channels for Exynos4x12
+    - mei: hbm: clean the feature flags on link reset
+    - mei: bus: move hw module get/put to probe/release
+    - stm class: Prevent division by zero
+    - stm class: Fix an endless loop in channel allocation
+    - crypto: caam - fix hash context DMA unmap size
+    - crypto: ccree - fix missing break in switch statement
+    - crypto: caam - fixed handling of sg list
+    - crypto: caam - fix DMA mapping of stack memory
+    - crypto: ccree - fix free of unallocated mlli buffer
+    - crypto: ccree - unmap buffer before copying IV
+    - crypto: ccree - don't copy zero size ciphertext
+    - crypto: cfb - add missing 'chunksize' property
+    - crypto: cfb - remove bogus memcpy() with src == dest
+    - crypto: ofb - fix handling partial blocks and make thread-safe
+    - crypto: ahash - fix another early termination in hash walk
+    - crypto: rockchip - fix scatterlist nents error
+    - crypto: rockchip - update new iv to device in multiple operations
+    - dax: Flush partial PMDs correctly
+    - nfit: Fix nfit_intel_shutdown_status() command submission
+    - nfit: acpi_nfit_ctl(): Check out_obj->type in the right place
+    - acpi/nfit: Fix bus command validation
+    - nfit/ars: Attempt a short-ARS whenever the ARS state is idle at boot
+    - nfit/ars: Attempt short-ARS even in the no_init_ars case
+    - libnvdimm/label: Clear 'updating' flag after label-set update
+    - libnvdimm, pfn: Fix over-trim in trim_pfn_device()
+    - libnvdimm/pmem: Honor force_raw for legacy pmem regions
+    - libnvdimm: Fix altmap reservation size calculation
+    - fix cgroup_do_mount() handling of failure exits
+    - crypto: aead - set CRYPTO_TFM_NEED_KEY if ->setkey() fails
+    - crypto: aegis - fix handling chunked inputs
+    - crypto: arm/crct10dif - revert to C code for short inputs
+    - crypto: arm64/aes-neonbs - fix returning final keystream block
+    - crypto: arm64/crct10dif - revert to C code for short inputs
+    - crypto: hash - set CRYPTO_TFM_NEED_KEY if ->setkey() fails
+    - crypto: morus - fix handling chunked inputs
+    - crypto: pcbc - remove bogus memcpy()s with src == dest
+    - crypto: skcipher - set CRYPTO_TFM_NEED_KEY if ->setkey() fails
+    - crypto: testmgr - skip crc32c context test for ahash algorithms
+    - crypto: x86/aegis - fix handling chunked inputs and MAY_SLEEP
+    - crypto: x86/aesni-gcm - fix crash on empty plaintext
+    - crypto: x86/morus - fix handling chunked inputs and MAY_SLEEP
+    - crypto: arm64/aes-ccm - fix logical bug in AAD MAC handling
+    - crypto: arm64/aes-ccm - fix bugs in non-NEON fallback routine
+    - CIFS: Fix leaking locked VFS cache pages in writeback retry
+    - CIFS: Do not reset lease state to NONE on lease break
+    - CIFS: Do not skip SMB2 message IDs on send failures
+    - CIFS: Fix read after write for files with read caching
+    - smb3: make default i/o size for smb3 mounts larger
+    - tracing: Use strncpy instead of memcpy for string keys in hist triggers
+    - tracing: Do not free iter->trace in fail path of tracing_open_pipe()
+    - tracing/perf: Use strndup_user() instead of buggy open-coded version
+    - vmw_balloon: release lock on error in vmballoon_reset()
+    - xen: fix dom0 boot on huge systems
+    - ACPI / device_sysfs: Avoid OF modalias creation for removed device
+    - mmc: sdhci-esdhc-imx: fix HS400 timing issue
+    - mmc: renesas_sdhi: Fix card initialization failure in high speed mode
+    - mmc:fix a bug when max_discard is 0
+    - spi: ti-qspi: Fix mmap read when more than one CS in use
+    - spi: pxa2xx: Setup maximum supported DMA transfer length
+    - spi: omap2-mcspi: Fix DMA and FIFO event trigger size mismatch
+    - spi: spi-gpio: fix SPI_CS_HIGH capability
+    - regulator: s2mps11: Fix steps for buck7, buck8 and LDO35
+    - regulator: max77620: Initialize values for DT properties
+    - regulator: s2mpa01: Fix step values for some LDOs
+    - mt76: fix corrupted software generated tx CCMP PN
+    - clocksource/drivers/exynos_mct: Move one-shot check from tick clear to ISR
+    - clocksource/drivers/exynos_mct: Clear timer interrupt when shutdown
+    - clocksource/drivers/arch_timer: Workaround for Allwinner A64 timer
+      instability
+    - s390: vfio_ap: link the vfio_ap devices to the vfio_ap bus subsystem
+    - s390/setup: fix early warning messages
+    - s390/virtio: handle find on invalid queue gracefully
+    - scsi: virtio_scsi: don't send sc payload with tmfs
+    - scsi: aacraid: Fix performance issue on logical drives
+    - scsi: sd: Optimal I/O size should be a multiple of physical block size
+    - scsi: target/iscsi: Avoid iscsit_release_commands_from_conn() deadlock
+    - scsi: qla2xxx: Fix LUN discovery if loop id is not assigned yet by firmware
+    - scsi: qla2xxx: Avoid PCI IRQ affinity mapping when multiqueue is not
+      supported
+    - scsi: qla2xxx: Use complete switch scan for RSCN events
+    - fs/devpts: always delete dcache dentry-s in dput()
+    - splice: don't merge into linked buffers
+    - ovl: During copy up, first copy up data and then xattrs
+    - ovl: Do not lose security.capability xattr over metadata file copy-up
+    - m68k: Add -ffreestanding to CFLAGS
+    - Btrfs: setup a nofs context for memory allocation at btrfs_create_tree()
+    - Btrfs: setup a nofs context for memory allocation at __btrfs_set_acl
+    - btrfs: scrub: fix circular locking dependency warning
+    - btrfs: drop the lock on error in btrfs_dev_replace_cancel
+    - btrfs: ensure that a DUP or RAID1 block group has exactly two stripes
+    - btrfs: init csum_list before possible free
+    - Btrfs: fix corruption reading shared and compressed extents after hole
+      punching
+    - Btrfs: fix deadlock between clone/dedupe and rename
+    - soc: qcom: rpmh: Avoid accessing freed memory from batch API
+    - libertas_tf: don't set URB_ZERO_PACKET on IN USB transfer
+    - irqchip/gic-v3-its: Avoid parsing _indirect_ twice for Device table
+    - irqchip/brcmstb-l2: Use _irqsave locking variants in non-interrupt code
+    - x86/kprobes: Prohibit probing on optprobe template code
+    - cpufreq: kryo: Release OPP tables on module removal
+    - cpufreq: tegra124: add missing of_node_put()
+    - cpufreq: pxa2xx: remove incorrect __init annotation
+    - ext4: fix check of inode in swap_inode_boot_loader
+    - ext4: cleanup pagecache before swap i_data
+    - mm: hwpoison: fix thp split handing in soft_offline_in_use_page()
+    - mm/vmalloc: fix size check for remap_vmalloc_range_partial()
+    - mm/memory.c: do_fault: avoid usage of stale vm_area_struct
+    - kernel/sysctl.c: add missing range check in do_proc_dointvec_minmax_conv
+    - nvmem: core: don't check the return value of notifier chain call
+    - device property: Fix the length used in PROPERTY_ENTRY_STRING()
+    - intel_th: Don't reference unassigned outputs
+    - parport_pc: fix find_superio io compare code, should use equal test.
+    - i2c: tegra: fix maximum transfer size
+    - i2c: tegra: update maximum transfer size
+    - media: i2c: ov5640: Fix post-reset delay
+    - gpio: pca953x: Fix dereference of irq data in shutdown
+    - ext4: update quota information while swapping boot loader inode
+    - ext4: add mask of ext4 flags to swap
+    - ext4: fix crash during online resizing
+    - dma: Introduce dma_max_mapping_size()
+    - swiotlb: Introduce swiotlb_max_mapping_size()
+    - swiotlb: Add is_swiotlb_active() function
+    - PCI/ASPM: Use LTR if already enabled by platform
+    - PCI/DPC: Fix print AER status in DPC event handling
+    - PCI: qcom: Don't deassert reset GPIO during probe
+    - PCI: dwc: skip MSI init if MSIs have been explicitly disabled
+    - PCI: pci-bridge-emul: Create per-bridge copy of register behavior
+    - PCI: pci-bridge-emul: Extend pci_bridge_emul_init() with flags
+    - IB/hfi1: Close race condition on user context disable and close
+    - IB/rdmavt: Fix loopback send with invalidate ordering
+    - IB/rdmavt: Fix concurrency panics in QP post_send and modify to error
+    - cxl: Wrap iterations over afu slices inside 'afu_list_lock'
+    - ext2: Fix underflow in ext2_max_size()
+    - clk: uniphier: Fix update register for CPU-gear
+    - clk: clk-twl6040: Fix imprecise external abort for pdmclk
+    - clk: samsung: exynos5: Fix possible NULL pointer exception on
+      platform_device_alloc() failure
+    - clk: samsung: exynos5: Fix kfree() of const memory on setting
+      driver_override
+    - clk: ingenic: Fix round_rate misbehaving with non-integer dividers
+    - clk: ingenic: Fix doc of ingenic_cgu_div_info
+    - usb: chipidea: tegra: Fix missed ci_hdrc_remove_device()
+    - usb: typec: tps6598x: handle block writes separately with plain-I2C adapters
+    - dmaengine: usb-dmac: Make DMAC system sleep callbacks explicit
+    - serial: uartps: Fix stuck ISR if RX disabled with non-empty FIFO
+    - serial: 8250_of: assume reg-shift of 2 for mrvl,mmp-uart
+    - serial: 8250_pci: Fix number of ports for ACCES serial cards
+    - serial: 8250_pci: Have ACCES cards that use the four port Pericom PI7C9X7954
+      chip use the pci_pericom_setup()
+    - jbd2: clear dirty flag when revoking a buffer from an older transaction
+    - jbd2: fix compile warning when using JBUFFER_TRACE
+    - selinux: add the missing walk_size + len check in selinux_sctp_bind_connect
+    - security/selinux: fix SECURITY_LSM_NATIVE_LABELS on reused superblock
+    - powerpc/32: Clear on-stack exception marker upon exception return
+    - powerpc/wii: properly disable use of BATs when requested.
+    - powerpc/powernv: Make opal log only readable by root
+    - powerpc/83xx: Also save/restore SPRG4-7 during suspend
+    - powerpc/kvm: Save and restore host AMR/IAMR/UAMOR
+    - powerpc/powernv: Don't reprogram SLW image on every KVM guest entry/exit
+    - powerpc/64s/hash: Fix assert_slb_presence() use of the slbfee. instruction
+    - powerpc: Fix 32-bit KVM-PR lockup and host crash with MacOS guest
+    - powerpc/ptrace: Simplify vr_get/set() to avoid GCC warning
+    - powerpc/hugetlb: Don't do runtime allocation of 16G pages in LPAR
+      configuration
+    - powerpc/smp: Fix NMI IPI timeout
+    - powerpc/smp: Fix NMI IPI xmon timeout
+    - powerpc/traps: fix recoverability of machine check handling on book3s/32
+    - powerpc/traps: Fix the message printed when stack overflows
+    - ARM: s3c24xx: Fix boolean expressions in osiris_dvs_notify
+    - arm64: Fix HCR.TGE status for NMI contexts
+    - arm64: debug: Don't propagate UNKNOWN FAR into si_code for debug signals
+    - arm64: debug: Ensure debug handlers check triggering exception level
+    - arm64: KVM: Fix architecturally invalid reset value for FPEXC32_EL2
+    - Revert "KVM/MMU: Flush tlb directly in the kvm_zap_gfn_range()"
+    - ipmi_si: Fix crash when using hard-coded device
+    - ipmi_si: fix use-after-free of resource->name
+    - dm: fix to_sector() for 32bit
+    - dm integrity: limit the rate of error messages
+    - media: cx25840: mark pad sig_types to fix cx231xx init
+    - mfd: sm501: Fix potential NULL pointer dereference
+    - cpcap-charger: generate events for userspace
+    - cpuidle: governor: Add new governors to cpuidle_governors again
+    - NFS: Fix I/O request leakages
+    - NFS: Fix an I/O request leakage in nfs_do_recoalesce
+    - NFS: Don't recoalesce on error in nfs_pageio_complete_mirror()
+    - nfsd: fix performance-limiting session calculation
+    - nfsd: fix memory corruption caused by readdir
+    - nfsd: fix wrong check in write_v4_end_grace()
+    - NFSv4.1: Reinitialise sequence results before retransmitting a request
+    - svcrpc: fix UDP on servers with lots of threads
+    - PM / wakeup: Rework wakeup source timer cancellation
+    - PM / OPP: Update performance state when freq == old_freq
+    - bcache: treat stale && dirty keys as bad keys
+    - bcache: use (REQ_META|REQ_PRIO) to indicate bio for metadata
+    - stable-kernel-rules.rst: add link to networking patch queue
+    - vt: perform safe console erase in the right order
+    - x86/unwind/orc: Fix ORC unwind table alignment
+    - perf intel-pt: Fix CYC timestamp calculation after OVF
+    - perf tools: Fix split_kallsyms_for_kcore() for trampoline symbols
+    - perf auxtrace: Define auxtrace record alignment
+    - perf intel-pt: Fix overlap calculation for padding
+    - perf/x86/intel/uncore: Fix client IMC events return huge result
+    - perf intel-pt: Fix divide by zero when TSC is not available
+    - md: Fix failed allocation of md_register_thread
+    - x86/kvmclock: set offset for kvm unstable clock
+    - x86/ftrace: Fix warning and considate ftrace_jmp_replace() and
+      ftrace_call_replace()
+    - tpm/tpm_crb: Avoid unaligned reads in crb_recv()
+    - tpm: Unify the send callback behaviour
+    - rcu: Do RCU GP kthread self-wakeup from softirq and interrupt
+    - media: imx: prpencvf: Stop upstream before disabling IDMA channel
+    - media: lgdt330x: fix lock status reporting
+    - media: sun6i: Fix CSI regmap's max_register
+    - media: uvcvideo: Avoid NULL pointer dereference at the end of streaming
+    - media: vimc: Add vimc-streamer for stream control
+    - media: imx-csi: Input connections to CSI should be optional
+    - media: imx: csi: Disable CSI immediately after last EOF
+    - media: imx: csi: Stop upstream before disabling IDMA channel
+    - drm/fb-helper: generic: Fix drm_fbdev_client_restore()
+    - drm/radeon/evergreen_cs: fix missing break in switch statement
+    - drm/amd/powerplay: correct power reading on fiji
+    - drm/amd/display: don't call dm_pp_ function from an fpu block
+    - KVM: Call kvm_arch_memslots_updated() before updating memslots
+    - KVM: VMX: Compare only a single byte for VMCS' "launched" in vCPU-run
+    - KVM: VMX: Zero out *all* general purpose registers after VM-Exit
+    - KVM: x86/mmu: Detect MMIO generation wrap in any address space
+    - KVM: x86/mmu: Do not cache MMIO accesses while memslots are in flux
+    - KVM: nVMX: Sign extend displacements of VMX instr's mem operands
+    - KVM: nVMX: Apply addr size mask to effective address for VMX instructions
+    - KVM: nVMX: Ignore limit checks on VMX instructions using flat segments
+    - KVM: nVMX: Check a single byte for VMCS "launched" in nested early checks
+    - net: dsa: lantiq_gswip: fix use-after-free on failed probe
+    - net: dsa: lantiq_gswip: fix OF child-node lookups
+    - s390/setup: fix boot crash for machine without EDAT-1
+    - SUNRPC: Prevent thundering herd when the socket is not connected
+    - SUNRPC: Fix up RPC back channel transmission
+    - SUNRPC: Respect RPC call timeouts when retrying transmission
+    - Linux 5.0.4
+    - [Config] update configs for 5.0.4 stable update
+
+  * New Intel Wireless-AC 9260 [8086:2526] card not correctly probed in Ubuntu
+    system (LP: #1821271)
+    - iwlwifi: add new card for 9260 series
+
+  * [CONFIG] please enable highdpi font FONT_TER16x32 (LP: #1819881)
+    - [Config]: enable highdpi Terminus 16x32 font support
+
+  * [SRU][B/B-OEM/C/D] Fix AMD IOMMU NULL dereference (LP: #1820990)
+    - iommu/amd: Fix NULL dereference bug in match_hid_uid
+
+  * some codecs stop working after S3 (LP: #1820930)
+    - ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec
+    - ALSA: hda - Don't trigger jackpoll_work in azx_resume
+
+  * tcm_loop.ko: move from modules-extra into main modules package
+    (LP: #1817786)
+    - [Packaging] move tcm_loop.lo to main linux-modules package
+
+  * C++ demangling support missing from perf (LP: #1396654)
+    - [Packaging] fix a mistype
+
+  * r8169 doesn't get woken up by ethernet cable plugging, no PME generated
+    (LP: #1817676)
+    - PCI: pciehp: Disable Data Link Layer State Changed event on suspend
+
+  * Disco update: v5.0.3 upstream stable release (LP: #1821074)
+    - connector: fix unsafe usage of ->real_parent
+    - fou, fou6: avoid uninit-value in gue_err() and gue6_err()
+    - gro_cells: make sure device is up in gro_cells_receive()
+    - ipv4/route: fail early when inet dev is missing
+    - l2tp: fix infoleak in l2tp_ip6_recvmsg()
+    - lan743x: Fix RX Kernel Panic
+    - lan743x: Fix TX Stall Issue
+    - net: hsr: fix memory leak in hsr_dev_finalize()
+    - net/hsr: fix possible crash in add_timer()
+    - net: sit: fix UBSAN Undefined behaviour in check_6rd
+    - net/x25: fix use-after-free in x25_device_event()
+    - net/x25: reset state in x25_connect()
+    - pptp: dst_release sk_dst_cache in pptp_sock_destruct
+    - ravb: Decrease TxFIFO depth of Q3 and Q2 to one
+    - route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race
+    - rxrpc: Fix client call queueing, waiting for channel
+    - sctp: remove sched init from sctp_stream_init
+    - tcp: do not report TCP_CM_INQ of 0 for closed connections
+    - tcp: Don't access TCP_SKB_CB before initializing it
+    - tcp: handle inet_csk_reqsk_queue_add() failures
+    - vxlan: Fix GRO cells race condition between receive and link delete
+    - vxlan: test dev->flags & IFF_UP before calling gro_cells_receive()
+    - net/mlx4_core: Fix reset flow when in command polling mode
+    - net/mlx4_core: Fix locking in SRIOV mode when switching between events and
+      polling
+    - net/mlx4_core: Fix qp mtt size calculation
+    - net: dsa: mv88e6xxx: Set correct interface mode for CPU/DSA ports
+    - vsock/virtio: fix kernel panic from virtio_transport_reset_no_sock
+    - net: sched: flower: insert new filter to idr after setting its mask
+    - f2fs: wait on atomic writes to count F2FS_CP_WB_DATA
+    - perf/x86: Fixup typo in stub functions
+    - ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against
+      Liquid Saffire 56
+    - ALSA: firewire-motu: fix construction of PCM frame for capture direction
+    - ALSA: hda: Extend i915 component bind timeout
+    - ALSA: hda - add more quirks for HP Z2 G4 and HP Z240
+    - ALSA: hda/realtek: Enable audio jacks of ASUS UX362FA with ALC294
+    - ALSA: hda/realtek - Reduce click noise on Dell Precision 5820 headphone
+    - ALSA: hda/realtek: Enable headset MIC of Acer TravelMate X514-51T with
+      ALC255
+    - perf/x86/intel: Fix memory corruption
+    - perf/x86/intel: Make dev_attr_allow_tsx_force_abort static
+    - It's wrong to add len to sector_nr in raid10 reshape twice
+    - drm: Block fb changes for async plane updates
+    - Linux 5.0.3
+
+  * Disco update: v5.0.2 upstream stable release (LP: #1820318)
+    - media: uvcvideo: Fix 'type' check leading to overflow
+    - Input: wacom_serial4 - add support for Wacom ArtPad II tablet
+    - Input: elan_i2c - add id for touchpad found in Lenovo s21e-20
+    - iscsi_ibft: Fix missing break in switch statement
+    - scsi: aacraid: Fix missing break in switch statement
+    - x86/PCI: Fixup RTIT_BAR of Intel Denverton Trace Hub
+    - arm64: dts: zcu100-revC: Give wifi some time after power-on
+    - arm64: dts: hikey: Give wifi some time after power-on
+    - arm64: dts: hikey: Revert "Enable HS200 mode on eMMC"
+    - ARM: dts: exynos: Fix pinctrl definition for eMMC RTSN line on Odroid X2/U3
+    - ARM: dts: exynos: Add minimal clkout parameters to Exynos3250 PMU
+    - ARM: dts: exynos: Fix max voltage for buck8 regulator on Odroid XU3/XU4
+    - drm: disable uncached DMA optimization for ARM and arm64
+    - media: Revert "media: rc: some events are dropped by userspace"
+    - Revert "PCI/PME: Implement runtime PM callbacks"
+    - bpf: Stop the psock parser before canceling its work
+    - gfs2: Fix missed wakeups in find_insert_glock
+    - staging: erofs: keep corrupted fs from crashing kernel in erofs_namei()
+    - staging: erofs: compressed_pages should not be accessed again after freed
+    - scripts/gdb: replace flags (MS_xyz -> SB_xyz)
+    - ath9k: Avoid OF no-EEPROM quirks without qca,no-eeprom
+    - perf/x86/intel: Make cpuc allocations consistent
+    - perf/x86/intel: Generalize dynamic constraint creation
+    - x86: Add TSX Force Abort CPUID/MSR
+    - perf/x86/intel: Implement support for TSX Force Abort
+    - Linux 5.0.2
+
+  * Linux security module stacking support
+    - LSM: Introduce LSM_FLAG_LEGACY_MAJOR
+    - LSM: Provide separate ordered initialization
+    - LSM: Plumb visibility into optional "enabled" state
+    - LSM: Lift LSM selection out of individual LSMs
+    - LSM: Build ordered list of LSMs to initialize
+    - LSM: Introduce CONFIG_LSM
+    - LSM: Introduce "lsm=" for boottime LSM selection
+    - LSM: Tie enabling logic to presence in ordered list
+    - LSM: Prepare for reorganizing "security=" logic
+    - LSM: Refactor "security=" in terms of enable/disable
+    - LSM: Separate idea of "major" LSM from "exclusive" LSM
+    - apparmor: Remove SECURITY_APPARMOR_BOOTPARAM_VALUE
+    - selinux: Remove SECURITY_SELINUX_BOOTPARAM_VALUE
+    - LSM: Add all exclusive LSMs to ordered initialization
+    - LSM: Split LSM preparation from initialization
+    - LoadPin: Initialize as ordered LSM
+    - Yama: Initialize as ordered LSM
+    - LSM: Introduce enum lsm_order
+    - capability: Initialize as LSM_ORDER_FIRST
+    - procfs: add smack subdir to attrs
+    - Smack: Abstract use of cred security blob
+    - SELinux: Abstract use of cred security blob
+    - SELinux: Remove cred security blob poisoning
+    - SELinux: Remove unused selinux_is_enabled
+    - AppArmor: Abstract use of cred security blob
+    - TOMOYO: Abstract use of cred security blob
+    - Infrastructure management of the cred security blob
+    - SELinux: Abstract use of file security blob
+    - Smack: Abstract use of file security blob
+    - LSM: Infrastructure management of the file security
+    - SELinux: Abstract use of inode security blob
+    - Smack: Abstract use of inode security blob
+    - LSM: Infrastructure management of the inode security
+    - LSM: Infrastructure management of the task security
+    - SELinux: Abstract use of ipc security blobs
+    - Smack: Abstract use of ipc security blobs
+    - LSM: Infrastructure management of the ipc security blob
+    - TOMOYO: Update LSM flags to no longer be exclusive
+    - LSM: generalize flag passing to security_capable
+    - LSM: Make lsm_early_cred() and lsm_early_task() local functions.
+    - LSM: Make some functions static
+    - apparmor: Adjust offset when accessing task blob.
+    - LSM: Ignore "security=" when "lsm=" is specified
+    - LSM: Update list of SECURITYFS users in Kconfig
+    - apparmor: delete the dentry in aafs_remove() to avoid a leak
+    - apparmor: fix double free when unpack of secmark rules fails
+    - SAUCE: LSM: Infrastructure management of the sock security
+    - SAUCE: LSM: Limit calls to certain module hooks
+    - SAUCE: LSM: Special handling for secctx lsm hooks
+    - SAUCE: LSM: Specify which LSM to display with /proc/self/attr/display
+    - SAUCE: Fix-up af_unix mediation for sock infrastructure management
+    - SAUCE: Revert "apparmor: Fix warning about unused function
+      apparmor_ipv6_postroute"
+    - SAUCE: Revert "apparmor: fix checkpatch error in Parse secmark policy"
+    - SAUCE: Revert "apparmor: add #ifdef checks for secmark filtering"
+    - SAUCE: Revert "apparmor: Allow filtering based on secmark policy"
+    - SAUCE: Revert "apparmor: Parse secmark policy"
+    - SAUCE: Revert "apparmor: Add a wildcard secid"
+    - SAUCE: Revert "apparmor: fix bad debug check in apparmor_secid_to_secctx()"
+    - SAUCE: Revert "apparmor: fixup secid map conversion to using IDR"
+    - SAUCE: Revert "apparmor: Use an IDR to allocate apparmor secids"
+    - SAUCE: Revert "apparmor: Fix memory leak of rule on error exit path"
+    - SAUCE: Revert "apparmor: modify audit rule support to support profile
+      stacks"
+    - SAUCE: Revert "apparmor: Add support for audit rule filtering"
+    - SAUCE: Revert "apparmor: add the ability to get a task's secid"
+    - SAUCE: Revert "apparmor: add support for mapping secids and using secctxes"
+    - SAUCE: apparmor: add proc subdir to attrs
+    - SAUCE: apparmor: add an apparmorfs entry to access current attrs
+    - SAUCE: apparmor: update flags to no longer be exclusive
+    - SAUCE: update configs and annotations for LSM stacking
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_EARLY_PRINTK_USB_XDBC=y
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - [Config] CONFIG_RANDOM_TRUST_CPU=y
+    - [Config] refresh annotations for recent config changes
+    - ubuntu: vbox -- update to 6.0.4-dfsg-7
+    - Revert "UBUNTU: SAUCE: i2c:amd I2C Driver based on PCI Interface for
+      upcoming platform"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 04 Apr 2019 14:49:59 -0500
+
+linux (5.0.0-8.9) disco; urgency=medium
+
+  * linux: 5.0.0-8.9 -proposed tracker (LP: #1819759)
+
+  * hisi_sas: add debugfs support (LP: #1819500)
+    - scsi: hisi_sas: Create root and device debugfs directories
+    - scsi: hisi_sas: Alloc debugfs snapshot buffer memory for all registers
+    - scsi: hisi_sas: Take debugfs snapshot for all regs
+    - scsi: hisi_sas: Debugfs global register create file and add file operations
+    - scsi: hisi_sas: Add debugfs for port registers
+    - scsi: hisi_sas: Add debugfs CQ file and add file operations
+    - scsi: hisi_sas: Add debugfs DQ file and add file operations
+    - scsi: hisi_sas: Add debugfs IOST file and add file operations
+    - scsi: hisi_sas: No need to check return value of debugfs_create functions
+    - scsi: hisi_sas: Fix type casting and missing static qualifier in debugfs
+      code
+    - scsi: hisi_sas: Add debugfs ITCT file and add file operations
+
+  * [disco] hns driver updates from 5.1 merge window (LP: #1819535)
+    - net: hns: Use struct_size() in devm_kzalloc()
+    - net: hns3: modify enet reinitialization interface
+    - net: hns3: remove unused member in struct hns3_enet_ring
+    - net: hns3: remove unnecessary hns3_adjust_tqps_num
+    - net: hns3: reuse reinitialization interface in the hns3_set_channels
+    - net: hns3: add interface hclge_tm_bp_setup
+    - net: hns3: modify parameter checks in the hns3_set_channels
+    - net: hns3: remove redundant codes in hclge_knic_setup
+    - net: hns3: fix user configuration loss for ethtool -L
+    - net: hns3: adjust the use of alloc_tqps and num_tqps
+    - net: hns3: fix wrong combined count returned by ethtool -l
+    - net: hns3: do reinitialization while ETS configuration changed
+    - net: hns3: add HNAE3_RESTORE_CLIENT interface in enet module
+    - net: hns3: add calling roce callback function when link status change
+    - net: hns3: add rx multicast packets statistic
+    - net: hns3: refactor the statistics updating for netdev
+    - net: hns3: fix rss configuration lost problem when setting channel
+    - net: hns3: fix for shaper not setting when TC num changes
+    - net: hns3: fix bug of ethtool_ops.get_channels for VF
+    - net: hns3: clear param in ring when free ring
+    - net: hns3: Change fw error code NOT_EXEC to NOT_SUPPORTED
+    - net: hns3: do not return GE PFC setting err when initializing
+    - net: hns3: add ETS TC weight setting in SSU module
+    - net: hns3: add statistics for PFC frames and MAC control frames
+    - net: hns3: fix PFC not setting problem for DCB module
+    - net: hns3: don't update packet statistics for packets dropped by hardware
+    - net: hns3: clear pci private data when unload hns3 driver
+    - net: hns3: add error handling in hclge_ieee_setets
+    - net: hns3: fix return value handle issue for hclge_set_loopback()
+    - net: hns3: fix broadcast promisc issue for revision 0x20
+    - net: hns3: After setting the loopback, add the status of getting MAC
+    - net: hns3: do reinitialization while mqprio configuration changed
+    - net: hns3: remove dcb_ops->map_update in hclge_dcb
+    - net: hns3: call hns3_nic_set_real_num_queue with netdev down
+    - net: hns3: add 8 BD limit for tx flow
+    - net: hns3: add initialization for nic state
+    - net: hns3: don't allow vf to enable promisc mode
+    - net: hns3: reuse the definition of l3 and l4 header info union
+    - net: hns3: fix VF dump register issue
+    - net: hns3: use the correct interface to stop|open port
+    - net: hns3: change hnae3_register_ae_dev() to int
+    - net: hns3: only support tc 0 for VF
+    - net: hns3: Fix NULL deref when unloading driver
+    - net: hns3: fix netif_napi_del() not do problem when unloading
+    - net: hns3: fix for rss result nonuniform
+    - net: hns3: fix improper error handling in the hclge_init_ae_dev()
+    - net: hns3: fix an issue for hclgevf_ae_get_hdev
+    - net: hns3: stop sending keep alive msg to PF when VF is resetting
+    - net: hns3: keep flow director state unchanged when reset
+    - net: hns3: Check for allocation failure
+    - net: hns3: fix a code style issue for hns3_update_new_int_gl()
+    - net: hns3: fix an issue for hns3_update_new_int_gl
+    - net: hns3: Modify parameter type from int to bool in set_gro_en
+    - net: hns3: code optimization for hclge_rx_buffer_calc
+    - net: hns3: add hclge_cmd_check_retval() to parse comman's return value
+    - net: hns3: move some set_bit statement into hclge_prepare_mac_addr
+    - net: hns3: fix a wrong checking in the hclge_tx_buffer_calc()
+    - net: hns3: fix the problem that the supported port is empty
+    - net: hns3: optimize the maximum TC macro
+    - net: hns3: don't allow user to change vlan filter state
+    - net: hns3: modify the upper limit judgment condition
+    - net: hns3: MAC table entry count function increases operation 0 value
+      protection measures
+    - net: hns3: make function hclge_set_all_vf_rst() static
+    - net: hns3: add pointer checking at the beginning of the exported functions.
+    - net: hns3: Check variable is valid before assigning it to another
+    - net: hns3: convert mac advertize and supported from u32 to link mode
+    - net: hns3: fix port info query issue for copper port
+    - net: hns3: modify print message of ssu common ecc errors
+    - net: hns3: some bugfix of ppu(rcb) ras errors
+    - net: hns3: enable 8~11th bit of mac common msi-x error
+    - net: hns3: fix 6th bit of ppp mpf abnormal errors
+    - net: hns3: Record VF unicast and multicast tables
+    - net: hns3: Record VF vlan tables
+    - net: hns3: uninitialize command queue while unloading PF driver
+    - net: hns3: clear command queue's registers when unloading VF driver
+    - net: hns3: add xps setting support for hns3 driver
+    - net: hns3: avoid mult + div op in critical data path
+    - net: hns3: limit some variable scope in critical data path
+    - net: hns3: remove some ops in struct hns3_nic_ops
+    - net: hns3: add unlikely for error handling in data path
+    - net: hns3: replace hnae3_set_bit and hnae3_set_field in data path
+    - net: hns3: remove hnae3_get_bit in data path
+    - net: hns3: add support to config depth for tx|rx ring separately
+    - net: hns3: enable VF VLAN filter for each VF when initializing
+    - net: hns3: fix get VF RSS issue
+    - net: hns3: fix setting of the hns reset_type for rdma hw errors
+    - net: hns3: fix improper error handling for hns3_client_start
+    - net: hns: use struct_size() in devm_kzalloc()
+    - net: hns3: Fix a logical vs bitwise typo
+    - net: hns3: add dma_rmb() for rx description
+    - net: hns3: fix to stop multiple HNS reset due to the AER changes
+
+  * Build Nvidia drivers in conjunction with kernel (LP: #1764792)
+    - [Packaging] dkms-build -- support building against packages in PPAs
+    - [Packaging] dkms-build: do not redownload files on subsequent passes
+    - [Packaging] dkms-build -- elide partial Built-Using information
+    - [Packaging] dkms-build -- remove retpoline data from final binary packages
+    - [Packaging] dkms-build--nvidia* -- check gcc version against primary build
+    - [Packaging] dkms-build -- add support for unversioned overrides
+    - [Packaging] dkms-build--nvidia-* -- convert to generic -N form
+    - [Packaging] fix-filenames -- handle exact string removal
+    - [Packaging] dkms-build--nvidia-N -- remove GCC versions
+
+  * Disco update: v5.0.1 upstream stable release (LP: #1819515)
+    - cpufreq: Use struct kobj_attribute instead of struct global_attr
+    - staging: erofs: fix mis-acted TAIL merging behavior
+    - binder: create node flag to request sender's security context
+    - USB: serial: option: add Telit ME910 ECM composition
+    - USB: serial: cp210x: add ID for Ingenico 3070
+    - USB: serial: ftdi_sio: add ID for Hjelmslund Electronics USB485
+    - driver core: Postpone DMA tear-down until after devres release
+    - staging: erofs: fix fast symlink w/o xattr when fs xattr is on
+    - staging: erofs: fix memleak of inode's shared xattr array
+    - staging: erofs: fix race of initializing xattrs of a inode at the same time
+    - staging: erofs: fix illegal address access under memory pressure
+    - staging: comedi: ni_660x: fix missing break in switch statement
+    - staging: wilc1000: fix to set correct value for 'vif_num'
+    - staging: android: ion: fix sys heap pool's gfp_flags
+    - staging: android: ashmem: Don't call fallocate() with ashmem_mutex held.
+    - staging: android: ashmem: Avoid range_alloc() allocation with ashmem_mutex
+      held.
+    - ip6mr: Do not call __IP6_INC_STATS() from preemptible context
+    - net: dsa: mv88e6xxx: add call to mv88e6xxx_ports_cmode_init to probe for new
+      DSA framework
+    - net: dsa: mv88e6xxx: handle unknown duplex modes gracefully in
+      mv88e6xxx_port_set_duplex
+    - net: dsa: mv8e6xxx: fix number of internal PHYs for 88E6x90 family
+    - net: mscc: Enable all ports in QSGMII
+    - net: sched: put back q.qlen into a single location
+    - net-sysfs: Fix mem leak in netdev_register_kobject
+    - qmi_wwan: Add support for Quectel EG12/EM12
+    - sctp: call iov_iter_revert() after sending ABORT
+    - team: Free BPF filter when unregistering netdev
+    - tipc: fix RDM/DGRAM connect() regression
+    - x86/CPU/AMD: Set the CPB bit unconditionally on F17h
+    - x86/boot/compressed/64: Do not read legacy ROM on EFI system
+    - tracing: Fix event filters and triggers to handle negative numbers
+    - xhci: tegra: Prevent error pointer dereference
+    - usb: xhci: Fix for Enabling USB ROLE SWITCH QUIRK on
+      INTEL_SUNRISEPOINT_LP_XHCI
+    - applicom: Fix potential Spectre v1 vulnerabilities
+    - alpha: wire up io_pgetevents system call
+    - MIPS: irq: Allocate accurate order pages for irq stack
+    - aio: Fix locking in aio_poll()
+    - xtensa: fix get_wchan
+    - gnss: sirf: fix premature wakeup interrupt enable
+    - USB: serial: cp210x: fix GPIO in autosuspend
+    - Revert "selftests: firmware: add CONFIG_FW_LOADER_USER_HELPER_FALLBACK to
+      config"
+    - Revert "selftests: firmware: remove use of non-standard diff -Z option"
+    - selftests: firmware: fix verify_reqs() return value
+    - Bluetooth: btrtl: Restore old logic to assume firmware is already loaded
+    - Bluetooth: Fix locking in bt_accept_enqueue() for BH context
+    - Linux 5.0.1
+
+  * sky2 ethernet card doesn't work after returning from suspend
+    (LP: #1807259) // sky2 ethernet card link not up after suspend
+    (LP: #1809843) // Disco update: v5.0.1 upstream stable release
+    (LP: #1819515)
+    - sky2: Disable MSI on Dell Inspiron 1545 and Gateway P-79
+
+  * tls selftest failures/hangs on i386 (LP: #1813607)
+    - [Config] CONFIG_TLS=n for i386
+
+  * CVE-2019-8980
+    - exec: Fix mem leak in kernel_read_file
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: net: Use 'ipproto ipv6-icmp' to match ICMPv6 headers
+    - [Config] enable nvidia build
+    - [Config] update gcc version to 8.3
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: selftests: pmtu: disable accept_dad for tests"
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Tue, 12 Mar 2019 16:15:44 -0300
+
+linux (5.0.0-7.8) disco; urgency=medium
+
+  * linux: 5.0.0-7.8 -proposed tracker (LP: #1818519)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * unnecessary request_queue freeze (LP: #1815733)
+    - block: avoid setting nr_requests to current value
+    - block: avoid setting none scheduler if it's already none
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: net: Don't fail test_vxlan_under_vrf on xfail
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 04 Mar 2019 08:46:10 -0600
+
+linux (5.0.0-6.7) disco; urgency=medium
+
+  * linux: 5.0.0-6.7 -proposed tracker (LP: #1817585)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - [Packaging] resync getabis
+
+  * installer does not support iSCSI iBFT (LP: #1817321)
+    - d-i: add iscsi_ibft to scsi-modules
+
+  * Silent "Unknown key" message when pressing keyboard backlight hotkey
+    (LP: #1817063)
+    - platform/x86: dell-wmi: Ignore new keyboard backlight change event
+
+  * Fix I219 doesn't get woken up after plugging ethernet cable (LP: #1817058)
+    - e1000e: Disable runtime PM on CNP+
+
+  * efi/arm/arm64: Allow SetVirtualAddressMap() to be omitted (LP: #1814982)
+    - efi/arm/arm64: Allow SetVirtualAddressMap() to be omitted
+
+  * CVE-2019-3460
+    - Bluetooth: Check L2CAP option sizes returned from l2cap_get_conf_opt
+
+  * CVE-2019-3459
+    - Bluetooth: Verify that l2cap_get_conf_opt provides large enough buffer
+
+  * kernel net tls selftest fails on 5.0 (LP: #1816716)
+    - SAUCE: Revert "selftests/tls: Add test for recv(PEEK) spanning across
+      multiple records"
+
+  * Please enable CONFIG_DMA_CMA=y on arm64 (LP: #1803206)
+    - [Config] annotations -- enforce CONFIG_DMA_CMA and update notes
+
+  * [19.04 FEAT] [LS1801] PCI Virtual function enablement (LP: #1814684)
+    - s390/pci: map IOV resources
+    - s390/pci: improve bar check
+
+  * glibc 2.28-0ubuntu1 ADT test failure with linux 5.0.0-1.2 (LP: #1813060)
+    - SAUCE: prevent a glibc test failure when looking for obsolete types on
+      headers
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Enforce CONFIG_ZCRYPT_MULTIDEVNODES in annotations
+    - SAUCE: selftests: pmtu: disable accept_dad for tests
+    - SAUCE: arm64: add kernel config option to lock down when in Secure Boot mode
+    - SAUCE: selftests: net: Make test for VXLAN underlay in non-default VRF an
+      expected failure
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 25 Feb 2019 09:37:36 -0600
+
+linux (5.0.0-5.6) disco; urgency=medium
+
+  * [ALSA] [PATCH] System76 darp5 and oryp5 fixups (LP: #1815831)
+    - ALSA: hda/realtek - Headset microphone and internal speaker support for
+      System76 oryp5
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Fix aufs menus in annotations file
+    - [Config] CONFIG_SAMPLE_TRACE_PRINTK=m
+    - [Config] Update annotations based on configs
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 18 Feb 2019 10:04:11 +0100
+
+linux (5.0.0-4.5) disco; urgency=medium
+
+  * linux-buildinfo: pull out ABI information into its own package
+    (LP: #1806380)
+    - [Packaging] autoreconstruct -- base tag is always primary mainline version
+
+  * [Packaging] Allow overlay of config annotations (LP: #1752072)
+    - [Packaging] config-check: Add an include directive
+
+  * Miscellaneous Ubuntu changes
+    - hio -- stub out BIOVEC_PHYS_MERGEABLE for 4.20+
+    - hio -- replace use of do_gettimeofday()
+    - hio -- part_round_stats() removed in 5.0
+    - hio -- device_add_disk() grew a 'groups' argument in 4.20
+    - enable hio build
+    - Revert "UBUNTU: [Packaging] autoreconstruct -- base tag is always primary
+      mainline version"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 12 Feb 2019 08:15:32 -0600
+
+linux (5.0.0-3.4) disco; urgency=medium
+
+  * CONFIG_TEST_BPF is disabled (LP: #1813955)
+    - [Config]: Reenable TEST_BPF
+
+  * Ignore "incomplete report" from Elan touchpanels (LP: #1813733)
+    - HID: i2c-hid: Ignore input report if there's no data present on Elan
+      touchpanels
+
+  * SecureBoot support for arm64 (LP: #1804481)
+    - Build signed kernels for arm64
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: net: fix "from" match test in fib_rule_tests.sh
+    - [Config] CONFIG_PCMCIA=n for arm64 and s390x
+    - [Config] CONFIG_SERIAL_SC16IS7XX=n for s390x
+    - [Config] disable I2C TPM drivers for s390x
+    - [Config] CONFIG_RAPIDIO=n for s390x
+    - [Config] CONFIG_DMADEVICES=n for s390x
+    - [Config] disable gpio drivers for s390x
+    - [Config] CONFIG_SENSORS_OCC_P8_I2C=m for ppc64el
+    - [Config] disable I2C hardware drivers for s390x
+    - [Config] CONFIG_I3C=n for s390x
+    - [Config] CONFIG_SERIO=n for s390x
+    - [Config] disable misc drivers for s390x
+    - [Config] disable EEPROM drivers for s390x
+    - [Config] disable MFD drivers for s390x
+    - [Config] CONFIG_NVMEM=n for s390x
+    - [Config] CONFIG_MLXSW_I2C=n for s390x
+    - [Config] CONFIG_NET_VENDOR_MICROCHIP=n for s390x
+    - [Config] CONFIG_PPP=n for s390x
+    - [Config] CONFIG_PCCARD=n for s390x
+    - [Config] CONFIG_PCI_MESON=y
+    - [Config] CONFIG_SCSI_MYRB=n for s390x
+    - [Config] CONFIG_REGULATOR=n for s390x
+    - [Config] CONFIG_ZIIRAVE_WATCHDOG=n for s390x
+    - [Config] CONFIG_NCSI_OEM_CMD_GET_MAC=y
+    - [Config] update annotations following config review
+    - [Packaging] remove handoff check for uefi signing
+    - [Packaging] decompress gzipped efi images in signing tarball
+    - vbox-update: allow leading whitespace when fixing up KERN_DIR
+    - ubuntu: vbox -- update to 6.0.4-dfsg-3
+    - vbox: remove remount check in sf_read_super_aux()
+    - enable vbox build
+    - [Config] CONFIG_ANDROID_BINDER_DEVICES=""
+    - SAUCE: import aufs driver
+    - [Config]: Enable aufs
+    - [Config] relocate aufs annotations to menu
+    - [Config] remove unmatched configs from annotations
+    - [Config] fix up abi for removed modules
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) module: remove support for having IMA validate modules
+    - SAUCE: (efi-lockdown) Move EFI signature blob parser to shared location
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - [Config] (efi-lockdown) enable importing of efi certificates for module sig
+      verification
+
+  * Miscellaneous upstream changes
+    - binder: fix CONFIG_ANDROID_BINDER_DEVICES
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 05 Feb 2019 14:26:12 -0600
+
+linux (5.0.0-2.3) disco; urgency=medium
+
+  * kernel oops in bcache module (LP: #1793901)
+    - SAUCE: bcache: never writeback a discard operation
+
+  * Enable sound card power saving by default (LP: #1804265)
+    - [Config] CONFIG_SND_HDA_POWER_SAVE_DEFAULT=1
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: selftests: disable some failing networking tests"
+    - SAUCE: ashmem: turn into module
+    - SAUCE: binder: turn into module
+    - SAUCE: binder: give binder_alloc its own debug mask file
+    - [Config] enable binder and ashmem as modules
+    - SAUCE: selftests: net: replace AF_MAX with INT_MAX in socket.c
+    - SAUCE: selftests/ftrace: Fix tab expansion in trace_marker snapshot trigger
+      test
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 29 Jan 2019 06:57:32 -0600
+
+linux (5.0.0-1.2) disco; urgency=medium
+
+  * Fix non-working QCA Rome Bluetooth after S3 (LP: #1812812)
+    - USB: Add new USB LPM helpers
+    - USB: Consolidate LPM checks to avoid enabling LPM twice
+
+  * bluetooth controller not detected with 4.15 kernel (LP: #1810797)
+    - SAUCE: btqcomsmd: introduce BT_QCOMSMD_HACK
+    - [Config] arm64: snapdragon: BT_QCOMSMD_HACK=y
+
+  * [19.04 FEAT| Enable virtio-gpu for s390x (LP: #1799467)
+    - [Config] enable virtio-gpu for s390x
+
+  * Crash on "ip link add foo type ipip" (LP: #1811803)
+    - SAUCE: fan: Fix NULL pointer dereference
+
+  * Fix not working Goodix touchpad (LP: #1811929)
+    - HID: i2c-hid: Disable runtime PM on Goodix touchpad
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - enable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 22 Jan 2019 13:56:17 -0600
+
+linux (5.0.0-0.1) disco; urgency=medium
+
+  * Build Nvidia drivers in conjunction with kernel (LP: #1764792)
+    - [Packaging] dkms -- add per package post-process step
+    - [Packaging] dkms -- switch to a consistent build prefix length and strip
+    - [Packaging] nvidia -- build and sign nvidia packages and ship signatures
+    - [Packaging] nvidia -- make nvidia package version explicit
+
+  * Add support for ALC3277 codec on new Dell edge gateways (LP: #1807334)
+    - [Config] CONFIG_SND_SOC_INTEL_KBL_RT5660_MACH=m
+
+  * RTL8822BE WiFi Disabled in Kernel 4.18.0-12 (LP: #1806472)
+    - [Config] CONFIG_RTLWIFI_DEBUG_ST=n
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu -- disable vbox build
+    - ubuntu -- disable hio build
+    - Disable zfs build
+    - SAUCE: import aufs driver
+    - update dkms package versions
+    - [Config] disable aufs config options
+    - [Config] disable nvidia build
+    - update dropped.txt
+    - [Packaging] disable nvidia dkms builds for mainline
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation
+      defined
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - [Config] set config options for efi lockdown
+    - Revert "UBUNTU: SAUCE: import aufs driver"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 17 Jan 2019 12:31:29 -0600
+
+linux (5.0.0-0.0) disco; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 16 Jan 2019 14:48:05 -0600
+
+linux (4.20.0-2.3) disco; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.20
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 03 Jan 2019 12:11:43 -0600
+
+linux (4.20.0-1.2) disco; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Power leakage at S5 with Qualcomm Atheros QCA9377 802.11ac Wireless Network
+    Adapter (LP: #1805607)
+    - SAUCE: ath10k: provide reset function for QCA9377 chip
+
+  * zfs/spl build in conjunction with the kernel from DKMS source (LP: #1807378)
+    - [Packaging] dkms -- dkms package build packaging support
+    - [Packaging] dkms -- save build objects artifacts for validation
+    - [Packaging] dkms -- add general Built-Using: support
+    - [Packaging] simplify Provides comma handling
+    - [Packaging] zfs/spl -- remove packaging support for incorporated source
+    - [Packaging] zfs/spl -- remove incorporated source
+    - [Packaging] zfs/spl -- build via dkms
+    - [Packaging] zfs/spl -- make zfs package version explicit
+    - [Packaging] update-version-dkms -- sync archive versions to package
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] update-version-dkms -- fix getting distrbution from changelog
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.20-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 11 Dec 2018 11:33:08 -0600
+
+linux (4.20.0-0.1) disco; urgency=medium
+
+  * Overlayfs in user namespace leaks directory content of inaccessible
+    directories (LP: #1793458) // CVE-2018-6559
+    - Revert "ovl: relax permission checking on underlying layers"
+    - SAUCE: overlayfs: ensure mounter privileges when reading directories
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) efi: Add EFI signature data types
+    - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) Fix for module sig verification
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: Import aufs driver
+    - ubuntu: vbox -- update to 5.2.22-dfsg-2
+    - ubuntu -- disable vbox build
+    - ubuntu -- disable hio build
+    - Disable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.20-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 07 Dec 2018 07:13:42 -0600
+
+linux (4.20.0-0.0) disco; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 06 Dec 2018 10:20:19 -0600
+
+linux (4.19.0-8.9) disco; urgency=medium
+
+  * linux: 4.19.0-8.9 -proposed tracker (LP: #1806952)
+
+  * Workaround CSS timeout on AMD SNPS 3.0 xHC (LP: #1806838)
+    - xhci: workaround CSS timeout on AMD SNPS 3.0 xHC
+
+  * Fix Intel I210 doesn't work when ethernet cable gets plugged (LP: #1806818)
+    - igb: Fix an issue that PME is not enabled during runtime suspend
+
+  * The line-out on the Dell Dock station can't work (LP: #1806532)
+    - ALSA: usb-audio: Add vendor and product name for Dell WD19 Dock
+
+  * CVE-2018-19407
+    - KVM: X86: Fix scan ioapic use-before-initialization
+
+  * PC SN720 NVMe WDC 256GB consumes more power in S2Idle than during long idle
+    (LP: #1805775)
+    - SAUCE: pci/nvme: prevent WDC PC SN720 NVMe from entering D3 and being
+      disabled
+
+  * Disco update: 4.19.6 upstream stable release (LP: #1806909)
+    - HID: steam: remove input device when a hid client is running.
+    - efi/libstub: arm: support building with clang
+    - usb: core: Fix hub port connection events lost
+    - usb: dwc3: gadget: fix ISOC TRB type on unaligned transfers
+    - usb: dwc3: gadget: Properly check last unaligned/zero chain TRB
+    - usb: dwc3: core: Clean up ULPI device
+    - usb: dwc3: Fix NULL pointer exception in dwc3_pci_remove()
+    - xhci: Fix leaking USB3 shared_hcd at xhci removal
+    - xhci: handle port status events for removed USB3 hcd
+    - xhci: Add check for invalid byte size error when UAS devices are connected.
+    - usb: xhci: fix uninitialized completion when USB3 port got wrong status
+    - usb: xhci: fix timeout for transition from RExit to U0
+    - xhci: Add quirk to workaround the errata seen on Cavium Thunder-X2 Soc
+    - usb: xhci: Prevent bus suspend if a port connect change or polling state is
+      detected
+    - ALSA: oss: Use kvzalloc() for local buffer allocations
+    - MAINTAINERS: Add Sasha as a stable branch maintainer
+    - Documentation/security-bugs: Clarify treatment of embargoed information
+    - Documentation/security-bugs: Postpone fix publication in exceptional cases
+    - mmc: sdhci-pci: Try "cd" for card-detect lookup before using NULL
+    - mmc: sdhci-pci: Workaround GLK firmware failing to restore the tuning value
+    - gpio: don't free unallocated ida on gpiochip_add_data_with_key() error path
+    - iwlwifi: fix wrong WGDS_WIFI_DATA_SIZE
+    - iwlwifi: mvm: support sta_statistics() even on older firmware
+    - iwlwifi: mvm: fix regulatory domain update when the firmware starts
+    - iwlwifi: mvm: don't use SAR Geo if basic SAR is not used
+    - brcmfmac: fix reporting support for 160 MHz channels
+    - opp: ti-opp-supply: Dynamically update u_volt_min
+    - opp: ti-opp-supply: Correct the supply in _get_optimal_vdd_voltage call
+    - tools/power/cpupower: fix compilation with STATIC=true
+    - v9fs_dir_readdir: fix double-free on p9stat_read error
+    - selinux: Add __GFP_NOWARN to allocation at str_read()
+    - Input: synaptics - avoid using uninitialized variable when probing
+    - bfs: add sanity check at bfs_fill_super()
+    - sctp: clear the transport of some out_chunk_list chunks in
+      sctp_assoc_rm_peer
+    - gfs2: Don't leave s_fs_info pointing to freed memory in init_sbd
+    - llc: do not use sk_eat_skb()
+    - mm: don't warn about large allocations for slab
+    - mm/memory.c: recheck page table entry with page table lock held
+    - tcp: do not release socket ownership in tcp_close()
+    - drm/fb-helper: Blacklist writeback when adding connectors to fbdev
+    - drm/amdgpu: Add missing firmware entry for HAINAN
+    - drm/vc4: Set ->legacy_cursor_update to false when doing non-async updates
+    - drm/amdgpu: Fix oops when pp_funcs->switch_power_profile is unset
+    - drm/i915: Disable LP3 watermarks on all SNB machines
+    - drm/ast: change resolution may cause screen blurred
+    - drm/ast: fixed cursor may disappear sometimes
+    - drm/ast: Remove existing framebuffers before loading driver
+    - can: flexcan: Unlock the MB unconditionally
+    - can: dev: can_get_echo_skb(): factor out non sending code to
+      __can_get_echo_skb()
+    - can: dev: __can_get_echo_skb(): replace struct can_frame by canfd_frame to
+      access frame length
+    - can: dev: __can_get_echo_skb(): Don't crash the kernel if can_priv::echo_skb
+      is accessed out of bounds
+    - can: dev: __can_get_echo_skb(): print error message, if trying to echo non
+      existing skb
+    - can: rx-offload: introduce can_rx_offload_get_echo_skb() and
+      can_rx_offload_queue_sorted() functions
+    - can: rx-offload: rename can_rx_offload_irq_queue_err_skb() to
+      can_rx_offload_queue_tail()
+    - can: flexcan: use can_rx_offload_queue_sorted() for flexcan_irq_bus_*()
+    - can: flexcan: handle tx-complete CAN frames via rx-offload infrastructure
+    - can: raw: check for CAN FD capable netdev in raw_sendmsg()
+    - can: hi311x: Use level-triggered interrupt
+    - can: flexcan: Always use last mailbox for TX
+    - can: flexcan: remove not needed struct flexcan_priv::tx_mb and struct
+      flexcan_priv::tx_mb_idx
+    - ACPICA: AML interpreter: add region addresses in global list during
+      initialization
+    - IB/hfi1: Eliminate races in the SDMA send error path
+    - fsnotify: generalize handling of extra event flags
+    - fanotify: fix handling of events on child sub-directory
+    - pinctrl: meson: fix pinconf bias disable
+    - pinctrl: meson: fix gxbb ao pull register bits
+    - pinctrl: meson: fix gxl ao pull register bits
+    - pinctrl: meson: fix meson8 ao pull register bits
+    - pinctrl: meson: fix meson8b ao pull register bits
+    - tools/testing/nvdimm: Fix the array size for dimm devices.
+    - scsi: lpfc: fix remoteport access
+    - scsi: hisi_sas: Remove set but not used variable 'dq_list'
+    - KVM: PPC: Move and undef TRACE_INCLUDE_PATH/FILE
+    - cpufreq: imx6q: add return value check for voltage scale
+    - rtc: cmos: Do not export alarm rtc_ops when we do not support alarms
+    - rtc: pcf2127: fix a kmemleak caused in pcf2127_i2c_gather_write
+    - crypto: simd - correctly take reqsize of wrapped skcipher into account
+    - floppy: fix race condition in __floppy_read_block_0()
+    - powerpc/io: Fix the IO workarounds code to work with Radix
+    - sched/fair: Fix cpu_util_wake() for 'execl' type workloads
+    - perf/x86/intel/uncore: Add more IMC PCI IDs for KabyLake and CoffeeLake CPUs
+    - block: copy ioprio in __bio_clone_fast() and bounce
+    - SUNRPC: Fix a bogus get/put in generic_key_to_expire()
+    - riscv: add missing vdso_install target
+    - RISC-V: Silence some module warnings on 32-bit
+    - drm/amdgpu: fix bug with IH ring setup
+    - kdb: Use strscpy with destination buffer size
+    - NFSv4: Fix an Oops during delegation callbacks
+    - powerpc/numa: Suppress "VPHN is not supported" messages
+    - efi/arm: Revert deferred unmap of early memmap mapping
+    - z3fold: fix possible reclaim races
+    - mm, memory_hotplug: check zone_movable in has_unmovable_pages
+    - tmpfs: make lseek(SEEK_DATA/SEK_HOLE) return ENXIO with a negative offset
+    - mm, page_alloc: check for max order in hot path
+    - dax: Avoid losing wakeup in dax_lock_mapping_entry
+    - include/linux/pfn_t.h: force '~' to be parsed as an unary operator
+    - tty: wipe buffer.
+    - tty: wipe buffer if not echoing data
+    - gfs2: Fix iomap buffer head reference counting bug
+    - rcu: Make need_resched() respond to urgent RCU-QS needs
+    - media: ov5640: Re-work MIPI startup sequence
+    - media: ov5640: Fix timings setup code
+    - media: ov5640: fix exposure regression
+    - media: ov5640: fix auto gain & exposure when changing mode
+    - media: ov5640: fix wrong binning value in exposure calculation
+    - media: ov5640: fix auto controls values when switching to manual mode
+    - Linux 4.19.6
+
+  * linux-buildinfo: pull out ABI information into its own package
+    (LP: #1806380)
+    - [Packaging] limit preparation to linux-libc-dev in headers
+    - [Packaging] commonise debhelper invocation
+    - [Packaging] ABI -- accumulate abi information at the end of the build
+    - [Packaging] buildinfo -- add basic build information
+    - [Packaging] buildinfo -- add firmware information to the flavour ABI
+    - [Packaging] buildinfo -- add compiler information to the flavour ABI
+    - [Packaging] buildinfo -- add buildinfo support to getabis
+    - [Packaging] getabis -- handle all known package combinations
+    - [Packaging] getabis -- support parsing a simple version
+
+  * linux packages should own /usr/lib/linux/triggers (LP: #1770256)
+    - [Packaging] own /usr/lib/linux/triggers
+
+  * Miscellaneous upstream changes
+    - blk-mq: fix corruption with direct issue
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 05 Dec 2018 09:18:30 -0600
+
+linux (4.19.0-7.8) disco; urgency=medium
+
+  * linux: 4.19.0-7.8 -proposed tracker (LP: #1805465)
+
+  * Fix and issue that LG I2C touchscreen stops working after reboot
+    (LP: #1805085)
+    - HID: i2c-hid: Disable runtime PM for LG touchscreen
+
+  * click/pop noise in the headphone on several lenovo laptops (LP: #1805079) //
+    click/pop noise in the headphone on several lenovo laptops (LP: #1805079)
+    - ALSA: hda/realtek - fix the pop noise on headphone for lenovo laptops
+
+  * Regression: hinic performance degrades over time (LP: #1805248)
+    - Revert "net-next/hinic: add checksum offload and TSO support"
+
+  * Disco update: 4.19.5 upstream stable release (LP: #1805461)
+    - drm/i915: Replace some PAGE_SIZE with I915_GTT_PAGE_SIZE
+    - cifs: don't dereference smb_file_target before null check
+    - cifs: fix return value for cifs_listxattr
+    - arm64: kprobe: make page to RO mode when allocate it
+    - block: brd: associate with queue until adding disk
+    - net: hns3: bugfix for rtnl_lock's range in the hclgevf_reset()
+    - net: hns3: bugfix for rtnl_lock's range in the hclge_reset()
+    - net: hns3: bugfix for handling mailbox while the command queue reinitialized
+    - net: hns3: bugfix for the initialization of command queue's spin lock
+    - ixgbe: fix MAC anti-spoofing filter after VFLR
+    - reiserfs: propagate errors from fill_with_dentries() properly
+    - hfs: prevent btree data loss on root split
+    - hfsplus: prevent btree data loss on root split
+    - perf unwind: Take pgoff into account when reporting elf to libdwfl
+    - um: Give start_idle_thread() a return code
+    - drm/edid: Add 6 bpc quirk for BOE panel.
+    - afs: Handle EIO from delivery function
+    - platform/x86: intel_telemetry: report debugfs failure
+    - clk: fixed-rate: fix of_node_get-put imbalance
+    - perf symbols: Set PLT entry/header sizes properly on Sparc
+    - fs/exofs: fix potential memory leak in mount option parsing
+    - clk: samsung: exynos5420: Enable PERIS clocks for suspend
+    - apparmor: Fix uninitialized value in aa_split_fqname
+    - x86/earlyprintk: Add a force option for pciserial device
+    - platform/x86: acerhdf: Add BIOS entry for Gateway LT31 v1.3307
+    - clk: meson-axg: pcie: drop the mpll3 clock parent
+    - arm64: percpu: Initialize ret in the default case
+    - clk: meson: clk-pll: drop CLK_GET_RATE_NOCACHE where unnecessary
+    - clk: renesas: r9a06g032: Fix UART34567 clock rate
+    - clk: ti: fix OF child-node lookup
+    - serial: sh-sci: Fix receive on SCIFA/SCIFB variants with DMA
+    - netfilter: ipv6: fix oops when defragmenting locally generated fragments
+    - netfilter: bridge: define INT_MIN & INT_MAX in userspace
+    - s390/decompressor: add missing FORCE to build targets
+    - s390/vdso: add missing FORCE to build targets
+    - HID: i2c-hid: Add a small delay after sleep command for Raydium touchpanel
+    - Revert "HID: add NOGET quirk for Eaton Ellipse MAX UPS"
+    - HID: alps: allow incoming reports when only the trackstick is opened
+    - Revert "netfilter: nft_numgen: add map lookups for numgen random operations"
+    - netfilter: ipset: list:set: Decrease refcount synchronously on deletion and
+      replace
+    - netfilter: ipset: actually allow allowable CIDR 0 in hash:net,port,net
+    - netfilter: ipset: fix ip_set_list allocation failure
+    - s390/mm: fix mis-accounting of pgtable_bytes
+    - s390/mm: Fix ERROR: "__node_distance" undefined!
+    - bpf: fix bpf_prog_get_info_by_fd to return 0 func_lens for unpriv
+    - netfilter: ipset: Correct rcu_dereference() call in ip_set_put_comment()
+    - netfilter: xt_IDLETIMER: add sysfs filename checking routine
+    - netfilter: ipset: Fix calling ip_set() macro at dumping
+    - netfilter: nft_compat: ebtables 'nat' table is normal chain type
+    - s390/qeth: fix HiperSockets sniffer
+    - s390/qeth: unregister netdevice only when registered
+    - net: hns3: Fix for out-of-bounds access when setting pfc back pressure
+    - hwmon: (ibmpowernv) Remove bogus __init annotations
+    - ARM: dts: imx6sll: fix typo for fsl,imx6sll-i2c node
+    - ARM: dts: fsl: Fix improperly quoted stdout-path values
+    - Revert "drm/exynos/decon5433: implement frame counter"
+    - arm64: dts: renesas: r8a7795: add missing dma-names on hscif2
+    - arm64: dts: renesas: condor: switch from EtherAVB to GEther
+    - xen/grant-table: Fix incorrect gnttab_dma_free_pages() pr_debug message
+    - clk: fixed-factor: fix of_node_get-put imbalance
+    - mtd: nand: Fix nanddev_pos_next_page() kernel-doc header
+    - lib/raid6: Fix arm64 test build
+    - drm/amd/display: Stop leaking planes
+    - block: Clear kernel memory before copying to user
+    - drm/amd/display: Drop reusing drm connector for MST
+    - drm/amd/amdgpu/dm: Fix dm_dp_create_fake_mst_encoder()
+    - s390/perf: Change CPUM_CF return code in event init function
+    - ceph: quota: fix null pointer dereference in quota check
+    - of/device: Really only set bus DMA mask when appropriate
+    - nvme: make sure ns head inherits underlying device limits
+    - i2c: omap: Enable for ARCH_K3
+    - i2c: qcom-geni: Fix runtime PM mismatch with child devices
+    - sched/core: Take the hotplug lock in sched_init_smp()
+    - perf tools: Fix undefined symbol scnprintf in libperf-jvmti.so
+    - perf tools: Do not zero sample_id_all for group members
+    - ice: Fix dead device link issue with flow control
+    - ice: Fix the bytecount sent to netdev_tx_sent_queue
+    - ice: Change req_speeds to be u16
+    - i40e: restore NETIF_F_GSO_IPXIP[46] to netdev features
+    - qed: Fix memory/entry leak in qed_init_sp_request()
+    - qed: Fix blocking/unlimited SPQ entries leak
+    - qed: Fix SPQ entries not returned to pool in error flows
+    - qed: Fix potential memory corruption
+    - net: stmmac: Fix RX packet size > 8191
+    - net: aquantia: fix potential IOMMU fault after driver unbind
+    - net: aquantia: fixed enable unicast on 32 macvlan
+    - net: aquantia: invalid checksumm offload implementation
+    - kbuild: deb-pkg: fix too low build version number
+    - Revert "scripts/setlocalversion: git: Make -dirty check more robust"
+    - SUNRPC: drop pointless static qualifier in xdr_get_next_encode_buffer()
+    - x86/mm: Move LDT remap out of KASLR region on 5-level paging
+    - x86/ldt: Unmap PTEs for the slot before freeing LDT pages
+    - x86/ldt: Remove unused variable in map_ldt_struct()
+    - media: v4l: event: Add subscription to list before calling "add" operation
+    - MIPS: OCTEON: cavium_octeon_defconfig: re-enable OCTEON USB driver
+    - RISC-V: Fix raw_copy_{to,from}_user()
+    - uio: Fix an Oops on load
+    - ALSA: hda/realtek - Add quirk entry for HP Pavilion 15
+    - ALSA: hda/ca0132 - Call pci_iounmap() instead of iounmap()
+    - can: kvaser_usb: Fix accessing freed memory in kvaser_usb_start_xmit()
+    - can: kvaser_usb: Fix potential uninitialized variable use
+    - usb: cdc-acm: add entry for Hiro (Conexant) modem
+    - USB: Wait for extra delay time after USB_PORT_FEAT_RESET for quirky hub
+    - usb: quirks: Add delay-init quirk for Corsair K70 LUX RGB
+    - misc: atmel-ssc: Fix section annotation on atmel_ssc_get_driver_data
+    - USB: misc: appledisplay: add 20" Apple Cinema Display
+    - gnss: serial: fix synchronous write timeout
+    - gnss: sirf: fix synchronous write timeout
+    - mtd: rawnand: atmel: fix OF child-node lookup
+    - drivers/misc/sgi-gru: fix Spectre v1 vulnerability
+    - ACPI / platform: Add SMB0001 HID to forbidden_id_list
+    - HID: uhid: forbid UHID_CREATE under KERNEL_DS or elevated privileges
+    - HID: Add quirk for Primax PIXART OEM mice
+    - HID: Add quirk for Microsoft PIXART OEM mouse
+    - libceph: fall back to sendmsg for slab pages
+    - mt76x0: run vco calibration for each channel configuration
+    - Linux 4.19.5
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: Build signed kernels for arm64"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 27 Nov 2018 10:38:34 -0600
+
+linux (4.19.0-6.7) disco; urgency=medium
+
+  * linux: 4.19.0-6.7 -proposed tracker (LP: #1805195)
+
+  * SecureBoot support for arm64 (LP: #1804481)
+    - Build signed kernels for arm64
+
+  * Add pointstick support for Cirque Touchpad (LP: #1805081)
+    - HID: multitouch: Add pointstick support for Cirque Touchpad
+
+  * Power consumption during s2idle is higher than long idle (Intel SSDPEKKF)
+    (LP: #1804588)
+    - SAUCE: pci: prevent Intel NVMe SSDPEKKF from entering D3
+    - SAUCE: nvme: add quirk to not call disable function when suspending
+
+  * Disco update: 4.19.4 upstream stable release (LP: #1805159)
+    - flow_dissector: do not dissect l4 ports for fragments
+    - ibmvnic: fix accelerated VLAN handling
+    - ip_tunnel: don't force DF when MTU is locked
+    - ipv6: fix a dst leak when removing its exception
+    - ipv6: Fix PMTU updates for UDP/raw sockets in presence of VRF
+    - net: bcmgenet: protect stop from timeout
+    - net-gro: reset skb->pkt_type in napi_reuse_skb()
+    - sctp: not allow to set asoc prsctp_enable by sockopt
+    - tcp: Fix SOF_TIMESTAMPING_RX_HARDWARE to use the latest timestamp during TCP
+      coalescing
+    - tg3: Add PHY reset for 5717/5719/5720 in change ring and flow control paths
+    - tipc: don't assume linear buffer when reading ancillary data
+    - tipc: fix lockdep warning when reinitilaizing sockets
+    - tuntap: fix multiqueue rx
+    - net: systemport: Protect stop from timeout
+    - net/sched: act_pedit: fix memory leak when IDR allocation fails
+    - net: sched: cls_flower: validate nested enc_opts_policy to avoid warning
+    - tipc: fix link re-establish failure
+    - net/mlx5e: Don't match on vlan non-existence if ethertype is wildcarded
+    - net/mlx5e: Claim TC hw offloads support only under a proper build config
+    - net/mlx5e: Adjust to max number of channles when re-attaching
+    - net/mlx5e: RX, verify received packet size in Linear Striding RQ
+    - Revert "sctp: remove sctp_transport_pmtu_check"
+    - net/mlx5e: Always use the match level enum when parsing TC rule match
+    - net/mlx5e: Fix selftest for small MTUs
+    - net/mlx5e: Removed unnecessary warnings in FEC caps query
+    - inet: frags: better deal with smp races
+    - l2tp: fix a sock refcnt leak in l2tp_tunnel_register
+    - net/mlx5: IPSec, Fix the SA context hash key
+    - net/mlx5e: IPoIB, Reset QP after channels are closed
+    - net: dsa: mv88e6xxx: Fix clearing of stats counters
+    - net: phy: realtek: fix RTL8201F sysfs name
+    - sctp: define SCTP_SS_DEFAULT for Stream schedulers
+    - net: qualcomm: rmnet: Fix incorrect assignment of real_dev
+    - net: dsa: microchip: initialize mutex before use
+    - sctp: fix strchange_flags name for Stream Change Event
+    - net: phy: mdio-gpio: Fix working over slow can_sleep GPIOs
+    - sctp: not increase stream's incnt before sending addstrm_in request
+    - mlxsw: spectrum: Fix IP2ME CPU policer configuration
+    - net: smsc95xx: Fix MTU range
+    - rxrpc: Fix lockup due to no error backoff after ack transmit error
+    - usbnet: smsc95xx: disable carrier check while suspending
+    - Revert "x86/speculation: Enable cross-hyperthread spectre v2 STIBP
+      mitigation"
+    - Linux 4.19.4
+
+  * Disco update: 4.19.3 upstream stable release (LP: #1805158)
+    - powerpc/traps: restore recoverability of machine_check interrupts
+    - powerpc/64/module: REL32 relocation range check
+    - powerpc/mm: Fix page table dump to work on Radix
+    - powerpc/mm: fix always true/false warning in slice.c
+    - drm/amd/display: fix bug of accessing invalid memory
+    - Input: wm97xx-ts - fix exit path
+    - powerpc/Makefile: Fix PPC_BOOK3S_64 ASFLAGS
+    - powerpc/eeh: Fix possible null deref in eeh_dump_dev_log()
+    - tty: check name length in tty_find_polling_driver()
+    - tracing/kprobes: Check the probe on unloaded module correctly
+    - drm/nouveau/secboot/acr: fix memory leak
+    - drm/amdgpu/powerplay: fix missing break in switch statements
+    - ARM: imx_v6_v7_defconfig: Select CONFIG_TMPFS_POSIX_ACL
+    - powerpc/nohash: fix undefined behaviour when testing page size support
+    - drm/msm/gpu: fix parameters in function msm_gpu_crashstate_capture
+    - drm/msm/disp/dpu: Use proper define for drm_encoder_init() 'encoder_type'
+    - drm/msm: dpu: Allow planes to extend past active display
+    - powerpc/mm: Don't report hugepage tables as memory leaks when using kmemleak
+    - drm/omap: fix memory barrier bug in DMM driver
+    - drm/amd/display: Raise dispclk value for dce120 by 15%
+    - drm/amd/display: fix gamma not being applied
+    - drm/hisilicon: hibmc: Do not carry error code in HiBMC framebuffer pointer
+    - media: pci: cx23885: handle adding to list failure
+    - media: coda: don't overwrite h.264 profile_idc on decoder instance
+    - MIPS: kexec: Mark CPU offline before disabling local IRQ
+    - powerpc/boot: Ensure _zimage_start is a weak symbol
+    - powerpc/memtrace: Remove memory in chunks
+    - MIPS/PCI: Call pcie_bus_configure_settings() to set MPS/MRRS
+    - staging: erofs: fix a missing endian conversion
+    - serial: 8250_of: Fix for lack of interrupt support
+    - sc16is7xx: Fix for multi-channel stall
+    - media: tvp5150: fix width alignment during set_selection()
+    - powerpc/selftests: Wait all threads to join
+    - staging:iio:ad7606: fix voltage scales
+    - drm: rcar-du: Update Gen3 output limitations
+    - drm/amdgpu: Fix SDMA TO after GPU reset v3
+    - staging: most: video: fix registration of an empty comp core_component
+    - 9p locks: fix glock.client_id leak in do_lock
+    - udf: Prevent write-unsupported filesystem to be remounted read-write
+    - ARM: dts: imx6ull: keep IMX6UL_ prefix for signals on both i.MX6UL and
+      i.MX6ULL
+    - media: ov5640: fix mode change regression
+    - 9p: clear dangling pointers in p9stat_free
+    - drm/amdgpu: fix integer overflow test in amdgpu_bo_list_create()
+    - media: ov5640: fix restore of last mode set
+    - cdrom: fix improper type cast, which can leat to information leak.
+    - ovl: fix error handling in ovl_verify_set_fh()
+    - ovl: fix recursive oi->lock in ovl_link()
+    - ovl: check whiteout in ovl_create_over_whiteout()
+    - ovl: automatically enable redirect_dir on metacopy=on
+    - serial: sh-sci: Fix could not remove dev_attr_rx_fifo_timeout
+    - scsi: qla2xxx: Fix incorrect port speed being set for FC adapters
+    - scsi: qla2xxx: Fix process response queue for ISP26XX and above
+    - scsi: qla2xxx: Remove stale debug trace message from tcm_qla2xxx
+    - scsi: qla2xxx: Fix early srb free on abort
+    - scsi: qla2xxx: shutdown chip if reset fail
+    - scsi: qla2xxx: Reject bsg request if chip is down.
+    - scsi: qla2xxx: Fix re-using LoopID when handle is in use
+    - scsi: qla2xxx: Fix for double free of SRB structure
+    - scsi: qla2xxx: Fix NVMe session hang on unload
+    - scsi: qla2xxx: Fix NVMe Target discovery
+    - scsi: qla2xxx: Fix duplicate switch database entries
+    - scsi: qla2xxx: Fix driver hang when FC-NVMe LUNs are configured
+    - vfs: fix FIGETBSZ ioctl on an overlayfs file
+    - fuse: Fix use-after-free in fuse_dev_do_read()
+    - fuse: Fix use-after-free in fuse_dev_do_write()
+    - fuse: fix blocked_waitq wakeup
+    - fuse: set FR_SENT while locked
+    - drm/msm: fix OF child-node lookup
+    - arm64: dts: stratix10: Support Ethernet Jumbo frame
+    - arm64: dts: stratix10: fix multicast filtering
+    - clk: meson-gxbb: set fclk_div3 as CLK_IS_CRITICAL
+    - clk: meson: axg: mark fdiv2 and fdiv3 as critical
+    - zram: close udev startup race condition as default groups
+    - MIPS: Loongson-3: Fix CPU UART irq delivery problem
+    - MIPS: Loongson-3: Fix BRIDGE irq delivery problem
+    - xtensa: add NOTES section to the linker script
+    - xtensa: make sure bFLT stack is 16 byte aligned
+    - xtensa: fix boot parameters address translation
+    - um: Drop own definition of PTRACE_SYSEMU/_SINGLESTEP
+    - clk: s2mps11: Fix matching when built as module and DT node contains
+      compatible
+    - clk: at91: Fix division by zero in PLL recalc_rate()
+    - clk: sunxi-ng: h6: fix bus clocks' divider position
+    - clk: rockchip: fix wrong mmc sample phase shift for rk3328
+    - clk: rockchip: Fix static checker warning in rockchip_ddrclk_get_parent call
+    - libceph: bump CEPH_MSG_MAX_DATA_LEN
+    - Revert "ceph: fix dentry leak in splice_dentry()"
+    - thermal: core: Fix use-after-free in thermal_cooling_device_destroy_sysfs
+    - mach64: fix display corruption on big endian machines
+    - mach64: fix image corruption due to reading accelerator registers
+    - acpi/nfit, x86/mce: Handle only uncorrectable machine checks
+    - acpi/nfit, x86/mce: Validate a MCE's address before using it
+    - acpi, nfit: Fix ARS overflow continuation
+    - reset: hisilicon: fix potential NULL pointer dereference
+    - crypto: hisilicon - Fix NULL dereference for same dst and src
+    - crypto: hisilicon - Fix reference after free of memories on error path
+    - vhost/scsi: truncate T10 PI iov_iter to prot_bytes
+    - scsi: qla2xxx: Initialize port speed to avoid setting lower speed
+    - SCSI: fix queue cleanup race before queue initialization is done
+    - Revert "powerpc/8xx: Use L1 entry APG to handle _PAGE_ACCESSED for
+      CONFIG_SWAP"
+    - soc: ti: QMSS: Fix usage of irq_set_affinity_hint
+    - ocfs2: fix a misuse a of brelse after failing ocfs2_check_dir_entry
+    - ocfs2: free up write context when direct IO failed
+    - mm: thp: relax __GFP_THISNODE for MADV_HUGEPAGE mappings
+    - memory_hotplug: cond_resched in __remove_pages
+    - netfilter: conntrack: fix calculation of next bucket number in early_drop
+    - ARM: 8809/1: proc-v7: fix Thumb annotation of cpu_v7_hvc_switch_mm
+    - bonding/802.3ad: fix link_failure_count tracking
+    - mtd: spi-nor: cadence-quadspi: Return error code in
+      cqspi_direct_read_execute()
+    - mtd: nand: Fix nanddev_neraseblocks()
+    - mtd: docg3: don't set conflicting BCH_CONST_PARAMS option
+    - hwmon: (core) Fix double-free in __hwmon_device_register()
+    - perf cs-etm: Correct CPU mode for samples
+    - perf stat: Handle different PMU names with common prefix
+    - perf callchain: Honour the ordering of PERF_CONTEXT_{USER,KERNEL,etc}
+    - perf intel-pt/bts: Calculate cpumode for synthesized samples
+    - perf intel-pt: Insert callchain context into synthesized callchains
+    - of, numa: Validate some distance map rules
+    - x86/cpu/vmware: Do not trace vmware_sched_clock()
+    - x86/hyper-v: Enable PIT shutdown quirk
+    - termios, tty/tty_baudrate.c: fix buffer overrun
+    - arch/alpha, termios: implement BOTHER, IBSHIFT and termios2
+    - watchdog/core: Add missing prototypes for weak functions
+    - btrfs: fix pinned underflow after transaction aborted
+    - Btrfs: fix missing data checksums after a ranged fsync (msync)
+    - Btrfs: fix cur_offset in the error case for nocow
+    - Btrfs: fix infinite loop on inode eviction after deduplication of eof block
+    - Btrfs: fix data corruption due to cloning of eof block
+    - btrfs: tree-checker: Fix misleading group system information
+    - clockevents/drivers/i8253: Add support for PIT shutdown quirk
+    - ext4: add missing brelse() update_backups()'s error path
+    - ext4: add missing brelse() in set_flexbg_block_bitmap()'s error path
+    - ext4: add missing brelse() add_new_gdb_meta_bg()'s error path
+    - ext4: avoid potential extra brelse in setup_new_flex_group_blocks()
+    - ext4: missing !bh check in ext4_xattr_inode_write()
+    - ext4: fix possible inode leak in the retry loop of ext4_resize_fs()
+    - ext4: avoid buffer leak on shutdown in ext4_mark_iloc_dirty()
+    - ext4: avoid buffer leak in ext4_orphan_add() after prior errors
+    - ext4: fix missing cleanup if ext4_alloc_flex_bg_array() fails while resizing
+    - ext4: avoid possible double brelse() in add_new_gdb() on error path
+    - ext4: fix possible leak of sbi->s_group_desc_leak in error path
+    - ext4: fix possible leak of s_journal_flag_rwsem in error path
+    - ext4: fix buffer leak in ext4_xattr_get_block() on error path
+    - ext4: release bs.bh before re-using in ext4_xattr_block_find()
+    - ext4: fix buffer leak in ext4_xattr_move_to_block() on error path
+    - ext4: fix buffer leak in ext4_expand_extra_isize_ea() on error path
+    - ext4: fix buffer leak in __ext4_read_dirblock() on error path
+    - mount: Prevent MNT_DETACH from disconnecting locked mounts
+    - mnt: fix __detach_mounts infinite loop
+    - uapi: fix linux/kfd_ioctl.h userspace compilation errors
+    - ARM: cpuidle: Don't register the driver when back-end init returns -ENXIO
+    - kdb: use correct pointer when 'btc' calls 'btt'
+    - kdb: print real address of pointers instead of hashed addresses
+    - sunrpc: correct the computation for page_ptr when truncating
+    - NFSv4: Don't exit the state manager without clearing
+      NFS4CLNT_MANAGER_RUNNING
+    - nfsd: COPY and CLONE operations require the saved filehandle to be set
+    - rtc: hctosys: Add missing range error reporting
+    - fuse: fix use-after-free in fuse_direct_IO()
+    - fuse: fix leaked notify reply
+    - fuse: fix possibly missed wake-up after abort
+    - selinux: check length properly in SCTP bind hook
+    - gfs2: Put bitmap buffers in put_super
+    - gfs2: Fix metadata read-ahead during truncate (2)
+    - libata: blacklist SAMSUNG MZ7TD256HAFV-000L9 SSD
+    - crypto: user - fix leaking uninitialized memory to userspace
+    - lib/ubsan.c: don't mark __ubsan_handle_builtin_unreachable as noreturn
+    - hugetlbfs: fix kernel BUG at fs/hugetlbfs/inode.c:444!
+    - mm/swapfile.c: use kvzalloc for swap_info_struct allocation
+    - efi/arm/libstub: Pack FDT after populating it
+    - mm: don't reclaim inodes with many attached pages
+    - scripts/spdxcheck.py: make python3 compliant
+    - drm/rockchip: Allow driver to be shutdown on reboot/kexec
+    - drm/amdgpu: Fix typo in amdgpu_vmid_mgr_init
+    - drm/amdgpu: add missing CHIP_HAINAN in amdgpu_ucode_get_load_type
+    - drm/amdgpu: Suppress keypresses from ACPI_VIDEO events
+    - drm/nouveau: Check backlight IDs are >= 0, not > 0
+    - drm/nouveau: Fix nv50_mstc->best_encoder()
+    - drm/amd/powerplay: Enable/Disable NBPSTATE on On/OFF of UVD
+    - drm/etnaviv: fix bogus fence complete check in timeout handler
+    - drm/dp_mst: Check if primary mstb is null
+    - drm: panel-orientation-quirks: Add quirk for Acer One 10 (S1003)
+    - drm/i915/dp: Link train Fallback on eDP only if fallback link BW can fit
+      panel's native mode
+    - drm/i915: Use the correct crtc when sanitizing plane mapping
+    - drm/i915: Restore vblank interrupts earlier
+    - drm/i915: Don't unset intel_connector->mst_port
+    - drm/i915: Skip vcpi allocation for MSTB ports that are gone
+    - drm/i915: Large page offsets for pread/pwrite
+    - drm/i915/dp: Fix link retraining comment in intel_dp_long_pulse()
+    - drm/i915/dp: Restrict link retrain workaround to external monitors
+    - drm/i915/icl: Fix the macros for DFLEXDPMLE register bits
+    - drm/i915/hdmi: Add HDMI 2.0 audio clock recovery N values
+    - drm/i915: Mark up GTT sizes as u64
+    - drm/i915: Fix error handling for the NV12 fb dimensions check
+    - drm/i915: Fix ilk+ watermarks when disabling pipes
+    - drm/i915: Compare user's 64b GTT offset even on 32b
+    - drm/i915: Don't oops during modeset shutdown after lpe audio deinit
+    - drm/i915: Mark pin flags as u64
+    - drm/i915/ringbuffer: Delay after EMIT_INVALIDATE for gen4/gen5
+    - drm/i915/execlists: Force write serialisation into context image vs
+      execution
+    - drm/i915: Fix possible race in intel_dp_add_mst_connector()
+    - drm/i915: Fix NULL deref when re-enabling HPD IRQs on systems with MST
+    - drm/i915: Fix hpd handling for pins with two encoders
+    - CONFIG_XEN_PV breaks xen_create_contiguous_region on ARM
+    - Revert "ACPICA: AML interpreter: add region addresses in global list during
+      initialization"
+    - Linux 4.19.3
+
+  * glibc 2.28-0ubuntu1 ADT test failure with linux 4.19.0-5.6 (LP: #1805154)
+    - SAUCE: Revert "x86: vdso: Use $LD instead of $CC to link"
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.12-1ubuntu1, zfs to 0.7.12-1ubuntu1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 26 Nov 2018 11:44:00 -0600
+
+linux (4.19.0-5.6) disco; urgency=medium
+
+  * crash in ENA driver on removing an interface (LP: #1802341)
+    - SAUCE: net: ena: fix crash during ena_remove()
+
+  * Ubuntu 18.04.1 - [s390x] Kernel panic while stressing network bonding
+    (LP: #1797367)
+    - s390/qeth: sanitize strings in debug messages
+
+  * Disco update: 4.19.2 upstream stable release (LP: #1803410)
+    - bpf: fix partial copy of map_ptr when dst is scalar
+    - MIPS: VDSO: Reduce VDSO_RANDOMIZE_SIZE to 64MB for 64bit
+    - gpio: mxs: Get rid of external API call
+    - mtd: rawnand: marvell: fix the IRQ handler complete() condition
+    - mtd: maps: gpio-addr-flash: Fix ioremapped size
+    - mtd: spi-nor: fsl-quadspi: fix read error for flash size larger than 16MB
+    - mtd: spi-nor: intel-spi: Add support for Intel Ice Lake SPI serial flash
+    - mtd: spi-nor: fsl-quadspi: Don't let -EINVAL on the bus
+    - spi: spi-mem: Adjust op len based on message/transfer size limitations
+    - spi: bcm-qspi: switch back to reading flash using smaller chunks
+    - spi: bcm-qspi: fix calculation of address length
+    - bcache: trace missed reading by cache_missed
+    - bcache: fix ioctl in flash device
+    - bcache: correct dirty data statistics
+    - bcache: fix miss key refill->end in writeback
+    - hwmon: (pmbus) Fix page count auto-detection.
+    - jffs2: free jffs2_sb_info through jffs2_kill_sb()
+    - block: setup bounce bio_sets properly
+    - block: make sure discard bio is aligned with logical block size
+    - block: make sure writesame bio is aligned with logical block size
+    - cpufreq: conservative: Take limits changes into account properly
+    - dma-mapping: fix panic caused by passing empty cma command line argument
+    - pcmcia: Implement CLKRUN protocol disabling for Ricoh bridges
+    - ACPI / OSL: Use 'jiffies' as the time bassis for acpi_os_get_timer()
+    - ACPICA: AML interpreter: add region addresses in global list during
+      initialization
+    - ACPICA: AML Parser: fix parse loop to correctly skip erroneous extended
+      opcodes
+    - acpi, nfit: Fix Address Range Scrub completion tracking
+    - kprobes/x86: Use preempt_enable() in optimized_callback()
+    - mailbox: PCC: handle parse error
+    - parisc: Fix address in HPMC IVA
+    - parisc: Fix map_pages() to not overwrite existing pte entries
+    - parisc: Fix exported address of os_hpmc handler
+    - ALSA: hda - Add quirk for ASUS G751 laptop
+    - ALSA: hda - Fix headphone pin config for ASUS G751
+    - ALSA: hda - Add mic quirk for the Lenovo G50-30 (17aa:3905)
+    - ALSA: hda: Add 2 more models to the power_save blacklist
+    - ALSA: ca0106: Disable IZD on SB0570 DAC to fix audio pops
+    - ALSA: hda - Fix incorrect clearance of thinkpad_acpi hooks
+    - x86/speculation: Enable cross-hyperthread spectre v2 STIBP mitigation
+    - x86/xen: Fix boot loader version reported for PVH guests
+    - x86/corruption-check: Fix panic in memory_corruption_check() when boot
+      option without value is provided
+    - x86/kvm/nVMX: allow bare VMXON state migration
+    - x86/mm/pat: Disable preemption around __flush_tlb_all()
+    - x86/numa_emulation: Fix uniform-split numa emulation
+    - ARM: dts: exynos: Disable pull control for MAX8997 interrupts on Origen
+    - net: socionext: Reset tx queue in ndo_stop
+    - net: loopback: clear skb->tstamp before netif_rx()
+    - locking/lockdep: Fix debug_locks off performance problem
+    - netfilter: xt_nat: fix DNAT target for shifted portmap ranges
+    - ataflop: fix error handling during setup
+    - swim: fix cleanup on setup error
+    - arm64: cpufeature: ctr: Fix cpu capability check for late CPUs
+    - hv_netvsc: fix vf serial matching with pci slot info
+    - nfp: devlink port split support for 1x100G CXP NIC
+    - tun: Consistently configure generic netdev params via rtnetlink
+    - s390/sthyi: Fix machine name validity indication
+    - hwmon: (pwm-fan) Set fan speed to 0 on suspend
+    - lightnvm: pblk: fix race on sysfs line state
+    - lightnvm: pblk: fix two sleep-in-atomic-context bugs
+    - lightnvm: pblk: fix race condition on metadata I/O
+    - spi: spi-ep93xx: Use dma_data_direction for ep93xx_spi_dma_{finish,prepare}
+    - perf tools: Free temporary 'sys' string in read_event_files()
+    - perf tools: Cleanup trace-event-info 'tdata' leak
+    - perf tools: Free 'printk' string in parse_ftrace_printk()
+    - perf strbuf: Match va_{add,copy} with va_end
+    - cpupower: Fix coredump on VMWare
+    - bcache: Populate writeback_rate_minimum attribute
+    - mmc: sdhci-pci-o2micro: Add quirk for O2 Micro dev 0x8620 rev 0x01
+    - sdhci: acpi: add free_slot callback
+    - mtd: rawnand: denali: set SPARE_AREA_SKIP_BYTES register to 8 if unset
+    - iwlwifi: pcie: avoid empty free RB queue
+    - iwlwifi: mvm: clear HW_RESTART_REQUESTED when stopping the interface
+    - iwlwifi: mvm: check for n_profiles validity in EWRD ACPI
+    - x86/olpc: Indicate that legacy PC XO-1 platform should not register RTC
+    - wlcore: Fix BUG with clear completion on timeout
+    - ACPI/PPTT: Handle architecturally unknown cache types
+    - ACPI / PM: LPIT: Register sysfs attributes based on FADT
+    - ACPI / processor: Fix the return value of acpi_processor_ids_walk()
+    - cpufreq: dt: Try freeing static OPPs only if we have added them
+    - x86/intel_rdt: Show missing resctrl mount options
+    - mtd: rawnand: atmel: Fix potential NULL pointer dereference
+    - nvme: call nvme_complete_rq when nvmf_check_ready fails for mpath I/O
+    - ath10k: fix tx status flag setting for management frames
+    - signal: Introduce COMPAT_SIGMINSTKSZ for use in compat_sys_sigaltstack
+    - ice: fix changing of ring descriptor size (ethtool -G)
+    - ice: update fw version check logic
+    - net: hns3: Fix for packet buffer setting bug
+    - Bluetooth: btbcm: Add entry for BCM4335C0 UART bluetooth
+    - Bluetooth: hci_qca: Remove hdev dereference in qca_close().
+    - x86: boot: Fix EFI stub alignment
+    - net: hns3: Add nic state check before calling netif_tx_wake_queue
+    - net: hns3: Fix ets validate issue
+    - pinctrl: sunxi: fix 'pctrl->functions' allocation in
+      sunxi_pinctrl_build_state
+    - pinctrl: qcom: spmi-mpp: Fix err handling of pmic_mpp_set_mux
+    - brcmfmac: fix for proper support of 160MHz bandwidth
+    - net: hns3: Check hdev state when getting link status
+    - net: hns3: Set STATE_DOWN bit of hdev state when stopping net
+    - net: phy: phylink: ensure the carrier is off when starting phylink
+    - block, bfq: correctly charge and reset entity service in all cases
+    - arm64: entry: Allow handling of undefined instructions from EL1
+    - kprobes: Return error if we fail to reuse kprobe instead of BUG_ON()
+    - spi: gpio: No MISO does not imply no RX
+    - ACPI / LPSS: Add alternative ACPI HIDs for Cherry Trail DMA controllers
+    - pinctrl: qcom: spmi-mpp: Fix drive strength setting
+    - bpf/verifier: fix verifier instability
+    - failover: Add missing check to validate 'slave_dev' in
+      net_failover_slave_unregister
+    - perf tests: Fix record+probe_libc_inet_pton.sh without ping's debuginfo
+    - pinctrl: spmi-mpp: Fix pmic_mpp_config_get() to be compliant
+    - pinctrl: ssbi-gpio: Fix pm8xxx_pin_config_get() to be compliant
+    - net: hns3: Preserve vlan 0 in hardware table
+    - net: hns3: Fix ping exited problem when doing lp selftest
+    - net: hns3: Fix for vf vlan delete failed problem
+    - net: dsa: mv88e6xxx: Fix writing to a PHY page.
+    - mt76x2u: run device cleanup routine if resume fails
+    - rsi: fix memory alignment issue in ARM32 platforms
+    - libertas_tf: prevent underflow in process_cmdrequest()
+    - iwlwifi: mvm: fix BAR seq ctrl reporting
+    - gpio: brcmstb: allow 0 width GPIO banks
+    - ixgbe: disallow IPsec Tx offload when in SR-IOV mode
+    - ixgbevf: VF2VF TCP RSS
+    - wil6210: fix RX buffers release and unmap
+    - ath10k: schedule hardware restart if WMI command times out
+    - libata: Apply NOLPM quirk for SAMSUNG MZ7TD256HAFV-000L9
+    - thermal: rcar_thermal: Prevent doing work after unbind
+    - thermal: da9062/61: Prevent hardware access during system suspend
+    - cifs: fix a credits leak for compund commands
+    - cgroup, netclassid: add a preemption point to write_classid
+    - net: stmmac: dwmac-sun8i: fix OF child-node lookup
+    - f2fs: fix to account IO correctly for cgroup writeback
+    - MD: Memory leak when flush bio size is zero
+    - md: fix memleak for mempool
+    - of: Add missing exports of node name compare functions
+    - scsi: esp_scsi: Track residual for PIO transfers
+    - scsi: ufs: Schedule clk gating work on correct queue
+    - UAPI: ndctl: Fix g++-unsupported initialisation in headers
+    - KVM: nVMX: Clear reserved bits of #DB exit qualification
+    - scsi: megaraid_sas: fix a missing-check bug
+    - RDMA/core: Do not expose unsupported counters
+    - RDMA/cm: Respect returned status of cm_init_av_by_path
+    - IB/ipoib: Clear IPCB before icmp_send
+    - RDMA/bnxt_re: Avoid accessing nq->bar_reg_iomem in failure case
+    - RDMA/bnxt_re: Fix recursive lock warning in debug kernel
+    - usb: host: ohci-at91: fix request of irq for optional gpio
+    - PCI: mediatek: Fix mtk_pcie_find_port() endpoint/port matching logic
+    - PCI: cadence: Use AXI region 0 to signal interrupts from EP
+    - usb: typec: tcpm: Report back negotiated PPS voltage and current
+    - tpm: suppress transmit cmd error logs when TPM 1.2 is disabled/deactivated
+    - f2fs: clear PageError on the read path
+    - Drivers: hv: vmbus: Use cpumask_var_t for on-stack cpu mask
+    - VMCI: Resource wildcard match fixed
+    - PCI / ACPI: Enable wake automatically for power managed bridges
+    - xprtrdma: Reset credit grant properly after a disconnect
+    - irqchip/pdc: Setup all edge interrupts as rising edge at GIC
+    - usb: dwc2: fix call to vbus supply exit routine, call it unlocked
+    - usb: dwc2: fix a race with external vbus supply
+    - usb: gadget: udc: atmel: handle at91sam9rl PMC
+    - ext4: fix argument checking in EXT4_IOC_MOVE_EXT
+    - MD: fix invalid stored role for a disk
+    - PCI: cadence: Correct probe behaviour when failing to get PHY
+    - nvmem: check the return value of nvmem_add_cells()
+    - xhci: Avoid USB autosuspend when resuming USB2 ports.
+    - scsi: qla2xxx: Fix recursive mailbox timeout
+    - f2fs: fix to recover inode's crtime during POR
+    - f2fs: fix to recover inode's i_flags during POR
+    - PCI/MSI: Warn and return error if driver enables MSI/MSI-X twice
+    - coresight: etb10: Fix handling of perf mode
+    - PCI: dwc: pci-dra7xx: Enable errata i870 for both EP and RC mode
+    - crypto: caam - fix implicit casts in endianness helpers
+    - usb: chipidea: Prevent unbalanced IRQ disable
+    - Smack: ptrace capability use fixes
+    - driver/dma/ioat: Call del_timer_sync() without holding prep_lock
+    - ASoC: AMD: Fix capture unstable in beginning for some runs
+    - firmware: coreboot: Unmap ioregion after device population
+    - IB/ipoib: Use dev_port to expose network interface port numbers
+    - IB/mlx5: Allow transition of DCI QP to reset
+    - uio: ensure class is registered before devices
+    - scsi: lpfc: Correct soft lockup when running mds diagnostics
+    - scsi: lpfc: Correct race with abort on completion path
+    - f2fs: avoid sleeping under spin_lock
+    - f2fs: report error if quota off error during umount
+    - signal: Always deliver the kernel's SIGKILL and SIGSTOP to a pid namespace
+      init
+    - f2fs: fix to flush all dirty inodes recovered in readonly fs
+    - mfd: menelaus: Fix possible race condition and leak
+    - dmaengine: dma-jz4780: Return error if not probed from DT
+    - IB/rxe: fix for duplicate request processing and ack psns
+    - ALSA: hda: Check the non-cached stream buffers more explicitly
+    - cpupower: Fix AMD Family 0x17 msr_pstate size
+    - Revert "f2fs: fix to clear PG_checked flag in set_page_dirty()"
+    - f2fs: fix missing up_read
+    - f2fs: fix to recover cold bit of inode block during POR
+    - f2fs: fix to account IO correctly
+    - OPP: Free OPP table properly on performance state irregularities
+    - ARM: dts: exynos: Convert exynos5250.dtsi to opp-v2 bindings
+    - ARM: dts: exynos: Mark 1 GHz CPU OPP as suspend OPP on Exynos5250
+    - xen-swiotlb: use actually allocated size on check physical continuous
+    - tpm: Restore functionality to xen vtpm driver.
+    - xen/blkfront: avoid NULL blkfront_info dereference on device removal
+    - xen/balloon: Support xend-based toolstack
+    - xen: fix race in xen_qlock_wait()
+    - xen: make xen_qlock_wait() nestable
+    - xen/pvh: increase early stack size
+    - xen/pvh: don't try to unplug emulated devices
+    - libertas: don't set URB_ZERO_PACKET on IN USB transfer
+    - usbip:vudc: BUG kmalloc-2048 (Not tainted): Poison overwritten
+    - usb: typec: tcpm: Fix APDO PPS order checking to be based on voltage
+    - usb: gadget: udc: renesas_usb3: Fix b-device mode for "workaround"
+    - mt76: mt76x2: fix multi-interface beacon configuration
+    - iwlwifi: mvm: check return value of rs_rate_from_ucode_rate()
+    - net/ipv4: defensive cipso option parsing
+    - dmaengine: ppc4xx: fix off-by-one build failure
+    - scsi: sched/wait: Add wait_event_lock_irq_timeout for TASK_UNINTERRUPTIBLE
+      usage
+    - scsi: target: Fix target_wait_for_sess_cmds breakage with active signals
+    - libnvdimm: Hold reference on parent while scheduling async init
+    - libnvdimm, region: Fail badblocks listing for inactive regions
+    - libnvdimm, pmem: Fix badblocks population for 'raw' namespaces
+    - ASoC: intel: skylake: Add missing break in skl_tplg_get_token()
+    - ASoC: sta32x: set ->component pointer in private struct
+    - IB/mlx5: Fix MR cache initialization
+    - IB/rxe: Revise the ib_wr_opcode enum
+    - jbd2: fix use after free in jbd2_log_do_checkpoint()
+    - gfs2_meta: ->mount() can get NULL dev_name
+    - ext4: fix EXT4_IOC_SWAP_BOOT
+    - ext4: initialize retries variable in ext4_da_write_inline_data_begin()
+    - ext4: fix setattr project check in fssetxattr ioctl
+    - ext4: propagate error from dquot_initialize() in EXT4_IOC_FSSETXATTR
+    - ext4: fix use-after-free race in ext4_remount()'s error path
+    - selinux: fix mounting of cgroup2 under older policies
+    - HID: wacom: Work around HID descriptor bug in DTK-2451 and DTH-2452
+    - HID: hiddev: fix potential Spectre v1
+    - EDAC, amd64: Add Family 17h, models 10h-2fh support
+    - EDAC, {i7core,sb,skx}_edac: Fix uncorrected error counting
+    - EDAC, skx_edac: Fix logical channel intermediate decoding
+    - ARM: dts: dra7: Fix up unaligned access setting for PCIe EP
+    - PCI/ASPM: Fix link_state teardown on device removal
+    - PCI: Add Device IDs for Intel GPU "spurious interrupt" quirk
+    - signal/GenWQE: Fix sending of SIGKILL
+    - signal: Guard against negative signal numbers in copy_siginfo_from_user32
+    - crypto: lrw - Fix out-of bounds access on counter overflow
+    - crypto: tcrypt - fix ghash-generic speed test
+    - crypto: aesni - don't use GFP_ATOMIC allocation if the request doesn't cross
+      a page in gcm
+    - crypto: morus/generic - fix for big endian systems
+    - crypto: aegis/generic - fix for big endian systems
+    - crypto: speck - remove Speck
+    - mm: /proc/pid/smaps_rollup: fix NULL pointer deref in smaps_pte_range()
+    - userfaultfd: disable irqs when taking the waitqueue lock
+    - ima: fix showing large 'violations' or 'runtime_measurements_count'
+    - ima: open a new file instance if no read permissions
+    - hugetlbfs: dirty pages as they are added to pagecache
+    - mm/rmap: map_pte() was not handling private ZONE_DEVICE page properly
+    - mm/hmm: fix race between hmm_mirror_unregister() and mmu_notifier callback
+    - KVM: arm/arm64: Ensure only THP is candidate for adjustment
+    - KVM: arm64: Fix caching of host MDCR_EL2 value
+    - kbuild: fix kernel/bounds.c 'W=1' warning
+    - iio: ad5064: Fix regulator handling
+    - iio: adc: imx25-gcq: Fix leak of device_node in mx25_gcq_setup_cfgs()
+    - iio: adc: at91: fix acking DRDY irq on simple conversions
+    - iio: adc: at91: fix wrong channel number in triggered buffer mode
+    - w1: omap-hdq: fix missing bus unregister at removal
+    - smb3: allow stats which track session and share reconnects to be reset
+    - smb3: do not attempt cifs operation in smb3 query info error path
+    - smb3: on kerberos mount if server doesn't specify auth type use krb5
+    - printk: Fix panic caused by passing log_buf_len to command line
+    - genirq: Fix race on spurious interrupt detection
+    - tpm: fix response size validation in tpm_get_random()
+    - NFC: nfcmrvl_uart: fix OF child-node lookup
+    - NFSv4.1: Fix the r/wsize checking
+    - nfs: Fix a missed page unlock after pg_doio()
+    - nfsd: correctly decrement odstate refcount in error path
+    - nfsd: Fix an Oops in free_session()
+    - lockd: fix access beyond unterminated strings in prints
+    - dm ioctl: harden copy_params()'s copy_from_user() from malicious users
+    - dm zoned: fix metadata block ref counting
+    - dm zoned: fix various dmz_get_mblock() issues
+    - media: ov7670: make "xclk" clock optional
+    - fsnotify: Fix busy inodes during unmount
+    - powerpc64/module elfv1: Set opd addresses after module relocation
+    - powerpc/msi: Fix compile error on mpc83xx
+    - powerpc/tm: Fix HFSCR bit for no suspend case
+    - powerpc/64s/hash: Do not use PPC_INVALIDATE_ERAT on CPUs before POWER9
+    - MIPS: OCTEON: fix out of bounds array access on CN68XX
+    - rtc: ds1307: fix ds1339 wakealarm support
+    - rtc: cmos: Fix non-ACPI undefined reference to `hpet_rtc_interrupt'
+    - rtc: cmos: Remove the `use_acpi_alarm' module parameter for !ACPI
+    - power: supply: twl4030-charger: fix OF sibling-node lookup
+    - ocxl: Fix access to the AFU Descriptor Data
+    - iommu/arm-smmu: Ensure that page-table updates are visible before TLBI
+    - TC: Set DMA masks for devices
+    - net: bcmgenet: fix OF child-node lookup
+    - media: v4l2-tpg: fix kernel oops when enabling HFLIP and OSD
+    - Revert "media: dvbsky: use just one mutex for serializing device R/W ops"
+    - kgdboc: Passing ekgdboc to command line causes panic
+    - remoteproc: qcom: q6v5: Propagate EPROBE_DEFER
+    - media: cec: make cec_get_edid_spa_location() an inline function
+    - media: cec: integrate cec_validate_phys_addr() in cec-api.c
+    - xen: fix xen_qlock_wait()
+    - xen: remove size limit of privcmd-buf mapping interface
+    - xen-blkfront: fix kernel panic with negotiate_mq error path
+    - media: cec: add new tx/rx status bits to detect aborts/timeouts
+    - media: cec: fix the Signal Free Time calculation
+    - media: cec: forgot to cancel delayed work
+    - media: em28xx: use a default format if TRY_FMT fails
+    - media: tvp5150: avoid going past array on v4l2_querymenu()
+    - media: em28xx: fix input name for Terratec AV 350
+    - media: em28xx: make v4l2-compliance happier by starting sequence on zero
+    - media: em28xx: fix handler for vidioc_s_input()
+    - media: adv7604: when the EDID is cleared, unconfigure CEC as well
+    - media: adv7842: when the EDID is cleared, unconfigure CEC as well
+    - drm/mediatek: fix OF sibling-node lookup
+    - media: media colorspaces*.rst: rename AdobeRGB to opRGB
+    - media: replace ADOBERGB by OPRGB
+    - media: hdmi.h: rename ADOBE_RGB to OPRGB and ADOBE_YCC to OPYCC
+    - arm64: lse: remove -fcall-used-x0 flag
+    - rpmsg: smd: fix memory leak on channel create
+    - Cramfs: fix abad comparison when wrap-arounds occur
+    - ARM: dts: socfpga: Fix SDRAM node address for Arria10
+    - arm64: dts: stratix10: Correct System Manager register size
+    - soc: qcom: rmtfs-mem: Validate that scm is available
+    - soc/tegra: pmc: Fix child-node lookup
+    - selftests/ftrace: Fix synthetic event test to delete event correctly
+    - selftests/powerpc: Fix ptrace tm failure
+    - tracing: Return -ENOENT if there is no target synthetic event
+    - btrfs: qgroup: Avoid calling qgroup functions if qgroup is not enabled
+    - btrfs: Handle owner mismatch gracefully when walking up tree
+    - btrfs: locking: Add extra check in btrfs_init_new_buffer() to avoid deadlock
+    - btrfs: fix error handling in free_log_tree
+    - btrfs: fix error handling in btrfs_dev_replace_start
+    - btrfs: Enhance btrfs_trim_fs function to handle error better
+    - btrfs: Ensure btrfs_trim_fs can trim the whole filesystem
+    - btrfs: iterate all devices during trim, instead of fs_devices::alloc_list
+    - btrfs: don't attempt to trim devices that don't support it
+    - btrfs: keep trim from interfering with transaction commits
+    - btrfs: wait on caching when putting the bg cache
+    - Btrfs: don't clean dirty pages during buffered writes
+    - btrfs: release metadata before running delayed refs
+    - btrfs: protect space cache inode alloc with GFP_NOFS
+    - btrfs: reset max_extent_size on clear in a bitmap
+    - btrfs: make sure we create all new block groups
+    - Btrfs: fix warning when replaying log after fsync of a tmpfile
+    - Btrfs: fix wrong dentries after fsync of file that got its parent replaced
+    - btrfs: qgroup: Dirty all qgroups before rescan
+    - Btrfs: fix null pointer dereference on compressed write path error
+    - Btrfs: fix assertion on fsync of regular file when using no-holes feature
+    - Btrfs: fix deadlock when writing out free space caches
+    - btrfs: reset max_extent_size properly
+    - btrfs: set max_extent_size properly
+    - btrfs: don't use ctl->free_space for max_extent_size
+    - btrfs: only free reserved extent if we didn't insert it
+    - btrfs: fix insert_reserved error handling
+    - btrfs: don't run delayed_iputs in commit
+    - btrfs: move the dio_sem higher up the callchain
+    - Btrfs: fix use-after-free during inode eviction
+    - Btrfs: fix use-after-free when dumping free space
+    - net: sched: Remove TCA_OPTIONS from policy
+    - vt: fix broken display when running aptitude
+    - bpf: wait for running BPF programs when updating map-in-map
+    - vga_switcheroo: Fix missing gpu_bound call at audio client registration
+    - MD: fix invalid stored role for a disk - try2
+    - Linux 4.19.2
+
+  * [FEAT] Guest-dedicated Crypto Adapters (LP: #1787405)
+    - KVM: s390: vsie: simulate VCPU SIE entry/exit
+    - KVM: s390: introduce and use KVM_REQ_VSIE_RESTART
+    - KVM: s390: refactor crypto initialization
+    - s390: vfio-ap: base implementation of VFIO AP device driver
+    - s390: vfio-ap: register matrix device with VFIO mdev framework
+    - s390: vfio-ap: sysfs interfaces to configure adapters
+    - s390: vfio-ap: sysfs interfaces to configure domains
+    - s390: vfio-ap: sysfs interfaces to configure control domains
+    - s390: vfio-ap: sysfs interface to view matrix mdev matrix
+    - KVM: s390: interface to clear CRYCB masks
+    - s390: vfio-ap: implement mediated device open callback
+    - s390: vfio-ap: implement VFIO_DEVICE_GET_INFO ioctl
+    - s390: vfio-ap: zeroize the AP queues
+    - s390: vfio-ap: implement VFIO_DEVICE_RESET ioctl
+    - KVM: s390: Clear Crypto Control Block when using vSIE
+    - KVM: s390: vsie: Do the CRYCB validation first
+    - KVM: s390: vsie: Make use of CRYCB FORMAT2 clear
+    - KVM: s390: vsie: Allow CRYCB FORMAT-2
+    - KVM: s390: vsie: allow CRYCB FORMAT-1
+    - KVM: s390: vsie: allow CRYCB FORMAT-0
+    - KVM: s390: vsie: allow guest FORMAT-0 CRYCB on host FORMAT-1
+    - KVM: s390: vsie: allow guest FORMAT-1 CRYCB on host FORMAT-2
+    - KVM: s390: vsie: allow guest FORMAT-0 CRYCB on host FORMAT-2
+    - KVM: s390: device attrs to enable/disable AP interpretation
+    - KVM: s390: CPU model support for AP virtualization
+    - s390: doc: detailed specifications for AP virtualization
+    - KVM: s390: fix locking for crypto setting error path
+    - KVM: s390: Tracing APCB changes
+    - s390: vfio-ap: setup APCB mask using KVM dedicated function
+    - [Config:] Enable CONFIG_S390_AP_IOMMU and set CONFIG_VFIO_AP to module.
+
+  * Bypass of mount visibility through userns + mount propagation (LP: #1789161)
+    - mount: Retest MNT_LOCKED in do_umount
+    - mount: Don't allow copying MNT_UNBINDABLE|MNT_LOCKED mounts
+
+  *  CVE-2018-18955: nested user namespaces with more than five extents
+    incorrectly grant privileges over inode (LP: #1801924) // CVE-2018-18955
+    - userns: also map extents in the reverse map to kernel IDs
+
+  * kdump fail due to an IRQ storm (LP: #1797990)
+    - SAUCE: x86/PCI: Export find_cap() to be used in early PCI code
+    - SAUCE: x86/quirks: Add parameter to clear MSIs early on boot
+    - SAUCE: x86/quirks: Scan all busses for early PCI quirks
+
+  * Disable LPM for Raydium Touchscreens (LP: #1802248)
+    - USB: quirks: Add no-lpm quirk for Raydium touchscreens
+
+  * Power consumption during s2idle is higher than long idle(sk hynix)
+    (LP: #1801875)
+    - SAUCE: pci: prevent sk hynix nvme from entering D3
+    - SAUCE: nvme: add quirk to not call disable function when suspending
+
+  * Disco update: v4.19.1 upstream stable release (LP: #1801739)
+    - bridge: do not add port to router list when receives query with source
+      0.0.0.0
+    - ipv6/ndisc: Preserve IPv6 control buffer if protocol error handlers are
+      called
+    - net/mlx5e: fix csum adjustments caused by RXFCS
+    - net: sched: gred: pass the right attribute to gred_change_table_def()
+    - net: stmmac: Fix stmmac_mdio_reset() when building stmmac as modules
+    - net: udp: fix handling of CHECKSUM_COMPLETE packets
+    - Revert "net: simplify sock_poll_wait"
+    - rtnetlink: Disallow FDB configuration for non-Ethernet device
+    - vhost: Fix Spectre V1 vulnerability
+    - bonding: fix length of actor system
+    - openvswitch: Fix push/pop ethernet validation
+    - net/ipv6: Allow onlink routes to have a device mismatch if it is the default
+      route
+    - net/smc: fix smc_buf_unuse to use the lgr pointer
+    - mlxsw: spectrum_switchdev: Don't ignore deletions of learned MACs
+    - mlxsw: core: Fix devlink unregister flow
+    - net: drop skb on failure in ip_check_defrag()
+    - net: Properly unlink GRO packets on overflow.
+    - r8169: fix broken Wake-on-LAN from S5 (poweroff)
+    - Revert "be2net: remove desc field from be_eq_obj"
+    - sctp: check policy more carefully when getting pr status
+    - sparc64: Export __node_distance.
+    - sparc64: Make corrupted user stacks more debuggable.
+    - sparc64: Wire up compat getpeername and getsockname.
+    - net: bridge: remove ipv6 zero address check in mcast queries
+    - Linux 4.19.1
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.11-1ubuntu1, zfs to 0.7.11-3ubuntu1
+    - [Config] updateconfigs after 4.19.2 stable update
+    - [Config] Disable unneded options for s390
+    - [Config] Update annotations for 4.19
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 15 Nov 2018 09:55:37 -0800
+
+linux (4.19.0-4.5) disco; urgency=medium
+
+  * Add checksum offload and TSO support for HiNIC adapters (LP: #1800664)
+    - net-next/hinic: add checksum offload and TSO support
+
+  * [Bionic][Cosmic] Fix to ipmi to support vendor specific messages greater
+    than 255 bytes (LP: #1799794)
+    - ipmi:ssif: Add support for multi-part transmit messages > 2 parts
+
+  * Packaging resync (LP: #1786013)
+    - [Package] add support for specifying the primary makefile
+
+  * Update ENA driver to version 2.0.1K (LP: #1798182)
+    - net: ena: minor performance improvement
+    - net: ena: complete host info to match latest ENA spec
+    - net: ena: introduce Low Latency Queues data structures according to ENA spec
+    - net: ena: add functions for handling Low Latency Queues in ena_com
+    - net: ena: add functions for handling Low Latency Queues in ena_netdev
+    - net: ena: use CSUM_CHECKED device indication to report skb's checksum status
+    - net: ena: explicit casting and initialization, and clearer error handling
+    - net: ena: limit refill Rx threshold to 256 to avoid latency issues
+    - net: ena: change rx copybreak default to reduce kernel memory pressure
+    - net: ena: remove redundant parameter in ena_com_admin_init()
+    - net: ena: update driver version to 2.0.1
+    - net: ena: fix indentations in ena_defs for better readability
+    - net: ena: Fix Kconfig dependency on X86
+    - net: ena: enable Low Latency Queues
+    - net: ena: fix compilation error in xtensa architecture
+
+  * [Bionic][Cosmic]  ipmi: Fix timer race with module unload (LP: #1799281)
+    - ipmi: Fix timer race with module unload
+
+  * Overlayfs in user namespace leaks directory content of inaccessible
+    directories (LP: #1793458) // CVE-2018-6559
+    - SAUCE: overlayfs: ensure mounter privileges when reading directories
+
+  * not able to unwind the stack from within __kernel_clock_gettime in the Linux
+    vDSO (LP: #1797963)
+    - powerpc/vdso: Correct call frame information
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Don't print secure boot state
+      from the efi stub"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Make get_cert_list() use
+      efi_status_to_str() to print error messages."
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err()."
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Make get_cert_list() not complain
+      about cert lists that aren't present."
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable
+      to be suppressed"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI
+      Secure Boot"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add EFI signature data types"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time
+      addition of keys to secondary keyring"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in
+      secure boot mode"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to
+      indicate secure boot mode"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Copy secure_boot flag in boot params
+      across kexec reboot"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down perf"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) bpf: Restrict kernel image access
+      functions when the kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down kprobes"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down /proc/kcore"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the
+      testmmiotrace module"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down module params that specify
+      hardware parameters (eg. ioport)"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down TIOCSSERIAL"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) acpi: Disable APEI error injection if
+      the kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) acpi: Disable ACPI table override if
+      the kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param
+      when the kernel has been locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) ACPI: Limit access to custom_method
+      when the kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) x86: Lock down IO port access when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) PCI: Lock down BAR access when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is
+      locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) hibernate: Disable when the kernel is
+      locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Enforce module signatures if the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Add a SysRq option to lift kernel
+      lockdown"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Add the ability to lock down access to
+      the running kernel image"
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) efi: Add EFI signature data types
+    - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) efi/x86: Call efi_parse_options() from efi_main()
+    - SAUCE: (efi-lockdown) Fix for module sig verification
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) module: remove support for having IMA validate modules
+    - [Packaging] generate Vcs-Git url from changelog
+    - [Config] CONFIG_SCSI_MQ_DEFAULT=y
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 02 Nov 2018 14:22:55 -0500
+
+linux (4.19.0-3.4) cosmic; urgency=medium
+
+  * Support Edge Gateway's Bluetooth LED (LP: #1798332)
+    - SAUCE: Bluetooth: Support for LED on Edge Gateways
+
+  * Support Edge Gateway's WIFI LED (LP: #1798330)
+    - SAUCE: mwifiex: Switch WiFi LED state according to the device status
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.19
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 22 Oct 2018 09:13:39 -0500
+
+linux (4.19.0-2.3) cosmic; urgency=medium
+
+  * fscache: bad refcounting in fscache_op_complete leads to OOPS (LP: #1797314)
+    - SAUCE: fscache: Fix race in decrementing refcount of op->npages
+
+  * Provide mode where all vCPUs on a core must be the same VM (LP: #1792957)
+    - KVM: PPC: Book3S HV: Provide mode where all vCPUs on a core must be the same
+      VM
+
+  * The front MIC can't work on the Lenovo M715 (LP: #1797292)
+    - ALSA: hda/realtek - Fix the problem of the front MIC on the Lenovo M715
+
+  * arm64: snapdragon: WARNING: CPU: 0 PID: 1 at drivers/irqchip/irq-gic.c:1016
+    gic_irq_domain_translate (LP: #1797143)
+    - SAUCE: arm64: dts: msm8916: camms: fix gic_irq_domain_translate warnings
+
+  * Dell new AIO requires a new uart backlight driver (LP: #1727235)
+    - SAUCE: platform/x86: dell-uart-backlight: new backlight driver for DELL AIO
+    - updateconfigs for Dell UART backlight driver
+
+  * Please make CONFIG_PWM_LPSS_PCI and CONFIG_PWM_LPSS_PLATFORM built in to
+    make brightness adjustment working on various BayTrail/CherryTrail-based
+    devices (LP: #1783964)
+    - [Config]: Make PWM_LPSS_* built-in
+
+  * check and fix zkey required kernel modules locations in debs, udebs, and
+    initramfs (LP: #1794346)
+    - [Config] add s390 crypto modules to crypt-modules udeb
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_VBOXGUEST=n
+    - ubuntu: vbox -- update to 5.2.18-dfsg-2
+    - ubuntu: enable vbox build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.19-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 15 Oct 2018 10:52:04 -0500
+
+linux (4.19.0-1.2) cosmic; urgency=medium
+
+  * Page leaking in cachefiles_read_backing_file while vmscan is active
+    (LP: #1793430)
+    - SAUCE: cachefiles: Page leaking in cachefiles_read_backing_file while vmscan
+      is active
+
+  * SRU: Enable middle button of touchpad on ThinkPad P72 (LP: #1793463)
+    - Input: elantech - enable middle button of touchpad on ThinkPad P72
+
+  * Improvements to the kernel source package preparation (LP: #1793461)
+    - [Packaging] startnewrelease: add support for backport kernels
+
+  * Fix unusable NVIDIA GPU after S3 (LP: #1793338)
+    - SAUCE: PCI: Reprogram bridge prefetch registers on resume
+
+  * Error reported when creating ZFS pool with "-t" option, despite successful
+    pool creation (LP: #1769937)
+    - SAUCE: (noup) Update zfs to 0.7.9-3ubuntu6
+
+  * device hotplug of vfio devices can lead to deadlock in vfio_pci_release
+    (LP: #1792099)
+    - SAUCE: vfio -- release device lock before userspace requests
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] retpoline -- fix temporary filenaming
+    - CONFIG_BCH_CONST_PARAMS=n
+    - Packaging: final-checks: remove trailing backport suffix
+    - SAUCE: import aufs driver
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.19-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 25 Sep 2018 16:32:24 -0500
+
+linux (4.19.0-0.1) cosmic; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu -- disable vbox build
+    - Disable zfs build
+    - SAUCE: Import aufs driver
+    - Update dropped.txt
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.19-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 13 Sep 2018 07:54:47 -0500
+
+linux (4.19.0-0.0) cosmic; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 13 Sep 2018 06:44:09 -0500
+
+linux (4.18.0-8.9) cosmic; urgency=medium
+
+  * linux: 4.18.0-8.9 -proposed tracker (LP: #1791663)
+
+  * Cosmic update to v4.18.7 stable release (LP: #1791660)
+    - rcu: Make expedited GPs handle CPU 0 being offline
+    - net: 6lowpan: fix reserved space for single frames
+    - net: mac802154: tx: expand tailroom if necessary
+    - 9p/net: Fix zero-copy path in the 9p virtio transport
+    - spi: davinci: fix a NULL pointer dereference
+    - spi: pxa2xx: Add support for Intel Ice Lake
+    - spi: spi-fsl-dspi: Fix imprecise abort on VF500 during probe
+    - spi: cadence: Change usleep_range() to udelay(), for atomic context
+    - mmc: block: Fix unsupported parallel dispatch of requests
+    - mmc: renesas_sdhi_internal_dmac: mask DMAC interrupts
+    - mmc: renesas_sdhi_internal_dmac: fix #define RST_RESERVED_BITS
+    - readahead: stricter check for bdi io_pages
+    - block: fix infinite loop if the device loses discard capability
+    - block: blk_init_allocated_queue() set q->fq as NULL in the fail case
+    - block: really disable runtime-pm for blk-mq
+    - blkcg: Introduce blkg_root_lookup()
+    - block: Introduce blk_exit_queue()
+    - block: Ensure that a request queue is dissociated from the cgroup controller
+    - apparmor: fix bad debug check in apparmor_secid_to_secctx()
+    - dma-buf: Move BUG_ON from _add_shared_fence to _add_shared_inplace
+    - libertas: fix suspend and resume for SDIO connected cards
+    - media: Revert "[media] tvp5150: fix pad format frame height"
+    - mailbox: xgene-slimpro: Fix potential NULL pointer dereference
+    - Replace magic for trusting the secondary keyring with #define
+    - Fix kexec forbidding kernels signed with keys in the secondary keyring to
+      boot
+    - powerpc/fadump: handle crash memory ranges array index overflow
+    - powerpc/64s: Fix page table fragment refcount race vs speculative references
+    - powerpc/pseries: Fix endianness while restoring of r3 in MCE handler.
+    - powerpc/pkeys: Give all threads control of their key permissions
+    - powerpc/pkeys: Deny read/write/execute by default
+    - powerpc/pkeys: key allocation/deallocation must not change pkey registers
+    - powerpc/pkeys: Save the pkey registers before fork
+    - powerpc/pkeys: Fix calculation of total pkeys.
+    - powerpc/pkeys: Preallocate execute-only key
+    - powerpc/nohash: fix pte_access_permitted()
+    - powerpc64/ftrace: Include ftrace.h needed for enable/disable calls
+    - powerpc/powernv/pci: Work around races in PCI bridge enabling
+    - cxl: Fix wrong comparison in cxl_adapter_context_get()
+    - IB/mlx5: Honor cnt_set_id_valid flag instead of set_id
+    - IB/mlx5: Fix leaking stack memory to userspace
+    - IB/srpt: Fix srpt_cm_req_recv() error path (1/2)
+    - IB/srpt: Fix srpt_cm_req_recv() error path (2/2)
+    - IB/srpt: Support HCAs with more than two ports
+    - overflow.h: Add arithmetic shift helper
+    - RDMA/mlx5: Fix shift overflow in mlx5_ib_create_wq
+    - ib_srpt: Fix a use-after-free in srpt_close_ch()
+    - ib_srpt: Fix a use-after-free in __srpt_close_all_ch()
+    - RDMA/rxe: Set wqe->status correctly if an unexpected response is received
+    - 9p: fix multiple NULL-pointer-dereferences
+    - fs/9p/xattr.c: catch the error of p9_client_clunk when setting xattr failed
+    - 9p/virtio: fix off-by-one error in sg list bounds check
+    - net/9p/client.c: version pointer uninitialized
+    - net/9p/trans_fd.c: fix race-condition by flushing workqueue before the
+      kfree()
+    - dm integrity: change 'suspending' variable from bool to int
+    - dm thin: stop no_space_timeout worker when switching to write-mode
+    - dm cache metadata: save in-core policy_hint_size to on-disk superblock
+    - dm cache metadata: set dirty on all cache blocks after a crash
+    - dm crypt: don't decrease device limits
+    - dm writecache: fix a crash due to reading past end of dirty_bitmap
+    - uart: fix race between uart_put_char() and uart_shutdown()
+    - Drivers: hv: vmbus: Fix the offer_in_progress in vmbus_process_offer()
+    - Drivers: hv: vmbus: Reset the channel callback in vmbus_onoffer_rescind()
+    - iio: sca3000: Fix missing return in switch
+    - iio: ad9523: Fix displayed phase
+    - iio: ad9523: Fix return value for ad952x_store()
+    - extcon: Release locking when sending the notification of connector state
+    - eventpoll.h: wrap casts in () properly
+    - vmw_balloon: fix inflation of 64-bit GFNs
+    - vmw_balloon: do not use 2MB without batching
+    - vmw_balloon: VMCI_DOORBELL_SET does not check status
+    - vmw_balloon: fix VMCI use when balloon built into kernel
+    - rtc: omap: fix resource leak in registration error path
+    - rtc: omap: fix potential crash on power off
+    - tracing: Do not call start/stop() functions when tracing_on does not change
+    - tracing/blktrace: Fix to allow setting same value
+    - printk/tracing: Do not trace printk_nmi_enter()
+    - livepatch: Validate module/old func name length
+    - uprobes: Use synchronize_rcu() not synchronize_sched()
+    - mfd: hi655x: Fix regmap area declared size for hi655x
+    - ovl: fix wrong use of impure dir cache in ovl_iterate()
+    - ACPICA: AML Parser: skip opcodes that open a scope upon parse failure
+    - ACPICA: Clear status of all events when entering sleep states
+    - drivers/block/zram/zram_drv.c: fix bug storing backing_dev
+    - sched: idle: Avoid retaining the tick when it has been stopped
+    - cpuidle: menu: Handle stopped tick more aggressively
+    - cpufreq: governor: Avoid accessing invalid governor_data
+    - PM / sleep: wakeup: Fix build error caused by missing SRCU support
+    - ALSA: ac97: fix device initialization in the compat layer
+    - ALSA: ac97: fix check of pm_runtime_get_sync failure
+    - ALSA: ac97: fix unbalanced pm_runtime_enable
+    - i2c: designware: Re-init controllers with pm_disabled set on resume
+    - KVM: VMX: fixes for vmentry_l1d_flush module parameter
+    - KVM: PPC: Book3S: Fix guest DMA when guest partially backed by THP pages
+    - xtensa: limit offsets in __loop_cache_{all,page}
+    - xtensa: increase ranges in ___invalidate_{i,d}cache_all
+    - block, bfq: return nbytes and not zero from struct cftype .write() method
+    - pnfs/blocklayout: off by one in bl_map_stripe()
+    - nfsd: fix leaked file lock with nfs exported overlayfs
+    - NFSv4 client live hangs after live data migration recovery
+    - NFSv4: Fix locking in pnfs_generic_recover_commit_reqs
+    - NFSv4: Fix a sleep in atomic context in nfs4_callback_sequence()
+    - ARM: tegra: Fix Tegra30 Cardhu PCA954x reset
+    - ARM: dts: am57xx-idk: Enable dual role for USB2 port
+    - pwm: omap-dmtimer: Return -EPROBE_DEFER if no dmtimer platform data
+    - mm/tlb: Remove tlb_remove_table() non-concurrent condition
+    - iommu/ipmmu-vmsa: Don't register as BUS IOMMU if machine doesn't have IPMMU-
+      VMSA
+    - iommu/vt-d: Add definitions for PFSID
+    - iommu/vt-d: Fix dev iotlb pfsid use
+    - sys: don't hold uts_sem while accessing userspace memory
+    - userns: move user access out of the mutex
+    - ubifs: Fix memory leak in lprobs self-check
+    - Revert "UBIFS: Fix potential integer overflow in allocation"
+    - ubifs: Check data node size before truncate
+    - ubifs: xattr: Don't operate on deleted inodes
+    - ubifs: Fix directory size calculation for symlinks
+    - ubifs: Fix synced_i_size calculation for xattr inodes
+    - pwm: tiehrpwm: Don't use emulation mode bits to control PWM output
+    - pwm: tiehrpwm: Fix disabling of output of PWMs
+    - fb: fix lost console when the user unplugs a USB adapter
+    - udlfb: fix semaphore value leak
+    - udlfb: fix display corruption of the last line
+    - udlfb: don't switch if we are switching to the same videomode
+    - udlfb: set optimal write delay
+    - udlfb: make a local copy of fb_ops
+    - udlfb: handle allocation failure
+    - udlfb: set line_length in dlfb_ops_set_par
+    - getxattr: use correct xattr length
+    - libnvdimm: Use max contiguous area for namespace size
+    - libnvdimm: fix ars_status output length calculation
+    - bcache: release dc->writeback_lock properly in bch_writeback_thread()
+    - kconfig: fix "Can't open ..." in parallel build
+    - perf auxtrace: Fix queue resize
+    - crypto: vmx - Fix sleep-in-atomic bugs
+    - crypto: aesni - Use unaligned loads from gcm_context_data
+    - crypto: arm64/sm4-ce - check for the right CPU feature bit
+    - crypto: caam - fix DMA mapping direction for RSA forms 2 & 3
+    - crypto: caam/jr - fix descriptor DMA unmapping
+    - crypto: caam/qi - fix error path in xts setkey
+    - fs/quota: Fix spectre gadget in do_quotactl
+    - udf: Fix mounting of Win7 created UDF filesystems
+    - cpuidle: menu: Retain tick when shallow state is selected
+    - arm64: mm: always enable CONFIG_HOLES_IN_ZONE
+    - Linux 4.18.7
+
+  * CVE-2017-5715
+    - s390: detect etoken facility
+    - KVM: s390: add etoken support for guests
+
+  * Missing Intel GPU pci-id's (LP: #1789924)
+    - drm/i915/whl: Introducing Whiskey Lake platform
+    - drm/i915/aml: Introducing Amber Lake platform
+    - drm/i915/cfl: Add a new CFL PCI ID.
+
+  * [18.10 FEAT] Add kernel config options for SMC-R/D (LP: #1789934)
+    - s390/ism: add device driver for internal shared memory
+    - CONFIG_ISM=y for s390
+
+  * Cosmic update to v4.18.6 stable release (LP: #1791105)
+    - PATCH scripts/kernel-doc
+    - scripts/kernel-doc: Escape all literal braces in regexes
+    - scsi: libsas: dynamically allocate and free ata host
+    - xprtrdma: Fix disconnect regression
+    - mei: don't update offset in write
+    - cifs: add missing support for ACLs in SMB 3.11
+    - CIFS: fix uninitialized ptr deref in smb2 signing
+    - cifs: add missing debug entries for kconfig options
+    - cifs: use a refcount to protect open/closing the cached file handle
+    - cifs: check kmalloc before use
+    - smb3: enumerating snapshots was leaving part of the data off end
+    - smb3: Do not send SMB3 SET_INFO if nothing changed
+    - smb3: don't request leases in symlink creation and query
+    - smb3: fill in statfs fsid and correct namelen
+    - btrfs: use correct compare function of dirty_metadata_bytes
+    - btrfs: don't leak ret from do_chunk_alloc
+    - Btrfs: fix mount failure after fsync due to hard link recreation
+    - Btrfs: fix btrfs_write_inode vs delayed iput deadlock
+    - Btrfs: fix send failure when root has deleted files still open
+    - Btrfs: send, fix incorrect file layout after hole punching beyond eof
+    - hwmon: (k10temp) 27C Offset needed for Threadripper2
+    - bpf, arm32: fix stack var offset in jit
+    - regulator: arizona-ldo1: Use correct device to get enable GPIO
+    - iommu/arm-smmu: Error out only if not enough context interrupts
+    - printk: Split the code for storing a message into the log buffer
+    - printk: Create helper function to queue deferred console handling
+    - printk/nmi: Prevent deadlock when accessing the main log buffer in NMI
+    - kprobes/arm64: Fix %p uses in error messages
+    - arm64: Fix mismatched cache line size detection
+    - arm64: Handle mismatched cache type
+    - arm64: mm: check for upper PAGE_SHIFT bits in pfn_valid()
+    - arm64: dts: rockchip: corrected uart1 clock-names for rk3328
+    - KVM: arm/arm64: Fix potential loss of ptimer interrupts
+    - KVM: arm/arm64: Fix lost IRQs from emulated physcial timer when blocked
+    - KVM: arm/arm64: Skip updating PMD entry if no change
+    - KVM: arm/arm64: Skip updating PTE entry if no change
+    - s390/kvm: fix deadlock when killed by oom
+    - perf kvm: Fix subcommands on s390
+    - stop_machine: Reflow cpu_stop_queue_two_works()
+    - stop_machine: Atomically queue and wake stopper threads
+    - ext4: check for NUL characters in extended attribute's name
+    - ext4: use ext4_warning() for sb_getblk failure
+    - ext4: sysfs: print ext4_super_block fields as little-endian
+    - ext4: reset error code in ext4_find_entry in fallback
+    - ext4: fix race when setting the bitmap corrupted flag
+    - x86/gpu: reserve ICL's graphics stolen memory
+    - platform/x86: wmi: Do not mix pages and kmalloc
+    - platform/x86: ideapad-laptop: Apply no_hw_rfkill to Y20-15IKBM, too
+    - mm: move tlb_table_flush to tlb_flush_mmu_free
+    - mm/tlb, x86/mm: Support invalidating TLB caches for RCU_TABLE_FREE
+    - x86/speculation/l1tf: Fix overflow in l1tf_pfn_limit() on 32bit
+    - x86/speculation/l1tf: Fix off-by-one error when warning that system has too
+      much RAM
+    - x86/speculation/l1tf: Suggest what to do on systems with too much RAM
+    - x86/vdso: Fix vDSO build if a retpoline is emitted
+    - x86/process: Re-export start_thread()
+    - KVM: x86: ensure all MSRs can always be KVM_GET/SET_MSR'd
+    - KVM: x86: SVM: Call x86_spec_ctrl_set_guest/host() with interrupts disabled
+    - fuse: Don't access pipe->buffers without pipe_lock()
+    - fuse: fix initial parallel dirops
+    - fuse: fix double request_end()
+    - fuse: fix unlocked access to processing queue
+    - fuse: umount should wait for all requests
+    - fuse: Fix oops at process_init_reply()
+    - fuse: Add missed unlock_page() to fuse_readpages_fill()
+    - lib/vsprintf: Do not handle %pO[^F] as %px
+    - udl-kms: change down_interruptible to down
+    - udl-kms: handle allocation failure
+    - udl-kms: fix crash due to uninitialized memory
+    - udl-kms: avoid division
+    - b43legacy/leds: Ensure NUL-termination of LED name string
+    - b43/leds: Ensure NUL-termination of LED name string
+    - ASoC: dpcm: don't merge format from invalid codec dai
+    - ASoC: zte: Fix incorrect PCM format bit usages
+    - ASoC: sirf: Fix potential NULL pointer dereference
+    - ASoC: wm_adsp: Correct DSP pointer for preloader control
+    - soc: qcom: rmtfs-mem: fix memleak in probe error paths
+    - pinctrl: freescale: off by one in imx1_pinconf_group_dbg_show()
+    - scsi: qla2xxx: Fix stalled relogin
+    - x86/vdso: Fix lsl operand order
+    - x86/nmi: Fix NMI uaccess race against CR3 switching
+    - x86/irqflags: Mark native_restore_fl extern inline
+    - x86/spectre: Add missing family 6 check to microcode check
+    - x86/speculation/l1tf: Increase l1tf memory limit for Nehalem+
+    - hwmon: (nct6775) Fix potential Spectre v1
+    - x86/entry/64: Wipe KASAN stack shadow before rewind_stack_do_exit()
+    - x86: Allow generating user-space headers without a compiler
+    - s390/mm: fix addressing exception after suspend/resume
+    - s390/lib: use expoline for all bcr instructions
+    - s390: fix br_r1_trampoline for machines without exrl
+    - s390/qdio: reset old sbal_state flags
+    - s390/numa: move initial setup of node_to_cpumask_map
+    - s390/purgatory: Fix crash with expoline enabled
+    - s390/purgatory: Add missing FORCE to Makefile targets
+    - kprobes: Show blacklist addresses as same as kallsyms does
+    - kprobes: Replace %p with other pointer types
+    - kprobes/arm: Fix %p uses in error messages
+    - kprobes: Make list and blacklist root user read only
+    - MIPS: Correct the 64-bit DSP accumulator register size
+    - MIPS: memset.S: Fix byte_fixup for MIPSr6
+    - MIPS: Always use -march=<arch>, not -<arch> shortcuts
+    - MIPS: Change definition of cpu_relax() for Loongson-3
+    - MIPS: lib: Provide MIPS64r6 __multi3() for GCC < 7
+    - tpm: Return the actual size when receiving an unsupported command
+    - tpm: separate cmd_ready/go_idle from runtime_pm
+    - scsi: mpt3sas: Fix calltrace observed while running IO & reset
+    - scsi: mpt3sas: Fix _transport_smp_handler() error path
+    - scsi: sysfs: Introduce sysfs_{un,}break_active_protection()
+    - scsi: core: Avoid that SCSI device removal through sysfs triggers a deadlock
+    - iscsi target: fix session creation failure handling
+    - mtd: rawnand: hynix: Use ->exec_op() in hynix_nand_reg_write_op()
+    - mtd: rawnand: fsmc: Stop using chip->read_buf()
+    - mtd: rawnand: marvell: add suspend and resume hooks
+    - mtd: rawnand: qcom: wait for desc completion in all BAM channels
+    - clk: rockchip: fix clk_i2sout parent selection bits on rk3399
+    - clk: npcm7xx: fix memory allocation
+    - PM / clk: signedness bug in of_pm_clk_add_clks()
+    - power: generic-adc-battery: fix out-of-bounds write when copying channel
+      properties
+    - power: generic-adc-battery: check for duplicate properties copied from iio
+      channels
+    - watchdog: Mark watchdog touch functions as notrace
+    - cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status
+    - x86/dumpstack: Don't dump kernel memory based on usermode RIP
+    - Linux 4.18.6
+    - updateconfigs after v4.18.6 stable update
+
+  * random oopses on s390 systems using NVMe devices (LP: #1790480)
+    - s390/pci: fix out of bounds access during irq setup
+
+  * [18.10 FEAT] zcrypt DD: introduce APQN tags to support deterministic driver
+    binding (LP: #1784331)
+    - s390/zcrypt: code beautify
+    - s390/zcrypt: AP bus support for alternate driver(s)
+    - s390/zcrypt: hex string mask improvements for apmask and aqmask.
+
+  * performance drop with ATS enabled (LP: #1788097)
+    - powerpc/powernv: Fix concurrency issue with npu->mmio_atsd_usage
+
+  * Fix MCE handling for user access of poisoned device-dax mapping
+    (LP: #1774366)
+    - device-dax: Convert to vmf_insert_mixed and vm_fault_t
+    - device-dax: Enable page_mapping()
+    - device-dax: Set page->index
+    - filesystem-dax: Set page->index
+    - mm, madvise_inject_error: Disable MADV_SOFT_OFFLINE for ZONE_DEVICE pages
+    - mm, dev_pagemap: Do not clear ->mapping on final put
+    - mm, madvise_inject_error: Let memory_failure() optionally take a page
+      reference
+    - mm, memory_failure: Collect mapping size in collect_procs()
+    - filesystem-dax: Introduce dax_lock_mapping_entry()
+    - mm, memory_failure: Teach memory_failure() about dev_pagemap pages
+    - x86/mm/pat: Prepare {reserve, free}_memtype() for "decoy" addresses
+    - x86/memory_failure: Introduce {set, clear}_mce_nospec()
+    - libnvdimm, pmem: Restore page attributes when clearing errors
+
+  * Reconcile hns3 SAUCE patches with upstream (LP: #1787477)
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix comments for
+      hclge_get_ring_chain_from_mbx"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for using wrong mask and
+      shift in hclge_get_ring_chain_from_mbx"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for reset_level default
+      assignment probelm"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unnecessary ring
+      configuration operation while resetting"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix return value error in
+      hns3_reset_notify_down_enet"
+    - Revert "UBUNTU: SAUCE: net: hns3: Fix for phy link issue when using marvell
+      phy driver"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: separate roce from nic when
+      resetting"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: correct reset event status
+      register"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: prevent to request reset
+      frequently"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: reset net device with rtnl_lock"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify the order of initializeing
+      command queue register"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: prevent sending command during
+      global or core reset"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Use roce handle when calling roce
+      callback function"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove the warning when clear
+      reset cause"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix get_vector ops in
+      hclgevf_main module"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix warning bug when doing lp
+      selftest"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add configure for mac minimal
+      frame size"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for mailbox message truncated
+      problem"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for l4 checksum offload bug"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for waterline not setting
+      correctly"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for mac pause not disable in
+      pfc mode"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix tc setup when netdev is first
+      up"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add calling roce callback
+      function when link status change"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: optimize the process of notifying
+      roce client"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add pf reset for hip08 RoCE"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add SPDX tags to hns3 driver"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused struct member and
+      definition"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix mislead parameter name"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify inconsistent bit mask
+      macros"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: use decimal for bit offset
+      macros"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix unreasonable code comments"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove extra space and brackets"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: standardize the handle of return
+      value"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some redundant
+      assignments"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify hnae_ to hnae3_"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: use dma_zalloc_coherent instead
+      of kzalloc/dma_map_single"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: give default option while
+      dependency HNS3 set"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some unused members of
+      some structures"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove a redundant
+      hclge_cmd_csq_done"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: using modulo for cyclic counters
+      in hclge_cmd_send"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: simplify hclge_cmd_csq_clean"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some redundant
+      assignments"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove useless code in
+      hclge_cmd_send"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused
+      hclge_ring_to_dma_dir"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: use lower_32_bits and
+      upper_32_bits"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove back in struct hclge_hw"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: add unlikely for error check"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove the Redundant put_vector
+      in hns3_client_uninit"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: print the ret value in error
+      information"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: extraction an interface for state
+      state init|uninit"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused head file in
+      hnae3.c"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: add l4_type check for both ipv4
+      and ipv6"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: add vector status check before
+      free vector"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: rename the interface for
+      init_client_instance and uninit_client_instance"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove hclge_get_vector_index
+      from hclge_bind_ring_with_vector"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: RX BD information valid only in
+      last BD except VLD bit and buffer size"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: add support for serdes loopback
+      selftest"
+    - net: hns3: Updates RX packet info fetch in case of multi BD
+    - net: hns3: remove hclge_get_vector_index from hclge_bind_ring_with_vector
+    - net: hns3: rename the interface for init_client_instance and
+      uninit_client_instance
+    - net: hns3: add vector status check before free vector
+    - net: hns3: add l4_type check for both ipv4 and ipv6
+    - net: hns3: add unlikely for error check
+    - net: hns3: remove unused head file in hnae3.c
+    - net: hns3: extraction an interface for state init|uninit
+    - net: hns3: print the ret value in error information
+    - net: hns3: remove the Redundant put_vector in hns3_client_uninit
+    - net: hns3: remove back in struct hclge_hw
+    - net: hns3: use lower_32_bits and upper_32_bits
+    - net: hns3: remove unused hclge_ring_to_dma_dir
+    - net: hns3: remove useless code in hclge_cmd_send
+    - net: hns3: remove some redundant assignments
+    - net: hns3: simplify hclge_cmd_csq_clean
+    - net: hns3: remove a redundant hclge_cmd_csq_done
+    - net: hns3: remove some unused members of some structures
+    - net: hns3: give default option while dependency HNS3 set
+    - net: hns3: use dma_zalloc_coherent instead of kzalloc/dma_map_single
+    - net: hns3: modify hnae_ to hnae3_
+    - net: hns3: Fix tc setup when netdev is first up
+    - net: hns3: Fix for mac pause not disable in pfc mode
+    - net: hns3: Fix for waterline not setting correctly
+    - net: hns3: Fix for l4 checksum offload bug
+    - net: hns3: Fix for mailbox message truncated problem
+    - net: hns3: Add configure for mac minimal frame size
+    - net: hns3: Fix warning bug when doing lp selftest
+    - net: hns3: Fix get_vector ops in hclgevf_main module
+    - net: hns3: Remove the warning when clear reset cause
+    - net: hns3: Prevent sending command during global or core reset
+    - net: hns3: Modify the order of initializing command queue register
+    - net: hns3: Reset net device with rtnl_lock
+    - net: hns3: Prevent to request reset frequently
+    - net: hns3: Correct reset event status register
+    - net: hns3: Fix return value error in hns3_reset_notify_down_enet
+    - net: hns3: remove unnecessary ring configuration operation while resetting
+    - net: hns3: Fix for reset_level default assignment probelm
+    - net: hns3: Fix for using wrong mask and shift in
+      hclge_get_ring_chain_from_mbx
+    - net: hns3: Fix comments for hclge_get_ring_chain_from_mbx
+    - net: hns3: Remove some redundant assignments
+    - net: hns3: Standardize the handle of return value
+    - net: hns3: Remove extra space and brackets
+    - net: hns3: Correct unreasonable code comments
+    - net: hns3: Use decimal for bit offset macros
+    - net: hns3: Modify inconsistent bit mask macros
+    - net: hns3: Fix misleading parameter name
+    - net: hns3: Remove unused struct member and definition
+    - net: hns3: Add SPDX tags to HNS3 PF driver
+    - net: hns3: Add support for serdes loopback selftest
+    - net: hns3: Fix for phy link issue when using marvell phy driver
+
+  * [Regression] kernel crashdump fails on arm64 (LP: #1786878)
+    - arm64: export memblock_reserve()d regions via /proc/iomem
+    - drivers: acpi: add dependency of EFI for arm64
+    - efi/arm: preserve early mapping of UEFI memory map longer for BGRT
+    - efi/arm: map UEFI memory map even w/o runtime services enabled
+    - arm64: acpi: fix alignment fault in accessing ACPI
+    - [Config] CONFIG_ARCH_SUPPORTS_ACPI=y
+    - arm64: fix ACPI dependencies
+    - ACPI: fix menuconfig presentation of ACPI submenu
+
+  * TB 16 issue on Dell Lattitude 7490 with large amount of data (LP: #1785780)
+    - r8152: disable RX aggregation on new Dell TB16 dock
+
+  * Support Power Management for Thunderbolt Controller  (LP: #1789358)
+    - thunderbolt: Use 64-bit DMA mask if supported by the platform
+    - thunderbolt: Do not unnecessarily call ICM get route
+    - thunderbolt: No need to take tb->lock in domain suspend/complete
+    - thunderbolt: Use correct ICM commands in system suspend
+    - thunderbolt: Add support for runtime PM
+
+  * Enable AMD PCIe MP2 for AMDI0011 (LP: #1773940)
+    - SAUCE: i2c:amd I2C Driver based on PCI Interface for upcoming platform
+    - SAUCE: i2c:amd move out pointer in union i2c_event_base
+    - SAUCE: i2c:amd Depends on ACPI
+    - [Config] i2c: CONFIG_I2C_AMD_MP2=y on x86
+
+  * Microphone cannot be detected with front panel audio combo jack on HP Z8-G4
+    machine (LP: #1789145)
+    - ALSA: hda/realtek - Fix HP Headset Mic can't record
+
+  * Please enable CONFIG_PAGE_POISONING (LP: #1783651)
+    - [Config] Enable CONFIG_PAGE_POISONING configs
+
+  * Tango platform uses __initcall without further checks (LP: #1787945)
+    - [Config] disable ARCH_TANGO
+
+  * [18.10 FEAT] SMC-Direct (LP: #1786902)
+    - net/smc: determine port attributes independent from pnet table
+    - net/smc: add pnetid support
+    - net/smc: add base infrastructure for SMC-D and ISM
+    - net/smc: add pnetid support for SMC-D and ISM
+    - net/smc: add SMC-D support in CLC messages
+    - net/smc: add SMC-D support in data transfer
+    - net/smc: add SMC-D support in af_smc
+    - net/smc: add SMC-D diag support
+    - net/smc: provide smc mode in smc_diag.c
+    - net/smc: eliminate cursor read and write calls
+    - net/smc: add function to get link group from link
+    - net/smc: use DECLARE_BITMAP for rtokens_used_mask
+    - net/smc: remove local variable page in smc_rx_splice()
+    - net/smc: Remove a WARN_ON() statement
+    - net/smc: Simplify ib_post_(send|recv|srq_recv)() calls
+    - net/smc: fewer parameters for smc_llc_send_confirm_link()
+    - net/smc: use correct vlan gid of RoCE device
+    - net/smc: provide fallback reason code
+    - net/smc: improve delete link processing
+    - net: simplify sock_poll_wait
+    - net/smc: send response to test link signal
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations for CONFIG_CRYPTO_SPECK_NEON
+    - [Config] fix up annotatios for CONFIG_CRYPTO_SPECK
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 10 Sep 2018 07:08:38 -0500
+
+linux (4.18.0-7.8) cosmic; urgency=medium
+
+  * linux: 4.18.0-7.8 -proposed tracker (LP: #1789459)
+
+  * pmtu.sh fails on 4.18 kernel (LP: #1789436)
+    - SAUCE: Revert "vti6: fix PMTU caching and reporting on xmit"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 Aug 2018 11:08:51 -0500
+
+linux (4.18.0-6.7) cosmic; urgency=medium
+
+  * linux: 4.18.0-6.7 -proposed tracker (LP: #1788881)
+
+  * systemd 237-3ubuntu10 ADT test failure with linux 4.18.0-5.6 (LP: #1787440)
+    - Config: Disable BPF_JIT_ALWAYS_ON on i386
+
+  * execveat03 in ubuntu_ltp_syscalls failed on X/B (LP: #1786729)
+    - cap_inode_getsecurity: use d_find_any_alias() instead of d_find_alias()
+
+  * Cosmic update to v4.18.5 stable release (LP: #1788874)
+    - EDAC: Add missing MEM_LRDDR4 entry in edac_mem_types[]
+    - pty: fix O_CLOEXEC for TIOCGPTPEER
+    - mm: Allow non-direct-map arguments to free_reserved_area()
+    - x86/mm/init: Pass unconverted symbol addresses to free_init_pages()
+    - x86/mm/init: Add helper for freeing kernel image pages
+    - x86/mm/init: Remove freed kernel image areas from alias mapping
+    - powerpc64s: Show ori31 availability in spectre_v1 sysfs file not v2
+    - ext4: fix spectre gadget in ext4_mb_regular_allocator()
+    - drm/i915/kvmgt: Fix potential Spectre v1
+    - drm/amdgpu/pm: Fix potential Spectre v1
+    - parisc: Remove unnecessary barriers from spinlock.h
+    - parisc: Remove ordered stores from syscall.S
+    - PCI: Restore resized BAR state on resume
+    - PCI / ACPI / PM: Resume all bridges on suspend-to-RAM
+    - PCI: hotplug: Don't leak pci_slot on registration failure
+    - PCI: aardvark: Size bridges before resources allocation
+    - PCI: Skip MPS logic for Virtual Functions (VFs)
+    - PCI: pciehp: Fix use-after-free on unplug
+    - PCI: pciehp: Fix unprotected list iteration in IRQ handler
+    - i2c: core: ACPI: Properly set status byte to 0 for multi-byte writes
+    - i2c: imx: Fix race condition in dma read
+    - reiserfs: fix broken xattr handling (heap corruption, bad retval)
+    - Linux 4.18.5
+
+  * [18.10 FEAT] Add kernel config option "CONFIG_SCLP_OFB" (LP: #1787898)
+    - [Config] CONFIG_SCLP_OFB=y for s390x
+
+  * errors when scanning partition table of corrupted AIX disk (LP: #1787281)
+    - partitions/aix: fix usage of uninitialized lv_info and lvname structures
+    - partitions/aix: append null character to print data from disk
+
+  * Apply NVMe bugfix from Google that bjf asked for (LP: #1787635)
+    - nvme-pci: add a memory barrier to nvme_dbbuf_update_and_check_event
+
+  * ThinkPad systems have no HDMI sound when using the nvidia GPU (LP: #1787058)
+    - ACPI / OSI: Add OEM _OSI string to enable NVidia HDMI audio
+
+  * Cosmic update to v4.18.4 stable release (LP: #1788454)
+    - l2tp: use sk_dst_check() to avoid race on sk->sk_dst_cache
+    - net_sched: fix NULL pointer dereference when delete tcindex filter
+    - net_sched: Fix missing res info when create new tc_index filter
+    - r8169: don't use MSI-X on RTL8168g
+    - ALSA: hda - Sleep for 10ms after entering D3 on Conexant codecs
+    - ALSA: hda - Turn CX8200 into D3 as well upon reboot
+    - ALSA: vx222: Fix invalid endian conversions
+    - ALSA: virmidi: Fix too long output trigger loop
+    - ALSA: cs5535audio: Fix invalid endian conversion
+    - ALSA: dice: fix wrong copy to rx parameters for Alesis iO26
+    - ALSA: hda: Correct Asrock B85M-ITX power_save blacklist entry
+    - ALSA: memalloc: Don't exceed over the requested size
+    - ALSA: vxpocket: Fix invalid endian conversions
+    - ALSA: seq: Fix poll() error return
+    - media: gl861: fix probe of dvb_usb_gl861
+    - USB: serial: sierra: fix potential deadlock at close
+    - USB: serial: pl2303: add a new device id for ATEN
+    - USB: option: add support for DW5821e
+    - ACPI / PM: save NVS memory for ASUS 1025C laptop
+    - tty: serial: 8250: Revert NXP SC16C2552 workaround
+    - serial: 8250_exar: Read INT0 from slave device, too
+    - serial: 8250_dw: always set baud rate in dw8250_set_termios
+    - serial: 8250_dw: Add ACPI support for uart on Broadcom SoC
+    - uio: fix wrong return value from uio_mmap()
+    - misc: sram: fix resource leaks in probe error path
+    - Revert "uio: use request_threaded_irq instead"
+    - Bluetooth: avoid killing an already killed socket
+    - isdn: Disable IIOCDBGVAR
+    - net: sock_diag: Fix spectre v1 gadget in __sock_diag_cmd()
+    - hv/netvsc: Fix NULL dereference at single queue mode fallback
+    - r8169: don't use MSI-X on RTL8106e
+    - ip_vti: fix a null pointer deferrence when create vti fallback tunnel
+    - net: ethernet: mvneta: Fix napi structure mixup on armada 3700
+    - net: mvneta: fix mvneta_config_rss on armada 3700
+    - cls_matchall: fix tcf_unbind_filter missing
+    - Linux 4.18.4
+
+  * Cosmic update to v4.18.3 stable release (LP: #1788453)
+    - x86/speculation/l1tf: Exempt zeroed PTEs from inversion
+    - Linux 4.18.3
+
+  * Cosmic update to v4.18.2 stable release (LP: #1788452)
+    - x86/l1tf: Fix build error seen if CONFIG_KVM_INTEL is disabled
+    - x86: i8259: Add missing include file
+    - x86/hyper-v: Check for VP_INVAL in hyperv_flush_tlb_others()
+    - x86/platform/UV: Mark memblock related init code and data correctly
+    - x86/mm/pti: Clear Global bit more aggressively
+    - xen/pv: Call get_cpu_address_sizes to set x86_virt/phys_bits
+    - x86/mm: Disable ioremap free page handling on x86-PAE
+    - kbuild: verify that $DEPMOD is installed
+    - crypto: ccree - fix finup
+    - crypto: ccree - fix iv handling
+    - crypto: ccp - Check for NULL PSP pointer at module unload
+    - crypto: ccp - Fix command completion detection race
+    - crypto: x86/sha256-mb - fix digest copy in sha256_mb_mgr_get_comp_job_avx2()
+    - crypto: vmac - require a block cipher with 128-bit block size
+    - crypto: vmac - separate tfm and request context
+    - crypto: blkcipher - fix crash flushing dcache in error path
+    - crypto: ablkcipher - fix crash flushing dcache in error path
+    - crypto: skcipher - fix aligning block size in skcipher_copy_iv()
+    - crypto: skcipher - fix crash flushing dcache in error path
+    - ioremap: Update pgtable free interfaces with addr
+    - x86/mm: Add TLB purge to free pmd/pte page interfaces
+    - Linux 4.18.2
+
+  * Cosmic update to v4.18.2 stable release (LP: #1788452) // CVE-2018-9363
+    - Bluetooth: hidp: buffer overflow in hidp_process_report
+
+  * linux-cloud-tools-common: Ensure hv-kvp-daemon.service starts before
+    walinuxagent.service (LP: #1739107)
+    - [Debian] hyper-v -- Ensure that hv-kvp-daemon.service starts before
+      walinuxagent.service
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: ipvs: remove nbsp characters from Kconfig
+    - [Config] CONFIG_MPROFILE_KERNEL=y for ppc64el
+    - [Config] CONFIG_DRM_RCAR_LVDS=m for snapdragon
+    - [Config] CONFIG_MDIO_MSCC_MIIM=n for s390x
+    - [Config] CONFIG_NET_VENDOR_MICROSEMI=n, CONFIG_NET_VENDOR_NI=n for s390x
+    - [Config] update annotations following config review
+    - [Debian] set CROSS_COMPILE when generating kernel configs
+    - [Config] Disable the Speck cipher
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 24 Aug 2018 14:18:15 -0500
+
+linux (4.18.0-5.6) cosmic; urgency=medium
+
+  * Cosmic update to v4.18.1 stable release (LP: #1787264)
+    - x86/paravirt: Fix spectre-v2 mitigations for paravirt guests
+    - x86/speculation: Protect against userspace-userspace spectreRSB
+    - kprobes/x86: Fix %p uses in error messages
+    - x86/irqflags: Provide a declaration for native_save_fl
+    - x86/speculation/l1tf: Increase 32bit PAE __PHYSICAL_PAGE_SHIFT
+    - x86/speculation/l1tf: Change order of offset/type in swap entry
+    - x86/speculation/l1tf: Protect swap entries against L1TF
+    - x86/speculation/l1tf: Protect PROT_NONE PTEs against speculation
+    - x86/speculation/l1tf: Make sure the first page is always reserved
+    - x86/speculation/l1tf: Add sysfs reporting for l1tf
+    - x86/speculation/l1tf: Disallow non privileged high MMIO PROT_NONE mappings
+    - x86/speculation/l1tf: Limit swap file size to MAX_PA/2
+    - x86/bugs: Move the l1tf function and define pr_fmt properly
+    - sched/smt: Update sched_smt_present at runtime
+    - x86/smp: Provide topology_is_primary_thread()
+    - x86/topology: Provide topology_smt_supported()
+    - cpu/hotplug: Make bringup/teardown of smp threads symmetric
+    - cpu/hotplug: Split do_cpu_down()
+    - cpu/hotplug: Provide knobs to control SMT
+    - x86/cpu: Remove the pointless CPU printout
+    - x86/cpu/AMD: Remove the pointless detect_ht() call
+    - x86/cpu/common: Provide detect_ht_early()
+    - x86/cpu/topology: Provide detect_extended_topology_early()
+    - x86/cpu/intel: Evaluate smp_num_siblings early
+    - x86/CPU/AMD: Do not check CPUID max ext level before parsing SMP info
+    - x86/cpu/AMD: Evaluate smp_num_siblings early
+    - x86/apic: Ignore secondary threads if nosmt=force
+    - x86/speculation/l1tf: Extend 64bit swap file size limit
+    - x86/cpufeatures: Add detection of L1D cache flush support.
+    - x86/CPU/AMD: Move TOPOEXT reenablement before reading smp_num_siblings
+    - x86/speculation/l1tf: Protect PAE swap entries against L1TF
+    - x86/speculation/l1tf: Fix up pte->pfn conversion for PAE
+    - Revert "x86/apic: Ignore secondary threads if nosmt=force"
+    - cpu/hotplug: Boot HT siblings at least once
+    - x86/KVM: Warn user if KVM is loaded SMT and L1TF CPU bug being present
+    - x86/KVM/VMX: Add module argument for L1TF mitigation
+    - x86/KVM/VMX: Add L1D flush algorithm
+    - x86/KVM/VMX: Add L1D MSR based flush
+    - x86/KVM/VMX: Add L1D flush logic
+    - x86/KVM/VMX: Split the VMX MSR LOAD structures to have an host/guest numbers
+    - x86/KVM/VMX: Add find_msr() helper function
+    - x86/KVM/VMX: Separate the VMX AUTOLOAD guest/host number accounting
+    - x86/KVM/VMX: Extend add_atomic_switch_msr() to allow VMENTER only MSRs
+    - x86/KVM/VMX: Use MSR save list for IA32_FLUSH_CMD if required
+    - cpu/hotplug: Online siblings when SMT control is turned on
+    - x86/litf: Introduce vmx status variable
+    - x86/kvm: Drop L1TF MSR list approach
+    - x86/l1tf: Handle EPT disabled state proper
+    - x86/kvm: Move l1tf setup function
+    - x86/kvm: Add static key for flush always
+    - x86/kvm: Serialize L1D flush parameter setter
+    - x86/kvm: Allow runtime control of L1D flush
+    - cpu/hotplug: Expose SMT control init function
+    - cpu/hotplug: Set CPU_SMT_NOT_SUPPORTED early
+    - x86/bugs, kvm: Introduce boot-time control of L1TF mitigations
+    - Documentation: Add section about CPU vulnerabilities
+    - x86/speculation/l1tf: Unbreak !__HAVE_ARCH_PFN_MODIFY_ALLOWED architectures
+    - x86/KVM/VMX: Initialize the vmx_l1d_flush_pages' content
+    - Documentation/l1tf: Fix typos
+    - cpu/hotplug: detect SMT disabled by BIOS
+    - x86/KVM/VMX: Don't set l1tf_flush_l1d to true from vmx_l1d_flush()
+    - x86/KVM/VMX: Replace 'vmx_l1d_flush_always' with 'vmx_l1d_flush_cond'
+    - x86/KVM/VMX: Move the l1tf_flush_l1d test to vmx_l1d_flush()
+    - x86/irq: Demote irq_cpustat_t::__softirq_pending to u16
+    - x86/KVM/VMX: Introduce per-host-cpu analogue of l1tf_flush_l1d
+    - x86: Don't include linux/irq.h from asm/hardirq.h
+    - x86/irq: Let interrupt handlers set kvm_cpu_l1tf_flush_l1d
+    - x86/KVM/VMX: Don't set l1tf_flush_l1d from vmx_handle_external_intr()
+    - Documentation/l1tf: Remove Yonah processors from not vulnerable list
+    - x86/speculation: Simplify sysfs report of VMX L1TF vulnerability
+    - x86/speculation: Use ARCH_CAPABILITIES to skip L1D flush on vmentry
+    - KVM: VMX: Tell the nested hypervisor to skip L1D flush on vmentry
+    - cpu/hotplug: Fix SMT supported evaluation
+    - x86/speculation/l1tf: Invert all not present mappings
+    - x86/speculation/l1tf: Make pmd/pud_mknotpresent() invert
+    - x86/mm/pat: Make set_memory_np() L1TF safe
+    - x86/mm/kmmio: Make the tracer robust against L1TF
+    - tools headers: Synchronise x86 cpufeatures.h for L1TF additions
+    - x86/microcode: Allow late microcode loading with SMT disabled
+    - x86/smp: fix non-SMP broken build due to redefinition of
+      apic_id_is_primary_thread
+    - cpu/hotplug: Non-SMP machines do not make use of booted_once
+    - x86/init: fix build with CONFIG_SWAP=n
+    - Linux 4.18.1
+    - [Config] updateconfigs after v4.18.1 stable update
+
+  * Consider enabling CONFIG_NETWORK_PHY_TIMESTAMPING (LP: #1785816)
+    - [Config] Enable timestamping in network PHY devices
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_SYSCTL_SYSCALL=n
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 15 Aug 2018 14:20:59 -0500
+
+linux (4.18.0-4.5) cosmic; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 06 Aug 2018 13:54:02 -0500
+
+linux (4.18.0-3.4) cosmic; urgency=medium
+
+  * Suspend fails in Ubuntu and Kubuntu 18.04 but works fine in Ubuntu and
+    Kubuntu 17.10 (and on Kubuntu 18.04 using kernel 4.14.47) (LP: #1774950)
+    - ACPI / LPSS: Avoid PM quirks on suspend and resume from hibernation
+
+  * hinic interfaces aren't getting predictable names (LP: #1783138)
+    - hinic: Link the logical network device to the pci device in sysfs
+
+  * libvirtd is unable to configure bridge devices inside of LXD containers
+    (LP: #1784501)
+    - kernfs: allow creating kernfs objects with arbitrary uid/gid
+    - sysfs, kobject: allow creating kobject belonging to arbitrary users
+    - kobject: kset_create_and_add() - fetch ownership info from parent
+    - driver core: set up ownership of class devices in sysfs
+    - net-sysfs: require net admin in the init ns for setting tx_maxrate
+    - net-sysfs: make sure objects belong to container's owner
+    - net: create reusable function for getting ownership info of sysfs inodes
+    - bridge: make sure objects belong to container's owner
+    - sysfs: Fix regression when adding a file to an existing group
+
+  * locking sockets broken due to missing AppArmor socket mediation patches
+    (LP: #1780227)
+    - UBUNTU SAUCE: apparmor: fix apparmor mediating locking non-fs, unix sockets
+
+  * Update2 for ocxl driver (LP: #1781436)
+    - ocxl: Fix page fault handler in case of fault on dying process
+
+  * HDMI/DP audio can't work on the laptop of Dell Latitude 5495 (LP: #1782689)
+    - ALSA: hda: use PCI_BASE_CLASS_DISPLAY to replace PCI_CLASS_DISPLAY_VGA
+    - vga_switcheroo: set audio client id according to bound GPU id
+
+  * Allow Raven Ridge's audio controller to be runtime suspended (LP: #1782540)
+    - ALSA: hda: Add AZX_DCAPS_PM_RUNTIME for AMD Raven Ridge
+
+  * Invoking obsolete 'firmware_install' target breaks snap build (LP: #1782166)
+    - snapcraft.yaml: stop invoking the obsolete (and non-existing)
+      'firmware_install' target
+
+  * snapcraft.yaml: missing ubuntu-retpoline-extract-one script breaks the build
+    (LP: #1782116)
+    - snapcraft.yaml: copy retpoline-extract-one to scripts before build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 01 Aug 2018 08:49:40 -0500
+
+linux (4.18.0-2.3) cosmic; urgency=medium
+
+  * Kernel error "task zfs:pid blocked for more than 120 seconds" (LP: #1781364)
+    - SAUCE: (noup) zfs to 0.7.9-3ubuntu4
+
+  * [Regression] EXT4-fs error (device sda1): ext4_validate_inode_bitmap:99:
+    comm stress-ng: Corrupt inode bitmap (LP: #1780137)
+    - SAUCE: ext4: fix ext4_validate_inode_bitmap: comm stress-ng: Corrupt inode
+      bitmap
+
+  * Cloud-init causes potentially huge boot delays with 4.15 kernels
+    (LP: #1780062)
+    - random: Make getrandom() ready earlier
+
+  * hisi_sas_v3_hw: internal task abort: timeout and not done. (LP: #1777736)
+    - scsi: hisi_sas: Update a couple of register settings for v3 hw
+
+  * hisi_sas: Add missing PHY spinlock init (LP: #1777734)
+    - scsi: hisi_sas: Add missing PHY spinlock init
+
+  * hisi_sas: improve read performance by pre-allocating slot DMA buffers
+    (LP: #1777727)
+    - scsi: hisi_sas: Use dmam_alloc_coherent()
+    - scsi: hisi_sas: Pre-allocate slot DMA buffers
+
+  * hisi_sas: Failures during host reset (LP: #1777696)
+    - scsi: hisi_sas: Only process broadcast change in phy_bcast_v3_hw()
+    - scsi: hisi_sas: Fix the conflict between dev gone and host reset
+    - scsi: hisi_sas: Adjust task reject period during host reset
+    - scsi: hisi_sas: Add a flag to filter PHY events during reset
+    - scsi: hisi_sas: Release all remaining resources in clear nexus ha
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.9-3ubuntu2, zfs to 0.7.9-3ubuntu3
+    - SAUCE: mm: Fix exports that inadvertently make put_page() EXPORT_SYMBOL_GPL
+    - Enable zfs build
+    - SAUCE: Import aufs driver
+    - Revert "UBUNTU: [Config]: set CONFIG_EDAC_DEBUG=y for ARM64"
+    - [Config] retpoline -- review and accept retpoline changes
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc5
+  * Rebase to v4.18-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 24 Jul 2018 08:41:22 -0500
+
+linux (4.18.0-1.2) cosmic; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 09 Jul 2018 07:36:31 -0500
+
+linux (4.18.0-0.1) cosmic; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu -- disable vbox build
+    - Disable zfs build
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) ima: require secure_boot rules in lockdown mode
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) efi: Add EFI signature data types
+    - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) lockdown: fix coordination of kernel module signature
+      verification
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) efi: Don't print secure boot state from the efi stub
+    - SAUCE: (namespace) block_dev: Support checking inode permissions in
+      lookup_bdev()
+    - SAUCE: (namespace) block_dev: Check permissions towards block device inode
+      when mounting
+    - SAUCE: (namespace) mtd: Check permissions towards mtd block device inode
+      when mounting
+    - SAUCE: (namespace) ext4: Add support for unprivileged mounts from user
+      namespaces
+    - SAUCE: (namespace) ext4: Add module parameter to enable user namespace
+      mounts
+    - SAUCE: (namespace) block_dev: Forbid unprivileged mounting when device is
+      opened for writing
+    - SAUCE: Import aufs driver
+    - Update dropped.txt
+    - [Config] updateconfigs after 4.18-rc3 rebase
+    - SAUCE: (no-up): ASoC: Intel: bytcr-rt5660: Remove snd_soc_codec use for 4.18
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 06 Jul 2018 10:46:37 -0500
+
+linux (4.18.0-0.0) cosmic; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 03 Jul 2018 11:10:33 -0500
+
+linux (4.17.0-4.5) cosmic; urgency=medium
+
+  * linux: 4.17.0-4.5 -proposed tracker (LP: #1779399)
+
+  * Update to ocxl driver for 18.04.1 (LP: #1775786)
+    - powerpc: Add TIDR CPU feature for POWER9
+    - powerpc: Use TIDR CPU feature to control TIDR allocation
+    - powerpc: use task_pid_nr() for TID allocation
+    - ocxl: Rename pnv_ocxl_spa_remove_pe to clarify it's action
+    - ocxl: Expose the thread_id needed for wait on POWER9
+    - ocxl: Add an IOCTL so userspace knows what OCXL features are available
+    - ocxl: Document new OCXL IOCTLs
+    - ocxl: Fix missing unlock on error in afu_ioctl_enable_p9_wait()
+
+  * Please include ax88179_178a and r8152 modules in d-i udeb (LP: #1771823)
+    - [Config:] d-i: Add ax88179_178a and r8152 to nic-modules
+
+  * glibc pkeys test fail on powerpc (LP: #1776967)
+    - [Config] Temporarily disable CONFIG_PPC_MEM_KEYS
+
+  * After update to 4.13-43 Intel Graphics are Laggy (LP: #1773520)
+    - Revert "drm/i915/edp: Allow alternate fixed mode for eDP if available."
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.9-3ubuntu1, zfs to 0.7.9-3ubuntu1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 29 Jun 2018 13:37:52 -0500
+
+linux (4.17.0-3.4) cosmic; urgency=medium
+
+  * linux: 4.17.0-3.4 -proposed tracker (LP: #1779124)
+
+  * Cosmic update to v4.17.3 stable release (LP: #1778997)
+    - net: aquantia: fix unsigned numvecs comparison with less than zero
+    - bonding: re-evaluate force_primary when the primary slave name changes
+    - cdc_ncm: avoid padding beyond end of skb
+    - ipv6: allow PMTU exceptions to local routes
+    - net: dsa: add error handling for pskb_trim_rcsum
+    - net: phy: dp83822: use BMCR_ANENABLE instead of BMSR_ANEGCAPABLE for DP83620
+    - net/sched: act_simple: fix parsing of TCA_DEF_DATA
+    - tcp: verify the checksum of the first data segment in a new connection
+    - tls: fix use-after-free in tls_push_record
+    - tls: fix waitall behavior in tls_sw_recvmsg
+    - socket: close race condition between sock_close() and sockfs_setattr()
+    - udp: fix rx queue len reported by diag and proc interface
+    - net: in virtio_net_hdr only add VLAN_HLEN to csum_start if payload holds
+      vlan
+    - hv_netvsc: Fix a network regression after ifdown/ifup
+    - ACPICA: AML parser: attempt to continue loading table after error
+    - ext4: fix hole length detection in ext4_ind_map_blocks()
+    - ext4: update mtime in ext4_punch_hole even if no blocks are released
+    - ext4: do not allow external inodes for inline data
+    - ext4: bubble errors from ext4_find_inline_data_nolock() up to ext4_iget()
+    - ext4: correctly handle a zero-length xattr with a non-zero e_value_offs
+    - ext4: fix fencepost error in check for inode count overflow during resize
+    - driver core: Don't ignore class_dir_create_and_add() failure.
+    - Btrfs: allow empty subvol= again
+    - Btrfs: fix clone vs chattr NODATASUM race
+    - Btrfs: fix memory and mount leak in btrfs_ioctl_rm_dev_v2()
+    - btrfs: return error value if create_io_em failed in cow_file_range
+    - btrfs: scrub: Don't use inode pages for device replace
+    - ALSA: usb-audio: Disable the quirk for Nura headset
+    - ALSA: hda/conexant - Add fixup for HP Z2 G4 workstation
+    - ALSA: hda - Handle kzalloc() failure in snd_hda_attach_pcm_stream()
+    - ALSA: hda: add dock and led support for HP EliteBook 830 G5
+    - ALSA: hda: add dock and led support for HP ProBook 640 G4
+    - x86/MCE: Fix stack out-of-bounds write in mce-inject.c: Flags_read()
+    - smb3: fix various xid leaks
+    - smb3: on reconnect set PreviousSessionId field
+    - CIFS: 511c54a2f69195b28afb9dd119f03787b1625bb4 adds a check for session
+      expiry
+    - cifs: For SMB2 security informaion query, check for minimum sized security
+      descriptor instead of sizeof FileAllInformation class
+    - nbd: fix nbd device deletion
+    - nbd: update size when connected
+    - nbd: use bd_set_size when updating disk size
+    - blk-mq: reinit q->tag_set_list entry only after grace period
+    - bdi: Move cgroup bdi_writeback to a dedicated low concurrency workqueue
+    - cpufreq: Fix new policy initialization during limits updates via sysfs
+    - cpufreq: ti-cpufreq: Fix an incorrect error return value
+    - cpufreq: governors: Fix long idle detection logic in load calculation
+    - libata: zpodd: small read overflow in eject_tray()
+    - libata: Drop SanDisk SD7UB3Q*G1001 NOLPM quirk
+    - nvme/pci: Sync controller reset for AER slot_reset
+    - w1: mxc_w1: Enable clock before calling clk_get_rate() on it
+    - x86/vector: Fix the args of vector_alloc tracepoint
+    - x86/apic/vector: Prevent hlist corruption and leaks
+    - x86/apic: Provide apic_ack_irq()
+    - x86/ioapic: Use apic_ack_irq()
+    - x86/platform/uv: Use apic_ack_irq()
+    - irq_remapping: Use apic_ack_irq()
+    - genirq/generic_pending: Do not lose pending affinity update
+    - genirq/affinity: Defer affinity setting if irq chip is busy
+    - genirq/migration: Avoid out of line call if pending is not set
+    - x86/intel_rdt: Enable CMT and MBM on new Skylake stepping
+    - media: uvcvideo: Prevent setting unavailable flags
+    - media: rc: ensure input/lirc device can be opened after register
+    - iwlwifi: fw: harden page loading code
+    - orangefs: set i_size on new symlink
+    - orangefs: report attributes_mask and attributes for statx
+    - HID: intel_ish-hid: ipc: register more pm callbacks to support hibernation
+    - HID: wacom: Correct logical maximum Y for 2nd-gen Intuos Pro large
+    - vhost: fix info leak due to uninitialized memory
+    - mm, page_alloc: do not break __GFP_THISNODE by zonelist reset
+    - Linux 4.17.3
+
+  * Use-after-free in sk_peer_label (LP: #1778646)
+    - SAUCE: apparmor: fix use after free in sk_peer_label
+
+  * kernel: Fix memory leak on CCA and EP11 CPRB processing. (LP: #1775390)
+    - s390/zcrypt: Fix CCA and EP11 CPRB processing failure memory leak.
+
+  * Various fixes for CXL kernel module (LP: #1774471)
+    - cxl: Configure PSL to not use APC virtual machines
+    - cxl: Disable prefault_mode in Radix mode
+
+  * Bluetooth not working (LP: #1764645)
+    - Bluetooth: btusb: Apply QCA Rome patches for some ATH3012 models
+
+  * Fake SAS addresses for SATA disks on HiSilicon D05 are non-unique
+    (LP: #1776750)
+    - scsi: hisi_sas: make SAS address of SATA disks unique
+
+  * linux-snapdragon: wcn36xx: mac address generation on boot (LP: #1776491)
+    - [Config] arm64: snapdragon: WCN36XX_SNAPDRAGON_HACKS=y
+    - SAUCE: wcn36xx: read MAC from file or randomly generate one
+
+  * Lenovo V330 needs patch in ideapad_laptop module for rfkill (LP: #1774636)
+    - SAUCE: Add Lenovo V330 to the ideapad_laptop rfkill blacklist
+
+  * register on binfmt_misc may overflow and crash the system (LP: #1775856)
+    - fs/binfmt_misc.c: do not allow offset overflow
+
+  * Network installs fail on SocioNext board (LP: #1775884)
+    - net: socionext: reset hardware in ndo_stop
+    - net: netsec: enable tx-irq during open callback
+
+  * Fix several bugs in RDMA/hns driver (LP: #1770974)
+    - RDMA/hns: Drop local zgid in favor of core defined variable
+    - RDMA/hns: Add 64KB page size support for hip08
+    - RDMA/hns: Rename the idx field of db
+    - RDMA/hns: Modify uar allocation algorithm to avoid bitmap exhaust
+    - RDMA/hns: Increase checking CMQ status timeout value
+    - RDMA/hns: Add reset process for RoCE in hip08
+    - RDMA/hns: Fix the illegal memory operation when cross page
+    - RDMA/hns: Implement the disassociate_ucontext API
+
+  * powerpc/livepatch: Implement reliable stack tracing for the consistency
+    model (LP: #1771844)
+    - powerpc/livepatch: Implement reliable stack tracing for the consistency
+      model
+
+  * Adding back alx WoL feature (LP: #1772610)
+    - SAUCE: Revert "alx: remove WoL support"
+    - SAUCE: alx: add enable_wol paramenter
+
+  * Lancer A0 Asic HBA's won't boot with 18.04 (LP: #1768103)
+    - scsi: lpfc: Fix WQ/CQ creation for older asic's.
+    - scsi: lpfc: Fix 16gb hbas failing cq create.
+
+  * [LTCTest][OPAL][OP920] cpupower idle-info is not listing stop4 and stop5
+    idle states when all CORES are guarded (LP: #1771780)
+    - powerpc/powernv/cpuidle: Init all present cpus for deep states
+
+  * Huawei 25G/100G Network Adapters Unsupported (LP: #1770970)
+    - net-next/hinic: add pci device ids for 25ge and 100ge card
+
+  * Expose arm64 CPU topology to userspace (LP: #1770231)
+    - drivers: base: cacheinfo: move cache_setup_of_node()
+    - drivers: base: cacheinfo: setup DT cache properties early
+    - cacheinfo: rename of_node to fw_token
+    - arm64/acpi: Create arch specific cpu to acpi id helper
+    - ACPI/PPTT: Add Processor Properties Topology Table parsing
+    - [Config] CONFIG_ACPI_PPTT=y
+    - ACPI: Enable PPTT support on ARM64
+    - drivers: base cacheinfo: Add support for ACPI based firmware tables
+    - arm64: Add support for ACPI based firmware tables
+    - arm64: topology: rename cluster_id
+    - arm64: topology: enable ACPI/PPTT based CPU topology
+    - ACPI: Add PPTT to injectable table list
+    - arm64: topology: divorce MC scheduling domain from core_siblings
+
+  * Vcs-Git header on bionic linux source package points to zesty git tree
+    (LP: #1766055)
+    - [Packaging]: Update Vcs-Git
+
+  * Request to revert SAUCE patches in the 18.04 SRU and update with upstream
+    version (LP: #1768431)
+    - scsi: cxlflash: Handle spurious interrupts
+    - scsi: cxlflash: Remove commmands from pending list on timeout
+    - scsi: cxlflash: Synchronize reset and remove ops
+    - SAUCE: (no-up) cxlflash: OCXL diff between v2 and v3
+
+  * hisi_sas robustness fixes (LP: #1774466)
+    - scsi: hisi_sas: delete timer when removing hisi_sas driver
+    - scsi: hisi_sas: print device id for errors
+    - scsi: hisi_sas: Add some checks to avoid free'ing a sas_task twice
+    - scsi: hisi_sas: check host frozen before calling "done" function
+    - scsi: hisi_sas: check sas_dev gone earlier in hisi_sas_abort_task()
+    - scsi: hisi_sas: stop controller timer for reset
+    - scsi: hisi_sas: update PHY linkrate after a controller reset
+    - scsi: hisi_sas: change slot index allocation mode
+    - scsi: hisi_sas: Change common allocation mode of device id
+    - scsi: hisi_sas: Reset disks when discovered
+    - scsi: hisi_sas: Create a scsi_host_template per HW module
+    - scsi: hisi_sas: Init disks after controller reset
+    - scsi: hisi_sas: Try wait commands before before controller reset
+    - scsi: hisi_sas: Include TMF elements in struct hisi_sas_slot
+    - scsi: hisi_sas: Add v2 hw force PHY function for internal ATA command
+    - scsi: hisi_sas: Terminate STP reject quickly for v2 hw
+    - scsi: hisi_sas: Fix return value when get_free_slot() failed
+    - scsi: hisi_sas: Mark PHY as in reset for nexus reset
+
+  * hisi_sas: Support newer v3 hardware (LP: #1774467)
+    - scsi: hisi_sas: update RAS feature for later revision of v3 HW
+    - scsi: hisi_sas: check IPTT is valid before using it for v3 hw
+    - scsi: hisi_sas: fix PI memory size
+    - scsi: hisi_sas: config ATA de-reset as an constrained command for v3 hw
+    - scsi: hisi_sas: remove redundant handling to event95 for v3
+    - scsi: hisi_sas: add readl poll timeout helper wrappers
+    - scsi: hisi_sas: workaround a v3 hw hilink bug
+    - scsi: hisi_sas: Add LED feature for v3 hw
+
+  * hisi_sas: improve performance by optimizing DQ locking (LP: #1774472)
+    - scsi: hisi_sas: optimise the usage of DQ locking
+    - scsi: hisi_sas: relocate smp sg map
+    - scsi: hisi_sas: make return type of prep functions void
+    - scsi: hisi_sas: allocate slot buffer earlier
+    - scsi: hisi_sas: Don't lock DQ for complete task sending
+    - scsi: hisi_sas: Use device lock to protect slot alloc/free
+    - scsi: hisi_sas: add check of device in hisi_sas_task_exec()
+    - scsi: hisi_sas: fix a typo in hisi_sas_task_prep()
+
+  * FS-Cache: Assertion failed: FS-Cache: 6 == 5 is false (LP: #1774336)
+    - SAUCE: CacheFiles: fix a read_waiter/read_copier race
+
+  * enable mic-mute hotkey and led on Lenovo M820z and M920z (LP: #1774306)
+    - ALSA: hda/realtek - Enable mic-mute hotkey for several Lenovo AIOs
+
+  * hns3 driver updates (LP: #1768670)
+    - net: hns3: Remove error log when getting pfc stats fails
+    - net: hns3: fix to correctly fetch l4 protocol outer header
+    - net: hns3: Fixes the out of bounds access in hclge_map_tqp
+    - net: hns3: Fixes the error legs in hclge_init_ae_dev function
+    - net: hns3: fix for phy_addr error in hclge_mac_mdio_config
+    - net: hns3: Fix to support autoneg only for port attached with phy
+    - net: hns3: fix a dead loop in hclge_cmd_csq_clean
+    - net: hns3: Fix for packet loss due wrong filter config in VLAN tbls
+    - net: hns3: Remove packet statistics in the range of 8192~12287
+    - net: hns3: Add support of hardware rx-vlan-offload to HNS3 VF driver
+    - net: hns3: Fix for setting mac address when resetting
+    - net: hns3: remove add/del_tunnel_udp in hns3_enet module
+    - net: hns3: fix for cleaning ring problem
+    - net: hns3: refactor the loopback related function
+    - net: hns3: Fix for deadlock problem occurring when unregistering ae_algo
+    - net: hns3: Fix for the null pointer problem occurring when initializing
+      ae_dev failed
+    - net: hns3: Add a check for client instance init state
+    - net: hns3: Change return type of hnae3_register_ae_dev
+    - net: hns3: Change return type of hnae3_register_ae_algo
+    - net: hns3: Change return value in hnae3_register_client
+    - net: hns3: Fixes the back pressure setting when sriov is enabled
+    - net: hns3: Fix for fiber link up problem
+    - net: hns3: Add support of .sriov_configure in HNS3 driver
+    - net: hns3: Fixes the missing PCI iounmap for various legs
+    - net: hns3: Fixes error reported by Kbuild and internal review
+    - net: hns3: Fixes API to fetch ethernet header length with kernel default
+    - net: hns3: cleanup of return values in hclge_init_client_instance()
+    - net: hns3: Fix the missing client list node initialization
+    - net: hns3: Fix for hns3 module is loaded multiple times problem
+    - net: hns3: Use enums instead of magic number in hclge_is_special_opcode
+    - net: hns3: Fix for netdev not running problem after calling net_stop and
+      net_open
+    - net: hns3: Fixes kernel panic issue during rmmod hns3 driver
+    - net: hns3: Fix for CMDQ and Misc. interrupt init order problem
+    - net: hns3: Updates RX packet info fetch in case of multi BD
+    - net: hns3: Add support for tx_accept_tag2 and tx_accept_untag2 config
+    - net: hns3: Add STRP_TAGP field support for hardware revision 0x21
+    - net: hns3: Add support to enable TX/RX promisc mode for H/W rev(0x21)
+    - net: hns3: Fix for PF mailbox receving unknown message
+    - net: hns3: Fixes the state to indicate client-type initialization
+    - net: hns3: Fixes the init of the VALID BD info in the descriptor
+    - net: hns3: Removes unnecessary check when clearing TX/RX rings
+    - net: hns3: Clear TX/RX rings when stopping port & un-initializing client
+    - net: hns3: Remove unused led control code
+    - net: hns3: Adds support for led locate command for copper port
+    - net: hns3: Fixes initalization of RoCE handle and makes it conditional
+    - net: hns3: Disable vf vlan filter when vf vlan table is full
+    - net: hns3: Add support for IFF_ALLMULTI flag
+    - net: hns3: Add repeat address checking for setting mac address
+    - net: hns3: Fix setting mac address error
+    - net: hns3: Fix for service_task not running problem after resetting
+    - net: hns3: Fix for hclge_reset running repeatly problem
+    - net: hns3: Fix for phy not link up problem after resetting
+    - net: hns3: Add missing break in misc_irq_handle
+    - net: hns3: Fix for vxlan tx checksum bug
+    - net: hns3: Optimize the PF's process of updating multicast MAC
+    - net: hns3: Optimize the VF's process of updating multicast MAC
+    - SAUCE: {topost} net: hns3: add support for serdes loopback selftest
+    - SAUCE: {topost} net: hns3: RX BD information valid only in last BD except
+      VLD bit and buffer size
+    - SAUCE: {topost} net: hns3: remove hclge_get_vector_index from
+      hclge_bind_ring_with_vector
+    - SAUCE: {topost} net: hns3: rename the interface for init_client_instance and
+      uninit_client_instance
+    - SAUCE: {topost} net: hns3: add vector status check before free vector
+    - SAUCE: {topost} net: hns3: add l4_type check for both ipv4 and ipv6
+    - SAUCE: {topost} net: hns3: remove unused head file in hnae3.c
+    - SAUCE: {topost} net: hns3: extraction an interface for state state
+      init|uninit
+    - SAUCE: {topost} net: hns3: print the ret value in error information
+    - SAUCE: {topost} net: hns3: remove the Redundant put_vector in
+      hns3_client_uninit
+    - SAUCE: {topost} net: hns3: add unlikely for error check
+    - SAUCE: {topost} net: hns3: remove back in struct hclge_hw
+    - SAUCE: {topost} net: hns3: use lower_32_bits and upper_32_bits
+    - SAUCE: {topost} net: hns3: remove unused hclge_ring_to_dma_dir
+    - SAUCE: {topost} net: hns3: remove useless code in hclge_cmd_send
+    - SAUCE: {topost} net: hns3: remove some redundant assignments
+    - SAUCE: {topost} net: hns3: simplify hclge_cmd_csq_clean
+    - SAUCE: {topost} net: hns3: using modulo for cyclic counters in
+      hclge_cmd_send
+    - SAUCE: {topost} net: hns3: remove a redundant hclge_cmd_csq_done
+    - SAUCE: {topost} net: hns3: remove some unused members of some structures
+    - SAUCE: {topost} net: hns3: give default option while dependency HNS3 set
+    - SAUCE: {topost} net: hns3: use dma_zalloc_coherent instead of
+      kzalloc/dma_map_single
+    - SAUCE: {topost} net: hns3: modify hnae_ to hnae3_
+    - SAUCE: {topost} net: hns3: fix unused function warning in VF driver
+    - SAUCE: {topost} net: hns3: remove some redundant assignments
+    - SAUCE: {topost} net: hns3: standardize the handle of return value
+    - SAUCE: {topost} net: hns3: remove extra space and brackets
+    - SAUCE: {topost} net: hns3: fix unreasonable code comments
+    - SAUCE: {topost} net: hns3: use decimal for bit offset macros
+    - SAUCE: {topost} net: hns3: modify inconsistent bit mask macros
+    - SAUCE: {topost} net: hns3: fix mislead parameter name
+    - SAUCE: {topost} net: hns3: remove unused struct member and definition
+    - SAUCE: {topost} net: hns3: Add SPDX tags to hns3 driver
+    - SAUCE: {topost} net: hns3: Add pf reset for hip08 RoCE
+    - SAUCE: {topost} net: hns3: optimize the process of notifying roce client
+    - SAUCE: {topost} net: hns3: Add calling roce callback function when link
+      status change
+    - SAUCE: {topost} net: hns3: fix tc setup when netdev is first up
+    - SAUCE: {topost} net: hns3: fix for mac pause not disable in pfc mode
+    - SAUCE: {topost} net: hns3: fix for waterline not setting correctly
+    - SAUCE: {topost} net: hns3: fix for l4 checksum offload bug
+    - SAUCE: {topost} net: hns3: fix for mailbox message truncated problem
+    - SAUCE: {topost} net: hns3: Add configure for mac minimal frame size
+    - SAUCE: {topost} net: hns3: fix warning bug when doing lp selftest
+    - SAUCE: {topost} net: hns3: fix get_vector ops in hclgevf_main module
+    - SAUCE: {topost} net: hns3: remove the warning when clear reset cause
+    - SAUCE: {topost} net: hns3: Use roce handle when calling roce callback
+      function
+    - SAUCE: {topost} net: hns3: prevent sending command during global or core
+      reset
+    - SAUCE: {topost} net: hns3: modify the order of initializeing command queue
+      register
+    - SAUCE: {topost} net: hns3: reset net device with rtnl_lock
+    - SAUCE: {topost} net: hns3: prevent to request reset frequently
+    - SAUCE: {topost} net: hns3: correct reset event status register
+    - SAUCE: {topost} net: hns3: separate roce from nic when resetting
+    - SAUCE: net: hns3: Fix for phy link issue when using marvell phy driver
+    - SAUCE: {topost} net: hns3: fix return value error in
+      hns3_reset_notify_down_enet
+    - SAUCE: {topost} net: hns3: remove unnecessary ring configuration operation
+      while resetting
+    - SAUCE: {topost} net: hns3: fix for reset_level default assignment probelm
+    - SAUCE: {topost} net: hns3: fix for using wrong mask and shift in
+      hclge_get_ring_chain_from_mbx
+    - SAUCE: {topost} net: hns3: fix comments for hclge_get_ring_chain_from_mbx
+    - SAUCE: net: hns3: Fix for VF mailbox cannot receiving PF response
+    - SAUCE: net: hns3: Fix for VF mailbox receiving unknown message
+    - SAUCE: net: hns3: Optimize PF CMDQ interrupt switching process
+
+  * CVE-2018-7755
+    - SAUCE: floppy: Do not copy a kernel pointer to user memory in FDGETPRM ioctl
+
+  * Incorrect blacklist of bcm2835_wdt (LP: #1766052)
+    - [Packaging] Fix missing watchdog for Raspberry Pi
+
+  * kernel: Fix arch random implementation (LP: #1775391)
+    - s390/archrandom: Rework arch random implementation.
+
+  * [Ubuntu 1804][boston][ixgbe] EEH causes kernel BUG at /build/linux-
+    jWa1Fv/linux-4.15.0/drivers/pci/msi.c:352 (i2S) (LP: #1776389)
+    - ixgbe/ixgbevf: Free IRQ when PCI error recovery removes the device
+
+  * Cosmic update to v4.17.2 stable release (LP: #1779117)
+    - crypto: chelsio - request to HW should wrap
+    - blkdev_report_zones_ioctl(): Use vmalloc() to allocate large buffers
+    - KVM: X86: Fix reserved bits check for MOV to CR3
+    - KVM: x86: introduce linear_{read,write}_system
+    - kvm: fix typo in flag name
+    - kvm: nVMX: Enforce cpl=0 for VMX instructions
+    - KVM: x86: pass kvm_vcpu to kvm_read_guest_virt and
+      kvm_write_guest_virt_system
+    - kvm: x86: use correct privilege level for sgdt/sidt/fxsave/fxrstor access
+    - staging: android: ion: Switch to pr_warn_once in ion_buffer_destroy
+    - NFC: pn533: don't send USB data off of the stack
+    - usbip: vhci_sysfs: fix potential Spectre v1
+    - usb-storage: Add support for FL_ALWAYS_SYNC flag in the UAS driver
+    - usb-storage: Add compatibility quirk flags for G-Technologies G-Drive
+    - Input: xpad - add GPD Win 2 Controller USB IDs
+    - phy: qcom-qusb2: Fix crash if nvmem cell not specified
+    - usb: core: message: remove extra endianness conversion in
+      usb_set_isoch_delay
+    - usb: typec: wcove: Remove dependency on HW FSM
+    - usb: gadget: function: printer: avoid wrong list handling in printer_write()
+    - usb: gadget: udc: renesas_usb3: fix double phy_put()
+    - usb: gadget: udc: renesas_usb3: should remove debugfs
+    - usb: gadget: udc: renesas_usb3: should call pm_runtime_enable() before add
+      udc
+    - usb: gadget: udc: renesas_usb3: should call devm_phy_get() before add udc
+    - usb: gadget: udc: renesas_usb3: should fail if devm_phy_get() returns error
+    - usb: gadget: udc: renesas_usb3: disable the controller's irqs for
+      reconnecting
+    - serial: sh-sci: Stop using printk format %pCr
+    - tty/serial: atmel: use port->name as name in request_irq()
+    - serial: samsung: fix maxburst parameter for DMA transactions
+    - serial: 8250: omap: Fix idling of clocks for unused uarts
+    - vmw_balloon: fixing double free when batching mode is off
+    - doc: fix sysfs ABI documentation
+    - arm64: defconfig: Enable CONFIG_PINCTRL_MT7622 by default
+    - tty: pl011: Avoid spuriously stuck-off interrupts
+    - crypto: ccree - correct host regs offset
+    - Input: goodix - add new ACPI id for GPD Win 2 touch screen
+    - Input: elan_i2c - add ELAN0612 (Lenovo v330 14IKB) ACPI ID
+    - crypto: caam - strip input zeros from RSA input buffer
+    - crypto: caam - fix DMA mapping dir for generated IV
+    - crypto: caam - fix IV DMA mapping and updating
+    - crypto: caam/qi - fix IV DMA mapping and updating
+    - crypto: caam - fix size of RSA prime factor q
+    - crypto: cavium - Fix fallout from CONFIG_VMAP_STACK
+    - crypto: cavium - Limit result reading attempts
+    - crypto: vmx - Remove overly verbose printk from AES init routines
+    - crypto: vmx - Remove overly verbose printk from AES XTS init
+    - crypto: omap-sham - fix memleak
+    - Linux 4.17.2
+
+  * Cosmic update to v4.17.1 stable release (LP: #1779116)
+    - netfilter: nf_flow_table: attach dst to skbs
+    - bnx2x: use the right constant
+    - ip6mr: only set ip6mr_table from setsockopt when ip6mr_new_table succeeds
+    - ipv6: omit traffic class when calculating flow hash
+    - l2tp: fix refcount leakage on PPPoL2TP sockets
+    - netdev-FAQ: clarify DaveM's position for stable backports
+    - net: metrics: add proper netlink validation
+    - net/packet: refine check for priv area size
+    - rtnetlink: validate attributes in do_setlink()
+    - sctp: not allow transport timeout value less than HZ/5 for hb_timer
+    - team: use netdev_features_t instead of u32
+    - vrf: check the original netdevice for generating redirect
+    - net: dsa: b53: Fix for brcm tag issue in Cygnus SoC
+    - ipmr: fix error path when ipmr_new_table fails
+    - PCI: hv: Do not wait forever on a device that has disappeared
+    - Linux 4.17.1
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: crypto: thunderx_zip: Fix fallout from
+      CONFIG_VMAP_STACK"
+    - Revert "UBUNTU: SAUCE: cred: Add clone_cred() interface"
+    - SAUCE: apparmor: userspace queries
+    - SAUCE: apparmor: patch to provide compatibility with v2.x net rules
+    - SAUCE: apparmor: af_unix mediation
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 28 Jun 2018 08:03:32 -0500
+
+linux (4.17.0-2.3) cosmic; urgency=medium
+
+  * linux: 4.17.0-2.3 -proposed tracker (LP: #1776276)
+
+  * Miscellaneous Ubuntu changes
+    - Config: remove IrDA from annotations
+    - Config: remove scsi drivers from annotations
+    - Config: remove BT_HCIBTUART from annotations
+    - Config: pstore zlib support was renamed
+    - Config: disable NVRAM for armhf on annotations
+    - Config: Disable VT on s390x
+    - Config: Update SSB and B43/B44 options
+    - Config: some options not supported on some arches anymore
+    - Config: renamed and removed options
+    - Config: TCG_CRB is required for IMA on ACPI systems
+    - Config: EXTCON_AXP288 depends on X86
+    - Config: CONFIG_FSI depends on OF
+    - Config: DRM_RCAR_LVDS now depends on DRM
+    - CONFIG: Allow CONFIG_LEDS_MLXCPLD for i386
+    - Config: Enable HINIC on arm64
+    - Config: Set PPS and PTP_1588_CLOCK as y
+    - Config: Some NF_TABLES options are built-in now
+    - Config: GENERIC_CPU for ppc64el
+    - Config: KEXEC_FILE=n for s390x
+    - Config: CRYPTO_DEFLATE is needed by PSTORE_DEFLATE_COMPRESS
+    - Config: Disable STM32 support
+    - Config: Enable FORTIFY_SOURCE for armhf
+    - Config: use STRONG instead of AUTO for CC_STACKPROTECTOR
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.17
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Mon, 11 Jun 2018 15:22:10 -0300
+
+linux (4.17.0-1.2) cosmic; urgency=medium
+
+  [ Seth Forshee ]
+  * [Config] enable EDAC_DEBUG on ARM64 (LP: #1772516)
+    - [Config]: set CONFIG_EDAC_DEBUG=y for ARM64
+
+  * Ubuntu 18.04 kernel crashed while in degraded mode (LP: #1770849)
+    - SAUCE: powerpc/perf: Fix memory allocation for core-imc based on
+      num_possible_cpus()
+
+  * Integrated Webcam Realtek Integrated_Webcam_HD (0bda:58f4) not working in
+    DELL XPS 13 9370 with firmware 1.50 (LP: #1763748)
+    - SAUCE: media: uvcvideo: Support realtek's UVC 1.5 device
+
+  * Switch Build-Depends: transfig to fig2dev (LP: #1770770)
+    - [Config] update Build-Depends: transfig to fig2dev
+
+  * update-initramfs not adding i915 GuC firmware for Kaby Lake, firmware fails
+    to load (LP: #1728238)
+    - Revert "UBUNTU: SAUCE: (no-up) i915: Remove MODULE_FIRMWARE statements for
+      unreleased firmware"
+
+  * No driver for Huawei network adapters on arm64 (LP: #1769899)
+    - net-next/hinic: add arm64 support
+
+  * linux-snapdragon: reduce EPROBEDEFER noise during boot (LP: #1768761)
+    - [Config] snapdragon: DRM_I2C_ADV7511=y
+
+  * Add d-i support for Huawei NICs (LP: #1767490)
+    - d-i: add hinic to nic-modules udeb
+
+  * Acer Swift sf314-52 power button not managed  (LP: #1766054)
+    - SAUCE: platform/x86: acer-wmi: add another KEY_POWER keycode
+
+  * Include nfp driver in linux-modules (LP: #1768526)
+    - [Config] Add nfp.ko to generic inclusion list
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Import aufs driver
+    - [Config] Enable AUFS config options
+    - SAUCE: (efi-lockdown) Fix for module sig verification
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) efi: Don't print secure boot state from the efi stub
+    - [Config] CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y
+    - SAUCE: (efi-lockdown) really lock down kernel under EFI secure boot
+    - SAUCE: (noup) Update spl to 0.7.5-1ubuntu3, zfs to 0.7.5-1ubuntu17
+    - enable zfs build
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) ima: require secure_boot rules in
+      lockdown mode"
+    - Rebased to v4.17-rc6
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Tue, 22 May 2018 14:48:13 -0300
+
+linux (4.17.0-0.1) bionic; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.17-rc4
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Tue, 08 May 2018 16:38:51 -0300
+
+linux (4.17.0-0.0) bionic; urgency=medium
+
+  * Dummy entry.
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Fri, 27 Apr 2018 11:01:13 -0300
+
+linux (4.16.0-4.5) bionic; urgency=medium
+
+  * [18.04 FEAT] Add kvm_stat from kernel tree (LP: #1734130)
+    - tools/kvm_stat: Fix python3 syntax
+    - tools/kvm_stat: Don't use deprecated file()
+    - tools/kvm_stat: Remove unused function
+    - [Packaging] Add linux-tools-host package for VM host tools
+    - [Config] do_tools_host=true for amd64
+
+  * [Featire] CNL: Enable RAPL support (LP: #1685712)
+    - powercap: RAPL: Add support for Cannon Lake
+
+  * Bionic update to v4.16.2 stable release (LP: #1763388)
+    - sparc64: Oracle DAX driver depends on SPARC64
+    - arp: fix arp_filter on l3slave devices
+    - net: dsa: Discard frames from unused ports
+    - net/ipv6: Increment OUTxxx counters after netfilter hook
+    - net/sched: fix NULL dereference in the error path of tcf_bpf_init()
+    - pptp: remove a buggy dst release in pptp_connect()
+    - sctp: do not leak kernel memory to user space
+    - sctp: sctp_sockaddr_af must check minimal addr length for AF_INET6
+    - vlan: also check phy_driver ts_info for vlan's real device
+    - net: fool proof dev_valid_name()
+    - ip_tunnel: better validate user provided tunnel names
+    - ipv6: sit: better validate user provided tunnel names
+    - ip6_gre: better validate user provided tunnel names
+    - ip6_tunnel: better validate user provided tunnel names
+    - vti6: better validate user provided tunnel names
+    - net_sched: fix a missing idr_remove() in u32_delete_key()
+    - nfp: use full 40 bits of the NSP buffer address
+    - Linux 4.16.2
+
+  * sky2 gigabit ethernet driver sometimes stops working after lid-open resume
+    from sleep (88E8055) (LP: #1758507) // Bionic update to v4.16.2 stable
+    release (LP: #1763388)
+    - sky2: Increase D3 delay to sky2 stops working after suspend
+
+  * Merge the linux-snapdragon kernel into bionic master/snapdragon
+    (LP: #1763040)
+    - arm64: defconfig: enable REMOTEPROC
+    - arm64: defconfig: enable QCOM audio drivers for APQ8016 and DB410c
+    - kernel: configs; add distro.config
+    - arm64: configs: enable WCN36xx
+    - kernel: distro.config: enable debug friendly USB network adpater
+    - arm64: configs: enable QCOM Venus
+    - arm64: defconfig: Enable a53/apcs and avs
+    - arm64: defconfig: enable ondemand governor as default
+    - arm64: defconfig: enable QCOM_TSENS
+    - kernel: configs: enable dm_mod and dm_crypt
+    - Force the SMD regulator driver to be compiled-in
+    - arm64: defconfig: enable CFG80211_DEFAULT_PS by default
+    - arm64: configs: enable BT_QCOMSMD
+    - kernel: configs: add more USB net drivers
+    - arm64: defconfig: disable ANALOG_TV and DIGITAL_TV
+    - arm64: configs: Enable camera drivers
+    - kernel: configs: add freq stat to sysfs
+    - arm64: defconfig: enable CONFIG_USB_CONFIGFS_F_FS by default
+    - arm64: defconfig: Enable QRTR features
+    - kernel: configs: set USB_CONFIG_F_FS in distro.config
+    - kernel: distro.config: enable 'schedutil' CPUfreq governor
+    - kernel: distro.config: enable 'fq' and 'fq_codel' qdiscs
+    - kernel: distro.config: enable 'BBR' TCP congestion algorithm
+    - arm64: defconfig: enable LEDS_QCOM_LPG
+    - HACK: drm/msm/iommu: Remove runtime_put calls in map/unmap
+    - power: avs: Add support for CPR (Core Power Reduction)
+    - power: avs: cpr: Use raw mem access for qfprom
+    - power: avs: cpr: fix with new reg_sequence structures
+    - power: avs: cpr: Register with cpufreq-dt
+    - regulator: smd: Add floor and corner operations
+    - PM / OPP: Support adjusting OPP voltages at runtime
+    - PM / OPP: Drop RCU usage in dev_pm_opp_adjust_voltage()
+    - PM / OPP: HACK: Allow to set regulator without opp_list
+    - PM / OPP: Add a helper to get an opp regulator for device
+    - cpufreq: Add apq8016 to cpufreq-dt-platdev blacklist
+    - regulator: smd: Allow REGULATOR_QCOM_SMD_RPM=m
+    - ov5645: I2C address change
+    - i2c: Add Qualcomm Camera Control Interface driver
+    - camss: vfe: Skip first four frames from sensor
+    - camss: Do not register if no cameras are present
+    - i2c-qcom-cci: Fix run queue completion timeout
+    - i2c-qcom-cci: Fix I2C address bug
+    - media: ov5645: Fix I2C address
+    - drm/bridge/adv7511: Delay clearing of HPD interrupt status
+    - HACK: drm/msm/adv7511: Don't rely on interrupts for EDID parsing
+    - leds: Add driver for Qualcomm LPG
+    - wcn36xx: Fix warning due to duplicate scan_completed notification
+    - arm64: dts: Add CPR DT node for msm8916
+    - arm64: dts: add spmi-regulator nodes
+    - arm64: dts: msm8916: Add cpufreq support
+    - arm64: dts: msm8916: Add a shared CPU opp table
+    - arm64: dts: msm8916: Add cpu cooling maps
+    - arm64: dts: pm8916: Mark the s2 regulator as always-on
+    - arm64: dts: qcom: msm8916: Add msm8916 A53 PLL DT node
+    - arm64: dts: qcom: msm8916: Use the new APCS mailbox driver
+    - arm64: dts: qcom: msm8916: Add clock properties to the APCS node
+    - dt-bindings: media: Binding document for Qualcomm Camera Control Interface
+      driver
+    - MAINTAINERS: Add Qualcomm Camera Control Interface driver
+    - DT: leds: Add Qualcomm Light Pulse Generator binding
+    - arm64: dts: qcom: msm8996: Add mpp and lpg blocks
+    - arm64: dts: qcom: Add pwm node for pm8916
+    - arm64: dts: qcom: Add user LEDs on db820c
+    - arm64: dts: qcom: Add WiFI/BT LEDs on db820c
+    - ARM: dts: qcom: Add LPG node to pm8941
+    - ARM: dts: qcom: honami: Add LPG node and RGB LED
+    - arm64: dts: qcom: Add Camera Control Interface support
+    - arm64: dts: qcom: Add apps_iommu vfe child node
+    - arm64: dts: qcom: Add camss device node
+    - arm64: dts: qcom: Add ov5645 device nodes
+    - arm64: dts: msm8916: Fix camera sensors I2C addresses
+    - arm: dts: qcom: db410c: Enable PWM signal on MPP4
+    - packaging: arm64: add a uboot flavour - part1
+    - packaging: arm64: add a uboot flavour - part2
+    - packaging: arm64: add a uboot flavour - part3
+    - packaging: arm64: add a uboot flavour - part4
+    - packaging: arm64: add a uboot flavour - part5
+    - packaging: arm64: rename uboot flavour to snapdragon
+    - [Config] updateconfigs after qcomlt import
+    - [Config] arm64: snapdragon: COMMON_CLK_QCOM=y
+    - [Config] arm64: snapdragon: MSM_GCC_8916=y
+    - [Config] arm64: snapdragon: REGULATOR_FIXED_VOLTAGE=y
+    - [Config] arm64: snapdragon: PINCTRL_MSM8916=y
+    - [Config] arm64: snapdragon: HWSPINLOCK_QCOM=y
+    - [Config] arm64: snapdragon: SPMI=y, SPMI_MSM_PMIC_ARB=y
+    - [Config] arm64: snapdragon: REGMAP_SPMI=y, PINCTRL_QCOM_SPMI_PMIC=y
+    - [Config] arm64: snapdragon: REGULATOR_QCOM_SPMI=y
+    - [Config] arm64: snapdragon: MFD_SPMI_PMIC=y
+    - [Config] arm64: snapdragon: QCOM_SMEM=y
+    - [Config] arm64: snapdragon: RPMSG=y, RPMSG_QCOM_SMD=y
+    - [Config] arm64: snapdragon: QCOM_SMD_RPM=y, REGULATOR_QCOM_SMD_RPM=y
+    - [Config] arm64: snapdragon: QCOM_CLK_SMD_RPM=y
+    - [Config] arm64: snapdragon: QCOM_BAM_DMA=y
+    - [Config] arm64: snapdragon: QCOM_HIDMA=y, QCOM_HIDMA_MGMT=y
+    - [Config] arm64: snapdragon: QCOM_CPR=y
+    - [Config] arm64: snapdragon: QCOM_QFPROM=y, QCOM_TSENS=y
+    - [Config] arm64: snapdragon: MMC_SDHCI=y, MMC_SDHCI_PLTFM=y, MMC_SDHCI_MSM=y
+    - [Config] turn off DRM_MSM_REGISTER_LOGGING
+    - [Config] arm64: snapdragon: I2C_QUP=y
+    - [Config] arm64: snapdragon: SPI_QUP=y
+    - [Config] arm64: snapdragon: USB_ULPI_BUS=y, PHY_QCOM_USB_HS=y
+    - [Config] arm64: snapdragon: QCOM_APCS_IPC=y
+    - [Config] arm64: snapdragon: QCOM_WCNSS_CTRL=y
+    - [Config] arm64: snapdragon: QCOM_SMSM=y
+    - [Config] arm64: snapdragon: QCOM_SMP2P=y
+    - [Config] arm64: snapdragon: DRM_MSM=y
+    - [Config] arm64: snapdragon: SND_SOC=y
+    - [Config] arm64: snapdragon: QCOM_WCNSS_PIL=m
+    - [Config] arm64: snapdragon: INPUT_PM8941_PWRKEY=y
+    - [Config] arm64: snapdragon: MEDIA_SUBDRV_AUTOSELECT=y, VIDEO_OV5645=m
+    - [Config] arm64: snapdragon: SND_SOC_APQ8016_SBC=y, SND_SOC_LPASS_APQ8016=y
+    - [Config] arm64: snapdragon: SND_SOC_MSM8916_WCD_ANALOG=y,
+      SND_SOC_MSM8916_WCD_DIGITAL=y
+    - SAUCE: media: ov5645: skip address change if dt addr == default addr
+    - SAUCE: drm/msm/adv7511: wrap hacks under CONFIG_ADV7511_SNAPDRAGON_HACKS
+      #ifdefs
+    - [Config] arm64: snapdragon: ADV7511_SNAPDRAGON_HACKS=y
+    - [Packaging] fix up snapdragon abi paths
+
+  * LSM stacking patches for bionic (LP: #1763062)
+    - SAUCE: LSM stacking: procfs: add smack subdir to attrs
+    - SAUCE: LSM stacking: LSM: Manage credential security blobs
+    - SAUCE: LSM stacking: LSM: Manage file security blobs
+    - SAUCE: LSM stacking: LSM: Manage task security blobs
+    - SAUCE: LSM stacking: LSM: Manage remaining security blobs
+    - SAUCE: LSM stacking: LSM: General stacking
+    - SAUCE: LSM stacking: fixup initialize task->security
+    - SAUCE: LSM stacking: fixup: alloc_task_ctx is dead code
+    - SAUCE: LSM stacking: add support for stacking getpeersec_stream
+    - SAUCE: LSM stacking: add stacking support to apparmor network hooks
+    - SAUCE: LSM stacking: fixup apparmor stacking enablement
+    - SAUCE: LSM stacking: fixup stacking kconfig
+    - SAUCE: LSM stacking: allow selecting multiple LSMs using kernel boot params
+    - SAUCE: LSM stacking: provide prctl interface for setting context
+    - SAUCE: LSM stacking: inherit current display LSM
+    - SAUCE: LSM stacking: keep an index for each registered LSM
+    - SAUCE: LSM stacking: verify display LSM
+    - SAUCE: LSM stacking: provide a way to specify the default display lsm
+    - SAUCE: LSM stacking: make sure LSM blob align on 64 bit boundaries
+    - SAUCE: LSM stacking: add /proc/<pid>/attr/display_lsm
+    - SAUCE: LSM stacking: add Kconfig to set default display LSM
+    - SAUCE: LSM stacking: add configs for LSM stacking
+    - SAUCE: LSM stacking: add apparmor and selinux proc dirs
+    - SAUCE: LSM stacking: remove procfs context interface
+
+  * linux 4.13.0-13.14 ADT test failure with linux 4.13.0-13.14
+    (LP: #1720779) // LSM stacking patches for bionic (LP: #1763062)
+    - SAUCE: LSM stacking: check for invalid zero sized writes
+
+  * Support cq/rq record doorbell for RDMA on HSilicon hip08 systems
+    (LP: #1762755)
+    - RDMA/hns: Support rq record doorbell for the user space
+    - RDMA/hns: Support cq record doorbell for the user space
+    - RDMA/hns: Support rq record doorbell for kernel space
+    - RDMA/hns: Support cq record doorbell for kernel space
+    - RDMA/hns: Fix cqn type and init resp
+    - RDMA/hns: Fix init resp when alloc ucontext
+    - RDMA/hns: Fix cq record doorbell enable in kernel
+
+  * Replace LPC patchset with upstream version (LP: #1762758)
+    - Revert "UBUNTU: SAUCE: MAINTAINERS: Add maintainer for HiSilicon LPC driver"
+    - Revert "UBUNTU: SAUCE: HISI LPC: Add ACPI support"
+    - Revert "UBUNTU: SAUCE: ACPI / scan: do not enumerate Indirect IO host
+      children"
+    - Revert "UBUNTU: SAUCE: HISI LPC: Support the LPC host on Hip06/Hip07 with DT
+      bindings"
+    - Revert "UBUNTU: SAUCE: OF: Add missing I/O range exception for indirect-IO
+      devices"
+    - Revert "UBUNTU: SAUCE: PCI: Apply the new generic I/O management on PCI IO
+      hosts"
+    - Revert "UBUNTU: SAUCE: PCI: Add fwnode handler as input param of
+      pci_register_io_range()"
+    - Revert "UBUNTU: SAUCE: PCI: Remove unused __weak attribute in
+      pci_register_io_range()"
+    - Revert "UBUNTU: SAUCE: LIB: Introduce a generic PIO mapping method"
+    - lib: Add generic PIO mapping method
+    - PCI: Remove __weak tag from pci_register_io_range()
+    - PCI: Add fwnode handler as input param of pci_register_io_range()
+    - PCI: Apply the new generic I/O management on PCI IO hosts
+    - of: Add missing I/O range exception for indirect-IO devices
+    - HISI LPC: Support the LPC host on Hip06/Hip07 with DT bindings
+    - ACPI / scan: Rename acpi_is_serial_bus_slave() for more general use
+    - ACPI / scan: Do not enumerate Indirect IO host children
+    - HISI LPC: Add ACPI support
+    - MAINTAINERS: Add John Garry as maintainer for HiSilicon LPC driver
+
+  * Enable Tunneled Operations on POWER9 (LP: #1762448)
+    - powerpc/powernv: Enable tunneled operations
+    - cxl: read PHB indications from the device tree
+
+  * PSL traces reset after PERST for debug AFU image (LP: #1762462)
+    - cxl: Enable NORST bit in PSL_DEBUG register for PSL9
+
+  * NFS + sec=krb5 is broken (LP: #1759791)
+    - sunrpc: remove incorrect HMAC request initialization
+
+  * Raspberry Pi 3 microSD support missing from the installer (LP: #1729128)
+    - d-i: add bcm2835 to block-modules
+
+  * Backport USB core quirks (LP: #1762695)
+    - usb: core: Add "quirks" parameter for usbcore
+    - usb: core: Copy parameter string correctly and remove superfluous null check
+    - usb: core: Add USB_QUIRK_DELAY_CTRL_MSG to usbcore quirks
+
+  * [Ubuntu 18.04] cryptsetup: 'device-mapper: reload ioctl on  failed' when
+    setting up a second end-to-end encrypted disk (LP: #1762353)
+    - SAUCE: s390/crypto: Adjust s390 aes and paes cipher
+
+  * System Z {kernel} UBUNTU18.04 wrong kernel config (LP: #1762719)
+    - s390: move nobp parameter functions to nospec-branch.c
+    - s390: add automatic detection of the spectre defense
+    - s390: report spectre mitigation via syslog
+    - s390: add sysfs attributes for spectre
+    - [Config] CONFIG_EXPOLINE_AUTO=y, CONFIG_KERNEL_NOBP=n for s390
+    - s390: correct nospec auto detection init order
+
+  * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5715
+    - powerpc/64s: Wire up cpu_show_spectre_v2()
+
+  * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5753
+    - powerpc/64s: Wire up cpu_show_spectre_v1()
+
+  * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5754
+    - powerpc/rfi-flush: Move the logic to avoid a redo into the debugfs code
+    - powerpc/rfi-flush: Make it possible to call setup_rfi_flush() again
+    - powerpc/rfi-flush: Always enable fallback flush on pseries
+    - powerpc/rfi-flush: Differentiate enabled and patched flush types
+    - powerpc/rfi-flush: Call setup_rfi_flush() after LPM migration
+    - powerpc/64s: Move cpu_show_meltdown()
+    - powerpc/64s: Enhance the information in cpu_show_meltdown()
+    - powerpc/powernv: Use the security flags in pnv_setup_rfi_flush()
+    - powerpc/pseries: Use the security flags in pseries_setup_rfi_flush()
+
+  * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5715 //
+    CVE-2017-5753 // CVE-2017-5754
+    - powerpc/pseries: Add new H_GET_CPU_CHARACTERISTICS flags
+    - powerpc: Add security feature flags for Spectre/Meltdown
+    - powerpc/pseries: Set or clear security feature flags
+    - powerpc/powernv: Set or clear security feature flags
+
+  * Hisilicon network subsystem 3 support (LP: #1761610)
+    - net: hns3: export pci table of hclge and hclgevf to userspace
+    - d-i: Add hns3 drivers to nic-modules
+
+  * "ip a" command on a guest VM shows UNKNOWN status (LP: #1761534)
+    - virtio-net: Fix operstate for virtio when no VIRTIO_NET_F_STATUS
+
+  * perf vendor events arm64: Enable JSON events for ThunderX2 B0 (LP: #1760712)
+    - perf vendor events: Drop incomplete multiple mapfile support
+    - perf vendor events: Fix error code in json_events()
+    - perf vendor events: Drop support for unused topic directories
+    - perf vendor events: Add support for pmu events vendor subdirectory
+    - perf vendor events arm64: Relocate ThunderX2 JSON to cavium subdirectory
+    - perf vendor events arm64: Relocate Cortex A53 JSONs to arm subdirectory
+    - perf vendor events: Add support for arch standard events
+    - perf vendor events arm64: Add armv8-recommended.json
+    - perf vendor events arm64: Fixup ThunderX2 to use recommended events
+    - perf vendor events arm64: fixup A53 to use recommended events
+    - perf vendor events arm64: add HiSilicon hip08 JSON file
+    - perf vendor events arm64: Enable JSON events for ThunderX2 B0
+
+  * Warning "cache flush timed out!" seen when unloading the cxl driver
+    (LP: #1762367)
+    - cxl: Check if PSL data-cache is available before issue flush request
+
+  * Bionic update to v4.16.1 stable release (LP: #1763170)
+    - bitmap: fix memset optimization on big-endian systems
+    - USB: serial: ftdi_sio: add RT Systems VX-8 cable
+    - USB: serial: ftdi_sio: add support for Harman FirmwareHubEmulator
+    - USB: serial: cp210x: add ELDAT Easywave RX09 id
+    - serial: 8250: Add Nuvoton NPCM UART
+    - mei: remove dev_err message on an unsupported ioctl
+    - /dev/mem: Avoid overwriting "err" in read_mem()
+    - media: usbtv: prevent double free in error case
+    - parport_pc: Add support for WCH CH382L PCI-E single parallel port card.
+    - crypto: lrw - Free rctx->ext with kzfree
+    - crypto: ccp - Fill the result buffer only on digest, finup, and final ops
+    - crypto: talitos - don't persistently map req_ctx->hw_context and
+      req_ctx->buf
+    - crypto: inside-secure - fix clock management
+    - crypto: testmgr - Fix incorrect values in PKCS#1 test vector
+    - crypto: talitos - fix IPsec cipher in length
+    - crypto: ahash - Fix early termination in hash walk
+    - crypto: caam - Fix null dereference at error path
+    - crypto: ccp - return an actual key size from RSA max_size callback
+    - crypto: arm,arm64 - Fix random regeneration of S_shipped
+    - crypto: x86/cast5-avx - fix ECB encryption when long sg follows short one
+    - Bluetooth: hci_bcm: Add 6 new ACPI HIDs
+    - Btrfs: fix unexpected cow in run_delalloc_nocow
+    - siox: fix possible buffer overflow in device_add_store
+    - staging: comedi: ni_mio_common: ack ai fifo error interrupts.
+    - Revert "base: arch_topology: fix section mismatch build warnings"
+    - Input: ALPS - fix TrackStick detection on Thinkpad L570 and Latitude 7370
+    - Input: i8042 - add Lenovo ThinkPad L460 to i8042 reset list
+    - Input: i8042 - enable MUX on Sony VAIO VGN-CS series to fix touchpad
+    - vt: change SGR 21 to follow the standards
+    - Fix slab name "biovec-(1<<(21-12))"
+    - signal: Correct the offset of si_pkey and si_lower in struct siginfo on m68k
+    - Linux 4.16.1
+
+  * [18.04][config] regression: nvme and nvme_core couldn't be built as modules
+    starting 4.15-rc2 (LP: #1759893)
+    - SAUCE: Revert "lightnvm: include NVM Express driver if OCSSD is selected for
+      build"
+    - [Config] CONFIG_BLK_DEV_NMVE=m
+
+  * FFe: Enable configuring resume offset via sysfs (LP: #1760106)
+    - PM / hibernate: Make passing hibernate offsets more friendly
+
+  * Ubuntu18.04:POWER9:DD2.2 - Unable to start a KVM guest with default machine
+    type(pseries-bionic) complaining "KVM implementation does not support
+    Transactional Memory, try cap-htm=off" (kvm) (LP: #1752026)
+    - powerpc: Use feature bit for RTC presence rather than timebase presence
+    - powerpc: Book E: Remove unused CPU_FTR_L2CSR bit
+    - powerpc: Free up CPU feature bits on 64-bit machines
+    - powerpc: Add CPU feature bits for TM bug workarounds on POWER9 v2.2
+    - powerpc/powernv: Provide a way to force a core into SMT4 mode
+    - KVM: PPC: Book3S HV: Work around transactional memory bugs in POWER9
+    - KVM: PPC: Book3S HV: Work around XER[SO] bug in fake suspend mode
+    - KVM: PPC: Book3S HV: Work around TEXASR bug in fake suspend state
+
+  * [Feature][CFL][ICL] [CNL]Thunderbolt support (Titan Ridge) (LP: #1730775)
+    - thunderbolt: Resume control channel after hibernation image is created
+    - thunderbolt: Serialize PCIe tunnel creation with PCI rescan
+    - thunderbolt: Handle connecting device in place of host properly
+    - thunderbolt: Do not overwrite error code when domain adding fails
+    - thunderbolt: Wait a bit longer for root switch config space
+    - thunderbolt: Wait a bit longer for ICM to authenticate the active NVM
+    - thunderbolt: Handle rejected Thunderbolt devices
+    - thunderbolt: Factor common ICM add and update operations out
+    - thunderbolt: Correct function name in kernel-doc comment
+    - thunderbolt: Add tb_switch_get()
+    - thunderbolt: Add tb_switch_find_by_route()
+    - thunderbolt: Add tb_xdomain_find_by_route()
+    - thunderbolt: Add constant for approval timeout
+    - thunderbolt: Move driver ready handling to struct icm
+    - thunderbolt: Add 'boot' attribute for devices
+    - thunderbolt: Add support for preboot ACL
+    - thunderbolt: Introduce USB only (SL4) security level
+    - thunderbolt: Add support for Intel Titan Ridge
+
+  * QCA9377 requires more IRAM banks for its new firmware (LP: #1748345)
+    - ath10k: update the IRAM bank number for QCA9377
+
+  * Fix an issue that when system in S3, USB keyboard can't wake up the system.
+    (LP: #1759511)
+    - ACPI / PM: Allow deeper wakeup power states with no _SxD nor _SxW
+
+  * cxl: Fix timebase synchronization status on POWER9 missing (CAPI)
+    (LP: #1757228)
+    - cxl: Fix timebase synchronization status on P9
+
+  * [Feature]Update Ubuntu 18.04 lpfc FC driver with 32/64GB HBA support and bug
+    fixes (LP: #1752182)
+    - scsi: lpfc: Fix frequency of Release WQE CQEs
+    - scsi: lpfc: Increase CQ and WQ sizes for SCSI
+    - scsi: lpfc: move placement of target destroy on driver detach
+    - scsi: lpfc: correct debug counters for abort
+    - scsi: lpfc: Add WQ Full Logic for NVME Target
+    - scsi: lpfc: Fix PRLI handling when topology type changes
+    - scsi: lpfc: Fix IO failure during hba reset testing with nvme io.
+    - scsi: lpfc: Fix RQ empty firmware trap
+    - scsi: lpfc: Allow set of maximum outstanding SCSI cmd limit for a target
+    - scsi: lpfc: Fix soft lockup in lpfc worker thread during LIP testing
+    - scsi: lpfc: Fix issue_lip if link is disabled
+    - scsi: lpfc: Indicate CONF support in NVMe PRLI
+    - scsi: lpfc: Fix SCSI io host reset causing kernel crash
+    - scsi: lpfc: Validate adapter support for SRIU option
+    - scsi: lpfc: Fix header inclusion in lpfc_nvmet
+    - scsi: lpfc: Treat SCSI Write operation Underruns as an error
+    - scsi: lpfc: Fix nonrecovery of NVME controller after cable swap.
+    - scsi: lpfc: update driver version to 11.4.0.7
+    - scsi: lpfc: Update 11.4.0.7 modified files for 2018 Copyright
+    - scsi: lpfc: Rework lpfc to allow different sli4 cq and eq handlers
+    - scsi: lpfc: Rework sli4 doorbell infrastructure
+    - scsi: lpfc: Add SLI-4 if_type=6 support to the code base
+    - scsi: lpfc: Add push-to-adapter support to sli4
+    - scsi: lpfc: Add PCI Ids for if_type=6 hardware
+    - scsi: lpfc: Add 64G link speed support
+    - scsi: lpfc: Add if_type=6 support for cycling valid bits
+    - scsi: lpfc: Enable fw download on if_type=6 devices
+    - scsi: lpfc: Add embedded data pointers for enhanced performance
+    - scsi: lpfc: Fix nvme embedded io length on new hardware
+    - scsi: lpfc: Work around NVME cmd iu SGL type
+    - scsi: lpfc: update driver version to 12.0.0.0
+    - scsi: lpfc: Change Copyright of 12.0.0.0 modified files to 2018
+    - scsi: lpfc: use __raw_writeX on DPP copies
+    - scsi: lpfc: Add missing unlock in WQ full logic
+
+  * /dev/bcache/by-uuid links not created after reboot (LP: #1729145)
+    - SAUCE: (no-up) bcache: decouple emitting a cached_dev CHANGE uevent
+
+  * DKMS driver builds fail with: Cannot use CONFIG_STACK_VALIDATION=y, please
+    install libelf-dev, libelf-devel or elfutils-libelf-devel (LP: #1760876)
+    - [Packaging] include the retpoline extractor in the headers
+
+  * Use med_with_dipm SATA LPM to save more power for mobile platforms
+    (LP: #1759547)
+    - [Config] CONFIG_SATA_MOBILE_LPM_POLICY=3
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Only install cloud init files when do_tools_common=true
+    - SAUCE: Import aufs driver
+    - [Config] Enable AUFS config options
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 12 Apr 2018 09:30:56 -0500
+
+linux (4.16.0-3.4) bionic; urgency=medium
+
+  * Allow multiple mounts of zfs datasets (LP: #1759848)
+    - SAUCE: Allow mounting datasets more than once (LP: #1759848)
+
+  * zfs system process hung on container stop/delete (LP: #1754584)
+    - SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)
+    - Revert "UBUNTU: SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)"
+    - SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)
+
+  * ubuntu_zram_smoke test will cause soft lockup on Artful ThunderX ARM64
+    (LP: #1755073)
+    - SAUCE: crypto: thunderx_zip: Fix fallout from CONFIG_VMAP_STACK
+
+  * CAPI Flash (cxlflash) update (LP: #1752672)
+    - SAUCE: cxlflash: Preserve number of interrupts for master contexts
+    - SAUCE: cxlflash: Avoid clobbering context control register value
+    - SAUCE: cxlflash: Add argument identifier names
+    - SAUCE: cxlflash: Introduce OCXL backend
+    - SAUCE: cxlflash: Hardware AFU for OCXL
+    - SAUCE: cxlflash: Read host function configuration
+    - SAUCE: cxlflash: Setup function acTag range
+    - SAUCE: cxlflash: Read host AFU configuration
+    - SAUCE: cxlflash: Setup AFU acTag range
+    - SAUCE: cxlflash: Setup AFU PASID
+    - SAUCE: cxlflash: Adapter context support for OCXL
+    - SAUCE: cxlflash: Use IDR to manage adapter contexts
+    - SAUCE: cxlflash: Support adapter file descriptors for OCXL
+    - SAUCE: cxlflash: Support adapter context discovery
+    - SAUCE: cxlflash: Support image reload policy modification
+    - SAUCE: cxlflash: MMIO map the AFU
+    - SAUCE: cxlflash: Support starting an adapter context
+    - SAUCE: cxlflash: Support process specific mappings
+    - SAUCE: cxlflash: Support AFU state toggling
+    - SAUCE: cxlflash: Support reading adapter VPD data
+    - SAUCE: cxlflash: Setup function OCXL link
+    - SAUCE: cxlflash: Setup OCXL transaction layer
+    - SAUCE: cxlflash: Support process element lifecycle
+    - SAUCE: cxlflash: Support AFU interrupt management
+    - SAUCE: cxlflash: Support AFU interrupt mapping and registration
+    - SAUCE: cxlflash: Support starting user contexts
+    - SAUCE: cxlflash: Support adapter context polling
+    - SAUCE: cxlflash: Support adapter context reading
+    - SAUCE: cxlflash: Support adapter context mmap and release
+    - SAUCE: cxlflash: Support file descriptor mapping
+    - SAUCE: cxlflash: Introduce object handle fop
+    - SAUCE: cxlflash: Setup LISNs for user contexts
+    - SAUCE: cxlflash: Setup LISNs for master contexts
+    - SAUCE: cxlflash: Update synchronous interrupt status bits
+    - SAUCE: cxlflash: Introduce OCXL context state machine
+    - SAUCE: cxlflash: Register for translation errors
+    - SAUCE: cxlflash: Support AFU reset
+    - SAUCE: cxlflash: Enable OCXL operations
+
+  * [Artful][Wyse 3040] System hang when trying to enable an offlined CPU core
+    (LP: #1736393)
+    - SAUCE: drm/i915:Don't set chip specific data
+    - SAUCE: drm/i915: make previous commit affects Wyse 3040 only
+
+  * zed process consuming 100% cpu (LP: #1751796)
+    - SAUCE: Fix ioctl loop-spin in zed (LP: #1751796)
+
+  * Ubuntu18.04:PowerPC - Set Transparent Huge Pages (THP) by default to
+    "always" (LP: #1753708)
+    - Config: Set TRANSPARENT_HUGEPAGE_ALWAYS=y on ppc64el
+
+  * retpoline hints: primary infrastructure and initial hints (LP: #1758856)
+    - [Packaging] retpoline -- add safe usage hint support
+    - [Packaging] retpoline-check -- only report additions
+    - [Packaging] retpoline -- widen indirect call/jmp detection
+    - [Packaging] retpoline -- elide %rip relative indirections
+    - [Packaging] retpoline -- clear hint information from packages
+    - SAUCE: apm -- annotate indirect calls within
+      firmware_restrict_branch_speculation_{start,end}
+    - SAUCE: EFI -- annotate indirect calls within
+      firmware_restrict_branch_speculation_{start,end}
+    - SAUCE: early/late -- annotate indirect calls in early/late initialisation
+      code
+    - SAUCE: vga_set_mode -- avoid jump tables
+    - [Config] retpoine -- switch to new format
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] final-checks -- remove check for empty retpoline files
+    - [Packaging] skip cloud tools packaging when not building package
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.16
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 02 Apr 2018 16:15:36 -0500
+
+linux (4.16.0-2.3) bionic; urgency=medium
+
+  * devpts: handle bind-mounts (LP: #1755857)
+    - SAUCE: devpts: hoist out check for DEVPTS_SUPER_MAGIC
+    - SAUCE: devpts: resolve devpts bind-mounts
+    - SAUCE: devpts: comment devpts_mntget()
+    - SAUCE: selftests: add devpts selftests
+
+  * [bionic][arm64] d-i: add hisi_sas_v3_hw to scsi-modules (LP: #1756103)
+    - d-i: add hisi_sas_v3_hw to scsi-modules
+
+  * [Bionic][ARM64] PCI and SAS driver patches for hip08 SoCs (LP: #1756094)
+    - SAUCE: scsi: hisi_sas: config for hip08 ES
+    - SAUCE: scsi: hisi_sas: export device table of v3 hw to userspace
+
+  * s390/crypto: Fix kernel crash on aes_s390 module remove (LP: #1753424)
+    - SAUCE: s390/crypto: Fix kernel crash on aes_s390 module remove.
+
+  * Fix ARC hit rate (LP: #1755158)
+    - SAUCE: Fix ARC hit rate (LP: #1755158)
+
+  * ZFS setgid broken on 0.7 (LP: #1753288)
+    - SAUCE: Fix ZFS setgid
+
+  * CONFIG_EFI=y on armhf (LP: #1726362)
+    - [Config] CONFIG_EFI=y on armhf, reconcile secureboot EFI settings
+
+  * [Feature] Add xHCI debug device support in the driver (LP: #1730832)
+    - [Config] CONFIG_USB_XHCI_DBGCAP=y
+
+  * retpoline: ignore %cs:0xNNN constant indirections (LP: #1752655)
+    - [Packaging] retpoline -- elide %cs:0xNNNN constants on i386
+    - [Config] retpoline -- clean up i386 retpoline files
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] retpoline-extract: flag *0xNNN(%reg) branches
+    - [Config] fix up retpoline abi files
+    - [Config] fix up retpoline abi files
+    - d-i: Add netsec to nic-modules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.16-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 19 Mar 2018 14:09:49 -0500
+
+linux (4.16.0-1.2) bionic; urgency=medium
+
+  * Driver not found in Ubuntu kernel does not detect interface (LP: #1745927)
+    - d-i: add cxgb4 to nic-modules
+
+  * Support low-pin-count devices on Hisilicon SoCs (LP: #1677319)
+    - [Config] CONFIG_INDIRECT_PIO=y
+    - SAUCE: LIB: Introduce a generic PIO mapping method
+    - SAUCE: PCI: Remove unused __weak attribute in pci_register_io_range()
+    - SAUCE: PCI: Add fwnode handler as input param of pci_register_io_range()
+    - SAUCE: PCI: Apply the new generic I/O management on PCI IO hosts
+    - SAUCE: OF: Add missing I/O range exception for indirect-IO devices
+    - [Config] CONFIG_HISILICON_LPC=y
+    - SAUCE: HISI LPC: Support the LPC host on Hip06/Hip07 with DT bindings
+    - SAUCE: ACPI / scan: do not enumerate Indirect IO host children
+    - SAUCE: HISI LPC: Add ACPI support
+    - SAUCE: MAINTAINERS: Add maintainer for HiSilicon LPC driver
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: tools: use CC for linking acpi tools
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.16-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 28 Feb 2018 10:17:23 -0600
+
+linux (4.16.0-0.1) bionic; urgency=medium
+
+  * retpoline abi files are empty on i386 (LP: #1751021)
+    - [Packaging] retpoline-extract -- instantiate retpoline files for i386
+    - [Packaging] final-checks -- sanity checking ABI contents
+    - [Packaging] final-checks -- check for empty retpoline files
+
+  * Miscellaneous upstream changes
+    - disable vbox build
+    - Disable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.16-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 22 Feb 2018 08:58:57 -0600
+
+linux (4.16.0-0.0) bionic; urgency=medium
+
+  * Dummy entry
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 21 Feb 2018 14:33:13 -0600
+
+linux (4.15.0-10.11) bionic; urgency=medium
+
+  * linux: 4.15.0-10.11 -proposed tracker (LP: #1749250)
+
+  * "swiotlb: coherent allocation failed" dmesg spam with linux 4.15.0-9.10
+    (LP: #1749202)
+    - swiotlb: suppress warning when __GFP_NOWARN is set
+    - drm/ttm: specify DMA_ATTR_NO_WARN for huge page pools
+
+  * linux-tools: perf incorrectly linking libbfd (LP: #1748922)
+    - SAUCE: tools -- add ability to disable libbfd
+    - [Packaging] correct disablement of libbfd
+
+  * [Artful] Realtek ALC225: 2 secs noise when a headset plugged in
+    (LP: #1744058)
+    - ALSA: hda/realtek - update ALC225 depop optimize
+
+  * [Artful] Support headset mode for DELL WYSE (LP: #1723913)
+    - SAUCE: ALSA: hda/realtek - Add support headset mode for DELL WYSE
+
+  * headset mic can't be detected on two Dell machines (LP: #1748807)
+    - ALSA: hda/realtek - Support headset mode for ALC215/ALC285/ALC289
+    - ALSA: hda - Fix headset mic detection problem for two Dell machines
+
+  * Bionic update to v4.15.3 stable release (LP: #1749191)
+    - ip6mr: fix stale iterator
+    - net: igmp: add a missing rcu locking section
+    - qlcnic: fix deadlock bug
+    - qmi_wwan: Add support for Quectel EP06
+    - r8169: fix RTL8168EP take too long to complete driver initialization.
+    - tcp: release sk_frag.page in tcp_disconnect
+    - vhost_net: stop device during reset owner
+    - ipv6: addrconf: break critical section in addrconf_verify_rtnl()
+    - ipv6: change route cache aging logic
+    - Revert "defer call to mem_cgroup_sk_alloc()"
+    - net: ipv6: send unsolicited NA after DAD
+    - rocker: fix possible null pointer dereference in
+      rocker_router_fib_event_work
+    - tcp_bbr: fix pacing_gain to always be unity when using lt_bw
+    - cls_u32: add missing RCU annotation.
+    - ipv6: Fix SO_REUSEPORT UDP socket with implicit sk_ipv6only
+    - soreuseport: fix mem leak in reuseport_add_sock()
+    - net_sched: get rid of rcu_barrier() in tcf_block_put_ext()
+    - net: sched: fix use-after-free in tcf_block_put_ext
+    - media: mtk-vcodec: add missing MODULE_LICENSE/DESCRIPTION
+    - media: soc_camera: soc_scale_crop: add missing
+      MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - media: tegra-cec: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - gpio: uniphier: fix mismatch between license text and MODULE_LICENSE
+    - crypto: tcrypt - fix S/G table for test_aead_speed()
+    - Linux 4.15.3
+
+  * bnx2x_attn_int_deasserted3:4323 MC assert! (LP: #1715519) //
+    CVE-2018-1000026
+    - net: create skb_gso_validate_mac_len()
+    - bnx2x: disable GSO where gso_size is too big for hardware
+
+  * ethtool -p fails to light NIC LED on HiSilicon D05 systems (LP: #1748567)
+    - net: hns: add ACPI mode support for ethtool -p
+
+  * CVE-2017-5715 (Spectre v2 Intel)
+    - [Packaging] retpoline files must be sorted
+    - [Packaging] pull in retpoline files
+
+  * [Feature] PXE boot with Intel Omni-Path (LP: #1712031)
+    - d-i: Add hfi1 to nic-modules
+
+  * CVE-2017-5715 (Spectre v2 retpoline)
+    - [Packaging] retpoline -- add call site validation
+    - [Config] disable retpoline checks for first upload
+
+  * Do not duplicate changelog entries assigned to more than one bug or CVE
+    (LP: #1743383)
+    - [Packaging] git-ubuntu-log -- handle multiple bugs/cves better
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 13 Feb 2018 11:33:58 -0600
+
+linux (4.15.0-9.10) bionic; urgency=medium
+
+  * linux: 4.15.0-9.10 -proposed tracker (LP: #1748244)
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] tests -- remove gcc-multilib dependency for arm64
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 08 Feb 2018 11:25:04 -0600
+
+linux (4.15.0-8.9) bionic; urgency=medium
+
+  * linux: 4.15.0-8.9 -proposed tracker (LP: #1748075)
+
+  * Bionic update to v4.15.2 stable release (LP: #1748072)
+    - KVM: x86: Make indirect calls in emulator speculation safe
+    - KVM: VMX: Make indirect call speculation safe
+    - module/retpoline: Warn about missing retpoline in module
+    - x86/cpufeatures: Add CPUID_7_EDX CPUID leaf
+    - x86/cpufeatures: Add Intel feature bits for Speculation Control
+    - x86/cpufeatures: Add AMD feature bits for Speculation Control
+    - x86/msr: Add definitions for new speculation control MSRs
+    - x86/pti: Do not enable PTI on CPUs which are not vulnerable to Meltdown
+    - x86/cpufeature: Blacklist SPEC_CTRL/PRED_CMD on early Spectre v2 microcodes
+    - x86/speculation: Add basic IBPB (Indirect Branch Prediction Barrier) support
+    - x86/alternative: Print unadorned pointers
+    - x86/nospec: Fix header guards names
+    - x86/bugs: Drop one "mitigation" from dmesg
+    - x86/cpu/bugs: Make retpoline module warning conditional
+    - x86/cpufeatures: Clean up Spectre v2 related CPUID flags
+    - x86/retpoline: Simplify vmexit_fill_RSB()
+    - x86/speculation: Simplify indirect_branch_prediction_barrier()
+    - auxdisplay: img-ascii-lcd: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - iio: adc/accel: Fix up module licenses
+    - pinctrl: pxa: pxa2xx: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - ASoC: pcm512x: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - KVM: nVMX: Eliminate vmcs02 pool
+    - KVM: VMX: introduce alloc_loaded_vmcs
+    - objtool: Improve retpoline alternative handling
+    - objtool: Add support for alternatives at the end of a section
+    - objtool: Warn on stripped section symbol
+    - x86/mm: Fix overlap of i386 CPU_ENTRY_AREA with FIX_BTMAP
+    - x86/spectre: Check CONFIG_RETPOLINE in command line parser
+    - x86/entry/64: Remove the SYSCALL64 fast path
+    - x86/entry/64: Push extra regs right away
+    - x86/asm: Move 'status' from thread_struct to thread_info
+    - Documentation: Document array_index_nospec
+    - array_index_nospec: Sanitize speculative array de-references
+    - x86: Implement array_index_mask_nospec
+    - x86: Introduce barrier_nospec
+    - x86: Introduce __uaccess_begin_nospec() and uaccess_try_nospec
+    - x86/usercopy: Replace open coded stac/clac with __uaccess_{begin, end}
+    - x86/uaccess: Use __uaccess_begin_nospec() and uaccess_try_nospec
+    - x86/get_user: Use pointer masking to limit speculation
+    - x86/syscall: Sanitize syscall table de-references under speculation
+    - vfs, fdtable: Prevent bounds-check bypass via speculative execution
+    - nl80211: Sanitize array index in parse_txq_params
+    - x86/spectre: Report get_user mitigation for spectre_v1
+    - x86/spectre: Fix spelling mistake: "vunerable"-> "vulnerable"
+    - x86/cpuid: Fix up "virtual" IBRS/IBPB/STIBP feature bits on Intel
+    - x86/speculation: Use Indirect Branch Prediction Barrier in context switch
+    - x86/paravirt: Remove 'noreplace-paravirt' cmdline option
+    - KVM: VMX: make MSR bitmaps per-VCPU
+    - x86/kvm: Update spectre-v1 mitigation
+    - x86/retpoline: Avoid retpolines for built-in __init functions
+    - x86/spectre: Simplify spectre_v2 command line parsing
+    - x86/pti: Mark constant arrays as __initconst
+    - x86/speculation: Fix typo IBRS_ATT, which should be IBRS_ALL
+    - KVM/x86: Update the reverse_cpuid list to include CPUID_7_EDX
+    - KVM/x86: Add IBPB support
+    - KVM/VMX: Emulate MSR_IA32_ARCH_CAPABILITIES
+    - KVM/VMX: Allow direct access to MSR_IA32_SPEC_CTRL
+    - KVM/SVM: Allow direct access to MSR_IA32_SPEC_CTRL
+    - serial: core: mark port as initialized after successful IRQ change
+    - fpga: region: release of_parse_phandle nodes after use
+    - Linux 4.15.2
+
+  * Add support for the NIC on SynQuacer E-Series boards (LP: #1747792)
+    - net: phy: core: remove now uneeded disabling of interrupts
+    - [Config] CONFIG_NET_VENDOR_SOCIONEXT=y & CONFIG_SNI_NETSEC=m
+    - net: socionext: Add Synquacer NetSec driver
+    - net: socionext: include linux/io.h to fix build
+    - net: socionext: Fix error return code in netsec_netdev_open()
+
+  * [Artful/Bionic] [Config] enable EDAC_GHES for ARM64 (LP: #1747746)
+    - [Config] CONFIG_EDAC_GHES=y
+
+  * support thunderx2 vendor pmu events (LP: #1747523)
+    - perf pmu: Pass pmu as a parameter to get_cpuid_str()
+    - perf tools arm64: Add support for get_cpuid_str function.
+    - perf pmu: Add helper function is_pmu_core to detect PMU CORE devices
+    - perf vendor events arm64: Add ThunderX2 implementation defined pmu core
+      events
+    - perf pmu: Add check for valid cpuid in perf_pmu__find_map()
+
+  * linux 4.14.0-7.9 ADT test failure with linux 4.14.0-7.9 (LP: #1732463)
+    - SAUCE: mm: disable vma based swap readahead by default
+    - SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Fix CONFIG_PROFILE_ALL_BRANCHES annotations
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 07 Feb 2018 21:13:27 -0600
+
+linux (4.15.0-7.8) bionic; urgency=medium
+
+  * Bionic update to v4.15.1 stable release (LP: #1747169)
+    - Bluetooth: hci_serdev: Init hci_uart proto_lock to avoid oops
+    - tools/gpio: Fix build error with musl libc
+    - gpio: stmpe: i2c transfer are forbiden in atomic context
+    - gpio: Fix kernel stack leak to userspace
+    - ALSA: hda - Reduce the suspend time consumption for ALC256
+    - crypto: ecdh - fix typo in KPP dependency of CRYPTO_ECDH
+    - crypto: aesni - handle zero length dst buffer
+    - crypto: aesni - fix typo in generic_gcmaes_decrypt
+    - crypto: aesni - add wrapper for generic gcm(aes)
+    - crypto: aesni - Fix out-of-bounds access of the data buffer in generic-gcm-
+      aesni
+    - crypto: aesni - Fix out-of-bounds access of the AAD buffer in generic-gcm-
+      aesni
+    - crypto: inside-secure - fix hash when length is a multiple of a block
+    - crypto: inside-secure - avoid unmapping DMA memory that was not mapped
+    - crypto: sha3-generic - fixes for alignment and big endian operation
+    - crypto: af_alg - whitelist mask and type
+    - HID: wacom: EKR: ensure devres groups at higher indexes are released
+    - HID: wacom: Fix reporting of touch toggle (WACOM_HID_WD_MUTE_DEVICE) events
+    - power: reset: zx-reboot: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - gpio: iop: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - gpio: ath79: add missing MODULE_DESCRIPTION/LICENSE
+    - mtd: nand: denali_pci: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - igb: Free IRQs when device is hotplugged
+    - ima/policy: fix parsing of fsuuid
+    - scsi: aacraid: Fix udev inquiry race condition
+    - scsi: aacraid: Fix hang in kdump
+    - scsi: storvsc: missing error code in storvsc_probe()
+    - staging: lustre: separate a connection destroy from free struct kib_conn
+    - staging: ccree: NULLify backup_info when unused
+    - staging: ccree: fix fips event irq handling build
+    - tty: fix data race between tty_init_dev and flush of buf
+    - usb: option: Add support for FS040U modem
+    - USB: serial: pl2303: new device id for Chilitag
+    - USB: cdc-acm: Do not log urb submission errors on disconnect
+    - CDC-ACM: apply quirk for card reader
+    - USB: serial: io_edgeport: fix possible sleep-in-atomic
+    - usbip: prevent bind loops on devices attached to vhci_hcd
+    - usbip: list: don't list devices attached to vhci_hcd
+    - USB: serial: simple: add Motorola Tetra driver
+    - usb: f_fs: Prevent gadget unbind if it is already unbound
+    - usb: uas: unconditionally bring back host after reset
+    - usb/gadget: Fix "high bandwidth" check in usb_gadget_ep_match_desc()
+    - ANDROID: binder: remove waitqueue when thread exits.
+    - android: binder: use VM_ALLOC to get vm area
+    - mei: me: allow runtime pm for platform with D0i3
+    - serial: 8250_of: fix return code when probe function fails to get reset
+    - serial: 8250_uniphier: fix error return code in uniphier_uart_probe()
+    - serial: 8250_dw: Revert "Improve clock rate setting"
+    - serial: imx: Only wakeup via RTSDEN bit if the system has RTS/CTS
+    - spi: imx: do not access registers while clocks disabled
+    - iio: adc: stm32: fix scan of multiple channels with DMA
+    - iio: chemical: ccs811: Fix output of IIO_CONCENTRATION channels
+    - test_firmware: fix missing unlock on error in config_num_requests_store()
+    - Input: synaptics-rmi4 - unmask F03 interrupts when port is opened
+    - Input: synaptics-rmi4 - do not delete interrupt memory too early
+    - x86/efi: Clarify that reset attack mitigation needs appropriate userspace
+    - Linux 4.15.1
+
+  * Dell XPS 13 9360 bluetooth (Atheros) won't connect after resume
+    (LP: #1744712)
+    - Revert "Bluetooth: btusb: fix QCA Rome suspend/resume"
+    - Bluetooth: btusb: Restore QCA Rome suspend/resume fix with a "rewritten"
+      version
+
+  * apparmor profile load in stacked policy container fails (LP: #1746463)
+    - SAUCE: apparmor: fix display of .ns_name for containers
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 04 Feb 2018 11:56:32 +0100
+
+linux (4.15.0-6.7) bionic; urgency=low
+
+  * upload urgency should be medium by default (LP: #1745338)
+    - [Packaging] update urgency to medium by default
+
+  * Shutdown hang on 16.04 with iscsi targets (LP: #1569925)
+    - scsi: libiscsi: Allow sd_shutdown on bad transport
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.5-1ubuntu1, zfs to 0.7.5-1ubuntu1
+    - Revert "UBUNTU: SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM"
+    - Revert "UBUNTU: SAUCE: mm: disable vma based swap readahead by default"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 29 Jan 2018 08:47:07 -0600
+
+linux (4.15.0-5.6) bionic; urgency=low
+
+  * $(LOCAL_ENV_CC) and $(LOCAL_ENV_DISTCC_HOSTS) should be properly quoted
+    (LP: #1744077)
+    - [Debian] pass LOCAL_ENV_CC and LOCAL_ENV_DISTCC_HOSTS properly
+
+  * Missing install-time driver for QLogic QED 25/40/100Gb Ethernet NIC
+    (LP: #1743638)
+    - [d-i] Add qede to nic-modules udeb
+
+  * boot failure on AMD Raven + WesternXT (LP: #1742759)
+    - SAUCE: drm/amdgpu: add atpx quirk handling (v2)
+
+  * Unable to handle kernel NULL pointer dereference at isci_task_abort_task
+    (LP: #1726519)
+    - SAUCE: Revert "scsi: libsas: allow async aborts"
+
+  * Update Ubuntu-4.15.0 config to support Intel Atom devices (LP: #1739939)
+    - [Config] CONFIG_SERIAL_DEV_BUS=y, CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v4.15-rc7
+    - [Config] CONFIG_CPU_ISOLATION=y
+    - [Config] Update annotations following config review
+    - Revert "UBUNTU: SAUCE: Import aufs driver"
+    - SAUCE: Import aufs driver
+    - ubuntu: vbox -- update to 5.2.6-dfsg-1
+    - ubuntu: vbox: build fixes for 4.15
+    - ubuntu: vbox -- update to 5.2.6-dfsg-2
+    - hio: updates for timer api changes in 4.15
+    - enable hio build
+    - Rebase to v4.15-rc9
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc9
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 22 Jan 2018 10:16:05 -0600
+
+linux (4.15.0-4.5) bionic; urgency=low
+
+  * [0cf3:e010] QCA6174A XR failed to pair with bt 4.0 device  (LP: #1741166)
+    - SAUCE: Bluetooth: btusb: Add support for 0cf3:e010
+
+  * External HDMI monitor failed to show screen on Lenovo X1 series
+    (LP: #1738523)
+    - SAUCE: drm/i915: Disable writing of TMDS_OE on Lenovo ThinkPad X1 series
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] autoreconstruct - add resoration of execute permissions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 10 Jan 2018 10:24:22 -0600
+
+linux (4.15.0-3.4) bionic; urgency=low
+
+  * ubuntu/xr-usb-serial didn't get built in zesty and artful (LP: #1733281)
+    - SAUCE: make sure ubuntu/xr-usb-serial builds for x86
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 03 Jan 2018 20:20:43 -0600
+
+linux (4.15.0-2.3) bionic; urgency=low
+
+  * nvidia-graphics-drivers-384 384.90-0ubuntu6 ADT test failure with linux
+    4.15.0-1.2 (LP: #1737752)
+    - x86/mm: Unbreak modules that use the DMA API
+
+  * Ubuntu 17.10 corrupting BIOS - many LENOVO laptops models (LP: #1734147)
+    - [Config] CONFIG_SPI_INTEL_SPI_*=n
+
+  * power: commonise configs IBMVETH/IBMVSCSI and ensure both are in linux-image
+    and udebs (LP: #1521712)
+    - [Config] Include ibmvnic in nic-modules
+
+  * Enable arm64 emulation of removed ARMv7 instructions (LP: #1545542)
+    - [Config] Enable support for emulation of deprecated ARMv8 instructions
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl with 4.15 compat fix (LP:#1737761)
+    - Enable zfs build
+    - [Debian] add icp to zfs-modules.ignore
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 18 Dec 2017 09:27:13 -0600
+
+linux (4.15.0-1.2) bionic; urgency=low
+
+  * Disabling zfs does not always disable module checks for the zfs modules
+    (LP: #1737176)
+    - [Packaging] disable zfs module checks when zfs is disabled
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_UNWINDER_FRAME_POINTER=y for amd64
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 10 Dec 2017 22:07:19 -0600
+
+linux (4.15.0-0.1) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu: vbox -- update to 5.2.2-dfsg-2
+    - ubuntu: vbox: build fixes for 4.15
+    - disable hio build
+    - [Config] Update kernel lockdown options to fix build errors
+    - Disable zfs build
+    - SAUCE: Import aufs driver
+    - [Config] Enable AUFS config options
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 08 Dec 2017 13:55:42 -0600
+
+linux (4.14.0-11.13) bionic; urgency=low
+
+  * linux: 4.14.0-11.13 -proposed tracker (LP: #1736168)
+
+  * CVE-2017-1000405
+    - mm, thp: Do not make page table dirty unconditionally in touch_p[mu]d()
+
+  * linux 4.14.0-7.9 ADT test failure with linux 4.14.0-7.9 (LP: #1732463)
+    - SAUCE: mm: disable vma based swap readahead by default
+    - SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM
+
+  * Bionic update to v4.14.3 stable release (LP: #1735843)
+    - s390: fix transactional execution control register handling
+    - s390/noexec: execute kexec datamover without DAT
+    - s390/runtime instrumention: fix possible memory corruption
+    - s390/guarded storage: fix possible memory corruption
+    - s390/disassembler: add missing end marker for e7 table
+    - s390/disassembler: increase show_code buffer size
+    - ACPI / PM: Fix acpi_pm_notifier_lock vs flush_workqueue() deadlock
+    - ACPI / EC: Fix regression related to triggering source of EC event handling
+    - cpufreq: schedutil: Reset cached_raw_freq when not in sync with next_freq
+    - serdev: fix registration of second slave
+    - sched: Make resched_cpu() unconditional
+    - lib/mpi: call cond_resched() from mpi_powm() loop
+    - x86/boot: Fix boot failure when SMP MP-table is based at 0
+    - x86/decoder: Add new TEST instruction pattern
+    - x86/entry/64: Fix entry_SYSCALL_64_after_hwframe() IRQ tracing
+    - x86/entry/64: Add missing irqflags tracing to native_load_gs_index()
+    - perf/x86/intel: Hide TSX events when RTM is not supported
+    - arm64: Implement arch-specific pte_access_permitted()
+    - ARM: 8722/1: mm: make STRICT_KERNEL_RWX effective for LPAE
+    - ARM: 8721/1: mm: dump: check hardware RO bit for LPAE
+    - uapi: fix linux/tls.h userspace compilation error
+    - uapi: fix linux/rxrpc.h userspace compilation errors
+    - MIPS: cmpxchg64() and HAVE_VIRT_CPU_ACCOUNTING_GEN don't work for 32-bit SMP
+    - MIPS: ralink: Fix MT7628 pinmux
+    - MIPS: ralink: Fix typo in mt7628 pinmux function
+    - net: mvneta: fix handling of the Tx descriptor counter
+    - nbd: wait uninterruptible for the dead timeout
+    - nbd: don't start req until after the dead connection logic
+    - PM / OPP: Add missing of_node_put(np)
+    - PCI/ASPM: Account for downstream device's Port Common_Mode_Restore_Time
+    - PCI/ASPM: Use correct capability pointer to program LTR_L1.2_THRESHOLD
+    - PCI: hv: Use effective affinity mask
+    - PCI: Set Cavium ACS capability quirk flags to assert RR/CR/SV/UF
+    - PCI: Apply Cavium ThunderX ACS quirk to more Root Ports
+    - ALSA: hda: Add Raven PCI ID
+    - dm integrity: allow unaligned bv_offset
+    - dm cache: fix race condition in the writeback mode overwrite_bio
+      optimisation
+    - dm crypt: allow unaligned bv_offset
+    - dm zoned: ignore last smaller runt zone
+    - dm mpath: remove annoying message of 'blk_get_request() returned -11'
+    - dm bufio: fix integer overflow when limiting maximum cache size
+    - ovl: Put upperdentry if ovl_check_origin() fails
+    - dm: allocate struct mapped_device with kvzalloc
+    - sched/rt: Simplify the IPI based RT balancing logic
+    - MIPS: pci: Remove KERN_WARN instance inside the mt7620 driver
+    - dm: fix race between dm_get_from_kobject() and __dm_destroy()
+    - dm: discard support requires all targets in a table support discards
+    - MIPS: Fix odd fp register warnings with MIPS64r2
+    - MIPS: Fix MIPS64 FP save/restore on 32-bit kernels
+    - MIPS: dts: remove bogus bcm96358nb4ser.dtb from dtb-y entry
+    - MIPS: Fix an n32 core file generation regset support regression
+    - MIPS: BCM47XX: Fix LED inversion for WRT54GSv1
+    - MIPS: math-emu: Fix final emulation phase for certain instructions
+    - rt2x00usb: mark device removed when get ENOENT usb error
+    - mm/z3fold.c: use kref to prevent page free/compact race
+    - autofs: don't fail mount for transient error
+    - nilfs2: fix race condition that causes file system corruption
+    - fscrypt: lock mutex before checking for bounce page pool
+    - eCryptfs: use after free in ecryptfs_release_messaging()
+    - libceph: don't WARN() if user tries to add invalid key
+    - bcache: check ca->alloc_thread initialized before wake up it
+    - fs: guard_bio_eod() needs to consider partitions
+    - fanotify: fix fsnotify_prepare_user_wait() failure
+    - isofs: fix timestamps beyond 2027
+    - btrfs: change how we decide to commit transactions during flushing
+    - f2fs: expose some sectors to user in inline data or dentry case
+    - NFS: Fix typo in nomigration mount option
+    - NFS: Revert "NFS: Move the flock open mode check into nfs_flock()"
+    - nfs: Fix ugly referral attributes
+    - NFS: Avoid RCU usage in tracepoints
+    - NFS: revalidate "." etc correctly on "open".
+    - nfsd: deal with revoked delegations appropriately
+    - rtlwifi: rtl8192ee: Fix memory leak when loading firmware
+    - rtlwifi: fix uninitialized rtlhal->last_suspend_sec time
+    - iwlwifi: fix firmware names for 9000 and A000 series hw
+    - md: fix deadlock error in recent patch.
+    - md: don't check MD_SB_CHANGE_CLEAN in md_allow_write
+    - Bluetooth: btqcomsmd: Add support for BD address setup
+    - md/bitmap: revert a patch
+    - fsnotify: clean up fsnotify_prepare/finish_user_wait()
+    - fsnotify: pin both inode and vfsmount mark
+    - fsnotify: fix pinning group in fsnotify_prepare_user_wait()
+    - ata: fixes kernel crash while tracing ata_eh_link_autopsy event
+    - ext4: fix interaction between i_size, fallocate, and delalloc after a crash
+    - ext4: prevent data corruption with inline data + DAX
+    - ext4: prevent data corruption with journaling + DAX
+    - ALSA: pcm: update tstamp only if audio_tstamp changed
+    - ALSA: usb-audio: Add sanity checks to FE parser
+    - ALSA: usb-audio: Fix potential out-of-bound access at parsing SU
+    - ALSA: usb-audio: Add sanity checks in v2 clock parsers
+    - ALSA: timer: Remove kernel warning at compat ioctl error paths
+    - ALSA: hda/realtek - Fix ALC275 no sound issue
+    - ALSA: hda: Fix too short HDMI/DP chmap reporting
+    - ALSA: hda - Fix yet remaining issue with vmaster 0dB initialization
+    - ALSA: hda/realtek - Fix ALC700 family no sound issue
+    - ASoC: sun8i-codec: Invert Master / Slave condition
+    - ASoC: sun8i-codec: Fix left and right channels inversion
+    - ASoC: sun8i-codec: Set the BCLK divider
+    - mfd: lpc_ich: Avoton/Rangeley uses SPI_BYT method
+    - fix a page leak in vhost_scsi_iov_to_sgl() error recovery
+    - 9p: Fix missing commas in mount options
+    - fs/9p: Compare qid.path in v9fs_test_inode
+    - net/9p: Switch to wait_event_killable()
+    - scsi: qla2xxx: Suppress a kernel complaint in qla_init_base_qpair()
+    - scsi: sd_zbc: Fix sd_zbc_read_zoned_characteristics()
+    - scsi: lpfc: fix pci hot plug crash in timer management routines
+    - scsi: lpfc: fix pci hot plug crash in list_add call
+    - scsi: lpfc: Fix crash receiving ELS while detaching driver
+    - scsi: lpfc: Fix FCP hba_wqidx assignment
+    - scsi: lpfc: Fix oops if nvmet_fc_register_targetport fails
+    - iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref
+    - iscsi-target: Fix non-immediate TMR reference leak
+    - target: fix null pointer regression in core_tmr_drain_tmr_list
+    - target: fix buffer offset in core_scsi3_pri_read_full_status
+    - target: Fix QUEUE_FULL + SCSI task attribute handling
+    - target: Fix caw_sem leak in transport_generic_request_failure
+    - target: Fix quiese during transport_write_pending_qf endless loop
+    - target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK
+    - mtd: Avoid probe failures when mtd->dbg.dfs_dir is invalid
+    - mtd: nand: Export nand_reset() symbol
+    - mtd: nand: atmel: Actually use the PM ops
+    - mtd: nand: omap2: Fix subpage write
+    - mtd: nand: Fix writing mtdoops to nand flash.
+    - mtd: nand: mtk: fix infinite ECC decode IRQ issue
+    - mailbox: bcm-flexrm-mailbox: Fix FlexRM ring flush sequence
+    - p54: don't unregister leds when they are not initialized
+    - block: Fix a race between blk_cleanup_queue() and timeout handling
+    - raid1: prevent freeze_array/wait_all_barriers deadlock
+    - genirq: Track whether the trigger type has been set
+    - irqchip/gic-v3: Fix ppi-partitions lookup
+    - lockd: double unregister of inetaddr notifiers
+    - KVM: PPC: Book3S HV: Don't call real-mode XICS hypercall handlers if not
+      enabled
+    - KVM: nVMX: set IDTR and GDTR limits when loading L1 host state
+    - KVM: SVM: obey guest PAT
+    - kvm: vmx: Reinstate support for CPUs without virtual NMI
+    - dax: fix PMD faults on zero-length files
+    - dax: fix general protection fault in dax_alloc_inode
+    - SUNRPC: Fix tracepoint storage issues with svc_recv and svc_rqst_status
+    - clk: ti: dra7-atl-clock: fix child-node lookups
+    - libnvdimm, dimm: clear 'locked' status on successful DIMM enable
+    - libnvdimm, pfn: make 'resource' attribute only readable by root
+    - libnvdimm, namespace: fix label initialization to use valid seq numbers
+    - libnvdimm, region : make 'resource' attribute only readable by root
+    - libnvdimm, namespace: make 'resource' attribute only readable by root
+    - svcrdma: Preserve CB send buffer across retransmits
+    - IB/srpt: Do not accept invalid initiator port names
+    - IB/cm: Fix memory corruption in handling CM request
+    - IB/hfi1: Fix incorrect available receive user context count
+    - IB/srp: Avoid that a cable pull can trigger a kernel crash
+    - IB/core: Avoid crash on pkey enforcement failed in received MADs
+    - IB/core: Only maintain real QPs in the security lists
+    - NFC: fix device-allocation error return
+    - spi-nor: intel-spi: Fix broken software sequencing codes
+    - i40e: Use smp_rmb rather than read_barrier_depends
+    - igb: Use smp_rmb rather than read_barrier_depends
+    - igbvf: Use smp_rmb rather than read_barrier_depends
+    - ixgbevf: Use smp_rmb rather than read_barrier_depends
+    - i40evf: Use smp_rmb rather than read_barrier_depends
+    - fm10k: Use smp_rmb rather than read_barrier_depends
+    - ixgbe: Fix skb list corruption on Power systems
+    - parisc: Fix validity check of pointer size argument in new CAS
+      implementation
+    - powerpc: Fix boot on BOOK3S_32 with CONFIG_STRICT_KERNEL_RWX
+    - powerpc/mm/radix: Fix crashes on Power9 DD1 with radix MMU and STRICT_RWX
+    - powerpc/perf/imc: Use cpu_to_node() not topology_physical_package_id()
+    - powerpc/signal: Properly handle return value from uprobe_deny_signal()
+    - powerpc/64s: Fix masking of SRR1 bits on instruction fault
+    - powerpc/64s/radix: Fix 128TB-512TB virtual address boundary case allocation
+    - powerpc/64s/hash: Fix 512T hint detection to use >= 128T
+    - powerpc/64s/hash: Fix 128TB-512TB virtual address boundary case allocation
+    - powerpc/64s/hash: Fix fork() with 512TB process address space
+    - powerpc/64s/hash: Allow MAP_FIXED allocations to cross 128TB boundary
+    - media: Don't do DMA on stack for firmware upload in the AS102 driver
+    - media: rc: check for integer overflow
+    - media: rc: nec decoder should not send both repeat and keycode
+    - cx231xx-cards: fix NULL-deref on missing association descriptor
+    - media: v4l2-ctrl: Fix flags field on Control events
+    - media: venus: fix wrong size on dma_free
+    - media: venus: venc: fix bytesused v4l2_plane field
+    - media: venus: reimplement decoder stop command
+    - ARM64: dts: meson-gxl: Add alternate ARM Trusted Firmware reserved memory
+      zone
+    - iwlwifi: fix wrong struct for a000 device
+    - iwlwifi: add a new a000 device
+    - iwlwifi: pcie: sort IDs for the 9000 series for easier comparisons
+    - iwlwifi: add new cards for a000 series
+    - iwlwifi: add new cards for 8265 series
+    - iwlwifi: add new cards for 8260 series
+    - iwlwifi: fix PCI IDs and configuration mapping for 9000 series
+    - iwlwifi: mvm: support version 7 of the SCAN_REQ_UMAC FW command
+    - e1000e: Fix error path in link detection
+    - e1000e: Fix return value test
+    - e1000e: Separate signaling for link check/link up
+    - e1000e: Avoid receiver overrun interrupt bursts
+    - e1000e: fix buffer overrun while the I219 is processing DMA transactions
+    - Linux 4.14.3
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: s390/topology: don't inline cpu_to_node
+    - SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to 0.7.3-1ubuntu1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 04 Dec 2017 09:08:07 -0600
+
+linux (4.14.0-10.12) bionic; urgency=low
+
+  * linux: 4.14.0-10.12 -proposed tracker (LP: #1734901)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Enable the ACPI kernel debugger and acpidbg tool
+    - [Packaging] Include arch/arm64/kernel/ftrace-mod.o in headers package
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 Nov 2017 08:46:49 -0600
+
+linux (4.14.0-9.11) bionic; urgency=low
+
+  * linux: 4.14.0-9.11 -proposed tracker (LP: #1734728)
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to
+      0.7.3-1ubuntu1"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Nov 2017 12:44:48 -0600
+
+linux (4.14.0-8.10) bionic; urgency=low
+
+  * linux: 4.14.0-8.10 -proposed tracker (LP: #1734695)
+
+  * Bionic update to v4.14.2 stable release (LP: #1734694)
+    - bio: ensure __bio_clone_fast copies bi_partno
+    - af_netlink: ensure that NLMSG_DONE never fails in dumps
+    - vxlan: fix the issue that neigh proxy blocks all icmpv6 packets
+    - net: cdc_ncm: GetNtbFormat endian fix
+    - fealnx: Fix building error on MIPS
+    - net/sctp: Always set scope_id in sctp_inet6_skb_msgname
+    - ima: do not update security.ima if appraisal status is not INTEGRITY_PASS
+    - serial: omap: Fix EFR write on RTS deassertion
+    - serial: 8250_fintek: Fix finding base_port with activated SuperIO
+    - tpm-dev-common: Reject too short writes
+    - rcu: Fix up pending cbs check in rcu_prepare_for_idle
+    - mm/pagewalk.c: report holes in hugetlb ranges
+    - ocfs2: fix cluster hang after a node dies
+    - ocfs2: should wait dio before inode lock in ocfs2_setattr()
+    - ipmi: fix unsigned long underflow
+    - mm/page_alloc.c: broken deferred calculation
+    - mm/page_ext.c: check if page_ext is not prepared
+    - coda: fix 'kernel memory exposure attempt' in fsync
+    - ipmi: Prefer ACPI system interfaces over SMBIOS ones
+    - Linux 4.14.2
+
+  * Bionic update to v4.14.1 stable release (LP: #1734693)
+    - EDAC, sb_edac: Don't create a second memory controller if HA1 is not present
+    - dmaengine: dmatest: warn user when dma test times out
+    - media: imon: Fix null-ptr-deref in imon_probe
+    - media: dib0700: fix invalid dvb_detach argument
+    - crypto: dh - Fix double free of ctx->p
+    - crypto: dh - Don't permit 'p' to be 0
+    - crypto: dh - Don't permit 'key' or 'g' size longer than 'p'
+    - crypto: brcm - Explicity ACK mailbox message
+    - USB: early: Use new USB product ID and strings for DbC device
+    - USB: usbfs: compute urb->actual_length for isochronous
+    - USB: Add delay-init quirk for Corsair K70 LUX keyboards
+    - usb: gadget: f_fs: Fix use-after-free in ffs_free_inst
+    - USB: serial: metro-usb: stop I/O after failed open
+    - USB: serial: Change DbC debug device binding ID
+    - USB: serial: qcserial: add pid/vid for Sierra Wireless EM7355 fw update
+    - USB: serial: garmin_gps: fix I/O after failed probe and remove
+    - USB: serial: garmin_gps: fix memory leak on probe errors
+    - selftests/x86/protection_keys: Fix syscall NR redefinition warnings
+    - x86/MCE/AMD: Always give panic severity for UC errors in kernel context
+    - platform/x86: peaq-wmi: Add DMI check before binding to the WMI interface
+    - platform/x86: peaq_wmi: Fix missing terminating entry for peaq_dmi_table
+    - HID: cp2112: add HIDRAW dependency
+    - HID: wacom: generic: Recognize WACOM_HID_WD_PEN as a type of pen collection
+    - rpmsg: glink: Add missing MODULE_LICENSE
+    - staging: wilc1000: Fix bssid buffer offset in Txq
+    - staging: sm750fb: Fix parameter mistake in poke32
+    - staging: ccree: fix 64 bit scatter/gather DMA ops
+    - staging: greybus: spilib: fix use-after-free after deregistration
+    - staging: rtl8188eu: Revert 4 commits breaking ARP
+    - spi: fix use-after-free at controller deregistration
+    - sparc32: Add cmpxchg64().
+    - sparc64: mmu_context: Add missing include files
+    - sparc64: Fix page table walk for PUD hugepages
+    - Linux 4.14.1
+
+  * Set PANIC_TIMEOUT=10 on Power Systems (LP: #1730660)
+    - [Config]: Set PANIC_TIMEOUT=10 on ppc64el
+
+  * enable CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH easily confuse users
+    (LP: #1732627)
+    - [Config] CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH=n
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to 0.7.3-1ubuntu1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Nov 2017 07:43:44 -0600
+
+linux (4.14.0-7.9) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor: add base infastructure for socket mediation
+    - SAUCE: apparmor: af_unix mediation
+    - SAUCE: LSM stacking: procfs: add smack subdir to attrs
+    - SAUCE: LSM stacking: LSM: manage credential security blobs
+    - SAUCE: LSM stacking: LSM: Manage file security blobs
+    - SAUCE: LSM stacking: LSM: manage task security blobs
+    - SAUCE: LSM stacking: LSM: Infrastructure management of the remaining blobs
+    - SAUCE: LSM stacking: LSM: general but not extreme module stacking
+    - SAUCE: LSM stacking: LSM: Complete task_alloc hook
+    - SAUCE: LSM stacking: fixup procsfs: add smack subdir to attrs
+    - SAUCE: LSM stacking: fixup initialize task->security
+    - SAUCE: LSM stacking: fixup: alloc_task_ctx is dead code
+    - SAUCE: LSM stacking: add support for stacking getpeersec_stream
+    - SAUCE: LSM stacking: add stacking support to apparmor network hooks
+    - SAUCE: LSM stacking: fixup apparmor stacking enablement
+    - SAUCE: LSM stacking: fixup stacking kconfig
+    - SAUCE: LSM stacking: allow selecting multiple LSMs using kernel boot params
+    - SAUCE: LSM stacking: provide prctl interface for setting context
+    - SAUCE: LSM stacking: inherit current display LSM
+    - SAUCE: LSM stacking: keep an index for each registered LSM
+    - SAUCE: LSM stacking: verify display LSM
+    - SAUCE: LSM stacking: provide a way to specify the default display lsm
+    - SAUCE: LSM stacking: make sure LSM blob align on 64 bit boundaries
+    - SAUCE: LSM stacking: add /proc/<pid>/attr/display_lsm
+    - SAUCE: LSM stacking: add Kconfig to set default display LSM
+    - SAUCE: LSM stacking: add configs for LSM stacking
+    - SAUCE: LSM stacking: check for invalid zero sized writes
+    - [Config] Run updateconfigs after merging LSM stacking
+    - [Config] CONFIG_AMD_MEM_ENCRYPT=y
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 13 Nov 2017 08:12:08 -0600
+
+linux (4.14.0-6.8) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: add workarounds to enable ZFS for 4.14
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 06 Nov 2017 11:39:00 -0600
+
+linux (4.14.0-5.7) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Fix invocation of dh_prep for dbgsym packages
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 31 Oct 2017 07:07:23 -0500
+
+linux (4.14.0-4.5) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] virtualbox -- reduce in kernel module versions
+    - vbox-update: Fix up KERN_DIR definitions
+    - ubuntu: vbox -- update to 5.2.0-dfsg-2
+    - [Config] CONFIG_AMD_MEM_ENCRYPT=n
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 30 Oct 2017 13:29:20 -0500
+
+linux (4.14.0-3.4) artful; urgency=low
+
+  * Touchpad and TrackPoint Dose Not Work on Lenovo X1C6 and X280 (LP: #1723986)
+    - SAUCE: Input: synaptics-rmi4 - RMI4 can also use SMBUS version 3
+    - SAUCE: Input: synaptics - Lenovo X1 Carbon 5 should use SMBUS/RMI
+    - SAUCE: Input: synaptics - add Intertouch support on X1 Carbon 6th and X280
+
+  * powerpc/64s: Add workaround for P9 vector CI load issuenext (LP: #1721070)
+    - powerpc/64s: Add workaround for P9 vector CI load issue
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: staging: vboxvideo: Fix reporting invalid suggested-offset-properties
+    - [Config] CONFIG_DRM_VBOXVIDEO=m
+    - SAUCE: Import aufs driver
+    - [Config] Enable aufs
+    - [Config] Reorder annotations file after enabling aufs
+    - vbox-update: Disable imported vboxvideo module
+    - ubuntu: vbox -- update to 5.1.30-dfsg-1
+    - Enable vbox
+    - hio: Use correct sizes when initializing ssd_index_bits* arrays
+    - hio: Update io stat accounting for 4.14
+    - Enable hio
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc5
+  * Rebase to v4.14-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 23 Oct 2017 13:53:52 -0500
+
+linux (4.14.0-2.3) artful; urgency=low
+
+  * [Bug] USB controller failed to respond on Denverton after loading
+    intel_th_pci module (LP: #1715833)
+    - SAUCE: PCI: Disable broken RTIT_BAR of Intel TH
+
+  * CONFIG_DEBUG_FS is not enabled by "make zfcpdump_defconfig" with Ubuntu
+    17.10 (kernel 4.13) (LP: #1719290)
+    - SAUCE: s390: update zfcpdump_defconfig
+
+  * Add installer support for Broadcom BCM573xx network drivers. (LP: #1720466)
+    - d-i: Add bnxt_en to nic-modules.
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Update annotations for 4.14-rc2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc3
+  * Rebase to v4.14-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 11 Oct 2017 16:04:27 -0500
+
+linux (4.14.0-1.2) artful; urgency=low
+
+  * [Bug] USB 3.1 Gen2 works as 5Gbps (LP: #1720045)
+    - xhci: set missing SuperSpeedPlus Link Protocol bit in roothub descriptor
+
+  * Please make linux-libc-dev Provide: aufs-dev (LP: #1716091)
+    - [Packaging] Add aufs-dev to the Provides: for linux-libc-dev
+
+  * Upgrade to 4.13.0-11.12 in artful amd64 VM breaks display on wayland
+    (LP: #1718679)
+    - [Config] CONFIG_DRM_VBOXVIDEO=n
+
+  * ipmmu-vmsa driver breaks arm64 boots (LP: #1718734)
+    - [Config] Disable CONFIG_IPMMU_VMSA on arm64
+
+  * autopkgtest profile fails to build on armhf (LP: #1717920)
+    - [Packaging] autopkgtest -- disable d-i when dropping flavours
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_I2C_XLP9XX=m
+    - [Packaging] Use SRCPKGNAME rather than hard-coding the source package name
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 29 Sep 2017 09:09:11 -0400
+
+linux (4.14.0-0.1) artful; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - Disable vbox build
+    - Disable hio build
+    - Disable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 19 Sep 2017 20:22:29 -0500
+
+linux (4.13.0-11.12) artful; urgency=low
+
+  * linux: 4.13.0-11.12 -proposed tracker (LP: #1716699)
+
+  * kernel panic -not syncing: Fatal exception: panic_on_oops (LP: #1708399)
+    - s390/mm: fix local TLB flushing vs. detach of an mm address space
+    - s390/mm: fix race on mm->context.flush_mm
+
+  * CVE-2017-1000251
+    - Bluetooth: Properly check L2CAP config option output buffer length
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 12 Sep 2017 10:18:38 -0500
+
+linux (4.13.0-10.11) artful; urgency=low
+
+  * linux: 4.13.0-10.11 -proposed tracker (LP: #1716287)
+
+  * please add aufs-dkms to the Provides: for the kernel packages (LP: #1716093)
+    - [Packaging] Add aufs-dkms to the Provides: for kernel packages
+
+  * Artful update to v4.13.1 stable release (LP: #1716284)
+    - usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard
+    - USB: serial: option: add support for D-Link DWM-157 C1
+    - usb: Add device quirk for Logitech HD Pro Webcam C920-C
+    - usb:xhci:Fix regression when ATI chipsets detected
+    - USB: musb: fix external abort on suspend
+    - ANDROID: binder: add padding to binder_fd_array_object.
+    - ANDROID: binder: add hwbinder,vndbinder to BINDER_DEVICES.
+    - USB: core: Avoid race of async_completed() w/ usbdev_release()
+    - staging/rts5208: fix incorrect shift to extract upper nybble
+    - staging: ccree: save ciphertext for CTS IV
+    - staging: fsl-dpaa2/eth: fix off-by-one FD ctrl bitmaks
+    - iio: adc: ti-ads1015: fix incorrect data rate setting update
+    - iio: adc: ti-ads1015: fix scale information for ADS1115
+    - iio: adc: ti-ads1015: enable conversion when CONFIG_PM is not set
+    - iio: adc: ti-ads1015: avoid getting stale result after runtime resume
+    - iio: adc: ti-ads1015: don't return invalid value from buffer setup callbacks
+    - iio: adc: ti-ads1015: add adequate wait time to get correct conversion
+    - driver core: bus: Fix a potential double free
+    - HID: wacom: Do not completely map WACOM_HID_WD_TOUCHRINGSTATUS usage
+    - binder: free memory on error
+    - crypto: caam/qi - fix compilation with CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
+    - crypto: caam/qi - fix compilation with DEBUG enabled
+    - thunderbolt: Fix reset response_type
+    - fpga: altera-hps2fpga: fix multiple init of l3_remap_lock
+    - intel_th: pci: Add Cannon Lake PCH-H support
+    - intel_th: pci: Add Cannon Lake PCH-LP support
+    - ath10k: fix memory leak in rx ring buffer allocation
+    - drm/vgem: Pin our pages for dmabuf exports
+    - drm/ttm: Fix accounting error when fail to get pages for pool
+    - drm/dp/mst: Handle errors from drm_atomic_get_private_obj_state() correctly
+    - rtlwifi: rtl_pci_probe: Fix fail path of _rtl_pci_find_adapter
+    - Bluetooth: Add support of 13d3:3494 RTL8723BE device
+    - iwlwifi: pci: add new PCI ID for 7265D
+    - dlm: avoid double-free on error path in dlm_device_{register,unregister}
+    - mwifiex: correct channel stat buffer overflows
+    - MCB: add support for SC31 to mcb-lpc
+    - s390/mm: avoid empty zero pages for KVM guests to avoid postcopy hangs
+    - drm/nouveau/pci/msi: disable MSI on big-endian platforms by default
+    - drm/nouveau: Fix error handling in nv50_disp_atomic_commit
+    - workqueue: Fix flag collision
+    - ahci: don't use MSI for devices with the silly Intel NVMe remapping scheme
+    - cs5536: add support for IDE controller variant
+    - scsi: sg: protect against races between mmap() and SG_SET_RESERVED_SIZE
+    - scsi: sg: recheck MMAP_IO request length with lock held
+    - of/device: Prevent buffer overflow in of_device_modalias()
+    - rtlwifi: Fix memory leak when firmware request fails
+    - rtlwifi: Fix fallback firmware loading
+    - Linux 4.13.1
+
+  * Kernel has trouble recognizing Corsair Strafe RGB keyboard (LP: #1678477)
+    - usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard
+
+  * SRIOV: warning if unload VFs (LP: #1715073)
+    - PCI: Disable VF decoding before pcibios_sriov_disable() updates resources
+
+  * [Patch] network-i40e:NVM bug fixes (cherrypick from 4.14) (LP: #1715578)
+    - i40e: avoid NVM acquire deadlock during NVM update
+    - i40e: point wb_desc at the nvm_wb_desc during i40e_read_nvm_aq
+
+  * [P9,POwer NV] Perf PMU event : pm_br_2path and pm_ld_miss_l1 is counted
+    twice when perf stat is done (perf:) (LP: #1714571)
+    - perf vendor events powerpc: Remove duplicate events
+
+  * Unable to install Ubuntu on the NVMe disk under VMD PCI domain
+    (LP: #1703339)
+    - [Config] Include vmd in storage-core-modules udeb
+
+  * 17.10 fails to boot on POWER9 DD2.0 with Deep stop states (LP: #1715064)
+    - powerpc/powernv: Save/Restore additional SPRs for stop4 cpuidle
+    - powerpc/powernv: Clear PECE1 in LPCR via stop-api only on Hotplug
+    - SAUCE: powerpc/powernv: Clear LPCR[PECE1] via stop-api only for deep state
+      offline
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/seccomp: Support glibc 2.26 siginfo_t.h
+    - Revert "UBUNTU: SAUCE: Import aufs driver"
+    - SAUCE: Import aufs driver
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 10 Sep 2017 17:48:59 -0500
+
+linux (4.13.0-9.10) artful; urgency=low
+
+  * linux: 4.13.0-9.10 -proposed tracker (LP: #1715145)
+
+  * EDAC sbridge: Failed to register device with error -22. (LP: #1714112)
+    - [Config] CONFIG_EDAC_GHES=n
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu: vbox -- update to 5.1.26-dfsg-2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 05 Sep 2017 07:51:19 -0500
+
+linux (4.13.0-8.9) artful; urgency=low
+
+  * snapd 2.27.3+17.10 ADT test failure with linux 4.13.0-6.7 (LP: #1713103)
+    - SAUCE: apparmor: fix apparmorfs DAC access, permissions
+
+  * enable ARCH_SUNXI (and friends) in arm64 kernel .config (LP: #1701137)
+    - [Config] Enable CONFIG_ARCH_SUNXI and related options for arm64
+
+  * [Bug] Harrisonville: pnd2_edac always fail to load on B1 stepping
+    Harrisonville SDP (LP: #1709257)
+    - EDAC, pnd2: Build in a minimal sideband driver for Apollo Lake
+    - EDAC, pnd2: Mask off the lower four bits of a BAR
+    - EDAC, pnd2: Conditionally unhide/hide the P2SB PCI device to read BAR
+    - EDAC, pnd2: Properly toggle hidden state for P2SB PCI device
+    - SAUCE: i2c: i801: Restore the presence state of P2SB PCI device after
+      reading BAR
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: Import aufs driver"
+    - SAUCE: Import aufs driver
+    - SAUCE: selftests/powerpc: Disable some ptrace selftests
+    - [Config] CONFIG_CRYPTO_DEV_NITROX_CNN55XX=n for s390x
+    - [Config] CONFIG_I2C_SLAVE=n for amd64, i386, ppc64el
+    - [Config] Disable CONFIG_MDIO_* options for s390x
+    - [Config] CONFIG_SCSI_MQ_DEFAULT=n for s390x
+    - [Config] Update annotations for 4.13
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 31 Aug 2017 14:27:09 -0500
+
+linux (4.13.0-7.8) artful; urgency=low
+
+  * linux 4.12.0-11.12 ADT test failure with linux 4.12.0-11.12 (LP: #1710904)
+    - SAUCE: selftests/powerpc: Use snprintf to construct DSCR sysfs interface
+      paths
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: seccomp: log actions even when audit is disabled"
+
+  * Miscellaneous upstream changes
+    - seccomp: Provide matching filter for introspection
+    - seccomp: Sysctl to display available actions
+    - seccomp: Operation for checking if an action is available
+    - seccomp: Sysctl to configure actions that are allowed to be logged
+    - seccomp: Selftest for detection of filter flag support
+    - seccomp: Filter flag to log all actions except SECCOMP_RET_ALLOW
+    - seccomp: Action to log before allowing
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 28 Aug 2017 08:12:24 -0500
+
+linux (4.13.0-6.7) artful; urgency=low
+
+  * HID: multitouch: Support ALPS PTP Stick and Touchpad devices (LP: #1712481)
+    - SAUCE: HID: multitouch: Support ALPS PTP stick with pid 0x120A
+
+  * sort ABI files with C.UTF-8 locale (LP: #1712345)
+    - [Packaging] sort ABI files with C.UTF-8 locale
+
+  * igb: Support using Broadcom 54616 as PHY (LP: #1712024)
+    - SAUCE: igb: add support for using Broadcom 54616 as PHY
+
+  * RPT related fixes missing in Ubuntu 16.04.3 (LP: #1709220)
+    - powerpc/mm/radix: Improve _tlbiel_pid to be usable for PWC flushes
+    - powerpc/mm/radix: Improve TLB/PWC flushes
+    - powerpc/mm/radix: Avoid flushing the PWC on every flush_tlb_range
+
+  * Linux 4.12 refuses to load self-signed modules under Secure Boot with
+    properly enrolled keys (LP: #1712168)
+    - SAUCE: (efi-lockdown) MODSIGN: Fix module signature verification
+
+  * [17.10 FEAT] Enable NVMe driver - kernel (LP: #1708432)
+    - [Config] CONFIG_BLK_DEV_NVME=m for s390
+
+  * Artful: 4.12.0-11.12: Boot panic in vlv2_plat_configure_clock+0x3b/0xa0
+    (LP: #1711298)
+    - [Config] CONFIG_INTEL_ATOMISP=n
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor: af_unix mediation
+
+  * Miscellaneous upstream changes
+    - apparmor: Fix shadowed local variable in unpack_trans_table()
+    - apparmor: Fix logical error in verify_header()
+    - apparmor: Fix an error code in aafs_create()
+    - apparmor: Redundant condition: prev_ns. in [label.c:1498]
+    - apparmor: add the ability to mediate signals
+    - apparmor: add mount mediation
+    - apparmor: cleanup conditional check for label in label_print
+    - apparmor: add support for absolute root view based labels
+    - apparmor: make policy_unpack able to audit different info messages
+    - apparmor: add more debug asserts to apparmorfs
+    - apparmor: add base infastructure for socket mediation
+    - apparmor: move new_null_profile to after profile lookup fns()
+    - apparmor: fix race condition in null profile creation
+    - apparmor: ensure unconfined profiles have dfas initialized
+    - apparmor: fix incorrect type assignment when freeing proxies
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 23 Aug 2017 08:10:38 -0500
+
+linux (4.13.0-5.6) artful; urgency=low
+
+  * Ubuntu17.10 - perf: Update Power9 PMU event JSON files (LP: #1708630)
+    - perf pmu-events: Support additional POWER8+ PVR in mapfile
+    - perf vendor events: Add POWER9 PMU events
+    - perf vendor events: Add POWER9 PVRs to mapfile
+    - SAUCE: perf vendor events powerpc: remove suffix in mapfile
+    - SAUCE: perf vendor events powerpc: Update POWER9 events
+
+  * Disable CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE (LP: #1709171)
+    - [Config] CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=n for ppc64el
+
+  * Please only recommend or suggest initramfs-tools | linux-initramfs-tool for
+    kernels able to boot without initramfs (LP: #1700972)
+    - [Debian] Don't depend on initramfs-tools
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Import aufs driver
+    - SAUCE: aufs -- Add missing argument to loop_switch() call
+    - [Config] Enable aufs
+    - SAUCE: (noup) Update spl to 0.6.5.11-ubuntu1, zfs to 0.6.5.11-1ubuntu3
+    - Enable zfs build
+    - SAUCE: powerpc: Always initialize input array when calling epapr_hypercall()
+    - [Packaging] switch up to debhelper 9
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 15 Aug 2017 09:24:16 -0500
+
+linux (4.13.0-4.5) artful; urgency=low
+
+  * Lenovo Yoga 910 Sensors (LP: #1708120)
+    - SAUCE: (no-up) HID: Add quirk for Lenovo Yoga 910 with ITE Chips
+
+  * Unable to install Ubuntu on the NVMe disk under VMD PCI domain
+    (LP: #1703339)
+    - [Config] Add vmd driver to generic inclusion list
+
+  * Set CONFIG_SATA_HIGHBANK=y on armhf (LP: #1703430)
+    - [Config] CONFIG_SATA_HIGHBANK=y
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu: vbox -- update to 5.1.26-dfsg-1
+    - SAUCE: hio: Build fixes for 4.13
+    - Enable hio build
+    - SAUCE: (noup) Update spl to 0.6.5.11-1, zfs to 0.6.5.11-1ubuntu1
+    - [debian] use all rather than amd64 dkms debs for sync
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 08 Aug 2017 11:31:48 -0500
+
+linux (4.13.0-3.4) artful; urgency=low
+
+  * Adt tests of src:linux time out often on armhf lxc containers (LP: #1705495)
+    - [Packaging] tests -- reduce rebuild test to one flavour
+    - [Packaging] tests -- reduce rebuild test to one flavour -- use filter
+
+  * snapd 2.26.8+17.10 ADT test failure with linux 4.12.0-6.7 (LP: #1704158)
+    - SAUCE: virtio_net: Revert mergeable buffer handling rework
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 31 Jul 2017 10:08:16 -0500
+
+linux (4.13.0-2.3) artful; urgency=low
+
+  * Change CONFIG_IBMVETH to module (LP: #1704479)
+    - [Config] CONFIG_IBMVETH=m
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 24 Jul 2017 13:58:08 -0500
+
+linux (4.13.0-1.2) artful; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Support sphinx-based kernel documentation
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 20 Jul 2017 09:18:33 -0500
+
+linux (4.13.0-0.1) artful; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - Disable hio
+    - Disable zfs build
+    - ubuntu: vbox -- update to 5.1.24-dfsg-1
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 19 Jul 2017 15:09:31 -0500
+
+linux (4.12.0-7.8) artful; urgency=low
+
+  * ThunderX: soft lockup on 4.8+ kernels when running qemu-efi with vhost=on
+    (LP: #1673564)
+    - arm64: Add a facility to turn an ESR syndrome into a sysreg encoding
+    - KVM: arm/arm64: vgic-v3: Add accessors for the ICH_APxRn_EL2 registers
+    - KVM: arm64: Make kvm_condition_valid32() accessible from EL2
+    - KVM: arm64: vgic-v3: Add hook to handle guest GICv3 sysreg accesses at EL2
+    - KVM: arm64: vgic-v3: Add ICV_BPR1_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_IGRPEN1_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_IAR1_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_EOIR1_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_AP1Rn_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_HPPIR1_EL1 handler
+    - KVM: arm64: vgic-v3: Enable trapping of Group-1 system registers
+    - KVM: arm64: Enable GICv3 Group-1 sysreg trapping via command-line
+    - KVM: arm64: vgic-v3: Add ICV_BPR0_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_IGNREN0_EL1 handler
+    - KVM: arm64: vgic-v3: Add misc Group-0 handlers
+    - KVM: arm64: vgic-v3: Enable trapping of Group-0 system registers
+    - KVM: arm64: Enable GICv3 Group-0 sysreg trapping via command-line
+    - arm64: Add MIDR values for Cavium cn83XX SoCs
+    - arm64: Add workaround for Cavium Thunder erratum 30115
+    - KVM: arm64: vgic-v3: Add ICV_DIR_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_RPR_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_CTLR_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_PMR_EL1 handler
+    - KVM: arm64: Enable GICv3 common sysreg trapping via command-line
+    - KVM: arm64: vgic-v3: Log which GICv3 system registers are trapped
+    - KVM: arm64: Log an error if trapping a read-from-write-only GICv3 access
+    - KVM: arm64: Log an error if trapping a write-to-read-only GICv3 access
+
+  * hns: under heavy load, NIC may fail and require reboot (LP: #1704146)
+    - net: hns: Bugfix for Tx timeout handling in hns driver
+
+  * New ACPI identifiers for ThunderX SMMU (LP: #1703437)
+    - iommu/arm-smmu: Plumb in new ACPI identifiers
+
+  * Transparent hugepages should default to enabled=madvise (LP: #1703742)
+    - SAUCE: use CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y as default
+
+  * Artful update to v4.12.1 stable release (LP: #1703858)
+    - driver core: platform: fix race condition with driver_override
+    - RDMA/uverbs: Check port number supplied by user verbs cmds
+    - usb: dwc3: replace %p with %pK
+    - USB: serial: cp210x: add ID for CEL EM3588 USB ZigBee stick
+    - usb: usbip: set buffer pointers to NULL after free
+    - Add USB quirk for HVR-950q to avoid intermittent device resets
+    - usb: Fix typo in the definition of Endpoint[out]Request
+    - USB: core: fix device node leak
+    - USB: serial: option: add two Longcheer device ids
+    - USB: serial: qcserial: new Sierra Wireless EM7305 device ID
+    - xhci: Limit USB2 port wake support for AMD Promontory hosts
+    - gfs2: Fix glock rhashtable rcu bug
+    - Add "shutdown" to "struct class".
+    - tpm: Issue a TPM2_Shutdown for TPM2 devices.
+    - tpm: fix a kernel memory leak in tpm-sysfs.c
+    - powerpc/powernv: Fix CPU_HOTPLUG=n idle.c compile error
+    - x86/uaccess: Optimize copy_user_enhanced_fast_string() for short strings
+    - sched/fair, cpumask: Export for_each_cpu_wrap()
+    - sched/core: Implement new approach to scale select_idle_cpu()
+    - sched/numa: Use down_read_trylock() for the mmap_sem
+    - sched/numa: Override part of migrate_degrades_locality() when idle balancing
+    - sched/fair: Simplify wake_affine() for the single socket case
+    - sched/numa: Implement NUMA node level wake_affine()
+    - sched/fair: Remove effective_load()
+    - sched/numa: Hide numa_wake_affine() from UP build
+    - xen: avoid deadlock in xenbus driver
+    - crypto: drbg - Fixes panic in wait_for_completion call
+    - Linux 4.12.1
+
+  * cxlflash update request in the Xenial SRU stream (LP: #1702521)
+    - scsi: cxlflash: Combine the send queue locks
+    - scsi: cxlflash: Update cxlflash_afu_sync() to return errno
+    - scsi: cxlflash: Reset hardware queue context via specified register
+    - scsi: cxlflash: Schedule asynchronous reset of the host
+    - scsi: cxlflash: Handle AFU sync failures
+    - scsi: cxlflash: Track pending scsi commands in each hardware queue
+    - scsi: cxlflash: Flush pending commands in cleanup path
+    - scsi: cxlflash: Add scsi command abort handler
+    - scsi: cxlflash: Create character device to provide host management interface
+    - scsi: cxlflash: Separate AFU internal command handling from AFU sync
+      specifics
+    - scsi: cxlflash: Introduce host ioctl support
+    - scsi: cxlflash: Refactor AFU capability checking
+    - scsi: cxlflash: Support LUN provisioning
+    - scsi: cxlflash: Support AFU debug
+    - scsi: cxlflash: Support WS16 unmap
+    - scsi: cxlflash: Remove zeroing of private command data
+    - scsi: cxlflash: Update TMF command processing
+    - scsi: cxlflash: Avoid double free of character device
+    - scsi: cxlflash: Update send_tmf() parameters
+    - scsi: cxlflash: Update debug prints in reset handlers
+
+  * make snap-pkg support (LP: #1700747)
+    - make snap-pkg support
+
+  * Quirk for non-compliant PCI bridge on HiSilicon D05 board (LP: #1698706)
+    - SAUCE: PCI: Support hibmc VGA cards behind a misbehaving HiSilicon bridge
+
+  * arm64: fix crash reading /proc/kcore (LP: #1702749)
+    - fs/proc: kcore: use kcore_list type to check for vmalloc/module address
+    - arm64: mm: select CONFIG_ARCH_PROC_KCORE_TEXT
+
+  * Opal and POWER9 DD2 (LP: #1702159)
+    - SAUCE: powerpc/powernv: Tell OPAL about our MMU mode on POWER9
+
+  * Data corruption with hio driver  (LP: #1701316)
+    - SAUCE: hio: Fix incorrect use of enum req_opf values
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.6.5.10-1, zfs to 0.6.5.10-1ubuntu2
+    - snapcraft.yaml: Sync with xenial
+    - [Config] CONFIG_CAVIUM_ERRATUM_30115=y
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and
+      MokSBState"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 14 Jul 2017 15:25:41 -0500
+
+linux (4.12.0-6.7) artful; urgency=low
+
+  * update ENA driver to 1.2.0k from net-next (LP: #1701575)
+    - net: ena: change return value for unsupported features unsupported return
+      value
+    - net: ena: add hardware hints capability to the driver
+    - net: ena: change sizeof() argument to be the type pointer
+    - net: ena: add reset reason for each device FLR
+    - net: ena: add support for out of order rx buffers refill
+    - net: ena: allow the driver to work with small number of msix vectors
+    - net: ena: use napi_schedule_irqoff when possible
+    - net: ena: separate skb allocation to dedicated function
+    - net: ena: use lower_32_bits()/upper_32_bits() to split dma address
+    - net: ena: update driver's rx drop statistics
+    - net: ena: update ena driver to version 1.2.0
+
+  * APST gets enabled against explicit kernel option (LP: #1699004)
+    - nvme: explicitly disable APST on quirked devices
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: hio: Update to Huawei ES3000_V2 (2.1.0.40)
+    - SAUCE: hio updates for 4.12
+    - SAUCE: Enable hio build
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 05 Jul 2017 14:23:20 -0500
+
+linux (4.12.0-5.6) artful; urgency=low
+
+  * ERAT invalidate on context switch removal (LP: #1700819)
+    - powerpc: Only do ERAT invalidate on radix context switch on P9 DD1
+
+  * powerpc: Invalidate ERAT on powersave wakeup for POWER9 (LP: #1700521)
+    - SAUCE: powerpc: Invalidate ERAT on powersave wakeup for POWER9
+
+  * Miscellaneous Ubuntu changes
+    - d-i: Move qcom-emac from arm64 to shared nic-modules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 03 Jul 2017 07:52:02 -0500
+
+linux (4.12.0-4.5) artful; urgency=low
+
+  * aacraid driver may return uninitialized stack data to userspace
+    (LP: #1700077)
+    - SAUCE: scsi: aacraid: Don't copy uninitialized stack memory to userspace
+
+  * KILLER1435-S[0489:e0a2] BT cannot search BT 4.0 device (LP: #1699651)
+    - Bluetooth: btusb: Add support for 0489:e0a2 QCA_ROME device
+
+  * AACRAID for power9 platform (LP: #1689980)
+    - scsi: aacraid: Remove __GFP_DMA for raw srb memory
+    - scsi: aacraid: Fix DMAR issues with iommu=pt
+    - scsi: aacraid: Added 32 and 64 queue depth for arc natives
+    - scsi: aacraid: Set correct Queue Depth for HBA1000 RAW disks
+    - scsi: aacraid: Remove reset support from check_health
+    - scsi: aacraid: Change wait time for fib completion
+    - scsi: aacraid: Log count info of scsi cmds before reset
+    - scsi: aacraid: Print ctrl status before eh reset
+    - scsi: aacraid: Using single reset mask for IOP reset
+    - scsi: aacraid: Rework IOP reset
+    - scsi: aacraid: Add periodic checks to see IOP reset status
+    - scsi: aacraid: Rework SOFT reset code
+    - scsi: aacraid: Rework aac_src_restart
+    - scsi: aacraid: Use correct function to get ctrl health
+    - scsi: aacraid: Make sure ioctl returns on controller reset
+    - scsi: aacraid: Enable ctrl reset for both hba and arc
+    - scsi: aacraid: Add reset debugging statements
+    - scsi: aacraid: Remove reference to Series-9
+    - scsi: aacraid: Update driver version to 50834
+
+  * hibmc driver does not include "pci:" prefix in bus ID (LP: #1698700)
+    - SAUCE: drm: hibmc: Use set_busid function from drm core
+
+  * HiSilicon D05: installer doesn't appear on VGA (LP: #1698954)
+    - d-i: Add hibmc-drm to kernel-image udeb
+
+  * Fix /proc/cpuinfo revision for POWER9 DD2 (LP: #1698844)
+    - SAUCE: powerpc: Fix /proc/cpuinfo revision for POWER9 DD2
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_SATA_MV=n and CONFIG_GENERIC_PHY=n for s390x
+    - [Config] CONFIG_ATA=n for s390x
+    - [Config] Update annotations for 4.12
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 26 Jun 2017 11:27:29 -0500
+
+linux (4.12.0-3.4) artful; urgency=low
+
+  * Miscellaneous upstream changes
+    - ufs: fix the logics for tail relocation
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 19 Jun 2017 14:50:39 -0500
+
+linux (4.12.0-2.3) artful; urgency=low
+
+  * CVE-2014-9900
+    - SAUCE: (no-up) net: Zeroing the structure ethtool_wolinfo in
+      ethtool_get_wol()
+
+  * System doesn't boot properly on Gigabyte AM4 motherboards (AMD Ryzen)
+    (LP: #1671360)
+    - pinctrl/amd: Use regular interrupt instead of chained
+
+  * extend-diff-ignore should use exact matches (LP: #1693504)
+    - [Packaging] exact extend-diff-ignore matches
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: efi: Don't print secure boot state from the efi stub
+    - ubuntu: vbox -- Update to 5.1.22-dfsg-1
+    - SAUCE: vbox fixes for 4.12
+    - Re-enable virtualbox build
+    - [Config] CONFIG_ORANGEFS_FS=m
+    - SAUCE: (noup) Update spl to 0.6.5.9-1ubuntu2, zfs to 0.6.5.9-5ubuntu7
+    - Enable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc4
+  * Rebase to v4.12-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 11 Jun 2017 22:25:13 -0500
+
+linux (4.12.0-1.2) artful; urgency=low
+
+  * Enable Matrox driver for Ubuntu 16.04.3 (LP: #1693337)
+    - [Config] Enable CONFIG_DRM_MGAG200 as module
+
+  * Support low-pin-count devices on Hisilicon SoCs (LP: #1677319)
+    - [Config] CONFIG_LIBIO=y on arm64 only
+    - SAUCE: LIBIO: Introduce a generic PIO mapping method
+    - SAUCE: OF: Add missing I/O range exception for indirect-IO devices
+    - [Config] CONFIG_HISILICON_LPC=y
+    - SAUCE: LPC: Support the device-tree LPC host on Hip06/Hip07
+    - SAUCE: LIBIO: Support the dynamically logical PIO registration of ACPI host
+      I/O
+    - SAUCE: LPC: Add the ACPI LPC support
+    - SAUCE: PCI: Apply the new generic I/O management on PCI IO hosts
+    - SAUCE: PCI: Restore codepath for !CONFIG_LIBIO
+
+  * POWER9: Additional patches for TTY and CPU_IDLE (LP: #1674325)
+    - SAUCE: tty: Fix ldisc crash on reopened tty
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Add build-dep on libnuma-dev to enable 'perf bench numa'
+    - Rebase to v4.12-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 29 May 2017 20:56:29 -0500
+
+linux (4.12.0-0.1) artful; urgency=low
+
+  * please enable CONFIG_ARM64_LSE_ATOMICS (LP: #1691614)
+    - [Config] CONFIG_ARM64_LSE_ATOMICS=y
+
+  * [Regression] NUMA_BALANCING disabled on arm64 (LP: #1690914)
+    - [Config] CONFIG_NUMA_BALANCING{,_DEFAULT_ENABLED}=y on arm64
+
+  * exec'ing a setuid binary from a threaded program sometimes fails to setuid
+    (LP: #1672819)
+    - SAUCE: exec: ensure file system accounting in check_unsafe_exec is correct
+
+  * Miscellaneous Ubuntu changes
+    - Update find-missing-sauce.sh to compare to artful
+    - Update dropped.txt
+    - SAUCE: (efi-lockdown) efi: Add EFI_SECURE_BOOT bit
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/mem and /dev/kmem when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Add a sysrq option to exit secure boot mode
+    - SAUCE: (efi-lockdown) kexec: Disable at runtime if the kernel is locked down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) kexec_file: Disable at runtime if securelevel has been
+      set
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) asus-wmi: Restrict debugfs interface when the kernel
+      is locked down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Enable cold boot attack mitigation
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) scsi: Lock down the eata driver
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) efi: Add EFI signature data types
+    - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) efi: Add secure_boot state and status bit for
+      MokSBState
+    - SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and MokSBState
+    - [Config] Set values for UEFI secure boot lockdown options
+    - Disable virtualbox build
+    - Disable hio build
+    - SAUCE: securityfs: Replace CURRENT_TIME with current_time()
+    - Disable zfs build
+    - [Debian] Work out upstream tag for use with gen-auto-reconstruct
+    - SAUCE: Import aufs driver
+    - SAUCE: aufs -- Include linux/mm.h in fs/aufs/file.h
+    - [Config] Enable aufs
+    - SAUCE: perf callchain: Include errno.h on x86 unconditinally
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 21 May 2017 23:44:44 -0500
+
+linux (4.11.0-3.8) artful; urgency=low
+
+  [ Seth Forshee ]
+
+  * Release Tracking Bug
+    - LP: #1690999
+
+  * apparmor_parser hangs indefinitely when called by multiple threads
+    (LP: #1645037)
+    - SAUCE: apparmor: fix lock ordering for mkdir
+
+  * apparmor leaking securityfs pin count (LP: #1660846)
+    - SAUCE: apparmor: fix leak on securityfs pin count
+
+  * apparmor reference count leak when securityfs_setup_d_inode\ () fails
+    (LP: #1660845)
+    - SAUCE: apparmor: fix reference count leak when securityfs_setup_d_inode()
+      fails
+
+  * apparmor not checking error if security_pin_fs() fails (LP: #1660842)
+    - SAUCE: apparmor: fix not handling error case when securityfs_pin_fs() fails
+
+  * libvirt profile is blocking global setrlimit despite having no rlimit rule
+    (LP: #1679704)
+    - SAUCE: apparmor: fix complain mode failure for rlimit mediation
+    - apparmor: update auditing of rlimit check to provide capability information
+
+  * apparmor: does not provide a way to detect policy updataes (LP: #1678032)
+    - SAUCE: apparmor: add policy revision file interface
+
+  * apparmor does not make support of query data visible (LP: #1678023)
+    - SAUCE: apparmor: add label data availability to the feature set
+
+  * apparmor query interface does not make supported query info available
+    (LP: #1678030)
+    - SAUCE: apparmor: add information about the query inteface to the feature set
+
+  * change_profile incorrect when using namespaces with a compound stack
+    (LP: #1677959)
+    - SAUCE: apparmor: fix label parse for stacked labels
+
+  * Regression in 4.4.0-65-generic causes very frequent system crashes
+    (LP: #1669611)
+    - apparmor: sync of apparmor 3.6+ (17.04)
+
+  * Artful update to 4.11.1 stable release (LP: #1690814)
+    - dm ioctl: prevent stack leak in dm ioctl call
+    - drm/sti: fix GDP size to support up to UHD resolution
+    - power: supply: lp8788: prevent out of bounds array access
+    - brcmfmac: Ensure pointer correctly set if skb data location changes
+    - brcmfmac: Make skb header writable before use
+    - sparc64: fix fault handling in NGbzero.S and GENbzero.S
+    - refcount: change EXPORT_SYMBOL markings
+    - net: macb: fix phy interrupt parsing
+    - tcp: fix access to sk->sk_state in tcp_poll()
+    - geneve: fix incorrect setting of UDP checksum flag
+    - bpf: enhance verifier to understand stack pointer arithmetic
+    - bpf, arm64: fix jit branch offset related to ldimm64
+    - tcp: fix wraparound issue in tcp_lp
+    - net: ipv6: Do not duplicate DAD on link up
+    - net: usb: qmi_wwan: add Telit ME910 support
+    - tcp: do not inherit fastopen_req from parent
+    - ipv4, ipv6: ensure raw socket message is big enough to hold an IP header
+    - rtnetlink: NUL-terminate IFLA_PHYS_PORT_NAME string
+    - ipv6: initialize route null entry in addrconf_init()
+    - ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf
+    - tcp: randomize timestamps on syncookies
+    - bnxt_en: allocate enough space for ->ntp_fltr_bmap
+    - bpf: don't let ldimm64 leak map addresses on unprivileged
+    - net: mdio-mux: bcm-iproc: call mdiobus_free() in error path
+    - f2fs: sanity check segment count
+    - xen/arm,arm64: fix xen_dma_ops after 815dd18 "Consolidate get_dma_ops..."
+    - xen: Revert commits da72ff5bfcb0 and 72a9b186292d
+    - block: get rid of blk_integrity_revalidate()
+    - Linux 4.11.1
+
+  * Module signing exclusion for staging drivers does not work properly
+    (LP: #1690908)
+    - SAUCE: Fix module signing exclusion in package builds
+
+  * perf: qcom: Add L3 cache PMU driver (LP: #1689856)
+    - [Config] CONFIG_QCOM_L3_PMU=y
+    - perf: qcom: Add L3 cache PMU driver
+
+  * No PMU support for ACPI-based arm64 systems (LP: #1689661)
+    - drivers/perf: arm_pmu: rework per-cpu allocation
+    - drivers/perf: arm_pmu: manage interrupts per-cpu
+    - drivers/perf: arm_pmu: split irq request from enable
+    - drivers/perf: arm_pmu: remove pointless PMU disabling
+    - drivers/perf: arm_pmu: define armpmu_init_fn
+    - drivers/perf: arm_pmu: fold init into alloc
+    - drivers/perf: arm_pmu: factor out pmu registration
+    - drivers/perf: arm_pmu: simplify cpu_pmu_request_irqs()
+    - drivers/perf: arm_pmu: handle no platform_device
+    - drivers/perf: arm_pmu: rename irq request/free functions
+    - drivers/perf: arm_pmu: split cpu-local irq request/free
+    - drivers/perf: arm_pmu: move irq request/free into probe
+    - drivers/perf: arm_pmu: split out platform device probe logic
+    - arm64: add function to get a cpu's MADT GICC table
+    - [Config] CONFIG_ARM_PMU_ACPI=y
+    - drivers/perf: arm_pmu: add ACPI framework
+    - arm64: pmuv3: handle !PMUv3 when probing
+    - arm64: pmuv3: use arm_pmu ACPI framework
+
+  * Fix NVLINK2 TCE route (LP: #1690155)
+    - powerpc/powernv: Fix TCE kill on NVLink2
+
+  * CVE-2017-0605
+    - tracing: Use strlcpy() instead of strcpy() in __trace_find_cmdline()
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Restore powerpc arch to annotations file
+    - [Config] Disable runtime testing modules
+    - [Config] Disable drivers not needed on s390x
+    - [Config] Update annotations for 4.11
+    - [Config] updateconfigs after apparmor updates
+
+  * Miscellaneous upstream changes
+    - apparmor: use SHASH_DESC_ON_STACK
+    - apparmor: fix invalid reference to index variable of iterator line 836
+    - apparmor: fix parameters so that the permission test is bypassed at boot
+    - apparmor: Make path_max parameter readonly
+    - apparmorfs: Combine two function calls into one in aa_fs_seq_raw_abi_show()
+    - apparmorfs: Use seq_putc() in two functions
+    - apparmor: provide information about path buffer size at boot
+    - apparmor: add/use fns to print hash string hex value
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 16 May 2017 00:39:13 -0500
+
+linux (4.11.0-2.7) artful; urgency=low
+
+  * kernel-wedge fails in artful due to leftover squashfs-modules d-i files
+    (LP: #1688259)
+    - Remove squashfs-modules files from d-i
+    - [Config] as squashfs-modules is builtin kernel-image must Provides: it
+
+  * [Zesty] d-i: replace msm_emac with qcom_emac (LP: #1677297)
+    - Revert "UBUNTU: d-i: initrd needs msm_emac on amberwing platform."
+    - d-i: initrd needs qcom_emac on amberwing platform.
+
+  * update for V3 kernel bits and improved multiple fan slice support
+    (LP: #1470091)
+    - SAUCE: fan: tunnel multiple mapping mode (v3)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.6.5.9-1ubuntu1, zfs to 0.6.5.9-5ubuntu5
+    - Enable zfs
+    - SAUCE: fan: add VXLAN implementation
+    - SAUCE: (efi-lockdown) efi: Add EFI_SECURE_BOOT bit
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/mem and /dev/kmem when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Add a sysrq option to exit secure boot mode
+    - SAUCE: (efi-lockdown) kexec: Disable at runtime if the kernel is locked down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) kexec_file: Disable at runtime if securelevel has been
+      set
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) asus-wmi: Restrict debugfs interface when the kernel
+      is locked down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Enable cold boot attack mitigation
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) scsi: Lock down the eata driver
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Add EFI signature data types
+    - SAUCE: (efi-lockdown) Add an EFI signature blob parser and key loader.
+    - SAUCE: (efi-lockdown) KEYS: Add a system blacklist keyring
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Support not importing certs from db
+    - SAUCE: (efi-lockdown) MODSIGN: Don't try secure boot if EFI runtime is
+      disabled
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) efi: Add secure_boot state and status bit for
+      MokSBState
+    - SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and MokSBState
+    - [Config] Set values for UEFI secure boot lockdown options
+    - Update dropped.txt
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 05 May 2017 07:43:14 -0500
+
+linux (4.11.0-1.6) artful; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Use default compression for all packages
+    - SAUCE: (namespace) block_dev: Support checking inode permissions in
+      lookup_bdev()
+    - SAUCE: (namespace) block_dev: Check permissions towards block device inode
+      when mounting
+    - SAUCE: (namespace) mtd: Check permissions towards mtd block device inode
+      when mounting
+    - SAUCE: (namespace) fs: Allow superblock owner to change ownership of inodes
+    - SAUCE: (namespace) fs: Don't remove suid for CAP_FSETID for userns root
+    - SAUCE: (namespace) fs: Allow superblock owner to access do_remount_sb()
+    - SAUCE: (namespace) capabilities: Allow privileged user in s_user_ns to set
+      security.* xattrs
+    - SAUCE: (namespace) fs: Allow CAP_SYS_ADMIN in s_user_ns to freeze and thaw
+      filesystems
+    - SAUCE: (namespace) fuse: Add support for pid namespaces
+    - SAUCE: (namespace) fuse: Support fuse filesystems outside of init_user_ns
+    - SAUCE: (namespace) fuse: Restrict allow_other to the superblock's namespace
+      or a descendant
+    - SAUCE: (namespace) fuse: Allow user namespace mounts
+    - SAUCE: (namespace) ext4: Add support for unprivileged mounts from user
+      namespaces
+    - SAUCE: (namespace) evm: Don't update hmacs in user ns mounts
+    - SAUCE: (namespace) ext4: Add module parameter to enable user namespace
+      mounts
+    - SAUCE: (namespace) block_dev: Forbid unprivileged mounting when device is
+      opened for writing
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 26 Apr 2017 10:08:29 -0500
+
+linux (4.11.0-0.5) artful; urgency=low
+
+  * [Hyper-V][SAUCE] pci-hyperv: Use only 16 bit integer for PCI domain
+    (LP: #1684971)
+    - SAUCE: pci-hyperv: Use only 16 bit integer for PCI domain
+
+  * [Hyper-V] Ubuntu 14.04.2 LTS Generation 2 SCSI Errors on VSS Based Backups
+    (LP: #1470250)
+    - SAUCE: Tools: hv: vss: Thaw the filesystem and continue after freeze fails
+
+  * Enable virtual scsi server driver for Power (LP: #1615665)
+    - SAUCE: Return TCMU-generated sense data to fabric module
+
+  * include/linux/security.h header syntax error with !CONFIG_SECURITYFS
+    (LP: #1630990)
+    - SAUCE: (no-up) include/linux/security.h -- fix syntax error with
+      CONFIG_SECURITYFS=n
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Import aufs driver
+    - [Config] Enable aufs
+    - [Debian] Add script to update virtualbox
+    - ubuntu: vbox -- Update to 5.1.20-dfsg-2
+    - Enable vbox
+    - SAUCE: aufs -- Include linux/mm.h in fs/aufs/file.h
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 25 Apr 2017 13:42:54 -0500
+
+linux (4.11.0-0.4) zesty; urgency=low
+
+  * POWER9: Improve performance on memory management (LP: #1681429)
+    - SAUCE: powerpc/mm/radix: Don't do page walk cache flush when doing full mm
+      flush
+    - SAUCE: powerpc/mm/radix: Remove unnecessary ptesync
+
+  * Miscellaneous Ubuntu changes
+    - find-missing-sauce.sh
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 18 Apr 2017 08:19:43 -0500
+
+linux (4.11.0-0.3) zesty; urgency=low
+
+  * Disable CONFIG_HVC_UDBG on ppc64el (LP: #1680888)
+    - [Config] Disable CONFIG_HVC_UDBG on ppc64el
+
+  * smartpqi driver needed in initram disk and installer (LP: #1680156)
+    - [Config] Add smartpqi to d-i
+
+  * Disable CONFIG_SECURITY_SELINUX_DISABLE (LP: #1680315)
+    - [Config] CONFIG_SECURITY_SELINUX_DISABLE=n
+
+  * Miscellaneous Ubuntu changes
+    - [Config] flash-kernel should be a Breaks
+    - [Config] drop the info directory
+    - [Config] drop NOTES as obsolete
+    - [Config] drop changelog.historical as obsolete
+    - rebase to v4.11-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc6
+
+ -- Tim Gardner <tim.gardner@canonical.com>  Tue, 11 Apr 2017 07:16:52 -0600
+
+linux (4.11.0-0.2) zesty; urgency=low
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc5
+
+ -- Tim Gardner <tim.gardner@canonical.com>  Mon, 03 Apr 2017 08:26:07 +0100
+
+linux (4.11.0-0.1) zesty; urgency=low
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc4
+    - LP: #1591053
+
+ -- Tim Gardner <tim.gardner@canonical.com>  Mon, 20 Mar 2017 05:15:32 -0600
+
+linux (4.11.0-0.0) zesty; urgency=low
+
+  * dummy entry
+
+ -- Tim Gardner <tim.gardner@canonical.com>  Mon, 20 Mar 2017 05:15:32 -0600
--- linux-qcom-6.8.0.orig/debian.master/config/README.rst
+++ linux-qcom-6.8.0/debian.master/config/README.rst
@@ -0,0 +1,185 @@
+==================
+Config Annotations
+==================
+
+:Author: Andrea Righi
+
+Overview
+========
+
+Each Ubuntu kernel needs to maintain its own .config for each supported
+architecture and each flavour.
+
+Every time a new patch is applied or a kernel is rebased on top of a new
+one, we need to update the .config's accordingly (config options can be
+added, removed and also renamed).
+
+So, we need to make sure that some critical config options are always
+matching the desired value in order to have a functional kernel.
+
+State of the art
+================
+
+At the moment configs are maintained as a set of Kconfig chunks (inside
+`debian.<kernel>/config/`): a global one, plus per-arch / per-flavour
+chunks.
+
+In addition to that, we need to maintain also a file called
+'annotations'; the purpose of this file is to make sure that some
+critical config options are not silently removed or changed when the
+real .config is re-generated (for example after a rebase or after
+applying a new set of patches).
+
+The main problem with this approach is that, often, we have duplicate
+information that is stored both in the Kconfig chunks *and* in the
+annotations files and, at the same time, the whole .config's information
+is distributed between Kconfig chunks and annotations, making it hard to
+maintain, review and manage in general.
+
+Proposed solution
+=================
+
+The proposed solution is to store all the config information into the
+"annotations" format and get rid of the config chunks (basically the
+real .config's can be produced "compiling" annotations).
+
+Implementation
+==============
+
+To help the management of the annotations an helper script is provided
+(`debian/scripts/misc/annotations`):
+
+```
+usage: annotations [-h] [--version] [--file FILE] [--arch ARCH] [--flavour FLAVOUR] [--config CONFIG]
+                   (--query | --export | --import FILE | --update FILE | --check FILE)
+
+Manage Ubuntu kernel .config and annotations
+
+options:
+  -h, --help            show this help message and exit
+  --version, -v         show program's version number and exit
+  --file FILE, -f FILE  Pass annotations or .config file to be parsed
+  --arch ARCH, -a ARCH  Select architecture
+  --flavour FLAVOUR, -l FLAVOUR
+                        Select flavour (default is "generic")
+  --config CONFIG, -c CONFIG
+                        Select a specific config option
+
+Action:
+  --query, -q           Query annotations
+  --export, -e          Convert annotations to .config format
+  --import FILE, -i FILE
+                        Import a full .config for a specific arch and flavour into annotations
+  --update FILE, -u FILE
+                        Import a partial .config into annotations (only resync configs specified in FILE)
+  --check FILE, -k FILE
+                        Validate kernel .config with annotations
+```
+
+This script allows to query config settings (per arch/flavour/config),
+export them into the Kconfig format (generating the real .config files)
+and check if the final .config matches the rules defined in the
+annotations.
+
+Examples (annotations is defined as an alias to `debian/scripts/annotations`):
+
+ - Show settings for `CONFIG_DEBUG_INFO_BTF` for master kernel across all the
+   supported architectures and flavours:
+
+```
+$ annotations --query --config CONFIG_DEBUG_INFO_BTF
+{
+    "policy": {
+        "amd64": "y",
+        "arm64": "y",
+        "armhf": "n",
+        "ppc64el": "y",
+        "riscv64": "y",
+        "s390x": "y"
+    },
+    "note": "'Needs newer pahole for armhf'"
+}
+```
+
+ - Dump kernel .config for arm64 and flavour generic-64k:
+
+```
+$ annotations --arch arm64 --flavour generic-64k --export
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_COMPAT=y
+...
+```
+
+ - Update annotations file with a new kernel .config for amd64 flavour
+   generic:
+
+```
+$ annotations --arch amd64 --flavour generic --import build/.config
+```
+
+Moreover, an additional kernelconfig commands are provided
+(via debian/rules targets):
+ - `migrateconfigs`: automatically merge all the previous configs into
+   annotations (local changes still need to be committed)
+
+Annotations headers
+===================
+
+The main annotations file should contain a header to define the architectures
+and flavours that are supported.
+
+Here is the format of the header for the generic kernel:
+```
+# Menu: HEADER
+# FORMAT: 4
+# ARCH: amd64 arm64 armhf ppc64el riscv64 s390x
+# FLAVOUR: amd64-generic arm64-generic arm64-generic-64k armhf-generic armhf-generic-lpae ppc64el-generic riscv64-generic s390x-generic
+
+```
+
+Example header of a derivative (linux-aws):
+```
+# Menu: HEADER
+# FORMAT: 4
+# ARCH: amd64 arm64
+# FLAVOUR: amd64-aws arm64-aws
+# FLAVOUR_DEP: {'amd64-aws': 'amd64-generic', 'arm64-aws': 'arm64-generic'}
+
+include "../../debian.master/config/annotations"
+
+# Below you can define only the specific linux-aws configs that differ from linux generic
+
+```
+
+Pros and Cons
+=============
+
+ Pros:
+  - avoid duplicate information in .config's and annotations
+  - allow to easily define groups of config settings (for a specific
+    environment or feature, such as annotations.clouds, annotations.ubuntu,
+    annotations.snapd, etc.)
+  - config options are more accessible, easy to change and review
+  - we can easily document how config options are managed (and external
+    contributors won't be discouraged anymore when they need to to change a
+    config option)
+
+ Cons:
+  - potential regressions: the new tool/scripts can have potential bugs,
+    so we could experience regressions due to some missed config changes
+  - kernel team need to understand the new process (even if everything
+    is transparent, kernel cranking process is the same, there might be
+    corner cases that need to be addressed and resolved manually)
+
+TODO
+====
+
+ - Migrate all flavour and arch definitions into annotations (rather
+   than having this information defined in multiple places inside
+   debian/scripts); right now this information is "partially" migrated,
+   meaning that we need to define arches and flavours in the headers
+   section of annotations (so that the annotations tool can figure out
+   the list of supported arches and flavours), but arches and flavours
+   are still defined elsewhere, ideally we would like to have arches and
+   flavours defined only in one place: annotations.
--- linux-qcom-6.8.0.orig/debian.master/config/annotations
+++ linux-qcom-6.8.0/debian.master/config/annotations
@@ -0,0 +1,15570 @@
+# Menu: HEADER
+# FORMAT: 4
+# ARCH: amd64 arm64 armhf ppc64el riscv64 s390x
+# FLAVOUR: amd64-generic arm64-generic arm64-generic-64k armhf-generic ppc64el-generic riscv64-generic s390x-generic
+
+CONFIG_ACCESSIBILITY                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_ACCESSIBILITY                            note<'LP: #1967702'>
+
+CONFIG_ACPI_CUSTOM_METHOD                       policy<{'amd64': 'n', 'arm64': 'n', 'riscv64': 'n'}>
+CONFIG_ACPI_CUSTOM_METHOD                       note<'SECURITY: allows arbitrary execution'>
+
+CONFIG_AGP                                      policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_AGP                                      note<'not autoloadable'>
+
+CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE         policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE         note<'LP: #2051835'>
+
+CONFIG_ARCH_MMAP_RND_BITS                       policy<{'amd64': '32', 'arm64': '33', 'arm64-generic-64k': '29', 'armhf': '16', 'ppc64el': '29', 'riscv64': '24'}>
+CONFIG_ARCH_MMAP_RND_BITS                       note<'LP: #1983357'>
+
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS                policy<{'amd64': '16', 'arm64': '16', 'arm64-generic-64k': '-', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS                note<'LP: #1983357'>
+
+CONFIG_ARCH_ROCKCHIP                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_ROCKCHIP                            note<'LP: #1825222'>
+
+CONFIG_ARM64_ERRATUM_843419                     policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_843419                     note<'LP: #1647793'>
+
+CONFIG_ARM64_ERRATUM_858921                     policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_858921                     note<'LP: #1675509'>
+
+CONFIG_ARM64_USE_LSE_ATOMICS                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_USE_LSE_ATOMICS                    note<'LP: #1691614'>
+
+CONFIG_ARM64_VA_BITS_48                         policy<{'arm64': 'y'}>
+CONFIG_ARM64_VA_BITS_48                         note<'Cavium ThunderX 2-socket needs a minimum of 41 bits of VA'>
+
+CONFIG_ARMV8_DEPRECATED                         policy<{'arm64': 'y', 'arm64-generic-64k': '-'}>
+CONFIG_ARMV8_DEPRECATED                         note<'LP: #1545542'>
+
+CONFIG_ARM_HIGHBANK_CPUIDLE                     policy<{'armhf': 'y'}>
+CONFIG_ARM_HIGHBANK_CPUIDLE                     note<'broken on ecx-1000'>
+
+CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT       policy<{'arm64': 'n', 'armhf': '-'}>
+CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT       note<'LP: #1845820'>
+
+CONFIG_ASYMMETRIC_KEY_TYPE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ASYMMETRIC_KEY_TYPE                      note<'module signing'>
+
+CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE            note<'module signing'>
+
+CONFIG_ATA_PIIX                                 policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ATA_PIIX                                 note<'LP: #1627324'>
+
+CONFIG_BINFMT_SCRIPT                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BINFMT_SCRIPT                            note<'required if init is a shell script such as in initramfs-tools'>
+
+CONFIG_BLK_DEV_DM                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_DM                               note<'LP: #560717'>
+
+CONFIG_BLK_DEV_NVME                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BLK_DEV_NVME                             note<'LP: #1759893'>
+
+CONFIG_BLK_DEV_RAM                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BLK_DEV_RAM                              note<'LP: #1593293'>
+
+CONFIG_BLK_DEV_RAM_SIZE                         policy<{'amd64': '65536', 'arm64': '65536', 'armhf': '65536', 'ppc64el': '65536', 'riscv64': '65536', 's390x': '65536'}>
+CONFIG_BLK_DEV_RAM_SIZE                         note<'Ramdisk size should be a minimum of 64M'>
+
+CONFIG_BLK_DEV_SD                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_SD                               note<'LP: #1627330'>
+
+CONFIG_BLK_DEV_SR                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_SR                               note<'LP: #1627330'>
+
+CONFIG_BLK_DEV_THROTTLING                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_THROTTLING                       note<'CGROUP disk consumption control'>
+
+CONFIG_BPF_UNPRIV_DEFAULT_OFF                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BPF_UNPRIV_DEFAULT_OFF                   note<'security reason'>
+
+CONFIG_CHR_DEV_SG                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CHR_DEV_SG                               note<'not autoloadable'>
+
+CONFIG_CMA                                      policy<{'amd64': 'n', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CMA                                      note<'LP: #1803206'>
+
+CONFIG_CMA_SIZE_MBYTES                          policy<{'arm64': '32', 'armhf': '32', 'riscv64': '32'}>
+CONFIG_CMA_SIZE_MBYTES                          note<'LP: #1823753'>
+
+CONFIG_COMPAT_BRK                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_COMPAT_BRK                               note<'disables brk ASLR'>
+
+CONFIG_CONSOLE_LOGLEVEL_QUIET                   policy<{'amd64': '3', 'arm64': '3', 'armhf': '3', 'ppc64el': '3', 'riscv64': '3', 's390x': '3'}>
+CONFIG_CONSOLE_LOGLEVEL_QUIET                   note<'LP: #2049390'>
+
+CONFIG_CP15_BARRIER_EMULATION                   policy<{'arm64': 'y', 'arm64-generic-64k': '-'}>
+CONFIG_CP15_BARRIER_EMULATION                   note<'LP: #1545542'>
+
+CONFIG_CPUFREQ_DT                               policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPUFREQ_DT                               note<'not autoloadable'>
+
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'y'}>
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE         note<'for bootspeed'>
+
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE                note<'not autoloadable'>
+
+CONFIG_CPU_FREQ_GOV_ONDEMAND                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_FREQ_GOV_ONDEMAND                    note<'not autoloadable'>
+
+CONFIG_CPU_FREQ_GOV_PERFORMANCE                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_FREQ_GOV_PERFORMANCE                 note<'not autoloadable'>
+
+CONFIG_CPU_FREQ_GOV_POWERSAVE                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_FREQ_GOV_POWERSAVE                   note<'not autoloadable'>
+
+CONFIG_CPU_FREQ_GOV_USERSPACE                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_FREQ_GOV_USERSPACE                   note<'not autoloadable'>
+
+CONFIG_CPU_FREQ_STAT                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_FREQ_STAT                            note<'dependancy of boot essential'>
+
+CONFIG_CRASH_DUMP                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRASH_DUMP                               note<'LP: #1363180'>
+
+CONFIG_CRYPTO_SHA512                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_SHA512                            note<'module signing'>
+
+CONFIG_CRYPTO_SHA512_ARM                        policy<{'armhf': 'y'}>
+CONFIG_CRYPTO_SHA512_ARM                        note<'LP: #2034061'>
+
+CONFIG_CRYPTO_SHA512_ARM64                      policy<{'arm64': 'y'}>
+CONFIG_CRYPTO_SHA512_ARM64                      note<'LP: #2034061'>
+
+CONFIG_CRYPTO_SHA512_ARM64_CE                   policy<{'arm64': 'y'}>
+CONFIG_CRYPTO_SHA512_ARM64_CE                   note<'LP: #2034061'>
+
+CONFIG_CRYPTO_SHA512_S390                       policy<{'s390x': 'y'}>
+CONFIG_CRYPTO_SHA512_S390                       note<'LP: #2034061'>
+
+CONFIG_CRYPTO_SHA512_SSSE3                      policy<{'amd64': 'y'}>
+CONFIG_CRYPTO_SHA512_SSSE3                      note<'LP: #2034061'>
+
+CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE          note<'Obsolete w/ no known userspace dependencies'>
+
+CONFIG_DEBUG_FS                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEBUG_FS                                 note<'required debug option'>
+
+CONFIG_DEBUG_INFO                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEBUG_INFO                               note<'required for debug packages'>
+
+CONFIG_DEBUG_INFO_BTF                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEBUG_INFO_BTF                           note<'Needs newer pahole for armhf'>
+
+CONFIG_DEBUG_INFO_SPLIT                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_INFO_SPLIT                         note<'LP: #1413664'>
+
+CONFIG_DEBUG_KERNEL                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEBUG_KERNEL                             note<'required debug option'>
+
+CONFIG_DEFAULT_MMAP_MIN_ADDR                    policy<{'amd64': '65536', 'arm64': '32768', 'armhf': '32768', 'ppc64el': '65536', 'riscv64': '65536', 's390x': '65536'}>
+CONFIG_DEFAULT_MMAP_MIN_ADDR                    note<'LP: #1531327'>
+
+CONFIG_DEVTMPFS                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEVTMPFS                                 note<'upstart requirement'>
+
+CONFIG_DEVTMPFS_MOUNT                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEVTMPFS_MOUNT                           note<'upstart requirement'>
+
+CONFIG_DMA_CMA                                  policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_DMA_CMA                                  note<'LP: #1803206'>
+
+CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING note<'LP: #2019040'>
+
+CONFIG_DRM                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_DRM                                      note<'LP: #1965303'>
+
+CONFIG_DRM_AMDGPU_CIK                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_AMDGPU_CIK                           note<'for zesty'>
+
+CONFIG_DRM_HISI_HIBMC                           policy<{'arm64': 'm'}>
+CONFIG_DRM_HISI_HIBMC                           note<'LP: #1762940'>
+
+CONFIG_DRM_MGAG200                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_MGAG200                              note<'LP: #1693337'>
+
+CONFIG_DRM_SIMPLEDRM                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_DRM_SIMPLEDRM                            note<'LP: #1965303'>
+
+CONFIG_DRM_VBOXVIDEO                            policy<{'amd64': 'm'}>
+CONFIG_DRM_VBOXVIDEO                            note<'LP: #1718679'>
+
+CONFIG_DVB_DUMMY_FE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_DUMMY_FE                             note<'expert use only'>
+
+CONFIG_ECRYPT_FS                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ECRYPT_FS                                note<'not autoloadable'>
+
+CONFIG_EFIVAR_FS                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_EFIVAR_FS                                note<'needed for variable EFI update'>
+
+CONFIG_EFI_HANDOVER_PROTOCOL                    policy<{'amd64': 'y'}>
+CONFIG_EFI_HANDOVER_PROTOCOL                    note<'{GRUB may include some downstream patches that may rely on the handover protocol, so make sure this is enabled}'>
+
+CONFIG_EFI_ZBOOT                                policy<{'arm64': 'y', 'riscv64': 'n'}>
+CONFIG_EFI_ZBOOT                                note<'LP: #2002226'>
+
+CONFIG_EVM                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EVM                                      note<'LP: #1643652'>
+
+CONFIG_EVM_ATTR_FSUUID                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EVM_ATTR_FSUUID                          note<'LP: #1643652'>
+
+CONFIG_EVM_LOAD_X509                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_EVM_LOAD_X509                            note<'LP: #1643652'>
+
+CONFIG_EVM_X509_PATH                            policy<{'ppc64el': '"/etc/keys/x509_evm.der"'}>
+CONFIG_EVM_X509_PATH                            note<'LP: #1643652'>
+
+CONFIG_EXT2_FS                                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_EXT2_FS                                  note<'ext4 handling via EXT4_USE_FOR_EXT23'>
+
+CONFIG_EXT3_FS                                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_EXT3_FS                                  note<'ext4 handling via EXT4_USE_FOR_EXT23'>
+
+CONFIG_FA_DUMP                                  policy<{'ppc64el': 'y'}>
+CONFIG_FA_DUMP                                  note<'LP: #1415562'>
+
+CONFIG_FB_EFI                                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'riscv64': 'n'}>
+CONFIG_FB_EFI                                   note<'LP: #1965303'>
+
+CONFIG_FB_VESA                                  policy<{'amd64': 'n'}>
+CONFIG_FB_VESA                                  note<'LP: #1965303'>
+
+CONFIG_FHANDLE                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FHANDLE                                  note<'LP: #1412543'>
+
+CONFIG_FUSE_FS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FUSE_FS                                  note<'not autoloadable'>
+
+CONFIG_FW_LOADER_USER_HELPER_FALLBACK           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FW_LOADER_USER_HELPER_FALLBACK           note<'LP: #1398458'>
+
+CONFIG_GPIO_CDEV_V1                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GPIO_CDEV_V1                             note<'LP: #1953613'>
+
+CONFIG_GPIO_EM                                  policy<{'armhf': 'n'}>
+CONFIG_GPIO_EM                                  note<'h/w not encounted'>
+
+CONFIG_GPIO_TWL4030                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GPIO_TWL4030                             note<'LP: #921934'>
+
+CONFIG_HIBERNATION                              policy<{'amd64': 'y', 'arm64': 'n', 'armhf': 'y', 'ppc64el': 'n', 'riscv64': '-'}>
+CONFIG_HIBERNATION                              note<'LP: #1867753'>
+
+CONFIG_HOTPLUG_PCI_PCIE                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': '-', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HOTPLUG_PCI_PCIE                         note<'LP: #1374440'>
+
+CONFIG_HOTPLUG_PCI_SHPC                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': 'n', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_HOTPLUG_PCI_SHPC                         note<'LP: #1374440'>
+
+CONFIG_HSA_AMD_P2P                              policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_HSA_AMD_P2P                              note<'LP: #1987394'>
+
+CONFIG_HSU_DMA                                  policy<{'amd64': 'y'}>
+CONFIG_HSU_DMA                                  note<'required by CONFIG_SERIAL_8250_MID (LP: #2009283)'>
+
+CONFIG_HVC_UDBG                                 policy<{'ppc64el': 'n'}>
+CONFIG_HVC_UDBG                                 note<'LP: #1680888'>
+
+CONFIG_HZ_100                                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'y'}>
+CONFIG_HZ_100                                   note<'LP: #2051342'>
+
+CONFIG_HZ_1000                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_HZ_1000                                  note<'LP: #2051342'>
+
+CONFIG_HZ_250                                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_HZ_250                                   note<'LP: #2051342'>
+
+CONFIG_I2C_CHARDEV                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_I2C_CHARDEV                              note<'LP: #1417032'>
+
+CONFIG_IBMVNIC                                  policy<{'ppc64el': 'm'}>
+CONFIG_IBMVNIC                                  note<'LP: #1628187'>
+
+CONFIG_IDLE_PAGE_TRACKING                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IDLE_PAGE_TRACKING                       note<'is there a cost associated with this?'>
+
+CONFIG_IIO_SIMPLE_DUMMY_BUFFER                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_IIO_SIMPLE_DUMMY_BUFFER                  note<'dummy driver'>
+
+CONFIG_IIO_SIMPLE_DUMMY_EVENTS                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_IIO_SIMPLE_DUMMY_EVENTS                  note<'dummy driver'>
+
+CONFIG_IMA                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IMA                                      note<'LP: #1643652'>
+
+CONFIG_IMA_APPRAISE                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IMA_APPRAISE                             note<'LP: #1643652'>
+
+CONFIG_IMA_ARCH_POLICY                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IMA_ARCH_POLICY                          note<'LP: #1866909'>
+
+CONFIG_IMA_DEFAULT_HASH_SHA256                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IMA_DEFAULT_HASH_SHA256                  note<'LP: #2041735'>
+
+CONFIG_IMA_KEXEC                                policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IMA_KEXEC                                note<'LP: #1643652'>
+
+CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY note<'LP: #1667490'>
+
+CONFIG_IMA_READ_POLICY                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IMA_READ_POLICY                          note<'LP: #1866909'>
+
+CONFIG_IMA_SIG_TEMPLATE                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IMA_SIG_TEMPLATE                         note<'LP: #1643652'>
+
+CONFIG_IMA_WRITE_POLICY                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IMA_WRITE_POLICY                         note<'LP: #1667490'>
+
+CONFIG_INPUT_UINPUT                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_INPUT_UINPUT                             note<'LP: #584812'>
+
+CONFIG_INTEGRITY_PLATFORM_KEYRING               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INTEGRITY_PLATFORM_KEYRING               note<'Required for lockdown'>
+
+CONFIG_INTEL_ATOMISP                            policy<{'amd64': 'n'}>
+CONFIG_INTEL_ATOMISP                            note<'LP: #2017444'>
+
+CONFIG_INTEL_ATOMISP2_PM                        policy<{'amd64': 'm'}>
+CONFIG_INTEL_ATOMISP2_PM                        note<'LP: #2017444'>
+
+CONFIG_INTEL_IOMMU_DEFAULT_ON                   policy<{'amd64': 'y'}>
+CONFIG_INTEL_IOMMU_DEFAULT_ON                   note<'LP: #1951440'>
+
+CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON     policy<{'amd64': 'y'}>
+CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON     note<'LP: #1951440'>
+
+CONFIG_IOMMU_DEBUGFS                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IOMMU_DEBUGFS                            note<'LP: #1861057'>
+
+CONFIG_IOMMU_DEFAULT_DMA_LAZY                   policy<{'amd64': 'y', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'y'}>
+CONFIG_IOMMU_DEFAULT_DMA_LAZY                   note<'LP: #2071471'>
+
+CONFIG_IOMMU_DEFAULT_DMA_STRICT                 policy<{'amd64': 'n', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_IOMMU_DEFAULT_DMA_STRICT                 note<'LP: #2071471'>
+
+CONFIG_IPMMU_VMSA                               policy<{'arm64': 'n', 'armhf': 'n', 'riscv64': '-'}>
+CONFIG_IPMMU_VMSA                               note<'LP: #1718734'>
+
+CONFIG_IPV6                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPV6                                     note<'if this is a module we get a module load for every ipv6 packet'>
+
+CONFIG_IP_PNP                                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IP_PNP                                   note<'LP: #1259861'>
+
+CONFIG_ISM                                      policy<{'s390x': 'm'}>
+CONFIG_ISM                                      note<'LP: #1789934'>
+
+CONFIG_KERNEL_ZSTD                              policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_KERNEL_ZSTD                              note<'LP: #1931725'>
+
+CONFIG_KEXEC_BZIMAGE_VERIFY_SIG                 policy<{'amd64': 'y'}>
+CONFIG_KEXEC_BZIMAGE_VERIFY_SIG                 note<'Q: check this is in sync with the kexec/kdump userspace'>
+
+CONFIG_KFENCE_STATIC_KEYS                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': '-', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_KFENCE_STATIC_KEYS                       note<'LP: #1948038'>
+
+CONFIG_KGDB_SERIAL_CONSOLE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_KGDB_SERIAL_CONSOLE                      note<'early debugging support'>
+
+CONFIG_KVM                                      policy<{'amd64': 'm', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'm', 's390x': 'y'}>
+CONFIG_KVM                                      note<'LP: #1532886'>
+
+CONFIG_LATENCYTOP                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LATENCYTOP                               note<'LP: #2051342'>
+
+CONFIG_LEGACY_TIOCSTI                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_LEGACY_TIOCSTI                           note<'LP:#2046192'>
+
+CONFIG_LOAD_PPC_KEYS                            policy<{'ppc64el': 'y'}>
+CONFIG_LOAD_PPC_KEYS                            note<'LP: #1866909'>
+
+CONFIG_LOCALVERSION_AUTO                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_LOCALVERSION_AUTO                        note<'triggers packaging failures'>
+
+CONFIG_LRU_GEN                                  policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LRU_GEN                                  note<'{Enable multi-gen LRU by default - LP: #2023629}'>
+
+CONFIG_LRU_GEN_ENABLED                          policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LRU_GEN_ENABLED                          note<'{Enable multi-gen LRU by default - LP: #2023629}'>
+
+CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE            policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'n', 's390x': 'n'}>
+CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE            note<'LP: #1848492'>
+
+CONFIG_MFD_SM501                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_SM501                                note<'boot essential on OMAP4'>
+
+CONFIG_MFD_TPS65217                             policy<{'arm64': 'm', 'armhf': 'y', 'ppc64el': 'n', 'riscv64': 'm'}>
+CONFIG_MFD_TPS65217                             note<'boot essential on AM335x'>
+
+CONFIG_MHP_MEMMAP_ON_MEMORY                     policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_MHP_MEMMAP_ON_MEMORY                     note<'LP: #2051835'>
+
+CONFIG_MMC_BLOCK                                policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MMC_BLOCK                                note<'boot essential on armhf/arm64'>
+
+CONFIG_MMC_OMAP_HS                              policy<{'armhf': 'y'}>
+CONFIG_MMC_OMAP_HS                              note<'boot essential on arm'>
+
+CONFIG_MMC_SDHCI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MMC_SDHCI                                note<'installation essential on omap/highbank'>
+
+CONFIG_MMC_SDHCI_PLTFM                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_SDHCI_PLTFM                          note<'boot essential on highbank'>
+
+CONFIG_MODIFY_LDT_SYSCALL                       policy<{'amd64': 'y'}>
+CONFIG_MODIFY_LDT_SYSCALL                       note<'Q: check this with security'>
+
+CONFIG_MODULE_COMPRESS_ZSTD                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MODULE_COMPRESS_ZSTD                     note<'LP: #2028568'>
+
+CONFIG_MODVERSIONS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MODVERSIONS                              note<'required as we have a livepatch/drivers modules signing key'>
+
+CONFIG_MTD                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MTD                                      note<'boot essential on arm'>
+
+CONFIG_MTD_BLOCK                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MTD_BLOCK                                note<'boot essential on arm'>
+
+CONFIG_MTD_DOCG3                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MTD_DOCG3                                note<'LP: #1792205'>
+
+CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_MTD_NAND_DISKONCHIP_BBTWRITE             note<'can be enabled at runtime'>
+
+CONFIG_MTD_OF_PARTS                             policy<{'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_OF_PARTS                             note<'boot essential on arm'>
+
+CONFIG_MTD_ONENAND_VERIFY_WRITE                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_ONENAND_VERIFY_WRITE                 note<'writes here are not checked in full without'>
+
+CONFIG_MTD_RAW_NAND                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MTD_RAW_NAND                             note<'boot essential on arm'>
+
+CONFIG_NETWORK_PHY_TIMESTAMPING                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETWORK_PHY_TIMESTAMPING                 note<'LP: #1785816'>
+
+CONFIG_NET_9P                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_9P                                   note<'LP: #1557994'>
+
+CONFIG_NET_DROP_MONITOR                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_DROP_MONITOR                         note<'LP: #1660634'>
+
+CONFIG_NET_SWITCHDEV                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_SWITCHDEV                            note<'updated to y for s390x starting with focal'>
+
+CONFIG_NET_VENDOR_EMULEX                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_EMULEX                        note<'LP: #1543165'>
+
+CONFIG_NLS                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NLS                                      note<'dependancy of boot essential'>
+
+CONFIG_NOP_USB_XCEIV                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_NOP_USB_XCEIV                            note<'boot essential on omap/highbank'>
+
+CONFIG_NO_HZ_FULL                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_NO_HZ_FULL                               note<'LP: #2051342'>
+
+CONFIG_NO_HZ_IDLE                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NO_HZ_IDLE                               note<'LP: #2051342'>
+
+CONFIG_NR_CPUS                                  policy<{'amd64': '8192', 'arm64': '512', 'armhf': '4', 'ppc64el': '2048', 'riscv64': '32', 's390x': '512'}>
+CONFIG_NR_CPUS                                  note<'LP: #2042897 (arm64), LP: #1967889 (riscv64), LP: #1864198 (s390x)'>
+
+CONFIG_NUMA                                     policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NUMA                                     note<'LP: #1557690'>
+
+CONFIG_NUMA_BALANCING_DEFAULT_ENABLED           policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NUMA_BALANCING_DEFAULT_ENABLED           note<'LP: #1557690'>
+
+CONFIG_NUMA_EMU                                 policy<{'amd64': 'n'}>
+CONFIG_NUMA_EMU                                 note<'LP: #1864198'>
+
+CONFIG_NVMEM                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NVMEM                                    note<'LP: #1543165'>
+
+CONFIG_NVRAM                                    policy<{'amd64': 'm', 'ppc64el': 'y'}>
+CONFIG_NVRAM                                    note<'LP: #1837726'>
+
+CONFIG_N_GSM                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_N_GSM                                    note<'LP: #1404670'>
+
+CONFIG_OSNOISE_TRACER                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_OSNOISE_TRACER                           note<'This enables the osnoise tracer for the kernel. LP: #2018591'>
+
+CONFIG_PAGE_POISONING                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PAGE_POISONING                           note<'LP: #1783651'>
+
+CONFIG_PANIC_ON_OOPS                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PANIC_ON_OOPS                            note<'keep working if at all possible'>
+
+CONFIG_PATA_HPT3X3_DMA                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_PATA_HPT3X3_DMA                          note<'DMA mode is documented problematic'>
+
+CONFIG_PCIEASPM_DEFAULT                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCIEASPM_DEFAULT                         note<'LP: #1398544'>
+
+CONFIG_PCIEPORTBUS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'n', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCIEPORTBUS                              note<'LP: #1665404'>
+
+CONFIG_PCI_DYNAMIC_OF_NODES                     policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_PCI_DYNAMIC_OF_NODES                     note<'LP: #2074376'>
+
+CONFIG_PCI_MESON                                policy<{'amd64': 'n', 'arm64': 'm', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PCI_MESON                                note<'LP: #2007745'>
+
+CONFIG_PCI_NR_FUNCTIONS                         policy<{'s390x': '512'}>
+CONFIG_PCI_NR_FUNCTIONS                         note<'LP: #1866056'>
+
+CONFIG_PINCTRL_CHERRYVIEW                       policy<{'amd64': 'y'}>
+CONFIG_PINCTRL_CHERRYVIEW                       note<'LP: #1630238'>
+
+CONFIG_PM                                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PM                                       note<'LP: #1867753'>
+
+CONFIG_PPC_MEM_KEYS                             policy<{'ppc64el': 'n'}>
+CONFIG_PPC_MEM_KEYS                             note<'LP: #1776967'>
+
+CONFIG_PPC_SECURE_BOOT                          policy<{'ppc64el': 'y'}>
+CONFIG_PPC_SECURE_BOOT                          note<'LP: #1855668'>
+
+CONFIG_PPC_SECVAR_SYSFS                         policy<{'ppc64el': 'y'}>
+CONFIG_PPC_SECVAR_SYSFS                         note<'LP: #1866909'>
+
+CONFIG_PREEMPT_DYNAMIC                          policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_PREEMPT_DYNAMIC                          note<'LP: #2051342'>
+
+CONFIG_PSI_DEFAULT_DISABLED                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'y'}>
+CONFIG_PSI_DEFAULT_DISABLED                     note<'LP: #1876044'>
+
+CONFIG_QCOM_QDF2400_ERRATUM_0065                policy<{'arm64': 'y'}>
+CONFIG_QCOM_QDF2400_ERRATUM_0065                note<'LP: #1672486'>
+
+CONFIG_QETH_OSX                                 policy<{'s390x': 'n'}>
+CONFIG_QETH_OSX                                 note<'LP: #1959890'>
+
+CONFIG_RCU_LAZY                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_RCU_LAZY                                 note<'LP: #2051342'>
+
+CONFIG_RCU_LAZY_DEFAULT_OFF                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_RCU_LAZY_DEFAULT_OFF                     note<'LP: #2051342'>
+
+CONFIG_RCU_NOCB_CPU                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_RCU_NOCB_CPU                             note<'LP: #2051342'>
+
+CONFIG_RCU_NOCB_CPU_DEFAULT_ALL                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': '-', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_RCU_NOCB_CPU_DEFAULT_ALL                 note<'LP: #2051342'>
+
+CONFIG_REGULATOR_FIXED_VOLTAGE                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_REGULATOR_FIXED_VOLTAGE                  note<'boot essential on arm and the Allwinner D1 RISC-V SoC'>
+
+CONFIG_REGULATOR_TPS65217                       policy<{'arm64': 'm', 'armhf': 'y', 'ppc64el': '-', 'riscv64': 'm'}>
+CONFIG_REGULATOR_TPS65217                       note<'boot essential on AM335x'>
+
+CONFIG_REGULATOR_TWL4030                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_TWL4030                        note<'boot requisite for omap4'>
+
+CONFIG_RTC_DRV_CMOS                             policy<{'amd64': 'y', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_RTC_DRV_CMOS                             note<'boot essential on i386/amd64'>
+
+CONFIG_RTC_DRV_EFI                              policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_EFI                              note<'LP: #1583738'>
+
+CONFIG_RTC_DRV_TWL4030                          policy<{'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_TWL4030                          note<'boot essential on OMAP3/OMAP4'>
+
+CONFIG_RT_GROUP_SCHED                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_RT_GROUP_SCHED                           note<'LP: #1875665'>
+
+CONFIG_S390_UV_UAPI                             policy<{'s390x': 'y'}>
+CONFIG_S390_UV_UAPI                             note<'LP: #2048919'>
+
+CONFIG_SAMPLE_TRACE_PRINTK                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SAMPLE_TRACE_PRINTK                      note<'Required for ftrace selftests'>
+
+CONFIG_SATA_AHCI_PLATFORM                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_AHCI_PLATFORM                       note<'boot essential on highbank'>
+
+CONFIG_SATA_HIGHBANK                            policy<{'armhf': 'y'}>
+CONFIG_SATA_HIGHBANK                            note<'LP: #1703430'>
+
+CONFIG_SCLP_OFB                                 policy<{'s390x': 'y'}>
+CONFIG_SCLP_OFB                                 note<'LP: #1787898'>
+
+CONFIG_SCSI_IPR_DUMP                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SCSI_IPR_DUMP                            note<'LP: #1343109'>
+
+CONFIG_SCSI_IPR_TRACE                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SCSI_IPR_TRACE                           note<'LP: #1343109'>
+
+CONFIG_SCSI_VIRTIO                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCSI_VIRTIO                              note<'enable initrdless boot in VMs for ease of use, cloud-kernel parity and disaster recovery, LP: #1685291'>
+
+CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS        note<'LP: #1990064'>
+
+CONFIG_SECURITY_SAFESETID                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_SAFESETID                       note<'LP: #1845391'>
+
+CONFIG_SERIAL_8250_DW                           policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_DW                           note<'several RISC-V boards needs this for console output'>
+
+CONFIG_SERIAL_8250_MID                          policy<{'amd64': 'y'}>
+CONFIG_SERIAL_8250_MID                          note<'required to provide console on some Intel SoC platforms (LP: #2009283)'>
+
+CONFIG_SERIAL_DEV_BUS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SERIAL_DEV_BUS                           note<'LP: #1739939'>
+
+CONFIG_SERIAL_DEV_CTRL_TTYPORT                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SERIAL_DEV_CTRL_TTYPORT                  note<'LP: #1739939'>
+
+CONFIG_SERIAL_SH_SCI                            policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_SH_SCI                            note<'LP: #2022361'>
+
+CONFIG_SERIAL_SH_SCI_CONSOLE                    policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_SH_SCI_CONSOLE                    note<'LP: #2022361'>
+
+CONFIG_SERIAL_SH_SCI_EARLYCON                   policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_SH_SCI_EARLYCON                   note<'LP: #2022361'>
+
+CONFIG_SETEND_EMULATION                         policy<{'arm64': 'y', 'arm64-generic-64k': '-'}>
+CONFIG_SETEND_EMULATION                         note<'LP: #1545542'>
+
+CONFIG_SMC                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SMC                                      note<'LP: #1789934'>
+
+CONFIG_SMC_DIAG                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SMC_DIAG                                 note<'LP: #1789934'>
+
+CONFIG_SND                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND                                      note<'not autoloadable on omap'>
+
+CONFIG_SND_HDA_POWER_SAVE_DEFAULT               policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'ppc64el': '1', 'riscv64': '1'}>
+CONFIG_SND_HDA_POWER_SAVE_DEFAULT               note<'LP: #1804265'>
+
+CONFIG_SND_HDA_RECONFIG                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_HDA_RECONFIG                         note<'allows fixes to be tested live'>
+
+CONFIG_SND_PCM_OSS                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SND_PCM_OSS                              note<'deprecated in favour of pulseaudio emulation'>
+
+CONFIG_SND_SOC                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC                                  note<'not autoloadable on omap'>
+
+CONFIG_SND_SOC_AMD_RENOIR                       policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_RENOIR                       note<'LP: #1881046'>
+
+CONFIG_SND_SOC_AMD_RENOIR_MACH                  policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_RENOIR_MACH                  note<'LP: #1881046'>
+
+CONFIG_SND_SOC_INTEL_CFL                        policy<{'amd64': 'n'}>
+CONFIG_SND_SOC_INTEL_CFL                        note<'deprecated'>
+
+CONFIG_SND_SOC_INTEL_CML_H                      policy<{'amd64': 'n'}>
+CONFIG_SND_SOC_INTEL_CML_H                      note<'deprecated'>
+
+CONFIG_SND_SOC_INTEL_CML_LP                     policy<{'amd64': 'n'}>
+CONFIG_SND_SOC_INTEL_CML_LP                     note<'deprecated'>
+
+CONFIG_SND_SOC_INTEL_CNL                        policy<{'amd64': 'n'}>
+CONFIG_SND_SOC_INTEL_CNL                        note<'deprecated'>
+
+CONFIG_SND_SOC_INTEL_SKYLAKE                    policy<{'amd64': 'n'}>
+CONFIG_SND_SOC_INTEL_SKYLAKE                    note<'deprecated'>
+
+CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC      policy<{'amd64': 'y'}>
+CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC      note<'LP: #1915117'>
+
+CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH         policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH         note<'LP: #1921632'>
+
+CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES   policy<{'amd64': 'y'}>
+CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES   note<'LP: #1921632'>
+
+CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC              policy<{'amd64': 'y'}>
+CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC              note<'LP: #1848490'>
+
+CONFIG_SND_SOC_SOF_HDA_LINK                     policy<{'amd64': 'y'}>
+CONFIG_SND_SOC_SOF_HDA_LINK                     note<'LP: #1848490'>
+
+CONFIG_SOUND                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SOUND                                    note<'not autoloadable on omap'>
+
+CONFIG_SOUNDWIRE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SOUNDWIRE                                note<'LP: #1855685'>
+
+CONFIG_SOUND_OSS_CORE_PRECLAIM                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SOUND_OSS_CORE_PRECLAIM                  note<'LP: #1385510'>
+
+CONFIG_SQUASHFS                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SQUASHFS                                 note<'LP: #1593134'>
+
+CONFIG_SQUASHFS_4K_DEVBLK_SIZE                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SQUASHFS_4K_DEVBLK_SIZE                  note<'non-default block size'>
+
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU             note<'LP: #1980861'>
+
+CONFIG_STACK_VALIDATION                         policy<{'amd64': 'y'}>
+CONFIG_STACK_VALIDATION                         note<'needed for livepatch'>
+
+CONFIG_SUN6I_RTC_CCU                            policy<{'arm64': 'm', 'riscv64': 'y'}>
+CONFIG_SUN6I_RTC_CCU                            note<'needed by Allwinner D1 pinctrl/gpio'>
+
+CONFIG_SWP_EMULATION                            policy<{'arm64': 'y', 'arm64-generic-64k': '-'}>
+CONFIG_SWP_EMULATION                            note<'LP: #1545542'>
+
+CONFIG_SYSFB_SIMPLEFB                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_SYSFB_SIMPLEFB                           note<'LP: #1965303'>
+
+CONFIG_TCG_TIS_I2C_ATMEL                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'y', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_TCG_TIS_I2C_ATMEL                        note<'LP: #1643652'>
+
+CONFIG_TCG_TIS_I2C_INFINEON                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'y', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_TCG_TIS_I2C_INFINEON                     note<'LP: #1643652'>
+
+CONFIG_TCG_TIS_I2C_NUVOTON                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'y', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_TCG_TIS_I2C_NUVOTON                      note<'LP: #1643652'>
+
+CONFIG_TCG_TPM                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TCG_TPM                                  note<'needed for early validation'>
+
+CONFIG_TEST_BLACKHOLE_DEV                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TEST_BLACKHOLE_DEV                       note<'Used by net selftests'>
+
+CONFIG_TIMERLAT_TRACER                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TIMERLAT_TRACER                          note<'This enables the osnoise tracer for the kernel. LP: #2018591'>
+
+CONFIG_TMPFS_POSIX_ACL                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TMPFS_POSIX_ACL                          note<'some /dev nodes require POSIX ACLs, like /dev/dsp'>
+
+CONFIG_TOUCHSCREEN_ELAN                         policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_ELAN                         note<'LP: #1630238'>
+
+CONFIG_TUNE_Z16                                 policy<{'s390x': 'y'}>
+CONFIG_TUNE_Z16                                 note<'LP: #1982833 in general, always pick the newest tune available'>
+
+CONFIG_UBSAN                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'n', 's390x': 'y'}>
+CONFIG_UBSAN                                    note<'LP: #1942215'>
+
+CONFIG_UNWINDER_FRAME_POINTER                   policy<{'amd64': 'y', 'armhf': 'y'}>
+CONFIG_UNWINDER_FRAME_POINTER                   note<'needed for livepatch'>
+
+CONFIG_USB_EHCI_HCD                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_EHCI_HCD                             note<'ensures USB 2.0/1.1 probe ordering'>
+
+CONFIG_USB_EHCI_HCD_PLATFORM                    policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_EHCI_HCD_PLATFORM                    note<'Dont use the generic ehci/ohci code on omap, it doesnt work'>
+
+CONFIG_USB_HCD_BCMA                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_HCD_BCMA                             note<'USB_{O,E}HCI_HCD_PLATFORM must be off on omap'>
+
+CONFIG_USB_HCD_SSB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_HCD_SSB                              note<'USB_{O,E}HCI_HCD_PLATFORM must be off on omap'>
+
+CONFIG_USB_M66592                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_USB_M66592                               note<'gadget device'>
+
+CONFIG_USB_MUSB_HDRC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_MUSB_HDRC                            note<'not autoloadable on omap'>
+
+CONFIG_USB_OTG                                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'y'}>
+CONFIG_USB_OTG                                  note<'LP: #1411295'>
+
+CONFIG_USB_SERIAL_DEBUG                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_DEBUG                         note<'not actually debug'>
+
+CONFIG_USB_UHCI_HCD                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_UHCI_HCD                             note<'ensures USB 2.0/1.1 probe ordering'>
+
+CONFIG_USB_XHCI_DBGCAP                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_XHCI_DBGCAP                          note<'LP: #1730832'>
+
+CONFIG_USB_XHCI_HCD                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_XHCI_HCD                             note<'ensures USB 2.0/1.1 probe ordering'>
+
+CONFIG_VFAT_FS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VFAT_FS                                  note<'needed on arm to ensure we can write the kernel when replacing'>
+
+CONFIG_VFIO                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VFIO                                     note<'LP: #1636733'>
+
+CONFIG_VFIO_PCI                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VFIO_PCI                                 note<'LP: #1636733'>
+
+CONFIG_VFIO_PCI_ZDEV_KVM                        policy<{'s390x': 'y'}>
+CONFIG_VFIO_PCI_ZDEV_KVM                        note<'LP: #2042853'>
+
+CONFIG_VIDEO_VIMC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_VIMC                               note<'LP: #1831482'>
+
+CONFIG_VIRTIO_BLK                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIRTIO_BLK                               note<'LP: #2030745'>
+
+CONFIG_VIRTIO_MMIO                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_VIRTIO_MMIO                              note<'LP: #1557689'>
+
+CONFIG_VIRTIO_NET                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIRTIO_NET                               note<'KVM paravirt support -- cloud-init currently racy with this as a module (LP: #2036968)'>
+
+CONFIG_WWAN                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_WWAN                                     note<'LP: #2033406'>
+
+CONFIG_X509_CERTIFICATE_PARSER                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_X509_CERTIFICATE_PARSER                  note<'module signing'>
+
+CONFIG_X86_ACPI_CPUFREQ                         policy<{'amd64': 'y'}>
+CONFIG_X86_ACPI_CPUFREQ                         note<'not autoloadable'>
+
+CONFIG_X86_KERNEL_IBT                           policy<{'amd64': 'n'}>
+CONFIG_X86_KERNEL_IBT                           note<'LP: #1980484'>
+
+CONFIG_X86_PCC_CPUFREQ                          policy<{'amd64': 'y'}>
+CONFIG_X86_PCC_CPUFREQ                          note<'not autoloadable'>
+
+CONFIG_X86_POWERNOW_K8                          policy<{'amd64': 'y'}>
+CONFIG_X86_POWERNOW_K8                          note<'not autoloadable'>
+
+CONFIG_X86_SPEEDSTEP_CENTRINO                   policy<{'amd64': 'y'}>
+CONFIG_X86_SPEEDSTEP_CENTRINO                   note<'not autoloadable'>
+
+CONFIG_X86_UV                                   policy<{'amd64': 'y'}>
+CONFIG_X86_UV                                   note<'LP: #1863810'>
+
+CONFIG_X86_X32_ABI                              policy<{'amd64': 'n'}>
+CONFIG_X86_X32_ABI                              note<'LP: #1994516'>
+
+CONFIG_XEN_512GB                                policy<{'amd64': 'y'}>
+CONFIG_XEN_512GB                                note<'Q: is this related to the utlemming questions on memory size?'>
+
+CONFIG_XEN_ACPI_PROCESSOR                       policy<{'amd64': 'y'}>
+CONFIG_XEN_ACPI_PROCESSOR                       note<'boot essential on XEN host'>
+
+CONFIG_XEN_BLKDEV_FRONTEND                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-'}>
+CONFIG_XEN_BLKDEV_FRONTEND                      note<'not autoloadable -- XEN paravirt support'>
+
+CONFIG_XEN_NETDEV_FRONTEND                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-'}>
+CONFIG_XEN_NETDEV_FRONTEND                      note<'not autoloadable -- XEN paravirt support'>
+
+CONFIG_XZ_DEC                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XZ_DEC                                   note<'boot essential -- initramfs decompressor'>
+
+CONFIG_ZLIB_DFLTCC                              policy<{'s390x': 'y'}>
+CONFIG_ZLIB_DFLTCC                              note<'LP: #1830208'>
+
+CONFIG_ZONE_DMA                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 's390x': 'y'}>
+CONFIG_ZONE_DMA                                 note<'LP: #1628523'>
+
+
+# ---- Annotations without notes ----
+
+CONFIG_104_QUAD_8                               policy<{'amd64': 'm'}>
+CONFIG_60XX_WDT                                 policy<{'amd64': 'm'}>
+CONFIG_64BIT                                    policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_6LOWPAN                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_6LOWPAN_DEBUGFS                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_6LOWPAN_GHC_EXT_HDR_DEST                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_6LOWPAN_GHC_EXT_HDR_FRAG                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_6LOWPAN_GHC_EXT_HDR_HOP                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_6LOWPAN_GHC_EXT_HDR_ROUTE                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_6LOWPAN_GHC_ICMPV6                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_6LOWPAN_GHC_UDP                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_6LOWPAN_NHC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_6LOWPAN_NHC_DEST                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_6LOWPAN_NHC_FRAGMENT                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_6LOWPAN_NHC_HOP                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_6LOWPAN_NHC_IPV6                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_6LOWPAN_NHC_MOBILITY                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_6LOWPAN_NHC_ROUTING                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_6LOWPAN_NHC_UDP                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_6PACK                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_8139CP                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_8139TOO                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_8139TOO_8129                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_8139TOO_PIO                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_8139TOO_TUNE_TWISTER                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_8139_OLD_RX_RESET                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_842_COMPRESS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_842_DECOMPRESS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_9P_FS                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_9P_FSCACHE                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_9P_FS_POSIX_ACL                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_9P_FS_SECURITY                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_A11Y_BRAILLE_CONSOLE                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_A64FX_DIAG                               policy<{'arm64': 'y'}>
+CONFIG_ABP060MG                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AC97_BUS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ACENIC                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ACENIC_OMIT_TIGON_I                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ACERHDF                                  policy<{'amd64': 'm'}>
+CONFIG_ACER_WIRELESS                            policy<{'amd64': 'm'}>
+CONFIG_ACER_WMI                                 policy<{'amd64': 'm'}>
+CONFIG_ACORN_PARTITION                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ACPI                                     policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_AC                                  policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_ADXL                                policy<{'amd64': 'y'}>
+CONFIG_ACPI_AGDI                                policy<{'arm64': 'y'}>
+CONFIG_ACPI_ALS                                 policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_ACPI_APEI                                policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_APEI_EINJ                           policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_ACPI_APEI_ERST_DEBUG                     policy<{'amd64': 'n', 'arm64': 'n'}>
+CONFIG_ACPI_APEI_GHES                           policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_APEI_MEMORY_FAILURE                 policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_APEI_PCIEAER                        policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_APEI_SEA                            policy<{'arm64': 'y'}>
+CONFIG_ACPI_APMT                                policy<{'arm64': 'y'}>
+CONFIG_ACPI_BATTERY                             policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_BGRT                                policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_BUTTON                              policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_CCA_REQUIRED                        policy<{'arm64': 'y'}>
+CONFIG_ACPI_CMPC                                policy<{'amd64': 'm'}>
+CONFIG_ACPI_CONFIGFS                            policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_ACPI_CONTAINER                           policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_CPPC_CPUFREQ                        policy<{'arm64': 'm'}>
+CONFIG_ACPI_CPPC_CPUFREQ_FIE                    policy<{'arm64': 'y'}>
+CONFIG_ACPI_CPPC_LIB                            policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_CPU_FREQ_PSS                        policy<{'amd64': 'y'}>
+CONFIG_ACPI_CUSTOM_DSDT_FILE                    policy<{'amd64': '""'}>
+CONFIG_ACPI_DEBUG                               policy<{'amd64': 'y', 'arm64': 'n', 'riscv64': 'n'}>
+CONFIG_ACPI_DEBUGGER                            policy<{'amd64': 'y', 'arm64': 'n', 'riscv64': 'n'}>
+CONFIG_ACPI_DEBUGGER_USER                       policy<{'amd64': 'y'}>
+CONFIG_ACPI_DOCK                                policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_DPTF                                policy<{'amd64': 'y'}>
+CONFIG_ACPI_EC_DEBUGFS                          policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_ACPI_EXTLOG                              policy<{'amd64': 'm'}>
+CONFIG_ACPI_FAN                                 policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_FFH                                 policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_FPDT                                policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_GENERIC_GSI                         policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_GTDT                                policy<{'arm64': 'y'}>
+CONFIG_ACPI_HED                                 policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_HMAT                                policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_HOTPLUG_CPU                         policy<{'amd64': 'y', 'arm64': '-'}>
+CONFIG_ACPI_HOTPLUG_IOAPIC                      policy<{'amd64': 'y'}>
+CONFIG_ACPI_HOTPLUG_MEMORY                      policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_I2C_OPREGION                        policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_IORT                                policy<{'arm64': 'y'}>
+CONFIG_ACPI_IPMI                                policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_ACPI_LEGACY_TABLES_LOOKUP                policy<{'amd64': 'y'}>
+CONFIG_ACPI_LPIT                                policy<{'amd64': 'y'}>
+CONFIG_ACPI_MCFG                                policy<{'arm64': 'y'}>
+CONFIG_ACPI_MDIO                                policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_NFIT                                policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_ACPI_NUMA                                policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_PCC                                 policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_PCI_SLOT                            policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_PFRUT                               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_ACPI_PLATFORM_PROFILE                    policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_ACPI_PPTT                                policy<{'arm64': 'y'}>
+CONFIG_ACPI_PRMT                                policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_PROCESSOR                           policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_PROCESSOR_AGGREGATOR                policy<{'amd64': 'm'}>
+CONFIG_ACPI_PROCESSOR_CSTATE                    policy<{'amd64': 'y'}>
+CONFIG_ACPI_PROCESSOR_IDLE                      policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_REDUCED_HARDWARE_ONLY               policy<{'amd64': 'n', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_REV_OVERRIDE_POSSIBLE               policy<{'amd64': 'y'}>
+CONFIG_ACPI_SBS                                 policy<{'amd64': 'm'}>
+CONFIG_ACPI_SLEEP                               policy<{'amd64': 'y'}>
+CONFIG_ACPI_SPCR_TABLE                          policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT         policy<{'amd64': 'y'}>
+CONFIG_ACPI_TABLE_LIB                           policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': '-'}>
+CONFIG_ACPI_TABLE_UPGRADE                       policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_TAD                                 policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_ACPI_THERMAL                             policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_THERMAL_LIB                         policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_THERMAL_REL                         policy<{'amd64': 'm'}>
+CONFIG_ACPI_TOSHIBA                             policy<{'amd64': 'm'}>
+CONFIG_ACPI_VIDEO                               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_ACPI_VIOT                                policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ACPI_WATCHDOG                            policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ACPI_WMI                                 policy<{'amd64': 'm'}>
+CONFIG_ACQUIRE_WDT                              policy<{'amd64': 'm'}>
+CONFIG_ACRN_GUEST                               policy<{'amd64': 'y'}>
+CONFIG_ACRN_HSM                                 policy<{'amd64': 'm'}>
+CONFIG_AD2S1200                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD2S1210                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD2S90                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD3552R                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD4130                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5064                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5110                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD525X_DPOT                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_AD525X_DPOT_I2C                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD525X_DPOT_SPI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5272                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5360                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5380                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5421                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5446                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5449                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5504                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5592R                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5592R_BASE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5593R                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5624R_SPI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5686                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5686_SPI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5696_I2C                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5755                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5758                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5761                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5764                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5766                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5770R                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5791                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD5933                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7091R                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7091R5                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7091R8                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7124                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7150                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7192                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7266                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7280                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7291                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7292                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7293                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7298                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7303                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD74115                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD74413R                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7476                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7606                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7606_IFACE_PARALLEL                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7606_IFACE_SPI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7746                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7766                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7768_1                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7780                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7791                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7793                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7816                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7887                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7923                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD7949                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD799X                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD8366                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD8801                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD9467                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD9523                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD9832                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD9834                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADA4250                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADAPTEC_STARFIRE                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ADF4350                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADF4371                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADF4377                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADFS_FS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ADFS_FS_RW                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ADIN1100_PHY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ADIN1110                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADIN_PHY                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ADIS16080                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADIS16130                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADIS16136                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADIS16201                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADIS16203                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADIS16209                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADIS16240                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADIS16260                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADIS16400                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADIS16460                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADIS16475                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADIS16480                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADI_AXI_ADC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADJD_S311                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADM8211                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADMV1013                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADMV1014                                 policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADMV4420                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADMV8818                                 policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADRF6780                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADT7316                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADT7316_I2C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADT7316_SPI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADUX1020                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADVANTECH_EC_WDT                         policy<{'amd64': 'm'}>
+CONFIG_ADVANTECH_WDT                            policy<{'amd64': 'm'}>
+CONFIG_ADVISE_SYSCALLS                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ADV_SWBUTTON                             policy<{'amd64': 'm'}>
+CONFIG_ADXL313                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADXL313_I2C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADXL313_SPI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADXL355                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADXL355_I2C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADXL355_SPI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADXL367                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADXL367_I2C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADXL367_SPI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADXL372                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADXL372_I2C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADXL372_SPI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADXRS290                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ADXRS450                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AD_SIGMA_DELTA                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AEABI                                    policy<{'armhf': 'y'}>
+CONFIG_AFE4403                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AFE4404                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AFFS_FS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_AFIUCV                                   policy<{'s390x': 'm'}>
+CONFIG_AFS_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_AFS_DEBUG_CURSOR                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_AFS_FS                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_AFS_FSCACHE                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_AF_KCM                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_AF_RXRPC                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_AF_RXRPC_DEBUG                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_AF_RXRPC_INJECT_LOSS                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_AF_RXRPC_INJECT_RX_DELAY                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_AF_RXRPC_IPV6                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_AF_UNIX_OOB                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_AGP_AMD64                                policy<{'amd64': 'y'}>
+CONFIG_AGP_INTEL                                policy<{'amd64': 'y'}>
+CONFIG_AGP_SIS                                  policy<{'amd64': 'm'}>
+CONFIG_AGP_VIA                                  policy<{'amd64': 'y'}>
+CONFIG_AHCI_CEVA                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AHCI_DM816                               policy<{'armhf': 'm'}>
+CONFIG_AHCI_DWC                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AHCI_IMX                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_AHCI_MTK                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_AHCI_MVEBU                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_AHCI_QORIQ                               policy<{'arm64': 'm', 'armhf': '-', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_AHCI_SUNXI                               policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_AHCI_TEGRA                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_AHCI_XGENE                               policy<{'arm64': 'm'}>
+CONFIG_AIC79XX_CMDS_PER_DEVICE                  policy<{'amd64': '32', 'arm64': '32', 'armhf': '32', 'ppc64el': '32', 'riscv64': '32'}>
+CONFIG_AIC79XX_DEBUG_ENABLE                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_AIC79XX_DEBUG_MASK                       policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0'}>
+CONFIG_AIC79XX_REG_PRETTY_PRINT                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_AIC79XX_RESET_DELAY_MS                   policy<{'amd64': '5000', 'arm64': '5000', 'armhf': '5000', 'ppc64el': '5000', 'riscv64': '5000'}>
+CONFIG_AIC7XXX_CMDS_PER_DEVICE                  policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'ppc64el': '8', 'riscv64': '8'}>
+CONFIG_AIC7XXX_DEBUG_ENABLE                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_AIC7XXX_DEBUG_MASK                       policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0'}>
+CONFIG_AIC7XXX_REG_PRETTY_PRINT                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_AIC7XXX_RESET_DELAY_MS                   policy<{'amd64': '5000', 'arm64': '5000', 'armhf': '5000', 'ppc64el': '5000', 'riscv64': '5000'}>
+CONFIG_AIC94XX_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_AIO                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_AIX_PARTITION                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_AK09911                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AK8974                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AK8975                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AL3010                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AL3320A                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ALIBABA_ENI_VDPA                         policy<{'amd64': 'm'}>
+CONFIG_ALIBABA_UNCORE_DRW_PMU                   policy<{'arm64': 'm'}>
+CONFIG_ALIENWARE_WMI                            policy<{'amd64': 'm'}>
+CONFIG_ALIGNMENT_TRAP                           policy<{'armhf': 'y'}>
+CONFIG_ALIM1535_WDT                             policy<{'amd64': 'm'}>
+CONFIG_ALIM7101_WDT                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ALLOW_DEV_COREDUMP                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ALTERA_FREEZE_BRIDGE                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ALTERA_MBOX                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ALTERA_MSGDMA                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ALTERA_PR_IP_CORE                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ALTERA_PR_IP_CORE_PLAT                   policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ALTERA_STAPL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ALTERA_TSE                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ALTERNATE_USER_ADDRESS_SPACE             policy<{'s390x': 'y'}>
+CONFIG_ALTIVEC                                  policy<{'ppc64el': 'y'}>
+CONFIG_ALX                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_AL_FIC                                   policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_AM2315                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AM335X_CONTROL_USB                       policy<{'armhf': 'm'}>
+CONFIG_AM335X_PHY_USB                           policy<{'armhf': 'm'}>
+CONFIG_AMBA_PL08X                               policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_AMD8111_ETH                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_AMDTEE                                   policy<{'amd64': 'm'}>
+CONFIG_AMD_HSMP                                 policy<{'amd64': 'm'}>
+CONFIG_AMD_IOMMU                                policy<{'amd64': 'y'}>
+CONFIG_AMD_MEM_ENCRYPT                          policy<{'amd64': 'y'}>
+CONFIG_AMD_NB                                   policy<{'amd64': 'y'}>
+CONFIG_AMD_NUMA                                 policy<{'amd64': 'y'}>
+CONFIG_AMD_PHY                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_AMD_PMC                                  policy<{'amd64': 'm'}>
+CONFIG_AMD_PMF                                  policy<{'amd64': 'm'}>
+CONFIG_AMD_PMF_DEBUG                            policy<{'amd64': 'y'}>
+CONFIG_AMD_PTDMA                                policy<{'amd64': 'm'}>
+CONFIG_AMD_SFH_HID                              policy<{'amd64': 'm'}>
+CONFIG_AMD_WBRF                                 policy<{'amd64': 'y'}>
+CONFIG_AMD_XGBE                                 policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_AMD_XGBE_DCB                             policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_AMD_XGBE_HAVE_ECC                        policy<{'amd64': 'y'}>
+CONFIG_AMIGA_PARTITION                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_AMILO_RFKILL                             policy<{'amd64': 'm'}>
+CONFIG_AMLOGIC_THERMAL                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_AMPERE_CORESIGHT_PMU_ARCH_SYSTEM_PMU     policy<{'arm64': 'm'}>
+CONFIG_AMPERE_ERRATUM_AC03_CPU_38               policy<{'arm64': 'y'}>
+CONFIG_AMT                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ANDROID_BINDERFS                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ANDROID_BINDER_DEVICES                   policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'ppc64el': '""', 'riscv64': '""'}>
+CONFIG_ANDROID_BINDER_IPC                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ANDROID_BINDER_IPC_SELFTEST              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ANON_VMA_NAME                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_AOSONG_AGS02MA                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_APDS9300                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_APDS9802ALS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_APDS9960                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_APERTURE_HELPERS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_APM_EMULATION                            policy<{'armhf': 'n'}>
+CONFIG_APPLDATA_BASE                            policy<{'s390x': 'y'}>
+CONFIG_APPLDATA_MEM                             policy<{'s390x': 'm'}>
+CONFIG_APPLDATA_NET_SUM                         policy<{'s390x': 'm'}>
+CONFIG_APPLDATA_OS                              policy<{'s390x': 'm'}>
+CONFIG_APPLE_ADMAC                              policy<{'arm64': 'm'}>
+CONFIG_APPLE_AIC                                policy<{'arm64': 'y'}>
+CONFIG_APPLE_DART                               policy<{'arm64': 'm'}>
+CONFIG_APPLE_GMUX                               policy<{'amd64': 'm'}>
+CONFIG_APPLE_M1_CPU_PMU                         policy<{'arm64': 'y'}>
+CONFIG_APPLE_MAILBOX                            policy<{'arm64': 'm'}>
+CONFIG_APPLE_MFI_FASTCHARGE                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_APPLE_PMGR_PWRSTATE                      policy<{'arm64': 'y'}>
+CONFIG_APPLE_PROPERTIES                         policy<{'amd64': 'y'}>
+CONFIG_APPLE_RTKIT                              policy<{'arm64': 'm'}>
+CONFIG_APPLE_SART                               policy<{'arm64': 'm'}>
+CONFIG_APPLE_WATCHDOG                           policy<{'arm64': 'm'}>
+CONFIG_APPLICOM                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_APQ_GCC_8084                             policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_APQ_MMCC_8084                            policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_AQTION                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_AQUANTIA_PHY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_AR5523                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ARCH_32BIT_OFF_T                         policy<{'armhf': 'y'}>
+CONFIG_ARCH_32BIT_USTAT_F_TINODE                policy<{'s390x': 'y'}>
+CONFIG_ARCH_ACTIONS                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_AIROHA                              policy<{'armhf': 'y'}>
+CONFIG_ARCH_ALPINE                              policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_ARCH_APPLE                               policy<{'arm64': 'y'}>
+CONFIG_ARCH_ARTPEC                              policy<{'armhf': 'y'}>
+CONFIG_ARCH_ASPEED                              policy<{'armhf': 'y'}>
+CONFIG_ARCH_AT91                                policy<{'armhf': 'n'}>
+CONFIG_ARCH_AXXIA                               policy<{'armhf': 'y'}>
+CONFIG_ARCH_BCM                                 policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_ARCH_BERLIN                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS              policy<{'arm64': 'y'}>
+CONFIG_ARCH_BINFMT_ELF_STATE                    policy<{'arm64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_BITMAIN                             policy<{'arm64': 'y'}>
+CONFIG_ARCH_CLOCKSOURCE_INIT                    policy<{'amd64': 'y', 'riscv64': '-'}>
+CONFIG_ARCH_CONFIGURES_CPU_MITIGATIONS          policy<{'amd64': 'y'}>
+CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 's390x': 'y'}>
+CONFIG_ARCH_CPUIDLE_HALTPOLL                    policy<{'amd64': 'y'}>
+CONFIG_ARCH_CPU_PROBE_RELEASE                   policy<{'ppc64el': 'y'}>
+CONFIG_ARCH_DEFAULT_KEXEC_IMAGE_VERIFY_SIG      policy<{'arm64': 'y'}>
+CONFIG_ARCH_DIGICOLOR                           policy<{'armhf': 'n'}>
+CONFIG_ARCH_DISABLE_KASAN_INLINE                policy<{'ppc64el': 'y'}>
+CONFIG_ARCH_DMA_ADDR_T_64BIT                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_DMA_DEFAULT_COHERENT                policy<{'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_DOVE                                policy<{'armhf': 'n'}>
+CONFIG_ARCH_EMEV2                               policy<{'armhf': 'y'}>
+CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION           policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG               policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE             policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK             policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_ENABLE_THP_MIGRATION                policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_EXYNOS                              policy<{'arm64': 'n', 'armhf': 'y'}>
+CONFIG_ARCH_EXYNOS3                             policy<{'armhf': 'n'}>
+CONFIG_ARCH_EXYNOS4                             policy<{'armhf': 'n'}>
+CONFIG_ARCH_EXYNOS5                             policy<{'armhf': 'n'}>
+CONFIG_ARCH_FLATMEM_ENABLE                      policy<{'armhf': 'y'}>
+CONFIG_ARCH_FORCE_MAX_ORDER                     policy<{'arm64': '13', 'armhf': '11', 'ppc64el': '8'}>
+CONFIG_ARCH_HAS_ACPI_TABLE_UPGRADE              policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ARCH_HAS_ADD_PAGES                       policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_ARCH_HAS_BANDGAP                         policy<{'armhf': 'y'}>
+CONFIG_ARCH_HAS_BINFMT_FLAT                     policy<{'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_HAS_CACHE_LINE_SIZE                 policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ARCH_HAS_CC_PLATFORM                     policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_ARCH_HAS_COPY_MC                         policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_ARCH_HAS_CPU_CACHE_INVALIDATE_MEMREGION  policy<{'amd64': 'y'}>
+CONFIG_ARCH_HAS_CPU_FINALIZE_INIT               policy<{'amd64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_HAS_CPU_PASID                       policy<{'amd64': 'y'}>
+CONFIG_ARCH_HAS_CPU_RELAX                       policy<{'amd64': 'y'}>
+CONFIG_ARCH_HAS_CURRENT_STACK_POINTER           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_DEBUG_VIRTUAL                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE                policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_DEBUG_WX                        policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED               policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_DMA_ALLOC                       policy<{'armhf': 'y'}>
+CONFIG_ARCH_HAS_DMA_MAP_DIRECT                  policy<{'ppc64el': 'y'}>
+CONFIG_ARCH_HAS_DMA_PREP_COHERENT               policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_HAS_EARLY_DEBUG                     policy<{'amd64': 'y'}>
+CONFIG_ARCH_HAS_ELFCORE_COMPAT                  policy<{'amd64': 'y'}>
+CONFIG_ARCH_HAS_ELF_RANDOMIZE                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_FAST_MULTIPLIER                 policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED           policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_FORTIFY_SOURCE                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_HAS_GIGANTIC_PAGE                   policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_HUGEPD                          policy<{'ppc64el': 'y'}>
+CONFIG_ARCH_HAS_HW_PTE_YOUNG                    policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ARCH_HAS_KCOV                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_KEEPINITRD                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_HAS_MEMBARRIER_CALLBACKS            policy<{'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_MEMREMAP_COMPAT_ALIGN           policy<{'ppc64el': 'y'}>
+CONFIG_ARCH_HAS_MEM_ENCRYPT                     policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_MMIOWB                          policy<{'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_HAS_NMI_SAFE_THIS_CPU_OPS           policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG               policy<{'amd64': 'y'}>
+CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_HAS_PARANOID_L1D_FLUSH              policy<{'amd64': 'y'}>
+CONFIG_ARCH_HAS_PHYS_TO_DMA                     policy<{'ppc64el': 'y'}>
+CONFIG_ARCH_HAS_PKEYS                           policy<{'amd64': 'y'}>
+CONFIG_ARCH_HAS_PMEM_API                        policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_HAS_PTE_DEVMAP                      policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_ARCH_HAS_PTE_SPECIAL                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_RELR                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_HAS_RESET_CONTROLLER                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_HAS_SCALED_CPUTIME                  policy<{'s390x': 'y'}>
+CONFIG_ARCH_HAS_SETUP_DMA_OPS                   policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_HAS_SET_DIRECT_MAP                  policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_SET_MEMORY                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_STRICT_KERNEL_RWX               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_STRICT_MODULE_RWX               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_SUBPAGE_FAULTS                  policy<{'arm64': 'y'}>
+CONFIG_ARCH_HAS_SYNC_CORE_BEFORE_USERMODE       policy<{'amd64': 'y'}>
+CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU                policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE             policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_HAS_SYSCALL_WRAPPER                 policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_TEARDOWN_DMA_OPS                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_HAS_TICK_BROADCAST                  policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE              policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_ARCH_HAS_UBSAN                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_VDSO_DATA                       policy<{'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAS_ZONE_DMA_SET                    policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ARCH_HAVE_ELF_PROT                       policy<{'arm64': 'y'}>
+CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_ARCH_HAVE_TRACE_MMIO_ACCESS              policy<{'arm64': 'y'}>
+CONFIG_ARCH_HI3xxx                              policy<{'armhf': 'y'}>
+CONFIG_ARCH_HIBERNATION_HEADER                  policy<{'amd64': 'y', 'riscv64': '-'}>
+CONFIG_ARCH_HIBERNATION_POSSIBLE                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-'}>
+CONFIG_ARCH_HIGHBANK                            policy<{'armhf': 'y'}>
+CONFIG_ARCH_HIP01                               policy<{'armhf': 'n'}>
+CONFIG_ARCH_HIP04                               policy<{'armhf': 'y'}>
+CONFIG_ARCH_HISI                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_HIX5HD2                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_HPE                                 policy<{'armhf': 'y'}>
+CONFIG_ARCH_HPE_GXP                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_INLINE_READ_LOCK                    policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_READ_LOCK_BH                 policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_READ_LOCK_IRQ                policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_READ_LOCK_IRQSAVE            policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_READ_TRYLOCK                 policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_READ_UNLOCK                  policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_READ_UNLOCK_BH               policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQ              policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_READ_UNLOCK_IRQRESTORE       policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_SPIN_LOCK                    policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_SPIN_LOCK_BH                 policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQ                policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_SPIN_LOCK_IRQSAVE            policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK                 policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_SPIN_TRYLOCK_BH              policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_SPIN_UNLOCK                  policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_BH               policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQ              policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE       policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_WRITE_LOCK                   policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_WRITE_LOCK_BH                policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQ               policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_WRITE_LOCK_IRQSAVE           policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_WRITE_TRYLOCK                policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_WRITE_UNLOCK                 policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_BH              policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQ             policy<{'s390x': 'y'}>
+CONFIG_ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE      policy<{'s390x': 'y'}>
+CONFIG_ARCH_INTEL_SOCFPGA                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_IPQ40XX                             policy<{'armhf': 'n'}>
+CONFIG_ARCH_K3                                  policy<{'arm64': 'y'}>
+CONFIG_ARCH_KEEMBAY                             policy<{'arm64': 'y'}>
+CONFIG_ARCH_KEEP_MEMBLOCK                       policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_KEYSTONE                            policy<{'armhf': 'n'}>
+CONFIG_ARCH_LAYERSCAPE                          policy<{'arm64': 'y'}>
+CONFIG_ARCH_LG1K                                policy<{'arm64': 'y'}>
+CONFIG_ARCH_MA35                                policy<{'arm64': 'y'}>
+CONFIG_ARCH_MAY_HAVE_PC_FDC                     policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_ARCH_MDM9615                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_MEDIATEK                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_MEMORY_PROBE                        policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_ARCH_MESON                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_MICROCHIP_POLARFIRE                 policy<{'riscv64': 'y'}>
+CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC                 policy<{'amd64': 'y'}>
+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT               policy<{'amd64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_ARCH_MIGHT_HAVE_PC_SERIO                 policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_ARCH_MILBEAUT                            policy<{'armhf': 'y'}>
+CONFIG_ARCH_MILBEAUT_M10V                       policy<{'armhf': 'y'}>
+CONFIG_ARCH_MMAP_RND_BITS_MAX                   policy<{'amd64': '32', 'arm64': '33', 'arm64-generic-64k': '29', 'armhf': '16', 'ppc64el': '29', 'riscv64': '24'}>
+CONFIG_ARCH_MMAP_RND_BITS_MIN                   policy<{'amd64': '28', 'arm64': '18', 'arm64-generic-64k': '14', 'armhf': '8', 'ppc64el': '14', 'riscv64': '18'}>
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX            policy<{'amd64': '16', 'arm64': '16', 'ppc64el': '13', 'riscv64': '17'}>
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN            policy<{'amd64': '8', 'arm64': '11', 'arm64-generic-64k': '7', 'ppc64el': '7', 'riscv64': '8'}>
+CONFIG_ARCH_MMP                                 policy<{'armhf': 'n'}>
+CONFIG_ARCH_MSM8909                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_MSM8916                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_MSM8960                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_MSM8974                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_MSM8X60                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_MSTARV7                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_MULTIPLATFORM                       policy<{'armhf': 'y'}>
+CONFIG_ARCH_MULTI_V6                            policy<{'armhf': 'n'}>
+CONFIG_ARCH_MULTI_V6_V7                         policy<{'armhf': 'y'}>
+CONFIG_ARCH_MULTI_V7                            policy<{'armhf': 'y'}>
+CONFIG_ARCH_MVEBU                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_MXC                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED              policy<{'armhf': 'y'}>
+CONFIG_ARCH_NPCM                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_NPCM7XX                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_NXP                                 policy<{'arm64': 'y'}>
+CONFIG_ARCH_OMAP                                policy<{'armhf': 'y'}>
+CONFIG_ARCH_OMAP2PLUS                           policy<{'armhf': 'y'}>
+CONFIG_ARCH_OMAP2PLUS_TYPICAL                   policy<{'armhf': 'y'}>
+CONFIG_ARCH_OMAP3                               policy<{'armhf': 'n'}>
+CONFIG_ARCH_OMAP4                               policy<{'armhf': 'n'}>
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX                 policy<{'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT         policy<{'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_PENSANDO                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_PROC_KCORE_TEXT                     policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_QCOM                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_R7S72100                            policy<{'armhf': 'y'}>
+CONFIG_ARCH_R7S9210                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_R8A73A4                             policy<{'armhf': 'n'}>
+CONFIG_ARCH_R8A7740                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_R8A7742                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_R8A7743                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_R8A7744                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_R8A7745                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_R8A77470                            policy<{'armhf': 'y'}>
+CONFIG_ARCH_R8A774A1                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R8A774B1                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R8A774C0                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R8A774E1                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R8A7778                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_R8A7779                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_R8A7790                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_R8A7791                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_R8A7792                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_R8A7793                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_R8A7794                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_R8A77951                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R8A77960                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R8A77961                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R8A77965                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R8A77970                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R8A77980                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R8A77990                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R8A77995                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R8A779A0                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R8A779F0                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R8A779G0                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_R9A06G032                           policy<{'armhf': 'y'}>
+CONFIG_ARCH_R9A07G043                           policy<{'arm64': 'y', 'riscv64': '-'}>
+CONFIG_ARCH_R9A07G044                           policy<{'arm64': 'y'}>
+CONFIG_ARCH_R9A07G054                           policy<{'arm64': 'y'}>
+CONFIG_ARCH_R9A08G045                           policy<{'arm64': 'y'}>
+CONFIG_ARCH_R9A09G011                           policy<{'arm64': 'y'}>
+CONFIG_ARCH_RCAR_GEN1                           policy<{'armhf': 'y'}>
+CONFIG_ARCH_RCAR_GEN2                           policy<{'armhf': 'y'}>
+CONFIG_ARCH_RCAR_GEN3                           policy<{'arm64': 'y'}>
+CONFIG_ARCH_RDA                                 policy<{'armhf': 'y'}>
+CONFIG_ARCH_REALTEK                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_REALVIEW                            policy<{'armhf': 'n'}>
+CONFIG_ARCH_RENESAS                             policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_RMOBILE                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_RV64I                               policy<{'riscv64': 'y'}>
+CONFIG_ARCH_RZG2L                               policy<{'arm64': 'y', 'riscv64': '-'}>
+CONFIG_ARCH_RZN1                                policy<{'armhf': 'y'}>
+CONFIG_ARCH_S32                                 policy<{'arm64': 'y'}>
+CONFIG_ARCH_S5PV210                             policy<{'armhf': 'n'}>
+CONFIG_ARCH_SEATTLE                             policy<{'arm64': 'y'}>
+CONFIG_ARCH_SELECTS_CRASH_DUMP                  policy<{'ppc64el': 'y'}>
+CONFIG_ARCH_SELECTS_KEXEC                       policy<{'riscv64': 'y'}>
+CONFIG_ARCH_SELECTS_KEXEC_FILE                  policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_SELECT_MEMORY_MODEL                 policy<{'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_SH73A0                              policy<{'armhf': 'y'}>
+CONFIG_ARCH_SIFIVE                              policy<{'riscv64': 'y'}>
+CONFIG_ARCH_SOPHGO                              policy<{'riscv64': 'y'}>
+CONFIG_ARCH_SPARSEMEM_DEFAULT                   policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_ARCH_SPARSEMEM_ENABLE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_SPARX5                              policy<{'arm64': 'y'}>
+CONFIG_ARCH_SPRD                                policy<{'arm64': 'y'}>
+CONFIG_ARCH_STACKWALK                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_STARFIVE                            policy<{'riscv64': 'y'}>
+CONFIG_ARCH_STI                                 policy<{'armhf': 'n'}>
+CONFIG_ARCH_STM32                               policy<{'arm64': 'y', 'armhf': 'n'}>
+CONFIG_ARCH_SUNPLUS                             policy<{'armhf': 'y'}>
+CONFIG_ARCH_SUNXI                               policy<{'arm64': 'y', 'armhf': 'n', 'riscv64': 'y'}>
+CONFIG_ARCH_SUPPORTS_ACPI                       policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_SUPPORTS_CFI_CLANG                  policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_SUPPORTS_CRASH_DUMP                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_SUPPORTS_CRASH_HOTPLUG              policy<{'amd64': 'y'}>
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC            policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_SUPPORTS_HUGETLBFS                  policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_SUPPORTS_INT128                     policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_SUPPORTS_KEXEC                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_SUPPORTS_KEXEC_BZIMAGE_VERIFY_SIG   policy<{'amd64': 'y'}>
+CONFIG_ARCH_SUPPORTS_KEXEC_FILE                 policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_SUPPORTS_KEXEC_IMAGE_VERIFY_SIG     policy<{'arm64': 'y'}>
+CONFIG_ARCH_SUPPORTS_KEXEC_JUMP                 policy<{'amd64': 'y'}>
+CONFIG_ARCH_SUPPORTS_KEXEC_PURGATORY            policy<{'amd64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_SUPPORTS_KEXEC_SIG                  policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_SUPPORTS_KEXEC_SIG_FORCE            policy<{'amd64': 'y'}>
+CONFIG_ARCH_SUPPORTS_LTO_CLANG                  policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ARCH_SUPPORTS_LTO_CLANG_THIN             policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE             policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_ARCH_SUPPORTS_NUMA_BALANCING             policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_SUPPORTS_PAGE_TABLE_CHECK           policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_SUPPORTS_PER_VMA_LOCK               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_SUPPORTS_SHADOW_CALL_STACK          policy<{'arm64': 'y'}>
+CONFIG_ARCH_SUPPORTS_UPROBES                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_SUSPEND_NONZERO_CPU                 policy<{'ppc64el': 'y'}>
+CONFIG_ARCH_SUSPEND_POSSIBLE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_SYNQUACER                           policy<{'arm64': 'y'}>
+CONFIG_ARCH_TEGRA                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_TEGRA_114_SOC                       policy<{'armhf': 'y'}>
+CONFIG_ARCH_TEGRA_124_SOC                       policy<{'armhf': 'y'}>
+CONFIG_ARCH_TEGRA_132_SOC                       policy<{'arm64': 'y'}>
+CONFIG_ARCH_TEGRA_186_SOC                       policy<{'arm64': 'y'}>
+CONFIG_ARCH_TEGRA_194_SOC                       policy<{'arm64': 'y'}>
+CONFIG_ARCH_TEGRA_210_SOC                       policy<{'arm64': 'y'}>
+CONFIG_ARCH_TEGRA_234_SOC                       policy<{'arm64': 'y'}>
+CONFIG_ARCH_TEGRA_2x_SOC                        policy<{'armhf': 'y'}>
+CONFIG_ARCH_TEGRA_3x_SOC                        policy<{'armhf': 'y'}>
+CONFIG_ARCH_THEAD                               policy<{'riscv64': 'y'}>
+CONFIG_ARCH_THUNDER                             policy<{'arm64': 'y'}>
+CONFIG_ARCH_THUNDER2                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_U8500                               policy<{'armhf': 'n'}>
+CONFIG_ARCH_UNIPHIER                            policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_ARCH_USES_HIGH_VMA_FLAGS                 policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ARCH_USES_PG_ARCH_X                      policy<{'arm64': 'y'}>
+CONFIG_ARCH_USES_PG_UNCACHED                    policy<{'amd64': 'y'}>
+CONFIG_ARCH_USE_BUILTIN_BSWAP                   policy<{'amd64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_ARCH_USE_CMPXCHG_LOCKREF                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_ARCH_USE_GNU_PROPERTY                    policy<{'arm64': 'y'}>
+CONFIG_ARCH_USE_MEMREMAP_PROT                   policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_USE_MEMTEST                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_USE_QUEUED_RWLOCKS                  policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_USE_QUEUED_SPINLOCKS                policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_ARCH_USE_SYM_ANNOTATIONS                 policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY      policy<{'ppc64el': 'y'}>
+CONFIG_ARCH_VEXPRESS                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA        policy<{'armhf': 'y'}>
+CONFIG_ARCH_VEXPRESS_DCSCB                      policy<{'armhf': 'y'}>
+CONFIG_ARCH_VEXPRESS_SPC                        policy<{'armhf': 'y'}>
+CONFIG_ARCH_VEXPRESS_TC2_PM                     policy<{'armhf': 'y'}>
+CONFIG_ARCH_VIRT                                policy<{'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_VISCONTI                            policy<{'arm64': 'y'}>
+CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT           policy<{'amd64': 'y', 's390x': '-'}>
+CONFIG_ARCH_WANTS_NO_INSTR                      policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_WANTS_THP_SWAP                      policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': '-', 'riscv64': 'y'}>
+CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH        policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION       policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': '-', 'ppc64el': '-', 's390x': '-'}>
+CONFIG_ARCH_WANT_DEFAULT_BPF_JIT                policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT    policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_WANT_FLAT_DTB_INSTALL               policy<{'armhf': 'y'}>
+CONFIG_ARCH_WANT_FRAME_POINTERS                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_WANT_GENERAL_HUGETLB                policy<{'amd64': 'y', 'armhf': 'y', 'riscv64': '-'}>
+CONFIG_ARCH_WANT_HUGE_PMD_SHARE                 policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': '-', 'riscv64': 'y'}>
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION              policy<{'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM           policy<{'ppc64el': 'y'}>
+CONFIG_ARCH_WANT_KERNEL_PMD_MKWRITE             policy<{'s390x': 'y'}>
+CONFIG_ARCH_WANT_LD_ORPHAN_WARN                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ARCH_WANT_OLD_COMPAT_IPC                 policy<{'amd64': 'y', 'ppc64el': '-', 's390x': '-'}>
+CONFIG_ARCH_WANT_OPTIMIZE_DAX_VMEMMAP           policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP       policy<{'amd64': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_WANT_PMD_MKWRITE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ARCH_WEAK_RELEASE_ACQUIRE                policy<{'ppc64el': 'y'}>
+CONFIG_ARCH_WM8850                              policy<{'armhf': 'n'}>
+CONFIG_ARCH_XGENE                               policy<{'arm64': 'y'}>
+CONFIG_ARCH_ZYNQ                                policy<{'armhf': 'n'}>
+CONFIG_ARCH_ZYNQMP                              policy<{'arm64': 'y'}>
+CONFIG_ARCNET                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ARCNET_1051                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ARCNET_1201                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ARCNET_CAP                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ARCNET_COM20020                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ARCNET_COM20020_CS                       policy<{'amd64': 'm'}>
+CONFIG_ARCNET_COM20020_PCI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ARCNET_COM90xx                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ARCNET_COM90xxIO                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ARCNET_RAW                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ARCNET_RIM_I                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ARCX_ANYBUS_CONTROLLER                   policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ARC_EMAC_CORE                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM                                      policy<{'armhf': 'y'}>
+CONFIG_ARM64                                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_16K_PAGES                          policy<{'arm64': 'n'}>
+CONFIG_ARM64_4K_PAGES                           policy<{'arm64': 'y', 'arm64-generic-64k': 'n'}>
+CONFIG_ARM64_64K_PAGES                          policy<{'arm64': 'n', 'arm64-generic-64k': 'y'}>
+CONFIG_ARM64_ACPI_PARKING_PROTOCOL              policy<{'arm64': 'y'}>
+CONFIG_ARM64_AMU_EXTN                           policy<{'arm64': 'y'}>
+CONFIG_ARM64_AS_HAS_MTE                         policy<{'arm64': 'y'}>
+CONFIG_ARM64_BTI                                policy<{'arm64': 'y'}>
+CONFIG_ARM64_CNP                                policy<{'arm64': 'y'}>
+CONFIG_ARM64_CONT_PMD_SHIFT                     policy<{'arm64': '4', 'arm64-generic-64k': '5'}>
+CONFIG_ARM64_CONT_PTE_SHIFT                     policy<{'arm64': '4', 'arm64-generic-64k': '5'}>
+CONFIG_ARM64_DEBUG_PRIORITY_MASKING             policy<{'arm64': 'n'}>
+CONFIG_ARM64_E0PD                               policy<{'arm64': 'y'}>
+CONFIG_ARM64_EPAN                               policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_1024718                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_1165522                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_1286807                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_1319367                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_1418040                    policy<{'arm64': 'y', 'arm64-generic-64k': '-'}>
+CONFIG_ARM64_ERRATUM_1463225                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_1508412                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_1530923                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_1542419                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_1742098                    policy<{'arm64': 'y', 'arm64-generic-64k': '-'}>
+CONFIG_ARM64_ERRATUM_2051678                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_2054223                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_2067961                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_2077057                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_2441007                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_2441009                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_2457168                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_2645198                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_2658417                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_2966298                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_3117295                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_3194386                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_819472                     policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_824069                     policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_826319                     policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_827319                     policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_832075                     policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_834220                     policy<{'arm64': 'y'}>
+CONFIG_ARM64_ERRATUM_845719                     policy<{'arm64': 'y', 'arm64-generic-64k': '-'}>
+CONFIG_ARM64_HW_AFDBM                           policy<{'arm64': 'y'}>
+CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419          policy<{'arm64': 'y'}>
+CONFIG_ARM64_LSE_ATOMICS                        policy<{'arm64': 'y'}>
+CONFIG_ARM64_MTE                                policy<{'arm64': 'y'}>
+CONFIG_ARM64_PAGE_SHIFT                         policy<{'arm64': '12', 'arm64-generic-64k': '16'}>
+CONFIG_ARM64_PAN                                policy<{'arm64': 'y'}>
+CONFIG_ARM64_PA_BITS                            policy<{'arm64': '48'}>
+CONFIG_ARM64_PA_BITS_48                         policy<{'arm64': 'y'}>
+CONFIG_ARM64_PA_BITS_52                         policy<{'arm64-generic-64k': 'n'}>
+CONFIG_ARM64_PMEM                               policy<{'arm64': 'y'}>
+CONFIG_ARM64_PSEUDO_NMI                         policy<{'arm64': 'y'}>
+CONFIG_ARM64_PTR_AUTH                           policy<{'arm64': 'y'}>
+CONFIG_ARM64_PTR_AUTH_KERNEL                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_RAS_EXTN                           policy<{'arm64': 'y'}>
+CONFIG_ARM64_RELOC_TEST                         policy<{'arm64': 'n'}>
+CONFIG_ARM64_SVE                                policy<{'arm64': 'y'}>
+CONFIG_ARM64_SW_TTBR0_PAN                       policy<{'arm64': 'y'}>
+CONFIG_ARM64_TAGGED_ADDR_ABI                    policy<{'arm64': 'y'}>
+CONFIG_ARM64_TLB_RANGE                          policy<{'arm64': 'y'}>
+CONFIG_ARM64_VA_BITS                            policy<{'arm64': '48'}>
+CONFIG_ARM64_VA_BITS_39                         policy<{'arm64': 'n', 'arm64-generic-64k': '-'}>
+CONFIG_ARM64_VA_BITS_42                         policy<{'arm64-generic-64k': 'n'}>
+CONFIG_ARM64_VA_BITS_52                         policy<{'arm64-generic-64k': 'n'}>
+CONFIG_ARM64_WORKAROUND_CLEAN_CACHE             policy<{'arm64': 'y'}>
+CONFIG_ARM64_WORKAROUND_REPEAT_TLBI             policy<{'arm64': 'y'}>
+CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT          policy<{'arm64': 'y'}>
+CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD policy<{'arm64': 'y'}>
+CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE       policy<{'arm64': 'y'}>
+CONFIG_ARMADA375_USBCLUSTER_PHY                 policy<{'armhf': 'y'}>
+CONFIG_ARMADA_370_CLK                           policy<{'armhf': 'y'}>
+CONFIG_ARMADA_370_XP_IRQ                        policy<{'armhf': 'y'}>
+CONFIG_ARMADA_370_XP_TIMER                      policy<{'armhf': 'y'}>
+CONFIG_ARMADA_375_CLK                           policy<{'armhf': 'y'}>
+CONFIG_ARMADA_37XX_CLK                          policy<{'arm64': 'y'}>
+CONFIG_ARMADA_37XX_RWTM_MBOX                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARMADA_37XX_WATCHDOG                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARMADA_38X_CLK                           policy<{'armhf': 'y'}>
+CONFIG_ARMADA_39X_CLK                           policy<{'armhf': 'y'}>
+CONFIG_ARMADA_AP806_SYSCON                      policy<{'arm64': 'y'}>
+CONFIG_ARMADA_AP_CPU_CLK                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARMADA_AP_CP_HELPER                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARMADA_CP110_SYSCON                      policy<{'arm64': 'y'}>
+CONFIG_ARMADA_THERMAL                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARMADA_XP_CLK                            policy<{'armhf': 'y'}>
+CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM       policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_ARM_AMBA                                 policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_ARM_APPENDED_DTB                         policy<{'armhf': 'y'}>
+CONFIG_ARM_APPLE_SOC_CPUFREQ                    policy<{'arm64': 'm'}>
+CONFIG_ARM_ARCH_TIMER                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_ARCH_TIMER_EVTSTREAM                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND            policy<{'arm64': 'y'}>
+CONFIG_ARM_ARMADA_37XX_CPUFREQ                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_ARMADA_8K_CPUFREQ                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_ATAG_DTB_COMPAT                      policy<{'armhf': 'n'}>
+CONFIG_ARM_BIG_LITTLE_CPUIDLE                   policy<{'armhf': 'y'}>
+CONFIG_ARM_CCI                                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_CCI400_COMMON                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_CCI400_PMU                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_CCI400_PORT_CTRL                     policy<{'armhf': 'y'}>
+CONFIG_ARM_CCI5xx_PMU                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_CCI_PMU                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_CCN                                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_CHARLCD                              policy<{'armhf': 'y'}>
+CONFIG_ARM_CMN                                  policy<{'arm64': 'm'}>
+CONFIG_ARM_CORESIGHT_PMU_ARCH_SYSTEM_PMU        policy<{'arm64': 'm'}>
+CONFIG_ARM_CPUIDLE                              policy<{'armhf': 'y'}>
+CONFIG_ARM_CPU_SUSPEND                          policy<{'armhf': 'y'}>
+CONFIG_ARM_CPU_TOPOLOGY                         policy<{'armhf': 'y'}>
+CONFIG_ARM_DMA_IOMMU_ALIGNMENT                  policy<{'armhf': '8'}>
+CONFIG_ARM_DMA_MEM_BUFFERABLE                   policy<{'armhf': 'y'}>
+CONFIG_ARM_DMA_USE_IOMMU                        policy<{'armhf': 'y'}>
+CONFIG_ARM_DMC620_PMU                           policy<{'arm64': 'm'}>
+CONFIG_ARM_DSU_PMU                              policy<{'arm64': 'm'}>
+CONFIG_ARM_ERRATA_430973                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_643719                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_720789                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_754322                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_754327                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_764319                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_764369                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_773022                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_775420                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_798181                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_814220                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_818325_852422                 policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_821420                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_825619                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_852421                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_852423                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_857271                        policy<{'armhf': 'y'}>
+CONFIG_ARM_ERRATA_857272                        policy<{'armhf': 'y'}>
+CONFIG_ARM_EXYNOS_BUS_DEVFREQ                   policy<{'armhf': 'n'}>
+CONFIG_ARM_EXYNOS_CPUIDLE                       policy<{'armhf': 'n'}>
+CONFIG_ARM_FFA_SMCCC                            policy<{'arm64': 'y'}>
+CONFIG_ARM_FFA_TRANSPORT                        policy<{'arm64': 'm'}>
+CONFIG_ARM_GIC                                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_GIC_MAX_NR                           policy<{'arm64': '1', 'armhf': '1'}>
+CONFIG_ARM_GIC_PM                               policy<{'arm64': 'y'}>
+CONFIG_ARM_GIC_V2M                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_GIC_V3                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_GIC_V3_ITS                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_GIC_V3_ITS_FSL_MC                    policy<{'arm64': 'y'}>
+CONFIG_ARM_GIC_V3_ITS_PCI                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_GLOBAL_TIMER                         policy<{'armhf': 'y'}>
+CONFIG_ARM_GT_INITIAL_PRESCALER_VAL             policy<{'armhf': '1'}>
+CONFIG_ARM_HAS_GROUP_RELOCS                     policy<{'armhf': 'y'}>
+CONFIG_ARM_HEAVY_MB                             policy<{'armhf': 'y'}>
+CONFIG_ARM_HIGHBANK_CPUFREQ                     policy<{'armhf': 'm'}>
+CONFIG_ARM_IMX6Q_CPUFREQ                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_IMX8M_DDRC_DEVFREQ                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_IMX_BUS_DEVFREQ                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_IMX_CPUFREQ_DT                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_KPROBES_TEST                         policy<{'armhf': 'm'}>
+CONFIG_ARM_L1_CACHE_SHIFT                       policy<{'armhf': '6'}>
+CONFIG_ARM_L1_CACHE_SHIFT_6                     policy<{'armhf': 'y'}>
+CONFIG_ARM_LPAE                                 policy<{'armhf': 'y'}>
+CONFIG_ARM_MEDIATEK_CCI_DEVFREQ                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_MEDIATEK_CPUFREQ                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_MEDIATEK_CPUFREQ_HW                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_MHU                                  policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_ARM_MHU_V2                               policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_ARM_MODULE_PLTS                          policy<{'armhf': 'y'}>
+CONFIG_ARM_MVEBU_V7_CPUIDLE                     policy<{'armhf': 'y'}>
+CONFIG_ARM_OMAP2PLUS_CPUFREQ                    policy<{'armhf': 'y'}>
+CONFIG_ARM_PATCH_IDIV                           policy<{'armhf': 'y'}>
+CONFIG_ARM_PATCH_PHYS_VIRT                      policy<{'armhf': 'y'}>
+CONFIG_ARM_PL172_MPMC                           policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_ARM_PMU                                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_PMUV3                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_PMU_ACPI                             policy<{'arm64': 'y'}>
+CONFIG_ARM_PSCI                                 policy<{'armhf': 'y'}>
+CONFIG_ARM_PSCI_CHECKER                         policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_ARM_PSCI_CPUIDLE                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_PSCI_CPUIDLE_DOMAIN                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_PSCI_FW                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_PTDUMP_CORE                          policy<{'armhf': 'y'}>
+CONFIG_ARM_PTDUMP_DEBUGFS                       policy<{'armhf': 'n'}>
+CONFIG_ARM_QCOM_CPUFREQ_HW                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_QCOM_CPUFREQ_NVMEM                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_QCOM_SPM_CPUIDLE                     policy<{'armhf': 'y'}>
+CONFIG_ARM_RK3399_DMC_DEVFREQ                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_SBSA_WATCHDOG                        policy<{'arm64': 'm'}>
+CONFIG_ARM_SCMI_CPUFREQ                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_SCMI_HAVE_MSG                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_SCMI_HAVE_SHMEM                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_SCMI_HAVE_TRANSPORT                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_SCMI_NEED_DEBUGFS                    policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_SCMI_PERF_DOMAIN                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_SCMI_POWERCAP                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_SCMI_POWER_CONTROL                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_SCMI_POWER_DOMAIN                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_SCMI_PROTOCOL                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_SCMI_RAW_MODE_SUPPORT                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_SCMI_TRANSPORT_MAILBOX               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_SCMI_TRANSPORT_SMC                   policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_SCMI_TRANSPORT_VIRTIO                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_ENABLE  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_SCPI_CPUFREQ                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_SCPI_POWER_DOMAIN                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_SCPI_PROTOCOL                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_SDE_INTERFACE                        policy<{'arm64': 'y'}>
+CONFIG_ARM_SMCCC_SOC_ID                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_SMC_WATCHDOG                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_SMMU                                 policy<{'arm64': 'y', 'armhf': 'n'}>
+CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS              policy<{'arm64': 'n', 'armhf': '-'}>
+CONFIG_ARM_SMMU_QCOM                            policy<{'arm64': 'y'}>
+CONFIG_ARM_SMMU_QCOM_DEBUG                      policy<{'arm64': 'y', 'arm64-generic-64k': 'n'}>
+CONFIG_ARM_SMMU_V3                              policy<{'arm64': 'y'}>
+CONFIG_ARM_SMMU_V3_PMU                          policy<{'arm64': 'm'}>
+CONFIG_ARM_SMMU_V3_SVA                          policy<{'arm64': 'y'}>
+CONFIG_ARM_SP805_WATCHDOG                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_SPE_PMU                              policy<{'arm64': 'm'}>
+CONFIG_ARM_SUN8I_A33_MBUS_DEVFREQ               policy<{'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_ARM_TEGRA124_CPUFREQ                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_TEGRA186_CPUFREQ                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_TEGRA194_CPUFREQ                     policy<{'arm64': 'm'}>
+CONFIG_ARM_TEGRA20_CPUFREQ                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_TEGRA_CPUIDLE                        policy<{'armhf': 'n'}>
+CONFIG_ARM_TEGRA_DEVFREQ                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ARM_THUMB                                policy<{'armhf': 'y'}>
+CONFIG_ARM_THUMBEE                              policy<{'armhf': 'y'}>
+CONFIG_ARM_TIMER_SP804                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_TI_CPUFREQ                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ARM_VEXPRESS_SPC_CPUFREQ                 policy<{'armhf': 'm'}>
+CONFIG_ARM_VIC                                  policy<{'armhf': 'y'}>
+CONFIG_ARM_VIC_NR                               policy<{'armhf': '2'}>
+CONFIG_ARM_VIRT_EXT                             policy<{'armhf': 'y'}>
+CONFIG_AS3935                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AS73211                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ASM_MODVERSIONS                          policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ASN1                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ASN1_ENCODER                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ASPEED_ADC                               policy<{'armhf': 'm'}>
+CONFIG_ASPEED_BT_IPMI_BMC                       policy<{'armhf': 'm'}>
+CONFIG_ASPEED_KCS_IPMI_BMC                      policy<{'armhf': 'm'}>
+CONFIG_ASPEED_LPC_CTRL                          policy<{'armhf': 'm'}>
+CONFIG_ASPEED_LPC_SNOOP                         policy<{'armhf': 'm'}>
+CONFIG_ASPEED_P2A_CTRL                          policy<{'armhf': 'm'}>
+CONFIG_ASPEED_SOCINFO                           policy<{'armhf': 'y'}>
+CONFIG_ASPEED_UART_ROUTING                      policy<{'armhf': 'm'}>
+CONFIG_ASPEED_WATCHDOG                          policy<{'armhf': 'y'}>
+CONFIG_ASSOCIATIVE_ARRAY                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_AST2600_I3C_MASTER                       policy<{'armhf': 'm'}>
+CONFIG_ASUS_LAPTOP                              policy<{'amd64': 'm'}>
+CONFIG_ASUS_NB_WMI                              policy<{'amd64': 'm'}>
+CONFIG_ASUS_TF103C_DOCK                         policy<{'amd64': 'm'}>
+CONFIG_ASUS_WIRELESS                            policy<{'amd64': 'm'}>
+CONFIG_ASUS_WMI                                 policy<{'amd64': 'm'}>
+CONFIG_ASYNC_CORE                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ASYNC_MEMCPY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ASYNC_PQ                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ASYNC_RAID6_RECOV                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ASYNC_RAID6_TEST                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA              policy<{'arm64': 'y'}>
+CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA             policy<{'arm64': 'y'}>
+CONFIG_ASYNC_TX_DMA                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ASYNC_TX_ENABLE_CHANNEL_SWITCH           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ASYNC_XOR                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_AS_AVX512                                policy<{'amd64': 'y'}>
+CONFIG_AS_GFNI                                  policy<{'amd64': 'y'}>
+CONFIG_AS_HAS_ARMV8_2                           policy<{'arm64': 'y'}>
+CONFIG_AS_HAS_ARMV8_3                           policy<{'arm64': 'y'}>
+CONFIG_AS_HAS_ARMV8_4                           policy<{'arm64': 'y'}>
+CONFIG_AS_HAS_ARMV8_5                           policy<{'arm64': 'y'}>
+CONFIG_AS_HAS_CFI_NEGATE_RA_STATE               policy<{'arm64': 'y'}>
+CONFIG_AS_HAS_INSN                              policy<{'riscv64': 'y'}>
+CONFIG_AS_HAS_LDAPR                             policy<{'arm64': 'y'}>
+CONFIG_AS_HAS_LSE_ATOMICS                       policy<{'arm64': 'y'}>
+CONFIG_AS_HAS_NON_CONST_ULEB128                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_AS_HAS_OPTION_ARCH                       policy<{'riscv64': 'y'}>
+CONFIG_AS_HAS_SHA3                              policy<{'arm64': 'y'}>
+CONFIG_AS_HAS_ULEB128                           policy<{'riscv64': 'y'}>
+CONFIG_AS_IS_GNU                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_AS_SHA1_NI                               policy<{'amd64': 'y'}>
+CONFIG_AS_SHA256_NI                             policy<{'amd64': 'y'}>
+CONFIG_AS_TPAUSE                                policy<{'amd64': 'y'}>
+CONFIG_AS_VERSION                               policy<{'amd64': '24200', 'arm64': '24200', 'armhf': '24200', 'ppc64el': '24200', 'riscv64': '24200', 's390x': '24200'}>
+CONFIG_AS_VFP_VMRS_FPINST                       policy<{'armhf': 'y'}>
+CONFIG_AS_WRUSS                                 policy<{'amd64': 'y'}>
+CONFIG_AT76C50X_USB                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AT803X_PHY                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ATA                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_ATAGS                                    policy<{'armhf': 'y'}>
+CONFIG_ATAGS_PROC                               policy<{'armhf': 'y'}>
+CONFIG_ATALK                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ATARI_PARTITION                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_ATA_ACPI                                 policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ATA_BMDMA                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATA_FORCE                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATA_GENERIC                              policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ATA_OVER_ETH                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ATA_SFF                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATA_VERBOSE_ERROR                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH10K                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH10K_AHB                               policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH10K_CE                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH10K_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_ATH10K_DEBUGFS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH10K_PCI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH10K_SDIO                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH10K_SNOC                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ATH10K_SPECTRAL                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH10K_TRACING                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH10K_USB                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH11K                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH11K_AHB                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_ATH11K_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_ATH11K_DEBUGFS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH11K_PCI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH11K_SPECTRAL                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH11K_TRACING                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH12K                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'n', 'riscv64': 'm'}>
+CONFIG_ATH12K_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'riscv64': 'n'}>
+CONFIG_ATH12K_TRACING                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_ATH5K                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH5K_DEBUG                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_ATH5K_PCI                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH5K_TRACER                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_ATH6KL                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH6KL_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_ATH6KL_SDIO                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH6KL_TRACING                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_ATH6KL_USB                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH9K                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH9K_AHB                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH9K_BTCOEX_SUPPORT                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH9K_CHANNEL_CONTEXT                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH9K_COMMON                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH9K_COMMON_DEBUG                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH9K_COMMON_SPECTRAL                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH9K_DEBUGFS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH9K_DYNACK                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_ATH9K_HTC                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH9K_HTC_DEBUGFS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH9K_HW                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH9K_HWRNG                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH9K_PCI                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH9K_PCI_NO_EEPROM                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH9K_PCOEM                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH9K_RFKILL                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH9K_STATION_STATISTICS                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH9K_WOW                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATH_COMMON                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATH_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_ATL1                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ATL1C                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ATL1E                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ATL2                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ATLAS_EZO_SENSOR                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATLAS_PH_SENSOR                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATM                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ATM_BR2684                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATM_BR2684_IPFILTER                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ATM_CLIP                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATM_CLIP_NO_ICMP                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ATM_DRIVERS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATM_DUMMY                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATM_ENI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATM_ENI_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ATM_ENI_TUNE_BURST                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ATM_FORE200E                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATM_FORE200E_DEBUG                       policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0'}>
+CONFIG_ATM_FORE200E_TX_RETRY                    policy<{'amd64': '16', 'arm64': '16', 'armhf': '16', 'ppc64el': '16', 'riscv64': '16'}>
+CONFIG_ATM_FORE200E_USE_TASKLET                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ATM_HE                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATM_HE_USE_SUNI                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATM_IA                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATM_IA_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ATM_IDT77252                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATM_IDT77252_DEBUG                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ATM_IDT77252_RCV_ALL                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ATM_IDT77252_USE_SUNI                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ATM_LANAI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATM_LANE                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATM_MPOA                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATM_NICSTAR                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATM_NICSTAR_USE_IDT77105                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ATM_NICSTAR_USE_SUNI                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ATM_SOLOS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATM_TCP                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ATOMIC64_SELFTEST                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ATP                                      policy<{'amd64': 'm'}>
+CONFIG_AUDIT                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_AUDITSYSCALL                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_AUDIT_ARCH                               policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_AUDIT_ARCH_COMPAT_GENERIC                policy<{'arm64': 'y'}>
+CONFIG_AUDIT_COMPAT_GENERIC                     policy<{'arm64': 'y', 'arm64-generic-64k': '-'}>
+CONFIG_AUDIT_GENERIC                            policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_AUTOFS_FS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'y'}>
+CONFIG_AUTO_ZRELADDR                            policy<{'armhf': 'y'}>
+CONFIG_AUXDISPLAY                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_AUXILIARY_BUS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_AX25                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AX25_DAMA_SLAVE                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_AX45MP_L2_CACHE                          policy<{'riscv64': 'n'}>
+CONFIG_AX88796                                  policy<{'armhf': 'm'}>
+CONFIG_AX88796B_PHY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_AX88796B_RUST_PHY                        policy<{'amd64': 'n'}>
+CONFIG_AX88796_93CX6                            policy<{'armhf': 'n'}>
+CONFIG_AXI_DMAC                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_AXP20X_ADC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AXP20X_POWER                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AXP288_ADC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_AXP288_CHARGER                           policy<{'amd64': 'm'}>
+CONFIG_AXP288_FUEL_GAUGE                        policy<{'amd64': 'm'}>
+CONFIG_B43                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_B43LEGACY                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_B43LEGACY_DEBUG                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_B43LEGACY_DMA                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43LEGACY_DMA_AND_PIO_MODE               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43LEGACY_DMA_MODE                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_B43LEGACY_HWRNG                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43LEGACY_LEDS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43LEGACY_PCICORE_AUTOSELECT             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43LEGACY_PCI_AUTOSELECT                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43LEGACY_PIO                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43LEGACY_PIO_MODE                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_B43_BCMA                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43_BCMA_PIO                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43_BUSES_BCMA                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_B43_BUSES_BCMA_AND_SSB                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43_BUSES_SSB                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_B43_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_B43_HWRNG                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43_LEDS                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43_PCICORE_AUTOSELECT                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43_PCI_AUTOSELECT                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43_PHY_G                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43_PHY_HT                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43_PHY_LP                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43_PHY_N                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43_PIO                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B43_SDIO                                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_B43_SSB                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B44                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_B44_PCI                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B44_PCICORE_AUTOSELECT                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B44_PCI_AUTOSELECT                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_B53                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_B53_MDIO_DRIVER                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_B53_MMAP_DRIVER                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_B53_SERDES                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_B53_SPI_DRIVER                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_B53_SRAB_DRIVER                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BACKLIGHT_88PM860X                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_AAT2870                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_ADP5520                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_ADP8860                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_ADP8870                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_APPLE                          policy<{'amd64': 'm'}>
+CONFIG_BACKLIGHT_ARCXCNN                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_AS3711                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_BD6107                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_CLASS_DEVICE                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_BACKLIGHT_DA903X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_DA9052                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_GPIO                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_KTD253                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_KTZ8866                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BACKLIGHT_LED                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BACKLIGHT_LM3533                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BACKLIGHT_LM3630A                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_LM3639                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_LP855X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_LP8788                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_LV5207LP                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_MAX8925                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_MP3309C                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BACKLIGHT_MT6370                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BACKLIGHT_PANDORA                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_PCF50633                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BACKLIGHT_PWM                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_QCOM_WLED                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKLIGHT_RAVE_SP                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BACKLIGHT_RT4831                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BACKLIGHT_SAHARA                         policy<{'amd64': 'm'}>
+CONFIG_BACKLIGHT_SKY81452                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BACKLIGHT_TPS65217                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': 'm'}>
+CONFIG_BACKLIGHT_WM831X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BACKTRACE_SELF_TEST                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BACKTRACE_VERBOSE                        policy<{'armhf': 'n'}>
+CONFIG_BALLOON_COMPACTION                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BARCO_P50_GPIO                           policy<{'amd64': 'm'}>
+CONFIG_BAREUDP                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_BASE_FULL                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BASE_SMALL                               policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0', 's390x': '0'}>
+CONFIG_BATMAN_ADV                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_BATMAN_ADV_BATMAN_V                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_BATMAN_ADV_BLA                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BATMAN_ADV_DAT                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BATMAN_ADV_DEBUG                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_BATMAN_ADV_MCAST                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BATMAN_ADV_NC                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BATMAN_ADV_TRACING                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_BATTERY_88PM860X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_ACER_A500                        policy<{'armhf': 'm'}>
+CONFIG_BATTERY_ACT8945A                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BATTERY_AXP20X                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BATTERY_BQ27XXX                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_BATTERY_BQ27XXX_HDQ                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BATTERY_BQ27XXX_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BATTERY_CPCAP                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BATTERY_CW2015                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_DA9030                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_DA9052                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_DA9150                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BATTERY_DS2760                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_DS2780                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_DS2781                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_DS2782                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_GAUGE_LTC2941                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_GOLDFISH                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_MAX17040                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_MAX17042                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_MAX1721X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_PM8916_BMS_VM                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_BATTERY_QCOM_BATTMGR                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BATTERY_RT5033                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_RX51                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BATTERY_SAMSUNG_SDI                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BATTERY_SBS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BATTERY_SURFACE                          policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_BATTERY_TWL4030_MADC                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BATTERY_UG3105                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BAYCOM_EPP                               policy<{'armhf': 'm'}>
+CONFIG_BAYCOM_PAR                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BAYCOM_SER_FDX                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BAYCOM_SER_HDX                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BCACHE                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BCACHEFS_DEBUG                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BCACHEFS_ERASURE_CODING                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BCACHEFS_FS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BCACHEFS_LOCK_TIME_STATS                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BCACHEFS_NO_LATENCY_ACCT                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BCACHEFS_POSIX_ACL                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BCACHEFS_QUOTA                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BCACHEFS_SIX_OPTIMISTIC_SPIN             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BCACHEFS_TESTS                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BCACHE_ASYNC_REGISTRATION                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BCACHE_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BCH                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BCM54140_PHY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BCM7XXX_PHY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BCM84881_PHY                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_BCM87XX_PHY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BCMA                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_BCMA_BLOCKIO                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BCMA_DEBUG                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_BCMA_DRIVER_GMAC_CMN                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BCMA_DRIVER_GPIO                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BCMA_DRIVER_PCI                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BCMA_HOST_PCI                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BCMA_HOST_PCI_POSSIBLE                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BCMA_HOST_SOC                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BCMA_POSSIBLE                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BCMA_SFLASH                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BCMGENET                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BCM_KONA_USB2_PHY                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_BCM_NET_PHYLIB                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BCM_NET_PHYPTP                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BCM_SBA_RAID                             policy<{'arm64': 'm'}>
+CONFIG_BCM_VK                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_BCM_VK_TTY                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BD957XMUF_WATCHDOG                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BE2ISCSI                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_BE2NET                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BE2NET_BE2                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BE2NET_BE3                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BE2NET_HWMON                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BE2NET_LANCER                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BE2NET_SKYHAWK                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BEFS_DEBUG                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_BEFS_FS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_BERLIN2_ADC                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_BFQ_CGROUP_DEBUG                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BFQ_GROUP_IOSCHED                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BFS_FS                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_BH1750                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BH1780                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BIG_LITTLE                               policy<{'armhf': 'y'}>
+CONFIG_BINARY_PRINTF                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BINDGEN_VERSION_TEXT                     policy<{'amd64': '"bindgen 0.65.1"'}>
+CONFIG_BINFMT_ELF                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BINFMT_ELF_FDPIC                         policy<{'armhf': 'y'}>
+CONFIG_BINFMT_FLAT                              policy<{'armhf': 'y', 'riscv64': 'n'}>
+CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK          policy<{'armhf': 'y'}>
+CONFIG_BINFMT_FLAT_OLD                          policy<{'armhf': 'y'}>
+CONFIG_BINFMT_MISC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BINFMT_ZFLAT                             policy<{'armhf': 'y'}>
+CONFIG_BITREVERSE                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLKDEV_UBLK_LEGACY_OPCODES               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_BLK_CGROUP                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_CGROUP_FC_APPID                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_CGROUP_IOCOST                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_CGROUP_IOLATENCY                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BLK_CGROUP_IOPRIO                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_CGROUP_PUNT_BIO                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_CGROUP_RWSTAT                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEBUG_FS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEBUG_FS_ZONED                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_3W_XXXX_RAID                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BLK_DEV_BSG                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_BSGLIB                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_BSG_COMMON                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_DM_BUILTIN                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_DRBD                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BLK_DEV_FD                               policy<{'amd64': 'm', 'ppc64el': 'm'}>
+CONFIG_BLK_DEV_FD_RAWCMD                        policy<{'amd64': 'n', 'ppc64el': 'n'}>
+CONFIG_BLK_DEV_INITRD                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_INTEGRITY                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_INTEGRITY_T10                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_IO_TRACE                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_LOOP                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_LOOP_MIN_COUNT                   policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'ppc64el': '8', 'riscv64': '8', 's390x': '8'}>
+CONFIG_BLK_DEV_MD                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_NBD                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BLK_DEV_NULL_BLK                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BLK_DEV_PCIESSD_MTIP32XX                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_BLK_DEV_PMEM                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BLK_DEV_RAM_COUNT                        policy<{'amd64': '16', 'arm64': '16', 'armhf': '16', 'ppc64el': '16', 'riscv64': '16', 's390x': '16'}>
+CONFIG_BLK_DEV_RBD                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BLK_DEV_RNBD                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_RNBD_CLIENT                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BLK_DEV_RNBD_SERVER                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BLK_DEV_THROTTLING_LOW                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BLK_DEV_UBLK                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_BLK_DEV_WRITE_MOUNTED                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_DEV_ZONED                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_ICQ                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_INLINE_ENCRYPTION                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_MQ_PCI                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_MQ_STACKING                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_MQ_VIRTIO                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_PM                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BLK_RQ_ALLOC_TIME                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_SED_OPAL                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_WBT                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLK_WBT_MQ                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLOCK                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLOCK_HOLDER_DEPRECATED                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BLOCK_LEGACY_AUTOLOAD                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BL_SWITCHER                              policy<{'armhf': 'y'}>
+CONFIG_BL_SWITCHER_DUMMY_IF                     policy<{'armhf': 'm'}>
+CONFIG_BMA220                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMA400                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMA400_I2C                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMA400_SPI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMC150_ACCEL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMC150_ACCEL_I2C                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMC150_ACCEL_SPI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMC150_MAGN                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMC150_MAGN_I2C                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMC150_MAGN_SPI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BME680                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BME680_I2C                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BME680_SPI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMG160                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMG160_I2C                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMG160_SPI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMI088_ACCEL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMI088_ACCEL_SPI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMI160                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMI160_I2C                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMI160_SPI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMI323                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMI323_I2C                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMI323_SPI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMP280                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMP280_I2C                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BMP280_SPI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BNA                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BNX2                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BNX2X                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BNX2X_SRIOV                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BNXT                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_BNXT_DCB                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BNXT_FLOWER_OFFLOAD                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BNXT_HWMON                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BNXT_SRIOV                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BOARD_TPCI200                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BONDING                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BOOTPARAM_HARDLOCKUP_PANIC               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_BOOTTIME_TRACING                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BOOTX_TEXT                               policy<{'ppc64el': 'n'}>
+CONFIG_BOOT_CONFIG                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BOOT_CONFIG_EMBED                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BOOT_CONFIG_FORCE                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BOOT_PRINTK_DELAY                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_BOOT_VESA_SUPPORT                        policy<{'amd64': 'y'}>
+CONFIG_BOSCH_BNO055                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BOSCH_BNO055_I2C                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BOSCH_BNO055_SERIAL                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BOUNCE                                   policy<{'armhf': 'y'}>
+CONFIG_BPF                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BPF_EVENTS                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BPF_JIT                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BPF_JIT_ALWAYS_ON                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BPF_JIT_DEFAULT_ON                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BPF_KPROBE_OVERRIDE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BPF_LSM                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BPF_PRELOAD                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BPF_STREAM_PARSER                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BPF_SYSCALL                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BPQETHER                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BQL                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BRANCH_PROFILE_NONE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BRCMDBG                                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_BRCMFMAC                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BRCMFMAC_PCIE                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BRCMFMAC_PROTO_BCDC                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BRCMFMAC_PROTO_MSGBUF                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BRCMFMAC_SDIO                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BRCMFMAC_USB                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BRCMSMAC                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BRCMSMAC_LEDS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BRCMUTIL                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BRCM_TRACING                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BRIDGE                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_CFM                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BRIDGE_EBT_802_3                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_AMONG                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_ARP                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_ARPREPLY                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_BROUTE                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_DNAT                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_IP                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_IP6                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_LIMIT                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_LOG                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_MARK                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_MARK_T                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_NFLOG                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_PKTTYPE                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_REDIRECT                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_SNAT                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_STP                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_T_FILTER                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_T_NAT                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_EBT_VLAN                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_IGMP_SNOOPING                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BRIDGE_MRP                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BRIDGE_NETFILTER                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_NF_EBTABLES                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BRIDGE_VLAN_FILTERING                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BROADCOM_PHY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BSD_DISKLABEL                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_BSD_PROCESS_ACCT                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BSD_PROCESS_ACCT_V3                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BT                                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BTREE                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BTRFS_ASSERT                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BTRFS_DEBUG                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BTRFS_FS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_BTRFS_FS_POSIX_ACL                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BTRFS_FS_REF_VERIFY                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BTRFS_FS_RUN_SANITY_TESTS                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BTT                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_6LOWPAN                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_AOSPEXT                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_ATH3K                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_BCM                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_BNEP                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_BNEP_MC_FILTER                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_BNEP_PROTO_FILTER                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_BREDR                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_CMTP                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_DEBUGFS                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIBCM203X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_HCIBCM4377                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_HCIBFUSB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_HCIBLUECARD                           policy<{'amd64': 'm'}>
+CONFIG_BT_HCIBPA10X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_HCIBT3C                               policy<{'amd64': 'm'}>
+CONFIG_BT_HCIBTSDIO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_HCIBTUSB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_HCIBTUSB_AUTOSUSPEND                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIBTUSB_BCM                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIBTUSB_MTK                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIBTUSB_POLL_SYNC                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIBTUSB_RTL                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIDTL1                               policy<{'amd64': 'm'}>
+CONFIG_BT_HCIRSI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_HCIUART                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_HCIUART_3WIRE                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIUART_AG6XX                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIUART_ATH3K                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIUART_BCM                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIUART_BCSP                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIUART_H4                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIUART_INTEL                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIUART_LL                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIUART_MRVL                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIUART_NOKIA                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_HCIUART_QCA                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIUART_RTL                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIUART_SERDEV                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_HCIVHCI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_HIDP                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_INTEL                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_LE                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_LEDS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_LE_L2CAP_ECRED                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_MRVL                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_MRVL_SDIO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_MSFTEXT                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_MTK                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_MTKSDIO                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_MTKUART                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_NXPUART                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_QCA                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_QCOMSMD                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_BT_RFCOMM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_RFCOMM_TTY                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_BT_RTL                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BT_SELFTEST                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_BT_VIRTIO                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_BUFFER_HEAD                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BUG                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BUG_ON_DATA_CORRUPTION                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_BUILDTIME_MCOUNT_SORT                    policy<{'amd64': 'y', 'armhf': 'y'}>
+CONFIG_BUILDTIME_TABLE_SORT                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_BUILD_SALT                               policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'ppc64el': '""', 'riscv64': '""', 's390x': '""'}>
+CONFIG_BUILTIN_RETURN_ADDRESS_STRIPS_PAC        policy<{'arm64': 'y'}>
+CONFIG_BXT_WC_PMIC_OPREGION                     policy<{'amd64': 'y'}>
+CONFIG_BYTCRC_PMIC_OPREGION                     policy<{'amd64': 'y'}>
+CONFIG_C2PORT                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_C2PORT_DURAMAR_2150                      policy<{'amd64': 'm'}>
+CONFIG_CACHEFILES                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CACHEFILES_DEBUG                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CACHEFILES_ERROR_INJECTION               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CACHEFILES_ONDEMAND                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CACHESTAT_SYSCALL                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CACHE_FEROCEON_L2                        policy<{'armhf': 'y'}>
+CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH           policy<{'armhf': 'n'}>
+CONFIG_CACHE_L2X0                               policy<{'armhf': 'y'}>
+CONFIG_CACHE_L2X0_PMU                           policy<{'armhf': 'y'}>
+CONFIG_CACHE_TAUROS2                            policy<{'armhf': 'y'}>
+CONFIG_CADENCE_WATCHDOG                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_CAIF                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_CAIF_DEBUG                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_CAIF_DRIVERS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CAIF_NETDEV                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAIF_TTY                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAIF_USB                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAIF_VIRTIO                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CALL_DEPTH_TRACKING                      policy<{'amd64': 'y'}>
+CONFIG_CALL_PADDING                             policy<{'amd64': 'y'}>
+CONFIG_CALL_THUNKS                              policy<{'amd64': 'y'}>
+CONFIG_CALL_THUNKS_DEBUG                        policy<{'amd64': 'n'}>
+CONFIG_CAN                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_CAN_8DEV_USB                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_BCM                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_BXCAN                                policy<{'arm64': 'm'}>
+CONFIG_CAN_CALC_BITTIMING                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CAN_CAN327                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_CC770                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_CC770_ISA                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_CC770_PLATFORM                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_CTUCANFD                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_CTUCANFD_PCI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_CTUCANFD_PLATFORM                    policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_C_CAN                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_C_CAN_PCI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_C_CAN_PLATFORM                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_DEBUG_DEVICES                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_CAN_DEV                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_EMS_PCI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_EMS_PCMCIA                           policy<{'amd64': 'm'}>
+CONFIG_CAN_EMS_USB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_ESD_USB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_ETAS_ES58X                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_F81601                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_F81604                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_FLEXCAN                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_GRCAN                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_GS_USB                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_GW                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_HI311X                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_IFI_CANFD                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_ISOTP                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_J1939                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_JANZ_ICAN3                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_KVASER_PCI                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_KVASER_PCIEFD                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_KVASER_USB                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_MCBA_USB                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_MCP251X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_MCP251XFD                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_MCP251XFD_SANITY                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_CAN_MSCAN                                policy<{'ppc64el': 'm'}>
+CONFIG_CAN_M_CAN                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_M_CAN_PCI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_M_CAN_PLATFORM                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_M_CAN_TCAN4X5X                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_NETLINK                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CAN_PEAK_PCI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_PEAK_PCIEC                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CAN_PEAK_PCIEFD                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_PEAK_PCMCIA                          policy<{'amd64': 'm'}>
+CONFIG_CAN_PEAK_USB                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_PLX_PCI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_RAW                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_RCAR                                 policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_RCAR_CANFD                           policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_RX_OFFLOAD                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CAN_SJA1000                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_SJA1000_ISA                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_SJA1000_PLATFORM                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_SLCAN                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_SOFTING                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_SOFTING_CS                           policy<{'amd64': 'm'}>
+CONFIG_CAN_SUN4I                                policy<{'riscv64': 'm'}>
+CONFIG_CAN_TI_HECC                              policy<{'armhf': 'm'}>
+CONFIG_CAN_UCAN                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_VCAN                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_VXCAN                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CAN_XILINXCAN                            policy<{'arm64': 'm'}>
+CONFIG_CAPI_TRACE                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CARDBUS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': '-'}>
+CONFIG_CARL9170                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CARL9170_DEBUGFS                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_CARL9170_HWRNG                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CARL9170_LEDS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CARL9170_WPC                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CARMINE_DRAM_CUSTOM                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_CASSINI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CAVIUM_CPT                               policy<{'arm64': 'm'}>
+CONFIG_CAVIUM_ERRATUM_22375                     policy<{'arm64': 'y'}>
+CONFIG_CAVIUM_ERRATUM_23144                     policy<{'arm64': 'y'}>
+CONFIG_CAVIUM_ERRATUM_23154                     policy<{'arm64': 'y'}>
+CONFIG_CAVIUM_ERRATUM_27456                     policy<{'arm64': 'y'}>
+CONFIG_CAVIUM_ERRATUM_30115                     policy<{'arm64': 'y'}>
+CONFIG_CAVIUM_PTP                               policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CAVIUM_TX2_ERRATUM_219                   policy<{'arm64': 'y'}>
+CONFIG_CB710_CORE                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_CB710_DEBUG                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_CB710_DEBUG_ASSUMPTIONS                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CC10001_ADC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CCS811                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CCW                                      policy<{'s390x': 'y'}>
+CONFIG_CCWGROUP                                 policy<{'s390x': 'm'}>
+CONFIG_CCW_CONSOLE                              policy<{'s390x': 'y'}>
+CONFIG_CC_CAN_LINK                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_CAN_LINK_STATIC                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_HAS_ASM_GOTO_OUTPUT                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_HAS_ASM_INLINE                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_HAS_AUTO_VAR_INIT_PATTERN             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_HAS_AUTO_VAR_INIT_ZERO_BARE           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_HAS_BRANCH_PROT_PAC_RET               policy<{'arm64': 'y'}>
+CONFIG_CC_HAS_BRANCH_PROT_PAC_RET_BTI           policy<{'arm64': 'y'}>
+CONFIG_CC_HAS_ELFV2                             policy<{'ppc64el': 'y'}>
+CONFIG_CC_HAS_ENTRY_PADDING                     policy<{'amd64': 'y'}>
+CONFIG_CC_HAS_IBT                               policy<{'amd64': 'y'}>
+CONFIG_CC_HAS_INT128                            policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_HAS_KASAN_GENERIC                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_HAS_KASAN_SW_TAGS                     policy<{'arm64': 'y'}>
+CONFIG_CC_HAS_NO_PROFILE_FN_ATTR                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_HAS_PCREL                             policy<{'ppc64el': 'y'}>
+CONFIG_CC_HAS_PREFIXED                          policy<{'ppc64el': 'y'}>
+CONFIG_CC_HAS_RETURN_THUNK                      policy<{'amd64': 'y'}>
+CONFIG_CC_HAS_SANCOV_TRACE_PC                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_HAS_SANE_STACKPROTECTOR               policy<{'amd64': 'y'}>
+CONFIG_CC_HAS_SIGN_RETURN_ADDRESS               policy<{'arm64': 'y'}>
+CONFIG_CC_HAS_SLS                               policy<{'amd64': 'y'}>
+CONFIG_CC_HAS_UBSAN_BOUNDS_STRICT               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_CC_HAS_WORKING_NOSANITIZE_ADDRESS        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_HAS_ZERO_CALL_USED_REGS               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_HAVE_SHADOW_CALL_STACK                policy<{'arm64': 'y'}>
+CONFIG_CC_HAVE_STACKPROTECTOR_SYSREG            policy<{'arm64': 'y'}>
+CONFIG_CC_HAVE_STACKPROTECTOR_TLS               policy<{'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_CC_IMPLICIT_FALLTHROUGH                  policy<{'amd64': '"-Wimplicit-fallthrough=5"', 'arm64': '"-Wimplicit-fallthrough=5"', 'armhf': '"-Wimplicit-fallthrough=5"', 'ppc64el': '"-Wimplicit-fallthrough=5"', 'riscv64': '"-Wimplicit-fallthrough=5"', 's390x': '"-Wimplicit-fallthrough=5"'}>
+CONFIG_CC_IS_GCC                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_NO_ARRAY_BOUNDS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_NO_STRINGOP_OVERFLOW                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CC_OPTIMIZE_FOR_SIZE                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CC_VERSION_TEXT                          policy<{'amd64': '"x86_64-linux-gnu-gcc-13 (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"', 'arm64': '"aarch64-linux-gnu-gcc-13 (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"', 'armhf': '"arm-linux-gnueabihf-gcc-13 (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"', 'ppc64el': '"powerpc64le-linux-gnu-gcc-13 (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"', 'riscv64': '"riscv64-linux-gnu-gcc-13 (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"', 's390x': '"s390x-linux-gnu-gcc-13 (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"'}>
+CONFIG_CDNS_I3C_MASTER                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CDROM                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CDROM_PKTCDVD                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CDX_BUS                                  policy<{'arm64': 'y'}>
+CONFIG_CDX_CONTROLLER                           policy<{'arm64': 'm'}>
+CONFIG_CEC_CH7322                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CEC_CORE                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CEC_CROS_EC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CEC_GPIO                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-', 'ppc64el': '-', 'riscv64': 'm'}>
+CONFIG_CEC_MESON_AO                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CEC_MESON_G12A_AO                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CEC_NOTIFIER                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CEC_PIN                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': '-', 'riscv64': 'y'}>
+CONFIG_CEC_PIN_ERROR_INJ                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': '-', 'ppc64el': '-', 'riscv64': 'n'}>
+CONFIG_CEC_SAMSUNG_S5P                          policy<{'armhf': 'n'}>
+CONFIG_CEC_SECO                                 policy<{'amd64': 'm'}>
+CONFIG_CEC_SECO_RC                              policy<{'amd64': 'y'}>
+CONFIG_CEC_STM32                                policy<{'arm64': 'm'}>
+CONFIG_CEC_TEGRA                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CEPH_FS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CEPH_FSCACHE                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CEPH_FS_POSIX_ACL                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CEPH_FS_SECURITY_LABEL                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CEPH_LIB                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CEPH_LIB_PRETTYDEBUG                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CEPH_LIB_USE_DNS_RESOLVER                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CERT_STORE                               policy<{'s390x': 'y'}>
+CONFIG_CFAG12864B                               policy<{'amd64': 'm'}>
+CONFIG_CFAG12864B_RATE                          policy<{'amd64': '20'}>
+CONFIG_CFG80211                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CFG80211_CERTIFICATION_ONUS              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_CFG80211_CRDA_SUPPORT                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CFG80211_DEBUGFS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CFG80211_DEFAULT_PS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CFG80211_DEVELOPER_WARNINGS              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_CFG80211_REQUIRE_SIGNED_REGDB            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CFG80211_WEXT                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CFG80211_WEXT_EXPORT                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CFS_BANDWIDTH                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CGROUPS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CGROUP_BPF                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CGROUP_CPUACCT                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CGROUP_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CGROUP_DEVICE                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CGROUP_FAVOR_DYNMODS                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CGROUP_FREEZER                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CGROUP_HUGETLB                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CGROUP_MISC                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CGROUP_NET_CLASSID                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CGROUP_NET_PRIO                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CGROUP_PERF                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CGROUP_PIDS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CGROUP_RDMA                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CGROUP_SCHED                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CGROUP_WRITEBACK                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CHARGER_88PM860X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_ADP5061                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_AXP20X                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_BD99954                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_BQ2415X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_BQ24190                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_BQ24257                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_BQ24735                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_BQ2515X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_BQ256XX                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_BQ25890                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_BQ25980                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_CPCAP                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CHARGER_CROS_PCHG                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CHARGER_CROS_USBPD                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CHARGER_DA9150                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_DETECTOR_MAX14656                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_GPIO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_ISP1704                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_LP8727                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_LP8788                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_LT3651                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_LTC4162L                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_MANAGER                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CHARGER_MAX14577                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_MAX77650                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_MAX77693                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_MAX77976                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_MAX8903                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_MAX8997                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_MAX8998                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_MP2629                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_MT6360                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_MT6370                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_PCF50633                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_PM8916_LBC                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CHARGER_QCOM_SMB2                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CHARGER_QCOM_SMBB                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CHARGER_RK817                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_RT5033                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_RT9455                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_RT9467                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'n', 'riscv64': 'm'}>
+CONFIG_CHARGER_RT9471                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_SBS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_SC2731                           policy<{'arm64': 'm'}>
+CONFIG_CHARGER_SMB347                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_SURFACE                          policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_CHARGER_TPS65090                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHARGER_TPS65217                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': 'm'}>
+CONFIG_CHARGER_TWL4030                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_UCS1002                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARGER_WILCO                            policy<{'amd64': 'm'}>
+CONFIG_CHARLCD                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHARLCD_BL_FLASH                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CHARLCD_BL_OFF                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_CHARLCD_BL_ON                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_CHECKPOINT_RESTORE                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CHECK_SIGNATURE                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CHELSIO_INLINE_CRYPTO                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CHELSIO_IPSEC_INLINE                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHELSIO_LIB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHELSIO_T1                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHELSIO_T1_1G                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CHELSIO_T3                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHELSIO_T4                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHELSIO_T4VF                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CHELSIO_T4_DCB                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CHELSIO_T4_FCOE                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CHELSIO_TLS_DEVICE                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CHROMEOS_ACPI                            policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_CHROMEOS_LAPTOP                          policy<{'amd64': 'm'}>
+CONFIG_CHROMEOS_PRIVACY_SCREEN                  policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_CHROMEOS_PSTORE                          policy<{'amd64': 'm'}>
+CONFIG_CHROMEOS_TBMC                            policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_CHROME_PLATFORMS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CHR_DEV_SCH                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CHR_DEV_ST                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CHSC_SCH                                 policy<{'s390x': 'm'}>
+CONFIG_CHTCRC_PMIC_OPREGION                     policy<{'amd64': 'y'}>
+CONFIG_CHT_DC_TI_PMIC_OPREGION                  policy<{'amd64': 'y'}>
+CONFIG_CHT_WC_PMIC_OPREGION                     policy<{'amd64': 'y'}>
+CONFIG_CICADA_PHY                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CIFS                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CIFS_ALLOW_INSECURE_LEGACY               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CIFS_DEBUG                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CIFS_DEBUG2                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CIFS_DEBUG_DUMP_KEYS                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CIFS_DFS_UPCALL                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CIFS_FSCACHE                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CIFS_POSIX                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CIFS_SMB_DIRECT                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CIFS_STATS2                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CIFS_SWN_UPCALL                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CIFS_UPCALL                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CIFS_XATTR                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CIO_DAC                                  policy<{'amd64': 'm'}>
+CONFIG_CIO_INJECT                               policy<{'s390x': 'n'}>
+CONFIG_CLANG_VERSION                            policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0', 's390x': '0'}>
+CONFIG_CLKBLD_I8253                             policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_CLKEVT_I8253                             policy<{'amd64': 'y'}>
+CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK      policy<{'armhf': 'y'}>
+CONFIG_CLKSRC_EXYNOS_MCT                        policy<{'armhf': 'y'}>
+CONFIG_CLKSRC_IMX_GPT                           policy<{'armhf': 'y'}>
+CONFIG_CLKSRC_IMX_TPM                           policy<{'armhf': 'y'}>
+CONFIG_CLKSRC_MMIO                              policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_CLKSRC_QCOM                              policy<{'armhf': 'y'}>
+CONFIG_CLKSRC_STM32_LP                          policy<{'arm64': 'y'}>
+CONFIG_CLKSRC_TI_32K                            policy<{'armhf': 'y'}>
+CONFIG_CLKSRC_VERSATILE                         policy<{'armhf': 'y'}>
+CONFIG_CLK_ACTIONS                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CLK_ANALOGBITS_WRPLL_CLN28HPC            policy<{'riscv64': 'y'}>
+CONFIG_CLK_EMEV2                                policy<{'armhf': 'y'}>
+CONFIG_CLK_GFM_LPASS_SM8250                     policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_CLK_ICST                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CLK_IMX5                                 policy<{'armhf': 'y'}>
+CONFIG_CLK_IMX6Q                                policy<{'armhf': 'y'}>
+CONFIG_CLK_IMX6SL                               policy<{'armhf': 'y'}>
+CONFIG_CLK_IMX6SLL                              policy<{'armhf': 'y'}>
+CONFIG_CLK_IMX6SX                               policy<{'armhf': 'y'}>
+CONFIG_CLK_IMX6UL                               policy<{'armhf': 'y'}>
+CONFIG_CLK_IMX7D                                policy<{'armhf': 'y'}>
+CONFIG_CLK_IMX7ULP                              policy<{'armhf': 'y'}>
+CONFIG_CLK_IMX8MM                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CLK_IMX8MN                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CLK_IMX8MP                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CLK_IMX8MQ                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CLK_IMX8QXP                              policy<{'arm64': 'y'}>
+CONFIG_CLK_IMX8ULP                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CLK_IMX93                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CLK_INTEL_SOCFPGA                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CLK_INTEL_SOCFPGA32                      policy<{'armhf': 'y'}>
+CONFIG_CLK_INTEL_SOCFPGA64                      policy<{'arm64': 'y'}>
+CONFIG_CLK_LS1028A_PLLDIG                       policy<{'arm64': 'm'}>
+CONFIG_CLK_MA35D1                               policy<{'arm64': 'y'}>
+CONFIG_CLK_OWL_S500                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CLK_OWL_S700                             policy<{'arm64': 'y'}>
+CONFIG_CLK_OWL_S900                             policy<{'arm64': 'y'}>
+CONFIG_CLK_PX30                                 policy<{'arm64': 'y'}>
+CONFIG_CLK_QORIQ                                policy<{'arm64': 'y'}>
+CONFIG_CLK_R7S9210                              policy<{'armhf': 'y'}>
+CONFIG_CLK_R8A7740                              policy<{'armhf': 'y'}>
+CONFIG_CLK_R8A7742                              policy<{'armhf': 'y'}>
+CONFIG_CLK_R8A7743                              policy<{'armhf': 'y'}>
+CONFIG_CLK_R8A7745                              policy<{'armhf': 'y'}>
+CONFIG_CLK_R8A77470                             policy<{'armhf': 'y'}>
+CONFIG_CLK_R8A774A1                             policy<{'arm64': 'y'}>
+CONFIG_CLK_R8A774B1                             policy<{'arm64': 'y'}>
+CONFIG_CLK_R8A774C0                             policy<{'arm64': 'y'}>
+CONFIG_CLK_R8A774E1                             policy<{'arm64': 'y'}>
+CONFIG_CLK_R8A7778                              policy<{'armhf': 'y'}>
+CONFIG_CLK_R8A7779                              policy<{'armhf': 'y'}>
+CONFIG_CLK_R8A7790                              policy<{'armhf': 'y'}>
+CONFIG_CLK_R8A7791                              policy<{'armhf': 'y'}>
+CONFIG_CLK_R8A7792                              policy<{'armhf': 'y'}>
+CONFIG_CLK_R8A7794                              policy<{'armhf': 'y'}>
+CONFIG_CLK_R8A7795                              policy<{'arm64': 'y'}>
+CONFIG_CLK_R8A77960                             policy<{'arm64': 'y'}>
+CONFIG_CLK_R8A77961                             policy<{'arm64': 'y'}>
+CONFIG_CLK_R8A77965                             policy<{'arm64': 'y'}>
+CONFIG_CLK_R8A77970                             policy<{'arm64': 'y'}>
+CONFIG_CLK_R8A77980                             policy<{'arm64': 'y'}>
+CONFIG_CLK_R8A77990                             policy<{'arm64': 'y'}>
+CONFIG_CLK_R8A77995                             policy<{'arm64': 'y'}>
+CONFIG_CLK_R8A779A0                             policy<{'arm64': 'y'}>
+CONFIG_CLK_R8A779F0                             policy<{'arm64': 'y'}>
+CONFIG_CLK_R8A779G0                             policy<{'arm64': 'y'}>
+CONFIG_CLK_R9A06G032                            policy<{'armhf': 'y'}>
+CONFIG_CLK_R9A07G043                            policy<{'arm64': 'y', 'riscv64': '-'}>
+CONFIG_CLK_R9A07G044                            policy<{'arm64': 'y'}>
+CONFIG_CLK_R9A07G054                            policy<{'arm64': 'y'}>
+CONFIG_CLK_R9A08G045                            policy<{'arm64': 'y'}>
+CONFIG_CLK_R9A09G011                            policy<{'arm64': 'y'}>
+CONFIG_CLK_RCAR_CPG_LIB                         policy<{'arm64': 'y'}>
+CONFIG_CLK_RCAR_GEN2_CPG                        policy<{'armhf': 'y'}>
+CONFIG_CLK_RCAR_GEN3_CPG                        policy<{'arm64': 'y'}>
+CONFIG_CLK_RCAR_GEN4_CPG                        policy<{'arm64': 'y'}>
+CONFIG_CLK_RCAR_USB2_CLOCK_SEL                  policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_CLK_RENESAS                              policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_CLK_RENESAS_CPG_MSSR                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CLK_RENESAS_CPG_MSTP                     policy<{'armhf': 'y'}>
+CONFIG_CLK_RENESAS_DIV6                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CLK_RK3036                               policy<{'armhf': 'y'}>
+CONFIG_CLK_RK312X                               policy<{'armhf': 'y'}>
+CONFIG_CLK_RK3188                               policy<{'armhf': 'y'}>
+CONFIG_CLK_RK322X                               policy<{'armhf': 'y'}>
+CONFIG_CLK_RK3288                               policy<{'armhf': 'y'}>
+CONFIG_CLK_RK3308                               policy<{'arm64': 'y'}>
+CONFIG_CLK_RK3328                               policy<{'arm64': 'y'}>
+CONFIG_CLK_RK3368                               policy<{'arm64': 'y'}>
+CONFIG_CLK_RK3399                               policy<{'arm64': 'y'}>
+CONFIG_CLK_RK3568                               policy<{'arm64': 'y', 'armhf': '-'}>
+CONFIG_CLK_RK3588                               policy<{'arm64': 'y'}>
+CONFIG_CLK_RV110X                               policy<{'armhf': 'y'}>
+CONFIG_CLK_RV1126                               policy<{'armhf': 'y'}>
+CONFIG_CLK_RZA1                                 policy<{'armhf': 'y'}>
+CONFIG_CLK_RZG2L                                policy<{'arm64': 'y', 'riscv64': '-'}>
+CONFIG_CLK_SH73A0                               policy<{'armhf': 'y'}>
+CONFIG_CLK_SIFIVE                               policy<{'riscv64': 'y'}>
+CONFIG_CLK_SIFIVE_PRCI                          policy<{'riscv64': 'y'}>
+CONFIG_CLK_SP810                                policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': '-'}>
+CONFIG_CLK_STARFIVE_JH7100                      policy<{'riscv64': 'n'}>
+CONFIG_CLK_STARFIVE_JH7110_AON                  policy<{'riscv64': 'm'}>
+CONFIG_CLK_STARFIVE_JH7110_ISP                  policy<{'riscv64': 'm'}>
+CONFIG_CLK_STARFIVE_JH7110_PLL                  policy<{'riscv64': 'y'}>
+CONFIG_CLK_STARFIVE_JH7110_STG                  policy<{'riscv64': 'm'}>
+CONFIG_CLK_STARFIVE_JH7110_SYS                  policy<{'riscv64': 'y'}>
+CONFIG_CLK_STARFIVE_JH7110_VOUT                 policy<{'riscv64': 'm'}>
+CONFIG_CLK_STARFIVE_JH71X0                      policy<{'riscv64': 'y'}>
+CONFIG_CLK_TEGRA_BPMP                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CLK_TWL                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CLK_TWL6040                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CLK_VEXPRESS_OSC                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CLK_VF610                                policy<{'armhf': 'y'}>
+CONFIG_CLK_X1E80100_GCC                         policy<{'arm64': 'm'}>
+CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE          policy<{'amd64': 'y'}>
+CONFIG_CLOCKSOURCE_WATCHDOG                     policy<{'amd64': 'y'}>
+CONFIG_CLOCKSOURCE_WATCHDOG_MAX_SKEW_US         policy<{'amd64': '100'}>
+CONFIG_CLONE_BACKWARDS                          policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CLONE_BACKWARDS2                         policy<{'s390x': 'y'}>
+CONFIG_CLOSURES                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CLS_U32_MARK                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CLS_U32_PERF                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CLZ_TAB                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CM32181                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CM3232                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CM3323                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CM3605                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CM36651                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CMA_ALIGNMENT                            policy<{'arm64': '8', 'armhf': '8', 'riscv64': '8'}>
+CONFIG_CMA_AREAS                                policy<{'arm64': '7', 'armhf': '7', 'ppc64el': '7', 'riscv64': '7', 's390x': '7'}>
+CONFIG_CMA_DEBUG                                policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CMA_DEBUGFS                              policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CMA_SIZE_SEL_MAX                         policy<{'arm64': 'n', 'armhf': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_CMA_SIZE_SEL_MBYTES                      policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_CMA_SIZE_SEL_MIN                         policy<{'arm64': 'n', 'armhf': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_CMA_SIZE_SEL_PERCENTAGE                  policy<{'arm64': 'n', 'armhf': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_CMA_SYSFS                                policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CMDLINE                                  policy<{'arm64': '"console=ttyAMA0"', 'armhf': '""', 'ppc64el': '""', 'riscv64': '""'}>
+CONFIG_CMDLINE_BOOL                             policy<{'amd64': 'n'}>
+CONFIG_CMDLINE_FORCE                            policy<{'arm64': 'n', 'armhf': '-'}>
+CONFIG_CMDLINE_FROM_BOOTLOADER                  policy<{'arm64': 'y', 'armhf': '-'}>
+CONFIG_CMDLINE_PARTITION                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_CMM                                      policy<{'ppc64el': 'm', 's390x': 'y'}>
+CONFIG_CMM_IUCV                                 policy<{'s390x': 'y'}>
+CONFIG_CMODEL_MEDANY                            policy<{'riscv64': 'y'}>
+CONFIG_CMODEL_MEDLOW                            policy<{'riscv64': 'n'}>
+CONFIG_CNIC                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_CODA_FS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CODE_PATCHING_SELFTEST                   policy<{'ppc64el': 'n'}>
+CONFIG_COMEDI                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_COMEDI_8254                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_8255                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_8255_PCI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_8255_SA                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADDI_APCI_1032                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADDI_APCI_1500                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADDI_APCI_1516                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADDI_APCI_1564                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADDI_APCI_16XX                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADDI_APCI_2032                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADDI_APCI_2200                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADDI_APCI_3120                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADDI_APCI_3501                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADDI_APCI_3XXX                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADDI_WATCHDOG                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADL_PCI6208                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADL_PCI7X3X                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADL_PCI8164                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADL_PCI9111                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADL_PCI9118                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADQ12B                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADV_PCI1710                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADV_PCI1720                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADV_PCI1723                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADV_PCI1724                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADV_PCI1760                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ADV_PCI_DIO                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_AIO_AIO12_8                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_AIO_IIRO_16                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_AMPLC_DIO200                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_AMPLC_DIO200_ISA                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_AMPLC_DIO200_PCI                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_AMPLC_PC236                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_AMPLC_PC236_ISA                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_AMPLC_PC236_PCI                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_AMPLC_PC263_ISA                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_AMPLC_PC263_PCI                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_AMPLC_PCI224                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_AMPLC_PCI230                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_BOND                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_C6XDIGIO                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_CB_DAS16_CS                       policy<{'amd64': 'm'}>
+CONFIG_COMEDI_CB_PCIDAS                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_CB_PCIDAS64                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_CB_PCIDDA                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_CB_PCIMDAS                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_CB_PCIMDDA                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_CONTEC_PCI_DIO                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DAC02                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DAQBOARD2000                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DAS08                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DAS08_CS                          policy<{'amd64': 'm'}>
+CONFIG_COMEDI_DAS08_ISA                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DAS08_PCI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DAS16                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DAS16M1                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DAS1800                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DAS6402                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DAS800                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_COMEDI_DEFAULT_BUF_MAXSIZE_KB            policy<{'amd64': '20480', 'arm64': '20480', 'armhf': '20480', 'ppc64el': '20480', 'riscv64': '20480'}>
+CONFIG_COMEDI_DEFAULT_BUF_SIZE_KB               policy<{'amd64': '2048', 'arm64': '2048', 'armhf': '2048', 'ppc64el': '2048', 'riscv64': '2048'}>
+CONFIG_COMEDI_DMM32AT                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DT2801                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DT2811                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DT2814                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DT2815                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DT2817                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DT282X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DT3000                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DT9812                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_DYNA_PCI10XX                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_FL512                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_GSC_HPDI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ICP_MULTI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_II_PCI20KC                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ISADMA                            policy<{'amd64': 'm', 'ppc64el': 'm'}>
+CONFIG_COMEDI_ISA_DRIVERS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_COMEDI_JR3_PCI                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_KCOMEDILIB                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_KE_COUNTER                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ME4000                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_ME_DAQ                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_MF6X4                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_MISC_DRIVERS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_COMEDI_MITE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_MPC624                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_MULTIQ3                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_6527                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_65XX                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_660X                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_670X                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_ATMIO                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_ATMIO16D                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_AT_A2150                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_AT_AO                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_DAQ_700_CS                     policy<{'amd64': 'm'}>
+CONFIG_COMEDI_NI_DAQ_DIO24_CS                   policy<{'amd64': 'm'}>
+CONFIG_COMEDI_NI_LABPC                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_LABPC_CS                       policy<{'amd64': 'm'}>
+CONFIG_COMEDI_NI_LABPC_ISA                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_LABPC_ISADMA                   policy<{'amd64': 'm', 'ppc64el': 'm'}>
+CONFIG_COMEDI_NI_LABPC_PCI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_MIO_CS                         policy<{'amd64': 'm'}>
+CONFIG_COMEDI_NI_PCIDIO                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_PCIMIO                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_ROUTING                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_TIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_TIOCMD                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_NI_USB6501                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_PARPORT                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_PCI_DRIVERS                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_PCL711                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_PCL724                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_PCL726                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_PCL730                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_PCL812                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_PCL816                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_PCL818                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_PCM3724                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_PCMAD                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_PCMCIA_DRIVERS                    policy<{'amd64': 'm'}>
+CONFIG_COMEDI_PCMDA12                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_PCMMIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_PCMUIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_QUATECH_DAQP_CS                   policy<{'amd64': 'm'}>
+CONFIG_COMEDI_RTD520                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_RTI800                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_RTI802                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_S526                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_S626                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_TEST                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_TESTS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_TESTS_EXAMPLE                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_TESTS_NI_ROUTES                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_USBDUX                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_USBDUXFAST                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_USBDUXSIGMA                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_USB_DRIVERS                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMEDI_VMK80XX                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMAND_LINE_SIZE                        policy<{'s390x': '4096'}>
+CONFIG_COMMON_CLK                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_COMMON_CLK_A1_PERIPHERALS                policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_A1_PLL                        policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_APPLE_NCO                     policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_ASPEED                        policy<{'armhf': 'y'}>
+CONFIG_COMMON_CLK_AXG                           policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_AXG_AUDIO                     policy<{'arm64': 'm', 'armhf': 'n'}>
+CONFIG_COMMON_CLK_AXI_CLKGEN                    policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMON_CLK_BD718XX                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMON_CLK_BM1880                        policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_CDCE706                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_COMMON_CLK_CDCE925                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMON_CLK_CS2000_CP                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_COMMON_CLK_EN7523                        policy<{'armhf': 'y'}>
+CONFIG_COMMON_CLK_FIXED_MMIO                    policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_COMMON_CLK_FSL_FLEXSPI                   policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_FSL_SAI                       policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_G12A                          policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_GXBB                          policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_HI3516CV300                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_HI3519                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_HI3559A                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_HI3660                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_HI3670                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_HI3798CV200                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_HI6220                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_HI655X                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_LOCHNAGAR                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMON_CLK_MAX77686                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMON_CLK_MAX9485                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_COMMON_CLK_MEDIATEK                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_MEDIATEK_FHCTL                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_MESON8B                       policy<{'armhf': 'y'}>
+CONFIG_COMMON_CLK_MESON_AO_CLKC                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MESON_CLKC_UTILS              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_MESON_CPU_DYNDIV              policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MESON_DUALDIV                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MESON_EE_CLKC                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MESON_MPLL                    policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_MESON_PHASE                   policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MESON_PLL                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_MESON_REGMAP                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_MESON_SCLK_DIV                policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MESON_VID_PLL_DIV             policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT2701                        policy<{'armhf': 'n'}>
+CONFIG_COMMON_CLK_MT2712                        policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT2712_BDPSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT2712_IMGSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT2712_JPGDECSYS              policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT2712_MFGCFG                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT2712_MMSYS                  policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT2712_VDECSYS                policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT2712_VENCSYS                policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6765                        policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6765_AUDIOSYS               policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6765_CAMSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6765_GCESYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6765_IMGSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6765_MFGSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6765_MIPI0ASYS              policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6765_MIPI0BSYS              policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6765_MIPI1ASYS              policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6765_MIPI1BSYS              policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6765_MIPI2ASYS              policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6765_MIPI2BSYS              policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6765_MMSYS                  policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6765_VCODECSYS              policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6779                        policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6779_AUDSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6779_CAMSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6779_IMGSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6779_IPESYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6779_MFGCFG                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6779_MMSYS                  policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6779_VDECSYS                policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6779_VENCSYS                policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6795                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_MT6795_MFGCFG                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_MT6795_MMSYS                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_MT6795_VDECSYS                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_MT6795_VENCSYS                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_MT6797                        policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6797_IMGSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6797_MMSYS                  policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6797_VDECSYS                policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT6797_VENCSYS                policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT7622                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_MT7622_AUDSYS                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_MT7622_ETHSYS                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_MT7622_HIFSYS                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_MT7629                        policy<{'armhf': 'y'}>
+CONFIG_COMMON_CLK_MT7629_ETHSYS                 policy<{'armhf': 'y'}>
+CONFIG_COMMON_CLK_MT7629_HIFSYS                 policy<{'armhf': 'y'}>
+CONFIG_COMMON_CLK_MT7981                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_MT7981_ETHSYS                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_MT7986                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_MT7986_ETHSYS                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_MT7988                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_MT8135                        policy<{'armhf': 'y'}>
+CONFIG_COMMON_CLK_MT8167                        policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8167_AUDSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8167_IMGSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8167_MFGCFG                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8167_MMSYS                  policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8167_VDECSYS                policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8173                        policy<{'arm64': 'y', 'armhf': '-'}>
+CONFIG_COMMON_CLK_MT8173_IMGSYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8173_MMSYS                  policy<{'arm64': 'y', 'armhf': '-'}>
+CONFIG_COMMON_CLK_MT8173_VDECSYS                policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8173_VENCSYS                policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8183                        policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8183_AUDIOSYS               policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8183_CAMSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8183_IMGSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8183_IPU_ADL                policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8183_IPU_CONN               policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8183_IPU_CORE0              policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8183_IPU_CORE1              policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8183_MFGCFG                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8183_MMSYS                  policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8183_VDECSYS                policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8183_VENCSYS                policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8186                        policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8186_CAMSYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8186_IMGSYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8186_IMP_IIC_WRAP           policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8186_IPESYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8186_MCUSYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8186_MDPSYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8186_MFGCFG                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8186_MMSYS                  policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8186_VDECSYS                policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8186_VENCSYS                policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8186_WPESYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8188                        policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8188_ADSP_AUDIO26M          policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8188_CAMSYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8188_IMGSYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8188_IMP_IIC_WRAP           policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8188_IPESYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8188_MFGCFG                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8188_VDECSYS                policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8188_VDOSYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8188_VENCSYS                policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8188_VPPSYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8188_WPESYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8192                        policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8192_AUDSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8192_CAMSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8192_IMGSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8192_IMP_IIC_WRAP           policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8192_IPESYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8192_MDPSYS                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8192_MFGCFG                 policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8192_MMSYS                  policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8192_MSDC                   policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8192_SCP_ADSP               policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8192_VDECSYS                policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8192_VENCSYS                policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8195                        policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_MT8195_APUSYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8195_CAMSYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8195_IMGSYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8195_IMP_IIC_WRAP           policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8195_IPESYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8195_MFGCFG                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8195_SCP_ADSP               policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8195_VDECSYS                policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8195_VDOSYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8195_VENCSYS                policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8195_VPPSYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8195_WPESYS                 policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_MT8365                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_MT8365_APU                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_MT8365_CAM                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_MT8365_MFG                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_MT8365_MMSYS                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_MT8365_VDEC                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_MT8365_VENC                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_MT8516                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_MT8516_AUDSYS                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_NUVOTON                       policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_PALMAS                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_COMMON_CLK_PWM                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_COMMON_CLK_QCOM                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_RK808                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMON_CLK_ROCKCHIP                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_COMMON_CLK_RS9_PCIE                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMON_CLK_S2MPS11                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMON_CLK_S4_PERIPHERALS                policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_S4_PLL                        policy<{'arm64': 'm'}>
+CONFIG_COMMON_CLK_SAMSUNG                       policy<{'armhf': 'y'}>
+CONFIG_COMMON_CLK_SCMI                          policy<{'arm64': 'y', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_SCPI                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_CLK_SI514                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMON_CLK_SI521XX                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMON_CLK_SI5341                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_COMMON_CLK_SI5351                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_COMMON_CLK_SI544                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_COMMON_CLK_SI570                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMON_CLK_SP7021                        policy<{'armhf': 'm'}>
+CONFIG_COMMON_CLK_STM32MP                       policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_TI_ADPLL                      policy<{'armhf': 'y'}>
+CONFIG_COMMON_CLK_TPS68470                      policy<{'amd64': 'm'}>
+CONFIG_COMMON_CLK_VC3                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMON_CLK_VC5                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMON_CLK_VC7                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_COMMON_CLK_VISCONTI                      policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_WM831X                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_COMMON_CLK_XGENE                         policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_XLNX_CLKWZRD                  policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'n'}>
+CONFIG_COMMON_CLK_ZYNQMP                        policy<{'arm64': 'y'}>
+CONFIG_COMMON_RESET_HI3660                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMMON_RESET_HI6220                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_COMPACTION                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_COMPACT_UNEVICTABLE_DEFAULT              policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'ppc64el': '1', 'riscv64': '1', 's390x': '1'}>
+CONFIG_COMPAL_LAPTOP                            policy<{'amd64': 'm'}>
+CONFIG_COMPAT                                   policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_COMPAT_32                                policy<{'amd64': 'y'}>
+CONFIG_COMPAT_32BIT_TIME                        policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': 'n', 'armhf': 'y', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_COMPAT_ALIGNMENT_FIXUPS                  policy<{'arm64': 'n', 'arm64-generic-64k': '-'}>
+CONFIG_COMPAT_BINFMT_ELF                        policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': '-', 'ppc64el': '-', 's390x': '-'}>
+CONFIG_COMPAT_FOR_U64_ALIGNMENT                 policy<{'amd64': 'y'}>
+CONFIG_COMPAT_NETLINK_MESSAGES                  policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': '-', 'ppc64el': '-'}>
+CONFIG_COMPAT_OLD_SIGACTION                     policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': '-', 'ppc64el': '-', 's390x': '-'}>
+CONFIG_COMPAT_VDSO                              policy<{'amd64': 'n'}>
+CONFIG_COMPILE_TEST                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CONFIGFS_FS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CONNECTOR                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CONSOLE_LOGLEVEL_DEFAULT                 policy<{'amd64': '7', 'arm64': '7', 'armhf': '7', 'ppc64el': '7', 'riscv64': '7', 's390x': '7'}>
+CONFIG_CONSOLE_POLL                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CONSOLE_TRANSLATIONS                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CONTEXT_SWITCH_TRACER                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CONTEXT_TRACKING                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CONTEXT_TRACKING_IDLE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CONTEXT_TRACKING_USER                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CONTEXT_TRACKING_USER_FORCE              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_CONTIG_ALLOC                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CORDIC                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_COREDUMP                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CORESIGHT                                policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CORTINA_PHY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_COUNTER                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CPA_DEBUG                                policy<{'amd64': 'n'}>
+CONFIG_CPCAP_ADC                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CPU5_WDT                                 policy<{'amd64': 'm'}>
+CONFIG_CPUFREQ_DT_PLATDEV                       policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPUMASK_OFFSTACK                         policy<{'amd64': 'y'}>
+CONFIG_CPUSETS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CPU_32v6K                                policy<{'armhf': 'y'}>
+CONFIG_CPU_32v7                                 policy<{'armhf': 'y'}>
+CONFIG_CPU_ABRT_EV7                             policy<{'armhf': 'y'}>
+CONFIG_CPU_BIG_ENDIAN                           policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 's390x': 'y'}>
+CONFIG_CPU_BPREDICT_DISABLE                     policy<{'armhf': 'n'}>
+CONFIG_CPU_CACHE_V7                             policy<{'armhf': 'y'}>
+CONFIG_CPU_CACHE_VIPT                           policy<{'armhf': 'y'}>
+CONFIG_CPU_COPY_V6                              policy<{'armhf': 'y'}>
+CONFIG_CPU_CP15                                 policy<{'armhf': 'y'}>
+CONFIG_CPU_CP15_MMU                             policy<{'armhf': 'y'}>
+CONFIG_CPU_FREQ                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE        policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND            policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'n'}>
+CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL           policy<{'amd64': 'y', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_CPU_FREQ_GOV_ATTR_SET                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_FREQ_GOV_COMMON                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_FREQ_THERMAL                         policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_HAS_ASID                             policy<{'armhf': 'y'}>
+CONFIG_CPU_HOTPLUG_STATE_CONTROL                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CPU_IBPB_ENTRY                           policy<{'amd64': 'y'}>
+CONFIG_CPU_IBRS_ENTRY                           policy<{'amd64': 'y'}>
+CONFIG_CPU_ICACHE_DISABLE                       policy<{'armhf': 'n'}>
+CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND           policy<{'armhf': 'y'}>
+CONFIG_CPU_IDLE                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_IDLE_GOV_HALTPOLL                    policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_CPU_IDLE_GOV_LADDER                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_IDLE_GOV_MENU                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_IDLE_GOV_TEO                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_IDLE_MULTIPLE_DRIVERS                policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_IDLE_THERMAL                         policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_ISOLATION                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CPU_LITTLE_ENDIAN                        policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_CPU_MITIGATIONS                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CPU_PABRT_V7                             policy<{'armhf': 'y'}>
+CONFIG_CPU_PJ4                                  policy<{'armhf': 'y'}>
+CONFIG_CPU_PJ4B                                 policy<{'armhf': 'y'}>
+CONFIG_CPU_PM                                   policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_RMAP                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CPU_SPECTRE                              policy<{'armhf': 'y'}>
+CONFIG_CPU_SRSO                                 policy<{'amd64': 'y'}>
+CONFIG_CPU_SUP_AMD                              policy<{'amd64': 'y'}>
+CONFIG_CPU_SUP_CENTAUR                          policy<{'amd64': 'y'}>
+CONFIG_CPU_SUP_HYGON                            policy<{'amd64': 'y'}>
+CONFIG_CPU_SUP_INTEL                            policy<{'amd64': 'y'}>
+CONFIG_CPU_SUP_ZHAOXIN                          policy<{'amd64': 'y'}>
+CONFIG_CPU_THERMAL                              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CPU_THUMB_CAPABLE                        policy<{'armhf': 'y'}>
+CONFIG_CPU_TLB_V7                               policy<{'armhf': 'y'}>
+CONFIG_CPU_UNRET_ENTRY                          policy<{'amd64': 'y'}>
+CONFIG_CPU_V7                                   policy<{'armhf': 'y'}>
+CONFIG_CRAMFS                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_CRAMFS_BLOCKDEV                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CRAMFS_MTD                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CRASH_CORE                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRASH_HOTPLUG                            policy<{'amd64': 'y'}>
+CONFIG_CRASH_MAX_MEMORY_RANGES                  policy<{'amd64': '8192'}>
+CONFIG_CRC16                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRC32                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRC32_BIT                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CRC32_SARWATE                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CRC32_SELFTEST                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CRC32_SLICEBY4                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CRC32_SLICEBY8                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRC4                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRC64                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRC64_ROCKSOFT                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRC7                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_CRC8                                     policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRC_CCITT                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRC_ITU_T                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_CRC_T10DIF                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CROSS_MEMORY_ATTACH                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CROS_EC                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_EC_CHARDEV                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_EC_DEBUGFS                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_EC_I2C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_EC_ISHTP                            policy<{'amd64': 'm'}>
+CONFIG_CROS_EC_LIGHTBAR                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_EC_LPC                              policy<{'amd64': 'm'}>
+CONFIG_CROS_EC_MKBP_PROXIMITY                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_EC_PROTO                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CROS_EC_RPMSG                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_EC_SENSORHUB                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_EC_SPI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_EC_SYSFS                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_EC_TYPEC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_EC_UART                             policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_CROS_EC_VBC                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_HPS_I2C                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_KBD_LED_BACKLIGHT                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_TYPEC_SWITCH                        policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_CROS_USBPD_LOGGER                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CROS_USBPD_NOTIFY                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_842                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_ACOMP2                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_ADIANTUM                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_AEAD                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_AEAD2                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_AEGIS128                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_AEGIS128_AESNI_SSE2               policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_AEGIS128_SIMD                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CRYPTO_AES                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_AES_ARM                           policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_AES_ARM64                         policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_AES_ARM64_BS                      policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_AES_ARM64_CE                      policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_AES_ARM64_CE_BLK                  policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_AES_ARM64_CE_CCM                  policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_AES_ARM64_NEON_BLK                policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_AES_ARM_BS                        policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_AES_ARM_CE                        policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_AES_NI_INTEL                      policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_AES_S390                          policy<{'s390x': 'm'}>
+CONFIG_CRYPTO_AES_TI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_AKCIPHER                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_AKCIPHER2                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_ALGAPI                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_ALGAPI2                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_ANSI_CPRNG                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_ARCH_HAVE_LIB_BLAKE2S             policy<{'amd64': 'y', 'armhf': 'y'}>
+CONFIG_CRYPTO_ARCH_HAVE_LIB_CHACHA              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_ARCH_HAVE_LIB_CURVE25519          policy<{'amd64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_ARIA                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_CRYPTO_ARIA_AESNI_AVX2_X86_64            policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_ARIA_AESNI_AVX_X86_64             policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_ARIA_GFNI_AVX512_X86_64           policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_AUTHENC                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_BLAKE2B                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_BLAKE2B_NEON                      policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_BLAKE2S_ARM                       policy<{'armhf': 'y'}>
+CONFIG_CRYPTO_BLAKE2S_X86                       policy<{'amd64': 'y'}>
+CONFIG_CRYPTO_BLOWFISH                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_BLOWFISH_COMMON                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_BLOWFISH_X86_64                   policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_CAMELLIA                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64        policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64         policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_CAMELLIA_X86_64                   policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_CAST5                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_CAST5_AVX_X86_64                  policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_CAST6                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_CAST6_AVX_X86_64                  policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_CAST_COMMON                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_CBC                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_CCM                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_CHACHA20                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_CHACHA20POLY1305                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_CHACHA20_NEON                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_CHACHA20_P10                      policy<{'ppc64el': 'm'}>
+CONFIG_CRYPTO_CHACHA20_X86_64                   policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_CHACHA_S390                       policy<{'s390x': 'm'}>
+CONFIG_CRYPTO_CMAC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_CRC32                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_CRC32C                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_CRC32C_INTEL                      policy<{'amd64': 'y'}>
+CONFIG_CRYPTO_CRC32C_VPMSUM                     policy<{'ppc64el': 'm'}>
+CONFIG_CRYPTO_CRC32_ARM_CE                      policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_CRC32_PCLMUL                      policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_CRC32_S390                        policy<{'s390x': 'm'}>
+CONFIG_CRYPTO_CRC64_ROCKSOFT                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_CRCT10DIF                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_CRCT10DIF_ARM64_CE                policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_CRCT10DIF_ARM_CE                  policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_CRCT10DIF_PCLMUL                  policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_CRCT10DIF_VPMSUM                  policy<{'ppc64el': 'm'}>
+CONFIG_CRYPTO_CRYPTD                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_CTR                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_CTS                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_CURVE25519                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_CURVE25519_NEON                   policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_CURVE25519_X86                    policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_DEFLATE                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_DES                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_DES3_EDE_X86_64                   policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_DES_S390                          policy<{'s390x': 'm'}>
+CONFIG_CRYPTO_DEV_ALLWINNER                     policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_CRYPTO_DEV_AMLOGIC_GXL                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CRYPTO_DEV_ARTPEC6                       policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_ASPEED                        policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_ASPEED_ACRY                   policy<{'armhf': 'y'}>
+CONFIG_CRYPTO_DEV_ASPEED_DEBUG                  policy<{'armhf': 'n'}>
+CONFIG_CRYPTO_DEV_ASPEED_HACE_CRYPTO            policy<{'armhf': 'y'}>
+CONFIG_CRYPTO_DEV_ASPEED_HACE_HASH              policy<{'armhf': 'y'}>
+CONFIG_CRYPTO_DEV_ATMEL_ECC                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_CRYPTO_DEV_ATMEL_I2C                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_ATMEL_SHA204A                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_CRYPTO_DEV_CAVIUM_ZIP                    policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_CCP                           policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_CRYPTO_DEV_CCP_CRYPTO                    policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_CCP_DD                        policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_CCP_DEBUGFS                   policy<{'amd64': 'n', 'arm64': 'n'}>
+CONFIG_CRYPTO_DEV_CCREE                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_CHELSIO                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_CPT                           policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_EXYNOS_RNG                    policy<{'armhf': 'n'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI        policy<{'arm64': 'y'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG                policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD      policy<{'arm64': '255', 'armhf': '255'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD       policy<{'arm64': '2048', 'armhf': '2048'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_JR                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE             policy<{'arm64': '9', 'armhf': '9'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_TEST             policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM                policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_HISI_HPRE                     policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_HISI_QM                       policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_HISI_SEC                      policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_HISI_SEC2                     policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_HISI_TRNG                     policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_HISI_ZIP                      policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_IAA_CRYPTO                    policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_DEV_IAA_CRYPTO_STATS              policy<{'amd64': 'n'}>
+CONFIG_CRYPTO_DEV_JH7110                        policy<{'arm64': '-', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4           policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS       policy<{'arm64': 'y'}>
+CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB       policy<{'arm64': 'y'}>
+CONFIG_CRYPTO_DEV_KEEMBAY_OCS_ECC               policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_KEEMBAY_OCS_HCU               policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_KEEMBAY_OCS_HCU_HMAC_SHA224   policy<{'arm64': 'y'}>
+CONFIG_CRYPTO_DEV_MARVELL                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_MARVELL_CESA                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_MXS_DCP                       policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_CRYPTO_DEV_NITROX                        policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_NITROX_CNN55XX                policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_CRYPTO_DEV_NX                            policy<{'ppc64el': 'y'}>
+CONFIG_CRYPTO_DEV_NX_COMPRESS                   policy<{'ppc64el': 'm'}>
+CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV           policy<{'ppc64el': 'm'}>
+CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES           policy<{'ppc64el': 'm'}>
+CONFIG_CRYPTO_DEV_OCTEONTX2_CPT                 policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_OCTEONTX_CPT                  policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_OMAP                          policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_OMAP_AES                      policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_OMAP_DES                      policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_OMAP_SHAM                     policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_PADLOCK                       policy<{'amd64': 'y'}>
+CONFIG_CRYPTO_DEV_PADLOCK_AES                   policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_DEV_PADLOCK_SHA                   policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_DEV_QAT                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_QAT_420XX                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_QAT_4XXX                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_QAT_C3XXX                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_QAT_C3XXXVF                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_QAT_C62X                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_QAT_C62XVF                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_QAT_DH895xCC                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_QAT_DH895xCCVF                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_CRYPTO_DEV_QCE                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_QCE_AEAD                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CRYPTO_DEV_QCE_ENABLE_AEAD               policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_CRYPTO_DEV_QCE_ENABLE_ALL                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CRYPTO_DEV_QCE_ENABLE_SHA                policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_CRYPTO_DEV_QCE_ENABLE_SKCIPHER           policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_CRYPTO_DEV_QCE_SHA                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CRYPTO_DEV_QCE_SKCIPHER                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CRYPTO_DEV_QCE_SW_MAX_LEN                policy<{'arm64': '512', 'armhf': '512'}>
+CONFIG_CRYPTO_DEV_QCOM_RNG                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_ROCKCHIP                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_CRYPTO_DEV_S5P                           policy<{'armhf': 'n'}>
+CONFIG_CRYPTO_DEV_SA2UL                         policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_SAFEXCEL                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_CRYPTO_DEV_SAHARA                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_DEV_SP_CCP                        policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_CRYPTO_DEV_SP_PSP                        policy<{'amd64': 'y'}>
+CONFIG_CRYPTO_DEV_STM32_CRC                     policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_STM32_CRYP                    policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_STM32_HASH                    policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_SUN4I_SS                      policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG                policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG                 policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_CRYPTO_DEV_SUN8I_CE                      policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG                policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_CRYPTO_DEV_SUN8I_CE_HASH                 policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG                 policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG                 policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_CRYPTO_DEV_SUN8I_SS                      policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG                policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_CRYPTO_DEV_SUN8I_SS_HASH                 policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_CRYPTO_DEV_SUN8I_SS_PRNG                 policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_CRYPTO_DEV_VIRTIO                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_DEV_VMX                           policy<{'ppc64el': 'y'}>
+CONFIG_CRYPTO_DEV_VMX_ENCRYPT                   policy<{'ppc64el': 'm'}>
+CONFIG_CRYPTO_DEV_ZYNQMP_AES                    policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DEV_ZYNQMP_SHA3                   policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_DH                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_DH_RFC7919_GROUPS                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_DRBG                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_DRBG_CTR                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_DRBG_HASH                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_DRBG_HMAC                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_DRBG_MENU                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_ECB                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_ECC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_ECDH                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_ECDSA                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_ECHAINIV                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_ECRDSA                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_ENGINE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_ESSIV                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_FCRYPT                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_GCM                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_GENIV                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_GHASH                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_GHASH_ARM64_CE                    policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_GHASH_ARM_CE                      policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL              policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_GHASH_S390                        policy<{'s390x': 'm'}>
+CONFIG_CRYPTO_HASH                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_HASH2                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_HASH_INFO                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_HCTR2                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_CRYPTO_HMAC                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_HW                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_JITTERENTROPY                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKS       policy<{'amd64': '64', 'arm64': '64', 'armhf': '64', 'ppc64el': '64', 'riscv64': '64', 's390x': '64'}>
+CONFIG_CRYPTO_JITTERENTROPY_MEMORY_BLOCKSIZE    policy<{'amd64': '32', 'arm64': '32', 'armhf': '32', 'ppc64el': '32', 'riscv64': '32', 's390x': '32'}>
+CONFIG_CRYPTO_JITTERENTROPY_OSR                 policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'ppc64el': '1', 'riscv64': '1', 's390x': '1'}>
+CONFIG_CRYPTO_KDF800108_CTR                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_KEYWRAP                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_KPP                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_KPP2                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_LIB_AES                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_LIB_ARC4                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC               policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_LIB_CHACHA                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_LIB_CHACHA20POLY1305              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_LIB_CHACHA_GENERIC                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_LIB_CURVE25519                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_LIB_CURVE25519_GENERIC            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_LIB_DES                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_LIB_GF128MUL                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_LIB_POLY1305                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_LIB_POLY1305_GENERIC              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_LIB_POLY1305_RSIZE                policy<{'amd64': '11', 'arm64': '9', 'armhf': '9', 'ppc64el': '1', 'riscv64': '1', 's390x': '1'}>
+CONFIG_CRYPTO_LIB_SHA1                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_LIB_SHA256                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_LIB_UTILS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_LRW                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_LZ4                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_LZ4HC                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_LZO                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_MANAGER                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_MANAGER2                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_MD4                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_MD5                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_MD5_PPC                           policy<{'ppc64el': 'm'}>
+CONFIG_CRYPTO_MICHAEL_MIC                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_NHPOLY1305                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_NHPOLY1305_AVX2                   policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_NHPOLY1305_NEON                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_NHPOLY1305_SSE2                   policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_NULL                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_NULL2                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_PAES_S390                         policy<{'s390x': 'm'}>
+CONFIG_CRYPTO_PCBC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_PCRYPT                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_POLY1305                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_POLY1305_ARM                      policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_POLY1305_NEON                     policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_POLY1305_P10                      policy<{'ppc64el': 'm'}>
+CONFIG_CRYPTO_POLY1305_X86_64                   policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_POLYVAL                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_POLYVAL_ARM64_CE                  policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_POLYVAL_CLMUL_NI                  policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_RMD160                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_RNG                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_RNG2                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_RNG_DEFAULT                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_RSA                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_SEQIV                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_SERPENT                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_SERPENT_AVX2_X86_64               policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_SERPENT_AVX_X86_64                policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_SERPENT_SSE2_X86_64               policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_SHA1                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_SHA1_ARM                          policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_SHA1_ARM64_CE                     policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_SHA1_ARM_CE                       policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_SHA1_ARM_NEON                     policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_SHA1_PPC                          policy<{'ppc64el': 'm'}>
+CONFIG_CRYPTO_SHA1_S390                         policy<{'s390x': 'm'}>
+CONFIG_CRYPTO_SHA1_SSSE3                        policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_SHA256                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_SHA256_ARM                        policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_SHA256_ARM64                      policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_SHA256_S390                       policy<{'s390x': 'm'}>
+CONFIG_CRYPTO_SHA256_SSSE3                      policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_SHA2_ARM64_CE                     policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_SHA2_ARM_CE                       policy<{'armhf': 'm'}>
+CONFIG_CRYPTO_SHA3                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_SHA3_256_S390                     policy<{'s390x': 'm'}>
+CONFIG_CRYPTO_SHA3_512_S390                     policy<{'s390x': 'm'}>
+CONFIG_CRYPTO_SHA3_ARM64                        policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_SIG                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_SIG2                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_SIMD                              policy<{'amd64': 'm', 'armhf': 'm'}>
+CONFIG_CRYPTO_SKCIPHER                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_SKCIPHER2                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_SM2                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_SM3                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_SM3_ARM64_CE                      policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_SM3_AVX_X86_64                    policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_SM3_GENERIC                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_CRYPTO_SM3_NEON                          policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_SM4                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_SM4_AESNI_AVX2_X86_64             policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_SM4_AESNI_AVX_X86_64              policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_SM4_ARM64_CE                      policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_SM4_ARM64_CE_BLK                  policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_SM4_ARM64_CE_CCM                  policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_SM4_ARM64_CE_GCM                  policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_SM4_ARM64_NEON_BLK                policy<{'arm64': 'm'}>
+CONFIG_CRYPTO_SM4_GENERIC                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_CRYPTO_STATS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_STREEBOG                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_TEST                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_TWOFISH                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_TWOFISH_AVX_X86_64                policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_TWOFISH_COMMON                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_TWOFISH_X86_64                    policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_TWOFISH_X86_64_3WAY               policy<{'amd64': 'm'}>
+CONFIG_CRYPTO_USER                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_USER_API                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_USER_API_AEAD                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_USER_API_HASH                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_USER_API_RNG                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_USER_API_RNG_CAVP                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CRYPTO_USER_API_SKCIPHER                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_VMAC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_VPMSUM_TESTER                     policy<{'ppc64el': 'm'}>
+CONFIG_CRYPTO_WP512                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_XCBC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_XCTR                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CRYPTO_XTS                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_CRYPTO_XXHASH                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CRYPTO_ZSTD                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CS89x0                                   policy<{'armhf': 'm'}>
+CONFIG_CS89x0_PLATFORM                          policy<{'armhf': 'm'}>
+CONFIG_CSD_LOCK_WAIT_DEBUG                      policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_CTCM                                     policy<{'s390x': 'm'}>
+CONFIG_CURRENT_POINTER_IN_TPIDRURO              policy<{'armhf': 'y'}>
+CONFIG_CUSE                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_CW1200                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CW1200_WLAN_SDIO                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CW1200_WLAN_SPI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CXD2880_SPI_DRV                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CXL                                      policy<{'ppc64el': 'm'}>
+CONFIG_CXLFLASH                                 policy<{'ppc64el': 'm'}>
+CONFIG_CXL_ACPI                                 policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': '-'}>
+CONFIG_CXL_BASE                                 policy<{'ppc64el': 'y'}>
+CONFIG_CXL_BUS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_CXL_MEM                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CXL_MEM_RAW_COMMANDS                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_CXL_PCI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CXL_PMEM                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CXL_PMU                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CXL_PORT                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_CXL_REGION                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CXL_REGION_INVALIDATION_TEST             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_CXL_SUSPEND                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_CX_ECAT                                  policy<{'amd64': 'm'}>
+CONFIG_CYPRESS_FIRMWARE                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DA280                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DA311                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DA9052_WATCHDOG                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DA9055_WATCHDOG                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DA9062_THERMAL                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DA9062_WATCHDOG                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DA9063_WATCHDOG                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DA9150_GPADC                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DAMON                                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DASD                                     policy<{'s390x': 'm'}>
+CONFIG_DASD_DIAG                                policy<{'s390x': 'm'}>
+CONFIG_DASD_ECKD                                policy<{'s390x': 'm'}>
+CONFIG_DASD_EER                                 policy<{'s390x': 'y'}>
+CONFIG_DASD_FBA                                 policy<{'s390x': 'm'}>
+CONFIG_DASD_PROFILE                             policy<{'s390x': 'y'}>
+CONFIG_DATA_SHIFT                               policy<{'ppc64el': '24'}>
+CONFIG_DAVICOM_PHY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DAX                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DA_MON_EVENTS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DA_MON_EVENTS_ID                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DCA                                      policy<{'amd64': 'm'}>
+CONFIG_DCACHE_WORD_ACCESS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_DCB                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DCDBAS                                   policy<{'amd64': 'm'}>
+CONFIG_DCSSBLK                                  policy<{'s390x': 'm'}>
+CONFIG_DDR                                      policy<{'armhf': 'y'}>
+CONFIG_DE2104X                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DE2104X_DSL                              policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0'}>
+CONFIG_DEBUGGER                                 policy<{'ppc64el': 'y'}>
+CONFIG_DEBUG_ALIGN_RODATA                       policy<{'armhf': 'y'}>
+CONFIG_DEBUG_ATOMIC_SLEEP                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_BOOT_PARAMS                        policy<{'amd64': 'n'}>
+CONFIG_DEBUG_BUGVERBOSE                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEBUG_CGROUP_REF                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_CLOSURES                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_DEVRES                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_DRIVER                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_EFI                                policy<{'arm64': 'n'}>
+CONFIG_DEBUG_ENTRY                              policy<{'amd64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_64B           policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_FORCE_WEAK_PER_CPU                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_FS_ALLOW_ALL                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEBUG_FS_ALLOW_NONE                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_FS_DISALLOW_MOUNT                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_GPIO                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_HIGHMEM                            policy<{'armhf': 'n'}>
+CONFIG_DEBUG_INFO_BTF_MODULES                   policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEBUG_INFO_COMPRESSED_NONE               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEBUG_INFO_COMPRESSED_ZLIB               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_INFO_COMPRESSED_ZSTD               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_INFO_DWARF4                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_INFO_DWARF5                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_INFO_NONE                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_INFO_REDUCED                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_IRQFLAGS                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_KERNEL_DC                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_DEBUG_KMAP_LOCAL                         policy<{'armhf': 'n'}>
+CONFIG_DEBUG_KMEMLEAK                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_KOBJECT                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_LIST                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_LL                                 policy<{'armhf': 'n'}>
+CONFIG_DEBUG_LL_INCLUDE                         policy<{'armhf': '"mach/debug-macro.S"'}>
+CONFIG_DEBUG_LOCKING_API_SELFTESTS              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_LOCK_ALLOC                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_MAPLE_TREE                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_MEMORY_INIT                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_MISC                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEBUG_MUTEXES                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_NET                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_NMI_SELFTEST                       policy<{'amd64': 'n'}>
+CONFIG_DEBUG_NOTIFIERS                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_OBJECTS                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_PAGEALLOC                          policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_PAGE_REF                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_PERF_USE_VMALLOC                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_PER_CPU_MAPS                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_PINCTRL                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_DEBUG_PLIST                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_PREEMPT                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': '-', 'ppc64el': '-', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_DEBUG_RODATA_TEST                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_RSEQ                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_RT_MUTEXES                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_RWSEMS                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_SECTION_MISMATCH                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_SG                                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_SHIRQ                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_SPINLOCK                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_STACKOVERFLOW                      policy<{'ppc64el': 'n'}>
+CONFIG_DEBUG_STACK_USAGE                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_TEST_DRIVER_REMOVE                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_TIMEKEEPING                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_TLBFLUSH                           policy<{'amd64': 'n'}>
+CONFIG_DEBUG_USER                               policy<{'armhf': 'n'}>
+CONFIG_DEBUG_VF_UART_PORT                       policy<{'armhf': '1'}>
+CONFIG_DEBUG_VIRTUAL                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_DEBUG_VM                                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_VM_PGTABLE                         policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_WQ_FORCE_RR_CPU                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_WW_MUTEX_SLOWPATH                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEBUG_WX                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DECOMPRESS_BZIP2                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DECOMPRESS_GZIP                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DECOMPRESS_LZ4                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DECOMPRESS_LZMA                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DECOMPRESS_LZO                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DECOMPRESS_XZ                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DECOMPRESS_ZSTD                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEFAULT_CUBIC                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEFAULT_HOSTNAME                         policy<{'amd64': '"(none)"', 'arm64': '"(none)"', 'armhf': '"(none)"', 'ppc64el': '"(none)"', 'riscv64': '"(none)"', 's390x': '"(none)"'}>
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT                policy<{'amd64': '120', 'arm64': '120', 'armhf': '120', 'ppc64el': '120', 'riscv64': '120', 's390x': '120'}>
+CONFIG_DEFAULT_INIT                             policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'ppc64el': '""', 'riscv64': '""', 's390x': '""'}>
+CONFIG_DEFAULT_RENO                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEFAULT_SECURITY_APPARMOR                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEFAULT_SECURITY_DAC                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEFAULT_SECURITY_SELINUX                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEFAULT_SECURITY_SMACK                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEFAULT_SECURITY_TOMOYO                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEFAULT_TCP_CONG                         policy<{'amd64': '"cubic"', 'arm64': '"cubic"', 'armhf': '"cubic"', 'ppc64el': '"cubic"', 'riscv64': '"cubic"', 's390x': '"cubic"'}>
+CONFIG_DEFERRED_STRUCT_PAGE_INIT                policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DEFXX                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DELL_LAPTOP                              policy<{'amd64': 'm'}>
+CONFIG_DELL_RBTN                                policy<{'amd64': 'm'}>
+CONFIG_DELL_RBU                                 policy<{'amd64': 'm'}>
+CONFIG_DELL_SMBIOS                              policy<{'amd64': 'm'}>
+CONFIG_DELL_SMBIOS_SMM                          policy<{'amd64': 'y'}>
+CONFIG_DELL_SMBIOS_WMI                          policy<{'amd64': 'y'}>
+CONFIG_DELL_SMO8800                             policy<{'amd64': 'm'}>
+CONFIG_DELL_UART_BACKLIGHT                      policy<{'amd64': 'n'}>
+CONFIG_DELL_WMI                                 policy<{'amd64': 'm'}>
+CONFIG_DELL_WMI_AIO                             policy<{'amd64': 'm'}>
+CONFIG_DELL_WMI_DDV                             policy<{'amd64': 'm'}>
+CONFIG_DELL_WMI_DESCRIPTOR                      policy<{'amd64': 'm'}>
+CONFIG_DELL_WMI_LED                             policy<{'amd64': 'm'}>
+CONFIG_DELL_WMI_PRIVACY                         policy<{'amd64': 'y'}>
+CONFIG_DELL_WMI_SYSMAN                          policy<{'amd64': 'm'}>
+CONFIG_DEPRECATED_PARAM_STRUCT                  policy<{'armhf': 'n'}>
+CONFIG_DETECT_HUNG_TASK                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP                policy<{'armhf': 'n'}>
+CONFIG_DEVFREQ_EVENT_EXYNOS_PPMU                policy<{'armhf': 'n'}>
+CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DEVFREQ_GOV_PASSIVE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DEVFREQ_GOV_PERFORMANCE                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DEVFREQ_GOV_POWERSAVE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DEVFREQ_GOV_USERSPACE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DEVFREQ_THERMAL                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DEVICE_MIGRATION                         policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_DEVICE_PRIVATE                           policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_DEVMEM                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEVPORT                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_DEVTMPFS_SAFE                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DEV_COREDUMP                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DEV_DAX                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DEV_DAX_CXL                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DEV_DAX_HMEM                             policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_DEV_DAX_HMEM_DEVICES                     policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_DEV_DAX_KMEM                             policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 's390x': 'm'}>
+CONFIG_DEV_DAX_PMEM                             policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}>
+CONFIG_DEV_SYNC_PROBE                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DHT11                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DIAG288_WATCHDOG                         policy<{'s390x': 'm'}>
+CONFIG_DIMLIB                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DL2K                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DLHL60D                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DLM                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DLM_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DLN2_ADC                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DM9000                                   policy<{'armhf': 'm'}>
+CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL             policy<{'armhf': 'n'}>
+CONFIG_DM9051                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DM9102                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DMABUF_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DMABUF_HEAPS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DMABUF_HEAPS_CMA                         policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_DMABUF_HEAPS_SYSTEM                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DMABUF_MOVE_NOTIFY                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_DMABUF_SELFTESTS                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DMABUF_SYSFS_STATS                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DMADEVICES                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_DMADEVICES_DEBUG                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_DMAPOOL_TEST                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DMARD06                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DMARD09                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DMARD10                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DMAR_TABLE                               policy<{'amd64': 'y'}>
+CONFIG_DMATEST                                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_DMA_ACPI                                 policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_DMA_API_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DMA_BOUNCE_UNALIGNED_KMALLOC             policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_DMA_COHERENT_POOL                        policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_DMA_DECLARE_COHERENT                     policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DMA_DIRECT_REMAP                         policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_DMA_ENGINE                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DMA_ENGINE_RAID                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DMA_FENCE_TRACE                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DMA_MAP_BENCHMARK                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DMA_NONCOHERENT_MMAP                     policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_DMA_NUMA_CMA                             policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_DMA_OF                                   policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DMA_OMAP                                 policy<{'armhf': 'y'}>
+CONFIG_DMA_OPS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DMA_OPS_BYPASS                           policy<{'ppc64el': 'y'}>
+CONFIG_DMA_RESTRICTED_POOL                      policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DMA_SHARED_BUFFER                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DMA_SUN6I                                policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_DMA_VIRTUAL_CHANNELS                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'y'}>
+CONFIG_DMI                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DMIID                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK        policy<{'amd64': 'y'}>
+CONFIG_DMI_SYSFS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DM_AUDIT                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DM_BIO_PRISON                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_BUFIO                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_CACHE                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_CACHE_SMQ                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_CLONE                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_CRYPT                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_DEBUG                                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'y'}>
+CONFIG_DM_DEBUG_BLOCK_MANAGER_LOCKING           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DM_DELAY                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_DUST                                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DM_EBS                                   policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_ERA                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_FLAKEY                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_INIT                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DM_INTEGRITY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_LOG_USERSPACE                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_LOG_WRITES                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_MIRROR                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_MULTIPATH                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_MULTIPATH_HST                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_MULTIPATH_IOA                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_MULTIPATH_QL                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_MULTIPATH_ST                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_PERSISTENT_DATA                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_RAID                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_SNAPSHOT                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_SWITCH                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_THIN_PROVISIONING                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_UEVENT                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DM_UNSTRIPED                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_VERITY                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_VERITY_FEC                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DM_WRITECACHE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_ZERO                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DM_ZONED                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DNET                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DNOTIFY                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DNS_RESOLVER                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DOVE_CLK                                 policy<{'armhf': 'y'}>
+CONFIG_DOVE_THERMAL                             policy<{'armhf': 'm'}>
+CONFIG_DP83640_PHY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DP83822_PHY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DP83848_PHY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DP83867_PHY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DP83869_PHY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DP83TC811_PHY                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DP83TD510_PHY                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DP83TG720_PHY                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DPAA2_CONSOLE                            policy<{'arm64': 'm'}>
+CONFIG_DPAA_ERRATUM_A050385                     policy<{'arm64': 'y'}>
+CONFIG_DPLL                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DPM_WATCHDOG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_DPOT_DAC                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DPS310                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DPTF_PCH_FIVR                            policy<{'amd64': 'm'}>
+CONFIG_DPTF_POWER                               policy<{'amd64': 'm'}>
+CONFIG_DQL                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DRAGONRISE_FF                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRBD_FAULT_INJECTION                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DRM_ACCEL                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_DRM_ACCEL_HABANALABS                     policy<{'amd64': 'm'}>
+CONFIG_DRM_ACCEL_IVPU                           policy<{'amd64': 'm'}>
+CONFIG_DRM_ACCEL_QAIC                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_AMDGPU                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_AMDGPU_SI                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_AMDGPU_USERPTR                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_AMDGPU_WERROR                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'n'}>
+CONFIG_DRM_AMD_ACP                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_AMD_DC                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_AMD_DC_FP                            policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_DRM_AMD_DC_SI                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_AMD_SECURE_DISPLAY                   policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_DRM_ANALOGIX_ANX6345                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_ANALOGIX_ANX7625                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_ANALOGIX_ANX78XX                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_ANALOGIX_DP                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_ARCPGU                               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_ARMADA                               policy<{'armhf': 'm'}>
+CONFIG_DRM_ASPEED_GFX                           policy<{'armhf': 'm'}>
+CONFIG_DRM_AST                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_ATMEL_HLCDC                          policy<{'armhf': 'm'}>
+CONFIG_DRM_AUX_BRIDGE                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_AUX_HPD_BRIDGE                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_BOCHS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DRM_BRIDGE                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DRM_BUDDY                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_CDNS_DSI                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_CDNS_DSI_J721E                       policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_CDNS_MHDP8546                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_CDNS_MHDP8546_J721E                  policy<{'arm64': 'y'}>
+CONFIG_DRM_CHIPONE_ICN6211                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_CHRONTEL_CH7033                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_CIRRUS_QEMU                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_CROS_EC_ANX7688                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_DEBUG_DP_MST_TOPOLOGY_REFS           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DRM_DEBUG_MM                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_DRM_DEBUG_MODESET_LOCK                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DRM_DISPLAY_CONNECTOR                    policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_DISPLAY_DP_HELPER                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_DISPLAY_HDCP_HELPER                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_DISPLAY_HDMI_HELPER                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_DISPLAY_HELPER                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_DP_AUX_BUS                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_DP_AUX_CHARDEV                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_DP_CEC                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_DW_HDMI                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': 'm'}>
+CONFIG_DRM_DW_HDMI_AHB_AUDIO                    policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': 'm'}>
+CONFIG_DRM_DW_HDMI_CEC                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': 'm'}>
+CONFIG_DRM_DW_HDMI_GP_AUDIO                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': 'm'}>
+CONFIG_DRM_DW_HDMI_I2S_AUDIO                    policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': 'm'}>
+CONFIG_DRM_DW_MIPI_DSI                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_ETNAVIV                              policy<{'amd64': 'n', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DRM_ETNAVIV_THERMAL                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_EXEC                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_EXYNOS                               policy<{'armhf': 'm'}>
+CONFIG_DRM_EXYNOS5433_DECON                     policy<{'armhf': 'y'}>
+CONFIG_DRM_EXYNOS7_DECON                        policy<{'armhf': 'n'}>
+CONFIG_DRM_EXYNOS_DSI                           policy<{'armhf': 'y'}>
+CONFIG_DRM_EXYNOS_FIMC                          policy<{'armhf': 'y'}>
+CONFIG_DRM_EXYNOS_FIMD                          policy<{'armhf': 'n'}>
+CONFIG_DRM_EXYNOS_G2D                           policy<{'armhf': 'y'}>
+CONFIG_DRM_EXYNOS_GSC                           policy<{'armhf': 'y'}>
+CONFIG_DRM_EXYNOS_HDMI                          policy<{'armhf': 'y'}>
+CONFIG_DRM_EXYNOS_IPP                           policy<{'armhf': 'y'}>
+CONFIG_DRM_EXYNOS_MIC                           policy<{'armhf': 'y'}>
+CONFIG_DRM_EXYNOS_MIXER                         policy<{'armhf': 'y'}>
+CONFIG_DRM_EXYNOS_ROTATOR                       policy<{'armhf': 'y'}>
+CONFIG_DRM_EXYNOS_SCALER                        policy<{'armhf': 'y'}>
+CONFIG_DRM_EXYNOS_VIDI                          policy<{'armhf': 'n'}>
+CONFIG_DRM_FBDEV_EMULATION                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_DRM_FBDEV_OVERALLOC                      policy<{'amd64': '100', 'arm64': '100', 'armhf': '100', 'ppc64el': '100', 'riscv64': '100', 's390x': '100'}>
+CONFIG_DRM_FSL_DCU                              policy<{'armhf': 'm'}>
+CONFIG_DRM_FSL_LDB                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_GEM_DMA_HELPER                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_GEM_SHMEM_HELPER                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_DRM_GM12U320                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DRM_GMA500                               policy<{'amd64': 'm'}>
+CONFIG_DRM_GPUVM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_GUD                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DRM_HDLCD                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_HDLCD_SHOW_UNDERRUN                  policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_DRM_HISI_KIRIN                           policy<{'arm64': 'm'}>
+CONFIG_DRM_HYPERV                               policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_DRM_I2C_ADV7511                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_I2C_ADV7511_AUDIO                    policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_I2C_ADV7511_CEC                      policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_I2C_CH7006                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_I2C_NXP_TDA9950                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_I2C_NXP_TDA998X                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_I2C_SIL164                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_I915                                 policy<{'amd64': 'm'}>
+CONFIG_DRM_I915_CAPTURE_ERROR                   policy<{'amd64': 'y'}>
+CONFIG_DRM_I915_COMPRESS_ERROR                  policy<{'amd64': 'y'}>
+CONFIG_DRM_I915_DEBUG                           policy<{'amd64': 'n'}>
+CONFIG_DRM_I915_DEBUG_GUC                       policy<{'amd64': 'n'}>
+CONFIG_DRM_I915_DEBUG_MMIO                      policy<{'amd64': 'n'}>
+CONFIG_DRM_I915_DEBUG_RUNTIME_PM                policy<{'amd64': 'n'}>
+CONFIG_DRM_I915_DEBUG_VBLANK_EVADE              policy<{'amd64': 'n'}>
+CONFIG_DRM_I915_DEBUG_WAKEREF                   policy<{'amd64': 'n'}>
+CONFIG_DRM_I915_FENCE_TIMEOUT                   policy<{'amd64': '10000'}>
+CONFIG_DRM_I915_FORCE_PROBE                     policy<{'amd64': '""'}>
+CONFIG_DRM_I915_GVT                             policy<{'amd64': 'y'}>
+CONFIG_DRM_I915_GVT_KVMGT                       policy<{'amd64': 'm'}>
+CONFIG_DRM_I915_HEARTBEAT_INTERVAL              policy<{'amd64': '2500'}>
+CONFIG_DRM_I915_LOW_LEVEL_TRACEPOINTS           policy<{'amd64': 'n'}>
+CONFIG_DRM_I915_MAX_REQUEST_BUSYWAIT            policy<{'amd64': '8000'}>
+CONFIG_DRM_I915_PREEMPT_TIMEOUT                 policy<{'amd64': '640'}>
+CONFIG_DRM_I915_PREEMPT_TIMEOUT_COMPUTE         policy<{'amd64': '7500'}>
+CONFIG_DRM_I915_PXP                             policy<{'amd64': 'y'}>
+CONFIG_DRM_I915_REQUEST_TIMEOUT                 policy<{'amd64': '20000'}>
+CONFIG_DRM_I915_SELFTEST                        policy<{'amd64': 'n'}>
+CONFIG_DRM_I915_STOP_TIMEOUT                    policy<{'amd64': '100'}>
+CONFIG_DRM_I915_SW_FENCE_CHECK_DAG              policy<{'amd64': 'n'}>
+CONFIG_DRM_I915_SW_FENCE_DEBUG_OBJECTS          policy<{'amd64': 'n'}>
+CONFIG_DRM_I915_TIMESLICE_DURATION              policy<{'amd64': '1'}>
+CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND           policy<{'amd64': '250'}>
+CONFIG_DRM_I915_USERPTR                         policy<{'amd64': 'y'}>
+CONFIG_DRM_I915_WERROR                          policy<{'amd64': 'n'}>
+CONFIG_DRM_IMX                                  policy<{'armhf': 'm'}>
+CONFIG_DRM_IMX8QM_LDB                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_IMX8QXP_LDB                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_IMX8QXP_PIXEL_COMBINER               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_IMX8QXP_PIXEL_LINK                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_IMX93_MIPI_DSI                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_IMX_DCSS                             policy<{'arm64': 'm'}>
+CONFIG_DRM_IMX_HDMI                             policy<{'armhf': 'm'}>
+CONFIG_DRM_IMX_LCDC                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_IMX_LCDIF                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_DRM_IMX_LDB                              policy<{'armhf': 'm'}>
+CONFIG_DRM_IMX_LDB_HELPER                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_IMX_PARALLEL_DISPLAY                 policy<{'armhf': 'm'}>
+CONFIG_DRM_IMX_TVE                              policy<{'armhf': 'm'}>
+CONFIG_DRM_ITE_IT6505                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_ITE_IT66121                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_KMB_DISPLAY                          policy<{'arm64': 'm'}>
+CONFIG_DRM_KMS_HELPER                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_DRM_KOMEDA                               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_LIMA                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_LOAD_EDID_FIRMWARE                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DRM_LOGICVC                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_LONTIUM_LT8912B                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_LONTIUM_LT9211                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_LONTIUM_LT9611                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_LONTIUM_LT9611UXC                    policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_LVDS_CODEC                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_MALI_DISPLAY                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_MCDE                                 policy<{'armhf': 'm'}>
+CONFIG_DRM_MEDIATEK                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_MEDIATEK_DP                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_MEDIATEK_HDMI                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_MESON                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_MESON_DW_HDMI                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_MESON_DW_MIPI_DSI                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_MIPI_DBI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_MIPI_DSI                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_MSM                                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_MSM_DP                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MSM_DPU                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MSM_DSI                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MSM_DSI_10NM_PHY                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MSM_DSI_14NM_PHY                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MSM_DSI_20NM_PHY                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MSM_DSI_28NM_8960_PHY                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MSM_DSI_28NM_PHY                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MSM_DSI_7NM_PHY                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MSM_GPU_STATE                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MSM_GPU_SUDO                         policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_DRM_MSM_HDMI                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MSM_HDMI_HDCP                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MSM_MDP4                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MSM_MDP5                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MSM_MDSS                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_MXS                                  policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_DRM_MXSFB                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_DRM_NOUVEAU                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_NOUVEAU_BACKLIGHT                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_NOUVEAU_GSP_DEFAULT                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_DRM_NOUVEAU_SVM                          policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n'}>
+CONFIG_DRM_NWL_MIPI_DSI                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_NXP_PTN3460                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_OFDRM                                policy<{'ppc64el': 'm'}>
+CONFIG_DRM_OMAP                                 policy<{'armhf': 'n'}>
+CONFIG_DRM_PANEL                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DRM_PANEL_ABT_Y030XX067A                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_ARM_VERSATILE                  policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_ASUS_Z00T_TM5P5_NT35596        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_AUO_A030JTN01                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_BOE_BF060Y8M_AJ0               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_BOE_HIMAX8279D                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_BOE_TV101WUM_NL6               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_BRIDGE                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DRM_PANEL_DSI_CM                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_EBBG_FT8719                    policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_EDP                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_ELIDA_KD35T133                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_FEIYANG_FY07024DI26A30D        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_HIMAX_HX8394                   policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_ILITEK_IL9322                  policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_ILITEK_ILI9341                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_ILITEK_ILI9805                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_ILITEK_ILI9881C                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_ILITEK_ILI9882T                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_INNOLUX_EJ030NA                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_INNOLUX_P079ZCA                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_JADARD_JD9365DA_H3             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_JDI_LPM102A188A                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_JDI_LT070ME05000               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_JDI_R63452                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_KHADAS_TS050                   policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_LEADTEK_LTK050H3146W           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_LEADTEK_LTK500HD1829           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_LG_LB035Q02                    policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_LG_LG4573                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_LVDS                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_MAGNACHIP_D53E6EA8966          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_MANTIX_MLAF057WE51             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_MIPI_DBI                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_NEC_NL8048HL11                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_NEWVISION_NV3051D              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_NEWVISION_NV3052C              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_NOVATEK_NT35510                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_NOVATEK_NT35560                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_NOVATEK_NT35950                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_NOVATEK_NT36523                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_NOVATEK_NT36672A               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_NOVATEK_NT39016                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_DRM_PANEL_ORISETECH_OTA5601A             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_ORISETECH_OTM8009A             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_RAYDIUM_RM67191                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_RAYDIUM_RM68200                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_RAYDIUM_RM692E5                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_RONBO_RB070D30                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SAMSUNG_DB7430                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SAMSUNG_LD9040                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SAMSUNG_S6D16D0                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SAMSUNG_S6D27A1                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SAMSUNG_S6D7AA0                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SAMSUNG_S6E63M0                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_DSI            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SAMSUNG_S6E63M0_SPI            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SAMSUNG_SOFEF00                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SEIKO_43WVF1G                  policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SHARP_LQ101R1SX01              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SHARP_LS037V7DW01              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SHARP_LS043T1LE01              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SHARP_LS060T1SX01              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SIMPLE                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SITRONIX_ST7701                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SITRONIX_ST7703                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SITRONIX_ST7789V               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SONY_ACX565AKM                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SONY_TD4353_JDI                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SONY_TULIP_TRULY_NT35521       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_STARTEK_KD070FHFID015          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_SYNAPTICS_R63353               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_TDO_TL070WSH30                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_TPO_TD028TTEC1                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_TPO_TD043MTEA1                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_TPO_TPG110                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_VISIONOX_R66451                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_VISIONOX_RM69299               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_VISIONOX_VTDR6130              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANEL_WIDECHIPS_WS2401               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DRM_PANEL_XINPENG_XPP055C272             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PANFROST                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_PARADE_PS8622                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PARADE_PS8640                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_PL111                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_POWERVR                              policy<{'arm64': 'm'}>
+CONFIG_DRM_PRIVACY_SCREEN                       policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_DRM_QXL                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_RADEON                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_RADEON_USERPTR                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_DRM_RCAR_CMM                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_RCAR_DU                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_RCAR_DW_HDMI                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_DRM_RCAR_LVDS                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': '-'}>
+CONFIG_DRM_RCAR_MIPI_DSI                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_RCAR_USE_CMM                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_RCAR_USE_LVDS                        policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_DRM_RCAR_USE_MIPI_DSI                    policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_DRM_RCAR_VSP                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_RCAR_WRITEBACK                       policy<{'arm64': 'y'}>
+CONFIG_DRM_ROCKCHIP                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_RZG2L_MIPI_DSI                       policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_SAMSUNG_DSIM                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_SCHED                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_SHMOBILE                             policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_SII902X                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_SII9234                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_SIL_SII8620                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_SIMPLE_BRIDGE                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_SPRD                                 policy<{'arm64': 'm'}>
+CONFIG_DRM_SSD130X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_SSD130X_I2C                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_SSD130X_SPI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_STM                                  policy<{'arm64': 'm'}>
+CONFIG_DRM_STM_DSI                              policy<{'arm64': 'm'}>
+CONFIG_DRM_SUBALLOC_HELPER                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_SUN4I                                policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_DRM_SUN6I_DSI                            policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_DRM_SUN8I_DW_HDMI                        policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_DRM_SUN8I_MIXER                          policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_DRM_SUN8I_TCON_TOP                       policy<{'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_TEGRA                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_TEGRA_DEBUG                          policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_DRM_TEGRA_STAGING                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DRM_THINE_THC63LVD1024                   policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_TIDSS                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DRM_TILCDC                               policy<{'armhf': 'm'}>
+CONFIG_DRM_TI_DLPC3433                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_TI_SN65DSI83                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_TI_SN65DSI86                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_TI_TFP410                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_TI_TPD12S015                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_TOSHIBA_TC358762                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_TOSHIBA_TC358764                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_TOSHIBA_TC358767                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_TOSHIBA_TC358768                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_TOSHIBA_TC358775                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DRM_TTM                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DRM_TTM_HELPER                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DRM_TVE200                               policy<{'armhf': 'm'}>
+CONFIG_DRM_UDL                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DRM_VGEM                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_VIRTIO_GPU                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DRM_VIRTIO_GPU_KMS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DRM_VKMS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_VMWGFX                               policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_DRM_VMWGFX_MKSSTATS                      policy<{'amd64': 'n'}>
+CONFIG_DRM_VRAM_HELPER                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DRM_XE                                   policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DRM_XEN                                  policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_DRM_XEN_FRONTEND                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_DRM_XE_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_DRM_XE_DEBUG_MEM                         policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_DRM_XE_DEBUG_SRIOV                       policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_DRM_XE_DEBUG_VM                          policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_DRM_XE_DISPLAY                           policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_XE_ENABLE_SCHEDTIMEOUT_LIMIT         policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DRM_XE_FORCE_PROBE                       policy<{'amd64': '""', 'arm64': '""', 'ppc64el': '""', 'riscv64': '""'}>
+CONFIG_DRM_XE_JOB_TIMEOUT_MAX                   policy<{'amd64': '10000', 'arm64': '10000', 'ppc64el': '10000', 'riscv64': '10000'}>
+CONFIG_DRM_XE_JOB_TIMEOUT_MIN                   policy<{'amd64': '1', 'arm64': '1', 'ppc64el': '1', 'riscv64': '1'}>
+CONFIG_DRM_XE_LARGE_GUC_BUFFER                  policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_DRM_XE_PREEMPT_TIMEOUT                   policy<{'amd64': '640000', 'arm64': '640000', 'ppc64el': '640000', 'riscv64': '640000'}>
+CONFIG_DRM_XE_PREEMPT_TIMEOUT_MAX               policy<{'amd64': '10000000', 'arm64': '10000000', 'ppc64el': '10000000', 'riscv64': '10000000'}>
+CONFIG_DRM_XE_PREEMPT_TIMEOUT_MIN               policy<{'amd64': '1', 'arm64': '1', 'ppc64el': '1', 'riscv64': '1'}>
+CONFIG_DRM_XE_SIMPLE_ERROR_CAPTURE              policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_DRM_XE_TIMESLICE_MAX                     policy<{'amd64': '10000000', 'arm64': '10000000', 'ppc64el': '10000000', 'riscv64': '10000000'}>
+CONFIG_DRM_XE_TIMESLICE_MIN                     policy<{'amd64': '1', 'arm64': '1', 'ppc64el': '1', 'riscv64': '1'}>
+CONFIG_DRM_XE_USERPTR_INVAL_INJECT              policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_DRM_XE_WERROR                            policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_DRM_ZYNQMP_DPSUB                         policy<{'arm64': 'm'}>
+CONFIG_DS1682                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DS1803                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DS4424                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DST_CACHE                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DTC                                      policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DTL                                      policy<{'ppc64el': 'y'}>
+CONFIG_DTPM                                     policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DTPM_CPU                                 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DTPM_DEVFREQ                             policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_DT_IDLE_GENPD                            policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_DT_IDLE_STATES                           policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_DUMMY                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DUMMY_CONSOLE                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DUMMY_CONSOLE_COLUMNS                    policy<{'amd64': '80', 'arm64': '80', 'armhf': '80', 'ppc64el': '80', 'riscv64': '80', 's390x': '80'}>
+CONFIG_DUMMY_CONSOLE_ROWS                       policy<{'amd64': '25', 'arm64': '25', 'armhf': '30', 'ppc64el': '25', 'riscv64': '25', 's390x': '25'}>
+CONFIG_DUMMY_IRQ                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DVB_A8293                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_AF9013                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_AF9033                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_AS102                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_AS102_FE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_ASCOT2E                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_ATBM8830                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_AU8522                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_AU8522_DTV                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_AU8522_V4L                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_AV7110                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_AV7110_IR                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DVB_AV7110_OSD                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DVB_B2C2_FLEXCOP                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_B2C2_FLEXCOP_PCI                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_B2C2_FLEXCOP_PCI_DEBUG               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_DVB_B2C2_FLEXCOP_USB                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_B2C2_FLEXCOP_USB_DEBUG               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_DVB_BCM3510                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_BT8XX                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_BUDGET                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_BUDGET_AV                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_BUDGET_CI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_BUDGET_CORE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_BUDGET_PATCH                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_C8SECTPFE                            policy<{'armhf': 'n'}>
+CONFIG_DVB_CORE                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_CX22700                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_CX22702                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_CX24110                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_CX24116                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_CX24117                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_CX24120                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_CX24123                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_CXD2099                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_CXD2820R                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_CXD2841ER                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_CXD2880                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_DDBRIDGE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_DDBRIDGE_MSIENABLE                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_DVB_DEMUX_SECTION_LOSS_LOG               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_DVB_DIB3000MB                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_DIB3000MC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_DIB7000M                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_DIB7000P                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_DIB8000                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_DIB9000                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_DM1105                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_DRX39XYJ                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_DRXD                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_DRXK                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_DS3000                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_DYNAMIC_MINORS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DVB_EC100                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_FIREDTV                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_FIREDTV_INPUT                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DVB_GP8PSK_FE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_HELENE                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_HOPPER                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_HORUS3A                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_ISL6405                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_ISL6421                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_ISL6423                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_IX2505V                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_L64781                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_LG2160                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_LGDT3305                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_LGDT3306A                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_LGDT330X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_LGS8GL5                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_LGS8GXX                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_LNBH25                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_LNBH29                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_LNBP21                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_LNBP22                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_M88DS3103                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_M88RS2000                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_MANTIS                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_MAX_ADAPTERS                         policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'ppc64el': '8', 'riscv64': '8'}>
+CONFIG_DVB_MB86A16                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_MB86A20S                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_MMAP                                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_DVB_MN88443X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_MN88472                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_MN88473                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_MT312                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_MT352                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_MXL5XX                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_MXL692                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_NET                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DVB_NETUP_UNIDVB                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_NGENE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_NXT200X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_NXT6000                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_OR51132                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_OR51211                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_PLATFORM_DRIVERS                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DVB_PLL                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_PLUTO2                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_PT1                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_PT3                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_RTL2830                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_RTL2832                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_RTL2832_SDR                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_S5H1409                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_S5H1411                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_S5H1420                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_S5H1432                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_S921                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_SI2165                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_SI2168                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_SI21XX                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_SMIPCIE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_SP2                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_SP8870                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_SP887X                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_STB0899                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_STB6000                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_STB6100                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_STV0288                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_STV0297                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_STV0299                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_STV0367                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_STV0900                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_STV090x                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_STV0910                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_STV6110                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_STV6110x                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_STV6111                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TC90522                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TDA10021                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TDA10023                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TDA10048                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TDA1004X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TDA10071                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TDA10086                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TDA18271C2DD                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TDA665x                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TDA8083                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TDA8261                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TDA826X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TEST_DRIVERS                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_DVB_TS2020                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TTUSB_BUDGET                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TTUSB_DEC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TUA6100                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TUNER_CX24113                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TUNER_DIB0070                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TUNER_DIB0090                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_TUNER_ITD1000                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_ULE_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_DVB_USB                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_A800                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_AF9005                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_AF9005_REMOTE                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_AF9015                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_AF9035                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_ANYSEE                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_AU6610                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_AZ6007                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_AZ6027                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_CE6230                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_CINERGY_T2                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_CXUSB                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_CXUSB_ANALOG                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_DVB_USB_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_DVB_USB_DIB0700                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_DIB3000MC                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_DIBUSB_MB                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_DIBUSB_MB_FAULTY                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_DVB_USB_DIBUSB_MC                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_DIGITV                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_DTT200U                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_DTV5100                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_DVBSKY                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_DW2102                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_EC168                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_GL861                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_GP8PSK                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_LME2510                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_M920X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_MXL111SF                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_NOVA_T_USB2                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_OPERA1                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_PCTV452E                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_RTL28XXU                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_TECHNISAT_USB2                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_TTUSB2                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_UMT_010                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_V2                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_VP702X                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_VP7045                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_USB_ZD1301                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_VES1820                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_VES1X93                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_ZD1301_DEMOD                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_ZL10036                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_ZL10039                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DVB_ZL10353                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DWC_PCIE_PMU                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DWC_XLGMAC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DWC_XLGMAC_PCI                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_DWMAC_DWC_QOS_ETH                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DWMAC_GENERIC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DWMAC_IMX8                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DWMAC_INTEL                              policy<{'amd64': 'm'}>
+CONFIG_DWMAC_INTEL_PLAT                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DWMAC_IPQ806X                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DWMAC_MEDIATEK                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DWMAC_MESON                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DWMAC_QCOM_ETHQOS                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DWMAC_ROCKCHIP                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DWMAC_SOCFPGA                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DWMAC_STARFIVE                           policy<{'riscv64': 'm'}>
+CONFIG_DWMAC_STM32                              policy<{'arm64': 'm'}>
+CONFIG_DWMAC_SUN8I                              policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_DWMAC_SUNXI                              policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_DWMAC_TEGRA                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_DWMAC_VISCONTI                           policy<{'arm64': 'm'}>
+CONFIG_DW_APB_ICTL                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DW_APB_TIMER                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DW_APB_TIMER_OF                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_DW_AXI_DMAC                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DW_DMAC                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DW_DMAC_CORE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DW_DMAC_PCI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DW_EDMA                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DW_EDMA_PCIE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_DW_I3C_MASTER                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_DW_WATCHDOG                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DW_XDATA_PCIE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_DYNAMIC_DEBUG                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DYNAMIC_DEBUG_CORE                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DYNAMIC_EVENTS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_DYNAMIC_FTRACE                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_DYNAMIC_FTRACE_WITH_ARGS                 policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS             policy<{'arm64': 'y'}>
+CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS         policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}>
+CONFIG_DYNAMIC_FTRACE_WITH_REGS                 policy<{'amd64': 'y', 'arm64': '-', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_DYNAMIC_MEMORY_LAYOUT                    policy<{'amd64': 'y'}>
+CONFIG_DYNAMIC_PHYSICAL_MASK                    policy<{'amd64': 'y'}>
+CONFIG_DYNAMIC_SIGFRAME                         policy<{'amd64': 'y', 'riscv64': 'y'}>
+CONFIG_E100                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_E1000                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_E1000E                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_E1000E_HWTS                              policy<{'amd64': 'y'}>
+CONFIG_EADM_SCH                                 policy<{'s390x': 'm'}>
+CONFIG_EARLY_PRINTK                             policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_EARLY_PRINTK_DBGP                        policy<{'amd64': 'y'}>
+CONFIG_EARLY_PRINTK_USB                         policy<{'amd64': 'y'}>
+CONFIG_EARLY_PRINTK_USB_XDBC                    policy<{'amd64': 'y'}>
+CONFIG_EBC_C384_WDT                             policy<{'amd64': 'm'}>
+CONFIG_ECHO                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ECRYPT_FS_MESSAGING                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EDAC                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_EDAC_ALTERA                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_EDAC_ALTERA_ETHERNET                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_EDAC_ALTERA_L2C                          policy<{'armhf': 'y'}>
+CONFIG_EDAC_ALTERA_NAND                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_EDAC_ALTERA_OCRAM                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_EDAC_ALTERA_QSPI                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_EDAC_ALTERA_SDMMC                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_EDAC_ALTERA_SDRAM                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_EDAC_ALTERA_USB                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_EDAC_AMD64                               policy<{'amd64': 'm'}>
+CONFIG_EDAC_ARMADA_XP                           policy<{'armhf': 'y'}>
+CONFIG_EDAC_ASPEED                              policy<{'armhf': 'm'}>
+CONFIG_EDAC_ATOMIC_SCRUB                        policy<{'amd64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_EDAC_BLUEFIELD                           policy<{'arm64': 'm'}>
+CONFIG_EDAC_CPC925                              policy<{'ppc64el': 'm'}>
+CONFIG_EDAC_DEBUG                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_EDAC_DECODE_MCE                          policy<{'amd64': 'm'}>
+CONFIG_EDAC_DMC520                              policy<{'arm64': 'm'}>
+CONFIG_EDAC_E752X                               policy<{'amd64': 'm'}>
+CONFIG_EDAC_GHES                                policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_EDAC_HIGHBANK_L2                         policy<{'armhf': 'm'}>
+CONFIG_EDAC_HIGHBANK_MC                         policy<{'armhf': 'm'}>
+CONFIG_EDAC_I10NM                               policy<{'amd64': 'm'}>
+CONFIG_EDAC_I3000                               policy<{'amd64': 'm'}>
+CONFIG_EDAC_I3200                               policy<{'amd64': 'm'}>
+CONFIG_EDAC_I5100                               policy<{'amd64': 'm'}>
+CONFIG_EDAC_I5400                               policy<{'amd64': 'm'}>
+CONFIG_EDAC_I7300                               policy<{'amd64': 'm'}>
+CONFIG_EDAC_I7CORE                              policy<{'amd64': 'm'}>
+CONFIG_EDAC_I82975X                             policy<{'amd64': 'm'}>
+CONFIG_EDAC_IE31200                             policy<{'amd64': 'm'}>
+CONFIG_EDAC_IGEN6                               policy<{'amd64': 'm'}>
+CONFIG_EDAC_LAYERSCAPE                          policy<{'arm64': 'm'}>
+CONFIG_EDAC_LEGACY_SYSFS                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_EDAC_NPCM                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_EDAC_PND2                                policy<{'amd64': 'm'}>
+CONFIG_EDAC_QCOM                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_EDAC_SBRIDGE                             policy<{'amd64': 'm'}>
+CONFIG_EDAC_SIFIVE                              policy<{'riscv64': 'y'}>
+CONFIG_EDAC_SKX                                 policy<{'amd64': 'm'}>
+CONFIG_EDAC_SUPPORT                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_EDAC_SYNOPSYS                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_EDAC_THUNDERX                            policy<{'arm64': 'm'}>
+CONFIG_EDAC_TI                                  policy<{'armhf': 'm'}>
+CONFIG_EDAC_VERSAL                              policy<{'arm64': 'm'}>
+CONFIG_EDAC_X38                                 policy<{'amd64': 'm'}>
+CONFIG_EDAC_XGENE                               policy<{'arm64': 'm'}>
+CONFIG_EDAC_ZYNQMP                              policy<{'arm64': 'm'}>
+CONFIG_EDD                                      policy<{'amd64': 'y'}>
+CONFIG_EDD_OFF                                  policy<{'amd64': 'y'}>
+CONFIG_EEEPC_LAPTOP                             policy<{'amd64': 'm'}>
+CONFIG_EEEPC_WMI                                policy<{'amd64': 'm'}>
+CONFIG_EEH                                      policy<{'ppc64el': 'y'}>
+CONFIG_EEPROM_93CX6                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_EEPROM_93XX46                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EEPROM_AT24                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_EEPROM_AT25                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EEPROM_EE1004                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_EEPROM_IDT_89HPESX                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_EEPROM_MAX6875                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_EFI                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_EFI_ARMSTUB_DTB_LOADER                   policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_EFI_BOOTLOADER_CONTROL                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_EFI_CAPSULE_LOADER                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_EFI_COCO_SECRET                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_EFI_CUSTOM_SSDT_OVERLAYS                 policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_EFI_DEV_PATH_PARSER                      policy<{'amd64': 'y'}>
+CONFIG_EFI_DISABLE_PCI_DMA                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'riscv64': 'n'}>
+CONFIG_EFI_DISABLE_RUNTIME                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'riscv64': 'n'}>
+CONFIG_EFI_DXE_MEM_ATTRIBUTES                   policy<{'amd64': 'y'}>
+CONFIG_EFI_EARLYCON                             policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_EFI_EMBEDDED_FIRMWARE                    policy<{'amd64': 'y'}>
+CONFIG_EFI_ESRT                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_EFI_FAKE_MEMMAP                          policy<{'amd64': 'n'}>
+CONFIG_EFI_GENERIC_STUB                         policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_EFI_MIXED                                policy<{'amd64': 'y'}>
+CONFIG_EFI_PARAMS_FROM_FDT                      policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_EFI_PARTITION                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EFI_PGT_DUMP                             policy<{'amd64': 'n'}>
+CONFIG_EFI_RCI2_TABLE                           policy<{'amd64': 'y'}>
+CONFIG_EFI_RUNTIME_MAP                          policy<{'amd64': 'y'}>
+CONFIG_EFI_RUNTIME_WRAPPERS                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_EFI_SECRET                               policy<{'amd64': 'm'}>
+CONFIG_EFI_SOFT_RESERVE                         policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_EFI_STUB                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_EFI_TEST                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_EFI_VARS_PSTORE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'riscv64': 'n'}>
+CONFIG_EFS_FS                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_EINT_MTK                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_EISA                                     policy<{'amd64': 'y'}>
+CONFIG_EISA_NAMES                               policy<{'amd64': 'y'}>
+CONFIG_EISA_PCI_EISA                            policy<{'amd64': 'y'}>
+CONFIG_EISA_VIRTUAL_ROOT                        policy<{'amd64': 'y'}>
+CONFIG_EISA_VLB_PRIMING                         policy<{'amd64': 'y'}>
+CONFIG_EL3                                      policy<{'amd64': 'm'}>
+CONFIG_ELFCORE                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ELF_CORE                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EMAC_ROCKCHIP                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_EM_TIMER_STI                             policy<{'armhf': 'y'}>
+CONFIG_ENA_ETHERNET                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ENC28J60                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ENC28J60_WRITEVERIFY                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ENCLOSURE_SERVICES                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ENCRYPTED_KEYS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ENCX24J600                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ENERGY_MODEL                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ENIC                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ENVELOPE_DETECTOR                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_EPAPR_BOOT                               policy<{'ppc64el': 'y'}>
+CONFIG_EPAPR_PARAVIRT                           policy<{'ppc64el': 'y'}>
+CONFIG_EPIC100                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EPOLL                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EQUALIZER                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_EROFS_FS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_EROFS_FS_DEBUG                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_EROFS_FS_ONDEMAND                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_EROFS_FS_PCPU_KTHREAD                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EROFS_FS_PCPU_KTHREAD_HIPRI              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_EROFS_FS_POSIX_ACL                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EROFS_FS_SECURITY                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EROFS_FS_XATTR                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EROFS_FS_ZIP                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EROFS_FS_ZIP_DEFLATE                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EROFS_FS_ZIP_LZMA                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ERRATA_ANDES                             policy<{'riscv64': 'n'}>
+CONFIG_ERRATA_SIFIVE                            policy<{'riscv64': 'y'}>
+CONFIG_ERRATA_SIFIVE_CIP_1200                   policy<{'riscv64': 'y'}>
+CONFIG_ERRATA_SIFIVE_CIP_453                    policy<{'riscv64': 'y'}>
+CONFIG_ERRATA_THEAD                             policy<{'riscv64': 'y'}>
+CONFIG_ERRATA_THEAD_CMO                         policy<{'riscv64': 'y'}>
+CONFIG_ERRATA_THEAD_MAE                         policy<{'riscv64': 'y'}>
+CONFIG_ERRATA_THEAD_PMU                         policy<{'riscv64': 'y'}>
+CONFIG_ET131X                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ETHERNET                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ETHOC                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ETHTOOL_NETLINK                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EUROTECH_WDT                             policy<{'amd64': 'm'}>
+CONFIG_EVENTFD                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EVENT_TRACING                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EVM_ADD_XATTRS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EVM_EXTRA_SMACK_XATTRS                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EXAR_WDT                                 policy<{'amd64': 'm'}>
+CONFIG_EXCLUSIVE_SYSTEM_RAM                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EXFAT_DEFAULT_IOCHARSET                  policy<{'amd64': '"utf8"', 'arm64': '"utf8"', 'armhf': '"utf8"', 'ppc64el': '"utf8"', 'riscv64': '"utf8"'}>
+CONFIG_EXFAT_FS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_EXPERT                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EXPOLINE                                 policy<{'s390x': 'y'}>
+CONFIG_EXPOLINE_AUTO                            policy<{'s390x': 'y'}>
+CONFIG_EXPOLINE_EXTERN                          policy<{'s390x': 'y'}>
+CONFIG_EXPOLINE_FULL                            policy<{'s390x': 'n'}>
+CONFIG_EXPOLINE_OFF                             policy<{'s390x': 'n'}>
+CONFIG_EXPORTFS                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EXPORTFS_BLOCK_OPS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EXT4_DEBUG                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_EXT4_FS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EXT4_FS_POSIX_ACL                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EXT4_FS_SECURITY                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EXT4_USE_FOR_EXT2                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_EXTCON                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_EXTCON_ADC_JACK                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_EXTCON_AXP288                            policy<{'amd64': 'm'}>
+CONFIG_EXTCON_FSA9480                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EXTCON_GPIO                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EXTCON_INTEL_CHT_WC                      policy<{'amd64': 'm'}>
+CONFIG_EXTCON_INTEL_INT3496                     policy<{'amd64': 'm'}>
+CONFIG_EXTCON_INTEL_MRFLD                       policy<{'amd64': 'm'}>
+CONFIG_EXTCON_MAX14577                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EXTCON_MAX3355                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EXTCON_MAX77693                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EXTCON_MAX77843                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EXTCON_MAX8997                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EXTCON_PALMAS                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EXTCON_PTN5150                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EXTCON_QCOM_SPMI_MISC                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_EXTCON_RT8973A                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EXTCON_RTK_TYPE_C                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_EXTCON_SM5502                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EXTCON_USBC_CROS_EC                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_EXTCON_USBC_TUSB320                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EXTCON_USB_GPIO                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_EXTRA_FIRMWARE                           policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'ppc64el': '""', 'riscv64': '""', 's390x': '""'}>
+CONFIG_EXTRA_TARGETS                            policy<{'ppc64el': '""'}>
+CONFIG_EXYNOS5422_DMC                           policy<{'armhf': 'n'}>
+CONFIG_EXYNOS_ADC                               policy<{'armhf': 'n'}>
+CONFIG_EXYNOS_AUDSS_CLK_CON                     policy<{'armhf': 'n'}>
+CONFIG_EXYNOS_CHIPID                            policy<{'armhf': 'n'}>
+CONFIG_EXYNOS_CLKOUT                            policy<{'armhf': 'n'}>
+CONFIG_EXYNOS_CPU_SUSPEND                       policy<{'armhf': 'y'}>
+CONFIG_EXYNOS_IOMMU                             policy<{'armhf': 'n'}>
+CONFIG_EXYNOS_IRQ_COMBINER                      policy<{'armhf': 'y'}>
+CONFIG_EXYNOS_PMU                               policy<{'armhf': 'y'}>
+CONFIG_EXYNOS_PMU_ARM_DRIVERS                   policy<{'armhf': 'y'}>
+CONFIG_EXYNOS_PM_DOMAINS                        policy<{'armhf': 'y'}>
+CONFIG_EXYNOS_SROM                              policy<{'armhf': 'y'}>
+CONFIG_EXYNOS_THERMAL                           policy<{'armhf': 'y'}>
+CONFIG_EXYNOS_USI                               policy<{'armhf': 'n'}>
+CONFIG_EZCHIP_NPS_MANAGEMENT_ENET               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_EZX_PCAP                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_F2FS_CHECK_FS                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_F2FS_FAULT_INJECTION                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_F2FS_FS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_F2FS_FS_COMPRESSION                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_F2FS_FS_LZ4                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_F2FS_FS_LZ4HC                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_F2FS_FS_LZO                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_F2FS_FS_LZORLE                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_F2FS_FS_POSIX_ACL                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_F2FS_FS_SECURITY                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_F2FS_FS_XATTR                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_F2FS_FS_ZSTD                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_F2FS_IOSTAT                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_F2FS_STAT_FS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_F2FS_UNFAIR_RWSEM                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_F71808E_WDT                              policy<{'amd64': 'm'}>
+CONFIG_FAILOVER                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FAIR_GROUP_SCHED                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FANOTIFY                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FARSYNC                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FAT_DEFAULT_CODEPAGE                     policy<{'amd64': '437', 'arm64': '437', 'armhf': '437', 'ppc64el': '437', 'riscv64': '437', 's390x': '437'}>
+CONFIG_FAT_DEFAULT_IOCHARSET                    policy<{'amd64': '"iso8859-1"', 'arm64': '"iso8859-1"', 'armhf': '"iso8859-1"', 'ppc64el': '"iso8859-1"', 'riscv64': '"iso8859-1"', 's390x': '"iso8859-1"'}>
+CONFIG_FAT_DEFAULT_UTF8                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FAT_FS                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FAULT_INJECTION                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FB                                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FB_3DFX                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_3DFX_ACCEL                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_FB_3DFX_I2C                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_FB_ARC                                   policy<{'amd64': 'm'}>
+CONFIG_FB_ARK                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_ASILIANT                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_FB_ATY                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_ATY128                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_ATY128_BACKLIGHT                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_ATY_BACKLIGHT                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_ATY_CT                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_ATY_GENERIC_LCD                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_FB_ATY_GX                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_BACKLIGHT                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_CARMINE                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_CARMINE_DRAM_EVAL                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_CFB_COPYAREA                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_FB_CFB_FILLRECT                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_FB_CFB_IMAGEBLIT                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_FB_CIRRUS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_CORE                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FB_CYBER2000                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_CYBER2000_DDC                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_DDC                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_DEFERRED_IO                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FB_DEVICE                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FB_DMAMEM_HELPERS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_FOREIGN_ENDIAN                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FB_GOLDFISH                              policy<{'riscv64': 'm'}>
+CONFIG_FB_HECUBA                                policy<{'amd64': 'm'}>
+CONFIG_FB_HGA                                   policy<{'amd64': 'm'}>
+CONFIG_FB_HYPERV                                policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_FB_I740                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_IBM_GXT4500                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FB_IMSTT                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_FB_IMX                                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_FB_IOMEM_FOPS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_FB_IOMEM_HELPERS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_IOMEM_HELPERS_DEFERRED                policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_FB_KYRO                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_MACMODES                              policy<{'ppc64el': 'm'}>
+CONFIG_FB_MATROX                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_MATROX_G                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_MATROX_I2C                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_MATROX_MAVEN                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_MATROX_MILLENIUM                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_MATROX_MYSTIQUE                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_MB862XX                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_MB862XX_I2C                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_MB862XX_LIME                          policy<{'ppc64el': 'n'}>
+CONFIG_FB_MB862XX_PCI_GDC                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_METRONOME                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_MODE_HELPERS                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FB_N411                                  policy<{'amd64': 'm'}>
+CONFIG_FB_NEOMAGIC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_NOTIFY                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FB_NVIDIA                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_NVIDIA_BACKLIGHT                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_NVIDIA_DEBUG                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_FB_NVIDIA_I2C                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_OF                                    policy<{'ppc64el': 'm'}>
+CONFIG_FB_OMAP2                                 policy<{'armhf': 'm'}>
+CONFIG_FB_OMAP2_CONNECTOR_ANALOG_TV             policy<{'armhf': 'n'}>
+CONFIG_FB_OMAP2_CONNECTOR_DVI                   policy<{'armhf': 'n'}>
+CONFIG_FB_OMAP2_CONNECTOR_HDMI                  policy<{'armhf': 'n'}>
+CONFIG_FB_OMAP2_DEBUG_SUPPORT                   policy<{'armhf': 'n'}>
+CONFIG_FB_OMAP2_DSS                             policy<{'armhf': 'm'}>
+CONFIG_FB_OMAP2_DSS_DEBUG                       policy<{'armhf': 'n'}>
+CONFIG_FB_OMAP2_DSS_DEBUGFS                     policy<{'armhf': 'n'}>
+CONFIG_FB_OMAP2_DSS_DPI                         policy<{'armhf': 'y'}>
+CONFIG_FB_OMAP2_DSS_DSI                         policy<{'armhf': 'n'}>
+CONFIG_FB_OMAP2_DSS_HDMI_COMMON                 policy<{'armhf': 'y'}>
+CONFIG_FB_OMAP2_DSS_INIT                        policy<{'armhf': 'y'}>
+CONFIG_FB_OMAP2_DSS_MIN_FCK_PER_PCK             policy<{'armhf': '0'}>
+CONFIG_FB_OMAP2_DSS_SDI                         policy<{'armhf': 'n'}>
+CONFIG_FB_OMAP2_DSS_SLEEP_AFTER_VENC_RESET      policy<{'armhf': 'y'}>
+CONFIG_FB_OMAP2_DSS_VENC                        policy<{'armhf': 'y'}>
+CONFIG_FB_OMAP2_ENCODER_OPA362                  policy<{'armhf': 'n'}>
+CONFIG_FB_OMAP2_ENCODER_TFP410                  policy<{'armhf': 'n'}>
+CONFIG_FB_OMAP2_ENCODER_TPD12S015               policy<{'armhf': 'n'}>
+CONFIG_FB_OMAP2_NUM_FBS                         policy<{'armhf': '3'}>
+CONFIG_FB_OMAP2_PANEL_DPI                       policy<{'armhf': 'n'}>
+CONFIG_FB_OMAP2_PANEL_LGPHILIPS_LB035Q02        policy<{'armhf': 'n'}>
+CONFIG_FB_OMAP4_DSS_HDMI                        policy<{'armhf': 'y'}>
+CONFIG_FB_OMAP5_DSS_HDMI                        policy<{'armhf': 'n'}>
+CONFIG_FB_OPENCORES                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_PM2                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_PM2_FIFO_DISCONNECT                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_PM3                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA          policy<{'arm64': 'y'}>
+CONFIG_FB_RADEON                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_RADEON_BACKLIGHT                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_RADEON_DEBUG                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_FB_RADEON_I2C                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_RIVA                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_RIVA_BACKLIGHT                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_RIVA_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_FB_RIVA_I2C                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_S1D13XXX                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_S3                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_S3_DDC                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_SAVAGE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_SAVAGE_ACCEL                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_FB_SAVAGE_I2C                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_SH_MOBILE_LCDC                        policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_FB_SIMPLE                                policy<{'amd64': '-', 'arm64': '-', 'armhf': '-', 'ppc64el': '-', 'riscv64': '-', 's390x': 'n'}>
+CONFIG_FB_SIS                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_SIS_300                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_SIS_315                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FB_SM501                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_SM712                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_SM750                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_FB_SMSCUFX                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_FB_SSD1307                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_SVGALIB                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_SYSMEM_FOPS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FB_SYSMEM_HELPERS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FB_SYSMEM_HELPERS_DEFERRED               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FB_SYS_COPYAREA                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FB_SYS_FILLRECT                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FB_SYS_IMAGEBLIT                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FB_TFT                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_FB_TFT_AGM1264K_FL                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_BD663474                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_HX8340BN                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_HX8347D                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_HX8353D                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_HX8357D                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_ILI9163                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_ILI9320                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_ILI9325                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_ILI9340                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_ILI9341                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_ILI9481                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_ILI9486                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_PCD8544                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_RA8875                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_S6D02A1                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_S6D1121                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_SEPS525                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_SH1106                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_SSD1289                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_SSD1305                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_SSD1306                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_SSD1331                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_SSD1351                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_ST7735R                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_ST7789V                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_TINYLCD                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_TLS8204                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_UC1611                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_UC1701                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TFT_UPD161704                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FB_TILEBLITTING                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_FB_TRIDENT                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_UDL                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_FB_UVESA                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_VGA16                                 policy<{'amd64': 'm', 'ppc64el': '-'}>
+CONFIG_FB_VIA                                   policy<{'amd64': 'm'}>
+CONFIG_FB_VIA_DIRECT_PROCFS                     policy<{'amd64': 'n'}>
+CONFIG_FB_VIA_X_COMPATIBILITY                   policy<{'amd64': 'y'}>
+CONFIG_FB_VIRTUAL                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FB_VOODOO1                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_VT8623                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FB_XILINX                                policy<{'arm64': 'm'}>
+CONFIG_FCOE                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_FCOE_FNIC                                policy<{'amd64': 'm'}>
+CONFIG_FDDI                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_FEALNX                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FEC                                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_FHCI_DEBUG                               policy<{'ppc64el': 'n'}>
+CONFIG_FIB_RULES                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FIELDBUS_DEV                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_FILE_LOCKING                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FIND_BIT_BENCHMARK                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FIPS_SIGNATURE_SELFTEST                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FIQ                                      policy<{'armhf': 'y'}>
+CONFIG_FIREWIRE                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FIREWIRE_NET                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FIREWIRE_NOSY                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FIREWIRE_OHCI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FIREWIRE_SBP2                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FIRMWARE_EDID                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FIRMWARE_MEMMAP                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_FIRMWARE_TABLE                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FIXED_PHY                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FIX_EARLYCON_MEM                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_FLATMEM_MANUAL                           policy<{'armhf': 'n'}>
+CONFIG_FM10K                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_FONTS                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FONT_10x18                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FONT_6x10                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FONT_6x11                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FONT_6x8                                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FONT_7x14                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FONT_8x16                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FONT_8x8                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FONT_ACORN_8x8                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FONT_MINI_4x6                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FONT_PEARL_8x8                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FONT_SUN12x22                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FONT_SUN8x16                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FONT_SUPPORT                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FONT_TER16x32                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FORCEDETH                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_FORCE_PCI                                policy<{'ppc64el': 'y'}>
+CONFIG_FORCE_SMP                                policy<{'ppc64el': 'y'}>
+CONFIG_FORTIFY_SOURCE                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'n', 's390x': 'y'}>
+CONFIG_FPGA                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_FPGA_BRIDGE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FPGA_DFL                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_FPGA_DFL_AFU                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FPGA_DFL_EMIF                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FPGA_DFL_FME                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FPGA_DFL_FME_BRIDGE                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FPGA_DFL_FME_MGR                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FPGA_DFL_FME_REGION                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FPGA_DFL_NIOS_INTEL_PAC_N3000            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FPGA_DFL_PCI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FPGA_M10_BMC_SEC_UPDATE                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_FPGA_MGR_ALTERA_CVP                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_FPGA_MGR_ALTERA_PS_SPI                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_FPGA_MGR_ICE40_SPI                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FPGA_MGR_LATTICE_SYSCONFIG               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FPGA_MGR_LATTICE_SYSCONFIG_SPI           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FPGA_MGR_MACHXO2_SPI                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_FPGA_MGR_MICROCHIP_SPI                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FPGA_MGR_SOCFPGA                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_FPGA_MGR_SOCFPGA_A10                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_FPGA_MGR_STRATIX10_SOC                   policy<{'arm64': 'm'}>
+CONFIG_FPGA_MGR_VERSAL_FPGA                     policy<{'arm64': 'm'}>
+CONFIG_FPGA_MGR_XILINX_SPI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_FPGA_MGR_ZYNQMP_FPGA                     policy<{'arm64': 'm'}>
+CONFIG_FPGA_REGION                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FPROBE                                   policy<{'amd64': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_FPROBE_EVENTS                            policy<{'amd64': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_FPU                                      policy<{'riscv64': 'y'}>
+CONFIG_FRAMEBUFFER_CONSOLE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FRAMER                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FRAMER_PEF2256                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FRAME_POINTER                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_FRAME_WARN                               policy<{'amd64': '1024', 'arm64': '1024', 'armhf': '1024', 'ppc64el': '2048', 'riscv64': '1024', 's390x': '1024'}>
+CONFIG_FREEZER                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FSCACHE                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FSCACHE_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FSCACHE_STATS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FSI                                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FSI_MASTER_ASPEED                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FSI_MASTER_AST_CF                        policy<{'armhf': 'm'}>
+CONFIG_FSI_MASTER_GPIO                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FSI_MASTER_HUB                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FSI_MASTER_I2CR                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FSI_NEW_DEV_NODE                         policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_FSI_OCC                                  policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FSI_SBEFIFO                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FSI_SCOM                                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FSL_BMAN_TEST                            policy<{'arm64': 'm'}>
+CONFIG_FSL_BMAN_TEST_API                        policy<{'arm64': 'n'}>
+CONFIG_FSL_DPAA                                 policy<{'arm64': 'y'}>
+CONFIG_FSL_DPAA2_ETH                            policy<{'arm64': 'm'}>
+CONFIG_FSL_DPAA2_ETH_DCB                        policy<{'arm64': 'y'}>
+CONFIG_FSL_DPAA2_PTP_CLOCK                      policy<{'arm64': 'm'}>
+CONFIG_FSL_DPAA2_QDMA                           policy<{'arm64': 'm'}>
+CONFIG_FSL_DPAA2_SWITCH                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_FSL_DPAA_CHECKING                        policy<{'arm64': 'y'}>
+CONFIG_FSL_DPAA_ETH                             policy<{'arm64': 'm'}>
+CONFIG_FSL_EDMA                                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FSL_ENETC                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_FSL_ENETC_CORE                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_FSL_ENETC_IERB                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_FSL_ENETC_MDIO                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_FSL_ENETC_PTP_CLOCK                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_FSL_ENETC_QOS                            policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_FSL_ENETC_VF                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_FSL_ERRATUM_A008585                      policy<{'arm64': 'y'}>
+CONFIG_FSL_FMAN                                 policy<{'arm64': 'y'}>
+CONFIG_FSL_GTM                                  policy<{'ppc64el': 'y'}>
+CONFIG_FSL_GUTS                                 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_FSL_IFC                                  policy<{'arm64': 'y'}>
+CONFIG_FSL_IMX8_DDR_PMU                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_FSL_IMX9_DDR_PMU                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_FSL_LBC                                  policy<{'ppc64el': 'y'}>
+CONFIG_FSL_MC_BUS                               policy<{'arm64': 'y', 'armhf': 'n'}>
+CONFIG_FSL_MC_DPIO                              policy<{'arm64': 'm'}>
+CONFIG_FSL_MC_UAPI_SUPPORT                      policy<{'arm64': 'y'}>
+CONFIG_FSL_PQ_MDIO                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_FSL_QDMA                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_FSL_QMAN_TEST                            policy<{'arm64': 'n'}>
+CONFIG_FSL_RCPM                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_FSL_UCC_HDLC                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_FSL_XGMAC_MDIO                           policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_FSNOTIFY                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FS_DAX                                   policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_FS_DAX_LIMITED                           policy<{'s390x': 'y'}>
+CONFIG_FS_DAX_PMD                               policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_FS_ENCRYPTION                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FS_ENCRYPTION_ALGS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FS_ENCRYPTION_INLINE_CRYPT               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FS_IOMAP                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FS_MBCACHE                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FS_POSIX_ACL                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FS_STACK                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FS_VERITY                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FS_VERITY_BUILTIN_SIGNATURES             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FTGMAC100                                policy<{'armhf': 'm'}>
+CONFIG_FTL                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FTMAC100                                 policy<{'armhf': 'm'}>
+CONFIG_FTRACE                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FTRACE_MCOUNT_RECORD                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_FTRACE_MCOUNT_USE_CC                     policy<{'amd64': 'y', 's390x': 'y'}>
+CONFIG_FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY policy<{'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT           policy<{'armhf': 'y', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_FTRACE_RECORD_RECURSION                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': '-', 's390x': 'n'}>
+CONFIG_FTRACE_SORT_STARTUP_TEST                 policy<{'amd64': 'n', 'armhf': 'n'}>
+CONFIG_FTRACE_STARTUP_TEST                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FTRACE_SYSCALLS                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FTR_FIXUP_SELFTEST                       policy<{'ppc64el': 'n'}>
+CONFIG_FTWDT010_WATCHDOG                        policy<{'armhf': 'm'}>
+CONFIG_FUEL_GAUGE_MM8013                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FUEL_GAUGE_SC27XX                        policy<{'arm64': 'm'}>
+CONFIG_FUJITSU_ERRATUM_010001                   policy<{'arm64': 'y'}>
+CONFIG_FUJITSU_ES                               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_FUJITSU_LAPTOP                           policy<{'amd64': 'm'}>
+CONFIG_FUJITSU_TABLET                           policy<{'amd64': 'm'}>
+CONFIG_FUNCTION_ALIGNMENT                       policy<{'amd64': '16', 'arm64': '8', 'armhf': '0', 'ppc64el': '4', 'riscv64': '0', 's390x': '8'}>
+CONFIG_FUNCTION_ALIGNMENT_16B                   policy<{'amd64': 'y'}>
+CONFIG_FUNCTION_ALIGNMENT_4B                    policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_FUNCTION_ALIGNMENT_8B                    policy<{'arm64': 'y', 's390x': 'y'}>
+CONFIG_FUNCTION_ERROR_INJECTION                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FUNCTION_GRAPH_RETVAL                    policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_FUNCTION_GRAPH_TRACER                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_FUNCTION_PADDING_BYTES                   policy<{'amd64': '16'}>
+CONFIG_FUNCTION_PADDING_CFI                     policy<{'amd64': '11'}>
+CONFIG_FUNCTION_PROFILER                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_FUNCTION_TRACER                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_FUN_CORE                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FUN_ETH                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FUSE_DAX                                 policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_FUSION                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_FUSION_CTL                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FUSION_FC                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_FUSION_LAN                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FUSION_LOGGING                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FUSION_MAX_SGE                           policy<{'amd64': '128', 'arm64': '128', 'armhf': '128', 'ppc64el': '128', 'riscv64': '128'}>
+CONFIG_FUSION_SAS                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_FUSION_SPI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_FUTEX                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FUTEX_PI                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FWNODE_MDIO                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FW_ATTR_CLASS                            policy<{'amd64': 'm'}>
+CONFIG_FW_CACHE                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_FW_CFG_SYSFS                             policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_FW_CFG_SYSFS_CMDLINE                     policy<{'amd64': 'n', 'arm64': 'n', 'riscv64': 'n'}>
+CONFIG_FW_CS_DSP                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_FW_LOADER                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FW_LOADER_COMPRESS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FW_LOADER_COMPRESS_XZ                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FW_LOADER_COMPRESS_ZSTD                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FW_LOADER_DEBUG                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FW_LOADER_PAGED_BUF                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FW_LOADER_SYSFS                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FW_LOADER_USER_HELPER                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_FW_UPLOAD                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_FXAS21002C                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FXAS21002C_I2C                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FXAS21002C_SPI                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FXLS8962AF                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FXLS8962AF_I2C                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FXLS8962AF_SPI                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FXOS8700                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FXOS8700_I2C                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_FXOS8700_SPI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GACT_PROB                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GADGET_UAC1                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GADGET_UAC1_LEGACY                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_GAMEPORT                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GAMEPORT_EMU10K1                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GAMEPORT_FM801                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GARP                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_GART_IOMMU                               policy<{'amd64': 'y'}>
+CONFIG_GCC10_NO_ARRAY_BOUNDS                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GCC_NO_STRINGOP_OVERFLOW                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE              policy<{'riscv64': 'y'}>
+CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS    policy<{'arm64': 'y'}>
+CONFIG_GCC_VERSION                              policy<{'amd64': '130300', 'arm64': '130300', 'armhf': '130300', 'ppc64el': '130300', 'riscv64': '130300', 's390x': '130300'}>
+CONFIG_GCOV_KERNEL                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_GDB_SCRIPTS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GDS_FORCE_MITIGATION                     policy<{'amd64': 'n'}>
+CONFIG_GEMINI_ETHERNET                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GENERIC_ADC_BATTERY                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GENERIC_ADC_THERMAL                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GENERIC_ALLOCATOR                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_ARCH_NUMA                        policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_ARCH_TOPOLOGY                    policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_BUG                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_BUG_RELATIVE_POINTERS            policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_CALIBRATE_DELAY                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_CLOCKEVENTS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST           policy<{'amd64': 'y'}>
+CONFIG_GENERIC_CMOS_UPDATE                      policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_GENERIC_CPU                              policy<{'amd64': 'y', 'ppc64el': '-'}>
+CONFIG_GENERIC_CPU_AUTOPROBE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_CPU_DEVICES                      policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_CPU_VULNERABILITIES              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_CSUM                             policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_EARLY_IOREMAP                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_ENTRY                            policy<{'amd64': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_FRAMER                           policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_GETTIMEOFDAY                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_HWEIGHT                          policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_IDLE_POLL_SETUP                  policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_IOMAP                            policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_GENERIC_IOREMAP                          policy<{'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_IRQ_CHIP                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_IRQ_DEBUGFS                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_IRQ_IPI                          policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_IRQ_IPI_MUX                      policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR             policy<{'amd64': 'y'}>
+CONFIG_GENERIC_IRQ_MIGRATION                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_IRQ_MULTI_HANDLER                policy<{'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_IRQ_PROBE                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y'}>
+CONFIG_GENERIC_IRQ_RESERVATION_MODE             policy<{'amd64': 'y'}>
+CONFIG_GENERIC_IRQ_SHOW                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_IRQ_SHOW_LEVEL                   policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_ISA_DMA                          policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED            policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_MSI_IRQ                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_NET_UTILS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_PCI_IOMAP                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_PENDING_IRQ                      policy<{'amd64': 'y'}>
+CONFIG_GENERIC_PHY                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_GENERIC_PHY_MIPI_DPHY                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_PINCONF                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_PINCTRL_GROUPS                   policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_PINMUX_FUNCTIONS                 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_PTDUMP                           policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_SCHED_CLOCK                      policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_GENERIC_SMP_IDLE_THREAD                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_STRNCPY_FROM_USER                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_STRNLEN_USER                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_TIME_VSYSCALL                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_TRACER                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENERIC_VDSO_32                          policy<{'armhf': 'y'}>
+CONFIG_GENERIC_VDSO_TIME_NS                     policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GENEVE                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_GENWQE                                   policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_GENWQE_PLATFORM_ERROR_RECOVERY           policy<{'amd64': '0', 'arm64': '0', 'ppc64el': '0', 'riscv64': '0', 's390x': '0'}>
+CONFIG_GEN_RTC                                  policy<{'ppc64el': 'y'}>
+CONFIG_GET_FREE_REGION                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GFS2_FS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_GFS2_FS_LOCKING_DLM                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GIANFAR                                  policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_GIGABYTE_WMI                             policy<{'amd64': 'm'}>
+CONFIG_GLOB                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GLOB_SELFTEST                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_GNSS                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GNSS_MTK_SERIAL                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GNSS_SERIAL                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GNSS_SIRF_SERIAL                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GNSS_UBX_SERIAL                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GNSS_USB                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GOLDFISH                                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_GOLDFISH_PIPE                            policy<{'riscv64': 'm'}>
+CONFIG_GOLDFISH_TTY                             policy<{'riscv64': 'm'}>
+CONFIG_GOOGLE_FIRMWARE                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_GP2AP002                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GP2AP020A00F                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPD_POCKET_FAN                           policy<{'amd64': 'm'}>
+CONFIG_GPIOLIB                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GPIOLIB_FASTPATH_LIMIT                   policy<{'amd64': '512', 'arm64': '512', 'armhf': '512', 'ppc64el': '512', 'riscv64': '512', 's390x': '512'}>
+CONFIG_GPIOLIB_IRQCHIP                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GPIO_104_DIO_48E                         policy<{'amd64': 'm'}>
+CONFIG_GPIO_104_IDIO_16                         policy<{'amd64': 'm'}>
+CONFIG_GPIO_104_IDI_48                          policy<{'amd64': 'm'}>
+CONFIG_GPIO_74X164                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_74XX_MMIO                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_AAEON                               policy<{'amd64': 'm'}>
+CONFIG_GPIO_ACPI                                policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_GPIO_ADNP                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_ADP5520                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GPIO_AGGREGATOR                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_GPIO_ALTERA                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_ALTERA_A10SR                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_GPIO_AMD8111                             policy<{'amd64': 'm'}>
+CONFIG_GPIO_AMDPT                               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_AMD_FCH                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GPIO_ARIZONA                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_ASPEED                              policy<{'armhf': 'm'}>
+CONFIG_GPIO_ASPEED_SGPIO                        policy<{'armhf': 'y'}>
+CONFIG_GPIO_BD71815                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_BD71828                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_BD9571MWV                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_BT8XX                               policy<{'s390x': 'm'}>
+CONFIG_GPIO_CADENCE                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_CDEV                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GPIO_CRYSTAL_COVE                        policy<{'amd64': 'y'}>
+CONFIG_GPIO_DA9052                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GPIO_DA9055                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GPIO_DAVINCI                             policy<{'arm64': 'y'}>
+CONFIG_GPIO_DLN2                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_DS4520                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_GPIO_DWAPB                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GPIO_EIC_SPRD                            policy<{'arm64': 'm'}>
+CONFIG_GPIO_ELKHARTLAKE                         policy<{'amd64': 'm'}>
+CONFIG_GPIO_EN7523                              policy<{'armhf': 'm'}>
+CONFIG_GPIO_EXAR                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_F7188X                              policy<{'amd64': 'm'}>
+CONFIG_GPIO_FTGPIO010                           policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GPIO_FXL6408                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GPIO_GENERIC                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_GPIO_GENERIC_PLATFORM                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_GPIO_GPIO_MM                             policy<{'amd64': 'm'}>
+CONFIG_GPIO_GRGPIO                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_GW_PLD                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_HISI                                policy<{'arm64': 'm'}>
+CONFIG_GPIO_HLWD                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_I8255                               policy<{'amd64': 'm'}>
+CONFIG_GPIO_ICH                                 policy<{'amd64': 'm'}>
+CONFIG_GPIO_IDIO_16                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_GPIO_IMX_SCU                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_GPIO_IT87                                policy<{'amd64': 'm'}>
+CONFIG_GPIO_JANZ_TTL                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_KEMPLD                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_LATCH                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GPIO_LJCA                                policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_LOGICVC                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_LP3943                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_LP873X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_LP87565                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_MADERA                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_MAX3191X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GPIO_MAX7300                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GPIO_MAX7301                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GPIO_MAX730X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_MAX732X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GPIO_MAX77620                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_MAX77650                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_MB86S7X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GPIO_MC33880                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GPIO_MENZ127                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_MLXBF                               policy<{'arm64': 'm'}>
+CONFIG_GPIO_MLXBF2                              policy<{'arm64': 'm'}>
+CONFIG_GPIO_MLXBF3                              policy<{'arm64': 'm'}>
+CONFIG_GPIO_ML_IOH                              policy<{'amd64': 'm'}>
+CONFIG_GPIO_MOCKUP                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_GPIO_MOXTET                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_MPC8XXX                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_GPIO_MSC313                              policy<{'armhf': 'y'}>
+CONFIG_GPIO_MVEBU                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_GPIO_MXC                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_GPIO_NPCM_SGPIO                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_GPIO_OMAP                                policy<{'armhf': 'y'}>
+CONFIG_GPIO_PALMAS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GPIO_PCA953X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GPIO_PCA953X_IRQ                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GPIO_PCA9570                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GPIO_PCF857X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GPIO_PCIE_IDIO_24                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_GPIO_PCI_IDIO_16                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_GPIO_PISOSR                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GPIO_PL061                               policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'm'}>
+CONFIG_GPIO_PMIC_EIC_SPRD                       policy<{'arm64': 'm'}>
+CONFIG_GPIO_RC5T583                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GPIO_RCAR                                policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_RDA                                 policy<{'armhf': 'y'}>
+CONFIG_GPIO_RDC321X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GPIO_REGMAP                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_GPIO_ROCKCHIP                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_GPIO_RTD                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_GPIO_SCH                                 policy<{'amd64': 'm'}>
+CONFIG_GPIO_SCH311X                             policy<{'amd64': 'm'}>
+CONFIG_GPIO_SIFIVE                              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GPIO_SIM                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_GPIO_SIOX                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GPIO_SL28CPLD                            policy<{'arm64': 'm'}>
+CONFIG_GPIO_SPRD                                policy<{'arm64': 'm'}>
+CONFIG_GPIO_STMPE                               policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GPIO_SYSCON                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_SYSFS                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GPIO_TANGIER                             policy<{'amd64': 'm'}>
+CONFIG_GPIO_TC3589X                             policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GPIO_TEGRA                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_GPIO_TEGRA186                            policy<{'arm64': 'y'}>
+CONFIG_GPIO_THUNDERX                            policy<{'arm64': 'm'}>
+CONFIG_GPIO_TPIC2810                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GPIO_TPS65086                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_TPS65218                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_TPS65219                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_TPS6586X                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GPIO_TPS65910                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GPIO_TPS65912                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GPIO_TPS68470                            policy<{'amd64': 'm'}>
+CONFIG_GPIO_TQMX86                              policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_TS4800                              policy<{'armhf': 'm'}>
+CONFIG_GPIO_TS4900                              policy<{'armhf': 'm'}>
+CONFIG_GPIO_TWL6040                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GPIO_VF610                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_GPIO_VIPERBOARD                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_VIRTIO                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GPIO_VISCONTI                            policy<{'arm64': 'm'}>
+CONFIG_GPIO_VX855                               policy<{'amd64': 'm'}>
+CONFIG_GPIO_WATCHDOG                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_WCD934X                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_WHISKEY_COVE                        policy<{'amd64': 'm'}>
+CONFIG_GPIO_WINBOND                             policy<{'amd64': 'm'}>
+CONFIG_GPIO_WM831X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GPIO_WM8350                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GPIO_WM8994                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GPIO_WS16C48                             policy<{'amd64': 'm'}>
+CONFIG_GPIO_XGENE                               policy<{'arm64': 'y'}>
+CONFIG_GPIO_XGENE_SB                            policy<{'arm64': 'm'}>
+CONFIG_GPIO_XILINX                              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'n'}>
+CONFIG_GPIO_XLP                                 policy<{'arm64': 'm'}>
+CONFIG_GPIO_XRA1403                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GPIO_ZEVIO                               policy<{'armhf': 'y'}>
+CONFIG_GPIO_ZYNQ                                policy<{'arm64': 'm'}>
+CONFIG_GPIO_ZYNQMP_MODEPIN                      policy<{'arm64': 'm'}>
+CONFIG_GP_PCI1XXXX                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_GRACE_PERIOD                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_GREENASIA_FF                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_GREYBUS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_GREYBUS_AUDIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_AUDIO_APB_CODEC                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_BEAGLEPLAY                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_BOOTROM                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_BRIDGED_PHY                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_ES2                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_FIRMWARE                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_GPIO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_HID                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_I2C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_LIGHT                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_LOG                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_LOOPBACK                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_POWER                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_PWM                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_RAW                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_SDIO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_SPI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_UART                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_USB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GREYBUS_VIBRATOR                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_GRO_CELLS                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_GTP                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_GUEST_PERF_EVENTS                        policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_GUP_TEST                                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_GVE                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_GXP_TIMER                                policy<{'armhf': 'y'}>
+CONFIG_GXP_WATCHDOG                             policy<{'armhf': 'm'}>
+CONFIG_HALTPOLL_CPUIDLE                         policy<{'amd64': 'm'}>
+CONFIG_HAMACHI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_HAMRADIO                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HANGCHECK_TIMER                          policy<{'amd64': 'm', 'ppc64el': 'm', 's390x': 'm'}>
+CONFIG_HAPPYMEAL                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HARDENED_USERCOPY                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HARDEN_BRANCH_HISTORY                    policy<{'armhf': 'y'}>
+CONFIG_HARDEN_BRANCH_PREDICTOR                  policy<{'armhf': 'y'}>
+CONFIG_HARDIRQS_SW_RESEND                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HARDLOCKUP_CHECK_TIMESTAMP               policy<{'amd64': 'y'}>
+CONFIG_HARDLOCKUP_DETECTOR                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HARDLOCKUP_DETECTOR_ARCH                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'n'}>
+CONFIG_HARDLOCKUP_DETECTOR_BUDDY                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'y', 'ppc64el': 'n', 'riscv64': 'y'}>
+CONFIG_HARDLOCKUP_DETECTOR_COUNTS_HRTIMER       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_HARDLOCKUP_DETECTOR_PERF                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_HARDLOCKUP_DETECTOR_PREFER_BUDDY         policy<{'amd64': 'n', 'arm64': 'n'}>
+CONFIG_HAS_DMA                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAS_IOMEM                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAS_IOPORT                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAS_IOPORT_MAP                           policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_64BIT_ALIGNED_ACCESS                policy<{'riscv64': 'y'}>
+CONFIG_HAVE_ACPI_APEI                           policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_HAVE_ACPI_APEI_NMI                       policy<{'amd64': 'y'}>
+CONFIG_HAVE_ALIGNED_STRUCT_PAGE                 policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_AUDITSYSCALL                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_BITREVERSE                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_HAVE_ARCH_COMPAT_MMAP_BASES              policy<{'amd64': 'y'}>
+CONFIG_HAVE_ARCH_COMPILER_H                     policy<{'arm64': 'y'}>
+CONFIG_HAVE_ARCH_HUGE_VMALLOC                   policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_ARCH_HUGE_VMAP                      policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_ARCH_JUMP_LABEL                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_JUMP_LABEL_RELATIVE            policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_KASAN                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_KASAN_HW_TAGS                  policy<{'arm64': 'y'}>
+CONFIG_HAVE_ARCH_KASAN_SW_TAGS                  policy<{'arm64': 'y'}>
+CONFIG_HAVE_ARCH_KASAN_VMALLOC                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_KCSAN                          policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_KFENCE                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_KGDB                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_ARCH_KGDB_QXFER_PKT                 policy<{'riscv64': 'y'}>
+CONFIG_HAVE_ARCH_KMSAN                          policy<{'amd64': 'y'}>
+CONFIG_HAVE_ARCH_MMAP_RND_BITS                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_ARCH_MMAP_RND_COMPAT_BITS           policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': '-', 'ppc64el': '-'}>
+CONFIG_HAVE_ARCH_NODE_DEV_GROUP                 policy<{'amd64': 'y'}>
+CONFIG_HAVE_ARCH_NVRAM_OPS                      policy<{'ppc64el': 'y'}>
+CONFIG_HAVE_ARCH_PFN_VALID                      policy<{'armhf': 'y'}>
+CONFIG_HAVE_ARCH_PREL32_RELOCATIONS             policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET        policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_SECCOMP                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_SECCOMP_FILTER                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_SOFT_DIRTY                     policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_STACKLEAK                      policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_ARCH_TRACEHOOK                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD       policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_HAVE_ARCH_USERFAULTFD_MINOR              policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_ARCH_USERFAULTFD_WP                 policy<{'amd64': 'y'}>
+CONFIG_HAVE_ARCH_VMAP_STACK                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES            policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_HAVE_ARM_ARCH_TIMER                      policy<{'armhf': 'y'}>
+CONFIG_HAVE_ARM_SCU                             policy<{'armhf': 'y'}>
+CONFIG_HAVE_ARM_SMCCC                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_HAVE_ARM_SMCCC_DISCOVERY                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_HAVE_ARM_TWD                             policy<{'armhf': 'y'}>
+CONFIG_HAVE_ASM_MODVERSIONS                     policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_BOOTMEM_INFO_NODE                   policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_HAVE_BUILDTIME_MCOUNT_SORT               policy<{'amd64': 'y', 'armhf': 'y'}>
+CONFIG_HAVE_CALL_THUNKS                         policy<{'amd64': 'y'}>
+CONFIG_HAVE_CLK                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_CLK_PREPARE                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_CMPXCHG_DOUBLE                      policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_CMPXCHG_LOCAL                       policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_CONTEXT_TRACKING_USER               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_CONTEXT_TRACKING_USER_OFFSTACK      policy<{'amd64': 'y'}>
+CONFIG_HAVE_C_RECORDMCOUNT                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_HAVE_DEBUG_KMEMLEAK                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_DEBUG_STACKOVERFLOW                 policy<{'ppc64el': 'y'}>
+CONFIG_HAVE_DMA_CONTIGUOUS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_DYNAMIC_FTRACE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_DYNAMIC_FTRACE_NO_PATCHABLE         policy<{'amd64': 'y'}>
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS            policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS        policy<{'arm64': 'y'}>
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS    policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS            policy<{'amd64': 'y', 'arm64': '-', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_EBPF_JIT                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_HAVE_EISA                                policy<{'amd64': 'y'}>
+CONFIG_HAVE_EXIT_THREAD                         policy<{'amd64': 'y', 'armhf': 'y'}>
+CONFIG_HAVE_FAST_GUP                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_HAVE_FENTRY                              policy<{'amd64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_FUNCTION_ARG_ACCESS_API             policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_FUNCTION_ERROR_INJECTION            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_FUNCTION_GRAPH_RETVAL               policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_FUNCTION_TRACER                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_HAVE_GCC_PLUGINS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_GENERIC_VDSO                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_HARDLOCKUP_DETECTOR_ARCH            policy<{'ppc64el': 'y'}>
+CONFIG_HAVE_HARDLOCKUP_DETECTOR_BUDDY           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF            policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_HAVE_HW_BREAKPOINT                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_HAVE_IMA_KEXEC                           policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_IMX_ANATOP                          policy<{'armhf': 'y'}>
+CONFIG_HAVE_IMX_GPC                             policy<{'armhf': 'y'}>
+CONFIG_HAVE_IMX_MMDC                            policy<{'armhf': 'y'}>
+CONFIG_HAVE_IMX_SRC                             policy<{'armhf': 'y'}>
+CONFIG_HAVE_INTEL_TXT                           policy<{'amd64': 'y'}>
+CONFIG_HAVE_IOREMAP_PROT                        policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK               policy<{'amd64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_IRQ_TIME_ACCOUNTING                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_JUMP_LABEL_HACK                     policy<{'amd64': 'y'}>
+CONFIG_HAVE_KCSAN_COMPILER                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_KERNEL_BZIP2                        policy<{'amd64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_KERNEL_GZIP                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_HAVE_KERNEL_LZ4                          policy<{'amd64': 'y', 'arm64': '-', 'armhf': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_HAVE_KERNEL_LZMA                         policy<{'amd64': 'y', 'arm64': '-', 'armhf': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_HAVE_KERNEL_LZO                          policy<{'amd64': 'y', 'arm64': '-', 'armhf': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_HAVE_KERNEL_UNCOMPRESSED                 policy<{'s390x': 'y'}>
+CONFIG_HAVE_KERNEL_XZ                           policy<{'amd64': 'y', 'arm64': '-', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_HAVE_KERNEL_ZSTD                         policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_HAVE_KPROBES                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_KPROBES_ON_FTRACE                   policy<{'amd64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_KRETPROBES                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_KVM                                 policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT             policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_KVM_DIRTY_RING                      policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_HAVE_KVM_DIRTY_RING_ACQ_REL              policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_HAVE_KVM_DIRTY_RING_TSO                  policy<{'amd64': 'y'}>
+CONFIG_HAVE_KVM_INVALID_WAKEUPS                 policy<{'s390x': 'y'}>
+CONFIG_HAVE_KVM_IRQCHIP                         policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_KVM_IRQ_BYPASS                      policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_HAVE_KVM_IRQ_ROUTING                     policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_KVM_MSI                             policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_KVM_NO_POLL                         policy<{'amd64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_KVM_PFNCACHE                        policy<{'amd64': 'y'}>
+CONFIG_HAVE_KVM_PM_NOTIFIER                     policy<{'amd64': 'y'}>
+CONFIG_HAVE_KVM_VCPU_ASYNC_IOCTL                policy<{'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_KVM_VCPU_RUN_PID_CHANGE             policy<{'arm64': 'y'}>
+CONFIG_HAVE_LD_DEAD_CODE_DATA_ELIMINATION       policy<{'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_LIVEPATCH                           policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_HAVE_MARCH_Z10_FEATURES                  policy<{'s390x': 'y'}>
+CONFIG_HAVE_MARCH_Z13_FEATURES                  policy<{'s390x': 'y'}>
+CONFIG_HAVE_MARCH_Z196_FEATURES                 policy<{'s390x': 'y'}>
+CONFIG_HAVE_MARCH_ZEC12_FEATURES                policy<{'s390x': 'y'}>
+CONFIG_HAVE_MEMBLOCK_PHYS_MAP                   policy<{'s390x': 'y'}>
+CONFIG_HAVE_MEMORYLESS_NODES                    policy<{'ppc64el': 'y'}>
+CONFIG_HAVE_MIXED_BREAKPOINTS_REGS              policy<{'amd64': 'y'}>
+CONFIG_HAVE_MMIOTRACE_SUPPORT                   policy<{'amd64': 'y'}>
+CONFIG_HAVE_MOD_ARCH_SPECIFIC                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_MOVE_PMD                            policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_MOVE_PUD                            policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_NMI                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_HAVE_NOINSTR_HACK                        policy<{'amd64': 'y'}>
+CONFIG_HAVE_NOINSTR_VALIDATION                  policy<{'amd64': 'y'}>
+CONFIG_HAVE_NOP_MCOUNT                          policy<{'s390x': 'y'}>
+CONFIG_HAVE_OBJTOOL                             policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_HAVE_OBJTOOL_MCOUNT                      policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_HAVE_OBJTOOL_NOP_MCOUNT                  policy<{'amd64': 'y'}>
+CONFIG_HAVE_OPTPROBES                           policy<{'amd64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_HAVE_PCI                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_PCSPKR_PLATFORM                     policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_HAVE_PERF_EVENTS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_PERF_EVENTS_NMI                     policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_HAVE_PERF_REGS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_PERF_USER_STACK_DUMP                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_PNETID                              policy<{'s390x': 'm'}>
+CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK          policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_PREEMPT_DYNAMIC                     policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_PREEMPT_DYNAMIC_CALL                policy<{'amd64': 'y'}>
+CONFIG_HAVE_PREEMPT_DYNAMIC_KEY                 policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_PROC_CPU                            policy<{'armhf': 'y'}>
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_RELIABLE_STACKTRACE                 policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_HAVE_RETHOOK                             policy<{'amd64': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_RSEQ                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_RUST                                policy<{'amd64': 'y'}>
+CONFIG_HAVE_SAMPLE_FTRACE_DIRECT                policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_SAMPLE_FTRACE_DIRECT_MULTI          policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_SCHED_AVG_IRQ                       policy<{'ppc64el': 'y'}>
+CONFIG_HAVE_SETUP_PER_CPU_AREA                  policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_SMP                                 policy<{'armhf': 'y'}>
+CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_STACKPROTECTOR                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HAVE_STACK_VALIDATION                    policy<{'amd64': 'y'}>
+CONFIG_HAVE_STATIC_CALL                         policy<{'amd64': 'y'}>
+CONFIG_HAVE_STATIC_CALL_INLINE                  policy<{'amd64': 'y'}>
+CONFIG_HAVE_SYSCALL_TRACEPOINTS                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_UACCESS_VALIDATION                  policy<{'amd64': 'y'}>
+CONFIG_HAVE_UID16                               policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': '-', 'armhf': 'y', 's390x': '-'}>
+CONFIG_HAVE_UNSTABLE_SCHED_CLOCK                policy<{'amd64': 'y'}>
+CONFIG_HAVE_USER_RETURN_NOTIFIER                policy<{'amd64': 'y'}>
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING                 policy<{'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_IDLE            policy<{'s390x': 'y'}>
+CONFIG_HBMC_AM654                               policy<{'arm64': 'm'}>
+CONFIG_HCALL_STATS                              policy<{'ppc64el': 'n'}>
+CONFIG_HD44780                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HD44780_COMMON                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HDC100X                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HDC2010                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HDC3020                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HDLC                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HDLC_CISCO                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HDLC_FR                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HDLC_PPP                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HDLC_RAW                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HDLC_RAW_ETH                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HDLC_X25                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HDMI                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HDMI_LPE_AUDIO                           policy<{'amd64': 'm'}>
+CONFIG_HDQ_MASTER_OMAP                          policy<{'armhf': 'm'}>
+CONFIG_HEADERS_INSTALL                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_HFI1_DEBUG_SDMA_ORDER                    policy<{'amd64': 'n'}>
+CONFIG_HFSPLUS_FS                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_HFS_FS                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_HI13X1_GMAC                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_HI3660_MBOX                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HI6220_MBOX                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HI6421V600_IRQ                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HI8435                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HIBERNATE_CALLBACKS                      policy<{'amd64': 'y', 'armhf': 'y', 'riscv64': '-'}>
+CONFIG_HIBERNATION_SNAPSHOT_DEV                 policy<{'amd64': 'y', 'armhf': 'y', 'riscv64': '-'}>
+CONFIG_HID                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HIDRAW                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_HID_A4TECH                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_ACCUTOUCH                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_ACRUX                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_ACRUX_FF                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HID_ALPS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_APPLE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_APPLEIR                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_ASUS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_AUREAL                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_BATTERY_STRENGTH                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_HID_BELKIN                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_BETOP_FF                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_BIGBEN_FF                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_BPF                                  policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_HID_CHERRY                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_CHICONY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_CMEDIA                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_CORSAIR                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_COUGAR                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_CP2112                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_CREATIVE_SB0540                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_CYPRESS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_DRAGONRISE                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_ELAN                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_ELECOM                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_ELO                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_EMS_FF                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_EVISION                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_EZKEY                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_FT260                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_GEMBIRD                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_GENERIC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_GFRM                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_GLORIOUS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_GOOGLE_HAMMER                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HID_GOOGLE_STADIA_FF                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_GREENASIA                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_GT683R                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_GYRATION                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_HOLTEK                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_HYPERV_MOUSE                         policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_HID_ICADE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_ITE                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_JABRA                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_KENSINGTON                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_KEYTOUCH                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_KYE                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_LCPOWER                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_LED                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_LENOVO                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_LETSKETCH                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_LOGITECH                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_LOGITECH_DJ                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_LOGITECH_HIDPP                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_MACALLY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_MAGICMOUSE                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_MALTRON                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_MAYFLASH                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_MCP2200                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_MCP2221                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_MEGAWORLD_FF                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_MICROSOFT                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_MONTEREY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_MULTITOUCH                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_NINTENDO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_NTI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_NTRIG                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_NVIDIA_SHIELD                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_ORTEK                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_PANTHERLORD                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_PENMOUNT                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_PETALYNX                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_PICOLCD                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_PICOLCD_BACKLIGHT                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HID_PICOLCD_CIR                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HID_PICOLCD_FB                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HID_PICOLCD_LCD                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HID_PICOLCD_LEDS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HID_PID                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HID_PLANTRONICS                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_PLAYSTATION                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_PRIMAX                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_PRODIKEYS                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_PXRC                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_RAZER                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_REDRAGON                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_RETRODE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_RMI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_ROCCAT                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SAITEK                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_SAMSUNG                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SEMITEK                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_SENSOR_ACCEL_3D                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SENSOR_ALS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SENSOR_CUSTOM_INTEL_HINGE            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SENSOR_CUSTOM_SENSOR                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SENSOR_DEVICE_ROTATION               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SENSOR_GYRO_3D                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SENSOR_HUB                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_SENSOR_HUMIDITY                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SENSOR_IIO_COMMON                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SENSOR_IIO_TRIGGER                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SENSOR_INCLINOMETER_3D               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SENSOR_MAGNETOMETER_3D               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SENSOR_PRESS                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SENSOR_PROX                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SENSOR_TEMP                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SIGMAMICRO                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SMARTJOYPLUS                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_SONY                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_SPEEDLINK                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_STEAM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_STEELSERIES                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_SUNPLUS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_SUPPORT                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_HID_THINGM                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_THRUSTMASTER                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_TIVO                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_TOPRE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_TOPSEED                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_TWINHAN                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_U2FZERO                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_UCLOGIC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_UDRAW_PS3                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_VIEWSONIC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_VIVALDI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_VIVALDI_COMMON                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_VRC2                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_WACOM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_WALTOP                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_WIIMOTE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_XIAOMI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HID_XINMO                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_ZEROPLUS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HID_ZYDACRON                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HIGHMEM                                  policy<{'armhf': 'y'}>
+CONFIG_HIGHPTE                                  policy<{'armhf': 'y'}>
+CONFIG_HIGH_RES_TIMERS                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HINIC                                    policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_HIP04_ETH                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HIPPI                                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_HISILICON_ERRATUM_161010101              policy<{'arm64': 'y'}>
+CONFIG_HISILICON_ERRATUM_161600802              policy<{'arm64': 'y'}>
+CONFIG_HISILICON_ERRATUM_162100801              policy<{'arm64': 'y'}>
+CONFIG_HISILICON_IRQ_MBIGEN                     policy<{'arm64': 'y'}>
+CONFIG_HISILICON_LPC                            policy<{'arm64': 'y'}>
+CONFIG_HISI_ACC_VFIO_PCI                        policy<{'arm64': 'm'}>
+CONFIG_HISI_DMA                                 policy<{'arm64': 'n', 'armhf': 'm'}>
+CONFIG_HISI_FEMAC                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HISI_HIKEY_USB                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'n'}>
+CONFIG_HISI_PCIE_PMU                            policy<{'arm64': 'm'}>
+CONFIG_HISI_PMU                                 policy<{'arm64': 'm'}>
+CONFIG_HISI_PTT                                 policy<{'arm64': 'm'}>
+CONFIG_HISI_THERMAL                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HIST_TRIGGERS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_HIST_TRIGGERS_DEBUG                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 's390x': 'n'}>
+CONFIG_HIX5HD2_GMAC                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HMC425                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HMC6352                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_HMC_DRV                                  policy<{'s390x': 'm'}>
+CONFIG_HMEM_REPORTING                           policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_HMM_MIRROR                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HMS_ANYBUSS_BUS                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HMS_PROFINET                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HNS                                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HNS3                                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HNS3_DCB                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_HNS3_ENET                                policy<{'arm64': 'm'}>
+CONFIG_HNS3_HCLGE                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HNS3_HCLGEVF                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HNS3_PMU                                 policy<{'arm64': 'm'}>
+CONFIG_HNS_DSAF                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HNS_ENET                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HNS_MDIO                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HOLTEK_FF                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HOTPLUG_CORE_SYNC                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_HOTPLUG_CORE_SYNC_DEAD                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_HOTPLUG_CORE_SYNC_FULL                   policy<{'amd64': 'y'}>
+CONFIG_HOTPLUG_CPU                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HOTPLUG_PARALLEL                         policy<{'amd64': 'y'}>
+CONFIG_HOTPLUG_PCI                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HOTPLUG_PCI_ACPI                         policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_HOTPLUG_PCI_ACPI_AMPERE_ALTRA            policy<{'arm64': 'm'}>
+CONFIG_HOTPLUG_PCI_ACPI_IBM                     policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_HOTPLUG_PCI_CPCI                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HOTPLUG_PCI_CPCI_GENERIC                 policy<{'amd64': 'm'}>
+CONFIG_HOTPLUG_PCI_CPCI_ZT5550                  policy<{'amd64': 'm'}>
+CONFIG_HOTPLUG_PCI_POWERNV                      policy<{'ppc64el': 'm'}>
+CONFIG_HOTPLUG_PCI_RPA                          policy<{'ppc64el': 'm'}>
+CONFIG_HOTPLUG_PCI_RPA_DLPAR                    policy<{'ppc64el': 'm'}>
+CONFIG_HOTPLUG_PCI_S390                         policy<{'s390x': 'y'}>
+CONFIG_HOTPLUG_SMT                              policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_HOTPLUG_SPLIT_STARTUP                    policy<{'amd64': 'y'}>
+CONFIG_HP03                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HP206C                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HPET                                     policy<{'amd64': 'y'}>
+CONFIG_HPET_EMULATE_RTC                         policy<{'amd64': 'y'}>
+CONFIG_HPET_MMAP                                policy<{'amd64': 'y'}>
+CONFIG_HPET_MMAP_DEFAULT                        policy<{'amd64': 'y'}>
+CONFIG_HPET_TIMER                               policy<{'amd64': 'y'}>
+CONFIG_HPFS_FS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_HPWDT_NMI_DECODING                       policy<{'amd64': 'y'}>
+CONFIG_HP_ACCEL                                 policy<{'amd64': 'm'}>
+CONFIG_HP_BIOSCFG                               policy<{'amd64': 'm'}>
+CONFIG_HP_ILO                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_HP_WATCHDOG                              policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_HP_WMI                                   policy<{'amd64': 'm'}>
+CONFIG_HSA_AMD                                  policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_HSA_AMD_SVM                              policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_HSC030PA                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HSC030PA_I2C                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HSC030PA_SPI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HSI                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_HSI_BOARDINFO                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_HSI_CHAR                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HSR                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_HT16K33                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_HTC_EGPIO                                policy<{'armhf': 'y'}>
+CONFIG_HTE                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_HTE_TEGRA194                             policy<{'arm64': 'm'}>
+CONFIG_HTE_TEGRA194_TEST                        policy<{'arm64': 'm'}>
+CONFIG_HTS221                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HTS221_I2C                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HTS221_SPI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HTU21                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HUAWEI_WMI                               policy<{'amd64': 'm'}>
+CONFIG_HUGETLBFS                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HUGETLB_PAGE                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP            policy<{'amd64': 'y', 'arm64': '-', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP_DEFAULT_ON policy<{'amd64': 'n', 'arm64': '-', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_HUGETLB_PAGE_SIZE_VARIABLE               policy<{'ppc64el': 'y'}>
+CONFIG_HVCS                                     policy<{'ppc64el': 'm'}>
+CONFIG_HVC_CONSOLE                              policy<{'ppc64el': 'y'}>
+CONFIG_HVC_DCC                                  policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_HVC_DRIVER                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HVC_IRQ                                  policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_HVC_IUCV                                 policy<{'s390x': 'y'}>
+CONFIG_HVC_OLD_HVSI                             policy<{'ppc64el': 'y'}>
+CONFIG_HVC_OPAL                                 policy<{'ppc64el': 'y'}>
+CONFIG_HVC_RTAS                                 policy<{'ppc64el': 'y'}>
+CONFIG_HVC_XEN                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-'}>
+CONFIG_HVC_XEN_FRONTEND                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-'}>
+CONFIG_HV_PERF_CTRS                             policy<{'ppc64el': 'y'}>
+CONFIG_HWLAT_TRACER                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HWMON                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_HWMON_DEBUG_CHIP                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_HWMON_VID                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HWPOISON_INJECT                          policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}>
+CONFIG_HWSPINLOCK                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_HWSPINLOCK_OMAP                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HWSPINLOCK_QCOM                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HWSPINLOCK_SPRD                          policy<{'arm64': 'm'}>
+CONFIG_HWSPINLOCK_SUN6I                         policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_HW_CONSOLE                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HW_PERF_EVENTS                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_HW_RANDOM                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HW_RANDOM_AMD                            policy<{'amd64': 'm'}>
+CONFIG_HW_RANDOM_ARM_SMCCC_TRNG                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HW_RANDOM_BA431                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_HW_RANDOM_CAVIUM                         policy<{'arm64': 'm'}>
+CONFIG_HW_RANDOM_CCTRNG                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'n', 'riscv64': 'm'}>
+CONFIG_HW_RANDOM_CN10K                          policy<{'arm64': 'm'}>
+CONFIG_HW_RANDOM_EXYNOS                         policy<{'armhf': 'n'}>
+CONFIG_HW_RANDOM_HISI                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HW_RANDOM_HISTB                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HW_RANDOM_IMX_RNGC                       policy<{'armhf': 'm'}>
+CONFIG_HW_RANDOM_INTEL                          policy<{'amd64': 'm'}>
+CONFIG_HW_RANDOM_JH7110                         policy<{'riscv64': 'm'}>
+CONFIG_HW_RANDOM_MESON                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HW_RANDOM_MTK                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HW_RANDOM_NPCM                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HW_RANDOM_OMAP                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HW_RANDOM_OPTEE                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_HW_RANDOM_POLARFIRE_SOC                  policy<{'riscv64': 'm'}>
+CONFIG_HW_RANDOM_POWERNV                        policy<{'ppc64el': 'm'}>
+CONFIG_HW_RANDOM_PSERIES                        policy<{'ppc64el': 'm'}>
+CONFIG_HW_RANDOM_S390                           policy<{'s390x': 'm'}>
+CONFIG_HW_RANDOM_STM32                          policy<{'arm64': 'm'}>
+CONFIG_HW_RANDOM_TIMERIOMEM                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_HW_RANDOM_TPM                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_HW_RANDOM_VIA                            policy<{'amd64': 'm'}>
+CONFIG_HW_RANDOM_VIRTIO                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_HW_RANDOM_XGENE                          policy<{'arm64': 'm'}>
+CONFIG_HW_RANDOM_XIPHERA                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_HX711                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_HYPERV                                   policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_HYPERVISOR_GUEST                         policy<{'amd64': 'y'}>
+CONFIG_HYPERV_BALLOON                           policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_HYPERV_IOMMU                             policy<{'amd64': 'y'}>
+CONFIG_HYPERV_KEYBOARD                          policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_HYPERV_NET                               policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_HYPERV_STORAGE                           policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_HYPERV_TESTING                           policy<{'amd64': 'n', 'arm64': 'n'}>
+CONFIG_HYPERV_TIMER                             policy<{'amd64': 'y'}>
+CONFIG_HYPERV_UTILS                             policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_HYPERV_VSOCKETS                          policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_HYPERV_VTL_MODE                          policy<{'amd64': 'n'}>
+CONFIG_HZ                                       policy<{'amd64': '1000', 'arm64': '1000', 'armhf': '250', 'ppc64el': '250', 'riscv64': '250', 's390x': '100'}>
+CONFIG_HZ_200                                   policy<{'armhf': 'n'}>
+CONFIG_HZ_300                                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_HZ_500                                   policy<{'armhf': 'n'}>
+CONFIG_HZ_FIXED                                 policy<{'armhf': '0'}>
+CONFIG_HZ_PERIODIC                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_I2C                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_I2CR_SCOM                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_ALGOBIT                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_I2C_ALGOPCA                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_ALI1535                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_ALI1563                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_ALI15X3                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_ALTERA                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_AMD756                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_AMD756_S4882                         policy<{'amd64': 'm'}>
+CONFIG_I2C_AMD8111                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_AMD_MP2                              policy<{'amd64': 'm', 'arm64': 'n', 'riscv64': 'n'}>
+CONFIG_I2C_APPLE                                policy<{'arm64': 'm'}>
+CONFIG_I2C_ARB_GPIO_CHALLENGE                   policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_ASPEED                               policy<{'armhf': 'm'}>
+CONFIG_I2C_ATR                                  policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_I2C_AXXIA                                policy<{'armhf': 'm'}>
+CONFIG_I2C_BOARDINFO                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_I2C_CADENCE                              policy<{'arm64': 'n'}>
+CONFIG_I2C_CBUS_GPIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_CCGX_UCSI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_CHT_WC                               policy<{'amd64': 'm'}>
+CONFIG_I2C_COMPAT                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_I2C_CP2615                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_I2C_CROS_EC_TUNNEL                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_DEBUG_ALGO                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_I2C_DEBUG_BUS                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_I2C_DEBUG_CORE                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_I2C_DEMUX_PINCTRL                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_DESIGNWARE_BAYTRAIL                  policy<{'amd64': 'y'}>
+CONFIG_I2C_DESIGNWARE_CORE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_I2C_DESIGNWARE_PCI                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_DESIGNWARE_PLATFORM                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_I2C_DESIGNWARE_SLAVE                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_I2C_DIOLAN_U2C                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_I2C_DLN2                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_EMEV2                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_I2C_EXYNOS5                              policy<{'armhf': 'n'}>
+CONFIG_I2C_FSI                                  policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_GPIO                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_GPIO_FAULT_INJECTOR                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_I2C_GXP                                  policy<{'armhf': 'm'}>
+CONFIG_I2C_HELPER_AUTO                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_I2C_HID                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_HID_ACPI                             policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_HID_CORE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_HID_OF                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_HID_OF_ELAN                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_HID_OF_GOODIX                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_HISI                                 policy<{'arm64': 'm'}>
+CONFIG_I2C_HIX5HD2                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_I801                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_IMX                                  policy<{'arm64': 'm', 'armhf': 'y'}>
+CONFIG_I2C_IMX_LPI2C                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_ISCH                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_ISMT                                 policy<{'amd64': 'm'}>
+CONFIG_I2C_KEMPLD                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_LJCA                                 policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_MESON                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_MICROCHIP_CORE                       policy<{'riscv64': 'm'}>
+CONFIG_I2C_MLXBF                                policy<{'arm64': 'm'}>
+CONFIG_I2C_MLXCPLD                              policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_I2C_MPC                                  policy<{'ppc64el': 'm'}>
+CONFIG_I2C_MT65XX                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_MUX                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_I2C_MUX_GPIO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_MUX_GPMUX                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_MUX_LTC4306                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_MUX_MLXCPLD                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_MUX_PCA9541                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_MUX_PCA954x                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_MUX_PINCTRL                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_MUX_REG                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_MV64XXX                              policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_NFORCE2                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_NFORCE2_S4985                        policy<{'amd64': 'm'}>
+CONFIG_I2C_NOMADIK                              policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_NPCM                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_NVIDIA_GPU                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_OCORES                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_OMAP                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_I2C_OPAL                                 policy<{'ppc64el': 'y'}>
+CONFIG_I2C_OWL                                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_PARPORT                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_PCA_PLATFORM                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_PCI1XXXX                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_PIIX4                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_PXA                                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_PXA_SLAVE                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_I2C_QCOM_CCI                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_QCOM_GENI                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_QUP                                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_RCAR                                 policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_RIIC                                 policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_RK3X                                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_ROBOTFUZZ_OSIF                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_I2C_RZV2M                                policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_S3C2410                              policy<{'armhf': 'n'}>
+CONFIG_I2C_SCMI                                 policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_SH_MOBILE                            policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_SI470X                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_SI4713                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_SIMTEC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_SIS5595                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_SIS630                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_SIS96X                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_SLAVE                                policy<{'amd64': 'n', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'n', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_I2C_SLAVE_EEPROM                         policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_SLAVE_TESTUNIT                       policy<{'arm64': 'n', 'armhf': 'n', 'riscv64': 'n'}>
+CONFIG_I2C_SMBUS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_SPRD                                 policy<{'arm64': 'y'}>
+CONFIG_I2C_STM32F4                              policy<{'arm64': 'm'}>
+CONFIG_I2C_STM32F7                              policy<{'arm64': 'm'}>
+CONFIG_I2C_STUB                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_I2C_SYNQUACER                            policy<{'arm64': 'm'}>
+CONFIG_I2C_TAOS_EVM                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_TEGRA                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_TEGRA_BPMP                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_THUNDERX                             policy<{'arm64': 'm'}>
+CONFIG_I2C_TINY_USB                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_I2C_VERSATILE                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_I2C_VIA                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_VIAPRO                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_VIPERBOARD                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_I2C_VIRTIO                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_XGENE_SLIMPRO                        policy<{'arm64': 'm'}>
+CONFIG_I2C_XILINX                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I2C_XLP9XX                               policy<{'arm64': 'm'}>
+CONFIG_I3C                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I40E                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_I40EVF                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_I40E_DCB                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_I6300ESB_WDT                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_I82092                                   policy<{'amd64': 'm'}>
+CONFIG_I8253_LOCK                               policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_I8254                                    policy<{'amd64': 'm'}>
+CONFIG_I8K                                      policy<{'amd64': 'y'}>
+CONFIG_IA32_EMULATION                           policy<{'amd64': 'y'}>
+CONFIG_IA32_EMULATION_DEFAULT_DISABLED          policy<{'amd64': 'n'}>
+CONFIG_IA32_FEAT_CTL                            policy<{'amd64': 'y'}>
+CONFIG_IAQCORE                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IAVF                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IB700_WDT                                policy<{'amd64': 'm'}>
+CONFIG_IBMASR                                   policy<{'amd64': 'm'}>
+CONFIG_IBMVETH                                  policy<{'ppc64el': 'm'}>
+CONFIG_IBMVIO                                   policy<{'ppc64el': 'y'}>
+CONFIG_IBMVMC                                   policy<{'ppc64el': 'm'}>
+CONFIG_IBM_ASM                                  policy<{'amd64': 'm'}>
+CONFIG_IBM_BSR                                  policy<{'ppc64el': 'm'}>
+CONFIG_IBM_PARTITION                            policy<{'s390x': 'y'}>
+CONFIG_IBM_RTL                                  policy<{'amd64': 'm'}>
+CONFIG_ICE                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ICE_HWMON                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ICE_HWTS                                 policy<{'amd64': 'y'}>
+CONFIG_ICE_SWITCHDEV                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ICP10100                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ICPLUS_PHY                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ICS932S401                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_IDEAPAD_LAPTOP                           policy<{'amd64': 'm'}>
+CONFIG_IDLE_INJECT                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IDPF                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IE6XX_WDT                                policy<{'amd64': 'm'}>
+CONFIG_IEEE802154                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_IEEE802154_6LOWPAN                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IEEE802154_ADF7242                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IEEE802154_AT86RF230                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IEEE802154_ATUSB                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IEEE802154_CA8210                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IEEE802154_CA8210_DEBUGFS                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IEEE802154_CC2520                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IEEE802154_DRIVERS                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IEEE802154_FAKELB                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IEEE802154_HWSIM                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IEEE802154_MCR20A                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IEEE802154_MRF24J40                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IEEE802154_NL802154_EXPERIMENTAL         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_IEEE802154_SOCKET                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IFB                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IFCVF                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IGB                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_IGBVF                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_IGB_DCA                                  policy<{'amd64': 'y'}>
+CONFIG_IGB_HWMON                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IGC                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_IIO                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_IIO_ADIS_LIB                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ADIS_LIB_BUFFER                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IIO_BACKEND                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_BUFFER                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IIO_BUFFER_CB                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_BUFFER_DMA                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_BUFFER_DMAENGINE                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_BUFFER_HW_CONSUMER                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_CONFIGFS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_CONSUMERS_PER_TRIGGER                policy<{'amd64': '2', 'arm64': '2', 'armhf': '2', 'ppc64el': '2', 'riscv64': '2'}>
+CONFIG_IIO_CROS_EC_ACCEL_LEGACY                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IIO_CROS_EC_BARO                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IIO_CROS_EC_LIGHT_PROX                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IIO_CROS_EC_SENSORS                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IIO_CROS_EC_SENSORS_CORE                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IIO_CROS_EC_SENSORS_LID_ANGLE            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IIO_GTS_HELPER                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_HRTIMER_TRIGGER                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_INTERRUPT_TRIGGER                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_INV_SENSORS_TIMESTAMP                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_KFIFO_BUF                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_KX022A                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_KX022A_I2C                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_KX022A_SPI                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_MS_SENSORS_I2C                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_MUX                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_RESCALE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_SCMI                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IIO_SIMPLE_DUMMY                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_SSP_SENSORHUB                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_SSP_SENSORS_COMMONS                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_STM32_LPTIMER_TRIGGER                policy<{'arm64': 'm'}>
+CONFIG_IIO_STM32_TIMER_TRIGGER                  policy<{'arm64': 'm'}>
+CONFIG_IIO_ST_ACCEL_3AXIS                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_ACCEL_I2C_3AXIS                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_ACCEL_SPI_3AXIS                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_GYRO_3AXIS                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_GYRO_I2C_3AXIS                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_GYRO_SPI_3AXIS                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_LSM6DSX                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_LSM6DSX_I2C                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_LSM6DSX_I3C                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_LSM6DSX_SPI                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_LSM9DS0                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_LSM9DS0_I2C                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_LSM9DS0_SPI                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_MAGN_3AXIS                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_MAGN_I2C_3AXIS                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_MAGN_SPI_3AXIS                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_PRESS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_PRESS_I2C                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_PRESS_SPI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_SENSORS_CORE                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_SENSORS_I2C                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_ST_SENSORS_SPI                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_SW_DEVICE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_SW_TRIGGER                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_SYSFS_TRIGGER                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_TIGHTLOOP_TRIGGER                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_TRIGGER                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IIO_TRIGGERED_BUFFER                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IIO_TRIGGERED_EVENT                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IKCONFIG                                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IKHEADERS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ILLEGAL_POINTER_VALUE                    policy<{'amd64': '0xdead000000000000', 'arm64': '0xdead000000000000', 'ppc64el': '0x5deadbeef0000000', 'riscv64': '0xdead000000000000'}>
+CONFIG_IMA_APPRAISE_BOOTPARAM                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IMA_APPRAISE_BUILD_POLICY                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IMA_APPRAISE_MODSIG                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IMA_BLACKLIST_KEYRING                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IMA_DEFAULT_HASH                         policy<{'amd64': '"sha256"', 'arm64': '"sha256"', 'armhf': '"sha256"', 'ppc64el': '"sha256"', 'riscv64': '"sha256"', 's390x': '"sha256"'}>
+CONFIG_IMA_DEFAULT_HASH_SHA1                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IMA_DEFAULT_HASH_SHA512                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IMA_DEFAULT_TEMPLATE                     policy<{'amd64': '"ima-ng"', 'arm64': '"ima-ng"', 'armhf': '"ima-ng"', 'ppc64el': '"ima-sig"', 'riscv64': '"ima-ng"', 's390x': '"ima-ng"'}>
+CONFIG_IMA_DISABLE_HTABLE                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IMA_LOAD_X509                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IMA_LSM_RULES                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IMA_MEASURE_PCR_IDX                      policy<{'amd64': '10', 'arm64': '10', 'armhf': '10', 'ppc64el': '10', 'riscv64': '10', 's390x': '10'}>
+CONFIG_IMA_NG_TEMPLATE                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'n', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IMA_QUEUE_EARLY_BOOT_KEYS                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_IMG_ASCII_LCD                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_IMX2_WDT                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX7D_ADC                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX7ULP_WDT                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX8MM_THERMAL                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX8M_BLK_CTRL                           policy<{'arm64': 'y'}>
+CONFIG_IMX8QXP_ADC                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX93_ADC                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX9_BLK_CTRL                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_IMX_DMA                                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX_DSP                                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX_DSP_REMOTEPROC                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX_GPCV2                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_IMX_GPCV2_PM_DOMAINS                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_IMX_INTMUX                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_IMX_IPUV3_CORE                           policy<{'armhf': 'm'}>
+CONFIG_IMX_IRQSTEER                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_IMX_MBOX                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX_MU_MSI                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX_REMOTEPROC                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX_SCU                                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_IMX_SCU_PD                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_IMX_SC_THERMAL                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX_SC_WDT                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX_SDMA                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX_THERMAL                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IMX_WEIM                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_INA2XX_ADC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INDIRECT_PIO                             policy<{'arm64': 'y'}>
+CONFIG_INET                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INET6_AH                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET6_ESP                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET6_ESPINTCP                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INET6_ESP_OFFLOAD                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET6_IPCOMP                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET6_TUNNEL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET6_XFRM_TUNNEL                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET_AH                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET_DCCP_DIAG                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET_DIAG                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET_DIAG_DESTROY                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INET_ESP                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET_ESPINTCP                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INET_ESP_OFFLOAD                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET_IPCOMP                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET_MPTCP_DIAG                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET_RAW_DIAG                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET_SCTP_DIAG                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET_TABLE_PERTURB_ORDER                 policy<{'amd64': '16', 'arm64': '16', 'armhf': '16', 'ppc64el': '16', 'riscv64': '16', 's390x': '16'}>
+CONFIG_INET_TCP_DIAG                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET_TUNNEL                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET_UDP_DIAG                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INET_XFRM_TUNNEL                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INFINIBAND                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INFINIBAND_ADDR_TRANS                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INFINIBAND_ADDR_TRANS_CONFIGFS           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INFINIBAND_BNXT_RE                       policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INFINIBAND_CXGB4                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INFINIBAND_EFA                           policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INFINIBAND_ERDMA                         policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_INFINIBAND_HFI1                          policy<{'amd64': 'm'}>
+CONFIG_INFINIBAND_HNS_HIP08                     policy<{'arm64': 'm'}>
+CONFIG_INFINIBAND_IPOIB                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INFINIBAND_IPOIB_CM                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INFINIBAND_IPOIB_DEBUG                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_INFINIBAND_IRDMA                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INFINIBAND_ISER                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INFINIBAND_ISERT                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INFINIBAND_MTHCA                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INFINIBAND_MTHCA_DEBUG                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_INFINIBAND_OCRDMA                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_INFINIBAND_ON_DEMAND_PAGING              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INFINIBAND_OPA_VNIC                      policy<{'amd64': 'm'}>
+CONFIG_INFINIBAND_QEDR                          policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INFINIBAND_QIB                           policy<{'amd64': 'm'}>
+CONFIG_INFINIBAND_QIB_DCA                       policy<{'amd64': 'y'}>
+CONFIG_INFINIBAND_RDMAVT                        policy<{'amd64': 'm'}>
+CONFIG_INFINIBAND_RTRS                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INFINIBAND_RTRS_CLIENT                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INFINIBAND_RTRS_SERVER                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INFINIBAND_SRP                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INFINIBAND_SRPT                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INFINIBAND_USER_ACCESS                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INFINIBAND_USER_MAD                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INFINIBAND_USER_MEM                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INFINIBAND_USNIC                         policy<{'amd64': 'm'}>
+CONFIG_INFINIBAND_VIRT_DMA                      policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INFINIBAND_VMWARE_PVRDMA                 policy<{'amd64': 'm', 'arm64': 'm', 'arm64-generic-64k': '-', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_INFTL                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INITRAMFS_PRESERVE_MTIME                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INITRAMFS_SOURCE                         policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'ppc64el': '""', 'riscv64': '""', 's390x': '""'}>
+CONFIG_INIT_ENV_ARG_LIMIT                       policy<{'amd64': '32', 'arm64': '32', 'armhf': '32', 'ppc64el': '32', 'riscv64': '32', 's390x': '32'}>
+CONFIG_INIT_ON_ALLOC_DEFAULT_ON                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INIT_ON_FREE_DEFAULT_ON                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_INIT_STACK_ALL_PATTERN                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_INIT_STACK_ALL_ZERO                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INIT_STACK_NONE                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_INLINE_READ_LOCK                         policy<{'s390x': 'y'}>
+CONFIG_INLINE_READ_LOCK_BH                      policy<{'s390x': 'y'}>
+CONFIG_INLINE_READ_LOCK_IRQ                     policy<{'s390x': 'y'}>
+CONFIG_INLINE_READ_LOCK_IRQSAVE                 policy<{'s390x': 'y'}>
+CONFIG_INLINE_READ_TRYLOCK                      policy<{'s390x': 'y'}>
+CONFIG_INLINE_READ_UNLOCK                       policy<{'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_INLINE_READ_UNLOCK_BH                    policy<{'s390x': 'y'}>
+CONFIG_INLINE_READ_UNLOCK_IRQ                   policy<{'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_INLINE_READ_UNLOCK_IRQRESTORE            policy<{'s390x': 'y'}>
+CONFIG_INLINE_SPIN_LOCK                         policy<{'s390x': 'y'}>
+CONFIG_INLINE_SPIN_LOCK_BH                      policy<{'s390x': 'y'}>
+CONFIG_INLINE_SPIN_LOCK_IRQ                     policy<{'s390x': 'y'}>
+CONFIG_INLINE_SPIN_LOCK_IRQSAVE                 policy<{'s390x': 'y'}>
+CONFIG_INLINE_SPIN_TRYLOCK                      policy<{'s390x': 'y'}>
+CONFIG_INLINE_SPIN_TRYLOCK_BH                   policy<{'s390x': 'y'}>
+CONFIG_INLINE_SPIN_UNLOCK_BH                    policy<{'s390x': 'y'}>
+CONFIG_INLINE_SPIN_UNLOCK_IRQ                   policy<{'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE            policy<{'s390x': 'y'}>
+CONFIG_INLINE_WRITE_LOCK                        policy<{'s390x': 'y'}>
+CONFIG_INLINE_WRITE_LOCK_BH                     policy<{'s390x': 'y'}>
+CONFIG_INLINE_WRITE_LOCK_IRQ                    policy<{'s390x': 'y'}>
+CONFIG_INLINE_WRITE_LOCK_IRQSAVE                policy<{'s390x': 'y'}>
+CONFIG_INLINE_WRITE_TRYLOCK                     policy<{'s390x': 'y'}>
+CONFIG_INLINE_WRITE_UNLOCK                      policy<{'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_INLINE_WRITE_UNLOCK_BH                   policy<{'s390x': 'y'}>
+CONFIG_INLINE_WRITE_UNLOCK_IRQ                  policy<{'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE           policy<{'s390x': 'y'}>
+CONFIG_INOTIFY_USER                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INPUT                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INPUT_88PM80X_ONKEY                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_88PM860X_ONKEY                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_AD714X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_AD714X_I2C                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_AD714X_SPI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_ADXL34X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_ADXL34X_I2C                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_ADXL34X_SPI                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_APANEL                             policy<{'amd64': 'm'}>
+CONFIG_INPUT_ARIZONA_HAPTICS                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_ATC260X_ONKEY                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_ATI_REMOTE2                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_ATLAS_BTNS                         policy<{'amd64': 'm'}>
+CONFIG_INPUT_ATMEL_CAPTOUCH                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_AXP20X_PEK                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_BBNSM_PWRKEY                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INPUT_BMA150                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_CM109                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_CMA3000                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_CMA3000_I2C                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_CPCAP_PWRBUTTON                    policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_DA7280_HAPTICS                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_DA9052_ONKEY                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_DA9055_ONKEY                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_DA9063_ONKEY                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_DRV260X_HAPTICS                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_DRV2665_HAPTICS                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_DRV2667_HAPTICS                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_E3X0_BUTTON                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_EVBUG                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_INPUT_EVDEV                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INPUT_FF_MEMLESS                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_INPUT_GPIO_BEEPER                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_GPIO_DECODER                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_GPIO_ROTARY_ENCODER                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_GPIO_VIBRA                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_HISI_POWERKEY                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INPUT_IBM_PANEL                          policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_IDEAPAD_SLIDEBAR                   policy<{'amd64': 'm', 'ppc64el': 'm'}>
+CONFIG_INPUT_IMS_PCU                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_IQS269A                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_IQS626A                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_IQS7222                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_JOYDEV                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_INPUT_JOYSTICK                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_INPUT_KEYBOARD                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_INPUT_KEYSPAN_REMOTE                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_KXTJ9                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_LEDS                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_MATRIXKMAP                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_INPUT_MAX77650_ONKEY                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_MAX77693_HAPTIC                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_MAX8925_ONKEY                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_MAX8997_HAPTIC                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_MC13783_PWRBUTTON                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_MISC                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_INPUT_MMA8450                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_MOUSE                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_INPUT_MOUSEDEV                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_INPUT_MOUSEDEV_PSAUX                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_INPUT_MOUSEDEV_SCREEN_X                  policy<{'amd64': '1024', 'arm64': '1024', 'armhf': '1024', 'ppc64el': '1024', 'riscv64': '1024'}>
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y                  policy<{'amd64': '768', 'arm64': '768', 'armhf': '768', 'ppc64el': '768', 'riscv64': '768'}>
+CONFIG_INPUT_PALMAS_PWRBUTTON                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_PCAP                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_PCF50633_PMU                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_PCF8574                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_PCSPKR                             policy<{'amd64': 'm', 'ppc64el': 'm'}>
+CONFIG_INPUT_PM8941_PWRKEY                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INPUT_PM8XXX_VIBRATOR                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INPUT_PMIC8XXX_PWRKEY                    policy<{'armhf': 'm'}>
+CONFIG_INPUT_POWERMATE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_PWM_BEEPER                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_PWM_VIBRA                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_RAVE_SP_PWRBUTTON                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_REGULATOR_HAPTIC                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_RETU_PWRBUTTON                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_RK805_PWRKEY                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_RT5120_PWRKEY                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_SC27XX_VIBRA                       policy<{'arm64': 'm'}>
+CONFIG_INPUT_SOC_BUTTON_ARRAY                   policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_SPARSEKMAP                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_INPUT_STPMIC1_ONKEY                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_TABLET                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_INPUT_TOUCHSCREEN                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_INPUT_TPS65218_PWRBUTTON                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_TPS65219_PWRBUTTON                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INPUT_TWL4030_PWRBUTTON                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_TWL4030_VIBRA                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_TWL6040_VIBRA                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_VIVALDIFMAP                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_INPUT_WM831X_ON                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INPUT_XEN_KBDDEV_FRONTEND                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_INPUT_YEALINK                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INSPUR_PLATFORM_PROFILE                  policy<{'amd64': 'm'}>
+CONFIG_INSTRUCTION_DECODER                      policy<{'amd64': 'y'}>
+CONFIG_INT3406_THERMAL                          policy<{'amd64': 'm'}>
+CONFIG_INT340X_THERMAL                          policy<{'amd64': 'm'}>
+CONFIG_INTEGRITY                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INTEGRITY_ASYMMETRIC_KEYS                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INTEGRITY_AUDIT                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INTEGRITY_CA_MACHINE_KEYRING             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'n'}>
+CONFIG_INTEGRITY_CA_MACHINE_KEYRING_MAX         policy<{'ppc64el': 'y'}>
+CONFIG_INTEGRITY_MACHINE_KEYRING                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_INTEGRITY_SIGNATURE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INTEGRITY_TRUSTED_KEYRING                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INTEL_ATOMISP2_LED                       policy<{'amd64': 'm'}>
+CONFIG_INTEL_ATOMISP2_PDX86                     policy<{'amd64': 'y'}>
+CONFIG_INTEL_BXTWC_PMIC_TMU                     policy<{'amd64': 'm'}>
+CONFIG_INTEL_BXT_PMIC_THERMAL                   policy<{'amd64': 'm'}>
+CONFIG_INTEL_BYTCRC_PWRSRC                      policy<{'amd64': 'm'}>
+CONFIG_INTEL_CHTDC_TI_PWRBTN                    policy<{'amd64': 'm'}>
+CONFIG_INTEL_CHTWC_INT33FE                      policy<{'amd64': 'm'}>
+CONFIG_INTEL_GTT                                policy<{'amd64': 'y'}>
+CONFIG_INTEL_HFI_THERMAL                        policy<{'amd64': 'y'}>
+CONFIG_INTEL_HID_EVENT                          policy<{'amd64': 'm'}>
+CONFIG_INTEL_IDLE                               policy<{'amd64': 'y'}>
+CONFIG_INTEL_IDMA64                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_INTEL_IDXD                               policy<{'amd64': 'm'}>
+CONFIG_INTEL_IDXD_BUS                           policy<{'amd64': 'm'}>
+CONFIG_INTEL_IDXD_COMPAT                        policy<{'amd64': 'n'}>
+CONFIG_INTEL_IDXD_PERFMON                       policy<{'amd64': 'y'}>
+CONFIG_INTEL_IDXD_SVM                           policy<{'amd64': 'y'}>
+CONFIG_INTEL_IFS                                policy<{'amd64': 'm'}>
+CONFIG_INTEL_INT0002_VGPIO                      policy<{'amd64': 'm'}>
+CONFIG_INTEL_IOATDMA                            policy<{'amd64': 'm'}>
+CONFIG_INTEL_IOMMU                              policy<{'amd64': 'y'}>
+CONFIG_INTEL_IOMMU_FLOPPY_WA                    policy<{'amd64': 'y'}>
+CONFIG_INTEL_IOMMU_PERF_EVENTS                  policy<{'amd64': 'y'}>
+CONFIG_INTEL_IOMMU_SVM                          policy<{'amd64': 'y'}>
+CONFIG_INTEL_IPS                                policy<{'amd64': 'm'}>
+CONFIG_INTEL_ISHTP_ECLITE                       policy<{'amd64': 'm'}>
+CONFIG_INTEL_ISH_FIRMWARE_DOWNLOADER            policy<{'amd64': 'm'}>
+CONFIG_INTEL_ISH_HID                            policy<{'amd64': 'm'}>
+CONFIG_INTEL_LDMA                               policy<{'amd64': 'y'}>
+CONFIG_INTEL_MEI                                policy<{'amd64': 'm'}>
+CONFIG_INTEL_MEI_GSC                            policy<{'amd64': 'm'}>
+CONFIG_INTEL_MEI_GSC_PROXY                      policy<{'amd64': 'm'}>
+CONFIG_INTEL_MEI_HDCP                           policy<{'amd64': 'm'}>
+CONFIG_INTEL_MEI_ME                             policy<{'amd64': 'm'}>
+CONFIG_INTEL_MEI_PXP                            policy<{'amd64': 'm'}>
+CONFIG_INTEL_MEI_TXE                            policy<{'amd64': 'm'}>
+CONFIG_INTEL_MEI_VSC                            policy<{'amd64': 'm'}>
+CONFIG_INTEL_MEI_VSC_HW                         policy<{'amd64': 'm'}>
+CONFIG_INTEL_MEI_WDT                            policy<{'amd64': 'm'}>
+CONFIG_INTEL_MRFLD_ADC                          policy<{'amd64': 'm'}>
+CONFIG_INTEL_MRFLD_PWRBTN                       policy<{'amd64': 'm'}>
+CONFIG_INTEL_OAKTRAIL                           policy<{'amd64': 'm'}>
+CONFIG_INTEL_PCH_THERMAL                        policy<{'amd64': 'm'}>
+CONFIG_INTEL_PMC_CORE                           policy<{'amd64': 'm'}>
+CONFIG_INTEL_PMT_CLASS                          policy<{'amd64': 'm'}>
+CONFIG_INTEL_PMT_CRASHLOG                       policy<{'amd64': 'm'}>
+CONFIG_INTEL_PMT_TELEMETRY                      policy<{'amd64': 'm'}>
+CONFIG_INTEL_POWERCLAMP                         policy<{'amd64': 'm'}>
+CONFIG_INTEL_PUNIT_IPC                          policy<{'amd64': 'm'}>
+CONFIG_INTEL_QEP                                policy<{'amd64': 'm', 'arm64': '-', 'armhf': '-', 'ppc64el': '-'}>
+CONFIG_INTEL_RAPL                               policy<{'amd64': 'm'}>
+CONFIG_INTEL_RAPL_CORE                          policy<{'amd64': 'm'}>
+CONFIG_INTEL_RAPL_TPMI                          policy<{'amd64': 'm'}>
+CONFIG_INTEL_RST                                policy<{'amd64': 'm'}>
+CONFIG_INTEL_SAR_INT1092                        policy<{'amd64': 'm'}>
+CONFIG_INTEL_SCU                                policy<{'amd64': 'y'}>
+CONFIG_INTEL_SCU_IPC                            policy<{'amd64': 'y'}>
+CONFIG_INTEL_SCU_IPC_UTIL                       policy<{'amd64': 'm'}>
+CONFIG_INTEL_SCU_PCI                            policy<{'amd64': 'y'}>
+CONFIG_INTEL_SCU_PLATFORM                       policy<{'amd64': 'm'}>
+CONFIG_INTEL_SDSI                               policy<{'amd64': 'm'}>
+CONFIG_INTEL_SKL_INT3472                        policy<{'amd64': 'm'}>
+CONFIG_INTEL_SMARTCONNECT                       policy<{'amd64': 'm'}>
+CONFIG_INTEL_SOC_DTS_IOSF_CORE                  policy<{'amd64': 'm'}>
+CONFIG_INTEL_SOC_DTS_THERMAL                    policy<{'amd64': 'm'}>
+CONFIG_INTEL_SOC_PMIC                           policy<{'amd64': 'y'}>
+CONFIG_INTEL_SOC_PMIC_BXTWC                     policy<{'amd64': 'm'}>
+CONFIG_INTEL_SOC_PMIC_CHTDC_TI                  policy<{'amd64': 'm'}>
+CONFIG_INTEL_SOC_PMIC_CHTWC                     policy<{'amd64': 'y'}>
+CONFIG_INTEL_SOC_PMIC_MRFLD                     policy<{'amd64': 'm'}>
+CONFIG_INTEL_SPEED_SELECT_INTERFACE             policy<{'amd64': 'm'}>
+CONFIG_INTEL_SPEED_SELECT_TPMI                  policy<{'amd64': 'm'}>
+CONFIG_INTEL_STRATIX10_RSU                      policy<{'arm64': 'm'}>
+CONFIG_INTEL_STRATIX10_SERVICE                  policy<{'arm64': 'm'}>
+CONFIG_INTEL_TCC                                policy<{'amd64': 'y'}>
+CONFIG_INTEL_TCC_COOLING                        policy<{'amd64': 'm'}>
+CONFIG_INTEL_TDX_GUEST                          policy<{'amd64': 'y'}>
+CONFIG_INTEL_TELEMETRY                          policy<{'amd64': 'm'}>
+CONFIG_INTEL_TH                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INTEL_TH_ACPI                            policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_INTEL_TH_DEBUG                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_INTEL_TH_GTH                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INTEL_TH_MSU                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INTEL_TH_PCI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INTEL_TH_PTI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INTEL_TH_STH                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INTEL_TPMI                               policy<{'amd64': 'm'}>
+CONFIG_INTEL_TURBO_MAX_3                        policy<{'amd64': 'y'}>
+CONFIG_INTEL_TXT                                policy<{'amd64': 'y'}>
+CONFIG_INTEL_UNCORE_FREQ_CONTROL                policy<{'amd64': 'm'}>
+CONFIG_INTEL_UNCORE_FREQ_CONTROL_TPMI           policy<{'amd64': 'm'}>
+CONFIG_INTEL_VBTN                               policy<{'amd64': 'm'}>
+CONFIG_INTEL_VSC                                policy<{'amd64': 'm'}>
+CONFIG_INTEL_VSEC                               policy<{'amd64': 'm'}>
+CONFIG_INTEL_WMI                                policy<{'amd64': 'y'}>
+CONFIG_INTEL_WMI_SBL_FW_UPDATE                  policy<{'amd64': 'm'}>
+CONFIG_INTEL_WMI_THUNDERBOLT                    policy<{'amd64': 'm'}>
+CONFIG_INTEL_XWAY_PHY                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_INTERCONNECT                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_INTERCONNECT_CLK                         policy<{'arm64': 'm'}>
+CONFIG_INTERCONNECT_IMX                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_IMX8MM                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_IMX8MN                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_IMX8MP                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_IMX8MQ                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_INTERCONNECT_QCOM_BCM_VOTER              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_MSM8916                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_MSM8939                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_MSM8974                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_MSM8996                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_OSM_L3                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_QCM2290                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_QCS404                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_QDU1000                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_RPMH                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_RPMH_POSSIBLE          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_INTERCONNECT_QCOM_SA8775P                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SC7180                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SC7280                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SC8180X                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SC8280XP               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SDM660                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SDM670                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SDM845                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SDX55                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SDX65                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SDX75                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SM6115                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SM6350                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SM8150                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SM8250                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SM8350                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SM8450                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SM8550                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SM8650                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_SMD_RPM                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_QCOM_X1E80100               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_INTERCONNECT_SAMSUNG                     policy<{'armhf': 'n'}>
+CONFIG_INTERRUPT_CNT                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_INTERRUPT_SANITIZE_REGISTERS             policy<{'ppc64el': 'y'}>
+CONFIG_INTERVAL_TREE                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_INTERVAL_TREE_SPAN_ITER                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_INTERVAL_TREE_TEST                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_INV_ICM42600                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INV_ICM42600_I2C                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INV_ICM42600_SPI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INV_MPU6050_I2C                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INV_MPU6050_IIO                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_INV_MPU6050_SPI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IOMMUFD                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_IOMMUFD_DRIVER                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IOMMU_API                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IOMMU_DEBUG                              policy<{'amd64': 'n'}>
+CONFIG_IOMMU_DEFAULT_PASSTHROUGH                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IOMMU_DMA                                policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}>
+CONFIG_IOMMU_HELPER                             policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_IOMMU_IOVA                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'y'}>
+CONFIG_IOMMU_IO_PGTABLE                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y'}>
+CONFIG_IOMMU_IO_PGTABLE_ARMV7S                  policy<{'arm64': 'y', 'armhf': 'n'}>
+CONFIG_IOMMU_IO_PGTABLE_ARMV7S_SELFTEST         policy<{'arm64': 'n'}>
+CONFIG_IOMMU_IO_PGTABLE_DART                    policy<{'arm64': 'y'}>
+CONFIG_IOMMU_IO_PGTABLE_LPAE                    policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_IOMMU_IO_PGTABLE_LPAE_SELFTEST           policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_IOMMU_MM_DATA                            policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_IOMMU_SUPPORT                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IOMMU_SVA                                policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_IONIC                                    policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_IOSCHED_BFQ                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IOSF_MBI                                 policy<{'amd64': 'y'}>
+CONFIG_IOSF_MBI_DEBUG                           policy<{'amd64': 'y'}>
+CONFIG_IOSM                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IO_DELAY_0X80                            policy<{'amd64': 'n'}>
+CONFIG_IO_DELAY_0XED                            policy<{'amd64': 'y'}>
+CONFIG_IO_DELAY_NONE                            policy<{'amd64': 'n'}>
+CONFIG_IO_DELAY_UDELAY                          policy<{'amd64': 'n'}>
+CONFIG_IO_EVENT_IRQ                             policy<{'ppc64el': 'y'}>
+CONFIG_IO_STRICT_DEVMEM                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IO_URING                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IO_WQ                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP5XXX_POWER                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IP6_NF_FILTER                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_IPTABLES                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_MANGLE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_MATCH_AH                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_MATCH_EUI64                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_MATCH_FRAG                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_MATCH_HL                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_MATCH_IPV6HEADER                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_MATCH_MH                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_MATCH_OPTS                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_MATCH_RPFILTER                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_MATCH_RT                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_MATCH_SRH                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_NAT                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_RAW                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_SECURITY                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_TARGET_HL                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_TARGET_MASQUERADE                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_TARGET_NPT                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_TARGET_REJECT                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP6_NF_TARGET_SYNPROXY                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IPACK_BUS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_IPC_NS                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPMB_DEVICE_INTERFACE                    policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_IPMI_DEVICE_INTERFACE                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IPMI_DMI_DECODE                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y'}>
+CONFIG_IPMI_HANDLER                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_IPMI_IPMB                                policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_IPMI_KCS_BMC                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IPMI_KCS_BMC_CDEV_IPMI                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IPMI_KCS_BMC_SERIO                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IPMI_PANIC_EVENT                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_IPMI_PLAT_DATA                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IPMI_POWERNV                             policy<{'ppc64el': 'm'}>
+CONFIG_IPMI_POWEROFF                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IPMI_SI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IPMI_SSIF                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IPMI_WATCHDOG                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IPQ_APSS_6018                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IPQ_APSS_PLL                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IPQ_GCC_4019                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IPQ_GCC_5018                             policy<{'arm64': 'm'}>
+CONFIG_IPQ_GCC_5332                             policy<{'arm64': 'm'}>
+CONFIG_IPQ_GCC_6018                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IPQ_GCC_806X                             policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_IPQ_GCC_8074                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IPQ_GCC_9574                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IPQ_LCC_806X                             policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_IPU_BRIDGE                               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_IPV6_FOU                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IPV6_FOU_TUNNEL                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IPV6_GRE                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IPV6_ILA                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IPV6_IOAM6_LWTUNNEL                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPV6_MIP6                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IPV6_MROUTE                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPV6_MROUTE_MULTIPLE_TABLES              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPV6_MULTIPLE_TABLES                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPV6_NDISC_NODETYPE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPV6_OPTIMISTIC_DAD                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IPV6_PIMSM_V2                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPV6_ROUTER_PREF                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPV6_ROUTE_INFO                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPV6_RPL_LWTUNNEL                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IPV6_SEG6_BPF                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPV6_SEG6_HMAC                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPV6_SEG6_LWTUNNEL                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPV6_SIT                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IPV6_SIT_6RD                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPV6_SUBTREES                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPV6_TUNNEL                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IPV6_VTI                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IPVLAN                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IPVLAN_L3S                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IPVTAP                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IPW2100                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IPW2100_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_IPW2100_MONITOR                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IPW2200                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IPW2200_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_IPW2200_MONITOR                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IPW2200_PROMISCUOUS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IPW2200_QOS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IPW2200_RADIOTAP                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IPWIRELESS                               policy<{'amd64': 'm'}>
+CONFIG_IP_ADVANCED_ROUTER                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_DCCP                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_DCCP_CCID2_DEBUG                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IP_DCCP_CCID3                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'y'}>
+CONFIG_IP_DCCP_CCID3_DEBUG                      policy<{'s390x': 'n'}>
+CONFIG_IP_DCCP_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IP_DCCP_TFRC_LIB                         policy<{'s390x': 'y'}>
+CONFIG_IP_FIB_TRIE_STATS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_MROUTE                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_MROUTE_COMMON                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_MROUTE_MULTIPLE_TABLES                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_MULTICAST                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_MULTIPLE_TABLES                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_NF_ARPFILTER                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_ARPTABLES                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_ARP_MANGLE                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_FILTER                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_IPTABLES                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_MANGLE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_MATCH_AH                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_MATCH_ECN                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_MATCH_RPFILTER                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_MATCH_TTL                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_NAT                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_RAW                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_SECURITY                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_TARGET_ECN                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_TARGET_MASQUERADE                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_TARGET_NETMAP                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_TARGET_REDIRECT                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_TARGET_REJECT                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_TARGET_SYNPROXY                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_NF_TARGET_TTL                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_PIMSM_V1                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_PIMSM_V2                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_ROUTE_CLASSID                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_ROUTE_MULTIPATH                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_ROUTE_VERBOSE                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_SCTP                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_BITMAP_IP                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_BITMAP_IPMAC                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_BITMAP_PORT                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_HASH_IP                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_HASH_IPMAC                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_HASH_IPMARK                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_HASH_IPPORT                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_HASH_IPPORTIP                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_HASH_IPPORTNET                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_HASH_MAC                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_HASH_NET                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_HASH_NETIFACE                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_HASH_NETNET                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_HASH_NETPORT                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_HASH_NETPORTNET                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_LIST_SET                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_SET_MAX                               policy<{'amd64': '256', 'arm64': '256', 'armhf': '256', 'ppc64el': '256', 'riscv64': '256', 's390x': '256'}>
+CONFIG_IP_VS                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_DEBUG                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IP_VS_DH                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_FO                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_FTP                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_IPV6                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_VS_LBLC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_LBLCR                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_LC                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_MH                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_MH_TAB_INDEX                       policy<{'amd64': '12', 'arm64': '12', 'armhf': '12', 'ppc64el': '12', 'riscv64': '12', 's390x': '12'}>
+CONFIG_IP_VS_NFCT                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_VS_NQ                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_OVF                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_PE_SIP                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_PROTO_AH                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_VS_PROTO_AH_ESP                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_VS_PROTO_ESP                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_VS_PROTO_SCTP                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_VS_PROTO_TCP                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_VS_PROTO_UDP                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IP_VS_RR                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_SED                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_SH                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_SH_TAB_BITS                        policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'ppc64el': '8', 'riscv64': '8', 's390x': '8'}>
+CONFIG_IP_VS_TAB_BITS                           policy<{'amd64': '12', 'arm64': '12', 'armhf': '12', 'ppc64el': '12', 'riscv64': '12', 's390x': '12'}>
+CONFIG_IP_VS_TWOS                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_IP_VS_WLC                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IP_VS_WRR                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IQS620AT_TEMP                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IQS621_ALS                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IQS624_POS                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IRQCHIP                                  policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IRQSOFF_TRACER                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_IRQSTACKS                                policy<{'armhf': 'y'}>
+CONFIG_IRQ_ALL_CPUS                             policy<{'ppc64el': 'y'}>
+CONFIG_IRQ_BYPASS_MANAGER                       policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'm', 'ppc64el': 'y', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IRQ_CROSSBAR                             policy<{'armhf': 'y'}>
+CONFIG_IRQ_DOMAIN                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IRQ_DOMAIN_HIERARCHY                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_IRQ_FORCED_THREADING                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IRQ_MSI_IOMMU                            policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}>
+CONFIG_IRQ_POLL                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IRQ_REMAP                                policy<{'amd64': 'y'}>
+CONFIG_IRQ_SIM                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IRQ_STACKS                               policy<{'riscv64': 'y'}>
+CONFIG_IRQ_TIME_ACCOUNTING                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_IRQ_WORK                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_IRSD200                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_ENE                                   policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_IR_FINTEK                                policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_IR_GPIO_CIR                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_GPIO_TX                               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_HIX5HD2                               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_IGORPLUGUSB                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_IGUANA                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_IMON                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_IMON_DECODER                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_IMON_RAW                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_ITE_CIR                               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_IR_JVC_DECODER                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_MCEUSB                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_MCE_KBD_DECODER                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_MESON                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IR_MESON_TX                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IR_MTK                                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_IR_NEC_DECODER                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_NUVOTON                               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_IR_PWM_TX                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_RC5_DECODER                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_RC6_DECODER                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_RCMM_DECODER                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_REDRAT3                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_SANYO_DECODER                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_SERIAL                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_SERIAL_TRANSMITTER                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IR_SHARP_DECODER                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_SONY_DECODER                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_SPI                                   policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_STREAMZAP                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_SUNXI                                 policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_IR_TOY                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_TTUSBIR                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IR_WINBOND_CIR                           policy<{'amd64': 'm'}>
+CONFIG_IR_XMP_DECODER                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ISA_BUS                                  policy<{'amd64': 'y'}>
+CONFIG_ISA_BUS_API                              policy<{'amd64': 'y'}>
+CONFIG_ISA_DMA_API                              policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_ISCSI_BOOT_SYSFS                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ISCSI_IBFT                               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_ISCSI_IBFT_FIND                          policy<{'amd64': 'y'}>
+CONFIG_ISCSI_TARGET                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ISCSI_TARGET_CXGB4                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ISCSI_TCP                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ISDN                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ISDN_CAPI                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ISDN_CAPI_MIDDLEWARE                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ISL29003                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ISL29020                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ISL29125                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ISL29501                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ISL76682                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ISO9660_FS                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_IT8712F_WDT                              policy<{'amd64': 'm'}>
+CONFIG_IT87_WDT                                 policy<{'amd64': 'm'}>
+CONFIG_ITCO_VENDOR_SUPPORT                      policy<{'amd64': 'y'}>
+CONFIG_ITCO_WDT                                 policy<{'amd64': 'm'}>
+CONFIG_ITG3200                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IUCV                                     policy<{'s390x': 'y'}>
+CONFIG_IWL3945                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IWL4965                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IWLDVM                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IWLEGACY                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IWLEGACY_DEBUG                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_IWLEGACY_DEBUGFS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IWLMVM                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IWLWIFI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_IWLWIFI_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_IWLWIFI_DEBUGFS                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IWLWIFI_DEVICE_TRACING                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IWLWIFI_LEDS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IWLWIFI_OPMODE_MODULAR                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IXGBE                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_IXGBEVF                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_IXGBEVF_IPSEC                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IXGBE_DCA                                policy<{'amd64': 'y'}>
+CONFIG_IXGBE_DCB                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IXGBE_HWMON                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_IXGBE_IPSEC                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JAILHOUSE_GUEST                          policy<{'amd64': 'y'}>
+CONFIG_JBD2                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_JBD2_DEBUG                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_JFFS2_CMODE_FAVOURLZO                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JFFS2_CMODE_NONE                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_JFFS2_CMODE_PRIORITY                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_JFFS2_CMODE_SIZE                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_JFFS2_COMPRESSION_OPTIONS                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JFFS2_FS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_JFFS2_FS_DEBUG                           policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0'}>
+CONFIG_JFFS2_FS_POSIX_ACL                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JFFS2_FS_SECURITY                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JFFS2_FS_WBUF_VERIFY                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_JFFS2_FS_WRITEBUFFER                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JFFS2_FS_XATTR                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JFFS2_LZO                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JFFS2_RTIME                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JFFS2_RUBIN                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_JFFS2_SUMMARY                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_JFFS2_ZLIB                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JFS_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_JFS_FS                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_JFS_POSIX_ACL                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JFS_SECURITY                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JFS_STATISTICS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JH71XX_PMU                               policy<{'riscv64': 'y'}>
+CONFIG_JME                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_JOLIET                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_JOYSTICK_A3D                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_ADC                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_JOYSTICK_ADI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_ANALOG                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_AS5011                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_COBRA                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_DB9                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_JOYSTICK_FSIA6B                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_GAMECON                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_JOYSTICK_GF2K                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_GRIP                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_GRIP_MP                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_GUILLEMOT                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_IFORCE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_IFORCE_232                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_JOYSTICK_IFORCE_USB                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_JOYSTICK_INTERACT                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_JOYDUMP                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_MAGELLAN                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_PSXPAD_SPI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_PSXPAD_SPI_FF                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JOYSTICK_PXRC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_QWIIC                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_SEESAW                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_JOYSTICK_SENSEHAT                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_JOYSTICK_SIDEWINDER                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_SPACEBALL                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_SPACEORB                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_STINGER                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_TMDC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_TURBOGRAFX                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_JOYSTICK_TWIDJOY                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_WALKERA0701                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_JOYSTICK_WARRIOR                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_XPAD                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JOYSTICK_XPAD_FF                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JOYSTICK_XPAD_LEDS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_JOYSTICK_ZHENHUA                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_JSA1212                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_JUMP_LABEL                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_JUMP_LABEL_FEATURE_CHECKS                policy<{'ppc64el': 'y'}>
+CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG           policy<{'ppc64el': 'n'}>
+CONFIG_K3_DMA                                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_K3_RTI_WATCHDOG                          policy<{'arm64': 'm'}>
+CONFIG_K3_THERMAL                               policy<{'arm64': 'm'}>
+CONFIG_KALLSYMS                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KALLSYMS_ABSOLUTE_PERCPU                 policy<{'amd64': 'y'}>
+CONFIG_KALLSYMS_ALL                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KALLSYMS_SELFTEST                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_KARMA_PARTITION                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_KASAN                                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_KCMP                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KCOV                                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_KCSAN                                    policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 's390x': 'n'}>
+CONFIG_KDB_CONTINUE_CATASTROPHIC                policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0'}>
+CONFIG_KDB_DEFAULT_ENABLE                       policy<{'amd64': '0x1', 'arm64': '0x1', 'armhf': '0x1', 'ppc64el': '0x1', 'riscv64': '0x1'}>
+CONFIG_KDB_KEYBOARD                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_KEEMBAY_WATCHDOG                         policy<{'arm64': 'm'}>
+CONFIG_KEMPLD_WDT                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KERNEL_BZIP2                             policy<{'amd64': 'n', 's390x': 'n'}>
+CONFIG_KERNEL_GZIP                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'n'}>
+CONFIG_KERNEL_LZ4                               policy<{'amd64': 'n', 'arm64': '-', 'armhf': 'n', 'riscv64': '-', 's390x': 'n'}>
+CONFIG_KERNEL_LZMA                              policy<{'amd64': 'n', 'arm64': '-', 'armhf': 'n', 'riscv64': '-', 's390x': 'n'}>
+CONFIG_KERNEL_LZO                               policy<{'amd64': 'n', 'arm64': '-', 'armhf': 'n', 'riscv64': '-', 's390x': 'n'}>
+CONFIG_KERNEL_MODE_NEON                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_KERNEL_NOBP                              policy<{'s390x': 'n'}>
+CONFIG_KERNEL_START                             policy<{'ppc64el': '0xc000000000000000'}>
+CONFIG_KERNEL_UNCOMPRESSED                      policy<{'s390x': 'n'}>
+CONFIG_KERNEL_XZ                                policy<{'amd64': 'n', 'arm64': '-', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': '-', 's390x': 'n'}>
+CONFIG_KERNFS                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KEXEC                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KEXEC_CORE                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KEXEC_ELF                                policy<{'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_KEXEC_FILE                               policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KEXEC_IMAGE_VERIFY_SIG                   policy<{'arm64': 'y'}>
+CONFIG_KEXEC_JUMP                               policy<{'amd64': 'y'}>
+CONFIG_KEXEC_SIG                                policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}>
+CONFIG_KEXEC_SIG_FORCE                          policy<{'amd64': 'n'}>
+CONFIG_KEYBOARD_ADC                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KEYBOARD_ADP5520                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_ADP5588                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_ADP5589                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_APPLESPI                        policy<{'amd64': 'm'}>
+CONFIG_KEYBOARD_ATKBD                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_KEYBOARD_BCM                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KEYBOARD_CAP11XX                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KEYBOARD_CROS_EC                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_KEYBOARD_CYPRESS_SF                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KEYBOARD_DLINK_DIR685                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_GOLDFISH_EVENTS                 policy<{'riscv64': 'm'}>
+CONFIG_KEYBOARD_GPIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_GPIO_POLLED                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_IMX                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_KEYBOARD_IMX_SC_KEY                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_KEYBOARD_IQS62X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KEYBOARD_LKKBD                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_LM8323                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_LM8333                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_MATRIX                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_MAX7359                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_MCS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_MPR121                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_MT6779                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_KEYBOARD_MTK_PMIC                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KEYBOARD_NEWTON                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_NVEC                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_KEYBOARD_OMAP4                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KEYBOARD_OPENCORES                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_PINEPHONE                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KEYBOARD_PMIC8XXX                        policy<{'armhf': 'm'}>
+CONFIG_KEYBOARD_QT1050                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_QT1070                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_QT2160                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_SAMSUNG                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_SNVS_PWRKEY                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_KEYBOARD_STMPE                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KEYBOARD_STOWAWAY                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_SUN4I_LRADC                     policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_KEYBOARD_SUNKBD                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_TC3589X                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KEYBOARD_TCA6416                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_TCA8418                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_TEGRA                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_KEYBOARD_TM2_TOUCHKEY                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_TWL4030                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYBOARD_XTKBD                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KEYS                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KEYS_REQUEST_CACHE                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KEY_DH_OPERATIONS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KEY_NOTIFICATIONS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KFENCE                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KFENCE_DEFERRABLE                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_KFENCE_NUM_OBJECTS                       policy<{'amd64': '255', 'arm64': '255', 'armhf': '255', 'ppc64el': '255', 'riscv64': '255', 's390x': '255'}>
+CONFIG_KFENCE_SAMPLE_INTERVAL                   policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0', 's390x': '0'}>
+CONFIG_KFENCE_STRESS_TEST_FAULTS                policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0', 's390x': '0'}>
+CONFIG_KGDB                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_KGDB_HONOUR_BLOCKLIST                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_KGDB_KDB                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_KGDB_LOW_LEVEL_TRAP                      policy<{'amd64': 'y'}>
+CONFIG_KGDB_TESTS                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_KHADAS_MCU_FAN_THERMAL                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_KMAP_LOCAL                               policy<{'armhf': 'y'}>
+CONFIG_KMAP_LOCAL_NON_LINEAR_PTE_ARRAY          policy<{'armhf': 'y'}>
+CONFIG_KMX61                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KPROBES                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KPROBES_ON_FTRACE                        policy<{'amd64': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_KPROBE_EVENTS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KPROBE_EVENTS_ON_NOTRACE                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': '-', 's390x': 'n'}>
+CONFIG_KPROBE_EVENT_GEN_TEST                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_KPSS_XCC                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_KRAITCC                                  policy<{'armhf': 'm'}>
+CONFIG_KRAIT_CLOCKS                             policy<{'armhf': 'y'}>
+CONFIG_KRAIT_L2_ACCESSORS                       policy<{'armhf': 'y'}>
+CONFIG_KRETPROBES                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KRETPROBE_ON_RETHOOK                     policy<{'amd64': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KS0108                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KS0108_DELAY                             policy<{'amd64': '2', 'arm64': '2', 'armhf': '2', 'ppc64el': '2', 'riscv64': '2'}>
+CONFIG_KS0108_PORT                              policy<{'amd64': '0x378', 'arm64': '0x378', 'armhf': '0x378', 'ppc64el': '0x378', 'riscv64': '0x378'}>
+CONFIG_KS7010                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KS8842                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KS8851                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KS8851_MLL                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KSM                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KSZ884X_PCI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_KUNIT                                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_KUNPENG_HCCS                             policy<{'arm64': 'm'}>
+CONFIG_KUSER_HELPERS                            policy<{'arm64': 'y', 'arm64-generic-64k': '-', 'armhf': 'y'}>
+CONFIG_KVM_AMD                                  policy<{'amd64': 'm'}>
+CONFIG_KVM_AMD_SEV                              policy<{'amd64': 'y'}>
+CONFIG_KVM_ASYNC_PF                             policy<{'amd64': 'y', 's390x': 'y'}>
+CONFIG_KVM_ASYNC_PF_SYNC                        policy<{'s390x': 'y'}>
+CONFIG_KVM_BOOK3S_64                            policy<{'ppc64el': 'm'}>
+CONFIG_KVM_BOOK3S_64_HANDLER                    policy<{'ppc64el': 'y'}>
+CONFIG_KVM_BOOK3S_64_HV                         policy<{'ppc64el': 'm'}>
+CONFIG_KVM_BOOK3S_HANDLER                       policy<{'ppc64el': 'y'}>
+CONFIG_KVM_BOOK3S_HV_EXIT_TIMING                policy<{'ppc64el': 'y'}>
+CONFIG_KVM_BOOK3S_HV_NESTED_PMU_WORKAROUND      policy<{'ppc64el': 'y'}>
+CONFIG_KVM_BOOK3S_HV_P9_TIMING                  policy<{'ppc64el': 'y'}>
+CONFIG_KVM_BOOK3S_HV_POSSIBLE                   policy<{'ppc64el': 'y'}>
+CONFIG_KVM_COMMON                               policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_KVM_COMPAT                               policy<{'amd64': 'y'}>
+CONFIG_KVM_EXTERNAL_WRITE_TRACKING              policy<{'amd64': 'y'}>
+CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT        policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_KVM_GENERIC_HARDWARE_ENABLING            policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES            policy<{'amd64': 'y'}>
+CONFIG_KVM_GENERIC_MMU_NOTIFIER                 policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_KVM_GENERIC_PRIVATE_MEM                  policy<{'amd64': 'y'}>
+CONFIG_KVM_GUEST                                policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_KVM_HYPERV                               policy<{'amd64': 'y'}>
+CONFIG_KVM_INTEL                                policy<{'amd64': 'm'}>
+CONFIG_KVM_MAX_NR_VCPUS                         policy<{'amd64': '4096'}>
+CONFIG_KVM_MMIO                                 policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': '-', 'riscv64': 'y'}>
+CONFIG_KVM_PRIVATE_MEM                          policy<{'amd64': 'y'}>
+CONFIG_KVM_PROVE_MMU                            policy<{'amd64': 'n'}>
+CONFIG_KVM_S390_UCONTROL                        policy<{'s390x': 'n'}>
+CONFIG_KVM_SMM                                  policy<{'amd64': 'y'}>
+CONFIG_KVM_SW_PROTECTED_VM                      policy<{'amd64': 'y'}>
+CONFIG_KVM_VFIO                                 policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_KVM_WERROR                               policy<{'amd64': 'y'}>
+CONFIG_KVM_XEN                                  policy<{'amd64': 'y'}>
+CONFIG_KVM_XFER_TO_GUEST_WORK                   policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_KVM_XICS                                 policy<{'ppc64el': 'y'}>
+CONFIG_KVM_XIVE                                 policy<{'ppc64el': 'y'}>
+CONFIG_KXCJK1013                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KXSD9                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KXSD9_I2C                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_KXSD9_SPI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_L2TP                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_L2TP_DEBUGFS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_L2TP_ETH                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_L2TP_IP                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_L2TP_V3                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LAN743X                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LAN966X_DCB                              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LAN966X_SWITCH                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LAPB                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_LAPBETHER                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LATTICE_ECP3_CONFIG                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LCD2S                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LCD_AMS369FG06                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LCD_CLASS_DEVICE                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_LCD_HX8357                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LCD_ILI922X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LCD_ILI9320                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LCD_L4F00242T03                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LCD_LMS283GF05                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LCD_LMS501KF03                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LCD_LTV350QV                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LCD_OTM3225A                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LCD_PLATFORM                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LCD_TDO24M                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LCD_VGG2432A4                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LCS                                      policy<{'s390x': 'm'}>
+CONFIG_LDISC_AUTOLOAD                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LDM_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_LDM_PARTITION                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_LD_DEAD_CODE_DATA_ELIMINATION            policy<{'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_LD_HEAD_STUB_CATCH                       policy<{'ppc64el': 'n'}>
+CONFIG_LD_IS_BFD                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LD_ORPHAN_WARN                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LD_ORPHAN_WARN_LEVEL                     policy<{'amd64': '"warn"', 'arm64': '"warn"', 'armhf': '"warn"', 'ppc64el': '"warn"', 'riscv64': '"warn"'}>
+CONFIG_LD_VERSION                               policy<{'amd64': '24200', 'arm64': '24200', 'armhf': '24200', 'ppc64el': '24200', 'riscv64': '24200', 's390x': '24200'}>
+CONFIG_LEDS_88PM860X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_AAEON                               policy<{'amd64': 'm'}>
+CONFIG_LEDS_AAT1290                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_ACER_A500                           policy<{'armhf': 'm'}>
+CONFIG_LEDS_ADP5520                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_AN30259A                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_APU                                 policy<{'amd64': 'm'}>
+CONFIG_LEDS_AS3645A                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_AW200XX                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_AW2013                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_BCM6328                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_BCM6358                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_BD2606MVV                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_BD2802                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_BLINKM                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_BRIGHTNESS_HW_CHANGED               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LEDS_CHT_WCOVE                           policy<{'amd64': 'm'}>
+CONFIG_LEDS_CLASS                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LEDS_CLASS_FLASH                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_CLASS_MULTICOLOR                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_CPCAP                               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_CR0014114                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_DA903X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_DA9052                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_DAC124S085                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_EL15203000                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_GPIO                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_GROUP_MULTICOLOR                    policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_INTEL_SS4200                        policy<{'amd64': 'm'}>
+CONFIG_LEDS_IS31FL319X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_IS31FL32XX                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_KTD202X                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_KTD2692                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_LM3530                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_LM3532                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_LM3533                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_LM355x                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_LM3601X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_LM36274                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_LM3642                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_LM3692X                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_LM3697                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_LP3944                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_LP3952                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_LP50XX                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_LP5521                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_LP5523                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_LP5562                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_LP55XX_COMMON                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_LP8501                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_LP8788                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_LP8860                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_LT3593                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_MAX5970                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_MAX77650                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_MAX77693                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_MAX8997                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_MC13783                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_MENF21BMC                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_MLXCPLD                             policy<{'amd64': 'm'}>
+CONFIG_LEDS_MLXREG                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_MT6323                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_MT6360                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_MT6370_FLASH                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_MT6370_RGB                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_NIC78BX                             policy<{'amd64': 'm'}>
+CONFIG_LEDS_NS2                                 policy<{'armhf': 'm'}>
+CONFIG_LEDS_PCA9532                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_PCA9532_GPIO                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LEDS_PCA955X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_PCA955X_GPIO                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LEDS_PCA963X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_PCA995X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_PM8058                              policy<{'armhf': 'm'}>
+CONFIG_LEDS_POWERNV                             policy<{'ppc64el': 'm'}>
+CONFIG_LEDS_PWM                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_PWM_MULTICOLOR                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_QCOM_FLASH                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_LEDS_QCOM_LPG                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_REGULATOR                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_RT4505                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_RT8515                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_SC27XX_BLTC                         policy<{'arm64': 'm'}>
+CONFIG_LEDS_SGM3140                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_SIEMENS_SIMATIC_IPC                 policy<{'amd64': 'm'}>
+CONFIG_LEDS_SIEMENS_SIMATIC_IPC_APOLLOLAKE      policy<{'amd64': 'm'}>
+CONFIG_LEDS_SIEMENS_SIMATIC_IPC_ELKHARTLAKE     policy<{'amd64': 'm'}>
+CONFIG_LEDS_SIEMENS_SIMATIC_IPC_F7188X          policy<{'amd64': 'm'}>
+CONFIG_LEDS_SPI_BYTE                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_SUN50I_A100                         policy<{'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_SYSCON                              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LEDS_TCA6507                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TI_LMU_COMMON                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TLC591XX                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TPS6105X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_TRIGGERS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LEDS_TRIGGER_ACTIVITY                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TRIGGER_AUDIO                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TRIGGER_BACKLIGHT                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TRIGGER_CAMERA                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TRIGGER_CPU                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LEDS_TRIGGER_DEFAULT_ON                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TRIGGER_DISK                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LEDS_TRIGGER_GPIO                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LEDS_TRIGGER_HEARTBEAT                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TRIGGER_MTD                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LEDS_TRIGGER_NETDEV                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TRIGGER_ONESHOT                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TRIGGER_PANIC                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LEDS_TRIGGER_PATTERN                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TRIGGER_TIMER                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TRIGGER_TRANSIENT                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TRIGGER_TTY                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_TURRIS_OMNIA                        policy<{'armhf': 'm'}>
+CONFIG_LEDS_USER                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_WM831X_STATUS                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LEDS_WM8350                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LED_TRIGGER_PHY                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LEGACY_DIRECT_IO                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LEGACY_PTYS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LEGACY_PTY_COUNT                         policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0', 's390x': '0'}>
+CONFIG_LEGACY_VSYSCALL_NONE                     policy<{'amd64': 'n'}>
+CONFIG_LEGACY_VSYSCALL_XONLY                    policy<{'amd64': 'y'}>
+CONFIG_LENOVO_WMI_HOTKEY_UTILITIES              policy<{'amd64': 'm'}>
+CONFIG_LENOVO_YMC                               policy<{'amd64': 'm'}>
+CONFIG_LG_LAPTOP                                policy<{'amd64': 'm'}>
+CONFIG_LIB80211                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIB80211_CRYPT_CCMP                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIB80211_CRYPT_TKIP                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIB80211_CRYPT_WEP                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIB80211_DEBUG                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_LIBCRC32C                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_LIBERTAS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIBERTAS_DEBUG                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_LIBERTAS_MESH                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LIBERTAS_SDIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIBERTAS_SPI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIBERTAS_THINFIRM                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIBERTAS_THINFIRM_DEBUG                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_LIBERTAS_THINFIRM_USB                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIBERTAS_USB                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIBFC                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_LIBFCOE                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_LIBFDT                                   policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LIBIPW                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIBIPW_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_LIBNVDIMM                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_LIBWX                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIDAR_LITE_V2                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LINEAR_RANGES                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LINEDISP                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIQUIDIO                                 policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LIQUIDIO_CORE                            policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIQUIDIO_VF                              policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LIRC                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LIST_HARDENED                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_LITEX                                    policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LITEX_LITEETH                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LITEX_SOC_CONTROLLER                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LIVEPATCH                                policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_LIVEPATCH_64                             policy<{'ppc64el': 'y'}>
+CONFIG_LKDTM                                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_LLC                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_LLC2                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_LLD_VERSION                              policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0', 's390x': '0'}>
+CONFIG_LMK04832                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LMP91000                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LOAD_IPL_KEYS                            policy<{'s390x': 'y'}>
+CONFIG_LOAD_UEFI_KEYS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_LOCALVERSION                             policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'ppc64el': '""', 'riscv64': '""', 's390x': '""'}>
+CONFIG_LOCKD                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_LOCKDEP_SUPPORT                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LOCKD_V4                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LOCKUP_DETECTOR                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LOCK_DEBUGGING_SUPPORT                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LOCK_DOWN_IN_SECURE_BOOT                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LOCK_EVENT_COUNTS                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_LOCK_MM_AND_FIND_VMA                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LOCK_SPIN_ON_OWNER                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LOCK_STAT                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_LOCK_TORTURE_TEST                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_LOGIG940_FF                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LOGIRUMBLEPAD2_FF                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LOGITECH_FF                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LOGIWHEELS_FF                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_LOGO                                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_LOG_BUF_SHIFT                            policy<{'amd64': '18', 'arm64': '18', 'armhf': '17', 'ppc64el': '18', 'riscv64': '18', 's390x': '18'}>
+CONFIG_LOG_CPU_MAX_BUF_SHIFT                    policy<{'amd64': '12', 'arm64': '12', 'armhf': '12', 'ppc64el': '12', 'riscv64': '12', 's390x': '12'}>
+CONFIG_LOOPBACK_TARGET                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_LP8788_ADC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LPARCFG                                  policy<{'ppc64el': 'y'}>
+CONFIG_LPC_ICH                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_LPC_SCH                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_LP_CONSOLE                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_LRU_CACHE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_LRU_GEN_STATS                            policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_LRU_GEN_WALKS_MMU                        policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_LSI_ET1011C_PHY                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_LSM                                      policy<{'amd64': '"landlock,lockdown,yama,integrity,apparmor"', 'arm64': '"landlock,lockdown,yama,integrity,apparmor"', 'armhf': '"landlock,lockdown,yama,integrity,apparmor"', 'ppc64el': '"landlock,lockdown,yama,integrity,apparmor"', 'riscv64': '"landlock,lockdown,yama,integrity,apparmor"', 's390x': '"landlock,lockdown,yama,integrity,apparmor"'}>
+CONFIG_LSM_MMAP_MIN_ADDR                        policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0', 's390x': '0'}>
+CONFIG_LS_EXTIRQ                                policy<{'arm64': 'y'}>
+CONFIG_LS_SCFG_MSI                              policy<{'arm64': 'y'}>
+CONFIG_LTC1660                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LTC2309                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LTC2471                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LTC2485                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LTC2496                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LTC2497                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LTC2632                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LTC2688                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LTC2983                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LTE_GDM724X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_LTO_NONE                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LTR390                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LTR501                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LTRF216A                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LV0104CS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_LWQ_TEST                                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_LWTUNNEL                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LWTUNNEL_BPF                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LXT_PHY                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_LZ4HC_COMPRESS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_LZ4_COMPRESS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_LZ4_DECOMPRESS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LZO_COMPRESS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_LZO_DECOMPRESS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_M62332                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAC80211                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAC80211_DEBUGFS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MAC80211_DEBUG_MENU                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_MAC80211_HAS_RC                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MAC80211_HWSIM                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAC80211_LEDS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MAC80211_MESH                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MAC80211_MESSAGE_TRACING                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MAC80211_RC_DEFAULT                      policy<{'amd64': '"minstrel_ht"', 'arm64': '"minstrel_ht"', 'armhf': '"minstrel_ht"', 'ppc64el': '"minstrel_ht"', 'riscv64': '"minstrel_ht"'}>
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MAC80211_RC_MINSTREL                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MAC80211_STA_HASH_MAX_SIZE               policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0'}>
+CONFIG_MAC802154                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MACB                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MACB_PCI                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MACB_USE_HWSTAMP                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MACHZ_WDT                                policy<{'amd64': 'm'}>
+CONFIG_MACH_ARMADA_370                          policy<{'armhf': 'y'}>
+CONFIG_MACH_ARMADA_375                          policy<{'armhf': 'y'}>
+CONFIG_MACH_ARMADA_38X                          policy<{'armhf': 'y'}>
+CONFIG_MACH_ARMADA_39X                          policy<{'armhf': 'y'}>
+CONFIG_MACH_ARMADA_XP                           policy<{'armhf': 'y'}>
+CONFIG_MACH_ARTPEC6                             policy<{'armhf': 'n'}>
+CONFIG_MACH_ASPEED_G6                           policy<{'armhf': 'y'}>
+CONFIG_MACH_BERLIN_BG2                          policy<{'armhf': 'y'}>
+CONFIG_MACH_BERLIN_BG2CD                        policy<{'armhf': 'y'}>
+CONFIG_MACH_BERLIN_BG2Q                         policy<{'armhf': 'y'}>
+CONFIG_MACH_DOVE                                policy<{'armhf': 'y'}>
+CONFIG_MACH_INFINITY                            policy<{'armhf': 'y'}>
+CONFIG_MACH_MESON6                              policy<{'armhf': 'y'}>
+CONFIG_MACH_MESON8                              policy<{'armhf': 'y'}>
+CONFIG_MACH_MT2701                              policy<{'armhf': 'y'}>
+CONFIG_MACH_MT6589                              policy<{'armhf': 'y'}>
+CONFIG_MACH_MT6592                              policy<{'armhf': 'y'}>
+CONFIG_MACH_MT7623                              policy<{'armhf': 'y'}>
+CONFIG_MACH_MT7629                              policy<{'armhf': 'y'}>
+CONFIG_MACH_MT8127                              policy<{'armhf': 'y'}>
+CONFIG_MACH_MT8135                              policy<{'armhf': 'y'}>
+CONFIG_MACH_MVEBU_ANY                           policy<{'armhf': 'y'}>
+CONFIG_MACH_MVEBU_V7                            policy<{'armhf': 'y'}>
+CONFIG_MACH_OMAP_GENERIC                        policy<{'armhf': 'y'}>
+CONFIG_MACINTOSH_DRIVERS                        policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_MACSEC                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MACVLAN                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MACVTAP                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MAC_EMUMOUSEBTN                          policy<{'amd64': 'm', 'ppc64el': 'm'}>
+CONFIG_MAC_PARTITION                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_MADERA_IRQ                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAG3110                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAGIC_SYSRQ                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE               policy<{'amd64': '0x01b6', 'arm64': '0x01b6', 'armhf': '0x01b6', 'ppc64el': '0x01b6', 'riscv64': '0x01b6', 's390x': '0x01b6'}>
+CONFIG_MAGIC_SYSRQ_SERIAL                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MAGIC_SYSRQ_SERIAL_SEQUENCE              policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'ppc64el': '""', 'riscv64': '""', 's390x': '""'}>
+CONFIG_MAILBOX                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_MAILBOX_TEST                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MANAGER_SBS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MANA_INFINIBAND                          policy<{'amd64': 'm'}>
+CONFIG_MANTIS_CORE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAPPING_DIRTY_HELPERS                    policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_MARCH_Z10                                policy<{'s390x': 'n'}>
+CONFIG_MARCH_Z13                                policy<{'s390x': 'y'}>
+CONFIG_MARCH_Z14                                policy<{'s390x': 'n'}>
+CONFIG_MARCH_Z15                                policy<{'s390x': 'n'}>
+CONFIG_MARCH_Z16                                policy<{'s390x': 'n'}>
+CONFIG_MARCH_Z16_TUNE                           policy<{'s390x': 'y'}>
+CONFIG_MARCH_Z196                               policy<{'s390x': 'n'}>
+CONFIG_MARCH_ZEC12                              policy<{'s390x': 'n'}>
+CONFIG_MARVELL_10G_PHY                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MARVELL_88Q2XXX_PHY                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MARVELL_88X2222_PHY                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MARVELL_CN10K_DDR_PMU                    policy<{'arm64': 'm'}>
+CONFIG_MARVELL_CN10K_TAD_PMU                    policy<{'arm64': 'm'}>
+CONFIG_MARVELL_GTI_WDT                          policy<{'arm64-generic': 'm', 'arm64-generic-64k': 'y'}>
+CONFIG_MARVELL_PHY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MATOM                                    policy<{'amd64': 'n'}>
+CONFIG_MAX1027                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX11100                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX1118                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX11205                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX11410                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX1241                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX1363                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX30100                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX30102                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX30208                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX31827                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX31856                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX31865                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX34408                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX44000                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX44009                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX517                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX5432                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX5481                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX5487                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX5522                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX5821                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX63XX_WATCHDOG                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MAX77541_ADC                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX77620_THERMAL                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX77620_WATCHDOG                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAX8925_POWER                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MAX9611                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAXIM_THERMOCOUPLE                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MAXLINEAR_GPHY                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MAXSMP                                   policy<{'amd64': 'y'}>
+CONFIG_MAX_PHYSMEM_BITS                         policy<{'s390x': '46'}>
+CONFIG_MAX_SKB_FRAGS                            policy<{'amd64': '17', 'arm64': '17', 'armhf': '17', 'ppc64el': '17', 'riscv64': '17', 's390x': '17'}>
+CONFIG_MB1232                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MC3230                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCB                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MCB_LPC                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCB_PCI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCHP_CLK_MPFS                            policy<{'riscv64': 'y'}>
+CONFIG_MCORE2                                   policy<{'amd64': 'n'}>
+CONFIG_MCP320X                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCP3422                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCP3564                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCP3911                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCP4018                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCP41010                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCP4131                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCP4531                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCP4725                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCP4728                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCP4821                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCP4922                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCP9600                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCPM                                     policy<{'armhf': 'y'}>
+CONFIG_MCPM_QUAD_CLUSTER                        policy<{'armhf': 'y'}>
+CONFIG_MCTP                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_MCTP_FLOWS                               policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_MCTP_SERIAL                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MCTP_TRANSPORT_I2C                       policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_MCTP_TRANSPORT_I3C                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MD                                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MDIO                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MDIO_ASPEED                              policy<{'armhf': 'm'}>
+CONFIG_MDIO_BCM_UNIMAC                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MDIO_BITBANG                             policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MDIO_BUS                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MDIO_BUS_MUX                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MDIO_BUS_MUX_GPIO                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MDIO_BUS_MUX_MESON_G12A                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MDIO_BUS_MUX_MESON_GXL                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MDIO_BUS_MUX_MMIOREG                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MDIO_BUS_MUX_MULTIPLEXER                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MDIO_CAVIUM                              policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MDIO_DEVICE                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MDIO_DEVRES                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MDIO_GPIO                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MDIO_HISI_FEMAC                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MDIO_I2C                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MDIO_IPQ4019                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MDIO_IPQ8064                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MDIO_MSCC_MIIM                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MDIO_MVUSB                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MDIO_OCTEON                              policy<{'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MDIO_REGMAP                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MDIO_SUN4I                               policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_MDIO_THUNDER                             policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MDIO_XGENE                               policy<{'arm64': 'm'}>
+CONFIG_MDM_GCC_9607                             policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_MDM_GCC_9615                             policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_MD_AUTODETECT                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MD_BITMAP_FILE                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MD_CLUSTER                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MD_RAID0                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MD_RAID1                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MD_RAID10                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MD_RAID456                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MEDIATEK_GE_PHY                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MEDIATEK_GE_SOC_PHY                      policy<{'amd64': 'n', 'arm64': 'm', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_MEDIATEK_MT6360_ADC                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIATEK_MT6370_ADC                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIATEK_MT6577_AUXADC                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MEDIATEK_WATCHDOG                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MEDIA_ALTERA_CI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_ANALOG_TV_SUPPORT                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_ATTACH                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_CAMERA_SUPPORT                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_CEC_RC                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_CEC_SUPPORT                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_MEDIA_COMMON_OPTIONS                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_CONTROLLER                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_CONTROLLER_DVB                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_DIGITAL_TV_SUPPORT                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_PCI_SUPPORT                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_PLATFORM_DRIVERS                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_PLATFORM_SUPPORT                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_RADIO_SUPPORT                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_SDR_SUPPORT                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_SUBDRV_AUTOSELECT                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_SUPPORT                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MEDIA_SUPPORT_FILTER                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_TEST_SUPPORT                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEDIA_TUNER                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_E4000                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_FC0011                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_FC0012                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_FC0013                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_FC2580                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_IT913X                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_M88RS6000T                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_MAX2165                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_MC44S803                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_MSI001                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_MT2060                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_MT2063                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_MT20XX                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_MT2131                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_MT2266                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_MXL301RF                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_MXL5005S                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_MXL5007T                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_QM1D1B0004                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_QM1D1C0042                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_QT1010                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_R820T                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_SI2157                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_SIMPLE                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_TDA18212                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_TDA18218                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_TDA18250                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_TDA18271                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_TDA827X                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_TDA8290                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_TDA9887                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_TEA5761                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_TEA5767                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_TUA9001                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_XC2028                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_XC4000                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_TUNER_XC5000                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEDIA_USB_SUPPORT                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEGARAID_LEGACY                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MEGARAID_MAILBOX                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEGARAID_MM                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MEGARAID_NEWGEN                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MEGARAID_SAS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MELLANOX_PLATFORM                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MEMBARRIER                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MEMCG                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MEMCG_KMEM                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MEMFD_CREATE                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MEMORY                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_MEMORY_BALLOON                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MEMORY_FAILURE                           policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_MEMORY_HOTPLUG                           policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_MEMORY_HOTREMOVE                         policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_MEMORY_ISOLATION                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MEMORY_NOTIFIER_ERROR_INJECT             policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 's390x': 'm'}>
+CONFIG_MEMREGION                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEMSTICK                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MEMSTICK_DEBUG                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MEMSTICK_JMICRON_38X                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEMSTICK_R592                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEMSTICK_REALTEK_PCI                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEMSTICK_REALTEK_USB                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEMSTICK_TIFM_MS                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEMSTICK_UNSAFE_RESUME                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MEMTEST                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MEM_SOFT_DIRTY                           policy<{'amd64': 'y', 'ppc64el': 'n', 's390x': 'y'}>
+CONFIG_MENF21BMC_WATCHDOG                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MENZ069_WATCHDOG                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MEN_A21_WDT                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MEN_Z188_ADC                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MERAKI_MX100                             policy<{'amd64': 'm'}>
+CONFIG_MESON6_TIMER                             policy<{'armhf': 'y'}>
+CONFIG_MESON_CANVAS                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MESON_CLK_MEASURE                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MESON_DDR_PMU                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MESON_EE_PM_DOMAINS                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MESON_GXBB_WATCHDOG                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MESON_GXL_PHY                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MESON_GX_PM_DOMAINS                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MESON_GX_SOCINFO                         policy<{'arm64': 'y'}>
+CONFIG_MESON_IRQ_GPIO                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MESON_MX_AO_ARC_REMOTEPROC               policy<{'armhf': 'm'}>
+CONFIG_MESON_MX_SOCINFO                         policy<{'armhf': 'y'}>
+CONFIG_MESON_SARADC                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MESON_SECURE_PM_DOMAINS                  policy<{'arm64': 'y', 'arm64-generic-64k': '-'}>
+CONFIG_MESON_SM                                 policy<{'arm64': 'y', 'arm64-generic-64k': '-'}>
+CONFIG_MESON_WATCHDOG                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MESSAGE_LOGLEVEL_DEFAULT                 policy<{'amd64': '4', 'arm64': '4', 'armhf': '4', 'ppc64el': '4', 'riscv64': '4', 's390x': '4'}>
+CONFIG_MFD_88PM800                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_88PM805                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_88PM860X                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_AAEON                                policy<{'amd64': 'm'}>
+CONFIG_MFD_AAT2870_CORE                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_AC100                                policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_MFD_ACER_A500_EC                         policy<{'armhf': 'm'}>
+CONFIG_MFD_ACT8945A                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_ALTERA_A10SR                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MFD_ALTERA_SYSMGR                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MFD_ARIZONA                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_ARIZONA_I2C                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_ARIZONA_SPI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MFD_AS3711                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_AS3722                               policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_ATC260X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_ATC260X_I2C                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_ATMEL_FLEXCOM                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_ATMEL_HLCDC                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_AXP20X                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_AXP20X_I2C                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_AXP20X_RSB                           policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_MFD_BCM590XX                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_BD9571MWV                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_CORE                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_MFD_CPCAP                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_CROS_EC_DEV                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MFD_CS42L43                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MFD_CS42L43_I2C                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MFD_CS42L43_SDW                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_CS47L15                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_CS47L24                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_CS47L35                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_CS47L85                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_CS47L90                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_CS47L92                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_DA9052_I2C                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_DA9052_SPI                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_DA9055                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_DA9062                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_DA9063                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_MFD_DA9150                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_DLN2                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MFD_EXYNOS_LPASS                         policy<{'armhf': 'n'}>
+CONFIG_MFD_GATEWORKS_GSC                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_HI6421_PMIC                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_HI6421_SPMI                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_HI655X_PMIC                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MFD_INTEL_LPSS                           policy<{'amd64': 'm'}>
+CONFIG_MFD_INTEL_LPSS_ACPI                      policy<{'amd64': 'm'}>
+CONFIG_MFD_INTEL_LPSS_PCI                       policy<{'amd64': 'm'}>
+CONFIG_MFD_INTEL_M10_BMC_CORE                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_INTEL_M10_BMC_PMCI                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_INTEL_M10_BMC_SPI                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_INTEL_PMC_BXT                        policy<{'amd64': 'm'}>
+CONFIG_MFD_INTEL_QUARK_I2C_GPIO                 policy<{'amd64': 'm'}>
+CONFIG_MFD_IQS62X                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_JANZ_CMODIO                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_KEMPLD                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_KHADAS_MCU                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MFD_LM3533                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_LOCHNAGAR                            policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_LP3943                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_LP8788                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_MADERA                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_MADERA_I2C                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_MADERA_SPI                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_MAX14577                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_MFD_MAX5970                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_MAX77541                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_MAX77620                             policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_MAX77650                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_MAX77686                             policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_MAX77693                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_MFD_MAX77714                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_MAX77843                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_MAX8907                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_MAX8925                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_MAX8997                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_MAX8998                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_MC13XXX                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_MC13XXX_I2C                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_MC13XXX_SPI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MFD_MENF21BMC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_MP2629                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_MT6360                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_MT6370                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_MT6397                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_NTXEC                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_NVEC                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MFD_OCELOT                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_OMAP_USB_HOST                        policy<{'armhf': 'y'}>
+CONFIG_MFD_PALMAS                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_PCF50633                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_PM8XXX                               policy<{'armhf': 'm'}>
+CONFIG_MFD_QCOM_PM8008                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_QCOM_RPM                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MFD_RC5T583                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_RDC321X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_RETU                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_RK8XX                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_RK8XX_I2C                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_RK8XX_SPI                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_RN5T618                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_ROHM_BD71828                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_ROHM_BD718XX                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_ROHM_BD957XMUF                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_RSMU_I2C                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_RSMU_SPI                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_RT4831                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_RT5033                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_RT5120                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_SC27XX_PMIC                          policy<{'arm64': 'm'}>
+CONFIG_MFD_SEC_CORE                             policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_SI476X_CORE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_SIMPLE_MFD_I2C                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_SKY81452                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_SL28CPLD                             policy<{'arm64': 'm'}>
+CONFIG_MFD_SM501_GPIO                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_SMPRO                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_SPMI_PMIC                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MFD_STM32_LPTIMER                        policy<{'arm64': 'm'}>
+CONFIG_MFD_STM32_TIMERS                         policy<{'arm64': 'm'}>
+CONFIG_MFD_STMFX                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_STMPE                                policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_STPMIC1                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_SUN4I_GPADC                          policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_MFD_SUN6I_PRCM                           policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_MFD_SY7636A                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_SYSCON                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_MFD_TC3589X                              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_TI_AM335X_TSCADC                     policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': '-', 's390x': '-'}>
+CONFIG_MFD_TI_LMU                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_TI_LP873X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_TI_LP87565                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_TPS65086                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_TPS65090                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_TPS65218                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_TPS65219                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_TPS6586X                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_TPS65910                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_TPS65912                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_TPS65912_I2C                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_MFD_TPS65912_SPI                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_TPS6594                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MFD_TPS6594_I2C                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MFD_TPS6594_SPI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MFD_TQMX86                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_TWL4030_AUDIO                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_VEXPRESS_SYSREG                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MFD_VIPERBOARD                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MFD_VX855                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_WCD934X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_WL1273_CORE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_WM5102                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_WM5110                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_WM831X                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_WM831X_I2C                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_WM831X_SPI                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_WM8350                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_WM8350_I2C                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_WM8400                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MFD_WM8994                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MFD_WM8997                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MFD_WM8998                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MHI_BUS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MHI_BUS_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MHI_BUS_EP                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MHI_BUS_PCI_GENERIC                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MHI_NET                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MHI_WWAN_CTRL                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MHI_WWAN_MBIM                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MICREL_KS8995MA                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MICREL_PHY                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MICROCHIP_PHY                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MICROCHIP_PIT64B                         policy<{'arm64': '-', 'armhf': 'y', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_MICROCHIP_T1S_PHY                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MICROCHIP_T1_PHY                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MICROCODE                                policy<{'amd64': 'y'}>
+CONFIG_MICROCODE_LATE_LOADING                   policy<{'amd64': 'n'}>
+CONFIG_MICROSEMI_PHY                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MICROSOFT_MANA                           policy<{'amd64': 'm', 'arm64': 'n'}>
+CONFIG_MIGHT_HAVE_CACHE_L2X0                    policy<{'armhf': 'y'}>
+CONFIG_MIGRATION                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MII                                      policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MILBEAUT_HDMAC                           policy<{'armhf': 'm'}>
+CONFIG_MILBEAUT_TIMER                           policy<{'armhf': 'y'}>
+CONFIG_MILBEAUT_XDMAC                           policy<{'armhf': 'm'}>
+CONFIG_MINIX_FS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MINIX_SUBPARTITION                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_MIPI_I3C_HCI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MISC_ALCOR_PCI                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MISC_FILESYSTEMS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MISC_RTSX                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MISC_RTSX_PCI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MISC_RTSX_USB                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MISDN                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MISDN_AVMFRITZ                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MISDN_DSP                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MISDN_HDLC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MISDN_HFCMULTI                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MISDN_HFCPCI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MISDN_HFCUSB                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MISDN_INFINEON                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MISDN_IPAC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MISDN_ISAR                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MISDN_L1OIP                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MISDN_NETJET                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MISDN_SPEEDFAX                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MISDN_W6692                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MITIGATE_SPECTRE_BRANCH_HISTORY          policy<{'arm64': 'y'}>
+CONFIG_MITIGATION_RFDS                          policy<{'amd64': 'y'}>
+CONFIG_MITIGATION_SPECTRE_BHI                   policy<{'amd64': 'y'}>
+CONFIG_MK8                                      policy<{'amd64': 'n'}>
+CONFIG_MKISS                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MLX4_CORE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MLX4_CORE_GEN2                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX4_DEBUG                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX4_EN                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MLX4_EN_DCB                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX4_INFINIBAND                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MLX5_BRIDGE                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_CLS_ACT                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_CORE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MLX5_CORE_EN                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_CORE_EN_DCB                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_CORE_IPOIB                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_DPLL                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MLX5_EN_ARFS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_EN_IPSEC                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_EN_RXNFC                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_EN_TLS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_ESWITCH                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_FPGA                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_INFINIBAND                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MLX5_MACSEC                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_MPFS                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_SF                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_MLX5_SF_MANAGER                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MLX5_SW_STEERING                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_TC_CT                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_TC_SAMPLE                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX5_VDPA                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MLX5_VDPA_NET                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MLX5_VDPA_STEERING_DEBUG                 policy<{'amd64': 'n', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MLX5_VFIO_PCI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MLX90614                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MLX90632                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MLX90635                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MLXBF_BOOTCTL                            policy<{'arm64': 'm'}>
+CONFIG_MLXBF_GIGE                               policy<{'arm64': 'm'}>
+CONFIG_MLXBF_PMC                                policy<{'arm64': 'm'}>
+CONFIG_MLXBF_TMFIFO                             policy<{'arm64': 'm'}>
+CONFIG_MLXFW                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MLXREG_HOTPLUG                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MLXREG_IO                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MLXREG_LC                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MLXSW_CORE                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MLXSW_CORE_HWMON                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MLXSW_CORE_THERMAL                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MLXSW_I2C                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MLXSW_MINIMAL                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MLXSW_PCI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MLXSW_SPECTRUM                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MLXSW_SPECTRUM_DCB                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MLX_PLATFORM                             policy<{'amd64': 'm'}>
+CONFIG_MLX_WDT                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MMA7455                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMA7455_I2C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMA7455_SPI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMA7660                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMA8452                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMA9551                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMA9551_CORE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMA9553                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMC                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_MMC35240                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMCONF_FAM10H                            policy<{'amd64': 'y'}>
+CONFIG_MMC_ALCOR                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_ARMMMCI                              policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'm'}>
+CONFIG_MMC_BLOCK_MINORS                         policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'ppc64el': '8', 'riscv64': '8'}>
+CONFIG_MMC_CAVIUM_THUNDERX                      policy<{'arm64': 'm'}>
+CONFIG_MMC_CB710                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MMC_CQHCI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MMC_CRYPTO                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MMC_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MMC_DW                                   policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_DW_BLUEFIELD                         policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_DW_EXYNOS                            policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_DW_HI3798CV200                       policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_DW_K3                                policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_DW_PCI                               policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_DW_PLTFM                             policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_DW_ROCKCHIP                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MMC_DW_STARFIVE                          policy<{'riscv64': 'm'}>
+CONFIG_MMC_HSQ                                  policy<{'amd64': 'n', 'arm64': 'm', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MMC_LITEX                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_MESON_GX                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MMC_MESON_MX_SDHC                        policy<{'armhf': 'm'}>
+CONFIG_MMC_MESON_MX_SDIO                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MMC_MTK                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MMC_MVSDIO                               policy<{'armhf': 'm'}>
+CONFIG_MMC_MXC                                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MMC_OMAP                                 policy<{'armhf': 'm'}>
+CONFIG_MMC_OWL                                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MMC_QCOM_DML                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MMC_REALTEK_PCI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_REALTEK_USB                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_RICOH_MMC                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MMC_SDHCI_ACPI                           policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_SDHCI_AM654                          policy<{'arm64': 'm', 'armhf': '-', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER  policy<{'ppc64el': 'y'}>
+CONFIG_MMC_SDHCI_CADENCE                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_SDHCI_DOVE                           policy<{'armhf': 'm'}>
+CONFIG_MMC_SDHCI_ESDHC_IMX                      policy<{'arm64': 'm', 'armhf': 'y'}>
+CONFIG_MMC_SDHCI_EXTERNAL_DMA                   policy<{'arm64': '-', 'armhf': 'y', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_MMC_SDHCI_F_SDH30                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_SDHCI_IO_ACCESSORS                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MMC_SDHCI_MILBEAUT                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_SDHCI_MSM                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MMC_SDHCI_NPCM                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MMC_SDHCI_OF_ARASAN                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_SDHCI_OF_ASPEED                      policy<{'armhf': 'm'}>
+CONFIG_MMC_SDHCI_OF_AT91                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_SDHCI_OF_DWCMSHC                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_SDHCI_OF_ESDHC                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_MMC_SDHCI_OF_HLWD                        policy<{'ppc64el': 'm'}>
+CONFIG_MMC_SDHCI_OF_SPARX5                      policy<{'arm64': 'm'}>
+CONFIG_MMC_SDHCI_OMAP                           policy<{'arm64': '-', 'armhf': 'm', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_MMC_SDHCI_PCI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_SDHCI_PXAV3                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MMC_SDHCI_S3C                            policy<{'armhf': 'n'}>
+CONFIG_MMC_SDHCI_SPRD                           policy<{'arm64': 'm'}>
+CONFIG_MMC_SDHCI_TEGRA                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MMC_SDHCI_XENON                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_SDHI                                 policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_SDHI_INTERNAL_DMAC                   policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_SDHI_SYS_DMAC                        policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_SDRICOH_CS                           policy<{'amd64': 'm'}>
+CONFIG_MMC_SH_MMCIF                             policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_SPI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_MMC_STM32_SDMMC                          policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_MMC_SUNPLUS                              policy<{'armhf': 'm'}>
+CONFIG_MMC_SUNXI                                policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_MMC_TEST                                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MMC_TIFM_SD                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MMC_TMIO_CORE                            policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_MMC_TOSHIBA_PCI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MMC_USDHI6ROL0                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MMC_USHC                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MMC_VIA_SDMMC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MMC_VUB300                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MMC_WBSD                                 policy<{'amd64': 'm', 'ppc64el': 'm'}>
+CONFIG_MMIOTRACE                                policy<{'amd64': 'y'}>
+CONFIG_MMIOTRACE_TEST                           policy<{'amd64': 'n'}>
+CONFIG_MMIOWB                                   policy<{'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MMU                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MMU_GATHER_MERGE_VMAS                    policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_MMU_GATHER_NO_GATHER                     policy<{'s390x': 'y'}>
+CONFIG_MMU_GATHER_PAGE_SIZE                     policy<{'ppc64el': 'y'}>
+CONFIG_MMU_GATHER_RCU_TABLE_FREE                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_MMU_GATHER_TABLE_FREE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_MMU_LAZY_TLB_REFCOUNT                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MMU_LAZY_TLB_SHOOTDOWN                   policy<{'ppc64el': 'y'}>
+CONFIG_MMU_NOTIFIER                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MODPROBE_PATH                            policy<{'amd64': '"/sbin/modprobe"', 'arm64': '"/sbin/modprobe"', 'armhf': '"/sbin/modprobe"', 'ppc64el': '"/sbin/modprobe"', 'riscv64': '"/sbin/modprobe"', 's390x': '"/sbin/modprobe"'}>
+CONFIG_MODULES                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MODULES_TREE_LOOKUP                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MODULES_USE_ELF_REL                      policy<{'armhf': 'y'}>
+CONFIG_MODULES_USE_ELF_RELA                     policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MODULE_ALLOW_BTF_MISMATCH                policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_COMPRESS_GZIP                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_COMPRESS_NONE                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_COMPRESS_XZ                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_DECOMPRESS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MODULE_FORCE_LOAD                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_FORCE_UNLOAD                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_SECTIONS                          policy<{'riscv64': 'y'}>
+CONFIG_MODULE_SIG                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MODULE_SIG_ALL                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MODULE_SIG_FORCE                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_SIG_FORMAT                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MODULE_SIG_HASH                          policy<{'amd64': '"sha512"', 'arm64': '"sha512"', 'armhf': '"sha512"', 'ppc64el': '"sha512"', 'riscv64': '"sha512"', 's390x': '"sha512"'}>
+CONFIG_MODULE_SIG_KEY                           policy<{'amd64': '"certs/signing_key.pem"', 'arm64': '"certs/signing_key.pem"', 'armhf': '"certs/signing_key.pem"', 'ppc64el': '"certs/signing_key.pem"', 'riscv64': '"certs/signing_key.pem"', 's390x': '"certs/signing_key.pem"'}>
+CONFIG_MODULE_SIG_KEY_TYPE_ECDSA                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_SIG_KEY_TYPE_RSA                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MODULE_SIG_SHA1                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_SIG_SHA256                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_SIG_SHA384                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_SIG_SHA3_256                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_SIG_SHA3_384                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_SIG_SHA3_512                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MODULE_SIG_SHA512                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MODULE_SRCVERSION_ALL                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MODULE_UNLOAD                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MODULE_UNLOAD_TAINT_TRACKING             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_MONREADER                                policy<{'s390x': 'm'}>
+CONFIG_MONWRITER                                policy<{'s390x': 'm'}>
+CONFIG_MOST                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MOST_CDEV                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MOST_COMPONENTS                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MOST_DIM2                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MOST_I2C                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MOST_NET                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MOST_SND                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MOST_USB_HDM                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MOST_VIDEO                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MOTORCOMM_PHY                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_MOUSE_APPLETOUCH                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MOUSE_BCM5974                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MOUSE_CYAPA                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MOUSE_ELAN_I2C                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MOUSE_ELAN_I2C_I2C                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_ELAN_I2C_SMBUS                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_GPIO                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MOUSE_PS2                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MOUSE_PS2_ALPS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_PS2_BYD                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_PS2_CYPRESS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_PS2_ELANTECH                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_PS2_ELANTECH_SMBUS                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_PS2_FOCALTECH                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_PS2_LIFEBOOK                       policy<{'amd64': 'y'}>
+CONFIG_MOUSE_PS2_LOGIPS2PP                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_PS2_SENTELIC                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_PS2_SMBUS                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_PS2_SYNAPTICS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_PS2_TOUCHKIT                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_PS2_TRACKPOINT                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MOUSE_PS2_VMMOUSE                        policy<{'amd64': 'y'}>
+CONFIG_MOUSE_SERIAL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MOUSE_SYNAPTICS_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MOUSE_SYNAPTICS_USB                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MOUSE_VSXXXAA                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MOXA_INTELLIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MOXA_SMARTIO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MOXTET                                   policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MP2629_ADC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MPIC                                     policy<{'ppc64el': 'y'}>
+CONFIG_MPIC_MSGR                                policy<{'ppc64el': 'n'}>
+CONFIG_MPILIB                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MPL115                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MPL115_I2C                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MPL115_SPI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MPL3115                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MPLS                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MPLS_IPTUNNEL                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MPLS_ROUTING                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MPRLS0025PA                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MPROFILE_KERNEL                          policy<{'ppc64el': 'y'}>
+CONFIG_MPSC                                     policy<{'amd64': 'n'}>
+CONFIG_MPTCP                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MPTCP_IPV6                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MPU3050                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MPU3050_I2C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MQ_IOSCHED_DEADLINE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MQ_IOSCHED_KYBER                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MRP                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MS5611                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MS5611_I2C                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MS5611_SPI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MS5637                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MSA311                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MSC313E_WATCHDOG                         policy<{'armhf': 'm'}>
+CONFIG_MSCC_OCELOT_SWITCH                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MSCC_OCELOT_SWITCH_LIB                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MSDOS_FS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_MSDOS_PARTITION                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MSE102X                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MSI_BITMAP_SELFTEST                      policy<{'ppc64el': 'n'}>
+CONFIG_MSI_EC                                   policy<{'amd64': 'm'}>
+CONFIG_MSI_LAPTOP                               policy<{'amd64': 'm'}>
+CONFIG_MSI_WMI                                  policy<{'amd64': 'm'}>
+CONFIG_MSM_GCC_8660                             policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_MSM_GCC_8909                             policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_MSM_GCC_8916                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MSM_GCC_8917                             policy<{'arm64': 'm'}>
+CONFIG_MSM_GCC_8939                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MSM_GCC_8953                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MSM_GCC_8960                             policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_MSM_GCC_8974                             policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_MSM_GCC_8976                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MSM_GCC_8994                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MSM_GCC_8996                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MSM_GCC_8998                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MSM_GPUCC_8998                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MSM_IOMMU                                policy<{'armhf': 'n'}>
+CONFIG_MSM_LCC_8960                             policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_MSM_MMCC_8960                            policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_MSM_MMCC_8974                            policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_MSM_MMCC_8994                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MSM_MMCC_8996                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MSM_MMCC_8998                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MSPRO_BLOCK                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MSTAR_MSC313_CPUPLL                      policy<{'armhf': 'y'}>
+CONFIG_MSTAR_MSC313_MPLL                        policy<{'armhf': 'y'}>
+CONFIG_MST_IRQ                                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MS_BLOCK                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7601U                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7603E                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7615E                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7615_COMMON                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7622_WMAC                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MT7663S                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7663U                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7663_USB_SDIO_COMMON                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT76_CONNAC_LIB                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT76_CORE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT76_LEDS                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MT76_SDIO                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT76_USB                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT76x02_LIB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT76x02_USB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT76x0E                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT76x0U                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT76x0_COMMON                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT76x2E                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT76x2U                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT76x2_COMMON                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7915E                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7921E                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7921S                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7921U                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7921_COMMON                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7925E                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7925U                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT7925_COMMON                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT792x_LIB                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT792x_USB                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MT798X_WMAC                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MT7996E                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTDRAM_ERASE_SIZE                        policy<{'amd64': '128', 'arm64': '128', 'armhf': '128', 'ppc64el': '128', 'riscv64': '128'}>
+CONFIG_MTDRAM_TOTAL_SIZE                        policy<{'amd64': '4096', 'arm64': '4096', 'armhf': '4096', 'ppc64el': '4096', 'riscv64': '4096'}>
+CONFIG_MTD_ABSENT                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_AFS_PARTS                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_AMD76XROM                            policy<{'amd64': 'm'}>
+CONFIG_MTD_BCM47XXSFLASH                        policy<{'armhf': 'm'}>
+CONFIG_MTD_BLKDEVS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_BLOCK2MTD                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_BLOCK_RO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_CFI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_CFI_ADV_OPTIONS                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MTD_CFI_AMDSTD                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_CFI_I1                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_CFI_I2                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_CFI_INTELEXT                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_CFI_STAA                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_CFI_UTIL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_CK804XROM                            policy<{'amd64': 'm'}>
+CONFIG_MTD_CMDLINE_PARTS                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MTD_COMPLEX_MAPPINGS                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_DATAFLASH                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_DATAFLASH_OTP                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_DATAFLASH_WRITE_VERIFY               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MTD_ESB2ROM                              policy<{'amd64': 'm'}>
+CONFIG_MTD_GEN_PROBE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_HYPERBUS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_ICHXROM                              policy<{'amd64': 'm'}>
+CONFIG_MTD_IMPA7                                policy<{'armhf': 'm'}>
+CONFIG_MTD_INTEL_VR_NOR                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_JEDECPROBE                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_L440GX                               policy<{'amd64': 'm'}>
+CONFIG_MTD_LPDDR                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_LPDDR2_NVM                           policy<{'armhf': 'm'}>
+CONFIG_MTD_MAP_BANK_WIDTH_1                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_MAP_BANK_WIDTH_2                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_MAP_BANK_WIDTH_4                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_MCHP23K256                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_MCHP48L640                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_MTDRAM                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_ARASAN                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_BRCMNAND                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_BRCMNAND_BCM63XX                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_BRCMNAND_BCMBCA                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_BRCMNAND_BRCMSTB                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_BRCMNAND_IPROC                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_CADENCE                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_CAFE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_CORE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_DENALI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_DENALI_DT                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_DENALI_PCI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_DISKONCHIP                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS        policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0'}>
+CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_MTD_NAND_ECC                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_NAND_ECC_MEDIATEK                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_ECC_MXIC                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_NAND_ECC_SW_BCH                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_NAND_ECC_SW_HAMMING                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MTD_NAND_FSL_IFC                         policy<{'arm64': 'm'}>
+CONFIG_MTD_NAND_GPIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_GPMI_NAND                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_HISI504                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_INTEL_LGM                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_MARVELL                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_MESON                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_MTK                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_MXC                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_MXIC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_NANDSIM                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_OMAP2                           policy<{'arm64': 'm', 'armhf': 'y'}>
+CONFIG_MTD_NAND_OMAP_BCH                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MTD_NAND_OMAP_BCH_BUILD                  policy<{'arm64': 'm', 'armhf': 'y'}>
+CONFIG_MTD_NAND_ORION                           policy<{'armhf': 'm'}>
+CONFIG_MTD_NAND_PL35X                           policy<{'armhf': 'm'}>
+CONFIG_MTD_NAND_PLATFORM                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_QCOM                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_RENESAS                         policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_RICOH                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_NAND_ROCKCHIP                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_STM32_FMC2                      policy<{'arm64': 'm'}>
+CONFIG_MTD_NAND_SUNXI                           policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_MTD_NAND_TEGRA                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_NAND_VF610_NFC                       policy<{'armhf': 'n'}>
+CONFIG_MTD_NETtel                               policy<{'amd64': 'm'}>
+CONFIG_MTD_ONENAND                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_ONENAND_2X_PROGRAM                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_ONENAND_GENERIC                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_ONENAND_OTP                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MTD_OOPS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_PARSER_TRX                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_PARTITIONED_MASTER                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MTD_PCI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_PCMCIA                               policy<{'amd64': 'm'}>
+CONFIG_MTD_PCMCIA_ANONYMOUS                     policy<{'amd64': 'n'}>
+CONFIG_MTD_PHRAM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_PHYSMAP                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_PHYSMAP_COMPAT                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MTD_PHYSMAP_GEMINI                       policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_MTD_PHYSMAP_GPIO_ADDR                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_PHYSMAP_IXP4XX                       policy<{'armhf': 'y'}>
+CONFIG_MTD_PHYSMAP_OF                           policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_PHYSMAP_VERSATILE                    policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_MTD_PLATRAM                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_PMC551                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_PMC551_BUGFIX                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MTD_PMC551_DEBUG                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MTD_POWERNV_FLASH                        policy<{'ppc64el': 'm'}>
+CONFIG_MTD_PSTORE                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_QCOMSMEM_PARTS                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTD_QINFO_PROBE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_RAM                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK              policy<{'amd64': '-1', 'arm64': '-1', 'armhf': '-1', 'ppc64el': '-1', 'riscv64': '-1'}>
+CONFIG_MTD_REDBOOT_PARTS                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_REDBOOT_PARTS_READONLY               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MTD_ROM                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_SBC_GXX                              policy<{'amd64': 'm'}>
+CONFIG_MTD_SCB2_FLASH                           policy<{'amd64': 'm'}>
+CONFIG_MTD_SLRAM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_SM_COMMON                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_SPI_NAND                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_SPI_NOR                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_SPI_NOR_SWP_DISABLE                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MTD_SPI_NOR_SWP_DISABLE_ON_VOLATILE      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_SPI_NOR_SWP_KEEP                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MTD_SPI_NOR_USE_4K_SECTORS               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_SST25L                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_SWAP                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_TESTS                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_MTD_UBI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_UBI_BEB_LIMIT                        policy<{'amd64': '20', 'arm64': '20', 'armhf': '20', 'ppc64el': '20', 'riscv64': '20'}>
+CONFIG_MTD_UBI_BLOCK                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_UBI_FASTMAP                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MTD_UBI_GLUEBI                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTD_UBI_WL_THRESHOLD                     policy<{'amd64': '4096', 'arm64': '4096', 'armhf': '4096', 'ppc64el': '4096', 'riscv64': '4096'}>
+CONFIG_MTK_ADSP_IPC                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTK_ADSP_MBOX                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTK_CMDQ                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTK_CMDQ_MBOX                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTK_CPUX_TIMER                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MTK_CQDMA                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTK_DEVAPC                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTK_HSDMA                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTK_INFRACFG                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MTK_IOMMU                                policy<{'arm64': 'm', 'armhf': 'n'}>
+CONFIG_MTK_IOMMU_V1                             policy<{'armhf': 'n'}>
+CONFIG_MTK_LVTS_THERMAL                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTK_LVTS_THERMAL_DEBUGFS                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MTK_MMSYS                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTK_PMIC_WRAP                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTK_REGULATOR_COUPLER                    policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MTK_SCP                                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTK_SCPSYS                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MTK_SCPSYS_PM_DOMAINS                    policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MTK_SMI                                  policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_MTK_SOC_THERMAL                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTK_SVS                                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTK_T7XX                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MTK_THERMAL                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTK_TIMER                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MTK_UART_APDMA                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MTRR                                     policy<{'amd64': 'y'}>
+CONFIG_MTRR_SANITIZER                           policy<{'amd64': 'y'}>
+CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT            policy<{'amd64': '1'}>
+CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT      policy<{'amd64': '1'}>
+CONFIG_MULTIPLEXER                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MULTIUSER                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MUSB_PIO_ONLY                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_MUTEX_SPIN_ON_OWNER                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_MUX_ADG792A                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MUX_ADGS1408                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MUX_GPIO                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MUX_MMIO                                 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MV643XX_ETH                              policy<{'armhf': 'm'}>
+CONFIG_MVEBU_CLK_COMMON                         policy<{'armhf': 'y'}>
+CONFIG_MVEBU_CLK_COREDIV                        policy<{'armhf': 'y'}>
+CONFIG_MVEBU_CLK_CPU                            policy<{'armhf': 'y'}>
+CONFIG_MVEBU_DEVBUS                             policy<{'armhf': 'y'}>
+CONFIG_MVEBU_GICP                               policy<{'arm64': 'y'}>
+CONFIG_MVEBU_ICU                                policy<{'arm64': 'y'}>
+CONFIG_MVEBU_MBUS                               policy<{'armhf': 'y'}>
+CONFIG_MVEBU_ODMI                               policy<{'arm64': 'y'}>
+CONFIG_MVEBU_PIC                                policy<{'arm64': 'y'}>
+CONFIG_MVEBU_SEI                                policy<{'arm64': 'y'}>
+CONFIG_MVMDIO                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MVNETA                                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MVNETA_BM_ENABLE                         policy<{'armhf': 'n'}>
+CONFIG_MVPP2                                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_MVPP2_PTP                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MV_XOR                                   policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MV_XOR_V2                                policy<{'arm64': 'y'}>
+CONFIG_MWAVE                                    policy<{'amd64': 'm'}>
+CONFIG_MWIFIEX                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MWIFIEX_PCIE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MWIFIEX_SDIO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MWIFIEX_USB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MWL8K                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MXC4005                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MXC6255                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_MXC_CLK                                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MXC_CLK_SCU                              policy<{'arm64': 'y'}>
+CONFIG_MXC_TZIC                                 policy<{'armhf': 'y'}>
+CONFIG_MXM_WMI                                  policy<{'amd64': 'm'}>
+CONFIG_MXS_DMA                                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_MYRI10GE                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_MYRI10GE_DCA                             policy<{'amd64': 'y'}>
+CONFIG_NAMESPACES                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NATIONAL_PHY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NATSEMI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_NAU7802                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NBPFAXI_DMA                              policy<{'armhf': 'm'}>
+CONFIG_NCN26000_PHY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'n', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_NCSI_OEM_CMD_GET_MAC                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NCSI_OEM_CMD_KEEP_PHY                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NDC_DIS_DYNAMIC_CACHING                  policy<{'arm64': 'y'}>
+CONFIG_ND_BTT                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ND_CLAIM                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ND_PFN                                   policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm'}>
+CONFIG_NE2K_PCI                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_NEED_DMA_MAP_STATE                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NEED_KVM_DIRTY_RING_WITH_BITMAP          policy<{'arm64': 'y'}>
+CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK           policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK            policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NEED_SG_DMA_FLAGS                        policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_NEED_SG_DMA_LENGTH                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_NEED_SRCU_NMI_SAFE                       policy<{'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_NEON                                     policy<{'armhf': 'y'}>
+CONFIG_NET                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETCONSOLE                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETCONSOLE_DYNAMIC                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETCONSOLE_EXTENDED_LOG                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NETDEVICES                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETDEVSIM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETDEV_NOTIFIER_ERROR_INJECT             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NETFILTER                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETFILTER_ADVANCED                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETFILTER_BPF_LINK                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETFILTER_CONNCOUNT                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_EGRESS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETFILTER_FAMILY_ARP                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETFILTER_FAMILY_BRIDGE                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETFILTER_INGRESS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETFILTER_NETLINK                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_NETLINK_ACCT                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_NETLINK_GLUE_CT                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETFILTER_NETLINK_HOOK                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_NETLINK_LOG                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_NETLINK_OSF                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_NETLINK_QUEUE                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_SKIP_EGRESS                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETFILTER_SYNPROXY                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XTABLES                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XTABLES_COMPAT                 policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': '-', 'ppc64el': '-', 'riscv64': '-', 's390x': '-'}>
+CONFIG_NETFILTER_XT_CONNMARK                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MARK                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_BPF                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_CGROUP                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_CLUSTER               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_COMMENT               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_CONNMARK              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_CPU                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_DCCP                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_DSCP                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_ECN                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_ESP                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_HELPER                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_HL                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_IPCOMP                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_IPRANGE               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_IPVS                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_L2TP                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_LENGTH                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_LIMIT                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_MAC                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_MARK                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_NFACCT                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_OSF                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_OWNER                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_POLICY                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_QUOTA                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_RATEEST               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_REALM                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_RECENT                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_SCTP                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_SOCKET                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_STATE                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_STATISTIC             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_STRING                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_TCPMSS                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_TIME                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_MATCH_U32                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_NAT                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_SET                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_AUDIT                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_CONNMARK             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_CT                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_DSCP                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_HL                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_HMARK                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_LED                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_NETFILTER_XT_TARGET_LOG                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_MARK                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_MASQUERADE           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_NETMAP               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_NFLOG                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_NOTRACK              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NETFILTER_XT_TARGET_RATEEST              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_REDIRECT             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_SECMARK              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_TCPMSS               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_TEE                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_TPROXY               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFILTER_XT_TARGET_TRACE                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETFS_STATS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETFS_SUPPORT                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETIUCV                                  policy<{'s390x': 'm'}>
+CONFIG_NETKIT                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETLABEL                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETLINK_DIAG                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NETPOLL                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETROM                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NETWORK_FILESYSTEMS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETWORK_SECMARK                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NETXEN_NIC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_NET_9P_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NET_9P_FD                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_9P_RDMA                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_9P_VIRTIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_9P_XEN                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_NET_ACT_BPF                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_CONNMARK                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_CSUM                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_CT                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_CTINFO                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_GACT                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_GATE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_IFE                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NET_ACT_IPT                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_MIRRED                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_MPLS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_NAT                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_PEDIT                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_POLICE                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_SAMPLE                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_SIMP                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_SKBEDIT                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_SKBMOD                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_TUNNEL_KEY                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_ACT_VLAN                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_CALXEDA_XGMAC                        policy<{'armhf': 'm'}>
+CONFIG_NET_CLS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_CLS_ACT                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_CLS_BASIC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_CLS_BPF                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_CLS_CGROUP                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_CLS_FLOW                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_CLS_FLOWER                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_CLS_FW                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_CLS_MATCHALL                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_CLS_ROUTE4                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_CLS_U32                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_CORE                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_DEVLINK                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_DEV_REFCNT_TRACKER                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NET_DSA                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_NET_DSA_AR9331                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_BCM_SF2                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_HIRSCHMANN_HELLCREEK             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_LANTIQ_GSWIP                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_LOOP                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_MICROCHIP_KSZ_COMMON             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_MICROCHIP_KSZ_PTP                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NET_DSA_MICROCHIP_KSZ_SPI                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_MSCC_FELIX                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'n'}>
+CONFIG_NET_DSA_MSCC_FELIX_DSA_LIB               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_MSCC_OCELOT_EXT                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'n', 'riscv64': 'm'}>
+CONFIG_NET_DSA_MSCC_SEVILLE                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_MT7530                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_MT7530_MDIO                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_MT7530_MMIO                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_MV88E6060                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_MV88E6XXX                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_MV88E6XXX_PTP                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NET_DSA_QCA8K                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NET_DSA_REALTEK                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_REALTEK_MDIO                     policy<{'amd64': 'n', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_REALTEK_RTL8365MB                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_REALTEK_RTL8366RB                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_REALTEK_SMI                      policy<{'amd64': 'n', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_RZN1_A5PSW                       policy<{'armhf': 'm'}>
+CONFIG_NET_DSA_SJA1105                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_SJA1105_PTP                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NET_DSA_SJA1105_TAS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NET_DSA_SJA1105_VL                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NET_DSA_SMSC_LAN9303                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_SMSC_LAN9303_I2C                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_SMSC_LAN9303_MDIO                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_AR9331                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_BRCM                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_BRCM_COMMON                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_BRCM_LEGACY                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_BRCM_PREPEND                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_DSA                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_DSA_COMMON                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_EDSA                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_GSWIP                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_HELLCREEK                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_KSZ                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_LAN9303                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_MTK                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_NONE                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_OCELOT                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_OCELOT_8021Q                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_QCA                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_RTL4_A                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_RTL8_4                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_RZN1_A5PSW                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_SJA1105                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_TRAILER                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_TAG_XRS700X                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_VITESSE_VSC73XX                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_VITESSE_VSC73XX_SPI              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_XRS700X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_XRS700X_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_DSA_XRS700X_MDIO                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_EGRESS                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_EMATCH                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_EMATCH_CANID                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NET_EMATCH_CMP                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_EMATCH_IPSET                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_EMATCH_IPT                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_EMATCH_META                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_EMATCH_NBYTE                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_EMATCH_STACK                         policy<{'amd64': '32', 'arm64': '32', 'armhf': '32', 'ppc64el': '32', 'riscv64': '32', 's390x': '32'}>
+CONFIG_NET_EMATCH_TEXT                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_EMATCH_U32                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_FAILOVER                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_FC                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_FLOW_LIMIT                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_FOU                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_FOU_IP_TUNNELS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_HANDSHAKE                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_IFE                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_INGRESS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_IPGRE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_IPGRE_BROADCAST                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_IPGRE_DEMUX                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_IPIP                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_IPVTI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_IP_TUNNEL                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_KEY                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_KEY_MIGRATE                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NET_L3_MASTER_DEV                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_MPLS_GSO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_NCSI                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_NS                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_NSH                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_NS_REFCNT_TRACKER                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NET_PKTGEN                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_POLL_CONTROLLER                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_PTP_CLASSIFY                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_REDIRECT                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_RX_BUSY_POLL                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_SB1000                               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_NET_SCHED                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_SCH_CAKE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_CBS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_CHOKE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_CODEL                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_DEFAULT                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NET_SCH_DRR                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_ETF                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_ETS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_FIFO                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_SCH_FQ                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_FQ_CODEL                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_FQ_PIE                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_GRED                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_HFSC                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_HHF                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_HTB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_INGRESS                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_MQPRIO                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_MQPRIO_LIB                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_MULTIQ                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_NETEM                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_PIE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_PLUG                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_PRIO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_QFQ                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_RED                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_SFB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_SFQ                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_SKBPRIO                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_TAPRIO                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_TBF                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SCH_TEQL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_SELFTESTS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_SOCK_MSG                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_TC_SKB_EXT                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_TEAM                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_TEAM_MODE_BROADCAST                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_TEAM_MODE_LOADBALANCE                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_TEAM_MODE_RANDOM                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_TEAM_MODE_ROUNDROBIN                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_TULIP                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NET_UDP_TUNNEL                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_VENDOR_3COM                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_8390                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NET_VENDOR_ACTIONS                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_NET_VENDOR_ADAPTEC                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_ADI                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NET_VENDOR_AGERE                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_ALACRITECH                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_ALLWINNER                     policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_NET_VENDOR_ALTEON                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_AMAZON                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_AMD                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_AQUANTIA                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_ARC                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_ASIX                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_ATHEROS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_BROADCOM                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_BROCADE                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_CADENCE                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_CAVIUM                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_CHELSIO                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_CIRRUS                        policy<{'amd64': 'y', 'armhf': 'y'}>
+CONFIG_NET_VENDOR_CISCO                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_CORTINA                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_DAVICOM                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_DEC                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_DLINK                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_ENGLEDER                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_EZCHIP                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_FARADAY                       policy<{'armhf': 'y'}>
+CONFIG_NET_VENDOR_FREESCALE                     policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_NET_VENDOR_FUJITSU                       policy<{'amd64': 'y'}>
+CONFIG_NET_VENDOR_FUNGIBLE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_GOOGLE                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_HISILICON                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_NET_VENDOR_HUAWEI                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_I825XX                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NET_VENDOR_IBM                           policy<{'ppc64el': 'y'}>
+CONFIG_NET_VENDOR_INTEL                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_LITEX                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_MARVELL                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_MEDIATEK                      policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_NET_VENDOR_MELLANOX                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_MICREL                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_MICROCHIP                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_MICROSEMI                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_MICROSOFT                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_MYRI                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_NATSEMI                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_NETERION                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_NETRONOME                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_NI                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_NVIDIA                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_OKI                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_PACKET_ENGINES                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_PENSANDO                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_QLOGIC                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_QUALCOMM                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_RDC                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_REALTEK                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_RENESAS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_ROCKER                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_SAMSUNG                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_SEEQ                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_SILAN                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_SIS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_SMSC                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_SOCIONEXT                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_SOLARFLARE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_STMICRO                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_SUN                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_SUNPLUS                       policy<{'armhf': 'y'}>
+CONFIG_NET_VENDOR_SYNOPSYS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_TEHUTI                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_TI                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_VERTEXCOM                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_VIA                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_WANGXUN                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_WIZNET                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NET_VENDOR_XILINX                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NET_VENDOR_XIRCOM                        policy<{'amd64': 'y'}>
+CONFIG_NET_VRF                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NET_XGENE                                policy<{'arm64': 'm'}>
+CONFIG_NET_XGENE_V2                             policy<{'arm64': 'm'}>
+CONFIG_NET_XGRESS                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NEW_LEDS                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_NFC                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_NFC_DIGITAL                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_FDP                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_FDP_I2C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_HCI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_MEI_PHY                              policy<{'amd64': 'm'}>
+CONFIG_NFC_MICROREAD                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_MICROREAD_I2C                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_MICROREAD_MEI                        policy<{'amd64': 'm'}>
+CONFIG_NFC_MRVL                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_MRVL_I2C                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_MRVL_SPI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_MRVL_UART                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_MRVL_USB                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_NCI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_NCI_SPI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_NCI_UART                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_NXP_NCI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_NXP_NCI_I2C                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_PN532_UART                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_PN533                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_PN533_I2C                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_PN533_USB                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_PN544                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_PN544_I2C                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_PN544_MEI                            policy<{'amd64': 'm'}>
+CONFIG_NFC_PORT100                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_S3FWRN5                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_S3FWRN5_I2C                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_S3FWRN82_UART                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_SHDLC                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NFC_SIM                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_ST21NFCA                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_ST21NFCA_I2C                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_ST95HF                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_ST_NCI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_ST_NCI_I2C                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_ST_NCI_SPI                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_TRF7970A                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFC_VIRTUAL_NCI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFIT_SECURITY_DEBUG                      policy<{'amd64': 'n', 'arm64': 'n', 'riscv64': 'n'}>
+CONFIG_NFP                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_NFP_APP_ABM_NIC                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NFP_APP_FLOWER                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NFP_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_NFP_NET_IPSEC                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NFSD                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFSD_BLOCKLAYOUT                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFSD_FLEXFILELAYOUT                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFSD_LEGACY_CLIENT_TRACKING              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NFSD_PNFS                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFSD_SCSILAYOUT                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFSD_V2                                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NFSD_V3_ACL                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFSD_V4                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFSD_V4_2_INTER_SSC                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFSD_V4_SECURITY_LABEL                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFS_ACL_SUPPORT                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFS_COMMON                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFS_DEBUG                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFS_DISABLE_UDP_SUPPORT                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFS_FS                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFS_FSCACHE                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFS_SWAP                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFS_USE_KERNEL_DNS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFS_USE_LEGACY_DNS                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NFS_V2                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFS_V3                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFS_V3_ACL                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFS_V4                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFS_V4_1                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN        policy<{'amd64': '"kernel.org"', 'arm64': '"kernel.org"', 'armhf': '"kernel.org"', 'ppc64el': '"kernel.org"', 'riscv64': '"kernel.org"', 's390x': '"kernel.org"'}>
+CONFIG_NFS_V4_1_MIGRATION                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFS_V4_2                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFS_V4_2_READ_PLUS                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NFS_V4_2_SSC_HELPER                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFS_V4_SECURITY_LABEL                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NFTL                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NFTL_RW                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NFT_BRIDGE_META                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_BRIDGE_REJECT                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_COMPAT                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_CONNLIMIT                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_CT                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_DUP_IPV4                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_DUP_IPV6                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_DUP_NETDEV                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_FIB                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_FIB_INET                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_FIB_IPV4                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_FIB_IPV6                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_FIB_NETDEV                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_FLOW_OFFLOAD                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_FWD_NETDEV                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_HASH                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_LIMIT                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_LOG                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_MASQ                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_NAT                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_NUMGEN                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_OSF                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_QUEUE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_QUOTA                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_REDIR                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_REJECT                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_REJECT_INET                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_REJECT_IPV4                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_REJECT_IPV6                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_REJECT_NETDEV                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_SOCKET                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_SYNPROXY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_TPROXY                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_TUNNEL                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NFT_XFRM                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CONNTRACK                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CONNTRACK_AMANDA                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CONNTRACK_BRIDGE                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CONNTRACK_BROADCAST                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CONNTRACK_EVENTS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_CONNTRACK_FTP                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CONNTRACK_H323                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CONNTRACK_IRC                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CONNTRACK_LABELS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_CONNTRACK_MARK                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_CONNTRACK_NETBIOS_NS                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CONNTRACK_OVS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_CONNTRACK_PPTP                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CONNTRACK_PROCFS                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NF_CONNTRACK_SANE                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CONNTRACK_SECMARK                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_CONNTRACK_SIP                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CONNTRACK_SNMP                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CONNTRACK_TFTP                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CONNTRACK_TIMEOUT                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_CONNTRACK_TIMESTAMP                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_CONNTRACK_ZONES                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_CT_NETLINK                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CT_NETLINK_HELPER                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CT_NETLINK_TIMEOUT                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_CT_PROTO_DCCP                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_CT_PROTO_GRE                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_CT_PROTO_SCTP                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_CT_PROTO_UDPLITE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_DEFRAG_IPV4                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_DEFRAG_IPV6                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_DUP_IPV4                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_DUP_IPV6                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_DUP_NETDEV                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_FLOW_TABLE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_FLOW_TABLE_INET                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_FLOW_TABLE_PROCFS                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NF_LOG_ARP                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_LOG_IPV4                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_LOG_IPV6                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_LOG_SYSLOG                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_NAT                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_NAT_AMANDA                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_NAT_FTP                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_NAT_H323                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_NAT_IRC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_NAT_MASQUERADE                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_NAT_OVS                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_NAT_PPTP                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_NAT_REDIRECT                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_NAT_SIP                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_NAT_SNMP_BASIC                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_NAT_TFTP                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_REJECT_IPV4                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_REJECT_IPV6                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_SOCKET_IPV4                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_SOCKET_IPV6                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_TABLES                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_TABLES_ARP                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_TABLES_BRIDGE                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_TABLES_INET                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_TABLES_IPV4                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_TABLES_IPV6                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_TABLES_NETDEV                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NF_TPROXY_IPV4                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NF_TPROXY_IPV6                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NGBE                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NI903X_WDT                               policy<{'amd64': 'm'}>
+CONFIG_NIC7018_WDT                              policy<{'amd64': 'm'}>
+CONFIG_NILFS2_FS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NINTENDO_FF                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NITRO_ENCLAVES                           policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_NIU                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_NI_XGE_MANAGEMENT_ENET                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_NL80211_TESTMODE                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_NLATTR                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NLMON                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_ASCII                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_1250                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_1251                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_437                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NLS_CODEPAGE_737                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_775                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_850                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_852                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_855                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_857                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_860                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_861                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_862                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_863                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_864                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_865                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_866                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_869                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_874                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_932                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_936                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_949                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_CODEPAGE_950                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_DEFAULT                              policy<{'amd64': '"utf8"', 'arm64': '"utf8"', 'armhf': '"utf8"', 'ppc64el': '"utf8"', 'riscv64': '"utf8"', 's390x': '"utf8"'}>
+CONFIG_NLS_ISO8859_1                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_ISO8859_13                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_ISO8859_14                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_ISO8859_15                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_ISO8859_2                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_ISO8859_3                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_ISO8859_4                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_ISO8859_5                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_ISO8859_6                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_ISO8859_7                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_ISO8859_8                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_ISO8859_9                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_KOI8_R                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_KOI8_U                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_MAC_CELTIC                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_MAC_CENTEURO                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_MAC_CROATIAN                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_MAC_CYRILLIC                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_MAC_GAELIC                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_MAC_GREEK                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_MAC_ICELAND                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_MAC_INUIT                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_MAC_ROMAN                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_MAC_ROMANIAN                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_MAC_TURKISH                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_UCS2_UTILS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NLS_UTF8                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NMI_CHECK_CPU                            policy<{'amd64': 'y'}>
+CONFIG_NMI_IPI                                  policy<{'ppc64el': 'y'}>
+CONFIG_NOA1305                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NODES_SHIFT                              policy<{'amd64': '10', 'arm64': '6', 'ppc64el': '8', 'riscv64': '2', 's390x': '1'}>
+CONFIG_NONPORTABLE                              policy<{'riscv64': 'n'}>
+CONFIG_NONSTATIC_KERNEL                         policy<{'ppc64el': 'y'}>
+CONFIG_NOP_TRACER                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NOTIFIER_ERROR_INJECTION                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NOUVEAU_DEBUG                            policy<{'amd64': '5', 'arm64': '5', 'armhf': '5', 'ppc64el': '5', 'riscv64': '5'}>
+CONFIG_NOUVEAU_DEBUG_DEFAULT                    policy<{'amd64': '3', 'arm64': '3', 'armhf': '3', 'ppc64el': '3', 'riscv64': '3'}>
+CONFIG_NOUVEAU_DEBUG_MMU                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_NOUVEAU_DEBUG_PUSH                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_NOUVEAU_PLATFORM_DRIVER                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_NOZOMI                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_NO_HZ                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NO_HZ_COMMON                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NO_IOPORT_MAP                            policy<{'armhf': 'y', 's390x': 'y'}>
+CONFIG_NPCM7XX_KCS_IPMI_BMC                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NPCM7XX_TIMER                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_NPCM7XX_WATCHDOG                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_NPCM_ADC                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NR_CPUS_DEFAULT                          policy<{'amd64': '8192'}>
+CONFIG_NR_CPUS_RANGE_BEGIN                      policy<{'amd64': '8192'}>
+CONFIG_NR_CPUS_RANGE_END                        policy<{'amd64': '8192'}>
+CONFIG_NR_IRQS                                  policy<{'ppc64el': '512'}>
+CONFIG_NS83820                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_NSM                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NTB                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_NTB_AMD                                  policy<{'amd64': 'n'}>
+CONFIG_NTB_EPF                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NTB_IDT                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NTB_INTEL                                policy<{'amd64': 'm'}>
+CONFIG_NTB_MSI                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NTB_MSI_TEST                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_NTB_NETDEV                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NTB_PERF                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NTB_PINGPONG                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NTB_SWITCHTEC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NTB_TOOL                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NTB_TRANSPORT                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NTFS3_64BIT_CLUSTER                      policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NTFS3_FS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NTFS3_FS_POSIX_ACL                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NTFS3_LZX_XPRESS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NTFS_DEBUG                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NTFS_FS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NTFS_RW                                  policy<{'amd64': 'n', 'arm64': 'n', 'arm64-generic-64k': '-', 'armhf': 'n', 'ppc64el': '-', 'riscv64': 'n', 's390x': 'y'}>
+CONFIG_NULL_TTY                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_NUMA_BALANCING                           policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NUMA_KEEP_MEMINFO                        policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_NVDIMM_DAX                               policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_NVDIMM_KEYS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NVDIMM_PFN                               policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_NVDIMM_SECURITY_TEST                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_NVEC_PAZ00                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NVEC_POWER                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NVHE_EL2_DEBUG                           policy<{'arm64': 'n'}>
+CONFIG_NVIDIA_CARMEL_CNP_ERRATUM                policy<{'arm64': 'y'}>
+CONFIG_NVIDIA_CORESIGHT_PMU_ARCH_SYSTEM_PMU     policy<{'arm64': 'm'}>
+CONFIG_NVIDIA_SHIELD_FF                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NVIDIA_WMI_EC_BACKLIGHT                  policy<{'amd64': 'm'}>
+CONFIG_NVMEM_APPLE_EFUSES                       policy<{'arm64': 'm'}>
+CONFIG_NVMEM_IMX_IIM                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NVMEM_IMX_OCOTP                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NVMEM_IMX_OCOTP_ELE                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NVMEM_IMX_OCOTP_SCU                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NVMEM_LAYERSCAPE_SFP                     policy<{'arm64': 'm'}>
+CONFIG_NVMEM_LAYOUTS                            policy<{'amd64': 'n', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NVMEM_LAYOUT_ONIE_TLV                    policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NVMEM_LAYOUT_SL28_VPD                    policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NVMEM_MESON_EFUSE                        policy<{'arm64': 'm', 'arm64-generic-64k': '-'}>
+CONFIG_NVMEM_MESON_MX_EFUSE                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NVMEM_MTK_EFUSE                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NVMEM_QCOM_QFPROM                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NVMEM_QCOM_SEC_QFPROM                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NVMEM_RAVE_SP_EEPROM                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NVMEM_REBOOT_MODE                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NVMEM_RMEM                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_NVMEM_ROCKCHIP_EFUSE                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NVMEM_ROCKCHIP_OTP                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NVMEM_SC27XX_EFUSE                       policy<{'arm64': 'm'}>
+CONFIG_NVMEM_SNVS_LPGPR                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_NVMEM_SPMI_SDAM                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NVMEM_SPRD_EFUSE                         policy<{'arm64': 'm'}>
+CONFIG_NVMEM_STM32_BSEC_OPTEE_TA                policy<{'arm64': 'y'}>
+CONFIG_NVMEM_STM32_ROMEM                        policy<{'arm64': 'm'}>
+CONFIG_NVMEM_SUNPLUS_OCOTP                      policy<{'armhf': 'm'}>
+CONFIG_NVMEM_SUNXI_SID                          policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_NVMEM_SYSFS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NVMEM_U_BOOT_ENV                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_NVMEM_VF610_OCOTP                        policy<{'armhf': 'n'}>
+CONFIG_NVMEM_ZYNQMP                             policy<{'arm64': 'y'}>
+CONFIG_NVME_APPLE                               policy<{'arm64': 'm'}>
+CONFIG_NVME_AUTH                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NVME_CORE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NVME_FABRICS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NVME_FC                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NVME_HOST_AUTH                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NVME_HWMON                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_NVME_KEYRING                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NVME_MULTIPATH                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NVME_RDMA                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NVME_TARGET                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NVME_TARGET_AUTH                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NVME_TARGET_FC                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NVME_TARGET_FCLOOP                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NVME_TARGET_LOOP                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NVME_TARGET_PASSTHRU                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NVME_TARGET_RDMA                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NVME_TARGET_TCP                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NVME_TARGET_TCP_TLS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NVME_TCP                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_NVME_TCP_TLS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_NVME_VERBOSE_ERRORS                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_NVSW_SN2201                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_NV_TCO                                   policy<{'amd64': 'm'}>
+CONFIG_NXP_C45_TJA11XX_PHY                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_NXP_CBTX_PHY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_NXP_TJA11XX_PHY                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_N_HDLC                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_OABI_COMPAT                              policy<{'armhf': 'n'}>
+CONFIG_OBJAGG                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_OBJTOOL                                  policy<{'amd64': 'y', 'ppc64el': '-'}>
+CONFIG_OCFS2_DEBUG_FS                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_OCFS2_DEBUG_MASKLOG                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_OCFS2_FS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_OCFS2_FS_O2CB                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_OCFS2_FS_STATS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_OCFS2_FS_USERSPACE_CLUSTER               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_OCTEONTX2_AF                             policy<{'arm64': 'm'}>
+CONFIG_OCTEONTX2_MBOX                           policy<{'arm64': 'm'}>
+CONFIG_OCTEONTX2_PF                             policy<{'arm64': 'm'}>
+CONFIG_OCTEONTX2_VF                             policy<{'arm64': 'm'}>
+CONFIG_OCTEON_EP                                policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_OCXL                                     policy<{'ppc64el': 'm'}>
+CONFIG_OCXL_BASE                                policy<{'ppc64el': 'y'}>
+CONFIG_OF                                       policy<{'amd64': 'n', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_OF_ADDRESS                               policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_OF_DYNAMIC                               policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_OF_EARLY_FLATTREE                        policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_OF_FLATTREE                              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_OF_FPGA_REGION                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_OF_GPIO                                  policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_OF_GPIO_MM_GPIOCHIP                      policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_OF_IOMMU                                 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_OF_IRQ                                   policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_OF_KOBJ                                  policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_OF_MDIO                                  policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_OF_NUMA                                  policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_OF_OVERLAY                               policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_OF_PMEM                                  policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_OF_RECONFIG_NOTIFIER_ERROR_INJECT        policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_OF_RESERVED_MEM                          policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_OF_RESOLVE                               policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_OF_UNITTEST                              policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_OID_REGISTRY                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_OLD_SIGACTION                            policy<{'armhf': 'y', 's390x': 'y'}>
+CONFIG_OLD_SIGSUSPEND                           policy<{'ppc64el': 'y'}>
+CONFIG_OLD_SIGSUSPEND3                          policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': '-', 'armhf': 'y', 's390x': 'y'}>
+CONFIG_OMAP2PLUS_MBOX                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_OMAP2PLUS_PRM                            policy<{'armhf': 'y'}>
+CONFIG_OMAP5_ERRATA_801819                      policy<{'armhf': 'y'}>
+CONFIG_OMAP_CONTROL_PHY                         policy<{'armhf': 'm'}>
+CONFIG_OMAP_DM_SYSTIMER                         policy<{'armhf': 'y'}>
+CONFIG_OMAP_DM_TIMER                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_OMAP_GPMC                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_OMAP_GPMC_DEBUG                          policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_OMAP_INTERCONNECT                        policy<{'armhf': 'y'}>
+CONFIG_OMAP_INTERCONNECT_BARRIER                policy<{'armhf': 'y'}>
+CONFIG_OMAP_IOMMU                               policy<{'armhf': 'y'}>
+CONFIG_OMAP_IOMMU_DEBUG                         policy<{'armhf': 'n'}>
+CONFIG_OMAP_IRQCHIP                             policy<{'armhf': 'y'}>
+CONFIG_OMAP_MBOX_KFIFO_SIZE                     policy<{'arm64': '256', 'armhf': '256'}>
+CONFIG_OMAP_OCP2SCP                             policy<{'armhf': 'm'}>
+CONFIG_OMAP_REMOTEPROC                          policy<{'armhf': 'm'}>
+CONFIG_OMAP_REMOTEPROC_WATCHDOG                 policy<{'armhf': 'n'}>
+CONFIG_OMAP_USB2                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_OMAP_WATCHDOG                            policy<{'armhf': 'm'}>
+CONFIG_OMFS_FS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_OPAL_CORE                                policy<{'ppc64el': 'n'}>
+CONFIG_OPAL_PRD                                 policy<{'ppc64el': 'm'}>
+CONFIG_OPENVSWITCH                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_OPENVSWITCH_GENEVE                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_OPENVSWITCH_GRE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_OPENVSWITCH_VXLAN                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_OPEN_DICE                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_OPT3001                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_OPT4001                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_OPTEE                                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_OPTEE_INSECURE_LOAD_IMAGE                policy<{'arm64': 'n'}>
+CONFIG_OPTPROBES                                policy<{'amd64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_ORANGEFS_FS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ORION_IRQCHIP                            policy<{'armhf': 'y'}>
+CONFIG_ORION_TIMER                              policy<{'armhf': 'y'}>
+CONFIG_ORION_WATCHDOG                           policy<{'armhf': 'm'}>
+CONFIG_OSF_PARTITION                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_OUTER_CACHE                              policy<{'armhf': 'y'}>
+CONFIG_OUTER_CACHE_SYNC                         policy<{'armhf': 'y'}>
+CONFIG_OUTPUT_FORMAT                            policy<{'amd64': '"elf64-x86-64"'}>
+CONFIG_OVERLAY_FS                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_OVERLAY_FS_DEBUG                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_OVERLAY_FS_INDEX                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_OVERLAY_FS_METACOPY                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_OVERLAY_FS_REDIRECT_DIR                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_OVERLAY_FS_XINO_AUTO                     policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_OWL_DMA                                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_OWL_EMAC                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_OWL_PM_DOMAINS                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_OWL_PM_DOMAINS_HELPER                    policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_OWL_TIMER                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_P2SB                                     policy<{'amd64': 'y'}>
+CONFIG_P54_COMMON                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_P54_LEDS                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_P54_PCI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_P54_SPI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_P54_SPI_DEFAULT_EEPROM                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_P54_USB                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PA12203001                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PACKET                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PACKET_DIAG                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_PACKING                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_PADATA                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PAGE_COUNTER                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PAGE_EXTENSION                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'y', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PAGE_IDLE_FLAG                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PAGE_OFFSET                              policy<{'armhf': '0xC0000000', 'ppc64el': '0xc000000000000000', 'riscv64': '0xff60000000000000'}>
+CONFIG_PAGE_OWNER                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PAGE_POOL                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PAGE_POOL_STATS                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PAGE_REPORTING                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PAGE_SIZE_64KB                           policy<{'ppc64el': 'y'}>
+CONFIG_PAGE_SIZE_LESS_THAN_256KB                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PAGE_SIZE_LESS_THAN_64KB                 policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': '-', 'armhf': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PAGE_TABLE_CHECK                         policy<{'amd64': 'n', 'arm64': 'n', 'riscv64': 'n'}>
+CONFIG_PAGE_TABLE_ISOLATION                     policy<{'amd64': 'y'}>
+CONFIG_PAHOLE_HAS_LANG_EXCLUDE                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PAHOLE_HAS_SPLIT_BTF                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PAHOLE_VERSION                           policy<{'amd64': '125', 'arm64': '125', 'armhf': '125', 'ppc64el': '125', 'riscv64': '125', 's390x': '125'}>
+CONFIG_PALMAS_GPADC                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PANASONIC_LAPTOP                         policy<{'amd64': 'm'}>
+CONFIG_PANEL                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PANEL_CHANGE_MESSAGE                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_PANEL_PARPORT                            policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0'}>
+CONFIG_PANEL_PROFILE                            policy<{'amd64': '5', 'arm64': '5', 'armhf': '5', 'ppc64el': '5', 'riscv64': '5'}>
+CONFIG_PANIC_ON_OOPS_VALUE                      policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0', 's390x': '0'}>
+CONFIG_PANIC_TIMEOUT                            policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '10', 'riscv64': '0', 's390x': '0'}>
+CONFIG_PANTHERLORD_FF                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PAPR_SCM                                 policy<{'ppc64el': 'm'}>
+CONFIG_PARAVIRT                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PARAVIRT_CLOCK                           policy<{'amd64': 'y'}>
+CONFIG_PARAVIRT_DEBUG                           policy<{'amd64': 'n'}>
+CONFIG_PARAVIRT_SPINLOCKS                       policy<{'amd64': 'y'}>
+CONFIG_PARAVIRT_TIME_ACCOUNTING                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'n'}>
+CONFIG_PARAVIRT_XXL                             policy<{'amd64': 'y'}>
+CONFIG_PARMAN                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_PARPORT                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_PARPORT_1284                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PARPORT_NOT_PC                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PARPORT_PANEL                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PARPORT_PC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PARPORT_PC_FIFO                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PARPORT_PC_PCMCIA                        policy<{'amd64': 'm'}>
+CONFIG_PARPORT_PC_SUPERIO                       policy<{'amd64': 'n', 'armhf': 'n', 'ppc64el': 'n'}>
+CONFIG_PARPORT_SERIAL                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PARTITION_ADVANCED                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PARTITION_PERCPU                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PATA_ACPI                                policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_ALI                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_AMD                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_ARTOP                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_ATIIXP                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_ATP867X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_CMD640_PCI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_CMD64X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_CYPRESS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_EFAR                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_HPT366                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_HPT37X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_HPT3X2N                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_HPT3X3                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_IMX                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PATA_IT8213                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_IT821X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_JMICRON                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_LEGACY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_MARVELL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_MPIIX                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_NETCELL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_NINJA32                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_NS87410                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_NS87415                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_OF_PLATFORM                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_OLDPIIX                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_OPTI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_OPTIDMA                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_PARPORT                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'n', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_ATEN                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_BPCK                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_BPCK6                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_COMM                        policy<{'amd64': 'm', 'arm64': 'n', 'arm64-generic-64k': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_DSTR                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_EPAT                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_EPATC8                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_PATA_PARPORT_EPIA                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_FIT2                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_FIT3                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_FRIQ                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_FRPW                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_KBIC                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_KTTI                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_ON20                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PARPORT_ON26                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PATA_PCMCIA                              policy<{'amd64': 'm'}>
+CONFIG_PATA_PDC2027X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_PDC_OLD                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_PLATFORM                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_RADISYS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_RDC                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_RZ1000                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_SCH                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_SERVERWORKS                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_SIL680                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_SIS                                 policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_TIMINGS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PATA_TOSHIBA                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_TRIFLEX                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_VIA                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PATA_WINBOND                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PC104                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_PC300TOO                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PC87413_WDT                              policy<{'amd64': 'm'}>
+CONFIG_PCC                                      policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_PCCARD                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PCCARD_NONSTATIC                         policy<{'amd64': 'y'}>
+CONFIG_PCENGINES_APU2                           policy<{'amd64': 'm'}>
+CONFIG_PCF50633_ADC                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PCF50633_GPIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PCI                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCI200SYN                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PCIEAER                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': '-', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCIEAER_CXL                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_PCIEAER_INJECT                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': '-', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PCIEASPM                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCIEASPM_PERFORMANCE                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PCIEASPM_POWERSAVE                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PCIEASPM_POWER_SUPERSAVE                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PCIE_AL                                  policy<{'arm64': 'y'}>
+CONFIG_PCIE_ALTERA                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCIE_ALTERA_MSI                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCIE_APPLE                               policy<{'arm64': 'm'}>
+CONFIG_PCIE_APPLE_MSI_DOORBELL_ADDR             policy<{'arm64': '0xfffff000'}>
+CONFIG_PCIE_ARMADA_8K                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCIE_BUS_DEFAULT                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCIE_BUS_PEER2PEER                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PCIE_BUS_PERFORMANCE                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PCIE_BUS_SAFE                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PCIE_BUS_TUNE_OFF                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PCIE_CADENCE                             policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PCIE_CADENCE_EP                          policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PCIE_CADENCE_HOST                        policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PCIE_CADENCE_PLAT                        policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PCIE_CADENCE_PLAT_EP                     policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PCIE_CADENCE_PLAT_HOST                   policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PCIE_DPC                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': '-', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCIE_DW                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCIE_DW_EP                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCIE_DW_HOST                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCIE_DW_PLAT                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCIE_DW_PLAT_EP                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCIE_DW_PLAT_HOST                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCIE_ECRC                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': '-', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PCIE_EDR                                 policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_PCIE_FU740                               policy<{'riscv64': 'y'}>
+CONFIG_PCIE_HISI_ERR                            policy<{'arm64': 'y'}>
+CONFIG_PCIE_HISI_STB                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCIE_KEEMBAY                             policy<{'arm64': 'y'}>
+CONFIG_PCIE_KEEMBAY_EP                          policy<{'arm64': 'y'}>
+CONFIG_PCIE_KEEMBAY_HOST                        policy<{'arm64': 'y'}>
+CONFIG_PCIE_KIRIN                               policy<{'arm64': 'y'}>
+CONFIG_PCIE_LAYERSCAPE_GEN4                     policy<{'arm64': 'n'}>
+CONFIG_PCIE_MEDIATEK                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCIE_MEDIATEK_GEN3                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PCIE_MICROCHIP_HOST                      policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PCIE_MOBIVEIL_PLAT                       policy<{'arm64': 'n'}>
+CONFIG_PCIE_PME                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_PCIE_PTM                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCIE_QCOM                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCIE_QCOM_EP                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PCIE_RCAR_EP                             policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_PCIE_RCAR_GEN4                           policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PCIE_RCAR_GEN4_EP                        policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PCIE_RCAR_GEN4_HOST                      policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PCIE_RCAR_HOST                           policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_PCIE_ROCKCHIP                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCIE_ROCKCHIP_DW_HOST                    policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCIE_ROCKCHIP_EP                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCIE_ROCKCHIP_HOST                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PCIE_TEGRA194                            policy<{'arm64': 'm'}>
+CONFIG_PCIE_TEGRA194_EP                         policy<{'arm64': 'm'}>
+CONFIG_PCIE_TEGRA194_HOST                       policy<{'arm64': 'm'}>
+CONFIG_PCIE_VISCONTI_HOST                       policy<{'arm64': 'y'}>
+CONFIG_PCIE_XILINX                              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PCIE_XILINX_CPM                          policy<{'arm64': 'y'}>
+CONFIG_PCIE_XILINX_DMA_PL                       policy<{'arm64': 'y'}>
+CONFIG_PCIE_XILINX_NWL                          policy<{'arm64': 'y'}>
+CONFIG_PCIPCWATCHDOG                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_PCI_AARDVARK                             policy<{'arm64': 'y'}>
+CONFIG_PCI_ATS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCI_BRIDGE_EMUL                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCI_CNB20LE_QUIRK                        policy<{'amd64': 'n'}>
+CONFIG_PCI_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PCI_DIRECT                               policy<{'amd64': 'y'}>
+CONFIG_PCI_DOE                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PCI_DOMAINS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCI_DOMAINS_GENERIC                      policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_PCI_DRA7XX                               policy<{'armhf': 'm'}>
+CONFIG_PCI_DRA7XX_EP                            policy<{'armhf': 'm'}>
+CONFIG_PCI_DRA7XX_HOST                          policy<{'armhf': 'm'}>
+CONFIG_PCI_ECAM                                 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PCI_ENDPOINT                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCI_ENDPOINT_CONFIGFS                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCI_ENDPOINT_TEST                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PCI_EPF_MHI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PCI_EPF_NTB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_PCI_EPF_TEST                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PCI_EPF_VNTB                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PCI_EXYNOS                               policy<{'armhf': 'n'}>
+CONFIG_PCI_FTPCI100                             policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PCI_HISI                                 policy<{'arm64': 'y'}>
+CONFIG_PCI_HOST_COMMON                          policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PCI_HOST_GENERIC                         policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PCI_HOST_THUNDER_ECAM                    policy<{'arm64': 'y'}>
+CONFIG_PCI_HOST_THUNDER_PEM                     policy<{'arm64': 'y'}>
+CONFIG_PCI_HYPERV                               policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_PCI_HYPERV_INTERFACE                     policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_PCI_IMX6                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCI_IMX6_EP                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCI_IMX6_HOST                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCI_IOV                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCI_J721E                                policy<{'arm64': 'y', 'armhf': '-', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_PCI_J721E_EP                             policy<{'arm64': 'y', 'armhf': '-', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_PCI_J721E_HOST                           policy<{'arm64': 'y', 'armhf': '-', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_PCI_KEYSTONE                             policy<{'arm64': 'y'}>
+CONFIG_PCI_KEYSTONE_EP                          policy<{'arm64': 'y'}>
+CONFIG_PCI_KEYSTONE_HOST                        policy<{'arm64': 'y'}>
+CONFIG_PCI_LABEL                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_PCI_LAYERSCAPE                           policy<{'arm64': 'y', 'armhf': 'n'}>
+CONFIG_PCI_LAYERSCAPE_EP                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCI_LOCKLESS_CONFIG                      policy<{'amd64': 'y'}>
+CONFIG_PCI_MMCONFIG                             policy<{'amd64': 'y'}>
+CONFIG_PCI_MSI                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCI_MSI_ARCH_FALLBACKS                   policy<{'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_PCI_MVEBU                                policy<{'armhf': 'm'}>
+CONFIG_PCI_P2PDMA                               policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_PCI_PASID                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_PCI_PF_STUB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_PCI_PRI                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_PCI_QUIRKS                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_PCI_RCAR_GEN2                            policy<{'armhf': 'y'}>
+CONFIG_PCI_REALLOC_ENABLE_AUTO                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCI_STUB                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_PCI_SW_SWITCHTEC                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_PCI_SYSCALL                              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_PCI_TEGRA                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PCI_V3_SEMI                              policy<{'armhf': 'y'}>
+CONFIG_PCI_XEN                                  policy<{'amd64': 'y'}>
+CONFIG_PCI_XGENE                                policy<{'arm64': 'y'}>
+CONFIG_PCI_XGENE_MSI                            policy<{'arm64': 'y'}>
+CONFIG_PCMCIA                                   policy<{'amd64': 'm', 'arm64': 'n', 'armhf': 'n', 'ppc64el': '-'}>
+CONFIG_PCMCIA_3C574                             policy<{'amd64': 'm'}>
+CONFIG_PCMCIA_3C589                             policy<{'amd64': 'm'}>
+CONFIG_PCMCIA_AHA152X                           policy<{'amd64': 'm'}>
+CONFIG_PCMCIA_AXNET                             policy<{'amd64': 'm'}>
+CONFIG_PCMCIA_FDOMAIN                           policy<{'amd64': 'm'}>
+CONFIG_PCMCIA_FMVJ18X                           policy<{'amd64': 'm'}>
+CONFIG_PCMCIA_LOAD_CIS                          policy<{'amd64': 'y'}>
+CONFIG_PCMCIA_NMCLAN                            policy<{'amd64': 'm'}>
+CONFIG_PCMCIA_PCNET                             policy<{'amd64': 'm'}>
+CONFIG_PCMCIA_QLOGIC                            policy<{'amd64': 'm'}>
+CONFIG_PCMCIA_SMC91C92                          policy<{'amd64': 'm'}>
+CONFIG_PCMCIA_SYM53C500                         policy<{'amd64': 'm'}>
+CONFIG_PCMCIA_XIRC2PS                           policy<{'amd64': 'm'}>
+CONFIG_PCMCIA_XIRCOM                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': '-'}>
+CONFIG_PCNET32                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PCPU_DEV_REFCNT                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PCP_BATCH_SCALE_MAX                      policy<{'amd64': '5', 'arm64': '5', 'armhf': '5', 'ppc64el': '5', 'riscv64': '5', 's390x': '5'}>
+CONFIG_PCSPKR_PLATFORM                          policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_PCS_LYNX                                 policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PCS_MTK_LYNXI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PCS_RZN1_MIIC                            policy<{'armhf': 'm'}>
+CONFIG_PCS_XPCS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PD6729                                   policy<{'amd64': 'm'}>
+CONFIG_PDC_ADMA                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PDS_CORE                                 policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PDS_VDPA                                 policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PDS_VFIO_PCI                             policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PECI                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_PECI_ASPEED                              policy<{'armhf': 'm'}>
+CONFIG_PECI_CPU                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PECI_NPCM                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PERCPU_STATS                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PERCPU_TEST                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PERF_EVENTS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PERF_EVENTS_AMD_BRS                      policy<{'amd64': 'y'}>
+CONFIG_PERF_EVENTS_AMD_POWER                    policy<{'amd64': 'n'}>
+CONFIG_PERF_EVENTS_AMD_UNCORE                   policy<{'amd64': 'm'}>
+CONFIG_PERF_EVENTS_INTEL_CSTATE                 policy<{'amd64': 'm'}>
+CONFIG_PERF_EVENTS_INTEL_RAPL                   policy<{'amd64': 'm'}>
+CONFIG_PERF_EVENTS_INTEL_UNCORE                 policy<{'amd64': 'y'}>
+CONFIG_PERF_USE_VMALLOC                         policy<{'armhf': 'y'}>
+CONFIG_PERSISTENT_KEYRINGS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PER_VMA_LOCK                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PER_VMA_LOCK_STATS                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PFAULT                                   policy<{'s390x': 'y'}>
+CONFIG_PGSTE                                    policy<{'s390x': 'y'}>
+CONFIG_PGTABLE_LEVELS                           policy<{'amd64': '5', 'arm64': '4', 'arm64-generic-64k': '3', 'armhf': '3', 'ppc64el': '4', 'riscv64': '5', 's390x': '5'}>
+CONFIG_PHANTOM                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_PHONET                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_PHYLIB                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PHYLIB_LEDS                              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PHYLINK                                  policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PHYSICAL_ALIGN                           policy<{'amd64': '0x200000'}>
+CONFIG_PHYSICAL_START                           policy<{'amd64': '0x1000000', 'ppc64el': '0x00000000'}>
+CONFIG_PHYS_ADDR_T_64BIT                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PHY_AM654_SERDES                         policy<{'arm64': 'm'}>
+CONFIG_PHY_BERLIN_SATA                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_BERLIN_USB                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_CADENCE_DPHY                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_CADENCE_DPHY_RX                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_CADENCE_SALVO                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_CADENCE_SIERRA                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_CADENCE_TORRENT                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_CAN_TRANSCEIVER                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_PHY_CPCAP_USB                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_DM816X_USB                           policy<{'armhf': 'm'}>
+CONFIG_PHY_EXYNOS_DP_VIDEO                      policy<{'armhf': 'n'}>
+CONFIG_PHY_EXYNOS_MIPI_VIDEO                    policy<{'armhf': 'n'}>
+CONFIG_PHY_EXYNOS_PCIE                          policy<{'armhf': 'n'}>
+CONFIG_PHY_FSL_IMX8MQ_USB                       policy<{'arm64': 'm'}>
+CONFIG_PHY_FSL_IMX8M_PCIE                       policy<{'arm64': 'm'}>
+CONFIG_PHY_FSL_LYNX_28G                         policy<{'arm64': 'm'}>
+CONFIG_PHY_HI3660_USB                           policy<{'arm64': 'm'}>
+CONFIG_PHY_HI3670_PCIE                          policy<{'arm64': 'm'}>
+CONFIG_PHY_HI3670_USB                           policy<{'arm64': 'm'}>
+CONFIG_PHY_HI6220_USB                           policy<{'arm64': 'm'}>
+CONFIG_PHY_HISI_INNO_USB2                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_HISTB_COMBPHY                        policy<{'arm64': 'm'}>
+CONFIG_PHY_HIX5HD2_SATA                         policy<{'armhf': 'm'}>
+CONFIG_PHY_INTEL_KEEMBAY_EMMC                   policy<{'arm64': 'm'}>
+CONFIG_PHY_INTEL_KEEMBAY_USB                    policy<{'arm64': 'm'}>
+CONFIG_PHY_INTEL_LGM_EMMC                       policy<{'amd64': 'm'}>
+CONFIG_PHY_J721E_WIZ                            policy<{'arm64': 'm'}>
+CONFIG_PHY_LAN966X_SERDES                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_MAPPHONE_MDM6600                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_MESON8B_USB2                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MESON8_HDMI_TX                       policy<{'armhf': 'm'}>
+CONFIG_PHY_MESON_AXG_MIPI_DPHY                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PHY_MESON_AXG_PCIE                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PHY_MESON_G12A_MIPI_DPHY_ANALOG          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MESON_G12A_USB2                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MESON_G12A_USB3_PCIE                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MESON_GXL_USB2                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MIXEL_LVDS_PHY                       policy<{'arm64': 'm'}>
+CONFIG_PHY_MIXEL_MIPI_DPHY                      policy<{'arm64': 'm'}>
+CONFIG_PHY_MTK_DP                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MTK_HDMI                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MTK_MIPI_DSI                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MTK_PCIE                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MTK_TPHY                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MTK_UFS                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MTK_XSPHY                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MVEBU_A3700_COMPHY                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MVEBU_A3700_UTMI                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MVEBU_A38X_COMPHY                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MVEBU_CP110_COMPHY                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MVEBU_CP110_UTMI                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_MVEBU_SATA                           policy<{'armhf': 'y'}>
+CONFIG_PHY_OCELOT_SERDES                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_PXA_28NM_HSIC                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_PHY_PXA_28NM_USB2                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_PHY_QCOM_APQ8064_SATA                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_EDP                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_EUSB2_REPEATER                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_IPQ4019_USB                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_IPQ806X_SATA                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_IPQ806X_USB                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_M31_USB                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_PCIE2                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_QMP                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_QMP_COMBO                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_QMP_PCIE                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_QMP_PCIE_8996                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_QMP_UFS                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_QMP_USB                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_QMP_USB_LEGACY                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_QUSB2                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_SGMII_ETH                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_SNPS_EUSB2                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_USB_HS                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_QCOM_USB_HSIC                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_QCOM_USB_HS_28NM                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_QCOM_USB_SS                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_R8A779F0_ETHERNET_SERDES             policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_RCAR_GEN2                            policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_RCAR_GEN3_PCIE                       policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_RCAR_GEN3_USB2                       policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_RCAR_GEN3_USB3                       policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_ROCKCHIP_DP                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_ROCKCHIP_DPHY_RX0                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_ROCKCHIP_EMMC                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_ROCKCHIP_INNO_HDMI                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_ROCKCHIP_INNO_USB2                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_ROCKCHIP_PCIE                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_ROCKCHIP_SNPS_PCIE3                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_ROCKCHIP_TYPEC                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_ROCKCHIP_USB                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_SAMSUNG_UFS                          policy<{'armhf': 'n'}>
+CONFIG_PHY_SAMSUNG_USB2                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PHY_SPARX5_SERDES                        policy<{'amd64': '-', 'arm64': 'm', 'armhf': '-', 'ppc64el': '-'}>
+CONFIG_PHY_STARFIVE_JH7110_DPHY_RX              policy<{'riscv64': 'm'}>
+CONFIG_PHY_STARFIVE_JH7110_PCIE                 policy<{'riscv64': 'm'}>
+CONFIG_PHY_STARFIVE_JH7110_USB                  policy<{'riscv64': 'm'}>
+CONFIG_PHY_STM32_USBPHYC                        policy<{'arm64': 'm'}>
+CONFIG_PHY_SUN4I_USB                            policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_PHY_SUN50I_USB3                          policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_PHY_SUN6I_MIPI_DPHY                      policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_PHY_SUN9I_USB                            policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PHY_SUNPLUS_USB                          policy<{'armhf': 'm'}>
+CONFIG_PHY_TEGRA194_P2U                         policy<{'arm64': 'm'}>
+CONFIG_PHY_TEGRA_XUSB                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PHY_TI_GMII_SEL                          policy<{'arm64': 'm', 'armhf': 'y'}>
+CONFIG_PHY_TUSB1210                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PHY_XGENE                                policy<{'arm64': 'y'}>
+CONFIG_PHY_XILINX_ZYNQMP                        policy<{'arm64': 'm'}>
+CONFIG_PI433                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PID_IN_CONTEXTIDR                        policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_PID_NS                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PINCONF                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_PINCTRL_AC5                              policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_ALDERLAKE                        policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_AMD                              policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_AMLOGIC_C3                       policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_AMLOGIC_T7                       policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_APPLE_GPIO                       policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_APQ8064                          policy<{'armhf': 'm'}>
+CONFIG_PINCTRL_APQ8084                          policy<{'armhf': 'm'}>
+CONFIG_PINCTRL_ARMADA_370                       policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_ARMADA_375                       policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_ARMADA_37XX                      policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_ARMADA_38X                       policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_ARMADA_39X                       policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_ARMADA_AP806                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_ARMADA_CP110                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_ARMADA_XP                        policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_AS370                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_AS3722                           policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_ASPEED                           policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_ASPEED_G6                        policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_AXP209                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PINCTRL_BAYTRAIL                         policy<{'amd64': 'y'}>
+CONFIG_PINCTRL_BERLIN                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_BERLIN_BG2                       policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_BERLIN_BG2CD                     policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_BERLIN_BG2Q                      policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_BERLIN_BG4CT                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_BM1880                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_BROXTON                          policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_CANNONLAKE                       policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_CEDARFORK                        policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_CS42L43                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PINCTRL_CS47L15                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_CS47L35                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_CS47L85                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_CS47L90                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_CS47L92                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_CY8C95X0                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PINCTRL_DA9062                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PINCTRL_DENVERTON                        policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_DOVE                             policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_ELKHARTLAKE                      policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_EMMITSBURG                       policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_EXYNOS                           policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_EXYNOS_ARM                       policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_GEMINILAKE                       policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_ICELAKE                          policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_IMX                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_IMX50                            policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_IMX51                            policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_IMX6Q                            policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_IMX6SL                           policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_IMX6SLL                          policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_IMX6SX                           policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_IMX6UL                           policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_IMX7D                            policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_IMX7ULP                          policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_IMX8DXL                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_IMX8MM                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_IMX8MN                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_IMX8MP                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_IMX8MQ                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_IMX8QM                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_IMX8QXP                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_IMX8ULP                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PINCTRL_IMX93                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PINCTRL_IMXRT1050                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_IMXRT1170                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_IMX_SCU                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_INTEL                            policy<{'amd64': 'y'}>
+CONFIG_PINCTRL_INTEL_PLATFORM                   policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_IPQ4019                          policy<{'armhf': 'm'}>
+CONFIG_PINCTRL_IPQ5018                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_IPQ5332                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_IPQ6018                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_IPQ8064                          policy<{'armhf': 'm'}>
+CONFIG_PINCTRL_IPQ8074                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_IPQ9574                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_JASPERLAKE                       policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_KEEMBAY                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_LAKEFIELD                        policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_LEWISBURG                        policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_LOCHNAGAR                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PINCTRL_LPASS_LPI                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PINCTRL_LYNXPOINT                        policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_MADERA                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PINCTRL_MAX77620                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PINCTRL_MCP23S08                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PINCTRL_MCP23S08_I2C                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PINCTRL_MCP23S08_SPI                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PINCTRL_MDM9607                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PINCTRL_MDM9615                          policy<{'armhf': 'm'}>
+CONFIG_PINCTRL_MESON                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_MESON8                           policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_MESON8B                          policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_MESON8_PMX                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_MESON_A1                         policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MESON_AXG                        policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MESON_AXG_PMX                    policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MESON_G12A                       policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MESON_GXBB                       policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MESON_GXL                        policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MESON_S4                         policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_METEORLAKE                       policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_METEORPOINT                      policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_MICROCHIP_SGPIO                  policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_MLXBF3                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_MSM                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_MSM8226                          policy<{'armhf': 'm'}>
+CONFIG_PINCTRL_MSM8660                          policy<{'armhf': 'm'}>
+CONFIG_PINCTRL_MSM8909                          policy<{'armhf': 'm'}>
+CONFIG_PINCTRL_MSM8916                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PINCTRL_MSM8953                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_MSM8960                          policy<{'armhf': 'm'}>
+CONFIG_PINCTRL_MSM8976                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_MSM8994                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_MSM8996                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_MSM8998                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_MSM8X74                          policy<{'armhf': 'm'}>
+CONFIG_PINCTRL_MT2701                           policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_MT2712                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT6397                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_MT6765                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT6779                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_MT6795                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT6797                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT7622                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT7623                           policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_MT7629                           policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_MT7981                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT7986                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT8127                           policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_MT8135                           policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_MT8167                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT8173                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT8183                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT8186                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT8188                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT8192                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT8195                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT8365                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT8516                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MTK                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_MTK_MOORE                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_MTK_PARIS                        policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MTK_V2                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_MVEBU                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_NPCM7XX                          policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_NPCM8XX                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PINCTRL_OCELOT                           policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_OWL                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_PALMAS                           policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_PEF2256                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PINCTRL_PFC_EMEV2                        policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_PFC_R8A7740                      policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_PFC_R8A7742                      policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_PFC_R8A7743                      policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_PFC_R8A7744                      policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_PFC_R8A7745                      policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_PFC_R8A77470                     policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_PFC_R8A774A1                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_R8A774B1                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_R8A774C0                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_R8A774E1                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_R8A7778                      policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_PFC_R8A7779                      policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_PFC_R8A7790                      policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_PFC_R8A7791                      policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_PFC_R8A7792                      policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_PFC_R8A7793                      policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_PFC_R8A7794                      policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_PFC_R8A77951                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_R8A77960                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_R8A77961                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_R8A77965                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_R8A77970                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_R8A77980                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_R8A77990                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_R8A77995                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_R8A779A0                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_R8A779F0                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_R8A779G0                     policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_PFC_SH73A0                       policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_QCM2290                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_QCOM_SPMI_PMIC                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PINCTRL_QCOM_SSBI_PMIC                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PINCTRL_QCS404                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_QDF2XXX                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_QDU1000                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_RENESAS                          policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_RK805                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PINCTRL_ROCKCHIP                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_RTD                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PINCTRL_RTD1315E                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PINCTRL_RTD1319D                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PINCTRL_RTD1619B                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PINCTRL_RZA1                             policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_RZA2                             policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_RZG2L                            policy<{'arm64': 'y', 'riscv64': '-'}>
+CONFIG_PINCTRL_RZN1                             policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_RZV2M                            policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_S32CC                            policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_S32G2                            policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_S500                             policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_S700                             policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_S900                             policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SA8775P                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SAMSUNG                          policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_SC7180                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SC7280                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SC7280_LPASS_LPI                 policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SC8180X                          policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SC8280XP                         policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SC8280XP_LPASS_LPI               policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SDM660                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SDM670                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SDM845                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SDX55                            policy<{'armhf': 'm'}>
+CONFIG_PINCTRL_SDX65                            policy<{'armhf': 'm'}>
+CONFIG_PINCTRL_SDX75                            policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SH_PFC                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_SH_PFC_GPIO                      policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_SINGLE                           policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_SM4450                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM6115                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM6115_LPASS_LPI                 policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM6125                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM6350                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM6375                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM7150                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM8150                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM8250                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM8250_LPASS_LPI                 policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM8350                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM8350_LPASS_LPI                 policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM8450                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM8450_LPASS_LPI                 policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM8550                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM8550_LPASS_LPI                 policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM8650                           policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SM8650_LPASS_LPI                 policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SPPCTL                           policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_SPRD                             policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SPRD_SC9860                      policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_STARFIVE_JH7100                  policy<{'riscv64': 'n'}>
+CONFIG_PINCTRL_STARFIVE_JH7110                  policy<{'riscv64': 'y'}>
+CONFIG_PINCTRL_STARFIVE_JH7110_AON              policy<{'riscv64': 'm'}>
+CONFIG_PINCTRL_STARFIVE_JH7110_SYS              policy<{'riscv64': 'y'}>
+CONFIG_PINCTRL_STM32                            policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_STM32MP257                       policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_STMFX                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PINCTRL_SUN20I_D1                        policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_SUN4I_A10                        policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN50I_A100                      policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN50I_A100_R                    policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN50I_A64                       policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN50I_A64_R                     policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN50I_H5                        policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN50I_H6                        policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN50I_H616                      policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN50I_H616_R                    policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN50I_H6_R                      policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN5I                            policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN6I_A31                        policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN6I_A31_R                      policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN8I_A23                        policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN8I_A23_R                      policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN8I_A33                        policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN8I_A83T                       policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN8I_A83T_R                     policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN8I_H3                         policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN8I_H3_R                       policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN8I_V3S                        policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN9I_A80                        policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUN9I_A80_R                      policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_PINCTRL_SUNRISEPOINT                     policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_SUNXI                            policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_SX150X                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PINCTRL_TEGRA                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_TEGRA114                         policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_TEGRA124                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_TEGRA194                         policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_TEGRA20                          policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_TEGRA210                         policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_TEGRA234                         policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_TEGRA30                          policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_TEGRA_XUSB                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_PINCTRL_TIGERLAKE                        policy<{'amd64': 'm'}>
+CONFIG_PINCTRL_TI_IODELAY                       policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_TMPV7700                         policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_TPS6594                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PINCTRL_VF610                            policy<{'armhf': 'y'}>
+CONFIG_PINCTRL_VISCONTI                         policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_X1E80100                         policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_ZYNQMP                           policy<{'arm64': 'm'}>
+CONFIG_PING                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PINMUX                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PJ4B_ERRATA_4742                         policy<{'armhf': 'y'}>
+CONFIG_PKCS7_MESSAGE_PARSER                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PKCS7_TEST_KEY                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_PKCS8_PRIVATE_KEY_PARSER                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_PKEY                                     policy<{'s390x': 'm'}>
+CONFIG_PL310_ERRATA_588369                      policy<{'armhf': 'y'}>
+CONFIG_PL310_ERRATA_727915                      policy<{'armhf': 'y'}>
+CONFIG_PL310_ERRATA_753970                      policy<{'armhf': 'y'}>
+CONFIG_PL310_ERRATA_769419                      policy<{'armhf': 'y'}>
+CONFIG_PL320_MBOX                               policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_PL330_DMA                                policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PL353_SMC                                policy<{'armhf': 'm'}>
+CONFIG_PLATFORM_MHU                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PLATFORM_SI4713                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PLAT_ORION                               policy<{'armhf': 'y'}>
+CONFIG_PLAT_SPEAR                               policy<{'armhf': 'n'}>
+CONFIG_PLAT_VERSATILE                           policy<{'armhf': 'y'}>
+CONFIG_PLAYSTATION_FF                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PLDMFW                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PLFXLC                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PLIP                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PLX_DMA                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PM8916_WATCHDOG                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PMBUS                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PMIC_ADP5520                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_PMIC_DA903X                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_PMIC_DA9052                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PMIC_OPREGION                            policy<{'amd64': 'y', 'arm64': 'n', 'riscv64': 'y'}>
+CONFIG_PMS7003                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PMU_SYSFS                                policy<{'ppc64el': 'n'}>
+CONFIG_PM_ADVANCED_DEBUG                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PM_AUTOSLEEP                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_PM_CLK                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PM_DEBUG                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PM_DEVFREQ                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_PM_DEVFREQ_EVENT                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PM_GENERIC_DOMAINS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PM_GENERIC_DOMAINS_OF                    policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PM_GENERIC_DOMAINS_SLEEP                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PM_NOTIFIER_ERROR_INJECT                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PM_OPP                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PM_SLEEP                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PM_SLEEP_DEBUG                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PM_SLEEP_SMP                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PM_SLEEP_SMP_NONZERO_CPU                 policy<{'ppc64el': 'y'}>
+CONFIG_PM_STD_PARTITION                         policy<{'amd64': '""', 'armhf': '""', 'riscv64': '-'}>
+CONFIG_PM_TEST_SUSPEND                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_PM_TRACE                                 policy<{'amd64': 'y'}>
+CONFIG_PM_TRACE_RTC                             policy<{'amd64': 'y'}>
+CONFIG_PM_USERSPACE_AUTOSLEEP                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_PM_WAKELOCKS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PM_WAKELOCKS_GC                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PM_WAKELOCKS_LIMIT                       policy<{'amd64': '100', 'arm64': '100', 'armhf': '100', 'ppc64el': '100', 'riscv64': '100'}>
+CONFIG_PNFS_BLOCK                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_PNFS_FILE_LAYOUT                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_PNFS_FLEXFILE_LAYOUT                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_PNP                                      policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_PNPACPI                                  policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_PNP_DEBUG_MESSAGES                       policy<{'amd64': 'n', 'arm64': 'n', 'riscv64': 'n'}>
+CONFIG_POLARFIRE_SOC_AUTO_UPDATE                policy<{'riscv64': 'm'}>
+CONFIG_POLARFIRE_SOC_MAILBOX                    policy<{'riscv64': 'm'}>
+CONFIG_POLARFIRE_SOC_SYS_CTRL                   policy<{'riscv64': 'm'}>
+CONFIG_POLYNOMIAL                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PORTABLE                                 policy<{'riscv64': 'y'}>
+CONFIG_POSIX_CPU_TIMERS_TASK_WORK               policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_POSIX_MQUEUE                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_POSIX_MQUEUE_SYSCTL                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_POSIX_TIMERS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_POWER10_CPU                              policy<{'ppc64el': 'n'}>
+CONFIG_POWER7_CPU                               policy<{'ppc64el': 'n'}>
+CONFIG_POWER8_CPU                               policy<{'ppc64el': 'n'}>
+CONFIG_POWER9_CPU                               policy<{'ppc64el': 'n'}>
+CONFIG_POWERCAP                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_POWERNV_CPUFREQ                          policy<{'ppc64el': 'y'}>
+CONFIG_POWERNV_CPUIDLE                          policy<{'ppc64el': 'y'}>
+CONFIG_POWERNV_OP_PANEL                         policy<{'ppc64el': 'm'}>
+CONFIG_POWERPC64_CPU                            policy<{'ppc64el': 'y'}>
+CONFIG_POWER_MLXBF                              policy<{'arm64': 'm'}>
+CONFIG_POWER_RESET                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_POWER_RESET_AS3722                       policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_POWER_RESET_ATC260X                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_POWER_RESET_AXXIA                        policy<{'armhf': 'y'}>
+CONFIG_POWER_RESET_BRCMKONA                     policy<{'armhf': 'y'}>
+CONFIG_POWER_RESET_GPIO                         policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_POWER_RESET_GPIO_RESTART                 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_POWER_RESET_HISI                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_POWER_RESET_LINKSTATION                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_POWER_RESET_LTC2952                      policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_POWER_RESET_MSM                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_POWER_RESET_MT6323                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_POWER_RESET_OCELOT_RESET                 policy<{'arm64': 'y'}>
+CONFIG_POWER_RESET_ODROID_GO_ULTRA_POWEROFF     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_POWER_RESET_QCOM_PON                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_POWER_RESET_QNAP                         policy<{'armhf': 'n'}>
+CONFIG_POWER_RESET_REGULATOR                    policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_POWER_RESET_RESTART                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_POWER_RESET_RMOBILE                      policy<{'armhf': 'm'}>
+CONFIG_POWER_RESET_SC27XX                       policy<{'arm64': 'm'}>
+CONFIG_POWER_RESET_SYSCON                       policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_POWER_RESET_SYSCON_POWEROFF              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_POWER_RESET_TPS65086                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_POWER_RESET_VERSATILE                    policy<{'armhf': 'y'}>
+CONFIG_POWER_RESET_VEXPRESS                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_POWER_RESET_XGENE                        policy<{'arm64': 'n'}>
+CONFIG_POWER_SUPPLY                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_POWER_SUPPLY_DEBUG                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_POWER_SUPPLY_HWMON                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PPC                                      policy<{'ppc64el': 'y'}>
+CONFIG_PPC64                                    policy<{'ppc64el': 'y'}>
+CONFIG_PPC64_BOOT_WRAPPER                       policy<{'ppc64el': 'y'}>
+CONFIG_PPC64_ELF_ABI_V2                         policy<{'ppc64el': 'y'}>
+CONFIG_PPC64_SUPPORTS_MEMORY_FAILURE            policy<{'ppc64el': 'y'}>
+CONFIG_PPC_4K_PAGES                             policy<{'ppc64el': 'n'}>
+CONFIG_PPC_64K_PAGES                            policy<{'ppc64el': 'y'}>
+CONFIG_PPC_64S_HASH_MMU                         policy<{'ppc64el': 'y'}>
+CONFIG_PPC_BARRIER_NOSPEC                       policy<{'ppc64el': 'y'}>
+CONFIG_PPC_BOOK3E_64                            policy<{'ppc64el': 'n'}>
+CONFIG_PPC_BOOK3S                               policy<{'ppc64el': 'y'}>
+CONFIG_PPC_BOOK3S_64                            policy<{'ppc64el': 'y'}>
+CONFIG_PPC_BOOK3S_IDLE                          policy<{'ppc64el': 'y'}>
+CONFIG_PPC_COPRO_BASE                           policy<{'ppc64el': 'y'}>
+CONFIG_PPC_DAWR                                 policy<{'ppc64el': 'y'}>
+CONFIG_PPC_DENORMALISATION                      policy<{'ppc64el': 'y'}>
+CONFIG_PPC_DISABLE_WERROR                       policy<{'ppc64el': 'n'}>
+CONFIG_PPC_DOORBELL                             policy<{'ppc64el': 'y'}>
+CONFIG_PPC_DT_CPU_FTRS                          policy<{'ppc64el': 'y'}>
+CONFIG_PPC_EARLY_DEBUG                          policy<{'ppc64el': 'n'}>
+CONFIG_PPC_EMULATED_STATS                       policy<{'ppc64el': 'n'}>
+CONFIG_PPC_EPAPR_HV_BYTECHAN                    policy<{'ppc64el': 'n'}>
+CONFIG_PPC_FAST_ENDIAN_SWITCH                   policy<{'ppc64el': 'n'}>
+CONFIG_PPC_FPU                                  policy<{'ppc64el': 'y'}>
+CONFIG_PPC_FPU_REGS                             policy<{'ppc64el': 'y'}>
+CONFIG_PPC_HASH_MMU_NATIVE                      policy<{'ppc64el': 'y'}>
+CONFIG_PPC_HAS_LBARX_LHARX                      policy<{'ppc64el': 'y'}>
+CONFIG_PPC_HAVE_PMU_SUPPORT                     policy<{'ppc64el': 'y'}>
+CONFIG_PPC_I8259                                policy<{'ppc64el': 'y'}>
+CONFIG_PPC_ICP_HV                               policy<{'ppc64el': 'y'}>
+CONFIG_PPC_ICP_NATIVE                           policy<{'ppc64el': 'y'}>
+CONFIG_PPC_ICS_RTAS                             policy<{'ppc64el': 'y'}>
+CONFIG_PPC_INDIRECT_PIO                         policy<{'ppc64el': 'y'}>
+CONFIG_PPC_IRQ_SOFT_MASK_DEBUG                  policy<{'ppc64el': 'n'}>
+CONFIG_PPC_KUAP                                 policy<{'ppc64el': 'y'}>
+CONFIG_PPC_KUAP_DEBUG                           policy<{'ppc64el': 'n'}>
+CONFIG_PPC_KUEP                                 policy<{'ppc64el': 'y'}>
+CONFIG_PPC_MEMTRACE                             policy<{'ppc64el': 'y'}>
+CONFIG_PPC_MSI_BITMAP                           policy<{'ppc64el': 'y'}>
+CONFIG_PPC_OF_BOOT_TRAMPOLINE                   policy<{'ppc64el': 'y'}>
+CONFIG_PPC_P7_NAP                               policy<{'ppc64el': 'y'}>
+CONFIG_PPC_PAGE_SHIFT                           policy<{'ppc64el': '16'}>
+CONFIG_PPC_PERF_CTRS                            policy<{'ppc64el': 'y'}>
+CONFIG_PPC_PKEY                                 policy<{'ppc64el': 'y'}>
+CONFIG_PPC_POWERNV                              policy<{'ppc64el': 'y'}>
+CONFIG_PPC_PROT_SAO_LPAR                        policy<{'ppc64el': 'n'}>
+CONFIG_PPC_PSERIES                              policy<{'ppc64el': 'y'}>
+CONFIG_PPC_QUEUED_SPINLOCKS                     policy<{'ppc64el': 'n'}>
+CONFIG_PPC_RADIX_MMU                            policy<{'ppc64el': 'y'}>
+CONFIG_PPC_RADIX_MMU_DEFAULT                    policy<{'ppc64el': 'y'}>
+CONFIG_PPC_RFI_SRR_DEBUG                        policy<{'ppc64el': 'n'}>
+CONFIG_PPC_RTAS                                 policy<{'ppc64el': 'y'}>
+CONFIG_PPC_RTAS_DAEMON                          policy<{'ppc64el': 'y'}>
+CONFIG_PPC_SMLPAR                               policy<{'ppc64el': 'y'}>
+CONFIG_PPC_SMP_MUXED_IPI                        policy<{'ppc64el': 'y'}>
+CONFIG_PPC_SPLPAR                               policy<{'ppc64el': 'y'}>
+CONFIG_PPC_SUBPAGE_PROT                         policy<{'ppc64el': 'y'}>
+CONFIG_PPC_SVM                                  policy<{'ppc64el': 'y'}>
+CONFIG_PPC_TRANSACTIONAL_MEM                    policy<{'ppc64el': 'y'}>
+CONFIG_PPC_UDBG_16550                           policy<{'ppc64el': 'y'}>
+CONFIG_PPC_UV                                   policy<{'ppc64el': 'y'}>
+CONFIG_PPC_VAS                                  policy<{'ppc64el': 'y'}>
+CONFIG_PPC_WATCHDOG                             policy<{'ppc64el': 'y'}>
+CONFIG_PPC_WERROR                               policy<{'ppc64el': 'y'}>
+CONFIG_PPC_XICS                                 policy<{'ppc64el': 'y'}>
+CONFIG_PPC_XIVE                                 policy<{'ppc64el': 'y'}>
+CONFIG_PPC_XIVE_NATIVE                          policy<{'ppc64el': 'y'}>
+CONFIG_PPC_XIVE_SPAPR                           policy<{'ppc64el': 'y'}>
+CONFIG_PPDEV                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PPP                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_PPPOATM                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PPPOE                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PPPOE_HASH_BITS                          policy<{'amd64': '4', 'arm64': '4', 'armhf': '4', 'ppc64el': '4', 'riscv64': '4'}>
+CONFIG_PPPOE_HASH_BITS_1                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_PPPOE_HASH_BITS_2                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_PPPOE_HASH_BITS_4                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PPPOE_HASH_BITS_8                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_PPPOL2TP                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PPP_ASYNC                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PPP_BSDCOMP                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PPP_DEFLATE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PPP_FILTER                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PPP_MPPE                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PPP_MULTILINK                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PPP_SYNC_TTY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PPS                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PPS_CLIENT_GPIO                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_PPS_CLIENT_KTIMER                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PPS_CLIENT_LDISC                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_PPS_CLIENT_PARPORT                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PPS_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PPTP                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PREEMPT                                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PREEMPTION                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': '-', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_PREEMPTIRQ_DELAY_TEST                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PREEMPT_BUILD                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': '-', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_PREEMPT_COUNT                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': '-', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_PREEMPT_NONE                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PREEMPT_NOTIFIERS                        policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PREEMPT_RCU                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': '-', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_PREEMPT_TRACER                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': '-', 'ppc64el': '-', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_PREEMPT_VOLUNTARY                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PREEMPT_VOLUNTARY_BUILD                  policy<{'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_PREFIX_SYMBOLS                           policy<{'amd64': 'y'}>
+CONFIG_PRESTERA                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PRESTERA_PCI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PREVENT_FIRMWARE_BUILD                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PRIME_NUMBERS                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PRINTER                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PRINTK                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PRINTK_CALLER                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PRINTK_INDEX                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PRINTK_TIME                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PRINT_STACK_DEPTH                        policy<{'ppc64el': '64'}>
+CONFIG_PRISM2_USB                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PROBE_EVENTS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PROBE_EVENTS_BTF_ARGS                    policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PROCESSOR_SELECT                         policy<{'amd64': 'y'}>
+CONFIG_PROC_CHILDREN                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PROC_CPU_RESCTRL                         policy<{'amd64': 'y'}>
+CONFIG_PROC_EVENTS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PROC_FS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PROC_KCORE                               policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PROC_MEM_ALWAYS_FORCE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PROC_MEM_FORCE_PTRACE                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PROC_MEM_NO_FORCE                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PROC_PAGE_MONITOR                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PROC_PID_ARCH_STATUS                     policy<{'amd64': 'y'}>
+CONFIG_PROC_PID_CPUSET                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PROC_SYSCTL                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PROC_THERMAL_MMIO_RAPL                   policy<{'amd64': 'm'}>
+CONFIG_PROC_VMCORE                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PROC_VMCORE_DEVICE_DUMP                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PROFILE_ALL_BRANCHES                     policy<{'riscv64': 'n'}>
+CONFIG_PROFILE_ANNOTATED_BRANCHES               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PROFILING                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PROTECTED_VIRTUALIZATION_GUEST           policy<{'s390x': 'y'}>
+CONFIG_PROVE_LOCKING                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_PROVIDE_OHCI1394_DMA_INIT                policy<{'amd64': 'n'}>
+CONFIG_PRU_REMOTEPROC                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PSAMPLE                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_PSERIES_CPUIDLE                          policy<{'ppc64el': 'y'}>
+CONFIG_PSERIES_ENERGY                           policy<{'ppc64el': 'm'}>
+CONFIG_PSERIES_PLPKS                            policy<{'ppc64el': 'y'}>
+CONFIG_PSERIES_PLPKS_SED                        policy<{'ppc64el': 'y'}>
+CONFIG_PSERIES_WDT                              policy<{'ppc64el': 'm'}>
+CONFIG_PSE_CONTROLLER                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_PSE_REGULATOR                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PSI                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PSTORE                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_PSTORE_BLK                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PSTORE_BLK_BLKDEV                        policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'ppc64el': '""', 'riscv64': '""', 's390x': '-'}>
+CONFIG_PSTORE_BLK_CONSOLE_SIZE                  policy<{'armhf': '64'}>
+CONFIG_PSTORE_BLK_KMSG_SIZE                     policy<{'amd64': '64', 'arm64': '64', 'armhf': '64', 'ppc64el': '64', 'riscv64': '64'}>
+CONFIG_PSTORE_BLK_MAX_REASON                    policy<{'amd64': '2', 'arm64': '2', 'armhf': '2', 'ppc64el': '2', 'riscv64': '2', 's390x': '-'}>
+CONFIG_PSTORE_COMPRESS                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PSTORE_CONSOLE                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'y', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_PSTORE_DEFAULT_KMSG_BYTES                policy<{'amd64': '10240', 'arm64': '10240', 'armhf': '10240', 'ppc64el': '10240', 'riscv64': '10240'}>
+CONFIG_PSTORE_FTRACE                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': '-', 's390x': '-'}>
+CONFIG_PSTORE_PMSG                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_PSTORE_RAM                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PSTORE_ZONE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PTDUMP_CORE                              policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_PTDUMP_DEBUGFS                           policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'y'}>
+CONFIG_PTE_MARKER_UFFD_WP                       policy<{'amd64': 'y'}>
+CONFIG_PTP_1588_CLOCK                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_PTP_1588_CLOCK_IDT82P33                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_PTP_1588_CLOCK_IDTCM                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_PTP_1588_CLOCK_INES                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_PTP_1588_CLOCK_KVM                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PTP_1588_CLOCK_MOCK                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_PTP_1588_CLOCK_OCP                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PTP_1588_CLOCK_OPTIONAL                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_PTP_1588_CLOCK_QORIQ                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_PTP_1588_CLOCK_VMW                       policy<{'amd64': 'm'}>
+CONFIG_PTP_DFL_TOD                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PUNIT_ATOM_DEBUG                         policy<{'amd64': 'm'}>
+CONFIG_PVH                                      policy<{'amd64': 'y'}>
+CONFIG_PVPANIC                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_PVPANIC_MMIO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PVPANIC_PCI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PWC_RZV2M                                policy<{'arm64': 'y'}>
+CONFIG_PWM                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_PWM_APPLE                                policy<{'arm64': 'm'}>
+CONFIG_PWM_ATMEL_HLCDC_PWM                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PWM_ATMEL_TCB                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PWM_BERLIN                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PWM_CLK                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PWM_CRC                                  policy<{'amd64': 'y'}>
+CONFIG_PWM_CROS_EC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PWM_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_PWM_DWC                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PWM_DWC_CORE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PWM_FSL_FTM                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PWM_HIBVT                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PWM_IMX1                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PWM_IMX27                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PWM_IMX_TPM                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PWM_IQS620A                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PWM_KEEMBAY                              policy<{'arm64': 'm'}>
+CONFIG_PWM_LP3943                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PWM_LPSS                                 policy<{'amd64': 'y'}>
+CONFIG_PWM_LPSS_PCI                             policy<{'amd64': 'y'}>
+CONFIG_PWM_LPSS_PLATFORM                        policy<{'amd64': 'y'}>
+CONFIG_PWM_MEDIATEK                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PWM_MESON                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PWM_MICROCHIP_CORE                       policy<{'riscv64': 'm'}>
+CONFIG_PWM_MTK_DISP                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PWM_NTXEC                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PWM_OMAP_DMTIMER                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PWM_PCA9685                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PWM_RCAR                                 policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PWM_RENESAS_TPU                          policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_PWM_ROCKCHIP                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PWM_RZ_MTU3                              policy<{'arm64': 'm', 'riscv64': '-'}>
+CONFIG_PWM_SAMSUNG                              policy<{'armhf': 'n'}>
+CONFIG_PWM_SIFIVE                               policy<{'riscv64': 'm'}>
+CONFIG_PWM_SL28CPLD                             policy<{'arm64': 'm'}>
+CONFIG_PWM_SPRD                                 policy<{'arm64': 'm'}>
+CONFIG_PWM_STM32                                policy<{'arm64': 'm'}>
+CONFIG_PWM_STM32_LP                             policy<{'arm64': 'm'}>
+CONFIG_PWM_STMPE                                policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PWM_SUN4I                                policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_PWM_SUNPLUS                              policy<{'armhf': 'm'}>
+CONFIG_PWM_SYSFS                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_PWM_TEGRA                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PWM_TIECAP                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PWM_TIEHRPWM                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_PWM_TWL                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PWM_TWL_LED                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_PWM_VISCONTI                             policy<{'arm64': 'm'}>
+CONFIG_PWM_XILINX                               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PWRSEQ_EMMC                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PWRSEQ_SD8787                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PWRSEQ_SIMPLE                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_PXA168_ETH                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCA7000                                  policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QCA7000_SPI                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QCA7000_UART                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QCM_DISPCC_2290                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCM_GCC_2290                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_A53PLL                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_A7PLL                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_AOSS_QMP                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_APCS_IPC                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_APR                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_BAM_DMA                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_BAM_DMUX                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_CLK_APCC_MSM8996                    policy<{'arm64': 'm'}>
+CONFIG_QCOM_CLK_APCS_MSM8916                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_CLK_APCS_SDX55                      policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_QCOM_CLK_RPM                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_CLK_RPMH                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_CLK_SMD_RPM                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_COINCELL                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_COMMAND_DB                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_CPR                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_EBI2                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_EMAC                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_QCOM_FALKOR_ERRATUM_1003                 policy<{'arm64': 'y'}>
+CONFIG_QCOM_FALKOR_ERRATUM_1009                 policy<{'arm64': 'y'}>
+CONFIG_QCOM_FALKOR_ERRATUM_E1041                policy<{'arm64': 'y'}>
+CONFIG_QCOM_FASTRPC                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_GDSC                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_GENI_SE                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_GPI_DMA                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_GSBI                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_HFPLL                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_HIDMA                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_QCOM_HIDMA_MGMT                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_QCOM_ICC_BWMON                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_INLINE_CRYPTO_ENGINE                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_IOMMU                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_IPA                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_IPCC                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_IRQ_COMBINER                        policy<{'arm64': 'y'}>
+CONFIG_QCOM_KRYO_L2_ACCESSORS                   policy<{'arm64': 'y'}>
+CONFIG_QCOM_L2_PMU                              policy<{'arm64': 'y'}>
+CONFIG_QCOM_L3_PMU                              policy<{'arm64': 'y'}>
+CONFIG_QCOM_LLCC                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_LMH                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_MDT_LOADER                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_MPM                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_OCMEM                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_PDC                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_PDR_HELPERS                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QCOM_PIL_INFO                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_PM8XXX_XOADC                        policy<{'armhf': 'm'}>
+CONFIG_QCOM_PMIC_GLINK                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QCOM_PMIC_PDCHARGER_ULOG                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QCOM_Q6V5_ADSP                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_Q6V5_COMMON                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_Q6V5_MSS                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_Q6V5_PAS                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_Q6V5_WCSS                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_QMI_HELPERS                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QCOM_QSEECOM                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_QSEECOM_UEFISECAPP                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_RAMP_CTRL                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_RMTFS_MEM                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_RPMCC                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_RPMH                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_RPMHPD                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_RPMPD                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_RPM_MASTER_STATS                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_RPROC_COMMON                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_SCM                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT           policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_QCOM_SMD_RPM                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_SMEM                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_SMEM_STATE                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_SMP2P                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_SMSM                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_SOCINFO                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_SPM                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_SPMI_ADC5                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QCOM_SPMI_ADC_TM5                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_SPMI_IADC                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QCOM_SPMI_RRADC                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_SPMI_TEMP_ALARM                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_SPMI_VADC                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QCOM_SSC_BLOCK_BUS                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_QCOM_STATS                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_SYSMON                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_TSENS                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_VADC_COMMON                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QCOM_WCNSS_CTRL                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCOM_WCNSS_PIL                           policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_QCOM_WDT                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCS_GCC_404                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCS_Q6SSTOP_404                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QCS_TURING_404                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QDIO                                     policy<{'s390x': 'm'}>
+CONFIG_QDU_ECPRICC_1000                         policy<{'arm64': 'm'}>
+CONFIG_QDU_GCC_1000                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_QED                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_QEDE                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QEDF                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QEDI                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QED_FCOE                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_QED_ISCSI                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_QED_LL2                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_QED_OOO                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_QED_RDMA                                 policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_QED_SRIOV                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_QETH                                     policy<{'s390x': 'm'}>
+CONFIG_QETH_L2                                  policy<{'s390x': 'm'}>
+CONFIG_QETH_L3                                  policy<{'s390x': 'm'}>
+CONFIG_QE_GPIO                                  policy<{'ppc64el': 'y'}>
+CONFIG_QE_TDM                                   policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_QE_USB                                   policy<{'ppc64el': 'y'}>
+CONFIG_QFMT_V1                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_QFMT_V2                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_QLA3XXX                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_QLCNIC                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_QLCNIC_DCB                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_QLCNIC_HWMON                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_QLCNIC_SRIOV                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_QNX4FS_FS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_QNX6FS_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_QNX6FS_FS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_QORIQ_CPUFREQ                            policy<{'arm64': 'm'}>
+CONFIG_QORIQ_THERMAL                            policy<{'arm64': 'm'}>
+CONFIG_QRTR                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_QRTR_MHI                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QRTR_SMD                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QRTR_TUN                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QSEMI_PHY                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_QTNFMAC                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QTNFMAC_PCIE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_QUEUED_RWLOCKS                           policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_QUEUED_SPINLOCKS                         policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_QUICC_ENGINE                             policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_QUOTA                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_QUOTACTL                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_QUOTA_DEBUG                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_QUOTA_NETLINK_INTERFACE                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_QUOTA_TREE                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_R6040                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_R8169                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_R8169_LEDS                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_R8712U                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RADIO_ADAPTERS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RADIO_MAXIRADIO                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RADIO_SAA7706H                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RADIO_SHARK                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RADIO_SHARK2                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RADIO_SI470X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RADIO_SI4713                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RADIO_SI476X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RADIO_TEA575X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RADIO_TEA5764                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RADIO_TEF6862                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RADIO_WL1273                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RADIO_WL128X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RAID6_PQ                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_RAID6_PQ_BENCHMARK                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RAID_ATTRS                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_RANDOM32_SELFTEST                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_RANDOMIZE_BASE                           policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RANDOMIZE_KSTACK_OFFSET                  policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT          policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_RANDOMIZE_MEMORY                         policy<{'amd64': 'y'}>
+CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING        policy<{'amd64': '0xa'}>
+CONFIG_RANDOMIZE_MODULE_REGION_FULL             policy<{'arm64': 'y'}>
+CONFIG_RANDOM_KMALLOC_CACHES                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RANDSTRUCT_NONE                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RAPIDIO                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_RAPIDIO_CHMAN                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RAPIDIO_CPS_GEN2                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RAPIDIO_CPS_XX                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RAPIDIO_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_RAPIDIO_DISC_TIMEOUT                     policy<{'amd64': '30', 'arm64': '30', 'armhf': '30', 'ppc64el': '30', 'riscv64': '30'}>
+CONFIG_RAPIDIO_DMA_ENGINE                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_RAPIDIO_ENUM_BASIC                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RAPIDIO_MPORT_CDEV                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RAPIDIO_RXS_GEN3                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RAPIDIO_TSI721                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RAS                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RAS_CEC                                  policy<{'amd64': 'y'}>
+CONFIG_RAS_CEC_DEBUG                            policy<{'amd64': 'n'}>
+CONFIG_RATIONAL                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RAVB                                     policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RAVE_SP_CORE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_RAVE_SP_WATCHDOG                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RBTREE_TEST                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_RCAR_DMAC                                policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RCAR_GEN3_THERMAL                        policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RCAR_GYRO_ADC                            policy<{'armhf': 'm'}>
+CONFIG_RCAR_REMOTEPROC                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RCAR_THERMAL                             policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RCU_CPU_STALL_CPUTIME                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RCU_CPU_STALL_TIMEOUT                    policy<{'amd64': '60', 'arm64': '60', 'armhf': '60', 'ppc64el': '60', 'riscv64': '60', 's390x': '60'}>
+CONFIG_RCU_EQS_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_RCU_EXPERT                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_RCU_EXP_CPU_STALL_TIMEOUT                policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0', 's390x': '0'}>
+CONFIG_RCU_NEED_SEGCBLIST                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RCU_REF_SCALE_TEST                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_RCU_SCALE_TEST                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_RCU_STALL_COMMON                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RCU_TORTURE_TEST                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_RCU_TRACE                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_RC_ATI_REMOTE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RC_CORE                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_RC_DECODERS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RC_DEVICES                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RC_LOOPBACK                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RC_MAP                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RC_XBOX_DVD                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RDA_INTC                                 policy<{'armhf': 'y'}>
+CONFIG_RDA_TIMER                                policy<{'armhf': 'y'}>
+CONFIG_RDMA_RXE                                 policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_RDMA_SIW                                 policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_RDS                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_RDS_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_RDS_RDMA                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_RDS_TCP                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_RD_BZIP2                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RD_GZIP                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RD_LZ4                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RD_LZMA                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RD_LZO                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RD_XZ                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RD_ZSTD                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_READABLE_ASM                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_READ_ONLY_THP_FOR_FS                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_REALTEK_AUTOPM                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_REALTEK_PHY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_REBOOT_MODE                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REED_SOLOMON                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REED_SOLOMON_DEC16                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_REED_SOLOMON_DEC8                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_REED_SOLOMON_ENC8                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_REED_SOLOMON_TEST                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_REGMAP                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_REGMAP_AC97                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_REGMAP_I2C                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_REGMAP_I3C                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGMAP_IRQ                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_REGMAP_MMIO                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_REGMAP_SCCB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGMAP_SLIMBUS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGMAP_SOUNDWIRE                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGMAP_SOUNDWIRE_MBQ                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGMAP_SPI                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_REGMAP_SPI_AVMM                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGMAP_SPMI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGMAP_W1                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_REGULATOR_88PG86X                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_88PM800                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_88PM8607                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_AAT2870                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_ACT8865                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_ACT8945A                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_AD5398                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_ANATOP                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_REGULATOR_ARIZONA_LDO1                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_ARIZONA_MICSUPP                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_ARM_SCMI                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_REGULATOR_AS3711                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_AS3722                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_ATC260X                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_AW37503                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_AXP20X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_BCM590XX                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_BD71815                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_BD71828                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_BD718XX                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_BD9571MWV                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_BD957XMUF                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_CPCAP                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_CROS_EC                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_REGULATOR_DA903X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_DA9052                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_DA9055                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_DA9062                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_DA9063                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_DA9121                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_DA9210                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_DA9211                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_DEBUG                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_REGULATOR_FAN53555                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_FAN53880                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_GPIO                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_HI6421                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_HI6421V530                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_HI6421V600                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_HI655X                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_REGULATOR_ISL6271A                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_ISL9305                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_LM363X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_LOCHNAGAR                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_LP3971                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_LP3972                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_LP872X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_LP873X                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_LP8755                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_LP87565                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_LP8788                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_LTC3589                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_LTC3676                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_MAX14577                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_MAX1586                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_MAX20086                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MAX20411                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MAX5970                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MAX77503                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MAX77541                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MAX77620                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MAX77650                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MAX77686                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MAX77693                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_MAX77802                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MAX77826                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_MAX77857                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MAX8649                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_MAX8660                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_MAX8893                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_MAX8907                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MAX8925                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_MAX8952                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_MAX8973                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MAX8997                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_MAX8998                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_MC13783                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MC13892                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MC13XXX_CORE                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MCP16502                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MP5416                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MP8859                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_MP886X                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MPQ7920                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MT6311                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_MT6315                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MT6323                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MT6331                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MT6332                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MT6357                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MT6358                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MT6359                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MT6360                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MT6370                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_MT6380                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_REGULATOR_MT6397                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_NETLINK_EVENTS                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_REGULATOR_PALMAS                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_PBIAS                          policy<{'armhf': 'm'}>
+CONFIG_REGULATOR_PCA9450                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_PCAP                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_PCF50633                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_PF8X00                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_PFUZE100                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_PV88060                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_PV88080                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_PV88090                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_PWM                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_QCOM_LABIBB                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_QCOM_REFGEN                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_REGULATOR_QCOM_RPM                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_REGULATOR_QCOM_RPMH                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_REGULATOR_QCOM_SMD_RPM                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_REGULATOR_QCOM_SPMI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_QCOM_USB_VBUS                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_RAA215300                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_RASPBERRYPI_TOUCHSCREEN_ATTINY policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_RC5T583                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_RK808                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_RN5T618                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_ROHM                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_RT4801                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_RT4803                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_RT4831                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_RT5033                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_RT5120                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_RT5190A                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_RT5739                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_RT5759                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_RT6160                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_RT6190                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_RT6245                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_RTMV20                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_RTQ2134                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_RTQ2208                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_RTQ6752                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_S2MPA01                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_S2MPS11                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_S5M8767                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_SC2731                         policy<{'arm64': 'm'}>
+CONFIG_REGULATOR_SKY81452                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_SLG51000                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_STM32_BOOSTER                  policy<{'arm64': 'm'}>
+CONFIG_REGULATOR_STM32_PWR                      policy<{'arm64': 'y'}>
+CONFIG_REGULATOR_STM32_VREFBUF                  policy<{'arm64': 'm'}>
+CONFIG_REGULATOR_STPMIC1                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_SY7636A                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_SY8106A                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_SY8824X                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_SY8827N                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_TI_ABB                         policy<{'armhf': 'y'}>
+CONFIG_REGULATOR_TPS51632                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_TPS6105X                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_TPS62360                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_TPS6286X                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_TPS6287X                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_TPS65023                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_TPS6507X                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_TPS65086                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_TPS65090                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_TPS65132                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_TPS65218                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_TPS65219                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_TPS6524X                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_TPS6586X                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_TPS65910                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_TPS65912                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_TPS6594                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_TPS68470                       policy<{'amd64': 'm'}>
+CONFIG_REGULATOR_USERSPACE_CONSUMER             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_VCTRL                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REGULATOR_VEXPRESS                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_REGULATOR_VIRTUAL_CONSUMER               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_VQMMC_IPQ4019                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_REGULATOR_WM831X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_WM8350                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_WM8400                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_REGULATOR_WM8994                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_REISERFS_CHECK                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_REISERFS_FS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_REISERFS_FS_POSIX_ACL                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_REISERFS_FS_SECURITY                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_REISERFS_FS_XATTR                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_REISERFS_PROC_INFO                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_RELAY                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RELOCATABLE                              policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RELOCATABLE_TEST                         policy<{'ppc64el': 'n'}>
+CONFIG_REMOTEPROC                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_REMOTEPROC_CDEV                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_REMOTE_TARGET                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_RENESAS_DMA                              policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_RENESAS_ETHER_SWITCH                     policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RENESAS_GEN4_PTP                         policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RENESAS_INTC_IRQPIN                      policy<{'armhf': 'y'}>
+CONFIG_RENESAS_IRQC                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_RENESAS_OSTM                             policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_RENESAS_PHY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_RENESAS_RPCIF                            policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RENESAS_RZA1_IRQC                        policy<{'armhf': 'y'}>
+CONFIG_RENESAS_RZAWDT                           policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RENESAS_RZG2LWDT                         policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RENESAS_RZG2L_IRQC                       policy<{'arm64': 'y', 'riscv64': '-'}>
+CONFIG_RENESAS_RZN1WDT                          policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RENESAS_USB_DMAC                         policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RENESAS_WDT                              policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RESET_A10SR                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RESET_ATTACK_MITIGATION                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_RESET_BERLIN                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_RESET_CONTROLLER                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_RESET_HISI                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_RESET_IMX7                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_RESET_MCHP_SPARX5                        policy<{'arm64': 'y'}>
+CONFIG_RESET_MESON                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_RESET_MESON_AUDIO_ARB                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RESET_NPCM                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_RESET_NUVOTON_MA35D1                     policy<{'arm64': 'y'}>
+CONFIG_RESET_POLARFIRE_SOC                      policy<{'riscv64': 'y'}>
+CONFIG_RESET_QCOM_AOSS                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_RESET_QCOM_PDC                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RESET_RZG2L_USBPHY_CTRL                  policy<{'arm64': 'y', 'riscv64': '-'}>
+CONFIG_RESET_SCMI                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RESET_SIMPLE                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RESET_SOCFPGA                            policy<{'armhf': 'y'}>
+CONFIG_RESET_STARFIVE_JH7100                    policy<{'riscv64': 'n'}>
+CONFIG_RESET_STARFIVE_JH7110                    policy<{'riscv64': 'y'}>
+CONFIG_RESET_STARFIVE_JH71X0                    policy<{'riscv64': 'y'}>
+CONFIG_RESET_SUNPLUS                            policy<{'armhf': 'y'}>
+CONFIG_RESET_SUNXI                              policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_RESET_TEGRA_BPMP                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_RESET_TI_SCI                             policy<{'arm64': 'm'}>
+CONFIG_RESET_TI_SYSCON                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RESET_TI_TPS380X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RETHOOK                                  policy<{'amd64': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RETHUNK                                  policy<{'amd64': 'y'}>
+CONFIG_RETPOLINE                                policy<{'amd64': 'y'}>
+CONFIG_RETU_WATCHDOG                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RFD77402                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RFD_FTL                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RFKILL                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_RFKILL_GPIO                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RFKILL_INPUT                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RFKILL_LEDS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RFS_ACCEL                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RICHTEK_RTQ6056                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RING_BUFFER                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RING_BUFFER_BENCHMARK                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_RING_BUFFER_STARTUP_TEST                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_RING_BUFFER_VALIDATE_TIME_DELTAS         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_RIONET                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RIONET_RX_SIZE                           policy<{'amd64': '128', 'arm64': '128', 'armhf': '128', 'ppc64el': '128', 'riscv64': '128'}>
+CONFIG_RIONET_TX_SIZE                           policy<{'amd64': '128', 'arm64': '128', 'armhf': '128', 'ppc64el': '128', 'riscv64': '128'}>
+CONFIG_RISCV                                    policy<{'riscv64': 'y'}>
+CONFIG_RISCV_ALTERNATIVE                        policy<{'riscv64': 'y'}>
+CONFIG_RISCV_ALTERNATIVE_EARLY                  policy<{'riscv64': 'y'}>
+CONFIG_RISCV_BOOT_SPINWAIT                      policy<{'riscv64': 'n'}>
+CONFIG_RISCV_DMA_NONCOHERENT                    policy<{'riscv64': 'y'}>
+CONFIG_RISCV_INTC                               policy<{'riscv64': 'y'}>
+CONFIG_RISCV_ISA_C                              policy<{'riscv64': 'y'}>
+CONFIG_RISCV_ISA_FALLBACK                       policy<{'riscv64': 'y'}>
+CONFIG_RISCV_ISA_SVNAPOT                        policy<{'riscv64': 'y'}>
+CONFIG_RISCV_ISA_SVPBMT                         policy<{'riscv64': 'n'}>
+CONFIG_RISCV_ISA_V                              policy<{'riscv64': 'y'}>
+CONFIG_RISCV_ISA_V_DEFAULT_ENABLE               policy<{'riscv64': 'y'}>
+CONFIG_RISCV_ISA_V_PREEMPTIVE                   policy<{'riscv64': 'y'}>
+CONFIG_RISCV_ISA_V_UCOPY_THRESHOLD              policy<{'riscv64': '768'}>
+CONFIG_RISCV_ISA_ZBB                            policy<{'riscv64': 'y'}>
+CONFIG_RISCV_ISA_ZICBOM                         policy<{'riscv64': 'y'}>
+CONFIG_RISCV_ISA_ZICBOZ                         policy<{'riscv64': 'y'}>
+CONFIG_RISCV_MISALIGNED                         policy<{'riscv64': 'y'}>
+CONFIG_RISCV_NONSTANDARD_CACHE_OPS              policy<{'riscv64': 'y'}>
+CONFIG_RISCV_PMU                                policy<{'riscv64': 'y'}>
+CONFIG_RISCV_PMU_LEGACY                         policy<{'riscv64': 'y'}>
+CONFIG_RISCV_PMU_SBI                            policy<{'riscv64': 'y'}>
+CONFIG_RISCV_SBI                                policy<{'riscv64': 'y'}>
+CONFIG_RISCV_SBI_CPUIDLE                        policy<{'riscv64': 'y'}>
+CONFIG_RISCV_SBI_V01                            policy<{'riscv64': 'n'}>
+CONFIG_RISCV_TIMER                              policy<{'riscv64': 'y'}>
+CONFIG_RISCV_USE_LINKER_RELAXATION              policy<{'riscv64': 'y'}>
+CONFIG_RMI4_2D_SENSOR                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RMI4_CORE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_RMI4_F03                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_RMI4_F03_SERIO                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RMI4_F11                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_RMI4_F12                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_RMI4_F30                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_RMI4_F34                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_RMI4_F3A                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_RMI4_F54                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RMI4_F55                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_RMI4_I2C                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RMI4_SMB                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RMI4_SPI                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RMNET                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RN5T618_ADC                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RN5T618_POWER                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RN5T618_WATCHDOG                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ROCKCHIP_ANALOGIX_DP                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKCHIP_CDN_DP                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKCHIP_DTPM                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ROCKCHIP_DW_HDMI                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKCHIP_DW_MIPI_DSI                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKCHIP_ERRATUM_3588001                 policy<{'arm64': 'y'}>
+CONFIG_ROCKCHIP_GRF                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKCHIP_INNO_HDMI                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKCHIP_IODOMAIN                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ROCKCHIP_IOMMU                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKCHIP_LVDS                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKCHIP_MBOX                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKCHIP_PHY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ROCKCHIP_PM_DOMAINS                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKCHIP_RGB                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKCHIP_RK3066_HDMI                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKCHIP_SARADC                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ROCKCHIP_THERMAL                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_ROCKCHIP_TIMER                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKCHIP_VOP                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKCHIP_VOP2                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_ROCKER                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RODATA_FULL_DEFAULT_ENABLED              policy<{'arm64': 'y'}>
+CONFIG_ROHM_BM1390                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ROHM_BU27008                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ROHM_BU27034                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ROMFS_BACKED_BY_BLOCK                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ROMFS_BACKED_BY_BOTH                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ROMFS_BACKED_BY_MTD                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_ROMFS_FS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ROMFS_ON_BLOCK                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ROSE                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RPCSEC_GSS_KRB5                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA1        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_AES_SHA2        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RPCSEC_GSS_KRB5_ENCTYPES_CAMELLIA        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RPMSG                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RPMSG_CHAR                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RPMSG_CTRL                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RPMSG_MTK_SCP                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RPMSG_NS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RPMSG_QCOM_GLINK                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RPMSG_QCOM_GLINK_RPM                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RPMSG_QCOM_GLINK_SMEM                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RPMSG_QCOM_SMD                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RPMSG_TTY                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RPMSG_VIRTIO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_RPMSG_WWAN_CTRL                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RPR0521                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RPS                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RSEQ                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RSI_91X                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RSI_COEX                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RSI_DEBUGFS                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_RSI_SDIO                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RSI_USB                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RST_RCAR                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_RT2400PCI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RT2500PCI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RT2500USB                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RT2800PCI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RT2800PCI_RT3290                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RT2800PCI_RT33XX                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RT2800PCI_RT35XX                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RT2800PCI_RT53XX                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RT2800USB                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RT2800USB_RT33XX                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RT2800USB_RT3573                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RT2800USB_RT35XX                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RT2800USB_RT53XX                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RT2800USB_RT55XX                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RT2800USB_UNKNOWN                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RT2800_LIB                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RT2800_LIB_MMIO                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RT2X00                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RT2X00_DEBUG                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_RT2X00_LIB                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RT2X00_LIB_CRYPTO                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RT2X00_LIB_DEBUGFS                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_RT2X00_LIB_FIRMWARE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RT2X00_LIB_LEDS                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RT2X00_LIB_MMIO                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RT2X00_LIB_PCI                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RT2X00_LIB_USB                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RT61PCI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RT73USB                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTAS_ERROR_LOGGING                       policy<{'ppc64el': 'y'}>
+CONFIG_RTAS_FLASH                               policy<{'ppc64el': 'm'}>
+CONFIG_RTAS_PROC                                policy<{'ppc64el': 'y'}>
+CONFIG_RTC_CLASS                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_RTC_DRV_88PM80X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_88PM860X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_ABB5ZES3                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_ABEOZ9                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_ABX80X                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_ARMADA38X                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RTC_DRV_AS3722                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_ASPEED                           policy<{'armhf': 'm'}>
+CONFIG_RTC_DRV_BBNSM                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RTC_DRV_BD70528                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_BQ32K                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_CADENCE                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_CPCAP                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_CROS_EC                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RTC_DRV_DA9052                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DA9055                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DA9063                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS1286                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS1302                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS1305                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS1307                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS1307_CENTURY                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_DRV_DS1343                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS1347                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS1374                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS1374_WDT                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_DRV_DS1390                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS1511                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS1553                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS1672                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS1685                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_DRV_DS1685_FAMILY                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS1689                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_RTC_DRV_DS17285                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_RTC_DRV_DS1742                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS17485                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_RTC_DRV_DS17885                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_RTC_DRV_DS2404                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS3232                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_DS3232_HWMON                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_DRV_EM3027                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_FM3130                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_FSL_FTM_ALARM                    policy<{'arm64': 'm'}>
+CONFIG_RTC_DRV_FTRTC010                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_GENERIC                          policy<{'ppc64el': 'y'}>
+CONFIG_RTC_DRV_GOLDFISH                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'y'}>
+CONFIG_RTC_DRV_HID_SENSOR_TIME                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_HYM8563                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_IMXDI                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RTC_DRV_IMX_SC                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RTC_DRV_ISL12022                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_ISL12026                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_ISL1208                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_LP8788                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_M41T80                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_M41T80_WDT                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_DRV_M41T93                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_M41T94                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_M48T35                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_M48T59                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_M48T86                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_MA35D1                           policy<{'arm64': 'm'}>
+CONFIG_RTC_DRV_MAX31335                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_MAX6900                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_MAX6902                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_MAX6916                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_MAX77686                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_MAX8907                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_MAX8925                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_MAX8997                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_MAX8998                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_MC13XXX                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_MCP795                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_MESON                            policy<{'armhf': 'm'}>
+CONFIG_RTC_DRV_MESON_VRTC                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RTC_DRV_MSC313                           policy<{'armhf': 'm'}>
+CONFIG_RTC_DRV_MSM6242                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_MT2712                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RTC_DRV_MT6397                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_MT7622                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RTC_DRV_MV                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_RTC_DRV_MXC                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RTC_DRV_MXC_V2                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RTC_DRV_NCT3018Y                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_NTXEC                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_OMAP                             policy<{'armhf': 'y'}>
+CONFIG_RTC_DRV_OPAL                             policy<{'ppc64el': 'y'}>
+CONFIG_RTC_DRV_OPTEE                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RTC_DRV_PALMAS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_PCAP                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_PCF2123                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_PCF2127                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_PCF50633                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_PCF85063                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_PCF8523                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_PCF85363                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_PCF8563                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_PCF8583                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_PL030                            policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_PL031                            policy<{'arm64': 'm', 'armhf': 'y', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_PM8XXX                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RTC_DRV_POLARFIRE_SOC                    policy<{'riscv64': 'm'}>
+CONFIG_RTC_DRV_R7301                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_R9701                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RC5T583                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RC5T619                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RK808                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RP5C01                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RS5C348                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RS5C372                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RTD119X                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_RTC_DRV_RV3028                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RV3029C2                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RV3029_HWMON                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_DRV_RV3032                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RV8803                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RX4581                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RX6110                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RX8010                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RX8025                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RX8581                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_RZN1                             policy<{'armhf': 'm'}>
+CONFIG_RTC_DRV_S35390A                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_S3C                              policy<{'armhf': 'n'}>
+CONFIG_RTC_DRV_S5M                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_SC27XX                           policy<{'arm64': 'm'}>
+CONFIG_RTC_DRV_SD3078                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_SH                               policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_SNVS                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RTC_DRV_SSD202D                          policy<{'armhf': 'm'}>
+CONFIG_RTC_DRV_STK17TA8                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_STM32                            policy<{'arm64': 'm'}>
+CONFIG_RTC_DRV_SUN6I                            policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_RTC_DRV_SUNPLUS                          policy<{'armhf': 'm'}>
+CONFIG_RTC_DRV_TEGRA                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_RTC_DRV_TEST                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_RTC_DRV_TI_K3                            policy<{'arm64': 'm'}>
+CONFIG_RTC_DRV_TPS6586X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_TPS65910                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_TPS6594                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_WILCO_EC                         policy<{'amd64': 'm'}>
+CONFIG_RTC_DRV_WM831X                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_WM8350                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_X1205                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_DRV_XGENE                            policy<{'arm64': 'y'}>
+CONFIG_RTC_DRV_ZYNQMP                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTC_HCTOSYS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_HCTOSYS_DEVICE                       policy<{'amd64': '"rtc0"', 'arm64': '"rtc0"', 'armhf': '"rtc0"', 'ppc64el': '"rtc0"', 'riscv64': '"rtc0"'}>
+CONFIG_RTC_I2C_AND_SPI                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_INTF_DEV                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_INTF_DEV_UIE_EMUL                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_RTC_INTF_PROC                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_INTF_SYSFS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_LIB                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_MC146818_LIB                         policy<{'amd64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_RTC_NVMEM                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_SYSTOHC                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTC_SYSTOHC_DEVICE                       policy<{'amd64': '"rtc0"', 'arm64': '"rtc0"', 'armhf': '"rtc0"', 'ppc64el': '"rtc0"', 'riscv64': '"rtc0"'}>
+CONFIG_RTD119X_WATCHDOG                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_RTL8180                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8187                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8187_LEDS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTL8188EE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8192CE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8192CU                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8192C_COMMON                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8192DE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8192E                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8192EE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8192SE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8723AE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8723BE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8723BS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8723_COMMON                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8821AE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8XXXU                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL8XXXU_UNTESTED                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTLBTCOEXIST                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTLLIB                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTLLIB_CRYPTO_CCMP                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTLLIB_CRYPTO_TKIP                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTLLIB_CRYPTO_WEP                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTLWIFI                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTLWIFI_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_RTLWIFI_PCI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTLWIFI_USB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTL_CARDS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTS5208                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_RTW88                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8723D                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8723DE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8723DS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8723DU                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8821C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8821CE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8821CS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8821CU                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8822B                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8822BE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8822BS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8822BU                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8822C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8822CE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8822CS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_8822CU                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_CORE                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_DEBUG                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTW88_DEBUGFS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTW88_PCI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_SDIO                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW88_USB                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW89                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW89_8851B                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW89_8851BE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW89_8852A                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW89_8852AE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW89_8852B                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW89_8852BE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW89_8852C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW89_8852CE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW89_CORE                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RTW89_DEBUG                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTW89_DEBUGFS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTW89_DEBUGMSG                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_RTW89_PCI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_RT_MUTEXES                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RUNTIME_KERNEL_TESTING_MENU              policy<{'riscv64': 'n'}>
+CONFIG_RUNTIME_TESTING_MENU                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RUST                                     policy<{'amd64': 'y'}>
+CONFIG_RUSTC_VERSION_TEXT                       policy<{'amd64': '"rustc 1.75.0 (82e1608df 2023-12-21) (built from a source tarball)"'}>
+CONFIG_RUST_BUILD_ASSERT_ALLOW                  policy<{'amd64': 'n'}>
+CONFIG_RUST_DEBUG_ASSERTIONS                    policy<{'amd64': 'n'}>
+CONFIG_RUST_IS_AVAILABLE                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RUST_OVERFLOW_CHECKS                     policy<{'amd64': 'y'}>
+CONFIG_RUST_PHYLIB_ABSTRACTIONS                 policy<{'amd64': 'y'}>
+CONFIG_RV                                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RV_MON_WWNR                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RV_REACTORS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RV_REACT_PANIC                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RV_REACT_PRINTK                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RWSEM_SPIN_ON_OWNER                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RXKAD                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_RXPERF                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_RZG2L_ADC                                policy<{'arm64': 'm', 'riscv64': '-'}>
+CONFIG_RZG2L_THERMAL                            policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_RZN1_DMAMUX                              policy<{'armhf': 'm'}>
+CONFIG_RZ_DMAC                                  policy<{'arm64': 'm', 'riscv64': '-'}>
+CONFIG_RZ_MTU3                                  policy<{'arm64': 'y', 'riscv64': '-'}>
+CONFIG_RZ_MTU3_CNT                              policy<{'arm64': 'm'}>
+CONFIG_S2IO                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_S390                                     policy<{'s390x': 'y'}>
+CONFIG_S390_GUEST                               policy<{'s390x': 'y'}>
+CONFIG_S390_HYPFS                               policy<{'s390x': 'y'}>
+CONFIG_S390_HYPFS_FS                            policy<{'s390x': 'y'}>
+CONFIG_S390_IOMMU                               policy<{'s390x': 'y'}>
+CONFIG_S390_PRNG                                policy<{'s390x': 'm'}>
+CONFIG_S390_TAPE                                policy<{'s390x': 'm'}>
+CONFIG_S390_TAPE_34XX                           policy<{'s390x': 'm'}>
+CONFIG_S390_TAPE_3590                           policy<{'s390x': 'm'}>
+CONFIG_S390_VMUR                                policy<{'s390x': 'm'}>
+CONFIG_S3C2410_WATCHDOG                         policy<{'armhf': 'n'}>
+CONFIG_S5P_DEV_MFC                              policy<{'armhf': 'y'}>
+CONFIG_SAMPLES                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SAMPLES_RUST                             policy<{'amd64': 'n'}>
+CONFIG_SAMPLE_AUXDISPLAY                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SAMPLE_CONFIGFS                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SAMPLE_FPROBE                            policy<{'amd64': 'n', 'riscv64': '-', 's390x': 'n'}>
+CONFIG_SAMPLE_FTRACE_DIRECT                     policy<{'amd64': 'm', 'arm64': 'n', 's390x': 'n'}>
+CONFIG_SAMPLE_FTRACE_DIRECT_MULTI               policy<{'amd64': 'n', 'arm64': 'n', 's390x': 'n'}>
+CONFIG_SAMPLE_FTRACE_OPS                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': '-', 's390x': 'n'}>
+CONFIG_SAMPLE_HW_BREAKPOINT                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n'}>
+CONFIG_SAMPLE_KDB                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SAMPLE_KFIFO                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SAMPLE_KOBJECT                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SAMPLE_KPROBES                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SAMPLE_LIVEPATCH                         policy<{'amd64': 'n', 'ppc64el': 'n', 's390x': 'n'}>
+CONFIG_SAMPLE_QMI_CLIENT                        policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_SAMPLE_RPMSG_CLIENT                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_SAMPLE_TRACE_ARRAY                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SAMPLE_TRACE_CUSTOM_EVENTS               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SAMPLE_TRACE_EVENTS                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SAMPLE_VFIO_MDEV_MBOCHS                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SAMPLE_VFIO_MDEV_MDPY                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SAMPLE_VFIO_MDEV_MDPY_FB                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SAMPLE_VFIO_MDEV_MTTY                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SAMPLE_WATCHDOG                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SAMSUNG_LAPTOP                           policy<{'amd64': 'm'}>
+CONFIG_SAMSUNG_MC                               policy<{'armhf': 'y'}>
+CONFIG_SAMSUNG_Q10                              policy<{'amd64': 'm'}>
+CONFIG_SATA_ACARD_AHCI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_AHCI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_AHCI_SEATTLE                        policy<{'arm64': 'm'}>
+CONFIG_SATA_DWC                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_DWC_OLD_DMA                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SATA_HOST                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SATA_INIC162X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_MOBILE_LPM_POLICY                   policy<{'amd64': '3', 'arm64': '3', 'armhf': '3', 'ppc64el': '3', 'riscv64': '3'}>
+CONFIG_SATA_MV                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_NV                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_PMP                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SATA_PROMISE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_QSTOR                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_RCAR                                policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SATA_SIL                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_SIL24                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_SIS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_SVW                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_SX4                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_ULI                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_VIA                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_VITESSE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SATA_ZPODD                               policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_SA_GCC_8775P                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SA_GPUCC_8775P                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SBC_EPX_C3_WATCHDOG                      policy<{'amd64': 'm'}>
+CONFIG_SBC_FITPC2_WATCHDOG                      policy<{'amd64': 'm'}>
+CONFIG_SBITMAP                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SBP_TARGET                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SC1200_WDT                               policy<{'amd64': 'm'}>
+CONFIG_SC27XX_ADC                               policy<{'arm64': 'm'}>
+CONFIG_SC92031                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCA3000                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCA3300                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCD30_CORE                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCD30_I2C                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCD30_SERIAL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCD4X                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCF_TORTURE_TEST                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SCHEDSTATS                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCHED_AUTOGROUP                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCHED_CLUSTER                            policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_SCHED_CORE                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_SCHED_DEBUG                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCHED_HRTICK                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCHED_INFO                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCHED_MC                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCHED_MC_PRIO                            policy<{'amd64': 'y'}>
+CONFIG_SCHED_MM_CID                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCHED_OMIT_FRAME_POINTER                 policy<{'amd64': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_SCHED_SMT                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_SCHED_STACK_END_CHECK                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCHED_THERMAL_PRESSURE                   policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SCHED_TOPOLOGY                           policy<{'s390x': 'y'}>
+CONFIG_SCHED_TRACER                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCLP_CONSOLE                             policy<{'s390x': 'y'}>
+CONFIG_SCLP_TTY                                 policy<{'s390x': 'y'}>
+CONFIG_SCLP_VT220_CONSOLE                       policy<{'s390x': 'y'}>
+CONFIG_SCLP_VT220_TTY                           policy<{'s390x': 'y'}>
+CONFIG_SCM_BLOCK                                policy<{'s390x': 'm'}>
+CONFIG_SCM_BUS                                  policy<{'s390x': 'y'}>
+CONFIG_SCOM_DEBUGFS                             policy<{'ppc64el': 'y'}>
+CONFIG_SCREEN_INFO                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_SCSI                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCSI_3W_9XXX                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_3W_SAS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_AACRAID                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_ACARD                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCSI_ADVANSYS                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCSI_AHA1740                             policy<{'amd64': 'm'}>
+CONFIG_SCSI_AIC79XX                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCSI_AIC7XXX                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCSI_AIC94XX                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCSI_AM53C974                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_ARCMSR                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_BFA_FC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_BNX2X_FCOE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_BNX2_ISCSI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_BUSLOGIC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCSI_CHELSIO_FCOE                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_COMMON                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCSI_CONSTANTS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCSI_CXGB3_ISCSI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_CXGB4_ISCSI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_DC395x                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCSI_DEBUG                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SCSI_DH                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCSI_DH_ALUA                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SCSI_DH_EMC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SCSI_DH_HP_SW                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SCSI_DH_RDAC                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SCSI_DMA                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCSI_DMX3191D                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCSI_EFCT                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_ENCLOSURE                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCSI_ESAS2R                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_FC_ATTRS                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SCSI_FDOMAIN                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCSI_FDOMAIN_PCI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCSI_FLASHPOINT                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SCSI_HISI_SAS                            policy<{'arm64': 'm'}>
+CONFIG_SCSI_HISI_SAS_DEBUGFS_DEFAULT_ENABLE     policy<{'arm64': 'n'}>
+CONFIG_SCSI_HISI_SAS_PCI                        policy<{'arm64': 'm'}>
+CONFIG_SCSI_HPSA                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_HPTIOP                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_IBMVFC                              policy<{'ppc64el': 'm'}>
+CONFIG_SCSI_IBMVFC_TRACE                        policy<{'ppc64el': 'y'}>
+CONFIG_SCSI_IBMVSCSI                            policy<{'ppc64el': 'm'}>
+CONFIG_SCSI_IBMVSCSIS                           policy<{'ppc64el': 'm'}>
+CONFIG_SCSI_IMM                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCSI_INIA100                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCSI_INITIO                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCSI_IPR                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_IPS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCSI_ISCI                                policy<{'amd64': 'm'}>
+CONFIG_SCSI_ISCSI_ATTRS                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SCSI_IZIP_SLOW_CTR                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SCSI_LOGGING                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCSI_LOWLEVEL                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCSI_LOWLEVEL_PCMCIA                     policy<{'amd64': 'y'}>
+CONFIG_SCSI_LPFC                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCSI_LPFC_DEBUG_FS                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SCSI_MOD                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCSI_MPI3MR                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_MPT2SAS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SCSI_MPT2SAS_MAX_SGE                     policy<{'amd64': '128', 'arm64': '128', 'armhf': '128', 'ppc64el': '128', 'riscv64': '128', 's390x': '128'}>
+CONFIG_SCSI_MPT3SAS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SCSI_MPT3SAS_MAX_SGE                     policy<{'amd64': '128', 'arm64': '128', 'armhf': '128', 'ppc64el': '128', 'riscv64': '128', 's390x': '128'}>
+CONFIG_SCSI_MVSAS                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCSI_MVSAS_DEBUG                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_SCSI_MVSAS_TASKLET                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_SCSI_MVUMI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_MYRB                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_MYRS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCSI_NETLINK                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCSI_NSP32                               policy<{'armhf': 'm'}>
+CONFIG_SCSI_PM8001                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_PMCRAID                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_PPA                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCSI_PROC_FS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCSI_QLA_FC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SCSI_QLA_ISCSI                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_QLOGIC_1280                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_SAS_ATA                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SCSI_SAS_ATTRS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SCSI_SAS_HOST_SMP                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCSI_SAS_LIBSAS                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SCSI_SCAN_ASYNC                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCSI_SIM710                              policy<{'amd64': 'm'}>
+CONFIG_SCSI_SMARTPQI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCSI_SNIC                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_SNIC_DEBUG_FS                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_SCSI_SPI_ATTRS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SCSI_SRP_ATTRS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'y', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SCSI_STEX                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_SYM53C8XX_2                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS              policy<{'amd64': '16', 'arm64': '16', 'armhf': '16', 'ppc64el': '16', 'riscv64': '16'}>
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE       policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'ppc64el': '1', 'riscv64': '1'}>
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS                  policy<{'amd64': '64', 'arm64': '64', 'armhf': '64', 'ppc64el': '64', 'riscv64': '64'}>
+CONFIG_SCSI_SYM53C8XX_MMIO                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SCSI_UFSHCD                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCSI_UFSHCD_PCI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCSI_UFSHCD_PLATFORM                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCSI_UFS_BSG                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SCSI_UFS_CDNS_PLATFORM                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCSI_UFS_CRYPTO                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SCSI_UFS_DWC_TC_PCI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCSI_UFS_DWC_TC_PLATFORM                 policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SCSI_UFS_EXYNOS                          policy<{'armhf': 'n'}>
+CONFIG_SCSI_UFS_HISI                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SCSI_UFS_HWMON                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SCSI_UFS_MEDIATEK                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SCSI_UFS_QCOM                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SCSI_UFS_RENESAS                         policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SCSI_UFS_SPRD                            policy<{'arm64': 'm'}>
+CONFIG_SCSI_UFS_TI_J721E                        policy<{'arm64': 'm'}>
+CONFIG_SCSI_WD719X                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SCTP_COOKIE_HMAC_MD5                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCTP_COOKIE_HMAC_SHA1                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SCTP_DBG_OBJCNT                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SC_CAMCC_7180                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_CAMCC_7280                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_CAMCC_8280XP                          policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_DISPCC_7180                           policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_DISPCC_7280                           policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_DISPCC_8280XP                         policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_GCC_7180                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_GCC_7280                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_GCC_8180X                             policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_GCC_8280XP                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_GPUCC_7180                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_GPUCC_7280                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_GPUCC_8280XP                          policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_LPASSCC_7280                          policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_LPASSCC_8280XP                        policy<{'arm64': 'm'}>
+CONFIG_SC_LPASS_CORECC_7180                     policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_LPASS_CORECC_7280                     policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_MSS_7180                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_VIDEOCC_7180                          policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SC_VIDEOCC_7280                          policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SDIO_UART                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SDMA_VERBOSITY                           policy<{'amd64': 'n'}>
+CONFIG_SDM_CAMCC_845                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SDM_DISPCC_845                           policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SDM_GCC_660                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SDM_GCC_845                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SDM_GPUCC_660                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SDM_GPUCC_845                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SDM_LPASSCC_845                          policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SDM_MMCC_660                             policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SDM_VIDEOCC_845                          policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SDR_MAX2175                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SDR_PLATFORM_DRIVERS                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SDX_GCC_55                               policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_SDX_GCC_65                               policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_SDX_GCC_75                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SD_ADC_MODULATOR                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SECCOMP                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECCOMP_CACHE_DEBUG                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SECCOMP_FILTER                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECONDARY_TRUSTED_KEYRING                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECONDARY_TRUSTED_KEYRING_SIGNED_BY_BUILTIN policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SECRETMEM                                policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECTION_MISMATCH_WARN_ONLY               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITYFS                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_APPARMOR                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_APPARMOR_DEBUG                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SECURITY_APPARMOR_EXPORT_BINARY          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_APPARMOR_HASH                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_APPARMOR_HASH_DEFAULT           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_APPARMOR_INTROSPECT_POLICY      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_APPARMOR_PARANOID_LOAD          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_DMESG_RESTRICT                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_INFINIBAND                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_LANDLOCK                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_LOADPIN                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SECURITY_LOCKDOWN_LSM                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_LOCKDOWN_LSM_EARLY              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_NETWORK                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_NETWORK_XFRM                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_PATH                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_PERF_EVENTS_RESTRICT            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_SELINUX                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_SELINUX_AVC_STATS               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_SELINUX_BOOTPARAM               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_SECURITY_SELINUX_DEBUG                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SECURITY_SELINUX_DEVELOP                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_SELINUX_SID2STR_CACHE_SIZE      policy<{'amd64': '256', 'arm64': '256', 'armhf': '256', 'ppc64el': '256', 'riscv64': '256', 's390x': '256'}>
+CONFIG_SECURITY_SELINUX_SIDTAB_HASH_BITS        policy<{'amd64': '9', 'arm64': '9', 'armhf': '9', 'ppc64el': '9', 'riscv64': '9', 's390x': '9'}>
+CONFIG_SECURITY_SMACK                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_SMACK_APPEND_SIGNALS            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_SMACK_BRINGUP                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SECURITY_SMACK_NETFILTER                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_TOMOYO                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER       policy<{'amd64': '"/sbin/init"', 'arm64': '"/sbin/init"', 'armhf': '"/sbin/init"', 'ppc64el': '"/sbin/init"', 'riscv64': '"/sbin/init"', 's390x': '"/sbin/init"'}>
+CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY         policy<{'amd64': '2048', 'arm64': '2048', 'armhf': '2048', 'ppc64el': '2048', 'riscv64': '2048', 's390x': '2048'}>
+CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG            policy<{'amd64': '1024', 'arm64': '1024', 'armhf': '1024', 'ppc64el': '1024', 'riscv64': '1024', 's390x': '1024'}>
+CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SECURITY_TOMOYO_POLICY_LOADER            policy<{'amd64': '"/sbin/tomoyo-init"', 'arm64': '"/sbin/tomoyo-init"', 'armhf': '"/sbin/tomoyo-init"', 'ppc64el': '"/sbin/tomoyo-init"', 'riscv64': '"/sbin/tomoyo-init"', 's390x': '"/sbin/tomoyo-init"'}>
+CONFIG_SECURITY_YAMA                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SEL3350_PLATFORM                         policy<{'amd64': 'm'}>
+CONFIG_SELECT_MEMORY_MODEL                      policy<{'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SENSEAIR_SUNRISE_CO2                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSIRION_SGP30                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSIRION_SGP40                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_AAEON                            policy<{'amd64': 'm'}>
+CONFIG_SENSORS_ABITUGURU                        policy<{'amd64': 'm'}>
+CONFIG_SENSORS_ABITUGURU3                       policy<{'amd64': 'm'}>
+CONFIG_SENSORS_ACBEL_FSG032                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_ACPI_POWER                       policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_AD7314                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_AD7414                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_AD7418                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADC128D818                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADCXX                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADM1025                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADM1026                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADM1029                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADM1031                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADM1177                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADM1266                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_ADM1275                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_ADM9240                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADS7828                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADS7871                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADT7310                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADT7410                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADT7411                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADT7462                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADT7470                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADT7475                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ADT7X10                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_AHT10                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_AMC6821                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_APDS990X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SENSORS_APPLESMC                         policy<{'amd64': 'm'}>
+CONFIG_SENSORS_AQUACOMPUTER_D5NEXT              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_ARM_SCMI                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SENSORS_ARM_SCPI                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SENSORS_AS370                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ASB100                           policy<{'amd64': 'm'}>
+CONFIG_SENSORS_ASC7621                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_ASPEED                           policy<{'armhf': 'm'}>
+CONFIG_SENSORS_ASUS_EC                          policy<{'amd64': 'm'}>
+CONFIG_SENSORS_ASUS_WMI                         policy<{'amd64': 'm'}>
+CONFIG_SENSORS_ATK0110                          policy<{'amd64': 'm'}>
+CONFIG_SENSORS_ATXP1                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_AXI_FAN_CONTROL                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_BEL_PFE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_BH1770                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SENSORS_BPA_RS600                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_CORETEMP                         policy<{'amd64': 'm'}>
+CONFIG_SENSORS_CORSAIR_CPRO                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_CORSAIR_PSU                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_DA9052_ADC                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_DA9055                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_DELL_SMM                         policy<{'amd64': 'm'}>
+CONFIG_SENSORS_DELTA_AHE50DC_FAN                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_DME1737                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_DPS920AB                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_DRIVETEMP                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_DS1621                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_DS620                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_EMC1403                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_EMC2103                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_EMC2305                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_EMC6W201                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_F71805F                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_F71882FG                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_F75375S                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_FAM15H_POWER                     policy<{'amd64': 'm'}>
+CONFIG_SENSORS_FSCHMD                           policy<{'amd64': 'm'}>
+CONFIG_SENSORS_FSP_3Y                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_FTSTEUTATES                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_G760A                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_G762                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_GIGABYTE_WATERFORCE              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_GL518SM                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_GL520SM                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_GPIO_FAN                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_GSC                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_GXP_FAN_CTRL                     policy<{'armhf': 'm'}>
+CONFIG_SENSORS_HDAPS                            policy<{'amd64': 'm'}>
+CONFIG_SENSORS_HIH6130                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_HMC5843                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_HMC5843_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_HMC5843_SPI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_HP_WMI                           policy<{'amd64': 'm'}>
+CONFIG_SENSORS_HS3001                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_I5500                            policy<{'amd64': 'm'}>
+CONFIG_SENSORS_I5K_AMB                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_IBMAEM                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_IBMPEX                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_IBMPOWERNV                       policy<{'ppc64el': 'm'}>
+CONFIG_SENSORS_IBM_CFFPS                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_IIO_HWMON                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_INA209                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_INA238                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_INA2XX                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_INA3221                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_INSPUR_IPSPS                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_INTEL_M10_BMC_HWMON              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_IR35221                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_IR36021                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_IR38064                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_IR38064_REGULATOR                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SENSORS_IRPS5401                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_ISL29018                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_ISL29028                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_ISL68137                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_IT87                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_JC42                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_K10TEMP                          policy<{'amd64': 'm'}>
+CONFIG_SENSORS_K8TEMP                           policy<{'amd64': 'm'}>
+CONFIG_SENSORS_LINEAGE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LIS3LV02D                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_LIS3_I2C                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SENSORS_LIS3_SPI                         policy<{'armhf': 'm', 'ppc64el': 'm', 'riscv64': '-', 's390x': '-'}>
+CONFIG_SENSORS_LM25066                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_LM25066_REGULATOR                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SENSORS_LM3533                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_LM63                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM70                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM73                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM75                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM77                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM78                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM80                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM83                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM85                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM87                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM90                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM92                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM93                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM95234                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM95241                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LM95245                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LOCHNAGAR                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_LT7182S                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_LTC2945                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LTC2947                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_LTC2947_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LTC2947_SPI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LTC2978                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_LTC2978_REGULATOR                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SENSORS_LTC2990                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LTC2991                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_LTC2992                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LTC3815                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_LTC4151                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LTC4215                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LTC4222                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LTC4245                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LTC4260                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LTC4261                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_LTC4286                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SENSORS_MAX1111                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_MAX127                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_MAX15301                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MAX16064                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MAX16065                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_MAX1619                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_MAX16601                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MAX1668                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_MAX197                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_MAX20730                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MAX20751                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MAX31722                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_MAX31730                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_MAX31760                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MAX31785                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MAX31790                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_MAX34440                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MAX6620                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MAX6621                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_MAX6639                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_MAX6650                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_MAX6697                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_MAX8688                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MC13783_ADC                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MC34VR500                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MCP3021                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_MENF21BMC_HWMON                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MLXREG_FAN                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SENSORS_MP2856                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MP2888                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MP2975                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MP2975_REGULATOR                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SENSORS_MP5023                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MP5990                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MPQ7932                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_MPQ7932_REGULATOR                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SENSORS_MR75203                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_NCT6683                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_NCT6775                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_NCT6775_CORE                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_NCT6775_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_NCT7802                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_NCT7904                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_NPCM7XX                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_NTC_THERMISTOR                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_NZXT_KRAKEN2                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_NZXT_SMART2                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_OCC                              policy<{'amd64': 'm', 'ppc64el': 'm'}>
+CONFIG_SENSORS_OCC_P8_I2C                       policy<{'amd64': 'm', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'm', 'riscv64': 'n'}>
+CONFIG_SENSORS_OCC_P9_SBE                       policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'm', 'riscv64': 'n'}>
+CONFIG_SENSORS_OXP                              policy<{'amd64': 'm'}>
+CONFIG_SENSORS_PC87360                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_PC87427                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_PCF8591                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_PECI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_PECI_CPUTEMP                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_PECI_DIMMTEMP                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_PIM4328                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_PLI1209BC                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_PLI1209BC_REGULATOR              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SENSORS_PM6764TR                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_PMBUS                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_POWERZ                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_POWR1220                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_PWM_FAN                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_PXE1610                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_Q54SJ108A2                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'n', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_RM3100                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_RM3100_I2C                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_RM3100_SPI                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_SBRMI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_SBTSI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_SCH5627                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_SCH5636                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_SCH56XX_COMMON                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_SFCTEMP                          policy<{'riscv64': 'm'}>
+CONFIG_SENSORS_SHT15                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_SHT21                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_SHT3x                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_SHT4x                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_SHTC1                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_SIS5595                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_SL28CPLD                         policy<{'arm64': 'm'}>
+CONFIG_SENSORS_SMPRO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_SMSC47B397                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_SMSC47M1                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_SMSC47M192                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_SPARX5                           policy<{'arm64': 'm'}>
+CONFIG_SENSORS_STPDDC60                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_STTS751                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_SY7636A                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_TC654                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_TC74                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_TDA38640                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_TDA38640_REGULATOR               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SENSORS_THMC50                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_TMP102                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_TMP103                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_TMP108                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_TMP401                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_TMP421                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_TMP464                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_TMP513                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_TPS23861                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_TPS40422                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_TPS53679                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_TPS546D24                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_TSL2550                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SENSORS_TSL2563                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_UCD9000                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_UCD9200                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_VEXPRESS                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SENSORS_VIA686A                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_VIA_CPUTEMP                      policy<{'amd64': 'm'}>
+CONFIG_SENSORS_VT1211                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_VT8231                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_W83627EHF                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_W83627HF                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_W83773G                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_W83781D                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_W83791D                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_W83792D                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_W83793                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_W83795                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_W83795_FANCTRL                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_SENSORS_W83L785TS                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_W83L786NG                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_WM831X                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_WM8350                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SENSORS_XDPE122                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_XDPE122_REGULATOR                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SENSORS_XDPE152                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_XGENE                            policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SENSORS_ZL6100                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SERIAL_8250                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_16550A_VARIANTS              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_ASPEED_VUART                 policy<{'armhf': 'm'}>
+CONFIG_SERIAL_8250_CONSOLE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_CS                           policy<{'amd64': 'm'}>
+CONFIG_SERIAL_8250_DEPRECATED_OPTIONS           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SERIAL_8250_DETECT_IRQ                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SERIAL_8250_DFL                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'n', 'riscv64': 'm'}>
+CONFIG_SERIAL_8250_DMA                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_DWLIB                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_EM                           policy<{'arm64': 'n', 'armhf': 'n', 'riscv64': 'n'}>
+CONFIG_SERIAL_8250_EXAR                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SERIAL_8250_EXTENDED                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_FINTEK                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_FSL                          policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_SERIAL_8250_LPSS                         policy<{'amd64': 'm'}>
+CONFIG_SERIAL_8250_MANY_PORTS                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_MEN_MCB                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SERIAL_8250_MT6577                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_8250_NR_UARTS                     policy<{'amd64': '48', 'arm64': '48', 'armhf': '48', 'ppc64el': '48', 'riscv64': '48'}>
+CONFIG_SERIAL_8250_OMAP                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_8250_OMAP_TTYO_FIXUP              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_8250_PCI                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_PCI1XXXX                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'n', 'riscv64': 'm'}>
+CONFIG_SERIAL_8250_PCILIB                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_PERICOM                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SERIAL_8250_PNP                          policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_RSA                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_RT288X                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_RUNTIME_UARTS                policy<{'amd64': '32', 'arm64': '32', 'armhf': '32', 'ppc64el': '32', 'riscv64': '32'}>
+CONFIG_SERIAL_8250_SHARE_IRQ                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_8250_TEGRA                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_ALTERA_JTAGUART                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SERIAL_ALTERA_UART                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SERIAL_ALTERA_UART_BAUDRATE              policy<{'amd64': '115200', 'arm64': '115200', 'armhf': '115200', 'ppc64el': '115200', 'riscv64': '115200'}>
+CONFIG_SERIAL_ALTERA_UART_MAXPORTS              policy<{'amd64': '4', 'arm64': '4', 'armhf': '4', 'ppc64el': '4', 'riscv64': '4'}>
+CONFIG_SERIAL_AMBA_PL010                        policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SERIAL_AMBA_PL011                        policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'm'}>
+CONFIG_SERIAL_AMBA_PL011_CONSOLE                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_ARC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SERIAL_ARC_NR_PORTS                      policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'ppc64el': '1', 'riscv64': '1'}>
+CONFIG_SERIAL_CONEXANT_DIGICOLOR                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SERIAL_CORE                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'm'}>
+CONFIG_SERIAL_CORE_CONSOLE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_EARLYCON                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_EARLYCON_RISCV_SBI                policy<{'riscv64': 'y'}>
+CONFIG_SERIAL_EARLYCON_SEMIHOST                 policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_FSL_LINFLEXUART                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SERIAL_FSL_LPUART                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SERIAL_ICOM                              policy<{'ppc64el': 'm'}>
+CONFIG_SERIAL_IMX                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_IMX_CONSOLE                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_IMX_EARLYCON                      policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_SERIAL_IPOCTAL                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SERIAL_JSM                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SERIAL_KGDB_NMI                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_LANTIQ                            policy<{'amd64': 'm'}>
+CONFIG_SERIAL_LITEUART                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SERIAL_LITEUART_MAX_PORTS                policy<{'arm64': '1', 'armhf': '1', 'ppc64el': '1', 'riscv64': '1'}>
+CONFIG_SERIAL_MAX3100                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SERIAL_MAX310X                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_MCTRL_GPIO                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_MEN_Z135                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SERIAL_MESON                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_MESON_CONSOLE                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_MILBEAUT_USIO                     policy<{'armhf': 'm'}>
+CONFIG_SERIAL_MILBEAUT_USIO_PORTS               policy<{'armhf': '4'}>
+CONFIG_SERIAL_MSM                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_MSM_CONSOLE                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_MULTI_INSTANTIATE                 policy<{'amd64': 'm', 'arm64': 'n', 'riscv64': 'n'}>
+CONFIG_SERIAL_MVEBU_CONSOLE                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_MVEBU_UART                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_NONSTANDARD                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_SERIAL_NUVOTON_MA35D1                    policy<{'arm64': 'm'}>
+CONFIG_SERIAL_OF_PLATFORM                       policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_OWL                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_OWL_CONSOLE                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_QCOM_GENI                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SERIAL_QCOM_GENI_CONSOLE                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_QE                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}>
+CONFIG_SERIAL_RDA                               policy<{'armhf': 'y'}>
+CONFIG_SERIAL_RDA_CONSOLE                       policy<{'armhf': 'y'}>
+CONFIG_SERIAL_RP2                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SERIAL_RP2_NR_UARTS                      policy<{'amd64': '32', 'arm64': '32', 'armhf': '32', 'ppc64el': '32', 'riscv64': '32'}>
+CONFIG_SERIAL_SAMSUNG                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SERIAL_SAMSUNG_CONSOLE                   policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_SAMSUNG_UARTS                     policy<{'arm64': '4', 'armhf': '4'}>
+CONFIG_SERIAL_SC16IS7XX                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SERIAL_SC16IS7XX_CORE                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SERIAL_SC16IS7XX_I2C                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_SC16IS7XX_SPI                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_SCCNXP                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_SERIAL_SCCNXP_CONSOLE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_SH_SCI_DMA                        policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_SERIAL_SH_SCI_NR_UARTS                   policy<{'arm64': '2', 'armhf': '2', 'riscv64': '2'}>
+CONFIG_SERIAL_SIFIVE                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'y'}>
+CONFIG_SERIAL_SIFIVE_CONSOLE                    policy<{'riscv64': 'y'}>
+CONFIG_SERIAL_SPRD                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SERIAL_STM32                             policy<{'arm64': 'm'}>
+CONFIG_SERIAL_ST_ASC                            policy<{'armhf': 'm'}>
+CONFIG_SERIAL_SUNPLUS                           policy<{'armhf': 'y'}>
+CONFIG_SERIAL_SUNPLUS_CONSOLE                   policy<{'armhf': 'y'}>
+CONFIG_SERIAL_TEGRA                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SERIAL_TEGRA_TCU                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_TEGRA_TCU_CONSOLE                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SERIAL_UARTLITE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SERIAL_UARTLITE_NR_UARTS                 policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'ppc64el': '1', 'riscv64': '1', 's390x': '1'}>
+CONFIG_SERIAL_XILINX_PS_UART                    policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SERIO                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_SERIO_ALTERA_PS2                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SERIO_AMBAKMI                            policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SERIO_APBPS2                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SERIO_ARC_PS2                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SERIO_CT82C710                           policy<{'amd64': 'm'}>
+CONFIG_SERIO_GPIO_PS2                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SERIO_I8042                              policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_SERIO_LIBPS2                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SERIO_NVEC_PS2                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SERIO_PARKBD                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SERIO_PCIPS2                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SERIO_PS2MULT                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SERIO_RAW                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SERIO_SERPORT                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SERIO_SUN4I_PS2                          policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_SERIO_XILINX_XPS_PS2                     policy<{'ppc64el': 'm'}>
+CONFIG_SEV_GUEST                                policy<{'amd64': 'm'}>
+CONFIG_SFC                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SFC_FALCON                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SFC_FALCON_MTD                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SFC_MCDI_LOGGING                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SFC_MCDI_MON                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SFC_MTD                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SFC_SIENA                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SFC_SIENA_MCDI_LOGGING                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SFC_SIENA_MCDI_MON                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SFC_SIENA_MTD                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SFC_SIENA_SRIOV                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SFC_SRIOV                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SFP                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SF_PDMA                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SGETMASK_SYSCALL                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SGI_GRU                                  policy<{'amd64': 'm'}>
+CONFIG_SGI_GRU_DEBUG                            policy<{'amd64': 'n'}>
+CONFIG_SGI_PARTITION                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_SGI_XP                                   policy<{'amd64': 'm'}>
+CONFIG_SGL_ALLOC                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SG_POOL                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SG_SPLIT                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SHADOW_CALL_STACK                        policy<{'arm64': 'y'}>
+CONFIG_SHMEM                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SHRINKER_DEBUG                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SHUFFLE_PAGE_ALLOCATOR                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SH_ETH                                   policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SH_TIMER_CMT                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SH_TIMER_MTU2                            policy<{'armhf': 'y'}>
+CONFIG_SH_TIMER_TMU                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SI1133                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SI1145                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SI7005                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SI7020                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SIEMENS_SIMATIC_IPC                      policy<{'amd64': 'm'}>
+CONFIG_SIEMENS_SIMATIC_IPC_BATT                 policy<{'amd64': 'm'}>
+CONFIG_SIEMENS_SIMATIC_IPC_BATT_APOLLOLAKE      policy<{'amd64': 'm'}>
+CONFIG_SIEMENS_SIMATIC_IPC_BATT_ELKHARTLAKE     policy<{'amd64': 'm'}>
+CONFIG_SIEMENS_SIMATIC_IPC_BATT_F7188X          policy<{'amd64': 'm'}>
+CONFIG_SIEMENS_SIMATIC_IPC_WDT                  policy<{'amd64': 'm'}>
+CONFIG_SIFIVE_CCACHE                            policy<{'riscv64': 'y'}>
+CONFIG_SIFIVE_PLIC                              policy<{'riscv64': 'y'}>
+CONFIG_SIGNALFD                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SIGNATURE                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SIGNED_PE_FILE_VERIFICATION              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SILICOM_PLATFORM                         policy<{'amd64': 'm'}>
+CONFIG_SIOX                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SIOX_BUS_GPIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SIS190                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SIS900                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SKB_EXTENSIONS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SKFP                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SKGE                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SKGE_DEBUG                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_SKGE_GENESIS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SKY2                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SKY2_DEBUG                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_SL28CPLD_WATCHDOG                        policy<{'arm64': 'm'}>
+CONFIG_SLAB_FREELIST_HARDENED                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SLAB_FREELIST_RANDOM                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SLAB_MERGE_DEFAULT                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SLHC                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SLICOSS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SLIC_DS26522                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SLIMBUS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SLIM_QCOM_CTRL                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SLIM_QCOM_NGD_CTRL                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SLIP                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SLIP_COMPRESSED                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SLIP_MODE_SLIP6                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SLIP_SMART                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SLS                                      policy<{'amd64': 'y'}>
+CONFIG_SLUB                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SLUB_CPU_PARTIAL                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SLUB_DEBUG                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SLUB_DEBUG_ON                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SLUB_STATS                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SLUB_TINY                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SMARTJOYPLUS_FF                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SMBFS                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SMB_SERVER                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SMB_SERVER_KERBEROS5                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SMB_SERVER_SMBDIRECT                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SMC91X                                   policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SMP                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SMPRO_ERRMON                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SMPRO_MISC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SMP_ON_UP                                policy<{'armhf': 'y'}>
+CONFIG_SMSC37B787_WDT                           policy<{'amd64': 'm'}>
+CONFIG_SMSC911X                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SMSC9420                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SMSC_PHY                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SMSC_SCH311X_WDT                         policy<{'amd64': 'm'}>
+CONFIG_SMSGIUCV                                 policy<{'s390x': 'y'}>
+CONFIG_SMSGIUCV_EVENT                           policy<{'s390x': 'm'}>
+CONFIG_SMS_SDIO_DRV                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SMS_SIANO_DEBUGFS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SMS_SIANO_MDTV                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SMS_SIANO_RC                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SMS_USB_DRV                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SMT_NUM_THREADS_DYNAMIC                  policy<{'ppc64el': 'y'}>
+CONFIG_SM_CAMCC_6350                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_CAMCC_8250                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_CAMCC_8450                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_CAMCC_8550                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_DISPCC_6115                           policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_DISPCC_6125                           policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_DISPCC_6350                           policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_DISPCC_6375                           policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_DISPCC_8250                           policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_DISPCC_8450                           policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_DISPCC_8550                           policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_DISPCC_8650                           policy<{'arm64': 'm'}>
+CONFIG_SM_FTL                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SM_GCC_4450                              policy<{'arm64': 'm'}>
+CONFIG_SM_GCC_6115                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GCC_6125                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GCC_6350                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GCC_6375                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GCC_7150                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SM_GCC_8150                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GCC_8250                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GCC_8350                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GCC_8450                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GCC_8550                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GCC_8650                              policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GPUCC_6115                            policy<{'arm64': 'm'}>
+CONFIG_SM_GPUCC_6125                            policy<{'arm64': 'm'}>
+CONFIG_SM_GPUCC_6350                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GPUCC_6375                            policy<{'arm64': 'm'}>
+CONFIG_SM_GPUCC_8150                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GPUCC_8250                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GPUCC_8350                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GPUCC_8450                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GPUCC_8550                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_GPUCC_8650                            policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_TCSRCC_8550                           policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_TCSRCC_8650                           policy<{'arm64': 'm'}>
+CONFIG_SM_VIDEOCC_8150                          policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_VIDEOCC_8250                          policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_VIDEOCC_8350                          policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_VIDEOCC_8450                          policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SM_VIDEOCC_8550                          policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SND_AC97_CODEC                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_AC97_POWER_SAVE                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_AC97_POWER_SAVE_DEFAULT              policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0'}>
+CONFIG_SND_AD1889                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_ALI5451                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_ALOOP                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_ALS300                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_ALS4000                              policy<{'amd64': 'm', 'ppc64el': 'm'}>
+CONFIG_SND_AMD_ACP_CONFIG                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_AMD_ASOC_ACP63                       policy<{'amd64': 'm'}>
+CONFIG_SND_AMD_ASOC_ACP70                       policy<{'amd64': 'm'}>
+CONFIG_SND_AMD_ASOC_REMBRANDT                   policy<{'amd64': 'm'}>
+CONFIG_SND_AMD_ASOC_RENOIR                      policy<{'amd64': 'm'}>
+CONFIG_SND_ARM                                  policy<{'armhf': 'y'}>
+CONFIG_SND_ARMAACI                              policy<{'armhf': 'm'}>
+CONFIG_SND_ASIHPI                               policy<{'amd64': 'm'}>
+CONFIG_SND_ATIIXP                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_ATIIXP_MODEM                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_ATMEL_SOC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_AU8810                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_AU8820                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_AU8830                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_AUDIO_GRAPH_CARD                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_AUDIO_GRAPH_CARD2                    policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_AUDIO_GRAPH_CARD2_CUSTOM_SAMPLE      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_AW2                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_AZT3328                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_BCD2000                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_BCM63XX_I2S_WHISTLER                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_BEBOB                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_BT87X                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_BT87X_OVERCLOCK                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SND_CA0106                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_CMIPCI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_COMPRESS_OFFLOAD                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_CS4281                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_CS46XX                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_CS46XX_NEW_DSP                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_CTL_FAST_LOOKUP                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SND_CTL_INPUT_VALIDATION                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SND_CTL_LED                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_CTXFI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_DARLA20                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_DARLA24                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SND_DESIGNWARE_I2S                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_DESIGNWARE_PCM                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_DICE                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_DMAENGINE_PCM                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_DMA_SGBUF                            policy<{'amd64': 'y'}>
+CONFIG_SND_DRIVERS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_DUMMY                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_DYNAMIC_MINORS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_ECHO3G                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_EMU10K1                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_EMU10K1X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_EMU10K1_SEQ                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_ENS1370                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_ENS1371                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_ES1938                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_ES1968                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_ES1968_INPUT                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SND_ES1968_RADIO                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SND_FIREFACE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_FIREWIRE                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_FIREWIRE_DIGI00X                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_FIREWIRE_LIB                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_FIREWIRE_MOTU                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_FIREWIRE_TASCAM                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_FIREWORKS                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_FM801                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_FM801_TEA575X_BOOL                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_GINA20                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_GINA24                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_ALIGNED_MMIO                     policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SND_HDA_CIRRUS_SCODEC                    policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_CODEC_ANALOG                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_CODEC_CA0110                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_CODEC_CA0132                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_CODEC_CA0132_DSP                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_HDA_CODEC_CIRRUS                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_CODEC_CMEDIA                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_CODEC_CONEXANT                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_CODEC_CS8409                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_CODEC_HDMI                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_CODEC_REALTEK                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_CODEC_SI3054                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_CODEC_SIGMATEL                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_CODEC_VIA                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_COMPONENT                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_HDA_CORE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_CS_DSP_CONTROLS                  policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_CTL_DEV_ID                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SND_HDA_DSP_LOADER                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_HDA_EXT_CORE                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_GENERIC                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_GENERIC_LEDS                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_HDA_HWDEP                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_HDA_I915                             policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_HDA_INPUT_BEEP                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_HDA_INPUT_BEEP_MODE                  policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0'}>
+CONFIG_SND_HDA_INTEL                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM         policy<{'amd64': 'y', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SND_HDA_PATCH_LOADER                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_HDA_PREALLOC_SIZE                    policy<{'amd64': '0', 'arm64': '64', 'armhf': '64', 'ppc64el': '64', 'riscv64': '64'}>
+CONFIG_SND_HDA_SCODEC_CS35L41                   policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_SCODEC_CS35L41_I2C               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_SCODEC_CS35L41_SPI               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_SCODEC_CS35L56                   policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_SCODEC_CS35L56_I2C               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_SCODEC_CS35L56_SPI               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_SCODEC_TAS2781_I2C               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDA_TEGRA                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_HDSP                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HDSPM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HRTIMER                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_HWDEP                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_I2S_HI6210_I2S                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_ICE1712                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_ICE1724                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_IMX_SOC                              policy<{'arm64': 'm', 'armhf': 'y'}>
+CONFIG_SND_INDIGO                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_INDIGODJ                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_INDIGODJX                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_INDIGOIO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_INDIGOIOX                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_INTEL8X0                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_INTEL8X0M                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_INTEL_BYT_PREFER_SOF                 policy<{'amd64': 'y'}>
+CONFIG_SND_INTEL_DSP_CONFIG                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_INTEL_NHLT                           policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_SND_INTEL_SOUNDWIRE_ACPI                 policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_ISIGHT                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_JACK                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_JACK_INPUT_DEV                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_KIRKWOOD_SOC                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_KIRKWOOD_SOC_ARMADA370_DB            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_KORG1212                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_LAYLA20                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_LAYLA24                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_LOLA                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_LX6464ES                             policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_MAESTRO3                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MAESTRO3_INPUT                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SND_MAX_CARDS                            policy<{'amd64': '32', 'arm64': '32', 'armhf': '32', 'ppc64el': '32', 'riscv64': '32'}>
+CONFIG_SND_MESON_AIU                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_AXG_FIFO                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_AXG_FRDDR                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_AXG_PDM                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_AXG_SOUND_CARD                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_AXG_SPDIFIN                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_AXG_SPDIFOUT                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_AXG_TDMIN                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_AXG_TDMOUT                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_AXG_TDM_FORMATTER              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_AXG_TDM_INTERFACE              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_AXG_TODDR                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_CARD_UTILS                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_CODEC_GLUE                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_G12A_TOACODEC                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_G12A_TOHDMITX                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MESON_GX_SOUND_CARD                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_MIA                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_MIXART                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_MIXER_OSS                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_MONA                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_MPU401                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_MPU401_UART                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_MTPAV                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_MTS64                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_NM256                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_OPL3_LIB                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_OPL3_LIB_SEQ                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_OSSEMUL                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_OXFW                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_OXYGEN                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_OXYGEN_LIB                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_PCI                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_PCM                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_PCMCIA                               policy<{'amd64': 'y'}>
+CONFIG_SND_PCMTEST                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_PCM_ELD                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_PCM_IEC958                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_PCM_TIMER                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_PCSP                                 policy<{'amd64': 'm'}>
+CONFIG_SND_PCXHR                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_PDAUDIOCF                            policy<{'amd64': 'm'}>
+CONFIG_SND_PORTMAN2X4                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_PPC                                  policy<{'ppc64el': 'y'}>
+CONFIG_SND_PROC_FS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_RAWMIDI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_RIPTIDE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_RME32                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_RME96                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_RME9652                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SB_COMMON                            policy<{'amd64': 'm', 'ppc64el': 'm'}>
+CONFIG_SND_SEQUENCER                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SEQUENCER_OSS                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SND_SEQ_DEVICE                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SEQ_DUMMY                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SEQ_HRTIMER_DEFAULT                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_SEQ_MIDI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SEQ_MIDI_EMUL                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SEQ_MIDI_EVENT                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SEQ_UMP                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_SEQ_UMP_CLIENT                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SEQ_VIRMIDI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SERIAL_GENERIC                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SERIAL_U16550                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SIMPLE_CARD                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SIMPLE_CARD_UTILS                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AC97_BUS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_SOC_AC97_CODEC                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ACPI                             policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ACPI_INTEL_MATCH                 policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_ADAU1372                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADAU1372_I2C                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADAU1372_SPI                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADAU1701                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADAU1761                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADAU1761_I2C                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADAU1761_SPI                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADAU17X1                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADAU7002                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADAU7118                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADAU7118_HW                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADAU7118_I2C                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADAU_UTILS                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADI_AXI_I2S                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ADI_AXI_SPDIF                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AK4104                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AK4118                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AK4375                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AK4458                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AK4554                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AK4613                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AK4642                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AK5386                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AK5558                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ALC5623                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ALC5632                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_AMD_ACP                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AMD_ACP3x                        policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_ACP5x                        policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_ACP6x                        policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_ACP_COMMON                   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_ACP_I2S                      policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_ACP_LEGACY_COMMON            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_ACP_PCI                      policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_ACP_PCM                      policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_ACP_PDM                      policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH        policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AMD_CZ_RT5645_MACH               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AMD_LEGACY_MACH                  policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_MACH_COMMON                  policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_PS                           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_PS_MACH                      policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_RPL_ACP6x                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_RV_RT5682_MACH               policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_SOF_MACH                     policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_ST_ES8336_MACH               policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AMD_VANGOGH_MACH                 policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AMD_YC_MACH                      policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_APPLE_MCA                        policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_APQ8016_SBC                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_ARIZONA                          policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_AUDIO_IIO_AUX                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AW8738                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AW87390                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AW88261                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AW88395                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AW88395_LIB                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_AW88399                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_BD28623                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_BT_SCO                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CHV3_CODEC                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CHV3_I2S                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_COMPRESS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_SOC_CPCAP                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CROS_EC_CODEC                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_CS35L32                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L33                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L34                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L35                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L36                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L41                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L41_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L41_LIB                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L41_SPI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L45                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L45_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L45_SPI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L56                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L56_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L56_SDW                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L56_SHARED                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS35L56_SPI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS4234                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS4265                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS4270                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS4271                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS4271_I2C                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS4271_SPI                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS42L42                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS42L42_CORE                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS42L42_SDW                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS42L43                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS42L43_SDW                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS42L51                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS42L51_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS42L52                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS42L56                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS42L73                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS42L83                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS42XX8                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS42XX8_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS43130                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS4341                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS4349                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CS53L30                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_CX2072X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_DA7213                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_DA7219                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_DAVINCI_MCASP                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_DMIC                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ES7134                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ES7241                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ES8316                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ES8326                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ES8328                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ES8328_I2C                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ES8328_SPI                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ES83XX_DSM_COMMON                policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_EUKREA_TLV320                    policy<{'armhf': 'm'}>
+CONFIG_SND_SOC_FSL_ASOC_CARD                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_FSL_ASRC                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_FSL_AUD2HTX                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_FSL_AUDMIX                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_FSL_EASRC                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_FSL_ESAI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_FSL_MICFIL                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_FSL_MQS                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_FSL_RPMSG                        policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_FSL_SAI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_FSL_SPDIF                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_FSL_SSI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_FSL_UTILS                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_FSL_XCVR                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_SOC_GTM601                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_HDA                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_HDAC_HDA                         policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_HDAC_HDMI                        policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_HDMI_CODEC                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_I2C_AND_SPI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ICS43432                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_IDT821034                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_IMG                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_SOC_IMG_I2S_IN                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_IMG_I2S_OUT                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_IMG_PARALLEL_OUT                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_IMG_PISTACHIO_INTERNAL_DAC       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_IMG_SPDIF_IN                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_IMG_SPDIF_OUT                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_IMX_AUDIO_RPMSG                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_IMX_AUDMIX                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_IMX_AUDMUX                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_IMX_CARD                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_IMX_ES8328                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_IMX_HDMI                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_IMX_PCM_DMA                      policy<{'arm64': 'm', 'armhf': 'y'}>
+CONFIG_SND_SOC_IMX_PCM_FIQ                      policy<{'armhf': 'y'}>
+CONFIG_SND_SOC_IMX_PCM_RPMSG                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_IMX_RPMSG                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_IMX_SGTL5000                     policy<{'arm64': 'm', 'armhf': 'y'}>
+CONFIG_SND_SOC_IMX_SPDIF                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_INNO_RK3036                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_INTEL_APL                        policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS                        policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_DA7219            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_DMIC              policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_ES8336            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_HDAUDIO           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_I2S_TEST          policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98357A         policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98373          policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_MAX98927          policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_NAU8825           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_PROBE             policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_RT274             policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_RT286             policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_RT298             policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_RT5514            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_RT5663            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_RT5682            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_AVS_MACH_SSM4567           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_BDW_RT5650_MACH            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_BDW_RT5677_MACH            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_BROADWELL_MACH             policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH  policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_BXT_RT298_MACH             policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_BYTCR_RT5640_MACH          policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_BYTCR_RT5651_MACH          policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_BYTCR_WM5102_MACH          policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_BYT_CHT_CX2072X_MACH       policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_BYT_CHT_DA7213_MACH        policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_BYT_CHT_ES8316_MACH        policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH       policy<{'amd64': 'n'}>
+CONFIG_SND_SOC_INTEL_CATPT                      policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_CHT_BSW_NAU8824_MACH       policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_CHT_BSW_RT5645_MACH        policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_CHT_BSW_RT5672_MACH        policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_CML_LP_DA7219_MAX98357A_MACH policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_DA7219_MAX98357A_GENERIC   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_EHL_RT5660_MACH            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_GLK                        policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_GLK_DA7219_MAX98357A_MACH  policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_GLK_RT5682_MAX98357A_MACH  policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_HASWELL_MACH               policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_HDA_DSP_COMMON             policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_KBL                        policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98357A_MACH  policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_KBL_DA7219_MAX98927_MACH   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_KBL_RT5660_MACH            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_KEEMBAY                    policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_INTEL_MACH                       policy<{'amd64': 'y'}>
+CONFIG_SND_SOC_INTEL_SKL                        policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH  policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SKL_RT286_MACH             policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SKYLAKE_COMMON             policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SKYLAKE_FAMILY             policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SKYLAKE_SSP_CLK            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_BOARD_HELPERS          policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_CIRRUS_COMMON          policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_CML_RT1011_RT5682_MACH policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_CS42L42_MACH           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_DA7219_MACH            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_ES8336_MACH            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_MAXIM_COMMON           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_NAU8825_MACH           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_NUVOTON_COMMON         policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_PCM512x_MACH           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_REALTEK_COMMON         policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_SSP_AMP_MACH           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_SSP_COMMON             policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SOF_WM8804_MACH            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SST                        policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_INTEL_SST_TOPLEVEL               policy<{'amd64': 'y'}>
+CONFIG_SND_SOC_J721E_EVM                        policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_JH7110_PWMDAC                    policy<{'riscv64': 'm'}>
+CONFIG_SND_SOC_JH7110_TDM                       policy<{'riscv64': 'm'}>
+CONFIG_SND_SOC_LOCHNAGAR_SC                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_LPASS_APQ8016                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_LPASS_CDC_DMA                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_LPASS_CPU                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_LPASS_HDMI                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_LPASS_IPQ806X                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_LPASS_MACRO_COMMON               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_LPASS_PLATFORM                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_LPASS_RX_MACRO                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_LPASS_SC7180                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_LPASS_SC7280                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_LPASS_TX_MACRO                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_LPASS_VA_MACRO                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_LPASS_WSA_MACRO                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX9759                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX98088                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX98090                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX98357A                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX98363                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX98373                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX98373_I2C                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX98373_SDW                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX98388                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX98390                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX98396                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX98504                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX98520                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX9860                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX9867                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MAX98927                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MEDIATEK                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MESON_T9015                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MIKROE_PROTO                     policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MSM8916_WCD_ANALOG               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MSM8916_WCD_DIGITAL              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MSM8996                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT2701                           policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_SND_SOC_MT6351                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MT6358                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MT6359                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT6359_ACCDET                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT6660                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_MT6797                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT6797_MT6351                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT7986                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT7986_WM8960                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT8173                           policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_SND_SOC_MT8183                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT8183_DA7219_MAX98357A          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT8183_MT6358_TS3A227E_MAX98357A policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT8186                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT8186_MT6366_DA7219_MAX98357    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT8186_MT6366_RT1019_RT5682S     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT8188                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT8188_MT6359                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT8192                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT8192_MT6359_RT1015_RT5682      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT8195                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MT8195_MT6359                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_MTK_BTCVSD                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_NAU8315                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_NAU8540                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_NAU8810                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_NAU8821                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_NAU8822                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_NAU8824                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_NAU8825                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_OMAP_MCBSP                       policy<{'armhf': 'm'}>
+CONFIG_SND_SOC_PCM1681                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM1789                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM1789_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM179X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM179X_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM179X_SPI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM186X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM186X_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM186X_SPI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM3060                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM3060_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM3060_SPI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM3168A                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM3168A_I2C                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM3168A_SPI                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM5102A                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM512x                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM512x_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PCM512x_SPI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_PEB2466                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_QCOM                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QCOM_COMMON                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QCOM_SDW                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6_ADM                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6_AFE                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6_AFE_CLOCKS                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6_AFE_DAI                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6_APM                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6_APM_DAI                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6_APM_LPASS_DAI              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6_ASM                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6_ASM_DAI                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6_COMMON                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6_CORE                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6_PRM                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6_PRM_LPASS_CLOCKS           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_QDSP6_ROUTING                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_RCAR                             policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RK3288_HDMI_ANALOG               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_RK3328                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RK3399_GRU_SOUND                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_RK817                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RL6231                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RL6347A                          policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_ROCKCHIP                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_ROCKCHIP_I2S                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_ROCKCHIP_I2S_TDM                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_ROCKCHIP_MAX98090                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_ROCKCHIP_PDM                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_ROCKCHIP_RT5645                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_ROCKCHIP_SPDIF                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_RT1011                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_RT1015                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_RT1015P                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_RT1017_SDCA_SDW                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT1019                           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_RT1308                           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_RT1308_SDW                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT1316_SDW                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT1318_SDW                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT274                            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_RT286                            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_RT298                            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_RT5514                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_RT5514_SPI                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_RT5616                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT5631                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT5640                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT5645                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT5651                           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_RT5659                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT5660                           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_RT5663                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_RT5670                           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_RT5677                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_RT5677_SPI                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_RT5682                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT5682S                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_RT5682_I2C                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT5682_SDW                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT700                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT700_SDW                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT711                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT711_SDCA_SDW                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT711_SDW                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT712_SDCA_DMIC_SDW              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT712_SDCA_SDW                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT715                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT715_SDCA_SDW                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT715_SDW                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT722_SDCA_SDW                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RT9120                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RTQ9128                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_RZ                               policy<{'arm64': 'm', 'riscv64': '-'}>
+CONFIG_SND_SOC_SAMSUNG                          policy<{'armhf': 'n'}>
+CONFIG_SND_SOC_SC7180                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_SC7280                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_SC8280XP                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_SDM845                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_SDW_MOCKUP                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SGTL5000                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SH4_FSI                          policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SI476X                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SIGMADSP                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SIGMADSP_I2C                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SIGMADSP_REGMAP                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SIMPLE_AMPLIFIER                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SIMPLE_MUX                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SM8250                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_SMA1303                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SOF                              policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SND_SOC_SOF_ACPI                         policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SOF_ACPI_DEV                     policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_ACP_PROBES                   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_ALDERLAKE                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_AMD_ACP63                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_AMD_COMMON                   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_AMD_REMBRANDT                policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_AMD_RENOIR                   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_AMD_TOPLEVEL                 policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_AMD_VANGOGH                  policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_APOLLOLAKE                   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_BAYTRAIL                     policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_BROADWELL                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_CANNONLAKE                   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_CLIENT                       policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_COFFEELAKE                   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_COMETLAKE                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_COMPRESS                     policy<{'arm64': 'y'}>
+CONFIG_SND_SOC_SOF_DEBUG_PROBES                 policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_DEVELOPER_SUPPORT            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': '-', 'ppc64el': '-'}>
+CONFIG_SND_SOC_SOF_ELKHARTLAKE                  policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_GEMINILAKE                   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_HDA                          policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_HDA_COMMON                   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_HDA_LINK_BASELINE            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_HDA_MLINK                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_HDA_PROBES                   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_ICELAKE                      policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_IMX8                         policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_SOF_IMX8M                        policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_SOF_IMX8ULP                      policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_SOF_IMX_COMMON                   policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_SOF_IMX_TOPLEVEL                 policy<{'arm64': 'y'}>
+CONFIG_SND_SOC_SOF_INTEL_APL                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_INTEL_ATOM_HIFI_EP           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_INTEL_CNL                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_INTEL_COMMON                 policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_INTEL_HIFI_EP_IPC            policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_INTEL_ICL                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_INTEL_LNL                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_INTEL_MTL                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_INTEL_SKL                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE              policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_INTEL_TGL                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL               policy<{'amd64': 'y'}>
+CONFIG_SND_SOC_SOF_IPC3                         policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_SND_SOC_SOF_IPC4                         policy<{'amd64': 'y'}>
+CONFIG_SND_SOC_SOF_JASPERLAKE                   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_KABYLAKE                     policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_LUNARLAKE                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_MERRIFIELD                   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_METEORLAKE                   policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_MT8186                       policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_SOF_MT8195                       policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_SOF_MTK_COMMON                   policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_SOF_MTK_TOPLEVEL                 policy<{'arm64': 'y'}>
+CONFIG_SND_SOC_SOF_OF                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SOF_OF_DEV                       policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_SOF_PCI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SOF_PCI_DEV                      policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE             policy<{'amd64': 'y'}>
+CONFIG_SND_SOC_SOF_SKYLAKE                      policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_TIGERLAKE                    policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_SOF_TOPLEVEL                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_SOC_SOF_XTENSA                       policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SND_SOC_SPDIF                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SPRD                             policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_SPRD_MCDT                        policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_SRC4XXX                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SRC4XXX_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SSM2305                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SSM2518                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SSM2602                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SSM2602_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SSM2602_SPI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SSM3515                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_SSM4567                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_STA32X                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_STA350                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_STARFIVE                         policy<{'riscv64': 'm'}>
+CONFIG_SND_SOC_STI_SAS                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_STM32_DFSDM                      policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_STM32_I2S                        policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_STM32_SAI                        policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_STM32_SPDIFRX                    policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_STORM                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TAS2552                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TAS2562                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TAS2764                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TAS2770                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TAS2780                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TAS2781_COMLIB                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TAS2781_FMWLIB                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TAS2781_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TAS5086                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TAS571X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TAS5720                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TAS5805M                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TAS6424                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TDA7419                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TEGRA                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA186_ASRC                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA186_DSPK                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA20_AC97                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA20_DAS                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA20_I2S                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA20_SPDIF                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA210_ADMAIF                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA210_ADX                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA210_AHUB                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA210_AMX                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA210_DMIC                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA210_I2S                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA210_MIXER                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA210_MVC                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA210_OPE                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA210_SFC                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA30_AHUB                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA30_I2S                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA_ALC5632                    policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA_AUDIO_GRAPH_CARD           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA_MACHINE_DRV                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA_MAX98088                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA_MAX98090                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA_RT5631                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA_RT5640                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA_RT5677                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA_SGTL5000                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA_TRIMSLICE                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA_WM8753                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA_WM8903                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TEGRA_WM9712                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TFA9879                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TFA989X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TI_EDMA_PCM                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TI_SDMA_PCM                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TI_UDMA_PCM                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_TLV320ADC3XXX                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TLV320ADCX140                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TLV320AIC23                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TLV320AIC23_I2C                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TLV320AIC23_SPI                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TLV320AIC31XX                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TLV320AIC32X4                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TLV320AIC32X4_I2C                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TLV320AIC32X4_SPI                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TLV320AIC3X                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TLV320AIC3X_I2C                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TLV320AIC3X_SPI                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TOPOLOGY                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SND_SOC_TPA6130A2                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TS3A227E                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TSCS42XX                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_TSCS454                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_UDA1334                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WCD9335                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WCD934X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WCD938X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WCD938X_SDW                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WCD_CLASSH                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WCD_MBHC                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM5102                           policy<{'amd64': 'm'}>
+CONFIG_SND_SOC_WM8510                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8523                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8524                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8580                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8711                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8728                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8731                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8731_I2C                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8731_SPI                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8737                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8741                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8750                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8753                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8770                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8776                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8782                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8804                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8804_I2C                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8804_SPI                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8903                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8904                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8940                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8960                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8961                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8962                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8974                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8978                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8985                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM8994                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_WM9712                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_WM_ADSP                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WM_HUBS                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_WSA881X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WSA883X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_WSA884X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_X1E80100                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SOC_XILINX_AUDIO_FORMATTER           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_XILINX_I2S                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_XILINX_SPDIF                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_XTFPGA_I2S                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SOC_ZL38060                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SONICVIBES                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_SPI                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_SST_ATOM_HIFI2_PLATFORM              policy<{'amd64': 'm'}>
+CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI         policy<{'amd64': 'm'}>
+CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_PCI          policy<{'amd64': 'm'}>
+CONFIG_SND_SUN4I_CODEC                          policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_SND_SUN4I_I2S                            policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_SND_SUN4I_SPDIF                          policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_SND_SUN50I_CODEC_ANALOG                  policy<{'arm64': 'm'}>
+CONFIG_SND_SUN50I_DMIC                          policy<{'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SND_SUN8I_ADDA_PR_REGMAP                 policy<{'arm64': 'm'}>
+CONFIG_SND_SUN8I_CODEC                          policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SND_SUN8I_CODEC_ANALOG                   policy<{'arm64': 'm', 'armhf': '-'}>
+CONFIG_SND_SUPPORT_OLD_API                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_SYNTH_EMUX                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_TEST_COMPONENT                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_TIMER                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_TRIDENT                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SND_UMP                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_UMP_LEGACY_RAWMIDI                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_USB                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_USB_6FIRE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_USB_AUDIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_USB_AUDIO_MIDI_V2                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_USB_AUDIO_USE_MEDIA_CONTROLLER       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_USB_CAIAQ                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_USB_CAIAQ_INPUT                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_USB_HIFACE                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_USB_LINE6                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_USB_POD                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_USB_PODHD                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_USB_TONEPORT                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_USB_UA101                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_USB_US122L                           policy<{'amd64': 'm'}>
+CONFIG_SND_USB_USX2Y                            policy<{'amd64': 'm', 'ppc64el': 'm'}>
+CONFIG_SND_USB_VARIAX                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_VERBOSE_PRINTK                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SND_VERBOSE_PROCFS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_VIA82XX                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_VIA82XX_MODEM                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_VIRMIDI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_VIRTIO                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_VIRTUOSO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_VMASTER                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SND_VX222                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_VXPOCKET                             policy<{'amd64': 'm'}>
+CONFIG_SND_VX_LIB                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SND_X86                                  policy<{'amd64': 'y'}>
+CONFIG_SND_XEN_FRONTEND                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_SND_YMFPCI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SNET_VDPA                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SNI_NETSEC                               policy<{'arm64': 'm'}>
+CONFIG_SOCFPGA_FPGA_BRIDGE                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SOCFPGA_SUSPEND                          policy<{'armhf': 'y'}>
+CONFIG_SOCIONEXT_SYNQUACER_PREITS               policy<{'arm64': 'y'}>
+CONFIG_SOCK_CGROUP_DATA                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SOCK_RX_QUEUE_MAPPING                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SOCK_VALIDATE_XMIT                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SOC_AM33XX                               policy<{'armhf': 'n'}>
+CONFIG_SOC_AM43XX                               policy<{'armhf': 'n'}>
+CONFIG_SOC_BUS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SOC_DRA7XX                               policy<{'armhf': 'y'}>
+CONFIG_SOC_HAS_OMAP2_SDRC                       policy<{'armhf': 'y'}>
+CONFIG_SOC_HAS_REALTIME_COUNTER                 policy<{'armhf': 'y'}>
+CONFIG_SOC_IMX5                                 policy<{'armhf': 'y'}>
+CONFIG_SOC_IMX50                                policy<{'armhf': 'y'}>
+CONFIG_SOC_IMX51                                policy<{'armhf': 'y'}>
+CONFIG_SOC_IMX53                                policy<{'armhf': 'n'}>
+CONFIG_SOC_IMX6                                 policy<{'armhf': 'y'}>
+CONFIG_SOC_IMX6Q                                policy<{'armhf': 'y'}>
+CONFIG_SOC_IMX6SL                               policy<{'armhf': 'y'}>
+CONFIG_SOC_IMX6SLL                              policy<{'armhf': 'y'}>
+CONFIG_SOC_IMX6SX                               policy<{'armhf': 'y'}>
+CONFIG_SOC_IMX6UL                               policy<{'armhf': 'y'}>
+CONFIG_SOC_IMX7D                                policy<{'armhf': 'y'}>
+CONFIG_SOC_IMX7D_CA7                            policy<{'armhf': 'y'}>
+CONFIG_SOC_IMX7ULP                              policy<{'armhf': 'y'}>
+CONFIG_SOC_IMX8M                                policy<{'arm64': 'y', 'armhf': 'n'}>
+CONFIG_SOC_IMX9                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SOC_LS1021A                              policy<{'armhf': 'n'}>
+CONFIG_SOC_MICROCHIP_POLARFIRE                  policy<{'riscv64': 'y'}>
+CONFIG_SOC_OMAP5                                policy<{'armhf': 'n'}>
+CONFIG_SOC_RENESAS                              policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_SOC_SAMSUNG                              policy<{'armhf': 'y'}>
+CONFIG_SOC_SIFIVE                               policy<{'riscv64': 'y'}>
+CONFIG_SOC_SP7021                               policy<{'armhf': 'y'}>
+CONFIG_SOC_STARFIVE                             policy<{'riscv64': 'y'}>
+CONFIG_SOC_TEGRA20_VOLTAGE_COUPLER              policy<{'armhf': 'y'}>
+CONFIG_SOC_TEGRA30_VOLTAGE_COUPLER              policy<{'armhf': 'y'}>
+CONFIG_SOC_TEGRA_CBB                            policy<{'arm64': 'm'}>
+CONFIG_SOC_TEGRA_FLOWCTRL                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SOC_TEGRA_FUSE                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SOC_TEGRA_PMC                            policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SOC_TEGRA_POWERGATE_BPMP                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SOC_TI                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_SOC_VF610                                policy<{'armhf': 'y'}>
+CONFIG_SOC_VIRT                                 policy<{'riscv64': 'y'}>
+CONFIG_SOFTIRQ_ON_OWN_STACK                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SOFTLOCKUP_DETECTOR                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SOFT_WATCHDOG                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SOFT_WATCHDOG_PRETIMEOUT                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SOLARIS_X86_PARTITION                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_SONYPI_COMPAT                            policy<{'amd64': 'y'}>
+CONFIG_SONY_FF                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SONY_LAPTOP                              policy<{'amd64': 'm'}>
+CONFIG_SOUNDWIRE_AMD                            policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SOUNDWIRE_CADENCE                        policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SOUNDWIRE_GENERIC_ALLOCATION             policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SOUNDWIRE_INTEL                          policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SOUNDWIRE_QCOM                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SOUND_OSS_CORE                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SP5100_TCO                               policy<{'amd64': 'm'}>
+CONFIG_SP7021_EMAC                              policy<{'armhf': 'm'}>
+CONFIG_SPAPR_TCE_IOMMU                          policy<{'ppc64el': 'y'}>
+CONFIG_SPARSEMEM                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SPARSEMEM_EXTREME                        policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SPARSEMEM_MANUAL                         policy<{'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SPARSEMEM_STATIC                         policy<{'armhf': 'y'}>
+CONFIG_SPARSEMEM_VMEMMAP                        policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SPARSEMEM_VMEMMAP_ENABLE                 policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SPARSE_IRQ                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SPARX5_DCB                               policy<{'arm64': 'y'}>
+CONFIG_SPARX5_SWITCH                            policy<{'amd64': '-', 'arm64': 'm', 'armhf': '-', 'ppc64el': '-'}>
+CONFIG_SPEAKUP                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPEAKUP_SYNTH_ACNTSA                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPEAKUP_SYNTH_APOLLO                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPEAKUP_SYNTH_AUDPTR                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPEAKUP_SYNTH_BNS                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPEAKUP_SYNTH_DECEXT                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPEAKUP_SYNTH_DECTLK                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPEAKUP_SYNTH_DUMMY                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPEAKUP_SYNTH_LTLK                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPEAKUP_SYNTH_SOFT                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPEAKUP_SYNTH_SPKOUT                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPEAKUP_SYNTH_TXPRT                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_SPI_ALTERA                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_ALTERA_CORE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_ALTERA_DFL                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_AMD                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_AMLOGIC_SPIFC_A1                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_ARMADA_3700                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_ASPEED_SMC                           policy<{'armhf': 'm'}>
+CONFIG_SPI_AX88796C                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_AX88796C_COMPRESSION                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SPI_AXI_SPI_ENGINE                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_BITBANG                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_BUTTERFLY                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_CADENCE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_CADENCE_QUADSPI                      policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_CADENCE_XSPI                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_CS42L43                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_SPI_DESIGNWARE                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_DLN2                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_DW_DMA                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SPI_DW_MMIO                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_DW_PCI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_DYNAMIC                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SPI_FSI                                  policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_FSL_DSPI                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_FSL_LIB                              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SPI_FSL_LPSPI                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_FSL_QUADSPI                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_FSL_SPI                              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SPI_GPIO                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_GXP                                  policy<{'armhf': 'm'}>
+CONFIG_SPI_HISI_KUNPENG                         policy<{'arm64': 'm'}>
+CONFIG_SPI_HISI_SFC                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_HISI_SFC_V3XX                        policy<{'arm64': 'm'}>
+CONFIG_SPI_IMX                                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_INTEL                                policy<{'amd64': 'm'}>
+CONFIG_SPI_INTEL_PCI                            policy<{'amd64': 'm'}>
+CONFIG_SPI_INTEL_PLATFORM                       policy<{'amd64': 'm'}>
+CONFIG_SPI_LANTIQ_SSC                           policy<{'amd64': 'm'}>
+CONFIG_SPI_LJCA                                 policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_LM70_LLP                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_LOOPBACK_TEST                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_MASTER                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SPI_MEM                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SPI_MESON_SPICC                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_MESON_SPIFC                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_MICROCHIP_CORE                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_MICROCHIP_CORE_QSPI                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_MT65XX                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_MTK_NOR                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_MTK_SNFI                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_MUX                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_MXIC                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_NPCM_FIU                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_NPCM_PSPI                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_NXP_FLEXSPI                          policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': '-', 's390x': '-'}>
+CONFIG_SPI_OC_TINY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_OMAP24XX                             policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SPI_ORION                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_PCI1XXXX                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_PL022                                policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_PXA2XX                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_PXA2XX_PCI                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_QCOM_GENI                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_QCOM_QSPI                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_QUP                                  policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_ROCKCHIP                             policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': '-', 's390x': '-'}>
+CONFIG_SPI_ROCKCHIP_SFC                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_RPCIF                                policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_RSPI                                 policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_RZV2M_CSI                            policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_S3C64XX                              policy<{'armhf': 'n'}>
+CONFIG_SPI_SC18IS602                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_SH_HSPI                              policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_SH_MSIOF                             policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_SIFIVE                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_SPI_SLAVE                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SPI_SLAVE_MT27XX                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_SLAVE_SYSTEM_CONTROL                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_SLAVE_TIME                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_SN_F_OSPI                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPI_SPIDEV                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_SPRD                                 policy<{'arm64': 'm'}>
+CONFIG_SPI_SPRD_ADI                             policy<{'arm64': 'm'}>
+CONFIG_SPI_STM32                                policy<{'arm64': 'm'}>
+CONFIG_SPI_STM32_QSPI                           policy<{'arm64': 'm'}>
+CONFIG_SPI_SUN4I                                policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_SPI_SUN6I                                policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_SPI_SUNPLUS_SP7021                       policy<{'armhf': 'm'}>
+CONFIG_SPI_SYNQUACER                            policy<{'arm64': 'm'}>
+CONFIG_SPI_TEGRA114                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_TEGRA20_SFLASH                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_TEGRA20_SLINK                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_TEGRA210_QUAD                        policy<{'arm64': 'y', 'armhf': 'm'}>
+CONFIG_SPI_THUNDERX                             policy<{'arm64': 'm'}>
+CONFIG_SPI_TI_QSPI                              policy<{'armhf': 'm'}>
+CONFIG_SPI_TLE62X0                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_WPCM_FIU                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPI_XCOMM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_XILINX                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPI_XLP                                  policy<{'arm64': 'm'}>
+CONFIG_SPI_ZYNQMP_GQSPI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SPLIT_PTLOCK_CPUS                        policy<{'amd64': '4', 'arm64': '4', 'armhf': '4', 'ppc64el': '4', 'riscv64': '4', 's390x': '4'}>
+CONFIG_SPMI                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SPMI_HISI3670                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPMI_MSM_PMIC_ARB                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPMI_MTK_PMIF                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPMI_PMIC_CLKDIV                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_SPRD_COMMON_CLK                          policy<{'arm64': 'm'}>
+CONFIG_SPRD_DMA                                 policy<{'arm64': 'm'}>
+CONFIG_SPRD_IOMMU                               policy<{'arm64': 'm'}>
+CONFIG_SPRD_MBOX                                policy<{'arm64': 'm'}>
+CONFIG_SPRD_SC9860_CLK                          policy<{'arm64': 'm'}>
+CONFIG_SPRD_SC9863A_CLK                         policy<{'arm64': 'm'}>
+CONFIG_SPRD_THERMAL                             policy<{'arm64': 'm'}>
+CONFIG_SPRD_TIMER                               policy<{'arm64': 'y'}>
+CONFIG_SPRD_UMS512_CLK                          policy<{'arm64': 'm'}>
+CONFIG_SPRD_WATCHDOG                            policy<{'arm64': 'm'}>
+CONFIG_SPS30                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPS30_I2C                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SPS30_SERIAL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SQUASHFS_DECOMP_MULTI                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SQUASHFS_DECOMP_SINGLE                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SQUASHFS_EMBEDDED                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SQUASHFS_FILE_CACHE                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SQUASHFS_FILE_DIRECT                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE             policy<{'amd64': '3', 'arm64': '3', 'armhf': '3', 'ppc64el': '3', 'riscv64': '3', 's390x': '3'}>
+CONFIG_SQUASHFS_LZ4                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SQUASHFS_LZO                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SQUASHFS_MOUNT_DECOMP_THREADS            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SQUASHFS_XATTR                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SQUASHFS_XZ                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SQUASHFS_ZLIB                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SQUASHFS_ZSTD                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SRAM                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_SRAM_EXEC                                policy<{'armhf': 'y'}>
+CONFIG_SRF04                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SRF08                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SSB                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SSB_B43_PCI_BRIDGE                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SSB_BLOCKIO                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SSB_DRIVER_GPIO                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_SSB_DRIVER_PCICORE                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SSB_DRIVER_PCICORE_POSSIBLE              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SSB_PCIHOST                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_SSB_PCIHOST_POSSIBLE                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SSB_PCMCIAHOST                           policy<{'amd64': 'n'}>
+CONFIG_SSB_PCMCIAHOST_POSSIBLE                  policy<{'amd64': 'y'}>
+CONFIG_SSB_POSSIBLE                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SSB_SDIOHOST                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SSB_SDIOHOST_POSSIBLE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SSB_SPROM                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SSFDC                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SSIF_IPMI_BMC                            policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_STACKDEPOT                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_STACKDEPOT_MAX_FRAMES                    policy<{'amd64': '64', 'arm64': '64', 'armhf': '64', 'ppc64el': '64', 'riscv64': '64', 's390x': '64'}>
+CONFIG_STACKPROTECTOR                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_STACKPROTECTOR_PER_TASK                  policy<{'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_STACKPROTECTOR_STRONG                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_STACKTRACE                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_STACKTRACE_BUILD_ID                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_STACKTRACE_SUPPORT                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_STACK_TRACER                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_STAGING                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_STAGING_BOARD                            policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_STAGING_MEDIA                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_STAGING_MEDIA_DEPRECATED                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_STANDALONE                               policy<{'amd64': 'n', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_STARFIVE_WATCHDOG                        policy<{'riscv64': 'y'}>
+CONFIG_STATIC_CALL_SELFTEST                     policy<{'amd64': 'n'}>
+CONFIG_STATIC_KEYS_SELFTEST                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': '-', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_STATIC_USERMODEHELPER                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_STE10XP                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_STEAM_FF                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_STK3310                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_STK8312                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_STK8BA50                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_STM                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_STM32_ADC                                policy<{'arm64': 'm'}>
+CONFIG_STM32_ADC_CORE                           policy<{'arm64': 'm'}>
+CONFIG_STM32_DAC                                policy<{'arm64': 'm'}>
+CONFIG_STM32_DAC_CORE                           policy<{'arm64': 'm'}>
+CONFIG_STM32_DFSDM_ADC                          policy<{'arm64': 'm'}>
+CONFIG_STM32_DFSDM_CORE                         policy<{'arm64': 'm'}>
+CONFIG_STM32_DMA                                policy<{'arm64': 'y'}>
+CONFIG_STM32_DMAMUX                             policy<{'arm64': 'y'}>
+CONFIG_STM32_FMC2_EBI                           policy<{'arm64': 'm'}>
+CONFIG_STM32_LPTIMER_CNT                        policy<{'arm64': 'm'}>
+CONFIG_STM32_MDMA                               policy<{'arm64': 'y'}>
+CONFIG_STM32_RPROC                              policy<{'arm64': 'm'}>
+CONFIG_STM32_TIMER_CNT                          policy<{'arm64': 'm'}>
+CONFIG_STM32_WATCHDOG                           policy<{'arm64': 'm'}>
+CONFIG_STMMAC_ETH                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_STMMAC_PCI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_STMMAC_PLATFORM                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_STMMAC_SELFTESTS                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_STMPE_ADC                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_STMPE_I2C                                policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_STMPE_SPI                                policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_STMP_DEVICE                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_STM_DUMMY                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_STM_PROTO_BASIC                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_STM_PROTO_SYS_T                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_STM_SOURCE_CONSOLE                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_STM_SOURCE_FTRACE                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_STM_SOURCE_HEARTBEAT                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_STP                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_STPMIC1_WATCHDOG                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_STREAM_PARSER                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_STRICT_DEVMEM                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_STRICT_KERNEL_RWX                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_STRICT_MODULE_RWX                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_STRICT_SIGALTSTACK_SIZE                  policy<{'amd64': 'n'}>
+CONFIG_STRING_SELFTEST                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_STRIP_ASM_SYMS                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_STUB_CLK_HI3660                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_STUB_CLK_HI6220                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_STX104                                   policy<{'amd64': 'm'}>
+CONFIG_ST_THERMAL                               policy<{'arm64': 'm'}>
+CONFIG_ST_THERMAL_MEMMAP                        policy<{'arm64': 'm'}>
+CONFIG_ST_UVIS25                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ST_UVIS25_I2C                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ST_UVIS25_SPI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SUN20I_D1_CCU                            policy<{'riscv64': 'y'}>
+CONFIG_SUN20I_D1_R_CCU                          policy<{'riscv64': 'y'}>
+CONFIG_SUN20I_GPADC                             policy<{'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_SUN20I_PPU                               policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_SUN4I_EMAC                               policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_SUN4I_GPADC                              policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_SUN4I_TIMER                              policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_SUN50I_A100_CCU                          policy<{'arm64': 'y'}>
+CONFIG_SUN50I_A100_R_CCU                        policy<{'arm64': 'y'}>
+CONFIG_SUN50I_A64_CCU                           policy<{'arm64': 'y'}>
+CONFIG_SUN50I_DE2_BUS                           policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_SUN50I_ERRATUM_UNKNOWN1                  policy<{'arm64': 'y'}>
+CONFIG_SUN50I_H616_CCU                          policy<{'arm64': 'y'}>
+CONFIG_SUN50I_H6_CCU                            policy<{'arm64': 'y'}>
+CONFIG_SUN50I_H6_R_CCU                          policy<{'arm64': 'y'}>
+CONFIG_SUN50I_IOMMU                             policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_SUN6I_MSGBOX                             policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_SUN6I_R_INTC                             policy<{'arm64': 'y'}>
+CONFIG_SUN8I_DE2_CCU                            policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_SUN8I_H3_CCU                             policy<{'arm64': 'y', 'armhf': '-'}>
+CONFIG_SUN8I_R_CCU                              policy<{'arm64': 'y', 'armhf': '-'}>
+CONFIG_SUN8I_THERMAL                            policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_SUNDANCE                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SUNDANCE_MMIO                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_SUNGEM                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SUNGEM_PHY                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SUNPLUS_SP7021_INTC                      policy<{'armhf': 'y'}>
+CONFIG_SUNPLUS_WATCHDOG                         policy<{'armhf': 'm'}>
+CONFIG_SUNRPC                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SUNRPC_BACKCHANNEL                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SUNRPC_DEBUG                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SUNRPC_GSS                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SUNRPC_SWAP                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SUNRPC_XPRT_RDMA                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_SUNXI_CCU                                policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_SUNXI_MBUS                               policy<{'arm64': 'y'}>
+CONFIG_SUNXI_NMI_INTC                           policy<{'arm64': 'y'}>
+CONFIG_SUNXI_RSB                                policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_SUNXI_SRAM                               policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_SUNXI_WATCHDOG                           policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_SUN_PARTITION                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_SURFACE3_WMI                             policy<{'amd64': 'm'}>
+CONFIG_SURFACE_3_POWER_OPREGION                 policy<{'amd64': 'm', 'arm64': 'n'}>
+CONFIG_SURFACE_ACPI_NOTIFY                      policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SURFACE_AGGREGATOR                       policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SURFACE_AGGREGATOR_BUS                   policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_SURFACE_AGGREGATOR_CDEV                  policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SURFACE_AGGREGATOR_ERROR_INJECTION       policy<{'amd64': 'n', 'arm64': 'n'}>
+CONFIG_SURFACE_AGGREGATOR_HUB                   policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SURFACE_AGGREGATOR_REGISTRY              policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SURFACE_AGGREGATOR_TABLET_SWITCH         policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SURFACE_DTX                              policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SURFACE_GPE                              policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SURFACE_HID                              policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SURFACE_HID_CORE                         policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SURFACE_HOTPLUG                          policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SURFACE_KBD                              policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SURFACE_PLATFORMS                        policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_SURFACE_PLATFORM_PROFILE                 policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_SURFACE_PRO3_BUTTON                      policy<{'amd64': 'm', 'arm64': 'n'}>
+CONFIG_SUSPEND                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SUSPEND_FREEZER                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_SUSPEND_SKIP_SYNC                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_SVC_I3C_MASTER                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SWAP                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SWIOTLB                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SWIOTLB_DYNAMIC                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SWIOTLB_XEN                              policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_SWPHY                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SWP_EMULATE                              policy<{'armhf': 'y'}>
+CONFIG_SW_SYNC                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SX9310                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SX9324                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SX9360                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SX9500                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SXGBE_ETH                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SX_COMMON                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SYMBOLIC_ERRNAME                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYNC_FILE                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYNTH_EVENTS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYNTH_EVENT_GEN_TEST                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SYN_COOKIES                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYSCON_REBOOT_MODE                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_SYSCTL                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYSCTL_ARCH_UNALIGN_ALLOW                policy<{'riscv64': 'y'}>
+CONFIG_SYSCTL_EXCEPTION_TRACE                   policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYSC_R8A7742                             policy<{'armhf': 'y'}>
+CONFIG_SYSC_R8A7743                             policy<{'armhf': 'y'}>
+CONFIG_SYSC_R8A7745                             policy<{'armhf': 'y'}>
+CONFIG_SYSC_R8A77470                            policy<{'armhf': 'y'}>
+CONFIG_SYSC_R8A774A1                            policy<{'arm64': 'y'}>
+CONFIG_SYSC_R8A774B1                            policy<{'arm64': 'y'}>
+CONFIG_SYSC_R8A774C0                            policy<{'arm64': 'y'}>
+CONFIG_SYSC_R8A774E1                            policy<{'arm64': 'y'}>
+CONFIG_SYSC_R8A7779                             policy<{'armhf': 'y'}>
+CONFIG_SYSC_R8A7790                             policy<{'armhf': 'y'}>
+CONFIG_SYSC_R8A7791                             policy<{'armhf': 'y'}>
+CONFIG_SYSC_R8A7792                             policy<{'armhf': 'y'}>
+CONFIG_SYSC_R8A7794                             policy<{'armhf': 'y'}>
+CONFIG_SYSC_R8A7795                             policy<{'arm64': 'y'}>
+CONFIG_SYSC_R8A77960                            policy<{'arm64': 'y'}>
+CONFIG_SYSC_R8A77961                            policy<{'arm64': 'y'}>
+CONFIG_SYSC_R8A77965                            policy<{'arm64': 'y'}>
+CONFIG_SYSC_R8A77970                            policy<{'arm64': 'y'}>
+CONFIG_SYSC_R8A77980                            policy<{'arm64': 'y'}>
+CONFIG_SYSC_R8A77990                            policy<{'arm64': 'y'}>
+CONFIG_SYSC_R8A77995                            policy<{'arm64': 'y'}>
+CONFIG_SYSC_R8A779A0                            policy<{'arm64': 'y'}>
+CONFIG_SYSC_R8A779F0                            policy<{'arm64': 'y'}>
+CONFIG_SYSC_R8A779G0                            policy<{'arm64': 'y'}>
+CONFIG_SYSC_RCAR                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SYSC_RCAR_GEN4                           policy<{'arm64': 'y'}>
+CONFIG_SYSC_RMOBILE                             policy<{'armhf': 'y'}>
+CONFIG_SYSFB                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_SYSFS                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYSFS_SYSCALL                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYSTEM76_ACPI                            policy<{'amd64': 'm'}>
+CONFIG_SYSTEMPORT                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_SYSTEM_BLACKLIST_AUTH_UPDATE             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_SYSTEM_BLACKLIST_HASH_LIST               policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'ppc64el': '""', 'riscv64': '""', 's390x': '""'}>
+CONFIG_SYSTEM_BLACKLIST_KEYRING                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYSTEM_DATA_VERIFICATION                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYSTEM_EXTRA_CERTIFICATE                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYSTEM_EXTRA_CERTIFICATE_SIZE            policy<{'amd64': '4096', 'arm64': '4096', 'armhf': '4096', 'ppc64el': '4096', 'riscv64': '4096', 's390x': '4096'}>
+CONFIG_SYSTEM_REVOCATION_KEYS                   policy<{'amd64': '"debian/canonical-revoked-certs.pem"', 'arm64': '"debian/canonical-revoked-certs.pem"', 'armhf': '"debian/canonical-revoked-certs.pem"', 'ppc64el': '"debian/canonical-revoked-certs.pem"', 'riscv64': '"debian/canonical-revoked-certs.pem"', 's390x': '"debian/canonical-revoked-certs.pem"'}>
+CONFIG_SYSTEM_REVOCATION_LIST                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYSTEM_TRUSTED_KEYRING                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYSTEM_TRUSTED_KEYS                      policy<{'amd64': '"debian/canonical-certs.pem"', 'arm64': '"debian/canonical-certs.pem"', 'armhf': '"debian/canonical-certs.pem"', 'ppc64el': '"debian/canonical-certs.pem"', 'riscv64': '"debian/canonical-certs.pem"', 's390x': '"debian/canonical-certs.pem"'}>
+CONFIG_SYSV68_PARTITION                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_SYSVIPC                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYSVIPC_COMPAT                           policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': '-', 'ppc64el': '-', 's390x': '-'}>
+CONFIG_SYSVIPC_SYSCTL                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_SYSV_FS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_SYS_HYPERVISOR                           policy<{'amd64': 'y', 'arm64': 'y', 's390x': 'y'}>
+CONFIG_SYS_SUPPORTS_APM_EMULATION               policy<{'armhf': 'y'}>
+CONFIG_SYS_SUPPORTS_EM_STI                      policy<{'armhf': 'y'}>
+CONFIG_SYS_SUPPORTS_SH_CMT                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_SYS_SUPPORTS_SH_MTU2                     policy<{'armhf': 'y'}>
+CONFIG_SYS_SUPPORTS_SH_TMU                      policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_T5403                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TABLET_SERIAL_WACOM4                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TABLET_USB_ACECAD                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TABLET_USB_AIPTEK                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TABLET_USB_HANWANG                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TABLET_USB_KBTAB                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TABLET_USB_PEGASUS                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TAHVO_USB                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TAHVO_USB_HOST_BY_DEFAULT                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TAP                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TARGET_CORE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TARGET_CPU                               policy<{'ppc64el': '"power8"'}>
+CONFIG_TARGET_CPU_BOOL                          policy<{'ppc64el': 'y'}>
+CONFIG_TASKSTATS                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TASKS_RCU                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': '-', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_TASKS_RCU_GENERIC                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TASKS_RUDE_RCU                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': '-', 's390x': 'y'}>
+CONFIG_TASKS_TRACE_RCU                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TASK_DELAY_ACCT                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TASK_IO_ACCOUNTING                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TASK_XACCT                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TCG_ATMEL                                policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TCG_CRB                                  policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_TCG_FTPM_TEE                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TCG_IBMVTPM                              policy<{'ppc64el': 'y'}>
+CONFIG_TCG_INFINEON                             policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_TCG_NSC                                  policy<{'amd64': 'm'}>
+CONFIG_TCG_TIS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TCG_TIS_CORE                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TCG_TIS_I2C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_TCG_TIS_I2C_CR50                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_TCG_TIS_SPI                              policy<{'amd64': 'm', 'arm64': 'y', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TCG_TIS_SPI_CR50                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TCG_TIS_ST33ZP24                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TCG_TIS_ST33ZP24_I2C                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_TCG_TIS_ST33ZP24_SPI                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TCG_TIS_SYNQUACER                        policy<{'arm64': 'm'}>
+CONFIG_TCG_VTPM_PROXY                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCG_XEN                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_TCM_FC                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCM_FILEIO                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCM_IBLOCK                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCM_PSCSI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCM_QLA2XXX                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TCM_QLA2XXX_DEBUG                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_TCM_USER2                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_AO                                   policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TCP_CONG_ADVANCED                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TCP_CONG_BBR                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_CONG_BIC                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_CONG_CDG                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_CONG_CUBIC                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TCP_CONG_DCTCP                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_CONG_HSTCP                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_CONG_HTCP                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_CONG_HYBLA                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_CONG_ILLINOIS                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_CONG_LP                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_CONG_NV                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_CONG_SCALABLE                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_CONG_VEGAS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_CONG_VENO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_CONG_WESTWOOD                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_CONG_YEAH                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TCP_MD5SIG                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TCP_SIGPOOL                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TCS3414                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TCS3472                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TDX_GUEST_DRIVER                         policy<{'amd64': 'm'}>
+CONFIG_TEE                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TEE_STMM_EFI                             policy<{'arm64-generic': 'n', 'arm64-generic-64k': 'm', 'armhf': 'm'}>
+CONFIG_TEGRA124_CLK_EMC                         policy<{'armhf': 'y'}>
+CONFIG_TEGRA124_EMC                             policy<{'armhf': 'y'}>
+CONFIG_TEGRA186_GPC_DMA                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TEGRA186_TIMER                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_TEGRA20_APB_DMA                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_TEGRA20_EMC                              policy<{'armhf': 'y'}>
+CONFIG_TEGRA210_ADMA                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TEGRA210_EMC                             policy<{'arm64': 'm'}>
+CONFIG_TEGRA210_EMC_TABLE                       policy<{'arm64': 'y'}>
+CONFIG_TEGRA30_EMC                              policy<{'armhf': 'y'}>
+CONFIG_TEGRA30_TSENSOR                          policy<{'armhf': 'm'}>
+CONFIG_TEGRA_ACONNECT                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TEGRA_AHB                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_TEGRA_BPMP                               policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_TEGRA_BPMP_THERMAL                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TEGRA_CLK_DFLL                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_TEGRA_GMI                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TEGRA_HOST1X                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TEGRA_HOST1X_CONTEXT_BUS                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_TEGRA_HOST1X_FIREWALL                    policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_TEGRA_HSP_MBOX                           policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_TEGRA_IOMMU_SMMU                         policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_TEGRA_IVC                                policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_TEGRA_MC                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_TEGRA_SOCTHERM                           policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_TEGRA_TIMER                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_TEGRA_WATCHDOG                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TEHUTI                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TELCLOCK                                 policy<{'amd64': 'm'}>
+CONFIG_TERANETICS_PHY                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TEST_ASYNC_DRIVER_PROBE                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_BITMAP                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_BITOPS                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_BPF                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TEST_CLOCKSOURCE_WATCHDOG                policy<{'amd64': 'n'}>
+CONFIG_TEST_DHRY                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_DIV64                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_DYNAMIC_DEBUG                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_FIRMWARE                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_FPU                                 policy<{'amd64': 'n'}>
+CONFIG_TEST_FREE_PAGES                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_HEXDUMP                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_HMM                                 policy<{'amd64': 'n', 'arm64': 'n', 'ppc64el': 'n'}>
+CONFIG_TEST_IDA                                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_KMOD                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_KSTRTOX                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_LIVEPATCH                           policy<{'amd64': 'n', 'ppc64el': 'n', 's390x': 'n'}>
+CONFIG_TEST_LKM                                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_LOCKUP                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_MAPLE_TREE                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_MEMCAT_P                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_MEMINIT                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_MIN_HEAP                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_OBJAGG                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_OBJPOOL                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_PARMAN                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_POWER                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TEST_PRINTF                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_REF_TRACKER                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_RHASHTABLE                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_SCANF                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_STATIC_KEYS                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_STRING_HELPERS                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_SYSCTL                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_UBSAN                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 's390x': 'n'}>
+CONFIG_TEST_UDELAY                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_USER_COPY                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_UUID                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_VMALLOC                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEST_XARRAY                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TEXTSEARCH                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TEXTSEARCH_BM                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TEXTSEARCH_FSM                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TEXTSEARCH_KMP                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_THERMAL                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_THERMAL_DEBUGFS                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_THERMAL_DEFAULT_GOV_BANG_BANG            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS      policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0'}>
+CONFIG_THERMAL_EMULATION                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_THERMAL_GOV_BANG_BANG                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_THERMAL_GOV_FAIR_SHARE                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_THERMAL_GOV_POWER_ALLOCATOR              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_THERMAL_GOV_STEP_WISE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_THERMAL_GOV_USER_SPACE                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_THERMAL_HWMON                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_THERMAL_MMIO                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_THERMAL_NETLINK                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_THERMAL_OF                               policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_THERMAL_STATISTICS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_THERMAL_WRITABLE_TRIPS                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_THINKPAD_ACPI                            policy<{'amd64': 'm'}>
+CONFIG_THINKPAD_ACPI_ALSA_SUPPORT               policy<{'amd64': 'y'}>
+CONFIG_THINKPAD_ACPI_DEBUG                      policy<{'amd64': 'n'}>
+CONFIG_THINKPAD_ACPI_DEBUGFACILITIES            policy<{'amd64': 'y'}>
+CONFIG_THINKPAD_ACPI_HOTKEY_POLL                policy<{'amd64': 'y'}>
+CONFIG_THINKPAD_ACPI_UNSAFE_LEDS                policy<{'amd64': 'n'}>
+CONFIG_THINKPAD_ACPI_VIDEO                      policy<{'amd64': 'y'}>
+CONFIG_THINKPAD_LMI                             policy<{'amd64': 'm'}>
+CONFIG_THP_SWAP                                 policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': '-', 'riscv64': 'y'}>
+CONFIG_THREAD_INFO_IN_TASK                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_THREAD_SHIFT                             policy<{'ppc64el': '14'}>
+CONFIG_THREAD_SIZE_ORDER                        policy<{'riscv64': '2'}>
+CONFIG_THRUSTMASTER_FF                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_THUMB2_KERNEL                            policy<{'armhf': 'n'}>
+CONFIG_THUNDERX2_PMU                            policy<{'arm64': 'm'}>
+CONFIG_THUNDER_NIC_BGX                          policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_THUNDER_NIC_PF                           policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_THUNDER_NIC_RGX                          policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_THUNDER_NIC_VF                           policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TICK_CPU_ACCOUNTING                      policy<{'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_TICK_ONESHOT                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TIFM_7XX1                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TIFM_CORE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_TIGON3                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TIGON3_HWMON                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TIMERFD                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TIMER_ACPI                               policy<{'arm64': 'y'}>
+CONFIG_TIMER_IMX_SYS_CTR                        policy<{'arm64': 'y'}>
+CONFIG_TIMER_OF                                 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': '-', 'riscv64': 'y'}>
+CONFIG_TIMER_PROBE                              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': '-', 'riscv64': 'y'}>
+CONFIG_TIME_NS                                  policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TINYDRM_HX8357D                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TINYDRM_ILI9163                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TINYDRM_ILI9225                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TINYDRM_ILI9341                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TINYDRM_ILI9486                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TINYDRM_MI0283QT                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TINYDRM_REPAPER                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TINYDRM_ST7586                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TINYDRM_ST7735R                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TIPC                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TIPC_CRYPTO                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TIPC_DIAG                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TIPC_MEDIA_IB                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TIPC_MEDIA_UDP                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TI_ADC081C                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_ADC0832                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_ADC084S021                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_ADC108S102                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_ADC12138                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_ADC128S052                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_ADC161S626                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_ADS1015                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_ADS1100                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_ADS124S08                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_ADS131E08                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_ADS7924                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_ADS7950                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_ADS8344                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_ADS8688                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_AM335X_ADC                            policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_TI_AM65_CPSW_QOS                         policy<{'arm64': 'y'}>
+CONFIG_TI_CPPI41                                policy<{'armhf': 'm'}>
+CONFIG_TI_CPSW                                  policy<{'armhf': 'y'}>
+CONFIG_TI_CPSW_PHY_SEL                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_TI_CPSW_SWITCHDEV                        policy<{'armhf': 'm'}>
+CONFIG_TI_CPTS                                  policy<{'armhf': 'y'}>
+CONFIG_TI_DAC082S085                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_DAC5571                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_DAC7311                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_DAC7612                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_DAVINCI_MDIO                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_TI_DMA_CROSSBAR                          policy<{'armhf': 'y'}>
+CONFIG_TI_ECAP_CAPTURE                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TI_EDMA                                  policy<{'armhf': 'y'}>
+CONFIG_TI_EMIF                                  policy<{'armhf': 'm'}>
+CONFIG_TI_ICSSG_PRUETH                          policy<{'arm64': 'm'}>
+CONFIG_TI_ICSS_IEP                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TI_K3_AM65_CPSW_NUSS                     policy<{'arm64': 'm'}>
+CONFIG_TI_K3_AM65_CPSW_SWITCHDEV                policy<{'arm64': 'y'}>
+CONFIG_TI_K3_AM65_CPTS                          policy<{'arm64': 'm'}>
+CONFIG_TI_K3_CPPI_DESC_POOL                     policy<{'arm64': 'm'}>
+CONFIG_TI_K3_DSP_REMOTEPROC                     policy<{'arm64': 'm'}>
+CONFIG_TI_K3_PSIL                               policy<{'arm64': 'y'}>
+CONFIG_TI_K3_R5_REMOTEPROC                      policy<{'arm64': 'm'}>
+CONFIG_TI_K3_RINGACC                            policy<{'arm64': 'y'}>
+CONFIG_TI_K3_SOCINFO                            policy<{'arm64': 'y'}>
+CONFIG_TI_K3_UDMA                               policy<{'arm64': 'y'}>
+CONFIG_TI_K3_UDMA_GLUE_LAYER                    policy<{'arm64': 'y'}>
+CONFIG_TI_LMP92064                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_MESSAGE_MANAGER                       policy<{'arm64': 'y'}>
+CONFIG_TI_PIPE3                                 policy<{'armhf': 'm'}>
+CONFIG_TI_PRUSS                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TI_PRUSS_INTC                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TI_PWMSS                                 policy<{'armhf': 'y'}>
+CONFIG_TI_SCI_CLK                               policy<{'arm64': 'm'}>
+CONFIG_TI_SCI_CLK_PROBE_FROM_FW                 policy<{'arm64': 'n'}>
+CONFIG_TI_SCI_INTA_IRQCHIP                      policy<{'arm64': 'y'}>
+CONFIG_TI_SCI_INTA_MSI_DOMAIN                   policy<{'arm64': 'y'}>
+CONFIG_TI_SCI_INTR_IRQCHIP                      policy<{'arm64': 'y'}>
+CONFIG_TI_SCI_PM_DOMAINS                        policy<{'arm64': 'm'}>
+CONFIG_TI_SCI_PROTOCOL                          policy<{'arm64': 'y'}>
+CONFIG_TI_SOC_THERMAL                           policy<{'arm64': '-', 'armhf': 'n', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_TI_ST                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TI_SYSC                                  policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_TI_SYSCON_CLK                            policy<{'arm64': 'y'}>
+CONFIG_TI_TLC4541                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_TMAG5273                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TI_TSC2046                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TLAN                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TLS                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TLS_DEVICE                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TLS_TOE                                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TMP006                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TMP007                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TMP117                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TMPFS                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TMPFS_INODE64                            policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TMPFS_QUOTA                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TMPFS_XATTR                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TN3215                                   policy<{'s390x': 'y'}>
+CONFIG_TN3215_CONSOLE                           policy<{'s390x': 'y'}>
+CONFIG_TN3270                                   policy<{'s390x': 'y'}>
+CONFIG_TN3270_CONSOLE                           policy<{'s390x': 'y'}>
+CONFIG_TN3270_FS                                policy<{'s390x': 'm'}>
+CONFIG_TOOLCHAIN_DEFAULT_CPU                    policy<{'ppc64el': 'n'}>
+CONFIG_TOOLCHAIN_HAS_V                          policy<{'riscv64': 'y'}>
+CONFIG_TOOLCHAIN_HAS_ZBB                        policy<{'riscv64': 'y'}>
+CONFIG_TOOLCHAIN_HAS_ZIHINTPAUSE                policy<{'riscv64': 'y'}>
+CONFIG_TOOLCHAIN_NEEDS_EXPLICIT_ZICSR_ZIFENCEI  policy<{'riscv64': 'y'}>
+CONFIG_TOOLS_SUPPORT_RELR                       policy<{'amd64': 'y', 'ppc64el': 'y'}>
+CONFIG_TOPSTAR_LAPTOP                           policy<{'amd64': 'm'}>
+CONFIG_TOSHIBA_BT_RFKILL                        policy<{'amd64': 'm'}>
+CONFIG_TOSHIBA_HAPS                             policy<{'amd64': 'm'}>
+CONFIG_TOSHIBA_WMI                              policy<{'amd64': 'n'}>
+CONFIG_TOUCHSCREEN_88PM860X                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_AD7877                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_AD7879                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_AD7879_I2C                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_AD7879_SPI                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_ADC                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_ADS7846                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_AR1021_I2C                   policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_ATMEL_MXT                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_ATMEL_MXT_T37                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_AUO_PIXCIR                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_BU21013                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_BU21029                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_CHIPONE_ICN8318              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_CHIPONE_ICN8505              policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_COLIBRI_VF50                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_CY8CTMA140                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_CY8CTMG110                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_CYTTSP4_CORE                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_CYTTSP4_I2C                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_CYTTSP4_SPI                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_CYTTSP5                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_CYTTSP_CORE                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_CYTTSP_I2C                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_CYTTSP_SPI                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_DA9034                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_DA9052                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_DMI                          policy<{'amd64': 'y'}>
+CONFIG_TOUCHSCREEN_DYNAPRO                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_EDT_FT5X06                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_EETI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_EGALAX                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_EGALAX_SERIAL                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_EKTF2127                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_ELO                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_EXC3000                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_FUJITSU                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_GOODIX                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_GUNZE                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_HAMPSHIRE                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_HIDEEP                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_HIMAX_HX83112B               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_HYCON_HY46XX                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_HYNITRON_CSTXXX              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_ILI210X                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_ILITEK                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_IMAGIS                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_IMX6UL_TSC                   policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_INEXIO                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_IQS5XX                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_IQS7211                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_MAX11801                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_MC13783                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_MCS5000                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_MELFAS_MIP4                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_MMS114                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_MSG2638                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_MTOUCH                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_NOVATEK_NVT_TS               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_PCAP                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_PENMOUNT                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_PIXCIR                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_RM_TS                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_ROHM_BU21023                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_S6SY761                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_SILEAD                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_SIS_I2C                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_ST1232                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_STMFTS                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_STMPE                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_SUN4I                        policy<{'arm64': 'n', 'armhf': '-', 'riscv64': 'n'}>
+CONFIG_TOUCHSCREEN_SUR40                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_SURFACE3_SPI                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_SX8654                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_TI_AM335X_TSC                policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_TOUCHSCREEN_TOUCHIT213                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_TOUCHRIGHT                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_TOUCHWIN                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_TPS6507X                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_TS4800                       policy<{'armhf': 'm'}>
+CONFIG_TOUCHSCREEN_TSC2004                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_TSC2005                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_TSC2007                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_TSC2007_IIO                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_TSC200X_CORE                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_TSC_SERIO                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_USB_3M                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_COMPOSITE                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_USB_DMC_TSC10                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_E2I                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_EASYTOUCH                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_EGALAX                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_ELO                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_ETT_TC45USB              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_ETURBO                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_GOTOP                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_GUNZE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_IDEALTEK                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_IRTOUCH                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_ITM                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_JASTEC                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_NEXIO                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_PANJIT                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_USB_ZYTRONIC                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_WACOM_I2C                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_WACOM_W8001                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_WDT87XX_I2C                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_WM831X                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_WM9705                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_WM9712                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_WM9713                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_TOUCHSCREEN_WM97XX                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TOUCHSCREEN_ZET6223                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_ZFORCE                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TOUCHSCREEN_ZINITIX                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TPL0102                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TPS6105X                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_TPS65010                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_TPS6507X                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_TPS6594_ESM                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TPS6594_PFSM                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TPS68470_PMIC_OPREGION                   policy<{'amd64': 'y'}>
+CONFIG_TQMX86_WDT                               policy<{'amd64': 'm'}>
+CONFIG_TRACEPOINTS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TRACEPOINT_BENCHMARK                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TRACER_MAX_TRACE                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TRACER_SNAPSHOT                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TRACE_CLOCK                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TRACE_EVAL_MAP_FILE                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TRACE_EVENT_INJECT                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT               policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_TRACE_IRQFLAGS_SUPPORT                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TRACE_MMIO_ACCESS                        policy<{'arm64': 'y'}>
+CONFIG_TRACING                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TRACING_MAP                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_TRACING_SUPPORT                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TRANSPARENT_HUGEPAGE                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TRANSPARENT_HUGEPAGE_MADVISE             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'n', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TRANSPARENT_HUGEPAGE_NEVER               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TRANS_TABLE                              policy<{'arm64': 'y'}>
+CONFIG_TREE_RCU                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TREE_SRCU                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TRIM_UNUSED_KSYMS                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TRUSTED_FOUNDATIONS                      policy<{'armhf': 'y'}>
+CONFIG_TRUSTED_KEYS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TRUSTED_KEYS_TPM                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TS4800_IRQ                               policy<{'armhf': 'm'}>
+CONFIG_TS4800_WATCHDOG                          policy<{'armhf': 'm'}>
+CONFIG_TSL2583                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TSL2591                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TSL2772                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TSL4531                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TSM_REPORTS                              policy<{'amd64': 'm'}>
+CONFIG_TSNEP                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_TSNEP_SELFTESTS                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TSYS01                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TSYS02D                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TTPCI_EEPROM                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TTY                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TTY_PRINTK                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_TTY_PRINTK_LEVEL                         policy<{'amd64': '6', 'arm64': '6', 'armhf': '6', 'ppc64el': '6', 'riscv64': '6'}>
+CONFIG_TULIP                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TULIP_MMIO                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_TULIP_MWI                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_TULIP_NAPI                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_TUN                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_TUNE_CPU                                 policy<{'ppc64el': '"-mtune=power10"'}>
+CONFIG_TUNE_DEFAULT                             policy<{'s390x': 'n'}>
+CONFIG_TUNE_GENERIC                             policy<{'riscv64': 'y'}>
+CONFIG_TUNE_Z10                                 policy<{'s390x': 'n'}>
+CONFIG_TUNE_Z13                                 policy<{'s390x': 'n'}>
+CONFIG_TUNE_Z14                                 policy<{'s390x': 'n'}>
+CONFIG_TUNE_Z15                                 policy<{'s390x': 'n'}>
+CONFIG_TUNE_Z196                                policy<{'s390x': 'n'}>
+CONFIG_TUNE_ZEC12                               policy<{'s390x': 'n'}>
+CONFIG_TUN_VNET_CROSS_LE                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_TURRIS_MOX_RWTM                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TWL4030_CORE                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_TWL4030_MADC                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TWL4030_POWER                            policy<{'armhf': 'y'}>
+CONFIG_TWL4030_USB                              policy<{'armhf': 'm'}>
+CONFIG_TWL4030_WATCHDOG                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TWL6030_GPADC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TWL6030_USB                              policy<{'armhf': 'm'}>
+CONFIG_TWL6040_CORE                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_TXGBE                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_TYPEC_ANX7411                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_DP_ALTMODE                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_FUSB302                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_HD3SS3220                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_MT6360                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_MUX_FSA4480                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_MUX_GPIO_SBU                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_MUX_INTEL_PMC                      policy<{'amd64': 'm'}>
+CONFIG_TYPEC_MUX_NB7VPQ904M                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_MUX_PI3USB30532                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_MUX_PTN36502                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_MUX_WCD939X_USBSS                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_NVIDIA_ALTMODE                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_QCOM_PMIC                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_TYPEC_RT1711H                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_RT1719                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_STUSB160X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_TCPCI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_TCPCI_MAXIM                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_TCPCI_MT6370                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_TCPM                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_TPS6598X                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_UCSI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPEC_WCOVE                              policy<{'amd64': 'm'}>
+CONFIG_TYPEC_WUSB3801                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_TYPHOON                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_UACCE                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_UACCESS_WITH_MEMCPY                      policy<{'armhf': 'n'}>
+CONFIG_UBIFS_ATIME_SUPPORT                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_UBIFS_FS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_UBIFS_FS_ADVANCED_COMPR                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_UBIFS_FS_AUTHENTICATION                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_UBIFS_FS_LZO                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_UBIFS_FS_SECURITY                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_UBIFS_FS_XATTR                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_UBIFS_FS_ZLIB                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_UBIFS_FS_ZSTD                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_UBSAN_ALIGNMENT                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 's390x': 'n'}>
+CONFIG_UBSAN_BOOL                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_UBSAN_BOUNDS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_UBSAN_BOUNDS_STRICT                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_UBSAN_DIV_ZERO                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 's390x': 'n'}>
+CONFIG_UBSAN_ENUM                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_UBSAN_SHIFT                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 's390x': 'y'}>
+CONFIG_UBSAN_TRAP                               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 's390x': 'n'}>
+CONFIG_UBSAN_UNREACHABLE                        policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 's390x': 'n'}>
+CONFIG_UBUNTU_HOST                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_UBUNTU_ODM_DRIVERS                       policy<{'amd64': 'y', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_UCC                                      policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_UCC_FAST                                 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_UCC_SLOW                                 policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y'}>
+CONFIG_UCLAMP_BUCKETS_COUNT                     policy<{'amd64': '5', 'arm64': '5', 'armhf': '5', 'ppc64el': '5', 'riscv64': '5'}>
+CONFIG_UCLAMP_TASK                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_UCLAMP_TASK_GROUP                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_UCS2_STRING                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_UCSI_ACPI                                policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_UCSI_CCG                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_UCSI_PMIC_GLINK                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_UCSI_STM32G0                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_UDBG_RTAS_CONSOLE                        policy<{'ppc64el': 'n'}>
+CONFIG_UDF_FS                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_UDMABUF                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_UEFI_CPER                                policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_UEFI_CPER_ARM                            policy<{'arm64': 'y'}>
+CONFIG_UEFI_CPER_X86                            policy<{'amd64': 'y'}>
+CONFIG_UEVENT_HELPER                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_UEVENT_HELPER_PATH                       policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'ppc64el': '""', 'riscv64': '""', 's390x': '""'}>
+CONFIG_UFS_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_UFS_FS                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_UFS_FS_WRITE                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_UHID                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_UID16                                    policy<{'amd64': 'y', 'arm64': 'y', 'arm64-generic-64k': '-', 'armhf': 'y', 's390x': '-'}>
+CONFIG_UIO                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_UIO_AEC                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_UIO_CIF                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_UIO_DFL                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_UIO_DMEM_GENIRQ                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_UIO_FSL_ELBC_GPCM                        policy<{'ppc64el': 'm'}>
+CONFIG_UIO_FSL_ELBC_GPCM_NETX5152               policy<{'ppc64el': 'n'}>
+CONFIG_UIO_HV_GENERIC                           policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_UIO_MF624                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_UIO_NETX                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_UIO_PCI_GENERIC                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_UIO_PDRV_GENIRQ                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_UIO_PRUSS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_UIO_SERCOS3                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ULI526X                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_ULTRIX_PARTITION                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_UNACCEPTED_MEMORY                        policy<{'amd64': 'y'}>
+CONFIG_UNCOMPRESS_INCLUDE                       policy<{'armhf': '"debug/uncompress.h"'}>
+CONFIG_UNICODE                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_UNICODE_NORMALIZATION_SELFTEST           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_UNINLINE_SPIN_UNLOCK                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-', 'ppc64el': '-', 'riscv64': 'y'}>
+CONFIG_UNIX                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_UNIX98_PTYS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_UNIXWARE_DISKLABEL                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_UNIX_DIAG                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_UNIX_SCM                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_UNMAP_KERNEL_AT_EL0                      policy<{'arm64': 'y'}>
+CONFIG_UNWINDER_ARM                             policy<{'armhf': 'n'}>
+CONFIG_UNWINDER_ORC                             policy<{'amd64': 'n'}>
+CONFIG_UPROBES                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_UPROBE_EVENTS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_US5182D                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB4                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_USB4_DEBUGFS_WRITE                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_USB4_DMA_TEST                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_USB4_NET                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USBIP_CORE                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USBIP_DEBUG                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_USBIP_HOST                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USBIP_VHCI_HCD                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USBIP_VHCI_HC_PORTS                      policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'ppc64el': '8', 'riscv64': '8'}>
+CONFIG_USBIP_VHCI_NR_HCS                        policy<{'amd64': '1', 'arm64': '1', 'armhf': '1', 'ppc64el': '1', 'riscv64': '1'}>
+CONFIG_USBIP_VUDC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USBPCWATCHDOG                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_ACM                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_ADUTUX                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_AIRSPY                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_ALI_M5632                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_AMD5536UDC                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_AN2720                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_ANNOUNCE_NEW_DEVICES                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_APPLEDISPLAY                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_ARCH_HAS_HCD                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_ARMLINUX                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_ASPEED_UDC                           policy<{'armhf': 'm'}>
+CONFIG_USB_ASPEED_VHUB                          policy<{'armhf': 'm'}>
+CONFIG_USB_ATM                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_AUDIO                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_AUTOSUSPEND_DELAY                    policy<{'amd64': '2', 'arm64': '2', 'armhf': '2', 'ppc64el': '2', 'riscv64': '2'}>
+CONFIG_USB_BDC_UDC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_BELKIN                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_C67X00_HCD                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_CATC                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CDC_COMPOSITE                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CDC_PHONET                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CDNS2_UDC                            policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CDNS3                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CDNS3_GADGET                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CDNS3_HOST                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CDNS3_IMX                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_CDNS3_PCI_WRAP                       policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CDNS3_STARFIVE                       policy<{'riscv64': 'm'}>
+CONFIG_USB_CDNS3_TI                             policy<{'arm64': 'm'}>
+CONFIG_USB_CDNSP_GADGET                         policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CDNSP_HOST                           policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CDNSP_PCI                            policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CDNS_HOST                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CDNS_SUPPORT                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_CHAOSKEY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_CHIPIDEA                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_CHIPIDEA_GENERIC                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CHIPIDEA_HOST                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CHIPIDEA_IMX                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CHIPIDEA_MSM                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CHIPIDEA_NPCM                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CHIPIDEA_PCI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CHIPIDEA_TEGRA                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CHIPIDEA_UDC                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_COMMON                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CONFIGFS_ACM                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_ECM                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_ECM_SUBSET                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_EEM                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_F_FS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_F_HID                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_F_LB_SS                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_F_MIDI                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_F_MIDI2                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_F_PRINTER                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_F_TCM                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_F_UAC1                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_F_UAC1_LEGACY               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_F_UAC2                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_F_UVC                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_MASS_STORAGE                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_NCM                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_OBEX                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_PHONET                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_RNDIS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONFIGFS_SERIAL                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_CONN_GPIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_CXACRU                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_CYPRESS_CY7C63                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_CYTHERM                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_DEFAULT_PERSIST                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_DSBR                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_DUMMY_HCD                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_USB_DWC2                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_DWC2_DEBUG                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_USB_DWC2_DUAL_ROLE                       policy<{'armhf': 'n'}>
+CONFIG_USB_DWC2_HOST                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_DWC2_PCI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_DWC2_PERIPHERAL                      policy<{'armhf': 'n'}>
+CONFIG_USB_DWC2_TRACK_MISSED_SOFS               policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_USB_DWC3                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_DWC3_AM62                            policy<{'arm64': 'm'}>
+CONFIG_USB_DWC3_DUAL_ROLE                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_DWC3_EXYNOS                          policy<{'armhf': 'n'}>
+CONFIG_USB_DWC3_GADGET                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_USB_DWC3_HAPS                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_DWC3_HOST                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_USB_DWC3_IMX8MP                          policy<{'arm64': 'm'}>
+CONFIG_USB_DWC3_KEYSTONE                        policy<{'arm64': 'm'}>
+CONFIG_USB_DWC3_MESON_G12A                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_DWC3_OF_SIMPLE                       policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_DWC3_OMAP                            policy<{'armhf': 'm'}>
+CONFIG_USB_DWC3_PCI                             policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_USB_DWC3_QCOM                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_DWC3_RTK                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_DWC3_ULPI                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_DWC3_XILINX                          policy<{'arm64': 'm'}>
+CONFIG_USB_DYNAMIC_MINORS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_EG20T                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_EHCI_EXYNOS                          policy<{'armhf': 'n'}>
+CONFIG_USB_EHCI_FSL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_EHCI_HCD_NPCM7XX                     policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_EHCI_HCD_OMAP                        policy<{'armhf': 'm'}>
+CONFIG_USB_EHCI_HCD_ORION                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_USB_EHCI_HCD_PPC_OF                      policy<{'ppc64el': 'y'}>
+CONFIG_USB_EHCI_PCI                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_EHCI_ROOT_HUB_TT                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_EHCI_TEGRA                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_EHCI_TT_NEWSCHED                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_EHSET_TEST_FIXTURE                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_EMI26                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_EMI62                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_EMXX                                 policy<{'arm64': 'm', 'armhf': 'y', 'riscv64': 'm'}>
+CONFIG_USB_EPSON2888                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_ETH                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_ETH_EEM                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_ETH_RNDIS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_EZUSB_FX2                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_FEW_INIT_RETRIES                     policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_USB_FHCI_HCD                             policy<{'ppc64el': 'm'}>
+CONFIG_USB_FUNCTIONFS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_FUNCTIONFS_ETH                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_FUNCTIONFS_GENERIC                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_FUNCTIONFS_RNDIS                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_F_ACM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_ECM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_EEM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_FS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_HID                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_MASS_STORAGE                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_MIDI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_MIDI2                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_NCM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_OBEX                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_PHONET                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_PRINTER                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_RNDIS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_SERIAL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_SS_LB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_SUBSET                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_TCM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_UAC1                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_UAC1_LEGACY                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_UAC2                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_F_UVC                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GADGET                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'y', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_GADGETFS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GADGET_DEBUG                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_USB_GADGET_DEBUG_FILES                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_USB_GADGET_DEBUG_FS                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS           policy<{'amd64': '2', 'arm64': '2', 'armhf': '2', 'ppc64el': '2', 'riscv64': '2'}>
+CONFIG_USB_GADGET_TARGET                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GADGET_VBUS_DRAW                     policy<{'amd64': '2', 'arm64': '2', 'armhf': '2', 'ppc64el': '2', 'riscv64': '2'}>
+CONFIG_USB_GADGET_XILINX                        policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GL860                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GOKU                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GPIO_VBUS                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_GR_UDC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_BENQ                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_CONEX                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_CPIA1                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_DTCS033                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_ETOMS                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_FINEPIX                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_JEILINJ                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_JL2005BCD                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_KINECT                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_KONICA                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_MARS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_MR97310A                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_NW80X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_OV519                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_OV534                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_OV534_9                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_PAC207                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_PAC7302                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_PAC7311                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SE401                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SN9C2028                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SN9C20X                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SONIXB                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SONIXJ                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SPCA1528                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SPCA500                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SPCA501                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SPCA505                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SPCA506                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SPCA508                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SPCA561                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SQ905                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SQ905C                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SQ930X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_STK014                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_STK1135                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_STV0680                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_SUNPLUS                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_T613                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_TOPRO                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_TOUPTEK                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_TV8532                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_VC032X                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_VICAM                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_XIRLINK_CIT                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_GSPCA_ZC3XX                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_G_ACM_MS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_G_DBGP                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_G_DBGP_PRINTK                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_USB_G_DBGP_SERIAL                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_G_HID                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_G_MULTI                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_USB_G_NCM                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_G_NOKIA                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_G_PRINTER                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_G_SERIAL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_G_WEBCAM                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_HACKRF                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_HCD_TEST_MODE                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_USB_HID                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_HIDDEV                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_HSIC_USB3503                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_HSIC_USB4604                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_HSO                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_HUB_USB251XB                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_IDMOUSE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_IOWARRIOR                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_IPHETH                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_ISIGHTFW                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_ISP116X_HCD                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_ISP1301                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_ISP1760                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_ISP1760_DUAL_ROLE                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_ISP1760_GADGET_ROLE                  policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_USB_ISP1760_HCD                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_ISP1760_HOST_ROLE                    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_USB_ISP1761_UDC                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_KAWETH                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_KBD                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_KC2190                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_KEENE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_LAN78XX                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_LCD                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_LD                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_LEDS_TRIGGER_USBPORT                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_LED_TRIG                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_LEGOTOWER                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_LGM_PHY                              policy<{'amd64': 'm'}>
+CONFIG_USB_LIBCOMPOSITE                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_LINK_LAYER_TEST                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_LJCA                                 policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_USB_M5602                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_MA901                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_MASS_STORAGE                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_MAX3420_UDC                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_MAX3421_HCD                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_MDC800                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_MICROTEK                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_MIDI_GADGET                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_MON                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_MOUSE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_MR800                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_MSI2500                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_MTU3                                 policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_MTU3_DEBUG                           policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_USB_MTU3_DUAL_ROLE                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_USB_MTU3_GADGET                          policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_USB_MTU3_HOST                            policy<{'arm64': 'n', 'armhf': 'n'}>
+CONFIG_USB_MUSB_DSPS                            policy<{'armhf': 'm'}>
+CONFIG_USB_MUSB_DUAL_ROLE                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_MUSB_GADGET                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_USB_MUSB_HOST                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_USB_MUSB_MEDIATEK                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_MUSB_OMAP2PLUS                       policy<{'armhf': 'm'}>
+CONFIG_USB_MUSB_POLARFIRE_SOC                   policy<{'riscv64': 'm'}>
+CONFIG_USB_MUSB_SUNXI                           policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_USB_MUSB_TUSB6010                        policy<{'armhf': 'm'}>
+CONFIG_USB_MV_U3D                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_MV_UDC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_MXS_PHY                              policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_USB_NET2272                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET2272_DMA                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_NET2280                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_AQC111                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_AX88179_178A                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_AX8817X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_CDCETHER                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_CDC_EEM                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_CDC_MBIM                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_CDC_NCM                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_CDC_SUBSET                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_CDC_SUBSET_ENABLE                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_CH9200                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_CX82310_ETH                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_DM9601                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_DRIVERS                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_NET_GL620A                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_HUAWEI_CDC_NCM                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_INT51X1                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_KALMIA                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_MCS7830                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_NET1080                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_PLUSB                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_QMI_WWAN                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_RNDIS_HOST                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_SMSC75XX                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_SMSC95XX                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_SR9700                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_SR9800                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_NET_ZAURUS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_OHCI_EXYNOS                          policy<{'armhf': 'n'}>
+CONFIG_USB_OHCI_HCD                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_OHCI_HCD_PCI                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_OHCI_HCD_PLATFORM                    policy<{'amd64': 'y', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_OHCI_HCD_PPC_OF_BE                   policy<{'ppc64el': 'n'}>
+CONFIG_USB_OHCI_HCD_PPC_OF_LE                   policy<{'ppc64el': 'n'}>
+CONFIG_USB_OHCI_LITTLE_ENDIAN                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_USB_ONBOARD_HUB                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_OTG_DISABLE_EXTERNAL_HUB             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_USB_OTG_FSM                              policy<{'riscv64': 'm'}>
+CONFIG_USB_OTG_PRODUCTLIST                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_USB_OXU210HP_HCD                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_PCI                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_PCI_AMD                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_PEGASUS                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_PHY                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_PRINTER                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_PULSE8_CEC                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_PWC                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_PWC_DEBUG                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_USB_PWC_INPUT_EVDEV                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_PXA27X                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_QCOM_EUD                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_R8A66597                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_R8A66597_HCD                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_RAINSHADOW_CEC                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_RAREMONO                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_RAW_GADGET                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_RENESAS_USB3                         policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_USB_RENESAS_USBF                         policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_USB_RENESAS_USBHS                        policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_USB_RENESAS_USBHS_HCD                    policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_USB_RENESAS_USBHS_UDC                    policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_USB_ROLES_INTEL_XHCI                     policy<{'amd64': 'm'}>
+CONFIG_USB_ROLE_SWITCH                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_RTL8150                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_RTL8152                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_RTL8153_ECM                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_RZV2M_USB3DRD                        policy<{'arm64': 'm'}>
+CONFIG_USB_S2255                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_SERIAL_AIRCABLE                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_ARK3116                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_BELKIN                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_CH341                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_CP210X                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_CYBERJACK                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_CYPRESS_M8                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_DIGI_ACCELEPORT               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_EDGEPORT                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_EDGEPORT_TI                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_EMPEG                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_F81232                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_F8153X                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_FTDI_SIO                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_GARMIN                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_GENERIC                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_SERIAL_IPAQ                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_IPW                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_IR                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_IUU                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_KEYSPAN                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_KEYSPAN_PDA                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_KLSI                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_KOBIL_SCT                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_MCT_U232                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_METRO                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_MOS7715_PARPORT               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_SERIAL_MOS7720                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_MOS7840                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_MXUPORT                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_NAVMAN                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_OMNINET                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_OPTICON                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_OPTION                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_OTI6858                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_PL2303                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_QCAUX                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_QT2                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_QUALCOMM                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_SAFE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_SAFE_PADDED                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_USB_SERIAL_SIERRAWIRELESS                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_SIMPLE                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_SPCP8X5                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_SSU100                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_SYMBOL                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_TI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_UPD78F0730                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_VISOR                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_WHITEHEAT                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_WISHBONE                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_WWAN                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_XR                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SERIAL_XSENS_MT                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SEVSEG                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_SI470X                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SI4713                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SIERRA_NET                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SISUSBVGA                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_SL811_CS                             policy<{'amd64': 'm'}>
+CONFIG_USB_SL811_HCD                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_SL811_HCD_ISO                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_SNP_CORE                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SNP_UDC_PLAT                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SPEEDTOUCH                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_STORAGE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_STORAGE_ALAUDA                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_STORAGE_CYPRESS_ATACB                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_STORAGE_DATAFAB                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_STORAGE_DEBUG                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_USB_STORAGE_ENE_UB6250                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_STORAGE_FREECOM                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_STORAGE_ISD200                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_STORAGE_JUMPSHOT                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_STORAGE_KARMA                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_STORAGE_ONETOUCH                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_STORAGE_REALTEK                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_STORAGE_SDDR09                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_STORAGE_SDDR55                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_STORAGE_USBAT                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_STV06XX                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_SUPPORT                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_USB_TEGRA_PHY                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_TEGRA_XUDC                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_TEST                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_TMC                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_TRANCEVIBRATOR                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_UAS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_UEAGLEATM                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_UHCI_ASPEED                          policy<{'armhf': 'y'}>
+CONFIG_USB_UHCI_PLATFORM                        policy<{'armhf': 'y'}>
+CONFIG_USB_UHCI_SUPPORT_NON_PCI_HC              policy<{'armhf': 'y'}>
+CONFIG_USB_ULPI                                 policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_USB_ULPI_BUS                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_ULPI_VIEWPORT                        policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_USB_USBNET                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_USS720                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_U_AUDIO                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_U_ETHER                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_U_SERIAL                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_VIDEO_CLASS                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_USB_VL600                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_WDM                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_XEN_HCD                              policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_USB_XHCI_HISTB                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_XHCI_MTK                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_XHCI_MVEBU                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_XHCI_PCI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_XHCI_PCI_RENESAS                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_XHCI_PLATFORM                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_XHCI_RCAR                            policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_USB_XHCI_RZV2M                           policy<{'arm64': 'y'}>
+CONFIG_USB_XHCI_TEGRA                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_USB_XUSBATM                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_YUREX                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USB_ZERO                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_USB_ZERO_HNPTEST                         policy<{'riscv64': 'n'}>
+CONFIG_USELIB                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_USERFAULTFD                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_USERIO                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_USER_DECRYPTED_DATA                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_USER_EVENTS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_USER_NS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_USER_RETURN_NOTIFIER                     policy<{'amd64': 'y'}>
+CONFIG_USER_STACKTRACE_SUPPORT                  policy<{'amd64': 'y', 's390x': 'y'}>
+CONFIG_USE_OF                                   policy<{'armhf': 'y'}>
+CONFIG_USE_PERCPU_NUMA_NODE_ID                  policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_UTS_NS                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_UVC_COMMON                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_UV_MMTIMER                               policy<{'amd64': 'm'}>
+CONFIG_UV_SYSFS                                 policy<{'amd64': 'm'}>
+CONFIG_U_SERIAL_CONSOLE                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_V4L2_ASYNC                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_V4L2_CCI                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_V4L2_CCI_I2C                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_V4L2_FLASH_LED_CLASS                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_V4L2_FWNODE                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_V4L2_H264                                policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_V4L2_JPEG_HELPER                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_V4L2_MEM2MEM_DEV                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_V4L2_VP9                                 policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_V4L_MEM2MEM_DRIVERS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_V4L_PLATFORM_DRIVERS                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_V4L_TEST_DRIVERS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VALIDATE_FS_PARSER                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VBOXGUEST                                policy<{'amd64': 'm'}>
+CONFIG_VBOXSF_FS                                policy<{'amd64': 'm'}>
+CONFIG_VCAP                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VCNL3020                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VCNL4000                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VCNL4035                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VCPU_STALL_DETECTOR                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VDPA                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_VDPA_SIM                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VDPA_SIM_BLOCK                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VDPA_SIM_NET                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VDPA_USER                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VDSO                                     policy<{'armhf': 'y'}>
+CONFIG_VEML6030                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VEML6070                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VEML6075                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VERSION_SIGNATURE                        policy<{'amd64': '""', 'arm64': '""', 'armhf': '""', 'ppc64el': '""', 'riscv64': '""', 's390x': '""'}>
+CONFIG_VETH                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VEXPRESS_CONFIG                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_VF610_ADC                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VF610_DAC                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VFIO_AMBA                                policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VFIO_AP                                  policy<{'s390x': 'm'}>
+CONFIG_VFIO_CCW                                 policy<{'s390x': 'm'}>
+CONFIG_VFIO_CDX                                 policy<{'arm64': 'm'}>
+CONFIG_VFIO_CONTAINER                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VFIO_DEBUGFS                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_VFIO_DEVICE_CDEV                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y'}>
+CONFIG_VFIO_FSL_MC                              policy<{'arm64': 'm'}>
+CONFIG_VFIO_GROUP                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VFIO_IOMMU_SPAPR_TCE                     policy<{'ppc64el': 'm'}>
+CONFIG_VFIO_IOMMU_TYPE1                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 's390x': 'm'}>
+CONFIG_VFIO_MDEV                                policy<{'amd64': 'm', 'arm64': '-', 'armhf': '-', 'ppc64el': '-', 'riscv64': '-', 's390x': 'm'}>
+CONFIG_VFIO_NOIOMMU                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VFIO_PCI_CORE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VFIO_PCI_IGD                             policy<{'amd64': 'y'}>
+CONFIG_VFIO_PCI_INTX                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VFIO_PCI_MMAP                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VFIO_PCI_VGA                             policy<{'amd64': 'y'}>
+CONFIG_VFIO_PLATFORM                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VFIO_PLATFORM_AMDXGBE_RESET              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VFIO_PLATFORM_BASE                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VFIO_PLATFORM_CALXEDAXGMAC_RESET         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VFIO_VIRQFD                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VFP                                      policy<{'armhf': 'y'}>
+CONFIG_VFPv3                                    policy<{'armhf': 'y'}>
+CONFIG_VF_USE_ARM_GLOBAL_TIMER                  policy<{'armhf': 'y'}>
+CONFIG_VF_USE_PIT_TIMER                         policy<{'armhf': 'n'}>
+CONFIG_VGASTATE                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VGA_ARB                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VGA_ARB_MAX_GPUS                         policy<{'amd64': '16', 'arm64': '16', 'armhf': '16', 'ppc64el': '16', 'riscv64': '16'}>
+CONFIG_VGA_CONSOLE                              policy<{'amd64': 'y', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_VGA_SWITCHEROO                           policy<{'amd64': 'y'}>
+CONFIG_VHOST                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VHOST_CROSS_ENDIAN_LEGACY                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_VHOST_IOTLB                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VHOST_MENU                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VHOST_NET                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VHOST_RING                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VHOST_SCSI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VHOST_TASK                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VHOST_VDPA                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VHOST_VSOCK                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VIA_RHINE                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_VIA_RHINE_MMIO                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIA_VELOCITY                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_VIA_WDT                                  policy<{'amd64': 'm'}>
+CONFIG_VIDEOBUF2_CORE                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEOBUF2_DMA_CONTIG                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEOBUF2_DMA_SG                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEOBUF2_DVB                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEOBUF2_MEMOPS                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEOBUF2_V4L2                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEOBUF2_VMALLOC                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEOMODE_HELPERS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_AD5820                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ADP1653                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ADV7170                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ADV7175                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ADV7180                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ADV7183                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ADV7343                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ADV7393                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ADV748X                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ADV7511                            policy<{'amd64': 'm'}>
+CONFIG_VIDEO_ADV7511_CEC                        policy<{'amd64': 'n'}>
+CONFIG_VIDEO_ADV7604                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ADV7604_CEC                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_ADV7842                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ADV7842_CEC                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_ADV_DEBUG                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_VIDEO_AK7375                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_AK881X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ALLEGRO_DVT                        policy<{'arm64': 'm'}>
+CONFIG_VIDEO_ALVIUM_CSI2                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_AMPHION_VPU                        policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_APTINA_PLL                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_AR0521                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ASPEED                             policy<{'amd64': '-', 'arm64': '-', 'armhf': 'm', 'ppc64el': '-', 'riscv64': '-'}>
+CONFIG_VIDEO_AU0828                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_AU0828_RC                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_AU0828_V4L2                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_BT819                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_BT848                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_BT856                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_BT866                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CADENCE_CSI2RX                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CADENCE_CSI2TX                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CAFE_CCIC                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CAMERA_SENSOR                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_CCS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CCS_PLL                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CMDLINE                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIDEO_COBALT                             policy<{'amd64': 'm'}>
+CONFIG_VIDEO_CODA                               policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_CS3308                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CS5345                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CS53L32A                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX18                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX18_ALSA                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX231XX                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX231XX_ALSA                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX231XX_DVB                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX231XX_RC                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_CX2341X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX23885                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX25821                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX25821_ALSA                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX25840                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX88                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX88_ALSA                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX88_BLACKBIRD                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX88_DVB                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX88_ENABLE_VP3054                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_CX88_MPEG                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_CX88_VP3054                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_DEV                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_DS90UB913                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_DS90UB953                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_DS90UB960                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_DT3155                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_DW100                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_DW9714                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_DW9719                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_DW9768                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_DW9807_VCM                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_EM28XX                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_EM28XX_ALSA                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_EM28XX_DVB                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_EM28XX_RC                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_EM28XX_V4L2                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ET8EK8                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_FB_IVTV                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_FB_IVTV_FORCE_PAT                  policy<{'amd64': 'y'}>
+CONFIG_VIDEO_FIXED_MINOR_RANGES                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_VIDEO_GC0308                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_GC2145                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_GO7007                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_GO7007_LOADER                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_GO7007_USB                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_GO7007_USB_S2250_BOARD             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_GS1662                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_HANTRO                             policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_HANTRO_IMX8M                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_VIDEO_HANTRO_ROCKCHIP                    policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_VIDEO_HANTRO_SUNXI                       policy<{'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_HDPVR                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_HEXIUM_GEMINI                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_HEXIUM_ORION                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_HI556                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_HI846                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_HI847                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_I2C                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IMX208                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IMX214                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IMX219                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IMX258                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IMX274                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IMX290                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IMX296                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IMX319                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IMX334                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IMX335                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IMX355                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IMX412                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IMX415                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IMX7_CSI                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_IMX8MQ_MIPI_CSI2                   policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_IMX8_ISI                           policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_IMX8_ISI_M2M                       policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_VIDEO_IMX8_JPEG                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_IMX_MEDIA                          policy<{'arm64': '-', 'armhf': 'm'}>
+CONFIG_VIDEO_IMX_MIPI_CSIS                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_IMX_PXP                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_IMX_VDOA                           policy<{'armhf': 'm'}>
+CONFIG_VIDEO_IPU3_CIO2                          policy<{'amd64': 'm'}>
+CONFIG_VIDEO_IPU3_IMGU                          policy<{'amd64': 'm'}>
+CONFIG_VIDEO_IR_I2C                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ISL7998X                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IVTV                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_IVTV_ALSA                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_KS0127                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_LM3560                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_LM3646                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_M52790                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MAX9271_LIB                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MAX9286                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MAX96712                           policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MEDIATEK_JPEG                      policy<{'arm64': 'n'}>
+CONFIG_VIDEO_MEDIATEK_MDP                       policy<{'arm64': 'n'}>
+CONFIG_VIDEO_MEDIATEK_MDP3                      policy<{'arm64': 'n'}>
+CONFIG_VIDEO_MEDIATEK_VCODEC                    policy<{'arm64': 'n'}>
+CONFIG_VIDEO_MEDIATEK_VPU                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_MEM2MEM_DEINTERLACE                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MESON_GE2D                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_MESON_VDEC                         policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_MGB4                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ML86V7667                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MSP3400                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MT9M001                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MT9M111                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MT9M114                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MT9P031                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MT9T112                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MT9V011                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MT9V032                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MT9V111                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MUX                                policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_MXB                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_NOMODESET                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIDEO_NPCM_VCD_ECE                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_OG01A1B                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV01A10                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV02A10                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV08D10                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV08X40                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV13858                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV13B10                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV2640                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV2659                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV2680                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV2685                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV2740                             policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV4689                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV5640                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV5645                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV5647                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV5648                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV5670                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV5675                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV5693                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV5695                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV64A40                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV6650                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV7251                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV7640                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV7670                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV772X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV7740                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV8856                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV8858                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV8865                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV9282                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV9640                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV9650                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_OV9734                             policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_PCI_SKELETON                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_VIDEO_PVRUSB2                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_PVRUSB2_DEBUGIFC                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_VIDEO_PVRUSB2_DVB                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_PVRUSB2_SYSFS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_QCOM_CAMSS                         policy<{'arm64': 'm'}>
+CONFIG_VIDEO_QCOM_VENUS                         policy<{'arm64': 'm'}>
+CONFIG_VIDEO_RCAR_CSI2                          policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_RCAR_DRIF                          policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_RCAR_ISP                           policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_RCAR_VIN                           policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_RDACM20                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_RDACM21                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_RENESAS_CEU                        policy<{'armhf': 'm'}>
+CONFIG_VIDEO_RENESAS_FCP                        policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_RENESAS_FDP1                       policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_RENESAS_JPU                        policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_RENESAS_VSP1                       policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_RJ54N1                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ROCKCHIP_ISP1                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_ROCKCHIP_RGA                       policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_ROCKCHIP_VDEC                      policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_RZG2L_CRU                          policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_RZG2L_CSI2                         policy<{'arm64': 'm', 'armhf': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_S5C73M3                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_S5K5BAF                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_S5K6A3                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAA6588                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAA6752HS                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAA7110                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAA711X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAA7127                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAA7134                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAA7134_ALSA                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAA7134_DVB                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAA7134_GO7007                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAA7134_RC                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_SAA7146                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAA7146_VV                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAA7164                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAA717X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAA7185                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS                 policy<{'armhf': 'n'}>
+CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC                 policy<{'armhf': 'n'}>
+CONFIG_VIDEO_SAMSUNG_S5P_G2D                    policy<{'armhf': 'n'}>
+CONFIG_VIDEO_SAMSUNG_S5P_JPEG                   policy<{'armhf': 'n'}>
+CONFIG_VIDEO_SAMSUNG_S5P_MFC                    policy<{'armhf': 'n'}>
+CONFIG_VIDEO_SOLO6X10                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'n', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SONY_BTF_MPX                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_STARFIVE_CAMSS                     policy<{'riscv64': 'm'}>
+CONFIG_VIDEO_STK1160                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_STM32_DCMI                         policy<{'arm64': 'm'}>
+CONFIG_VIDEO_STM32_DCMIPP                       policy<{'arm64': 'm'}>
+CONFIG_VIDEO_STM32_DMA2D                        policy<{'arm64': 'm'}>
+CONFIG_VIDEO_ST_MIPID02                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ST_VGXY61                          policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SUN4I_CSI                          policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_VIDEO_SUN6I_CSI                          policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_VIDEO_SUN6I_ISP                          policy<{'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SUN6I_MIPI_CSI2                    policy<{'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SUN8I_A83T_MIPI_CSI2               policy<{'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_SUN8I_DEINTERLACE                  policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_VIDEO_SUN8I_ROTATE                       policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_VIDEO_SUNXI                              policy<{'arm64': 'y', 'armhf': '-', 'riscv64': 'y'}>
+CONFIG_VIDEO_SUNXI_CEDRUS                       policy<{'arm64': 'm', 'armhf': '-', 'riscv64': 'm'}>
+CONFIG_VIDEO_TC358743                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TC358743_CEC                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_TC358746                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TDA1997X                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TDA7432                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TDA9840                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TEA6415C                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TEA6420                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TEGRA                              policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_TEGRA_TPG                          policy<{'arm64': 'y', 'armhf': '-'}>
+CONFIG_VIDEO_TEGRA_VDE                          policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_THP7312                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_THS7303                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_THS8200                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TI_CAL                             policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_VIDEO_TI_CAL_MC                          policy<{'arm64': 'y', 'armhf': 'y'}>
+CONFIG_VIDEO_TI_CSC                             policy<{'armhf': 'm'}>
+CONFIG_VIDEO_TI_J721E_CSI2RX                    policy<{'arm64': 'm'}>
+CONFIG_VIDEO_TI_SC                              policy<{'armhf': 'm'}>
+CONFIG_VIDEO_TI_VPDMA                           policy<{'armhf': 'm'}>
+CONFIG_VIDEO_TI_VPE                             policy<{'armhf': 'm'}>
+CONFIG_VIDEO_TI_VPE_DEBUG                       policy<{'armhf': 'n'}>
+CONFIG_VIDEO_TLV320AIC23B                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TUNER                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TVAUDIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TVEEPROM                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TVP514X                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TVP5150                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TVP7002                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TW2804                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TW5864                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TW68                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TW686X                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TW9900                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TW9903                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TW9906                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_TW9910                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_UDA1342                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_UPD64031A                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_UPD64083                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_USBTV                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_V4L2_I2C                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_V4L2_SUBDEV_API                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_V4L2_TPG                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_VIA_CAMERA                         policy<{'amd64': 'm'}>
+CONFIG_VIDEO_VICODEC                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_VIM2M                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_VISL                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_VIVID                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_VIVID_CEC                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIDEO_VIVID_MAX_DEVS                     policy<{'amd64': '64', 'arm64': '64', 'armhf': '64', 'ppc64el': '64', 'riscv64': '64'}>
+CONFIG_VIDEO_VP27SMPX                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_VPX3220                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_WAVE_VPU                           policy<{'arm64': 'm'}>
+CONFIG_VIDEO_WM8739                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_WM8775                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_XILINX                             policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_XILINX_CSI2RXSS                    policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_XILINX_TPG                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_XILINX_VTC                         policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIDEO_ZORAN                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_VIPERBOARD_ADC                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIRTIO                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIRTIO_ANCHOR                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIRTIO_BALLOON                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIRTIO_CONSOLE                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIRTIO_DMA_SHARED_BUFFER                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VIRTIO_FS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VIRTIO_INPUT                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VIRTIO_IOMMU                             policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_VIRTIO_MEM                               policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_VIRTIO_MENU                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIRTIO_PCI                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIRTIO_PCI_ADMIN_LEGACY                  policy<{'amd64': 'y'}>
+CONFIG_VIRTIO_PCI_LEGACY                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIRTIO_PCI_LIB                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIRTIO_PCI_LIB_LEGACY                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIRTIO_PMEM                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_VIRTIO_VDPA                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VIRTIO_VFIO_PCI                          policy<{'amd64': 'm'}>
+CONFIG_VIRTIO_VSOCKETS                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VIRTIO_VSOCKETS_COMMON                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VIRTUALIZATION                           policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIRT_CPU_ACCOUNTING                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIRT_CPU_ACCOUNTING_GEN                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VIRT_CPU_ACCOUNTING_NATIVE               policy<{'ppc64el': 'n', 's390x': 'y'}>
+CONFIG_VIRT_DRIVERS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VIRT_WIFI                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VISCONTI_WATCHDOG                        policy<{'arm64': 'm'}>
+CONFIG_VISL_DEBUGFS                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_VITESSE_PHY                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VL53L0X_I2C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VL6180                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VLAN_8021Q                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VLAN_8021Q_GVRP                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VLAN_8021Q_MVRP                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VMAP_PFN                                 policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VMAP_STACK                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VMCP                                     policy<{'s390x': 'y'}>
+CONFIG_VMCP_CMA_SIZE                            policy<{'s390x': '4'}>
+CONFIG_VMD                                      policy<{'amd64': 'm'}>
+CONFIG_VME_BUS                                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_VME_FAKE                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_VME_TSI148                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_VME_USER                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_VMGENID                                  policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_VMLINUX_MAP                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VMLOGRDR                                 policy<{'s390x': 'm'}>
+CONFIG_VMSPLIT_1G                               policy<{'armhf': 'n'}>
+CONFIG_VMSPLIT_2G                               policy<{'armhf': 'n'}>
+CONFIG_VMSPLIT_3G                               policy<{'armhf': 'y'}>
+CONFIG_VMWARE_BALLOON                           policy<{'amd64': 'm'}>
+CONFIG_VMWARE_PVSCSI                            policy<{'amd64': 'm'}>
+CONFIG_VMWARE_VMCI                              policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_VMWARE_VMCI_VSOCKETS                     policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_VMXNET3                                  policy<{'amd64': 'm', 'arm64': 'm', 'arm64-generic-64k': '-', 'armhf': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_VM_EVENT_COUNTERS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VORTEX                                   policy<{'amd64': 'm', 'arm64': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VP_VDPA                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VSOCKETS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VSOCKETS_DIAG                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VSOCKETS_LOOPBACK                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VSOCKMON                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VSX                                      policy<{'ppc64el': 'y'}>
+CONFIG_VT                                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VT6655                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VT6656                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_VT_CONSOLE                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VT_CONSOLE_SLEEP                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_VT_HW_CONSOLE_BINDING                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_VXFS_FS                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_VXLAN                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_VZ89X                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_W1                                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_W1_CON                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': '-'}>
+CONFIG_W1_MASTER_AMD_AXI                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_W1_MASTER_DS2482                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_MASTER_DS2490                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_MASTER_GPIO                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_MASTER_MATROX                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_MASTER_MXC                            policy<{'arm64': 'm', 'armhf': 'm'}>
+CONFIG_W1_MASTER_SGI                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS2405                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS2406                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS2408                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS2408_READBACK                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_W1_SLAVE_DS2413                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS2423                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS2430                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS2431                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS2433                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS2433_CRC                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS2438                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS250X                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS2780                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS2781                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS2805                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS28E04                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_DS28E17                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_SMEM                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W1_SLAVE_THERM                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_W83627HF_WDT                             policy<{'amd64': 'm'}>
+CONFIG_W83877F_WDT                              policy<{'amd64': 'm'}>
+CONFIG_W83977F_WDT                              policy<{'amd64': 'm'}>
+CONFIG_WAFER_WDT                                policy<{'amd64': 'm'}>
+CONFIG_WAN                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_WANT_COMPAT_NETLINK_MESSAGES             policy<{'amd64': 'y'}>
+CONFIG_WANT_DEV_COREDUMP                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WANXL                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WARN_ALL_UNSEEDED_RANDOM                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_WATCHDOG                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_WATCHDOG_CORE                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_WATCHDOG_NOWAYOUT                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_WATCHDOG_OPEN_TIMEOUT                    policy<{'amd64': '0', 'arm64': '0', 'armhf': '0', 'ppc64el': '0', 'riscv64': '0', 's390x': '0'}>
+CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_WATCHDOG_PRETIMEOUT_GOV                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_WATCHDOG_PRETIMEOUT_GOV_SEL              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_WATCHDOG_RTAS                            policy<{'ppc64el': 'm'}>
+CONFIG_WATCHDOG_SYSFS                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_WATCH_QUEUE                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_WCN36XX                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WCN36XX_DEBUGFS                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_WDAT_WDT                                 policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}>
+CONFIG_WDTPCI                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_WERROR                                   policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_WEXT_CORE                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WEXT_PRIV                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WEXT_PROC                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WEXT_SPY                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WFX                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WIL6210                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WIL6210_DEBUGFS                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WIL6210_ISR_COR                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WIL6210_TRACING                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WILC1000                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WILC1000_HW_OOB_INTR                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WILC1000_SDIO                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WILC1000_SPI                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WILCO_EC                                 policy<{'amd64': 'm'}>
+CONFIG_WILCO_EC_DEBUGFS                         policy<{'amd64': 'm'}>
+CONFIG_WILCO_EC_EVENTS                          policy<{'amd64': 'm'}>
+CONFIG_WILCO_EC_TELEMETRY                       policy<{'amd64': 'm'}>
+CONFIG_WINBOND_840                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_WINDFARM                                 policy<{'ppc64el': 'm'}>
+CONFIG_WINMATE_FM07_KEYS                        policy<{'amd64': 'm'}>
+CONFIG_WIREGUARD                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_WIREGUARD_DEBUG                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_WIRELESS                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WIRELESS_EXT                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WIRELESS_HOTKEY                          policy<{'amd64': 'm'}>
+CONFIG_WIZNET_BUS_ANY                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WIZNET_BUS_DIRECT                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_WIZNET_BUS_INDIRECT                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': '-'}>
+CONFIG_WIZNET_W5100                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_WIZNET_W5100_SPI                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WIZNET_W5300                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_WL1251                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WL1251_SDIO                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WL1251_SPI                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WL12XX                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WL18XX                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WLAN                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_ADMTEK                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_ATH                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_ATMEL                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_BROADCOM                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_INTEL                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_INTERSIL                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_MARVELL                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_MEDIATEK                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_MICROCHIP                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_PURELIFI                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_QUANTENNA                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_RALINK                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_REALTEK                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_RSI                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_SILABS                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_ST                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_TI                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLAN_VENDOR_ZYDAS                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WLCORE                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WLCORE_SDIO                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WLCORE_SPI                               policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_WM831X_BACKUP                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_WM831X_POWER                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_WM831X_WATCHDOG                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_WM8350_POWER                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_WM8350_WATCHDOG                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_WMI_BMOF                                 policy<{'amd64': 'm'}>
+CONFIG_WPCM450_SOC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_WQ_CPU_INTENSIVE_REPORT                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_WQ_POWER_EFFICIENT_DEFAULT               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'n'}>
+CONFIG_WQ_WATCHDOG                              policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_WWAN_DEBUGFS                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_WWAN_HWSIM                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_WW_MUTEX_SELFTEST                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_X25                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_X86                                      policy<{'amd64': 'y'}>
+CONFIG_X86_16BIT                                policy<{'amd64': 'y'}>
+CONFIG_X86_5LEVEL                               policy<{'amd64': 'y'}>
+CONFIG_X86_64                                   policy<{'amd64': 'y'}>
+CONFIG_X86_64_ACPI_NUMA                         policy<{'amd64': 'y'}>
+CONFIG_X86_64_SMP                               policy<{'amd64': 'y'}>
+CONFIG_X86_ACPI_CPUFREQ_CPB                     policy<{'amd64': 'y'}>
+CONFIG_X86_AMD_FREQ_SENSITIVITY                 policy<{'amd64': 'm'}>
+CONFIG_X86_AMD_PLATFORM_DEVICE                  policy<{'amd64': 'y'}>
+CONFIG_X86_AMD_PSTATE                           policy<{'amd64': 'y'}>
+CONFIG_X86_AMD_PSTATE_DEFAULT_MODE              policy<{'amd64': '3'}>
+CONFIG_X86_AMD_PSTATE_UT                        policy<{'amd64': 'n'}>
+CONFIG_X86_ANDROID_TABLETS                      policy<{'amd64': 'm'}>
+CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK    policy<{'amd64': 'y'}>
+CONFIG_X86_CET                                  policy<{'amd64': 'y'}>
+CONFIG_X86_CHECK_BIOS_CORRUPTION                policy<{'amd64': 'y'}>
+CONFIG_X86_CMOV                                 policy<{'amd64': 'y'}>
+CONFIG_X86_CMPXCHG64                            policy<{'amd64': 'y'}>
+CONFIG_X86_CPA_STATISTICS                       policy<{'amd64': 'n'}>
+CONFIG_X86_CPUID                                policy<{'amd64': 'm'}>
+CONFIG_X86_CPU_RESCTRL                          policy<{'amd64': 'y'}>
+CONFIG_X86_DEBUGCTLMSR                          policy<{'amd64': 'y'}>
+CONFIG_X86_DEBUG_FPU                            policy<{'amd64': 'y'}>
+CONFIG_X86_DECODER_SELFTEST                     policy<{'amd64': 'n'}>
+CONFIG_X86_DIRECT_GBPAGES                       policy<{'amd64': 'y'}>
+CONFIG_X86_ESPFIX64                             policy<{'amd64': 'y'}>
+CONFIG_X86_EXTENDED_PLATFORM                    policy<{'amd64': 'y'}>
+CONFIG_X86_GOLDFISH                             policy<{'amd64': 'n'}>
+CONFIG_X86_HAVE_PAE                             policy<{'amd64': 'y'}>
+CONFIG_X86_HV_CALLBACK_VECTOR                   policy<{'amd64': 'y'}>
+CONFIG_X86_INTEL_LPSS                           policy<{'amd64': 'y'}>
+CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS         policy<{'amd64': 'y'}>
+CONFIG_X86_INTEL_MID                            policy<{'amd64': 'n'}>
+CONFIG_X86_INTEL_PSTATE                         policy<{'amd64': 'y'}>
+CONFIG_X86_INTEL_TSX_MODE_AUTO                  policy<{'amd64': 'n'}>
+CONFIG_X86_INTEL_TSX_MODE_OFF                   policy<{'amd64': 'y'}>
+CONFIG_X86_INTEL_TSX_MODE_ON                    policy<{'amd64': 'n'}>
+CONFIG_X86_INTERNODE_CACHE_SHIFT                policy<{'amd64': '6'}>
+CONFIG_X86_IOPL_IOPERM                          policy<{'amd64': 'y'}>
+CONFIG_X86_IO_APIC                              policy<{'amd64': 'y'}>
+CONFIG_X86_L1_CACHE_SHIFT                       policy<{'amd64': '6'}>
+CONFIG_X86_LOCAL_APIC                           policy<{'amd64': 'y'}>
+CONFIG_X86_MCE                                  policy<{'amd64': 'y'}>
+CONFIG_X86_MCELOG_LEGACY                        policy<{'amd64': 'y'}>
+CONFIG_X86_MCE_AMD                              policy<{'amd64': 'y'}>
+CONFIG_X86_MCE_INJECT                           policy<{'amd64': 'm'}>
+CONFIG_X86_MCE_INTEL                            policy<{'amd64': 'y'}>
+CONFIG_X86_MCE_THRESHOLD                        policy<{'amd64': 'y'}>
+CONFIG_X86_MEM_ENCRYPT                          policy<{'amd64': 'y'}>
+CONFIG_X86_MINIMUM_CPU_FAMILY                   policy<{'amd64': '64'}>
+CONFIG_X86_MPPARSE                              policy<{'amd64': 'y'}>
+CONFIG_X86_MSR                                  policy<{'amd64': 'm'}>
+CONFIG_X86_NEED_RELOCS                          policy<{'amd64': 'y'}>
+CONFIG_X86_NUMACHIP                             policy<{'amd64': 'y'}>
+CONFIG_X86_P4_CLOCKMOD                          policy<{'amd64': 'm'}>
+CONFIG_X86_PAT                                  policy<{'amd64': 'y'}>
+CONFIG_X86_PKG_TEMP_THERMAL                     policy<{'amd64': 'm'}>
+CONFIG_X86_PLATFORM_DEVICES                     policy<{'amd64': 'y'}>
+CONFIG_X86_PLATFORM_DRIVERS_DELL                policy<{'amd64': 'y'}>
+CONFIG_X86_PLATFORM_DRIVERS_HP                  policy<{'amd64': 'y'}>
+CONFIG_X86_PMEM_LEGACY                          policy<{'amd64': 'y'}>
+CONFIG_X86_PMEM_LEGACY_DEVICE                   policy<{'amd64': 'y'}>
+CONFIG_X86_PM_TIMER                             policy<{'amd64': 'y'}>
+CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS         policy<{'amd64': 'y'}>
+CONFIG_X86_SGX                                  policy<{'amd64': 'y'}>
+CONFIG_X86_SGX_KVM                              policy<{'amd64': 'y'}>
+CONFIG_X86_SPEEDSTEP_LIB                        policy<{'amd64': 'm'}>
+CONFIG_X86_SUPPORTS_MEMORY_FAILURE              policy<{'amd64': 'y'}>
+CONFIG_X86_THERMAL_VECTOR                       policy<{'amd64': 'y'}>
+CONFIG_X86_TSC                                  policy<{'amd64': 'y'}>
+CONFIG_X86_UMIP                                 policy<{'amd64': 'y'}>
+CONFIG_X86_USER_SHADOW_STACK                    policy<{'amd64': 'y'}>
+CONFIG_X86_VERBOSE_BOOTUP                       policy<{'amd64': 'n'}>
+CONFIG_X86_VMX_FEATURE_NAMES                    policy<{'amd64': 'y'}>
+CONFIG_X86_VSMP                                 policy<{'amd64': 'n'}>
+CONFIG_X86_VSYSCALL_EMULATION                   policy<{'amd64': 'y'}>
+CONFIG_X86_X2APIC                               policy<{'amd64': 'y'}>
+CONFIG_X9250                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_XARRAY_MULTI                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XDP_SOCKETS                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XDP_SOCKETS_DIAG                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_XEN                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'n'}>
+CONFIG_XENFS                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_XEN_ACPI                                 policy<{'amd64': 'y'}>
+CONFIG_XEN_AUTO_XLATE                           policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_XEN_BACKEND                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-'}>
+CONFIG_XEN_BALLOON                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-'}>
+CONFIG_XEN_BALLOON_MEMORY_HOTPLUG               policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_XEN_BLKDEV_BACKEND                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_XEN_COMPAT_XENFS                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-'}>
+CONFIG_XEN_DEBUG_FS                             policy<{'amd64': 'n'}>
+CONFIG_XEN_DEV_EVTCHN                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_XEN_DOM0                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-'}>
+CONFIG_XEN_EFI                                  policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_XEN_FBDEV_FRONTEND                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_XEN_FRONT_PGDIR_SHBUF                    policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_XEN_GNTDEV                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_XEN_GNTDEV_DMABUF                        policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-'}>
+CONFIG_XEN_GRANT_DEV_ALLOC                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_XEN_GRANT_DMA_ALLOC                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-'}>
+CONFIG_XEN_GRANT_DMA_IOMMU                      policy<{'arm64': 'y'}>
+CONFIG_XEN_GRANT_DMA_OPS                        policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_XEN_HAVE_PVMMU                           policy<{'amd64': 'y'}>
+CONFIG_XEN_HAVE_VPMU                            policy<{'amd64': 'y'}>
+CONFIG_XEN_MCE_LOG                              policy<{'amd64': 'y'}>
+CONFIG_XEN_MEMORY_HOTPLUG_LIMIT                 policy<{'amd64': '512'}>
+CONFIG_XEN_NETDEV_BACKEND                       policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_XEN_PCIDEV_BACKEND                       policy<{'amd64': 'm'}>
+CONFIG_XEN_PCIDEV_FRONTEND                      policy<{'amd64': 'm'}>
+CONFIG_XEN_PCIDEV_STUB                          policy<{'arm64': 'm'}>
+CONFIG_XEN_PCI_STUB                             policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_XEN_PRIVCMD                              policy<{'amd64': 'm', 'arm64': 'm'}>
+CONFIG_XEN_PRIVCMD_EVENTFD                      policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_XEN_PV                                   policy<{'amd64': 'y'}>
+CONFIG_XEN_PVCALLS_BACKEND                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': '-'}>
+CONFIG_XEN_PVCALLS_FRONTEND                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_XEN_PVH                                  policy<{'amd64': 'y'}>
+CONFIG_XEN_PVHVM                                policy<{'amd64': 'y'}>
+CONFIG_XEN_PVHVM_GUEST                          policy<{'amd64': 'y'}>
+CONFIG_XEN_PVHVM_SMP                            policy<{'amd64': 'y'}>
+CONFIG_XEN_PV_DOM0                              policy<{'amd64': 'y'}>
+CONFIG_XEN_PV_MSR_SAFE                          policy<{'amd64': 'y'}>
+CONFIG_XEN_PV_SMP                               policy<{'amd64': 'y'}>
+CONFIG_XEN_SAVE_RESTORE                         policy<{'amd64': 'y'}>
+CONFIG_XEN_SCRUB_PAGES_DEFAULT                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-'}>
+CONFIG_XEN_SCSI_BACKEND                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_XEN_SCSI_FRONTEND                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_XEN_SYMS                                 policy<{'amd64': 'y'}>
+CONFIG_XEN_SYS_HYPERVISOR                       policy<{'amd64': 'y', 'arm64': 'y', 'armhf': '-'}>
+CONFIG_XEN_UNPOPULATED_ALLOC                    policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_XEN_VIRTIO                               policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_XEN_VIRTIO_FORCE_GRANT                   policy<{'amd64': 'n', 'arm64': 'n'}>
+CONFIG_XEN_WDT                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}>
+CONFIG_XEN_XENBUS_FRONTEND                      policy<{'amd64': 'y', 'arm64': 'y'}>
+CONFIG_XFRM                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XFRM_AH                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_XFRM_ALGO                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_XFRM_ESP                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_XFRM_ESPINTCP                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XFRM_INTERFACE                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_XFRM_IPCOMP                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_XFRM_MIGRATE                             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_XFRM_OFFLOAD                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XFRM_STATISTICS                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XFRM_SUB_POLICY                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_XFRM_USER                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_XFRM_USER_COMPAT                         policy<{'amd64': 'm'}>
+CONFIG_XFS_DEBUG                                policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_XFS_FS                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_XFS_ONLINE_SCRUB                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_XFS_POSIX_ACL                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XFS_QUOTA                                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XFS_RT                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XFS_SUPPORT_ASCII_CI                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XFS_SUPPORT_V4                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XFS_WARN                                 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_XGENE_DMA                                policy<{'arm64': 'm'}>
+CONFIG_XGENE_PMU                                policy<{'arm64': 'y'}>
+CONFIG_XGENE_SLIMPRO_MBOX                       policy<{'arm64': 'm'}>
+CONFIG_XIAOMI_WMI                               policy<{'amd64': 'm'}>
+CONFIG_XILINX_AMS                               policy<{'arm64': 'm'}>
+CONFIG_XILINX_AXI_EMAC                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_XILINX_DMA                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_XILINX_EMACLITE                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_XILINX_GMII2RGMII                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_XILINX_INTC                              policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_XILINX_LL_TEMAC                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_XILINX_PR_DECOUPLER                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_XILINX_SDFEC                             policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_XILINX_VCU                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_XILINX_WATCHDOG                          policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_XILINX_WINDOW_WATCHDOG                   policy<{'arm64': 'm'}>
+CONFIG_XILINX_XADC                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_XILINX_XDMA                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_XILINX_ZYNQMP_DMA                        policy<{'arm64': 'm'}>
+CONFIG_XILINX_ZYNQMP_DPDMA                      policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_XILLYBUS                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_XILLYBUS_CLASS                           policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_XILLYBUS_OF                              policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_XILLYBUS_PCIE                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_XILLYUSB                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}>
+CONFIG_XIL_AXIS_FIFO                            policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_XLNX_EVENT_MANAGER                       policy<{'arm64': 'y'}>
+CONFIG_XLNX_R5_REMOTEPROC                       policy<{'arm64': 'm'}>
+CONFIG_XMON                                     policy<{'ppc64el': 'y'}>
+CONFIG_XMON_DEFAULT                             policy<{'ppc64el': 'n'}>
+CONFIG_XMON_DEFAULT_RO_MODE                     policy<{'ppc64el': 'y'}>
+CONFIG_XMON_DISASSEMBLY                         policy<{'ppc64el': 'y'}>
+CONFIG_XOR_BLOCKS                               policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_XPOWER_PMIC_OPREGION                     policy<{'amd64': 'y'}>
+CONFIG_XPS                                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XXHASH                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XZ_DEC_ARM                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_XZ_DEC_ARMTHUMB                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_XZ_DEC_BCJ                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_XZ_DEC_MICROLZMA                         policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_XZ_DEC_POWERPC                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_XZ_DEC_SPARC                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_XZ_DEC_TEST                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_XZ_DEC_X86                               policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}>
+CONFIG_YAM                                      policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_YAMAHA_YAS530                            policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_YELLOWFIN                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_YENTA                                    policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': '-'}>
+CONFIG_YENTA_ENE_TUNE                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': '-'}>
+CONFIG_YENTA_O2                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': '-'}>
+CONFIG_YENTA_RICOH                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': '-'}>
+CONFIG_YENTA_TI                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': '-'}>
+CONFIG_YENTA_TOSHIBA                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': '-'}>
+CONFIG_YOGABOOK                                 policy<{'amd64': 'm'}>
+CONFIG_Z3FOLD                                   policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_Z3FOLD_DEPRECATED                        policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ZBOOT_ROM_BSS                            policy<{'armhf': '0x0'}>
+CONFIG_ZBOOT_ROM_TEXT                           policy<{'armhf': '0x0'}>
+CONFIG_ZBUD                                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZCRYPT                                   policy<{'s390x': 'm'}>
+CONFIG_ZCRYPT_DEBUG                             policy<{'s390x': 'n'}>
+CONFIG_ZD1211RW                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ZD1211RW_DEBUG                           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}>
+CONFIG_ZEROPLUS_FF                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}>
+CONFIG_ZERO_CALL_USED_REGS                      policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZFCP                                     policy<{'s390x': 'm'}>
+CONFIG_ZIIRAVE_WATCHDOG                         policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}>
+CONFIG_ZISOFS                                   policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZLIB_DEFLATE                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZLIB_INFLATE                             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZONEFS_FS                                policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ZONE_DEVICE                              policy<{'amd64': 'y', 'arm64': 'y', 'ppc64el': 'y'}>
+CONFIG_ZONE_DMA32                               policy<{'amd64': 'y', 'arm64': 'y', 'riscv64': 'y'}>
+CONFIG_ZOPT2201                                 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ZPA2326                                  policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ZPA2326_I2C                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ZPA2326_SPI                              policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}>
+CONFIG_ZPOOL                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZRAM                                     policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}>
+CONFIG_ZRAM_DEF_COMP                            policy<{'amd64': '"lzo-rle"', 'arm64': '"lzo-rle"', 'armhf': '"lzo-rle"', 'ppc64el': '"lzo-rle"', 'riscv64': '"lzo-rle"', 's390x': '"lzo-rle"'}>
+CONFIG_ZRAM_DEF_COMP_842                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZRAM_DEF_COMP_LZ4                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZRAM_DEF_COMP_LZ4HC                      policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZRAM_DEF_COMP_LZO                        policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZRAM_DEF_COMP_LZORLE                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZRAM_DEF_COMP_ZSTD                       policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZRAM_MEMORY_TRACKING                     policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZRAM_MULTI_COMP                          policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZRAM_TRACK_ENTRY_ACTIME                  policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZRAM_WRITEBACK                           policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZSMALLOC                                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZSMALLOC_CHAIN_SIZE                      policy<{'amd64': '8', 'arm64': '8', 'armhf': '8', 'ppc64el': '8', 'riscv64': '8', 's390x': '8'}>
+CONFIG_ZSMALLOC_STAT                            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZSTD_COMMON                              policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZSTD_COMPRESS                            policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZSTD_DECOMPRESS                          policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZSWAP                                    policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZSWAP_COMPRESSOR_DEFAULT                 policy<{'amd64': '"lzo"', 'arm64': '"lzo"', 'armhf': '"lzo"', 'ppc64el': '"lzo"', 'riscv64': '"lzo"', 's390x': '"lzo"'}>
+CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC           policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO             policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD            policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZSWAP_DEFAULT_ON                         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZSWAP_EXCLUSIVE_LOADS_DEFAULT_ON         policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZSWAP_SHRINKER_DEFAULT_ON                policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZSWAP_ZPOOL_DEFAULT                      policy<{'amd64': '"zbud"', 'arm64': '"zbud"', 'armhf': '"zbud"', 'ppc64el': '"zbud"', 'riscv64': '"zbud"', 's390x': '"zbud"'}>
+CONFIG_ZSWAP_ZPOOL_DEFAULT_Z3FOLD_DEPRECATED    policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD                 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}>
+CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC             policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}>
+CONFIG_ZYNQMP_FIRMWARE                          policy<{'arm64': 'y'}>
+CONFIG_ZYNQMP_FIRMWARE_DEBUG                    policy<{'arm64': 'n'}>
+CONFIG_ZYNQMP_IPI_MBOX                          policy<{'arm64': 'y'}>
+CONFIG_ZYNQMP_PM_DOMAINS                        policy<{'arm64': 'y'}>
+CONFIG_ZYNQMP_POWER                             policy<{'arm64': 'y'}>
--- linux-qcom-6.8.0.orig/debian.master/control.d/flavour-control.stub
+++ linux-qcom-6.8.0/debian.master/control.d/flavour-control.stub
@@ -0,0 +1,153 @@
+# Items that get replaced:
+# FLAVOUR
+# DESC
+# ARCH
+# SUPPORTED
+# TARGET
+# BOOTLOADER
+# =PROVIDES=
+#
+# Items marked with =FOO= are optional
+#
+# This file describes the template for packages that are created for each flavour
+# in debian/control.d/vars.*
+#
+# This file gets edited in a couple of places. See the debian/control.stub rule in
+# debian/rules. PGGVER, ABINUM, and SRCPKGNAME are all converted in the
+# process of creating debian/control.
+#
+# The flavour specific strings (ARCH, DESC, etc) are converted using values from the various
+# flavour files in debian/control.d/vars.*
+#
+# XXX: Leave the blank line before the first package!!
+
+Package: linux-image=SIGN-ME-PKG=-PKGVER-ABINUM-FLAVOUR
+Build-Profiles: <!stage1>
+Architecture: ARCH
+Section: kernel
+Priority: optional
+Provides: linux-image, fuse-module, =PROVIDES=${linux:rprovides}
+Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-PKGVER-ABINUM-FLAVOUR
+Recommends: BOOTLOADER, initramfs-tools | linux-initramfs-tool
+Breaks: flash-kernel (<< 3.90ubuntu2) [arm64 armhf], s390-tools (<< 2.3.0-0ubuntu3) [s390x]
+Conflicts: linux-image=SIGN-PEER-PKG=-PKGVER-ABINUM-FLAVOUR
+Suggests: fdutils, SRCPKGNAME-tools, linux-headers-PKGVER-ABINUM-FLAVOUR, linux-modules-extra-PKGVER-ABINUM-FLAVOUR
+Description: Linux kernel image for version PKGVER on DESC
+ This package contains the=SIGN-ME-TXT= Linux kernel image for version PKGVER on
+ DESC.
+ .
+ Supports SUPPORTED processors.
+ .
+ TARGET
+ .
+ You likely do not want to install this package directly. Instead, install
+ the linux-FLAVOUR meta-package, which will ensure that upgrades work
+ correctly, and that supporting packages are also installed.
+
+Package: linux-modules-PKGVER-ABINUM-FLAVOUR
+Build-Profiles: <!stage1>
+Architecture: ARCH
+Section: kernel
+Priority: optional
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Built-Using: ${linux:BuiltUsing}
+Description: Linux kernel extra modules for version PKGVER on DESC
+ Contains the corresponding System.map file, the modules built by the
+ packager, and scripts that try to ensure that the system is not left in an
+ unbootable state after an update.
+ .
+ Supports SUPPORTED processors.
+ .
+ TARGET
+ .
+ You likely do not want to install this package directly. Instead, install
+ the linux-FLAVOUR meta-package, which will ensure that upgrades work
+ correctly, and that supporting packages are also installed.
+
+Package: linux-modules-extra-PKGVER-ABINUM-FLAVOUR
+Build-Profiles: <!stage1>
+Architecture: ARCH
+Section: kernel
+Priority: optional
+Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-PKGVER-ABINUM-FLAVOUR, wireless-regdb
+Description: Linux kernel extra modules for version PKGVER on DESC
+ This package contains the Linux kernel extra modules for version PKGVER on
+ DESC.
+ .
+ Also includes the corresponding System.map file, the modules built by the
+ packager, and scripts that try to ensure that the system is not left in an
+ unbootable state after an update.
+ .
+ Supports SUPPORTED processors.
+ .
+ TARGET
+ .
+ You likely do not want to install this package directly. Instead, install
+ the linux-FLAVOUR meta-package, which will ensure that upgrades work
+ correctly, and that supporting packages are also installed.
+
+Package: linux-headers-PKGVER-ABINUM-FLAVOUR
+Build-Profiles: <!stage1>
+Architecture: ARCH
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, SRCPKGNAME-headers-PKGVER-ABINUM, ${shlibs:Depends}
+Provides: linux-headers, linux-headers-3.0
+Description: Linux kernel headers for version PKGVER on DESC
+ This package provides kernel header files for version PKGVER on
+ DESC.
+ .
+ This is for sites that want the latest kernel headers.  Please read
+ /usr/share/doc/linux-headers-PKGVER-ABINUM/debian.README.gz for details.
+
+Package: SRCPKGNAME-lib-rust-PKGVER-ABINUM-FLAVOUR
+Build-Profiles: <!stage1>
+Architecture: amd64
+Multi-Arch: foreign
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, coreutils
+Description: Rust library files related to Linux kernel version PKGVER
+ This package provides kernel library files for version PKGVER, that allow to
+ compile out-of-tree kernel modules written in Rust.
+
+Package: linux-image=SIGN-ME-PKG=-PKGVER-ABINUM-FLAVOUR-dbgsym
+Build-Profiles: <!stage1>
+Architecture: ARCH
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}
+Provides: linux-debug
+Description: Linux kernel debug image for version PKGVER on DESC
+ This package provides the=SIGN-ME-TXT= kernel debug image for version PKGVER on
+ DESC.
+ .
+ This is for sites that wish to debug the kernel.
+ .
+ The kernel image contained in this package is NOT meant to boot from. It
+ is uncompressed, and unstripped. This package also includes the
+ unstripped modules.
+
+Package: linux-tools-PKGVER-ABINUM-FLAVOUR
+Build-Profiles: <!stage1>
+Architecture: ARCH
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, SRCPKGNAME-tools-PKGVER-ABINUM
+Description: Linux kernel version specific tools for version PKGVER-ABINUM
+ This package provides the architecture dependant parts for kernel
+ version locked tools (such as perf and x86_energy_perf_policy) for
+ version PKGVER-ABINUM on
+ =HUMAN=.
+
+Package: linux-cloud-tools-PKGVER-ABINUM-FLAVOUR
+Build-Profiles: <!stage1>
+Architecture: ARCH
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, SRCPKGNAME-cloud-tools-PKGVER-ABINUM
+Description: Linux kernel version specific cloud tools for version PKGVER-ABINUM
+ This package provides the architecture dependant parts for kernel
+ version locked tools for cloud for version PKGVER-ABINUM on
+ =HUMAN=.
+
--- linux-qcom-6.8.0.orig/debian.master/control.d/generic.inclusion-list
+++ linux-qcom-6.8.0/debian.master/control.d/generic.inclusion-list
@@ -0,0 +1,307 @@
+arch/*/{crypto,kernel,oprofile}
+arch/*/kvm/kvm.ko
+arch/powerpc/kvm/kvm-hv.ko
+arch/powerpc/kvm/kvm-pr.ko
+arch/powerpc/kvm/vfio.ko
+arch/powerpc/platforms/powernv/opal-prd.ko
+arch/s390/*
+arch/x86/kvm/kvm-amd.ko
+arch/x86/kvm/kvm-intel.ko
+crypto/*
+drivers/acpi/*
+drivers/ata/acard-ahci.ko
+drivers/ata/ahci.ko
+drivers/ata/ahci_platform.ko
+drivers/ata/ahci_tegra.ko
+drivers/ata/ata_generic.ko
+drivers/ata/libahci.ko
+drivers/ata/libahci_platform.ko
+drivers/block/brd.ko
+drivers/block/cryptoloop.ko
+drivers/block/floppy.ko
+drivers/block/loop.ko
+drivers/block/nbd.ko
+drivers/block/rbd.ko
+drivers/block/virtio_blk.ko
+drivers/block/xen-blkfront.ko
+drivers/bus/tegra-aconnect.ko
+drivers/char/hangcheck-timer.ko
+drivers/char/hw_random/powernv-rng.ko
+drivers/char/hw_random/virtio-rng.ko
+drivers/char/ipmi/*
+drivers/char/ipmi/ipmi_msghandler.ko
+drivers/char/lp.ko
+drivers/char/nvram.ko
+drivers/char/ppdev.ko
+drivers/char/raw.ko
+drivers/char/virtio_console.ko
+drivers/clk/clk-max77686.ko
+drivers/cpufreq/tegra186-cpufreq.ko
+drivers/cpufreq/tegra194-cpufreq.ko
+drivers/crypto/nx/*
+drivers/crypto/vmx/vmx-crypto.ko
+drivers/dma/tegra210-adma.ko
+drivers/firmware/dmi-sysfs.ko
+drivers/firmware/efi/*
+drivers/firmware/iscsi_ibft.ko
+drivers/gpio/gpio-max77620.ko
+drivers/gpu/drm/ast/ast.ko
+drivers/gpu/drm/bochs/bochs-drm.ko
+drivers/gpu/drm/cirrus/cirrus.ko
+drivers/gpu/drm/drm.ko
+drivers/gpu/drm/drm_kms_helper.ko
+drivers/gpu/drm/tegra/tegra-drm.ko
+drivers/gpu/drm/ttm/ttm.ko
+drivers/gpu/drm/vboxvideo/vboxvideo.ko
+drivers/gpu/drm/virtio/virtio-gpu.ko
+drivers/gpu/drm/vmwgfx/vmwgfx.ko
+drivers/gpu/drm/xen/drm_xen_front.ko
+drivers/gpu/host1x/host1x.ko
+drivers/hid/hid-generic.ko
+drivers/hid/hid-hyperv.ko
+drivers/hid/hid.ko
+drivers/hid/usbhid/usbhid.ko
+drivers/hv/*
+drivers/hwmon/ibmpowernv.ko
+drivers/hwmon/pwm-fan.ko
+drivers/i2c/busses/i2c-tegra-bpmp.ko
+drivers/i2c/busses/i2c-tegra-bpmp.ko
+drivers/i2c/busses/i2c-tegra.ko
+drivers/infiniband/core/ib_addr.ko
+drivers/infiniband/core/ib_cm.ko
+drivers/infiniband/core/ib_core.ko
+drivers/infiniband/core/ib_mad.ko
+drivers/infiniband/core/ib_sa.ko
+drivers/infiniband/core/iw_cm.ko
+drivers/infiniband/core/rdma_cm.ko
+drivers/infiniband/ulp/iser/ib_iser.ko
+drivers/infiniband/ulp/isert/ib_isert.ko
+drivers/input/evbug.ko
+drivers/input/gameport/gameport.ko
+drivers/input/input-leds.ko
+drivers/input/joydev.ko
+drivers/input/keyboard/gpio_keys.ko
+drivers/input/misc/xen-kbdfront.ko
+drivers/input/mouse/psmouse.ko
+drivers/input/serio/hyperv-keyboard.ko
+drivers/input/serio/serio_raw.ko
+drivers/input/serio/serport.ko
+drivers/input/touchscreen/usbtouchscreen.ko
+drivers/leds/leds-powernv.ko
+drivers/md/*
+drivers/memory/tegra/tegra210-emc.ko
+drivers/message/fusion*
+drivers/misc/cxl/*
+drivers/misc/eeprom/at24.ko
+drivers/misc/vmw_balloon.ko
+drivers/misc/vmw_vmci/vmw_vmci.ko
+drivers/mmc/host/sdhci-tegra.ko
+drivers/mtd/cmdlinepart.ko
+drivers/mtd/devices/powernv_flash.ko
+drivers/mtd/ofpart.ko
+drivers/net/appletalk/ipddp.ko
+drivers/net/bonding/bonding.ko
+drivers/net/caif/caif_virtio.ko
+drivers/net/dummy.ko
+drivers/net/eql.ko
+drivers/net/ethernet/8390/8390.ko
+drivers/net/ethernet/8390/ne2k-pci.ko
+drivers/net/ethernet/amazon/ena/ena.ko
+drivers/net/ethernet/amd/pcnet32.ko
+drivers/net/ethernet/broadcom/bnx2x/*
+drivers/net/ethernet/broadcom/tg3.ko
+drivers/net/ethernet/dec/tulip/*
+drivers/net/ethernet/emulex/benet/*
+drivers/net/ethernet/ibm/*
+drivers/net/ethernet/intel/e1000/e1000.ko
+drivers/net/ethernet/intel/e1000e/e1000e.ko
+drivers/net/ethernet/intel/i40e/*
+drivers/net/ethernet/intel/iavf/iavf.ko
+drivers/net/ethernet/intel/igb/*
+drivers/net/ethernet/intel/igbvf/igbvf.ko
+drivers/net/ethernet/intel/ixgbe/*
+drivers/net/ethernet/intel/ixgbevf/ixgbevf.ko
+drivers/net/ethernet/mellanox/*
+drivers/net/ethernet/netronome/nfp/nfp.ko
+drivers/net/ethernet/realtek/8139cp.ko
+drivers/net/ethernet/realtek/8139too.ko
+drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.ko
+drivers/net/ethernet/stmicro/stmmac/stmmac-platform.ko
+drivers/net/ethernet/stmicro/stmmac/stmmac.ko
+drivers/net/fddi/*
+drivers/net/geneve.ko
+drivers/net/hyperv/hv_netvsc.ko
+drivers/net/ifb.ko
+drivers/net/ipvlan/*
+drivers/net/macvlan.ko
+drivers/net/macvtap.ko
+drivers/net/mii.ko
+drivers/net/netconsole.ko
+drivers/net/pcs/pcs-xpcs.ko
+drivers/net/phy/marvell.ko
+drivers/net/phy/phylink.ko
+drivers/net/ppp/*
+drivers/net/ppp/bsd_comp.ko
+drivers/net/slip/*
+drivers/net/veth.ko
+drivers/net/virtio_net.ko
+drivers/net/vmxnet3/vmxnet3.ko
+drivers/net/vxlan.ko
+drivers/net/wireguard/wireguard.ko
+drivers/net/wwan/*
+drivers/net/xen-netback/*
+drivers/net/xen-netfront.ko
+drivers/nvme/host/nvme.ko
+drivers/nvmem/nvmem_core.ko
+drivers/parport/parport.ko
+drivers/parport/parport_pc.ko
+drivers/pci/controller/dwc/pcie-tegra194.ko
+drivers/pci/host/vmd.ko
+drivers/phy/tegra/phy-tegra194-p2u.ko
+drivers/pinctrl/pinctrl-max77620.ko
+drivers/platform/x86/pvpanic.ko
+drivers/pps/pps_core.ko
+drivers/ptp/ptp.ko
+drivers/pwm/pwm-tegra.ko
+drivers/regulator/fixed.ko
+drivers/regulator/max77620-regulator.ko
+drivers/rtc/rtc-max77686.ko
+drivers/rtc/rtc-tegra.ko
+drivers/s390/*
+drivers/s390/block/xpram.ko
+drivers/scsi/BusLogic.ko
+drivers/scsi/aacraid/*
+drivers/scsi/cxlflash/*
+drivers/scsi/device_handler/scsi_dh_alua.ko
+drivers/scsi/device_handler/scsi_dh_emc.ko
+drivers/scsi/device_handler/scsi_dh_hp_sw.ko
+drivers/scsi/device_handler/scsi_dh_rdac.ko
+drivers/scsi/hv_storvsc.ko
+drivers/scsi/ibmvscsi/*
+drivers/scsi/ipr.ko
+drivers/scsi/iscsi_boot_sysfs.ko
+drivers/scsi/iscsi_tcp.ko
+drivers/scsi/libiscsi.ko
+drivers/scsi/libiscsi_tcp.ko
+drivers/scsi/libsas/*
+drivers/scsi/lpfc/*
+drivers/scsi/megaraid/*
+drivers/scsi/mpt3sas/*
+drivers/scsi/osd/libosd.ko
+drivers/scsi/osd/osd.ko
+drivers/scsi/qla1280.ko
+drivers/scsi/qla2xxx/*
+drivers/scsi/raid_class.ko
+drivers/scsi/scsi_transport_fc.ko
+drivers/scsi/scsi_transport_iscsi.ko
+drivers/scsi/scsi_transport_sas.ko
+drivers/scsi/scsi_transport_spi.ko
+drivers/scsi/sd_mod.ko
+drivers/scsi/sr_mod.ko
+drivers/scsi/virtio_scsi.ko
+drivers/scsi/vmw_pvscsi.ko
+drivers/spi/spi-tegra114.ko
+drivers/staging/media/tegra-video/tegra-video.ko
+drivers/target/loopback/tcm_loop.ko
+drivers/target/target_core*.ko
+drivers/thermal/tegra/tegra-bpmp-thermal.ko
+drivers/tty/serial/jsm/*
+drivers/tty/serial/serial-tegra.ko
+drivers/uio/uio.ko
+drivers/uio/uio_pdrv_genirq.ko
+drivers/usb/gadget/udc/tegra-xudc.ko
+drivers/usb/host/*
+drivers/usb/storage/uas.ko
+drivers/usb/storage/usb-storage.ko
+drivers/vfio/*
+drivers/vhost/*
+drivers/video/fbdev/*
+drivers/video/vgastate.ko
+drivers/virt/vboxguest/vboxguest.ko
+drivers/virtio/*
+drivers/watchdog/softdog.ko
+drivers/watchdog/wdat_wdt.ko
+drivers/xen/*
+fs/9p/*
+fs/aufs/aufs.ko
+fs/autofs/autofs4.ko
+fs/binfmt_misc.ko
+fs/btrfs/*
+fs/cachefiles/cachefiles.ko
+fs/ceph/*
+fs/smb/*
+fs/configfs/*
+fs/dlm/dlm.ko
+fs/ecryptfs/*
+fs/efivarfs/*
+fs/erofs/*
+fs/exofs/libore.ko
+fs/ext4/*
+fs/fat/*
+fs/fscache/*
+fs/fuse/*
+fs/isofs/*
+fs/lockd/*
+fs/nfs/*
+fs/nfs_common/*
+fs/nfsd/*
+fs/nls/nls_cp437.ko
+fs/nls/nls_iso8859-1.ko
+fs/overlayfs/*
+fs/shiftfs.ko
+fs/squashfs/*
+fs/udf/*
+fs/ufs/*
+fs/vboxsf/vboxsf.ko
+fs/xfs/*
+lib/*
+net/6lowpan/*
+net/802/*
+net/8021q/*
+net/9p/*
+net/appletalk/*
+net/atm/*
+net/ax25/*
+net/bpfilter/*
+net/bridge/*
+net/can/*
+net/ceph/libceph.ko
+net/core/*
+net/dccp/*
+net/decnet/*
+net/ieee802154/*
+net/ipv4/*
+net/ipv6/*
+net/ipx/*
+net/key/*
+net/lapb/*
+net/llc/*
+net/netfilter/*
+net/netlink/netlink_diag.ko
+net/netrom/*
+net/openvswitch/*
+net/packet/af_packet_diag.ko
+net/phonet/*
+net/rose/*
+net/rxrpc/*
+net/sched/*
+net/sctp/*
+net/sunrpc/auth_gss/auth_rpcgss.ko
+net/sunrpc/auth_gss/rpcsec_gss_krb5.ko
+net/sunrpc/sunrpc.ko
+net/tipc/*
+net/unix/unix_diag.ko
+net/vmw_vsock/*
+net/x25/*
+net/xfrm/*
+! find sound/core -name oss -prune -o -name *.ko -print
+sound/drivers/pcsp/snd-pcsp.ko
+sound/pci/hda/snd-hda-tegra.ko
+sound/pci/snd-ens1370.ko
+sound/soc/tegra/snd-soc-tegra186-dspk.ko
+sound/soc/tegra/snd-soc-tegra210-admaif.ko
+sound/soc/tegra/snd-soc-tegra210-ahub.ko
+sound/soc/tegra/snd-soc-tegra210-dmic.ko
+sound/soc/tegra/snd-soc-tegra210-i2s.ko
+sound/soundcore.ko
+ubuntu/ubuntu-host/ubuntu-host.ko
--- linux-qcom-6.8.0.orig/debian.master/control.d/vars.generic
+++ linux-qcom-6.8.0/debian.master/control.d/vars.generic
@@ -0,0 +1,6 @@
+arch="amd64 armhf arm64 ppc64el s390x"
+supported="Generic"
+target="Geared toward desktop and server systems."
+desc="=HUMAN= SMP"
+bootloader="grub-pc [amd64] | grub-efi-amd64 [amd64] | grub-efi-ia32 [amd64] | grub [amd64] | lilo [amd64] | flash-kernel [armhf arm64] | grub-efi-arm64 [arm64] | grub-efi-arm [armhf] | grub-ieee1275 [ppc64el]"
+provides="kvm-api-4, redhat-cluster-modules, ivtv-modules, virtualbox-guest-modules [amd64]"
--- linux-qcom-6.8.0.orig/debian.master/control.d/vars.generic-64k
+++ linux-qcom-6.8.0/debian.master/control.d/vars.generic-64k
@@ -0,0 +1,6 @@
+arch="arm64"
+supported="Generic 64K pages"
+target="Geared toward desktop and server systems."
+desc="=HUMAN= SMP"
+bootloader="grub-efi-arm64 [arm64] | flash-kernel [arm64]"
+provides="kvm-api-4, redhat-cluster-modules, ivtv-modules"
--- linux-qcom-6.8.0.orig/debian.master/control.d/vars.generic-lpae
+++ linux-qcom-6.8.0/debian.master/control.d/vars.generic-lpae
@@ -0,0 +1,6 @@
+arch="armhf"
+supported="Generic LPAE"
+target="Geared toward desktop and server systems."
+desc="=HUMAN= SMP"
+bootloader="flash-kernel [armhf] | grub-efi-arm [armhf]"
+provides="kvm-api-4, redhat-cluster-modules, ivtv-modules"
--- linux-qcom-6.8.0.orig/debian.master/control.stub.in
+++ linux-qcom-6.8.0/debian.master/control.stub.in
@@ -0,0 +1,98 @@
+Source: SRCPKGNAME
+Section: devel
+Priority: optional
+Maintainer: Ubuntu Kernel Team <kernel-team@lists.ubuntu.com>
+Rules-Requires-Root: no
+Standards-Version: 3.9.4.0
+Build-Depends:
+ autoconf <!stage1>,
+ automake <!stage1>,
+ bc <!stage1>,
+ bindgen-0.65 [amd64 arm64 armhf ppc64el riscv64 s390x],
+ bison <!stage1>,
+ clang-18 [amd64 arm64 armhf ppc64el riscv64 s390x],
+ cpio,
+ curl <!stage1>,
+ debhelper-compat (= 10),
+ default-jdk-headless <!stage1>,
+ dkms <!stage1>,
+ dwarfdump <!stage1>,
+ flex <!stage1>,
+ gawk <!stage1>,
+ java-common <!stage1>,
+ kmod <!stage1>,
+ libaudit-dev <!stage1>,
+ libcap-dev <!stage1>,
+ libdw-dev <!stage1>,
+ libelf-dev <!stage1>,
+ libiberty-dev <!stage1>,
+ liblzma-dev <!stage1>,
+ libnewt-dev <!stage1>,
+ libnuma-dev [amd64 arm64 ppc64el s390x] <!stage1>,
+ libpci-dev <!stage1>,
+ libssl-dev <!stage1>,
+ libstdc++-dev,
+ libtool <!stage1>,
+ libtraceevent-dev [amd64 arm64 armhf ppc64el s390x riscv64] <!stage1>,
+ libtracefs-dev [amd64 arm64 armhf ppc64el s390x riscv64] <!stage1>,
+ libudev-dev <!stage1>,
+ libunwind8-dev [amd64 arm64 armhf ppc64el] <!stage1>,
+ makedumpfile [amd64] <!stage1>,
+ openssl <!stage1>,
+ pahole [amd64 arm64 armhf ppc64el s390x riscv64] | dwarves (>= 1.21) [amd64 arm64 armhf ppc64el s390x riscv64] <!stage1>,
+ pkg-config <!stage1>,
+ python3 <!stage1>,
+ python3-dev <!stage1>,
+ python3-setuptools <!stage1>,
+ rsync [!i386] <!stage1>,
+ rust-src [amd64 arm64 armhf ppc64el riscv64 s390x],
+ rustc [amd64 arm64 armhf ppc64el riscv64 s390x],
+ rustfmt [amd64 arm64 armhf ppc64el riscv64 s390x],
+ uuid-dev <!stage1>,
+ zstd <!stage1>,
+Build-Depends-Indep:
+ asciidoc <!stage1>,
+ bzip2 <!stage1>,
+ python3-docutils <!stage1>,
+ sharutils <!stage1>,
+ xmlto <!stage1>,
+Vcs-Git: git://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/=SERIES=
+XS-Testsuite: autopkgtest
+#XS-Testsuite-Depends: gcc-4.7 binutils
+
+Package: SRCPKGNAME-headers-PKGVER-ABINUM
+Build-Profiles: <!stage1>
+Architecture: all
+Multi-Arch: foreign
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, coreutils
+Description: Header files related to Linux kernel version PKGVER
+ This package provides kernel header files for version PKGVER, for sites
+ that want the latest kernel headers. Please read
+ /usr/share/doc/SRCPKGNAME-headers-PKGVER-ABINUM/debian.README.gz for details
+
+Package: SRCPKGNAME-tools-PKGVER-ABINUM
+Build-Profiles: <!stage1>
+Architecture: amd64 armhf arm64 ppc64el s390x
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, ${shlibs:Depends}, linux-tools-common
+Description: Linux kernel version specific tools for version PKGVER-ABINUM
+ This package provides the architecture dependant parts for kernel
+ version locked tools (such as perf and x86_energy_perf_policy) for
+ version PKGVER-ABINUM on
+ =HUMAN=.
+ You probably want to install linux-tools-PKGVER-ABINUM-<flavour>.
+
+Package: SRCPKGNAME-cloud-tools-PKGVER-ABINUM
+Build-Profiles: <!stage1>
+Architecture: amd64 armhf
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, ${shlibs:Depends}, linux-cloud-tools-common
+Description: Linux kernel version specific cloud tools for version PKGVER-ABINUM
+ This package provides the architecture dependant parts for kernel
+ version locked tools for cloud tools for version PKGVER-ABINUM on
+ =HUMAN=.
+ You probably want to install linux-cloud-tools-PKGVER-ABINUM-<flavour>.
--- linux-qcom-6.8.0.orig/debian.master/copyright
+++ linux-qcom-6.8.0/debian.master/copyright
@@ -0,0 +1,29 @@
+This is the Ubuntu prepackaged version of the Linux kernel.
+Linux was written by Linus Torvalds <Linus.Torvalds@cs.Helsinki.FI>
+and others.
+
+This package was put together by the Ubuntu Kernel Team, from
+sources retrieved from upstream linux git.
+The sources may be found at most Linux ftp sites, including 
+ftp://ftp.kernel.org/pub/linux/kernel/
+
+This package is currently maintained by the
+Ubuntu Kernel Team <ubuntu-kernel@lists.ubuntu.com>
+
+Linux is copyrighted by Linus Torvalds and others.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 dated June, 1991.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+On Ubuntu Linux systems, the complete text of the GNU General
+Public License v2 can be found in `/usr/share/common-licenses/GPL-2'.
--- linux-qcom-6.8.0.orig/debian.master/dkms-versions
+++ linux-qcom-6.8.0/debian.master/dkms-versions
@@ -0,0 +1,5 @@
+zfs-linux 2.2.2-0ubuntu9.2 modulename=zfs debpath=pool/universe/z/%package%/zfs-dkms_%version%_all.deb arch=amd64 arch=arm64 arch=ppc64el arch=s390x rprovides=spl-modules rprovides=spl-dkms rprovides=zfs-modules rprovides=zfs-dkms
+ipu6-drivers 0~git202406240945.aecec2aa-0ubuntu2~24.04.2 modulename=ipu6 debpath=pool/universe/i/%package%/intel-ipu6-dkms_%version%_amd64.deb arch=amd64 rprovides=ipu6-modules rprovides=intel-ipu6-dkms type=standalone
+backport-iwlwifi-dkms 11510-0ubuntu1.1 modulename=iwlwifi debpath=pool/universe/b/%package%/backport-iwlwifi-dkms_%version%_all.deb arch=amd64 rprovides=iwlwifi-modules rprovides=backport-iwlwifi-dkms type=standalone
+v4l2loopback 0.12.7-2ubuntu5 modulename=v4l2loopback debpath=pool/universe/v/%package%/v4l2loopback-dkms_%version%_all.deb arch=amd64 rprovides=v4l2loopback-modules rprovides=v4l2loopback-dkms
+usbio-drivers 0~git202312141918.78ffb706-0ubuntu2.1 modulename=usbio debpath=pool/universe/u/%package%/intel-usbio-dkms_%version%_amd64.deb arch=amd64 rprovides=usbio-modules rprovides=intel-usbio-dkms type=standalone
--- linux-qcom-6.8.0.orig/debian.master/modprobe.d/common.conf
+++ linux-qcom-6.8.0/debian.master/modprobe.d/common.conf
@@ -0,0 +1,3 @@
+# LP:1434842 -- disable OSS drivers by default to allow pulseaudio to emulate
+blacklist snd-mixer-oss
+blacklist snd-pcm-oss
--- linux-qcom-6.8.0.orig/debian.master/reconstruct
+++ linux-qcom-6.8.0/debian.master/reconstruct
@@ -0,0 +1,57 @@
+# Recreate any symlinks created since the orig.
+chmod +x 'arch/mips/pci/pcie-octeon.c'
+chmod +x 'debian/cloud-tools/hv_get_dhcp_info'
+chmod +x 'debian/cloud-tools/hv_get_dns_info'
+chmod +x 'debian/cloud-tools/hv_set_ifconfig'
+chmod +x 'debian/rules'
+chmod +x 'debian/scripts/checks/final-checks'
+chmod +x 'debian/scripts/checks/module-signature-check'
+chmod +x 'debian/scripts/control-create'
+chmod +x 'debian/scripts/dkms-build'
+chmod +x 'debian/scripts/dkms-build--nvidia-N'
+chmod +x 'debian/scripts/dkms-build-configure--zfs'
+chmod +x 'debian/scripts/file-downloader'
+chmod +x 'debian/scripts/link-headers'
+chmod +x 'debian/scripts/link-lib-rust'
+chmod +x 'debian/scripts/misc/annotations'
+chmod +x 'debian/scripts/misc/find-missing-sauce.sh'
+chmod +x 'debian/scripts/misc/gen-auto-reconstruct'
+chmod +x 'debian/scripts/misc/git-ubuntu-log'
+chmod +x 'debian/scripts/misc/insert-changes'
+chmod +x 'debian/scripts/misc/insert-ubuntu-changes'
+chmod +x 'debian/scripts/misc/kernelconfig'
+chmod +x 'debian/scripts/module-inclusion'
+chmod +x 'debian/scripts/sign-module'
+chmod +x 'debian/templates/extra.postinst.in'
+chmod +x 'debian/templates/extra.postrm.in'
+chmod +x 'debian/templates/headers.postinst.in'
+chmod +x 'debian/templates/image.postinst.in'
+chmod +x 'debian/templates/image.postrm.in'
+chmod +x 'debian/templates/image.preinst.in'
+chmod +x 'debian/templates/image.prerm.in'
+chmod +x 'debian/tests-build/check-aliases'
+chmod +x 'debian/tests/rebuild'
+chmod +x 'debian/tests/ubuntu-regression-suite'
+chmod +x 'drivers/watchdog/f71808e_wdt.c'
+chmod +x 'tools/testing/selftests/gpio/gpio-aggregator.sh'
+chmod +x 'tools/testing/selftests/net/ipv6_route_update_soft_lockup.sh'
+# Remove any files deleted from the orig.
+rm -f 'arch/arm/kernel/pj4-cp0.c'
+rm -f 'arch/arm64/boot/dts/qcom/pm2250.dtsi'
+rm -f 'arch/arm64/boot/dts/qcom/sdm845-db845c-navigation-mezzanine.dts'
+rm -f 'arch/loongarch/include/asm/dma-direct.h'
+rm -f 'arch/loongarch/include/asm/qspinlock.h'
+rm -f 'arch/s390/kernel/earlypgm.S'
+rm -f 'arch/sparc/lib/cmpdi2.c'
+rm -f 'arch/sparc/lib/ucmpdi2.c'
+rm -f 'drivers/dax/pmem/Makefile'
+rm -f 'drivers/dax/pmem/pmem.c'
+rm -f 'drivers/gpu/drm/gma500/psb_lid.c'
+rm -f 'drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c'
+rm -f 'include/linux/amd-pstate.h'
+rm -f 'include/linux/iio/adc/adi-axi-adc.h'
+rm -f 'net/bluetooth/a2mp.c'
+rm -f 'net/bluetooth/a2mp.h'
+rm -f 'net/bluetooth/amp.c'
+rm -f 'net/bluetooth/amp.h'
+exit 0
--- linux-qcom-6.8.0.orig/debian.master/rules.d/amd64.mk
+++ linux-qcom-6.8.0/debian.master/rules.d/amd64.mk
@@ -0,0 +1,22 @@
+human_arch	= 64 bit x86
+build_arch	= x86
+defconfig	= defconfig
+flavours	= generic
+build_image	= bzImage
+kernel_file	= arch/$(build_arch)/boot/bzImage
+install_file	= vmlinuz
+vdso		= vdso_install
+no_dumpfile	= true
+uefi_signed     = true
+do_tools_usbip  = true
+do_tools_cpupower = true
+do_tools_perf   = true
+do_tools_perf_jvmti = true
+do_tools_perf_python = true
+do_tools_bpftool = true
+do_tools_x86	= true
+do_tools_hyperv	= true
+do_tools_rtla = true
+do_extras_package = true
+do_tools_acpidbg = true
+do_lib_rust     = true
--- linux-qcom-6.8.0.orig/debian.master/rules.d/arm64.mk
+++ linux-qcom-6.8.0/debian.master/rules.d/arm64.mk
@@ -0,0 +1,22 @@
+human_arch	= ARMv8
+build_arch	= arm64
+defconfig	= defconfig
+flavours	= generic generic-64k
+build_image	= Image.gz
+kernel_file	= arch/$(build_arch)/boot/Image.gz
+install_file	= vmlinuz
+no_dumpfile = true
+uefi_signed     = true
+
+vdso		= vdso_install
+
+do_extras_package = true
+do_tools_usbip  = true
+do_tools_cpupower = true
+do_tools_perf   = true
+do_tools_perf_jvmti = true
+do_tools_perf_python = true
+do_tools_bpftool = true
+do_tools_rtla = true
+
+do_dtbs		= true
--- linux-qcom-6.8.0.orig/debian.master/rules.d/armhf.mk
+++ linux-qcom-6.8.0/debian.master/rules.d/armhf.mk
@@ -0,0 +1,19 @@
+human_arch	= ARM (hard float)
+build_arch	= arm
+defconfig	= defconfig
+flavours	= generic
+build_image	= zImage
+kernel_file	= arch/$(build_arch)/boot/zImage
+install_file	= vmlinuz
+no_dumpfile	= true
+
+do_tools_usbip  = true
+do_tools_cpupower = true
+do_tools_perf	= true
+do_tools_perf_jvmti = true
+do_tools_perf_python = true
+do_tools_bpftool = true
+do_tools_bpftool_stub = true
+do_tools_rtla = true
+
+do_dtbs		= true
--- linux-qcom-6.8.0.orig/debian.master/rules.d/i386.mk
+++ linux-qcom-6.8.0/debian.master/rules.d/i386.mk
@@ -0,0 +1,15 @@
+human_arch	= 32 bit x86
+build_arch	= i386
+defconfig	= defconfig
+flavours        = generic
+build_image	= bzImage
+kernel_file	= arch/$(build_arch)/boot/bzImage
+install_file	= vmlinuz
+vdso		= vdso_install
+no_dumpfile	= true
+do_flavour_image_package = false
+do_tools	= false
+do_extras_package = false
+do_source_package = false
+do_flavour_header_package = false
+do_common_headers_indep = false
--- linux-qcom-6.8.0.orig/debian.master/rules.d/ppc64el.mk
+++ linux-qcom-6.8.0/debian.master/rules.d/ppc64el.mk
@@ -0,0 +1,19 @@
+human_arch	= PowerPC 64el
+build_arch	= powerpc
+defconfig	= pseries_le_defconfig
+flavours	= generic
+build_image	= vmlinux.strip
+kernel_file     = arch/powerpc/boot/vmlinux.strip
+install_file	= vmlinux
+no_dumpfile	= true
+do_extras_package = true
+opal_signed       = false
+do_tools_usbip    = true
+do_tools_cpupower = true
+do_tools_perf	  = true
+do_tools_perf_jvmti = true
+do_tools_perf_python = true
+do_tools_bpftool  = true
+do_tools_rtla = true
+
+#do_flavour_image_package = false
--- linux-qcom-6.8.0.orig/debian.master/rules.d/riscv64.mk
+++ linux-qcom-6.8.0/debian.master/rules.d/riscv64.mk
@@ -0,0 +1,25 @@
+human_arch     = RISC-V
+build_arch     = riscv
+defconfig      = defconfig
+flavours       = generic
+build_image    = Image
+kernel_file    = arch/$(build_arch)/boot/Image
+install_file   = vmlinuz
+
+vdso           = vdso_install
+no_dumpfile    = true
+
+do_flavour_image_package = false
+do_tools                 = false
+do_tools_common          = false
+do_source_package        = false
+do_flavour_header_package = false
+do_common_headers_indep = false
+do_extras_package      = false
+do_tools_usbip         = false
+do_tools_cpupower      = false
+do_tools_perf          = false
+do_tools_perf_jvmti    = false
+do_tools_perf_python = false
+do_tools_bpftool       = false
+do_dtbs                = false
--- linux-qcom-6.8.0.orig/debian.master/rules.d/s390x.mk
+++ linux-qcom-6.8.0/debian.master/rules.d/s390x.mk
@@ -0,0 +1,20 @@
+human_arch      = System 390x
+build_arch      = s390
+defconfig       = defconfig
+flavours        = generic
+build_image	= bzImage
+kernel_file	= arch/$(build_arch)/boot/bzImage
+install_file	= vmlinuz
+
+vdso		= vdso_install
+no_dumpfile	= true
+
+do_extras_package = true
+sipl_signed       = true
+do_tools_usbip    = true
+do_tools_cpupower = true
+do_tools_perf     = true
+do_tools_perf_jvmti = true
+do_tools_perf_python = true
+do_tools_bpftool  = true
+do_tools_rtla = false
--- linux-qcom-6.8.0.orig/debian.master/rules.d/x32.mk
+++ linux-qcom-6.8.0/debian.master/rules.d/x32.mk
@@ -0,0 +1,12 @@
+human_arch	= 64 bit x86 (32 bit userspace)
+build_arch	= x86
+defconfig	= defconfig
+flavours	= 
+build_image	= bzImage
+kernel_file	= arch/$(build_arch)/boot/bzImage
+install_file	= vmlinuz
+vdso		= vdso_install
+no_dumpfile	= true
+uefi_signed     = true
+
+do_flavour_image_package = false
--- linux-qcom-6.8.0.orig/debian.master/tracking-bug
+++ linux-qcom-6.8.0/debian.master/tracking-bug
@@ -0,0 +1 @@
+2114668 2025.06.16-2
--- linux-qcom-6.8.0.orig/debian.master/upstream-stable
+++ linux-qcom-6.8.0/debian.master/upstream-stable
@@ -0,0 +1,8 @@
+# The following upstream stable releases have been ported:
+[upstream-stable]
+    linux-6.6.y = v6.6.77
+    linux-6.8.y = v6.8.12
+    linux-6.9.y = v6.9.12
+    linux-6.10.y = v6.10.14
+    linux-6.11.y = v6.11.11
+    linux-6.12.y = v6.12.14
--- linux-qcom-6.8.0.orig/debian.master/variants
+++ linux-qcom-6.8.0/debian.master/variants
@@ -0,0 +1,2 @@
+-6.8
+--
--- linux-qcom-6.8.0.orig/debian.qcom/changelog
+++ linux-qcom-6.8.0/debian.qcom/changelog
@@ -0,0 +1,38887 @@
+linux-qcom (6.8.0-1054.54oem2) noble; urgency=medium
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] remove reconstruct"
+
+ -- Hui Wang <hui.wang@canonical.com>  Mon, 08 Sep 2025 19:05:04 +0800
+
+linux-qcom (6.8.0-1054.54oem1) noble; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+
+ -- Hui Wang <hui.wang@canonical.com>  Mon, 08 Sep 2025 17:07:45 +0800
+
+linux-qcom (6.8.0-1051.51oem3) noble; urgency=medium
+
+  * Unable to hear the audio playback clip from the RB8 hardware speakers with
+    Server & Desktop images
+    - ASoC: qcs9075-iq-evk: Enable audio on qcs9075-iq-evk
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update to Yocto GA 1.5
+    - SAUCE: firmware: qcom: si-core:  include <workqueue_types.h>
+    - SAUCE: sound/soc/qcom/qcm6490: suppress invalid dai id error
+    - SAUCE: partially revert "enable platform sound-dai"
+    - [Packaging] remove reconstruct
+
+  * Miscellaneous upstream changes
+    - PENDING: arm64: dts: qcom: Update the thermal sensor names
+    - PENDING: drivers: pinctrl: Add support for context save/restore
+    - PENDING: pinctrl: qcom: sa8775p: Add PM suspend callbacks
+    - PENDING: arm64: dts: qcom: qcs8300: Update carveouts
+    - QCLINUX: arm64: defconfigs: Enable SA8797P Pinctrl
+    - PENDING: pinctrl: qcom: Add TLMM Driver for SA8797p platform
+    - QCLINUX: iommu: Remove atomic allocation check to fix smmu mapping
+      failure
+    - QCLINUX: arm64: defconfig: Align Gen5auto configs with Gen4auto
+    - PENDING: arm64: dts: qcom: qcs9075-rb8: Set the BT bootstrap bin when
+      init Uart
+    - PENDING: arm64: dts: qcom: sa8775p: add GPDSP fastrpc-compute-cb nodes
+    - PENDING: misc: fastrpc: Add support for gpdsp remoteproc
+    - QCLINUX: arm64: defconfig: Enable Tracer Configs
+    - FROMLIST: soc: qcom: Add qcom_rproc_minidump module
+    - FROMLIST: remoteproc: qcom_q6v5_pas: Use qcom_rproc_minidump()
+    - FROMLIST: remoteproc: qcom: Remove minidump related data from
+      qcom_common.c
+    - FROMLIST: pstore/ram: Add ramoops information notifier support
+    - FROMLIST: soc: qcom: Add Qualcomm APSS minidump kernel driver
+    - QCLINUX: defconfig: Enable ebtables and netfilter configuration
+    - PENDING: drm/msm/dp: correct the configuration ctrl reg for streams
+    - UPSTREAM: arm64: dts: qcom: Fix max speed for usb_1 on qcs8300
+    - QCLINUX: arm64: configs: qcom_debug: Fix up order of CONFIGs
+    - PENDING: net: stmmac: Enable MMC counters for 25gmac
+    - PENDING: ASoC: qcom: q6prm: Add lpass mclk id support
+    - QCLINUX: firmware: qcom_scm_addon: Enable SCM for Memory Dump
+    - FROMLIST: wifi: ath11k: add function to get next srng desc
+    - PENDING: arm64: dts: qcom: sa8255p: Enable USB role switch
+    - QCLINUX: arm64: configs: qcom_debug: Enable PSTORE
+    - QCLINUX: arm64: configs: qcom_debug: Enable QCOM_MINIDUMP
+    - FROMLIST: wifi: ath11k: fix HTC rx insufficient length
+    - UPSTREAM: BACKPORT: arm64: dts: qcom: qcs6490-rb3gen2: Enable USB Type-C
+      display
+    - FROMLIST: wifi: ath11k: fix node corruption in ar->arvifs list
+    - PENDING: arm64: dts: qcom: Enable tsens and thermal for QCS615 SoC
+    - Revert "PENDING: net: stmmac: Create new mdio for every emac instance"
+    - QCLINUX: firmware: qcom_scm_addon: Update SCM call for Memory Dump
+    - PENDING: net: stmmac: Fix USXGMII link up sequence
+    - QCLINUX: arm64: configs: qcom_debug: Enable QCOM_MINIDUMP
+    - QCLINUX: ASoC: qcs9075: Add Stub AIF0 & AIF1
+    - QCLINUX: arm64: dts: qcom: Add mem-object node for si_core
+    - PENDING: firmware: qcom: Add si_core and si_core_xts
+    - QCLINUX: Disable QCOM_SMCINVOKE
+    - QCLINUX: Enable QCOM_SI_CORE and QCOM_SI_CORE_XTS
+    - PENDING: drivers: mailbox: ipcc: Add Deep Sleep support for qcom-ipcc
+      driver
+    - QCLINUX: arm64: dts: qcom: Fix issue of USB hub & DP not working
+      properly
+    - PENDING: net: PCS: Rework and expose qcom_xpcs_destroy function
+    - PENDING: net: stmmac: Use pcs_init and pcs_exit functions
+    - PENDING: iommu/arm-smmu: add ACTLR data and support for sa8797p
+    - PENDING: drm/msm/dpu: Correct the index of intf_6 vsync irq
+    - FROMLIST: PCI: Add support for PCIe wake interrupt
+    - PENDING: arm64: dts: qcom: sa8255p: Disable USB U1/U2 entry
+    - PENDING: net: phy: aquantia: Add polling for global status register
+      before checking for provision and firmware ID's
+    - PENDING: drm/msm/dp: Add the stream 2 and stream 3 clk for 4 MST
+    - PENDING: drm/msm/dp: add support for programming p2/p3 register block
+    - QCLINUX: arm64: dts: qcom: Add PCIe wake for HSP
+    - PENDING: drm/msm/dp: add support for programming mst2/mst3 register
+      block
+    - PENDING: drm/msm/dp: add catalog support for 4 streams MST
+    - PENDING: drm/msm/dp: add interface map needed to enable 4 streams
+    - PENDING: arm64/dts/qcom: add mst support for MST2/MST3 clk and registers
+    - PENDING: net: stmmac: Reset few of the IO macro registers to POR values
+      before programming
+    - PENDING: net: stmmac: Enable L2 split header support on XGMAC
+    - PENDING: net: pcs: Enable PCS Fusa Shared interrupt
+    - PENDING: net: stmmac: Enable safety interrupt only after PCS link up
+    - QCLINUX: ASoC: qcs8275: Add support for QCS8275 RB4
+    - QCLINUX: iommu/arm-smmu: Invoke pm runtime for context fault
+    - FROMGIT: serial: qcom-geni: Remove alias dependency from qcom serial
+      driver
+    - QCLINUX: Revert "serial: qcom-geni: fix receiver enable"
+    - QCLINUX: Revert "Revert "FROMLIST: arm64: dts: qcom: sa8775p: Add CPUs
+      to psci power domain""
+    - QCLINUX: arm64: qcom_defconfig: Enable EXT4_FS_SECURITY
+    - PENDING: scsi: ufs-qcom: Fix MCQ version handling to update CFG register
+    - PENDING: soc: qcom: qcom_stats: Add SMEM items for multiple subsystems
+    - PENDING: arm64: dts: qcom: sa7255p: Add PCIe EP nodes
+    - PENDING: arm64: dts: qcom: Revert uart0 support for qcs9075-iq-9075-evk
+    - PENDING: arm64: dts: qcom: qcs8300: Add gpu_speed_bin to qfprom node
+    - QCLINUX: tz_log: Revert "QCLINUX: qcom: tz_log: differentiate hlos and
+      hypversior of creating shmbridge"
+    - QCLINUX: tz_log: Revert "QCLINUX: qcom: tz_log: enable tz_log support
+      hypervisor"
+    - QCLINUX: smcinvoke: Revert "QCLINUX: smcinvoke: Add support hypervisor
+      of shmbridge"
+    - PENDING: coresight: fix NULL pointer issue when get CSR's name
+    - PENDING: arm64: dts: qcom: Add support for QCS8275 IQ8 EVK board
+    - QCLINUX:arm64: dts: qcom: Add eMMC support for qcs8300
+    - QCLINUX: dcc: Add Deep Sleep support for qcom-dcc driver
+    - QCLINUX: firmware: qcom_scm_addon: Add SCM call to init multi GPU
+      instance
+    - QCLINUX: firmware: qcom_scm_addon: Add interface to load CCU
+    - PENDING: Adapt to kennel v6.6.78, modify the corresponding driver
+      function interface
+    - FROMLIST: firmware: qcom_scm: Check for waitq state in
+      wait_for_completion
+    - PENDING: net: PCS: supply Tx to Rx loopback clock for HW configuration
+    - QCLINUX: arm64: dts: qcom: Add msm-id & board-id for qcs8275 IQ8
+    - PENDING: arm64: dts: qcom: Enable primary USB controller on QCS8275 RB4
+    - FROMLIST: arm64: dts: qcom: sa8775p: add support for video node
+    - FROMLIST: arm64: dts: qcom: sa8775p-ride: enable video
+    - FROMLIST: arm64: dts: qcom: qcs8300: add support for video node
+    - FROMLIST: arm64: dts: qcom: qcs8300-ride: enable video
+    - PENDING: drivers: pinctrl: Add suspend to RAM support
+    - Revert "QCLINUX: remoteproc: Panic on remoteproc crash"
+    - PENDING: drivers: char: add remote debugger driver support for GDSP
+    - PENDING: net: stmmac: Use generic PCS field and move pcs_pre_init before
+      Serdes powerup
+    - PENDING: arm64: dts: qcom: sa7255p: Enable uart12 in sa7255p
+    - PENDING: pinctrl: qcom: sa8797p: Add PM suspend callbacks
+    - QCLINUX: firmware: qcom: si-core: Switch to tzmem interfaces
+    - PENDING: arm64: dts: qcom: Add support for the IQ-9075-evk mezz
+    - PENDING: arm64: dts: qcom: tpm enablement for qcs9075-iq-9075-evk
+    - PENDING: i2c: qcom-geni: Defer i2c geni driver probe if firmware file
+      not found
+    - PENDING: arm64: dts: qcom: Enable USB2 controller on QCS8275 IQ8 EVK
+    - PENDING: arm64: dts: qcom: Add UFS support for QCS8275 IQ8 EVK
+    - PENDING: arm64: dts: qcom: Flatten USB DT node for USB2 on QCS9075 RB8
+      Platform
+    - QCLINUX: arm64: dts: qcom: Add audio mdf reserved memory for sa7255
+    - QCLINUX: firmware: Remove qtee_shmbridge driver
+    - QCLINUX: arm64: defconfig: qcom: Enable AMC6821 Sensor driver
+    - PENDING: arm64: qcs9075-evk: remove uart bt en and bootstrap pin in DTS
+    - PENDING: arm64: dts: qcom: Enable PCIe0 & PCIe1 for QCS8275 IQ8 EVK
+    - PENDING: arm64: dts: qcom: add gpio expander support for IQ8-8275-EVK
+    - PENDING: arm64: dts: qcom: Add support for remoteproc instances
+    - PENDING: arm64: dts: qcom: sa8775p: add rdbg nodes
+    - QCLINUX: arm64: dts: qcom: qcs8275: addons dt support for IQ8 QCS8275
+    - PENDING: arm64: dts: qcom: Flatten USB DT node
+    - PENDING: arm64: dts: qcom: qcs8300: Define interconnect bandwidth value
+    - PENDING: dt-bindings: arm: qcom: add the SoC ID for SA8650P
+    - PENDING: arm64: dts: qcom: add support for IQ8-8275-evk mezz board
+    - PENDING: arm64: dts: qcom: Enable BT on QCS8275 IQ8 EVK
+    - PENDING: arm64: dts: qcom: Enable ethernet on QCS8275 IQ8 EVK
+    - PENDING: arm64: dts: qcom: qcs8275: Enable gpi-dma node
+    - FROMGIT: arm64: dts: qcom: sa8775p: Add default pin configurations for
+      QUP SEs
+    - PENDING: arm64: dts: qcom: Add fan controller support for
+      qcs9075-iq-9075-evk
+    - QCLINUX: dcc: Add suspend to RAM support for qcom-dcc driver
+    - PENDING: drivers: mailbox: ipcc: Add suspend to RAM  support for qcom-
+      ipcc driver
+    - PENDING: net: stmmac: disable PCS interrupt if PCS
+    - PENDING: arm64: dts: qcom: Add DRD mode support
+    - QCLINUX: soc: qcom: Adapt smci header with latest copyright guidelines
+    - PENDING: arm64: dts: qcom: Flatten USB DT node
+    - QCLINUX: arm64: dts: qcom: Enable the second ethernet on QCS9075-IQ9
+      Mezz
+    - QCLINUX:arm64: dts: qcom: Add sdcard support for qcs9075 rb8
+    - PENDING: drm/bridge: lt9611uxc: extend mode valid checks
+    - PENDING: arm64: dts: qcom: Enable QPS615 on IQ8 EVK Mezz
+    - PENDING: driver: bluetooth: hci_qca: Disable hci_auto_off when BT_EN is
+      consistently pulled up by hardware
+    - PENDING: driver: bluetooth: hci_qca: fix ssr fail when BT_EN is
+      consistently pulled up by hardware
+    - PENDING: arm64: dts: qcom: Enable QPS615 on IQ-9075-evk mezz
+    - QCLINUX: arm64: dts: qcom: Add support for Eth0 and Eth1 on QPS615 for
+    - BACKPORT: PCI: of: Add of_pci_get_equalization_presets() API
+    - BACKPORT: PCI: dwc: Update pci->num_lanes to maximum supported link
+      width
+    - BACKPORT: PCI: Add lane equalization register offsets
+    - BACKPORT: PCI: dwc: Add support for configuring lane equalization
+      presets
+    - PENDING: PCI: qcom: Add equalization settings for 8.0 GT/s
+    - PENDING: arm64: dts: qcom: sa8775p: Add PCIe lane equalization preset
+      properties
+    - PENDING: arm64: dts: qcom: Make status disabled for remote endpoints on
+      mezz
+    - FROMLIST: PCI: dwc: Set PORT_LOGIC_LINK_WIDTH to one lane
+    - FROMLIST: phy: qcom: qmp-pcie: Update PHY settings for SA8775P
+    - PENDING: arm64: dts: qcom: Add support for QCS8275 IQ8 Pro SKU EVK board
+    - QCLINUX: arm64: dts: qcom: Add msm-id & board-id for QCS8275 IQ8 Pro SKU
+    - QCLINUX: arm64: dts: qcom: addons dt support for IQ8 QCS8275 Pro SKU
+    - PENDING: arm64: dts: qcom: add io expander support for IQ8-8275 Pro SKU
+    - PENDING: arm64: dts: qcom: Enable primary USB
+    - PENDING: arm64: dts: qcom: Add DRD mode support
+    - PENDING: arm64: dts: qcom: Enable USB2 controller
+    - QCLINUX: usb: dwc3: qcom: Fix calling of regulator get
+    - PENDING: arm64: dts: msm: Add UFS support for QCS8275 IQ8 Pro SKU EVK
+    - PENDING: arm64: dts: qcom: Update phy reset GPIO for Eth0 and Eth1 on
+    - PENDING: arm64: dts: qcom: Add wakeup source
+    - PENDING: arm64: dts: qcom: Add wakeup source
+    - PENDING: arm64: dts: qcom: Add usb conn gpio
+    - PENDING: arm64: dts: qcom: Add SD card support for QCS8275 IQ EVK
+    - PENDING: arm64: dts: qcom: Add SD card support for QCS8275 IQ8 Pro SKU
+    - PENDING: arm64: dts: qcom: Enable PCIe for QCS8275 IQ8 Pro SKU EVK
+    - PENDING: arm64: dts: qcom: Add wakeup source
+    - PENDING: arm64: dts: qcom: Enable vqmmc voltage switching for qcs9075
+      rb8
+    - PENDING: usb: typec: Add wakeup support from
+    - QCLINUX: arm64: dts: qcom: Fix eud ep in sa8775p-ride
+    - PENDING: misc: eud: Add High-Speed Phy control for EUD operations
+    - PENDING: misc: eud: Handle usb role switch notifications
+    - PENDING: misc: eud: Add an API to identify the role switch context
+    - PENDING: usb: dwc3: qcom: Handle Vbus OFF notification from EUD
+    - PENDING: arm64: dts: qcom: Add HS Phy node to EUD for SC7280
+    - PENDING: arm64: dts: qcom: Rearrange the role switch eps for QCM6490
+    - PENDING: arm64: dts: qcom: Rearrange the role switch for QCS6490 RB3Gen2
+    - PENDING: arm64: dts: qcom: Add status prop for ICE nodes
+    - PENDING: arm64: dts: qcom: Enable ICE node for eMMC
+    - PENDING: arm64: dts: qcom: tpm enablement for qcs8275-iq-8275-evk
+    - QCLINUX: arm64: dts: qcom: Disable eMMC ICE
+    - PENDING: arm64: dts: qcom: Add EEPROM support for IQ-9075-evk
+    - QCLINUX: net: stmmac: Add EEPROM support to driver
+    - kernel: arm64: dts: qcom: enable EEPROM Client Driver
+    - kernel: config: qcom: enable AT24 EEPROM driver
+    - arm64: dts: rubikpi: add RUBIK Pi related basic device tree
+    - arm64: dts: rubikpi: compatible with USB-A 2.0 port
+    - arm64: dts: rubikpi: enable USB3.0 HUB
+    - arm64: dts: rubikpi: enable M.2 port
+    - net: ax88179b: add driver
+    - arm64: dts: rubikpi: enable fan
+    - arm64: defconfig: enable ax88179b config
+    - wifi: ap6256: add driver
+    - arm64: dts: rubikpi: enable Wi-Fi
+    - arm64: dts: rubikpi3: enable bluetooth
+    - serial: qcom-geni: increase uart ports to 13
+    - arm64: dts: rubikpi: enable rtc to support time writing
+    - arm64: dts: rubikpi: camera: bringup imx219 and imx477
+    - drm/bridge: lt9611: rubikpi: enable hdmi out
+    - arm64: dts: rubikpi3: enable hdmi out interface
+    - ASoC: es8316: rubikpi: enable 3.5mm headphone jack
+    - arm64: dts: rubikpi3: enable 3.5mm headphone jack
+    - spi: spidev: add an entry for thundercomm,rubikpi
+    - arm64: dts: rubikpi: enable bus interface on 40 pin
+    - ASoC: qcom: qcm6490: rubikpi: enable HDMI OUT audio
+    - arm64: dts: rubikpi3: enable HDMI OUT audio
+    - arm64: dts: rubikpi3: Enable Bluetooth kernel driver
+    - drm/bridge: lt9611: rubikpi: fix the problem of hot plug failure
+    - arm64: dts: rubikpi3: modify the interrupt trigger mode of HDMI out
+    - arm64: dts: rubikpi: camera: Remove unnecessary gpio controls
+    - Ubuntu: [Config] update CONFIG options for Rubik Pi 3
+
+  [ Ubuntu: 6.8.0-64.67 ]
+
+  * noble/linux: 6.8.0-64.67 -proposed tracker (LP: #2114668)
+  * Unexpected system reboot at loading GUI session on some AMD platforms
+    (LP: #2112462)
+    - drm/amdgpu/hdp4: use memcfg register to post the write for HDP flush
+    - drm/amdgpu/hdp5: use memcfg register to post the write for HDP flush
+    - drm/amdgpu/hdp5.2: use memcfg register to post the write for HDP flush
+    - drm/amdgpu/hdp6: use memcfg register to post the write for HDP flush
+  * [UBUNTU 24.04] s390/pci: Fix immediate re-add of PCI function after remove
+    (LP: #2114174)
+    - s390/pci: rename lock member in struct zpci_dev
+    - s390/pci: introduce lock to synchronize state of zpci_dev's
+    - s390/pci: remove hotplug slot when releasing the device
+    - s390/pci: Remove redundant bus removal and disable from
+      zpci_release_device()
+    - s390/pci: Prevent self deletion in disable_slot()
+    - s390/pci: Allow re-add of a reserved but not yet removed device
+    - s390/pci: Serialize device addition and removal
+  * [UBUNTU 24.04] s390/pci: Fix immediate re-add of PCI function after remove
+    (LP: #2114174) // CVE-2025-37946
+    - s390/pci: Fix duplicate pci_dev_put() in disable_slot() when PF has
+      child VFs
+  * [UBUNTU 24.04] s390/pci: Fix immediate re-add of PCI function after remove
+    (LP: #2114174) // CVE-2025-37974
+    - s390/pci: Fix missing check for zpci_create_device() error return
+  * [UBUNTU 24.04] s390/pci: Fix immediate re-add of PCI function after remove
+    (LP: #2114174) // CVE-2024-56699
+    - s390/pci: Fix potential double remove of hotplug slot
+  * System will restart while resuming with SATA HDD or nvme installed with
+    password set (LP: #2110090)
+    - PCI: Explicitly put devices into D0 when initializing
+  * Noble update: upstream stable patchset 2025-06-12 (LP: #2114239)
+    - btrfs: fix assertion failure when splitting ordered extent after
+      transaction abort
+    - btrfs: fix use-after-free when attempting to join an aborted transaction
+    - arm64/mm: Ensure adequate HUGE_MAX_HSTATE
+    - exec: fix up /proc/pid/comm in the execveat(AT_EMPTY_PATH) case
+    - s390/stackleak: Use exrl instead of ex in __stackleak_poison()
+    - btrfs: fix data race when accessing the inode's disk_i_size at
+      btrfs_drop_extents()
+    - btrfs: convert BUG_ON in btrfs_reloc_cow_block() to proper error
+      handling
+    - sched: Don't try to catch up excess steal time.
+    - locking/ww_mutex/test: Use swap() macro
+    - lockdep: Fix upper limit for LOCKDEP_*_BITS configs
+    - x86/amd_nb: Restrict init function to AMD-based systems
+    - drm/virtio: New fence for every plane update
+    - drm: Add panel backlight quirks
+    - drm: panel-backlight-quirks: Add Framework 13 matte panel
+    - drm: panel-backlight-quirks: Add Framework 13 glossy and 2.8k panels
+    - nvkm/gsp: correctly advance the read pointer of GSP message queue
+    - nvkm: correctly calculate the available space of the GSP cmdq buffer
+    - drm/amd/display: Populate chroma prefetch parameters, DET buffer fix
+    - drm/amd/display: Overwriting dualDPP UBF values before usage
+    - printk: Fix signed integer overflow when defining LOG_BUF_LEN_MAX
+    - drm/connector: add mutex to protect ELD from concurrent access
+    - drm/bridge: anx7625: use eld_mutex to protect access to connector->eld
+    - drm/bridge: ite-it66121: use eld_mutex to protect access to
+      connector->eld
+    - drm/amd/display: use eld_mutex to protect access to connector->eld
+    - drm/exynos: hdmi: use eld_mutex to protect access to connector->eld
+    - drm/radeon: use eld_mutex to protect access to connector->eld
+    - drm/sti: hdmi: use eld_mutex to protect access to connector->eld
+    - drm/vc4: hdmi: use eld_mutex to protect access to connector->eld
+    - drm/amd/display: Fix Mode Cutoff in DSC Passthrough to DP2.1 Monitor
+    - drm/amdgpu: Don't enable sdma 4.4.5 CTXEMPTY interrupt
+    - drm/amdkfd: Queue interrupt work to different CPU
+    - drm/bridge: it6505: Change definition MAX_HDCP_DOWN_STREAM_COUNT
+    - drm/bridge: it6505: fix HDCP Bstatus check
+    - drm/bridge: it6505: fix HDCP encryption when R0 ready
+    - drm/bridge: it6505: fix HDCP CTS compare V matching
+    - drm/bridge: it6505: fix HDCP V match check is not performed correctly
+    - drm/bridge: it6505: fix HDCP CTS KSV list wait timer
+    - safesetid: check size of policy writes
+    - drm/amd/display: Increase sanitizer frame larger than limit when compile
+      testing with clang
+    - drm/amd/display: Limit Scaling Ratio on DCN3.01
+    - wifi: rtw89: add crystal_cap check to avoid setting as overflow value
+    - tun: fix group permission check
+    - mmc: core: Respect quirk_max_rate for non-UHS SDIO card
+    - mmc: sdhci-esdhc-imx: enable 'SDHCI_QUIRK_NO_LED' quirk for S32G
+    - wifi: brcmsmac: add gain range check to wlc_phy_iqcal_gainparams_nphy()
+    - tomoyo: don't emit warning in tomoyo_write_control()
+    - mfd: lpc_ich: Add another Gemini Lake ISA bridge PCI device-id
+    - wifi: rtw88: add __packed attribute to efuse layout struct
+    - clk: qcom: Make GCC_8150 depend on QCOM_GDSC
+    - HID: multitouch: Add quirk for Hantick 5288 touchpad
+    - HID: Wacom: Add PCI Wacom device support
+    - net/mlx5: use do_aux_work for PHC overflow checks
+    - wifi: brcmfmac: Check the return value of
+      of_property_read_string_index()
+    - wifi: iwlwifi: pcie: Add support for new device ids
+    - wifi: iwlwifi: avoid memory leak
+    - i2c: Force ELAN06FA touchpad I2C bus freq to 100KHz
+    - APEI: GHES: Have GHES honor the panic= setting
+    - Bluetooth: btusb: Add new VID/PID 13d3/3610 for MT7922
+    - Bluetooth: btusb: Add new VID/PID 13d3/3628 for MT7925
+    - Bluetooth: MGMT: Fix slab-use-after-free Read in
+      mgmt_remove_adv_monitor_sync
+    - net: wwan: iosm: Fix hibernation by re-binding the driver around it
+    - mmc: sdhci-msm: Correctly set the load for the regulator
+    - octeon_ep: update tx/rx stats locally for persistence
+    - tipc: re-order conditions in tipc_crypto_key_rcv()
+    - selftests/net/ipsec: Fix Null pointer dereference in rtattr_pack()
+    - x86/kexec: Allocate PGD for x86_64 transition page tables separately
+    - iommu/arm-smmu-qcom: add sdm670 adreno iommu compatible
+    - iommu/arm-smmu-v3: Clean up more on probe failure
+    - platform/x86: int3472: Check for adev == NULL
+    - platform/x86: acer-wmi: Add support for Acer PH14-51
+    - ASoC: soc-pcm: don't use soc_pcm_ret() on .prepare callback
+    - platform/x86: acer-wmi: Add support for Acer Predator PH16-72
+    - ASoC: amd: Add ACPI dependency to fix build error
+    - Input: allocate keycode for phone linking
+    - platform/x86: acer-wmi: add support for Acer Nitro AN515-58
+    - platform/x86: acer-wmi: Ignore AC events
+    - xfs: report realtime block quota limits on realtime directories
+    - xfs: don't over-report free space or inodes in statvfs
+    - tty: xilinx_uartps: split sysrq handling
+    - tty: vt: pass proper pointers from tioclinux()
+    - tty: Permit some TIOCL_SETSEL modes without CAP_SYS_ADMIN
+    - tty: Require CAP_SYS_ADMIN for all usages of TIOCL_SELMOUSEREPORT
+    - platform/x86: serdev_helpers: Check for serial_ctrl_uid == NULL
+    - nvme: handle connectivity loss in nvme_set_queue_count
+    - firmware: iscsi_ibft: fix ISCSI_IBFT Kconfig entry
+    - gpu: drm_dp_cec: fix broken CEC adapter properties check
+    - ice: put Rx buffers after being done with current frame
+    - ice: gather page_count()'s of each frag right before XDP prog call
+    - ice: stop storing XDP verdict within ice_rx_buf
+    - nvme-fc: use ctrl state getter
+    - net: bcmgenet: Correct overlaying of PHY and MAC Wake-on-LAN
+    - vmxnet3: Fix tx queue race condition with XDP
+    - tg3: Disable tg3 PCIe AER on system reboot
+    - udp: gso: do not drop small packets when PMTU reduces
+    - rxrpc: Fix the rxrpc_connection attend queue handling
+    - gpio: pca953x: Improve interrupt support
+    - net: atlantic: fix warning during hot unplug
+    - net: rose: lock the socket in rose_bind()
+    - ACPI: property: Fix return value for nval == 0 in acpi_data_prop_read()
+    - tun: revert fix group permission check
+    - net: sched: Fix truncation of offloaded action statistics
+    - rxrpc: Fix call state set to not include the SERVER_SECURING state
+    - cpufreq: s3c64xx: Fix compilation warning
+    - leds: lp8860: Write full EEPROM, not only half of it
+    - ALSA: hda/realtek: Enable Mute LED on HP Laptop 14s-fq1xxx
+    - drm/modeset: Handle tiled displays in pan_display_atomic.
+    - drm/client: Handle tiled displays better
+    - smb: client: fix order of arguments of tracepoints
+    - smb: client: change lease epoch type from unsigned int to __u16
+    - s390/futex: Fix FUTEX_OP_ANDN implementation
+    - arm64: Filter out SVE hwcaps when FEAT_SVE isn't implemented
+    - m68k: vga: Fix I/O defines
+    - fs/proc: do_task_stat: Fix ESP not readable during coredump
+    - binfmt_flat: Fix integer overflow bug on 32 bit systems
+    - accel/ivpu: Fix Qemu crash when running in passthrough
+    - arm64/kvm: Configure HYP TCR.PS/DS based on host stage1
+    - arm64/sme: Move storage of reg_smidr to __cpuinfo_store_cpu()
+    - KVM: arm64: timer: Always evaluate the need for a soft timer
+    - drm/rockchip: cdn-dp: Use drm_connector_helper_hpd_irq_event()
+    - arm64: dts: rockchip: increase gmac rx_delay on rk3399-puma
+    - remoteproc: omap: Handle ARM dma_iommu_mapping
+    - KVM: Explicitly verify target vCPU is online in kvm_get_vcpu()
+    - KVM: s390: vsie: fix some corner-cases when grabbing vsie pages
+    - ksmbd: fix integer overflows on 32 bit systems
+    - drm/amd/display: Optimize cursor position updates
+    - drm/amd/pm: Mark MM activity as unsupported
+    - drm/amdkfd: only flush the validate MES contex
+    - drm/i915/guc: Debug print LRC state entries only if the context is
+      pinned
+    - drm/i915: Fix page cleanup on DMA remap failure
+    - drm/komeda: Add check for komeda_get_layer_fourcc_list()
+    - drm/i915/dp: Iterate DSC BPP from high to low on all platforms
+    - drm/i915: Drop 64bpp YUV formats from ICL+ SDR planes
+    - drm/amd/display: Fix seamless boot sequence
+    - Bluetooth: L2CAP: accept zero as a special value for MTU auto-selection
+    - clk: sunxi-ng: a100: enable MMC clock reparenting
+    - clk: mmp2: call pm_genpd_init() only after genpd.name is set
+    - media: i2c: ds90ub960: Fix UB9702 refclk register access
+    - clk: qcom: clk-alpha-pll: fix alpha mode configuration
+    - clk: qcom: gcc-sm8550: Do not turn off PCIe GDSCs during gdsc_disable()
+    - clk: qcom: gcc-sm8650: Do not turn off PCIe GDSCs during gdsc_disable()
+    - clk: qcom: gcc-sm6350: Add missing parent_map for two clocks
+    - clk: qcom: dispcc-sm6350: Add missing parent_map for a clock
+    - clk: qcom: gcc-mdm9607: Fix cmd_rcgr offset for blsp1_uart6 rcg
+    - clk: qcom: clk-rpmh: prevent integer overflow in recalc_rate
+    - clk: mediatek: mt2701-vdec: fix conversion to mtk_clk_simple_probe
+    - clk: mediatek: mt2701-aud: fix conversion to mtk_clk_simple_probe
+    - clk: mediatek: mt2701-bdp: add missing dummy clk
+    - clk: mediatek: mt2701-img: add missing dummy clk
+    - clk: mediatek: mt2701-mm: add missing dummy clk
+    - blk-cgroup: Fix class @block_class's subsystem refcount leakage
+    - efi: libstub: Use '-std=gnu11' to fix build with GCC 15
+    - perf bench: Fix undefined behavior in cmpworker()
+    - scsi: ufs: core: Fix the HIGH/LOW_TEMP Bit Definitions
+    - of: Correct child specifier used as input of the 2nd nexus node
+    - of: Fix of_find_node_opts_by_path() handling of alias+path+options
+    - Input: bbnsm_pwrkey - add remove hook
+    - HID: hid-sensor-hub: don't use stale platform-data on remove
+    - ring-buffer: Do not allow events in NMI with generic atomic64 cmpxchg()
+    - atomic64: Use arch_spin_locks instead of raw_spin_locks
+    - wifi: rtlwifi: rtl8821ae: Fix media status report
+    - wifi: brcmfmac: fix NULL pointer dereference in brcmf_txfinalize()
+    - wifi: mt76: mt7921u: Add VID/PID for TP-Link TXE50UH
+    - wifi: rtw88: sdio: Fix disconnection after beacon loss
+    - wifi: mt76: mt7915: add module param to select 5 GHz or 6 GHz on MT7916
+    - usb: gadget: f_tcm: Translate error to sense
+    - usb: gadget: f_tcm: Decrement command ref count on cleanup
+    - usb: gadget: f_tcm: ep_autoconfig with fullspeed endpoint
+    - usb: gadget: f_tcm: Don't prepare BOT write request twice
+    - usbnet: ipheth: fix possible overflow in DPE length check
+    - usbnet: ipheth: use static NDP16 location in URB
+    - usbnet: ipheth: check that DPE points past NCM header
+    - usbnet: ipheth: refactor NCM datagram loop
+    - usbnet: ipheth: break up NCM header size computation
+    - usbnet: ipheth: fix DPE OoB read
+    - usbnet: ipheth: document scope of NCM implementation
+    - ASoC: acp: Support microphone from Lenovo Go S
+    - soc: qcom: socinfo: Avoid out of bounds read of serial number
+    - serial: sh-sci: Drop __initdata macro for port_cfg
+    - serial: sh-sci: Do not probe the serial port if its slot in sci_ports[]
+      is in use
+    - MIPS: Loongson64: remove ROM Size unit in boardinfo
+    - LoongArch: Extend the maximum number of watchpoints
+    - powerpc/pseries/eeh: Fix get PE state translation
+    - dm-crypt: don't update io->sector after kcryptd_crypt_write_io_submit()
+    - dm-crypt: track tag_offset in convert_context
+    - mips/math-emu: fix emulation of the prefx instruction
+    - MIPS: pci-legacy: Override pci_address_to_pio
+    - block: don't revert iter for -EIOCBQUEUED
+    - firmware: qcom: scm: Fix missing read barrier in qcom_scm_is_available()
+    - ALSA: hda/realtek: Enable headset mic on Positivo C6400
+    - ALSA: hda: Fix headset detection failure due to unstable sort
+    - ALSA: hda/realtek: Fix built-in mic on another ASUS VivoBook model
+    - ALSA: hda/realtek: Fix built-in mic breakage on ASUS VivoBook X515JA
+    - arm64: tegra: Fix Tegra234 PCIe interrupt-map
+    - PCI: endpoint: Finish virtual EP removal in pci_epf_remove_vepf()
+    - PCI: dwc: ep: Write BAR_MASK before iATU registers in pci_epc_set_bar()
+    - PCI: dwc: ep: Prevent changing BAR size/flags in pci_epc_set_bar()
+    - scsi: st: Don't set pos_unknown just after device recognition
+    - scsi: qla2xxx: Move FCE Trace buffer allocation to user control
+    - scsi: ufs: qcom: Fix crypto key eviction
+    - scsi: ufs: core: Fix use-after free in init error and remove paths
+    - scsi: storvsc: Set correct data length for sending SCSI command without
+      payload
+    - scsi: core: Do not retry I/Os during depopulation
+    - kbuild: Move -Wenum-enum-conversion to W=2
+    - rust: init: use explicit ABI to clean warning in future compilers
+    - x86/boot: Use '-std=gnu11' to fix build with GCC 15
+    - ubi: Add a check for ubi_num
+    - ARM: dts: dra7: Add bus_dma_limit for l4 cfg bus
+    - ARM: dts: ti/omap: gta04: fix pm issues caused by spi module
+    - arm64: dts: qcom: sm6115: Fix MPSS memory length
+    - arm64: dts: qcom: sm6115: Fix CDSP memory length
+    - arm64: dts: qcom: sm6115: Fix ADSP memory base and length
+    - arm64: dts: qcom: sm6350: Fix ADSP memory length
+    - arm64: dts: qcom: sm6350: Fix MPSS memory length
+    - arm64: dts: qcom: sm6350: Fix uart1 interconnect path
+    - arm64: dts: qcom: sm6375: Fix ADSP memory length
+    - arm64: dts: qcom: sm6375: Fix CDSP memory base and length
+    - arm64: dts: qcom: sm6375: Fix MPSS memory base and length
+    - arm64: dts: qcom: sm8350: Fix ADSP memory base and length
+    - arm64: dts: qcom: sm8350: Fix CDSP memory base and length
+    - arm64: dts: qcom: sm8350: Fix MPSS memory length
+    - arm64: dts: qcom: sm8450: Fix CDSP memory length
+    - arm64: dts: qcom: sm8450: Fix MPSS memory length
+    - arm64: dts: qcom: sm8550: Fix CDSP memory length
+    - arm64: dts: qcom: sm8550: Fix MPSS memory length
+    - arm64: dts: qcom: sm8450: add missing qcom,non-secure-domain property
+    - arm64: dts: qcom: sm8450: Fix ADSP memory base and length
+    - arm64: dts: qcom: sm8550: add missing qcom,non-secure-domain property
+    - arm64: dts: qcom: sm8550: Add dma-coherent property
+    - arm64: dts: qcom: sm8550: Fix ADSP memory base and length
+    - arm64: dts: qcom: sm8650: Fix CDSP memory length
+    - arm64: dts: qcom: sm8650: Fix MPSS memory length
+    - arm64: dts: qcom: sm8550: correct MDSS interconnects
+    - arm64: dts: qcom: sm8650: correct MDSS interconnects
+    - crypto: qce - fix priority to be less than ARMv8 CE
+    - arm64: tegra: Fix typo in Tegra234 dce-fabric compatible
+    - arm64: tegra: Disable Tegra234 sce-fabric node
+    - parisc: Temporarily disable jump label support
+    - pwm: microchip-core: fix incorrect comparison with max period
+    - xfs: Propagate errors from xfs_reflink_cancel_cow_range in
+      xfs_dax_write_iomap_end
+    - xfs: Add error handling for xfs_reflink_cancel_cow_range
+    - ACPI: PRM: Remove unnecessary strict handler address checks
+    - tpm: Change to kvalloc() in eventlog/acpi.c
+    - rv: Reset per-task monitors also for idle tasks
+    - hrtimers: Force migrate away hrtimers queued after
+      CPUHP_AP_HRTIMERS_DYING
+    - kfence: skip __GFP_THISNODE allocations on NUMA systems
+    - media: ccs: Clean up parsed CCS static data on parse failure
+    - mm/hugetlb: fix avoid_reserve to allow taking folio from subpool
+    - iio: light: as73211: fix channel handling in only-color triggered buffer
+    - soc: mediatek: mtk-devapc: Fix leaking IO map on error paths
+    - soc: mediatek: mtk-devapc: Fix leaking IO map on driver remove
+    - soc: qcom: smem_state: fix missing of_node_put in error path
+    - media: mmp: Bring back registration of the device
+    - media: mc: fix endpoint iteration
+    - media: nuvoton: Fix an error check in npcm_video_ece_init()
+    - media: imx296: Add standby delay during probe
+    - media: ov5640: fix get_light_freq on auto
+    - media: stm32: dcmipp: correct dma_set_mask_and_coherent mask value
+    - media: ccs: Fix CCS static data parsing for large block sizes
+    - media: ccs: Fix cleanup order in ccs_probe()
+    - media: i2c: ds90ub9x3: Fix extra fwnode_handle_put()
+    - media: i2c: ds90ub960: Fix use of non-existing registers on UB9702
+    - media: i2c: ds90ub960: Fix UB9702 VC map
+    - media: i2c: ds90ub960: Fix logging SP & EQ status only for UB9702
+    - media: uvcvideo: Fix crash during unbind if gpio unit is in use
+    - media: uvcvideo: Fix event flags in uvc_ctrl_send_events
+    - media: uvcvideo: Support partial control reads
+    - media: uvcvideo: Remove redundant NULL assignment
+    - media: uvcvideo: Refactor iterators
+    - media: uvcvideo: Only save async fh if success
+    - media: uvcvideo: Remove dangling pointers
+    - mm: kmemleak: fix upper boundary check for physical address objects
+    - mm/compaction: fix UBSAN shift-out-of-bounds warning
+    - ata: libata-sff: Ensure that we cannot write outside the allocated
+      buffer
+    - crypto: qce - fix goto jump in error path
+    - crypto: qce - unregister previously registered algos in error path
+    - nvmem: qcom-spmi-sdam: Set size in struct nvmem_config
+    - nvmem: core: improve range check for nvmem_cell_write()
+    - nvmem: imx-ocotp-ele: simplify read beyond device check
+    - nvmem: imx-ocotp-ele: fix MAC address byte order
+    - nvmem: imx-ocotp-ele: fix reading from non zero offset
+    - nvmem: imx-ocotp-ele: set word length to 1
+    - io_uring: fix multishots with selected buffers
+    - io_uring/net: don't retry connect operation on EPOLLERR
+    - selftests: mptcp: connect: -f: no reconnect
+    - pnfs/flexfiles: retry getting layout segment for reads
+    - ocfs2: fix incorrect CPU endianness conversion causing mount failure
+    - ocfs2: handle a symlink read error correctly
+    - nilfs2: fix possible int overflows in nilfs_fiemap()
+    - nfs: Make NFS_FSCACHE select NETFS_SUPPORT instead of depending on it
+    - NFSD: Encode COMPOUND operation status on page boundaries
+    - mailbox: tegra-hsp: Clear mailbox before using message
+    - NFC: nci: Add bounds checking in nci_hci_create_pipe()
+    - irqchip/apple-aic: Only handle PMC interrupt as FIQ when configured so
+    - mtd: onenand: Fix uninitialized retlen in do_otp_read()
+    - misc: misc_minor_alloc to use ida for all dynamic/misc dynamic minors
+    - char: misc: deallocate static minor in error path
+    - misc: fastrpc: Deregister device nodes properly in error scenarios
+    - misc: fastrpc: Fix registered buffer page address
+    - misc: fastrpc: Fix copy buffer page size
+    - net/ncsi: wait for the last response to Deselect Package before
+      configuring channel
+    - net: phy: c45-tjaxx: add delay between MDIO write and read in soft_reset
+    - maple_tree: simplify split calculation
+    - scripts/gdb: fix aarch64 userspace detection in get_current_task
+    - tracing/osnoise: Fix resetting of tracepoints
+    - rtla/osnoise: Distinguish missing workload option
+    - rtla: Add trace_instance_stop
+    - rtla/timerlat_hist: Stop timerlat tracer on signal
+    - rtla/timerlat_top: Stop timerlat tracer on signal
+    - pinctrl: samsung: fix fwnode refcount cleanup if
+      platform_get_irq_optional() fails
+    - ptp: Ensure info->enable callback is always set
+    - RDMA/mlx5: Fix a race for an ODP MR which leads to CQE with error
+    - rtc: zynqmp: Fix optional clock name property
+    - MIPS: ftrace: Declare ftrace_get_parent_ra_addr() as static
+    - xfs: avoid nested calls to __xfs_trans_commit
+    - xfs: don't lose solo superblock counter update transactions
+    - spi: atmel-quadspi: Create `atmel_qspi_ops` to support newer SoC
+      families
+    - spi: atmel-qspi: Memory barriers after memory-mapped I/O
+    - btrfs: avoid monopolizing a core when activating a swap file
+    - mptcp: prevent excessive coalescing on receive
+    - Revert "drm/amd/display: Fix green screen issue after suspend"
+    - statmount: let unset strings be empty
+    - arm64: dts: rockchip: add reset-names for combphy on rk3568
+    - ocfs2: check dir i_size in ocfs2_find_entry
+    - Upstream stable to v6.6.77, v6.12.14
+  * kvmppc_set_passthru_irq_hv: Could not assign IRQ map traces are seen when
+    pci device is attached to kvm guest when "xive=off" is set (LP: #2109951)
+    - KVM: PPC: Book3S HV: Fix IRQ map warnings with XICS on pSeries KVM Guest
+  * Latitude 5450 is experiencing packet loss on Ethernet in Ubuntu 22.04
+    (LP: #2106558)
+    - e1000e: change k1 configuration on MTP and later platforms
+  * cpufreq amd-pstate: cpuinfo_max_freq reports incorrect value
+    (LP: #2109609)
+    - SAUCE: Revert "Revert "cpufreq: amd-pstate: Fix the inconsistency in max
+      frequency units""
+  * Backport pci=config_acs parameter with fix commit (LP: #2100340)
+    - PCI: Extend ACS configurability
+    - PCI: Fix pci_enable_acs() support for the ACS quirks
+    - PCI/ACS: Fix 'pci=config_acs=' parameter
+  * [UBUNTU 24.04] s390/pci: Fix zpci_bus_is_isolated_vf() for non-VF
+    (LP: #2111599)
+    - s390/pci: Fix zpci_bus_is_isolated_vf() for non-VFs
+  * nvme/tcp hangs IO on arm (LP: #2106381)
+    - nvmet-tcp: Fix a possible sporadic response drops in weakly ordered arch
+  * CVE-2025-37750
+    - smb: client: fix UAF in decryption with multichannel
+  * CVE-2025-40364
+    - io_uring: fix io_req_prep_async with provided buffers
+  * CVE-2024-49887
+    - f2fs: fix to handle segment allocation failure correctly
+    - f2fs: fix to don't panic system for no free segment fault injection
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953)
+    - powerpc/book3s64/hugetlb: Fix disabling hugetlb when fadump is active
+    - dlm: fix srcu_read_lock() return type to int
+    - afs: Fix EEXIST error returned from afs_rmdir() to be ENOTEMPTY
+    - afs: Fix directory format encoding struct
+    - afs: Fix cleanup of immediately failed async calls
+    - fs: fix proc_handler for sysctl_nr_open
+    - block: retry call probe after request_module in blk_request_module
+    - pstore/blk: trivial typo fixes
+    - nvme: Add error check for xa_store in nvme_get_effects_log
+    - selftests/powerpc: Fix argument order to timer_sub()
+    - nvme: Add error path for xa_store in nvme_init_effects
+    - partitions: ldm: remove the initial kernel-doc notation
+    - select: Fix unbalanced user_access_end()
+    - nvme: fix bogus kzalloc() return check in nvme_init_effects_log()
+    - afs: Fix the fallback handling for the YFS.RemoveFile2 RPC call
+    - perf/core: Save raw sample data conditionally based on sample type
+    - sched/fair: Fix value reported by hot tasks pulled in /proc/schedstat
+    - x86/cpu: Enable SD_ASYM_PACKING for PKG domain on AMD
+    - x86/topology: Use x86_sched_itmt_flags for PKG domain unconditionally
+    - drm/msm/dp: set safe_to_exit_level before printing it
+    - drm/etnaviv: Fix page property being used for non writecombine buffers
+    - drm/amd/pm: Fix an error handling path in
+      vega10_enable_se_edc_force_stall_config()
+    - drm/rockchip: vop2: Fix cluster windows alpha ctrl regsiters offset
+    - drm/rockchip: vop2: Fix the mixer alpha setup for layer 0
+    - drm/rockchip: vop2: Fix the windows switch between different layers
+    - drm/rockchip: vop2: Check linear format for Cluster windows on rk3566/8
+    - drm/rockchip: vop2: include rockchip_drm_drv.h
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8150
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SC8180X
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8250
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8350
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8550
+    - drm/msm: Check return value of of_dma_configure()
+    - drm/bridge: it6505: Change definition of AUX_FIFO_MAX_SIZE
+    - drm/amdgpu: tear down ttm range manager for doorbell in
+      amdgpu_ttm_fini()
+    - genirq: Make handle_enforce_irqctx() unconditionally available
+    - wifi: ath11k: Fix unexpected return buffer manager error for
+      WCN6750/WCN6855
+    - wifi: rtlwifi: do not complete firmware loading needlessly
+    - wifi: rtlwifi: rtl8192se: rise completion of firmware loading as last
+      step
+    - wifi: rtlwifi: wait for firmware loading before releasing memory
+    - wifi: rtlwifi: fix init_sw_vars leak when probe fails
+    - wifi: rtlwifi: usb: fix workqueue leak when probe fails
+    - net_sched: sch_sfq: annotate data-races around q->perturb_period
+    - net_sched: sch_sfq: handle bigger packets
+    - spi: zynq-qspi: Add check for clk_enable()
+    - dt-bindings: mmc: controller: clarify the address-cells description
+    - of: remove internal arguments from of_property_for_each_u32()
+    - clk: fix an OF node reference leak in of_clk_get_parent_name()
+    - dt-bindings: leds: class-multicolor: Fix path to color definitions
+    - wifi: rtlwifi: destroy workqueue at rtl_deinit_core
+    - wifi: rtlwifi: pci: wait for firmware loading before releasing memory
+    - HID: multitouch: fix support for Goodix PID 0x01e9
+    - regulator: dt-bindings: mt6315: Drop regulator-compatible property
+    - wifi: brcmfmac: add missing header include for brcmf_dbg
+    - ACPI: fan: cleanup resources in the error path of .probe()
+    - cpupower: fix TSC MHz calculation
+    - dt-bindings: mfd: bd71815: Fix rsense and typos
+    - leds: netxbig: Fix an OF node reference leak in
+      netxbig_leds_get_of_pdata()
+    - inetpeer: remove create argument of inet_getpeer_v[46]()
+    - inetpeer: remove create argument of inet_getpeer()
+    - inetpeer: update inetpeer timestamp in inet_getpeer()
+    - inetpeer: do not get a refcount in inet_getpeer()
+    - pwm: stm32-lp: Add check for clk_enable()
+    - cpufreq: schedutil: Fix superfluous updates caused by need_freq_update
+    - gpio: pca953x: log an error when failing to get the reset GPIO
+    - cpufreq: qcom: Fix qcom_cpufreq_hw_recalc_rate() to query LUT if LMh IRQ
+      is not available
+    - cpufreq: qcom: Implement clk_ops::determine_rate() for qcom_cpufreq*
+      clocks
+    - clk: imx8mp: Fix clkout1/2 support
+    - dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and PLL_MIPI
+    - clk: sunxi-ng: a64: drop redundant CLK_PLL_VIDEO0_2X and CLK_PLL_MIPI
+    - clk: sunxi-ng: a64: stop force-selecting PLL-MIPI as TCON0 parent
+    - regulator: of: Implement the unwind path of of_regulator_match()
+    - OPP: OF: Fix an OF node leak in _opp_add_static_v2()
+    - ipmi: ssif_bmc: Fix new request loss when bmc ready for a response
+    - wifi: ath12k: fix tx power, max reg power update to firmware
+    - clk: qcom: gcc-sdm845: Do not use shared clk_ops for QUPs
+    - HID: fix generic desktop D-Pad controls
+    - leds: cht-wcove: Use devm_led_classdev_register() to avoid memory leak
+    - mfd: syscon: Remove extern from function prototypes
+    - mfd: syscon: Add of_syscon_register_regmap() API
+    - mfd: syscon: Use scoped variables with memory allocators to simplify
+      error paths
+    - mfd: syscon: Fix race in device_node_get_regmap()
+    - samples/landlock: Fix possible NULL dereference in parse_path()
+    - wifi: wlcore: fix unbalanced pm_runtime calls
+    - wifi: mt76: mt7915: Fix mesh scan on MT7916 DBDC
+    - wifi: mac80211: fix tid removal during mesh forwarding
+    - wifi: mac80211: Fix common size calculation for ML element
+    - net/smc: fix data error when recvmsg with MSG_PEEK flag
+    - wifi: mt76: mt76u_vendor_request: Do not print error messages when
+      -EPROTO
+    - wifi: mt76: mt7921: fix using incorrect group cipher after
+      disconnection.
+    - wifi: mt76: mt7915: fix overflows seen when writing limit attributes
+    - wifi: mt76: mt7996: fix rx filter setting for bfee functionality
+    - wifi: mt76: mt7915: firmware restart on devices with a second pcie link
+    - wifi: mt76: connac: move mt7615_mcu_del_wtbl_all to connac
+    - wifi: mt76: mt7915: improve hardware restart reliability
+    - wifi: mt76: mt7915: fix omac index assignment after hardware reset
+    - wifi: mt76: mt7915: fix register mapping
+    - wifi: mt76: mt7996: fix register mapping
+    - wifi: mt76: mt7996: add max mpdu len capability
+    - wifi: mt76: mt7996: fix the capability of reception of EHT MU PPDU
+    - wifi: mt76: mt7996: fix HE Phy capability
+    - wifi: mt76: mt7996: fix incorrect indexing of MIB FW event
+    - wifi: mt76: mt7996: fix ldpc setting
+    - cpufreq: ACPI: Fix max-frequency computation
+    - selftests: timers: clocksource-switch: Adapt progress to kselftest
+      framework
+    - selftests: harness: fix printing of mismatch values in __EXPECT()
+    - wifi: cfg80211: adjust allocation of colocated AP data
+    - inet: ipmr: fix data-races
+    - clk: analogbits: Fix incorrect calculation of vco rate delta
+    - pwm: stm32: Add check for clk_enable()
+    - selftests/landlock: Fix error message
+    - net/mlxfw: Drop hard coded max FW flash image size
+    - octeon_ep: remove firmware stats fetch in ndo_get_stats64
+    - netfilter: nf_tables: fix set size with rbtree backend
+    - netfilter: nft_flow_offload: update tcp state flags under lock
+    - tcp_cubic: fix incorrect HyStart round start detection
+    - libbpf: don't adjust USDT semaphore address if .stapsdt.base addr is
+      missing
+    - tools/testing/selftests/bpf/test_tc_tunnel.sh: Fix wait for server bind
+    - libbpf: Fix segfault due to libelf functions not setting errno
+    - ASoC: sun4i-spdif: Add clock multiplier settings
+    - selftests/bpf: Fix fill_link_info selftest on powerpc
+    - crypto: caam - use JobR's space to access page 0 regs
+    - perf header: Fix one memory leakage in process_bpf_btf()
+    - perf header: Fix one memory leakage in process_bpf_prog_info()
+    - perf bpf: Fix two memory leakages when calling
+      perf_env__insert_bpf_prog_info()
+    - ASoC: renesas: rz-ssi: Use only the proper amount of dividers
+    - perf expr: Initialize is_test value in expr__ctx_new()
+    - ktest.pl: Remove unused declarations in run_bisect_test function
+    - crypto: hisilicon/sec2 - fix for aead icv error
+    - crypto: hisilicon/sec2 - fix for aead invalid authsize
+    - crypto: ixp4xx - fix OF node reference leaks in init_ixp_crypto()
+    - ALSA: seq: remove redundant 'tristate' for SND_SEQ_UMP_CLIENT
+    - ALSA: seq: Make dependency on UMP clearer
+    - padata: fix sysfs store callback check
+    - perf top: Don't complain about lack of vmlinux when not resolving some
+      kernel samples
+    - perf machine: Don't ignore _etext when not a text symbol
+    - perf namespaces: Introduce nsinfo__set_in_pidns()
+    - perf namespaces: Fixup the nsinfo__in_pidns() return type, its bool
+    - ASoC: Intel: avs: Prefix SKL/APL-specific members
+    - ASoC: Intel: avs: Abstract IPC handling
+    - ASoC: Intel: avs: Do not readq() u32 registers
+    - ASoC: Intel: avs: Fix theoretical infinite loop
+    - perf report: Fix misleading help message about --demangle
+    - pinctrl: stm32: Add check for clk_enable()
+    - pinctrl: amd: Take suspend type into consideration which pins are non-
+      wake
+    - bpf: tcp: Mark bpf_load_hdr_opt() arg2 as read-write
+    - ALSA: hda/realtek - Fixed headphone distorted sound on Acer Aspire
+      A115-31 laptop
+    - perf lock: Fix parse_lock_type which only retrieve one lock flag
+    - padata: add pd get/put refcnt helper
+    - cifs: Use cifs_autodisable_serverino() for disabling
+      CIFS_MOUNT_SERVER_INUM in readdir.c
+    - soc: atmel: fix device_node release in atmel_soc_device_init()
+    - ARM: at91: pm: change BU Power Switch to automatic mode
+    - arm64: dts: mediatek: mt8186: Move wakeup to MTU3 to get working suspend
+    - arm64: dts: mt8183: set DMIC one-wire mode on Damu
+    - arm64: dts: mediatek: mt8516: fix GICv2 range
+    - arm64: dts: mediatek: mt8516: fix wdt irq type
+    - arm64: dts: mediatek: mt8516: add i2c clock-div property
+    - arm64: dts: mediatek: mt8516: reserve 192 KiB for TF-A
+    - ARM: dts: stm32: Fix IPCC EXTI declaration on stm32mp151
+    - RDMA/mlx4: Avoid false error about access to uninitialized gids array
+    - arm64: dts: mediatek: mt8173-evb: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8173-elm: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8192-asurada: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8195-cherry: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8195-demo: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8173-elm: Fix MT6397 PMIC sub-node names
+    - arm64: dts: mediatek: mt8173-evb: Fix MT6397 PMIC sub-node names
+    - ARM: dts: aspeed: yosemite4: correct the compatible string of adm1272
+    - ARM: dts: aspeed: yosemite4: Add required properties for IOE on fan
+      boards
+    - ARM: dts: aspeed: yosemite4: correct the compatible string for max31790
+    - arm: dts: socfpga: use reset-name "stmmaceth-ocp" instead of "ahb"
+    - RDMA/rxe: Improve newline in printing messages
+    - RDMA/rxe: Fix mismatched max_msg_sz
+    - arm64: dts: mediatek: mt8183: kenzo: Support second source touchscreen
+    - arm64: dts: mediatek: mt8183: willow: Support second source touchscreen
+    - RDMA/srp: Fix error handling in srp_add_port
+    - arm64: dts: mediatek: mt8195: Remove suspend-breaking reset from pcie1
+    - ARM: dts: stm32: Deduplicate serial aliases and chosen node for
+      STM32MP15xx DHCOM SoM
+    - ARM: dts: stm32: Swap USART3 and UART8 alias on STM32MP15xx DHCOM SoM
+    - arm64: dts: mediatek: mt8183-kukui-jacuzzi: Drop pp3300_panel voltage
+      settings
+    - arm64: dts: qcom: msm8996-xiaomi-gemini: Fix LP5562 LED1 reg property
+    - arm64: dts: qcom: move common parts for sa8775p-ride variants into a
+      .dtsi
+    - arm64: dts: qcom: sa8775p: Update sleep_clk frequency
+    - arm64: dts: qcom: msm8996: Fix up USB3 interrupts
+    - arm64: dts: qcom: msm8994: Describe USB interrupts
+    - arm64: dts: qcom: sm7225-fairphone-fp4: Drop extra qcom,msm-id value
+    - arm64: dts: qcom: msm8916: correct sleep clock frequency
+    - arm64: dts: qcom: msm8939: correct sleep clock frequency
+    - arm64: dts: qcom: msm8994: correct sleep clock frequency
+    - arm64: dts: qcom: qcs404: correct sleep clock frequency
+    - arm64: dts: qcom: q[dr]u1000: correct sleep clock frequency
+    - arm64: dts: qcom: qrb4210-rb2: correct sleep clock frequency
+    - arm64: dts: qcom: sc7280: correct sleep clock frequency
+    - arm64: dts: qcom: sdx75: correct sleep clock frequency
+    - arm64: dts: qcom: sm4450: correct sleep clock frequency
+    - arm64: dts: qcom: sm6125: correct sleep clock frequency
+    - arm64: dts: qcom: sm6375: correct sleep clock frequency
+    - arm64: dts: qcom: sm8250: correct sleep clock frequency
+    - arm64: dts: qcom: sm8350: correct sleep clock frequency
+    - arm64: dts: qcom: sm8450: correct sleep clock frequency
+    - ARM: dts: microchip: sama5d27_wlsom1_ek: Add no-1-8-v property to sdmmc0
+      node
+    - arm64: dts: ti: k3-am62: Remove duplicate GICR reg
+    - arm64: dts: ti: k3-am62a: Remove duplicate GICR reg
+    - arm64: dts: allwinner: a64: explicitly assign clock parent for TCON0
+    - RDMA/bnxt_re: Fix to drop reference to the mmap entry in case of error
+    - ARM: omap1: Fix up the Retu IRQ on Nokia 770
+    - arm64: dts: qcom: sdm845-db845c-navigation-mezzanine: Convert mezzanine
+      riser to dtso
+    - arm64: dts: qcom: sdm845-db845c-navigation-mezzanine: remove disabled
+      ov7251 camera
+    - arm64: dts: qcom: sc7180-trogdor-quackingstick: add missing avee-supply
+    - arm64: dts: qcom: sc7180-*: Remove thermal zone polling delays
+    - arm64: dts: qcom: sc7180-trogdor-pompom: rename 5v-choke thermal zone
+    - arm64: dts: qcom: sc7180: change labels to lower-case
+    - arm64: dts: qcom: sc7180: fix psci power domain node names
+    - arm64: dts: qcom: sm8150-microsoft-surface-duo: fix typos in da7280
+      properties
+    - arm64: dts: qcom: sc8280xp: Fix up remoteproc register space sizes
+    - dts: arm64: mediatek: mt8195: Remove MT8183 compatible for OVL
+    - arm64: dts: mediatek: add per-SoC compatibles for keypad nodes
+    - arm64: dts: qcom: sdm845: Fix interrupt types of camss interrupts
+    - arm64: dts: qcom: sm8250: Fix interrupt types of camss interrupts
+    - ARM: dts: mediatek: mt7623: fix IR nodename
+    - fbdev: omapfb: Fix an OF node leak in dss_of_port_get_parent_device()
+    - arm64: tegra: Fix DMA ID for SPI2
+    - i3c: dw: Add hot-join support.
+    - RDMA/mlx5: Fix indirect mkey ODP page count
+    - of: reserved-memory: Do not make kmemleak ignore freed address
+    - efi: sysfb_efi: fix W=1 warnings when EFI is not set
+    - spi: omap2-mcspi: Correctly handle devm_clk_get_optional() errors
+    - media: rc: iguanair: handle timeouts
+    - media: lmedm04: Handle errors for lme2510_int_read
+    - PCI: endpoint: Destroy the EPC device in devm_pci_epc_destroy()
+    - media: marvell: Add check for clk_enable()
+    - media: i2c: imx290: Register 0x3011 varies between imx327 and imx290
+    - media: i2c: imx412: Add missing newline to prints
+    - media: i2c: ov9282: Correct the exposure offset
+    - media: mipi-csis: Add check for clk_enable()
+    - media: camif-core: Add check for clk_enable()
+    - media: uvcvideo: Propagate buf->error to userspace
+    - mtd: rawnand: brcmnand: fix status read of brcmnand_waitfunc
+    - mtd: hyperbus: hbmc-am654: fix an OF node reference leak
+    - media: nxp: imx8-isi: fix v4l2-compliance test errors
+    - watchdog: rti_wdt: Fix an OF node leak in rti_wdt_probe()
+    - staging: media: imx: fix OF node leak in imx_media_add_of_subdevs()
+    - media: dvb-usb-v2: af9035: fix ISO C90 compilation error on
+      af9035_i2c_master_xfer
+    - PCI: endpoint: pci-epf-test: Set dma_chan_rx pointer to NULL on error
+    - PCI: endpoint: pci-epf-test: Fix check for DMA MEMCPY test
+    - scsi: mpt3sas: Set ioc->manu_pg11.EEDPTagMode directly to 1
+    - scsi: ufs: bsg: Delete bsg_dev when setting up bsg fails
+    - ocfs2: mark dquot as inactive if failed to start trans while releasing
+      dquot
+    - module: Extend the preempt disabled section in
+      dereference_symbol_descriptor().
+    - serial: 8250: Adjust the timeout for FIFO mode
+    - NFSv4.2: fix COPY_NOTIFY xdr buf size calculation
+    - NFSv4.2: mark OFFLOAD_CANCEL MOVEABLE
+    - tools/bootconfig: Fix the wrong format specifier
+    - xfrm: replay: Fix the update of replay_esn->oseq_hi for GSO
+    - dmaengine: ti: edma: fix OF node reference leaks in edma_driver
+    - rtc: loongson: clear TOY_MATCH0_REG in loongson_rtc_isr()
+    - regulator: core: Add missing newline character
+    - gpio: mxc: remove dead code after switch to DT-only
+    - net: fec: implement TSO descriptor cleanup
+    - PM: hibernate: Add error handling for syscore_suspend()
+    - iavf: allow changing VLAN state without calling PF
+    - net: netdevsim: try to close UDP port harness races
+    - ptp: Properly handle compat ioctls
+    - net: stmmac: Limit the number of MTL queues to hardware capability
+    - net: stmmac: Limit FIFO size by hardware capability
+    - perf trace: Fix runtime error of index out of bounds
+    - Bluetooth: btnxpuart: Fix glitches seen in dual A2DP streaming
+    - vsock: Allow retrying on connect() failure
+    - bgmac: reduce max frame size to support just MTU 1500
+    - net: sh_eth: Fix missing rtnl lock in suspend/resume path
+    - genksyms: fix memory leak when the same symbol is added from source
+    - genksyms: fix memory leak when the same symbol is read from *.symref
+      file
+    - RISC-V: Mark riscv_v_init() as __init
+    - ASoC: rockchip: i2s_tdm: Re-add the set_sysclk callback
+    - io_uring/uring_cmd: use cached cmd_op in io_uring_cmd_sock()
+    - cifs: Fix getting and setting SACLs over SMB1
+    - kconfig: fix file name in warnings when loading KCONFIG_DEFCONFIG_LIST
+    - kconfig: fix memory leak in sym_warn_unmet_dep()
+    - hexagon: fix using plain integer as NULL pointer warning in cmpxchg
+    - hexagon: Fix unbalanced spinlock in die()
+    - f2fs: Introduce linear search for dentries
+    - Revert "SUNRPC: Reduce thread wake-up rate when receiving large RPC
+      messages"
+    - kbuild: switch from lz4c to lz4 for compression
+    - selftests/rseq: Fix handling of glibc without rseq support
+    - ktest.pl: Check kernelrelease return in get_version
+    - ALSA: usb-audio: Add delay quirk for iBasso DC07 Pro
+    - usb: gadget: f_tcm: Fix Get/SetInterface return value
+    - usb: dwc3-am62: Fix an OF node leak in phy_syscon_pll_refclk()
+    - usb: dwc3: core: Defer the probe until USB power supply ready
+    - usb: typec: tcpm: set SRC_SEND_CAPABILITIES timeout to
+      PD_T_SENDER_RESPONSE
+    - usb: typec: tcpci: Prevent Sink disconnection before vPpsShutdown in SPR
+      PPS
+    - btrfs: output the reason for open_ctree() failure
+    - s390: Add '-std=gnu11' to decompressor and purgatory CFLAGS
+    - LoongArch: Change 8 to 14 for LOONGARCH_MAX_{BRP,WRP}
+    - block: copy back bounce buffer to user-space correctly in case of split
+    - nvme-tcp: Fix I/O queue cpu spreading for multiple controllers
+    - sched/fair: Untangle NEXT_BUDDY and pick_next_task()
+    - sched: Fix race between yield_to() and try_to_wake_up()
+    - drm/v3d: Fix performance counter source settings on V3D 7.x
+    - drm/rockchip: vop2: fix rk3588 dp+dsi maxclk verification
+    - drm/rockchip: vop2: Set AXI id for rk3588
+    - drm/rockchip: vop2: Setup delay cycle for Esmart2/3
+    - drm/rockchip: vop2: Add check for 32 bpp format for rk3588
+    - drm/msm/dpu: provide DSPP and correct LM config for SDM670
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8650
+    - drm/msm: don't clean up priv->kms prematurely
+    - drm/msm/mdp4: correct LCDC regulator name
+    - wifi: rtlwifi: rtl8821ae: phy: restore removed code to fix infinite loop
+    - selftests/bpf: Actuate tx_metadata_len in xdp_hw_metadata
+    - selftests: ktap_helpers: Fix uninitialized variable
+    - inet: constify inet_sk_bound_dev_eq() net parameter
+    - inet: constify 'struct net' parameter of various lookup helpers
+    - udp: constify 'struct net' parameter of socket lookups
+    - inet6: constify 'struct net' parameter of various lookup helpers
+    - ipv6: udp: constify 'struct net' parameter of socket lookups
+    - dt-bindings: clock: imx93: Drop IMX93_CLK_END macro definition
+    - dt-bindings: clock: Add i.MX91 clock support
+    - dt-bindings: clock: imx93: Add SPDIF IPG clk
+    - clk: imx93: Move IMX93_CLK_END macro to clk driver
+    - clk: imx: add i.MX91 clk
+    - clk: imx93: Add IMX93_CLK_SPDIF_IPG clock
+    - arm64: dts: imx93: Use IMX93_CLK_SPDIF_IPG as SPDIF IPG clock
+    - clk: imx: Apply some clks only for i.MX93
+    - wifi: rtw89: mcc: consider time limits not divisible by 1024
+    - wifi: iwlwifi: cleanup uefi variables loading
+    - wifi: iwlwifi: fw: read STEP table from correct UEFI var
+    - wifi: mt76: mt7996: fix overflows seen when writing limit attributes
+    - wifi: mt76: mt7996: fix definition of tx descriptor
+    - Bluetooth: btbcm: Fix NULL deref in btbcm_get_board_name()
+    - platform/mellanox: mlxbf-pmc: incorrect type in assignment
+    - platform/x86: x86-android-tablets: make platform data be static
+    - crypto: api - Fix boot-up self-test race
+    - pinctrl: nomadik: Add check for clk_enable()
+    - rhashtable: Fix potential deadlock by moving schedule_work outside lock
+    - crypto: iaa - Fix IAA disabling that occurs when sync_mode is set to
+      'async'
+    - perf maps: Fix display of kernel symbols
+    - perf MANIFEST: Add arch/*/include/uapi/asm/bpf_perf_event.h to the perf
+      tarball
+    - ALSA: hda: Fix compilation of snd_hdac_adsp_xxx() helpers
+    - tools: Sync if_xdp.h uapi tooling header
+    - rhashtable: Fix rhashtable_try_insert test
+    - ARM: dts: imx7-tqma7: add missing vs-supply for LM75A (rev. 01xxx)
+    - arm64: dts: renesas: rzg3s-smarc: Fix the debug serial alias
+    - arm64: dts: mediatek: mt8395-genio-1200-evk: Drop regulator-compatible
+      property
+    - arm64: dts: qcom: sm8550: correct sleep clock frequency
+    - arm64: dts: qcom: sm8650: correct sleep clock frequency
+    - arm64: dts: qcom: x1e80100: correct sleep clock frequency
+    - ARM: dts: microchip: sama5d29_curiosity: Add no-1-8-v property to sdmmc0
+      node
+    - RDMA/hns: Clean up the legacy CONFIG_INFINIBAND_HNS
+    - [Config] updateconfigs for INFINIBAND_HNS
+    - RDMA/cxgb4: Notify rdma stack for IB_EVENT_QP_LAST_WQE_REACHED event
+    - iommu: iommufd: fix WARNING in iommufd_device_unbind
+    - remoteproc: mtk_scp: Only populate devices for SCP cores
+    - PCI: imx6: Deassert apps_reset in imx_pcie_deassert_core_reset()
+    - PCI: dwc: Always stop link in the dw_pcie_suspend_noirq
+    - PCI: microchip: Add support for using either Root Port 1 or 2
+    - PCI: microchip: Set inbound address translation for coherent or non-
+      coherent mode
+    - erofs: get rid of erofs_{find,insert}_workgroup
+    - erofs: move erofs_workgroup operations into zdata.c
+    - erofs: sunset `struct erofs_workgroup`
+    - erofs: fix potential return value overflow of z_erofs_shrink_scan()
+    - tty: mips_ejtag_fdc: fix one more u8 warning
+    - xfrm: Add support for per cpu xfrm state handling.
+    - xfrm: Cache used outbound xfrm states at the policy.
+    - xfrm: Add an inbound percpu state cache.
+    - xfrm: Don't disable preemption while looking up cache state.
+    - idpf: add read memory barrier when checking descriptor done bit
+    - net/ncsi: use dev_set_mac_address() for Get MC MAC Address handling
+    - tools: ynl: c: correct reverse decode of empty attrs
+    - selftests: mptcp: extend CFLAGS to keep options from environment
+    - selftests: net/{lib,openvswitch}: extend CFLAGS to keep options from
+      environment
+    - net: ethtool: only allow set_rxnfc with rss + ring_cookie if driver opts
+      in
+    - ethtool: Fix set RXNFC command with symmetric RSS hash
+    - tools/power turbostat: Fix forked child affinity regression
+    - md: add a new callback pers->bitmap_sector()
+    - md/raid5: implement pers->bitmap_sector()
+    - xfs: check for dead buffers in xfs_buf_find_insert
+    - xfs: don't shut down the filesystem for media failures beyond end of log
+    - usb: dwc3: Skip resume if pm_runtime_set_active() fails
+    - clk: qcom: gcc-x1e80100: Do not turn off usb_2 controller GDSC
+    - xfrm: Add error handling when nla_put_u32() returns an error
+    - xfrm: Fix acquire state insertion.
+    - ethtool: Fix access to uninitialized fields in set RXNFC command
+    - ASoC: da7213: Initialize the mutex
+    - drm/amd/display: Add hubp cache reset when powergating
+    - KVM: x86: Plumb in the vCPU to kvm_x86_ops.hwapic_isr_update()
+    - ethtool: ntuple: fix rss + ring_cookie check
+    - Upstream stable to v6.6.76, v6.12.13
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57975
+    - btrfs: do proper folio cleanup when run_delalloc_nocow() failed
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21714
+    - RDMA/mlx5: Fix implicit ODP use after free
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21801
+    - net: ravb: Fix missing rtnl lock in suspend/resume path
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21809
+    - rxrpc, afs: Fix peer hash locking vs RCU callback
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58057
+    - idpf: convert workqueues to unbound
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57953
+    - rtc: tps6594: Fix integer overflow on 32bit systems
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57982
+    - xfrm: state: fix out-of-bounds read during lookup
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21721
+    - nilfs2: handle errors that nilfs_prepare_chunk() may return
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21722
+    - nilfs2: do not force clear folio if buffer is referenced
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21798
+    - firewire: test: Fix potential null dereference in firewire kunit test
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21723
+    - scsi: mpi3mr: Fix possible crash when setting up bsg fails
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21724
+    - iommufd/iova_bitmap: Fix shift-out-of-bounds in
+      iova_bitmap_offset_to_index()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21825
+    - bpf: Cancel the running bpf_timer through kworker for PREEMPT_RT
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57990
+    - wifi: mt76: mt7925: fix off by one in mt7925_load_clc()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57974
+    - udp: Deal with race between UDP socket address change and rehash
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57994
+    - ptr_ring: do not block hard interrupts in ptr_ring_resize_multiple()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57999
+    - powerpc/pseries/iommu: IOMMU incorrectly marks MMIO range in DDW
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58054
+    - staging: media: max96712: fix kernel oops when removing module
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58055
+    - usb: gadget: f_tcm: Don't free command immediately
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57979
+    - pps: Fix a use-after-free
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57980
+    - media: uvcvideo: Fix double free in error path
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58056
+    - remoteproc: core: Fix ida_free call while not allocated
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21705
+    - mptcp: handle fastopen disconnect correctly
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21707
+    - mptcp: consolidate suboption status
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57981
+    - usb: xhci: Fix NULL pointer dereference on certain command aborts
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21708
+    - net: usb: rtl8150: enable basic endpoint checking
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21826
+    - netfilter: nf_tables: reject mismatching sum of field_len with set key
+      length
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21808
+    - net: xdp: Disallow attaching device-bound programs in generic mode
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21710
+    - tcp: correct handling of extreme memory squeeze
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21715
+    - net: davicom: fix UAF in dm9000_drv_remove
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21716
+    - vxlan: Fix uninit-value in vxlan_vnifilter_dump()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21718
+    - net: rose: fix timer races against user threads
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21719
+    - ipmr: do not call mr_mfc_uses_dev() for unres entries
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21802
+    - net: hns3: fix oops when unload drivers paralleling
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58058
+    - ubifs: skip dumping tnc tree when zroot is null
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58069
+    - rtc: pcf85063: fix potential OOB write in PCF85063 NVMEM read
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21720
+    - xfrm: delete intermediate secpath entry in packet offload mode
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21803
+    - LoongArch: Fix warnings during S3 suspend
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21810
+    - driver core: class: Fix wild pointer dereferences in API
+      class_dev_iter_next()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21811
+    - nilfs2: protect access to buffers with no active references
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21804
+    - PCI: rcar-ep: Fix incorrect variable used when calling
+      devm_request_mem_region()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21829
+    - RDMA/rxe: Fix the warning "__rxe_cleanup+0x12c/0x170 [rdma_rxe]"
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57984
+    - i3c: dw: Fix use-after-free in dw_i3c_master driver due to race
+      condition
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58034
+    - memory: tegra20-emc: fix an OF node reference bug in
+      tegra_emc_find_node_by_ram_code()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57973
+    - rdma/cxgb4: Prevent potential integer overflow on 32bit
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21725
+    - smb: client: fix oops due to unset link speed
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21726
+    - padata: avoid UAF for reorder_work
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21727
+    - padata: fix UAF in padata_reorder
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21728
+    - bpf: Send signals asynchronously if !preemptible
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58070
+    - bpf: bpf_local_storage: Always use bpf_mem_alloc in PREEMPT_RT
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21711
+    - net/rose: prevent integer overflows in rose_setsockopt()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21799
+    - net: ethernet: ti: am65-cpsw: fix freeing IRQ in
+      am65_cpsw_nuss_remove_tx_chns()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21806
+    - net: let net.core.dev_weight always be non-zero
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21830
+    - landlock: Handle weird files
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21828
+    - wifi: mac80211: don't flush non-uploaded STAs
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58061
+    - wifi: mac80211: prohibit deactivating all links
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57993
+    - HID: hid-thrustmaster: Fix warning in thrustmaster_probe by adding
+      endpoint check
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21812
+    - ax25: rcu protect dev->ax25_ptr
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58071
+    - team: prevent adding a device which is already a team device lower
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58063
+    - wifi: rtlwifi: fix memory leaks and invalid access at probe error path
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58072
+    - wifi: rtlwifi: remove unused check_buddy_priv
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58053
+    - rxrpc: Fix handling of received connection abort
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57996
+    - net_sched: sch_sfq: don't allow 1 packet limit
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57997
+    - wifi: wcn36xx: fix channel survey memory allocation size
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58051
+    - ipmi: ipmb: Add check devm_kasprintf() returned value
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58068
+    - OPP: fix dev_pm_opp_find_bw_*() when bandwidth table not initialized
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57998
+    - OPP: add index check to assert to avoid buffer overflow in _read_freq()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58052
+    - drm/amdgpu: Fix potential NULL pointer dereference in
+      atomctrl_get_smc_sclk_range_table
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57986
+    - HID: core: Fix assumption that Resolution Multipliers must be in Logical
+      Collections
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21731
+    - nbd: don't allow reconnect after disconnect
+  * CVE-2025-37798
+    - sch_htb: make htb_qlen_notify() idempotent
+    - sch_htb: make htb_deactivate() idempotent
+    - sch_drr: make drr_qlen_notify() idempotent
+    - sch_hfsc: make hfsc_qlen_notify() idempotent
+    - sch_qfq: make qfq_qlen_notify() idempotent
+    - sch_ets: make est_qlen_notify() idempotent
+    - codel: remove sch->q.qlen check before qdisc_tree_reduce_backlog()
+  * CVE-2025-37997
+    - netfilter: ipset: fix region locking in hash types
+  * CVE-2025-22088
+    - RDMA/erdma: Prevent use-after-free in erdma_accept_newconn()
+  * CVE-2025-37890
+    - net_sched: hfsc: Fix a UAF vulnerability in class with netem as child
+      qdisc
+    - sch_hfsc: Fix qlen accounting bug when using peek in hfsc_enqueue()
+    - net_sched: hfsc: Address reentrant enqueue adding class to eltree twice
+  * raid1: Fix NULL pointer dereference in process_checks() (LP: #2112519)
+    - md/raid1: Add check for missing source disk in process_checks()
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - [Packaging] update annotations scripts
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 23 Jul 2025 18:48:06 +0900
+
+linux-qcom (6.8.0-1050.50) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1050.50 -proposed tracker (LP: #2116573)
+
+  * Incorrect graphics dtbo file used in case of qcs5430-fp(2p5|3)-addons-
+    rb3gen2-vision-mezz-ovl.dtb
+    - SAUCE: fix graphics DTBO for qcs5430-{fp2p5,fp3}-addons-rb3gen2-vision-
+      mezz
+
+  * [linux-libc-dev-qcom] Requires smcinvoke.h for securemsm build
+    - SAUCE: include linux/smcinvoke.h in linux-libc-dev-qcom package
+
+  * [QC] Kernel crash from libgbm - followup
+    - QCLINUX: iommu/arm-smmu: qcom: Fix arm_smmu_domain usage in fault
+      handler
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 11 Jul 2025 20:30:43 +0900
+
+linux-qcom (6.8.0-1049.49) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1049.49 -proposed tracker (LP: #2116298)
+
+  * [RB3] miscellanea/check_prerelease test failed
+    - [Packaging] remove uefi_signed=true
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 10 Jul 2025 10:20:07 +0900
+
+linux-qcom (6.8.0-1048.48) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1048.48 -proposed tracker (LP: #2116048)
+
+  * [RB3] [x04] deadlock in cam_mem_mgr_cleanup_table
+    - SAUCE: camera_kt: fix double locking in cleanup function
+
+  * CONFIG_MMAP_MIN_ADDR should 32768
+    - UBUNTU [Config] set CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 07 Jul 2025 17:39:47 +0900
+
+linux-qcom (6.8.0-1047.47) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1047.47 -proposed tracker (LP: #2115413)
+
+  * [RB3] ucsi_glink.pmic_glink_ucsi pmic_glink.ucsi.0: PPM init failed, stop
+    trying
+    - SAUCE: usb: dwc3: make sure reset is deasserted before enabling clocks
+
+  * [RB8][x03] qcom-sa8775p-lpass-lpi-pinctrl errors found in dmesg
+    - QCLINUX: arm64: dts: qcom: update lpi-quad pin functions for qcs9075-rb8
+
+  * [qcom] Qcom kernel crashes in virtual machine
+    - SAUCE: gunyah_qcom: check qcom,msm-id property before HW access
+
+  * [5430][x03] SoC id not known by qcom/socinfo.c kernel driver Edit
+    - QCLINUX: soc: qcom: socinfo: add QCS5430 SoC ID
+    - QCLINUX: dt-bindings: arm: qcom,ids: add SoC ID for QCS5430
+
+  * [RB3] Enable sound-dais in our kernel for ALSA
+    - ASoC: qcom: topology: validate the max_op_port value
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 26 Jun 2025 21:07:26 +0900
+
+linux-qcom (6.8.0-1046.46) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1046.46 -proposed tracker (LP: #2114979)
+
+  * [qcom] Qcom kernel crashes in virtual machine
+    - SAUCE: gunyah_qcom: check qcom,msm-id property before HW access
+
+  * [RB3] Plugged USB storage is not detected via type-c port after reboot
+    occasionally
+    - soc: qcom: pmic_glink: Fix possible race between rpmsg and pmicglink
+      probe
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 19 Jun 2025 22:04:02 +0900
+
+linux-qcom (6.8.0-1045.45) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1045.45 -proposed tracker (LP: #2114901)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update Ubuntu.md
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Config] add FLAVOUR_DEP
+    - [package] fix Vcs-Git
+    - SAUCE: arm64: dts: qcm6490: enable platform sound-dai
+    - SAUCE: ASoC: q6dsp: increase AR_MAX_MOD_LINKS
+    - SAUCE: arm64: dts: qcom fix interrupts arguments
+    - SAUCE: usb: dwc3: do not call dwc3_remove() when dwc3_qcom_probe_core()
+      fails
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 18 Jun 2025 23:42:59 +0900
+
+linux-qcom (6.8.0-1043.43) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1043.43 -proposed tracker (LP: #2112456)
+
+  * [5430] thermal_sys failed to bind errors found in dmesg
+    - SAUCE: comment out invalid cooling-maps
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs
+
+  [ Ubuntu: 6.8.0-62.65 ]
+
+  * noble/linux: 6.8.0-62.65 -proposed tracker (LP: #2110737)
+  * Rotate the Canonical Livepatch key (LP: #2111244)
+    - [Config] Prepare for Canonical Livepatch key rotation
+  * KVM bug causes Firecracker crash when it runs the vCPU for the first time
+    (LP: #2109859)
+    - vhost: return task creation error instead of NULL
+    - kvm: retry nx_huge_page_recovery_thread creation
+  * CVE-2025-2312 cifs.upcall could access incorrect kerberos credentials cache
+    (LP: #2099914) // CVE-2025-2312
+    - CIFS: New mount option for cifs.upcall namespace resolution
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640)
+    - ASoC: wm8994: Add depends on MFD core
+    - ASoC: samsung: Add missing selects for MFD_WM8994
+    - seccomp: Stub for !CONFIG_SECCOMP
+    - scsi: iscsi: Fix redundant response for ISCSI_UEVENT_GET_HOST_STATS request
+    - of/unittest: Add test that of_address_to_resource() fails on non-
+      translatable address
+    - irqchip/sunxi-nmi: Add missing SKIP_WAKE flag
+    - hwmon: (drivetemp) Set scsi command timeout to 10s
+    - ASoC: samsung: Add missing depends on I2C
+    - ata: libata-core: Set ATA_QCFLAG_RTF_FILLED in fill_result_tf()
+    - Revert "libfs: fix infinite directory reads for offset dir"
+    - libfs: Replace simple_offset end-of-directory detection
+    - Revert "HID: multitouch: Add support for lenovo Y9000P Touchpad"
+    - ALSA: usb-audio: Add delay quirk for USB Audio Device
+    - Input: xpad - add support for Nacon Pro Compact
+    - Input: atkbd - map F23 key to support default copilot shortcut
+    - Input: xpad - add unofficial Xbox 360 wireless receiver clone
+    - Input: xpad - add QH Electronics VID/PID
+    - Input: xpad - improve name of 8BitDo controller 2dc8:3106
+    - Input: xpad - add support for Nacon Evol-X Xbox One Controller
+    - Input: xpad - add support for wooting two he (arm)
+    - ASoC: codecs: es8316: Fix HW rate calculation for 48Mhz MCLK
+    - ASoC: cs42l43: Add codec force suspend/resume ops
+    - ALSA: hda/realtek: Fix volume adjustment issue on Lenovo ThinkBook 16P Gen5
+    - libfs: Return ENOSPC when the directory offset range is exhausted
+    - Revert "libfs: Add simple_offset_empty()"
+    - libfs: Use d_children list to iterate simple_offset directories
+    - wifi: rtl8xxxu: add more missing rtl8192cu USB IDs
+    - HID: wacom: Initialize brightness of LED trigger
+    - Upstream stable to v6.6.75, v6.12.12
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21689
+    - USB: serial: quatech2: fix null-ptr-deref in qt2_process_read_urb()
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21690
+    - scsi: storvsc: Ratelimit warning logs to prevent VM denial of service
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21691
+    - cachestat: fix page cache statistics permission checking
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21692
+    - net: sched: fix ets qdisc OOB Indexing
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21699
+    - gfs2: Truncate address space when flipping GFS2_DIF_JDATA flag
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2024-50157
+    - RDMA/bnxt_re: Avoid CPU lockups due fifo occupancy check loop
+  * rtw89: Support hardware rfkill (LP: #2077384)
+    - wifi: rtw89: add support for hardware rfkill
+  * Introduce configfs-based interface for gpio-aggregator (LP: #2103496)
+    - gpio: introduce utilities for synchronous fake device creation
+    - bitmap: Define a cleanup function for bitmaps
+    - gpio: aggregator: simplify aggr_parse() with scoped bitmap
+    - gpio: aggregator: protect driver attr handlers against module unload
+    - gpio: aggregator: reorder functions to prepare for configfs introduction
+    - gpio: aggregator: unify function naming
+    - gpio: aggregator: add gpio_aggregator_{alloc, free}()
+    - gpio: aggregator: introduce basic configfs interface
+    - [Config] Enable DEV_SYNC_PROBE as module
+    - SAUCE: gpio: aggregator: Fix error code in gpio_aggregator_activate()
+    - gpio: aggregator: rename 'name' to 'key' in gpio_aggregator_parse()
+    - gpio: aggregator: expose aggregator created via legacy sysfs to configfs
+    - SAUCE: gpio: aggregator: fix "_sysfs" prefix check in
+      gpio_aggregator_make_group()
+    - SAUCE: gpio: aggregator: Fix gpio_aggregator_line_alloc() checking
+    - SAUCE: gpio: aggregator: Return an error if there are no GPIOs in
+      gpio_aggregator_parse()
+    - SAUCE: gpio: aggregator: Fix leak in gpio_aggregator_parse()
+    - gpio: aggregator: cancel deferred probe for devices created via configfs
+    - Documentation: gpio: document configfs interface for gpio-aggregator
+    - selftests: gpio: add test cases for gpio-aggregator
+    - SAUCE: selftests: gpio: gpio-aggregator: add a test case for _sysfs prefix
+      reservation
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449)
+    - net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()
+    - net: add exit_batch_rtnl() method
+    - gtp: use exit_batch_rtnl() method
+    - gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp().
+    - gtp: Suppress list corruption splat in gtp_net_exit_batch_rtnl().
+    - nfp: bpf: prevent integer overflow in nfp_bpf_event_output()
+    - net: xilinx: axienet: Fix IRQ coalescing packet count overflow
+    - net/mlx5: Fix RDMA TX steering prio
+    - net/mlx5e: Rely on reqid in IPsec tunnel mode
+    - net/mlx5e: Always start IPsec sequence number from 1
+    - drm/vmwgfx: Add new keep_resv BO param
+    - drm/v3d: Assign job pointer to NULL before signaling the fence
+    - soc: ti: pruss: Fix pruss APIs
+    - hwmon: (tmp513) Fix division of negative numbers
+    - i2c: mux: demux-pinctrl: check initial mux selection, too
+    - i2c: rcar: fix NACK handling when being a target
+    - hfs: Sanity check the root record
+    - fs: fix missing declaration of init_files
+    - kheaders: Ignore silly-rename files
+    - cachefiles: Parse the "secctx" immediately
+    - scsi: ufs: core: Honor runtime/system PM levels if set by host controller
+      drivers
+    - selftests: tc-testing: reduce rshift value
+    - ACPI: resource: acpi_dev_irq_override(): Check DMI match last
+    - poll_wait: add mb() to fix theoretical race between waitqueue_active() and
+      .poll()
+    - RDMA/bnxt_re: Fix to export port num to ib_query_qp
+    - nvmet: propagate npwg topology
+    - ALSA: hda/realtek: Add support for Ayaneo System using CS35L41 HDA
+    - i2c: atr: Fix client detach
+    - mptcp: be sure to send ack when mptcp-level window re-opens
+    - mptcp: fix spurious wake-up on under memory pressure
+    - selftests: mptcp: avoid spurious errors on disconnect
+    - net: ethernet: xgbe: re-add aneg to supported features in PHY quirks
+    - vsock/virtio: cancel close work in the destructor
+    - vsock: reset socket state when de-assigning the transport
+    - nouveau/fence: handle cross device fences properly
+    - irqchip: Plug a OF node reference leak in platform_irqchip_probe()
+    - irqchip/gic-v3: Handle CPU_PM_ENTER_FAILED correctly
+    - drm/i915/fb: Relax clear color alignment to 64 bytes
+    - drm/amdgpu: always sync the GFX pipe on ctx switch
+    - ocfs2: fix deadlock in ocfs2_get_system_file_inode
+    - nfsd: add list_head nf_gc to struct nfsd_file
+    - x86/xen: fix SLS mitigation in xen_hypercall_iret()
+    - efi/zboot: Limit compression options to GZIP and ZSTD
+    - [Config] updateconfigs for HAVE_KERNEL_(LZ4|LZMA|LZO|XZ)
+    - net: ravb: Fix max TX frame size for RZ/V2M
+    - net/mlx5: SF, Fix add port error handling
+    - drm/vmwgfx: Unreserve BO on error
+    - i2c: testunit: on errors, repeat NACK until STOP
+    - hwmon: (ltc2991) Fix mixed signed/unsigned in DIV_ROUND_CLOSEST
+    - fs/qnx6: Fix building with GCC 15
+    - gpio: sim: lock up configfs that an instantiated device depends on
+    - gpio: sim: lock hog configfs items if present
+    - platform/x86: ISST: Add Clearwater Forest to support list
+    - drm/nouveau/disp: Fix missing backlight control on Macbook 5,1
+    - net/ncsi: fix locking in Get MAC Address handling
+    - drm/amd/display: Do not elevate mem_type change to full update
+    - drm/xe: Mark ComputeCS read mode as UC on iGPU
+    - drm/amdgpu/smu13: update powersave optimizations
+    - drm/amdgpu: fix fw attestation for MP0_14_0_{2/3}
+    - drm/amdgpu: disable gfxoff with the compute workload on gfx12
+    - drm/amd/display: Fix PSR-SU not support but still call the
+      amdgpu_dm_psr_enable
+    - Upstream stable to v6.6.73, v6.6.74, v6.12.11
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21672
+    - afs: Fix merge preference rule failure condition
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21682
+    - eth: bnxt: always recalculate features after XDP clearing, fix null-deref
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-53124
+    - net: fix data-races around sk->sk_forward_alloc
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-57924
+    - fs: relax assertions on failure to encode file handles
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-57951
+    - hrtimers: Handle CPU state correctly on hotplug
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-57949
+    - irqchip/gic-v3-its: Don't enable interrupts in its_irq_set_vcpu_affinity()
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21668
+    - pmdomain: imx8mp-blk-ctrl: add missing loop break condition
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21684
+    - gpio: xilinx: Convert gpio_lock to raw spinlock
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21694
+    - fs/proc: fix softlockup in __read_vmcore (part 2)
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21665
+    - filemap: avoid truncating 64-bit offset to 32 bits
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21666
+    - vsock: prevent null-ptr-deref in vsock_*[has_data|has_space]
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21669
+    - vsock/virtio: discard packets if the transport changes
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21670
+    - vsock/bpf: return early if transport is not assigned
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21667
+    - iomap: avoid avoid truncating 64-bit offset to 32 bits
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-57948
+    - mac802154: check local interfaces before deleting sdata list
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21673
+    - smb: client: fix double free of TCP_Server_Info::hostname
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21697
+    - drm/v3d: Ensure job pointer is set to NULL after job completion
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21674
+    - net/mlx5e: Fix inversion dependency warning while enabling IPsec tunnel
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21675
+    - net/mlx5: Clear port select structure when fail to create
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21676
+    - net: fec: handle page_pool_dev_alloc_pages error
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21678
+    - gtp: Destroy device along with udp socket's netns dismantle.
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21680
+    - pktgen: Avoid out-of-bounds access in get_imix_entries
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21681
+    - openvswitch: fix lockup on tx to unregistering netdev with carrier
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21683
+    - bpf: Fix bpf_sk_select_reuseport() memory leak
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update annotations scripts
+
+  [ Ubuntu: 6.8.0-60.63 ]
+
+  * noble/linux: 6.8.0-60.63 -proposed tracker (LP: #2107138)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2025.04.14)
+  * Missing upstream commits for LP: #2102181 (LP: #2107336)
+    - libperf cpumap: Add any, empty and min helpers
+    - libperf cpumap: Ensure empty cpumap is NULL from alloc
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770)
+    - memblock: use numa_valid_node() helper to check for invalid node ID
+    - jbd2: increase IO priority for writing revoke records
+    - jbd2: flush filesystem device before updating tail sequence
+    - dm array: fix unreleased btree blocks on closing a faulty array cursor
+    - dm array: fix cursor index when skipping across block boundaries
+    - exfat: fix the infinite loop in __exfat_free_cluster()
+    - erofs: fix PSI memstall accounting
+    - ASoC: rt722: add delay time to wait for the calibration procedure
+    - ASoC: mediatek: disable buffer pre-allocation
+    - selftests/alsa: Fix circular dependency involving global-timer
+    - ieee802154: ca8210: Add missing check for kfifo_alloc() in ca8210_probe()
+    - net: 802: LLC+SNAP OID:PID lookup on start of skb data
+    - tcp/dccp: complete lockless accesses to sk->sk_max_ack_backlog
+    - tcp/dccp: allow a connection when sk_max_ack_backlog is zero
+    - net: libwx: fix firmware mailbox abnormal return
+    - pds_core: limit loop over fw name list
+    - bnxt_en: Fix possible memory leak when hwrm_req_replace fails
+    - cxgb4: Avoid removal of uninserted tid
+    - ice: fix incorrect PHY settings for 100 GB/s
+    - igc: return early when failing to read EECD register
+    - tls: Fix tls_sw_sendmsg error handling
+    - eth: gve: use appropriate helper to set xdp_features
+    - Bluetooth: hci_sync: Fix not setting Random Address when required
+    - Bluetooth: MGMT: Fix Add Device to responding before completing
+    - Bluetooth: btnxpuart: Fix driver sending truncated data
+    - tcp: Annotate data-race around sk->sk_mark in tcp_v4_send_reset
+    - riscv: Fix early ftrace nop patching
+    - memblock tests: fix implicit declaration of function 'numa_valid_node'
+    - iio: imu: inv_icm42600: fix timestamps after suspend if sensor is on
+    - netfilter: nf_tables: imbalance in flowtable binding
+    - drm/mediatek: stop selecting foreign drivers
+    - [Config] updateconfigs for MTK_SMI
+    - drm/mediatek: Fix YCbCr422 color format issue for DP
+    - drm/mediatek: Fix mode valid issue for dp
+    - drm/mediatek: Add return value check when reading DPCD
+    - cpuidle: riscv-sbi: fix device node release in early exit of
+      for_each_possible_cpu
+    - scsi: ufs: qcom: Power off the PHY if it was already powered on in
+      ufs_qcom_power_up_sequence()
+    - dm-ebs: don't set the flag DM_TARGET_PASSES_INTEGRITY
+    - ksmbd: Implement new SMB3 POSIX type
+    - thermal: of: fix OF node leak in of_thermal_zone_find()
+    - smb: client: sync the root session and superblock context passwords before
+      automounting
+    - ACPI: resource: Add TongFang GM5HG0A to irq1_edge_low_force_override[]
+    - ACPI: resource: Add Asus Vivobook X1504VAP to irq1_level_low_skip_override[]
+    - drm/amd/display: increase MAX_SURFACES to the value supported by hw
+    - io_uring/timeout: fix multishot updates
+    - dm-verity FEC: Fix RS FEC repair for roots unaligned to block size (take 2)
+    - USB: serial: option: add MeiG Smart SRM815
+    - USB: serial: option: add Neoway N723-EA support
+    - staging: iio: ad9834: Correct phase range check
+    - staging: iio: ad9832: Correct phase range check
+    - usb-storage: Add max sectors quirk for Nokia 208
+    - USB: serial: cp210x: add Phoenix Contact UPS Device
+    - usb: dwc3: gadget: fix writing NYET threshold
+    - misc: microchip: pci1xxxx: Resolve return code mismatch during GPIO set
+      config
+    - tty: serial: 8250: Fix another runtime PM usage counter underflow
+    - usb: dwc3-am62: Disable autosuspend during remove
+    - USB: usblp: return error when setting unsupported protocol
+    - USB: core: Disable LPM only for non-suspended ports
+    - usb: fix reference leak in usb_new_device()
+    - usb: gadget: midi2: Reverse-select at the right place
+    - usb: chipidea: ci_hdrc_imx: decrement device's refcount in .remove() and in
+      the error path of .probe()
+    - usb: gadget: f_uac2: Fix incorrect setting of bNumEndpoints
+    - usb: typec: tcpm/tcpci_maxim: fix error code in
+      max_contaminant_read_resistance_kohm()
+    - usb: gadget: configfs: Ignore trailing LF for user strings to cdev
+    - iio: gyro: fxas21002c: Fix missing data update in trigger handler
+    - iio: adc: ti-ads124s08: Use gpiod_set_value_cansleep()
+    - iio: inkern: call iio_device_put() only on mapped devices
+    - iio: adc: ad7124: Disable all channels at probe time
+    - riscv: kprobes: Fix incorrect address calculation
+    - ARM: dts: imxrt1050: Fix clocks for mmc
+    - arm64: dts: rockchip: add hevc power domain clock to rk3328
+    - pmdomain: imx: gpcv2: Simplify with scoped for each OF child loop
+    - pmdomain: imx: gpcv2: fix an OF node reference leak in imx_gpcv2_probe()
+    - workqueue: Add rcu lock check at the end of work item execution
+    - workqueue: Update lock debugging code
+    - mm/hugetlb: enforce that PMD PT sharing has split PMD PT locks
+    - riscv: Fix text patching when IPI are used
+    - drm/mediatek: Only touch DISP_REG_OVL_PITCH_MSB if AFBC is supported
+    - ovl: pass realinode to ovl_encode_real_fh() instead of realdentry
+    - net: don't dump Tx and uninitialized NAPIs
+    - ice: fix max values for dpll pin phase adjust
+    - net: hns3: fixed reset failure issues caused by the incorrect reset type
+    - net: hns3: fix missing features due to dev->features configuration too early
+    - net: hns3: Resolved the issue that the debugfs query result is inconsistent.
+    - net: hns3: initialize reset_timer before hclgevf_misc_irq_init()
+    - mctp i3c: fix MCTP I3C driver multi-thread issue
+    - drm/mediatek: Move mtk_crtc_finish_page_flip() to ddp_cmdq_cb()
+    - drm/mediatek: Add support for 180-degree rotation in the display driver
+    - drm/mediatek: mtk_dsi: Add registers to pdata to fix MT8186/MT8188
+    - platform/x86: intel/pmc: Fix ioremap() of bad address
+    - riscv: module: remove relocation_head rel_entry member allocation
+    - cgroup/cpuset: Prevent leakage of isolated CPUs into sched domains
+    - fs: kill MNT_ONRB
+    - gpio: loongson: Fix Loongson-2K2000 ACPI GPIO register offset
+    - drm/amd/pm: fix BUG: scheduling while atomic
+    - drm/amdkfd: wq_release signals dma_fence only when available
+    - drm/amd/display: fix divide error in DM plane scale calcs
+    - drm/amd/display: fix page fault due to max surface definition mismatch
+    - serial: stm32: use port lock wrappers for break control
+    - usb: host: xhci-plat: set skip_phy_initialization if software node has
+      XHCI_SKIP_PHY_INIT property
+    - iio: imu: inv_icm42600: add register caching in the regmap
+    - iio: imu: inv_icm42600: fix spi burst write not supported
+    - Upstream stable to v6.6.71, v6.6.72, v6.12.10
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21659
+    - netdev: prevent accessing NAPI instances from another namespace
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21634
+    - cgroup/cpuset: remove kernfs active break
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21635
+    - rds: sysctl: rds_tcp_{rcv,snd}buf: avoid using current->nsproxy
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21643
+    - netfs: Fix kernel async DIO
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21649
+    - net: hns3: fix kernel crash when 1588 is sent on HIP08 devices
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21650
+    - net: hns3: fixed hclge_fetch_pf_reg accesses bar space out of bounds issue
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21651
+    - net: hns3: don't auto enable misc vector
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21654
+    - ovl: support encoding fid from inode with no alias
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57883
+    - mm: hugetlb: independent PMD page table shared count
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57888
+    - workqueue: Do not warn when cancelling WQ_MEM_RECLAIM work from
+      !WQ_MEM_RECLAIM worker
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21631
+    - block, bfq: fix waker_bfqq UAF after bfq_split_bfqq()
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21656
+    - hwmon: (drivetemp) Fix driver producing garbage data when SCSI errors occur
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21655
+    - io_uring/eventfd: ensure io_eventfd_signal() defers another RCU period
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57904
+    - iio: adc: at91: call input_free_device() on allocated iio_dev
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57906
+    - iio: adc: ti-ads8688: fix information leak in triggered buffer
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57907
+    - iio: adc: rockchip_saradc: fix information leak in triggered buffer
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57908
+    - iio: imu: kmx61: fix information leak in triggered buffer
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57910
+    - iio: light: vcnl4035: fix information leak in triggered buffer
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57911
+    - iio: dummy: iio_simply_dummy_buffer: fix information leak in triggered
+      buffer
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57912
+    - iio: pressure: zpa2326: fix information leak in triggered buffer
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57913
+    - usb: gadget: f_fs: Remove WARN_ON in functionfs_bind
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21632
+    - x86/fpu: Ensure shadow stack is active before "getting" registers
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57916
+    - misc: microchip: pci1xxxx: Resolve kernel panic during GPIO IRQ handling
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57917
+    - topology: Keep the cpumask unchanged when printing cpumap
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57939
+    - riscv: Fix sleeping in invalid context in die()
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21636
+    - sctp: sysctl: plpmtud_probe_interval: avoid using current->nsproxy
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21637
+    - sctp: sysctl: udp_port: avoid using current->nsproxy
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21638
+    - sctp: sysctl: auth_enable: avoid using current->nsproxy
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21639
+    - sctp: sysctl: rto_min/max: avoid using current->nsproxy
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21640
+    - sctp: sysctl: cookie_hmac_alg: avoid using current->nsproxy
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21642
+    - mptcp: sysctl: sched: avoid using current->nsproxy
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21664
+    - dm thin: make get_first_thin use rcu-safe list first function
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57945
+    - riscv: mm: Fix the out of bound issue of vmemmap address
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21660
+    - ksmbd: fix unexpectedly changed path in ksmbd_vfs_kern_path_locked
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21645
+    - platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled
+      it
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21646
+    - afs: Fix the maximum cell name length
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57925
+    - ksmbd: fix a missing return value check bug
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57926
+    - drm/mediatek: Set private->all_drm_private[i]->drm to NULL if mtk_drm_bind
+      returns err
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21662
+    - net/mlx5: Fix variable not being completed when function returns
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21663
+    - net: stmmac: dwmac-tegra: Read iommu stream id from device tree
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21647
+    - sched: sch_cake: add bounds checks to host bulk flow fairness counts
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21648
+    - netfilter: conntrack: clamp maximum hashtable size to INT_MAX
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21652
+    - ipvlan: Fix use-after-free in ipvlan_get_iflink().
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21658
+    - btrfs: avoid NULL pointer dereference if no valid extent tree
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21653
+    - net_sched: cls_flow: validate TCA_FLOW_RSHIFT attribute
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-47736
+    - erofs: handle overlapped pclusters out of crafted images properly
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57940
+    - exfat: fix the infinite loop in exfat_readdir()
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57929
+    - dm array: fix releasing a faulty array block twice in dm_array_cursor_end
+  * intel_idle: add Granite Rapids Xeon (D) support (LP: #2106638)
+    - intel_idle: add Granite Rapids Xeon support
+    - intel_idle: add Granite Rapids Xeon D support
+  * [SRU] Enable speaker/mic mute LEDs on Lenovo ideapad and thinkbook
+    (LP: #2106449)
+    - ALSA: hda: Support for Ideapad hotkey mute LEDs
+    - platform/x86:lenovo-wmi-hotkey-utilities.c: Support for mic and audio mute
+      LEDs
+    - [Config] Enable Lenovo wmi hotkey driver
+  * Backport "PCI: Wait for device readiness with Configuration RRS" to N/O
+    (LP: #2106251)
+    - PCI: Wait for device readiness with Configuration RRS
+    - PCI: Avoid FLR for Mediatek MT7922 WiFi
+  * Enable OOB P-state control for Intel Sierra Forest/Granite Rapids
+    (LP: #2106275)
+    - cpufreq: intel_pstate: Support Granite Rapids and Sierra Forest OOB mode
+  * mptcp BUG 'scheduling while atomic' in mptcp_pm_nl_append_new_local_addr
+    (LP: #2101120)
+    - mptcp: fix 'scheduling while atomic' in mptcp_pm_nl_append_new_local_addr
+  * CVE-2025-21971
+    - net_sched: Prevent creation of classes with TC_H_ROOT
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632)
+    - smb/client: rename cifs_ntsd to smb_ntsd
+    - smb/client: rename cifs_sid to smb_sid
+    - smb/client: rename cifs_acl to smb_acl
+    - smb/client: rename cifs_ace to smb_ace
+    - fs/smb/client: implement chmod() for SMB3 POSIX Extensions
+    - smb: client: stop flooding dmesg in smb2_calc_signature()
+    - media: uvcvideo: Force UVC version to 1.0a for 0408:4033
+    - Bluetooth: btusb: Add new VID/PID 13d3/3602 for MT7925
+    - watchdog: rzg2l_wdt: Remove reset de-assert from probe
+    - watchdog: rzg2l_wdt: Rely on the reset driver for doing proper reset
+    - watchdog: rzg2l_wdt: Power on the watchdog domain in the restart handler
+    - ALSA: ump: Use guard() for locking
+    - ALSA: ump: Don't open legacy substream for an inactive group
+    - scsi: mpi3mr: Use ida to manage mrioc ID
+    - scsi: mpi3mr: Start controller indexing from 0
+    - ACPI/IORT: Add PMCG platform information for HiSilicon HIP10/11
+    - ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A
+    - x86/ptrace: Cleanup the definition of the pt_regs structure
+    - x86/ptrace: Add FRED additional information to the pt_regs structure
+    - Bluetooth: btusb: add callback function in btusb suspend/resume
+    - Bluetooth: btusb: mediatek: add callback function in btusb_disconnect
+    - platform/x86: mlx-platform: call pci_dev_put() to balance the refcount
+    - mmc: sdhci-msm: fix crypto key eviction
+    - tracing: Handle old buffer mappings for event strings and functions
+    - tracing: Fix trace_check_vprintf() when tp_printk is used
+    - tracing: Check "%s" dereference via the field and not the TP_printk format
+    - RDMA/bnxt_re: Allow MSN table capability check
+    - RDMA/bnxt_re: Remove always true dattr validity check
+    - RDMA/mlx5: Enforce same type port association for multiport RoCE
+    - RDMA/bnxt_re: Avoid initializing the software queue for user queues
+    - RDMA/bnxt_re: Avoid sending the modify QP workaround for latest adapters
+    - nvme-pci: 512 byte aligned dma pool segment quirk
+    - RDMA/bnxt_re: Fix the check for 9060 condition
+    - RDMA/bnxt_re: Add check for path mtu in modify_qp
+    - RDMA/bnxt_re: Fix reporting hw_ver in query_device
+    - RDMA/bnxt_re: Fix max_qp_wrs reported
+    - RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters
+    - RDMA/bnxt_re: Disable use of reserved wqes
+    - RDMA/bnxt_re: Add send queue size check for variable wqe
+    - RDMA/bnxt_re: Fix MSN table size for variable wqe mode
+    - drm/bridge: adv7511_audio: Update Audio InfoFrame properly
+    - net: dsa: microchip: Fix KSZ9477 set_ageing_time function
+    - net: dsa: microchip: Fix LAN937X set_ageing_time function
+    - RDMA/hns: Refactor mtr find
+    - RDMA/hns: Remove unused parameters and variables
+    - RDMA/hns: Fix mapping error of zero-hop WQE buffer
+    - RDMA/hns: Fix warning storm caused by invalid input in IO path
+    - RDMA/hns: Fix missing flush CQE for DWQE
+    - ip_tunnel: annotate data-races around t->parms.link
+    - ipv4: ip_tunnel: Unmask upper DSCP bits in ip_tunnel_bind_dev()
+    - ipv4: ip_tunnel: Unmask upper DSCP bits in ip_md_tunnel_xmit()
+    - ipv4: ip_tunnel: Unmask upper DSCP bits in ip_tunnel_xmit()
+    - net: Fix netns for ip_tunnel_init_flow()
+    - net/mlx5: DR, select MSIX vector 0 for completion queue creation
+    - net/mlx5e: macsec: Maintain TX SA from encoding_sa
+    - drm/i915/dg1: Fix power gate sequence.
+    - net: llc: reset skb->transport_header
+    - ALSA: usb-audio: US16x08: Initialize array before use
+    - eth: bcmsysport: fix call balance of priv->clk handling routines
+    - net: mv643xx_eth: fix an OF node reference leak
+    - net: sfc: Correct key_len for efx_tc_ct_zone_ht_params
+    - net: wwan: iosm: Properly check for valid exec stage in ipc_mmio_init()
+    - net: ti: icssg-prueth: Fix clearing of IEP_CMP_CFG registers during iep_init
+    - wifi: mac80211: wake the queues in case of failure in resume
+    - ALSA: hda/ca0132: Use standard HD-audio quirk matching helpers
+    - ALSA: hda/realtek: Add new alc2xx-fixup-headset-mic model
+    - sound: usb: enable DSD output for ddHiFi TC44C
+    - sound: usb: format: don't warn that raw DSD is unsupported
+    - bpf: fix potential error return
+    - ksmbd: retry iterate_dir in smb2_query_dir
+    - smb: client: destroy cfid_put_wq on module exit
+    - net: usb: qmi_wwan: add Telit FE910C04 compositions
+    - irqchip/gic: Correct declaration of *percpu_base pointer in union gic_base
+    - ARC: build: Try to guess GCC variant of cross compiler
+    - RDMA/bnxt_re: Fix the max WQE size for static WQE support
+    - modpost: fix input MODULE_DEVICE_TABLE() built for 64-bit on 32-bit host
+    - modpost: fix the missed iteration for the max bit in do_input()
+    - ALSA: seq: Check UMP support for midi_version change
+    - ALSA hda/realtek: Add quirk for Framework F111:000C
+    - kcov: mark in_softirq_really() as __always_inline
+    - scripts/sorttable: fix orc_sort_cmp() to maintain symmetry and transitivity
+    - sky2: Add device ID 11ab:4373 for Marvell 88E8075
+    - drm: adv7511: Drop dsi single lane support
+    - dt-bindings: display: adi,adv7533: Drop single lane support
+    - fs/proc/task_mmu: fix pagemap flags with PMD THP entries on 32bit
+    - mm/readahead: fix large folio support in async readahead
+    - mptcp: fix recvbuffer adjust on sleeping rcvmsg
+    - mptcp: don't always assume copied data in mptcp_cleanup_rbuf()
+    - RDMA/bnxt_re: Fix max SGEs for the Work Request
+    - scsi: hisi_sas: Remove redundant checks for automatic debugfs dump
+    - platform/x86: hp-wmi: Add thermal profile support for 8BAD boards
+    - platform/x86: hp-wmi: Fix platform profile option switch bug on Omen and
+      Victus laptops
+    - platform/x86: hp-wmi: Fix implementation of the platform_profile_omen_get
+      function
+    - platform/x86: hp-wmi: mark 8A15 board for timed OMEN thermal profile
+    - RDMA/core: Fix ENODEV error for iWARP test over vlan
+    - net: phy: micrel: Dynamically control external clock of KSZ PHY
+    - netdev-genl: avoid empty messages in napi get
+    - net: stmmac: restructure the error path of stmmac_probe_config_dt()
+    - net/mlx5e: Fix netif state handling
+    - net/mlx5e: Keep netdev when leave switchdev for devlink set legacy only
+    - drm/i915/cx0_phy: Fix C10 pll programming sequence
+    - RDMA/bnxt_re: Fix error recovery sequence
+    - btrfs: allow swap activation to be interruptible
+    - perf/x86/intel: Add Arrow Lake U support
+    - ALSA: hda: cs35l56: Remove calls to
+      cs35l56_force_sync_asp1_registers_from_cache()
+    - ALSA: hda/realtek - Add support for ASUS Zen AIO 27 Z272SD_A272SD audio
+    - spi: spi-cadence-qspi: Disable STIG mode for Altera SoCFPGA.
+    - ARC: build: disallow invalid PAE40 + 4K page config
+    - bpf: refactor bpf_helper_changes_pkt_data to use helper number
+    - bpf: consider that tail calls invalidate packet pointers
+    - maple_tree: reload mas before the second call for mas_empty_area
+    - io_uring/rw: fix downgraded mshot read
+    - wifi: iwlwifi: mvm: Fix __counted_by usage in cfg80211_wowlan_nd_*
+    - net: ethernet: ti: am65-cpsw: default to round-robin for host port receive
+    - gve: process XSK TX descriptors as part of RX NAPI
+    - gve: trigger RX NAPI instead of TX NAPI in gve_xsk_wakeup
+    - mm: reinstate ability to map write-sealed memfd mappings read-only
+    - Upstream stable to v6.6.70, v6.12.9
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57898
+    - wifi: cfg80211: clear link ID from bitmap during link delete after clean up
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57882
+    - mptcp: fix TCP options overflow.
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57884
+    - mm: vmscan: account for free pages to prevent infinite Loop in
+      throttle_direct_reclaim()
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57885
+    - mm/kmemleak: fix sleeping function called from invalid context at print
+      message
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57932
+    - gve: guard XDP xmit NDO on existence of xdp queues
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57933
+    - gve: guard XSK operations on the existence of queues
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57887
+    - drm: adv7511: Fix use-after-free in adv7533_attach_dsi()
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57938
+    - net/sctp: Prevent autoclose integer overflow in sctp_association_init()
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57889
+    - pinctrl: mcp23s08: Fix sleeping in atomic context due to regmap locking
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57890
+    - RDMA/uverbs: Prevent integer overflow issue
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57892
+    - ocfs2: fix slab-use-after-free due to dangling pointer dqi_priv
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57893
+    - ALSA: seq: oss: Fix races at processing SysEx messages
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57895
+    - ksmbd: set ATTR_CTIME flags when setting mtime
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57896
+    - btrfs: flush delalloc workers queue before stopping cleaner kthread during
+      unmount
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57897
+    - drm/amdkfd: Correct the migration DMA map direction
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57899
+    - wifi: mac80211: fix mbss changed flags corruption on 32 bit systems
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57900
+    - ila: serialize calls to nf_register_net_hooks()
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57901
+    - af_packet: fix vlan_get_protocol_dgram() vs MSG_PEEK
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57902
+    - af_packet: fix vlan_get_tci() vs MSG_PEEK
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57903
+    - net: restrict SO_REUSEPORT to inet sockets
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-36476
+    - RDMA/rtrs: Ensure 'ib_sge list' is accessible
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-39282
+    - net: wwan: t7xx: Fix FSM command timeout issue
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57801
+    - net/mlx5e: Skip restore TC rules for vport rep without loaded flag
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57802
+    - netrom: check buffer length before accessing it
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57841
+    - net: fix memory leak in tcp_conn_request()
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57931
+    - selinux: ignore unknown extended permissions
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-56761
+    - x86/fred: Clear WFE in missing-ENDBRANCH #CPs
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-53179
+    - smb: client: fix use-after-free of signing key
+  * uprobe-related panics during profiling (LP: #2104210)
+    - uprobes: Fix race in uprobe_free_utask
+  * ubuntu_bpf failed to build on Noble / Oracular (LP: #2069407)
+    - selftests/bpf: Fix compilation failure when CONFIG_NET_FOU!=y
+  * nfsd hangs and never recovers after NFS4ERR_DELAY and a connection loss
+    (LP: #2103564)
+    - NFSD: Reset cb_seq_status after NFS4ERR_DELAY
+  * thermal: Fix temperature readings on intel hardware (LP: #2103427)
+    - thermal: intel: intel_tcc: Add model checks for temperature registers
+    - thermal: intel: intel_tcc_cooling: Use a model-specific bitmask for TCC
+      offset
+    - hwmon: (coretemp) Extend the bitmask to read temperature to 0xff
+  * [SRU] Fix Lenovo M70/90 gen6 micmute key and led (LP: #2101811)
+    - ALSA: hda/realtek - add supported Mic Mute LED for Lenovo platform
+    - ALSA: hda: realtek: fix incorrect IS_REACHABLE() usage
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869)
+    - ceph: allocate sparse_ext map only for sparse reads
+    - mm/vmstat: fix a W=1 clang compiler warning
+    - tcp_bpf: Charge receive socket buffer in bpf_tcp_ingress()
+    - tcp_bpf: Add sk_rmem_alloc related logic for tcp_bpf ingress redirection
+    - bpf: Check negative offsets in __bpf_skb_min_len()
+    - mtd: diskonchip: Cast an operand to prevent potential overflow
+    - mtd: rawnand: arasan: Fix double assertion of chip-select
+    - mtd: rawnand: arasan: Fix missing de-registration of NAND
+    - phy: qcom-qmp: Fix register name in RX Lane config of SC8280XP
+    - phy: core: Fix an OF node refcount leakage in _of_phy_get()
+    - phy: core: Fix an OF node refcount leakage in of_phy_provider_lookup()
+    - phy: core: Fix that API devm_phy_put() fails to release the phy
+    - phy: core: Fix that API devm_of_phy_provider_unregister() fails to
+      unregister the phy provider
+    - phy: core: Fix that API devm_phy_destroy() fails to destroy the phy
+    - phy: usb: Toggle the PHY power during init
+    - phy: rockchip: naneng-combphy: fix phy reset
+    - dmaengine: mv_xor: fix child node refcount handling in early exit
+    - dmaengine: dw: Select only supported masters for ACPI devices
+    - dmaengine: tegra: Return correct DMA status when paused
+    - dmaengine: fsl-edma: implement the cleanup path of fsl_edma3_attach_pd()
+    - dmaengine: apple-admac: Avoid accessing registers in probe
+    - stddef: make __struct_group() UAPI C++-friendly
+    - tracing/kprobe: Make trace_kprobe's module callback called after jump_label
+      update
+    - watchdog: it87_wdt: add PWRGD enable quirk for Qotom QCML04
+    - watchdog: mediatek: Add support for MT6735 TOPRGU/WDT
+    - scsi: qla1280: Fix hw revision numbering for ISP1020/1040
+    - udf: Skip parent dir link count update if corrupted
+    - ALSA: hda/conexant: fix Z60MR100 startup pop issue
+    - ALSA: sh: Use standard helper for buffer accesses
+    - smb: server: Fix building with GCC 15
+    - regmap: Use correct format specifier for logging range errors
+    - LoongArch: Fix reserving screen info memory for above-4G firmware
+    - LoongArch: BPF: Adjust the parameter of emit_jirl()
+    - platform/x86: asus-nb-wmi: Ignore unknown event 0xCF
+    - spi: intel: Add Panther Lake SPI controller support
+    - scsi: mpt3sas: Diag-Reset when Doorbell-In-Use bit is set during driver load
+      time
+    - scsi: storvsc: Do not flag MAINTENANCE_IN return of SRB_STATUS_DATA_OVERRUN
+      as an error
+    - spi: omap2-mcspi: Fix the IS_ERR() bug for devm_clk_get_optional_enabled()
+    - blk-mq: register cpuhp callback after hctx is added to xarray table
+    - blk-mq: move cpuhp callback registering out of q->sysfs_lock
+    - MIPS: Probe toolchain support of -msym32
+    - MIPS: mipsregs: Set proper ISA level for virt extensions
+    - freezer, sched: Report frozen tasks as 'D' instead of 'R'
+    - tracing: Constify string literal data member in struct trace_event_call
+    - io_uring/sqpoll: fix sqpoll error handling races
+    - i2c: microchip-core: actually use repeated sends
+    - i2c: imx: add imx7d compatible string for applying erratum ERR007805
+    - i2c: microchip-core: fix "ghost" detections
+    - btrfs: sysfs: fix direct super block member reads
+    - ALSA: sh: Fix wrong argument order for copy_from_iter()
+    - block: avoid to reuse `hctx` not removed from cpuhp callback list
+    - fork: avoid inappropriate uprobe access to invalid mm
+    - ASoC: SOF: Intel: hda-dai: Do not release the link DMA on STOP
+    - power: supply: bq24190: Fix BQ24296 Vbus regulator support
+    - udf: Verify inode link counts before performing rename
+    - ALSA: ump: Indicate the inactive group in legacy substream names
+    - ALSA: ump: Update legacy substream names upon FB info update
+    - scsi: mpi3mr: Synchronize access to ioctl data buffer
+    - scsi: mpi3mr: Handling of fault code for insufficient power
+    - objtool: Add bch2_trans_unlocked_error() to bcachefs noreturns
+    - dmaengine: loongson2-apb: Change GENMASK to GENMASK_ULL
+    - perf/x86/intel/ds: Add PEBS format 6
+    - btrfs: add and use helper to verify the calling task has locked the inode
+    - btrfs: fix race with memory mapped writes when activating swap file
+    - btrfs: fix swap file activation failure due to extents that used to be
+      shared
+    - ALSA: ump: Shut up truncated string warning
+    - Upstream stable to v6.6.69, v6.12.8
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56758
+    - btrfs: check folio mapping after unlock in relocate_one_folio()
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56759
+    - btrfs: fix use-after-free when COWing tree bock and tracing is enabled
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57806
+    - btrfs: fix transaction atomicity bug when enabling simple quotas
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57793
+    - virt: tdx-guest: Just leak decrypted memory on unrecoverable errors
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56764
+    - ublk: detach gendisk from ublk device if add_disk() fails
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57804
+    - scsi: mpi3mr: Fix corrupt config pages PHY state is switched in sysfs
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57792
+    - power: supply: gpio-charger: Fix set charge current limits
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56760
+    - PCI/MSI: Handle lack of irqdomain gracefully
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56763
+    - tracing: Prevent bad count for tracing_cpumask_write
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57946
+    - virtio-blk: don't keep queue frozen during system suspend
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57807
+    - scsi: megaraid_sas: Fix for a potential deadlock
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56767
+    - dmaengine: at_xdmac: avoid null_prt_deref in at_xdmac_prep_dma_memset
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56769
+    - media: dvb-frontends: dib3000mb: fix uninit-value in dib3000_write_reg
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266)
+    - usb: dwc2: gadget: Don't write invalid mapped sg entries into dma_desc with
+      iommu enabled
+    - PCI: vmd: Create domain symlink before pci_bus_add_devices()
+    - PCI: Add ACS quirk for Broadcom BCM5760X NIC
+    - usb: cdns3-ti: Add workaround for Errata i2409
+    - MIPS: Loongson64: DTS: Fix msi node for ls7a
+    - ASoC: Intel: sof_sdw: fix jack detection on ADL-N variant RVP
+    - ASoC: Intel: sof_sdw: add quirk for Dell SKU 0B8C
+    - usb: cdns3: Add quirk flag to enable suspend residency
+    - platform/x86: p2sb: Make p2sb_get_devfn() return void
+    - p2sb: Factor out p2sb_read_from_cache()
+    - p2sb: Introduce the global flag p2sb_hidden_by_bios
+    - p2sb: Move P2SB hide and unhide code to p2sb_scan_and_cache()
+    - p2sb: Do not scan and remove the P2SB device when it is unhidden
+    - i2c: pnx: Fix timeout in wait functions
+    - xfs: fix the contact address for the sysfs ABI documentation
+    - xfs: verify buffer, inode, and dquot items every tx commit
+    - xfs: use consistent uid/gid when grabbing dquots for inodes
+    - xfs: declare xfs_file.c symbols in xfs_file.h
+    - xfs: create a new helper to return a file's allocation unit
+    - xfs: Fix xfs_flush_unmap_range() range for RT
+    - xfs: Fix xfs_prepare_shift() range for RT
+    - xfs: convert comma to semicolon
+    - xfs: fix file_path handling in tracepoints
+    - xfs: remove unused parameter in macro XFS_DQUOT_LOGRES
+    - xfs: attr forks require attr, not attr2
+    - xfs: conditionally allow FS_XFLAG_REALTIME changes if S_DAX is set
+    - xfs: Fix the owner setting issue for rmap query in xfs fsmap
+    - xfs: use XFS_BUF_DADDR_NULL for daddrs in getfsmap code
+    - xfs: take m_growlock when running growfsrt
+    - xfs: reset rootdir extent size hint after growfsrt
+    - tools: hv: change permissions of NetworkManager configuration file
+    - cxl/pci: Fix potential bogus return value upon successful probing
+    - cxl/region: Fix region creation for greater than x2 switches
+    - net/smc: check sndbuf_space again after NOSPACE flag is set in smc_poll
+    - ionic: use ee->offset when returning sprom data
+    - net: renesas: rswitch: rework ts tags management
+    - net: hinic: Fix cleanup in create_rxqs/txqs()
+    - net: ethernet: bgmac-platform: fix an OF node reference leak
+    - ipvs: Fix clamp() of ip_vs_conn_tab on small memory systems
+    - netfilter: ipset: Fix for recursive locking warning
+    - selftests: openvswitch: fix tcpdump execution
+    - net: mdiobus: fix an OF node reference leak
+    - mmc: sdhci-tegra: Remove SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC quirk
+    - mmc: mtk-sd: disable wakeup in .remove() and in the error path of .probe()
+    - EDAC/amd64: Simplify ECC check on unified memory controllers
+    - chelsio/chtls: prevent potential integer overflow on 32bit
+    - i2c: riic: Always round-up when calculating bus period
+    - efivarfs: Fix error on non-existent file
+    - hexagon: Disable constant extender optimization for LLVM prior to 19.1.0
+    - USB: serial: option: add TCL IK512 MBIM & ECM
+    - USB: serial: option: add MeiG Smart SLM770A
+    - USB: serial: option: add Netprisma LCUK54 modules for WWAN Ready
+    - USB: serial: option: add MediaTek T7XX compositions
+    - USB: serial: option: add Telit FE910C04 rmnet compositions
+    - thunderbolt: Improve redrive mode handling
+    - drm/panel: novatek-nt35950: fix return value check in nt35950_probe()
+    - i915/guc: Reset engine utilization buffer before registration
+    - i915/guc: Ensure busyness counter increases motonically
+    - i915/guc: Accumulate active runtime on gt reset
+    - hwmon: (tmp513) Fix interpretation of values of Shunt Voltage and Limit
+      Registers
+    - hwmon: (tmp513) Fix Current Register value interpretation
+    - hwmon: (tmp513) Fix interpretation of values of Temperature Result and Limit
+      Registers
+    - zram: refuse to use zero sized block device as backing device
+    - zram: fix uninitialized ZRAM not releasing backing device
+    - zram: fix potential UAF of zram table
+    - vmalloc: fix accounting with i915
+    - btrfs: tree-checker: reject inline extent items with 0 ref count
+    - smb: client: fix TCP timers deadlock after rmmod
+    - tracing: Fix test_event_printk() to process entire print argument
+    - tracing: Add missing helper functions in event pointer dereference check
+    - tracing: Add "%s" check in test_event_printk()
+    - tracing: Have process_string() also allow arrays
+    - selftests/memfd: run sysctl tests when PID namespace support is enabled
+    - selftests/bpf: Use asm constraint "m" for LoongArch
+    - io_uring: Fix registered ring file refcount leak
+    - NFS/pnfs: Fix a live lock between recalled layouts and layoutget
+    - of/irq: Fix interrupt-map cell length check in of_irq_parse_imap_parent()
+    - of/irq: Fix using uninitialized variable @addr_len in API of_irq_parse_one()
+    - nilfs2: fix buffer head leaks in calls to truncate_inode_pages()
+    - udmabuf: also check for F_SEAL_FUTURE_WRITE
+    - of: Fix error path in of_parse_phandle_with_args_map()
+    - of: Fix refcount leakage for OF node returned by __of_get_dma_parent()
+    - ceph: validate snapdirname option length when mounting
+    - ceph: improve error handling and short/overflow-read logic in
+      __ceph_sync_read()
+    - ceph: fix memory leaks in __ceph_sync_read()
+    - epoll: Add synchronous wakeup support for ep_poll_callback
+    - io_uring/rw: avoid punting to io-wq directly
+    - drm/amdgpu: Handle NULL bo->tbo.resource (again) in amdgpu_vm_bo_update
+    - xfs: sb_spino_align is not verified
+    - xfs: fix sparse inode limits on runt AG
+    - xfs: fix sb_spino_align checks for large fsblock sizes
+    - xfs: fix zero byte checking in the superblock scrubber
+    - netdev: fix repeated netlink messages in queue dump
+    - team: Fix feature exposure when no ports are present
+    - can: m_can: fix missed interrupts with m_can_pci
+    - netdev-genl: avoid empty messages in queue dump
+    - KVM: arm64: Do not allow ID_AA64MMFR0_EL1.ASIDbits to be overridden
+    - KVM: arm64: Fix set_id_regs selftest for ASIDBITS becoming unwritable
+    - net: mctp: handle skb cleanup on sock_queue failures
+    - xhci: retry Stop Endpoint on buggy NEC controllers
+    - usb: xhci: Limit Stop Endpoint retries
+    - usb: xhci: Avoid queuing redundant Stop Endpoint commands
+    - xhci: Turn NEC specific quirk for handling Stop Endpoint errors generic
+    - thunderbolt: Add support for Intel Panther Lake-M/P
+    - thunderbolt: Don't display nvm_version unless upgrade supported
+    - drm/panel: st7701: Add prepare_prev_first flag to drm_panel
+    - drm/panel: synaptics-r63353: Fix regulator unbalance
+    - drm/amdgpu/nbio7.11: fix IP version check
+    - drm/amdgpu/nbio7.7: fix IP version check
+    - fgraph: Still initialize idle shadow stacks when starting
+    - x86/hyperv: Fix hv tsc page based sched_clock for hibernation
+    - ocfs2: fix the space leak in LA when releasing LA
+    - of: property: fw_devlink: Do not use interrupt-parent directly
+    - of: address: Preserve the flags portion on 1:1 dma-ranges mapping
+    - Upstream stable to v6.6.68, v6.12.7
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56710
+    - ceph: fix memory leak in ceph_direct_read_write()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-53685
+    - ceph: give up on paths longer than PATH_MAX
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-54193
+    - accel/ivpu: Fix WARN in ivpu_ipc_send_receive_internal()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-54455
+    - accel/ivpu: Fix general protection fault in ivpu_bo_list()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-53690
+    - nilfs2: prevent use of deleted inode
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56709
+    - io_uring: check if iowq is killed before queuing
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-55881
+    - KVM: x86: Play nice with protected guests in complete_hypercall_exit()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-55916
+    - Drivers: hv: util: Avoid accessing a ringbuffer not initialized yet
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56369
+    - drm/modes: Avoid divide by zero harder in drm_mode_vrefresh()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56372
+    - net: tun: fix tun_napi_alloc_frags()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56715
+    - ionic: Fix netdev notifier unregister on failure
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56716
+    - netdevsim: prevent bad user input in nsim_dev_health_break_write()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56717
+    - net: mscc: ocelot: fix incorrect IFH SRC_PORT field in
+      ocelot_ifh_set_basic()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-57791
+    - net/smc: check return value of sock_recvmsg when draining clc data
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-47408
+    - net/smc: check smcd_v2_ext_offset when receiving proposal msg
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-49568
+    - net/smc: check v2_ext_offset/eid_cnt/ism_gid_cnt when receiving proposal msg
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-49571
+    - net/smc: check iparea_offset and ipv6_prefixes_cnt when receiving proposal
+      msg
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56718
+    - net/smc: protect link down work from execute after lgr freed
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-41013
+    - xfs: don't walk off the end of a directory data block
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181)
+    - perf/x86/intel/ds: Unconditionally drain PEBS DS when changing PEBS_DATA_CFG
+    - ksmbd: fix racy issue from session lookup and expire
+    - splice: do not checksum AF_UNIX sockets
+    - tcp: check space before adding MPTCP SYN options
+    - ALSA: usb-audio: Add implicit feedback quirk for Yamaha THR5
+    - usb: host: max3421-hcd: Correctly abort a USB request.
+    - ata: sata_highbank: fix OF node reference leak in highbank_initialize_phys()
+    - usb: dwc2: Fix HCD resume
+    - usb: dwc2: hcd: Fix GetPortStatus & SetPortFeature
+    - usb: dwc2: Fix HCD port connection race
+    - scsi: ufs: core: Update compl_time_stamp_local_clock after completing a cqe
+    - usb: gadget: midi2: Fix interpretation of is_midi1 bits
+    - usb: ehci-hcd: fix call balance of clocks handling routines
+    - usb: typec: anx7411: fix fwnode_handle reference leak
+    - usb: typec: anx7411: fix OF node reference leaks in
+      anx7411_typec_switch_probe()
+    - usb: dwc3: xilinx: make sure pipe clock is deselected in usb2 only mode
+    - drm/i915: Fix memory leak by correcting cache object name in error handler
+    - xfs: update btree keys correctly when _insrec splits an inode root block
+    - xfs: don't drop errno values when we fail to ficlone the entire range
+    - xfs: return from xfs_symlink_verify early on V4 filesystems
+    - xfs: fix scrub tracepoints when inode-rooted btrees are involved
+    - xfs: only run precommits once per transaction object
+    - bpf: Check size for BTF-based ctx access of pointer members
+    - bpf: Fix theoretical prog_array UAF in __uprobe_perf_func()
+    - bpf,perf: Fix invalid prog_array access in perf_event_detach_bpf_prog
+    - bpf, sockmap: Fix update element with same
+    - wifi: mac80211: init cnt before accessing elem in
+      ieee80211_copy_mbssid_beacon
+    - wifi: mac80211: clean up 'ret' in sta_link_apply_parameters()
+    - wifi: mac80211: fix station NSS capability initialization order
+    - batman-adv: Do not send uninitialized TT changes
+    - batman-adv: Remove uninitialized data in full table TT response
+    - batman-adv: Do not let TT changes list grows indefinitely
+    - wifi: cfg80211: sme: init n_channels before channels[] access
+    - selftests: mlxsw: sharedbuffer: Remove h1 ingress test case
+    - selftests: mlxsw: sharedbuffer: Remove duplicate test cases
+    - selftests: mlxsw: sharedbuffer: Ensure no extra packets are counted
+    - ptp: kvm: x86: Return EOPNOTSUPP instead of ENODEV from kvm_arch_ptp_init()
+    - net: mscc: ocelot: fix memory leak on ocelot_port_add_txtstamp_skb()
+    - net: mscc: ocelot: improve handling of TX timestamp for unknown skb
+    - net: mscc: ocelot: ocelot->ts_id_lock and ocelot_port->tx_skbs.lock are IRQ-
+      safe
+    - net: mscc: ocelot: be resilient to loss of PTP packets during transmission
+    - net: mscc: ocelot: perform error cleanup in ocelot_hwstamp_set()
+    - spi: aspeed: Fix an error handling path in aspeed_spi_[read|write]_user()
+    - net: sparx5: fix FDMA performance issue
+    - net: sparx5: fix the maximum frame length register
+    - ACPI: resource: Fix memory resource type union access
+    - cxgb4: use port number to set mac addr
+    - qca_spi: Fix clock speed for multiple QCA7000
+    - qca_spi: Make driver probing reliable
+    - ASoC: amd: yc: Fix the wrong return value
+    - Documentation: PM: Clarify pm_runtime_resume_and_get() return value
+    - net: renesas: rswitch: fix race window between tx start and complete
+    - net: renesas: rswitch: fix leaked pointer on error path
+    - net: renesas: rswitch: handle stop vs interrupt race
+    - net: dsa: felix: fix stuck CPU-injected packets with short taprio windows
+    - netem: Update sch->q.qlen before qdisc_tree_reduce_backlog()
+    - bonding: Fix feature propagation of NETIF_F_GSO_ENCAP_ALL
+    - team: Fix feature propagation of NETIF_F_GSO_ENCAP_ALL
+    - ACPICA: events/evxfregn: don't release the ContextMutex that was never
+      acquired
+    - Bluetooth: iso: Fix recursive locking warning
+    - Bluetooth: SCO: Add support for 16 bits transparent voice setting
+    - net: renesas: rswitch: fix initial MPIC register setting
+    - net: dsa: microchip: KSZ9896 register regmap alignment to 32 bit boundaries
+    - blk-iocost: Avoid using clamp() on inuse in __propagate_weights()
+    - kselftest/arm64: abi: fix SVCR detection
+    - KVM: arm64: Disable MPAM visibility by default and ignore VMM writes
+    - selftests/bpf: remove use of __xlated()
+    - xen/netfront: fix crash when removing device
+    - x86: make get_cpu_vendor() accessible from Xen code
+    - objtool/x86: allow syscall instruction
+    - x86/static-call: provide a way to do very early static-call updates
+    - x86/xen: don't do PV iret hypercall through hypercall page
+    - x86/xen: add central hypercall functions
+    - x86/xen: fix xen_hypercall_hvm() to not clobber %rbx
+    - x86/xen: add FRAME_END to xen_hypercall_hvm()
+    - x86/xen: use new hypercall functions instead of hypercall page
+    - x86/xen: remove hypercall page
+    - x86/static-call: fix 32-bit build
+    - x86/asm: Make serialize() always_inline
+    - x86/static-call: Remove early_boot_irqs_disabled check to fix Xen PVH dom0
+    - serial: sh-sci: Check if TX data was written to device in .tx_empty()
+    - gpio: ljca: Initialize num before accessing item in ljca_gpio_config
+    - ALSA: hda/realtek: Fix headset mic on Acer Nitro 5
+    - drm/amdkfd: Use device based logging for errors
+    - drm/amdkfd: pause autosuspend when creating pdd
+    - drm/amdkfd: fixed page fault when enable MES shader debugger
+    - drm/i915/color: Stop using non-posted DSB writes for legacy LUT
+    - drm/amd/pm: Set SMU v13.0.7 default workload type
+    - xfs: return a 64-bit block count from xfs_btree_count_blocks
+    - perf machine: Initialize machine->env to address a segfault
+    - bnxt_en: Fix GSO type for HW GRO packets on 5750X chips
+    - net: renesas: rswitch: fix possible early skb release
+    - Bluetooth: Improve setsockopt() handling of malformed user input
+    - libperf: evlist: Fix --cpu argument on hybrid platform
+    - selftests: netfilter: Stabilize rpath.sh
+    - net, team, bonding: Add netdev_base_features helper
+    - bonding: Fix initial {vlan,mpls}_feature set in bond_compute_features
+    - team: Fix initial vlan_feature set in __team_compute_features
+    - drm/xe: fix the ERR_PTR() returned on failure to allocate tiny pt
+    - Upstream stable to v6.6.67, v6.12.6
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56652
+    - drm/xe/reg_sr: Remove register pool
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-54460
+    - Bluetooth: iso: Fix circular lock in iso_listen_bis
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-57879
+    - Bluetooth: iso: Always release hdev at the end of iso_listen_bis
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56656
+    - bnxt_en: Fix aggregation ID mask to prevent oops on 5760X chips
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-53125
+    - bpf: sync_linked_regs() must preserve subreg_def
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56654
+    - Bluetooth: hci_event: Fix using rcu_read_(un)lock while iterating
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56770
+    - net/sched: netem: account for backlog updates from child qdisc
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-54683
+    - netfilter: IDLETIMER: Fix for possible ABBA deadlock
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-55639
+    - net: renesas: rswitch: avoid use-after-put for a device tree node
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56657
+    - ALSA: control: Avoid WARN() for symlink errors
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56659
+    - net: lapb: increase LAPB_HEADER_LEN
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56660
+    - net/mlx5: DR, prevent potential error pointer dereference
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56662
+    - acpi: nfit: vmalloc-out-of-bounds Read in acpi_nfit_ctl
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56664
+    - bpf, sockmap: Fix race between element replace and close()
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56667
+    - drm/i915: Fix NULL pointer dereference in capture_engine
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56670
+    - usb: gadget: u_serial: Fix the issue that gs_start_io crashed due to
+      accessing null pointer
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-53687
+    - riscv: Fix IPIs usage in kfence_protect_page()
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56675
+    - bpf: Fix UAF via mismatching bpf_prog/attachment RCU flavors
+  * Noble update: upstream stable patchset 2025-02-04 (LP: #2097393)
+    - selftests: net: Remove executable bits from library scripts
+  * CVE-2024-56653
+    - Bluetooth: btmtk: avoid UAF in btmtk_process_coredump
+
+  [ Ubuntu: 6.8.0-58.60 ]
+
+  * noble/linux: 6.8.0-58.60 -proposed tracker (LP: #2102529)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2025.03.17)
+  * wdat_wdt.ko should be pulled in by linux-image-virtual (LP: #2098554)
+    - [Packaging]: wdat_wdt.ko is moved from "linux-modules-extra-*-generic" to
+      "linux-modules-*-generic"
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118)
+    - openrisc: Use asm-generic's version of fix_to_virt() & virt_to_fix()
+    - iTCO_wdt: mask NMI_NOW bit for update_no_reboot_bit() call
+    - watchdog: xilinx_wwdt: Calculate max_hw_heartbeat_ms using clock frequency
+    - watchdog: apple: Actually flush writes after requesting watchdog restart
+    - watchdog: mediatek: Make sure system reset gets asserted in
+      mtk_wdt_restart()
+    - can: gs_usb: add VID/PID for Xylanta SAINT3 product family
+    - can: gs_usb: add usb endpoint address detection at driver probe step
+    - can: sun4i_can: sun4i_can_err(): call can_change_state() even if cf is NULL
+    - can: m_can: m_can_handle_lec_err(): fix {rx,tx}_errors statistics
+    - can: ifi_canfd: ifi_canfd_handle_lec_err(): fix {rx,tx}_errors statistics
+    - can: hi311x: hi3110_can_ist(): fix {rx,tx}_errors statistics
+    - can: sja1000: sja1000_err(): fix {rx,tx}_errors statistics
+    - can: sun4i_can: sun4i_can_err(): fix {rx,tx}_errors statistics
+    - can: ems_usb: ems_usb_rx_err(): fix {rx,tx}_errors statistics
+    - can: f81604: f81604_handle_can_bus_errors(): fix {rx,tx}_errors statistics
+    - ipvs: fix UB due to uninitialized stack access in ip_vs_protocol_init()
+    - selftests: hid: fix typo and exit code
+    - ptp: Add error handling for adjfine callback in ptp_clock_adjtime
+    - net/sched: tbf: correct backlog statistic for GSO packets
+    - net: hsr: fix fill_frame_info() regression vs VLAN packets
+    - platform/x86: asus-wmi: add support for vivobook fan profiles
+    - platform/x86: asus-wmi: Fix inconsistent use of thermal policies
+    - platform/x86: asus-wmi: Ignore return value when writing thermal policy
+    - net/smc: mark optional smcd_ops and check for support when called
+    - net/smc: add operations to merge sndbuf with peer DMB
+    - net/smc: {at|de}tach sndbuf to peer DMB if supported
+    - net/smc: refactoring initialization of smc sock
+    - net/qed: allow old cards not supporting "num_images" to work
+    - ixgbevf: stop attempting IPSEC offload on Mailbox API 1.5
+    - ixgbe: downgrade logging of unsupported VF API version to debug
+    - net: sched: fix erspan_opt settings in cls_flower
+    - netfilter: nft_set_hash: skip duplicated elements pending gc run
+    - netfilter: nft_set_hash: unaligned atomic read on struct nft_set_ext
+    - ethtool: Fix wrong mod state in case of verbose and no_mask bitset
+    - mlxsw: spectrum_acl_flex_keys: Constify struct mlxsw_afk_element_inst
+    - mlxsw: spectrum_acl_flex_keys: Use correct key block on Spectrum-4
+    - net/mlx5e: Remove workaround to avoid syndrome for internal port
+    - xhci: Allow RPM on the USB controller (1022:43f7) by default
+    - gpio: grgpio: use a helper variable to store the address of ofdev->dev
+    - usb: dwc3: gadget: Rewrite endpoint allocation flow
+    - usb: dwc3: ep0: Don't reset resource alloc flag (including ep0)
+    - usb: dwc3: ep0: Don't clear ep0 DWC3_EP_TRANSFER_STARTED
+    - mmc: mtk-sd: use devm_mmc_alloc_host
+    - mmc: mtk-sd: Fix error handle of probe function
+    - mmc: mtk-sd: fix devm_clk_get_optional usage
+    - mmc: mtk-sd: Fix MMC_CAP2_CRYPTO flag setting
+    - zram: do not mark idle slots that cannot be idle
+    - zram: clear IDLE flag in mark_idle()
+    - powerpc/vdso: Refactor CFLAGS for CVDSO build
+    - powerpc/vdso: Drop -mstack-protector-guard flags in 32-bit files with clang
+    - ntp: Remove invalid cast in time offset math
+    - driver core: Add FWLINK_FLAG_IGNORE to completely ignore a fwnode link
+    - driver core: fw_devlink: Stop trying to optimize cycle detection logic
+    - drivers: core: fix device leak in __fw_devlink_relax_cycles()
+    - i3c: master: support to adjust first broadcast address speed
+    - i3c: master: svc: use slow speed for first broadcast address
+    - i3c: master: svc: Modify enabled_events bit 7:0 to act as IBI enable counter
+    - i3c: master: Replace hard code 2 with macro I3C_ADDR_SLOT_STATUS_BITS
+    - i3c: master: Extend address status bit to 4 and add
+      I3C_ADDR_SLOT_EXT_DESIRED
+    - i3c: master: Fix dynamic address leak when 'assigned-address' is present
+    - i3c: master: Fix missing 'ret' assignment in set_speed()
+    - drm/bridge: it6505: update usleep_range for RC circuit charge time
+    - drm/bridge: it6505: Fix inverted reset polarity
+    - scsi: ufs: core: Always initialize the UIC done completion
+    - scsi: ufs: core: Add ufshcd_send_bsg_uic_cmd() for UFS BSG
+    - bpf, vsock: Fix poll() missing a queue
+    - bpf, vsock: Invoke proto::close on close()
+    - xsk: always clear DMA mapping information when unmapping the pool
+    - bpftool: fix potential NULL pointer dereferencing in prog_dump()
+    - drm/sti: Add __iomem for mixer_dbg_mxn's parameter
+    - ALSA: seq: ump: Use automatic cleanup of kfree()
+    - ALSA: ump: Update substream name from assigned FB names
+    - ALSA: seq: ump: Fix seq port updates per FB info notify
+    - ALSA: usb-audio: Notify xrun for low-latency mode
+    - tools: Override makefile ARCH variable if defined, but empty
+    - ASoC: SOF: ipc3-topology: Convert the topology pin index to ALH dai index
+    - ASoC: SOF: ipc3-topology: fix resource leaks in
+      sof_ipc3_widget_setup_comp_dai()
+    - bpf: Fix narrow scalar spill onto 64-bit spilled scalar slots
+    - scsi: scsi_debug: Fix hrtimer support for ndelay
+    - ASoC: mediatek: mt8188-mt6359: Remove hardcoded dmic codec
+    - drm/v3d: Enable Performance Counters before clearing them
+    - scatterlist: fix incorrect func name in kernel-doc
+    - iio: magnetometer: yas530: use signed integer type for clamp limits
+    - bpf: Handle BPF_EXIST and BPF_NOEXIST for LPM trie
+    - bpf: Remove unnecessary kfree(im_node) in lpm_trie_update_elem
+    - bpf: Handle in-place update for full LPM trie correctly
+    - bpf: Fix exact match conditions in trie_get_next_key()
+    - x86/CPU/AMD: WARN when setting EFER.AUTOIBRS if and only if the WRMSR fails
+    - watchdog: rti: of: honor timeout-sec property
+    - can: mcp251xfd: mcp251xfd_get_tef_len(): work around erratum DS80000789E 6.
+    - tracing: Fix cmp_entries_dup() to respect sort() comparison rules
+    - arm64: Ensure bits ASID[15:8] are masked out when the kernel uses 8-bit
+      ASIDs
+    - ALSA: usb-audio: add mixer mapping for Corsair HS80
+    - ALSA: hda/realtek: Enable mute and micmute LED on HP ProBook 430 G8
+    - ALSA: hda/realtek: Add support for Samsung Galaxy Book3 360 (NP730QFG)
+    - scsi: qla2xxx: Fix abort in bsg timeout
+    - scsi: qla2xxx: Fix NVMe and NPIV connect issue
+    - scsi: qla2xxx: Supported speed displayed incorrectly for VPorts
+    - scsi: qla2xxx: Remove check req_sg_cnt should be equal to rsp_sg_cnt
+    - scsi: ufs: core: Add missing post notify for power mode change
+    - fs/smb/client: cifs_prime_dcache() for SMB3 POSIX reparse points
+    - drm/dp_mst: Verify request type in the corresponding down message reply
+    - drm/amdgpu/hdp5.2: do a posting read when flushing HDP
+    - modpost: Add .irqentry.text to OTHER_SECTIONS
+    - x86/kexec: Restore GDT on return from ::preserve_context kexec
+    - dma-buf: fix dma_fence_array_signaled v4
+    - dma-fence: Fix reference leak on fence merge failure path
+    - dma-fence: Use kernel's sort for merging fences
+    - regmap: detach regmap from dev on regmap_exit
+    - mmc: sdhci-pci: Add DMI quirk for missing CD GPIO on Vexia Edu Atla 10
+      tablet
+    - mmc: core: Further prevent card detect during shutdown
+    - ocfs2: update seq_file index in ocfs2_dlm_seq_next
+    - lib: stackinit: hide never-taken branch from compiler
+    - kasan: make report_lock a raw spinlock
+    - x86/mm: Add _PAGE_NOPTISHADOW bit to avoid updating userspace page tables
+    - epoll: annotate racy check
+    - kselftest/arm64: Log fp-stress child startup errors to stdout
+    - btrfs: avoid unnecessary device path update for the same device
+    - btrfs: do not clear read-only when adding sprout device
+    - kselftest/arm64: Don't leak pipe fds in pac.exec_sign_all()
+    - hwmon: (nct6775) Add 665-ACE/600M-CL to ASUS WMI monitoring list
+    - ACPI: x86: Make UART skip quirks work on PCI UARTs without an UID
+    - perf/x86/amd: Warn only on new bits set
+    - spi: spi-fsl-lpspi: Adjust type of scldiv
+    - HID: add per device quirk to force bind to hid-generic
+    - media: uvcvideo: RealSense D421 Depth module metadata
+    - media: uvcvideo: Add a quirk for the Kaiweets KTI-W02 infrared camera
+    - media: cx231xx: Add support for Dexatek USB Video Grabber 1d19:6108
+    - mmc: core: Add SD card quirk for broken poweroff notification
+    - mmc: sdhci-esdhc-imx: enable quirks SDHCI_QUIRK_NO_LED
+    - regmap: maple: Provide lockdep (sub)class for maple tree's internal lock
+    - selftests/resctrl: Protect against array overflow when reading strings
+    - drm/vc4: hdmi: Avoid log spam for audio start failure
+    - drm/vc4: hvs: Set AXI panic modes for the HVS
+    - drm: panel-orientation-quirks: Add quirk for AYA NEO 2 model
+    - drm: panel-orientation-quirks: Add quirk for AYA NEO Founder edition
+    - drm: panel-orientation-quirks: Add quirk for AYA NEO GEEK
+    - drm/bridge: it6505: Enable module autoloading
+    - drm/mcde: Enable module autoloading
+    - drm/radeon/r600_cs: Fix possible int overflow in r600_packet3_check()
+    - drm/display: Fix building with GCC 15
+    - ALSA: hda: Use own quirk lookup helper
+    - ALSA: hda/conexant: Use the new codec SSID matching
+    - r8169: don't apply UDP padding quirk on RTL8126A
+    - samples/bpf: Fix a resource leak
+    - net: fec_mpc52xx_phy: Use %pa to format resource_size_t
+    - net: ethernet: fs_enet: Use %pa to format resource_size_t
+    - net/sched: cbs: Fix integer overflow in cbs_set_port_rate()
+    - Bluetooth: L2CAP: handle NULL sock pointer in l2cap_sock_alloc
+    - wifi: ath5k: add PCI ID for SX76X
+    - wifi: ath5k: add PCI ID for Arcadyan devices
+    - fanotify: allow reporting errors on failure to open fd
+    - drm/panel: simple: Add Microchip AC69T88A LVDS Display panel
+    - net: sfp: change quirks for Alcatel Lucent G-010S-P
+    - net: stmmac: Programming sequence for VLAN packets with split header
+    - drm/sched: memset() 'job' in drm_sched_job_init()
+    - amdgpu/uvd: get ring reference from rq scheduler
+    - drm/amdgpu: don't access invalid sched
+    - drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts for vega20_ih
+    - drm/amdgpu: Dereference the ATCS ACPI buffer
+    - netlink: specs: Add missing bitset attrs to ethtool spec
+    - drm/amdgpu: refine error handling in amdgpu_ttm_tt_pin_userptr
+    - fsl/fman: Validate cell-index value obtained from Device Tree
+    - drm/amdgpu: skip amdgpu_device_cache_pci_state under sriov
+    - ALSA: usb-audio: Make mic volume workarounds globally applicable
+    - wifi: ipw2x00: libipw_rx_any(): fix bad alignment
+    - dsa: qca8k: Use nested lock to avoid splat
+    - Bluetooth: btusb: Add RTL8852BE device 0489:e123 to device tables
+    - Bluetooth: Add new quirks for ATS2851
+    - Bluetooth: Support new quirks for ATS2851
+    - Bluetooth: Set quirks for ATS2851
+    - ASoC: hdmi-codec: reorder channel allocation list
+    - rocker: fix link status detection in rocker_carrier_init()
+    - net/neighbor: clear error in case strict check is not set
+    - netpoll: Use rcu_access_pointer() in __netpoll_setup
+    - pinctrl: freescale: fix COMPILE_TEST error with PINCTRL_IMX_SCU
+    - tracing/ftrace: disable preemption in syscall probe
+    - tracing: Use atomic64_inc_return() in trace_clock_counter()
+    - tools/rtla: fix collision with glibc sched_attr/sched_set_attr
+    - rtla/timerlat: Make timerlat_top_cpu->*_count unsigned long long
+    - scsi: ufs: core: Make DMA mask configuration more flexible
+    - scsi: lpfc: Call lpfc_sli4_queue_unset() in restart and rmmod paths
+    - clk: qcom: rcg2: add clk_rcg2_shared_floor_ops
+    - clk: qcom: rpmh: add support for SAR2130P
+    - clk: qcom: tcsrcc-sm8550: add SAR2130P support
+    - scsi: st: Don't modify unknown block number in MTIOCGET
+    - scsi: st: Add MTIOCGET and MTLOAD to ioctls allowed after device reset
+    - pinctrl: qcom-pmic-gpio: add support for PM8937
+    - pinctrl: qcom: spmi-mpp: Add PM8937 compatible
+    - thermal/drivers/qcom/tsens-v1: Add support for MSM8937 tsens
+    - nvdimm: rectify the illogical code within nd_dax_probe()
+    - smb: client: memcpy() with surrounding object base address
+    - verification/dot2: Improve dot parser robustness
+    - KMSAN: uninit-value in inode_go_dump (5)
+    - PCI: qcom: Add support for IPQ9574
+    - PCI: vmd: Add DID 8086:B06F and 8086:B60B for Intel client SKUs
+    - PCI: vmd: Set devices to D0 before enabling PM L1 Substates
+    - PCI: Detect and trust built-in Thunderbolt chips
+    - PCI: Add 'reset_subordinate' to reset hierarchy below bridge
+    - PCI: Add ACS quirk for Wangxun FF5xxx NICs
+    - f2fs: print message if fscorrupted was found in f2fs_new_node_page()
+    - ACPI: x86: Add skip i2c clients quirk for Acer Iconia One 8 A1-840
+    - ACPI: x86: Clean up Asus entries in acpi_quirk_skip_dmi_ids[]
+    - fs/ntfs3: Fix case when unmarked clusters intersect with zone
+    - usb: chipidea: udc: handle USB Error Interrupt if IOC not set
+    - iio: light: ltr501: Add LTER0303 to the supported devices
+    - ASoC: amd: yc: fix internal mic on Redmi G 2022
+    - drm/amdgpu/vcn: reset fw_shared when VCPU buffers corrupted on vcn v4.0.3
+    - drm/amdgpu/vcn: reset fw_shared under SRIOV
+    - ASoC: amd: yc: Add quirk for microphone on Lenovo Thinkpad T14s Gen 6
+      21M1CTO1WW
+    - misc: eeprom: eeprom_93cx6: Add quirk for extra read clock cycle
+    - rtc: cmos: avoid taking rtc_lock for extended period of time
+    - serial: 8250_dw: Add Sophgo SG2044 quirk
+    - smb: client: don't try following DFS links in cifs_tree_connect()
+    - setlocalversion: work around "git describe" performance
+    - sched/core: Remove the unnecessary need_resched() check in nohz_csd_func()
+    - sched/fair: Check idle_cpu() before need_resched() to detect ilb CPU turning
+      busy
+    - sched/core: Prevent wakeup of ksoftirqd during idle load balance
+    - btrfs: fix missing snapshot drew unlock when root is dead during swap
+      activation
+    - clk: en7523: Initialize num before accessing hws in en7523_register_clocks()
+    - tracing/eprobe: Fix to release eprobe when failed to add dyn_event
+    - x86: Fix build regression with CONFIG_KEXEC_JUMP enabled
+    - Revert "unicode: Don't special case ignorable code points"
+    - vfio/mlx5: Align the page tracking max message size with the device
+      capability
+    - selftests/ftrace: adjust offset for kprobe syntax error test
+    - KVM: x86/mmu: Ensure that kvm_release_pfn_clean() takes exact pfn from
+      kvm_faultin_pfn()
+    - jffs2: Fix rtime decompressor
+    - mm/damon/vaddr: fix issue in damon_va_evenly_split_region()
+    - iio: invensense: fix multiple odr switch when FIFO is off
+    - ocfs2: Revert "ocfs2: fix the la space leak when unmounting an ocfs2 volume"
+    - ALSA: hda: Fix build error without CONFIG_SND_DEBUG
+    - usb: dwc3: ep0: Don't reset resource alloc flag
+    - ALSA: usb-audio: Update UMP group attributes for GTB blocks, too
+    - platform/x86: asus-wmi: Fix thermal profile initialization
+    - i3c: master: svc: fix possible assignment of the same address to two devices
+    - btrfs: drop unused parameter file_offset from
+      btrfs_encoded_read_regular_fill_pages()
+    - md/raid5: Wait sync io to finish before changing group cnt
+    - media: platform: rga: fix 32-bit DMA limitation
+    - net: phy: dp83869: fix status reporting for 1000base-x autonegotiation
+    - remoteproc: qcom_q6v5_pas: disable auto boot for wpss
+    - mtd: spinand: winbond: Fix 512GW and 02JW OOB layout
+    - PCI: Pass domain number to pci_bus_release_domain_nr() explicitly
+    - dt-bindings: net: fec: add pps channel property
+    - net: fec: refactor PPS channel configuration
+    - net: fec: make PPS channel configurable
+    - drm/xe/xe_guc_ads: save/restore OA registers and allowlist regs
+    - drm/xe/migrate: use XE_BO_FLAG_PAGETABLE
+    - drm/amd: Add some missing straps from NBIO 7.11.0
+    - drm/amd: Fix initialization mistake for NBIO 7.11 devices
+    - drm/amdgpu/pm: Don't use OD table on Arcturus
+    - drm/amd/pm: Remove arcturus min power limit
+    - drm/amd/display: update pipe selection policy to check head pipe
+    - drm/amd/display: Remove PIPE_DTO_SRC_SEL programming from set_dtbclk_dto
+    - Revert "drm/xe/xe_guc_ads: save/restore OA registers and allowlist regs"
+    - ipv6: avoid possible NULL deref in modify_prefix_route()
+    - net: phy: microchip: Reset LAN88xx PHY to ensure clean link state on
+      LAN7800/7850
+    - ice: fix PHY Clock Recovery availability check
+    - vsock/test: fix failures due to wrong SO_RCVLOWAT parameter
+    - vsock/test: fix parameter types in SO_VM_SOCKETS_* calls
+    - mmc: core Convert UNSTUFF_BITS macro to inline function
+    - mmc: sd: SDUC Support Recognition
+    - mmc: core: Adjust ACMD22 to SDUC
+    - mmc: core: Use GFP_NOIO in ACMD22
+    - f2fs: clean up w/ F2FS_{BLK_TO_BYTES,BTYES_TO_BLK}
+    - f2fs: fix to adjust appropriate length for fiemap
+    - f2fs: fix to requery extent which cross boundary of inquiry
+    - drm/amd/display: calculate final viewport before TAP optimization
+    - drm/amd/display: Ignore scalar validation failure if pipe is phantom
+    - pmdomain: core: Add missing put_device()
+    - pmdomain: core: Fix error path in pm_genpd_init() when ida alloc fails
+    - pmdomain: core: add dummy release function to genpd device
+    - bpf: Ensure reg is PTR_TO_STACK in process_iter_arg
+    - bpf: Don't mark STACK_INVALID as STACK_MISC in mark_stack_slot_misc
+    - LoongArch: KVM: Protect kvm_check_requests() with SRCU
+    - net :mana :Request a V2 response version for MANA_QUERY_GF_STAT
+    - ALSA: usb-audio: Add extra PID for RME Digiface USB
+    - ALSA: hda/realtek: fix micmute LEDs don't work on HP Laptops
+    - scsi: ufs: pltfrm: Disable runtime PM during removal of glue drivers
+    - io_uring/cmd: document some uring_cmd related helpers
+    - io_uring: Change res2 parameter type in io_uring_cmd_done
+    - selftests/damon: add _damon_sysfs.py to TEST_FILES
+    - drm/amd/display: Correct prefetch calculation
+    - drm/amd/amdgpu: allow use kiq to do hdp flush under sriov
+    - drm/amdgpu/hdp6.0: do a posting read when flushing HDP
+    - drm/amdgpu/hdp4.0: do a posting read when flushing HDP
+    - drm/amdgpu/hdp5.0: do a posting read when flushing HDP
+    - x86/cpu/intel: Switch to new Intel CPU model defines
+    - x86/cpu/intel: Drop stray FAM6 check with new Intel CPU model defines
+    - x86/cpu: Add Lunar Lake to list of CPUs with a broken MONITOR implementation
+    - mm/damon: fix order of arguments in damos_before_apply tracepoint
+    - mm: respect mmap hint address when aligning for THP
+    - scsi: ufs: pltfrm: Drop PM runtime reference count after ufshcd_remove()
+    - memblock: allow zero threshold in validate_numa_converage()
+    - s390/pci: Sort PCI functions prior to creating virtual busses
+    - s390/pci: Use topology ID for multi-function devices
+    - s390/pci: Ignore RID for isolated VFs
+    - s390/pci: Fix SR-IOV for PFs initially in standby
+    - s390/pci: Pull search for parent PF out of zpci_iov_setup_virtfn()
+    - s390/pci: Fix handling of isolated VFs
+    - ext4: partial zero eof block on unaligned inode size extension
+    - crypto: ecdsa - Convert byte arrays with key coordinates to digits
+    - crypto: ecc - Prevent ecc_digits_from_bytes from reading too many bytes
+    - crypto: ecdsa - Rename keylen to bufsize where necessary
+    - crypto: ecdsa - Use ecc_digits_from_bytes to convert signature
+    - crypto: ecdsa - Avoid signed integer overflow on signature decoding
+    - ACPI: video: force native for Apple MacbookPro11,2 and Air7,2
+    - cleanup: Adjust scoped_guard() macros to avoid potential warning
+    - gpio: free irqs that are still requested when the chip is being removed
+    - media: uvcvideo: Force UVC version to 1.0a for 0408:4035
+    - media: uvcvideo: Force UVC version to 1.0a for 0408:4033
+    - wifi: mac80211: export ieee80211_purge_tx_queue() for drivers
+    - drm/amd/display: skip disable CRTC in seemless bootup case
+    - drm/amd/display: disable SG displays on cyan skillfish
+    - wifi: mac80211: Add non-atomic station iterator
+    - accel/qaic: Add AIC080 support
+    - mptcp: annotate data-races around subflow->fully_established
+    - net/tcp: Add missing lockdep annotations for TCP-AO hlist traversals
+    - drm/amd/display: Prune Invalid Modes For HDMI Output
+    - i2c: i801: Add support for Intel Arrow Lake-H
+    - i2c: i801: Add support for Intel Panther Lake
+    - Bluetooth: hci_conn: Reduce hci_conn_drop() calls in two functions
+    - Bluetooth: btusb: Add new VID/PID 13d3/3602 for MT7925
+    - Bluetooth: btusb: Add USB HW IDs for MT7921/MT7922/MT7925
+    - Bluetooth: btusb: Add new VID/PID 0489/e111 for MT7925
+    - Bluetooth: btusb: Add new VID/PID 0489/e124 for MT7925
+    - Bluetooth: btusb: Add 3 HWIDs for MT7925
+    - rtla/timerlat: Make timerlat_hist_cpu->*_count unsigned long long
+    - ring-buffer: Correct stale comments related to non-consuming readers
+    - ring-buffer: Limit time with disabled interrupts in rb_check_pages()
+    - scsi: lpfc: Check SLI_ACTIVE flag in FDMI cmpl before submitting follow up
+      FDMI
+    - scsi: lpfc: Prevent NDLP reference count underflow in dev_loss_tmo callback
+    - clk: qcom: clk-alpha-pll: Add support for zonda ole pll configure
+    - clk: qcom: clk-alpha-pll: Add NSS HUAYRA ALPHA PLL support for ipq9574
+    - mailbox: pcc: Check before sending MCTP PCC response ACK
+    - remoteproc: qcom: pas: Add support for SA8775p ADSP, CDSP and GPDSP
+    - remoteproc: qcom: pas: enable SAR2130P audio DSP support
+    - fs/ntfs3: Implement fallocate for compressed files
+    - fs/ntfs3: Fix warning in ni_fiemap
+    - regulator: qcom-rpmh: Update ranges for FTSMPS525
+    - usb: chipidea: add CI_HDRC_HAS_SHORT_PKT_LIMIT flag
+    - usb: chipidea: udc: limit usb request length to max 16KB
+    - usb: chipidea: udc: create bounce buffer for problem sglist entries if
+      possible
+    - iio: adc: ad7192: Convert from of specific to fwnode property handling
+    - iio: adc: ad7192: properly check spi_get_device_match_data()
+    - usb: typec: ucsi: add callback for connector status updates
+    - usb: typec: ucsi: glink: move GPIO reading into connector_status callback
+    - usb: typec: ucsi: add update_connector callback
+    - usb: typec: ucsi: glink: set orientation aware if supported
+    - usb: typec: ucsi: glink: be more precise on orientation-aware ports
+    - usb: typec: ucsi: glink: fix off-by-one in connector_status
+    - usb: typec: ucsi: Set orientation as none when connector is unplugged
+    - nvme: use helper nvme_ctrl_state in nvme_keep_alive_finish function
+    - Revert "nvme: make keep-alive synchronous operation"
+    - irqchip/gic-v3-its: Avoid explicit cpumask allocation on stack
+    - irqchip/gicv3-its: Add workaround for hip09 ITS erratum 162100801
+    - [Config] updateconfigs for HISILICON_ERRATUM_162100801
+    - drm/amd/display: Add option to retrieve detile buffer size
+    - btrfs: drop unused parameter options from open_ctree()
+    - btrfs: drop unused parameter data from btrfs_fill_super()
+    - btrfs: fix mount failure due to remount races
+    - net/mlx5: unique names for per device caches
+    - s390/pci: Fix leak of struct zpci_dev when zpci_add_device() fails
+    - ALSA: hda/realtek: Fix spelling mistake "Firelfy" -> "Firefly"
+    - softirq: Allow raising SCHED_SOFTIRQ from SMP-call-function on RT kernel
+    - Upstream stable to v6.6.65, v6.6.66, v6.12.4, v6.12.5
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-41932
+    - sched: fix warning in sched_setaffinity
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57872
+    - scsi: ufs: pltfrm: Dellocate HBA during ufshcd_pltfrm_remove()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56588
+    - scsi: hisi_sas: Create all dump files during debugfs initialization
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-47794
+    - bpf: Prevent tailcall infinite loop caused by freplace
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56599
+    - wifi: ath10k: avoid NULL pointer error during sdio remove
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56607
+    - wifi: ath12k: fix atomic calls in ath12k_mac_op_set_bitrate_mask()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56608
+    - drm/amd/display: Fix out-of-bounds access in 'dcn21_link_encoder_create'
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56609
+    - wifi: rtw88: use ieee80211_purge_tx_queue() to purge TX skb
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56782
+    - ACPI: x86: Add adev NULL check to acpi_quirk_skip_serdev_enumeration()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-48876
+    - stackdepot: fix stack_depot_save_flags() in NMI context
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56620
+    - scsi: ufs: qcom: Only free platform MSIs when ESI is enabled
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56621
+    - scsi: ufs: core: Cancel RTC work during ufshcd_remove()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-49569
+    - nvme-rdma: unquiesce admin_q before destroy it
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56632
+    - nvme-tcp: fix the memleak while create new ctrl failed
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56647
+    - net: Fix icmp host relookup triggering ip_rt_bug
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56775
+    - drm/amd/display: Fix handling of plane refcount
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56561
+    - PCI: endpoint: Fix PCI domain ID release in pci_epc_destroy()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56550
+    - s390/stacktrace: Use break instead of return statement
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56771
+    - mtd: spinand: winbond: Fix 512GW, 01GW, 01JW and 02JW ECC information
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56568
+    - iommu/arm-smmu: Defer probe of clients after smmu device bound
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56772
+    - kunit: string-stream: Fix a UAF bug in kunit_init_suite()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56773
+    - kunit: Fix potential null dereference in kunit_device_driver_test()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56580
+    - media: qcom: camss: fix error path on configuration of power domains
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57850
+    - jffs2: Prevent rtime decompress memory corruption
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56583
+    - sched/deadline: Fix warning in migrate_enable for boosted tasks
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56611
+    - mm/mempolicy: fix migrate_to_node() assuming there is at least one VMA in a
+      MM
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56613
+    - sched/numa: fix memory leak due to the overwritten vma->numab_state
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56584
+    - io_uring/tctx: work around xa_store() allocation error issue
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56781
+    - powerpc/prom_init: Fixup missing powermac #size-cells
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56785
+    - MIPS: Loongson64: DTS: Really fix PCIe port nodes for ls7a
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56585
+    - LoongArch: Fix sleeping in atomic context for PREEMPT_RT
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-41935
+    - f2fs: fix to shrink read extent node in batches
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-43098
+    - i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to
+      avoid deadlock
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-45828
+    - i3c: mipi-i3c-hci: Mask ring interrupts before ring stop request
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56586
+    - f2fs: fix f2fs_bug_on when uninstalling filesystem call f2fs_evict_inode.
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56587
+    - leds: class: Protect brightness_show() with led_cdev->led_access mutex
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56786
+    - bpf: put bpf_link's program when link is safe to be deallocated
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-47141
+    - pinmux: Use sequential access to access desc->pinmux data
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56589
+    - scsi: hisi_sas: Add cond_resched() for no forced preemption model
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56590
+    - Bluetooth: hci_core: Fix not checking skb length on hci_acldata_packet
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56592
+    - bpf: Call free_htab_elem() after htab_unlock_bucket()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56593
+    - wifi: brcmfmac: Fix oops due to NULL pointer dereference in
+      brcmf_sdiod_sglist_rw()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56594
+    - drm/amdgpu: set the right AMDGPU sg segment limitation
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57843
+    - virtio-net: fix overflow inside virtnet_rq_alloc
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56596
+    - jfs: fix array-index-out-of-bounds in jfs_readdir
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56597
+    - jfs: fix shift-out-of-bounds in dbSplit
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-47143
+    - dma-debug: fix a possible deadlock on radix_lock
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56601
+    - net: inet: do not leave a dangling sk pointer in inet_create()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56602
+    - net: ieee802154: do not leave a dangling sk pointer in ieee802154_create()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56603
+    - net: af_can: do not leave a dangling sk pointer in can_create()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56604
+    - Bluetooth: RFCOMM: avoid leaving dangling sk pointer in rfcomm_sock_alloc()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56605
+    - Bluetooth: L2CAP: do not leave dangling sk pointer on error in
+      l2cap_sock_create()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56606
+    - af_packet: avoid erroring out after sock_init_data() in packet_create()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-47809
+    - dlm: fix possible lkb_resource null dereference
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-48873
+    - wifi: rtw89: check return value of ieee80211_probereq_get() for RNR
+  * Missing support for USB-C Apple Magic Trackpad (LP: #2098063) // Noble
+    update: upstream stable patchset 2025-03-12 (LP: #2102118)
+    - HID: magicmouse: Apple Magic Trackpad 2 USB-C driver support
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56787
+    - soc: imx8m: Probe the SoC driver as platform driver
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56610
+    - kcsan: Turn report_filterlist_lock into a raw_spinlock
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-48875
+    - btrfs: don't take dev_replace rwsem on task already holding it
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57849
+    - s390/cpum_sf: Handle CPU hotplug remove during sampling
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57876
+    - drm/dp_mst: Fix resetting msg rx state after topology removal
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56616
+    - drm/dp_mst: Fix MST sideband message body length check
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-48881
+    - bcache: revert replacing IS_ERR_OR_NULL with IS_ERR again
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56619
+    - nilfs2: fix potential out-of-bounds memory access in nilfs_find_entry()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56622
+    - scsi: ufs: core: sysfs: Prevent div by zero
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56623
+    - scsi: qla2xxx: Fix use after free on unload
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57874
+    - arm64: ptrace: fix partial SETREGSET for NT_ARM_TAGGED_ADDR_CTRL
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56625
+    - can: dev: can_set_termination(): allow sleeping GPIOs
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56626
+    - ksmbd: fix Out-of-Bounds Write in ksmbd_vfs_stream_write
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56628
+    - LoongArch: Add architecture specific huge_pte_clear()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56629
+    - HID: wacom: fix when get product name maybe null pointer
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56630
+    - ocfs2: free inode when ocfs2_get_init_inode() fails
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56631
+    - scsi: sg: Fix slab-use-after-free read in sg_release()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-50051
+    - spi: mpc52xx: Add cancel_work_sync before module remove
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56633
+    - tcp_bpf: Fix the sk_mem_uncharge logic in tcp_bpf_sendmsg
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56565
+    - f2fs: fix to drop all discards after creating snapshot on lvm device
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56634
+    - gpio: grgpio: Add NULL check in grgpio_probe
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56635
+    - net: avoid potential UAF in default_operstate()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56636
+    - geneve: do not assume mac header is set in geneve_xmit_skb()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56637
+    - netfilter: ipset: Hold module reference while requesting a module
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56638
+    - netfilter: nft_inner: incorrect percpu area handling under softirq
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-52332
+    - igb: Fix potential invalid memory access in igb_init_module()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56640
+    - net/smc: fix LGR and link use-after-free issue
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56641
+    - net/smc: initialize close_work early to avoid warning
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56643
+    - dccp: Fix memory leak in dccp_feat_change_recv
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56644
+    - net/ipv6: release expired exception dst cached in socket
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56645
+    - can: j1939: j1939_session_new(): fix skb reference counting
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56648
+    - net: hsr: avoid potential out-of-bound access in fill_frame_info()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56649
+    - net: enetc: Do not configure preemptible TCs if SIs do not support
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56783
+    - netfilter: nft_socket: remove WARN_ON_ONCE on maximum cgroup level
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56650
+    - netfilter: x_tables: fix LED ID check in led_tg_check()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915)
+    - wifi: radiotap: Avoid -Wflex-array-member-not-at-end warnings
+    - ASoC: codecs: rt5640: Always disable IRQs from rt5640_cancel_work()
+    - ASoC: Intel: bytcr_rt5640: Add support for non ACPI instantiated codec
+    - ASoC: Intel: bytcr_rt5640: Add DMI quirk for Vexia Edu Atla 10 tablet
+    - ASoC: Intel: sst: Support LPE0F28 ACPI HID
+    - wifi: iwlwifi: mvm: Use the sync timepoint API in suspend
+    - mac80211: fix user-power when emulating chanctx
+    - usb: add support for new USB device ID 0x17EF:0x3098 for the r8152 driver
+    - selftests/watchdog-test: Fix system accidentally reset after watchdog-test
+    - ALSA: hda/realtek: Add subwoofer quirk for Infinix ZERO BOOK 13
+    - x86/amd_nb: Fix compile-testing without CONFIG_AMD_NB
+    - bpf: fix filed access without lock
+    - net: usb: qmi_wwan: add Quectel RG650V
+    - soc: qcom: Add check devm_kasprintf() returned value
+    - firmware: arm_scmi: Reject clear channel request on A2P
+    - regulator: rk808: Add apply_bit for BUCK3 on RK809
+    - platform/x86: dell-smbios-base: Extends support to Alienware products
+    - platform/x86: dell-wmi-base: Handle META key Lock/Unlock events
+    - ASoC: tas2781: Add new driver version for tas2563 & tas2781 qfn chip
+    - tools/lib/thermal: Remove the thermal.h soft link when doing make clean
+    - can: j1939: fix error in J1939 documentation.
+    - platform/x86: thinkpad_acpi: Fix for ThinkPad's with ECFW showing incorrect
+      fan speed
+    - ASoC: amd: yc: Support dmic on another model of Lenovo Thinkpad E14 Gen 6
+    - ASoC: stm: Prevent potential division by zero in stm32_sai_mclk_round_rate()
+    - ASoC: stm: Prevent potential division by zero in stm32_sai_get_clk_div()
+    - drm: panel-orientation-quirks: Make Lenovo Yoga Tab 3 X90F DMI match less
+      strict
+    - proc/softirqs: replace seq_printf with seq_put_decimal_ull_width
+    - ASoC: audio-graph-card2: Purge absent supplies for device tree nodes
+    - LoongArch: Define a default value for VM_DATA_DEFAULT_FLAGS
+    - ALSA: usb-audio: Fix Yamaha P-125 Quirk Entry
+    - ARM: 9420/1: smp: Fix SMP for xip kernels
+    - ipmr: Fix access to mfc_cache_list without lock held
+    - mptcp: fix possible integer overflow in mptcp_reset_tout_timer
+    - arm64: probes: Disable kprobes/uprobes on MOPS instructions
+    - kselftest/arm64: mte: fix printf type warnings about __u64
+    - kselftest/arm64: mte: fix printf type warnings about longs
+    - s390/cio: Do not unregister the subchannel based on DNV
+    - s390/pageattr: Implement missing kernel_page_present()
+    - ext4: avoid remount errors with 'abort' mount option
+    - mips: asm: fix warning when disabling MIPS_FP_SUPPORT
+    - m68k: mvme147: Fix SCSI controller IRQ numbers
+    - m68k: mvme147: Reinstate early console
+    - arm64: fix .data.rel.ro size assertion when CONFIG_LTO_CLANG
+    - acpi/arm64: Adjust error handling procedure in gtdt_parse_timer_block()
+    - cachefiles: Fix missing pos updates in cachefiles_ondemand_fd_write_iter()
+    - block: fix bio_split_rw_at to take zone_write_granularity into account
+    - s390/syscalls: Avoid creation of arch/arch/ directory
+    - ext4: remove calls to to set/clear the folio error flag
+    - ext4: pipeline buffer reads in mext_page_mkuptodate()
+    - ext4: remove array of buffer_heads from mext_page_mkuptodate()
+    - ext4: fix race in buffer_head read fault injection
+    - nvme-pci: reverse request order in nvme_queue_rqs
+    - virtio_blk: reverse request order in virtio_queue_rqs
+    - crypto: qat - remove check after debugfs_create_dir()
+    - firmware: google: Unregister driver_info on failure
+    - crypto: qat - remove faulty arbiter config reset
+    - thermal: core: Initialize thermal zones before registering them
+    - EDAC/fsl_ddr: Fix bad bit shift operations
+    - EDAC/skx_common: Differentiate memory error sources
+    - EDAC/{skx_common,i10nm}: Fix incorrect far-memory error source indicator
+    - crypto: cavium - Fix the if condition to exit loop after timeout
+    - amd-pstate: Set min_perf to nominal_perf for active mode performance gov
+    - crypto: hisilicon/qm - disable same error report before resetting
+    - crypto: inside-secure - Fix the return value of safexcel_xcbcmac_cra_init()
+    - doc: rcu: update printed dynticks counter bits
+    - hwmon: (pmbus_core) Allow to hook PMBUS_SMBALERT_MASK
+    - hwmon: (pmbus/core) clear faults after setting smbalert mask
+    - hwmon: (nct6775-core) Fix overflows seen when writing limit attributes
+    - ACPI: CPPC: Fix _CPC register setting issue
+    - crypto: caam - add error check to caam_rsa_set_priv_key_form
+    - crypto: cavium - Fix an error handling path in cpt_ucode_load_fw()
+    - rcuscale: Do a proper cleanup if kfree_scale_init() fails
+    - tools/lib/thermal: Make more generic the command encoding function
+    - thermal/lib: Fix memory leak on error in thermal_genl_auto()
+    - x86/unwind/orc: Fix unwind for newly forked tasks
+    - time: Partially revert cleanup on msecs_to_jiffies() documentation
+    - time: Fix references to _msecs_to_jiffies() handling of values
+    - kcsan, seqlock: Support seqcount_latch_t
+    - kcsan, seqlock: Fix incorrect assumption in read_seqbegin()
+    - clocksource/drivers:sp804: Make user selectable
+    - clocksource/drivers/timer-ti-dm: Fix child node refcount handling
+    - spi: spi-fsl-lpspi: Use IRQF_NO_AUTOEN flag in request_irq()
+    - microblaze: Export xmb_manager functions
+    - arm64: dts: mt8195: Fix dtbs_check error for mutex node
+    - arm64: dts: mt8195: Fix dtbs_check error for infracfg_ao node
+    - soc: ti: smartreflex: Use IRQF_NO_AUTOEN flag in request_irq()
+    - arm64: dts: qcom: sm6350: Fix GPU frequencies missing on some speedbins
+    - ARM: dts: microchip: sam9x60: Add missing property atmel,usart-mode
+    - mmc: mmc_spi: drop buggy snprintf()
+    - openrisc: Implement fixmap to fix earlycon
+    - efi/libstub: fix efi_parse_options() ignoring the default command line
+    - tpm: fix signed/unsigned bug when checking event logs
+    - media: i2c: ds90ub960: Fix missing return check on ub960_rxport_read call
+    - arm64: dts: mt8183: krane: Fix the address of eeprom at i2c4
+    - arm64: dts: mt8183: kukui: Fix the address of eeprom at i2c4
+    - arm64: dts: mediatek: mt8173-elm-hana: Add vdd-supply to second source
+      trackpad
+    - Revert "cgroup: Fix memory leak caused by missing cgroup_bpf_offline"
+    - cgroup/bpf: only cgroup v2 can be attached by bpf programs
+    - regulator: rk808: Restrict DVS GPIOs to the RK808 variant only
+    - arm64: dts: mt8183: fennel: add i2c2's i2c-scl-internal-delay-ns
+    - arm64: dts: mt8183: burnet: add i2c2's i2c-scl-internal-delay-ns
+    - arm64: dts: mt8183: cozmo: add i2c2's i2c-scl-internal-delay-ns
+    - arm64: dts: mt8183: Damu: add i2c2's i2c-scl-internal-delay-ns
+    - pwm: imx27: Workaround of the pwm output bug when decrease the duty cycle
+    - ARM: dts: cubieboard4: Fix DCDC5 regulator constraints
+    - arm64: dts: ti: k3-j7200: use ti,j7200-padconf compatible
+    - arm64: dts: ti: k3-j7200: Fix register map for main domain pmx
+    - arm64: dts: ti: k3-j7200: Fix clock ids for MCSPI instances
+    - arm64: dts: ti: k3-j721e: Fix clock IDs for MCSPI instances
+    - arm64: dts: ti: k3-j721s2: Fix clock IDs for MCSPI instances
+    - um: Unconditionally call unflatten_device_tree()
+    - x86/of: Unconditionally call unflatten_and_copy_device_tree()
+    - of/fdt: add dt_phys arg to early_init_dt_scan and early_init_dt_verify
+    - riscv: Fix wrong usage of __pa() on a fixmap address
+    - pmdomain: ti-sci: Add missing of_node_put() for args.np
+    - spi: tegra210-quad: Avoid shift-out-of-bounds
+    - spi: zynqmp-gqspi: Undo runtime PM changes at driver exit time​
+    - regmap: irq: Set lockdep class for hierarchical IRQ domains
+    - arm64: dts: renesas: hihope: Drop #sound-dai-cells
+    - arm64: dts: mediatek: Add ADC node on MT6357, MT6358, MT6359 PMICs
+    - arm64: dts: mediatek: mt6358: fix dtbs_check error
+    - arm64: dts: mediatek: mt8183-kukui-jacuzzi: Fix DP bridge supply names
+    - arm64: dts: mediatek: mt8183-kukui-jacuzzi: Add supplies for fixed
+      regulators
+    - selftests/resctrl: Split fill_buf to allow tests finer-grained control
+    - selftests/resctrl: Refactor fill_buf functions
+    - selftests/resctrl: Fix memory overflow due to unhandled wraparound
+    - selftests/resctrl: Protect against array overrun during iMC config parsing
+    - arm64: dts: rockchip: correct analog audio name on Indiedroid Nova
+    - platform/x86: panasonic-laptop: Return errno correctly in show callback
+    - drm/mm: Mark drm_mm_interval_tree*() functions with __maybe_unused
+    - drm/vc4: hvs: Don't write gamma luts on 2711
+    - drm/vc4: hvs: Fix dlist debug not resetting the next entry pointer
+    - drm/vc4: hvs: Remove incorrect limit from hvs_dlist debugfs function
+    - drm/vc4: hvs: Correct logic on stopping an HVS channel
+    - drm/omap: Fix possible NULL dereference
+    - drm/omap: Fix locking in omap_gem_new_dmabuf()
+    - wifi: p54: Use IRQF_NO_AUTOEN flag in request_irq()
+    - wifi: mwifiex: Use IRQF_NO_AUTOEN flag in request_irq()
+    - drm/imx/dcss: Use IRQF_NO_AUTOEN flag in request_irq()
+    - drm/imx/ipuv3: Use IRQF_NO_AUTOEN flag in request_irq()
+    - drm/v3d: Address race-condition in MMU flush
+    - wifi: ath10k: fix invalid VHT parameters in supported_vht_mcs_rate_nss1
+    - wifi: ath10k: fix invalid VHT parameters in supported_vht_mcs_rate_nss2
+    - dt-bindings: vendor-prefixes: Add NeoFidelity, Inc
+    - ASoC: fsl_micfil: fix regmap_write_bits usage
+    - ASoC: dt-bindings: mt6359: Update generic node name and dmic-mode
+    - drm/bridge: anx7625: Drop EDID cache on bridge power off
+    - drm/bridge: it6505: Drop EDID cache on bridge power off
+    - libbpf: Fix expected_attach_type set handling in program load callback
+    - libbpf: Fix output .symtab byte-order during linking
+    - bpf: Fix the xdp_adjust_tail sample prog issue
+    - wifi: ath11k: Fix CE offset address calculation for WCN6750 in SSR
+    - ice: consistently use q_idx in ice_vc_cfg_qs_msg()
+    - drm/vc4: Match drm_dev_enter and exit calls in vc4_hvs_atomic_flush
+    - libbpf: fix sym_is_subprog() logic for weak global subprogs
+    - ASoC: rt722-sdca: Remove logically deadcode in rt722-sdca.c
+    - libbpf: never interpret subprogs in .text as entry programs
+    - netdevsim: copy addresses for both in and out paths
+    - drm/bridge: tc358767: Fix link properties discovery
+    - selftests/bpf: Fix msg_verify_data in test_sockmap
+    - selftests/bpf: Fix txmsg_redir of test_txmsg_pull in test_sockmap
+    - drm: fsl-dcu: enable PIXCLK on LS1021A
+    - drm/msm/dpu: on SDM845 move DSPP_3 to LM_5 block
+    - drm/msm/dpu: drop LM_3 / LM_4 on SDM845
+    - drm/msm/dpu: drop LM_3 / LM_4 on MSM8998
+    - selftests/bpf: fix test_spin_lock_fail.c's global vars usage
+    - drm/panfrost: Remove unused id_mask from struct panfrost_model
+    - bpf, arm64: Remove garbage frame for struct_ops trampoline
+    - drm/msm/adreno: Use IRQF_NO_AUTOEN flag in request_irq()
+    - drm/msm/gpu: Check the status of registration to PM QoS
+    - drm/etnaviv: Request pages from DMA32 zone on addressing_limited
+    - drm/etnaviv: hold GPU lock across perfmon sampling
+    - wifi: wfx: Fix error handling in wfx_core_init()
+    - drm/msm/dpu: cast crtc_clk calculation to u64 in _dpu_core_perf_calc_clk()
+    - bpf, bpftool: Fix incorrect disasm pc
+    - drm/vkms: Drop unnecessary call to drm_crtc_cleanup()
+    - drm: use ATOMIC64_INIT() for atomic64_t
+    - netfilter: nf_tables: avoid false-positive lockdep splat on rule deletion
+    - netfilter: nf_tables: must hold rcu read lock while iterating expression
+      type list
+    - netfilter: nf_tables: skip transaction if update object is not implemented
+    - netfilter: nf_tables: must hold rcu read lock while iterating object type
+      list
+    - netlink: typographical error in nlmsg_type constants definition
+    - selftests/bpf: Add txmsg_pass to pull/push/pop in test_sockmap
+    - selftests/bpf: Fix SENDPAGE data logic in test_sockmap
+    - selftests/bpf: Fix total_bytes in msg_loop_rx in test_sockmap
+    - selftests/bpf: Add push/pop checking for msg_verify_data in test_sockmap
+    - bpf, sockmap: Several fixes to bpf_msg_push_data
+    - bpf, sockmap: Fix sk_msg_reset_curr
+    - sock_diag: add module pointer to "struct sock_diag_handler"
+    - sock_diag: allow concurrent operations
+    - sock_diag: allow concurrent operation in sock_diag_rcv_msg()
+    - net: use unrcu_pointer() helper
+    - selftests: net: really check for bg process completion
+    - drm/amdkfd: Fix wrong usage of INIT_WORK()
+    - bpf: Force uprobe bpf program to always return 0
+    - net: rfkill: gpio: Add check for clk_enable()
+    - netpoll: Use rcu_access_pointer() in netpoll_poll_lock
+    - wireguard: selftests: load nf_conntrack if not present
+    - cppc_cpufreq: Use desired perf if feedback ctrs are 0 or unchanged
+    - clk: mediatek: drop two dead config options
+    - [Config] drop COMMON_CLK_MT8195_AUDSYS and COMMON_CLK_MT8195_MSDC
+    - trace/trace_event_perf: remove duplicate samples on the first tracepoint
+      event
+    - pinctrl: zynqmp: drop excess struct member description
+    - scsi: hisi_sas: Enable all PHYs that are not disabled by user during
+      controller reset
+    - mfd: tps65010: Use IRQF_NO_AUTOEN flag in request_irq() to fix race
+    - mfd: da9052-spi: Change read-mask to write-mask
+    - cpufreq: loongson2: Unregister platform_driver on failure
+    - powerpc/fadump: Refactor and prepare fadump_cma_init for late init
+    - mtd: hyperbus: rpc-if: Add missing MODULE_DEVICE_TABLE
+    - mtd: rawnand: atmel: Fix possible memory leak
+    - mtd: rawnand: fix double free in atmel_pmecc_create_user()
+    - mtd: spi-nor: spansion: Use nor->addr_nbytes in octal DTR mode in
+      RD_ANY_REG_OP
+    - RDMA/hns: Fix an AEQE overflow error caused by untimely update of eq_db_ci
+    - RDMA/hns: Use dev_* printings in hem code instead of ibdev_*
+    - RDMA/bnxt_re: Check cqe flags to know imm_data vs inv_irkey
+    - clk: sunxi-ng: d1: Fix PLL_AUDIO0 preset
+    - clk: renesas: rzg2l: Fix FOUTPOSTDIV clk
+    - RDMA/rxe: Set queue pair cur_qp_state when being queried
+    - RISC-V: KVM: Fix APLIC in_clrip and clripnum write emulation
+    - clk: imx: lpcg-scu: SW workaround for errata (e10858)
+    - clk: imx: fracn-gppll: correct PLL initialization flow
+    - clk: imx: fracn-gppll: fix pll power up
+    - clk: imx: clk-scu: fix clk enable state save and restore
+    - clk: imx: imx8-acm: Fix return value check in
+      clk_imx_acm_attach_pm_domains()
+    - iommu/vt-d: Fix checks and print in dmar_fault_dump_ptes()
+    - iommu/vt-d: Fix checks and print in pgtable_walk()
+    - checkpatch: check for missing Fixes tags
+    - checkpatch: always parse orig_commit in fixes tag
+    - mfd: rt5033: Fix missing regmap_del_irq_chip()
+    - fs/proc/kcore.c: fix coccinelle reported ERROR instances
+    - scsi: fusion: Remove unused variable 'rc'
+    - scsi: sg: Enable runtime power management
+    - x86/tdx: Introduce wrappers to read and write TD metadata
+    - x86/tdx: Rename tdx_parse_tdinfo() to tdx_setup()
+    - x86/tdx: Dynamically disable SEPT violations from causing #VEs
+    - RDMA/hns: Fix out-of-order issue of requester when setting FENCE
+    - cpufreq: CPPC: Fix wrong return value in cppc_get_cpu_cost()
+    - cpufreq: CPPC: Fix wrong return value in cppc_get_cpu_power()
+    - dax: delete a stale directory pmem
+    - KVM: PPC: Book3S HV: Stop using vc->dpdes for nested KVM guests
+    - KVM: PPC: Book3S HV: Avoid returning to nested hypervisor on pending
+      doorbells
+    - powerpc/sstep: make emulate_vsx_load and emulate_vsx_store static
+    - powerpc/kexec: Fix return of uninitialized variable
+    - IB/mlx5: Allocate resources just before first QP/SRQ is created
+    - clk: ralink: mtmips: fix clock plan for Ralink SoC RT3883
+    - clk: ralink: mtmips: remove duplicated 'xtal' clock for Ralink SoC RT3883
+    - dt-bindings: clock: axi-clkgen: include AXI clk
+    - clk: clk-axi-clkgen: make sure to enable the AXI bus clock
+    - arm64: dts: qcom: sc8180x: Add a SoC-specific compatible to cpufreq-hw
+    - pinctrl: k210: Undef K210_PC_DEFAULT
+    - smb: cached directories can be more than root file handle
+    - mailbox: arm_mhuv2: clean up loop in get_irq_chan_comb()
+    - perf cs-etm: Don't flush when packet_queue fills up
+    - gfs2: Get rid of gfs2_glock_queue_put in signal_our_withdraw
+    - gfs2: Replace gfs2_glock_queue_put with gfs2_glock_put_async
+    - gfs2: Rename GLF_VERIFY_EVICT to GLF_VERIFY_DELETE
+    - gfs2: Allow immediate GLF_VERIFY_DELETE work
+    - gfs2: Fix unlinked inode cleanup
+    - perf stat: Close cork_fd when create_perf_stat_counter() failed
+    - perf stat: Fix affinity memory leaks on error path
+    - perf trace: Keep exited threads for summary
+    - perf test attr: Add back missing topdown events
+    - f2fs: compress: fix inconsistent update of i_blocks in
+      release_compress_blocks and reserve_compress_blocks
+    - perf probe: Fix libdw memory leak
+    - perf probe: Correct demangled symbols in C++ program
+    - rust: macros: fix documentation of the paste! macro
+    - PCI: cpqphp: Use PCI_POSSIBLE_ERROR() to check config reads
+    - PCI: cpqphp: Fix PCIBIOS_* return value confusion
+    - perf ftrace latency: Fix unit on histogram first entry when using --use-nsec
+    - f2fs: fix the wrong f2fs_bug_on condition in f2fs_do_replace_block
+    - f2fs: check curseg->inited before write_sum_page in change_curseg
+    - f2fs: fix to avoid use GC_AT when setting gc_mode as GC_URGENT_LOW or
+      GC_URGENT_MID
+    - PCI: cadence: Extract link setup sequence from cdns_pcie_host_setup()
+    - PCI: cadence: Set cdns_pcie_host_init() global
+    - PCI: j721e: Add reset GPIO to struct j721e_pcie
+    - PCI: j721e: Use T_PERST_CLK_US macro
+    - PCI: j721e: Add suspend and resume support
+    - PCI: j721e: Deassert PERST# after a delay of PCIE_T_PVPERL_MS milliseconds
+    - f2fs: fix to avoid forcing direct write to use buffered IO on inline_data
+      inode
+    - perf trace: avoid garbage when not printing a trace event's arguments
+    - m68k: mcfgpio: Fix incorrect register offset for CONFIG_M5441x
+    - m68k: coldfire/device.c: only build FEC when HW macros are defined
+    - perf list: Fix topic and pmu_name argument order
+    - perf trace: Fix tracing itself, creating feedback loops
+    - perf trace: Do not lose last events in a race
+    - perf trace: Avoid garbage when not printing a syscall's arguments
+    - remoteproc: qcom: pas: add minidump_id to SM8350 resources
+    - rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name length
+    - remoteproc: qcom_q6v5_mss: Re-order writes to the IMEM region
+    - nfsd: restore callback functionality for NFSv4.0
+    - NFSD: Cap the number of bytes copied by nfs4_reset_recoverydir()
+    - NFSD: Fix nfsd4_shutdown_copy()
+    - hwmon: (tps23861) Fix reporting of negative temperatures
+    - vdpa/mlx5: Fix suboptimal range on iotlb iteration
+    - selftests/mount_setattr: Fix failures on 64K PAGE_SIZE kernels
+    - gpio: zevio: Add missed label initialisation
+    - fs_parser: update mount_api doc to match function signature
+    - LoongArch: Fix build failure with GCC 15 (-std=gnu23)
+    - LoongArch: BPF: Sign-extend return values
+    - power: supply: core: Remove might_sleep() from power_supply_put()
+    - power: supply: bq27xxx: Fix registers of bq27426
+    - power: supply: rt9471: Fix wrong WDT function regfield declaration
+    - power: supply: rt9471: Use IC status regfield to report real charger status
+    - net: usb: lan78xx: Fix memory leak on device unplug by freeing PHY device
+    - tg3: Set coherent DMA mask bits to 31 for BCM57766 chipsets
+    - net: usb: lan78xx: Fix refcounting and autosuspend on invalid WoL
+      configuration
+    - net: microchip: vcap: Add typegroup table terminators in kunit tests
+    - net/ipv6: delete temporary address if mngtmpaddr is removed or unmanaged
+    - net: mdio-ipq4019: add missing error check
+    - marvell: pxa168_eth: fix call balance of pep->clk handling routines
+    - net: stmmac: dwmac-socfpga: Set RX watchdog interrupt as broken
+    - octeontx2-af: RPM: Fix mismatch in lmac type
+    - octeontx2-af: RPM: Fix low network performance
+    - octeontx2-pf: Reset MAC stats during probe
+    - octeontx2-af: RPM: fix stale RSFEC counters
+    - octeontx2-af: RPM: fix stale FCFEC counters
+    - octeontx2-af: Quiesce traffic before NIX block reset
+    - spi: atmel-quadspi: Fix register name in verbose logging function
+    - net: hsr: fix hsr_init_sk() vs network/transport headers.
+    - bnxt_en: Reserve rings after PCIe AER recovery if NIC interface is down
+    - bnxt_en: Refactor bnxt_ptp_init()
+    - bnxt_en: Unregister PTP during PCI shutdown and suspend
+    - llc: Improve setsockopt() handling of malformed user input
+    - rxrpc: Improve setsockopt() handling of malformed user input
+    - tcp: Fix use-after-free of nreq in reqsk_timer_handler().
+    - ip6mr: fix tables suspicious RCU usage
+    - ipmr: fix tables suspicious RCU usage
+    - iio: light: al3010: Fix an error handling path in al3010_probe()
+    - usb: using mutex lock and supporting O_NONBLOCK flag in iowarrior_read()
+    - usb: yurex: make waiting on yurex_write interruptible
+    - USB: chaoskey: fail open after removal
+    - USB: chaoskey: Fix possible deadlock chaoskey_list_lock
+    - misc: apds990x: Fix missing pm_runtime_disable()
+    - counter: stm32-timer-cnt: Add check for clk_enable()
+    - counter: ti-ecap-capture: Add check for clk_enable()
+    - ALSA: hda/realtek: Update ALC256 depop procedure
+    - drm/radeon: add helper rdev_to_drm(rdev)
+    - drm/radeon: change rdev->ddev to rdev_to_drm(rdev)
+    - drm/radeon: Fix spurious unplug event on radeon HDMI
+    - apparmor: fix 'Do simple duplicate message elimination'
+    - ASoC: amd: yc: Fix for enabling DMIC on acp6x via _DSD entry
+    - gfs2: Don't set GLF_LOCK in gfs2_dispose_glock_lru
+    - gfs2: Remove and replace gfs2_glock_queue_work
+    - f2fs: fix fiemap failure issue when page size is 16KB
+    - usb: ehci-spear: fix call balance of sehci clk handling routines
+    - ALSA: usb-audio: Fix a DMA to stack memory bug
+    - ASoC: Intel: sst: Fix used of uninitialized ctx to log an error
+    - soc: qcom: socinfo: fix revision check in qcom_socinfo_probe()
+    - ext4: supress data-race warnings in ext4_free_inodes_{count,set}()
+    - ext4: fix FS_IOC_GETFSMAP handling
+    - jfs: xattr: check invalid xattr size more strictly
+    - ASoC: amd: yc: Add a quirk for microfone on Lenovo ThinkPad P14s Gen 5
+      21MES00B00
+    - ASoC: codecs: Fix atomicity violation in snd_soc_component_get_drvdata()
+    - perf/x86/intel/pt: Fix buffer full but size is 0 case
+    - crypto: x86/aegis128 - access 32-bit arguments as 32-bit
+    - KVM: x86/mmu: Skip the "try unsync" path iff the old SPTE was a leaf SPTE
+    - powerpc/pseries: Fix KVM guest detection for disabling hardlockup detector
+    - KVM: arm64: vgic-v3: Sanitise guest writes to GICR_INVLPIR
+    - KVM: arm64: Ignore PMCNTENSET_EL0 while checking for overflow status
+    - KVM: arm64: vgic-its: Clear ITE when DISCARD frees an ITE
+    - KVM: arm64: vgic-its: Add a data length check in vgic_its_save_*
+    - KVM: arm64: vgic-its: Clear DTE when MAPD unmaps a device
+    - fsnotify: fix sending inotify event with unexpected filename
+    - tty: ldsic: fix tty_ldisc_autoload sysctl's proc_handler
+    - locking/lockdep: Avoid creating new name string literals in
+      lockdep_set_subclass()
+    - tools/nolibc: s390: include std.h
+    - pinctrl: qcom: spmi: fix debugfs drive strength
+    - dt-bindings: iio: dac: ad3552r: fix maximum spi speed
+    - exfat: fix uninit-value in __exfat_get_dentry_set
+    - Bluetooth: Fix type of len in rfcomm_sock_getsockopt{,_old}()
+    - Compiler Attributes: disable __counted_by for clang < 19.1.3
+    - usb: xhci: Fix TD invalidation under pending Set TR Dequeue
+    - ARM: dts: omap36xx: declare 1GHz OPP as turbo again
+    - wifi: brcmfmac: release 'root' node in all execution paths
+    - Revert "usb: gadget: composite: fix OS descriptors w_value logic"
+    - gpio: exar: set value when external pull-up or pull-down is present
+    - spi: Fix acpi deferred irq probe
+    - cpufreq: mediatek-hw: Fix wrong return value in mtk_cpufreq_get_cpu_power()
+    - cifs: support mounting with alternate password to allow password rotation
+    - parisc/ftrace: Fix function graph tracing disablement
+    - platform/chrome: cros_ec_typec: fix missing fwnode reference decrement
+    - ubi: wl: Put source PEB into correct list if trying locking LEB failed
+    - dt-bindings: serial: rs485: Fix rs485-rts-delay property
+    - serial: 8250_fintek: Add support for F81216E
+    - serial: 8250: omap: Move pm_runtime_get_sync
+    - iio: gts: Fix uninitialized symbol 'ret'
+    - ublk: fix ublk_ch_mmap() for 64K page size
+    - arm64: tls: Fix context-switching of tpidrro_el0 when kpti is enabled
+    - block: fix missing dispatching request when queue is started or unquiesced
+    - block: fix ordering between checking QUEUE_FLAG_QUIESCED request adding
+    - block: fix ordering between checking BLK_MQ_S_STOPPED request adding
+    - blk-mq: Make blk_mq_quiesce_tagset() hold the tag list mutex less long
+    - HID: wacom: Interpret tilt data from Intuos Pro BT as signed values
+    - soc: fsl: rcpm: fix missing of_node_put() in copy_ippdexpcr1_setting()
+    - media: v4l2-core: v4l2-dv-timings: check cvt/gtf result
+    - ALSA: ump: Fix evaluation of MIDI 1.0 FB info
+    - ALSA: hda/realtek: Update ALC225 depop procedure
+    - ALSA: hda/realtek: Fixup ALC225 depop procedure
+    - ALSA: hda/realtek: Set PCBeep to default value for ALC274
+    - ALSA: hda/realtek: Fix Internal Speaker and Mic boost of Infinix Y4 Max
+    - ALSA: hda/realtek: Apply quirk for Medion E15433
+    - smb3: request handle caching when caching directories
+    - smb: client: handle max length for SMB symlinks
+    - cifs: Add tracing for the cifs_tcon struct refcounting
+    - usb: dwc3: gadget: Fix checking for number of TRBs left
+    - ublk: fix error code for unsupported command
+    - lib: string_helpers: silence snprintf() output truncation warning
+    - um: Fix the return value of elf_core_copy_task_fpregs
+    - um: Always dump trace for specified task in show_stack
+    - rtc: st-lpc: Use IRQF_NO_AUTOEN flag in request_irq()
+    - rtc: abx80x: Fix WDT bit position of the status register
+    - ubi: fastmap: wl: Schedule fm_work if wear-leveling pool is empty
+    - ubifs: Correct the total block count by deducting journal reservation
+    - jffs2: fix use of uninitialized variable
+    - rtc: rzn1: fix BCD to rtc_time conversion errors
+    - nvme-multipath: prepare for "queue-depth" iopolicy
+    - nvme-multipath: implement "queue-depth" iopolicy
+    - nvme-multipath: avoid hang on inaccessible namespaces
+    - nvme/multipath: Fix RCU list traversal to use SRCU primitive
+    - block: return unsigned int from bdev_io_min
+    - 9p/xen: fix init sequence
+    - perf/arm-smmuv3: Fix lockdep assert in ->event_init()
+    - perf/arm-cmn: Ensure port and device id bits are set properly
+    - smb: client: disable directory caching when dir_cache_timeout is zero
+    - cifs: Fix parsing native symlinks relative to the export
+    - cifs: Fix parsing reparse point with native symlink in SMB1 non-UNICODE
+      session
+    - rtc: ab-eoz9: don't fail temperature reads on undervoltage notification
+    - init/modpost: conditionally check section mismatch to __meminit*
+    - Rename .data.unlikely to .data..unlikely
+    - Rename .data.once to .data..once to fix resetting WARN*_ONCE
+    - modpost: remove incorrect code in do_eisa_entry()
+    - cifs: during remount, make sure passwords are in sync
+    - cifs: unlock on error in smb3_reconfigure()
+    - nfs: ignore SB_RDONLY when mounting nfs
+    - SUNRPC: timeout and cancel TLS handshake with -ETIMEDOUT
+    - xfs: remove unknown compat feature check in superblock write validation
+    - btrfs: don't loop for nowait writes when checking for cross references
+    - md/md-bitmap: Add missing destroy_work_on_stack()
+    - arm64: dts: allwinner: pinephone: Add mount matrix to accelerometer
+    - arm64: dts: freescale: imx8mm-verdin: Fix SD regulator startup delay
+    - arm64: dts: ti: k3-am62-verdin: Fix SD regulator startup delay
+    - media: i2c: dw9768: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - arm64: dts: freescale: imx8mp-verdin: Fix SD regulator startup delay
+    - media: imx-jpeg: Fix potential error pointer dereference in detach_pm()
+    - media: verisilicon: av1: Fix reference video buffer pointer assignment
+    - media: platform: exynos4-is: Fix an OF node reference leak in
+      fimc_md_is_isp_available
+    - media: amphion: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - media: venus: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - media: gspca: ov534-ov772x: Fix off-by-one error in set_frame_rate()
+    - media: uvcvideo: Stop stream during unregister
+    - maple_tree: refine mas_store_root() on storing NULL
+    - vmstat: call fold_vm_zone_numa_events() before show per zone NUMA event
+    - zram: clear IDLE flag after recompression
+    - iommu/io-pgtable-arm: Fix stage-2 map/unmap for concatenated tables
+    - leds: lp55xx: Remove redundant test for invalid channel number
+    - clk: qcom: gcc-qcs404: fix initial rate of GPLL3
+    - ARM: 9429/1: ioremap: Sync PGDs for VMALLOC shadow
+    - ARM: 9430/1: entry: Do a dummy read from VMAP shadow
+    - ARM: 9431/1: mm: Pair atomic_set_release() with _read_acquire()
+    - ceph: extract entity name from device id
+    - util_macros.h: fix/rework find_closest() macros
+    - scsi: ufs: exynos: Fix hibern8 notify callbacks
+    - i3c: master: svc: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - PCI: keystone: Set mode as Root Complex for "ti,keystone-pcie" compatible
+    - PCI: keystone: Add link up check to ks_pcie_other_map_bus()
+    - PCI: endpoint: Clear secondary (not primary) EPC in pci_epc_remove_epf()
+    - fs/proc/kcore.c: Clear ret value in read_kcore_iter after successful
+      iov_iter_zero
+    - thermal: int3400: Fix reading of current_uuid for active policy
+    - leds: flash: mt6360: Fix device_for_each_child_node() refcounting in error
+      paths
+    - ovl: properly handle large files in ovl_security_fileattr
+    - dm: Fix typo in error message
+    - dm thin: Add missing destroy_work_on_stack()
+    - PCI: of_property: Assign PCI instead of CPU bus address to dynamic PCI nodes
+    - PCI: rockchip-ep: Fix address translation unit programming
+    - iio: accel: kx022a: Fix raw read format
+    - iio: Fix fwnode_handle in __fwnode_iio_channel_get_by_name()
+    - iio: gts: fix infinite loop for gain_to_scaletables()
+    - powerpc: Fix stack protector Kconfig test for clang
+    - powerpc: Adjust adding stack protector flags to KBUILD_CLAGS for clang
+    - udmabuf: use vmf_insert_pfn and VM_PFNMAP for handling mmap
+    - drm/mediatek: Fix child node refcount handling in early exit
+    - drm/etnaviv: flush shader L1 cache after user commandstream
+    - drm: xlnx: zynqmp_dpsub: fix hotplug detection
+    - drm/amdkfd: Use the correct wptr size
+    - drm/amd/pm: update current_socclk and current_uclk in gpu_metrics on smu
+      v13.0.7
+    - posix-timers: Target group sigqueue to current task only if not exiting
+    - wifi: cfg80211: Add wiphy_delayed_work_pending()
+    - wifi: mac80211: Convert color collision detection to wiphy work
+    - spi: stm32: fix missing device mode capability in stm32mp25
+    - usb: typec: use cleanup facility for 'altmodes_node'
+    - platform/x86: ideapad-laptop: add missing Ideapad Pro 5 fn keys
+    - integrity: Avoid -Wflex-array-member-not-at-end warnings
+    - integrity: Use static_assert() to check struct sizes
+    - ASoC: max9768: Fix event generation for playback mute
+    - ARM: 9434/1: cfi: Fix compilation corner case
+    - drm/amd/display: Skip Invalid Streams from DSC Policy
+    - drm/amd/display: Fix DSC-re-computing
+    - drm/amd/display: Fix incorrect DSC recompute trigger
+    - s390/facilities: Fix warning about shadow of global variable
+    - cachefiles: Fix incorrect length return value in
+      cachefiles_ondemand_fd_write_iter()
+    - thermal: core: Drop thermal_zone_device_is_enabled()
+    - thermal: core: Synchronize suspend-prepare and post-suspend actions
+    - thermal: core: Rearrange PM notification code
+    - thermal: core: Represent suspend-related thermal zone flags as bits
+    - thermal: core: Mark thermal zones as initializing to start with
+    - thermal: core: Fix race between zone registration and system suspend
+    - crypto: qat - Fix missing destroy_workqueue in adf_init_aer()
+    - sched/cpufreq: Ensure sd is rebuilt for EAS check
+    - cleanup: Remove address space of returned pointer
+    - ARM: dts: renesas: genmai: Fix partition size for QSPI NOR Flash
+    - arm64: dts: mediatek: mt8395-genio-1200-evk: Fix dtbs_check error for phy
+    - scripts/kernel-doc: Do not track section counter across processed files
+    - arm64: dts: qcom: x1e80100: Resize GIC Redistributor register region
+    - scripts/kernel-doc: add modeline for vim users
+    - scripts/kernel-doc: simplify function printing
+    - scripts/kernel-doc: separate out function signature
+    - scripts/kernel-doc: simplify signature printing
+    - doc: kerneldoc.py: fix indentation
+    - kernel-doc: allow object-like macros in ReST output
+    - arm64: dts: mediatek: mt8188: Fix USB3 PHY port default status
+    - arm64: dts: rockchip: Remove 'enable-active-low' from two boards
+    - arm64: dts: qcom: x1e80100: Update C4/C5 residency/exit numbers
+    - dt-bindings: cache: qcom,llcc: Fix X1E80100 reg entries
+    - pwm: Assume a disabled PWM to emit a constant inactive output
+    - drm/imagination: Convert to use time_before macro
+    - drm/imagination: Use pvr_vm_context_get()
+    - drm/v3d: Flush the MMU before we supply more memory to the binner
+    - drm/amdgpu: Fix JPEG v4.0.3 register write
+    - ASoC: fsl-asoc-card: Add missing handling of {hp,mic}-dt-gpios
+    - wifi: rtl8xxxu: Perform update_beacon_work when beaconing is enabled
+    - selftests/bpf: netns_new() and netns_free() helpers.
+    - selftests/bpf: Fix backtrace printing for selftests crashes
+    - selftests/bpf: add missing header include for htons
+    - drm/vc4: hdmi: Increase audio MAI fifo dreq threshold
+    - drm/vc4: Introduce generation number enum
+    - drm/vc4: Match drm_dev_enter and exit calls in vc4_hvs_lut_load
+    - drm/vc4: Correct generation check in vc4_hvs_lut_load
+    - bpf: Tighten tail call checks for lingering locks, RCU, preempt_disable
+    - drm/panfrost: Add missing OPP table refcnt decremental
+    - selftests: netfilter: Fix missing return values in conntrack_dump_flush
+    - Bluetooth: btintel: Do no pass vendor events to stack
+    - Bluetooth: btbcm: fix missing of_node_put() in btbcm_get_board_name()
+    - Bluetooth: ISO: Use kref to track lifetime of iso_conn
+    - Bluetooth: ISO: Do not emit LE PA Create Sync if previous is pending
+    - Bluetooth: hci_conn: Use __counted_by() to avoid -Wfamnae warning
+    - Bluetooth: hci_conn: Use struct_size() in hci_le_big_create_sync()
+    - Bluetooth: ISO: Do not emit LE BIG Create Sync if previous is pending
+    - Bluetooth: ISO: Send BIG Create Sync via hci_sync
+    - Bluetooth: iso: Fix circular lock in iso_conn_big_sync
+    - net: txgbe: remove GPIO interrupt controller
+    - net: txgbe: fix null pointer to pcs
+    - RDMA/core: Provide rdma_user_mmap_disassociate() to disassociate mmap pages
+    - RDMA/hns: Disassociate mmap pages for all uctx when HW is being reset
+    - iommu/amd: Remove amd_iommu_domain_update() from page table freeing
+    - iommu/amd/pgtbl_v2: Take protection domain lock before invalidating TLB
+    - RDMA/hns: Fix flush cqe error when racing with destroy qp
+    - RDMA/hns: Modify debugfs name
+    - leds: max5970: Fix unreleased fwnode_handle in probe function
+    - kasan: move checks to do_strncpy_from_user
+    - kunit: skb: use "gfp" variable instead of hardcoding GFP_KERNEL
+    - RDMA/hns: Fix different dgids mapping to the same dip_idx
+    - RDMA/hns: Fix accessing invalid dip_ctx during destroying QP
+    - rust: kernel: add srctree-relative doclinks
+    - rust: kernel: fix THIS_MODULE header path in ThisModule doc comment
+    - i3c: master: Remove i3c_dev_disable_ibi_locked(olddev) on device hotjoin
+    - remoteproc: qcom: pas: Remove subdevs on the error path of adsp_probe()
+    - remoteproc: qcom: adsp: Remove subdevs on the error path of adsp_probe()
+    - nfsd: Revert "nfsd: release svc_expkey/svc_export with rcu_work"
+    - f2fs: clean up val{>>,<<}F2FS_BLKSIZE_BITS
+    - f2fs: fix to do cast in F2FS_{BLK_TO_BYTES, BTYES_TO_BLK} to avoid overflow
+    - vfio/mlx5: Fix unwind flows in mlx5vf_pci_save/resume_device_data()
+    - exfat: fix file being changed by unaligned direct write
+    - bnxt_en: Set backplane link modes correctly for ethtool
+    - devres: Fix page faults when tracing devres from unloaded modules
+    - usb: gadget: uvc: wake pump everytime we update the free list
+    - drm/xe/ufence: Wake up waiters after setting ufence->signalled
+    - net_sched: sch_fq: don't follow the fast path if Tx is behind now
+    - ASoC: da7213: Populate max_register to regmap_config
+    - KVM: x86: switch hugepage recovery thread to vhost_task
+    - kvm: defer huge page recovery vhost task to later
+    - KVM: x86/mmu: Ensure NX huge page recovery thread is alive before waking
+    - KVM: arm64: Change kvm_handle_mmio_return() return polarity
+    - dt-bindings: pinctrl: samsung: Fix interrupt constraint for variants with
+      fallbacks
+    - xhci: Fix control transfer error on Etron xHCI host
+    - xhci: Combine two if statements for Etron xHCI host
+    - xhci: Don't perform Soft Retry for Etron xHCI host
+    - xhci: Don't issue Reset Device command to Etron xHCI host
+    - mtd: spi-nor: core: replace dummy buswidth from addr to data
+    - Revert "mtd: spi-nor: core: replace dummy buswidth from addr to data"
+    - RISC-V: Scalar unaligned access emulated on hotplug CPUs
+    - serial: amba-pl011: Fix RX stall when DMA is used
+    - serial: amba-pl011: fix build regression
+    - i40e: Fix handling changed priv flags
+    - netdev-genl: Hold rcu_read_lock in napi_get
+    - usb: misc: ljca: set small runtime autosuspend delay
+    - usb: misc: ljca: move usb_autopm_put_interface() after wait for response
+    - blk-mq: add non_owner variant of start_freeze/unfreeze queue APIs
+    - block: model freeze & enter queue as lock for supporting lockdep
+    - block: always verify unfreeze lock on the owner task
+    - x86/Documentation: Update algo in init_size description of boot protocol
+    - kbuild: deb-pkg: Don't fail if modules.order is missing
+    - tools/power turbostat: Fix trailing '\n' parsing
+    - block: don't verify IO lock for freeze/unfreeze in elevator_init_mq()
+    - zram: permit only one post-processing operation at a time
+    - perf jevents: Don't stop at the first matched pmu when searching a events
+      table
+    - docs: media: update location of the media patches
+    - Revert "KVM: VMX: Move LOAD_IA32_PERF_GLOBAL_CTRL errata handling out of
+      setup_vmcs_config()"
+    - soc: fsl: cpm1: qmc: Fix blank line and spaces
+    - soc: fsl: cpm1: qmc: Re-order probe() operations
+    - soc: fsl: cpm1: qmc: Introduce qmc_init_resource() and its CPM1 version
+    - soc: fsl: cpm1: qmc: Introduce qmc_{init,exit}_xcc() and their CPM1 version
+    - soc: fsl: cpm1: qmc: Set the ret error code on platform_get_irq() failure
+    - x86/mm: Carve out INVLPG inline asm for use by others
+    - ALSA: hda/realtek: Enable mic on Vaio VJFH52
+    - ALSA: hda/realtek: Enable speaker pins for Medion E15443 platform
+    - ALSA: hda/realtek: fix mute/micmute LEDs don't work for EliteBook X G1i
+    - usb: dwc3: gadget: Add missing check for single port RAM in TxFIFO resizing
+      logic
+    - sched: Initialize idle tasks only once
+    - Upstream stable to v6.6.64, v6.11.11, v6.12.1, v6.12.2, v6.12.3
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53222
+    - zram: fix NULL pointer in comp_algorithm_show()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53169
+    - nvme-fabrics: fix kernel crash while shutting down controller
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56721
+    - x86/CPU/AMD: Terminate the erratum_1386_microcode array
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53187
+    - io_uring: check for overflows in io_pin_pages
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53147
+    - exfat: fix out-of-bounds access of directory entries
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53196
+    - KVM: arm64: Don't retire aborted MMIO instruction
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56685
+    - ASoC: mediatek: Check num_codecs is not zero to avoid panic during probe
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53201
+    - drm/amd/display: Fix null check for pipe_ctx->plane_state in
+      dcn20_program_pipe
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53203
+    - usb: typec: fix potential array underflow in ucsi_ccg_sync_control()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53209
+    - bnxt_en: Fix receive ring space parameters when XDP is active
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56742
+    - vfio/mlx5: Fix an unwind issue in mlx5vf_add_migration_pages()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53216
+    - nfsd: release svc_expkey/svc_export with rcu_work
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53219
+    - virtiofs: use pages instead of pointer for kernel direct IO
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53221
+    - f2fs: fix null-ptr-deref in f2fs_submit_page_bio()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53228
+    - riscv: kvm: Fix out-of-bounds array access
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53232
+    - iommu/s390: Implement blocking domain
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53236
+    - xsk: Free skb when TX metadata options are invalid
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56703
+    - ipv6: Fix soft lockups in fib6_select_path under high next hop churn
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56540
+    - accel/ivpu: Prevent recovery invocation during probe and resume
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53163
+    - crypto: qat/qat_420xx - fix off by one in uof_get_name()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56755
+    - netfs/fscache: Add a memory barrier for FSCACHE_VOLUME_CREATING
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56549
+    - cachefiles: Fix NULL pointer dereference in object->file
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56551
+    - drm/amdgpu: fix usage slab after free
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56776
+    - drm/sti: avoid potential dereference of error pointers
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56777
+    - drm/sti: avoid potential dereference of error pointers in
+      sti_gdp_atomic_check
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56778
+    - drm/sti: avoid potential dereference of error pointers in
+      sti_hqvdp_atomic_check
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56557
+    - iio: adc: ad7923: Fix buffer overflow for tx_buf and ring_xfer
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56779
+    - nfsd: fix nfs4_openowner leak when concurrent nfsd4_open occur
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56558
+    - nfsd: make sure exp active before svc_export_show
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56562
+    - i3c: master: Fix miss free init_dyn_addr at i3c_master_put_i3c_addrs()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56566
+    - mm/slub: Avoid list corruption when removing a slab from the full list
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-57838
+    - s390/entry: Mark IRQ entries to fix stack depot warnings
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56567
+    - ad7780: fix division by zero in ad7780_write_raw()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56569
+    - ftrace: Fix regression with module command in stack_trace_filter
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56570
+    - ovl: Filter invalid inodes with missing lookup function
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56572
+    - media: platform: allegro-dvt: Fix possible memory leak in
+      allocate_buffers_internal()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56573
+    - efi/libstub: Free correct pointer on failure
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56574
+    - media: ts2020: fix null-ptr-deref in ts2020_probe()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56575
+    - media: imx-jpeg: Ensure power suppliers be suspended before detach them
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56576
+    - media: i2c: tc358743: Fix crash in the probe error path when using polling
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56577
+    - media: mtk-jpeg: Fix null-ptr-deref during unload module
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56578
+    - media: imx-jpeg: Set video drvdata before register video device
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56579
+    - media: amphion: Set video drvdata before register video device
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56581
+    - btrfs: ref-verify: fix use-after-free after invalid ref action
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56774
+    - btrfs: add a sanity check for btrfs root in btrfs_search_slot()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56780
+    - quota: flush quota_release_work upon quota writeback
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53168
+    - sunrpc: fix one UAF issue caused by sunrpc kernel tcp socket
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56688
+    - sunrpc: clear XPRT_SOCK_UPD_TIMEOUT when reset transport
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56729
+    - smb: Initialize cfid->tcon before performing network ops
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56704
+    - 9p/xen: fix release of IRQ
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53171
+    - ubifs: authentication: Fix use-after-free in ubifs_tnc_end_commit
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53172
+    - ubi: fastmap: Fix duplicate slab cache names while attaching
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56739
+    - rtc: check if __rtc_read_time was successful in rtc_timer_do_work()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53173
+    - NFSv4.0: Fix a use-after-free problem in the asynchronous open()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53145
+    - um: Fix potential integer overflow during physmem setup
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53174
+    - SUNRPC: make sure cache entry active before cache_show
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53146
+    - NFSD: Prevent a potential integer overflow
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53175
+    - ipc: fix memleak if msg_init_ns failed in create_ipc_ns
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56692
+    - f2fs: fix to do sanity check on node blkaddr in truncate_node()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56698
+    - usb: dwc3: gadget: Fix looping of queued SG entries
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56687
+    - usb: musb: Fix hardware lockup on first Rx endpoint request
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53176
+    - smb: During unmount, ensure all cached dir instances drop their dentry
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53177
+    - smb: prevent use-after-free due to open_cached_dir error paths
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53178
+    - smb: Don't leak cfid when reconnect races with open_cached_dir
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53180
+    - ALSA: pcm: Add sanity NULL check for the default mmap fault handler
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56700
+    - media: wl128x: Fix atomicity violation in fmc_send_cmd()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2022-49034
+    - sh: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53181
+    - um: vector: Do not use drvdata in release
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53183
+    - um: net: Do not use drvdata in release
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53184
+    - um: ubd: Do not use drvdata in release
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53185
+    - smb: client: fix NULL ptr deref in crypto_aead_setkey()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53188
+    - wifi: ath12k: fix crash when unbinding
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53190
+    - wifi: rtlwifi: Drastically reduce the attempts to read efuse in case of
+      failures
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53191
+    - wifi: ath12k: fix warning when unbinding
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56741
+    - apparmor: test: Fix memory leak for aa_unpack_strdup()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53148
+    - comedi: Flush partial mappings in error case
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53194
+    - PCI: Fix use-after-free of slot->bus on hot remove
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53195
+    - KVM: arm64: Get rid of userspace_irqchip_in_use
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53197
+    - ALSA: usb-audio: Fix potential out-of-bound accesses for Extigy and Mbox
+      devices
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-42122
+    - drm/amd/display: Add NULL pointer check for kzalloc
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-49906
+    - drm/amd/display: Check null pointer before try to access it
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53150
+    - ALSA: usb-audio: Fix out of bounds reads when finding clock sources
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53198
+    - xen: Fix the issue of resource not being properly released in
+      xenbus_dev_probe()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-41014
+    - xfs: add bounds checking to xlog_recover_process_data
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53200
+    - drm/amd/display: Fix null check for pipe_ctx->plane_state in hwss_setup_dpp
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53202
+    - firmware_loader: Fix possible resource leak in fw_log_firmware_info()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53208
+    - Bluetooth: MGMT: Fix slab-use-after-free Read in set_powered_sync
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53210
+    - s390/iucv: MSG_PEEK causes memory leak in iucv_sock_destruct()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53213
+    - net: usb: lan78xx: Fix double free issue with interrupt buffer allocation
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53214
+    - vfio/pci: Properly hide first-in-list PCIe extended capability
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53215
+    - svcrdma: fix miss destroy percpu_counter in svc_rdma_proc_init()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53217
+    - NFSD: Prevent NULL dereference in nfsd4_process_cb_update()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56689
+    - PCI: endpoint: epf-mhi: Avoid NULL dereference if DT lacks 'mmio'
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53151
+    - svcrdma: Address an integer overflow
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53218
+    - f2fs: fix race in concurrent f2fs_stop_gc_thread
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56744
+    - f2fs: fix to avoid potential deadlock in f2fs_record_stop_reason()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53220
+    - f2fs: fix to account dirty data in __get_secs_required()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56745
+    - PCI: Fix reset_method_store() memory leak
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53223
+    - clk: ralink: mtmips: fix clocks probe order in oldest ralink SoCs
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53154
+    - clk: clk-apple-nco: Add NULL check in applnco_probe
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53224
+    - RDMA/mlx5: Move events notifier registration to be after device registration
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56746
+    - fbdev: sh7760fb: Fix a possible memory leak in sh7760fb_alloc_mem()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53155
+    - ocfs2: fix uninitialized value in ocfs2_file_read_iter()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53226
+    - RDMA/hns: Fix NULL pointer derefernce in hns_roce_map_mr_sg()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56747
+    - scsi: qedi: Fix a possible memory leak in qedi_alloc_and_init_sb()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56748
+    - scsi: qedf: Fix a possible memory leak in qedf_alloc_and_init_sb()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53229
+    - RDMA/rxe: Fix the qp flush warnings in req
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56722
+    - RDMA/hns: Fix cpu stuck caused by printings during reset
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53230
+    - cpufreq: CPPC: Fix possible null-ptr-deref for cppc_get_cpu_cost()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53231
+    - cpufreq: CPPC: Fix possible null-ptr-deref for cpufreq_cpu_get_raw()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56701
+    - powerpc/pseries: Fix dtl_access_lock to be a rw_semaphore
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56678
+    - powerpc/mm/fault: Fix kfence page fault reporting
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56677
+    - powerpc/fadump: Move fadump_cma_init to setup_arch() after initmem_init()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56723
+    - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for PMIC devices
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56724
+    - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for TMU device
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56691
+    - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for USB Type-C device
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53233
+    - unicode: Fix utf8_load() error path
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56694
+    - bpf: fix recursive lock when verdict program return SK_PASS
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53234
+    - erofs: handle NONHEAD !delta[1] lclusters gracefully
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53239
+    - ALSA: 6fire: Release resources at card release
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56531
+    - ALSA: caiaq: Use snd_card_free_when_closed() at disconnection
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56532
+    - ALSA: us122l: Use snd_card_free_when_closed() at disconnection
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56533
+    - ALSA: usx2y: Use snd_card_free_when_closed() at disconnection
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56751
+    - ipv6: release nexthop on device removal
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56720
+    - bpf, sockmap: Several fixes to bpf_msg_pop_data
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56538
+    - drm: zynqmp_kms: Unplug DRM device before removal
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56752
+    - drm/nouveau/gr/gf100: Fix missing unlock in gf100_gr_chan_new()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56725
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_dcbnl.c
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56707
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_dmac_flt.c
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56726
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in cn10k.c
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56727
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_flows.c
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56728
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56679
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_common.c
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56539
+    - wifi: mwifiex: Fix memcpy() field-spanning write warning in
+      mwifiex_config_scan()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56543
+    - wifi: ath12k: Skip Rx TID cleanup for self peer
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56683
+    - drm/vc4: hdmi: Avoid hang with debug registers when suspended
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56545
+    - HID: hyperv: streamline driver probe to avoid devres issues
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56705
+    - media: atomisp: Add check for rgby_data memory allocation failure
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53157
+    - firmware: arm_scpi: Check the DVFS OPP count returned by the firmware
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53158
+    - soc: qcom: geni-se: fix array underflow in geni_se_clk_tbl_get()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56546
+    - drivers: soc: xilinx: add the missing kfree in xlnx_add_cb_for_suspend()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56681
+    - crypto: bcm - add error check in the ahash_hmac_init function
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53160
+    - rcu/kvfree: Fix data-race in __mod_timer / kvfree_call_rcu
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56708
+    - EDAC/igen6: Avoid segmentation fault on module unload
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56690
+    - crypto: pcrypt - Call crypto layer directly when padata_do_parallel() return
+      -EBUSY
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53161
+    - EDAC/bluefield: Fix potential integer overflow
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53162
+    - crypto: qat/qat_4xxx - fix off by one in uof_get_name()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56754
+    - crypto: caam - Fix the pointer passed to caam_qi_shutdown()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56548
+    - hfsplus: don't query the device logical block size multiple times
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56756
+    - nvme-pci: fix freeing of the HMB descriptor table
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53142
+    - initramfs: avoid filename buffer overrun
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56693
+    - brd: defer automatic disk creation until module initialization succeeds
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-44955
+    - drm/amd/display: Don't refer to dc_sink in is_dsc_need_re_compute
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-49899
+    - drm/amd/display: Initialize denominators' default to 1
+  * Noble update: upstream stable patchset 2025-03-06 (LP: #2101042)
+    - sctp: fix possible UAF in sctp_v6_available()
+    - net: vertexcom: mse102x: Fix tx_bytes calculation
+    - drm/rockchip: vop: Fix a dereferenced before check warning
+    - mptcp: error out earlier on disconnect
+    - mptcp: cope racing subflow creation in mptcp_rcv_space_adjust
+    - net/mlx5: fs, lock FTE when checking if active
+    - net/mlx5e: kTLS, Fix incorrect page refcounting
+    - net/mlx5e: clear xdp features on non-uplink representors
+    - net/mlx5e: CT: Fix null-ptr-deref in add rule err flow
+    - virtio/vsock: Fix accept_queue memory leak
+    - Bluetooth: btintel: Direct exception event to bluetooth stack
+    - net: sched: cls_u32: Fix u32's systematic failure to free IDR entries for
+      hnodes.
+    - samples: pktgen: correct dev to DEV
+    - net: stmmac: dwmac-mediatek: Fix inverted handling of mediatek,mac-wol
+    - net: Make copy_safe_from_sockptr() match documentation
+    - stmmac: dwmac-intel-plat: fix call balance of tx_clk handling routines
+    - net: ti: icssg-prueth: Fix 1 PPS sync
+    - bonding: add ns target multicast address to slave device
+    - ARM: 9419/1: mm: Fix kernel memory mapping for xip kernels
+    - x86/mm: Fix a kdump kernel failure on SME system when CONFIG_IMA_KEXEC=y
+    - mm: fix NULL pointer dereference in alloc_pages_bulk_noprof
+    - ocfs2: uncache inode which has failed entering the group
+    - vdpa: solidrun: Fix UB bug with devres
+    - vdpa/mlx5: Fix PA offset with unaligned starting iotlb map
+    - vp_vdpa: fix id_table array not null terminated error
+    - ima: fix buffer overrun in ima_eventdigest_init_common
+    - KVM: nVMX: Treat vpid01 as current if L2 is active, but with VPID disabled
+    - KVM: x86: Unconditionally set irr_pending when updating APICv state
+    - KVM: VMX: Bury Intel PT virtualization (guest/host mode) behind
+      CONFIG_BROKEN
+    - nilfs2: fix null-ptr-deref in block_touch_buffer tracepoint
+    - nommu: pass NULL argument to vma_iter_prealloc()
+    - ALSA: hda/realtek - Fixed Clevo platform headset Mic issue
+    - ocfs2: fix UBSAN warning in ocfs2_verify_volume()
+    - nilfs2: fix null-ptr-deref in block_dirty_buffer tracepoint
+    - LoongArch: Fix early_numa_add_cpu() usage for FDT systems
+    - LoongArch: Disable KASAN if PGDIR_SIZE is too large for cpu_vabits
+    - LoongArch: Make KASAN work with 5-level page-tables
+    - Revert "mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K"
+    - mmc: sunxi-mmc: Fix A100 compatible description
+    - drm/bridge: tc358768: Fix DSI command tx
+    - pmdomain: imx93-blk-ctrl: correct remove path
+    - nouveau: fw: sync dma after setup is called.
+    - drm/amd: Fix initialization mistake for NBIO 7.7.0
+    - drm/amd/display: Adjust VSDB parser for replay feature
+    - lib/buildid: Fix build ID parsing logic
+    - media: dvbdev: fix the logic when DVB_DYNAMIC_MINORS is not set
+    - mptcp: add userspace_pm_lookup_addr_by_id helper
+    - mptcp: update local address flags when setting it
+    - mptcp: hold pm lock when deleting entry
+    - mptcp: drop lookup_by_id in lookup_addr
+    - mptcp: pm: use _rcu variant under rcu_read_lock
+    - mm: avoid unsafe VMA hook invocation when error arises on mmap hook
+    - mm: unconditionally close VMAs on error
+    - mm: refactor map_deny_write_exec()
+    - mm: refactor arch_calc_vm_flag_bits() and arm64 MTE handling
+    - mm: resolve faulty mmap_region() error path behaviour
+    - net/mlx5: Fix msix vectors to respect platform limit
+    - vsock: Fix sk_error_queue memory leak
+    - virtio/vsock: Improve MSG_ZEROCOPY error handling
+    - net: phylink: ensure PHY momentary link-fails are handled
+    - drm/vmwgfx: avoid null_ptr_deref in vmw_framebuffer_surface_create_handle
+    - ARM: fix cacheflush with PAN
+    - drm/amd/display: Run idle optimizations at end of vblank handler
+    - drm/amd/display: Change some variable name of psr
+    - x86/CPU/AMD: Clear virtualized VMLOAD/VMSAVE on Zen4 client
+    - x86/stackprotector: Work around strict Clang TLS symbol requirements
+    - sched/task_stack: fix object_is_on_stack() for KASAN tagged pointers
+    - fs/proc/task_mmu: prevent integer overflow in pagemap_scan_get_args()
+    - mm/mremap: fix address wraparound in move_page_tables()
+    - KVM: selftests: Disable strict aliasing
+    - mm: page_alloc: move mlocked flag clearance into free_pages_prepare()
+    - LoongArch: Add WriteCombine shadow mapping in KASAN
+    - drm/xe: handle flat ccs during hibernation on igpu
+    - pmdomain: arm: Use FLAG_DEV_NAME_FW to ensure unique names
+    - pmdomain: core: Add GENPD_FLAG_DEV_NAME_FW flag
+    - nouveau: handle EBUSY and EAGAIN for GSP aux errors.
+    - nouveau/dp: handle retries for AUX CH transfers with GSP.
+    - drm/amdgpu: fix check in gmc_v9_0_get_vm_pte()
+    - drm/amdgpu: Fix video caps for H264 and HEVC encode maximum size
+    - drm/amd/pm: print pp_dpm_mclk in ascending order on SMU v14.0.0
+    - drm/amd/display: Handle dml allocation failure to avoid crash
+    - drm/amd/display: Fix failure to read vram info due to static BP_RESULT
+    - drm/xe: Restore system memory GGTT mappings
+    - drm/xe: improve hibernation on igpu
+    - net: sched: u32: Add test case for systematic hnode IDR leaks
+    - Upstream stable to v6.6.63, v6.11.10
+  * Noble update: upstream stable patchset 2025-03-04 (LP: #2100894)
+    - 9p: v9fs_fid_find: also lookup by inode if not found dentry
+    - 9p: Avoid creating multiple slab caches with the same name
+    - selftests/bpf: Verify that sync_linked_regs preserves subreg_def
+    - irqchip/ocelot: Fix trigger register address
+    - nvme: tcp: avoid race between queue_lock lock and destroy
+    - block: Fix elevator_get_default() checking for NULL q->tag_set
+    - HID: multitouch: Add support for B2402FVA track point
+    - HID: multitouch: Add quirk for HONOR MagicBook Art 14 touchpad
+    - iommu/arm-smmu: Clarify MMU-500 CPRE workaround
+    - nvme: disable CC.CRIME (NVME_CC_CRIME)
+    - bpf: use kvzmalloc to allocate BPF verifier environment
+    - crypto: api - Fix liveliness check in crypto_alg_tested
+    - crypto: marvell/cesa - Disable hash algorithms
+    - sound: Make CONFIG_SND depend on INDIRECT_IOMEM instead of UML
+    - drm/vmwgfx: Limit display layout ioctl array size to
+      VMWGFX_NUM_DISPLAY_UNITS
+    - RDMA/siw: Add sendpage_ok() check to disable MSG_SPLICE_PAGES
+    - nvme-multipath: defer partition scanning
+    - drm/amdkfd: Accounting pdd vram_usage for svm
+    - powerpc/powernv: Free name on error in opal_event_init()
+    - net: phy: mdio-bcm-unimac: Add BCM6846 support
+    - nvme-loop: flush off pending I/O while shutting down loop controller
+    - smb: client: Fix use-after-free of network namespace.
+    - nvme/host: Fix RCU list traversal to use SRCU primitive
+    - vDPA/ifcvf: Fix pci_read_config_byte() return code handling
+    - bpf: Add sk_is_inet and IS_ICSK check in tls_sw_has_ctx_tx/rx
+    - bpf: Fix mismatched RCU unlock flavour in bpf_out_neigh_v6
+    - ASoC: amd: yc: Add quirk for ASUS Vivobook S15 M3502RA
+    - ASoC: amd: yc: Fix non-functional mic on ASUS E1404FA
+    - fs: Fix uninitialized value issue in from_kuid and from_kgid
+    - HID: multitouch: Add quirk for Logitech Bolt receiver w/ Casa touchpad
+    - HID: lenovo: Add support for Thinkpad X1 Tablet Gen 3 keyboard
+    - RISCV: KVM: use raw_spinlock for critical section in imsic
+    - ASoC: rt722-sdca: increase clk_stop_timeout to fix clock stop issue
+    - LoongArch: Use "Exception return address" to comment ERA
+    - ASoC: fsl_micfil: Add sample rate constraint
+    - net: usb: qmi_wwan: add Fibocom FG132 0x0112 composition
+    - bpf: Check validity of link->type in bpf_link_show_fdinfo()
+    - mm: support order-1 folios in the page cache
+    - mm: always initialise folio->_deferred_list
+    - mm: refactor folio_undo_large_rmappable()
+    - mm/thp: fix deferred split unqueue naming and locking
+    - 9p: fix slab cache name creation for real
+    - nvmet-passthru: clear EUID/NGUID/UUID while using loop target
+    - pinctrl: intel: platform: Add Panther Lake to the list of supported
+    - s390/ap: Fix CCA crypto card behavior within protected execution environment
+    - selftests/bpf: Assert link info uprobe_multi count & path_size if unset
+    - ALSA: hda/tas2781: Add new quirk for Lenovo, ASUS, Dell projects
+    - drm/xe/query: Increase timestamp width
+    - nvme: make keep-alive synchronous operation
+    - samples/landlock: Fix port parsing in sandboxer
+    - ASoC: Intel: avs: Update stream status in a separate thread
+    - ASoC: codecs: Fix error handling in aw_dev_get_dsp_status function
+    - netfs: Downgrade i_rwsem for a buffered write
+    - afs: Fix lock recursion
+    - HID: i2c-hid: Delayed i2c resume wakeup for 0x0d42 Goodix touchpad
+    - LoongArch: KVM: Mark hrtimer to expire in hard interrupt context
+    - drm/xe: Don't restart parallel queues multiple times on GT reset
+    - Upstream stable to v6.6.62, v6.11.9
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292)
+    - arm64: dts: rockchip: Fix rt5651 compatible value on rk3399-eaidk-610
+    - arm64: dts: rockchip: Fix rt5651 compatible value on rk3399-sapphire-
+      excavator
+    - arm64: dts: rockchip: Remove hdmi's 2nd interrupt on rk3328
+    - arm64: dts: rockchip: Fix wakeup prop names on PineNote BT node
+    - arm64: dts: rockchip: Fix reset-gpios property on brcm BT nodes
+    - arm64: dts: rockchip: fix i2c2 pinctrl-names property on anbernic-rg353p/v
+    - arm64: dts: rockchip: Fix bluetooth properties on rk3566 box demo
+    - arm64: dts: rockchip: Fix bluetooth properties on Rock960 boards
+    - arm64: dts: rockchip: Add DTS for FriendlyARM NanoPi R2S Plus
+    - arm64: dts: rockchip: Remove undocumented supports-emmc property
+    - arm64: dts: rockchip: Remove #cooling-cells from fan on Theobroma lion
+    - arm64: dts: rockchip: Fix LED triggers on rk3308-roc-cc
+    - arm64: dts: rockchip: remove num-slots property from rk3328-nanopi-r2s-plus
+    - arm64: dts: imx8-ss-vpu: Fix imx8qm VPU IRQs
+    - arm64: dts: imx8mp: correct sdhc ipg clk
+    - arm64: dts: rockchip: remove orphaned pinctrl-names from pinephone pro
+    - ARM: dts: rockchip: fix rk3036 acodec node
+    - ARM: dts: rockchip: drop grf reference from rk3036 hdmi
+    - ARM: dts: rockchip: Fix the spi controller on rk3036
+    - ARM: dts: rockchip: Fix the realtek audio codec on rk3036-kylin
+    - arm64: dts: rockchip: Correct GPIO polarity on brcm BT nodes
+    - sunrpc: handle -ENOTCONN in xs_tcp_setup_socket()
+    - NFSv3: only use NFS timeout for MOUNT when protocols are compatible
+    - nfs: avoid i_lock contention in nfs_clear_invalid_mapping
+    - net: enetc: set MAC address to the VF net_device
+    - dt-bindings: net: xlnx,axi-ethernet: Correct phy-mode property value
+    - can: c_can: fix {rx,tx}_errors statistics
+    - can: c_can: c_can_handle_bus_err(): update statistics if skb allocation
+      fails
+    - ice: change q_index variable type to s16 to store -1 value
+    - e1000e: Remove Meteor Lake SMBUS workarounds
+    - net: phy: ti: add PHY_RST_AFTER_CLK_EN flag
+    - net: stmmac: Fix unbalanced IRQ wake disable warning on single irq case
+    - netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx
+    - netfilter: nf_tables: wait for rcu grace period on net_device removal
+    - netfilter: nf_tables: do not defer rule destruction via call_rcu
+    - net: arc: rockchip: fix emac mdio node support
+    - drivers: net: ionic: add missed debugfs cleanup to ionic_probe() error path
+    - Revert "ALSA: hda/conexant: Mute speakers at suspend / shutdown"
+    - media: stb0899_algo: initialize cfr before using it
+    - media: dvb_frontend: don't play tricks with underflow values
+    - media: adv7604: prevent underflow condition when reporting colorspace
+    - scsi: sd_zbc: Use kvzalloc() to allocate REPORT ZONES buffer
+    - ALSA: firewire-lib: fix return value on fail in amdtp_tscm_init()
+    - tools/lib/thermal: Fix sampling handler context ptr
+    - thermal/of: support thermal zones w/o trips subnode
+    - ASoC: SOF: sof-client-probes-ipc4: Set param_size extension bits
+    - media: pulse8-cec: fix data timestamp at pulse8_setup()
+    - media: v4l2-ctrls-api: fix error handling for v4l2_g_ctrl()
+    - can: m_can: m_can_close(): don't call free_irq() for IRQ-less devices
+    - can: mcp251xfd: mcp251xfd_get_tef_len(): fix length calculation
+    - can: mcp251xfd: mcp251xfd_ring_alloc(): fix coalescing configuration when
+      switching CAN modes
+    - ksmbd: count all requests in req_running counter
+    - ksmbd: fix broken transfers when exceeding max simultaneous operations
+    - pwm: imx-tpm: Use correct MODULO value for EPWM mode
+    - rpmsg: glink: Handle rejected intent request better
+    - drm/amdgpu: Adjust debugfs eviction and IB access permissions
+    - drm/amdgpu: Adjust debugfs register access permissions
+    - drm/amdgpu: Fix DPX valid mode check on GC 9.4.3
+    - thermal/drivers/qcom/lmh: Remove false lockdep backtrace
+    - dm cache: correct the number of origin blocks to match the target length
+    - dm cache: optimize dirty bit checking with find_next_bit when resizing
+    - dm-unstriped: cast an operand to sector_t to prevent potential uint32_t
+      overflow
+    - ALSA: usb-audio: Add quirk for HP 320 FHD Webcam
+    - net: wwan: t7xx: Fix off-by-one error in t7xx_dpmaif_rx_buf_alloc()
+    - mptcp: use sock_kfree_s instead of kfree
+    - arm64: Kconfig: Make SME depend on BROKEN for now
+    - [Config] updateconfigs for ARM64_SME
+    - arm64: smccc: Remove broken support for SMCCCv1.3 SVE discard hint
+    - Revert "wifi: mac80211: fix RCU list iterations"
+    - i2c: designware: do not hold SCL low when I2C_DYNAMIC_TAR_UPDATE is not set
+    - fs/proc: fix compile warning about variable 'vmcore_mmap_ops'
+    - usb: dwc3: fix fault at system suspend if device was already runtime
+      suspended
+    - USB: serial: qcserial: add support for Sierra Wireless EM86xx
+    - USB: serial: option: add Fibocom FG132 0x0112 composition
+    - USB: serial: option: add Quectel RG650V
+    - irqchip/gic-v3: Force propagation of the active state with a read-back
+    - ucounts: fix counter leak in inc_rlimit_get_ucounts()
+    - ASoC: amd: yc: fix internal mic on Xiaomi Book Pro 14 2022
+    - arm64: dts: rockchip: Designate Turing RK1's system power controller
+    - EDAC/qcom: Make irq configuration optional
+    - arm64: dts: rockchip: Drop regulator-init-microvolt from two boards
+    - net: dpaa_eth: print FD status in CPU endianness in dpaa_eth_fd tracepoint
+    - virtio_net: Sync rss config to device when virtnet_probe
+    - drm/xe: Set mask bits for CCS_MODE register
+    - drm/amd/display: Fix brightness level not retained over reboot
+    - drm/imagination: Add a per-file PVR context list
+    - mptcp: no admin perm to list endpoints
+    - btrfs: fix the length of reserved qgroup to free
+    - btrfs: fix per-subvolume RO/RW flags with new mount API
+    - clk: qcom: gcc-x1e80100: Fix USB MP SS1 PHY GDSC pwrsts flags
+    - clk: qcom: clk-alpha-pll: Fix pll post div mask when width is not set
+    - objpool: fix to make percpu slot allocation more robust
+    - mm/damon/core: handle zero {aggregation,ops_update} intervals
+    - mm/damon/core: handle zero schemes apply interval
+    - mm/mlock: set the correct prev on failure
+    - clk: qcom: gcc-x1e80100: Fix halt_check for pipediv2 clocks
+    - staging: vchiq_arm: Get the rid off struct vchiq_2835_state
+    - staging: vchiq_arm: Use devm_kzalloc() for vchiq_arm_state allocation
+    - drm/xe/guc/ct: Flush g2h worker in case of g2h response timeout
+    - drm/xe: Move LNL scheduling WA to xe_device.h
+    - drm/xe/ufence: Flush xe ordered_wq in case of ufence timeout
+    - drm/xe/guc/tlb: Flush g2h worker in case of tlb timeout
+    - xtensa: Emulate one-byte cmpxchg
+    - Upstream stable to v6.6.61, v6.11.8
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50270
+    - mm/damon/core: avoid overflow in damon_feed_loop_next_input()
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50274
+    - idpf: avoid vport access in idpf_get_link_ksettings
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53067
+    - scsi: ufs: core: Start the RTC update work later
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53084
+    - drm/imagination: Break an object reference loop
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53085
+    - tpm: Lock TPM chip in tpm_pm_suspend() first
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53086
+    - drm/xe: Drop VM dma-resv lock on xe_sync_in_fence_get failure in exec IOCTL
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53087
+    - drm/xe: Fix possible exec queue leak in exec IOCTL
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50288
+    - media: vivid: fix buffer overwrite when using > 32 buffers
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50289
+    - media: av7110: fix a spectre vulnerability
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53062
+    - media: mgb4: protect driver against spectre
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50291
+    - media: dvb-core: add missing buffer index check
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50297
+    - net: xilinx: axienet: Enqueue Tx packets in dql before dmaengine starts
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50267
+    - USB: serial: io_edgeport: fix use after free in debug printk
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50268
+    - usb: typec: fix potential out of bounds in ucsi_ccg_update_set_new_cam_cmd()
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53083
+    - usb: typec: qcom-pmic: init value of hdr_len/txbuf_len earlier
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50269
+    - usb: musb: sunxi: Fix accessing an released usb phy
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50271
+    - signal: restore the override_rlimit logic
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50272
+    - filemap: Fix bounds checking in filemap_read()
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50273
+    - btrfs: reinitialize delayed ref list after deleting it from the list
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50275
+    - arm64/sve: Discard stale CPU state when handling SVE traps
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50276
+    - net: vertexcom: mse102x: Fix possible double free of TX skb
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53066
+    - nfs: Fix KMSAN warning in decode_getfattr_attrs()
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50278
+    - dm cache: fix potential out-of-bounds access on the first resume
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50279
+    - dm cache: fix out-of-bounds access to the dirty bitset when resizing
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50280
+    - dm cache: fix flushing uninitialized delayed_work on cache_ctr error
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53060
+    - drm/amdgpu: prevent NULL pointer dereference if ATIF is not supported
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50282
+    - drm/amdgpu: add missing size check in amdgpu_debugfs_gprwave_read()
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50283
+    - ksmbd: fix slab-use-after-free in smb3_preauth_hash_rsp
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50284
+    - ksmbd: Fix the missing xa_store error check
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50285
+    - ksmbd: check outstanding simultaneous SMB operations
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50286
+    - ksmbd: fix slab-use-after-free in ksmbd_smb2_session_create
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50287
+    - media: v4l2-tpg: prevent the risk of a division by zero
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50290
+    - media: cx24116: prevent overflows on SNR calculus
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53061
+    - media: s5p-jpeg: prevent buffer overflows
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53081
+    - media: ar0521: don't overflow when checking PLL values
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50292
+    - ASoC: stm32: spdifrx: fix dma channel release in stm32_spdifrx_remove
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50294
+    - rxrpc: Fix missing locking causing hanging calls
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50295
+    - net: arc: fix the device for dma_map_single/dma_unmap_single
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53082
+    - virtio_net: Add hash_key_length check
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50296
+    - net: hns3: fix kernel crash when uninstalling driver
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53088
+    - i40e: fix race condition by adding filter's intermediate sync state
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50298
+    - net: enetc: allocate vf_state during PF probes
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50299
+    - sctp: properly validate chunk size in sctp_sf_ootb()
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50300
+    - regulator: rtq2208: Fix uninitialized use of regulator_config
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50301
+    - security/keys: fix slab-out-of-bounds in key_task_permission
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53072
+    - platform/x86/amd/pmc: Detect when STB is not available
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53068
+    - firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996)
+    - Input: xpad - sort xpad_device by vendor and product ID
+    - Input: xpad - add support for 8BitDo Ultimate 2C Wireless Controller
+    - cgroup: Fix potential overflow issue when checking max_depth
+    - spi: geni-qcom: Fix boot warning related to pm_runtime and devres
+    - wifi: iwlegacy: Fix "field-spanning write" warning in il_enqueue_hcmd()
+    - mac80211: MAC80211_MESSAGE_TRACING should depend on TRACING
+    - wifi: mac80211: skip non-uploaded keys in ieee80211_iter_keys
+    - wifi: ath11k: Fix invalid ring usage in full monitor mode
+    - wifi: brcm80211: BRCM_TRACING should depend on TRACING
+    - RDMA/cxgb4: Dump vendor specific QP details
+    - RDMA/mlx5: Round max_rd_atomic/max_dest_rd_atomic up instead of down
+    - RDMA/bnxt_re: Fix the usage of control path spin locks
+    - RDMA/bnxt_re: synchronize the qp-handle table array
+    - RDMA/bnxt_re: Fix the locking while accessing the QP table
+    - wifi: iwlwifi: mvm: disconnect station vifs if recovery failed
+    - wifi: iwlwifi: mvm: don't add default link in fw restart flow
+    - ASoC: cs42l51: Fix some error handling paths in cs42l51_probe()
+    - net: stmmac: dwmac4: Fix high address display by updating reg_space[] from
+      register values
+    - net: stmmac: fix TSO DMA API usage causing oops
+    - gtp: allow -1 to be specified as file description from userspace
+    - bpf: Force checkpoint when jmp history is too long
+    - net: skip offload for NETIF_F_IPV6_CSUM if ipv6 header contains extension
+    - net: reenable NETIF_F_IPV6_CSUM offload for BIG TCP packets
+    - mlxsw: spectrum_ptp: Add missing verification before pushing Tx header
+    - bpf, test_run: Fix LIVE_FRAME frame update after a page has been recycled
+    - iomap: improve shared block detection in iomap_unshare_iter
+    - iomap: don't bother unsharing delalloc extents
+    - iomap: share iomap_unshare_iter predicate code with fsdax
+    - fsdax: remove zeroing code from dax_unshare_iter
+    - iomap: turn iomap_want_unshare_iter into an inline function
+    - kasan: Fix Software Tag-Based KASAN with GCC
+    - firmware: arm_sdei: Fix the input parameter of cpuhp_remove_state()
+    - afs: Fix missing subdir edit when renamed between parent dirs
+    - smb: client: set correct device number on nfs reparse points
+    - cxl/events: Fix Trace DRAM Event Record
+    - fs/ntfs3: Fix warning possible deadlock in ntfs_set_state
+    - fs/ntfs3: Stale inode instead of bad
+    - scsi: scsi_transport_fc: Allow setting rport state to current state
+    - cifs: Fix creating native symlinks pointing to current or parent directory
+    - thermal: intel: int340x: processor: Remove MMIO RAPL CPU hotplug support
+    - thermal: intel: int340x: processor: Add MMIO RAPL PL4 support
+    - net: amd: mvme147: Fix probe banner message
+    - NFS: remove revoked delegation from server's delegation list
+    - misc: sgi-gru: Don't disable preemption in GRU driver
+    - usb: gadget: dummy_hcd: Switch to hrtimer transfer scheduler
+    - usb: gadget: dummy_hcd: Set transfer interval to 1 microframe
+    - usb: gadget: dummy_hcd: execute hrtimer callback in softirq context
+    - USB: gadget: dummy-hcd: Fix "task hung" problem
+    - ALSA: usb-audio: Add quirks for Dell WD19 dock
+    - usbip: tools: Fix detach_port() invalid port error path
+    - usb: phy: Fix API devm_usb_put_phy() can not release the phy
+    - usb: typec: fix unreleased fwnode_handle in typec_port_register_altmodes()
+    - usb: typec: qcom-pmic-typec: use fwnode_handle_put() to release fwnodes
+    - xhci: Fix Link TRB DMA in command ring stopped completion event
+    - xhci: Use pm_runtime_get to prevent RPM on unsupported systems
+    - Revert "driver core: Fix uevent_show() vs driver detach race"
+    - iio: light: veml6030: fix microlux value calculation
+    - RISC-V: ACPI: fix early_ioremap to early_memremap
+    - tools/mm: -Werror fixes in page-types/slabinfo
+    - tools/mm: fix compile error
+    - thunderbolt: Honor TMU requirements in the domain when setting TMU mode
+    - mmc: sdhci-pci-gli: GL9767: Fix low power mode on the set clock function
+    - mmc: sdhci-pci-gli: GL9767: Fix low power mode in the SD Express process
+    - block: fix sanity checks in blk_rq_map_user_bvec
+    - cgroup/bpf: use a dedicated workqueue for cgroup bpf destruction
+    - phy: freescale: imx8m-pcie: Do CMN_RST just before PHY PLL lock check
+    - riscv: vdso: Prevent the compiler from inserting calls to memset()
+    - Input: edt-ft5x06 - fix regmap leak when probe fails
+    - ALSA: hda/realtek: Limit internal Mic boost on Dell platform
+    - riscv: efi: Set NX compat flag in PE/COFF header
+    - riscv: Use '%u' to format the output of 'cpu'
+    - riscv: Remove unused GENERATING_ASM_OFFSETS
+    - riscv: Remove duplicated GET_RM
+    - cxl/port: Fix cxl_bus_rescan() vs bus_rescan_devices()
+    - cxl/acpi: Ensure ports ready at cxl_acpi_probe() return
+    - mei: use kvmalloc for read buffer
+    - mm/page_alloc: let GFP_ATOMIC order-0 allocs access highatomic reserves
+    - x86/traps: Enable UBSAN traps on x86
+    - x86/traps: move kmsan check after instrumentation_begin
+    - kasan: remove vmalloc_percpu test
+    - vmscan,migrate: fix page count imbalance on node stats when demoting pages
+    - io_uring: always lock __io_cqring_overflow_flush
+    - mm: huge_memory: add vma_thp_disabled() and thp_disabled_by_hw()
+    - mm: don't install PMD mappings when THPs are disabled by the hw/process/vma
+    - perf trace: Fix non-listed archs in the syscalltbl routines
+    - dpll: add Embedded SYNC feature for a pin
+    - ice: add callbacks for Embedded SYNC enablement on dpll pins
+    - bpf: Add bpf_mem_alloc_check_size() helper
+    - net: ethernet: mtk_wed: fix path of MT7988 WO firmware
+    - drm/mediatek: ovl: Remove the color format comment for ovl_fmt_convert()
+    - drm/mediatek: Fix get efuse issue for MT8188 DPTX
+    - ACPI: resource: Fold Asus Vivobook Pro N6506M* DMI quirks together
+    - powercap: intel_rapl_msr: Add PL4 support for Arrowlake-U
+    - usb: typec: qcom-pmic-typec: fix missing fwnode removal in error path
+    - mm: shrinker: avoid memleak in alloc_shrinker_info
+    - firmware: microchip: auto-update: fix poll_complete() to not report spurious
+      timeout errors
+    - soc: qcom: pmic_glink: Handle GLINK intent allocation rejections
+    - cxl/port: Fix CXL port initialization order when the subsystem is built-in
+    - btrfs: merge btrfs_orig_bbio_end_io() into btrfs_bio_end_io()
+    - posix-cpu-timers: Clear TICK_DEP_BIT_POSIX_TIMER on clone
+    - mm/ksm: remove redundant code in ksm_fork
+    - nvme: re-fix error-handling for io_uring nvme-passthrough
+    - btrfs: fix extent map merging not happening for adjacent extents
+    - btrfs: fix defrag not merging contiguous extents due to merged extent maps
+    - mm, mmap: limit THP alignment of anonymous mappings to PMD-aligned sizes
+    - mm: multi-gen LRU: ignore non-leaf pmd_young for force_scan=true
+    - mm: multi-gen LRU: remove MM_LEAF_OLD and MM_NONLEAF_TOTAL stats
+    - mm: shrink skip folio mapped by an exiting process
+    - mm: multi-gen LRU: use {ptep,pmdp}_clear_young_notify()
+    - drm/i915: Skip programming FIA link enable bits for MTL+
+    - drm/i915/display: WA for Re-initialize dispcnlunitt1 xosc clock
+    - drm/i915/dp: Clear VSC SDP during post ddi disable routine
+    - drm/i915/pps: Disable DPLS_GATING around pps sequence
+    - drm/i915: move rawclk from runtime to display runtime info
+    - drm/xe/display: drop unused rawclk_freq and RUNTIME_INFO()
+    - drm/xe: Support 'nomodeset' kernel command-line option
+    - drm/xe/xe2hpg: Introduce performance tuning changes for Xe2_HPG
+    - drm/amdgpu/swsmu: fix ordering for setting workload_mask
+    - drm/amdgpu/swsmu: default to fullscreen 3D profile for dGPUs
+    - drm/amdgpu: handle default profile on on devices without fullscreen 3D
+    - MIPS: export __cmpxchg_small()
+    - rcu/kvfree: Add kvfree_rcu_barrier() API
+    - rcu/kvfree: Refactor kvfree_rcu_queue_batch()
+    - Upstream stable to v6.6.60, v6.11.7
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53050
+    - drm/i915/hdcp: Add encoder check in hdcp2_get_capability
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53051
+    - drm/i915/hdcp: Add encoder check in intel_hdcp_get_capability
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50303
+    - resource,kexec: walk_system_ram_res_rev must retain resource flags
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50263
+    - fork: only invoke khugepaged, ksm hooks if no error
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50220
+    - fork: do not invoke uffd on fork if error occurs
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50221
+    - drm/amd/pm: Vangogh: Fix kernel memory out of bounds write
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53053
+    - scsi: ufs: core: Fix another deadlock during RTC update
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50225
+    - btrfs: fix error propagation of split bios
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50230
+    - nilfs2: fix kernel bug due to missing clearing of checked flag
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50238
+    - phy: qcom: qmp-usbc: fix NULL-deref on runtime suspend
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53044
+    - net/sched: sch_api: fix xa_insert() error path in tcf_block_get_ext()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50304
+    - ipv4: ip_tunnel: Fix suspicious RCU usage warning in ip_tunnel_find()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53048
+    - ice: fix crash on probe for DPLL enabled E810 LOM
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53045
+    - ASoC: dapm: fix bounds checker error in dapm_widget_list_create
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53055
+    - wifi: iwlwifi: mvm: fix 6 GHz scan construction
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53046
+    - arm64: dts: imx8ulp: correct the flexspi compatible string
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53052
+    - io_uring/rw: fix missing NOWAIT check for O_DIRECT start write
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50215
+    - nvmet-auth: assign dh_key to NULL after kfree_sensitive
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50216
+    - xfs: fix finding a last resort AG in xfs_filestream_pick_ag
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53043
+    - mctp i2c: handle NULL header address
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50218
+    - ocfs2: pass u64 to ocfs2_truncate_inline maybe overflow
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53047
+    - mptcp: init: protect sched with rcu_read_lock
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50222
+    - iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50223
+    - sched/numa: Fix the potential null pointer dereference in task_numa_work()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50224
+    - spi: spi-fsl-dspi: Fix crash when not using GPIO chip select
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50226
+    - cxl/port: Fix use-after-free, permit out-of-order decoder shutdown
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50231
+    - iio: gts-helper: Fix memory leaks in iio_gts_build_avail_scale_table()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53076
+    - iio: gts-helper: Fix memory leaks for the error path of
+      iio_gts_build_avail_scale_table()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50232
+    - iio: adc: ad7124: fix division by zero in ad7124_set_channel_odr()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50234
+    - wifi: iwlegacy: Clear stale interrupts before resuming device
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50235
+    - wifi: cfg80211: clear wdev->cqm_config pointer on free
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50236
+    - wifi: ath10k: Fix memory leak in management tx
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50237
+    - wifi: mac80211: do not pass a stopped vif to the driver in .get_txpower
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50239
+    - phy: qcom: qmp-usb-legacy: fix NULL-deref on runtime suspend
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50240
+    - phy: qcom: qmp-usb: fix NULL-deref on runtime suspend
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50242
+    - fs/ntfs3: Additional check in ntfs_file_release
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50243
+    - fs/ntfs3: Fix general protection fault in run_is_mapped_full
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50244
+    - fs/ntfs3: Additional check in ni_clear()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50245
+    - fs/ntfs3: Fix possible deadlock in mi_read
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50246
+    - fs/ntfs3: Add rough attr alloc_size check
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50247
+    - fs/ntfs3: Check if more than chunk-size bytes are written
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50250
+    - fsdax: dax_unshare_iter needs to copy entire blocks
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50251
+    - netfilter: nft_payload: sanitize offset and length before calling
+      skb_checksum()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50252
+    - mlxsw: spectrum_ipip: Fix memory leak when changing remote IPv6 address
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50255
+    - Bluetooth: hci: fix null-ptr-deref in hci_read_supported_codecs
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50257
+    - netfilter: Fix use-after-free in get_info()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50258
+    - net: fix crash when config small gso_max_size/gso_ipv4_max_size
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50262
+    - bpf: Fix out-of-bounds write in trie_get_next_key()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50259
+    - netdevsim: Add trailing zero to terminate the string in
+      nsim_nexthop_bucket_activity_write()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53042
+    - ipv4: ip_tunnel: Fix suspicious RCU usage warning in ip_tunnel_init_flow()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53058
+    - net: stmmac: TSO: Fix unbalanced DMA map/unmap for non-paged SKB data
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50261
+    - macsec: Fix use-after-free while sending the offloading packet
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53059
+    - wifi: iwlwifi: mvm: Fix response handling in iwl_mvm_send_recovery_cmd()
+  * Noble update: upstream stable patchset 2025-02-07 (LP: #2097575)
+    - irqchip/gic-v3-its: Fix VSYNC referencing an unmapped VPE on GIC v4.1
+    - xfs: fix error returns from xfs_bmapi_write
+    - xfs: fix xfs_bmap_add_extent_delay_real for partial conversions
+    - xfs: remove a racy if_bytes check in xfs_reflink_end_cow_extent
+    - xfs: require XFS_SB_FEAT_INCOMPAT_LOG_XATTRS for attr log intent item
+      recovery
+    - xfs: check opcode and iovec count match in xlog_recover_attri_commit_pass2
+    - xfs: fix missing check for invalid attr flags
+    - xfs: check shortform attr entry flags specifically
+    - xfs: validate recovered name buffers when recovering xattr items
+    - xfs: enforce one namespace per attribute
+    - xfs: revert commit 44af6c7e59b12
+    - xfs: use dontcache for grabbing inodes during scrub
+    - xfs: match lock mode in xfs_buffered_write_iomap_begin()
+    - xfs: make the seq argument to xfs_bmapi_convert_delalloc() optional
+    - xfs: make xfs_bmapi_convert_delalloc() to allocate the target offset
+    - xfs: convert delayed extents to unwritten when zeroing post eof blocks
+    - xfs: allow symlinks with short remote targets
+    - xfs: make sure sb_fdblocks is non-negative
+    - xfs: fix unlink vs cluster buffer instantiation race
+    - xfs: fix freeing speculative preallocations for preallocated files
+    - xfs: allow unlinked symlinks and dirs with zero size
+    - xfs: restrict when we try to align cow fork delalloc to cowextsz hints
+    - selftests: mptcp: join: change capture/checksum as bool
+    - selftests: mptcp: join: test for prohibited MPC to port-based endp
+    - selftests: mptcp: remove duplicated variables
+    - iio: accel: bma400: Fix uninitialized variable field_value in tap event
+      handling.
+    - bpf: Make sure internal and UAPI bpf_redirect flags don't overlap
+    - bpf: devmap: provide rxq after redirect
+    - cpufreq/amd-pstate: Fix amd_pstate mode switch on shared memory systems
+    - lib/Kconfig.debug: fix grammar in RUST_BUILD_ASSERT_ALLOW
+    - bpf: Fix memory leak in bpf_core_apply
+    - RDMA/bnxt_re: Fix a possible memory leak
+    - RDMA/bnxt_re: Fix incorrect AVID type in WQE structure
+    - RDMA/bnxt_re: Add a check for memory allocation
+    - x86/resctrl: Avoid overflow in MB settings in bw_validate()
+    - ARM: dts: bcm2837-rpi-cm3-io3: Fix HDMI hpd-gpio pin
+    - bpf: Add cookie to perf_event bpf_link_info records
+    - bpf: fix unpopulated name_len field in perf_event link info
+    - selftests/bpf: Add cookies check for perf_event fill_link_info test
+    - selftests/bpf: fix perf_event link info name_len assertion
+    - s390/pci: Handle PCI error codes other than 0x3a
+    - bpf: fix kfunc btf caching for modules
+    - iio: frequency: {admv4420,adrf6780}: format Kconfig entries
+    - iio: frequency: admv4420: fix missing select REMAP_SPI in Kconfig
+    - drm/vmwgfx: Handle possible ENOMEM in vmw_stdu_connector_atomic_check
+    - selftests/bpf: Fix cross-compiling urandom_read
+    - task_work: Add TWA_NMI_CURRENT as an additional notify mode.
+    - sched/core: Disable page allocation in task_tick_mm_cid()
+    - ALSA: hda/cs8409: Fix possible NULL dereference
+    - firmware: arm_scmi: Fix the double free in scmi_debugfs_common_setup()
+    - RDMA/cxgb4: Fix RDMA_CM_EVENT_UNREACHABLE error for iWARP
+    - RDMA/irdma: Fix misspelling of "accept*"
+    - RDMA/srpt: Make slab cache names unique
+    - ipv4: give an IPv4 dev to blackhole_netdev
+    - RDMA/bnxt_re: Fix the max CQ WQEs for older adapters
+    - RDMA/bnxt_re: Fix out of bound check
+    - RDMA/bnxt_re: Return more meaningful error
+    - RDMA/bnxt_re: Fix a bug while setting up Level-2 PBL pages
+    - RDMA/bnxt_re: Fix the GID table length
+    - accel/qaic: Fix the for loop used to walk SG table
+    - drm/msm/dpu: make sure phys resources are properly initialized
+    - drm/msm/dpu: check for overflow in _dpu_crtc_setup_lm_bounds()
+    - drm/msm/dsi: improve/fix dsc pclk calculation
+    - drm/msm/dsi: fix 32-bit signed integer extension in pclk_rate calculation
+    - drm/msm: Avoid NULL dereference in msm_disp_state_print_regs()
+    - drm/msm: Allocate memory for disp snapshot with kvzalloc()
+    - firmware: arm_scmi: Queue in scmi layer for mailbox implementation
+    - net/smc: Fix memory leak when using percpu refs
+    - net: usb: usbnet: fix race in probe failure
+    - net: stmmac: dwmac-tegra: Fix link bring-up sequence
+    - octeontx2-af: Fix potential integer overflows on integer shifts
+    - drm/amd/amdgpu: Fix double unlock in amdgpu_mes_add_ring
+    - macsec: don't increment counters for an unrelated SA
+    - netdevsim: use cond_resched() in nsim_dev_trap_report_work()
+    - net: ethernet: aeroflex: fix potential memory leak in
+      greth_start_xmit_gbit()
+    - net/smc: Fix searching in list of known pnetids in smc_pnet_add_pnetid
+    - net: xilinx: axienet: fix potential memory leak in axienet_start_xmit()
+    - bpf: Fix truncation bug in coerce_reg_to_size_sx()
+    - irqchip/renesas-rzg2l: Fix missing put_device
+    - drm/msm/dpu: don't always program merge_3d block
+    - net: bcmasp: fix potential memory leak in bcmasp_xmit()
+    - tcp/dccp: Don't use timer_pending() in reqsk_queue_unlink().
+    - net: dsa: mv88e6xxx: Fix the max_vid definition for the MV88E6361
+    - genetlink: hold RCU in genlmsg_mcast()
+    - ravb: Remove setting of RX software timestamp
+    - net: ravb: Only advertise Rx/Tx timestamps if hardware supports it
+    - scsi: target: core: Fix null-ptr-deref in target_alloc_device()
+    - smb: client: fix possible double free in smb2_set_ea()
+    - smb: client: fix OOBs when building SMB2_IOCTL request
+    - usb: typec: altmode should keep reference to parent
+    - s390: Initialize psw mask in perf_arch_fetch_caller_regs()
+    - bpf: Fix link info netfilter flags to populate defrag flag
+    - vmxnet3: Fix packet corruption in vmxnet3_xdp_xmit_frame
+    - net/mlx5: Check for invalid vector index on EQ creation
+    - net/mlx5: Fix command bitmask initialization
+    - net/mlx5: Unregister notifier on eswitch init failure
+    - bpf, sockmap: SK_DROP on attempted redirects of unsupported af_vsock
+    - vsock: Update rx_bytes on read_skb()
+    - vsock: Update msg_count on read_skb()
+    - bpf, vsock: Drop static vsock_bpf_prot initialization
+    - riscv, bpf: Make BPF_CMPXCHG fully ordered
+    - nvme-pci: fix race condition between reset and nvme_dev_disable()
+    - bpf: Fix iter/task tid filtering
+    - cdrom: Avoid barrier_nospec() in cdrom_ioctl_media_changed()
+    - khugepaged: inline hpage_collapse_alloc_folio()
+    - khugepaged: convert alloc_charge_hpage to alloc_charge_folio
+    - khugepaged: remove hpage from collapse_file()
+    - mm: khugepaged: fix the arguments order in khugepaged_collapse_file trace
+      point
+    - iio: adc: ti-lmp92064: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - xhci: dbgtty: remove kfifo_out() wrapper
+    - xhci: dbgtty: use kfifo from tty_port struct
+    - xhci: dbc: honor usb transfer size boundaries.
+    - usb: gadget: f_uac2: fix non-newline-terminated function name
+    - usb: gadget: f_uac2: fix return value for UAC2_ATTRIBUTE_STRING store
+    - XHCI: Separate PORT and CAPs macros into dedicated file
+    - usb: dwc3: core: Fix system suspend on TI AM62 platforms
+    - tracing/fprobe-event: cleanup: Fix a wrong comment in fprobe event
+    - tracing/probes: cleanup: Set trace_probe::nr_args at trace_probe_init
+    - tracing/probes: Support $argN in return probe (kprobe and fprobe)
+    - uprobes: encapsulate preparation of uprobe args buffer
+    - uprobes: prepare uprobe args buffer lazily
+    - uprobes: prevent mutex_lock() under rcu_read_lock()
+    - uprobe: avoid out-of-bounds memory access of fetching args
+    - exec: don't WARN for racy path_noexec check
+    - ASoC: amd: yc: Add quirk for HP Dragonfly pro one
+    - ASoC: codecs: lpass-rx-macro: add missing CDC_RX_BCL_VBAT_RF_PROC2 to
+      default regs values
+    - ASoC: fsl_sai: Enable 'FIFO continue on error' FCONT bit
+    - arm64: Force position-independent veneers
+    - udf: refactor udf_current_aext() to handle error
+    - udf: refactor udf_next_aext() to handle error
+    - udf: refactor inode_bmap() to handle error
+    - udf: fix uninit-value use in udf_get_fileshortad
+    - ASoC: qcom: sm8250: add qrb4210-rb2-sndcard compatible string
+    - cifs: Validate content of NFS reparse point buffer
+    - platform/x86: dell-sysman: add support for alienware products
+    - LoongArch: Don't crash in stack_top() for tasks without vDSO
+    - jfs: Fix sanity check in dbMount
+    - tracing/probes: Fix MAX_TRACE_ARGS limit handling
+    - tracing: Consider the NULL character when validating the event length
+    - xfrm: extract dst lookup parameters into a struct
+    - xfrm: respect ip protocols rules criteria when performing dst lookups
+    - netfilter: bpf: must hold reference on net namespace
+    - net/sun3_82586: fix potential memory leak in sun3_82586_send_packet()
+    - net: plip: fix break; causing plip to never transmit
+    - octeon_ep: Implement helper for iterating packets in Rx queue
+    - octeon_ep: Add SKB allocation failures handling in __octep_oq_process_rx()
+    - net: dsa: mv88e6xxx: Fix error when setting port policy on mv88e6393x
+    - fsl/fman: Save device references taken in mac_probe()
+    - fsl/fman: Fix refcount handling of fman-related devices
+    - netfilter: xtables: fix typo causing some targets not to load on IPv6
+    - net: wwan: fix global oob in wwan_rtnl_policy
+    - net/sched: adjust device watchdog timer to detect stopped queue at right
+      time
+    - net: fix races in netdev_tx_sent_queue()/dev_watchdog()
+    - net: usb: usbnet: fix name regression
+    - bpf: Add MEM_WRITE attribute
+    - bpf: Fix overloading of MEM_UNINIT's meaning
+    - bpf: Remove MEM_UNINIT from skb/xdp MTU helpers
+    - net/sched: act_api: deny mismatched skip_sw/skip_hw flags for actions
+      created by classifiers
+    - net: sched: fix use-after-free in taprio_change()
+    - net: sched: use RCU read-side critical section in taprio_dump()
+    - posix-clock: posix-clock: Fix unbalanced locking in pc_clock_settime()
+    - Bluetooth: SCO: Fix UAF on sco_sock_timeout
+    - Bluetooth: ISO: Fix UAF on iso_sock_timeout
+    - bpf,perf: Fix perf_event_detach_bpf_prog error handling
+    - net: dsa: mv88e6xxx: group cycle counter coefficients
+    - net: dsa: mv88e6xxx: read cycle counter period from hardware
+    - net: dsa: mv88e6xxx: support 4000ps cycle counter period
+    - ASoC: dt-bindings: davinci-mcasp: Fix interrupts property
+    - ASoC: dt-bindings: davinci-mcasp: Fix interrupt properties
+    - ASoC: loongson: Fix component check failed on FDT systems
+    - ASoC: max98388: Fix missing increment of variable slot_found
+    - ASoC: rsnd: Fix probe failure on HiHope boards due to endpoint parsing
+    - ASoC: fsl_micfil: Add a flag to distinguish with different volume control
+      types
+    - ALSA: firewire-lib: Avoid division by zero in apply_constraint_to_size()
+    - powercap: dtpm_devfreq: Fix error check against dev_pm_qos_add_request()
+    - nfsd: cancel nfsd_shrinker_work using sync mode in nfs4_state_shutdown_net
+    - ALSA: hda/realtek: Update default depop procedure
+    - smb: client: Handle kstrdup failures for passwords
+    - cpufreq: CPPC: fix perf_to_khz/khz_to_perf conversion exception
+    - btrfs: fix passing 0 to ERR_PTR in btrfs_search_dir_index_item()
+    - btrfs: zoned: fix zone unusable accounting for freed reserved extent
+    - ACPI: resource: Add LG 16T90SP to irq1_level_low_skip_override[]
+    - ACPI: PRM: Find EFI_MEMORY_RUNTIME block for PRM handler and context
+    - ACPI: button: Add DMI quirk for Samsung Galaxy Book2 to fix initial lid
+      detection issue
+    - nilfs2: fix kernel bug due to missing clearing of buffer delay flag
+    - openat2: explicitly return -E2BIG for (usize > PAGE_SIZE)
+    - KVM: nSVM: Ignore nCR3[4:0] when loading PDPTEs from memory
+    - KVM: arm64: Fix shift-out-of-bounds bug
+    - KVM: arm64: Don't eagerly teardown the vgic on init error
+    - x86/lam: Disable ADDRESS_MASKING in most cases
+    - [Config] disable ADDRESS_MASKING
+    - ALSA: hda/tas2781: select CRC32 instead of CRC32_SARWATE
+    - ALSA: hda/realtek: Add subwoofer quirk for Acer Predator G9-593
+    - LoongArch: Get correct cores_per_package for SMT systems
+    - LoongArch: Enable IRQ if do_ale() triggered in irq-enabled context
+    - LoongArch: Make KASAN usable for variable cpu_vabits
+    - xfrm: fix one more kernel-infoleak in algo dumping
+    - hv_netvsc: Fix VF namespace also in synthetic NIC NETDEV_REGISTER event
+    - drm/amd/display: Disable PSR-SU on Parade 08-01 TCON too
+    - selinux: improve error checking in sel_write_load()
+    - net: phy: dp83822: Fix reset pin definitions
+    - ata: libata: Set DID_TIME_OUT for commands that actually timed out
+    - ASoC: qcom: Fix NULL Dereference in asoc_qcom_lpass_cpu_platform_probe()
+    - platform/x86: dell-wmi: Ignore suspend notifications
+    - ACPI: PRM: Clean up guid type in struct prm_handler_info
+    - tracing: probes: Fix to zero initialize a local variable
+    - task_work: make TWA_NMI_CURRENT handling conditional on IRQ_WORK
+    - xfrm: validate new SA's prefixlen using SA family when sel.family is unset
+    - bpf: Use raw_spinlock_t in ringbuf
+    - reset: starfive: jh71x0: Fix accessing the empty member on JH7110 SoC
+    - bpf: Fix unpopulated path_size when uprobe_multi fields unset
+    - RDMA/bnxt_re: Fix incorrect dereference of srq in async event
+    - RDMA/bnxt_re: Get the toggle bits from SRQ events
+    - RDMA/bnxt_re: Change the sequence of updating the CQ toggle value
+    - drm/msm/dpu: move CRTC resource assignment to dpu_encoder_virt_atomic_check
+    - ring-buffer: Fix reader locking when changing the sub buffer order
+    - drm/msm/dpu: Don't always set merge_3d pending flush
+    - drm/msm/a6xx+: Insert a fence wait before SMMU table update
+    - drm/xe: Take job list lock in xe_sched_add_pending_job
+    - drm/xe: Use bookkeep slots for external BO's in exec IOCTL
+    - net: ethernet: mtk_eth_soc: fix memory corruption during fq dma init
+    - net/mlx5e: Don't call cleanup on profile rollback failure
+    - bpf: Fix print_reg_state's constant scalar dump
+    - fsnotify: optimize the case of no parent watcher
+    - fsnotify: Avoid data race between fsnotify_recalc_mask() and
+      fsnotify_object_watched()
+    - drm/xe/mcr: Use Xe2_LPM steering tables for Xe2_HPM
+    - objpool: fix choosing allocation for percpu slots
+    - bnxt_en: replace ptp_lock with irqsave variant
+    - bpf, arm64: Fix address emission with tag-based KASAN enabled
+    - net: dsa: microchip: disable EEE for KSZ879x/KSZ877x/KSZ876x
+    - ASoC: topology: Bump minimal topology ABI version
+    - fbdev: wm8505fb: select CONFIG_FB_IOMEM_FOPS
+    - btrfs: qgroup: set a more sane default value for subtree drop threshold
+    - btrfs: clear force-compress on remount when compress mount option is given
+    - x86/amd_nb: Add new PCI IDs for AMD family 1Ah model 60h-70h
+    - x86/amd_nb: Add new PCI ID for AMD family 1Ah model 20h
+    - btrfs: reject ro->rw reconfiguration if there are hard ro requirements
+    - xfs: don't fail repairs on metadata files with no attr fork
+    - drm/bridge: Fix assignment of the of_node of the parent to aux bridge
+    - platform/x86/intel/pmc: Fix pmc_core_iounmap to call iounmap for valid
+      addresses
+    - fgraph: Fix missing unlock in register_ftrace_graph()
+    - fgraph: Change the name of cpuhp state to "fgraph:online"
+    - ASoC: SOF: Intel: hda: Always clean up link DMA during stop
+    - ASoC: dapm: avoid container_of() to get component
+    - ASoC: qcom: sc7280: Fix missing Soundwire runtime stream alloc
+    - ASoC: qcom: sdm845: add missing soundwire runtime stream alloc
+    - soundwire: intel_ace2x: Send PDI stream number during prepare
+    - x86: support user address masking instead of non-speculative conditional
+    - ASoC: qcom: Select missing common Soundwire module code on SDM845
+    - SAUCE: Revert "iio: adc: ti-lmp92064: add missing select
+      IIO_(TRIGGERED_)BUFFER in Kconfig"
+    - Upstream stable to v6.6.58, v6.6.59, v6.11.6
+  * CVE-2025-21756
+    - vsock: Keep the binding until socket destruction
+    - vsock: Orphan socket after transport release
+  * Fix NIC name changes for ice (LP: #2100264)
+    - ice: Remove ndo_get_phys_port_name
+  * CVE-2024-50256
+    - netfilter: nf_reject_ipv6: fix potential crash in nf_send_reset6()
+  * CVE-2025-21702
+    - pfifo_tail_enqueue: Drop new packet when sch->limit == 0
+  * CVE-2024-50167
+    - be2net: fix potential memory leak in be_xmit()
+  * Fix line-out playback on some platforms with Cirrus Logic “Dolphin” hardware
+    (LP: #2099880)
+    - ALSA: hda/cirrus: Correct the full scale volume set logic
+  * Enable Large Language Model (LLM) workloads using Intel NPU (LP: #2098972)
+    - accel/ivpu: Increase DMA address range
+  * Patchset for TUXEDO devices (LP: #2098104)
+    - wifi: ath12k: add fallback board name without variant while searching
+      board-2.bin
+    - wifi: ath12k: remove unused ATH12K_BD_IE_BOARD_EXT
+    - wifi: ath12k: add support to search regdb data in board-2.bin for WCN7850
+    - wifi: ath12k: support default regdb while searching board-2.bin for WCN7850
+    - ACPI: resource: Use IRQ override on Maibenben X565
+    - ACPI: resource: Do IRQ override on TongFang GXxHRXx and GMxHGxx
+    - ALSA: hda/realtek: Fix headset mic on TUXEDO Gemini 17 Gen3
+    - ALSA: hda/realtek: Fix headset mic on TUXEDO Stellaris 16 Gen6 mb1
+    - PCI: Avoid putting some root ports into D3 on TUXEDO Sirius Gen1
+    - nvme-pci: Add TUXEDO InfinityFlex to Samsung sleep quirk
+    - nvme-pci: Add TUXEDO IBP Gen9 to Samsung sleep quirk
+  * Introduce and use sendpages_ok() instead of sendpage_ok() in nvme-tcp and
+    drbd (LP: #2093871)
+    - net: introduce helper sendpages_ok()
+    - nvme-tcp: use sendpages_ok() instead of sendpage_ok()
+    - drbd: use sendpages_ok() instead of sendpage_ok()
+  * CVE-2024-56765
+    - powerpc/pseries/vas: Add close() callback in vas_vm_ops struct
+  * CVE-2025-21700
+    - net: sched: Disallow replacing of child qdisc from one parent to another
+  * CVE-2024-56615
+    - bpf: fix OOB devmap writes when deleting elements
+  * CVE-2024-56651
+    - can: hi311x: hi3110_can_ist(): fix potential use-after-free
+  * CVE-2024-56627
+    - ksmbd: fix Out-of-Bounds Read in ksmbd_vfs_stream_read
+  * CVE-2024-56600
+    - net: inet6: do not leave a dangling sk pointer in inet6_create()
+  * CVE-2024-56661
+    - tipc: fix NULL deref in cleanup_bearer()
+  * CVE-2024-56642
+    - tipc: Fix use-after-free of kernel socket in cleanup_bearer().
+  * CVE-2024-53227
+    - scsi: bfa: Fix use-after-free in bfad_im_module_exit()
+  * CVE-2024-53237
+    - Bluetooth: fix use-after-free in device_for_each_child()
+  * CVE-2024-53166
+    - block, bfq: fix bfqq uaf in bfq_limit_depth()
+  * CVE-2024-50265
+    - ocfs2: remove entry once instead of null-ptr-dereference in
+      ocfs2_xa_remove()
+  * CVE-2024-50249
+    - ACPI: CPPC: Make rmw_lock a raw_spin_lock
+  * iBFT iSCSI out-of-bounds shift UBSAN warning (LP: #2097824)
+    - iscsi_ibft: Fix UBSAN shift-out-of-bounds warning in ibft_attr_show_nic()
+  * [Ubuntu 24.04] MultiVM - L2 guest(s) running stress-ng getting stuck at
+    booting after triggering crash (LP: #2077722)
+    - KVM: PPC: Book3S HV: Mask off LPCR_MER for a vCPU before running it to avoid
+      spurious interrupts
+  * btrfs will WARN_ON() in btrfs_remove_qgroup() unnecessarily (LP: #2091719)
+    - btrfs: improve the warning and error message for btrfs_remove_qgroup()
+  * CVE-2024-50248
+    - ntfs3: Add bounds checking to mi_enum_attr()
+    - fs/ntfs3: Sequential field availability check in mi_enum_attr()
+  * CVE-2025-21701
+    - net: avoid race between device unregistration and ethnl ops
+  * CVE-2024-57798
+    - drm/dp_mst: Ensure mst_primary pointer is valid in
+      drm_dp_mst_handle_up_req()
+  * CVE-2024-56672
+    - blk-cgroup: Fix UAF in blkcg_unpin_online()
+  * CVE-2024-56658
+    - net: defer final 'struct net' free in netns dismantle
+  * CVE-2024-56598
+    - jfs: array-index-out-of-bounds fix in dtReadFirst
+  * CVE-2024-56595
+    - jfs: add a check to prevent array-index-out-of-bounds in dbAdjTree
+  * CVE-2024-53140
+    - netlink: terminate outstanding dump on socket close
+  * CVE-2024-53063
+    - media: dvbdev: prevent the risk of out of memory access
+  * CVE-2024-50302
+    - HID: core: zero-initialize the report buffer
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 04 Jun 2025 20:20:57 +0900
+
+linux-qcom (6.8.0-1042.42) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1042.42 -proposed tracker (LP: #2112174)
+
+  * Miscellaneous Ubuntu changes
+    - [configs] change CONFIG_HWSPINLOCK_QCOM to y
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 30 May 2025 17:59:33 +0900
+
+linux-qcom (6.8.0-1041.41) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1041.41 -proposed tracker (LP: #2111886)
+
+  * [RB3][x02] spf core errors found in dmesg
+    - SAUCE: qcom: spf-core: use pr_info() for successful logs
+
+  * [RB3][x03] va_macro error found in dmesg
+    - SAUCE: ASoC: lpass-va-macro: change dt entry missing to dev_info()
+
+  * [RB8][x02] spmi errors found in dmesg
+    - SAUCE: arm64: sa8775: remove allow-set-time property from rtc
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: switch WIFI firmware to *.mbn from *.mdt
+
+  * Miscellaneous upstream changes
+    - msm: camera: icp: Remove Redundant Structure Field
+    - msm: camera: uapi: Adding flex array support to fix UBSAN kernel panic
+    - PENDING: rpmsg: glink: do not serve intent request if no callback present
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 28 May 2025 16:55:09 +0900
+
+linux-qcom (6.8.0-1040.40) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1040.40 -proposed tracker (LP: #2110187)
+
+  * "[6490][x02] tc956x_pci-eth errors found in dmesg"
+    - Ubuntu: SAUCE: change phy detection log-level from alert to info
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: follow-up renaming from qcs9075-rb8 to qcs9075-iq-9075-evk
+
+  * Miscellaneous upstream changes
+    - PENDING: qcom: ice: Add ice probe
+    - PENDING: arm64: dts: qcom: Rename qcs9075-rb8 to qcs9075-iq-9075-evk
+    - QCLINUX: arm64: dts: qcom: qcs9075-addons: Rename rb8 to iq-9075-evk
+    - PENDING: tty: serial: qcom-geni-serial: fix CTS control for UART in loopback
+      mode
+    - QCLINUX: arm64: deconfig: enable CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT
+    - PENDING: misc: fastrpc: Remove PD status check
+    - Revert "FROMLIST: arm64: dts: qcom: sa8775p: Add CPUs to psci power domain"
+    - Revert "BACKPORT: UPSTREAM: arm64: dts: qcom: sa8775p: add CPU idle states"
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 09 May 2025 17:00:23 +0900
+
+linux-qcom (6.8.0-1039.39) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1039.39 -proposed tracker (LP: #2108955)
+
+  * [RB8][x02] hd3ss3220 not boud to the device
+    - Revert "usb: dwc3: core: set force_gen1 bit in USB31 devices if max speed is
+      SS"
+
+  * "[RB8][x02] The firmware for i2c_qcom_geni (qupv3fw.elf) not in
+    initramfs" // "[RB8][x02] qcom_geni_serial errors found in dmesg"
+    - SAUCE: qcom-geni-se.c: add MODULE_FIRMWARE() to copy firmware to initrd
+
+  * Miscellaneous upstream changes
+    - kgsl: Read DDR type from device tree node
+    - qcom: qtee_shmbridge: change pr_err() to pr_info() for bridge size
+    - qcom: qtee_shmbridge: change pr_err() to pr_info() for bridge size
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 24 Apr 2025 12:47:31 +0900
+
+linux-qcom (6.8.0-1038.38) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1038.38 -proposed tracker (LP: #2107286)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.qcom/dkms-versions -- update from kernel-versions
+      (main/d2025.04.13)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: fix firmware for rb8
+
+  * Miscellaneous upstream changes
+    - kgsl: Fix UBSAN warning in kgsl_get_page_size
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 14 Apr 2025 02:26:32 +0900
+
+linux-qcom (6.8.0-1037.37) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1037.37 -proposed tracker (LP: #2106781)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: add QCS6490 industrical kit dt to compiled-dtb.dtb
+    - [Config] Disable CONFIG_DRM_MSM_VALIDATE_XML
+
+  * Miscellaneous upstream changes
+    - QCLINUX: arm64: dts: qcom: qcm6490-graphics: Don't disable drm gpu/gmu nodes
+    - QCLINUX: arm64: dts: qcom: qcs9100-graphics: Don't disable drm gpu/gmu nodes
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 11 Apr 2025 08:22:42 +0900
+
+linux-qcom (6.8.0-1036.36) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1036.36 -proposed tracker (LP: #2105444)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.qcom/dkms-versions -- update from kernel-versions
+      (main/d2025.03.31)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Add Makefile code to apply overlays for GA1.4
+    - [Packaging] build zfs
+
+  * Miscellaneous upstream changes
+    - PENDING: drm/msm/dsi: Add DSI support for SA8775P
+    - PENDING: drm/msm/dsi: add DSI PHY configuration for SA8775P
+    - QCLINUX: Revert "PENDING: drm/bridge: anx7625: Fix circular dependency"
+    - PENDING: arm64: dts: qcom: sa8775p: add DSI CTRL and PHY support
+    - PENDING: ASoC: dt-bindings: q6dsp: Add High Speed Audio DAI ID support for
+      MI2S and TDM
+    - PENDING: net: pcs: Add 5G baseR changes in PCS driver
+    - PENDING: net: stmmac: Add support for 5GbaseR to configure mac
+    - PENDING: ASoC: qcom: q6dsp: Add SDR High speed DAI support for MI2S and TDM
+    - PENDING: ASoC: qcom: qcm9100: Add machine driver for qcs9100-ride and
+      qcs9075-rb8 boards
+    - PENDING: net: phy: aquantia: Add support for 5GbaseR
+    - PENDING: arm64: dts: qcom: sa8775p: add anx7625 DSI to DP bridge nodes
+    - PENDING: drm/bridge: anx7625: vote for pm runtime during bridge attach
+    - PENDING: drm/bridge: anx7625: update bridge_ops and sink detect logic
+    - PENDING: arm64: defconfig: qcom_gen5auto: Enable TSC
+    - PENDING: arm64: dts: qcom: qcs8300: Add support for camss
+    - PENDING: media: qcom: camss: Add support for camss driver on qcs8300
+    - PENDING: media: qcom: camss: add TPG support on camss for qcs8300
+    - PENDING: net: stmmac: Enable PTP Packet id based timestamping
+    - PENDING: net: PCS: Call PCS link up sequence for 10GBASER
+    - PENDING: net: stmmac: Add support for 10GBASER mode within Mac link up
+    - PENDING: ARM: dts: msm: Add RPMh stats for 8255p
+    - QCLINUX: arm64: dts: qcom: Update the DAI ID for SDR High Speed dailinks
+    - QCLINUX: Revert "PENDING: tty: serial: qcom-geni-serial: Increase Rx buffer
+      size"
+    - UPSTREAM: BACKPORT: arm64: dts: qcm6490: Add interconnect for CDSP
+      remoteproc
+    - BACKPORT: FROMLIST: remoteproc: qcom: Add iommu map_unmap helper function
+    - BACKPORT: FROMLIST: remoteproc: qcom: Add helper function to support IOMMU
+      devmem translation
+    - BACKPORT: FROMLIST: remoteproc: qcom: Add support to parse qcom,devmem
+      property
+    - BACKPORT: FROMLIST: remoteproc: qcom: Add support of SHM bridge to enable
+      memory protection
+    - BACKPORT: FROMLIST: remoteproc: qcom: Enable map/unmap and SHM bridge
+      support
+    - QCLINUX: drm/msm: Remove changes made to prevent gpu probe
+    - FROMLIST: arm64: dts: qcom: sa8775p: Add gpu and gmu nodes
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Don't disable drm gpu/gmu nodes
+    - QCLINUX: arm64: dts: qcom: qcs615: addons: Add coresight nodes
+    - PENDING: arm64: dts: qcom: sa8255p: Update hysteresis to 10degC
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add EL2 dtb support
+    - QCLINUX: arm64: dts: qcom: qcs615: addons: Add memory dump table
+    - QCLINUX: arm64: defconfig: qcom: Enable QCS9100 machine driver config
+    - PENDING: arm64: dts: qcom: sa7255p: Disable USB U1/U2 entry
+    - FROMGIT: arm64: dts: qcom: sc8280xp: Disable USB U1/U2 entry
+    - FROMGIT: arm64: dts: qcom: sc8180x: Disable USB U1/U2 entry
+    - PENDING: Coresight: Add an integer array to tmc driver data
+    - PENDING: pinctrl: qcom: fix sa8775p lpass lpi quad pinctrl setting
+    - FROMLIST: arm64: dts: qcom: sa8775p: Remove extra entries from the iommus
+      property
+    - QCLINUX: arm64: dts: qcom: add hs0 mi2s dai for qcs9075-rb8
+    - QCLINUX: arm64: dts: qcom: qcs615: addons: Enable DCC
+    - PENDING: usb: dwc3: qcom: Adding GPIO-based regulator functionality for VBUS
+    - PENDING: arm64: dts: configs: Enable HD3SS322 USB Type-C DRP port controller
+      driver on QCS9075 RB8
+    - PENDING: arm64: dts: qcom: Flatten USB DT node for USB0 on QCS9075 RB8
+      Platform
+    - PENDING: arm64: dts: qcom: Add DRD mode support for USB0 on QCS9075 RB8
+    - PENDING: arm64: dts: qcom: Flatten USB DT node for USB1 on QCS9075 RB8
+      Platform
+    - PENDING: arm64: dts: qcom: Add host mode support for USB1 on QCS9075 RB8
+    - FROMLIST: dt-bindings: clock: Add Qualcomm QCS615 Camera clock controller
+    - FROMLIST: clk: qcom: camcc-qcs615: Add QCS615 camera clock controller driver
+    - FROMLIST: dt-bindings: clock: Add Qualcomm QCS615 Display clock controller
+    - FROMLIST: clk: qcom: dispcc-qcs615: Add QCS615 display clock controller
+      driver
+    - FROMLIST: dt-bindings: clock: Add Qualcomm QCS615 Graphics clock controller
+    - FROMLIST: clk: qcom: gpucc-qcs615: Add QCS615 graphics clock controller
+      driver
+    - FROMLIST: dt-bindings: clock: Add Qualcomm QCS615 Video clock controller
+    - FROMLIST: clk: qcom: videocc-qcs615: Add QCS615 video clock controller
+      driver
+    - FROMLIST: arm64: defconfig: Enable QCS615 clock controllers
+    - PENDING: ASoC: qcom: q6dsp: Update formats and max rate for Primary i2s
+    - QCLINUX: arm64: defconfigs: Disable TBU support
+    - FROMLIST: arm64: dts: qcom: sa8775p-ride: Add firmware-name in BT node
+    - QCLINUX: Revert "PENDING: arm64: qcs9075-rb8: disable uart bt en pin in DTS"
+    - FROMLIST: arm64: dts: qcom: sa8775p: Remove cdsp compute-cb@10
+    - FROMLIST: arm64: dts: qcom: qcs8300-ride: Add firmware-name in BT node
+    - PENDING: arm64: dts: qcom: qcs8300: enable DSI-DP bridge port on QCS8300
+    - PENDING: driver: bluetooth: hci_qca: fix SSR unable to wake up bug
+    - QCLINUX: arm64: deconfig: Enable QCS615 clock controllers
+    - FROMLIST: arm64: dts: qcom: Add clock nodes for multimedia clock
+    - FROMLIST: arm64: dts: qcom: Add cpu scaling clock node
+    - QCLINUX: ASoC: qcom: common: Add qcom_snd_parse_of_v2 support
+    - QCLINUX: arm64: defconfigs: Enable CONFIG_PM_DEBUG
+    - PENDING: serial: qcom-geni: Optimize qcom_geni_uart_ports and increase UART
+      ports to 5
+    - QCLINUX: firmware: qcom_tzmem: Use ns_vmid_num to set self owner bit
+    - QCLINUX: arm64: dts: qcom: sa8775p: Fix cdsp1 node properties
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add EL2 dtb support for ride board
+    - PENDING: ASoC: qcom: q6dsp: Update rates for Primary i2s rx
+    - QCLINUX: arm64: dts: Remove unused pcie1 QPS615 phy node for QEP8121
+    - PENDING: arm64: dts: qcom: qcs9075: Add displayport1 device node
+    - PENDING: serial: qcom-geni-serial: Enable support for
+    - PENDING: net: stmmac: dwmac-qcom-ethqos: Configure host DMA width for
+      SA8797P
+    - QCLINUX: arm64: dts: Replace AQR113c phy with RTL8211 phy
+    - QCLINUX: arm64: defconfig: enable Novatek NT36672E and Lontium lt9611UXC
+      configs
+    - PENDING: net: stmmac: Fix NULL pointer access for GPTP packets
+    - PENDING: arm64: dts: qcom: qcs9075: Change phy-mode to SGMII
+    - QCLINUX: ASoC: qcom: qcm6490: Use qcom_snd_parse_of_v2 to support common
+      dailink data
+    - PENDING: ASoC: qcom: qcm9100: Fix the dapm routings for qcs8300
+    - QCLINUX: duplicate msm/ to msm_default/
+    - QCLINUX: Add support to compile msm_display.ko
+    - Ubuntu: [Config] update CONFIGs for GA 1.4
+
+  [ Ubuntu: 6.8.0-56.58 ]
+
+  * noble/linux: 6.8.0-56.58 -proposed tracker (LP: #2098244)
+  * Noble update: upstream stable patchset 2024-07-19 (LP: #2073603)
+    - Revert "drm: Make drivers depends on DRM_DW_HDMI"
+    - Revert "UBUNTU: [Config] Drivers now depend on DRM_DW_HDMI"
+  * drm/amd/display: Add check for granularity in dml ceil/floor helpers
+    (LP: #2098080)
+    - drm/amd/display: Add check for granularity in dml ceil/floor helpers
+  * optimized default EPP for GNR family (LP: #2097554)
+    - cpufreq: intel_pstate: Update Balance-performance EPP for Granite Rapids
+  * Incorrect LAPIC/x2APIC parsing order (LP: #2097455)
+    - x86/acpi: Fix LAPIC/x2APIC parsing order
+  * MGLRU: page allocation failure on NUMA-enabled systems (LP: #2097214)
+    - mm/vmscan: wake up flushers conditionally to avoid cgroup OOM
+  * Upstream commit 65357e2c164a: "RDMA/mana_ib: set node_guid" applied
+    incorrectly (LP: #2096885)
+    - Revert "RDMA/mana_ib: set node_guid"
+  * AppArmor early policy load not funcitoning (LP: #2095370)
+    - SAUCE: Revert "UBUNTU: SAUCE: apparmor4.0.0 [67/90]: userns - add the
+      ability to reference a global variable for a feature value"
+  * apparmor unconfined profile blocks pivot_root (LP: #2067900)
+    - SAUCE: Revert "UBUNTU: SAUCE: apparmor4.0.0 [81/90]: apparmor: convert easy
+      uses of unconfined() to label_mediates()"
+  * CVE-2024-50117
+    - drm/amd: Guard against bad data for ATIF ACPI method
+  * CVE-2024-56582
+    - btrfs: fix use-after-free in btrfs_encoded_read_endio()
+  * CVE-2024-53165
+    - sh: intc: Fix use-after-free bug in register_intc_controller()
+  * CVE-2024-53156
+    - wifi: ath9k: add range check for conn_rsp_epid in htc_connect_service()
+  * CVE-2024-56663
+    - wifi: nl80211: fix NL80211_ATTR_MLO_LINK_ID off-by-one
+  * CVE-2024-56614
+    - xsk: fix OOB map writes when deleting elements
+  * VM boots slowly with large-BAR GPU Passthrough due to pci/probe.c redundancy
+    (LP: #2097389)
+    - PCI: Batch BAR sizing operations
+  * Noble update: upstream stable patchset 2025-02-04 (LP: #2097393)
+    - Revert "PCI/MSI: Provide stubs for IMS functions"
+    - gfs2: Revert "introduce qd_bh_get_or_undo"
+    - gfs2: qd_check_sync cleanups
+    - gfs2: Revert "ignore negated quota changes"
+    - Revert "powerpc/ps3_defconfig: Disable PPC64_BIG_ENDIAN_ELF_ABI_V2"
+    - tracing: Have saved_cmdlines arrays all in one allocation
+    - spi: spi-fsl-lpspi: remove redundant spi_controller_put call
+    - ata: ahci: Add mask_port_map module parameter
+    - ASoC: tas2781: mark dvc_tlv with __maybe_unused
+    - scsi: sd: Do not repeat the starting disk message
+    - bootconfig: Fix the kerneldoc of _xbc_exit()
+    - perf sched: Move start_work_mutex and work_done_wait_mutex initialization to
+      perf_sched__replay()
+    - perf sched: Fix memory leak in perf_sched__map()
+    - perf sched: Move curr_thread initialization to perf_sched__map()
+    - perf sched: Move curr_pid and cpu_last_switched initialization to
+      perf_sched__{lat|map|replay}()
+    - libsubcmd: Don't free the usage string
+    - selftests: Introduce Makefile variable to list shared bash scripts
+    - jbd2: fix kernel-doc for j_transaction_overhead_buffers
+    - lib/build_OID_registry: avoid non-destructive substitution for Perl < 5.13.2
+      compat
+    - drm/amd/display: Remove a redundant check in authenticated_dp
+    - drm/amd/display: Revert "Check HDCP returned status"
+    - zram: don't free statically defined names
+    - x86/amd_nb: Add new PCI IDs for AMD family 0x1a
+    - rtnetlink: change nlk->cb_mutex role
+    - rtnetlink: add RTNL_FLAG_DUMP_UNLOCKED flag
+    - mpls: no longer hold RTNL in mpls_netconf_dump_devconf()
+    - phonet: no longer hold RTNL in route_dumpit()
+    - rcu/nocb: Make IRQs disablement symmetric
+    - HID: asus: add ROG Ally N-Key ID and keycodes
+    - HID: asus: add ROG Z13 lightbar
+    - hid-asus: add ROG Ally X prod ID to quirk list
+    - scsi: Revert "scsi: sd: Do not repeat the starting disk message"
+    - btrfs: fix uninitialized pointer free in add_inode_ref()
+    - btrfs: fix uninitialized pointer free on read_alloc_one_name() error
+    - ksmbd: fix user-after-free from session log off
+    - ALSA: hda/conexant - Fix audio routing for HP EliteOne 1000 G2
+    - mptcp: pm: fix UaF read in mptcp_pm_nl_rm_addr_or_subflow
+    - net: enetc: remove xdp_drops statistic from enetc_xdp_drop()
+    - net: enetc: block concurrent XDP transmissions during ring reconfiguration
+    - net: enetc: disable Tx BD rings after they are empty
+    - net: enetc: disable NAPI after all rings are disabled
+    - net: enetc: add missing static descriptor and inline keyword
+    - posix-clock: Fix missing timespec64 check in pc_clock_settime()
+    - udp: Compute L4 checksum as usual when not segmenting the skb
+    - arm64: probes: Remove broken LDR (literal) uprobe support
+    - arm64: probes: Fix simulate_ldr*_literal()
+    - arm64: probes: Fix uprobes for big-endian kernels
+    - net: macb: Avoid 20s boot delay by skipping MDIO bus registration for fixed-
+      link PHY
+    - net: microchip: vcap api: Fix memory leaks in vcap_api_encode_rule_test()
+    - maple_tree: correct tree corruption on spanning store
+    - nilfs2: propagate directory read errors from nilfs_find_entry()
+    - fat: fix uninitialized variable
+    - mm/mremap: fix move_normal_pmd/retract_page_tables race
+    - mm/swapfile: skip HugeTLB pages for unuse_vma
+    - mm/damon/tests/sysfs-kunit.h: fix memory leak in
+      damon_sysfs_test_add_targets()
+    - tcp: fix mptcp DSS corruption due to large pmtu xmit
+    - net: fec: Move `fec_ptp_read()` to the top of the file
+    - net: fec: Remove duplicated code
+    - mptcp: prevent MPC handshake on port-based signal endpoints
+    - iommu/vt-d: Fix incorrect pci_for_each_dma_alias() for non-PCI devices
+    - s390/sclp: Deactivate sclp after all its users
+    - s390/sclp_vt220: Convert newlines to CRLF instead of LFCR
+    - KVM: s390: gaccess: Check if guest address is in memslot
+    - KVM: s390: Change virtual to physical address access in diag 0x258 handler
+    - x86/cpufeatures: Define X86_FEATURE_AMD_IBPB_RET
+    - x86/cpufeatures: Add a IBPB_NO_RET BUG flag
+    - x86/entry: Have entry_ibpb() invalidate return predictions
+    - x86/bugs: Skip RSB fill at VMEXIT
+    - x86/bugs: Do not use UNTRAIN_RET with IBPB on entry
+    - fgraph: Use CPU hotplug mechanism to initialize idle shadow stacks
+    - blk-rq-qos: fix crash on rq_qos_wait vs. rq_qos_wake_function race
+    - io_uring/sqpoll: close race on waiting for sqring entries
+    - blk-mq: setup queue ->tag_set before initializing hctx
+    - ublk: don't allow user copy for unprivileged device
+    - selftest: hid: add the missing tests directory
+    - Input: xpad - add support for MSI Claw A1M
+    - scsi: mpi3mr: Correct a test in mpi3mr_sas_port_add()
+    - scsi: mpi3mr: Validate SAS port assignments
+    - scsi: ufs: core: Set SDEV_OFFLINE when UFS is shut down
+    - scsi: ufs: core: Fix the issue of ICU failure
+    - scsi: ufs: core: Requeue aborted request
+    - drm/radeon: Fix encoder->possible_clones
+    - drm/i915/dp_mst: Handle error during DSC BW overhead/slice calculation
+    - drm/i915/dp_mst: Don't require DSC hblank quirk for a non-DSC compatible
+      mode
+    - drm/xe/xe_sync: initialise ufence.signalled
+    - drm/xe/ufence: ufence can be signaled right after wait_woken
+    - drm/vmwgfx: Cleanup kms setup without 3d
+    - drm/vmwgfx: Handle surface check failure correctly
+    - drm/amdgpu/pm: Fix code alignment issue
+    - drm/amdgpu/smu13: always apply the powersave optimization
+    - drm/amdgpu/swsmu: Only force workload setup on init
+    - iio: dac: ad5770r: add missing select REGMAP_SPI in Kconfig
+    - iio: dac: ltc1660: add missing select REGMAP_SPI in Kconfig
+    - iio: dac: stm32-dac-core: add missing select REGMAP_MMIO in Kconfig
+    - iio: adc: ti-ads8688: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: hid-sensors: Fix an error handling path in
+      _hid_sensor_set_report_latency()
+    - iio: light: veml6030: fix ALS sensor resolution
+    - iio: light: veml6030: fix IIO device retrieval from embedded device
+    - iio: light: opt3001: add missing full-scale range value
+    - iio: amplifiers: ada4250: add missing select REGMAP_SPI in Kconfig
+    - iio: frequency: adf4377: add missing select REMAP_SPI in Kconfig
+    - iio: light: bu27008: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: resolver: ad2s1210 add missing select REGMAP in Kconfig
+    - iio: pressure: bm1390: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: dac: ad5766: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: proximity: mb1232: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: dac: ad3552r: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: adc: ti-lmp92064: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: adc: ti-lmp92064: add missing select REGMAP_SPI in Kconfig
+    - iio: adc: ti-ads124s08: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: resolver: ad2s1210: add missing select (TRIGGERED_)BUFFER in Kconfig
+    - iio: accel: kx022a: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - Bluetooth: Call iso_exit() on module unload
+    - Bluetooth: Remove debugfs directory on module init failure
+    - Bluetooth: ISO: Fix multiple init when debugfs is disabled
+    - Bluetooth: btusb: Fix not being able to reconnect after suspend
+    - Bluetooth: btusb: Fix regression with fake CSR controllers 0a12:0001
+    - vt: prevent kernel-infoleak in con_font_get()
+    - xhci: tegra: fix checked USB2 port number
+    - xhci: Fix incorrect stream context type macro
+    - xhci: Mitigate failed set dequeue pointer commands
+    - USB: serial: option: add support for Quectel EG916Q-GL
+    - USB: serial: option: add Telit FN920C04 MBIM compositions
+    - usb: typec: qcom-pmic-typec: fix sink status being overwritten with RP_DEF
+    - usb: dwc3: Wait for EndXfer completion before restoring GUSB2PHYCFG
+    - misc: microchip: pci1xxxx: add support for NVMEM_DEVID_AUTO for EEPROM
+      device
+    - misc: microchip: pci1xxxx: add support for NVMEM_DEVID_AUTO for OTP device
+    - serial: imx: Update mctrl old_status on RTSD interrupt
+    - parport: Proper fix for array out-of-bounds access
+    - x86/resctrl: Annotate get_mem_config() functions as __init
+    - x86/apic: Always explicitly disarm TSC-deadline timer
+    - x86/CPU/AMD: Only apply Zenbleed fix for Zen2 during late microcode load
+    - x86/entry_32: Do not clobber user EFLAGS.ZF
+    - x86/entry_32: Clear CPU buffers after register restore in NMI return
+    - tty: n_gsm: Fix use-after-free in gsm_cleanup_mux
+    - x86/bugs: Use code segment selector for VERW operand
+    - pinctrl: intel: platform: fix error path in device_for_each_child_node()
+    - pinctrl: ocelot: fix system hang on level based interrupts
+    - pinctrl: stm32: check devm_kasprintf() returned value
+    - pinctrl: apple: check devm_kasprintf() returned value
+    - irqchip/gic-v4: Don't allow a VMOVP on a dying VPE
+    - irqchip/sifive-plic: Unmask interrupt in plic_irq_enable()
+    - serial: qcom-geni: fix polled console initialisation
+    - serial: qcom-geni: revert broken hibernation support
+    - serial: qcom-geni: fix shutdown race
+    - serial: qcom-geni: fix dma rx cancellation
+    - serial: qcom-geni: fix receiver enable
+    - mm: vmscan.c: fix OOM on swap stress test
+    - ALSA: hda/conexant - Use cached pin control for Node 0x1d on HP EliteOne
+      1000 G2
+    - Upstream stable to v6.6.57, v6.11.5
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301)
+    - Revert "perf callchain: Fix stitch LBR memory leaks"
+    - ASoC: amd: acp: add ZSC control register programming sequence
+    - virtio: rename virtio_config_enabled to virtio_config_core_enabled
+    - virtio: allow driver to disable the configure change notification
+    - virtio-net: synchronize operstate with admin state on up/down
+    - virtio-net: synchronize probe with ndo_set_features
+    - wifi: rtw89: limit the PPDU length for VHT rate to 0x40000
+    - af_unix: Don't call skb_get() for OOB skb.
+    - af_unix: Remove single nest in manage_oob().
+    - af_unix: Rename unlinked_skb in manage_oob().
+    - af_unix: Move spin_lock() in manage_oob().
+    - iommu/amd: Move allocation of the top table into v1_alloc_pgtable
+    - iommu/amd: Set the pgsize_bitmap correctly
+    - drm/xe: Move and export xe_hw_engine lookup.
+    - drm/msm/dp: rename wide_bus_en to wide_bus_supported
+    - drm/msm/dp: enable widebus on all relevant chipsets
+    - bpf, arm64: Fix tailcall hierarchy
+    - libbpf: Don't take direct pointers into BTF data from st_ops
+    - s390/entry: Move early program check handler to entry.S
+    - selftests/bpf: fix to avoid __msg tag de-duplication by clang
+    - libbpf: Ensure new BTF objects inherit input endianness
+    - PCI: dwc: ep: Rename dw_pcie_ep_exit() to dw_pcie_ep_deinit()
+    - PCI: qcom-ep: Enable controller resources like PHY only after refclk is
+      available
+    - net: ravb: Fix maximum TX frame size for GbEth devices
+    - ravb: Make it clear the information relates to maximum frame size
+    - net: ravb: Fix R-Car RX frame size limit
+    - netfilter: nf_tables: missing objects with no memcg accounting
+    - PCI: dra7xx: Fix error handling when IRQ request fails in probe
+    - KVM: x86: Re-split x2APIC ICR into ICR+ICR2 for AMD (x2AVIC)
+    - intel_idle: fix ACPI _CST matching for newer Xeon platforms
+    - wifi: mt76: mt7925: fix a potential association failure upon resuming
+    - cifs: Remove intermediate object of failed create reparse call
+    - drm/amd/display: Disable replay if VRR capability is false
+    - drm/amd/display: Fix VRR cannot enable
+    - l2tp: free sessions using rcu
+    - net: skbuff: sprinkle more __GFP_NOWARN on ingress allocs
+    - nvme: fix metadata handling in nvme-passthrough
+    - wifi: wilc1000: Do not operate uninitialized hardware during suspend/resume
+    - x86/apic: Remove logical destination mode for 64-bit
+    - pmdomain: core: Use dev_name() instead of kobject_get_path() in debugfs
+    - drm/xe: Name and document Wa_14019789679
+    - drm/xe: Add timeout to preempt fences
+    - drm/amd/display: Fix possible overflow in integer multiplication
+    - ext4: fix error message when rejecting the default hash
+    - power: supply: Drop use_cnt check from power_supply_property_is_writeable()
+    - ALSA: hda/realtek: fix mute/micmute LED for HP mt645 G8
+    - drm/xe: Generate oob before compiling anything
+    - clk: qcom: gcc-sc8180x: Register QUPv3 RCGs for DFS on sc8180x
+    - drm/amd/display: Restore Optimized pbn Value if Failed to Disable DSC
+    - Revert "drm/amd/display: Skip Recompute DSC Params if no Stream on Link"
+    - pmdomain: core: Reduce debug summary table width
+    - fs/ntfs3: Do not call file_modified if collapse range failed
+    - fs/ntfs3: Optimize large writes into sparse file
+    - fs/ntfs3: Fix sparse warning in ni_fiemap
+    - fs/ntfs3: Refactor enum_rstbl to suppress static checker
+    - virtio_console: fix misc probe bugs
+    - ntfs3: Change to non-blocking allocation in ntfs_d_hash
+    - bpf: Call the missed btf_record_free() when map creation fails
+    - selftests/bpf: Fix ARG_PTR_TO_LONG {half-,}uninitialized test
+    - bpf: Check percpu map value size first
+    - s390/facility: Disable compile time optimization for decompressor code
+    - s390/mm: Add cond_resched() to cmm_alloc/free_pages()
+    - bpf, x64: Fix a jit convergence issue
+    - ext4: nested locking for xattr inode
+    - s390/cpum_sf: Remove WARN_ON_ONCE statements
+    - ktest.pl: Avoid false positives with grub2 skip regex
+    - soundwire: intel_bus_common: enable interrupts before exiting reset
+    - PCI: Add function 0 DMA alias quirk for Glenfly Arise chip
+    - clk: bcm: bcm53573: fix OF node leak in init
+    - PCI: Add ACS quirk for Qualcomm SA8775P
+    - i2c: i801: Use a different adapter-name for IDF adapters
+    - PCI: Mark Creative Labs EMU20k2 INTx masking as broken
+    - RISC-V: Don't have MAX_PHYSMEM_BITS exceed phys_addr_t
+    - mfd: intel_soc_pmic_chtwc: Make Lenovo Yoga Tab 3 X90F DMI match less strict
+    - mfd: intel-lpss: Add Intel Arrow Lake-H LPSS PCI IDs
+    - mfd: intel-lpss: Rename SPI intel_lpss_platform_info structs
+    - mfd: intel-lpss: Add Intel Panther Lake LPSS PCI IDs
+    - riscv: Omit optimized string routines when using KASAN
+    - riscv: avoid Imbalance in RAS
+    - RDMA/mlx5: Enforce umem boundaries for explicit ODP page faults
+    - PCI: qcom: Disable mirroring of DBI and iATU register space in BAR region
+    - PCI: endpoint: Assign PCI domain number for endpoint controllers
+    - soundwire: cadence: re-check Peripheral status with delayed_work
+    - riscv/kexec_file: Fix relocation type R_RISCV_ADD16 and R_RISCV_SUB16
+      unknown
+    - media: videobuf2-core: clear memory related fields in
+      __vb2_plane_dmabuf_put()
+    - remoteproc: imx_rproc: Use imx specific hook for find_loaded_rsc_table
+    - usb: chipidea: udc: enable suspend interrupt after usb reset
+    - usb: dwc2: Adjust the timing of USB Driver Interrupt Registration in the
+      Crashkernel Scenario
+    - xhci: dbc: Fix STALL transfer event handling
+    - usb: host: xhci-plat: Parse xhci-missing_cas_quirk and apply quirk
+    - comedi: ni_routing: tools: Check when the file could not be opened
+    - LoongArch: Fix memleak in pci_acpi_scan_root()
+    - netfilter: nf_nat: don't try nat source port reallocation for reverse dir
+      clash
+    - netfilter: nf_reject: Fix build warning when CONFIG_BRIDGE_NETFILTER=n
+    - tools/iio: Add memory allocation failure check for trigger_name
+    - staging: vme_user: added bound check to geoid
+    - driver core: bus: Return -EIO instead of 0 when show/store invalid bus
+      attribute
+    - scsi: lpfc: Add ELS_RSP cmd to the list of WQEs to flush in
+      lpfc_els_flush_cmd()
+    - scsi: lpfc: Revise TRACE_EVENT log flag severities from KERN_ERR to
+      KERN_WARNING
+    - NFSD: Mark filecache "down" if init fails
+    - nfsd: nfsd_destroy_serv() must call svc_destroy() even if nfsd_startup_net()
+      failed
+    - ice: set correct dst VSI in only LAN filters
+    - ice: clear port vlan config during reset
+    - ice: disallow DPLL_PIN_STATE_SELECTABLE for dpll output pins
+    - ice: fix VLAN replay after reset
+    - SUNRPC: Fix integer overflow in decode_rc_list()
+    - tcp: fix to allow timestamp undo if no retransmits were sent
+    - tcp: fix tcp_enter_recovery() to zero retrans_stamp when it's safe
+    - tcp: fix TFO SYN_RECV to not zero retrans_stamp with retransmits out
+    - rxrpc: Fix uninitialised variable in rxrpc_send_data()
+    - selftests: net: no_forwarding: fix VID for $swp2 in one_bridge_two_pvids()
+      test
+    - Bluetooth: btusb: Don't fail external suspend requests
+    - net: phy: bcm84881: Fix some error handling paths
+    - Revert "net: stmmac: set PP_FLAG_DMA_SYNC_DEV only if XDP is enabled"
+    - net: ethernet: adi: adin1110: Fix some error handling path in
+      adin1110_read_fifo()
+    - net: dsa: b53: fix jumbo frame mtu check
+    - net: dsa: b53: fix max MTU for 1g switches
+    - net: dsa: b53: fix max MTU for BCM5325/BCM5365
+    - net: dsa: b53: allow lower MTUs on BCM5325/5365
+    - net: dsa: b53: fix jumbo frames on 10/100 ports
+    - drm/nouveau: pass cli to nouveau_channel_new() instead of drm+device
+    - nouveau/dmem: Fix privileged error in copy engine channel
+    - gpio: aspeed: Add the flush write to ensure the write complete.
+    - gpio: aspeed: Use devm_clk api to manage clock source
+    - powercap: intel_rapl_tpmi: Ignore minor version change
+    - ice: Fix netif_is_ice() in Safe Mode
+    - ice: Flush FDB entries before reset
+    - e1000e: change I219 (19) devices to ADP
+    - net: ibm: emac: mal: fix wrong goto
+    - btrfs: zoned: fix missing RCU locking in error message when loading zone
+      info
+    - sctp: ensure sk_state is set to CLOSED if hashing fails in sctp_listen_start
+    - netfilter: fib: check correct rtable in vrf setups
+    - net: ibm: emac: mal: add dcr_unmap to _remove
+    - net: dsa: refuse cross-chip mirroring operations
+    - rtnetlink: Add bulk registration helpers for rtnetlink message handlers.
+    - vxlan: Handle error of rtnl_register_module().
+    - bridge: Handle error of rtnl_register_module().
+    - mctp: Handle error of rtnl_register_module().
+    - mpls: Handle error of rtnl_register_module().
+    - phonet: Handle error of rtnl_register_module().
+    - rcu/nocb: Fix rcuog wake-up from offline softirq
+    - x86/amd_nb: Add new PCI IDs for AMD family 1Ah model 60h
+    - HID: multitouch: Add support for lenovo Y9000P Touchpad
+    - hwmon: intel-m10-bmc-hwmon: relabel Columbiaville to CVL Die Temperature
+    - hwmon: (tmp513) Add missing dependency on REGMAP_I2C
+    - hwmon: (mc34vr500) Add missing dependency on REGMAP_I2C
+    - hwmon: (adm9240) Add missing dependency on REGMAP_I2C
+    - hwmon: (adt7470) Add missing dependency on REGMAP_I2C
+    - hwmon: (ltc2991) Add missing dependency on REGMAP_I2C
+    - HID: plantronics: Workaround for an unexcepted opposite volume key
+    - Revert "usb: yurex: Replace snprintf() with the safer scnprintf() variant"
+    - usb: dwc3: core: Stop processing of pending events if controller is halted
+    - usb: xhci: Fix problem with xhci resume from suspend
+    - usb: storage: ignore bogus device raised by JieLi BR21 USB sound chip
+    - usb: dwc3: re-enable runtime PM after failed resume
+    - usb: gadget: core: force synchronous registration
+    - hid: intel-ish-hid: Fix uninitialized variable 'rv' in
+      ish_fw_xfer_direct_dma
+    - ACPI: resource: Make Asus ExpertBook B2402 matches cover more models
+    - ACPI: resource: Make Asus ExpertBook B2502 matches cover more models
+    - drm/amdkfd: Fix an eviction fence leak
+    - drm/amd/display: fix hibernate entry for DCN35+
+    - drm/xe/guc_submit: fix xa_store() error checking
+    - drm/i915/hdcp: fix connector refcounting
+    - drm/xe/ct: fix xa_store() error checking
+    - scsi: ufs: Use pre-calculated offsets in ufshcd_init_lrb()
+    - mmc: sdhci-of-dwcmshc: Prevent stale command interrupt handling
+    - mptcp: fallback when MPTCP opts are dropped after 1st data
+    - ata: libata: avoid superfluous disk spin down + spin up during hibernation
+    - OPP: fix error code in dev_pm_opp_set_config()
+    - net: dsa: lan9303: ensure chip reset and wait for READY status
+    - mptcp: pm: do not remove closing subflows
+    - powercap: intel_rapl_tpmi: Fix bogus register reading
+    - selftests/mm: fix incorrect buffer->mirror size in hmm2 double_map test
+    - selftests/rseq: Fix mm_cid test failure
+    - btrfs: split remaining space to discard in chunks
+    - btrfs: add cancellation points to trim loops
+    - fs/proc/kcore.c: allow translation of physical memory addresses
+    - io_uring/rw: fix cflags posting for single issue multishot read
+    - Upstream stable to v6.6.56, v6.11.1, v6.11.2, v6.11.3, v6.11.4
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50182
+    - secretmem: disable memfd_secret() if arch cannot set direct map
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50019
+    - kthread: unpark only parked kthread
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50096
+    - nouveau/dmem: Fix vulnerability in migrate_to_ram upon copy error
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50020
+    - ice: Fix improper handling of refcount in ice_sriov_set_msix_vec_count()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50021
+    - ice: Fix improper handling of refcount in ice_dpll_init_rclk_pins()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50022
+    - device-dax: correct pgoff align in dax_set_mapping()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50185
+    - mptcp: handle consistently DSS corruption
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50023
+    - net: phy: Remove LED entry from LEDs list on unregister
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50024
+    - net: Fix an unsafe loop on the list
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50186
+    - net: explicitly clear the sk pointer, when pf->create fails
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50025
+    - scsi: fnic: Move flush_work initialization out of if block
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50026
+    - scsi: wd33c93: Don't use stale scsi_pointer value
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50027
+    - thermal: core: Free tzp copy along with the thermal zone
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50028
+    - thermal: core: Reference count the zone in thermal_zone_get_by_id()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50029
+    - Bluetooth: hci_conn: Fix UAF in hci_enhanced_setup_sync
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50030
+    - drm/xe/ct: prevent UAF in send_recv()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50187
+    - drm/vc4: Stop the active perfmon before being destroyed
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50031
+    - drm/v3d: Stop the active perfmon before being destroyed
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50189
+    - HID: amd_sfh: Switch to device-managed dmam_alloc_coherent()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50033
+    - slip: make slhc_remember() more robust against malicious packets
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50035
+    - ppp: fix ppp_async_encode() illegal access
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50036
+    - net: do not delay dst_entries_add() in dst_release()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50038
+    - netfilter: xtables: avoid NFPROTO_UNSPEC where needed
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50039
+    - net/sched: accept TCA_STAB only for root qdisc
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50040
+    - igb: Do not bring the device up after non-fatal error
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50041
+    - i40e: Fix macvlan leak by synchronizing access to mac_filter_hash
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50042
+    - ice: Fix increasing MSI-X on VF
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50093
+    - thermal: intel: int340x: processor: Fix warning during module unload
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50044
+    - Bluetooth: RFCOMM: FIX possible deadlock in rfcomm_sk_state_change
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50045
+    - netfilter: br_netfilter: fix panic with metadata_dst skb
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50188
+    - net: phy: dp83869: fix memory corruption when enabling fiber
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50046
+    - NFSv4: Prevent NULL-pointer dereference in nfs42_complete_copies()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50180
+    - fbdev: sisfb: Fix strbuf array overflow
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50047
+    - smb: client: fix UAF in async decryption
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50048
+    - fbcon: Fix a NULL pointer dereference issue in fbcon_putcs
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50049
+    - drm/amd/display: Check null pointer before dereferencing se
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50090
+    - drm/xe/oa: Fix overflow in oa batch buffer
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50183
+    - scsi: lpfc: Ensure DA_ID handling completion before deleting an NPIV
+      instance
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50055
+    - driver core: bus: Fix double free in driver API bus_register()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50056
+    - usb: gadget: uvc: Fix ERR_PTR dereference in uvc_v4l2.c
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50184
+    - virtio_pmem: Check device status before requesting flush
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50057
+    - usb: typec: tipd: Free IRQ only if it was requested before
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50058
+    - serial: protect uart_port_dtr_rts() in uart_shutdown() too
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50181
+    - clk: imx: Remove CLK_SET_PARENT_GATE for DRAM mux for i.MX7D
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50059
+    - ntb: ntb_hw_switchtec: Fix use after free vulnerability in
+      switchtec_ntb_remove due to race condition
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50060
+    - io_uring: check if we need to reschedule during overflow flush
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50061
+    - i3c: master: cdns: Fix use after free vulnerability in cdns_i3c_master
+      Driver Due to Race Condition
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50062
+    - RDMA/rtrs-srv: Avoid null pointer deref during path establishment
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50095
+    - RDMA/mad: Improve handling of timed out WRs of mad agent
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50063
+    - bpf: Prevent tail call between progs attached to different hooks
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50191
+    - ext4: don't set SB_RDONLY after filesystem errors
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50064
+    - zram: free secondary algorithms names
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50089
+    - unicode: Don't special case ignorable code points
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49865
+    - drm/xe/vm: move xa_alloc to prevent UAF
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49968
+    - ext4: filesystems without casefold feature cannot be mounted with siphash
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49893
+    - drm/amd/display: Check stream_status before it is used
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49972
+    - drm/amd/display: Deallocate DML memory if allocation fails
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49914
+    - drm/amd/display: Add null check for pipe_ctx->plane_state in
+      dcn20_program_pipe
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49920
+    - drm/amd/display: Check null pointers before multiple uses
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49921
+    - drm/amd/display: Check null pointers before used
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50009
+    - cpufreq: amd-pstate: add check for cpufreq_cpu_get's return value
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-47726
+    - f2fs: fix to wait dio completion
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-47711
+    - af_unix: Don't return OOB skb in manage_oob().
+  * CVE-2024-53170
+    - block: fix uaf for flush rq while iterating tags
+  * CVE-2024-50148
+    - Bluetooth: bnep: fix wild-memory-access in proto_unregister
+  * CVE-2024-50134
+    - drm/vboxvideo: Replace fake VLA at end of vbva_mouse_pointer_shape with real
+      VLA
+  * CVE-2024-50171
+    - net: systemport: fix potential memory leak in bcm_sysport_xmit()
+  * CVE-2024-50229
+    - nilfs2: fix potential deadlock with newly created symlinks
+  * CVE-2024-50233
+    - staging: iio: frequency: ad9832: fix division by zero in
+      ad9832_calc_freqreg()
+  * [Lenovo Ubuntu 24.04 Bug] dmesg show "spi-nor: probe of spi0.0 failed with
+    error -95" (LP: #2070339)
+    - mtd: core: Don't fail mtd_otp_nvmem_add() if OTP is unsupported
+    - mtd: core: Align comment with an action in mtd_otp_nvmem_add()
+  * python perf module missing in realtime kernel (LP: #2089411)
+    - [Packaging] linux-tools: Add missing python perf symlink
+    - [Packaging] linux-tools: Fix python perf library packaging
+    - [Packaging] linux-tools: Fall back to old python perf path
+  * CVE-2024-53104
+    - media: uvcvideo: Skip parsing frames of type UVC_VS_UNDEFINED in
+      uvc_parse_format
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 31 Mar 2025 03:30:47 +0900
+
+linux-qcom (6.8.0-1035.35) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1034.34 -proposed tracker (LP: #2103614)
+
+  * [RB8] iris_vpu module crashes the kernel
+    - Ubuntu: [Config] enable CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
+
+  * Miscellaneous upstream changes
+    - kgsl: Add support for using compatible string "qcom,kgsl"
+    - ARM: dts: msm: Don't allow drm driver probe kgsl nodes
+    - QCLINUX: drm/msm: Remove changes made to prevent gpu probe
+    - FROMLIST: arm64: dts: qcom: sa8775p: Add gpu and gmu nodes
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Don't disable drm gpu/gmu nodes
+    - BACKPORT: arm64: dts: qcom: sc7280: don't enable GPU on unsupported devices
+    - QCLINUX: arm64: deconfig: enable CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT
+    - QCLINUX: Add support to compile msm_display.ko
+    - Ubuntu: [Config] enable CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 19 Mar 2025 23:02:25 +0900
+
+linux-qcom (6.8.0-1033.33) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1033.33 -proposed tracker (LP: #2101706)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: arm64: dts: disable iris_vpu on RB8 board for now
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Sun, 09 Mar 2025 13:41:59 +0900
+
+linux-qcom (6.8.0-1032.32) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1032.32 -proposed tracker (LP: #2100991)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: build camera drivers for qcm6490/qcs9100 separately
+    - SAUCE: ubuntu/qcom/camera: replace strlcpy() with strscpy() (take 2)
+    - SAUCE: ubuntu/qcom/camera: use sizeof() instead of V4L2_SUBDEV_NAME_SIZE
+      (take 2)
+    - SAUCE: ubuntu/qcom/camera: remove camera_banner
+    - SAUCE: ubuntu/qcom: add missing inclusion
+    - SAUCE: hack modpost to allow multiple exports
+    - SAUCE: fix phy-mode for RB8 board
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 06 Mar 2025 11:34:29 +0900
+
+linux-qcom (6.8.0-1031.31) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1031.31 -proposed tracker (LP: #2099991)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: add qcs9075-addons-rb8-ovl.dtb
+
+  * Miscellaneous upstream changes
+    - PENDING: arm64: dts: qcom: qcs9075: Enable ethernet on QCS9075 RB8
+    - video: driver: fix life cycle of a buffer shared across multiple clients
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Tue, 25 Feb 2025 23:33:35 +0900
+
+linux-qcom (6.8.0-1030.30) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1030.30 -proposed tracker (LP: #2098733)
+
+  * "[RB3] tc956x_pci-eth errors found in dmesg"
+    - SAUCE: ubuntu/qcom/qps615: suppress false alerts
+    - SAUCE: ubuntu/qcom/qps615: use INFO level for logging
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: import external DT from GA 1.3.1
+    - SAUCE: Add Makefile code to apply overlays for GA1.2
+    - SAUCE: ubuntu/qcom/graphics: import qcm6490 graphics driver code from
+      GA1.3.1
+    - SAUCE: ubuntu/qcom/camera: import qcm6490 camera driver code from GA1.3.1
+    - SAUCE: ubuntu/qcom/qps615: import ethernet driver from GA1.3.1
+    - SAUCE: ubuntu/qcom/video: import video driver from GA 1.3.1
+    - SAUCE: ubuntu/qcom: build external drivers
+    - SAUCE: ubuntu/qcom/camera: fix build warnings and errors
+    - SAUCE: rename qcom,phy-rst-gpio to qcom,phy-rst-gpio-id
+    - SAUCE: suppress unneeded build logs
+    - SAUCE: ubuntu/qcom: suppress Wno-enum-int-mismatch warning
+    - SAUCE: ubuntu/qcom/graphics: change strtobool() to kstrtobool()
+    - SAUCE: ubuntu/qcom/graphics: dynamically allocate the kgsl-pool shrinker for
+      kernel>=6.7
+    - SAUCE: ubuntu/qcom/camera: remove unused camera_banner
+    - SAUCE: ubuntu/qcom/camera: use sizeof() instead of V4L2_SUBDEV_NAME_SIZE
+    - SAUCE: ubuntu/qcom/camera: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/video: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: auto-load module
+    - SAUCE: ubuntu/qcom: add missing inclusion
+    - SAUCE: disable downstream display driver
+    - [Config] update config options for GA 1.3.2
+    - SAUCE: import external DT from GA 1.3.2
+    - SAUCE: merge two msm-camera.h
+    - [Packaging] update contents of linux-libc-dev-qcom package
+
+  * Miscellaneous upstream changes
+    - PENDING: arm64: dts: qcom: sa8255p-ride: Disable aoss_qmp
+    - FROMLIST: clk: qcom: Update the support for alpha mode configuration
+    - FROMLIST: clk: qcom: clk-alpha-pll: Add support for dynamic update for
+      slewing PLLs
+    - FROMLIST: phy: qcom: qmp-usbc: Add qmp configuration for QCS615
+    - FROMLIST: mmc: sdhci-msm: Enable MMC_CAP_AGGRESSIVE_PM for qualcomm
+      controllers
+    - QCLINUX: arm64: defconfig: Enable Ftrace for Gen5 Auto targets
+    - FROMLIST: net: stmmac: dwmac-qcom-ethqos: add support for EMAC on qcs615
+      platforms
+    - FROMLIST: arm64: dts: qcom: qcs615: add ethernet node
+    - FROMLIST: arm64: dts: qcom: qcs615-ride: Enable ethernet node
+    - FROMLIST: net: stmmac: qcom-ethqos: Enable RX programmable swap on qcs615
+    - FROMLIST: arm64: dts: qcom: qcs615-ride: Enable RX programmable swap on
+      qcs615-ride
+    - PENDING: net: stmmac: Create new mdio for every emac instance
+    - PENDING: arm64: dts: qcom: Add coresight nodes for QCS615
+    - PENDING: media: qcom: camss: Add support for camss driver on sa8775p
+    - PENDING: arm64: dts: qcom: sa8775p: Add support for camss
+    - PENDING: add TPG driver on camss for sa8775p
+    - QCLINUX: arm64: defconfig: Enable GS_USB
+    - QCLINUX: firmware: qcom_scm: Set SHE scm to atomic
+    - PENDING: ptp: qcom: Add support for Time Stamp Counter(TSC) driver
+    - PENDING: ptp: ptp_qcom_tsc: Add nsecs support for adjtime
+    - QCLINUX: arm64: dts: qcom: add lpi-quad mi2s/tdm dai for qcs9075-rb8
+    - PENDING: clk: qcom: videocc-sa8775p: Add HW_CTRL for video_cc_mvs0_gdsc
+    - QCLINUX: arm64: qcs9075-rb8: disable uart bt en pin in DTS
+    - FROMGIT: arm64: dts: qcom: sa8775p: Disable USB U1/U2 entry
+    - QCLINUX: arm64: defconfig: Enable MHI driver for Gen5auto targets
+    - QCLINUX: arm64: dts: qcom: add support for GPIO expander on rb8 board
+    - PENDING: net: PCS: Fix USXGMII reset sequence to poll for proper bit
+    - PENDING: drm/msm/dpu: remove duplicate formats from wb_formats list
+    - BACKPORT: UPSTREAM: phy: add NXP PTN3222 eUSB2 to USB2 redriver
+    - QCLINUX: ASoC: qcom: qdsp6: Increase the timeout to 20 secs
+    - Revert "PENDING: arm64: dts: qcom: qcs9075: Update memory map for qcs9075"
+    - PENDING: arm64: dts: qcom: qcs9xxx: Update memory map for qcs9xxx boards
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Tue, 18 Feb 2025 17:04:47 +0900
+
+linux-qcom (6.8.0-1029.29) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1028.28 -proposed tracker (LP: #2098058)
+
+  * Add list of source files to linux-buildinfo (LP: #2086606)
+    - [Packaging] Add list of used source files to buildinfo package
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: disable downstream display driver
+
+  * Miscellaneous upstream changes
+    - kernel: Enable upstream display on qcm6490 rgb3gen2
+
+  [ Ubuntu: 6.8.0-54.56 ]
+
+  * CVE-2025-0927
+    - SAUCE: fs: hfs/hfsplus: add key_len boundary check to hfs_bnode_read_key
+
+  [ Ubuntu: 6.8.0-53.55 ]
+
+  * noble/linux: 6.8.0-53.55 -proposed tracker (LP: #2093677)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2025.01.13)
+  * generate and ship vmlinux.h to allow packages to build BPF CO-RE
+    (LP: #2050083)
+    - [Packaging] add linux-bpf-dev package
+    - [Packaging] do not attempt to generate BTF header on armhf
+  * Unable to boot as a guest on VMware ESX (LP: #2091941)
+    - ptp/vmware: Use VMware hypercall API
+    - input/vmmouse: Use VMware hypercall API
+    - drm/vmwgfx: Use VMware hypercall API
+    - x86/vmware: Use VMware hypercall API
+    - x86/vmware: Correct macro names
+    - x86/vmware: Remove legacy VMWARE_HYPERCALL* macros
+  * When /dev/vmbus/hv_kvp is not present, disable hv-kvp-daemon (LP: #2091744)
+    - [Packaging] disable hv-kvp-daemon if needed
+  * Backport "netkit: Add option for scrubbing skb meta data" to 6.8
+    (LP: #2091184)
+    - netkit: Add option for scrubbing skb meta data
+  * KVM: Cache CPUID at KVM.ko module init to reduce latency of VM-Enter and VM-
+    Exit (LP: #2093146)
+    - KVM: x86: Cache CPUID.0xD XSTATE offsets+sizes during module init
+  * [SRU] add support of QCA BT 0489:e0fc (LP: #2085406)
+    - Bluetooth: btusb: add Foxconn 0xe0fc for Qualcomm WCN785x
+  * ice driver RTNL assertion failed warning on shutdown/reboot (LP: #2091107)
+    - ice: Remove and readd netdev during devlink reload
+  * vfio_pci soft lockup on VM start while using PCIe passthrough (LP: #2089306)
+    - SAUCE: Revert "vfio/pci: Insert full vma on mmap'd MMIO fault"
+    - SAUCE: Revert "vfio/pci: Use unmap_mapping_range()"
+  * [SRU] Fix error of resume on rtl8168fp (LP: #2087507)
+    - r8169: avoid unsolicited interrupts
+  * [SRU] power: intel_pstate: HWP interrupt support for maximum ratio changed
+    (LP: #2090852)
+    - x86/cpufeatures: Add HWP highest perf change feature flag
+    - cpufreq: intel_pstate: Support highest performance change interrupt
+  * Noble update: upstream stable patchset 2024-11-29 (LP: #2089884)
+    - static_call: Handle module init failure correctly in
+      static_call_del_module()
+    - static_call: Replace pointless WARN_ON() in static_call_module_notify()
+    - jump_label: Simplify and clarify static_key_fast_inc_cpus_locked()
+    - jump_label: Fix static_key_slow_dec() yet again
+    - scsi: st: Fix input/output error on empty drive reset
+    - scsi: pm8001: Do not overwrite PCI queue mapping
+    - drm/amdgpu: Fix get each xcp macro
+    - mailbox: rockchip: fix a typo in module autoloading
+    - mailbox: bcm2835: Fix timeout during suspend mode
+    - ceph: remove the incorrect Fw reference check when dirtying pages
+    - ieee802154: Fix build error
+    - net: sparx5: Fix invalid timestamps
+    - net/mlx5: Fix error path in multi-packet WQE transmit
+    - net/mlx5: Added cond_resched() to crdump collection
+    - net/mlx5e: Fix NULL deref in mlx5e_tir_builder_alloc()
+    - net/mlx5e: Fix crash caused by calling __xfrm_state_delete() twice
+    - netfilter: uapi: NFTA_FLOWTABLE_HOOK is NLA_NESTED
+    - net: ieee802154: mcr20a: Use IRQF_NO_AUTOEN flag in request_irq()
+    - net: wwan: qcom_bam_dmux: Fix missing pm_runtime_disable()
+    - selftests: netfilter: Fix nft_audit.sh for newer nft binaries
+    - netfilter: nf_tables: prevent nf_skb_duplicated corruption
+    - Bluetooth: MGMT: Fix possible crash on mgmt_index_removed
+    - Bluetooth: MGMT: Fix possible deadlocks
+    - Bluetooth: L2CAP: Fix uaf in l2cap_connect
+    - Bluetooth: hci_core: Fix calling mgmt_device_connected
+    - Bluetooth: btmrvl: Use IRQF_NO_AUTOEN flag in request_irq()
+    - net: Add netif_get_gro_max_size helper for GRO
+    - net: Fix gso_features_check to check for both dev->gso_{ipv4_,}max_size
+    - net: ethernet: lantiq_etop: fix memory disclosure
+    - net: fec: Restart PPS after link state change
+    - net: fec: Reload PTP registers after link-state change
+    - net: avoid potential underflow in qdisc_pkt_len_init() with UFO
+    - net: add more sanity checks to qdisc_pkt_len_init()
+    - net: stmmac: dwmac4: extend timeout for VLAN Tag register busy bit check
+    - ipv4: ip_gre: Fix drops of small packets in ipgre_xmit
+    - net: test for not too small csum_start in virtio_net_hdr_to_skb()
+    - ppp: do not assume bh is held in ppp_channel_bridge_input()
+    - iomap: constrain the file range passed to iomap_file_unshare
+    - dt-bindings: net: xlnx,axi-ethernet: Add missing reg minItems
+    - sctp: set sk_state back to CLOSED if autobind fails in sctp_listen_start
+    - i2c: xiic: improve error message when transfer fails to start
+    - i2c: xiic: Try re-initialization on bus busy timeout
+    - loop: don't set QUEUE_FLAG_NOMERGES
+    - ASoC: atmel: mchp-pdmc: Skip ALSA restoration if substream runtime is
+      uninitialized
+    - ALSA: mixer_oss: Remove some incorrect kfree_const() usages
+    - ALSA: hda/realtek: Fix the push button function for the ALC257
+    - ALSA: hda/generic: Unconditionally prefer preferred_dacs pairs
+    - ASoC: imx-card: Set card.owner to avoid a warning calltrace if SND=m
+    - cifs: Fix buffer overflow when parsing NFS reparse points
+    - cifs: Do not convert delimiter when parsing NFS-style symlinks
+    - ALSA: gus: Fix some error handling paths related to get_bpos() usage
+    - ALSA: hda/conexant: Fix conflicting quirk for System76 Pangolin
+    - wifi: ath9k: fix possible integer overflow in ath9k_get_et_stats()
+    - wifi: rtw89: avoid to add interface to list twice when SER
+    - wifi: ath9k_htc: Use __skb_set_length() for resetting urb before resubmit
+    - crypto: x86/sha256 - Add parentheses around macros' single arguments
+    - crypto: octeontx - Fix authenc setkey
+    - crypto: octeontx2 - Fix authenc setkey
+    - ice: Adjust over allocation of memory in ice_sched_add_root_node() and
+      ice_sched_add_node()
+    - wifi: iwlwifi: mvm: Fix a race in scan abort flow
+    - wifi: iwlwifi: mvm: drop wrong STA selection in TX
+    - wifi: cfg80211: Set correct chandef when starting CAC
+    - net/xen-netback: prevent UAF in xenvif_flush_hash()
+    - net: hisilicon: hip04: fix OF node leak in probe()
+    - net: hisilicon: hns_dsaf_mac: fix OF node leak in hns_mac_get_info()
+    - net: hisilicon: hns_mdio: fix OF node leak in probe()
+    - ACPI: PAD: fix crash in exit_round_robin()
+    - ACPICA: Fix memory leak if acpi_ps_get_next_namepath() fails
+    - ACPICA: Fix memory leak if acpi_ps_get_next_field() fails
+    - e1000e: avoid failing the system during pm_suspend
+    - wifi: mt76: mt7915: disable tx worker during tx BA session enable/disable
+    - net: sched: consistently use rcu_replace_pointer() in taprio_change()
+    - Bluetooth: btusb: Add Realtek RTL8852C support ID 0x0489:0xe122
+    - Bluetooth: btrtl: Set msft ext address filter quirk for RTL8852B
+    - ACPI: video: Add force_vendor quirk for Panasonic Toughbook CF-18
+    - ACPI: CPPC: Add support for setting EPP register in FFH
+    - blk_iocost: fix more out of bound shifts
+    - wifi: ath12k: fix array out-of-bound access in SoC stats
+    - wifi: ath11k: fix array out-of-bound access in SoC stats
+    - wifi: rtw88: select WANT_DEV_COREDUMP
+    - ACPI: EC: Do not release locks during operation region accesses
+    - ACPICA: check null return of ACPI_ALLOCATE_ZEROED() in
+      acpi_db_convert_to_package()
+    - tipc: guard against string buffer overrun
+    - net: mvpp2: Increase size of queue_name buffer
+    - bnxt_en: Extend maximum length of version string by 1 byte
+    - ipv4: Check !in_dev earlier for ioctl(SIOCSIFADDR).
+    - wifi: rtw89: correct base HT rate mask for firmware
+    - ipv4: Mask upper DSCP bits and ECN bits in NETLINK_FIB_LOOKUP family
+    - net: atlantic: Avoid warning about potential string truncation
+    - crypto: simd - Do not call crypto_alloc_tfm during registration
+    - netpoll: Ensure clean state on setup failures
+    - tcp: avoid reusing FIN_WAIT2 when trying to find port in connect() process
+    - wifi: iwlwifi: mvm: use correct key iteration
+    - wifi: iwlwifi: mvm: avoid NULL pointer dereference
+    - ACPICA: iasl: handle empty connection_node
+    - proc: add config & param to block forcing mem writes
+    - [Config] updateconfigs to select PROC_MEM_ALWAYS_FORCE
+    - drivers/perf: arm_spe: Use perf_allow_kernel() for permissions
+    - can: netlink: avoid call to do_set_data_bittiming callback with stale
+      can_priv::ctrlmode
+    - wifi: mt76: mt7915: add dummy HW offload of IEEE 802.11 fragmentation
+    - wifi: mt76: mt7915: hold dev->mt76.mutex while disabling tx worker
+    - wifi: mwifiex: Fix memcpy() field-spanning write warning in
+      mwifiex_cmd_802_11_scan_ext()
+    - nfp: Use IRQF_NO_AUTOEN flag in request_irq()
+    - ALSA: usb-audio: Add input value sanity checks for standard types
+    - x86/ioapic: Handle allocation failures gracefully
+    - ALSA: usb-audio: Define macros for quirk table entries
+    - ALSA: usb-audio: Replace complex quirk lines with macros
+    - ALSA: usb-audio: Add logitech Audio profile quirk
+    - ASoC: codecs: wsa883x: Handle reading version failure
+    - tools/x86/kcpuid: Protect against faulty "max subleaf" values
+    - x86/pkeys: Add PKRU as a parameter in signal handling functions
+    - x86/pkeys: Restore altstack access in sigreturn()
+    - x86/kexec: Add EFI config table identity mapping for kexec kernel
+    - ALSA: asihpi: Fix potential OOB array access
+    - ALSA: hdsp: Break infinite MIDI input flush loop
+    - tools/nolibc: powerpc: limit stack-protector workaround to GCC
+    - selftests/nolibc: avoid passing NULL to printf("%s")
+    - x86/syscall: Avoid memcpy() for ia32 syscall_get_arguments()
+    - hwmon: (nct6775) add G15CF to ASUS WMI monitoring list
+    - fbdev: efifb: Register sysfs groups through driver core
+    - fbdev: pxafb: Fix possible use after free in pxafb_task()
+    - rcuscale: Provide clear error when async specified without primitives
+    - power: reset: brcmstb: Do not go into infinite loop if reset fails
+    - iommu/vt-d: Always reserve a domain ID for identity setup
+    - iommu/vt-d: Fix potential lockup if qi_submit_sync called with 0 count
+    - drm/stm: Avoid use-after-free issues with crtc and plane
+    - drm/amdgpu: disallow multiple BO_HANDLES chunks in one submit
+    - drm/amdgpu: prevent BO_HANDLES error from being overwritten
+    - drm/amdkfd: amdkfd_free_gtt_mem clear the correct pointer
+    - drm/amd/display: Add null check for top_pipe_to_program in
+      commit_planes_for_stream
+    - ata: pata_serverworks: Do not use the term blacklist
+    - ata: sata_sil: Rename sil_blacklist to sil_quirks
+    - HID: Ignore battery for all ELAN I2C-HID devices
+    - drm/amd/display: Handle null 'stream_status' in
+      'planes_changed_for_existing_stream'
+    - drm/amd/display: Check null pointers before using dc->clk_mgr
+    - drm/amd/display: Add null check for 'afb' in
+      amdgpu_dm_plane_handle_cursor_update (v2)
+    - drm/amd/display: fix double free issue during amdgpu module unload
+    - jfs: UBSAN: shift-out-of-bounds in dbFindBits
+    - jfs: Fix uaf in dbFreeBits
+    - jfs: check if leafidx greater than num leaves per dmap tree
+    - scsi: smartpqi: correct stream detection
+    - drm/msm/adreno: Assign msm_gpu->pdev earlier to avoid nullptrs
+    - jfs: Fix uninit-value access of new_ea in ea_buffer
+    - drm/amdgpu: add raven1 gfxoff quirk
+    - drm/amdgpu: enable gfxoff quirk on HP 705G4
+    - drm/amdkfd: Fix resource leak in criu restore queue
+    - HID: multitouch: Add support for Thinkpad X12 Gen 2 Kbd Portfolio
+    - platform/x86: touchscreen_dmi: add nanote-next quirk
+    - drm/stm: ltdc: reset plane transparency after plane disable
+    - drm/amd/display: Check stream before comparing them
+    - drm/amd/display: Check link_res->hpo_dp_link_enc before using it
+    - drm/amd/display: Fix index out of bounds in DCN30 degamma hardware format
+      translation
+    - drm/amd/display: Fix index out of bounds in degamma hardware format
+      translation
+    - drm/amd/display: Fix index out of bounds in DCN30 color transformation
+    - drm/amd/display: Avoid overflow assignment in link_dp_cts
+    - drm/amd/display: Initialize get_bytes_per_element's default to 1
+    - drm/printer: Allow NULL data in devcoredump printer
+    - perf,x86: avoid missing caller address in stack traces captured in uprobe
+    - scsi: lpfc: Update PRLO handling in direct attached topology
+    - drm/amdgpu: fix unchecked return value warning for amdgpu_gfx
+    - perf: Fix event_function_call() locking
+    - scsi: NCR5380: Initialize buffer for MSG IN and STATUS transfers
+    - drm/radeon/r100: Handle unknown family in r100_cp_init_microcode()
+    - drm/amdgpu: Block MMR_READ IOCTL in reset
+    - drm/amdgpu/gfx9: use rlc safe mode for soft recovery
+    - drm/amd/pm: ensure the fw_info is not null before using it
+    - of/irq: Refer to actual buffer size in of_irq_parse_one()
+    - powerpc/pseries: Use correct data types from pseries_hp_errorlog struct
+    - drm/amdgpu/gfx11: use rlc safe mode for soft recovery
+    - drm/amdgpu/gfx10: use rlc safe mode for soft recovery
+    - platform/x86: lenovo-ymc: Ignore the 0x0 state
+    - ksmbd: add refcnt to ksmbd_conn struct
+    - ksmbd: fix use-after-free in SMB request handling
+    - bpf: Make the pointer returned by iter next method valid
+    - ext4: ext4_search_dir should return a proper error
+    - ext4: avoid use-after-free in ext4_ext_show_leaf()
+    - ext4: fix i_data_sem unlock order in ext4_ind_migrate()
+    - bpftool: Fix undefined behavior caused by shifting into the sign bit
+    - iomap: handle a post-direct I/O invalidate race in
+      iomap_write_delalloc_release
+    - bpftool: Fix undefined behavior in qsort(NULL, 0, ...)
+    - spi: spi-imx: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - spi: spi-cadence: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - spi: spi-cadence: Fix missing spi_controller_is_target() check
+    - selftest: hid: add missing run-hid-tools-tests.sh
+    - spi: s3c64xx: fix timeout counters in flush_fifo
+    - selftests: breakpoints: use remaining time to check if suspend succeed
+    - accel/ivpu: Add missing MODULE_FIRMWARE metadata
+    - spi: rpc-if: Add missing MODULE_DEVICE_TABLE
+    - perf: Really fix event_function_call() locking
+    - selftests: vDSO: fix vDSO name for powerpc
+    - selftests: vDSO: fix vdso_config for powerpc
+    - selftests: vDSO: fix vDSO symbols lookup for powerpc64
+    - powerpc/vdso: Flag VDSO64 entry points as functions
+    - selftests/mm: fix charge_reserved_hugetlb.sh test
+    - powerpc/vdso: Fix VDSO data access when running in a non-root time namespace
+    - selftests: vDSO: fix ELF hash table entry size for s390x
+    - selftests: vDSO: fix vdso_config for s390
+    - Revert "ALSA: hda: Conditionally use snooping for AMD HDMI"
+    - platform/x86: ISST: Fix the KASAN report slab-out-of-bounds bug
+    - i2c: stm32f7: Do not prepare/unprepare clock during runtime suspend/resume
+    - i2c: qcom-geni: Use IRQF_NO_AUTOEN flag in request_irq()
+    - i2c: xiic: Wait for TX empty to avoid missed TX NAKs
+    - media: i2c: ar0521: Use cansleep version of gpiod_set_value()
+    - i2c: xiic: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - i2c: designware: fix controller is holding SCL low while ENABLE bit is
+      disabled
+    - rust: sync: require `T: Sync` for `LockedBy::access`
+    - ovl: fail if trusted xattrs are needed but caller lacks permission
+    - firmware: tegra: bpmp: Drop unused mbox_client_to_bpmp()
+    - memory: tegra186-emc: drop unused to_tegra186_emc()
+    - dt-bindings: clock: exynos7885: Fix duplicated binding
+    - spi: bcm63xx: Fix module autoloading
+    - spi: bcm63xx: Fix missing pm_runtime_disable()
+    - power: supply: hwmon: Fix missing temp1_max_alarm attribute
+    - perf/core: Fix small negative period being ignored
+    - parisc: Fix itlb miss handler for 64-bit programs
+    - drm/mediatek: ovl_adaptor: Add missing of_node_put()
+    - drm: Consistently use struct drm_mode_rect for FB_DAMAGE_CLIPS
+    - ALSA: hda/tas2781: Add new quirk for Lenovo Y990 Laptop
+    - ALSA: core: add isascii() check to card ID generator
+    - ALSA: usb-audio: Add delay quirk for VIVO USB-C HEADSET
+    - ALSA: usb-audio: Add native DSD support for Luxman D-08u
+    - ALSA: line6: add hw monitor volume control to POD HD500X
+    - ALSA: hda/realtek: Add quirk for Huawei MateBook 13 KLV-WX9
+    - ALSA: hda/realtek: Add a quirk for HP Pavilion 15z-ec200
+    - ext4: correct encrypted dentry name hash when not casefolded
+    - ext4: fix slab-use-after-free in ext4_split_extent_at()
+    - ext4: propagate errors from ext4_find_extent() in ext4_insert_range()
+    - ext4: fix incorrect tid assumption in ext4_fc_mark_ineligible()
+    - ext4: dax: fix overflowing extents beyond inode size when partially writing
+    - ext4: fix incorrect tid assumption in __jbd2_log_wait_for_space()
+    - ext4: drop ppath from ext4_ext_replay_update_ex() to avoid double-free
+    - ext4: aovid use-after-free in ext4_ext_insert_extent()
+    - ext4: fix double brelse() the buffer of the extents path
+    - ext4: fix timer use-after-free on failed mount
+    - ext4: update orig_path in ext4_find_extent()
+    - ext4: fix incorrect tid assumption in ext4_wait_for_tail_page_commit()
+    - ext4: fix incorrect tid assumption in jbd2_journal_shrink_checkpoint_list()
+    - ext4: fix fast commit inode enqueueing during a full journal commit
+    - ext4: use handle to mark fc as ineligible in __track_dentry_update()
+    - ext4: mark fc as ineligible using an handle in ext4_xattr_set()
+    - parisc: Fix 64-bit userspace syscall path
+    - parisc: Allow mmap(MAP_STACK) memory to automatically expand upwards
+    - parisc: Fix stack start for ADDR_NO_RANDOMIZE personality
+    - drm/rockchip: vop: clear DMA stop bit on RK3066
+    - of: address: Report error on resource bounds overflow
+    - of/irq: Support #msi-cells=<0> in of_msi_get_domain
+    - drm: omapdrm: Add missing check for alloc_ordered_workqueue
+    - resource: fix region_intersects() vs add_memory_driver_managed()
+    - jbd2: stop waiting for space when jbd2_cleanup_journal_tail() returns error
+    - jbd2: correctly compare tids with tid_geq function in jbd2_fc_begin_commit
+    - mm: krealloc: consider spare memory for __GFP_ZERO
+    - mm: krealloc: Fix MTE false alarm in __do_krealloc
+    - ocfs2: fix the la space leak when unmounting an ocfs2 volume
+    - ocfs2: fix uninit-value in ocfs2_get_block()
+    - ocfs2: reserve space for inline xattr before attaching reflink tree
+    - ocfs2: cancel dqi_sync_work before freeing oinfo
+    - ocfs2: remove unreasonable unlock in ocfs2_read_blocks
+    - ocfs2: fix null-ptr-deref when journal load failed.
+    - ocfs2: fix possible null-ptr-deref in ocfs2_set_buffer_uptodate
+    - arm64: fix selection of HAVE_DYNAMIC_FTRACE_WITH_ARGS
+    - arm64: Subscribe Microsoft Azure Cobalt 100 to erratum 3194386
+    - riscv: define ILLEGAL_POINTER_VALUE for 64bit
+    - [Config] updateconfigs to set ILLEGAL_POINTER_VALUE for riscv64
+    - exfat: fix memory leak in exfat_load_bitmap()
+    - perf python: Disable -Wno-cast-function-type-mismatch if present on clang
+    - perf hist: Update hist symbol when updating maps
+    - nfsd: fix delegation_blocked() to block correctly for at least 30 seconds
+    - nfsd: map the EBADMSG to nfserr_io to avoid warning
+    - NFSD: Fix NFSv4's PUTPUBFH operation
+    - i3c: master: svc: Fix use after free vulnerability in svc_i3c_master Driver
+      Due to Race Condition
+    - RDMA/mana_ib: use the correct page size for mapping user-mode doorbell page
+    - riscv: Fix kernel stack size when KASAN is enabled
+    - aoe: fix the potential use-after-free problem in more places
+    - media: ov5675: Fix power on/off delay timings
+    - clk: rockchip: fix error for unknown clocks
+    - remoteproc: k3-r5: Fix error handling when power-up failed
+    - clk: qcom: dispcc-sm8250: use CLK_SET_RATE_PARENT for branch clocks
+    - media: sun4i_csi: Implement link validate for sun4i_csi subdev
+    - clk: qcom: gcc-sm8450: Do not turn off PCIe GDSCs during gdsc_disable()
+    - media: uapi/linux/cec.h: cec_msg_set_reply_to: zero flags
+    - clk: qcom: clk-rpmh: Fix overflow in BCM vote
+    - clk: samsung: exynos7885: Update CLKS_NR_FSYS after bindings fix
+    - clk: qcom: gcc-sm8150: De-register gcc_cpuss_ahb_clk_src
+    - media: venus: fix use after free bug in venus_remove due to race condition
+    - clk: qcom: gcc-sm8250: Do not turn off PCIe GDSCs during gdsc_disable()
+    - media: qcom: camss: Remove use_count guard in stop_streaming
+    - media: qcom: camss: Fix ordering of pm_runtime_enable
+    - clk: qcom: gcc-sc8180x: Fix the sdcc2 and sdcc4 clocks freq table
+    - clk: qcom: clk-alpha-pll: Fix CAL_L_VAL override for LUCID EVO PLL
+    - smb: client: use actual path when queryfs
+    - smb3: fix incorrect mode displayed for read-only files
+    - iio: magnetometer: ak8975: Fix reading for ak099xx sensors
+    - vrf: revert "vrf: Remove unnecessary RCU-bh critical section"
+    - gso: fix udp gso fraglist segmentation after pull from frag_list
+    - tomoyo: fallback to realpath if symlink's pathname does not exist
+    - net: stmmac: Fix zero-division error when disabling tc cbs
+    - rtc: at91sam9: fix OF node leak in probe() error path
+    - Input: adp5589-keys - fix NULL pointer dereference
+    - Input: adp5589-keys - fix adp5589_gpio_get_value()
+    - cachefiles: fix dentry leak in cachefiles_open_file()
+    - btrfs: fix a NULL pointer dereference when failed to start a new trasacntion
+    - btrfs: send: fix invalid clone operation for file that got its size
+      decreased
+    - btrfs: wait for fixup workers before stopping cleaner kthread during umount
+    - cpufreq: Avoid a bad reference count on CPU node
+    - gpio: davinci: fix lazy disable
+    - net: pcs: xpcs: fix the wrong register that was written back
+    - Bluetooth: hci_event: Align BR/EDR JUST_WORKS paring with LE
+    - mac802154: Fix potential RCU dereference issue in mac802154_scan_worker
+    - ceph: fix cap ref leak via netfs init_request
+    - tracing/hwlat: Fix a race during cpuhp processing
+    - tracing/timerlat: Drop interface_lock in stop_kthread()
+    - tracing/timerlat: Fix a race during cpuhp processing
+    - tracing/timerlat: Fix duplicated kthread creation due to CPU online/offline
+    - rtla: Fix the help text in osnoise and timerlat top tools
+    - drm/i915/gem: fix bitwise and logical AND mixup
+    - drm/sched: Add locking to drm_sched_entity_modify_sched
+    - drm/amd/display: Add HDR workaround for specific eDP
+    - cpufreq: intel_pstate: Make hwp_notify_lock a raw spinlock
+    - kconfig: qconf: fix buffer overflow in debug links
+    - platform/x86: x86-android-tablets: Fix use after free on
+      platform_device_register() errors
+    - i2c: core: Lock address during client device instantiation
+    - i2c: synquacer: Remove a clk reference from struct synquacer_i2c
+    - i2c: synquacer: Deal with optional PCLK correctly
+    - arm64: cputype: Add Neoverse-N3 definitions
+    - arm64: errata: Expand speculative SSBS workaround once more
+    - io_uring/net: harden multishot termination case for recv
+    - uprobes: fix kernel info leak via "[uprobes]" vma
+    - mm: z3fold: deprecate CONFIG_Z3FOLD
+    - [Config] updateconfigs for deprecated CONFIG_Z3FOLD
+    - drm/amd/display: Allow backlight to go below
+      `AMDGPU_DM_DEFAULT_MIN_BACKLIGHT`
+    - build-id: require program headers to be right after ELF header
+    - lib/buildid: harden build ID parsing logic
+    - sched: psi: fix bogus pressure spikes from aggregation race
+    - net: mana: Enable MANA driver on ARM64 with 4K page size
+    - net: mana: Add support for page sizes other than 4KB on ARM64
+    - [Config] updateconfigs for MICROSOFT_MANA
+    - RDMA/mana_ib: use the correct page table index based on hardware page size
+    - media: imx335: Fix reset-gpio handling
+    - remoteproc: k3-r5: Acquire mailbox handle during probe routine
+    - remoteproc: k3-r5: Delay notification of wakeup event
+    - dt-bindings: clock: qcom: Add missing UFS QREF clocks
+    - dt-bindings: clock: qcom: Add GPLL9 support on gcc-sc8180x
+    - iio: pressure: bmp280: Improve indentation and line wrapping
+    - iio: pressure: bmp280: Use BME prefix for BME280 specifics
+    - iio: pressure: bmp280: Fix regmap for BMP280 device
+    - iio: pressure: bmp280: Fix waiting time for BMP3xx configuration
+    - r8169: Fix spelling mistake: "tx_underun" -> "tx_underrun"
+    - r8169: add tally counter fields added with RTL8125
+    - clk: qcom: gcc-sc8180x: Add GPLL9 support
+    - ACPI: battery: Simplify battery hook locking
+    - ACPI: battery: Fix possible crash when unregistering a battery hook
+    - btrfs: drop the backref cache during relocation if we commit
+    - drm/rockchip: vop: enable VOP_FEATURE_INTERNAL_RGB on RK3066
+    - rxrpc: Fix a race between socket set up and I/O thread creation
+    - vhost/scsi: null-ptr-dereference in vhost_scsi_get_req()
+    - crypto: octeontx* - Select CRYPTO_AUTHENC
+    - drm/amd/display: Revert Avoid overflow assignment
+    - perf report: Fix segfault when 'sym' sort key is not used
+    - drm/amd/display: enable_hpo_dp_link_output: Check link_res->hpo_dp_link_enc
+      before using it
+    - Revert "ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path"
+    - perf python: Allow checking for the existence of warning options in clang
+    - drm/i915/dp: Fix AUX IO power enabling for eDP PSR
+    - drm/amd/display: handle nulled pipe context in DCE110's set_drr()
+    - selftests: netfilter: Add missing return value
+    - afs: Fix the setting of the server responding flag
+    - net: dsa: improve shutdown sequence
+    - bridge: mcast: Fail MDB get request on empty entry
+    - net/ncsi: Disable the ncsi work before freeing the associated structure
+    - drm/xe: Restore pci state upon resume
+    - drm/xe: Resume TDR after GT reset
+    - drm/xe: Prevent null pointer access in xe_migrate_copy
+    - fs/inode: Prevent dump_mapping() accessing invalid dentry.d_name.name
+    - ACPI: resource: Skip IRQ override on Asus Vivobook Go E1404GAB
+    - nvme-keyring: restrict match length for version '1' identifiers
+    - nvme-tcp: sanitize TLS key handling
+    - nvme-fabrics: typo in nvmf_parse_key()
+    - nvme-tcp: check for invalidated or revoked key
+    - net: fec: don't save PTP state if PTP is unsupported
+    - wifi: mac80211: fix RCU list iterations
+    - netdev-genl: Set extack and fix error on napi-get
+    - block: fix integer overflow in BLKSECDISCARD
+    - arm64: trans_pgd: mark PTEs entries as valid to avoid dead kexec()
+    - net: phy: Check for read errors in SIOCGMIIREG
+    - wifi: rtw89: avoid reading out of bounds when loading TX power FW elements
+    - x86/bugs: Add missing NO_SSB flag
+    - x86/bugs: Fix handling when SRSO mitigation is disabled
+    - net: napi: Prevent overflow of napi_defer_hard_irqs
+    - crypto: hisilicon - fix missed error branch
+    - ALSA: usb-audio: Add quirk for RME Digiface USB
+    - ALSA: usb-audio: Add mixer quirk for RME Digiface USB
+    - ALSA: control: Use automatic cleanup of kfree()
+    - ALSA: control: Fix unannotated kfree() cleanup
+    - ALSA: control: Use guard() for locking
+    - ALSA: control: Take power_ref lock primarily
+    - x86/mm/ident_map: Use gbpages only where full GB page should be mapped.
+    - ASoC: Intel: boards: always check the result of
+      acpi_dev_get_first_match_dev()
+    - rcu-tasks: Add data to eliminate RCU-tasks/do_exit() deadlocks
+    - rcu-tasks: Initialize data to eliminate RCU-tasks/do_exit() deadlocks
+    - rcu-tasks: Fix access non-existent percpu rtpcp variable in
+      rcu_tasks_need_gpcb()
+    - pmdomain: core: Don't hold the genpd-lock when calling dev_pm_domain_set()
+    - iommu/vt-d: Unconditionally flush device TLB for pasid table updates
+    - iommu/arm-smmu-v3: Do not use devm for the cd table allocations
+    - drm/amd/display: Pass non-null to dcn20_validate_apply_pipe_split_flags
+    - drm/amd/display: Check null pointers before using them
+    - drm/amd/display: Add null check for head_pipe in
+      dcn201_acquire_free_pipe_for_layer
+    - drm/amd/display: Add null check for head_pipe in
+      dcn32_acquire_idle_pipe_for_head_pipe_in_layer
+    - drm/amd/display: Add NULL check for clk_mgr and clk_mgr->funcs in
+      dcn30_init_hw
+    - drm/amd/display: Add NULL check for clk_mgr in dcn32_init_hw
+    - drm/amd/display: Use gpuvm_min_page_size_kbytes for DML2 surfaces
+    - scsi: smartpqi: Add new controller PCI IDs
+    - drm/amd/display: Add NULL check for function pointer in
+      dcn20_set_output_transfer_func
+    - drm/amd/display: Add NULL check for function pointer in
+      dcn32_set_output_transfer_func
+    - scsi: smartpqi: add new controller PCI IDs
+    - drm/amd/display: Check null-initialized variables
+    - drm/amd/display: Check phantom_stream before it is used
+    - drm/amdgpu/gfx9: properly handle error ints on all pipes
+    - scsi: lpfc: Validate hdwq pointers before dereferencing in reset/errata
+      paths
+    - scsi: lpfc: Fix unsolicited FLOGI kref imbalance when in direct attached
+      topology
+    - drm/amdgpu: check PS, WS index
+    - drm/amdgpu: fix wrong sizeof argument
+    - drm/amdgpu: fix unchecked return value warning for amdgpu_atombios
+    - drm/amdgpu/gfx11: enter safe mode before touching CP_INT_CNTL
+    - drm/xe: Invert page fault queue head / tail
+    - drm/xe: Add helper macro to loop each DSS
+    - drm/xe: fix multicast support for Xe_LP platforms
+    - drm/xe: Use topology to determine page fault queue size
+    - drm/xe: Drop warn on xe_guc_pc_gucrc_disable in guc pc fini
+    - ovl: fsync after metadata copy-up
+    - HID: i2c-hid: ensure various commands do not interfere with each other
+    - platform/mellanox: mlxbf-pmc: Replace uintN_t with kernel-style types
+    - platform/mellanox: mlxbf-pmc: Cleanup signed/unsigned mix-up
+    - platform/mellanox: mlxbf-pmc: fix signedness bugs
+    - platform/mellanox: mlxbf-pmc: fix lockdep warning
+    - bpf: Fix a sdiv overflow issue
+    - ALSA: control: Fix power_ref lock order for compat code, too
+    - perf callchain: Fix stitch LBR memory leaks
+    - drm/xe: fixup xe_alloc_pf_queue
+    - drm/xe: Fix memory leak on xe_alloc_pf_queue failure
+    - nvme-tcp: fix link failure for TCP auth
+    - f2fs: fix zoned block device information initialization
+    - f2fs: add write priority option based on zone UFS
+    - f2fs: make BG GC more aggressive for zoned devices
+    - f2fs: introduce migration_window_granularity
+    - f2fs: increase BG GC migration window granularity when boosted for zoned
+      devices
+    - f2fs: do FG_GC when GC boosting is required for zoned devices
+    - f2fs: forcibly migrate to secure space for zoned device file pinning
+    - mm, slub: avoid zeroing kmalloc redzone
+    - drm/v3d: Prevent out of bounds access in performance query extensions
+    - ext4: fix access to uninitialised lock in fc replay path
+    - ext4: fix off by one issue in alloc_flex_gd()
+    - scripts/gdb: add iteration function for rbtree
+    - scripts/gdb: fix lx-mounts command error
+    - sched/deadline: Comment sched_dl_entity::dl_server variable
+    - sched/core: Add clearing of ->dl_server in put_prev_task_balance()
+    - sched/core: Clear prev->dl_server in CFS pick fast path
+    - drivers/perf: riscv: Align errno for unsupported perf event
+    - ACPI: resource: Remove duplicate Asus E1504GAB IRQ override
+    - ACPI: resource: Loosen the Asus E1404GAB DMI match to also cover the E1404GA
+    - ACPI: resource: Add Asus Vivobook X1704VAP to irq1_level_low_skip_override[]
+    - ACPI: resource: Add Asus ExpertBook B2502CVA to
+      irq1_level_low_skip_override[]
+    - firmware/sysfb: Disable sysfb for firmware buffers with unknown parent
+    - close_range(): fix the logics in descriptor table trimming
+    - drm/sched: Fix dynamic job-flow control race
+    - drm/sched: Always wake up correct scheduler in drm_sched_entity_push_job
+    - drm/sched: Always increment correct scheduler score
+    - drm/xe: Delete unused GuC submission_state.suspend
+    - drm/xe: Use ordered wq for preempt fence waiting
+    - drm/xe: fix UAF around queue destruction
+    - sunrpc: change sp_nrthreads from atomic_t to unsigned int.
+    - NFSD: Async COPY result needs to return a write verifier
+    - NFSD: Limit the number of concurrent async COPY operations
+    - NFSD: Initialize struct nfsd4_copy earlier
+    - NFSD: Never decrement pending_async_copies on error
+    - drm/sched: revert "Always increment correct scheduler score"
+    - ALSA: control: Fix leftover snd_power_unref()
+    - Upstream stable to v6.6.55, v6.10.14
+  * By always inlining _compound_head(), clone() sees 3%+ performance increase
+    (LP: #2089327)
+    - mm: always inline _compound_head() with
+      CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y
+  * Random flickering with Intel i915 (Comet Lake and Kaby Lake) on Linux 6.8+
+    (LP: #2086587)
+    - SAUCE: iommu/intel: disable DMAR for KBL and CML integrated gfx
+  * Add list of source files to linux-buildinfo (LP: #2086606)
+    - [Packaging] Sort build dependencies alphabetically
+    - [Packaging] Add list of used source files to buildinfo package
+  * UFS: uspi->s_3apb UBSAN: shift-out-of-bounds (LP: #2087853)
+    - ufs: ufs_sb_private_info: remove unused s_{2, 3}apb fields
+  * Mute/mic LEDs don't function on HP EliteBook 645 G10 (LP: #2087983)
+    - ALSA: hda/realtek: fix mute/micmute LEDs for a HP EliteBook 645 G10
+  * Noble update: upstream stable patchset 2024-11-22 (LP: #2089340)
+    - EDAC/synopsys: Fix ECC status and IRQ control race condition
+    - EDAC/synopsys: Fix error injection on Zynq UltraScale+
+    - wifi: rtw88: always wait for both firmware loading attempts
+    - crypto: xor - fix template benchmarking
+    - ACPI: PMIC: Remove unneeded check in tps68470_pmic_opregion_probe()
+    - wifi: brcmfmac: export firmware interface functions
+    - wifi: brcmfmac: introducing fwil query functions
+    - wifi: ath9k: Remove error checks when creating debugfs entries
+    - wifi: ath12k: fix BSS chan info request WMI command
+    - wifi: ath12k: match WMI BSS chan info structure with firmware definition
+    - wifi: ath12k: fix invalid AMPDU factor calculation in
+      ath12k_peer_assoc_h_he()
+    - net: stmmac: dwmac-loongson: Init ref and PTP clocks rate
+    - arm64: signal: Fix some under-bracketed UAPI macros
+    - wifi: rtw88: remove CPT execution branch never used
+    - RISC-V: KVM: Fix sbiret init before forwarding to userspace
+    - RISC-V: KVM: Allow legacy PMU access from guest
+    - RISC-V: KVM: Fix to allow hpmcounter31 from the guest
+    - mount: handle OOM on mnt_warn_timestamp_expiry
+    - ARM: 9410/1: vfp: Use asm volatile in fmrx/fmxr macros
+    - powercap: intel_rapl: Fix off by one in get_rpi()
+    - kselftest/arm64: signal: fix/refactor SVE vector length enumeration
+    - drivers/perf: Fix ali_drw_pmu driver interrupt status clearing
+    - wifi: mac80211: don't use rate mask for offchannel TX either
+    - wifi: iwlwifi: remove AX101, AX201 and AX203 support from LNL
+    - wifi: iwlwifi: config: label 'gl' devices as discrete
+    - wifi: iwlwifi: mvm: increase the time between ranging measurements
+    - padata: Honor the caller's alignment in case of chunk_size 0
+    - drivers/perf: hisi_pcie: Record hardware counts correctly
+    - drivers/perf: hisi_pcie: Fix TLP headers bandwidth counting
+    - kselftest/arm64: Actually test SME vector length changes via sigreturn
+    - can: j1939: use correct function name in comment
+    - ACPI: CPPC: Fix MASK_VAL() usage
+    - netfilter: nf_tables: elements with timeout below CONFIG_HZ never expire
+    - netfilter: nf_tables: reject element expiration with no timeout
+    - netfilter: nf_tables: reject expiration higher than timeout
+    - netfilter: nf_tables: remove annotation to access set timeout while holding
+      lock
+    - perf/arm-cmn: Improve debugfs pretty-printing for large configs
+    - perf/arm-cmn: Refactor node ID handling. Again.
+    - perf/arm-cmn: Fix CCLA register offset
+    - perf/arm-cmn: Ensure dtm_idx is big enough
+    - cpufreq: ti-cpufreq: Introduce quirks to handle syscon fails appropriately
+    - wifi: mt76: mt7915: fix oops on non-dbdc mt7986
+    - wifi: mt76: mt7996: use hweight16 to get correct tx antenna
+    - wifi: mt76: mt7996: fix traffic delay when switching back to working channel
+    - wifi: mt76: mt7996: fix wmm set of station interface to 3
+    - wifi: mt76: mt7996: fix HE and EHT beamforming capabilities
+    - wifi: mt76: mt7996: fix EHT beamforming capability check
+    - x86/sgx: Fix deadlock in SGX NUMA node search
+    - pm:cpupower: Add missing powercap_set_enabled() stub function
+    - crypto: hisilicon/hpre - mask cluster timeout error
+    - crypto: hisilicon/qm - reset device before enabling it
+    - crypto: hisilicon/qm - inject error before stopping queue
+    - wifi: mt76: mt7603: fix mixed declarations and code
+    - wifi: cfg80211: fix UBSAN noise in cfg80211_wext_siwscan()
+    - wifi: mt76: mt7915: fix rx filter setting for bfee functionality
+    - wifi: mt76: mt7996: ensure 4-byte alignment for beacon commands
+    - wifi: mt76: mt7996: fix uninitialized TLV data
+    - wifi: cfg80211: fix two more possible UBSAN-detected off-by-one errors
+    - wifi: mac80211: use two-phase skb reclamation in ieee80211_do_stop()
+    - wifi: wilc1000: fix potential RCU dereference issue in
+      wilc_parse_join_bss_param
+    - Bluetooth: hci_core: Fix sending MGMT_EV_CONNECT_FAILED
+    - Bluetooth: hci_sync: Ignore errors from HCI_OP_REMOTE_NAME_REQ_CANCEL
+    - sock_map: Add a cond_resched() in sock_hash_free()
+    - can: bcm: Clear bo->bcm_proc_read after remove_proc_entry().
+    - can: m_can: enable NAPI before enabling interrupts
+    - can: m_can: m_can_close(): stop clocks after device has been shut down
+    - Bluetooth: btusb: Fix not handling ZPL/short-transfer
+    - bareudp: Pull inner IP header in bareudp_udp_encap_recv().
+    - bareudp: Pull inner IP header on xmit.
+    - net: enetc: Use IRQF_NO_AUTOEN flag in request_irq()
+    - net: ipv6: rpl_iptunnel: Fix memory leak in rpl_input
+    - net: tipc: avoid possible garbage value
+    - ipv6: avoid possible NULL deref in rt6_uncached_list_flush_dev()
+    - ublk: move zone report data out of request pdu
+    - nbd: fix race between timeout and normal completion
+    - block, bfq: fix possible UAF for bfqq->bic with merge chain
+    - block, bfq: choose the last bfqq from merge chain in bfq_setup_cooperator()
+    - block, bfq: don't break merge chain in bfq_split_bfqq()
+    - cachefiles: Fix non-taking of sb_writers around set/removexattr
+    - erofs: fix incorrect symlink detection in fast symlink
+    - block, bfq: fix uaf for accessing waker_bfqq after splitting
+    - block, bfq: fix procress reference leakage for bfqq in merge chain
+    - io_uring/io-wq: do not allow pinning outside of cpuset
+    - io_uring/io-wq: inherit cpuset of cgroup in io worker
+    - block: fix potential invalid pointer dereference in blk_add_partition
+    - spi: ppc4xx: handle irq_of_parse_and_map() errors
+    - arm64: dts: exynos: exynos7885-jackpotlte: Correct RAM amount to 4GB
+    - arm64: dts: mediatek: mt8186: Fix supported-hw mask for GPU OPPs
+    - firmware: arm_scmi: Fix double free in OPTEE transport
+    - spi: ppc4xx: Avoid returning 0 when failed to parse and map IRQ
+    - regulator: Return actual error in of_regulator_bulk_get_all()
+    - arm64: dts: renesas: r9a07g043u: Correct GICD and GICR sizes
+    - arm64: dts: renesas: r9a07g054: Correct GICD and GICR sizes
+    - arm64: dts: renesas: r9a07g044: Correct GICD and GICR sizes
+    - ARM: dts: microchip: sam9x60: Fix rtc/rtt clocks
+    - arm64: dts: rockchip: Correct vendor prefix for Hardkernel ODROID-M1
+    - arm64: dts: ti: k3-j721e-sk: Fix reversed C6x carveout locations
+    - arm64: dts: ti: k3-j721e-beagleboneai64: Fix reversed C6x carveout locations
+    - spi: bcmbca-hsspi: Fix missing pm_runtime_disable()
+    - ARM: dts: microchip: sama7g5: Fix RTT clock
+    - ARM: dts: imx7d-zii-rmu2: fix Ethernet PHY pinctrl property
+    - ARM: versatile: fix OF node leak in CPUs prepare
+    - reset: berlin: fix OF node leak in probe() error path
+    - reset: k210: fix OF node leak in probe() error path
+    - clocksource/drivers/qcom: Add missing iounmap() on errors in
+      msm_dt_timer_init()
+    - arm64: dts: mediatek: mt8195: Correct clock order for dp_intf*
+    - x86/mm: Use IPIs to synchronize LAM enablement
+    - ASoC: rt5682s: Return devm_of_clk_add_hw_provider to transfer the error
+    - ASoC: tas2781: remove unused acpi_subysystem_id
+    - ASoC: tas2781: Use of_property_read_reg()
+    - ASoC: tas2781-i2c: Drop weird GPIO code
+    - ASoC: tas2781-i2c: Get the right GPIO line
+    - selftests/ftrace: Add required dependency for kprobe tests
+    - ALSA: hda: cs35l41: fix module autoloading
+    - m68k: Fix kernel_clone_args.flags in m68k_clone()
+    - ASoC: loongson: fix error release
+    - hwmon: (max16065) Fix overflows seen when writing limits
+    - hwmon: (max16065) Remove use of i2c_match_id()
+    - hwmon: (max16065) Fix alarm attributes
+    - mtd: slram: insert break after errors in parsing the map
+    - hwmon: (ntc_thermistor) fix module autoloading
+    - power: supply: axp20x_battery: Remove design from min and max voltage
+    - power: supply: max17042_battery: Fix SOC threshold calc w/ no current sense
+    - fbdev: hpfb: Fix an error handling path in hpfb_dio_probe()
+    - iommu/amd: Do not set the D bit on AMD v2 table entries
+    - mtd: powernv: Add check devm_kasprintf() returned value
+    - rcu/nocb: Fix RT throttling hrtimer armed from offline CPU
+    - mtd: rawnand: mtk: Use for_each_child_of_node_scoped()
+    - mtd: rawnand: mtk: Factorize out the logic cleaning mtk chips
+    - mtd: rawnand: mtk: Fix init error path
+    - iommu/arm-smmu-qcom: hide last LPASS SMMU context bank from linux
+    - iommu/arm-smmu-qcom: Work around SDM845 Adreno SMMU w/ 16K pages
+    - iommu/arm-smmu-qcom: apply num_context_bank fixes for SDM630 / SDM660
+    - pmdomain: core: Harden inter-column space in debug summary
+    - drm/stm: Fix an error handling path in stm_drm_platform_probe()
+    - drm/stm: ltdc: check memory returned by devm_kzalloc()
+    - drm/amd/display: Add null check for set_output_gamma in
+      dcn30_set_output_transfer_func
+    - drm/amdgpu: properly handle vbios fake edid sizing
+    - drm/radeon: properly handle vbios fake edid sizing
+    - scsi: smartpqi: revert propagate-the-multipath-failure-to-SML-quickly
+    - scsi: NCR5380: Check for phase match during PDMA fixup
+    - drm/amd/amdgpu: Properly tune the size of struct
+    - drm/rockchip: vop: Allow 4096px width scaling
+    - drm/rockchip: dw_hdmi: Fix reading EDID when using a forced mode
+    - drm/radeon/evergreen_cs: fix int overflow errors in cs track offsets
+    - drm/bridge: lontium-lt8912b: Validate mode in drm_bridge_funcs::mode_valid()
+    - drm/vc4: hdmi: Handle error case of pm_runtime_resume_and_get
+    - scsi: elx: libefc: Fix potential use after free in efc_nport_vport_del()
+    - jfs: fix out-of-bounds in dbNextAG() and diAlloc()
+    - drm/mediatek: Fix missing configuration flags in mtk_crtc_ddp_config()
+    - drm/mediatek: Use spin_lock_irqsave() for CRTC event lock
+    - powerpc/8xx: Fix initial memory mapping
+    - powerpc/8xx: Fix kernel vs user address comparison
+    - powerpc/vdso: Inconditionally use CFUNC macro
+    - drm/msm: Fix incorrect file name output in adreno_request_fw()
+    - drm/msm/a5xx: disable preemption in submits by default
+    - drm/msm/a5xx: properly clear preemption records on resume
+    - drm/msm/a5xx: fix races in preemption evaluation stage
+    - drm/msm/a5xx: workaround early ring-buffer emptiness check
+    - ipmi: docs: don't advertise deprecated sysfs entries
+    - drm/msm/dsi: correct programming sequence for SM8350 / SM8450
+    - drm/msm: fix %s null argument error
+    - drivers:drm:exynos_drm_gsc:Fix wrong assignment in gsc_bind()
+    - xen: use correct end address of kernel for conflict checking
+    - HID: wacom: Support sequence numbers smaller than 16-bit
+    - HID: wacom: Do not warn about dropped packets for first packet
+    - ata: libata: Clear DID_TIME_OUT for ATA PT commands with sense data
+    - minmax: avoid overly complex min()/max() macro arguments in xen
+    - xen: introduce generic helper checking for memory map conflicts
+    - xen: move max_pfn in xen_memory_setup() out of function scope
+    - xen: add capability to remap non-RAM pages to different PFNs
+    - xen: tolerate ACPI NVS memory overlapping with Xen allocated memory
+    - xen/swiotlb: add alignment check for dma buffers
+    - xen/swiotlb: fix allocated size
+    - tpm: Clean up TPM space after command failure
+    - sched/fair: Make SCHED_IDLE entity be preempted in strict hierarchy
+    - selftests/bpf: Workaround strict bpf_lsm return value check.
+    - selftests/bpf: Fix error linking uprobe_multi on mips
+    - bpf: Use -Wno-error in certain tests when building with GCC
+    - bpf: Disable some `attribute ignored' warnings in GCC
+    - bpf: Temporarily define BPF_NO_PRESEVE_ACCESS_INDEX for GCC
+    - selftests/bpf: Add CFLAGS per source file and runner
+    - selftests/bpf: Fix wrong binary in Makefile log output
+    - tools/runqslower: Fix LDFLAGS and add LDLIBS support
+    - selftests/bpf: Use pid_t consistently in test_progs.c
+    - selftests/bpf: Fix compile error from rlim_t in sk_storage_map.c
+    - selftests/bpf: Fix error compiling bpf_iter_setsockopt.c with musl libc
+    - selftests/bpf: Drop unneeded error.h includes
+    - selftests/bpf: Fix missing ARRAY_SIZE() definition in bench.c
+    - selftests/bpf: Fix missing UINT_MAX definitions in benchmarks
+    - selftests/bpf: Fix missing BUILD_BUG_ON() declaration
+    - selftests/bpf: Replace CHECK with ASSERT_* in ns_current_pid_tgid test
+    - selftests/bpf: Refactor out some functions in ns_current_pid_tgid test
+    - selftests/bpf: Add a cgroup prog bpf_get_ns_current_pid_tgid() test
+    - selftests/bpf: Fix include of <sys/fcntl.h>
+    - selftests/bpf: Fix compiling parse_tcp_hdr_opt.c with musl-libc
+    - selftests/bpf: Fix compiling kfree_skb.c with musl-libc
+    - selftests/bpf: Fix compiling flow_dissector.c with musl-libc
+    - selftests/bpf: Fix compiling tcp_rtt.c with musl-libc
+    - selftests/bpf: Fix compiling core_reloc.c with musl-libc
+    - selftests/bpf: Fix errors compiling lwt_redirect.c with musl libc
+    - selftests/bpf: Fix errors compiling decap_sanity.c with musl libc
+    - selftests/bpf: Fix errors compiling cg_storage_multi.h with musl libc
+    - selftests/bpf: Fix arg parsing in veristat, test_progs
+    - selftests/bpf: Fix error compiling test_lru_map.c
+    - selftests/bpf: Fix C++ compile error from missing _Bool type
+    - selftests/bpf: Fix flaky selftest lwt_redirect/lwt_reroute
+    - selftests/bpf: Fix redefinition errors compiling lwt_reroute.c
+    - selftests/bpf: Fix compile if backtrace support missing in libc
+    - selftests/bpf: Fix error compiling tc_redirect.c with musl libc
+    - samples/bpf: Fix compilation errors with cf-protection option
+    - bpf: correctly handle malformed BPF_CORE_TYPE_ID_LOCAL relos
+    - xz: cleanup CRC32 edits from 2018
+    - kthread: fix task state in kthread worker if being frozen
+    - ext4: clear EXT4_GROUP_INFO_WAS_TRIMMED_BIT even mount with discard
+    - smackfs: Use rcu_assign_pointer() to ensure safe assignment in smk_set_cipso
+    - ext4: avoid buffer_head leak in ext4_mark_inode_used()
+    - ext4: avoid potential buffer_head leak in __ext4_new_inode()
+    - ext4: avoid negative min_clusters in find_group_orlov()
+    - ext4: return error on ext4_find_inline_entry
+    - ext4: avoid OOB when system.data xattr changes underneath the filesystem
+    - ext4: check stripe size compatibility on remount as well
+    - sched/numa: Fix the vma scan starving issue
+    - nilfs2: fix potential null-ptr-deref in nilfs_btree_insert()
+    - nilfs2: determine empty node blocks as corrupted
+    - nilfs2: fix potential oob read in nilfs_btree_check_delete()
+    - bpf: Fix bpf_strtol and bpf_strtoul helpers for 32bit
+    - bpf: Fix helper writes to read-only maps
+    - bpf: Improve check_raw_mode_ok test for MEM_UNINIT-tagged types
+    - bpf: Zero former ARG_PTR_TO_{LONG,INT} args in case of error
+    - perf mem: Free the allocated sort string, fixing a leak
+    - perf inject: Fix leader sampling inserting additional samples
+    - perf report: Fix --total-cycles --stdio output error
+    - perf sched timehist: Fix missing free of session in perf_sched__timehist()
+    - perf stat: Display iostat headers correctly
+    - perf sched timehist: Fixed timestamp error when unable to confirm event
+      sched_in time
+    - perf time-utils: Fix 32-bit nsec parsing
+    - clk: imx: clk-audiomix: Correct parent clock for earc_phy and audpll
+    - clk: imx: imx6ul: fix default parent for enet*_ref_sel
+    - clk: imx: composite-8m: Less function calls in __imx8m_clk_hw_composite()
+      after error detection
+    - clk: imx: composite-8m: Enable gate clk with mcore_booted
+    - clk: imx: composite-93: keep root clock on when mcore enabled
+    - clk: imx: composite-7ulp: Check the PCC present bit
+    - clk: imx: fracn-gppll: fix fractional part of PLL getting lost
+    - clk: imx: imx8mp: fix clock tree update of TF-A managed clocks
+    - clk: imx: imx8qxp: Register dc0_bypass0_clk before disp clk
+    - clk: imx: imx8qxp: Parent should be initialized earlier than the clock
+    - remoteproc: imx_rproc: Correct ddr alias for i.MX8M
+    - remoteproc: imx_rproc: Initialize workqueue earlier
+    - clk: rockchip: Set parent rate for DCLK_VOP clock on RK3228
+    - clk: qcom: dispcc-sm8550: fix several supposed typos
+    - clk: qcom: dispcc-sm8550: use rcg2_ops for mdss_dptx1_aux_clk_src
+    - clk: qcom: dispcc-sm8650: Update the GDSC flags
+    - clk: qcom: dispcc-sm8550: use rcg2_shared_ops for ESC RCGs
+    - leds: bd2606mvv: Fix device child node usage in bd2606mvv_probe()
+    - pinctrl: ti: iodelay: Use scope based of_node_put() cleanups
+    - pinctrl: ti: ti-iodelay: Fix some error handling paths
+    - Input: ilitek_ts_i2c - avoid wrong input subsystem sync
+    - Input: ilitek_ts_i2c - add report id message validation
+    - drivers: media: dvb-frontends/rtl2832: fix an out-of-bounds write error
+    - drivers: media: dvb-frontends/rtl2830: fix an out-of-bounds write error
+    - PCI: Wait for Link before restoring Downstream Buses
+    - firewire: core: correct range of block for case of switch statement
+    - PCI: keystone: Fix if-statement expression in ks_pcie_quirk()
+    - clk: qcom: ipq5332: Register gcc_qdss_tsctr_clk_src
+    - clk: qcom: dispcc-sm8250: use special function for Lucid 5LPE PLL
+    - leds: leds-pca995x: Add support for NXP PCA9956B
+    - leds: pca995x: Use device_for_each_child_node() to access device child nodes
+    - leds: pca995x: Fix device child node usage in pca995x_probe()
+    - x86/PCI: Check pcie_find_root_port() return for NULL
+    - nvdimm: Fix devs leaks in scan_labels()
+    - PCI: xilinx-nwl: Fix register misspelling
+    - PCI: xilinx-nwl: Clean up clock on probe failure/removal
+    - media: platform: rzg2l-cru: rzg2l-csi2: Add missing MODULE_DEVICE_TABLE
+    - RDMA/iwcm: Fix WARNING:at_kernel/workqueue.c:#check_flush_dependency
+    - pinctrl: single: fix missing error code in pcs_probe()
+    - clk: at91: sama7g5: Allocate only the needed amount of memory for PLLs
+    - media: mediatek: vcodec: Fix H264 multi stateless decoder smatch warning
+    - media: mediatek: vcodec: Fix VP8 stateless decoder smatch warning
+    - media: mediatek: vcodec: Fix H264 stateless decoder smatch warning
+    - RDMA/rtrs: Reset hb_missed_cnt after receiving other traffic from peer
+    - RDMA/rtrs-clt: Reset cid to con_num - 1 to stay in bounds
+    - clk: ti: dra7-atl: Fix leak of of_nodes
+    - clk: starfive: Use pm_runtime_resume_and_get to fix pm_runtime_get_sync()
+      usage
+    - clk: rockchip: rk3588: Fix 32k clock name for pmu_24m_32k_100m_src_p
+    - nfsd: remove unneeded EEXIST error check in nfsd_do_file_acquire
+    - nfsd: fix refcount leak when file is unhashed after being found
+    - pinctrl: mvebu: Fix devinit_dove_pinctrl_probe function
+    - IB/core: Fix ib_cache_setup_one error flow cleanup
+    - PCI: kirin: Fix buffer overflow in kirin_pcie_parse_port()
+    - RDMA/erdma: Return QP state in erdma_query_qp
+    - RDMA/mlx5: Limit usage of over-sized mkeys from the MR cache
+    - watchdog: imx_sc_wdt: Don't disable WDT in suspend
+    - RDMA/hns: Don't modify rq next block addr in HIP09 QPC
+    - RDMA/hns: Fix Use-After-Free of rsv_qp on HIP08
+    - RDMA/hns: Fix the overflow risk of hem_list_calc_ba_range()
+    - RDMA/hns: Fix spin_unlock_irqrestore() called with IRQs enabled
+    - RDMA/hns: Fix VF triggering PF reset in abnormal interrupt handler
+    - RDMA/hns: Fix 1bit-ECC recovery address in non-4K OS
+    - RDMA/hns: Optimize hem allocation performance
+    - RDMA/hns: Fix restricted __le16 degrades to integer issue
+    - RDMA/mlx5: Obtain upper net device only when needed
+    - riscv: Fix fp alignment bug in perf_callchain_user()
+    - RDMA/cxgb4: Added NULL check for lookup_atid
+    - RDMA/irdma: fix error message in irdma_modify_qp_roce()
+    - ntb: intel: Fix the NULL vs IS_ERR() bug for debugfs_create_dir()
+    - ntb_perf: Fix printk format
+    - ntb: Force physically contiguous allocation of rx ring buffers
+    - nfsd: call cache_put if xdr_reserve_space returns NULL
+    - nfsd: return -EINVAL when namelen is 0
+    - crypto: caam - Pad SG length when allocating hash edesc
+    - crypto: powerpc/p10-aes-gcm - Disable CRYPTO_AES_GCM_P10
+    - f2fs: atomic: fix to avoid racing w/ GC
+    - f2fs: reduce expensive checkpoint trigger frequency
+    - f2fs: fix to avoid racing in between read and OPU dio write
+    - f2fs: Create COW inode from parent dentry for atomic write
+    - f2fs: fix to wait page writeback before setting gcing flag
+    - f2fs: atomic: fix to truncate pagecache before on-disk metadata truncation
+    - f2fs: support .shutdown in f2fs_sops
+    - f2fs: fix to avoid use-after-free in f2fs_stop_gc_thread()
+    - f2fs: compress: don't redirty sparse cluster during {,de}compress
+    - f2fs: prevent atomic file from being dirtied before commit
+    - f2fs: get rid of online repaire on corrupted directory
+    - f2fs: fix to don't set SB_RDONLY in f2fs_handle_critical_error()
+    - spi: atmel-quadspi: Undo runtime PM changes at driver exit time
+    - spi: spi-fsl-lpspi: Undo runtime PM changes at driver exit time
+    - lib/sbitmap: define swap_lock as raw_spinlock_t
+    - spi: atmel-quadspi: Avoid overwriting delay register settings
+    - nvme-multipath: system fails to create generic nvme device
+    - iio: adc: ad7606: fix oversampling gpio array
+    - iio: adc: ad7606: fix standby gpio state to match the documentation
+    - driver core: Fix error handling in driver API device_rename()
+    - ABI: testing: fix admv8818 attr description
+    - iio: chemical: bme680: Fix read/write ops to device by adding mutexes
+    - iio: magnetometer: ak8975: drop incorrect AK09116 compatible
+    - dt-bindings: iio: asahi-kasei,ak8975: drop incorrect AK09116 compatible
+    - driver core: Fix a potential null-ptr-deref in module_add_driver()
+    - serial: 8250: omap: Cleanup on error in request_irq
+    - coresight: tmc: sg: Do not leak sg_table
+    - interconnect: icc-clk: Add missed num_nodes initialization
+    - cxl/pci: Fix to record only non-zero ranges
+    - vhost_vdpa: assign irq bypass producer token correctly
+    - ep93xx: clock: Fix off by one in ep93xx_div_recalc_rate()
+    - Revert "dm: requeue IO if mapping table not yet available"
+    - net: xilinx: axienet: Schedule NAPI in two steps
+    - net: xilinx: axienet: Fix packet counting
+    - netfilter: nf_reject_ipv6: fix nf_reject_ip6_tcphdr_put()
+    - net: seeq: Fix use after free vulnerability in ether3 Driver Due to Race
+      Condition
+    - net: ipv6: select DST_CACHE from IPV6_RPL_LWTUNNEL
+    - tcp: check skb is non-NULL in tcp_rto_delta_us()
+    - net: qrtr: Update packets cloning when broadcasting
+    - bonding: Fix unnecessary warnings and logs from bond_xdp_get_xmit_slave()
+    - virtio_net: Fix mismatched buf address when unmapping for small packets
+    - netfilter: nf_tables: Keep deleted flowtable hooks until after RCU
+    - netfilter: ctnetlink: compile ctnetlink_label_size with
+      CONFIG_NF_CONNTRACK_EVENTS
+    - netfilter: nf_tables: use rcu chain hook list iterator from netlink dump
+      path
+    - io_uring/sqpoll: do not allow pinning outside of cpuset
+    - io_uring: check for presence of task_work rather than TIF_NOTIFY_SIGNAL
+    - mm: call the security_mmap_file() LSM hook in remap_file_pages()
+    - drm/amd/display: Fix Synaptics Cascaded Panamera DSC Determination
+    - Revert "net: libwx: fix alloc msix vectors failed"
+    - xen: move checks for e820 conflicts further up
+    - xen: allow mapping ACPI data using a different physical address
+    - io_uring/sqpoll: retain test for whether the CPU is valid
+    - io_uring/sqpoll: do not put cpumask on stack
+    - Remove *.orig pattern from .gitignore
+    - PCI: Revert to the original speed after PCIe failed link retraining
+    - PCI: Clear the LBMS bit after a link retrain
+    - PCI: dra7xx: Fix threaded IRQ request for "dra7xx-pcie-main" IRQ
+    - PCI: imx6: Fix missing call to phy_power_off() in error handling
+    - PCI: Correct error reporting with PCIe failed link retraining
+    - PCI: Use an error code with PCIe failed link retraining
+    - PCI: xilinx-nwl: Fix off-by-one in INTx IRQ handler
+    - Revert "soc: qcom: smd-rpm: Match rpmsg channel instead of compatible"
+    - ASoC: rt5682: Return devm_of_clk_add_hw_provider to transfer the error
+    - soc: fsl: cpm1: tsa: Fix tsa_write8()
+    - soc: versatile: integrator: fix OF node leak in probe() error path
+    - Revert "media: tuners: fix error return code of
+      hybrid_tuner_request_state()"
+    - iommufd: Protect against overflow of ALIGN() during iova allocation
+    - Input: adp5588-keys - fix check on return code
+    - Input: i8042 - add TUXEDO Stellaris 16 Gen5 AMD to i8042 quirk table
+    - Input: i8042 - add TUXEDO Stellaris 15 Slim Gen6 AMD to i8042 quirk table
+    - Input: i8042 - add another board name for TUXEDO Stellaris Gen5 AMD line
+    - KVM: arm64: Add memory length checks and remove inline in do_ffa_mem_xfer
+    - KVM: x86: Enforce x2APIC's must-be-zero reserved ICR bits
+    - KVM: x86: Move x2APIC ICR helper above kvm_apic_write_nodecode()
+    - KVM: Use dedicated mutex to protect kvm_usage_count to avoid deadlock
+    - drm/amd/display: Add HDMI DSC native YCbCr422 support
+    - drm/amd/display: Round calculated vtotal
+    - drm/amd/display: Validate backlight caps are sane
+    - KEYS: prevent NULL pointer dereference in find_asymmetric_key()
+    - powerpc/atomic: Use YZ constraints for DS-form instructions
+    - fs: Create a generic is_dot_dotdot() utility
+    - ksmbd: make __dir_empty() compatible with POSIX
+    - ksmbd: allow write with FILE_APPEND_DATA
+    - ksmbd: handle caseless file creation
+    - ata: libata-scsi: Fix ata_msense_control() CDL page reporting
+    - scsi: sd: Fix off-by-one error in sd_read_block_characteristics()
+    - scsi: ufs: qcom: Update MODE_MAX cfg_bw value
+    - scsi: mac_scsi: Revise printk(KERN_DEBUG ...) messages
+    - scsi: mac_scsi: Refactor polling loop
+    - scsi: mac_scsi: Disallow bus errors during PDMA send
+    - can: esd_usb: Remove CAN_CTRLMODE_3_SAMPLES for CAN-USB/3-FD
+    - wifi: rtw88: Fix USB/SDIO devices not transmitting beacons
+    - usbnet: fix cyclical race on disconnect with work queue
+    - USB: appledisplay: close race between probe and completion handler
+    - USB: misc: cypress_cy7c63: check for short transfer
+    - USB: class: CDC-ACM: fix race between get_serial and set_serial
+    - usb: cdnsp: Fix incorrect usb_request status
+    - usb: dwc2: drd: fix clock gating on USB role switch
+    - bus: integrator-lm: fix OF node leak in probe()
+    - bus: mhi: host: pci_generic: Fix the name for the Telit FE990A
+    - firmware_loader: Block path traversal
+    - tty: rp2: Fix reset with non forgiving PCIe host bridges
+    - xhci: Set quirky xHC PCI hosts to D3 _after_ stopping and freeing them.
+    - serial: qcom-geni: fix fifo polling timeout
+    - crypto: ccp - Properly unregister /dev/sev on sev PLATFORM_STATUS failure
+    - drbd: Fix atomicity violation in drbd_uuid_set_bm()
+    - drbd: Add NULL check for net_conf to prevent dereference in state validation
+    - ACPI: sysfs: validate return type of _STR method
+    - ACPI: resource: Add another DMI match for the TongFang GMxXGxx
+    - efistub/tpm: Use ACPI reclaim memory for event log to avoid corruption
+    - perf/x86/intel/pt: Fix sampling synchronization
+    - wifi: mt76: mt7921: Check devm_kasprintf() returned value
+    - wifi: mt76: mt7915: check devm_kasprintf() returned value
+    - wifi: mt76: mt7996: fix NULL pointer dereference in mt7996_mcu_sta_bfer_he
+    - wifi: rtw88: 8821cu: Remove VID/PID 0bda:c82c
+    - wifi: rtw88: 8822c: Fix reported RX band width
+    - wifi: mt76: mt7615: check devm_kasprintf() returned value
+    - debugobjects: Fix conditions in fill_pool()
+    - btrfs: tree-checker: fix the wrong output of data backref objectid
+    - btrfs: always update fstrim_range on failure in FITRIM ioctl
+    - f2fs: fix several potential integer overflows in file offsets
+    - f2fs: prevent possible int overflow in dir_block_index()
+    - f2fs: avoid potential int overflow in sanity_check_area_boundary()
+    - f2fs: Require FMODE_WRITE for atomic write ioctls
+    - f2fs: fix to check atomic_file in f2fs ioctl interfaces
+    - hwrng: mtk - Use devm_pm_runtime_enable
+    - hwrng: bcm2835 - Add missing clk_disable_unprepare in bcm2835_rng_init
+    - hwrng: cctrng - Add missing clk_disable_unprepare in cctrng_resume
+    - arm64: esr: Define ESR_ELx_EC_* constants as UL
+    - arm64: errata: Enable the AC03_CPU_38 workaround for ampere1a
+    - arm64: dts: rockchip: Raise Pinebook Pro's panel backlight PWM frequency
+    - arm64: dts: qcom: sa8775p: Mark APPS and PCIe SMMUs as DMA coherent
+    - arm64: dts: rockchip: Correct the Pinebook Pro battery design capacity
+    - vfs: fix race between evice_inodes() and find_inode()&iput()
+    - fs: Fix file_set_fowner LSM hook inconsistencies
+    - nfs: fix memory leak in error path of nfs4_do_reclaim
+    - EDAC/igen6: Fix conversion of system address to physical memory address
+    - icmp: change the order of rate limits
+    - cpuidle: riscv-sbi: Use scoped device node handling to fix missing
+      of_node_put
+    - padata: use integer wrap around to prevent deadlock on seq_nr overflow
+    - spi: fspi: involve lut_num for struct nxp_fspi_devtype_data
+    - ARM: dts: imx6ul-geam: fix fsl,pins property in tscgrp pinctrl
+    - soc: versatile: realview: fix memory leak during device remove
+    - soc: versatile: realview: fix soc_dev leak during device remove
+    - USB: misc: yurex: fix race between read and write
+    - xhci: Add a quirk for writing ERST in high-low order
+    - usb: xhci: fix loss of data on Cadence xHC
+    - pps: remove usage of the deprecated ida_simple_xx() API
+    - pps: add an error check in parport_attach
+    - serial: don't use uninitialized value in uart_poll_init()
+    - x86/idtentry: Incorporate definitions/declarations of the FRED entries
+    - x86/entry: Remove unwanted instrumentation in common_interrupt()
+    - lib/bitmap: add bitmap_{read,write}()
+    - btrfs: subpage: fix the bitmap dump which can cause bitmap corruption
+    - btrfs: fix race setting file private on concurrent lseek using same fd
+    - dt-bindings: spi: nxp-fspi: support i.MX93 and i.MX95
+    - dt-bindings: spi: nxp-fspi: add imx8ulp support
+    - thunderbolt: Improve DisplayPort tunnel setup process to be more robust
+    - bpf: lsm: Set bpf_lsm_blob_sizes.lbs_task to 0
+    - dm-verity: restart or panic on an I/O error
+    - lockdep: fix deadlock issue between lockdep and rcu
+    - mm: only enforce minimum stack gap size if it's sensible
+    - spi: fspi: add support for imx8ulp
+    - module: Fix KCOV-ignored file name
+    - mm/damon/vaddr: protect vma traversal in __damon_va_thre_regions() with rcu
+      read lock
+    - i2c: aspeed: Update the stop sw state when the bus recovery occurs
+    - i2c: isch: Add missed 'else'
+    - Documentation: KVM: fix warning in "make htmldocs"
+    - bpf: Fix use-after-free in bpf_uprobe_multi_link_attach()
+    - wifi: brcmfmac: add linefeed at end of file
+    - x86/tdx: Fix "in-kernel MMIO" check
+    - spi: atmel-quadspi: Fix wrong register value written to MR
+    - Revert: "dm-verity: restart or panic on an I/O error"
+    - wifi: ath11k: use work queue to process beacon tx event
+    - crypto: qat - disable IOV in adf_dev_stop()
+    - crypto: qat - fix recovery flow for VFs
+    - crypto: qat - ensure correct order in VF restarting handler
+    - crypto: iaa - Fix potential use after free bug
+    - autofs: fix missing fput for FSCONFIG_SET_FD
+    - arm64: smp: smp_send_stop() and crash_smp_send_stop() should try non-NMI
+      first
+    - thermal: core: Fold two functions into their respective callers
+    - thermal: core: Fix rounding of delay jiffies
+    - perf/dwc_pcie: Fix registration issue in multi PCIe controller instances
+    - perf/dwc_pcie: Always register for PCIe bus notifier
+    - ACPI: video: force native for some T2 macbooks
+    - ACPI: video: force native for Apple MacbookPro9,2
+    - wifi: cfg80211: fix bug of mapping AF3x to incorrect User Priority
+    - wifi: mac80211: fix the comeback long retry times
+    - ACPICA: Implement ACPI_WARNING_ONCE and ACPI_ERROR_ONCE
+    - ACPICA: executer/exsystem: Don't nag user about every Stall() violating the
+      spec
+    - netfilter: nft_dynset: annotate data-races around set timeout
+    - wifi: mt76: mt7921: fix wrong UNII-4 freq range check for the channel usage
+    - crypto: ccp - do not request interrupt on cmd completion when irqs disabled
+    - wifi: mt76: connac: fix checksum offload fields of connac3 RXD
+    - net: hsr: Use the seqnr lock for frames received via interlink port.
+    - crypto: n2 - Set err to EINVAL if snprintf fails for hmac
+    - firmware: qcom: scm: Disable SDI and write no dump to dump mode
+    - arm64: dts: renesas: r9a08g045: Correct GICD and GICR sizes
+    - arm64: tegra: Correct location of power-sensors for IGX Orin
+    - arm64: dts: ti: k3-am654-idk: Fix dtbs_check warning in ICSSG dmas
+    - selftests/ftrace: Fix eventfs ownership testcase to find mount point
+    - iommu/amd: Introduce struct protection_domain.pd_mode
+    - iommu/amd: Allocate the page table root using GFP_KERNEL
+    - iommu/amd: Convert comma to semicolon
+    - platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
+    - kselftest: dt: Ignore nodes that have ancestors disabled
+    - bpf, x64: Fix tailcall hierarchy
+    - bpf, lsm: Add check for BPF LSM return value
+    - bpf: Fix compare error in function retval_range_within
+    - bpf: Fail verification for sign-extension of packet data/data_end/data_meta
+    - selftests/bpf: Support checks against a regular expression
+    - selftests/bpf: no need to track next_match_pos in struct test_loader
+    - selftests/bpf: extract test_loader->expect_msgs as a data structure
+    - selftests/bpf: allow checking xlated programs in verifier_* tests
+    - selftests/bpf: __arch_* macro to limit test cases to specific archs
+    - libbpf: Fix bpf_object__open_skeleton()'s mishandling of options
+    - s390/ap: Fix deadlock caused by recursive lock of the AP bus scan mutex
+    - sched/deadline: Fix schedstats vs deadline servers
+    - perf scripts python cs-etm: Restore first sample log in verbose mode
+    - perf lock contention: Change stack_id type to s32
+    - quota: avoid missing put_quota_format when DQUOT_SUSPENDED is passed
+    - media: staging: media: starfive: camss: Drop obsolete return value
+      documentation
+    - leds: gpio: Set num_leds after allocation
+    - iommufd/selftest: Fix buffer read overrrun in the dirty test
+    - iommufd: Check the domain owner of the parent before creating a nesting
+      domain
+    - RDMA/mlx5: Fix counter update on MR cache mkey creation
+    - RDMA/mlx5: Drop redundant work canceling from clean_keys()
+    - RDMA/mlx5: Fix MR cache temp entries cleanup
+    - RDMA/hns: Fix ah error counter in sw stat not increasing
+    - Coresight: Set correct cs_mode for TPDM to fix disable issue
+    - Coresight: Set correct cs_mode for dummy source to fix disable issue
+    - interconnect: qcom: sm8250: Enable sync_state
+    - vdpa/mlx5: Fix invalid mr resource destroy
+    - net: stmmac: set PP_FLAG_DMA_SYNC_DEV only if XDP is enabled
+    - selftests: netfilter: Avoid hanging ipvs.sh
+    - io_uring/rw: treat -EOPNOTSUPP for IOCB_NOWAIT like -EAGAIN
+    - mm: migrate: annotate data-race in migrate_folio_unmap()
+    - selftests/bpf: correctly move 'log' upon successful match
+    - soc: fsl: cpm1: qmc: Update TRNSYNC only in transparent mode
+    - drm/amdgpu/vcn: enable AV1 on both instances
+    - drm/amd/display: Clean up dsc blocks in accelerated mode
+    - drm/amd/display: Skip to enable dsc if it has been off
+    - arm64: dts: mediatek: mt8195-cherry: Mark USB 3.0 on xhci1 as disabled
+    - usb: xHCI: add XHCI_RESET_ON_RESUME quirk for Phytium xHCI host
+    - serial: qcom-geni: fix false console tx restart
+    - crypto: qcom-rng - fix support for ACPI-based systems
+    - ACPI: resource: Do IRQ override on MECHREV GM7XG0M
+    - perf/x86/intel: Allow to setup LBR for counting event for BPF
+    - f2fs: check discard support for conventional zones
+    - netfs: Delete subtree of 'fs/netfs' when netfs module exits
+    - md: Don't flush sync_work in md_write_start()
+    - tools/nolibc: include arch.h from string.h
+    - KVM: x86: Make x2APIC ID 100% readonly
+    - x86/mm/cpa: Warn for set_memory_XXcrypted() VMM fails
+    - x86/mm: Make x86_platform.guest.enc_status_change_*() return an error
+    - x86/tdx: Account shared memory
+    - x86/mm: Add callbacks to prepare encrypted memory for kexec
+    - x86/tdx: Convert shared memory back to private on kexec
+    - soc: qcom: geni-se: add GP_LENGTH/IRQ_EN_SET/IRQ_EN_CLEAR registers
+    - serial: qcom-geni: fix arg types for qcom_geni_serial_poll_bit()
+    - serial: qcom-geni: introduce qcom_geni_serial_poll_bitfield()
+    - idpf: stop using macros for accessing queue descriptors
+    - fs_parse: add uid & gid option option parsing helpers
+    - compiler.h: specify correct attribute for .rodata..c_jump_table
+    - exfat: resolve memory leak from exfat_create_upcase_table()
+    - s390/ftrace: Avoid calling unwinder in ftrace_return_address()
+    - fbdev: xen-fbfront: Assign fb_info->device
+    - [Config] update configs for CONFIG_CRYPTO_AES_GCM_P10
+    - Upstream stable to v6.6.54, v6.10.13
+  * Backport some AppArmor complain-mode profile bugfixes from Oracular
+    (LP: #2086210)
+    - SAUCE: apparmor4.0.0 [94/99]: apparmor: allocate xmatch for nullpdf inside
+      aa_alloc_null
+    - SAUCE: apparmor4.0.0 [95/99]: apparmor: properly handle cx/px lookup failure
+      for complain mode profiles
+  * Noble update: upstream stable patchset 2024-11-08 (LP: #2087519)
+    - ASoC: SOF: mediatek: Add missing board compatible
+    - ASoC: mediatek: mt8188: Mark AFE_DAC_CON0 register as volatile
+    - ASoC: allow module autoloading for table db1200_pids
+    - ASoC: allow module autoloading for table board_ids
+    - scsi: lpfc: Fix overflow build issue
+    - pinctrl: at91: make it work with current gpiolib
+    - hwmon: (asus-ec-sensors) remove VRM temp X570-E GAMING
+    - microblaze: don't treat zero reserved memory regions as error
+    - platform/x86: x86-android-tablets: Make Lenovo Yoga Tab 3 X90F DMI match
+      less strict
+    - net: ftgmac100: Ensure tx descriptor updates are visible
+    - LoongArch: Define ARCH_IRQ_INIT_FLAGS as IRQ_NOPROBE
+    - wifi: iwlwifi: lower message level for FW buffer destination
+    - wifi: iwlwifi: mvm: fix iwl_mvm_scan_fits() calculation
+    - wifi: iwlwifi: mvm: fix iwl_mvm_max_scan_ie_fw_cmd_room()
+    - wifi: iwlwifi: mvm: pause TCM when the firmware is stopped
+    - wifi: iwlwifi: mvm: don't wait for tx queues if firmware is dead
+    - wifi: mac80211: free skb on error path in ieee80211_beacon_get_ap()
+    - wifi: iwlwifi: clear trans->state earlier upon error
+    - can: mcp251xfd: mcp251xfd_ring_init(): check TX-coalescing configuration
+    - ASoC: Intel: soc-acpi-cht: Make Lenovo Yoga Tab 3 X90F DMI match less strict
+    - ASoC: intel: fix module autoloading
+    - ASoC: google: fix module autoloading
+    - ASoC: tda7419: fix module autoloading
+    - ASoC: fix module autoloading
+    - spi: spidev: Add an entry for elgin,jg10309-01
+    - ASoC: amd: yc: Add a quirk for MSI Bravo 17 (D7VEK)
+    - ALSA: hda: add HDMI codec ID for Intel PTL
+    - drm: komeda: Fix an issue related to normalized zpos
+    - spi: bcm63xx: Enable module autoloading
+    - smb: client: fix hang in wait_for_response() for negproto
+    - x86/hyperv: Set X86_FEATURE_TSC_KNOWN_FREQ when Hyper-V provides frequency
+    - tools: hv: rm .*.cmd when make clean
+    - spi: spidev: Add missing spi_device_id for jg10309-01
+    - ocfs2: add bounds checking to ocfs2_xattr_find_entry()
+    - ocfs2: strict bound check before memcmp in ocfs2_xattr_find_entry()
+    - drm: Use XArray instead of IDR for minors
+    - accel: Use XArray instead of IDR for minors
+    - drm: Expand max DRM device number to full MINORBITS
+    - powercap/intel_rapl: Add support for AMD family 1Ah
+    - netfilter: nft_socket: make cgroupsv2 matching work with namespaces
+    - netfilter: nft_socket: Fix a NULL vs IS_ERR() bug in
+      nft_socket_cgroup_subtree_level()
+    - nvme-pci: qdepth 1 quirk
+    - x86/mm: Switch to new Intel CPU model defines
+    - can: mcp251xfd: properly indent labels
+    - can: mcp251xfd: move mcp251xfd_timestamp_start()/stop() into
+      mcp251xfd_chip_start/stop()
+    - USB: serial: pl2303: add device id for Macrosilicon MS3020
+    - USB: usbtmc: prevent kernel-usb-infoleak
+    - platform/x86: asus-wmi: Fix spurious rfkill on UX8406MA
+    - ASoC: mediatek: mt8188-mt6359: Modify key
+    - clk: qcom: gcc-sm8650: Don't use shared clk_ops for QUPs
+    - ice: check for XDP rings instead of bpf program when unconfiguring
+    - powercap/intel_rapl: Fix the energy-pkg event for AMD CPUs
+    - powercap: intel_rapl: Change an error pointer to NULL
+    - Upstream stable to v6.6.53, v6.10.12
+
+  [ Ubuntu: 6.8.0-52.53 ]
+
+  * noble/linux: 6.8.0-52.53 -proposed tracker (LP: #2093521)
+  * CVE-2024-53164
+    - net: sched: fix ordering of qlen adjustment
+  * CVE-2024-53141
+    - netfilter: ipset: add missing range check in bitmap_ip_uadt
+  * CVE-2024-53103
+    - hv_sock: Initializing vsk->trans to NULL to prevent a dangling pointer
+
+  [ Ubuntu: 6.8.0-51.52 ]
+
+  * noble/linux: 6.8.0-51.52 -proposed tracker (LP: #2090369)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+    - [Packaging] update variants
+  * MGLRU: kswapd uses 100% CPU when MGLRU is enabled and under memory pressure
+    (LP: #2087886)
+    - mm/mglru: only clear kswapd_failures if reclaimable
+  * CVE-2024-50264
+    - vsock/virtio: Initialization of the dangling pointer occurring in vsk->trans
+  * CVE-2024-53057
+    - net/sched: stop qdisc_tree_reduce_backlog on TC_H_ROOT
+  * CVE-2024-49967
+    - ext4: no need to continue when the number of entries is 1
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 12 Feb 2025 21:04:42 +0900
+
+linux-qcom (6.8.0-1027.27) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1027.27 -proposed tracker (LP: #2097551)
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 07 Feb 2025 00:20:45 +0900
+
+linux-qcom (6.8.0-1025.25) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1025.25 -proposed tracker (LP: #2097247)
+    - [Packaging] switch from jammy to noble
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 03 Feb 2025 22:35:26 +0900
+
+linux-qcom (6.8.0-1023.23) jammy; urgency=medium
+
+  * jammy/linux-qcom: 6.8.0-1023.23 -proposed tracker (LP: #2097246)
+
+  * Miscellaneous upstream changes
+    - PENDING: iommu/arm-smmu: add ACTLR data and support for sa7255p
+    - QCLINUX: arm64: dts: qcom: Enable gpu tsens mitigation for sa8775p variants
+    - PENDING: arm64: dts: qcom: sa8255p: Add ICE node
+    - QCLINUX: arm64: defconfigs: Enable PCIe EP configuration
+    - QCLINUX: firmware: qtee_shmbridge: Fix stubs
+    - FROMLIST: firmware: qcom: scm: add a call for deriving the software secret
+    - FROMLIST: firmware: qcom: scm: add calls for creating, preparing and
+      importing keys
+    - QCLINUX: arm64: qcom_defconfig: enable SHM Bridge support for the TZ memory
+      allocator
+    - QCLINUX: firmware: qtee_shmbrige: Disable bridge enablement call
+    - PENDING: firmware: qcom_tzmem: Add register/deregister interfaces
+    - PENDING: firmware: qcom: tz_log: Migrate to qcom_tzmem interfaces
+    - PENDING: soc: qcom: memory_dump: Use qcom_tzmem interfaces
+    - PENDING: arm64: defconfig: qcom: Enable MMC crypto
+    - QCLINUX: soc: qcom: smem: Switch partitions to xarray
+    - QCLINUX: soc: qcom: smem: Ignore multi remote host partitions
+    - PENDING: arm64: dts: qcom: sa8255p: Add PCIe EP nodes
+    - PENDING: qcom: ice: enable ufs clock scaling
+    - PENDING: arm64: dts: qcom: qcs9075-rb8: Add PON resin support
+    - PENDING: arm64: dts: qcom: Add duplicate funnel device
+    - PENDING: clk: qcom: videocc-sa8775p: Remove HW_CTRL for video_cc_mvs0_gdsc
+    - PENDING: arm64: dts: qcom: Add cpufreq_hw support on sa7255p
+    - QCLINUX: ASoC: qcom: qdsp6: msm_audio_mem: Fix excessive logging in
+      msm_audio_mem_ioctl fun
+    - BACKPORT: FROMLIST: arm64: dts: qcom: qcs9100: Update memory map for QCS9100
+      Ride and QCS9100 Ride Rev3
+    - QCLINUX: firmware: qcom_scm: Fix indentation for ice scm calls
+    - FROMLIST: PCI: epf-mhi: Update device id for SA8775P
+    - FROMLIST: bus: mhi: host: pci_generic: Add supoprt for SA8775P target
+    - QCLINUX: usb: dwc3: qcom: export core_exit_mode and free_event_buffers
+    - FROMLIST: net: Add MHI Endpoint network driver
+    - PENDING: arm64: dts: qcom: Add MXC power domain to camcc node on QCS8300
+    - PENDING: arm64: dts: qcom: sa7255p: Add pcie nodes
+    - PENDING: net: phy: aquantia: AQR113c fix up PMA capabilities
+    - QCLINUX: arm64: dts: qcom: Add nodes for Data Capture and Compare
+    - QCLINUX: arm64: dts: qcom: Update the size for swao-etf node
+    - PENDING: thermal: qcom: add support for nsp1 qmi tmd devices
+    - PENDING: arm64: dts: qcom: Disable idle injection cooling device for cpu0
+    - QCLINUX: arm64: dts: qcom: Enable cdsp qmi tmd devices for sa8775p variants
+    - QCLINUX: arm64: dts: qcom: use 2nd trip for gpu passive cooling mitigation
+    - PENDING: net: stmmac: Add sa8797p support within ethqos driver
+    - PENDING: net: stmmac: Add 4k Virtualization support to Emac registers
+    - PENDING: net: stmmac: Add IO macro configuration for USXGMII
+    - PENDING: arm64: dts: qcom: Enable EUD on QCS9075 RB8
+    - PENDING: arm64: dts: qcom: sa7255p: Add ICE node
+    - QCLINUX: arm64: defconfig: enable scmi-cpufreq and cpucp mbox
+    - PENDING: net: stmmac: Add Qcom specific changes for HDMA
+    - QCLINUX: arm64: defconfigs: Enable MHI configs for PCIE RC and EP
+    - FROMLIST: drm/msm/dpu: fix the intf_type of MST interfaces
+    - FROMLIST: drm/msm/dp: split msm_dp_panel_read_sink_caps() into two parts
+    - FROMLIST: drm/msm/dp: add a helper to read mst caps for dp_panel
+    - FROMLIST: drm/msm/dp: remove dp_display's dp_mode and use dp_panel's instead
+    - FROMLIST: drm/msm/dp: break up dp_display_enable into two parts
+    - FROMLIST: drm/msm/dp: re-arrange dp_display_disable() into functional parts
+    - FROMLIST: drm/msm/dp: allow dp_ctrl stream APIs to use any panel passed to
+      it
+    - PENDING: net: stmmac: Add missing 25GMAC link capabilities
+    - PENDING: phy: qcom: qmp: Add default Type-C reverse orientation flag
+    - PENDING: net: stmmac: Move desc cache compute within HDMA
+    - PENDING: net: PCS: Add Qualcomm XPCS driver
+    - PENDING: arm64: dts: qcom: qcs8300: add support for steam 1
+    - FROMLIST: nvmem: qfprom: Add constraint read for some SoCs
+    - FROMLIST: arm64/dts/qcom: add mst support for stream 1 clk
+    - FROMLIST: drm/msm/dp: move the pixel clock control to its own API
+    - PENDING: net: stmmac: Use new Qualcomm XPCS driver
+    - QCLINUX: arm64: defconfig: Remove HVC console for Gen5auto targets
+    - PENDING: ASoC: codecs: wcd937x: fix aux playback issue
+    - FROMLIST: arm64: dts: qcom: sa8775p: Add CPUs to psci power domain
+    - QCLINUX: arm64: dts: qcom: Disable HCI uart for Industrial mezz kit
+    - PENDING: soc: qcom: smcinvoke: Remove mem-buf dependency for PVM
+    - QCLINUX: ASoC: qcom: qcm6490: fix the probe defer issue
+    - FROMLIST: drm/msm/dp: split dp_ctrl_off() into stream and link parts
+    - FROMLIST: drm/msm/dp: make bridge helpers use dp_display to allow re-use
+    - FROMLIST: drm/msm/dp: separate dp_display_prepare() into its own API
+    - FROMLIST: drm/msm/dp: introduce stream_id for each DP panel
+    - FROMLIST: drm/msm/dp: convert dp_display_set_mode() to use dp_panel argument
+    - FROMLIST: drm/msm/dp: add support for programming p1 register block
+    - FROMLIST: drm/msm/dp: use stream_id to change offsets in dp_catalog
+    - FROMLIST: drm/msm/dp: add support to send ACT packets for MST
+    - FROMLIST: drm/msm/dp: add support to program mst support in mainlink
+    - FROMLIST: drm/msm/dp: no need to update tu calculation for mst
+    - FROMLIST: drm/msm/dp: add support for mst channel slot allocation
+    - FROMLIST: drm/msm/dp: add support to send vcpf packets in dp controller
+    - FROMLIST: drm/msm/dp: always program MST_FIFO_CONSTANT_FILL for MST
+    - FROMLIST: drm/msm/dp: abstract out the dp_display stream helpers to accept a
+      panel
+    - FROMLIST: drm/msm/dp: move link related operations to dp_display_unprepare()
+    - FROMLIST: drm/msm/dp: replace power_on with active_stream_cnt for dp_display
+    - FROMLIST: drm/msm/dp: make the SST bridge disconnected when
+    - PENDING: drm/msm/dp: make the mst disable call separate
+    - FROMLIST: drm/msm/dp: add an API to initialize MST on sink side
+    - FROMLIST: drm/msm/dp: skip reading the EDID for MST cases
+    - FROMLIST: drm/msm/dp: add dp_display_get_panel() to initialize DP panel
+    - FROMLIST: drm/msm/dp: add dp_mst_drm to manage DP MST bridge operations
+    - FROMLIST: drm/msm/dp: add connector abstraction for DP MST
+    - FROMLIST: drm/msm/dp: add irq hpd callback for dp mst
+    - PENDING: drm/msm/dp: use the max_streams from dp catalog
+    - FROMLIST: drm/msm/dp: add support to re-use and clear the panel edid
+    - FROMLIST: drm/msm/dp: add a mst session mutex to protect bridge ops
+    - FROMLIST: drm/msm/dp: propagate hpd state changes to dp mst module
+    - PENDING: drm/msm/dp: make the changes for hpd to work
+    - FROMLIST: drm/msm: add support for non-blocking commits
+    - FROMLIST: drm/msm: initialize DRM MST encoders for DP controllers
+    - FROMLIST: drm/msm/dp: initialize dp_mst module for each DP MST controller
+    - FROMLIST: drm/msm: add a stream to intf map for DP controller
+    - FROMLIST: drm/msm/dpu: use msm_dp_get_mst_intf_id() to get the intf id
+    - FROMLIST: drm/msm/dp: populate the max_streams for sa8775 mst controller
+    - PENDING: drm/msm/dpu: make max h_display split to 2560 to allow 4 streams
+    - PENDING: drm/msm/dp: populate the max streams for DP1
+    - FROMLIST: drm: allow encoder mode_set even when connectors change for crtc
+    - PENDING: drm/msm/dp: fix up the hpd state machine for mst cases
+    - PENDING: drm/msm/dp: use stream id for streams clk on
+    - PENDING: drm/msm/dp: populate the max_streams for qcs8300
+    - FROMLIST: arm64/dts/qcom: add mst support for stream 0 clk
+    - FROMLIST: irqchip: gic-v3: Handle failure case of CPU enters low power state
+    - PENDING: arm64: dts: qcom: qcs8300: Fix quirks being added to usb node
+    - QCLINUX: arm64: dts: qcom: remove unused tlmm gpio entry
+    - FROMLIST: Revert "PENDING: Bluetooth: hci_sync: Fix disconnect
+    - PENDING: arm64: dts: qcom: Add L3 interconnect device for QCS8300
+    - PENDING: arm64: dts: qcom: Add static vote for QCS8300
+    - QCLINUX: arm64: defconfig: Enable additional debug configs for gen5auto
+    - QCLINUX: arm64: dts: qcom: Add reserved regions
+    - PENDING: arm64: dts: qcom: qcs8300: Add support to scale DDR/L3
+    - PENDING: arm64: dts: qcom: qcs8300: Add LMH interrupts for cpufreq_hw node
+    - PENDING: clk: qcom: gdsc: Increase the GDSC status poll timeout
+    - QCLINUX: firmware: shmbridge/tzmem: Improve error reporting
+    - QCLINUX: ASoC: qcom: qdsp6: Increase the timeout to 5 secs
+    - PENDING: net: stmmac: enable SGMII loopback for DMA reset
+    - QCLINUX: arm64: dts: qcom: Add addons support for QCS615 RIDE
+    - QCLINUX: arm64: dts: qcom: Add board-id and msm-id for QCS615
+    - QCLINUX: arm64: deconfig: enable clock controller, interconnect and pinctrl
+      for QCS615
+    - BACKPORT: FROMGIT: clk: qcom: rpmhcc: Add support for QCS615 Clocks
+    - BACKPORT: FROMGIT: clk: qcom: gcc: Add support for QCS615 GCC clocks
+    - FROMLIST: pinctrl: qcom: correct the ngpios entry for QCS615
+    - PENDING: net: stmmac: Support 10GBaseR iomacro configuration
+    - QCLINUX: arm64: defconfig: enable carveout heaps
+    - FROMLIST: misc: fastrpc: Fix race condition in MUNMAP
+    - PENDING: net: PCS: Add 10GBaseR support in XPCS driver
+    - PENDING: arm64: dts: qcom: qcs9075: Update memory map for qcs9075
+    - Ubuntu: [Config] update CONFIG options for Yocto GA 1.3.1
+    - drm/i915: convert remaining intel_dp_vsc_sdp_pack
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 03 Feb 2025 17:53:58 +0900
+
+linux-qcom (6.8.0-1019.19) jammy; urgency=medium
+
+  * jammy/linux-qcom: 6.8.0-1019.19 -proposed tracker (LP: #2095417)
+
+  * "[RB3] tc956x_pci-eth errors found in dmesg"
+    - SAUCE: ubuntu/qcom/qps615: suppress false alerts
+    - SAUCE: ubuntu/qcom/qps615: use INFO level for logging
+
+  * [RB3] drm sde error/ msm-dsi-error found in dmesg
+    - SAUCE: do not show error on EPROBE_DEFER
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: import external DT from GA 1.3
+    - SAUCE: Add Makefile code to apply overlays for GA1.2
+    - SAUCE: ubuntu/qcom/display: import qcm6490 display code from GA1.3
+    - SAUCE: ubuntu/qcom/graphics: import qcm6490 graphics driver code from GA1.3
+    - SAUCE: ubuntu/qcom/camera: import qcm6490 camera driver code from GA1.3
+    - SAUCE: ubuntu/qcom/qps615: import ethernet driver from GA1.3
+    - SAUCE: ubuntu/qcom/video: import video driver from GA 1.3
+    - SAUCE: ubuntu/qcom: build external drivers
+    - SAUCE: ubuntu/qcom/camera: fix build warnings and errors
+    - SAUCE: suppress unneeded build logs
+    - SAUCE: ubuntu/qcom: suppress Wno-enum-int-mismatch warning
+    - SAUCE: ubuntu/qcom/graphics: change strtobool() to kstrtobool()
+    - SAUCE: ubuntu/qcom/graphics: dynamically allocate the kgsl-pool shrinker for
+      kernel>=6.7
+    - SAUCE: ubuntu/qcom/camera: remove unused camera_banner
+    - SAUCE: ubuntu/qcom/camera: use sizeof() instead of V4L2_SUBDEV_NAME_SIZE
+    - SAUCE: ubuntu/qcom/camera: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/video: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: auto-load module
+    - SAUCE: ubuntu/qcom: add missing inclusion
+    - SAUCE: ubuntu/qcom/display: Rename min_buffers_needed to min_queued_buffers
+    - SAUCE: ubuntu/qcom: remove DRM_UNLOCKED
+    - SAUCE: ubuntu/qcom/display: suppress EPROBE_DEFER error log
+    - SAUCE: Add Makefile code to apply qcs5430 overlays for GA1.2
+    - SAUCE: rename qcom,phy-rst-gpio to qcom,phy-rst-gpio-id
+    - SAUCE: comment out BUILD_TIMESTAMP
+    - SAUCE: add more DT to combined-dtb.dtb
+
+  * Miscellaneous upstream changes
+    - PENDING: usb: typec: ucsi_glink: Search current directory for headers
+    - PENDING: iommu/arm-smmu-qcom: Add SA8255p SMMUv2
+    - FROMLIST: usb: misc: qcom_eud: Access mode manager through secure calls
+    - FROMLIST: arm64: dts: qcom: sc7280: Update eud compatible string
+    - PENDING: arm64: dts: qcom: sa8775p: Add EUD dt node
+    - QCLINUX: arm64: dts: qcom: Add DT configuration
+    - PENDING: phy: qcom: Add support for eDP PHY on qcs8300
+    - UPSTREAM: wifi: ath11k: fix connection failure due to unexpected peer delete
+    - PENDING: arm64: dts: qcom: sa8775p-ride: Enable gpi-dma and qup node
+    - FROMLIST: wifi: ath11k: enable fw_wmi_diag_event hw param for WCN6750
+    - PENDING: Bluetooth: mgmt: Verify cmd pending status before removing it
+    - QCLINUX: firmware: qcom_scm: Add new scm to update Camera QoS
+    - QCLINUX: arm64: defconfig: Enable usb5807 driver
+    - QCLINUX: arm64: defconfigs: Add configs for Auto targets
+    - PENDING: drm/msm/dpu: Add QCS8300 support
+    - PENDING: arm64: dts: qcom: qcs8300: Add CDSP and ADSP fastrpc nodes
+    - PENDING: net: stmmac: Add the missing programming sequence for Split header
+      feature
+    - QCLINUX: firmware: qcom_scm_addon: Fix qcom_she_op missing arginfo and res
+    - UPSTREAM: arm64: mm: Batch dsb and isb when populating pgtables
+    - UPSTREAM: arm64: mm: Don't remap pgtables for allocate vs populate
+    - PENDING: drm/msm/dp: Add DisplayPort controller for QCS8300
+    - PENDING: arm64: dts: qcom: sa8775p: Enable EUD function
+    - PENDING: arm64: dts: qcom: qcs8300: Add BWMON instances
+    - PENDING: Bluetooth: mgmt: Verify command pending status before removing it
+    - PENDING: pinctrl: qcom: Add qcs8300 lpass lpi pinctrl driver
+    - QCLINUX: ASoC: qcm6490: Add sound card support for QCS8300
+    - QCLINUX: qcom: qtee_shmbridge: Register dma bridge
+    - PENDING: drm/msm: mdss: Add QCS8300 support
+    - QCLINUX: arm64: deconfig: qcom: disable CONFIG_ARM_SCMI_CPUFREQ
+    - PENDING: net: phy: aquantia: Fix aquantia driver to support 2.5Gbps
+    - QCLINUX: arm64: defconfig: Enable LPASS LPI QCS8300 pinctrl
+    - PENDING: arm64: dts: qcom: Add on-board PMICs for qcs8300
+    - PENDING: arm64: dts: qcom: Add PMIC GPIO devices for qcs8300
+    - PENDING: arm64: dts: qcom: Add PMIC RTC device for qcs8300
+    - PENDING: arm64: dts: qcom: qcs8300-ride: Add Bluetooth support
+    - PENDING: arm64: dts: qcom: sa8775p: Enable high bandwidth for hs isoc eps
+    - PENDING: arm64: dts: qcom: sa8255p-ride: Disable USB wakeup capability
+    - PENDING: usb: dwc3: Update nominal max votes for qcom usb
+    - PENDING: tty: serial: qcom-geni-serial: Increase Rx buffer size
+    - PENDING: arm64: dts: qcom: qcs8300: add display dt nodes
+    - QCLINUX: ARM64: configs: Remove Gunyah in-tree drivers
+    - PENDING: arm64: dts: qcom: qcs8300: Add gpr device tree node for ADSP
+    - QCLINUX: arm64: dts: qcom: qcs8300: Add lpass_tlmm node for lpi pinctrl
+    - QCLINUX: arm64: dts: qcom: qcs8300: Add sound node for qcs8300 ridesx target
+    - PENDING: arm64: dts: qcom: qcs8300: Add DisplayPort device node
+    - PENDING: usb: dwc3: Reserve Higher Bandwidth for HS Periodic EPs
+    - QCLINUX: arm64: defconfig: Add configs for Gen5auto targets
+    - QCLINUX: soc: qcom: Fix showing watchdog device attr "disable"
+    - PENDING: QCLINUX: arm64: PCI: qcom: Add support for QCS8300 SoC
+    - QCLINUX: secure-buffer: Minor cleanup
+    - PENDING: phy: qcom-qmp-pcie: add dual lane PHY support for QCS8300
+    - PENDING: pinctrl: qcom: add tlmm driver for sa7255p platform
+    - QCLINUX: arm64: defconfigs: Enable SA7255P Pinctrl
+    - PENDING: ARM64: dts: qcom: Update camera PIL memory to 7MB
+    - PENDING: arm64: dts: qcom: Add dcvsh interrupts
+    - QCLINUX: arm64: dts: qcom: addons: Add TGU components
+    - PENDING: arm64: dts: qcom: Add lpass_stm device
+    - PENDING: arm64: dts: qcom: qcs8300: Add EUD dt node
+    - QCLINUX: arm64: configs: Disable the console for perf build
+    - PENDING: arm64: dts: qcom: qcs8300: enable pcie0 for QCS8300
+    - PENDING: arm64: dts: qcom: qcs8300: Correct IRQ number of EL2 non-secure
+      physical timer
+    - PENDING: QCLINUX: arm64: dts: add pmu node for WCN6855
+    - PENDING: arm64: dts: qcom: qcs8300: add Watchdog
+    - QCLINUX: dcc: Configure the correct bit for MEM_MAP_VER3
+    - QCLINUX: arm64: defconfig: Enable EFI runtime service
+    - QCLINUX: rpmsg: glink: Get reference of channel objects in rx path
+    - PENDING: arm64: dts: qcom: Add support for SA7255p Ride platform
+    - PENDING: arm64: dts: qcom: sa7255p: Add UFS node
+    - PENDING: arm64: dts: qcom: sa7255p: Add USB nodes
+    - QCLINUX: arm64: dts: qcom: Add/Modify board-id and msm-id for V1,v2 and V3
+    - PENDING: arm64: dts: qcom: add the PCIE SMMU node
+    - PENDING: arm64: dts: qcom: Add nodes for Data Capture and Compare
+    - QCLINUX: secure-buffer: Roll-back failed assigns
+    - QCLINUX: dma-heap: qcom: Reclaim pages we failed to hyp-assign
+    - QCLINUX: arm64: dts: qcom: sa8775p: add ride r3 addons dts support
+    - QCLINUX: arm64: dts: qcom: qcs9100: add addons ride dts support
+    - PENDING: pinctrl: qcom: add pdc wakeup irq map for sa7255p
+    - PENDING: slimbus: messaging: Free transaction ID in delayed interrupt
+      scenario
+    - PENDING: clk: qcom: videocc-sa8775p: Increase mvs0c divider to div-3
+    - PENDING: arm64: dts: qcom: Add support for tsens and thermal for SA7255p
+    - PENDING: net: stmmac: dwmac-qcom-ethqos: Add ethernet support for sa8620
+    - PENDING: net: stmmac: Fix SPH feature to support AV packets
+    - PENDING: arm64: dts: qcom: sa8255p: Add PCIe nodes
+    - PENDING: arm64: dts: qcom: Add PCIe SMMU node for SA7255P
+    - QCLINUX: arm64: dts: qcom: addons: Correct the dcc version
+    - QCLINUX: Revert "PENDING: net: phy: aquantia: Fix aquantia driver to
+    - QCLINUX: arm64: dts: qcom: addons: add periphid for TGU
+    - PENDING: arm64: dts: qcom: Add the Adreno SMMU node for SA7255P
+    - QCLINUX: arm64: defconfig: Enable Intel IXGBE driver
+    - PENDING: dt-bindings: arm: qcom,ids: add SoC ID for SA7255P
+    - PENDING: soc: qcom: socinfo: add support for SA7255P SoC
+    - PENDING: arm64: dts: qcom: qcs8300: enable pcie1 for QCS8300
+    - PENDING: arm64: dts: qcom: add support for ipcc
+    - PENDING: arm64: dts: qcom: Add WDT device node for SA7255
+    - PENDING: arm64: dts: qcom: sa8775p: Enable DPTX1 on MDSS0 for SA8775P target
+    - PENDING: arm64: dts: qcom: sa8775p: Enable DPTX1 on MDSS0 for SA8775P target
+    - QCLINUX: arm64: deconfig: enable dm-verity configs
+    - QCLINUX: arm64: deconfig: qcom: disable SOC_DEBUG CONFIG
+    - QCLINUX: arm64: dts: qcom: qcs6490-addons-rb3gen2: Enable camera subsystem
+    - FROMLIST: arm64: dts: qcom: Disable TPDM_GCC for QCS8300
+    - QCLINUX: arm64: defconfig: Enable Aquantia Phy
+    - PENDING: arm64: dts: qcom: sc7280: Update camss driver properties
+    - QCLINUX: usb: dwc3: qcom: Add shutdown callback for qcom wrapper
+    - QCLINUX: drivers: thermal: Add dummy set hysteresis operation for all
+      sensors
+    - PENDING: arm64: dts: qcom: sa7255p: Enable i2c15 for audio
+    - QCLINUX: arm64: deconfig: qcom: enable IOMMU_DEFAULT_DMA_LAZY
+    - PENDING: arm64: dts: qcom: qcs8300: update videocc compatible
+    - PENDING: arm64: dts: qcom: qcs8300: add rdbg nodes
+    - PENDING: arm64: dts: qcom: qcs8300: add TRNG node
+    - QCLINUX: arm64: dts: qcom: Add msm-id/board-id for SA7255P
+    - PENDING: arm64: dts: qcom: sa8775p: Define interconnect bandwidth value in
+      dtsi
+    - PENDING: arm64: qcom: dts: Add psci sys_reset2 modes for SA8255P & SA7255P
+    - PENDING: Bluetooth: Increase settling time for baudrate change VSC
+    - QCLINUX: arm64: dts: qcom: Enable TPM device
+    - PENDING: arm64: dts: qcom: qcs8300: add ICE node
+    - BACKPORT: Bluetooth: MGMT: Fix possible crash on mgmt_index_removed
+    - QCLINUX: arm64: dts: qcom: qcs6490-rb3gen2: Move the msm-id and board-id
+    - QCLINUX: arm64: defconfigs: Add configs for Auto targets
+    - FROMLIST: wifi: ath11k: Fix unexpected return buffer manager error for
+      WCN6750/WCN6855
+    - PENDING: soc: qcom: qup_fw: QUP SE Firmware load from Linux
+    - FROMLIST: arm64: dts: qcom: qcs8300: Add PMU support for QCS8300
+    - BACKPORT: FROMLIST: io_uring: Do not set iowait before sleeping
+    - PENDING: dt-bindings: arm: qcom,ids: add SoC ID for SA8797P
+    - PENDING: soc: qcom: socinfo: add support for SA8797P SoC
+    - PENDING: arm64: dts: qcom: qcs8300: Add tz-log node
+    - QCLINUX: arm64: dts: qcom: qcs8300: add dcodec and macro clk
+    - QCLINUX: ASoC: qcm6490: Add AIF3 and AIF4 for qcs8300
+    - PENDING: arm64: dts: qcom: qcs8300: Add spi dev node for qcs8300 ridesx
+      target
+    - PENDING: arm64: dts: qcom: qcs8300: Enable i2c15 node for qcs8300 ridesx
+      target
+    - QCLINUX: arm64: dts: qcom: qcs8300: Enable HS MI2S
+    - PENDING: arm64: dts: qcom: qcs8300: Add shmbridge and smcinvoke nodes
+    - PENDING: arm64: dts: qcom: qcs8300-addons: Add CMA heap
+    - PENDING: drivers: char: fix rdbg driver init sequence
+    - PENDING: arm64: dts: qcom: qcs8300: add QCrypto nodes
+    - QCLINUX: arm64: dts: qcom: addons: Enable mem-buf and secure-buffer for
+      qcs8300
+    - PENDING: clk: qcom: common: Add support to attach multiple power domains
+    - PENDING: clk: qcom: gdsc: Add support to link multiple PDs as GDSC parents
+    - PENDING: clk: qcom: camcc-sa8775p: Add support to attach multiple pds
+    - PENDING: arm64: dts: qcom: Add MXC power domain to camcc node on SA8775P
+    - PENDING: arm64: qcom: dts: qcs8300: Add psci sys_reset2 modes
+    - FROMLIST: dt-bindings: arm: qcom,ids: add SoC ID for QCS9075
+    - FROMLIST: soc: qcom: socinfo: add QCS9075 SoC ID
+    - FROMLIST: arm64: dts: qcom: Add support for QCS9075 RB8
+    - FROMLIST: arm64: dts: qcom: Add support for QCS9075 Ride & Ride-r3
+    - QCLINUX: arm64: dts: qcom: Add msm-id & board-id for qcs9075-rb8
+    - QCLINUX: arm64: dts: qcom: qcs9075: Add msm-id & board-id for ride/ride-r3
+    - PENDING: ARM: dts: qcom: Add ADC thermistor support for SA8775P
+    - PENDING: arm64: dts: qcom: qcs8300: Add adsp memory-region and vmids
+    - PENDING: arm64: dts: qcom: qcs9075-rb8: Add support for remoteproc instances
+    - PENDING: arm64: dts: qcom: qcs9075-rb8: Enable llcc node
+    - FROMLIST: net: stmmac: Add snps_id, dev_id to struct plat_stmmacenet_data
+    - FROMLIST: net: stmmac: Integrate dw25gmac into stmmac hwif handling
+    - QCLINUX:arm64:defconfigs: Enable NO_HZ_FULL for better rcu performance
+    - PENDING: serial: qcom-geni: Support of uart firmware load from Linux
+    - PENDING: spi: geni-qcom: Load spi Firmware from driver probe
+    - PENDING: i2c: qcom-geni: Load i2c Firmware from driver probe
+    - PENDING: arm64: dts: qcom: Disable USB U1/U2 entry for QCS9100/QCS8300
+    - FROMLIST: net: stmmac: Add basic dw25gmac support in stmmac core
+    - QCLINUX: arm64: dts: qcom: qcs9100: Enable DISPLAY-PORT
+    - PENDING: misc: fastrpc: Add support for invoke v2
+    - PENDING: wifi: ath11k: fix wrong overriding for VHT Beamformee STS
+      Capability
+    - QCLINUX: arm64: dts: qcom: Add QPS615 and PHY devicetree config for RC0 for
+      RB3Gen2 ia-mezz
+    - QCLINUX: arm64: dts: qcom: Add support for Eth0 and Eth1 on QPS615 for
+      RB3Gen2 ia-mezz
+    - QCLINUX: arm64: dts: qcom: Add QPS615 and PHY devicestree config for RC1 for
+      RB3gen2 IPC board
+    - QCLINUX: arm64: dts: qcom: Add QPS615 Ethernet support for RC1 for RB3gen2
+      IPC board
+    - PENDING: ARM: dts: qcom: Add support for PMIC peripherals for qcs8300
+    - PENDING: arm64: dts: qcom: sa8775p: Add dma heap for cdsp_secure_heap_mem
+    - PENDING: spi: spi-geni-qcom: Add immediate DMA support
+    - PENDING: arm64: dts: qcom: qcs8300: Add dma heap for cdsp_secure_heap_mem
+    - QCLINUX: ASoC: qcs9100: add HDMI/DP Jack
+    - QCLINUX: arm64: dts: qcom: qcs6490-rb3gen2: disable camss driver
+    - PENDING: net: stmmac: pass stmmac_priv in some callbacks
+    - FROMLIST: arm64: dts: qcom: sa8775p: Update iommu-map entry
+    - PENDING: Bluetooth: clear cmd_sync_work_list when power off
+    - QCLINUX: dma-heap: qcom: Snapshot of dma-buf-carveout-heap
+    - PENDING: clk: qcom: Add support for qdss_xo clock for QCS8300
+    - PENDING: arm64: dts: qcom: Fix dr_mode for secondary port
+    - PENDING: arm64: qcs9075-rb8: Enable PCIe0 & PCIe1 nodes
+    - BACKPORT: PCI: Add ACS quirk for Qualcomm SA8775P
+    - PENDING: Bluetooth: hci_sync: Fix disconnect complete event timeout issue
+    - PENDING: arm64: dts: qcom: qcs8300: Delete duplicate cdsp fastrpc nodes
+    - BACKPORT: PCI: qcom-ep: Add HDMA support for SA8775P SoC
+    - QCLINUX: arm64: defconfigs: convert usb configs to module
+    - PENDING: arm64: dts: qcom: sa8775p: Define interconnect bandwidth value in
+      dtsi
+    - PENDING: arm64: dts: qcom: Enable cpu idle injection for cpu tsens for
+      qcs9100
+    - PENDING: pinctrl: sa8775p: Enable egpio function for pingroups
+    - PENDING: arm64: dts: qcom: Memory map for qcs8300 v1 approved
+    - PENDING: arm-smmu-qcom: program actlr earlier in init to include GPU and GMU
+    - QCLINUX: arm64: defconfig: qcom: Enable EMC2305 Sensor driver
+    - QCLINUX: arm64: dts: qcom: qcs9075: Add support for rb8 addons
+    - QCLINUX: arm64: dts: qcom: qcs9075: Add support for ride/ride-r3 addons
+    - PENDING: arm64: dts: qcom: Add wlan support for qcs9075-rb8
+    - PENDING: arm64: qcs9075-rb8: Config BT bootstrap pin in DTS
+    - FROMLIST: qcom: llcc/edac: Correct interrupt enable register configuration
+    - PENDING: arm64: dts: qcom: Enable cpu idle injection for cpu tsens for
+      qcs9075
+    - QCLINUX: arm64: dts: qcom: Fix dr_mode for non-primary ports
+    - QCLINUX: arm64: dts: qcom: qcs6490-rb3gen2: disable camss driver
+    - BACKPORT: PCI: epf-mhi: Add "pci_epf_mhi_" prefix to the function names
+    - QCLINUX: rpmsg: Align channel objects reference in rx path
+    - QCLINUX: arm64: dts: qcom: qcs6490-addons-rb3gen2: Enable camera subsystem"
+    - PENDING: qcom: ice: Remove ice probe
+    - PENDING: arm64: dts: qcom: qcs9100-rb8: QUP Firmware load from Linux
+    - QCLINUX: arm64: dts: qcom: Enable usb controller on QCS9075 RB8
+    - QCLINUX: arm64: dts: qcom: qcs9075: Add UFS support for QCS9075 RB8
+    - PENDING: arm64: dts: qcom: qcs9075: Add displayport device node
+    - QCLINUX: arm64: dts: qcom: add audio support for qcs9075-rb8
+    - QCLINUX: ASoC: qcm6490: Add support for QCS9075 RB8
+    - QCLINUX: clk: qcom: videocc-sa8775: disable HW CTRL for video GDSC
+    - PENDING: arm64: dts: qcom: update power-domain for display-controller
+    - PENDING: hwmon: Add I2C detection and initialization for EMC2303
+    - BACKPORT: FROMLIST: arm64: dts: qcom: qcs9100: Update memory map  for
+      QCS9100 Ride and QCS9100 Ride Rev3
+    - FROMLIST: usb: misc: usb5807: Add driver
+    - PENDING: USB: Adapt USB5807 driver for IPC hardware design
+    - PENDING: wifi: ath11k: add support for MU EDCA
+    - PENDING: ARM: dts: qcom: Update thermal zone names for qcs8300
+    - PENDING: pinctrl: qcs8300: Update function and group binding
+    - QCLINUX: drm/msm: Avoid probing gpu device
+    - QCLINUX: arm64: dts: qcom: qcs6490-rb3gen2: enable camera sensor
+    - PENDING: arm64: dts: qcom: qcs8300: Add capacity and DPC properties
+    - Revert: ICE eMMC and probe
+    - QCLINUX: arm64: defconfig: Enable GPUCC SA8775P driver as static module
+    - Ubuntu: [Config] update CONFIG options for GA 1.3
+    - Ubuntu: [Config] change CONFIG_USB_DWC3 to y
+    - Ubuntu: [Config] change CONFIG_SENSORS_EMC2305 to y
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 22 Jan 2025 07:54:04 +0900
+
+linux-qcom (6.8.0-1018.18) jammy; urgency=medium
+
+  * "[Canonical][RB3] [ftmdaemon] WlanSetPhyRFMode fail by ftmdaemon tool"
+    - [Config] Enable CONFIG_NL80211_TESTMODE
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 19 Dec 2024 21:02:17 +0900
+
+linux-qcom (6.8.0-1017.17) jammy; urgency=medium
+
+  * Miscellaneous upstream changes
+    - scsi: ufs: qcom: revive the enabled check in ufs_qcom_host_clk_get()
+    - Revert "usb: typec: fsa4480: Relax CHIP_ID check"
+    - Revert "usb: typec: fsa4480: Check if the chip is really there"
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Tue, 17 Dec 2024 04:05:48 +0900
+
+linux-qcom (6.8.0-1016.16) jammy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Add Makefile code to apply qcs5430 overlays for GA1.2
+
+  * Miscellaneous upstream changes
+    - msm: camera: isp: Fix warnings
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Tue, 10 Dec 2024 15:45:41 +0900
+
+linux-qcom (6.8.0-1015.15) jammy; urgency=medium
+
+  * Noble update: upstream stable patchset 2024-10-02 (LP: #2083488)
+    - [Config] Update CONFIG_SCREEN_INFO
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+
+  * [RB3] CONFIG_KASAN_GENERIC report potential memory bug in tc956x_pcie_eth
+    - SAUCE: ubuntu/qcom/qps615: suppress KASAN error
+
+  * Miscellaneous Ubuntu changes
+    - [Config] set CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND
+
+  [ Ubuntu: 6.8.0-50.51 ]
+
+  * noble/linux: 6.8.0-50.51 -proposed tracker (LP: #2086301)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2024.10.28)
+  * Noble update: upstream stable patchset 2024-10-31 (LP: #2086138)
+    - device property: Add cleanup.h based fwnode_handle_put() scope based
+      cleanup.
+    - device property: Introduce device_for_each_child_node_scoped()
+    - iio: adc: ad7124: Switch from of specific to fwnode based property handling
+    - ksmbd: override fsids for share path check
+    - ksmbd: override fsids for smb2_query_info()
+    - usbnet: ipheth: remove extraneous rx URB length check
+    - usbnet: ipheth: drop RX URBs with no payload
+    - usbnet: ipheth: do not stop RX on failing RX callback
+    - usbnet: ipheth: fix carrier detection in modes 1 and 4
+    - net: ethernet: use ip_hdrlen() instead of bit shift
+    - drm: panel-orientation-quirks: Add quirk for Ayn Loki Zero
+    - drm: panel-orientation-quirks: Add quirk for Ayn Loki Max
+    - net: phy: vitesse: repair vsc73xx autonegotiation
+    - powerpc/mm: Fix boot warning with hugepages and CONFIG_DEBUG_VIRTUAL
+    - wifi: mt76: mt7921: fix NULL pointer access in mt7921_ipv6_addr_change
+    - net: hns3: use correct release function during uninitialization
+    - btrfs: update target inode's ctime on unlink
+    - Input: ads7846 - ratelimit the spi_sync error message
+    - Input: synaptics - enable SMBus for HP Elitebook 840 G2
+    - HID: multitouch: Add support for GT7868Q
+    - scripts: kconfig: merge_config: config files: add a trailing newline
+    - platform/surface: aggregator_registry: Add Support for Surface Pro 10
+    - platform/surface: aggregator_registry: Add support for Surface Laptop Go 3
+    - drm/msm/adreno: Fix error return if missing firmware-name
+    - Input: i8042 - add Fujitsu Lifebook E756 to i8042 quirk table
+    - smb/server: fix return value of smb2_open()
+    - NFSv4: Fix clearing of layout segments in layoutreturn
+    - NFS: Avoid unnecessary rescanning of the per-server delegation list
+    - platform/x86: panasonic-laptop: Fix SINF array out of bounds accesses
+    - platform/x86: panasonic-laptop: Allocate 1 entry extra in the sinf array
+    - mptcp: pm: Fix uaf in __timer_delete_sync
+    - arm64: dts: rockchip: fix eMMC/SPI corruption when audio has been used on
+      RK3399 Puma
+    - arm64: dts: rockchip: override BIOS_DISABLE signal via GPIO hog on RK3399
+      Puma
+    - minmax: reduce min/max macro expansion in atomisp driver
+    - net: tighten bad gso csum offset check in virtio_net_hdr
+    - dm-integrity: fix a race condition when accessing recalc_sector
+    - x86/hyperv: fix kexec crash due to VP assist page corruption
+    - mm: avoid leaving partial pfn mappings around in error case
+    - arm64: dts: rockchip: fix PMIC interrupt pin in pinctrl for ROCK Pi E
+    - drm/amd/display: Disable error correction if it's not supported
+    - drm/amd/display: Fix FEC_READY write on DP LT
+    - eeprom: digsy_mtc: Fix 93xx46 driver probe failure
+    - cxl/core: Fix incorrect vendor debug UUID define
+    - selftests/bpf: Support SOCK_STREAM in unix_inet_redir_to_connected()
+    - hwmon: (pmbus) Conditionally clear individual status bits for pmbus rev >=
+      1.2
+    - ice: Fix lldp packets dropping after changing the number of channels
+    - ice: fix accounting for filters shared by multiple VSIs
+    - ice: fix VSI lists confusion when adding VLANs
+    - igb: Always call igb_xdp_ring_update_tail() under Tx lock
+    - net/mlx5: Update the list of the PCI supported devices
+    - net/mlx5e: Add missing link modes to ptys2ethtool_map
+    - net/mlx5e: Add missing link mode to ptys2ext_ethtool_map
+    - net/mlx5: Explicitly set scheduling element and TSAR type
+    - net/mlx5: Add missing masks and QoS bit masks for scheduling elements
+    - net/mlx5: Correct TASR typo into TSAR
+    - net/mlx5: Verify support for scheduling element and TSAR type
+    - net/mlx5: Fix bridge mode operations when there are no VFs
+    - fou: fix initialization of grc
+    - octeontx2-af: Modify SMQ flush sequence to drop packets
+    - net: ftgmac100: Enable TX interrupt to avoid TX timeout
+    - selftests: net: csum: Fix checksums for packets with non-zero padding
+    - netfilter: nft_socket: fix sk refcount leaks
+    - net: dsa: felix: ignore pending status of TAS module when it's disabled
+    - net: dpaa: Pad packets to ETH_ZLEN
+    - tracing/osnoise: Fix build when timerlat is not enabled
+    - spi: nxp-fspi: fix the KASAN report out-of-bounds bug
+    - drm/syncobj: Fix syncobj leak in drm_syncobj_eventfd_ioctl
+    - dma-buf: heaps: Fix off-by-one in CMA heap fault handler
+    - drm/nouveau/fb: restore init() for ramgp102
+    - drm/amdgpu/atomfirmware: Silence UBSAN warning
+    - drm/amd/amdgpu: apply command submission parser for JPEG v1
+    - spi: geni-qcom: Undo runtime PM changes at driver exit time
+    - spi: geni-qcom: Fix incorrect free_irq() sequence
+    - drm/i915/guc: prevent a possible int overflow in wq offsets
+    - ASoC: codecs: avoid possible garbage value in peb2466_reg_read()
+    - cifs: Fix signature miscalculation
+    - pinctrl: meteorlake: Add Arrow Lake-H/U ACPI ID
+    - ASoC: meson: axg-card: fix 'use-after-free'
+    - drm/mediatek: Set sensible cursor width/height values to fix crash
+    - Input: edt-ft5x06 - add support for FocalTech FT5452 and FT8719
+    - Input: edt-ft5x06 - add support for FocalTech FT8201
+    - cgroup/cpuset: Eliminate unncessary sched domains rebuilds in hotplug
+    - spi: zynqmp-gqspi: Scale timeout by data size
+    - drm/xe: use devm instead of drmm for managed bo
+    - net: libwx: fix number of Rx and Tx descriptors
+    - clocksource: hyper-v: Use lapic timer in a TDX VM without paravisor
+    - bcachefs: Fix bch2_extents_match() false positive
+    - bcachefs: Don't delete open files in online fsck
+    - firmware: qcom: uefisecapp: Fix deadlock in qcuefi_acquire()
+    - riscv: dts: starfive: jh7110-common: Fix lower rate of CPUfreq by setting
+      PLL0 rate to 1.5GHz
+    - cxl: Restore XOR'd position bits during address translation
+    - netlink: specs: mptcp: fix port endianness
+    - drm/amd/display: Avoid race between dcn10_set_drr() and dc_state_destruct()
+    - drm/amd/display: Avoid race between dcn35_set_drr() and dc_state_destruct()
+    - drm/amd/amdgpu: apply command submission parser for JPEG v2+
+    - drm/xe/client: fix deadlock in show_meminfo()
+    - drm/xe/client: remove bogus rcu list usage
+    - drm/xe/client: add missing bo locking in show_meminfo()
+    - tracing/kprobes: Fix build error when find_module() is not available
+    - drm/xe/display: fix compat IS_DISPLAY_STEP() range end
+    - Upstream stable to v6.6.52, v6.10.11
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849)
+    - KVM: SVM: fix emulation of msr reads/writes of MSR_FS_BASE and MSR_GS_BASE
+    - KVM: SVM: Don't advertise Bus Lock Detect to guest if SVM support is missing
+    - ALSA: hda/conexant: Add pincfg quirk to enable top speakers on Sirius
+      devices
+    - ALSA: hda/realtek: add patch for internal mic in Lenovo V145
+    - ALSA: hda/realtek: Support mute LED on HP Laptop 14-dq2xxx
+    - ksmbd: Unlock on in ksmbd_tcp_set_interfaces()
+    - ata: libata: Fix memory leak for error path in ata_host_alloc()
+    - irqchip/gic-v2m: Fix refcount leak in gicv2m_of_init()
+    - x86/kaslr: Expose and use the end of the physical memory address space
+    - nvme-pci: Add sleep quirk for Samsung 990 Evo
+    - rust: types: Make Opaque::get const
+    - rust: macros: provide correct provenance when constructing THIS_MODULE
+    - Revert "Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE"
+    - Bluetooth: MGMT: Ignore keys being loaded with invalid type
+    - mmc: core: apply SD quirks earlier during probe
+    - mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K
+    - mmc: sdhci-of-aspeed: fix module autoloading
+    - mmc: cqhci: Fix checking of CQHCI_HALT state
+    - fuse: update stats for pages in dropped aux writeback list
+    - fuse: use unsigned type for getxattr/listxattr size truncation
+    - fuse: fix memory leak in fuse_create_open
+    - clk: starfive: jh7110-sys: Add notifier for PLL0 clock
+    - clk: qcom: clk-alpha-pll: Fix the pll post div mask
+    - clk: qcom: clk-alpha-pll: Fix the trion pll postdiv set rate API
+    - kexec_file: fix elfcorehdr digest exclusion when CONFIG_CRASH_HOTPLUG=y
+    - tracing: Avoid possible softlockup in tracing_iter_reset()
+    - tracing/timerlat: Add interface_lock around clearing of kthread in
+      stop_kthread()
+    - net: mctp-serial: Fix missing escapes on transmit
+    - x86/fpu: Avoid writing LBR bit to IA32_XSS unless supported
+    - x86/apic: Make x2apic_disable() work correctly
+    - drm/i915: Do not attempt to load the GSC multiple times
+    - ALSA: control: Apply sanity check of input values for user elements
+    - ALSA: hda: Add input value sanity checks to HDMI channel map controls
+    - wifi: ath12k: fix uninitialize symbol error on ath12k_peer_assoc_h_he()
+    - smack: unix sockets: fix accept()ed socket label
+    - bpf, verifier: Correct tail_call_reachable for bpf prog
+    - accel/habanalabs/gaudi2: unsecure edma max outstanding register
+    - irqchip/armada-370-xp: Do not allow mapping IRQ 0 and 1
+    - af_unix: Remove put_pid()/put_cred() in copy_peercred().
+    - x86/kmsan: Fix hook for unaligned accesses
+    - iommu: sun50i: clear bypass register
+    - netfilter: nf_conncount: fix wrong variable type
+    - fs/ntfs3: One more reason to mark inode bad
+    - riscv: kprobes: Use patch_text_nosync() for insn slots
+    - media: vivid: fix wrong sizeimage value for mplane
+    - leds: spi-byte: Call of_node_put() on error path
+    - wifi: brcmsmac: advertise MFP_CAPABLE to enable WPA3
+    - usb: uas: set host status byte on data completion error
+    - drm/amd/display: Check HDCP returned status
+    - drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts
+    - media: vivid: don't set HDMI TX controls if there are no HDMI outputs
+    - vfio/spapr: Always clear TCEs before unsetting the window
+    - ice: Check all ice_vsi_rebuild() errors in function
+    - Input: ili210x - use kvmalloc() to allocate buffer for firmware update
+    - media: qcom: camss: Add check for v4l2_fwnode_endpoint_parse
+    - pcmcia: Use resource_size function on resource object
+    - drm/amdgpu: check for LINEAR_ALIGNED correctly in check_tiling_flags_gfx6
+    - can: m_can: Release irq on error in m_can_open
+    - can: mcp251xfd: fix ring configuration when switching from CAN-CC to CAN-FD
+      mode
+    - rust: kbuild: fix export of bss symbols
+    - cifs: Fix FALLOC_FL_ZERO_RANGE to preflush buffered part of target region
+    - igb: Fix not clearing TimeSync interrupts for 82580
+    - platform/x86: dell-smbios: Fix error path in dell_smbios_init()
+    - regulator: core: Stub devm_regulator_bulk_get_const() if !CONFIG_REGULATOR
+    - can: kvaser_pciefd: Skip redundant NULL pointer check in ISR
+    - can: kvaser_pciefd: Remove unnecessary comment
+    - can: kvaser_pciefd: Rename board_irq to pci_irq
+    - can: kvaser_pciefd: Move reset of DMA RX buffers to the end of the ISR
+    - can: kvaser_pciefd: Use a single write when releasing RX buffers
+    - Bluetooth: qca: If memdump doesn't work, re-enable IBS
+    - Bluetooth: hci_sync: Introduce hci_cmd_sync_run/hci_cmd_sync_run_once
+    - Bluetooth: MGMT: Fix not generating command complete for MGMT_OP_DISCONNECT
+    - igc: Unlock on error in igc_io_resume()
+    - ice: do not bring the VSI up, if it was down before the XDP setup
+    - usbnet: modern method to get random MAC
+    - bpf, net: Fix a potential race in do_sock_getsockopt()
+    - bareudp: Fix device stats updates.
+    - r8152: fix the firmware doesn't work
+    - net: bridge: br_fdb_external_learn_add(): always set EXT_LEARN
+    - net: dsa: vsc73xx: fix possible subblocks range of CAPT block
+    - selftests: net: enable bind tests
+    - firmware: cs_dsp: Don't allow writes to read-only controls
+    - phy: zynqmp: Take the phy mutex in xlate
+    - ASoC: topology: Properly initialize soc_enum values
+    - dm init: Handle minors larger than 255
+    - iommu/vt-d: Handle volatile descriptor status read
+    - cgroup: Protect css->cgroup write under css_set_lock
+    - devres: Initialize an uninitialized struct member
+    - virtio_ring: fix KMSAN error for premapped mode
+    - crypto: qat - fix unintentional re-enabling of error interrupts
+    - ASoc: TAS2781: replace beXX_to_cpup with get_unaligned_beXX for potentially
+      broken alignment
+    - libbpf: Add NULL checks to bpf_object__{prev_map,next_map}
+    - drm/amdgpu: Set no_hw_access when VF request full GPU fails
+    - ext4: fix possible tid_t sequence overflows
+    - jbd2: avoid mount failed when commit block is partial submitted
+    - dma-mapping: benchmark: Don't starve others when doing the test
+    - drm/amdgpu: reject gang submit on reserved VMIDs
+    - smp: Add missing destroy_work_on_stack() call in smp_call_on_cpu()
+    - fs/ntfs3: Check more cases when directory is corrupted
+    - btrfs: replace BUG_ON with ASSERT in walk_down_proc()
+    - cxl/region: Verify target positions using the ordered target list
+    - riscv: set trap vector earlier
+    - tcp: Don't drop SYN+ACK for simultaneous connect().
+    - net: dpaa: avoid on-stack arrays of NR_CPUS elements
+    - LoongArch: Use correct API to map cmdline in relocate_kernel()
+    - regmap: maple: work around gcc-14.1 false-positive warning
+    - vfs: Fix potential circular locking through setxattr() and removexattr()
+    - i3c: master: svc: resend target address when get NACK
+    - kselftests: dmabuf-heaps: Ensure the driver name is null-terminated
+    - btrfs: initialize location to fix -Wmaybe-uninitialized in
+      btrfs_lookup_dentry()
+    - s390/vmlinux.lds.S: Move ro_after_init section behind rodata section
+    - usbnet: ipheth: race between ipheth_close and error handling
+    - spi: spi-fsl-lpspi: limit PRESCALE bit in TCR register
+    - ata: pata_macio: Use WARN instead of BUG
+    - NFSv4: Add missing rescheduling points in
+      nfs_client_return_marked_delegations
+    - ACPI: CPPC: Add helper to get the highest performance value
+    - cpufreq: amd-pstate: Enable amd-pstate preferred core support
+    - cpufreq: amd-pstate: fix the highest frequency issue which limits
+      performance
+    - tcp: process the 3rd ACK with sk_socket for TFO/MPTCP
+    - iio: buffer-dmaengine: fix releasing dma channel on error
+    - iio: fix scale application in iio_convert_raw_to_processed_unlocked
+    - iio: adc: ad7124: fix config comparison
+    - iio: adc: ad7606: remove frstdata check for serial mode
+    - iio: adc: ad7124: fix chip ID mismatch
+    - usb: dwc3: core: update LC timer as per USB Spec V3.2
+    - usb: cdns2: Fix controller reset issue
+    - usb: dwc3: Avoid waking up gadget during startxfer
+    - nvmem: Fix return type of devm_nvmem_device_get() in kerneldoc
+    - Drivers: hv: vmbus: Fix rescind handling in uio_hv_generic
+    - clocksource/drivers/imx-tpm: Fix return -ETIME when delta exceeds INT_MAX
+    - clocksource/drivers/imx-tpm: Fix next event not taking effect sometime
+    - clocksource/drivers/timer-of: Remove percpu irq related code
+    - uprobes: Use kzalloc to allocate xol area
+    - Revert "mm: skip CMA pages when they are not available"
+    - workqueue: wq_watchdog_touch is always called with valid CPU
+    - workqueue: Improve scalability of workqueue watchdog touch
+    - ACPI: processor: Return an error if acpi_processor_get_info() fails in
+      processor_add()
+    - ACPI: processor: Fix memory leaks in error paths of processor_add()
+    - arm64: acpi: Move get_cpu_for_acpi_id() to a header
+    - can: mcp251xfd: mcp251xfd_handle_rxif_ring_uinc(): factor out in separate
+      function
+    - can: mcp251xfd: rx: prepare to workaround broken RX FIFO head index erratum
+    - can: mcp251xfd: clarify the meaning of timestamp
+    - can: mcp251xfd: rx: add workaround for erratum DS80000789E 6 of mcp2518fd
+    - drm/amd: Add gfx12 swizzle mode defs
+    - drm/amdgpu: handle gfx12 in amdgpu_display_verify_sizes
+    - ata: libata-scsi: Remove redundant sense_buffer memsets
+    - ata: libata-scsi: Check ATA_QCFLAG_RTF_FILLED before using result_tf
+    - crypto: starfive - Align rsa input data to 32-bit
+    - crypto: starfive - Fix nent assignment in rsa dec
+    - clk: qcom: ipq9574: Update the alpha PLL type for GPLLs
+    - powerpc/64e: remove unused IBM HTW code
+    - powerpc/64e: split out nohash Book3E 64-bit code
+    - powerpc/64e: Define mmu_pte_psize static
+    - powerpc/vdso: Don't discard rela sections
+    - ASoC: tegra: Fix CBB error during probe()
+    - nvme-pci: allocate tagset on reset if necessary
+    - ASoc: SOF: topology: Clear SOF link platform name upon unload
+    - ASoC: sunxi: sun4i-i2s: fix LRCLK polarity in i2s mode
+    - clk: qcom: gcc-sm8550: Don't use parking clk_ops for QUPs
+    - clk: qcom: gcc-sm8550: Don't park the USB RCG at registration time
+    - drm/i915/fence: Mark debug_fence_init_onstack() with __maybe_unused
+    - drm/i915/fence: Mark debug_fence_free() with __maybe_unused
+    - gpio: rockchip: fix OF node leak in probe()
+    - gpio: modepin: Enable module autoloading
+    - riscv: Fix toolchain vector detection
+    - riscv: Do not restrict memory size because of linear mapping on nommu
+    - membarrier: riscv: Add full memory barrier in switch_mm()
+    - [Config] updateconfigs for ARCH_HAS_MEMBARRIER_CALLBACKS
+    - x86/mm: Fix PTI for i386 some more
+    - btrfs: fix race between direct IO write and fsync when using same fd
+    - spi: spi-fsl-lpspi: Fix off-by-one in prescale max
+    - ALSA: hda/realtek: Enable Mute Led for HP Victus 15-fb1xxx
+    - ALSA: hda/realtek - Fix inactive headset mic jack for ASUS Vivobook 15
+      X1504VAP
+    - fuse: clear PG_uptodate when using a stolen page
+    - riscv: misaligned: remove CONFIG_RISCV_M_MODE specific code
+    - parisc: Delay write-protection until mark_rodata_ro() call
+    - pinctrl: qcom: x1e80100: Bypass PDC wakeup parent for now
+    - maple_tree: remove rcu_read_lock() from mt_validate()
+    - Revert "wifi: ath11k: restore country code during resume"
+    - btrfs: qgroup: don't use extent changeset when not needed
+    - btrfs: zoned: handle broken write pointer on zones
+    - drm/xe/gsc: Do not attempt to load the GSC multiple times
+    - drm/amdgpu: always allocate cleared VRAM for GEM allocations
+    - drm/amd/display: Lock DC and exit IPS when changing backlight
+    - ALSA: hda/realtek: extend quirks for Clevo V5[46]0
+    - cgroup/cpuset: Delay setting of CS_CPU_EXCLUSIVE until valid partition
+    - virt: sev-guest: Mark driver struct with __refdata to prevent section
+      mismatch
+    - media: b2c2: flexcop-usb: fix flexcop_usb_memory_req
+    - gve: Add adminq mutex lock
+    - wifi: rtw89: wow: prevent to send unexpected H2C during download Firmware
+    - drm/amdgpu: add missing error handling in function
+      amdgpu_gmc_flush_gpu_tlb_pasid
+    - crypto: qat - initialize user_input.lock for rate_limiting
+    - locking: Add rwsem_assert_held() and rwsem_assert_held_write()
+    - fs: don't copy to userspace under namespace semaphore
+    - fs: relax permissions for statmount()
+    - seccomp: release task filters when the task exits
+    - drm/amdgpu/display: handle gfx12 in amdgpu_dm_plane_format_mod_supported
+    - can: m_can: Remove m_can_rx_peripheral indirection
+    - can: m_can: Do not cancel timer from within timer
+    - mm: Provide a means of invalidation without using launder_folio
+    - cifs: Fix copy offload to flush destination region
+    - hwmon: ltc2991: fix register bits defines
+    - scripts: fix gfp-translate after ___GFP_*_BITS conversion to an enum
+    - ptp: ocp: convert serial ports to array
+    - ptp: ocp: adjust sysfs entries to expose tty information
+    - ice: check ICE_VSI_DOWN under rtnl_lock when preparing for reset
+    - ice: remove ICE_CFG_BUSY locking from AF_XDP code
+    - net: xilinx: axienet: Fix race in axienet_stop
+    - iommu/vt-d: Remove control over Execute-Requested requests
+    - block: don't call bio_uninit from bio_endio
+    - tracing/kprobes: Add symbol counting check when module loads
+    - perf/x86/intel: Hide Topdown metrics events if the feature is not enumerated
+    - PCI: qcom: Override NO_SNOOP attribute for SA8775P RC
+    - staging: vchiq_core: Bubble up wait_event_interruptible() return value
+    - watchdog: imx7ulp_wdt: keep already running watchdog enabled
+    - btrfs: slightly loosen the requirement for qgroup removal
+    - drm/amdgpu: add PSP RAS address query command
+    - drm/amdgpu: add mutex to protect ras shared memory
+    - s390/boot: Do not assume the decompressor range is reserved
+    - drm/amdgpu: Fix two reset triggered in a row
+    - drm/amdgpu: Add reset_context flag for host FLR
+    - drm/amdgpu: Fix amdgpu_device_reset_sriov retry logic
+    - fs: only copy to userspace on success in listmount()
+    - iio: adc: ad7124: fix DT configuration parsing
+    - nvmem: u-boot-env: error if NVMEM device is too small
+    - mm: zswap: rename is_zswap_enabled() to zswap_is_enabled()
+    - mm/memcontrol: respect zswap.writeback setting from parent cg too
+    - path: add cleanup helper
+    - fs: simplify error handling
+    - fs: relax permissions for listmount()
+    - hid: bpf: add BPF_JIT dependency
+    - net/mlx5e: SHAMPO, Use KSMs instead of KLMs
+    - net/mlx5e: SHAMPO, Fix page leak
+    - drm/xe/xe2: Add workaround 14021402888
+    - drm/xe/xe2lpg: Extend workaround 14021402888
+    - clk: qcom: gcc-x1e80100: Fix USB 0 and 1 PHY GDSC pwrsts flags
+    - clk: qcom: gcc-x1e80100: Don't use parking clk_ops for QUPs
+    - nouveau: fix the fwsec sb verification register.
+    - riscv: Add tracepoints for SBI calls and returns
+    - riscv: Improve sbi_ecall() code generation by reordering arguments
+    - riscv: Fix RISCV_ALTERNATIVE_EARLY
+    - cifs: Fix zero_point init on inode initialisation
+    - nvme: rename nvme_sc_to_pr_err to nvme_status_to_pr_err
+    - nvme: fix status magic numbers
+    - nvme: rename CDR/MORE/DNR to NVME_STATUS_*
+    - nvmet: Identify-Active Namespace ID List command should reject invalid nsid
+    - drm/i915/display: Add mechanism to use sink model when applying quirk
+    - drm/i915/display: Increase Fast Wake Sync length as a quirk
+    - LoongArch: Use accessors to page table entries instead of direct dereference
+    - Upstream stable to v6.6.51, v6.10.10
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46823
+    - kunit/overflow: Fix UB in overflow_allocation_test
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46834
+    - ethtool: fail closed if we can't get max channel used in indirection tables
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46751
+    - btrfs: don't BUG_ON() when 0 reference count at btrfs_lookup_extent_info()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46753
+    - btrfs: handle errors from btrfs_dec_ref() properly
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46841
+    - btrfs: don't BUG_ON on ENOMEM from btrfs_lookup_extent_info() in
+      walk_down_proc()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46754
+    - bpf: Remove tst_run from lwt_seg6local_prog_ops.
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46824
+    - iommufd: Require drivers to supply the cache_invalidate_user ops
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46842
+    - scsi: lpfc: Handle mailbox timeouts in lpfc_get_sfp_info
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46766
+    - ice: move netif_queue_set_napi to rtnl-protected sections
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46772
+    - drm/amd/display: Check denominator crb_pipes before used
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46774
+    - powerpc/rtas: Prevent Spectre v1 gadget construction in sys_rtas()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46775
+    - drm/amd/display: Validate function returns
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46778
+    - drm/amd/display: Check UnboundedRequestEnabled's value
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46779
+    - drm/imagination: Free pvr_vm_gpuva after unlink
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46792
+    - riscv: misaligned: Restrict user access to kernel memory
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46793
+    - ASoC: Intel: Boards: Fix NULL pointer deref in BYT/CHT boards harder
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46735
+    - ublk_drv: fix NULL pointer dereference in ublk_ctrl_start_recovery()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46737
+    - nvmet-tcp: fix kernel crash if commands allocation fails
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46822
+    - arm64: acpi: Harden get_cpu_for_acpi_id() against missing CPU entry
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46713
+    - perf/aux: Fix AUX buffer serialization
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46739
+    - uio_hv_generic: Fix kernel NULL pointer dereference in hv_uio_rescind
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46740
+    - binder: fix UAF caused by offsets overwrite
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46741
+    - misc: fastrpc: Fix double free of 'buf' in error path
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47663
+    - staging: iio: frequency: ad9834: Validate frequency parameter value
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46832
+    - MIPS: cevt-r4k: Don't call get_c0_compare_int if timer irq is installed
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47668
+    - lib/generic-radix-tree.c: Fix rare race in __genradix_ptr_alloc()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46744
+    - Squashfs: sanity check symbolic link size
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46745
+    - Input: uinput - reject requests with unreasonable number of slots
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46746
+    - HID: amd_sfh: free driver_data after destroying hid device
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47664
+    - spi: hisi-kunpeng: Add verification for the max_frequency provided by the
+      firmware
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47665
+    - i3c: mipi-i3c-hci: Error out instead on BUG_ON() in IBI DMA setup
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46749
+    - Bluetooth: btnxpuart: Fix Null pointer dereference in btnxpuart_flush()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46750
+    - PCI: Add missing bridge lock to pci_bus_lock()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46752
+    - btrfs: replace BUG_ON() with error handling at update_ref_for_cow()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46840
+    - btrfs: clean up our handling of refs == 0 in snapshot delete
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46755
+    - wifi: mwifiex: Do not return unused priv in mwifiex_get_priv_by_id()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47666
+    - scsi: pm80xx: Set phy->enable_completion only when we wait for it
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46843
+    - scsi: ufs: core: Remove SCSI host only if added
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46760
+    - wifi: rtw88: usb: schedule rx work after everything is set up
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46761
+    - pci/hotplug/pnv_php: Fix hotplug driver crash on Powernv
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46844
+    - um: line: always fill *error_out in setup_one_line()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46762
+    - xen: privcmd: Fix possible access to a freed kirqfd instance
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46763
+    - fou: Fix null-ptr-deref in GRO.
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46765
+    - ice: protect XDP configuration with a mutex
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46767
+    - net: phy: Fix missing of_node_put() for leds
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46768
+    - hwmon: (hp-wmi-sensors) Check if WMI event data exists
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46770
+    - ice: Add netif_device_attach/detach into PF reset flow
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46771
+    - can: bcm: Remove proc entry when dev is unregistered.
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46773
+    - drm/amd/display: Check denominator pbn_div before used
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47667
+    - PCI: keystone: Add workaround for Errata #i2037 (AM65x SR 1.0)
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46835
+    - drm/amdgpu: Fix smatch static checker warning
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46776
+    - drm/amd/display: Run DC_LOG_DC after checking link->link_enc
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46836
+    - usb: gadget: aspeed_udc: validate endpoint index for ast udc
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46777
+    - udf: Avoid excessive partition lengths
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46825
+    - wifi: iwlwifi: mvm: use IWL_FW_CHECK for link ID check
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46826
+    - ELF: fix kernel.randomize_va_space double read
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46827
+    - wifi: ath12k: fix firmware crash due to invalid peer nss
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47669
+    - nilfs2: fix state management in error path of log writing function
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46780
+    - nilfs2: protect references to superblock parameters exposed in sysfs
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46781
+    - nilfs2: fix missing cleanup on rollforward recovery error
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46828
+    - sched: sch_cake: fix bulk flow accounting logic for host fairness
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46782
+    - ila: call nf_unregister_net_hooks() sooner
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46783
+    - tcp_bpf: fix return value of tcp_bpf_sendmsg()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46784
+    - net: mana: Fix error handling in mana_create_txq/rxq's NAPI cleanup
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46785
+    - eventfs: Use list_del_rcu() for SRCU protected list variable
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46786
+    - fscache: delete fscache_cookie_lru_timer when fscache exits to avoid UAF
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46787
+    - userfaultfd: fix checks for huge PMDs
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46838
+    - userfaultfd: don't BUG_ON() if khugepaged yanks our page table
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46845
+    - tracing/timerlat: Only clear timer if a kthread exists
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46788
+    - tracing/osnoise: Use a cpumask to know what threads are kthreads
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46846
+    - spi: rockchip: Resolve unbalanced runtime PM / system PM handling
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46847
+    - mm: vmalloc: ensure vmap_block is initialised before adding to queue
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46791
+    - can: mcp251x: fix deadlock if an interrupt occurs during mcp251x_open
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46829
+    - rtmutex: Drop rt_mutex::wait_lock before scheduling
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46848
+    - perf/x86/intel: Limit the period on Haswell
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46794
+    - x86/tdx: Fix data leak in mmio_read()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46795
+    - ksmbd: unset the binding mark of a reused connection
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46797
+    - powerpc/qspinlock: Fix deadlock in MCS queue
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46830
+    - KVM: x86: Acquire kvm->srcu when handling KVM_SET_VCPU_EVENTS
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46798
+    - ASoC: dapm: Fix UAF for snd_soc_pcm_runtime object
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46831
+    - net: microchip: vcap: Fix use-after-free error in kunit test
+  * Navi24 RX6300 light up issue on 6.8 kernel (LP: #2084513)
+    - drm/amd/display: Ensure populate uclk in bb construction
+  * Noble update: upstream stable patchset 2024-10-18 (LP: #2084941)
+    - 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
+    - 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
+    - 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)
+    - 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/amdkfd: Check debug trap enable before write dbg_ev_file
+    - 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
+    - btrfs: factor out stripe length calculation into a helper
+    - btrfs: scrub: update last_physical after scrubbing one stripe
+    - btrfs: fix qgroup reserve leaks in cow_file_range
+    - virtio-net: check feature before configuring the vq coalescing command
+    - drm/amd/display: Handle the case which quad_part is equal 0
+    - drm/amdgpu: Handle sg size limit for contiguous allocation
+    - drm/amd/pm: fix uninitialized variable warning for smu_v13
+    - drm/amdgpu: fix uninitialized scalar variable warning
+    - drm/amd/display: Ensure array index tg_inst won't be -1
+    - drm/amd/display: handle invalid connector indices
+    - drm/amd/display: Increase MAX_LINKS by 2
+    - drm/amd/display: Stop amdgpu_dm initialize when link nums greater than
+      max_links
+    - drm/amd/display: Fix incorrect size calculation for loop
+    - drm/amd/display: Use kcalloc() instead of kzalloc()
+    - drm/amd/display: Add missing NULL pointer check within
+      dpcd_extend_address_range
+    - drm/amd/display: Release state memory if amdgpu_dm_create_color_properties
+      fail
+    - drm/amd/display: Check link_index before accessing dc->links[]
+    - drm/amd/display: Add otg_master NULL check within
+      resource_log_pipe_topology_update
+    - drm/amd/display: Release clck_src memory if clk_src_construct fails
+    - drm/amd/display: Fix writeback job lock evasion within dm_crtc_high_irq
+    - drm/xe: Demote CCS_MODE info to debug only
+    - drm/drm-bridge: Drop conditionals around of_node pointers
+    - drm/amdgpu: fix uninitialized variable warning for amdgpu_xgmi
+    - drm/amdgpu: fix uninitialized variable warning for jpeg_v4
+    - drm/amdgpu: Fix uninitialized variable warning in amdgpu_info_ioctl
+    - wifi: ath12k: initialize 'ret' in ath12k_dp_rxdma_ring_sel_config_wcn7850()
+    - drm/amdgpu/pm: Check input value for power profile setting on smu11, smu13
+      and smu14
+    - drm/xe: Fix the warning conditions
+    - drm/amd/display: Fix pipe addition logic in calc_blocks_to_ungate DCN35
+    - wifi: cfg80211: restrict operation during radar detection
+    - remoteproc: qcom_q6v5_pas: Add hwspinlock bust on stop
+    - tcp: annotate data-races around tw->tw_ts_recent and tw->tw_ts_recent_stamp
+    - drm/xe: Don't overmap identity VRAM mapping
+    - net: tcp/dccp: prepare for tw_timer un-pinning
+    - drm/xe: Ensure caller uses sole domain for xe_force_wake_assert_held
+    - drm/xe: Check valid domain is passed in xe_force_wake_ref
+    - thermal: trip: Use READ_ONCE() for lockless access to trip properties
+    - drm/xe: Add GuC state asserts to deregister_exec_queue
+    - drm/amdgpu: fix overflowed constant warning in mmhub_set_clockgating()
+    - drm/amd/display: Remove register from DCN35 DMCUB diagnostic collection
+    - drm/amd/display: Disable DMCUB timeout for DCN35
+    - drm/amd/display: Avoid overflow from uint32_t to uint8_t
+    - pinctrl: core: reset gpio_device in loop in pinctrl_pins_show()
+    - Upstream stable to v6.6.50, v6.10.9
+  * CVE-2024-46747
+    - HID: cougar: fix slab-out-of-bounds Read in cougar_report_fixup
+  * CVE-2024-46725
+    - drm/amdgpu: Fix out-of-bounds write warning
+  * CVE-2024-46724
+    - drm/amdgpu: Fix out-of-bounds read of df_v1_7_channel_number
+  * [SRU] Fix AST DP output after resume (LP: #2083022)
+    - drm/ast: Inline drm_simple_encoder_init()
+    - drm/ast: Implement atomic enable/disable for encoders
+    - drm/ast: Program mode for AST DP in atomic_mode_set
+    - drm/ast: Move mode-setting code into mode_set_nofb CRTC helper
+    - drm/ast: Handle primary-plane format setup in atomic_update
+    - drm/ast: Remove gamma LUT updates from DPMS code
+    - drm/ast: Only set VGA SCREEN_DISABLE bit in CRTC code
+    - drm/ast: Inline ast_crtc_dpms() into callers
+    - drm/ast: Use drm_atomic_helper_commit_tail() helper
+  * UBSAN array-index-out-of-bounds reported with N-6.8 on P9 node baltar
+    (LP: #2078038)
+    - scripts/kernel-doc: reindent
+    - compiler_types: add Endianness-dependent __counted_by_{le, be}
+    - scsi: aacraid: union aac_init: Replace 1-element array with flexible array
+    - scsi: aacraid: struct aac_ciss_phys_luns_resp: Replace 1-element array with
+      flexible array
+    - scsi: aacraid: Rearrange order of struct aac_srb_unit
+    - scsi: aacraid: struct {user, }sgmap{, 64, raw}: Replace 1-element arrays
+      with flexible arrays
+  * r8169: transmit queue 0 timed out error when re-plugging the Ethernet cable
+    (LP: #2084526)
+    - r8169: disable ALDPS per default for RTL8125
+  * [SRU] cpufreq: intel_pstate: Support Emerald Rapids OOB mode (LP: #2084834)
+    - cpufreq: intel_pstate: Support Emerald Rapids OOB mode
+  * CVE-2024-46723
+    - drm/amdgpu: fix ucode out-of-bounds read warning
+  * CVE-2024-46743
+    - of/irq: Prevent device address out-of-bounds read in interrupt map walk
+  * CVE-2024-46757
+    - hwmon: (nct6775-core) Fix underflows seen when writing limit attributes
+  * [SRU] Ubuntu 24.04 - GPU cannot be installed with DL380a Gen12 (2P, SRF-SP)
+    (LP: #2081079)
+    - perf/x86/uncore: Save the unit control address of all units
+    - perf/x86/uncore: Support per PMU cpumask
+    - perf/x86/uncore: Retrieve the unit ID from the unit control RB tree
+    - perf/x86/uncore: Apply the unit control RB tree to MMIO uncore units
+    - perf/x86/uncore: Apply the unit control RB tree to MSR uncore units
+    - perf/x86/uncore: Apply the unit control RB tree to PCI uncore units
+    - perf/x86/uncore: Cleanup unused unit structure
+    - perf/x86/intel/uncore: Support HBM and CXL PMON counters
+  * Noble update: upstream stable patchset 2024-10-11 (LP: #2084225)
+    - ALSA: seq: Skip event type filtering for UMP events
+    - LoongArch: Remove the unused dma-direct.h
+    - btrfs: fix a use-after-free when hitting errors inside btrfs_submit_chunk()
+    - btrfs: run delayed iputs when flushing delalloc
+    - smb/client: avoid dereferencing rdata=NULL in smb2_new_read_req()
+    - pinctrl: rockchip: correct RK3328 iomux width flag for GPIO2-B pins
+    - pinctrl: single: fix potential NULL dereference in pcs_get_function()
+    - wifi: wfx: repair open network AP mode
+    - wifi: mwifiex: duplicate static structs used in driver instances
+    - net: mana: Fix race of mana_hwc_post_rx_wqe and new hwc response
+    - mptcp: close subflow when receiving TCP+FIN
+    - mptcp: sched: check both backup in retrans
+    - mptcp: pm: reuse ID 0 after delete and re-add
+    - mptcp: pm: skip connecting to already established sf
+    - mptcp: pm: reset MPC endp ID when re-added
+    - mptcp: pm: send ACK on an active subflow
+    - mptcp: pm: do not remove already closed subflows
+    - mptcp: pm: fix ID 0 endp usage after multiple re-creations
+    - mptcp: pm: ADD_ADDR 0 is not a new address
+    - selftests: mptcp: join: check removing ID 0 endpoint
+    - selftests: mptcp: join: no extra msg if no counter
+    - selftests: mptcp: join: check re-re-adding ID 0 endp
+    - drm/amdgpu/swsmu: always force a state reprogram on init
+    - drm/vmwgfx: Fix prime with external buffers
+    - usb: typec: fix up incorrectly backported "usb: typec: tcpm: unregister
+      existing source caps before re-registration"
+    - ASoC: amd: acp: fix module autoloading
+    - ASoC: SOF: amd: Fix for acp init sequence
+    - pinctrl: mediatek: common-v2: Fix broken bias-disable for
+      PULL_PU_PD_RSEL_TYPE
+    - pinctrl: starfive: jh7110: Correct the level trigger configuration of iev
+      register
+    - ovl: pass string to ovl_parse_layer()
+    - ovl: fix wrong lowerdir number check for parameter Opt_lowerdir
+    - ovl: ovl_parse_param_lowerdir: Add missed '\n' for pr_err
+    - mm: Fix missing folio invalidation calls during truncation
+    - cifs: Fix FALLOC_FL_PUNCH_HOLE support
+    - selinux,smack: don't bypass permissions check in inode_setsecctx hook
+    - iommufd: Do not allow creating areas without READ or WRITE
+    - phy: fsl-imx8mq-usb: fix tuning parameter name
+    - dmaengine: dw-edma: Fix unmasking STOP and ABORT interrupts for HDMA
+    - dmaengine: dw-edma: Do not enable watermark interrupts for HDMA
+    - phy: xilinx: phy-zynqmp: Fix SGMII linkup failure on resume
+    - dmaengine: dw: Add peripheral bus width verification
+    - dmaengine: dw: Add memory bus width verification
+    - Bluetooth: btnxpuart: Resolve TX timeout error in power save stress test
+    - Bluetooth: btnxpuart: Handle FW Download Abort scenario
+    - Bluetooth: btnxpuart: Fix random crash seen while removing driver
+    - Bluetooth: hci_core: Fix not handling hibernation actions
+    - iommu: Do not return 0 from map_pages if it doesn't do anything
+    - netfilter: nf_tables: restore IP sanity checks for netdev/egress
+    - wifi: iwlwifi: fw: fix wgds rev 3 exact size
+    - ethtool: check device is present when getting link settings
+    - netfilter: nf_tables_ipv6: consider network offset in netdev/egress
+      validation
+    - selftests: forwarding: no_forwarding: Down ports on cleanup
+    - selftests: forwarding: local_termination: Down ports on cleanup
+    - bonding: implement xdo_dev_state_free and call it after deletion
+    - bonding: extract the use of real_device into local variable
+    - bonding: change ipsec_lock from spin lock to mutex
+    - gtp: fix a potential NULL pointer dereference
+    - sctp: fix association labeling in the duplicate COOKIE-ECHO case
+    - drm/amd/display: avoid using null object of framebuffer
+    - net: busy-poll: use ktime_get_ns() instead of local_clock()
+    - nfc: pn533: Add poll mod list filling check
+    - soc: qcom: cmd-db: Map shared memory as WC, not WB
+    - soc: qcom: pmic_glink: Actually communicate when remote goes down
+    - soc: qcom: pmic_glink: Fix race during initialization
+    - cdc-acm: Add DISABLE_ECHO quirk for GE HealthCare UI Controller
+    - scsi: sd: Ignore command SYNCHRONIZE CACHE error if format in progress
+    - USB: serial: option: add MeiG Smart SRM825L
+    - ARM: dts: imx6dl-yapp43: Increase LED current to match the yapp4 HW design
+    - usb: dwc3: omap: add missing depopulate in probe error path
+    - usb: dwc3: core: Prevent USB core invalid event buffer address access
+    - usb: dwc3: st: fix probed platform device ref count on probe error path
+    - usb: dwc3: st: add missing depopulate in probe error path
+    - usb: core: sysfs: Unmerge @usb3_hardware_lpm_attr_group in
+      remove_power_attributes()
+    - usb: cdnsp: fix incorrect index in cdnsp_get_hw_deq function
+    - usb: cdnsp: fix for Link TRB with TC
+    - ARM: dts: omap3-n900: correct the accelerometer orientation
+    - arm64: dts: imx8mp-beacon-kit: Fix Stereo Audio on WM8962
+    - arm64: dts: imx93: add nvmem property for fec1
+    - arm64: dts: imx93: add nvmem property for eqos
+    - arm64: dts: imx93: update default value for snps,clk-csr
+    - arm64: dts: freescale: imx93-tqma9352: fix CMA alloc-ranges
+    - arm64: dts: freescale: imx93-tqma9352-mba93xxla: fix typo
+    - scsi: aacraid: Fix double-free on probe failure
+    - apparmor: fix policy_unpack_test on big endian systems
+    - mptcp: pr_debug: add missing \n at the end
+    - mptcp: make pm_remove_addrs_and_subflows static
+    - mptcp: pm: fix RM_ADDR ID for the initial subflow
+    - mptcp: avoid duplicated SUB_CLOSED events
+    - drm/i915/dsi: Make Lenovo Yoga Tab 3 X90F DMI match less strict
+    - drm/vmwgfx: Prevent unmapping active read buffers
+    - drm/vmwgfx: Disable coherent dumb buffers without 3d
+    - firmware/sysfb: Set firmware-framebuffer parent device
+    - firmware/sysfb: Create firmware device only for enabled PCI devices
+    - video/aperture: optionally match the device in sysfb_disable()
+    - drm/xe: Prepare display for D3Cold
+    - drm/xe/display: Make display suspend/resume work on discrete
+    - drm/xe/vm: Simplify if condition
+    - drm/xe/exec_queue: Rename xe_exec_queue::compute to xe_exec_queue::lr
+    - drm/xe: prevent UAF around preempt fence
+    - pinctrl: qcom: x1e80100: Update PDC hwirq map
+    - ASoC: SOF: amd: move iram-dram fence register programming sequence
+    - nfsd: ensure that nfsd4_fattr_args.context is zeroed out
+    - backing-file: convert to using fops->splice_write
+    - pinctrl: qcom: x1e80100: Fix special pin offsets
+    - afs: Fix post-setattr file edit to do truncation correctly
+    - netfs: Fix netfs_release_folio() to say no if folio dirty
+    - netfs: Fix missing iterator reset on retry of short read
+    - dmaengine: ti: omap-dma: Initialize sglen after allocation
+    - pktgen: use cpus_read_lock() in pg_net_init()
+    - net_sched: sch_fq: fix incorrect behavior for small weights
+    - tcp: fix forever orphan socket caused by tcp_abort
+    - drm/xe/hwmon: Fix WRITE_I1 param from u32 to u16
+    - usb: typec: fsa4480: Relax CHIP_ID check
+    - firmware: qcom: scm: Mark get_wq_ctx() as atomic call
+    - usb: gadget: uvc: queue pump work in uvcg_video_enable()
+    - usb: dwc3: xilinx: add missing depopulate in probe error path
+    - usb: typec: ucsi: Move unregister out of atomic section
+    - firmware: microchip: fix incorrect error report of programming:timeout on
+      success
+    - Upstream stable to v6.6.49, v6.10.8
+  * Fix blank screen on external display after reconnecting the USB type-C
+    (LP: #2081786) // Noble update: upstream stable patchset 2024-10-11
+    (LP: #2084225)
+    - drm/i915/display: add intel_display -> drm_device backpointer
+    - drm/i915/display: add generic to_intel_display() macro
+    - drm/i915/dp_mst: Fix MST state after a sink reset
+  * Noble update: upstream stable patchset 2024-10-09 (LP: #2084005)
+    - tty: serial: fsl_lpuart: mark last busy before uart_add_one_port
+    - tty: atmel_serial: use the correct RTS flag.
+    - Revert "ACPI: EC: Evaluate orphan _REG under EC device"
+    - Revert "misc: fastrpc: Restrict untrusted app to attach to privileged PD"
+    - Revert "usb: typec: tcpm: clear pd_event queue in PORT_RESET"
+    - selinux: revert our use of vma_is_initial_heap()
+    - fuse: Initialize beyond-EOF page contents before setting uptodate
+    - char: xillybus: Don't destroy workqueue from work item running on it
+    - char: xillybus: Refine workqueue handling
+    - char: xillybus: Check USB endpoints when probing device
+    - ALSA: usb-audio: Add delay quirk for VIVO USB-C-XE710 HEADSET
+    - ALSA: usb-audio: Support Yamaha P-125 quirk entry
+    - xhci: Fix Panther point NULL pointer deref at full-speed re-enumeration
+    - thunderbolt: Mark XDomain as unplugged when router is removed
+    - ALSA: hda/tas2781: fix wrong calibrated data order
+    - s390/dasd: fix error recovery leading to data corruption on ESE devices
+    - KVM: s390: fix validity interception issue when gisa is switched off
+    - riscv: change XIP's kernel_map.size to be size of the entire kernel
+    - i2c: tegra: Do not mark ACPI devices as irq safe
+    - ACPICA: Add a depth argument to acpi_execute_reg_methods()
+    - ACPI: EC: Evaluate _REG outside the EC scope more carefully
+    - arm64: ACPI: NUMA: initialize all values of acpi_early_node_map to
+      NUMA_NO_NODE
+    - dm resume: don't return EINVAL when signalled
+    - dm persistent data: fix memory allocation failure
+    - fs/ntfs3: add prefix to bitmap_size() and use BITS_TO_U64()
+    - s390/cio: rename bitmap_size() -> idset_bitmap_size()
+    - btrfs: rename bitmap_set_bits() -> btrfs_bitmap_set_bits()
+    - bitmap: introduce generic optimized bitmap_size()
+    - fix bitmap corruption on close_range() with CLOSE_RANGE_UNSHARE
+    - i2c: qcom-geni: Add missing geni_icc_disable in geni_i2c_runtime_resume
+    - rtla/osnoise: Prevent NULL dereference in error handling
+    - net: mana: Fix RX buf alloc_size alignment and atomic op panic
+    - net: mana: Fix doorbell out of order violation and avoid unnecessary
+      doorbell rings
+    - wifi: brcmfmac: cfg80211: Handle SSID based pmksa deletion
+    - selinux: fix potential counting error in avc_add_xperms_decision()
+    - selinux: add the processing of the failure of avc_add_xperms_decision()
+    - mm/memory-failure: use raw_spinlock_t in struct memory_failure_cpu
+    - btrfs: tree-checker: reject BTRFS_FT_UNKNOWN dir type
+    - btrfs: zoned: properly take lock to read/update block group's zoned
+      variables
+    - btrfs: tree-checker: add dev extent item checks
+    - drm/amdgpu: Actually check flags for all context ops.
+    - memcg_write_event_control(): fix a user-triggerable oops
+    - drm/amdgpu/jpeg2: properly set atomics vmid field
+    - drm/amdgpu/jpeg4: properly set atomics vmid field
+    - s390/uv: Panic for set and remove shared access UVC errors
+    - bpf: Fix updating attached freplace prog in prog_array map
+    - igc: Fix packet still tx after gate close by reducing i226 MAC retry buffer
+    - igc: Fix qbv_config_change_errors logics
+    - igc: Fix reset adapter logics when tx mode change
+    - net/mlx5e: Take state lock during tx timeout reporter
+    - net/mlx5e: Correctly report errors for ethtool rx flows
+    - net: axienet: Fix register defines comment description
+    - net: dsa: vsc73xx: pass value in phy_write operation
+    - net: dsa: vsc73xx: use read_poll_timeout instead delay loop
+    - net: dsa: vsc73xx: check busy flag in MDIO operations
+    - net: ethernet: mtk_wed: fix use-after-free panic in
+      mtk_wed_setup_tc_block_cb()
+    - mlxbf_gige: disable RX filters until RX path initialized
+    - mptcp: correct MPTCP_SUBFLOW_ATTR_SSN_OFFSET reserved size
+    - tcp: Update window clamping condition
+    - netfilter: allow ipv6 fragments to arrive on different devices
+    - netfilter: flowtable: initialise extack before use
+    - netfilter: nf_queue: drop packets with cloned unconfirmed conntracks
+    - netfilter: nf_tables: Audit log dump reset after the fact
+    - netfilter: nf_tables: Introduce nf_tables_getobj_single
+    - netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests
+    - vsock: fix recursive ->recvmsg calls
+    - selftests: net: lib: ignore possible errors
+    - selftests: net: lib: kill PIDs before del netns
+    - net: hns3: fix wrong use of semaphore up
+    - net: hns3: use the user's cfg after reset
+    - net: hns3: fix a deadlock problem when config TC during resetting
+    - gpio: mlxbf3: Support shutdown() function
+    - ALSA: hda/realtek: Fix noise from speakers on Lenovo IdeaPad 3 15IAU7
+    - rust: work around `bindgen` 0.69.0 issue
+    - rust: suppress error messages from CONFIG_{RUSTC,BINDGEN}_VERSION_TEXT
+    - rust: fix the default format for CONFIG_{RUSTC,BINDGEN}_VERSION_TEXT
+    - cpu/SMT: Enable SMT only if a core is online
+    - powerpc/topology: Check if a core is online
+    - arm64: Fix KASAN random tag seed initialization
+    - block: Fix lockdep warning in blk_mq_mark_tag_wait
+    - wifi: ath12k: Add missing qmi_txn_cancel() calls
+    - quota: Remove BUG_ON from dqget()
+    - riscv: blacklist assembly symbols for kprobe
+    - kernfs: fix false-positive WARN(nr_mmapped) in kernfs_drain_open_files
+    - media: pci: cx23885: check cx23885_vdev_init() return
+    - fs: binfmt_elf_efpic: don't use missing interpreter's properties
+    - scsi: lpfc: Initialize status local variable in lpfc_sli4_repost_sgl_list()
+    - media: drivers/media/dvb-core: copy user arrays safely
+    - wifi: iwlwifi: mvm: avoid garbage iPN
+    - net/sun3_82586: Avoid reading past buffer in debug output
+    - drm/lima: set gp bus_stop bit before hard reset
+    - gpio: sysfs: extend the critical section for unregistering sysfs devices
+    - hrtimer: Select housekeeping CPU during migration
+    - virtiofs: forbid newlines in tags
+    - accel/habanalabs: fix debugfs files permissions
+    - clocksource/drivers/arm_global_timer: Guard against division by zero
+    - tick: Move got_idle_tick away from common flags
+    - netlink: hold nlk->cb_mutex longer in __netlink_dump_start()
+    - md: clean up invalid BUG_ON in md_ioctl
+    - x86: Increase brk randomness entropy for 64-bit systems
+    - memory: stm32-fmc2-ebi: check regmap_read return value
+    - parisc: Use irq_enter_rcu() to fix warning at kernel/context_tracking.c:367
+    - rxrpc: Don't pick values out of the wire header when setting up security
+    - f2fs: stop checkpoint when get a out-of-bounds segment
+    - powerpc/boot: Handle allocation failure in simple_realloc()
+    - powerpc/boot: Only free if realloc() succeeds
+    - btrfs: delayed-inode: drop pointless BUG_ON in __btrfs_remove_delayed_item()
+    - btrfs: defrag: change BUG_ON to assertion in btrfs_defrag_leaves()
+    - btrfs: change BUG_ON to assertion when checking for delayed_node root
+    - btrfs: push errors up from add_async_extent()
+    - btrfs: handle invalid root reference found in may_destroy_subvol()
+    - btrfs: send: handle unexpected data in header buffer in begin_cmd()
+    - btrfs: send: handle unexpected inode in header process_recorded_refs()
+    - btrfs: change BUG_ON to assertion in tree_move_down()
+    - btrfs: delete pointless BUG_ON check on quota root in
+      btrfs_qgroup_account_extent()
+    - f2fs: fix to do sanity check in update_sit_entry
+    - usb: gadget: fsl: Increase size of name buffer for endpoints
+    - nvme: clear caller pointer on identify failure
+    - Bluetooth: bnep: Fix out-of-bound access
+    - firmware: cirrus: cs_dsp: Initialize debugfs_root to invalid
+    - rtc: nct3018y: fix possible NULL dereference
+    - net: hns3: add checking for vf id of mailbox
+    - nvmet-tcp: do not continue for invalid icreq
+    - NFS: avoid infinite loop in pnfs_update_layout.
+    - openrisc: Call setup_memory() earlier in the init sequence
+    - s390/iucv: fix receive buffer virtual vs physical address confusion
+    - irqchip/renesas-rzg2l: Do not set TIEN and TINT source at the same time
+    - platform/x86: lg-laptop: fix %s null argument warning
+    - usb: dwc3: core: Skip setting event buffers for host only controllers
+    - irqchip/gic-v3-its: Remove BUG_ON in its_vpe_irq_domain_alloc
+    - ext4: set the type of max_zeroout to unsigned int to avoid overflow
+    - nvmet-rdma: fix possible bad dereference when freeing rsps
+    - selftests/bpf: Fix a few tests for GCC related warnings.
+    - Revert "bpf, sockmap: Prevent lock inversion deadlock in map delete elem"
+    - nvme: use srcu for iterating namespace list
+    - drm/amdgpu: fix dereference null return value for the function
+      amdgpu_vm_pt_parent
+    - hrtimer: Prevent queuing of hrtimer without a function callback
+    - nvme: fix namespace removal list
+    - gtp: pull network headers in gtp_dev_xmit()
+    - riscv: entry: always initialize regs->a0 to -ENOSYS
+    - smb3: fix lock breakage for cached writes
+    - dm suspend: return -ERESTARTSYS instead of -EINTR
+    - selftests: memfd_secret: don't build memfd_secret test on unsupported arches
+    - mm/vmalloc: fix page mapping if vm_area_alloc_pages() with high order
+      fallback to order 0
+    - btrfs: send: allow cloning non-aligned extent if it ends at i_size
+    - drm/amd/amdgpu: command submission parser for JPEG
+    - platform/surface: aggregator: Fix warning when controller is destroyed in
+      probe
+    - ALSA: hda/tas2781: Use correct endian conversion
+    - Bluetooth: hci_core: Fix LE quote calculation
+    - Bluetooth: SMP: Fix assumption of Central always being Initiator
+    - net: mscc: ocelot: use ocelot_xmit_get_vlan_info() also for FDMA and
+      register injection
+    - net: mscc: ocelot: fix QoS class for injected packets with "ocelot-8021q"
+    - net: mscc: ocelot: serialize access to the injection/extraction groups
+    - tc-testing: don't access non-existent variable on exception
+    - selftests: udpgro: report error when receive failed
+    - tcp/dccp: bypass empty buckets in inet_twsk_purge()
+    - tcp/dccp: do not care about families in inet_twsk_purge()
+    - tcp: prevent concurrent execution of tcp_sk_exit_batch
+    - net: mctp: test: Use correct skb for route input check
+    - kcm: Serialise kcm_sendmsg() for the same socket.
+    - netfilter: nft_counter: Disable BH in nft_counter_offload_stats().
+    - netfilter: nft_counter: Synchronize nft_counter_reset() against reader.
+    - ip6_tunnel: Fix broken GRO
+    - bonding: fix bond_ipsec_offload_ok return type
+    - bonding: fix null pointer deref in bond_ipsec_offload_ok
+    - bonding: fix xfrm real_dev null pointer dereference
+    - bonding: fix xfrm state handling when clearing active slave
+    - ice: fix page reuse when PAGE_SIZE is over 8k
+    - ice: fix ICE_LAST_OFFSET formula
+    - ice: fix truesize operations for PAGE_SIZE >= 8192
+    - dpaa2-switch: Fix error checking in dpaa2_switch_seed_bp()
+    - igb: cope with large MAX_SKB_FRAGS
+    - net: dsa: mv88e6xxx: Fix out-of-bound access
+    - udp: fix receiving fraglist GSO packets
+    - ipv6: fix possible UAF in ip6_finish_output2()
+    - ipv6: prevent possible UAF in ip6_xmit()
+    - bnxt_en: Fix double DMA unmapping for XDP_REDIRECT
+    - netfilter: flowtable: validate vlan header
+    - octeontx2-af: Fix CPT AF register offset calculation
+    - net: xilinx: axienet: Always disable promiscuous mode
+    - net: xilinx: axienet: Fix dangling multicast addresses
+    - net: ovs: fix ovs_drop_reasons error
+    - drm/msm/dpu: don't play tricks with debug macros
+    - drm/msm/dp: fix the max supported bpp logic
+    - drm/msm/dpu: split dpu_encoder_wait_for_event into two functions
+    - drm/msm/dpu: capture snapshot on the first commit_done timeout
+    - drm/msm/dpu: move dpu_encoder's connector assignment to atomic_enable()
+    - drm/msm/dp: reset the link phy params before link training
+    - drm/msm/dpu: cleanup FB if dpu_format_populate_layout fails
+    - drm/msm/dpu: take plane rotation into account for wide planes
+    - drm/msm: fix the highest_bank_bit for sc7180
+    - mmc: mmc_test: Fix NULL dereference on allocation failure
+    - Bluetooth: MGMT: Add error handling to pair_device()
+    - scsi: core: Fix the return value of scsi_logical_block_count()
+    - ksmbd: the buffer of smb2 query dir response has at least 1 byte
+    - drm/amdgpu: Validate TA binary size
+    - net: dsa: microchip: fix PTP config failure when using multiple ports
+    - MIPS: Loongson64: Set timer mode in cpu-probe
+    - HID: wacom: Defer calculation of resolution until resolution_code is known
+    - Input: i8042 - add forcenorestore quirk to leave controller untouched even
+      on s3
+    - Input: i8042 - use new forcenorestore quirk to replace old buggy quirk
+      combination
+    - cxgb4: add forgotten u64 ivlan cast before shift
+    - KVM: arm64: Make ICC_*SGI*_EL1 undef in the absence of a vGICv3
+    - mmc: mtk-sd: receive cmd8 data when hs400 tuning fail
+    - mmc: dw_mmc: allow biu and ciu clocks to defer
+    - smb3: fix broken cached reads when posix locks
+    - pmdomain: imx: scu-pd: Remove duplicated clocks
+    - pmdomain: imx: wait SSAR when i.MX93 power domain on
+    - nouveau/firmware: use dma non-coherent allocator
+    - mptcp: pm: re-using ID of unused removed ADD_ADDR
+    - mptcp: pm: re-using ID of unused removed subflows
+    - mptcp: pm: re-using ID of unused flushed subflows
+    - mptcp: pm: remove mptcp_pm_remove_subflow()
+    - mptcp: pm: only mark 'subflow' endp as available
+    - mptcp: pm: only decrement add_addr_accepted for MPJ req
+    - mptcp: pm: check add_addr_accept_max before accepting new ADD_ADDR
+    - mptcp: pm: only in-kernel cannot have entries with ID 0
+    - mptcp: pm: fullmesh: select the right ID later
+    - mptcp: pm: avoid possible UaF when selecting endp
+    - selftests: mptcp: join: validate fullmesh endp on 1st sf
+    - selftests: mptcp: join: restrict fullmesh endp on 1st sf
+    - selftests: mptcp: join: check re-using ID of closed subflow
+    - tcp: do not export tcp_twsk_purge()
+    - drm/msm/mdss: specify cfg bandwidth for SDM670
+    - drm/panel: nt36523: Set 120Hz fps for xiaomi,elish panels
+    - igc: Fix qbv tx latency by setting gtxoffset
+    - ALSA: timer: Relax start tick time check for slave timer elements
+    - bpf: Fix a kernel verifier crash in stacksafe()
+    - selftests/bpf: Add a test to verify previous stacksafe() fix
+    - Revert "s390/dasd: Establish DMA alignment"
+    - Input: MT - limit max slots
+    - tools: move alignment-related macros to new <linux/align.h>
+    - Revert "serial: 8250_omap: Set the console genpd always on if no console
+      suspend"
+    - usb: misc: ljca: Add Lunar Lake ljca GPIO HID to ljca_gpio_hids[]
+    - usb: xhci: Check for xhci->interrupters being allocated in
+      xhci_mem_clearup()
+    - vfs: Don't evict inode under the inode lru traversing context
+    - tracing: Return from tracing_buffers_read() if the file has been closed
+    - mm: fix endless reclaim on machines with unaccepted memory
+    - fs/netfs/fscache_cookie: add missing "n_accesses" check
+    - mm/numa: no task_numa_fault() call if PMD is changed
+    - mm/numa: no task_numa_fault() call if PTE is changed
+    - btrfs: check delayed refs when we're checking if a ref exists
+    - drm/amd/display: Adjust cursor position
+    - drm/amd/display: fix s2idle entry for DCN3.5+
+    - drm/amd/display: Enable otg synchronization logic for DCN321
+    - drm/amd/display: fix cursor offset on rotation 180
+    - netfs: Fault in smaller chunks for non-large folio mappings
+    - libfs: fix infinite directory reads for offset dir
+    - kallsyms: Avoid weak references for kallsyms symbols
+    - kbuild: avoid unneeded kallsyms step 3
+    - kbuild: refactor variables in scripts/link-vmlinux.sh
+    - kbuild: remove PROVIDE() for kallsyms symbols
+    - kallsyms: get rid of code for absolute kallsyms
+    - [Config] Remove CONFIG_KALLSYMS_BASE_RELATIVE
+    - kallsyms: Do not cleanup .llvm.<hash> suffix before sorting symbols
+    - bpf: Replace deprecated strncpy with strscpy
+    - kallsyms: replace deprecated strncpy with strscpy
+    - kallsyms: rework symbol lookup return codes
+    - kallsyms: Match symbols exactly with CONFIG_LTO_CLANG
+    - drm/v3d: Fix out-of-bounds read in `v3d_csd_job_run()`
+    - drm/amd/display: Don't register panel_power_savings on OLED panels
+    - wifi: ath12k: use 128 bytes aligned iova in transmit path for WCN7850
+    - kbuild: merge temporary vmlinux for BTF and kallsyms
+    - kbuild: avoid scripts/kallsyms parsing /dev/null
+    - Bluetooth: HCI: Invert LE State quirk to be opt-out rather then opt-in
+    - net/mlx5: Fix IPsec RoCE MPV trace call
+    - selftests: udpgro: no need to load xdp for gro
+    - ice: use internal pf id instead of function number
+    - drm/msm/dpu: limit QCM2290 to RGB formats only
+    - drm/msm/dpu: relax YUV requirements
+    - spi: spi-cadence-quadspi: Fix OSPI NOR failures during system resume
+    - drm/xe/display: stop calling domains_driver_remove twice
+    - drm/xe: Fix opregion leak
+    - drm/xe/mmio: move mmio_fini over to devm
+    - drm/xe: reset mmio mappings with devm
+    - drm/xe: Fix tile fini sequence
+    - drm/xe: Fix missing workqueue destroy in xe_gt_pagefault
+    - drm/xe: Free job before xe_exec_queue_put
+    - thermal/debugfs: Fix the NULL vs IS_ERR() confusion in debugfs_create_dir()
+    - nvme: move stopping keep-alive into nvme_uninit_ctrl()
+    - drm/amdgpu/sdma5.2: limit wptr workaround to sdma 5.2.1
+    - s390/ap: Refine AP bus bindings complete processing
+    - net: ngbe: Fix phy mode set to external phy
+    - iommufd/device: Fix hwpt at err_unresv in iommufd_device_do_replace()
+    - cgroup/cpuset: fix panic caused by partcmd_update
+    - cgroup/cpuset: Clear effective_xcpus on cpus_allowed clearing only if
+      cpus.exclusive not set
+    - of: Introduce for_each_*_child_of_node_scoped() to automate of_node_put()
+      handling
+    - thermal: of: Fix OF node leak in thermal_of_trips_init() error path
+    - thermal: of: Fix OF node leak in thermal_of_zone_register()
+    - thermal: of: Fix OF node leak in of_thermal_zone_find() error paths
+    - Upstream stable to v6.6.48, v6.10.7
+  * Unable to list directories using CIFS on 6.8 kernel (LP: #2082423) // Noble
+    update: upstream stable patchset 2024-10-09 (LP: #2084005)
+    - smb: client: ignore unhandled reparse tags
+  * CVE-2024-46759
+    - hwmon: (adc128d818) Fix underflows seen when writing limit attributes
+  * CVE-2024-46758
+    - hwmon: (lm95234) Fix underflows seen when writing limit attributes
+  * CVE-2024-46756
+    - hwmon: (w83627ehf) Fix underflows seen when writing limit attributes
+  * CVE-2024-46738
+    - VMCI: Fix use-after-free when removing resource in vmci_resource_remove()
+  * CVE-2024-46722
+    - drm/amdgpu: fix mc_data out-of-bounds read warning
+  * LXD fan bridge causes blocked tasks (LP: #2064176)
+    - SAUCE: fan: release rcu_read_lock on skb discard path
+    - SAUCE: fan: fix racy device stat update
+  * x86/CPU/AMD: Add models 0x10-0x1f to the Zen5 range (LP: #2081863)
+    - x86/CPU/AMD: Add models 0x60-0x6f to the Zen5 range
+  * UBSAN: array-index-out-of-bounds in module mt76 (LP: #2081785)
+    - wifi: mt76: mt7925: fix a potential array-index-out-of-bounds issue for clc
+  * The system hangs after resume with thunderbolt monitor(AMD GPU [1002:1900])
+    (LP: #2083182)
+    - SAUCE: drm/amd/display: Fix system hang while resume with TBT monitor
+  * [SRU] GPU: support additional device ids for DG2 driver (LP: #2083701)
+    - drm/i915: Add new PCI IDs to DG2 platform in driver
+  * [SRU]Intel Arrow Lake IBECC feature backport request for ubuntu 22.04.5 and
+    24.04.1 server (LP: #2077861)
+    - EDAC/igen6: Add Intel Arrow Lake-U/H SoCs support
+  * Noble update: upstream stable patchset 2024-10-07 (LP: #2083794)
+    - ASoC: topology: Clean up route loading
+    - ASoC: topology: Fix route memory corruption
+    - LoongArch: Define __ARCH_WANT_NEW_STAT in unistd.h
+    - sunrpc: don't change ->sv_stats if it doesn't exist
+    - nfsd: stop setting ->pg_stats for unused stats
+    - sunrpc: pass in the sv_stats struct through svc_create_pooled
+    - sunrpc: remove ->pg_stats from svc_program
+    - nfsd: remove nfsd_stats, make th_cnt a global counter
+    - nfsd: make svc_stat per-network namespace instead of global
+    - mm: gup: stop abusing try_grab_folio
+    - nvme/pci: Add APST quirk for Lenovo N60z laptop
+    - genirq/cpuhotplug: Skip suspended interrupts when restoring affinity
+    - genirq/cpuhotplug: Retry with cpu_online_mask when migration fails
+    - quota: Detect loops in quota tree
+    - bpf: Replace bpf_lpm_trie_key 0-length array with flexible array
+    - fs: Annotate struct file_handle with __counted_by() and use struct_size()
+    - mISDN: fix MISDN_TIME_STAMP handling
+    - mm/page_table_check: support userfault wr-protect entries
+    - bpf, net: Use DEV_STAT_INC()
+    - f2fs: fix to do sanity check on F2FS_INLINE_DATA flag in inode during GC
+    - f2fs: fix to cover read extent cache access with lock
+    - fou: remove warn in gue_gro_receive on unsupported protocol
+    - jfs: fix null ptr deref in dtInsertEntry
+    - jfs: Fix shift-out-of-bounds in dbDiscardAG
+    - fs/ntfs3: Do copy_to_user out of run_lock
+    - ALSA: usb: Fix UBSAN warning in parse_audio_unit()
+    - binfmt_flat: Fix corruption when not offsetting data start
+    - mm/debug_vm_pgtable: drop RANDOM_ORVALUE trick
+    - KVM: arm64: Don't defer TLB invalidation when zapping table entries
+    - KVM: arm64: Don't pass a TLBI level hint when zapping table entries
+    - drm/amd/display: Defer handling mst up request in resume
+    - drm/amd/display: Guard cursor idle reallow by DC debug option
+    - drm/amd/display: Separate setting and programming of cursor
+    - drm/amd/display: Prevent IPX From Link Detect and Set Mode
+    - ASoC: cs35l56: Patch CS35L56_IRQ1_MASK_18 to the default value
+    - platform/x86/amd/pmf: Fix to Update HPD Data When ALS is Disabled
+    - platform/x86: ideapad-laptop: introduce a generic notification chain
+    - platform/x86: ideapad-laptop: move ymc_trigger_ec from lenovo-ymc
+    - platform/x86: ideapad-laptop: add a mutex to synchronize VPC commands
+    - drm/amd/display: Solve mst monitors blank out problem after resume
+    - drm/amdgpu/display: Fix null pointer dereference in
+      dc_stream_program_cursor_position
+    - Upstream stable to v6.6.47, v6.10.6
+  * Noble update: upstream stable patchset 2024-10-04 (LP: #2083656)
+    - irqchip/mbigen: Fix mbigen node address layout
+    - platform/x86/intel/ifs: Initialize union ifs_status to zero
+    - jump_label: Fix the fix, brown paper bags galore
+    - x86/mm: Fix pti_clone_pgtable() alignment assumption
+    - x86/mm: Fix pti_clone_entry_text() for i386
+    - smb: client: move most of reparse point handling code to common file
+    - smb: client: set correct d_type for reparse DFS/DFSR and mount point
+    - smb: client: handle lack of FSCTL_GET_REPARSE_POINT support
+    - sctp: Fix null-ptr-deref in reuseport_add_sock().
+    - net: usb: qmi_wwan: fix memory leak for not ip packets
+    - net: bridge: mcast: wait for previous gc cycles when removing port
+    - net: linkwatch: use system_unbound_wq
+    - ice: Fix reset handler
+    - Bluetooth: l2cap: always unlock channel in l2cap_conless_channel()
+    - Bluetooth: hci_sync: avoid dup filtering when passive scanning with adv
+      monitor
+    - net/smc: add the max value of fallback reason count
+    - net: dsa: bcm_sf2: Fix a possible memory leak in bcm_sf2_mdio_register()
+    - l2tp: fix lockdep splat
+    - net: bcmgenet: Properly overlay PHY and MAC Wake-on-LAN capabilities
+    - net: fec: Stop PPS on driver remove
+    - gpio: prevent potential speculation leaks in gpio_device_get_desc()
+    - hwmon: corsair-psu: add USB id of HX1200i Series 2023 psu
+    - rcutorture: Fix rcu_torture_fwd_cb_cr() data race
+    - md: do not delete safemode_timer in mddev_suspend
+    - md/raid5: avoid BUG_ON() while continue reshape after reassembling
+    - block: change rq_integrity_vec to respect the iterator
+    - rcu: Fix rcu_barrier() VS post CPUHP_TEARDOWN_CPU invocation
+    - clocksource/drivers/sh_cmt: Address race condition for clock events
+    - ACPI: battery: create alarm sysfs attribute atomically
+    - ACPI: SBS: manage alarm sysfs attribute through psy core
+    - xen: privcmd: Switch from mutex to spinlock for irqfds
+    - wifi: nl80211: disallow setting special AP channel widths
+    - wifi: ath12k: fix memory leak in ath12k_dp_rx_peer_frag_setup()
+    - net/mlx5e: SHAMPO, Fix invalid WQ linked list unlink
+    - selftests/bpf: Fix send_signal test with nested CONFIG_PARAVIRT
+    - af_unix: Don't retry after unix_state_lock_nested() in
+      unix_stream_connect().
+    - PCI: Add Edimax Vendor ID to pci_ids.h
+    - udf: prevent integer overflow in udf_bitmap_free_blocks()
+    - wifi: nl80211: don't give key data to userspace
+    - can: mcp251xfd: tef: prepare to workaround broken TEF FIFO tail index
+      erratum
+    - can: mcp251xfd: tef: update workaround for erratum DS80000789E 6 of
+      mcp2518fd
+    - net: stmmac: qcom-ethqos: enable SGMII loopback during DMA reset on
+      sa8775p-ride-r3
+    - btrfs: do not clear page dirty inside extent_write_locked_range()
+    - btrfs: fix invalid mapping of extent xarray state
+    - btrfs: fix bitmap leak when loading free space cache on duplicate entry
+    - Bluetooth: btnxpuart: Shutdown timer and prevent rearming when driver
+      unloading
+    - drm/amd/display: Add delay to improve LTTPR UHBR interop
+    - drm/amdgpu: fix potential resource leak warning
+    - drm/amdgpu/pm: Fix the param type of set_power_profile_mode
+    - drm/amdgpu/pm: Fix the null pointer dereference for smu7
+    - drm/amdgpu: Fix the null pointer dereference to ras_manager
+    - drm/amdgpu/pm: Fix the null pointer dereference in apply_state_adjust_rules
+    - drm/admgpu: fix dereferencing null pointer context
+    - drm/amdgpu: Add lock around VF RLCG interface
+    - drm/amd/pm: Fix the null pointer dereference for vega10_hwmgr
+    - media: amphion: Remove lock in s_ctrl callback
+    - drm/amd/display: Add null checker before passing variables
+    - media: uvcvideo: Ignore empty TS packets
+    - media: uvcvideo: Fix the bandwdith quirk on USB 3.x
+    - media: xc2028: avoid use-after-free in load_firmware_cb()
+    - ext4: fix uninitialized variable in ext4_inlinedir_to_tree
+    - jbd2: avoid memleak in jbd2_journal_write_metadata_buffer
+    - s390/sclp: Prevent release of buffer in I/O
+    - SUNRPC: Fix a race to wake a sync task
+    - profiling: remove profile=sleep support
+    - scsi: mpt3sas: Avoid IOMMU page faults on REPORT ZONES
+    - irqchip/meson-gpio: Convert meson_gpio_irq_controller::lock to
+      'raw_spinlock_t'
+    - irqchip/loongarch-cpu: Fix return value of lpic_gsi_to_irq()
+    - sched/cputime: Fix mul_u64_u64_div_u64() precision for cputime
+    - net: drop bad gso csum_start and offset in virtio_net_hdr
+    - arm64: Add Neoverse-V2 part
+    - arm64: barrier: Restore spec_bar() macro
+    - arm64: cputype: Add Cortex-X4 definitions
+    - arm64: cputype: Add Neoverse-V3 definitions
+    - arm64: errata: Add workaround for Arm errata 3194386 and 3312417
+    - arm64: cputype: Add Cortex-X3 definitions
+    - arm64: cputype: Add Cortex-A720 definitions
+    - arm64: cputype: Add Cortex-X925 definitions
+    - arm64: errata: Unify speculative SSBS errata logic
+    - [Config] Set ARM64_ERRATUM_3194386=y
+    - arm64: errata: Expand speculative SSBS workaround
+    - arm64: cputype: Add Cortex-X1C definitions
+    - arm64: cputype: Add Cortex-A725 definitions
+    - arm64: errata: Expand speculative SSBS workaround (again)
+    - i2c: smbus: Improve handling of stuck alerts
+    - ASoC: codecs: wcd938x-sdw: Correct Soundwire ports mask
+    - ASoC: codecs: wsa881x: Correct Soundwire ports mask
+    - ASoC: codecs: wsa883x: parse port-mapping information
+    - ASoC: codecs: wsa883x: Correct Soundwire ports mask
+    - ASoC: codecs: wsa884x: parse port-mapping information
+    - ASoC: codecs: wsa884x: Correct Soundwire ports mask
+    - ASoC: sti: add missing probe entry for player and reader
+    - spi: spidev: Add missing spi_device_id for bh2228fv
+    - ASoC: SOF: Remove libraries from topology lookups
+    - i2c: smbus: Send alert notifications to all devices if source not found
+    - bpf: kprobe: remove unused declaring of bpf_kprobe_override
+    - kprobes: Fix to check symbol prefixes correctly
+    - i2c: qcom-geni: Add missing clk_disable_unprepare in geni_i2c_runtime_resume
+    - i2c: qcom-geni: Add missing geni_icc_disable in geni_i2c_runtime_resume
+    - spi: spi-fsl-lpspi: Fix scldiv calculation
+    - ALSA: usb-audio: Re-add ScratchAmp quirk entries
+    - ASoC: meson: axg-fifo: fix irq scheduling issue with PREEMPT_RT
+    - cifs: cifs_inval_name_dfs_link_error: correct the check for fullpath
+    - module: warn about excessively long module waits
+    - module: make waiting for a concurrent module loader interruptible
+    - drm/i915/gem: Fix Virtual Memory mapping boundaries calculation
+    - drm/amd/display: Skip Recompute DSC Params if no Stream on Link
+    - drm/amdgpu: Forward soft recovery errors to userspace
+    - drm/i915/gem: Adjust vma offset for framebuffer mmap offset
+    - drm/client: fix null pointer dereference in drm_client_modeset_probe
+    - ALSA: line6: Fix racy access to midibuf
+    - ALSA: hda: Add HP MP9 G4 Retail System AMS to force connect list
+    - ALSA: hda/realtek: Add Framework Laptop 13 (Intel Core Ultra) to quirks
+    - ALSA: hda/hdmi: Yet more pin fix for HP EliteDesk 800 G4
+    - usb: vhci-hcd: Do not drop references before new references are gained
+    - USB: serial: debug: do not echo input by default
+    - usb: gadget: core: Check for unset descriptor
+    - usb: gadget: midi2: Fix the response for FB info with block 0xff
+    - usb: gadget: u_serial: Set start_delayed during suspend
+    - usb: gadget: u_audio: Check return codes from usb_ep_enable and
+      config_ep_by_speed.
+    - scsi: mpi3mr: Avoid IOMMU page faults on REPORT ZONES
+    - scsi: ufs: core: Do not set link to OFF state while waking up from
+      hibernation
+    - scsi: ufs: core: Fix hba->last_dme_cmd_tstamp timestamp updating logic
+    - tick/broadcast: Move per CPU pointer access into the atomic section
+    - vhost-vdpa: switch to use vmf_insert_pfn() in the fault handler
+    - ntp: Clamp maxerror and esterror to operating range
+    - clocksource: Scale the watchdog read retries automatically
+    - clocksource: Fix brown-bag boolean thinko in cs_watchdog_read()
+    - driver core: Fix uevent_show() vs driver detach race
+    - tracefs: Fix inode allocation
+    - tracefs: Use generic inode RCU for synchronizing freeing
+    - ntp: Safeguard against time_constant overflow
+    - timekeeping: Fix bogus clock_was_set() invocation in do_adjtimex()
+    - serial: core: check uartclk for zero to avoid divide by zero
+    - memcg: protect concurrent access to mem_cgroup_idr
+    - parisc: fix unaligned accesses in BPF
+    - parisc: fix a possible DMA corruption
+    - ASoC: amd: yc: Add quirk entry for OMEN by HP Gaming Laptop 16-n0xxx
+    - kcov: properly check for softirq context
+    - irqchip/xilinx: Fix shift out of bounds
+    - genirq/irqdesc: Honor caller provided affinity in alloc_desc()
+    - LoongArch: Enable general EFI poweroff method
+    - power: supply: qcom_battmgr: return EAGAIN when firmware service is not up
+    - power: supply: axp288_charger: Fix constant_charge_voltage writes
+    - power: supply: axp288_charger: Round constant_charge_voltage writes down
+    - tracing: Fix overflow in get_free_elt()
+    - padata: Fix possible divide-by-0 panic in padata_mt_helper()
+    - smb3: fix setting SecurityFlags when encryption is required
+    - eventfs: Don't return NULL in eventfs_create_dir()
+    - eventfs: Use SRCU for freeing eventfs_inodes
+    - selftests: mm: add s390 to ARCH check
+    - btrfs: avoid using fixed char array size for tree names
+    - x86/paravirt: Fix incorrect virt spinlock setting on bare metal
+    - x86/mtrr: Check if fixed MTRRs exist before saving them
+    - sched/smt: Introduce sched_smt_present_inc/dec() helper
+    - sched/smt: Fix unbalance sched_smt_present dec/inc
+    - sched/core: Introduce sched_set_rq_on/offline() helper
+    - sched/core: Fix unbalance set_rq_online/offline() in sched_cpu_deactivate()
+    - drm/bridge: analogix_dp: properly handle zero sized AUX transactions
+    - drm/dp_mst: Skip CSN if topology probing is not done yet
+    - drm/lima: Mark simple_ondemand governor as softdep
+    - drm/mgag200: Set DDC timeout in milliseconds
+    - drm/mgag200: Bind I2C lifetime to DRM device
+    - drm/radeon: Remove __counted_by from StateArray.states[]
+    - mptcp: fully established after ADD_ADDR echo on MPJ
+    - mptcp: pm: deny endp with signal + subflow + port
+    - block: use the right type for stub rq_integrity_vec()
+    - btrfs: fix corruption after buffer fault in during direct IO append write
+    - tools headers arm64: Sync arm64's cputype.h with the kernel sources
+    - mm/hugetlb: fix potential race in __update_and_free_hugetlb_folio()
+    - xfs: fix log recovery buffer allocation for the legacy h_size fixup
+    - mptcp: pm: reduce indentation blocks
+    - mptcp: pm: don't try to create sf if alloc failed
+    - mptcp: pm: do not ignore 'subflow' if 'signal' flag is also set
+    - selftests: mptcp: join: ability to invert ADD_ADDR check
+    - selftests: mptcp: join: test both signal & subflow
+    - Revert "selftests: mptcp: simult flows: mark 'unbalanced' tests as flaky"
+    - btrfs: fix double inode unlock for direct IO sync writes
+    - perf/x86/intel/cstate: Switch to new Intel CPU model defines
+    - perf/x86/intel/cstate: Add Arrowlake support
+    - perf/x86/intel/cstate: Add Lunarlake support
+    - perf/x86/intel/cstate: Add pkg C2 residency counter for Sierra Forest
+    - platform/x86: intel-vbtn: Protect ACPI notify handler against recursion
+    - perf/x86/amd: Use try_cmpxchg() in events/amd/{un,}core.c
+    - perf/x86/intel: Support the PEBS event mask
+    - perf/x86: Support counter mask
+    - perf/x86: Fix smp_processor_id()-in-preemptible warnings
+    - virtio-net: unbreak vq resizing when coalescing is not negotiated
+    - net: dsa: microchip: Fix Wake-on-LAN check to not return an error
+    - net: dsa: microchip: disable EEE for KSZ8567/KSZ9567/KSZ9896/KSZ9897.
+    - regmap: kunit: Use a KUnit action to call regmap_exit()
+    - regmap: kunit: Replace a kmalloc/kfree() pair with KUnit-managed alloc
+    - regmap: kunit: Fix memory leaks in gen_regmap() and gen_raw_regmap()
+    - debugobjects: Annotate racy debug variables
+    - nvme: apple: fix device reference counting
+    - cpufreq: amd-pstate: Allow users to write 'default' EPP string
+    - cpufreq: amd-pstate: auto-load pstate driver by default
+    - soc: qcom: icc-bwmon: Allow for interrupts to be shared across instances
+    - ACPI: resource: Skip IRQ override on Asus Vivobook Pro N6506MU
+    - ACPI: resource: Skip IRQ override on Asus Vivobook Pro N6506MJ
+    - thermal: intel: hfi: Give HFI instances package scope
+    - wifi: ath12k: fix race due to setting ATH12K_FLAG_EXT_IRQ_ENABLED too early
+    - wifi: rtlwifi: handle return value of usb init TX/RX
+    - wifi: rtw89: pci: fix RX tag race condition resulting in wrong RX length
+    - wifi: mac80211: fix NULL dereference at band check in starting tx ba session
+    - bpf: add missing check_func_arg_reg_off() to prevent out-of-bounds memory
+      accesses
+    - mlxsw: pci: Lock configuration space of upstream bridge during reset
+    - btrfs: do not BUG_ON() when freeing tree block after error
+    - btrfs: reduce nesting for extent processing at btrfs_lookup_extent_info()
+    - btrfs: fix data race when accessing the last_trans field of a root
+    - drm/xe/preempt_fence: enlarge the fence critical section
+    - drm/amd/display: Handle HPD_IRQ for internal link
+    - drm/amd/amdkfd: Fix a resource leak in svm_range_validate_and_map()
+    - drm/xe/xe_guc_submit: Fix exec queue stop race condition
+    - drm/amd/display: Add null checks for 'stream' and 'plane' before
+      dereferencing
+    - drm/amd/display: Wake DMCUB before sending a command for replay feature
+    - drm/amd/display: reduce ODM slice count to initial new dc state only when
+      needed
+    - of: Add cleanup.h based auto release via __free(device_node) markings
+    - media: i2c: ov5647: replacing of_node_put with __free(device_node)
+    - drm/amd/display: Fix null pointer deref in dcn20_resource.c
+    - ext4: sanity check for NULL pointer after ext4_force_shutdown
+    - mm, slub: do not call do_slab_free for kfence object
+    - ASoC: cs35l56: Revert support for dual-ownership of ASP registers
+    - drm/atomic: allow no-op FB_ID updates for async flips
+    - drm/amd/display: Replace dm_execute_dmub_cmd with
+      dc_wake_and_execute_dmub_cmd
+    - drm/xe/rtp: Fix off-by-one when processing rules
+    - drm/xe: Use dma_fence_chain_free in chain fence unused as a sync
+    - drm/xe/hwmon: Fix PL1 disable flow in xe_hwmon_power_max_write
+    - drm/xe: Move lrc snapshot capturing to xe_lrc.c
+    - drm/xe: Minor cleanup in LRC handling
+    - drm/test: fix the gem shmem test to map the sg table.
+    - usb: typec: pd: no opencoding of FIELD_GET
+    - usb: typec: fsa4480: Check if the chip is really there
+    - PM: runtime: Simplify pm_runtime_get_if_active() usage
+    - scsi: ufs: core: Fix deadlock during RTC update
+    - serial: sc16is7xx: fix invalid FIFO access with special register set
+    - tracing: Have format file honor EVENT_FILE_FL_FREED
+    - mm: list_lru: fix UAF for memory cgroup
+    - net/tcp: Disable TCP-AO static key after RCU grace period
+    - Revert "drm/amd/display: Handle HPD_IRQ for internal link"
+    - idpf: fix memleak in vport interrupt configuration
+    - drm/amd/display: Add null check in resource_log_pipe_topology_update
+    - Upstream stable to v6.6.46, v6.10.5
+  * Noble update: upstream stable patchset 2024-10-02 (LP: #2083488)
+    - sysctl: allow change system v ipc sysctls inside ipc namespace
+    - sysctl: allow to change limits for posix messages queues
+    - sysctl: treewide: drop unused argument ctl_table_root::set_ownership(table)
+    - ext4: factor out a common helper to query extent map
+    - ext4: check the extent status again before inserting delalloc block
+    - leds: trigger: Store brightness set by led_trigger_event()
+    - leds: trigger: Call synchronize_rcu() before calling trig->activate()
+    - KVM: VMX: Move posted interrupt descriptor out of VMX code
+    - fbdev/vesafb: Replace references to global screen_info by local pointer
+    - video: Add helpers for decoding screen_info
+    - [Config] Update CONFIG_SCREEN_INFO
+    - video: Provide screen_info_get_pci_dev() to find screen_info's PCI device
+    - firmware/sysfb: Update screen_info for relocated EFI framebuffers
+    - mm: page_alloc: control latency caused by zone PCP draining
+    - mm/page_alloc: fix pcp->count race between drain_pages_zone() vs
+      __rmqueue_pcplist()
+    - f2fs: fix to avoid use SSR allocate when do defragment
+    - f2fs: assign CURSEG_ALL_DATA_ATGC if blkaddr is valid
+    - dmaengine: fsl-edma: add address for channel mux register in fsl_edma_chan
+    - dmaengine: fsl-edma: add i.MX8ULP edma support
+    - perf: imx_perf: fix counter start and config sequence
+    - MIPS: Loongson64: DTS: Fix PCIe port nodes for ls7a
+    - MIPS: dts: loongson: Fix liointc IRQ polarity
+    - MIPS: dts: loongson: Fix ls2k1000-rtc interrupt
+    - ARM: 9406/1: Fix callchain_trace() return value
+    - HID: amd_sfh: Move sensor discovery before HID device initialization
+    - perf tool: fix dereferencing NULL al->maps
+    - drm/nouveau: prime: fix refcount underflow
+    - drm/vmwgfx: Fix overlay when using Screen Targets
+    - drm/vmwgfx: Trigger a modeset when the screen moves
+    - sched: act_ct: take care of padding in struct zones_ht_key
+    - wifi: cfg80211: fix reporting failed MLO links status with
+      cfg80211_connect_done
+    - net: phy: realtek: add support for RTL8366S Gigabit PHY
+    - ALSA: hda: conexant: Fix headset auto detect fail in the polling mode
+    - Bluetooth: btintel: Fail setup on error
+    - Bluetooth: hci_sync: Fix suspending with wrong filter policy
+    - tcp: annotate data-races around tp->window_clamp
+    - tcp: Adjust clamping window for applications specifying SO_RCVBUF
+    - net: axienet: start napi before enabling Rx/Tx
+    - rtnetlink: Don't ignore IFLA_TARGET_NETNSID when ifname is specified in
+      rtnl_dellink().
+    - i915/perf: Remove code to update PWR_CLK_STATE for gen12
+    - ice: respect netif readiness in AF_XDP ZC related ndo's
+    - ice: don't busy wait for Rx queue disable in ice_qp_dis()
+    - ice: replace synchronize_rcu with synchronize_net
+    - ice: add missing WRITE_ONCE when clearing ice_rx_ring::xdp_prog
+    - drm/i915/hdcp: Fix HDCP2_STREAM_STATUS macro
+    - net: mvpp2: Don't re-use loop iterator
+    - net: phy: micrel: Fix the KSZ9131 MDI-X status issue
+    - ALSA: hda: Conditionally use snooping for AMD HDMI
+    - netfilter: iptables: Fix null-ptr-deref in iptable_nat_table_init().
+    - netfilter: iptables: Fix potential null-ptr-deref in
+      ip6table_nat_table_init().
+    - net/mlx5: Always drain health in shutdown callback
+    - net/mlx5: Fix error handling in irq_pool_request_irq
+    - net/mlx5: Lag, don't use the hardcoded value of the first port
+    - net/mlx5: Fix missing lock on sync reset reload
+    - net/mlx5e: Require mlx5 tc classifier action support for IPsec prio
+      capability
+    - net/mlx5e: Fix CT entry update leaks of modify header context
+    - net/mlx5e: Add a check for the return value from mlx5_port_set_eth_ptys
+    - igc: Fix double reset adapter triggered from a single taprio cmd
+    - ipv6: fix ndisc_is_useropt() handling for PIO
+    - perf: riscv: Fix selecting counters in legacy mode
+    - riscv/mm: Add handling for VM_FAULT_SIGSEGV in mm_fault_error()
+    - riscv: Fix linear mapping checks for non-contiguous memory regions
+    - arm64: jump_label: Ensure patched jump_labels are visible to all CPUs
+    - rust: SHADOW_CALL_STACK is incompatible with Rust
+    - platform/chrome: cros_ec_proto: Lock device when updating MKBP version
+    - HID: wacom: Modify pen IDs
+    - btrfs: zoned: fix zone_unusable accounting on making block group read-write
+      again
+    - btrfs: do not subtract delalloc from avail bytes
+    - protect the fetch of ->fd[fd] in do_dup2() from mispredictions
+    - mptcp: sched: check both directions for backup
+    - ALSA: usb-audio: Correct surround channels in UAC1 channel map
+    - ALSA: hda/realtek: Add quirk for Acer Aspire E5-574G
+    - ALSA: seq: ump: Optimize conversions from SysEx to UMP
+    - Revert "ALSA: firewire-lib: obsolete workqueue for period update"
+    - Revert "ALSA: firewire-lib: operate for period elapse event in process
+      context"
+    - drm/vmwgfx: Fix a deadlock in dma buf fence polling
+    - drm/virtio: Fix type of dma-fence context variable
+    - drm/i915: Fix possible int overflow in skl_ddi_calculate_wrpll()
+    - net: usb: sr9700: fix uninitialized variable use in sr_mdio_read
+    - r8169: don't increment tx_dropped in case of NETDEV_TX_BUSY
+    - mptcp: fix user-space PM announced address accounting
+    - mptcp: distinguish rcv vs sent backup flag in requests
+    - mptcp: fix NL PM announced address accounting
+    - mptcp: mib: count MPJ with backup flag
+    - mptcp: fix bad RCVPRUNED mib accounting
+    - mptcp: pm: only set request_bkup flag when sending MP_PRIO
+    - mptcp: fix duplicate data handling
+    - selftests: mptcp: always close input's FD if opened
+    - selftests: mptcp: join: validate backup in MPJ
+    - selftests: mptcp: join: check backup support in signal endp
+    - mm/huge_memory: mark racy access onhuge_anon_orders_always
+    - mm: fix khugepaged activation policy
+    - x86/cpu/vfm: Add/initialize x86_vfm field to struct cpuinfo_x86
+    - perf/x86/intel: Switch to new Intel CPU model defines
+    - perf/x86/intel: Add a distinct name for Granite Rapids
+    - drm/gpuvm: fix missing dependency to DRM_EXEC
+    - netlink: specs: correct the spec of ethtool
+    - ethtool: rss: echo the context number back
+    - wifi: cfg80211: correct S1G beacon length calculation
+    - ethtool: fix setting key and resetting indir at once
+    - ice: modify error handling when setting XSK pool in ndo_bpf
+    - ice: toggle netif_carrier when setting up XSK pool
+    - ice: improve updating ice_{t,r}x_ring::xsk_pool
+    - ice: xsk: fix txq interrupt mapping
+    - drm/atomic: Allow userspace to use explicit sync with atomic async flips
+    - drm/atomic: Allow userspace to use damage clips with async flips
+    - riscv/purgatory: align riscv_kernel_entry
+    - perf arch events: Fix duplicate RISC-V SBI firmware event name
+    - RISC-V: Enable the IPI before workqueue_online_cpu()
+    - ceph: force sending a cap update msg back to MDS for revoke op
+    - drm/vmwgfx: Remove unused code
+    - drm/vmwgfx: Fix handling of dumb buffers
+    - drm/v3d: Prevent out of bounds access in performance query extensions
+    - drm/v3d: Fix potential memory leak in the timestamp extension
+    - drm/v3d: Fix potential memory leak in the performance extension
+    - drm/v3d: Validate passed in drm syncobj handles in the timestamp extension
+    - drm/v3d: Validate passed in drm syncobj handles in the performance extension
+    - nouveau: set placement to original placement on uvmm validate.
+    - wifi: ath12k: fix soft lockup on suspend
+    - mptcp: pm: fix backup support in signal endpoints
+    - selftests: mptcp: fix error path
+    - Upstream stable to v6.6.45, v6.10.4
+  * [SRU] Fix AST DP output after resume (LP: #2083022) // Noble update:
+    upstream stable patchset 2024-10-02 (LP: #2083488)
+    - drm/ast: astdp: Wake up during connector status detection
+    - drm/ast: Fix black screen after resume
+  * [SRU]Fail to locate the LED of NVME disk behind  Intel VMD (LP: #2077287) //
+    Noble update: upstream stable patchset 2024-10-02 (LP: #2083488)
+    - PCI: pciehp: Retain Power Indicator bits for userspace indicators
+  * Noble update: upstream stable patchset 2024-09-30 (LP: #2083196)
+    - powerpc/configs: Update defconfig with now user-visible CONFIG_FSL_IFC
+    - spi: spi-microchip-core: Fix the number of chip selects supported
+    - spi: atmel-quadspi: Add missing check for clk_prepare
+    - EDAC, i10nm: make skx_common.o a separate module
+    - rcu/tasks: Fix stale task snaphot for Tasks Trace
+    - platform/chrome: cros_ec_debugfs: fix wrong EC message version
+    - ubd: refactor the interrupt handler
+    - ubd: untagle discard vs write zeroes not support handling
+    - block: initialize integrity buffer to zero before writing it to media
+    - x86/kconfig: Add as-instr64 macro to properly evaluate AS_WRUSS
+    - hfsplus: fix to avoid false alarm of circular locking
+    - x86/of: Return consistent error type from x86_of_pci_irq_enable()
+    - x86/pci/intel_mid_pci: Fix PCIBIOS_* return code handling
+    - x86/pci/xen: Fix PCIBIOS_* return code handling
+    - x86/platform/iosf_mbi: Convert PCIBIOS_* return codes to errnos
+    - cgroup/cpuset: Prevent UAF in proc_cpuset_show()
+    - hwmon: (adt7475) Fix default duty on fan is disabled
+    - block: Call .limit_depth() after .hctx has been set
+    - block/mq-deadline: Fix the tag reservation code
+    - md: Don't wait for MD_RECOVERY_NEEDED for HOT_REMOVE_DISK ioctl
+    - pwm: stm32: Always do lazy disabling
+    - nvmet-auth: fix nvmet_auth hash error handling
+    - drm/meson: fix canvas release in bind function
+    - pwm: atmel-tcb: Fix race condition and convert to guards
+    - hwmon: (max6697) Fix underflow when writing limit attributes
+    - hwmon: (max6697) Fix swapped temp{1,8} critical alarms
+    - arm64: dts: qcom: sc8180x: Correct PCIe slave ports
+    - arm64: dts: qcom: sc8180x: add power-domain to UFS PHY
+    - arm64: dts: qcom: sdm845: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm6115: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm6350: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm8250: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm8350: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm8450: add power-domain to UFS PHY
+    - arm64: dts: qcom: msm8996-xiaomi-common: drop excton from the USB PHY
+    - arm64: dts: qcom: sdm850-lenovo-yoga-c630: fix IPA firmware path
+    - arm64: dts: qcom: msm8998: enable adreno_smmu by default
+    - soc: qcom: pmic_glink: Handle the return value of pmic_glink_init
+    - soc: qcom: rpmh-rsc: Ensure irqs aren't disabled by rpmh_rsc_send_data()
+      callers
+    - arm64: dts: rockchip: Add sdmmc related properties on rk3308-rock-pi-s
+    - arm64: dts: rockchip: Add pinctrl for UART0 to rk3308-rock-pi-s
+    - arm64: dts: rockchip: Add mdio and ethernet-phy nodes to rk3308-rock-pi-s
+    - arm64: dts: rockchip: Update WIFi/BT related nodes on rk3308-rock-pi-s
+    - arm64: dts: qcom: msm8996: specify UFS core_clk frequencies
+    - arm64: dts: qcom: sa8775p: mark ethernet devices as DMA-coherent
+    - soc: xilinx: rename cpu_number1 to dummy_cpu_number
+    - ARM: dts: sunxi: remove duplicated entries in makefile
+    - ARM: dts: stm32: Add arm,no-tick-in-suspend to STM32MP15xx STGEN timer
+    - arm64: dts: qcom: qrb4210-rb2: make L9A always-on
+    - cpufreq: ti-cpufreq: Handle deferred probe with dev_err_probe()
+    - OPP: ti: Fix ti_opp_supply_probe wrong return values
+    - memory: fsl_ifc: Make FSL_IFC config visible and selectable
+    - arm64: dts: ti: k3-am62x: Drop McASP AFIFOs
+    - arm64: dts: ti: k3-am625-beagleplay: Drop McASP AFIFOs
+    - arm64: dts: ti: k3-am62-verdin: Drop McASP AFIFOs
+    - arm64: dts: qcom: qdu1000: Add secure qfprom node
+    - soc: qcom: icc-bwmon: Fix refcount imbalance seen during bwmon_remove
+    - soc: qcom: pdr: protect locator_addr with the main mutex
+    - soc: qcom: pdr: fix parsing of domains lists
+    - arm64: dts: rockchip: Increase VOP clk rate on RK3328
+    - arm64: dts: amlogic: sm1: fix spdif compatibles
+    - ARM: dts: imx6qdl-kontron-samx6i: fix phy-mode
+    - ARM: dts: imx6qdl-kontron-samx6i: fix PHY reset
+    - ARM: dts: imx6qdl-kontron-samx6i: fix board reset
+    - ARM: dts: imx6qdl-kontron-samx6i: fix SPI0 chip selects
+    - ARM: dts: imx6qdl-kontron-samx6i: fix PCIe reset polarity
+    - arm64: dts: mediatek: mt8195: Fix GPU thermal zone name for SVS
+    - arm64: dts: mediatek: mt8183-kukui: Drop bogus output-enable property
+    - arm64: dts: mediatek: mt8192-asurada: Add off-on-delay-us for
+      pp3300_mipibrdg
+    - arm64: dts: mediatek: mt7622: fix "emmc" pinctrl mux
+    - arm64: dts: mediatek: mt8183-kukui: Fix the value of `dlg,jack-det-rate`
+      mismatch
+    - arm64: dts: mediatek: mt8183-kukui-jacuzzi: Add ports node for anx7625
+    - arm64: dts: amlogic: gx: correct hdmi clocks
+    - arm64: dts: amlogic: add power domain to hdmitx
+    - arm64: dts: amlogic: setup hdmi system clock
+    - arm64: dts: rockchip: Drop invalid mic-in-differential on rk3568-rock-3a
+    - arm64: dts: rockchip: Fix mic-in-differential usage on rk3566-roc-pc
+    - arm64: dts: rockchip: Fix mic-in-differential usage on rk3568-evb1-v10
+    - arm64: dts: renesas: r8a779a0: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r8a779f0: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r8a779g0: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r9a07g043u: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r9a07g044: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r9a07g054: Add missing hypervisor virtual timer IRQ
+    - m68k: atari: Fix TT bootup freeze / unexpected (SCU) interrupt messages
+    - arm64: dts: imx8mp: Fix pgc_mlmix location
+    - arm64: dts: imx8mp: add HDMI power-domains
+    - arm64: dts: imx8mp: Fix pgc vpu locations
+    - x86/xen: Convert comma to semicolon
+    - arm64: dts: rockchip: Add missing power-domains for rk356x vop_mmu
+    - arm64: dts: rockchip: fix regulator name for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: fix usb regulator for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: fix pmu_io supply for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: remove unused usb2 nodes for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: disable display subsystem for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: fixes PHY reset for Lunzn Fastrhino R68S
+    - arm64: dts: qcom: sm6350: Add missing qcom,non-secure-domain property
+    - cpufreq/amd-pstate: Fix the scaling_max_freq setting on shared memory CPPC
+      systems
+    - m68k: cmpxchg: Fix return value for default case in __arch_xchg()
+    - ARM: spitz: fix GPIO assignment for backlight
+    - vmlinux.lds.h: catch .bss..L* sections into BSS")
+    - firmware: turris-mox-rwtm: Do not complete if there are no waiters
+    - firmware: turris-mox-rwtm: Fix checking return value of
+      wait_for_completion_timeout()
+    - firmware: turris-mox-rwtm: Initialize completion before mailbox
+    - wifi: brcmsmac: LCN PHY code is used for BCM4313 2G-only device
+    - wifi: ath12k: Correct 6 GHz frequency value in rx status
+    - wifi: ath12k: Fix tx completion ring (WBM2SW) setup failure
+    - bpftool: Un-const bpf_func_info to fix it for llvm 17 and newer
+    - selftests/bpf: Fix prog numbers in test_sockmap
+    - net: esp: cleanup esp_output_tail_tcp() in case of unsupported ESPINTCP
+    - wifi: ath12k: change DMA direction while mapping reinjected packets
+    - wifi: ath12k: fix invalid memory access while processing fragmented packets
+    - wifi: ath12k: fix firmware crash during reo reinject
+    - wifi: ath11k: fix wrong definition of CE ring's base address
+    - wifi: ath12k: fix wrong definition of CE ring's base address
+    - tcp: add tcp_done_with_error() helper
+    - tcp: fix race in tcp_write_err()
+    - tcp: fix races in tcp_v[46]_err()
+    - net/smc: set rmb's SG_MAX_SINGLE_ALLOC limitation only when
+      CONFIG_ARCH_NO_SG_CHAIN is defined
+    - selftests/bpf: Check length of recv in test_sockmap
+    - udf: Fix lock ordering in udf_evict_inode()
+    - lib: objagg: Fix general protection fault
+    - mlxsw: spectrum_acl_erp: Fix object nesting warning
+    - mlxsw: spectrum_acl: Fix ACL scale regression and firmware errors
+    - perf/x86: Serialize set_attr_rdpmc()
+    - jump_label: Fix concurrency issues in static_key_slow_dec()
+    - wifi: ath11k: fix wrong handling of CCMP256 and GCMP ciphers
+    - wifi: cfg80211: fix typo in cfg80211_calculate_bitrate_he()
+    - wifi: cfg80211: handle 2x996 RU allocation in
+      cfg80211_calculate_bitrate_he()
+    - udf: Fix bogus checksum computation in udf_rename()
+    - net: fec: Refactor: #define magic constants
+    - net: fec: Fix FEC_ECR_EN1588 being cleared on link-down
+    - libbpf: Checking the btf_type kind when fixing variable offsets
+    - xfrm: Fix unregister netdevice hang on hardware offload.
+    - ipvs: Avoid unnecessary calls to skb_is_gso_sctp
+    - netfilter: nf_tables: rise cap on SELinux secmark context
+    - wifi: rtw89: 8852b: fix definition of KIP register number
+    - wifi: rtl8xxxu: 8188f: Limit TX power index
+    - xfrm: Export symbol xfrm_dev_state_delete.
+    - bpftool: Mount bpffs when pinmaps path not under the bpffs
+    - perf/x86/intel/pt: Fix pt_topa_entry_for_page() address calculation
+    - perf: Fix perf_aux_size() for greater-than 32-bit size
+    - perf: Prevent passing zero nr_pages to rb_alloc_aux()
+    - perf: Fix default aux_watermark calculation
+    - perf/x86/intel/cstate: Fix Alderlake/Raptorlake/Meteorlake
+    - wifi: rtw89: Fix array index mistake in rtw89_sta_info_get_iter()
+    - xfrm: fix netdev reference count imbalance
+    - xfrm: call xfrm_dev_policy_delete when kill policy
+    - wifi: virt_wifi: avoid reporting connection success with wrong SSID
+    - gss_krb5: Fix the error handling path for crypto_sync_skcipher_setkey
+    - wifi: virt_wifi: don't use strlen() in const context
+    - locking/rwsem: Add __always_inline annotation to __down_write_common() and
+      inlined callers
+    - selftests/bpf: Close fd in error path in drop_on_reuseport
+    - selftests/bpf: Null checks for links in bpf_tcp_ca
+    - selftests/bpf: Close obj in error path in xdp_adjust_tail
+    - selftests/resctrl: Convert perror() to ksft_perror() or ksft_print_msg()
+    - selftests/resctrl: Fix closing IMC fds on error and open-code R+W instead of
+      loops
+    - bpf: annotate BTF show functions with __printf
+    - bna: adjust 'name' buf size of bna_tcb and bna_ccb structures
+    - bpf: Eliminate remaining "make W=1" warnings in kernel/bpf/btf.o
+    - bpf: Fix null pointer dereference in resolve_prog_type() for
+      BPF_PROG_TYPE_EXT
+    - selftests: forwarding: devlink_lib: Wait for udev events after reloading
+    - Bluetooth: hci_bcm4377: Use correct unit for timeouts
+    - Bluetooth: btintel: Refactor btintel_set_ppag()
+    - Bluetooth: btnxpuart: Add handling for boot-signature timeout errors
+    - xdp: fix invalid wait context of page_pool_destroy()
+    - net: bridge: mst: Check vlan state for egress decision
+    - drm/rockchip: vop2: Fix the port mux of VP2
+    - drm/arm/komeda: Fix komeda probe failing if there are no links in the
+      secondary pipeline
+    - drm/amdkfd: Fix CU Masking for GFX 9.4.3
+    - drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq()
+    - drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_generic_write_seq()
+    - drm/amd/pm: Fix aldebaran pcie speed reporting
+    - drm/amdgpu: Fix memory range calculation
+    - drm/amdgpu: Check if NBIO funcs are NULL in amdgpu_device_baco_exit
+    - drm/amdgpu: Remove GC HW IP 9.3.0 from noretry=1
+    - drm/panel: himax-hx8394: Handle errors from mipi_dsi_dcs_set_display_on()
+      better
+    - drm/panel: boe-tv101wum-nl6: If prepare fails, disable GPIO before
+      regulators
+    - drm/panel: boe-tv101wum-nl6: Check for errors on the NOP in prepare()
+    - drm/bridge: Fixed a DP link training bug
+    - drm/bridge: it6505: fix hibernate to resume no display issue
+    - media: pci: ivtv: Add check for DMA map result
+    - media: imon: Fix race getting ictx->lock
+    - media: i2c: Fix imx412 exposure control
+    - media: v4l: async: Fix NULL pointer dereference in adding ancillary links
+    - s390/mm: Convert make_page_secure to use a folio
+    - s390/mm: Convert gmap_make_secure to use a folio
+    - s390/uv: Don't call folio_wait_writeback() without a folio reference
+    - media: mediatek: vcodec: Handle invalid decoder vsi
+    - x86/shstk: Make return uprobe work with shadow stack
+    - ipmi: ssif_bmc: prevent integer overflow on 32bit systems
+    - saa7134: Unchecked i2c_transfer function result fixed
+    - media: i2c: imx219: fix msr access command sequence
+    - media: uvcvideo: Disable autosuspend for Insta360 Link
+    - media: uvcvideo: Quirk for invalid dev_sof in Logitech C922
+    - media: uvcvideo: Add quirk for invalid dev_sof in Logitech C920
+    - media: uvcvideo: Override default flags
+    - drm: zynqmp_dpsub: Fix an error handling path in zynqmp_dpsub_probe()
+    - drm: zynqmp_kms: Fix AUX bus not getting unregistered
+    - media: rcar-vin: Fix YUYV8_1X16 handling for CSI-2
+    - media: rcar-csi2: Disable runtime_pm in probe error
+    - media: rcar-csi2: Cleanup subdevice in remove()
+    - media: renesas: vsp1: Fix _irqsave and _irq mix
+    - media: renesas: vsp1: Store RPF partition configuration per RPF instance
+    - drm/mediatek: Add missing plane settings when async update
+    - drm/mediatek: Use 8-bit alpha in ETHDR
+    - drm/mediatek: Fix XRGB setting error in OVL
+    - drm/mediatek: Fix XRGB setting error in Mixer
+    - drm/mediatek: Fix destination alpha error in OVL
+    - drm/mediatek: Turn off the layers with zero width or height
+    - drm/mediatek: Add OVL compatible name for MT8195
+    - media: imx-jpeg: Drop initial source change event if capture has been setup
+    - leds: trigger: Unregister sysfs attributes before calling deactivate()
+    - drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC
+    - drm/msm/dpu: drop validity checks for clear_pending_flush() ctl op
+    - perf test: Make test_arm_callgraph_fp.sh more robust
+    - perf pmus: Fixes always false when compare duplicates aliases
+    - perf report: Fix condition in sort__sym_cmp()
+    - drm/etnaviv: fix DMA direction handling for cached RW buffers
+    - drm/qxl: Add check for drm_cvt_mode
+    - Revert "leds: led-core: Fix refcount leak in of_led_get()"
+    - drm/mediatek: Remove less-than-zero comparison of an unsigned value
+    - ext4: fix infinite loop when replaying fast_commit
+    - drm/mediatek/dp: switch to ->edid_read callback
+    - drm/mediatek/dp: Fix spurious kfree()
+    - media: venus: flush all buffers in output plane streamoff
+    - perf intel-pt: Fix aux_watermark calculation for 64-bit size
+    - perf intel-pt: Fix exclude_guest setting
+    - mfd: rsmu: Split core code into separate module
+    - mfd: omap-usb-tll: Use struct_size to allocate tll
+    - xprtrdma: Fix rpcrdma_reqs_reset()
+    - SUNRPC: avoid soft lockup when transmitting UDP to reachable server.
+    - NFSv4.1 another fix for EXCHGID4_FLAG_USE_PNFS_DS for DS server
+    - ext4: don't track ranges in fast_commit if inode has inlined data
+    - ext4: avoid writing unitialized memory to disk in EA inodes
+    - leds: flash: leds-qcom-flash: Test the correct variable in init
+    - sparc64: Fix incorrect function signature and add prototype for
+      prom_cif_init
+    - SUNRPC: Fixup gss_status tracepoint error output
+    - iio: Fix the sorting functionality in iio_gts_build_avail_time_table
+    - PCI: Fix resource double counting on remove & rescan
+    - PCI: keystone: Relocate ks_pcie_set/clear_dbi_mode()
+    - PCI: keystone: Don't enable BAR 0 for AM654x
+    - PCI: keystone: Fix NULL pointer dereference in case of DT error in
+      ks_pcie_setup_rc_app_regs()
+    - PCI: rcar: Demote WARN() to dev_warn_ratelimited() in rcar_pcie_wakeup()
+    - scsi: ufs: mcq: Fix missing argument 'hba' in MCQ_OPR_OFFSET_n
+    - clk: qcom: gcc-sc7280: Update force mem core bit for UFS ICE clock
+    - clk: qcom: camcc-sc7280: Add parent dependency to all camera GDSCs
+    - iio: frequency: adrf6780: rm clk provider include
+    - coresight: Fix ref leak when of_coresight_parse_endpoint() fails
+    - RDMA/mlx5: Set mkeys for dmabuf at PAGE_SIZE
+    - ASoc: tas2781: Enable RCA-based playback without DSP firmware download
+    - ASoC: cs35l56: Accept values greater than 0 as IRQ numbers
+    - usb: typec-mux: nb7vpq904m: unregister typec switch on probe error and
+      remove
+    - RDMA/cache: Release GID table even if leak is detected
+    - clk: qcom: gpucc-sm8350: Park RCG's clk source at XO during disable
+    - clk: qcom: gcc-sa8775p: Update the GDSC wait_val fields and flags
+    - clk: qcom: gpucc-sa8775p: Remove the CLK_IS_CRITICAL and ALWAYS_ON flags
+    - clk: qcom: gpucc-sa8775p: Park RCG's clk source at XO during disable
+    - clk: qcom: gpucc-sa8775p: Update wait_val fields for GPU GDSC's
+    - interconnect: qcom: qcm2290: Fix mas_snoc_bimc RPM master ID
+    - Input: qt1050 - handle CHIP_ID reading error
+    - RDMA/mlx4: Fix truncated output warning in mad.c
+    - RDMA/mlx4: Fix truncated output warning in alias_GUID.c
+    - RDMA/mlx5: Use sq timestamp as QP timestamp when RoCE is disabled
+    - RDMA/rxe: Don't set BTH_ACK_MASK for UC or UD QPs
+    - ASoC: qcom: Adjust issues in case of DT error in
+      asoc_qcom_lpass_cpu_platform_probe()
+    - scsi: lpfc: Fix a possible null pointer dereference
+    - hwrng: core - Fix wrong quality calculation at hw rng registration
+    - powerpc/prom: Add CPU info to hardware description string later
+    - ASoC: max98088: Check for clk_prepare_enable() error
+    - mtd: make mtd_test.c a separate module
+    - RDMA/device: Return error earlier if port in not valid
+    - Input: elan_i2c - do not leave interrupt disabled on suspend failure
+    - ASoC: amd: Adjust error handling in case of absent codec device
+    - PCI: endpoint: Clean up error handling in vpci_scan_bus()
+    - PCI: endpoint: Fix error handling in epf_ntb_epc_cleanup()
+    - vhost/vsock: always initialize seqpacket_allow
+    - net: missing check virtio
+    - nvmem: rockchip-otp: set add_legacy_fixed_of_cells config option
+    - crypto: qat - extend scope of lock in adf_cfg_add_key_value_param()
+    - clk: qcom: kpss-xcc: Return of_clk_add_hw_provider to transfer the error
+    - clk: qcom: Park shared RCGs upon registration
+    - clk: en7523: fix rate divider for slic and spi clocks
+    - MIPS: Octeron: remove source file executable bit
+    - PCI: qcom-ep: Disable resources unconditionally during PERST# assert
+    - PCI: dwc: Fix index 0 incorrectly being interpreted as a free ATU slot
+    - powerpc/xmon: Fix disassembly CPU feature checks
+    - macintosh/therm_windtunnel: fix module unload.
+    - RDMA/hns: Check atomic wr length
+    - RDMA/hns: Fix unmatch exception handling when init eq table fails
+    - RDMA/hns: Fix missing pagesize and alignment check in FRMR
+    - RDMA/hns: Fix shift-out-bounds when max_inline_data is 0
+    - RDMA/hns: Fix undifined behavior caused by invalid max_sge
+    - RDMA/hns: Fix insufficient extend DB for VFs.
+    - iommu/vt-d: Fix identity map bounds in si_domain_init()
+    - RDMA/core: Remove NULL check before dev_{put, hold}
+    - RDMA: Fix netdev tracker in ib_device_set_netdev
+    - bnxt_re: Fix imm_data endianness
+    - netfilter: ctnetlink: use helper function to calculate expect ID
+    - netfilter: nf_set_pipapo: fix initial map fill
+    - ipvs: properly dereference pe in ip_vs_add_service
+    - gve: Fix XDP TX completion handling when counters overflow
+    - net: flow_dissector: use DEBUG_NET_WARN_ON_ONCE
+    - ipv4: Fix incorrect TOS in route get reply
+    - ipv4: Fix incorrect TOS in fibmatch route get reply
+    - net: dsa: mv88e6xxx: Limit chip-wide frame size config to CPU ports
+    - net: dsa: b53: Limit chip-wide jumbo frame config to CPU ports
+    - fs/ntfs3: Merge synonym COMPRESSION_UNIT and NTFS_LZNT_CUNIT
+    - fs/ntfs3: Fix transform resident to nonresident for compressed files
+    - fs/ntfs3: Deny getting attr data block in compressed frame
+    - fs/ntfs3: Missed NI_FLAG_UPDATE_PARENT setting
+    - fs/ntfs3: Fix getting file type
+    - fs/ntfs3: Add missing .dirty_folio in address_space_operations
+    - pinctrl: rockchip: update rk3308 iomux routes
+    - pinctrl: core: fix possible memory leak when pinctrl_enable() fails
+    - pinctrl: single: fix possible memory leak when pinctrl_enable() fails
+    - pinctrl: ti: ti-iodelay: fix possible memory leak when pinctrl_enable()
+      fails
+    - pinctrl: freescale: mxs: Fix refcount of child
+    - fs/ntfs3: Replace inode_trylock with inode_lock
+    - fs/ntfs3: Correct undo if ntfs_create_inode failed
+    - fs/ntfs3: Drop stray '\' (backslash) in formatting string
+    - fs/ntfs3: Fix field-spanning write in INDEX_HDR
+    - pinctrl: renesas: r8a779g0: Fix CANFD5 suffix
+    - pinctrl: renesas: r8a779g0: Fix FXR_TXEN[AB] suffixes
+    - pinctrl: renesas: r8a779g0: Fix (H)SCIF1 suffixes
+    - pinctrl: renesas: r8a779g0: Fix (H)SCIF3 suffixes
+    - pinctrl: renesas: r8a779g0: Fix IRQ suffixes
+    - pinctrl: renesas: r8a779g0: FIX PWM suffixes
+    - pinctrl: renesas: r8a779g0: Fix TCLK suffixes
+    - pinctrl: renesas: r8a779g0: Fix TPU suffixes
+    - fs/proc/task_mmu: indicate PM_FILE for PMD-mapped file THP
+    - fs/proc/task_mmu.c: add_to_pagemap: remove useless parameter addr
+    - fs/proc/task_mmu: don't indicate PM_MMAP_EXCLUSIVE without PM_PRESENT
+    - fs/proc/task_mmu: properly detect PM_MMAP_EXCLUSIVE per page of PMD-mapped
+      THPs
+    - nilfs2: avoid undefined behavior in nilfs_cnt32_ge macro
+    - rtc: interface: Add RTC offset to alarm after fix-up
+    - fs/ntfs3: Fix the format of the "nocase" mount option
+    - fs/ntfs3: Missed error return
+    - fs/ntfs3: Keep runs for $MFT::$ATTR_DATA and $MFT::$ATTR_BITMAP
+    - powerpc/8xx: fix size given to set_huge_pte_at()
+    - s390/dasd: fix error checks in dasd_copy_pair_store()
+    - sbitmap: use READ_ONCE to access map->word
+    - sbitmap: fix io hung due to race on sbitmap_word::cleared
+    - LoongArch: Check TIF_LOAD_WATCH to enable user space watchpoint
+    - landlock: Don't lose track of restrictions on cred_transfer
+    - hugetlb: force allocating surplus hugepages on mempolicy allowed nodes
+    - mm/hugetlb: fix possible recursive locking detected warning
+    - mm/mglru: fix div-by-zero in vmpressure_calc_level()
+    - mm: mmap_lock: replace get_memcg_path_buf() with on-stack buffer
+    - mm/mglru: fix overshooting shrinker memory
+    - x86/efistub: Avoid returning EFI_SUCCESS on error
+    - x86/efistub: Revert to heap allocated boot_params for PE entrypoint
+    - exfat: fix potential deadlock on __exfat_get_dentry_set
+    - dt-bindings: thermal: correct thermal zone node name limit
+    - tick/broadcast: Make takeover of broadcast hrtimer reliable
+    - net: netconsole: Disable target before netpoll cleanup
+    - af_packet: Handle outgoing VLAN packets without hardware offloading
+    - btrfs: fix extent map use-after-free when adding pages to compressed bio
+    - kernel: rerun task_work while freezing in get_signal()
+    - ipv4: fix source address selection with route leak
+    - ipv6: take care of scope when choosing the src addr
+    - NFSD: Support write delegations in LAYOUTGET
+    - sched/fair: set_load_weight() must also call reweight_task() for SCHED_IDLE
+      tasks
+    - fuse: verify {g,u}id mount options correctly
+    - ata: libata-scsi: Fix offsets for the fixed format sense data
+    - char: tpm: Fix possible memory leak in tpm_bios_measurements_open()
+    - media: venus: fix use after free in vdec_close
+    - ata: libata-scsi: Do not overwrite valid sense data when CK_COND=1
+    - hfs: fix to initialize fields of hfs_inode_info after hfs_alloc_inode()
+    - ext2: Verify bitmap and itable block numbers before using them
+    - io_uring/io-wq: limit retrying worker initialisation
+    - drm/gma500: fix null pointer dereference in cdv_intel_lvds_get_modes
+    - drm/gma500: fix null pointer dereference in psb_intel_lvds_get_modes
+    - scsi: qla2xxx: Fix optrom version displayed in FDMI
+    - drm/amd/display: Check for NULL pointer
+    - apparmor: use kvfree_sensitive to free data->data
+    - cifs: fix potential null pointer use in destroy_workqueue in init_cifs error
+      path
+    - cifs: fix reconnect with SMB1 UNIX Extensions
+    - cifs: mount with "unix" mount option for SMB1 incorrectly handled
+    - task_work: s/task_work_cancel()/task_work_cancel_func()/
+    - task_work: Introduce task_work_cancel() again
+    - udf: Avoid using corrupted block bitmap buffer
+    - m68k: amiga: Turn off Warp1260 interrupts during boot
+    - ext4: check dot and dotdot of dx_root before making dir indexed
+    - ext4: make sure the first directory block is not a hole
+    - io_uring: tighten task exit cancellations
+    - trace/pid_list: Change gfp flags in pid_list_fill_irq()
+    - selftests/landlock: Add cred_transfer test
+    - wifi: mwifiex: Fix interface type change
+    - wifi: rtw88: usb: Fix disconnection after beacon loss
+    - drivers: soc: xilinx: check return status of get_api_version()
+    - leds: ss4200: Convert PCIBIOS_* return codes to errnos
+    - leds: mt6360: Fix memory leak in mt6360_init_isnk_properties()
+    - media: imx-pxp: Fix ERR_PTR dereference in pxp_probe()
+    - jbd2: make jbd2_journal_get_max_txn_bufs() internal
+    - jbd2: precompute number of transaction descriptor blocks
+    - jbd2: avoid infinite transaction commit loop
+    - media: uvcvideo: Fix integer overflow calculating timestamp
+    - KVM: VMX: Split out the non-virtualization part of vmx_interrupt_blocked()
+    - KVM: nVMX: Request immediate exit iff pending nested event needs injection
+    - ALSA: ump: Don't update FB name for static blocks
+    - ALSA: ump: Force 1 Group for MIDI1 FBs
+    - ALSA: usb-audio: Fix microphone sound on HD webcam.
+    - ALSA: usb-audio: Move HD Webcam quirk to the right place
+    - ALSA: usb-audio: Add a quirk for Sonix HD USB Camera
+    - tools/memory-model: Fix bug in lock.cat
+    - hwrng: amd - Convert PCIBIOS_* return codes to errnos
+    - parisc: Fix warning at drivers/pci/msi/msi.h:121
+    - PCI: hv: Return zero, not garbage, when reading PCI_INTERRUPT_PIN
+    - PCI: dw-rockchip: Fix initial PERST# GPIO value
+    - PCI: rockchip: Use GPIOD_OUT_LOW flag while requesting ep_gpio
+    - PCI: loongson: Enable MSI in LS7A Root Complex
+    - binder: fix hang of unregistered readers
+    - hostfs: fix dev_t handling
+    - efi/libstub: Zero initialize heap allocated struct screen_info
+    - fs/ntfs3: Update log->page_{mask,bits} if log->page_size changed
+    - scsi: qla2xxx: Return ENOBUFS if sg_cnt is more than one for ELS cmds
+    - ASoC: fsl: fsl_qmc_audio: Check devm_kasprintf() returned value
+    - f2fs: fix to force buffered IO on inline_data inode
+    - f2fs: fix to don't dirty inode for readonly filesystem
+    - f2fs: fix return value of f2fs_convert_inline_inode()
+    - f2fs: use meta inode for GC of atomic file
+    - f2fs: use meta inode for GC of COW file
+    - clk: davinci: da8xx-cfgchip: Initialize clk_init_data before use
+    - ubi: eba: properly rollback inside self_check_eba
+    - block: fix deadlock between sd_remove & sd_release
+    - mm: fix old/young bit handling in the faulting path
+    - decompress_bunzip2: fix rare decompression failure
+    - kbuild: Fix '-S -c' in x86 stack protector scripts
+    - ASoC: SOF: ipc4-topology: Preserve the DMA Link ID for ChainDMA on unprepare
+    - ASoC: amd: yc: Support mic on Lenovo Thinkpad E16 Gen 2
+    - kobject_uevent: Fix OOB access within zap_modalias_env()
+    - gve: Fix an edge case for TSO skb validity check
+    - ice: Add a per-VF limit on number of FDIR filters
+    - devres: Fix devm_krealloc() wasting memory
+    - devres: Fix memory leakage caused by driver API devm_free_percpu()
+    - irqdomain: Fixed unbalanced fwnode get and put
+    - irqchip/imx-irqsteer: Handle runtime power management correctly
+    - mm/numa_balancing: teach mpol_to_str about the balancing mode
+    - rtc: cmos: Fix return value of nvmem callbacks
+    - scsi: lpfc: Allow DEVICE_RECOVERY mode after RSCN receipt if in PRLI_ISSUE
+      state
+    - scsi: qla2xxx: During vport delete send async logout explicitly
+    - scsi: qla2xxx: Unable to act on RSCN for port online
+    - scsi: qla2xxx: Fix for possible memory corruption
+    - scsi: qla2xxx: Use QP lock to search for bsg
+    - scsi: qla2xxx: Reduce fabric scan duplicate code
+    - scsi: qla2xxx: Fix flash read failure
+    - scsi: qla2xxx: Complete command early within lock
+    - scsi: qla2xxx: validate nvme_local_port correctly
+    - perf: Fix event leak upon exit
+    - perf: Fix event leak upon exec and file release
+    - perf stat: Fix the hard-coded metrics calculation on the hybrid
+    - perf/x86/intel/uncore: Fix the bits of the CHA extended umask for SPR
+    - perf/x86/intel/ds: Fix non 0 retire latency on Raptorlake
+    - perf/x86/intel/pt: Fix topa_entry base length
+    - perf/x86/intel/pt: Fix a topa_entry base address calculation
+    - drm/i915/gt: Do not consider preemption during execlists_dequeue for gen8
+    - drm/amdgpu/sdma5.2: Update wptr registers as well as doorbell
+    - drm/udl: Remove DRM_CONNECTOR_POLL_HPD
+    - drm/dp_mst: Fix all mstb marked as not probed after suspend/resume
+    - drm/amdgpu: reset vm state machine after gpu reset(vram lost)
+    - drm/amd/amdgpu: Fix uninitialized variable warnings
+    - drm/i915/dp: Reset intel_dp->link_trained before retraining the link
+    - drm/i915/dp: Don't switch the LTTPR mode on an active link
+    - rtc: isl1208: Fix return value of nvmem callbacks
+    - rtc: abx80x: Fix return value of nvmem callback on read
+    - watchdog/perf: properly initialize the turbo mode timestamp and rearm
+      counter
+    - platform: mips: cpu_hwmon: Disable driver on unsupported hardware
+    - RDMA/iwcm: Fix a use-after-free related to destroying CM IDs
+    - selftests/sigaltstack: Fix ppc64 GCC build
+    - dm-verity: fix dm_is_verity_target() when dm-verity is builtin
+    - rbd: don't assume rbd_is_lock_owner() for exclusive mappings
+    - remoteproc: stm32_rproc: Fix mailbox interrupts queuing
+    - remoteproc: imx_rproc: Skip over memory region when node value is NULL
+    - remoteproc: imx_rproc: Fix refcount mistake in imx_rproc_addr_init
+    - MIPS: dts: loongson: Add ISA node
+    - MIPS: ip30: ip30-console: Add missing include
+    - MIPS: dts: loongson: Fix GMAC phy node
+    - MIPS: Loongson64: env: Hook up Loongsson-2K
+    - MIPS: Loongson64: Remove memory node for builtin-dtb
+    - MIPS: Loongson64: reset: Prioritise firmware service
+    - MIPS: Loongson64: Test register availability before use
+    - drm/etnaviv: don't block scheduler when GPU is still active
+    - drm/panfrost: Mark simple_ondemand governor as softdep
+    - rbd: rename RBD_LOCK_STATE_RELEASING and releasing_wait
+    - rbd: don't assume RBD_LOCK_STATE_LOCKED for exclusive mappings
+    - lib/build_OID_registry: don't mention the full path of the script in output
+    - video: logo: Drop full path of the input filename in generated file
+    - Bluetooth: btusb: Add RTL8852BE device 0489:e125 to device tables
+    - Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x13d3:0x3591
+    - minmax: scsi: fix mis-use of 'clamp()' in sr.c
+    - mm/mglru: fix ineffective protection calculation
+    - PCI/DPC: Fix use-after-free on concurrent DPC and hot-removal
+    - f2fs: fix to truncate preallocated blocks in f2fs_file_open()
+    - kdb: address -Wformat-security warnings
+    - kdb: Use the passed prompt in kdb_position_cursor()
+    - dmaengine: ti: k3-udma: Fix BCHAN count with UHC and HC channels
+    - phy: cadence-torrent: Check return value on register read
+    - phy: zynqmp: Enable reference clock correctly
+    - um: time-travel: fix time-travel-start option
+    - um: time-travel: fix signal blocking race/hang
+    - f2fs: fix start segno of large section
+    - watchdog: rzg2l_wdt: Use pm_runtime_resume_and_get()
+    - watchdog: rzg2l_wdt: Check return status of pm_runtime_put()
+    - f2fs: fix to update user block counts in block_operations()
+    - kbuild: avoid build error when single DTB is turned into composite DTB
+    - selftests/bpf: fexit_sleep: Fix stack allocation for arm64
+    - libbpf: Fix no-args func prototype BTF dumping syntax
+    - af_unix: Disable MSG_OOB handling for sockets in sockmap/sockhash
+    - dma: fix call order in dmam_free_coherent
+    - bpf, events: Use prog to emit ksymbol event for main program
+    - tools/resolve_btfids: Fix comparison of distinct pointer types warning in
+      resolve_btfids
+    - MIPS: SMP-CPS: Fix address for GCR_ACCESS register for CM3 and later
+    - ipv4: Fix incorrect source address in Record Route option
+    - net: bonding: correctly annotate RCU in bond_should_notify_peers()
+    - ice: Fix recipe read procedure
+    - netfilter: nft_set_pipapo_avx2: disable softinterrupts
+    - net: stmmac: Correct byte order of perfect_match
+    - net: nexthop: Initialize all fields in dumped nexthops
+    - bpf: Fix a segment issue when downgrading gso_size
+    - apparmor: Fix null pointer deref when receiving skb during sock creation
+    - powerpc: fix a file leak in kvm_vcpu_ioctl_enable_cap()
+    - lirc: rc_dev_get_from_fd(): fix file leak
+    - auxdisplay: ht16k33: Drop reference after LED registration
+    - ASoC: SOF: imx8m: Fix DSP control regmap retrieval
+    - spi: microchip-core: fix the issues in the isr
+    - spi: microchip-core: defer asserting chip select until just before write to
+      TX FIFO
+    - spi: microchip-core: only disable SPI controller when register value change
+      requires it
+    - spi: microchip-core: fix init function not setting the master and motorola
+      modes
+    - spi: microchip-core: ensure TX and RX FIFOs are empty at start of a transfer
+    - nvme-pci: Fix the instructions for disabling power management
+    - ASoC: sof: amd: fix for firmware reload failure in Vangogh platform
+    - spi: spidev: add correct compatible for Rohm BH2228FV
+    - ASoC: Intel: use soc_intel_is_byt_cr() only when IOSF_MBI is reachable
+    - ASoC: TAS2781: Fix tasdev_load_calibrated_data()
+    - ceph: fix incorrect kmalloc size of pagevec mempool
+    - s390/pci: Refactor arch_setup_msi_irqs()
+    - s390/pci: Allow allocation of more than 1 MSI interrupt
+    - s390/cpum_cf: Fix endless loop in CF_DIAG event stop
+    - iommu: sprd: Avoid NULL deref in sprd_iommu_hw_en
+    - io_uring: fix io_match_task must_hold
+    - nvme-pci: add missing condition check for existence of mapped data
+    - fs: don't allow non-init s_user_ns for filesystems without FS_USERNS_MOUNT
+    - md/raid0: don't free conf on raid0_run failure
+    - md/raid1: don't free conf on raid0_run failure
+    - io_uring: Fix probe of disabled operations
+    - cgroup/cpuset: Optimize isolated partition only generate_sched_domains()
+      calls
+    - cgroup/cpuset: Fix remote root partition creation problem
+    - x86/syscall: Mark exit[_group] syscall handlers __noreturn
+    - perf: arm_pmuv3: Avoid assigning fixed cycle counter with threshold
+    - md/raid5: recheck if reshape has finished with device_lock held
+    - hwmon: (ltc2991) re-order conditions to fix off by one bug
+    - arm64: smp: Fix missing IPI statistics
+    - arm64: dts: qcom: sc7280: Remove CTS/RTS configuration
+    - ARM: dts: qcom: msm8226-microsoft-common: Enable smbb explicitly
+    - OPP: Fix missing cleanup on error in _opp_attach_genpd()
+    - arm64: dts: qcom: sc8280xp-*: Remove thermal zone polling delays
+    - arm64: dts: ti: k3-am62-main: Fix the reg-range for main_pktdma
+    - arm64: dts: ti: k3-am62a-main: Fix the reg-range for main_pktdma
+    - arm64: dts: ti: k3-am62p-main: Fix the reg-range for main_pktdma
+    - arm64: dts: ti: k3-am62a7: Drop McASP AFIFOs
+    - arm64: dts: ti: k3-am62p5: Drop McASP AFIFOs
+    - arm64: dts: ti: k3-am62p5-sk: Fix pinmux for McASP1 TX
+    - arm64: dts: qcom: sc7180-trogdor: Disable pwmleds node where unused
+    - arm64: dts: mediatek: mt8192: Fix GPU thermal zone name for SVS
+    - arm64: dts: mediatek: mt8183-pico6: Fix wake-on-X event node names
+    - arm64: dts: renesas: r9a08g045: Add missing hypervisor virtual timer IRQ
+    - cpufreq/amd-pstate-ut: Convert nominal_freq to khz during comparisons
+    - wifi: mac80211: cancel multi-link reconf work on disconnect
+    - wifi: ath11k: refactor setting country code logic
+    - wifi: ath11k: restore country code during resume
+    - net: ethernet: cortina: Restore TSO support
+    - tcp: fix races in tcp_abort()
+    - hns3: avoid linking objects into multiple modules
+    - sched/core: Move preempt_model_*() helpers from sched.h to preempt.h
+    - sched/core: Drop spinlocks on contention iff kernel is preemptible
+    - net: dsa: ksz_common: Allow only up to two HSR HW offloaded ports for
+      KSZ9477
+    - libbpf: Skip base btf sanity checks
+    - wifi: mac80211: add ieee80211_tdls_sta_link_id()
+    - wifi: iwlwifi: fix iwl_mvm_get_valid_rx_ant()
+    - wifi: ath12k: advertise driver capabilities for MBSSID and EMA
+    - riscv, bpf: Fix out-of-bounds issue when preparing trampoline image
+    - perf/x86/amd/uncore: Avoid PMU registration if counters are unavailable
+    - perf/x86/amd/uncore: Fix DF and UMC domain identification
+    - NFSD: Fix nfsdcld warning
+    - net: page_pool: fix warning code
+    - bpf, arm64: Fix trampoline for BPF_TRAMP_F_CALL_ORIG
+    - Bluetooth: hci_event: Set QoS encryption from BIGInfo report
+    - Bluetooth: hci_core, hci_sync: cleanup struct discovery_state
+    - Bluetooth: Fix usage of __hci_cmd_sync_status
+    - tcp: Don't access uninit tcp_rsk(req)->ao_keyid in
+      tcp_create_openreq_child().
+    - drm/panel: ilitek-ili9882t: If prepare fails, disable GPIO before regulators
+    - drm/panel: ilitek-ili9882t: Check for errors on the NOP in prepare()
+    - drm/amd/display: Move 'struct scaler_data' off stack
+    - media: i2c: hi846: Fix V4L2_SUBDEV_FORMAT_TRY get_selection()
+    - drm/msm/dpu: fix encoder irq wait skip
+    - drm/msm/dpu: drop duplicate drm formats from wb2_formats arrays
+    - drm/msm/dp: fix runtime_pm handling in dp_wait_hpd_asserted
+    - perf maps: Switch from rbtree to lazily sorted array for addresses
+    - perf maps: Fix use after free in __maps__fixup_overlap_and_insert
+    - drm/bridge: samsung-dsim: Set P divider based on min/max of fin pll
+    - drm/i915/psr: Print Panel Replay status instead of frame lock status
+    - drm/mediatek: Set DRM mode configs accordingly
+    - drm/msm/dsi: set video mode widebus enable bit when widebus is enabled
+    - tools/perf: Fix the string match for "/tmp/perf-$PID.map" files in dso__load
+    - drm/amd/display: Add null check before access structs
+    - nfs: pass explicit offset/count to trace events
+    - PCI: endpoint: pci-epf-test: Make use of cached 'epc_features' in
+      pci_epf_test_core_init()
+    - PCI: tegra194: Set EP alignment restriction for inbound ATU
+    - riscv: smp: fail booting up smp if inconsistent vlen is detected
+    - clk: meson: s4: fix fixed_pll_dco clock
+    - clk: meson: s4: fix pwm_j_div parent clock
+    - usb: typec-mux: ptn36502: unregister typec switch on probe error and remove
+    - mtd: spi-nor: winbond: fix w25q128 regression
+    - iommufd/selftest: Fix dirty bitmap tests with u8 bitmaps
+    - iommufd/selftest: Fix iommufd_test_dirty() to handle <u8 bitmaps
+    - iommufd/selftest: Add tests for <= u8 bitmap sizes
+    - iommufd/selftest: Fix tests to use MOCK_PAGE_SIZE based buffer sizes
+    - iommufd/iova_bitmap: Check iova_bitmap_done() after set ahead
+    - clk: qcom: gcc-x1e80100: Fix halt_check for all pipe clocks
+    - dm-raid: Fix WARN_ON_ONCE check for sync_thread in raid_resume
+    - kvm: s390: Reject memory region operations for ucontrol VMs
+    - eeprom: ee1004: Call i2c_new_scanned_device to instantiate thermal sensor
+    - clk: qcom: gcc-x1e80100: Set parent rate for USB3 sec and tert PHY pipe clks
+    - workqueue: Introduce from_work() helper for cleaner callback declarations
+    - RDMA/hns: Fix mbx timing out before CMD execution is completed
+    - crypto: mxs-dcp - Ensure payload is zero when using key slot
+    - RDMA/mana_ib: Enable RoCE on port 1
+    - RDMA/mana_ib: set node_guid
+    - rtc: tps6594: Fix memleak in probe
+    - selftests/damon/access_memory: use user-defined region size
+    - md-cluster: fix hanging issue while a new disk adding
+    - power: supply: ab8500: Fix error handling when calling
+      iio_read_channel_processed()
+    - power: supply: ingenic: Fix some error handling paths in
+      ingenic_battery_get_property()
+    - remoteproc: mediatek: Don't attempt to remap l1tcm memory if missing
+    - remoteproc: k3-r5: Fix IPC-only mode detection
+    - mailbox: imx: fix TXDB_V2 channel race condition
+    - mailbox: mtk-cmdq: Move devm_mbox_controller_register() after
+      devm_pm_runtime_enable()
+    - mm: huge_memory: use !CONFIG_64BIT to relax huge page alignment on 32 bit
+      machines
+    - mm/huge_memory: avoid PMD-size page cache if needed
+    - thermal/drivers/broadcom: Fix race between removal and clock disable
+    - workqueue: Always queue work items to the newest PWQ for order workqueues
+    - ipv6: fix source address selection with route leak
+    - drm/xe: Use write-back caching mode for system memory on DGFX
+    - md/raid5: fix spares errors about rcu usage
+    - media: stm32: dcmipp: correct error handling in dcmipp_create_subdevs
+    - tpm_tis_spi: add missing attpm20p SPI device ID entry
+    - sysctl: always initialize i_uid/i_gid
+    - media: i2c: Kconfig: Fix missing firmware upload config select
+    - genirq: Set IRQF_COND_ONESHOT in request_irq()
+    - cpufreq: qcom-nvmem: fix memory leaks in probe error paths
+    - leds: triggers: Flush pending brightness before activating trigger
+    - media: i2c: alvium: Move V4L2_CID_GAIN to V4L2_CID_ANALOG_GAIN
+    - KVM: nVMX: Add a helper to get highest pending from Posted Interrupt vector
+    - KVM: nVMX: Check for pending posted interrupts when looking for nested
+      events
+    - ALSA: hda/realtek: cs35l41: Fixup remaining asus strix models
+    - fbdev: vesafb: Detect VGA compatibility from screen info's VESA attributes
+    - drm/fbdev-dma: Fix framebuffer mode for big endian devices
+    - xhci: Apply XHCI_RESET_TO_DEFAULT quirk to TGL
+    - dmaengine: fsl-edma: clean up unused "fsl,imx8qm-adma" compatible string
+    - dmaengine: fsl-edma: change the memory access from local into remote mode in
+      i.MX 8QM
+    - clk: samsung: fix getting Exynos4 fin_pll rate from external clocks
+    - bus: mhi: ep: Do not allocate memory for MHI objects from DMA zone
+    - ASoC: SOF: ipc4-topology: Use correct queue_id for requesting input pin
+      format
+    - arch: um: rust: Use the generated target.json again
+    - f2fs: fix null reference error when checking end of zone
+    - selftests: forwarding: skip if kernel not support setting bridge fdb
+      learning limit
+    - xsk: Require XDP_UMEM_TX_METADATA_LEN to actuate tx_metadata_len
+    - drm/xe/exec: Fix minor bug related to xe_sync_entry_cleanup
+    - thermal: trip: Split thermal_zone_device_set_mode()
+    - apparmor: unpack transition table if dfa is not present
+    - i3c: mipi-i3c-hci: Fix number of DAT/DCT entries for HCI versions < 1.1
+    - selinux,smack: remove the capability checks in the removexattr hooks
+    - selftests/bpf: DENYLIST.aarch64: Skip fexit_sleep again
+    - nilfs2: handle inconsistent state in nilfs_btnode_create_block()
+    - Upstream stable to v6.6.44, v6.10.3
+  * Noble update: upstream stable patchset 2024-09-30 (LP: #2083196) //
+    CVE-2024-42284
+    - tipc: Return non-zero value from tipc_udp_addr2str() on error
+  * CVE-2024-44987
+    - ipv6: prevent UAF in ip6_send_skb()
+  * CVE-2024-42301
+    - dev/parport: fix the array out-of-bounds risk
+  * CVE-2024-44998
+    - atm: idt77252: prevent use after free in dequeue_rx()
+
+  [ Ubuntu: 6.8.0-49.49 ]
+
+  * noble/linux: 6.8.0-49.49 -proposed tracker (LP: #2085942)
+  * CVE-2024-46800
+    - sch/netem: fix use after free in netem_dequeue
+  * mm/folios: xfs hangs with hung task timeouts with corrupted folio pointer
+    lists (LP: #2085495)
+    - lib/xarray: introduce a new helper xas_get_order
+    - mm/filemap: return early if failed to allocate memory for split
+    - mm/filemap: optimize filemap folio adding
+  * CVE-2024-43882
+    - exec: Fix ToCToU between perm check and set-uid/gid usage
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 04 Dec 2024 13:04:13 +0900
+
+linux-qcom (6.8.0-1014.14) jammy; urgency=medium
+
+  * [RB3] CONFIG_KASAN_GENERIC report potential memory bug in tc956x_pcie_eth
+    - SAUCE: ubuntu/qcom/qps615: suppress KASAN error
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: arm64: dts: qcom: remove redundant code in qcs6490.dtsi
+
+  * Miscellaneous upstream changes
+    - QCLINUX: data-eth: qps615: Properly set HW address assign type property
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 24 Oct 2024 22:10:11 +0900
+
+linux-qcom (6.8.0-1013.13) jammy; urgency=medium
+
+  * "[RB3] tc956x_pci-eth errors found in dmesg"
+    - SAUCE: ubuntu/qcom/qps615: suppress false alerts
+    - SAUCE: ubuntu/qcom/qps615: use INFO level for logging
+
+  * [RB3] drm sde error/ msm-dsi-error found in dmesg
+    - SAUCE: do not show error on EPROBE_DEFER
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: arm64: dts: qcom: enable WIFI
+    - SAUCE: import external DT from GA 1.2
+    - SAUCE: Add Makefile code to apply overlays for GA1.2
+    - SAUCE: ubuntu/qcom/display: import qcm6490 display code from GA1.2
+    - SAUCE: ubuntu/qcom/graphics: import qcm6490 graphics driver code from GA1.2
+    - SAUCE: ubuntu/qcom/camera: import qcm6490 camera driver code from GA1.2
+    - SAUCE: ubuntu/qcom/qps615: import ethernet driver from GA1.2
+    - SAUCE: ubuntu/qcom/video: import video driver from GA 1.2
+    - SAUCE: ubuntu/qcom/touch: import touch driver from GA 1.2
+    - SAUCE: ubuntu/qcom: build external drivers
+    - SAUCE: ubuntu/qcom/camera: fix build warnings and errors
+    - SAUCE: suppress unneeded build logs
+    - SAUCE: ubuntu/qcom: suppress warning and error
+    - SAUCE: ubuntu/qcom/graphics: change strtobool() to kstrtobool()
+    - SAUCE: ubuntu/qcom/graphics: dynamically allocate the kgsl-pool shrinker for
+      kernel>=6.7
+    - SAUCE: ubuntu/qcom/camera: remove unused camera_banner
+    - SAUCE: ubuntu/qcom/camera: use sizeof() instead of V4L2_SUBDEV_NAME_SIZE
+    - SAUCE: ubuntu/qcom/camera: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/video: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/touch: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: auto-load module
+    - SAUCE: ubuntu/qcom: add missing inclusion
+    - SAUCE: ubuntu/qcom/display: Rename min_buffers_needed to min_queued_buffers
+    - SAUCE: ubuntu/qcom: remove DRM_UNLOCKED
+    - SAUCE: ubuntu/qcom/display: suppress EPROBE_DEFER error log
+    - SAUCE: rename qcom,phy-rst-gpio to qcom,phy-rst-gpio-id
+    - SAUCE: Revert "PENDING: arm64: dts: qcom: qcs6490-rb3gen2: Enable IMX577
+      camera sensor"
+    - SAUCE: ASoC: wsa883x:  suppress noisy pr_err
+
+  * Miscellaneous upstream changes
+    - Revert "rpmsg: glink: Introduce packet tracepoints"
+    - PENDING: arm64: dts: qcom: sa8775p: add TBU support
+    - QCLINUX: coresight: add etr ATID filter function support
+    - PENDING: ASOC: WSA883X: Add swr slave dev number kcontrol
+    - FROMLIST: arm64: dts: qcom: sc7280: Add PCIe0 node
+    - QCLINUX: arm64: defconfig: qcom: Enable BT_BNEP
+    - QCLINUX: arm64: dts: qcom: sa8775p-ride: add board id and msm id support
+    - PENDING: coresight: tmc: Fix byte-cntr irq count mismatch issue
+    - QCLINUX: arm64: qcom_debug: Enable ATH trace
+    - QCLINUX: arm64: dts: qcom: sa8775p: Disable gunyah watchdog
+    - PENDING: arm64: dts: qcom: sa8775p: Add tz-log node
+    - QCLINUX: arm64: defconfig: qcom: Enable UINPUT
+    - PENDING: arm64: dts: qcom: sa8775: add QCrypto nodes
+    - PENDING: arm64: dts: qcom: sa8775p: add coresight components
+    - QCLINUX: arm64: dts: qcom: sa8775p: addons: add coresight components
+    - QCLINUX: net: can: Add support for mcp25xxfd driver
+    - BACKPORT: FROMLIST: wifi: ath11k: Add firmware coredump collection support
+    - QCLINUX: arm64: defconfig: Enable ATH reg setting
+    - PENDING: media: qcom: camss: Designate lite subdevices in resources
+    - PENDING: thermal: qcom: Add support for MBG Temp monitor
+    - FROMLIST: soc: qcom: icc-bwmon: Allow for interrupts to be shared across
+      instances
+    - PENDING: dt-bindings: iio: Add ADC5 GEN3 Channel macros
+    - PENDING: arm64: dts: qcom: sa8775p: Add cpu and llcc BWMON
+    - QCLINUX: ASoC: qcom: qcm6490: Add sound card compatible for qcs6490 rb3gen2
+      mezzanine boards
+    - QCLINUX: arm64: dts: qcom: qcm6490-rb3: Add uart4 node for RB3GEN2 video-
+      mezz
+    - BACKPORT: FROMLIST: iio: adc: Add support for QCOM PMIC5 Gen3 ADC
+    - PENDING: arm64: dts: qcom: sc7280: Add support for camss
+    - PENDING: arm64: dts: qcom: sa8775p: add remaining coresight components
+    - QCLINUX: arm64: dts: qcom: Remove iommu enc dec data from venus node
+    - PENDING: ARM: dts: qcom: Add support for MBG TM for pm8775
+    - PENDING: dt-bindings: clock: qcom: Add qdss_xo clock SA8775P
+    - PENDING: clk: qcom: Add support for qdss_xo clock for SA8775P
+    - PENDING: arm64: dts: qcom: sa8775p: add dma-coherent for smmu
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add dcc device tree node
+    - QCLINUX: arm64: dts: qcom: Add memory dump table on SA8775p
+    - PENDING: arm64: dts: qcom: sa8775p: Add fastrpc nsession property
+    - PENDING: arm64: dts: qcom: qcs6490-rb3gen2: Enable IMX577 camera sensor
+    - PENDING: i2c: Enable IMX577 camera sensor for qcm6490
+    - QCLINUX: arm64: defconfig: qcom: Enable IMX577 module support
+    - QCLINUX: arm64: qcom_debug: Enable ath11k coredump
+    - QCLINUX: ASoC: qcom: qcm6490: Update widgets for rb3gen2-ia-mezz board
+    - PENDING: misc: dcc: Fix invalid character issue
+    - QCLINUX: ASoC: qcm6490: Add sound card support for QCS9100
+    - PENDING: arm64: dts: qcom: sa8775p: add NSP0 fastrpc-compute-cb nodes
+    - QCLINUX: arm64: dts: qcom: Add board-id and msm-id for Rb3Gen2
+    - PENDING: arm64: dts: qcom: sa8775p: Add QFPROM node
+    - PENDING: arm64: dts: qcom: sa8775p: Correct the device name for TPDM and CTI
+    - QCLINUX: arm64: defconfig: Update memory configs
+    - PENDING: arm64: dts: qcom: sa8775p: Add memory region for audioPD
+    - FROMLIST: coresight: Add support to get preferred id for system trace
+      sources
+    - FROMLIST: coresight: dummy: Add reserve atid support for dummy source
+    - QCLINUX: virt: gunyah: Zero state_data after vcpu_run
+    - QCLINUX: arm64: defconfig: qcom: Enable MBG TM and ADC5 Gen3
+    - QCLINUX: arm64: dts: qcom: sa8775p: addons: Correct the device name for
+    - QCLINUX: arm64: dts: qcom: Add trace-id of modem_diag for qcm6490
+    - PENDING: misc: fastrpc: Fix registered buffer page address
+    - PENDING: arm64: dts: qcom: qcm6490: Use existing tcsr_2 node from sc7280
+    - PENDING: pinctrl: qcom: Add sa8775p lpass lpi pinctrl driver
+    - PENDING: opp: add a new helper set_opp api
+    - PENDING: can: mcp251xfd: enable CAN transceiver using gpio_0
+    - PENDING: arm64: config: Enable MCP251x CAN Device
+    - QCLINUX: ASoC: codecs: msm-stub: Add AIF2 dai support for LPI MI2S interface
+    - PENDING: arm64: dts: qcom: Add MCP251xFD CAN Controller
+    - PENDING: firmware: arm_scmi: add qcom smc xport descriptor
+    - QCLINUX: arm64: dts: qcom: sa8775p: Remove status override for watchdog node
+    - PENDING: arm64: dts: qcom: sc7280: Add device name for CTIs
+    - QCLINUX: arm64: defconfig: Enable LPASS LPI SA8775P pinctrl
+    - PENDING: crypto: qce - Add command descriptor support for crypto driver
+    - QCLINUX: usb: dwc3: core: Set driver data before core init
+    - QCLINUX: ASoC: qcom: qcm6490: Remove LPASS_CDC_DMA_TX3 dai id from
+      qcm6490_snd_init
+    - QCLINUX: ASoC: codecs: wcd937x: Add conditional regulator control for
+      wcd937x
+    - QCLINUX: coresight: tpdm: Correct the TPDA Key
+    - QCLINUX: arm64: dts: qcom: Bringup wcd9375 headphone on rb3gen2-ia-mezz
+      board
+    - PENDING: soc: qcom: socinfo: add SoC Info support for QCS9100 platform
+    - PENDING: dt-bindings: arm: qcom,ids: Add SoC ID for QCS9100
+    - PENDING: arm64: dts: qcom: sa8775p: Add gpr device tree node for ADSP
+    - PENDING: soc: qcom: socinfo: add SoC Info support for QCM6490 and QCS6490
+      platform
+    - PENDING: dt-bindings: arm: qcom,ids: Add SoC ID for QCM6490 and QCS6490
+    - PENDING: pinctrl: sa8775p: Update function and group binding
+    - QCLINUX: ASoC: qcom: qcm6490: Add AIF2 dapm pinctrl widget for QCS9100
+    - PENDING: arm64: dts: qcom: sa8775p: Add TCSR halt register space
+    - QCLINUX: soc: qcom: Update soc wdt node only for sc7280
+    - PENDING: arm64: qcom: dts: sa8775p: Add psci sys_reset2 modes
+    - QCLINUX: soc: qcom: Add documentation to align with code
+    - PENDING: arm64: dts: qcom: sa8775p: add rdbg nodes
+    - PENDING: gunyah: Add support for tracking Guest VM run time
+    - QCLINUX: arm64: dts: qcom: Add qcm6490 IDP dts file
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add lpass_tlmm node for lpi pinctrl
+    - PENDING: drivers: char: add remote debugger driver support for cDSP1
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add sound node for qcs9100 ridesx target
+    - PENDING: coresight: tmc: Remove duplicated ETR disable HW
+    - PENDING: arm64: dts: qcom: sc7280: Add msr properties to TPDMs
+    - QCLINUX: arm64: dts: qcom: Enable the uart for Rb3gen2-IA-MEZZ board
+    - QCLINUX: arm64: dts: qcom: Bring up LED-GPIO for Rb3gen2-IA-MEZZ board
+    - PENDING: ARM: dts: qcom: sa8775p: Update VADC interrupt-name
+    - QCLINUX: arm64: dts: qcom: Bring up I2C switch for Rb3gen2-IA-MEZZ board
+    - QCLINUX: arm64: deconfig: qcom: Enable vfio driver
+    - QCLINUX: arm64: deconfig: qcom: Enable mhi_bus_ep driver
+    - FROMLIST: iommu/arm-smmu-qcom: NULL pointer check for driver data
+    - QCLINUX: Revert "QCLINUX: net: can: Add support for mcp25xxfd driver"
+    - QCLINUX: qcom: tz_log: enable tz_log support hypervisor
+    - QCLINUX: coresight: Use desc name to get the CSR node
+    - QCLINUX: arm64: dts: qcom: Bring up TPM for Rb3gen2-IA-MEZZ board
+    - QCLINUX: arm64: defconfig: Enable NULL TTY for VM's
+    - QCLINUX: arm64: deconfig: qcom: disable smccc_trng driver
+    - QCLINUX: coresight: Enable ETR ATID filter for remote-etm
+    - PENDING: coresight: Disable RTB for coresight-stm
+    - PENDING: arm64: dts: qcom: sa8775p: Add protection-domain support for APM
+      and PRM
+    - PENDING: wifi: ath11k: fix vmalloc-out-of-bounds
+    - PENDING: arm64: dts: qcom: qcs6490-rb3gen2: Update the io-channels
+    - QCLINUX: arm64: defconfig: Remove unused VM config
+    - QCLINUX: coresight: Add extended CTI support
+    - QCLINUX: coresight: Remote-etm can probe successfully without ATID
+    - PENDING: iommu/arm-smmu-qcom: Fix compilation error
+    - QCLINUX: arm64: defconfig: Update VM memory and cpu configs
+    - QCLINUX: firmware: qcom_scm_addon:  Add qcom_she_op and
+      qcom_scm_ddrbw_profiler scm calls
+    - FROMLIST: arm64: dts: qcom: sa8775p: Add capacity and DPC properties
+    - QCLINUX: arm64: dts: restore wlan_ce_mem node
+    - QCLINUX: clk: qcom: dispcc1-sa8775p: Reparent dptx crypto RCG's to XO
+    - PENDING: arm64: dts: qcom: sa8775p: Correct the names of TPDMs
+    - PENDING: ath11k: Send pdev suspend before sending qmi mode off
+    - PENDING: dt-bindings: arm: qcom: add the SoC ID for SA8255P
+    - PENDING: soc: qcom: socinfo: add support for SA8255P
+    - PENDING: ARM64: dts: qcom: sa8775p: change camera PIL memory to 7MB
+    - PENDING: iommu/arm-smmu: add ACTLR data and support for sa8775p
+    - PENDING: arm64: dts: qcom: Add L3 interconnect device for SA8775P
+    - PENDING: interconnect: qcom: Add EPSS L3 support on SA8775P
+    - PENDING: usb: dwc3: Redesign flattening implementation
+    - PENDING: pinctrl: sa8775p: Add support for SA8255p SoC
+    - QCLINUX: smcinvoke: Add support hypervisor of shmbridge
+    - BACKPORT: wifi: mac80211: track capability/opmode NSS separately
+    - QCLINUX: drm/msm: Avoid probing gpu device
+    - QCLINUX: arm64: dts: qcom: sa8775p: addons: Enable byte-cntr for ETR1
+    - dt-bindings: net: Document QCA808x PHYs
+    - PENDING: dt-bindings: arm: qcom,ids: add SoC ID for QCS8300/QCS8275
+    - PENDING: soc: qcom: socinfo: add QCS8300/QCS8275 SoC ID
+    - PENDING: dt-bindings: pinctrl: describe qcs8300-tlmm
+    - PENDING: dt-bindings: qcom,pdc: document QCS8300 Power Domain Controller
+    - PENDING: arm64: dts: qcom: Add L3/DDR freq scaling from cpufreq on SA8775P
+    - QCLINUX: arm64: defconfig: qcom: Enable WLAN debug configs
+    - PENDING: pinctrl: qcom: add the tlmm driver for QCS8300 platforms
+    - FROMLIST: arm64: dts: qcom: sa8775p-ride: Add QCS9100 compatible
+    - PENDING: dt-bindings: clock: qcom: Add GCC clocks for QCS8300
+    - PENDING: clk: qcom: Add support for Global Clock Controller on QCS8300
+    - PENDING: dt-bindings: interconnect: Add Qualcomm QCS8300 DT bindings
+    - QCLINUX: arm64: defconfig: enable arm64 pmem
+    - PENDING: interconnect: qcom: add QCS8300 interconnect provider driver
+    - PENDING: dt-bindings: clock: qcom: Add GPU clocks for QCS8300
+    - PENDING: dt-bindings: power: qcom,rpmpd: document qcs8300
+    - PENDING: arm64: dts: qcom: Add static vote for SA8775P
+    - PENDING: arm64: dts: qcom: add initial support for QCS8300 DTSI
+    - PENDING: arm64: dts: qcom: add base QCS8300 RIDE dts
+    - QCLINUX: arm64: dts: qcom: Add addons support for QCS8300
+    - PENDING: arm64: dts: qcom: qcs8300: Add IMEM, PIL info and download mode
+      region
+    - QCLINUX: arm64: dts: qcom: qcs8300: define kaslr offset and mem dump table
+      regions
+    - QCLINUX: arm64: dts: qcom: qcs8300: addons: Add CSR device
+    - QCLINUX: arm64: deconfig: enable clock controller, interconnect and pinctrl
+      for QCS8300
+    - PENDING: soc: qcom: llcc: add errata to get bank num
+    - PENDING: soc: qcom: llcc: Add llcc configuration support for the QCS8300
+      platform
+    - PENDING:arm64: dts: qcom: qcs8300: Add qmp device nodes
+    - PENDING: arm64: dts: qcom: qcs8300: Add llcc support for the QCS8300
+      platform
+    - PENDING: drivers: phy: qualcomm: qmp-ufs qcs8300 compatible
+    - PENDING: dt-bindings: clock: qcom: Add CAMCC clocks for QCS8300
+    - QCLINUX: arm64: dts: qcom: Add qcs5430 dts support
+    - PENDING: arm64: dts: qcom: qcs8300: Add interconnect device nodes
+    - PENDING: arm64: dts: qcom: qcs8300: Add support for cpufreq hw
+    - QCLINUX: arm64: defconfig: Add Aquantia AQR115C config
+    - PENDING: net: stmmac: dwmac-qcom-ethqos: add support for emac4 on qcs8300
+      platforms
+    - PENDING: arm64: dts: qcom: qcs8300: add the SGMII PHY node
+    - FROMGIT: Bluetooth: SMP: Fix assumption of Central always being Initiator
+    - QCLINUX: arm64: dts: qcom: qcs8300: Add dma-buf heaps support
+    - PENDING: arm64: dts: qcom: qcs8300: add rpmhpd dts node
+    - PENDING: arm64: dts: qcom: qcs8300: Add regulators dts node
+    - PENDING: phy: qcom: add support for SGMII SerDes PHY on qcs8300 platform
+    - PENDING: clk: qcom: Add support for Camera Clock Controller on QCS8300
+    - PENDING: clk: qcom: Add support for GPU Clock Controller on QCS8300
+    - PENDING: arm64: dts: qcom: qcs8300: add coresight components
+    - QCLINUX: arm64: dts: qcom: qcs8300: Add dcc device tree node
+    - PENDING: arm64: dts: qcom: qcs8300: add the first 1Gb ethernet interface
+    - PENDING: arm64: dts: qcom: qcs8300-ride: enable the SerDes PHY
+    - PENDING: arm64: dts: qcom: qcs8300-ride: add pin functions for ethernet0
+    - PENDING: arm64: dts: qcom: qcs8300-ride: enable ethernet0
+    - PENDING: arm64: dts: qcom: qcs8300: add UFS nodes
+    - PENDING: arm64: dts: qcom: qcs8300: add the pcie smmu node
+    - PENDING: arm64: dts: qcom: qcs8300-ride: Add ufs mem
+    - PENDING: dmaengine: qcom: bam_dma: Correct descriptor FIFO size
+    - PENDING: arm64: dts: qcom: qcs8300: Add clock controllers support
+    - PENDING: remoteproc: qcom: pas: Add QCS8300 CDSP support
+    - PENDING: remoteproc: qcom: disable remoteproc auto boot for wpss
+    - PENDING: ARM: dt: add extended SPI specifier
+    - PENDING: arm64: dts: qcom: Add support for SA8255p Ride platform
+    - PENDING: arm64: dts: QCS8300: Add device node for gfx_smmu
+    - FROMLIST: misc: fastrpc: Add support for multiple PD from one process
+    - PENDING: arm64: dts: qcom: qcs8300: add CDSP support
+    - PENDING: arm64: dts: qcom: qcs8300-ride: enable CDSP for QCS8300
+    - PENDING: phy: qcom: Add support for eDP PHY on sa8775p
+    - PENDING: arm64: dts: qcom: qcs8300: add ADSP GPDSP support
+    - PENDING: arm64: dts: qcom: qcs8300-ride: enable ADSP GPDSP for QCS8300
+    - PENDING: arm64: dts: qcom: qcs8300: Add spmi bus
+    - QCLINUX: arm64: dts: qcom: qcs8300: addons: Add memory dump table
+    - PENDING: clk: qcom: gcc-qcs8300: Fixup the copyright
+    - PENDING: drm/msm/dp: Add DisplayPort controller for SA8775P
+    - PENDING: arm64: dts: qcom: mark ethernet devices as DMA-coherent
+    - PENDING: arm64: dts: qcom: sa8255p: enable safety IRQ
+    - PENDING: remoteproc: qcom: pas: Add QCS8300 ADSP GPDSP support
+    - FROMLIST: misc: fastrpc: Save actual DMA size in fastrpc_map structure
+    - FROMLIST: misc: fastrpc: Fix fastrpc_map_lookup operation
+    - FROMLIST: misc: fastrpc: Skip reference for DMA handles
+    - PENDING: phy: qcom: qmp: Add qmp conifguration for QCS8300
+    - PENDING: drm/msm: mdss: Add SA8775P support
+    - PENDING: drm/msm/dpu: Add SA8775P support
+    - QCLINUX: arm64: dts: qcom: qcm6490-rb3: Add uart4 node for RB3GEN2 vision-
+      mezz
+    - PENDING: arm64: dts: qcom: qcs8300: add "clock-names" property
+    - PENDING:wifi: ath11k: support DBS and DFS compatibility
+    - PENDING: pmdomain: qcom: rpmhpd: Add qcs8300 power domains
+    - QCLINUX: arm64: defconfig: Revert Add Aquantia AQR115C config
+    - QCLINUX: qcom: tz_log: differentiate hlos and hypversior of creating
+      shmbridge
+    - BACKPORT: FROMGIT: soc: qcom: smp2p: Introduce tracepoint support
+    - FROMLIST: wifi: ath11k: Fix double free issue during SRNG deinit
+    - PENDING: arm64: dts: qcom: Add support for usb nodes on QCS8300
+    - PENDING: arm64: dts: qcom: sa8775p: add display dt nodes
+    - QCLINUX: coresight: Correct the loglevel of the log info
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add spi dev node for qcs100 ridesx
+      target
+    - PENDING: arm64: dts: qcom: qcs8300: Add QUPv3 configuration
+    - PENDING: arm64: dts: qcom: sa8775p: Add DisplayPort device node
+    - PENDING: arm64: dts: qcom: Enable USB controllers for QCS8300
+    - PENDING: smcinvoke: Decrement the server object ref count in mutex context
+    - QCLINUX: defconfig: Enable SKBEDIT AND CLS TC utilities
+    - PENDING: coresight: tmc: flush remaining data when ETR is disabled
+    - QCLINUX: Revert "drivers: core: synchronize really_probe() and dev_uevent()"
+    - PENDING: drm/bridge: anx7625: change the gpio_set_value API
+    - PENDING: Bluetooth: mgmt: Verify cmd pending status before removing it
+    - PENDING: remoteproc: qcom: pas: fix QCS8300 GPDSP support
+    - PENDING: Bluetooth: mgmt: Verify command pending status before removing it
+    - QCLINUX: arm64: dts: qcom: sa8775p: Enable HS MI2S
+    - QCLINUX: ASoC: qcm6490: Add AIF0 and AIF3 for qcs9100
+    - QCLINUX: ASoC: codecs: msm-stub: Add AIF0 and AIF3 DAIs
+    - QCLINUX: ASoC: qcm6490: add macro and dcodec clk for qcs9100
+    - QCLINUX: arm64: dts: qcom: sa8775p: add dcodec and macro clk
+    - QCLINUX: arm64: dts: qcom: Add HSP dts support
+    - QCLINUX: arm64: dts: qcom: Add HSP BT dts support
+    - QCLINUX: arm64: dts: qcom: Disable MPSS on HSP dts
+    - QCLINUX: arm64: dts: qcom: Add PCIe node on HSP
+    - PENDING: arm64: dts: qcom: sc7280: add ICE node
+    - PENDING: qcom: ice: Remove ice probe
+    - QCLINUX: mmc: host: support wrapped keys in mmc
+    - PENDING: mmc: host: add support to derive software secret
+    - PENDING: mmc: host: add support for generate, import and prepare keys
+    - PENDING: mmc: host: wrapped keys support in mmc qcom
+    - PENDING: mmc: host: implement derive sw secret vop in mmc qcom
+    - PENDING: mmc: host: support for generate, import and prepare key
+    - PENDING: arm64: defconfig: qcom: Enable MMC crypto
+    - QCLINUX: net: qrtr: mhi: synchronize qrtr and mhi preparation
+    - PENDING: ath11k: Fix CE offset address calculation for WCN6750 in SSR
+    - QCLINUX: rpmsg: glink: multi enter for unregister path
+    - PENDING: arm64: dts: qcom: sa8775p: Update memory map for SA8775P
+    - Ubuntu: [Config] update CONFIG options for GA 1.2
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 18 Oct 2024 18:49:17 +0900
+
+linux-qcom (6.8.0-1012.12) jammy; urgency=medium
+
+  * perf build disables tracepoint support (LP: #2076190)
+    - [Packaging] add libtraceevent as dependency
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 04 Oct 2024 12:13:50 +0900
+
+linux-qcom (6.8.0-1011.11) jammy; urgency=medium
+
+  * "[RB3] tc956x_pci-eth errors found in dmesg"
+    - SAUCE: ubuntu/qcom/qps615: suppress false alerts
+    - SAUCE: ubuntu/qcom/qps615: use INFO level for logging
+
+  * "[RB3] slim-ngd-ctrl error found in dmesg"
+    - SAUCE: qcom-ngd-ctrl: suppress "QMI handle is NULL" error
+    - SAUCE: qcom-ngd-ctrl: fix race condition for completion
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] remove modules-extra package
+
+  [ Ubuntu: 6.8.0-48.48 ]
+
+  * noble/linux: 6.8.0-48.48 -proposed tracker (LP: #2082437)
+  * [SRU][Noble] Bad EPP defaults cause performance regressions on select Intel
+    CPUs (LP: #2077470)
+    - x86/cpu/vfm: Update arch/x86/include/asm/intel-family.h
+    - cpufreq: intel_pstate: Allow model specific EPPs
+    - cpufreq: intel_pstate: Update default EPPs for Meteor Lake
+    - cpufreq: intel_pstate: Switch to new Intel CPU model defines
+    - cpufreq: intel_pstate: Update Meteor Lake EPPs
+    - cpufreq: intel_pstate: Use Meteor Lake EPPs for Arrow Lake
+    - cpufreq: intel_pstate: Update Balance performance EPP for Emerald Rapids
+  * power: Enable intel_rapl driver (LP: #2078834)
+    - powercap: intel_rapl: Add support for ArrowLake-H platform
+  * x86/vmware: Add TDX hypercall support (LP: #2077729)
+    - x86/vmware: Introduce VMware hypercall API
+    - x86/vmware: Add TDX hypercall support
+  * Guest crashes post migration with migrate_misplaced_folio+0x4cc/0x5d0
+    (LP: #2076866)
+    - mm/mempolicy: use numa_node_id() instead of cpu_to_node()
+    - mm/numa_balancing: allow migrate on protnone reference with
+      MPOL_PREFERRED_MANY policy
+    - mm: convert folio_estimated_sharers() to folio_likely_mapped_shared()
+    - mm: factor out the numa mapping rebuilding into a new helper
+    - mm: support multi-size THP numa balancing
+    - mm/migrate: make migrate_misplaced_folio() return 0 on success
+    - mm/migrate: move NUMA hinting fault folio isolation + checks under PTL
+    - mm: fix possible OOB in numa_rebuild_large_mapping()
+  * Add 'mm: hold PTL from the first PTE while reclaiming a large folio' to fix
+    L2 Guest hang during LTP Test (LP: #2076147)
+    - mm: hold PTL from the first PTE while reclaiming a large folio
+  * KOP L2 guest fails to boot with 1 core - SMT8 topology (LP: #2070329)
+    - KVM: PPC: Book3S HV nestedv2: Add DPDES support in helper library for Guest
+      state buffer
+    - KVM: PPC: Book3S HV nestedv2: Fix doorbell emulation
+  * L2 Guest migration: continuously dumping while running NFS guest migration
+    (LP: #2076406)
+    - KVM: PPC: Book3S HV: Fix the set_one_reg for MMCR3
+    - KVM: PPC: Book3S HV: Fix the get_one_reg of SDAR
+    - KVM: PPC: Book3S HV: Add one-reg interface for DEXCR register
+    - KVM: PPC: Book3S HV nestedv2: Keep nested guest DEXCR in sync
+    - KVM: PPC: Book3S HV: Add one-reg interface for HASHKEYR register
+    - KVM: PPC: Book3S HV nestedv2: Keep nested guest HASHKEYR in sync
+    - KVM: PPC: Book3S HV: Add one-reg interface for HASHPKEYR register
+    - KVM: PPC: Book3S HV nestedv2: Keep nested guest HASHPKEYR in sync
+  * perf build disables tracepoint support (LP: #2076190)
+    - [Packaging] perf: reenable libtraceevent
+  * Please backport the more restrictive XSAVES deactivation for  Zen1/2 arch
+    (LP: #2077321)
+    - x86/CPU/AMD: Improve the erratum 1386 workaround
+  * Fix alsa scarlett2 driver in 6.8  (LP: #2076402)
+    - ALSA: scarlett2: Move initialisation code lower in the source
+    - ALSA: scarlett2: Implement handling of the ACK notification
+  * rtw89: reset IDMEM mode to prevent download firmware failure (LP: #2077396)
+    - wifi: rtw89: 885xb: reset IDMEM mode to prevent download firmware failure
+  * CVE-2024-43858
+    - jfs: Fix array-index-out-of-bounds in diFree
+  * CVE-2024-42280
+    - mISDN: Fix a use after free in hfcmulti_tx()
+  * CVE-2024-42271
+    - net/iucv: fix use after free in iucv_sock_close()
+  * [Ubuntu-24.04] FADump with recommended crash size is making the L1 hang
+    (LP: #2060039)
+    - powerpc/64s/radix/kfence: map __kfence_pool at page granularity
+  * Noble update: upstream stable patchset 2024-09-09 (LP: #2079945)
+    - ocfs2: add bounds checking to ocfs2_check_dir_entry()
+    - jfs: don't walk off the end of ealist
+    - fs/ntfs3: Add a check for attr_names and oatbl
+    - fs/ntfs3: Validate ff offset
+    - usb: gadget: midi2: Fix incorrect default MIDI2 protocol setup
+    - ALSA: hda/realtek: Enable headset mic on Positivo SU C1400
+    - ALSA: hda/realtek: Fix the speaker output on Samsung Galaxy Book Pro 360
+    - arm64: dts: qcom: qrb4210-rb2: switch I2C2 to i2c-gpio
+    - arm64: dts: qcom: msm8996: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: sm6350: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: ipq6018: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: sdm630: Disable SS instance in Parkmode for USB
+    - ALSA: pcm_dmaengine: Don't synchronize DMA channel when DMA is paused
+    - ALSA: seq: ump: Skip useless ports for static blocks
+    - filelock: Fix fcntl/close race recovery compat path
+    - tun: add missing verification for short frame
+    - tap: add missing verification for short frame
+    - s390/mm: Fix VM_FAULT_HWPOISON handling in do_exception()
+    - ALSA: hda/tas2781: Add new quirk for Lenovo Hera2 Laptop
+    - arm64: dts: qcom: sc7180: Disable SuperSpeed instances in park mode
+    - arm64: dts: qcom: sc7280: Disable SuperSpeed instances in park mode
+    - arm64: dts: qcom: qrb2210-rb1: switch I2C2 to i2c-gpio
+    - arm64: dts: qcom: msm8998: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: ipq8074: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: sdm845: Disable SS instance in Parkmode for USB
+    - Upstream stable to v6.6.43, v6.9.12
+  * Noble update: upstream stable patchset 2024-09-02 (LP: #2078304)
+    - filelock: Remove locks reliably when fcntl/close race is detected
+    - scsi: core: alua: I/O errors for ALUA state transitions
+    - scsi: sr: Fix unintentional arithmetic wraparound
+    - scsi: qedf: Don't process stag work during unload and recovery
+    - scsi: qedf: Wait for stag work during unload
+    - scsi: qedf: Set qed_slowpath_params to zero before use
+    - efi/libstub: zboot.lds: Discard .discard sections
+    - ACPI: EC: Abort address space access upon error
+    - ACPI: EC: Avoid returning AE_OK on errors in address space handler
+    - tools/power/cpupower: Fix Pstate frequency reporting on AMD Family 1Ah CPUs
+    - wifi: mac80211: mesh: init nonpeer_pm to active by default in mesh sdata
+    - wifi: mac80211: apply mcast rate only if interface is up
+    - wifi: mac80211: handle tasklet frames before stopping
+    - wifi: cfg80211: fix 6 GHz scan request building
+    - wifi: iwlwifi: mvm: d3: fix WoWLAN command version lookup
+    - wifi: iwlwifi: mvm: remove stale STA link data during restart
+    - wifi: iwlwifi: mvm: Handle BIGTK cipher in kek_kck cmd
+    - wifi: iwlwifi: mvm: handle BA session teardown in RF-kill
+    - wifi: iwlwifi: mvm: properly set 6 GHz channel direct probe option
+    - wifi: iwlwifi: mvm: Fix scan abort handling with HW rfkill
+    - wifi: mac80211: fix UBSAN noise in ieee80211_prep_hw_scan()
+    - selftests: cachestat: Fix build warnings on ppc64
+    - selftests/openat2: Fix build warnings on ppc64
+    - selftests/futex: pass _GNU_SOURCE without a value to the compiler
+    - of/irq: Factor out parsing of interrupt-map parent phandle+args from
+      of_irq_parse_raw()
+    - Input: silead - Always support 10 fingers
+    - net: ipv6: rpl_iptunnel: block BH in rpl_output() and rpl_input()
+    - ila: block BH in ila_output()
+    - arm64: armv8_deprecated: Fix warning in isndep cpuhp starting process
+    - null_blk: fix validation of block size
+    - kconfig: gconf: give a proper initial state to the Save button
+    - kconfig: remove wrong expr_trans_bool()
+    - input: Add event code for accessibility key
+    - input: Add support for "Do Not Disturb"
+    - HID: Ignore battery for ELAN touchscreens 2F2C and 4116
+    - NFSv4: Fix memory leak in nfs4_set_security_label
+    - nfs: propagate readlink errors in nfs_symlink_filler
+    - nfs: Avoid flushing many pages with NFS_FILE_SYNC
+    - nfs: don't invalidate dentries on transient errors
+    - cachefiles: add consistency check for copen/cread
+    - cachefiles: Set object to close if ondemand_id < 0 in copen
+    - cachefiles: make on-demand read killable
+    - fs/file: fix the check in find_next_fd()
+    - mei: demote client disconnect warning on suspend to debug
+    - iomap: Fix iomap_adjust_read_range for plen calculation
+    - drm/exynos: dp: drop driver owner initialization
+    - drm: panel-orientation-quirks: Add quirk for Aya Neo KUN
+    - drm/mediatek: Call drm_atomic_helper_shutdown() at shutdown time
+    - nvme: avoid double free special payload
+    - nvmet: always initialize cqe.result
+    - ALSA: hda: cs35l56: Fix lifecycle of codec pointer
+    - wifi: cfg80211: wext: add extra SIOCSIWSCAN data check
+    - ALSA: hda/realtek: Support Lenovo Thinkbook 16P Gen 5
+    - KVM: PPC: Book3S HV: Prevent UAF in kvm_spapr_tce_attach_iommu_group()
+    - drm/vmwgfx: Fix missing HYPERVISOR_GUEST dependency
+    - ALSA: hda/realtek: Add more codec ID to no shutup pins list
+    - spi: Fix OCTAL mode support
+    - cpumask: limit FORCE_NR_CPUS to just the UP case
+    - [Config] Remove FORCE_NR_CPUS
+    - selftests: openvswitch: Set value to nla flags.
+    - drm/amdgpu: Indicate CU havest info to CP
+    - ALSA: hda: cs35l56: Select SERIAL_MULTI_INSTANTIATE
+    - mips: fix compat_sys_lseek syscall
+    - Input: elantech - fix touchpad state on resume for Lenovo N24
+    - Input: i8042 - add Ayaneo Kun to i8042 quirk table
+    - ASoC: rt722-sdca-sdw: add silence detection register as volatile
+    - Input: xpad - add support for ASUS ROG RAIKIRI PRO
+    - ASoC: topology: Fix references to freed memory
+    - ASoC: topology: Do not assign fields that are already set
+    - bytcr_rt5640 : inverse jack detect for Archos 101 cesium
+    - ALSA: dmaengine: Synchronize dma channel after drop()
+    - ASoC: ti: davinci-mcasp: Set min period size using FIFO config
+    - ASoC: ti: omap-hdmi: Fix too long driver name
+    - ASoC: SOF: sof-audio: Skip unprepare for in-use widgets on error rollback
+    - ASoC: rt722-sdca-sdw: add debounce time for type detection
+    - nvme: fix NVME_NS_DEAC may incorrectly identifying the disk as EXT_LBA.
+    - Input: ads7846 - use spi_device_id table
+    - can: kvaser_usb: fix return value for hif_usb_send_regout
+    - gpio: pca953x: fix pca953x_irq_bus_sync_unlock race
+    - octeontx2-pf: Fix coverity and klockwork issues in octeon PF driver
+    - s390/sclp: Fix sclp_init() cleanup on failure
+    - platform/mellanox: nvsw-sn2201: Add check for platform_device_add_resources
+    - platform/x86: wireless-hotkey: Add support for LG Airplane Button
+    - platform/x86: lg-laptop: Remove LGEX0815 hotkey handling
+    - platform/x86: lg-laptop: Change ACPI device id
+    - platform/x86: lg-laptop: Use ACPI device handle when evaluating WMAB/WMBB
+    - btrfs: qgroup: fix quota root leak after quota disable failure
+    - ibmvnic: Add tx check to prevent skb leak
+    - ALSA: PCM: Allow resume only for suspended streams
+    - ALSA: hda/relatek: Enable Mute LED on HP Laptop 15-gw0xxx
+    - ALSA: dmaengine_pcm: terminate dmaengine before synchronize
+    - ASoC: amd: yc: Fix non-functional mic on ASUS M5602RA
+    - net: usb: qmi_wwan: add Telit FN912 compositions
+    - net: mac802154: Fix racy device stats updates by DEV_STATS_INC() and
+      DEV_STATS_ADD()
+    - powerpc/pseries: Whitelist dtl slub object for copying to userspace
+    - powerpc/eeh: avoid possible crash when edev->pdev changes
+    - scsi: libsas: Fix exp-attached device scan after probe failure scanned in
+      again after probe failed
+    - tee: optee: ffa: Fix missing-field-initializers warning
+    - Bluetooth: hci_core: cancel all works upon hci_unregister_dev()
+    - Bluetooth: btnxpuart: Enable Power Save feature on startup
+    - bluetooth/l2cap: sync sock recv cb and release
+    - erofs: ensure m_llen is reset to 0 if metadata is invalid
+    - drm/amd/display: Add refresh rate range check
+    - drm/amd/display: Account for cursor prefetch BW in DML1 mode support
+    - drm/amd/display: Fix refresh rate range for some panel
+    - drm/radeon: check bo_va->bo is non-NULL before using it
+    - fs: better handle deep ancestor chains in is_subdir()
+    - wifi: iwlwifi: properly set WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK
+    - drivers/perf: riscv: Reset the counter to hpmevent mapping while starting
+      cpus
+    - riscv: stacktrace: fix usage of ftrace_graph_ret_addr()
+    - spi: imx: Don't expect DMA for i.MX{25,35,50,51,53} cspi devices
+    - ksmbd: return FILE_DEVICE_DISK instead of super magic
+    - ASoC: SOF: Intel: hda-pcm: Limit the maximum number of periods by
+      MAX_BDL_ENTRIES
+    - selftest/timerns: fix clang build failures for abs() calls
+    - selftests/vDSO: fix clang build errors and warnings
+    - hfsplus: fix uninit-value in copy_name
+    - selftests/bpf: Extend tcx tests to cover late tcx_entry release
+    - spi: mux: set ctlr->bits_per_word_mask
+    - ALSA: hda: Use imply for suggesting CONFIG_SERIAL_MULTI_INSTANTIATE
+    - [Config] Update CONFIG_SERIAL_MULTI_INSTANTIATE
+    - cifs: fix noisy message on copy_file_range
+    - Bluetooth: L2CAP: Fix deadlock
+    - of/irq: Disable "interrupt-map" parsing for PASEMI Nemo
+    - wifi: cfg80211: wext: set ssids=NULL for passive scans
+    - wifi: mac80211: disable softirqs for queued frame handling
+    - wifi: iwlwifi: mvm: don't wake up rx_sync_waitq upon RFKILL
+    - cachefiles: fix slab-use-after-free in fscache_withdraw_volume()
+    - cachefiles: fix slab-use-after-free in cachefiles_withdraw_cookie()
+    - btrfs: ensure fast fsync waits for ordered extents after a write failure
+    - PNP: Hide pnp_bus_type from the non-PNP code
+    - ACPI: AC: Properly notify powermanagement core about changes
+    - selftests/overlayfs: Fix build error on ppc64
+    - nvme-fabrics: use reserved tag for reg read/write command
+    - LoongArch: Fix GMAC's phy-mode definitions in dts
+    - io_uring: fix possible deadlock in io_register_iowq_max_workers()
+    - vfio: Create vfio_fs_type with inode per device
+    - vfio/pci: Use unmap_mapping_range()
+    - parport: amiga: Mark driver struct with __refdata to prevent section
+      mismatch
+    - drm: renesas: shmobile: Call drm_atomic_helper_shutdown() at shutdown time
+    - vfio/pci: Insert full vma on mmap'd MMIO fault
+    - ALSA: hda: cs35l41: Support Lenovo Thinkbook 16P Gen 5
+    - ALSA: hda: cs35l41: Support Lenovo Thinkbook 13x Gen 4
+    - ALSA: hda/realtek: Support Lenovo Thinkbook 13x Gen 4
+    - wifi: mac80211: Avoid address calculations via out of bounds array indexing
+    - drm/amd/display: change dram_clock_latency to 34us for dcn35
+    - closures: Change BUG_ON() to WARN_ON()
+    - ASoC: codecs: ES8326: Solve headphone detection issue
+    - ASoC: Intel: avs: Fix route override
+    - net: mvpp2: fill-in dev_port attribute
+    - btrfs: scrub: handle RST lookup error correctly
+    - clk: qcom: apss-ipq-pll: remove 'config_ctl_hi_val' from Stromer pll configs
+    - drm/amd/display: Update efficiency bandwidth for dcn351
+    - drm/amd/display: Fix array-index-out-of-bounds in dml2/FCLKChangeSupport
+    - btrfs: fix uninitialized return value in the ref-verify tool
+    - spi: davinci: Unset POWERDOWN bit when releasing resources
+    - mm: page_ref: remove folio_try_get_rcu()
+    - ALSA: hda: cs35l41: Fix swapped l/r audio channels for Lenovo ThinBook 13x
+      Gen4
+    - netfs, fscache: export fscache_put_volume() and add fscache_try_get_volume()
+    - Upstream stable to v6.6.42, v6.9.11
+  * CVE-2024-27022
+    - Revert "Revert "fork: defer linking file vma until vma is fully
+      initialized""
+  * UBSAN: array-index-out-of-bounds in /build/linux-Z1RxaK/linux-
+    6.8.0/drivers/gpu/drm/amd/amdgpu/../pm/powerplay/hwmgr/processpptables.c:124
+    9:61 (LP: #2078041)
+    - drm/amdgpu/pptable: convert some variable sized arrays to [] style
+    - drm/amdgpu: convert some variable sized arrays to [] style
+    - drm/amdgpu/pptable: Fix UBSAN array-index-out-of-bounds
+  * alsa: Headphone and Speaker couldn't output sound intermittently
+    (LP: #2077690)
+    - ALSA: hda/realtek - Fixed ALC256 headphone no sound
+    - ALSA: hda/realtek - FIxed ALC285 headphone no sound
+  * Fix ethernet performance on JSL and EHL (LP: #2077858)
+    - intel_idle: Disable promotion to C1E on Jasper Lake and Elkhart Lake
+  * Noble update: upstream stable patchset 2024-08-29 (LP: #2078289)
+    - Revert "usb: xhci: prevent potential failure in handle_tx_event() for
+      Transfer events without TRB"
+    - Compiler Attributes: Add __uninitialized macro
+    - mm: prevent derefencing NULL ptr in pfn_section_valid()
+    - scsi: ufs: core: Fix ufshcd_clear_cmd racing issue
+    - scsi: ufs: core: Fix ufshcd_abort_one racing issue
+    - vfio/pci: Init the count variable in collecting hot-reset devices
+    - cachefiles: propagate errors from vfs_getxattr() to avoid infinite loop
+    - cachefiles: stop sending new request when dropping object
+    - cachefiles: cancel all requests for the object that is being dropped
+    - cachefiles: wait for ondemand_object_worker to finish when dropping object
+    - cachefiles: cyclic allocation of msg_id to avoid reuse
+    - cachefiles: add missing lock protection when polling
+    - dsa: lan9303: Fix mapping between DSA port number and PHY address
+    - filelock: fix potential use-after-free in posix_lock_inode
+    - fs/dcache: Re-use value stored to dentry->d_flags instead of re-reading
+    - vfs: don't mod negative dentry count when on shrinker list
+    - net: bcmasp: Fix error code in probe()
+    - tcp: fix incorrect undo caused by DSACK of TLP retransmit
+    - bpf: Fix too early release of tcx_entry
+    - net: phy: microchip: lan87xx: reinit PHY after cable test
+    - skmsg: Skip zero length skb in sk_msg_recvmsg
+    - octeontx2-af: Fix incorrect value output on error path in
+      rvu_check_rsrc_availability()
+    - net: fix rc7's __skb_datagram_iter()
+    - i40e: Fix XDP program unloading while removing the driver
+    - net: ethernet: lantiq_etop: fix double free in detach
+    - bpf: fix order of args in call to bpf_map_kvcalloc
+    - bpf: make timer data struct more generic
+    - bpf: replace bpf_timer_init with a generic helper
+    - bpf: Fail bpf_timer_cancel when callback is being cancelled
+    - net: ethernet: mtk-star-emac: set mac_managed_pm when probing
+    - ppp: reject claimed-as-LCP but actually malformed packets
+    - ethtool: netlink: do not return SQI value if link is down
+    - udp: Set SOCK_RCU_FREE earlier in udp_lib_get_port().
+    - net, sunrpc: Remap EPERM in case of connection failure in
+      xs_tcp_setup_socket
+    - s390: Mark psw in __load_psw_mask() as __unitialized
+    - arm64: dts: qcom: sc8180x: Fix LLCC reg property again
+    - firmware: cs_dsp: Fix overflow checking of wmfw header
+    - firmware: cs_dsp: Return error if block header overflows file
+    - firmware: cs_dsp: Validate payload length before processing block
+    - firmware: cs_dsp: Prevent buffer overrun when processing V2 alg headers
+    - ASoC: SOF: Intel: hda: fix null deref on system suspend entry
+    - firmware: cs_dsp: Use strnlen() on name fields in V1 wmfw files
+    - ARM: davinci: Convert comma to semicolon
+    - octeontx2-af: replace cpt slot with lf id on reg write
+    - octeontx2-af: fix a issue with cpt_lf_alloc mailbox
+    - octeontx2-af: fix detection of IP layer
+    - octeontx2-af: fix issue with IPv6 ext match for RSS
+    - octeontx2-af: fix issue with IPv4 match for RSS
+    - cifs: fix setting SecurityFlags to true
+    - Revert "sched/fair: Make sure to try to detach at least one movable task"
+    - tcp: avoid too many retransmit packets
+    - net: ks8851: Fix deadlock with the SPI chip variant
+    - net: ks8851: Fix potential TX stall after interface reopen
+    - USB: serial: option: add Telit generic core-dump composition
+    - USB: serial: option: add Telit FN912 rmnet compositions
+    - USB: serial: option: add Fibocom FM350-GL
+    - USB: serial: option: add support for Foxconn T99W651
+    - USB: serial: option: add Netprisma LCUK54 series modules
+    - USB: serial: option: add Rolling RW350-GL variants
+    - USB: serial: mos7840: fix crash on resume
+    - USB: Add USB_QUIRK_NO_SET_INTF quirk for START BP-850k
+    - usb: dwc3: pci: add support for the Intel Panther Lake
+    - usb: gadget: configfs: Prevent OOB read/write in usb_string_copy()
+    - USB: core: Fix duplicate endpoint bug by clearing reserved bits in the
+      descriptor
+    - misc: microchip: pci1xxxx: Fix return value of nvmem callbacks
+    - hpet: Support 32-bit userspace
+    - xhci: always resume roothubs if xHC was reset during resume
+    - s390/mm: Add NULL pointer check to crst_table_free() base_crst_free()
+    - mm: vmalloc: check if a hash-index is in cpu_possible_mask
+    - mm/filemap: skip to create PMD-sized page cache if needed
+    - mm/filemap: make MAX_PAGECACHE_ORDER acceptable to xarray
+    - ksmbd: discard write access to the directory open
+    - iio: trigger: Fix condition for own trigger
+    - arm64: dts: qcom: sa8775p: Correct IRQ number of EL2 non-secure physical
+      timer
+    - arm64: dts: qcom: sc8280xp-x13s: fix touchscreen power on
+    - nvmem: rmem: Fix return value of rmem_read()
+    - nvmem: meson-efuse: Fix return value of nvmem callbacks
+    - nvmem: core: only change name to fram for current attribute
+    - platform/x86: toshiba_acpi: Fix array out-of-bounds access
+    - tty: serial: ma35d1: Add a NULL check for of_node
+    - ALSA: hda/realtek: add quirk for Clevo V5[46]0TU
+    - ALSA: hda/realtek: Enable Mute LED on HP 250 G7
+    - ALSA: hda/realtek: Limit mic boost on VAIO PRO PX
+    - Fix userfaultfd_api to return EINVAL as expected
+    - pmdomain: qcom: rpmhpd: Skip retention level for Power Domains
+    - libceph: fix race between delayed_work() and ceph_monc_stop()
+    - ACPI: processor_idle: Fix invalid comparison with insertion sort for latency
+    - cpufreq: ACPI: Mark boost policy as enabled when setting boost
+    - cpufreq: Allow drivers to advertise boost enabled
+    - wireguard: selftests: use acpi=off instead of -no-acpi for recent QEMU
+    - wireguard: allowedips: avoid unaligned 64-bit memory accesses
+    - wireguard: queueing: annotate intentional data race in cpu round robin
+    - wireguard: send: annotate intentional data race in checking empty queue
+    - misc: fastrpc: Fix DSP capabilities request
+    - misc: fastrpc: Avoid updating PD type for capability request
+    - misc: fastrpc: Copy the complete capability structure to user
+    - misc: fastrpc: Fix memory leak in audio daemon attach operation
+    - misc: fastrpc: Fix ownership reassignment of remote heap
+    - misc: fastrpc: Restrict untrusted app to attach to privileged PD
+    - mm/shmem: disable PMD-sized page cache if needed
+    - mm/damon/core: merge regions aggressively when max_nr_regions is unmet
+    - selftests/net: fix gro.c compilation failure due to non-existent
+      opt_ipproto_off
+    - ext4: avoid ptr null pointer dereference
+    - sched: Move psi_account_irqtime() out of update_rq_clock_task() hotpath
+    - i2c: rcar: bring hardware to known state when probing
+    - i2c: mark HostNotify target address as used
+    - i2c: rcar: ensure Gen3+ reset does not disturb local targets
+    - i2c: testunit: avoid re-issued work after read message
+    - i2c: rcar: clear NO_RXDMA flag after resetting
+    - x86/bhi: Avoid warning in #DB handler due to BHI mitigation
+    - kbuild: Make ld-version.sh more robust against version string changes
+    - spi: axi-spi-engine: fix sleep calculation
+    - minixfs: Fix minixfs_rename with HIGHMEM
+    - bpf: Defer work in bpf_timer_cancel_and_free
+    - netfilter: nf_tables: prefer nft_chain_validate
+    - arm64: dts: qcom: x1e80100-*: Allocate some CMA buffers
+    - arm64: dts: qcom: sm6115: add iommu for sdhc_1
+    - arm64: dts: qcom: qdu1000: Fix LLCC reg property
+    - net: ethtool: Fix RSS setting
+    - nilfs2: fix kernel bug on rename operation of broken directory
+    - cachestat: do not flush stats in recency check
+    - mm: fix crashes from deferred split racing folio migration
+    - nvmem: core: limit cell sysfs permissions to main attribute ones
+    - serial: imx: ensure RTS signal is not left active after shutdown
+    - mmc: sdhci: Fix max_seg_size for 64KiB PAGE_SIZE
+    - mmc: davinci_mmc: Prevent transmitted data size from exceeding sgm's length
+    - mm/readahead: limit page cache size in page_cache_ra_order()
+    - Revert "dt-bindings: cache: qcom,llcc: correct QDU1000 reg entries"
+    - sched/deadline: Fix task_struct reference leak
+    - Upstream stable to v6.6.40, v6.6.41, v6.9.10
+  * [SRU][HPE 24.04] Intel FVL NIC FW flash fails with inbox driver, causing
+    driver not detected (LP: #2076675) // Noble update: upstream stable patchset
+    2024-08-29 (LP: #2078289)
+    - i40e: fix: remove needless retries of NVM update
+  * CVE-2024-41022
+    - drm/amdgpu: Fix signedness bug in sdma_v4_0_process_trap_irq()
+  *  Deadlock occurs while suspending md raid  (LP: #2073695)
+    - md: change the return value type of md_write_start to void
+    - md: fix deadlock between mddev_suspend and flush bio
+  * Lenovo X12 Detachable Gen 2 unresponsive under light load (LP: #2076361)
+    - drm/i915: Enable Wa_16019325821
+    - drm/i915/guc: Add support for w/a KLVs
+    - drm/i915/guc: Enable Wa_14019159160
+  * Regression: unable to reach low idle states on Tiger Lake (LP: #2072679)
+    - SAUCE: PCI: ASPM: Allow OS to configure ASPM where BIOS is incapable of
+    - SAUCE: PCI: vmd: Let OS control ASPM for devices under VMD domain
+  * Noble update: upstream stable patchset 2024-08-22 (LP: #2077600)
+    - locking/mutex: Introduce devm_mutex_init()
+    - leds: an30259a: Use devm_mutex_init() for mutex initialization
+    - crypto: hisilicon/debugfs - Fix debugfs uninit process issue
+    - drm/lima: fix shared irq handling on driver remove
+    - powerpc: Avoid nmi_enter/nmi_exit in real mode interrupt.
+    - media: dvb: as102-fe: Fix as10x_register_addr packing
+    - media: dvb-usb: dib0700_devices: Add missing release_firmware()
+    - IB/core: Implement a limit on UMAD receive List
+    - scsi: qedf: Make qedf_execute_tmf() non-preemptible
+    - selftests/bpf: adjust dummy_st_ops_success to detect additional error
+    - selftests/bpf: do not pass NULL for non-nullable params in dummy_st_ops
+    - selftests/bpf: dummy_st_ops should reject 0 for non-nullable params
+    - RISC-V: KVM: Fix the initial sample period value
+    - crypto: aead,cipher - zeroize key buffer after use
+    - media: mediatek: vcodec: Only free buffer VA that is not NULL
+    - drm/amdgpu: Fix uninitialized variable warnings
+    - drm/amdgpu: Initialize timestamp for some legacy SOCs
+    - drm/amd/display: Check index msg_id before read or write
+    - drm/amd/display: Check pipe offset before setting vblank
+    - drm/amd/display: Skip finding free audio for unknown engine_id
+    - drm/amd/display: Fix uninitialized variables in DM
+    - drm/amdgpu: fix uninitialized scalar variable warning
+    - drm/amdgpu: fix the warning about the expression (int)size - len
+    - media: dw2102: Don't translate i2c read into write
+    - riscv: Apply SiFive CIP-1200 workaround to single-ASID sfence.vma
+    - sctp: prefer struct_size over open coded arithmetic
+    - firmware: dmi: Stop decoding on broken entry
+    - Input: ff-core - prefer struct_size over open coded arithmetic
+    - wifi: mt76: replace skb_put with skb_put_zero
+    - wifi: mt76: mt7996: add sanity checks for background radar trigger
+    - thermal/drivers/mediatek/lvts_thermal: Check NULL ptr on lvts_data
+    - media: dvb-frontends: tda18271c2dd: Remove casting during div
+    - media: s2255: Use refcount_t instead of atomic_t for num_channels
+    - media: dvb-frontends: tda10048: Fix integer overflow
+    - i2c: i801: Annotate apanel_addr as __ro_after_init
+    - powerpc/64: Set _IO_BASE to POISON_POINTER_DELTA not 0 for CONFIG_PCI=n
+    - orangefs: fix out-of-bounds fsid access
+    - kunit: Fix timeout message
+    - powerpc/xmon: Check cpu id in commands "c#", "dp#" and "dx#"
+    - selftests/net: fix uninitialized variables
+    - igc: fix a log entry using uninitialized netdev
+    - bpf: Avoid uninitialized value in BPF_CORE_READ_BITFIELD
+    - serial: imx: Raise TX trigger level to 8
+    - jffs2: Fix potential illegal address access in jffs2_free_inode
+    - s390/pkey: Wipe sensitive data on failure
+    - btrfs: scrub: initialize ret in scrub_simple_mirror() to fix compilation
+      warning
+    - cdrom: rearrange last_media_change check to avoid unintentional overflow
+    - tools/power turbostat: Remember global max_die_id
+    - vhost: Use virtqueue mutex for swapping worker
+    - vhost: Release worker mutex during flushes
+    - vhost_task: Handle SIGKILL by flushing work and exiting
+    - mac802154: fix time calculation in ieee802154_configure_durations()
+    - net: phy: phy_device: Fix PHY LED blinking code comment
+    - UPSTREAM: tcp: fix DSACK undo in fast recovery to call tcp_try_to_open()
+    - net/mlx5: E-switch, Create ingress ACL when needed
+    - net/mlx5e: Add mqprio_rl cleanup and free in mlx5e_priv_cleanup()
+    - Bluetooth: hci_event: Fix setting of unicast qos interval
+    - Bluetooth: Ignore too large handle values in BIG
+    - Bluetooth: ISO: Check socket flag instead of hcon
+    - bluetooth/hci: disallow setting handle bigger than HCI_CONN_HANDLE_MAX
+    - KVM: s390: fix LPSWEY handling
+    - e1000e: Fix S0ix residency on corporate systems
+    - gpiolib: of: fix lookup quirk for MIPS Lantiq
+    - net: allow skb_datagram_iter to be called from any context
+    - net: txgbe: initialize num_q_vectors for MSI/INTx interrupts
+    - net: ntb_netdev: Move ntb_netdev_rx_handler() to call netif_rx() from
+      __netif_rx()
+    - gpio: mmio: do not calculate bgpio_bits via "ngpios"
+    - wifi: wilc1000: fix ies_len type in connect path
+    - riscv: kexec: Avoid deadlock in kexec crash path
+    - netfilter: nf_tables: unconditionally flush pending work before notifier
+    - bonding: Fix out-of-bounds read in bond_option_arp_ip_targets_set()
+    - selftests: fix OOM in msg_zerocopy selftest
+    - selftests: make order checking verbose in msg_zerocopy selftest
+    - inet_diag: Initialize pad field in struct inet_diag_req_v2
+    - mlxsw: core_linecards: Fix double memory deallocation in case of invalid INI
+      file
+    - gpiolib: of: add polarity quirk for TSC2005
+    - cpu: Fix broken cmdline "nosmp" and "maxcpus=0"
+    - platform/x86: toshiba_acpi: Fix quickstart quirk handling
+    - Revert "igc: fix a log entry using uninitialized netdev"
+    - nilfs2: fix inode number range checks
+    - nilfs2: add missing check for inode numbers on directory entries
+    - mm: optimize the redundant loop of mm_update_owner_next()
+    - mm: avoid overflows in dirty throttling logic
+    - btrfs: fix adding block group to a reclaim list and the unused list during
+      reclaim
+    - scsi: mpi3mr: Use proper format specifier in mpi3mr_sas_port_add()
+    - Bluetooth: hci_bcm4377: Fix msgid release
+    - Bluetooth: qca: Fix BT enable failure again for QCA6390 after warm reboot
+    - can: kvaser_usb: Explicitly initialize family in leafimx driver_info struct
+    - fsnotify: Do not generate events for O_PATH file descriptors
+    - Revert "mm/writeback: fix possible divide-by-zero in wb_dirty_limits(),
+      again"
+    - drm/nouveau: fix null pointer dereference in nouveau_connector_get_modes
+    - drm/amdgpu/atomfirmware: silence UBSAN warning
+    - drm: panel-orientation-quirks: Add quirk for Valve Galileo
+    - clk: qcom: gcc-ipq9574: Add BRANCH_HALT_VOTED flag
+    - clk: sunxi-ng: common: Don't call hw_to_ccu_common on hw without common
+    - powerpc/pseries: Fix scv instruction crash with kexec
+    - powerpc/64s: Fix unnecessary copy to 0 when kernel is booted at address 0
+    - mtd: rawnand: Ensure ECC configuration is propagated to upper layers
+    - mtd: rawnand: Fix the nand_read_data_op() early check
+    - mtd: rawnand: Bypass a couple of sanity checks during NAND identification
+    - mtd: rawnand: rockchip: ensure NVDDR timings are rejected
+    - net: stmmac: dwmac-qcom-ethqos: fix error array size
+    - arm64: dts: rockchip: Fix the DCDC_REG2 minimum voltage on Quartz64 Model B
+    - media: dw2102: fix a potential buffer overflow
+    - clk: qcom: gcc-sm6350: Fix gpll6* & gpll7 parents
+    - clk: qcom: clk-alpha-pll: set ALPHA_EN bit for Stromer Plus PLLs
+    - clk: mediatek: mt8183: Only enable runtime PM on mt8183-mfgcfg
+    - i2c: pnx: Fix potential deadlock warning from del_timer_sync() call in isr
+    - fs/ntfs3: Mark volume as dirty if xattr is broken
+    - ALSA: hda/realtek: Enable headset mic of JP-IK LEAP W502 with ALC897
+    - vhost-scsi: Handle vhost_vq_work_queue failures for events
+    - nvme-multipath: find NUMA path only for online numa-node
+    - dma-mapping: benchmark: avoid needless copy_to_user if benchmark fails
+    - connector: Fix invalid conversion in cn_proc.h
+    - nvme: adjust multiples of NVME_CTRL_PAGE_SIZE in offset
+    - regmap-i2c: Subtract reg size from max_write
+    - platform/x86: touchscreen_dmi: Add info for GlobalSpace SolT IVW 11.6"
+      tablet
+    - platform/x86: touchscreen_dmi: Add info for the EZpad 6s Pro
+    - nvmet: fix a possible leak when destroy a ctrl during qp establishment
+    - kbuild: fix short log for AS in link-vmlinux.sh
+    - nfc/nci: Add the inconsistency check between the input data length and count
+    - spi: cadence: Ensure data lines set to low during dummy-cycle period
+    - ALSA: ump: Set default protocol when not given explicitly
+    - drm/amdgpu: silence UBSAN warning
+    - null_blk: Do not allow runt zone with zone capacity smaller then zone size
+    - nilfs2: fix incorrect inode allocation from reserved inodes
+    - leds: mlxreg: Use devm_mutex_init() for mutex initialization
+    - net: dql: Avoid calling BUG() when WARN() is enough
+    - drm/xe: Add outer runtime_pm protection to xe_live_ktest@xe_dma_buf
+    - bpf: mark bpf_dummy_struct_ops.test_1 parameter as nullable
+    - drm/amdgpu: fix double free err_addr pointer warnings
+    - drm/amd/display: Fix overlapping copy within dml_core_mode_programming
+    - drm/amd/display: update pipe topology log to support subvp
+    - drm/amd/display: Do not return negative stream id for array
+    - drm/amd/display: ASSERT when failing to find index by plane/stream id
+    - usb: xhci: prevent potential failure in handle_tx_event() for Transfer
+      events without TRB
+    - media: i2c: st-mipid02: Use the correct div function
+    - media: tc358746: Use the correct div_ function
+    - crypto: hisilicon/sec2 - fix for register offset
+    - s390/pkey: Use kfree_sensitive() to fix Coccinelle warnings
+    - s390/pkey: Wipe copies of clear-key structures on failure
+    - s390/pkey: Wipe copies of protected- and secure-keys
+    - wifi: cfg80211: restrict NL80211_ATTR_TXQ_QUANTUM values
+    - wifi: mac80211: fix BSS_CHANGED_UNSOL_BCAST_PROBE_RESP
+    - net: txgbe: remove separate irq request for MSI and INTx
+    - net: txgbe: add extra handle for MSI/INTx into thread irq handle
+    - net: txgbe: free isb resources at the right time
+    - btrfs: always do the basic checks for btrfs_qgroup_inherit structure
+    - net: phy: aquantia: add missing include guards
+    - drm/fbdev-generic: Fix framebuffer on big endian devices
+    - net: stmmac: enable HW-accelerated VLAN stripping for gmac4 only
+    - net: rswitch: Avoid use-after-free in rswitch_poll()
+    - ice: use proper macro for testing bit
+    - drm/xe/mcr: Avoid clobbering DSS steering
+    - tcp: Don't flag tcp_sk(sk)->rx_opt.saw_unknown for TCP AO.
+    - btrfs: zoned: fix calc_available_free_space() for zoned mode
+    - btrfs: fix folio refcount in __alloc_dummy_extent_buffer()
+    - Bluetooth: Add quirk to ignore reserved PHY bits in LE Extended Adv Report
+    - drm/xe: fix error handling in xe_migrate_update_pgtables
+    - drm/ttm: Always take the bo delayed cleanup path for imported bos
+    - fs: don't misleadingly warn during thaw operations
+    - drm/amdkfd: Let VRAM allocations go to GTT domain on small APUs
+    - drm/amdgpu: correct hbm field in boot status
+    - Upstream stable to v6.6.38, v6.6.39, v6.9.9
+  * Panels show garbage or flickering when i915.psr2 enabled (LP: #2069993)
+    - SAUCE: drm/i915/display/psr: add a psr2 disable quirk table
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x4d_0x10_0x93_0x15
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x30_0xe4_0x8b_0x07
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x30_0xe4_0x78_0x07
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x30_0xe4_0x8c_0x07
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x06_0xaf_0x9a_0xf9
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x4d_0x10_0x8f_0x15
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x06_0xaf_0xa3_0xc3
+  * Random flickering with Intel i915 (Gen9 GPUs in 6th-8th gen CPUs) on Linux
+    6.8 (LP: #2062951)
+    - SAUCE: iommu/intel: disable DMAR for SKL integrated gfx
+  * [SRU][22.04.5]: mpi3mr driver update (LP: #2073583)
+    - scsi: mpi3mr: HDB allocation and posting for hardware and firmware buffers
+    - scsi: mpi3mr: Trigger support
+    - scsi: mpi3mr: Add ioctl support for HDB
+    - scsi: mpi3mr: Support PCI Error Recovery callback handlers
+    - scsi: mpi3mr: Prevent PCI writes from driver during PCI error recovery
+    - scsi: mpi3mr: Driver version update
+  * Fix power consumption while using HW accelerated video decode on AMD
+    platforms (LP: #2073282)
+    - drm/amdgpu/vcn: identify unified queue in sw init
+    - drm/amdgpu/vcn: not pause dpg for unified queue
+  * Noble update: upstream stable patchset 2024-08-09 (LP: #2076435)
+    - usb: typec: ucsi: Never send a lone connector change ack
+    - usb: typec: ucsi: Ack also failed Get Error commands
+    - Input: ili210x - fix ili251x_read_touch_data() return value
+    - pinctrl: fix deadlock in create_pinctrl() when handling -EPROBE_DEFER
+    - pinctrl: rockchip: fix pinmux bits for RK3328 GPIO2-B pins
+    - pinctrl: rockchip: fix pinmux bits for RK3328 GPIO3-B pins
+    - pinctrl: rockchip: use dedicated pinctrl type for RK3328
+    - pinctrl: rockchip: fix pinmux reset in rockchip_pmx_set
+    - MIPS: pci: lantiq: restore reset gpio polarity
+    - ASoC: rockchip: i2s-tdm: Fix trcm mode by setting clock on right mclk
+    - ASoC: mediatek: mt8183-da7219-max98357: Fix kcontrol name collision
+    - ASoC: atmel: atmel-classd: Re-add dai_link->platform to fix card init
+    - workqueue: Increase worker desc's length to 32
+    - ASoC: q6apm-lpass-dai: close graph on prepare errors
+    - bpf: Add missed var_off setting in set_sext32_default_val()
+    - bpf: Add missed var_off setting in coerce_subreg_to_size_sx()
+    - s390/pci: Add missing virt_to_phys() for directed DIBV
+    - ASoC: amd: acp: add a null check for chip_pdev structure
+    - ASoC: amd: acp: remove i2s configuration check in acp_i2s_probe()
+    - ASoC: fsl-asoc-card: set priv->pdev before using it
+    - net: dsa: microchip: fix initial port flush problem
+    - openvswitch: get related ct labels from its master if it is not confirmed
+    - mlxsw: spectrum_buffers: Fix memory corruptions on Spectrum-4 systems
+    - ibmvnic: Free any outstanding tx skbs during scrq reset
+    - net: phy: micrel: add Microchip KSZ 9477 to the device table
+    - net: dsa: microchip: use collision based back pressure mode
+    - ice: Rebuild TC queues on VSI queue reconfiguration
+    - xdp: Remove WARN() from __xdp_reg_mem_model()
+    - netfilter: fix undefined reference to 'netfilter_lwtunnel_*' when
+      CONFIG_SYSCTL=n
+    - btrfs: use NOFS context when getting inodes during logging and log replay
+    - Fix race for duplicate reqsk on identical SYN
+    - ALSA: seq: Fix missing channel at encoding RPN/NRPN MIDI2 messages
+    - net: dsa: microchip: fix wrong register write when masking interrupt
+    - sparc: fix old compat_sys_select()
+    - sparc: fix compat recv/recvfrom syscalls
+    - parisc: use correct compat recv/recvfrom syscalls
+    - powerpc: restore some missing spu syscalls
+    - tcp: fix tcp_rcv_fastopen_synack() to enter TCP_CA_Loss for failed TFO
+    - ALSA: seq: Fix missing MSB in MIDI2 SPP conversion
+    - netfilter: nf_tables: fully validate NFT_DATA_VALUE on store to data
+      registers
+    - net: mana: Fix possible double free in error handling path
+    - drm/panel: ilitek-ili9881c: Fix warning with GPIO controllers that sleep
+    - vduse: validate block features only with block devices
+    - vduse: Temporarily fail if control queue feature requested
+    - x86/fpu: Fix AMD X86_BUG_FXSAVE_LEAK fixup
+    - mtd: partitions: redboot: Added conversion of operands to a larger type
+    - wifi: ieee80211: check for NULL in ieee80211_mle_size_ok()
+    - bpf: Mark bpf prog stack with kmsan_unposion_memory in interpreter mode
+    - RDMA/restrack: Fix potential invalid address access
+    - net/iucv: Avoid explicit cpumask var allocation on stack
+    - net/dpaa2: Avoid explicit cpumask var allocation on stack
+    - crypto: ecdh - explicitly zeroize private_key
+    - ALSA: emux: improve patch ioctl data validation
+    - media: dvbdev: Initialize sbuf
+    - irqchip/loongson: Select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP for
+      IRQ_LOONGARCH_CPU
+    - soc: ti: wkup_m3_ipc: Send NULL dummy message instead of pointer message
+    - gfs2: Fix NULL pointer dereference in gfs2_log_flush
+    - drm/radeon/radeon_display: Decrease the size of allocated memory
+    - nvme: fixup comment for nvme RDMA Provider Type
+    - drm/panel: simple: Add missing display timing flags for KOE TX26D202VM0BWA
+    - gpio: davinci: Validate the obtained number of IRQs
+    - RISC-V: fix vector insn load/store width mask
+    - drm/amdgpu: Fix pci state save during mode-1 reset
+    - riscv: stacktrace: convert arch_stack_walk() to noinstr
+    - gpiolib: cdev: Disallow reconfiguration without direction (uAPI v1)
+    - randomize_kstack: Remove non-functional per-arch entropy filtering
+    - x86: stop playing stack games in profile_pc()
+    - parisc: use generic sys_fanotify_mark implementation
+    - Revert "MIPS: pci: lantiq: restore reset gpio polarity"
+    - pinctrl: qcom: spmi-gpio: drop broken pm8008 support
+    - ocfs2: fix DIO failure due to insufficient transaction credits
+    - nfs: drop the incorrect assertion in nfs_swap_rw()
+    - mm: fix incorrect vbq reference in purge_fragmented_block
+    - mmc: sdhci-pci-o2micro: Convert PCIBIOS_* return codes to errnos
+    - mmc: sdhci-brcmstb: check R1_STATUS for erase/trim/discard
+    - mmc: sdhci-pci: Convert PCIBIOS_* return codes to errnos
+    - mmc: sdhci: Do not invert write-protect twice
+    - mmc: sdhci: Do not lock spinlock around mmc_gpio_get_ro()
+    - iio: xilinx-ams: Don't include ams_ctrl_channels in scan_mask
+    - counter: ti-eqep: enable clock at probe
+    - kbuild: doc: Update default INSTALL_MOD_DIR from extra to updates
+    - kbuild: Fix build target deb-pkg: ln: failed to create hard link
+    - i2c: testunit: don't erase registers after STOP
+    - i2c: testunit: discard write requests while old command is running
+    - ata: libata-core: Fix null pointer dereference on error
+    - ata,scsi: libata-core: Do not leak memory for ata_port struct members
+    - iio: adc: ad7266: Fix variable checking bug
+    - iio: accel: fxls8962af: select IIO_BUFFER & IIO_KFIFO_BUF
+    - iio: chemical: bme680: Fix pressure value output
+    - iio: chemical: bme680: Fix calibration data variable
+    - iio: chemical: bme680: Fix overflows in compensate() functions
+    - iio: chemical: bme680: Fix sensor data read operation
+    - net: usb: ax88179_178a: improve link status logs
+    - usb: gadget: printer: SS+ support
+    - usb: gadget: printer: fix races against disable
+    - usb: musb: da8xx: fix a resource leak in probe()
+    - usb: atm: cxacru: fix endpoint checking in cxacru_bind()
+    - usb: dwc3: core: remove lock of otg mode during gadget suspend/resume to
+      avoid deadlock
+    - usb: gadget: aspeed_udc: fix device address configuration
+    - usb: typec: ucsi: glink: fix child node release in probe function
+    - usb: ucsi: stm32: fix command completion handling
+    - usb: dwc3: core: Add DWC31 version 2.00a controller
+    - usb: dwc3: core: Workaround for CSR read timeout
+    - Revert "serial: core: only stop transmit when HW fifo is empty"
+    - serial: 8250_omap: Implementation of Errata i2310
+    - serial: imx: set receiver level before starting uart
+    - serial: core: introduce uart_port_tx_limited_flags()
+    - serial: bcm63xx-uart: fix tx after conversion to uart_port_tx_limited()
+    - tty: mcf: MCF54418 has 10 UARTS
+    - net: can: j1939: Initialize unused data in j1939_send_one()
+    - net: can: j1939: recover socket queue on CAN bus error during BAM
+      transmission
+    - net: can: j1939: enhanced error handling for tightly received RTS messages
+      in xtp_rx_rts_session_new
+    - PCI/MSI: Fix UAF in msi_capability_init
+    - cpufreq: intel_pstate: Use HWP to initialize ITMT if CPPC is missing
+    - irqchip/loongson-eiointc: Use early_cpu_to_node() instead of cpu_to_node()
+    - cpu/hotplug: Fix dynstate assignment in __cpuhp_setup_state_cpuslocked()
+    - irqchip/loongson-liointc: Set different ISRs for different cores
+    - kbuild: Install dtb files as 0644 in Makefile.dtbinst
+    - sh: rework sync_file_range ABI
+    - btrfs: zoned: fix initial free space detection
+    - csky, hexagon: fix broken sys_sync_file_range
+    - hexagon: fix fadvise64_64 calling conventions
+    - drm/drm_file: Fix pid refcounting race
+    - drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_ld_modes
+    - drm/fbdev-dma: Only set smem_start is enable per module option
+    - drm/amdgpu: avoid using null object of framebuffer
+    - drm/i915/gt: Fix potential UAF by revoke of fence registers
+    - drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_hd_modes
+    - drm/amd/display: Send DP_TOTAL_LTTPR_CNT during detection if LTTPR is
+      present
+    - drm/amdgpu/atomfirmware: fix parsing of vram_info
+    - batman-adv: Don't accept TT entries for out-of-spec VIDs
+    - can: mcp251xfd: fix infinite loop when xmit fails
+    - ata: ahci: Clean up sysfs file on error
+    - ata: libata-core: Fix double free on error
+    - ftruncate: pass a signed offset
+    - syscalls: fix compat_sys_io_pgetevents_time64 usage
+    - syscalls: fix sys_fanotify_mark prototype
+    - Revert "cpufreq: amd-pstate: Fix the inconsistency in max frequency units"
+    - mm/page_alloc: Separate THP PCP into movable and non-movable categories
+    - arm64: dts: rockchip: Fix SD NAND and eMMC init on rk3308-rock-pi-s
+    - arm64: dts: rockchip: Rename LED related pinctrl nodes on rk3308-rock-pi-s
+    - arm64: dts: rockchip: Fix the value of `dlg,jack-det-rate` mismatch on
+      rk3399-gru
+    - ARM: dts: rockchip: rk3066a: add #sound-dai-cells to hdmi node
+    - arm64: dts: rockchip: make poweroff(8) work on Radxa ROCK 5A
+    - arm64: dts: rockchip: fix PMIC interrupt pin on ROCK Pi E
+    - arm64: dts: rockchip: Add sound-dai-cells for RK3368
+    - cxl/region: Move cxl_dpa_to_region() work to the region driver
+    - cxl/region: Avoid null pointer dereference in region lookup
+    - cxl/region: check interleave capability
+    - serial: imx: only set receiver level if it is zero
+    - serial: 8250_omap: Fix Errata i2310 with RX FIFO level check
+    - tracing/net_sched: NULL pointer dereference in perf_trace_qdisc_reset()
+    - pwm: stm32: Improve precision of calculation in .apply()
+    - pwm: stm32: Fix for settings using period > UINT32_MAX
+    - pwm: stm32: Calculate prescaler with a division instead of a loop
+    - pwm: stm32: Refuse too small period requests
+    - ASoC: cs42l43: Increase default type detect time and button delay
+    - ASoC: amd: acp: move chip->flag variable assignment
+    - bonding: fix incorrect software timestamping report
+    - mlxsw: pci: Fix driver initialization with Spectrum-4
+    - vxlan: Pull inner IP header in vxlan_xmit_one().
+    - ASoC: mediatek: mt8195: Add platform entry for ETDM1_OUT_BE dai link
+    - af_unix: Stop recv(MSG_PEEK) at consumed OOB skb.
+    - af_unix: Don't stop recv(MSG_DONTWAIT) if consumed OOB skb is at the head.
+    - af_unix: Don't stop recv() at consumed ex-OOB skb.
+    - af_unix: Fix wrong ioctl(SIOCATMARK) when consumed OOB skb is at the head.
+    - bpf: Take return from set_memory_ro() into account with bpf_prog_lock_ro()
+    - bpf: Take return from set_memory_rox() into account with
+      bpf_jit_binary_lock_ro()
+    - drm/xe: Fix potential integer overflow in page size calculation
+    - drm/xe: Add a NULL check in xe_ttm_stolen_mgr_init
+    - drm/amd/display: correct hostvm flag
+    - drm/amd/display: Skip pipe if the pipe idx not set properly
+    - bpf: Add a check for struct bpf_fib_lookup size
+    - drm/xe/xe_devcoredump: Check NULL before assignments
+    - iommu/arm-smmu-v3: Do not allow a SVA domain to be set on the wrong PASID
+    - evm: Enforce signatures on unsupported filesystem for EVM_INIT_X509
+    - drm/xe: Check pat.ops before dumping PAT settings
+    - nvmet: do not return 'reserved' for empty TSAS values
+    - nvmet: make 'tsas' attribute idempotent for RDMA
+    - iommu/amd: Fix GT feature enablement again
+    - gpiolib: cdev: Ignore reconfiguration without direction
+    - kasan: fix bad call to unpoison_slab_object
+    - mm/memory: don't require head page for do_set_pmd()
+    - SUNRPC: Fix backchannel reply, again
+    - Revert "usb: gadget: u_ether: Re-attach netif device to mirror detachment"
+    - Revert "usb: gadget: u_ether: Replace netif_stop_queue with
+      netif_device_detach"
+    - tty: serial: 8250: Fix port count mismatch with the device
+    - tty: mxser: Remove __counted_by from mxser_board.ports[]
+    - nvmet-fc: Remove __counted_by from nvmet_fc_tgt_queue.fod[]
+    - ata: libata-core: Add ATA_HORKAGE_NOLPM for all Crucial BX SSD1 models
+    - bcachefs: Fix sb_field_downgrade validation
+    - bcachefs: Fix sb-downgrade validation
+    - bcachefs: Fix bch2_sb_downgrade_update()
+    - bcachefs: Fix setting of downgrade recovery passes/errors
+    - bcachefs: btree_gc can now handle unknown btrees
+    - pwm: stm32: Fix calculation of prescaler
+    - pwm: stm32: Fix error message to not describe the previous error path
+    - cxl/region: Convert cxl_pmem_region_alloc to scope-based resource management
+    - cxl/mem: Fix no cxl_nvd during pmem region auto-assembling
+    - arm64: dts: rockchip: Fix the i2c address of es8316 on Cool Pi 4B
+    - netfs: Fix netfs_page_mkwrite() to check folio->mapping is valid
+    - netfs: Fix netfs_page_mkwrite() to flush conflicting data, not wait
+    - Upstream stable to v6.6.37, v6.9.8
+  * [UBUNTU 22.04] s390/cpum_cf: make crypto counters upward compatible
+    (LP: #2074380)
+    - s390/cpum_cf: make crypto counters upward compatible across machine types
+  * CVE-2024-45016
+    - netem: fix return value if duplicate enqueue fails
+
+  [ Ubuntu: 6.8.0-45.45 ]
+
+  * noble/linux: 6.8.0-45.45 -proposed tracker (LP: #2078100)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/s2024.08.05)
+  * Noble update: upstream stable patchset 2024-08-09 (LP: #2076435) //
+    CVE-2024-41009
+    - bpf: Fix overrunning reservations in ringbuf
+  * CVE-2024-42160
+    - f2fs: check validation of fault attrs in f2fs_build_fault_attr()
+    - f2fs: Add inline to f2fs_build_fault_attr() stub
+  * Noble update: upstream stable patchset 2024-08-22 (LP: #2077600) //
+    CVE-2024-42224
+    - net: dsa: mv88e6xxx: Correct check for empty list
+  * Noble update: upstream stable patchset 2024-08-22 (LP: #2077600) //
+    CVE-2024-42154
+    - tcp_metrics: validate source addr length
+  * CVE-2024-42228
+    - drm/amdgpu: Using uninitialized value *size when calling amdgpu_vce_cs_reloc
+  * CVE-2024-42159
+    - scsi: mpi3mr: Sanitise num_phys
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 03 Oct 2024 23:24:01 +0900
+
+linux-qcom (6.8.0-1010.10) jammy; urgency=medium
+
+  * jammy/linux-qcom: 6.8.0-1010.10 -proposed tracker (LP: #2081038)
+
+  * Disable PCI_DYNAMIC_OF_NODES in Ubuntu (LP: #2074376)
+    - [Config] Disable PCI_DYNAMIC_OF_NODES
+
+  * Reenable CONFIG_UBSAN for noble (LP: #2076650)
+    - [Config] Remove CONFIG_UBSAN_SANITIZE_ALL
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update update.conf
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] create linux-libc-dev-qcom package
+    - SAUCE: rdbg: include <linux/platform_device.h>
+    - SAUCE: add empty dkms-versions
+
+  * Miscellaneous upstream changes
+    - Ubuntu: [Config] enable more CONFIG options based on GA 1.1
+
+  [ Ubuntu: 6.8.0-44.44 ]
+
+  * noble/linux: 6.8.0-44.44 -proposed tracker (LP: #2076647)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2024.08.05)
+  * Disable PCI_DYNAMIC_OF_NODES in Ubuntu (LP: #2074376)
+    - [Config] Disable PCI_DYNAMIC_OF_NODES
+  * [SRU] Turbostat support for Arrow Lake H (LP: #2074372)
+    - tools/power turbostat: Enhance ARL/LNL support
+    - x86/cpu: Add model number for another Intel Arrow Lake mobile processor
+    - tools/power turbostat: Add ARL-H support
+  * Noble update: upstream stable patchset 2024-07-30 (LP: #2075154)
+    - fs/writeback: bail out if there is no more inodes for IO and queued once
+    - padata: Disable BH when taking works lock on MT path
+    - crypto: hisilicon/sec - Fix memory leak for sec resource release
+    - crypto: hisilicon/qm - Add the err memory release process to qm uninit
+    - io_uring/sqpoll: work around a potential audit memory leak
+    - rcutorture: Fix rcu_torture_one_read() pipe_count overflow comment
+    - rcutorture: Make stall-tasks directly exit when rcutorture tests end
+    - rcutorture: Fix invalid context warning when enable srcu barrier testing
+    - block/ioctl: prefer different overflow check
+    - ssb: Fix potential NULL pointer dereference in ssb_device_uevent()
+    - selftests/bpf: Prevent client connect before server bind in
+      test_tc_tunnel.sh
+    - selftests/bpf: Fix flaky test btf_map_in_map/lookup_update
+    - batman-adv: bypass empty buckets in batadv_purge_orig_ref()
+    - wifi: ath9k: work around memset overflow warning
+    - af_packet: avoid a false positive warning in packet_setsockopt()
+    - ACPI: x86: Add PNP_UART1_SKIP quirk for Lenovo Blade2 tablets
+    - drop_monitor: replace spin_lock by raw_spin_lock
+    - scsi: qedi: Fix crash while reading debugfs attribute
+    - net: sfp: add quirk for ATS SFP-GE-T 1000Base-TX module
+    - net/sched: fix false lockdep warning on qdisc root lock
+    - kselftest: arm64: Add a null pointer check
+    - net: dsa: realtek: keep default LED state in rtl8366rb
+    - netpoll: Fix race condition in netpoll_owner_active
+    - wifi: mt76: mt7921s: fix potential hung tasks during chip recovery
+    - HID: Add quirk for Logitech Casa touchpad
+    - HID: asus: fix more n-key report descriptors if n-key quirked
+    - ACPI: video: Add backlight=native quirk for Lenovo Slim 7 16ARH7
+    - Bluetooth: ath3k: Fix multiple issues reported by checkpatch.pl
+    - drm/amd/display: Exit idle optimizations before HDCP execution
+    - platform/x86: toshiba_acpi: Add quirk for buttons on Z830
+    - ASoC: Intel: sof_sdw: add JD2 quirk for HP Omen 14
+    - ASoC: Intel: sof_sdw: add quirk for Dell SKU 0C0F
+    - drm/lima: add mask irq callback to gp and pp
+    - drm/lima: mask irqs in timeout path before hard reset
+    - ALSA: hda/realtek: Add quirks for Lenovo 13X
+    - powerpc/pseries: Enforce hcall result buffer validity and size
+    - media: intel/ipu6: Fix build with !ACPI
+    - media: mtk-vcodec: potential null pointer deference in SCP
+    - powerpc/io: Avoid clang null pointer arithmetic warnings
+    - platform/x86: p2sb: Don't init until unassigned resources have been assigned
+    - power: supply: cros_usbpd: provide ID table for avoiding fallback match
+    - iommu/arm-smmu-v3: Free MSIs in case of ENOMEM
+    - ext4: fix uninitialized ratelimit_state->lock access in __ext4_fill_super()
+    - kprobe/ftrace: bail out if ftrace was killed
+    - usb: gadget: uvc: configfs: ensure guid to be valid before set
+    - f2fs: remove clear SB_INLINECRYPT flag in default_options
+    - usb: misc: uss720: check for incompatible versions of the Belkin F5U002
+    - Avoid hw_desc array overrun in dw-axi-dmac
+    - usb: dwc3: pci: Don't set "linux,phy_charger_detect" property on Lenovo Yoga
+      Tab2 1380
+    - usb: typec: ucsi_glink: drop special handling for CCI_BUSY
+    - udf: udftime: prevent overflow in udf_disk_stamp_to_time()
+    - PCI/PM: Avoid D3cold for HP Pavilion 17 PC/1972 PCIe Ports
+    - f2fs: don't set RO when shutting down f2fs
+    - MIPS: Octeon: Add PCIe link status check
+    - serial: imx: Introduce timeout when waiting on transmitter empty
+    - serial: exar: adding missing CTI and Exar PCI ids
+    - usb: gadget: function: Remove usage of the deprecated ida_simple_xx() API
+    - tty: add the option to have a tty reject a new ldisc
+    - vfio/pci: Collect hot-reset devices to local buffer
+    - cpufreq: amd-pstate: fix memory leak on CPU EPP exit
+    - ACPI: EC: Install address space handler at the namespace root
+    - PCI: Do not wait for disconnected devices when resuming
+    - ALSA: hda: cs35l41: Possible null pointer dereference in
+      cs35l41_hda_unbind()
+    - ALSA: seq: ump: Fix missing System Reset message handling
+    - MIPS: Routerboard 532: Fix vendor retry check code
+    - mips: bmips: BCM6358: make sure CBR is correctly set
+    - tracing: Build event generation tests only as modules
+    - ALSA: hda/realtek: Remove Framework Laptop 16 from quirks
+    - ALSA/hda: intel-dsp-config: Document AVS as dsp_driver option
+    - ice: avoid IRQ collision to fix init failure on ACPI S3 resume
+    - btrfs: zoned: allocate dummy checksums for zoned NODATASUM writes
+    - net: mvpp2: use slab_build_skb for oversized frames
+    - cipso: fix total option length computation
+    - ALSA: hda: cs35l56: Component should be unbound before deconstruction
+    - ALSA: hda: tas2781: Component should be unbound before deconstruction
+    - bpf: Avoid splat in pskb_pull_reason
+    - ALSA: hda/realtek: Enable headset mic on IdeaPad 330-17IKB 81DM
+    - netrom: Fix a memory leak in nr_heartbeat_expiry()
+    - ipv6: prevent possible NULL deref in fib6_nh_init()
+    - ipv6: prevent possible NULL dereference in rt6_probe()
+    - xfrm6: check ip6_dst_idev() return value in xfrm6_get_saddr()
+    - netns: Make get_net_ns() handle zero refcount net
+    - qca_spi: Make interrupt remembering atomic
+    - net: lan743x: disable WOL upon resume to restore full data path operation
+    - net: lan743x: Support WOL at both the PHY and MAC appropriately
+    - net: phy: mxl-gpy: Remove interrupt mask clearing from config_init
+    - net/sched: act_api: fix possible infinite loop in tcf_idr_check_alloc()
+    - tipc: force a dst refcount before doing decryption
+    - sched: act_ct: add netns into the key of tcf_ct_flow_table
+    - ptp: fix integer overflow in max_vclocks_store
+    - selftests: openvswitch: Use bash as interpreter
+    - net: stmmac: No need to calculate speed divider when offload is disabled
+    - virtio_net: checksum offloading handling fix
+    - virtio_net: fixing XDP for fully checksummed packets handling
+    - octeontx2-pf: Add error handling to VLAN unoffload handling
+    - octeontx2-pf: Fix linking objects into multiple modules
+    - netfilter: ipset: Fix suspicious rcu_dereference_protected()
+    - seg6: fix parameter passing when calling NF_HOOK() in End.DX4 and End.DX6
+      behaviors
+    - netfilter: move the sysctl nf_hooks_lwtunnel into the netfilter core
+    - ice: Fix VSI list rule with ICE_SW_LKUP_LAST type
+    - bnxt_en: Restore PTP tx_avail count in case of skb_pad() error
+    - net: usb: rtl8150 fix unintiatilzed variables in rtl8150_get_link_ksettings
+    - RDMA/bnxt_re: Fix the max msix vectors macro
+    - spi: cs42l43: Correct SPI root clock speed
+    - RDMA/rxe: Fix responder length checking for UD request packets
+    - regulator: core: Fix modpost error "regulator_get_regmap" undefined
+    - dmaengine: idxd: Fix possible Use-After-Free in irq_process_work_list
+    - dmaengine: ioatdma: Fix leaking on version mismatch
+    - dmaengine: ioatdma: Fix error path in ioat3_dma_probe()
+    - dmaengine: ioatdma: Fix kmemleak in ioat_pci_probe()
+    - dmaengine: fsl-edma: avoid linking both modules
+    - dmaengine: ioatdma: Fix missing kmem_cache_destroy()
+    - regulator: bd71815: fix ramp values
+    - thermal/drivers/mediatek/lvts_thermal: Return error in case of invalid efuse
+      data
+    - arm64: dts: imx8mp: Fix TC9595 input clock on DH i.MX8M Plus DHCOM SoM
+    - arm64: dts: freescale: imx8mp-venice-gw73xx-2x: fix BT shutdown GPIO
+    - arm64: dts: imx93-11x11-evk: Remove the 'no-sdio' property
+    - arm64: dts: freescale: imx8mm-verdin: enable hysteresis on slow input pin
+    - ACPICA: Revert "ACPICA: avoid Info: mapping multiple BARs. Your kernel is
+      fine."
+    - spi: spi-imx: imx51: revert burst length calculation back to bits_per_word
+    - io_uring/rsrc: fix incorrect assignment of iter->nr_segs in io_import_fixed
+    - firmware: psci: Fix return value from psci_system_suspend()
+    - RDMA/mlx5: Fix unwind flow as part of mlx5_ib_stage_init_init
+    - RDMA/mlx5: Add check for srq max_sge attribute
+    - RDMA/mana_ib: Ignore optional access flags for MRs
+    - ACPI: EC: Evaluate orphan _REG under EC device
+    - arm64: defconfig: enable the vf610 gpio driver
+    - ext4: avoid overflow when setting values via sysfs
+    - ext4: fix slab-out-of-bounds in ext4_mb_find_good_group_avg_frag_lists()
+    - net: stmmac: Assign configured channel value to EXTTS event
+    - net: usb: ax88179_178a: improve reset check
+    - net: do not leave a dangling sk pointer, when socket creation fails
+    - btrfs: retry block group reclaim without infinite loop
+    - scsi: ufs: core: Free memory allocated for model before reinit
+    - cifs: fix typo in module parameter enable_gcm_256
+    - LoongArch: Fix watchpoint setting error
+    - LoongArch: Trigger user-space watchpoints correctly
+    - LoongArch: Fix multiple hardware watchpoint issues
+    - KVM: Fix a data race on last_boosted_vcpu in kvm_vcpu_on_spin()
+    - KVM: arm64: Disassociate vcpus from redistributor region on teardown
+    - KVM: x86: Always sync PIR to IRR prior to scanning I/O APIC routes
+    - RDMA/rxe: Fix data copy for IB_SEND_INLINE
+    - RDMA/mlx5: Remove extra unlock on error path
+    - RDMA/mlx5: Follow rb_key.ats when creating new mkeys
+    - ovl: fix encoding fid for lower only root
+    - ALSA: hda/realtek: Limit mic boost on N14AP7
+    - ALSA: hda/realtek: Add quirk for Lenovo Yoga Pro 7 14AHP9
+    - drm/i915/mso: using joiner is not possible with eDP MSO
+    - drm/radeon: fix UBSAN warning in kv_dpm.c
+    - drm/amdgpu: fix UBSAN warning in kv_dpm.c
+    - dt-bindings: dma: fsl-edma: fix dma-channels constraints
+    - ocfs2: fix NULL pointer dereference in ocfs2_journal_dirty()
+    - ocfs2: fix NULL pointer dereference in ocfs2_abort_trigger()
+    - gcov: add support for GCC 14
+    - kcov: don't lose track of remote references during softirqs
+    - efi/x86: Free EFI memory map only when installing a new one.
+    - serial: 8250_dw: Revert "Move definitions to the shared header"
+    - mm: mmap: allow for the maximum number of bits for randomizing mmap_base by
+      default
+    - tcp: clear tp->retrans_stamp in tcp_rcv_fastopen_synack()
+    - mm/page_table_check: fix crash on ZONE_DEVICE
+    - i2c: ocores: set IACK bit after core is enabled
+    - dt-bindings: i2c: atmel,at91sam: correct path to i2c-controller schema
+    - dt-bindings: i2c: google,cros-ec-i2c-tunnel: correct path to i2c-controller
+      schema
+    - spi: stm32: qspi: Fix dual flash mode sanity test in stm32_qspi_setup()
+    - arm64: dts: imx8qm-mek: fix gpio number for reg_usdhc2_vmmc
+    - spi: stm32: qspi: Clamp stm32_qspi_get_mode() output to CCR_BUSWIDTH_4
+    - perf: script: add raw|disasm arguments to --insn-trace option
+    - nbd: Improve the documentation of the locking assumptions
+    - nbd: Fix signal handling
+    - tracing: Add MODULE_DESCRIPTION() to preemptirq_delay_test
+    - x86/cpu/vfm: Add new macros to work with (vendor/family/model) values
+    - x86/cpu: Fix x86_match_cpu() to match just X86_VENDOR_INTEL
+    - drm/amd/display: revert Exit idle optimizations before HDCP execution
+    - ASoC: Intel: sof-sdw: really remove FOUR_SPEAKER quirk
+    - net/sched: unregister lockdep keys in qdisc_create/qdisc_alloc error path
+    - kprobe/ftrace: fix build error due to bad function definition
+    - hid: asus: asus_report_fixup: fix potential read out of bounds
+    - Revert "mm: mmap: allow for the maximum number of bits for randomizing
+      mmap_base by default"
+    - platform/chrome: cros_usbpd_logger: provide ID table for avoiding fallback
+      match
+    - platform/chrome: cros_usbpd_notify: provide ID table for avoiding fallback
+      match
+    - ubsan: Avoid i386 UBSAN handler crashes with Clang
+    - arm64: defconfig: select INTERCONNECT_QCOM_SM6115 as built-in
+    - bpf: Avoid kfree_rcu() under lock in bpf_lpm_trie.
+    - devlink: use kvzalloc() to allocate devlink instance resources
+    - wifi: rtw89: 8852c: add quirk to set PCI BER for certain platforms
+    - clocksource: Make watchdog and suspend-timing multiplication overflow safe
+    - ACPI: resource: Do IRQ override on GMxBGxx (XMG APEX 17 M23)
+    - wifi: ath12k: add string type to search board data in board-2.bin for
+      WCN7850
+    - wifi: ath12k: add firmware-2.bin support
+    - wifi: ath12k: fix kernel crash during resume
+    - arm64/sysreg: Update PIE permission encodings
+    - ACPI: resource: Skip IRQ override on Asus Vivobook Pro N6506MV
+    - wifi: ath12k: fix the problem that down grade phy mode operation
+    - bpf: avoid uninitialized warnings in verifier_global_subprogs.c
+    - selftests: net: fix timestamp not arriving in cmsg_time.sh
+    - net: ena: Add validation for completion descriptors consistency
+    - drm/amd/display: Workaround register access in idle race with cursor
+    - cgroup/cpuset: Make cpuset hotplug processing synchronous
+    - platform/x86: x86-android-tablets: Unregister devices in reverse order
+    - platform/x86: x86-android-tablets: Add Lenovo Yoga Tablet 2 Pro 1380F/L data
+    - ALSA: hda/realtek: Add quirks for HP Omen models using CS35L41
+    - ext4: fold quota accounting into ext4_xattr_inode_lookup_create()
+    - ext4: do not create EA inode under buffer lock
+    - f2fs: fix to detect inconsistent nat entry during truncation
+    - usb: typec: ucsi_glink: rework quirks implementation
+    - xhci: remove XHCI_TRUST_TX_LENGTH quirk
+    - clk: Add a devm variant of clk_rate_exclusive_get()
+    - clk: Provide !COMMON_CLK dummy for devm_clk_rate_exclusive_get()
+    - i2c: lpi2c: Avoid calling clk_get_rate during transfer
+    - cxl: Add post-reset warning if reset results in loss of previously committed
+      HDM decoders
+    - OPP: Fix required_opp_tables for multiple genpds using same table
+    - wifi: iwlwifi: mvm: fix ROC version check
+    - wifi: mac80211: Recalc offload when monitor stop
+    - ice: fix 200G link speed message log
+    - ice: implement AQ download pkg retry
+    - bpf: Fix reg_set_min_max corruption of fake_reg
+    - ALSA: hda: cs35l41: Component should be unbound before deconstruction
+    - netdev-genl: fix error codes when outputting XDP features
+    - arm64: dts: freescale: imx8mm-verdin: Fix GPU speed
+    - phy: qcom-qmp: qserdes-txrx: Add missing registers offsets
+    - phy: qcom-qmp: pcs: Add missing v6 N4 register offsets
+    - phy: qcom: qmp-combo: Switch from V6 to V6 N4 register offsets
+    - powerpc/crypto: Add generated P8 asm to .gitignore
+    - spi: Exctract spi_dev_check_cs() helper
+    - spi: Fix SPI slave probe failure
+    - net: phy: dp83tg720: wake up PHYs in managed mode
+    - net: phy: dp83tg720: get master/slave configuration in link down state
+    - RDMA/mlx5: Ensure created mkeys always have a populated rb_key
+    - drm/amdgpu: fix locking scope when flushing tlb
+    - drm/amd/display: Remove redundant idle optimization check
+    - drm/amd/display: Attempt to avoid empty TUs when endpoint is DPIA
+    - ata: ahci: Do not enable LPM if no LPM states are supported by the HBA
+    - dmaengine: xilinx: xdma: Fix data synchronisation in xdma_channel_isr()
+    - net/tcp_ao: Don't leak ao_info on error-path
+    - mm: shmem: fix getting incorrect lruvec when replacing a shmem folio
+    - selftests: mptcp: print_test out of verify_listener_events
+    - selftests: mptcp: userspace_pm: fixed subtest names
+    - ima: Avoid blocking in RCU read-side critical section
+    - virt: guest_memfd: fix reference leak on hwpoisoned page
+    - thermal: int340x: processor_thermal: Support shared interrupts
+    - thermal: core: Change PM notifier priority to the minimum
+    - wifi: ath12k: check M3 buffer size as well whey trying to reuse it
+    - Upstream stable to v6.6.36, v6.9.7
+  * [SRU] Add Dynamic Tuning Technology (DTT)  support for Lunar Lake
+    (LP: #2073961)
+    - thermal: int340x: processor_thermal: Add Lunar Lake-M PCI ID
+  * Kubuntu 24.04 freezes after plugging in ethernet cable (LP: #2073358)
+    - e1000e: move force SMBUS near the end of enable_ulp function
+    - e1000e: fix force smbus during suspend flow
+  * Noble update: upstream stable patchset 2024-07-25 (LP: #2074091)
+    - wifi: mac80211: mesh: Fix leak of mesh_preq_queue objects
+    - wifi: mac80211: Fix deadlock in ieee80211_sta_ps_deliver_wakeup()
+    - wifi: cfg80211: fully move wiphy work to unbound workqueue
+    - wifi: cfg80211: Lock wiphy in cfg80211_get_station
+    - wifi: cfg80211: pmsr: use correct nla_get_uX functions
+    - wifi: iwlwifi: mvm: don't initialize csa_work twice
+    - wifi: iwlwifi: mvm: revert gen2 TX A-MPDU size to 64
+    - wifi: iwlwifi: mvm: set properly mac header
+    - wifi: iwlwifi: dbg_ini: move iwl_dbg_tlv_free outside of debugfs ifdef
+    - wifi: iwlwifi: mvm: check n_ssids before accessing the ssids
+    - wifi: iwlwifi: mvm: don't read past the mfuart notifcation
+    - wifi: mac80211: correctly parse Spatial Reuse Parameter Set element
+    - scsi: ufs: mcq: Fix error output and clean up ufshcd_mcq_abort()
+    - RISC-V: KVM: No need to use mask when hart-index-bit is 0
+    - RISC-V: KVM: Fix incorrect reg_subtype labels in
+      kvm_riscv_vcpu_set_reg_isa_ext function
+    - ax25: Fix refcount imbalance on inbound connections
+    - ax25: Replace kfree() in ax25_dev_free() with ax25_dev_put()
+    - net/ncsi: Fix the multi thread manner of NCSI driver
+    - net: phy: micrel: fix KSZ9477 PHY issues after suspend/resume
+    - bpf: Fix a potential use-after-free in bpf_link_free()
+    - KVM: SEV-ES: Disallow SEV-ES guests when X86_FEATURE_LBRV is absent
+    - KVM: SEV-ES: Delegate LBR virtualization to the processor
+    - vmxnet3: disable rx data ring on dma allocation failure
+    - ipv6: ioam: block BH from ioam6_output()
+    - ipv6: sr: block BH in seg6_output_core() and seg6_input_core()
+    - net: tls: fix marking packets as decrypted
+    - bpf: Set run context for rawtp test_run callback
+    - octeontx2-af: Always allocate PF entries from low prioriy zone
+    - net/smc: avoid overwriting when adjusting sock bufsizes
+    - net: phy: Micrel KSZ8061: fix errata solution not taking effect problem
+    - net: sched: sch_multiq: fix possible OOB write in multiq_tune()
+    - vxlan: Fix regression when dropping packets due to invalid src addresses
+    - tcp: count CLOSE-WAIT sockets for TCP_MIB_CURRESTAB
+    - mptcp: count CLOSE-WAIT sockets for MPTCP_MIB_CURRESTAB
+    - net/mlx5: Stop waiting for PCI if pci channel is offline
+    - net/mlx5: Always stop health timer during driver removal
+    - net/mlx5: Fix tainted pointer delete is case of flow rules creation fail
+    - net/sched: taprio: always validate TCA_TAPRIO_ATTR_PRIOMAP
+    - ptp: Fix error message on failed pin verification
+    - ice: fix iteration of TLVs in Preserved Fields Area
+    - ice: remove af_xdp_zc_qps bitmap
+    - ice: add flag to distinguish reset from .ndo_bpf in XDP rings config
+    - net: wwan: iosm: Fix tainted pointer delete is case of region creation fail
+    - af_unix: Set sk->sk_state under unix_state_lock() for truly disconencted
+      peer.
+    - af_unix: Annodate data-races around sk->sk_state for writers.
+    - af_unix: Annotate data-race of sk->sk_state in unix_inq_len().
+    - af_unix: Annotate data-races around sk->sk_state in unix_write_space() and
+      poll().
+    - af_unix: Annotate data-race of sk->sk_state in unix_stream_connect().
+    - af_unix: Annotate data-races around sk->sk_state in sendmsg() and recvmsg().
+    - af_unix: Annotate data-race of sk->sk_state in unix_stream_read_skb().
+    - af_unix: Annotate data-races around sk->sk_state in UNIX_DIAG.
+    - af_unix: Annotate data-races around sk->sk_sndbuf.
+    - af_unix: Annotate data-race of net->unx.sysctl_max_dgram_qlen.
+    - af_unix: Use unix_recvq_full_lockless() in unix_stream_connect().
+    - af_unix: Use skb_queue_empty_lockless() in unix_release_sock().
+    - af_unix: Use skb_queue_len_lockless() in sk_diag_show_rqlen().
+    - af_unix: Annotate data-race of sk->sk_shutdown in sk_diag_fill().
+    - ipv6: fix possible race in __fib6_drop_pcpu_from()
+    - net: ethtool: fix the error condition in ethtool_get_phy_stats_ethtool()
+    - selftests/mm: log a consistent test name for check_compaction
+    - irqchip/riscv-intc: Allow large non-standard interrupt number
+    - irqchip/riscv-intc: Introduce Andes hart-level interrupt controller
+    - eventfs: Update all the eventfs_inodes from the events descriptor
+    - io_uring/rsrc: don't lock while !TASK_RUNNING
+    - io_uring: check for non-NULL file pointer in io_file_can_poll()
+    - USB: class: cdc-wdm: Fix CPU lockup caused by excessive log messages
+    - USB: xen-hcd: Traverse host/ when CONFIG_USB_XEN_HCD is selected
+    - usb: typec: tcpm: fix use-after-free case in tcpm_register_source_caps
+    - usb: typec: tcpm: Ignore received Hard Reset in TOGGLING state
+    - mei: me: release irq in mei_me_pci_resume error path
+    - tty: n_tty: Fix buffer offsets when lookahead is used
+    - serial: port: Don't block system suspend even if bytes are left to xmit
+    - landlock: Fix d_parent walk
+    - jfs: xattr: fix buffer overflow for invalid xattr
+    - xhci: Set correct transferred length for cancelled bulk transfers
+    - xhci: Apply reset resume quirk to Etron EJ188 xHCI host
+    - xhci: Handle TD clearing for multiple streams case
+    - xhci: Apply broken streams quirk to Etron EJ188 xHCI host
+    - thunderbolt: debugfs: Fix margin debugfs node creation condition
+    - scsi: core: Disable CDL by default
+    - scsi: mpi3mr: Fix ATA NCQ priority support
+    - scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory
+    - scsi: sd: Use READ(16) when reading block zero on large capacity disks
+    - gve: Clear napi->skb before dev_kfree_skb_any()
+    - powerpc/uaccess: Fix build errors seen with GCC 13/14
+    - HID: nvidia-shield: Add missing check for input_ff_create_memless
+    - cxl/test: Add missing vmalloc.h for tools/testing/cxl/test/mem.c
+    - cxl/region: Fix memregion leaks in devm_cxl_add_region()
+    - cachefiles: add output string to cachefiles_obj_[get|put]_ondemand_fd
+    - cachefiles: remove requests from xarray during flushing requests
+    - cachefiles: add spin_lock for cachefiles_ondemand_info
+    - cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd()
+    - cachefiles: fix slab-use-after-free in cachefiles_ondemand_daemon_read()
+    - cachefiles: remove err_put_fd label in cachefiles_ondemand_daemon_read()
+    - cachefiles: never get a new anonymous fd if ondemand_id is valid
+    - cachefiles: defer exposing anon_fd until after copy_to_user() succeeds
+    - cachefiles: flush all requests after setting CACHEFILES_DEAD
+    - selftests/ftrace: Fix to check required event file
+    - clk: sifive: Do not register clkdevs for PRCI clocks
+    - NFSv4.1 enforce rootpath check in fs_location query
+    - SUNRPC: return proper error from gss_wrap_req_priv
+    - NFS: add barriers when testing for NFS_FSDATA_BLOCKED
+    - selftests/tracing: Fix event filter test to retry up to 10 times
+    - nvme: fix nvme_pr_* status code parsing
+    - drm/panel: sitronix-st7789v: Add check for of_drm_get_panel_orientation
+    - platform/x86: dell-smbios: Fix wrong token data in sysfs
+    - gpio: tqmx86: fix typo in Kconfig label
+    - gpio: tqmx86: introduce shadow register for GPIO output value
+    - gpio: tqmx86: store IRQ trigger type and unmask status separately
+    - gpio: tqmx86: fix broken IRQ_TYPE_EDGE_BOTH interrupt type
+    - HID: core: remove unnecessary WARN_ON() in implement()
+    - iommu/amd: Fix sysfs leak in iommu init
+    - iommu: Return right value in iommu_sva_bind_device()
+    - io_uring/io-wq: Use set_bit() and test_bit() at worker->flags
+    - io_uring/io-wq: avoid garbage value of 'match' in io_wq_enqueue()
+    - HID: logitech-dj: Fix memory leak in logi_dj_recv_switch_to_dj_mode()
+    - drm/vmwgfx: Refactor drm connector probing for display modes
+    - drm/vmwgfx: Filter modes which exceed graphics memory
+    - drm/vmwgfx: 3D disabled should not effect STDU memory limits
+    - drm/vmwgfx: Remove STDU logic from generic mode_valid function
+    - drm/vmwgfx: Don't memcmp equivalent pointers
+    - af_unix: Annotate data-race of sk->sk_state in unix_accept().
+    - modpost: do not warn about missing MODULE_DESCRIPTION() for vmlinux.o
+    - net: sfp: Always call `sfp_sm_mod_remove()` on remove
+    - net: hns3: fix kernel crash problem in concurrent scenario
+    - net: hns3: add cond_resched() to hns3 ring buffer init process
+    - liquidio: Adjust a NULL pointer handling path in lio_vf_rep_copy_packet
+    - net: stmmac: dwmac-qcom-ethqos: Configure host DMA width
+    - drm/komeda: check for error-valued pointer
+    - drm/bridge/panel: Fix runtime warning on panel bridge release
+    - tcp: fix race in tcp_v6_syn_recv_sock()
+    - net dsa: qca8k: fix usages of device_get_named_child_node()
+    - geneve: Fix incorrect inner network header offset when innerprotoinherit is
+      set
+    - net/mlx5e: Fix features validation check for tunneled UDP (non-VXLAN)
+      packets
+    - Bluetooth: fix connection setup in l2cap_connect
+    - netfilter: nft_inner: validate mandatory meta and payload
+    - netfilter: ipset: Fix race between namespace cleanup and gc in the list:set
+      type
+    - x86/asm: Use %c/%n instead of %P operand modifier in asm templates
+    - x86/uaccess: Fix missed zeroing of ia32 u64 get_user() range checking
+    - scsi: ufs: core: Quiesce request queues before checking pending cmds
+    - net: pse-pd: Use EOPNOTSUPP error code instead of ENOTSUPP
+    - gve: ignore nonrelevant GSO type bits when processing TSO headers
+    - net: stmmac: replace priv->speed with the portTransmitRate from the tc-cbs
+      parameters
+    - block: sed-opal: avoid possible wrong address reference in
+      read_sed_opal_key()
+    - block: fix request.queuelist usage in flush
+    - nvmet-passthru: propagate status from id override functions
+    - net/ipv6: Fix the RT cache flush via sysctl using a previous delay
+    - net: bridge: mst: pass vlan group directly to br_mst_vlan_set_state
+    - net: bridge: mst: fix suspicious rcu usage in br_mst_set_state
+    - ionic: fix use after netif_napi_del()
+    - af_unix: Read with MSG_PEEK loops if the first unread byte is OOB
+    - bnxt_en: Adjust logging of firmware messages in case of released token in
+      __hwrm_send()
+    - misc: microchip: pci1xxxx: fix double free in the error handling of
+      gp_aux_bus_probe()
+    - ksmbd: move leading slash check to smb2_get_name()
+    - ksmbd: fix missing use of get_write in in smb2_set_ea()
+    - x86/boot: Don't add the EFI stub to targets, again
+    - iio: adc: ad9467: fix scan type sign
+    - iio: dac: ad5592r: fix temperature channel scaling value
+    - iio: invensense: fix odr switching to same value
+    - iio: imu: inv_icm42600: delete unneeded update watermark call
+    - drivers: core: synchronize really_probe() and dev_uevent()
+    - parisc: Try to fix random segmentation faults in package builds
+    - ACPI: x86: Force StorageD3Enable on more products
+    - drm/exynos/vidi: fix memory leak in .get_modes()
+    - drm/exynos: hdmi: report safe 640x480 mode as a fallback when no EDID found
+    - mptcp: ensure snd_una is properly initialized on connect
+    - mptcp: pm: inc RmAddr MIB counter once per RM_ADDR ID
+    - mptcp: pm: update add_addr counters after connect
+    - clkdev: Update clkdev id usage to allow for longer names
+    - irqchip/gic-v3-its: Fix potential race condition in its_vlpi_prop_update()
+    - x86/kexec: Fix bug with call depth tracking
+    - x86/amd_nb: Check for invalid SMN reads
+    - perf/core: Fix missing wakeup when waiting for context reference
+    - perf auxtrace: Fix multiple use of --itrace option
+    - riscv: fix overlap of allocated page and PTR_ERR
+    - tracing/selftests: Fix kprobe event name test for .isra. functions
+    - kheaders: explicitly define file modes for archived headers
+    - null_blk: Print correct max open zones limit in null_init_zoned_dev()
+    - sock_map: avoid race between sock_map_close and sk_psock_put
+    - dma-buf: handle testing kthreads creation failure
+    - vmci: prevent speculation leaks by sanitizing event in event_deliver()
+    - spmi: hisi-spmi-controller: Do not override device identifier
+    - knfsd: LOOKUP can return an illegal error value
+    - fs/proc: fix softlockup in __read_vmcore
+    - ocfs2: use coarse time for new created files
+    - ocfs2: fix races between hole punching and AIO+DIO
+    - PCI: rockchip-ep: Remove wrong mask on subsys_vendor_id
+    - dmaengine: axi-dmac: fix possible race in remove()
+    - remoteproc: k3-r5: Wait for core0 power-up before powering up core1
+    - remoteproc: k3-r5: Do not allow core1 to power up before core0 via sysfs
+    - iio: adc: axi-adc: make sure AXI clock is enabled
+    - iio: invensense: fix interrupt timestamp alignment
+    - riscv: rewrite __kernel_map_pages() to fix sleeping in invalid context
+    - rtla/timerlat: Simplify "no value" printing on top
+    - rtla/auto-analysis: Replace \t with spaces
+    - drm/i915/gt: Disarm breadcrumbs if engines are already idle
+    - drm/shmem-helper: Fix BUG_ON() on mmap(PROT_WRITE, MAP_PRIVATE)
+    - drm/i915/dpt: Make DPT object unshrinkable
+    - drm/i915: Fix audio component initialization
+    - intel_th: pci: Add Meteor Lake-S support
+    - pmdomain: ti-sci: Fix duplicate PD referrals
+    - btrfs: zoned: fix use-after-free due to race with dev replace
+    - xfs: fix imprecise logic in xchk_btree_check_block_owner
+    - xfs: fix scrub stats file permissions
+    - xfs: fix SEEK_HOLE/DATA for regions with active COW extents
+    - xfs: shrink failure needs to hold AGI buffer
+    - xfs: ensure submit buffers on LSN boundaries in error handlers
+    - xfs: allow sunit mount option to repair bad primary sb stripe values
+    - xfs: don't use current->journal_info
+    - xfs: allow cross-linking special files without project quota
+    - swiotlb: Enforce page alignment in swiotlb_alloc()
+    - swiotlb: Reinstate page-alignment for mappings >= PAGE_SIZE
+    - swiotlb: extend buffer pre-padding to alloc_align_mask if necessary
+    - tick/nohz_full: Don't abuse smp_call_function_single() in
+      tick_setup_device()
+    - mm/huge_memory: don't unpoison huge_zero_folio
+    - serial: 8250_pxa: Configure tx_loadsz to match FIFO IRQ level
+    - Revert "fork: defer linking file vma until vma is fully initialized"
+    - remoteproc: k3-r5: Jump to error handling labels in start/stop errors
+    - greybus: Fix use-after-free bug in gb_interface_release due to race
+      condition.
+    - ima: Fix use-after-free on a dentry's dname.name
+    - serial: core: Add UPIO_UNKNOWN constant for unknown port type
+    - serial: port: Introduce a common helper to read properties
+    - serial: 8250_dw: Switch to use uart_read_port_properties()
+    - serial: 8250_dw: Replace ACPI device check by a quirk
+    - serial: 8250_dw: Don't use struct dw8250_data outside of 8250_dw
+    - usb-storage: alauda: Check whether the media is initialized
+    - misc: microchip: pci1xxxx: Fix a memory leak in the error handling of
+      gp_aux_bus_probe()
+    - i2c: at91: Fix the functionality flags of the slave-only interface
+    - i2c: designware: Fix the functionality flags of the slave-only interface
+    - zap_pid_ns_processes: clear TIF_NOTIFY_SIGNAL along with TIF_SIGPENDING
+    - wifi: ath11k: fix WCN6750 firmware crash caused by 17 num_vdevs
+    - cpufreq: amd-pstate: Unify computation of
+      {max,min,nominal,lowest_nonlinear}_freq
+    - cpufreq: amd-pstate: Add quirk for the pstate CPPC capabilities missing
+    - cpufreq: amd-pstate: remove global header file
+    - virtio_net: fix possible dim status unrecoverable
+    - net: ethernet: mtk_eth_soc: handle dma buffer size soc specific
+    - ice: fix reads from NVM Shadow RAM on E830 and E825-C devices
+    - ice: map XDP queues to vectors in ice_vsi_map_rings_to_vectors()
+    - x86/cpu: Get rid of an unnecessary local variable in get_cpu_address_sizes()
+    - x86/cpu: Provide default cache line size if not enumerated
+    - selftests/mm: ksft_exit functions do not return
+    - selftests/mm: compaction_test: fix bogus test success and reduce probability
+      of OOM-killer invocation
+    - .editorconfig: remove trim_trailing_whitespace option
+    - kcov, usb: disable interrupts in kcov_remote_start_usb_softirq
+    - ata: libata-scsi: Set the RMB bit only for removable media devices
+    - powerpc/85xx: fix compile error without CONFIG_CRASH_DUMP
+    - kselftest/alsa: Ensure _GNU_SOURCE is defined
+    - thermal: core: Do not fail cdev registration because of invalid initial
+      state
+    - Bluetooth: hci_sync: Fix not using correct handle
+    - net/sched: initialize noop_qdisc owner
+    - tcp: use signed arithmetic in tcp_rtx_probe0_timed_out()
+    - drm/nouveau: don't attempt to schedule hpd_work on headless cards
+    - drm/xe/xe_gt_idle: use GT forcewake domain assertion
+    - drm/xe: flush engine buffers before signalling user fence on all engines
+    - drm/xe: Remove mem_access from guc_pc calls
+    - drm/xe: move disable_c6 call
+    - bnxt_en: Cap the size of HWRM_PORT_PHY_QCFG forwarded response
+    - iio: imu: bmi323: Fix trigger notification in case of error
+    - iio: pressure: bmp280: Fix BMP580 temperature reading
+    - iio: temperature: mlx90635: Fix ERR_PTR dereference in mlx90635_probe()
+    - thermal: ACPI: Invalidate trip points with temperature of 0 or below
+    - x86/mm/numa: Use NUMA_NO_NODE when calling memblock_set_node()
+    - memblock: make memblock_set_node() also warn about use of MAX_NUMNODES
+    - perf script: Show also errors for --insn-trace option
+    - wifi: cfg80211: validate HE operation element parsing
+    - wifi: rtlwifi: Ignore IEEE80211_CONF_CHANGE_RETRY_LIMITS
+    - locking/atomic: scripts: fix ${atomic}_sub_and_test() kerneldoc
+    - ata: ahci: Do not apply Intel PCS quirk on Intel Alder Lake
+    - ata: libata-core: Add ATA_HORKAGE_NOLPM for Apacer AS340
+    - ata: libata-core: Add ATA_HORKAGE_NOLPM for Crucial CT240BX500SSD1
+    - ata: libata-core: Add ATA_HORKAGE_NOLPM for AMD Radeon S3 SSD
+    - kexec: fix the unexpected kexec_dprintk() macro
+    - ocfs2: update inode fsync transaction id in ocfs2_unlink and ocfs2_link
+    - dm-integrity: set discard_granularity to logical block size
+    - drm/bridge: aux-hpd-bridge: correct devm_drm_dp_hpd_bridge_add() stub
+    - iio: temperature: mcp9600: Fix temperature reading for negative values
+    - drm/mst: Fix NULL pointer dereference at drm_dp_add_payload_part2
+    - riscv: force PAGE_SIZE linear mapping if debug_pagealloc is enabled
+    - drm/xe: Properly handle alloc_guc_id() failure
+    - wifi: iwlwifi: mvm: support iwl_dev_tx_power_cmd_v8
+    - wifi: iwlwifi: mvm: fix a crash on 7265
+    - mei: vsc: Fix wrong invocation of ACPI SID method
+    - Upstream stable to v6.6.35, v6.9.6
+  * [SRU] Add support for intel trace hub for last platforms (LP: #2073926) //
+    Noble update: upstream stable patchset 2024-07-25 (LP: #2074091)
+    - intel_th: pci: Add Granite Rapids support
+    - intel_th: pci: Add Granite Rapids SOC support
+    - intel_th: pci: Add Sapphire Rapids SOC support
+    - intel_th: pci: Add Lunar Lake support
+  * Fix L2CAP/LE/CPU/BV-02-C bluetooth certification failure (LP: #2072858) //
+    Noble update: upstream stable patchset 2024-07-25 (LP: #2074091)
+    - Bluetooth: L2CAP: Fix rejecting L2CAP_CONN_PARAM_UPDATE_REQ
+  * Noble update: upstream stable patchset 2024-07-22 (LP: #2073788)
+    - drm/i915/hwmon: Get rid of devm
+    - afs: Don't cross .backup mountpoint from backup volume
+    - erofs: avoid allocating DEFLATE streams before mounting
+    - vxlan: Fix regression when dropping packets due to invalid src addresses
+    - drm/sun4i: hdmi: Convert encoder to atomic
+    - drm/sun4i: hdmi: Move mode_set into enable
+    - f2fs: fix to do sanity check on i_xattr_nid in sanity_check_inode()
+    - media: lgdt3306a: Add a check against null-pointer-def
+    - drm/amdgpu: add error handle to avoid out-of-bounds
+    - wifi: rtw89: correct aSIFSTime for 6GHz band
+    - ata: pata_legacy: make legacy_exit() work again
+    - fsverity: use register_sysctl_init() to avoid kmemleak warning
+    - proc: Move fdinfo PTRACE_MODE_READ check into the inode .permission
+      operation
+    - platform/chrome: cros_ec: Handle events during suspend after resume
+      completion
+    - thermal/drivers/qcom/lmh: Check for SCM availability at probe
+    - soc: qcom: rpmh-rsc: Enhance check for VRM in-flight request
+    - ACPI: resource: Do IRQ override on TongFang GXxHRXx and GMxHGxx
+    - arm64: tegra: Correct Tegra132 I2C alias
+    - arm64: dts: qcom: qcs404: fix bluetooth device address
+    - md/raid5: fix deadlock that raid5d() wait for itself to clear
+      MD_SB_CHANGE_PENDING
+    - wifi: rtl8xxxu: Fix the TX power of RTL8192CU, RTL8723AU
+    - wifi: rtlwifi: rtl8192de: Fix 5 GHz TX power
+    - wifi: rtlwifi: rtl8192de: Fix low speed with WPA3-SAE
+    - wifi: rtlwifi: rtl8192de: Fix endianness issue in RX path
+    - arm64: dts: qcom: sc8280xp: add missing PCIe minimum OPP
+    - arm64: dts: hi3798cv200: fix the size of GICR
+    - arm64: dts: ti: verdin-am62: Set memory size to 2gb
+    - media: mc: Fix graph walk in media_pipeline_start
+    - media: mc: mark the media devnode as registered from the, start
+    - media: mxl5xx: Move xpt structures off stack
+    - media: v4l2-core: hold videodev_lock until dev reg, finishes
+    - media: v4l: async: Properly re-initialise notifier entry in unregister
+    - media: v4l: async: Don't set notifier's V4L2 device if registering fails
+    - media: v4l: async: Fix notifier list entry init
+    - mmc: core: Add mmc_gpiod_set_cd_config() function
+    - mmc: sdhci: Add support for "Tuning Error" interrupts
+    - mmc: sdhci-acpi: Sort DMI quirks alphabetically
+    - mmc: sdhci-acpi: Fix Lenovo Yoga Tablet 2 Pro 1380 sdcard slot not working
+    - mmc: sdhci-acpi: Disable write protect detection on Toshiba WT10-A
+    - mmc: sdhci-acpi: Add quirk to enable pull-up on the card-detect GPIO on Asus
+      T100TA
+    - drm/fbdev-generic: Do not set physical framebuffer address
+    - fbdev: savage: Handle err return when savagefb_check_var failed
+    - drm/amdgpu/atomfirmware: add intergrated info v2.3 table
+    - 9p: add missing locking around taking dentry fid list
+    - drm/amd: Fix shutdown (again) on some SMU v13.0.4/11 platforms
+    - Revert "drm/amdkfd: fix gfx_target_version for certain 11.0.3 devices"
+    - KVM: SVM: WARN on vNMI + NMI window iff NMIs are outright masked
+    - KVM: arm64: Fix AArch32 register narrowing on userspace write
+    - KVM: arm64: Allow AArch32 PSTATE.M to be restored as System mode
+    - KVM: arm64: AArch32: Fix spurious trapping of conditional instructions
+    - LoongArch: Add all CPUs enabled by fdt to NUMA node 0
+    - LoongArch: Override higher address bits in JUMP_VIRT_ADDR
+    - clk: bcm: dvp: Assign ->num before accessing ->hws
+    - clk: bcm: rpi: Assign ->num before accessing ->hws
+    - clk: qcom: clk-alpha-pll: fix rate setting for Stromer PLLs
+    - crypto: ecdsa - Fix module auto-load on add-key
+    - crypto: ecrdsa - Fix module auto-load on add_key
+    - crypto: qat - Fix ADF_DEV_RESET_SYNC memory leak
+    - kbuild: Remove support for Clang's ThinLTO caching
+    - mm: fix race between __split_huge_pmd_locked() and GUP-fast
+    - filemap: add helper mapping_max_folio_size()
+    - iomap: fault in smaller chunks for non-large folio mappings
+    - i2c: acpi: Unbind mux adapters before delete
+    - HID: i2c-hid: elan: fix reset suspend current leakage
+    - scsi: core: Handle devices which return an unusually large VPD page count
+    - net/ipv6: Fix route deleting failure when metric equals 0
+    - net/9p: fix uninit-value in p9_client_rpc()
+    - mm/ksm: fix ksm_pages_scanned accounting
+    - mm/ksm: fix ksm_zero_pages accounting
+    - kmsan: do not wipe out origin when doing partial unpoisoning
+    - tpm_tis: Do *not* flush uninitialized work
+    - intel_th: pci: Add Meteor Lake-S CPU support
+    - rtla/timerlat: Fix histogram report when a cpu count is 0
+    - sparc64: Fix number of online CPUs
+    - mm/cma: drop incorrect alignment check in cma_init_reserved_mem
+    - mm/hugetlb: pass correct order_per_bit to cma_declare_contiguous_nid
+    - mm: /proc/pid/smaps_rollup: avoid skipping vma after getting mmap_lock again
+    - mm/vmalloc: fix vmalloc which may return null if called with __GFP_NOFAIL
+    - selftests/mm: compaction_test: fix incorrect write of zero to nr_hugepages
+    - selftests/mm: fix build warnings on ppc64
+    - watchdog: rti_wdt: Set min_hw_heartbeat_ms to accommodate a safety margin
+    - bonding: fix oops during rmmod
+    - wifi: ath10k: fix QCOM_RPROC_COMMON dependency
+    - kdb: Fix buffer overflow during tab-complete
+    - kdb: Use format-strings rather than '\0' injection in kdb_read()
+    - kdb: Fix console handling when editing and tab-completing commands
+    - kdb: Merge identical case statements in kdb_read()
+    - kdb: Use format-specifiers rather than memset() for padding in kdb_read()
+    - sparc: move struct termio to asm/termios.h
+    - drm/amdkfd: handle duplicate BOs in reserve_bo_and_cond_vms
+    - ext4: Fixes len calculation in mpage_journal_page_buffers
+    - ext4: set type of ac_groups_linear_remaining to __u32 to avoid overflow
+    - ext4: fix mb_cache_entry's e_refcnt leak in ext4_xattr_block_cache_find()
+    - riscv: dts: starfive: Remove PMIC interrupt info for Visionfive 2 board
+    - ARM: dts: samsung: smdkv310: fix keypad no-autorepeat
+    - ARM: dts: samsung: smdk4412: fix keypad no-autorepeat
+    - ARM: dts: samsung: exynos4412-origen: fix keypad no-autorepeat
+    - parisc: Define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+    - parisc: Define sigset_t in parisc uapi header
+    - s390/ap: Fix crash in AP internal function modify_bitmap()
+    - s390/cpacf: Split and rework cpacf query functions
+    - s390/cpacf: Make use of invalid opcode produce a link error
+    - i3c: master: svc: fix invalidate IBI type and miss call client IBI handler
+    - genirq/irqdesc: Prevent use-after-free in irq_find_at_or_after()
+    - ASoC: SOF: ipc4-topology: Fix input format query of process modules without
+      base extension
+    - ALSA: ump: Don't clear bank selection after sending a program change
+    - ALSA: ump: Don't accept an invalid UMP protocol number
+    - EDAC/amd64: Convert PCIBIOS_* return codes to errnos
+    - EDAC/igen6: Convert PCIBIOS_* return codes to errnos
+    - nfs: fix undefined behavior in nfs_block_bits()
+    - NFS: Fix READ_PLUS when server doesn't support OP_READ_PLUS
+    - eventfs: Fix a possible null pointer dereference in eventfs_find_events()
+    - eventfs: Keep the directories from having the same inode number as files
+    - tracefs: Clear EVENT_INODE flag in tracefs_drop_inode()
+    - btrfs: fix crash on racing fsync and size-extending write into prealloc
+    - btrfs: fix leak of qgroup extent records after transaction abort
+    - ALSA: seq: Fix incorrect UMP type for system messages
+    - powerpc/bpf: enforce full ordering for ATOMIC operations with BPF_FETCH
+    - smb: client: fix deadlock in smb2_find_smb_tcon()
+    - smp: Provide 'setup_max_cpus' definition on UP too
+    - drm/xe/bb: assert width in xe_bb_create_job()
+    - crypto: starfive - Do not free stack buffer
+    - btrfs: qgroup: fix initialization of auto inherit array
+    - wifi: rtl8xxxu: enable MFP support with security flag of RX descriptor
+    - media: mgb4: Fix double debugfs remove
+    - media: ov2740: Fix LINK_FREQ and PIXEL_RATE control value reporting
+    - firmware: qcom_scm: disable clocks if qcom_scm_bw_enable() fails
+    - LoongArch: Fix built-in DTB detection
+    - LoongArch: Fix entry point in kernel image header
+    - clk: qcom: apss-ipq-pll: use stromer ops for IPQ5018 to fix boot failure
+    - net/tcp: Don't consider TCP_CLOSE in TCP_AO_ESTABLISHED
+    - selftests: net: lib: support errexit with busywait
+    - selftests: net: lib: avoid error removing empty netns name
+    - cpufreq: amd-pstate: Fix the inconsistency in max frequency units
+    - mm/memory-failure: fix handling of dissolved but not taken off from buddy
+      pages
+    - selftests/mm: compaction_test: fix bogus test success on Aarch64
+    - irqchip/riscv-intc: Prevent memory leak when riscv_intc_init_common() fails
+    - Revert "perf record: Reduce memory for recording PERF_RECORD_LOST_SAMPLES
+      event"
+    - hwmon: (ltc2992) Fix memory leak in ltc2992_parse_dt()
+    - riscv: enable HAVE_ARCH_HUGE_VMAP for XIP kernel
+    - btrfs: qgroup: update rescan message levels and error codes
+    - btrfs: qgroup: fix qgroup id collision across mounts
+    - btrfs: cache folio size and shift in extent_buffer
+    - btrfs: protect folio::private when attaching extent buffer folios
+    - bpf: fix multi-uprobe PID filtering logic
+    - powerpc/64/bpf: fix tail calls for PCREL addressing
+    - nilfs2: fix potential kernel bug due to lack of writeback flag waiting
+    - nilfs2: fix nilfs_empty_dir() misjudgment and long loop on I/O errors
+    - Upstream stable to v6.6.34, v6.9.5
+  * Noble update: upstream stable patchset 2024-07-19 (LP: #2073603)
+    - perf record: Delete session after stopping sideband thread
+    - perf probe: Add missing libgen.h header needed for using basename()
+    - iio: core: Leave private pointer NULL when no private data supplied
+    - greybus: lights: check return of get_channel_from_mode
+    - phy: qcom: qmp-combo: fix duplicate return in qmp_v4_configure_dp_phy
+    - f2fs: multidev: fix to recognize valid zero block address
+    - f2fs: fix to wait on page writeback in __clone_blkaddrs()
+    - fpga: manager: add owner module and take its refcount
+    - fpga: bridge: add owner module and take its refcount
+    - counter: linux/counter.h: fix Excess kernel-doc description warning
+    - perf annotate: Get rid of duplicate --group option item
+    - usb: typec: ucsi: always register a link to USB PD device
+    - usb: typec: ucsi: simplify partner's PD caps registration
+    - perf stat: Do not fail on metrics on s390 z/VM systems
+    - soundwire: cadence: fix invalid PDI offset
+    - dmaengine: idma64: Add check for dma_set_max_seg_size
+    - firmware: dmi-id: add a release callback function
+    - perf annotate: Fix annotation_calc_lines() to pass correct address to
+      get_srcline()
+    - serial: max3100: Lock port->lock when calling uart_handle_cts_change()
+    - serial: max3100: Update uart_driver_registered on driver removal
+    - serial: max3100: Fix bitwise types
+    - greybus: arche-ctrl: move device table to its right location
+    - PCI: tegra194: Fix probe path for Endpoint mode
+    - serial: sc16is7xx: add proper sched.h include for sched_set_fifo()
+    - module: don't ignore sysfs_create_link() failures
+    - interconnect: qcom: qcm2290: Fix mas_snoc_bimc QoS port assignment
+    - arm64: dts: meson: fix S4 power-controller node
+    - perf tests: Make "test data symbol" more robust on Neoverse N1
+    - perf tests: Apply attributes to all events in object code reading test
+    - perf record: Fix debug message placement for test consumption
+    - dt-bindings: PCI: rcar-pci-host: Add missing IOMMU properties
+    - perf bench uprobe: Remove lib64 from libc.so.6 binary path
+    - f2fs: compress: fix to relocate check condition in
+      f2fs_{release,reserve}_compress_blocks()
+    - f2fs: compress: fix to relocate check condition in
+      f2fs_ioc_{,de}compress_file()
+    - f2fs: fix to relocate check condition in f2fs_fallocate()
+    - f2fs: fix to check pinfile flag in f2fs_move_file_range()
+    - iio: adc: stm32: Fixing err code to not indicate success
+    - riscv: dts: starfive: visionfive 2: Remove non-existing TDM hardware
+    - coresight: etm4x: Fix unbalanced pm_runtime_enable()
+    - perf docs: Document bpf event modifier
+    - perf test shell arm_coresight: Increase buffer size for Coresight basic
+      tests
+    - iio: pressure: dps310: support negative temperature values
+    - iio: buffer-dmaengine: export buffer alloc and free functions
+    - iio: add the IIO backend framework
+    - [CONFIG] Update CONFIG_IIO_BACKEND
+    - iio: adc: ad9467: convert to backend framework
+    - [Config] Update CONFIG_AD9467
+    - iio: adc: adi-axi-adc: move to backend framework
+    - [Config] Update CONFIG_ADI_AXI_ADC
+    - iio: adc: adi-axi-adc: only error out in major version mismatch
+    - coresight: etm4x: Do not hardcode IOMEM access for register restore
+    - coresight: etm4x: Do not save/restore Data trace control registers
+    - coresight: etm4x: Safe access for TRCQCLTR
+    - coresight: etm4x: Fix access to resource selector registers
+    - vfio/pci: fix potential memory leak in vfio_intx_enable()
+    - fpga: region: add owner module and take its refcount
+    - udf: Remove GFP_NOFS allocation in udf_expand_file_adinicb()
+    - udf: Convert udf_expand_file_adinicb() to use a folio
+    - microblaze: Remove gcc flag for non existing early_printk.c file
+    - microblaze: Remove early printk call from cpuinfo-static.c
+    - PCI: Wait for Link Training==0 before starting Link retrain
+    - perf intel-pt: Fix unassigned instruction op (discovered by MemorySanitizer)
+    - leds: pwm: Disable PWM when going to suspend
+    - ovl: remove upper umask handling from ovl_create_upper()
+    - PCI: of_property: Return error for int_map allocation failure
+    - VMCI: Fix an error handling path in vmci_guest_probe_device()
+    - dt-bindings: pinctrl: mediatek: mt7622: fix array properties
+    - pinctrl: qcom: pinctrl-sm7150: Fix sdc1 and ufs special pins regs
+    - watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger
+    - watchdog: bd9576: Drop "always-running" property
+    - watchdog: sa1100: Fix PTR_ERR_OR_ZERO() vs NULL check in sa1100dog_probe()
+    - dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: fix msm899[68] power-domains
+    - dt-bindings: phy: qcom,usb-snps-femto-v2: use correct fallback for sc8180x
+    - dmaengine: idxd: Avoid unnecessary destruction of file_ida
+    - usb: gadget: u_audio: Fix race condition use of controls after free during
+      gadget unbind.
+    - usb: gadget: u_audio: Clear uac pointer when freed.
+    - stm class: Fix a double free in stm_register_device()
+    - ppdev: Add an error check in register_device
+    - i2c: cadence: Avoid fifo clear after start
+    - i2c: synquacer: Fix an error handling path in synquacer_i2c_probe()
+    - perf bench internals inject-build-id: Fix trap divide when collecting just
+      one DSO
+    - perf ui browser: Don't save pointer to stack memory
+    - extcon: max8997: select IRQ_DOMAIN instead of depending on it
+    - dt-bindings: spmi: hisilicon,hisi-spmi-controller: fix binding references
+    - PCI/EDR: Align EDR_PORT_DPC_ENABLE_DSM with PCI Firmware r3.3
+    - PCI/EDR: Align EDR_PORT_LOCATE_DSM with PCI Firmware r3.3
+    - f2fs: support printk_ratelimited() in f2fs_printk()
+    - f2fs: use BLKS_PER_SEG, BLKS_PER_SEC, and SEGS_PER_SEC
+    - f2fs: separate f2fs_gc_range() to use GC for a range
+    - f2fs: kill heap-based allocation
+    - f2fs: support file pinning for zoned devices
+    - f2fs: fix block migration when section is not aligned to pow2
+    - perf ui browser: Avoid SEGV on title
+    - perf report: Avoid SEGV in report__setup_sample_type()
+    - perf thread: Fixes to thread__new() related to initializing comm
+    - perf symbols: Fix ownership of string in dso__load_vmlinux()
+    - f2fs: compress: fix to update i_compr_blocks correctly
+    - f2fs: deprecate io_bits
+    - f2fs: introduce get_available_block_count() for cleanup
+    - f2fs: compress: fix error path of inc_valid_block_count()
+    - f2fs: compress: fix to cover {reserve,release}_compress_blocks() w/ cp_rwsem
+      lock
+    - f2fs: fix to release node block count in error path of f2fs_new_node_page()
+    - f2fs: compress: don't allow unaligned truncation on released compress inode
+    - serial: sh-sci: protect invalidating RXDMA on shutdown
+    - libsubcmd: Fix parse-options memory leak
+    - perf daemon: Fix file leak in daemon_session__control
+    - f2fs: fix to add missing iput() in gc_data_segment()
+    - usb: fotg210: Add missing kernel doc description
+    - perf stat: Don't display metric header for non-leader uncore events
+    - perf tools: Use pmus to describe type from attribute
+    - perf tools: Add/use PMU reverse lookup from config to name
+    - perf pmu: Assume sysfs events are always the same case
+    - perf pmu: Count sys and cpuid JSON events separately
+    - LoongArch: Fix callchain parse error with kernel tracepoint events again
+    - s390/vdso64: filter out munaligned-symbols flag for vdso
+    - s390/vdso: Generate unwind information for C modules
+    - s390/vdso: Create .build-id links for unstripped vdso files
+    - s390/vdso: Use standard stack frame layout
+    - s390/ipl: Fix incorrect initialization of len fields in nvme reipl block
+    - s390/ipl: Fix incorrect initialization of nvme dump block
+    - s390/boot: Remove alt_stfle_fac_list from decompressor
+    - dt-bindings: PCI: rockchip,rk3399-pcie: Add missing maxItems to ep-gpios
+    - gpiolib: acpi: Fix failed in acpi_gpiochip_find() by adding parent node
+      match
+    - eventfs: Do not differentiate the toplevel events directory
+    - eventfs: Create eventfs_root_inode to store dentry
+    - eventfs/tracing: Add callback for release of an eventfs_inode
+    - eventfs: Free all of the eventfs_inode after RCU
+    - eventfs: Have "events" directory get permissions from its parent
+    - dt-bindings: adc: axi-adc: update bindings for backend framework
+    - dt-bindings: adc: axi-adc: add clocks property
+    - Input: ims-pcu - fix printf string overflow
+    - mmc: sdhci_am654: Add tuning algorithm for delay chain
+    - mmc: sdhci_am654: Write ITAPDLY for DDR52 timing
+    - mmc: sdhci_am654: Add OTAP/ITAP delay enable
+    - mmc: sdhci_am654: Add ITAPDLYSEL in sdhci_j721e_4bit_set_clock
+    - mmc: sdhci_am654: Fix ITAPDLY for HS400 timing
+    - Input: pm8xxx-vibrator - correct VIB_MAX_LEVELS calculation
+    - media: v4l: Don't turn on privacy LED if streamon fails
+    - media: ov2680: Clear the 'ret' variable on success
+    - media: ov2680: Allow probing if link-frequencies is absent
+    - media: ov2680: Do not fail if data-lanes property is absent
+    - drm/msm/dsi: Print dual-DSI-adjusted pclk instead of original mode pclk
+    - drm/msm/dpu: Always flush the slave INTF on the CTL
+    - drm/mediatek: dp: Fix mtk_dp_aux_transfer return value
+    - drm/meson: gate px_clk when setting rate
+    - um: Fix return value in ubd_init()
+    - um: vector: fix bpfflash parameter evaluation
+    - fs/ntfs3: Check 'folio' pointer for NULL
+    - fs/ntfs3: Use 64 bit variable to avoid 32 bit overflow
+    - fs/ntfs3: Use variable length array instead of fixed size
+    - drm/msm/dpu: Add callback function pointer check before its call
+    - drm/bridge: tc358775: fix support for jeida-18 and jeida-24
+    - media: stk1160: fix bounds checking in stk1160_copy_video()
+    - Input: cyapa - add missing input core locking to suspend/resume functions
+    - drm/amdgpu: init microcode chip name from ip versions
+    - drm/amdgpu: Fix buffer size in gfx_v9_4_3_init_ cp_compute_microcode() and
+      rlc_microcode()
+    - media: mediatek: vcodec: fix possible unbalanced PM counter
+    - tools/arch/x86/intel_sdsi: Fix maximum meter bundle length
+    - tools/arch/x86/intel_sdsi: Fix meter_show display
+    - tools/arch/x86/intel_sdsi: Fix meter_certificate decoding
+    - platform/x86: thinkpad_acpi: Take hotkey_mutex during hotkey_exit()
+    - media: flexcop-usb: fix sanity check of bNumEndpoints
+    - powerpc/pseries: Add failure related checks for h_get_mpp and h_get_ppp
+    - um: Fix the -Wmissing-prototypes warning for __switch_mm
+    - um: Fix the -Wmissing-prototypes warning for get_thread_reg
+    - um: Fix the declaration of kasan_map_memory
+    - cxl/trace: Correct DPA field masks for general_media & dram events
+    - cxl/region: Fix cxlr_pmem leaks
+    - media: sunxi: a83-mips-csi2: also select GENERIC_PHY
+    - media: cec: cec-adap: always cancel work in cec_transmit_msg_fh
+    - media: cec: cec-api: add locking in cec_release()
+    - media: cec: core: avoid recursive cec_claim_log_addrs
+    - media: cec: core: avoid confusing "transmit timed out" message
+    - Revert "drm/bridge: ti-sn65dsi83: Fix enable error path"
+    - drm: zynqmp_dpsub: Always register bridge
+    - selftests/powerpc/dexcr: Add -no-pie to hashchk tests
+    - drm/msm/a6xx: Avoid a nullptr dereference when speedbin setting fails
+    - ASoC: tas2781: Fix a warning reported by robot kernel test
+    - null_blk: Fix the WARNING: modpost: missing MODULE_DESCRIPTION()
+    - ALSA: hda/cs_dsp_ctl: Use private_free for control cleanup
+    - ALSA: hda: cs35l56: Fix lifetime of cs_dsp instance
+    - ASoC: mediatek: mt8192: fix register configuration for tdm
+    - drm/nouveau: use tile_mode and pte_kind for VM_BIND bo allocations
+    - blk-cgroup: fix list corruption from resetting io stat
+    - blk-cgroup: fix list corruption from reorder of WRITE ->lqueued
+    - blk-cgroup: Properly propagate the iostat update up the hierarchy
+    - regulator: bd71828: Don't overwrite runtime voltages
+    - xen/x86: add extra pages to unpopulated-alloc if available
+    - perf/arm-dmc620: Fix lockdep assert in ->event_init()
+    - x86/kconfig: Select ARCH_WANT_FRAME_POINTERS again when
+      UNWINDER_FRAME_POINTER=y
+    - [Config] Update CONFIG_ARCH_WANT_FRAME_POINTERS
+    - net: Always descend into dsa/ folder with CONFIG_NET_DSA enabled
+    - ipv6: sr: fix missing sk_buff release in seg6_input_core
+    - selftests: net: kill smcrouted in the cleanup logic in amt.sh
+    - nfc: nci: Fix uninit-value in nci_rx_work
+    - ASoC: tas2552: Add TX path for capturing AUDIO-OUT data
+    - ASoC: tas2781: Fix wrong loading calibrated data sequence
+    - NFSv4: Fixup smatch warning for ambiguous return
+    - nfs: keep server info for remounts
+    - sunrpc: fix NFSACL RPC retry on soft mount
+    - rpcrdma: fix handling for RDMA_CM_EVENT_DEVICE_REMOVAL
+    - regulator: pickable ranges: don't always cache vsel
+    - regulator: tps6287x: Force writing VSEL bit
+    - af_unix: Update unix_sk(sk)->oob_skb under sk_receive_queue lock.
+    - ipv6: sr: fix memleak in seg6_hmac_init_algo
+    - regulator: tps6594-regulator: Correct multi-phase configuration
+    - tcp: Fix shift-out-of-bounds in dctcp_update_alpha().
+    - pNFS/filelayout: fixup pNfs allocation modes
+    - openvswitch: Set the skbuff pkt_type for proper pmtud support.
+    - arm64: asm-bug: Add .align 2 to the end of __BUG_ENTRY
+    - rv: Update rv_en(dis)able_monitor doc to match kernel-doc
+    - net: lan966x: Remove ptp traps in case the ptp is not enabled.
+    - virtio: delete vq in vp_find_vqs_msix() when request_irq() fails
+    - i3c: master: svc: change ENXIO to EAGAIN when IBI occurs during start frame
+    - Revert "ixgbe: Manual AN-37 for troublesome link partners for X550 SFI"
+    - net: fec: avoid lock evasion when reading pps_enable
+    - tls: fix missing memory barrier in tls_init
+    - net: relax socket state check at accept time.
+    - nfc: nci: Fix handling of zero-length payload packets in nci_rx_work()
+    - drivers/xen: Improve the late XenStore init protocol
+    - ice: Interpret .set_channels() input differently
+    - kasan, fortify: properly rename memintrinsics
+    - tracing/probes: fix error check in parse_btf_field()
+    - tpm_tis_spi: Account for SPI header when allocating TPM SPI xfer buffer
+    - netfilter: nfnetlink_queue: acquire rcu_read_lock() in
+      instance_destroy_rcu()
+    - netfilter: ipset: Add list flush to cancel_gc
+    - netfilter: nft_payload: restore vlan q-in-q match support
+    - spi: Don't mark message DMA mapped when no transfer in it is
+    - dma-mapping: benchmark: fix up kthread-related error handling
+    - dma-mapping: benchmark: fix node id validation
+    - dma-mapping: benchmark: handle NUMA_NO_NODE correctly
+    - nvme-multipath: fix io accounting on failover
+    - nvmet: fix ns enable/disable possible hang
+    - drm/amd/display: Enable colorspace property for MST connectors
+    - net: phy: micrel: set soft_reset callback to genphy_soft_reset for KSZ8061
+    - net/mlx5: Lag, do bond only if slaves agree on roce state
+    - net/mlx5: Fix MTMP register capability offset in MCAM register
+    - net/mlx5: Use mlx5_ipsec_rx_status_destroy to correctly delete status rules
+    - net/mlx5e: Fix IPsec tunnel mode offload feature check
+    - net/mlx5e: Use rx_missed_errors instead of rx_dropped for reporting buffer
+      exhaustion
+    - net/mlx5e: Fix UDP GSO for encapsulated packets
+    - dma-buf/sw-sync: don't enable IRQ from sync_print_obj()
+    - bpf: Fix potential integer overflow in resolve_btfids
+    - ALSA: jack: Use guard() for locking
+    - ALSA: core: Remove debugfs at disconnection
+    - ALSA: hda/realtek: Adjust G814JZR to use SPI init for amp
+    - enic: Validate length of nl attributes in enic_set_vf_port
+    - af_unix: Annotate data-race around unix_sk(sk)->addr.
+    - af_unix: Read sk->sk_hash under bindlock during bind().
+    - Octeontx2-pf: Free send queue buffers incase of leaf to inner
+    - net: usb: smsc95xx: fix changing LED_SEL bit value updated from EEPROM
+    - ASoC: cs42l43: Only restrict 44.1kHz for the ASP
+    - bpf: Allow delete from sockmap/sockhash only if update is allowed
+    - net:fec: Add fec_enet_deinit()
+    - net: micrel: Fix lan8841_config_intr after getting out of sleep mode
+    - ice: fix accounting if a VLAN already exists
+    - selftests: mptcp: simult flows: mark 'unbalanced' tests as flaky
+    - selftests: mptcp: add ms units for tc-netem delay
+    - selftests: mptcp: join: mark 'fail' tests as flaky
+    - ALSA: seq: Fix missing bank setup between MIDI1/MIDI2 UMP conversion
+    - ALSA: seq: Don't clear bank selection at event -> UMP MIDI2 conversion
+    - net: ti: icssg-prueth: Fix start counter for ft1 filter
+    - netfilter: nft_payload: skbuff vlan metadata mangle support
+    - netfilter: tproxy: bail out if IP has been disabled on the device
+    - netfilter: nft_fib: allow from forward/input without iif selector
+    - net/sched: taprio: make q->picos_per_byte available to fill_sched_entry()
+    - net/sched: taprio: extend minimum interval restriction to entire cycle too
+    - kconfig: fix comparison to constant symbols, 'm', 'n'
+    - drm/i915/guc: avoid FIELD_PREP warning
+    - kheaders: use `command -v` to test for existence of `cpio`
+    - spi: stm32: Don't warn about spurious interrupts
+    - net: dsa: microchip: fix RGMII error in KSZ DSA driver
+    - net: ena: Reduce lines with longer column width boundary
+    - net: ena: Fix redundant device NUMA node override
+    - ipvlan: Dont Use skb->sk in ipvlan_process_v{4,6}_outbound
+    - ALSA: seq: Fix yet another spot for system message conversion
+    - powerpc/pseries/lparcfg: drop error message from guest name lookup
+    - drm/panel: sitronix-st7789v: fix timing for jt240mhqs_hwt_ek_e3 panel
+    - drm/panel: sitronix-st7789v: tweak timing for jt240mhqs_hwt_ek_e3 panel
+    - drm/panel: sitronix-st7789v: fix display size for jt240mhqs_hwt_ek_e3 panel
+    - hwmon: (intel-m10-bmc-hwmon) Fix multiplier for N6000 board power sensor
+    - hwmon: (shtc1) Fix property misspelling
+    - ALSA: seq: ump: Fix swapped song position pointer data
+    - ALSA: timer: Set lower bound of start tick time
+    - x86/efistub: Omit physical KASLR when memory reservations exist
+    - efi: libstub: only free priv.runtime_map when allocated
+    - x86/pci: Skip early E820 check for ECAM region
+    - KVM: x86: Don't advertise guest.MAXPHYADDR as host.MAXPHYADDR in CPUID
+    - genirq/cpuhotplug, x86/vector: Prevent vector leak during CPU offline
+    - platform/x86/intel/tpmi: Handle error from tpmi_process_info()
+    - platform/x86/intel-uncore-freq: Don't present root domain on error
+    - perf sched timehist: Fix -g/--call-graph option failure
+    - f2fs: write missing last sum blk of file pinning section
+    - f2fs: use f2fs_{err,info}_ratelimited() for cleanup
+    - SUNRPC: Fix loop termination condition in gss_free_in_token_pages()
+    - riscv: prevent pt_regs corruption for secondary idle threads
+    - riscv: stacktrace: fixed walk_stackframe()
+    - perf build: Fix out of tree build related to installation of sysreg-defs
+    - dt-bindings: pinctrl: qcom: update functions to match with driver
+    - usb: typec: ucsi: allow non-partner GET_PDOS for Qualcomm devices
+    - perf report: Fix PAI counter names for s390 virtual machines
+    - PCI: dwc: ep: Fix DBI access failure for drivers requiring refclk from host
+    - perf map: Remove kernel map before updating start and end addresses
+    - riscv: dts: starfive: visionfive 2: Remove non-existing I2S hardware
+    - pinctrl: renesas: rzg2l: Limit 2.5V power supply to Ethernet interfaces
+    - riscv: Flush the instruction cache during SMP bringup
+    - usb: xhci: check if 'requested segments' exceeds ERST capacity
+    - spmi: pmic-arb: Replace three IS_ERR() calls by null pointer checks in
+      spmi_pmic_arb_probe()
+    - perf symbols: Remove map from list before updating addresses
+    - perf symbols: Update kcore map before merging in remaining symbols
+    - s390/ftrace: Use unwinder instead of __builtin_return_address()
+    - s390/stacktrace: Merge perf_callchain_user() and arch_stack_walk_user()
+    - s390/stacktrace: Skip first user stack frame
+    - s390/stacktrace: Improve detection of invalid instruction pointers
+    - s390/vdso: Introduce and use struct stack_frame_vdso_wrapper
+    - s390/stackstrace: Detect vdso stack frames
+    - s390/ap: Fix bind complete udev event sent after each AP bus scan
+    - ocfs2: correctly use ocfs2_find_next_zero_bit()
+    - mailbox: mtk-cmdq: Fix pm_runtime_get_sync() warning in mbox shutdown
+    - Input: ioc3kbd - add device table
+    - phy: qcom: qmp-combo: fix sm8650 voltage swing table
+    - media: ti: j721e-csi2rx: Fix races while restarting DMA
+    - drm/msm/dpu: Allow configuring multiple active DSC blocks
+    - drm: Make drivers depends on DRM_DW_HDMI
+    - [Config] Drivers now depend on DRM_DW_HDMI
+    - string: Prepare to merge strscpy_kunit.c into string_kunit.c
+    - string: Prepare to merge strcat KUnit tests into string_kunit.c
+    - drm/msm/adreno: fix CP cycles stat retrieval on a7xx
+    - printk: Fix LOG_CPU_MAX_BUF_SHIFT when BASE_SMALL is enabled
+    - powerpc/bpf/32: Fix failing test_bpf tests
+    - KVM: PPC: Book3S HV nestedv2: Cancel pending DEC exception
+    - KVM: PPC: Book3S HV nestedv2: Fix an error handling path in
+      gs_msg_ops_kvmhv_nestedv2_config_fill_info()
+    - KVM: arm64: Destroy mpidr_data for 'late' vCPU creation
+    - Bluetooth: ISO: Handle PA sync when no BIGInfo reports are generated
+    - Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init()
+    - ubsan: Restore dependency on ARCH_HAS_UBSAN
+    - selftests: forwarding: Have RET track kselftest framework constants
+    - selftests: forwarding: Convert log_test() to recognize RET values
+    - selftests: net: Unify code of busywait() and slowwait()
+    - selftests/net: use tc rule to filter the na packet
+    - virtio_balloon: Give the balloon its own wakeup source
+    - riscv: cpufeature: Fix thead vector hwcap removal
+    - riscv: cpufeature: Fix extension subset checking
+    - riscv: selftests: Add hwprobe binaries to .gitignore
+    - idpf: Interpret .set_channels() input differently
+    - null_blk: fix null-ptr-dereference while configuring 'power' and
+      'submit_queues'
+    - netfs: Fix setting of BDP_ASYNC from iocb flags
+    - cifs: Set zero_point in the copy_file_range() and remap_file_range()
+    - cifs: Fix missing set of remote_i_size
+    - selftests: net: lib: set 'i' as local
+    - nvme: fix multipath batched completion accounting
+    - netkit: Fix setting mac address in l2 mode
+    - netkit: Fix pkt_type override upon netkit pass verdict
+    - null_blk: Fix return value of nullb_device_power_store()
+    - idpf: don't enable NAPI and interrupts prior to allocating Rx buffers
+    - selftests: mptcp: join: mark 'fastclose' tests as flaky
+    - drm/xe: Add dbg messages on the suspend resume functions.
+    - drm/xe: check pcode init status only on root gt of root tile
+    - drm/xe: Change pcode timeout to 50msec while polling again
+    - drm/xe: Only use reserved BCS instances for usm migrate exec queue
+    - sd: also set max_user_sectors when setting max_sectors
+    - block: stack max_user_sectors
+    - ipv6: introduce dst_rt6_info() helper
+    - inet: introduce dst_rtable() helper
+    - net: fix __dst_negative_advice() race
+    - ice: fix 200G PHY types to link speed mapping
+    - x86/topology/intel: Unlock CPUID before evaluating anything
+    - Upstream stable to v6.6.33, v6.9.4
+  * Reenable CONFIG_UBSAN for noble (LP: #2076650)
+    - ubsan: Remove CONFIG_UBSAN_SANITIZE_ALL
+    - [Config] Remove CONFIG_UBSAN_SANITIZE_ALL
+  * Dangling symlink to linux-lib-rust when Rust is disabled (LP: #2072592)
+    - [Packaging] Check do_lib_rust before linking Rust lib files
+  * kdump doesn't work with UEFI secure boot and kernel lockdown enabled on
+    ARM64 (LP: #2033007)
+    - [Config]: Enable CONFIG_KEXEC_IMAGE_VERIFY_SIG on arm64
+  * net/sched: Fix conntrack use-after-free (LP: #2073092)
+    - net/sched: Fix UAF when resolving a clash
+  * No sound on Huawei Matebook D14  AMD since Linux 6.8.0-38 [regression]
+    (LP: #2073049)
+    - ASoC: amd: acp: fix for acp platform device creation failure
+  * i915: Fixup regressions introduced with enabling single CCS engine
+    (LP: #2072755)
+    - drm/i915/gt: Fix CCS id's calculation for CCS mode setting
+  * [Ubuntu 24.04] FW1060.00 (NH1060_026) sosreport is running to Kernel OOPS
+    crash (LP: #2070358)
+    - nfsd: initialise nfsd_info.mutex early.
+  * 6.8 generic & amdpgu / polaris (LP: #2072428)
+    - drm/amdgpu: Adjust logic in amdgpu_device_partner_bandwidth()
+  * md: nvme over tcp with a striped underlying md raid device leads to data
+    corruption (LP: #2075110)
+    - md/md-bitmap: fix writing non bitmap pages
+  * Linux 6.8 fails to boot on ARM64 if any param is more than 146 chars
+    (LP: #2069534)
+    - SAUCE: arm64: v6.8: cmdline param >= 146 chars kills kernel
+  * CVE-2024-39484
+    - mmc: davinci: Don't strip remove function when driver is builtin
+  * CVE-2024-39292
+    - um: Add winch to winch_handlers before registering winch IRQ
+  * Miscellaneous upstream changes
+    - bnx2x: Fix multiple UBSAN array-index-out-of-bounds
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 18 Sep 2024 21:04:33 +0900
+
+linux-qcom (6.8.0-1009.9) jammy; urgency=medium
+
+  * [RB3] Kernel call trace while inserting storage to type-c USB port
+    - SAUCE: usb3: dwc3-qcom: Fix calltrace for USB host mode
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 02 Sep 2024 10:37:50 +0900
+
+linux-qcom (6.8.0-1008.8) jammy; urgency=medium
+
+  * [RB3] drm sde error/ msm-dsi-error found in dmesg
+    - SAUCE: do not show error on EPROBE_DEFER
+
+  * [RB3] slim-ngd-ctrl error found in dmesg
+    - SAUCE: dma: qcom: bam_dma: set DMA_PRIVATE
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: generate combined-dtb.dtb at compile time
+    - SAUCE: rename qcom,phy-rst-gpio to qcom,phy-rst-gpio-id
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 21 Aug 2024 03:11:39 +0900
+
+linux-qcom (6.8.0-1007.7) jammy; urgency=medium
+
+  * [RB3] gpi 900000.dma-controller error found in dmesg
+    - dmaengine: qcom: gpi: set DMA_PRIVATE flag
+
+  * [RB3] btfm_slime error message found in dmesg
+    - SAUCE: ubuntu/qcom: fix bogus error message
+
+  * [RB3] Bluetooth device is not detected
+    - SAUCE: Set local-bd-address to fix bluetooth detection
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: ubuntu/qcom/video: import video driver from GA 1.1
+    - SAUCE: ubuntu/qcom/touch: import touch driver from GA 1.1
+    - SAUCE: ubuntu/qcom/video: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/touch: replace strlcpy() with strscpy()
+    - SAUCE: build video and touch external drivers
+
+  [ Ubuntu: 6.8.0-40.40 ]
+
+  * noble/linux: 6.8.0-40.40 -proposed tracker (LP: #2072201)
+  * FPS of glxgear with fullscreen is too low on MTL platform (LP: #2069380)
+    - drm/i915: Bypass LMEMBAR/GTTMMADR for MTL stolen memory access
+  * a critical typo in the code managing the ASPM  settings for PCI Express
+    devices (LP: #2071889)
+    - PCI/ASPM: Restore parent state to parent, child state to child
+  * [UBUNTU 24.04] IOMMU DMA mode changed in kernel config causes massive
+    throughput degradation for PCI-related network workloads (LP: #2071471)
+    - [Config] Set IOMMU_DEFAULT_DMA_STRICT=n and IOMMU_DEFAULT_DMA_LAZY=yes for
+      s390x
+  * UBSAN: array-index-out-of-bounds in
+    /build/linux-D15vQj/linux-6.5.0/drivers/md/bcache/bset.c:1098:3
+    (LP: #2039368)
+    - bcache: fix variable length array abuse in btree_iter
+  * Mute/mic LEDs and speaker no function on EliteBook 645/665 G11
+    (LP: #2071296)
+    - ALSA: hda/realtek: fix mute/micmute LEDs don't work for EliteBook 645/665
+      G11.
+  * failed to enable IPU6 camera sensor on kernel >= 6.8: ivsc_ace
+    intel_vsc-5db76cf6-0a68-4ed6-9b78-0361635e2447: switch camera to host
+    failed: -110 (LP: #2067364)
+    - mei: vsc: Don't stop/restart mei device during system suspend/resume
+    - SAUCE: media: ivsc: csi: don't count privacy on as error
+    - SAUCE: media: ivsc: csi: add separate lock for v4l2 control handler
+    - SAUCE: media: ivsc: csi: remove privacy status in struct mei_csi
+    - SAUCE: mei: vsc: Enhance IVSC chipset stability during warm reboot
+    - SAUCE: mei: vsc: Enhance SPI transfer of IVSC rom
+    - SAUCE: mei: vsc: Utilize the appropriate byte order swap function
+    - SAUCE: mei: vsc: Prevent timeout error with added delay post-firmware
+      download
+  * failed to probe camera sensor on Dell XPS 9315: ov01a10 i2c-OVTI01A0:00:
+    failed to check hwcfg: -22 (LP: #2070251)
+    - ACPI: utils: Make acpi_handle_path() not static
+    - ACPI: property: Ignore bad graph port nodes on Dell XPS 9315
+    - ACPI: property: Polish ignoring bad data nodes
+    - ACPI: scan: Ignore camera graph port nodes on all Dell Tiger, Alder and
+      Raptor Lake models
+  * Update amd_sfh for AMD strix series (LP: #2058331)
+    - HID: amd_sfh: Increase sensor command timeout
+    - HID: amd_sfh: Improve boot time when SFH is available
+    - HID: amd_sfh: Extend MP2 register access to SFH
+    - HID: amd_sfh: Set the AMD SFH driver to depend on x86
+  * RFIM and SAGV Linux Support for G10 models (LP: #2070158)
+    - drm/i915/display: Add meaningful traces for QGV point info error handling
+    - drm/i915/display: Extract code required to calculate max qgv/psf gv point
+    - drm/i915/display: extract code to prepare qgv points mask
+    - drm/i915/display: Disable SAGV on bw init, to force QGV point recalculation
+    - drm/i915/display: handle systems with duplicate psf gv points
+    - drm/i915/display: force qgv check after the hw state readout
+  * Update amd-pmf for AMD strix series (LP: #2058330)
+    - platform/x86/amd/pmf: Differentiate PMF ACPI versions
+    - platform/x86/amd/pmf: Disable debugfs support for querying power thermals
+    - platform/x86/amd/pmf: Add support to get sbios requests in PMF driver
+    - platform/x86/amd/pmf: Add support to notify sbios heart beat event
+    - platform/x86/amd/pmf: Add support to get APTS index numbers for static
+      slider
+    - platform/x86/amd/pmf: Add support to get sps default APTS index values
+    - platform/x86/amd/pmf: Update sps power thermals according to the platform-
+      profiles
+  * noble:linux: ADT ubuntu-regression-suite misses fakeroot dependency
+    (LP: #2070042)
+    - [DEP-8] Add missing fakeroot dependency
+  * Noble update: v6.8.12 upstream stable release (LP: #2071621)
+    - sunrpc: use the struct net as the svc proc private
+    - x86/tsc: Trust initial offset in architectural TSC-adjust MSRs
+    - selftests/ftrace: Fix BTFARG testcase to check fprobe is enabled correctly
+    - ftrace: Fix possible use-after-free issue in ftrace_location()
+    - Revert "arm64: fpsimd: Implement lazy restore for kernel mode FPSIMD"
+    - arm64/fpsimd: Avoid erroneous elide of user state reload
+    - Reapply "arm64: fpsimd: Implement lazy restore for kernel mode FPSIMD"
+    - tty: n_gsm: fix missing receive state reset after mode switch
+    - speakup: Fix sizeof() vs ARRAY_SIZE() bug
+    - serial: sc16is7xx: fix bug in sc16is7xx_set_baud() when using prescaler
+    - serial: 8250_bcm7271: use default_mux_rate if possible
+    - serial: 8520_mtk: Set RTS on shutdown for Rx in-band wakeup
+    - Input: try trimming too long modalias strings
+    - io_uring: fail NOP if non-zero op flags is passed in
+    - Revert "r8169: don't try to disable interrupts if NAPI is, scheduled
+      already"
+    - r8169: Fix possible ring buffer corruption on fragmented Tx packets.
+    - ring-buffer: Fix a race between readers and resize checks
+    - net: mana: Fix the extra HZ in mana_hwc_send_request
+    - tools/latency-collector: Fix -Wformat-security compile warns
+    - tools/nolibc/stdlib: fix memory error in realloc()
+    - net: ti: icssg_prueth: Fix NULL pointer dereference in prueth_probe()
+    - net: lan966x: remove debugfs directory in probe() error path
+    - net: smc91x: Fix m68k kernel compilation for ColdFire CPU
+    - nilfs2: fix use-after-free of timer for log writer thread
+    - nilfs2: fix unexpected freezing of nilfs_segctor_sync()
+    - nilfs2: fix potential hang in nilfs_detach_log_writer()
+    - fs/ntfs3: Remove max link count info display during driver init
+    - fs/ntfs3: Taking DOS names into account during link counting
+    - fs/ntfs3: Fix case when index is reused during tree transformation
+    - fs/ntfs3: Break dir enumeration if directory contents error
+    - ksmbd: avoid to send duplicate oplock break notifications
+    - ksmbd: ignore trailing slashes in share paths
+    - ALSA: core: Fix NULL module pointer assignment at card init
+    - ALSA: Fix deadlocks with kctl removals at disconnection
+    - KEYS: asymmetric: Add missing dependency on CRYPTO_SIG
+    - [Config] updateconfigs for CRYPTO_SIG
+    - KEYS: asymmetric: Add missing dependencies of FIPS_SIGNATURE_SELFTEST
+    - HID: nintendo: Fix N64 controller being identified as mouse
+    - dmaengine: xilinx: xdma: Clarify kdoc in XDMA driver
+    - wifi: mac80211: don't use rate mask for scanning
+    - wifi: mac80211: ensure beacon is non-S1G prior to extracting the beacon
+      timestamp field
+    - wifi: cfg80211: fix the order of arguments for trace events of the tx_rx_evt
+      class
+    - dt-bindings: rockchip: grf: Add missing type to 'pcie-phy' node
+    - HID: mcp-2221: cancel delayed_work only when CONFIG_IIO is enabled
+    - net: usb: qmi_wwan: add Telit FN920C04 compositions
+    - drm/amd/display: Set color_mgmt_changed to true on unsuspend
+    - drm/amdgpu: Update BO eviction priorities
+    - drm/amd/pm: Restore config space after reset
+    - drm/amdkfd: Add VRAM accounting for SVM migration
+    - drm/amdgpu: Fix the ring buffer size for queue VM flush
+    - Revert "net: txgbe: fix i2c dev name cannot match clkdev"
+    - Revert "net: txgbe: fix clk_name exceed MAX_DEV_ID limits"
+    - cpu: Ignore "mitigations" kernel parameter if CPU_MITIGATIONS=n
+    - LoongArch: Lately init pmu after smp is online
+    - drm/etnaviv: fix tx clock gating on some GC7000 variants
+    - selftests: sud_test: return correct emulated syscall value on RISC-V
+    - riscv: thead: Rename T-Head PBMT to MAE
+    - [Config] updateconfigs for ERRATA_THEAD_MAE
+    - riscv: T-Head: Test availability bit before enabling MAE errata
+    - sched/isolation: Fix boot crash when maxcpus < first housekeeping CPU
+    - ASoC: Intel: bytcr_rt5640: Apply Asus T100TA quirk to Asus T100TAM too
+    - regulator: irq_helpers: duplicate IRQ name
+    - ALSA: hda: cs35l56: Exit cache-only after cs35l56_wait_for_firmware_boot()
+    - ASoC: SOF: ipc4-pcm: Use consistent name for snd_sof_pcm_stream pointer
+    - ASoC: SOF: ipc4-pcm: Use consistent name for sof_ipc4_timestamp_info pointer
+    - ASoC: SOF: ipc4-pcm: Introduce generic sof_ipc4_pcm_stream_priv
+    - ASoC: SOF: pcm: Restrict DSP D0i3 during S0ix to IPC3
+    - ASoC: acp: Support microphone from device Acer 315-24p
+    - ASoC: rt5645: Fix the electric noise due to the CBJ contacts floating
+    - ASoC: dt-bindings: rt5645: add cbj sleeve gpio property
+    - ASoC: rt722-sdca: modify channel number to support 4 channels
+    - ASoC: rt722-sdca: add headset microphone vrefo setting
+    - regulator: qcom-refgen: fix module autoloading
+    - regulator: vqmmc-ipq4019: fix module autoloading
+    - ASoC: cs35l41: Update DSP1RX5/6 Sources for DSP config
+    - ASoC: rt715: add vendor clear control register
+    - ASoC: rt715-sdca: volume step modification
+    - KVM: selftests: Add test for uaccesses to non-existent vgic-v2 CPUIF
+    - Input: xpad - add support for ASUS ROG RAIKIRI
+    - btrfs: take the cleaner_mutex earlier in qgroup disable
+    - EDAC/versal: Do not register for NOC errors
+    - fpga: dfl-pci: add PCI subdevice ID for Intel D5005 card
+    - bpf, x86: Fix PROBE_MEM runtime load check
+    - ALSA: emu10k1: make E-MU FPGA writes potentially more reliable
+    - softirq: Fix suspicious RCU usage in __do_softirq()
+    - platform/x86: ISST: Add Grand Ridge to HPM CPU list
+    - ASoC: da7219-aad: fix usage of device_get_named_child_node()
+    - ASoC: cs35l56: fix usages of device_get_named_child_node()
+    - ALSA: hda: intel-dsp-config: harden I2C/I2S codec detection
+    - Input: amimouse - mark driver struct with __refdata to prevent section
+      mismatch
+    - drm/amdgpu: Fix VRAM memory accounting
+    - drm/amd/display: Ensure that dmcub support flag is set for DCN20
+    - drm/amd/display: Add dtbclk access to dcn315
+    - drm/amd/display: Allocate zero bw after bw alloc enable
+    - drm/amd/display: Add VCO speed parameter for DCN31 FPU
+    - drm/amd/display: Fix DC mode screen flickering on DCN321
+    - drm/amd/display: Disable seamless boot on 128b/132b encoding
+    - drm/amdkfd: Flush the process wq before creating a kfd_process
+    - x86/mm: Remove broken vsyscall emulation code from the page fault code
+    - nvme: find numa distance only if controller has valid numa id
+    - nvmet-auth: return the error code to the nvmet_auth_host_hash() callers
+    - nvmet-auth: replace pr_debug() with pr_err() to report an error.
+    - nvme: cancel pending I/O if nvme controller is in terminal state
+    - nvmet-tcp: fix possible memory leak when tearing down a controller
+    - nvmet: fix nvme status code when namespace is disabled
+    - nvme-tcp: strict pdu pacing to avoid send stalls on TLS
+    - epoll: be better about file lifetimes
+    - nvmet: prevent sprintf() overflow in nvmet_subsys_nsid_exists()
+    - openpromfs: finish conversion to the new mount API
+    - crypto: bcm - Fix pointer arithmetic
+    - firmware: qcom: qcm: fix unused qcom_scm_qseecom_allowlist
+    - mm/slub, kunit: Use inverted data to corrupt kmem cache
+    - firmware: raspberrypi: Use correct device for DMA mappings
+    - ecryptfs: Fix buffer size for tag 66 packet
+    - nilfs2: fix out-of-range warning
+    - parisc: add missing export of __cmpxchg_u8()
+    - crypto: ccp - drop platform ifdef checks
+    - crypto: x86/nh-avx2 - add missing vzeroupper
+    - crypto: x86/sha256-avx2 - add missing vzeroupper
+    - crypto: x86/sha512-avx2 - add missing vzeroupper
+    - s390/cio: fix tracepoint subchannel type field
+    - io_uring: use the right type for work_llist empty check
+    - rcu-tasks: Fix show_rcu_tasks_trace_gp_kthread buffer overflow
+    - rcu: Fix buffer overflow in print_cpu_stall_info()
+    - ARM: configs: sunxi: Enable DRM_DW_HDMI
+    - jffs2: prevent xattr node from overflowing the eraseblock
+    - libfs: Re-arrange locking in offset_iterate_dir()
+    - libfs: Define a minimum directory offset
+    - libfs: Add simple_offset_empty()
+    - maple_tree: Add mtree_alloc_cyclic()
+    - libfs: Convert simple directory offsets to use a Maple Tree
+    - libfs: Fix simple_offset_rename_exchange()
+    - libfs: Add simple_offset_rename() API
+    - shmem: Fix shmem_rename2()
+    - io-wq: write next_work before dropping acct_lock
+    - mm/userfaultfd: Do not place zeropages when zeropages are disallowed
+    - s390/mm: Re-enable the shared zeropage for !PV and !skeys KVM guests
+    - crypto: octeontx2 - add missing check for dma_map_single
+    - crypto: qat - improve error message in adf_get_arbiter_mapping()
+    - crypto: qat - improve error logging to be consistent across features
+    - soc: qcom: pmic_glink: don't traverse clients list without a lock
+    - soc: qcom: pmic_glink: notify clients about the current state
+    - firmware: qcom: scm: Fix __scm and waitq completion variable initialization
+    - soc: mediatek: cmdq: Fix typo of CMDQ_JUMP_RELATIVE
+    - null_blk: Fix missing mutex_destroy() at module removal
+    - crypto: qat - validate slices count returned by FW
+    - hwrng: stm32 - use logical OR in conditional
+    - hwrng: stm32 - put IP into RPM suspend on failure
+    - hwrng: stm32 - repair clock handling
+    - kunit/fortify: Fix mismatched kvalloc()/vfree() usage
+    - io_uring/net: remove dependency on REQ_F_PARTIAL_IO for sr->done_io
+    - io_uring/net: fix sendzc lazy wake polling
+    - soc: qcom: pmic_glink: Make client-lock non-sleeping
+    - lkdtm: Disable CFI checking for perms functions
+    - md: fix resync softlockup when bitmap size is less than array size
+    - crypto: qat - specify firmware files for 402xx
+    - block: refine the EOF check in blkdev_iomap_begin
+    - block: fix and simplify blkdevparts= cmdline parsing
+    - block: support to account io_ticks precisely
+    - wifi: ath10k: poll service ready message before failing
+    - wifi: brcmfmac: pcie: handle randbuf allocation failure
+    - wifi: ath11k: don't force enable power save on non-running vdevs
+    - bpftool: Fix missing pids during link show
+    - libbpf: Prevent null-pointer dereference when prog to load has no BTF
+    - wifi: ath12k: use correct flag field for 320 MHz channels
+    - wifi: mt76: mt7915: workaround too long expansion sparse warnings
+    - x86/boot: Ignore relocations in .notes sections in walk_relocs() too
+    - wifi: ieee80211: fix ieee80211_mle_basic_sta_prof_size_ok()
+    - wifi: iwlwifi: mvm: Do not warn on invalid link on scan complete
+    - wifi: iwlwifi: mvm: allocate STA links only for active links
+    - wifi: mac80211: don't select link ID if not provided in scan request
+    - wifi: iwlwifi: implement can_activate_links callback
+    - wifi: iwlwifi: mvm: fix active link counting during recovery
+    - wifi: iwlwifi: mvm: select STA mask only for active links
+    - wifi: iwlwifi: reconfigure TLC during HW restart
+    - wifi: iwlwifi: mvm: fix check in iwl_mvm_sta_fw_id_mask
+    - sched/fair: Add EAS checks before updating root_domain::overutilized
+    - ACPI: bus: Indicate support for _TFP thru _OSC
+    - ACPI: bus: Indicate support for more than 16 p-states thru _OSC
+    - ACPI: bus: Indicate support for the Generic Event Device thru _OSC
+    - ACPI: Fix Generic Initiator Affinity _OSC bit
+    - ACPI: bus: Indicate support for IRQ ResourceSource thru _OSC
+    - enetc: avoid truncating error message
+    - qed: avoid truncating work queue length
+    - mlx5: avoid truncating error message
+    - mlx5: stop warning for 64KB pages
+    - bitops: add missing prototype check
+    - dlm: fix user space lock decision to copy lvb
+    - wifi: carl9170: re-fix fortified-memset warning
+    - bpftool: Mount bpffs on provided dir instead of parent dir
+    - bpf: Pack struct bpf_fib_lookup
+    - bpf: prevent r10 register from being marked as precise
+    - x86/microcode/AMD: Avoid -Wformat warning with clang-15
+    - scsi: ufs: qcom: Perform read back after writing reset bit
+    - scsi: ufs: qcom: Perform read back after writing REG_UFS_SYS1CLK_1US
+    - scsi: ufs: qcom: Perform read back after writing unipro mode
+    - scsi: ufs: qcom: Perform read back after writing CGC enable
+    - scsi: ufs: cdns-pltfrm: Perform read back after writing HCLKDIV
+    - scsi: ufs: core: Perform read back after writing UTP_TASK_REQ_LIST_BASE_H
+    - scsi: ufs: core: Perform read back after disabling interrupts
+    - scsi: ufs: core: Perform read back after disabling UIC_COMMAND_COMPL
+    - ACPI: LPSS: Advertise number of chip selects via property
+    - EDAC/skx_common: Allow decoding of SGX addresses
+    - locking/atomic/x86: Correct the definition of __arch_try_cmpxchg128()
+    - irqchip/alpine-msi: Fix off-by-one in allocation error path
+    - irqchip/loongson-pch-msi: Fix off-by-one on allocation error path
+    - ACPI: disable -Wstringop-truncation
+    - gfs2: Don't forget to complete delayed withdraw
+    - gfs2: Fix "ignore unlock failures after withdraw"
+    - arm64: Remove unnecessary irqflags alternative.h include
+    - x86/boot/64: Clear most of CR4 in startup_64(), except PAE, MCE and LA57
+    - selftests/bpf: Fix umount cgroup2 error in test_sockmap
+    - tcp: increase the default TCP scaling ratio
+    - cpufreq: exit() callback is optional
+    - x86/pat: Introduce lookup_address_in_pgd_attr()
+    - x86/pat: Restructure _lookup_address_cpa()
+    - x86/pat: Fix W^X violation false-positives when running as Xen PV guest
+    - udp: Avoid call to compute_score on multiple sites
+    - openrisc: traps: Don't send signals to kernel mode threads
+    - cppc_cpufreq: Fix possible null pointer dereference
+    - wifi: iwlwifi: mvm: init vif works only once
+    - scsi: libsas: Fix the failure of adding phy with zero-address to port
+    - scsi: hpsa: Fix allocation size for Scsi_Host private data
+    - x86/purgatory: Switch to the position-independent small code model
+    - wifi: ath12k: fix out-of-bound access of qmi_invoke_handler()
+    - thermal/drivers/mediatek/lvts_thermal: Add coeff for mt8192
+    - thermal/drivers/tsens: Fix null pointer dereference
+    - dt-bindings: thermal: loongson,ls2k-thermal: Add Loongson-2K0500 compatible
+    - dt-bindings: thermal: loongson,ls2k-thermal: Fix incorrect compatible
+      definition
+    - wifi: ath10k: Fix an error code problem in
+      ath10k_dbg_sta_write_peer_debug_trigger()
+    - gfs2: Remove ill-placed consistency check
+    - gfs2: Fix potential glock use-after-free on unmount
+    - gfs2: finish_xmote cleanup
+    - gfs2: do_xmote fixes
+    - thermal/debugfs: Avoid excessive updates of trip point statistics
+    - selftests/bpf: Fix a fd leak in error paths in open_netns
+    - scsi: ufs: core: mcq: Fix ufshcd_mcq_sqe_search()
+    - cpufreq: brcmstb-avs-cpufreq: ISO C90 forbids mixed declarations
+    - wifi: ath10k: populate board data for WCN3990
+    - net: dsa: mv88e6xxx: Add support for model-specific pre- and post-reset
+      handlers
+    - net: dsa: mv88e6xxx: Avoid EEPROM timeout without EEPROM on 88E6250-family
+      switches
+    - tcp: avoid premature drops in tcp_add_backlog()
+    - thermal/debugfs: Create records for cdev states as they get used
+    - thermal/debugfs: Pass cooling device state to thermal_debug_cdev_add()
+    - pwm: sti: Prepare removing pwm_chip from driver data
+    - pwm: sti: Simplify probe function using devm functions
+    - drivers/perf: hisi_pcie: Fix out-of-bound access when valid event group
+    - drivers/perf: hisi: hns3: Fix out-of-bound access when valid event group
+    - drivers/perf: hisi: hns3: Actually use devm_add_action_or_reset()
+    - net: give more chances to rcu in netdev_wait_allrefs_any()
+    - macintosh/via-macii: Fix "BUG: sleeping function called from invalid
+      context"
+    - wifi: carl9170: add a proper sanity check for endpoints
+    - bpf: Fix verifier assumptions about socket->sk
+    - selftests/bpf: Run cgroup1_hierarchy test in own mount namespace
+    - wifi: ar5523: enable proper endpoint verification
+    - pwm: Drop useless member .of_pwm_n_cells of struct pwm_chip
+    - pwm: Let the of_xlate callbacks accept references without period
+    - pwm: Drop duplicate check against chip->npwm in of_pwm_xlate_with_flags()
+    - pwm: Reorder symbols in core.c
+    - pwm: Provide an inline function to get the parent device of a given chip
+    - pwm: meson: Change prototype of a few helpers to prepare further changes
+    - pwm: meson: Make use of pwmchip_parent() accessor
+    - pwm: meson: Add check for error from clk_round_rate()
+    - pwm: meson: Use mul_u64_u64_div_u64() for frequency calculating
+    - bpf: Add BPF_PROG_TYPE_CGROUP_SKB attach type enforcement in BPF_LINK_CREATE
+    - sh: kprobes: Merge arch_copy_kprobe() into arch_prepare_kprobe()
+    - Revert "sh: Handle calling csum_partial with misaligned data"
+    - wifi: mt76: mt7603: fix tx queue of loopback packets
+    - wifi: mt76: mt7603: add wpdma tx eof flag for PSE client reset
+    - wifi: mt76: mt7996: fix size of txpower MCU command
+    - wifi: mt76: mt7925: ensure 4-byte alignment for suspend & wow command
+    - wifi: mt76: mt7996: fix uninitialized variable in mt7996_irq_tasklet()
+    - wifi: mt76: mt7996: fix potential memory leakage when reading chip
+      temperature
+    - libbpf: Fix error message in attach_kprobe_multi
+    - wifi: nl80211: Avoid address calculations via out of bounds array indexing
+    - wifi: rtw89: wow: refine WoWLAN flows of HCI interrupts and low power mode
+    - selftests/binderfs: use the Makefile's rules, not Make's implicit rules
+    - selftests/resctrl: fix clang build failure: use LOCAL_HDRS
+    - selftests: default to host arch for LLVM builds
+    - kunit: Fix kthread reference
+    - kunit: unregister the device on error
+    - kunit: bail out early in __kunit_test_suites_init() if there are no suites
+      to test
+    - selftests/bpf: Fix pointer arithmetic in test_xdp_do_redirect
+    - HID: intel-ish-hid: ipc: Add check for pci_alloc_irq_vectors
+    - scsi: bfa: Ensure the copied buf is NUL terminated
+    - scsi: qedf: Ensure the copied buf is NUL terminated
+    - scsi: qla2xxx: Fix debugfs output for fw_resource_count
+    - gpio: nuvoton: Fix sgpio irq handle error
+    - x86/numa: Fix SRAT lookup of CFMWS ranges with numa_fill_memblks()
+    - wifi: mwl8k: initialize cmd->addr[] properly
+    - HID: amd_sfh: Handle "no sensors" in PM operations
+    - usb: aqc111: stop lying about skb->truesize
+    - net: usb: sr9700: stop lying about skb->truesize
+    - m68k: Fix spinlock race in kernel thread creation
+    - m68k: mac: Fix reboot hang on Mac IIci
+    - dm-delay: fix workqueue delay_timer race
+    - dm-delay: fix hung task introduced by kthread mode
+    - dm-delay: fix max_delay calculations
+    - ptp: ocp: fix DPLL functions
+    - net: ipv6: fix wrong start position when receive hop-by-hop fragment
+    - eth: sungem: remove .ndo_poll_controller to avoid deadlocks
+    - selftests: net: add missing config for amt.sh
+    - selftests: net: move amt to socat for better compatibility
+    - net: ethernet: mediatek: split tx and rx fields in mtk_soc_data struct
+    - net: ethernet: mediatek: use ADMAv1 instead of ADMAv2.0 on MT7981 and MT7986
+    - ice: Fix package download algorithm
+    - net: ethernet: cortina: Locking fixes
+    - af_unix: Fix data races in unix_release_sock/unix_stream_sendmsg
+    - net: usb: smsc95xx: stop lying about skb->truesize
+    - net: openvswitch: fix overwriting ct original tuple for ICMPv6
+    - ipv6: sr: add missing seg6_local_exit
+    - ipv6: sr: fix incorrect unregister order
+    - ipv6: sr: fix invalid unregister error path
+    - net/mlx5: Fix peer devlink set for SF representor devlink port
+    - net/mlx5: Reload only IB representors upon lag disable/enable
+    - net/mlx5: Add a timeout to acquire the command queue semaphore
+    - net/mlx5: Discard command completions in internal error
+    - s390/bpf: Emit a barrier for BPF_FETCH instructions
+    - riscv, bpf: make some atomic operations fully ordered
+    - ax25: Use kernel universal linked list to implement ax25_dev_list
+    - ax25: Fix reference count leak issues of ax25_dev
+    - ax25: Fix reference count leak issue of net_device
+    - dpll: fix return value check for kmemdup
+    - net: fec: remove .ndo_poll_controller to avoid deadlocks
+    - mptcp: SO_KEEPALIVE: fix getsockopt support
+    - mptcp: cleanup writer wake-up
+    - mptcp: avoid some duplicate code in socket option handling
+    - mptcp: implement TCP_NOTSENT_LOWAT support
+    - mptcp: cleanup SOL_TCP handling
+    - mptcp: fix full TCP keep-alive support
+    - net: stmmac: Offload queueMaxSDU from tc-taprio
+    - net: stmmac: est: Per Tx-queue error count for HLBF
+    - net: stmmac: Report taprio offload status
+    - net: stmmac: move the EST lock to struct stmmac_priv
+    - net: micrel: Fix receiving the timestamp in the frame for lan8841
+    - Bluetooth: compute LE flow credits based on recvbuf space
+    - Bluetooth: qca: Fix error code in qca_read_fw_build_info()
+    - Bluetooth: ISO: Add hcon for listening bis sk
+    - Bluetooth: ISO: Clean up returns values in iso_connect_ind()
+    - Bluetooth: ISO: Make iso_get_sock_listen generic
+    - Bluetooth: Remove usage of the deprecated ida_simple_xx() API
+    - Bluetooth: hci_event: Remove code to removed CONFIG_BT_HS
+    - Bluetooth: HCI: Remove HCI_AMP support
+    - ice: make ice_vsi_cfg_rxq() static
+    - ice: make ice_vsi_cfg_txq() static
+    - overflow: Change DEFINE_FLEX to take __counted_by member
+    - Bluetooth: hci_conn, hci_sync: Use __counted_by() to avoid -Wfamnae warnings
+    - Bluetooth: hci_core: Fix not handling hdev->le_num_of_adv_sets=1
+    - drm/bridge: Fix improper bridge init order with pre_enable_prev_first
+    - drm/ci: update device type for volteer devices
+    - drm/nouveau/dp: Fix incorrect return code in r535_dp_aux_xfer()
+    - drm/omapdrm: Fix console by implementing fb_dirty
+    - drm/omapdrm: Fix console with deferred ops
+    - printk: Let no_printk() use _printk()
+    - dev_printk: Add and use dev_no_printk()
+    - drm/lcdif: Do not disable clocks on already suspended hardware
+    - drm/dp: Don't attempt AUX transfers when eDP panels are not powered
+    - drm/panel: atna33xc20: Fix unbalanced regulator in the case HPD doesn't
+      assert
+    - drm/amd/display: Fix potential index out of bounds in color transformation
+      function
+    - drm/amd/display: Remove redundant condition in dcn35_calc_blocks_to_gate()
+    - ASoC: Intel: Disable route checks for Skylake boards
+    - ASoC: Intel: avs: ssm4567: Do not ignore route checks
+    - mtd: core: Report error if first mtd_otp_size() call fails in
+      mtd_otp_nvmem_add()
+    - mtd: rawnand: hynix: fixed typo
+    - drm/imagination: avoid -Woverflow warning
+    - ASoC: mediatek: Assign dummy when codec not specified for a DAI link
+    - drm/panel: ltk050h3146w: add MIPI_DSI_MODE_VIDEO to LTK050H3148W flags
+    - drm/panel: ltk050h3146w: drop duplicate commands from LTK050H3148W init
+    - fbdev: shmobile: fix snprintf truncation
+    - ASoC: kirkwood: Fix potential NULL dereference
+    - drm/meson: vclk: fix calculation of 59.94 fractional rates
+    - drm/mediatek: Add 0 size check to mtk_drm_gem_obj
+    - drm/mediatek: Init `ddp_comp` with devm_kcalloc()
+    - ASoC: SOF: Intel: hda-dai: fix channel map configuration for aggregated
+      dailink
+    - powerpc/fsl-soc: hide unused const variable
+    - ASoC: SOF: Intel: mtl: Correct rom_status_reg
+    - ASoC: SOF: Intel: lnl: Correct rom_status_reg
+    - ASoC: SOF: Intel: mtl: Disable interrupts when firmware boot failed
+    - ASoC: SOF: Intel: mtl: Implement firmware boot state check
+    - fbdev: sisfb: hide unused variables
+    - selftests: cgroup: skip test_cgcore_lesser_ns_open when cgroup2 mounted
+      without nsdelegate
+    - ASoC: Intel: avs: Restore stream decoupling on prepare
+    - ASoC: Intel: avs: Fix ASRC module initialization
+    - ASoC: Intel: avs: Fix potential integer overflow
+    - ASoC: Intel: avs: Test result of avs_get_module_entry()
+    - media: ngene: Add dvb_ca_en50221_init return value check
+    - staging: media: starfive: Remove links when unregistering devices
+    - media: rcar-vin: work around -Wenum-compare-conditional warning
+    - media: radio-shark2: Avoid led_names truncations
+    - drm: bridge: cdns-mhdp8546: Fix possible null pointer dereference
+    - platform/x86: xiaomi-wmi: Fix race condition when reporting key events
+    - drm/msm/dp: allow voltage swing / pre emphasis of 3
+    - drm/msm/dp: Avoid a long timeout for AUX transfer if nothing connected
+    - media: ipu3-cio2: Request IRQ earlier
+    - media: dt-bindings: ovti,ov2680: Fix the power supply names
+    - media: i2c: et8ek8: Don't strip remove function when driver is builtin
+    - media: v4l2-subdev: Fix stream handling for crop API
+    - fbdev: sh7760fb: allow modular build
+    - media: atomisp: ssh_css: Fix a null-pointer dereference in
+      load_video_binaries
+    - drm/arm/malidp: fix a possible null pointer dereference
+    - drm: vc4: Fix possible null pointer dereference
+    - ASoC: tracing: Export SND_SOC_DAPM_DIR_OUT to its value
+    - drm/bridge: anx7625: Don't log an error when DSI host can't be found
+    - drm/bridge: icn6211: Don't log an error when DSI host can't be found
+    - drm/bridge: lt8912b: Don't log an error when DSI host can't be found
+    - drm/bridge: lt9611: Don't log an error when DSI host can't be found
+    - drm/bridge: lt9611uxc: Don't log an error when DSI host can't be found
+    - drm/bridge: tc358775: Don't log an error when DSI host can't be found
+    - drm/bridge: dpc3433: Don't log an error when DSI host can't be found
+    - drm/panel: novatek-nt35950: Don't log an error when DSI host can't be found
+    - drm/bridge: anx7625: Update audio status while detecting
+    - drm/panel: simple: Add missing Innolux G121X1-L03 format, flags, connector
+    - ALSA: hda: cs35l41: Remove Speaker ID for Lenovo Legion slim 7 16ARHA7
+    - drm/mipi-dsi: use correct return type for the DSC functions
+    - media: uvcvideo: Add quirk for Logitech Rally Bar
+    - drm/rockchip: vop2: Do not divide height twice for YUV
+    - drm/edid: Parse topology block for all DispID structure v1.x
+    - media: cadence: csi2rx: configure DPHY before starting source stream
+    - clk: samsung: exynosautov9: fix wrong pll clock id value
+    - RDMA/mlx5: Uncacheable mkey has neither rb_key or cache_ent
+    - RDMA/mlx5: Change check for cacheable mkeys
+    - RDMA/mlx5: Adding remote atomic access flag to updatable flags
+    - clk: mediatek: pllfh: Don't log error for missing fhctl node
+    - iommu: Undo pasid attachment only for the devices that have succeeded
+    - RDMA/hns: Fix return value in hns_roce_map_mr_sg
+    - RDMA/hns: Fix deadlock on SRQ async events.
+    - RDMA/hns: Fix UAF for cq async event
+    - RDMA/hns: Fix GMV table pagesize
+    - RDMA/hns: Use complete parentheses in macros
+    - RDMA/hns: Modify the print level of CQE error
+    - clk: mediatek: mt8365-mm: fix DPI0 parent
+    - clk: rs9: fix wrong default value for clock amplitude
+    - clk: qcom: clk-alpha-pll: remove invalid Stromer register offset
+    - RDMA/rxe: Fix seg fault in rxe_comp_queue_pkt
+    - RDMA/rxe: Allow good work requests to be executed
+    - RDMA/rxe: Fix incorrect rxe_put in error path
+    - IB/mlx5: Use __iowrite64_copy() for write combining stores
+    - clk: renesas: r8a779a0: Fix CANFD parent clock
+    - clk: renesas: r9a07g043: Add clock and reset entry for PLIC
+    - lib/test_hmm.c: handle src_pfns and dst_pfns allocation failure
+    - mm/ksm: fix ksm exec support for prctl
+    - clk: qcom: dispcc-sm8450: fix DisplayPort clocks
+    - clk: qcom: dispcc-sm6350: fix DisplayPort clocks
+    - clk: qcom: dispcc-sm8550: fix DisplayPort clocks
+    - clk: qcom: dispcc-sm8650: fix DisplayPort clocks
+    - clk: qcom: mmcc-msm8998: fix venus clock issue
+    - x86/insn: Fix PUSH instruction in x86 instruction decoder opcode map
+    - x86/insn: Add VEX versions of VPDPBUSD, VPDPBUSDS, VPDPWSSD and VPDPWSSDS
+    - ext4: avoid excessive credit estimate in ext4_tmpfile()
+    - RDMA/mana_ib: Introduce helpers to create and destroy mana queues
+    - RDMA/mana_ib: Use struct mana_ib_queue for CQs
+    - RDMA/mana_ib: boundary check before installing cq callbacks
+    - virt: acrn: stop using follow_pfn
+    - drivers/virt/acrn: fix PFNMAP PTE checks in acrn_vm_ram_map()
+    - sunrpc: removed redundant procp check
+    - nfsd: don't create nfsv4recoverydir in nfsdfs when not used.
+    - ext4: fix potential unnitialized variable
+    - ext4: remove the redundant folio_wait_stable()
+    - clk: qcom: Fix SC_CAMCC_8280XP dependencies
+    - [Config] updateconfigs for SC_CAMCC_8280XP
+    - clk: qcom: Fix SM_GPUCC_8650 dependencies
+    - [Config] updateconfigs for SM_GPUCC_8650
+    - clk: qcom: apss-ipq-pll: fix PLL rate for IPQ5018
+    - of: module: add buffer overflow check in of_modalias()
+    - bnxt_re: avoid shift undefined behavior in bnxt_qplib_alloc_init_hwq
+    - SUNRPC: Fix gss_free_in_token_pages()
+    - selftests/damon/_damon_sysfs: check errors from nr_schemes file reads
+    - selftests/kcmp: remove unused open mode
+    - RDMA/IPoIB: Fix format truncation compilation errors
+    - RDMA/cma: Fix kmemleak in rdma_core observed during blktests nvme/rdma use
+      siw
+    - samples/landlock: Fix incorrect free in populate_ruleset_net
+    - tracing/user_events: Prepare find/delete for same name events
+    - tracing/user_events: Fix non-spaced field matching
+    - modules: Drop the .export_symbol section from the final modules
+    - net: bridge: xmit: make sure we have at least eth header len bytes
+    - selftests: net: bridge: increase IGMP/MLD exclude timeout membership
+      interval
+    - net: bridge: mst: fix vlan use-after-free
+    - net: qrtr: ns: Fix module refcnt
+    - selftests/net/lib: no need to record ns name if it already exist
+    - idpf: don't skip over ethtool tcp-data-split setting
+    - netrom: fix possible dead-lock in nr_rt_ioctl()
+    - af_packet: do not call packet_read_pending() from tpacket_destruct_skb()
+    - sched/fair: Allow disabling sched_balance_newidle with
+      sched_relax_domain_level
+    - sched/core: Fix incorrect initialization of the 'burst' parameter in
+      cpu_max_write()
+    - net: wangxun: fix to change Rx features
+    - net: wangxun: match VLAN CTAG and STAG features
+    - net: txgbe: move interrupt codes to a separate file
+    - net: txgbe: use irq_domain for interrupt controller
+    - net: txgbe: fix to control VLAN strip
+    - l2tp: fix ICMP error handling for UDP-encap sockets
+    - io_uring/net: ensure async prep handlers always initialize ->done_io
+    - pwm: Fix setting period with #pwm-cells = <1> and of_pwm_single_xlate()
+    - net: txgbe: fix to clear interrupt status after handling IRQ
+    - net: txgbe: fix GPIO interrupt blocking
+    - Linux 6.8.12
+  * Noble update: v6.8.11 upstream stable release (LP: #2070355)
+    - drm/amd/display: Fix division by zero in setup_dsc_config
+    - net: ks8851: Fix another TX stall caused by wrong ISR flag handling
+    - ice: pass VSI pointer into ice_vc_isvalid_q_id
+    - ice: remove unnecessary duplicate checks for VF VSI ID
+    - Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_connect()
+    - Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init()
+    - KEYS: trusted: Fix memory leak in tpm2_key_encode()
+    - erofs: get rid of erofs_fs_context
+    - erofs: reliably distinguish block based and fscache mode
+    - binder: fix max_thread type inconsistency
+    - usb: dwc3: Wait unconditionally after issuing EndXfer command
+    - net: usb: ax88179_178a: fix link status when link is set to down/up
+    - usb: typec: ucsi: displayport: Fix potential deadlock
+    - usb: typec: tipd: fix event checking for tps25750
+    - usb: typec: tipd: fix event checking for tps6598x
+    - serial: kgdboc: Fix NMI-safety problems from keyboard reset code
+    - remoteproc: mediatek: Make sure IPI buffer fits in L2TCM
+    - KEYS: trusted: Do not use WARN when encode fails
+    - admin-guide/hw-vuln/core-scheduling: fix return type of PR_SCHED_CORE_GET
+    - docs: kernel_include.py: Cope with docutils 0.21
+    - Docs/admin-guide/mm/damon/usage: fix wrong example of DAMOS filter matching
+      sysfs file
+    - block: add a disk_has_partscan helper
+    - block: add a partscan sysfs attribute for disks
+    - Linux 6.8.11
+  * Noble update: v6.8.10 upstream stable release (LP: #2070349)
+    - rust: module: place generated init_module() function in .init.text
+    - rust: macros: fix soundness issue in `module!` macro
+    - wifi: nl80211: don't free NULL coalescing rule
+    - pinctrl: pinctrl-aspeed-g6: Fix register offset for pinconf of GPIOR-T
+    - pinctrl/meson: fix typo in PDM's pin name
+    - pinctrl: core: delete incorrect free in pinctrl_enable()
+    - pinctrl: mediatek: paris: Fix PIN_CONFIG_INPUT_SCHMITT_ENABLE readback
+    - pinctrl: mediatek: paris: Rework support for
+      PIN_CONFIG_{INPUT,OUTPUT}_ENABLE
+    - sunrpc: add a struct rpc_stats arg to rpc_create_args
+    - nfs: expose /proc/net/sunrpc/nfs in net namespaces
+    - nfs: make the rpc_stat per net namespace
+    - nfs: Handle error of rpc_proc_register() in nfs_net_init().
+    - pinctrl: baytrail: Fix selecting gpio pinctrl state
+    - power: rt9455: hide unused rt9455_boost_voltage_values
+    - power: supply: mt6360_charger: Fix of_match for usb-otg-vbus regulator
+    - pinctrl: devicetree: fix refcount leak in pinctrl_dt_to_map()
+    - nfsd: rename NFSD_NET_* to NFSD_STATS_*
+    - nfsd: expose /proc/net/sunrpc/nfsd in net namespaces
+    - nfsd: make all of the nfsd stats per-network namespace
+    - NFSD: add support for CB_GETATTR callback
+    - NFSD: Fix nfsd4_encode_fattr4() crasher
+    - regulator: mt6360: De-capitalize devicetree regulator subnodes
+    - regulator: change stubbed devm_regulator_get_enable to return Ok
+    - regulator: change devm_regulator_get_enable_optional() stub to return Ok
+    - bpf, kconfig: Fix DEBUG_INFO_BTF_MODULES Kconfig definition
+    - bpf, skmsg: Fix NULL pointer dereference in sk_psock_skb_ingress_enqueue
+    - regmap: Add regmap_read_bypassed()
+    - ASoC: SOF: Intel: add default firmware library path for LNL
+    - nvme: fix warn output about shared namespaces without CONFIG_NVME_MULTIPATH
+    - bpf: Fix a verifier verbose message
+    - spi: axi-spi-engine: use common AXI macros
+    - spi: axi-spi-engine: fix version format string
+    - spi: hisi-kunpeng: Delete the dump interface of data registers in debugfs
+    - bpf, arm64: Fix incorrect runtime stats
+    - riscv, bpf: Fix incorrect runtime stats
+    - ASoC: Intel: avs: Set name of control as in topology
+    - ASoC: codecs: wsa881x: set clk_stop_mode1 flag
+    - s390/mm: Fix storage key clearing for guest huge pages
+    - s390/mm: Fix clearing storage keys for huge pages
+    - arm32, bpf: Reimplement sign-extension mov instruction
+    - xdp: use flags field to disambiguate broadcast redirect
+    - efi/unaccepted: touch soft lockup during memory accept
+    - ice: ensure the copied buf is NUL terminated
+    - bna: ensure the copied buf is NUL terminated
+    - octeontx2-af: avoid off-by-one read from userspace
+    - thermal/debugfs: Free all thermal zone debug memory on zone removal
+    - thermal/debugfs: Fix two locking issues with thermal zone debug
+    - nsh: Restore skb->{protocol,data,mac_header} for outer header in
+      nsh_gso_segment().
+    - net l2tp: drop flow hash on forward
+    - thermal/debugfs: Prevent use-after-free from occurring after cdev removal
+    - s390/vdso: Add CFI for RA register to asm macro vdso_func
+    - Fix a potential infinite loop in extract_user_to_sg()
+    - ALSA: emu10k1: fix E-MU card dock presence monitoring
+    - ALSA: emu10k1: factor out snd_emu1010_load_dock_firmware()
+    - ALSA: emu10k1: move the whole GPIO event handling to the workqueue
+    - ALSA: emu10k1: fix E-MU dock initialization
+    - net: qede: sanitize 'rc' in qede_add_tc_flower_fltr()
+    - net: qede: use return from qede_parse_flow_attr() for flower
+    - net: qede: use return from qede_parse_flow_attr() for flow_spec
+    - net: qede: use return from qede_parse_actions()
+    - vxlan: Fix racy device stats updates.
+    - vxlan: Add missing VNI filter counter update in arp_reduce().
+    - ASoC: meson: axg-fifo: use FIELD helpers
+    - ASoC: meson: axg-fifo: use threaded irq to check periods
+    - ASoC: meson: axg-card: make links nonatomic
+    - ASoC: meson: axg-tdm-interface: manage formatters in trigger
+    - ASoC: meson: cards: select SND_DYNAMIC_MINORS
+    - ALSA: hda: intel-sdw-acpi: fix usage of device_get_named_child_node()
+    - s390/cio: Ensure the copied buf is NUL terminated
+    - cxgb4: Properly lock TX queue for the selftest.
+    - net: dsa: mv88e6xxx: Fix number of databases for 88E6141 / 88E6341
+    - drm/amdgpu: fix doorbell regression
+    - spi: fix null pointer dereference within spi_sync
+    - net: bridge: fix multicast-to-unicast with fraglist GSO
+    - net: core: reject skb_copy(_expand) for fraglist GSO skbs
+    - rxrpc: Clients must accept conn from any address
+    - tipc: fix a possible memleak in tipc_buf_append
+    - vxlan: Pull inner IP header in vxlan_rcv().
+    - s390/qeth: Fix kernel panic after setting hsuid
+    - drm/panel: ili9341: Correct use of device property APIs
+    - [Config] updateconfigs for DRM_PANEL_ILITEK_ILI9341
+    - drm/panel: ili9341: Respect deferred probe
+    - drm/panel: ili9341: Use predefined error codes
+    - ipv4: Fix uninit-value access in __ip_make_skb()
+    - net: gro: fix udp bad offset in socket lookup by adding
+      {inner_}network_offset to napi_gro_cb
+    - net: gro: add flush check in udp_gro_receive_segment
+    - drm/xe/display: Fix ADL-N detection
+    - clk: qcom: smd-rpm: Restore msm8976 num_clk
+    - clk: sunxi-ng: h6: Reparent CPUX during PLL CPUX rate change
+    - powerpc/pseries: make max polling consistent for longer H_CALLs
+    - powerpc/pseries/iommu: LPAR panics during boot up with a frozen PE
+    - EDAC/versal: Do not log total error counts
+    - swiotlb: initialise restricted pool list_head when SWIOTLB_DYNAMIC=y
+    - KVM: arm64: vgic-v2: Check for non-NULL vCPU in vgic_v2_parse_attr()
+    - exfat: fix timing of synchronizing bitmap and inode
+    - firmware: microchip: don't unconditionally print validation success
+    - scsi: ufs: core: Fix MCQ MAC configuration
+    - scsi: lpfc: Move NPIV's transport unregistration to after resource clean up
+    - scsi: lpfc: Remove IRQF_ONESHOT flag from threaded IRQ handling
+    - scsi: lpfc: Update lpfc_ramp_down_queue_handler() logic
+    - scsi: lpfc: Replace hbalock with ndlp lock in lpfc_nvme_unregister_port()
+    - scsi: lpfc: Release hbalock before calling lpfc_worker_wake_up()
+    - scsi: lpfc: Use a dedicated lock for ras_fwlog state
+    - gfs2: Fix invalid metadata access in punch_hole
+    - fs/9p: fix uninitialized values during inode evict
+    - wifi: mac80211: fix ieee80211_bss_*_flags kernel-doc
+    - wifi: cfg80211: fix rdev_dump_mpp() arguments order
+    - wifi: mac80211: fix prep_connection error path
+    - wifi: iwlwifi: read txq->read_ptr under lock
+    - wifi: iwlwifi: mvm: guard against invalid STA ID on removal
+    - net: mark racy access on sk->sk_rcvbuf
+    - drm/xe: Fix END redefinition
+    - scsi: mpi3mr: Avoid memcpy field-spanning write WARNING
+    - scsi: bnx2fc: Remove spin_lock_bh while releasing resources after upload
+    - btrfs: return accurate error code on open failure in open_fs_devices()
+    - drm/amdkfd: Check cgroup when returning DMABuf info
+    - drm/amdkfd: range check cp bad op exception interrupts
+    - bpf: Check bloom filter map value size
+    - selftests/ftrace: Fix event filter target_func selection
+    - kbuild: Disable KCSAN for autogenerated *.mod.c intermediaries
+    - ASoC: SOF: Intel: hda-dsp: Skip IMR boot on ACE platforms in case of S3
+      suspend
+    - regulator: tps65132: Add of_match table
+    - OSS: dmasound/paula: Mark driver struct with __refdata to prevent section
+      mismatch
+    - scsi: ufs: core: WLUN suspend dev/link state error recovery
+    - scsi: libsas: Align SMP request allocation to ARCH_DMA_MINALIGN
+    - scsi: ufs: core: Fix MCQ mode dev command timeout
+    - ALSA: line6: Zero-initialize message buffers
+    - block: fix overflow in blk_ioctl_discard()
+    - ASoC: codecs: ES8326: Solve error interruption issue
+    - ASoC: codecs: ES8326: modify clock table
+    - net: bcmgenet: Reset RBUF on first open
+    - vboxsf: explicitly deny setlease attempts
+    - ata: sata_gemini: Check clk_enable() result
+    - firewire: ohci: mask bus reset interrupts between ISR and bottom half
+    - tools/power turbostat: Fix added raw MSR output
+    - tools/power turbostat: Increase the limit for fd opened
+    - tools/power turbostat: Fix Bzy_MHz documentation typo
+    - tools/power turbostat: Do not print negative LPI residency
+    - tools/power turbostat: Expand probe_intel_uncore_frequency()
+    - tools/power turbostat: Print ucode revision only if valid
+    - tools/power turbostat: Fix warning upon failed /dev/cpu_dma_latency read
+    - btrfs: make btrfs_clear_delalloc_extent() free delalloc reserve
+    - btrfs: always clear PERTRANS metadata during commit
+    - memblock tests: fix undefined reference to `early_pfn_to_nid'
+    - memblock tests: fix undefined reference to `panic'
+    - memblock tests: fix undefined reference to `BIT'
+    - nouveau/gsp: Avoid addressing beyond end of rpc->entries
+    - scsi: target: Fix SELinux error when systemd-modules loads the target module
+    - scsi: hisi_sas: Handle the NCQ error returned by D2H frame
+    - blk-iocost: avoid out of bounds shift
+    - accel/ivpu: Remove d3hot_after_power_off WA
+    - accel/ivpu: Improve clarity of MMU error messages
+    - accel/ivpu: Fix missed error message after VPU rename
+    - platform/x86: acer-wmi: Add support for Acer PH18-71
+    - gpu: host1x: Do not setup DMA for virtual devices
+    - MIPS: scall: Save thread_info.syscall unconditionally on entry
+    - tools/power/turbostat: Fix uncore frequency file string
+    - net: add copy_safe_from_sockptr() helper
+    - nfc: llcp: fix nfc_llcp_setsockopt() unsafe copies
+    - drm/amdgpu: Refine IB schedule error logging
+    - drm/amd/display: add DCN 351 version for microcode load
+    - drm/amdgpu: add smu 14.0.1 discovery support
+    - drm/amdgpu: implement IRQ_STATE_ENABLE for SDMA v4.4.2
+    - drm/amd/display: Skip on writeback when it's not applicable
+    - drm/amd/pm: fix the high voltage issue after unload
+    - drm/amdgpu: Fix VCN allocation in CPX partition
+    - amd/amdkfd: sync all devices to wait all processes being evicted
+    - selftests: timers: Fix valid-adjtimex signed left-shift undefined behavior
+    - Drivers: hv: vmbus: Leak pages if set_memory_encrypted() fails
+    - Drivers: hv: vmbus: Track decrypted status in vmbus_gpadl
+    - hv_netvsc: Don't free decrypted memory
+    - uio_hv_generic: Don't free decrypted memory
+    - Drivers: hv: vmbus: Don't free ring buffers that couldn't be re-encrypted
+    - drm/xe/xe_migrate: Cast to output precision before multiplying operands
+    - drm/xe: Label RING_CONTEXT_CONTROL as masked
+    - smb3: fix broken reconnect when password changing on the server by allowing
+      password rotation
+    - iommu: mtk: fix module autoloading
+    - fs/9p: only translate RWX permissions for plain 9P2000
+    - fs/9p: translate O_TRUNC into OTRUNC
+    - fs/9p: fix the cache always being enabled on files with qid flags
+    - 9p: explicitly deny setlease attempts
+    - powerpc/crypto/chacha-p10: Fix failure on non Power10
+    - gpio: wcove: Use -ENOTSUPP consistently
+    - gpio: crystalcove: Use -ENOTSUPP consistently
+    - clk: Don't hold prepare_lock when calling kref_put()
+    - fs/9p: remove erroneous nlink init from legacy stat2inode
+    - fs/9p: drop inodes immediately on non-.L too
+    - gpio: lpc32xx: fix module autoloading
+    - drm/nouveau/dp: Don't probe eDP ports twice harder
+    - platform/x86/amd: pmf: Decrease error message to debug
+    - platform/x86: ISST: Add Granite Rapids-D to HPM CPU list
+    - drm/radeon: silence UBSAN warning (v3)
+    - net:usb:qmi_wwan: support Rolling modules
+    - blk-iocost: do not WARN if iocg was already offlined
+    - SUNRPC: add a missing rpc_stat for TCP TLS
+    - qibfs: fix dentry leak
+    - xfrm: Preserve vlan tags for transport mode software GRO
+    - ARM: 9381/1: kasan: clear stale stack poison
+    - tcp: defer shutdown(SEND_SHUTDOWN) for TCP_SYN_RECV sockets
+    - tcp: Use refcount_inc_not_zero() in tcp_twsk_unique().
+    - Bluetooth: Fix use-after-free bugs caused by sco_sock_timeout
+    - Bluetooth: msft: fix slab-use-after-free in msft_do_close()
+    - arm64: dts: mediatek: mt8183-pico6: Fix bluetooth node
+    - Bluetooth: HCI: Fix potential null-ptr-deref
+    - Bluetooth: l2cap: fix null-ptr-deref in l2cap_chan_timeout
+    - net: ks8851: Queue RX packets in IRQ handler instead of disabling BHs
+    - rtnetlink: Correct nested IFLA_VF_VLAN_LIST attribute validation
+    - hwmon: (corsair-cpro) Use a separate buffer for sending commands
+    - hwmon: (corsair-cpro) Use complete_all() instead of complete() in
+      ccp_raw_event()
+    - hwmon: (corsair-cpro) Protect ccp->wait_input_report with a spinlock
+    - phonet: fix rtm_phonet_notify() skb allocation
+    - netlink: specs: Add missing bridge linkinfo attrs
+    - nfc: nci: Fix kcov check in nci_rx_work()
+    - net: bridge: fix corrupted ethernet header on multicast-to-unicast
+    - ipv6: Fix potential uninit-value access in __ip6_make_skb()
+    - selftests: test_bridge_neigh_suppress.sh: Fix failures due to duplicate MAC
+    - rxrpc: Fix the names of the fields in the ACK trailer struct
+    - rxrpc: Fix congestion control algorithm
+    - rxrpc: Only transmit one ACK per jumbo packet received
+    - dt-bindings: net: mediatek: remove wrongly added clocks and SerDes
+    - ipv6: fib6_rules: avoid possible NULL dereference in fib6_rule_action()
+    - net-sysfs: convert dev->operstate reads to lockless ones
+    - hsr: Simplify code for announcing HSR nodes timer setup
+    - ipv6: annotate data-races around cnf.disable_ipv6
+    - ipv6: prevent NULL dereference in ip6_output()
+    - net/smc: fix neighbour and rtable leak in smc_ib_find_route()
+    - net: hns3: using user configure after hardware reset
+    - net: hns3: direct return when receive a unknown mailbox message
+    - net: hns3: change type of numa_node_mask as nodemask_t
+    - net: hns3: release PTP resources if pf initialization failed
+    - net: hns3: use appropriate barrier function after setting a bit value
+    - net: hns3: fix port vlan filter not disabled issue
+    - net: hns3: fix kernel crash when devlink reload during initialization
+    - net: dsa: mv88e6xxx: add phylink_get_caps for the mv88e6320/21 family
+    - drm/meson: dw-hdmi: power up phy on device init
+    - drm/meson: dw-hdmi: add bandgap setting for g12
+    - drm/connector: Add \n to message about demoting connector force-probes
+    - dm/amd/pm: Fix problems with reboot/shutdown for some SMU 13.0.4/13.0.11
+      users
+    - gpiolib: cdev: Fix use after free in lineinfo_changed_notify
+    - gpiolib: cdev: fix uninitialised kfifo
+    - drm/amdgpu: Fix comparison in amdgpu_res_cpu_visible
+    - drm/amdgpu: once more fix the call oder in amdgpu_ttm_move() v2
+    - firewire: nosy: ensure user_length is taken into account when fetching
+      packet contents
+    - Reapply "drm/qxl: simplify qxl_fence_wait"
+    - usb: typec: ucsi: Check for notifications after init
+    - usb: typec: ucsi: Fix connector check on init
+    - usb: Fix regression caused by invalid ep0 maxpacket in virtual SuperSpeed
+      device
+    - usb: ohci: Prevent missed ohci interrupts
+    - USB: core: Fix access violation during port device removal
+    - usb: gadget: composite: fix OS descriptors w_value logic
+    - usb: gadget: uvc: use correct buffer size when parsing configfs lists
+    - usb: gadget: f_fs: Fix race between aio_cancel() and AIO request complete
+    - usb: gadget: f_fs: Fix a race condition when processing setup packets.
+    - usb: xhci-plat: Don't include xhci.h
+    - usb: dwc3: core: Prevent phy suspend during init
+    - usb: typec: tcpm: clear pd_event queue in PORT_RESET
+    - usb: typec: tcpm: unregister existing source caps before re-registration
+    - usb: typec: tcpm: Check for port partner validity before consuming it
+    - ALSA: hda/realtek: Fix mute led of HP Laptop 15-da3001TU
+    - ALSA: hda/realtek: Fix conflicting PCI SSID 17aa:386f for Lenovo Legion
+      models
+    - firewire: ohci: fulfill timestamp for some local asynchronous transaction
+    - mm/slub: avoid zeroing outside-object freepointer for single free
+    - btrfs: add missing mutex_unlock in btrfs_relocate_sys_chunks()
+    - btrfs: set correct ram_bytes when splitting ordered extent
+    - btrfs: qgroup: do not check qgroup inherit if qgroup is disabled
+    - btrfs: make sure that WRITTEN is set on all metadata blocks
+    - maple_tree: fix mas_empty_area_rev() null pointer dereference
+    - mm/slab: make __free(kfree) accept error pointers
+    - mptcp: ensure snd_nxt is properly initialized on connect
+    - mptcp: only allow set existing scheduler for net.mptcp.scheduler
+    - workqueue: Fix selection of wake_cpu in kick_pool()
+    - dt-bindings: iio: health: maxim,max30102: fix compatible check
+    - iio:imu: adis16475: Fix sync mode setting
+    - iio: pressure: Fixes BME280 SPI driver data
+    - iio: pressure: Fixes SPI support for BMP3xx devices
+    - iio: accel: mxc4005: Interrupt handling fixes
+    - iio: accel: mxc4005: Reset chip on probe() and resume()
+    - kmsan: compiler_types: declare __no_sanitize_or_inline
+    - e1000e: change usleep_range to udelay in PHY mdic access
+    - tipc: fix UAF in error path
+    - xtensa: fix MAKE_PC_FROM_RA second argument
+    - net: bcmgenet: synchronize EXT_RGMII_OOB_CTRL access
+    - net: bcmgenet: synchronize use of bcmgenet_set_rx_mode()
+    - net: bcmgenet: synchronize UMAC_CMD access
+    - ASoC: tegra: Fix DSPK 16-bit playback
+    - ASoC: ti: davinci-mcasp: Fix race condition during probe
+    - dyndbg: fix old BUG_ON in >control parser
+    - slimbus: qcom-ngd-ctrl: Add timeout for wait operation
+    - clk: samsung: Revert "clk: Use device_get_match_data()"
+    - clk: sunxi-ng: common: Support minimum and maximum rate
+    - clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI
+    - mei: me: add lunar lake point M DID
+    - drm/nouveau/firmware: Fix SG_DEBUG error with nvkm_firmware_ctor()
+    - Revert "drm/nouveau/firmware: Fix SG_DEBUG error with nvkm_firmware_ctor()"
+    - drm/amdkfd: don't allow mapping the MMIO HDP page with large pages
+    - drm/ttm: Print the memory decryption status just once
+    - drm/vmwgfx: Fix Legacy Display Unit
+    - drm/vmwgfx: Fix invalid reads in fence signaled events
+    - drm/imagination: Ensure PVR_MIPS_PT_PAGE_COUNT is never zero
+    - drm/amd/display: Fix idle optimization checks for multi-display and dual eDP
+    - drm/nouveau/gsp: Use the sg allocator for level 2 of radix3
+    - drm/i915/gt: Automate CCS Mode setting during engine resets
+    - drm/i915/bios: Fix parsing backlight BDB data
+    - drm/amd/display: Handle Y carry-over in VCP X.Y calculation
+    - drm/amd/display: Fix incorrect DSC instance for MST
+    - arm64: dts: qcom: sa8155p-adp: fix SDHC2 CD pin configuration
+    - iommu/arm-smmu: Use the correct type in nvidia_smmu_context_fault()
+    - net: fix out-of-bounds access in ops_init
+    - hwmon: (pmbus/ucd9000) Increase delay from 250 to 500us
+    - misc/pvpanic-pci: register attributes via pci_driver
+    - x86/apic: Don't access the APIC when disabling x2APIC
+    - selftests/mm: fix powerpc ARCH check
+    - mm: use memalloc_nofs_save() in page_cache_ra_order()
+    - mm/userfaultfd: reset ptes when close() for wr-protected ones
+    - iommu/amd: Enhance def_domain_type to handle untrusted device
+    - fs/proc/task_mmu: fix loss of young/dirty bits during pagemap scan
+    - fs/proc/task_mmu: fix uffd-wp confusion in pagemap_scan_pmd_entry()
+    - nvme-pci: Add quirk for broken MSIs
+    - regulator: core: fix debugfs creation regression
+    - spi: microchip-core-qspi: fix setting spi bus clock rate
+    - ksmbd: off ipv6only for both ipv4/ipv6 binding
+    - ksmbd: avoid to send duplicate lease break notifications
+    - ksmbd: do not grant v2 lease if parent lease key and epoch are not set
+    - tracefs: Reset permissions on remount if permissions are options
+    - tracefs: Still use mount point as default permissions for instances
+    - eventfs: Do not treat events directory different than other directories
+    - Bluetooth: qca: fix invalid device address check
+    - Bluetooth: qca: fix wcn3991 device address check
+    - Bluetooth: qca: add missing firmware sanity checks
+    - Bluetooth: qca: fix NVM configuration parsing
+    - Bluetooth: qca: generalise device address check
+    - Bluetooth: qca: fix info leak when fetching board id
+    - Bluetooth: qca: fix info leak when fetching fw build id
+    - Bluetooth: qca: fix firmware check error path
+    - keys: Fix overwrite of key expiration on instantiation
+    - Linux 6.8.10
+  * Noble update: v6.8.9 upstream stable release (LP: #2070337)
+    - cifs: Fix reacquisition of volume cookie on still-live connection
+    - smb: client: fix rename(2) regression against samba
+    - cifs: reinstate original behavior again for forceuid/forcegid
+    - HID: intel-ish-hid: ipc: Fix dev_err usage with uninitialized dev->devc
+    - HID: logitech-dj: allow mice to use all types of reports
+    - arm64: dts: rockchip: set PHY address of MT7531 switch to 0x1f
+    - arm64: dts: rockchip: enable internal pull-up on Q7_USB_ID for RK3399 Puma
+    - arm64: dts: rockchip: fix alphabetical ordering RK3399 puma
+    - arm64: dts: rockchip: enable internal pull-up on PCIE_WAKE# for RK3399 Puma
+    - arm64: dts: rockchip: Fix the i2c address of es8316 on Cool Pi CM5
+    - arm64: dts: rockchip: Remove unsupported node from the Pinebook Pro dts
+    - arm64: dts: mediatek: mt8183: Add power-domains properity to mfgcfg
+    - arm64: dts: mediatek: mt8192: Add missing gce-client-reg to mutex
+    - arm64: dts: mediatek: mt8195: Add missing gce-client-reg to vpp/vdosys
+    - arm64: dts: mediatek: mt8195: Add missing gce-client-reg to mutex
+    - arm64: dts: mediatek: mt8195: Add missing gce-client-reg to mutex1
+    - arm64: dts: mediatek: cherry: Describe CPU supplies
+    - arm64: dts: mediatek: mt8192-asurada: Update min voltage constraint for
+      MT6315
+    - arm64: dts: mediatek: mt8195-cherry: Update min voltage constraint for
+      MT6315
+    - arm64: dts: mediatek: mt8183-kukui: Use default min voltage for MT6358
+    - arm64: dts: mediatek: mt7622: fix clock controllers
+    - arm64: dts: mediatek: mt7622: fix IR nodename
+    - arm64: dts: mediatek: mt7622: fix ethernet controller "compatible"
+    - arm64: dts: mediatek: mt7622: drop "reset-names" from thermal block
+    - arm64: dts: mediatek: mt7986: reorder properties
+    - arm64: dts: mediatek: mt7986: drop invalid properties from ethsys
+    - arm64: dts: mediatek: mt7986: drop "#reset-cells" from Ethernet controller
+    - arm64: dts: mediatek: mt7986: reorder nodes
+    - arm64: dts: mediatek: mt7986: drop invalid thermal block clock
+    - arm64: dts: mediatek: mt7986: prefix BPI-R3 cooling maps with "map-"
+    - arm64: dts: mediatek: mt2712: fix validation errors
+    - arm64: dts: rockchip: mark system power controller and fix typo on
+      orangepi-5-plus
+    - arm64: dts: rockchip: regulator for sd needs to be always on for BPI-R2Pro
+    - block: fix module reference leakage from bdev_open_by_dev error path
+    - arm64: dts: qcom: Fix type of "wdog" IRQs for remoteprocs
+    - arm64: dts: qcom: x1e80100: Fix the compatible for cluster idle states
+    - arm64: dts: qcom: sc8180x: Fix ss_phy_irq for secondary USB controller
+    - gpio: tangier: Use correct type for the IRQ chip data
+    - ARC: [plat-hsdk]: Remove misplaced interrupt-cells property
+    - wifi: mac80211: clean up assignments to pointer cache.
+    - wifi: mac80211: split mesh fast tx cache into local/proxied/forwarded
+    - wifi: iwlwifi: mvm: remove old PASN station when adding a new one
+    - wifi: iwlwifi: mvm: return uid from iwl_mvm_build_scan_cmd
+    - drm/gma500: Remove lid code
+    - wifi: mac80211_hwsim: init peer measurement result
+    - wifi: mac80211: remove link before AP
+    - wifi: mac80211: fix unaligned le16 access
+    - net: libwx: fix alloc msix vectors failed
+    - vxlan: drop packets from invalid src-address
+    - net: bcmasp: fix memory leak when bringing down interface
+    - mlxsw: core: Unregister EMAD trap using FORWARD action
+    - mlxsw: core_env: Fix driver initialization with old firmware
+    - mlxsw: pci: Fix driver initialization with old firmware
+    - ARM: dts: microchip: at91-sama7g5ek: Replace regulator-suspend-voltage with
+      the valid property
+    - icmp: prevent possible NULL dereferences from icmp_build_probe()
+    - bridge/br_netlink.c: no need to return void function
+    - bnxt_en: refactor reset close code
+    - bnxt_en: Fix the PCI-AER routines
+    - bnxt_en: Fix error recovery for 5760X (P7) chips
+    - cxl/core: Fix potential payload size confusion in cxl_mem_get_poison()
+    - net: dsa: mv88e6xx: fix supported_interfaces setup in
+      mv88e6250_phylink_get_caps()
+    - NFC: trf7970a: disable all regulators on removal
+    - netfs: Fix writethrough-mode error handling
+    - ax25: Fix netdev refcount issue
+    - soc: mediatek: mtk-svs: Append "-thermal" to thermal zone names
+    - tools: ynl: don't ignore errors in NLMSG_DONE messages
+    - net: usb: ax88179_178a: stop lying about skb->truesize
+    - tcp: Fix Use-After-Free in tcp_ao_connect_init
+    - net: gtp: Fix Use-After-Free in gtp_dellink
+    - net: phy: mediatek-ge-soc: follow netdev LED trigger semantics
+    - gpio: tegra186: Fix tegra186_gpio_is_accessible() check
+    - drm/xe: Remove sysfs only once on action add failure
+    - drm/xe: call free_gsc_pkt only once on action add failure
+    - Bluetooth: hci_event: Use HCI error defines instead of magic values
+    - Bluetooth: hci_conn: Only do ACL connections sequentially
+    - Bluetooth: Remove pending ACL connection attempts
+    - Bluetooth: hci_conn: Always use sk_timeo as conn_timeout
+    - Bluetooth: hci_conn: Fix UAF Write in __hci_acl_create_connection_sync
+    - Bluetooth: hci_sync: Add helper functions to manipulate cmd_sync queue
+    - Bluetooth: hci_sync: Attempt to dequeue connection attempt
+    - Bluetooth: ISO: Reassemble PA data for bcast sink
+    - Bluetooth: hci_sync: Use advertised PHYs on hci_le_ext_create_conn_sync
+    - Bluetooth: btusb: Fix triggering coredump implementation for QCA
+    - Bluetooth: hci_event: Fix sending HCI_OP_READ_ENC_KEY_SIZE
+    - Bluetooth: MGMT: Fix failing to MGMT_OP_ADD_UUID/MGMT_OP_REMOVE_UUID
+    - Bluetooth: btusb: mediatek: Fix double free of skb in coredump
+    - Bluetooth: hci_sync: Using hci_cmd_sync_submit when removing Adv Monitor
+    - Bluetooth: qca: set power_ctrl_enabled on NULL returned by
+      gpiod_get_optional()
+    - ipvs: Fix checksumming on GSO of SCTP packets
+    - net: openvswitch: Fix Use-After-Free in ovs_ct_exit
+    - mlxsw: Use refcount_t for reference counting
+    - mlxsw: spectrum_acl_tcam: Fix race in region ID allocation
+    - mlxsw: spectrum_acl_tcam: Fix race during rehash delayed work
+    - mlxsw: spectrum_acl_tcam: Fix possible use-after-free during activity update
+    - mlxsw: spectrum_acl_tcam: Fix possible use-after-free during rehash
+    - mlxsw: spectrum_acl_tcam: Rate limit error message
+    - mlxsw: spectrum_acl_tcam: Fix memory leak during rehash
+    - mlxsw: spectrum_acl_tcam: Fix warning during rehash
+    - mlxsw: spectrum_acl_tcam: Fix incorrect list API usage
+    - mlxsw: spectrum_acl_tcam: Fix memory leak when canceling rehash work
+    - eth: bnxt: fix counting packets discarded due to OOM and netpoll
+    - ARM: dts: imx6ull-tarragon: fix USB over-current polarity
+    - netfilter: nf_tables: honor table dormant flag from netdev release event
+      path
+    - net: phy: dp83869: Fix MII mode failure
+    - net: ti: icssg-prueth: Fix signedness bug in prueth_init_rx_chns()
+    - i40e: Do not use WQ_MEM_RECLAIM flag for workqueue
+    - i40e: Report MFS in decimal base instead of hex
+    - iavf: Fix TC config comparison with existing adapter TC config
+    - ice: fix LAG and VF lock dependency in ice_reset_vf()
+    - net: ethernet: ti: am65-cpts: Fix PTPv1 message type on TX packets
+    - octeontx2-af: fix the double free in rvu_npc_freemem()
+    - dpll: check that pin is registered in __dpll_pin_unregister()
+    - dpll: fix dpll_pin_on_pin_register() for multiple parent pins
+    - tls: fix lockless read of strp->msg_ready in ->poll
+    - af_unix: Suppress false-positive lockdep splat for spin_lock() in
+      __unix_gc().
+    - netfs: Fix the pre-flush when appending to a file in writethrough mode
+    - drm/amd/display: Check DP Alt mode DPCS state via DMUB
+    - Revert "drm/amd/display: fix USB-C flag update after enc10 feature init"
+    - xhci: move event processing for one interrupter to a separate function
+    - usb: xhci: correct return value in case of STS_HCE
+    - KVM: x86/pmu: Zero out PMU metadata on AMD if PMU is disabled
+    - KVM: x86/pmu: Set enable bits for GP counters in PERF_GLOBAL_CTRL at "RESET"
+    - drm: add drm_gem_object_is_shared_for_memory_stats() helper
+    - drm/amdgpu: add shared fdinfo stats
+    - drm/amdgpu: fix visible VRAM handling during faults
+    - Revert "UBUNTU: SAUCE: selftests/seccomp: fix check of fds being assigned"
+    - selftests/seccomp: user_notification_addfd check nextfd is available
+    - selftests/seccomp: Change the syscall used in KILL_THREAD test
+    - selftests/seccomp: Handle EINVAL on unshare(CLONE_NEWPID)
+    - x86/CPU/AMD: Add models 0x10-0x1f to the Zen5 range
+    - x86/cpu: Fix check for RDPKRU in __show_regs()
+    - rust: phy: implement `Send` for `Registration`
+    - rust: kernel: require `Send` for `Module` implementations
+    - rust: don't select CONSTRUCTORS
+    - [Config] updateconfigs to drop CONSTRUCTORS for rust
+    - rust: init: remove impl Zeroable for Infallible
+    - rust: make mutually exclusive with CFI_CLANG
+    - kbuild: rust: remove unneeded `@rustc_cfg` to avoid ICE
+    - kbuild: rust: force `alloc` extern to allow "empty" Rust files
+    - rust: remove `params` from `module` macro example
+    - Bluetooth: Fix type of len in {l2cap,sco}_sock_getsockopt_old()
+    - Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x0bda:0x4853
+    - Bluetooth: qca: fix NULL-deref on non-serdev suspend
+    - Bluetooth: qca: fix NULL-deref on non-serdev setup
+    - mtd: rawnand: qcom: Fix broken OP_RESET_DEVICE command in
+      qcom_misc_cmd_type_exec()
+    - mm/hugetlb: fix missing hugetlb_lock for resv uncharge
+    - mmc: sdhci-msm: pervent access to suspended controller
+    - mmc: sdhci-of-dwcmshc: th1520: Increase tuning loop count to 128
+    - mm: create FOLIO_FLAG_FALSE and FOLIO_TYPE_OPS macros
+    - mm: support page_mapcount() on page_has_type() pages
+    - mm/hugetlb: fix DEBUG_LOCKS_WARN_ON(1) when dissolve_free_hugetlb_folio()
+    - smb: client: Fix struct_group() usage in __packed structs
+    - smb3: missing lock when picking channel
+    - smb3: fix lock ordering potential deadlock in cifs_sync_mid_result
+    - btrfs: fallback if compressed IO fails for ENOSPC
+    - btrfs: fix wrong block_start calculation for btrfs_drop_extent_map_range()
+    - btrfs: scrub: run relocation repair when/only needed
+    - btrfs: fix information leak in btrfs_ioctl_logical_to_ino()
+    - x86/tdx: Preserve shared bit on mprotect()
+    - cpu: Re-enable CPU mitigations by default for !X86 architectures
+    - [Config] updateconfigs for CPU_MITIGATIONS
+    - eeprom: at24: fix memory corruption race condition
+    - LoongArch: Fix callchain parse error with kernel tracepoint events
+    - LoongArch: Fix access error when read fault on a write-only VMA
+    - arm64: dts: qcom: sc8280xp: add missing PCIe minimum OPP
+    - arm64: dts: qcom: sm8450: Fix the msi-map entries
+    - arm64: dts: rockchip: enable internal pull-up for Q7_THRM# on RK3399 Puma
+    - dmaengine: Revert "dmaengine: pl330: issue_pending waits until WFP state"
+    - dmaengine: xilinx: xdma: Fix wrong offsets in the buffers addresses in dma
+      descriptor
+    - dmaengine: xilinx: xdma: Fix synchronization issue
+    - drm/amdgpu/sdma5.2: use legacy HDP flush for SDMA2/3
+    - drm/amdgpu: Assign correct bits for SDMA HDP flush
+    - drm/atomic-helper: fix parameter order in drm_format_conv_state_copy() call
+    - drm/amdgpu/pm: Remove gpu_od if it's an empty directory
+    - drm/amdgpu/umsch: don't execute umsch test when GPU is in reset/suspend
+    - drm/amdgpu: Fix leak when GPU memory allocation fails
+    - drm/amdkfd: Fix rescheduling of restore worker
+    - drm/amdkfd: Fix eviction fence handling
+    - irqchip/gic-v3-its: Prevent double free on error
+    - ACPI: CPPC: Use access_width over bit_width for system memory accesses
+    - ACPI: CPPC: Fix bit_offset shift in MASK_VAL() macro
+    - ACPI: CPPC: Fix access width used for PCC registers
+    - net/mlx5e: Advertise mlx5 ethernet driver updates sk_buff md_dst for MACsec
+    - ethernet: Add helper for assigning packet type when dest address does not
+      match device address
+    - net: b44: set pause params only when interface is up
+    - macsec: Enable devices to advertise whether they update sk_buff md_dst
+      during offloads
+    - macsec: Detect if Rx skb is macsec-related for offloading devices that
+      update md_dst
+    - stackdepot: respect __GFP_NOLOCKDEP allocation flag
+    - fbdev: fix incorrect address computation in deferred IO
+    - udp: preserve the connected status if only UDP cmsg
+    - mtd: limit OTP NVMEM cell parse to non-NAND devices
+    - mtd: diskonchip: work around ubsan link failure
+    - firmware: qcom: uefisecapp: Fix memory related IO errors and crashes
+    - phy: qcom: qmp-combo: Fix register base for QSERDES_DP_PHY_MODE
+    - phy: qcom: qmp-combo: Fix VCO div offset on v3
+    - mm: turn folio_test_hugetlb into a PageType
+    - mm: zswap: fix shrinker NULL crash with cgroup_disable=memory
+    - dmaengine: owl: fix register access functions
+    - dmaengine: tegra186: Fix residual calculation
+    - idma64: Don't try to serve interrupts when device is powered off
+    - soundwire: amd: fix for wake interrupt handling for clockstop mode
+    - phy: marvell: a3700-comphy: Fix hardcoded array size
+    - phy: freescale: imx8m-pcie: fix pcie link-up instability
+    - phy: rockchip-snps-pcie3: fix bifurcation on rk3588
+    - phy: rockchip-snps-pcie3: fix clearing PHP_GRF_PCIESEL_CON bits
+    - phy: rockchip: naneng-combphy: Fix mux on rk3588
+    - phy: qcom: m31: match requested regulator name with dt schema
+    - dmaengine: idxd: Convert spinlock to mutex to lock evl workqueue
+    - dmaengine: idxd: Fix oops during rmmod on single-CPU platforms
+    - riscv: Fix TASK_SIZE on 64-bit NOMMU
+    - riscv: Fix loading 64-bit NOMMU kernels past the start of RAM
+    - phy: ti: tusb1210: Resolve charger-det crash if charger psy is unregistered
+    - dt-bindings: eeprom: at24: Fix ST M24C64-D compatible schema
+    - sched/eevdf: Always update V if se->on_rq when reweighting
+    - sched/eevdf: Fix miscalculation in reweight_entity() when se is not curr
+    - riscv: hwprobe: fix invalid sign extension for RISCV_HWPROBE_EXT_ZVFHMIN
+    - RISC-V: selftests: cbo: Ensure asm operands match constraints, take 2
+    - phy: qcom: qmp-combo: fix VCO div offset on v5_5nm and v6
+    - bounds: Use the right number of bits for power-of-two CONFIG_NR_CPUS
+    - Bluetooth: hci_sync: Fix UAF in hci_acl_create_conn_sync
+    - Bluetooth: hci_sync: Fix UAF on create_le_conn_complete
+    - Bluetooth: hci_sync: Fix UAF on hci_abort_conn_sync
+    - Linux 6.8.9
+  * amdgpu hangs on DCN 3.5 at bootup: RIP:
+    0010:dcn35_clk_mgr_construct+0x183/0x2210 [amdgpu] (LP: #2066233)
+    - drm/amd/display: Atom Integrated System Info v2_2 for DCN35
+  * [MTL] ACPI: PM: s2idle: Backport Linux ACPI s2idle patches to fix
+    suspend/resume issue (LP: #2069231)
+    - ACPI: PM: s2idle: Enable Low-Power S0 Idle MSFT UUID for non-AMD systems
+    - ACPI: PM: s2idle: Evaluate all Low-Power S0 Idle _DSM functions
+  * Removing legacy virtio-pci devices causes kernel panic (LP: #2067862)
+    - virtio-pci: Check if is_avq is NULL
+  * Mute/mic LEDs no function on ProBook 445/465 G11 (LP: #2069664)
+    - ALSA: hda/realtek: fix mute/micmute LEDs don't work for ProBook 445/465 G11.
+  * Mute/mic LEDs no function on  ProBook 440/460 G11 (LP: #2067669)
+    - ALSA: hda/realtek: fix mute/micmute LEDs don't work for ProBook 440/460 G11.
+  * rtw89_8852ce - Lost WIFI connection after suspend  (LP: #2065128)
+    - wifi: rtw89: reset AFEDIG register in power off sequence
+    - wifi: rtw89: 8852c: refine power sequence to imporve power consumption
+  * CVE-2024-25742
+    - x86/sev: Harden #VC instruction emulation somewhat
+    - x86/sev: Check for MWAITX and MONITORX opcodes in the #VC handler
+  * Noble update: v6.8.9 upstream stable release (LP: #2070337) //
+    CVE-2024-35984
+    - i2c: smbus: fix NULL function pointer dereference
+  * Noble update: v6.8.9 upstream stable release (LP: #2070337) //
+    CVE-2024-35990
+    - dma: xilinx_dpdma: Fix locking
+  * Noble update: v6.8.9 upstream stable release (LP: #2070337) //
+    CVE-2024-35997
+    - HID: i2c-hid: remove I2C_HID_READ_PENDING flag to prevent lock-up
+  * CVE-2024-36016
+    - tty: n_gsm: fix possible out-of-bounds in gsm0_receive()
+  * CVE-2024-36008
+    - ipv4: check for NULL idev in ip_route_use_hint()
+  * CVE-2024-35992
+    - phy: marvell: a3700-comphy: Fix out of bounds read
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 12 Aug 2024 10:40:26 +0900
+
+linux-qcom (6.8.0-1006.6) jammy; urgency=medium
+
+  * [qcom alpha] Suppress noisy logs
+    - SAUCE: ubuntu/qcom/wlan: supress noisy logs
+    - SAUCE: ubuntu/qcom/wlan: supress noisy logs (take 2)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: ubuntu/qcom/wlan: import wlan qclacld driver code from GA1.1
+    - SAUCE: ubuntu/qcom/display: import qcm6490 display code from GA1.1
+    - SAUCE: ubuntu/qcom/graphics: import qcm6490 graphics driver code from GA1.1
+    - SAUCE: ubuntu/qcom/camera: import qcm6490 camera driver code from GA1.1
+    - SAUCE: ubuntu/qcom/bt: import qcm6490 bluetooth driver from GA1.1
+    - SAUCE: ubuntu/qcom/qps615: import ethernet driver from GA1.1
+    - SAUCE: ubuntu/qcom: build external drivers
+    - SAUCE: ubuntu/qcom: suppress warning and error
+    - SAUCE: ubuntu/qcom/wlan: fix build warnings and errors in WLAN driver
+    - SAUCE: ubuntu/qcom/graphics: change strtobool() to kstrtobool()
+    - SAUCE: ubuntu/qcom/graphics: dynamically allocate the kgsl-pool shrinker for
+      kernel>=6.7
+    - SAUCE: ubuntu/qcom/camera: remove unused camera_banner
+    - SAUCE: ubuntu/qcom/camera: use sizeof() instead of V4L2_SUBDEV_NAME_SIZE
+    - SAUCE: ubuntu/qcom/camera: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: auto-load module
+    - SAUCE: ubuntu/qcom: add missing inclusion
+    - SAUCE: ubuntu/qcom/display: Rename min_buffers_needed to min_queued_buffers
+    - SAUCE: ubuntu/qcom: remove DRM_UNLOCKED
+    - SAUCE: ubuntu/qcom/display: suppress EPROBE_DEFER error log
+    - SAUCE: qcom/bt: support uevent module loading
+    - SAUCE: qcom/bt: add sentinel to MODULE_DEVICE_TABLE()
+    - SAUCE: import external DT from GA 1.1
+    - SAUCE: Add Makefile code to apply overlays for GA1
+
+  * Miscellaneous upstream changes
+    - QCLINUX: regulator: qcom-rpmh-regulator: Add debug-regulator support
+    - PENDING: arm64: dts: qcom: qcs8550-rb5gen2: enable PMIC Volume and Power
+      buttons
+    - FROMLIST: dt-bindings: arm: qcom,ids: Add SoC ID for SM8650P
+    - FROMLIST: soc: qcom: socinfo: Add SM8650P SoC ID table entry
+    - PENDING: slimbus: messaging: use memcpy_fromio for io mapped memory
+    - FROMLIST: arm64: dts: qcom: sm8650p: introduce sm8650p dtsi
+    - FROMLIST: arm64: dts: qcom: add base AIM500 dtsi
+    - FROMLIST: arm64: dts: qcom: add AIM500 AIoT
+    - PENDING: arm64: qcom: dts: qcs8550: Add modem rproc node
+    - QCLINUX: soc: qcom: f_qdss: Initialize qdss channel with NULL
+    - PENDING: misc: fastrpc: Check for static PD status
+    - QCLINUX: soc: qcom: Use SoC watchdog when Linux boots in hyp mode
+    - QCLINUX: arm64: dts: qcom: qcm6490: Leave SoC watchdog enabled
+    - QCLINUX: arm64: Enable watchdog configuration through sysfs
+    - QCLINUX: soc: qcom: Make SoC debug module as builtin module
+    - FROMLIST: soc: qcom: aoss: Add tracepoints in qmp_send()
+    - PENDING: arm64: dts: qcom: sc7280: Add gpio for sec MI2S mclk
+    - QCLINUX: arm64: dts: qcom: Add addons support for AIM500 AIoT
+    - QCLINUX: arm64: defconfig: qcom: enable SM8650 related config
+    - QCLINUX: arm64: dts: qcom: aim300: Add board-id and msm-id support
+    - PENDING: misc: fastrpc: Fix use after free on devices
+    - PENDING: arm64: dts: qcom: qcs8550-rb5gen2: Add definition for three LEDs
+    - PENDING: arm64: dts: qcom: qcs8550-rb5gen2: Add definitions for flash leds
+    - PENDING: iommu/arm-smmu-qcom: Fix an empty list_head accessing
+    - PENDING: trece: buses: Change __assign_str to __assign_str_len
+    - PENDING: spi: spi-geni-qcom: add trace log support
+    - Revert "QCLINUX: arm64: configs: qcom_defconfig: Disable NVMEM_REBOOT_MODE"
+    - PENDING: i2c: i2c-qcom-geni: Add trace log support
+    - PENDING: arm64: dts: qcom: sm8550: add slimbus DT node
+    - PENDING: arm64: dts: qcm6490: Disable nvmem-reboot-mode
+    - QCLINUX: usb: dwc3: Initialize variable ret to 0
+    - QCLINUX: usb: dwc3: qcom: Take wakelock to block pm suspend in autosleep
+    - PENDING: soc: qcom: memory_dump: initialize initialized value
+    - PENDING: arm64: dts: qcom: qcs6490-rb3gen2: disable ipa node on qcs6490
+    - PENDING: arm64: dts: qcom: Enable PCIe1 on aim500
+    - QCLINUX: arm64: dts: qcom: Add support for qps615 switch
+    - QCLINUX: arm64: defconfig: Enable ARM64_VA=39
+    - PENDING: arm64: dts: qcom: qcs6490-rb3gen2: Modify DVT device USB2
+    - QCLINUX: virt: gunyah: Use kvcalloc for tracking large number of pages
+    - PENDING: firmware: Error handling in qcom_scm_prepare_ice_key
+    - PENDING: arm64: dts: qcom: sa8775p: Add UART node
+    - QCLINUX: arm64: dts: qcom: Rename regulators for QCM6490
+    - PENDING: power: supply: qcom_battmgr: Add support to configure USB ICL
+    - QCLINUX: soc: qcom: Don't assume that soc watchdog is enabled by default
+    - PENDING: arm64: dts: Add missing clkreq pin configuration
+    - PENDING: arm64: dts: qcom: sa8775p: Add GPI configuration
+    - QCLINUX: arm64: dts: qcom: Add board-id and msm-id for Rb3Gen2
+    - QCLINUX: arm64: defconfig: Add AQC107 config
+    - QCLINUX: usb: dwc3: qcom: Avoid PM Resume if device is RT suspended
+    - PENDING: Bluetooth: Increase settling time for baudrate change VSC
+    - PENDING: remoteproc: qcom: pas: Add SA8775p remoteproc support
+    - PENDING: arm64: dts: qcom: sa8775p: add ADSP and CDSP support
+    - QCLINUX: arm64: dts: qcom: sa8775p: add addons dts support for sa8775p
+    - PENDING: arm64: dts: qcom: sa8775p: enable CDSP for SA8775p
+    - PENDING: remoteproc: qcom: pas: Add SA8775p CDSP1 remoteproc support
+    - PENDING: arm64: dts: qcom: sa8775p: add CDSP1 support
+    - PENDING: arm64: dts: qcom: sa8775p: enable CDSP1 for SA8775p
+    - PENDING: dt-bindings: mailbox: qcom-ipcc: Add GPDSP0 and GPDSP1 client
+    - PENDING: remoteproc: qcom: pas: Add SA8775p GPDSP0 and GPDSP1 remoteproc
+      support
+    - PENDING: arm64: dts: qcom: sa8775p: add GPDSP0 and GPDSP1 support
+    - QCLINUX: arm64: defconfig: Enable STMMAC eth and Marvell phy config
+    - PENDING: uapi: add userspace interface file to uapi
+    - PENDING: soc: qcom: llcc: add llcc config support for SA8775p platform
+    - PENDING: arm64: dts: qcom: sa8775p: Add llcc support for SA8775p platform
+    - PENDING: arm64: dts: qcom: sa8775p-ride: Enable llcc function
+    - QCLINUX: arm64: defconfig: qcom: Enable i3c support
+    - PENDING: soc: qcom: smem: Add boundary checks for partitions
+    - PENDING: crypto: qce - Fetch interconnect bandwidth value from dtsi
+    - PENDING: arm64: dts: qcom: sc7280: Define interconnect bandwidth value in
+      dtsi
+    - QCLINUX: rpmsg: glink: replace deprecated 'strcpy' with 'strscpy'
+    - QCLINUX: arm64: defconfig: enable configs required for kubernetes
+    - PENDING: slimbus: ngd: Add check before memory free
+    - QCLINUX: arm64: dts: qcom: sa8775p: add dma-buf heaps
+    - QCLINUX: arm64: dts: qcom: sa8775p: add secure buffer device
+    - QCLINUX: arm64: dts: qcom: sa8775p: add mem-buf device
+    - QCLINUX: arm64: dts: qcm6490-addons: Update memory dump table
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add gunyah watchdog support
+    - PENDING: pcie: Save & restore configuration space for qps615
+    - QCLINUX: thermal: qcom: Add support to update tsens trip based on nvmem data
+    - PENDING: arm64: dts: qcom: sa8775p: Add IMEM and PIL info region
+    - QCLINUX: arm64: dts: qcom: sa8775p: define kaslr offset and mem dump table
+      regions
+    - QCLINUX: arm64: dts: qcom: sa8775p-ride: Add board-id and msm-id support
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add shmbridge and smcinvoke nodes
+    - FROMLIST: arm64: dts: qcom: qcm8550: introduce qcs8550 dtsi
+    - PENDING: arm64: qcom: dts: qcs8550: Update included dtsi name for rb5gen2
+    - QCLINUX: arm64: dts: qcom: qcs8550: update qcs8550 addons dtsi file name
+    - PENDING: arm64: dts: qcom: sa8775p: enable ADSP and GPDSP for SA8775p
+    - PENDING: USB: pci-quirks: skip usb_early_handoff for Renesas PCI USB
+    - PENDING: coresight-tmc-etf: fix failure to disable/enable ETF after reading
+    - QCLINUX: PCI: qcom: Enable powering up upd controller
+    - QCLINUX: ASoC: qcm6490: Update channel slot number for slimbus codec dai
+    - PENDING: arm64: dts: qcom: aim500: Add more reserved gpio pins
+    - PENDING: soc: qcom: ice: Handle ice probe return
+    - PENDING: usb: dwc3: core: Handle failure of get sync during cable disconnect
+    - PENDING: arm64: dts: qcom: sa8775p: Enable smp2p-sleepstate
+    - QCLINUX: clk: qcom: gcc-sa8775p: Remove the HW control clocks on SA8775P
+    - PENDING: iris: Disable slice mode for VBR rate control
+    - PENDING: usb: dwc3: qcom: Introduce post-connection done vendor hook
+    - PENDING: misc: fastrpc: Add support for cdsp1 remoteproc
+    - QCLINUX: arm64: dts: qcom: Enable tsens dynamic trip update for qcm6490
+    - PENDING: crypto: qce - Bam crash during suspend-shutdown scenario
+    - PENDING: arm64: dts: qcom: sa8775p-ride: add Bluetooth support
+    - PENDING: arm64: dts: qcom: sa8775p: add CDSP1 fastrpc-compute-cb nodes
+    - PENDING: dt-bindings: clock: qcom: Add SA8775P video clock controller
+    - PENDING: clk: qcom: Add support for Video clock controller on SA8775P
+    - PENDING: dt-bindings: clock: qcom: Add SA8775P camera controller
+    - PENDING: clk: qcom: Add support for Camera Clock Controller on SA8775P
+    - PENDING: dt-bindings: clock: qcom: Add SA8775P display controller
+    - PENDING: clk: qcom: Add support for Display Controllers on SA8775P
+    - PENDING: clk: qcom: Remove the CLK_IS_CRITICAL flag for SA8775P
+    - QCLINUX: arm64: defconfig: enable Clock controllers SA8775P
+    - PENDING: arm64: dts: qcom: sa8775p: add clock controllers support
+    - QCLINUX: arm64: dts: qcs5430-rb3: Enable PCIE1
+    - FROMLIST: PCI: hold the rescan mutex when scanning for the first time
+    - FROMLIST: PCI/pwrctl: reuse the OF node for power controlled devices
+    - FROMLIST: PCI/pwrctl: create platform devices for child OF nodes of the port
+      node
+    - FROMLIST: PCI/pwrctl: add PCI power control core code
+    - FROMLIST: power: sequencing: implement the pwrseq core
+    - FROMLIST: power: pwrseq: add a driver for the PMU module on the QCom WCN
+      chipsets
+    - FROMLIST: PCI/pwrctl: add a PCI power control driver for power sequenced
+      devices
+    - PENDING: PCI/pwrctl: enable power control for WCN6855
+    - PENDING: power: pwrseq: add WCN6855 PMU support
+    - PENDING: arm64: dts: qcom: sa8775p-ride: add pmu node for WCN6855
+    - PENDING: Bluetooth: hci_qca: Drop unused event during BT on
+    - config: enable PCA953x PCA954x and ANX7625 driver
+    - PENDING: drm/bridge: anx7625: Fix circular dependency
+    - PENDING: iris: devicetree: remove iommu and video enc dec nodes
+    - PENDING: videocc: remove HW_CTRL from mvs0 gdsc
+    - PENDING: interconnect: qcom: sa8775p: enable qos programming
+    - PENDING: arm64: dts: qcom: sa8775p: Add reg field & clocks to program QoS
+    - PENDING: arm64: dts: qcom: Add SD Card node for qcm6490-rb3
+    - QCLINUX: arm64: dts: qcom: qcs6490: Add PCIe bridge and endpoint nodes
+    - QCLINUX: arm64: dts: qcom:Add QPS615 and PHY devicestree config
+    - QCLINUX: arm64: configs: qcom_defconfig: Enable NVMEM_REBOOT_MODE
+    - QCLINUX: arm64: defconfig: qcom: Disable ASPM
+    - PENDING: usb: dwc3: qcom: Check if driver is resumed before reg access
+    - PENDING: arm64: dts: qcom: sa8775p-ride: Change swctrl-gpios in BT
+    - PENDING: arm64: dts: qcom: sa8775p-pmics: enable rtc
+    - QCLINUX: arm64: dts: qcom: sa8775p-addons: Add CMA heap
+    - QCLINUX: arm64: defconfig: Enable vsock support
+    - QCLINUX: arm64: defconfig: Host kernel accelerator for virtio net
+    - QCLINUX: arm64: defconfig: Enable required virtio configs for VM
+    - QCLINUX: arm64: defconfig: Enable watchdog drivers for VM
+    - FROMLIST: drivers: qcom: icc-bwmon: Change zone1_thres_count to 3
+    - PENDING: crypto: qce - remove return values from qce_crypto_probe()
+    - thermal: re-add thermal_zone_set_trip()
+    - thermal: tsens: remove use of thermal_zone_device_exec()
+    - Revert "net: phylink: remove .validate() method"
+    - Ubuntu [Config] update configs for GA 1.1
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Tue, 23 Jul 2024 17:25:21 +0900
+
+linux-qcom (6.8.0-1005.5) jammy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] drop getabis data
+
+  * [RB3] Kernel back trace while audio play
+    - Revert "ASoC: qcom: Move Soundwire runtime stream alloc to soundcards"
+
+  * [qcom alpha] Suppress noisy logs
+    - SAUCE: ubuntu/qcom/wlan: supress noisy logs (take 2)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: qcom/bt: support uevent module loading
+    - SAUCE: qcom/bt: add sentinel to MODULE_DEVICE_TABLE()
+
+  [ Ubuntu: 6.8.0-38.38 ]
+
+  * noble/linux: 6.8.0-38.38 -proposed tracker (LP: #2068318)
+  * race_sched in ubuntu_stress_smoke_test will cause kernel panic on 6.8 with
+    Azure Standard_A2_v2 instance (LP: #2068024)
+    - sched/eevdf: Prevent vlag from going out of bounds in reweight_eevdf()
+  * Noble: btrfs: re-introduce 'norecovery' mount option (LP: #2068591)
+    - btrfs: re-introduce 'norecovery' mount option
+  * Fix system hang while entering suspend with AMD Navi3x graphics
+    (LP: #2063417)
+    - drm/amdgpu/mes: fix use-after-free issue
+  * Noble update: v6.8.8 upstream stable release (LP: #2068087)
+    - io_uring: Fix io_cqring_wait() not restoring sigmask on get_timespec64()
+      failure
+    - drm/i915/cdclk: Fix voltage_level programming edge case
+    - Revert "vmgenid: emit uevent when VMGENID updates"
+    - SUNRPC: Fix rpcgss_context trace event acceptor field
+    - selftests/ftrace: Limit length in subsystem-enable tests
+    - random: handle creditable entropy from atomic process context
+    - scsi: core: Fix handling of SCMD_FAIL_IF_RECOVERING
+    - net: usb: ax88179_178a: avoid writing the mac address before first reading
+    - btrfs: do not wait for short bulk allocation
+    - btrfs: zoned: do not flag ZEROOUT on non-dirty extent buffer
+    - r8169: fix LED-related deadlock on module removal
+    - r8169: add missing conditional compiling for call to r8169_remove_leds
+    - scsi: ufs: qcom: Add missing interconnect bandwidth values for Gear 5
+    - netfilter: nf_tables: Fix potential data-race in __nft_expr_type_get()
+    - netfilter: nf_tables: Fix potential data-race in __nft_obj_type_get()
+    - netfilter: br_netfilter: skip conntrack input hook for promisc packets
+    - netfilter: nft_set_pipapo: constify lookup fn args where possible
+    - netfilter: nft_set_pipapo: walk over current view on netlink dump
+    - netfilter: flowtable: validate pppoe header
+    - netfilter: flowtable: incorrect pppoe tuple
+    - af_unix: Call manage_oob() for every skb in unix_stream_read_generic().
+    - af_unix: Don't peek OOB data without MSG_OOB.
+    - net: sparx5: flower: fix fragment flags handling
+    - net/mlx5: Lag, restore buckets number to default after hash LAG deactivation
+    - net/mlx5: Restore mistakenly dropped parts in register devlink flow
+    - net/mlx5e: Prevent deadlock while disabling aRFS
+    - net: change maximum number of UDP segments to 128
+    - octeontx2-pf: fix FLOW_DIS_IS_FRAGMENT implementation
+    - selftests/tcp_ao: Make RST tests less flaky
+    - selftests/tcp_ao: Zero-init tcp_ao_info_opt
+    - selftests/tcp_ao: Fix fscanf() call for format-security
+    - selftests/tcp_ao: Printing fixes to confirm with format-security
+    - net: stmmac: Apply half-duplex-less constraint for DW QoS Eth only
+    - net: stmmac: Fix max-speed being ignored on queue re-init
+    - net: stmmac: Fix IP-cores specific MAC capabilities
+    - ice: tc: check src_vsi in case of traffic from VF
+    - ice: tc: allow zero flags in parsing tc flower
+    - ice: Fix checking for unsupported keys on non-tunnel device
+    - tun: limit printing rate when illegal packet received by tun dev
+    - net: dsa: mt7530: fix mirroring frames received on local port
+    - net: dsa: mt7530: fix port mirroring for MT7988 SoC switch
+    - s390/ism: Properly fix receive message buffer allocation
+    - netfilter: nf_tables: missing iterator type in lookup walk
+    - netfilter: nf_tables: restore set elements when delete set fails
+    - gpiolib: swnode: Remove wrong header inclusion
+    - netfilter: nf_tables: fix memleak in map from abort path
+    - net/sched: Fix mirred deadlock on device recursion
+    - net: ethernet: mtk_eth_soc: fix WED + wifi reset
+    - ravb: Group descriptor types used in Rx ring
+    - net: ravb: Count packets instead of descriptors in R-Car RX path
+    - net: ravb: Allow RX loop to move past DMA mapping errors
+    - net: ethernet: ti: am65-cpsw-nuss: cleanup DMA Channels before using them
+    - NFSD: fix endianness issue in nfsd4_encode_fattr4
+    - RDMA/rxe: Fix the problem "mutex_destroy missing"
+    - RDMA/cm: Print the old state when cm_destroy_id gets timeout
+    - RDMA/mlx5: Fix port number for counter query in multi-port configuration
+    - perf annotate: Make sure to call symbol__annotate2() in TUI
+    - perf lock contention: Add a missing NULL check
+    - s390/qdio: handle deferred cc1
+    - s390/cio: fix race condition during online processing
+    - iommufd: Add missing IOMMUFD_DRIVER kconfig for the selftest
+    - iommufd: Add config needed for iommufd_fail_nth
+    - drm: nv04: Fix out of bounds access
+    - drm/v3d: Don't increment `enabled_ns` twice
+    - userfaultfd: change src_folio after ensuring it's unpinned in UFFDIO_MOVE
+    - thunderbolt: Introduce tb_port_reset()
+    - thunderbolt: Introduce tb_path_deactivate_hop()
+    - thunderbolt: Make tb_switch_reset() support Thunderbolt 2, 3 and USB4
+      routers
+    - thunderbolt: Reset topology created by the boot firmware
+    - drm/panel: visionox-rm69299: don't unregister DSI device
+    - drm/radeon: make -fstrict-flex-arrays=3 happy
+    - ALSA: hda/realtek: Fix volumn control of ThinkBook 16P Gen4
+    - thermal/debugfs: Add missing count increment to thermal_debug_tz_trip_up()
+    - platform/x86/amd/pmc: Extend Framework 13 quirk to more BIOSes
+    - interconnect: qcom: x1e80100: Remove inexistent ACV_PERF BCM
+    - interconnect: Don't access req_list while it's being manipulated
+    - clk: Remove prepare_lock hold assertion in __clk_release()
+    - clk: Initialize struct clk_core kref earlier
+    - clk: Get runtime PM before walking tree during disable_unused
+    - clk: Get runtime PM before walking tree for clk_summary
+    - clk: mediatek: Do a runtime PM get on controllers during probe
+    - clk: mediatek: mt7988-infracfg: fix clocks for 2nd PCIe port
+    - selftests/powerpc/papr-vpd: Fix missing variable initialization
+    - x86/bugs: Fix BHI retpoline check
+    - x86/cpufeatures: Fix dependencies for GFNI, VAES, and VPCLMULQDQ
+    - block: propagate partition scanning errors to the BLKRRPART ioctl
+    - net/mlx5: E-switch, store eswitch pointer before registering devlink_param
+    - ALSA: seq: ump: Fix conversion from MIDI2 to MIDI1 UMP messages
+    - ALSA: hda/tas2781: correct the register for pow calibrated data
+    - ALSA: hda/realtek: Add quirks for Huawei Matebook D14 NBLB-WAX9N
+    - ALSA: hda/realtek - Enable audio jacks of Haier Boyue G42 with ALC269VC
+    - usb: misc: onboard_usb_hub: Disable the USB hub clock on failure
+    - misc: rtsx: Fix rts5264 driver status incorrect when card removed
+    - thunderbolt: Avoid notify PM core about runtime PM resume
+    - thunderbolt: Fix wake configurations after device unplug
+    - thunderbolt: Do not create DisplayPort tunnels on adapters of the same
+      router
+    - comedi: vmk80xx: fix incomplete endpoint checking
+    - serial: mxs-auart: add spinlock around changing cts state
+    - serial/pmac_zilog: Remove flawed mitigation for rx irq flood
+    - serial: 8250_dw: Revert: Do not reclock if already at correct rate
+    - serial: stm32: Return IRQ_NONE in the ISR if no handling happend
+    - serial: stm32: Reset .throttled state in .startup()
+    - serial: core: Fix regression when runtime PM is not enabled
+    - serial: core: Clearing the circular buffer before NULLifying it
+    - serial: core: Fix missing shutdown and startup for serial base port
+    - USB: serial: option: add Fibocom FM135-GL variants
+    - USB: serial: option: add support for Fibocom FM650/FG650
+    - USB: serial: option: add Lonsung U8300/U9300 product
+    - USB: serial: option: support Quectel EM060K sub-models
+    - USB: serial: option: add Rolling RW101-GL and RW135-GL support
+    - USB: serial: option: add Telit FN920C04 rmnet compositions
+    - Revert "usb: cdc-wdm: close race between read and workqueue"
+    - usb: dwc2: host: Fix dereference issue in DDMA completion flow.
+    - usb: Disable USB3 LPM at shutdown
+    - usb: gadget: f_ncm: Fix UAF ncm object at re-bind after usb ep transport
+      error
+    - usb: typec: tcpm: Correct the PDO counting in pd_set
+    - mei: me: disable RPL-S on SPS and IGN firmwares
+    - speakup: Avoid crash on very long word
+    - fs: sysfs: Fix reference leak in sysfs_break_active_protection()
+    - sched: Add missing memory barrier in switch_mm_cid
+    - KVM: x86: Snapshot if a vCPU's vendor model is AMD vs. Intel compatible
+    - KVM: x86/pmu: Disable support for adaptive PEBS
+    - KVM: x86/pmu: Do not mask LVTPC when handling a PMI on AMD platforms
+    - KVM: x86/mmu: x86: Don't overflow lpage_info when checking attributes
+    - KVM: x86/mmu: Write-protect L2 SPTEs in TDP MMU when clearing dirty status
+    - arm64/head: Disable MMU at EL2 before clearing HCR_EL2.E2H
+    - arm64: hibernate: Fix level3 translation fault in swsusp_save()
+    - init/main.c: Fix potential static_command_line memory overflow
+    - mm/madvise: make MADV_POPULATE_(READ|WRITE) handle VM_FAULT_RETRY properly
+    - mm/userfaultfd: allow hugetlb change protection upon poison entry
+    - mm,swapops: update check in is_pfn_swap_entry for hwpoison entries
+    - mm/memory-failure: fix deadlock when hugetlb_optimize_vmemmap is enabled
+    - mm/shmem: inline shmem_is_huge() for disabled transparent hugepages
+    - fuse: fix leaked ENOSYS error on first statx call
+    - drm/amdkfd: Fix memory leak in create_process failure
+    - drm/amdgpu: remove invalid resource->start check v2
+    - drm/ttm: stop pooling cached NUMA pages v2
+    - drm/xe: Fix bo leak in intel_fb_bo_framebuffer_init
+    - drm/vmwgfx: Fix prime import/export
+    - drm/vmwgfx: Sort primary plane formats by order of preference
+    - drm/vmwgfx: Fix crtc's atomic check conditional
+    - nouveau: fix instmem race condition around ptr stores
+    - bootconfig: use memblock_free_late to free xbc memory to buddy
+    - Squashfs: check the inode number is not the invalid value of zero
+    - nilfs2: fix OOB in nilfs_set_de_type
+    - fork: defer linking file vma until vma is fully initialized
+    - net: dsa: mt7530: fix improper frames on all 25MHz and 40MHz XTAL MT7530
+    - net: dsa: mt7530: fix enabling EEE on MT7531 switch on all boards
+    - ksmbd: fix slab-out-of-bounds in smb2_allocate_rsp_buf
+    - ksmbd: validate request buffer size in smb2_allocate_rsp_buf()
+    - ksmbd: clear RENAME_NOREPLACE before calling vfs_rename
+    - ksmbd: common: use struct_group_attr instead of struct_group for
+      network_open_info
+    - thunderbolt: Reset only non-USB4 host routers in resume
+    - Linux 6.8.8
+  * Fix inaudible HDMI/DP audio on USB-C MST dock (LP: #2064689)
+    - drm/i915/audio: Fix audio time stamp programming for DP
+  * Add Cirrus Logic CS35L56 amplifier support (LP: #2062135)
+    - ALSA: hda: realtek: Re-work CS35L41 fixups to re-use for other amps
+    - ALSA: hda/realtek: Add quirks for HP G11 Laptops using CS35L56
+  * net:fib_rule_tests.sh in ubuntu_kselftests_net fails on Noble (LP: #2066332)
+    - Revert "UBUNTU: SAUCE: selftests: net: fix "from" match test in
+      fib_rule_tests.sh"
+  * mtk_t7xx WWAN module fails to probe with: Invalid device status 0x1
+    (LP: #2049358)
+    - Revert "UBUNTU: SAUCE: net: wwan: t7xx: PCIe reset rescan"
+    - Revert "UBUNTU: SAUCE: net: wwan: t7xx: Add AP CLDMA"
+    - net: wwan: t7xx: Add AP CLDMA
+    - wwan: core: Add WWAN fastboot port type
+    - net: wwan: t7xx: Add sysfs attribute for device state machine
+    - net: wwan: t7xx: Infrastructure for early port configuration
+    - net: wwan: t7xx: Add fastboot WWAN port
+  * Pull-request to address TPM bypass issue (LP: #2037688)
+    - [Config]: Configure TPM drivers as builtins for arm64 in annotations
+  * re-enable Ubuntu FAN in the Noble kernel (LP: #2064508)
+    - SAUCE: fan: add VXLAN implementation
+    - SAUCE: fan: Fix NULL pointer dereference
+    - SAUCE: fan: support vxlan strict length validation
+  * update for V3 kernel bits and improved multiple fan slice support
+    (LP: #1470091) // re-enable Ubuntu FAN in the Noble kernel (LP: #2064508)
+    - SAUCE: fan: tunnel multiple mapping mode (v3)
+  * TCP memory  leak, slow network (arm64) (LP: #2045560)
+    - net: make SK_MEMORY_PCPU_RESERV tunable
+    - net: fix sk_memory_allocated_{add|sub} vs softirqs
+  * panel flickering after the i915.psr2 is enabled (LP: #2046315)
+    - drm/i915/alpm: Add ALPM register definitions
+    - drm/i915/psr: Add alpm_parameters struct
+    - drm/i915/alpm: Calculate ALPM Entry check
+    - drm/i915/alpm: Alpm aux wake configuration for lnl
+    - drm/i915/display: Make intel_dp_aux_fw_sync_len available for PSR code
+    - drm/i915/psr: Improve fast and IO wake lines calculation
+    - drm/i915/psr: Calculate IO wake and fast wake lines for DISPLAY_VER < 12
+    - drm/i915/display: Increase number of fast wake precharge pulses
+  * I2C HID device sometimes fails to initialize causing touchpad to not work
+    (LP: #2061040)
+    - HID: i2c-hid: Revert to await reset ACK before reading report descriptor
+  * Fix the RTL8852CE BT FW Crash based on SER false alarm (LP: #2060904)
+    - wifi: rtw89: disable txptctrl IMR to avoid flase alarm
+    - wifi: rtw89: pci: correct TX resource checking for PCI DMA channel of
+      firmware command
+  * [X13s] Fingerprint reader is not working (LP: #2065376)
+    - SAUCE: arm64: dts: qcom: sc8280xp: Add USB DWC3 Multiport controller
+    - SAUCE: arm64: dts: qcom: sc8280xp-x13s: enable USB MP and fingerprint reader
+  * Fix random HuC/GuC initialization failure of Intel i915 driver
+    (LP: #2061049)
+    - drm/i915/huc: Allow for very slow HuC loading
+  * Add support of TAS2781 amp of audio (LP: #2064064)
+    - ALSA: hda/tas2781: Add new vendor_id and subsystem_id to support ThinkPad
+      ICE-1
+  * Noble update: v6.8.7 upstream stable release (LP: #2065912)
+    - smb3: fix Open files on server counter going negative
+    - ata: libata-core: Allow command duration limits detection for ACS-4 drives
+    - ata: libata-scsi: Fix ata_scsi_dev_rescan() error path
+    - drm/amdgpu/vpe: power on vpe when hw_init
+    - batman-adv: Avoid infinite loop trying to resize local TT
+    - ceph: redirty page before returning AOP_WRITEPAGE_ACTIVATE
+    - ceph: switch to use cap_delay_lock for the unlink delay list
+    - virtio_net: Do not send RSS key if it is not supported
+    - arm64: tlb: Fix TLBI RANGE operand
+    - ARM: dts: imx7s-warp: Pass OV2680 link-frequencies
+    - raid1: fix use-after-free for original bio in raid1_write_request()
+    - ring-buffer: Only update pages_touched when a new page is touched
+    - Bluetooth: Fix memory leak in hci_req_sync_complete()
+    - drm/amd/pm: fixes a random hang in S4 for SMU v13.0.4/11
+    - platform/chrome: cros_ec_uart: properly fix race condition
+    - ACPI: scan: Do not increase dep_unmet for already met dependencies
+    - PM: s2idle: Make sure CPUs will wakeup directly on resume
+    - media: cec: core: remove length check of Timer Status
+    - btrfs: tests: allocate dummy fs_info and root in test_find_delalloc()
+    - ARM: OMAP2+: fix bogus MMC GPIO labels on Nokia N8x0
+    - ARM: OMAP2+: fix N810 MMC gpiod table
+    - mmc: omap: fix broken slot switch lookup
+    - mmc: omap: fix deferred probe
+    - mmc: omap: restore original power up/down steps
+    - ARM: OMAP2+: fix USB regression on Nokia N8x0
+    - firmware: arm_ffa: Fix the partition ID check in ffa_notification_info_get()
+    - firmware: arm_scmi: Make raw debugfs entries non-seekable
+    - cxl/mem: Fix for the index of Clear Event Record Handle
+    - cxl/core/regs: Fix usage of map->reg_type in cxl_decode_regblock() before
+      assigned
+    - arm64: dts: freescale: imx8mp-venice-gw72xx-2x: fix USB vbus regulator
+    - arm64: dts: freescale: imx8mp-venice-gw73xx-2x: fix USB vbus regulator
+    - drm/msm: Add newlines to some debug prints
+    - drm/msm/dpu: don't allow overriding data from catalog
+    - drm/msm/dpu: make error messages at dpu_core_irq_register_callback() more
+      sensible
+    - dt-bindings: display/msm: sm8150-mdss: add DP node
+    - arm64: dts: imx8-ss-conn: fix usdhc wrong lpcg clock order
+    - cxl/core: Fix initialization of mbox_cmd.size_out in get event
+    - Revert "drm/qxl: simplify qxl_fence_wait"
+    - nouveau: fix function cast warning
+    - drm/msm/adreno: Set highest_bank_bit for A619
+    - scsi: hisi_sas: Modify the deadline for ata_wait_after_reset()
+    - scsi: qla2xxx: Fix off by one in qla_edif_app_getstats()
+    - net: openvswitch: fix unwanted error log on timeout policy probing
+    - u64_stats: fix u64_stats_init() for lockdep when used repeatedly in one file
+    - xsk: validate user input for XDP_{UMEM|COMPLETION}_FILL_RING
+    - octeontx2-pf: Fix transmit scheduler resource leak
+    - block: fix q->blkg_list corruption during disk rebind
+    - lib: checksum: hide unused expected_csum_ipv6_magic[]
+    - geneve: fix header validation in geneve[6]_xmit_skb
+    - s390/ism: fix receive message buffer allocation
+    - bnxt_en: Fix possible memory leak in bnxt_rdma_aux_device_init()
+    - bnxt_en: Fix error recovery for RoCE ulp client
+    - bnxt_en: Reset PTP tx_avail after possible firmware reset
+    - ACPI: bus: allow _UID matching for integer zero
+    - base/node / ACPI: Enumerate node access class for 'struct access_coordinate'
+    - ACPI: HMAT: Introduce 2 levels of generic port access class
+    - ACPI: HMAT / cxl: Add retrieval of generic port coordinates for both access
+      classes
+    - cxl: Split out combine_coordinates() for common shared usage
+    - cxl: Split out host bridge access coordinates
+    - cxl: Remove checking of iter in cxl_endpoint_get_perf_coordinates()
+    - cxl: Fix retrieving of access_coordinates in PCIe path
+    - net: ks8851: Inline ks8851_rx_skb()
+    - net: ks8851: Handle softirqs at the end of IRQ thread to fix hang
+    - af_unix: Clear stale u->oob_skb.
+    - octeontx2-af: Fix NIX SQ mode and BP config
+    - ipv6: fib: hide unused 'pn' variable
+    - ipv4/route: avoid unused-but-set-variable warning
+    - ipv6: fix race condition between ipv6_get_ifaddr and ipv6_del_addr
+    - pds_core: use pci_reset_function for health reset
+    - pds_core: Fix pdsc_check_pci_health function to use work thread
+    - Bluetooth: ISO: Align broadcast sync_timeout with connection timeout
+    - Bluetooth: ISO: Don't reject BT_ISO_QOS if parameters are unset
+    - Bluetooth: hci_sync: Use QoS to determine which PHY to scan
+    - Bluetooth: hci_sync: Fix using the same interval and window for Coded PHY
+    - Bluetooth: SCO: Fix not validating setsockopt user input
+    - Bluetooth: RFCOMM: Fix not validating setsockopt user input
+    - Bluetooth: L2CAP: Fix not validating setsockopt user input
+    - Bluetooth: ISO: Fix not validating setsockopt user input
+    - Bluetooth: hci_sock: Fix not validating setsockopt user input
+    - Bluetooth: l2cap: Don't double set the HCI_CONN_MGMT_CONNECTED bit
+    - netfilter: complete validation of user input
+    - net/mlx5: SF, Stop waiting for FW as teardown was called
+    - net/mlx5: Register devlink first under devlink lock
+    - net/mlx5: offset comp irq index in name by one
+    - net/mlx5: Properly link new fs rules into the tree
+    - net/mlx5: Correctly compare pkt reformat ids
+    - net/mlx5e: RSS, Block changing channels number when RXFH is configured
+    - net/mlx5e: Fix mlx5e_priv_init() cleanup flow
+    - net/mlx5e: HTB, Fix inconsistencies with QoS SQs number
+    - net/mlx5e: Do not produce metadata freelist entries in Tx port ts WQE xmit
+    - net: sparx5: fix wrong config being used when reconfiguring PCS
+    - Revert "s390/ism: fix receive message buffer allocation"
+    - net: dsa: mt7530: trap link-local frames regardless of ST Port State
+    - af_unix: Do not use atomic ops for unix_sk(sk)->inflight.
+    - af_unix: Fix garbage collector racing against connect()
+    - net: ena: Fix potential sign extension issue
+    - net: ena: Wrong missing IO completions check order
+    - net: ena: Fix incorrect descriptor free behavior
+    - net: ena: Set tx_info->xdpf value to NULL
+    - drm/xe/display: Fix double mutex initialization
+    - drm/xe/hwmon: Cast result to output precision on left shift of operand
+    - tracing: hide unused ftrace_event_id_fops
+    - iommu/vt-d: Fix wrong use of pasid config
+    - iommu/vt-d: Allocate local memory for page request queue
+    - iommu/vt-d: Fix WARN_ON in iommu probe path
+    - io_uring: refactor DEFER_TASKRUN multishot checks
+    - io_uring: disable io-wq execution of multishot NOWAIT requests
+    - btrfs: qgroup: correctly model root qgroup rsv in convert
+    - btrfs: qgroup: fix qgroup prealloc rsv leak in subvolume operations
+    - btrfs: record delayed inode root in transaction
+    - btrfs: qgroup: convert PREALLOC to PERTRANS after record_root_in_trans
+    - io_uring/net: restore msg_control on sendzc retry
+    - kprobes: Fix possible use-after-free issue on kprobe registration
+    - fs/proc: remove redundant comments from /proc/bootconfig
+    - fs/proc: Skip bootloader comment if no embedded kernel parameters
+    - scsi: sg: Avoid sg device teardown race
+    - scsi: sg: Avoid race in error handling & drop bogus warn
+    - accel/ivpu: Check return code of ipc->lock init
+    - accel/ivpu: Fix PCI D0 state entry in resume
+    - accel/ivpu: Put NPU back to D3hot after failed resume
+    - accel/ivpu: Return max freq for DRM_IVPU_PARAM_CORE_CLOCK_RATE
+    - accel/ivpu: Fix deadlock in context_xa
+    - drm/vmwgfx: Enable DMA mappings with SEV
+    - drm/i915/vrr: Disable VRR when using bigjoiner
+    - drm/amdkfd: Reset GPU on queue preemption failure
+    - drm/ast: Fix soft lockup
+    - drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr()
+    - drm/client: Fully protect modes[] with dev->mode_config.mutex
+    - drm/msm/dp: fix runtime PM leak on disconnect
+    - drm/msm/dp: fix runtime PM leak on connect failure
+    - drm/amdgpu/umsch: reinitialize write pointer in hw init
+    - arm64: dts: imx8qm-ss-dma: fix can lpcg indices
+    - arm64: dts: imx8-ss-dma: fix can lpcg indices
+    - arm64: dts: imx8-ss-dma: fix adc lpcg indices
+    - arm64: dts: imx8-ss-conn: fix usb lpcg indices
+    - arm64: dts: imx8-ss-dma: fix pwm lpcg indices
+    - arm64: dts: imx8-ss-lsio: fix pwm lpcg indices
+    - arm64: dts: imx8-ss-dma: fix spi lpcg indices
+    - vhost: Add smp_rmb() in vhost_vq_avail_empty()
+    - vhost: Add smp_rmb() in vhost_enable_notify()
+    - perf/x86: Fix out of range data
+    - x86/cpu: Actually turn off mitigations by default for
+      SPECULATION_MITIGATIONS=n
+    - selftests/timers/posix_timers: Reimplement check_timer_distribution()
+    - selftests: timers: Fix posix_timers ksft_print_msg() warning
+    - selftests: timers: Fix abs() warning in posix_timers test
+    - selftests: kselftest: Mark functions that unconditionally call exit() as
+      __noreturn
+    - x86/apic: Force native_apic_mem_read() to use the MOV instruction
+    - irqflags: Explicitly ignore lockdep_hrtimer_exit() argument
+    - selftests: kselftest: Fix build failure with NOLIBC
+    - kernfs: annotate different lockdep class for of->mutex of writable files
+    - x86/bugs: Fix return type of spectre_bhi_state()
+    - x86/bugs: Fix BHI documentation
+    - x86/bugs: Cache the value of MSR_IA32_ARCH_CAPABILITIES
+    - x86/bugs: Rename various 'ia32_cap' variables to 'x86_arch_cap_msr'
+    - x86/bugs: Fix BHI handling of RRSBA
+    - x86/bugs: Clarify that syscall hardening isn't a BHI mitigation
+    - x86/bugs: Remove CONFIG_BHI_MITIGATION_AUTO and spectre_bhi=auto
+    - [Config] updateconfigs to remove obsolete SPECTRE_BHI_AUTO
+    - x86/bugs: Replace CONFIG_SPECTRE_BHI_{ON,OFF} with
+      CONFIG_MITIGATION_SPECTRE_BHI
+    - [Config] updateconfigs to enable new MITIGATION_SPECTRE_BHI
+    - drm/i915/cdclk: Fix CDCLK programming order when pipes are active
+    - drm/i915/psr: Disable PSR when bigjoiner is used
+    - drm/i915: Disable port sync when bigjoiner is used
+    - drm/i915: Disable live M/N updates when using bigjoiner
+    - drm/amdgpu: Reset dGPU if suspend got aborted
+    - drm/amdgpu: always force full reset for SOC21
+    - drm/amdgpu: fix incorrect number of active RBs for gfx11
+    - drm/amdgpu: differentiate external rev id for gfx 11.5.0
+    - drm/amd/display: Program VSC SDP colorimetry for all DP sinks >= 1.4
+    - drm/amd/display: Set VSC SDP Colorimetry same way for MST and SST
+    - drm/amd/display: Do not recursively call manual trigger programming
+    - drm/amd/display: Return max resolution supported by DWB
+    - drm/amd/display: always reset ODM mode in context when adding first plane
+    - drm/amd/display: fix disable otg wa logic in DCN316
+    - Linux 6.8.7
+  * Noble update: v6.8.6 upstream stable release (LP: #2065899)
+    - amdkfd: use calloc instead of kzalloc to avoid integer overflow
+    - wifi: ath9k: fix LNA selection in ath_ant_try_scan()
+    - wifi: rtw89: fix null pointer access when abort scan
+    - bnx2x: Fix firmware version string character counts
+    - net: stmmac: dwmac-starfive: Add support for JH7100 SoC
+    - net: phy: phy_device: Prevent nullptr exceptions on ISR
+    - wifi: rtw89: pci: validate RX tag for RXQ and RPQ
+    - wifi: rtw89: pci: enlarge RX DMA buffer to consider size of RX descriptor
+    - VMCI: Fix memcpy() run-time warning in dg_dispatch_as_host()
+    - wifi: iwlwifi: pcie: Add the PCI device id for new hardware
+    - arm64: dts: qcom: qcm6490-idp: Add definition for three LEDs
+    - net: dsa: qca8k: put MDIO controller OF node if unavailable
+    - arm64: dts: qcom: qrb2210-rb1: disable cluster power domains
+    - printk: For @suppress_panic_printk check for other CPU in panic
+    - panic: Flush kernel log buffer at the end
+    - dump_stack: Do not get cpu_sync for panic CPU
+    - wifi: iwlwifi: pcie: Add new PCI device id and CNVI
+    - cpuidle: Avoid potential overflow in integer multiplication
+    - ARM: dts: rockchip: fix rk3288 hdmi ports node
+    - ARM: dts: rockchip: fix rk322x hdmi ports node
+    - arm64: dts: rockchip: fix rk3328 hdmi ports node
+    - arm64: dts: rockchip: fix rk3399 hdmi ports node
+    - net: add netdev_lockdep_set_classes() to virtual drivers
+    - arm64: dts: qcom: qcs6490-rb3gen2: Declare GCC clocks protected
+    - pmdomain: ti: Add a null pointer check to the omap_prm_domain_init
+    - pmdomain: imx8mp-blk-ctrl: imx8mp_blk: Add fdcc clock to hdmimix domain
+    - ACPI: resource: Add IRQ override quirk for ASUS ExpertBook B2502FBA
+    - ionic: set adminq irq affinity
+    - net: skbuff: add overflow debug check to pull/push helpers
+    - firmware: tegra: bpmp: Return directly after a failed kzalloc() in
+      get_filename()
+    - wifi: brcmfmac: Add DMI nvram filename quirk for ACEPC W5 Pro
+    - wifi: mt76: mt7915: add locking for accessing mapped registers
+    - wifi: mt76: mt7996: disable AMSDU for non-data frames
+    - wifi: mt76: mt7996: add locking for accessing mapped registers
+    - ACPI: x86: Move acpi_quirk_skip_serdev_enumeration() out of
+      CONFIG_X86_ANDROID_TABLETS
+    - ACPI: x86: Add DELL0501 handling to acpi_quirk_skip_serdev_enumeration()
+    - pstore/zone: Add a null pointer check to the psz_kmsg_read
+    - tools/power x86_energy_perf_policy: Fix file leak in get_pkg_num()
+    - net: pcs: xpcs: Return EINVAL in the internal methods
+    - dma-direct: Leak pages on dma_set_decrypted() failure
+    - wifi: ath11k: decrease MHI channel buffer length to 8KB
+    - iommu/arm-smmu-v3: Hold arm_smmu_asid_lock during all of attach_dev
+    - cpufreq: Don't unregister cpufreq cooling on CPU hotplug
+    - overflow: Allow non-type arg to type_max() and type_min()
+    - wifi: iwlwifi: Add missing MODULE_FIRMWARE() for *.pnvm
+    - wifi: cfg80211: check A-MSDU format more carefully
+    - btrfs: handle chunk tree lookup error in btrfs_relocate_sys_chunks()
+    - btrfs: export: handle invalid inode or root reference in btrfs_get_parent()
+    - btrfs: send: handle path ref underflow in header iterate_inode_ref()
+    - ice: use relative VSI index for VFs instead of PF VSI number
+    - net/smc: reduce rtnl pressure in smc_pnet_create_pnetids_list()
+    - netdev: let netlink core handle -EMSGSIZE errors
+    - Bluetooth: btintel: Fix null ptr deref in btintel_read_version
+    - Bluetooth: btmtk: Add MODULE_FIRMWARE() for MT7922
+    - Bluetooth: Add new quirk for broken read key length on ATS2851
+    - drm/vc4: don't check if plane->state->fb == state->fb
+    - drm/ci: uprev mesa version: fix kdl commit fetch
+    - drm/amdgpu: Skip do PCI error slot reset during RAS recovery
+    - Input: synaptics-rmi4 - fail probing if memory allocation for "phys" fails
+    - drm: panel-orientation-quirks: Add quirk for GPD Win Mini
+    - ASoC: SOF: amd: Optimize quirk for Valve Galileo
+    - drm/ttm: return ENOSPC from ttm_bo_mem_space v3
+    - scsi: ufs: qcom: Avoid re-init quirk when gears match
+    - drm/amd/display: increased min_dcfclk_mhz and min_fclk_mhz
+    - pinctrl: renesas: checker: Limit cfg reg enum checks to provided IDs
+    - sysv: don't call sb_bread() with pointers_lock held
+    - scsi: lpfc: Fix possible memory leak in lpfc_rcv_padisc()
+    - drm/amd/display: Disable idle reallow as part of command/gpint execution
+    - isofs: handle CDs with bad root inode but good Joliet root directory
+    - ASoC: Intel: sof_rt5682: dmi quirk cleanup for mtl boards
+    - ASoC: Intel: common: DMI remap for rebranded Intel NUC M15 (LAPRC710)
+      laptops
+    - rcu/nocb: Fix WARN_ON_ONCE() in the rcu_nocb_bypass_lock()
+    - rcu-tasks: Repair RCU Tasks Trace quiescence check
+    - Julia Lawall reported this null pointer dereference, this should fix it.
+    - media: sta2x11: fix irq handler cast
+    - ALSA: firewire-lib: handle quirk to calculate payload quadlets as data block
+      counter
+    - drm/panel: simple: Add BOE BP082WX1-100 8.2" panel
+    - x86/vdso: Fix rethunk patching for vdso-image-{32,64}.o
+    - ASoC: Intel: avs: Populate board selection with new I2S entries
+    - ext4: add a hint for block bitmap corrupt state in mb_groups
+    - ext4: forbid commit inconsistent quota data when errors=remount-ro
+    - drm/amd/display: Fix nanosec stat overflow
+    - accel/habanalabs: increase HL_MAX_STR to 64 bytes to avoid warnings
+    - i2c: designware: Fix RX FIFO depth define on Wangxun 10Gb NIC
+    - HID: input: avoid polling stylus battery on Chromebook Pompom
+    - drm/amd/amdgpu: Fix potential ioremap() memory leaks in amdgpu_device_init()
+    - drm: Check output polling initialized before disabling
+    - drm: Check polling initialized before enabling in
+      drm_helper_probe_single_connector_modes
+    - SUNRPC: increase size of rpc_wait_queue.qlen from unsigned short to unsigned
+      int
+    - PCI: Disable D3cold on Asus B1400 PCI-NVMe bridge
+    - Revert "ACPI: PM: Block ASUS B1400CEAE from suspend to idle by default"
+    - libperf evlist: Avoid out-of-bounds access
+    - crypto: iaa - Fix async_disable descriptor leak
+    - input/touchscreen: imagis: Correct the maximum touch area value
+    - drivers/perf: hisi: Enable HiSilicon Erratum 162700402 quirk for HIP09
+    - block: prevent division by zero in blk_rq_stat_sum()
+    - RDMA/cm: add timeout to cm_destroy_id wait
+    - Input: imagis - use FIELD_GET where applicable
+    - Input: allocate keycode for Display refresh rate toggle
+    - platform/x86: acer-wmi: Add support for Acer PH16-71
+    - platform/x86: acer-wmi: Add predator_v4 module parameter
+    - platform/x86: touchscreen_dmi: Add an extra entry for a variant of the Chuwi
+      Vi8 tablet
+    - perf/x86/amd/lbr: Discard erroneous branch entries
+    - ALSA: hda/realtek: Add quirk for Lenovo Yoga 9 14IMH9
+    - ktest: force $buildonly = 1 for 'make_warnings_file' test type
+    - Input: xpad - add support for Snakebyte GAMEPADs
+    - ring-buffer: use READ_ONCE() to read cpu_buffer->commit_page in concurrent
+      environment
+    - tools: iio: replace seekdir() in iio_generic_buffer
+    - bus: mhi: host: Add MHI_PM_SYS_ERR_FAIL state
+    - kernfs: RCU protect kernfs_nodes and avoid kernfs_idr_lock in
+      kernfs_find_and_get_node_by_id()
+    - usb: typec: ucsi: Add qcm6490-pmic-glink as needing PDOS quirk
+    - thunderbolt: Calculate DisplayPort tunnel bandwidth after DPRX capabilities
+      read
+    - usb: gadget: uvc: refactor the check for a valid buffer in the pump worker
+    - usb: gadget: uvc: mark incomplete frames with UVC_STREAM_ERR
+    - usb: typec: ucsi: Limit read size on v1.2
+    - serial: 8250_of: Drop quirk fot NPCM from 8250_port
+    - thunderbolt: Keep the domain powered when USB4 port is in redrive mode
+    - usb: typec: tcpci: add generic tcpci fallback compatible
+    - usb: sl811-hcd: only defined function checkdone if QUIRK2 is defined
+    - ASoC: amd: yc: Fix non-functional mic on ASUS M7600RE
+    - thermal/of: Assume polling-delay(-passive) 0 when absent
+    - ASoC: soc-core.c: Skip dummy codec when adding platforms
+    - x86/xen: attempt to inflate the memory balloon on PVH
+    - fbdev: viafb: fix typo in hw_bitblt_1 and hw_bitblt_2
+    - io_uring: clear opcode specific data for an early failure
+    - modpost: fix null pointer dereference
+    - drivers/nvme: Add quirks for device 126f:2262
+    - fbmon: prevent division by zero in fb_videomode_from_videomode()
+    - ALSA: hda/realtek: Add quirks for some Clevo laptops
+    - drm/amdgpu: Init zone device and drm client after mode-1 reset on reload
+    - gcc-plugins/stackleak: Avoid .head.text section
+    - media: mediatek: vcodec: Fix oops when HEVC init fails
+    - media: mediatek: vcodec: adding lock to protect decoder context list
+    - media: mediatek: vcodec: adding lock to protect encoder context list
+    - randomize_kstack: Improve entropy diffusion
+    - platform/x86/intel/hid: Don't wake on 5-button releases
+    - platform/x86: intel-vbtn: Update tablet mode switch at end of probe
+    - nouveau: fix devinit paths to only handle display on GSP.
+    - Bluetooth: btintel: Fixe build regression
+    - net: mpls: error out if inner headers are not set
+    - VMCI: Fix possible memcpy() run-time warning in
+      vmci_datagram_invoke_guest_handler()
+    - x86/vdso: Fix rethunk patching for vdso-image-x32.o too
+    - Revert "drm/amd/amdgpu: Fix potential ioremap() memory leaks in
+      amdgpu_device_init()"
+    - Linux 6.8.6
+  * Noble update: v6.8.5 upstream stable release (LP: #2065400)
+    - scripts/bpf_doc: Use silent mode when exec make cmd
+    - xsk: Don't assume metadata is always requested in TX completion
+    - s390/bpf: Fix bpf_plt pointer arithmetic
+    - bpf, arm64: fix bug in BPF_LDX_MEMSX
+    - dma-buf: Fix NULL pointer dereference in sanitycheck()
+    - arm64: bpf: fix 32bit unconditional bswap
+    - nfc: nci: Fix uninit-value in nci_dev_up and nci_ntf_packet
+    - nfsd: Fix error cleanup path in nfsd_rename()
+    - tools: ynl: fix setting presence bits in simple nests
+    - mlxbf_gige: stop PHY during open() error paths
+    - wifi: iwlwifi: mvm: pick the version of SESSION_PROTECTION_NOTIF
+    - wifi: iwlwifi: mvm: rfi: fix potential response leaks
+    - wifi: iwlwifi: mvm: include link ID when releasing frames
+    - ALSA: hda: cs35l56: Set the init_done flag before component_add()
+    - ice: Refactor FW data type and fix bitmap casting issue
+    - ice: fix memory corruption bug with suspend and rebuild
+    - ixgbe: avoid sleeping allocation in ixgbe_ipsec_vf_add_sa()
+    - igc: Remove stale comment about Tx timestamping
+    - drm/xe: Remove unused xe_bo->props struct
+    - drm/xe: Add exec_queue.sched_props.job_timeout_ms
+    - drm/xe/guc_submit: use jiffies for job timeout
+    - drm/xe/queue: fix engine_class bounds check
+    - drm/xe/device: fix XE_MAX_GT_PER_TILE check
+    - drm/xe/device: fix XE_MAX_TILES_PER_DEVICE check
+    - dpll: indent DPLL option type by a tab
+    - s390/qeth: handle deferred cc1
+    - net: hsr: hsr_slave: Fix the promiscuous mode in offload mode
+    - tcp: properly terminate timers for kernel sockets
+    - net: wwan: t7xx: Split 64bit accesses to fix alignment issues
+    - drm/rockchip: vop2: Remove AR30 and AB30 format support
+    - selftests: vxlan_mdb: Fix failures with old libnet
+    - gpiolib: Fix debug messaging in gpiod_find_and_request()
+    - ACPICA: debugger: check status of acpi_evaluate_object() in
+      acpi_db_walk_for_fields()
+    - net: hns3: fix index limit to support all queue stats
+    - net: hns3: fix kernel crash when devlink reload during pf initialization
+    - net: hns3: mark unexcuted loopback test result as UNEXECUTED
+    - tls: recv: process_rx_list shouldn't use an offset with kvec
+    - tls: adjust recv return with async crypto and failed copy to userspace
+    - tls: get psock ref after taking rxlock to avoid leak
+    - mlxbf_gige: call request_irq() after NAPI initialized
+    - drm/amd/display: Update P010 scaling cap
+    - drm/amd/display: Send DTBCLK disable message on first commit
+    - bpf: Protect against int overflow for stack access size
+    - cifs: Fix duplicate fscache cookie warnings
+    - netfilter: nf_tables: reject destroy command to remove basechain hooks
+    - netfilter: nf_tables: reject table flag and netdev basechain updates
+    - netfilter: nf_tables: skip netdev hook unregistration if table is dormant
+    - iommu: Validate the PASID in iommu_attach_device_pasid()
+    - net: bcmasp: Bring up unimac after PHY link up
+    - net: lan743x: Add set RFE read fifo threshold for PCI1x1x chips
+    - Octeontx2-af: fix pause frame configuration in GMP mode
+    - inet: inet_defrag: prevent sk release while still in use
+    - drm/i915: Stop doing double audio enable/disable on SDVO and g4x+ DP
+    - drm/i915/display: Disable AuxCCS framebuffers if built for Xe
+    - drm/i915/xelpg: Extend some workarounds/tuning to gfx version 12.74
+    - drm/i915/mtl: Update workaround 14018575942
+    - drm/i915: Do not print 'pxp init failed with 0' when it succeed
+    - dm integrity: fix out-of-range warning
+    - modpost: do not make find_tosym() return NULL
+    - kbuild: make -Woverride-init warnings more consistent
+    - mm/treewide: replace pud_large() with pud_leaf()
+    - Revert "x86/mm/ident_map: Use gbpages only where full GB page should be
+      mapped."
+    - gpio: cdev: sanitize the label before requesting the interrupt
+    - RISC-V: KVM: Fix APLIC setipnum_le/be write emulation
+    - RISC-V: KVM: Fix APLIC in_clrip[x] read emulation
+    - KVM: arm64: Fix host-programmed guest events in nVHE
+    - KVM: arm64: Fix out-of-IPA space translation fault handling
+    - selinux: avoid dereference of garbage after mount failure
+    - r8169: fix issue caused by buggy BIOS on certain boards with RTL8168d
+    - x86/cpufeatures: Add CPUID_LNX_5 to track recently added Linux-defined word
+    - x86/bpf: Fix IP after emitting call depth accounting
+    - Revert "Bluetooth: hci_qca: Set BDA quirk bit if fwnode exists in DT"
+    - arm64: dts: qcom: sc7180-trogdor: mark bluetooth address as broken
+    - Bluetooth: qca: fix device-address endianness
+    - Bluetooth: add quirk for broken address properties
+    - Bluetooth: hci_event: set the conn encrypted before conn establishes
+    - Bluetooth: Fix TOCTOU in HCI debugfs implementation
+    - netfilter: nf_tables: release batch on table validation from abort path
+    - netfilter: nf_tables: release mutex after nft_gc_seq_end from abort path
+    - selftests: mptcp: join: fix dev in check_endpoint
+    - net/rds: fix possible cp null dereference
+    - net: usb: ax88179_178a: avoid the interface always configured as random
+      address
+    - net: mana: Fix Rx DMA datasize and skb_over_panic
+    - vsock/virtio: fix packet delivery to tap device
+    - netfilter: nf_tables: reject new basechain after table flag update
+    - netfilter: nf_tables: flush pending destroy work before exit_net release
+    - netfilter: nf_tables: Fix potential data-race in __nft_flowtable_type_get()
+    - netfilter: nf_tables: discard table flag update with pending basechain
+      deletion
+    - netfilter: validate user input for expected length
+    - vboxsf: Avoid an spurious warning if load_nls_xxx() fails
+    - bpf, sockmap: Prevent lock inversion deadlock in map delete elem
+    - mptcp: prevent BPF accessing lowat from a subflow socket.
+    - x86/retpoline: Do the necessary fixup to the Zen3/4 srso return thunk for
+      !SRSO
+    - KVM: arm64: Use TLBI_TTL_UNKNOWN in __kvm_tlb_flush_vmid_range()
+    - KVM: arm64: Ensure target address is granule-aligned for range TLBI
+    - net/sched: act_skbmod: prevent kernel-infoleak
+    - net: dsa: sja1105: Fix parameters order in sja1110_pcs_mdio_write_c45()
+    - net/sched: fix lockdep splat in qdisc_tree_reduce_backlog()
+    - net: stmmac: fix rx queue priority assignment
+    - net: phy: micrel: lan8814: Fix when enabling/disabling 1-step timestamping
+    - net: txgbe: fix i2c dev name cannot match clkdev
+    - net: fec: Set mac_managed_pm during probe
+    - net: phy: micrel: Fix potential null pointer dereference
+    - net: dsa: mv88e6xxx: fix usable ports on 88e6020
+    - selftests: net: gro fwd: update vxlan GRO test expectations
+    - gro: fix ownership transfer
+    - idpf: fix kernel panic on unknown packet types
+    - ice: fix enabling RX VLAN filtering
+    - i40e: Fix VF MAC filter removal
+    - tcp: Fix bind() regression for v6-only wildcard and v4-mapped-v6 non-
+      wildcard addresses.
+    - erspan: make sure erspan_base_hdr is present in skb->head
+    - selftests: reuseaddr_conflict: add missing new line at the end of the output
+    - tcp: Fix bind() regression for v6-only wildcard and v4(-mapped-v6) non-
+      wildcard addresses.
+    - ax25: fix use-after-free bugs caused by ax25_ds_del_timer
+    - e1000e: Workaround for sporadic MDI error on Meteor Lake systems
+    - ipv6: Fix infinite recursion in fib6_dump_done().
+    - mlxbf_gige: stop interface during shutdown
+    - r8169: skip DASH fw status checks when DASH is disabled
+    - udp: do not accept non-tunnel GSO skbs landing in a tunnel
+    - udp: do not transition UDP GRO fraglist partial checksums to unnecessary
+    - udp: prevent local UDP tunnel packets from being GROed
+    - octeontx2-af: Fix issue with loading coalesced KPU profiles
+    - octeontx2-pf: check negative error code in otx2_open()
+    - octeontx2-af: Add array index check
+    - i40e: fix i40e_count_filters() to count only active/new filters
+    - i40e: fix vf may be used uninitialized in this function warning
+    - i40e: Enforce software interrupt during busy-poll exit
+    - drm/amd: Flush GFXOFF requests in prepare stage
+    - e1000e: Minor flow correction in e1000_shutdown function
+    - e1000e: move force SMBUS from enable ulp function to avoid PHY loss issue
+    - mean_and_variance: Drop always failing tests
+    - net: ravb: Let IP-specific receive function to interrogate descriptors
+    - net: ravb: Always process TX descriptor ring
+    - net: ravb: Always update error counters
+    - KVM: SVM: Use unsigned integers when dealing with ASIDs
+    - KVM: SVM: Add support for allowing zero SEV ASIDs
+    - selftests: mptcp: connect: fix shellcheck warnings
+    - selftests: mptcp: use += operator to append strings
+    - mptcp: don't account accept() of non-MPC client as fallback to TCP
+    - 9p: Fix read/write debug statements to report server reply
+    - ASoC: wm_adsp: Fix missing mutex_lock in wm_adsp_write_ctl()
+    - ASoC: cs42l43: Correct extraction of data pointer in suspend/resume
+    - riscv: mm: Fix prototype to avoid discarding const
+    - riscv: hwprobe: do not produce frtace relocation
+    - drivers/perf: riscv: Disable PERF_SAMPLE_BRANCH_* while not supported
+    - block: count BLK_OPEN_RESTRICT_WRITES openers
+    - RISC-V: Update AT_VECTOR_SIZE_ARCH for new AT_MINSIGSTKSZ
+    - ASoC: amd: acp: fix for acp pdm configuration check
+    - regmap: maple: Fix cache corruption in regcache_maple_drop()
+    - ALSA: hda: cs35l56: Add ACPI device match tables
+    - drm/panfrost: fix power transition timeout warnings
+    - nouveau/uvmm: fix addr/range calcs for remap operations
+    - drm/prime: Unbreak virtgpu dma-buf export
+    - ASoC: rt5682-sdw: fix locking sequence
+    - ASoC: rt711-sdca: fix locking sequence
+    - ASoC: rt711-sdw: fix locking sequence
+    - ASoC: rt712-sdca-sdw: fix locking sequence
+    - ASoC: rt722-sdca-sdw: fix locking sequence
+    - ASoC: ops: Fix wraparound for mask in snd_soc_get_volsw
+    - spi: s3c64xx: Extract FIFO depth calculation to a dedicated macro
+    - spi: s3c64xx: sort headers alphabetically
+    - spi: s3c64xx: explicitly include <linux/bits.h>
+    - spi: s3c64xx: remove else after return
+    - spi: s3c64xx: define a magic value
+    - spi: s3c64xx: allow full FIFO masks
+    - spi: s3c64xx: determine the fifo depth only once
+    - spi: s3c64xx: Use DMA mode from fifo size
+    - ASoC: amd: acp: fix for acp_init function error handling
+    - regmap: maple: Fix uninitialized symbol 'ret' warnings
+    - ata: sata_sx4: fix pdc20621_get_from_dimm() on 64-bit
+    - scsi: mylex: Fix sysfs buffer lengths
+    - scsi: sd: Unregister device if device_add_disk() failed in sd_probe()
+    - Revert "ALSA: emu10k1: fix synthesizer sample playback position and caching"
+    - drm/i915/dp: Fix DSC state HW readout for SST connectors
+    - cifs: Fix caching to try to do open O_WRONLY as rdwr on server
+    - spi: mchp-pci1xxx: Fix a possible null pointer dereference in
+      pci1xxx_spi_probe
+    - s390/pai: fix sampling event removal for PMU device driver
+    - thermal: gov_power_allocator: Allow binding without cooling devices
+    - thermal: gov_power_allocator: Allow binding without trip points
+    - drm/i915/gt: Limit the reserved VM space to only the platforms that need it
+    - ata: sata_mv: Fix PCI device ID table declaration compilation warning
+    - ASoC: SOF: amd: fix for false dsp interrupts
+    - SUNRPC: Fix a slow server-side memory leak with RPC-over-TCP
+    - riscv: use KERN_INFO in do_trap
+    - riscv: Fix warning by declaring arch_cpu_idle() as noinstr
+    - riscv: Disable preemption when using patch_map()
+    - nfsd: hold a lighter-weight client reference over CB_RECALL_ANY
+    - lib/stackdepot: move stack_record struct definition into the header
+    - stackdepot: rename pool_index to pool_index_plus_1
+    - x86/retpoline: Add NOENDBR annotation to the SRSO dummy return thunk
+    - Revert "drm/amd/display: Send DTBCLK disable message on first commit"
+    - gpio: cdev: check for NULL labels when sanitizing them for irqs
+    - gpio: cdev: fix missed label sanitizing in debounce_setup()
+    - ksmbd: don't send oplock break if rename fails
+    - ksmbd: validate payload size in ipc response
+    - ksmbd: do not set SMB2_GLOBAL_CAP_ENCRYPTION for SMB 3.1.1
+    - ALSA: hda: Add pplcllpl/u members to hdac_ext_stream
+    - ALSA: hda/realtek - Fix inactive headset mic jack
+    - ALSA: hda/realtek: Add sound quirks for Lenovo Legion slim 7 16ARHA7 models
+    - ALSA: hda/realtek: cs35l41: Support ASUS ROG G634JYR
+    - ALSA: hda/realtek: Update Panasonic CF-SZ6 quirk to support headset with
+      microphone
+    - io_uring/kbuf: get rid of lower BGID lists
+    - io_uring/kbuf: get rid of bl->is_ready
+    - io_uring/kbuf: protect io_buffer_list teardown with a reference
+    - io_uring/rw: don't allow multishot reads without NOWAIT support
+    - io_uring: use private workqueue for exit work
+    - io_uring/kbuf: hold io_buffer_list reference over mmap
+    - ASoC: SOF: Add dsp_max_burst_size_in_ms member to snd_sof_pcm_stream
+    - ASoC: SOF: ipc4-topology: Save the DMA maximum burst size for PCMs
+    - ASoC: SOF: Intel: hda-pcm: Use dsp_max_burst_size_in_ms to place constraint
+    - ASoC: SOF: Intel: hda: Implement get_stream_position (Linear Link Position)
+    - ASoC: SOF: Intel: mtl/lnl: Use the generic get_stream_position callback
+    - ASoC: SOF: Introduce a new callback pair to be used for PCM delay reporting
+    - ASoC: SOF: Intel: Set the dai/host get frame/byte counter callbacks
+    - ASoC: SOF: Intel: hda-common-ops: Do not set the get_stream_position
+      callback
+    - ASoC: SOF: ipc4-pcm: Use the snd_sof_pcm_get_dai_frame_counter() for
+      pcm_delay
+    - ASoC: SOF: Remove the get_stream_position callback
+    - ASoC: SOF: ipc4-pcm: Move struct sof_ipc4_timestamp_info definition locally
+    - ASoC: SOF: ipc4-pcm: Combine the SOF_IPC4_PIPE_PAUSED cases in pcm_trigger
+    - ASoC: SOF: ipc4-pcm: Invalidate the stream_start_offset in PAUSED state
+    - ASoC: SOF: sof-pcm: Add pointer callback to sof_ipc_pcm_ops
+    - ASoC: SOF: ipc4-pcm: Correct the delay calculation
+    - ASoC: SOF: Intel: hda: Compensate LLP in case it is not reset
+    - driver core: Introduce device_link_wait_removal()
+    - of: dynamic: Synchronize of_changeset_destroy() with the devlink removals
+    - of: module: prevent NULL pointer dereference in vsnprintf()
+    - x86/mm/pat: fix VM_PAT handling in COW mappings
+    - x86/mce: Make sure to grab mce_sysfs_mutex in set_bank()
+    - x86/coco: Require seeding RNG with RDRAND on CoCo systems
+    - perf/x86/intel/ds: Don't clear ->pebs_data_cfg for the last PEBS event
+    - riscv: Fix vector state restore in rt_sigreturn()
+    - arm64/ptrace: Use saved floating point state type to determine SVE layout
+    - mm/secretmem: fix GUP-fast succeeding on secretmem folios
+    - selftests/mm: include strings.h for ffsl
+    - s390/entry: align system call table on 8 bytes
+    - riscv: Fix spurious errors from __get/put_kernel_nofault
+    - riscv: process: Fix kernel gp leakage
+    - smb: client: fix UAF in smb2_reconnect_server()
+    - smb: client: guarantee refcounted children from parent session
+    - smb: client: refresh referral without acquiring refpath_lock
+    - smb: client: handle DFS tcons in cifs_construct_tcon()
+    - smb: client: serialise cifs_construct_tcon() with cifs_mount_mutex
+    - smb3: retrying on failed server close
+    - smb: client: fix potential UAF in cifs_debug_files_proc_show()
+    - smb: client: fix potential UAF in cifs_stats_proc_write()
+    - smb: client: fix potential UAF in cifs_stats_proc_show()
+    - smb: client: fix potential UAF in cifs_dump_full_key()
+    - smb: client: fix potential UAF in smb2_is_valid_oplock_break()
+    - smb: client: fix potential UAF in smb2_is_valid_lease_break()
+    - smb: client: fix potential UAF in is_valid_oplock_break()
+    - smb: client: fix potential UAF in smb2_is_network_name_deleted()
+    - smb: client: fix potential UAF in cifs_signal_cifsd_for_reconnect()
+    - drm/i915/mst: Limit MST+DSC to TGL+
+    - drm/i915/mst: Reject FEC+MST on ICL
+    - drm/i915/dp: Fix the computation for compressed_bpp for DISPLAY < 13
+    - drm/i915/gt: Disable HW load balancing for CCS
+    - drm/i915/gt: Do not generate the command streamer for all the CCS
+    - drm/i915/gt: Enable only one CCS for compute workload
+    - drm/xe: Use ring ops TLB invalidation for rebinds
+    - drm/xe: Rework rebinding
+    - Revert "x86/mpparse: Register APIC address only once"
+    - bpf: put uprobe link's path and task in release callback
+    - bpf: support deferring bpf_link dealloc to after RCU grace period
+    - efi/libstub: Add generic support for parsing mem_encrypt=
+    - x86/boot: Move mem_encrypt= parsing to the decompressor
+    - x86/sme: Move early SME kernel encryption handling into .head.text
+    - x86/sev: Move early startup code into .head.text section
+    - Linux 6.8.5
+  * CVE-2024-26926
+    - binder: check offset alignment in binder_get_object()
+  * CVE-2024-26922
+    - drm/amdgpu: validate the parameters of bo mapping operations more clearly
+  * CVE-2024-26924
+    - netfilter: nft_set_pipapo: do not free live element
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 05 Jul 2024 13:25:34 +0900
+
+linux-qcom (6.8.0-1004.4) jammy; urgency=medium
+
+  * [RB3] bluetooth hci0 failure found in dmesg
+    - SAUCE: bluetooth/hci_qca: fix timing
+
+  * ftrace:test.d--dynevent--add_remove_btfarg.tc in ubuntu_kselftests_ftrace
+    failed on some architectures (LP: #2067291)
+    - selftests/ftrace: Fix BTFARG testcase to check fprobe is enabled correctly
+
+  [ Ubuntu: 6.8.0-35.35 ]
+
+  * noble/linux: 6.8.0-35.35 -proposed tracker (LP: #2065886)
+  * CVE-2024-21823
+    - VFIO: Add the SPR_DSA and SPR_IAX devices to the denylist
+    - dmaengine: idxd: add a new security check to deal with a hardware erratum
+    - dmaengine: idxd: add a write() method for applications to submit work
+
+  [ Ubuntu: 6.8.0-34.34 ]
+
+  * noble/linux: 6.8.0-34.34 -proposed tracker (LP: #2065167)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2024.04.29)
+
+  [ Ubuntu: 6.8.0-32.32 ]
+
+  * noble/linux: 6.8.0-32.32 -proposed tracker (LP: #2064344)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] drop getabis data
+    - [Packaging] update variants
+    - [Packaging] update annotations scripts
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2024.04.29)
+  * Enable Nezha board (LP: #1975592)
+    - [Config] Enable CONFIG_REGULATOR_FIXED_VOLTAGE on riscv64
+  * Enable Nezha board (LP: #1975592) // Enable StarFive VisionFive 2 board
+    (LP: #2013232)
+    - [Config] Enable CONFIG_SERIAL_8250_DW on riscv64
+  * RISC-V kernel config is out of sync with other archs (LP: #1981437)
+    - [Config] Sync riscv64 config with other architectures
+  * obsolete out-of-tree ivsc dkms in favor of in-tree one (LP: #2061747)
+    - ACPI: scan: Defer enumeration of devices with a _DEP pointing to IVSC device
+    - Revert "mei: vsc: Call wake_up() in the threaded IRQ handler"
+    - mei: vsc: Unregister interrupt handler for system suspend
+    - media: ipu-bridge: Add ov01a10 in Dell XPS 9315
+    - SAUCE: media: ipu-bridge: Support more sensors
+  * Fix after-suspend-mediacard/sdhc-insert test failed (LP: #2042500)
+    - PCI/ASPM: Move pci_configure_ltr() to aspm.c
+    - PCI/ASPM: Always build aspm.c
+    - PCI/ASPM: Move pci_save_ltr_state() to aspm.c
+    - PCI/ASPM: Save L1 PM Substates Capability for suspend/resume
+    - PCI/ASPM: Call pci_save_ltr_state() from pci_save_pcie_state()
+    - PCI/ASPM: Disable L1 before configuring L1 Substates
+    - PCI/ASPM: Update save_state when configuration changes
+  * RTL8852BE fw security fail then lost WIFI function during suspend/resume
+    cycle (LP: #2063096)
+    - wifi: rtw89: download firmware with five times retry
+  * intel_rapl_common: Add support for ARL and LNL (LP: #2061953)
+    - powercap: intel_rapl: Add support for Lunar Lake-M paltform
+    - powercap: intel_rapl: Add support for Arrow Lake
+  * Kernel panic during checkbox stress_ng_test on Grace running noble 6.8
+    (arm64+largemem) kernel (LP: #2058557)
+    - aio: Fix null ptr deref in aio_complete() wakeup
+  * Avoid creating non-working backlight sysfs knob from ASUS board
+    (LP: #2060422)
+    - platform/x86: asus-wmi: Consider device is absent when the read is ~0
+  * Include cifs.ko in linux-modules package (LP: #2042546)
+    - [Packaging] Replace fs/cifs with fs/smb/client in inclusion list
+  * Add Real-time Linux Analysis tool (rtla) to linux-tools (LP: #2059080)
+    - SAUCE: rtla: fix deb build
+    - [Packaging] add Real-time Linux Analysis tool (rtla) to linux-tools
+    - [Packaging] update dependencies for rtla
+  * Noble update: v6.8.4 upstream stable release (LP: #2060533)
+    - Revert "workqueue: Shorten events_freezable_power_efficient name"
+    - Revert "workqueue: Don't call cpumask_test_cpu() with -1 CPU in
+      wq_update_node_max_active()"
+    - Revert "workqueue: Implement system-wide nr_active enforcement for unbound
+      workqueues"
+    - Revert "workqueue: Introduce struct wq_node_nr_active"
+    - Revert "workqueue: RCU protect wq->dfl_pwq and implement accessors for it"
+    - Revert "workqueue: Make wq_adjust_max_active() round-robin pwqs while
+      activating"
+    - Revert "workqueue: Move nr_active handling into helpers"
+    - Revert "workqueue: Replace pwq_activate_inactive_work() with
+      [__]pwq_activate_work()"
+    - Revert "workqueue: Factor out pwq_is_empty()"
+    - Revert "workqueue: Move pwq->max_active to wq->max_active"
+    - Revert "workqueue.c: Increase workqueue name length"
+    - Linux 6.8.4
+  * Noble update: v6.8.3 upstream stable release (LP: #2060531)
+    - drm/vmwgfx: Unmap the surface before resetting it on a plane state
+    - wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach
+    - wifi: brcmfmac: avoid invalid list operation when vendor attach fails
+    - media: staging: ipu3-imgu: Set fields before media_entity_pads_init()
+    - arm64: dts: qcom: sc7280: Add additional MSI interrupts
+    - remoteproc: virtio: Fix wdg cannot recovery remote processor
+    - clk: qcom: gcc-sdm845: Add soft dependency on rpmhpd
+    - smack: Set SMACK64TRANSMUTE only for dirs in smack_inode_setxattr()
+    - smack: Handle SMACK64TRANSMUTE in smack_inode_setsecurity()
+    - arm: dts: marvell: Fix maxium->maxim typo in brownstone dts
+    - drm/vmwgfx: Fix possible null pointer derefence with invalid contexts
+    - arm64: dts: qcom: sm8450-hdk: correct AMIC4 and AMIC5 microphones
+    - serial: max310x: fix NULL pointer dereference in I2C instantiation
+    - drm/vmwgfx: Fix the lifetime of the bo cursor memory
+    - pci_iounmap(): Fix MMIO mapping leak
+    - media: xc4000: Fix atomicity violation in xc4000_get_frequency
+    - media: mc: Add local pad to pipeline regardless of the link state
+    - media: mc: Fix flags handling when creating pad links
+    - media: nxp: imx8-isi: Check whether crossbar pad is non-NULL before access
+    - media: mc: Add num_links flag to media_pad
+    - media: mc: Rename pad variable to clarify intent
+    - media: mc: Expand MUST_CONNECT flag to always require an enabled link
+    - media: nxp: imx8-isi: Mark all crossbar sink pads as MUST_CONNECT
+    - md: use RCU lock to protect traversal in md_spares_need_change()
+    - KVM: Always flush async #PF workqueue when vCPU is being destroyed
+    - arm64: dts: qcom: sm8550-qrd: correct WCD9385 TX port mapping
+    - arm64: dts: qcom: sm8550-mtp: correct WCD9385 TX port mapping
+    - cpufreq: amd-pstate: Fix min_perf assignment in amd_pstate_adjust_perf()
+    - thermal/intel: Fix intel_tcc_get_temp() to support negative CPU temperature
+    - powercap: intel_rapl: Fix a NULL pointer dereference
+    - powercap: intel_rapl: Fix locking in TPMI RAPL
+    - powercap: intel_rapl_tpmi: Fix a register bug
+    - powercap: intel_rapl_tpmi: Fix System Domain probing
+    - powerpc/smp: Adjust nr_cpu_ids to cover all threads of a core
+    - powerpc/smp: Increase nr_cpu_ids to include the boot CPU
+    - sparc64: NMI watchdog: fix return value of __setup handler
+    - sparc: vDSO: fix return value of __setup handler
+    - selftests/mqueue: Set timeout to 180 seconds
+    - pinctrl: qcom: sm8650-lpass-lpi: correct Kconfig name
+    - ext4: correct best extent lstart adjustment logic
+    - drm/amdgpu/display: Address kdoc for 'is_psr_su' in 'fill_dc_dirty_rects'
+    - block: Clear zone limits for a non-zoned stacked queue
+    - kasan/test: avoid gcc warning for intentional overflow
+    - bounds: support non-power-of-two CONFIG_NR_CPUS
+    - fat: fix uninitialized field in nostale filehandles
+    - fuse: fix VM_MAYSHARE and direct_io_allow_mmap
+    - mfd: twl: Select MFD_CORE
+    - ubifs: Set page uptodate in the correct place
+    - ubi: Check for too small LEB size in VTBL code
+    - ubi: correct the calculation of fastmap size
+    - ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path
+    - mtd: rawnand: meson: fix scrambling mode value in command macro
+    - md/md-bitmap: fix incorrect usage for sb_index
+    - x86/nmi: Fix the inverse "in NMI handler" check
+    - parisc/unaligned: Rewrite 64-bit inline assembly of emulate_ldd()
+    - parisc: Avoid clobbering the C/B bits in the PSW with tophys and tovirt
+      macros
+    - parisc: Fix ip_fast_csum
+    - parisc: Fix csum_ipv6_magic on 32-bit systems
+    - parisc: Fix csum_ipv6_magic on 64-bit systems
+    - parisc: Strip upper 32 bit of sum in csum_ipv6_magic for 64-bit builds
+    - md/raid5: fix atomicity violation in raid5_cache_count
+    - iio: adc: rockchip_saradc: fix bitmask for channels on SARADCv2
+    - iio: adc: rockchip_saradc: use mask for write_enable bitfield
+    - docs: Restore "smart quotes" for quotes
+    - cpufreq: Limit resolving a frequency to policy min/max
+    - PM: suspend: Set mem_sleep_current during kernel command line setup
+    - vfio/pds: Always clear the save/restore FDs on reset
+    - clk: qcom: gcc-ipq5018: fix terminating of frequency table arrays
+    - clk: qcom: gcc-ipq6018: fix terminating of frequency table arrays
+    - clk: qcom: gcc-ipq8074: fix terminating of frequency table arrays
+    - clk: qcom: gcc-ipq9574: fix terminating of frequency table arrays
+    - clk: qcom: camcc-sc8280xp: fix terminating of frequency table arrays
+    - clk: qcom: mmcc-apq8084: fix terminating of frequency table arrays
+    - clk: qcom: mmcc-msm8974: fix terminating of frequency table arrays
+    - usb: xhci: Add error handling in xhci_map_urb_for_dma
+    - powerpc/fsl: Fix mfpmr build errors with newer binutils
+    - USB: serial: ftdi_sio: add support for GMC Z216C Adapter IR-USB
+    - USB: serial: add device ID for VeriFone adapter
+    - USB: serial: cp210x: add ID for MGP Instruments PDS100
+    - wifi: mac80211: track capability/opmode NSS separately
+    - USB: serial: option: add MeiG Smart SLM320 product
+    - KVM: x86/xen: inject vCPU upcall vector when local APIC is enabled
+    - USB: serial: cp210x: add pid/vid for TDK NC0110013M and MM0110113M
+    - PM: sleep: wakeirq: fix wake irq warning in system suspend
+    - mmc: tmio: avoid concurrent runs of mmc_request_done()
+    - fuse: replace remaining make_bad_inode() with fuse_make_bad()
+    - fuse: fix root lookup with nonzero generation
+    - fuse: don't unhash root
+    - usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros
+    - usb: dwc3-am62: fix module unload/reload behavior
+    - usb: dwc3-am62: Disable wakeup at remove
+    - serial: core: only stop transmit when HW fifo is empty
+    - serial: Lock console when calling into driver before registration
+    - btrfs: qgroup: always free reserved space for extent records
+    - btrfs: fix off-by-one chunk length calculation at contains_pending_extent()
+    - wifi: rtw88: Add missing VID/PIDs for 8811CU and 8821CU
+    - docs: Makefile: Add dependency to $(YNL_INDEX) for targets other than
+      htmldocs
+    - PCI/PM: Drain runtime-idle callbacks before driver removal
+    - PCI/DPC: Quirk PIO log size for Intel Raptor Lake Root Ports
+    - Revert "Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d""
+    - md: don't clear MD_RECOVERY_FROZEN for new dm-raid until resume
+    - md: export helpers to stop sync_thread
+    - md: export helper md_is_rdwr()
+    - md: add a new helper reshape_interrupted()
+    - dm-raid: really frozen sync_thread during suspend
+    - md/dm-raid: don't call md_reap_sync_thread() directly
+    - dm-raid: add a new helper prepare_suspend() in md_personality
+    - dm-raid456, md/raid456: fix a deadlock for dm-raid456 while io concurrent
+      with reshape
+    - dm-raid: fix lockdep waring in "pers->hot_add_disk"
+    - powerpc: xor_vmx: Add '-mhard-float' to CFLAGS
+    - mac802154: fix llsec key resources release in mac802154_llsec_key_del
+    - mm: swap: fix race between free_swap_and_cache() and swapoff()
+    - mmc: core: Fix switch on gp3 partition
+    - Bluetooth: btnxpuart: Fix btnxpuart_close
+    - leds: trigger: netdev: Fix kernel panic on interface rename trig notify
+    - drm/etnaviv: Restore some id values
+    - landlock: Warn once if a Landlock action is requested while disabled
+    - io_uring: fix mshot read defer taskrun cqe posting
+    - hwmon: (amc6821) add of_match table
+    - io_uring: fix io_queue_proc modifying req->flags
+    - ext4: fix corruption during on-line resize
+    - nvmem: meson-efuse: fix function pointer type mismatch
+    - slimbus: core: Remove usage of the deprecated ida_simple_xx() API
+    - phy: tegra: xusb: Add API to retrieve the port number of phy
+    - usb: gadget: tegra-xudc: Fix USB3 PHY retrieval logic
+    - speakup: Fix 8bit characters from direct synth
+    - debugfs: fix wait/cancellation handling during remove
+    - PCI/AER: Block runtime suspend when handling errors
+    - io_uring/net: correctly handle multishot recvmsg retry setup
+    - io_uring: fix mshot io-wq checks
+    - PCI: qcom: Disable ASPM L0s for sc8280xp, sa8540p and sa8295p
+    - sparc32: Fix parport build with sparc32
+    - nfs: fix UAF in direct writes
+    - NFS: Read unlock folio on nfs_page_create_from_folio() error
+    - kbuild: Move -Wenum-{compare-conditional,enum-conversion} into W=1
+    - PCI: qcom: Enable BDF to SID translation properly
+    - PCI: dwc: endpoint: Fix advertised resizable BAR size
+    - PCI: hv: Fix ring buffer size calculation
+    - cifs: prevent updating file size from server if we have a read/write lease
+    - cifs: allow changing password during remount
+    - thermal/drivers/mediatek: Fix control buffer enablement on MT7896
+    - vfio/pci: Disable auto-enable of exclusive INTx IRQ
+    - vfio/pci: Lock external INTx masking ops
+    - vfio/platform: Disable virqfds on cleanup
+    - vfio/platform: Create persistent IRQ handlers
+    - vfio/fsl-mc: Block calling interrupt handler without trigger
+    - tpm,tpm_tis: Avoid warning splat at shutdown
+    - ksmbd: replace generic_fillattr with vfs_getattr
+    - ksmbd: retrieve number of blocks using vfs_getattr in
+      set_file_allocation_info
+    - platform/x86/intel/tpmi: Change vsec offset to u64
+    - io_uring/rw: return IOU_ISSUE_SKIP_COMPLETE for multishot retry
+    - io_uring: clean rings on NO_MMAP alloc fail
+    - ring-buffer: Do not set shortest_full when full target is hit
+    - ring-buffer: Fix full_waiters_pending in poll
+    - ring-buffer: Use wait_event_interruptible() in ring_buffer_wait()
+    - tracing/ring-buffer: Fix wait_on_pipe() race
+    - dlm: fix user space lkb refcounting
+    - soc: fsl: qbman: Always disable interrupts when taking cgr_lock
+    - soc: fsl: qbman: Use raw spinlock for cgr_lock
+    - s390/zcrypt: fix reference counting on zcrypt card objects
+    - drm/probe-helper: warn about negative .get_modes()
+    - drm/panel: do not return negative error codes from drm_panel_get_modes()
+    - drm/exynos: do not return negative values from .get_modes()
+    - drm/imx/ipuv3: do not return negative values from .get_modes()
+    - drm/vc4: hdmi: do not return negative values from .get_modes()
+    - clocksource/drivers/timer-riscv: Clear timer interrupt on timer
+      initialization
+    - memtest: use {READ,WRITE}_ONCE in memory scanning
+    - Revert "block/mq-deadline: use correct way to throttling write requests"
+    - lsm: use 32-bit compatible data types in LSM syscalls
+    - lsm: handle the NULL buffer case in lsm_fill_user_ctx()
+    - f2fs: mark inode dirty for FI_ATOMIC_COMMITTED flag
+    - f2fs: truncate page cache before clearing flags when aborting atomic write
+    - nilfs2: fix failure to detect DAT corruption in btree and direct mappings
+    - nilfs2: prevent kernel bug at submit_bh_wbc()
+    - cifs: make sure server interfaces are requested only for SMB3+
+    - cifs: reduce warning log level for server not advertising interfaces
+    - cifs: open_cached_dir(): add FILE_READ_EA to desired access
+    - mtd: rawnand: Fix and simplify again the continuous read derivations
+    - mtd: rawnand: Add a helper for calculating a page index
+    - mtd: rawnand: Ensure all continuous terms are always in sync
+    - mtd: rawnand: Constrain even more when continuous reads are enabled
+    - cpufreq: dt: always allocate zeroed cpumask
+    - io_uring/futex: always remove futex entry for cancel all
+    - io_uring/waitid: always remove waitid entry for cancel all
+    - x86/CPU/AMD: Update the Zenbleed microcode revisions
+    - ksmbd: fix slab-out-of-bounds in smb_strndup_from_utf16()
+    - net: esp: fix bad handling of pages from page_pool
+    - NFSD: Fix nfsd_clid_class use of __string_len() macro
+    - drm/i915: Add missing ; to __assign_str() macros in tracepoint code
+    - net: hns3: tracing: fix hclgevf trace event strings
+    - cxl/trace: Properly initialize cxl_poison region name
+    - ksmbd: fix potencial out-of-bounds when buffer offset is invalid
+    - virtio: reenable config if freezing device failed
+    - LoongArch: Change __my_cpu_offset definition to avoid mis-optimization
+    - LoongArch: Define the __io_aw() hook as mmiowb()
+    - LoongArch/crypto: Clean up useless assignment operations
+    - wireguard: netlink: check for dangling peer via is_dead instead of empty
+      list
+    - wireguard: netlink: access device through ctx instead of peer
+    - wireguard: selftests: set RISCV_ISA_FALLBACK on riscv{32,64}
+    - ahci: asm1064: asm1166: don't limit reported ports
+    - drm/amd/display: Change default size for dummy plane in DML2
+    - drm/amdgpu: amdgpu_ttm_gart_bind set gtt bound flag
+    - drm/amdgpu/pm: Fix NULL pointer dereference when get power limit
+    - drm/amdgpu/pm: Check the validity of overdiver power limit
+    - drm/amd/display: Override min required DCFCLK in dml1_validate
+    - drm/amd/display: Allow dirty rects to be sent to dmub when abm is active
+    - drm/amd/display: Init DPPCLK from SMU on dcn32
+    - drm/amd/display: Update odm when ODM combine is changed on an otg master
+      pipe with no plane
+    - drm/amd/display: Fix idle check for shared firmware state
+    - drm/amd/display: Amend coasting vtotal for replay low hz
+    - drm/amd/display: Lock all enabled otg pipes even with no planes
+    - drm/amd/display: Implement wait_for_odm_update_pending_complete
+    - drm/amd/display: Return the correct HDCP error code
+    - drm/amd/display: Add a dc_state NULL check in dc_state_release
+    - drm/amd/display: Fix noise issue on HDMI AV mute
+    - dm snapshot: fix lockup in dm_exception_table_exit
+    - x86/pm: Work around false positive kmemleak report in msr_build_context()
+    - wifi: brcmfmac: add per-vendor feature detection callback
+    - wifi: brcmfmac: cfg80211: Use WSEC to set SAE password
+    - wifi: brcmfmac: Demote vendor-specific attach/detach messages to info
+    - drm/ttm: Make sure the mapped tt pages are decrypted when needed
+    - drm/amd/display: Unify optimize_required flags and VRR adjustments
+    - drm/amd/display: Add more checks for exiting idle in DC
+    - btrfs: add set_folio_extent_mapped() helper
+    - btrfs: replace sb::s_blocksize by fs_info::sectorsize
+    - btrfs: add helpers to get inode from page/folio pointers
+    - btrfs: add helpers to get fs_info from page/folio pointers
+    - btrfs: add helper to get fs_info from struct inode pointer
+    - btrfs: qgroup: validate btrfs_qgroup_inherit parameter
+    - vfio: Introduce interface to flush virqfd inject workqueue
+    - vfio/pci: Create persistent INTx handler
+    - drm/bridge: add ->edid_read hook and drm_bridge_edid_read()
+    - drm/bridge: lt8912b: use drm_bridge_edid_read()
+    - drm/bridge: lt8912b: clear the EDID property on failures
+    - drm/bridge: lt8912b: do not return negative values from .get_modes()
+    - drm/amd/display: Remove pixle rate limit for subvp
+    - drm/amd/display: Revert Remove pixle rate limit for subvp
+    - workqueue: Shorten events_freezable_power_efficient name
+    - drm/amd/display: Use freesync when `DRM_EDID_FEATURE_CONTINUOUS_FREQ` found
+    - netfilter: nf_tables: reject constant set with timeout
+    - Revert "crypto: pkcs7 - remove sha1 support"
+    - x86/efistub: Call mixed mode boot services on the firmware's stack
+    - ASoC: amd: yc: Revert "Fix non-functional mic on Lenovo 21J2"
+    - ASoC: amd: yc: Revert "add new YC platform variant (0x63) support"
+    - Fix memory leak in posix_clock_open()
+    - wifi: rtw88: 8821cu: Fix connection failure
+    - x86/Kconfig: Remove CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT
+    - x86/sev: Fix position dependent variable references in startup code
+    - clocksource/drivers/arm_global_timer: Fix maximum prescaler value
+    - ARM: 9352/1: iwmmxt: Remove support for PJ4/PJ4B cores
+    - ARM: 9359/1: flush: check if the folio is reserved for no-mapping addresses
+    - entry: Respect changes to system call number by trace_sys_enter()
+    - swiotlb: Fix double-allocation of slots due to broken alignment handling
+    - swiotlb: Honour dma_alloc_coherent() alignment in swiotlb_alloc()
+    - swiotlb: Fix alignment checks when both allocation and DMA masks are present
+    - iommu/dma: Force swiotlb_max_mapping_size on an untrusted device
+    - printk: Update @console_may_schedule in console_trylock_spinning()
+    - irqchip/renesas-rzg2l: Flush posted write in irq_eoi()
+    - irqchip/renesas-rzg2l: Rename rzg2l_tint_eoi()
+    - irqchip/renesas-rzg2l: Rename rzg2l_irq_eoi()
+    - irqchip/renesas-rzg2l: Prevent spurious interrupts when setting trigger type
+    - kprobes/x86: Use copy_from_kernel_nofault() to read from unsafe address
+    - efi/libstub: fix efi_random_alloc() to allocate memory at alloc_min or
+      higher address
+    - x86/mpparse: Register APIC address only once
+    - x86/fpu: Keep xfd_state in sync with MSR_IA32_XFD
+    - efi: fix panic in kdump kernel
+    - pwm: img: fix pwm clock lookup
+    - selftests/mm: Fix build with _FORTIFY_SOURCE
+    - btrfs: handle errors returned from unpin_extent_cache()
+    - btrfs: fix warning messages not printing interval at unpin_extent_range()
+    - btrfs: do not skip re-registration for the mounted device
+    - mfd: intel-lpss: Switch to generalized quirk table
+    - mfd: intel-lpss: Introduce QUIRK_CLOCK_DIVIDER_UNITY for XPS 9530
+    - drm/i915: Replace a memset() with zero initialization
+    - drm/i915: Try to preserve the current shared_dpll for fastset on type-c
+      ports
+    - drm/i915: Include the PLL name in the debug messages
+    - drm/i915: Suppress old PLL pipe_mask checks for MG/TC/TBT PLLs
+    - crypto: iaa - Fix nr_cpus < nr_iaa case
+    - drm/amd/display: Prevent crash when disable stream
+    - ALSA: hda/tas2781: remove digital gain kcontrol
+    - ALSA: hda/tas2781: add locks to kcontrols
+    - mm: zswap: fix writeback shinker GFP_NOIO/GFP_NOFS recursion
+    - init: open /initrd.image with O_LARGEFILE
+    - x86/efistub: Add missing boot_params for mixed mode compat entry
+    - efi/libstub: Cast away type warning in use of max()
+    - x86/efistub: Reinstate soft limit for initrd loading
+    - prctl: generalize PR_SET_MDWE support check to be per-arch
+    - ARM: prctl: reject PR_SET_MDWE on pre-ARMv6
+    - tmpfs: fix race on handling dquot rbtree
+    - btrfs: validate device maj:min during open
+    - btrfs: fix race in read_extent_buffer_pages()
+    - btrfs: zoned: don't skip block groups with 100% zone unusable
+    - btrfs: zoned: use zone aware sb location for scrub
+    - btrfs: zoned: fix use-after-free in do_zone_finish()
+    - wifi: mac80211: check/clear fast rx for non-4addr sta VLAN changes
+    - wifi: cfg80211: add a flag to disable wireless extensions
+    - wifi: iwlwifi: mvm: disable MLO for the time being
+    - wifi: iwlwifi: fw: don't always use FW dump trig
+    - wifi: iwlwifi: mvm: handle debugfs names more carefully
+    - Revert "drm/amd/display: Fix sending VSC (+ colorimetry) packets for DP/eDP
+      displays without PSR"
+    - fbdev: Select I/O-memory framebuffer ops for SBus
+    - exec: Fix NOMMU linux_binprm::exec in transfer_args_to_stack()
+    - hexagon: vmlinux.lds.S: handle attributes section
+    - mm: cachestat: fix two shmem bugs
+    - selftests/mm: sigbus-wp test requires UFFD_FEATURE_WP_HUGETLBFS_SHMEM
+    - selftests/mm: fix ARM related issue with fork after pthread_create
+    - mmc: sdhci-omap: re-tuning is needed after a pm transition to support emmc
+      HS200 mode
+    - mmc: core: Initialize mmc_blk_ioc_data
+    - mmc: core: Avoid negative index with array access
+    - sdhci-of-dwcmshc: disable PM runtime in dwcmshc_remove()
+    - block: Do not force full zone append completion in req_bio_endio()
+    - thermal: devfreq_cooling: Fix perf state when calculate dfc res_util
+    - Revert "thermal: core: Don't update trip points inside the hysteresis range"
+    - nouveau/dmem: handle kcalloc() allocation failure
+    - net: ll_temac: platform_get_resource replaced by wrong function
+    - net: wan: framer: Add missing static inline qualifiers
+    - net: phy: qcom: at803x: fix kernel panic with at8031_probe
+    - drm/xe/query: fix gt_id bounds check
+    - drm/dp: Fix divide-by-zero regression on DP MST unplug with nouveau
+    - drm/vmwgfx: Create debugfs ttm_resource_manager entry only if needed
+    - drm/amdkfd: fix TLB flush after unmap for GFX9.4.2
+    - drm/amdgpu: fix deadlock while reading mqd from debugfs
+    - drm/amd/display: Remove MPC rate control logic from DCN30 and above
+    - drm/amd/display: Set DCN351 BB and IP the same as DCN35
+    - drm/i915/hwmon: Fix locking inversion in sysfs getter
+    - drm/i915/vma: Fix UAF on destroy against retire race
+    - drm/i915/bios: Tolerate devdata==NULL in
+      intel_bios_encoder_supports_dp_dual_mode()
+    - drm/i915/vrr: Generate VRR "safe window" for DSB
+    - drm/i915/dsi: Go back to the previous INIT_OTP/DISPLAY_ON order, mostly
+    - drm/i915/dsb: Fix DSB vblank waits when using VRR
+    - drm/i915: Do not match JSL in ehl_combo_pll_div_frac_wa_needed()
+    - drm/i915: Pre-populate the cursor physical dma address
+    - drm/i915/gt: Reset queue_priority_hint on parking
+    - drm/amd/display: Fix bounds check for dcn35 DcfClocks
+    - Bluetooth: hci_sync: Fix not checking error on hci_cmd_sync_cancel_sync
+    - mtd: spinand: Add support for 5-byte IDs
+    - Revert "usb: phy: generic: Get the vbus supply"
+    - usb: cdc-wdm: close race between read and workqueue
+    - usb: misc: ljca: Fix double free in error handling path
+    - USB: UAS: return ENODEV when submit urbs fail with device not attached
+    - vfio/pds: Make sure migration file isn't accessed after reset
+    - ring-buffer: Make wake once of ring_buffer_wait() more robust
+    - btrfs: fix extent map leak in unexpected scenario at unpin_extent_cache()
+    - ALSA: sh: aica: reorder cleanup operations to avoid UAF bugs
+    - scsi: ufs: qcom: Provide default cycles_in_1us value
+    - scsi: sd: Fix TCG OPAL unlock on system resume
+    - scsi: core: Fix unremoved procfs host directory regression
+    - staging: vc04_services: changen strncpy() to strscpy_pad()
+    - staging: vc04_services: fix information leak in create_component()
+    - genirq: Introduce IRQF_COND_ONESHOT and use it in pinctrl-amd
+    - usb: dwc3: Properly set system wakeup
+    - USB: core: Fix deadlock in usb_deauthorize_interface()
+    - USB: core: Add hub_get() and hub_put() routines
+    - USB: core: Fix deadlock in port "disable" sysfs attribute
+    - usb: dwc2: host: Fix remote wakeup from hibernation
+    - usb: dwc2: host: Fix hibernation flow
+    - usb: dwc2: host: Fix ISOC flow in DDMA mode
+    - usb: dwc2: gadget: Fix exiting from clock gating
+    - usb: dwc2: gadget: LPM flow fix
+    - usb: udc: remove warning when queue disabled ep
+    - usb: typec: ucsi: Fix race between typec_switch and role_switch
+    - usb: typec: tcpm: fix double-free issue in tcpm_port_unregister_pd()
+    - usb: typec: tcpm: Correct port source pdo array in pd_set callback
+    - usb: typec: tcpm: Update PD of Type-C port upon pd_set
+    - usb: typec: Return size of buffer if pd_set operation succeeds
+    - usb: typec: ucsi: Clear EVENT_PENDING under PPM lock
+    - usb: typec: ucsi: Ack unsupported commands
+    - usb: typec: ucsi_acpi: Refactor and fix DELL quirk
+    - usb: typec: ucsi: Clear UCSI_CCI_RESET_COMPLETE before reset
+    - scsi: qla2xxx: Prevent command send on chip reset
+    - scsi: qla2xxx: Fix N2N stuck connection
+    - scsi: qla2xxx: Split FCE|EFT trace control
+    - scsi: qla2xxx: Update manufacturer detail
+    - scsi: qla2xxx: NVME|FCP prefer flag not being honored
+    - scsi: qla2xxx: Fix command flush on cable pull
+    - scsi: qla2xxx: Fix double free of the ha->vp_map pointer
+    - scsi: qla2xxx: Fix double free of fcport
+    - scsi: qla2xxx: Change debug message during driver unload
+    - scsi: qla2xxx: Delay I/O Abort on PCI error
+    - x86/bugs: Fix the SRSO mitigation on Zen3/4
+    - crash: use macro to add crashk_res into iomem early for specific arch
+    - drm/amd/display: fix IPX enablement
+    - x86/bugs: Use fixed addressing for VERW operand
+    - Revert "x86/bugs: Use fixed addressing for VERW operand"
+    - usb: dwc3: pci: Drop duplicate ID
+    - scsi: lpfc: Correct size for cmdwqe/rspwqe for memset()
+    - scsi: lpfc: Correct size for wqe for memset()
+    - scsi: libsas: Add a helper sas_get_sas_addr_and_dev_type()
+    - scsi: libsas: Fix disk not being scanned in after being removed
+    - perf/x86/amd/core: Update and fix stalled-cycles-* events for Zen 2 and
+      later
+    - x86/sev: Skip ROM range scans and validation for SEV-SNP guests
+    - tools/resolve_btfids: fix build with musl libc
+    - drm/amdgpu: fix use-after-free bug
+    - drm/sched: fix null-ptr-deref in init entity
+    - Linux 6.8.3
+    - [Config] updateconfigs following v6.8.3 import
+  * Noble update: v6.8.3 upstream stable release (LP: #2060531) //
+    [Ubuntu-24.04] Hugepage memory is not getting released even after destroying
+    the guest! (LP: #2062556)
+    - block: Fix page refcounts for unaligned buffers in __bio_release_pages()
+  *  [SPR][EMR][GNR] TDX: efi: TD Measurement support for kernel cmdline/initrd
+    sections from EFI stub  (LP: #2060130)
+    - efi/libstub: Use TPM event typedefs from the TCG PC Client spec
+    - efi/tpm: Use symbolic GUID name from spec for final events table
+    - efi/libstub: Add Confidential Computing (CC) measurement typedefs
+    - efi/libstub: Measure into CC protocol if TCG2 protocol is absent
+    - efi/libstub: Add get_event_log() support for CC platforms
+    - x86/efistub: Remap kernel text read-only before dropping NX attribute
+  * Fix acpi_power_meter accessing IPMI region before it's ready (LP: #2059263)
+    - ACPI: IPMI: Add helper to wait for when SMI is selected
+    - hwmon: (acpi_power_meter) Ensure IPMI space handler is ready on Dell systems
+  * Drop fips-checks script from trees (LP: #2055083)
+    - [Packaging] Remove fips-checks script
+  * alsa/realtek: adjust max output valume for headphone on 2 LG machines
+    (LP: #2058573)
+    - ALSA: hda/realtek: fix the hp playback volume issue for LG machines
+  * Noble update: v6.8.2 upstream stable release (LP: #2060097)
+    - do_sys_name_to_handle(): use kzalloc() to fix kernel-infoleak
+    - workqueue.c: Increase workqueue name length
+    - workqueue: Move pwq->max_active to wq->max_active
+    - workqueue: Factor out pwq_is_empty()
+    - workqueue: Replace pwq_activate_inactive_work() with [__]pwq_activate_work()
+    - workqueue: Move nr_active handling into helpers
+    - workqueue: Make wq_adjust_max_active() round-robin pwqs while activating
+    - workqueue: RCU protect wq->dfl_pwq and implement accessors for it
+    - workqueue: Introduce struct wq_node_nr_active
+    - workqueue: Implement system-wide nr_active enforcement for unbound
+      workqueues
+    - workqueue: Don't call cpumask_test_cpu() with -1 CPU in
+      wq_update_node_max_active()
+    - iomap: clear the per-folio dirty bits on all writeback failures
+    - fs: Fix rw_hint validation
+    - io_uring: remove looping around handling traditional task_work
+    - io_uring: remove unconditional looping in local task_work handling
+    - s390/dasd: Use dev_*() for device log messages
+    - s390/dasd: fix double module refcount decrement
+    - fs/hfsplus: use better @opf description
+    - md: fix kmemleak of rdev->serial
+    - rcu/exp: Fix RCU expedited parallel grace period kworker allocation failure
+      recovery
+    - rcu/exp: Handle RCU expedited grace period kworker allocation failure
+    - fs/select: rework stack allocation hack for clang
+    - block: fix deadlock between bd_link_disk_holder and partition scan
+    - md: Don't clear MD_CLOSING when the raid is about to stop
+    - kunit: Setup DMA masks on the kunit device
+    - ovl: Always reject mounting over case-insensitive directories
+    - kunit: test: Log the correct filter string in executor_test
+    - lib/cmdline: Fix an invalid format specifier in an assertion msg
+    - lib: memcpy_kunit: Fix an invalid format specifier in an assertion msg
+    - time: test: Fix incorrect format specifier
+    - rtc: test: Fix invalid format specifier.
+    - net: test: Fix printf format specifier in skb_segment kunit test
+    - drm/xe/tests: Fix printf format specifiers in xe_migrate test
+    - drm: tests: Fix invalid printf format specifiers in KUnit tests
+    - md/raid1: factor out helpers to add rdev to conf
+    - md/raid1: record nonrot rdevs while adding/removing rdevs to conf
+    - md/raid1: fix choose next idle in read_balance()
+    - io_uring/net: unify how recvmsg and sendmsg copy in the msghdr
+    - io_uring/net: move receive multishot out of the generic msghdr path
+    - io_uring/net: fix overflow check in io_recvmsg_mshot_prep()
+    - nvme: host: fix double-free of struct nvme_id_ns in ns_update_nuse()
+    - aoe: fix the potential use-after-free problem in aoecmd_cfg_pkts
+    - x86/mm: Ensure input to pfn_to_kaddr() is treated as a 64-bit type
+    - x86/resctrl: Remove hard-coded memory bandwidth limit
+    - x86/resctrl: Read supported bandwidth sources from CPUID
+    - x86/resctrl: Implement new mba_MBps throttling heuristic
+    - x86/sme: Fix memory encryption setting if enabled by default and not
+      overridden
+    - timekeeping: Fix cross-timestamp interpolation on counter wrap
+    - timekeeping: Fix cross-timestamp interpolation corner case decision
+    - timekeeping: Fix cross-timestamp interpolation for non-x86
+    - x86/asm: Remove the __iomem annotation of movdir64b()'s dst argument
+    - sched/fair: Take the scheduling domain into account in select_idle_smt()
+    - sched/fair: Take the scheduling domain into account in select_idle_core()
+    - wifi: ath10k: fix NULL pointer dereference in
+      ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev()
+    - wifi: b43: Stop/wake correct queue in DMA Tx path when QoS is disabled
+    - wifi: b43: Stop/wake correct queue in PIO Tx path when QoS is disabled
+    - wifi: b43: Stop correct queue in DMA worker when QoS is disabled
+    - wifi: b43: Disable QoS for bcm4331
+    - wifi: wilc1000: fix declarations ordering
+    - wifi: wilc1000: fix RCU usage in connect path
+    - wifi: ath11k: add support to select 6 GHz regulatory type
+    - wifi: ath11k: store cur_regulatory_info for each radio
+    - wifi: ath11k: fix a possible dead lock caused by ab->base_lock
+    - wifi: rtl8xxxu: add cancel_work_sync() for c2hcmd_work
+    - wifi: wilc1000: do not realloc workqueue everytime an interface is added
+    - wifi: wilc1000: fix multi-vif management when deleting a vif
+    - wifi: mwifiex: debugfs: Drop unnecessary error check for
+      debugfs_create_dir()
+    - ARM: dts: renesas: r8a73a4: Fix external clocks and clock rate
+    - arm64: dts: qcom: x1e80100: drop qcom,drv-count
+    - arm64: dts: qcom: sc8180x: Hook up VDD_CX as GCC parent domain
+    - arm64: dts: qcom: sc8180x: Fix up big CPU idle state entry latency
+    - arm64: dts: qcom: sc8180x: Add missing CPU off state
+    - arm64: dts: qcom: sc8180x: Fix eDP PHY power-domains
+    - arm64: dts: qcom: sc8180x: Don't hold MDP core clock at FMAX
+    - arm64: dts: qcom: sc8180x: Require LOW_SVS vote for MMCX if DISPCC is on
+    - arm64: dts: qcom: sc8180x: Add missing CPU<->MDP_CFG path
+    - arm64: dts: qcom: sc8180x: Shrink aoss_qmp register space size
+    - cpufreq: brcmstb-avs-cpufreq: add check for cpufreq_cpu_get's return value
+    - cpufreq: mediatek-hw: Wait for CPU supplies before probing
+    - sock_diag: annotate data-races around sock_diag_handlers[family]
+    - inet_diag: annotate data-races around inet_diag_table[]
+    - bpftool: Silence build warning about calloc()
+    - selftests/bpf: Fix potential premature unload in bpf_testmod
+    - libbpf: Apply map_set_def_max_entries() for inner_maps on creation
+    - selftest/bpf: Add map_in_maps with BPF_MAP_TYPE_PERF_EVENT_ARRAY values
+    - bpftool: Fix wrong free call in do_show_link
+    - wifi: ath12k: Fix issues in channel list update
+    - selftests/bpf: Fix the flaky tc_redirect_dtime test
+    - selftests/bpf: Wait for the netstamp_needed_key static key to be turned on
+    - wifi: cfg80211: add RNR with reporting AP information
+    - wifi: mac80211: use deflink and fix typo in link ID check
+    - wifi: iwlwifi: change link id in time event to s8
+    - af_unix: Annotate data-race of gc_in_progress in wait_for_unix_gc().
+    - arm64: dts: qcom: sm8450: Add missing interconnects to serial
+    - soc: qcom: socinfo: rename PM2250 to PM4125
+    - arm64: dts: qcom: sc7280: Add static properties to cryptobam
+    - arm64: dts: qcom: qcm6490-fairphone-fp5: Add missing reserved-memory
+    - arm64: dts: qcom: sdm845-oneplus-common: improve DAI node naming
+    - arm64: dts: qcom: rename PM2250 to PM4125
+    - cpufreq: mediatek-hw: Don't error out if supply is not found
+    - libbpf: Fix faccessat() usage on Android
+    - libbpf: fix __arg_ctx type enforcement for perf_event programs
+    - pmdomain: qcom: rpmhpd: Drop SA8540P gfx.lvl
+    - arm64: dts: qcom: sa8540p: Drop gfx.lvl as power-domain for gpucc
+    - arm64: dts: renesas: r8a779g0: Restore sort order
+    - arm64: dts: renesas: r8a779g0: Add missing SCIF_CLK2
+    - selftests/bpf: Disable IPv6 for lwt_redirect test
+    - arm64: dts: imx8mm-kontron: Disable pullups for I2C signals on OSM-S i.MX8MM
+    - arm64: dts: imx8mm-kontron: Disable pullups for I2C signals on SL/BL i.MX8MM
+    - arm64: dts: imx8mm-kontron: Disable pullups for onboard UART signals on BL
+      OSM-S board
+    - arm64: dts: imx8mm-kontron: Disable pullups for onboard UART signals on BL
+      board
+    - arm64: dts: imx8mm-kontron: Disable pull resistors for SD card signals on BL
+      OSM-S board
+    - arm64: dts: imx8mm-kontron: Disable pull resistors for SD card signals on BL
+      board
+    - arm64: dts: imx8mm-kontron: Fix interrupt for RTC on OSM-S i.MX8MM module
+    - arm64: dts: imx8qm: Align edma3 power-domains resources indentation
+    - arm64: dts: imx8qm: Correct edma3 power-domains and interrupt numbers
+    - libbpf: Add missing LIBBPF_API annotation to libbpf_set_memlock_rlim API
+    - wifi: ath9k: delay all of ath9k_wmi_event_tasklet() until init is complete
+    - wifi: ath11k: change to move WMI_VDEV_PARAM_SET_HEMU_MODE before
+      WMI_PEER_ASSOC_CMDID
+    - wifi: ath12k: fix fetching MCBC flag for QCN9274
+    - wifi: iwlwifi: mvm: report beacon protection failures
+    - wifi: iwlwifi: dbg-tlv: ensure NUL termination
+    - wifi: iwlwifi: acpi: fix WPFC reading
+    - wifi: iwlwifi: mvm: initialize rates in FW earlier
+    - wifi: iwlwifi: fix EWRD table validity check
+    - wifi: iwlwifi: mvm: d3: fix IPN byte order
+    - wifi: iwlwifi: always have 'uats_enabled'
+    - wifi: iwlwifi: mvm: fix the TLC command after ADD_STA
+    - wifi: iwlwifi: read BIOS PNVM only for non-Intel SKU
+    - gpio: vf610: allow disabling the vf610 driver
+    - selftests/bpf: trace_helpers.c: do not use poisoned type
+    - bpf: make sure scalar args don't accept __arg_nonnull tag
+    - bpf: don't emit warnings intended for global subprogs for static subprogs
+    - arm64: dts: imx8mm-venice-gw71xx: fix USB OTG VBUS
+    - pwm: atmel-hlcdc: Fix clock imbalance related to suspend support
+    - net: blackhole_dev: fix build warning for ethh set but not used
+    - spi: consolidate setting message->spi
+    - spi: move split xfers for CS_WORD emulation
+    - arm64: dts: ti: k3-am62p5-sk: Enable CPSW MDIO node
+    - arm64: dts: ti: k3-j721s2: Fix power domain for VTM node
+    - arm64: dts: ti: k3-j784s4: Fix power domain for VTM node
+    - wifi: ath11k: initialize rx_mcs_80 and rx_mcs_160 before use
+    - wifi: libertas: fix some memleaks in lbs_allocate_cmd_buffer()
+    - arm64: dts: ti: k3-am69-sk: remove assigned-clock-parents for unused VP
+    - libbpf: fix return value for PERF_EVENT __arg_ctx type fix up check
+    - arm64: dts: ti: k3-am62p-mcu/wakeup: Disable MCU and wakeup R5FSS nodes
+    - arm64: dts: qcom: x1e80100-qcp: Fix supplies for LDOs 3E and 2J
+    - libbpf: Use OPTS_SET() macro in bpf_xdp_query()
+    - wifi: wfx: fix memory leak when starting AP
+    - arm64: dts: qcom: qcm2290: declare VLS CLAMP register for USB3 PHY
+    - arm64: dts: qcom: sm6115: declare VLS CLAMP register for USB3 PHY
+    - arm64: dts: qcom: sm8650: Fix UFS PHY clocks
+    - wifi: ath12k: fix incorrect logic of calculating vdev_stats_id
+    - printk: nbcon: Relocate 32bit seq macros
+    - printk: ringbuffer: Do not skip non-finalized records with prb_next_seq()
+    - printk: Wait for all reserved records with pr_flush()
+    - printk: Add this_cpu_in_panic()
+    - printk: ringbuffer: Cleanup reader terminology
+    - printk: ringbuffer: Skip non-finalized records in panic
+    - printk: Disable passing console lock owner completely during panic()
+    - pwm: sti: Fix capture for st,pwm-num-chan < st,capture-num-chan
+    - tools/resolve_btfids: Refactor set sorting with types from btf_ids.h
+    - tools/resolve_btfids: Fix cross-compilation to non-host endianness
+    - wifi: iwlwifi: support EHT for WH
+    - wifi: iwlwifi: properly check if link is active
+    - wifi: iwlwifi: mvm: fix erroneous queue index mask
+    - wifi: iwlwifi: mvm: don't set the MFP flag for the GTK
+    - wifi: iwlwifi: mvm: don't set replay counters to 0xff
+    - s390/pai: fix attr_event_free upper limit for pai device drivers
+    - s390/vdso: drop '-fPIC' from LDFLAGS
+    - arm64: dts: qcom: qcm6490-idp: Correct the voltage setting for vph_pwr
+    - arm64: dts: qcom: qcs6490-rb3gen2: Correct the voltage setting for vph_pwr
+    - selftests: forwarding: Add missing config entries
+    - selftests: forwarding: Add missing multicast routing config entries
+    - arm64: dts: qcom: sm6115: drop pipe clock selection
+    - ipv6: mcast: remove one synchronize_net() barrier in ipv6_mc_down()
+    - arm64: dts: mt8183: Move CrosEC base detection node to kukui-based DTs
+    - arm64: dts: mediatek: mt7986: fix reference to PWM in fan node
+    - arm64: dts: mediatek: mt7986: drop crypto's unneeded/invalid clock name
+    - arm64: dts: mediatek: mt7986: fix SPI bus width properties
+    - arm64: dts: mediatek: mt7986: fix SPI nodename
+    - arm64: dts: mediatek: mt7986: drop "#clock-cells" from PWM
+    - arm64: dts: mediatek: mt7986: add "#reset-cells" to infracfg
+    - arm64: dts: mediatek: mt8192-asurada: Remove CrosEC base detection node
+    - arm64: dts: mediatek: mt8192: fix vencoder clock name
+    - arm64: dts: mediatek: mt8186: fix VENC power domain clocks
+    - arm64: dts: mediatek: mt7622: add missing "device_type" to memory nodes
+    - can: m_can: Start/Cancel polling timer together with interrupts
+    - wifi: iwlwifi: mvm: Fix the listener MAC filter flags
+    - bpf: Mark bpf_spin_{lock,unlock}() helpers with notrace correctly
+    - arm64: dts: qcom: sdm845: Use the Low Power Island CX/MX for SLPI
+    - soc: qcom: llcc: Check return value on Broadcast_OR reg read
+    - ARM: dts: qcom: msm8974: correct qfprom node size
+    - arm64: dts: mediatek: mt8186: Add missing clocks to ssusb power domains
+    - arm64: dts: mediatek: mt8186: Add missing xhci clock to usb controllers
+    - arm64: dts: ti: am65x: Fix dtbs_install for Rocktech OLDI overlay
+    - cpufreq: qcom-hw: add CONFIG_COMMON_CLK dependency
+    - wifi: wilc1000: prevent use-after-free on vif when cleaning up all
+      interfaces
+    - pwm: dwc: use pm_sleep_ptr() macro
+    - arm64: dts: ti: k3-am69-sk: fix PMIC interrupt number
+    - arm64: dts: ti: k3-j721e-sk: fix PMIC interrupt number
+    - arm64: dts: ti: k3-am62-main: disable usb lpm
+    - ACPI: processor_idle: Fix memory leak in acpi_processor_power_exit()
+    - bus: tegra-aconnect: Update dependency to ARCH_TEGRA
+    - iommu/amd: Mark interrupt as managed
+    - wifi: brcmsmac: avoid function pointer casts
+    - arm64: dts: qcom: sdm845-db845c: correct PCIe wake-gpios
+    - arm64: dts: qcom: sm8150: correct PCIe wake-gpios
+    - powercap: dtpm_cpu: Fix error check against freq_qos_add_request()
+    - net: ena: Remove ena_select_queue
+    - arm64: dts: ti: k3-j7200-common-proc-board: Modify Pinmux for wkup_uart0 and
+      mcu_uart0
+    - arm64: dts: ti: k3-j7200-common-proc-board: Remove clock-frequency from
+      mcu_uart0
+    - arm64: dts: ti: k3-j721s2-common-proc-board: Remove Pinmux for CTS and RTS
+      in wkup_uart0
+    - arm64: dts: ti: k3-j784s4-evm: Remove Pinmux for CTS and RTS in wkup_uart0
+    - arm64: dts: ti: k3-am64-main: Fix ITAP/OTAP values for MMC
+    - arm64: dts: mt8195-cherry-tomato: change watchdog reset boot flow
+    - arm64: dts: ti: Add common1 register space for AM65x SoC
+    - arm64: dts: ti: Add common1 register space for AM62x SoC
+    - firmware: arm_scmi: Fix double free in SMC transport cleanup path
+    - wifi: cfg80211: set correct param change count in ML element
+    - arm64: dts: ti: k3-j721e: Fix mux-reg-masks in hbmc_mux
+    - arm64: dts: ti: k3-j784s4-main: Fix mux-reg-masks in serdes_ln_ctrl
+    - arm64: dts: ti: k3-am62p: Fix memory ranges for DMSS
+    - wifi: wilc1000: revert reset line logic flip
+    - ARM: dts: arm: realview: Fix development chip ROM compatible value
+    - memory: tegra: Correct DLA client names
+    - wifi: mt76: mt7996: fix fw loading timeout
+    - wifi: mt76: mt7925: fix connect to 80211b mode fail in 2Ghz band
+    - wifi: mt76: mt7925: fix SAP no beacon issue in 5Ghz and 6Ghz band
+    - wifi: mt76: mt7925: fix mcu query command fail
+    - wifi: mt76: mt7925: fix wmm queue mapping
+    - wifi: mt76: mt7925: fix fw download fail
+    - wifi: mt76: mt7925: fix WoW failed in encrypted mode
+    - wifi: mt76: mt7925: fix the wrong header translation config
+    - wifi: mt76: mt7925: add flow to avoid chip bt function fail
+    - wifi: mt76: mt7925: add support to set ifs time by mcu command
+    - wifi: mt76: mt7925: update PCIe DMA settings
+    - wifi: mt76: mt7996: check txs format before getting skb by pid
+    - wifi: mt76: mt7996: fix TWT issues
+    - wifi: mt76: mt7996: fix incorrect interpretation of EHT MCS caps
+    - wifi: mt76: mt7996: fix HE beamformer phy cap for station vif
+    - wifi: mt76: mt7996: fix efuse reading issue
+    - wifi: mt76: mt7996: fix HIF_TXD_V2_1 value
+    - wifi: mt76: mt792x: fix ethtool warning
+    - wifi: mt76: mt7921e: fix use-after-free in free_irq()
+    - wifi: mt76: mt7925e: fix use-after-free in free_irq()
+    - wifi: mt76: mt7921: fix incorrect type conversion for CLC command
+    - wifi: mt76: mt792x: fix a potential loading failure of the 6Ghz channel
+      config from ACPI
+    - wifi: mt76: fix the issue of missing txpwr settings from ch153 to ch177
+    - arm64: dts: renesas: rzg2l: Add missing interrupts to IRQC nodes
+    - arm64: dts: renesas: r9a08g045: Add missing interrupts to IRQC node
+    - arm64: dts: renesas: rzg3s-smarc-som: Guard Ethernet IRQ GPIO hogs
+    - arm64: dts: renesas: r8a779a0: Correct avb[01] reg sizes
+    - arm64: dts: renesas: r8a779g0: Correct avb[01] reg sizes
+    - net: mctp: copy skb ext data when fragmenting
+    - pstore: inode: Only d_invalidate() is needed
+    - arm64: dts: allwinner: h6: Add RX DMA channel for SPDIF
+    - ARM: dts: imx6dl-yapp4: Fix typo in the QCA switch register address
+    - ARM: dts: imx6dl-yapp4: Move the internal switch PHYs under the switch node
+    - arm64: dts: imx8mp: Set SPI NOR to max 40 MHz on Data Modul i.MX8M Plus eDM
+      SBC
+    - arm64: dts: imx8mp-evk: Fix hdmi@3d node
+    - regulator: userspace-consumer: add module device table
+    - gpiolib: Pass consumer device through to core in
+      devm_fwnode_gpiod_get_index()
+    - arm64: dts: marvell: reorder crypto interrupts on Armada SoCs
+    - ACPI: resource: Do IRQ override on Lunnen Ground laptops
+    - ACPI: resource: Add MAIBENBEN X577 to irq1_edge_low_force_override
+    - ACPI: scan: Fix device check notification handling
+    - arm64: dts: rockchip: add missing interrupt-names for rk356x vdpu
+    - arm64: dts: rockchip: fix reset-names for rk356x i2s2 controller
+    - arm64: dts: rockchip: drop rockchip,trcm-sync-tx-only from rk3588 i2s
+    - objtool: Fix UNWIND_HINT_{SAVE,RESTORE} across basic blocks
+    - x86, relocs: Ignore relocations in .notes section
+    - SUNRPC: fix a memleak in gss_import_v2_context
+    - SUNRPC: fix some memleaks in gssx_dec_option_array
+    - arm64: dts: qcom: sm8550: Fix SPMI channels size
+    - arm64: dts: qcom: sm8650: Fix SPMI channels size
+    - mmc: wmt-sdmmc: remove an incorrect release_mem_region() call in the .remove
+      function
+    - ACPI: CPPC: enable AMD CPPC V2 support for family 17h processors
+    - btrfs: fix race when detecting delalloc ranges during fiemap
+    - wifi: rtw88: 8821cu: Fix firmware upload fail
+    - wifi: rtw88: 8821c: Fix beacon loss and disconnect
+    - wifi: rtw88: 8821c: Fix false alarm count
+    - wifi: brcm80211: handle pmk_op allocation failure
+    - riscv: dts: starfive: jh7100: fix root clock names
+    - PCI: Make pci_dev_is_disconnected() helper public for other drivers
+    - iommu/vt-d: Don't issue ATS Invalidation request when device is disconnected
+    - iommu/vt-d: Use rbtree to track iommu probed devices
+    - iommu/vt-d: Improve ITE fault handling if target device isn't present
+    - iommu/vt-d: Use device rbtree in iopf reporting path
+    - iommu: Add static iommu_ops->release_domain
+    - iommu/vt-d: Fix NULL domain on device release
+    - igc: Fix missing time sync events
+    - igb: Fix missing time sync events
+    - ice: fix stats being updated by way too large values
+    - Bluetooth: Remove HCI_POWER_OFF_TIMEOUT
+    - Bluetooth: mgmt: Remove leftover queuing of power_off work
+    - Bluetooth: Remove superfluous call to hci_conn_check_pending()
+    - Bluetooth: Remove BT_HS
+    - Bluetooth: hci_event: Fix not indicating new connection for BIG Sync
+    - Bluetooth: hci_qca: don't use IS_ERR_OR_NULL() with gpiod_get_optional()
+    - Bluetooth: hci_core: Cancel request on command timeout
+    - Bluetooth: hci_sync: Fix overwriting request callback
+    - Bluetooth: hci_h5: Add ability to allocate memory for private data
+    - Bluetooth: btrtl: fix out of bounds memory access
+    - Bluetooth: hci_core: Fix possible buffer overflow
+    - Bluetooth: msft: Fix memory leak
+    - Bluetooth: btusb: Fix memory leak
+    - Bluetooth: af_bluetooth: Fix deadlock
+    - Bluetooth: fix use-after-free in accessing skb after sending it
+    - sr9800: Add check for usbnet_get_endpoints
+    - s390/cache: prevent rebuild of shared_cpu_list
+    - bpf: Fix DEVMAP_HASH overflow check on 32-bit arches
+    - bpf: Fix hashtab overflow check on 32-bit arches
+    - bpf: Fix stackmap overflow check on 32-bit arches
+    - net: dsa: microchip: make sure drive strength configuration is not lost by
+      soft reset
+    - dpll: spec: use proper enum for pin capabilities attribute
+    - iommu: Fix compilation without CONFIG_IOMMU_INTEL
+    - ipv6: fib6_rules: flush route cache when rule is changed
+    - net: ip_tunnel: make sure to pull inner header in ip_tunnel_rcv()
+    - octeontx2-af: Fix devlink params
+    - net: phy: fix phy_get_internal_delay accessing an empty array
+    - dpll: fix dpll_xa_ref_*_del() for multiple registrations
+    - net: hns3: fix wrong judgment condition issue
+    - net: hns3: fix kernel crash when 1588 is received on HIP08 devices
+    - net: hns3: fix port duplex configure error in IMP reset
+    - Bluetooth: Fix eir name length
+    - net: phy: dp83822: Fix RGMII TX delay configuration
+    - erofs: fix lockdep false positives on initializing erofs_pseudo_mnt
+    - OPP: debugfs: Fix warning around icc_get_name()
+    - tcp: fix incorrect parameter validation in the do_tcp_getsockopt() function
+    - ipmr: fix incorrect parameter validation in the ip_mroute_getsockopt()
+      function
+    - l2tp: fix incorrect parameter validation in the pppol2tp_getsockopt()
+      function
+    - udp: fix incorrect parameter validation in the udp_lib_getsockopt() function
+    - net: kcm: fix incorrect parameter validation in the kcm_getsockopt) function
+    - net/x25: fix incorrect parameter validation in the x25_getsockopt() function
+    - devlink: Fix length of eswitch inline-mode
+    - r8152: fix unknown device for choose_configuration
+    - nfp: flower: handle acti_netdevs allocation failure
+    - bpf: hardcode BPF_PROG_PACK_SIZE to 2MB * num_possible_nodes()
+    - dm raid: fix false positive for requeue needed during reshape
+    - dm: call the resume method on internal suspend
+    - fbdev/simplefb: change loglevel when the power domains cannot be parsed
+    - drm/tegra: dsi: Add missing check for of_find_device_by_node
+    - drm/tegra: dpaux: Fix PM disable depth imbalance in tegra_dpaux_probe
+    - drm/tegra: dsi: Fix some error handling paths in tegra_dsi_probe()
+    - drm/tegra: dsi: Fix missing pm_runtime_disable() in the error handling path
+      of tegra_dsi_probe()
+    - drm/tegra: hdmi: Fix some error handling paths in tegra_hdmi_probe()
+    - drm/tegra: rgb: Fix some error handling paths in tegra_dc_rgb_probe()
+    - drm/tegra: rgb: Fix missing clk_put() in the error handling paths of
+      tegra_dc_rgb_probe()
+    - drm/tegra: output: Fix missing i2c_put_adapter() in the error handling paths
+      of tegra_output_probe()
+    - drm/rockchip: inno_hdmi: Fix video timing
+    - drm: Don't treat 0 as -1 in drm_fixp2int_ceil
+    - drm/vkms: Avoid reading beyond LUT array
+    - drm/vmwgfx: fix a memleak in vmw_gmrid_man_get_node
+    - drm/rockchip: lvds: do not overwrite error code
+    - drm/rockchip: lvds: do not print scary message when probing defer
+    - drm/panel-edp: use put_sync in unprepare
+    - drm/lima: fix a memleak in lima_heap_alloc
+    - ASoC: amd: acp: Add missing error handling in sof-mach
+    - ASoC: SOF: amd: Fix memory leak in amd_sof_acp_probe()
+    - ASoC: SOF: core: Skip firmware test for custom loaders
+    - ASoC: SOF: amd: Compute file paths on firmware load
+    - soundwire: stream: add missing const to Documentation
+    - dmaengine: tegra210-adma: Update dependency to ARCH_TEGRA
+    - media: tc358743: register v4l2 async device only after successful setup
+    - media: cadence: csi2rx: use match fwnode for media link
+    - PCI/DPC: Print all TLP Prefixes, not just the first
+    - perf record: Fix possible incorrect free in record__switch_output()
+    - perf record: Check conflict between '--timestamp-filename' option and pipe
+      mode before recording
+    - HID: lenovo: Add middleclick_workaround sysfs knob for cptkbd
+    - drm/amd/display: Fix a potential buffer overflow in 'dp_dsc_clock_en_read()'
+    - perf pmu: Treat the msr pmu as software
+    - crypto: qat - avoid memcpy() overflow warning
+    - ALSA: hda: cs35l41: Set Channel Index correctly when system is missing _DSD
+    - drm/amd/display: Fix potential NULL pointer dereferences in
+      'dcn10_set_output_transfer_func()'
+    - ASoC: sh: rz-ssi: Fix error message print
+    - drm/vmwgfx: Fix vmw_du_get_cursor_mob fencing of newly-created MOBs
+    - clk: renesas: r8a779g0: Fix PCIe clock name
+    - pinctrl: renesas: rzg2l: Fix locking in rzg2l_dt_subnode_to_map()
+    - pinctrl: renesas: r8a779g0: Add missing SCIF_CLK2 pin group/function
+    - clk: samsung: exynos850: Propagate SPI IPCLK rate change
+    - media: v4l2: cci: print leading 0 on error
+    - perf evsel: Fix duplicate initialization of data->id in
+      evsel__parse_sample()
+    - perf bpf: Clean up the generated/copied vmlinux.h
+    - clk: meson: Add missing clocks to axg_clk_regmaps
+    - media: em28xx: annotate unchecked call to media_device_register()
+    - media: v4l2-tpg: fix some memleaks in tpg_alloc
+    - media: v4l2-mem2mem: fix a memleak in v4l2_m2m_register_entity
+    - media: dt-bindings: techwell,tw9900: Fix port schema ref
+    - mtd: spinand: esmt: Extend IDs to 5 bytes
+    - media: edia: dvbdev: fix a use-after-free
+    - pinctrl: mediatek: Drop bogus slew rate register range for MT8186
+    - pinctrl: mediatek: Drop bogus slew rate register range for MT8192
+    - drm/amdgpu: Fix potential out-of-bounds access in
+      'amdgpu_discovery_reg_base_init()'
+    - clk: qcom: reset: Commonize the de/assert functions
+    - clk: qcom: reset: Ensure write completion on reset de/assertion
+    - quota: Fix potential NULL pointer dereference
+    - quota: Fix rcu annotations of inode dquot pointers
+    - quota: Properly annotate i_dquot arrays with __rcu
+    - ASoC: Intel: ssp-common: Add stub for sof_ssp_get_codec_name
+    - PCI/P2PDMA: Fix a sleeping issue in a RCU read section
+    - PCI: switchtec: Fix an error handling path in switchtec_pci_probe()
+    - crypto: xilinx - call finalize with bh disabled
+    - drivers/ps3: select VIDEO to provide cmdline functions
+    - perf thread_map: Free strlist on normal path in thread_map__new_by_tid_str()
+    - perf srcline: Add missed addr2line closes
+    - dt-bindings: msm: qcom, mdss: Include ommited fam-b compatible
+    - drm/msm/dpu: fix the programming of INTF_CFG2_DATA_HCTL_EN
+    - drm/msm/dpu: Only enable DSC_MODE_MULTIPLEX if dsc_merge is enabled
+    - drm/radeon/ni: Fix wrong firmware size logging in ni_init_microcode()
+    - drm/amd/display: fix NULL checks for adev->dm.dc in amdgpu_dm_fini()
+    - clk: renesas: r8a779g0: Correct PFC/GPIO parent clocks
+    - clk: renesas: r8a779f0: Correct PFC/GPIO parent clock
+    - clk: renesas: r9a07g04[34]: Use SEL_SDHI1_STS status configuration for SD1
+      mux
+    - ALSA: seq: fix function cast warnings
+    - perf expr: Fix "has_event" function for metric style events
+    - perf stat: Avoid metric-only segv
+    - perf metric: Don't remove scale from counts
+    - ASoC: meson: aiu: fix function pointer type mismatch
+    - ASoC: meson: t9015: fix function pointer type mismatch
+    - powerpc: Force inlining of arch_vmap_p{u/m}d_supported()
+    - ASoC: SOF: Add some bounds checking to firmware data
+    - drm: ci: use clk_ignore_unused for apq8016
+    - NTB: fix possible name leak in ntb_register_device()
+    - media: cedrus: h265: Fix configuring bitstream size
+    - media: sun8i-di: Fix coefficient writes
+    - media: sun8i-di: Fix power on/off sequences
+    - media: sun8i-di: Fix chroma difference threshold
+    - staging: media: starfive: Set 16 bpp for capture_raw device
+    - media: imx: csc/scaler: fix v4l2_ctrl_handler memory leak
+    - media: go7007: add check of return value of go7007_read_addr()
+    - media: pvrusb2: remove redundant NULL check
+    - media: videobuf2: Add missing doc comment for waiting_in_dqbuf
+    - media: pvrusb2: fix pvr2_stream_callback casts
+    - clk: qcom: dispcc-sdm845: Adjust internal GDSC wait times
+    - drm/amd/display: Add 'replay' NULL check in 'edp_set_replay_allow_active()'
+    - drm/panel: boe-tv101wum-nl6: make use of prepare_prev_first
+    - drm/msm/dpu: finalise global state object
+    - drm/mediatek: dsi: Fix DSI RGB666 formats and definitions
+    - PCI: Mark 3ware-9650SE Root Port Extended Tags as broken
+    - drm/bridge: adv7511: fix crash on irq during probe
+    - pinctrl: renesas: Allow the compiler to optimize away sh_pfc_pm
+    - clk: hisilicon: hi3519: Release the correct number of gates in
+      hi3519_clk_unregister()
+    - clk: hisilicon: hi3559a: Fix an erroneous devm_kfree()
+    - clk: mediatek: mt8135: Fix an error handling path in
+      clk_mt8135_apmixed_probe()
+    - clk: mediatek: mt7622-apmixedsys: Fix an error handling path in
+      clk_mt8135_apmixed_probe()
+    - clk: mediatek: mt8183: Correct parent of CLK_INFRA_SSPM_32K_SELF
+    - clk: mediatek: mt7981-topckgen: flag SGM_REG_SEL as critical
+    - drm/tegra: put drm_gem_object ref on error in tegra_fb_create
+    - tty: mips_ejtag_fdc: Fix passing incompatible pointer type warning
+    - media: ivsc: csi: Swap SINK and SOURCE pads
+    - media: i2c: imx290: Fix IMX920 typo
+    - mfd: syscon: Call of_node_put() only when of_parse_phandle() takes a ref
+    - mfd: altera-sysmgr: Call of_node_put() only when of_parse_phandle() takes a
+      ref
+    - perf print-events: make is_event_supported() more robust
+    - crypto: arm/sha - fix function cast warnings
+    - crypto: ccp - Avoid discarding errors in psp_send_platform_access_msg()
+    - crypto: qat - remove unused macros in qat_comp_alg.c
+    - crypto: qat - removed unused macro in adf_cnv_dbgfs.c
+    - crypto: qat - avoid division by zero
+    - crypto: qat - remove double initialization of value
+    - crypto: qat - fix ring to service map for dcc in 4xxx
+    - crypto: qat - fix ring to service map for dcc in 420xx
+    - crypto: jitter - fix CRYPTO_JITTERENTROPY help text
+    - drm/tidss: Fix initial plane zpos values
+    - drm/tidss: Fix sync-lost issue with two displays
+    - clk: imx: imx8mp: Fix SAI_MCLK_SEL definition
+    - mtd: maps: physmap-core: fix flash size larger than 32-bit
+    - mtd: rawnand: lpc32xx_mlc: fix irq handler prototype
+    - mtd: rawnand: brcmnand: exec_op helper functions return type fixes
+    - ASoC: meson: axg-tdm-interface: fix mclk setup without mclk-fs
+    - ASoC: meson: axg-tdm-interface: add frame rate constraint
+    - drm/msm/a6xx: specify UBWC config for sc7180
+    - drm/msm/a7xx: Fix LLC typo
+    - dt-bindings: arm-smmu: fix SM8[45]50 GPU SMMU if condition
+    - perf pmu: Fix a potential memory leak in perf_pmu__lookup()
+    - HID: amd_sfh: Update HPD sensor structure elements
+    - HID: amd_sfh: Avoid disabling the interrupt
+    - drm/amdgpu: Fix missing break in ATOM_ARG_IMM Case of atom_get_src_int()
+    - media: pvrusb2: fix uaf in pvr2_context_set_notify
+    - media: dvb-frontends: avoid stack overflow warnings with clang
+    - media: go7007: fix a memleak in go7007_load_encoder
+    - media: ttpci: fix two memleaks in budget_av_attach
+    - media: mediatek: vcodec: avoid -Wcast-function-type-strict warning
+    - arm64: ftrace: Don't forbid CALL_OPS+CC_OPTIMIZE_FOR_SIZE with Clang
+    - drm/tests: helpers: Include missing drm_drv header
+    - drm/amd/pm: Fix esm reg mask use to get pcie speed
+    - gpio: nomadik: fix offset bug in nmk_pmx_set()
+    - drm/mediatek: Fix a null pointer crash in mtk_drm_crtc_finish_page_flip
+    - mfd: cs42l43: Fix wrong register defaults
+    - powerpc/32: fix ADB_CUDA kconfig warning
+    - powerpc/pseries: Fix potential memleak in papr_get_attr()
+    - powerpc/hv-gpci: Fix the H_GET_PERF_COUNTER_INFO hcall return value checks
+    - clk: qcom: gcc-ipq5018: fix 'enable_reg' offset of 'gcc_gmac0_sys_clk'
+    - clk: qcom: gcc-ipq5018: fix 'halt_reg' offset of 'gcc_pcie1_pipe_clk'
+    - clk: qcom: gcc-ipq5018: fix register offset for GCC_UBI0_AXI_ARES reset
+    - perf vendor events amd: Fix Zen 4 cache latency events
+    - drm/msm/dpu: allow certain formats for CDM for DP
+    - drm/msm/dpu: add division of drm_display_mode's hskew parameter
+    - media: usbtv: Remove useless locks in usbtv_video_free()
+    - drm/xe: Fix ref counting leak on page fault
+    - drm/xe: Replace 'grouped target' in Makefile with pattern rule
+    - lib/stackdepot: fix first entry having a 0-handle
+    - lib/stackdepot: off by one in depot_fetch_stack()
+    - modules: wait do_free_init correctly
+    - mfd: cs42l43: Fix wrong GPIO_FN_SEL and SPI_CLK_CONFIG1 defaults
+    - power: supply: mm8013: fix "not charging" detection
+    - powerpc/embedded6xx: Fix no previous prototype for avr_uart_send() etc.
+    - powerpc/4xx: Fix warp_gpio_leds build failure
+    - RISC-V: KVM: Forward SEED CSR access to user space
+    - leds: aw2013: Unlock mutex before destroying it
+    - leds: sgm3140: Add missing timer cleanup and flash gpio control
+    - backlight: hx8357: Fix potential NULL pointer dereference
+    - backlight: ktz8866: Correct the check for of_property_read_u32
+    - backlight: lm3630a: Initialize backlight_properties on init
+    - backlight: lm3630a: Don't set bl->props.brightness in get_brightness
+    - backlight: da9052: Fully initialize backlight_properties during probe
+    - backlight: lm3639: Fully initialize backlight_properties during probe
+    - backlight: lp8788: Fully initialize backlight_properties during probe
+    - sparc32: Use generic cmpdi2/ucmpdi2 variants
+    - mtd: maps: sun_uflash: Declare uflash_devinit static
+    - sparc32: Do not select GENERIC_ISA_DMA
+    - sparc32: Fix section mismatch in leon_pci_grpci
+    - clk: Fix clk_core_get NULL dereference
+    - clk: zynq: Prevent null pointer dereference caused by kmalloc failure
+    - PCI: brcmstb: Fix broken brcm_pcie_mdio_write() polling
+    - cifs: Fix writeback data corruption
+    - ALSA: hda/realtek: fix ALC285 issues on HP Envy x360 laptops
+    - ALSA: hda/tas2781: use dev_dbg in system_resume
+    - ALSA: hda/tas2781: add lock to system_suspend
+    - ALSA: hda/tas2781: do not reset cur_* values in runtime_suspend
+    - ALSA: hda/tas2781: do not call pm_runtime_force_* in system_resume/suspend
+    - ALSA: hda/tas2781: restore power state after system_resume
+    - ALSA: scarlett2: Fix Scarlett 4th Gen 4i4 low-voltage detection
+    - ALSA: scarlett2: Fix Scarlett 4th Gen autogain status values
+    - ALSA: scarlett2: Fix Scarlett 4th Gen input gain range
+    - ALSA: scarlett2: Fix Scarlett 4th Gen input gain range again
+    - mips: cm: Convert __mips_cm_l2sync_phys_base() to weak function
+    - platform/x86/intel/pmc/lnl: Remove SSRAM support
+    - platform/x86/intel/pmc/arl: Put GNA device in D3
+    - platform/x86/amd/pmf: Do not use readl() for policy buffer access
+    - ALSA: usb-audio: Stop parsing channels bits when all channels are found.
+    - phy: qcom: qmp-usb: split USB-C PHY driver
+    - phy: qcom: qmp-usbc: add support for the Type-C handling
+    - phy: qcom: qmp-usbc: handle CLAMP register in a correct way
+    - scsi: hisi_sas: Fix a deadlock issue related to automatic dump
+    - RDMA/irdma: Remove duplicate assignment
+    - RDMA/srpt: Do not register event handler until srpt device is fully setup
+    - f2fs: compress: fix to guarantee persisting compressed blocks by CP
+    - f2fs: compress: fix to cover normal cluster write with cp_rwsem
+    - f2fs: compress: fix to check unreleased compressed cluster
+    - f2fs: compress: fix to avoid inconsistence bewteen i_blocks and dnode
+    - f2fs: fix to remove unnecessary f2fs_bug_on() to avoid panic
+    - f2fs: zone: fix to wait completion of last bio in zone correctly
+    - f2fs: fix NULL pointer dereference in f2fs_submit_page_write()
+    - f2fs: compress: fix to cover f2fs_disable_compressed_file() w/ i_sem
+    - f2fs: fix to avoid potential panic during recovery
+    - scsi: csiostor: Avoid function pointer casts
+    - i3c: dw: Disable IBI IRQ depends on hot-join and SIR enabling
+    - RDMA/hns: Fix mis-modifying default congestion control algorithm
+    - RDMA/device: Fix a race between mad_client and cm_client init
+    - RDMA/rtrs-clt: Check strnlen return len in sysfs mpath_policy_store()
+    - scsi: bfa: Fix function pointer type mismatch for hcb_qe->cbfn
+    - f2fs: fix to create selinux label during whiteout initialization
+    - f2fs: compress: fix to check zstd compress level correctly in mount option
+    - net: sunrpc: Fix an off by one in rpc_sockaddr2uaddr()
+    - NFSv4.2: fix nfs4_listxattr kernel BUG at mm/usercopy.c:102
+    - NFSv4.2: fix listxattr maximum XDR buffer size
+    - f2fs: compress: fix to check compress flag w/ .i_sem lock
+    - f2fs: check number of blocks in a current section
+    - watchdog: starfive: Check pm_runtime_enabled() before decrementing usage
+      counter
+    - watchdog: stm32_iwdg: initialize default timeout
+    - f2fs: fix to use correct segment type in f2fs_allocate_data_block()
+    - f2fs: ro: compress: fix to avoid caching unaligned extent
+    - RDMA/mana_ib: Fix bug in creation of dma regions
+    - RDMA/mana_ib: Introduce mdev_to_gc helper function
+    - RDMA/mana_ib: Introduce mana_ib_get_netdev helper function
+    - RDMA/mana_ib: Introduce mana_ib_install_cq_cb helper function
+    - RDMA/mana_ib: Use virtual address in dma regions for MRs
+    - Input: iqs7222 - add support for IQS7222D v1.1 and v1.2
+    - NFS: Fix nfs_netfs_issue_read() xarray locking for writeback interrupt
+    - NFS: Fix an off by one in root_nfs_cat()
+    - NFSv4.1/pnfs: fix NFS with TLS in pnfs
+    - ACPI: HMAT: Remove register of memory node for generic target
+    - f2fs: compress: relocate some judgments in f2fs_reserve_compress_blocks
+    - f2fs: compress: fix reserve_cblocks counting error when out of space
+    - f2fs: fix to truncate meta inode pages forcely
+    - f2fs: zone: fix to remove pow2 check condition for zoned block device
+    - cxl: Fix the incorrect assignment of SSLBIS entry pointer initial location
+    - perf/x86/amd/core: Avoid register reset when CPU is dead
+    - afs: Revert "afs: Hide silly-rename files from userspace"
+    - afs: Don't cache preferred address
+    - afs: Fix occasional rmdir-then-VNOVNODE with generic/011
+    - f2fs: fix to avoid use-after-free issue in f2fs_filemap_fault
+    - nfs: fix panic when nfs4_ff_layout_prepare_ds() fails
+    - ovl: relax WARN_ON in ovl_verify_area()
+    - io_uring/net: correct the type of variable
+    - remoteproc: stm32: Fix incorrect type in assignment for va
+    - remoteproc: stm32: Fix incorrect type assignment returned by
+      stm32_rproc_get_loaded_rsc_tablef
+    - iio: pressure: mprls0025pa fix off-by-one enum
+    - usb: phy: generic: Get the vbus supply
+    - tty: vt: fix 20 vs 0x20 typo in EScsiignore
+    - serial: max310x: fix syntax error in IRQ error message
+    - tty: serial: samsung: fix tx_empty() to return TIOCSER_TEMT
+    - arm64: dts: broadcom: bcmbca: bcm4908: drop invalid switch cells
+    - coresight: Fix issue where a source device's helpers aren't disabled
+    - coresight: etm4x: Set skip_power_up in etm4_init_arch_data function
+    - xhci: Add interrupt pending autoclear flag to each interrupter
+    - xhci: make isoc_bei_interval variable interrupter specific.
+    - xhci: remove unnecessary event_ring_deq parameter from xhci_handle_event()
+    - xhci: update event ring dequeue pointer position to controller correctly
+    - coccinelle: device_attr_show: Remove useless expression STR
+    - kconfig: fix infinite loop when expanding a macro at the end of file
+    - iio: gts-helper: Fix division loop
+    - bus: mhi: ep: check the correct variable in mhi_ep_register_controller()
+    - hwtracing: hisi_ptt: Move type check to the beginning of
+      hisi_ptt_pmu_event_init()
+    - rtc: mt6397: select IRQ_DOMAIN instead of depending on it
+    - rtc: max31335: fix interrupt status reg
+    - serial: 8250_exar: Don't remove GPIO device on suspend
+    - staging: greybus: fix get_channel_from_mode() failure path
+    - mei: vsc: Call wake_up() in the threaded IRQ handler
+    - mei: vsc: Don't use sleeping condition in wait_event_timeout()
+    - usb: gadget: net2272: Use irqflags in the call to net2272_probe_fin
+    - char: xilinx_hwicap: Fix NULL vs IS_ERR() bug
+    - x86/hyperv: Use per cpu initial stack for vtl context
+    - ASoC: tlv320adc3xxx: Don't strip remove function when driver is builtin
+    - thermal/drivers/mediatek/lvts_thermal: Fix a memory leak in an error
+      handling path
+    - thermal/drivers/qoriq: Fix getting tmu range
+    - io_uring: don't save/restore iowait state
+    - spi: lpspi: Avoid potential use-after-free in probe()
+    - spi: Restore delays for non-GPIO chip select
+    - ASoC: rockchip: i2s-tdm: Fix inaccurate sampling rates
+    - nouveau: reset the bo resource bus info after an eviction
+    - tcp: Fix NEW_SYN_RECV handling in inet_twsk_purge()
+    - rds: tcp: Fix use-after-free of net in reqsk_timer_handler().
+    - octeontx2-af: Use matching wake_up API variant in CGX command interface
+    - s390/vtime: fix average steal time calculation
+    - net/sched: taprio: proper TCA_TAPRIO_TC_ENTRY_INDEX check
+    - devlink: Fix devlink parallel commands processing
+    - riscv: Only check online cpus for emulated accesses
+    - soc: fsl: dpio: fix kcalloc() argument order
+    - cpufreq: Fix per-policy boost behavior on SoCs using cpufreq_boost_set_sw()
+    - io_uring: Fix release of pinned pages when __io_uaddr_map fails
+    - tcp: Fix refcnt handling in __inet_hash_connect().
+    - vmxnet3: Fix missing reserved tailroom
+    - hsr: Fix uninit-value access in hsr_get_node()
+    - net: txgbe: fix clk_name exceed MAX_DEV_ID limits
+    - spi: spi-mem: add statistics support to ->exec_op() calls
+    - spi: Fix error code checking in spi_mem_exec_op()
+    - nvme: fix reconnection fail due to reserved tag allocation
+    - drm/xe: Invalidate userptr VMA on page pin fault
+    - drm/xe: Skip VMAs pin when requesting signal to the last XE_EXEC
+    - net: mediatek: mtk_eth_soc: clear MAC_MCR_FORCE_LINK only when MAC is up
+    - net: ethernet: mtk_eth_soc: fix PPE hanging issue
+    - io_uring: fix poll_remove stalled req completion
+    - ASoC: SOF: amd: Move signed_fw_image to struct acp_quirk_entry
+    - ASoC: SOF: amd: Skip IRAM/DRAM size modification for Steam Deck OLED
+    - riscv: Fix compilation error with FAST_GUP and rv32
+    - xen/evtchn: avoid WARN() when unbinding an event channel
+    - xen/events: increment refcnt only if event channel is refcounted
+    - packet: annotate data-races around ignore_outgoing
+    - xfrm: Allow UDP encapsulation only in offload modes
+    - net: veth: do not manipulate GRO when using XDP
+    - net: dsa: mt7530: prevent possible incorrect XTAL frequency selection
+    - spi: spi-imx: fix off-by-one in mx51 CPU mode burst length
+    - drm: Fix drm_fixp2int_round() making it add 0.5
+    - virtio: uapi: Drop __packed attribute in linux/virtio_pci.h
+    - vdpa_sim: reset must not run
+    - vdpa/mlx5: Allow CVQ size changes
+    - virtio: packed: fix unmap leak for indirect desc table
+    - net: move dev->state into net_device_read_txrx group
+    - wireguard: receive: annotate data-race around receiving_counter.counter
+    - rds: introduce acquire/release ordering in acquire/release_in_xmit()
+    - hsr: Handle failures in module init
+    - ipv4: raw: Fix sending packets from raw sockets via IPsec tunnels
+    - nouveau/gsp: don't check devinit disable on GSP.
+    - ceph: stop copying to iter at EOF on sync reads
+    - net: phy: fix phy_read_poll_timeout argument type in genphy_loopback
+    - dm-integrity: fix a memory leak when rechecking the data
+    - net/bnx2x: Prevent access to a freed page in page_pool
+    - devlink: fix port new reply cmd type
+    - octeontx2: Detect the mbox up or down message via register
+    - octeontx2-pf: Wait till detach_resources msg is complete
+    - octeontx2-pf: Use default max_active works instead of one
+    - octeontx2-pf: Send UP messages to VF only when VF is up.
+    - octeontx2-af: Use separate handlers for interrupts
+    - drm/amdgpu: add MMHUB 3.3.1 support
+    - drm/amdgpu: fix mmhub client id out-of-bounds access
+    - drm/amdgpu: drop setting buffer funcs in sdma442
+    - netfilter: nft_set_pipapo: release elements in clone only from destroy path
+    - netfilter: nf_tables: do not compare internal table flags on updates
+    - rcu: add a helper to report consolidated flavor QS
+    - net: report RCU QS on threaded NAPI repolling
+    - bpf: report RCU QS in cpumap kthread
+    - net: dsa: mt7530: fix link-local frames that ingress vlan filtering ports
+    - net: dsa: mt7530: fix handling of all link-local frames
+    - netfilter: nf_tables: Fix a memory leak in nf_tables_updchain
+    - spi: spi-mt65xx: Fix NULL pointer access in interrupt handler
+    - selftests: forwarding: Fix ping failure due to short timeout
+    - dm io: Support IO priority
+    - dm-integrity: align the outgoing bio in integrity_recheck
+    - x86/efistub: Clear decompressor BSS in native EFI entrypoint
+    - x86/efistub: Don't clear BSS twice in mixed mode
+    - printk: Adjust mapping for 32bit seq macros
+    - printk: Use prb_first_seq() as base for 32bit seq macros
+    - Linux 6.8.2
+    - [Config] updateconfig following v6.8.2 import
+  * Provide python perf module (LP: #2051560)
+    - [Packaging] enable perf python module
+    - [Packaging] provide a wrapper module for python-perf
+  * To support AMD Adaptive Backlight Management (ABM) for power profiles daemon
+    >= 2.0 (LP: #2056716)
+    - drm/amd/display: add panel_power_savings sysfs entry to eDP connectors
+    - drm/amdgpu: respect the abmlevel module parameter value if it is set
+  * Miscellaneous Ubuntu changes
+    - [Config] Disable StarFive JH7100 support
+    - [Config] Disable Renesas RZ/Five support
+    - [Config] Disable BINFMT_FLAT for riscv64
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 03 Jun 2024 17:15:49 +0900
+
+linux-qcom (6.8.0-1003.3) jammy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - Fix PCIe bus error
+    - Fix GPU regression
+    - Fix qps615 firmware load
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 10 May 2024 14:41:07 +0900
+
+linux-qcom (6.8.0-1002.2) jammy; urgency=medium
+
+  [ Ubuntu: 6.8.0-31.31 ]
+
+  * noble/linux: 6.8.0-31.31 -proposed tracker (LP: #2062933)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.04.04)
+
+  [ Ubuntu: 6.8.0-30.30 ]
+
+  * noble/linux: 6.8.0-30.30 -proposed tracker (LP: #2061893)
+  * System unstable, kernel ring buffer flooded with "BUG: Bad page state in
+    process swapper/0" (LP: #2056706)
+    - xen-netfront: Add missing skb_mark_for_recycle
+
+  [ Ubuntu: 6.8.0-29.29 ]
+
+  * noble/linux: 6.8.0-29.29 -proposed tracker (LP: #2061888)
+  * [24.04 FEAT] [SEC2353] zcrypt: extend error recovery to deal with device
+    scans (LP: #2050019)
+    - s390/zcrypt: harmonize debug feature calls and defines
+    - s390/zcrypt: introduce dynamic debugging for AP and zcrypt code
+    - s390/pkey: harmonize pkey s390 debug feature calls
+    - s390/pkey: introduce dynamic debugging for pkey
+    - s390/ap: add debug possibility for AP messages
+    - s390/zcrypt: add debug possibility for CCA and EP11 messages
+    - s390/ap: rearm APQNs bindings complete completion
+    - s390/ap: clarify AP scan bus related functions and variables
+    - s390/ap: rework ap_scan_bus() to return true on config change
+    - s390/ap: introduce mutex to lock the AP bus scan
+    - s390/zcrypt: introduce retries on in-kernel send CPRB functions
+    - s390/zcrypt: improve zcrypt retry behavior
+    - s390/pkey: improve pkey retry behavior
+  * [24.04 FEAT] Memory hotplug vmem pages (s390x) (LP: #2051835)
+    - mm/memory_hotplug: introduce MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers
+    - s390/mm: allocate vmemmap pages from self-contained memory range
+    - s390/sclp: remove unhandled memory notifier type
+    - s390/mm: implement MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers
+    - s390: enable MHP_MEMMAP_ON_MEMORY
+    - [Config] enable CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE and
+      CONFIG_MHP_MEMMAP_ON_MEMORY for s390x
+
+  [ Ubuntu: 6.8.0-28.28 ]
+
+  * noble/linux: 6.8.0-28.28 -proposed tracker (LP: #2061867)
+  * linux-gcp 6.8.0-1005.5 (+ others) Noble kernel regression iwth new apparmor
+    profiles/features (LP: #2061851)
+    - SAUCE: apparmor4.0.0 [92/90]: fix address mapping for recvfrom
+
+  [ Ubuntu: 6.8.0-25.25 ]
+
+  * noble/linux: 6.8.0-25.25 -proposed tracker (LP: #2061083)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.04.04)
+  * Apply mitigations for the native BHI hardware vulnerabilty (LP: #2060909)
+    - x86/cpufeatures: Add new word for scattered features
+    - x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file
+    - x86/syscall: Don't force use of indirect calls for system calls
+    - x86/bhi: Add support for clearing branch history at syscall entry
+    - x86/bhi: Define SPEC_CTRL_BHI_DIS_S
+    - x86/bhi: Enumerate Branch History Injection (BHI) bug
+    - x86/bhi: Add BHI mitigation knob
+    - x86/bhi: Mitigate KVM by default
+    - KVM: x86: Add BHI_NO
+    - x86: set SPECTRE_BHI_ON as default
+    - [Config] enable spectre_bhi=auto by default
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [01/90]: LSM stacking v39: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [02/90]: LSM stacking v39: SM: Infrastructure
+      management of the sock security
+    - SAUCE: apparmor4.0.0 [03/90]: LSM stacking v39: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [04/90]: LSM stacking v39: IMA: avoid label collisions
+      with stacked LSMs
+    - SAUCE: apparmor4.0.0 [05/90]: LSM stacking v39: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [06/90]: LSM stacking v39: LSM: Add lsmblob_to_secctx
+      hook
+    - SAUCE: apparmor4.0.0 [07/90]: LSM stacking v39: Audit: maintain an lsmblob
+      in audit_context
+    - SAUCE: apparmor4.0.0 [08/90]: LSM stacking v39: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [09/90]: LSM stacking v39: Audit: Update shutdown LSM
+      data
+    - SAUCE: apparmor4.0.0 [10/90]: LSM stacking v39: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [11/90]: LSM stacking v39: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [12/90]: LSM stacking v39: Audit: use an lsmblob in
+      audit_names
+    - SAUCE: apparmor4.0.0 [13/90]: LSM stacking v39: LSM: Create new
+      security_cred_getlsmblob LSM hook
+    - SAUCE: apparmor4.0.0 [14/90]: LSM stacking v39: Audit: Change context data
+      from secid to lsmblob
+    - SAUCE: apparmor4.0.0 [15/90]: LSM stacking v39: Netlabel: Use lsmblob for
+      audit data
+    - SAUCE: apparmor4.0.0 [16/90]: LSM stacking v39: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [17/90]: LSM stacking v39: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [18/90]: LSM stacking v39: LSM: Use lsmcontext in
+      security_lsmblob_to_secctx
+    - SAUCE: apparmor4.0.0 [19/90]: LSM stacking v39: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [20/90]: LSM stacking v39: LSM: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [21/90]: LSM stacking v39: LSM:
+      security_lsmblob_to_secctx module selection
+    - SAUCE: apparmor4.0.0 [22/90]: LSM stacking v39: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [23/90]: LSM stacking v39: Audit: Allow multiple
+      records in an audit_buffer
+    - SAUCE: apparmor4.0.0 [24/90]: LSM stacking v39: Audit: Add record for
+      multiple task security contexts
+    - SAUCE: apparmor4.0.0 [25/90]: LSM stacking v39: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [26/90]: LSM stacking v39: Audit: Add record for
+      multiple object contexts
+    - SAUCE: apparmor4.0.0 [27/90]: LSM stacking v39: LSM: Remove unused
+      lsmcontext_init()
+    - SAUCE: apparmor4.0.0 [28/90]: LSM stacking v39: LSM: Improve logic in
+      security_getprocattr
+    - SAUCE: apparmor4.0.0 [29/90]: LSM stacking v39: LSM: secctx provider check
+      on release
+    - SAUCE: apparmor4.0.0 [31/90]: LSM stacking v39: LSM: Exclusive secmark usage
+    - SAUCE: apparmor4.0.0 [32/90]: LSM stacking v39: LSM: Identify which LSM
+      handles the context string
+    - SAUCE: apparmor4.0.0 [33/90]: LSM stacking v39: AppArmor: Remove the
+      exclusive flag
+    - SAUCE: apparmor4.0.0 [34/90]: LSM stacking v39: LSM: Add mount opts blob
+      size tracking
+    - SAUCE: apparmor4.0.0 [35/90]: LSM stacking v39: LSM: allocate mnt_opts blobs
+      instead of module specific data
+    - SAUCE: apparmor4.0.0 [36/90]: LSM stacking v39: LSM: Infrastructure
+      management of the key security blob
+    - SAUCE: apparmor4.0.0 [37/90]: LSM stacking v39: LSM: Infrastructure
+      management of the mnt_opts security blob
+    - SAUCE: apparmor4.0.0 [38/90]: LSM stacking v39: LSM: Correct handling of
+      ENOSYS in inode_setxattr
+    - SAUCE: apparmor4.0.0 [39/90]: LSM stacking v39: LSM: Remove lsmblob
+      scaffolding
+    - SAUCE: apparmor4.0.0 [40/90]: LSM stacking v39: LSM: Allow reservation of
+      netlabel
+    - SAUCE: apparmor4.0.0 [41/90]: LSM stacking v39: LSM: restrict
+      security_cred_getsecid() to a single LSM
+    - SAUCE: apparmor4.0.0 [42/90]: LSM stacking v39: Smack: Remove
+      LSM_FLAG_EXCLUSIVE
+    - SAUCE: apparmor4.0.0 [43/90]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0
+      [12/95]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [44/90]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [45/90]: add unpriviled user ns mediation
+    - SAUCE: apparmor4.0.0 [46/90]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [47/90]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [48/90]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [49/90]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [50/90]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/90]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/90]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/90]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [54/90]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [55/90]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [56/90]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [57/90]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [58/90]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [59/90]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [60/90]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [61/90]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [62/90]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [63/90]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [64/90]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [65/90] v6.8 prompt:fixup interruptible
+    - SAUCE: apparmor4.0.0 [69/90]: add io_uring mediation
+    - SAUCE: apparmor4.0.0 [70/90]: apparmor: fix oops when racing to retrieve
+      notification
+    - SAUCE: apparmor4.0.0 [71/90]: apparmor: fix notification header size
+    - SAUCE: apparmor4.0.0 [72/90]: apparmor: fix request field from a prompt
+      reply that denies all access
+    - SAUCE: apparmor4.0.0 [73/90]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+    - SAUCE: apparmor4.0.0 [74/90]: apparmor: cleanup attachment perm lookup to
+      use lookup_perms()
+    - SAUCE: apparmor4.0.0 [75/90]: apparmor: remove redundant unconfined check.
+    - SAUCE: apparmor4.0.0 [76/90]: apparmor: switch signal mediation to using
+      RULE_MEDIATES
+    - SAUCE: apparmor4.0.0 [77/90]: apparmor: ensure labels with more than one
+      entry have correct flags
+    - SAUCE: apparmor4.0.0 [78/90]: apparmor: remove explicit restriction that
+      unconfined cannot use change_hat
+    - SAUCE: apparmor4.0.0 [79/90]: apparmor: cleanup: refactor file_perm() to
+      provide semantics of some checks
+    - SAUCE: apparmor4.0.0 [80/90]: apparmor: carry mediation check on label
+    - SAUCE: apparmor4.0.0 [81/90]: apparmor: convert easy uses of unconfined() to
+      label_mediates()
+    - SAUCE: apparmor4.0.0 [82/90]: apparmor: add additional flags to extended
+      permission.
+    - SAUCE: apparmor4.0.0 [83/90]: apparmor: add support for profiles to define
+      the kill signal
+    - SAUCE: apparmor4.0.0 [84/90]: apparmor: fix x_table_lookup when stacking is
+      not the first entry
+    - SAUCE: apparmor4.0.0 [85/90]: apparmor: allow profile to be transitioned
+      when a user ns is created
+    - SAUCE: apparmor4.0.0 [86/90]: apparmor: add ability to mediate caps with
+      policy state machine
+    - SAUCE: apparmor4.0.0 [87/90]: fixup notify
+    - SAUCE: apparmor4.0.0 [88/90]: apparmor: add fine grained ipv4/ipv6 mediation
+    - SAUCE: apparmor4.0.0 [89/90]:apparmor: disable tailglob responses for now
+    - SAUCE: apparmor4.0.0 [90/90]: apparmor: Fix notify build warnings
+    - SAUCE: apparmor4.0.0: fix reserved mem for when we save ipv6 addresses
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [66/90]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [67/90]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [68/90]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+  * [MTL] x86: Fix Cache info sysfs is not populated (LP: #2049793)
+    - SAUCE: cacheinfo: Check for null last-level cache info
+    - SAUCE: cacheinfo: Allocate memory for memory if not done from the primary
+      CPU
+    - SAUCE: x86/cacheinfo: Delete global num_cache_leaves
+    - SAUCE: x86/cacheinfo: Clean out init_cache_level()
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor4.0.0: LSM stacking v39: fix build error with
+      CONFIG_SECURITY=n
+    - [Config] toolchain version update
+
+  [ Ubuntu: 6.8.0-22.22 ]
+
+  * noble/linux: 6.8.0-22.22 -proposed tracker (LP: #2060238)
+
+  [ Ubuntu: 6.8.0-21.21 ]
+
+  * noble/linux: 6.8.0-21.21 -proposed tracker (LP: #2060225)
+  * Miscellaneous Ubuntu changes
+    - [Config] update toolchain version in annotations
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 01 May 2024 13:45:36 +0900
+
+linux-qcom (6.8.0-1001.1) jammy; urgency=medium
+
+  * Import GA1
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Tue, 09 Apr 2024 01:46:04 +0900
+
+linux-qcom (6.8.0-1000.0) jammy; urgency=medium
+
+  [ Ubuntu: 6.8.0-20.20 ]
+
+  * noble/linux: 6.8.0-20.20 -proposed tracker (LP: #2058221)
+  * Noble update: v6.8.1 upstream stable release (LP: #2058224)
+    - x86/mmio: Disable KVM mitigation when X86_FEATURE_CLEAR_CPU_BUF is set
+    - Documentation/hw-vuln: Add documentation for RFDS
+    - x86/rfds: Mitigate Register File Data Sampling (RFDS)
+    - KVM/x86: Export RFDS_NO and RFDS_CLEAR to guests
+    - Linux 6.8.1
+  * Autopkgtest failures on amd64 (LP: #2048768)
+    - [Packaging] update to clang-18
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor4.0.0: LSM stacking v39: fix build error with
+      CONFIG_SECURITY=n
+    - [Config] amd64: MITIGATION_RFDS=y
+
+  [ Ubuntu: 6.8.0-19.19 ]
+
+  * noble/linux: 6.8.0-19.19 -proposed tracker (LP: #2057910)
+  * Miscellaneous Ubuntu changes
+    - [Packaging] re-introduce linux-doc as an empty package
+
+  [ Ubuntu: 6.8.0-18.18 ]
+
+  * noble/linux: 6.8.0-18.18 -proposed tracker (LP: #2057456)
+  * Miscellaneous Ubuntu changes
+    - [Packaging] drop dependency on libclang-17
+
+  [ Ubuntu: 6.8.0-17.17 ]
+
+  * noble/linux: 6.8.0-17.17 -proposed tracker (LP: #2056745)
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] Add debian/control sanity check"
+
+  [ Ubuntu: 6.8.0-16.16 ]
+
+  * noble/linux: 6.8.0-16.16 -proposed tracker (LP: #2056738)
+  * left-over ceph debugging printks (LP: #2056616)
+    - Revert "UBUNTU: SAUCE: ceph: make sure all the files successfully put before
+      unmounting"
+  * qat: Improve error recovery flows (LP: #2056354)
+    - crypto: qat - add heartbeat error simulator
+    - crypto: qat - disable arbitration before reset
+    - crypto: qat - update PFVF protocol for recovery
+    - crypto: qat - re-enable sriov after pf reset
+    - crypto: qat - add fatal error notification
+    - crypto: qat - add auto reset on error
+    - crypto: qat - limit heartbeat notifications
+    - crypto: qat - improve aer error reset handling
+    - crypto: qat - change SLAs cleanup flow at shutdown
+    - crypto: qat - resolve race condition during AER recovery
+    - Documentation: qat: fix auto_reset section
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [01/87]: LSM stacking v39: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [02/87]: LSM stacking v39: SM: Infrastructure
+      management of the sock security
+    - SAUCE: apparmor4.0.0 [03/87]: LSM stacking v39: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [04/87]: LSM stacking v39: IMA: avoid label collisions
+      with stacked LSMs
+    - SAUCE: apparmor4.0.0 [05/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [06/87]: LSM stacking v39: LSM: Add lsmblob_to_secctx
+      hook
+    - SAUCE: apparmor4.0.0 [07/87]: LSM stacking v39: Audit: maintain an lsmblob
+      in audit_context
+    - SAUCE: apparmor4.0.0 [08/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [09/87]: LSM stacking v39: Audit: Update shutdown LSM
+      data
+    - SAUCE: apparmor4.0.0 [10/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [11/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [12/87]: LSM stacking v39: Audit: use an lsmblob in
+      audit_names
+    - SAUCE: apparmor4.0.0 [13/87]: LSM stacking v39: LSM: Create new
+      security_cred_getlsmblob LSM hook
+    - SAUCE: apparmor4.0.0 [14/87]: LSM stacking v39: Audit: Change context data
+      from secid to lsmblob
+    - SAUCE: apparmor4.0.0 [15/87]: LSM stacking v39: Netlabel: Use lsmblob for
+      audit data
+    - SAUCE: apparmor4.0.0 [16/87]: LSM stacking v39: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [17/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [18/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_lsmblob_to_secctx
+    - SAUCE: apparmor4.0.0 [19/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [20/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [21/87]: LSM stacking v39: LSM:
+      security_lsmblob_to_secctx module selection
+    - SAUCE: apparmor4.0.0 [22/87]: LSM stacking v39: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [23/87]: LSM stacking v39: Audit: Allow multiple
+      records in an audit_buffer
+    - SAUCE: apparmor4.0.0 [24/87]: LSM stacking v39: Audit: Add record for
+      multiple task security contexts
+    - SAUCE: apparmor4.0.0 [25/87]: LSM stacking v39: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [26/87]: LSM stacking v39: Audit: Add record for
+      multiple object contexts
+    - SAUCE: apparmor4.0.0 [27/87]: LSM stacking v39: LSM: Remove unused
+      lsmcontext_init()
+    - SAUCE: apparmor4.0.0 [28/87]: LSM stacking v39: LSM: Improve logic in
+      security_getprocattr
+    - SAUCE: apparmor4.0.0 [29/87]: LSM stacking v39: LSM: secctx provider check
+      on release
+    - SAUCE: apparmor4.0.0 [31/87]: LSM stacking v39: LSM: Exclusive secmark usage
+    - SAUCE: apparmor4.0.0 [32/87]: LSM stacking v39: LSM: Identify which LSM
+      handles the context string
+    - SAUCE: apparmor4.0.0 [33/87]: LSM stacking v39: AppArmor: Remove the
+      exclusive flag
+    - SAUCE: apparmor4.0.0 [34/87]: LSM stacking v39: LSM: Add mount opts blob
+      size tracking
+    - SAUCE: apparmor4.0.0 [35/87]: LSM stacking v39: LSM: allocate mnt_opts blobs
+      instead of module specific data
+    - SAUCE: apparmor4.0.0 [36/87]: LSM stacking v39: LSM: Infrastructure
+      management of the key security blob
+    - SAUCE: apparmor4.0.0 [37/87]: LSM stacking v39: LSM: Infrastructure
+      management of the mnt_opts security blob
+    - SAUCE: apparmor4.0.0 [38/87]: LSM stacking v39: LSM: Correct handling of
+      ENOSYS in inode_setxattr
+    - SAUCE: apparmor4.0.0 [39/87]: LSM stacking v39: LSM: Remove lsmblob
+      scaffolding
+    - SAUCE: apparmor4.0.0 [40/87]: LSM stacking v39: LSM: Allow reservation of
+      netlabel
+    - SAUCE: apparmor4.0.0 [41/87]: LSM stacking v39: LSM: restrict
+      security_cred_getsecid() to a single LSM
+    - SAUCE: apparmor4.0.0 [42/87]: LSM stacking v39: Smack: Remove
+      LSM_FLAG_EXCLUSIVE
+    - SAUCE: apparmor4.0.0 [43/87]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0
+      [12/95]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [44/87]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [45/87]: add unpriviled user ns mediation
+    - SAUCE: apparmor4.0.0 [46/87]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [47/87]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [48/87]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [49/87]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [50/87]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/87]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/87]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/87]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [54/87]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [55/87]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [56/87]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [57/87]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [58/87]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [59/87]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [60/87]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [61/87]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [62/87]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [63/87]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [64/87]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [65/87] v6.8 prompt:fixup interruptible
+    - SAUCE: apparmor4.0.0 [69/87]: add io_uring mediation
+    - SAUCE: apparmor4.0.0 [70/87]: apparmor: fix oops when racing to retrieve
+      notification
+    - SAUCE: apparmor4.0.0 [71/87]: apparmor: fix notification header size
+    - SAUCE: apparmor4.0.0 [72/87]: apparmor: fix request field from a prompt
+      reply that denies all access
+    - SAUCE: apparmor4.0.0 [73/87]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+    - SAUCE: apparmor4.0.0 [74/87]: apparmor: cleanup attachment perm lookup to
+      use lookup_perms()
+    - SAUCE: apparmor4.0.0 [75/87]: apparmor: remove redundant unconfined check.
+    - SAUCE: apparmor4.0.0 [76/87]: apparmor: switch signal mediation to using
+      RULE_MEDIATES
+    - SAUCE: apparmor4.0.0 [77/87]: apparmor: ensure labels with more than one
+      entry have correct flags
+    - SAUCE: apparmor4.0.0 [78/87]: apparmor: remove explicit restriction that
+      unconfined cannot use change_hat
+    - SAUCE: apparmor4.0.0 [79/87]: apparmor: cleanup: refactor file_perm() to
+      provide semantics of some checks
+    - SAUCE: apparmor4.0.0 [80/87]: apparmor: carry mediation check on label
+    - SAUCE: apparmor4.0.0 [81/87]: apparmor: convert easy uses of unconfined() to
+      label_mediates()
+    - SAUCE: apparmor4.0.0 [82/87]: apparmor: add additional flags to extended
+      permission.
+    - SAUCE: apparmor4.0.0 [83/87]: apparmor: add support for profiles to define
+      the kill signal
+    - SAUCE: apparmor4.0.0 [84/87]: apparmor: fix x_table_lookup when stacking is
+      not the first entry
+    - SAUCE: apparmor4.0.0 [85/87]: apparmor: allow profile to be transitioned
+      when a user ns is created
+    - SAUCE: apparmor4.0.0 [86/87]: apparmor: add ability to mediate caps with
+      policy state machine
+    - SAUCE: apparmor4.0.0 [87/87]: fixup notify
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [66/87]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [67/87]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [68/87]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+  * Enable lowlatency settings in the generic kernel (LP: #2051342)
+    - [Config] enable low-latency settings
+  * hwmon: (coretemp) Fix core count limitation (LP: #2056126)
+    - hwmon: (coretemp) Introduce enum for attr index
+    - hwmon: (coretemp) Remove unnecessary dependency of array index
+    - hwmon: (coretemp) Replace sensor_device_attribute with device_attribute
+    - hwmon: (coretemp) Remove redundant pdata->cpu_map[]
+    - hwmon: (coretemp) Abstract core_temp helpers
+    - hwmon: (coretemp) Split package temp_data and core temp_data
+    - hwmon: (coretemp) Remove redundant temp_data->is_pkg_data
+    - hwmon: (coretemp) Use dynamic allocated memory for core temp_data
+  * Miscellaneous Ubuntu changes
+    - [Config] Disable CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION
+    - [Packaging] remove debian/scripts/misc/arch-has-odm-enabled.sh
+    - rebase on v6.8
+    - [Config] toolchain version update
+  * Miscellaneous upstream changes
+    - crypto: qat - add fatal error notify method
+  * Rebase on v6.8
+
+  [ Ubuntu: 6.8.0-15.15 ]
+
+  * noble/linux: 6.8.0-15.15 -proposed tracker (LP: #2055871)
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.8-rc7
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] Transition laptop-23.10 to generic"
+  * Rebase on v6.8-rc7
+
+  [ Ubuntu: 6.8.0-14.14 ]
+
+  * noble/linux: 6.8.0-14.14 -proposed tracker (LP: #2055551)
+  * Please change CONFIG_CONSOLE_LOGLEVEL_QUIET to 3 (LP: #2049390)
+    - [Config] reduce verbosity when booting in quiet mode
+  * linux: please move erofs.ko (CONFIG_EROFS for EROFS support) from linux-
+    modules-extra to linux-modules (LP: #2054809)
+    - UBUNTU [Packaging]: Include erofs in linux-modules instead of linux-modules-
+      extra
+  * linux: please move dmi-sysfs.ko (CONFIG_DMI_SYSFS for SMBIOS support) from
+    linux-modules-extra to linux-modules (LP: #2045561)
+    - [Packaging] Move dmi-sysfs.ko into linux-modules
+  * Enable CONFIG_INTEL_IOMMU_DEFAULT_ON and
+    CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON (LP: #1951440)
+    - [Config] enable Intel DMA remapping by default
+  * disable Intel DMA remapping by default (LP: #1971699)
+    - [Config] update tracking bug for CONFIG_INTEL_IOMMU_DEFAULT_ON
+  * Packaging resync (LP: #1786013)
+    - debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.02.29)
+  * Miscellaneous Ubuntu changes
+    - SAUCE: modpost: Replace 0-length array with flex-array member
+    - [packaging] do not include debian/ directory in a binary package
+    - [packaging] remove debian/stamps/keep-dir
+
+  [ Ubuntu: 6.8.0-13.13 ]
+
+  * noble/linux: 6.8.0-13.13 -proposed tracker (LP: #2055421)
+  * Packaging resync (LP: #1786013)
+    - debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.02.29)
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.8-rc6
+    - [Config] updateconfifs following v6.8-rc6 rebase
+  * Rebase on v6.8-rc6
+
+  [ Ubuntu: 6.8.0-12.12 ]
+
+  * linux-tools-common: man page of usbip[d] is misplaced (LP: #2054094)
+    - [Packaging] rules: Put usbip manpages in the correct directory
+  * Validate connection interval to pass Bluetooth Test Suite (LP: #2052005)
+    - Bluetooth: Enforce validation on max value of connection interval
+  * Turning COMPAT_32BIT_TIME off on s390x (LP: #2038583)
+    - [Config] Turn off 31-bit COMPAT on s390x
+  * Don't produce linux-source binary package (LP: #2043994)
+    - [Packaging] Add debian/control sanity check
+  * Don't produce linux-*-source-<version> package (LP: #2052439)
+    - [Packaging] Move linux-source package stub to debian/control.d
+    - [Packaging] Build linux-source package only for the main kernel
+  * Don't produce linux-*-cloud-tools-common, linux-*-tools-common and
+    linux-*-tools-host binary packages (LP: #2048183)
+    - [Packaging] Move indep tools package stubs to debian/control.d
+    - [Packaging] Build indep tools packages only for the main kernel
+  * Enable CONFIG_INTEL_IOMMU_DEFAULT_ON and
+    CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON (LP: #1951440)
+    - [Config] enable Intel DMA remapping by default
+  * disable Intel DMA remapping by default (LP: #1971699)
+    - [Config] update tracking bug for CONFIG_INTEL_IOMMU_DEFAULT_ON
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Transition laptop-23.10 to generic
+
+  [ Ubuntu: 6.8.0-11.11 ]
+
+  * noble/linux: 6.8.0-11.11 -proposed tracker (LP: #2053094)
+  * Miscellaneous Ubuntu changes
+    - [Packaging] riscv64: disable building unnecessary binary debs
+
+  [ Ubuntu: 6.8.0-10.10 ]
+
+  * noble/linux: 6.8.0-10.10 -proposed tracker (LP: #2053015)
+  * Miscellaneous Ubuntu changes
+    - [Packaging] add Rust build-deps for riscv64
+  * Miscellaneous upstream changes
+    - Revert "Revert "UBUNTU: [Packaging] temporarily disable Rust dependencies on
+      riscv64""
+
+  [ Ubuntu: 6.8.0-9.9 ]
+
+  * noble/linux: 6.8.0-9.9 -proposed tracker (LP: #2052945)
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] temporarily disable Rust dependencies on
+      riscv64"
+
+  [ Ubuntu: 6.8.0-8.8 ]
+
+  * noble/linux: 6.8.0-8.8 -proposed tracker (LP: #2052918)
+  * Miscellaneous Ubuntu changes
+    - [Packaging] riscv64: enable linux-libc-dev build
+    - v6.8-rc4 rebase
+  * Rebase on v6.8-rc4
+
+  [ Ubuntu: 6.8.0-7.7 ]
+
+  * noble/linux: 6.8.0-7.7 -proposed tracker (LP: #2052691)
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [01/87]: LSM stacking v39: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [02/87]: LSM stacking v39: SM: Infrastructure
+      management of the sock security
+    - SAUCE: apparmor4.0.0 [03/87]: LSM stacking v39: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [04/87]: LSM stacking v39: IMA: avoid label collisions
+      with stacked LSMs
+    - SAUCE: apparmor4.0.0 [05/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [06/87]: LSM stacking v39: LSM: Add lsmblob_to_secctx
+      hook
+    - SAUCE: apparmor4.0.0 [07/87]: LSM stacking v39: Audit: maintain an lsmblob
+      in audit_context
+    - SAUCE: apparmor4.0.0 [08/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [09/87]: LSM stacking v39: Audit: Update shutdown LSM
+      data
+    - SAUCE: apparmor4.0.0 [10/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [11/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [12/87]: LSM stacking v39: Audit: use an lsmblob in
+      audit_names
+    - SAUCE: apparmor4.0.0 [13/87]: LSM stacking v39: LSM: Create new
+      security_cred_getlsmblob LSM hook
+    - SAUCE: apparmor4.0.0 [14/87]: LSM stacking v39: Audit: Change context data
+      from secid to lsmblob
+    - SAUCE: apparmor4.0.0 [15/87]: LSM stacking v39: Netlabel: Use lsmblob for
+      audit data
+    - SAUCE: apparmor4.0.0 [16/87]: LSM stacking v39: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [17/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [18/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_lsmblob_to_secctx
+    - SAUCE: apparmor4.0.0 [19/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [20/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [21/87]: LSM stacking v39: LSM:
+      security_lsmblob_to_secctx module selection
+    - SAUCE: apparmor4.0.0 [22/87]: LSM stacking v39: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [23/87]: LSM stacking v39: Audit: Allow multiple
+      records in an audit_buffer
+    - SAUCE: apparmor4.0.0 [24/87]: LSM stacking v39: Audit: Add record for
+      multiple task security contexts
+    - SAUCE: apparmor4.0.0 [25/87]: LSM stacking v39: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [26/87]: LSM stacking v39: Audit: Add record for
+      multiple object contexts
+    - SAUCE: apparmor4.0.0 [27/87]: LSM stacking v39: LSM: Remove unused
+      lsmcontext_init()
+    - SAUCE: apparmor4.0.0 [28/87]: LSM stacking v39: LSM: Improve logic in
+      security_getprocattr
+    - SAUCE: apparmor4.0.0 [29/87]: LSM stacking v39: LSM: secctx provider check
+      on release
+    - SAUCE: apparmor4.0.0 [31/87]: LSM stacking v39: LSM: Exclusive secmark usage
+    - SAUCE: apparmor4.0.0 [32/87]: LSM stacking v39: LSM: Identify which LSM
+      handles the context string
+    - SAUCE: apparmor4.0.0 [33/87]: LSM stacking v39: AppArmor: Remove the
+      exclusive flag
+    - SAUCE: apparmor4.0.0 [34/87]: LSM stacking v39: LSM: Add mount opts blob
+      size tracking
+    - SAUCE: apparmor4.0.0 [35/87]: LSM stacking v39: LSM: allocate mnt_opts blobs
+      instead of module specific data
+    - SAUCE: apparmor4.0.0 [36/87]: LSM stacking v39: LSM: Infrastructure
+      management of the key security blob
+    - SAUCE: apparmor4.0.0 [37/87]: LSM stacking v39: LSM: Infrastructure
+      management of the mnt_opts security blob
+    - SAUCE: apparmor4.0.0 [38/87]: LSM stacking v39: LSM: Correct handling of
+      ENOSYS in inode_setxattr
+    - SAUCE: apparmor4.0.0 [39/87]: LSM stacking v39: LSM: Remove lsmblob
+      scaffolding
+    - SAUCE: apparmor4.0.0 [40/87]: LSM stacking v39: LSM: Allow reservation of
+      netlabel
+    - SAUCE: apparmor4.0.0 [41/87]: LSM stacking v39: LSM: restrict
+      security_cred_getsecid() to a single LSM
+    - SAUCE: apparmor4.0.0 [42/87]: LSM stacking v39: Smack: Remove
+      LSM_FLAG_EXCLUSIVE
+    - SAUCE: apparmor4.0.0 [43/87]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0
+      [12/95]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [44/87]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [45/87]: add unpriviled user ns mediation
+    - SAUCE: apparmor4.0.0 [46/87]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [47/87]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [48/87]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [49/87]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [50/87]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/87]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/87]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/87]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [54/87]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [55/87]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [56/87]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [57/87]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [58/87]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [59/87]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [60/87]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [61/87]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [62/87]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [63/87]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [64/87]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [65/87] v6.8 prompt:fixup interruptible
+    - SAUCE: apparmor4.0.0 [69/87]: add io_uring mediation
+    - SAUCE: apparmor4.0.0 [70/87]: apparmor: fix oops when racing to retrieve
+      notification
+    - SAUCE: apparmor4.0.0 [71/87]: apparmor: fix notification header size
+    - SAUCE: apparmor4.0.0 [72/87]: apparmor: fix request field from a prompt
+      reply that denies all access
+    - SAUCE: apparmor4.0.0 [73/87]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+    - SAUCE: apparmor4.0.0 [74/87]: apparmor: cleanup attachment perm lookup to
+      use lookup_perms()
+    - SAUCE: apparmor4.0.0 [75/87]: apparmor: remove redundant unconfined check.
+    - SAUCE: apparmor4.0.0 [76/87]: apparmor: switch signal mediation to using
+      RULE_MEDIATES
+    - SAUCE: apparmor4.0.0 [77/87]: apparmor: ensure labels with more than one
+      entry have correct flags
+    - SAUCE: apparmor4.0.0 [78/87]: apparmor: remove explicit restriction that
+      unconfined cannot use change_hat
+    - SAUCE: apparmor4.0.0 [79/87]: apparmor: cleanup: refactor file_perm() to
+      provide semantics of some checks
+    - SAUCE: apparmor4.0.0 [80/87]: apparmor: carry mediation check on label
+    - SAUCE: apparmor4.0.0 [81/87]: apparmor: convert easy uses of unconfined() to
+      label_mediates()
+    - SAUCE: apparmor4.0.0 [82/87]: apparmor: add additional flags to extended
+      permission.
+    - SAUCE: apparmor4.0.0 [83/87]: apparmor: add support for profiles to define
+      the kill signal
+    - SAUCE: apparmor4.0.0 [84/87]: apparmor: fix x_table_lookup when stacking is
+      not the first entry
+    - SAUCE: apparmor4.0.0 [85/87]: apparmor: allow profile to be transitioned
+      when a user ns is created
+    - SAUCE: apparmor4.0.0 [86/87]: apparmor: add ability to mediate caps with
+      policy state machine
+    - SAUCE: apparmor4.0.0 [87/87]: fixup notify
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [66/87]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [67/87]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [68/87]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+
+  [ Ubuntu: 6.8.0-6.6 ]
+
+  * noble/linux: 6.8.0-6.6 -proposed tracker (LP: #2052592)
+  * Packaging resync (LP: #1786013)
+    - debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.02.07)
+    - [Packaging] update variants
+  * FIPS kernels should default to fips mode (LP: #2049082)
+    - SAUCE: Enable fips mode by default, in FIPS kernels only
+  * Fix snapcraftyaml.yaml for jammy:linux-raspi (LP: #2051468)
+    - [Packaging] Remove old snapcraft.yaml
+  * Azure: Fix regression introduced in LP: #2045069 (LP: #2052453)
+    - hv_netvsc: Register VF in netvsc_probe if NET_DEVICE_REGISTER missed
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Remove in-tree abi checks
+    - [Packaging] drop abi files with clean
+    - [Packaging] Remove do_full_source variable (fixup)
+    - [Packaging] Remove update-dkms-versions and move dkms-versions
+    - [Config] updateconfigs following v6.8-rc3 rebase
+    - [packaging] rename to linux
+    - [packaging] rebase on v6.8-rc3
+    - [packaging] disable signing for ppc64el
+  * Rebase on v6.8-rc3
+
+  [ Ubuntu: 6.8.0-5.5 ]
+
+  * noble/linux-unstable: 6.8.0-5.5 -proposed tracker (LP: #2052136)
+  * Miscellaneous upstream changes
+    - Revert "mm/sparsemem: fix race in accessing memory_section->usage"
+
+  [ Ubuntu: 6.8.0-4.4 ]
+
+  * noble/linux-unstable: 6.8.0-4.4 -proposed tracker (LP: #2051502)
+  * Migrate from fbdev drivers to simpledrm and DRM fbdev emulation layer
+    (LP: #1965303)
+    - [Config] enable simpledrm and DRM fbdev emulation layer
+  * Miscellaneous Ubuntu changes
+    - [Config] toolchain update
+  * Miscellaneous upstream changes
+    - rust: upgrade to Rust 1.75.0
+
+  [ Ubuntu: 6.8.0-3.3 ]
+
+  * noble/linux-unstable: 6.8.0-3.3 -proposed tracker (LP: #2051488)
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [43/87]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0
+      [12/95]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [44/87]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [45/87]: add unpriviled user ns mediation
+    - SAUCE: apparmor4.0.0 [46/87]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [47/87]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [48/87]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [49/87]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [50/87]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/87]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/87]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/87]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [54/87]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [55/87]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [56/87]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [57/87]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [58/87]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [59/87]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [60/87]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [61/87]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [62/87]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [63/87]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [64/87]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [69/87]: add io_uring mediation
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+  * apparmor restricts read access of user namespace mediation sysctls to root
+    (LP: #2040194)
+    - SAUCE: apparmor4.0.0 [73/87]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+  * AppArmor spams kernel log with assert when auditing (LP: #2040192)
+    - SAUCE: apparmor4.0.0 [72/87]: apparmor: fix request field from a prompt
+      reply that denies all access
+  * apparmor notification files verification (LP: #2040250)
+    - SAUCE: apparmor4.0.0 [71/87]: apparmor: fix notification header size
+  * apparmor oops when racing to retrieve a notification (LP: #2040245)
+    - SAUCE: apparmor4.0.0 [70/87]: apparmor: fix oops when racing to retrieve
+      notification
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [66/87]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [67/87]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [68/87]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor4.0.0 [01/87]: LSM stacking v39: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [02/87]: LSM stacking v39: SM: Infrastructure
+      management of the sock security
+    - SAUCE: apparmor4.0.0 [03/87]: LSM stacking v39: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [04/87]: LSM stacking v39: IMA: avoid label collisions
+      with stacked LSMs
+    - SAUCE: apparmor4.0.0 [05/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [06/87]: LSM stacking v39: LSM: Add lsmblob_to_secctx
+      hook
+    - SAUCE: apparmor4.0.0 [07/87]: LSM stacking v39: Audit: maintain an lsmblob
+      in audit_context
+    - SAUCE: apparmor4.0.0 [08/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [09/87]: LSM stacking v39: Audit: Update shutdown LSM
+      data
+    - SAUCE: apparmor4.0.0 [10/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [11/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [12/87]: LSM stacking v39: Audit: use an lsmblob in
+      audit_names
+    - SAUCE: apparmor4.0.0 [13/87]: LSM stacking v39: LSM: Create new
+      security_cred_getlsmblob LSM hook
+    - SAUCE: apparmor4.0.0 [14/87]: LSM stacking v39: Audit: Change context data
+      from secid to lsmblob
+    - SAUCE: apparmor4.0.0 [15/87]: LSM stacking v39: Netlabel: Use lsmblob for
+      audit data
+    - SAUCE: apparmor4.0.0 [16/87]: LSM stacking v39: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [17/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [18/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_lsmblob_to_secctx
+    - SAUCE: apparmor4.0.0 [19/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [20/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [21/87]: LSM stacking v39: LSM:
+      security_lsmblob_to_secctx module selection
+    - SAUCE: apparmor4.0.0 [22/87]: LSM stacking v39: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [23/87]: LSM stacking v39: Audit: Allow multiple
+      records in an audit_buffer
+    - SAUCE: apparmor4.0.0 [24/87]: LSM stacking v39: Audit: Add record for
+      multiple task security contexts
+    - SAUCE: apparmor4.0.0 [25/87]: LSM stacking v39: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [26/87]: LSM stacking v39: Audit: Add record for
+      multiple object contexts
+    - SAUCE: apparmor4.0.0 [27/87]: LSM stacking v39: LSM: Remove unused
+      lsmcontext_init()
+    - SAUCE: apparmor4.0.0 [28/87]: LSM stacking v39: LSM: Improve logic in
+      security_getprocattr
+    - SAUCE: apparmor4.0.0 [29/87]: LSM stacking v39: LSM: secctx provider check
+      on release
+    - SAUCE: apparmor4.0.0 [30/87]: LSM stacking v39: LSM: Single calls in
+      socket_getpeersec hooks
+    - SAUCE: apparmor4.0.0 [31/87]: LSM stacking v39: LSM: Exclusive secmark usage
+    - SAUCE: apparmor4.0.0 [32/87]: LSM stacking v39: LSM: Identify which LSM
+      handles the context string
+    - SAUCE: apparmor4.0.0 [33/87]: LSM stacking v39: AppArmor: Remove the
+      exclusive flag
+    - SAUCE: apparmor4.0.0 [34/87]: LSM stacking v39: LSM: Add mount opts blob
+      size tracking
+    - SAUCE: apparmor4.0.0 [35/87]: LSM stacking v39: LSM: allocate mnt_opts blobs
+      instead of module specific data
+    - SAUCE: apparmor4.0.0 [36/87]: LSM stacking v39: LSM: Infrastructure
+      management of the key security blob
+    - SAUCE: apparmor4.0.0 [37/87]: LSM stacking v39: LSM: Infrastructure
+      management of the mnt_opts security blob
+    - SAUCE: apparmor4.0.0 [38/87]: LSM stacking v39: LSM: Correct handling of
+      ENOSYS in inode_setxattr
+    - SAUCE: apparmor4.0.0 [39/87]: LSM stacking v39: LSM: Remove lsmblob
+      scaffolding
+    - SAUCE: apparmor4.0.0 [40/87]: LSM stacking v39: LSM: Allow reservation of
+      netlabel
+    - SAUCE: apparmor4.0.0 [41/87]: LSM stacking v39: LSM: restrict
+      security_cred_getsecid() to a single LSM
+    - SAUCE: apparmor4.0.0 [42/87]: LSM stacking v39: Smack: Remove
+      LSM_FLAG_EXCLUSIVE
+    - SAUCE: apparmor4.0.0 [65/87] v6.8 prompt:fixup interruptible
+    - SAUCE: apparmor4.0.0 [74/87]: apparmor: cleanup attachment perm lookup to
+      use lookup_perms()
+    - SAUCE: apparmor4.0.0 [75/87]: apparmor: remove redundant unconfined check.
+    - SAUCE: apparmor4.0.0 [76/87]: apparmor: switch signal mediation to using
+      RULE_MEDIATES
+    - SAUCE: apparmor4.0.0 [77/87]: apparmor: ensure labels with more than one
+      entry have correct flags
+    - SAUCE: apparmor4.0.0 [78/87]: apparmor: remove explicit restriction that
+      unconfined cannot use change_hat
+    - SAUCE: apparmor4.0.0 [79/87]: apparmor: cleanup: refactor file_perm() to
+      provide semantics of some checks
+    - SAUCE: apparmor4.0.0 [80/87]: apparmor: carry mediation check on label
+    - SAUCE: apparmor4.0.0 [81/87]: apparmor: convert easy uses of unconfined() to
+      label_mediates()
+    - SAUCE: apparmor4.0.0 [82/87]: apparmor: add additional flags to extended
+      permission.
+    - SAUCE: apparmor4.0.0 [83/87]: apparmor: add support for profiles to define
+      the kill signal
+    - SAUCE: apparmor4.0.0 [84/87]: apparmor: fix x_table_lookup when stacking is
+      not the first entry
+    - SAUCE: apparmor4.0.0 [85/87]: apparmor: allow profile to be transitioned
+      when a user ns is created
+    - SAUCE: apparmor4.0.0 [86/87]: apparmor: add ability to mediate caps with
+      policy state machine
+    - SAUCE: apparmor4.0.0 [87/87]: fixup notify
+    - [Config] updateconfigs following v6.8-rc2 rebase
+
+  [ Ubuntu: 6.8.0-2.2 ]
+
+  * noble/linux-unstable: 6.8.0-2.2 -proposed tracker (LP: #2051110)
+  * Miscellaneous Ubuntu changes
+    - [Config] toolchain update
+    - [Config] enable Rust
+
+  [ Ubuntu: 6.8.0-1.1 ]
+
+  * noble/linux-unstable: 6.8.0-1.1 -proposed tracker (LP: #2051102)
+  * Miscellaneous Ubuntu changes
+    - [packaging] move to v6.8-rc1
+    - [Config] updateconfigs following v6.8-rc1 rebase
+    - SAUCE: export file_close_fd() instead of close_fd_get_file()
+    - SAUCE: cpufreq: s/strlcpy/strscpy/
+    - debian/dkms-versions -- temporarily disable zfs dkms
+    - debian/dkms-versions -- temporarily disable ipu6 and isvsc dkms
+    - debian/dkms-versions -- temporarily disable v4l2loopback
+
+  [ Ubuntu: 6.8.0-0.0 ]
+
+  * Empty entry.
+
+  [ Ubuntu: 6.7.0-7.7 ]
+
+  * noble/linux-unstable: 6.7.0-7.7 -proposed tracker (LP: #2049357)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+  * Miscellaneous Ubuntu changes
+    - [Packaging] re-enable signing for s390x and ppc64el
+
+  [ Ubuntu: 6.7.0-6.6 ]
+
+  * Empty entry.
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 27 Mar 2024 23:23:18 +0900
+
+linux-qcom (6.7.0-1012.12) jammy; urgency=medium
+
+  * [qcom alpha] Suppress noisy logs
+    - SAUCE: icnss2: supress noisy logs
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: update apply overlay application for pre-GA
+    - SAUCE: update graphics DT overlay to pre-GA
+    - SAUCE: update display DT overlay to pre-GA
+    - SAUCE: update camera overlay to pre-GA
+    - SAUCE: update bluetooth DT overlay to pre-GA
+    - SAUCE: update wlan DT overlay to pre-GA
+    - [config] Disable CONFIG_EFI_ZBOOT
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 21 Mar 2024 02:17:22 +0900
+
+linux-qcom (6.7.0-1011.11) jammy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: update wlan qclacld driver code to pre-GA
+    - SAUCE: update qcm6490 display code to pre-GA
+    - SAUCE: fix build warnings and errors in WLAN driver
+    - SAUCE: import qcm6490 graphics driver code
+    - SAUCE: dynamically allocate the kgsl-pool shrinker for kernel>=6.7
+    - SAUCE: change strtobool() to kstrtobool()
+    - SAUCE: update qcm6490 camera driver code to pre-GA
+    - SAUCE: use sizeof() instead of V4L2_SUBDEV_NAME_SIZE
+    - SAUCE: remove unused camera_banner
+    - Config: Update config after applying Pre-GA patches
+    - Packaging: Update module list after merging pre-ga patches
+
+  * Miscellaneous upstream changes
+    - QCLINUX: arm64: defconfig: qcom: Enable UVC/UAC related configs
+    - FROMGIT: scsi: ufs: qcom: Add support to Configure
+      PA_VS_CORE_CLK_40NS_CYCLES
+    - FROMLIST: iommu/arm-smmu: add ACTLR data and support for SC7280
+    - FROMLIST: iommu/arm-smmu: re-enable context caching in smmu reset operation
+    - PENDING: soundwire: qcom: add channel mask port configuration for soundwire
+      master
+    - PENDING: dt-bindings: soundwire: qcom: Document the port channel mask
+      property
+    - PENDING: arm64: dts: qcom: sc7280: add channel mask ports for tx soundwire
+    - FROMGIT: iio: adc: Add PM7325 PMIC7 ADC bindings
+    - PENDING: iris: fix LTR_COUNT configuration to firmware
+    - PENDING: i2c: i2c-qcom-geni: Add Multi EE feature support
+    - FROMLIST: dt-bindings: misc: qcom,dcc: Add the dtschema
+    - PENDING: ASoC: qcom: qcm6490: Fix clock freq for mi2s and tdm
+    - FROMLIST: misc: dcc: Add driver support for Data Capture and Compare
+      unit(DCC)
+    - PENDING: misc: fastrpc: Release PDR handle
+    - QCLINUX: arm64: configs: qcom: Enable TRACE_MMIO_ACCESS
+    - PENDING: arm64: dts: qcom: sc7280: Correct the compatible of dcc
+    - QCLINUX: arm64: defconfig: Enable DCC config
+    - QCLINUX: arm64: defconfig: qcom: Disable DEBUG_INFO_REDUCED
+    - PENDING: scsi: ufs: host: Bugfix evict key call in ufs host
+    - FROMLIST: soc: qcom: ice: support for hardware wrapped keys
+    - PENDING: iris: change the default value of HEADER_MODE config
+    - QCLINUX: ASoC: qcom: audio-pkt: avoid duplicate sysfs during ssr
+    - QCLINUX: ASoC: qcom: qdsp6: Add support to create CMA heap
+    - QCLINUX: soc: qcom: Implement a driver to write kaslr addr to imem
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Add reserved memory for audio ml
+    - QCLINUX: arm64: defconfig: Enable smp2p_sleepstate
+    - FROMGIT: dt-bindings: soc: qcom,aoss-qmp: document the SM8560 Always-On
+      Subsystem side channel
+    - FROMGIT: dt-bindings: interconnect: qcom-bwmon: document SM8650 BWMONs
+    - FROMGIT: dt-bindings: usb: qcom,dwc3: document the SM8560 SuperSpeed DWC3
+      USB controller
+    - FROMGIT: dt-bindings: dma: qcom,gpi: document the SM8650 GPI DMA Engine
+    - FROMGIT: dt-bindings: crypto: qcom,inline-crypto-engine: document the SM8650
+      ICE
+    - FROMGIT: dt-bindings: qcom,pdc: Add compatible for SM8550
+    - FROMGIT: arm64: dts: qcom: sm8550: add TRNG node
+    - FROMGIT: dt-bindings: qcom,pdc: document the SM8650 Power Domain Controller
+    - FROMGIT: dt-bindings: soc: qcom: pmic-glink: document SM8650 compatible
+    - FROMGIT: dt-bindings: crypto: qcom,prng: document SM8650
+    - FROMGIT: dt-bindings: firmware: qcom,scm: document SM8650 SCM Firmware
+      Interface
+    - FROMGIT: dt-bindings: iommu: arm,smmu: document the SM8650 System MMU
+    - FROMGIT: dt-bindings: thermal: qcom-tsens: document the SM8650 Temperature
+      Sensor
+    - FROMGIT: dt-bindings: clock: qcom: document the SM8650 TCSR Clock Controller
+    - FROMGIT: dt-bindings: clock: qcom: document the SM8650 General Clock
+      Controller
+    - FROMGIT: dt-bindings: clock: qcom: document the SM8650 Display Clock
+      Controller
+    - FROMGIT: dt-bindings: clock: qcom: document the SM8650 GPU Clock Controller
+    - FROMGIT: clk: qcom: add the SM8650 Global Clock Controller driver, part 1
+    - FROMGIT: clk: qcom: add the SM8650 Global Clock Controller driver, part 2
+    - FROMGIT: clk: qcom: add the SM8650 TCSR Clock Controller driver
+    - FROMGIT: clk: qcom: add the SM8650 Display Clock Controller driver
+    - FROMGIT: clk: qcom: add the SM8650 GPU Clock Controller driver
+    - FROMGIT: clk: qcom: rpmh: add clocks for SM8650
+    - FROMGIT: dt-bindings: interconnect: document the RPMh Network-On-Chip
+      Interconnect in Qualcomm SM8650 SoC
+    - FROMGIT: interconnect: qcom: introduce RPMh Network-On-Chip Interconnect on
+      SM8650 SoC
+    - FROMGIT: dt-bindings: cache: qcom,llcc: Document the SM8650 Last Level Cache
+      Controller
+    - FROMGIT: soc: qcom: llcc: Add configuration data for SM8650
+    - FROMGIT: drm/msm/dpu: enable smartdma on sm8350
+    - FROMGIT: drm/msm/dpu: enable SmartDMA on SM8450
+    - FROMGIT: drm/msm/dpu: populate SSPP scaler block version
+    - FROMGIT: drm/msm/dpu: Drop unused get_scaler_ver callback from SSPP
+    - FROMGIT: drm/msm/dpu: Drop unused qseed_type from catalog dpu_caps
+    - FROMGIT: drm/msm/dpu: drop the `id' field from DPU_HW_SUBBLK_INFO
+    - FROMGIT: drm/msm/dpu: drop the `smart_dma_priority' field from struct
+      dpu_sspp_sub_blks
+    - FROMGIT: drm/msm/dpu: deduplicate some (most) of SSPP sub-blocks
+    - FROMGIT: drm/msm/dpu: drop DPU_HW_SUBBLK_INFO macro
+    - FROMGIT: drm/msm/dpu: rewrite scaler and CSC presense checks
+    - FROMGIT: drm/msm/dpu: merge DPU_SSPP_SCALER_QSEED3, QSEED3LITE, QSEED4
+    - FROMGIT: drm/msm/gpu: drop duplicating VIG feature masks
+    - FROMGIT: dt-bindings: display: msm-dsi-phy-7nm: document the SM8650 DSI PHY
+    - FROMGIT: dt-bindings: display: msm-dsi-controller-main: document the SM8650
+      DSI Controller
+    - FROMGIT: dt-bindings: display: msm: document the SM8650 DPU
+    - FROMGIT: dt-bindings: display: msm: document the SM8650 Mobile Display
+      Subsystem
+    - FROMGIT: drm/msm/dpu: add support for SM8650 DPU
+    - FROMGIT: drm/msm: mdss: add support for SM8650
+    - FROMGIT: drm/msm: dsi: add support for DSI-PHY on SM8650
+    - FROMGIT: drm/msm: dsi: add support for DSI 2.8.0
+    - FROMGIT: dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: document the SM8650
+      QMP UFS PHY
+    - FROMGIT: dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: document the SM8650
+      QMP PCIe PHYs
+    - FROMGIT: dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy: document the
+      SM8650 QMP USB/DP Combo PHY
+    - FROMGIT: dt-bindings: phy: qcom,snps-eusb2: document the SM8650 Synopsys
+      eUSB2 PHY
+    - FROMGIT: phy: qcom: qmp-ufs: add QMP UFS PHY tables for SM8650
+    - FROMGIT: phy: qcom: qmp-pcie: add QMP PCIe PHY tables for SM8650
+    - FROMGIT: phy: qcom: qmp-combo: add QMP USB3/DP PHY tables for SM8650
+    - FROMGIT: dt-bindings: pinctrl: document the SM8650 Top Level Mode
+      Multiplexer
+    - FROMGIT: pinctrl: qcom: handle intr_target_reg wakeup_present/enable bits
+    - FROMGIT: pinctrl: qcom: sm8650-lpass-lpi: add SM8650 LPASS
+    - FROMGIT: pinctrl: qcom: Introduce the SM8650 Top Level Mode Multiplexer
+      driver
+    - FROMGIT: dt-bindings: arm: qcom,ids: Add SoC ID for SM8650
+    - FROMGIT: soc: qcom: socinfo: Add SM8650 SoC ID table entry
+    - FROMGIT: dt-bindings: arm: qcom: document SM8650 and the reference boards
+    - FROMGIT: arm64: dts: qcom: add initial SM8650 dtsi
+    - FROMGIT: arm64: dts: qcom: pm8550ve: make PMK8550VE SID configurable
+    - FROMGIT: arm64: dts: qcom: sm8650: add initial SM8650 MTP dts
+    - FROMGIT: arm64: dts: qcom: sm8650: add initial SM8650 QRD dts
+    - FROMGIT: arm64: dts: qcom: sm8650: add interconnect dependent device nodes
+    - FROMGIT: arm64: dts: qcom: sm8650-mtp: add interconnect dependent device
+      nodes
+    - FROMGIT: arm64: dts: qcom: sm8650-qrd: add interconnect dependent device
+      nodes
+    - FROMGIT: dt-bindings: clock: qcom: Document the SM8650 RPMH Clock Controller
+    - QCLINUX: ASoC: qcm6490: Initialize slimbus dais
+    - QCLINUX: arm64: dts: qcom: qcm6490-rb3: Add sound node for RB3 Gen2 nav mezz
+    - PENDING: videocc: enable HW_CTRL for mvs0 gdsc
+    - PENDING: iris: switch vcodec gdsc mode before handling vcodec clocks
+    - PENDING: arm64: dts: qcom: qcm6490-rb3g2: Add PCIe nodes
+    - QCLINUX: dt-bindings: pci: qps615: Add qps615 QCOM PCIe switch
+    - QCLINUX: arm64: dts: qcm6490-rb3: Add support for qps615 switch
+    - QCLINUX: pci: controller: misc: Add qcom qps615 switch driver
+    - QCLINUX: soc: qcom: Register a panic_notifier to cause wdt bite on panic
+    - PENDING: arm64: boot: dts: qcm6490: Add CMA heap for smcinvoke
+    - PENDING: soundwire: qcom: Add support for multiple sample rates
+    - PENDING: ASoC: codecs: lpass: Add macro and dcodec clock disable in suspend
+    - QCLINUX: arm64: defconfig: qcom: Enable CONFIG_SCHED_DEBUG
+    - PENDING: iris: fix bitrate mode setting to firmware
+    - PENDING: i2c: i2c-qcom-geni: Correct I2C TRE sequence
+    - QCLINUX: Revert "QCLINUX: soc: qcom: smcinvoke: Add hardcoded mem-buf API
+      values"
+    - PENDING: dt-bindings: phy: qcom,qmp: Add PCIe qcom,refclk-always-on property
+    - PENDING: phy: qcom-qmp-pcie: Add endpoint refclk control register offset
+    - BACKPORT: FROMGIT: dt-bindings: power: rpmpd: Update part number to X1E80100
+    - FROMGIT: pmdomain: qcom: rpmhpd: Update part number to X1E80100
+    - FROMGIT: dt-bindings: pinctrl: qcom: Add X1E80100 pinctrl
+    - FROMGIT: pinctrl: qcom: Add X1E80100 pinctrl driver
+    - BACKPORT: FROMGIT: dt-bindings: cache: qcom,llcc: Add X1E80100 compatible
+    - FROMGIT: dt-bindings: arm: qcom-soc: extend pattern for matching existing
+      SoCs
+    - FROMGIT: dt-bindings: arm: qcom-soc: extend pattern matching for X1E80100
+      SoC
+    - FROMGIT: dt-bindings: firmware: qcom,scm: document SCM on X1E80100 SoCs
+    - FROMGIT: dt-bindings: clock: qcom: Add X1E80100 GCC clocks
+    - FROMGIT: dt-bindings: clock: qcom-rpmhcc: Add RPMHCC bindings for X1E80100
+    - FROMGIT: clk: qcom: Add Global Clock controller (GCC) driver for X1E80100
+    - FROMGIT: clk: qcom: rpmh: Add support for X1E80100 rpmh clocks
+    - FROMGIT: dt-bindings: arm: cpus: Add qcom,oryon compatible
+    - FROMGIT: dt-bindings: arm: qcom: Document X1E80100 SoC and boards
+    - FROMGIT: dt-bindings: arm-smmu: Add compatible for X1E80100 SoC
+    - FROMGIT: dt-bindings: dma: qcom: gpi: add compatible for X1E80100
+    - FROMGIT: dt-bindings: interrupt-controller: qcom,pdc: document pdc on
+      X1E80100
+    - FROMGIT: dt-bindings: interconnect: Add Qualcomm X1E80100 SoC
+    - FROMGIT: interconnect: qcom: Add X1E80100 interconnect provider driver
+    - FROMGIT: arm64: dts: qcom: Add base X1E80100 dtsi and the QCP dts
+    - UPSTREAM: arm64: dts: qcom: x1e80100: Add Compute Reference Device
+    - QCLINUX: Add audio support for rb3gen2 video mezzanine boards
+    - PENDING: phy: qcom-qmp-pcie: Add support for keeping refclk always on
+    - QCLINUX: arm64: configs: qcom: Disable QCOM_FORCE_WDOG_BITE_ON_PANIC
+    - QCLINUX: arm64: configs: qcom: Enable QCOM_SOC_DEBUG driver
+    - Revert "QCLINUX: virt: gunyah: Write KASLR addr to IMEM"
+    - PENDING: Revert "PENDING: soc: qcom: smcinvoke: Add custom CMA heap support"
+    - PENDING: ASoC: qcom: q6dsp: Add support for multiple sample rates
+    - PENDING: i2c: i2c-qcom-geni: Add support to identify NACK in GSI Mode
+    - PENDING: pinctrl: qcom: lpass-lpi: Add suspend and resume runtime pm ops
+    - PENDING: arm64: dts: qcom: Enable support for pcie1 clocks on rb3 board
+    - QCLINUX: arm64: defconfig: qcom: Add support for NB7VPQ904M on AIM300
+    - QCLINUX: arm64: defconfig: qcom: Enable PCIe related configs
+    - QCLINUX: arm64: defconfig: qcom: Auto update configs
+    - QCLINUX: arm64: defconfig: qcom: Enable MODULE_SIG config
+    - PENDING: arm64: dts: qcom: Enable and update ipa to load gsi fw
+    - PENDING: drivers: smp2p: Add snapshot of smp2p_sleepstate driver
+    - PENDING: ARM: msm: Add support for smp2p_sleepstate
+    - QCLINUX: Revert "QCLINUX: arm64: dts: qcm6490-rb3: Add support for PM8008
+      PMIC"
+    - PENDING: firmware: shmbridge: Set dma capabilities 32bit by default
+    - PENDING: arm64: dts: qcom: qcm6490-addons: Enable smp2p-sleepstate
+    - PENDING: soc: qcom: qmi_encdec: out of bound check for input buffer
+    - PENDING: iris: configure work mode to STAGE 1 in CBR use case
+    - FROMLIST: arm64: dts: qcom: sc7280: Add additional MSI interrupts
+    - QCLINUX: soc: glink_altmode: Add API to notify hpd-irq & orientation
+    - PENDING: arm64: dts: qcom: sm8550: Add dma-coherent property
+    - QCLINUX: arm64: defconfig: qcom: Enable testmode config for QCM6490
+    - FROMGIT: arm64: dts: qcom: pm8550: drop PWM address/size cells
+    - FROMLIST: dt-bindings: arm: qcom: Document QCM8550, QCS8550 SoC and board
+    - FROMLIST: dt-bindings: arm: qcom,ids: add SoC ID for QCM8550 and QCS8550
+    - FROMLIST: soc: qcom: socinfo: add SoC Info support for QCM8550 and QCS8550
+      platform
+    - FROMGIT: ASoC: dt-bindings: qcom,sm8250: add SM8550 sound card
+    - FROMLIST: arm64: dts: qcom: qcm8550: introduce qcm8550 dtsi
+    - FROMLIST: arm64: dts: qcom: add base AIM300 dtsi
+    - FROMLIST: arm64: dts: qcom: aim300: add AIM300 AIoT
+    - FROMGIT: arm64: dts: qcom: sm8550: Add GPU nodes
+    - QCLINUX: arm64: defconfig: Add VM configs for qcm6490
+    - FROMLIST: misc: fastrpc: Mark all sessions as invalid in cb_remove
+    - PENDING: wil6210: Drop unicast sub frame if part of a multicast amsdu
+    - QCLINUX: arm64: defconfig: Add support for USB mouse&keyboard on AIM300
+    - QCLINUX: arm64: defconfig: Add qcom vm configs
+    - QCLINUX: dt-bindings: arm: qcom: Add X1E80100 addons support
+    - QCLINUX: arm64: defconfig: Add configs for Radar enumeration over USB
+    - QCLINUX: arm64: dts: qcm6490-idp: Add label for pmic-glink DT node
+    - PENDING: iris: replace dev_info with dev_dbg
+    - PENDING: iris: add support for dynamic resolution flag
+    - FROMLIST: media: v4l2-ctrls: add encoder maximum bitrate control
+    - QCLINUX: arm64: dts: Add x1e80100-addons CRD and QCP
+    - QCLINUX: arm64: defconfig: Enable X1E80100 base configs
+    - QCLINUX: arm64: defconfig: qcom: enable SM8550 GPUCC/CAMCC
+    - QCLINUX: arm64: dts: qcm6490-addons: Add label for pmic-glink DT node
+    - FROMGIT: soc: qcom: add ADSP PDCharger ULOG driver
+    - PENDING: soc: qcom: add snapshot for panel event notifier
+    - QCLINUX: arm64: defconfig: enable panel_event_notifier
+    - PENDING: iris: add new rate control type MBR for encoder
+    - QCLINUX: arm64: defconfig: qcom: enable flash led device
+    - PENDING: qcom: defconfig: enable module compilation of videoCC 8550
+    - PENDING: arm64: boot: dts: Add Support for nb7vpq904m on QCM6490 RB3
+    - QCLINUX: dt-bindings: arm: qcom: Add QCS8550 addons support
+    - PENDING:arm64:defconfig:add realtek config
+    - FROMLIST: phy: qcom: qmp-pcie: Update PCIe1 PHY settings for SM8550
+    - FROMLIST: arm64: dts: qcom: sm8550: Increase supported MSI interrupts
+    - FROMLIST: phy: qcom: qmp-pcie: Update PCIe0 PHY settings for SM8550
+    - FROMLIST: arm64: dts: qcom: aim300: Enable PCIe0 for WLAN
+    - PENDING: arm64: dts: qcom: aim300: Add smmu id for each BDF
+    - QCLINUX: arm64: dts: qcom: Add addons support for AIM300 AIOT
+    - QCLINUX: arm64: dts: qcom: aim300: Add support for qps615 switch
+    - PENDING: arm64: dts: qcom: qcs8550: overwrite video attribute in qcs8550
+    - PENDING: arm64: dts: qcom: sm8550: fix this issue of ICE HW generate key
+    - PENDING: arm64: dts: qcom: sm8550: add iris DT node
+    - FROMGIT: ufs: core: Add CPU latency QoS support for ufs driver
+    - QCLINUX: arm64: defconfig: Prune qcom_defconfig
+    - QCLINUX: arm64: defconfig: enable displayport config
+    - QCLINUX: arm64: dts: qcom: qcm6490-rb3: Add sound node for RB3 Gen2 video
+      mezz
+    - QCLINUX: dt-bindings: soc: qcom: Add secure buffer doc
+    - PENDING: slimbus: qcom-ngd-ctrl: Add null check for dma descriptor
+    - PENDING: slimbus: qcom-ngd-ctrl: Add timeout for wait operation
+    - QCLINUX: ASoC: codecs: msm-stub: Add input and output dapm widget
+    - QCLINUX: ASoC: qcom: qcm6490: Modify dapm routings for pinctrl widget
+    - QCLINUX: arm64: defconfig: qcom: Enable CEC support
+    - PENDING: arm64: dts: qcom: aim300: update PIL firmware path and name
+    - PENDING: arm64: dts: qcom: Disable the lpasscc node on qcm6490
+    - PENDING: dt-bindings: arm: qcom: Document rb5gen2-hdk board
+    - PENDING: arm64: dts: qcom: Add initial support for rb5gen2 SOM
+    - QCLINUX: arm64: dts: qcom: Add tz-log node
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Update the MI2S pinctrl name
+    - PENDING: arm64: dts: qcom: Add initial support for rb5gen2 HDK board
+    - QCLINUX: arm64: dts: qcom: Add board-id and msm-id for qcs8550-rb5gen2-HDK
+    - PENDING: iris: add to support max input buffer count
+    - PENDING: iris: update firmware path for SM8550
+    - FROMLIST: coresight: etm4x: Set skip_power_up in etm4_init_arch_data
+      function
+    - FROMGIT: coresight-tpdm: Remove the unnecessary lock
+    - FROMGIT: dt-bindings: arm: Add support for DSB element size
+    - FROMGIT: coresight-tpdm: Introduce TPDM subtype to TPDM driver
+    - FROMGIT: coresight-tpda: Add DSB dataset support
+    - FROMGIT: coresight-tpdm: Initialize DSB subunit configuration
+    - FROMGIT: coresight-tpdm: Add reset node to TPDM node
+    - FROMGIT: coresight-tpdm: Add nodes to set trigger timestamp and type
+    - FROMGIT: coresight-tpdm: Add node to set dsb programming mode
+    - PENDING: ASoC: dt-bindings: qcom,lpass-rx-macro: Document the rx_mclk muxsel
+      property
+    - PENDING: dt-bindings: soc: qcom: Add documentation for memory-dump
+    - FROMGIT: coresight-tpdm: Add nodes for dsb edge control
+    - FROMGIT: coresight-tpdm: Add nodes to configure pattern match output
+    - FROMGIT: coresight-tpdm: Add nodes for timestamp request
+    - FROMGIT: dt-bindings: arm: Add support for DSB MSR register
+    - FROMLIST: coresight: core: Add device name support
+    - FROMGIT: coresight-tpdm: Add nodes for dsb msr support
+    - FROMGIT: coresight-tpdm: Correct the property name of MSR number
+    - FROMLIST: coresight-tpdm: Optimize the store function of tpdm simple dataset
+    - FROMLIST: coresight-tpdm: Optimize the useage of tpdm_has_dsb_dataset
+    - FROMLIST: dt-bindings: arm: qcom,coresight-tpdm: Add support for CMB element
+      size
+    - FROMLIST: coresight-tpdm: Add CMB dataset support
+    - FROMLIST: coresight-tpda: Add support to configure CMB element
+    - FROMLIST: coresight-tpdm: Add support to configure CMB
+    - FROMLIST: coresight-tpdm: Add pattern registers support for CMB
+    - FROMLIST: coresight-tpdm: Add timestamp control register support for the CMB
+    - FROMLIST: dt-bindings: arm: qcom,coresight-tpdm: Add support for TPDM CMB
+      MSR register
+    - FROMLIST: coresight-tpdm: Add msr register support for CMB
+    - QCLINUX: arm64: defconfig: Align qcm6490 configs
+    - QCLINUX: arm64: defconfig: Enable zram for qcm6490
+    - QCLINUX: arm64: defconfig: Enable UIO for qcm6490
+    - PENDING: soundwire: stream: Skip asynchronous mode support
+    - PENDING: ASoC: codec: lpass-rx-macro: Add native sample rate headset
+      playback support
+    - PENDING: ASoC: qcom: q6dsp: Update channels and max rate for TDM
+    - QCLINUX: arm64: dts: qcom: qcm6490-rb3: Add MI2S Data1 line support
+    - QCLINUX: ASoC: qcom: qcm6490: Remove clock set in machine driver
+    - QCLINUX: ASoC: codecs: Update channels and sample rate for stub codec
+    - QCLINUX: drivers: soc: qcom: Add support for qcom secure buffer driver
+    - QCLINUX: drivers: dma-buf: heaps: Use hyp_assign_table implementation
+    - QCLINUX: arm64: configs: qcom: Enable secure buffer driver
+    - PENDING: ASoC: qcom: q6dsp: Add support for multiple sample rates
+    - PENDING: slimbus: qcom-ngd-ctrl: Reduce autosuspend delay to 100msec
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Disable drm gpu/gmu nodes
+    - PENDING: arm64: dts: qcom: qcm6490: Add vi-feedback dai-link for qcm6490 idp
+      & rb3 platform
+    - PENDING: ASoC: qcom: qcm6490: Add handling for WSA Codec DMA TX
+    - PENDING: dt-bindings: wsa883x: Document port mapping property
+    - PENDING: ASoC: wsa883x: Add Speaker Protection Support
+    - PENDING: soundwire: qcom: Update Port Reading logic from DT node
+    - PENDING: ASoC: wsa883x: Add Get temperature control
+    - FROMLIST: dt-bindings: arm: Add device-name in the coresight components
+    - PENDING: arm64: dts: qcom: Add label for timer node
+    - PENDING: Revert "silmbus: ngd: register controller after power up."
+    - PENDING: arm64: dts: qcom: qcm6490: Add rx-mclk and rx-npl clock support
+    - PENDING: soc: qcom: Add snapshot of memory dump driver
+    - PENDING: dt-bindings: soc: qcom: Add memory dump table bindings
+    - FROMLIST: soc: qcom: mdt_loader: Add Upperbounds check for program header
+      access
+    - PENDING: slimbus: qcom-ngd-ctrl: validate dma descriptor tx base address
+    - PENDING: gunyah: vm_mgr: Add lent memory
+    - PENDING: iris: fix sfr handling logic
+    - QCLINUX: arm64: defconfig: qcom: Enable USB Audio/MIDI driver
+    - PENDING: iris: fix logic to switch gdsc mode
+    - PENDING: slimbus: stream: Fix null pointer dereference of stream
+    - PENDING: slimbus: qcom-ngd-ctrl: Synchronize suspend/resume routine with
+      mutex
+    - PENDING: slimbus: qcom-ngd-ctrl: Return for channel disconnect/removal
+      during SSR
+    - PENDING: slimbus: qcom-ngd-ctrl: Handle race condition between SSR and qmi
+      request
+    - PENDING: slimbus: qcom-ngd-ctrl: Re-order platform driver registration
+    - PENDING: shmbridge/tz_log/smcinvoke: Adapt generic VMID/PERM entries
+    - PENDING: slimbus: qcom-ngd-ctrl: enable/disable ngd interrupt in runtime ops
+    - PENDING: slimbus: qcom-ngd-ctrl: Move qmi_handle_release to
+      QCOM_SSR_AFTER_SHUTDOWN
+    - PENDING: slimbus: qcom-ngd-ctrl: Avoid deadlock in SSR/PDR path
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Add the secure-buffer device
+    - PENDING: ASoC: codecs: lpass-va-macro: Add sleep after digitial unmute to
+      avoid pop issue
+    - PENDING: crypto: qce - Implement suspend/resume for crypto driver
+    - PENDING: slimbus: qcom-ngd-ctrl: Register QMI service once resources are
+      available
+    - PENDING: slimbus: qcom-ngd: Handle SSR and xfer message scenario
+    - UPSTREAM: regulator: qcom-rpmh: extend to support multiple linear voltage
+      ranges
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Add dummy msm_gpu node
+    - QCLINUX: arm64: dts: qcm6490-addons: Add nodes for memory dump
+    - QCLINUX: arm64: defconfig: Enable memory dump
+    - Revert "ASoC: codecs: wsa883x: make use of new mute_unmute_on_trigger flag"
+    - UPSTREAM: regulator: qcom-rpmh: add support for pm8010 regulators
+    - UPSTREAM: regulator: dt-bindings: qcom,rpmh: add compatible for pm8010
+    - PENDING: slimbus: qcom-ngd-ctrl: Return from cb if TX capability exchange
+      timeout
+    - QCLINUX: arm64: configs: qcom: Enable EFI_DISABLE_RUNTIME
+    - QCLINUX: ASoC: qcom: qdsp6: Cleanup APM during audio_pkt release
+    - PENDING: iris: fix min and max fps values in enum_frameintervals
+    - QCLINUX: arm64: dts: qcm6490-addons: Add label for typec-retimer
+    - PENDING: dt-bindings: soc: qcom: Replace "_" with "-" for memory dump
+    - FROMLIST: remoteproc: qcom: probe all child devices
+    - PENDING: misc: fastrpc: Fix memory corruption in DSP capabilities
+    - PENDING: iommu/arm-smmu-qcom: Fix use-after-free issue in qcom_smmu_create()
+    - QCLINUX: Revert "FROMLIST: sched/pelt: Introduce PELT multiplier"
+    - FROMLIST: sched/pelt: Introduce PELT multiplier
+    - FROMLIST: firmware/psci: Move psci_init_system_suspend() to late_initcall()
+    - FROMGIT: arm64: dts: qcom: sc7280: Add static properties to cryptobam
+    - QCLINUX: arm64: defconfig: Enable autosleep and wakelocks
+    - BACKPORT: FROMLIST: arm64: dts: qcom: sc7280: Add power-domains for cpuidle
+      states
+    - BACKPORT: FROMLIST: arm64: dts: qcom: sc7280: Update domain-idle-states for
+      cluster sleep
+    - PENDING: firmware: shmbridge: Defer probe if qcom_scm is not up
+    - Revert "PENDING: wil6210: Drop unicast sub frame if part of a multicast
+      amsdu"
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Sat, 16 Mar 2024 13:26:39 +0800
+
+linux-qcom (6.7.0-1010.10) jammy; urgency=medium
+
+  * Add camera driver
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 08 Feb 2024 10:48:07 +0900
+
+linux-qcom (6.7.0-1009.9) jammy; urgency=medium
+
+  * Enable display driver
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 07 Feb 2024 01:13:11 +0900
+
+linux-qcom (6.7.0-1008.8) jammy; urgency=medium
+
+  * Enable wlan driver
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 24 Jan 2024 14:53:34 +0900
+
+linux-qcom (6.7.0-1007.7) jammy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] sync
+    - Revert "arm64: dts: qcom: sc7280: Add power-domains for cpuidle states"
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Tue, 16 Jan 2024 13:01:33 +0900
+
+linux-qcom (6.7.0-1005.5) jammy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: drivers: dma-buf: qcom: adjust shrinker since api changed
+    - SAUCE: firmware: qcom_scm: fix building error
+    - [Config]: enable kconfigs in the qcom_addons of alpha release
+    - [Packaging]: update abi after kconfig is changed
+
+ -- Hui Wang <hui.wang@canonical.com>  Sat, 13 Jan 2024 18:58:00 +0800
+
+linux-qcom (6.7.0-1004.4) jammy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config]: Update annotations after merge alpha patches
+    - [Packaging]: Update abi
+
+  * Miscellaneous upstream changes
+    - FROMLIST: dma-heap: Add proper kref handling on dma-buf heaps
+    - FROMLIST: dma-heap: Provide accessors so that in-kernel drivers can allocate
+      dmabufs from specific heaps
+    - QCLINUX: arm64: defconfig: qcom: Enable POWERCAP, IDLE_INJECT and
+      CPU_IDLE_THERMAL
+    - PENDING: arm64: dts: qcom: qcm6490: add fastrpc nodes
+    - PENDING: misc: fastrpc: Avoid ref count increment for invoke context
+    - PENDING: dt-bindings: soc: qcom,apr: Add audio-pkt and spf-core compatible
+      support
+    - PENDING: ASoC: dt-bindings: Add compatible for wcd9370 codec
+    - PENDING: arm64: dts: qcom: qcm6490: Add memory region for audioPD
+    - FROMLIST: soc: qcom: llcc: Fix dis_cap_alloc and retain_on_pc configuration
+    - FROMLIST: arm64: dts: qcom: sc7280: Add capacity and DPC properties
+    - FROMLIST: iommu: Allow passing custom allocators to pgtable drivers
+    - FROMLIST: iommu: Extend LPAE page table format to support custom allocators
+    - QCLINUX: dt-bindings: qcom: Add IMEM nodes
+    - PENDING: clk: qcom: camcc-sc7280: Add parent dependency to all camera GDSCs
+    - PENDING: dt-bindings: media: Add sm8550 dt schema
+    - PENDING: MAINTAINERS: Add Qualcomm Iris video accelerator driver
+    - PENDING: iris: register video device to platform driver
+    - PENDING: iris: initialize power resources
+    - PENDING: iris: introduce state machine for iris core
+    - PENDING: iris: introduce shared queues for host and firmware communication
+    - PENDING: iris: add PIL functionality for video firmware
+    - PENDING: iris: introduce packetization layer for creating HFI packets
+    - PENDING: iris: add video processing unit(VPU) specific register handling
+    - PENDING: iris: introduce platform specific capabilities for core and
+      instance
+    - PENDING: iris: implement iris v4l2 file ops
+    - PENDING: iris: add handling for interrupt service routine(ISR) invoked by
+      hardware
+    - PENDING: iris: implement iris v4l2_ctrl_ops and prepare capabilities
+    - PENDING: iris: introduce memory pool for buffer management
+    - PENDING: iris: implement vb2_ops queue setup
+    - PENDING: iris: introduce and implement iris vb2 mem ops
+    - PENDING: iris: implement HFI to queue and release buffers
+    - PENDING: iris: add video hardware internal buffer count and size calculation
+    - PENDING: iris: implement internal buffer management
+    - PENDING: iris: introduce instance states
+    - PENDING: iris: implement iris v4l2 ioctl ops supported by decoder
+    - PENDING: iris: subscribe input and output properties to firmware
+    - PENDING: iris: subscribe src change and handle firmware responses
+    - PENDING: iris: implement vb2 streaming ops on capture and output planes
+    - QCLINUX: arm64: configs: qcom: Enable QCOM_WDT_CORE
+    - QCLINUX: arm64: configs: qcom: Enable PANIC ON BITE
+    - QCLINUX: soc: qcom: Add support for watchdog framework
+    - PENDING: iris: implement vb2 ops for buf_queue and firmware response
+    - PENDING: iris: add instance sub states and implement DRC and Drain sequence
+    - PENDING: iris: implement power management
+    - FROMLIST: docs: gunyah: Introduce Gunyah Hypervisor
+    - FROMLIST: dt-bindings: Add binding for gunyah hypervisor
+    - FROMLIST: gunyah: Common types and error codes for Gunyah hypercalls
+    - FROMLIST: arm-smmu: Add iommu support to share pgtable
+    - PENDING: iris: register video encoder device to platform driver
+    - FROMLIST: virt: gunyah: Add hypercalls to identify Gunyah
+    - FROMLIST: virt: gunyah: msgq: Add hypercalls to send and receive messages
+    - FROMLIST: mailbox: Add Gunyah message queue mailbox
+    - FROMLIST: gunyah: rsc_mgr: Add resource manager RPC core
+    - FROMLIST: gunyah: rsc_mgr: Add VM lifecycle RPC
+    - FROMLIST: gunyah: vm_mgr: Introduce basic VM Manager
+    - FROMLIST: gunyah: rsc_mgr: Add RPC for sharing memory
+    - FROMLIST: gunyah: vm_mgr: Add/remove user memory regions
+    - FROMLIST: gunyah: vm_mgr: Add ioctls to support basic non-proxy VM boot
+    - FROMLIST: samples: Add sample userspace Gunyah VM Manager
+    - FROMLIST: gunyah: rsc_mgr: Add platform ops on mem_lend/mem_reclaim
+    - FROMLIST: virt: gunyah: Add Qualcomm Gunyah platform ops
+    - FROMLIST: docs: gunyah: Document Gunyah VM Manager
+    - FROMLIST: virt: gunyah: Translate gh_rm_hyp_resource into gunyah_resource
+    - FROMLIST: gunyah: vm_mgr: Add framework for VM Functions
+    - FROMLIST: virt: gunyah: Add resource tickets
+    - FROMLIST: virt: gunyah: Add IO handlers
+    - FROMLIST: virt: gunyah: Add proxy-scheduled vCPUs
+    - FROMLIST: virt: gunyah: Add hypercalls for sending doorbell
+    - FROMLIST: virt: gunyah: Add irqfd interface
+    - FROMLIST: virt: gunyah: Add ioeventfd
+    - FROMLIST: MAINTAINERS: Add Gunyah hypervisor drivers section
+    - PENDING: iris: add platform specific instance capabilities for encoder
+    - PENDING: iris: implement iris v4l2 ioctl ops supported by encoder
+    - PENDING: iris: add vb2 streaming and buffer ops for encoder
+    - PENDING: iris: add power management for encoder
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Add node for gh_watchdog
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Add node for IMEM
+    - QCLINUX: dt-bindings: watchdog: Add qcom,gh-watchdog
+    - QCLINUX: virt: gunyah: Gunyah virtual watchdog driver
+    - QCLINUX: virt: gunyah: Write KASLR addr to IMEM
+    - QCLINUX: arm64: configs: qcom: Enable GH_VIRT_WATCHDOG
+    - PENDING: misc: fastrpc: Redesign remote heap management
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Disable wdt-sc7280
+    - PENDING: dt-bindings: media: Add qcm6490 dt schema
+    - PENDING: ASoC: dt-bindings: Add compatibles for qcm6490
+    - PENDING: arm64: dts: qcom: qcm6490: update venus node
+    - PENDING: qcom: defconfig: auto update of defconfig
+    - PENDING: qcom: defconfig: enable module compilation of iris
+    - PENDING: videocc: remove HW_CTRL from mvs0 gdsc
+    - FROMLIST: scsi: ufs: qcom: dt-bindings: Add SC7280 compatible string
+    - PENDING: iris: change interconnect name and correct few api
+    - PENDING: iris: add qcm6490 platform support
+    - PENDING: iris: add internal buffer calculation for iris2
+    - PENDING: iris: add power up/down sequence and bandwidth calculation
+    - FROMLIST: stm: class: Add MIPI OST protocol support
+    - PENDING: arm64: dts: qcom: qcm6490: Enable remoteprocs for RB3 Gen2
+    - FROMLIST: MAINTAINERS: Add the entry for DCC(Data Capture and Compare)
+      driver support
+    - PENDING: regulator: add a regulator driver for the PM8008 PMIC
+    - QCLINUX: drivers: regulator: Add snapshot of qpnp-lcdb regulator driver
+    - QCLINUX: mfd: introduce I2C PMIC controller
+    - FROMLIST: arm64: dts: qcom: sc7280: Add slimbus DT node
+    - QCLINUX: arm64: defconfig: disable display configs
+    - PENDING: ASoC: qcom: qcm6490: Add machine driver
+    - PENDING: arm64: dts: Increase min voltage of l1b and l10c rails
+    - QCLINUX: arm64: configs: Sort entries in qcom_addons
+    - QCLINUX: regulator: add debug control library
+    - QCLINUX: regulator: add proxy consumer library
+    - FROMGIT: arm64: dts: qcom: sc7280: add TRNG node
+    - QCLINUX: dt-bindings: arm: qcom: Add QCM6490 addons support
+    - QCLINUX: arm64: dts: qcom: qcm6490: Add addons support for RB3
+    - PENDING: arm64: qcom: dts: Enable pmk8350 RTC for qcm6490-idp
+    - PENDING: arm64: dts: qcom: sc7280: Add cti nodes
+    - PENDING: arm64: dts: qcom: qcm6490: overwrite video attribute in qcm6490
+    - QCLINUX: defconfig: Enable qcom-wled & qpnp-lcdb-regulator for qcm6490
+    - QCLINUX: pinctrl: qcom: spmi-gpio: Add PM7325b support
+    - PENDING: iris: update video firmware path for qcm6490
+    - QCLINUX: backlight: qcom-wled: Add support for PM7325b compatible
+    - QCLINUX: dt-bindings: backlight: qcom-wled: Add PM7325B support
+    - QCLINUX: arm64: dts: qcom: Add support for PM7325b PMIC
+    - QCLINUX: soc: qcom: apr: GPR support for audioreach solution
+    - PENDING: ASoC: codecs: lpass-macro: Add support for channel map mixer
+      control
+    - PENDING: ASoC: codecs: wcd937x: Add wcd937x codec driver
+    - PENDING: ASoC: dt-bindings: Add property to support cpu dai with dummy ops
+    - FROMLIST: dma-buf: heaps: Introduce cma_heap_add() for non-default CMA heap
+    - FROMLIST: drm/drm_mode_object: increase max objects to accommodate new color
+      props
+    - PENDING: arm64: qcom: dts: qcm6490-idp: Add BT node
+    - PENDING: misc: fastrpc: Fix DSP capabilities request
+    - PENDING: arm64: dts: qcom: qcm6490-idp: Add definition for three LEDs
+    - PENDING: arm64: qcom: dts: Support refgen regulator for qcm6490
+    - FROMGIT: scsi: ufs: ufs-sysfs: Expose UFS power info
+    - QCLINUX: defconfig: Enable LEICA regulator and proxy-consumer
+    - QCLINUX: defconfig: Enable refgen regulator for qcm6490
+    - PENDING: arm64: qcom: dts: qcm6490-rb3: Add BT node
+    - PENDING: arm64: dts: qcom: qcm6490-idp: add die temp ADC channel
+    - PENDING: defconfig: enable VADC, LPG and SPMI-TEMP-ALARM driver
+    - QCLINUX: ASoC: dt-bindings: qcom,spf-core-platform: Add msm audio mem for
+      spf core platform
+    - FROMLIST: iommu/arm-smmu: introduction of ACTLR for custom prefetcher
+      settings
+    - FROMLIST: iommu/arm-smmu: add ACTLR data and support for SM8550
+    - PENDING: ASoC: qcom: qdsp6: Add support for cpu dai with dummy ops
+    - PENDING: arm64: dts: qcom: qcm6490: Add gpr device tree node for ADSP
+    - QCLINUX: ASoC: qcom: qdsp6: Add spf-core, audio-pkt and msm-audio driver
+      support
+    - PENDING: arm64: dts: qcom: qcm6490-addons: Add shmbridge node
+    - PENDING: firmware: qcom: Add tz_log debug driver support
+    - PENDING: dt-bindings: firmware: Add tz-log doc
+    - PENDING: dt-bindings: soc: qcom: Add shmbridge doc
+    - PENDING: arm64: dts: qcom: qcm6490-addons: Add tz-log node
+    - PENDING: firmware: shmbridge: Add new driver support
+    - PENDING: arm64: dts: qcom: qcm6490: Add WSA codec macro for qcm6490 SoC
+    - PENDING: arm64: qcom: dts: qcm6490-rb3: Add remoteproc nodes
+    - QCLINUX: remoteproc: qcom: pas: disable auto boot for wpss
+    - PENDING: Bluetooth: hci_qca: Set BDA quirk bit if fwnode exists in DT
+    - PENDING: arm64: dts: qcom: qcm6490-idp: Add wcd9370 codec device tree node
+    - QCLINUX: arm64: dts: qcom: Add support for PM8008 PMIC
+    - QCLINUX: arm64: dts: qcom: Add PM7325b PMIC support for qcm6490-idp
+    - QCLINUX: arm64: defconfig: Enable QDSS configs
+    - QCLINUX: arm64: defconfig: qcom: Enable BT_RFCOMM
+    - QCLINUX: dt-bindings: arm: msm: Add remote debugger doc
+    - FROMLIST: usb: dwc3: qcom: Rename dwc3 platform_device reference
+    - FROMLIST: usb: dwc3: qcom: Merge resources from urs_usb device
+    - FROMLIST: usb: dwc3: Expose core driver as library
+    - FROMLIST: usb: dwc3: Override end of dwc3 memory resource
+    - FROMLIST: usb: dwc3: qcom: Add dwc3 core reference in driver state
+    - FROMLIST: usb: dwc3: qcom: Instantiate dwc3 core directly
+    - FROMLIST: usb: dwc3: qcom: Inline the qscratch constants
+    - QCLINUX: arm64: defconfig: qcom: Add USB defconfigs in qcom_defconfig
+    - FROMLIST: usb: dwc3: qcom: Flatten the Qualcomm dwc3 binding and
+      implementation
+    - FROMLIST: usb: dwc3: core: Register vendor hooks for dwc3-qcom
+    - FROMLIST: usb: dwc3: qcom: Enable autosuspend for host mode
+    - FROMLIST: usb: dwc3: core: Skip set_mode notification if cable is
+      disconnected
+    - PENDING: arm64: dts: qcom: qcm6490-idp: Enable pmic-glink and clients
+    - PENDING: arm64: dts: qcom: qcm6490: Add VMID for adsp mem heap
+    - FROMLIST: dt-bindings: input: qcom,pm8xxx-vib: add new SPMI vibrator module
+    - QCLINUX: drivers: char: add remote debugger driver
+    - PENDING: arm64: dts: qcom: qcm6490-idp: enable pon_key and pon_resin key
+    - QCLINUX: arm64: defconfig: Enable Audio support configs for QCM6490
+    - PENDING: arm64: dts: qcom: Flatten USB DT node for QCM6490
+    - PENDING: arm64: boot: dts: Add Type-c orientation support for QCM6490 IDP
+    - QCLINUX: arm64: dts: qcom: qcm6490: Add dt nodes for audio memory, audio-pkt
+      router and spf
+    - PENDING: arm64: dts: qcom: qcm6490-rb3: add die temp ADC channel
+    - PENDING: arm64: dts: qcom: qcm6490-rb3: Add definition for three LEDs
+    - PENDING: arm64: dts: qcom: qcm6490-idp: Add sound node for qcm6490 idp
+      platform
+    - PENDING: arm64: dts: qcom: qcm6490-rb3: Add sound node for RB3 Gen2
+    - PENDING: misc: fastrpc: Add support for unsigned PD
+    - PENDING: arm64: dts: qcm6490-idp: orientation-gpio support in pmic-glink
+    - QCLINUX: dt-bindings: qcom: Add msm stub audio codec documentation
+    - QCLINUX: arm64: dts: qcom: Add bindings for qcom-i2c-pmic and PM8008 devices
+    - FROMLIST: input: pm8xxx-vib: refactor to easily support new SPMI vibrator
+    - QCLINUX: arm64: defconfig: Add RDBG support for qcom_addons_debug
+    - PENDING: misc: fastrpc: Add static PD restart support
+    - PENDING: arm64: dts: qcom: qcm6490-rb3: Enable pmic-glink and clients
+    - QCLINUX: arm64: dts: qcm6490-rb3: Add support for PM8008 PMIC
+    - PENDING: dt-bindings: soc: qcom: Add mem-buf doc
+    - PENDING: drivers: soc: qcom: Add mem_buf driver support
+    - QCLINUX: arm64: configs: qcom: Enable QTEE_SHM_BRIDGE
+    - QCLINUX: arm64: configs: qcom: Enable CONFIG_QTI_TZ_LOG
+    - PENDING: firmware: shmbridge: Drop KP memory protection
+    - QCLINUX: arm64: configs: qcom: Enable PANIC_ON_OOPS
+    - FROMLIST: input: pm8xxx-vibrator: add new SPMI vibrator support
+    - PENDING: arm64: dts: qcom: qcm6490: Add mem-buf device nodes
+    - QCLINUX: arm64: defconfig: qcom: Enable mem-buf
+    - PENDING: dt-bindings: arm: msm: Add dmabuf heaps doc
+    - QCLINUX: drivers: dma-buf: Add QCOM Heaps
+    - FROMLIST: dt-bindings: iommu: Add Translation Buffer Unit bindings
+    - BACKPORT: FROMLIST: iommu/arm-smmu-qcom: Add support for TBUs
+    - FROMLIST: iommu/arm-smmu-qcom: Add Qualcomm TBU driver
+    - PENDING: iris: Fix copy of vb2 buf details to iris buf
+    - PENDING: misc: fastrpc: Pass proper arguments to scm call
+    - QCLINUX: drivers: dma-buf: heaps: Remove support for unused heaps and add
+      replacement for hyp_assign_table api
+    - QCLINUX: dt-bindings: arm: qcom: Add dt-bindings soft link for devicetree
+      constants
+    - FROMLIST: iommu/arm-smmu: Allow using a threaded handler for context
+      interrupts
+    - BACKPORT: FROMLIST: iommu/arm-smmu-qcom: Use a custom context fault handler
+      for sdm845
+    - PENDING: arm64: dts: qcom: sc7280: Add TBU support
+    - PENDING: arm64: dts: qcom: qcm6490-rb3: enable pon_key pon_resin & rtc
+    - QCLINUX: arm64: defconfig: qcom: Enable TBU support
+    - PENDING: iris: add support to set MAX input buffer count to firmware
+    - QCLINUX: dt-bindings: arm: qcom: Correct the symlink for
+      qcom_dma_heap_dt_constants
+    - QCLINUX: arm64: dts: qcom: qcm6490: Add dma-buf heaps support
+    - QCLINUX: arm64: defconfig: qcom: Enable QCOM Heaps
+    - PENDING: arm64: dts: qcom: qm6490-addons: Add smcinvoke node
+    - PENDING: dt-bindings: firmware: Add smcinvoke doc
+    - QCLINUX: defconfig: Enable ufs bsg node
+    - PENDING: iris: add cache management operation
+    - PENDING: dt-bindings: firmware: smcinvoke: Add memory-region
+    - PENDING: arm64: dts: qcm6490: Add memory-region for smcinvoke
+    - PENDING: dt-bindings: interconnect: Add QCOM_ICC_TAG_PERF_MODE macro
+    - FROMGIT: dt-bindings: phy: Add QMP UFS PHY comptible for SC7280
+    - PENDING: soc: qcom: Add smcinvoke driver support
+    - PENDING: soc: qcom: smcinvoke: Add custom CMA heap support
+    - PENDING: interconnect: qcom: Add support for PERF_MODE on RPMh targets
+    - QCLINUX: arm64: configs: qcom: Enable QCOM_SMCINVOKE
+    - PENDING: arm64: dts: qcom: qcm6490: Add dma-coherent property
+    - PENDING: interconnect: qcom: icc-rpmh: Add QoS config support
+    - PENDING: interconnect: qcom: sc7280: enable qos programming
+    - PENDING: arm64: dts: qcm6490-rb3: Increase min voltage of l1b & l10c rail
+    - PENDING: usb: dwc3: qcom: De-assert BCR upon resume
+    - PENDING: arm64: dts: qcom: sc7280: Add clocks for QOS programming
+    - QCLINUX: arm64: dts: qcom: qcm6490-idp: Add MI2S and TDM dai-link support
+    - PENDING: ASoC: qdsp6: q6apm: Add mi2s and tdm audio support
+    - PENDING: dt-bindings: Document the qcom,prmcc_clk property
+    - QCLINUX: ASoC: codecs: Add msm stub codec for audio usecase
+    - PENDING: iris: update output crop offset calculation for encoder
+    - QCLINUX: arm64: defconfig: qcom: Enable MSM_STUB config for QCM6490
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: add rdbg nodes
+    - FROMLIST: blk-crypto: add basic hardware-wrapped key support
+    - FROMLIST: blk-crypto: show supported key types in sysfs
+    - FROMLIST: blk-crypto: add ioctls to create and prepare hardware-wrapped keys
+    - PENDING: arm64: dts: qcom: sc7280: add ICE node
+    - QCLINUX: dt-bindings: pinctrl: qcom-pmic-gpio: Add pm7325b support
+    - FROMLIST: dt-bindings: crypto: ice: document the hwkm property
+    - PENDING: arm64: dts: qcm6490-rb3: Add LDO vibrator support
+    - QCLINUX: defconfig: Enable ldo vibrator driver config for qcm6490
+    - QCLINUX: arm64: defconfig: qcom: enable ICE driver
+    - QCLINUX: remoteproc: qcom: pas: Enable auto boot for wpss
+    - PENDING: ASoC: qcom: qdsp6: q6prm: Update the TDM clock id values
+    - QCLINUX: arm64: dts: qcom: qcm6490-rb3: Add MI2S and TDM dai-link support
+    - PENDING: misc: fastrpc: Add rpdev check in device_open
+    - FROMLIST: fscrypt: add support for hardware-wrapped keys
+    - FROMLIST: ice, ufs, mmc: use blk_crypto_key for program_key
+    - FROMLIST: qcom_scm: scm call for deriving a software secret
+    - FROMLIST: soc: qcom: ice: add hwkm support in ice
+    - FROMLIST: soc: qcom: ice: support for hardware wrapped keys
+    - QCLINUX: firmware: qcom_scm_addon: Add function qcom_scm_spin_cpu
+    - FROMLIST: ufs: core: support wrapped keys in ufs core
+    - FROMLIST: ufs: host: wrapped keys support in ufs qcom
+    - FROMGIT: dt-bindings: crypto: qcom-qce: document the SM8650 crypto engine
+    - FROMLIST: rpmsg: glink: smem: validate index before fifo read write
+    - PENDING: iris: update set bitrate api
+    - QCLINUX: arm64: defconfig: qcom: enable CRYPTO_USER_API
+    - FROMLIST: dt-bindings: crypto: qcom-qce: document the SC7280 crypto engine
+    - FROMLIST: arm64: dts: qcom: sc7280: add QCrypto nodes
+    - PENDING: iris: fix checks while handling the output buffers
+    - FROMLIST: qcom_scm: scm call for create, prepare and import keys
+    - FROMLIST: ufs: core: add support for generate, import and prepare keys
+    - FROMLIST: soc: qcom: support for generate, import and prepare key
+    - FROMLIST: ufs: host: support for generate, import and prepare key
+    - QCLINUX: arm64: defconfig: qcom: Enable KPROBE
+    - PENDING: iris: replace do_div with div64_u64
+    - PENDING: iris: fix rotation angle configuration to firmware
+    - QCLINUX: dt-bindings: arm: Add mezz board support on QCM6490
+    - PENDING: dt-bindings: arm: qcom: Add rb3gen2 mezzanine board support on
+      QCM6490
+    - PENDING: arm64: dts: qcom: Add qcm6490 rb3gen2 mezzanine board support
+    - FROMLIST: sched/pelt: Introduce PELT multiplier
+    - PENDING: wil6210: Drop plaintext frames on secure network
+    - PENDING: wil6210: check integrity of received AMSDU packets
+    - QCLINUX: arm64: dts: qcom: qcm6490: Add rb3gen2 board support
+    - QCLINUX: remoteproc: Panic on remoteproc crash
+    - QCLINUX: Add audio support for rb3gen2 vision mezzanine boards
+    - PENDING: arm64: dts: qcom: Flatten USB DT node on QCM6490 RB3 Platform
+    - PENDING: arm64: boot: dts: Add Type-c orientation support for QCM6490 RB3
+    - PENDING: firmware: qcom_scm: Make smcinvoke scm calls non-atomic
+    - PENDING: soc: qcom: ice: fix return value as per qcom-scm driver change
+    - PENDING: soc: qcom: ice: bugfix for HWKMv1 targets
+    - PENDING: firmware: qcom_smc-smc: Use qtee_shmbridge if available
+    - PENDING: include: linux: qtee_shmbridge: Add additional stubs
+    - PENDING: usb: dwc3: Add vendor hook for run_stop notification
+    - PENDING: arm64: dts: qcm6490-rb3: Update compatible string of pmic-glink
+    - PENDING: iris: add bit depth source change event for avc decoder
+    - QCLINUX: soc: qcom: smcinvoke: Add hardcoded mem-buf API values
+    - FROMLIST: soc: qcom: ice: bugfix for HWKMv1 targets
+    - FROMLIST: firmware: qcom_scm: scm call for deriving a software secret
+    - PENDING: firmware: qcom_scm: add FBE SCM calls with shmbridge
+    - QCLINUX: drivers: dmabuf: heaps: Remove alias for qcom system heap
+    - PENDING: iris: fix out of boundary hfi queue access
+    - QCLINUX: arm64: defconfig: Prune qcom_defconfig
+    - Revert "arm64: dts: qcom: sc7280: switch USB+DP QMP PHY to new style of
+      bindings"
+    - PENDING: arm64: dts: qcom: Add remote endpoints for QMP and USB nodes
+    - Revert "PENDING: wil6210: Drop plaintext frames on secure network"
+    - Revert "PENDING: wil6210: check integrity of received AMSDU packets"
+
+ -- Hui Wang <hui.wang@canonical.com>  Thu, 11 Jan 2024 14:22:29 +0800
+
+linux-qcom (6.7.0-1003.3) jammy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] remove helper scripts
+
+  * Miscellaneous Ubuntu changes
+    - Config: fix the environment for building in jammy
+    - [Packaging]: Update getabis for jammy
+    - [Config]: update annotations
+    - [Config]: Update config after cranky close
+    - [Packaging]: Update modules
+
+ -- Hui Wang <hui.wang@canonical.com>  Wed, 10 Jan 2024 22:28:08 +0800
+
+linux-qcom (6.7.0-1001.1) jammy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update Ubuntu.md
+    - [Packaging] update update.conf
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Init linux-qcom kernel creation
+    - Config: compose the init kconfig for linux-qcom
+    - [Packaing] adjust kernel modules
+    - Config: cleanup by running check-config
+
+  * Miscellaneous upstream changes
+    - QCLINUX: arm64: defconfig: Add qcom configs
+    - QCLINUX: arm64: dts: qcom: qcm6490: Add qcm6490 board support
+    - QCLINUX: arm64: defconfig: Enable dmabuf heaps for qcm6490
+    - QCLINUX: arm64: defconfig: qcom: Enable FTRACE
+    - QCLINUX: arm64: defconfig: Add DWC3_QCOM support in qcom_defconfig
+    - QCLINUX: arm64: defconfig: qcom: Enable zram
+    - QCLINUX: Revert "QCLINUX: arm64: dts: qcom: qcm6490: Add qcm6490 board
+      support"
+    - FROMLIST: arm64: dts: qcom: Add qcm6490 dts file
+    - QCLINUX: arm64: dts: qcom: Add qcm6490 addons support
+    - QCLINUX: arm64: dts: qcom: Add board-id and msm-id for QCM6490
+    - FROMLIST: dt-bindings: arm: qcom: Add QCM6490 IDP board
+    - PENDING: arm64: dts: qcom: Remove voltage vote support for UFS
+    - QCLINUX: arm64: defconfig: Enable Config for Phy and Controller
+    - PENDING: arm64: dts: qcm6490: Remove voltage voting for USB rails
+    - QCLINUX: arm64: dts: qcom: qcm6490: disable sdhc1 for ufs target
+    - QCLINUX: arm64: defconfig: Enable memory features
+    - FROMLIST: arm64: dts: qcom: sc7280: Add UFS nodes for sc7280 soc
+    - PENDING: arm64: dts: qcom: qcm6490: Add UFS nodes
+    - QCLINUX: arm64: defconfig: qcom: Enable SLAB_FREELIST_RANDOM
+    - QCLINUX: arm64: defconfig: qcom: Enable FORTIFY_SOURCE
+    - QCLINUX: arm64: dts: qcom: qcm6490: FIX: qcm6490 addons
+    - QCLINUX: arm64: defconfig: qcom: Disable DEVMEM and STRICT_DEVMEM
+    - PENDING: remoteproc: qcom: pas: Add ADSP, CDSP and WPSS support on SC7280
+      SoC
+    - PENDING: arm64: dts: qcom: qcm6490: Add ADSP, CDSP remoteproc support
+    - PENDING: arm64: dts: qcom: qcm6490: Update WPSS node to use PAS
+    - PENDING: dt-bindings: remoteproc: qcom: Add SC7280 ADSP, CDSP and WPSS
+      support
+    - PENDING: arm64: dts: qcom: qcm6490: Enable ADSP, CDSP, MPSS and WPSS support
+    - QCLINUX: arm64: defconfig: qcom: Enable SECURITY_SELINUX and
+      SECURITY_NETWORK
+    - QCLINUX: arm64: defconfig: qcom: Enable HARDENED_USERCOPY
+    - QCLINUX: arm64: defconfig: qcom: Enable SLAB_FREELIST_HARDENED
+    - QCLINUX: arm64: defconfig: qcom: Enable ARM64_SW_TTBR0_PAN
+    - PENDING: clk: qcom: gcc: Enable the force mem core for UFS ICE clock
+    - PENDING: arm64: dts: qcom: qcm6490: Add gpio-reserved-ranges
+    - FROMGIT: misc: fastrpc: Free DMA handles for RPC calls with no arguments
+    - PENDING: dt-bindings: clock: Add "qcom,adsp-skip-pll" property
+    - PENDING: clk: qcom: lpassaudiocc: Add support to skip PLL configuration
+    - QCLINUX: firmware: qcom_scm: provisioning addon scm call
+    - QCLINUX: arm64: defconfig: qcom: Auto update configs
+    - PENDING: dt-bindings: arm: qcom: Add QCM6490 RB3 board
+    - PENDING: arm64: dts: qcom: Add qcm6490 rb3 support
+    - QCLINUX: arm64: dts: qcom: Add board-id and msm-id for qcm6490-rb3
+    - PENDING: arm64: dts: qcm6490: Update the protected clocks for QCM6490
+    - QCLINUX: arm64: defconfig: Add clock controller configs for SC7280
+    - QCLINUX: arm64: configs: qcom: Disable CONFIG_QCOM_WDT
+    - FROMGIT: misc: fastrpc: Clean buffers on remote invocation failures
+    - QCLINUX: arm64: configs: qcom: Enable QCOM_SCM_ADDON
+    - QCLINUX: arm64: defconfig: qcom: Enable UCLAMP and SCHEDSTATS
+    - PENDING: arm64: dts: qcom: Remove voltage vote support for UFS
+    - PENDING: arm64: dts: qcm6490-rb3: Remove voltage voting for USB rails
+    - PENDING: arm64: dts: qcom: Add UFS nodes for qcm6490-rb3
+    - PENDING: arm64: dts: qcom: qcm6490: add phandle & modify adsp node
+    - PENDING: arm64: dts: qcom: sc7280: Add interconnect paths to UFSHC
+    - QCLINUX: arm64: defconfig: qcom: Enable bootconfig
+    - PENDING: arm64: dts: qcom: qcm6490: update memory map
+    - FROMLIST: arm64: dts: qcom: Update memorymap for qcm6490
+    - QCLINUX: arm64: dts: qcom: qcm6490: disable video fw attribute in qcm6490
+
+ -- Hui Wang <hui.wang@canonical.com>  Fri, 15 Dec 2023 08:12:34 +0800
+
+linux-qcom (6.7.0-1000.0) jammy; urgency=medium
+
+  * Init creation of linux-qcom
+
+ -- Hui Wang <hui.wang@canonical.com>  Wed, 13 Dec 2023 21:37:16 +0800
+
+linux-unstable (6.7.0-3.3) noble; urgency=medium
+
+  * noble/linux-unstable: 6.7.0-3.3 -proposed tracker (LP: #2046060)
+
+  * enable CONFIG_INTEL_TDX_HOST in linux >= 6.7 for noble (LP: #2046040)
+    - [Config] enable CONFIG_INTEL_TDX_HOST
+
+  * linux tools packages for derived kernels refuse to install simultaneously
+    due to libcpupower name collision (LP: #2035971)
+    - [Packaging] Statically link libcpupower into cpupower tool
+
+  * make lazy RCU a boot time option (LP: #2045492)
+    - SAUCE: rcu: Provide a boot time parameter to control lazy RCU
+
+  * Build failure if run in a console (LP: #2044512)
+    - [Packaging] Fix kernel module compression failures
+
+  * Turning COMPAT_32BIT_TIME off on arm64 (64k & derivatives) (LP: #2038582)
+    - [Config] y2038: Turn off COMPAT and COMPAT_32BIT_TIME on arm64 64k
+
+  * Turning COMPAT_32BIT_TIME off on riscv64 (LP: #2038584)
+    - [Config] y2038: Disable COMPAT_32BIT_TIME on riscv64
+
+  * Turning COMPAT_32BIT_TIME off on ppc64el (LP: #2038587)
+    - [Config] y2038: Disable COMPAT and COMPAT_32BIT_TIME on ppc64le
+
+  * [UBUNTU 23.04] Kernel config option missing for s390x PCI passthrough
+    (LP: #2042853)
+    - [Config] CONFIG_VFIO_PCI_ZDEV_KVM=y
+
+  * back-out zstd module compression automatic for backports (LP: #2045593)
+    - [Packaging] make ZSTD module compression conditional
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Remove do_full_source variable
+    - [Packaging] Remove obsolete config handling
+    - [Packaging] Remove support for sub-flavors
+    - [Packaging] Remove old linux-libc-dev version hack
+    - [Packaging] Remove obsolete scripts
+    - [Packaging] Remove README.inclusion-list
+    - [Packaging] make $(stampdir)/stamp-build-perarch depend on build-arch
+    - [Packaging] Enable rootless builds
+    - [Packaging] Allow to run debian/rules without (fake)root
+    - [Packaging] remove unneeded trailing slash for INSTALL_MOD_PATH
+    - [Packaging] override KERNELRELEASE instead of KERNELVERSION
+    - [Config] update toolchain versions in annotations
+    - [Packaging] drop useless linux-doc
+    - [Packaging] scripts: Rewrite insert-ubuntu-changes in Python
+    - [Packaging] enable riscv64 builds
+    - [Packaging] remove the last sub-flavours bit
+    - [Packaging] check debian.env to determine do_libc_dev_package
+    - [Packaging] remove debian.*/variants
+    - [Packaging] remove do_libc_dev_package variable
+    - [Packaging] move linux-libc-dev.stub to debian/control.d/
+    - [Packaging] Update check to build linux-libc-dev to the source package name
+    - [Packaging] rules: Remove startnewrelease target
+    - [Packaging] Remove debian/commit-templates
+    - [Config] update annotations after rebase to v6.7-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.7-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 11 Dec 2023 15:56:11 +0100
+
+linux-unstable (6.7.0-2.2) noble; urgency=medium
+
+  * noble/linux-unstable: 6.7.0-2.2 -proposed tracker (LP: #2045107)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] re-enable Rust
+    - [Config] enable Rust in annotations
+    - [Packaging] Remove do_enforce_all variable
+    - [Config] disable Softlogic 6x10 capture card driver on armhf
+    - [Packaging] disable Rust support
+    - [Config] update annotations after rebase to v6.7-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.7-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 29 Nov 2023 07:51:17 +0100
+
+linux-unstable (6.7.0-1.1) noble; urgency=medium
+
+  * noble/linux-unstable: 6.7.0-1.1 -proposed tracker (LP: #2044069)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update annotations scripts
+    - [Packaging] update helper scripts
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations after rebase to v6.7-rc2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.7-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 21 Nov 2023 10:45:24 +0100
+
+linux-unstable (6.7.0-0.0) noble; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 21 Nov 2023 07:26:46 +0100
+
+linux-unstable (6.6.0-12.12) noble; urgency=medium
+
+  * noble/linux-unstable: 6.6.0-12.12 -proposed tracker (LP: #2043664)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] temporarily disable zfs dkms
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 16 Nov 2023 10:20:26 +0100
+
+linux-unstable (6.6.0-11.11) noble; urgency=medium
+
+  * noble/linux-unstable: 6.6.0-11.11 -proposed tracker (LP: #2043480)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+    - [Packaging] resync update-dkms-versions helper
+    - [Packaging] update variants
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.11.14)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move to Noble
+    - [Config] toolchain version update
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 15 Nov 2023 14:50:40 +0100
+
+linux-unstable (6.6.0-10.10) noble; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-10.10 -proposed tracker (LP: #2043088)
+
+  * Bump arm64's CONFIG_NR_CPUS to 512 (LP: #2042897)
+    - [Config] Bump CONFIG_NR_CPUS to 512 for arm64
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Include a note for the NR_CPUS setting on riscv64
+    - SAUCE: apparmor4.0.0 [83/83]: Fix inode_init for changed prototype
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 09 Nov 2023 12:05:11 +0200
+
+linux-unstable (6.6.0-9.9) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-9.9 -proposed tracker (LP: #2041852)
+
+  * Switch IMA default hash to sha256 (LP: #2041735)
+    - [Config] Switch IMA_DEFAULT_HASH from sha1 to sha256
+
+  * apparmor restricts read access of user namespace mediation sysctls to root
+    (LP: #2040194)
+    - SAUCE: apparmor4.0.0 [82/82]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+
+  * AppArmor spams kernel log with assert when auditing (LP: #2040192)
+    - SAUCE: apparmor4.0.0 [81/82]: apparmor: fix request field from a prompt
+      reply that denies all access
+
+  * apparmor notification files verification (LP: #2040250)
+    - SAUCE: apparmor4.0.0 [80/82]: apparmor: fix notification header size
+
+  * apparmor oops when racing to retrieve a notification (LP: #2040245)
+    - SAUCE: apparmor4.0.0 [79/82]: apparmor: fix oops when racing to retrieve
+      notification
+
+  * Disable restricting unprivileged change_profile by default, due to LXD
+    latest/stable not yet compatible with this new apparmor feature
+    (LP: #2038567)
+    - SAUCE: apparmor4.0.0 [78/82]: apparmor: Make
+      apparmor_restrict_unprivileged_unconfined opt-in
+
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [01/82]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [02/82]: rename SK_CTX() to aa_sock and make it an
+      inline fn
+    - SAUCE: apparmor4.0.0 [03/82]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [04/82]: add user namespace creation mediation
+    - SAUCE: apparmor4.0.0 [05/82]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [06/82]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [07/82]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [08/82]: Stacking v38: LSM: Identify modules by more
+      than name
+    - SAUCE: apparmor4.0.0 [09/82]: Stacking v38: LSM: Add an LSM identifier for
+      external use
+    - SAUCE: apparmor4.0.0 [10/82]: Stacking v38: LSM: Identify the process
+      attributes for each module
+    - SAUCE: apparmor4.0.0 [11/82]: Stacking v38: LSM: Maintain a table of LSM
+      attribute data
+    - SAUCE: apparmor4.0.0 [12/82]: Stacking v38: proc: Use lsmids instead of lsm
+      names for attrs
+    - SAUCE: apparmor4.0.0 [13/82]: Stacking v38: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [14/82]: Stacking v38: LSM: Infrastructure management
+      of the sock security
+    - SAUCE: apparmor4.0.0 [15/82]: Stacking v38: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [16/82]: Stacking v38: LSM: provide lsm name and id
+      slot mappings
+    - SAUCE: apparmor4.0.0 [17/82]: Stacking v38: IMA: avoid label collisions with
+      stacked LSMs
+    - SAUCE: apparmor4.0.0 [18/82]: Stacking v38: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [19/82]: Stacking v38: LSM: Use lsmblob in
+      security_kernel_act_as
+    - SAUCE: apparmor4.0.0 [20/82]: Stacking v38: LSM: Use lsmblob in
+      security_secctx_to_secid
+    - SAUCE: apparmor4.0.0 [21/82]: Stacking v38: LSM: Use lsmblob in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [22/82]: Stacking v38: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [23/82]: Stacking v38: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [24/82]: Stacking v38: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [25/82]: Stacking v38: LSM: Use lsmblob in
+      security_cred_getsecid
+    - SAUCE: apparmor4.0.0 [26/82]: Stacking v38: LSM: Specify which LSM to
+      display
+    - SAUCE: apparmor4.0.0 [28/82]: Stacking v38: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [29/82]: Stacking v38: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [30/82]: Stacking v38: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [31/82]: Stacking v38: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [32/82]: Stacking v38: LSM: security_secid_to_secctx in
+      netlink netfilter
+    - SAUCE: apparmor4.0.0 [33/82]: Stacking v38: NET: Store LSM netlabel data in
+      a lsmblob
+    - SAUCE: apparmor4.0.0 [34/82]: Stacking v38: binder: Pass LSM identifier for
+      confirmation
+    - SAUCE: apparmor4.0.0 [35/82]: Stacking v38: LSM: security_secid_to_secctx
+      module selection
+    - SAUCE: apparmor4.0.0 [36/82]: Stacking v38: Audit: Keep multiple LSM data in
+      audit_names
+    - SAUCE: apparmor4.0.0 [37/82]: Stacking v38: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [38/82]: Stacking v38: LSM: Add a function to report
+      multiple LSMs
+    - SAUCE: apparmor4.0.0 [39/82]: Stacking v38: Audit: Allow multiple records in
+      an audit_buffer
+    - SAUCE: apparmor4.0.0 [40/82]: Stacking v38: Audit: Add record for multiple
+      task security contexts
+    - SAUCE: apparmor4.0.0 [41/82]: Stacking v38: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [42/82]: Stacking v38: Audit: Add record for multiple
+      object contexts
+    - SAUCE: apparmor4.0.0 [43/82]: Stacking v38: netlabel: Use a struct lsmblob
+      in audit data
+    - SAUCE: apparmor4.0.0 [44/82]: Stacking v38: LSM: Removed scaffolding
+      function lsmcontext_init
+    - SAUCE: apparmor4.0.0 [45/82]: Stacking v38: AppArmor: Remove the exclusive
+      flag
+    - SAUCE: apparmor4.0.0 [46/82]: combine common_audit_data and
+      apparmor_audit_data
+    - SAUCE: apparmor4.0.0 [47/82]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [48/82]: rename audit_data->label to
+      audit_data->subj_label
+    - SAUCE: apparmor4.0.0 [49/82]: pass cred through to audit info.
+    - SAUCE: apparmor4.0.0 [50/82]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/82]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/82]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/82]: cache buffers on percpu list if there is lock
+      contention
+    - SAUCE: apparmor4.0.0 [54/82]: advertise availability of exended perms
+    - SAUCE: apparmor4.0.0 [56/82]: cleanup: provide separate audit messages for
+      file and policy checks
+    - SAUCE: apparmor4.0.0 [57/82]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [58/82]: prompt - ref count pdb
+    - SAUCE: apparmor4.0.0 [59/82]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [60/82]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [61/82]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [62/82]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [63/82]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [64/82]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [65/82]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [66/82]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [67/82]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [68/82]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [69/82]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [74/82]: advertise disconnected.path is available
+    - SAUCE: apparmor4.0.0 [75/82]: fix invalid reference on profile->disconnected
+    - SAUCE: apparmor4.0.0 [76/82]: add io_uring mediation
+    - SAUCE: apparmor4.0.0 [77/82]: apparmor: Fix regression in mount mediation
+
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [70/82]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [71/82]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [72/82]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+    - SAUCE: apparmor4.0.0 [73/82]: userns - allow restricting unprivileged
+      change_profile
+
+  * LSM stacking and AppArmor for 6.2: additional fixes (LP: #2017903) // update
+    apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [55/82]: fix profile verification and enable it
+
+  * udev fails to make prctl() syscall with apparmor=0 (as used by maas by
+    default) (LP: #2016908) // update apparmor and LSM stacking patch set
+    (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [27/82]: Stacking v38: Fix prctl() syscall with
+      apparmor=0
+
+  * Miscellaneous Ubuntu changes
+    - [Config] SECURITY_APPARMOR_RESTRICT_USERNS=y
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 03 Nov 2023 11:59:12 +0100
+
+linux-unstable (6.6.0-8.8) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-8.8 -proposed tracker (LP: #2040243)
+
+  * Miscellaneous Ubuntu changes
+    - abi: gc reference to phy-rtk-usb2/phy-rtk-usb3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 24 Oct 2023 10:55:34 +0200
+
+linux-unstable (6.6.0-7.7) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-7.7 -proposed tracker (LP: #2040147)
+
+  * test_021_aslr_dapper_libs from ubuntu_qrt_kernel_security failed on K-5.19 /
+    J-OEM-6.1 / J-6.2 AMD64 (LP: #1983357)
+    - [Config]: set ARCH_MMAP_RND_{COMPAT_, }BITS to the maximum
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs following v6.6-rc7 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 23 Oct 2023 11:51:14 +0200
+
+linux-unstable (6.6.0-6.6) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-6.6 -proposed tracker (LP: #2039780)
+
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.6-rc6
+    - [Config] updateconfigs following v6.6-rc6 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.6-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 19 Oct 2023 12:09:16 +0200
+
+linux-unstable (6.6.0-5.5) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-5.5 -proposed tracker (LP: #2038899)
+
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.6-rc5
+    - [Config] updateconfigs following v6.6-rc5 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.6-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 10 Oct 2023 11:18:41 +0200
+
+linux-unstable (6.6.0-4.4) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-4.4 -proposed tracker (LP: #2038423)
+
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.6-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.6-rc4
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 04 Oct 2023 11:16:25 +0200
+
+linux-unstable (6.6.0-3.3) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-3.3 -proposed tracker (LP: #2037622)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs following v6.6-rc3 rebase
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: enforce rust availability only on x86_64"
+    - arm64: rust: Enable Rust support for AArch64
+    - arm64: rust: Enable PAC support for Rust.
+    - arm64: Restrict Rust support to little endian only.
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 28 Sep 2023 10:45:38 +0200
+
+linux-unstable (6.6.0-2.2) mantic; urgency=medium
+
+  * Miscellaneous upstream changes
+    - UBUBNTU: [Config] build all COMEDI drivers as modules
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 18 Sep 2023 14:42:56 +0200
+
+linux-unstable (6.6.0-1.1) mantic; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move linux to linux-unstable
+    - [Packaging] rebase on v6.6-rc1
+    - [Config] updateconfigs following v6.6-rc1 rebase
+    - [packaging] skip ABI, modules and retpoline checks
+    - update dropped.txt
+    - [Config] SHIFT_FS FTBFS with Linux 6.6, disable it
+    - [Config] DELL_UART_BACKLIGHT FTBFS with Linux 6.6, disable it
+    - [Packaging] debian/dkms-versions: temporarily disable dkms
+    - [Packaging] temporarily disable signing for s390x
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.6-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 15 Sep 2023 14:42:18 +0200
+
+linux-unstable (6.6.0-0.0) mantic; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 14 Sep 2023 15:03:19 +0200
+
+linux (6.5.0-5.5) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-5.5 -proposed tracker (LP: #2034546)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.08.23)
+
+
+linux (6.5.0-4.4) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-4.4 -proposed tracker (LP: #2034042)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.08.23)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 04 Sep 2023 16:55:44 +0200
+
+linux (6.5.0-3.3) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-3.3 -proposed tracker (LP: #2033904)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.08.23)
+
+  * [23.10] Please test secure-boot and lockdown on the early 6.5 kernel (s390x)
+    (LP: #2026833)
+    - [Packaging] re-enable signing for s390x
+
+  * Miscellaneous upstream changes
+    - module/decompress: use vmalloc() for zstd decompression workspace
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 01 Sep 2023 16:15:33 +0200
+
+linux (6.5.0-2.2) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-2.2 -proposed tracker (LP: #2033240)
+
+  * Soundwire support for Dell SKU0C87 devices (LP: #2029281)
+    - SAUCE: ASoC: Intel: soc-acpi: add support for Dell SKU0C87 devices
+
+  * Fix numerous AER related issues (LP: #2033025)
+    - SAUCE: PCI/AER: Disable AER service during suspend, again
+    - SAUCE: PCI/DPC: Disable DPC service during suspend, again
+
+  * Support Realtek RTL8852CE WiFi 6E/BT Combo (LP: #2025672)
+    - wifi: rtw89: debug: Fix error handling in rtw89_debug_priv_btc_manual_set()
+    - Bluetooth: btrtl: Load FW v2 otherwise FW v1 for RTL8852C
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Aug 2023 08:53:19 +0200
+
+linux (6.5.0-1.1) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-1.1 -proposed tracker (LP: #2032750)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync update-dkms-versions helper
+    - [Packaging] update variants
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.07.26)
+
+  * ceph: support idmapped mounts (LP: #2032959)
+    - SAUCE: libceph: add spinlock around osd->o_requests
+    - SAUCE: libceph: define struct ceph_sparse_extent and add some helpers
+    - SAUCE: libceph: new sparse_read op, support sparse reads on msgr2 crc
+      codepath
+    - SAUCE: libceph: support sparse reads on msgr2 secure codepath
+    - SAUCE: libceph: add sparse read support to msgr1
+    - SAUCE: libceph: add sparse read support to OSD client
+    - SAUCE: ceph: add new mount option to enable sparse reads
+    - SAUCE: ceph: preallocate inode for ops that may create one
+    - SAUCE: ceph: make ceph_msdc_build_path use ref-walk
+    - SAUCE: libceph: add new iov_iter-based ceph_msg_data_type and
+      ceph_osd_data_type
+    - SAUCE: ceph: use osd_req_op_extent_osd_iter for netfs reads
+    - SAUCE: ceph: fscrypt_auth handling for ceph
+    - SAUCE: ceph: implement -o test_dummy_encryption mount option
+    - SAUCE: ceph: add fscrypt ioctls and ceph.fscrypt.auth vxattr
+    - SAUCE: ceph: make ioctl cmds more readable in debug log
+    - SAUCE: ceph: add base64 endcoding routines for encrypted names
+    - SAUCE: ceph: encode encrypted name in ceph_mdsc_build_path and dentry
+      release
+    - SAUCE: ceph: send alternate_name in MClientRequest
+    - SAUCE: ceph: decode alternate_name in lease info
+    - SAUCE: ceph: set DCACHE_NOKEY_NAME flag in ceph_lookup/atomic_open()
+    - SAUCE: ceph: make d_revalidate call fscrypt revalidator for encrypted
+      dentries
+    - SAUCE: ceph: add helpers for converting names for userland presentation
+    - SAUCE: ceph: make ceph_fill_trace and ceph_get_name decrypt names
+    - SAUCE: ceph: pass the request to parse_reply_info_readdir()
+    - SAUCE: ceph: add support to readdir for encrypted names
+    - SAUCE: ceph: create symlinks with encrypted and base64-encoded targets
+    - SAUCE: ceph: add some fscrypt guardrails
+    - SAUCE: ceph: allow encrypting a directory while not having Ax caps
+    - SAUCE: ceph: mark directory as non-complete after loading key
+    - SAUCE: ceph: size handling in MClientRequest, cap updates and inode traces
+    - SAUCE: ceph: handle fscrypt fields in cap messages from MDS
+    - SAUCE: ceph: add infrastructure for file encryption and decryption
+    - SAUCE: libceph: add CEPH_OSD_OP_ASSERT_VER support
+    - SAUCE: libceph: allow ceph_osdc_new_request to accept a multi-op read
+    - SAUCE: ceph: add object version support for sync read
+    - SAUCE: ceph: add truncate size handling support for fscrypt
+    - SAUCE: ceph: don't use special DIO path for encrypted inodes
+    - SAUCE: ceph: align data in pages in ceph_sync_write
+    - SAUCE: ceph: add read/modify/write to ceph_sync_write
+    - SAUCE: ceph: add encryption support to writepage and writepages
+    - SAUCE: ceph: plumb in decryption during reads
+    - SAUCE: ceph: invalidate pages when doing direct/sync writes
+    - SAUCE: ceph: add support for encrypted snapshot names
+    - SAUCE: ceph: prevent snapshot creation in encrypted locked directories
+    - SAUCE: ceph: update documentation regarding snapshot naming limitations
+    - SAUCE: ceph: drop messages from MDS when unmounting
+    - SAUCE: ceph: wait for OSD requests' callbacks to finish when unmounting
+    - SAUCE: ceph: fix updating i_truncate_pagecache_size for fscrypt
+    - SAUCE: ceph: switch ceph_lookup/atomic_open() to use new fscrypt helper
+    - SAUCE: libceph: do not include crypto/algapi.h
+    - SAUCE: rbd: bump RBD_MAX_PARENT_CHAIN_LEN to 128
+    - SAUCE: ceph: dump info about cap flushes when we're waiting too long for
+      them
+    - SAUCE: mm: BUG if filemap_alloc_folio gives us a folio with a non-NULL
+      ->private
+    - SAUCE: ceph: make sure all the files successfully put before unmounting
+    - SAUCE: ceph: BUG if MDS changed truncate_seq with client caps still
+      outstanding
+    - SAUCE: ceph: add the *_client debug macros support
+    - SAUCE: ceph: pass the mdsc to several helpers
+    - SAUCE: ceph: rename _to_client() to _to_fs_client()
+    - SAUCE: ceph: move mdsmap.h to fs/ceph/
+    - SAUCE: ceph: add ceph_inode_to_client() helper support
+    - SAUCE: ceph: print the client global_id in all the debug logs
+    - SAUCE: ceph: make the members in struct ceph_mds_request_args_ext an union
+    - SAUCE: ceph: make num_fwd and num_retry to __u32
+    - SAUCE: fs: export mnt_idmap_get/mnt_idmap_put
+    - SAUCE: ceph: stash idmapping in mdsc request
+    - SAUCE: ceph: handle idmapped mounts in create_request_message()
+    - SAUCE: ceph: add enable_unsafe_idmap module parameter
+    - SAUCE: ceph: pass an idmapping to mknod/symlink/mkdir
+    - SAUCE: ceph: allow idmapped getattr inode op
+    - SAUCE: ceph: allow idmapped permission inode op
+    - SAUCE: ceph: pass idmap to __ceph_setattr
+    - SAUCE: ceph: allow idmapped setattr inode op
+    - SAUCE: ceph/acl: allow idmapped set_acl inode op
+    - SAUCE: ceph/file: allow idmapped atomic_open inode op
+    - SAUCE: ceph: allow idmapped mounts
+
+  * Got soft lockup CPU if dell_uart_backlight is probed (LP: #2032174)
+    - SAUCE: platform/x86: dell-uart-backlight: replace chars_in_buffer() with
+      flush_chars()
+
+  * Fix ACPI TAD  on some Intel based systems (LP: #2032767)
+    - ACPI: TAD: Install SystemCMOS address space handler for ACPI000E
+
+  * Fix unreliable ethernet cable detection on I219 NIC (LP: #2028122)
+    - e1000e: Use PME poll to circumvent unreliable ACPI wake
+
+  * Fix panel brightness issues on HP laptops (LP: #2032704)
+    - ACPI: video: Put ACPI video and its child devices into D0 on boot
+
+  * FATAL:credentials.cc(127)] Check failed: . : Permission denied (13)
+    (LP: #2017980)
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+
+  * Support initrdless boot on default qemu virt models and openstack
+    (LP: #2030745)
+    - [Config] set VIRTIO_BLK=y for default qemu/openstack boot
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] rust: use Rust 1.68.2
+    - [Packaging] depend on clang/libclang-15 for Rust
+    - [Config] update toolchain versions in annotations
+    - [Config] update annotations after rebase to v6.5-rc6
+    - [Config] update toolchain version in annotations
+    - [Packaging] temporarily disable Rust support
+    - [Packaging] temporarily disable signing for ppc64el
+    - [Packaging] temporarily disable signing for s390x
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 24 Aug 2023 17:47:10 +0200
+
+linux (6.5.0-0.0) mantic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 23 Aug 2023 08:14:48 +0200
+
+linux-unstable (6.5.0-4.4) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.5.0-4.4 -proposed tracker (LP: #2029086)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Add .NOTPARALLEL
+    - [Packaging] Remove meaningless $(header_arch)
+    - [Packaging] Fix File exists error in install-arch-headers
+    - [Packaging] clean debian/linux-* directories
+    - [Packaging] remove hmake
+    - [Packaging] install headers to debian/linux-libc-dev directly
+    - [Config] define CONFIG options for arm64 instead of arm64-generic
+    - [Config] update annotations after rebase to v6.5-rc4
+    - [Packaging] temporarily disable Rust support
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 31 Jul 2023 08:41:59 +0200
+
+linux-unstable (6.5.0-3.3) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.5.0-3.3 -proposed tracker (LP: #2028779)
+
+  * enable Rust support in the kernel (LP: #2007654)
+    - SAUCE: rust: support rustc-1.69.0
+    - [Packaging] depend on rustc-1.69.0
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync update-dkms-versions helper
+    - [Packaging] resync getabis
+
+  * Fix UBSAN in Intel EDAC driver (LP: #2028746)
+    - EDAC/i10nm: Skip the absent memory controllers
+
+  * Ship kernel modules Zstd compressed (LP: #2028568)
+    - SAUCE: Support but do not require compressed modules
+    - [Config] Enable support for ZSTD compressed modules
+    - [Packaging] ZSTD compress modules
+
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor3.2.0 [02/60]: rename SK_CTX() to aa_sock and make it an
+      inline fn
+    - SAUCE: apparmor3.2.0 [05/60]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor3.2.0 [08/60]: Stacking v38: LSM: Identify modules by more
+      than name
+    - SAUCE: apparmor3.2.0 [09/60]: Stacking v38: LSM: Add an LSM identifier for
+      external use
+    - SAUCE: apparmor3.2.0 [10/60]: Stacking v38: LSM: Identify the process
+      attributes for each module
+    - SAUCE: apparmor3.2.0 [11/60]: Stacking v38: LSM: Maintain a table of LSM
+      attribute data
+    - SAUCE: apparmor3.2.0 [12/60]: Stacking v38: proc: Use lsmids instead of lsm
+      names for attrs
+    - SAUCE: apparmor3.2.0 [13/60]: Stacking v38: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor3.2.0 [14/60]: Stacking v38: LSM: Infrastructure management
+      of the sock security
+    - SAUCE: apparmor3.2.0 [15/60]: Stacking v38: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor3.2.0 [16/60]: Stacking v38: LSM: provide lsm name and id
+      slot mappings
+    - SAUCE: apparmor3.2.0 [17/60]: Stacking v38: IMA: avoid label collisions with
+      stacked LSMs
+    - SAUCE: apparmor3.2.0 [18/60]: Stacking v38: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor3.2.0 [19/60]: Stacking v38: LSM: Use lsmblob in
+      security_kernel_act_as
+    - SAUCE: apparmor3.2.0 [20/60]: Stacking v38: LSM: Use lsmblob in
+      security_secctx_to_secid
+    - SAUCE: apparmor3.2.0 [21/60]: Stacking v38: LSM: Use lsmblob in
+      security_secid_to_secctx
+    - SAUCE: apparmor3.2.0 [22/60]: Stacking v38: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor3.2.0 [23/60]: Stacking v38: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor3.2.0 [24/60]: Stacking v38: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor3.2.0 [25/60]: Stacking v38: LSM: Use lsmblob in
+      security_cred_getsecid
+    - SAUCE: apparmor3.2.0 [26/60]: Stacking v38: LSM: Specify which LSM to
+      display
+    - SAUCE: apparmor3.2.0 [28/60]: Stacking v38: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor3.2.0 [29/60]: Stacking v38: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor3.2.0 [30/60]: Stacking v38: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor3.2.0 [31/60]: Stacking v38: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor3.2.0 [32/60]: Stacking v38: LSM: security_secid_to_secctx in
+      netlink netfilter
+    - SAUCE: apparmor3.2.0 [33/60]: Stacking v38: NET: Store LSM netlabel data in
+      a lsmblob
+    - SAUCE: apparmor3.2.0 [34/60]: Stacking v38: binder: Pass LSM identifier for
+      confirmation
+    - SAUCE: apparmor3.2.0 [35/60]: Stacking v38: LSM: security_secid_to_secctx
+      module selection
+    - SAUCE: apparmor3.2.0 [36/60]: Stacking v38: Audit: Keep multiple LSM data in
+      audit_names
+    - SAUCE: apparmor3.2.0 [37/60]: Stacking v38: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor3.2.0 [38/60]: Stacking v38: LSM: Add a function to report
+      multiple LSMs
+    - SAUCE: apparmor3.2.0 [39/60]: Stacking v38: Audit: Allow multiple records in
+      an audit_buffer
+    - SAUCE: apparmor3.2.0 [40/60]: Stacking v38: Audit: Add record for multiple
+      task security contexts
+    - SAUCE: apparmor3.2.0 [41/60]: Stacking v38: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor3.2.0 [42/60]: Stacking v38: Audit: Add record for multiple
+      object contexts
+    - SAUCE: apparmor3.2.0 [43/60]: Stacking v38: netlabel: Use a struct lsmblob
+      in audit data
+    - SAUCE: apparmor3.2.0 [44/60]: Stacking v38: LSM: Removed scaffolding
+      function lsmcontext_init
+    - SAUCE: apparmor3.2.0 [45/60]: Stacking v38: AppArmor: Remove the exclusive
+      flag
+    - SAUCE: apparmor3.2.0 [46/60]: combine common_audit_data and
+      apparmor_audit_data
+    - SAUCE: apparmor3.2.0 [47/60]: setup slab cache for audit data
+    - SAUCE: apparmor3.2.0 [48/60]: rename audit_data->label to
+      audit_data->subj_label
+    - SAUCE: apparmor3.2.0 [49/60]: pass cred through to audit info.
+    - SAUCE: apparmor3.2.0 [50/60]: Improve debug print infrastructure
+    - SAUCE: apparmor3.2.0 [51/60]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor3.2.0 [52/60]: enable userspace upcall for mediation
+    - SAUCE: apparmor3.2.0 [53/60]: cache buffers on percpu list if there is lock
+      contention
+    - SAUCE: apparmor3.2.0 [55/60]: advertise availability of exended perms
+    - SAUCE: apparmor3.2.0 [60/60]: [Config] enable
+      CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+
+  * LSM stacking and AppArmor for 6.2: additional fixes (LP: #2017903) // update
+    apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor3.2.0 [57/60]: fix profile verification and enable it
+
+  * udev fails to make prctl() syscall with apparmor=0 (as used by maas by
+    default) (LP: #2016908) // update apparmor and LSM stacking patch set
+    (LP: #2028253)
+    - SAUCE: apparmor3.2.0 [27/60]: Stacking v38: Fix prctl() syscall with
+      apparmor=0
+
+  * kinetic: apply new apparmor and LSM stacking patch set (LP: #1989983) //
+    update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor3.2.0 [01/60]: add/use fns to print hash string hex value
+    - SAUCE: apparmor3.2.0 [03/60]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor3.2.0 [04/60]: add user namespace creation mediation
+    - SAUCE: apparmor3.2.0 [06/60]: af_unix mediation
+    - SAUCE: apparmor3.2.0 [07/60]: Add fine grained mediation of posix mqueues
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Use consistent llvm/clang for rust
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 28 Jul 2023 07:44:20 +0200
+
+linux-unstable (6.5.0-2.2) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.5.0-2.2 -proposed tracker (LP: #2027953)
+
+  * Remove non-LPAE kernel flavor (LP: #2025265)
+    - [Packaging] Rename armhf generic-lpae flavor to generic
+
+  * Please enable Renesas RZ platform serial installer (LP: #2022361)
+    - [Config] enable hihope RZ/G2M serial console
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] snap: Remove old configs handling
+    - [Packaging] checks/final-checks: Remove old configs handling
+    - [Packaging] checks/final-checks: check existance of Makefile first
+    - [Packaging] checks/final-checks: Fix shellcheck issues
+    - [Packaging] add libstdc++-dev to the build dependencies
+    - [Config] update annotations after rebase to v6.5-rc2
+
+  * Miscellaneous upstream changes
+    - kbuild: rust: avoid creating temporary files
+    - rust: fix bindgen build error with UBSAN_BOUNDS_STRICT
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 18 Jul 2023 10:14:14 +0200
+
+linux-unstable (6.5.0-1.1) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.5.0-1.1 -proposed tracker (LP: #2026689)
+
+  * CVE-2023-31248
+    - netfilter: nf_tables: do not ignore genmask when looking up chain by id
+
+  * CVE-2023-35001
+    - netfilter: nf_tables: prevent OOB access in nft_byteorder_eval
+
+  * HDMI output with More than one child device for port B in VBT error
+    (LP: #2025195)
+    - SAUCE: drm/i915/quirks: Add multiple VBT quirk for HP ZBook Power G10
+
+  * CVE-2023-2640 // CVE-2023-32629
+    - SAUCE: overlayfs: default to userxattr when mounted from non initial user
+      namespace
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync update-dkms-versions helper
+
+  * enable Rust support in the kernel (LP: #2007654)
+    - SAUCE: btf, scripts: rust: drop is_rust_module.sh
+    - [Packaging] add rust dependencies
+
+  * CVE-2023-2612
+    - SAUCE: shiftfs: prevent lock unbalance in shiftfs_create_object()
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: shiftfs: support linux 6.5
+    - [Config] update annotations after rebase to v6.5-rc1
+    - [Config] temporarily disable Rust
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 10 Jul 2023 09:15:26 +0200
+
+linux-unstable (6.5.0-0.0) mantic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 05 Jul 2023 12:48:39 +0200
+
+linux-unstable (6.4.0-8.8) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-8.8 -proposed tracker (LP: #2025018)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update toolchain version (gcc) in annotations
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 26 Jun 2023 09:14:02 +0200
+
+linux-unstable (6.4.0-7.7) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-7.7 -proposed tracker (LP: #2024338)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 19 Jun 2023 08:51:27 +0200
+
+linux-unstable (6.4.0-6.6) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-6.6 -proposed tracker (LP: #2023966)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update annotations scripts
+
+  * enable multi-gen LRU by default (LP: #2023629)
+    - [Config] enable multi-gen LRU by default
+
+  * Fix Monitor lost after replug WD19TBS to SUT port with VGA/DVI to type-C
+    dongle (LP: #2021949)
+    - thunderbolt: Do not touch CL state configuration during discovery
+    - thunderbolt: Increase DisplayPort Connection Manager handshake timeout
+
+  * Neuter signing tarballs (LP: #2012776)
+    - [Packaging] remove the signing tarball support
+
+  * Enable Tracing Configs for OSNOISE and TIMERLAT (LP: #2018591)
+    - [Config] Enable OSNOISE_TRACER and TIMERLAT_TRACER configs
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Add CONFIG_AS_HAS_NON_CONST_LEB128 on riscv64
+    - [Packaging] introduce do_lib_rust and enable it only on generic amd64
+    - [Config] update annotations after rebase to v6.4-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 15 Jun 2023 20:11:07 +0200
+
+linux-unstable (6.4.0-5.5) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-5.5 -proposed tracker (LP: #2022886)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] update getabis to support linux-unstable
+    - UBUNTU [Config]: disable hibernation on riscv64
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 06 Jun 2023 08:18:01 +0200
+
+linux-unstable (6.4.0-4.4) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-4.4 -proposed tracker (LP: #2021597)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] udpate annotations after rebase to v6.4-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 30 May 2023 11:55:41 +0200
+
+linux-unstable (6.4.0-3.3) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-3.3 -proposed tracker (LP: #2021497)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+    - [Packaging] resync getabis
+
+  * support python < 3.9 with annotations (LP: #2020531)
+    - [Packaging] kconfig/annotations.py: support older way of merging dicts
+
+  * generate linux-lib-rust only on amd64 (LP: #2020356)
+    - [Packaging] generate linux-lib-rust only on amd64
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: never drop configs that have notes different than
+      the parent
+    - [Config] drop CONFIG_SMBFS_COMMON from annotations
+    - [Packaging] perf: build without libtraceevent
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 30 May 2023 08:38:10 +0200
+
+linux-unstable (6.4.0-2.2) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-2.2 -proposed tracker (LP: #2020330)
+
+  * Computer with Intel Atom CPU will  not boot with Kernel 6.2.0-20
+    (LP: #2017444)
+    - [Config]: Disable CONFIG_INTEL_ATOMISP
+
+  * Fix NVME storage with RAID ON disappeared under Dell factory WINPE
+    environment (LP: #2011768)
+    - SAUCE: PCI: vmd: Reset VMD config register between soft reboots
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Drop support of old config handling
+    - [Config] update annotations after rebase to v6.4-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 22 May 2023 11:22:14 +0200
+
+linux-unstable (6.4.0-1.1) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-1.1 -proposed tracker (LP: #2019965)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - [Packaging] update helper scripts
+
+  * Kernel 6.1 bumped the disk consumption on default images by 15%
+    (LP: #2015867)
+    - [Packaging] introduce a separate linux-lib-rust package
+
+  * Miscellaneous Ubuntu changes
+    - [Config] enable CONFIG_BLK_DEV_UBLK on amd64
+    - [Packaging] annotations: use python3 in the shebang
+    - SAUCE: blk-throttle: Fix io statistics for cgroup v1
+    - [Packaging] move to v6.4 and rename to linux-unstable
+    - [Config] update annotations after rebase to v6.4-rc1
+    - [Packaging] temporarily disable perf
+    - [Packaging] temporarily disable bpftool
+    - [Config] ppc64el: reduce CONFIG_ARCH_FORCE_MAX_ORDER from 9 to 8
+    - SAUCE: perf: explicitly disable libtraceevent
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 18 May 2023 07:34:09 +0200
+
+linux-unstable (6.4.0-0.0) mantic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 17 May 2023 15:29:25 +0200
+
+linux-unstable (6.3.0-2.2) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.3.0-2.2 -proposed tracker (LP: #2017788)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move python3-dev to build-depends
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 26 Apr 2023 21:52:12 +0200
+
+linux-unstable (6.3.0-1.1) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.3.0-1.1 -proposed tracker (LP: #2017776)
+
+  * RFC: virtio and virtio-scsi should be built in (LP: #1685291)
+    - [Config] Mark CONFIG_SCSI_VIRTIO built-in
+
+  * Debian autoreconstruct Fix restoration of execute permissions (LP: #2015498)
+    - [Debian] autoreconstruct - fix restoration of execute permissions
+
+  * [SRU][Jammy] CONFIG_PCI_MESON is not enabled (LP: #2007745)
+    - [Config] arm64: Enable PCI_MESON module
+
+  * vmd may fail to create sysfs entry while `pci_rescan_bus()` called in some
+    other drivers like wwan (LP: #2011389)
+    - SAUCE: PCI: vmd: guard device addition and removal
+
+  * Lunar update: v6.2.9 upstream stable release (LP: #2016877)
+    - [Config] ppc64: updateconfigs following v6.2.9 stable updates
+
+  * Lunar update: v6.2.8 upstream stable release (LP: #2016876)
+    - [Config] ppc64: updateconfigs following v6.2.8 stable updates
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Move final-checks script to debian/scripts/checks
+    - [Packaging] checks/final-checks: Honor 'do_skip_checks'
+    - [Packaging] Drop wireguard DKMS
+    - [Packaging] Remove update-version-dkms
+    - [Packaging] debian/rules: Add DKMS info to 'printenv' output
+    - [Packaging] ignore KBUILD_VERBOSE in arch-has-odm-enabled.sh
+    - SAUCE: shiftfs: support linux 6.3
+    - [Packaging] move to v6.3 and rename to linux-unstable
+    - [Config] latency-related optimizations
+    - [Config] update annotations after rebase to v6.3
+    - [Packaging] temporarily disable dkms
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 26 Apr 2023 14:53:52 +0200
+
+linux-unstable (6.3.0-0.0) lunar; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 25 Apr 2023 10:24:12 +0200
+
+linux (6.2.0-21.21) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-21.21 -proposed tracker (LP: #2016249)
+
+  * efivarfs:efivarfs.sh in ubuntu_kernel_selftests crash L-6.2 ARM64 node
+    dazzle (rcu_preempt detected stalls) (LP: #2015741)
+    - efi/libstub: smbios: Use length member instead of record struct size
+    - arm64: efi: Use SMBIOS processor version to key off Ampere quirk
+    - efi/libstub: smbios: Drop unused 'recsize' parameter
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/bpf: ignore pointer types check with clang
+    - SAUCE: selftests/bpf: avoid conflicting data types in profiler.inc.h
+    - [Packaging] get rid of unnecessary artifacts in linux-headers
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: Revert "efi: random: refresh non-volatile random seed
+      when RNG is initialized""
+    - Revert "UBUNTU: SAUCE: Revert "efi: random: fix NULL-deref when refreshing
+      seed""
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 14 Apr 2023 12:11:49 +0200
+
+linux (6.2.0-20.20) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-20.20 -proposed tracker (LP: #2015429)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * FTBFS with different dkms or when makeflags are set (LP: #2015361)
+    - [Packaging] FTBFS with different dkms or when makeflags are set
+
+  * expoline.o is packaged unconditionally for s390x (LP: #2013209)
+    - [Packaging] Copy expoline.o only when produced by the build
+
+  * net:l2tp.sh failure with lunar:linux 6.2 (LP: #2013014)
+    - SAUCE: l2tp: generate correct module alias strings
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: prevent duplicate include lines
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 06 Apr 2023 08:33:14 +0200
+
+linux (6.2.0-19.19) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-19.19 -proposed tracker (LP: #2012488)
+
+  * Neuter signing tarballs (LP: #2012776)
+    - [Packaging] neuter the signing tarball
+
+  * LSM stacking and AppArmor refresh for 6.2 kernel (LP: #2012136)
+    - Revert "UBUNTU: [Config] define CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS"
+    - Revert "UBUNTU: SAUCE: apparmor: add user namespace creation mediation"
+    - Revert "UBUNTU: SAUCE: apparmor: Add fine grained mediation of posix
+      mqueues"
+    - Revert "UBUNTU: SAUCE: Revert "apparmor: make __aa_path_perm() static""
+    - Revert "UBUNTU: SAUCE: LSM: Specify which LSM to display (using struct cred
+      as input)"
+    - Revert "UBUNTU: SAUCE: apparmor: Fix build error, make sk parameter const"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in smk_netlbl_mls()"
+    - Revert "UBUNTU: SAUCE: LSM: change ima_read_file() to use lsmblob"
+    - Revert "UBUNTU: SAUCE: apparmor: rename kzfree() to kfree_sensitive()"
+    - Revert "UBUNTU: SAUCE: AppArmor: Remove the exclusive flag"
+    - Revert "UBUNTU: SAUCE: LSM: Add /proc attr entry for full LSM context"
+    - Revert "UBUNTU: SAUCE: Audit: Fix incorrect static inline function
+      declration."
+    - Revert "UBUNTU: SAUCE: Audit: Fix for missing NULL check"
+    - Revert "UBUNTU: SAUCE: Audit: Add a new record for multiple object LSM
+      attributes"
+    - Revert "UBUNTU: SAUCE: Audit: Add new record for multiple process LSM
+      attributes"
+    - Revert "UBUNTU: SAUCE: NET: Store LSM netlabel data in a lsmblob"
+    - Revert "UBUNTU: SAUCE: LSM: security_secid_to_secctx in netlink netfilter"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmcontext in security_inode_getsecctx"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmcontext in security_secid_to_secctx"
+    - Revert "UBUNTU: SAUCE: LSM: Ensure the correct LSM context releaser"
+    - Revert "UBUNTU: SAUCE: LSM: Specify which LSM to display"
+    - Revert "UBUNTU: SAUCE: IMA: Change internal interfaces to use lsmblobs"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_cred_getsecid"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_inode_getsecid"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_task_getsecid"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_ipc_getsecid"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_secid_to_secctx"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_secctx_to_secid"
+    - Revert "UBUNTU: SAUCE: net: Prepare UDS for security module stacking"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_kernel_act_as"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_audit_rule_match"
+    - Revert "UBUNTU: SAUCE: LSM: Create and manage the lsmblob data structure."
+    - Revert "UBUNTU: SAUCE: LSM: Infrastructure management of the sock security"
+    - Revert "UBUNTU: SAUCE: apparmor: LSM stacking: switch from SK_CTX() to
+      aa_sock()"
+    - Revert "UBUNTU: SAUCE: apparmor: rename aa_sock() to aa_unix_sk()"
+    - Revert "UBUNTU: SAUCE: apparmor: disable showing the mode as part of a secid
+      to secctx"
+    - Revert "UBUNTU: SAUCE: apparmor: fix use after free in sk_peer_label"
+    - Revert "UBUNTU: SAUCE: apparmor: af_unix mediation"
+    - Revert "UBUNTU: SAUCE: apparmor: patch to provide compatibility with v2.x
+      net rules"
+    - Revert "UBUNTU: SAUCE: apparmor: add/use fns to print hash string hex value"
+    - SAUCE: apparmor: rename SK_CTX() to aa_sock and make it an inline fn
+    - SAUCE: apparmor: Add sysctls for additional controls of unpriv userns
+      restrictions
+    - SAUCE: Stacking v38: LSM: Identify modules by more than name
+    - SAUCE: Stacking v38: LSM: Add an LSM identifier for external use
+    - SAUCE: Stacking v38: LSM: Identify the process attributes for each module
+    - SAUCE: Stacking v38: LSM: Maintain a table of LSM attribute data
+    - SAUCE: Stacking v38: proc: Use lsmids instead of lsm names for attrs
+    - SAUCE: Stacking v38: integrity: disassociate ima_filter_rule from
+      security_audit_rule
+    - SAUCE: Stacking v38: LSM: Infrastructure management of the sock security
+    - SAUCE: Stacking v38: LSM: Add the lsmblob data structure.
+    - SAUCE: Stacking v38: LSM: provide lsm name and id slot mappings
+    - SAUCE: Stacking v38: IMA: avoid label collisions with stacked LSMs
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_audit_rule_match
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_kernel_act_as
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_secctx_to_secid
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_secid_to_secctx
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_ipc_getsecid
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_current_getsecid
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_inode_getsecid
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_cred_getsecid
+    - SAUCE: Stacking v38: LSM: Specify which LSM to display
+    - SAUCE: Stacking v38: LSM: Ensure the correct LSM context releaser
+    - SAUCE: Stacking v38: LSM: Use lsmcontext in security_secid_to_secctx
+    - SAUCE: Stacking v38: LSM: Use lsmcontext in security_inode_getsecctx
+    - SAUCE: Stacking v38: Use lsmcontext in security_dentry_init_security
+    - SAUCE: Stacking v38: LSM: security_secid_to_secctx in netlink netfilter
+    - SAUCE: Stacking v38: NET: Store LSM netlabel data in a lsmblob
+    - SAUCE: Stacking v38: binder: Pass LSM identifier for confirmation
+    - SAUCE: Stacking v38: LSM: security_secid_to_secctx module selection
+    - SAUCE: Stacking v38: Audit: Keep multiple LSM data in audit_names
+    - SAUCE: Stacking v38: Audit: Create audit_stamp structure
+    - SAUCE: Stacking v38: LSM: Add a function to report multiple LSMs
+    - SAUCE: Stacking v38: Audit: Allow multiple records in an audit_buffer
+    - SAUCE: Stacking v38: Audit: Add record for multiple task security contexts
+    - SAUCE: Stacking v38: audit: multiple subject lsm values for netlabel
+    - SAUCE: Stacking v38: Audit: Add record for multiple object contexts
+    - SAUCE: Stacking v38: netlabel: Use a struct lsmblob in audit data
+    - SAUCE: Stacking v38: LSM: Removed scaffolding function lsmcontext_init
+    - SAUCE: Stacking v38: AppArmor: Remove the exclusive flag
+    - SAUCE: apparmor: combine common_audit_data and apparmor_audit_data
+    - SAUCE: apparmor: setup slab cache for audit data
+    - SAUCE: apparmor: rename audit_data->label to audit_data->subj_label
+    - SAUCE: apparmor: pass cred through to audit info.
+    - SAUCE: apparmor: Improve debug print infrastructure
+    - SAUCE: apparmor: add the ability for profiles to have a learning cache
+    - SAUCE: apparmor: enable userspace upcall for mediation
+    - SAUCE: apparmor: cache buffers on percpu list if there is lock contention
+    - SAUCE: apparmor: fix policy_compat permission remap with extended
+      permissions
+    - SAUCE: apparmor: advertise availability of exended perms
+    - [Config] define CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+
+  * kinetic: apply new apparmor and LSM stacking patch set (LP: #1989983) // LSM
+    stacking and AppArmor refresh for 6.2 kernel (LP: #2012136)
+    - SAUCE: apparmor: add/use fns to print hash string hex value
+    - SAUCE: apparmor: patch to provide compatibility with v2.x net rules
+    - SAUCE: apparmor: add user namespace creation mediation
+    - SAUCE: apparmor: af_unix mediation
+    - SAUCE: apparmor: Add fine grained mediation of posix mqueues
+
+  * devlink_port_split from ubuntu_kernel_selftests.net fails on hirsute
+    (KeyError: 'flavour') (LP: #1937133)
+    - selftests: net: devlink_port_split.py: skip test if no suitable device
+      available
+
+  * NFS deathlock with last Kernel 5.4.0-144.161 and 5.15.0-67.74 (LP: #2009325)
+    - NFS: Correct timing for assigning access cache timestamp
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Sat, 25 Mar 2023 07:37:30 +0100
+
+linux (6.2.0-18.18) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-18.18 -proposed tracker (LP: #2011750)
+
+  * lunar/linux 6.2 fails to boot on arm64 (LP: #2011748)
+    - SAUCE: Revert "efi: random: fix NULL-deref when refreshing seed"
+    - SAUCE: Revert "efi: random: refresh non-volatile random seed when RNG is
+      initialized"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 15 Mar 2023 23:54:18 +0100
+
+linux (6.2.0-17.17) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-17.17 -proposed tracker (LP: #2011593)
+
+  * lunar/linux 6.2 fails to boot on ppc64el (LP: #2011413)
+    - SAUCE: Revert "powerpc: remove STACK_FRAME_OVERHEAD"
+    - SAUCE: Revert "powerpc/pseries: hvcall stack frame overhead"
+
+  * Speaker / Audio/Mic mute LED don't work on a HP platform (LP: #2011379)
+    - SAUCE: ALSA: hda/realtek: fix speaker, mute/micmute LEDs not work on a HP
+      platform
+
+  * Some QHD panels fail to refresh when PSR2 enabled (LP: #2009014)
+    - SAUCE: drm/i915/psr: Use calculated io and fast wake lines
+
+  * Lunar update: v6.2.6 upstream stable release (LP: #2011431)
+    - tpm: disable hwrng for fTPM on some AMD designs
+    - wifi: cfg80211: Partial revert "wifi: cfg80211: Fix use after free for wext"
+    - staging: rtl8192e: Remove function ..dm_check_ac_dc_power calling a script
+    - staging: rtl8192e: Remove call_usermodehelper starting RadioPower.sh
+    - Linux 6.2.6
+
+  * Lunar update: v6.2.5 upstream stable release (LP: #2011430)
+    - net/sched: Retire tcindex classifier
+    - auxdisplay: hd44780: Fix potential memory leak in hd44780_remove()
+    - fs/jfs: fix shift exponent db_agl2size negative
+    - driver: soc: xilinx: fix memory leak in xlnx_add_cb_for_notify_event()
+    - f2fs: don't rely on F2FS_MAP_* in f2fs_iomap_begin
+    - f2fs: fix to avoid potential deadlock
+    - objtool: Fix memory leak in create_static_call_sections()
+    - soc: mediatek: mtk-pm-domains: Allow mt8186 ADSP default power on
+    - soc: qcom: socinfo: Fix soc_id order
+    - memory: renesas-rpc-if: Split-off private data from struct rpcif
+    - memory: renesas-rpc-if: Move resource acquisition to .probe()
+    - soc: mediatek: mtk-svs: Enable the IRQ later
+    - pwm: sifive: Always let the first pwm_apply_state succeed
+    - pwm: stm32-lp: fix the check on arr and cmp registers update
+    - f2fs: introduce trace_f2fs_replace_atomic_write_block
+    - f2fs: clear atomic_write_task in f2fs_abort_atomic_write()
+    - soc: mediatek: mtk-svs: restore default voltages when svs_init02() fail
+    - soc: mediatek: mtk-svs: reset svs when svs_resume() fail
+    - soc: mediatek: mtk-svs: Use pm_runtime_resume_and_get() in svs_init01()
+    - f2fs: fix to do sanity check on extent cache correctly
+    - fs: f2fs: initialize fsdata in pagecache_write()
+    - f2fs: allow set compression option of files without blocks
+    - f2fs: fix to abort atomic write only during do_exist()
+    - um: vector: Fix memory leak in vector_config
+    - ubi: ensure that VID header offset + VID header size <= alloc, size
+    - ubifs: Fix build errors as symbol undefined
+    - ubifs: Fix memory leak in ubifs_sysfs_init()
+    - ubifs: Rectify space budget for ubifs_symlink() if symlink is encrypted
+    - ubifs: Rectify space budget for ubifs_xrename()
+    - ubifs: Fix wrong dirty space budget for dirty inode
+    - ubifs: do_rename: Fix wrong space budget when target inode's nlink > 1
+    - ubifs: Reserve one leb for each journal head while doing budget
+    - ubi: Fix use-after-free when volume resizing failed
+    - ubi: Fix unreferenced object reported by kmemleak in ubi_resize_volume()
+    - ubifs: Fix memory leak in alloc_wbufs()
+    - ubi: Fix possible null-ptr-deref in ubi_free_volume()
+    - ubifs: Re-statistic cleaned znode count if commit failed
+    - ubifs: dirty_cow_znode: Fix memleak in error handling path
+    - ubifs: ubifs_writepage: Mark page dirty after writing inode failed
+    - ubifs: ubifs_releasepage: Remove ubifs_assert(0) to valid this process
+    - ubi: fastmap: Fix missed fm_anchor PEB in wear-leveling after disabling
+      fastmap
+    - ubi: Fix UAF wear-leveling entry in eraseblk_count_seq_show()
+    - ubi: ubi_wl_put_peb: Fix infinite loop when wear-leveling work failed
+    - f2fs: fix to handle F2FS_IOC_START_ATOMIC_REPLACE in f2fs_compat_ioctl()
+    - f2fs: fix to avoid potential memory corruption in __update_iostat_latency()
+    - f2fs: fix to update age extent correctly during truncation
+    - f2fs: fix to update age extent in f2fs_do_zero_range()
+    - soc: qcom: stats: Populate all subsystem debugfs files
+    - f2fs: introduce IS_F2FS_IPU_* macro
+    - f2fs: fix to set ipu policy
+    - ext4: use ext4_fc_tl_mem in fast-commit replay path
+    - ext4: don't show commit interval if it is zero
+    - netfilter: nf_tables: allow to fetch set elements when table has an owner
+    - x86: um: vdso: Add '%rcx' and '%r11' to the syscall clobber list
+    - um: virtio_uml: free command if adding to virtqueue failed
+    - um: virtio_uml: mark device as unregistered when breaking it
+    - um: virtio_uml: move device breaking into workqueue
+    - um: virt-pci: properly remove PCI device from bus
+    - f2fs: synchronize atomic write aborts
+    - watchdog: rzg2l_wdt: Issue a reset before we put the PM clocks
+    - watchdog: rzg2l_wdt: Handle TYPE-B reset for RZ/V2M
+    - watchdog: at91sam9_wdt: use devm_request_irq to avoid missing free_irq() in
+      error path
+    - watchdog: Fix kmemleak in watchdog_cdev_register
+    - watchdog: pcwd_usb: Fix attempting to access uninitialized memory
+    - watchdog: sbsa_wdog: Make sure the timeout programming is within the limits
+    - netfilter: ctnetlink: fix possible refcount leak in
+      ctnetlink_create_conntrack()
+    - netfilter: conntrack: fix rmmod double-free race
+    - netfilter: ip6t_rpfilter: Fix regression with VRF interfaces
+    - netfilter: ebtables: fix table blob use-after-free
+    - netfilter: xt_length: use skb len to match in length_mt6
+    - netfilter: ctnetlink: make event listener tracking global
+    - netfilter: x_tables: fix percpu counter block leak on error path when
+      creating new netns
+    - swiotlb: mark swiotlb_memblock_alloc() as __init
+    - ptp: vclock: use mutex to fix "sleep on atomic" bug
+    - drm/i915: move a Kconfig symbol to unbreak the menu presentation
+    - ipv6: Add lwtunnel encap size of all siblings in nexthop calculation
+    - drm/i915/xelpmp: Consider GSI offset when doing MCR lookups
+    - octeontx2-pf: Recalculate UDP checksum for ptp 1-step sync packet
+    - net: sunhme: Fix region request
+    - sctp: add a refcnt in sctp_stream_priorities to avoid a nested loop
+    - octeontx2-pf: Use correct struct reference in test condition
+    - net: fix __dev_kfree_skb_any() vs drop monitor
+    - 9p/xen: fix version parsing
+    - 9p/xen: fix connection sequence
+    - 9p/rdma: unmap receive dma buffer in rdma_request()/post_recv()
+    - spi: tegra210-quad: Fix validate combined sequence
+    - mlx5: fix skb leak while fifo resync and push
+    - mlx5: fix possible ptp queue fifo use-after-free
+    - net/mlx5: ECPF, wait for VF pages only after disabling host PFs
+    - net/mlx5e: Verify flow_source cap before using it
+    - net/mlx5: Geneve, Fix handling of Geneve object id as error code
+    - ext4: fix incorrect options show of original mount_opt and extend mount_opt2
+    - nfc: fix memory leak of se_io context in nfc_genl_se_io
+    - net/sched: transition act_pedit to rcu and percpu stats
+    - net/sched: act_pedit: fix action bind logic
+    - net/sched: act_mpls: fix action bind logic
+    - net/sched: act_sample: fix action bind logic
+    - net: dsa: seville: ignore mscc-miim read errors from Lynx PCS
+    - net: dsa: felix: fix internal MDIO controller resource length
+    - ARM: dts: aspeed: p10bmc: Update battery node name
+    - ARM: dts: spear320-hmi: correct STMPE GPIO compatible
+    - tcp: tcp_check_req() can be called from process context
+    - vc_screen: modify vcs_size() handling in vcs_read()
+    - spi: tegra210-quad: Fix iterator outside loop
+    - rtc: sun6i: Always export the internal oscillator
+    - genirq/ipi: Fix NULL pointer deref in irq_data_get_affinity_mask()
+    - scsi: ipr: Work around fortify-string warning
+    - scsi: mpi3mr: Fix an issue found by KASAN
+    - scsi: mpi3mr: Use number of bits to manage bitmap sizes
+    - rtc: allow rtc_read_alarm without read_alarm callback
+    - io_uring: fix size calculation when registering buf ring
+    - loop: loop_set_status_from_info() check before assignment
+    - ASoC: adau7118: don't disable regulators on device unbind
+    - ASoC: apple: mca: Fix final status read on SERDES reset
+    - ASoC: apple: mca: Fix SERDES reset sequence
+    - ASoC: apple: mca: Improve handling of unavailable DMA channels
+    - nvme: bring back auto-removal of deleted namespaces during sequential scan
+    - nvme-tcp: don't access released socket during error recovery
+    - nvme-fabrics: show well known discovery name
+    - ASoC: zl38060 add gpiolib dependency
+    - ASoC: mediatek: mt8195: add missing initialization
+    - thermal: intel: quark_dts: fix error pointer dereference
+    - thermal: intel: BXT_PMIC: select REGMAP instead of depending on it
+    - cpufreq: apple-soc: Fix an IS_ERR() vs NULL check
+    - tracing: Add NULL checks for buffer in ring_buffer_free_read_page()
+    - kernel/printk/index.c: fix memory leak with using debugfs_lookup()
+    - firmware/efi sysfb_efi: Add quirk for Lenovo IdeaPad Duet 3
+    - bootconfig: Increase max nodes of bootconfig from 1024 to 8192 for DCC
+      support
+    - mfd: arizona: Use pm_runtime_resume_and_get() to prevent refcnt leak
+    - IB/hfi1: Update RMT size calculation
+    - iommu: Remove deferred attach check from __iommu_detach_device()
+    - PCI/ACPI: Account for _S0W of the target bridge in acpi_pci_bridge_d3()
+    - media: uvcvideo: Remove format descriptions
+    - media: uvcvideo: Handle cameras with invalid descriptors
+    - media: uvcvideo: Handle errors from calls to usb_string
+    - media: uvcvideo: Quirk for autosuspend in Logitech B910 and C910
+    - media: uvcvideo: Silence memcpy() run-time false positive warnings
+    - USB: fix memory leak with using debugfs_lookup()
+    - cacheinfo: Fix shared_cpu_map to handle shared caches at different levels
+    - usb: fotg210: List different variants
+    - dt-bindings: usb: Add device id for Genesys Logic hub controller
+    - staging: emxx_udc: Add checks for dma_alloc_coherent()
+    - tty: fix out-of-bounds access in tty_driver_lookup_tty()
+    - tty: serial: fsl_lpuart: disable the CTS when send break signal
+    - serial: sc16is7xx: setup GPIO controller later in probe
+    - mei: bus-fixup:upon error print return values of send and receive
+    - tools/iio/iio_utils:fix memory leak
+    - bus: mhi: ep: Fix the debug message for MHI_PKT_TYPE_RESET_CHAN_CMD cmd
+    - iio: accel: mma9551_core: Prevent uninitialized variable in
+      mma9551_read_status_word()
+    - iio: accel: mma9551_core: Prevent uninitialized variable in
+      mma9551_read_config_word()
+    - media: uvcvideo: Add GUID for BGRA/X 8:8:8:8
+    - soundwire: bus_type: Avoid lockdep assert in sdw_drv_probe()
+    - PCI/portdrv: Prevent LS7A Bus Master clearing on shutdown
+    - PCI: loongson: Prevent LS7A MRRS increases
+    - staging: pi433: fix memory leak with using debugfs_lookup()
+    - USB: dwc3: fix memory leak with using debugfs_lookup()
+    - USB: chipidea: fix memory leak with using debugfs_lookup()
+    - USB: ULPI: fix memory leak with using debugfs_lookup()
+    - USB: uhci: fix memory leak with using debugfs_lookup()
+    - USB: sl811: fix memory leak with using debugfs_lookup()
+    - USB: fotg210: fix memory leak with using debugfs_lookup()
+    - USB: isp116x: fix memory leak with using debugfs_lookup()
+    - USB: isp1362: fix memory leak with using debugfs_lookup()
+    - USB: gadget: gr_udc: fix memory leak with using debugfs_lookup()
+    - USB: gadget: bcm63xx_udc: fix memory leak with using debugfs_lookup()
+    - USB: gadget: lpc32xx_udc: fix memory leak with using debugfs_lookup()
+    - USB: gadget: pxa25x_udc: fix memory leak with using debugfs_lookup()
+    - USB: gadget: pxa27x_udc: fix memory leak with using debugfs_lookup()
+    - usb: host: xhci: mvebu: Iterate over array indexes instead of using pointer
+      math
+    - USB: ene_usb6250: Allocate enough memory for full object
+    - usb: uvc: Enumerate valid values for color matching
+    - usb: gadget: uvc: Make bSourceID read/write
+    - PCI: Align extra resources for hotplug bridges properly
+    - PCI: Take other bus devices into account when distributing resources
+    - PCI: Distribute available resources for root buses, too
+    - tty: pcn_uart: fix memory leak with using debugfs_lookup()
+    - misc: vmw_balloon: fix memory leak with using debugfs_lookup()
+    - drivers: base: component: fix memory leak with using debugfs_lookup()
+    - drivers: base: dd: fix memory leak with using debugfs_lookup()
+    - kernel/fail_function: fix memory leak with using debugfs_lookup()
+    - PCI: loongson: Add more devices that need MRRS quirk
+    - PCI: Add ACS quirk for Wangxun NICs
+    - PCI: pciehp: Add Qualcomm quirk for Command Completed erratum
+    - phy: rockchip-typec: Fix unsigned comparison with less than zero
+    - RDMA/cma: Distinguish between sockaddr_in and sockaddr_in6 by size
+    - soundwire: cadence: Remove wasted space in response_buf
+    - soundwire: cadence: Drain the RX FIFO after an IO timeout
+    - eth: fealnx: bring back this old driver
+    - net: tls: avoid hanging tasks on the tx_lock
+    - x86/resctl: fix scheduler confusion with 'current'
+    - vDPA/ifcvf: decouple hw features manipulators from the adapter
+    - vDPA/ifcvf: decouple config space ops from the adapter
+    - vDPA/ifcvf: alloc the mgmt_dev before the adapter
+    - vDPA/ifcvf: decouple vq IRQ releasers from the adapter
+    - vDPA/ifcvf: decouple config IRQ releaser from the adapter
+    - vDPA/ifcvf: decouple vq irq requester from the adapter
+    - vDPA/ifcvf: decouple config/dev IRQ requester and vectors allocator from the
+      adapter
+    - vDPA/ifcvf: ifcvf_request_irq works on ifcvf_hw
+    - vDPA/ifcvf: manage ifcvf_hw in the mgmt_dev
+    - vDPA/ifcvf: allocate the adapter in dev_add()
+    - drm/display/dp_mst: Add drm_atomic_get_old_mst_topology_state()
+    - drm/display/dp_mst: Fix down/up message handling after sink disconnect
+    - drm/display/dp_mst: Fix down message handling after a packet reception error
+    - drm/display/dp_mst: Fix payload addition on a disconnected sink
+    - drm/i915/dp_mst: Add the MST topology state for modesetted CRTCs
+    - drm/display/dp_mst: Handle old/new payload states in drm_dp_remove_payload()
+    - drm/i915/dp_mst: Fix payload removal during output disabling
+    - drm/i915: Fix system suspend without fbdev being initialized
+    - media: uvcvideo: Fix race condition with usb_kill_urb
+    - arm64: efi: Make efi_rt_lock a raw_spinlock
+    - usb: gadget: uvc: fix missing mutex_unlock() if kstrtou8() fails
+    - Linux 6.2.5
+
+  * Lunar update: v6.2.4 upstream stable release (LP: #2011428)
+    - Revert "blk-cgroup: synchronize pd_free_fn() from blkg_free_workfn() and
+      blkcg_deactivate_policy()"
+    - Revert "blk-cgroup: dropping parent refcount after pd_free_fn() is done"
+    - Linux 6.2.4
+
+  * Lunar update: v6.2.3 upstream stable release (LP: #2011425)
+    - HID: asus: use spinlock to protect concurrent accesses
+    - HID: asus: use spinlock to safely schedule workers
+    - iommu/amd: Fix error handling for pdev_pri_ats_enable()
+    - iommu/amd: Skip attach device domain is same as new domain
+    - iommu/amd: Improve page fault error reporting
+    - iommu: Attach device group to old domain in error path
+    - powerpc/mm: Rearrange if-else block to avoid clang warning
+    - ata: ahci: Revert "ata: ahci: Add Tiger Lake UP{3,4} AHCI controller"
+    - ARM: OMAP2+: Fix memory leak in realtime_counter_init()
+    - arm64: dts: qcom: qcs404: use symbol names for PCIe resets
+    - arm64: dts: qcom: msm8996-tone: Fix USB taking 6 minutes to wake up
+    - arm64: dts: qcom: sm6115: Fix UFS node
+    - arm64: dts: qcom: sm6115: Provide xo clk to rpmcc
+    - arm64: dts: qcom: sm8150-kumano: Panel framebuffer is 2.5k instead of 4k
+    - arm64: dts: qcom: pmi8950: Correct rev_1250v channel label to mv
+    - arm64: dts: qcom: sm6350: Fix up the ramoops node
+    - arm64: dts: qcom: sdm670-google-sargo: keep pm660 ldo8 on
+    - arm64: dts: qcom: Re-enable resin on MSM8998 and SDM845 boards
+    - arm64: dts: qcom: sm8350-sagami: Configure SLG51000 PMIC on PDX215
+    - arm64: dts: qcom: sm8350-sagami: Add GPIO line names for PMIC GPIOs
+    - arm64: dts: qcom: sm8350-sagami: Rectify GPIO keys
+    - arm64: dts: qcom: sm6350-lena: Flatten gpio-keys pinctrl state
+    - arm64: dts: qcom: sm6125: Reorder HSUSB PHY clocks to match bindings
+    - arm64: dts: qcom: sm6125-seine: Clean up gpio-keys (volume down)
+    - arm64: dts: imx8m: Align SoC unique ID node unit address
+    - ARM: zynq: Fix refcount leak in zynq_early_slcr_init
+    - fs: dlm: fix return value check in dlm_memory_init()
+    - arm64: dts: mediatek: mt8195: Add power domain to U3PHY1 T-PHY
+    - arm64: dts: mediatek: mt8183: Fix systimer 13 MHz clock description
+    - arm64: dts: mediatek: mt8192: Fix systimer 13 MHz clock description
+    - arm64: dts: mediatek: mt8195: Fix systimer 13 MHz clock description
+    - arm64: dts: mediatek: mt8186: Fix systimer 13 MHz clock description
+    - arm64: dts: qcom: sdm845-db845c: fix audio codec interrupt pin name
+    - arm64: dts: qcom: sdm845-xiaomi-beryllium: fix audio codec interrupt pin
+      name
+    - x86/acpi/boot: Do not register processors that cannot be onlined for x2APIC
+    - arm64: dts: qcom: sc7180: correct SPMI bus address cells
+    - arm64: dts: qcom: sc7280: correct SPMI bus address cells
+    - arm64: dts: qcom: sc8280xp: correct SPMI bus address cells
+    - arm64: dts: qcom: sm8450: correct Soundwire wakeup interrupt name
+    - arm64: dts: qcom: sdm845: make DP node follow the schema
+    - arm64: dts: qcom: msm8996-oneplus-common: drop vdda-supply from DSI PHY
+    - arm64: dts: qcom: sc8280xp: Vote for CX in USB controllers
+    - arm64: dts: meson-gxl: jethub-j80: Fix WiFi MAC address node
+    - arm64: dts: meson-gxl: jethub-j80: Fix Bluetooth MAC node name
+    - arm64: dts: meson-axg: jethub-j1xx: Fix MAC address node names
+    - arm64: dts: meson-gx: Fix Ethernet MAC address unit name
+    - arm64: dts: meson-g12a: Fix internal Ethernet PHY unit name
+    - arm64: dts: meson-gx: Fix the SCPI DVFS node name and unit address
+    - cpuidle, intel_idle: Fix CPUIDLE_FLAG_IRQ_ENABLE *again*
+    - arm64: dts: ti: k3-am62-main: Fix clocks for McSPI
+    - arm64: tegra: Fix duplicate regulator on Jetson TX1
+    - arm64: dts: qcom: msm8992-bullhead: Fix cont_splash_mem size
+    - arm64: dts: qcom: msm8992-bullhead: Disable dfps_data_mem
+    - arm64: dts: qcom: msm8956: use SoC-specific compat for tsens
+    - arm64: dts: qcom: ipq8074: correct USB3 QMP PHY-s clock output names
+    - arm64: dts: qcom: ipq8074: fix Gen2 PCIe QMP PHY
+    - arm64: dts: qcom: ipq8074: fix Gen3 PCIe QMP PHY
+    - arm64: dts: qcom: ipq8074: correct Gen2 PCIe ranges
+    - arm64: dts: qcom: ipq8074: fix Gen3 PCIe node
+    - arm64: dts: qcom: ipq8074: correct PCIe QMP PHY output clock names
+    - arm64: dts: meson: remove CPU opps below 1GHz for G12A boards
+    - ARM: OMAP1: call platform_device_put() in error case in
+      omap1_dm_timer_init()
+    - arm64: dts: mediatek: mt8192: Mark scp_adsp clock as broken
+    - ARM: bcm2835_defconfig: Enable the framebuffer
+    - ARM: s3c: fix s3c64xx_set_timer_source prototype
+    - arm64: dts: ti: k3-j7200: Fix wakeup pinmux range
+    - ARM: dts: exynos: correct wr-active property in Exynos3250 Rinato
+    - ARM: imx: Call ida_simple_remove() for ida_simple_get
+    - arm64: dts: amlogic: meson-gx: fix SCPI clock dvfs node name
+    - arm64: dts: amlogic: meson-axg: fix SCPI clock dvfs node name
+    - arm64: dts: amlogic: meson-gx: add missing SCPI sensors compatible
+    - arm64: dts: amlogic: meson-axg-jethome-jethub-j1xx: fix supply name of USB
+      controller node
+    - arm64: dts: amlogic: meson-gxl-s905d-sml5442tw: drop invalid clock-names
+      property
+    - arm64: dts: amlogic: meson-gx: add missing unit address to rng node name
+    - arm64: dts: amlogic: meson-gxl-s905w-jethome-jethub-j80: fix invalid rtc
+      node name
+    - arm64: dts: amlogic: meson-axg-jethome-jethub-j1xx: fix invalid rtc node
+      name
+    - arm64: dts: amlogic: meson-gxl: add missing unit address to eth-phy-mux node
+      name
+    - arm64: dts: amlogic: meson-gx-libretech-pc: fix update button name
+    - arm64: dts: amlogic: meson-sm1-bananapi-m5: fix adc keys node names
+    - arm64: dts: amlogic: meson-gxl-s905d-phicomm-n1: fix led node name
+    - arm64: dts: amlogic: meson-gxbb-kii-pro: fix led node name
+    - arm64: dts: amlogic: meson-g12b-odroid-go-ultra: fix rk818 pmic properties
+    - arm64: dts: amlogic: meson-sm1-odroid-hc4: fix active fan thermal trip
+    - locking/rwsem: Disable preemption in all down_read*() and up_read() code
+      paths
+    - arm64: tegra: Mark host1x as dma-coherent on Tegra194/234
+    - arm64: dts: renesas: beacon-renesom: Fix gpio expander reference
+    - arm64: dts: meson: radxa-zero: allow usb otg mode
+    - arm64: dts: meson: bananapi-m5: switch VDDIO_C pin to OPEN_DRAIN
+    - ARM: dts: sun8i: nanopi-duo2: Fix regulator GPIO reference
+    - ublk_drv: remove nr_aborted_queues from ublk_device
+    - ublk_drv: don't probe partitions if the ubq daemon isn't trusted
+    - ARM: dts: imx7s: correct iomuxc gpr mux controller cells
+    - sbitmap: remove redundant check in __sbitmap_queue_get_batch
+    - sbitmap: correct wake_batch recalculation to avoid potential IO hung
+    - arm64: dts: mt8195: Fix CPU map for single-cluster SoC
+    - arm64: dts: mt8192: Fix CPU map for single-cluster SoC
+    - arm64: dts: mt8186: Fix CPU map for single-cluster SoC
+    - arm64: dts: mediatek: mt7622: Add missing pwm-cells to pwm node
+    - arm64: dts: mediatek: mt8186: Fix watchdog compatible
+    - arm64: dts: mediatek: mt8195: Fix watchdog compatible
+    - arm64: dts: mediatek: mt7986: Fix watchdog compatible
+    - ARM: dts: stm32: Update part number NVMEM description on stm32mp131
+    - arm64: dts: qcom: sm8450-nagara: Correct firmware paths
+    - blk-mq: avoid sleep in blk_mq_alloc_request_hctx
+    - blk-mq: remove stale comment for blk_mq_sched_mark_restart_hctx
+    - blk-mq: wait on correct sbitmap_queue in blk_mq_mark_tag_wait
+    - blk-mq: Fix potential io hung for shared sbitmap per tagset
+    - blk-mq: correct stale comment of .get_budget
+    - arm64: dts: qcom: msm8996: support using GPLL0 as kryocc input
+    - arm64: dts: qcom: msm8996 switch from RPM_SMD_BB_CLK1 to RPM_SMD_XO_CLK_SRC
+    - arm64: dts: qcom: sm8350: drop incorrect cells from serial
+    - arm64: dts: qcom: sm8450: drop incorrect cells from serial
+    - arm64: dts: qcom: msm8992-lg-bullhead: Correct memory overlaps with the SMEM
+      and MPSS memory regions
+    - arm64: dts: qcom: msm8953: correct TLMM gpio-ranges
+    - arm64: dts: qcom: sm6115: correct TLMM gpio-ranges
+    - arm64: dts: qcom: msm8992-lg-bullhead: Enable regulators
+    - s390/dasd: Fix potential memleak in dasd_eckd_init()
+    - io_uring,audit: don't log IORING_OP_MADVISE
+    - sched/rt: pick_next_rt_entity(): check list_entry
+    - perf/x86/intel/ds: Fix the conversion from TSC to perf time
+    - x86/perf/zhaoxin: Add stepping check for ZXC
+    - KEYS: asymmetric: Fix ECDSA use via keyctl uapi
+    - block: ublk: check IO buffer based on flag need_get_data
+    - arm64: dts: qcom: pmk8350: Use the correct PON compatible
+    - erofs: relinquish volume with mutex held
+    - block: sync mixed merged request's failfast with 1st bio's
+    - block: Fix io statistics for cgroup in throttle path
+    - block: bio-integrity: Copy flags when bio_integrity_payload is cloned
+    - block: use proper return value from bio_failfast()
+    - wifi: mt76: mt7915: add missing of_node_put()
+    - wifi: mt76: mt7921s: fix slab-out-of-bounds access in sdio host
+    - wifi: mt76: mt7915: fix mt7915_rate_txpower_get() resource leaks
+    - wifi: mt76: mt7996: fix insecure data handling of mt7996_mcu_ie_countdown()
+    - wifi: mt76: mt7996: fix insecure data handling of
+      mt7996_mcu_rx_radar_detected()
+    - wifi: mt76: mt7996: fix integer handling issue of mt7996_rf_regval_set()
+    - wifi: mt76: mt7915: check return value before accessing free_block_num
+    - wifi: mt76: mt7996: check return value before accessing free_block_num
+    - wifi: mt76: mt7915: drop always true condition of __mt7915_reg_addr()
+    - wifi: mt76: mt7996: drop always true condition of __mt7996_reg_addr()
+    - wifi: mt76: mt7996: fix endianness warning in mt7996_mcu_sta_he_tlv
+    - wifi: mt76: mt76x0: fix oob access in mt76x0_phy_get_target_power
+    - wifi: mt76: mt7996: fix unintended sign extension of mt7996_hw_queue_read()
+    - wifi: mt76: mt7915: fix unintended sign extension of mt7915_hw_queue_read()
+    - wifi: mt76: fix coverity uninit_use_in_call in
+      mt76_connac2_reverse_frag0_hdr_trans()
+    - wifi: mt76: mt7921: resource leaks at mt7921_check_offload_capability()
+    - wifi: rsi: Fix memory leak in rsi_coex_attach()
+    - wifi: rtlwifi: rtl8821ae: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: rtlwifi: rtl8188ee: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: rtlwifi: rtl8723be: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: iwlegacy: common: don't call dev_kfree_skb() under spin_lock_irqsave()
+    - wifi: libertas: fix memory leak in lbs_init_adapter()
+    - wifi: rtl8xxxu: Fix assignment to bit field priv->pi_enabled
+    - wifi: rtl8xxxu: Fix assignment to bit field priv->cck_agc_report_type
+    - wifi: rtl8xxxu: don't call dev_kfree_skb() under spin_lock_irqsave()
+    - wifi: rtw89: 8852c: rfk: correct DACK setting
+    - wifi: rtw89: 8852c: rfk: correct DPK settings
+    - wifi: rtlwifi: Fix global-out-of-bounds bug in
+      _rtl8812ae_phy_set_txpower_limit()
+    - libbpf: Fix single-line struct definition output in btf_dump
+    - libbpf: Fix btf__align_of() by taking into account field offsets
+    - wifi: ipw2x00: don't call dev_kfree_skb() under spin_lock_irqsave()
+    - wifi: ipw2200: fix memory leak in ipw_wdev_init()
+    - wifi: wilc1000: fix potential memory leak in wilc_mac_xmit()
+    - wifi: wilc1000: add missing unregister_netdev() in wilc_netdev_ifc_init()
+    - wifi: brcmfmac: fix potential memory leak in brcmf_netdev_start_xmit()
+    - wifi: brcmfmac: unmap dma buffer in brcmf_msgbuf_alloc_pktid()
+    - wifi: libertas_tf: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: libertas: if_usb: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: libertas: main: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: libertas: cmdresp: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: wl3501_cs: don't call kfree_skb() under spin_lock_irqsave()
+    - libbpf: Fix invalid return address register in s390
+    - crypto: x86/ghash - fix unaligned access in ghash_setkey()
+    - crypto: ux500 - update debug config after ux500 cryp driver removal
+    - ACPICA: Drop port I/O validation for some regions
+    - genirq: Fix the return type of kstat_cpu_irqs_sum()
+    - rcu-tasks: Improve comments explaining tasks_rcu_exit_srcu purpose
+    - rcu-tasks: Remove preemption disablement around srcu_read_[un]lock() calls
+    - rcu-tasks: Fix synchronize_rcu_tasks() VS zap_pid_ns_processes()
+    - lib/mpi: Fix buffer overrun when SG is too long
+    - crypto: ccp - Avoid page allocation failure warning for SEV_GET_ID2
+    - platform/chrome: cros_ec_typec: Update port DP VDO
+    - ACPICA: nsrepair: handle cases without a return value correctly
+    - libbpf: Fix map creation flags sanitization
+    - bpf_doc: Fix build error with older python versions
+    - selftests/xsk: print correct payload for packet dump
+    - selftests/xsk: print correct error codes when exiting
+    - arm64/cpufeature: Fix field sign for DIT hwcap detection
+    - arm64/sysreg: Fix errors in 32 bit enumeration values
+    - kselftest/arm64: Fix syscall-abi for systems without 128 bit SME
+    - workqueue: Protects wq_unbound_cpumask with wq_pool_attach_mutex
+    - s390/early: fix sclp_early_sccb variable lifetime
+    - s390/vfio-ap: fix an error handling path in vfio_ap_mdev_probe_queue()
+    - x86/signal: Fix the value returned by strict_sas_size()
+    - thermal/drivers/tsens: Drop msm8976-specific defines
+    - thermal/drivers/tsens: Sort out msm8976 vs msm8956 data
+    - thermal/drivers/tsens: fix slope values for msm8939
+    - thermal/drivers/tsens: limit num_sensors to 9 for msm8939
+    - wifi: rtw89: fix potential leak in rtw89_append_probe_req_ie()
+    - wifi: rtw89: Add missing check for alloc_workqueue
+    - wifi: rtl8xxxu: Fix memory leaks with RTL8723BU, RTL8192EU
+    - wifi: orinoco: check return value of hermes_write_wordrec()
+    - wifi: rtw88: Use rtw_iterate_vifs() for rtw_vif_watch_dog_iter()
+    - wifi: rtw88: Use non-atomic sta iterator in rtw_ra_mask_info_update()
+    - thermal/drivers/imx_sc_thermal: Fix the loop condition
+    - wifi: ath9k: htc_hst: free skb in ath9k_htc_rx_msg() if there is no callback
+      function
+    - wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
+    - wifi: ath9k: Fix potential stack-out-of-bounds write in
+      ath9k_wmi_rsp_callback()
+    - wifi: ath11k: Fix memory leak in ath11k_peer_rx_frag_setup
+    - wifi: cfg80211: Fix extended KCK key length check in
+      nl80211_set_rekey_data()
+    - ACPI: battery: Fix missing NUL-termination with large strings
+    - selftests/bpf: Fix build errors if CONFIG_NF_CONNTRACK=m
+    - crypto: ccp - Failure on re-initialization due to duplicate sysfs filename
+    - crypto: essiv - Handle EBUSY correctly
+    - crypto: seqiv - Handle EBUSY correctly
+    - powercap: fix possible name leak in powercap_register_zone()
+    - bpf: Fix state pruning for STACK_DYNPTR stack slots
+    - bpf: Fix missing var_off check for ARG_PTR_TO_DYNPTR
+    - bpf: Fix partial dynptr stack slot reads/writes
+    - x86/microcode: Add a parameter to microcode_check() to store CPU
+      capabilities
+    - x86/microcode: Check CPU capabilities after late microcode update correctly
+    - x86/microcode: Adjust late loading result reporting message
+    - net: ethernet: ti: am65-cpsw/cpts: Fix CPTS release action
+    - selftests/bpf: Fix vmtest static compilation error
+    - crypto: xts - Handle EBUSY correctly
+    - leds: led-class: Add missing put_device() to led_put()
+    - drm/nouveau/disp: Fix nvif_outp_acquire_dp() argument size
+    - s390/bpf: Add expoline to tail calls
+    - wifi: iwlwifi: mei: fix compilation errors in rfkill()
+    - kselftest/arm64: Fix enumeration of systems without 128 bit SME
+    - can: rcar_canfd: Fix R-Car V3U CAN mode selection
+    - can: rcar_canfd: Fix R-Car V3U GAFLCFG field accesses
+    - selftests/bpf: Initialize tc in xdp_synproxy
+    - crypto: ccp - Flush the SEV-ES TMR memory before giving it to firmware
+    - bpftool: profile online CPUs instead of possible
+    - wifi: mt76: mt7921: fix deadlock in mt7921_abort_roc
+    - wifi: mt76: mt7915: call mt7915_mcu_set_thermal_throttling() only after
+      init_work
+    - wifi: mt76: mt7915: rework mt7915_mcu_set_thermal_throttling
+    - wifi: mt76: mt7915: rework mt7915_thermal_temp_store()
+    - wifi: mt76: mt7921: fix channel switch fail in monitor mode
+    - wifi: mt76: mt7996: fix chainmask calculation in mt7996_set_antenna()
+    - wifi: mt76: mt7996: update register for CFEND_RATE
+    - wifi: mt76: connac: fix POWER_CTRL command name typo
+    - wifi: mt76: mt7921: fix invalid remain_on_channel duration
+    - wifi: mt76: mt7915: fix memory leak in mt7915_mcu_exit
+    - wifi: mt76: mt7996: fix memory leak in mt7996_mcu_exit
+    - wifi: mt76: dma: fix memory leak running mt76_dma_tx_cleanup
+    - wifi: mt76: fix switch default case in mt7996_reverse_frag0_hdr_trans
+    - wifi: mt76: mt7915: fix WED TxS reporting
+    - wifi: mt76: add memory barrier to SDIO queue kick
+    - wifi: mt76: mt7996: rely on mt76_connac2_mac_tx_rate_val
+    - net/mlx5: Enhance debug print in page allocation failure
+    - irqchip: Fix refcount leak in platform_irqchip_probe
+    - irqchip/alpine-msi: Fix refcount leak in alpine_msix_init_domains
+    - irqchip/irq-mvebu-gicp: Fix refcount leak in mvebu_gicp_probe
+    - irqchip/ti-sci: Fix refcount leak in ti_sci_intr_irq_domain_probe
+    - s390/mem_detect: fix detect_memory() error handling
+    - s390/vmem: fix empty page tables cleanup under KASAN
+    - s390/boot: cleanup decompressor header files
+    - s390/mem_detect: rely on diag260() if sclp_early_get_memsize() fails
+    - s390/boot: fix mem_detect extended area allocation
+    - net: add sock_init_data_uid()
+    - tun: tun_chr_open(): correctly initialize socket uid
+    - tap: tap_open(): correctly initialize socket uid
+    - rxrpc: Fix overwaking on call poking
+    - OPP: fix error checking in opp_migrate_dentry()
+    - cpufreq: davinci: Fix clk use after free
+    - Bluetooth: hci_conn: Refactor hci_bind_bis() since it always succeeds
+    - Bluetooth: L2CAP: Fix potential user-after-free
+    - Bluetooth: hci_qca: get wakeup status from serdev device handle
+    - net: ipa: generic command param fix
+    - s390: vfio-ap: tighten the NIB validity check
+    - s390/ap: fix status returned by ap_aqic()
+    - s390/ap: fix status returned by ap_qact()
+    - libbpf: Fix alen calculation in libbpf_nla_dump_errormsg()
+    - xen/grant-dma-iommu: Implement a dummy probe_device() callback
+    - rds: rds_rm_zerocopy_callback() correct order for list_add_tail()
+    - crypto: rsa-pkcs1pad - Use akcipher_request_complete
+    - m68k: /proc/hardware should depend on PROC_FS
+    - RISC-V: time: initialize hrtimer based broadcast clock event device
+    - clocksource/drivers/riscv: Patch riscv_clock_next_event() jump before first
+      use
+    - wifi: iwl3945: Add missing check for create_singlethread_workqueue
+    - wifi: iwl4965: Add missing check for create_singlethread_workqueue()
+    - wifi: brcmfmac: Rename Cypress 89459 to BCM4355
+    - wifi: brcmfmac: pcie: Add IDs/properties for BCM4355
+    - wifi: brcmfmac: pcie: Add IDs/properties for BCM4377
+    - wifi: brcmfmac: pcie: Perform correct BCM4364 firmware selection
+    - wifi: mwifiex: fix loop iterator in mwifiex_update_ampdu_txwinsize()
+    - wifi: rtw89: fix parsing offset for MCC C2H
+    - selftests/bpf: Fix out-of-srctree build
+    - ACPI: resource: Add IRQ overrides for MAINGEAR Vector Pro 2 models
+    - ACPI: resource: Do IRQ override on all TongFang GMxRGxx
+    - crypto: octeontx2 - Fix objects shared between several modules
+    - crypto: crypto4xx - Call dma_unmap_page when done
+    - vfio/ccw: remove WARN_ON during shutdown
+    - wifi: mac80211: move color collision detection report in a delayed work
+    - wifi: mac80211: make rate u32 in sta_set_rate_info_rx()
+    - wifi: mac80211: fix non-MLO station association
+    - wifi: mac80211: Don't translate MLD addresses for multicast
+    - wifi: mac80211: avoid u32_encode_bits() warning
+    - wifi: mac80211: fix off-by-one link setting
+    - tools/lib/thermal: Fix thermal_sampling_exit()
+    - thermal/drivers/hisi: Drop second sensor hi3660
+    - selftests/bpf: Fix map_kptr test.
+    - wifi: mac80211: pass 'sta' to ieee80211_rx_data_set_sta()
+    - bpf: Zeroing allocated object from slab in bpf memory allocator
+    - selftests/bpf: Fix xdp_do_redirect on s390x
+    - can: esd_usb: Move mislocated storage of SJA1000_ECC_SEG bits in case of a
+      bus error
+    - can: esd_usb: Make use of can_change_state() and relocate checking skb for
+      NULL
+    - xsk: check IFF_UP earlier in Tx path
+    - LoongArch, bpf: Use 4 instructions for function address in JIT
+    - bpf: Fix global subprog context argument resolution logic
+    - irqchip/irq-brcmstb-l2: Set IRQ_LEVEL for level triggered interrupts
+    - irqchip/irq-bcm7120-l2: Set IRQ_LEVEL for level triggered interrupts
+    - net/smc: fix potential panic dues to unprotected smc_llc_srv_add_link()
+    - net/smc: fix application data exception
+    - selftests/net: Interpret UDP_GRO cmsg data as an int value
+    - l2tp: Avoid possible recursive deadlock in l2tp_tunnel_register()
+    - net: bcmgenet: fix MoCA LED control
+    - net: lan966x: Fix possible deadlock inside PTP
+    - net/mlx4_en: Introduce flexible array to silence overflow warning
+    - net/mlx5e: Align IPsec ASO result memory to be as required by hardware
+    - selftest: fib_tests: Always cleanup before exit
+    - sefltests: netdevsim: wait for devlink instance after netns removal
+    - drm: Fix potential null-ptr-deref due to drmm_mode_config_init()
+    - drm/fourcc: Add missing big-endian XRGB1555 and RGB565 formats
+    - drm/bridge: ti-sn65dsi83: Fix delay after reset deassert to match spec
+    - drm: mxsfb: DRM_IMX_LCDIF should depend on ARCH_MXC
+    - drm: mxsfb: DRM_MXSFB should depend on ARCH_MXS || ARCH_MXC
+    - drm/bridge: megachips: Fix error handling in i2c_register_driver()
+    - drm/vkms: Fix memory leak in vkms_init()
+    - drm/vkms: Fix null-ptr-deref in vkms_release()
+    - drm/modes: Use strscpy() to copy command-line mode name
+    - drm/vc4: dpi: Fix format mapping for RGB565
+    - drm/bridge: it6505: Guard bridge power in IRQ handler
+    - drm: tidss: Fix pixel format definition
+    - gpu: ipu-v3: common: Add of_node_put() for reference returned by
+      of_graph_get_port_by_id()
+    - drm/ast: Init iosys_map pointer as I/O memory for damage handling
+    - drm/vc4: drop all currently held locks if deadlock happens
+    - hwmon: (ftsteutates) Fix scaling of measurements
+    - drm/msm/dpu: check for null return of devm_kzalloc() in dpu_writeback_init()
+    - drm/msm/hdmi: Add missing check for alloc_ordered_workqueue
+    - pinctrl: qcom: pinctrl-msm8976: Correct function names for wcss pins
+    - pinctrl: stm32: Fix refcount leak in stm32_pctrl_get_irq_domain
+    - pinctrl: rockchip: Fix refcount leak in rockchip_pinctrl_parse_groups
+    - drm/vc4: hvs: Configure the HVS COB allocations
+    - drm/vc4: hvs: Set AXI panic modes
+    - drm/vc4: hvs: SCALER_DISPBKGND_AUTOHS is only valid on HVS4
+    - drm/vc4: hvs: Correct interrupt masking bit assignment for HVS5
+    - drm/vc4: hvs: Fix colour order for xRGB1555 on HVS5
+    - drm/vc4: hdmi: Correct interlaced timings again
+    - drm/msm: clean event_thread->worker in case of an error
+    - drm/panel-edp: fix name for IVO product id 854b
+    - scsi: qla2xxx: Fix exchange oversubscription
+    - scsi: qla2xxx: Fix exchange oversubscription for management commands
+    - scsi: qla2xxx: edif: Fix clang warning
+    - ASoC: fsl_sai: initialize is_dsp_mode flag
+    - drm/bridge: tc358767: Set default CLRSIPO count
+    - drm/msm/adreno: Fix null ptr access in adreno_gpu_cleanup()
+    - ALSA: hda/ca0132: minor fix for allocation size
+    - drm/amdgpu: Use the sched from entity for amdgpu_cs trace
+    - drm/msm/gem: Add check for kmalloc
+    - drm/msm/dpu: Disallow unallocated resources to be returned
+    - drm/bridge: lt9611: fix sleep mode setup
+    - drm/bridge: lt9611: fix HPD reenablement
+    - drm/bridge: lt9611: fix polarity programming
+    - drm/bridge: lt9611: fix programming of video modes
+    - drm/bridge: lt9611: fix clock calculation
+    - drm/bridge: lt9611: pass a pointer to the of node
+    - regulator: tps65219: use IS_ERR() to detect an error pointer
+    - drm/mipi-dsi: Fix byte order of 16-bit DCS set/get brightness
+    - drm: exynos: dsi: Fix MIPI_DSI*_NO_* mode flags
+    - drm/msm/dsi: Allow 2 CTRLs on v2.5.0
+    - scsi: ufs: exynos: Fix DMA alignment for PAGE_SIZE != 4096
+    - drm/msm/dpu: sc7180: add missing WB2 clock control
+    - drm/msm: use strscpy instead of strncpy
+    - drm/msm/dpu: Add check for cstate
+    - drm/msm/dpu: Add check for pstates
+    - drm/msm/mdp5: Add check for kzalloc
+    - habanalabs: bugs fixes in timestamps buff alloc
+    - pinctrl: bcm2835: Remove of_node_put() in bcm2835_of_gpio_ranges_fallback()
+    - pinctrl: mediatek: Initialize variable pullen and pullup to zero
+    - pinctrl: mediatek: Initialize variable *buf to zero
+    - gpu: host1x: Fix mask for syncpoint increment register
+    - gpu: host1x: Don't skip assigning syncpoints to channels
+    - drm/tegra: firewall: Check for is_addr_reg existence in IMM check
+    - drm/i915/mtl: Add initial gt workarounds
+    - drm/i915/xehp: GAM registers don't need to be re-applied on engine resets
+    - pinctrl: renesas: rzg2l: Fix configuring the GPIO pins as interrupts
+    - drm/i915/xehp: Annotate a couple more workaround registers as MCR
+    - drm/msm/dpu: set pdpu->is_rt_pipe early in dpu_plane_sspp_atomic_update()
+    - drm/mediatek: dsi: Reduce the time of dsi from LP11 to sending cmd
+    - drm/mediatek: Use NULL instead of 0 for NULL pointer
+    - drm/mediatek: Drop unbalanced obj unref
+    - drm/mediatek: mtk_drm_crtc: Add checks for devm_kcalloc
+    - drm/mediatek: Clean dangling pointer on bind error path
+    - ASoC: soc-compress.c: fixup private_data on snd_soc_new_compress()
+    - dt-bindings: display: mediatek: Fix the fallback for mediatek,mt8186-disp-
+      ccorr
+    - gpio: pca9570: rename platform_data to chip_data
+    - gpio: vf610: connect GPIO label to dev name
+    - ASoC: topology: Properly access value coming from topology file
+    - spi: dw_bt1: fix MUX_MMIO dependencies
+    - ASoC: mchp-spdifrx: fix controls which rely on rsr register
+    - ASoC: mchp-spdifrx: fix return value in case completion times out
+    - ASoC: mchp-spdifrx: fix controls that works with completion mechanism
+    - ASoC: mchp-spdifrx: disable all interrupts in mchp_spdifrx_dai_remove()
+    - dm: improve shrinker debug names
+    - regmap: apply reg_base and reg_downshift for single register ops
+    - accel: fix CONFIG_DRM dependencies
+    - ASoC: rsnd: fixup #endif position
+    - ASoC: mchp-spdifrx: Fix uninitialized use of mr in mchp_spdifrx_hw_params()
+    - ASoC: dt-bindings: meson: fix gx-card codec node regex
+    - regulator: tps65219: use generic set_bypass()
+    - hwmon: (asus-ec-sensors) add missing mutex path
+    - hwmon: (ltc2945) Handle error case in ltc2945_value_store
+    - ALSA: hda: Fix the control element identification for multiple codecs
+    - drm/amdgpu: fix enum odm_combine_mode mismatch
+    - scsi: mpt3sas: Fix a memory leak
+    - scsi: aic94xx: Add missing check for dma_map_single()
+    - HID: multitouch: Add quirks for flipped axes
+    - HID: retain initial quirks set up when creating HID devices
+    - ASoC: qcom: q6apm-lpass-dai: unprepare stream if its already prepared
+    - ASoC: qcom: q6apm-dai: fix race condition while updating the position
+      pointer
+    - ASoC: qcom: q6apm-dai: Add SNDRV_PCM_INFO_BATCH flag
+    - ASoC: codecs: lpass: register mclk after runtime pm
+    - ASoC: codecs: lpass: fix incorrect mclk rate
+    - drm/amd/display: don't call dc_interrupt_set() for disabled crtcs
+    - HID: logitech-hidpp: Hard-code HID++ 1.0 fast scroll support
+    - spi: bcm63xx-hsspi: Fix multi-bit mode setting
+    - hwmon: (mlxreg-fan) Return zero speed for broken fan
+    - ASoC: tlv320adcx140: fix 'ti,gpio-config' DT property init
+    - dm: remove flush_scheduled_work() during local_exit()
+    - nfs4trace: fix state manager flag printing
+    - NFS: fix disabling of swap
+    - drm/i915/pvc: Implement recommended caching policy
+    - drm/i915/pvc: Annotate two more workaround/tuning registers as MCR
+    - drm/i915: Fix GEN8_MISCCPCTL
+    - spi: synquacer: Fix timeout handling in synquacer_spi_transfer_one()
+    - ASoC: soc-dapm.h: fixup warning struct snd_pcm_substream not declared
+    - HID: bigben: use spinlock to protect concurrent accesses
+    - HID: bigben_worker() remove unneeded check on report_field
+    - HID: bigben: use spinlock to safely schedule workers
+    - hid: bigben_probe(): validate report count
+    - ALSA: hda/hdmi: Register with vga_switcheroo on Dual GPU Macbooks
+    - drm/shmem-helper: Fix locking for drm_gem_shmem_get_pages_sgt()
+    - NFSD: enhance inter-server copy cleanup
+    - NFSD: fix leaked reference count of nfsd4_ssc_umount_item
+    - nfsd: fix race to check ls_layouts
+    - nfsd: clean up potential nfsd_file refcount leaks in COPY codepath
+    - NFSD: fix problems with cleanup on errors in nfsd4_copy
+    - nfsd: fix courtesy client with deny mode handling in nfs4_upgrade_open
+    - nfsd: don't fsync nfsd_files on last close
+    - NFSD: copy the whole verifier in nfsd_copy_write_verifier
+    - cifs: Fix lost destroy smbd connection when MR allocate failed
+    - cifs: Fix warning and UAF when destroy the MR list
+    - cifs: use tcon allocation functions even for dummy tcon
+    - gfs2: jdata writepage fix
+    - perf llvm: Fix inadvertent file creation
+    - leds: led-core: Fix refcount leak in of_led_get()
+    - leds: is31fl319x: Wrap mutex_destroy() for devm_add_action_or_rest()
+    - leds: simatic-ipc-leds-gpio: Make sure we have the GPIO providing driver
+    - tools/tracing/rtla: osnoise_hist: use total duration for average calculation
+    - perf inject: Use perf_data__read() for auxtrace
+    - perf intel-pt: Do not try to queue auxtrace data on pipe
+    - perf stat: Hide invalid uncore event output for aggr mode
+    - perf jevents: Correct bad character encoding
+    - perf test bpf: Skip test if kernel-debuginfo is not present
+    - perf tools: Fix auto-complete on aarch64
+    - perf stat: Avoid merging/aggregating metric counts twice
+    - sparc: allow PM configs for sparc32 COMPILE_TEST
+    - selftests: find echo binary to use -ne options
+    - selftests/ftrace: Fix bash specific "==" operator
+    - selftests: use printf instead of echo -ne
+    - perf record: Fix segfault with --overwrite and --max-size
+    - printf: fix errname.c list
+    - perf tests stat_all_metrics: Change true workload to sleep workload for
+      system wide check
+    - objtool: add UACCESS exceptions for __tsan_volatile_read/write
+    - selftests/ftrace: Fix probepoint testcase to ignore __pfx_* symbols
+    - sysctl: fix proc_dobool() usability
+    - mfd: rk808: Re-add rk808-clkout to RK818
+    - mfd: cs5535: Don't build on UML
+    - mfd: pcf50633-adc: Fix potential memleak in pcf50633_adc_async_read()
+    - dmaengine: idxd: Set traffic class values in GRPCFG on DSA 2.0
+    - RDMA/erdma: Fix refcount leak in erdma_mmap
+    - dmaengine: HISI_DMA should depend on ARCH_HISI
+    - RDMA/hns: Fix refcount leak in hns_roce_mmap
+    - iio: light: tsl2563: Do not hardcode interrupt trigger type
+    - usb: gadget: fusb300_udc: free irq on the error path in fusb300_probe()
+    - i2c: designware: fix i2c_dw_clk_rate() return size to be u32
+    - i2c: qcom-geni: change i2c_master_hub to static
+    - soundwire: cadence: Don't overflow the command FIFOs
+    - driver core: fix potential null-ptr-deref in device_add()
+    - kobject: Fix slab-out-of-bounds in fill_kobj_path()
+    - alpha/boot/tools/objstrip: fix the check for ELF header
+    - media: uvcvideo: Check for INACTIVE in uvc_ctrl_is_accessible()
+    - media: uvcvideo: Implement mask for V4L2_CTRL_TYPE_MENU
+    - media: uvcvideo: Refactor uvc_ctrl_mappings_uvcXX
+    - media: uvcvideo: Refactor power_line_frequency_controls_limited
+    - coresight: etm4x: Fix accesses to TRCSEQRSTEVR and TRCSEQSTR
+    - coresight: cti: Prevent negative values of enable count
+    - coresight: cti: Add PM runtime call in enable_store
+    - usb: typec: intel_pmc_mux: Don't leak the ACPI device reference count
+    - PCI/IOV: Enlarge virtfn sysfs name buffer
+    - PCI: switchtec: Return -EFAULT for copy_to_user() errors
+    - PCI: endpoint: pci-epf-vntb: Add epf_ntb_mw_bar_clear() num_mws kernel-doc
+    - hwtracing: hisi_ptt: Only add the supported devices to the filters list
+    - tty: serial: fsl_lpuart: disable Rx/Tx DMA in lpuart32_shutdown()
+    - tty: serial: fsl_lpuart: clear LPUART Status Register in lpuart32_shutdown()
+    - serial: tegra: Add missing clk_disable_unprepare() in tegra_uart_hw_init()
+    - Revert "char: pcmcia: cm4000_cs: Replace mdelay with usleep_range in
+      set_protocol"
+    - eeprom: idt_89hpesx: Fix error handling in idt_init()
+    - applicom: Fix PCI device refcount leak in applicom_init()
+    - firmware: stratix10-svc: add missing gen_pool_destroy() in
+      stratix10_svc_drv_probe()
+    - firmware: stratix10-svc: fix error handle while alloc/add device failed
+    - VMCI: check context->notify_page after call to get_user_pages_fast() to
+      avoid GPF
+    - mei: pxp: Use correct macros to initialize uuid_le
+    - misc/mei/hdcp: Use correct macros to initialize uuid_le
+    - misc: fastrpc: Fix an error handling path in fastrpc_rpmsg_probe()
+    - iommu/exynos: Fix error handling in exynos_iommu_init()
+    - driver core: fix resource leak in device_add()
+    - driver core: location: Free struct acpi_pld_info *pld before return false
+    - drivers: base: transport_class: fix possible memory leak
+    - drivers: base: transport_class: fix resource leak when
+      transport_add_device() fails
+    - firmware: dmi-sysfs: Fix null-ptr-deref in dmi_sysfs_register_handle
+    - selftests: iommu: Fix test_cmd_destroy_access() call in user_copy
+    - iommufd: Add three missing structures in ucmd_buffer
+    - fotg210-udc: Add missing completion handler
+    - dmaengine: dw-edma: Fix missing src/dst address of interleaved xfers
+    - fpga: microchip-spi: move SPI I/O buffers out of stack
+    - fpga: microchip-spi: rewrite status polling in a time measurable way
+    - usb: early: xhci-dbc: Fix a potential out-of-bound memory access
+    - tty: serial: fsl_lpuart: Fix the wrong RXWATER setting for rx dma case
+    - RDMA/cxgb4: add null-ptr-check after ip_dev_find()
+    - usb: musb: mediatek: don't unregister something that wasn't registered
+    - usb: gadget: configfs: Restrict symlink creation is UDC already binded
+    - phy: mediatek: remove temporary variable @mask_
+    - PCI: mt7621: Delay phy ports initialization
+    - iommu/vt-d: Set No Execute Enable bit in PASID table entry
+    - power: supply: remove faulty cooling logic
+    - RDMA/siw: Fix user page pinning accounting
+    - RDMA/cxgb4: Fix potential null-ptr-deref in pass_establish()
+    - usb: max-3421: Fix setting of I/O pins
+    - RDMA/irdma: Cap MSIX used to online CPUs + 1
+    - serial: fsl_lpuart: fix RS485 RTS polariy inverse issue
+    - tty: serial: imx: disable Ageing Timer interrupt request irq
+    - driver core: fw_devlink: Add DL_FLAG_CYCLE support to device links
+    - driver core: fw_devlink: Don't purge child fwnode's consumer links
+    - driver core: fw_devlink: Allow marking a fwnode link as being part of a
+      cycle
+    - driver core: fw_devlink: Consolidate device link flag computation
+    - driver core: fw_devlink: Improve check for fwnode with no device/driver
+    - driver core: fw_devlink: Make cycle detection more robust
+    - mtd: mtdpart: Don't create platform device that'll never probe
+    - usb: host: fsl-mph-dr-of: reuse device_set_of_node_from_dev
+    - dmaengine: dw-edma: Fix readq_ch() return value truncation
+    - PCI: Fix dropping valid root bus resources with .end = zero
+    - phy: rockchip-typec: fix tcphy_get_mode error case
+    - PCI: qcom: Fix host-init error handling
+    - iw_cxgb4: Fix potential NULL dereference in c4iw_fill_res_cm_id_entry()
+    - iommu: Fix error unwind in iommu_group_alloc()
+    - iommu/amd: Do not identity map v2 capable device when snp is enabled
+    - dmaengine: sf-pdma: pdma_desc memory leak fix
+    - dmaengine: dw-axi-dmac: Do not dereference NULL structure
+    - dmaengine: ptdma: check for null desc before calling pt_cmd_callback
+    - iommu/vt-d: Fix error handling in sva enable/disable paths
+    - iommu/vt-d: Allow to use flush-queue when first level is default
+    - RDMA/rxe: Cleanup mr_check_range
+    - RDMA/rxe: Move rxe_map_mr_sg to rxe_mr.c
+    - RDMA-rxe: Isolate mr code from atomic_reply()
+    - RDMA-rxe: Isolate mr code from atomic_write_reply()
+    - RDMA/rxe: Cleanup page variables in rxe_mr.c
+    - RDMA/rxe: Replace rxe_map and rxe_phys_buf by xarray
+    - Subject: RDMA/rxe: Handle zero length rdma
+    - RDMA/mana_ib: Fix a bug when the PF indicates more entries for registering
+      memory on first packet
+    - RDMA/rxe: Fix missing memory barriers in rxe_queue.h
+    - IB/hfi1: Fix math bugs in hfi1_can_pin_pages()
+    - IB/hfi1: Fix sdma.h tx->num_descs off-by-one errors
+    - Revert "remoteproc: qcom_q6v5_mss: map/unmap metadata region before/after
+      use"
+    - remoteproc: qcom_q6v5_mss: Use a carveout to authenticate modem headers
+    - media: ti: cal: fix possible memory leak in cal_ctx_create()
+    - media: platform: ti: Add missing check for devm_regulator_get
+    - media: imx: imx7-media-csi: fix missing clk_disable_unprepare() in
+      imx7_csi_init()
+    - powerpc: Remove linker flag from KBUILD_AFLAGS
+    - s390/vdso: Drop '-shared' from KBUILD_CFLAGS_64
+    - builddeb: clean generated package content
+    - media: max9286: Fix memleak in max9286_v4l2_register()
+    - media: ov2740: Fix memleak in ov2740_init_controls()
+    - media: ov5675: Fix memleak in ov5675_init_controls()
+    - media: i2c: tc358746: fix missing return assignment
+    - media: i2c: tc358746: fix ignoring read error in g_register callback
+    - media: i2c: tc358746: fix possible endianness issue
+    - media: ov5640: Fix soft reset sequence and timings
+    - media: ov5640: Handle delays when no reset_gpio set
+    - media: mc: Get media_device directly from pad
+    - media: i2c: ov772x: Fix memleak in ov772x_probe()
+    - media: i2c: imx219: Split common registers from mode tables
+    - media: i2c: imx219: Fix binning for RAW8 capture
+    - media: platform: mtk-mdp3: Fix return value check in mdp_probe()
+    - media: camss: csiphy-3ph: avoid undefined behavior
+    - media: platform: mtk-mdp3: fix Kconfig dependencies
+    - media: v4l2-jpeg: correct the skip count in jpeg_parse_app14_data
+    - media: v4l2-jpeg: ignore the unknown APP14 marker
+    - media: hantro: Fix JPEG encoder ENUM_FRMSIZE on RK3399
+    - media: imx-jpeg: Apply clk_bulk api instead of operating specific clk
+    - media: amphion: correct the unspecified color space
+    - media: drivers/media/v4l2-core/v4l2-h264 : add detection of null pointers
+    - media: rc: Fix use-after-free bugs caused by ene_tx_irqsim()
+    - media: atomisp: fix videobuf2 Kconfig depenendency
+    - media: atomisp: Only set default_run_mode on first open of a stream/asd
+    - media: i2c: ov7670: 0 instead of -EINVAL was returned
+    - media: usb: siano: Fix use after free bugs caused by do_submit_urb
+    - media: saa7134: Use video_unregister_device for radio_dev
+    - rpmsg: glink: Avoid infinite loop on intent for missing channel
+    - rpmsg: glink: Release driver_override
+    - ARM: OMAP2+: omap4-common: Fix refcount leak bug
+    - arm64: dts: qcom: msm8996: Add additional A2NoC clocks
+    - udf: Define EFSCORRUPTED error code
+    - context_tracking: Fix noinstr vs KASAN
+    - exit: Detect and fix irq disabled state in oops
+    - ARM: dts: exynos: Use Exynos5420 compatible for the MIPI video phy
+    - fs: Use CHECK_DATA_CORRUPTION() when kernel bugs are detected
+    - blk-iocost: fix divide by 0 error in calc_lcoefs()
+    - blk-cgroup: dropping parent refcount after pd_free_fn() is done
+    - blk-cgroup: synchronize pd_free_fn() from blkg_free_workfn() and
+      blkcg_deactivate_policy()
+    - trace/blktrace: fix memory leak with using debugfs_lookup()
+    - btrfs: scrub: improve tree block error reporting
+    - arm64: zynqmp: Enable hs termination flag for USB dwc3 controller
+    - cpuidle, intel_idle: Fix CPUIDLE_FLAG_INIT_XSTATE
+    - x86/fpu: Don't set TIF_NEED_FPU_LOAD for PF_IO_WORKER threads
+    - cpuidle: drivers: firmware: psci: Dont instrument suspend code
+    - cpuidle: lib/bug: Disable rcu_is_watching() during WARN/BUG
+    - perf/x86/intel/uncore: Add Meteor Lake support
+    - wifi: ath9k: Fix use-after-free in ath9k_hif_usb_disconnect()
+    - wifi: ath11k: fix monitor mode bringup crash
+    - wifi: brcmfmac: Fix potential stack-out-of-bounds in brcmf_c_preinit_dcmds()
+    - rcu: Make RCU_LOCKDEP_WARN() avoid early lockdep checks
+    - rcu: Suppress smp_processor_id() complaint in
+      synchronize_rcu_expedited_wait()
+    - srcu: Delegate work to the boot cpu if using SRCU_SIZE_SMALL
+    - rcu-tasks: Make rude RCU-Tasks work well with CPU hotplug
+    - rcu-tasks: Handle queue-shrink/callback-enqueue race condition
+    - wifi: ath11k: debugfs: fix to work with multiple PCI devices
+    - thermal: intel: Fix unsigned comparison with less than zero
+    - timers: Prevent union confusion from unexpected restart_syscall()
+    - x86/bugs: Reset speculation control settings on init
+    - bpftool: Always disable stack protection for BPF objects
+    - wifi: brcmfmac: ensure CLM version is null-terminated to prevent stack-out-
+      of-bounds
+    - wifi: rtw89: fix assignation of TX BD RAM table
+    - wifi: mt7601u: fix an integer underflow
+    - inet: fix fast path in __inet_hash_connect()
+    - ice: restrict PTP HW clock freq adjustments to 100, 000, 000 PPB
+    - ice: add missing checks for PF vsi type
+    - Compiler attributes: GCC cold function alignment workarounds
+    - ACPI: Don't build ACPICA with '-Os'
+    - bpf, docs: Fix modulo zero, division by zero, overflow, and underflow
+    - thermal: intel: intel_pch: Add support for Wellsburg PCH
+    - clocksource: Suspend the watchdog temporarily when high read latency
+      detected
+    - crypto: hisilicon: Wipe entire pool on error
+    - net: bcmgenet: Add a check for oversized packets
+    - m68k: Check syscall_trace_enter() return code
+    - s390/mm,ptdump: avoid Kasan vs Memcpy Real markers swapping
+    - netfilter: nf_tables: NULL pointer dereference in nf_tables_updobj()
+    - can: isotp: check CAN address family in isotp_bind()
+    - gcc-plugins: drop -std=gnu++11 to fix GCC 13 build
+    - tools/power/x86/intel-speed-select: Add Emerald Rapid quirk
+    - platform/x86: dell-ddv: Add support for interface version 3
+    - wifi: mt76: dma: free rx_head in mt76_dma_rx_cleanup
+    - ACPI: video: Fix Lenovo Ideapad Z570 DMI match
+    - net/mlx5: fw_tracer: Fix debug print
+    - coda: Avoid partial allocation of sig_inputArgs
+    - uaccess: Add minimum bounds check on kernel buffer size
+    - s390/idle: mark arch_cpu_idle() noinstr
+    - time/debug: Fix memory leak with using debugfs_lookup()
+    - PM: domains: fix memory leak with using debugfs_lookup()
+    - PM: EM: fix memory leak with using debugfs_lookup()
+    - Bluetooth: Fix issue with Actions Semi ATS2851 based devices
+    - Bluetooth: btusb: Add new PID/VID 0489:e0f2 for MT7921
+    - Bluetooth: btusb: Add VID:PID 13d3:3529 for Realtek RTL8821CE
+    - wifi: rtw89: debug: avoid invalid access on RTW89_DBG_SEL_MAC_30
+    - hv_netvsc: Check status in SEND_RNDIS_PKT completion message
+    - s390/kfence: fix page fault reporting
+    - devlink: Fix TP_STRUCT_entry in trace of devlink health report
+    - scm: add user copy checks to put_cmsg()
+    - drm: panel-orientation-quirks: Add quirk for Lenovo Yoga Tab 3 X90F
+    - drm: panel-orientation-quirks: Add quirk for DynaBook K50
+    - drm/amd/display: Reduce expected sdp bandwidth for dcn321
+    - drm/amd/display: Revert Reduce delay when sink device not able to ACK 00340h
+      write
+    - drm/amd/display: Fix potential null-deref in dm_resume
+    - drm/omap: dsi: Fix excessive stack usage
+    - HID: Add Mapping for System Microphone Mute
+    - drm/tiny: ili9486: Do not assume 8-bit only SPI controllers
+    - drm/amd/display: Defer DIG FIFO disable after VID stream enable
+    - drm/radeon: free iio for atombios when driver shutdown
+    - drm/amd: Avoid BUG() for case of SRIOV missing IP version
+    - drm/amdkfd: Page aligned memory reserve size
+    - scsi: lpfc: Fix use-after-free KFENCE violation during sysfs firmware write
+    - Revert "fbcon: don't lose the console font across generic->chip driver
+      switch"
+    - drm/amd: Avoid ASSERT for some message failures
+    - drm: amd: display: Fix memory leakage
+    - drm/amd/display: fix mapping to non-allocated address
+    - HID: uclogic: Add frame type quirk
+    - HID: uclogic: Add battery quirk
+    - HID: uclogic: Add support for XP-PEN Deco Pro SW
+    - HID: uclogic: Add support for XP-PEN Deco Pro MW
+    - drm/msm/dsi: Add missing check for alloc_ordered_workqueue
+    - drm: rcar-du: Add quirk for H3 ES1.x pclk workaround
+    - drm: rcar-du: Fix setting a reserved bit in DPLLCR
+    - drm/drm_print: correct format problem
+    - drm/amd/display: Set hvm_enabled flag for S/G mode
+    - drm/client: Test for connectors before sending hotplug event
+    - habanalabs: extend fatal messages to contain PCI info
+    - habanalabs: fix bug in timestamps registration code
+    - docs/scripts/gdb: add necessary make scripts_gdb step
+    - drm/msm/dpu: Add DSC hardware blocks to register snapshot
+    - ASoC: soc-compress: Reposition and add pcm_mutex
+    - ASoC: kirkwood: Iterate over array indexes instead of using pointer math
+    - regulator: max77802: Bounds check regulator id against opmode
+    - regulator: s5m8767: Bounds check id indexing into arrays
+    - Revert "drm/amdgpu: TA unload messages are not actually sent to psp when
+      amdgpu is uninstalled"
+    - drm/amd/display: fix FCLK pstate change underflow
+    - gfs2: Improve gfs2_make_fs_rw error handling
+    - hwmon: (coretemp) Simplify platform device handling
+    - hwmon: (nct6775) Directly call ASUS ACPI WMI method
+    - hwmon: (nct6775) B650/B660/X670 ASUS boards support
+    - pinctrl: at91: use devm_kasprintf() to avoid potential leaks
+    - drm/amd/display: Do not commit pipe when updating DRR
+    - scsi: snic: Fix memory leak with using debugfs_lookup()
+    - scsi: ufs: core: Fix device management cmd timeout flow
+    - HID: logitech-hidpp: Don't restart communication if not necessary
+    - drm/amd/display: Enable P-state validation checks for DCN314
+    - drm: panel-orientation-quirks: Add quirk for Lenovo IdeaPad Duet 3 10IGL5
+    - drm/amd/display: Disable HUBP/DPP PG on DCN314 for now
+    - drm/amd/display: disable SubVP + DRR to prevent underflow
+    - dm thin: add cond_resched() to various workqueue loops
+    - dm cache: add cond_resched() to various workqueue loops
+    - nfsd: zero out pointers after putting nfsd_files on COPY setup error
+    - nfsd: don't hand out delegation on setuid files being opened for write
+    - cifs: prevent data race in smb2_reconnect()
+    - drm/i915/mtl: Correct implementation of Wa_18018781329
+    - drm/shmem-helper: Revert accidental non-GPL export
+    - driver core: fw_devlink: Avoid spurious error message
+    - wifi: rtl8xxxu: fixing transmisison failure for rtl8192eu
+    - firmware: coreboot: framebuffer: Ignore reserved pixel color bits
+    - block: don't allow multiple bios for IOCB_NOWAIT issue
+    - block: clear bio->bi_bdev when putting a bio back in the cache
+    - block: be a bit more careful in checking for NULL bdev while polling
+    - rtc: pm8xxx: fix set-alarm race
+    - ipmi: ipmb: Fix the MODULE_PARM_DESC associated to 'retry_time_ms'
+    - ipmi:ssif: resend_msg() cannot fail
+    - ipmi_ssif: Rename idle state and check
+    - ipmi:ssif: Add a timer between request retries
+    - io_uring: Replace 0-length array with flexible array
+    - io_uring: use user visible tail in io_uring_poll()
+    - io_uring: handle TIF_NOTIFY_RESUME when checking for task_work
+    - io_uring: add a conditional reschedule to the IOPOLL cancelation loop
+    - io_uring: add reschedule point to handle_tw_list()
+    - io_uring/rsrc: disallow multi-source reg buffers
+    - io_uring: remove MSG_NOSIGNAL from recvmsg
+    - io_uring/poll: allow some retries for poll triggering spuriously
+    - io_uring: fix fget leak when fs don't support nowait buffered read
+    - s390/extmem: return correct segment type in __segment_load()
+    - s390: discard .interp section
+    - s390/kprobes: fix irq mask clobbering on kprobe reenter from post_handler
+    - s390/kprobes: fix current_kprobe never cleared after kprobes reenter
+    - KVM: s390: disable migration mode when dirty tracking is disabled
+    - cifs: improve checking of DFS links over STATUS_OBJECT_NAME_INVALID
+    - cifs: Fix uninitialized memory read in smb3_qfs_tcon()
+    - cifs: Fix uninitialized memory reads for oparms.mode
+    - cifs: fix mount on old smb servers
+    - cifs: introduce cifs_io_parms in smb2_async_writev()
+    - cifs: split out smb3_use_rdma_offload() helper
+    - cifs: don't try to use rdma offload on encrypted connections
+    - cifs: Check the lease context if we actually got a lease
+    - cifs: return a single-use cfid if we did not get a lease
+    - scsi: mpi3mr: Fix missing mrioc->evtack_cmds initialization
+    - scsi: mpi3mr: Fix issues in mpi3mr_get_all_tgt_info()
+    - scsi: mpi3mr: Remove unnecessary memcpy() to alltgt_info->dmi
+    - btrfs: hold block group refcount during async discard
+    - btrfs: sysfs: update fs features directory asynchronously
+    - locking/rwsem: Prevent non-first waiter from spinning in down_write()
+      slowpath
+    - ksmbd: fix wrong data area length for smb2 lock request
+    - ksmbd: do not allow the actual frame length to be smaller than the rfc1002
+      length
+    - ksmbd: fix possible memory leak in smb2_lock()
+    - torture: Fix hang during kthread shutdown phase
+    - ARM: dts: exynos: correct HDMI phy compatible in Exynos4
+    - io_uring: mark task TASK_RUNNING before handling resume/task work
+    - hfs: fix missing hfs_bnode_get() in __hfs_bnode_create
+    - fs: hfsplus: fix UAF issue in hfsplus_put_super
+    - exfat: fix reporting fs error when reading dir beyond EOF
+    - exfat: fix unexpected EOF while reading dir
+    - exfat: redefine DIR_DELETED as the bad cluster number
+    - exfat: fix inode->i_blocks for non-512 byte sector size device
+    - fs: dlm: start midcomms before scand
+    - fs: dlm: fix use after free in midcomms commit
+    - fs: dlm: be sure to call dlm_send_queue_flush()
+    - fs: dlm: fix race setting stop tx flag
+    - fs: dlm: don't set stop rx flag after node reset
+    - fs: dlm: move sending fin message into state change handling
+    - fs: dlm: send FIN ack back in right cases
+    - f2fs: fix information leak in f2fs_move_inline_dirents()
+    - f2fs: retry to update the inode page given data corruption
+    - f2fs: fix cgroup writeback accounting with fs-layer encryption
+    - f2fs: fix kernel crash due to null io->bio
+    - f2fs: Revert "f2fs: truncate blocks in batch in __complete_revoke_list()"
+    - ocfs2: fix defrag path triggering jbd2 ASSERT
+    - ocfs2: fix non-auto defrag path not working issue
+    - fs/cramfs/inode.c: initialize file_ra_state
+    - selftests/landlock: Skip overlayfs tests when not supported
+    - selftests/landlock: Test ptrace as much as possible with Yama
+    - udf: Truncate added extents on failed expansion
+    - udf: Do not bother merging very long extents
+    - udf: Do not update file length for failed writes to inline files
+    - udf: Preserve link count of system files
+    - udf: Detect system inodes linked into directory hierarchy
+    - udf: Fix file corruption when appending just after end of preallocated
+      extent
+    - md: don't update recovery_cp when curr_resync is ACTIVE
+    - KVM: Destroy target device if coalesced MMIO unregistration fails
+    - KVM: VMX: Fix crash due to uninitialized current_vmcs
+    - KVM: Register /dev/kvm as the _very_ last thing during initialization
+    - KVM: x86: Purge "highest ISR" cache when updating APICv state
+    - KVM: x86: Blindly get current x2APIC reg value on "nodecode write" traps
+    - KVM: x86: Don't inhibit APICv/AVIC on xAPIC ID "change" if APIC is disabled
+    - KVM: x86: Don't inhibit APICv/AVIC if xAPIC ID mismatch is due to 32-bit ID
+    - KVM: SVM: Flush the "current" TLB when activating AVIC
+    - KVM: SVM: Process ICR on AVIC IPI delivery failure due to invalid target
+    - KVM: SVM: Don't put/load AVIC when setting virtual APIC mode
+    - KVM: x86: Inject #GP if WRMSR sets reserved bits in APIC Self-IPI
+    - KVM: x86: Inject #GP on x2APIC WRMSR that sets reserved bits 63:32
+    - KVM: SVM: Fix potential overflow in SEV's send|receive_update_data()
+    - KVM: SVM: hyper-v: placate modpost section mismatch error
+    - selftests: x86: Fix incorrect kernel headers search path
+    - x86/virt: Force GIF=1 prior to disabling SVM (for reboot flows)
+    - x86/crash: Disable virt in core NMI crash handler to avoid double shootdown
+    - x86/reboot: Disable virtualization in an emergency if SVM is supported
+    - x86/reboot: Disable SVM, not just VMX, when stopping CPUs
+    - x86/kprobes: Fix __recover_optprobed_insn check optimizing logic
+    - x86/kprobes: Fix arch_check_optimized_kprobe check within optimized_kprobe
+      range
+    - x86/microcode/amd: Remove load_microcode_amd()'s bsp parameter
+    - x86/microcode/AMD: Add a @cpu parameter to the reloading functions
+    - x86/microcode/AMD: Fix mixed steppings support
+    - x86/speculation: Allow enabling STIBP with legacy IBRS
+    - Documentation/hw-vuln: Document the interaction between IBRS and STIBP
+    - virt/sev-guest: Return -EIO if certificate buffer is not large enough
+    - brd: mark as nowait compatible
+    - brd: return 0/-error from brd_insert_page()
+    - brd: check for REQ_NOWAIT and set correct page allocation mask
+    - ima: fix error handling logic when file measurement failed
+    - ima: Align ima_file_mmap() parameters with mmap_file LSM hook
+    - selftests/powerpc: Fix incorrect kernel headers search path
+    - selftests/ftrace: Fix eprobe syntax test case to check filter support
+    - selftests: sched: Fix incorrect kernel headers search path
+    - selftests: core: Fix incorrect kernel headers search path
+    - selftests: pid_namespace: Fix incorrect kernel headers search path
+    - selftests: arm64: Fix incorrect kernel headers search path
+    - selftests: clone3: Fix incorrect kernel headers search path
+    - selftests: pidfd: Fix incorrect kernel headers search path
+    - selftests: membarrier: Fix incorrect kernel headers search path
+    - selftests: kcmp: Fix incorrect kernel headers search path
+    - selftests: media_tests: Fix incorrect kernel headers search path
+    - selftests: gpio: Fix incorrect kernel headers search path
+    - selftests: filesystems: Fix incorrect kernel headers search path
+    - selftests: user_events: Fix incorrect kernel headers search path
+    - selftests: ptp: Fix incorrect kernel headers search path
+    - selftests: sync: Fix incorrect kernel headers search path
+    - selftests: rseq: Fix incorrect kernel headers search path
+    - selftests: move_mount_set_group: Fix incorrect kernel headers search path
+    - selftests: mount_setattr: Fix incorrect kernel headers search path
+    - selftests: perf_events: Fix incorrect kernel headers search path
+    - selftests: ipc: Fix incorrect kernel headers search path
+    - selftests: futex: Fix incorrect kernel headers search path
+    - selftests: drivers: Fix incorrect kernel headers search path
+    - selftests: dmabuf-heaps: Fix incorrect kernel headers search path
+    - selftests: vm: Fix incorrect kernel headers search path
+    - selftests: seccomp: Fix incorrect kernel headers search path
+    - irqdomain: Fix association race
+    - irqdomain: Fix disassociation race
+    - irqdomain: Look for existing mapping only once
+    - irqdomain: Drop bogus fwspec-mapping error handling
+    - irqdomain: Refactor __irq_domain_alloc_irqs()
+    - irqdomain: Fix mapping-creation race
+    - irqdomain: Fix domain registration race
+    - crypto: qat - fix out-of-bounds read
+    - mm/damon/paddr: fix missing folio_put()
+    - ALSA: ice1712: Do not left ice->gpio_mutex locked in aureon_add_controls()
+    - ALSA: hda/realtek: Add quirk for HP EliteDesk 800 G6 Tower PC
+    - jbd2: fix data missing when reusing bh which is ready to be checkpointed
+    - ext4: optimize ea_inode block expansion
+    - ext4: refuse to create ea block when umounted
+    - cxl/pmem: Fix nvdimm registration races
+    - Input: exc3000 - properly stop timer on shutdown
+    - mtd: spi-nor: sfdp: Fix index value for SCCR dwords
+    - mtd: spi-nor: spansion: Consider reserved bits in CFR5 register
+    - dm: send just one event on resize, not two
+    - dm: add cond_resched() to dm_wq_work()
+    - dm: add cond_resched() to dm_wq_requeue_work()
+    - wifi: rtw88: use RTW_FLAG_POWERON flag to prevent to power on/off twice
+    - wifi: rtl8xxxu: Use a longer retry limit of 48
+    - wifi: ath11k: allow system suspend to survive ath11k
+    - wifi: cfg80211: Fix use after free for wext
+    - wifi: cfg80211: Set SSID if it is not already set
+    - cpuidle: add ARCH_SUSPEND_POSSIBLE dependencies
+    - qede: fix interrupt coalescing configuration
+    - thermal: intel: powerclamp: Fix cur_state for multi package system
+    - dm flakey: fix logic when corrupting a bio
+    - dm cache: free background tracker's queued work in btracker_destroy
+    - dm flakey: don't corrupt the zero page
+    - dm flakey: fix a bug with 32-bit highmem systems
+    - hwmon: (peci/cputemp) Fix off-by-one in coretemp_label allocation
+    - hwmon: (nct6775) Fix incorrect parenthesization in nct6775_write_fan_div()
+    - spi: intel: Check number of chip selects after reading the descriptor
+    - ARM: dts: qcom: sdx65: Add Qcom SMMU-500 as the fallback for IOMMU node
+    - ARM: dts: qcom: sdx55: Add Qcom SMMU-500 as the fallback for IOMMU node
+    - ARM: dts: exynos: correct TMU phandle in Exynos4210
+    - ARM: dts: exynos: correct TMU phandle in Exynos4
+    - ARM: dts: exynos: correct TMU phandle in Odroid XU3 family
+    - ARM: dts: exynos: correct TMU phandle in Exynos5250
+    - ARM: dts: exynos: correct TMU phandle in Odroid XU
+    - ARM: dts: exynos: correct TMU phandle in Odroid HC1
+    - arm64: acpi: Fix possible memory leak of ffh_ctxt
+    - arm64: mm: hugetlb: Disable HUGETLB_PAGE_OPTIMIZE_VMEMMAP
+    - arm64: Reset KASAN tag in copy_highpage with HW tags only
+    - fuse: add inode/permission checks to fileattr_get/fileattr_set
+    - rbd: avoid use-after-free in do_rbd_add() when rbd_dev_create() fails
+    - ceph: update the time stamps and try to drop the suid/sgid
+    - regulator: core: Use ktime_get_boottime() to determine how long a regulator
+      was off
+    - panic: fix the panic_print NMI backtrace setting
+    - mm/hwpoison: convert TTU_IGNORE_HWPOISON to TTU_HWPOISON
+    - genirq/msi, platform-msi: Ensure that MSI descriptors are unreferenced
+    - genirq/msi: Take the per-device MSI lock before validating the control
+      structure
+    - spi: spi-sn-f-ospi: fix duplicate flag while assigning to mode_bits
+    - alpha: fix FEN fault handling
+    - dax/kmem: Fix leak of memory-hotplug resources
+    - mips: fix syscall_get_nr
+    - media: ipu3-cio2: Fix PM runtime usage_count in driver unbind
+    - remoteproc/mtk_scp: Move clk ops outside send_lock
+    - vfio: Fix NULL pointer dereference caused by uninitialized group->iommufd
+    - docs: gdbmacros: print newest record
+    - mm: memcontrol: deprecate charge moving
+    - mm/thp: check and bail out if page in deferred queue already
+    - ktest.pl: Give back console on Ctrt^C on monitor
+    - kprobes: Fix to handle forcibly unoptimized kprobes on freeing_list
+    - ktest.pl: Fix missing "end_monitor" when machine check fails
+    - ktest.pl: Add RUN_TIMEOUT option with default unlimited
+    - memory tier: release the new_memtier in find_create_memory_tier()
+    - ring-buffer: Handle race between rb_move_tail and rb_check_pages
+    - tools/bootconfig: fix single & used for logical condition
+    - tracing/eprobe: Fix to add filter on eprobe description in README file
+    - iommu/amd: Add a length limitation for the ivrs_acpihid command-line
+      parameter
+    - scsi: aacraid: Allocate cmd_priv with scsicmd
+    - scsi: qla2xxx: Fix link failure in NPIV environment
+    - scsi: qla2xxx: Check if port is online before sending ELS
+    - scsi: qla2xxx: Fix DMA-API call trace on NVMe LS requests
+    - scsi: qla2xxx: Remove unintended flag clearing
+    - scsi: qla2xxx: Fix erroneous link down
+    - scsi: qla2xxx: Remove increment of interface err cnt
+    - scsi: ses: Don't attach if enclosure has no components
+    - scsi: ses: Fix slab-out-of-bounds in ses_enclosure_data_process()
+    - scsi: ses: Fix possible addl_desc_ptr out-of-bounds accesses
+    - scsi: ses: Fix possible desc_ptr out-of-bounds accesses
+    - scsi: ses: Fix slab-out-of-bounds in ses_intf_remove()
+    - RISC-V: add a spin_shadow_stack declaration
+    - riscv: Avoid enabling interrupts in die()
+    - riscv: mm: fix regression due to update_mmu_cache change
+    - riscv: jump_label: Fixup unaligned arch_static_branch function
+    - riscv: ftrace: Fixup panic by disabling preemption
+    - riscv, mm: Perform BPF exhandler fixup on page fault
+    - riscv: ftrace: Remove wasted nops for !RISCV_ISA_C
+    - riscv: ftrace: Reduce the detour code size to half
+    - MIPS: DTS: CI20: fix otg power gpio
+    - PCI/PM: Observe reset delay irrespective of bridge_d3
+    - PCI: Unify delay handling for reset and resume
+    - PCI: hotplug: Allow marking devices as disconnected during bind/unbind
+    - PCI: Avoid FLR for AMD FCH AHCI adapters
+    - PCI/DPC: Await readiness of secondary bus after reset
+    - bus: mhi: ep: Only send -ENOTCONN status if client driver is available
+    - bus: mhi: ep: Move chan->lock to the start of processing queued ch ring
+    - bus: mhi: ep: Save channel state locally during suspend and resume
+    - iommufd: Make sure to zero vfio_iommu_type1_info before copying to user
+    - iommufd: Do not add the same hwpt to the ioas->hwpt_list twice
+    - iommu/vt-d: Avoid superfluous IOTLB tracking in lazy mode
+    - iommu/vt-d: Fix PASID directory pointer coherency
+    - vfio/type1: exclude mdevs from VFIO_UPDATE_VADDR
+    - vfio/type1: prevent underflow of locked_vm via exec()
+    - vfio/type1: track locked_vm per dma
+    - vfio/type1: restore locked_vm
+    - drm/amd: Fix initialization for nbio 7.5.1
+    - drm/i915/quirks: Add inverted backlight quirk for HP 14-r206nv
+    - drm/radeon: Fix eDP for single-display iMac11,2
+    - drm/i915: Don't use stolen memory for ring buffers with LLC
+    - drm/i915: Don't use BAR mappings for ring buffers with LLC
+    - drm/gud: Fix UBSAN warning
+    - drm/edid: fix AVI infoframe aspect ratio handling
+    - drm/edid: fix parsing of 3D modes from HDMI VSDB
+    - qede: avoid uninitialized entries in coal_entry array
+    - brd: use radix_tree_maybe_preload instead of radix_tree_preload
+    - net: avoid double iput when sock_alloc_file fails
+    - Linux 6.2.3
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations after applying 6.2.3 stable patches
+    - [Config] update annotations after applying 6.2.6 stable patches
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 14 Mar 2023 16:43:44 +0100
+
+linux (6.2.0-16.16) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-16.16 -proposed tracker (LP: #2009914)
+
+  * linux-libc-dev is no longer multi-arch safe (LP: #2009355)
+    - Revert "UBUNTU: [Packaging] install headers to debian/linux-libc-dev
+      directly"
+
+  * linux: CONFIG_SERIAL_8250_MID=y (LP: #2009283)
+    - [Config] enable CONFIG_SERIAL_8250_MID=y
+
+  * cpufreq: intel_pstate: Update Balance performance EPP for Sapphire Rapids
+    (LP: #2008519)
+    - cpufreq: intel_pstate: Adjust balance_performance EPP for Sapphire Rapids
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 10 Mar 2023 18:34:28 +0100
+
+linux (6.2.0-15.15) lunar; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: document annotations headers
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 10 Mar 2023 07:36:59 +0100
+
+linux (6.2.0-14.14) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-14.14 -proposed tracker (LP: #2009856)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] rust: add rust build dependencies to all arches
+    - [Packaging] Support skipped dkms modules
+    - [Packaging] actually enforce set -e in dkms-build--nvidia-N
+    - [Packaging] Preserve the correct log file variable value
+    - [Packaging] update getabis
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 09 Mar 2023 16:40:36 +0100
+
+linux (6.2.0-13.13) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-13.13 -proposed tracker (LP: #2009704)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * mt7921: add support of MTFG table (LP: #2009642)
+    - wifi: mt76: mt7921: add support to update fw capability with MTFG table
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Mar 2023 14:40:25 +0100
+
+linux (6.2.0-12.12) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-12.12 -proposed tracker (LP: #2009698)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: enforce rust availability only on x86_64
+    - [Config] update CONFIG_RUST_IS_AVAILABLE
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Mar 2023 12:50:15 +0100
+
+linux (6.2.0-11.11) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-11.11 -proposed tracker (LP: #2009697)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] do not stop the build if rust is not available
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Mar 2023 12:24:55 +0100
+
+linux (6.2.0-10.10) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-10.10 -proposed tracker (LP: #2009673)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * enable Rust support in the kernel (LP: #2007654)
+    - [Packaging] propagate makefile variables to kernelconfig
+    - SAUCE: rust: fix regexp in scripts/is_rust_module.sh
+    - SAUCE: scripts: rust: drop is_rust_module.sh
+    - SAUCE: rust: allow to use INIT_STACK_ALL_ZERO
+    - SAUCE: scripts: Exclude Rust CUs with pahole
+    - SAUCE: modpost: support arbitrary symbol length in modversion
+    - SAUCE: allows to enable Rust with modversions
+    - SAUCE: rust: properly detect the version of libclang used by bindgen
+    - [Packaging] rust: add the proper make flags to enable rust support
+    - [Packaging] add rust dependencies
+    - [Packaging] bpftool: always use vmlinux to generate headers
+    - [Packaging] run rustavailable target as debugging before build
+    - [Config] enable Rust support
+
+  * Fail to output sound to external monitor which connects via docking station
+    (LP: #2009024)
+    - [Config] Enable CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Makefile: replace rsync with tar
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Mar 2023 12:01:56 +0100
+
+linux (6.2.0-1.1) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-1.1 -proposed tracker (LP: #2009621)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * kinetic: apply new apparmor and LSM stacking patch set (LP: #1989983)
+    - SAUCE: apparmor: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor: add user namespace creation mediation
+
+  * Lunar update: v6.2.2 upstream stable release (LP: #2009358)
+    - ALSA: hda: cs35l41: Correct error condition handling
+    - crypto: arm64/sm4-gcm - Fix possible crash in GCM cryption
+    - bpf: bpf_fib_lookup should not return neigh in NUD_FAILED state
+    - vc_screen: don't clobber return value in vcs_read
+    - drm/amd/display: Move DCN314 DOMAIN power control to DMCUB
+    - drm/amd/display: Properly reuse completion structure
+    - scripts/tags.sh: fix incompatibility with PCRE2
+    - wifi: rtw88: usb: Set qsel correctly
+    - wifi: rtw88: usb: send Zero length packets if necessary
+    - wifi: rtw88: usb: drop now unnecessary URB size check
+    - usb: dwc3: pci: add support for the Intel Meteor Lake-M
+    - USB: serial: option: add support for VW/Skoda "Carstick LTE"
+    - usb: gadget: u_serial: Add null pointer check in gserial_resume
+    - arm64: dts: uniphier: Fix property name in PXs3 USB node
+    - usb: typec: pd: Remove usb_suspend_supported sysfs from sink PDO
+    - USB: core: Don't hold device lock while reading the "descriptors" sysfs file
+    - Linux 6.2.2
+
+  * Lunar update: v6.2.1 upstream stable release (LP: #2009127)
+    - uaccess: Add speculation barrier to copy_from_user()
+    - x86/alternatives: Introduce int3_emulate_jcc()
+    - x86/alternatives: Teach text_poke_bp() to patch Jcc.d32 instructions
+    - x86/static_call: Add support for Jcc tail-calls
+    - HID: mcp-2221: prevent UAF in delayed work
+    - wifi: mwifiex: Add missing compatible string for SD8787
+    - audit: update the mailing list in MAINTAINERS
+    - platform/x86/amd/pmf: Add depends on CONFIG_POWER_SUPPLY
+    - platform/x86: nvidia-wmi-ec-backlight: Add force module parameter
+    - ext4: Fix function prototype mismatch for ext4_feat_ktype
+    - randstruct: disable Clang 15 support
+    - bpf: add missing header file include
+    - Linux 6.2.1
+
+  * Fix mediatek wifi driver crash when loading wrong SAR table (LP: #2009118)
+    - wifi: mt76: mt7921: fix error code of return in mt7921_acpi_read
+
+  * overlayfs mounts as R/O over idmapped mount (LP: #2009065)
+    - SAUCE: overlayfs: handle idmapped mounts in ovl_do_(set|remove)xattr
+
+  * RaptorLake: Fix the Screen is shaking by onboard HDMI port in mirror mode
+    (LP: #1993561)
+    - drm/i915/display: Drop check for doublescan mode in modevalid
+    - drm/i915/display: Prune Interlace modes for Display >=12
+
+  * screen flicker after PSR2 enabled (LP: #2007516)
+    - SAUCE: drm/i915/display/psr: Disable PSR2 sel fetch on panel SHP 5457
+
+  * [23.04 FEAT] Support for new IBM Z Hardware (IBM z16) - Reset DAT-Protection
+    facility support (LP: #1982378)
+    - s390/mm: add support for RDP (Reset DAT-Protection)
+
+  * [23.04 FEAT] zcrypt DD: AP command filtering (LP: #2003637)
+    - s390/zcrypt: introduce ctfm field in struct CPRBX
+
+  * rtcpie in timers from ubuntu_kernel_selftests randomly failing
+    (LP: #1814234)
+    - SAUCE: selftest: rtcpie: Force passing unreliable subtest
+
+  * [23.04 FEAT] Support for List-Directed IPL and re-IPL from ECKD DASD
+    (LP: #2003394)
+    - s390/ipl: add DEFINE_GENERIC_LOADPARM()
+    - s390/ipl: add loadparm parameter to eckd ipl/reipl data
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: drm/i915/sseu: fix max_subslices array-index-out-of-bounds access
+    - SAUCE: mtd: spi-nor: Fix shift-out-of-bounds in spi_nor_set_erase_type
+    - SAUCE: Revert "fbdev: Make registered_fb[] private to fbmem.c"
+    - [Packaging] disable signing for ppc64el
+    - [Config] define CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+    - SAUCE: Revert "arm64/fpsimd: Make kernel_neon_ API _GPL"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 07 Mar 2023 18:45:31 +0100
+
+linux (6.2.0-0.0) lunar; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 03 Mar 2023 08:42:43 +0100
+
+linux-unstable (6.2.0-10.10) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-10.10 -proposed tracker (LP: #2007818)
+
+  * Built-in camera device dies after runtime suspended (LP: #2007530)
+    - SAUCE: usb: xhci: Workaround for runpm issue on AMD xHC
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations after rebase to v6.2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 20 Feb 2023 10:36:20 +0100
+
+linux-unstable (6.2.0-9.9) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-9.9 -proposed tracker (LP: #2007069)
+
+  * Move kernel ADT tests to python3 (LP: #2004429)
+    - [Debian] Use a python3 compatable kernel-testing repo
+
+  * Mediatek FM350-GL wwan module failed to init: Invalid device status 0x1
+    (LP: #2002089)
+    - SAUCE: Revert "net: wwan: t7xx: Add AP CLDMA"
+    - SAUCE: net: wwan: t7xx: Add AP CLDMA
+    - SAUCE: net: wwan: t7xx: Infrastructure for early port configuration
+    - SAUCE: net: wwan: t7xx: PCIe reset rescan
+    - SAUCE: net: wwan: t7xx: Enable devlink based fw flashing and coredump
+      collection
+    - SAUCE: net: wwan: t7xx: Devlink documentation
+
+  * LXD containers using shiftfs on ZFS or TMPFS broken on 5.15.0-48.54
+    (LP: #1990849)
+    - SAUCE: shiftfs: fix -EOVERFLOW inside the container
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: do not drop undefined configs in derivatives
+    - [Packaging]: annotations: fix _remove_entry() logic
+    - [Packaging] rsync no longer available on lunar
+    - [Packaging] annotations: Handle single-line annoation rules
+    - [Packaging] annotations: Preserve single-line annotation rules
+    - [Packaging] annotations: Fix linter errors
+    - [Packaging] annotations: Clean up policy writes
+    - [Packaging] annotations: Handle tabs in annotations file
+    - [Packaging] annotations: Fail on invalid lines
+    - [Packaging] annotations: Write out annotations with notes first
+    - [Packaging] annotations: Check validity of FLAVOUR_DEP
+    - [Config] update annotations to split configs with/without notes
+    - [Packaging] annotations: various code cleanups
+    - [Config] update annotations after rebase to v6.2-rc8
+
+  * Miscellaneous upstream changes
+    - selftests/net: mv bpf/nat6to4.c to net folder
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc8
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 13 Feb 2023 09:32:18 +0100
+
+linux-unstable (6.2.0-8.8) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-8.8 -proposed tracker (LP: #2004229)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] re-enable signing for ppc64el and s390x
+    - SAUCE: s390/decompressor: specify __decompress() buf len to avoid overflow
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 31 Jan 2023 08:21:21 +0100
+
+linux-unstable (6.2.0-7.7) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-7.7 -proposed tracker (LP: #2004142)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 30 Jan 2023 10:23:15 +0100
+
+linux-unstable (6.2.0-6.6) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-6.6 -proposed tracker (LP: #2004138)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] debian/rules: Bring back 'editconfigs'
+    - [Packaging] debian/rules: 1-maintainer.mk -- Use make's if-else
+    - [Packaging] annotations: make sure to always drop undefined configs
+    - [Config] update annotations after rebase to v6.2-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 30 Jan 2023 09:20:26 +0100
+
+linux-unstable (6.2.0-5.5) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-5.5 -proposed tracker (LP: #2003682)
+
+  * [23.04] Kernel 6.2 does not boot on s390x (LP: #2003348)
+    - SAUCE Revert "zstd: import usptream v1.5.2"
+    - SAUCE: Revert "zstd: Move zstd-common module exports to
+      zstd_common_module.c"
+
+  * Revoke & rotate to new signing key (LP: #2002812)
+    - [Packaging] Revoke and rotate to new signing key
+
+  * CVE-2023-0179
+    - netfilter: nft_payload: incorrect arithmetics when fetching VLAN header bits
+
+  * [23.04] net/smc: Alibaba patches about tunable buffer sizes may cause errors
+    and need to be removed (kernel 6.2) (LP: #2003547)
+    - SAUCE: Revert "net/smc: Unbind r/w buffer size from clcsock and make them
+      tunable"
+    - SAUCE: Revert "net/smc: Introduce a specific sysctl for TEST_LINK time"
+
+  * 5.15 stuck at boot on c4.large (LP: #1956780)
+    - SAUCE: Revert "PCI/MSI: Mask MSI-X vectors only on success"
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] scripts/misc/kernelconfig: Disable config checks for mainline
+      builds
+    - [Packaging] annotations: add CONFIG_GCC_VERSION to the list of ignored
+      configs
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 23 Jan 2023 08:20:26 +0100
+
+linux-unstable (6.2.0-4.4) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-4.4 -proposed tracker (LP: #2003051)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] add python3 as a build dependency
+    - [Packaging] scripts/misc/kernelconfig: Rewrite
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 17 Jan 2023 09:18:54 +0100
+
+linux-unstable (6.2.0-3.3) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-3.3 -proposed tracker (LP: #2002939)
+
+  * Enable kernel config for P2PDMA (LP: #1987394)
+    - [Config] Enable CONFIG_HSA_AMD_P2P
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (no-up) Remove obj- += foo.o hack
+    - SAUCE: (no-up) re-add ubuntu/ directory
+    - [Config] enable EFI handover protocol
+    - [Packaging] Fix module-check error when modules are compressed
+    - SAUCE: (no-up) do not remove debian directory by 'make mrproper'
+    - [Packaging] debian/rules: Drop AUTOBUILD
+    - [Packaging] debian/rules: Drop NOKERNLOG and PRINTSHAS env variables
+    - [Packaging] debian/rules: Replace skip<foo> variables with skip_checks
+    - [Packaging] checks/retpoline-check: Make 'skipretpoline' argument optional
+    - [Packaging] checks/module-signature-check: Add 'skip_checks' argument
+    - [Packaging] debian/rules: Rename 'skip_dbg' to 'do_dbgsym_package'
+    - [Packaging] debian/rules: Rename 'skip_checks' to 'do_skip_checks'
+    - [Packaging] debian/rules: Rename 'full_build' to 'do_full_build'
+    - [Packaging] debian/rules: Fix PPA debug package builds
+    - [Packaging] debian/rules: Remove debug package install directory earlier
+    - [Packaging] debian/rules: Remove unnecessary 'lockme_<foo>' variables
+    - [Packaging] debian/rules: Remove unused target 'diffupstream'
+    - [Packaging] debian/rules: Mark PHONY targets individually
+    - [Packaging] debian/rules: Clean up 'help' target output
+    - [Packaging] debian/rules: Clean up 'printenv' target output
+    - [Packaging] debian/rules: Add missing 'do_<foo>' variables to 'printenv'
+    - [Config] update annotations after rebase to v6.2-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 16 Jan 2023 16:01:40 +0100
+
+linux-unstable (6.2.0-2.2) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-2.2 -proposed tracker (LP: #2001892)
+
+  * Soundwire support for the Intel RPL Gen 0C40/0C11 platforms (LP: #2000030)
+    - SAUCE: ASoC: Intel: soc-acpi: add configuration for variant of 0C40 product
+    - SAUCE: ASoC: Intel: soc-acpi: add configuration for variant of 0C11 product
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update toolchain version in annotations
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] Support skipped dkms modules"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 05 Jan 2023 09:19:55 +0100
+
+linux-unstable (6.2.0-1.1) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-1.1 -proposed tracker (LP: #2000904)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: remove configs that are undefined across all
+      arches/flavours
+    - SAUCE: Revert "apparmor: make __aa_path_perm() static"
+    - [Packaging] abi-check: ignore failures when abi check is skipped
+    - [Packaging] temporarily disable zfs dkms
+    - [Config] update annotations after rebase to 6.2-rc1
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 04 Jan 2023 12:08:32 +0100
+
+linux-unstable (6.2.0-0.0) lunar; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Sun, 01 Jan 2023 10:16:00 +0100
+
+linux (6.1.0-11.11) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-11.11 -proposed tracker (LP: #2000704)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Lunar update: v6.1.1 upstream stable release (LP: #2000706)
+    - x86/vdso: Conditionally export __vdso_sgx_enter_enclave()
+    - libbpf: Fix uninitialized warning in btf_dump_dump_type_data
+    - PCI: mt7621: Add sentinel to quirks table
+    - mips: ralink: mt7621: define MT7621_SYSC_BASE with __iomem
+    - mips: ralink: mt7621: soc queries and tests as functions
+    - mips: ralink: mt7621: do not use kzalloc too early
+    - irqchip/ls-extirq: Fix endianness detection
+    - udf: Discard preallocation before extending file with a hole
+    - udf: Fix preallocation discarding at indirect extent boundary
+    - udf: Do not bother looking for prealloc extents if i_lenExtents matches
+      i_size
+    - udf: Fix extending file within last block
+    - usb: gadget: uvc: Prevent buffer overflow in setup handler
+    - USB: serial: option: add Quectel EM05-G modem
+    - USB: serial: cp210x: add Kamstrup RF sniffer PIDs
+    - USB: serial: f81232: fix division by zero on line-speed change
+    - USB: serial: f81534: fix division by zero on line-speed change
+    - xhci: Apply XHCI_RESET_TO_DEFAULT quirk to ADL-N
+    - staging: r8188eu: fix led register settings
+    - igb: Initialize mailbox message for VF reset
+    - usb: typec: ucsi: Resume in separate work
+    - usb: dwc3: pci: Update PCIe device ID for USB3 controller on CPU sub-system
+      for Raptor Lake
+    - cifs: fix oops during encryption
+    - KEYS: encrypted: fix key instantiation with user-provided data
+    - Linux 6.1.1
+
+  * Expose built-in trusted and revoked certificates (LP: #1996892)
+    - [Packaging] Expose built-in trusted and revoked certificates
+
+  * Fix System cannot detect bluetooth after running suspend stress test
+    (LP: #1998727)
+    - wifi: rtw88: 8821c: enable BT device recovery mechanism
+
+  * Gnome doesn't run smooth when performing normal usage with RPL-P CPU
+    (LP: #1998419)
+    - drm/i915/rpl-p: Add stepping info
+
+  * Mute/mic LEDs no function on a HP platfrom (LP: #1998882)
+    - ALSA: hda/realtek: fix mute/micmute LEDs for a HP ProBook
+
+  * Add additional Mediatek MT7922 BT device ID (LP: #1998885)
+    - Bluetooth: btusb: Add a new VID/PID 0489/e0f2 for MT7922
+
+  * Support Icicle Kit reference design v2022.10 (LP: #1993148)
+    - SAUCE: riscv: dts: microchip: Disable PCIe on the Icicle Kit
+
+  * Add iommu passthrough quirk for Intel IPU6 on RaptorLake (LP: #1989041)
+    - SAUCE: iommu: intel-ipu: use IOMMU passthrough mode for Intel IPUs on Raptor
+      Lake
+
+  * Enable Intel FM350 wwan CCCI driver port logging (LP: #1997686)
+    - net: wwan: t7xx: use union to group port type specific data
+    - net: wwan: t7xx: Add port for modem logging
+
+  * TEE Support for CCP driver (LP: #1991608)
+    - crypto: ccp - Add support for TEE for PCI ID 0x14CA
+
+  * Kinetic update: v5.19.17 upstream stable release (LP: #1994179)
+    - Revert "fs: check FMODE_LSEEK to control internal pipe splicing"
+    - kbuild: Add skip_encoding_btf_enum64 option to pahole
+
+  * Kinetic update: v5.19.15 upstream stable release (LP: #1994078)
+    - Revert "clk: ti: Stop using legacy clkctrl names for omap4 and 5"
+
+  * support independent clock and LED GPIOs for Intel IPU6 platforms
+    (LP: #1989046)
+    - SAUCE: platform/x86: int3472: support independent clock and LED GPIOs
+
+  * Kernel livepatch support for for s390x (LP: #1639924)
+    - [Config] Enable EXPOLINE_EXTERN on s390x
+
+  * Kinetic update: v5.19.7 upstream stable release (LP: #1988733)
+    - Revert "PCI/portdrv: Don't disable AER reporting in
+      get_port_device_capability()"
+
+  * Kinetic update: v5.19.3 upstream stable release (LP: #1987345)
+    - Revert "mm: kfence: apply kmemleak_ignore_phys on early allocated pool"
+
+  * Fix non-working e1000e device after resume (LP: #1951861)
+    - SAUCE: Revert "e1000e: Add polling mechanism to indicate CSME DPG exit"
+
+  * Add additional Mediatek MT7921 WiFi/BT device IDs (LP: #1937004)
+    - SAUCE: Bluetooth: btusb: Add support for Foxconn Mediatek Chip
+
+  * Fix system sleep on TGL systems with Intel ME (LP: #1919321)
+    - SAUCE: PCI: Serialize TGL e1000e PM ops
+
+  * Fix broken e1000e device after S3 (LP: #1897755)
+    - SAUCE: e1000e: Increase polling timeout on MDIC ready bit
+
+  * Fix unusable USB hub on Dell TB16 after S3 (LP: #1855312)
+    - SAUCE: USB: core: Make port power cycle a seperate helper function
+    - SAUCE: USB: core: Attempt power cycle port when it's in eSS.Disabled state
+
+  * Set explicit CC in the headers package (LP: #1999750)
+    - [Packaging] Set explicit CC in the headers package
+
+  * commit cf58599cded35cf4affed1e659c0e2c742d3fda7 seems to be missing in
+    kinetic master to remove "hio" reference from Makefile (LP: #1999556)
+    - SAUCE: remove leftover reference to ubuntu/hio driver
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] kernelconfig: always complete all config checks
+    - [Packaging] annotations: unify same rule across all flavour within the same
+      arch
+    - [Config] annotations: compact annotations file
+    - [Config] disable EFI_ZBOOT
+    - SAUCE: input: i8042: fix section mismatch warning
+    - debian/dkms-versions -- re-enable zfs
+    - [Packaging] old-kernelconfig: update config-check path
+    - [Packaging] update getabis
+    - [Packaging] update Ubuntu.md
+
+  * Miscellaneous upstream changes
+    - Revert "drm/i915/opregion: check port number bounds for SWSCI display power
+      state"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 30 Dec 2022 11:23:16 +0100
+
+linux (6.1.0-10.10) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-10.10 -proposed tracker (LP: #1999569)
+
+  * Soundwire support for the Intel RPL Gen platforms (LP: #1997944)
+    - ASoC: Intel: sof_sdw: Add support for SKU 0C10 product
+    - ASoC: Intel: soc-acpi: add SKU 0C10 SoundWire configuration
+    - ASoC: Intel: sof_sdw: Add support for SKU 0C40 product
+    - ASoC: Intel: soc-acpi: add SKU 0C40 SoundWire configuration
+    - ASoC: Intel: sof_sdw: Add support for SKU 0C4F product
+    - ASoC: rt1318: Add RT1318 SDCA vendor-specific driver
+    - ASoC: intel: sof_sdw: add rt1318 codec support.
+    - ASoC: Intel: sof_sdw: Add support for SKU 0C11 product
+    - ASoC: Intel: soc-acpi: add SKU 0C11 SoundWire configuration
+    - SAUCE: ASoC: Intel: soc-acpi: update codec addr on 0C11/0C4F product
+    - [Config] enable CONFIG_SND_SOC_RT1318_SDW
+
+  * Virtual GPU driver packaging regression (LP: #1996112)
+    - [Packaging] Reintroduce VM DRM drivers into modules
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 13 Dec 2022 22:14:08 +0100
+
+linux (6.1.0-9.9) lunar; urgency=medium
+
+  * Empty entry (ABI bump)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 13 Dec 2022 21:31:08 +0100
+
+linux (6.1.0-3.3) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-3.3 -proposed tracker (LP: #1999534)
+
+  * [DEP-8] Run ADT regression suite for lowlatency kernels Jammy and later
+    (LP: #1999528)
+    - [DEP-8] Fix regression suite to run on lowlatency
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: do not add constraints on toolchain versions
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 13 Dec 2022 16:45:59 +0100
+
+linux (6.1.0-2.2) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-2.2 -proposed tracker (LP: #1999411)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: do not enforce toolchain versions
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 12 Dec 2022 17:05:59 +0100
+
+linux (6.1.0-1.1) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-1.1 -proposed tracker (LP: #1999373)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: set and delete configs from command line
+    - [Packaging] migrateconfigs: ignore README.rst if it doesn't exist
+    - [Packaging] migrate-annotations: properly determine arches in derivatives
+    - [Packaging] annotations: allow to set note to config options directly
+    - [Packaging] annotations: assume --query as default command
+    - [Packaging] annotations: allow to query using CONFIG_<option> or <option>
+    - [Packaging] annotations: support flavour inheritance
+    - [Packaging] annotations: properly merge configs with includes
+    - [Packaging] annotations: accept config options with or without CONFIG_
+      prefix
+    - [Packaging] annotations: clarify error message with --import
+    - [Packaging] annotations: properly support multiple levels of inclusion
+    - [Packaging] annotations: catch syntax errors in annotations
+    - [Packaging] kernelconfig: report arch and flavour in config-check log
+    - [Packaging] annotations: prevent generating .pyc files on import
+    - [Packaging] annotations: prevent python broken pipe errors
+    - [Packaging] annotations: allow to specify --write and --note at the same
+      time
+    - [Packaging] annotations: add an option to enable config autocompletion in
+      bash
+    - [Packaging] annotations: introduce --source
+    - [Packaging] annotations: add missing CONFIG_ prefix in main()
+    - [Packaging] Remove obsolete etc/kernelconfig
+    - [Packaging] Rewrite debian/scripts/abi-check in Python
+    - [Packaging] Simplify debian/scripts/module-check
+    - [Packaging] Clean up debian/scripts/module-check
+    - [Packaging] Move checker scripts to debian/scripts/checks
+    - [Packaging] mark phony targets
+    - [Packaging] Make the compiler for fix-filenames explicit
+    - [Packaging] add -rR MAKEFLAGS to clear implicit rules
+    - [Packaging] use dpkg-parsechangelog to get package name and series
+    - [Packaging] simplify revision/release
+    - [Packaging] simplify custom_override
+    - [Packaging] Remove meaningless code in install-arch-headers
+    - [Packaging] use olddefconfig in stamp-prepare-tree
+    - [Packaging] use parralel builds in more places
+    - [Packaging] install headers to debian/linux-libc-dev directly
+    - [Packaging] simplify abinum and uploadnum definitions
+    - [Packaging] Remove unused INSTALL_FW_PATH
+    - [Packaging] Merge install commands
+    - [Config] clean up deprecated notes in annotations
+    - [Packaging] automatically apply changes to annotations and drop
+      importconfigs
+    - [Packaging] kernelconfig: drop listnewconfigs
+    - [Packaging] annotations: do not hijack CONFIGS/* to update annotations
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 12 Dec 2022 10:05:03 +0100
+
+linux (6.1.0-0.0) lunar; urgency=medium
+
+  * Empty entry
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 12 Dec 2022 09:42:01 +0100
+
+linux-unstable (6.1.0-9.9) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-9.9 -proposed tracker (LP: #1998078)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Set ARM64_ERRATUM_2077057=y
+    - SAUCE: add python cached bytecode to .gitignore
+    - [Packaging] config-check: ignore values that are not defined in annotations
+    - [Packaging] config-check: do not strictly enforce CONFIG_CC_VERSION_TEXT
+    - [Packaging] config-check: support annotations format 4
+    - [Packaging] introduce annotations script
+    - [Packaging] add a README.rst to document the new annotations schema
+    - [Packaging] kernelconfig: automatically generate configs from annotations
+    - [Packaging] drop deprecated script tristate.sh
+    - [Packaging] use annotations to generate initial configs check them
+    - [Packaging] simplify kernelconfig
+    - [Packaging] kernelconfig: always keep configs
+    - [Packaging] kernelconfig: provide listnewconfigs
+    - [Packaging] kernelconfig: introduce importconfigs
+    - [Packaging] snap: support new annotations with snapcraft
+    - [Packaging] final-checks: support new annotations
+    - [Packaging] introduce migrate-annotations
+    - [Packaging] re-introduce previous kernelconfig as old-kernelconfig
+    - [Packaging] provide migrateconfigs debian/rules target
+    - [Packaging] correctly propagate errors during updateconfigs
+    - [Packaging] annotations: report failed config checks in alphabetic order
+    - [Config] merge configs into annotations
+    - [Config] udpate annotations after rebase to v6.1-rc7
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Nov 2022 11:25:44 +0100
+
+linux-unstable (6.1.0-8.8) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-8.8 -proposed tracker (LP: #1997357)
+
+  *  Fibocom WWAN FM350-GL suspend error (notebook not suspend) (LP: #1990700)
+    - net: wwan: t7xx: Add AP CLDMA
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v6.1-rc6
+    - [Config] update configs following v6.1-rc6 rebase
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs following v6.1-rc6 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 22 Nov 2022 11:56:26 +0100
+
+linux-unstable (6.1.0-7.7) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-7.7 -proposed tracker (LP: #1996731)
+
+  * Miscellaneous Ubuntu changes
+    - ppc64el: remove missing module
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 16 Nov 2022 11:37:05 +0100
+
+linux-unstable (6.1.0-6.6) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-6.6 -proposed tracker (LP: #1996616)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs following v6.1-rc5 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 15 Nov 2022 15:55:33 +0100
+
+linux-unstable (6.1.0-5.5) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-5.5 -proposed tracker (LP: #1995875)
+
+  * Please have linux-tools-common Provide: bpftool (LP: #1981089)
+    - [Packaging] let linux-tools-common provides bpftool
+
+  * Miscellaneous Ubuntu changes
+    - packaging: switch to lunar series
+    - Rebase to v6.1-rc4
+    - [Config] toolchian update
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc4
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 07 Nov 2022 16:43:21 +0100
+
+linux-unstable (6.1.0-4.4) lunar; urgency=medium
+
+  * kinetic/linux-unstable: 6.1.0-4.4 -proposed tracker (LP: #1995500)
+
+  * Fix ath11k deadlock on WCN6855 (LP: #1995041)
+    - SAUCE: wifi: ath11k: avoid deadlock during regulatory update in
+      ath11k_regd_update()
+
+  * Bump (kernel) '-mtune' to z16 / arch14 with 23.04 (LP: #1982833)
+    - [Config] Enable mtune z16
+
+  * armhf kernel compiled with gcc-12 fails to boot on pi 3/2 (LP: #1993120)
+    - [Packaging] Support arch-specific compilers in updateconfigs
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs after rebase to 6.1-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 03 Nov 2022 14:00:41 +0100
+
+linux-unstable (6.1.0-3.3) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.1.0-3.3 -proposed tracker (LP: #1994037)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Support skipped dkms modules
+    - [Config] update configs after rebase to 6.1-rc2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 24 Oct 2022 15:53:11 +0200
+
+linux-unstable (6.1.0-2.2) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.1.0-2.2 -proposed tracker (LP: #1993350)
+
+  * Populating Hyper-V MSR for Ubuntu 13.10 (LP: #1193172)
+    - SAUCE: (no-up) hv: Supply vendor ID and package ABI
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: perf tools: Fix man page build wrt perf-arm-coresight.txt
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 18 Oct 2022 23:02:31 +0200
+
+linux-unstable (6.1.0-1.1) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.1.0-1.1 -proposed tracker (LP: #1993118)
+
+  * Raise CONFIG_NR_CPUS (LP: #1967889)
+    - [Config] Raise riscv64 CONFIG_NR_CPUS to 32
+
+  * rcu_sched detected stalls on CPUs/tasks (LP: #1967130)
+    - [Config] Disable VMAP_STACK on riscv64
+
+  * Disable sv57 as the userspace is not ready (LP: #1991790)
+    - SAUCE: riscv: mm: Force disable sv57
+
+  * earlyconsole prints question marks on 5.19.0-1002-generic (LP: #1988984)
+    - [Config] Set CONFIG_PWM_SIFIVE=m for riscv64
+
+  * RCU stalls (LP: #1991951)
+    - [Config] Harmonize RCU_CPU_STALL_TIMEOUT
+
+  * backport dkms fixes to build modules correctly for hwe-5.19+ kernels with
+    custom compiler (LP: #1991664)
+    - [Packaging] use versioned gcc-12
+    - [Packaging] Update configs with versioned compiler version
+
+  * FTBFS on kinetic (LP: #1990964)
+    - SAUCE: uapi: Fixup strace compile error
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] sameport -- add support for sameport versioning
+    - [Packaging] move to kernel 6.1
+    - SAUCE: platform/x86: dell-uart-backlight: remove
+      acpi_video_set_dmi_backlight_type()
+    - SAUCE: shiftfs: support kernel 6.1
+    - [Config] update configs and annotations after rebase to 6.1-rc1
+    - debian/dkms-versions -- temporarily disable dkms builds
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 18 Oct 2022 17:21:43 +0200
+
+linux-unstable (6.1.0-0.0) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 17 Oct 2022 08:57:58 +0200
+
+linux-unstable (6.0.0-9.9) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-9.9 -proposed tracker (LP: #1991521)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update toolchain configs after rebase to 6.0
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 03 Oct 2022 15:51:57 +0200
+
+linux-unstable (6.0.0-8.8) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-8.8 -proposed tracker (LP: #1990101)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 20 Sep 2022 10:22:14 +0200
+
+linux-unstable (6.0.0-7.7) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-7.7 -proposed tracker (LP: #1989331)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+    - [Packaging] resync getabis
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Please enable CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU (LP: #1980861)
+    - [Config] Switch from DECOMP_SINGLE to DECOMP_MULTI_PERCPU
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Pass kernel build_arch to dkms
+    - [Packaging[ get rid of unnecessary 'set -x'
+    - [Config] update configs and annotations after rebase to 6.0-rc5
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 12 Sep 2022 14:03:55 +0200
+
+linux-unstable (6.0.0-6.6) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-6.6 -proposed tracker (LP: #1988706)
+
+  * Support Intel TDX guest attestation driver (LP: #1988120)
+    - SAUCE: x86/tdx: Add TDX Guest attestation interface driver
+    - SAUCE: selftests: tdx: Test GetReport TDX attestation feature
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] temporarily disable signing for ppc64el and s390x
+    - [Config] enable security-related configs
+    - [Config] update toolchain versions
+    - [Packaging] fix URLs used to retrieve kernel ABI
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 05 Sep 2022 16:59:40 +0200
+
+linux-unstable (6.0.0-5.5) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-5.5 -proposed tracker (LP: #1988019)
+
+  * LSM: Configuring Too Many LSMs Causes Kernel Panic on Boot (LP: #1987998)
+    - SAUCE: LSM: Change Landlock from LSMBLOB_NEEDED to LSMBLOB_NOT_NEEDED
+
+  * RISC-V kernel config is out of sync with other archs (LP: #1981437)
+    - [Config] Align riscv64 CONFIG_LSM with other architectures
+    - [Config] Enable CONFIG_DRM_RCAR_USE_LVDS for riscv64
+    - [Config] Enable CONFIG_DTPM for riscv64
+    - [Config] Set CONFIG_MTD_RAW_NAND=m for riscv64
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging]: always use fully qualified <triplet>-gcc-VER toolchain
+    - [Packaging] use unversioned default gcc
+    - [Packaging] Remove circular dependency between image & modules
+    - [Config] update configs after rebase to 6.0-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 29 Aug 2022 09:18:39 +0200
+
+linux-unstable (6.0.0-4.4) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-4.4 -proposed tracker (LP: #1987517)
+
+  * Fix invalid MAC address after hotplug tbt dock (LP: #1942999)
+    - SAUCE: igc: wait for the MAC copy when enabled MAC passthrough
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] getabis: Add modules.builtin to the ABI
+
+  * Miscellaneous upstream changes
+    - perf tools: Fix compile error for x86
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 24 Aug 2022 15:10:24 +0200
+
+linux-unstable (6.0.0-3.3) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-3.3 -proposed tracker (LP: #1987241)
+
+  * [22.04 FEAT] Deactivitate  CONFIG_QETH_OSX kernel config option
+    (LP: #1959890)
+    - [Config] disable CONFIG_QETH_OSX on s390x
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Make stamp-install-<flavor> target reentrant
+    - [Config] update toolchain version
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 22 Aug 2022 09:09:26 +0200
+
+linux-unstable (6.0.0-2.2) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-2.2 -proposed tracker (LP: #1986844)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "perf tools: Use Python devtools for version autodetection
+      rather than runtime"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 17 Aug 2022 19:40:07 +0200
+
+linux-unstable (6.0.0-1.1) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-1.1 -proposed tracker (LP: #1986784)
+
+  * refactoring of overlayfs fix to properly support shiftfs (LP: #1983640)
+    - SAUCE: for aufs mmap: print the virtual file path
+    - SAUCE: overlayfs: fix incorrect mnt_id of files opened from map_files
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move to kernel 6.0
+    - [Config] update configs and annotations after rebase to 6.0-rc1
+    - [Packaging] temporarily disable dkms
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 17 Aug 2022 16:56:18 +0200
+
+linux-unstable (6.0.0-0.0) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 17 Aug 2022 10:23:42 +0200
+
+linux (5.19.0-15.15) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-15.15 -proposed tracker (LP: #1983335)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations to support both gcc-11 and gcc-12
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 02 Aug 2022 09:23:01 +0200
+
+linux (5.19.0-14.14) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-14.14 -proposed tracker (LP: #1983273)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] module-signature-check: Check debian.<foo>/signature-inclusion
+    - [Packaging] Introduce debian/scripts/sign-module
+    - SAUCE: Switch to using debian/scripts/sign-module
+    - [Config] update configs/annotations after rebase to 5.19
+    - [Config] update configs after moving to gcc-12
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging]: always use fully qualified <triplet>-gcc-VER
+      toolchain"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 01 Aug 2022 17:19:01 +0200
+
+linux (5.19.0-13.13) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-13.13 -proposed tracker (LP: #1983033)
+
+  * network-manager/1.36.4-2ubuntu1 ADT test failure with linux/5.15.0-28.29
+    (LP: #1971418)
+    - Revert "rfkill: make new event layout opt-in"
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Tighten up LP bug links in annotations
+    - [Config] Use mark<ENFORCED> for CONFIG_DEVTMPFS
+    - [Config] Use flag<DEPRECATED> for CONFIG_HIPPI
+    - [Config] Use note<> for CONFIG_XEN_ACPI_PROCESSOR
+    - [Config] Fix DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING annotation
+    - [Config] Fix CONFIG_CPU_LITTLE_ENDIAN annotation
+    - SAUCE: x86/bugs: Do not enable IBPB at firmware entry when IBPB is not
+      available
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 28 Jul 2022 17:04:33 +0200
+
+linux (5.19.0-12.12) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-12.12 -proposed tracker (LP: #1982741)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging]: always use fully qualified <triplet>-gcc-VER toolchain
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 26 Jul 2022 15:07:13 +0200
+
+linux (5.19.0-11.11) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-11.11 -proposed tracker (LP: #1982726)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * GPIO character device v1 API not enabled in kernel (LP: #1953613)
+    - [Config] Enable CONFIG_GPIO_CDEV_V1
+
+  * Use kernel-testing repo from launchpad for ADT tests (LP: #1968016)
+    - [Debian] Use kernel-testing repo from launchpad
+
+  * Support AMD P-State cpufreq control mechanism (LP: #1956509)
+    - [Config] enable X86_AMD_PSTATE as built-in on amd64
+
+  * PCIE LnkCtl ASPM not enabled under VMD mode for Alder Lake platforms
+    (LP: #1942160)
+    - SAUCE: PCI/ASPM: Enable ASPM for links under VMD domain
+    - SAUCE: PCI/ASPM: Enable LTR for endpoints behind VMD
+    - SAUCE: vmd: fixup bridge ASPM by driver name instead
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Double the speed of updateconfigs
+    - Remove ubuntu/hio driver
+    - [Config] update config after rebase to 5.19-rc8
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc8
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 25 Jul 2022 08:54:21 +0200
+
+linux (5.19.0-10.10) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-10.10 -proposed tracker (LP: #1982013)
+
+  * enable config for fixing 5.17 kernel won't load mok (LP: #1972802)
+    - [Config] enable configs for fixing kernel won't load mok
+
+  * RISC-V kernel config is out of sync with other archs (LP: #1981437)
+    - [Config] Disable CONFIG_CXL_MEM_RAW_COMMANDS on riscv64
+    - [Config] Disable CONFIG_EROFS_FS_ZIP_LZMA on riscv64
+    - [Config] Disable CONFIG_FONT_6x8 on riscv64
+    - [Config] Disable CONFIG_NTFS3_64BIT_CLUSTER on riscv64
+    - [Config] Disable CONFIG_SCSI_IZIP_EPP16 on riscv64
+    - [Config] Disable CONFIG_SCSI_UFS_HWMON on riscv64
+    - [Config] Disable CONFIG_SPI_AX88796C_COMPRESSION on riscv64
+    - [Config] Disable CONFIG_VIDEO_ZORAN on riscv64
+    - [Config] Enable CONFIG_BPF_KPROBE_OVERRIDE on riscv64
+    - [Config] Enable CONFIG_CACHEFILES_ERROR_INJECTION on riscv64
+    - [Config] Enable CONFIG_DRM_AMD_DC_SI on riscv64
+    - [Config] Enable CONFIG_NUMA_BALANCING on riscv64
+    - [Config] Enable CONFIG_PROC_VMCORE_DEVICE_DUMP on riscv64
+    - [Config] Enable CONFIG_WLAN_VENDOR_MICROCHIP on riscv64
+    - [Config] Set CONFIG_MHI_WWAN_CTRL=m on riscv64
+    - [Config] Set CONFIG_NFC_S3FWRN82_UART=m on riscv64
+    - [Config] Enable CONFIG_EFIVAR_FS on riscv64
+    - [Config] Enable CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES on riscv64
+    - [Config] Enable CONFIG_STRICT_DEVMEM on riscv64
+    - [Config] Enable CONFIG_VMAP_STACK on riscv64
+    - [Config] Enable CONFIG_KEXEC_FILE on riscv64
+    - [Config] Set CONFIG_MTD_PSTORE=m on riscv64
+    - [Config] Set CONFIG_KFENCE_SAMPLE_INTERVAL=0 on riscv64
+    - [Config] Enable CONFIG_KEXEC_FILE on s390x
+
+  * Ubuntu 22.04 and 20.04 DPC Fixes for Failure Cases of DownPort Containment
+    events (LP: #1965241)
+    - Enable config option CONFIG_PCIE_EDR
+    - Correct CONFIG_PCIE_EDR annotation on arm64
+
+  * config CONFIG_HISI_PMU for  kunpeng920 (LP: #1956086)
+    - [Config] CONFIG_HISI_PMU=m
+
+  * Skip setting ethernet LED on Dell EMC board (LP: #1971667)
+    - SAUCE: net: phy: marvell: Skip setting LED on Dell EMC board
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] ignore warnings from the output of ld.bfd
+    - [Packaging] Fix bashism in dkms-build script
+    - [Packaging] Always catch errors in dkms-build scripts
+    - [Packaging] Fix dkms builds with linker @module.mod files
+    - [Packaging] mark dkms-build-configure--zfs executable
+    - [Config] update configs and annotations after rebase to 5.19-rc7
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 18 Jul 2022 23:45:28 +0200
+
+linux (5.19.0-9.9) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-9.9 -proposed tracker (LP: #1980622)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update config after rebase to 5.19-rc5
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 04 Jul 2022 12:05:04 +0200
+
+linux (5.19.0-8.8) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-8.8 -proposed tracker (LP: #1980482)
+
+  * temporarily disable CONFIG_X86_KERNEL_IBT (LP: #1980484)
+    - [Config] temporarily disable CONFIG_X86_KERNEL_IBT
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 01 Jul 2022 11:58:56 +0200
+
+linux (5.19.0-7.7) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-7.7 -proposed tracker (LP: #1980056)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * RISC-V enables CONFIG_COMPAT in the unstable branch (LP: #1980061)
+    - [Config] Disable CONFIG_COMPAT on RISC-V
+
+  * No RISC-V configuration in the unstable tree (LP: #1979647)
+    - [Config] Merge riscv64 config and annotations
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 28 Jun 2022 12:25:48 +0200
+
+linux (5.19.0-6.6) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 28 Jun 2022 07:50:17 +0200
+
+linux-unstable (5.19.0-6.6) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-6.6 -proposed tracker (LP: #1979948)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Remove 'family=ubuntu' concept
+    - [Packaging] final-checks: Remove useless sourcing of kernelconfig
+    - [Config] update config after rebase to 5.19-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 27 Jun 2022 09:16:40 +0200
+
+linux-unstable (5.19.0-5.5) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-5.5 -proposed tracker (LP: #1979611)
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] temporarily disable signing for ppc64el and
+      s390x"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 23 Jun 2022 11:13:32 +0200
+
+linux-unstable (5.19.0-4.4) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-4.4 -proposed tracker (LP: #1979177)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs after rebase to 5.19-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 20 Jun 2022 09:02:58 +0200
+
+linux-unstable (5.19.0-3.3) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-3.3 -proposed tracker (LP: #1978439)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations for 5.19
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 13 Jun 2022 07:16:32 +0200
+
+linux-unstable (5.19.0-2.2) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-2.2 -proposed tracker (LP: #1978313)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 10 Jun 2022 15:17:20 +0200
+
+linux-unstable (5.19.0-1.1) kinetic; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * linux: Staging modules should be unsigned (LP: #1642368)
+    - [Packaging] Move and update signature inclusion list
+    - [Packaging] Strip signatures from untrusted staging modules
+    - [Packaging] Add module-signature-check
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to 5.19-rc1
+    - [Packaging] move to kernel 5.19
+    - [Packaging] workaround missing python3-dev dependency
+    - SAUCE: Revert "perf tools: Use Python devtools for version autodetection
+      rather than runtime"
+    - SAUCE: watchdog: gxp: Add missing MODULE_LICENSE
+    - [Packaging] add python3-dev as build dependency
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 10 Jun 2022 14:43:46 +0200
+
+linux-unstable (5.19.0-0.0) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 09 Jun 2022 12:13:06 +0200
+
+linux (5.18.0-6.6) kinetic; urgency=medium
+
+  * kinetic/linux: 5.18.0-6.6 -proposed tracker (LP: #1976327)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] temporarily disable signing for ppc64el and s390x
+    - [Config] update toolchain versions
+    - [Config] enable CONFIG_X86_KERNEL_IBT
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 31 May 2022 11:05:51 +0200
+
+linux (5.18.0-5.5) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 23 May 2022 16:59:47 +0200
+
+linux-unstable (5.18.0-5.5) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-5.5 -proposed tracker (LP: #1975458)
+
+  * enable CONFIG_DEVTMPFS_SAFE (LP: #1974442)
+    - [Config] enable CONFIG_DEVTMPFS_SAFE
+
+  * build backport-iwlwifi-dkms as linux-modules-iwlwifi-ABI (LP: #1969434)
+    - [Packaging] drop do_<mod> arch specific configs
+
+  * prevent kernel panic with overlayfs + shiftfs (LP: #1973620)
+    - SAUCE: overlayfs: prevent dereferencing struct file in ovl_vm_prfile_set()
+
+  * linux-image-5.0.0-35-generic breaks checkpointing of container
+    (LP: #1857257) // re-apply missing overlayfs SAUCE patch (LP: #1967924)
+    - SAUCE: overlayfs: fix incorrect mnt_id of files opened from map_files
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 23 May 2022 11:21:38 +0200
+
+linux-unstable (5.18.0-4.4) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-4.4 -proposed tracker (LP: #1973587)
+
+  * build backport-iwlwifi-dkms as linux-modules-iwlwifi-ABI (LP: #1969434)
+    - [Packaging] support standalone dkms module builds
+
+  * Enable speakup kernel modules to allow the speakup screen reader to function
+    (LP: #1967702)
+    - [Config] CONFIG_SPEAKUP=m for all but s390x
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] temporarily disable v4l2loopback"
+    - Revert "UBUNTU: [Packaging] temporarily disable zfs"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 16 May 2022 14:15:35 +0200
+
+linux-unstable (5.18.0-3.3) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-3.3 -proposed tracker (LP: #1972162)
+
+  * disable Intel DMA remapping by default (LP: #1971699)
+    - Revert "UBUNTU: [Config] enable Intel DMA remapping options by default"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 May 2022 12:15:39 +0200
+
+linux-unstable (5.18.0-2.2) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-2.2 -proposed tracker (LP: #1971340)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs after rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 03 May 2022 12:24:49 +0200
+
+linux-unstable (5.18.0-1.1) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 03 May 2022 09:38:06 +0200
+
+linux-unstable (5.18.0-1.1) jammy; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-1.1 -proposed tracker (LP: #1969476)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to 5.18
+    - [Packaging] temporarily disable zfs
+    - [Packaging] temporarily disable v4l2loopback
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 27 Apr 2022 20:26:42 +0200
+
+linux-unstable (5.18.0-0.0) jammy; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 19 Apr 2022 16:20:00 +0200
+
+linux-unstable (5.17.0-8.8) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-8.8 -proposed tracker (LP: #1969016)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 14 Apr 2022 10:30:39 +0200
+
+linux-unstable (5.17.0-7.7) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-7.7 -proposed tracker (LP: #1968988)
+
+  * zfcpdump-kernel update to v5.15 (LP: #1965766)
+    - SAUCE: Audit: Fix incorrect static inline function declration.
+
+  * intel_iommu breaks Intel IPU6 camera: isys port open ready failed -16
+    (LP: #1958004)
+    - SAUCE: iommu: intel-ipu: use IOMMU passthrough mode for Intel IPUs
+
+  * Jammy update: v5.17.3 upstream stable release (LP: #1968986)
+    - lib/logic_iomem: correct fallback config references
+    - um: fix and optimize xor select template for CONFIG64 and timetravel mode
+    - rtc: wm8350: Handle error for wm8350_register_irq
+    - net: dsa: felix: fix possible NULL pointer dereference
+    - mm: kfence: fix objcgs vector allocation
+    - KVM: x86/pmu: Use different raw event masks for AMD and Intel
+    - KVM: SVM: Fix kvm_cache_regs.h inclusions for is_guest_mode()
+    - KVM: x86/svm: Clear reserved bits written to PerfEvtSeln MSRs
+    - KVM: x86/pmu: Fix and isolate TSX-specific performance event logic
+    - KVM: x86/emulator: Emulate RDPID only if it is enabled in guest
+    - drm: Add orientation quirk for GPD Win Max
+    - Bluetooth: hci_sync: Fix compilation warning
+    - ath5k: fix OOB in ath5k_eeprom_read_pcal_info_5111
+    - Bluetooth: fix null ptr deref on hci_sync_conn_complete_evt
+    - drm/amd/display: Add signal type check when verify stream backends same
+    - drm/amdkfd: enable heavy-weight TLB flush on Arcturus
+    - drm/edid: remove non_desktop quirk for HPN-3515 and LEN-B800.
+    - drm/edid: improve non-desktop quirk logging
+    - Bluetooth: hci_event: Ignore multiple conn complete events
+    - drm/amd/amdgpu/amdgpu_cs: fix refcount leak of a dma_fence obj
+    - drm/amd/display: Fix memory leak
+    - drm/amd/display: Use PSR version selected during set_psr_caps
+    - usb: gadget: tegra-xudc: Do not program SPARAM
+    - usb: gadget: tegra-xudc: Fix control endpoint's definitions
+    - usb: cdnsp: fix cdnsp_decode_trb function to properly handle ret value
+    - ptp: replace snprintf with sysfs_emit
+    - Bluetooth: hci_sync: Fix queuing commands when HCI_UNREGISTER is set
+    - selftests, xsk: Fix bpf_res cleanup test
+    - net/mlx5e: TC, Hold sample_attr on stack instead of pointer
+    - drm/amdkfd: Don't take process mutex for svm ioctls
+    - drm/amdkfd: Ensure mm remain valid in svm deferred_list work
+    - drm/amdkfd: svm range restore work deadlock when process exit
+    - drm/amdgpu: Fix an error message in rmmod
+    - mlxsw: spectrum: Guard against invalid local ports
+    - RDMA/rtrs-clt: Do stop and failover outside reconnect work.
+    - powerpc/xive: Export XIVE IPI information for online-only processors.
+    - powerpc: dts: t104xrdb: fix phy type for FMAN 4/5
+    - ath11k: fix kernel panic during unload/load ath11k modules
+    - ath11k: pci: fix crash on suspend if board file is not found
+    - ath11k: mhi: use mhi_sync_power_up()
+    - net/smc: Send directly when TCP_CORK is cleared
+    - drm/bridge: Add missing pm_runtime_put_sync
+    - bpf: Make dst_port field in struct bpf_sock 16-bit wide
+    - scsi: mvsas: Replace snprintf() with sysfs_emit()
+    - scsi: bfa: Replace snprintf() with sysfs_emit()
+    - drm/v3d: fix missing unlock
+    - power: supply: axp20x_battery: properly report current when discharging
+    - mt76: mt7921: fix crash when startup fails.
+    - mt76: dma: initialize skip_unmap in mt76_dma_rx_fill
+    - i40e: Add sending commands in atomic context
+    - cfg80211: don't add non transmitted BSS to 6GHz scanned channels
+    - libbpf: Fix build issue with llvm-readelf
+    - ipv6: make mc_forwarding atomic
+    - ref_tracker: implement use-after-free detection
+    - net: initialize init_net earlier
+    - powerpc: Set crashkernel offset to mid of RMA region
+    - drm/amdgpu: Fix recursive locking warning
+    - scsi: smartpqi: Fix rmmod stack trace
+    - scsi: smartpqi: Fix kdump issue when controller is locked up
+    - PCI: aardvark: Fix support for MSI interrupts
+    - kvm: selftests: aarch64: fix assert in gicv3_access_reg
+    - kvm: selftests: aarch64: pass vgic_irq guest args as a pointer
+    - kvm: selftests: aarch64: fix the failure check in
+      kvm_set_gsi_routing_irqchip_check
+    - kvm: selftests: aarch64: fix some vgic related comments
+    - kvm: selftests: aarch64: use a tighter assert in vgic_poke_irq()
+    - iommu/arm-smmu-v3: fix event handling soft lockup
+    - usb: ehci: add pci device support for Aspeed platforms
+    - KVM: arm64: Do not change the PMU event filter after a VCPU has run
+    - libbpf: Fix accessing syscall arguments on powerpc
+    - libbpf: Fix accessing the first syscall argument on arm64
+    - libbpf: Fix accessing the first syscall argument on s390
+    - PCI: endpoint: Fix alignment fault error in copy tests
+    - tcp: Don't acquire inet_listen_hashbucket::lock with disabled BH.
+    - PCI: pciehp: Add Qualcomm quirk for Command Completed erratum
+    - scsi: mpi3mr: Fix deadlock while canceling the fw event
+    - scsi: mpi3mr: Fix reporting of actual data transfer size
+    - scsi: mpi3mr: Fix memory leaks
+    - powerpc/set_memory: Avoid spinlock recursion in change_page_attr()
+    - power: supply: axp288-charger: Set Vhold to 4.4V
+    - drm/sprd: fix potential NULL dereference
+    - drm/sprd: check the platform_get_resource() return value
+    - drm/amd/display: reset lane settings after each PHY repeater LT
+    - net/mlx5e: Disable TX queues before registering the netdev
+    - HID: apple: Report Magic Keyboard 2021 battery over USB
+    - HID: apple: Report Magic Keyboard 2021 with fingerprint reader battery over
+      USB
+    - usb: dwc3: pci: Set the swnode from inside dwc3_pci_quirks()
+    - iwlwifi: mvm: Correctly set fragmented EBS
+    - iwlwifi: fix small doc mistake for iwl_fw_ini_addr_val
+    - iwlwifi: mvm: move only to an enabled channel
+    - ipv6: annotate some data-races around sk->sk_prot
+    - drm/msm/dsi: Remove spurious IRQF_ONESHOT flag
+    - x86/mce: Work around an erratum on fast string copy instructions
+    - rtw89: fix RCU usage in rtw89_core_txq_push()
+    - ath11k: Fix frames flush failure caused by deadlock
+    - ipv4: Invalidate neighbour for broadcast address upon address addition
+    - rtw88: change rtw_info() to proper message level
+    - dm ioctl: prevent potential spectre v1 gadget
+    - dm: requeue IO if mapping table not yet available
+    - drm/amdkfd: make CRAT table missing message informational only
+    - vfio/pci: Stub vfio_pci_vga_rw when !CONFIG_VFIO_PCI_VGA
+    - scsi: pm8001: Fix pm80xx_pci_mem_copy() interface
+    - scsi: pm8001: Fix pm8001_mpi_task_abort_resp()
+    - scsi: pm8001: Fix tag values handling
+    - scsi: pm8001: Fix task leak in pm8001_send_abort_all()
+    - scsi: pm8001: Fix tag leaks on error
+    - scsi: pm8001: Fix memory leak in pm8001_chip_fw_flash_update_req()
+    - mt76: mt7915: fix injected MPDU transmission to not use HW A-MSDU
+    - mctp: make __mctp_dev_get() take a refcount hold
+    - powerpc/64s/hash: Make hash faults work in NMI context
+    - mt76: mt7615: Fix assigning negative values to unsigned variable
+    - power: supply: axp288_charger: Use acpi_quirk_skip_acpi_ac_and_battery()
+    - power: supply: axp288_fuel_gauge: Use acpi_quirk_skip_acpi_ac_and_battery()
+    - scsi: aha152x: Fix aha152x_setup() __setup handler return value
+    - scsi: hisi_sas: Free irq vectors in order for v3 HW
+    - scsi: hisi_sas: Limit users changing debugfs BIST count value
+    - net/smc: correct settings of RMB window update limit
+    - mips: ralink: fix a refcount leak in ill_acc_of_setup()
+    - iavf: stop leaking iavf_status as "errno" values
+    - macvtap: advertise link netns via netlink
+    - platform/x86: thinkpad_acpi: Add dual fan probe
+    - tuntap: add sanity checks about msg_controllen in sendmsg
+    - Bluetooth: mediatek: fix the conflict between mtk and msft vendor event
+    - Bluetooth: Fix not checking for valid hdev on bt_dev_{info,warn,err,dbg}
+    - Bluetooth: use memset avoid memory leaks
+    - bnxt_en: Eliminate unintended link toggle during FW reset
+    - PCI: endpoint: Fix misused goto label
+    - MIPS: fix fortify panic when copying asm exception handlers
+    - powerpc/code-patching: Pre-map patch area
+    - powerpc/64e: Tie PPC_BOOK3E_64 to PPC_FSL_BOOK3E
+    - powerpc/secvar: fix refcount leak in format_show()
+    - scsi: libfc: Fix use after free in fc_exch_abts_resp()
+    - platform/x86: x86-android-tablets: Depend on EFI and SPI
+    - can: isotp: set default value for N_As to 50 micro seconds
+    - can: etas_es58x: es58x_fd_rx_event_msg(): initialize rx_event_msg before
+      calling es58x_check_msg_len()
+    - riscv: Fixed misaligned memory access. Fixed pointer comparison.
+    - net: account alternate interface name memory
+    - net: limit altnames to 64k total
+    - net/mlx5e: Remove overzealous validations in netlink EEPROM query
+    - platform/x86: hp-wmi: Fix SW_TABLET_MODE detection method
+    - platform/x86: hp-wmi: Fix 0x05 error code reported by several WMI calls
+    - net: sfp: add 2500base-X quirk for Lantech SFP module
+    - usb: dwc3: omap: fix "unbalanced disables for smps10_out1" on omap5evm
+    - xen/usb: harden xen_hcd against malicious backends
+    - mt76: fix monitor mode crash with sdio driver
+    - xtensa: fix DTC warning unit_address_format
+    - iwlwifi: mei: fix building iwlmei
+    - MIPS: ingenic: correct unit node address
+    - Bluetooth: Fix use after free in hci_send_acl
+    - netfilter: conntrack: revisit gc autotuning
+    - netlabel: fix out-of-bounds memory accesses
+    - ceph: fix inode reference leakage in ceph_get_snapdir()
+    - ceph: fix memory leak in ceph_readdir when note_last_dentry returns error
+    - lib/Kconfig.debug: add ARCH dependency for FUNCTION_ALIGN option
+    - init/main.c: return 1 from handled __setup() functions
+    - minix: fix bug when opening a file with O_DIRECT
+    - clk: si5341: fix reported clk_rate when output divider is 2
+    - clk: mediatek: Fix memory leaks on probe
+    - staging: vchiq_arm: Avoid NULL ptr deref in vchiq_dump_platform_instances
+    - staging: vchiq_core: handle NULL result of find_service_by_handle
+    - phy: amlogic: phy-meson-gxl-usb2: fix shared reset controller use
+    - phy: amlogic: meson8b-usb2: Use dev_err_probe()
+    - phy: amlogic: meson8b-usb2: fix shared reset control use
+    - clk: rockchip: drop CLK_SET_RATE_PARENT from dclk_vop* on rk3568
+    - cpufreq: CPPC: Fix performance/frequency conversion
+    - opp: Expose of-node's name in debugfs
+    - staging: wfx: apply the necessary SDIO quirks for the Silabs WF200
+    - staging: wfx: fix an error handling in wfx_init_common()
+    - w1: w1_therm: fixes w1_seq for ds28ea00 sensors
+    - NFSv4.2: fix reference count leaks in _nfs42_proc_copy_notify()
+    - NFSv4: Protect the state recovery thread against direct reclaim
+    - habanalabs: fix possible memory leak in MMU DR fini
+    - habanalabs: reject host map with mmu disabled
+    - habanalabs/gaudi: handle axi errors from NIC engines
+    - xen: delay xen_hvm_init_time_ops() if kdump is boot on vcpu>=32
+    - clk: ti: Preserve node in ti_dt_clocks_register()
+    - clk: Enforce that disjoints limits are invalid
+    - SUNRPC/xprt: async tasks mustn't block waiting for memory
+    - SUNRPC: remove scheduling boost for "SWAPPER" tasks.
+    - NFS: swap IO handling is slightly different for O_DIRECT IO
+    - NFS: swap-out must always use STABLE writes.
+    - x86: Annotate call_on_stack()
+    - x86/Kconfig: Do not allow CONFIG_X86_X32_ABI=y with llvm-objcopy
+    - serial: samsung_tty: do not unlock port->lock for uart_write_wakeup()
+    - virtio_console: eliminate anonymous module_init & module_exit
+    - jfs: prevent NULL deref in diFree
+    - SUNRPC: Fix socket waits for write buffer space
+    - NFS: nfsiod should not block forever in mempool_alloc()
+    - NFS: Avoid writeback threads getting stuck in mempool_alloc()
+    - selftests: net: Add tls config dependency for tls selftests
+    - parisc: Fix CPU affinity for Lasi, WAX and Dino chips
+    - parisc: Fix patch code locking and flushing
+    - mm: fix race between MADV_FREE reclaim and blkdev direct IO read
+    - drm/amdgpu: fix off by one in amdgpu_gfx_kiq_acquire()
+    - Drivers: hv: vmbus: Fix initialization of device object in
+      vmbus_device_register()
+    - Drivers: hv: vmbus: Fix potential crash on module unload
+    - netfilter: bitwise: fix reduce comparisons
+    - Revert "NFSv4: Handle the special Linux file open access mode"
+    - NFSv4: fix open failure with O_ACCMODE flag
+    - scsi: core: scsi_logging: Fix a BUG
+    - scsi: sr: Fix typo in CDROM(CLOSETRAY|EJECT) handling
+    - scsi: core: Fix sbitmap depth in scsi_realloc_sdev_budget_map()
+    - scsi: zorro7xx: Fix a resource leak in zorro7xx_remove_one()
+    - vdpa: mlx5: prevent cvq work from hogging CPU
+    - net: sfc: add missing xdp queue reinitialization
+    - net/tls: fix slab-out-of-bounds bug in decrypt_internal
+    - vrf: fix packet sniffing for traffic originating from ip tunnels
+    - skbuff: fix coalescing for page_pool fragment recycling
+    - Revert "net: dsa: stop updating master MTU from master.c"
+    - ice: Clear default forwarding VSI during VSI release
+    - ice: Fix MAC address setting
+    - mctp: Fix check for dev_hard_header() result
+    - mctp: Use output netdev to allocate skb headroom
+    - net: ipv4: fix route with nexthop object delete warning
+    - net: stmmac: Fix unset max_speed difference between DT and non-DT platforms
+    - drm/imx: imx-ldb: Check for null pointer after calling kmemdup
+    - drm/imx: Fix memory leak in imx_pd_connector_get_modes
+    - drm/imx: dw_hdmi-imx: Fix bailout in error cases of probe
+    - regulator: rtq2134: Fix missing active_discharge_on setting
+    - spi: rpc-if: Fix RPM imbalance in probe error path
+    - regulator: atc260x: Fix missing active_discharge_on setting
+    - arch/arm64: Fix topology initialization for core scheduling
+    - bnxt_en: Synchronize tx when xdp redirects happen on same ring
+    - bnxt_en: reserve space inside receive page for skb_shared_info
+    - bnxt_en: Prevent XDP redirect from running when stopping TX queue
+    - sfc: Do not free an empty page_ring
+    - RDMA/mlx5: Don't remove cache MRs when a delay is needed
+    - RDMA/mlx5: Add a missing update of cache->last_add
+    - IB/cm: Cancel mad on the DREQ event when the state is MRA_REP_RCVD
+    - cifs: fix potential race with cifsd thread
+    - IB/rdmavt: add lock to call to rvt_error_qp to prevent a race condition
+    - sctp: count singleton chunks in assoc user stats
+    - dpaa2-ptp: Fix refcount leak in dpaa2_ptp_probe
+    - ice: Set txq_teid to ICE_INVAL_TEID on ring creation
+    - ice: Do not skip not enabled queues in ice_vc_dis_qs_msg
+    - ipv6: Fix stats accounting in ip6_pkt_drop
+    - ice: synchronize_rcu() when terminating rings
+    - ice: xsk: fix VSI state check in ice_xsk_wakeup()
+    - ice: clear cmd_type_offset_bsz for TX rings
+    - net: openvswitch: don't send internal clone attribute to the userspace.
+    - net: ethernet: mv643xx: Fix over zealous checking of_get_mac_address()
+    - net: openvswitch: fix leak of nested actions
+    - rxrpc: fix a race in rxrpc_exit_net()
+    - net: sfc: fix using uninitialized xdp tx_queue
+    - net: phy: mscc-miim: reject clause 45 register accesses
+    - qede: confirm skb is allocated before using
+    - spi: bcm-qspi: fix MSPI only access with bcm_qspi_exec_mem_op()
+    - drm/amd/display: Fix for dmub outbox notification enable
+    - drm/amd/display: Remove redundant dsc power gating from init_hw
+    - bpf: Support dual-stack sockets in bpf_tcp_check_syncookie
+    - drbd: Fix five use after free bugs in get_initial_state
+    - scsi: sd: sd_read_cpr() requires VPD pages
+    - scsi: ufs: ufshpb: Fix a NULL check on list iterator
+    - io_uring: nospec index for tags on files update
+    - io_uring: don't touch scm_fp_list after queueing skb
+    - SUNRPC: Handle ENOMEM in call_transmit_status()
+    - SUNRPC: Handle low memory situations in call_status()
+    - SUNRPC: svc_tcp_sendmsg() should handle errors from xdr_alloc_bvec()
+    - iommu/omap: Fix regression in probe for NULL pointer dereference
+    - perf unwind: Don't show unwind error messages when augmenting frame pointer
+      stack
+    - perf: arm-spe: Fix perf report --mem-mode
+    - perf tools: Fix perf's libperf_print callback
+    - perf session: Remap buf if there is no space for event
+    - arm64: Add part number for Arm Cortex-A78AE
+    - scsi: mpt3sas: Fix use after free in _scsih_expander_node_remove()
+    - scsi: ufs: ufs-pci: Add support for Intel MTL
+    - Revert "mmc: sdhci-xenon: fix annoying 1.8V regulator warning"
+    - mmc: block: Check for errors after write on SPI
+    - mmc: mmci: stm32: correctly check all elements of sg list
+    - mmc: renesas_sdhi: special 4tap settings only apply to HS400
+    - mmc: renesas_sdhi: don't overwrite TAP settings when HS400 tuning is
+      complete
+    - mmc: core: Fixup support for writeback-cache for eMMC and SD
+    - lz4: fix LZ4_decompress_safe_partial read out of bound
+    - highmem: fix checks in __kmap_local_sched_{in,out}
+    - mmmremap.c: avoid pointless invalidate_range_start/end on mremap(old_size=0)
+    - mm/mempolicy: fix mpol_new leak in shared_policy_replace
+    - io_uring: don't check req->file in io_fsync_prep()
+    - io_uring: defer splice/tee file validity check until command issue
+    - io_uring: implement compat handling for IORING_REGISTER_IOWQ_AFF
+    - io_uring: fix race between timeout flush and removal
+    - x86/pm: Save the MSR validity status at context setup
+    - x86/speculation: Restore speculation related MSRs during S3 resume
+    - perf/x86/intel: Update the FRONTEND MSR mask on Sapphire Rapids
+    - btrfs: fix qgroup reserve overflow the qgroup limit
+    - btrfs: zoned: traverse devices under chunk_mutex in btrfs_can_activate_zone
+    - btrfs: remove device item and update super block in the same transaction
+    - btrfs: avoid defragging extents whose next extents are not targets
+    - btrfs: prevent subvol with swapfile from being deleted
+    - spi: core: add dma_map_dev for __spi_unmap_msg()
+    - cifs: force new session setup and tcon for dfs
+    - qed: fix ethtool register dump
+    - arm64: patch_text: Fixup last cpu should be master
+    - RDMA/hfi1: Fix use-after-free bug for mm struct
+    - drbd: fix an invalid memory access caused by incorrect use of list iterator
+    - gpio: Restrict usage of GPIO chip irq members before initialization
+    - x86/msi: Fix msi message data shadow struct
+    - x86/mm/tlb: Revert retpoline avoidance approach
+    - perf/x86/intel: Don't extend the pseudo-encoding to GP counters
+    - ata: sata_dwc_460ex: Fix crash due to OOB write
+    - perf: qcom_l2_pmu: fix an incorrect NULL check on list iterator
+    - perf/core: Inherit event_caps
+    - irqchip/gic-v3: Fix GICR_CTLR.RWP polling
+    - fbdev: Fix unregistering of framebuffers without device
+    - amd/display: set backlight only if required
+    - drm/panel: ili9341: fix optional regulator handling
+    - drm/amd/display: Fix by adding FPU protection for dcn30_internal_validate_bw
+    - drm/amdgpu/display: change pipe policy for DCN 2.1
+    - drm/amdgpu/smu10: fix SoC/fclk units in auto mode
+    - drm/amdgpu/vcn: Fix the register setting for vcn1
+    - drm/nouveau/pmu: Add missing callbacks for Tegra devices
+    - drm/amdkfd: Create file descriptor after client is added to smi_clients list
+    - drm/amdgpu: don't use BACO for reset in S3
+    - SUNRPC: Ensure we flush any closed sockets before xs_xprt_free()
+    - Revert "ACPI: processor: idle: Only flush cache on entering C3"
+    - drm/amdkfd: Fix variable set but not used warning
+    - net/smc: send directly on setting TCP_NODELAY
+    - Revert "selftests: net: Add tls config dependency for tls selftests"
+    - bpf: Make remote_port field in struct bpf_sk_lookup 16-bit wide
+    - selftests/bpf: Fix u8 narrow load checks for bpf_sk_lookup remote_port
+    - bpf: Treat bpf_sk_lookup remote_port as a 2-byte field
+    - perf build: Don't use -ffat-lto-objects in the python feature test when
+      building with clang-13
+    - perf python: Fix probing for some clang command line options
+    - tools build: Filter out options and warnings not supported by clang
+    - tools build: Use $(shell ) instead of `` to get embedded libperl's ccopts
+    - dmaengine: Revert "dmaengine: shdma: Fix runtime PM imbalance on error"
+    - KVM: avoid NULL pointer dereference in kvm_dirty_ring_push
+    - Drivers: hv: vmbus: Replace smp_store_mb() with virt_store_mb()
+    - powerpc: Fix virt_addr_valid() for 64-bit Book3E & 32-bit
+    - Revert "powerpc: Set max_mapnr correctly"
+    - x86/bug: Prevent shadowing in __WARN_FLAGS
+    - objtool: Fix SLS validation for kcov tail-call replacement
+    - sched/core: Fix forceidle balancing
+    - sched: Teach the forced-newidle balancer about CPU affinity limitation.
+    - x86,static_call: Fix __static_call_return0 for i386
+    - x86/extable: Prefer local labels in .set directives
+    - irqchip/gic-v4: Wait for GICR_VPENDBASER.Dirty to clear before descheduling
+    - powerpc/64: Fix build failure with allyesconfig in book3s_64_entry.S
+    - irqchip/gic, gic-v3: Prevent GSI to SGI translations
+    - mm/sparsemem: fix 'mem_section' will never be NULL gcc 12 warning
+    - static_call: Don't make __static_call_return0 static
+    - io_uring: move read/write file prep state into actual opcode handler
+    - io_uring: propagate issue_flags state down to file assignment
+    - io_uring: defer file assignment
+    - io_uring: drop the old style inflight file tracking
+    - Linux 5.17.3
+
+  * Jammy update: v5.17.2 upstream stable release Edit (LP: #1968984)
+    - Revert "swiotlb: rework "fix info leak with DMA_FROM_DEVICE""
+    - USB: serial: pl2303: add IBM device IDs
+    - dt-bindings: usb: hcd: correct usb-device path
+    - USB: serial: pl2303: fix GS type detection
+    - USB: serial: simple: add Nokia phone driver
+    - mm: kfence: fix missing objcg housekeeping for SLAB
+    - locking/lockdep: Avoid potential access of invalid memory in lock_class
+    - drm/amdgpu: move PX checking into amdgpu_device_ip_early_init
+    - drm/amdgpu: only check for _PR3 on dGPUs
+    - iommu/iova: Improve 32-bit free space estimate
+    - block: flush plug based on hardware and software queue order
+    - block: ensure plug merging checks the correct queue at least once
+    - usb: typec: tipd: Forward plug orientation to typec subsystem
+    - USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c
+    - xhci: fix garbage USBSTS being logged in some cases
+    - xhci: fix runtime PM imbalance in USB2 resume
+    - xhci: make xhci_handshake timeout for xhci_reset() adjustable
+    - xhci: fix uninitialized string returned by xhci_decode_ctrl_ctx()
+    - mei: me: disable driver on the ign firmware
+    - mei: me: add Alder Lake N device id.
+    - mei: avoid iterator usage outside of list_for_each_entry
+    - bus: mhi: pci_generic: Add mru_default for Quectel EM1xx series
+    - bus: mhi: Fix pm_state conversion to string
+    - bus: mhi: Fix MHI DMA structure endianness
+    - docs: sphinx/requirements: Limit jinja2<3.1
+    - coresight: Fix TRCCONFIGR.QE sysfs interface
+    - coresight: syscfg: Fix memleak on registration failure in
+      cscfg_create_device
+    - dt-bindings: iio: adc: zynqmp_ams: Add clock entry
+    - iio: adc: xilinx-ams: Fix single channel switching sequence
+    - iio: accel: mma8452: use the correct logic to get mma8452_data
+    - iio: adc: aspeed: Add divider flag to fix incorrect voltage reading.
+    - iio: imu: st_lsm6dsx: use dev_to_iio_dev() to get iio_dev struct
+    - iio: afe: rescale: use s64 for temporary scale calculations
+    - iio: adc: xilinx-ams: Fixed missing PS channels
+    - iio: adc: xilinx-ams: Fixed wrong sequencer register settings
+    - iio: inkern: apply consumer scale on IIO_VAL_INT cases
+    - iio: inkern: apply consumer scale when no channel scale is available
+    - iio: inkern: make a best effort on offset calculation
+    - greybus: svc: fix an error handling bug in gb_svc_hello()
+    - clk: rockchip: re-add rational best approximation algorithm to the
+      fractional divider
+    - clk: uniphier: Fix fixed-rate initialization
+    - ptrace: Check PTRACE_O_SUSPEND_SECCOMP permission on PTRACE_SEIZE
+    - cifs: truncate the inode and mapping when we simulate fcollapse
+    - cifs: fix handlecache and multiuser
+    - cifs: we do not need a spinlock around the tree access during umount
+    - KEYS: fix length validation in keyctl_pkey_params_get_2()
+    - KEYS: asymmetric: enforce that sig algo matches key algo
+    - KEYS: asymmetric: properly validate hash_algo and encoding
+    - Documentation: add link to stable release candidate tree
+    - Documentation: update stable tree link
+    - firmware: stratix10-svc: add missing callback parameter on RSU
+    - firmware: sysfb: fix platform-device leak in error path
+    - HID: intel-ish-hid: Use dma_alloc_coherent for firmware update
+    - SUNRPC: avoid race between mod_timer() and del_timer_sync()
+    - SUNRPC: Do not dereference non-socket transports in sysfs
+    - NFS: NFSv2/v3 clients should never be setting NFS_CAP_XATTR
+    - NFSD: prevent underflow in nfssvc_decode_writeargs()
+    - NFSD: prevent integer overflow on 32 bit systems
+    - f2fs: fix to unlock page correctly in error path of is_alive()
+    - f2fs: quota: fix loop condition at f2fs_quota_sync()
+    - f2fs: fix to do sanity check on .cp_pack_total_block_count
+    - remoteproc: Fix count check in rproc_coredump_write()
+    - mm/mlock: fix two bugs in user_shm_lock()
+    - pinctrl: ingenic: Fix regmap on X series SoCs
+    - pinctrl: samsung: drop pin banks references on error paths
+    - net: bnxt_ptp: fix compilation error
+    - spi: mxic: Fix the transmit path
+    - mtd: spi-nor: Skip erase logic when SPI_NOR_NO_ERASE is set
+    - mtd: rawnand: protect access to rawnand devices while in suspend
+    - can: ems_usb: ems_usb_start_xmit(): fix double dev_kfree_skb() in error path
+    - can: m_can: m_can_tx_handler(): fix use after free of skb
+    - can: usb_8dev: usb_8dev_start_xmit(): fix double dev_kfree_skb() in error
+      path
+    - jffs2: fix use-after-free in jffs2_clear_xattr_subsystem
+    - jffs2: fix memory leak in jffs2_do_mount_fs
+    - jffs2: fix memory leak in jffs2_scan_medium
+    - mm: fs: fix lru_cache_disabled race in bh_lru
+    - mm: don't skip swap entry even if zap_details specified
+    - mm/pages_alloc.c: don't create ZONE_MOVABLE beyond the end of a node
+    - mm: invalidate hwpoison page cache page in fault path
+    - mempolicy: mbind_range() set_policy() after vma_merge()
+    - scsi: core: sd: Add silence_suspend flag to suppress some PM messages
+    - scsi: ufs: Fix runtime PM messages never-ending cycle
+    - scsi: scsi_transport_fc: Fix FPIN Link Integrity statistics counters
+    - scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands
+    - qed: display VF trust config
+    - qed: validate and restrict untrusted VFs vlan promisc mode
+    - riscv: dts: canaan: Fix SPI3 bus width
+    - riscv: Fix fill_callchain return value
+    - riscv: Increase stack size under KASAN
+    - RISC-V: Declare per cpu boot data as static
+    - Revert "Input: clear BTN_RIGHT/MIDDLE on buttonpads"
+    - cifs: do not skip link targets when an I/O fails
+    - cifs: fix incorrect use of list iterator after the loop
+    - cifs: prevent bad output lengths in smb2_ioctl_query_info()
+    - cifs: fix NULL ptr dereference in smb2_ioctl_query_info()
+    - ALSA: cs4236: fix an incorrect NULL check on list iterator
+    - ALSA: hda: Avoid unsol event during RPM suspending
+    - ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock
+    - ALSA: hda/realtek: Fix audio regression on Mi Notebook Pro 2020
+    - rtc: mc146818-lib: fix locking in mc146818_set_time
+    - rtc: pl031: fix rtc features null pointer dereference
+    - io_uring: ensure that fsnotify is always called
+    - ocfs2: fix crash when mount with quota enabled
+    - drm/simpledrm: Add "panel orientation" property on non-upright mounted LCD
+      panels
+    - mm: madvise: skip unmapped vma holes passed to process_madvise
+    - mm: madvise: return correct bytes advised with process_madvise
+    - Revert "mm: madvise: skip unmapped vma holes passed to process_madvise"
+    - mm,hwpoison: unmap poisoned page before invalidation
+    - mm: only re-generate demotion targets when a numa node changes its N_CPU
+      state
+    - mm/kmemleak: reset tag when compare object pointer
+    - dm stats: fix too short end duration_ns when using precise_timestamps
+    - dm: fix use-after-free in dm_cleanup_zoned_dev()
+    - dm: interlock pending dm_io and dm_wait_for_bios_completion
+    - dm: fix double accounting of flush with data
+    - dm integrity: set journal entry unused when shrinking device
+    - tracing: Have trace event string test handle zero length strings
+    - drbd: fix potential silent data corruption
+    - can: isotp: sanitize CAN ID checks in isotp_bind()
+    - PCI: fu740: Force 2.5GT/s for initial device probe
+    - arm64: signal: nofpsimd: Do not allocate fp/simd context when not available
+    - arm64: Do not defer reserve_crashkernel() for platforms with no DMA memory
+      zones
+    - arm64: dts: qcom: sm8250: Fix MSI IRQ for PCIe1 and PCIe2
+    - arm64: dts: ti: k3-am65: Fix gic-v3 compatible regs
+    - arm64: dts: ti: k3-j721e: Fix gic-v3 compatible regs
+    - arm64: dts: ti: k3-j7200: Fix gic-v3 compatible regs
+    - arm64: dts: ti: k3-am64: Fix gic-v3 compatible regs
+    - arm64: dts: ti: k3-j721s2: Fix gic-v3 compatible regs
+    - ASoC: SOF: Intel: Fix NULL ptr dereference when ENOMEM
+    - mmc: core: use sysfs_emit() instead of sprintf()
+    - Revert "ACPI: Pass the same capabilities to the _OSC regardless of the query
+      flag"
+    - ACPI: properties: Consistently return -ENOENT if there are no more
+      references
+    - coredump: Also dump first pages of non-executable ELF libraries
+    - ext4: fix ext4_fc_stats trace point
+    - ext4: fix fs corruption when tring to remove a non-empty directory with IO
+      error
+    - ext4: make mb_optimize_scan option work with set/unset mount cmd
+    - ext4: make mb_optimize_scan performance mount option work with extents
+    - samples/landlock: Fix path_list memory leak
+    - landlock: Use square brackets around "landlock-ruleset"
+    - mailbox: tegra-hsp: Flush whole channel
+    - btrfs: zoned: put block group after final usage
+    - block: fix rq-qos breakage from skipping rq_qos_done_bio()
+    - block: limit request dispatch loop duration
+    - block: don't merge across cgroup boundaries if blkcg is enabled
+    - drm/edid: check basic audio support on CEA extension block
+    - fbdev: Hot-unplug firmware fb devices on forced removal
+    - video: fbdev: sm712fb: Fix crash in smtcfb_read()
+    - video: fbdev: atari: Atari 2 bpp (STe) palette bugfix
+    - rfkill: make new event layout opt-in
+    - ARM: dts: at91: sama7g5: Remove unused properties in i2c nodes
+    - ARM: dts: at91: sama5d2: Fix PMERRLOC resource size
+    - ARM: dts: exynos: fix UART3 pins configuration in Exynos5250
+    - ARM: dts: exynos: add missing HDMI supplies on SMDK5250
+    - ARM: dts: exynos: add missing HDMI supplies on SMDK5420
+    - mgag200 fix memmapsl configuration in GCTL6 register
+    - carl9170: fix missing bit-wise or operator for tx_params
+    - pstore: Don't use semaphores in always-atomic-context code
+    - thermal: int340x: Increase bitmap size
+    - lib/raid6/test: fix multiple definition linking error
+    - exec: Force single empty string when argv is empty
+    - crypto: rsa-pkcs1pad - only allow with rsa
+    - crypto: rsa-pkcs1pad - correctly get hash from source scatterlist
+    - crypto: rsa-pkcs1pad - restore signature length check
+    - crypto: rsa-pkcs1pad - fix buffer overread in pkcs1pad_verify_complete()
+    - bcache: fixup multiple threads crash
+    - PM: domains: Fix sleep-in-atomic bug caused by genpd_debug_remove()
+    - DEC: Limit PMAX memory probing to R3k systems
+    - media: gpio-ir-tx: fix transmit with long spaces on Orange Pi PC
+    - media: omap3isp: Use struct_group() for memcpy() region
+    - media: venus: vdec: fixed possible memory leak issue
+    - media: venus: hfi_cmds: List HDR10 property as unsupported for v1 and v3
+    - media: venus: venc: Fix h264 8x8 transform control
+    - media: davinci: vpif: fix unbalanced runtime PM get
+    - media: davinci: vpif: fix unbalanced runtime PM enable
+    - media: davinci: vpif: fix use-after-free on driver unbind
+    - mips: Always permit to build u-boot images
+    - btrfs: zoned: mark relocation as writing
+    - btrfs: extend locking to all space_info members accesses
+    - btrfs: verify the tranisd of the to-be-written dirty extent buffer
+    - xtensa: define update_mmu_tlb function
+    - xtensa: fix stop_machine_cpuslocked call in patch_text
+    - xtensa: fix xtensa_wsr always writing 0
+    - KVM: s390x: fix SCK locking
+    - drm/syncobj: flatten dma_fence_chains on transfer
+    - drm/nouveau/backlight: Fix LVDS backlight detection on some laptops
+    - drm/nouveau/backlight: Just set all backlight types as RAW
+    - drm/fb-helper: Mark screen buffers in system memory with FBINFO_VIRTFB
+    - brcmfmac: firmware: Allocate space for default boardrev in nvram
+    - brcmfmac: pcie: Release firmwares in the brcmf_pcie_setup error path
+    - brcmfmac: pcie: Declare missing firmware files in pcie.c
+    - brcmfmac: pcie: Replace brcmf_pcie_copy_mem_todev with memcpy_toio
+    - brcmfmac: pcie: Fix crashes due to early IRQs
+    - drm/i915/opregion: check port number bounds for SWSCI display power state
+    - drm/i915/gem: add missing boundary check in vm_access
+    - PCI: imx6: Allow to probe when dw_pcie_wait_for_link() fails
+    - PCI: pciehp: Clear cmd_busy bit in polling mode
+    - PCI: xgene: Revert "PCI: xgene: Use inbound resources for setup"
+    - PCI: xgene: Revert "PCI: xgene: Fix IB window setup"
+    - regulator: qcom_smd: fix for_each_child.cocci warnings
+    - selinux: access superblock_security_struct in LSM blob way
+    - selinux: check return value of sel_make_avc_files
+    - crypto: ccp - Ensure psp_ret is always init'd in
+      __sev_platform_init_locked()
+    - crypto: qat - fix a signedness bug in get_service_enabled()
+    - hwrng: cavium - HW_RANDOM_CAVIUM should depend on ARCH_THUNDER
+    - crypto: sun8i-ss - really disable hash on A80
+    - crypto: kdf - Select hmac in addition to sha256
+    - crypto: qat - fix access to PFVF interrupt registers for GEN4
+    - crypto: authenc - Fix sleep in atomic context in decrypt_tail
+    - crypto: octeontx2 - select CONFIG_NET_DEVLINK
+    - crypto: mxs-dcp - Fix scatterlist processing
+    - selinux: Fix selinux_sb_mnt_opts_compat()
+    - thermal: int340x: Check for NULL after calling kmemdup()
+    - crypto: octeontx2 - remove CONFIG_DM_CRYPT check
+    - spi: tegra114: Add missing IRQ check in tegra_spi_probe
+    - spi: tegra210-quad: Fix missin IRQ check in tegra_qspi_probe
+    - perf: MARVELL_CN10K_TAD_PMU should depend on ARCH_THUNDER
+    - selftests/sgx: Fix NULL-pointer-dereference upon early test failure
+    - selftests/sgx: Do not attempt enclave build without valid enclave
+    - selftests/sgx: Ensure enclave data available during debug print
+    - stack: Constrain and fix stack offset randomization with Clang builds
+    - arm64/mm: avoid fixmap race condition when create pud mapping
+    - security: add sctp_assoc_established hook
+    - blk-cgroup: set blkg iostat after percpu stat aggregation
+    - selftests/x86: Add validity check and allow field splitting
+    - selftests/sgx: Treat CC as one argument
+    - crypto: rockchip - ECB does not need IV
+    - block: update io_ticks when io hang
+    - audit: log AUDIT_TIME_* records only from rules
+    - EVM: fix the evm= __setup handler return value
+    - crypto: ccree - don't attempt 0 len DMA mappings
+    - crypto: hisilicon/sec - fix the aead software fallback for engine
+    - spi: pxa2xx-pci: Balance reference count for PCI DMA device
+    - hwmon: (pmbus) Add mutex to regulator ops
+    - hwmon: (sch56xx-common) Replace WDOG_ACTIVE with WDOG_HW_RUNNING
+    - nvme: cleanup __nvme_check_ids
+    - nvme: fix the check for duplicate unique identifiers
+    - block: don't delete queue kobject before its children
+    - PM: hibernate: fix __setup handler error handling
+    - PM: suspend: fix return value of __setup handler
+    - spi: spi-zynqmp-gqspi: Handle error for dma_set_mask
+    - hwrng: atmel - disable trng on failure path
+    - crypto: sun8i-ss - call finalize with bh disabled
+    - crypto: sun8i-ce - call finalize with bh disabled
+    - crypto: amlogic - call finalize with bh disabled
+    - crypto: gemini - call finalize with bh disabled
+    - crypto: vmx - add missing dependencies
+    - clocksource/drivers/timer-ti-dm: Fix regression from errata i940 fix
+    - clocksource/drivers/exynos_mct: Handle DTS with higher number of interrupts
+    - clocksource/drivers/timer-microchip-pit64b: Use notrace
+    - clocksource/drivers/timer-of: Check return value of of_iomap in
+      timer_of_base_init()
+    - arm64: prevent instrumentation of bp hardening callbacks
+    - perf/arm-cmn: Hide XP PUB events for CMN-600
+    - perf/arm-cmn: Update watchpoint format
+    - KEYS: trusted: Fix trusted key backends when building as module
+    - KEYS: trusted: Avoid calling null function trusted_key_exit
+    - ACPI: APEI: fix return value of __setup handlers
+    - crypto: ccp - ccp_dmaengine_unregister release dma channels
+    - crypto: ccree - Fix use after free in cc_cipher_exit()
+    - crypto: qat - fix initialization of pfvf cap_msg structures
+    - crypto: qat - fix initialization of pfvf rts_map_msg structures
+    - hwrng: nomadik - Change clk_disable to clk_disable_unprepare
+    - hwmon: (pmbus) Add Vin unit off handling
+    - clocksource: acpi_pm: fix return value of __setup handler
+    - io_uring: don't check unrelated req->open.how in accept request
+    - io_uring: terminate manual loop iterator loop correctly for non-vecs
+    - watch_queue: Fix NULL dereference in error cleanup
+    - watch_queue: Actually free the watch
+    - f2fs: fix to enable ATGC correctly via gc_idle sysfs interface
+    - sched/debug: Remove mpol_get/put and task_lock/unlock from sched_show_numa
+    - sched/core: Export pelt_thermal_tp
+    - sched/sugov: Ignore 'busy' filter when rq is capped by uclamp_max
+    - sched/uclamp: Fix iowait boost escaping uclamp restriction
+    - rseq: Remove broken uapi field layout on 32-bit little endian
+    - perf/core: Fix address filter parser for multiple filters
+    - perf/x86/intel/pt: Fix address filter config for 32-bit kernel
+    - sched/fair: Improve consistency of allowed NUMA balance calculations
+    - f2fs: fix missing free nid in f2fs_handle_failed_inode
+    - ext4: fix remount with 'abort' option
+    - nfsd: more robust allocation failure handling in nfsd_file_cache_init
+    - sched/cpuacct: Fix charge percpu cpuusage
+    - sched/rt: Plug rt_mutex_setprio() vs push_rt_task() race
+    - f2fs: fix to avoid potential deadlock
+    - btrfs: fix unexpected error path when reflinking an inline extent
+    - iomap: Fix iomap_invalidatepage tracepoint
+    - fs: erofs: add sanity check for kobject in erofs_unregister_sysfs
+    - f2fs: fix compressed file start atomic write may cause data corruption
+    - cifs: use a different reconnect helper for non-cifsd threads
+    - selftests, x86: fix how check_cc.sh is being invoked
+    - drivers/base/memory: add memory block to memory group after registration
+      succeeded
+    - kunit: make kunit_test_timeout compatible with comment
+    - pinctrl: samsung: Remove EINT handler for Exynos850 ALIVE and CMGP gpios
+    - media: staging: media: zoran: fix usage of vb2_dma_contig_set_max_seg_size
+    - media: camss: csid-170: fix non-10bit formats
+    - media: camss: csid-170: don't enable unused irqs
+    - media: camss: csid-170: set the right HALT_CMD when disabled
+    - media: camss: vfe-170: fix "VFE halt timeout" error
+    - media: staging: media: imx: imx7-mipi-csis: Make subdev name unique
+    - media: v4l2-mem2mem: Apply DST_QUEUE_OFF_BASE on MMAP buffers across ioctls
+    - media: mtk-vcodec: potential dereference of null pointer
+    - media: imx: imx8mq-mipi-csi2: remove wrong irq config write operation
+    - media: imx: imx8mq-mipi_csi2: fix system resume
+    - media: bttv: fix WARNING regression on tunerless devices
+    - media: atmel: atmel-sama7g5-isc: fix ispck leftover
+    - ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively
+    - ASoC: codecs: Check for error pointer after calling devm_regmap_init_mmio
+    - ASoC: xilinx: xlnx_formatter_pcm: Handle sysclk setting
+    - ASoC: simple-card-utils: Set sysclk on all components
+    - memory: tegra20-emc: Correct memory device mask
+    - media: coda: Fix missing put_device() call in coda_get_vdoa_data
+    - media: meson: vdec: potential dereference of null pointer
+    - media: hantro: Fix overfill bottom register field name
+    - media: ov6650: Fix set format try processing path
+    - media: v4l: Avoid unaligned access warnings when printing 4cc modifiers
+    - media: ov5648: Don't pack controls struct
+    - media: ov2740: identify module after subdev initialisation
+    - media: aspeed: Correct value for h-total-pixels
+    - video: fbdev: matroxfb: set maxvram of vbG200eW to the same as vbG200 to
+      avoid black screen
+    - video: fbdev: controlfb: Fix COMPILE_TEST build
+    - video: fbdev: smscufx: Fix null-ptr-deref in ufx_usb_probe()
+    - video: fbdev: atmel_lcdfb: fix an error code in atmel_lcdfb_probe()
+    - video: fbdev: fbcvt.c: fix printing in fb_cvt_print_name()
+    - ARM: dts: Fix OpenBMC flash layout label addresses
+    - ASoC: max98927: add missing header file
+    - arm64: dts: qcom: sc7280: Fix gmu unit address
+    - firmware: qcom: scm: Remove reassignment to desc following initializer
+    - ARM: dts: qcom: ipq4019: fix sleep clock
+    - soc: qcom: rpmpd: Check for null return of devm_kcalloc
+    - soc: qcom: ocmem: Fix missing put_device() call in of_get_ocmem
+    - soc: qcom: aoss: Fix missing put_device call in qmp_get
+    - soc: qcom: aoss: remove spurious IRQF_ONESHOT flags
+    - arm64: dts: qcom: sdm845: fix microphone bias properties and values
+    - arm64: dts: qcom: sm8250: fix PCIe bindings to follow schema
+    - arm64: dts: qcom: msm8916-j5: Fix typo
+    - arm64: dts: broadcom: bcm4908: use proper TWD binding
+    - arm64: dts: qcom: sm8150: Correct TCS configuration for apps rsc
+    - arm64: dts: qcom: sm8350: Correct TCS configuration for apps rsc
+    - arm64: dts: qcom: sm8450: Update cpuidle states parameters
+    - arm64: dts: qcom: msm8994: Provide missing "xo_board" and "sleep_clk" to GCC
+    - arm64: dts: qcom: ipq6018: fix usb reference period
+    - firmware: ti_sci: Fix compilation failure when CONFIG_TI_SCI_PROTOCOL is not
+      defined
+    - soc: ti: wkup_m3_ipc: Fix IRQ check in wkup_m3_ipc_probe
+    - cpuidle: qcom-spm: Check if any CPU is managed by SPM
+    - ARM: dts: sun8i: v3s: Move the csi1 block to follow address order
+    - ARM: dts: stm32: fix AV96 board SAI2 pin muxing on stm32mp15
+    - vsprintf: Fix potential unaligned access
+    - ARM: dts: qcom: sdx55: Fix the address used for PCIe EP local addr space
+    - ARM: dts: imx: Add missing LVDS decoder on M53Menlo
+    - media: mexon-ge2d: fixup frames size in registers
+    - media: video/hdmi: handle short reads of hdmi info frame.
+    - media: ti-vpe: cal: Fix a NULL pointer dereference in
+      cal_ctx_v4l2_init_formats()
+    - media: em28xx: initialize refcount before kref_get
+    - media: uapi: Init VP9 stateless decode params
+    - media: usb: go7007: s2250-board: fix leak in probe()
+    - media: cedrus: H265: Fix neighbour info buffer size
+    - media: cedrus: h264: Fix neighbour info buffer size
+    - arm64: dts: ti: k3-j721s2-mcu-wakeup: Fix the interrupt-parent for
+      wkup_gpioX instances
+    - ASoC: codecs: rx-macro: fix accessing compander for aux
+    - ASoC: codecs: rx-macro: fix accessing array out of bounds for enum type
+    - ASoC: codecs: va-macro: fix accessing array out of bounds for enum type
+    - ASoC: codecs: wc938x: fix accessing array out of bounds for enum type
+    - ASoC: codecs: wcd938x: fix kcontrol max values
+    - ASoC: codecs: wcd934x: fix kcontrol max values
+    - ASoC: codecs: wcd934x: fix return value of wcd934x_rx_hph_mode_put
+    - media: v4l2-core: Initialize h264 scaling matrix
+    - media: hantro: sunxi: Fix VP9 steps
+    - media: ov5640: Fix set format, v4l2_mbus_pixelcode not updated
+    - selftests: vm: remove dependecy from internal kernel macros
+    - selftests/lkdtm: Add UBSAN config
+    - vsprintf: Fix %pK with kptr_restrict == 0
+    - uaccess: fix nios2 and microblaze get_user_8()
+    - ASoC: rt5663: check the return value of devm_kzalloc() in rt5663_parse_dp()
+    - ASoC: acp: check the return value of devm_kzalloc() in
+      acp_legacy_dai_links_create()
+    - soc: mediatek: pm-domains: Add wakeup capacity support in power domain
+    - mmc: sdhci_am654: Fix the driver data of AM64 SoC
+    - ASoC: ti: davinci-i2s: Add check for clk_enable()
+    - ALSA: spi: Add check for clk_enable()
+    - arm64: dts: ns2: Fix spi-cpol and spi-cpha property
+    - arm64: dts: broadcom: Fix sata nodename
+    - printk: fix return value of printk.devkmsg __setup handler
+    - ASoC: mxs-saif: Handle errors for clk_enable
+    - ASoC: atmel_ssc_dai: Handle errors for clk_enable
+    - ASoC: dwc-i2s: Handle errors for clk_enable
+    - ASoC: soc-compress: prevent the potentially use of null pointer
+    - media: i2c: Fix pixel array positions in ov8865
+    - memory: emif: Add check for setup_interrupts
+    - memory: emif: check the pointer temp in get_device_details()
+    - ALSA: firewire-lib: fix uninitialized flag for AV/C deferred transaction
+    - arm64: dts: rockchip: Fix SDIO regulator supply properties on rk3399-firefly
+    - m68k: coldfire/device.c: only build for MCF_EDMA when h/w macros are defined
+    - media: stk1160: If start stream fails, return buffers with
+      VB2_BUF_STATE_QUEUED
+    - media: vidtv: Check for null return of vzalloc
+    - ASoC: cs35l41: Fix GPIO2 configuration
+    - ASoC: cs35l41: Fix max number of TX channels
+    - ASoC: atmel: Add missing of_node_put() in at91sam9g20ek_audio_probe
+    - ASoC: wm8350: Handle error for wm8350_register_irq
+    - ASoC: fsi: Add check for clk_enable
+    - video: fbdev: omapfb: Add missing of_node_put() in dvic_probe_of
+    - media: saa7134: fix incorrect use to determine if list is empty
+    - ivtv: fix incorrect device_caps for ivtvfb
+    - ASoC: atmel: Fix error handling in snd_proto_probe
+    - ASoC: rockchip: i2s: Fix missing clk_disable_unprepare() in
+      rockchip_i2s_probe
+    - ASoC: SOF: Add missing of_node_put() in imx8m_probe
+    - ASoC: mediatek: mt8192-mt6359: Fix error handling in mt8192_mt6359_dev_probe
+    - ASoC: rk817: Fix missing clk_disable_unprepare() in rk817_platform_probe
+    - ASoC: dmaengine: do not use a NULL prepare_slave_config() callback
+    - ASoC: mxs: Fix error handling in mxs_sgtl5000_probe
+    - ASoC: fsl_spdif: Disable TX clock when stop
+    - ASoC: imx-es8328: Fix error return code in imx_es8328_probe()
+    - ASoC: SOF: Intel: enable DMI L1 for playback streams
+    - ASoC: msm8916-wcd-digital: Fix missing clk_disable_unprepare() in
+      msm8916_wcd_digital_probe
+    - mmc: davinci_mmc: Handle error for clk_enable
+    - rtla/osnoise: Fix osnoise hist stop tracing message
+    - ASoC: rockchip: Fix PM usage reference of rockchip_i2s_tdm_resume
+    - ASoC: atmel: Fix error handling in sam9x5_wm8731_driver_probe
+    - ASoC: msm8916-wcd-analog: Fix error handling in pm8916_wcd_analog_spmi_probe
+    - ASoC: mediatek: mt8195: Fix error handling in
+      mt8195_mt6359_rt1019_rt5682_dev_probe
+    - ASoC: codecs: wcd934x: Add missing of_node_put() in wcd934x_codec_parse_data
+    - ASoC: amd: Fix reference to PCM buffer address
+    - ARM: configs: multi_v5_defconfig: re-enable CONFIG_V4L_PLATFORM_DRIVERS
+    - ARM: configs: multi_v5_defconfig: re-enable DRM_PANEL and FB_xxx
+    - drm/bridge: sn65dsi83: Fix an error handling path in sn65dsi83_probe()
+    - drm/meson: osd_afbcd: Add an exit callback to struct meson_afbcd_ops
+    - drm/meson: Fix error handling when afbcd.ops->init fails
+    - drm/bridge: Fix free wrong object in sii8620_init_rcp_input_dev
+    - drm/bridge: Add missing pm_runtime_disable() in __dw_mipi_dsi_probe
+    - drm/bridge: nwl-dsi: Fix PM disable depth imbalance in nwl_dsi_probe
+    - drm: bridge: adv7511: Fix ADV7535 HPD enablement
+    - ath11k: add missing of_node_put() to avoid leak
+    - ath10k: fix memory overwrite of the WoWLAN wakeup packet pattern
+    - drm/v3d/v3d_drv: Check for error num after setting mask
+    - Bluetooth: hci_sync: unlock on error in hci_inquiry_result_with_rssi_evt()
+    - ath11k: free peer for station when disconnect from AP for QCA6390/WCN6855
+    - drm/panfrost: Check for error num after setting mask
+    - bpftool: Fix error check when calling hashmap__new()
+    - libbpf: Fix possible NULL pointer dereference when destroying skeleton
+    - bpftool: Only set obj->skeleton on complete success
+    - ath11k: fix error code in ath11k_qmi_assign_target_mem_chunk()
+    - udmabuf: validate ubuf->pagecount
+    - bpf: Fix UAF due to race between btf_try_get_module and load_module
+    - drm/selftests/test-drm_dp_mst_helper: Fix memory leak in
+      sideband_msg_req_encode_decode
+    - drm/locking: fix drm_modeset_acquire_ctx kernel-doc
+    - selftests: bpf: Fix bind on used port
+    - Bluetooth: btintel: Fix WBS setting for Intel legacy ROM products
+    - Bluetooth: hci_serdev: call init_rwsem() before p->open()
+    - Bluetooth: mt7921s: fix firmware coredump retrieve
+    - Bluetooth: mt7921s: fix bus hang with wrong privilege
+    - Bluetooth: btmtksdio: refactor btmtksdio_runtime_[suspend|resume]()
+    - Bluetooth: mt7921s: fix btmtksdio_[drv|fw]_pmctrl()
+    - Bluetooth: btmtksdio: mask out interrupt status
+    - mtd: onenand: Check for error irq
+    - mtd: rawnand: gpmi: fix controller timings setting
+    - selftests, xsk: Fix rx_full stats test
+    - drm/edid: Don't clear formats if using deep color
+    - drm/edid: Split deep color modes between RGB and YUV444
+    - ionic: fix type complaint in ionic_dev_cmd_clean()
+    - ionic: start watchdog after all is setup
+    - ionic: Don't send reset commands if FW isn't running
+    - ionic: fix up printing of timeout error
+    - ionic: Correctly print AQ errors if completions aren't received
+    - net: dsa: Move VLAN filtering syncing out of dsa_switch_bridge_leave
+    - net: dsa: Avoid cross-chip syncing of VLAN filtering
+    - Bluetooth: hci_event: Fix HCI_EV_VENDOR max_len
+    - drm/nouveau/acr: Fix undefined behavior in nvkm_acr_hsfw_load_bl()
+    - drm/amd/display: Call dc_stream_release for remove link enc assignment
+    - drm/amd/display: Fix a NULL pointer dereference in
+      amdgpu_dm_connector_add_common_modes()
+    - drm/amd/pm: return -ENOTSUPP if there is no get_dpm_ultimate_freq function
+    - net: phy: at803x: move page selection fix to config_init
+    - selftests/bpf/test_xdp_redirect_multi: use temp netns for testing
+    - ath9k_htc: fix uninit value bugs
+    - ath11k: set WMI_PEER_40MHZ while peer assoc for 6 GHz
+    - RDMA/core: Set MR type in ib_reg_user_mr
+    - KVM: PPC: Fix vmx/vsx mixup in mmio emulation
+    - selftests/net: timestamping: Fix bind_phc check
+    - rtw88: check for validity before using a pointer
+    - rtw88: fix idle mode flow for hw scan
+    - rtw88: fix memory overrun and memory leak during hw_scan
+    - drm/bridge: lt9611: Fix an error handling path in lt9611_probe()
+    - i40e: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
+    - i40e: respect metadata on XSK Rx to skb
+    - ice: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
+    - ice: respect metadata on XSK Rx to skb
+    - igc: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
+    - ixgbe: pass bi->xdp to ixgbe_construct_skb_zc() directly
+    - ixgbe: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
+    - ixgbe: respect metadata on XSK Rx to skb
+    - power: reset: gemini-poweroff: Fix IRQ check in gemini_poweroff_probe
+    - ray_cs: Check ioremap return value
+    - powerpc: dts: t1040rdb: fix ports names for Seville Ethernet switch
+    - KVM: PPC: Book3S HV: Check return value of kvmppc_radix_init
+    - powerpc/perf: Don't use perf_hw_context for trace IMC PMU
+    - mt76: connac: fix sta_rec_wtbl tag len
+    - mt76: mt7915: use proper aid value in mt7915_mcu_wtbl_generic_tlv in sta
+      mode
+    - mt76: mt7915: use proper aid value in mt7915_mcu_sta_basic_tlv
+    - mt76: mt76_connac: fix MCU_CE_CMD_SET_ROC definition error
+    - mt76: mt7921: set EDCA parameters with the MCU CE command
+    - mt76: mt7921: do not always disable fw runtime-pm
+    - mt76: mt7921: fix a leftover race in runtime-pm
+    - mt76: mt7615: fix a leftover race in runtime-pm
+    - mt76: mt7915: fix ht mcs in mt7915_mac_add_txs_skb()
+    - mt76: mt7921: fix ht mcs in mt7921_mac_add_txs_skb()
+    - mt76: mt7921s: fix mt7921s_mcu_[fw|drv]_pmctrl
+    - mt76: mt7921e: fix possible probe failure after reboot
+    - mt76: mt7603: check sta_rates pointer in mt7603_sta_rate_tbl_update
+    - mt76: mt7615: check sta_rates pointer in mt7615_sta_rate_tbl_update
+    - mt76: mt7915: fix possible memory leak in mt7915_mcu_add_sta
+    - mt76: mt7921s: fix a possible memory leak in mt7921_load_patch
+    - mt76: mt7915: fix mcs_map in mt7915_mcu_set_sta_he_mcs()
+    - mt76: mt7915: fix the nss setting in bitrates
+    - ptp: unregister virtual clocks when unregistering physical clock.
+    - net: dsa: mv88e6xxx: Enable port policy support on 6097
+    - bpf: Fix a btf decl_tag bug when tagging a function
+    - mac80211: limit bandwidth in HE capabilities
+    - scripts/dtc: Call pkg-config POSIXly correct
+    - livepatch: Fix build failure on 32 bits processors
+    - net: asix: add proper error handling of usb read errors
+    - i2c: bcm2835: Fix the error handling in 'bcm2835_i2c_probe()'
+    - mtd: mchp23k256: Add SPI ID table
+    - mtd: mchp48l640: Add SPI ID table
+    - selftests/bpf: Extract syscall wrapper
+    - selftests/bpf: Use "__se_" prefix on architectures without syscall wrapper
+    - igc: avoid kernel warning when changing RX ring parameters
+    - igb: refactor XDP registration
+    - drm/amdgpu: Don't offset by 2 in FRU EEPROM
+    - PCI: aardvark: Fix reading MSI interrupt number
+    - PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on emulated bridge
+    - RDMA/rxe: Check the last packet by RXE_END_MASK
+    - libbpf: Fix signedness bug in btf_dump_array_data()
+    - libbpf: Fix riscv register names
+    - cxl/core: Fix cxl_probe_component_regs() error message
+    - tools/testing/cxl: Fix root port to host bridge assignment
+    - cxl/regs: Fix size of CXL Capability Header Register
+    - Netvsc: Call hv_unmap_memory() in the netvsc_device_remove()
+    - net:enetc: allocate CBD ring data memory using DMA coherent methods
+    - libbpf: Fix compilation warning due to mismatched printf format
+    - rtw88: fix use after free in rtw_hw_scan_update_probe_req()
+    - drm/bridge: dw-hdmi: use safe format when first in bridge chain
+    - power: supply: ab8500: Swap max and overvoltage
+    - libbpf: Fix libbpf.map inheritance chain for LIBBPF_0.7.0
+    - libbpf: Use dynamically allocated buffer when receiving netlink messages
+    - power: supply: ab8500: Fix memory leak in ab8500_fg_sysfs_init
+    - HID: i2c-hid: fix GET/SET_REPORT for unnumbered reports
+    - iommu/ipmmu-vmsa: Check for error num after setting mask
+    - drm/bridge: anx7625: Fix overflow issue on reading EDID
+    - ath11k: fix uninitialized rate_idx in ath11k_dp_tx_update_txcompl()
+    - i2c: pasemi: Drop I2C classes from platform driver variant
+    - bpftool: Fix the error when lookup in no-btf maps
+    - drm/amd/pm: enable pm sysfs write for one VF mode
+    - drm/amd/display: Add affected crtcs to atomic state for dsc mst unplug
+    - bpftool: Fix pretty print dump for maps without BTF loaded
+    - libbpf: Fix memleak in libbpf_netlink_recv()
+    - IB/cma: Allow XRC INI QPs to set their local ACK timeout
+    - cxl/core/port: Rename bus.c to port.c
+    - cxl/port: Hold port reference until decoder release
+    - dax: make sure inodes are flushed before destroy cache
+    - selftests: mptcp: add csum mib check for mptcp_connect
+    - iwlwifi: mvm: Don't call iwl_mvm_sta_from_mac80211() with NULL sta
+    - iwlwifi: mvm: don't iterate unadded vifs when handling FW SMPS req
+    - iwlwifi: mvm: align locking in D3 test debugfs
+    - iwlwifi: yoyo: remove DBGI_SRAM address reset writing
+    - iwlwifi: yoyo: Avoid using dram data if allocation failed
+    - iwlwifi: mvm: fix off by one in iwl_mvm_stat_iterator_all_macs()
+    - iwlwifi: Fix -EIO error code that is never returned
+    - iwlwifi: mvm: Fix an error code in iwl_mvm_up()
+    - mtd: rawnand: pl353: Set the nand chip node as the flash node
+    - drm/msm/dp: do not initialize phy until plugin interrupt received
+    - drm/msm/dp: populate connector of struct dp_panel
+    - drm/msm/dp: stop link training after link training 2 failed
+    - drm/msm/dp: always add fail-safe mode into connector mode list
+    - drm/msm/dsi: Use "ref" fw clock instead of global name for VCO parent
+    - drm/msm/dsi/phy: fix 7nm v4.0 settings for C-PHY mode
+    - drm/msm/dpu: add DSPP blocks teardown
+    - drm/msm/dpu: fix dp audio condition
+    - drm/msm/dpu: remove msm_dp cached in dpu_encoder_virt
+    - drm/msm/dp: fix panel bridge attachment
+    - i40e: remove dead stores on XSK hotpath
+    - ath11k: Invalidate cached reo ring entry before accessing it
+    - mips: Enable KCSAN
+    - dm crypt: fix get_key_size compiler warning if !CONFIG_KEYS
+    - vfio/pci: fix memory leak during D3hot to D0 transition
+    - vfio/pci: wake-up devices around reset functions
+    - scsi: fnic: Fix a tracing statement
+    - scsi: pm8001: Fix command initialization in pm80XX_send_read_log()
+    - scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req()
+    - scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config()
+    - scsi: pm8001: Fix le32 values handling in
+      pm80xx_set_sas_protocol_timer_config()
+    - scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update()
+    - scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req()
+    - scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req()
+    - scsi: pm8001: Fix NCQ NON DATA command task initialization
+    - scsi: pm8001: Fix NCQ NON DATA command completion handling
+    - scsi: pm8001: Fix abort all task initialization
+    - mt76: do not always copy ethhdr in reverse_frag0_hdr_trans
+    - mt76: fix endianness errors in reverse_frag0_hdr_trans
+    - mt76: mt7921s: fix missing fc type/sub-type for 802.11 pkts
+    - net: dsa: realtek-smi: fix kdoc warnings
+    - net: dsa: realtek-smi: move to subdirectory
+    - RDMA/mlx5: Fix the flow of a miss in the allocation of a cache ODP MR
+    - drm/amd/display: Remove vupdate_int_entry definition
+    - TOMOYO: fix __setup handlers return values
+    - power: supply: sbs-charger: Don't cancel work that is not initialized
+    - mt76: mt7915: enlarge wcid size to 544
+    - mt76: mt7915: fix the muru tlv issue
+    - drm/dp: Fix OOB read when handling Post Cursor2 register
+    - ext2: correct max file size computing
+    - drm/tegra: Fix reference leak in tegra_dsi_ganged_probe
+    - power: supply: bq24190_charger: Fix bq24190_vbus_is_enabled() wrong false
+      return
+    - scsi: hisi_sas: Change permission of parameter prot_mask
+    - drm/bridge: cdns-dsi: Make sure to to create proper aliases for dt
+    - bpf, arm64: Call build_prologue() first in first JIT pass
+    - bpf, arm64: Feed byte-offset into bpf line info
+    - xsk: Fix race at socket teardown
+    - RDMA/irdma: Fix netdev notifications for vlan's
+    - RDMA/irdma: Fix Passthrough mode in VM
+    - RDMA/irdma: Remove incorrect masking of PD
+    - libbpf: Fix BPF_MAP_TYPE_PERF_EVENT_ARRAY auto-pinning
+    - gpu: host1x: Fix an error handling path in 'host1x_probe()'
+    - gpu: host1x: Fix a memory leak in 'host1x_remove()'
+    - libbpf: Skip forward declaration when counting duplicated type names
+    - powerpc/mm/numa: skip NUMA_NO_NODE onlining in parse_numa_properties()
+    - powerpc/Makefile: Don't pass -mcpu=powerpc64 when building 32-bit
+    - KVM: x86: Fix emulation in writing cr8
+    - KVM: x86/emulator: Defer not-present segment check in
+      __load_segment_descriptor()
+    - KVM: SVM: Exit to userspace on ENOMEM/EFAULT GHCB errors
+    - hv_balloon: rate-limit "Unhandled message" warning
+    - KVM: arm64: Enable Cortex-A510 erratum 2077057 by default
+    - i2c: xiic: Make bus names unique
+    - net: phy: micrel: Fix concurrent register access
+    - Bluetooth: hci_sync: fix undefined return of hci_disconnect_all_sync()
+    - Bluetooth: Fix skb allocation in mgmt_remote_name() &
+      mgmt_device_connected()
+    - power: supply: wm8350-power: Handle error for wm8350_register_irq
+    - power: supply: wm8350-power: Add missing free in free_charger_irq
+    - IB/hfi1: Allow larger MTU without AIP
+    - RDMA/core: Fix ib_qp_usecnt_dec() called when error
+    - PCI: Reduce warnings on possible RW1C corruption
+    - net: axienet: fix RX ring refill allocation failure handling
+    - drm/msm/a6xx: Fix missing ARRAY_SIZE() check
+    - mips: DEC: honor CONFIG_MIPS_FP_SUPPORT=n
+    - MIPS: Sanitise Cavium switch cases in TLB handler synthesizers
+    - powerpc/sysdev: fix incorrect use to determine if list is empty
+    - powerpc/64s: Don't use DSISR for SLB faults
+    - mfd: mc13xxx: Add check for mc13xxx_irq_request
+    - libbpf: Unmap rings when umem deleted
+    - selftests/bpf: Make test_lwt_ip_encap more stable and faster
+    - platform/x86: huawei-wmi: check the return value of device_create_file()
+    - scsi: mpt3sas: Fix incorrect 4GB boundary check
+    - powerpc: 8xx: fix a return value error in mpc8xx_pic_init
+    - xtensa: add missing XCHAL_HAVE_WINDOWED check
+    - iwlwifi: pcie: fix SW error MSI-X mapping
+    - vxcan: enable local echo for sent CAN frames
+    - ath10k: Fix error handling in ath10k_setup_msa_resources
+    - mips: cdmm: Fix refcount leak in mips_cdmm_phys_base
+    - MIPS: RB532: fix return value of __setup handler
+    - MIPS: pgalloc: fix memory leak caused by pgd_free()
+    - mtd: rawnand: atmel: fix refcount issue in atmel_nand_controller_init
+    - power: ab8500_chargalg: Use CLOCK_MONOTONIC
+    - RDMA/irdma: Prevent some integer underflows
+    - Revert "RDMA/core: Fix ib_qp_usecnt_dec() called when error"
+    - RDMA/mlx5: Fix memory leak in error flow for subscribe event routine
+    - bpf, sockmap: Fix memleak in sk_psock_queue_msg
+    - bpf, sockmap: Fix memleak in tcp_bpf_sendmsg while sk msg is full
+    - bpf, sockmap: Fix more uncharged while msg has more_data
+    - bpf, sockmap: Fix double uncharge the mem of sk_msg
+    - samples/bpf, xdpsock: Fix race when running for fix duration of time
+    - USB: storage: ums-realtek: fix error code in rts51x_read_mem()
+    - drm/amd/display: Fix double free during GPU reset on DC streams
+    - RDMA/rxe: Change variable and function argument to proper type
+    - RDMA/rxe: Fix ref error in rxe_av.c
+    - powerpc/xive: fix return value of __setup handler
+    - powerpc/time: Fix KVM host re-arming a timer beyond decrementer range
+    - drm/i915/display: Fix HPD short pulse handling for eDP
+    - drm/i915/display: Do not re-enable PSR after it was marked as not reliable
+    - netfilter: flowtable: Fix QinQ and pppoe support for inet table
+    - mt76: mt7921: fix mt7921_queues_acq implementation
+    - can: isotp: return -EADDRNOTAVAIL when reading from unbound socket
+    - can: isotp: support MSG_TRUNC flag when reading from socket
+    - bareudp: use ipv6_mod_enabled to check if IPv6 enabled
+    - PCI: imx6: Invoke the PHY exit function after PHY power off
+    - PCI: imx6: Assert i.MX8MM CLKREQ# even if no device present
+    - ibmvnic: fix race between xmit and reset
+    - af_unix: Fix some data-races around unix_sk(sk)->oob_skb.
+    - selftests/bpf: Fix error reporting from sock_fields programs
+    - Bluetooth: hci_uart: add missing NULL check in h5_enqueue
+    - Bluetooth: call hci_le_conn_failed with hdev lock in hci_le_conn_failed
+    - Bluetooth: btmtksdio: Fix kernel oops in btmtksdio_interrupt
+    - RDMA/nldev: Prevent underflow in nldev_stat_set_counter_dynamic_doit()
+    - ipv4: Fix route lookups when handling ICMP redirects and PMTU updates
+    - mptcp: Fix crash due to tcp_tsorted_anchor was initialized before release
+      skb
+    - af_netlink: Fix shift out of bounds in group mask calculation
+    - i2c: meson: Fix wrong speed use from probe
+    - netfilter: conntrack: Add and use nf_ct_set_auto_assign_helper_warned()
+    - i2c: mux: demux-pinctrl: do not deactivate a master that is not active
+    - powerpc/pseries: Fix use after free in remove_phb_dynamic()
+    - ax25: Fix refcount leaks caused by ax25_cb_del()
+    - ax25: Fix NULL pointer dereferences in ax25 timers
+    - drm/i915: Fix renamed struct field
+    - selftests/bpf/test_lirc_mode2.sh: Exit with proper code
+    - bpftool: Fix print error when show bpf map
+    - PCI: Avoid broken MSI on SB600 USB devices
+    - net: bcmgenet: Use stronger register read/writes to assure ordering
+    - tcp: ensure PMTU updates are processed during fastopen
+    - openvswitch: always update flow key after nat
+    - net: dsa: fix panic on shutdown if multi-chip tree failed to probe
+    - net: wwan: qcom_bam_dmux: fix wrong pointer passed to IS_ERR()
+    - tipc: fix the timer expires after interval 100ms
+    - mfd: asic3: Add missing iounmap() on error asic3_mfd_probe
+    - ice: fix 'scheduling while atomic' on aux critical err interrupt
+    - ice: don't allow to run ice_send_event_to_aux() in atomic ctx
+    - drivers: ethernet: cpsw: fix panic when interrupt coaleceing is set via
+      ethtool
+    - kernel/resource: fix kfree() of bootmem memory again
+    - clk: renesas: r9a07g044: Update multiplier and divider values for PLL2/3
+    - staging: r8188eu: release_firmware is not called if allocation fails
+    - mxser: fix xmit_buf leak in activate when LSR == 0xff
+    - fsi: scom: Fix error handling
+    - fsi: scom: Remove retries in indirect scoms
+    - pwm: lpc18xx-sct: Initialize driver data and hardware before pwmchip_add()
+    - pps: clients: gpio: Propagate return value from pps_gpio_probe
+    - fsi: Aspeed: Fix a potential double free
+    - misc: alcor_pci: Fix an error handling path
+    - cpufreq: qcom-cpufreq-nvmem: fix reading of PVS Valid fuse
+    - soundwire: intel: fix wrong register name in intel_shim_wake
+    - clk: qcom: ipq8074: fix PCI-E clock oops
+    - dmaengine: idxd: restore traffic class defaults after wq reset
+    - iio: mma8452: Fix probe failing when an i2c_device_id is used
+    - staging: qlge: add unregister_netdev in qlge_probe
+    - serial: 8250_aspeed_vuart: add PORT_ASPEED_VUART port type
+    - staging:iio:adc:ad7280a: Fix handing of device address bit reversing.
+    - clk: renesas: r8a779f0: Fix RSW2 clock divider
+    - pinctrl: renesas: r8a77470: Reduce size for narrow VIN1 channel
+    - pinctrl: renesas: checker: Fix miscalculation of number of states
+    - clk: qcom: ipq8074: Use floor ops for SDCC1 clock
+    - phy: dphy: Correct lpx parameter and its derivatives(ta_{get,go,sure})
+    - phy: phy-brcm-usb: fixup BCM4908 support
+    - serial: 8250_mid: Balance reference count for PCI DMA device
+    - serial: 8250_lpss: Balance reference count for PCI DMA device
+    - NFS: Use of mapping_set_error() results in spurious errors
+    - serial: 8250: Fix race condition in RTS-after-send handling
+    - iio: adc: Add check for devm_request_threaded_irq
+    - habanalabs: Add check for pci_enable_device
+    - NFS: Return valid errors from nfs2/3_decode_dirent()
+    - staging: r8188eu: fix endless loop in recv_func
+    - dma-debug: fix return value of __setup handlers
+    - clk: imx7d: Remove audio_mclk_root_clk
+    - clk: imx: off by one in imx_lpcg_parse_clks_from_dt()
+    - clk: at91: sama7g5: fix parents of PDMCs' GCLK
+    - clk: qcom: clk-rcg2: Update logic to calculate D value for RCG
+    - clk: qcom: clk-rcg2: Update the frac table for pixel clock
+    - clk: starfive: jh7100: Don't round divisor up twice
+    - clk: starfive: jh7100: Handle audio_div clock properly
+    - dmaengine: hisi_dma: fix MSI allocate fail when reload hisi_dma
+    - remoteproc: qcom: Fix missing of_node_put in adsp_alloc_memory_region
+    - remoteproc: qcom_wcnss: Add missing of_node_put() in
+      wcnss_alloc_memory_region
+    - remoteproc: qcom_q6v5_mss: Fix some leaks in q6v5_alloc_memory_region
+    - nvdimm/region: Fix default alignment for small regions
+    - clk: actions: Terminate clk_div_table with sentinel element
+    - clk: loongson1: Terminate clk_div_table with sentinel element
+    - clk: hisilicon: Terminate clk_div_table with sentinel element
+    - clk: clps711x: Terminate clk_div_table with sentinel element
+    - clk: Fix clk_hw_get_clk() when dev is NULL
+    - clk: tegra: tegra124-emc: Fix missing put_device() call in
+      emc_ensure_emc_driver
+    - mailbox: imx: fix crash in resume on i.mx8ulp
+    - NFS: remove unneeded check in decode_devicenotify_args()
+    - staging: mt7621-dts: fix LEDs and pinctrl on GB-PC1 devicetree
+    - staging: mt7621-dts: fix formatting
+    - staging: mt7621-dts: fix pinctrl properties for ethernet
+    - staging: mt7621-dts: fix GB-PC2 devicetree
+    - pinctrl: ocelot: fix confops resource index
+    - pinctrl: ocelot: fix duplicate debugfs entry
+    - pinctrl: mediatek: Fix missing of_node_put() in mtk_pctrl_init
+    - pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_* readback
+    - pinctrl: mediatek: paris: Fix "argument" argument type for mtk_pinconf_get()
+    - pinctrl: mediatek: paris: Fix pingroup pin config state readback
+    - pinctrl: mediatek: paris: Skip custom extra pin config dump for virtual
+      GPIOs
+    - pinctrl: ocelot: Fix interrupt parsing
+    - pinctrl: microchip-sgpio: lock RMW access
+    - pinctrl: nomadik: Add missing of_node_put() in nmk_pinctrl_probe
+    - pinctrl/rockchip: Add missing of_node_put() in rockchip_pinctrl_probe
+    - clk: visconti: prevent array overflow in visconti_clk_register_gates()
+    - tty: hvc: fix return value of __setup handler
+    - kgdboc: fix return value of __setup handler
+    - serial: 8250: fix XOFF/XON sending when DMA is used
+    - virt: acrn: obtain pa from VMA with PFNMAP flag
+    - virt: acrn: fix a memory leak in acrn_dev_ioctl()
+    - kgdbts: fix return value of __setup handler
+    - firmware: google: Properly state IOMEM dependency
+    - driver core: dd: fix return value of __setup handler
+    - perf test arm64: Test unwinding using fame-pointer (fp) mode
+    - jfs: fix divide error in dbNextAG
+    - SUNRPC/call_alloc: async tasks mustn't block waiting for memory
+    - SUNRPC: improve 'swap' handling: scheduling and PF_MEMALLOC
+    - SUNRPC: Don't call connect() more than once on a TCP socket
+    - perf parse-events: Move slots only with topdown
+    - netfilter: egress: Report interface as outgoing
+    - netfilter: nf_conntrack_tcp: preserve liberal flag in tcp options
+    - SUNRPC don't resend a task on an offlined transport
+    - NFSv4.1: don't retry BIND_CONN_TO_SESSION on session error
+    - kdb: Fix the putarea helper function
+    - perf stat: Fix forked applications enablement of counters
+    - net: stmmac: dwmac-qcom-ethqos: Enable RGMII functional clock on resume
+    - clk: qcom: gcc-msm8994: Fix gpll4 width
+    - vsock/virtio: initialize vdev->priv before using VQs
+    - vsock/virtio: read the negotiated features before using VQs
+    - vsock/virtio: enable VQs early on probe
+    - clk: Initialize orphan req_rate
+    - xen: fix is_xen_pmu()
+    - net: enetc: report software timestamping via SO_TIMESTAMPING
+    - net: hns3: fix bug when PF set the duplicate MAC address for VFs
+    - net: hns3: fix port base vlan add fail when concurrent with reset
+    - net: hns3: add vlan list lock to protect vlan list
+    - net: hns3: refine the process when PF set VF VLAN
+    - net: phy: broadcom: Fix brcm_fet_config_init()
+    - selftests: test_vxlan_under_vrf: Fix broken test case
+    - NFS: Don't loop forever in nfs_do_recoalesce()
+    - libperf tests: Fix typo in perf_evlist__open() failure error messages
+    - net: hns3: fix ethtool tx copybreak buf size indicating not aligned issue
+    - net: hns3: add max order judgement for tx spare buffer
+    - net: hns3: clean residual vf config after disable sriov
+    - net: hns3: add netdev reset check for hns3_set_tunable()
+    - net: hns3: add NULL pointer check for hns3_set/get_ringparam()
+    - net: hns3: fix phy can not link up when autoneg off and reset
+    - net: sparx5: depends on PTP_1588_CLOCK_OPTIONAL
+    - qlcnic: dcb: default to returning -EOPNOTSUPP
+    - net/x25: Fix null-ptr-deref caused by x25_disconnect
+    - net: sparx5: switchdev: fix possible NULL pointer dereference
+    - octeontx2-af: initialize action variable
+    - selftests: tls: skip cmsg_to_pipe tests with TLS=n
+    - net/sched: act_ct: fix ref leak when switching zones
+    - NFSv4/pNFS: Fix another issue with a list iterator pointing to the head
+    - net: dsa: bcm_sf2_cfp: fix an incorrect NULL check on list iterator
+    - fs: fd tables have to be multiples of BITS_PER_LONG
+    - lib/test: use after free in register_test_dev_kmod()
+    - fs: fix fd table size alignment properly
+    - LSM: general protection fault in legacy_parse_param
+    - regulator: rpi-panel: Handle I2C errors/timing to the Atmel
+    - crypto: hisilicon/qm - cleanup warning in qm_vf_read_qos
+    - crypto: octeontx2 - CN10K CPT to RNM workaround
+    - gcc-plugins/stackleak: Exactly match strings instead of prefixes
+    - rcu: Kill rnp->ofl_seq and use only rcu_state.ofl_lock for exclusion
+    - pinctrl: npcm: Fix broken references to chip->parent_device
+    - rcu: Mark writes to the rcu_segcblist structure's ->flags field
+    - block: throttle split bio in case of iops limit
+    - memstick/mspro_block: fix handling of read-only devices
+    - block/bfq_wf2q: correct weight to ioprio
+    - crypto: xts - Add softdep on ecb
+    - crypto: hisilicon/sec - not need to enable sm4 extra mode at HW V3
+    - block, bfq: don't move oom_bfqq
+    - selinux: use correct type for context length
+    - powercap/dtpm_cpu: Reset per_cpu variable in the release function
+    - arm64: module: remove (NOLOAD) from linker script
+    - selinux: allow FIOCLEX and FIONCLEX with policy capability
+    - loop: use sysfs_emit() in the sysfs xxx show()
+    - Fix incorrect type in assignment of ipv6 port for audit
+    - irqchip/qcom-pdc: Fix broken locking
+    - irqchip/nvic: Release nvic_base upon failure
+    - fs/binfmt_elf: Fix AT_PHDR for unusual ELF files
+    - hwrng: cavium - fix NULL but dereferenced coccicheck error
+    - bfq: fix use-after-free in bfq_dispatch_request
+    - ACPICA: Avoid walking the ACPI Namespace if it is not there
+    - ACPI / x86: Add skip i2c clients quirk for Nextbook Ares 8
+    - ACPI / x86: Add skip i2c clients quirk for Lenovo Yoga Tablet 1050F/L
+    - lib/raid6/test/Makefile: Use $(pound) instead of \# for Make 4.3
+    - Revert "Revert "block, bfq: honor already-setup queue merges""
+    - ACPI/APEI: Limit printable size of BERT table data
+    - PM: core: keep irq flags in device_pm_check_callbacks()
+    - parisc: Fix non-access data TLB cache flush faults
+    - parisc: Fix handling off probe non-access faults
+    - nvme-tcp: lockdep: annotate in-kernel sockets
+    - spi: tegra20: Use of_device_get_match_data()
+    - spi: fsi: Implement a timeout for polling status
+    - atomics: Fix atomic64_{read_acquire,set_release} fallbacks
+    - locking/lockdep: Iterate lock_classes directly when reading lockdep files
+    - ext4: correct cluster len and clusters changed accounting in ext4_mb_mark_bb
+    - ext4: fix ext4_mb_mark_bb() with flex_bg with fast_commit
+    - sched/tracing: Report TASK_RTLOCK_WAIT tasks as TASK_UNINTERRUPTIBLE
+    - ext4: don't BUG if someone dirty pages without asking ext4 first
+    - f2fs: fix to do sanity check on curseg->alloc_type
+    - NFSD: Fix nfsd_breaker_owns_lease() return values
+    - f2fs: don't get FREEZE lock in f2fs_evict_inode in frozen fs
+    - btrfs: harden identification of a stale device
+    - btrfs: make search_csum_tree return 0 if we get -EFBIG
+    - btrfs: handle csum lookup errors properly on reads
+    - btrfs: do not double complete bio on errors during compressed reads
+    - btrfs: do not clean up repair bio if submit fails
+    - f2fs: use spin_lock to avoid hang
+    - f2fs: compress: fix to print raw data size in error path of lz4
+      decompression
+    - Adjust cifssb maximum read size
+    - ntfs: add sanity check on allocation size
+    - media: staging: media: zoran: move videodev alloc
+    - media: staging: media: zoran: calculate the right buffer number for
+      zoran_reap_stat_com
+    - media: staging: media: zoran: fix various V4L2 compliance errors
+    - media: atmel: atmel-isc-base: report frame sizes as full supported range
+    - media: ir_toy: free before error exiting
+    - ASoC: sh: rz-ssi: Make the data structures available before registering the
+      handlers
+    - ASoC: cs42l42: Report full jack status when plug is detected
+    - ASoC: SOF: Intel: match sdw version on link_slaves_found
+    - media: imx-jpeg: Prevent decoding NV12M jpegs into single-planar buffers
+    - ASoC: SOF: Intel: hda: Remove link assignment limitation
+    - media: iommu/mediatek-v1: Free the existed fwspec if the master dev already
+      has
+    - media: iommu/mediatek: Return ENODEV if the device is NULL
+    - media: iommu/mediatek: Add device_link between the consumer and the larb
+      devices
+    - video: fbdev: nvidiafb: Use strscpy() to prevent buffer overflow
+    - video: fbdev: w100fb: Reset global state
+    - video: fbdev: cirrusfb: check pixclock to avoid divide by zero
+    - video: fbdev: omapfb: acx565akm: replace snprintf with sysfs_emit
+    - ARM: dts: qcom: fix gic_irq_domain_translate warnings for msm8960
+    - ARM: dts: bcm2837: Add the missing L1/L2 cache information
+    - ASoC: madera: Add dependencies on MFD
+    - media: atomisp_gmin_platform: Add DMI quirk to not turn AXP ELDO2 regulator
+      off on some boards
+    - media: atomisp: fix dummy_ptr check to avoid duplicate active_bo
+    - ARM: ftrace: avoid redundant loads or clobbering IP
+    - ALSA: hda: Fix driver index handling at re-binding
+    - ARM: dts: imx7: Use audio_mclk_post_div instead audio_mclk_root_clk
+    - arm64: defconfig: build imx-sdma as a module
+    - video: fbdev: omapfb: panel-dsi-cm: Use sysfs_emit() instead of snprintf()
+    - video: fbdev: omapfb: panel-tpo-td043mtea1: Use sysfs_emit() instead of
+      snprintf()
+    - video: fbdev: udlfb: replace snprintf in show functions with sysfs_emit
+    - ARM: dts: bcm2711: Add the missing L1/L2 cache information
+    - ASoC: soc-core: skip zero num_dai component in searching dai name
+    - ASoC: Intel: sof_es8336: add quirk for Huawei D15 2021
+    - media: imx-jpeg: fix a bug of accessing array out of bounds
+    - media: cx88-mpeg: clear interrupt status register before streaming video
+    - ASoC: rt5682s: Fix the wrong jack type detected
+    - ARM: tegra: transformer: Drop reg-shift for Tegra HS UART
+    - uaccess: fix type mismatch warnings from access_ok()
+    - lib/test_lockup: fix kernel pointer check for separate address spaces
+    - ARM: tegra: tamonten: Fix I2C3 pad setting
+    - ARM: mmp: Fix failure to remove sram device
+    - ASoC: amd: vg: fix for pm resume callback sequence
+    - ASoC: amd: vangogh: fix uninitialized symbol warning in machine driver
+    - video: fbdev: sm712fb: Fix crash in smtcfb_write()
+    - media: i2c: ov5648: Fix lockdep error
+    - media: Revert "media: em28xx: add missing em28xx_close_extension"
+    - media: hdpvr: initialize dev->worker at hdpvr_register_videodev
+    - ASoC: SOF: debug: clarify operator precedence
+    - ASoC: Intel: sof_sdw: fix quirks for 2022 HP Spectre x360 13"
+    - ASoC: SOF: Intel: hda: retrieve DMIC number for I2S boards
+    - ALSA: intel-nhlt: add helper to detect SSP link mask
+    - ALSA: intel-dsp-config: add more ACPI HIDs for ES83x6 devices
+    - ASoC: Intel: soc-acpi: add more ACPI HIDs for ES83x6 devices
+    - ALSA: intel-dspconfig: add ES8336 support for CNL
+    - ASoC: Intel: Revert "ASoC: Intel: sof_es8336: add quirk for Huawei D15 2021"
+    - ASoC: Intel: sof_es8336: log all quirks
+    - tracing: Have TRACE_DEFINE_ENUM affect trace event types as well
+    - mmc: host: Return an error when ->enable_sdio_irq() ops is missing
+    - ASoC: mediatek: Fix error handling in mt8183_da7219_max98357_dev_probe
+    - media: atomisp: fix bad usage at error handling logic
+    - ALSA: hda/realtek: Add alc256-samsung-headphone fixup
+    - KVM: SVM: Allow AVIC support on system w/ physical APIC ID > 255
+    - KVM: x86: Reinitialize context if host userspace toggles EFER.LME
+    - KVM: x86/mmu: Use common TDP MMU zap helper for MMU notifier unmap hook
+    - KVM: x86/mmu: Move "invalid" check out of kvm_tdp_mmu_get_root()
+    - KVM: x86/mmu: Zap _all_ roots when unmapping gfn range in TDP MMU
+    - KVM: x86/mmu: Check for present SPTE when clearing dirty bit in TDP MMU
+    - KVM: x86: hyper-v: Drop redundant 'ex' parameter from kvm_hv_send_ipi()
+    - KVM: x86: hyper-v: Drop redundant 'ex' parameter from kvm_hv_flush_tlb()
+    - KVM: x86: hyper-v: Fix the maximum number of sparse banks for XMM fast TLB
+      flush hypercalls
+    - KVM: x86: hyper-v: HVCALL_SEND_IPI_EX is an XMM fast hypercall
+    - powerpc/kasan: Fix early region not updated correctly
+    - powerpc/tm: Fix more userspace r13 corruption
+    - powerpc/lib/sstep: Fix 'sthcx' instruction
+    - powerpc/lib/sstep: Fix build errors with newer binutils
+    - powerpc: Add set_memory_{p/np}() and remove set_memory_attr()
+    - powerpc: Fix build errors with newer binutils
+    - drm/dp: Fix off-by-one in register cache size
+    - drm/i915: Treat SAGV block time 0 as SAGV disabled
+    - drm/i915: Fix PSF GV point mask when SAGV is not possible
+    - drm/i915: Reject unsupported TMDS rates on ICL+
+    - scsi: qla2xxx: Refactor asynchronous command initialization
+    - scsi: qla2xxx: Implement ref count for SRB
+    - scsi: qla2xxx: Fix stuck session in gpdb
+    - scsi: qla2xxx: Fix warning message due to adisc being flushed
+    - scsi: qla2xxx: Fix scheduling while atomic
+    - scsi: qla2xxx: Fix premature hw access after PCI error
+    - scsi: qla2xxx: Fix wrong FDMI data for 64G adapter
+    - scsi: qla2xxx: Fix warning for missing error code
+    - scsi: qla2xxx: Fix device reconnect in loop topology
+    - scsi: qla2xxx: edif: Fix clang warning
+    - scsi: qla2xxx: Fix T10 PI tag escape and IP guard options for 28XX adapters
+    - scsi: qla2xxx: Add devids and conditionals for 28xx
+    - scsi: qla2xxx: Check for firmware dump already collected
+    - scsi: qla2xxx: Suppress a kernel complaint in qla_create_qpair()
+    - scsi: qla2xxx: Fix disk failure to rediscover
+    - scsi: qla2xxx: Fix incorrect reporting of task management failure
+    - scsi: qla2xxx: Fix hang due to session stuck
+    - scsi: qla2xxx: Fix laggy FC remote port session recovery
+    - scsi: qla2xxx: Fix missed DMA unmap for NVMe ls requests
+    - scsi: qla2xxx: Fix crash during module load unload test
+    - scsi: qla2xxx: Fix N2N inconsistent PLOGI
+    - scsi: qla2xxx: Fix stuck session of PRLI reject
+    - scsi: qla2xxx: Reduce false trigger to login
+    - scsi: qla2xxx: Use correct feature type field during RFF_ID processing
+    - platform: chrome: Split trace include file
+    - MIPS: crypto: Fix CRC32 code
+    - KVM: x86: Check lapic_in_kernel() before attempting to set a SynIC irq
+    - KVM: x86: Avoid theoretical NULL pointer dereference in
+      kvm_irq_delivery_to_apic_fast()
+    - KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC wasn't activated
+    - KVM: x86/mmu: do compare-and-exchange of gPTE via the user address
+    - KVM: Prevent module exit until all VMs are freed
+    - KVM: x86: fix sending PV IPI
+    - KVM: SVM: fix panic on out-of-bounds guest IRQ
+    - KVM: avoid double put_page with gfn-to-pfn cache
+    - ubifs: rename_whiteout: Fix double free for whiteout_ui->data
+    - ubifs: Fix deadlock in concurrent rename whiteout and inode writeback
+    - ubifs: Add missing iput if do_tmpfile() failed in rename whiteout
+    - ubifs: Rename whiteout atomically
+    - ubifs: Fix 'ui->dirty' race between do_tmpfile() and writeback work
+    - ubifs: Rectify space amount budget for mkdir/tmpfile operations
+    - ubifs: setflags: Make dirtied_ino_d 8 bytes aligned
+    - ubifs: Fix read out-of-bounds in ubifs_wbuf_write_nolock()
+    - ubifs: Fix to add refcount once page is set private
+    - ubifs: rename_whiteout: correct old_dir size computing
+    - nvme: allow duplicate NSIDs for private namespaces
+    - nvme: fix the read-only state for zoned namespaces with unsupposed features
+    - wireguard: queueing: use CFI-safe ptr_ring cleanup function
+    - wireguard: socket: free skb in send6 when ipv6 is disabled
+    - wireguard: socket: ignore v6 endpoints when ipv6 is disabled
+    - XArray: Fix xas_create_range() when multi-order entry present
+    - can: mcba_usb: mcba_usb_start_xmit(): fix double dev_kfree_skb in error path
+    - can: mcba_usb: properly check endpoint type
+    - can: mcp251xfd: mcp251xfd_register_get_dev_id(): fix return of error value
+    - XArray: Include bitmap.h from xarray.h
+    - XArray: Update the LRU list in xas_split()
+    - modpost: restore the warning message for missing symbol versions
+    - rtc: gamecube: Fix refcount leak in gamecube_rtc_read_offset_from_sram
+    - rtc: check if __rtc_read_time was successful
+    - loop: fix ioctl calls using compat_loop_info
+    - gfs2: gfs2_setattr_size error path fix
+    - gfs2: Fix gfs2_file_buffered_write endless loop workaround
+    - gfs2: Make sure FITRIM minlen is rounded up to fs block size
+    - net: hns3: fix the concurrency between functions reading debugfs
+    - net: hns3: fix software vlan talbe of vlan 0 inconsistent with hardware
+    - rxrpc: fix some null-ptr-deref bugs in server_key.c
+    - rxrpc: Fix call timer start racing with call destruction
+    - mailbox: imx: fix wakeup failure from freeze mode
+    - crypto: x86/poly1305 - Fixup SLS
+    - crypto: arm/aes-neonbs-cbc - Select generic cbc and aes
+    - watch_queue: Free the page array when watch_queue is dismantled
+    - pinctrl: pinconf-generic: Print arguments for bias-pull-*
+    - watchdog: rti-wdt: Add missing pm_runtime_disable() in probe function
+    - net: sparx5: uses, depends on BRIDGE or !BRIDGE
+    - pinctrl: nuvoton: npcm7xx: Rename DS() macro to DSTR()
+    - pinctrl: nuvoton: npcm7xx: Use %zu printk format for ARRAY_SIZE()
+    - ASoC: rockchip: i2s_tdm: Fixup config for SND_SOC_DAIFMT_DSP_A/B
+    - ASoC: mediatek: mt6358: add missing EXPORT_SYMBOLs
+    - ubi: Fix race condition between ctrl_cdev_ioctl and ubi_cdev_ioctl
+    - ARM: iop32x: offset IRQ numbers by 1
+    - block: Fix the maximum minor value is blk_alloc_ext_minor()
+    - block: restore the old set_task_ioprio() behaviour wrt PF_EXITING
+    - Revert "virtio-pci: harden INTX interrupts"
+    - Revert "virtio_pci: harden MSI-X interrupts"
+    - virtio: use virtio_device_ready() in virtio_device_restore()
+    - io_uring: remove poll entry from list when canceling all
+    - io_uring: bump poll refs to full 31-bits
+    - io_uring: fix memory leak of uid in files registration
+    - riscv module: remove (NOLOAD)
+    - ACPI: CPPC: Avoid out of bounds access when parsing _CPC data
+    - vhost: handle error while adding split ranges to iotlb
+    - spi: Fix Tegra QSPI example
+    - platform/chrome: cros_ec_typec: Check for EC device
+    - platform/x86: asus-wmi: Fix regression when probing for fan curve control
+    - can: isotp: restore accidentally removed MSG_PEEK feature
+    - proc: bootconfig: Add null pointer check
+    - x86/fpu/xstate: Fix the ARCH_REQ_XCOMP_PERM implementation
+    - x86/sev: Unroll string mmio with CC_ATTR_GUEST_UNROLL_STRING_IO
+    - drm/connector: Fix typo in documentation
+    - scsi: qla2xxx: Add qla2x00_async_done() for async routines
+    - staging: mt7621-dts: fix pinctrl-0 items to be size-1 items on ethernet
+    - docs: fix 'make htmldocs' warning in SCTP.rst
+    - arm64: mm: Drop 'const' from conditional arm64_dma_phys_limit definition
+    - ASoC: soc-compress: Change the check for codec_dai
+    - KVM: x86: SVM: fix avic spec based definitions again
+    - ax25: fix UAF bug in ax25_send_control()
+    - Reinstate some of "swiotlb: rework "fix info leak with DMA_FROM_DEVICE""
+    - tracing: Have type enum modifications copy the strings
+    - mips: Enable KCSAN - take 2
+    - net: add skb_set_end_offset() helper
+    - mm/mmap: return 1 from stack_guard_gap __setup() handler
+    - ARM: 9187/1: JIVE: fix return value of __setup handler
+    - mm/memcontrol: return 1 from cgroup.memory __setup() handler
+    - mm/usercopy: return 1 from hardened_usercopy __setup() handler
+    - af_unix: Support POLLPRI for OOB.
+    - libbpf: Define BTF_KIND_* constants in btf.h to avoid compilation errors
+    - bpf: Adjust BPF stack helper functions to accommodate skip > 0
+    - bpf: Fix comment for helper bpf_current_task_under_cgroup()
+    - nbd: fix possible overflow on 'first_minor' in nbd_dev_add()
+    - mmc: rtsx: Use pm_runtime_{get,put}() to handle runtime PM
+    - dt-bindings: mtd: nand-controller: Fix the reg property description
+    - dt-bindings: mtd: nand-controller: Fix a comment in the examples
+    - dt-bindings: spi: mxic: The interrupt property is not mandatory
+    - media: dt-binding: media: hynix,hi846: use $defs/port-base port description
+    - media: dt-bindings: media: hynix,hi846: add link-frequencies description
+    - dt-bindings: memory: mtk-smi: Rename clock to clocks
+    - dt-bindings: memory: mtk-smi: No need mediatek,larb-id for mt8167
+    - dt-bindings: memory: mtk-smi: Correct minItems to 2 for the gals clocks
+    - dt-bindings: pinctrl: mt8195: fix bias-pull-{up,down} checks
+    - dt-bindings: pinctrl: pinctrl-microchip-sgpio: Fix example
+    - ubi: fastmap: Return error code if memory allocation fails in add_aeb()
+    - net: preserve skb_end_offset() in skb_unclone_keeptruesize()
+    - ASoC: SOF: Intel: Fix build error without SND_SOC_SOF_PCI_DEV
+    - ASoC: topology: Allow TLV control to be either read or write
+    - perf vendor events: Update metrics for SkyLake Server
+    - media: ov6650: Add try support to selection API operations
+    - media: ov6650: Fix crop rectangle affected by set format
+    - pinctrl: canonical rsel resistance selection property
+    - spi: mediatek: support tick_delay without enhance_timing
+    - ARM: dts: spear1340: Update serial node properties
+    - ARM: dts: spear13xx: Update SPI dma properties
+    - arm64: dts: ls1043a: Update i2c dma properties
+    - arm64: dts: ls1046a: Update i2c node dma properties
+    - um: Fix uml_mconsole stop/go
+    - docs: sysctl/kernel: add missing bit to panic_print
+    - xsk: Do not write NULL in SW ring at allocation failure
+    - ice: xsk: Fix indexing in ice_tx_xsk_pool()
+    - vdpa/mlx5: Avoid processing works if workqueue was destroyed
+    - openvswitch: Fixed nd target mask field in the flow dump.
+    - torture: Make torture.sh help message match reality
+    - n64cart: convert bi_disk to bi_bdev->bd_disk fix build
+    - Revert "nbd: fix possible overflow on 'first_minor' in nbd_dev_add()"
+    - mmc: rtsx: Let MMC core handle runtime PM
+    - mmc: rtsx: Fix build errors/warnings for unused variable
+    - coredump: Snapshot the vmas in do_coredump
+    - coredump: Remove the WARN_ON in dump_vma_snapshot
+    - coredump/elf: Pass coredump_params into fill_note_info
+    - coredump: Use the vma snapshot in fill_files_note
+    - Linux 5.17.2
+
+  * Jammy update: v5.17.1 upstream stable release (LP: #1968982)
+    - tpm: Fix error handling in async work
+    - Bluetooth: btusb: Add another Realtek 8761BU
+    - llc: fix netdevice reference leaks in llc_ui_bind()
+    - ASoC: sti: Fix deadlock via snd_pcm_stop_xrun() call
+    - ALSA: oss: Fix PCM OSS buffer allocation overflow
+    - ALSA: usb-audio: add mapping for new Corsair Virtuoso SE
+    - ALSA: hda/realtek: Add quirk for Clevo NP70PNJ
+    - ALSA: hda/realtek: Add quirk for Clevo NP50PNJ
+    - ALSA: hda/realtek - Fix headset mic problem for a HP machine with alc671
+    - ALSA: hda/realtek: Add quirk for ASUS GA402
+    - ALSA: pcm: Fix races among concurrent hw_params and hw_free calls
+    - ALSA: pcm: Fix races among concurrent read/write and buffer changes
+    - ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls
+    - ALSA: pcm: Fix races among concurrent prealloc proc writes
+    - ALSA: pcm: Add stream lock during PCM reset ioctl operations
+    - ALSA: usb-audio: Add mute TLV for playback volumes on RODE NT-USB
+    - ALSA: cmipci: Restore aux vol on suspend/resume
+    - ALSA: pci: fix reading of swapped values from pcmreg in AC97 codec
+    - drivers: net: xgene: Fix regression in CRC stripping
+    - netfilter: nf_tables: initialize registers in nft_do_chain()
+    - netfilter: nf_tables: validate registers coming from userspace.
+    - ACPI / x86: Work around broken XSDT on Advantech DAC-BJ01 board
+    - ACPI: battery: Add device HID and quirk for Microsoft Surface Go 3
+    - ACPI: video: Force backlight native for Clevo NL5xRU and NL5xNU
+    - crypto: qat - disable registration of algorithms
+    - Bluetooth: btusb: Add one more Bluetooth part for the Realtek RTL8852AE
+    - Bluetooth: hci_sync: Add a new quirk to skip HCI_FLT_CLEAR_ALL
+    - Bluetooth: btusb: Use quirk to skip HCI_FLT_CLEAR_ALL on fake CSR
+      controllers
+    - Revert "ath: add support for special 0x0 regulatory domain"
+    - drm/virtio: Ensure that objs is not NULL in virtio_gpu_array_put_free()
+    - jbd2: fix use-after-free of transaction_t race
+    - rcu: Don't deboost before reporting expedited quiescent state
+    - uaccess: fix integer overflow on access_ok()
+    - mac80211: fix potential double free on mesh join
+    - tpm: fix reference counting for struct tpm_chip
+    - tpm: use try_get_ops() in tpm-space.c
+    - wcn36xx: Differentiate wcn3660 from wcn3620
+    - m68k: fix access_ok for coldfire
+    - nds32: fix access_ok() checks in get/put_user
+    - drm/msm/gpu: Fix crash on devices without devfreq support (v2)
+    - llc: only change llc->dev when bind() succeeds
+    - Linux 5.17.1
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: shiftfs: always rely on init_user_ns
+    - [Config] update configs and annotations after stable updates
+    - SAUCE: sfc: The size of the RX recycle ring should be more flexible
+    - [Packaging] remove references to lowlatency flavor
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 14 Apr 2022 08:45:40 +0200
+
+linux-unstable (5.17.0-6.6) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-6.6 -proposed tracker (LP: #1965731)
+
+  * dependency on crda obsolete according to Debian (LP: #1958918)
+    - [Packaging] switch dependency from crda to wireless-regdb
+
+  * Miscellaneous Ubuntu changes
+    - [Config] disable CONFIG_SYSFB_SIMPLEFB on amd64
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.17
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 21 Mar 2022 09:46:03 +0100
+
+linux-unstable (5.17.0-5.5) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-5.5 -proposed tracker (LP: #1964766)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync dkms-build{,--nvidia-N} from LRMv5
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to v5.17-rc8
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.17-rc8
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 14 Mar 2022 13:15:50 +0100
+
+linux-unstable (5.17.0-4.4) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-4.4 -proposed tracker (LP: #1963880)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.17-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 07 Mar 2022 10:20:48 +0100
+
+linux-unstable (5.17.0-3.3) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-3.3 -proposed tracker (LP: #1962450)
+
+  * 5.15 stuck at boot on c4.large (LP: #1956780)
+    - Revert "PCI/MSI: Mask MSI-X vectors only on success"
+
+  * [22.04 FEAT] KVM: Enable storage key checking for intercepted instruction
+    handled by userspace (LP: #1933179)
+    - s390/uaccess: Add copy_from/to_user_key functions
+    - KVM: s390: Honor storage keys when accessing guest memory
+    - KVM: s390: handle_tprot: Honor storage keys
+    - KVM: s390: Add optional storage key checking to MEMOP IOCTL
+    - KVM: s390: Add vm IOCTL for key checked guest absolute memory access
+    - KVM: s390: Rename existing vcpu memop functions
+    - KVM: s390: Update api documentation for memop ioctl
+    - KVM: s390: Clarify key argument for MEM_OP in api docs
+    - KVM: s390: Add missing vm MEM_OP size check
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.17-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Feb 2022 09:42:32 +0100
+
+linux-unstable (5.17.0-2.2) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-2.2 -proposed tracker (LP: #1962137)
+
+  * CVE-2022-25636
+    - netfilter: nf_tables_offload: incorrect flow offload action array size
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+    - [Packaging] update Ubuntu.md
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Jammy update: v5.15.22 upstream stable release (LP: #1960516)
+    - Revert "ASoC: mediatek: Check for error clk pointer"
+    - [Config] disable FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
+
+  * Jammy update: v5.15.20 upstream stable release (LP: #1960509)
+    - Revert "UBUNTU: SAUCE: Revert "e1000e: Additional PHY power saving in S0ix""
+
+  * Jammy update: v5.15.19 upstream stable release (LP: #1959879)
+    - drm/etnaviv: relax submit size limits
+
+  * Jammy update: v5.15.17 upstream stable release (LP: #1959376)
+    - net: dsa: hellcreek: Allow PTP P2P measurements on blocked ports
+    - rtw88: add quirk to disable pci caps on HP 250 G7 Notebook PC
+    - ASoC: mediatek: Check for error clk pointer
+    - regulator: da9121: Prevent current limit change when enabled
+    - ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream
+    - drm/etnaviv: limit submit sizes
+    - Bluetooth: hci_sync: Fix not setting adv set duration
+    - net: axienet: Wait for PhyRstCmplt after core reset
+
+  * rtw88_8821ce causes freeze (LP: #1927808) // Jammy update: v5.15.17 upstream
+    stable release (LP: #1959376)
+    - rtw88: Disable PCIe ASPM while doing NAPI poll on 8821CE
+
+  * Jammy update: v5.15.15 upstream stable release (LP: #1958418)
+    - Bluetooth: btusb: Add support for Foxconn MT7922A
+    - Bluetooth: btbcm: disable read tx power for MacBook Air 8,1 and 8,2
+    - platform/x86/intel: hid: add quirk to support Surface Go 3
+
+  * Support USB4 DP alt mode for AMD Yellow Carp graphics card (LP: #1953008)
+    - SAUCE: drm/amd/display: Fixup previous PSR policy commit
+
+  * alsa/sdw: add sdw audio machine driver for several ADL machines
+    (LP: #1951563)
+    - ASoC: Intel: sof_sdw: Add support for SKU 0B11 product
+    - ASoC: Intel: sof_sdw: Add support for SKU 0B13 product
+    - ASoC: Intel: sof_sdw: Add support for SKU 0B29 product
+    - ASoC: Intel: sof_sdw: Add support for SKU 0B12 product
+
+  * Improve performance and idle power consumption (LP: #1941893)
+    - x86: ACPI: cstate: Optimize C3 entry on AMD CPUs
+
+  * Fix spurious wakeup caused by Intel 7560 WWAN (LP: #1956443)
+    - net: wwan: iosm: Keep device at D0 for s2idle case
+
+  * Jammy update: v5.15.13 upstream stable release (LP: #1956926)
+    - scsi: lpfc: Terminate string in lpfc_debugfs_nvmeio_trc_write()
+    - net/mlx5: Fix tc max supported prio for nic mode
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Update dependency of pahole / dwarves
+    - [packaging] unhook lowlatency flavours from the build
+    - [Packaging] use default zstd compression
+    - [Packaging] do not use compression for image packages
+    - [Packaging] use xz compression for ddebs
+    - SAUCE: Makefile: Remove inclusion of lbm header files
+    - SAUCE: Makefile: Fix compiler warnings
+    - [Config] drop unused lowlatency configs
+    - [Config] update configs and annotations after rebase to v5.17-rc5
+
+  * Miscellaneous upstream changes
+    - Revert "rtw88: Disable PCIe ASPM while doing NAPI poll on 8821CE"
+    - MAINTAINERS: Add scripts/pahole-flags.sh to BPF section
+    - kbuild: Add CONFIG_PAHOLE_VERSION
+    - lib/Kconfig.debug: Use CONFIG_PAHOLE_VERSION
+    - lib/Kconfig.debug: Allow BTF + DWARF5 with pahole 1.21+
+    - Revert "UBUNTU: [Packaging] temporarily disable zfs"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 24 Feb 2022 09:41:40 +0100
+
+linux-unstable (5.17.0-1.1) jammy; urgency=medium
+
+  * Rebase to 5.17-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 21 Feb 2022 08:22:18 +0100
+
+linux-unstable (5.17.0-0.0) jammy; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 28 Jan 2022 17:14:13 +0100
+
+linux (5.15.0-18.18) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-18.18 -proposed tracker (LP: #1958638)
+
+  * CVE-2021-4155
+    - xfs: map unwritten blocks in XFS_IOC_{ALLOC, FREE}SP just like fallocate
+
+  * CVE-2022-0185
+    - SAUCE: vfs: test that one given mount param is not larger than PAGE_SIZE
+
+  * [UBUNTU 20.04] KVM hardware diagnose data improvements for guest kernel -
+    kernel part (LP: #1953334)
+    - KVM: s390: add debug statement for diag 318 CPNC data
+
+  * OOB write on BPF_RINGBUF (LP: #1956585)
+    - SAUCE: bpf: prevent helper argument PTR_TO_ALLOC_MEM to have offset other
+      than 0
+
+  * Miscellaneous Ubuntu changes
+    - [Config] re-enable shiftfs
+    - [SAUCE] shiftfs: support kernel 5.15
+    - [Config] update toolchain versions
+
+  * Miscellaneous upstream changes
+    - vfs: fs_context: fix up param length parsing in legacy_parse_param
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 21 Jan 2022 13:32:27 +0100
+
+linux (5.15.0-17.17) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-17.17 -proposed tracker (LP: #1957809)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 13 Jan 2022 17:11:21 +0100
+
+linux (5.15.0-16.16) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-16.16 -proposed tracker (LP: #1956820)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * 5.15 stuck at boot on c4.large (LP: #1956780)
+    - Revert "PCI/MSI: Mask MSI-X vectors only on success"
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] temporarily disable signed v4l2loopback"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Sat, 08 Jan 2022 10:57:58 +0100
+
+linux (5.15.0-15.15) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-15.15 -proposed tracker (LP: #1956314)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * rtw88_8821ce causes freeze (LP: #1927808)
+    - rtw88: Disable PCIe ASPM while doing NAPI poll on 8821CE
+
+  * alsa/sdw: fix the  audio sdw codec parsing logic in the acpi table
+    (LP: #1955686)
+    - ALSA: hda: intel-sdw-acpi: go through HDAS ACPI at max depth of 2
+    - ALSA: hda: intel-sdw-acpi: harden detection of controller
+
+  * Got black screen when resume from s2idle with AMD dGPU (LP: #1955790)
+    - SAUCE: drm/amdgpu: put SMU into proper state on runpm suspending for BOCO
+      capable platform
+    - SAUCE: drm/amdgpu: always reset the asic in suspend (v2)
+
+  *  Fix USB3 detection on HP dock (LP: #1955443)
+    - usb: hub: Add delay for SuperSpeed hub resume to let links transit to U0
+
+  * support signed v4l2loopback dkms build (LP: #1938531)
+    - enable v4l2loopback builds on amd64 kernels
+    - support v4l2loopback dkms build
+
+  * Jammy update: v5.15.12 upstream stable release (LP: #1956305)
+    - arm64: vdso32: require CROSS_COMPILE_COMPAT for gcc+bfd
+    - net: usb: lan78xx: add Allied Telesis AT29M2-AF
+    - ext4: prevent partial update of the extent blocks
+    - ext4: check for out-of-order index extents in ext4_valid_extent_entries()
+    - ext4: check for inconsistent extents between index and leaf block
+    - selftests: KVM: Fix non-x86 compiling
+    - HID: holtek: fix mouse probing
+    - HID: potential dereference of null pointer
+    - NFSD: Fix READDIR buffer overflow
+    - PM: sleep: Fix error handling in dpm_prepare()
+    - arm64: dts: allwinner: orangepi-zero-plus: fix PHY mode
+    - bus: sunxi-rsb: Fix shutdown
+    - spi: change clk_disable_unprepare to clk_unprepare
+    - ucounts: Fix rlimit max values check
+    - drm/mediatek: hdmi: Perform NULL pointer check for mtk_hdmi_conf
+    - ASoC: meson: aiu: fifo: Add missing dma_coerce_mask_and_coherent()
+    - RDMA/hns: Fix RNR retransmission issue for HIP08
+    - IB/qib: Fix memory leak in qib_user_sdma_queue_pkts()
+    - RDMA/hns: Replace kfree() with kvfree()
+    - netfilter: nf_tables: fix use-after-free in nft_set_catchall_destroy()
+    - netfilter: fix regression in looped (broad|multi)cast's MAC handling
+    - ARM: dts: imx6qdl-wandboard: Fix Ethernet support
+    - ice: Use xdp_buf instead of rx_buf for xsk zero-copy
+    - ice: xsk: return xsk buffers back to pool when cleaning the ring
+    - net: marvell: prestera: fix incorrect return of port_find
+    - net: marvell: prestera: fix incorrect structure access
+    - qlcnic: potential dereference null pointer of rx_queue->page_ring
+    - tcp: move inet->rx_dst_ifindex to sk->sk_rx_dst_ifindex
+    - ipv6: move inet6_sk(sk)->rx_dst_cookie to sk->sk_rx_dst_cookie
+    - inet: fully convert sk->sk_rx_dst to RCU rules
+    - net: accept UFOv6 packages in virtio_net_hdr_to_skb
+    - net: skip virtio_net_hdr_set_proto if protocol already set
+    - igb: fix deadlock caused by taking RTNL in RPM resume path
+    - ipmi: Fix UAF when uninstall ipmi_si and ipmi_msghandler module
+    - gpio: virtio: remove timeout
+    - bonding: fix ad_actor_system option setting to default
+    - fjes: Check for error irq
+    - drivers: net: smc911x: Check for error irq
+    - net: ks8851: Check for error irq
+    - sfc: Check null pointer of rx_queue->page_ring
+    - sfc: falcon: Check null pointer of rx_queue->page_ring
+    - asix: fix uninit-value in asix_mdio_read()
+    - asix: fix wrong return value in asix_check_host_enable()
+    - io_uring: zero iocb->ki_pos for stream file types
+    - veth: ensure skb entering GRO are not cloned.
+    - net: stmmac: ptp: fix potentially overflowing expression
+    - net: bridge: Use array_size() helper in copy_to_user()
+    - net: bridge: fix ioctl old_deviceless bridge argument
+    - r8152: fix the force speed doesn't work for RTL8156
+    - net: stmmac: dwmac-visconti: Fix value of ETHER_CLK_SEL_FREQ_SEL_2P5M
+    - pinctrl: bcm2835: Change init order for gpio hogs
+    - hwmon: (lm90) Fix usage of CONFIG2 register in detect function
+    - hwmon: (lm90) Prevent integer overflow/underflow in hysteresis calculations
+    - hwmon: (lm90) Introduce flag indicating extended temperature support
+    - hwmon: (lm90) Add basic support for TI TMP461
+    - hwmon: (lm90) Drop critical attribute support for MAX6654
+    - ARM: 9160/1: NOMMU: Reload __secondary_data after PROCINFO_INITFUNC
+    - uapi: Fix undefined __always_inline on non-glibc systems
+    - compiler.h: Fix annotation macro misplacement with Clang
+    - platform/x86/intel: Remove X86_PLATFORM_DRIVERS_INTEL
+    - kernel/crash_core: suppress unknown crashkernel parameter warning
+    - Revert "x86/boot: Pull up cmdline preparation and early param parsing"
+    - x86/boot: Move EFI range reservation after cmdline parsing
+    - ALSA: jack: Check the return value of kstrdup()
+    - ALSA: drivers: opl3: Fix incorrect use of vp->state
+    - ALSA: rawmidi - fix the uninitalized user_pversion
+    - ALSA: hda/hdmi: Disable silent stream on GLK
+    - ALSA: hda/realtek: Amp init fixup for HP ZBook 15 G6
+    - ALSA: hda/realtek: Add new alc285-hp-amp-init model
+    - ALSA: hda/realtek: fix mute/micmute LEDs for a HP ProBook
+    - ALSA: hda/realtek: Fix quirk for Clevo NJ51CU
+    - ASoC: meson: aiu: Move AIU_I2S_MISC hold setting to aiu-fifo-i2s
+    - ASoC: tegra: Add DAPM switches for headphones and mic jack
+    - ASoC: tegra: Restore headphones jack name on Nyan Big
+    - Input: atmel_mxt_ts - fix double free in mxt_read_info_block
+    - ipmi: bail out if init_srcu_struct fails
+    - ipmi: ssif: initialize ssif_info->client early
+    - ipmi: fix initialization when workqueue allocation fails
+    - parisc: Correct completer in lws start
+    - parisc: Fix mask used to select futex spinlock
+    - tee: handle lookup of shm with reference count 0
+    - x86/pkey: Fix undefined behaviour with PKRU_WD_BIT
+    - platform/x86: amd-pmc: only use callbacks for suspend
+    - platform/x86: intel_pmc_core: fix memleak on registration failure
+    - KVM: x86: Always set kvm_run->if_flag
+    - KVM: x86/mmu: Don't advance iterator after restart due to yielding
+    - KVM: nVMX: Synthesize TRIPLE_FAULT for L2 if emulation is required
+    - KVM: VMX: Always clear vmx->fail on emulation_required
+    - KVM: VMX: Wake vCPU when delivering posted IRQ even if vCPU == this vCPU
+    - pinctrl: stm32: consider the GPIO offset to expose all the GPIO lines
+    - gpio: dln2: Fix interrupts when replugging the device
+    - mmc: sdhci-tegra: Fix switch to HS400ES mode
+    - mmc: meson-mx-sdhc: Set MANUAL_STOP for multi-block SDIO commands
+    - mmc: core: Disable card detect during shutdown
+    - mmc: mmci: stm32: clear DLYB_CR after sending tuning command
+    - ARM: 9169/1: entry: fix Thumb2 bug in iWMMXt exception handling
+    - ksmbd: fix error code in ndr_read_int32()
+    - ksmbd: fix uninitialized symbol 'pntsd_size'
+    - ksmbd: disable SMB2_GLOBAL_CAP_ENCRYPTION for SMB 3.1.1
+    - mac80211: fix locking in ieee80211_start_ap error path
+    - mm: mempolicy: fix THP allocations escaping mempolicy restrictions
+    - mm, hwpoison: fix condition in free hugetlb page path
+    - mm/hwpoison: clear MF_COUNT_INCREASED before retrying get_any_page()
+    - mm/damon/dbgfs: protect targets destructions with kdamond_lock
+    - tee: optee: Fix incorrect page free bug
+    - f2fs: fix to do sanity check on last xattr entry in __f2fs_setxattr()
+    - netfs: fix parameter of cleanup()
+    - KVM: VMX: Fix stale docs for kvm-intel.emulate_invalid_guest_state
+    - arm64: dts: lx2160a: fix scl-gpios property name
+    - kfence: fix memory leak when cat kfence objects
+    - Input: iqs626a - prohibit inlining of channel parsing functions
+    - Input: elants_i2c - do not check Remark ID on eKTH3900/eKTH5312
+    - Input: goodix - add id->model mapping for the "9111" model
+    - ASoC: tas2770: Fix setting of high sample rates
+    - ASoC: SOF: Intel: pci-tgl: add new ADL-P variant
+    - ASoC: SOF: Intel: pci-tgl: add ADL-N support
+    - ASoC: rt5682: fix the wrong jack type detected
+    - pinctrl: mediatek: fix global-out-of-bounds issue
+    - hwmom: (lm90) Fix citical alarm status for MAX6680/MAX6681
+    - hwmon: (lm90) Do not report 'busy' status bit as alarm
+    - r8152: sync ocp base
+    - ax25: NPD bug when detaching AX25 device
+    - hamradio: defer ax25 kfree after unregister_netdev
+    - hamradio: improve the incomplete fix to avoid NPD
+    - tun: avoid double free in tun_free_netdev
+    - phonet/pep: refuse to enable an unbound pipe
+    - Linux 5.15.12
+
+  * Thinkpad E14 Gen2: Kernel panic with trackpad and trackpoint enabled
+    (LP: #1945590) // Jammy update: v5.15.12 upstream stable release
+    (LP: #1956305)
+    - Input: elantech - fix stack out of bound access in
+      elantech_change_report_id()
+
+  * Jammy update: v5.15.11 upstream stable release (LP: #1956302)
+    - reset: tegra-bpmp: Revert Handle errors in BPMP response
+    - KVM: VMX: clear vmx_x86_ops.sync_pir_to_irr if APICv is disabled
+    - KVM: selftests: Make sure kvm_create_max_vcpus test won't hit RLIMIT_NOFILE
+    - KVM: downgrade two BUG_ONs to WARN_ON_ONCE
+    - x86/kvm: remove unused ack_notifier callbacks
+    - KVM: X86: Fix tlb flush for tdp in kvm_invalidate_pcid()
+    - mac80211: fix rate control for retransmitted frames
+    - mac80211: fix regression in SSN handling of addba tx
+    - mac80211: mark TX-during-stop for TX in in_reconfig
+    - mac80211: send ADDBA requests using the tid/queue of the aggregation session
+    - mac80211: validate extended element ID is present
+    - firmware: arm_scpi: Fix string overflow in SCPI genpd driver
+    - bpf: Fix kernel address leakage in atomic fetch
+    - bpf, selftests: Add test case for atomic fetch on spilled pointer
+    - bpf: Fix signed bounds propagation after mov32
+    - bpf: Make 32->64 bounds propagation slightly more robust
+    - bpf, selftests: Add test case trying to taint map value pointer
+    - bpf: Fix kernel address leakage in atomic cmpxchg's r0 aux reg
+    - bpf, selftests: Update test case for atomic cmpxchg on r0 with pointer
+    - vduse: fix memory corruption in vduse_dev_ioctl()
+    - vduse: check that offset is within bounds in get_config()
+    - virtio_ring: Fix querying of maximum DMA mapping size for virtio device
+    - vdpa: check that offsets are within bounds
+    - s390/entry: fix duplicate tracking of irq nesting level
+    - recordmcount.pl: look for jgnop instruction as well as bcrl on s390
+    - arm64: dts: ten64: remove redundant interrupt declaration for gpio-keys
+    - ceph: fix up non-directory creation in SGID directories
+    - dm btree remove: fix use after free in rebalance_children()
+    - audit: improve robustness of the audit queue handling
+    - btrfs: convert latest_bdev type to btrfs_device and rename
+    - btrfs: use latest_dev in btrfs_show_devname
+    - btrfs: update latest_dev when we create a sprout device
+    - btrfs: remove stale comment about the btrfs_show_devname
+    - scsi: ufs: core: Retry START_STOP on UNIT_ATTENTION
+    - arm64: dts: rockchip: remove mmc-hs400-enhanced-strobe from rk3399-khadas-
+      edge
+    - arm64: dts: rockchip: fix rk3308-roc-cc vcc-sd supply
+    - arm64: dts: rockchip: fix rk3399-leez-p710 vcc3v3-lan supply
+    - arm64: dts: rockchip: fix audio-supply for Rock Pi 4
+    - arm64: dts: rockchip: fix poweroff on helios64
+    - dmaengine: idxd: add halt interrupt support
+    - dmaengine: idxd: fix calling wq quiesce inside spinlock
+    - mac80211: track only QoS data frames for admission control
+    - tee: amdtee: fix an IS_ERR() vs NULL bug
+    - ceph: fix duplicate increment of opened_inodes metric
+    - ceph: initialize pathlen variable in reconnect_caps_cb
+    - ARM: socfpga: dts: fix qspi node compatible
+    - arm64: dts: imx8mq: remove interconnect property from lcdif
+    - clk: Don't parent clks until the parent is fully registered
+    - soc: imx: Register SoC device only on i.MX boards
+    - iwlwifi: mvm: don't crash on invalid rate w/o STA
+    - virtio: always enter drivers/virtio/
+    - virtio/vsock: fix the transport to work with VMADDR_CID_ANY
+    - vdpa: Consider device id larger than 31
+    - Revert "drm/fb-helper: improve DRM fbdev emulation device names"
+    - selftests: net: Correct ping6 expected rc from 2 to 1
+    - s390/kexec_file: fix error handling when applying relocations
+    - sch_cake: do not call cake_destroy() from cake_init()
+    - inet_diag: fix kernel-infoleak for UDP sockets
+    - netdevsim: don't overwrite read only ethtool parms
+    - selftests: icmp_redirect: pass xfail=0 to log_test()
+    - net: hns3: fix use-after-free bug in hclgevf_send_mbx_msg
+    - net: hns3: fix race condition in debugfs
+    - selftests: Add duplicate config only for MD5 VRF tests
+    - selftests: Fix raw socket bind tests with VRF
+    - selftests: Fix IPv6 address bind tests
+    - dmaengine: idxd: fix missed completion on abort path
+    - dmaengine: st_fdma: fix MODULE_ALIAS
+    - drm: simpledrm: fix wrong unit with pixel clock
+    - net/sched: sch_ets: don't remove idle classes from the round-robin list
+    - selftests/net: toeplitz: fix udp option
+    - net: dsa: mv88e6xxx: Unforce speed & duplex in mac_link_down()
+    - selftest/net/forwarding: declare NETIFS p9 p10
+    - mptcp: never allow the PM to close a listener subflow
+    - drm/ast: potential dereference of null pointer
+    - drm/i915/display: Fix an unsigned subtraction which can never be negative.
+    - mac80211: agg-tx: don't schedule_and_wake_txq() under sta->lock
+    - cfg80211: Acquire wiphy mutex on regulatory work
+    - mac80211: fix lookup when adding AddBA extension element
+    - net: stmmac: fix tc flower deletion for VLAN priority Rx steering
+    - flow_offload: return EOPNOTSUPP for the unsupported mpls action type
+    - rds: memory leak in __rds_conn_create()
+    - ice: Use div64_u64 instead of div_u64 in adjfine
+    - ice: Don't put stale timestamps in the skb
+    - drm/amd/display: Set exit_optimized_pwr_state for DCN31
+    - drm/amd/pm: fix a potential gpu_metrics_table memory leak
+    - mptcp: remove tcp ulp setsockopt support
+    - mptcp: clear 'kern' flag from fallback sockets
+    - mptcp: fix deadlock in __mptcp_push_pending()
+    - soc/tegra: fuse: Fix bitwise vs. logical OR warning
+    - igb: Fix removal of unicast MAC filters of VFs
+    - igbvf: fix double free in `igbvf_probe`
+    - igc: Fix typo in i225 LTR functions
+    - ixgbe: Document how to enable NBASE-T support
+    - ixgbe: set X550 MDIO speed before talking to PHY
+    - netdevsim: Zero-initialize memory for new map's value in function
+      nsim_bpf_map_alloc
+    - net/packet: rx_owner_map depends on pg_vec
+    - net: stmmac: dwmac-rk: fix oob read in rk_gmac_setup
+    - sfc_ef100: potential dereference of null pointer
+    - dsa: mv88e6xxx: fix debug print for SPEED_UNFORCED
+    - net: Fix double 0x prefix print in SKB dump
+    - net/smc: Prevent smc_release() from long blocking
+    - net: systemport: Add global locking for descriptor lifecycle
+    - sit: do not call ipip6_dev_free() from sit_init_net()
+    - afs: Fix mmap
+    - arm64: kexec: Fix missing error code 'ret' warning in load_other_segments()
+    - bpf: Fix extable fixup offset.
+    - bpf, selftests: Fix racing issue in btf_skc_cls_ingress test
+    - powerpc/85xx: Fix oops when CONFIG_FSL_PMC=n
+    - USB: gadget: bRequestType is a bitfield, not a enum
+    - Revert "usb: early: convert to readl_poll_timeout_atomic()"
+    - KVM: x86: Drop guest CPUID check for host initiated writes to
+      MSR_IA32_PERF_CAPABILITIES
+    - tty: n_hdlc: make n_hdlc_tty_wakeup() asynchronous
+    - USB: NO_LPM quirk Lenovo USB-C to Ethernet Adapher(RTL8153-04)
+    - usb: dwc2: fix STM ID/VBUS detection startup delay in dwc2_driver_probe
+    - PCI/MSI: Clear PCI_MSIX_FLAGS_MASKALL on error
+    - PCI/MSI: Mask MSI-X vectors only on success
+    - usb: xhci-mtk: fix list_del warning when enable list debug
+    - usb: xhci: Extend support for runtime power management for AMD's Yellow
+      carp.
+    - usb: cdnsp: Fix incorrect status for control request
+    - usb: cdnsp: Fix incorrect calling of cdnsp_died function
+    - usb: cdnsp: Fix issue in cdnsp_log_ep trace event
+    - usb: cdnsp: Fix lack of spin_lock_irqsave/spin_lock_restore
+    - usb: typec: tcpm: fix tcpm unregister port but leave a pending timer
+    - usb: gadget: u_ether: fix race in setting MAC address in setup phase
+    - USB: serial: cp210x: fix CP2105 GPIO registration
+    - USB: serial: option: add Telit FN990 compositions
+    - selinux: fix sleeping function called from invalid context
+    - btrfs: fix memory leak in __add_inode_ref()
+    - btrfs: fix double free of anon_dev after failure to create subvolume
+    - btrfs: check WRITE_ERR when trying to read an extent buffer
+    - btrfs: fix missing blkdev_put() call in btrfs_scan_one_device()
+    - zonefs: add MODULE_ALIAS_FS
+    - iocost: Fix divide-by-zero on donation from low hweight cgroup
+    - serial: 8250_fintek: Fix garbled text for console
+    - timekeeping: Really make sure wall_to_monotonic isn't positive
+    - cifs: sanitize multiple delimiters in prepath
+    - locking/rtmutex: Fix incorrect condition in rtmutex_spin_on_owner()
+    - riscv: dts: unleashed: Add gpio card detect to mmc-spi-slot
+    - riscv: dts: unmatched: Add gpio card detect to mmc-spi-slot
+    - perf inject: Fix segfault due to close without open
+    - perf inject: Fix segfault due to perf_data__fd() without open
+    - libata: if T_LENGTH is zero, dma direction should be DMA_NONE
+    - powerpc/module_64: Fix livepatching for RO modules
+    - drm/amdgpu: correct register access for RLC_JUMP_TABLE_RESTORE
+    - drm/amdgpu: don't override default ECO_BITs setting
+    - drm/amd/pm: fix reading SMU FW version from amdgpu_firmware_info on YC
+    - Revert "can: m_can: remove support for custom bit timing"
+    - can: m_can: make custom bittiming fields const
+    - can: m_can: pci: use custom bit timings for Elkhart Lake
+    - ARM: dts: imx6ull-pinfunc: Fix CSI_DATA07__ESAI_TX0 pad name
+    - xsk: Do not sleep in poll() when need_wakeup set
+    - mptcp: add missing documented NL params
+    - bpf, x64: Factor out emission of REX byte in more cases
+    - bpf: Fix extable address check.
+    - USB: core: Make do_proc_control() and do_proc_bulk() killable
+    - media: mxl111sf: change mutex_init() location
+    - fuse: annotate lock in fuse_reverse_inval_entry()
+    - ovl: fix warning in ovl_create_real()
+    - scsi: scsi_debug: Don't call kcalloc() if size arg is zero
+    - scsi: scsi_debug: Fix type in min_t to avoid stack OOB
+    - scsi: scsi_debug: Sanity check block descriptor length in resp_mode_select()
+    - io-wq: remove spurious bit clear on task_work addition
+    - io-wq: check for wq exit after adding new worker task_work
+    - rcu: Mark accesses to rcu_state.n_force_qs
+    - io-wq: drop wqe lock before creating new worker
+    - bus: ti-sysc: Fix variable set but not used warning for reinit_modules
+    - selftests/damon: test debugfs file reads/writes with huge count
+    - Revert "xsk: Do not sleep in poll() when need_wakeup set"
+    - xen/blkfront: harden blkfront against event channel storms
+    - xen/netfront: harden netfront against event channel storms
+    - xen/console: harden hvc_xen against event channel storms
+    - xen/netback: fix rx queue stall detection
+    - xen/netback: don't queue unlimited number of packages
+    - Linux 5.15.11
+
+  * Jammy update: v5.15.10 upstream stable release (LP: #1956301)
+    - nfc: fix segfault in nfc_genl_dump_devices_done
+    - hwmon: (corsair-psu) fix plain integer used as NULL pointer
+    - RDMA: Fix use-after-free in rxe_queue_cleanup
+    - RDMA/mlx5: Fix releasing unallocated memory in dereg MR flow
+    - mtd: rawnand: Fix nand_erase_op delay
+    - mtd: rawnand: Fix nand_choose_best_timings() on unsupported interface
+    - inet: use #ifdef CONFIG_SOCK_RX_QUEUE_MAPPING consistently
+    - dt-bindings: media: nxp,imx7-mipi-csi2: Drop bad if/then schema
+    - clk: qcom: sm6125-gcc: Swap ops of ice and apps on sdcc1
+    - perf bpf_skel: Do not use typedef to avoid error on old clang
+    - netfs: Fix lockdep warning from taking sb_writers whilst holding mmap_lock
+    - RDMA/irdma: Fix a user-after-free in add_pble_prm
+    - RDMA/irdma: Fix a potential memory allocation issue in
+      'irdma_prm_add_pble_mem()'
+    - RDMA/irdma: Report correct WC errors
+    - RDMA/irdma: Don't arm the CQ more than two times if no CE for this CQ
+    - ice: fix FDIR init missing when reset VF
+    - vmxnet3: fix minimum vectors alloc issue
+    - i2c: virtio: fix completion handling
+    - drm/msm: Fix null ptr access msm_ioctl_gem_submit()
+    - drm/msm/a6xx: Fix uinitialized use of gpu_scid
+    - drm/msm/dsi: set default num_data_lanes
+    - drm/msm/dp: Avoid unpowered AUX xfers that caused crashes
+    - KVM: arm64: Save PSTATE early on exit
+    - s390/test_unwind: use raw opcode instead of invalid instruction
+    - Revert "tty: serial: fsl_lpuart: drop earlycon entry for i.MX8QXP"
+    - net/mlx4_en: Update reported link modes for 1/10G
+    - loop: Use pr_warn_once() for loop_control_remove() warning
+    - ALSA: hda: Add Intel DG2 PCI ID and HDMI codec vid
+    - ALSA: hda/hdmi: fix HDA codec entry table order for ADL-P
+    - parisc/agp: Annotate parisc agp init functions with __init
+    - i2c: rk3x: Handle a spurious start completion interrupt flag
+    - net: netlink: af_netlink: Prevent empty skb by adding a check on len.
+    - drm/amdgpu: cancel the correct hrtimer on exit
+    - drm/amdgpu: check atomic flag to differeniate with legacy path
+    - drm/amd/display: Fix for the no Audio bug with Tiled Displays
+    - drm/amdkfd: fix double free mem structure
+    - drm/amd/display: add connector type check for CRC source set
+    - drm/amdkfd: process_info lock not needed for svm
+    - tracing: Fix a kmemleak false positive in tracing_map
+    - staging: most: dim2: use device release method
+    - fuse: make sure reclaim doesn't write the inode
+    - perf inject: Fix itrace space allowed for new attributes
+    - Linux 5.15.10
+
+  * Jammy update: v5.15.9 upstream stable release (LP: #1955161)
+    - netfilter: selftest: conntrack_vrf.sh: fix file permission
+    - Linux 5.15.9
+
+  * [SRU][I/J/OEM-5.13/OEM-5.14] Fix pci port lost when hotplug dock
+    (LP: #1954646)
+    - PCI: Re-enable Downstream Port LTR after reset or hotplug
+
+  * Add support for NVIDIA EC backlight (LP: #1953286)
+    - platform/x86: Add driver for ACPI WMAA EC-based backlight control
+    - platform/x86: Remove "WMAA" from identifier names in wmaa-backlight-wmi.c
+    - platform/x86: Rename wmaa-backlight-wmi to nvidia-wmi-ec-backlight
+    - [Config] NVIDIA_WMI_EC_BACKLIGHT=m
+
+  * Improve USB Type-C support (LP: #1950974)
+    - usb: typec: ucsi: Always cancel the command if PPM reports BUSY condition
+    - usb: typec: ucsi: Don't stop alt mode registration on busy condition
+    - usb: typec: ucsi: Add polling mechanism for partner tasks like alt mode
+      checking
+    - usb: typec: ucsi: acpi: Reduce the command completion timeout
+    - usb: typec: ucsi: Check the partner alt modes always if there is PD contract
+    - usb: typec: ucsi: Read the PDOs in separate work
+    - usb: typec: ucsi: Better fix for missing unplug events issue
+
+  *  Fix power button wakeup with shared IRQs on AMD platforms (LP: #1953540)
+    - pinctrl: amd: Fix wakeups when IRQ is shared with SCI
+
+  * AMD: Suspend not working when some cores are disabled through cpufreq
+    (LP: #1954930)
+    - ACPI: processor idle: Allow playing dead in C3 state
+
+  * Jammy update: v5.15.8 upstream stable release (LP: #1954931)
+    - Revert "UBUNTU: SAUCE: selftests: fib_tests: assign address to dummy1 for
+      rp_filter tests"
+    - usb: gadget: uvc: fix multiple opens
+    - HID: quirks: Add quirk for the Microsoft Surface 3 type-cover
+    - HID: google: add eel USB id
+    - HID: intel-ish-hid: ipc: only enable IRQ wakeup when requested
+    - HID: add hid_is_usb() function to make it simpler for USB detection
+    - HID: add USB_HID dependancy to hid-prodikeys
+    - HID: add USB_HID dependancy to hid-chicony
+    - HID: add USB_HID dependancy on some USB HID drivers
+    - HID: bigbenff: prevent null pointer dereference
+    - HID: wacom: fix problems when device is not a valid USB device
+    - HID: check for valid USB device for many HID drivers
+    - mtd: dataflash: Add device-tree SPI IDs
+    - mmc: spi: Add device-tree SPI IDs
+    - HID: sony: fix error path in probe
+    - HID: Ignore battery for Elan touchscreen on Asus UX550VE
+    - platform/x86/intel: hid: add quirk to support Surface Go 3
+    - nft_set_pipapo: Fix bucket load in AVX2 lookup routine for six 8-bit groups
+    - IB/hfi1: Insure use of smp_processor_id() is preempt disabled
+    - IB/hfi1: Fix early init panic
+    - IB/hfi1: Fix leak of rcvhdrtail_dummy_kvaddr
+    - can: kvaser_usb: get CAN clock frequency from device
+    - can: kvaser_pciefd: kvaser_pciefd_rx_error_frame(): increase correct
+      stats->{rx,tx}_errors counter
+    - can: sja1000: fix use after free in ems_pcmcia_add_card()
+    - can: pch_can: pch_can_rx_normal: fix use after free
+    - can: m_can: m_can_read_fifo: fix memory leak in error branch
+    - can: m_can: pci: fix incorrect reference clock rate
+    - can: m_can: pci: fix iomap_read_fifo() and iomap_write_fifo()
+    - can: m_can: Disable and ignore ELO interrupt
+    - net: dsa: mv88e6xxx: fix "don't use PHY_DETECT on internal PHY's"
+    - net: dsa: mv88e6xxx: allow use of PHYs on CPU and DSA ports
+    - x86/sme: Explicitly map new EFI memmap table as encrypted
+    - platform/x86: amd-pmc: Fix s2idle failures on certain AMD laptops
+    - nfc: fix potential NULL pointer deref in nfc_genl_dump_ses_done
+    - selftests: netfilter: add a vrf+conntrack testcase
+    - vrf: don't run conntrack on vrf with !dflt qdisc
+    - bpf, x86: Fix "no previous prototype" warning
+    - bpf, sockmap: Attach map progs to psock early for feature probes
+    - bpf: Make sure bpf_disable_instrumentation() is safe vs preemption.
+    - bpf: Fix the off-by-two error in range markings
+    - ice: ignore dropped packets during init
+    - ethtool: do not perform operations on net devices being unregistered
+    - bonding: make tx_rebalance_counter an atomic
+    - nfp: Fix memory leak in nfp_cpp_area_cache_add()
+    - udp: using datalen to cap max gso segments
+    - netfilter: nft_exthdr: break evaluation if setting TCP option fails
+    - netfilter: conntrack: annotate data-races around ct->timeout
+    - iavf: restore MSI state on reset
+    - iavf: Fix reporting when setting descriptor count
+    - IB/hfi1: Correct guard on eager buffer deallocation
+    - devlink: fix netns refcount leak in devlink_nl_cmd_reload()
+    - net: bcm4908: Handle dma_set_coherent_mask error codes
+    - net: dsa: mv88e6xxx: error handling for serdes_power functions
+    - net: dsa: felix: Fix memory leak in felix_setup_mmio_filtering
+    - net/sched: fq_pie: prevent dismantle issue
+    - net: mvpp2: fix XDP rx queues registering
+    - KVM: x86: Don't WARN if userspace mucks with RCX during string I/O exit
+    - KVM: x86: Ignore sparse banks size for an "all CPUs", non-sparse IPI req
+    - KVM: x86: Wait for IPIs to be delivered when handling Hyper-V TLB flush
+      hypercall
+    - timers: implement usleep_idle_range()
+    - mm/damon/core: fix fake load reports due to uninterruptible sleeps
+    - mm/slub: fix endianness bug for alloc/free_traces attributes
+    - mm: bdi: initialize bdi_min_ratio when bdi is unregistered
+    - ALSA: ctl: Fix copy of updated id with element read/write
+    - ALSA: hda/realtek - Add headset Mic support for Lenovo ALC897 platform
+    - ALSA: hda/realtek: Fix quirk for TongFang PHxTxX1
+    - ALSA: pcm: oss: Fix negative period/buffer sizes
+    - ALSA: pcm: oss: Limit the period size to 16MB
+    - ALSA: pcm: oss: Handle missing errors in snd_pcm_oss_change_params*()
+    - cifs: Fix crash on unload of cifs_arc4.ko
+    - scsi: qla2xxx: Format log strings only if needed
+    - btrfs: clear extent buffer uptodate when we fail to write it
+    - btrfs: fix re-dirty process of tree-log nodes
+    - btrfs: replace the BUG_ON in btrfs_del_root_ref with proper error handling
+    - btrfs: free exchange changeset on failures
+    - perf intel-pt: Fix some PGE (packet generation enable/control flow packets)
+      usage
+    - perf intel-pt: Fix sync state when a PSB (synchronization) packet is found
+    - perf intel-pt: Fix intel_pt_fup_event() assumptions about setting state type
+    - perf intel-pt: Fix state setting when receiving overflow (OVF) packet
+    - perf intel-pt: Fix next 'err' value, walking trace
+    - perf intel-pt: Fix missing 'instruction' events with 'q' option
+    - perf intel-pt: Fix error timestamp setting on the decoder error path
+    - md: fix update super 1.0 on rdev size change
+    - nfsd: fix use-after-free due to delegation race
+    - nfsd: Fix nsfd startup race (again)
+    - tracefs: Have new files inherit the ownership of their parent
+    - selftests: KVM: avoid failures due to reserved HyperTransport region
+    - hwmon: (pwm-fan) Ensure the fan going on in .probe()
+    - mmc: renesas_sdhi: initialize variable properly when tuning
+    - clk: qcom: regmap-mux: fix parent clock lookup
+    - thermal: int340x: Fix VCoRefLow MMIO bit offset for TGL
+    - drm/syncobj: Deal with signalled fences in drm_syncobj_find_fence.
+    - libata: add horkage for ASMedia 1092
+    - io_uring: ensure task_work gets run as part of cancelations
+    - wait: add wake_up_pollfree()
+    - binder: use wake_up_pollfree()
+    - signalfd: use wake_up_pollfree()
+    - aio: keep poll requests on waitqueue until completed
+    - aio: fix use-after-free due to missing POLLFREE handling
+    - tracefs: Set all files to the same group ownership as the mount option
+    - i2c: mpc: Use atomic read and fix break condition
+    - block: fix ioprio_get(IOPRIO_WHO_PGRP) vs setuid(2)
+    - scsi: pm80xx: Do not call scsi_remove_host() in pm8001_alloc()
+    - scsi: scsi_debug: Fix buffer size of REPORT ZONES command
+    - ALSA: usb-audio: Reorder snd_djm_devices[] entries
+    - qede: validate non LSO skb length
+    - PM: runtime: Fix pm_runtime_active() kerneldoc comment
+    - ASoC: rt5682: Fix crash due to out of scope stack vars
+    - ASoC: qdsp6: q6routing: Fix return value from msm_routing_put_audio_mixer
+    - ASoC: codecs: wsa881x: fix return values from kcontrol put
+    - ASoC: codecs: wcd934x: handle channel mappping list correctly
+    - ASoC: codecs: wcd934x: return correct value from mixer put
+    - RDMA/hns: Do not halt commands during reset until later
+    - RDMA/hns: Do not destroy QP resources in the hw resetting phase
+    - hwmon: (dell-smm) Fix warning on /proc/i8k creation error
+    - clk: imx: use module_platform_driver
+    - clk: qcom: clk-alpha-pll: Don't reconfigure running Trion
+    - i40e: Fix failed opcode appearing if handling messages from VF
+    - i40e: Fix pre-set max number of queues for VF
+    - mtd: rawnand: fsmc: Take instruction delay into account
+    - mtd: rawnand: fsmc: Fix timing computation
+    - bpf, sockmap: Re-evaluate proto ops when psock is removed from sockmap
+    - i40e: Fix NULL pointer dereference in i40e_dbg_dump_desc
+    - Revert "PCI: aardvark: Fix support for PCI_ROM_ADDRESS1 on emulated bridge"
+    - drm/amd/display: Fix DPIA outbox timeout after S3/S4/reset
+    - perf tools: Fix SMT detection fast read path
+    - Documentation/locking/locktypes: Update migrate_disable() bits.
+    - dt-bindings: net: Reintroduce PHY no lane swap binding
+    - tools build: Remove needless libpython-version feature check that breaks
+      test-all fast path
+    - net: cdc_ncm: Allow for dwNtbOutMaxSize to be unset or zero
+    - net: altera: set a couple error code in probe()
+    - net: fec: only clear interrupt of handling queue in fec_enet_rx_queue()
+    - net, neigh: clear whole pneigh_entry at alloc time
+    - net/qla3xxx: fix an error code in ql_adapter_up()
+    - selftests/fib_tests: Rework fib_rp_filter_test()
+    - USB: gadget: detect too-big endpoint 0 requests
+    - USB: gadget: zero allocate endpoint 0 buffers
+    - Revert "usb: dwc3: dwc3-qcom: Enable tx-fifo-resize property by default"
+    - usb: core: config: fix validation of wMaxPacketValue entries
+    - usb: core: config: using bit mask instead of individual bits
+    - xhci: avoid race between disable slot command and host runtime suspend
+    - iio: gyro: adxrs290: fix data signedness
+    - iio: trigger: Fix reference counting
+    - iio: trigger: stm32-timer: fix MODULE_ALIAS
+    - iio: stk3310: Don't return error code in interrupt handler
+    - iio: mma8452: Fix trigger reference couting
+    - iio: ltr501: Don't return error code in trigger handler
+    - iio: kxsd9: Don't return error code in trigger handler
+    - iio: itg3200: Call iio_trigger_notify_done() on error
+    - iio: dln2-adc: Fix lockdep complaint
+    - iio: dln2: Check return value of devm_iio_trigger_register()
+    - iio: at91-sama5d2: Fix incorrect sign extension
+    - iio: adc: stm32: fix a current leak by resetting pcsel before disabling vdda
+    - iio: adc: axp20x_adc: fix charging current reporting on AXP22x
+    - iio: ad7768-1: Call iio_trigger_notify_done() on error
+    - iio: accel: kxcjk-1013: Fix possible memory leak in probe and remove
+    - nvmem: eeprom: at25: fix FRAM byte_len
+    - bus: mhi: pci_generic: Fix device recovery failed issue
+    - bus: mhi: core: Add support for forced PM resume
+    - csky: fix typo of fpu config macro
+    - irqchip/aspeed-scu: Replace update_bits with write_bits.
+    - irqchip/armada-370-xp: Fix return value of armada_370_xp_msi_alloc()
+    - irqchip/armada-370-xp: Fix support for Multi-MSI interrupts
+    - aio: Fix incorrect usage of eventfd_signal_allowed()
+    - irqchip/irq-gic-v3-its.c: Force synchronisation when issuing INVALL
+    - irqchip: nvic: Fix offset for Interrupt Priority Offsets
+    - misc: fastrpc: fix improper packet size calculation
+    - clocksource/drivers/dw_apb_timer_of: Fix probe failure
+    - bpf: Add selftests to cover packet access corner cases
+    - Linux 5.15.8
+
+  * Can't read/write SD card after running CPU offline test in 5.11.0 and 5.13.0
+    (LP: #1951784) // Jammy update: v5.15.8 upstream stable release
+    (LP: #1954931)
+    - misc: rtsx: Avoid mangling IRQ during runtime PM
+
+  * Enable Landlock by default (LP: #1953192)
+    - [Config] Enable Landlock by default
+
+  * Add s0i3 RTC wake up for AMD systems (LP: #1950013)
+    - platform/x86: amd-pmc: Export Idlemask values based on the APU
+    - platform/x86: amd-pmc: adjust arguments for `amd_pmc_send_cmd`
+    - platform/x86: amd-pmc: Add special handling for timer based S0i3 wakeup
+
+  * Fix runtime power management on USB controller with XHCI_RESET_ON_RESUME
+    flag (LP: #1954369)
+    - SAUCE: xhci: Remove CONFIG_USB_DEFAULT_PERSIST to prevent xHCI from runtime
+      suspending
+
+  * Fix System hangs on black screen when reboot (LP: #1949321)
+    - drm/i915/hdmi: convert intel_hdmi_to_dev to intel_hdmi_to_i915
+    - drm/i915: Don't request GMBUS to generate irqs when called while irqs are
+      off
+    - drm/i915/hdmi: Turn DP++ TMDS output buffers back on in encoder->shutdown()
+
+  * require CAP_NET_ADMIN to attach N_HCI ldisc (LP: #1949516)
+    - Bluetooth: hci_ldisc: require CAP_NET_ADMIN to attach N_HCI ldisc
+
+  * mt7921e: Failed to start WM firmware (LP: #1954300)
+    - SAUCE: Bluetooth: btusb: Handle download_firmware failure cases
+    - SAUCE: Bluetooth: btusb: Return error code when getting patch status failed
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Add list of built-in modules to the ABI
+    - [Packaging] abi-check: Process modules.builtin
+    - SAUCE: allow to use __wake_up_pollfree() from GPL modules
+    - [Packaging] enforce xz compression for debs
+    - [Config] update config after v5.15.12
+    - [Packaging] temporarily disable signed v4l2loopback
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 04 Jan 2022 11:22:10 +0100
+
+linux (5.15.0-14.14) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-14.14 -proposed tracker (LP: #1954627)
+
+  * Jammy update: v5.15.7 upstream stable release (LP: #1953731)
+    - ALSA: usb-audio: Restrict rates for the shared clocks
+    - ALSA: usb-audio: Rename early_playback_start flag with lowlatency_playback
+    - ALSA: usb-audio: Disable low-latency playback for free-wheel mode
+    - ALSA: usb-audio: Disable low-latency mode for implicit feedback sync
+    - ALSA: usb-audio: Check available frames for the next packet size
+    - ALSA: usb-audio: Add spinlock to stop_urbs()
+    - ALSA: usb-audio: Improved lowlatency playback support
+    - ALSA: usb-audio: Avoid killing in-flight URBs during draining
+    - ALSA: usb-audio: Fix packet size calculation regression
+    - ALSA: usb-audio: Less restriction for low-latency playback mode
+    - ALSA: usb-audio: Switch back to non-latency mode at a later point
+    - ALSA: usb-audio: Don't start stream for capture at prepare
+    - gfs2: release iopen glock early in evict
+    - gfs2: Fix length of holes reported at end-of-file
+    - powerpc/pseries/ddw: Revert "Extend upper limit for huge DMA window for
+      persistent memory"
+    - powerpc/pseries/ddw: Do not try direct mapping with persistent memory and
+      one window
+    - drm/sun4i: fix unmet dependency on RESET_CONTROLLER for PHY_SUN6I_MIPI_DPHY
+    - mac80211: do not access the IV when it was stripped
+    - mac80211: fix throughput LED trigger
+    - x86/hyperv: Move required MSRs check to initial platform probing
+    - net/smc: Transfer remaining wait queue entries during fallback
+    - atlantic: Fix OOB read and write in hw_atl_utils_fw_rpc_wait
+    - net: return correct error code
+    - pinctrl: qcom: fix unmet dependencies on GPIOLIB for GPIOLIB_IRQCHIP
+    - platform/x86: dell-wmi-descriptor: disable by default
+    - platform/x86: thinkpad_acpi: Add support for dual fan control
+    - platform/x86: thinkpad_acpi: Fix WWAN device disabled issue after S3 deep
+    - s390/setup: avoid using memblock_enforce_memory_limit
+    - btrfs: silence lockdep when reading chunk tree during mount
+    - btrfs: check-integrity: fix a warning on write caching disabled disk
+    - thermal: core: Reset previous low and high trip during thermal zone init
+    - scsi: iscsi: Unblock session then wake up error handler
+    - drm/amd/pm: Remove artificial freq level on Navi1x
+    - drm/amd/amdkfd: Fix kernel panic when reset failed and been triggered again
+    - drm/amd/amdgpu: fix potential memleak
+    - ata: ahci: Add Green Sardine vendor ID as board_ahci_mobile
+    - ata: libahci: Adjust behavior when StorageD3Enable _DSD is set
+    - ethernet: hisilicon: hns: hns_dsaf_misc: fix a possible array overflow in
+      hns_dsaf_ge_srst_by_port()
+    - ipv6: check return value of ipv6_skip_exthdr
+    - net: tulip: de4x5: fix the problem that the array 'lp->phy[8]' may be out of
+      bound
+    - net: ethernet: dec: tulip: de4x5: fix possible array overflows in
+      type3_infoblock()
+    - perf sort: Fix the 'weight' sort key behavior
+    - perf sort: Fix the 'ins_lat' sort key behavior
+    - perf sort: Fix the 'p_stage_cyc' sort key behavior
+    - perf inject: Fix ARM SPE handling
+    - perf hist: Fix memory leak of a perf_hpp_fmt
+    - perf report: Fix memory leaks around perf_tip()
+    - tracing: Don't use out-of-sync va_list in event printing
+    - net/smc: Avoid warning of possible recursive locking
+    - ACPI: Add stubs for wakeup handler functions
+    - net/tls: Fix authentication failure in CCM mode
+    - vrf: Reset IPCB/IP6CB when processing outbound pkts in vrf dev xmit
+    - kprobes: Limit max data_size of the kretprobe instances
+    - ALSA: hda/cs8409: Set PMSG_ON earlier inside cs8409 driver
+    - rt2x00: do not mark device gone on EPROTO errors during start
+    - ipmi: Move remove_work to dedicated workqueue
+    - cpufreq: Fix get_cpu_device() failure in add_cpu_dev_symlink()
+    - iwlwifi: mvm: retry init flow if failed
+    - dma-buf: system_heap: Use 'for_each_sgtable_sg' in pages free flow
+    - s390/pci: move pseudo-MMIO to prevent MIO overlap
+    - fget: check that the fd still exists after getting a ref to it
+    - sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl
+    - sata_fsl: fix warning in remove_proc_entry when rmmod sata_fsl
+    - scsi: lpfc: Fix non-recovery of remote ports following an unsolicited LOGO
+    - scsi: ufs: ufs-pci: Add support for Intel ADL
+    - ipv6: fix memory leak in fib6_rule_suppress
+    - drm/amd/display: Allow DSC on supported MST branch devices
+    - drm/i915/dp: Perform 30ms delay after source OUI write
+    - KVM: fix avic_set_running for preemptable kernels
+    - KVM: Disallow user memslot with size that exceeds "unsigned long"
+    - KVM: x86/mmu: Fix TLB flush range when handling disconnected pt
+    - KVM: Ensure local memslot copies operate on up-to-date arch-specific data
+    - KVM: x86: ignore APICv if LAPIC is not enabled
+    - KVM: nVMX: Emulate guest TLB flush on nested VM-Enter with new vpid12
+    - KVM: nVMX: Flush current VPID (L1 vs. L2) for KVM_REQ_TLB_FLUSH_GUEST
+    - KVM: nVMX: Abide to KVM_REQ_TLB_FLUSH_GUEST request on nested vmentry/vmexit
+    - KVM: VMX: prepare sync_pir_to_irr for running with APICv disabled
+    - KVM: x86: Use a stable condition around all VT-d PI paths
+    - KVM: MMU: shadow nested paging does not have PKU
+    - KVM: arm64: Avoid setting the upper 32 bits of TCR_EL2 and CPTR_EL2 to 1
+    - KVM: X86: Use vcpu->arch.walk_mmu for kvm_mmu_invlpg()
+    - KVM: x86: check PIR even for vCPUs with disabled APICv
+    - tracing/histograms: String compares should not care about signed values
+    - net: dsa: mv88e6xxx: Fix application of erratum 4.8 for 88E6393X
+    - net: dsa: mv88e6xxx: Drop unnecessary check in
+      mv88e6393x_serdes_erratum_4_6()
+    - net: dsa: mv88e6xxx: Save power by disabling SerDes trasmitter and receiver
+    - net: dsa: mv88e6xxx: Add fix for erratum 5.2 of 88E6393X family
+    - net: dsa: mv88e6xxx: Fix inband AN for 2500base-x on 88E6393X family
+    - net: dsa: mv88e6xxx: Link in pcs_get_state() if AN is bypassed
+    - wireguard: selftests: increase default dmesg log size
+    - wireguard: allowedips: add missing __rcu annotation to satisfy sparse
+    - wireguard: selftests: actually test for routing loops
+    - wireguard: selftests: rename DEBUG_PI_LIST to DEBUG_PLIST
+    - wireguard: device: reset peer src endpoint when netns exits
+    - wireguard: receive: use ring buffer for incoming handshakes
+    - wireguard: receive: drop handshakes if queue lock is contended
+    - wireguard: ratelimiter: use kvcalloc() instead of kvzalloc()
+    - i2c: stm32f7: flush TX FIFO upon transfer errors
+    - i2c: stm32f7: recover the bus on access timeout
+    - i2c: stm32f7: stop dma transfer in case of NACK
+    - i2c: cbus-gpio: set atomic transfer callback
+    - natsemi: xtensa: fix section mismatch warnings
+    - tcp: fix page frag corruption on page fault
+    - net: qlogic: qlcnic: Fix a NULL pointer dereference in
+      qlcnic_83xx_add_rings()
+    - net: mpls: Fix notifications when deleting a device
+    - siphash: use _unaligned version by default
+    - arm64: ftrace: add missing BTIs
+    - iwlwifi: fix warnings produced by kernel debug options
+    - net/mlx5e: IPsec: Fix Software parser inner l3 type setting in case of
+      encapsulation
+    - net/mlx4_en: Fix an use-after-free bug in mlx4_en_try_alloc_resources()
+    - selftests: net: Correct case name
+    - net: dsa: b53: Add SPI ID table
+    - mt76: mt7915: fix NULL pointer dereference in mt7915_get_phy_mode
+    - ASoC: tegra: Fix wrong value type in ADMAIF
+    - ASoC: tegra: Fix wrong value type in I2S
+    - ASoC: tegra: Fix wrong value type in DMIC
+    - ASoC: tegra: Fix wrong value type in DSPK
+    - ASoC: tegra: Fix kcontrol put callback in ADMAIF
+    - ASoC: tegra: Fix kcontrol put callback in I2S
+    - ASoC: tegra: Fix kcontrol put callback in DMIC
+    - ASoC: tegra: Fix kcontrol put callback in DSPK
+    - ASoC: tegra: Fix kcontrol put callback in AHUB
+    - rxrpc: Fix rxrpc_peer leak in rxrpc_look_up_bundle()
+    - rxrpc: Fix rxrpc_local leak in rxrpc_lookup_peer()
+    - ALSA: intel-dsp-config: add quirk for CML devices based on ES8336 codec
+    - net: stmmac: Avoid DMA_CHAN_CONTROL write if no Split Header support
+    - net: usb: lan78xx: lan78xx_phy_init(): use PHY_POLL instead of "0" if no IRQ
+      is available
+    - net: marvell: mvpp2: Fix the computation of shared CPUs
+    - dpaa2-eth: destroy workqueue at the end of remove function
+    - octeontx2-af: Fix a memleak bug in rvu_mbox_init()
+    - net: annotate data-races on txq->xmit_lock_owner
+    - ipv4: convert fib_num_tclassid_users to atomic_t
+    - net/smc: fix wrong list_del in smc_lgr_cleanup_early
+    - net/rds: correct socket tunable error in rds_tcp_tune()
+    - net/smc: Keep smc_close_final rc during active close
+    - drm/msm/a6xx: Allocate enough space for GMU registers
+    - drm/msm: Do hw_init() before capturing GPU state
+    - drm/vc4: kms: Wait for the commit before increasing our clock rate
+    - drm/vc4: kms: Fix return code check
+    - drm/vc4: kms: Add missing drm_crtc_commit_put
+    - drm/vc4: kms: Clear the HVS FIFO commit pointer once done
+    - drm/vc4: kms: Don't duplicate pending commit
+    - drm/vc4: kms: Fix previous HVS commit wait
+    - atlantic: Increase delay for fw transactions
+    - atlatnic: enable Nbase-t speeds with base-t
+    - atlantic: Fix to display FW bundle version instead of FW mac version.
+    - atlantic: Add missing DIDs and fix 115c.
+    - Remove Half duplex mode speed capabilities.
+    - atlantic: Fix statistics logic for production hardware
+    - atlantic: Remove warn trace message.
+    - KVM: x86/mmu: Skip tlb flush if it has been done in zap_gfn_range()
+    - KVM: x86/mmu: Pass parameter flush as false in
+      kvm_tdp_mmu_zap_collapsible_sptes()
+    - drm/msm/devfreq: Fix OPP refcnt leak
+    - drm/msm: Fix mmap to include VM_IO and VM_DONTDUMP
+    - drm/msm: Fix wait_fence submitqueue leak
+    - drm/msm: Restore error return on invalid fence
+    - ASoC: rk817: Add module alias for rk817-codec
+    - iwlwifi: Fix memory leaks in error handling path
+    - KVM: X86: Fix when shadow_root_level=5 && guest root_level<4
+    - KVM: SEV: initialize regions_list of a mirror VM
+    - net/mlx5e: Fix missing IPsec statistics on uplink representor
+    - net/mlx5: Move MODIFY_RQT command to ignore list in internal error state
+    - net/mlx5: E-switch, Respect BW share of the new group
+    - net/mlx5: E-Switch, fix single FDB creation on BlueField
+    - net/mlx5: E-Switch, Check group pointer before reading bw_share value
+    - KVM: x86/pmu: Fix reserved bits for AMD PerfEvtSeln register
+    - KVM: VMX: Set failure code in prepare_vmcs02()
+    - mctp: Don't let RTM_DELROUTE delete local routes
+    - Revert "drm/i915: Implement Wa_1508744258"
+    - io-wq: don't retry task_work creation failure on fatal conditions
+    - x86/sev: Fix SEV-ES INS/OUTS instructions for word, dword, and qword
+    - x86/entry: Add a fence for kernel entry SWAPGS in paranoid_entry()
+    - x86/entry: Use the correct fence macro after swapgs in kernel CR3
+    - x86/xen: Add xenpv_restore_regs_and_return_to_usermode()
+    - preempt/dynamic: Fix setup_preempt_mode() return value
+    - sched/uclamp: Fix rq->uclamp_max not set on first enqueue
+    - KVM: SEV: Return appropriate error codes if SEV-ES scratch setup fails
+    - KVM: x86/mmu: Rename slot_handle_leaf to slot_handle_level_4k
+    - KVM: x86/mmu: Remove spurious TLB flushes in TDP MMU zap collapsible path
+    - net/mlx5e: Rename lro_timeout to packet_merge_timeout
+    - net/mlx5e: Rename TIR lro functions to TIR packet merge functions
+    - net/mlx5e: Sync TIR params updates against concurrent create/modify
+    - serial: 8250_bcm7271: UART errors after resuming from S2
+    - parisc: Fix KBUILD_IMAGE for self-extracting kernel
+    - parisc: Fix "make install" on newer debian releases
+    - parisc: Mark cr16 CPU clocksource unstable on all SMP machines
+    - vgacon: Propagate console boot parameters before calling `vc_resize'
+    - xhci: Fix commad ring abort, write all 64 bits to CRCR register.
+    - USB: NO_LPM quirk Lenovo Powered USB-C Travel Hub
+    - usb: typec: tcpm: Wait in SNK_DEBOUNCED until disconnect
+    - usb: cdns3: gadget: fix new urb never complete if ep cancel previous
+      requests
+    - usb: cdnsp: Fix a NULL pointer dereference in cdnsp_endpoint_init()
+    - x86/tsc: Add a timer to make sure TSC_adjust is always checked
+    - x86/tsc: Disable clocksource watchdog for TSC on qualified platorms
+    - x86/64/mm: Map all kernel memory into trampoline_pgd
+    - tty: serial: msm_serial: Deactivate RX DMA for polling support
+    - serial: pl011: Add ACPI SBSA UART match id
+    - serial: tegra: Change lower tolerance baud rate limit for tegra20 and
+      tegra30
+    - serial: core: fix transmit-buffer reset and memleak
+    - serial: 8250_pci: Fix ACCES entries in pci_serial_quirks array
+    - serial: 8250_pci: rewrite pericom_do_set_divisor()
+    - serial: 8250: Fix RTS modem control while in rs485 mode
+    - serial: liteuart: Fix NULL pointer dereference in ->remove()
+    - serial: liteuart: fix use-after-free and memleak on unbind
+    - serial: liteuart: fix minor-number leak on probe errors
+    - ipmi: msghandler: Make symbol 'remove_work_wq' static
+    - Linux 5.15.7
+
+  * Updates to ib_peer_memory requested by Nvidia (LP: #1947206)
+    - SAUCE: RDMA/core: Updated ib_peer_memory
+    - SAUCE: RDMA/core: ib_peer_memory fix build errors
+
+  * Jammy update: v5.15.6 upstream stable release (LP: #1953370)
+    - scsi: sd: Fix sd_do_mode_sense() buffer length handling
+    - ACPI: Get acpi_device's parent from the parent field
+    - ACPI: CPPC: Add NULL pointer check to cppc_get_perf()
+    - USB: serial: pl2303: fix GC type detection
+    - USB: serial: option: add Telit LE910S1 0x9200 composition
+    - USB: serial: option: add Fibocom FM101-GL variants
+    - usb: dwc2: gadget: Fix ISOC flow for elapsed frames
+    - usb: dwc2: hcd_queue: Fix use of floating point literal
+    - usb: dwc3: leave default DMA for PCI devices
+    - usb: dwc3: core: Revise GHWPARAMS9 offset
+    - usb: dwc3: gadget: Ignore NoStream after End Transfer
+    - usb: dwc3: gadget: Check for L1/L2/U3 for Start Transfer
+    - usb: dwc3: gadget: Fix null pointer exception
+    - net: usb: Correct PHY handling of smsc95xx
+    - net: nexthop: fix null pointer dereference when IPv6 is not enabled
+    - usb: chipidea: ci_hdrc_imx: fix potential error pointer dereference in probe
+    - usb: typec: fusb302: Fix masking of comparator and bc_lvl interrupts
+    - usb: xhci: tegra: Check padctrl interrupt presence in device tree
+    - usb: hub: Fix usb enumeration issue due to address0 race
+    - usb: hub: Fix locking issues with address0_mutex
+    - binder: fix test regression due to sender_euid change
+    - ALSA: ctxfi: Fix out-of-range access
+    - ALSA: hda/realtek: Add quirk for ASRock NUC Box 1100
+    - ALSA: hda/realtek: Fix LED on HP ProBook 435 G7
+    - media: cec: copy sequence field for the reply
+    - Revert "parisc: Fix backtrace to always include init funtion names"
+    - HID: wacom: Use "Confidence" flag to prevent reporting invalid contacts
+    - staging/fbtft: Fix backlight
+    - staging: greybus: Add missing rwsem around snd_ctl_remove() calls
+    - staging: rtl8192e: Fix use after free in _rtl92e_pci_disconnect()
+    - staging: r8188eu: Use kzalloc() with GFP_ATOMIC in atomic context
+    - staging: r8188eu: Fix breakage introduced when 5G code was removed
+    - staging: r8188eu: use GFP_ATOMIC under spinlock
+    - staging: r8188eu: fix a memory leak in rtw_wx_read32()
+    - fuse: release pipe buf after last use
+    - xen: don't continue xenstore initialization in case of errors
+    - xen: detect uninitialized xenbus in xenbus_init
+    - io_uring: correct link-list traversal locking
+    - io_uring: fail cancellation for EXITING tasks
+    - io_uring: fix link traversal locking
+    - drm/amdgpu: IH process reset count when restart
+    - drm/amdgpu/pm: fix powerplay OD interface
+    - drm/nouveau: recognise GA106
+    - ksmbd: downgrade addition info error msg to debug in smb2_get_info_sec()
+    - ksmbd: contain default data stream even if xattr is empty
+    - ksmbd: fix memleak in get_file_stream_info()
+    - KVM: PPC: Book3S HV: Prevent POWER7/8 TLB flush flushing SLB
+    - tracing/uprobe: Fix uprobe_perf_open probes iteration
+    - tracing: Fix pid filtering when triggers are attached
+    - mmc: sdhci-esdhc-imx: disable CMDQ support
+    - mmc: sdhci: Fix ADMA for PAGE_SIZE >= 64KiB
+    - mdio: aspeed: Fix "Link is Down" issue
+    - arm64: mm: Fix VM_BUG_ON(mm != &init_mm) for trans_pgd
+    - cpufreq: intel_pstate: Fix active mode offline/online EPP handling
+    - powerpc/32: Fix hardlockup on vmap stack overflow
+    - iomap: Fix inline extent handling in iomap_readpage
+    - NFSv42: Fix pagecache invalidation after COPY/CLONE
+    - PCI: aardvark: Deduplicate code in advk_pcie_rd_conf()
+    - PCI: aardvark: Implement re-issuing config requests on CRS response
+    - PCI: aardvark: Simplify initialization of rootcap on virtual bridge
+    - PCI: aardvark: Fix link training
+    - drm/amd/display: Fix OLED brightness control on eDP
+    - proc/vmcore: fix clearing user buffer by properly using clear_user()
+    - ASoC: SOF: Intel: hda: fix hotplug when only codec is suspended
+    - netfilter: ctnetlink: fix filtering with CTA_TUPLE_REPLY
+    - netfilter: ctnetlink: do not erase error code with EINVAL
+    - netfilter: ipvs: Fix reuse connection if RS weight is 0
+    - netfilter: flowtable: fix IPv6 tunnel addr match
+    - media: v4l2-core: fix VIDIOC_DQEVENT handling on non-x86
+    - firmware: arm_scmi: Fix null de-reference on error path
+    - ARM: dts: BCM5301X: Fix I2C controller interrupt
+    - ARM: dts: BCM5301X: Add interrupt properties to GPIO node
+    - ARM: dts: bcm2711: Fix PCIe interrupts
+    - ASoC: qdsp6: q6routing: Conditionally reset FrontEnd Mixer
+    - ASoC: qdsp6: q6asm: fix q6asm_dai_prepare error handling
+    - ASoC: topology: Add missing rwsem around snd_ctl_remove() calls
+    - ASoC: codecs: wcd938x: fix volatile register range
+    - ASoC: codecs: wcd934x: return error code correctly from hw_params
+    - ASoC: codecs: lpass-rx-macro: fix HPHR setting CLSH mask
+    - net: ieee802154: handle iftypes as u32
+    - firmware: arm_scmi: Fix base agent discover response
+    - firmware: arm_scmi: pm: Propagate return value to caller
+    - ASoC: stm32: i2s: fix 32 bits channel length without mclk
+    - NFSv42: Don't fail clone() unless the OP_CLONE operation failed
+    - ARM: socfpga: Fix crash with CONFIG_FORTIRY_SOURCE
+    - drm/nouveau/acr: fix a couple NULL vs IS_ERR() checks
+    - scsi: qla2xxx: edif: Fix off by one bug in qla_edif_app_getfcinfo()
+    - scsi: mpt3sas: Fix kernel panic during drive powercycle test
+    - scsi: mpt3sas: Fix system going into read-only mode
+    - scsi: mpt3sas: Fix incorrect system timestamp
+    - drm/vc4: fix error code in vc4_create_object()
+    - drm/aspeed: Fix vga_pw sysfs output
+    - net: marvell: prestera: fix brige port operation
+    - net: marvell: prestera: fix double free issue on err path
+    - HID: input: Fix parsing of HID_CP_CONSUMER_CONTROL fields
+    - HID: input: set usage type to key on keycode remap
+    - HID: magicmouse: prevent division by 0 on scroll
+    - iavf: Prevent changing static ITR values if adaptive moderation is on
+    - iavf: Fix refreshing iavf adapter stats on ethtool request
+    - iavf: Fix VLAN feature flags after VFR
+    - x86/pvh: add prototype for xen_pvh_init()
+    - xen/pvh: add missing prototype to header
+    - ALSA: intel-dsp-config: add quirk for JSL devices based on ES8336 codec
+    - mptcp: fix delack timer
+    - mptcp: use delegate action to schedule 3rd ack retrans
+    - af_unix: fix regression in read after shutdown
+    - firmware: smccc: Fix check for ARCH_SOC_ID not implemented
+    - ipv6: fix typos in __ip6_finish_output()
+    - nfp: checking parameter process for rx-usecs/tx-usecs is invalid
+    - net: stmmac: retain PTP clock time during SIOCSHWTSTAMP ioctls
+    - net: ipv6: add fib6_nh_release_dsts stub
+    - net: nexthop: release IPv6 per-cpu dsts when replacing a nexthop group
+    - ice: fix vsi->txq_map sizing
+    - ice: avoid bpf_prog refcount underflow
+    - scsi: core: sysfs: Fix setting device state to SDEV_RUNNING
+    - scsi: scsi_debug: Zero clear zones at reset write pointer
+    - erofs: fix deadlock when shrink erofs slab
+    - i2c: virtio: disable timeout handling
+    - net/smc: Ensure the active closing peer first closes clcsock
+    - mlxsw: spectrum: Protect driver from buggy firmware
+    - net: ipa: directly disable ipa-setup-ready interrupt
+    - net: ipa: separate disabling setup from modem stop
+    - net: ipa: kill ipa_cmd_pipeline_clear()
+    - net: marvell: mvpp2: increase MTU limit when XDP enabled
+    - cpufreq: intel_pstate: Add Ice Lake server to out-of-band IDs
+    - nvmet-tcp: fix incomplete data digest send
+    - drm/hyperv: Fix device removal on Gen1 VMs
+    - arm64: uaccess: avoid blocking within critical sections
+    - net/ncsi : Add payload to be 32-bit aligned to fix dropped packets
+    - PM: hibernate: use correct mode for swsusp_close()
+    - drm/amd/display: Fix DPIA outbox timeout after GPU reset
+    - drm/amd/display: Set plane update flags for all planes in reset
+    - tcp_cubic: fix spurious Hystart ACK train detections for not-cwnd-limited
+      flows
+    - lan743x: fix deadlock in lan743x_phy_link_status_change()
+    - net: phylink: Force link down and retrigger resolve on interface change
+    - net: phylink: Force retrigger in case of latched link-fail indicator
+    - net/smc: Fix NULL pointer dereferencing in smc_vlan_by_tcpsk()
+    - net/smc: Fix loop in smc_listen
+    - nvmet: use IOCB_NOWAIT only if the filesystem supports it
+    - igb: fix netpoll exit with traffic
+    - MIPS: loongson64: fix FTLB configuration
+    - MIPS: use 3-level pgtable for 64KB page size on MIPS_VA_BITS_48
+    - tls: splice_read: fix record type check
+    - tls: splice_read: fix accessing pre-processed records
+    - tls: fix replacing proto_ops
+    - net: stmmac: Disable Tx queues when reconfiguring the interface
+    - net/sched: sch_ets: don't peek at classes beyond 'nbands'
+    - ethtool: ioctl: fix potential NULL deref in ethtool_set_coalesce()
+    - net: vlan: fix underflow for the real_dev refcnt
+    - net/smc: Don't call clcsock shutdown twice when smc shutdown
+    - net: hns3: fix VF RSS failed problem after PF enable multi-TCs
+    - net: hns3: fix incorrect components info of ethtool --reset command
+    - net: mscc: ocelot: don't downgrade timestamping RX filters in SIOCSHWTSTAMP
+    - net: mscc: ocelot: correctly report the timestamping RX filters in ethtool
+    - locking/rwsem: Make handoff bit handling more consistent
+    - perf: Ignore sigtrap for tracepoints destined for other tasks
+    - sched/scs: Reset task stack state in bringup_cpu()
+    - iommu/rockchip: Fix PAGE_DESC_HI_MASKs for RK3568
+    - iommu/vt-d: Fix unmap_pages support
+    - f2fs: quota: fix potential deadlock
+    - f2fs: set SBI_NEED_FSCK flag when inconsistent node block found
+    - riscv: dts: microchip: fix board compatible
+    - riscv: dts: microchip: drop duplicated MMC/SDHC node
+    - cifs: nosharesock should not share socket with future sessions
+    - ceph: properly handle statfs on multifs setups
+    - iommu/amd: Clarify AMD IOMMUv2 initialization messages
+    - vdpa_sim: avoid putting an uninitialized iova_domain
+    - vhost/vsock: fix incorrect used length reported to the guest
+    - ksmbd: Fix an error handling path in 'smb2_sess_setup()'
+    - tracing: Check pid filtering when creating events
+    - cifs: nosharesock should be set on new server
+    - io_uring: fix soft lockup when call __io_remove_buffers
+    - firmware: arm_scmi: Fix type error assignment in voltage protocol
+    - firmware: arm_scmi: Fix type error in sensor protocol
+    - docs: accounting: update delay-accounting.rst reference
+    - blk-mq: cancel blk-mq dispatch work in both blk_cleanup_queue and
+      disk_release()
+    - block: avoid to quiesce queue in elevator_init_mq
+    - drm/amdgpu/gfx10: add wraparound gpu counter check for APUs as well
+    - drm/amdgpu/gfx9: switch to golden tsc registers for renoir+
+    - Linux 5.15.6
+
+  * Fix bogus HDMI audio interface  (LP: #1953208)
+    - ALSA: hda/hdmi: Consider ELD is invalid when no SAD is present
+
+  * Miscellaneous Ubuntu changes
+    - [Config] re-enabled UBSAN without TRAP
+    - SAUCE: ipv6: fix NULL pointer dereference in ip6_output()
+    - SAUCE: RDMA/core: Introduce peer memory interface
+    - [Config] toolchain version update
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] Temporarily disable signing for ppc64el and s390x"
+    - Revert "UBUNTU: SAUCE: vt -- maintain bootloader screen mode and content
+      until vt switch"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 13 Dec 2021 12:13:17 +0100
+
+linux (5.15.0-13.13) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-13.13 -proposed tracker (LP: #1952583)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync update-dkms-versions helper
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Jammy update: v5.15.5 upstream stable release (LP: #1952579)
+    - arm64: zynqmp: Do not duplicate flash partition label property
+    - arm64: zynqmp: Fix serial compatible string
+    - clk: sunxi-ng: Unregister clocks/resets when unbinding
+    - ARM: dts: sunxi: Fix OPPs node name
+    - arm64: dts: allwinner: h5: Fix GPU thermal zone node name
+    - arm64: dts: allwinner: a100: Fix thermal zone node name
+    - staging: wfx: ensure IRQ is ready before enabling it
+    - ARM: dts: BCM5301X: Fix nodes names
+    - ARM: dts: BCM5301X: Fix MDIO mux binding
+    - ARM: dts: NSP: Fix mpcore, mmc node names
+    - arm64: dts: broadcom: bcm4908: Move reboot syscon out of bus
+    - scsi: pm80xx: Fix memory leak during rmmod
+    - scsi: lpfc: Fix list_add() corruption in lpfc_drain_txq()
+    - ASoC: mediatek: mt8195: Add missing of_node_put()
+    - arm64: dts: rockchip: Disable CDN DP on Pinebook Pro
+    - arm64: dts: hisilicon: fix arm,sp805 compatible string
+    - RDMA/bnxt_re: Check if the vlan is valid before reporting
+    - bus: ti-sysc: Add quirk handling for reinit on context lost
+    - bus: ti-sysc: Use context lost quirk for otg
+    - usb: musb: tusb6010: check return value after calling
+      platform_get_resource()
+    - usb: typec: tipd: Remove WARN_ON in tps6598x_block_read
+    - ARM: dts: ux500: Skomer regulator fixes
+    - staging: rtl8723bs: remove possible deadlock when disconnect (v2)
+    - staging: rtl8723bs: remove a second possible deadlock
+    - staging: rtl8723bs: remove a third possible deadlock
+    - ARM: BCM53016: Specify switch ports for Meraki MR32
+    - arm64: dts: qcom: msm8998: Fix CPU/L2 idle state latency and residency
+    - arm64: dts: qcom: ipq6018: Fix qcom,controlled-remotely property
+    - arm64: dts: qcom: ipq8074: Fix qcom,controlled-remotely property
+    - arm64: dts: qcom: sdm845: Fix qcom,controlled-remotely property
+    - arm64: dts: freescale: fix arm,sp805 compatible string
+    - arm64: dts: ls1012a: Add serial alias for ls1012a-rdb
+    - RDMA/rxe: Separate HW and SW l/rkeys
+    - ASoC: SOF: Intel: hda-dai: fix potential locking issue
+    - scsi: core: Fix scsi_mode_sense() buffer length handling
+    - ALSA: usb-audio: disable implicit feedback sync for Behringer UFX1204 and
+      UFX1604
+    - clk: imx: imx6ul: Move csi_sel mux to correct base register
+    - ASoC: es8316: Use IRQF_NO_AUTOEN when requesting the IRQ
+    - ASoC: rt5651: Use IRQF_NO_AUTOEN when requesting the IRQ
+    - ASoC: nau8824: Add DMI quirk mechanism for active-high jack-detect
+    - scsi: advansys: Fix kernel pointer leak
+    - scsi: smartpqi: Add controller handshake during kdump
+    - arm64: dts: imx8mm-kontron: Fix reset delays for ethernet PHY
+    - ALSA: intel-dsp-config: add quirk for APL/GLK/TGL devices based on ES8336
+      codec
+    - ASoC: Intel: soc-acpi: add missing quirk for TGL SDCA single amp
+    - ASoC: Intel: sof_sdw: add missing quirk for Dell SKU 0A45
+    - firmware_loader: fix pre-allocated buf built-in firmware use
+    - HID: multitouch: disable sticky fingers for UPERFECT Y
+    - ALSA: usb-audio: Add support for the Pioneer DJM 750MK2 Mixer/Soundcard
+    - ARM: dts: omap: fix gpmc,mux-add-data type
+    - usb: host: ohci-tmio: check return value after calling
+      platform_get_resource()
+    - ASoC: rt5682: fix a little pop while playback
+    - ARM: dts: ls1021a: move thermal-zones node out of soc/
+    - ARM: dts: ls1021a-tsn: use generic "jedec,spi-nor" compatible for flash
+    - ALSA: ISA: not for M68K
+    - iommu/vt-d: Do not falsely log intel_iommu is unsupported kernel option
+    - tty: tty_buffer: Fix the softlockup issue in flush_to_ldisc
+    - MIPS: sni: Fix the build
+    - scsi: scsi_debug: Fix out-of-bound read in resp_readcap16()
+    - scsi: scsi_debug: Fix out-of-bound read in resp_report_tgtpgs()
+    - scsi: target: Fix ordered tag handling
+    - scsi: target: Fix alua_tg_pt_gps_count tracking
+    - iio: imu: st_lsm6dsx: Avoid potential array overflow in st_lsm6dsx_set_odr()
+    - RDMA/core: Use kvzalloc when allocating the struct ib_port
+    - scsi: lpfc: Fix use-after-free in lpfc_unreg_rpi() routine
+    - scsi: lpfc: Fix link down processing to address NULL pointer dereference
+    - scsi: lpfc: Allow fabric node recovery if recovery is in progress before
+      devloss
+    - memory: tegra20-emc: Add runtime dependency on devfreq governor module
+    - powerpc/5200: dts: fix memory node unit name
+    - ARM: dts: qcom: fix memory and mdio nodes naming for RB3011
+    - arm64: dts: qcom: Fix node name of rpm-msg-ram device nodes
+    - ALSA: gus: fix null pointer dereference on pointer block
+    - ALSA: usb-audio: fix null pointer dereference on pointer cs_desc
+    - clk: at91: sama7g5: remove prescaler part of master clock
+    - iommu/dart: Initialize DART_STREAMS_ENABLE
+    - powerpc/dcr: Use cmplwi instead of 3-argument cmpli
+    - powerpc/8xx: Fix Oops with STRICT_KERNEL_RWX without DEBUG_RODATA_TEST
+    - sh: check return code of request_irq
+    - maple: fix wrong return value of maple_bus_init().
+    - f2fs: fix up f2fs_lookup tracepoints
+    - f2fs: fix to use WHINT_MODE
+    - f2fs: fix wrong condition to trigger background checkpoint correctly
+    - sh: fix kconfig unmet dependency warning for FRAME_POINTER
+    - sh: math-emu: drop unused functions
+    - sh: define __BIG_ENDIAN for math-emu
+    - f2fs: compress: disallow disabling compress on non-empty compressed file
+    - f2fs: fix incorrect return value in f2fs_sanity_check_ckpt()
+    - clk: ingenic: Fix bugs with divided dividers
+    - clk/ast2600: Fix soc revision for AHB
+    - clk: qcom: gcc-msm8996: Drop (again) gcc_aggre1_pnoc_ahb_clk
+    - KVM: arm64: Fix host stage-2 finalization
+    - mips: BCM63XX: ensure that CPU_SUPPORTS_32BIT_KERNEL is set
+    - MIPS: boot/compressed/: add __bswapdi2() to target for ZSTD decompression
+    - sched/core: Mitigate race cpus_share_cache()/update_top_cache_domain()
+    - sched/fair: Prevent dead task groups from regaining cfs_rq's
+    - perf/x86/vlbr: Add c->flags to vlbr event constraints
+    - blkcg: Remove extra blkcg_bio_issue_init
+    - tracing/histogram: Do not copy the fixed-size char array field over the
+      field size
+    - perf bpf: Avoid memory leak from perf_env__insert_btf()
+    - perf bench futex: Fix memory leak of perf_cpu_map__new()
+    - perf tests: Remove bash construct from record+zstd_comp_decomp.sh
+    - drm/nouveau: hdmigv100.c: fix corrupted HDMI Vendor InfoFrame
+    - bpf: Fix inner map state pruning regression.
+    - samples/bpf: Fix summary per-sec stats in xdp_sample_user
+    - samples/bpf: Fix incorrect use of strlen in xdp_redirect_cpu
+    - selftests: net: switch to socat in the GSO GRE test
+    - net/ipa: ipa_resource: Fix wrong for loop range
+    - tcp: Fix uninitialized access in skb frags array for Rx 0cp.
+    - tracing: Add length protection to histogram string copies
+    - nl80211: fix radio statistics in survey dump
+    - mac80211: fix monitor_sdata RCU/locking assertions
+    - net: ipa: HOLB register sometimes must be written twice
+    - net: ipa: disable HOLB drop when updating timer
+    - selftests: gpio: fix gpio compiling error
+    - net: bnx2x: fix variable dereferenced before check
+    - bnxt_en: reject indirect blk offload when hw-tc-offload is off
+    - tipc: only accept encrypted MSG_CRYPTO msgs
+    - sock: fix /proc/net/sockstat underflow in sk_clone_lock()
+    - net/smc: Make sure the link_id is unique
+    - NFSD: Fix exposure in nfsd4_decode_bitmap()
+    - iavf: Fix return of set the new channel count
+    - iavf: check for null in iavf_fix_features
+    - iavf: free q_vectors before queues in iavf_disable_vf
+    - iavf: don't clear a lock we don't hold
+    - iavf: Fix failure to exit out from last all-multicast mode
+    - iavf: prevent accidental free of filter structure
+    - iavf: validate pointers
+    - iavf: Fix for the false positive ASQ/ARQ errors while issuing VF reset
+    - iavf: Fix for setting queues to 0
+    - iavf: Restore VLAN filters after link down
+    - bpf: Fix toctou on read-only map's constant scalar tracking
+    - MIPS: generic/yamon-dt: fix uninitialized variable error
+    - mips: bcm63xx: add support for clk_get_parent()
+    - mips: lantiq: add support for clk_get_parent()
+    - gpio: rockchip: needs GENERIC_IRQ_CHIP to fix build errors
+    - platform/x86: hp_accel: Fix an error handling path in 'lis3lv02d_probe()'
+    - platform/x86: think-lmi: Abort probe on analyze failure
+    - udp: Validate checksum in udp_read_sock()
+    - btrfs: make 1-bit bit-fields of scrub_page unsigned int
+    - RDMA/core: Set send and receive CQ before forwarding to the driver
+    - net/mlx5e: kTLS, Fix crash in RX resync flow
+    - net/mlx5e: Wait for concurrent flow deletion during neigh/fib events
+    - net/mlx5: E-Switch, Fix resetting of encap mode when entering switchdev
+    - net/mlx5e: nullify cq->dbg pointer in mlx5_debug_cq_remove()
+    - net/mlx5: Update error handler for UCTX and UMEM
+    - net/mlx5: E-Switch, rebuild lag only when needed
+    - net/mlx5e: CT, Fix multiple allocations and memleak of mod acts
+    - net/mlx5: Lag, update tracker when state change event received
+    - net/mlx5: E-Switch, return error if encap isn't supported
+    - scsi: ufs: core: Improve SCSI abort handling
+    - scsi: core: sysfs: Fix hang when device state is set via sysfs
+    - scsi: ufs: core: Fix task management completion timeout race
+    - scsi: ufs: core: Fix another task management completion race
+    - net: mvmdio: fix compilation warning
+    - net: sched: act_mirred: drop dst for the direction from egress to ingress
+    - net: dpaa2-eth: fix use-after-free in dpaa2_eth_remove
+    - net: virtio_net_hdr_to_skb: count transport header in UFO
+    - i40e: Fix correct max_pkt_size on VF RX queue
+    - i40e: Fix NULL ptr dereference on VSI filter sync
+    - i40e: Fix changing previously set num_queue_pairs for PFs
+    - i40e: Fix ping is lost after configuring ADq on VF
+    - RDMA/mlx4: Do not fail the registration on port stats
+    - i40e: Fix warning message and call stack during rmmod i40e driver
+    - i40e: Fix creation of first queue by omitting it if is not power of two
+    - i40e: Fix display error code in dmesg
+    - NFC: reorganize the functions in nci_request
+    - NFC: reorder the logic in nfc_{un,}register_device
+    - NFC: add NCI_UNREG flag to eliminate the race
+    - e100: fix device suspend/resume
+    - ptp: ocp: Fix a couple NULL vs IS_ERR() checks
+    - tools build: Fix removal of feature-sync-compare-and-swap feature detection
+    - riscv: fix building external modules
+    - KVM: PPC: Book3S HV: Use GLOBAL_TOC for kvmppc_h_set_dabr/xdabr()
+    - powerpc: clean vdso32 and vdso64 directories
+    - powerpc/pseries: rename numa_dist_table to form2_distances
+    - powerpc/pseries: Fix numa FORM2 parsing fallback code
+    - pinctrl: qcom: sdm845: Enable dual edge errata
+    - pinctrl: qcom: sm8350: Correct UFS and SDC offsets
+    - perf/x86/intel/uncore: Fix filter_tid mask for CHA events on Skylake Server
+    - perf/x86/intel/uncore: Fix IIO event constraints for Skylake Server
+    - perf/x86/intel/uncore: Fix IIO event constraints for Snowridge
+    - s390/kexec: fix return code handling
+    - blk-cgroup: fix missing put device in error path from blkg_conf_pref()
+    - dmaengine: remove debugfs #ifdef
+    - tun: fix bonding active backup with arp monitoring
+    - Revert "mark pstore-blk as broken"
+    - pstore/blk: Use "%lu" to format unsigned long
+    - hexagon: export raw I/O routines for modules
+    - hexagon: clean up timer-regs.h
+    - tipc: check for null after calling kmemdup
+    - ipc: WARN if trying to remove ipc object which is absent
+    - shm: extend forced shm destroy to support objects from several IPC nses
+    - mm: kmemleak: slob: respect SLAB_NOLEAKTRACE flag
+    - hugetlb, userfaultfd: fix reservation restore on userfaultfd error
+    - kmap_local: don't assume kmap PTEs are linear arrays in memory
+    - mm/damon/dbgfs: use '__GFP_NOWARN' for user-specified size buffer allocation
+    - mm/damon/dbgfs: fix missed use of damon_dbgfs_lock
+    - x86/boot: Pull up cmdline preparation and early param parsing
+    - x86/sgx: Fix free page accounting
+    - x86/hyperv: Fix NULL deref in set_hv_tscchange_cb() if Hyper-V setup fails
+    - KVM: x86: Assume a 64-bit hypercall for guests with protected state
+    - KVM: x86: Fix uninitialized eoi_exit_bitmap usage in vcpu_load_eoi_exitmap()
+    - KVM: x86/mmu: include EFER.LMA in extended mmu role
+    - KVM: x86/xen: Fix get_attr of KVM_XEN_ATTR_TYPE_SHARED_INFO
+    - powerpc/signal32: Fix sigset_t copy
+    - powerpc/xive: Change IRQ domain to a tree domain
+    - powerpc/8xx: Fix pinned TLBs with CONFIG_STRICT_KERNEL_RWX
+    - Revert "drm/i915/tgl/dsi: Gate the ddi clocks after pll mapping"
+    - Revert "parisc: Reduce sigreturn trampoline to 3 instructions"
+    - ata: libata: improve ata_read_log_page() error message
+    - ata: libata: add missing ata_identify_page_supported() calls
+    - scsi: qla2xxx: Fix mailbox direction flags in qla2xxx_get_adapter_id()
+    - pinctrl: ralink: include 'ralink_regs.h' in 'pinctrl-mt7620.c'
+    - s390/setup: avoid reserving memory above identity mapping
+    - s390/boot: simplify and fix kernel memory layout setup
+    - s390/vdso: filter out -mstack-guard and -mstack-size
+    - s390/kexec: fix memory leak of ipl report buffer
+    - s390/dump: fix copying to user-space of swapped kdump oldmem
+    - block: Check ADMIN before NICE for IOPRIO_CLASS_RT
+    - fbdev: Prevent probing generic drivers if a FB is already registered
+    - KVM: SEV: Disallow COPY_ENC_CONTEXT_FROM if target has created vCPUs
+    - KVM: nVMX: don't use vcpu->arch.efer when checking host state on nested
+      state load
+    - drm/cma-helper: Release non-coherent memory with dma_free_noncoherent()
+    - printk: restore flushing of NMI buffers on remote CPUs after NMI backtraces
+    - udf: Fix crash after seekdir
+    - spi: fix use-after-free of the add_lock mutex
+    - net: stmmac: socfpga: add runtime suspend/resume callback for stratix10
+      platform
+    - Drivers: hv: balloon: Use VMBUS_RING_SIZE() wrapper for dm_ring_size
+    - btrfs: fix memory ordering between normal and ordered work functions
+    - fs: handle circular mappings correctly
+    - net: stmmac: Fix signed/unsigned wreckage
+    - parisc/sticon: fix reverse colors
+    - cfg80211: call cfg80211_stop_ap when switch from P2P_GO type
+    - mac80211: fix radiotap header generation
+    - mac80211: drop check for DONT_REORDER in __ieee80211_select_queue
+    - drm/amd/display: Update swizzle mode enums
+    - drm/amd/display: Limit max DSC target bpp for specific monitors
+    - drm/i915/guc: Fix outstanding G2H accounting
+    - drm/i915/guc: Don't enable scheduling on a banned context, guc_id invalid,
+      not registered
+    - drm/i915/guc: Workaround reset G2H is received after schedule done G2H
+    - drm/i915/guc: Don't drop ce->guc_active.lock when unwinding context
+    - drm/i915/guc: Unwind context requests in reverse order
+    - drm/udl: fix control-message timeout
+    - drm/prime: Fix use after free in mmap with drm_gem_ttm_mmap
+    - drm/nouveau: Add a dedicated mutex for the clients list
+    - drm/nouveau: use drm_dev_unplug() during device removal
+    - drm/nouveau: clean up all clients on device removal
+    - drm/i915/dp: Ensure sink rate values are always valid
+    - drm/i915/dp: Ensure max link params are always valid
+    - drm/i915: Fix type1 DVI DP dual mode adapter heuristic for modern platforms
+    - drm/amdgpu: fix set scaling mode Full/Full aspect/Center not works on vga
+      and dvi connectors
+    - drm/amd/pm: avoid duplicate powergate/ungate setting
+    - signal: Implement force_fatal_sig
+    - exit/syscall_user_dispatch: Send ordinary signals on failure
+    - signal/powerpc: On swapcontext failure force SIGSEGV
+    - signal/s390: Use force_sigsegv in default_trap_handler
+    - signal/sparc32: Exit with a fatal signal when try_to_clear_window_buffer
+      fails
+    - signal/sparc32: In setup_rt_frame and setup_fram use force_fatal_sig
+    - signal/vm86_32: Properly send SIGSEGV when the vm86 state cannot be saved.
+    - signal/x86: In emulate_vsyscall force a signal instead of calling do_exit
+    - signal: Replace force_sigsegv(SIGSEGV) with force_fatal_sig(SIGSEGV)
+    - signal: Don't always set SA_IMMUTABLE for forced signals
+    - signal: Replace force_fatal_sig with force_exit_sig when in doubt
+    - hugetlbfs: flush TLBs correctly after huge_pmd_unshare
+    - RDMA/netlink: Add __maybe_unused to static inline in C file
+    - bpf: Forbid bpf_ktime_get_coarse_ns and bpf_timer_* in tracing progs
+    - selinux: fix NULL-pointer dereference when hashtab allocation fails
+    - ASoC: DAPM: Cover regression by kctl change notification fix
+    - ASoC: rsnd: fixup DMAEngine API
+    - usb: max-3421: Use driver data instead of maintaining a list of bound
+      devices
+    - ice: Fix VF true promiscuous mode
+    - ice: Delete always true check of PF pointer
+    - fs: export an inode_update_time helper
+    - btrfs: update device path inode time instead of bd_inode
+    - net: add and use skb_unclone_keeptruesize() helper
+    - x86/Kconfig: Fix an unused variable error in dell-smm-hwmon
+    - ALSA: hda: hdac_ext_stream: fix potential locking issues
+    - ALSA: hda: hdac_stream: fix potential locking issue in
+      snd_hdac_stream_assign()
+    - Linux 5.15.5
+
+  * Fix non-working e1000e device after resume (LP: #1951861)
+    - SAUCE: Revert "e1000e: Additional PHY power saving in S0ix"
+    - SAUCE: Revert "e1000e: Add polling mechanism to indicate CSME DPG exit"
+    - SAUCE: Revert "e1000e: Add handshake with the CSME to support S0ix"
+
+  * [SRU][I/OEM-5.13/OEM-5.14] Add MAC passthrough support for more Lenovo docks
+    (LP: #1951767)
+    - net: usb: r8152: Add MAC passthrough support for more Lenovo Docks
+
+  * [amdgpu] USB4 support for DP tunneling (LP: #1951868)
+    - drm/amd/display: Support for DMUB HPD interrupt handling
+    - drm/amd/display: Update link encoder object creation.
+    - drm/amd/display: USB4 DPIA enumeration and AUX Tunneling
+    - drm/amd/display: Support for DMUB HPD and HPD RX interrupt handling
+    - drm/amd/display: Set DPIA link endpoint type
+    - drm/amd/display: Stub out DPIA link training call
+    - drm/amd/display: Add stub to get DPIA tunneling device data
+    - drm/amd/display: Skip DPCD read for DPTX-to-DPIA hop
+    - drm/amd/display: Train DPIA links with fallback
+    - drm/amd/display: Implement DPIA training loop
+    - drm/amd/display: Implement DPIA link configuration
+    - drm/amd/display: Implement DPIA clock recovery phase
+    - drm/amd/display: Implement DPIA equalisation phase
+    - drm/amd/display: Implement end of training for hop in DPIA display path
+    - drm/amd/display: Support for SET_CONFIG processing with DMUB
+    - drm/amd/display: isolate link training setting override to its own function
+    - drm/amd/display: Read USB4 DP tunneling data from DPCD.
+    - drm/amd/display: Add dpia debug options
+    - drm/amd/display: Support for SET_CONFIG processing with DMUB
+    - drm/amd/display: Add DPCD writes at key points
+    - drm/amd/display: Fix DIG_HPD_SELECT for USB4 display endpoints.
+    - drm/amd/display: Add helper for blanking all dp displays
+    - drm/amd/display: Fix link training fallback logic
+    - drm/amd/display: Add debug flags for USB4 DP link training.
+    - drm/amd/display: Fix dynamic link encoder access.
+    - drm/amd/display: Fix concurrent dynamic encoder assignment
+    - drm/amd/display: Fix dynamic encoder reassignment
+    - drm/amd/display: Fix for access for ddc pin and aux engine.
+    - drm/amd/display: Deadlock/HPD Status/Crash Bug Fix
+    - drm/amd/display: Fix USB4 Aux via DMUB terminate unexpectedly
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Rewrite debian/scripts/module-check in Python
+    - [Config] update config and annotations after applying v5.15.5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 29 Nov 2021 09:25:37 +0100
+
+linux (5.15.0-12.12) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-12.12 -proposed tracker (LP: #1951810)
+
+  * Jammy update: v5.15.4 upstream stable release (LP: #1951820)
+    - string: uninline memcpy_and_pad
+    - Revert "drm: fb_helper: improve CONFIG_FB dependency"
+    - Revert "drm: fb_helper: fix CONFIG_FB dependency"
+    - KVM: Fix steal time asm constraints
+    - btrfs: introduce btrfs_is_data_reloc_root
+    - btrfs: zoned: add a dedicated data relocation block group
+    - btrfs: zoned: only allow one process to add pages to a relocation inode
+    - btrfs: zoned: use regular writes for relocation
+    - btrfs: check for relocation inodes on zoned btrfs in should_nocow
+    - btrfs: zoned: allow preallocation for relocation inodes
+    - fortify: Explicitly disable Clang support
+    - block: Add a helper to validate the block size
+    - loop: Use blk_validate_block_size() to validate block size
+    - Bluetooth: btusb: Add support for TP-Link UB500 Adapter
+    - parisc/entry: fix trace test in syscall exit path
+    - PCI/MSI: Deal with devices lying about their MSI mask capability
+    - PCI: Add MSI masking quirk for Nvidia ION AHCI
+    - perf/core: Avoid put_page() when GUP fails
+    - thermal: Fix NULL pointer dereferences in of_thermal_ functions
+    - Revert "ACPI: scan: Release PM resources blocked by unused objects"
+    - Linux 5.15.4
+
+  * Jammy update: v5.15.3 upstream stable release (LP: #1951822)
+    - xhci: Fix USB 3.1 enumeration issues by increasing roothub power-on-good
+      delay
+    - usb: xhci: Enable runtime-pm by default on AMD Yellow Carp platform
+    - Input: iforce - fix control-message timeout
+    - Input: elantench - fix misreporting trackpoint coordinates
+    - Input: i8042 - Add quirk for Fujitsu Lifebook T725
+    - libata: fix read log timeout value
+    - ocfs2: fix data corruption on truncate
+    - scsi: scsi_ioctl: Validate command size
+    - scsi: core: Avoid leaving shost->last_reset with stale value if EH does not
+      run
+    - scsi: core: Remove command size deduction from scsi_setup_scsi_cmnd()
+    - scsi: lpfc: Don't release final kref on Fport node while ABTS outstanding
+    - scsi: lpfc: Fix FCP I/O flush functionality for TMF routines
+    - scsi: qla2xxx: Fix crash in NVMe abort path
+    - scsi: qla2xxx: Fix kernel crash when accessing port_speed sysfs file
+    - scsi: qla2xxx: Fix use after free in eh_abort path
+    - ce/gf100: fix incorrect CE0 address calculation on some GPUs
+    - char: xillybus: fix msg_ep UAF in xillyusb_probe()
+    - mmc: mtk-sd: Add wait dma stop done flow
+    - mmc: dw_mmc: Dont wait for DRTO on Write RSP error
+    - exfat: fix incorrect loading of i_blocks for large files
+    - io-wq: remove worker to owner tw dependency
+    - parisc: Fix set_fixmap() on PA1.x CPUs
+    - parisc: Fix ptrace check on syscall return
+    - tpm: Check for integer overflow in tpm2_map_response_body()
+    - firmware/psci: fix application of sizeof to pointer
+    - crypto: s5p-sss - Add error handling in s5p_aes_probe()
+    - media: rkvdec: Do not override sizeimage for output format
+    - media: ite-cir: IR receiver stop working after receive overflow
+    - media: rkvdec: Support dynamic resolution changes
+    - media: ir-kbd-i2c: improve responsiveness of hauppauge zilog receivers
+    - media: v4l2-ioctl: Fix check_ext_ctrls
+    - ALSA: hda/realtek: Fix mic mute LED for the HP Spectre x360 14
+    - ALSA: hda/realtek: Add a quirk for HP OMEN 15 mute LED
+    - ALSA: hda/realtek: Add quirk for Clevo PC70HS
+    - ALSA: hda/realtek: Headset fixup for Clevo NH77HJQ
+    - ALSA: hda/realtek: Add a quirk for Acer Spin SP513-54N
+    - ALSA: hda/realtek: Add quirk for ASUS UX550VE
+    - ALSA: hda/realtek: Add quirk for HP EliteBook 840 G7 mute LED
+    - ALSA: ua101: fix division by zero at probe
+    - ALSA: 6fire: fix control and bulk message timeouts
+    - ALSA: line6: fix control and interrupt message timeouts
+    - ALSA: mixer: oss: Fix racy access to slots
+    - ALSA: mixer: fix deadlock in snd_mixer_oss_set_volume
+    - ALSA: usb-audio: Line6 HX-Stomp XL USB_ID for 48k-fixed quirk
+    - ALSA: usb-audio: Add registration quirk for JBL Quantum 400
+    - ALSA: hda: Free card instance properly at probe errors
+    - ALSA: synth: missing check for possible NULL after the call to kstrdup
+    - ALSA: pci: rme: Fix unaligned buffer addresses
+    - ALSA: PCM: Fix NULL dereference at mmap checks
+    - ALSA: timer: Fix use-after-free problem
+    - ALSA: timer: Unconditionally unlink slave instances, too
+    - Revert "ext4: enforce buffer head state assertion in ext4_da_map_blocks"
+    - ext4: fix lazy initialization next schedule time computation in more
+      granular unit
+    - ext4: ensure enough credits in ext4_ext_shift_path_extents
+    - ext4: refresh the ext4_ext_path struct after dropping i_data_sem.
+    - fuse: fix page stealing
+    - x86/sme: Use #define USE_EARLY_PGTABLE_L5 in mem_encrypt_identity.c
+    - x86/cpu: Fix migration safety with X86_BUG_NULL_SEL
+    - x86/irq: Ensure PI wakeup handler is unregistered before module unload
+    - x86/iopl: Fake iopl(3) CLI/STI usage
+    - btrfs: clear MISSING device status bit in btrfs_close_one_device
+    - btrfs: fix lost error handling when replaying directory deletes
+    - btrfs: call btrfs_check_rw_degradable only if there is a missing device
+    - KVM: x86/mmu: Drop a redundant, broken remote TLB flush
+    - KVM: VMX: Unregister posted interrupt wakeup handler on hardware unsetup
+    - KVM: PPC: Tick accounting should defer vtime accounting 'til after IRQ
+      handling
+    - ia64: kprobes: Fix to pass correct trampoline address to the handler
+    - selinux: fix race condition when computing ocontext SIDs
+    - ipmi:watchdog: Set panic count to proper value on a panic
+    - md/raid1: only allocate write behind bio for WriteMostly device
+    - hwmon: (pmbus/lm25066) Add offset coefficients
+    - regulator: s5m8767: do not use reset value as DVS voltage if GPIO DVS is
+      disabled
+    - regulator: dt-bindings: samsung,s5m8767: correct s5m8767,pmic-buck-default-
+      dvs-idx property
+    - EDAC/sb_edac: Fix top-of-high-memory value for Broadwell/Haswell
+    - mwifiex: fix division by zero in fw download path
+    - ath6kl: fix division by zero in send path
+    - ath6kl: fix control-message timeout
+    - ath10k: fix control-message timeout
+    - ath10k: fix division by zero in send path
+    - PCI: Mark Atheros QCA6174 to avoid bus reset
+    - rtl8187: fix control-message timeouts
+    - evm: mark evm_fixmode as __ro_after_init
+    - ifb: Depend on netfilter alternatively to tc
+    - platform/surface: aggregator_registry: Add support for Surface Laptop Studio
+    - mt76: mt7615: fix skb use-after-free on mac reset
+    - HID: surface-hid: Use correct event registry for managing HID events
+    - HID: surface-hid: Allow driver matching for target ID 1 devices
+    - wcn36xx: Fix HT40 capability for 2Ghz band
+    - wcn36xx: Fix tx_status mechanism
+    - wcn36xx: Fix (QoS) null data frame bitrate/modulation
+    - PM: sleep: Do not let "syscore" devices runtime-suspend during system
+      transitions
+    - mwifiex: Read a PCI register after writing the TX ring write pointer
+    - mwifiex: Try waking the firmware until we get an interrupt
+    - libata: fix checking of DMA state
+    - dma-buf: fix and rework dma_buf_poll v7
+    - wcn36xx: handle connection loss indication
+    - rsi: fix occasional initialisation failure with BT coex
+    - rsi: fix key enabled check causing unwanted encryption for vap_id > 0
+    - rsi: fix rate mask set leading to P2P failure
+    - rsi: Fix module dev_oper_mode parameter description
+    - perf/x86/intel/uncore: Support extra IMC channel on Ice Lake server
+    - perf/x86/intel/uncore: Fix invalid unit check
+    - perf/x86/intel/uncore: Fix Intel ICX IIO event constraints
+    - RDMA/qedr: Fix NULL deref for query_qp on the GSI QP
+    - ASoC: tegra: Set default card name for Trimslice
+    - ASoC: tegra: Restore AC97 support
+    - signal: Remove the bogus sigkill_pending in ptrace_stop
+    - memory: renesas-rpc-if: Correct QSPI data transfer in Manual mode
+    - signal/mips: Update (_save|_restore)_fp_context to fail with -EFAULT
+    - soc: samsung: exynos-pmu: Fix compilation when nothing selects
+      CONFIG_MFD_CORE
+    - soc: fsl: dpio: replace smp_processor_id with raw_smp_processor_id
+    - soc: fsl: dpio: use the combined functions to protect critical zone
+    - mtd: rawnand: socrates: Keep the driver compatible with on-die ECC engines
+    - mctp: handle the struct sockaddr_mctp padding fields
+    - power: supply: max17042_battery: Prevent int underflow in set_soc_threshold
+    - power: supply: max17042_battery: use VFSOC for capacity when no rsns
+    - iio: core: fix double free in iio_device_unregister_sysfs()
+    - iio: core: check return value when calling dev_set_name()
+    - KVM: arm64: Extract ESR_ELx.EC only
+    - KVM: x86: Fix recording of guest steal time / preempted status
+    - KVM: x86: Add helper to consolidate core logic of SET_CPUID{2} flows
+    - KVM: nVMX: Query current VMCS when determining if MSR bitmaps are in use
+    - KVM: nVMX: Handle dynamic MSR intercept toggling
+    - can: peak_usb: always ask for BERR reporting for PCAN-USB devices
+    - can: mcp251xfd: mcp251xfd_irq(): add missing
+      can_rx_offload_threaded_irq_finish() in case of bus off
+    - can: j1939: j1939_tp_cmd_recv(): ignore abort message in the BAM transport
+    - can: j1939: j1939_can_recv(): ignore messages with invalid source address
+    - can: j1939: j1939_tp_cmd_recv(): check the dst address of TP.CM_BAM
+    - iio: adc: tsc2046: fix scan interval warning
+    - powerpc/85xx: Fix oops when mpc85xx_smp_guts_ids node cannot be found
+    - io_uring: honour zeroes as io-wq worker limits
+    - ring-buffer: Protect ring_buffer_reset() from reentrancy
+    - serial: core: Fix initializing and restoring termios speed
+    - ifb: fix building without CONFIG_NET_CLS_ACT
+    - xen/balloon: add late_initcall_sync() for initial ballooning done
+    - ovl: fix use after free in struct ovl_aio_req
+    - ovl: fix filattr copy-up failure
+    - PCI: pci-bridge-emul: Fix emulation of W1C bits
+    - PCI: cadence: Add cdns_plat_pcie_probe() missing return
+    - cxl/pci: Fix NULL vs ERR_PTR confusion
+    - PCI: aardvark: Do not clear status bits of masked interrupts
+    - PCI: aardvark: Fix checking for link up via LTSSM state
+    - PCI: aardvark: Do not unmask unused interrupts
+    - PCI: aardvark: Fix reporting Data Link Layer Link Active
+    - PCI: aardvark: Fix configuring Reference clock
+    - PCI: aardvark: Fix return value of MSI domain .alloc() method
+    - PCI: aardvark: Read all 16-bits from PCIE_MSI_PAYLOAD_REG
+    - PCI: aardvark: Fix support for bus mastering and PCI_COMMAND on emulated
+      bridge
+    - PCI: aardvark: Fix support for PCI_BRIDGE_CTL_BUS_RESET on emulated bridge
+    - PCI: aardvark: Set PCI Bridge Class Code to PCI Bridge
+    - PCI: aardvark: Fix support for PCI_ROM_ADDRESS1 on emulated bridge
+    - quota: check block number when reading the block in quota file
+    - quota: correct error number in free_dqentry()
+    - cifs: To match file servers, make sure the server hostname matches
+    - cifs: set a minimum of 120s for next dns resolution
+    - mfd: simple-mfd-i2c: Select MFD_CORE to fix build error
+    - pinctrl: core: fix possible memory leak in pinctrl_enable()
+    - coresight: cti: Correct the parameter for pm_runtime_put
+    - coresight: trbe: Fix incorrect access of the sink specific data
+    - coresight: trbe: Defer the probe on offline CPUs
+    - iio: buffer: check return value of kstrdup_const()
+    - iio: buffer: Fix memory leak in iio_buffers_alloc_sysfs_and_mask()
+    - iio: buffer: Fix memory leak in __iio_buffer_alloc_sysfs_and_mask()
+    - iio: buffer: Fix memory leak in iio_buffer_register_legacy_sysfs_groups()
+    - drivers: iio: dac: ad5766: Fix dt property name
+    - iio: dac: ad5446: Fix ad5622_write() return value
+    - iio: ad5770r: make devicetree property reading consistent
+    - Documentation:devicetree:bindings:iio:dac: Fix val
+    - USB: serial: keyspan: fix memleak on probe errors
+    - serial: 8250: fix racy uartclk update
+    - ksmbd: set unique value to volume serial field in FS_VOLUME_INFORMATION
+    - io-wq: serialize hash clear with wakeup
+    - serial: 8250: Fix reporting real baudrate value in c_ospeed field
+    - Revert "serial: 8250: Fix reporting real baudrate value in c_ospeed field"
+    - most: fix control-message timeouts
+    - USB: iowarrior: fix control-message timeouts
+    - USB: chipidea: fix interrupt deadlock
+    - power: supply: max17042_battery: Clear status bits in interrupt handler
+    - component: do not leave master devres group open after bind
+    - dma-buf: WARN on dmabuf release with pending attachments
+    - drm: panel-orientation-quirks: Update the Lenovo Ideapad D330 quirk (v2)
+    - drm: panel-orientation-quirks: Add quirk for KD Kurio Smart C15200 2-in-1
+    - drm: panel-orientation-quirks: Add quirk for the Samsung Galaxy Book 10.6
+    - Bluetooth: sco: Fix lock_sock() blockage by memcpy_from_msg()
+    - Bluetooth: fix use-after-free error in lock_sock_nested()
+    - Bluetooth: call sock_hold earlier in sco_conn_del
+    - drm/panel-orientation-quirks: add Valve Steam Deck
+    - rcutorture: Avoid problematic critical section nesting on PREEMPT_RT
+    - platform/x86: wmi: do not fail if disabling fails
+    - drm/amdgpu: move iommu_resume before ip init/resume
+    - MIPS: lantiq: dma: add small delay after reset
+    - MIPS: lantiq: dma: reset correct number of channel
+    - locking/lockdep: Avoid RCU-induced noinstr fail
+    - net: sched: update default qdisc visibility after Tx queue cnt changes
+    - rcu-tasks: Move RTGS_WAIT_CBS to beginning of rcu_tasks_kthread() loop
+    - smackfs: Fix use-after-free in netlbl_catmap_walk()
+    - ath11k: Align bss_chan_info structure with firmware
+    - crypto: aesni - check walk.nbytes instead of err
+    - x86/mm/64: Improve stack overflow warnings
+    - x86: Increase exception stack sizes
+    - mwifiex: Run SET_BSS_MODE when changing from P2P to STATION vif-type
+    - mwifiex: Properly initialize private structure on interface type changes
+    - spi: Check we have a spi_device_id for each DT compatible
+    - fscrypt: allow 256-bit master keys with AES-256-XTS
+    - drm/amdgpu: Fix MMIO access page fault
+    - drm/amd/display: Fix null pointer dereference for encoders
+    - selftests: net: fib_nexthops: Wait before checking reported idle time
+    - ath11k: Avoid reg rules update during firmware recovery
+    - ath11k: add handler for scan event WMI_SCAN_EVENT_DEQUEUED
+    - ath11k: Change DMA_FROM_DEVICE to DMA_TO_DEVICE when map reinjected packets
+    - ath10k: high latency fixes for beacon buffer
+    - octeontx2-pf: Enable promisc/allmulti match MCAM entries.
+    - media: mt9p031: Fix corrupted frame after restarting stream
+    - media: netup_unidvb: handle interrupt properly according to the firmware
+    - media: atomisp: Fix error handling in probe
+    - media: stm32: Potential NULL pointer dereference in dcmi_irq_thread()
+    - media: uvcvideo: Set capability in s_param
+    - media: uvcvideo: Return -EIO for control errors
+    - media: uvcvideo: Set unique vdev name based in type
+    - media: vidtv: Fix memory leak in remove
+    - media: s5p-mfc: fix possible null-pointer dereference in s5p_mfc_probe()
+    - media: s5p-mfc: Add checking to s5p_mfc_probe().
+    - media: videobuf2: rework vb2_mem_ops API
+    - media: imx: set a media_device bus_info string
+    - media: rcar-vin: Use user provided buffers when starting
+    - media: mceusb: return without resubmitting URB in case of -EPROTO error.
+    - ia64: don't do IA64_CMPXCHG_DEBUG without CONFIG_PRINTK
+    - rtw88: fix RX clock gate setting while fifo dump
+    - brcmfmac: Add DMI nvram filename quirk for Cyberbook T116 tablet
+    - media: rcar-csi2: Add checking to rcsi2_start_receiver()
+    - ipmi: Disable some operations during a panic
+    - fs/proc/uptime.c: Fix idle time reporting in /proc/uptime
+    - kselftests/sched: cleanup the child processes
+    - ACPICA: Avoid evaluating methods too early during system resume
+    - cpufreq: Make policy min/max hard requirements
+    - ice: Move devlink port to PF/VF struct
+    - media: imx-jpeg: Fix possible null pointer dereference
+    - media: ipu3-imgu: imgu_fmt: Handle properly try
+    - media: ipu3-imgu: VIDIOC_QUERYCAP: Fix bus_info
+    - media: usb: dvd-usb: fix uninit-value bug in dibusb_read_eeprom_byte()
+    - net-sysfs: try not to restart the syscall if it will fail eventually
+    - drm/amdkfd: rm BO resv on validation to avoid deadlock
+    - tracefs: Have tracefs directories not set OTH permission bits by default
+    - tracing: Disable "other" permission bits in the tracefs files
+    - ath: dfs_pattern_detector: Fix possible null-pointer dereference in
+      channel_detector_create()
+    - KVM: arm64: Propagate errors from __pkvm_prot_finalize hypercall
+    - mmc: moxart: Fix reference count leaks in moxart_probe
+    - iov_iter: Fix iov_iter_get_pages{,_alloc} page fault return value
+    - ACPI: battery: Accept charges over the design capacity as full
+    - ACPI: scan: Release PM resources blocked by unused objects
+    - drm/amd/display: fix null pointer deref when plugging in display
+    - drm/amdkfd: fix resume error when iommu disabled in Picasso
+    - net: phy: micrel: make *-skew-ps check more lenient
+    - leaking_addresses: Always print a trailing newline
+    - thermal/core: Fix null pointer dereference in thermal_release()
+    - drm/msm: prevent NULL dereference in msm_gpu_crashstate_capture()
+    - thermal/drivers/tsens: Add timeout to get_temp_tsens_valid
+    - block: bump max plugged deferred size from 16 to 32
+    - floppy: fix calling platform_device_unregister() on invalid drives
+    - md: update superblock after changing rdev flags in state_store
+    - memstick: r592: Fix a UAF bug when removing the driver
+    - locking/rwsem: Disable preemption for spinning region
+    - lib/xz: Avoid overlapping memcpy() with invalid input with in-place
+      decompression
+    - lib/xz: Validate the value before assigning it to an enum variable
+    - workqueue: make sysfs of unbound kworker cpumask more clever
+    - tracing/cfi: Fix cmp_entries_* functions signature mismatch
+    - mt76: mt7915: fix an off-by-one bound check
+    - mwl8k: Fix use-after-free in mwl8k_fw_state_machine()
+    - iwlwifi: change all JnP to NO-160 configuration
+    - block: remove inaccurate requeue check
+    - media: allegro: ignore interrupt if mailbox is not initialized
+    - drm/amdgpu/pm: properly handle sclk for profiling modes on vangogh
+    - nvmet: fix use-after-free when a port is removed
+    - nvmet-rdma: fix use-after-free when a port is removed
+    - nvmet-tcp: fix use-after-free when a port is removed
+    - nvme: drop scan_lock and always kick requeue list when removing namespaces
+    - samples/bpf: Fix application of sizeof to pointer
+    - arm64: vdso32: suppress error message for 'make mrproper'
+    - PM: hibernate: Get block device exclusively in swsusp_check()
+    - selftests: kvm: fix mismatched fclose() after popen()
+    - selftests/bpf: Fix perf_buffer test on system with offline cpus
+    - iwlwifi: mvm: disable RX-diversity in powersave
+    - smackfs: use __GFP_NOFAIL for smk_cipso_doi()
+    - ARM: clang: Do not rely on lr register for stacktrace
+    - gre/sit: Don't generate link-local addr if addr_gen_mode is
+      IN6_ADDR_GEN_MODE_NONE
+    - can: bittiming: can_fixup_bittiming(): change type of tseg1 and alltseg to
+      unsigned int
+    - gfs2: Cancel remote delete work asynchronously
+    - gfs2: Fix glock_hash_walk bugs
+    - ARM: 9136/1: ARMv7-M uses BE-8, not BE-32
+    - tools/latency-collector: Use correct size when writing queue_full_warning
+    - vrf: run conntrack only in context of lower/physdev for locally generated
+      packets
+    - net: annotate data-race in neigh_output()
+    - ACPI: AC: Quirk GK45 to skip reading _PSR
+    - ACPI: resources: Add one more Medion model in IRQ override quirk
+    - btrfs: reflink: initialize return value to 0 in btrfs_extent_same()
+    - btrfs: do not take the uuid_mutex in btrfs_rm_device
+    - spi: bcm-qspi: Fix missing clk_disable_unprepare() on error in
+      bcm_qspi_probe()
+    - wcn36xx: Correct band/freq reporting on RX
+    - wcn36xx: Fix packet drop on resume
+    - Revert "wcn36xx: Enable firmware link monitoring"
+    - ftrace: do CPU checking after preemption disabled
+    - inet: remove races in inet{6}_getname()
+    - x86/hyperv: Protect set_hv_tscchange_cb() against getting preempted
+    - drm/amd/display: dcn20_resource_construct reduce scope of FPU enabled
+    - perf/x86/intel: Fix ICL/SPR INST_RETIRED.PREC_DIST encodings
+    - parisc: fix warning in flush_tlb_all
+    - task_stack: Fix end_of_stack() for architectures with upwards-growing stack
+    - erofs: don't trigger WARN() when decompression fails
+    - parisc/unwind: fix unwinder when CONFIG_64BIT is enabled
+    - parisc/kgdb: add kgdb_roundup() to make kgdb work with idle polling
+    - netfilter: conntrack: set on IPS_ASSURED if flows enters internal stream
+      state
+    - selftests/bpf: Fix strobemeta selftest regression
+    - fbdev/efifb: Release PCI device's runtime PM ref during FB destroy
+    - drm/bridge: anx7625: Propagate errors from sp_tx_rst_aux()
+    - perf/x86/intel/uncore: Fix Intel SPR CHA event constraints
+    - perf/x86/intel/uncore: Fix Intel SPR IIO event constraints
+    - perf/x86/intel/uncore: Fix Intel SPR M2PCIE event constraints
+    - perf/x86/intel/uncore: Fix Intel SPR M3UPI event constraints
+    - drm/bridge: it66121: Initialize {device,vendor}_ids
+    - drm/bridge: it66121: Wait for next bridge to be probed
+    - Bluetooth: fix init and cleanup of sco_conn.timeout_work
+    - libbpf: Don't crash on object files with no symbol tables
+    - Bluetooth: hci_uart: fix GPF in h5_recv
+    - rcu: Fix existing exp request check in sync_sched_exp_online_cleanup()
+    - MIPS: lantiq: dma: fix burst length for DEU
+    - x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
+    - objtool: Handle __sanitize_cov*() tail calls
+    - net/mlx5: Publish and unpublish all devlink parameters at once
+    - drm/v3d: fix wait for TMU write combiner flush
+    - crypto: sm4 - Do not change section of ck and sbox
+    - virtio-gpu: fix possible memory allocation failure
+    - lockdep: Let lock_is_held_type() detect recursive read as read
+    - net: net_namespace: Fix undefined member in key_remove_domain()
+    - net: phylink: don't call netif_carrier_off() with NULL netdev
+    - drm: bridge: it66121: Fix return value it66121_probe
+    - spi: Fixed division by zero warning
+    - cgroup: Make rebind_subsystems() disable v2 controllers all at once
+    - wcn36xx: Fix Antenna Diversity Switching
+    - wilc1000: fix possible memory leak in cfg_scan_result()
+    - Bluetooth: btmtkuart: fix a memleak in mtk_hci_wmt_sync
+    - drm/amdgpu: Fix crash on device remove/driver unload
+    - drm/amd/display: Pass display_pipe_params_st as const in DML
+    - drm/amdgpu: move amdgpu_virt_release_full_gpu to fini_early stage
+    - crypto: caam - disable pkc for non-E SoCs
+    - crypto: qat - power up 4xxx device
+    - Bluetooth: hci_h5: Fix (runtime)suspend issues on RTL8723BS HCIs
+    - bnxt_en: Check devlink allocation and registration status
+    - qed: Don't ignore devlink allocation failures
+    - rxrpc: Fix _usecs_to_jiffies() by using usecs_to_jiffies()
+    - mptcp: do not shrink snd_nxt when recovering
+    - fortify: Fix dropped strcpy() compile-time write overflow check
+    - mac80211: twt: don't use potentially unaligned pointer
+    - cfg80211: always free wiphy specific regdomain
+    - net/mlx5: Accept devlink user input after driver initialization complete
+    - net: dsa: rtl8366rb: Fix off-by-one bug
+    - net: dsa: rtl8366: Fix a bug in deleting VLANs
+    - bpf/tests: Fix error in tail call limit tests
+    - ath11k: fix some sleeping in atomic bugs
+    - ath11k: Avoid race during regd updates
+    - ath11k: fix packet drops due to incorrect 6 GHz freq value in rx status
+    - ath11k: Fix memory leak in ath11k_qmi_driver_event_work
+    - gve: DQO: avoid unused variable warnings
+    - ath10k: Fix missing frame timestamp for beacon/probe-resp
+    - ath10k: sdio: Add missing BH locking around napi_schdule()
+    - drm/ttm: stop calling tt_swapin in vm_access
+    - arm64: mm: update max_pfn after memory hotplug
+    - drm/amdgpu: fix warning for overflow check
+    - libbpf: Fix skel_internal.h to set errno on loader retval < 0
+    - media: em28xx: add missing em28xx_close_extension
+    - media: meson-ge2d: Fix rotation parameter changes detection in
+      'ge2d_s_ctrl()'
+    - media: cxd2880-spi: Fix a null pointer dereference on error handling path
+    - media: ttusb-dec: avoid release of non-acquired mutex
+    - media: dvb-usb: fix ununit-value in az6027_rc_query
+    - media: imx258: Fix getting clock frequency
+    - media: v4l2-ioctl: S_CTRL output the right value
+    - media: mtk-vcodec: venc: fix return value when start_streaming fails
+    - media: TDA1997x: handle short reads of hdmi info frame.
+    - media: mtk-vpu: Fix a resource leak in the error handling path of
+      'mtk_vpu_probe()'
+    - media: imx-jpeg: Fix the error handling path of 'mxc_jpeg_probe()'
+    - media: i2c: ths8200 needs V4L2_ASYNC
+    - media: sun6i-csi: Allow the video device to be open multiple times
+    - media: radio-wl1273: Avoid card name truncation
+    - media: si470x: Avoid card name truncation
+    - media: tm6000: Avoid card name truncation
+    - media: cx23885: Fix snd_card_free call on null card pointer
+    - media: atmel: fix the ispck initialization
+    - scs: Release kasan vmalloc poison in scs_free process
+    - kprobes: Do not use local variable when creating debugfs file
+    - crypto: ecc - fix CRYPTO_DEFAULT_RNG dependency
+    - drm: fb_helper: fix CONFIG_FB dependency
+    - cpuidle: Fix kobject memory leaks in error paths
+    - media: em28xx: Don't use ops->suspend if it is NULL
+    - ath10k: Don't always treat modem stop events as crashes
+    - ath9k: Fix potential interrupt storm on queue reset
+    - PM: EM: Fix inefficient states detection
+    - x86/insn: Use get_unaligned() instead of memcpy()
+    - EDAC/amd64: Handle three rank interleaving mode
+    - rcu: Always inline rcu_dynticks_task*_{enter,exit}()
+    - rcu: Fix rcu_dynticks_curr_cpu_in_eqs() vs noinstr
+    - netfilter: nft_dynset: relax superfluous check on set updates
+    - media: venus: fix vpp frequency calculation for decoder
+    - media: dvb-frontends: mn88443x: Handle errors of clk_prepare_enable()
+    - crypto: ccree - avoid out-of-range warnings from clang
+    - crypto: qat - detect PFVF collision after ACK
+    - crypto: qat - disregard spurious PFVF interrupts
+    - hwrng: mtk - Force runtime pm ops for sleep ops
+    - ima: fix deadlock when traversing "ima_default_rules".
+    - b43legacy: fix a lower bounds test
+    - b43: fix a lower bounds test
+    - gve: Recover from queue stall due to missed IRQ
+    - gve: Track RX buffer allocation failures
+    - mmc: sdhci-omap: Fix NULL pointer exception if regulator is not configured
+    - mmc: sdhci-omap: Fix context restore
+    - memstick: avoid out-of-range warning
+    - memstick: jmb38x_ms: use appropriate free function in jmb38x_ms_alloc_host()
+    - net, neigh: Fix NTF_EXT_LEARNED in combination with NTF_USE
+    - hwmon: Fix possible memleak in __hwmon_device_register()
+    - hwmon: (pmbus/lm25066) Let compiler determine outer dimension of
+      lm25066_coeff
+    - ath10k: fix max antenna gain unit
+    - kernel/sched: Fix sched_fork() access an invalid sched_task_group
+    - net: fealnx: fix build for UML
+    - net: intel: igc_ptp: fix build for UML
+    - net: tulip: winbond-840: fix build for UML
+    - tcp: switch orphan_count to bare per-cpu counters
+    - crypto: octeontx2 - set assoclen in aead_do_fallback()
+    - thermal/core: fix a UAF bug in __thermal_cooling_device_register()
+    - drm/msm/dsi: do not enable irq handler before powering up the host
+    - drm/msm: Fix potential Oops in a6xx_gmu_rpmh_init()
+    - drm/msm: potential error pointer dereference in init()
+    - drm/msm: unlock on error in get_sched_entity()
+    - drm/msm: fix potential NULL dereference in cleanup
+    - drm/msm: uninitialized variable in msm_gem_import()
+    - net: stream: don't purge sk_error_queue in sk_stream_kill_queues()
+    - thermal/drivers/qcom/lmh: make QCOM_LMH depends on QCOM_SCM
+    - mailbox: Remove WARN_ON for async_cb.cb in cmdq_exec_done
+    - media: ivtv: fix build for UML
+    - media: ir_toy: assignment to be16 should be of correct type
+    - mmc: mxs-mmc: disable regulator on error and in the remove function
+    - io-wq: Remove duplicate code in io_workqueue_create()
+    - block: ataflop: fix breakage introduced at blk-mq refactoring
+    - platform/x86: thinkpad_acpi: Fix bitwise vs. logical warning
+    - mailbox: mtk-cmdq: Validate alias_id on probe
+    - mailbox: mtk-cmdq: Fix local clock ID usage
+    - ACPI: PM: Turn off unused wakeup power resources
+    - ACPI: PM: Fix sharing of wakeup power resources
+    - drm/amdkfd: Fix an inappropriate error handling in allloc memory of gpu
+    - mt76: mt7921: fix endianness in mt7921_mcu_tx_done_event
+    - mt76: mt7915: fix endianness warning in mt7915_mac_add_txs_skb
+    - mt76: mt7921: fix endianness warning in mt7921_update_txs
+    - mt76: mt7615: fix endianness warning in mt7615_mac_write_txwi
+    - mt76: mt7915: fix info leak in mt7915_mcu_set_pre_cal()
+    - mt76: connac: fix mt76_connac_gtk_rekey_tlv usage
+    - mt76: fix build error implicit enumeration conversion
+    - mt76: mt7921: fix survey-dump reporting
+    - mt76: mt76x02: fix endianness warnings in mt76x02_mac.c
+    - mt76: mt7921: Fix out of order process by invalid event pkt
+    - mt76: mt7915: fix potential overflow of eeprom page index
+    - mt76: mt7915: fix bit fields for HT rate idx
+    - mt76: mt7921: fix dma hang in rmmod
+    - mt76: connac: fix GTK rekey offload failure on WPA mixed mode
+    - mt76: overwrite default reg_ops if necessary
+    - mt76: mt7921: report HE MU radiotap
+    - mt76: mt7921: fix firmware usage of RA info using legacy rates
+    - mt76: mt7921: fix kernel warning from cfg80211_calculate_bitrate
+    - mt76: mt7921: always wake device if necessary in debugfs
+    - mt76: mt7915: fix hwmon temp sensor mem use-after-free
+    - mt76: mt7615: fix hwmon temp sensor mem use-after-free
+    - mt76: mt7915: fix possible infinite loop release semaphore
+    - mt76: mt7921: fix retrying release semaphore without end
+    - mt76: mt7615: fix monitor mode tear down crash
+    - mt76: connac: fix possible NULL pointer dereference in
+      mt76_connac_get_phy_mode_v2
+    - mt76: mt7915: fix sta_rec_wtbl tag len
+    - mt76: mt7915: fix muar_idx in mt7915_mcu_alloc_sta_req()
+    - rsi: stop thread firstly in rsi_91x_init() error handling
+    - mwifiex: Send DELBA requests according to spec
+    - iwlwifi: mvm: reset PM state on unsuccessful resume
+    - iwlwifi: pnvm: don't kmemdup() more than we have
+    - iwlwifi: pnvm: read EFI data only if long enough
+    - net: enetc: unmap DMA in enetc_send_cmd()
+    - phy: micrel: ksz8041nl: do not use power down mode
+    - nbd: Fix use-after-free in pid_show
+    - nvme-rdma: fix error code in nvme_rdma_setup_ctrl
+    - PM: hibernate: fix sparse warnings
+    - clocksource/drivers/timer-ti-dm: Select TIMER_OF
+    - x86/sev: Fix stack type check in vc_switch_off_ist()
+    - drm/msm: Fix potential NULL dereference in DPU SSPP
+    - drm/msm/dsi: fix wrong type in msm_dsi_host
+    - crypto: tcrypt - fix skcipher multi-buffer tests for 1420B blocks
+    - smackfs: use netlbl_cfg_cipsov4_del() for deleting cipso_v4_doi
+    - KVM: selftests: Fix nested SVM tests when built with clang
+    - libbpf: Fix memory leak in btf__dedup()
+    - bpftool: Avoid leaking the JSON writer prepared for program metadata
+    - libbpf: Fix overflow in BTF sanity checks
+    - libbpf: Fix BTF header parsing checks
+    - mt76: mt7615: mt7622: fix ibss and meshpoint
+    - s390/gmap: validate VMA in __gmap_zap()
+    - s390/gmap: don't unconditionally call pte_unmap_unlock() in __gmap_zap()
+    - s390/mm: validate VMA in PGSTE manipulation functions
+    - s390/mm: fix VMA and page table handling code in storage key handling
+      functions
+    - s390/uv: fully validate the VMA before calling follow_page()
+    - KVM: s390: pv: avoid double free of sida page
+    - KVM: s390: pv: avoid stalls for kvm_s390_pv_init_vm
+    - irq: mips: avoid nested irq_enter()
+    - net: dsa: avoid refcount warnings when ->port_{fdb,mdb}_del returns error
+    - ARM: 9142/1: kasan: work around LPAE build warning
+    - ath10k: fix module load regression with iram-recovery feature
+    - block: ataflop: more blk-mq refactoring fixes
+    - blk-cgroup: synchronize blkg creation against policy deactivation
+    - libbpf: Fix off-by-one bug in bpf_core_apply_relo()
+    - tpm: fix Atmel TPM crash caused by too frequent queries
+    - tpm_tis_spi: Add missing SPI ID
+    - libbpf: Fix endianness detection in BPF_CORE_READ_BITFIELD_PROBED()
+    - tcp: don't free a FIN sk_buff in tcp_remove_empty_skb()
+    - tracing: Fix missing trace_boot_init_histograms kstrdup NULL checks
+    - cpufreq: intel_pstate: Fix cpu->pstate.turbo_freq initialization
+    - spi: spi-rpc-if: Check return value of rpcif_sw_init()
+    - samples/kretprobes: Fix return value if register_kretprobe() failed
+    - KVM: s390: Fix handle_sske page fault handling
+    - libertas_tf: Fix possible memory leak in probe and disconnect
+    - libertas: Fix possible memory leak in probe and disconnect
+    - wcn36xx: add proper DMA memory barriers in rx path
+    - wcn36xx: Fix discarded frames due to wrong sequence number
+    - bpf: Avoid races in __bpf_prog_run() for 32bit arches
+    - bpf: Fixes possible race in update_prog_stats() for 32bit arches
+    - wcn36xx: Channel list update before hardware scan
+    - drm/amdgpu: fix a potential memory leak in amdgpu_device_fini_sw()
+    - drm/amdgpu/gmc6: fix DMA mask from 44 to 40 bits
+    - selftests/bpf: Fix fd cleanup in sk_lookup test
+    - selftests/bpf: Fix memory leak in test_ima
+    - sctp: allow IP fragmentation when PLPMTUD enters Error state
+    - sctp: reset probe_timer in sctp_transport_pl_update
+    - sctp: subtract sctphdr len in sctp_transport_pl_hlen
+    - sctp: return true only for pathmtu update in sctp_transport_pl_toobig
+    - net: amd-xgbe: Toggle PLL settings during rate change
+    - ipmi: kcs_bmc: Fix a memory leak in the error handling path of
+      'kcs_bmc_serio_add_device()'
+    - nfp: fix NULL pointer access when scheduling dim work
+    - nfp: fix potential deadlock when canceling dim work
+    - net: phylink: avoid mvneta warning when setting pause parameters
+    - net: bridge: fix uninitialized variables when BRIDGE_CFM is disabled
+    - selftests: net: bridge: update IGMP/MLD membership interval value
+    - crypto: pcrypt - Delay write to padata->info
+    - selftests/bpf: Fix fclose/pclose mismatch in test_progs
+    - udp6: allow SO_MARK ctrl msg to affect routing
+    - ibmvnic: don't stop queue in xmit
+    - ibmvnic: Process crqs after enabling interrupts
+    - ibmvnic: delay complete()
+    - selftests: mptcp: fix proto type in link_failure tests
+    - skmsg: Lose offset info in sk_psock_skb_ingress
+    - cgroup: Fix rootcg cpu.stat guest double counting
+    - bpf: Fix propagation of bounds from 64-bit min/max into 32-bit and var_off.
+    - bpf: Fix propagation of signed bounds from 64-bit min/max into 32-bit.
+    - of: unittest: fix EXPECT text for gpio hog errors
+    - cpufreq: Fix parameter in parse_perf_domain()
+    - staging: r8188eu: fix memory leak in rtw_set_key
+    - arm64: dts: meson: sm1: add Ethernet PHY reset line for ODROID-C4/HC4
+    - iio: st_sensors: disable regulators after device unregistration
+    - RDMA/rxe: Fix wrong port_cap_flags
+    - ARM: dts: BCM5301X: Fix memory nodes names
+    - arm64: dts: broadcom: bcm4908: Fix UART clock name
+    - clk: mvebu: ap-cpu-clk: Fix a memory leak in error handling paths
+    - scsi: pm80xx: Fix lockup in outbound queue management
+    - scsi: qla2xxx: edif: Use link event to wake up app
+    - scsi: lpfc: Fix NVMe I/O failover to non-optimized path
+    - ARM: s3c: irq-s3c24xx: Fix return value check for s3c24xx_init_intc()
+    - arm64: dts: rockchip: Fix GPU register width for RK3328
+    - ARM: dts: qcom: msm8974: Add xo_board reference clock to DSI0 PHY
+    - RDMA/bnxt_re: Fix query SRQ failure
+    - arm64: dts: ti: k3-j721e-main: Fix "max-virtual-functions" in PCIe EP nodes
+    - arm64: dts: ti: k3-j721e-main: Fix "bus-range" upto 256 bus number for PCIe
+    - arm64: dts: ti: j7200-main: Fix "vendor-id"/"device-id" properties of pcie
+      node
+    - arm64: dts: ti: j7200-main: Fix "bus-range" upto 256 bus number for PCIe
+    - arm64: dts: meson-g12a: Fix the pwm regulator supply properties
+    - arm64: dts: meson-g12b: Fix the pwm regulator supply properties
+    - arm64: dts: meson-sm1: Fix the pwm regulator supply properties
+    - bus: ti-sysc: Fix timekeeping_suspended warning on resume
+    - ARM: dts: at91: tse850: the emac<->phy interface is rmii
+    - arm64: dts: qcom: sc7180: Base dynamic CPU power coefficients in reality
+    - soc: qcom: llcc: Disable MMUHWT retention
+    - arm64: dts: qcom: sc7280: fix display port phy reg property
+    - scsi: dc395: Fix error case unwinding
+    - MIPS: loongson64: make CPU_LOONGSON64 depends on MIPS_FP_SUPPORT
+    - JFS: fix memleak in jfs_mount
+    - pinctrl: renesas: rzg2l: Fix missing port register 21h
+    - ASoC: wcd9335: Use correct version to initialize Class H
+    - arm64: dts: qcom: msm8916: Fix Secondary MI2S bit clock
+    - arm64: dts: renesas: beacon: Fix Ethernet PHY mode
+    - iommu/mediatek: Fix out-of-range warning with clang
+    - arm64: dts: qcom: pm8916: Remove wrong reg-names for rtc@6000
+    - iommu/dma: Fix sync_sg with swiotlb
+    - iommu/dma: Fix arch_sync_dma for map
+    - ALSA: hda: Reduce udelay() at SKL+ position reporting
+    - ALSA: hda: Use position buffer for SKL+ again
+    - ALSA: usb-audio: Fix possible race at sync of urb completions
+    - soundwire: debugfs: use controller id and link_id for debugfs
+    - power: reset: at91-reset: check properly the return value of devm_of_iomap
+    - scsi: ufs: core: Fix ufshcd_probe_hba() prototype to match the definition
+    - scsi: ufs: core: Stop clearing UNIT ATTENTIONS
+    - scsi: megaraid_sas: Fix concurrent access to ISR between IRQ polling and
+      real interrupt
+    - scsi: pm80xx: Fix misleading log statement in pm8001_mpi_get_nvmd_resp()
+    - driver core: Fix possible memory leak in device_link_add()
+    - arm: dts: omap3-gta04a4: accelerometer irq fix
+    - ASoC: SOF: topology: do not power down primary core during topology removal
+    - iio: st_pressure_spi: Add missing entries SPI to device ID table
+    - soc/tegra: Fix an error handling path in tegra_powergate_power_up()
+    - memory: fsl_ifc: fix leak of irq and nand_irq in fsl_ifc_ctrl_probe
+    - clk: at91: check pmc node status before registering syscore ops
+    - powerpc/mem: Fix arch/powerpc/mm/mem.c:53:12: error: no previous prototype
+      for 'create_section_mapping'
+    - video: fbdev: chipsfb: use memset_io() instead of memset()
+    - powerpc: fix unbalanced node refcount in check_kvm_guest()
+    - powerpc/paravirt: correct preempt debug splat in vcpu_is_preempted()
+    - serial: 8250_dw: Drop wrong use of ACPI_PTR()
+    - usb: gadget: hid: fix error code in do_config()
+    - power: supply: rt5033_battery: Change voltage values to µV
+    - power: supply: max17040: fix null-ptr-deref in max17040_probe()
+    - scsi: csiostor: Uninitialized data in csio_ln_vnp_read_cbfn()
+    - RDMA/mlx4: Return missed an error if device doesn't support steering
+    - usb: musb: select GENERIC_PHY instead of depending on it
+    - staging: most: dim2: do not double-register the same device
+    - staging: ks7010: select CRYPTO_HASH/CRYPTO_MICHAEL_MIC
+    - RDMA/core: Set sgtable nents when using ib_dma_virt_map_sg()
+    - dyndbg: make dyndbg a known cli param
+    - powerpc/perf: Fix cycles/instructions as PM_CYC/PM_INST_CMPL in power10
+    - pinctrl: renesas: checker: Fix off-by-one bug in drive register check
+    - ARM: dts: stm32: Reduce DHCOR SPI NOR frequency to 50 MHz
+    - ARM: dts: stm32: fix STUSB1600 Type-C irq level on stm32mp15xx-dkx
+    - ARM: dts: stm32: fix SAI sub nodes register range
+    - ARM: dts: stm32: fix AV96 board SAI2 pin muxing on stm32mp15
+    - ASoC: cs42l42: Always configure both ASP TX channels
+    - ASoC: cs42l42: Correct some register default values
+    - ASoC: cs42l42: Defer probe if request_threaded_irq() returns EPROBE_DEFER
+    - soc: qcom: rpmhpd: Make power_on actually enable the domain
+    - soc: qcom: socinfo: add two missing PMIC IDs
+    - iio: buffer: Fix double-free in iio_buffers_alloc_sysfs_and_mask()
+    - usb: typec: STUSB160X should select REGMAP_I2C
+    - iio: adis: do not disabe IRQs in 'adis_init()'
+    - soundwire: bus: stop dereferencing invalid slave pointer
+    - scsi: ufs: ufshcd-pltfrm: Fix memory leak due to probe defer
+    - scsi: lpfc: Wait for successful restart of SLI3 adapter during host sg_reset
+    - serial: imx: fix detach/attach of serial console
+    - usb: dwc2: drd: fix dwc2_force_mode call in dwc2_ovr_init
+    - usb: dwc2: drd: fix dwc2_drd_role_sw_set when clock could be disabled
+    - usb: dwc2: drd: reset current session before setting the new one
+    - powerpc/booke: Disable STRICT_KERNEL_RWX, DEBUG_PAGEALLOC and KFENCE
+    - usb: dwc3: gadget: Skip resizing EP's TX FIFO if already resized
+    - firmware: qcom_scm: Fix error retval in __qcom_scm_is_call_available()
+    - soc: qcom: rpmhpd: fix sm8350_mxc's peer domain
+    - soc: qcom: apr: Add of_node_put() before return
+    - arm64: dts: qcom: pmi8994: Fix "eternal"->"external" typo in WLED node
+    - arm64: dts: qcom: sdm845: Use RPMH_CE_CLK macro directly
+    - arm64: dts: qcom: sdm845: Fix Qualcomm crypto engine bus clock
+    - pinctrl: equilibrium: Fix function addition in multiple groups
+    - ASoC: topology: Fix stub for snd_soc_tplg_component_remove()
+    - phy: qcom-qusb2: Fix a memory leak on probe
+    - phy: ti: gmii-sel: check of_get_address() for failure
+    - phy: qcom-qmp: another fix for the sc8180x PCIe definition
+    - phy: qcom-snps: Correct the FSEL_MASK
+    - phy: Sparx5 Eth SerDes: Fix return value check in sparx5_serdes_probe()
+    - serial: xilinx_uartps: Fix race condition causing stuck TX
+    - clk: at91: sam9x60-pll: use DIV_ROUND_CLOSEST_ULL
+    - clk: at91: clk-master: check if div or pres is zero
+    - clk: at91: clk-master: fix prescaler logic
+    - HID: u2fzero: clarify error check and length calculations
+    - HID: u2fzero: properly handle timeouts in usb_submit_urb
+    - powerpc/nohash: Fix __ptep_set_access_flags() and ptep_set_wrprotect()
+    - powerpc/book3e: Fix set_memory_x() and set_memory_nx()
+    - powerpc/44x/fsp2: add missing of_node_put
+    - powerpc/xmon: fix task state output
+    - ALSA: oxfw: fix functional regression for Mackie Onyx 1640i in v5.14 or
+      later
+    - iommu/dma: Fix incorrect error return on iommu deferred attach
+    - powerpc: Don't provide __kernel_map_pages() without
+      ARCH_SUPPORTS_DEBUG_PAGEALLOC
+    - ASoC: cs42l42: Correct configuring of switch inversion from ts-inv
+    - RDMA/hns: Fix initial arm_st of CQ
+    - RDMA/hns: Modify the value of MAX_LP_MSG_LEN to meet hardware compatibility
+    - ASoC: rsnd: Fix an error handling path in 'rsnd_node_count()'
+    - serial: cpm_uart: Protect udbg definitions by CONFIG_SERIAL_CPM_CONSOLE
+    - virtio_ring: check desc == NULL when using indirect with packed
+    - vdpa/mlx5: Fix clearing of VIRTIO_NET_F_MAC feature bit
+    - mips: cm: Convert to bitfield API to fix out-of-bounds access
+    - power: supply: bq27xxx: Fix kernel crash on IRQ handler register error
+    - RDMA/core: Require the driver to set the IOVA correctly during rereg_mr
+    - apparmor: fix error check
+    - rpmsg: Fix rpmsg_create_ept return when RPMSG config is not defined
+    - mtd: rawnand: intel: Fix potential buffer overflow in probe
+    - nfsd: don't alloc under spinlock in rpc_parse_scope_id
+    - rtc: ds1302: Add SPI ID table
+    - rtc: ds1390: Add SPI ID table
+    - rtc: pcf2123: Add SPI ID table
+    - remoteproc: imx_rproc: Fix TCM io memory type
+    - i2c: i801: Use PCI bus rescan mutex to protect P2SB access
+    - dmaengine: idxd: move out percpu_ref_exit() to ensure it's outside
+      submission
+    - rtc: mcp795: Add SPI ID table
+    - Input: ariel-pwrbutton - add SPI device ID table
+    - i2c: mediatek: fixing the incorrect register offset
+    - NFS: Default change_attr_type to NFS4_CHANGE_TYPE_IS_UNDEFINED
+    - NFS: Don't set NFS_INO_DATA_INVAL_DEFER and NFS_INO_INVALID_DATA
+    - NFS: Ignore the directory size when marking for revalidation
+    - NFS: Fix dentry verifier races
+    - pnfs/flexfiles: Fix misplaced barrier in nfs4_ff_layout_prepare_ds
+    - drm/bridge/lontium-lt9611uxc: fix provided connector suport
+    - drm/plane-helper: fix uninitialized variable reference
+    - PCI: aardvark: Don't spam about PIO Response Status
+    - PCI: aardvark: Fix preserving PCI_EXP_RTCTL_CRSSVE flag on emulated bridge
+    - opp: Fix return in _opp_add_static_v2()
+    - NFS: Fix deadlocks in nfs_scan_commit_list()
+    - sparc: Add missing "FORCE" target when using if_changed
+    - fs: orangefs: fix error return code of orangefs_revalidate_lookup()
+    - Input: st1232 - increase "wait ready" timeout
+    - drm/bridge: nwl-dsi: Add atomic_get_input_bus_fmts
+    - mtd: spi-nor: hisi-sfc: Remove excessive clk_disable_unprepare()
+    - PCI: uniphier: Serialize INTx masking/unmasking and fix the bit operation
+    - mtd: rawnand: arasan: Prevent an unsupported configuration
+    - mtd: core: don't remove debugfs directory if device is in use
+    - remoteproc: Fix a memory leak in an error handling path in
+      'rproc_handle_vdev()'
+    - rtc: rv3032: fix error handling in rv3032_clkout_set_rate()
+    - dmaengine: at_xdmac: call at_xdmac_axi_config() on resume path
+    - dmaengine: at_xdmac: fix AT_XDMAC_CC_PERID() macro
+    - dmaengine: stm32-dma: fix stm32_dma_get_max_width
+    - NFS: Fix up commit deadlocks
+    - NFS: Fix an Oops in pnfs_mark_request_commit()
+    - Fix user namespace leak
+    - auxdisplay: img-ascii-lcd: Fix lock-up when displaying empty string
+    - auxdisplay: ht16k33: Connect backlight to fbdev
+    - auxdisplay: ht16k33: Fix frame buffer device blanking
+    - soc: fsl: dpaa2-console: free buffer before returning from
+      dpaa2_console_read
+    - netfilter: nfnetlink_queue: fix OOB when mac header was cleared
+    - dmaengine: dmaengine_desc_callback_valid(): Check for `callback_result`
+    - dmaengine: tegra210-adma: fix pm runtime unbalance
+    - dmanegine: idxd: fix resource free ordering on driver removal
+    - dmaengine: idxd: reconfig device after device reset command
+    - signal/sh: Use force_sig(SIGKILL) instead of do_group_exit(SIGKILL)
+    - m68k: set a default value for MEMORY_RESERVE
+    - watchdog: f71808e_wdt: fix inaccurate report in WDIOC_GETTIMEOUT
+    - ar7: fix kernel builds for compiler test
+    - scsi: target: core: Remove from tmr_list during LUN unlink
+    - scsi: qla2xxx: Relogin during fabric disturbance
+    - scsi: qla2xxx: Fix gnl list corruption
+    - scsi: qla2xxx: Turn off target reset during issue_lip
+    - scsi: qla2xxx: edif: Fix app start fail
+    - scsi: qla2xxx: edif: Fix app start delay
+    - scsi: qla2xxx: edif: Flush stale events and msgs on session down
+    - scsi: qla2xxx: edif: Increase ELS payload
+    - scsi: qla2xxx: edif: Fix EDIF bsg
+    - NFSv4: Fix a regression in nfs_set_open_stateid_locked()
+    - dmaengine: idxd: fix resource leak on dmaengine driver disable
+    - i2c: xlr: Fix a resource leak in the error handling path of
+      'xlr_i2c_probe()'
+    - gpio: realtek-otto: fix GPIO line IRQ offset
+    - xen-pciback: Fix return in pm_ctrl_init()
+    - nbd: fix max value for 'first_minor'
+    - nbd: fix possible overflow for 'first_minor' in nbd_dev_add()
+    - io-wq: fix max-workers not correctly set on multi-node system
+    - net: davinci_emac: Fix interrupt pacing disable
+    - kselftests/net: add missed icmp.sh test to Makefile
+    - kselftests/net: add missed setup_loopback.sh/setup_veth.sh to Makefile
+    - kselftests/net: add missed SRv6 tests
+    - kselftests/net: add missed vrf_strict_mode_test.sh test to Makefile
+    - kselftests/net: add missed toeplitz.sh/toeplitz_client.sh to Makefile
+    - ethtool: fix ethtool msg len calculation for pause stats
+    - openrisc: fix SMP tlb flush NULL pointer dereference
+    - net: vlan: fix a UAF in vlan_dev_real_dev()
+    - net: dsa: felix: fix broken VLAN-tagged PTP under VLAN-aware bridge
+    - ice: Fix replacing VF hardware MAC to existing MAC filter
+    - ice: Fix not stopping Tx queues for VFs
+    - kdb: Adopt scheduler's task classification
+    - ACPI: PMIC: Fix intel_pmic_regs_handler() read accesses
+    - PCI: j721e: Fix j721e_pcie_probe() error path
+    - nvdimm/btt: do not call del_gendisk() if not needed
+    - scsi: bsg: Fix errno when scsi_bsg_register_queue() fails
+    - scsi: ufs: ufshpb: Use proper power management API
+    - scsi: ufs: core: Fix NULL pointer dereference
+    - scsi: ufs: ufshpb: Properly handle max-single-cmd
+    - drm/nouveau/svm: Fix refcount leak bug and missing check against null bug
+    - nvdimm/pmem: cleanup the disk if pmem_release_disk() is yet assigned
+    - block/ataflop: use the blk_cleanup_disk() helper
+    - block/ataflop: add registration bool before calling del_gendisk()
+    - block/ataflop: provide a helper for cleanup up an atari disk
+    - ataflop: remove ataflop_probe_lock mutex
+    - PCI: Do not enable AtomicOps on VFs
+    - cpufreq: intel_pstate: Clear HWP desired on suspend/shutdown and offline
+    - net: phy: fix duplex out of sync problem while changing settings
+    - block: fix device_add_disk() kobject_create_and_add() error handling
+    - drm/ttm: remove ttm_bo_vm_insert_huge()
+    - bonding: Fix a use-after-free problem when bond_sysfs_slave_add() failed
+    - octeontx2-pf: select CONFIG_NET_DEVLINK
+    - ALSA: memalloc: Catch call with NULL snd_dma_buffer pointer
+    - mfd: core: Add missing of_node_put for loop iteration
+    - mfd: cpcap: Add SPI device ID table
+    - mfd: sprd: Add SPI device ID table
+    - mfd: altera-sysmgr: Fix a mistake caused by resource_size conversion
+    - ACPI: PM: Fix device wakeup power reference counting error
+    - libbpf: Fix lookup_and_delete_elem_flags error reporting
+    - selftests/bpf/xdp_redirect_multi: Put the logs to tmp folder
+    - selftests/bpf/xdp_redirect_multi: Use arping to accurate the arp number
+    - selftests/bpf/xdp_redirect_multi: Give tcpdump a chance to terminate cleanly
+    - selftests/bpf/xdp_redirect_multi: Limit the tests in netns
+    - drm: fb_helper: improve CONFIG_FB dependency
+    - Revert "drm/imx: Annotate dma-fence critical section in commit path"
+    - drm/amdgpu/powerplay: fix sysfs_emit/sysfs_emit_at handling
+    - can: etas_es58x: es58x_rx_err_msg(): fix memory leak in error path
+    - can: mcp251xfd: mcp251xfd_chip_start(): fix error handling for
+      mcp251xfd_chip_rx_int_enable()
+    - mm/zsmalloc.c: close race window between zs_pool_dec_isolated() and
+      zs_unregister_migration()
+    - zram: off by one in read_block_state()
+    - perf bpf: Add missing free to bpf_event__print_bpf_prog_info()
+    - llc: fix out-of-bound array index in llc_sk_dev_hash()
+    - nfc: pn533: Fix double free when pn533_fill_fragment_skbs() fails
+    - litex_liteeth: Fix a double free in the remove function
+    - arm64: arm64_ftr_reg->name may not be a human-readable string
+    - arm64: pgtable: make __pte_to_phys/__phys_to_pte_val inline functions
+    - bpf, sockmap: Remove unhash handler for BPF sockmap usage
+    - bpf, sockmap: Fix race in ingress receive verdict with redirect to self
+    - bpf: sockmap, strparser, and tls are reusing qdisc_skb_cb and colliding
+    - bpf, sockmap: sk_skb data_end access incorrect when src_reg = dst_reg
+    - dmaengine: stm32-dma: fix burst in case of unaligned memory address
+    - dmaengine: stm32-dma: avoid 64-bit division in stm32_dma_get_max_width
+    - gve: Fix off by one in gve_tx_timeout()
+    - drm/i915/fb: Fix rounding error in subsampled plane size calculation
+    - init: make unknown command line param message clearer
+    - seq_file: fix passing wrong private data
+    - drm/amdgpu: fix uvd crash on Polaris12 during driver unloading
+    - net: dsa: mv88e6xxx: Don't support >1G speeds on 6191X on ports other than
+      10
+    - net/sched: sch_taprio: fix undefined behavior in ktime_mono_to_any
+    - net: hns3: fix ROCE base interrupt vector initialization bug
+    - net: hns3: fix pfc packet number incorrect after querying pfc parameters
+    - net: hns3: fix kernel crash when unload VF while it is being reset
+    - net: hns3: allow configure ETS bandwidth of all TCs
+    - net: stmmac: allow a tc-taprio base-time of zero
+    - net: ethernet: ti: cpsw_ale: Fix access to un-initialized memory
+    - net: marvell: mvpp2: Fix wrong SerDes reconfiguration order
+    - vsock: prevent unnecessary refcnt inc for nonblocking connect
+    - net/smc: fix sk_refcnt underflow on linkdown and fallback
+    - cxgb4: fix eeprom len when diagnostics not implemented
+    - selftests/net: udpgso_bench_rx: fix port argument
+    - thermal: int340x: fix build on 32-bit targets
+    - smb3: do not error on fsync when readonly
+    - ARM: 9155/1: fix early early_iounmap()
+    - ARM: 9156/1: drop cc-option fallbacks for architecture selection
+    - parisc: Fix backtrace to always include init funtion names
+    - parisc: Flush kernel data mapping in set_pte_at() when installing pte for
+      user page
+    - MIPS: fix duplicated slashes for Platform file path
+    - MIPS: fix *-pkg builds for loongson2ef platform
+    - MIPS: Fix assembly error from MIPSr2 code used within MIPS_ISA_ARCH_LEVEL
+    - x86/mce: Add errata workaround for Skylake SKX37
+    - PCI/MSI: Move non-mask check back into low level accessors
+    - PCI/MSI: Destroy sysfs before freeing entries
+    - KVM: x86: move guest_pv_has out of user_access section
+    - posix-cpu-timers: Clear task::posix_cputimers_work in copy_process()
+    - irqchip/sifive-plic: Fixup EOI failed when masked
+    - f2fs: should use GFP_NOFS for directory inodes
+    - f2fs: include non-compressed blocks in compr_written_block
+    - f2fs: fix UAF in f2fs_available_free_memory
+    - ceph: fix mdsmap decode when there are MDS's beyond max_mds
+    - erofs: fix unsafe pagevec reuse of hooked pclusters
+    - drm/i915/guc: Fix blocked context accounting
+    - block: Hold invalidate_lock in BLKDISCARD ioctl
+    - block: Hold invalidate_lock in BLKZEROOUT ioctl
+    - block: Hold invalidate_lock in BLKRESETZONE ioctl
+    - ksmbd: Fix buffer length check in fsctl_validate_negotiate_info()
+    - ksmbd: don't need 8byte alignment for request length in ksmbd_check_message
+    - dmaengine: ti: k3-udma: Set bchan to NULL if a channel request fail
+    - dmaengine: ti: k3-udma: Set r/tchan or rflow to NULL if request fail
+    - dmaengine: bestcomm: fix system boot lockups
+    - net, neigh: Enable state migration between NUD_PERMANENT and NTF_USE
+    - 9p/net: fix missing error check in p9_check_errors
+    - mm/filemap.c: remove bogus VM_BUG_ON
+    - memcg: prohibit unconditional exceeding the limit of dying tasks
+    - mm, oom: pagefault_out_of_memory: don't force global OOM for dying tasks
+    - mm, oom: do not trigger out_of_memory from the #PF
+    - mm, thp: lock filemap when truncating page cache
+    - mm, thp: fix incorrect unmap behavior for private pages
+    - mfd: dln2: Add cell for initializing DLN2 ADC
+    - video: backlight: Drop maximum brightness override for brightness zero
+    - bcache: fix use-after-free problem in bcache_device_free()
+    - bcache: Revert "bcache: use bvec_virt"
+    - PM: sleep: Avoid calling put_device() under dpm_list_mtx
+    - s390/cpumf: cpum_cf PMU displays invalid value after hotplug remove
+    - s390/cio: check the subchannel validity for dev_busid
+    - s390/tape: fix timer initialization in tape_std_assign()
+    - s390/ap: Fix hanging ioctl caused by orphaned replies
+    - s390/cio: make ccw_device_dma_* more robust
+    - remoteproc: elf_loader: Fix loading segment when is_iomem true
+    - remoteproc: Fix the wrong default value of is_iomem
+    - remoteproc: imx_rproc: Fix ignoring mapping vdev regions
+    - remoteproc: imx_rproc: Fix rsc-table name
+    - mtd: rawnand: fsmc: Fix use of SM ORDER
+    - mtd: rawnand: ams-delta: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: xway: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: mpc5121: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: gpio: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: pasemi: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: orion: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: plat_nand: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: au1550nd: Keep the driver compatible with on-die ECC engines
+    - powerpc/vas: Fix potential NULL pointer dereference
+    - powerpc/bpf: Fix write protecting JIT code
+    - powerpc/32e: Ignore ESR in instruction storage interrupt handler
+    - powerpc/powernv/prd: Unregister OPAL_MSG_PRD2 notifier during module unload
+    - powerpc/security: Use a mutex for interrupt exit code patching
+    - powerpc/64s/interrupt: Fix check_return_regs_valid() false positive
+    - powerpc/pseries/mobility: ignore ibm, platform-facilities updates
+    - powerpc/85xx: fix timebase sync issue when CONFIG_HOTPLUG_CPU=n
+    - drm/sun4i: Fix macros in sun8i_csc.h
+    - PCI: Add PCI_EXP_DEVCTL_PAYLOAD_* macros
+    - PCI: aardvark: Fix PCIe Max Payload Size setting
+    - SUNRPC: Partial revert of commit 6f9f17287e78
+    - drm/amd/display: Look at firmware version to determine using dmub on dcn21
+    - media: vidtv: move kfree(dvb) to vidtv_bridge_dev_release()
+    - cifs: fix memory leak of smb3_fs_context_dup::server_hostname
+    - ath10k: fix invalid dma_addr_t token assignment
+    - mmc: moxart: Fix null pointer dereference on pointer host
+    - selftests/x86/iopl: Adjust to the faked iopl CLI/STI usage
+    - selftests/bpf: Fix also no-alu32 strobemeta selftest
+    - arch/cc: Introduce a function to check for confidential computing features
+    - x86/sev: Add an x86 version of cc_platform_has()
+    - x86/sev: Make the #VC exception stacks part of the default stacks storage
+    - media: videobuf2: always set buffer vb2 pointer
+    - media: videobuf2-dma-sg: Fix buf->vb NULL pointer dereference
+    - Linux 5.15.3
+
+  * kernel panic: NULL pointer dereference in wb_timer_f() (LP: #1947557) //
+    Jammy update: v5.15.3 upstream stable release (LP: #1951822)
+    - blk-wbt: prevent NULL pointer dereference in wb_timer_fn
+
+  * Medion Notebook Keyboard not working (LP: #1909814) // Jammy update: v5.15.3
+    upstream stable release (LP: #1951822)
+    - ACPI: resources: Add DMI-based legacy IRQ override quirk
+
+  * Enable CONFIG_INTEL_IOMMU_DEFAULT_ON and
+    CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON on jammy 5.15 (LP: #1951440)
+    - [Config] enable Intel DMA remapping options by default
+
+  * Thinkpad E14 Gen2: Kernel panic with trackpad and trackpoint enabled
+    (LP: #1945590)
+    - SAUCE: Input: elantech - Fix stack out of bound access in
+      elantech_change_report_id()
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: LSM: Specify which LSM to display (using struct cred as input)
+    - SAUCE: selftests/seccomp: fix check of fds being assigned
+    - [Config] enable SUNRPC_DISABLE_INSECURE_ENCTYPES
+    - [Config] updateconfigs following v5.15.3, v5.15.4 import
+
+  * Miscellaneous upstream changes
+    - binder: use cred instead of task for selinux checks
+    - binder: use cred instead of task for getsecid
+    - Revert "UBUNTU: SAUCE: storvsc: use small sg_tablesize on x86"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 22 Nov 2021 13:14:15 +0100
+
+linux (5.15.0-11.11) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-11.11 -proposed tracker (LP: #1950948)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * OOPs on boot: invalid opcode: 0000 [#1] SMP NOPTI (LP: #1942215)
+    - SAUCE: ACPICA: prevent out-of-bound access with buggy DSDT
+    - [Config] disable UBSAN
+    - SAUCE: ACPICA: avoid accessing operands out-of-bounds
+
+  * Jammy update: v5.15.2 upstream stable release (LP: #1950949)
+    - KVM: x86: avoid warning with -Wbitwise-instead-of-logical
+    - Revert "x86/kvm: fix vcpu-id indexed array sizes"
+    - usb: ehci: handshake CMD_RUN instead of STS_HALT
+    - usb: gadget: Mark USB_FSL_QE broken on 64-bit
+    - usb: musb: Balance list entry in musb_gadget_queue
+    - usb-storage: Add compatibility quirk flags for iODD 2531/2541
+    - Revert "proc/wchan: use printk format instead of lookup_symbol_name()"
+    - binder: use euid from cred instead of using task
+    - binder: don't detect sender/target during buffer cleanup
+    - kfence: always use static branches to guard kfence_alloc()
+    - kfence: default to dynamic branch instead of static keys mode
+    - btrfs: fix lzo_decompress_bio() kmap leakage
+    - staging: rtl8712: fix use-after-free in rtl8712_dl_fw
+    - isofs: Fix out of bound access for corrupted isofs image
+    - comedi: dt9812: fix DMA buffers on stack
+    - comedi: ni_usb6501: fix NULL-deref in command paths
+    - comedi: vmk80xx: fix transfer-buffer overflows
+    - comedi: vmk80xx: fix bulk-buffer overflow
+    - comedi: vmk80xx: fix bulk and interrupt message timeouts
+    - staging: r8712u: fix control-message timeout
+    - staging: rtl8192u: fix control-message timeouts
+    - staging: r8188eu: fix memleak in rtw_wx_set_enc_ext
+    - media: staging/intel-ipu3: css: Fix wrong size comparison imgu_css_fw_init
+    - rsi: fix control-message timeout
+    - Linux 5.15.2
+
+  * reuseport_bpf_numa in net from ubuntu_kernel_selftests fails on ppc64le
+    (LP: #1867570)
+    - selftests/net: Fix reuseport_bpf_numa by skipping unavailable nodes
+
+  * Miscellaneous Ubuntu changes
+    - packaging: switch getabis to the linux package name
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (no-up) rename the adv7511 drm driver to adv7511_drm"
+    - Revert "UBUNTU: SAUCE: drm/i915/dp: Use max params for older panels"
+    - Revert "UBUNTU: SAUCE: i915: Fix build error due to missing struct
+      definition"
+    - selftests/core: fix conflicting types compile error for close_range()
+    - selftests: net: test_vxlan_under_vrf: fix HV connectivity test
+    - Revert "UBUNTU: SAUCE: ACPICA: prevent out-of-bound access with buggy DSDT"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 15 Nov 2021 10:12:47 +0100
+
+linux (5.15.0-10.10) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-10.10 -proposed tracker (LP: #1950133)
+
+  * Jammy update: v5.15.1 upstream stable release (LP: #1950131)
+    - sfc: Fix reading non-legacy supported link modes
+    - media: firewire: firedtv-avc: fix a buffer overflow in avc_ca_pmt()
+    - Revert "xhci: Set HCD flag to defer primary roothub registration"
+    - Revert "usb: core: hcd: Add support for deferring roothub registration"
+    - drm/amdkfd: fix boot failure when iommu is disabled in Picasso.
+    - Revert "soc: imx: gpcv2: move reset assert after requesting domain power up"
+    - ARM: 9120/1: Revert "amba: make use of -1 IRQs warn"
+    - Revert "wcn36xx: Disable bmps when encryption is disabled"
+    - drm/amdgpu: revert "Add autodump debugfs node for gpu reset v8"
+    - drm/amd/display: Revert "Directly retrain link from debugfs"
+    - Revert "drm/i915/gt: Propagate change in error status to children on unhold"
+    - ALSA: usb-audio: Add quirk for Audient iD14
+    - Linux 5.15.1
+
+  * Miscellaneous Ubuntu changes
+    - packaging: fixup previous ABI/spin to -9.9
+    - [Packaging] Drop unused d-i build-deps and packaging
+    - [Packaging] Drop now unsupported d-i/ input files
+
+  * Miscellaneous upstream changes
+    - selftests: net: properly support IPv6 in GSO GRE test
+    - signal: Add SA_IMMUTABLE to ensure forced siganls do not get changed
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 08 Nov 2021 14:43:24 +0100
+
+linux (5.15.0-9.9) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-1.1 -proposed tracker (LP: #1949876)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - [Packaging] update Ubuntu.md
+
+  * Add F81966 watchdog support (LP: #1949063)
+    - SAUCE: ODM: watchdog: f71808e_wdt: Add F81966 support
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Rewrite debian/scripts/misc/insert-changes.pl in Python
+    - [Packaging] change source package name to linux
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 04 Nov 2021 18:47:19 +0100
+
+linux (5.15.0-0.0) jammy; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 04 Nov 2021 16:47:16 +0100
+
+linux-unstable (5.15.0-8.8) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.15.0-8.8 -proposed tracker (LP: #1949436)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Drop "UBUNTU: SAUCE: cachefiles: Page leaking in
+    cachefiles_read_backing_file while vmscan is active" (LP: #1947709)
+    - Revert "UBUNTU: SAUCE: cachefiles: Page leaking in
+      cachefiles_read_backing_file while vmscan is active"
+
+  * Add l2tp.sh in net from ubuntu_kernel_selftests back (LP: #1934293)
+    - Revert "UBUNTU: SAUCE: selftests/net -- disable l2tp.sh test"
+
+  * Check for changes relevant for security certifications (LP: #1945989)
+    - [Packaging] Add fips-checks as part of finalchecks
+
+  * Add final-checks to check certificates (LP: #1947174)
+    - [Packaging] Add system trusted and revocation keys final check
+
+  * Can only reach PC3 when ethernet is plugged r8169 (LP: #1946433)
+    - r8169: Enable chip-specific ASPM regardless of PCIe ASPM status
+    - PCI/ASPM: Introduce a new helper to report ASPM capability
+    - r8169: Implement dynamic ASPM mechanism
+
+  * rtw89 kernel module for Realtek 8852 wifi is missing (LP: #1945967)
+    - rtw89: add Realtek 802.11ax driver
+    - rtw89: Remove redundant check of ret after call to rtw89_mac_enable_bb_rf
+    - rtw89: fix return value check in rtw89_cam_send_sec_key_cmd()
+    - rtw89: remove unneeded semicolon
+    - [Config] RTW89=m
+
+  * Fix A yellow screen pops up in an instant (< 1 second) and then disappears
+    before loading the system (LP: #1945932)
+    - drm/i915: Stop force enabling pipe bottom color gammma/csc
+
+  * disable CONFIG_KFENCE_STATIC_KEYS in linux 5.15 (LP: #1948038)
+    - [Config] disable CONFIG_KFENCE_STATIC_KEYS
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Remove old and unused firmware helper scripts
+    - [Packaging] Replace Perl oneliner with Bash statements
+    - rebase to v5.15
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 02 Nov 2021 08:29:45 +0100
+
+linux-unstable (5.15.0-7.7) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.15.0-7.7 -proposed tracker (LP: #1948770)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Temporarily disable signing for ppc64el and s390x
+    - packaging: switch release to Jammy
+    - rebase to v5.15-rc7
+    - [Config] GCC version update
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 26 Oct 2021 11:38:14 +0200
+
+linux-unstable (5.15.0-6.6) jammy; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-6.6 -proposed tracker (LP: #1947565)
+
+  * [impish] Remove the downstream xr-usb-uart driver (LP: #1945938)
+    - SAUCE: xr-usb-serial: remove driver
+    - [Config] update modules list
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.15-rc6
+    - [Config] update config & annotations following v5.15-rc6 rebase
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: xr-usb-serial: switch to tty_alloc_driver() and
+      tty_driver_kref_put()"
+    - Revert "UBUNTU: SAUCE: xr-usb-serial: update return code for
+      xr_usb_serial_tty_write_room() and xr_usb_serial_tty_chars_in_buffer()"
+    - Revert "UBUNTU: [Packaging] FTBFS: disable zfs"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 18 Oct 2021 12:24:45 +0200
+
+linux-unstable (5.15.0-5.5) impish; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-5.5 -proposed tracker (LP: #1946338)
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.15-rc5
+    - [Config] FB_SIMPLE=m
+    - [Config] update annotations
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 11 Oct 2021 12:14:02 +0200
+
+linux-unstable (5.15.0-4.4) impish; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-4.4 -proposed tracker (LP: #1945953)
+
+  * Fix missing HDMI audio on Intel RKL (LP: #1945556)
+    - drm/i915/audio: Use BIOS provided value for RKL HDA link
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: media: atomisp: add missing return type (fix -Werror=return-type)
+    - SAUCE: xr-usb-serial: switch to tty_alloc_driver() and tty_driver_kref_put()
+    - rebase to v5.15-rc4
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] FTBFS: disable INTEL_ATOMISP"
+    - Revert "UBUNTU: [Config] FTBFS: disable xr-usb-serial"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc4
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 04 Oct 2021 10:52:41 +0200
+
+linux-unstable (5.15.0-3.3) impish; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-3.3 -proposed tracker (LP: #1944944)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.15-rc3
+    - [Config] updateconfigs following v5.15-rc3 rebase
+    - [Packaging] correctly evaluate release in update-dkms-versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 27 Sep 2021 16:48:03 +0200
+
+linux-unstable (5.15.0-2.2) impish; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-2.2 -proposed tracker (LP: #1944423)
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.15-rc2
+    - [Config] updateconfigs following v5.15-rc2 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc2
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 21 Sep 2021 11:46:59 +0200
+
+linux-unstable (5.15.0-1.1) impish; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  *  LRMv5: switch primary version handling to kernel-versions data set
+    (LP: #1928921)
+    - [Packaging] switch to kernel-versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] remove remaining references to ports
+    - [Packaging] drop x32 architecture configs
+    - [Config] mark CONFIG_BPF_UNPRIV_DEFAULT_OFF enforced
+    - [Packaging] bump kernel version to 5.15
+    - rebase to v5.15-rc1
+    - [Config] updateconfigs following v5.15-rc1 rebase
+    - [Config] FTBFS: disable INTEL_ATOMISP
+    - [Config] FTBFS: disable xr-usb-serial
+    - [Packaging] FTBFS: disable zfs
+
+  * Miscellaneous upstream changes
+    - Revert "r8169: avoid link-up interrupt issue on RTL8106e if user enables
+      ASPM"
+    - Revert "UBUNTU: SAUCE: RDMA/core: Introduce peer memory interface"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 17 Sep 2021 11:42:25 +0200
+
+linux-unstable (5.15.0-0.0) impish; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 15 Sep 2021 11:54:10 +0200
+
+linux-unstable (5.14.0-9.9) impish; urgency=medium
+
+  * impish/linux-unstable: 5.14.0-9.9 -proposed tracker (LP: #1943022)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] NVIDIA -- Add the NVIDIA 470 driver
+    - [Packaging] NVIDIA: transition -460 and -465 to -470, transition -460-server
+      to -470-server
+
+  * Miscellaneous upstream changes
+    - vt_kdsetmode: extend console locking
+    - Bluetooth: btusb: check conditions before enabling USB ALT 3 for WBS
+    - net: dsa: mt7530: fix VLAN traffic leaks again
+    - btrfs: fix NULL pointer dereference when deleting device by invalid id
+    - Revert "floppy: reintroduce O_NDELAY fix"
+    - fscrypt: add fscrypt_symlink_getattr() for computing st_size
+    - ext4: report correct st_size for encrypted symlinks
+    - f2fs: report correct st_size for encrypted symlinks
+    - ubifs: report correct st_size for encrypted symlinks
+    - net: don't unconditionally copy_from_user a struct ifreq for socket ioctls
+    - audit: move put_tree() to avoid trim_trees refcount underflow and UAF
+    - Linux 5.14.1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 08 Sep 2021 12:20:18 +0200
+
+linux-unstable (5.14.0-8.8) impish; urgency=medium
+
+  * impish/linux-unstable: 5.14.0-8.8 -proposed tracker (LP: #1941887)
+
+  * Fix  Intel AC9560 BT function cannot turn on if BT turn off before S3 entry
+    (LP: #1941696)
+    - SAUCE: Bluetooth: btusb: add a reject table to disable msft
+
+  *  Add USB4 support for AMD SoC (LP: #1941036)
+    - thunderbolt: Add vendor specific NHI quirk for auto-clearing interrupt
+      status
+    - thunderbolt: Handle ring interrupt by reading interrupt status register
+    - thunderbolt: Do not read control adapter config space
+    - thunderbolt: Fix port linking by checking all adapters
+
+  * Support builtin revoked certificates (LP: #1932029)
+    - [Config] Enforce SYSTEM_TRUSTED_KEYS and SYSTEM_REVOCATION_KEYS
+
+  * GPIO error logs in start and dmesg after update of kernel (LP: #1937897)
+    - ODM: mfd: Check AAEON BFPI version before adding device
+
+  * initramfs-tools & kernel: use zstd as the default compression method
+    (LP: #1931725)
+    - [Config] enforce ZSTD compression
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.14
+    - [Config] RESET_MCHP_SPARX5 depends on ARCH_SPARX5
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] FTBFS: disable zfs"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 30 Aug 2021 12:57:19 +0200
+
+linux-unstable (5.14.0-7.7) impish; urgency=medium
+
+  * Please enable CONFIG_UBSAN_BOUNDS (LP: #1914685)
+    - [Config] Enable CONFIG_UBSAN_BOUNDS
+
+  * CONFIG_HARDENED_USERCOPY_FALLBACK should be disabled (LP: #1855340)
+    - [Config] Disable CONFIG_HARDENED_USERCOPY_FALLBACK
+
+  * fs: removing mandatory locks (LP: #1940392)
+    - [Config] Disable CONFIG_MANDATORY_FILE_LOCKING
+
+  * Fix kernel panic caused by legacy devices on AMD platforms (LP: #1936682)
+    - SAUCE: iommu/amd: Keep swiotlb enabled to ensure devices with 32bit DMA
+      still work
+
+  * ALSA: hda/cs8409: Add support for dolphin (LP: #1939541)
+    - ALSA: hda/cirrus: Move CS8409 HDA bridge to separate module
+    - ALSA: hda/cs8409: Move arrays of configuration to a new file
+    - ALSA: hda/cs8409: Use enums for register names and coefficients
+    - ALSA: hda/cs8409: Mask all CS42L42 interrupts on initialization
+    - ALSA: hda/cs8409: Reduce HS pops/clicks for Cyborg
+    - ALSA: hda/cs8409: Disable unnecessary Ring Sense for Cyborg/Warlock/Bullseye
+    - ALSA: hda/cs8409: Disable unsolicited responses during suspend
+    - ALSA: hda/cs8409: Disable unsolicited response for the first boot
+    - ALSA: hda/cs8409: Mask CS42L42 wake events
+    - ALSA: hda/cs8409: Simplify CS42L42 jack detect.
+    - ALSA: hda/cs8409: Prevent I2C access during suspend time
+    - ALSA: hda/cs8409: Generalize volume controls
+    - ALSA: hda/cs8409: Dont disable I2C clock between consecutive accesses
+    - ALSA: hda/cs8409: Avoid setting the same I2C address for every access
+    - ALSA: hda/cs8409: Avoid re-setting the same page as the last access
+    - ALSA: hda/cs8409: Support i2c bulk read/write functions
+    - ALSA: hda/cs8409: Separate CS8409, CS42L42 and project functions
+    - ALSA: hda/cs8409: Move codec properties to its own struct
+    - ALSA: hda/cs8409: Support multiple sub_codecs for Suspend/Resume/Unsol
+      events
+    - ALSA: hda/cs8409: Add Support to disable jack type detection for CS42L42
+    - ALSA: hda/cs8409: Add support for dolphin
+    - ALSA: hda/cs8409: Enable Full Scale Volume for Line Out Codec on Dolphin
+    - ALSA: hda/cs8409: Set fixed sample rate of 48kHz for CS42L42
+    - ALSA: hda/cs8409: Use timeout rather than retries for I2C transaction waits
+    - ALSA: hda/cs8409: Remove unnecessary delays
+    - ALSA: hda/cs8409: Follow correct CS42L42 power down sequence for suspend
+    - ALSA: hda/cs8409: Unmute/Mute codec when stream starts/stops
+    - ALSA: hda/cs8409: Prevent pops and clicks during suspend
+    - SAUCE: ALSA: hda/cs8409: Prevent pops and clicks during reboot
+    - [Config] Enable Cirrus Logic HDA bridge support
+
+  * e1000e: add handshake with the Intel CSME to support S0ix (LP: #1937252)
+    - SAUCE: e1000e: Add handshake with the CSME to support S0ix
+    - SAUCE: e1000e: Add polling mechanism to indicate CSME DPG exit
+    - SAUCE: e1000e: Additional PHY power saving in S0ix
+
+  * AMDGPU: Fix System hang after resume from suspend (LP: #1940204)
+    - SAUCE: drm/amdgpu: disable BACO support for 699F:C7 polaris12 SKU
+      temporarily
+
+  * [Regression] Audio card [8086:9d71] not detected after upgrade from linux
+    5.4 to 5.8 (LP: #1915117)
+    - [Config] set CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to y
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.14-rc7
+    - [Config] updateconfigs following 5.14-rc7 rebase
+    - [Config] Enable CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT
+    - [Config] annotations: set CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT to y
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] annotations: set
+      CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to y"
+    - Revert "UBUNTU: [Config] set CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to
+      y"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 24 Aug 2021 10:32:31 +0200
+
+linux-unstable (5.14.0-6.6) impish; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - no changes upload (to avoid picking up libc6 from -proposed)
+
+  * No changes upload (to avoid picking up libc6 from -proposed)
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 18 Aug 2021 13:41:16 +0200
+
+linux-unstable (5.14.0-5.5) impish; urgency=medium
+
+  * disable “CONFIG_HISI_DMA” config for ubuntu version (LP: #1936771)
+    - [Config] Disable CONFIG_HISI_DMA
+
+  * Dell XPS 17 (9710) PCI/internal sound card not detected  (LP: #1935850)
+    - ASoC: Intel: sof_sdw: include rt711.h for RT711 JD mode
+    - ASoC: Intel: sof_sdw: add quirk for Dell XPS 9710
+
+  * [regression] USB device is not detected during boot (LP: #1939638)
+    - SAUCE: Revert "usb: core: reduce power-on-good delay time of root hub"
+
+  * armhf build failure (LP: #1939308)
+    - SAUCE: arm: Fix instruction set selection for GCC 11
+
+  * REGRESSION: shiftfs lets sendfile fail with EINVAL (LP: #1939301)
+    - SAUCE: shiftfs: fix sendfile() invocations
+
+  * Wobbly graphics on built-in display since linux-image-5.11.0-22-generic
+    (LP: #1936708)
+    - SAUCE: drm/i915/dp: Use max params for older panels
+
+  * [SRU][H/OEM-5.10/OEM-5.13/U] Fix system hang after unplug tbt dock
+    (LP: #1938689)
+    - SAUCE: igc: fix page fault when thunderbolt is unplugged
+
+  * e1000e blocks the boot process when it tried to write checksum to its NVM
+    (LP: #1936998)
+    - SAUCE: e1000e: Do not take care about recovery NVM checksum
+
+  * [Regression] Audio card [8086:9d71] not detected after upgrade from linux
+    5.4 to 5.8 (LP: #1915117)
+    - [Config] set CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to y
+    - [Config] annotations: set CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to y
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs following 5.14-rc6 rebase
+    - rebase to v5.14-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 17 Aug 2021 17:49:15 +0200
+
+linux-unstable (5.14.0-4.4) impish; urgency=medium
+
+  * impish/linux-unstable: 5.14.0-4.4 -proposed tracker (LP: #1938566)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous upstream changes
+    - Revert "riscv: Get CPU manufacturer information"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 03 Aug 2021 14:50:27 +0200
+
+linux-unstable (5.14.0-3.3) impish; urgency=medium
+
+  * Add additional Mediatek MT7921 WiFi/BT device IDs (LP: #1937004)
+    - SAUCE: Bluetooth: btusb: Add Mediatek MT7921 support for Foxconn
+    - SAUCE: Bluetooth: btusb: Add Mediatek MT7921 support for IMC Network
+    - SAUCE: Bluetooth: btusb: Add support for Foxconn Mediatek Chip
+
+  * Fix display output on HP hybrid GFX laptops (LP: #1936296)
+    - drm/i915: Invoke another _DSM to enable MUX on HP Workstation laptops
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.14-rc3
+    - [Config] updateconfigs following 5.14-rc3 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 26 Jul 2021 12:52:38 +0200
+
+linux-unstable (5.14.0-2.2) impish; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: xr-usb-serial: update return code for xr_usb_serial_tty_write_room()
+      and xr_usb_serial_tty_chars_in_buffer()
+    - SAUCE: platform/x86: dell-uart-backlight: update return code for
+      uart_chars_in_buffer(()
+    - [Config] updateconfigs following 5.14-rc2 rebase
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] FTBFS: disable ubuntu/xr-usb-serial"
+    - Revert "UBUNTU: [Config] FTBFS: disable DELL_UART_BACKLIGHT"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc2
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 22 Jul 2021 11:03:28 +0200
+
+linux-unstable (5.14.0-1.1) impish; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] bump kernel version to 5.14
+    - [Config] updateconfigs following 5.14-rc1 rebase
+    - [Config] update annotations
+    - [Packaging] FTBFS: disable zfs
+    - [Config] FTBFS: disable DELL_UART_BACKLIGHT
+    - [Config] FTBFS: disable ubuntu/xr-usb-serial
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] update variants"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 16 Jul 2021 15:20:04 +0200
+
+linux-unstable (5.14.0-0.0) impish; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 13 Jul 2021 12:15:35 +0200
+
+linux (5.13.0-11.11) impish; urgency=medium
+
+  * impish/linux: 5.13.0-11.11 -proposed tracker (LP: #1933854)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Support builtin revoked certificates (LP: #1932029)
+    - [Packaging] build canonical-revoked-certs.pem from branch/arch certs
+    - [Packaging] Revoke 2012 UEFI signing certificate as built-in
+    - [Config] Configure CONFIG_SYSTEM_REVOCATION_KEYS with revoked keys
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Change source package name to linux
+
+  * Miscellaneous upstream changes
+    - mm/page_alloc: Correct return value of populated elements if bulk array is
+      populated
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 29 Jun 2021 07:50:25 +0200
+
+linux (5.13.0-10.10) impish; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Jun 2021 08:40:05 +0200
+
+linux-unstable (5.13.0-10.10) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-10.10 -proposed tracker (LP: #1933795)
+
+  * Pixel format change broken for Elgato Cam Link 4K (LP: #1932367)
+    - media: uvcvideo: Fix pixel format change for Elgato Cam Link 4K
+
+  * initramfs-tools & kernel: use zstd as the default compression method
+    (LP: #1931725)
+    - s390/decompressor: correct BOOT_HEAP_SIZE condition
+    - s390/boot: add zstd support
+    - [Packaging] use ZSTD to compress s390 kernels
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: tls: fix chacha+bidir tests
+    - SAUCE: selftests: icmp_redirect: support expected failures
+    - [Config] update configs and annotations after rebase to 5.13
+
+  * Miscellaneous upstream changes
+    - tls: prevent oversized sendfile() hangs by ignoring MSG_MORE
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Jun 2021 08:40:05 +0200
+
+linux-unstable (5.13.0-9.9) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-9.9 -proposed tracker (LP: #1933070)
+
+  * Add support for selective build of special drivers (LP: #1912789)
+    - [Packaging] Add support for ODM drivers
+    - [Packaging] Turn on ODM support for amd64
+    - [Packaging] Fix ODM support in actual build
+    - [Packaging] Fix ODM DRIVERS Kconfig
+
+  * Add support for IO functions of AAEON devices (LP: #1929504)
+    - ODM: [Config] update config for AAEON devices
+    - ODM: hwmon: add driver for AAEON devices
+    - ODM: leds: add driver for AAEON devices
+    - ODM: watchdog: add driver for AAEON devices
+    - ODM: gpio: add driver for AAEON devices
+    - ODM: mfd: Add support for IO functions of AAEON devices
+
+  * Disable hv-kvp-daemon.service on certain instance types (LP: #1932081)
+    - [Packaging]: Add kernel command line condition to hv-kvp-daemon service
+
+  * Fix non-working GPU on Some HP desktops (LP: #1931147)
+    - PCI: Coalesce host bridge contiguous apertures
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: seccomp: bump up timeout to 5min
+    - SAUCE: Revert "net/tls(TLS_SW): Add selftest for 'chunked' sendfile test"
+    - [Config] update annotations after rebase to 5.13-rc7
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 21 Jun 2021 10:55:36 +0200
+
+linux-unstable (5.13.0-8.8) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-8.8 -proposed tracker (LP: #1932018)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * initramfs-tools & kernel: use zstd as the default compression method
+    (LP: #1931725)
+    - [Config] use ZSTD to compress amd64 kernels
+
+  * Miscellaneous Ubuntu changes
+    - [Config] enable signing for ppc64el
+    - SAUCE: powerpc: Fix initrd corruption with relative jump labels
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 15 Jun 2021 15:07:34 +0200
+
+linux-unstable (5.13.0-7.7) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-7.7 -proposed tracker (LP: #1931840)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+    - [Packaging] resync getabis
+    - [Packaging] update helper scripts
+    - update dkms package versions
+
+  * Intel ADL-S graphics feature enabling (LP: #1931240)
+    - SAUCE: drm/i915/adl_s: ADL-S platform Update PCI ids for Mobile BGA
+
+  * Kernel package builds running out of space on builders (LP: #1930713)
+    - [Config] CONFIG_DEBUG_INFO_COMPRESSED=n
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] remove nvidia dkms build support
+    - [Config] remove now unsued do_dkms_nvidia* build variables
+    - [Config] enable signing for s390x
+    - [Config] update annotations after configs review
+    - [Config] update toolchain versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 14 Jun 2021 11:53:08 +0200
+
+linux-unstable (5.13.0-6.6) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-6.6 -proposed tracker (LP: #1931071)
+
+  * Kernel package builds running out of space on builders (LP: #1930713)
+    - [Debian] use stamps for flavour install targets
+    - [Debian] run install-$(flavour) targets during build phase
+    - [Debian] remove dh_testroot from install targets
+    - [Debian] dkms-build -- use fakeroot if not running as root
+    - [Debian] exclude $(DEBIAN)/__abi.current from linux-source
+
+  * [UBUNTU 21.04] tools/kvm_stat: Add restart delay (LP: #1921870)
+    - [Debian] install kvm_stat systemd service
+
+  * Debugging symbols (dbgsym) packages are missing GDB kernel scripts
+    (LP: #1928715)
+    - [Packaging] Build and include GDB Python scripts into debug packages
+
+  * Can't detect intel wifi 6235 (LP: #1920180)
+    - SAUCE: iwlwifi: add new pci id for 6235
+
+  * Select correct boot VGA when BIOS doesn't do it properly (LP: #1929217)
+    - vgaarb: Use ACPI HID name to find integrated GPU
+
+  * Fix kernel panic on Intel Bluetooth (LP: #1928838)
+    - Bluetooth: Shutdown controller after workqueues are flushed or cancelled
+
+  * build module CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH=m for 5.11,  5.13-rc2
+    and later (LP: #1921632)
+    - [Config] enable soundwire audio mach driver
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_SND_SOC_RT1308 can only be enabled on amd64
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 07 Jun 2021 10:45:13 +0200
+
+linux-unstable (5.13.0-5.5) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-5.5 -proposed tracker (LP: #1930205)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Config] set CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 31 May 2021 12:32:38 +0200
+
+linux-unstable (5.13.0-4.4) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-4.4 -proposed tracker (LP: #1929404)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Support importing mokx keys into revocation list from the mok table
+    (LP: #1928679)
+    - SAUCE: integrity: add informational messages when revoking certs
+
+  * Support importing mokx keys into revocation list from the mok table
+    (LP: #1928679) // CVE-2020-26541 when certificates are revoked via
+    MokListXRT.
+    - SAUCE: integrity: Load mokx certs from the EFI MOK config table
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Temporarily disable signing for ppc64el and s390x
+    - SAUCE: Revert "UBUNTU: SAUCE: overlayfs: Be more careful about copying up
+      sxid files"
+    - SAUCE: Revert "UBUNTU: SAUCE: overlayfs: Propogate nosuid from lower and
+      upper mounts"
+    - SAUCE: Revert "UBUNTU: SAUCE: overlayfs: Enable user namespace mounts"
+    - SAUCE: Revert "UBUNTU: SAUCE: overlayfs: ensure mounter privileges when
+      reading directories"
+    - SAUCE: Revert "UBUNTU: SAUCE: fs: Move SB_I_NOSUID to the top of s_iflags"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 24 May 2021 13:06:17 +0200
+
+linux-unstable (5.13.0-3.3) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-3.3 -proposed tracker (LP: #1928655)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 17 May 2021 11:55:02 +0200
+
+linux-unstable (5.13.0-2.2) impish; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] enable CONFIG_DEBUG_INFO_COMPRESSED
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] temporarily disable BPF JIT"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 14 May 2021 09:19:02 +0200
+
+linux-unstable (5.13.0-1.1) impish; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 12 May 2021 11:35:23 +0200
+
+linux-unstable (5.13.0-0.0) impish; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 11 May 2021 08:40:09 +0200
+
+linux-unstable (5.12.0-11.11) impish; urgency=medium
+
+  * Impish update: v5.12.1 upstream stable release (LP: #1927094)
+    - net: hso: fix NULL-deref on disconnect regression
+    - USB: CDC-ACM: fix poison/unpoison imbalance
+    - iwlwifi: Fix softirq/hardirq disabling in iwl_pcie_gen2_enqueue_hcmd()
+    - cfg80211: fix locking in netlink owner interface destruction
+    - mei: me: add Alder Lake P device id.
+    - Linux 5.12.1
+
+  * Packaging resync (LP: #1786013) // Impish update: v5.12.1 upstream stable
+    release (LP: #1927094)
+    - update dkms package versions
+
+  * Gigabyte R120-T33 (ARM ThunderX SoC) fails to boot in ACPI mode
+    (LP: #1925075) // Impish update: v5.12.1 upstream stable release
+    (LP: #1927094)
+    - ACPI: GTDT: Don't corrupt interrupt mappings on watchdow probe failure
+
+  * Fix kernel panic at boot on dual GFX systems (LP: #1926792) // Impish
+    update: v5.12.1 upstream stable release (LP: #1927094)
+    - drm/amdgpu: Register VGA clients after init can no longer fail
+
+  * On TGL platforms screen shows garbage when browsing website by scrolling
+    mouse (LP: #1926579) // Impish update: v5.12.1 upstream stable release
+    (LP: #1927094)
+    - SAUCE: drm/i915/display: Disable PSR2 if TGL Display stepping is B1 from A0
+
+  * CirrusLogic: Cracking noises appears in built-in speaker when output volume
+    is set >80% (LP: #1924997) // Impish update: v5.12.1 upstream stable release
+    (LP: #1927094)
+    - SAUCE: ALSA: hda/cirrus: Use CS8409 Equalizer to fix abnormal sounds on
+      Bullseye
+
+  * Enable mute/micmute LEDs and limit mic boost on EliteBook 845 G8
+    (LP: #1925415) // Impish update: v5.12.1 upstream stable release
+    (LP: #1927094)
+    - ALSA: hda/realtek: Enable mute/micmute LEDs and limit mic boost on EliteBook
+      845 G8
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: PCI: Disable broken RTIT_BAR of Intel TH"
+    - Revert "UBUNTU: [Config] temporarily disable ZFS"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 04 May 2021 18:35:54 +0200
+
+linux-unstable (5.12.0-10.10) impish; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Drop versioned ABI directory names
+    - [Packaging] getabis: Download ABIs into an unversioned directory
+    - [Packaging] final-checks: Handle unversioned ABI directories
+    - bump to impish
+    - [Config] GCC version update
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 29 Apr 2021 12:27:20 +0200
+
+linux-unstable (5.12.0-9.9) impish; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 26 Apr 2021 11:14:16 -0500
+
+linux-unstable (5.12.0-8.8) hirsute; urgency=medium
+
+  * CVE-2021-3492
+    - SAUCE: shiftfs: free allocated memory in shiftfs_btrfs_ioctl_fd_replace()
+      error paths
+    - SAUCE: shiftfs: handle copy_to_user() return values correctly
+
+  * Fix no picture from HDMI when it's plugged after boot (LP: #1924238)
+    - drm/i915/display: Handle lane polarity for DDI port
+
+  * hirsute beta desktop AMD64 ISO kernel panic on boot when booting using UEFI
+    (LP: #1922403)
+    - SAUCE: efifb: Check efifb_pci_dev before using it
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v5.12-rc8
+    - [Config] updateconfigs following 5.12-rc8 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc8
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 19 Apr 2021 11:37:27 +0200
+
+linux-unstable (5.12.0-7.7) hirsute; urgency=medium
+
+  * drm/i915: Drop force_probe requirement for Rocket Lake (LP: #1905466)
+    - drm/i915/rkl: Remove require_force_probe protection
+
+  * HP m400 cartridges fail to find NIC when deploying hirsute (LP: #1918793)
+    - PCI: xgene: Fix cfg resource mapping
+
+  * Update - Fix no screen show on display after S3 on CML-R  (LP: #1922768)
+    - drm/i915/gen9bc: Handle TGP PCH during suspend/resume
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: RDMA/core: Introduce peer memory interface
+    - Rebase to v5.12-rc7
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 12 Apr 2021 11:48:07 +0200
+
+linux-unstable (5.12.0-6.6) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * i915 doesn't support some high pixel clock 4k * 60Hz monitors (LP: #1922372)
+    - drm/i915/vbt: update DP max link rate table
+
+  * Tegra "mmc0: Timeout waiting for hardware interrupt" (LP: #1921140)
+    - SAUCE: mmc: host: Add required callbacks to set/clear CQE_EN bit
+
+  * Enable ath11k debugfs/tracing (LP: #1922033)
+    - [Config] enable ath11k debugfs/tracing
+
+  * Fix mic on P620 after S3 resume (LP: #1921757)
+    - ALSA: usb-audio: Carve out connector value checking into a helper
+    - ALSA: usb-audio: Check connector value on resume
+
+  * Miscellaneous Ubuntu changes
+    - [Config] amd64,arm64: build KFENCE support but disable it by default
+      (KFENCE_SAMPLE_INTERVAL=0)
+    - Rebase to v5.12-rc6
+
+  * Miscellaneous upstream changes
+    - drm/dp: add MSO related DPCD registers
+    - drm/i915/edp: reject modes with dimensions other than fixed mode
+    - drm/i915/edp: always add fixed mode to probed modes in ->get_modes()
+    - drm/i915/edp: read sink MSO configuration for eDP 1.4+
+    - drm/i915/reg: add stream splitter configuration definitions
+    - drm/i915/mso: add splitter state readout for platforms that support it
+    - drm/i915/mso: add splitter state check
+    - drm/i915/edp: modify fixed and downclock modes for MSO
+    - drm/i915/edp: enable eDP MSO during link training
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 07 Apr 2021 11:42:55 +0200
+
+linux-unstable (5.12.0-5.5) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * alsa/realtek: extend the delay time in the  determine_headset_type for a
+    Dell AIO (LP: #1920747)
+    - SAUCE: ALSA: hda/realtek: fix a determine_headset_type issue for a Dell AIO
+
+  * power off stress test will hang on the TGL machines (LP: #1919930)
+    - SAUCE: ASoC: SOF: Intel: TGL: set shutdown callback to hda_dsp_shutdown
+    - [Config] set SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1 to n
+
+  * lockdown on power (LP: #1855668)
+    - SAUCE: (lockdown) powerpc: lock down kernel in secure boot mode
+
+  * Miscellaneous Ubuntu changes
+    - [Config] arm64 -- unify build_image and kernel_file values
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - SAUCE: xr-usb-serial: clean up indentation
+    - SAUCE: xr-usb-serial: clean up build warnings
+    - SAUCE: apparmor: Fix build error, make sk parameter const
+    - Rebase to v5.12-rc5
+    - [Config] updateconfigs following v5.12-rc5 rebase
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (lockdown) s390: Lock down the kernel when the IPL
+      secure flag is set"
+    - Revert "UBUNTU: SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to
+      indicate secure boot mode"
+    - Revert "UBUNTU: SAUCE: (lockdown) powerpc: lock down kernel in secure boot
+      mode"
+    - Revert "UBUNTU: SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic"
+    - Revert "UBUNTU: SAUCE: (lockdown) arm64: Allow locking down the kernel under
+      EFI secure boot"
+    - Revert "UBUNTU: SAUCE: (lockdown) KEYS: Make use of platform keyring for
+      module signature verify"
+    - Revert "UBUNTU: SAUCE: (lockdown) efi: Lock down the kernel if booted in
+      secure boot mode"
+    - Revert "UBUNTU: SAUCE: (lockdown) security: lockdown: expose a hook to lock
+      the kernel down"
+    - Revert "UBUNTU: SAUCE: (lockdown) Make get_cert_list() use
+      efi_status_to_str() to print error messages."
+    - Revert "UBUNTU: SAUCE: (lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err()."
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 29 Mar 2021 12:59:38 +0200
+
+linux-unstable (5.12.0-4.4) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Fix broken efifb on graphics device without driver (LP: #1914411)
+    - SAUCE: efifb: Ensure graphics device for efifb stays at PCI D0
+
+  * Fix system sleep on TGL systems with Intel ME (LP: #1919321)
+    - SAUCE: PCI: Serialize TGL e1000e PM ops
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v5.12-rc4
+    - [Config] updateconfigs following v5.12-rc4 rebase
+
+  * Miscellaneous upstream changes
+    - riscv: dts: fu740: fix cache-controller interrupts
+    - riscv: sifive: fu740: cpu{1, 2, 3, 4} set compatible to sifive, u74-mc
+    - riscv: sifive: unmatched: update for 16GB rev3
+    - riscv: Add 3 SBI wrapper functions to get cpu manufacturer information
+    - riscv: Get CPU manufacturer information
+    - riscv: Introduce alternative mechanism to apply errata solution
+    - riscv: sifive: apply errata "cip-453" patch
+    - clk: sifive: Add pcie_aux clock in prci driver for PCIe driver
+    - clk: sifive: Use reset-simple in prci driver for PCIe driver
+    - MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver
+    - dt-bindings: PCI: Add SiFive FU740 PCIe host controller
+    - PCI: designware: Add SiFive FU740 PCIe host controller driver
+    - riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc4
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 22 Mar 2021 12:43:14 +0100
+
+linux-unstable (5.12.0-3.3) hirsute; urgency=medium
+
+  *  riscv: revert SiFive Unleashed CPUFreq (LP: #1917433)
+    - SAUCE: Revert "SiFive Unleashed CPUFreq"
+
+  * Dell Precision 5550 takes up to 10 seconds to respond when coming out of
+    sleep (LP: #1919123)
+    - SAUCE: Input: i8042 - add dmi quirk
+
+  * LRMv4: switch to signing nvidia modules via the Ubuntu Modules signing key
+    (LP: #1918134)
+    - [Packaging] sync dkms-build et al from LRMv4
+
+  * curtin: install flash-kernel in arm64 UEFI unexpected (LP: #1918427)
+    - [Packaging] Allow grub-efi-arm* to satisfy recommends on ARM
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Enable Tegra support in arm64 for NVIDIA Jetson (LP: #1918471)
+    - [Config] enable ARCH_TEGRA and all Tegra SOC's
+    - [Packaging] include modern Tegra modules
+
+  * Cirrus Audio Codec CS8409/CS42L42: Input Device does not switch to headset
+    Mic when a headset is inserted (LP: #1918378)
+    - SAUCE: ALSA: hda/cirrus: Fix Headset Mic volume control name
+
+  * Cirrus Audio Codec CS8409/CS42L42 support (LP: #1916554)
+    - ALSA: hda/cirrus: Increase AUTO_CFG_MAX_INS from 8 to 18
+    - ALSA: hda/cirrus: Add support for CS8409 HDA bridge and CS42L42 companion
+      codec.
+    - ALSA: hda/cirrus: Add jack detect interrupt support from CS42L42 companion
+      codec.
+    - ALSA: hda/cirrus: Add Headphone and Headset MIC Volume Control
+
+  * drm/i915: Drop force_probe requirement for JSL (LP: #1917843)
+    - SAUCE: drm/i915: Drop require_force_probe from JSL
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Skip d-i code if udebs are disabled
+    - [Packaging] Disable udebs if $DEBIAN/d-i doesn't exist
+    - [Packaging] remove dh-systemd build dependency
+    - [Config] fix several annotaions with enforcement typos
+    - [Config] refresh annotations
+    - [Config] updateconfigs following v5.12-rc3 rebase
+    - annotations: fixup after v5.12-rc3 rebase
+    - Rebase to v5.12-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 16 Mar 2021 18:43:03 +0100
+
+linux-unstable (5.12.0-2.2) hirsute; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v5.12-rc2
+    - [Config] updateconfigs following v5.12-rc2 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc2
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 08 Mar 2021 11:22:04 +0100
+
+linux-unstable (5.12.0-1.1) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Support no udeb profile (LP: #1916095)
+    - [Packaging] replace custom filter script with dctrl-tools
+    - [Packaging] correctly implement noudeb build profiles.
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] dkms-versions -- remove nvidia-graphics-drivers-440-server
+    - [Debian] run ubuntu-regression-suite for linux-unstable
+    - [Packaging] remove Provides: aufs-dkms
+    - [Config] update config and annotations following v5.12-rc1 rebase
+    - [Config] disable nvidia and nvidia_server builds
+    - [Config] temporarily disable ZFS
+    - temporarily disable modules check
+    - annotations: s390: temporarily remove CONFIG_KMSG_IDS
+    - [Config] amd64: FTBFS: disable HIO
+    - [Config] FTBFS: disable SHIFT_FS
+    - [Config] s390: temporarily remove CONFIG_KMSG_IDS
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] disable nvidia and nvidia_server builds"
+    - Revert "UBUNTU: SAUCE: s390: kernel message catalog"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 04 Mar 2021 18:26:12 +0100
+
+linux-unstable (5.12.0-0.0) hirsute; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 04 Mar 2021 18:17:32 +0100
+
+linux-unstable (5.11.0-10.11) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Support CML-S CPU + TGP PCH (LP: #1909457)
+    - drm/i915/rkl: new rkl ddc map for different PCH
+    - SAUCE: drm/i915/gen9_bc : Add TGP PCH support
+
+  * Use DCPD to control HP DreamColor panel (LP: #1911001)
+    - SAUCE: drm/dp: Another HP DreamColor panel brigntness fix
+
+  * Update nvidia dkms build for module linker script changes
+    - [Packaging] build-dkms--nvidia-N -- Update for preprocessed module linker
+      script
+
+  * Please trust Canonical Livepatch Service kmod signing key (LP: #1898716)
+    - [Config] enable CONFIG_MODVERSIONS=y
+    - [Packaging] build canonical-certs.pem from branch/arch certs
+    - [Config] add Canonical Livepatch Service key to SYSTEM_TRUSTED_KEYS
+    - [Config] add ubuntu-drivers key to SYSTEM_TRUSTED_KEYS
+
+  * Miscellaneous Ubuntu changes
+    - [Config] re-enable nvidia dkms
+    - SAUCE: selftests: memory-hotplug: bump timeout to 10min
+    - [Debian] update-aufs.sh -- Don't apply tmpfs-idr.patch
+    - [Config] Update configs
+    - [Config] disable nvidia and nvidia_server builds
+    - SAUCE: Import aufs driver
+    - [Config] CONFIG_AUFS_FS=n
+    - [Config] refresh annotations file
+    - [Config] set CONFIG_MIPI_I3C_HCI=m consistently
+    - [Config] set CONFIG_PINCTRL_MSM8953=m on armhf generic-lpae
+    - [Packaging] Change source package name to linux-unstable
+    - [Config] update LD_VERSION in config due to toolchain update
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: tmpfs: Don't use 64-bit inodes by defulat with 32-bit
+      ino_t"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 22 Feb 2021 07:18:07 +0100
+
+linux-unstable (5.11.0-9.10) hirsute; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 22 Feb 2021 07:02:45 +0100
+
+linux (5.11.0-9.10) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs/annotations after rebase to 5.11
+    - zfs-modules.ignore: add zzstd
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 15 Feb 2021 16:29:36 +0100
+
+linux (5.11.0-8.9) hirsute; urgency=medium
+
+  * Missing device id for Intel TGL-H ISH [8086:43fc] in intel-ish-hid driver
+    (LP: #1914543)
+    - SAUCE: HID: intel-ish-hid: ipc: Add Tiger Lake H PCI device ID
+
+  *  Add support for new Realtek ethernet NIC (LP: #1914604)
+    - r8169: Add support for another RTL8168FP
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: tmpfs: Don't use 64-bit inodes by defulat with 32-bit ino_t
+    - [Config] Set CONFIG_TMPFS_INODE64=n for s390x
+    - [Config] re-enable ZFS
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 08 Feb 2021 11:56:23 +0100
+
+linux (5.11.0-7.8) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  *  Boot fails: failed to validate module [nls_iso8859_1] BTF: -22
+    (LP: #1911359)
+    - SAUCE: x86/entry: build thunk_$(BITS) only if CONFIG_PREEMPTION=y
+
+  * Remove scary stack trace from Realtek WiFi driver (LP: #1913263)
+    - rtw88: reduce the log level for failure of tx report
+
+  * Fix unexpected AER/DPC on PCH400 and PCH500 (LP: #1913691)
+    - Revert "UBUNTU: SAUCE: PCI: Enable ACS quirk on all CML root ports"
+    - Revert "UBUNTU: SAUCE: PCI: Enable ACS quirk on CML root port"
+    - SAUCE: PCI/AER: Disable AER interrupt during suspend
+    - SAUCE: PCI/DPC: Disable DPC interrupt during suspend
+
+  * switch to an autogenerated nvidia series based core via dkms-versions
+    (LP: #1912803)
+    - [Packaging] nvidia -- use dkms-versions to define versions built
+    - [Packaging] update-version-dkms -- maintain flags fields
+
+  * Introduce the new NVIDIA 460-server series and update the 460 series
+    (LP: #1913200)
+    - [Config] dkms-versions -- add the 460-server nvidia driver
+
+  * Fix the video can't output through WD19TB connected with TGL platform during
+    cold-boot (LP: #1910211)
+    - SAUCE: drm/i915/dp: Prevent setting LTTPR mode if no LTTPR is detected
+
+  * Stop using get_scalar_status command in Dell AIO uart backlight driver
+    (LP: #1865402)
+    - SAUCE: platform/x86: dell-uart-backlight: add get_display_mode command
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/seccomp: Accept any valid fd in user_notification_addfd
+    - [Packaging] Don't disable CONFIG_DEBUG_INFO in headers packages
+    - [Config] update configs/annotations after rebase to 5.11-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 01 Feb 2021 10:27:52 +0100
+
+linux (5.11.0-6.7) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Prevent thermal shutdown during boot process (LP: #1906168)
+    - thermal/drivers/acpi: Use hot and critical ops
+    - thermal/core: Remove notify ops
+    - thermal: int340x: Fix unexpected shutdown at critical temperature
+    - thermal: intel: pch: Fix unexpected shutdown at critical temperature
+
+  * riscv: backport support for SiFive Unmatched (LP: #1910965)
+    - RISC-V: Update l2 cache DT documentation to add support for SiFive FU740
+    - RISC-V: sifive_l2_cache: Update L2 cache driver to support SiFive FU740
+    - dt-bindings: riscv: Update DT binding docs to support SiFive FU740 SoC
+    - riscv: dts: add initial support for the SiFive FU740-C000 SoC
+    - dt-bindings: riscv: Update YAML doc to support SiFive HiFive Unmatched board
+    - riscv: dts: add initial board data for the SiFive HiFive Unmatched
+    - PCI: microsemi: Add host driver for Microsemi PCIe controller
+    - Microsemi PCIe expansion board DT entry.
+    - SiFive Unleashed CPUFreq
+    - SiFive HiFive Unleashed: Add PWM LEDs (D1, D2, D3, D4)
+
+  * initramfs unpacking failed (LP: #1835660)
+    - lib/decompress_unlz4.c: correctly handle zero-padding around initrds.
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to 5.11-rc5
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 25 Jan 2021 09:31:31 +0100
+
+linux (5.11.0-5.6) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update config and annotations after rebase to 5.11-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 18 Jan 2021 10:46:10 +0100
+
+linux (5.11.0-4.5) hirsute; urgency=medium
+
+  *  Boot fails: failed to validate module [nls_iso8859_1] BTF: -22
+    (LP: #1911359)
+    - SAUCE: x86/entry: build thunk_$(BITS) only if CONFIG_PREEMPTION=y
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 14 Jan 2021 12:53:26 +0100
+
+linux (5.11.0-3.4) hirsute; urgency=medium
+
+  *  Boot fails: failed to validate module [nls_iso8859_1] BTF: -22
+    (LP: #1911359)
+    - bpf: Allow empty module BTFs
+    - libbpf: Allow loading empty BTFs
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 14 Jan 2021 07:43:45 +0100
+
+linux (5.11.0-2.3) hirsute; urgency=medium
+
+  * DMI entry syntax fix for Pegatron / ByteSpeed C15B (LP: #1910639)
+    - Input: i8042 - unbreak Pegatron C15B
+
+  * SYNA30B4:00 06CB:CE09 Mouse  on HP EliteBook 850 G7 not working at all
+    (LP: #1908992)
+    - HID: multitouch: Enable multi-input for Synaptics pointstick/touchpad device
+
+  * debian/scripts/file-downloader does not handle positive failures correctly
+    (LP: #1878897)
+    - [Packaging] file-downloader not handling positive failures correctly
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * CVE-2021-1052 // CVE-2021-1053
+    - [Packaging] NVIDIA -- Add the NVIDIA 460 driver
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Remove nvidia-455 dkms build
+    - SAUCE: ALSA: hda/realtek: fix right sounds and mute/micmute LEDs for HP
+      machines
+    - [Config] update configs and annotations after rebase to 5.11-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 11 Jan 2021 09:52:27 +0100
+
+linux (5.11.0-1.2) hirsute; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 07 Jan 2021 16:57:01 +0100
+
+linux (5.11.0-0.1) hirsute; urgency=medium
+
+  * dep-8 ubuntu-regression-suite tests are not run for all linux-hwe-* kernels
+    (LP: #1908529)
+    - [dep-8] Allow all hwe kernels
+
+  * Fix reading speed and duplex sysfs on igc device (LP: #1906851)
+    - igc: Report speed and duplex as unknown when device is runtime suspended
+
+  * rtwpci driver blocks the system to enter PC10, stuck at PC3 (LP: #1907200)
+    - SAUCE: rtw88: 8723de: let cpu enter c10
+
+  * [21.04 FEAT] Deactivate CONFIG_QETH_OSN kernel config option (LP: #1906370)
+    - [Config] Deactivate CONFIG_QETH_OSN kernel config option
+
+  * Add dpcd backlight control for 0x4c83 0x4f41 (LP: #1905663)
+    - SAUCE: drm/dp: Add dpcd backlight control for 0x4c83 0x4f41
+
+  * disable building bpf selftests (LP: #1908144)
+    - SAUCE: selftests/bpf: Clarify build error if no vmlinux
+    - SAUCE: selftests: Skip BPF selftests by default
+    - disable building bpf selftests (no VMLINUX_BTF)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - [Config] update configs and annotations after rebase to v5.11-rc1
+    - hio: fix build error with kernel 5.11
+    - SAUCE: shiftfs: fix build error with 5.11
+    - [Config] temporarily disable ZFS
+    - check-aliases: do not error if modules.alias does not exist
+    - ppc64el: don't build stripped vdso
+
+  * Miscellaneous upstream changes
+    - irq: export irq_check_status_bit
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 04 Jan 2021 09:17:48 +0100
+
+linux (5.11.0-0.0) hirsute; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 30 Dec 2020 09:04:41 +0100
+
+linux (5.10.0-9.10) hirsute; urgency=medium
+
+  * Use INTx for Pericom USB controllers (LP: #1906839)
+    - PCI: Disable MSI for Pericom PCIe-USB adapter
+
+  * disable building bpf selftests (LP: #1908144)
+    - SAUCE: selftests/bpf: clarify build error if no vmlinux
+    - SAUCE: selftests: Skip BPF seftests by default
+    - disable building bpf selftests (no VMLINUX_BTF)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Enable CONFIG_BPF_LSM
+
+  * Miscellaneous upstream changes
+    - Revert "md: change mddev 'chunk_sectors' from int to unsigned"
+    - Revert "dm raid: fix discard limits for raid1 and raid10"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 15 Dec 2020 10:16:14 +0100
+
+linux (5.10.0-8.9) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Fix bpf selftest compilation with clang 11
+    - bpf: Fix selftest compilation on clang 11
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to v5.10
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 14 Dec 2020 08:57:57 +0100
+
+linux (5.10.0-7.8) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Fix linux-libc-dev build for hirsute forward port kernels (LP: #1904067)
+    - [Debian] Build linux-libc-dev for debian.master* branches
+
+  * Update kernel packaging to support forward porting kernels (LP: #1902957)
+    - [Debian] Update for leader included in BACKPORT_SUFFIX
+
+  * Introduce the new NVIDIA 455 series (LP: #1897751)
+    - [Packaging] NVIDIA -- Add signed modules for the 455 driver
+
+  * 5.10 kernel fails to boot with secure boot disabled (LP: #1904906)
+    - [Config] CONFIG_RCU_SCALE_TEST=n
+
+  * Miscellaneous Ubuntu changes
+    - [Config] s390x: disable GPIO_CDEV
+    - [Config] ARM_CMN=m
+    - [Config] disable GPIO_CDEV_V1
+    - [Config] Reorder annotations after 5.10-rc6 rebase
+    - [Packaging] Remove nvidia-435 dkms build
+    - [Packaging] Change source package name to linux
+    - [Config] Update configs and annotations after rebase to v5.10-rc7
+    - SAUCE: Revert "mm/filemap: add static for function
+      __add_to_page_cache_locked"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 07 Dec 2020 00:15:20 -0600
+
+linux (5.10.0-6.7) hirsute; urgency=medium
+
+  * Empty entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 06 Dec 2020 22:13:46 -0600
+
+linux-5.10 (5.10.0-6.7) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Avoid double newline when running insertchanges (LP: #1903293)
+    - [Packaging] insertchanges: avoid double newline
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging]: linux-modules should depend on linux-image
+    - [Packaging]: linux-image should suggest linux-modules-extra
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 30 Nov 2020 07:47:34 +0100
+
+linux-5.10 (5.10.0-5.6) hirsute; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] add CONFIG_INFINIBAND_VIRT_DMA
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 23 Nov 2020 13:17:44 +0100
+
+linux-5.10 (5.10.0-4.5) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] reduce the size required to build packages
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 16 Nov 2020 08:33:54 +0100
+
+linux-5.10 (5.10.0-3.4) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * e1000e: fix issues with S0ix (LP: #1902687)
+    - SAUCE: e1000e: fix S0ix flow to allow S0i3.2 subset entry
+    - SAUCE: e1000e: allow turning s0ix flows on for systems with ME
+    - SAUCE: e1000e: Add Dell's Comet Lake systems into s0ix heuristics
+    - SAUCE: e1000e: Add more Dell CML systems into s0ix heuristics
+    - [Config] Update CONFIG_E1000E for ppc64el in annotations
+
+  * perf: Add support for Rocket Lake (LP: #1902004)
+    - SAUCE: perf/x86/intel: Add Rocket Lake CPU support
+    - SAUCE: perf/x86/cstate: Add Rocket Lake CPU support
+    - SAUCE: perf/x86/msr: Add Rocket Lake CPU support
+    - SAUCE: perf/x86/intel/uncore: Add Rocket Lake support
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Disable CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE
+    - [Config] update CONFIG_MST_IRQ after rebase to 5.10-rc3
+    - [Config] drop obsolete SND_SST_IPC options
+    - [Config] re-enable ZFS
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 Nov 2020 09:37:08 +0100
+
+linux-5.10 (5.10.0-2.3) hirsute; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Switch arm64 default cpufreq governor to ondemand
+    - [Debian] Include scripts/module.lds from builddir in headers package
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 03 Nov 2020 21:01:52 -0600
+
+linux-5.10 (5.10.0-1.2) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Fix non-working Intel NVMe after S3 (LP: #1900847)
+    - SAUCE: PCI: Enable ACS quirk on all CML root ports
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move to hirsute
+    - [Config] Update configs and annotations after rebase to 5.10-rc2
+    - [Config] Update numerous configs to conform with policy
+    - [Config] Switch default CPUFreq governer for arm64/armhf to schedultil
+    - [Config] Temporarily disable DEBUG_INFO_BTF for armhf
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 02 Nov 2020 13:18:27 -0600
+
+linux-5.10 (5.10.0-0.1) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Update configs and annotations for v5.10-rc1
+    - SAUCE: platform/x86: dell-uart-backlight: rename kzfree() to
+      kfree_sensitive()
+    - SAUCE: apparmor: rename kzfree() to kfree_sensitive()
+    - SAUCE: LSM: change ima_read_file() to use lsmblob
+    - SAUCE: LSM: Use lsmblob in smk_netlbl_mls()
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] Change source package name to linux-5.10"
+    - s390: correct __bootdata / __bootdata_preserved macros
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 27 Oct 2020 16:57:07 +0100
+
+linux-5.10 (5.10.0-0.0) groovy; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 26 Oct 2020 14:55:48 +0100
+
+linux-5.9 (5.9.0-2.3) groovy; urgency=medium
+
+  * Fix system reboot when disconnecting WiFi (LP: #1899726)
+    - iwlwifi: msix: limit max RX queues for 9000 family
+
+  * booting linux-generic-lpae armhf kernel under qemu results in relocation out
+    of range, and thus no modules can be loaded (LP: #1899519)
+    - [Config] armhf: ARM_MODULE_PLTS=y
+
+  * Fix broken MSI interrupt after HDA controller was suspended (LP: #1899586)
+    - ALSA: hda: fix jack detection with Realtek codecs when in D3
+
+  * CVE-2020-16119
+    - SAUCE: dccp: avoid double free of ccid on child socket
+
+  * python3-venv is gone (LP: #1896801)
+    - SAUCE: doc: remove python3-venv dependency
+
+  * *-tools-common packages descriptions have typo "PGKVER" (LP: #1898903)
+    - [Packaging] Fix typo in -tools template s/PGKVER/PKGVER/
+
+  * Enable brightness control on HP DreamColor panel (LP: #1898865)
+    - SAUCE: drm/i915/dpcd_bl: Skip testing control capability with force DPCD
+      quirk
+    - SAUCE: drm/dp: HP DreamColor panel brigntness fix
+
+  * HP Zbook Studio G7 boots into corrupted screen with PSR featured panel
+    (LP: #1897501)
+    - SAUCE: drm/i915/psr: allow overriding PSR disable param by quirk
+    - SAUCE: drm/dp: add DP_QUIRK_FORCE_PSR_CHIP_DEFAULT quirk to CMN prod-ID
+      19-15
+
+  * Fix broken e1000e device after S3 (LP: #1897755)
+    - SAUCE: e1000e: Increase polling timeout on MDIC ready bit
+
+  * Wakeup the system by touching the touchpad (LP: #1888331)
+    - HID: i2c-hid: Enable wakeup capability from Suspend-to-Idle
+
+  * Enable LTR for endpoints behind VMD (LP: #1896598)
+    - SAUCE: PCI/ASPM: Enable LTR for endpoints behind VMD
+
+  * [SRU] [Focal/OEM-5.6/Groovy]Fix AMD usb host controller lost after stress S3
+    (LP: #1893914)
+    - SAUCE: xhci: workaround for S3 issue on AMD SNPS 3.0 xHC
+
+  * debian/rules editconfigs does not work on s390x to change s390x only configs
+    (LP: #1863116)
+    - [Packaging] kernelconfig -- only update/edit configurations on architectures
+      we have compiler support
+
+  * Fix non-working NVMe after S3 (LP: #1895718)
+    - SAUCE: PCI: Enable ACS quirk on CML root port
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: bpf: Check CONFIG_BPF option for resolve_btfids
+    - SAUCE: tools resolve_btfids: Always force HOSTARCH
+    - packaging: arm64: add a 64KB mem pages flavour called 'generic-64k'
+    - packaging: arm64: generic-64k: skip ABI, modules and retpoline checks
+    - SAUCE: drm/i915/display: Fix null deref in intel_psr_atomic_check()
+    - [Config] Update toolchain versions
+    - [Config] Refresh annotations
+    - Add ubuntu-host module
+    - CONFIG_UBUNTU_HOST=m
+    - SAUCE: apparmor: drop prefixing abs root labels with '='
+    - SAUCE: apparmor: disable showing the mode as part of a secid to secctx
+    - SAUCE: apparmor: rename aa_sock() to aa_unix_sk()
+    - SAUCE: apparmor: LSM stacking: switch from SK_CTX() to aa_sock()
+    - SAUCE: LSM: Infrastructure management of the sock security
+    - SAUCE: LSM: Create and manage the lsmblob data structure.
+    - SAUCE: LSM: Use lsmblob in security_audit_rule_match
+    - SAUCE: LSM: Use lsmblob in security_kernel_act_as
+    - SAUCE: net: Prepare UDS for security module stacking
+    - SAUCE: LSM: Use lsmblob in security_secctx_to_secid
+    - SAUCE: LSM: Use lsmblob in security_secid_to_secctx
+    - SAUCE: LSM: Use lsmblob in security_ipc_getsecid
+    - SAUCE: LSM: Use lsmblob in security_task_getsecid
+    - SAUCE: LSM: Use lsmblob in security_inode_getsecid
+    - SAUCE: LSM: Use lsmblob in security_cred_getsecid
+    - SAUCE: IMA: Change internal interfaces to use lsmblobs
+    - SAUCE: LSM: Specify which LSM to display
+    - SAUCE: LSM: Ensure the correct LSM context releaser
+    - SAUCE: LSM: Use lsmcontext in security_secid_to_secctx
+    - SAUCE: LSM: Use lsmcontext in security_inode_getsecctx
+    - SAUCE: LSM: security_secid_to_secctx in netlink netfilter
+    - SAUCE: NET: Store LSM netlabel data in a lsmblob
+    - SAUCE: LSM: Verify LSM display sanity in binder
+    - SAUCE: Audit: Add new record for multiple process LSM attributes
+    - SAUCE: Audit: Add a new record for multiple object LSM
+    - SAUCE: LSM: Add /proc attr entry for full LSM context
+    - SAUCE: AppArmor: Remove the exclusive flag
+    - SAUCE: Audit: Fix for missing NULL check
+
+  * Miscellaneous upstream changes
+    - tty: hvcs: Don't NULL tty->driver_data until hvcs_cleanup()
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.9
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 14 Oct 2020 13:31:18 -0500
+
+linux-5.9 (5.9.0-1.2) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Update configs after rebase to 5.9-rc6
+    - SAUCE: dax: Fix compilation for CONFIG_DAX && !CONFIG_FS_DAX
+    - SAUCE: bpf: Use --no-fail option if CONFIG_BPF is not enabled
+    - SAUCE: tools resolve_btfids: Always force HOSTARCH
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.9-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 21 Sep 2020 14:39:34 -0500
+
+linux-5.9 (5.9.0-0.1) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Update configs and annotations for v5.9-rc1
+    - SAUCE: i915: Fix build error due to missing struct definition
+    - hio -- Update blk_queue_split() calls for changes in 5.9-rc1
+    - hio -- Updates for move of make_request_fn to struct block_device_operations
+    - [Config] Disable zfs dkms build
+    - [Config] Disable nvidia dkms build
+    - [Config] Disable nvidia server dkms builds
+    - SAUCE: remoteproc: qcom: Use div_u64() for 64-bit division
+    - SAUCE: PCI/ASPM: Enable ASPM for links under VMD domain
+    - [Packaging] Bind hv_vss_daemon startup to hv_vss device
+    - [Packaging] bind hv_fcopy_daemon startup to hv_fcopy device
+    - [Config] Re-enable UEFI signing for arm64
+    - SAUCE: Revert "UBUNTU: SAUCE: export __get_vm_area_caller() and map_kernel_range()"
+    - [Config] Set the default CPU governor to ONDEMAND
+    - [Packaging] update variants
+    - [Packaging] update helper scripts
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.9-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 17 Sep 2020 15:01:21 -0500
+
+linux-5.9 (5.9.0-0.0) groovy; urgency=medium
+
+  * Empty entry
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 18 Aug 2020 16:48:03 -0500
+
+linux (5.8.0-16.17) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-16.17 -proposed tracker (LP: #1891233)
+
+  * Miscellaneous Ubuntu changes
+    - hio -- Update to use bio_{start,end}_io_acct with 5.8+
+    - Enable hio driver
+    - [Packaging] Temporarily disable building doc package contents
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 11 Aug 2020 15:32:58 -0500
+
+linux (5.8.0-15.16) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-15.16 -proposed tracker (LP: #1891177)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Documentation: import error c_funcptr_sig_re, c_sig_re (sphinx-
+      doc/sphinx@0f49e30c)
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 11 Aug 2020 09:29:58 -0500
+
+linux (5.8.0-14.15) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-14.15 -proposed tracker (LP: #1891085)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * msg_zerocopy.sh in net from ubuntu_kernel_selftests failed (LP: #1812620)
+    - selftests/net: relax cpu affinity requirement in msg_zerocopy test
+
+  * Fix missing HDMI/DP Audio on an HP Desktop (LP: #1890441)
+    - ALSA: hda/hdmi: Add quirk to force connectivity
+
+  * Add initial audio support for Lenovo ThinkStation P620 (LP: #1890317)
+    - ALSA: usb-audio: Add support for Lenovo ThinkStation P620
+
+  * Fix IOMMU error on AMD Radeon Pro W5700 (LP: #1890306)
+    - PCI: Mark AMD Navi10 GPU rev 0x00 ATS as broken
+
+  * Enlarge hisi_sec2 capability (LP: #1890222)
+    - crypto: hisilicon - update SEC driver module parameter
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Re-enable signing for ppc64el
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 10 Aug 2020 15:26:46 -0500
+
+linux (5.8.0-13.14) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Remove i386 configs
+    - SAUCE: apply a workaround to re-enable CONFIG_CRYPTO_AEGIS128_SIMD
+    - SAUCE: export __get_vm_area_caller() and map_kernel_range()
+    - [Config] drop CONFIG_BINFMT_AOUT enforcement
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] disable CONFIG_CRYPTO_AEGIS128_SIMD"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 04 Aug 2020 09:51:50 +0200
+
+linux (5.8.0-12.13) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-12.13 -proposed tracker (LP: #1889481)
+
+  * Fix right speaker of HP laptop (LP: #1889375)
+    - SAUCE: hda/realtek: Fix right speaker of HP laptop
+
+  * blk_update_request error when mount nvme partition (LP: #1872383)
+    - SAUCE: nvme-pci: prevent SK hynix PC400 from using Write Zeroes command
+
+  * Add support for Atlantic NIC firmware v4 (LP: #1886908)
+    - Revert "UBUNTU: SAUCE: net: atlantic: Add support for firmware v4"
+    - net: atlantic: align return value of ver_match function with function name
+    - net: atlantic: add support for FW 4.x
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Fix debian/tests for linux-5.8 -> linux rename
+    - SAUCE: selftests/powerpc: return skip code for spectre_v2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 29 Jul 2020 16:58:47 -0500
+
+linux (5.8.0-11.12) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-11.12 -proposed tracker (LP: #1889336)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] dwarves is not required for linux-libc-dev or stage1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 Jul 2020 22:33:24 -0500
+
+linux (5.8.0-10.11) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-10.11 -proposed tracker (LP: #1889316)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Add more packages to Build-Depends-Indep for docs
+    - [Debian] Specify python executable in kmake
+    - [Debian] Don't treat warnings as errors during perf builds
+    - [Config] Disable signing for ppc64el
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 Jul 2020 17:09:52 -0500
+
+linux (5.8.0-9.10) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-9.10 -proposed tracker (LP: #1889140)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Fix s390x compile error on F32 utils/stat-display.c
+    - [Packaging] Add python3-venv to Build-Depends-Indep
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Jul 2020 21:01:46 -0500
+
+linux (5.8.0-8.9) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-8.9 -proposed tracker (LP: #1889104)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - update dkms package versions
+    - [Packaging] update variants
+
+  * Introduce the new NVIDIA 450-server and the 450 UDA series (LP: #1887674)
+    - [Packaging] NVIDIA -- Add signed modules for 450 450-server
+
+  * Introduce the new NVIDIA 418-server and 440-server series, and update the
+    current NVIDIA drivers (LP: #1881137)
+    - [packaging] add signed modules for the 418-server and the 440-server
+      flavours
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "radix-tree: Use local_lock for protection"
+    - [Config] CONFIG_DEBUG_INFO_COMPRESSED=n
+    - [Config] disable CONFIG_CRYPTO_AEGIS128_SIMD
+    - [Config] Enable nvidia dkms build
+
+  * Miscellaneous upstream changes
+    - usbip: tools: fix build error for multiple definition
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Jul 2020 11:18:12 -0500
+
+linux (5.8.0-7.8) groovy; urgency=medium
+
+  * Empty entry
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Jul 2020 09:22:19 +0200
+
+linux-5.8 (5.8.0-7.8) groovy; urgency=medium
+
+  * soc/amd/renoir: detect dmic from acpi table (LP: #1887734)
+    - ASoC: amd: add logic to check dmic hardware runtime
+    - ASoC: amd: add ACPI dependency check
+    - ASoC: amd: fixed kernel warnings
+
+  * linux 4.15.0-109-generic network DoS regression vs -108 (LP: #1886668)
+    - SAUCE: Revert "netprio_cgroup: Fix unlimited memory leak of v2 cgroups"
+
+  * Add support for Atlantic NIC firmware v4 (LP: #1886908)
+    - SAUCE: net: atlantic: Add support for firmware v4
+
+  * MGA G200e doesn't work under GDM Wayland (LP: #1886140)
+    - drm/mgag200: Remove HW cursor
+    - drm/mgag200: Clean up mga_set_start_address()
+    - drm/mgag200: Clean up mga_crtc_do_set_base()
+    - drm/mgag200: Move mode-setting code into separate helper function
+    - drm/mgag200: Split MISC register update into PLL selection, SYNC and I/O
+    - drm/mgag200: Update mode registers after plane registers
+    - drm/mgag200: Set pitch in a separate helper function
+    - drm/mgag200: Set primary plane's format in separate helper function
+    - drm/mgag200: Move TAGFIFO reset into separate function
+    - drm/mgag200: Move hiprilvl setting into separate functions
+    - drm/mgag200: Move register initialization into separate function
+    - drm/mgag200: Remove out-commented suspend/resume helpers
+    - drm/mgag200: Use simple-display data structures
+    - drm/mgag200: Convert to simple KMS helper
+    - drm/mgag200: Replace VRAM helpers with SHMEM helpers
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: s390/bpf: fix sign extension in branch_ku
+    - SAUCE: selftests: net: ip_defrag: modprobe missing nf_defrag_ipv6 support
+    - SAUCE: selftests: fib_nexthop_multiprefix: fix cleanup() netns deletion
+    - [packaging] debhelper-compat (= 10) (and retire debian/compat)
+    - [Config] Update configs after rebase to 5.8-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 20 Jul 2020 09:55:47 +0200
+
+linux-5.8 (5.8.0-6.7) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * perf build broken after updating to bintuils 2.34.90.20200706-1ubuntu1
+    (LP: #1887397)
+    - SAUCE: libtraceevent: Strip symbol version from nm output
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 13 Jul 2020 14:07:53 -0500
+
+linux-5.8 (5.8.0-5.6) groovy; urgency=medium
+
+  * linux-libc-dev broken for crossbuilding, Multi-Arch:same violation
+    (LP: #1886188)
+    - [Packaging] Produce linux-libc-deb package for riscv64
+    - [Debian] Disallow building linux-libc-dev from linux-riscv
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "UBUNTU: SAUCE: test_bpf: remove expected fail for Ctx heavy
+      transformations test on s390"
+    - SAUCE: Revert "test_bpf: flag tests that cannot be jited on s390"
+    - [Config] Update configs (gcc update)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 13 Jul 2020 08:42:14 +0200
+
+linux-5.8 (5.8.0-4.5) groovy; urgency=medium
+
+  * Add generic LED class support for audio LED (LP: #1885896)
+    - ALSA: hda: generic: Always call led-trigger for mic mute LED
+    - ALSA: hda: generic: Add a helper for mic-mute LED with LED classdev
+    - ALSA: hda/realtek: Convert to cdev-variant of mic-mute LED controls
+    - ALSA: hda/conexant: Convert to cdev-variant of mic-mute LED controls
+    - ALSA: hda/sigmatel: Convert to cdev-variant of mic-mute LED controls
+    - ALSA: hda: generic: Drop unused snd_hda_gen_fixup_micmute_led()
+    - ALSA: hda: generic: Drop the old mic-mute LED hook
+    - ALSA: hda: generic: Add vmaster mute LED helper
+    - ALSA: hda/realtek: Use the new vmaster mute LED helper
+    - ALSA: hda/conexant: Use the new vmaster mute LED helper
+    - ALSA: hda/sigmatel: Use the new vmaster mute LED helper
+    - ALSA: hda/realtek: Unify LED helper code
+    - ALSA: hda: Let LED cdev handling suspend/resume
+
+  * seccomp_bpf fails on powerpc (LP: #1885757)
+    - SAUCE: selftests/seccomp: fix ptrace tests on powerpc
+
+  * CVE-2020-11935
+    - SAUCE: aufs: do not call i_readcount_inc()
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Update aufs to 5.x-rcN 20200622
+    - [Config] Update configs to set CONFIG_SND_HDA_GENERIC_LEDS value
+    - [Config] CONFIG_SECURITY_DMESG_RESTRICT=y
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 06 Jul 2020 08:14:28 -0500
+
+linux-5.8 (5.8.0-3.4) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - update dkms package versions
+
+  * lxc 1:4.0.2-0ubuntu1 ADT test failure with linux-5.8 5.8.0-1.2
+    (LP: #1884635)
+    - SAUCE: overlayfs: fix faulty rebase
+
+  * shiftfs: O_TMPFILE reports ESTALE (LP: #1872757)
+    - SAUCE: shiftfs: prevent ESTALE for LOOKUP_JUMP lookups
+
+  * shiftfs: fix btrfs regression (LP: #1884767)
+    - SAUCE: Revert "UBUNTU: SAUCE: shiftfs: fix dentry revalidation"
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_DEBUG_INFO_COMPRESSED=y
+    - SAUCE: regulator: rename da903x to da903x-regulator
+    - [Config] Add da903x to modules.ignore
+    - [Config] Update configs for rebase to 5.8-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 29 Jun 2020 08:48:25 -0500
+
+linux-5.8 (5.8.0-2.3) groovy; urgency=medium
+
+  * Support Audio Mute LED for two new HP laptops (LP: #1884251)
+    - ALSA: hda/realtek: Add mute LED and micmute LED support for HP systems
+
+  * CVE-2019-16089
+    - SAUCE: nbd_genl_status: null check for nla_nest_start
+
+  * tpm: fix TIS locality timeout problems (LP: #1881710)
+    - SAUCE: tpm: fix TIS locality timeout problems
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: security,perf: Allow further restriction of perf_event_open
+    - [Config] CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
+    - [Config] Update configs and annotations for 5.8-rc2
+    - [Config] Enable zfs
+    - [Config] Enable CONFIG_DEBUG_INFO_BTF
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 22 Jun 2020 15:05:54 -0500
+
+linux-5.8 (5.8.0-1.2) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Support linux-x.y in udeb package names
+    - [Packaging] Use SRCPKGNAME for udeb packages
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 17 Jun 2020 19:34:32 -0500
+
+linux-5.8 (5.8.0-0.1) groovy; urgency=medium
+
+  * Docker registry doesn't stay up and keeps restarting (LP: #1879690)
+    - Revert "UBUNTU: SAUCE: overlayfs: use shiftfs hacks only with shiftfs as underlay"
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Update source package name to linux-5.8
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - SAUCE: (lockdown) powerpc: lock down kernel in secure boot mode
+    - SAUCE: Import aufs driver
+    - [Config] Update configs for v5.8-rc1
+    - [Config] Update annotations for v5.8-rc1 config changes
+    - SAUCE: shiftfs -- Fix build errors from missing fiemap definitions
+    - Disable hio driver
+
+  * Miscellaneous upstream changes
+    - acpi: disallow loading configfs acpi tables when locked down
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 17 Jun 2020 11:54:24 -0500
+
+linux-5.8 (5.8.0-0.0) groovy; urgency=medium
+
+  * Empty entry
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 14 Jun 2020 22:40:35 -0500
+
+linux-5.7 (5.7.0-8.9) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Enforce all config annotations (LP: #1879327)
+    - [Config]: do not enforce CONFIG_VERSION_SIGNATURE
+    - [Config]: prepare to enforce all
+    - [Config]: enforce all config options
+
+  * Miscellaneous Ubuntu changes
+    - [Config]: annotations review after 5.7 rebase
+    - [Config] annotations: IXP4XX* depends on ARCH_IXP4XX
+    - [Config] THERMAL_GOV_POWER_ALLOCATOR=y
+    - [Config] annotations: SOC_CAMERA is marked as BROKEN
+    - [Config] annotations: NFSD_V4_2_INTER_SSC depends on NFS_FS=y
+    - [Config] annotations: CRYPTO_DEV_CHELSIO_TLS depends on legacy (and largely
+      unmantained) TLS_TOE
+    - [Config] annotations: SERIO_OLPC_APSP depends on ARCH_MMP
+    - [Config] RTW88_DEBUG=y
+    - [Config] annotations: ISDN_CAPI is a bool, and BT_CMTP depends on  it
+    - [Config] annotations SND_SOC_SOF_DEVELOPER_SUPPORT depends on
+      SND_SOC_SOF_DEVELOPER_SUPPORT
+    - [Config] annotations: SND_SOC_SOF_BAYTRAIL_SUPPORT is mutually exclusive
+      with SND_SST_ATOM_HIFI2_PLATFORM_ACPI
+    - [Config] annotations: DEBUG_IMX_UART_PORT is defined only any
+      DEBUG_IMX*_UART is enabled
+    - [Config] annotations: HW_RANDOM_IMX_RNGC depends on SOC_IMX25
+    - [Config] annotations: armhf: VIRTUALIZATION support was removed for arm32
+    - [Config] annotations: arm64: remove DEBUG_ALIGN_RODATA
+    - [Config] annotations: ppc64: DATA_SHIFT defaults to PPC_PAGE_SHIFT
+    - [Config] arm64: enforce ARM64_USE_LSE_ATOMICS
+    - [Config] s390x: MOST is not set
+    - [Config] s390x: BCM84881_PHY is not set
+    - [Config] s390x: XILINX_LL_TEMAC is not set
+    - [Config] s390x: PHY_INTEL_EMMC requires GENERIC_PHY (off by default on
+      s390x)
+    - [Config] s390x: CHECK_STACK conflicts with VMAP_STACK
+    - [Config] annotations: s390x: NODES_SHIFT=1
+    - [Config] annotations: import new symbols
+    - [Config] annotations: remove unmatched menu and options
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 12 Jun 2020 12:03:01 +0200
+
+linux-5.7 (5.7.0-7.8) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+    - [Packaging] update helper scripts
+
+  * [UBUNTU 20.04] s390x/pci: fix linking between PF and VF for multifunction
+    devices (LP: #1879704)
+    - PCI/IOV: Introduce pci_iov_sysfs_link() function
+    - s390/pci: create links between PFs and VFs
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Disable UEFI signing for arm64
+    - Rebase to v5.7.1
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7.1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 08 Jun 2020 11:16:58 +0200
+
+linux-5.7 (5.7.0-6.7) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - update dkms package versions
+
+  * shiftfs: fix btrfs snapshot deletion (LP: #1879688)
+    - SAUCE: shiftfs: let userns root destroy subvolumes from other users
+
+  * seccomp_benchmark times out on eoan (LP: #1881576)
+    - SAUCE: selftests/seccomp: use 90s as timeout
+
+  * Realtek 8723DE [10ec:d723] subsystem [10ec:d738]  disconnects unsolicitedly
+    when Bluetooth is paired: Reason: 23=IEEE8021X_FAILED (LP: #1878147)
+    - SAUCE: Revert "UBUNTU: SAUCE: rtw88: Move driver IQK to set channel before
+      association for 11N chip"
+    - SAUCE: Revert "UBUNTU: SAUCE: rtw88: fix rate for a while after being
+      connected"
+    - SAUCE: Revert "UBUNTU: SAUCE: rtw88: No retry and report for auth and assoc"
+    - SAUCE: Revert "UBUNTU: SAUCE: rtw88: 8723d: Add coex support"
+    - rtw88: 8723d: Add coex support
+    - SAUCE: rtw88: coex: 8723d: set antanna control owner
+    - SAUCE: rtw88: coex: 8723d: handle BT inquiry cases
+    - SAUCE: rtw88: fix EAPOL 4-way failure by finish IQK earlier
+
+  * ASoC/amd: add audio driver for amd renoir (LP: #1881046)
+    - ASoC: amd: add Renoir ACP3x IP register header
+    - ASoC: amd: add Renoir ACP PCI driver
+    - ASoC: amd: add acp init/de-init functions
+    - ASoC: amd: create acp3x pdm platform device
+    - ASoC: amd: add ACP3x PDM platform driver
+    - ASoC: amd: irq handler changes for ACP3x PDM dma driver
+    - ASoC: amd: add acp3x pdm driver dma ops
+    - ASoC: amd: add ACP PDM DMA driver dai ops
+    - ASoC: amd: add Renoir ACP PCI driver PM ops
+    - ASoC: amd: add ACP PDM DMA driver pm ops
+    - ASoC: amd: enable Renoir acp3x drivers build
+    - ASoC: amd: create platform devices for Renoir
+    - ASoC: amd: RN machine driver using dmic
+    - ASoC: amd: enable build for RN machine driver
+    - ASoC: amd: fix kernel warning
+    - ASoC: amd: refactoring dai_hw_params() callback
+    - ASoC: amd: return error when acp de-init fails
+    - [Config]: enable amd renoir ASoC audio
+
+  * Slow send speed with Intel I219-V on Ubuntu 18.04.1 (LP: #1802691)
+    - e1000e: Disable TSO for buffer overrun workaround
+
+  * Fix incorrect speed/duplex when I210 device is runtime suspended
+    (LP: #1880656)
+    - igb: Report speed and duplex as unknown when device is runtime suspended
+
+  * Fix Pericom USB controller OHCI/EHCI PME# defect (LP: #1879321)
+    - serial: 8250_pci: Move Pericom IDs to pci_ids.h
+    - PCI: Avoid Pericom USB controller OHCI/EHCI PME# defect
+
+  * [UBUNTU 20.04] s390x/pci: enumerate pci functions per physical adapter
+    (LP: #1874056)
+    - s390/pci: Expose new port attribute for PCIe functions
+    - s390/pci: adaptation of iommu to multifunction
+    - s390/pci: define kernel parameters for PCI multifunction
+    - s390/pci: define RID and RID available
+    - s390/pci: create zPCI bus
+    - s390/pci: adapt events for zbus
+    - s390/pci: Handling multifunctions
+    - s390/pci: Do not disable PF when VFs exist
+    - s390/pci: Documentation for zPCI
+    - s390/pci: removes wrong PCI multifunction assignment
+
+  * add 16-bit width registers support for EEPROM at24 device (LP: #1876699)
+    - regmap-i2c: add 16-bit width registers support
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Enable virtualbox guest and shared-folder modules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 01 Jun 2020 16:11:24 -0500
+
+linux-5.7 (5.7.0-5.6) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * [UBUNTU 20.04] PSI generates overhead on s390x (LP: #1876044)
+    - Ubuntu: [Config] CONFIG_PSI is enabled by default, but creates additional
+      overhead on s390x, hence should be disabled by default on s390x only.
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v5.7-rc7
+    - [Config] ppc64el: disable STRICT_KERNEL_RWX
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 25 May 2020 11:44:09 +0200
+
+linux-5.7 (5.7.0-4.5) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * update-initramfs complains of missing amdgpu firmware files (LP: #1873325)
+    - SAUCE: drm/amdgpu: Remove unreleased arcturus and navi12 firmware from
+      modinfo
+
+  * Support DMIC micmute LED on HP platforms (LP: #1876859)
+    - ALSA: hda/realtek - Introduce polarity for micmute LED GPIO
+    - ALSA: hda/realtek - Enable micmute LED on and HP system
+    - ALSA: hda/realtek - Add LED class support for micmute LED
+    - ALSA: hda/realtek - Fix unused variable warning w/o
+      CONFIG_LEDS_TRIGGER_AUDIO
+    - ASoC: SOF: Update correct LED status at the first time usage of
+      update_mute_led()
+
+  * Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW),
+    REV=0x354 [8086:a0f0] subsystem id [1a56:1651] wireless adapter not found
+    due to firmware crash (LP: #1874685)
+    - SAUCE: iwlwifi: pcie: handle QuZ configs with killer NICs as well
+
+  * rtkit-daemon[*]: Failed to make ourselves RT: Operation not permitted after
+    upgrade to 20.04 (LP: #1875665)
+    - [Config] Turn off CONFIG_RT_GROUP_SCHED everywhere
+
+  * Unable to handle kernel pointer dereference in virtual kernel address space
+    on Eoan (LP: #1876645)
+    - SAUCE: overlayfs: fix shitfs special-casing
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: skip building selftest 'runqslower' if kernel not built
+    - Rebase to v5.7-rc6
+    - [Config] updateconfigs after 5.7-rc6 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 18 May 2020 11:27:25 +0200
+
+linux-5.7 (5.7.0-3.4) groovy; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7-rc5
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * getitimer returns it_value=0 erroneously (LP: #1349028)
+    - [Config] CONTEXT_TRACKING_FORCE policy should be unset
+
+  * lockdown on power (LP: #1855668) // Ubuntu Kernel Support for OpenPOWER NV
+    Secure & Trusted Boot (LP: #1866909)
+    - [Config] Enable configs for OpenPOWER NV Secure & Trusted Boot
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Import aufs driver
+    - [Config] Enable aufs
+    - [Config] annotations: remove SND_SOC_SOF_HDA_COMMON_HDMI_CODEC
+    - [Config] Remove CONFIG_SND_HDA_INTEL_DETECT_DMIC from annotations
+    - [Debian] final-checks -- Do not remove ~* from abi
+    - [Config] Enable 5-level page table support for x86
+    - [Config] updateconfigs after 5.7-rc5 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 11 May 2020 10:25:42 +0200
+
+linux-5.7 (5.7.0-2.3) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - update dkms package versions
+    - [Packaging] update helper scripts
+
+  * ASUS T100HAN boots to a blank screen with a cursor [i965: Failed to submit
+    batchbuffer: Input/output error] (LP: #1860754)
+    - [Config] CONFIG_PMIC_OPREGION=y and CONFIG_GPIO_CRYSTAL_COVE=y for amd64
+
+  * ubuntu/focal64 fails to mount Vagrant shared folders  (LP: #1873506)
+    - [Packaging] Move virtualbox modules to linux-modules
+    - [Packaging] Remove vbox and zfs modules from generic.inclusion-list
+
+  * built-using constraints preventing uploads (LP: #1875601)
+    - temporarily drop Built-Using data
+
+  * dkms artifacts may expire from the pool (LP: #1850958)
+    - [Packaging] autoreconstruct -- manage executable debian files
+    - [packaging] handle downloads from the librarian better
+
+  * Add signed modules for the 435 NVIDIA driver (LP: #1875888)
+    - [Packaging] NVIDIA -- add signed modules for the 435 NVIDIA driver
+
+  * [Selftests] Apply various fixes and improvements (LP: #1870543)
+    - SAUCE: selftests/seccomp -- Disable timeout for seccomp tests
+
+  * [17.04 FEAT] Integrate kernel message catalogue for s390x into Ubuntu
+    distribution (LP: #1628889)
+    - SAUCE: s390: kernel message catalog
+
+  * Overlayfs in user namespace leaks directory content of inaccessible
+    directories (LP: #1793458) // CVE-2018-6559
+    - SAUCE: overlayfs: ensure mounter privileges when reading directories
+
+  * suspend only works once on ThinkPad X1 Carbon gen 7 (LP: #1865570)
+    - SAUCE: e1000e: Disable s0ix flow for X1 Carbon 7th
+
+  * [ICL] TC port in legacy/static mode can't be detected due TCCOLD
+    (LP: #1868936)
+    - drm/i915/display: Move out code to return the digital_port of the aux ch
+    - drm/i915/display: Add intel_legacy_aux_to_power_domain()
+    - drm/i915/display: Split hsw_power_well_enable() into two
+    - drm/i915/tc/icl: Implement TC cold sequences
+    - drm/i915/tc: Skip ref held check for TC legacy aux power wells
+    - drm/i915/tc/tgl: Implement TC cold sequences
+    - drm/i915/tc: Catch TC users accessing FIA registers without enable aux
+    - drm/i915/tc: Do not warn when aux power well of static TC ports timeout
+
+  * Touchpad doesn't work on Dell Inspiron 7000 2-in-1 (LP: #1851901)
+    - Revert "UBUNTU: SAUCE: mfd: intel-lpss: add quirk for Dell XPS 13 7390
+      2-in-1"
+
+  * 'Elan touchpad' not detected on 'Lenovo ThinkBook 15 IIL' (LP: #1861610)
+    - SAUCE: Input: elan_i2c - add more hardware ID for Lenovo laptop
+
+  * linux-image-5.0.0-35-generic breaks checkpointing of container
+    (LP: #1857257)
+    - SAUCE: overlayfs: use shiftfs hacks only with shiftfs as underlay
+
+  * alsa/sof: kernel oops on the machine without Intel hdmi audio codec (a
+    regression in the  asoc machine driver) (LP: #1874359)
+    - ASoC: intel/skl/hda - fix oops on systems without i915 audio codec
+
+  * Add debian/rules targets to compile/run kernel selftests (LP: #1874286)
+    - [Packaging] add support to compile/run selftests
+
+  * 5.4.0-24.28 does not seem to apply rtprio, whereas -21 does. (LP: #1873315)
+    - [Config] lowlatency: turn off RT_GROUP_SCHED
+
+  * alsa/sof: external mic can't be deteced on Lenovo and HP laptops
+    (LP: #1872569)
+    - SAUCE: ASoC: intel/skl/hda - set autosuspend timeout for hda codecs
+
+  * shiftfs: O_TMPFILE reports ESTALE (LP: #1872757)
+    - SAUCE: shiftfs: fix dentry revalidation
+
+  * shiftfs: broken shiftfs nesting (LP: #1872094)
+    - SAUCE: shiftfs: record correct creator credentials
+
+  * lockdown on power (LP: #1855668)
+    - SAUCE: (lockdown) powerpc: lock down kernel in secure boot mode
+
+  * Add support for Realtek 8723DE wireless adapter (LP: #1780590)
+    - SAUCE: rtw88: add adaptivity support for EU/JP regulatory
+    - SAUCE: rtw88: update tx descriptor of mgmt and rsvd page packets
+    - SAUCE: rtw88: sar: dump sar information via debugfs
+    - SAUCE: rtw88: 8723d: add IQ calibration
+    - SAUCE: rtw88: 8723d: Add power tracking
+    - SAUCE: rtw88: 8723d: implement flush queue
+    - SAUCE: rtw88: 8723d: set ltecoex register address in chip_info
+    - SAUCE: rtw88: 8723d: Add coex support
+    - SAUCE: rtw88: 8723d: Add shutdown callback to disable BT USB suspend
+
+  * Fix authentication fail on Realtek WiFi 8723de (LP: #1871300)
+    - SAUCE: rtw88: No retry and report for auth and assoc
+    - SAUCE: rtw88: fix rate for a while after being connected
+    - SAUCE: rtw88: Move driver IQK to set channel before association for 11N chip
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: rtw88: fix 'const' mismatch in power suequence hooks
+    - SAUCE: rtw88: fix 'const' mismatch in
+      __priority_queue_cfg_legacy()/__priority_queue_cfg()
+    - [Config] RTW88=m
+    - SAUCE: (lockdown) Revert carried-forward lockdown patches
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - [Config] Add back CONFIG_LOCK_DOWN_IN_SECURE_BOOT annotation for ppc64el
+    - [Config] CONFIG_RT_GROUP_SCHED=y
+    - [Packaging] Include modules.builtin.modinfo in linux-modules
+    - SAUCE: LSM: Infrastructure management of the sock security
+    - SAUCE: Fix-up af_unix mediation for sock infrastructure management
+    - SAUCE: Revert "apparmor: Allow filtering based on secmark policy"
+    - SAUCE: Revert "apparmor: Parse secmark policy"
+    - SAUCE: Revert "apparmor: Add a wildcard secid"
+    - SAUCE: Revert "apparmor: fixup secid map conversion to using IDR"
+    - SAUCE: Revert "apparmor: Use an IDR to allocate apparmor secids"
+    - SAUCE: Revert "apparmor: add support for mapping secids and using secctxes"
+    - Update dropped.txt for restored apparmor patches
+    - Remove lockdown patches from dropped.txt
+    - SAUCE: powerpc/ima: require IMA module signatures only if MODULE_SIG is not
+      enabled
+    - SAUCE: selftests/ftrace: Use printf instead of echo in kprobe syntax error
+      tests
+    - SAUCE: selftests/net -- disable l2tp.sh test
+    - SAUCE: selftests/net -- disable timeout
+    - SAUCE: tools: hv: Update shebang to use python3 instead of python
+    - Remove dropped.txt
+    - [Packaging] move linux-doc and linux-libc-dev stubs to debian.master
+    - [Debian] Support generating configs for riscv64
+    - [Config] CONFIG_KMSG_IDS=y for s390x
+    - [Packaging] add libcap-dev dependency
+    - [Config] CONFIG_AD5770R=m
+    - [Config] CONFIG_AL3010=m
+    - [Config] CONFIG_APPLE_MFI_FASTCHARGE=m
+    - [Config] CONFIG_BAREUDP=m
+    - [Config] CONFIG_CRYPTO_DEV_OCTEONTX_CPT=m
+    - [Config] CONFIG_CRYPTO_DEV_ZYNQMP_AES=m
+    - [Config] CONFIG_DRM_DISPLAY_CONNECTOR=m
+    - [Config] CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
+    - [Config] CONFIG_DRM_PANEL_ELIDA_KD35T133=m
+    - [Config] CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02=m
+    - [Config] CONFIG_DRM_PANEL_NOVATEK_NT35510=m
+    - [Config] CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01=m
+    - [Config] CONFIG_DRM_PARADE_PS8640=m
+    - [Config] CONFIG_DRM_SIMPLE_BRIDGE=m
+    - [Config] CONFIG_DRM_TIDSS=m
+    - [Config] CONFIG_DRM_TI_TPD12S015=m
+    - [Config] CONFIG_DRM_TOSHIBA_TC358768=m
+    - [Config] CONFIG_EDAC_DMC520=m
+    - [Config] CONFIG_EXFAT_FS=m
+    - [Config] CONFIG_GP2AP002=m
+    - [Config] CONFIG_GPIO_MLXBF2=m
+    - [Config] CONFIG_HID_GLORIOUS=m
+    - [Config] CONFIG_HID_MCP2221=m
+    - [Config] CONFIG_HMC425=m
+    - [Config] CONFIG_ICP10100=m
+    - [Config] CONFIG_IMX8MM_THERMAL=m
+    - [Config] CONFIG_IMX_SC_THERMAL=m
+    - [Config] CONFIG_INTERCONNECT_QCOM_OSM_L3=m
+    - [Config] CONFIG_INTERCONNECT_QCOM_SC7180=m
+    - [Config] CONFIG_K3_RTI_WATCHDOG=m
+    - [Config] CONFIG_MDIO_IPQ8064=m
+    - [Config] CONFIG_MDIO_MVUSB=m
+    - [Config] CONFIG_MHI_BUS=m
+    - [Config] CONFIG_OCTEONTX2_VF=m
+    - [Config] CONFIG_PHY_CADENCE_TORRENT=m
+    - [Config] CONFIG_PHY_QCOM_USB_HS_28NM=m
+    - [Config] CONFIG_PHY_QCOM_USB_SS=m
+    - [Config] CONFIG_PINCTRL_DA9062=m
+    - [Config] CONFIG_PINCTRL_IPQ6018=m
+    - [Config] CONFIG_PTP_1588_CLOCK_IDT82P33=m
+    - [Config] CONFIG_PTP_1588_CLOCK_VMW=m
+    - [Config] CONFIG_QCOM_IPA=m
+    - [Config] CONFIG_REGULATOR_MP5416=m
+    - [Config] CONFIG_REGULATOR_MP886X=m
+    - [Config] CONFIG_RN5T618_ADC=m
+    - [Config] CONFIG_RTC_DRV_MT2712=m
+    - [Config] CONFIG_RTC_DRV_RC5T619=m
+    - [Config] CONFIG_SC_MSS_7180=m
+    - [Config] CONFIG_SENSORS_AXI_FAN_CONTROL=m
+    - [Config] CONFIG_SM_GCC_8250=m
+    - [Config] CONFIG_SND_BCM63XX_I2S_WHISTLER=m
+    - [Config] CONFIG_SND_MESON_AIU=m
+    - [Config] CONFIG_SND_MESON_G12A_TOACODEC=m
+    - [Config] CONFIG_SND_MESON_GX_SOUND_CARD=m
+    - [Config] CONFIG_SND_SOC_AMD_RV_RT5682_MACH=m
+    - [Config] CONFIG_SND_SOC_INTEL_SOF_PCM512x_MACH=m
+    - [Config] CONFIG_SND_SOC_MESON_T9015=m
+    - [Config] CONFIG_SND_SOC_RT5682_SDW=m
+    - [Config] CONFIG_SND_SOC_TLV320ADCX140=m
+    - [Config] CONFIG_SPI_FSI=m
+    - [Config] CONFIG_SPI_MTK_NOR=m
+    - [Config] CONFIG_SPI_MUX=m
+    - [Config] CONFIG_SPRD_THERMAL=m
+    - [Config] CONFIG_SURFACE_3_POWER_OPREGION=m
+    - [Config] CONFIG_TINYDRM_ILI9486=m
+    - [Config] CONFIG_TI_K3_AM65_CPSW_NUSS=m
+    - [Config] CONFIG_TYPEC_MUX_INTEL_PMC=m
+    - [Config] CONFIG_UACCE=m
+    - [Config] CONFIG_UNIPHIER_XDMAC=m
+    - [Config] CONFIG_USB_MAX3420_UDC=m
+    - [Config] CONFIG_USB_RAW_GADGET=m
+    - [Config] CONFIG_VHOST_VDPA=m
+    - [Config] CONFIG_VIDEO_IMX219=m
+    - [Config] CONFIG_VIDEO_SUN8I_ROTATE=m
+    - [Config] CONFIG_VIRTIO_VDPA=m
+    - [Config] CONFIG_MOST_COMPONENTS=m
+    - [Config] CONFIG_MFD_IQS62X=m
+    - packaging: getabis: switch to ckt-ppa:bootstrap/linux-5.7
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: rtw88: add rtw_read8_mask and rtw_read16_mask"
+    - Revert "UBUNTU: SAUCE: drm/i915/fbc: disable framebuffer compression on
+      IceLake"
+    - Revert "UBUNTU: SAUCE: platform/x86: dell-uart-backlight: move retry block"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 04 May 2020 10:48:48 +0200
+
+linux-5.7 (5.7.0-1.2) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: hio: pass make_request ptr directly to blk_alloc_queue()
+    - SAUCE: hio: locally define disk_map_sector_rcu()
+    - SAUCE: hio: Revert "block: unexport disk_map_sector_rcu"
+    - SAUCE: hio: include <linux/part_stat.h>
+    - [Config] amd64: i386: HIO=m
+    - [Config] updateconfigs after 5.7-rc3 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 27 Apr 2020 11:31:38 +0200
+
+linux-5.7 (5.7.0-0.1) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after rebase to 5.7-rc1
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7-rc1
+  * Rebase to v5.7-rc2
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 16 Apr 2020 11:53:58 +0200
+
+linux-5.7 (5.7.0-0.0) focal; urgency=medium
+
+  * Dummy entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 16 Apr 2020 11:53:58 +0200
+
+linux-5.6 (5.6.0-7.7) focal; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Kernel Oops - general protection fault: 0000 [#1] SMP PTI after
+    disconnecting thunderbolt docking station (LP: #1864754)
+    - SAUCE: ptp: free ptp clock properly
+
+  * swap storms kills interactive use (LP: #1861359)
+    - SAUCE: mm/page_alloc.c: disable memory reclaim watermark boosting by default
+
+  * sysfs: incorrect network device permissions on network namespace change
+    (LP: #1865359)
+    - sysfs: add sysfs_file_change_owner()
+    - sysfs: add sysfs_link_change_owner()
+    - sysfs: add sysfs_group{s}_change_owner()
+    - sysfs: add sysfs_change_owner()
+    - device: add device_change_owner()
+    - drivers/base/power: add dpm_sysfs_change_owner()
+    - net-sysfs: add netdev_change_owner()
+    - net-sysfs: add queue_change_owner()
+    - net: fix sysfs permssions when device changes network namespace
+    - sysfs: fix static inline declaration of sysfs_groups_change_owner()
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after rebase to 5.6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 31 Mar 2020 10:45:09 +0200
+
+linux-5.6 (5.6.0-6.6) focal; urgency=medium
+
+  * suspend only works once on ThinkPad X1 Carbon gen 7 (LP: #1865570)
+    - SAUCE: e1000e: Disable s0ix flow for X1 Carbon 7th
+
+  *  Make Dell WD19 dock more reliable after suspend (LP: #1868217)
+    - xhci: Ensure link state is U3 after setting USB_SS_PORT_LS_U3
+    - xhci: Wait until link state trainsits to U0 after setting USB_SS_PORT_LS_U0
+    - xhci: Finetune host initiated USB3 rootport link suspend and resume
+
+  * update-version-dkms doesn't add a BugLink (LP: #1867790)
+    - [Packaging] Add BugLink to update-version-dkms commit
+
+  * Add support for Realtek 8723DE wireless adapter (LP: #1780590)
+    - SAUCE: rtw88: add regulatory process strategy for different chipset
+    - SAUCE: rtw88: support dynamic user regulatory setting
+    - SAUCE: rtw88: Use secondary channel offset enumeration
+    - SAUCE: rtw88: 8822c: modify rf protection setting
+    - SAUCE: rtw88: disable TX-AMSDU on 2.4G band
+    - SAUCE: Revert "rtw88: disable TX-AMSDU on 2.4G band"
+    - SAUCE: rtw88: disable TX-AMSDU on 2.4G band
+    - SAUCE: rtw88: remove unused parameter vif in rtw_lps_pg_info_get()
+    - SAUCE: rtw88: add rtw_read8_mask and rtw_read16_mask
+    - SAUCE: rtw88: pci: 8822c should set clock delay to zero
+    - SAUCE: rtw88: move rtw_enter_ips() to the last when config
+    - SAUCE: rtw88: avoid holding mutex for cancel_delayed_work_sync()
+    - SAUCE: rtw88: add ciphers to suppress error message
+    - SAUCE: rtw88: 8822c: update power sequence to v16
+    - SAUCE: rtw88: Fix incorrect beamformee role setting
+    - SAUCE: rtw88: don't hold all IRQs disabled for PS operations
+    - SAUCE: rtw88: extract alloc rsvd_page and h2c skb routines
+    - SAUCE: rtw88: associate reserved pages with each vif
+    - SAUCE: rtw88: add adaptivity support for EU/JP regulatory
+    - SAUCE: rtw88: 8723d: Add basic chip capabilities
+    - SAUCE: rtw88: 8723d: add beamform wrapper functions
+    - SAUCE: rtw88: 8723d: Add power sequence
+    - SAUCE: rtw88: 8723d: Add RF read/write ops
+    - SAUCE: rtw88: 8723d: Add mac/bb/rf/agc/power_limit tables
+    - SAUCE: rtw88: 8723d: Add cfg_ldo25 to control LDO25
+    - SAUCE: rtw88: 8723d: Add new chip op efuse_grant() to control efuse access
+    - SAUCE: rtw88: 8723d: Add read_efuse to recognize efuse info from map
+    - SAUCE: rtw88: add legacy firmware download for 8723D devices
+    - SAUCE: rtw88: no need to send additional information to legacy firmware
+    - SAUCE: rtw88: 8723d: Add mac power-on/-off function
+    - SAUCE: rtw88: decompose while(1) loop of power sequence polling command
+    - SAUCE: rtw88: 8723d: 11N chips don't support H2C queue
+    - SAUCE: rtw88: 8723d: implement set_tx_power_index ops
+    - SAUCE: rtw88: 8723d: Organize chip TX/RX FIFO
+    - SAUCE: rtw88: 8723d: initialize mac/bb/rf basic functions
+    - SAUCE: rtw88: 8723d: Add DIG parameter
+    - SAUCE: rtw88: 8723d: Add query_rx_desc
+    - SAUCE: rtw88: 8723d: Add set_channel
+    - SAUCE: rtw88: handle C2H_CCX_TX_RPT to know if packet TX'ed successfully
+    - SAUCE: rtw88: 8723d: 11N chips don't support LDPC
+    - SAUCE: rtw88: set default port to firmware
+    - SAUCE: rtw88: update tx descriptor of mgmt and rsvd page packets
+    - SAUCE: rtw88: sar: add SAR of TX power limit
+    - SAUCE: rtw88: sar: Load static SAR table from ACPI WRDS method
+    - SAUCE: rtw88: sar: Load dynamic SAR table from ACPI methods
+    - SAUCE: rtw88: sar: apply dynamic SAR table to tx power limit
+    - SAUCE: rtw88: sar: add sar_work to poll if dynamic SAR table is changed
+    - SAUCE: rtw88: sar: dump sar information via debugfs
+    - SAUCE: rtw88: 8723d: Add chip_ops::false_alarm_statistics
+    - SAUCE: rtw88: 8723d: Set IG register for CCK rate
+    - SAUCE: rtw88: 8723d: add interface configurations table
+    - SAUCE: rtw88: 8723d: Add LC calibration
+    - SAUCE: rtw88: 8723d: add IQ calibration
+    - SAUCE: rtw88: 8723d: Add power tracking
+    - SAUCE: rtw88: 8723d: Add shutdown callback to disable BT USB suspend
+    - SAUCE: rtw88: 8723d: implement flush queue
+    - SAUCE: rtw88: 8723d: set ltecoex register address in chip_info
+    - SAUCE: rtw88: 8723d: Add coex support
+    - SAUCE: rtw88: fill zeros to words 0x06 and 0x07 of security cam entry
+    - SAUCE: rtw88: 8723d: Add 8723DE to Kconfig and Makefile
+    - [Config] CONFIG_RTW88_8723DE=y
+
+  * [Ubuntu 20.04] Unset HIBERNATION and PM kernel config options for focal
+    (LP: #1867753)
+    - [Config] CONFIG_HIBERNATION=n and CONFIG_PM=n for s390x
+
+  * [20.04 FEAT] Base KVM setup for secure guests - kernel part (LP: #1835531)
+    - s390/protvirt: introduce host side setup
+    - s390/protvirt: add ultravisor initialization
+    - s390/mm: provide memory management functions for protected KVM guests
+    - s390/mm: add (non)secure page access exceptions handlers
+    - s390/protvirt: Add sysfs firmware interface for Ultravisor information
+    - KVM: s390/interrupt: do not pin adapter interrupt pages
+    - KVM: s390: protvirt: Add UV debug trace
+    - KVM: s390: add new variants of UV CALL
+    - KVM: s390: protvirt: Add initial vm and cpu lifecycle handling
+    - KVM: s390: protvirt: Secure memory is not mergeable
+    - KVM: s390/mm: Make pages accessible before destroying the guest
+    - KVM: s390: protvirt: Handle SE notification interceptions
+    - KVM: s390: protvirt: Instruction emulation
+    - KVM: s390: protvirt: Implement interrupt injection
+    - KVM: s390: protvirt: Add SCLP interrupt handling
+    - KVM: s390: protvirt: Handle spec exception loops
+    - KVM: s390: protvirt: Add new gprs location handling
+    - KVM: S390: protvirt: Introduce instruction data area bounce buffer
+    - KVM: s390: protvirt: handle secure guest prefix pages
+    - KVM: s390/mm: handle guest unpin events
+    - KVM: s390: protvirt: Write sthyi data to instruction data area
+    - KVM: s390: protvirt: STSI handling
+    - KVM: s390: protvirt: disallow one_reg
+    - KVM: s390: protvirt: Do only reset registers that are accessible
+    - KVM: s390: protvirt: Only sync fmt4 registers
+    - KVM: s390: protvirt: Add program exception injection
+    - KVM: s390: protvirt: UV calls in support of diag308 0, 1
+    - KVM: s390: protvirt: Report CPU state to Ultravisor
+    - KVM: s390: protvirt: Support cmd 5 operation state
+    - KVM: s390: protvirt: Mask PSW interrupt bits for interception 104 and 112
+    - KVM: s390: protvirt: do not inject interrupts after start
+    - KVM: s390: protvirt: Add UV cpu reset calls
+    - DOCUMENTATION: Protected virtual machine introduction and IPL
+    - KVM: s390: protvirt: introduce and enable KVM_CAP_S390_PROTECTED
+    - KVM: s390: protvirt: Add KVM api documentation
+    - mm/gup/writeback: add callbacks for inaccessible pages
+
+  * All PS/2 ports on PS/2 Serial add-in bracket are not working after S3
+    (LP: #1866734)
+    - SAUCE: Input: i8042 - fix the selftest retry logic
+
+  * Sys oopsed with sysfs test in ubuntu_stress_smoke_test on X-hwe ARM64
+    (LP: #1866772)
+    - ACPI: sysfs: copy ACPI data using io memory copying
+
+  * Miscellaneous Ubuntu changes
+    - hio -- remove duplicated MODULE_DEVICE_TABLE declaration
+    - SAUCE: r8169: disable ASPM L1.1
+    - [Config] update annotations from configs
+    - [Config] update configs after annotation file review
+    - SAUCE: Revert "tools/power turbostat: Fix 32-bit capabilities warning"
+
+  * Miscellaneous upstream changes
+    - drm/i915: Fix eDP DPCD aux max backlight calculations
+    - drm/dp: Introduce EDID-based quirks
+    - drm/i915: Force DPCD backlight mode on X1 Extreme 2nd Gen 4K AMOLED panel
+    - drm/i915: Force DPCD backlight mode for some Dell CML 2020 panels
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 25 Mar 2020 18:09:13 +0100
+
+linux-5.6 (5.6.0-5.5) focal; urgency=medium
+
+  * please help enable CONFIG_EROFS_FS_ZIP (LP: #1867099)
+    - [Config] CONFIG_EROFS_FS_ZIP=y
+    - [Config] CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT=1
+
+  * Miscellaneous Ubuntu changes
+    - Config: Fix SND_HDA_PREALLOC_SIZE annotations
+    - Config: Fix DATA_SHIFT annotations
+    - Config: remove ANDROID_VSOC from annotations
+    - Config: remove arm arch from annotations
+    - Config: Update SOC_R8A7796X annotations
+    - Config: Update CLK_R8A7796X annotations
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.6-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 18 Mar 2020 17:25:30 +0100
+
+linux-5.6 (5.6.0-4.4) focal; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+    - [Packaging] update helper scripts
+
+  * Add sysfs attribute to show remapped NVMe (LP: #1863621)
+    - SAUCE: ata: ahci: Add sysfs attribute to show remapped NVMe device count
+
+  * [20.04 FEAT] Compression improvements in Linux kernel (LP: #1830208)
+    - [Config] Introducing s390x specific kernel config option CONFIG_ZLIB_DFLTCC
+
+  * [UBUNTU 20.04] s390x/pci: increase CONFIG_PCI_NR_FUNCTIONS to 512 in kernel
+    config (LP: #1866056)
+    - [Config] Increase CONFIG_PCI_NR_FUNCTIONS from 64 to 512 starting with focal
+      on s390x
+
+  * CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set (LP: #1865332)
+    - [Config] CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+
+  * [UBUNTU 20.04] Enable CONFIG_NET_SWITCHDEV in kernel config for s390x
+    starting with focal (LP: #1865452)
+    - [Config] Enable CONFIG_NET_SWITCHDEV in kernel config for s390x starting
+      with focal
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "UBUNTU: SAUCE: blk/core: Gracefully handle unset
+      make_request_fn"
+    - [Packaging] prevent duplicated entries in modules.ignore
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.6-rc5
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 Mar 2020 09:42:06 +0100
+
+linux-5.6 (5.6.0-3.3) focal; urgency=medium
+
+  * nsleep-lat / set-timer-lat / inconsistency-check / raw_skew from timer in
+    ubuntu_kernel_selftests timeout on 5.3 / 5.4 (LP: #1864626)
+    - selftests/timers: Turn off timeout setting
+
+  * Update kernel options CONFIG_NR_CPUS and CONFIG_NUMA_EMU for focal
+    (LP: #1864198)
+    - Ubuntu: [Config] Update kernel options CONFIG_NR_CPUS and CONFIG_NUMA_EMU
+
+  * alsa/hda/realtek: fix a mute led regression on Lenovo X1 Carbon
+    (LP: #1864576)
+    - SAUCE: ALSA: hda/realtek - Fix a regression for mute led on Lenovo Carbon X1
+
+  * r8152 init may take up to 40 seconds at initialization with Dell WD19/WD19DC
+    during hotplug (LP: #1864284)
+    - UBUNTU SAUCE: r8151: check disconnect status after long sleep
+
+  * Another Dell AIO backlight issue (LP: #1863880)
+    - SAUCE: platform/x86: dell-uart-backlight: move retry block
+
+  * Backport GetFB2 ioctl (LP: #1863874)
+    - SAUCE: drm: Add getfb2 ioctl
+
+  * Focal Fossa (20.04) feature request - Enable CONFIG_X86_UV (LP: #1863810)
+    - [Config] CONFIG_X86_UV=y
+
+  * Miscellaneous Ubuntu changes
+    - debian: remove snapdragon config, rules and flavour
+    - remove snapdragon abi files
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.6-rc4
+
+  * Miscellaneous upstream changes
+    - updateconfigs following snapdragon removal
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 04 Mar 2020 08:21:10 +0100
+
+linux-5.6 (5.6.0-2.2) focal; urgency=medium
+
+  * Sometimes can't adjust brightness on Dell AIO (LP: #1862885)
+    - SAUCE: platform/x86: dell-uart-backlight: increase retry times
+
+  * Dell XPS 13 (7390) Display Flickering - 19.10  (LP: #1849947)
+    - SAUCE: drm/i915: Disable PSR by default on all platforms
+
+  * Miscellaneous Ubuntu changes
+    - [debian] ignore missing wireguard module
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - [Config] CONFIG_LOCK_DOWN_IN_SECURE_BOOT=y
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.6-rc3
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (lockdown) s390/ipl: lockdown kernel when booted
+      secure"
+    - Revert "UBUNTU: SAUCE: (lockdown) KEYS: Make use of platform keyring for
+      module signature verify"
+    - Revert "UBUNTU: SAUCE: (lockdown) Add a SysRq option to lift kernel
+      lockdown"
+    - Revert "UBUNTU: SAUCE: (lockdown) security: lockdown: expose a hook to lock
+      the kernel down"
+    - Revert "UBUNTU: SAUCE: (lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err()."
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 24 Feb 2020 18:57:22 +0100
+
+linux-5.6 (5.6.0-1.1) focal; urgency=medium
+
+  *  Integrate Intel SGX driver into linux-azure (LP: #1844245)
+    - [Packaging] Add systemd service to load intel_sgx
+
+  * QAT drivers for C3XXX and C62X not included as modules (LP: #1845959)
+    - [Config] CRYPTO_DEV_QAT_C3XXX=m, CRYPTO_DEV_QAT_C62X=m and
+      CRYPTO_DEV_QAT_DH895xCC=m
+
+  * 5.4.0-11 crash on cryptsetup open (LP: #1860231)
+    - SAUCE: blk/core: Gracefully handle unset make_request_fn
+
+  * multi-zone raid0 corruption (LP: #1850540)
+    - SAUCE: md/raid0: Use kernel specific layout
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - update dropped.txt after rebase to v5.6-rc1
+    - [Config] updateconfigs after rebase to 5.6-rc1
+    - hio -- proc_create() requires a "struct proc_ops" in 5.6
+    - SAUCE: arm: fix build error in kvm tracepoint
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] Disable the uselib system call"
+    - Revert "UBUNTU: [Config] Disable legacy PTY naming"
+    - Revert "UBUNTU: [Config] Enforce filtered access to iomem"
+    - Revert "UBUNTU: [Config] Enable notifier call chain validations"
+    - Revert "UBUNTU: [Config] Enable scatterlist validation"
+    - Revert "UBUNTU: [Config] Enable cred sanity checks"
+    - Revert "UBUNTU: [Config] Enable linked list manipulation checks"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 13 Feb 2020 17:20:27 +0100
+
+linux-5.6 (5.6.0-0.0) focal; urgency=medium
+
+  * Dummy entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 10 Feb 2020 11:06:18 +0100
+
+linux-5.5 (5.5.0-7.8) focal; urgency=medium
+
+  * CONFIG_USELIB should be disabled (LP: #1855341)
+    - [Config] Disable the uselib system call
+
+  * CONFIG_LEGACY_PTYS should be disabled (LP: #1855339)
+    - [Config] Disable legacy PTY naming
+
+  * CONFIG_IO_STRICT_DEVMEM should be enabled (LP: #1855338)
+    - [Config] Enforce filtered access to iomem
+
+  * CONFIG_DEBUG_NOTIFIERS should be enabled (LP: #1855337)
+    - [Config] Enable notifier call chain validations
+
+  * CONFIG_DEBUG_SG should be enabled (LP: #1855336)
+    - [Config] Enable scatterlist validation
+
+  * CONFIG_DEBUG_CREDENTIALS should be enabled (LP: #1855335)
+    - [Config] Enable cred sanity checks
+
+  * CONFIG_DEBUG_LIST should be enabled (LP: #1855334)
+    - [Config] Enable linked list manipulation checks
+
+  * shiftfs: prevent lower dentries from going negative during unlink
+    (LP: #1860041)
+    - SAUCE: shiftfs: prevent lower dentries from going negative during unlink
+
+  * [SRU][B/OEM-B/OEM-OSP1/D/E/Unstable] UBUNTU: SAUCE: Use native backlight on
+    Lenovo E41-25/45 (LP: #1859561)
+    - SAUCE: ACPI: video: Use native backlight on Lenovo E41-25/45
+
+  * USB key cannot be detected by hotplug on Sunix USB Type-A 3.1 Gen 2 card
+    [1b21:2142]  (LP: #1858988)
+    - SAUCE: PCI: Avoid ASMedia XHCI USB PME# from D0 defect
+
+  * Dell AIO can't adjust brightness (LP: #1858761)
+    - SAUCE: platform/x86: dell-uart-backlight: add retry for get scalar status
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Fix typo in annotations file
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 27 Jan 2020 11:39:38 +0100
+
+linux-5.5 (5.5.0-6.7) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Update ubuntu-regression-suite dependency to python2
+    - [Packaging] Fix ubuntu-regression-suite python dependency for hwe kernel
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.5-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 20 Jan 2020 10:16:01 +0100
+
+linux-5.5 (5.5.0-5.6) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.5-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 13 Jan 2020 15:50:12 +0100
+
+linux-5.5 (5.5.0-4.5) focal; urgency=medium
+
+  * linux build and autopkg tests need to use python2 instead of python
+    (LP: #1858487)
+    - [Packaging] Remove python-dev build dependency
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Jan 2020 16:00:26 +0100
+
+linux-5.5 (5.5.0-3.4) focal; urgency=medium
+
+  * [SRU][B/OEM-B/OEM-OSP1/D/E/F] Add LG I2C touchscreen multitouch support
+    (LP: #1857541)
+    - SAUCE: HID: multitouch: Add LG MELF0410 I2C touchscreen support
+
+  * Make vfio-pci built-in or xhci_hcd optional (LP: #1770845)
+    - [Config]: built-in VFIO_PCI for amd64
+
+  * multi-zone raid0 corruption (LP: #1850540)
+    - SAUCE: md/raid0: Link to wiki with guidance on multi-zone RAID0 layout
+      migration
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Change source package to linux-5.5
+    - [Packaging] Don't use SRCPKGNAME for linux-libc-dev
+    - [Packaging] Remove linux-source-3 Provides: from linux-source
+    - [Packaging] Fix linux-doc in linux-image Suggests:
+    - [Debian] Read variants list into a variable
+    - [Packaging] Generate linux-libc-dev package only for primary variant
+    - [Packaging] Generate linux-doc for only the primary variant
+    - [Debian] Update linux source package name in debian/tests/*
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.5-rc3
+    - [Config] disable PCI_MESON
+    - [Config] Add pinctrl-equilibrium to modules.ignore
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.5-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Jan 2020 11:28:43 +0100
+
+linux-5.5 (5.5.0-2.3) focal; urgency=medium
+
+  * Empty entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 17 Dec 2019 22:33:59 -0600
+
+linux (5.5.0-2.3) focal; urgency=medium
+
+  * Support DPCD aux brightness control (LP: #1856134)
+    - SAUCE: drm/i915: Fix eDP DPCD aux max backlight calculations
+    - SAUCE: drm/i915: Assume 100% brightness when not in DPCD control mode
+    - SAUCE: drm/i915: Fix DPCD register order in intel_dp_aux_enable_backlight()
+    - SAUCE: drm/i915: Auto detect DPCD backlight support by default
+    - SAUCE: drm/i915: Force DPCD backlight mode on X1 Extreme 2nd Gen 4K AMOLED
+      panel
+    - USUNTU: SAUCE: drm/i915: Force DPCD backlight mode on Dell Precision 4K sku
+
+  * change kconfig of the soundwire bus driver from y to m (LP: #1855685)
+    - [Config]: SOUNDWIRE=m
+
+  * Fix unusable USB hub on Dell TB16 after S3 (LP: #1855312)
+    - SAUCE: USB: core: Make port power cycle a seperate helper function
+    - SAUCE: USB: core: Attempt power cycle port when it's in eSS.Disabled state
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] add python depends to ubuntu-regression-suite
+    - SAUCE: selftests: net: tls: remove recv_rcvbuf test
+    - update dkms package versions
+
+  * Miscellaneous upstream changes
+    - [Config] updateconfigs after rebase to 5.5-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 17 Dec 2019 16:02:43 +0100
+
+linux (5.5.0-1.2) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] disable nvidia dkms build
+    - [Config] disable virtualbox dkms build
+    - [Config] disable zfs dkms build
+    - update dropped.txt after rebase to v5.5-rc1
+    - SAUCE: (lockdown) Make get_cert_list() not complain about cert lists that
+      aren't present.
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - SAUCE: (lockdown) s390/ipl: lockdown kernel when booted secure
+    - [Config] Enable lockdown under secure boot
+    - update dkms package versions
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 12 Dec 2019 16:54:41 +0100
+
+linux (5.5.0-0.1) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after rebase to 5.5-rc1
+
+   [ Upstream Kernel Changes ]
+
+   * Rebase to v5.5-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 Dec 2019 19:03:35 +0100
+
+linux (5.5.0-0.0) focal; urgency=medium
+
+  * Dummy entry.
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 Dec 2019 15:14:37 +0100
+
+linux (5.4.0-8.11) focal; urgency=medium
+
+  * focal/linux: 5.4.0-8.9 -proposed tracker (LP: #1855448)
+
+  * update ENA driver for DIMLIB dynamic interrupt moderation (LP: #1853180)
+    - SAUCE: net: ena: fix issues in setting interrupt moderation params in
+      ethtool
+    - SAUCE: net: ena: fix too long default tx interrupt moderation interval
+
+  * Kernel build log filled with "/bin/bash: line 5: warning: command
+    substitution: ignored null byte in input" (LP: #1853843)
+    - [Debian] Fix warnings when checking for modules signatures
+
+  * hwe-edge kernel 5.3.0-23.25 kernel does not boot on Precision 5720 AIO
+    (LP: #1852581)
+    - [Packaging] Fix module signing with older modinfo
+
+  * Fix MST support on Ice Lake (LP: #1854432)
+    - drm/i915: fix port checks for MST support on gen >= 11
+
+  * headphone has noise as not mute on dell machines with alc236/256
+    (LP: #1854401)
+    - SAUCE: ALSA: hda/realtek - Dell headphone has noise on unmute for ALC236
+
+  * [CML-S62] Need enable intel_pmc_core driver patch for Comet lake- S 6+2
+    (LP: #1847450)
+    - SAUCE: platform/x86: intel_pmc_core: Add Comet Lake (CML) platform support
+      to intel_pmc_core driver
+
+  * CVE-2019-14901
+    - SAUCE: mwifiex: Fix heap overflow in mmwifiex_process_tdls_action_frame()
+
+  * CVE-2019-14896 // CVE-2019-14897
+    - SAUCE: libertas: Fix two buffer overflows at parsing bss descriptor
+
+  * CVE-2019-14895
+    - SAUCE: mwifiex: fix possible heap overflow in mwifiex_process_country_ie()
+
+  * [CML-S62] Need enable intel_rapl patch support for Comet lake- S 6+2
+    (LP: #1847454)
+    - powercap/intel_rapl: add support for CometLake Mobile
+    - powercap/intel_rapl: add support for Cometlake desktop
+
+  * External microphone can't work on some dell machines with the codec alc256
+    or alc236 (LP: #1853791)
+    - SAUCE: ALSA: hda/realtek - Move some alc256 pintbls to fallback table
+    - SAUCE: ALSA: hda/realtek - Move some alc236 pintbls to fallback table
+
+  * remount of multilower moved pivoted-root overlayfs root, results in I/O
+    errors on some modified files (LP: #1824407)
+    - SAUCE: ovl: fix lookup failure on multi lower squashfs
+
+  * [CML-S62] Need enable turbostat patch support for Comet lake- S 6+2
+    (LP: #1847451)
+    - SAUCE: tools/power turbostat: Add Cometlake support
+
+  * CONFIG_ARCH_ROCKCHIP is not set in ubuntu 18.04 aarch64,arm64 (LP: #1825222)
+    - [Config] Enable ROCKCHIP support for arm64
+
+  * [broadwell-rt286, playback] Since Linux 5.2rc2 audio playback no longer
+    works on Dell Venue 11 Pro 7140 (LP: #1846539)
+    - SAUCE: ASoC: SOF: Intel: Broadwell: clarify mutual exclusion with legacy
+      driver
+
+  * i40e: general protection fault in i40e_config_vf_promiscuous_mode
+    (LP: #1852663)
+    - SAUCE: i40e Fix GPF when deleting VMs
+
+  * libbpf check_abi fails on ppc64el (LP: #1854974)
+    - libbpf: Fix readelf output parsing on powerpc with recent binutils
+
+  * CVE-2019-19050
+    - crypto: user - fix memory leak in crypto_reportstat
+
+  * Make hotplugging docking station to Thunderbolt port more reliable
+    (LP: #1853991)
+    - PCI/PM: Add pcie_wait_for_link_delay()
+    - PCI/PM: Add missing link delays required by the PCIe spec
+
+  * i915: Display flickers (monitor loses signal briefly) during "flickerfree"
+    boot, while showing the BIOS logo on a black background (LP: #1836858)
+    - [Config] FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y
+
+  * [CML] New device id's for CMP-H (LP: #1846335)
+    - i2c: i801: Add support for Intel Comet Lake PCH-H
+    - mtd: spi-nor: intel-spi: Add support for Intel Comet Lake-H SPI serial flash
+    - mfd: intel-lpss: Add Intel Comet Lake PCH-H PCI IDs
+
+  * Focal update: v5.4.2 upstream stable release (LP: #1855326)
+    - io_uring: async workers should inherit the user creds
+    - net: separate out the msghdr copy from ___sys_{send,recv}msg()
+    - net: disallow ancillary data for __sys_{send,recv}msg_file()
+    - crypto: inside-secure - Fix stability issue with Macchiatobin
+    - driver core: platform: use the correct callback type for bus_find_device
+    - usb: dwc2: use a longer core rest timeout in dwc2_core_reset()
+    - staging: wilc1000: fix illegal memory access in wilc_parse_join_bss_param()
+    - staging: rtl8192e: fix potential use after free
+    - staging: rtl8723bs: Drop ACPI device ids
+    - staging: rtl8723bs: Add 024c:0525 to the list of SDIO device-ids
+    - USB: serial: ftdi_sio: add device IDs for U-Blox C099-F9P
+    - mei: bus: prefix device names on bus with the bus name
+    - mei: me: add comet point V device id
+    - thunderbolt: Power cycle the router if NVM authentication fails
+    - x86/fpu: Don't cache access to fpu_fpregs_owner_ctx
+    - gve: Fix the queue page list allocated pages count
+    - macvlan: schedule bc_work even if error
+    - mdio_bus: don't use managed reset-controller
+    - net: dsa: sja1105: fix sja1105_parse_rgmii_delays()
+    - net: macb: add missed tasklet_kill
+    - net: psample: fix skb_over_panic
+    - net: sched: fix `tc -s class show` no bstats on class with nolock subqueues
+    - openvswitch: fix flow command message size
+    - sctp: Fix memory leak in sctp_sf_do_5_2_4_dupcook
+    - slip: Fix use-after-free Read in slip_open
+    - sctp: cache netns in sctp_ep_common
+    - openvswitch: drop unneeded BUG_ON() in ovs_flow_cmd_build_info()
+    - openvswitch: remove another BUG_ON()
+    - net/tls: take into account that bpf_exec_tx_verdict() may free the record
+    - net/tls: free the record on encryption error
+    - net: skmsg: fix TLS 1.3 crash with full sk_msg
+    - selftests/tls: add a test for fragmented messages
+    - net/tls: remove the dead inplace_crypto code
+    - net/tls: use sg_next() to walk sg entries
+    - selftests: bpf: test_sockmap: handle file creation failures gracefully
+    - selftests: bpf: correct perror strings
+    - tipc: fix link name length check
+    - selftests: pmtu: use -oneline for ip route list cache
+    - r8169: fix jumbo configuration for RTL8168evl
+    - r8169: fix resume on cable plug-in
+    - ext4: add more paranoia checking in ext4_expand_extra_isize handling
+    - Revert "jffs2: Fix possible null-pointer dereferences in
+      jffs2_add_frag_to_fragtree()"
+    - crypto: talitos - Fix build error by selecting LIB_DES
+    - HID: core: check whether Usage Page item is after Usage ID items
+    - platform/x86: hp-wmi: Fix ACPI errors caused by too small buffer
+    - platform/x86: hp-wmi: Fix ACPI errors caused by passing 0 as input size
+    - Linux 5.4.2
+
+  * no HDMI video output since GDM greeter after linux-oem-osp1 version
+    5.0.0-1026 (LP: #1852386)
+    - drm/i915: Add new CNL PCH ID seen on a CML platform
+    - SAUCE: drm/i915: Fix detection for a CMP-V PCH
+
+  * Please add patch fixing RK818 ID detection (LP: #1853192)
+    - SAUCE: mfd: rk808: Fix RK818 ID template
+
+  * Raydium Touchscreen on ThinkPad L390 does not work (LP: #1849721)
+    - HID: i2c-hid: fix no irq after reset on raydium 3118
+
+  * Touchpad doesn't work on Dell Inspiron 7000 2-in-1 (LP: #1851901)
+    - Revert "UBUNTU: SAUCE: mfd: intel-lpss: add quirk for Dell XPS 13 7390
+      2-in-1"
+    - lib: devres: add a helper function for ioremap_uc
+    - mfd: intel-lpss: Use devm_ioremap_uc for MMIO
+
+  * Lenovo dock MAC Address pass through doesn't work in Ubuntu  (LP: #1827961)
+    - r8152: Add macpassthru support for ThinkPad Thunderbolt 3 Dock Gen 2
+
+  * Disable unreliable HPET on CFL-H system (LP: #1852216)
+    - SAUCE: x86/intel: Disable HPET on Intel Coffe Lake H platforms
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] Enable virtualbox dkms build
+    - [Config] update annotations to match current configs
+    - SAUCE: Add exfat module to signature inclusion list
+
+  * Miscellaneous upstream changes
+    - Bluetooth: Fix invalid-free in bcsp_close()
+    - ath9k_hw: fix uninitialized variable data
+    - ath10k: Fix a NULL-ptr-deref bug in ath10k_usb_alloc_urb_from_pipe
+    - ath10k: Fix HOST capability QMI incompatibility
+    - ath10k: restore QCA9880-AR1A (v1) detection
+    - Revert "Bluetooth: hci_ll: set operational frequency earlier"
+    - Revert "dm crypt: use WQ_HIGHPRI for the IO and crypt workqueues"
+    - md/raid10: prevent access of uninitialized resync_pages offset
+    - x86/insn: Fix awk regexp warnings
+    - x86/speculation: Fix incorrect MDS/TAA mitigation status
+    - x86/speculation: Fix redundant MDS mitigation message
+    - nbd: prevent memory leak
+    - x86/stackframe/32: Repair 32-bit Xen PV
+    - x86/xen/32: Make xen_iret_crit_fixup() independent of frame layout
+    - x86/xen/32: Simplify ring check in xen_iret_crit_fixup()
+    - x86/doublefault/32: Fix stack canaries in the double fault handler
+    - x86/pti/32: Size initial_page_table correctly
+    - x86/cpu_entry_area: Add guard page for entry stack on 32bit
+    - x86/entry/32: Fix IRET exception
+    - x86/entry/32: Use %ss segment where required
+    - x86/entry/32: Move FIXUP_FRAME after pushing %fs in SAVE_ALL
+    - x86/entry/32: Unwind the ESPFIX stack earlier on exception entry
+    - x86/entry/32: Fix NMI vs ESPFIX
+    - selftests/x86/mov_ss_trap: Fix the SYSENTER test
+    - selftests/x86/sigreturn/32: Invalidate DS and ES when abusing the kernel
+    - x86/pti/32: Calculate the various PTI cpu_entry_area sizes correctly, make
+      the CPU_ENTRY_AREA_PAGES assert precise
+    - x86/entry/32: Fix FIXUP_ESPFIX_STACK with user CR3
+    - futex: Prevent robust futex exit race
+    - ALSA: usb-audio: Fix NULL dereference at parsing BADD
+    - ALSA: usb-audio: Fix Scarlett 6i6 Gen 2 port data
+    - media: vivid: Set vid_cap_streaming and vid_out_streaming to true
+    - media: vivid: Fix wrong locking that causes race conditions on streaming
+      stop
+    - media: usbvision: Fix invalid accesses after device disconnect
+    - media: usbvision: Fix races among open, close, and disconnect
+    - cpufreq: Add NULL checks to show() and store() methods of cpufreq
+    - futex: Move futex exit handling into futex code
+    - futex: Replace PF_EXITPIDONE with a state
+    - exit/exec: Seperate mm_release()
+    - futex: Split futex_mm_release() for exit/exec
+    - futex: Set task::futex_state to DEAD right after handling futex exit
+    - futex: Mark the begin of futex exit explicitly
+    - futex: Sanitize exit state handling
+    - futex: Provide state handling for exec() as well
+    - futex: Add mutex around futex exit
+    - futex: Provide distinct return value when owner is exiting
+    - futex: Prevent exit livelock
+    - media: uvcvideo: Fix error path in control parsing failure
+    - media: b2c2-flexcop-usb: add sanity checking
+    - media: cxusb: detect cxusb_ctrl_msg error in query
+    - media: imon: invalid dereference in imon_touch_event
+    - media: mceusb: fix out of bounds read in MCE receiver buffer
+    - ALSA: hda - Disable audio component for legacy Nvidia HDMI codecs
+    - USBIP: add config dependency for SGL_ALLOC
+    - usbip: tools: fix fd leakage in the function of read_attr_usbip_status
+    - usbip: Fix uninitialized symbol 'nents' in stub_recv_cmd_submit()
+    - usb-serial: cp201x: support Mark-10 digital force gauge
+    - USB: chaoskey: fix error case of a timeout
+    - appledisplay: fix error handling in the scheduled work
+    - USB: serial: mos7840: add USB ID to support Moxa UPort 2210
+    - USB: serial: mos7720: fix remote wakeup
+    - USB: serial: mos7840: fix remote wakeup
+    - USB: serial: option: add support for DW5821e with eSIM support
+    - USB: serial: option: add support for Foxconn T77W968 LTE modules
+    - staging: comedi: usbduxfast: usbduxfast_ai_cmdtest rounding error
+    - powerpc/book3s64: Fix link stack flush on context switch
+    - KVM: PPC: Book3S HV: Flush link stack on guest exit to host kernel
+    - Linux 5.4.1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 06 Dec 2019 15:53:53 -0600
+
+linux (5.4.0-7.8) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/bpf: Comment out BPF_CORE_READ's which cause clang to
+      segfault
+    - Update nvidia-430 to nvidia-440
+    - [Config] Enable nvidia dkms build
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 25 Nov 2019 15:02:30 +0100
+
+linux (5.4.0-6.7) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.4-rc8
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 18 Nov 2019 12:08:01 +0100
+
+linux (5.4.0-5.6) focal; urgency=medium
+
+  * refcount underflow and type confusion in shiftfs (LP: #1850867) //
+    CVE-2019-15793
+    - SAUCE: shiftfs: Correct id translation for lower fs operations
+
+  * refcount underflow and type confusion in shiftfs (LP: #1850867) //
+    CVE-2019-15792
+    - SAUCE: shiftfs: prevent type confusion
+
+  * refcount underflow and type confusion in shiftfs (LP: #1850867) //
+    CVE-2019-15791
+    - SAUCE: shiftfs: Fix refcount underflow in btrfs ioctl handling
+
+  * Some EFI systems fail to boot in efi_init() when booted via maas
+    (LP: #1851810)
+    - SAUCE: efi: efi_get_memory_map -- increase map headroom
+
+  * seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test (LP: #1849281)
+    - SAUCE: seccomp: rework define for SECCOMP_USER_NOTIF_FLAG_CONTINUE
+    - SAUCE: seccomp: avoid overflow in implicit constant conversion
+
+  * dkms artifacts may expire from the pool (LP: #1850958)
+    - [Packaging] dkms -- try launchpad librarian for pool downloads
+    - [Packaging] dkms -- dkms-build quieten wget verbiage
+
+  * tsc marked unstable after entered PC10 on Intel CoffeeLake (LP: #1840239)
+    - SAUCE: x86/intel: Disable HPET on Intel Coffe Lake platforms
+    - SAUCE: x86/intel: Disable HPET on Intel Ice Lake platforms
+
+  * shiftfs: prevent exceeding project quotas (LP: #1849483)
+    - SAUCE: shiftfs: drop CAP_SYS_RESOURCE from effective capabilities
+
+  * shiftfs: fix fallocate() (LP: #1849482)
+    - SAUCE: shiftfs: setup correct s_maxbytes limit
+
+  * The alsa hda driver is not loaded due to the missing of PCIID for Comet
+    Lake-S [8086:a3f0] (LP: #1852070)
+    - SAUCE: ALSA: hda: Add Cometlake-S PCI ID
+
+  * Can't adjust brightness on DELL UHD dGPU AIO (LP: #1813877)
+    - SAUCE: platform/x86: dell-uart-backlight: add missing status command
+    - SAUCE: platform/x86: dell-uart-backlight: load driver by scalar status
+    - SAUCE: platform/x86: dell-uart-backlight: add force parameter
+    - SAUCE: platform/x86: dell-uart-backlight: add quirk for old platforms
+
+  * s_iflags overlap prevents unprivileged overlayfs mounts (LP: #1851677)
+    - SAUCE: fs: Move SB_I_NOSUID to the top of s_iflags
+
+  * ubuntu-aufs-modified mmap_region() breaks refcounting in overlayfs/shiftfs
+    error path (LP: #1850994) // CVE-2019-15794
+    - SAUCE: shiftfs: Restore vm_file value when lower fs mmap fails
+    - SAUCE: ovl: Restore vm_file value when lower fs mmap fails
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Convert update-aufs.sh to use aufs5
+    - SAUCE: import aufs driver
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 13 Nov 2019 11:56:35 -0800
+
+linux (5.4.0-4.5) focal; urgency=medium
+
+  * High power consumption using 5.0.0-25-generic (LP: #1840835)
+    - PCI: Add a helper to check Power Resource Requirements _PR3 existence
+    - ALSA: hda: Allow HDA to be runtime suspended when dGPU is not bound to a
+      driver
+    - PCI: Fix missing inline for pci_pr3_present()
+
+  * Fix signing of staging modules in eoan (LP: #1850234)
+    - [Packaging] Leave unsigned modules unsigned after adding .gnu_debuglink
+
+  * [20.04 FEAT] Set Architecture Level (ALS) to z13 (LP: #1837525)
+    - [Config] s390x bump march to z13, with tune to z15
+
+  * Miscellaneous Ubuntu changes
+    - [Debian]: do not skip tests for linux-hwe-edge
+    - update dkms package versions
+    - [Config] re-enable zfs
+    - [Config] rename module virtio_fs to virtiofs
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 04 Nov 2019 15:12:02 +0100
+
+linux (5.4.0-3.4) focal; urgency=medium
+
+  * seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test (LP: #1849281)
+    - SAUCE: seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test
+
+  * cloudimg: no iavf/i40evf module so no network available with SR-IOV enabled
+    cloud (LP: #1848481)
+    - [Packaging] include iavf/i40evf in generic
+
+  * CVE-2019-17666
+    - SAUCE: rtlwifi: Fix potential overflow on P2P code
+
+  * Change Config Option CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE for s390x from yes
+    to no (LP: #1848492)
+    - [Config] Change Config Option CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE for s390x
+      from yes to no
+
+  * Add Intel Comet Lake ethernet support (LP: #1848555)
+    - SAUCE: e1000e: Add support for Comet Lake
+
+  * seccomp: add SECCOMP_USER_NOTIF_FLAG_CONTINUE    (LP: #1847744)
+    - SAUCE: seccomp: add SECCOMP_USER_NOTIF_FLAG_CONTINUE
+    - SAUCE: seccomp: test SECCOMP_USER_NOTIF_FLAG_CONTINUE
+
+  * drm/i915: Fix the issue of "azx_get_response timeout" for hdmi audio on ICL
+    platforms (LP: #1847192)
+    - SAUCE: drm/i915: Fix audio power up sequence for gen10+ display
+    - SAUCE: drm/i915: extend audio CDCLK>=2*BCLK constraint to more platforms
+
+  * PM / hibernate: fix potential memory corruption (LP: #1847118)
+    - SAUCE: PM / hibernate: memory_bm_find_bit -- tighten node optimisation
+
+  * [regression] NoNewPrivileges incompatible with Apparmor (LP: #1844186)
+    - SAUCE: apparmor: fix nnp subset test for unconfined
+
+  * overlayfs: allow with shiftfs as underlay (LP: #1846272)
+    - SAUCE: overlayfs: allow with shiftfs as underlay
+
+  * eoan: alsa/sof: Enable SOF_HDA link and codec (LP: #1848490)
+    - [Config] Fix SOF Kconfig options
+
+  * linux won't build when new virtualbox version is present on the archive
+    (LP: #1848788)
+    - [Packaging]: download virtualbox from sources
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations from configs
+    - [Config] updateconfigs after rebase to 5.4-rc5
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 29 Oct 2019 12:01:27 -0500
+
+linux (5.4.0-2.3) eoan; urgency=medium
+
+  * Add installer support for iwlmvm adapters (LP: #1848236)
+    - d-i: Add iwlmvm to nic-modules
+
+  * shiftfs: rework how shiftfs opens files (LP: #1846265)
+    - SAUCE: shiftfs: rework how shiftfs opens files
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.4-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 21 Oct 2019 17:31:26 +0200
+
+linux (5.4.0-1.2) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.4-rc3
+    - [Config] add flexfb, fbtft_device and rio500 to modules.ignore
+    - [Config] amd64: ignore fbtft and all dependent modules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 14 Oct 2019 19:48:52 +0200
+
+linux (5.4.0-0.1) eoan; urgency=medium
+
+  * Enable the Dragonboards out of Eoan/master arm64 kernel (LP: #1846704)
+    - [Packaging] arm64: snapdragon: introduce a snapdragon flavour
+    - [Packaging] arm64: snapdragon: switch kernel format to Image
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8916=y
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8994=y
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8996=y
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8998=y
+    - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_RPMH=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_BAM_DMA=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_HIDMA_MGMT=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_HIDMA=y
+    - [Config] arm64: snapdragon: CONFIG_COMMON_CLK_QCOM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_RPMH=y
+    - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8916=y
+    - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8994=y
+    - [Config] arm64: snapdragon: CONFIG_MSM_MMCC_8996=y
+    - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8998=y
+    - [Config] arm64: snapdragon: CONFIG_HWSPINLOCK_QCOM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_APCS_IPC=y
+    - [Config] arm64: snapdragon: CONFIG_RPMSG_QCOM_GLINK_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_GENI_SE=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_SMEM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_SMD_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_SMP2P=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_SMSM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_QFPROM=y
+    - [Config] arm64: snapdragon: CONFIG_SERIAL_QCOM_GENI=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_TSENS=y
+    - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_SMD_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_SMD_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_RPMSG_QCOM_SMD=y
+    - [Config] arm64: snapdragon: CONFIG_MFD_QCOM_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_SCSI_UFSHCD=y
+    - [Config] arm64: snapdragon: CONFIG_SCSI_UFSHCD_PLATFORM=y
+    - [Config] arm64: snapdragon: CONFIG_SCSI_UFS_HISI=y
+    - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI=y
+    - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI_PLTFM=y
+    - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI_MSM=y
+    - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_SPMI=y
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+    - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_USB_HS=y
+    - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_QMP=y
+    - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_UFS=y
+    - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_USB_HSIC=y
+    - [Config] arm64: snapdragon: CONFIG_USB_CHIPIDEA_OF=y
+    - [Config] arm64: snapdragon: CONFIG_USB_EHCI_HCD_PLATFORM=y
+    - [Config] arm64: snapdragon: CONFIG_EXTCON_USB_GPIO=y
+    - [Config] arm64: snapdragon: CONFIG_REGULATOR_FIXED_VOLTAGE=y
+    - [Config] arm64: snapdragon: CONFIG_LEDS_GPIO=y
+    - [Config] arm64: snapdragon: CONFIG_USB_HSIC_USB3503=y
+    - [Config] arm64: snapdragon: CONFIG_USB_NET_DRIVERS=y
+    - [Config] arm64: snapdragon: CONFIG_USB_OTG=y
+    - [Config] arm64: snapdragon: CONFIG_USB_XHCI_PLATFORM=y
+    - [Config] arm64: snapdragon: CONFIG_USB_OHCI_HCD_PLATFORM=y
+    - [Config] arm64: snapdragon: CONFIG_USB_MUSB_HDRC=y
+    - [Config] arm64: snapdragon: CONFIG_USB_DWC3=y
+    - [Config] arm64: snapdragon: CONFIG_USB_DWC3_PCI=y
+    - [Config] arm64: snapdragon: CONFIG_USB_DWC3_OF_SIMPLE=y
+    - [Config] arm64: snapdragon: CONFIG_USB_DWC3_QCOM=y
+    - [Config] arm64: snapdragon: CONFIG_LEDS_PWM=y
+    - [Config] arm64: snapdragon: CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+    - [Config] arm64: snapdragon: CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_A53PLL=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_APCS_MSM8916=y
+    - [Config] arm64: snapdragon: CONFIG_NLS_ISO8859_1=y
+    - [Config] arm64: snapdragon: CONFIG_USB_USBNET=y
+    - [Config] arm64: snapdragon: CONFIG_CRYPTO_DEV_QCOM_RNG=y
+    - [Config] arm64: snapdragon: CONFIG_POWER_RESET_QCOM_PON=y
+    - [Config] arm64: snapdragon: CONFIG_INPUT_PM8941_PWRKEY=y
+    - [Config] arm64: snapdragon: CONFIG_KEYBOARD_GPIO=y
+    - [Config] arm64: snapdragon: CONFIG_RTC_DRV_PM8XXX=y
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after rebase to 5.4-rc2
+    - SAUCE: (lockdown) Make get_cert_list() not complain about cert lists that
+      aren't present.
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - SAUCE: (lockdown) s390/ipl: lockdown kernel when booted secure
+    - [Config] Enable lockdown under secure boot
+    - SAUCE: import aufs driver
+    - SAUCE: aufs: rwsem owner changed to atmoic_long_t in 5.3
+    - SAUCE: aufs: add "WITH Linux-syscall-note" to SPDX tag of uapi headers
+    - [Config] enable aufs
+    - update dkms package versions
+    - [Config] disable zfs
+    - [Config] disable nvidia dkms build
+    - [Config] disable virtualbox dkms build
+    - [Debian] Generate stub reconstruct for -rc kernels
+    - Revert "UBUNTU: SAUCE: (namespace) block_dev: Forbid unprivileged mounting
+      when device is opened for writing"
+    - Revert "UBUNTU: SAUCE: (namespace) ext4: Add module parameter to enable user
+      namespace mounts"
+    - Revert "UBUNTU: SAUCE: (namespace) ext4: Add support for unprivileged mounts
+      from user namespaces"
+    - Revert "UBUNTU: SAUCE: (namespace) mtd: Check permissions towards mtd block
+      device inode when mounting"
+    - Revert "UBUNTU: SAUCE: (namespace) block_dev: Check permissions towards
+      block device inode when mounting"
+    - Revert "UBUNTU: SAUCE: (namespace) block_dev: Support checking inode
+      permissions in lookup_bdev()"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 11 Oct 2019 16:42:41 -0500
+
+linux (5.4.0-0.0) eoan; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 08 Oct 2019 09:59:00 -0500
+
+linux (5.3.0-17.18) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-17.18 -proposed tracker (LP: #1846641)
+
+  * CVE-2019-17056
+    - nfc: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-17055
+    - mISDN: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-17054
+    - appletalk: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-17053
+    - ieee802154: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-17052
+    - ax25: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-15098
+    - ath6kl: fix a NULL-ptr-deref bug in ath6kl_usb_alloc_urb_from_pipe()
+
+  * xHCI on AMD Stoney Ridge cannot detect USB 2.0 or 1.1 devices.
+    (LP: #1846470)
+    - x86/PCI: Avoid AMD FCH XHCI USB PME# from D0 defect
+
+  * Re-enable linux-libc-dev build on i386 (LP: #1846508)
+    - [Packaging] Build only linux-libc-dev for i386
+    - [Debian] final-checks -- ignore archtictures with no binaries
+
+  * arm64: loop on boot after installing linux-generic-hwe-18.04-edge/bionic-
+    proposed (LP: #1845820)
+    - [Config] Disable CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
+
+  * Revert ESE DASD discard support (LP: #1846219)
+    - SAUCE: Revert "s390/dasd: Add discard support for ESE volumes"
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 03 Oct 2019 16:57:05 -0500
+
+linux (5.3.0-16.17) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-16.17 -proposed tracker (LP: #1846204)
+
+  * zfs fails to build on s390x  with debug symbols enabled (LP: #1846143)
+    - SAUCE: s390: Mark atomic const ops always inline
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 01 Oct 2019 07:46:43 -0500
+
+linux (5.3.0-15.16) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-15.16 -proposed tracker (LP: #1845987)
+
+  * Drop i386 build for 19.10 (LP: #1845714)
+    - [Packaging] Remove x32 arch references from control files
+    - [Debian] final-checks -- Get arch list from debian/control
+
+  * ZFS kernel modules lack debug symbols (LP: #1840704)
+    - [Debian] Fix conditional for setting zfs debug package path
+
+  * Use pyhon3-sphinx instead of python-sphinx for building html docs
+    (LP: #1845808)
+    - [Packaging] Update sphinx build dependencies to python3 packages
+
+  * Kernel panic with 19.10 beta image (LP: #1845454)
+    - efi/tpm: Don't access event->count when it isn't mapped.
+    - efi/tpm: don't traverse an event log with no events
+    - efi/tpm: only set efi_tpm_final_log_size after successful event log parsing
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 30 Sep 2019 11:57:20 -0500
+
+linux (5.3.0-14.15) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-14.15 -proposed tracker (LP: #1845728)
+
+  * Drop i386 build for 19.10 (LP: #1845714)
+    - [Debian] Remove support for producing i386 kernels
+    - [Debian] Don't use CROSS_COMPILE for i386 configs
+
+  * udevadm trigger will fail when trying to add /sys/devices/vio/
+    (LP: #1845572)
+    - SAUCE: powerpc/vio: drop bus_type from parent device
+
+  * Trying to online dasd drive results in invalid input/output from the kernel
+    on z/VM (LP: #1845323)
+    - SAUCE: s390/dasd: Fix error handling during online processing
+
+  * intel-lpss driver conflicts with write-combining MTRR region (LP: #1845584)
+    - SAUCE: mfd: intel-lpss: add quirk for Dell XPS 13 7390 2-in-1
+
+  * Support Hi1620 zip hw accelerator (LP: #1845355)
+    - [Config] Enable HiSilicon QM/ZIP as modules
+    - crypto: hisilicon - add queue management driver for HiSilicon QM module
+    - crypto: hisilicon - add hardware SGL support
+    - crypto: hisilicon - add HiSilicon ZIP accelerator support
+    - crypto: hisilicon - add SRIOV support for ZIP
+    - Documentation: Add debugfs doc for hisi_zip
+    - crypto: hisilicon - add debugfs for ZIP and QM
+    - MAINTAINERS: add maintainer for HiSilicon QM and ZIP controller driver
+    - crypto: hisilicon - fix kbuild warnings
+    - crypto: hisilicon - add dependency for CRYPTO_DEV_HISI_ZIP
+    - crypto: hisilicon - init curr_sgl_dma to fix compile warning
+    - crypto: hisilicon - add missing single_release
+    - crypto: hisilicon - fix error handle in hisi_zip_create_req_q
+    - crypto: hisilicon - Fix warning on printing %p with dma_addr_t
+    - crypto: hisilicon - Fix return value check in hisi_zip_acompress()
+    - crypto: hisilicon - avoid unused function warning
+
+  * SafeSetID LSM should be built but disabled by default (LP: #1845391)
+    - LSM: SafeSetID: Stop releasing uninitialized ruleset
+    - [Config] Build SafeSetID LSM but don't enable it by default
+
+  * CONFIG_LSM should not specify loadpin since it is not built (LP: #1845383)
+    - [Config] loadpin shouldn't be in CONFIG_LSM
+
+  * Add new pci-id's for CML-S, ICL (LP: #1845317)
+    - drm/i915/icl: Add missing device ID
+    - drm/i915/cml: Add Missing PCI IDs
+
+  * Thunderbolt support for ICL (LP: #1844680)
+    - thunderbolt: Correct path indices for PCIe tunnel
+    - thunderbolt: Move NVM upgrade support flag to struct icm
+    - thunderbolt: Use 32-bit writes when writing ring producer/consumer
+    - thunderbolt: Do not fail adding switch if some port is not implemented
+    - thunderbolt: Hide switch attributes that are not set
+    - thunderbolt: Expose active parts of NVM even if upgrade is not supported
+    - thunderbolt: Add support for Intel Ice Lake
+    - ACPI / property: Add two new Thunderbolt property GUIDs to the list
+
+  * Ubuntu 19.10 -  Additional PCI patch and fix (LP: #1844668)
+    - s390/pci: fix MSI message data
+
+  * Enhanced Hardware Support - Finalize Naming (LP: #1842774)
+    - s390: add support for IBM z15 machines
+    - [Config] CONFIG_MARCH_Z15=n, CONFIG_TUNE_Z15=n
+
+  * Eoan update: v5.3.1 upstream stable release (LP: #1845642)
+    - USB: usbcore: Fix slab-out-of-bounds bug during device reset
+    - media: tm6000: double free if usb disconnect while streaming
+    - phy: renesas: rcar-gen3-usb2: Disable clearing VBUS in over-current
+    - ip6_gre: fix a dst leak in ip6erspan_tunnel_xmit
+    - net/sched: fix race between deactivation and dequeue for NOLOCK qdisc
+    - net_sched: let qdisc_put() accept NULL pointer
+    - udp: correct reuseport selection with connected sockets
+    - xen-netfront: do not assume sk_buff_head list is empty in error handling
+    - net: dsa: Fix load order between DSA drivers and taggers
+    - net: stmmac: Hold rtnl lock in suspend/resume callbacks
+    - KVM: coalesced_mmio: add bounds checking
+    - Documentation: sphinx: Add missing comma to list of strings
+    - firmware: google: check if size is valid when decoding VPD data
+    - serial: sprd: correct the wrong sequence of arguments
+    - tty/serial: atmel: reschedule TX after RX was started
+    - nl80211: Fix possible Spectre-v1 for CQM RSSI thresholds
+    - Revert "arm64: Remove unnecessary ISBs from set_{pte,pmd,pud}"
+    - ovl: fix regression caused by overlapping layers detection
+    - phy: qcom-qmp: Correct ready status, again
+    - floppy: fix usercopy direction
+    - media: technisat-usb2: break out of loop at end of buffer
+    - Linux 5.3.1
+
+  * ZFS kernel modules lack debug symbols (LP: #1840704)
+    - [Debian]: Remove hardcoded $(pkgdir) in debug symbols handling
+    - [Debian]: Handle debug symbols for modules in extras too
+    - [Debian]: Check/link modules with debug symbols after DKMS modules
+    - [Debian]: Warn about modules without debug symbols
+    - [Debian]: dkms-build: new parameter for debug package directory
+    - [Debian]: dkms-build: zfs: support for debug symbols
+    - [Debian]: dkms-build: Avoid executing post-processor scripts twice
+    - [Debian]: dkms-build: Move zfs special-casing into configure script
+
+  * /proc/self/maps paths missing on live session (was vlc won't start; eoan
+    19.10 & bionic 18.04 ubuntu/lubuntu/kubuntu/xubuntu/ubuntu-mate dailies)
+    (LP: #1842382)
+    - SAUCE: Revert "UBUNTU: SAUCE: shiftfs: enable overlayfs on shiftfs"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 27 Sep 2019 16:08:06 -0500
+
+linux (5.3.0-13.14) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-13.14 -proposed tracker (LP: #1845105)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Remove binutils-dev build dependency
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 23 Sep 2019 19:26:43 -0500
+
+linux (5.3.0-12.13) eoan; urgency=medium
+
+  * Change kernel compression method to improve boot speed (LP: #1840934)
+    - [Packaging] Add lz4 build dependency for s390x
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Remove spl and zfs source
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 17 Sep 2019 13:36:26 +0200
+
+linux (5.3.0-11.12) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-11.12 -proposed tracker (LP: #1844144)
+
+  *  Suspend to RAM(S3) does not wake up for latest megaraid and mpt3sas
+    adapters(SAS3.5 onwards) (LP: #1838751)
+    - PCI: Restore Resizable BAR size bits correctly for 1MB BARs
+
+  * s390/setup: Actually init kernel lock down (LP: #1843961)
+    - SAUCE: (lockdown) s390/setup: Actually init kernel lock down
+
+  * cherrypick has_sipl fix (LP: #1843960)
+    - SAUCE: s390/sclp: Fix bit checked for has_sipl
+
+  * Change kernel compression method to improve boot speed (LP: #1840934)
+    - [Config]: Switch kernel compression from LZO to LZ4 on s390x
+
+  * Installation fails on eoan/PowerVM : missing /dev/nvram (LP: #1837726)
+    - [Config] CONFIG_NVRAM=y for ppc64el
+
+  * Miscellaneous Ubuntu changes
+    - [Config]: remove nvram from ppc64el modules ABI
+    - [Config] Update annotations for recent config changes
+    - SAUCE: sched: Add __ASSEMBLY__ guards around struct clone_args
+    - SAUCE: i2c: qcom-geni: Disable DMA processing on the Lenovo Yoga C630
+    - SAUCE: arm64: dts: qcom: Add Lenovo Yoga C630
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 16 Sep 2019 16:18:27 +0200
+
+linux (5.3.0-10.11) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-10.11 -proposed tracker (LP: #1843232)
+
+  * No sound inputs from the external microphone and headset on a Dell machine
+    (LP: #1842265)
+    - SAUCE: ALSA: hda - Expand pin_match function to match upcoming new tbls
+    - SAUCE: ALSA: hda - Define a fallback_pin_fixup_tbl for alc269 family
+
+  * Horizontal corrupted line at top of screen caused by framebuffer compression
+    (LP: #1840236)
+    - SAUCE: drm/i915/fbc: disable framebuffer compression on IceLake
+
+  * Add bpftool to linux-tools-common (LP: #1774815)
+    - [Debian] package bpftool in linux-tools-common
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc8
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 09 Sep 2019 10:00:41 +0200
+
+linux (5.3.0-9.10) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-9.10 -proposed tracker (LP: #1842393)
+
+  * shiftfs: mark kmem_cache as reclaimable (LP: #1842059)
+    - SAUCE: shiftfs: mark slab objects SLAB_RECLAIM_ACCOUNT
+
+  * shiftfs: drop entries from cache on unlink (LP: #1841977)
+    - SAUCE: shiftfs: fix buggy unlink logic
+
+  * Fix touchpad IRQ storm after S3 (LP: #1841396)
+    - pinctrl: intel: remap the pin number to gpio offset for irq enabled pin
+
+  * Please include DTBs for arm64 laptops (LP: #1842050)
+    - arm64: dts: qcom: Add Lenovo Miix 630
+    - arm64: dts: qcom: Add HP Envy x2
+    - arm64: dts: qcom: Add Asus NovaGo TP370QL
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: import aufs driver
+    - [Packaging]: ignore vbox modules when vbox is disabled
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 03 Sep 2019 10:27:33 +0200
+
+linux (5.3.0-8.9) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+
+  * Change kernel compression method to improve boot speed (LP: #1840934)
+    - [Config] change kernel compression method to improve boot speed
+    - [Packaging] add build dependencies for compression algorithms
+
+  * realtek r8822be kernel module fails after update to linux kernel-headers
+    5.0.0-21 (LP: #1838133)
+    - rtw88: Fix misuse of GENMASK macro
+    - rtw88: pci: Rearrange the memory usage for skb in RX ISR
+    - rtw88: pci: Use DMA sync instead of remapping in RX ISR
+    - rtw88: debug: dump tx power indexes in use
+    - rtw88: use txpwr_lmt_cfg_pair struct, not arrays
+    - rtw88: pci: remove set but not used variable 'ip_sel'
+    - rtw88: allow c2h operation in irq context
+    - rtw88: enclose c2h cmd handle with mutex
+    - rtw88: add BT co-existence support
+    - SAUCE: rtw88: pci: enable MSI interrupt
+
+  * VIMC module not available (CONFIG_VIDEO_VIMC not set) (LP: #1831482)
+    - [Config] Enable VIMC module
+
+  * Goodix touchpad may drop first input event (LP: #1840075)
+    - Revert "UBUNTU: SAUCE: i2c: designware: add G3 3590 into i2c quirk"
+    - Revert "UBUNTU: SAUCE: i2c: designware: add Inpiron 7591 into i2c quirk"
+    - Revert "UBUNTU: SAUCE: i2c: designware: add Inpiron/Vostro 7590 into i2c
+      quirk"
+    - Revert "UBUNTU: SAUCE: i2c: designware: Add disable runtime pm quirk"
+    - mfd: intel-lpss: Remove D3cold delay
+
+  * Include Sunix serial/parallel driver (LP: #1826716)
+    - serial: 8250_pci: Add support for Sunix serial boards
+    - parport: parport_serial: Add support for Sunix Multi I/O boards
+
+  * enable lockdown on s390x when Secure IPL is performed (LP: #1839622)
+    - SAUCE: (lockdown) s390/ipl: lockdown kernel when booted secure
+    - Ubuntu: [Config] Enable CONFIG_LOCK_DOWN_KERNEL on s390x.
+
+  * UBUNTU: SAUCE: shiftfs: pass correct point down (LP: #1837231)
+    - SAUCE: shiftfs: pass correct point down
+
+  * shiftfs: add O_DIRECT support (LP: #1837223)
+    - SAUCE: shiftfs: add O_DIRECT support
+
+  * Miscellaneous Ubuntu changes
+    - [Config] enable secureboot signing on s390x
+    - [Config] CONFIG_TEST_BLACKHOLE_DEV=m
+    - SAUCE: selftests: fib_tests: assign address to dummy1 for rp_filter tests
+    - [Debian] disable dkms builds for autopktest rebuilds
+    - update dkms package versions
+    - [Config] updateconfigs after v5.3-rc6 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 26 Aug 2019 10:09:42 +0200
+
+linux (5.3.0-7.8) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after v5.3-rc5 rebase
+    - remove missing module after updateconfigs
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 19 Aug 2019 15:31:24 +0200
+
+linux (5.3.0-6.7) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/bpf: prevent headers to be compiled as C code
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 14 Aug 2019 13:25:01 -0500
+
+linux (5.3.0-5.6) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] enable zfs build
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 13 Aug 2019 09:16:06 -0500
+
+linux (5.3.0-4.5) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+    - [Packaging] update helper scripts
+
+  * bcache: bch_allocator_thread(): hung task timeout (LP: #1784665) // Tight
+    timeout for bcache removal causes spurious failures (LP: #1796292)
+    - SAUCE: bcache: fix deadlock in bcache_allocator
+
+  * shiftfs: allow overlayfs (LP: #1838677)
+    - SAUCE: shiftfs: enable overlayfs on shiftfs
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "kbuild: modpost: do not parse unnecessary rules for vmlinux
+      modpost"
+    - update dkms package versions
+    - enable nvidia dkms build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 12 Aug 2019 10:41:27 -0500
+
+linux (5.3.0-3.4) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - SAUCE: aufs: add "WITH Linux-syscall-note" to SPDX tag of uapi headers
+    - [Config] add mux-* to modules.ignore
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 05 Aug 2019 18:17:09 +0200
+
+linux (5.3.0-2.3) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] add build dependincy on fontconfig
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 29 Jul 2019 12:18:46 -0400
+
+linux (5.3.0-1.2) eoan; urgency=medium
+
+  * System does not auto detect disconnection of external monitor (LP: #1835001)
+    - SAUCE: drm/i915: Add support for retrying hotplug
+    - SAUCE: drm/i915: Enable hotplug retry
+
+  * Please enable CONFIG_SCSI_UFS_QCOM as a module on arm64 (LP: #1837332)
+    - [Config] Enable CONFIG_SCSI_UFS_QCOM as a module on arm64.
+
+  * Add arm64 CONFIG_ARCH_MESON=y and related configs Edit (LP: #1820530)
+    - [Config] enable ARCH_MESON
+    - remove missing module
+    - [Config] update annotations after enabling ARCH_MESON for arm64
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: KVM: PPC: comment implicit fallthrough
+    - update dkms package versions
+    - [Config] enable vbox dkms build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 28 Jul 2019 23:10:16 -0400
+
+linux (5.3.0-0.1) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and
+      KEXEC_SIG_FORCE
+    - SAUCE: (efi-lockdown) kexec_file: Restrict at runtime if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) lockdown: Print current->comm in restriction messages
+    - SAUCE: (efi-lockdown) kexec: Allow kexec_file() with appropriate IMA policy
+      when locked down
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation
+      defined
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) KEYS: Make use of platform keyring for module
+      signature verify
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) furter KEXEC_VERIFY_SIG -> KEXEC_SIG updates
+    - SAUCE: (efi-lockdown) arm64: add kernel config option to lock down when in
+      Secure Boot mode
+    - SAUCE: import aufs driver
+    - SAUCE: aufs: rwsem owner changed to atmoic_long_t in 5.3
+    - [Config] disable zfs dkms build
+    - [Config] disable nvidia dkms build
+    - [Config] disable vbox dkms build
+    - SAUCE: perf diff: use llabs for s64 vaules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 23 Jul 2019 21:45:44 -0500
+
+linux (5.3.0-0.0) eoan; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 22 Jul 2019 10:19:04 -0500
+
+linux (5.2.0-9.10) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * input/mouse: alps trackpoint-only device doesn't work (LP: #1836752)
+    - SAUCE: Input: alps - don't handle ALPS cs19 trackpoint-only device
+    - SAUCE: Input: alps - fix a mismatch between a condition check and its
+      comment
+
+  * System does not auto detect disconnection of external monitor (LP: #1835001)
+    - SAUCE: drm/i915: Add support for retrying hotplug
+    - SAUCE: drm/i915: Enable hotplug retry
+
+  * alsa/hdmi: add icelake hdmi audio support for a Dell machine (LP: #1836916)
+    - SAUCE: ALSA: hda/hdmi - Remove duplicated define
+    - SAUCE: ALSA: hda/hdmi - Fix i915 reverse port/pin mapping
+
+  * First click on Goodix touchpad doesn't be recognized after runtime suspended
+    (LP: #1836836)
+    - SAUCE: i2c: designware: add G3 3590 into i2c quirk
+
+  * ixgbe{vf} - Physical Function gets IRQ when VF checks link state
+    (LP: #1836760)
+    - ixgbevf: Use cached link state instead of re-reading the value for ethtool
+
+  * Doing multiple squashfs (and other loop?) mounts in parallel breaks
+    (LP: #1836914)
+    - SAUCE: Revert "loop: Don't change loop device under exclusive opener"
+
+  * hibmc-drm Causes Unreadable Display for Huawei amd64 Servers (LP: #1762940)
+    - SAUCE: Make CONFIG_DRM_HISI_HIBMC depend on ARM64
+    - [Config] Set CONFIG_DRM_HISI_HIBMC to arm64 only
+    - [Config] add hibmc-drm to modules.ignore
+
+  * hda/realtek: can't detect external mic on a Dell machine (LP: #1836755)
+    - ALSA: hda/realtek: apply ALC891 headset fixup to one Dell machine
+
+  * Enable Armada SOCs and MVPP2 NIC driver for disco/generic arm64
+    (LP: #1835054)
+    - [Config] Enable Armada SOCs and MVPP2 NIC driver for disco/generic arm64
+
+  * Unhide Nvidia HDA audio controller (LP: #1836308)
+    - PCI: Enable NVIDIA HDA controllers
+
+  * Intel ethernet I219 may wrongly detect connection speed as 10Mbps
+    (LP: #1836177)
+    - e1000e: Make watchdog use delayed work
+
+  * Sometimes touchpad(goodix) can't use tap function (LP: #1836020)
+    - SAUCE: i2c: designware: add Inpiron/Vostro 7590 into i2c quirk
+    - SAUCE: i2c: designware: add Inpiron 7591 into i2c quirk
+
+  * Intel ethernet I219 has slow RX speed (LP: #1836152)
+    - e1000e: add workaround for possible stalled packet
+    - e1000e: disable force K1-off feature
+
+  * bcache: risk of data loss on I/O errors in backing or caching devices
+    (LP: #1829563)
+    - Revert "bcache: set CACHE_SET_IO_DISABLE in bch_cached_dev_error()"
+
+  * bnx2x driver causes 100% CPU load (LP: #1832082)
+    - bnx2x: Prevent ptp_task to be rescheduled indefinitely
+
+  * fcf-protection=none patch with new version
+    - Revert "UBUNTU: SAUCE: kbuild: add -fcf-protection=none to retpoline flags"
+    - SAUCE: kbuild: add -fcf-protection=none when using retpoline flags
+
+  * CVE-2019-12614
+    - powerpc/pseries/dlpar: Fix a missing check in dlpar_parse_cc_property()
+
+  * Eoan update: v5.2.1 upstream stable release (LP: #1836622)
+    - crypto: lrw - use correct alignmask
+    - crypto: talitos - rename alternative AEAD algos.
+    - fscrypt: don't set policy for a dead directory
+    - udf: Fix incorrect final NOT_ALLOCATED (hole) extent length
+    - media: stv0297: fix frequency range limit
+    - ALSA: usb-audio: Fix parse of UAC2 Extension Units
+    - ALSA: hda/realtek - Headphone Mic can't record after S3
+    - tpm: Actually fail on TPM errors during "get random"
+    - tpm: Fix TPM 1.2 Shutdown sequence to prevent future TPM operations
+    - block: fix .bi_size overflow
+    - block, bfq: NULL out the bic when it's no longer valid
+    - perf intel-pt: Fix itrace defaults for perf script
+    - perf auxtrace: Fix itrace defaults for perf script
+    - perf intel-pt: Fix itrace defaults for perf script intel-pt documentation
+    - perf pmu: Fix uncore PMU alias list for ARM64
+    - perf thread-stack: Fix thread stack return from kernel for kernel-only case
+    - perf header: Assign proper ff->ph in perf_event__synthesize_features()
+    - x86/ptrace: Fix possible spectre-v1 in ptrace_get_debugreg()
+    - x86/tls: Fix possible spectre-v1 in do_get_thread_area()
+    - Documentation: Add section about CPU vulnerabilities for Spectre
+    - Documentation/admin: Remove the vsyscall=native documentation
+    - mwifiex: Don't abort on small, spec-compliant vendor IEs
+    - USB: serial: ftdi_sio: add ID for isodebug v1
+    - USB: serial: option: add support for GosunCn ME3630 RNDIS mode
+    - Revert "serial: 8250: Don't service RX FIFO if interrupts are disabled"
+    - p54usb: Fix race between disconnect and firmware loading
+    - usb: gadget: f_fs: data_len used before properly set
+    - usb: gadget: ether: Fix race between gether_disconnect and rx_submit
+    - usb: dwc2: use a longer AHB idle timeout in dwc2_core_reset()
+    - usb: renesas_usbhs: add a workaround for a race condition of workqueue
+    - drivers/usb/typec/tps6598x.c: fix portinfo width
+    - drivers/usb/typec/tps6598x.c: fix 4CC cmd write
+    - p54: fix crash during initialization
+    - staging: comedi: dt282x: fix a null pointer deref on interrupt
+    - staging: wilc1000: fix error path cleanup in wilc_wlan_initialize()
+    - staging: bcm2835-camera: Restore return behavior of ctrl_set_bitrate()
+    - staging: comedi: amplc_pci230: fix null pointer deref on interrupt
+    - staging: mt7621-pci: fix PCIE_FTS_NUM_LO macro
+    - HID: Add another Primax PIXART OEM mouse quirk
+    - lkdtm: support llvm-objcopy
+    - binder: fix memory leak in error path
+    - binder: return errors from buffer copy functions
+    - iio: adc: stm32-adc: add missing vdda-supply
+    - coresight: Potential uninitialized variable in probe()
+    - coresight: etb10: Do not call smp_processor_id from preemptible
+    - coresight: tmc-etr: Do not call smp_processor_id() from preemptible
+    - coresight: tmc-etr: alloc_perf_buf: Do not call smp_processor_id from
+      preemptible
+    - coresight: tmc-etf: Do not call smp_processor_id from preemptible
+    - carl9170: fix misuse of device driver API
+    - Revert "x86/build: Move _etext to actual end of .text"
+    - VMCI: Fix integer overflow in VMCI handle arrays
+    - staging: vchiq_2835_arm: revert "quit using custom down_interruptible()"
+    - staging: vchiq: make wait events interruptible
+    - staging: vchiq: revert "switch to wait_for_completion_killable"
+    - staging: fsl-dpaa2/ethsw: fix memory leak of switchdev_work
+    - staging: bcm2835-camera: Replace spinlock protecting context_map with mutex
+    - staging: bcm2835-camera: Ensure all buffers are returned on disable
+    - staging: bcm2835-camera: Remove check of the number of buffers supplied
+    - staging: bcm2835-camera: Handle empty EOS buffers whilst streaming
+    - staging: rtl8712: reduce stack usage, again
+    - Linux 5.2.1
+    - [Config] updateconfigs after v5.2.1 stable update
+
+  * fcf-protection=none patch with upstream version
+    - Revert "UBUNTU: SAUCE: add -fcf-protection=none to retpoline flags"
+    - SAUCE: kbuild: add -fcf-protection=none to retpoline flags
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/ftrace: avoid failure when trying to probe a notrace
+      function
+    - SAUCE: selftests/powerpc/ptrace: fix build failure
+    - update dkms package versions
+    - [Packaging] add zlua to zfs-modules.ignore
+    - update dkms package versions
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 19 Jul 2019 15:04:45 -0500
+
+linux (5.2.0-8.9) eoan; urgency=medium
+
+  * linux: 5.2.0-8.9 -proposed tracker (LP: #1835700)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] replace zfs and spl build with zfs 0.8.1-1ubuntu1
+    - SAUCE: test_bpf: remove expected fail for Ctx heavy transformations test on
+      s390
+    - SAUCE: add -fcf-protection=none to retpoline flags
+    - SAUCE: usbip: ensure strings copied using strncpy are null-terminated
+    - SAUCE: usbip: add -Wno-address-of-packed-member to EXTRA_CFLAGS
+    - SAUCE: perf jvmti: ensure strncpy result is null-terminated
+    - update dkms package versions
+    - add removed zfs modules to modules.ignore
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 08 Jul 2019 07:13:41 -0500
+
+linux (5.2.0-7.8) eoan; urgency=medium
+
+  * Kernel panic upon resetting ixgbe SR-IOV VFIO virtual function using 5.0
+    kernel (LP: #1829652)
+    - SAUCE: ixgbe: Avoid NULL pointer dereference with VF on non-IPsec hw
+
+  * Hi1620 driver updates from upstream 5.2 merge window (LP: #1830815)
+    - net: hns3: initialize CPU reverse mapping
+    - net: hns3: refine the flow director handle
+    - net: hns3: add aRFS support for PF
+    - net: hns3: fix for FEC configuration
+    - RDMA/hns: Remove unnecessary print message in aeq
+    - RDMA/hns: Update CQE specifications
+    - RDMA/hns: Move spin_lock_irqsave to the correct place
+    - RDMA/hns: Remove jiffies operation in disable interrupt context
+    - RDMA/hns: Replace magic numbers with #defines
+    - net: hns3: fix compile warning without CONFIG_RFS_ACCEL
+    - net: hns3: fix for HNS3_RXD_GRO_SIZE_M macro
+    - net: hns3: add support for dump firmware statistics by debugfs
+    - net: hns3: use HCLGE_STATE_NIC_REGISTERED to indicate PF NIC client has
+      registered
+    - net: hns3: use HCLGE_STATE_ROCE_REGISTERED to indicate PF ROCE client has
+      registered
+    - net: hns3: use HCLGEVF_STATE_NIC_REGISTERED to indicate VF NIC client has
+      registered
+    - net: hns3: modify hclge_init_client_instance()
+    - net: hns3: modify hclgevf_init_client_instance()
+    - net: hns3: add handshake with hardware while doing reset
+    - net: hns3: stop schedule reset service while unloading driver
+    - net: hns3: adjust hns3_uninit_phy()'s location in the hns3_client_uninit()
+    - net: hns3: fix a memory leak issue for hclge_map_unmap_ring_to_vf_vector
+    - RDMA/hns: Bugfix for posting multiple srq work request
+    - net: hns3: remove redundant core reset
+    - net: hns3: don't configure new VLAN ID into VF VLAN table when it's full
+    - net: hns3: fix VLAN filter restore issue after reset
+    - net: hns3: set the port shaper according to MAC speed
+    - net: hns3: add a check to pointer in error_detected and slot_reset
+    - net: hns3: set ops to null when unregister ad_dev
+    - net: hns3: add handling of two bits in MAC tunnel interrupts
+    - net: hns3: remove setting bit of reset_requests when handling mac tunnel
+      interrupts
+    - net: hns3: add opcode about query and clear RAS & MSI-X to special opcode
+    - net: hns3: delay and separate enabling of NIC and ROCE HW errors
+    - RDMA/hns: fix inverted logic of readl read and shift
+    - RDMA/hns: Bugfix for filling the sge of srq
+    - net: hns3: log detail error info of ROCEE ECC and AXI errors
+    - net: hns3: fix wrong size of mailbox responding data
+    - net: hns3: make HW GRO handling compliant with SW GRO
+    - net: hns3: replace numa_node_id with numa_mem_id for buffer reusing
+    - net: hns3: refactor hns3_get_new_int_gl function
+    - net: hns3: trigger VF reset if a VF has an over_8bd_nfe_err
+    - net: hns3: delete the redundant user NIC codes
+    - net: hns3: small changes for magic numbers
+    - net: hns3: use macros instead of magic numbers
+    - net: hns3: refactor PF/VF RSS hash key configuration
+    - net: hns3: some modifications to simplify and optimize code
+    - net: hns3: fix some coding style issues
+    - net: hns3: delay setting of reset level for hw errors until slot_reset is
+      called
+    - net: hns3: fix avoid unnecessary resetting for the H/W errors which do not
+      require reset
+    - net: hns3: process H/W errors occurred before HNS dev initialization
+    - net: hns3: add recovery for the H/W errors occurred before the HNS dev
+      initialization
+    - net: hns3: some changes of MSI-X bits in PPU(RCB)
+    - net: hns3: extract handling of mpf/pf msi-x errors into functions
+    - net: hns3: clear restting state when initializing HW device
+    - net: hns3: free irq when exit from abnormal branch
+    - net: hns3: fix for dereferencing before null checking
+    - net: hns3: fix for skb leak when doing selftest
+    - net: hns3: delay ring buffer clearing during reset
+    - net: hns3: some variable modification
+    - net: hns3: fix dereference of ae_dev before it is null checked
+    - scsi: hisi_sas: Delete PHY timers when rmmod or probe failed
+    - scsi: hisi_sas: Fix the issue of argument mismatch of printing ecc errors
+    - scsi: hisi_sas: Reduce HISI_SAS_SGE_PAGE_CNT in size
+    - scsi: hisi_sas: Change the type of some numbers to unsigned
+    - scsi: hisi_sas: Ignore the error code between phy down to phy up
+    - scsi: hisi_sas: Disable stash for v3 hw
+    - net: hns3: Add missing newline at end of file
+    - RDMa/hns: Don't stuck in endless timeout loop
+
+  * Sometimes touchpad automatically trigger double click (LP: #1833484)
+    - SAUCE: i2c: designware: Add disable runtime pm quirk
+
+  * Add pointstick support on HP ZBook 17 G5 (LP: #1833387)
+    - Revert "HID: multitouch: Support ALPS PTP stick with pid 0x120A"
+
+  * depmod may prefer unsigned l-r-m nvidia modules to signed modules
+    (LP: #1834479)
+    - [Packaging] dkms-build--nvidia-N -- clean up unsigned ko files
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/powerpc: disable signal_fuzzer test
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 01 Jul 2019 07:22:18 -0500
+
+linux (5.2.0-6.7) eoan; urgency=medium
+
+  * hinic: fix oops due to race in set_rx_mode (LP: #1832048)
+    - hinic: fix a bug in set rx mode
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.2-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 23 Jun 2019 23:36:11 -0500
+
+linux (5.2.0-5.6) eoan; urgency=medium
+
+  * QCA9377 isn't being recognized sometimes (LP: #1757218)
+    - SAUCE: USB: Disable USB2 LPM at shutdown
+
+  * shiftfs: allow changing ro/rw for subvolumes (LP: #1832316)
+    - SAUCE: shiftfs: allow changing ro/rw for subvolumes
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Packaging] replace nvidia-418 dkms build with nvidia-430
+    - SAUCE: import aufs driver
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 17 Jun 2019 15:04:12 -0500
+
+linux (5.2.0-4.5) eoan; urgency=medium
+
+  * arm64: cma_alloc errors at boot (LP: #1823753)
+    - [Config] Bump CMA_SIZE_MBYTES to 32 on arm64
+    - dma-contiguous: add dma_{alloc,free}_contiguous() helpers
+    - dma-contiguous: use fallback alloc_pages for single pages
+    - dma-contiguous: fix !CONFIG_DMA_CMA version of dma_{alloc,
+      free}_contiguous()
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_MFD_TQMX86=n for s390x
+    - [Config] CONFIG_GPIO_AMD_FCH=n for s390x
+    - [Config] CONFIG_BACKLIGHT_CLASS_DEVICE=n on s390x
+    - [Config] CONFIG_LCD_CLASS_DEVICE=n for s390x
+    - [Config] CONFIG_DRM_ETNAVIV=m for armhf generic-lpae
+    - [Config] CONFIG_DRM_NOUVEAU_SVM=n
+    - [Config] CONFIG_HWMON=n for s390x
+    - [Config] CONFIG_NEW_LEDS=n for s390x
+    - [Config] CONFIG_MTD_NAND_OMAP2=y for armhf
+    - [Config] CONFIG_VOP_BUS=n for non-amd64 arches
+    - [Config] CONFIG_TI_CPSW_PHY_SEL=n
+    - [Config] CONFIG_INTERCONNECT=n for s390x
+    - [Config] CONFIG_SCSI_GDTH=n for s390x
+    - [Config] CONFIG_PACKING=n for s390x
+    - [Config] CONFIG_ARCH_MILBEAUT=y for armhf
+    - [Config] update annotations following config review
+    - update dkms package versions
+    - [Config] enable nvidia dkms build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 10 Jun 2019 07:00:11 -0500
+
+linux (5.2.0-3.4) eoan; urgency=medium
+
+  * [18.04/18.10] File libperf-jvmti.so is missing in linux-tools-common deb on
+    Ubuntu (LP: #1761379)
+    - [Packaging] Support building libperf-jvmti.so
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "bpf, selftest: test global data/bss/rodata sections"
+    - update dkms package versions
+    - [Config] enable zfs
+    - rebase to v5.2-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 02 Jun 2019 21:48:50 -0500
+
+linux (5.2.0-2.3) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: perf arm64: Fix mksyscalltbl when system kernel headers are ahead of
+      the kernel
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 May 2019 07:12:39 -0500
+
+linux (5.2.0-1.2) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_INTEGRITY_PLATFORM_KEYRING=y
+    - update dkms package versions
+    - [Config] enable vbox dkms build
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 May 2019 21:11:27 -0500
+
+linux (5.2.0-0.1) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: import aufs driver
+    - [Packaging] disable ZFS
+    - [Packaging] disable nvidia
+    - [Packaging] dkms-build -- expand paths searched for make.log files
+    - add virtualbox-guest-dkms dkms package build
+    - enable vbox dkms build for amd64 and i386
+    - update dkms package versions
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and
+      KEXEC_SIG_FORCE
+    - SAUCE: (efi-lockdown) kexec_file: Restrict at runtime if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) lockdown: Print current->comm in restriction messages
+    - SAUCE: (efi-lockdown) kexec: Allow kexec_file() with appropriate IMA policy
+      when locked down
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) KEYS: Make use of platform keyring for module
+      signature verify
+    - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation
+      defined
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) furter KEXEC_VERIFY_SIG -> KEXEC_SIG updates
+    - SAUCE: (efi-lockdown) arm64: add kernel config option to lock down when in
+      Secure Boot mode
+    - update dkms package versions
+    - [Config] disable vbox build
+    - SAUCE: s390: mark __cpacf_check_opcode() and cpacf_query_func() as
+      __always_inline
+    - SAUCE: IB/mlx5: use size_t instead of u64 when dividing
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 21 May 2019 11:18:43 -0500
+
+linux (5.2.0-0.0) eoan; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 21 May 2019 07:34:43 -0500
+
+linux (5.1.0-2.2) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+
+  * Eoan update: v5.1.2 upstream stable release (LP: #1829050)
+    - x86/msr-index: Cleanup bit defines
+    - x86/speculation: Consolidate CPU whitelists
+    - x86/speculation/mds: Add basic bug infrastructure for MDS
+    - x86/speculation/mds: Add BUG_MSBDS_ONLY
+    - x86/kvm: Expose X86_FEATURE_MD_CLEAR to guests
+    - x86/speculation/mds: Add mds_clear_cpu_buffers()
+    - x86/speculation/mds: Clear CPU buffers on exit to user
+    - x86/kvm/vmx: Add MDS protection when L1D Flush is not active
+    - x86/speculation/mds: Conditionally clear CPU buffers on idle entry
+    - x86/speculation/mds: Add mitigation control for MDS
+    - x86/speculation/mds: Add sysfs reporting for MDS
+    - x86/speculation/mds: Add mitigation mode VMWERV
+    - Documentation: Move L1TF to separate directory
+    - Documentation: Add MDS vulnerability documentation
+    - x86/speculation/mds: Add mds=full,nosmt cmdline option
+    - x86/speculation: Move arch_smt_update() call to after mitigation decisions
+    - x86/speculation/mds: Add SMT warning message
+    - x86/speculation/mds: Fix comment
+    - x86/speculation/mds: Print SMT vulnerable on MSBDS with mitigations off
+    - cpu/speculation: Add 'mitigations=' cmdline option
+    - x86/speculation: Support 'mitigations=' cmdline option
+    - powerpc/speculation: Support 'mitigations=' cmdline option
+    - s390/speculation: Support 'mitigations=' cmdline option
+    - x86/speculation/mds: Add 'mitigations=' support for MDS
+    - x86/mds: Add MDSUM variant to the MDS documentation
+    - Documentation: Correct the possible MDS sysfs values
+    - x86/speculation/mds: Fix documentation typo
+    - Linux 5.1.2
+
+  * Eoan update: v5.1.1 upstream stable release (LP: #1829046)
+    - Drivers: hv: vmbus: Remove the undesired put_cpu_ptr() in hv_synic_cleanup()
+    - ubsan: Fix nasty -Wbuiltin-declaration-mismatch GCC-9 warnings
+    - staging: greybus: power_supply: fix prop-descriptor request size
+    - staging: wilc1000: Avoid GFP_KERNEL allocation from atomic context.
+    - staging: most: cdev: fix chrdev_region leak in mod_exit
+    - staging: most: sound: pass correct device when creating a sound card
+    - usb: dwc3: Allow building USB_DWC3_QCOM without EXTCON
+    - usb: dwc3: Fix default lpm_nyet_threshold value
+    - USB: serial: f81232: fix interrupt worker not stop
+    - USB: cdc-acm: fix unthrottle races
+    - usb-storage: Set virt_boundary_mask to avoid SG overflows
+    - genirq: Prevent use-after-free and work list corruption
+    - intel_th: pci: Add Comet Lake support
+    - iio: adc: qcom-spmi-adc5: Fix of-based module autoloading
+    - cpufreq: armada-37xx: fix frequency calculation for opp
+    - ACPI / LPSS: Use acpi_lpss_* instead of acpi_subsys_* functions for
+      hibernate
+    - soc: sunxi: Fix missing dependency on REGMAP_MMIO
+    - scsi: lpfc: change snprintf to scnprintf for possible overflow
+    - scsi: qla2xxx: Fix incorrect region-size setting in optrom SYSFS routines
+    - scsi: qla2xxx: Set remote port devloss timeout to 0
+    - scsi: qla2xxx: Fix device staying in blocked state
+    - Bluetooth: hidp: fix buffer overflow
+    - Bluetooth: Align minimum encryption key size for LE and BR/EDR connections
+    - Bluetooth: Fix not initializing L2CAP tx_credits
+    - Bluetooth: hci_bcm: Fix empty regulator supplies for Intel Macs
+    - UAS: fix alignment of scatter/gather segments
+    - ASoC: Intel: avoid Oops if DMA setup fails
+    - i3c: Fix a shift wrap bug in i3c_bus_set_addr_slot_status()
+    - locking/futex: Allow low-level atomic operations to return -EAGAIN
+    - arm64: futex: Bound number of LDXR/STXR loops in FUTEX_WAKE_OP
+    - Linux 5.1.1
+
+  * shiftfs: lock security sensitive superblock flags (LP: #1827122)
+    - SAUCE: shiftfs: lock down certain superblock flags
+
+  * Please package libbpf (which is done out of the kernel src) in Debian [for
+    19.10] (LP: #1826410)
+    - SAUCE: tools -- fix add ability to disable libbfd
+
+  * ratelimit cma_alloc messages (LP: #1828092)
+    - SAUCE: cma: ratelimit cma_alloc error messages
+
+  * Headphone jack switch sense is inverted: plugging in headphones disables
+    headphone output (LP: #1824259)
+    - ASoC: rt5645: Headphone Jack sense inverts on the LattePanda board
+
+  * There are 4 HDMI/Displayport audio output listed in sound setting without
+    attach any HDMI/DP monitor (LP: #1827967)
+    - ALSA: hda/hdmi - Read the pin sense from register when repolling
+    - ALSA: hda/hdmi - Consider eld_valid when reporting jack event
+
+  * CONFIG_LOG_BUF_SHIFT set to 14 is too low on arm64 (LP: #1824864)
+    - [Config] CONFIG_LOG_BUF_SHIFT=18 on all 64bit arches
+
+  * CTAUTO:DevOps:860.50:devops4fp1:Error occurred during LINUX Dmesg error
+    Checking for all LINUX clients for devops4p10 (LP: #1766201)
+    - SAUCE: integrity: downgrade error to warning
+
+  * linux-buildinfo: pull out ABI information into its own package
+    (LP: #1806380)
+    - [Packaging] autoreconstruct -- base tag is always primary mainline version
+
+  * [SRU] Please sync vbox modules from virtualbox 6.0.6 on next kernel update
+    (LP: #1825210)
+    - vbox-update: updates for renamed makefiles
+    - ubuntu: vbox -- update to 6.0.6-dfsg-1
+
+  * autofs kernel module missing (LP: #1824333)
+    - [Config] Update autofs4 path in inclusion list
+
+  * The Realtek card reader does not enter PCIe 1.1/1.2 (LP: #1825487)
+    - SAUCE: misc: rtsx: Fixed rts5260 power saving parameter and sd glitch
+
+  * CVE-2019-3874
+    - sctp: implement memory accounting on tx path
+    - sctp: implement memory accounting on rx path
+
+  * apparmor does not start in Disco LXD containers (LP: #1824812)
+    - SAUCE: shiftfs: use separate llseek method for directories
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] autoreconstruct -- remove for -rc kernels
+    - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation
+      defined
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) furter KEXEC_VERIFY_SIG -> KEXEC_SIG updates
+    - [Config] (efi-lockdown): update configs after efi lockdown patch refresh
+    - [Packaging] don't delete efi_parser.c
+    - vbox-update -- do not fix up KERN_DIR or KBUILD_EXTMOD
+    - ubuntu: vbox -- update to 6.0.6-dfsg-2
+    - add nvidia-418 dkms build
+    - remove virtualbox guest drivers
+    - [Packaging] dkms-build -- expand paths searched for make.log files
+    - add virtualbox-guest-dkms dkms package build
+    - enable vbox dkms build for amd64 and i386
+    - [Config] update configs for v5.1(-rc7)? rebase
+    - update dkms package versions
+    - Add the ability to lock down access to the running kernel image
+    - Enforce module signatures if the kernel is locked down
+    - Restrict /dev/{mem,kmem,port} when the kernel is locked down
+    - kexec_load: Disable at runtime if the kernel is locked down
+    - Copy secure_boot flag in boot params across kexec reboot
+    - kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE
+    - kexec_file: Restrict at runtime if the kernel is locked down
+    - hibernate: Disable when the kernel is locked down
+    - uswsusp: Disable when the kernel is locked down
+    - PCI: Lock down BAR access when the kernel is locked down
+    - x86: Lock down IO port access when the kernel is locked down
+    - x86/msr: Restrict MSR access when the kernel is locked down
+    - ACPI: Limit access to custom_method when the kernel is locked down
+    - acpi: Ignore acpi_rsdp kernel param when the kernel has been locked down
+    - acpi: Disable ACPI table override if the kernel is locked down
+    - acpi: Disable APEI error injection if the kernel is locked down
+    - Prohibit PCMCIA CIS storage when the kernel is locked down
+    - Lock down TIOCSSERIAL
+    - Lock down module params that specify hardware parameters (eg. ioport)
+    - x86/mmiotrace: Lock down the testmmiotrace module
+    - Lock down /proc/kcore
+    - Lock down kprobes
+    - bpf: Restrict kernel image access functions when the kernel is locked down
+    - Lock down perf
+    - debugfs: Restrict debugfs when the kernel is locked down
+    - lockdown: Print current->comm in restriction messages
+    - kexec: Allow kexec_file() with appropriate IMA policy when locked down
+    - Make get_cert_list() not complain about cert lists that aren't present.
+    - Add efi_status_to_str() and rework efi_status_to_err().
+    - Make get_cert_list() use efi_status_to_str() to print error messages.
+    - efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode
+    - efi: Lock down the kernel if booted in secure boot mode
+    - KEYS: Make use of platform keyring for module signature verify
+
+  * Miscellaneous upstream changes
+    - ALSA: hdea/realtek - Headset fixup for System76 Gazelle (gaze14)
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 14 May 2019 12:32:56 -0500
+
+linux (5.1.0-1.1) eoan; urgency=medium
+
+  * bionic: fork out linux-snapdragon into its own topic kernel (LP: #1820868)
+    - [Packaging]: really drop snapdragon
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: fix vbox use of MAP_SHARED
+    - SAUCE: fix vbox use of vm_fault_t
+    - [Packaging] disable ZFS
+    - [Packaging] disable nvidia
+    - SAUCE: perf annotate: Fix build on 32 bit for BPF annotation
+    - [Config]: updateconfig after rebase to v5.1-rc
+    - [Config]: build ETNAVIV only on arm platforms
+    - [Config]: Disable CMA on non-arm platforms
+    - [Config]: MMC_CQHCI is needed by some built-in drivers
+    - [Config]: a.out support has been deprecated
+    - [Config]: R3964 was marked as BROKEN
+    - [Config]: Add SENSIRION_SGP30 module
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: tools: lib/bpf -- add generated headers to search
+      path"
+    - Revert "UBUNTU: SAUCE: btqcomsmd: introduce BT_QCOMSMD_HACK"
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Thu, 25 Apr 2019 10:03:25 -0300
+
+linux (5.1.0-0.0) eoan; urgency=medium
+
+  * Dummy entry.
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Thu, 25 Apr 2019 09:49:47 -0300
+
+linux (5.0.0-13.14) disco; urgency=medium
+
+  * linux: 5.0.0-13.14 -proposed tracker (LP: #1824819)
+
+  * Display only has 640x480 (LP: #1824677)
+    - Revert "UBUNTU: SAUCE: drm/nouveau: Disable nouveau driver by default"
+
+  * shiftfs: use after free when checking mount options (LP: #1824735)
+    - SAUCE: shiftfs: prevent use-after-free when verifying mount options
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 15 Apr 2019 09:11:23 -0500
+
+linux (5.0.0-12.13) disco; urgency=medium
+
+  * linux: 5.0.0-12.13 -proposed tracker (LP: #1824726)
+
+  * Linux 5.0 black screen on boot, display flickers (i915 regression with
+    certain laptop panels) (LP: #1824216)
+    - drm/i915/dp: revert back to max link rate and lane count on eDP
+
+  * kernel BUG at fs/attr.c:287 when using shiftfs (LP: #1824717)
+    - SAUCE: shiftfs: fix passing of attrs to underaly for setattr
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 14 Apr 2019 13:38:05 -0500
+
+linux (5.0.0-11.12) disco; urgency=medium
+
+  * linux: 5.0.0-11.12 -proposed tracker (LP: #1824383)
+
+  * hns3: PPU_PF_ABNORMAL_INT_ST over_8bd_no_fe found [error status=0x1]
+    (LP: #1824194)
+    - net: hns3: fix for not calculating tx bd num correctly
+
+  * disco: unable to use iptables/enable ufw under -virtual kernel
+    (LP: #1823862)
+    - [Packaging] add bpfilter to linux-modules
+
+  * Make shiftfs a module rather than built-in (LP: #1824354)
+    - [Config] CONFIG_SHIFT_FS=m
+
+  * shiftfs: chown sets untranslated ids in lower fs (LP: #1824350)
+    - SAUCE: shiftfs: use translated ids when chaning lower fs attrs
+
+  * [Hyper-V] KVP daemon fails to start on first boot of disco VM (LP: #1820063)
+    - [Packaging] bind hv_kvp_daemon startup to hv_kvp device
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 11 Apr 2019 10:17:19 -0500
+
+linux (5.0.0-10.11) disco; urgency=medium
+
+  * linux: 5.0.0-10.11 -proposed tracker (LP: #1823936)
+
+  * Apparmor enforcement failure in lxc selftests (LP: #1823379)
+    - SAUCE: apparmor: Restore Y/N in /sys for apparmor's "enabled"
+
+  * systemd cause kernel trace "BUG: unable to handle kernel paging request at
+    6db23a14" on Cosmic i386 (LP: #1813244)
+    - openvswitch: fix flow actions reallocation
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 09 Apr 2019 08:30:38 -0500
+
+linux (5.0.0-9.10) disco; urgency=medium
+
+  * linux: 5.0.0-9.10 -proposed tracker (LP: #1823228)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+    - [Packaging] update helper scripts
+    - [Packaging] resync retpoline extraction
+
+  * Huawei Hi1822 NIC has poor performance (LP: #1820187)
+    - net-next/hinic: replace disable_irq_nosync/enable_irq
+
+  * Add uid shifting overlay filesystem (shiftfs) (LP: #1823186)
+    - shiftfs: uid/gid shifting bind mount
+    - shiftfs: rework and extend
+    - shiftfs: support some btrfs ioctls
+    - [Config] enable shiftfs
+
+  * Cannot boot or install - have to use nomodeset (LP: #1821820)
+    - Revert "drm/i915/fbdev: Actually configure untiled displays"
+
+  * Disco update: v5.0.6 upstream stable release (LP: #1823060)
+    - netfilter: nf_tables: fix set double-free in abort path
+    - dccp: do not use ipv6 header for ipv4 flow
+    - genetlink: Fix a memory leak on error path
+    - gtp: change NET_UDP_TUNNEL dependency to select
+    - ipv6: make ip6_create_rt_rcu return ip6_null_entry instead of NULL
+    - mac8390: Fix mmio access size probe
+    - mISDN: hfcpci: Test both vendor & device ID for Digium HFC4S
+    - net: aquantia: fix rx checksum offload for UDP/TCP over IPv6
+    - net: datagram: fix unbounded loop in __skb_try_recv_datagram()
+    - net/packet: Set __GFP_NOWARN upon allocation in alloc_pg_vec
+    - net: phy: meson-gxl: fix interrupt support
+    - net: rose: fix a possible stack overflow
+    - net: stmmac: fix memory corruption with large MTUs
+    - net-sysfs: call dev_hold if kobject_init_and_add success
+    - net: usb: aqc111: Extend HWID table by QNAP device
+    - packets: Always register packet sk in the same order
+    - rhashtable: Still do rehash when we get EEXIST
+    - sctp: get sctphdr by offset in sctp_compute_cksum
+    - sctp: use memdup_user instead of vmemdup_user
+    - tcp: do not use ipv6 header for ipv4 flow
+    - tipc: allow service ranges to be connect()'ed on RDM/DGRAM
+    - tipc: change to check tipc_own_id to return in tipc_net_stop
+    - tipc: fix cancellation of topology subscriptions
+    - tun: properly test for IFF_UP
+    - vrf: prevent adding upper devices
+    - vxlan: Don't call gro_cells_destroy() before device is unregistered
+    - thunderx: enable page recycling for non-XDP case
+    - thunderx: eliminate extra calls to put_page() for pages held for recycling
+    - net: dsa: mv88e6xxx: fix few issues in mv88e6390x_port_set_cmode
+    - net: mii: Fix PAUSE cap advertisement from linkmode_adv_to_lcl_adv_t()
+      helper
+    - net: phy: don't clear BMCR in genphy_soft_reset
+    - r8169: fix cable re-plugging issue
+    - ila: Fix rhashtable walker list corruption
+    - tun: add a missing rcu_read_unlock() in error path
+    - powerpc/fsl: Fix the flush of branch predictor.
+    - Btrfs: fix incorrect file size after shrinking truncate and fsync
+    - btrfs: remove WARN_ON in log_dir_items
+    - btrfs: don't report readahead errors and don't update statistics
+    - btrfs: Fix bound checking in qgroup_trace_new_subtree_blocks
+    - btrfs: Avoid possible qgroup_rsv_size overflow in
+      btrfs_calculate_inode_block_rsv_size
+    - Btrfs: fix assertion failure on fsync with NO_HOLES enabled
+    - locks: wake any locks blocked on request before deadlock check
+    - tracing: initialize variable in create_dyn_event()
+    - ARM: imx6q: cpuidle: fix bug that CPU might not wake up at expected time
+    - powerpc: bpf: Fix generation of load/store DW instructions
+    - vfio: ccw: only free cp on final interrupt
+    - NFS: Fix nfs4_lock_state refcounting in nfs4_alloc_{lock,unlock}data()
+    - NFS: fix mount/umount race in nlmclnt.
+    - NFSv4.1 don't free interrupted slot on open
+    - net: dsa: qca8k: remove leftover phy accessors
+    - ALSA: rawmidi: Fix potential Spectre v1 vulnerability
+    - ALSA: seq: oss: Fix Spectre v1 vulnerability
+    - ALSA: pcm: Fix possible OOB access in PCM oss plugins
+    - ALSA: pcm: Don't suspend stream in unrecoverable PCM state
+    - ALSA: hda/realtek - Fixed Headset Mic JD not stable
+    - ALSA: hda/realtek: merge alc_fixup_headset_jack to alc295_fixup_chromebook
+    - ALSA: hda/realtek - Add support headset mode for DELL WYSE AIO
+    - ALSA: hda/realtek - Add support headset mode for New DELL WYSE NB
+    - ALSA: hda/realtek: Enable headset MIC of Acer AIO with ALC286
+    - ALSA: hda/realtek: Enable headset MIC of Acer Aspire Z24-890 with ALC286
+    - ALSA: hda/realtek - Add support for Acer Aspire E5-523G/ES1-432 headset mic
+    - ALSA: hda/realtek: Enable ASUS X441MB and X705FD headset MIC with ALC256
+    - ALSA: hda/realtek: Enable headset mic of ASUS P5440FF with ALC256
+    - ALSA: hda/realtek: Enable headset MIC of ASUS X430UN and X512DK with ALC256
+    - ALSA: hda/realtek - Fix speakers on Acer Predator Helios 500 Ryzen laptops
+    - kbuild: modversions: Fix relative CRC byte order interpretation
+    - fs/open.c: allow opening only regular files during execve()
+    - ocfs2: fix inode bh swapping mixup in ocfs2_reflink_inodes_lock
+    - scsi: sd: Fix a race between closing an sd device and sd I/O
+    - scsi: sd: Quiesce warning if device does not report optimal I/O size
+    - scsi: zfcp: fix rport unblock if deleted SCSI devices on Scsi_Host
+    - scsi: zfcp: fix scsi_eh host reset with port_forced ERP for non-NPIV FCP
+      devices
+    - drm/rockchip: vop: reset scale mode when win is disabled
+    - tty/serial: atmel: Add is_half_duplex helper
+    - tty/serial: atmel: RS485 HD w/DMA: enable RX after TX is stopped
+    - tty: mxs-auart: fix a potential NULL pointer dereference
+    - tty: atmel_serial: fix a potential NULL pointer dereference
+    - tty: serial: qcom_geni_serial: Initialize baud in qcom_geni_console_setup
+    - staging: comedi: ni_mio_common: Fix divide-by-zero for DIO cmdtest
+    - staging: olpc_dcon_xo_1: add missing 'const' qualifier
+    - staging: speakup_soft: Fix alternate speech with other synths
+    - staging: vt6655: Remove vif check from vnt_interrupt
+    - staging: vt6655: Fix interrupt race condition on device start up.
+    - staging: erofs: fix to handle error path of erofs_vmap()
+    - staging: erofs: fix error handling when failed to read compresssed data
+    - staging: erofs: keep corrupted fs from crashing kernel in erofs_readdir()
+    - serial: max310x: Fix to avoid potential NULL pointer dereference
+    - serial: mvebu-uart: Fix to avoid a potential NULL pointer dereference
+    - serial: sh-sci: Fix setting SCSCR_TIE while transferring data
+    - USB: serial: cp210x: add new device id
+    - USB: serial: ftdi_sio: add additional NovaTech products
+    - USB: serial: mos7720: fix mos_parport refcount imbalance on error path
+    - USB: serial: option: set driver_info for SIM5218 and compatibles
+    - USB: serial: option: add support for Quectel EM12
+    - USB: serial: option: add Olicard 600
+    - ACPI / CPPC: Fix guaranteed performance handling
+    - Disable kgdboc failed by echo space to /sys/module/kgdboc/parameters/kgdboc
+    - fs/proc/proc_sysctl.c: fix NULL pointer dereference in put_links
+    - drivers/block/zram/zram_drv.c: fix idle/writeback string compare
+    - blk-mq: fix sbitmap ws_active for shared tags
+    - cpufreq: intel_pstate: Also use CPPC nominal_perf for base_frequency
+    - cpufreq: scpi: Fix use after free
+    - drm/vgem: fix use-after-free when drm_gem_handle_create() fails
+    - drm/vkms: fix use-after-free when drm_gem_handle_create() fails
+    - drm/i915: Mark AML 0x87CA as ULX
+    - drm/i915/gvt: Fix MI_FLUSH_DW parsing with correct index check
+    - drm/i915/icl: Fix the TRANS_DDI_FUNC_CTL2 bitfield macro
+    - gpio: exar: add a check for the return value of ida_simple_get fails
+    - gpio: adnp: Fix testing wrong value in adnp_gpio_direction_input
+    - phy: sun4i-usb: Support set_mode to USB_HOST for non-OTG PHYs
+    - usb: mtu3: fix EXTCON dependency
+    - USB: gadget: f_hid: fix deadlock in f_hidg_write()
+    - usb: common: Consider only available nodes for dr_mode
+    - mm/memory.c: fix modifying of page protection by insert_pfn()
+    - usb: host: xhci-rcar: Add XHCI_TRUST_TX_LENGTH quirk
+    - xhci: Fix port resume done detection for SS ports with LPM enabled
+    - usb: xhci: dbc: Don't free all memory with spinlock held
+    - xhci: Don't let USB3 ports stuck in polling state prevent suspend
+    - usb: cdc-acm: fix race during wakeup blocking TX traffic
+    - usb: typec: tcpm: Try PD-2.0 if sink does not respond to 3.0 source-caps
+    - usb: typec: Fix unchecked return value
+    - mm/hotplug: fix offline undo_isolate_page_range()
+    - mm: add support for kmem caches in DMA32 zone
+    - iommu/io-pgtable-arm-v7s: request DMA32 memory, and improve debugging
+    - mm: mempolicy: make mbind() return -EIO when MPOL_MF_STRICT is specified
+    - mm/debug.c: fix __dump_page when mapping->host is not set
+    - mm/memory_hotplug.c: fix notification in offline error path
+    - mm/page_isolation.c: fix a wrong flag in set_migratetype_isolate()
+    - mm/migrate.c: add missing flush_dcache_page for non-mapped page migrate
+    - perf pmu: Fix parser error for uncore event alias
+    - perf intel-pt: Fix TSC slip
+    - objtool: Query pkg-config for libelf location
+    - powerpc/pseries/energy: Use OF accessor functions to read ibm,drc-indexes
+    - powerpc/64: Fix memcmp reading past the end of src/dest
+    - powerpc/pseries/mce: Fix misleading print for TLB mutlihit
+    - watchdog: Respect watchdog cpumask on CPU hotplug
+    - cpu/hotplug: Prevent crash when CPU bringup fails on CONFIG_HOTPLUG_CPU=n
+    - x86/smp: Enforce CONFIG_HOTPLUG_CPU when SMP=y
+    - KVM: Reject device ioctls from processes other than the VM's creator
+    - KVM: x86: Emulate MSR_IA32_ARCH_CAPABILITIES on AMD hosts
+    - KVM: x86: update %rip after emulating IO
+    - bpf: do not restore dst_reg when cur_state is freed
+    - mt76x02u: use usb_bulk_msg to upload firmware
+    - Linux 5.0.6
+
+  * RDMA/hns updates for disco (LP: #1822897)
+    - RDMA/hns: Fix the bug with updating rq head pointer when flush cqe
+    - RDMA/hns: Bugfix for the scene without receiver queue
+    - RDMA/hns: Add constraint on the setting of local ACK timeout
+    - RDMA/hns: Modify the pbl ba page size for hip08
+    - RDMA/hns: RDMA/hns: Assign rq head pointer when enable rq record db
+    - RDMA/hns: Add the process of AEQ overflow for hip08
+    - RDMA/hns: Add SCC context allocation support for hip08
+    - RDMA/hns: Add SCC context clr support for hip08
+    - RDMA/hns: Add timer allocation support for hip08
+    - RDMA/hns: Remove set but not used variable 'rst'
+    - RDMA/hns: Make some function static
+    - RDMA/hns: Fix the Oops during rmmod or insmod ko when reset occurs
+    - RDMA/hns: Fix the chip hanging caused by sending mailbox&CMQ during reset
+    - RDMA/hns: Fix the chip hanging caused by sending doorbell during reset
+    - RDMA/hns: Limit minimum ROCE CQ depth to 64
+    - RDMA/hns: Fix the state of rereg mr
+    - RDMA/hns: Set allocated memory to zero for wrid
+    - RDMA/hns: Delete useful prints for aeq subtype event
+    - RDMA/hns: Configure capacity of hns device
+    - RDMA/hns: Modify qp&cq&pd specification according to UM
+    - RDMA/hns: Bugfix for set hem of SCC
+    - RDMA/hns: Use GFP_ATOMIC in hns_roce_v2_modify_qp
+
+  * autopkgtests run too often, too much and don't skip enough (LP: #1823056)
+    - Set +x on rebuild testcase.
+    - Skip rebuild test, for regression-suite deps.
+    - Make ubuntu-regression-suite skippable on unbootable kernels.
+    - make rebuild use skippable error codes when skipping.
+    - Only run regression-suite, if requested to.
+
+  * touchpad not working on lenovo yoga 530 (LP: #1787775)
+    - Revert "UBUNTU: SAUCE: i2c:amd Depends on ACPI"
+    - Revert "UBUNTU: SAUCE: i2c:amd move out pointer in union i2c_event_base"
+    - i2c: add extra check to safe DMA buffer helper
+    - i2c: Add drivers for the AMD PCIe MP2 I2C controller
+    - [Config] Update config for AMD MP2 I2C driver
+
+  * Detect SMP PHY control command errors (LP: #1822680)
+    - scsi: libsas: Check SMP PHY control function result
+
+  * disable a.out support (LP: #1818552)
+    - [Config] Disable a.out support
+    - [Config] remove binfmt_aout from abi for i386 lowlatency
+
+  * bionic: fork out linux-snapdragon into its own topic kernel (LP: #1820868)
+    - [Packaging] remove snapdragon flavour support
+    - Revert "UBUNTU: SAUCE: (snapdragon) drm/msm/adv7511: wrap hacks under
+      CONFIG_ADV7511_SNAPDRAGON_HACKS #ifdefs"
+    - Revert "UBUNTU: SAUCE: (snapdragon) media: ov5645: skip address change if dt
+      addr == default addr"
+    - Revert "UBUNTU: SAUCE: (snapdragon) DT: leds: Add Qualcomm Light Pulse
+      Generator binding"
+    - Revert "UBUNTU: SAUCE: (snapdragon) MAINTAINERS: Add Qualcomm Camera Control
+      Interface driver"
+    - Revert "UBUNTU: SAUCE: (snapdragon) dt-bindings: media: Binding document for
+      Qualcomm Camera Control Interface driver"
+    - Revert "UBUNTU: SAUCE: (snapdragon) leds: Add driver for Qualcomm LPG"
+    - Revert "UBUNTU: SAUCE: (snapdragon) HACK: drm/msm/adv7511: Don't rely on
+      interrupts for EDID parsing"
+    - Revert "UBUNTU: SAUCE: (snapdragon) drm/bridge/adv7511: Delay clearing of
+      HPD interrupt status"
+    - Revert "UBUNTU: SAUCE: (snapdragon) media: ov5645: Fix I2C address"
+    - Revert "UBUNTU: SAUCE: (snapdragon) i2c-qcom-cci: Fix I2C address bug"
+    - Revert "UBUNTU: SAUCE: (snapdragon) i2c-qcom-cci: Fix run queue completion
+      timeout"
+    - Revert "UBUNTU: SAUCE: (snapdragon) camss: Do not register if no cameras are
+      present"
+    - Revert "UBUNTU: SAUCE: (snapdragon) i2c: Add Qualcomm Camera Control
+      Interface driver"
+    - Revert "UBUNTU: SAUCE: (snapdragon) ov5645: I2C address change"
+    - Revert "UBUNTU: SAUCE: (snapdragon) regulator: smd: Allow
+      REGULATOR_QCOM_SMD_RPM=m"
+    - Revert "UBUNTU: SAUCE: (snapdragon) cpufreq: Add apq8016 to cpufreq-dt-
+      platdev blacklist"
+    - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: Add a helper to get an opp
+      regulator for device"
+    - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: HACK: Allow to set regulator
+      without opp_list"
+    - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: Drop RCU usage in
+      dev_pm_opp_adjust_voltage()"
+    - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: Support adjusting OPP voltages
+      at runtime"
+    - Revert "UBUNTU: SAUCE: (snapdragon) regulator: smd: Add floor and corner
+      operations"
+    - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: cpr: Register with cpufreq-
+      dt"
+    - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: cpr: fix with new
+      reg_sequence structures"
+    - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: cpr: Use raw mem access for
+      qfprom"
+    - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: Add support for CPR (Core
+      Power Reduction)"
+    - Revert "UBUNTU: SAUCE: (snapdragon) HACK: drm/msm/iommu: Remove runtime_put
+      calls in map/unmap"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable LEDS_QCOM_LPG"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable 'BBR' TCP
+      congestion algorithm"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable 'fq' and
+      'fq_codel' qdiscs"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable
+      'schedutil' CPUfreq governor"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: set USB_CONFIG_F_FS in
+      distro.config"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable
+      CONFIG_USB_CONFIGFS_F_FS by default"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: add freq stat to sysfs"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: Enable camera drivers"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: disable ANALOG_TV and
+      DIGITAL_TV"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: add more USB net
+      drivers"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: enable BT_QCOMSMD"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable
+      CFG80211_DEFAULT_PS by default"
+    - Revert "UBUNTU: SAUCE: (snapdragon) Force the SMD regulator driver to be
+      compiled-in"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: enable dm_mod and
+      dm_crypt"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: Enable a53/apcs and
+      avs"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: enable QCOM Venus"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable debug
+      friendly USB network adpater"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: enable WCN36xx"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs; add distro.config"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable QCOM audio
+      drivers for APQ8016 and DB410c"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable REMOTEPROC"
+    - [Config] fix abi for remove i2c-qcom-cci module
+    - [Config] update annotations
+    - [Config] update configs following snapdragon removal
+
+  * Disco update: v5.0.5 upstream stable release (LP: #1822671)
+    - Revert "ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec"
+    - ALSA: hda - add Lenovo IdeaCentre B550 to the power_save_blacklist
+    - ALSA: firewire-motu: use 'version' field of unit directory to identify model
+    - mmc: pxamci: fix enum type confusion
+    - mmc: alcor: fix DMA reads
+    - mmc: mxcmmc: "Revert mmc: mxcmmc: handle highmem pages"
+    - mmc: renesas_sdhi: limit block count to 16 bit for old revisions
+    - drm/amdgpu: fix invalid use of change_bit
+    - drm/vmwgfx: Don't double-free the mode stored in par->set_mode
+    - drm/vmwgfx: Return 0 when gmrid::get_node runs out of ID's
+    - iommu/amd: fix sg->dma_address for sg->offset bigger than PAGE_SIZE
+    - iommu/iova: Fix tracking of recently failed iova address
+    - libceph: wait for latest osdmap in ceph_monc_blacklist_add()
+    - udf: Fix crash on IO error during truncate
+    - mips: loongson64: lemote-2f: Add IRQF_NO_SUSPEND to "cascade" irqaction.
+    - MIPS: Ensure ELF appended dtb is relocated
+    - MIPS: Fix kernel crash for R6 in jump label branch function
+    - powerpc/vdso64: Fix CLOCK_MONOTONIC inconsistencies across Y2038
+    - powerpc/security: Fix spectre_v2 reporting
+    - net/mlx5: Fix DCT creation bad flow
+    - scsi: core: Avoid that a kernel warning appears during system resume
+    - scsi: qla2xxx: Fix FC-AL connection target discovery
+    - scsi: ibmvscsi: Protect ibmvscsi_head from concurrent modificaiton
+    - scsi: ibmvscsi: Fix empty event pool access during host removal
+    - futex: Ensure that futex address is aligned in handle_futex_death()
+    - perf probe: Fix getting the kernel map
+    - objtool: Move objtool_file struct off the stack
+    - irqchip/gic-v3-its: Fix comparison logic in lpi_range_cmp
+    - clocksource/drivers/riscv: Fix clocksource mask
+    - ALSA: ac97: Fix of-node refcount unbalance
+    - ext4: fix NULL pointer dereference while journal is aborted
+    - ext4: fix data corruption caused by unaligned direct AIO
+    - ext4: brelse all indirect buffer in ext4_ind_remove_space()
+    - media: v4l2-ctrls.c/uvc: zero v4l2_event
+    - Bluetooth: hci_uart: Check if socket buffer is ERR_PTR in h4_recv_buf()
+    - Bluetooth: Fix decrementing reference count twice in releasing socket
+    - Bluetooth: hci_ldisc: Initialize hci_dev before open()
+    - Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in
+      hci_uart_set_proto()
+    - drm/vkms: Fix flush_work() without INIT_WORK().
+    - RDMA/cma: Rollback source IP address if failing to acquire device
+    - f2fs: fix to avoid deadlock of atomic file operations
+    - aio: simplify - and fix - fget/fput for io_submit()
+    - netfilter: ebtables: remove BUGPRINT messages
+    - loop: access lo_backing_file only when the loop device is Lo_bound
+    - x86/unwind: Handle NULL pointer calls better in frame unwinder
+    - x86/unwind: Add hardcoded ORC entry for NULL
+    - locking/lockdep: Add debug_locks check in __lock_downgrade()
+    - ALSA: hda - Record the current power state before suspend/resume calls
+    - ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec
+    - Linux 5.0.5
+
+  * hisi_sas updates for disco (LP: #1822385)
+    - scsi: hisi_sas: send primitive NOTIFY to SSP situation only
+    - scsi: hisi_sas: shutdown axi bus to avoid exception CQ returned
+    - scsi: hisi_sas: remove the check of sas_dev status in
+      hisi_sas_I_T_nexus_reset()
+    - scsi: hisi_sas: Remove unused parameter of function hisi_sas_alloc()
+    - scsi: hisi_sas: Reject setting programmed minimum linkrate > 1.5G
+    - scsi: hisi_sas: Fix losing directly attached disk when hot-plug
+    - scsi: hisi_sas: Correct memory allocation size for DQ debugfs
+    - scsi: hisi_sas: Some misc tidy-up
+    - scsi: hisi_sas: Fix to only call scsi_get_prot_op() for non-NULL scsi_cmnd
+    - scsi: hisi_sas: Add missing seq_printf() call in hisi_sas_show_row_32()
+    - scsi: hisi_sas: Add support for DIX feature for v3 hw
+    - scsi: hisi_sas: Add manual trigger for debugfs dump
+    - scsi: hisi_sas: change queue depth from 512 to 4096
+    - scsi: hisi_sas: Issue internal abort on all relevant queues
+    - scsi: hisi_sas: Use pci_irq_get_affinity() for v3 hw as experimental
+    - scsi: hisi_sas: Do some more tidy-up
+    - scsi: hisi_sas: Change return variable type in phy_up_v3_hw()
+    - scsi: hisi_sas: Fix a timeout race of driver internal and SMP IO
+    - scsi: hisi_sas: print PHY RX errors count for later revision of v3 hw
+    - scsi: hisi_sas: Set PHY linkrate when disconnected
+    - scsi: hisi_sas: Send HARD RESET to clear the previous affiliation of STP
+      target port
+    - scsi: hisi_sas: Change SERDES_CFG init value to increase reliability of
+      HiLink
+    - scsi: hisi_sas: Add softreset in hisi_sas_I_T_nexus_reset()
+
+  * [Patch][Raven 2] kernel 5.0.0 cannot boot because of psp response
+    (LP: #1822267)
+    - drm/amdgpu/psp: Fix can't detect psp INVOKE command failed
+    - drm/amdgpu/psp: ignore psp response status
+
+  * 3b080b2564287be91605bfd1d5ee985696e61d3c in ubuntu_btrfs_kernel_fixes
+    triggers system hang on i386 (LP: #1812845)
+    - btrfs: raid56: properly unmap parity page in finish_parity_scrub()
+
+  * enable CONFIG_DRM_BOCHS (LP: #1795857)
+    - [Config] Reenable DRM_BOCHS as module
+
+  * [Dell Precision 7530/5530 with Nvidia Quadro P1000] Live USB freezes or
+    cannot complete install when nouveau driver is loaded (crashing in GP100
+    code) (LP: #1822026)
+    - SAUCE: drm/nouveau: Disable nouveau driver by default
+
+  * Need to add Intel CML related pci-id's (LP: #1821863)
+    - drm/i915/cml: Add CML PCI IDS
+    - drm/i915/cml: Introduce Comet Lake PCH
+
+  * ARM: Add support for the SDEI interface (LP: #1822005)
+    - ACPI / APEI: Don't wait to serialise with oops messages when panic()ing
+    - ACPI / APEI: Remove silent flag from ghes_read_estatus()
+    - ACPI / APEI: Switch estatus pool to use vmalloc memory
+    - ACPI / APEI: Make hest.c manage the estatus memory pool
+    - ACPI / APEI: Make estatus pool allocation a static size
+    - ACPI / APEI: Don't store CPER records physical address in struct ghes
+    - ACPI / APEI: Remove spurious GHES_TO_CLEAR check
+    - ACPI / APEI: Don't update struct ghes' flags in read/clear estatus
+    - ACPI / APEI: Generalise the estatus queue's notify code
+    - ACPI / APEI: Don't allow ghes_ack_error() to mask earlier errors
+    - ACPI / APEI: Move NOTIFY_SEA between the estatus-queue and NOTIFY_NMI
+    - ACPI / APEI: Switch NOTIFY_SEA to use the estatus queue
+    - KVM: arm/arm64: Add kvm_ras.h to collect kvm specific RAS plumbing
+    - arm64: KVM/mm: Move SEA handling behind a single 'claim' interface
+    - ACPI / APEI: Move locking to the notification helper
+    - ACPI / APEI: Let the notification helper specify the fixmap slot
+    - ACPI / APEI: Pass ghes and estatus separately to avoid a later copy
+    - ACPI / APEI: Make GHES estatus header validation more user friendly
+    - ACPI / APEI: Split ghes_read_estatus() to allow a peek at the CPER length
+    - ACPI / APEI: Only use queued estatus entry during in_nmi_queue_one_entry()
+    - ACPI / APEI: Use separate fixmap pages for arm64 NMI-like notifications
+    - firmware: arm_sdei: Add ACPI GHES registration helper
+    - ACPI / APEI: Add support for the SDEI GHES Notification type
+
+  * CVE-2019-9857
+    - inotify: Fix fsnotify_mark refcount leak in inotify_update_existing_watch()
+
+  * scsi: libsas: Support SATA PHY connection rate unmatch fixing during
+    discovery (LP: #1821408)
+    - scsi: libsas: Support SATA PHY connection rate unmatch fixing during
+      discovery
+
+  * Qualcomm Atheros QCA9377 wireless does not work (LP: #1818204)
+    - platform/x86: ideapad-laptop: Add Ideapad 530S-14ARR to no_hw_rfkill list
+
+  * Lenovo ideapad 330-15ICH Wifi rfkill hard blocked (LP: #1811815)
+    - platform/x86: ideapad: Add ideapad 330-15ICH to no_hw_rfkill
+
+  * hid-sensor-hub spamming dmesg in 4.20 (LP: #1818547)
+    - HID: Increase maximum report size allowed by hid_field_extract()
+
+  * [disco] [5.0.0-7.8] can't mount guest cifs share (LP: #1821053)
+    - cifs: allow guest mounts to work for smb3.11
+    - SMB3: Fix SMB3.1.1 guest mounts to Samba
+
+  * Add HiSilicon SoC quirk for cpufreq (LP: #1821620)
+    - ACPI / CPPC: Add a helper to get desired performance
+    - cpufreq / cppc: Work around for Hisilicon CPPC cpufreq
+
+  * Disco update: v5.0.4 upstream stable release (LP: #1821607)
+    - 9p: use inode->i_lock to protect i_size_write() under 32-bit
+    - 9p/net: fix memory leak in p9_client_create
+    - ASoC: fsl_esai: fix register setting issue in RIGHT_J mode
+    - ASoC: codecs: pcm186x: fix wrong usage of DECLARE_TLV_DB_SCALE()
+    - ASoC: codecs: pcm186x: Fix energysense SLEEP bit
+    - iio: adc: exynos-adc: Fix NULL pointer exception on unbind
+    - iio: adc: exynos-adc: Use proper number of channels for Exynos4x12
+    - mei: hbm: clean the feature flags on link reset
+    - mei: bus: move hw module get/put to probe/release
+    - stm class: Prevent division by zero
+    - stm class: Fix an endless loop in channel allocation
+    - crypto: caam - fix hash context DMA unmap size
+    - crypto: ccree - fix missing break in switch statement
+    - crypto: caam - fixed handling of sg list
+    - crypto: caam - fix DMA mapping of stack memory
+    - crypto: ccree - fix free of unallocated mlli buffer
+    - crypto: ccree - unmap buffer before copying IV
+    - crypto: ccree - don't copy zero size ciphertext
+    - crypto: cfb - add missing 'chunksize' property
+    - crypto: cfb - remove bogus memcpy() with src == dest
+    - crypto: ofb - fix handling partial blocks and make thread-safe
+    - crypto: ahash - fix another early termination in hash walk
+    - crypto: rockchip - fix scatterlist nents error
+    - crypto: rockchip - update new iv to device in multiple operations
+    - dax: Flush partial PMDs correctly
+    - nfit: Fix nfit_intel_shutdown_status() command submission
+    - nfit: acpi_nfit_ctl(): Check out_obj->type in the right place
+    - acpi/nfit: Fix bus command validation
+    - nfit/ars: Attempt a short-ARS whenever the ARS state is idle at boot
+    - nfit/ars: Attempt short-ARS even in the no_init_ars case
+    - libnvdimm/label: Clear 'updating' flag after label-set update
+    - libnvdimm, pfn: Fix over-trim in trim_pfn_device()
+    - libnvdimm/pmem: Honor force_raw for legacy pmem regions
+    - libnvdimm: Fix altmap reservation size calculation
+    - fix cgroup_do_mount() handling of failure exits
+    - crypto: aead - set CRYPTO_TFM_NEED_KEY if ->setkey() fails
+    - crypto: aegis - fix handling chunked inputs
+    - crypto: arm/crct10dif - revert to C code for short inputs
+    - crypto: arm64/aes-neonbs - fix returning final keystream block
+    - crypto: arm64/crct10dif - revert to C code for short inputs
+    - crypto: hash - set CRYPTO_TFM_NEED_KEY if ->setkey() fails
+    - crypto: morus - fix handling chunked inputs
+    - crypto: pcbc - remove bogus memcpy()s with src == dest
+    - crypto: skcipher - set CRYPTO_TFM_NEED_KEY if ->setkey() fails
+    - crypto: testmgr - skip crc32c context test for ahash algorithms
+    - crypto: x86/aegis - fix handling chunked inputs and MAY_SLEEP
+    - crypto: x86/aesni-gcm - fix crash on empty plaintext
+    - crypto: x86/morus - fix handling chunked inputs and MAY_SLEEP
+    - crypto: arm64/aes-ccm - fix logical bug in AAD MAC handling
+    - crypto: arm64/aes-ccm - fix bugs in non-NEON fallback routine
+    - CIFS: Fix leaking locked VFS cache pages in writeback retry
+    - CIFS: Do not reset lease state to NONE on lease break
+    - CIFS: Do not skip SMB2 message IDs on send failures
+    - CIFS: Fix read after write for files with read caching
+    - smb3: make default i/o size for smb3 mounts larger
+    - tracing: Use strncpy instead of memcpy for string keys in hist triggers
+    - tracing: Do not free iter->trace in fail path of tracing_open_pipe()
+    - tracing/perf: Use strndup_user() instead of buggy open-coded version
+    - vmw_balloon: release lock on error in vmballoon_reset()
+    - xen: fix dom0 boot on huge systems
+    - ACPI / device_sysfs: Avoid OF modalias creation for removed device
+    - mmc: sdhci-esdhc-imx: fix HS400 timing issue
+    - mmc: renesas_sdhi: Fix card initialization failure in high speed mode
+    - mmc:fix a bug when max_discard is 0
+    - spi: ti-qspi: Fix mmap read when more than one CS in use
+    - spi: pxa2xx: Setup maximum supported DMA transfer length
+    - spi: omap2-mcspi: Fix DMA and FIFO event trigger size mismatch
+    - spi: spi-gpio: fix SPI_CS_HIGH capability
+    - regulator: s2mps11: Fix steps for buck7, buck8 and LDO35
+    - regulator: max77620: Initialize values for DT properties
+    - regulator: s2mpa01: Fix step values for some LDOs
+    - mt76: fix corrupted software generated tx CCMP PN
+    - clocksource/drivers/exynos_mct: Move one-shot check from tick clear to ISR
+    - clocksource/drivers/exynos_mct: Clear timer interrupt when shutdown
+    - clocksource/drivers/arch_timer: Workaround for Allwinner A64 timer
+      instability
+    - s390: vfio_ap: link the vfio_ap devices to the vfio_ap bus subsystem
+    - s390/setup: fix early warning messages
+    - s390/virtio: handle find on invalid queue gracefully
+    - scsi: virtio_scsi: don't send sc payload with tmfs
+    - scsi: aacraid: Fix performance issue on logical drives
+    - scsi: sd: Optimal I/O size should be a multiple of physical block size
+    - scsi: target/iscsi: Avoid iscsit_release_commands_from_conn() deadlock
+    - scsi: qla2xxx: Fix LUN discovery if loop id is not assigned yet by firmware
+    - scsi: qla2xxx: Avoid PCI IRQ affinity mapping when multiqueue is not
+      supported
+    - scsi: qla2xxx: Use complete switch scan for RSCN events
+    - fs/devpts: always delete dcache dentry-s in dput()
+    - splice: don't merge into linked buffers
+    - ovl: During copy up, first copy up data and then xattrs
+    - ovl: Do not lose security.capability xattr over metadata file copy-up
+    - m68k: Add -ffreestanding to CFLAGS
+    - Btrfs: setup a nofs context for memory allocation at btrfs_create_tree()
+    - Btrfs: setup a nofs context for memory allocation at __btrfs_set_acl
+    - btrfs: scrub: fix circular locking dependency warning
+    - btrfs: drop the lock on error in btrfs_dev_replace_cancel
+    - btrfs: ensure that a DUP or RAID1 block group has exactly two stripes
+    - btrfs: init csum_list before possible free
+    - Btrfs: fix corruption reading shared and compressed extents after hole
+      punching
+    - Btrfs: fix deadlock between clone/dedupe and rename
+    - soc: qcom: rpmh: Avoid accessing freed memory from batch API
+    - libertas_tf: don't set URB_ZERO_PACKET on IN USB transfer
+    - irqchip/gic-v3-its: Avoid parsing _indirect_ twice for Device table
+    - irqchip/brcmstb-l2: Use _irqsave locking variants in non-interrupt code
+    - x86/kprobes: Prohibit probing on optprobe template code
+    - cpufreq: kryo: Release OPP tables on module removal
+    - cpufreq: tegra124: add missing of_node_put()
+    - cpufreq: pxa2xx: remove incorrect __init annotation
+    - ext4: fix check of inode in swap_inode_boot_loader
+    - ext4: cleanup pagecache before swap i_data
+    - mm: hwpoison: fix thp split handing in soft_offline_in_use_page()
+    - mm/vmalloc: fix size check for remap_vmalloc_range_partial()
+    - mm/memory.c: do_fault: avoid usage of stale vm_area_struct
+    - kernel/sysctl.c: add missing range check in do_proc_dointvec_minmax_conv
+    - nvmem: core: don't check the return value of notifier chain call
+    - device property: Fix the length used in PROPERTY_ENTRY_STRING()
+    - intel_th: Don't reference unassigned outputs
+    - parport_pc: fix find_superio io compare code, should use equal test.
+    - i2c: tegra: fix maximum transfer size
+    - i2c: tegra: update maximum transfer size
+    - media: i2c: ov5640: Fix post-reset delay
+    - gpio: pca953x: Fix dereference of irq data in shutdown
+    - ext4: update quota information while swapping boot loader inode
+    - ext4: add mask of ext4 flags to swap
+    - ext4: fix crash during online resizing
+    - dma: Introduce dma_max_mapping_size()
+    - swiotlb: Introduce swiotlb_max_mapping_size()
+    - swiotlb: Add is_swiotlb_active() function
+    - PCI/ASPM: Use LTR if already enabled by platform
+    - PCI/DPC: Fix print AER status in DPC event handling
+    - PCI: qcom: Don't deassert reset GPIO during probe
+    - PCI: dwc: skip MSI init if MSIs have been explicitly disabled
+    - PCI: pci-bridge-emul: Create per-bridge copy of register behavior
+    - PCI: pci-bridge-emul: Extend pci_bridge_emul_init() with flags
+    - IB/hfi1: Close race condition on user context disable and close
+    - IB/rdmavt: Fix loopback send with invalidate ordering
+    - IB/rdmavt: Fix concurrency panics in QP post_send and modify to error
+    - cxl: Wrap iterations over afu slices inside 'afu_list_lock'
+    - ext2: Fix underflow in ext2_max_size()
+    - clk: uniphier: Fix update register for CPU-gear
+    - clk: clk-twl6040: Fix imprecise external abort for pdmclk
+    - clk: samsung: exynos5: Fix possible NULL pointer exception on
+      platform_device_alloc() failure
+    - clk: samsung: exynos5: Fix kfree() of const memory on setting
+      driver_override
+    - clk: ingenic: Fix round_rate misbehaving with non-integer dividers
+    - clk: ingenic: Fix doc of ingenic_cgu_div_info
+    - usb: chipidea: tegra: Fix missed ci_hdrc_remove_device()
+    - usb: typec: tps6598x: handle block writes separately with plain-I2C adapters
+    - dmaengine: usb-dmac: Make DMAC system sleep callbacks explicit
+    - serial: uartps: Fix stuck ISR if RX disabled with non-empty FIFO
+    - serial: 8250_of: assume reg-shift of 2 for mrvl,mmp-uart
+    - serial: 8250_pci: Fix number of ports for ACCES serial cards
+    - serial: 8250_pci: Have ACCES cards that use the four port Pericom PI7C9X7954
+      chip use the pci_pericom_setup()
+    - jbd2: clear dirty flag when revoking a buffer from an older transaction
+    - jbd2: fix compile warning when using JBUFFER_TRACE
+    - selinux: add the missing walk_size + len check in selinux_sctp_bind_connect
+    - security/selinux: fix SECURITY_LSM_NATIVE_LABELS on reused superblock
+    - powerpc/32: Clear on-stack exception marker upon exception return
+    - powerpc/wii: properly disable use of BATs when requested.
+    - powerpc/powernv: Make opal log only readable by root
+    - powerpc/83xx: Also save/restore SPRG4-7 during suspend
+    - powerpc/kvm: Save and restore host AMR/IAMR/UAMOR
+    - powerpc/powernv: Don't reprogram SLW image on every KVM guest entry/exit
+    - powerpc/64s/hash: Fix assert_slb_presence() use of the slbfee. instruction
+    - powerpc: Fix 32-bit KVM-PR lockup and host crash with MacOS guest
+    - powerpc/ptrace: Simplify vr_get/set() to avoid GCC warning
+    - powerpc/hugetlb: Don't do runtime allocation of 16G pages in LPAR
+      configuration
+    - powerpc/smp: Fix NMI IPI timeout
+    - powerpc/smp: Fix NMI IPI xmon timeout
+    - powerpc/traps: fix recoverability of machine check handling on book3s/32
+    - powerpc/traps: Fix the message printed when stack overflows
+    - ARM: s3c24xx: Fix boolean expressions in osiris_dvs_notify
+    - arm64: Fix HCR.TGE status for NMI contexts
+    - arm64: debug: Don't propagate UNKNOWN FAR into si_code for debug signals
+    - arm64: debug: Ensure debug handlers check triggering exception level
+    - arm64: KVM: Fix architecturally invalid reset value for FPEXC32_EL2
+    - Revert "KVM/MMU: Flush tlb directly in the kvm_zap_gfn_range()"
+    - ipmi_si: Fix crash when using hard-coded device
+    - ipmi_si: fix use-after-free of resource->name
+    - dm: fix to_sector() for 32bit
+    - dm integrity: limit the rate of error messages
+    - media: cx25840: mark pad sig_types to fix cx231xx init
+    - mfd: sm501: Fix potential NULL pointer dereference
+    - cpcap-charger: generate events for userspace
+    - cpuidle: governor: Add new governors to cpuidle_governors again
+    - NFS: Fix I/O request leakages
+    - NFS: Fix an I/O request leakage in nfs_do_recoalesce
+    - NFS: Don't recoalesce on error in nfs_pageio_complete_mirror()
+    - nfsd: fix performance-limiting session calculation
+    - nfsd: fix memory corruption caused by readdir
+    - nfsd: fix wrong check in write_v4_end_grace()
+    - NFSv4.1: Reinitialise sequence results before retransmitting a request
+    - svcrpc: fix UDP on servers with lots of threads
+    - PM / wakeup: Rework wakeup source timer cancellation
+    - PM / OPP: Update performance state when freq == old_freq
+    - bcache: treat stale && dirty keys as bad keys
+    - bcache: use (REQ_META|REQ_PRIO) to indicate bio for metadata
+    - stable-kernel-rules.rst: add link to networking patch queue
+    - vt: perform safe console erase in the right order
+    - x86/unwind/orc: Fix ORC unwind table alignment
+    - perf intel-pt: Fix CYC timestamp calculation after OVF
+    - perf tools: Fix split_kallsyms_for_kcore() for trampoline symbols
+    - perf auxtrace: Define auxtrace record alignment
+    - perf intel-pt: Fix overlap calculation for padding
+    - perf/x86/intel/uncore: Fix client IMC events return huge result
+    - perf intel-pt: Fix divide by zero when TSC is not available
+    - md: Fix failed allocation of md_register_thread
+    - x86/kvmclock: set offset for kvm unstable clock
+    - x86/ftrace: Fix warning and considate ftrace_jmp_replace() and
+      ftrace_call_replace()
+    - tpm/tpm_crb: Avoid unaligned reads in crb_recv()
+    - tpm: Unify the send callback behaviour
+    - rcu: Do RCU GP kthread self-wakeup from softirq and interrupt
+    - media: imx: prpencvf: Stop upstream before disabling IDMA channel
+    - media: lgdt330x: fix lock status reporting
+    - media: sun6i: Fix CSI regmap's max_register
+    - media: uvcvideo: Avoid NULL pointer dereference at the end of streaming
+    - media: vimc: Add vimc-streamer for stream control
+    - media: imx-csi: Input connections to CSI should be optional
+    - media: imx: csi: Disable CSI immediately after last EOF
+    - media: imx: csi: Stop upstream before disabling IDMA channel
+    - drm/fb-helper: generic: Fix drm_fbdev_client_restore()
+    - drm/radeon/evergreen_cs: fix missing break in switch statement
+    - drm/amd/powerplay: correct power reading on fiji
+    - drm/amd/display: don't call dm_pp_ function from an fpu block
+    - KVM: Call kvm_arch_memslots_updated() before updating memslots
+    - KVM: VMX: Compare only a single byte for VMCS' "launched" in vCPU-run
+    - KVM: VMX: Zero out *all* general purpose registers after VM-Exit
+    - KVM: x86/mmu: Detect MMIO generation wrap in any address space
+    - KVM: x86/mmu: Do not cache MMIO accesses while memslots are in flux
+    - KVM: nVMX: Sign extend displacements of VMX instr's mem operands
+    - KVM: nVMX: Apply addr size mask to effective address for VMX instructions
+    - KVM: nVMX: Ignore limit checks on VMX instructions using flat segments
+    - KVM: nVMX: Check a single byte for VMCS "launched" in nested early checks
+    - net: dsa: lantiq_gswip: fix use-after-free on failed probe
+    - net: dsa: lantiq_gswip: fix OF child-node lookups
+    - s390/setup: fix boot crash for machine without EDAT-1
+    - SUNRPC: Prevent thundering herd when the socket is not connected
+    - SUNRPC: Fix up RPC back channel transmission
+    - SUNRPC: Respect RPC call timeouts when retrying transmission
+    - Linux 5.0.4
+    - [Config] update configs for 5.0.4 stable update
+
+  * New Intel Wireless-AC 9260 [8086:2526] card not correctly probed in Ubuntu
+    system (LP: #1821271)
+    - iwlwifi: add new card for 9260 series
+
+  * [CONFIG] please enable highdpi font FONT_TER16x32 (LP: #1819881)
+    - [Config]: enable highdpi Terminus 16x32 font support
+
+  * [SRU][B/B-OEM/C/D] Fix AMD IOMMU NULL dereference (LP: #1820990)
+    - iommu/amd: Fix NULL dereference bug in match_hid_uid
+
+  * some codecs stop working after S3 (LP: #1820930)
+    - ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec
+    - ALSA: hda - Don't trigger jackpoll_work in azx_resume
+
+  * tcm_loop.ko: move from modules-extra into main modules package
+    (LP: #1817786)
+    - [Packaging] move tcm_loop.lo to main linux-modules package
+
+  * C++ demangling support missing from perf (LP: #1396654)
+    - [Packaging] fix a mistype
+
+  * r8169 doesn't get woken up by ethernet cable plugging, no PME generated
+    (LP: #1817676)
+    - PCI: pciehp: Disable Data Link Layer State Changed event on suspend
+
+  * Disco update: v5.0.3 upstream stable release (LP: #1821074)
+    - connector: fix unsafe usage of ->real_parent
+    - fou, fou6: avoid uninit-value in gue_err() and gue6_err()
+    - gro_cells: make sure device is up in gro_cells_receive()
+    - ipv4/route: fail early when inet dev is missing
+    - l2tp: fix infoleak in l2tp_ip6_recvmsg()
+    - lan743x: Fix RX Kernel Panic
+    - lan743x: Fix TX Stall Issue
+    - net: hsr: fix memory leak in hsr_dev_finalize()
+    - net/hsr: fix possible crash in add_timer()
+    - net: sit: fix UBSAN Undefined behaviour in check_6rd
+    - net/x25: fix use-after-free in x25_device_event()
+    - net/x25: reset state in x25_connect()
+    - pptp: dst_release sk_dst_cache in pptp_sock_destruct
+    - ravb: Decrease TxFIFO depth of Q3 and Q2 to one
+    - route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race
+    - rxrpc: Fix client call queueing, waiting for channel
+    - sctp: remove sched init from sctp_stream_init
+    - tcp: do not report TCP_CM_INQ of 0 for closed connections
+    - tcp: Don't access TCP_SKB_CB before initializing it
+    - tcp: handle inet_csk_reqsk_queue_add() failures
+    - vxlan: Fix GRO cells race condition between receive and link delete
+    - vxlan: test dev->flags & IFF_UP before calling gro_cells_receive()
+    - net/mlx4_core: Fix reset flow when in command polling mode
+    - net/mlx4_core: Fix locking in SRIOV mode when switching between events and
+      polling
+    - net/mlx4_core: Fix qp mtt size calculation
+    - net: dsa: mv88e6xxx: Set correct interface mode for CPU/DSA ports
+    - vsock/virtio: fix kernel panic from virtio_transport_reset_no_sock
+    - net: sched: flower: insert new filter to idr after setting its mask
+    - f2fs: wait on atomic writes to count F2FS_CP_WB_DATA
+    - perf/x86: Fixup typo in stub functions
+    - ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against
+      Liquid Saffire 56
+    - ALSA: firewire-motu: fix construction of PCM frame for capture direction
+    - ALSA: hda: Extend i915 component bind timeout
+    - ALSA: hda - add more quirks for HP Z2 G4 and HP Z240
+    - ALSA: hda/realtek: Enable audio jacks of ASUS UX362FA with ALC294
+    - ALSA: hda/realtek - Reduce click noise on Dell Precision 5820 headphone
+    - ALSA: hda/realtek: Enable headset MIC of Acer TravelMate X514-51T with
+      ALC255
+    - perf/x86/intel: Fix memory corruption
+    - perf/x86/intel: Make dev_attr_allow_tsx_force_abort static
+    - It's wrong to add len to sector_nr in raid10 reshape twice
+    - drm: Block fb changes for async plane updates
+    - Linux 5.0.3
+
+  * Disco update: v5.0.2 upstream stable release (LP: #1820318)
+    - media: uvcvideo: Fix 'type' check leading to overflow
+    - Input: wacom_serial4 - add support for Wacom ArtPad II tablet
+    - Input: elan_i2c - add id for touchpad found in Lenovo s21e-20
+    - iscsi_ibft: Fix missing break in switch statement
+    - scsi: aacraid: Fix missing break in switch statement
+    - x86/PCI: Fixup RTIT_BAR of Intel Denverton Trace Hub
+    - arm64: dts: zcu100-revC: Give wifi some time after power-on
+    - arm64: dts: hikey: Give wifi some time after power-on
+    - arm64: dts: hikey: Revert "Enable HS200 mode on eMMC"
+    - ARM: dts: exynos: Fix pinctrl definition for eMMC RTSN line on Odroid X2/U3
+    - ARM: dts: exynos: Add minimal clkout parameters to Exynos3250 PMU
+    - ARM: dts: exynos: Fix max voltage for buck8 regulator on Odroid XU3/XU4
+    - drm: disable uncached DMA optimization for ARM and arm64
+    - media: Revert "media: rc: some events are dropped by userspace"
+    - Revert "PCI/PME: Implement runtime PM callbacks"
+    - bpf: Stop the psock parser before canceling its work
+    - gfs2: Fix missed wakeups in find_insert_glock
+    - staging: erofs: keep corrupted fs from crashing kernel in erofs_namei()
+    - staging: erofs: compressed_pages should not be accessed again after freed
+    - scripts/gdb: replace flags (MS_xyz -> SB_xyz)
+    - ath9k: Avoid OF no-EEPROM quirks without qca,no-eeprom
+    - perf/x86/intel: Make cpuc allocations consistent
+    - perf/x86/intel: Generalize dynamic constraint creation
+    - x86: Add TSX Force Abort CPUID/MSR
+    - perf/x86/intel: Implement support for TSX Force Abort
+    - Linux 5.0.2
+
+  * Linux security module stacking support
+    - LSM: Introduce LSM_FLAG_LEGACY_MAJOR
+    - LSM: Provide separate ordered initialization
+    - LSM: Plumb visibility into optional "enabled" state
+    - LSM: Lift LSM selection out of individual LSMs
+    - LSM: Build ordered list of LSMs to initialize
+    - LSM: Introduce CONFIG_LSM
+    - LSM: Introduce "lsm=" for boottime LSM selection
+    - LSM: Tie enabling logic to presence in ordered list
+    - LSM: Prepare for reorganizing "security=" logic
+    - LSM: Refactor "security=" in terms of enable/disable
+    - LSM: Separate idea of "major" LSM from "exclusive" LSM
+    - apparmor: Remove SECURITY_APPARMOR_BOOTPARAM_VALUE
+    - selinux: Remove SECURITY_SELINUX_BOOTPARAM_VALUE
+    - LSM: Add all exclusive LSMs to ordered initialization
+    - LSM: Split LSM preparation from initialization
+    - LoadPin: Initialize as ordered LSM
+    - Yama: Initialize as ordered LSM
+    - LSM: Introduce enum lsm_order
+    - capability: Initialize as LSM_ORDER_FIRST
+    - procfs: add smack subdir to attrs
+    - Smack: Abstract use of cred security blob
+    - SELinux: Abstract use of cred security blob
+    - SELinux: Remove cred security blob poisoning
+    - SELinux: Remove unused selinux_is_enabled
+    - AppArmor: Abstract use of cred security blob
+    - TOMOYO: Abstract use of cred security blob
+    - Infrastructure management of the cred security blob
+    - SELinux: Abstract use of file security blob
+    - Smack: Abstract use of file security blob
+    - LSM: Infrastructure management of the file security
+    - SELinux: Abstract use of inode security blob
+    - Smack: Abstract use of inode security blob
+    - LSM: Infrastructure management of the inode security
+    - LSM: Infrastructure management of the task security
+    - SELinux: Abstract use of ipc security blobs
+    - Smack: Abstract use of ipc security blobs
+    - LSM: Infrastructure management of the ipc security blob
+    - TOMOYO: Update LSM flags to no longer be exclusive
+    - LSM: generalize flag passing to security_capable
+    - LSM: Make lsm_early_cred() and lsm_early_task() local functions.
+    - LSM: Make some functions static
+    - apparmor: Adjust offset when accessing task blob.
+    - LSM: Ignore "security=" when "lsm=" is specified
+    - LSM: Update list of SECURITYFS users in Kconfig
+    - apparmor: delete the dentry in aafs_remove() to avoid a leak
+    - apparmor: fix double free when unpack of secmark rules fails
+    - SAUCE: LSM: Infrastructure management of the sock security
+    - SAUCE: LSM: Limit calls to certain module hooks
+    - SAUCE: LSM: Special handling for secctx lsm hooks
+    - SAUCE: LSM: Specify which LSM to display with /proc/self/attr/display
+    - SAUCE: Fix-up af_unix mediation for sock infrastructure management
+    - SAUCE: Revert "apparmor: Fix warning about unused function
+      apparmor_ipv6_postroute"
+    - SAUCE: Revert "apparmor: fix checkpatch error in Parse secmark policy"
+    - SAUCE: Revert "apparmor: add #ifdef checks for secmark filtering"
+    - SAUCE: Revert "apparmor: Allow filtering based on secmark policy"
+    - SAUCE: Revert "apparmor: Parse secmark policy"
+    - SAUCE: Revert "apparmor: Add a wildcard secid"
+    - SAUCE: Revert "apparmor: fix bad debug check in apparmor_secid_to_secctx()"
+    - SAUCE: Revert "apparmor: fixup secid map conversion to using IDR"
+    - SAUCE: Revert "apparmor: Use an IDR to allocate apparmor secids"
+    - SAUCE: Revert "apparmor: Fix memory leak of rule on error exit path"
+    - SAUCE: Revert "apparmor: modify audit rule support to support profile
+      stacks"
+    - SAUCE: Revert "apparmor: Add support for audit rule filtering"
+    - SAUCE: Revert "apparmor: add the ability to get a task's secid"
+    - SAUCE: Revert "apparmor: add support for mapping secids and using secctxes"
+    - SAUCE: apparmor: add proc subdir to attrs
+    - SAUCE: apparmor: add an apparmorfs entry to access current attrs
+    - SAUCE: apparmor: update flags to no longer be exclusive
+    - SAUCE: update configs and annotations for LSM stacking
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_EARLY_PRINTK_USB_XDBC=y
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - [Config] CONFIG_RANDOM_TRUST_CPU=y
+    - [Config] refresh annotations for recent config changes
+    - ubuntu: vbox -- update to 6.0.4-dfsg-7
+    - Revert "UBUNTU: SAUCE: i2c:amd I2C Driver based on PCI Interface for
+      upcoming platform"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 04 Apr 2019 14:49:59 -0500
+
+linux (5.0.0-8.9) disco; urgency=medium
+
+  * linux: 5.0.0-8.9 -proposed tracker (LP: #1819759)
+
+  * hisi_sas: add debugfs support (LP: #1819500)
+    - scsi: hisi_sas: Create root and device debugfs directories
+    - scsi: hisi_sas: Alloc debugfs snapshot buffer memory for all registers
+    - scsi: hisi_sas: Take debugfs snapshot for all regs
+    - scsi: hisi_sas: Debugfs global register create file and add file operations
+    - scsi: hisi_sas: Add debugfs for port registers
+    - scsi: hisi_sas: Add debugfs CQ file and add file operations
+    - scsi: hisi_sas: Add debugfs DQ file and add file operations
+    - scsi: hisi_sas: Add debugfs IOST file and add file operations
+    - scsi: hisi_sas: No need to check return value of debugfs_create functions
+    - scsi: hisi_sas: Fix type casting and missing static qualifier in debugfs
+      code
+    - scsi: hisi_sas: Add debugfs ITCT file and add file operations
+
+  * [disco] hns driver updates from 5.1 merge window (LP: #1819535)
+    - net: hns: Use struct_size() in devm_kzalloc()
+    - net: hns3: modify enet reinitialization interface
+    - net: hns3: remove unused member in struct hns3_enet_ring
+    - net: hns3: remove unnecessary hns3_adjust_tqps_num
+    - net: hns3: reuse reinitialization interface in the hns3_set_channels
+    - net: hns3: add interface hclge_tm_bp_setup
+    - net: hns3: modify parameter checks in the hns3_set_channels
+    - net: hns3: remove redundant codes in hclge_knic_setup
+    - net: hns3: fix user configuration loss for ethtool -L
+    - net: hns3: adjust the use of alloc_tqps and num_tqps
+    - net: hns3: fix wrong combined count returned by ethtool -l
+    - net: hns3: do reinitialization while ETS configuration changed
+    - net: hns3: add HNAE3_RESTORE_CLIENT interface in enet module
+    - net: hns3: add calling roce callback function when link status change
+    - net: hns3: add rx multicast packets statistic
+    - net: hns3: refactor the statistics updating for netdev
+    - net: hns3: fix rss configuration lost problem when setting channel
+    - net: hns3: fix for shaper not setting when TC num changes
+    - net: hns3: fix bug of ethtool_ops.get_channels for VF
+    - net: hns3: clear param in ring when free ring
+    - net: hns3: Change fw error code NOT_EXEC to NOT_SUPPORTED
+    - net: hns3: do not return GE PFC setting err when initializing
+    - net: hns3: add ETS TC weight setting in SSU module
+    - net: hns3: add statistics for PFC frames and MAC control frames
+    - net: hns3: fix PFC not setting problem for DCB module
+    - net: hns3: don't update packet statistics for packets dropped by hardware
+    - net: hns3: clear pci private data when unload hns3 driver
+    - net: hns3: add error handling in hclge_ieee_setets
+    - net: hns3: fix return value handle issue for hclge_set_loopback()
+    - net: hns3: fix broadcast promisc issue for revision 0x20
+    - net: hns3: After setting the loopback, add the status of getting MAC
+    - net: hns3: do reinitialization while mqprio configuration changed
+    - net: hns3: remove dcb_ops->map_update in hclge_dcb
+    - net: hns3: call hns3_nic_set_real_num_queue with netdev down
+    - net: hns3: add 8 BD limit for tx flow
+    - net: hns3: add initialization for nic state
+    - net: hns3: don't allow vf to enable promisc mode
+    - net: hns3: reuse the definition of l3 and l4 header info union
+    - net: hns3: fix VF dump register issue
+    - net: hns3: use the correct interface to stop|open port
+    - net: hns3: change hnae3_register_ae_dev() to int
+    - net: hns3: only support tc 0 for VF
+    - net: hns3: Fix NULL deref when unloading driver
+    - net: hns3: fix netif_napi_del() not do problem when unloading
+    - net: hns3: fix for rss result nonuniform
+    - net: hns3: fix improper error handling in the hclge_init_ae_dev()
+    - net: hns3: fix an issue for hclgevf_ae_get_hdev
+    - net: hns3: stop sending keep alive msg to PF when VF is resetting
+    - net: hns3: keep flow director state unchanged when reset
+    - net: hns3: Check for allocation failure
+    - net: hns3: fix a code style issue for hns3_update_new_int_gl()
+    - net: hns3: fix an issue for hns3_update_new_int_gl
+    - net: hns3: Modify parameter type from int to bool in set_gro_en
+    - net: hns3: code optimization for hclge_rx_buffer_calc
+    - net: hns3: add hclge_cmd_check_retval() to parse comman's return value
+    - net: hns3: move some set_bit statement into hclge_prepare_mac_addr
+    - net: hns3: fix a wrong checking in the hclge_tx_buffer_calc()
+    - net: hns3: fix the problem that the supported port is empty
+    - net: hns3: optimize the maximum TC macro
+    - net: hns3: don't allow user to change vlan filter state
+    - net: hns3: modify the upper limit judgment condition
+    - net: hns3: MAC table entry count function increases operation 0 value
+      protection measures
+    - net: hns3: make function hclge_set_all_vf_rst() static
+    - net: hns3: add pointer checking at the beginning of the exported functions.
+    - net: hns3: Check variable is valid before assigning it to another
+    - net: hns3: convert mac advertize and supported from u32 to link mode
+    - net: hns3: fix port info query issue for copper port
+    - net: hns3: modify print message of ssu common ecc errors
+    - net: hns3: some bugfix of ppu(rcb) ras errors
+    - net: hns3: enable 8~11th bit of mac common msi-x error
+    - net: hns3: fix 6th bit of ppp mpf abnormal errors
+    - net: hns3: Record VF unicast and multicast tables
+    - net: hns3: Record VF vlan tables
+    - net: hns3: uninitialize command queue while unloading PF driver
+    - net: hns3: clear command queue's registers when unloading VF driver
+    - net: hns3: add xps setting support for hns3 driver
+    - net: hns3: avoid mult + div op in critical data path
+    - net: hns3: limit some variable scope in critical data path
+    - net: hns3: remove some ops in struct hns3_nic_ops
+    - net: hns3: add unlikely for error handling in data path
+    - net: hns3: replace hnae3_set_bit and hnae3_set_field in data path
+    - net: hns3: remove hnae3_get_bit in data path
+    - net: hns3: add support to config depth for tx|rx ring separately
+    - net: hns3: enable VF VLAN filter for each VF when initializing
+    - net: hns3: fix get VF RSS issue
+    - net: hns3: fix setting of the hns reset_type for rdma hw errors
+    - net: hns3: fix improper error handling for hns3_client_start
+    - net: hns: use struct_size() in devm_kzalloc()
+    - net: hns3: Fix a logical vs bitwise typo
+    - net: hns3: add dma_rmb() for rx description
+    - net: hns3: fix to stop multiple HNS reset due to the AER changes
+
+  * Build Nvidia drivers in conjunction with kernel (LP: #1764792)
+    - [Packaging] dkms-build -- support building against packages in PPAs
+    - [Packaging] dkms-build: do not redownload files on subsequent passes
+    - [Packaging] dkms-build -- elide partial Built-Using information
+    - [Packaging] dkms-build -- remove retpoline data from final binary packages
+    - [Packaging] dkms-build--nvidia* -- check gcc version against primary build
+    - [Packaging] dkms-build -- add support for unversioned overrides
+    - [Packaging] dkms-build--nvidia-* -- convert to generic -N form
+    - [Packaging] fix-filenames -- handle exact string removal
+    - [Packaging] dkms-build--nvidia-N -- remove GCC versions
+
+  * Disco update: v5.0.1 upstream stable release (LP: #1819515)
+    - cpufreq: Use struct kobj_attribute instead of struct global_attr
+    - staging: erofs: fix mis-acted TAIL merging behavior
+    - binder: create node flag to request sender's security context
+    - USB: serial: option: add Telit ME910 ECM composition
+    - USB: serial: cp210x: add ID for Ingenico 3070
+    - USB: serial: ftdi_sio: add ID for Hjelmslund Electronics USB485
+    - driver core: Postpone DMA tear-down until after devres release
+    - staging: erofs: fix fast symlink w/o xattr when fs xattr is on
+    - staging: erofs: fix memleak of inode's shared xattr array
+    - staging: erofs: fix race of initializing xattrs of a inode at the same time
+    - staging: erofs: fix illegal address access under memory pressure
+    - staging: comedi: ni_660x: fix missing break in switch statement
+    - staging: wilc1000: fix to set correct value for 'vif_num'
+    - staging: android: ion: fix sys heap pool's gfp_flags
+    - staging: android: ashmem: Don't call fallocate() with ashmem_mutex held.
+    - staging: android: ashmem: Avoid range_alloc() allocation with ashmem_mutex
+      held.
+    - ip6mr: Do not call __IP6_INC_STATS() from preemptible context
+    - net: dsa: mv88e6xxx: add call to mv88e6xxx_ports_cmode_init to probe for new
+      DSA framework
+    - net: dsa: mv88e6xxx: handle unknown duplex modes gracefully in
+      mv88e6xxx_port_set_duplex
+    - net: dsa: mv8e6xxx: fix number of internal PHYs for 88E6x90 family
+    - net: mscc: Enable all ports in QSGMII
+    - net: sched: put back q.qlen into a single location
+    - net-sysfs: Fix mem leak in netdev_register_kobject
+    - qmi_wwan: Add support for Quectel EG12/EM12
+    - sctp: call iov_iter_revert() after sending ABORT
+    - team: Free BPF filter when unregistering netdev
+    - tipc: fix RDM/DGRAM connect() regression
+    - x86/CPU/AMD: Set the CPB bit unconditionally on F17h
+    - x86/boot/compressed/64: Do not read legacy ROM on EFI system
+    - tracing: Fix event filters and triggers to handle negative numbers
+    - xhci: tegra: Prevent error pointer dereference
+    - usb: xhci: Fix for Enabling USB ROLE SWITCH QUIRK on
+      INTEL_SUNRISEPOINT_LP_XHCI
+    - applicom: Fix potential Spectre v1 vulnerabilities
+    - alpha: wire up io_pgetevents system call
+    - MIPS: irq: Allocate accurate order pages for irq stack
+    - aio: Fix locking in aio_poll()
+    - xtensa: fix get_wchan
+    - gnss: sirf: fix premature wakeup interrupt enable
+    - USB: serial: cp210x: fix GPIO in autosuspend
+    - Revert "selftests: firmware: add CONFIG_FW_LOADER_USER_HELPER_FALLBACK to
+      config"
+    - Revert "selftests: firmware: remove use of non-standard diff -Z option"
+    - selftests: firmware: fix verify_reqs() return value
+    - Bluetooth: btrtl: Restore old logic to assume firmware is already loaded
+    - Bluetooth: Fix locking in bt_accept_enqueue() for BH context
+    - Linux 5.0.1
+
+  * sky2 ethernet card doesn't work after returning from suspend
+    (LP: #1807259) // sky2 ethernet card link not up after suspend
+    (LP: #1809843) // Disco update: v5.0.1 upstream stable release
+    (LP: #1819515)
+    - sky2: Disable MSI on Dell Inspiron 1545 and Gateway P-79
+
+  * tls selftest failures/hangs on i386 (LP: #1813607)
+    - [Config] CONFIG_TLS=n for i386
+
+  * CVE-2019-8980
+    - exec: Fix mem leak in kernel_read_file
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: net: Use 'ipproto ipv6-icmp' to match ICMPv6 headers
+    - [Config] enable nvidia build
+    - [Config] update gcc version to 8.3
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: selftests: pmtu: disable accept_dad for tests"
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Tue, 12 Mar 2019 16:15:44 -0300
+
+linux (5.0.0-7.8) disco; urgency=medium
+
+  * linux: 5.0.0-7.8 -proposed tracker (LP: #1818519)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * unnecessary request_queue freeze (LP: #1815733)
+    - block: avoid setting nr_requests to current value
+    - block: avoid setting none scheduler if it's already none
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: net: Don't fail test_vxlan_under_vrf on xfail
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 04 Mar 2019 08:46:10 -0600
+
+linux (5.0.0-6.7) disco; urgency=medium
+
+  * linux: 5.0.0-6.7 -proposed tracker (LP: #1817585)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - [Packaging] resync getabis
+
+  * installer does not support iSCSI iBFT (LP: #1817321)
+    - d-i: add iscsi_ibft to scsi-modules
+
+  * Silent "Unknown key" message when pressing keyboard backlight hotkey
+    (LP: #1817063)
+    - platform/x86: dell-wmi: Ignore new keyboard backlight change event
+
+  * Fix I219 doesn't get woken up after plugging ethernet cable (LP: #1817058)
+    - e1000e: Disable runtime PM on CNP+
+
+  * efi/arm/arm64: Allow SetVirtualAddressMap() to be omitted (LP: #1814982)
+    - efi/arm/arm64: Allow SetVirtualAddressMap() to be omitted
+
+  * CVE-2019-3460
+    - Bluetooth: Check L2CAP option sizes returned from l2cap_get_conf_opt
+
+  * CVE-2019-3459
+    - Bluetooth: Verify that l2cap_get_conf_opt provides large enough buffer
+
+  * kernel net tls selftest fails on 5.0 (LP: #1816716)
+    - SAUCE: Revert "selftests/tls: Add test for recv(PEEK) spanning across
+      multiple records"
+
+  * Please enable CONFIG_DMA_CMA=y on arm64 (LP: #1803206)
+    - [Config] annotations -- enforce CONFIG_DMA_CMA and update notes
+
+  * [19.04 FEAT] [LS1801] PCI Virtual function enablement (LP: #1814684)
+    - s390/pci: map IOV resources
+    - s390/pci: improve bar check
+
+  * glibc 2.28-0ubuntu1 ADT test failure with linux 5.0.0-1.2 (LP: #1813060)
+    - SAUCE: prevent a glibc test failure when looking for obsolete types on
+      headers
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Enforce CONFIG_ZCRYPT_MULTIDEVNODES in annotations
+    - SAUCE: selftests: pmtu: disable accept_dad for tests
+    - SAUCE: arm64: add kernel config option to lock down when in Secure Boot mode
+    - SAUCE: selftests: net: Make test for VXLAN underlay in non-default VRF an
+      expected failure
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 25 Feb 2019 09:37:36 -0600
+
+linux (5.0.0-5.6) disco; urgency=medium
+
+  * [ALSA] [PATCH] System76 darp5 and oryp5 fixups (LP: #1815831)
+    - ALSA: hda/realtek - Headset microphone and internal speaker support for
+      System76 oryp5
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Fix aufs menus in annotations file
+    - [Config] CONFIG_SAMPLE_TRACE_PRINTK=m
+    - [Config] Update annotations based on configs
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 18 Feb 2019 10:04:11 +0100
+
+linux (5.0.0-4.5) disco; urgency=medium
+
+  * linux-buildinfo: pull out ABI information into its own package
+    (LP: #1806380)
+    - [Packaging] autoreconstruct -- base tag is always primary mainline version
+
+  * [Packaging] Allow overlay of config annotations (LP: #1752072)
+    - [Packaging] config-check: Add an include directive
+
+  * Miscellaneous Ubuntu changes
+    - hio -- stub out BIOVEC_PHYS_MERGEABLE for 4.20+
+    - hio -- replace use of do_gettimeofday()
+    - hio -- part_round_stats() removed in 5.0
+    - hio -- device_add_disk() grew a 'groups' argument in 4.20
+    - enable hio build
+    - Revert "UBUNTU: [Packaging] autoreconstruct -- base tag is always primary
+      mainline version"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 12 Feb 2019 08:15:32 -0600
+
+linux (5.0.0-3.4) disco; urgency=medium
+
+  * CONFIG_TEST_BPF is disabled (LP: #1813955)
+    - [Config]: Reenable TEST_BPF
+
+  * Ignore "incomplete report" from Elan touchpanels (LP: #1813733)
+    - HID: i2c-hid: Ignore input report if there's no data present on Elan
+      touchpanels
+
+  * SecureBoot support for arm64 (LP: #1804481)
+    - Build signed kernels for arm64
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: net: fix "from" match test in fib_rule_tests.sh
+    - [Config] CONFIG_PCMCIA=n for arm64 and s390x
+    - [Config] CONFIG_SERIAL_SC16IS7XX=n for s390x
+    - [Config] disable I2C TPM drivers for s390x
+    - [Config] CONFIG_RAPIDIO=n for s390x
+    - [Config] CONFIG_DMADEVICES=n for s390x
+    - [Config] disable gpio drivers for s390x
+    - [Config] CONFIG_SENSORS_OCC_P8_I2C=m for ppc64el
+    - [Config] disable I2C hardware drivers for s390x
+    - [Config] CONFIG_I3C=n for s390x
+    - [Config] CONFIG_SERIO=n for s390x
+    - [Config] disable misc drivers for s390x
+    - [Config] disable EEPROM drivers for s390x
+    - [Config] disable MFD drivers for s390x
+    - [Config] CONFIG_NVMEM=n for s390x
+    - [Config] CONFIG_MLXSW_I2C=n for s390x
+    - [Config] CONFIG_NET_VENDOR_MICROCHIP=n for s390x
+    - [Config] CONFIG_PPP=n for s390x
+    - [Config] CONFIG_PCCARD=n for s390x
+    - [Config] CONFIG_PCI_MESON=y
+    - [Config] CONFIG_SCSI_MYRB=n for s390x
+    - [Config] CONFIG_REGULATOR=n for s390x
+    - [Config] CONFIG_ZIIRAVE_WATCHDOG=n for s390x
+    - [Config] CONFIG_NCSI_OEM_CMD_GET_MAC=y
+    - [Config] update annotations following config review
+    - [Packaging] remove handoff check for uefi signing
+    - [Packaging] decompress gzipped efi images in signing tarball
+    - vbox-update: allow leading whitespace when fixing up KERN_DIR
+    - ubuntu: vbox -- update to 6.0.4-dfsg-3
+    - vbox: remove remount check in sf_read_super_aux()
+    - enable vbox build
+    - [Config] CONFIG_ANDROID_BINDER_DEVICES=""
+    - SAUCE: import aufs driver
+    - [Config]: Enable aufs
+    - [Config] relocate aufs annotations to menu
+    - [Config] remove unmatched configs from annotations
+    - [Config] fix up abi for removed modules
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) module: remove support for having IMA validate modules
+    - SAUCE: (efi-lockdown) Move EFI signature blob parser to shared location
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - [Config] (efi-lockdown) enable importing of efi certificates for module sig
+      verification
+
+  * Miscellaneous upstream changes
+    - binder: fix CONFIG_ANDROID_BINDER_DEVICES
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 05 Feb 2019 14:26:12 -0600
+
+linux (5.0.0-2.3) disco; urgency=medium
+
+  * kernel oops in bcache module (LP: #1793901)
+    - SAUCE: bcache: never writeback a discard operation
+
+  * Enable sound card power saving by default (LP: #1804265)
+    - [Config] CONFIG_SND_HDA_POWER_SAVE_DEFAULT=1
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: selftests: disable some failing networking tests"
+    - SAUCE: ashmem: turn into module
+    - SAUCE: binder: turn into module
+    - SAUCE: binder: give binder_alloc its own debug mask file
+    - [Config] enable binder and ashmem as modules
+    - SAUCE: selftests: net: replace AF_MAX with INT_MAX in socket.c
+    - SAUCE: selftests/ftrace: Fix tab expansion in trace_marker snapshot trigger
+      test
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 29 Jan 2019 06:57:32 -0600
+
+linux (5.0.0-1.2) disco; urgency=medium
+
+  * Fix non-working QCA Rome Bluetooth after S3 (LP: #1812812)
+    - USB: Add new USB LPM helpers
+    - USB: Consolidate LPM checks to avoid enabling LPM twice
+
+  * bluetooth controller not detected with 4.15 kernel (LP: #1810797)
+    - SAUCE: btqcomsmd: introduce BT_QCOMSMD_HACK
+    - [Config] arm64: snapdragon: BT_QCOMSMD_HACK=y
+
+  * [19.04 FEAT| Enable virtio-gpu for s390x (LP: #1799467)
+    - [Config] enable virtio-gpu for s390x
+
+  * Crash on "ip link add foo type ipip" (LP: #1811803)
+    - SAUCE: fan: Fix NULL pointer dereference
+
+  * Fix not working Goodix touchpad (LP: #1811929)
+    - HID: i2c-hid: Disable runtime PM on Goodix touchpad
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - enable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 22 Jan 2019 13:56:17 -0600
+
+linux (5.0.0-0.1) disco; urgency=medium
+
+  * Build Nvidia drivers in conjunction with kernel (LP: #1764792)
+    - [Packaging] dkms -- add per package post-process step
+    - [Packaging] dkms -- switch to a consistent build prefix length and strip
+    - [Packaging] nvidia -- build and sign nvidia packages and ship signatures
+    - [Packaging] nvidia -- make nvidia package version explicit
+
+  * Add support for ALC3277 codec on new Dell edge gateways (LP: #1807334)
+    - [Config] CONFIG_SND_SOC_INTEL_KBL_RT5660_MACH=m
+
+  * RTL8822BE WiFi Disabled in Kernel 4.18.0-12 (LP: #1806472)
+    - [Config] CONFIG_RTLWIFI_DEBUG_ST=n
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu -- disable vbox build
+    - ubuntu -- disable hio build
+    - Disable zfs build
+    - SAUCE: import aufs driver
+    - update dkms package versions
+    - [Config] disable aufs config options
+    - [Config] disable nvidia build
+    - update dropped.txt
+    - [Packaging] disable nvidia dkms builds for mainline
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation
+      defined
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - [Config] set config options for efi lockdown
+    - Revert "UBUNTU: SAUCE: import aufs driver"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 17 Jan 2019 12:31:29 -0600
+
+linux (5.0.0-0.0) disco; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 16 Jan 2019 14:48:05 -0600
+
+linux (4.20.0-2.3) disco; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.20
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 03 Jan 2019 12:11:43 -0600
+
+linux (4.20.0-1.2) disco; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Power leakage at S5 with Qualcomm Atheros QCA9377 802.11ac Wireless Network
+    Adapter (LP: #1805607)
+    - SAUCE: ath10k: provide reset function for QCA9377 chip
+
+  * zfs/spl build in conjunction with the kernel from DKMS source (LP: #1807378)
+    - [Packaging] dkms -- dkms package build packaging support
+    - [Packaging] dkms -- save build objects artifacts for validation
+    - [Packaging] dkms -- add general Built-Using: support
+    - [Packaging] simplify Provides comma handling
+    - [Packaging] zfs/spl -- remove packaging support for incorporated source
+    - [Packaging] zfs/spl -- remove incorporated source
+    - [Packaging] zfs/spl -- build via dkms
+    - [Packaging] zfs/spl -- make zfs package version explicit
+    - [Packaging] update-version-dkms -- sync archive versions to package
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] update-version-dkms -- fix getting distrbution from changelog
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.20-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 11 Dec 2018 11:33:08 -0600
+
+linux (4.20.0-0.1) disco; urgency=medium
+
+  * Overlayfs in user namespace leaks directory content of inaccessible
+    directories (LP: #1793458) // CVE-2018-6559
+    - Revert "ovl: relax permission checking on underlying layers"
+    - SAUCE: overlayfs: ensure mounter privileges when reading directories
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) efi: Add EFI signature data types
+    - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) Fix for module sig verification
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: Import aufs driver
+    - ubuntu: vbox -- update to 5.2.22-dfsg-2
+    - ubuntu -- disable vbox build
+    - ubuntu -- disable hio build
+    - Disable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.20-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 07 Dec 2018 07:13:42 -0600
+
+linux (4.20.0-0.0) disco; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 06 Dec 2018 10:20:19 -0600
+
+linux (4.19.0-8.9) disco; urgency=medium
+
+  * linux: 4.19.0-8.9 -proposed tracker (LP: #1806952)
+
+  * Workaround CSS timeout on AMD SNPS 3.0 xHC (LP: #1806838)
+    - xhci: workaround CSS timeout on AMD SNPS 3.0 xHC
+
+  * Fix Intel I210 doesn't work when ethernet cable gets plugged (LP: #1806818)
+    - igb: Fix an issue that PME is not enabled during runtime suspend
+
+  * The line-out on the Dell Dock station can't work (LP: #1806532)
+    - ALSA: usb-audio: Add vendor and product name for Dell WD19 Dock
+
+  * CVE-2018-19407
+    - KVM: X86: Fix scan ioapic use-before-initialization
+
+  * PC SN720 NVMe WDC 256GB consumes more power in S2Idle than during long idle
+    (LP: #1805775)
+    - SAUCE: pci/nvme: prevent WDC PC SN720 NVMe from entering D3 and being
+      disabled
+
+  * Disco update: 4.19.6 upstream stable release (LP: #1806909)
+    - HID: steam: remove input device when a hid client is running.
+    - efi/libstub: arm: support building with clang
+    - usb: core: Fix hub port connection events lost
+    - usb: dwc3: gadget: fix ISOC TRB type on unaligned transfers
+    - usb: dwc3: gadget: Properly check last unaligned/zero chain TRB
+    - usb: dwc3: core: Clean up ULPI device
+    - usb: dwc3: Fix NULL pointer exception in dwc3_pci_remove()
+    - xhci: Fix leaking USB3 shared_hcd at xhci removal
+    - xhci: handle port status events for removed USB3 hcd
+    - xhci: Add check for invalid byte size error when UAS devices are connected.
+    - usb: xhci: fix uninitialized completion when USB3 port got wrong status
+    - usb: xhci: fix timeout for transition from RExit to U0
+    - xhci: Add quirk to workaround the errata seen on Cavium Thunder-X2 Soc
+    - usb: xhci: Prevent bus suspend if a port connect change or polling state is
+      detected
+    - ALSA: oss: Use kvzalloc() for local buffer allocations
+    - MAINTAINERS: Add Sasha as a stable branch maintainer
+    - Documentation/security-bugs: Clarify treatment of embargoed information
+    - Documentation/security-bugs: Postpone fix publication in exceptional cases
+    - mmc: sdhci-pci: Try "cd" for card-detect lookup before using NULL
+    - mmc: sdhci-pci: Workaround GLK firmware failing to restore the tuning value
+    - gpio: don't free unallocated ida on gpiochip_add_data_with_key() error path
+    - iwlwifi: fix wrong WGDS_WIFI_DATA_SIZE
+    - iwlwifi: mvm: support sta_statistics() even on older firmware
+    - iwlwifi: mvm: fix regulatory domain update when the firmware starts
+    - iwlwifi: mvm: don't use SAR Geo if basic SAR is not used
+    - brcmfmac: fix reporting support for 160 MHz channels
+    - opp: ti-opp-supply: Dynamically update u_volt_min
+    - opp: ti-opp-supply: Correct the supply in _get_optimal_vdd_voltage call
+    - tools/power/cpupower: fix compilation with STATIC=true
+    - v9fs_dir_readdir: fix double-free on p9stat_read error
+    - selinux: Add __GFP_NOWARN to allocation at str_read()
+    - Input: synaptics - avoid using uninitialized variable when probing
+    - bfs: add sanity check at bfs_fill_super()
+    - sctp: clear the transport of some out_chunk_list chunks in
+      sctp_assoc_rm_peer
+    - gfs2: Don't leave s_fs_info pointing to freed memory in init_sbd
+    - llc: do not use sk_eat_skb()
+    - mm: don't warn about large allocations for slab
+    - mm/memory.c: recheck page table entry with page table lock held
+    - tcp: do not release socket ownership in tcp_close()
+    - drm/fb-helper: Blacklist writeback when adding connectors to fbdev
+    - drm/amdgpu: Add missing firmware entry for HAINAN
+    - drm/vc4: Set ->legacy_cursor_update to false when doing non-async updates
+    - drm/amdgpu: Fix oops when pp_funcs->switch_power_profile is unset
+    - drm/i915: Disable LP3 watermarks on all SNB machines
+    - drm/ast: change resolution may cause screen blurred
+    - drm/ast: fixed cursor may disappear sometimes
+    - drm/ast: Remove existing framebuffers before loading driver
+    - can: flexcan: Unlock the MB unconditionally
+    - can: dev: can_get_echo_skb(): factor out non sending code to
+      __can_get_echo_skb()
+    - can: dev: __can_get_echo_skb(): replace struct can_frame by canfd_frame to
+      access frame length
+    - can: dev: __can_get_echo_skb(): Don't crash the kernel if can_priv::echo_skb
+      is accessed out of bounds
+    - can: dev: __can_get_echo_skb(): print error message, if trying to echo non
+      existing skb
+    - can: rx-offload: introduce can_rx_offload_get_echo_skb() and
+      can_rx_offload_queue_sorted() functions
+    - can: rx-offload: rename can_rx_offload_irq_queue_err_skb() to
+      can_rx_offload_queue_tail()
+    - can: flexcan: use can_rx_offload_queue_sorted() for flexcan_irq_bus_*()
+    - can: flexcan: handle tx-complete CAN frames via rx-offload infrastructure
+    - can: raw: check for CAN FD capable netdev in raw_sendmsg()
+    - can: hi311x: Use level-triggered interrupt
+    - can: flexcan: Always use last mailbox for TX
+    - can: flexcan: remove not needed struct flexcan_priv::tx_mb and struct
+      flexcan_priv::tx_mb_idx
+    - ACPICA: AML interpreter: add region addresses in global list during
+      initialization
+    - IB/hfi1: Eliminate races in the SDMA send error path
+    - fsnotify: generalize handling of extra event flags
+    - fanotify: fix handling of events on child sub-directory
+    - pinctrl: meson: fix pinconf bias disable
+    - pinctrl: meson: fix gxbb ao pull register bits
+    - pinctrl: meson: fix gxl ao pull register bits
+    - pinctrl: meson: fix meson8 ao pull register bits
+    - pinctrl: meson: fix meson8b ao pull register bits
+    - tools/testing/nvdimm: Fix the array size for dimm devices.
+    - scsi: lpfc: fix remoteport access
+    - scsi: hisi_sas: Remove set but not used variable 'dq_list'
+    - KVM: PPC: Move and undef TRACE_INCLUDE_PATH/FILE
+    - cpufreq: imx6q: add return value check for voltage scale
+    - rtc: cmos: Do not export alarm rtc_ops when we do not support alarms
+    - rtc: pcf2127: fix a kmemleak caused in pcf2127_i2c_gather_write
+    - crypto: simd - correctly take reqsize of wrapped skcipher into account
+    - floppy: fix race condition in __floppy_read_block_0()
+    - powerpc/io: Fix the IO workarounds code to work with Radix
+    - sched/fair: Fix cpu_util_wake() for 'execl' type workloads
+    - perf/x86/intel/uncore: Add more IMC PCI IDs for KabyLake and CoffeeLake CPUs
+    - block: copy ioprio in __bio_clone_fast() and bounce
+    - SUNRPC: Fix a bogus get/put in generic_key_to_expire()
+    - riscv: add missing vdso_install target
+    - RISC-V: Silence some module warnings on 32-bit
+    - drm/amdgpu: fix bug with IH ring setup
+    - kdb: Use strscpy with destination buffer size
+    - NFSv4: Fix an Oops during delegation callbacks
+    - powerpc/numa: Suppress "VPHN is not supported" messages
+    - efi/arm: Revert deferred unmap of early memmap mapping
+    - z3fold: fix possible reclaim races
+    - mm, memory_hotplug: check zone_movable in has_unmovable_pages
+    - tmpfs: make lseek(SEEK_DATA/SEK_HOLE) return ENXIO with a negative offset
+    - mm, page_alloc: check for max order in hot path
+    - dax: Avoid losing wakeup in dax_lock_mapping_entry
+    - include/linux/pfn_t.h: force '~' to be parsed as an unary operator
+    - tty: wipe buffer.
+    - tty: wipe buffer if not echoing data
+    - gfs2: Fix iomap buffer head reference counting bug
+    - rcu: Make need_resched() respond to urgent RCU-QS needs
+    - media: ov5640: Re-work MIPI startup sequence
+    - media: ov5640: Fix timings setup code
+    - media: ov5640: fix exposure regression
+    - media: ov5640: fix auto gain & exposure when changing mode
+    - media: ov5640: fix wrong binning value in exposure calculation
+    - media: ov5640: fix auto controls values when switching to manual mode
+    - Linux 4.19.6
+
+  * linux-buildinfo: pull out ABI information into its own package
+    (LP: #1806380)
+    - [Packaging] limit preparation to linux-libc-dev in headers
+    - [Packaging] commonise debhelper invocation
+    - [Packaging] ABI -- accumulate abi information at the end of the build
+    - [Packaging] buildinfo -- add basic build information
+    - [Packaging] buildinfo -- add firmware information to the flavour ABI
+    - [Packaging] buildinfo -- add compiler information to the flavour ABI
+    - [Packaging] buildinfo -- add buildinfo support to getabis
+    - [Packaging] getabis -- handle all known package combinations
+    - [Packaging] getabis -- support parsing a simple version
+
+  * linux packages should own /usr/lib/linux/triggers (LP: #1770256)
+    - [Packaging] own /usr/lib/linux/triggers
+
+  * Miscellaneous upstream changes
+    - blk-mq: fix corruption with direct issue
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 05 Dec 2018 09:18:30 -0600
+
+linux (4.19.0-7.8) disco; urgency=medium
+
+  * linux: 4.19.0-7.8 -proposed tracker (LP: #1805465)
+
+  * Fix and issue that LG I2C touchscreen stops working after reboot
+    (LP: #1805085)
+    - HID: i2c-hid: Disable runtime PM for LG touchscreen
+
+  * click/pop noise in the headphone on several lenovo laptops (LP: #1805079) //
+    click/pop noise in the headphone on several lenovo laptops (LP: #1805079)
+    - ALSA: hda/realtek - fix the pop noise on headphone for lenovo laptops
+
+  * Regression: hinic performance degrades over time (LP: #1805248)
+    - Revert "net-next/hinic: add checksum offload and TSO support"
+
+  * Disco update: 4.19.5 upstream stable release (LP: #1805461)
+    - drm/i915: Replace some PAGE_SIZE with I915_GTT_PAGE_SIZE
+    - cifs: don't dereference smb_file_target before null check
+    - cifs: fix return value for cifs_listxattr
+    - arm64: kprobe: make page to RO mode when allocate it
+    - block: brd: associate with queue until adding disk
+    - net: hns3: bugfix for rtnl_lock's range in the hclgevf_reset()
+    - net: hns3: bugfix for rtnl_lock's range in the hclge_reset()
+    - net: hns3: bugfix for handling mailbox while the command queue reinitialized
+    - net: hns3: bugfix for the initialization of command queue's spin lock
+    - ixgbe: fix MAC anti-spoofing filter after VFLR
+    - reiserfs: propagate errors from fill_with_dentries() properly
+    - hfs: prevent btree data loss on root split
+    - hfsplus: prevent btree data loss on root split
+    - perf unwind: Take pgoff into account when reporting elf to libdwfl
+    - um: Give start_idle_thread() a return code
+    - drm/edid: Add 6 bpc quirk for BOE panel.
+    - afs: Handle EIO from delivery function
+    - platform/x86: intel_telemetry: report debugfs failure
+    - clk: fixed-rate: fix of_node_get-put imbalance
+    - perf symbols: Set PLT entry/header sizes properly on Sparc
+    - fs/exofs: fix potential memory leak in mount option parsing
+    - clk: samsung: exynos5420: Enable PERIS clocks for suspend
+    - apparmor: Fix uninitialized value in aa_split_fqname
+    - x86/earlyprintk: Add a force option for pciserial device
+    - platform/x86: acerhdf: Add BIOS entry for Gateway LT31 v1.3307
+    - clk: meson-axg: pcie: drop the mpll3 clock parent
+    - arm64: percpu: Initialize ret in the default case
+    - clk: meson: clk-pll: drop CLK_GET_RATE_NOCACHE where unnecessary
+    - clk: renesas: r9a06g032: Fix UART34567 clock rate
+    - clk: ti: fix OF child-node lookup
+    - serial: sh-sci: Fix receive on SCIFA/SCIFB variants with DMA
+    - netfilter: ipv6: fix oops when defragmenting locally generated fragments
+    - netfilter: bridge: define INT_MIN & INT_MAX in userspace
+    - s390/decompressor: add missing FORCE to build targets
+    - s390/vdso: add missing FORCE to build targets
+    - HID: i2c-hid: Add a small delay after sleep command for Raydium touchpanel
+    - Revert "HID: add NOGET quirk for Eaton Ellipse MAX UPS"
+    - HID: alps: allow incoming reports when only the trackstick is opened
+    - Revert "netfilter: nft_numgen: add map lookups for numgen random operations"
+    - netfilter: ipset: list:set: Decrease refcount synchronously on deletion and
+      replace
+    - netfilter: ipset: actually allow allowable CIDR 0 in hash:net,port,net
+    - netfilter: ipset: fix ip_set_list allocation failure
+    - s390/mm: fix mis-accounting of pgtable_bytes
+    - s390/mm: Fix ERROR: "__node_distance" undefined!
+    - bpf: fix bpf_prog_get_info_by_fd to return 0 func_lens for unpriv
+    - netfilter: ipset: Correct rcu_dereference() call in ip_set_put_comment()
+    - netfilter: xt_IDLETIMER: add sysfs filename checking routine
+    - netfilter: ipset: Fix calling ip_set() macro at dumping
+    - netfilter: nft_compat: ebtables 'nat' table is normal chain type
+    - s390/qeth: fix HiperSockets sniffer
+    - s390/qeth: unregister netdevice only when registered
+    - net: hns3: Fix for out-of-bounds access when setting pfc back pressure
+    - hwmon: (ibmpowernv) Remove bogus __init annotations
+    - ARM: dts: imx6sll: fix typo for fsl,imx6sll-i2c node
+    - ARM: dts: fsl: Fix improperly quoted stdout-path values
+    - Revert "drm/exynos/decon5433: implement frame counter"
+    - arm64: dts: renesas: r8a7795: add missing dma-names on hscif2
+    - arm64: dts: renesas: condor: switch from EtherAVB to GEther
+    - xen/grant-table: Fix incorrect gnttab_dma_free_pages() pr_debug message
+    - clk: fixed-factor: fix of_node_get-put imbalance
+    - mtd: nand: Fix nanddev_pos_next_page() kernel-doc header
+    - lib/raid6: Fix arm64 test build
+    - drm/amd/display: Stop leaking planes
+    - block: Clear kernel memory before copying to user
+    - drm/amd/display: Drop reusing drm connector for MST
+    - drm/amd/amdgpu/dm: Fix dm_dp_create_fake_mst_encoder()
+    - s390/perf: Change CPUM_CF return code in event init function
+    - ceph: quota: fix null pointer dereference in quota check
+    - of/device: Really only set bus DMA mask when appropriate
+    - nvme: make sure ns head inherits underlying device limits
+    - i2c: omap: Enable for ARCH_K3
+    - i2c: qcom-geni: Fix runtime PM mismatch with child devices
+    - sched/core: Take the hotplug lock in sched_init_smp()
+    - perf tools: Fix undefined symbol scnprintf in libperf-jvmti.so
+    - perf tools: Do not zero sample_id_all for group members
+    - ice: Fix dead device link issue with flow control
+    - ice: Fix the bytecount sent to netdev_tx_sent_queue
+    - ice: Change req_speeds to be u16
+    - i40e: restore NETIF_F_GSO_IPXIP[46] to netdev features
+    - qed: Fix memory/entry leak in qed_init_sp_request()
+    - qed: Fix blocking/unlimited SPQ entries leak
+    - qed: Fix SPQ entries not returned to pool in error flows
+    - qed: Fix potential memory corruption
+    - net: stmmac: Fix RX packet size > 8191
+    - net: aquantia: fix potential IOMMU fault after driver unbind
+    - net: aquantia: fixed enable unicast on 32 macvlan
+    - net: aquantia: invalid checksumm offload implementation
+    - kbuild: deb-pkg: fix too low build version number
+    - Revert "scripts/setlocalversion: git: Make -dirty check more robust"
+    - SUNRPC: drop pointless static qualifier in xdr_get_next_encode_buffer()
+    - x86/mm: Move LDT remap out of KASLR region on 5-level paging
+    - x86/ldt: Unmap PTEs for the slot before freeing LDT pages
+    - x86/ldt: Remove unused variable in map_ldt_struct()
+    - media: v4l: event: Add subscription to list before calling "add" operation
+    - MIPS: OCTEON: cavium_octeon_defconfig: re-enable OCTEON USB driver
+    - RISC-V: Fix raw_copy_{to,from}_user()
+    - uio: Fix an Oops on load
+    - ALSA: hda/realtek - Add quirk entry for HP Pavilion 15
+    - ALSA: hda/ca0132 - Call pci_iounmap() instead of iounmap()
+    - can: kvaser_usb: Fix accessing freed memory in kvaser_usb_start_xmit()
+    - can: kvaser_usb: Fix potential uninitialized variable use
+    - usb: cdc-acm: add entry for Hiro (Conexant) modem
+    - USB: Wait for extra delay time after USB_PORT_FEAT_RESET for quirky hub
+    - usb: quirks: Add delay-init quirk for Corsair K70 LUX RGB
+    - misc: atmel-ssc: Fix section annotation on atmel_ssc_get_driver_data
+    - USB: misc: appledisplay: add 20" Apple Cinema Display
+    - gnss: serial: fix synchronous write timeout
+    - gnss: sirf: fix synchronous write timeout
+    - mtd: rawnand: atmel: fix OF child-node lookup
+    - drivers/misc/sgi-gru: fix Spectre v1 vulnerability
+    - ACPI / platform: Add SMB0001 HID to forbidden_id_list
+    - HID: uhid: forbid UHID_CREATE under KERNEL_DS or elevated privileges
+    - HID: Add quirk for Primax PIXART OEM mice
+    - HID: Add quirk for Microsoft PIXART OEM mouse
+    - libceph: fall back to sendmsg for slab pages
+    - mt76x0: run vco calibration for each channel configuration
+    - Linux 4.19.5
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: Build signed kernels for arm64"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 27 Nov 2018 10:38:34 -0600
+
+linux (4.19.0-6.7) disco; urgency=medium
+
+  * linux: 4.19.0-6.7 -proposed tracker (LP: #1805195)
+
+  * SecureBoot support for arm64 (LP: #1804481)
+    - Build signed kernels for arm64
+
+  * Add pointstick support for Cirque Touchpad (LP: #1805081)
+    - HID: multitouch: Add pointstick support for Cirque Touchpad
+
+  * Power consumption during s2idle is higher than long idle (Intel SSDPEKKF)
+    (LP: #1804588)
+    - SAUCE: pci: prevent Intel NVMe SSDPEKKF from entering D3
+    - SAUCE: nvme: add quirk to not call disable function when suspending
+
+  * Disco update: 4.19.4 upstream stable release (LP: #1805159)
+    - flow_dissector: do not dissect l4 ports for fragments
+    - ibmvnic: fix accelerated VLAN handling
+    - ip_tunnel: don't force DF when MTU is locked
+    - ipv6: fix a dst leak when removing its exception
+    - ipv6: Fix PMTU updates for UDP/raw sockets in presence of VRF
+    - net: bcmgenet: protect stop from timeout
+    - net-gro: reset skb->pkt_type in napi_reuse_skb()
+    - sctp: not allow to set asoc prsctp_enable by sockopt
+    - tcp: Fix SOF_TIMESTAMPING_RX_HARDWARE to use the latest timestamp during TCP
+      coalescing
+    - tg3: Add PHY reset for 5717/5719/5720 in change ring and flow control paths
+    - tipc: don't assume linear buffer when reading ancillary data
+    - tipc: fix lockdep warning when reinitilaizing sockets
+    - tuntap: fix multiqueue rx
+    - net: systemport: Protect stop from timeout
+    - net/sched: act_pedit: fix memory leak when IDR allocation fails
+    - net: sched: cls_flower: validate nested enc_opts_policy to avoid warning
+    - tipc: fix link re-establish failure
+    - net/mlx5e: Don't match on vlan non-existence if ethertype is wildcarded
+    - net/mlx5e: Claim TC hw offloads support only under a proper build config
+    - net/mlx5e: Adjust to max number of channles when re-attaching
+    - net/mlx5e: RX, verify received packet size in Linear Striding RQ
+    - Revert "sctp: remove sctp_transport_pmtu_check"
+    - net/mlx5e: Always use the match level enum when parsing TC rule match
+    - net/mlx5e: Fix selftest for small MTUs
+    - net/mlx5e: Removed unnecessary warnings in FEC caps query
+    - inet: frags: better deal with smp races
+    - l2tp: fix a sock refcnt leak in l2tp_tunnel_register
+    - net/mlx5: IPSec, Fix the SA context hash key
+    - net/mlx5e: IPoIB, Reset QP after channels are closed
+    - net: dsa: mv88e6xxx: Fix clearing of stats counters
+    - net: phy: realtek: fix RTL8201F sysfs name
+    - sctp: define SCTP_SS_DEFAULT for Stream schedulers
+    - net: qualcomm: rmnet: Fix incorrect assignment of real_dev
+    - net: dsa: microchip: initialize mutex before use
+    - sctp: fix strchange_flags name for Stream Change Event
+    - net: phy: mdio-gpio: Fix working over slow can_sleep GPIOs
+    - sctp: not increase stream's incnt before sending addstrm_in request
+    - mlxsw: spectrum: Fix IP2ME CPU policer configuration
+    - net: smsc95xx: Fix MTU range
+    - rxrpc: Fix lockup due to no error backoff after ack transmit error
+    - usbnet: smsc95xx: disable carrier check while suspending
+    - Revert "x86/speculation: Enable cross-hyperthread spectre v2 STIBP
+      mitigation"
+    - Linux 4.19.4
+
+  * Disco update: 4.19.3 upstream stable release (LP: #1805158)
+    - powerpc/traps: restore recoverability of machine_check interrupts
+    - powerpc/64/module: REL32 relocation range check
+    - powerpc/mm: Fix page table dump to work on Radix
+    - powerpc/mm: fix always true/false warning in slice.c
+    - drm/amd/display: fix bug of accessing invalid memory
+    - Input: wm97xx-ts - fix exit path
+    - powerpc/Makefile: Fix PPC_BOOK3S_64 ASFLAGS
+    - powerpc/eeh: Fix possible null deref in eeh_dump_dev_log()
+    - tty: check name length in tty_find_polling_driver()
+    - tracing/kprobes: Check the probe on unloaded module correctly
+    - drm/nouveau/secboot/acr: fix memory leak
+    - drm/amdgpu/powerplay: fix missing break in switch statements
+    - ARM: imx_v6_v7_defconfig: Select CONFIG_TMPFS_POSIX_ACL
+    - powerpc/nohash: fix undefined behaviour when testing page size support
+    - drm/msm/gpu: fix parameters in function msm_gpu_crashstate_capture
+    - drm/msm/disp/dpu: Use proper define for drm_encoder_init() 'encoder_type'
+    - drm/msm: dpu: Allow planes to extend past active display
+    - powerpc/mm: Don't report hugepage tables as memory leaks when using kmemleak
+    - drm/omap: fix memory barrier bug in DMM driver
+    - drm/amd/display: Raise dispclk value for dce120 by 15%
+    - drm/amd/display: fix gamma not being applied
+    - drm/hisilicon: hibmc: Do not carry error code in HiBMC framebuffer pointer
+    - media: pci: cx23885: handle adding to list failure
+    - media: coda: don't overwrite h.264 profile_idc on decoder instance
+    - MIPS: kexec: Mark CPU offline before disabling local IRQ
+    - powerpc/boot: Ensure _zimage_start is a weak symbol
+    - powerpc/memtrace: Remove memory in chunks
+    - MIPS/PCI: Call pcie_bus_configure_settings() to set MPS/MRRS
+    - staging: erofs: fix a missing endian conversion
+    - serial: 8250_of: Fix for lack of interrupt support
+    - sc16is7xx: Fix for multi-channel stall
+    - media: tvp5150: fix width alignment during set_selection()
+    - powerpc/selftests: Wait all threads to join
+    - staging:iio:ad7606: fix voltage scales
+    - drm: rcar-du: Update Gen3 output limitations
+    - drm/amdgpu: Fix SDMA TO after GPU reset v3
+    - staging: most: video: fix registration of an empty comp core_component
+    - 9p locks: fix glock.client_id leak in do_lock
+    - udf: Prevent write-unsupported filesystem to be remounted read-write
+    - ARM: dts: imx6ull: keep IMX6UL_ prefix for signals on both i.MX6UL and
+      i.MX6ULL
+    - media: ov5640: fix mode change regression
+    - 9p: clear dangling pointers in p9stat_free
+    - drm/amdgpu: fix integer overflow test in amdgpu_bo_list_create()
+    - media: ov5640: fix restore of last mode set
+    - cdrom: fix improper type cast, which can leat to information leak.
+    - ovl: fix error handling in ovl_verify_set_fh()
+    - ovl: fix recursive oi->lock in ovl_link()
+    - ovl: check whiteout in ovl_create_over_whiteout()
+    - ovl: automatically enable redirect_dir on metacopy=on
+    - serial: sh-sci: Fix could not remove dev_attr_rx_fifo_timeout
+    - scsi: qla2xxx: Fix incorrect port speed being set for FC adapters
+    - scsi: qla2xxx: Fix process response queue for ISP26XX and above
+    - scsi: qla2xxx: Remove stale debug trace message from tcm_qla2xxx
+    - scsi: qla2xxx: Fix early srb free on abort
+    - scsi: qla2xxx: shutdown chip if reset fail
+    - scsi: qla2xxx: Reject bsg request if chip is down.
+    - scsi: qla2xxx: Fix re-using LoopID when handle is in use
+    - scsi: qla2xxx: Fix for double free of SRB structure
+    - scsi: qla2xxx: Fix NVMe session hang on unload
+    - scsi: qla2xxx: Fix NVMe Target discovery
+    - scsi: qla2xxx: Fix duplicate switch database entries
+    - scsi: qla2xxx: Fix driver hang when FC-NVMe LUNs are configured
+    - vfs: fix FIGETBSZ ioctl on an overlayfs file
+    - fuse: Fix use-after-free in fuse_dev_do_read()
+    - fuse: Fix use-after-free in fuse_dev_do_write()
+    - fuse: fix blocked_waitq wakeup
+    - fuse: set FR_SENT while locked
+    - drm/msm: fix OF child-node lookup
+    - arm64: dts: stratix10: Support Ethernet Jumbo frame
+    - arm64: dts: stratix10: fix multicast filtering
+    - clk: meson-gxbb: set fclk_div3 as CLK_IS_CRITICAL
+    - clk: meson: axg: mark fdiv2 and fdiv3 as critical
+    - zram: close udev startup race condition as default groups
+    - MIPS: Loongson-3: Fix CPU UART irq delivery problem
+    - MIPS: Loongson-3: Fix BRIDGE irq delivery problem
+    - xtensa: add NOTES section to the linker script
+    - xtensa: make sure bFLT stack is 16 byte aligned
+    - xtensa: fix boot parameters address translation
+    - um: Drop own definition of PTRACE_SYSEMU/_SINGLESTEP
+    - clk: s2mps11: Fix matching when built as module and DT node contains
+      compatible
+    - clk: at91: Fix division by zero in PLL recalc_rate()
+    - clk: sunxi-ng: h6: fix bus clocks' divider position
+    - clk: rockchip: fix wrong mmc sample phase shift for rk3328
+    - clk: rockchip: Fix static checker warning in rockchip_ddrclk_get_parent call
+    - libceph: bump CEPH_MSG_MAX_DATA_LEN
+    - Revert "ceph: fix dentry leak in splice_dentry()"
+    - thermal: core: Fix use-after-free in thermal_cooling_device_destroy_sysfs
+    - mach64: fix display corruption on big endian machines
+    - mach64: fix image corruption due to reading accelerator registers
+    - acpi/nfit, x86/mce: Handle only uncorrectable machine checks
+    - acpi/nfit, x86/mce: Validate a MCE's address before using it
+    - acpi, nfit: Fix ARS overflow continuation
+    - reset: hisilicon: fix potential NULL pointer dereference
+    - crypto: hisilicon - Fix NULL dereference for same dst and src
+    - crypto: hisilicon - Fix reference after free of memories on error path
+    - vhost/scsi: truncate T10 PI iov_iter to prot_bytes
+    - scsi: qla2xxx: Initialize port speed to avoid setting lower speed
+    - SCSI: fix queue cleanup race before queue initialization is done
+    - Revert "powerpc/8xx: Use L1 entry APG to handle _PAGE_ACCESSED for
+      CONFIG_SWAP"
+    - soc: ti: QMSS: Fix usage of irq_set_affinity_hint
+    - ocfs2: fix a misuse a of brelse after failing ocfs2_check_dir_entry
+    - ocfs2: free up write context when direct IO failed
+    - mm: thp: relax __GFP_THISNODE for MADV_HUGEPAGE mappings
+    - memory_hotplug: cond_resched in __remove_pages
+    - netfilter: conntrack: fix calculation of next bucket number in early_drop
+    - ARM: 8809/1: proc-v7: fix Thumb annotation of cpu_v7_hvc_switch_mm
+    - bonding/802.3ad: fix link_failure_count tracking
+    - mtd: spi-nor: cadence-quadspi: Return error code in
+      cqspi_direct_read_execute()
+    - mtd: nand: Fix nanddev_neraseblocks()
+    - mtd: docg3: don't set conflicting BCH_CONST_PARAMS option
+    - hwmon: (core) Fix double-free in __hwmon_device_register()
+    - perf cs-etm: Correct CPU mode for samples
+    - perf stat: Handle different PMU names with common prefix
+    - perf callchain: Honour the ordering of PERF_CONTEXT_{USER,KERNEL,etc}
+    - perf intel-pt/bts: Calculate cpumode for synthesized samples
+    - perf intel-pt: Insert callchain context into synthesized callchains
+    - of, numa: Validate some distance map rules
+    - x86/cpu/vmware: Do not trace vmware_sched_clock()
+    - x86/hyper-v: Enable PIT shutdown quirk
+    - termios, tty/tty_baudrate.c: fix buffer overrun
+    - arch/alpha, termios: implement BOTHER, IBSHIFT and termios2
+    - watchdog/core: Add missing prototypes for weak functions
+    - btrfs: fix pinned underflow after transaction aborted
+    - Btrfs: fix missing data checksums after a ranged fsync (msync)
+    - Btrfs: fix cur_offset in the error case for nocow
+    - Btrfs: fix infinite loop on inode eviction after deduplication of eof block
+    - Btrfs: fix data corruption due to cloning of eof block
+    - btrfs: tree-checker: Fix misleading group system information
+    - clockevents/drivers/i8253: Add support for PIT shutdown quirk
+    - ext4: add missing brelse() update_backups()'s error path
+    - ext4: add missing brelse() in set_flexbg_block_bitmap()'s error path
+    - ext4: add missing brelse() add_new_gdb_meta_bg()'s error path
+    - ext4: avoid potential extra brelse in setup_new_flex_group_blocks()
+    - ext4: missing !bh check in ext4_xattr_inode_write()
+    - ext4: fix possible inode leak in the retry loop of ext4_resize_fs()
+    - ext4: avoid buffer leak on shutdown in ext4_mark_iloc_dirty()
+    - ext4: avoid buffer leak in ext4_orphan_add() after prior errors
+    - ext4: fix missing cleanup if ext4_alloc_flex_bg_array() fails while resizing
+    - ext4: avoid possible double brelse() in add_new_gdb() on error path
+    - ext4: fix possible leak of sbi->s_group_desc_leak in error path
+    - ext4: fix possible leak of s_journal_flag_rwsem in error path
+    - ext4: fix buffer leak in ext4_xattr_get_block() on error path
+    - ext4: release bs.bh before re-using in ext4_xattr_block_find()
+    - ext4: fix buffer leak in ext4_xattr_move_to_block() on error path
+    - ext4: fix buffer leak in ext4_expand_extra_isize_ea() on error path
+    - ext4: fix buffer leak in __ext4_read_dirblock() on error path
+    - mount: Prevent MNT_DETACH from disconnecting locked mounts
+    - mnt: fix __detach_mounts infinite loop
+    - uapi: fix linux/kfd_ioctl.h userspace compilation errors
+    - ARM: cpuidle: Don't register the driver when back-end init returns -ENXIO
+    - kdb: use correct pointer when 'btc' calls 'btt'
+    - kdb: print real address of pointers instead of hashed addresses
+    - sunrpc: correct the computation for page_ptr when truncating
+    - NFSv4: Don't exit the state manager without clearing
+      NFS4CLNT_MANAGER_RUNNING
+    - nfsd: COPY and CLONE operations require the saved filehandle to be set
+    - rtc: hctosys: Add missing range error reporting
+    - fuse: fix use-after-free in fuse_direct_IO()
+    - fuse: fix leaked notify reply
+    - fuse: fix possibly missed wake-up after abort
+    - selinux: check length properly in SCTP bind hook
+    - gfs2: Put bitmap buffers in put_super
+    - gfs2: Fix metadata read-ahead during truncate (2)
+    - libata: blacklist SAMSUNG MZ7TD256HAFV-000L9 SSD
+    - crypto: user - fix leaking uninitialized memory to userspace
+    - lib/ubsan.c: don't mark __ubsan_handle_builtin_unreachable as noreturn
+    - hugetlbfs: fix kernel BUG at fs/hugetlbfs/inode.c:444!
+    - mm/swapfile.c: use kvzalloc for swap_info_struct allocation
+    - efi/arm/libstub: Pack FDT after populating it
+    - mm: don't reclaim inodes with many attached pages
+    - scripts/spdxcheck.py: make python3 compliant
+    - drm/rockchip: Allow driver to be shutdown on reboot/kexec
+    - drm/amdgpu: Fix typo in amdgpu_vmid_mgr_init
+    - drm/amdgpu: add missing CHIP_HAINAN in amdgpu_ucode_get_load_type
+    - drm/amdgpu: Suppress keypresses from ACPI_VIDEO events
+    - drm/nouveau: Check backlight IDs are >= 0, not > 0
+    - drm/nouveau: Fix nv50_mstc->best_encoder()
+    - drm/amd/powerplay: Enable/Disable NBPSTATE on On/OFF of UVD
+    - drm/etnaviv: fix bogus fence complete check in timeout handler
+    - drm/dp_mst: Check if primary mstb is null
+    - drm: panel-orientation-quirks: Add quirk for Acer One 10 (S1003)
+    - drm/i915/dp: Link train Fallback on eDP only if fallback link BW can fit
+      panel's native mode
+    - drm/i915: Use the correct crtc when sanitizing plane mapping
+    - drm/i915: Restore vblank interrupts earlier
+    - drm/i915: Don't unset intel_connector->mst_port
+    - drm/i915: Skip vcpi allocation for MSTB ports that are gone
+    - drm/i915: Large page offsets for pread/pwrite
+    - drm/i915/dp: Fix link retraining comment in intel_dp_long_pulse()
+    - drm/i915/dp: Restrict link retrain workaround to external monitors
+    - drm/i915/icl: Fix the macros for DFLEXDPMLE register bits
+    - drm/i915/hdmi: Add HDMI 2.0 audio clock recovery N values
+    - drm/i915: Mark up GTT sizes as u64
+    - drm/i915: Fix error handling for the NV12 fb dimensions check
+    - drm/i915: Fix ilk+ watermarks when disabling pipes
+    - drm/i915: Compare user's 64b GTT offset even on 32b
+    - drm/i915: Don't oops during modeset shutdown after lpe audio deinit
+    - drm/i915: Mark pin flags as u64
+    - drm/i915/ringbuffer: Delay after EMIT_INVALIDATE for gen4/gen5
+    - drm/i915/execlists: Force write serialisation into context image vs
+      execution
+    - drm/i915: Fix possible race in intel_dp_add_mst_connector()
+    - drm/i915: Fix NULL deref when re-enabling HPD IRQs on systems with MST
+    - drm/i915: Fix hpd handling for pins with two encoders
+    - CONFIG_XEN_PV breaks xen_create_contiguous_region on ARM
+    - Revert "ACPICA: AML interpreter: add region addresses in global list during
+      initialization"
+    - Linux 4.19.3
+
+  * glibc 2.28-0ubuntu1 ADT test failure with linux 4.19.0-5.6 (LP: #1805154)
+    - SAUCE: Revert "x86: vdso: Use $LD instead of $CC to link"
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.12-1ubuntu1, zfs to 0.7.12-1ubuntu1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 26 Nov 2018 11:44:00 -0600
+
+linux (4.19.0-5.6) disco; urgency=medium
+
+  * crash in ENA driver on removing an interface (LP: #1802341)
+    - SAUCE: net: ena: fix crash during ena_remove()
+
+  * Ubuntu 18.04.1 - [s390x] Kernel panic while stressing network bonding
+    (LP: #1797367)
+    - s390/qeth: sanitize strings in debug messages
+
+  * Disco update: 4.19.2 upstream stable release (LP: #1803410)
+    - bpf: fix partial copy of map_ptr when dst is scalar
+    - MIPS: VDSO: Reduce VDSO_RANDOMIZE_SIZE to 64MB for 64bit
+    - gpio: mxs: Get rid of external API call
+    - mtd: rawnand: marvell: fix the IRQ handler complete() condition
+    - mtd: maps: gpio-addr-flash: Fix ioremapped size
+    - mtd: spi-nor: fsl-quadspi: fix read error for flash size larger than 16MB
+    - mtd: spi-nor: intel-spi: Add support for Intel Ice Lake SPI serial flash
+    - mtd: spi-nor: fsl-quadspi: Don't let -EINVAL on the bus
+    - spi: spi-mem: Adjust op len based on message/transfer size limitations
+    - spi: bcm-qspi: switch back to reading flash using smaller chunks
+    - spi: bcm-qspi: fix calculation of address length
+    - bcache: trace missed reading by cache_missed
+    - bcache: fix ioctl in flash device
+    - bcache: correct dirty data statistics
+    - bcache: fix miss key refill->end in writeback
+    - hwmon: (pmbus) Fix page count auto-detection.
+    - jffs2: free jffs2_sb_info through jffs2_kill_sb()
+    - block: setup bounce bio_sets properly
+    - block: make sure discard bio is aligned with logical block size
+    - block: make sure writesame bio is aligned with logical block size
+    - cpufreq: conservative: Take limits changes into account properly
+    - dma-mapping: fix panic caused by passing empty cma command line argument
+    - pcmcia: Implement CLKRUN protocol disabling for Ricoh bridges
+    - ACPI / OSL: Use 'jiffies' as the time bassis for acpi_os_get_timer()
+    - ACPICA: AML interpreter: add region addresses in global list during
+      initialization
+    - ACPICA: AML Parser: fix parse loop to correctly skip erroneous extended
+      opcodes
+    - acpi, nfit: Fix Address Range Scrub completion tracking
+    - kprobes/x86: Use preempt_enable() in optimized_callback()
+    - mailbox: PCC: handle parse error
+    - parisc: Fix address in HPMC IVA
+    - parisc: Fix map_pages() to not overwrite existing pte entries
+    - parisc: Fix exported address of os_hpmc handler
+    - ALSA: hda - Add quirk for ASUS G751 laptop
+    - ALSA: hda - Fix headphone pin config for ASUS G751
+    - ALSA: hda - Add mic quirk for the Lenovo G50-30 (17aa:3905)
+    - ALSA: hda: Add 2 more models to the power_save blacklist
+    - ALSA: ca0106: Disable IZD on SB0570 DAC to fix audio pops
+    - ALSA: hda - Fix incorrect clearance of thinkpad_acpi hooks
+    - x86/speculation: Enable cross-hyperthread spectre v2 STIBP mitigation
+    - x86/xen: Fix boot loader version reported for PVH guests
+    - x86/corruption-check: Fix panic in memory_corruption_check() when boot
+      option without value is provided
+    - x86/kvm/nVMX: allow bare VMXON state migration
+    - x86/mm/pat: Disable preemption around __flush_tlb_all()
+    - x86/numa_emulation: Fix uniform-split numa emulation
+    - ARM: dts: exynos: Disable pull control for MAX8997 interrupts on Origen
+    - net: socionext: Reset tx queue in ndo_stop
+    - net: loopback: clear skb->tstamp before netif_rx()
+    - locking/lockdep: Fix debug_locks off performance problem
+    - netfilter: xt_nat: fix DNAT target for shifted portmap ranges
+    - ataflop: fix error handling during setup
+    - swim: fix cleanup on setup error
+    - arm64: cpufeature: ctr: Fix cpu capability check for late CPUs
+    - hv_netvsc: fix vf serial matching with pci slot info
+    - nfp: devlink port split support for 1x100G CXP NIC
+    - tun: Consistently configure generic netdev params via rtnetlink
+    - s390/sthyi: Fix machine name validity indication
+    - hwmon: (pwm-fan) Set fan speed to 0 on suspend
+    - lightnvm: pblk: fix race on sysfs line state
+    - lightnvm: pblk: fix two sleep-in-atomic-context bugs
+    - lightnvm: pblk: fix race condition on metadata I/O
+    - spi: spi-ep93xx: Use dma_data_direction for ep93xx_spi_dma_{finish,prepare}
+    - perf tools: Free temporary 'sys' string in read_event_files()
+    - perf tools: Cleanup trace-event-info 'tdata' leak
+    - perf tools: Free 'printk' string in parse_ftrace_printk()
+    - perf strbuf: Match va_{add,copy} with va_end
+    - cpupower: Fix coredump on VMWare
+    - bcache: Populate writeback_rate_minimum attribute
+    - mmc: sdhci-pci-o2micro: Add quirk for O2 Micro dev 0x8620 rev 0x01
+    - sdhci: acpi: add free_slot callback
+    - mtd: rawnand: denali: set SPARE_AREA_SKIP_BYTES register to 8 if unset
+    - iwlwifi: pcie: avoid empty free RB queue
+    - iwlwifi: mvm: clear HW_RESTART_REQUESTED when stopping the interface
+    - iwlwifi: mvm: check for n_profiles validity in EWRD ACPI
+    - x86/olpc: Indicate that legacy PC XO-1 platform should not register RTC
+    - wlcore: Fix BUG with clear completion on timeout
+    - ACPI/PPTT: Handle architecturally unknown cache types
+    - ACPI / PM: LPIT: Register sysfs attributes based on FADT
+    - ACPI / processor: Fix the return value of acpi_processor_ids_walk()
+    - cpufreq: dt: Try freeing static OPPs only if we have added them
+    - x86/intel_rdt: Show missing resctrl mount options
+    - mtd: rawnand: atmel: Fix potential NULL pointer dereference
+    - nvme: call nvme_complete_rq when nvmf_check_ready fails for mpath I/O
+    - ath10k: fix tx status flag setting for management frames
+    - signal: Introduce COMPAT_SIGMINSTKSZ for use in compat_sys_sigaltstack
+    - ice: fix changing of ring descriptor size (ethtool -G)
+    - ice: update fw version check logic
+    - net: hns3: Fix for packet buffer setting bug
+    - Bluetooth: btbcm: Add entry for BCM4335C0 UART bluetooth
+    - Bluetooth: hci_qca: Remove hdev dereference in qca_close().
+    - x86: boot: Fix EFI stub alignment
+    - net: hns3: Add nic state check before calling netif_tx_wake_queue
+    - net: hns3: Fix ets validate issue
+    - pinctrl: sunxi: fix 'pctrl->functions' allocation in
+      sunxi_pinctrl_build_state
+    - pinctrl: qcom: spmi-mpp: Fix err handling of pmic_mpp_set_mux
+    - brcmfmac: fix for proper support of 160MHz bandwidth
+    - net: hns3: Check hdev state when getting link status
+    - net: hns3: Set STATE_DOWN bit of hdev state when stopping net
+    - net: phy: phylink: ensure the carrier is off when starting phylink
+    - block, bfq: correctly charge and reset entity service in all cases
+    - arm64: entry: Allow handling of undefined instructions from EL1
+    - kprobes: Return error if we fail to reuse kprobe instead of BUG_ON()
+    - spi: gpio: No MISO does not imply no RX
+    - ACPI / LPSS: Add alternative ACPI HIDs for Cherry Trail DMA controllers
+    - pinctrl: qcom: spmi-mpp: Fix drive strength setting
+    - bpf/verifier: fix verifier instability
+    - failover: Add missing check to validate 'slave_dev' in
+      net_failover_slave_unregister
+    - perf tests: Fix record+probe_libc_inet_pton.sh without ping's debuginfo
+    - pinctrl: spmi-mpp: Fix pmic_mpp_config_get() to be compliant
+    - pinctrl: ssbi-gpio: Fix pm8xxx_pin_config_get() to be compliant
+    - net: hns3: Preserve vlan 0 in hardware table
+    - net: hns3: Fix ping exited problem when doing lp selftest
+    - net: hns3: Fix for vf vlan delete failed problem
+    - net: dsa: mv88e6xxx: Fix writing to a PHY page.
+    - mt76x2u: run device cleanup routine if resume fails
+    - rsi: fix memory alignment issue in ARM32 platforms
+    - libertas_tf: prevent underflow in process_cmdrequest()
+    - iwlwifi: mvm: fix BAR seq ctrl reporting
+    - gpio: brcmstb: allow 0 width GPIO banks
+    - ixgbe: disallow IPsec Tx offload when in SR-IOV mode
+    - ixgbevf: VF2VF TCP RSS
+    - wil6210: fix RX buffers release and unmap
+    - ath10k: schedule hardware restart if WMI command times out
+    - libata: Apply NOLPM quirk for SAMSUNG MZ7TD256HAFV-000L9
+    - thermal: rcar_thermal: Prevent doing work after unbind
+    - thermal: da9062/61: Prevent hardware access during system suspend
+    - cifs: fix a credits leak for compund commands
+    - cgroup, netclassid: add a preemption point to write_classid
+    - net: stmmac: dwmac-sun8i: fix OF child-node lookup
+    - f2fs: fix to account IO correctly for cgroup writeback
+    - MD: Memory leak when flush bio size is zero
+    - md: fix memleak for mempool
+    - of: Add missing exports of node name compare functions
+    - scsi: esp_scsi: Track residual for PIO transfers
+    - scsi: ufs: Schedule clk gating work on correct queue
+    - UAPI: ndctl: Fix g++-unsupported initialisation in headers
+    - KVM: nVMX: Clear reserved bits of #DB exit qualification
+    - scsi: megaraid_sas: fix a missing-check bug
+    - RDMA/core: Do not expose unsupported counters
+    - RDMA/cm: Respect returned status of cm_init_av_by_path
+    - IB/ipoib: Clear IPCB before icmp_send
+    - RDMA/bnxt_re: Avoid accessing nq->bar_reg_iomem in failure case
+    - RDMA/bnxt_re: Fix recursive lock warning in debug kernel
+    - usb: host: ohci-at91: fix request of irq for optional gpio
+    - PCI: mediatek: Fix mtk_pcie_find_port() endpoint/port matching logic
+    - PCI: cadence: Use AXI region 0 to signal interrupts from EP
+    - usb: typec: tcpm: Report back negotiated PPS voltage and current
+    - tpm: suppress transmit cmd error logs when TPM 1.2 is disabled/deactivated
+    - f2fs: clear PageError on the read path
+    - Drivers: hv: vmbus: Use cpumask_var_t for on-stack cpu mask
+    - VMCI: Resource wildcard match fixed
+    - PCI / ACPI: Enable wake automatically for power managed bridges
+    - xprtrdma: Reset credit grant properly after a disconnect
+    - irqchip/pdc: Setup all edge interrupts as rising edge at GIC
+    - usb: dwc2: fix call to vbus supply exit routine, call it unlocked
+    - usb: dwc2: fix a race with external vbus supply
+    - usb: gadget: udc: atmel: handle at91sam9rl PMC
+    - ext4: fix argument checking in EXT4_IOC_MOVE_EXT
+    - MD: fix invalid stored role for a disk
+    - PCI: cadence: Correct probe behaviour when failing to get PHY
+    - nvmem: check the return value of nvmem_add_cells()
+    - xhci: Avoid USB autosuspend when resuming USB2 ports.
+    - scsi: qla2xxx: Fix recursive mailbox timeout
+    - f2fs: fix to recover inode's crtime during POR
+    - f2fs: fix to recover inode's i_flags during POR
+    - PCI/MSI: Warn and return error if driver enables MSI/MSI-X twice
+    - coresight: etb10: Fix handling of perf mode
+    - PCI: dwc: pci-dra7xx: Enable errata i870 for both EP and RC mode
+    - crypto: caam - fix implicit casts in endianness helpers
+    - usb: chipidea: Prevent unbalanced IRQ disable
+    - Smack: ptrace capability use fixes
+    - driver/dma/ioat: Call del_timer_sync() without holding prep_lock
+    - ASoC: AMD: Fix capture unstable in beginning for some runs
+    - firmware: coreboot: Unmap ioregion after device population
+    - IB/ipoib: Use dev_port to expose network interface port numbers
+    - IB/mlx5: Allow transition of DCI QP to reset
+    - uio: ensure class is registered before devices
+    - scsi: lpfc: Correct soft lockup when running mds diagnostics
+    - scsi: lpfc: Correct race with abort on completion path
+    - f2fs: avoid sleeping under spin_lock
+    - f2fs: report error if quota off error during umount
+    - signal: Always deliver the kernel's SIGKILL and SIGSTOP to a pid namespace
+      init
+    - f2fs: fix to flush all dirty inodes recovered in readonly fs
+    - mfd: menelaus: Fix possible race condition and leak
+    - dmaengine: dma-jz4780: Return error if not probed from DT
+    - IB/rxe: fix for duplicate request processing and ack psns
+    - ALSA: hda: Check the non-cached stream buffers more explicitly
+    - cpupower: Fix AMD Family 0x17 msr_pstate size
+    - Revert "f2fs: fix to clear PG_checked flag in set_page_dirty()"
+    - f2fs: fix missing up_read
+    - f2fs: fix to recover cold bit of inode block during POR
+    - f2fs: fix to account IO correctly
+    - OPP: Free OPP table properly on performance state irregularities
+    - ARM: dts: exynos: Convert exynos5250.dtsi to opp-v2 bindings
+    - ARM: dts: exynos: Mark 1 GHz CPU OPP as suspend OPP on Exynos5250
+    - xen-swiotlb: use actually allocated size on check physical continuous
+    - tpm: Restore functionality to xen vtpm driver.
+    - xen/blkfront: avoid NULL blkfront_info dereference on device removal
+    - xen/balloon: Support xend-based toolstack
+    - xen: fix race in xen_qlock_wait()
+    - xen: make xen_qlock_wait() nestable
+    - xen/pvh: increase early stack size
+    - xen/pvh: don't try to unplug emulated devices
+    - libertas: don't set URB_ZERO_PACKET on IN USB transfer
+    - usbip:vudc: BUG kmalloc-2048 (Not tainted): Poison overwritten
+    - usb: typec: tcpm: Fix APDO PPS order checking to be based on voltage
+    - usb: gadget: udc: renesas_usb3: Fix b-device mode for "workaround"
+    - mt76: mt76x2: fix multi-interface beacon configuration
+    - iwlwifi: mvm: check return value of rs_rate_from_ucode_rate()
+    - net/ipv4: defensive cipso option parsing
+    - dmaengine: ppc4xx: fix off-by-one build failure
+    - scsi: sched/wait: Add wait_event_lock_irq_timeout for TASK_UNINTERRUPTIBLE
+      usage
+    - scsi: target: Fix target_wait_for_sess_cmds breakage with active signals
+    - libnvdimm: Hold reference on parent while scheduling async init
+    - libnvdimm, region: Fail badblocks listing for inactive regions
+    - libnvdimm, pmem: Fix badblocks population for 'raw' namespaces
+    - ASoC: intel: skylake: Add missing break in skl_tplg_get_token()
+    - ASoC: sta32x: set ->component pointer in private struct
+    - IB/mlx5: Fix MR cache initialization
+    - IB/rxe: Revise the ib_wr_opcode enum
+    - jbd2: fix use after free in jbd2_log_do_checkpoint()
+    - gfs2_meta: ->mount() can get NULL dev_name
+    - ext4: fix EXT4_IOC_SWAP_BOOT
+    - ext4: initialize retries variable in ext4_da_write_inline_data_begin()
+    - ext4: fix setattr project check in fssetxattr ioctl
+    - ext4: propagate error from dquot_initialize() in EXT4_IOC_FSSETXATTR
+    - ext4: fix use-after-free race in ext4_remount()'s error path
+    - selinux: fix mounting of cgroup2 under older policies
+    - HID: wacom: Work around HID descriptor bug in DTK-2451 and DTH-2452
+    - HID: hiddev: fix potential Spectre v1
+    - EDAC, amd64: Add Family 17h, models 10h-2fh support
+    - EDAC, {i7core,sb,skx}_edac: Fix uncorrected error counting
+    - EDAC, skx_edac: Fix logical channel intermediate decoding
+    - ARM: dts: dra7: Fix up unaligned access setting for PCIe EP
+    - PCI/ASPM: Fix link_state teardown on device removal
+    - PCI: Add Device IDs for Intel GPU "spurious interrupt" quirk
+    - signal/GenWQE: Fix sending of SIGKILL
+    - signal: Guard against negative signal numbers in copy_siginfo_from_user32
+    - crypto: lrw - Fix out-of bounds access on counter overflow
+    - crypto: tcrypt - fix ghash-generic speed test
+    - crypto: aesni - don't use GFP_ATOMIC allocation if the request doesn't cross
+      a page in gcm
+    - crypto: morus/generic - fix for big endian systems
+    - crypto: aegis/generic - fix for big endian systems
+    - crypto: speck - remove Speck
+    - mm: /proc/pid/smaps_rollup: fix NULL pointer deref in smaps_pte_range()
+    - userfaultfd: disable irqs when taking the waitqueue lock
+    - ima: fix showing large 'violations' or 'runtime_measurements_count'
+    - ima: open a new file instance if no read permissions
+    - hugetlbfs: dirty pages as they are added to pagecache
+    - mm/rmap: map_pte() was not handling private ZONE_DEVICE page properly
+    - mm/hmm: fix race between hmm_mirror_unregister() and mmu_notifier callback
+    - KVM: arm/arm64: Ensure only THP is candidate for adjustment
+    - KVM: arm64: Fix caching of host MDCR_EL2 value
+    - kbuild: fix kernel/bounds.c 'W=1' warning
+    - iio: ad5064: Fix regulator handling
+    - iio: adc: imx25-gcq: Fix leak of device_node in mx25_gcq_setup_cfgs()
+    - iio: adc: at91: fix acking DRDY irq on simple conversions
+    - iio: adc: at91: fix wrong channel number in triggered buffer mode
+    - w1: omap-hdq: fix missing bus unregister at removal
+    - smb3: allow stats which track session and share reconnects to be reset
+    - smb3: do not attempt cifs operation in smb3 query info error path
+    - smb3: on kerberos mount if server doesn't specify auth type use krb5
+    - printk: Fix panic caused by passing log_buf_len to command line
+    - genirq: Fix race on spurious interrupt detection
+    - tpm: fix response size validation in tpm_get_random()
+    - NFC: nfcmrvl_uart: fix OF child-node lookup
+    - NFSv4.1: Fix the r/wsize checking
+    - nfs: Fix a missed page unlock after pg_doio()
+    - nfsd: correctly decrement odstate refcount in error path
+    - nfsd: Fix an Oops in free_session()
+    - lockd: fix access beyond unterminated strings in prints
+    - dm ioctl: harden copy_params()'s copy_from_user() from malicious users
+    - dm zoned: fix metadata block ref counting
+    - dm zoned: fix various dmz_get_mblock() issues
+    - media: ov7670: make "xclk" clock optional
+    - fsnotify: Fix busy inodes during unmount
+    - powerpc64/module elfv1: Set opd addresses after module relocation
+    - powerpc/msi: Fix compile error on mpc83xx
+    - powerpc/tm: Fix HFSCR bit for no suspend case
+    - powerpc/64s/hash: Do not use PPC_INVALIDATE_ERAT on CPUs before POWER9
+    - MIPS: OCTEON: fix out of bounds array access on CN68XX
+    - rtc: ds1307: fix ds1339 wakealarm support
+    - rtc: cmos: Fix non-ACPI undefined reference to `hpet_rtc_interrupt'
+    - rtc: cmos: Remove the `use_acpi_alarm' module parameter for !ACPI
+    - power: supply: twl4030-charger: fix OF sibling-node lookup
+    - ocxl: Fix access to the AFU Descriptor Data
+    - iommu/arm-smmu: Ensure that page-table updates are visible before TLBI
+    - TC: Set DMA masks for devices
+    - net: bcmgenet: fix OF child-node lookup
+    - media: v4l2-tpg: fix kernel oops when enabling HFLIP and OSD
+    - Revert "media: dvbsky: use just one mutex for serializing device R/W ops"
+    - kgdboc: Passing ekgdboc to command line causes panic
+    - remoteproc: qcom: q6v5: Propagate EPROBE_DEFER
+    - media: cec: make cec_get_edid_spa_location() an inline function
+    - media: cec: integrate cec_validate_phys_addr() in cec-api.c
+    - xen: fix xen_qlock_wait()
+    - xen: remove size limit of privcmd-buf mapping interface
+    - xen-blkfront: fix kernel panic with negotiate_mq error path
+    - media: cec: add new tx/rx status bits to detect aborts/timeouts
+    - media: cec: fix the Signal Free Time calculation
+    - media: cec: forgot to cancel delayed work
+    - media: em28xx: use a default format if TRY_FMT fails
+    - media: tvp5150: avoid going past array on v4l2_querymenu()
+    - media: em28xx: fix input name for Terratec AV 350
+    - media: em28xx: make v4l2-compliance happier by starting sequence on zero
+    - media: em28xx: fix handler for vidioc_s_input()
+    - media: adv7604: when the EDID is cleared, unconfigure CEC as well
+    - media: adv7842: when the EDID is cleared, unconfigure CEC as well
+    - drm/mediatek: fix OF sibling-node lookup
+    - media: media colorspaces*.rst: rename AdobeRGB to opRGB
+    - media: replace ADOBERGB by OPRGB
+    - media: hdmi.h: rename ADOBE_RGB to OPRGB and ADOBE_YCC to OPYCC
+    - arm64: lse: remove -fcall-used-x0 flag
+    - rpmsg: smd: fix memory leak on channel create
+    - Cramfs: fix abad comparison when wrap-arounds occur
+    - ARM: dts: socfpga: Fix SDRAM node address for Arria10
+    - arm64: dts: stratix10: Correct System Manager register size
+    - soc: qcom: rmtfs-mem: Validate that scm is available
+    - soc/tegra: pmc: Fix child-node lookup
+    - selftests/ftrace: Fix synthetic event test to delete event correctly
+    - selftests/powerpc: Fix ptrace tm failure
+    - tracing: Return -ENOENT if there is no target synthetic event
+    - btrfs: qgroup: Avoid calling qgroup functions if qgroup is not enabled
+    - btrfs: Handle owner mismatch gracefully when walking up tree
+    - btrfs: locking: Add extra check in btrfs_init_new_buffer() to avoid deadlock
+    - btrfs: fix error handling in free_log_tree
+    - btrfs: fix error handling in btrfs_dev_replace_start
+    - btrfs: Enhance btrfs_trim_fs function to handle error better
+    - btrfs: Ensure btrfs_trim_fs can trim the whole filesystem
+    - btrfs: iterate all devices during trim, instead of fs_devices::alloc_list
+    - btrfs: don't attempt to trim devices that don't support it
+    - btrfs: keep trim from interfering with transaction commits
+    - btrfs: wait on caching when putting the bg cache
+    - Btrfs: don't clean dirty pages during buffered writes
+    - btrfs: release metadata before running delayed refs
+    - btrfs: protect space cache inode alloc with GFP_NOFS
+    - btrfs: reset max_extent_size on clear in a bitmap
+    - btrfs: make sure we create all new block groups
+    - Btrfs: fix warning when replaying log after fsync of a tmpfile
+    - Btrfs: fix wrong dentries after fsync of file that got its parent replaced
+    - btrfs: qgroup: Dirty all qgroups before rescan
+    - Btrfs: fix null pointer dereference on compressed write path error
+    - Btrfs: fix assertion on fsync of regular file when using no-holes feature
+    - Btrfs: fix deadlock when writing out free space caches
+    - btrfs: reset max_extent_size properly
+    - btrfs: set max_extent_size properly
+    - btrfs: don't use ctl->free_space for max_extent_size
+    - btrfs: only free reserved extent if we didn't insert it
+    - btrfs: fix insert_reserved error handling
+    - btrfs: don't run delayed_iputs in commit
+    - btrfs: move the dio_sem higher up the callchain
+    - Btrfs: fix use-after-free during inode eviction
+    - Btrfs: fix use-after-free when dumping free space
+    - net: sched: Remove TCA_OPTIONS from policy
+    - vt: fix broken display when running aptitude
+    - bpf: wait for running BPF programs when updating map-in-map
+    - vga_switcheroo: Fix missing gpu_bound call at audio client registration
+    - MD: fix invalid stored role for a disk - try2
+    - Linux 4.19.2
+
+  * [FEAT] Guest-dedicated Crypto Adapters (LP: #1787405)
+    - KVM: s390: vsie: simulate VCPU SIE entry/exit
+    - KVM: s390: introduce and use KVM_REQ_VSIE_RESTART
+    - KVM: s390: refactor crypto initialization
+    - s390: vfio-ap: base implementation of VFIO AP device driver
+    - s390: vfio-ap: register matrix device with VFIO mdev framework
+    - s390: vfio-ap: sysfs interfaces to configure adapters
+    - s390: vfio-ap: sysfs interfaces to configure domains
+    - s390: vfio-ap: sysfs interfaces to configure control domains
+    - s390: vfio-ap: sysfs interface to view matrix mdev matrix
+    - KVM: s390: interface to clear CRYCB masks
+    - s390: vfio-ap: implement mediated device open callback
+    - s390: vfio-ap: implement VFIO_DEVICE_GET_INFO ioctl
+    - s390: vfio-ap: zeroize the AP queues
+    - s390: vfio-ap: implement VFIO_DEVICE_RESET ioctl
+    - KVM: s390: Clear Crypto Control Block when using vSIE
+    - KVM: s390: vsie: Do the CRYCB validation first
+    - KVM: s390: vsie: Make use of CRYCB FORMAT2 clear
+    - KVM: s390: vsie: Allow CRYCB FORMAT-2
+    - KVM: s390: vsie: allow CRYCB FORMAT-1
+    - KVM: s390: vsie: allow CRYCB FORMAT-0
+    - KVM: s390: vsie: allow guest FORMAT-0 CRYCB on host FORMAT-1
+    - KVM: s390: vsie: allow guest FORMAT-1 CRYCB on host FORMAT-2
+    - KVM: s390: vsie: allow guest FORMAT-0 CRYCB on host FORMAT-2
+    - KVM: s390: device attrs to enable/disable AP interpretation
+    - KVM: s390: CPU model support for AP virtualization
+    - s390: doc: detailed specifications for AP virtualization
+    - KVM: s390: fix locking for crypto setting error path
+    - KVM: s390: Tracing APCB changes
+    - s390: vfio-ap: setup APCB mask using KVM dedicated function
+    - [Config:] Enable CONFIG_S390_AP_IOMMU and set CONFIG_VFIO_AP to module.
+
+  * Bypass of mount visibility through userns + mount propagation (LP: #1789161)
+    - mount: Retest MNT_LOCKED in do_umount
+    - mount: Don't allow copying MNT_UNBINDABLE|MNT_LOCKED mounts
+
+  *  CVE-2018-18955: nested user namespaces with more than five extents
+    incorrectly grant privileges over inode (LP: #1801924) // CVE-2018-18955
+    - userns: also map extents in the reverse map to kernel IDs
+
+  * kdump fail due to an IRQ storm (LP: #1797990)
+    - SAUCE: x86/PCI: Export find_cap() to be used in early PCI code
+    - SAUCE: x86/quirks: Add parameter to clear MSIs early on boot
+    - SAUCE: x86/quirks: Scan all busses for early PCI quirks
+
+  * Disable LPM for Raydium Touchscreens (LP: #1802248)
+    - USB: quirks: Add no-lpm quirk for Raydium touchscreens
+
+  * Power consumption during s2idle is higher than long idle(sk hynix)
+    (LP: #1801875)
+    - SAUCE: pci: prevent sk hynix nvme from entering D3
+    - SAUCE: nvme: add quirk to not call disable function when suspending
+
+  * Disco update: v4.19.1 upstream stable release (LP: #1801739)
+    - bridge: do not add port to router list when receives query with source
+      0.0.0.0
+    - ipv6/ndisc: Preserve IPv6 control buffer if protocol error handlers are
+      called
+    - net/mlx5e: fix csum adjustments caused by RXFCS
+    - net: sched: gred: pass the right attribute to gred_change_table_def()
+    - net: stmmac: Fix stmmac_mdio_reset() when building stmmac as modules
+    - net: udp: fix handling of CHECKSUM_COMPLETE packets
+    - Revert "net: simplify sock_poll_wait"
+    - rtnetlink: Disallow FDB configuration for non-Ethernet device
+    - vhost: Fix Spectre V1 vulnerability
+    - bonding: fix length of actor system
+    - openvswitch: Fix push/pop ethernet validation
+    - net/ipv6: Allow onlink routes to have a device mismatch if it is the default
+      route
+    - net/smc: fix smc_buf_unuse to use the lgr pointer
+    - mlxsw: spectrum_switchdev: Don't ignore deletions of learned MACs
+    - mlxsw: core: Fix devlink unregister flow
+    - net: drop skb on failure in ip_check_defrag()
+    - net: Properly unlink GRO packets on overflow.
+    - r8169: fix broken Wake-on-LAN from S5 (poweroff)
+    - Revert "be2net: remove desc field from be_eq_obj"
+    - sctp: check policy more carefully when getting pr status
+    - sparc64: Export __node_distance.
+    - sparc64: Make corrupted user stacks more debuggable.
+    - sparc64: Wire up compat getpeername and getsockname.
+    - net: bridge: remove ipv6 zero address check in mcast queries
+    - Linux 4.19.1
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.11-1ubuntu1, zfs to 0.7.11-3ubuntu1
+    - [Config] updateconfigs after 4.19.2 stable update
+    - [Config] Disable unneded options for s390
+    - [Config] Update annotations for 4.19
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 15 Nov 2018 09:55:37 -0800
+
+linux (4.19.0-4.5) disco; urgency=medium
+
+  * Add checksum offload and TSO support for HiNIC adapters (LP: #1800664)
+    - net-next/hinic: add checksum offload and TSO support
+
+  * [Bionic][Cosmic] Fix to ipmi to support vendor specific messages greater
+    than 255 bytes (LP: #1799794)
+    - ipmi:ssif: Add support for multi-part transmit messages > 2 parts
+
+  * Packaging resync (LP: #1786013)
+    - [Package] add support for specifying the primary makefile
+
+  * Update ENA driver to version 2.0.1K (LP: #1798182)
+    - net: ena: minor performance improvement
+    - net: ena: complete host info to match latest ENA spec
+    - net: ena: introduce Low Latency Queues data structures according to ENA spec
+    - net: ena: add functions for handling Low Latency Queues in ena_com
+    - net: ena: add functions for handling Low Latency Queues in ena_netdev
+    - net: ena: use CSUM_CHECKED device indication to report skb's checksum status
+    - net: ena: explicit casting and initialization, and clearer error handling
+    - net: ena: limit refill Rx threshold to 256 to avoid latency issues
+    - net: ena: change rx copybreak default to reduce kernel memory pressure
+    - net: ena: remove redundant parameter in ena_com_admin_init()
+    - net: ena: update driver version to 2.0.1
+    - net: ena: fix indentations in ena_defs for better readability
+    - net: ena: Fix Kconfig dependency on X86
+    - net: ena: enable Low Latency Queues
+    - net: ena: fix compilation error in xtensa architecture
+
+  * [Bionic][Cosmic]  ipmi: Fix timer race with module unload (LP: #1799281)
+    - ipmi: Fix timer race with module unload
+
+  * Overlayfs in user namespace leaks directory content of inaccessible
+    directories (LP: #1793458) // CVE-2018-6559
+    - SAUCE: overlayfs: ensure mounter privileges when reading directories
+
+  * not able to unwind the stack from within __kernel_clock_gettime in the Linux
+    vDSO (LP: #1797963)
+    - powerpc/vdso: Correct call frame information
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Don't print secure boot state
+      from the efi stub"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Make get_cert_list() use
+      efi_status_to_str() to print error messages."
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err()."
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Make get_cert_list() not complain
+      about cert lists that aren't present."
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable
+      to be suppressed"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI
+      Secure Boot"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add EFI signature data types"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time
+      addition of keys to secondary keyring"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in
+      secure boot mode"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to
+      indicate secure boot mode"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Copy secure_boot flag in boot params
+      across kexec reboot"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down perf"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) bpf: Restrict kernel image access
+      functions when the kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down kprobes"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down /proc/kcore"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the
+      testmmiotrace module"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down module params that specify
+      hardware parameters (eg. ioport)"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down TIOCSSERIAL"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) acpi: Disable APEI error injection if
+      the kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) acpi: Disable ACPI table override if
+      the kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param
+      when the kernel has been locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) ACPI: Limit access to custom_method
+      when the kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) x86: Lock down IO port access when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) PCI: Lock down BAR access when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is
+      locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) hibernate: Disable when the kernel is
+      locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Enforce module signatures if the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Add a SysRq option to lift kernel
+      lockdown"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Add the ability to lock down access to
+      the running kernel image"
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) efi: Add EFI signature data types
+    - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) efi/x86: Call efi_parse_options() from efi_main()
+    - SAUCE: (efi-lockdown) Fix for module sig verification
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) module: remove support for having IMA validate modules
+    - [Packaging] generate Vcs-Git url from changelog
+    - [Config] CONFIG_SCSI_MQ_DEFAULT=y
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 02 Nov 2018 14:22:55 -0500
+
+linux (4.19.0-3.4) cosmic; urgency=medium
+
+  * Support Edge Gateway's Bluetooth LED (LP: #1798332)
+    - SAUCE: Bluetooth: Support for LED on Edge Gateways
+
+  * Support Edge Gateway's WIFI LED (LP: #1798330)
+    - SAUCE: mwifiex: Switch WiFi LED state according to the device status
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.19
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 22 Oct 2018 09:13:39 -0500
+
+linux (4.19.0-2.3) cosmic; urgency=medium
+
+  * fscache: bad refcounting in fscache_op_complete leads to OOPS (LP: #1797314)
+    - SAUCE: fscache: Fix race in decrementing refcount of op->npages
+
+  * Provide mode where all vCPUs on a core must be the same VM (LP: #1792957)
+    - KVM: PPC: Book3S HV: Provide mode where all vCPUs on a core must be the same
+      VM
+
+  * The front MIC can't work on the Lenovo M715 (LP: #1797292)
+    - ALSA: hda/realtek - Fix the problem of the front MIC on the Lenovo M715
+
+  * arm64: snapdragon: WARNING: CPU: 0 PID: 1 at drivers/irqchip/irq-gic.c:1016
+    gic_irq_domain_translate (LP: #1797143)
+    - SAUCE: arm64: dts: msm8916: camms: fix gic_irq_domain_translate warnings
+
+  * Dell new AIO requires a new uart backlight driver (LP: #1727235)
+    - SAUCE: platform/x86: dell-uart-backlight: new backlight driver for DELL AIO
+    - updateconfigs for Dell UART backlight driver
+
+  * Please make CONFIG_PWM_LPSS_PCI and CONFIG_PWM_LPSS_PLATFORM built in to
+    make brightness adjustment working on various BayTrail/CherryTrail-based
+    devices (LP: #1783964)
+    - [Config]: Make PWM_LPSS_* built-in
+
+  * check and fix zkey required kernel modules locations in debs, udebs, and
+    initramfs (LP: #1794346)
+    - [Config] add s390 crypto modules to crypt-modules udeb
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_VBOXGUEST=n
+    - ubuntu: vbox -- update to 5.2.18-dfsg-2
+    - ubuntu: enable vbox build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.19-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 15 Oct 2018 10:52:04 -0500
+
+linux (4.19.0-1.2) cosmic; urgency=medium
+
+  * Page leaking in cachefiles_read_backing_file while vmscan is active
+    (LP: #1793430)
+    - SAUCE: cachefiles: Page leaking in cachefiles_read_backing_file while vmscan
+      is active
+
+  * SRU: Enable middle button of touchpad on ThinkPad P72 (LP: #1793463)
+    - Input: elantech - enable middle button of touchpad on ThinkPad P72
+
+  * Improvements to the kernel source package preparation (LP: #1793461)
+    - [Packaging] startnewrelease: add support for backport kernels
+
+  * Fix unusable NVIDIA GPU after S3 (LP: #1793338)
+    - SAUCE: PCI: Reprogram bridge prefetch registers on resume
+
+  * Error reported when creating ZFS pool with "-t" option, despite successful
+    pool creation (LP: #1769937)
+    - SAUCE: (noup) Update zfs to 0.7.9-3ubuntu6
+
+  * device hotplug of vfio devices can lead to deadlock in vfio_pci_release
+    (LP: #1792099)
+    - SAUCE: vfio -- release device lock before userspace requests
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] retpoline -- fix temporary filenaming
+    - CONFIG_BCH_CONST_PARAMS=n
+    - Packaging: final-checks: remove trailing backport suffix
+    - SAUCE: import aufs driver
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.19-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 25 Sep 2018 16:32:24 -0500
+
+linux (4.19.0-0.1) cosmic; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu -- disable vbox build
+    - Disable zfs build
+    - SAUCE: Import aufs driver
+    - Update dropped.txt
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.19-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 13 Sep 2018 07:54:47 -0500
+
+linux (4.19.0-0.0) cosmic; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 13 Sep 2018 06:44:09 -0500
+
+linux (4.18.0-8.9) cosmic; urgency=medium
+
+  * linux: 4.18.0-8.9 -proposed tracker (LP: #1791663)
+
+  * Cosmic update to v4.18.7 stable release (LP: #1791660)
+    - rcu: Make expedited GPs handle CPU 0 being offline
+    - net: 6lowpan: fix reserved space for single frames
+    - net: mac802154: tx: expand tailroom if necessary
+    - 9p/net: Fix zero-copy path in the 9p virtio transport
+    - spi: davinci: fix a NULL pointer dereference
+    - spi: pxa2xx: Add support for Intel Ice Lake
+    - spi: spi-fsl-dspi: Fix imprecise abort on VF500 during probe
+    - spi: cadence: Change usleep_range() to udelay(), for atomic context
+    - mmc: block: Fix unsupported parallel dispatch of requests
+    - mmc: renesas_sdhi_internal_dmac: mask DMAC interrupts
+    - mmc: renesas_sdhi_internal_dmac: fix #define RST_RESERVED_BITS
+    - readahead: stricter check for bdi io_pages
+    - block: fix infinite loop if the device loses discard capability
+    - block: blk_init_allocated_queue() set q->fq as NULL in the fail case
+    - block: really disable runtime-pm for blk-mq
+    - blkcg: Introduce blkg_root_lookup()
+    - block: Introduce blk_exit_queue()
+    - block: Ensure that a request queue is dissociated from the cgroup controller
+    - apparmor: fix bad debug check in apparmor_secid_to_secctx()
+    - dma-buf: Move BUG_ON from _add_shared_fence to _add_shared_inplace
+    - libertas: fix suspend and resume for SDIO connected cards
+    - media: Revert "[media] tvp5150: fix pad format frame height"
+    - mailbox: xgene-slimpro: Fix potential NULL pointer dereference
+    - Replace magic for trusting the secondary keyring with #define
+    - Fix kexec forbidding kernels signed with keys in the secondary keyring to
+      boot
+    - powerpc/fadump: handle crash memory ranges array index overflow
+    - powerpc/64s: Fix page table fragment refcount race vs speculative references
+    - powerpc/pseries: Fix endianness while restoring of r3 in MCE handler.
+    - powerpc/pkeys: Give all threads control of their key permissions
+    - powerpc/pkeys: Deny read/write/execute by default
+    - powerpc/pkeys: key allocation/deallocation must not change pkey registers
+    - powerpc/pkeys: Save the pkey registers before fork
+    - powerpc/pkeys: Fix calculation of total pkeys.
+    - powerpc/pkeys: Preallocate execute-only key
+    - powerpc/nohash: fix pte_access_permitted()
+    - powerpc64/ftrace: Include ftrace.h needed for enable/disable calls
+    - powerpc/powernv/pci: Work around races in PCI bridge enabling
+    - cxl: Fix wrong comparison in cxl_adapter_context_get()
+    - IB/mlx5: Honor cnt_set_id_valid flag instead of set_id
+    - IB/mlx5: Fix leaking stack memory to userspace
+    - IB/srpt: Fix srpt_cm_req_recv() error path (1/2)
+    - IB/srpt: Fix srpt_cm_req_recv() error path (2/2)
+    - IB/srpt: Support HCAs with more than two ports
+    - overflow.h: Add arithmetic shift helper
+    - RDMA/mlx5: Fix shift overflow in mlx5_ib_create_wq
+    - ib_srpt: Fix a use-after-free in srpt_close_ch()
+    - ib_srpt: Fix a use-after-free in __srpt_close_all_ch()
+    - RDMA/rxe: Set wqe->status correctly if an unexpected response is received
+    - 9p: fix multiple NULL-pointer-dereferences
+    - fs/9p/xattr.c: catch the error of p9_client_clunk when setting xattr failed
+    - 9p/virtio: fix off-by-one error in sg list bounds check
+    - net/9p/client.c: version pointer uninitialized
+    - net/9p/trans_fd.c: fix race-condition by flushing workqueue before the
+      kfree()
+    - dm integrity: change 'suspending' variable from bool to int
+    - dm thin: stop no_space_timeout worker when switching to write-mode
+    - dm cache metadata: save in-core policy_hint_size to on-disk superblock
+    - dm cache metadata: set dirty on all cache blocks after a crash
+    - dm crypt: don't decrease device limits
+    - dm writecache: fix a crash due to reading past end of dirty_bitmap
+    - uart: fix race between uart_put_char() and uart_shutdown()
+    - Drivers: hv: vmbus: Fix the offer_in_progress in vmbus_process_offer()
+    - Drivers: hv: vmbus: Reset the channel callback in vmbus_onoffer_rescind()
+    - iio: sca3000: Fix missing return in switch
+    - iio: ad9523: Fix displayed phase
+    - iio: ad9523: Fix return value for ad952x_store()
+    - extcon: Release locking when sending the notification of connector state
+    - eventpoll.h: wrap casts in () properly
+    - vmw_balloon: fix inflation of 64-bit GFNs
+    - vmw_balloon: do not use 2MB without batching
+    - vmw_balloon: VMCI_DOORBELL_SET does not check status
+    - vmw_balloon: fix VMCI use when balloon built into kernel
+    - rtc: omap: fix resource leak in registration error path
+    - rtc: omap: fix potential crash on power off
+    - tracing: Do not call start/stop() functions when tracing_on does not change
+    - tracing/blktrace: Fix to allow setting same value
+    - printk/tracing: Do not trace printk_nmi_enter()
+    - livepatch: Validate module/old func name length
+    - uprobes: Use synchronize_rcu() not synchronize_sched()
+    - mfd: hi655x: Fix regmap area declared size for hi655x
+    - ovl: fix wrong use of impure dir cache in ovl_iterate()
+    - ACPICA: AML Parser: skip opcodes that open a scope upon parse failure
+    - ACPICA: Clear status of all events when entering sleep states
+    - drivers/block/zram/zram_drv.c: fix bug storing backing_dev
+    - sched: idle: Avoid retaining the tick when it has been stopped
+    - cpuidle: menu: Handle stopped tick more aggressively
+    - cpufreq: governor: Avoid accessing invalid governor_data
+    - PM / sleep: wakeup: Fix build error caused by missing SRCU support
+    - ALSA: ac97: fix device initialization in the compat layer
+    - ALSA: ac97: fix check of pm_runtime_get_sync failure
+    - ALSA: ac97: fix unbalanced pm_runtime_enable
+    - i2c: designware: Re-init controllers with pm_disabled set on resume
+    - KVM: VMX: fixes for vmentry_l1d_flush module parameter
+    - KVM: PPC: Book3S: Fix guest DMA when guest partially backed by THP pages
+    - xtensa: limit offsets in __loop_cache_{all,page}
+    - xtensa: increase ranges in ___invalidate_{i,d}cache_all
+    - block, bfq: return nbytes and not zero from struct cftype .write() method
+    - pnfs/blocklayout: off by one in bl_map_stripe()
+    - nfsd: fix leaked file lock with nfs exported overlayfs
+    - NFSv4 client live hangs after live data migration recovery
+    - NFSv4: Fix locking in pnfs_generic_recover_commit_reqs
+    - NFSv4: Fix a sleep in atomic context in nfs4_callback_sequence()
+    - ARM: tegra: Fix Tegra30 Cardhu PCA954x reset
+    - ARM: dts: am57xx-idk: Enable dual role for USB2 port
+    - pwm: omap-dmtimer: Return -EPROBE_DEFER if no dmtimer platform data
+    - mm/tlb: Remove tlb_remove_table() non-concurrent condition
+    - iommu/ipmmu-vmsa: Don't register as BUS IOMMU if machine doesn't have IPMMU-
+      VMSA
+    - iommu/vt-d: Add definitions for PFSID
+    - iommu/vt-d: Fix dev iotlb pfsid use
+    - sys: don't hold uts_sem while accessing userspace memory
+    - userns: move user access out of the mutex
+    - ubifs: Fix memory leak in lprobs self-check
+    - Revert "UBIFS: Fix potential integer overflow in allocation"
+    - ubifs: Check data node size before truncate
+    - ubifs: xattr: Don't operate on deleted inodes
+    - ubifs: Fix directory size calculation for symlinks
+    - ubifs: Fix synced_i_size calculation for xattr inodes
+    - pwm: tiehrpwm: Don't use emulation mode bits to control PWM output
+    - pwm: tiehrpwm: Fix disabling of output of PWMs
+    - fb: fix lost console when the user unplugs a USB adapter
+    - udlfb: fix semaphore value leak
+    - udlfb: fix display corruption of the last line
+    - udlfb: don't switch if we are switching to the same videomode
+    - udlfb: set optimal write delay
+    - udlfb: make a local copy of fb_ops
+    - udlfb: handle allocation failure
+    - udlfb: set line_length in dlfb_ops_set_par
+    - getxattr: use correct xattr length
+    - libnvdimm: Use max contiguous area for namespace size
+    - libnvdimm: fix ars_status output length calculation
+    - bcache: release dc->writeback_lock properly in bch_writeback_thread()
+    - kconfig: fix "Can't open ..." in parallel build
+    - perf auxtrace: Fix queue resize
+    - crypto: vmx - Fix sleep-in-atomic bugs
+    - crypto: aesni - Use unaligned loads from gcm_context_data
+    - crypto: arm64/sm4-ce - check for the right CPU feature bit
+    - crypto: caam - fix DMA mapping direction for RSA forms 2 & 3
+    - crypto: caam/jr - fix descriptor DMA unmapping
+    - crypto: caam/qi - fix error path in xts setkey
+    - fs/quota: Fix spectre gadget in do_quotactl
+    - udf: Fix mounting of Win7 created UDF filesystems
+    - cpuidle: menu: Retain tick when shallow state is selected
+    - arm64: mm: always enable CONFIG_HOLES_IN_ZONE
+    - Linux 4.18.7
+
+  * CVE-2017-5715
+    - s390: detect etoken facility
+    - KVM: s390: add etoken support for guests
+
+  * Missing Intel GPU pci-id's (LP: #1789924)
+    - drm/i915/whl: Introducing Whiskey Lake platform
+    - drm/i915/aml: Introducing Amber Lake platform
+    - drm/i915/cfl: Add a new CFL PCI ID.
+
+  * [18.10 FEAT] Add kernel config options for SMC-R/D (LP: #1789934)
+    - s390/ism: add device driver for internal shared memory
+    - CONFIG_ISM=y for s390
+
+  * Cosmic update to v4.18.6 stable release (LP: #1791105)
+    - PATCH scripts/kernel-doc
+    - scripts/kernel-doc: Escape all literal braces in regexes
+    - scsi: libsas: dynamically allocate and free ata host
+    - xprtrdma: Fix disconnect regression
+    - mei: don't update offset in write
+    - cifs: add missing support for ACLs in SMB 3.11
+    - CIFS: fix uninitialized ptr deref in smb2 signing
+    - cifs: add missing debug entries for kconfig options
+    - cifs: use a refcount to protect open/closing the cached file handle
+    - cifs: check kmalloc before use
+    - smb3: enumerating snapshots was leaving part of the data off end
+    - smb3: Do not send SMB3 SET_INFO if nothing changed
+    - smb3: don't request leases in symlink creation and query
+    - smb3: fill in statfs fsid and correct namelen
+    - btrfs: use correct compare function of dirty_metadata_bytes
+    - btrfs: don't leak ret from do_chunk_alloc
+    - Btrfs: fix mount failure after fsync due to hard link recreation
+    - Btrfs: fix btrfs_write_inode vs delayed iput deadlock
+    - Btrfs: fix send failure when root has deleted files still open
+    - Btrfs: send, fix incorrect file layout after hole punching beyond eof
+    - hwmon: (k10temp) 27C Offset needed for Threadripper2
+    - bpf, arm32: fix stack var offset in jit
+    - regulator: arizona-ldo1: Use correct device to get enable GPIO
+    - iommu/arm-smmu: Error out only if not enough context interrupts
+    - printk: Split the code for storing a message into the log buffer
+    - printk: Create helper function to queue deferred console handling
+    - printk/nmi: Prevent deadlock when accessing the main log buffer in NMI
+    - kprobes/arm64: Fix %p uses in error messages
+    - arm64: Fix mismatched cache line size detection
+    - arm64: Handle mismatched cache type
+    - arm64: mm: check for upper PAGE_SHIFT bits in pfn_valid()
+    - arm64: dts: rockchip: corrected uart1 clock-names for rk3328
+    - KVM: arm/arm64: Fix potential loss of ptimer interrupts
+    - KVM: arm/arm64: Fix lost IRQs from emulated physcial timer when blocked
+    - KVM: arm/arm64: Skip updating PMD entry if no change
+    - KVM: arm/arm64: Skip updating PTE entry if no change
+    - s390/kvm: fix deadlock when killed by oom
+    - perf kvm: Fix subcommands on s390
+    - stop_machine: Reflow cpu_stop_queue_two_works()
+    - stop_machine: Atomically queue and wake stopper threads
+    - ext4: check for NUL characters in extended attribute's name
+    - ext4: use ext4_warning() for sb_getblk failure
+    - ext4: sysfs: print ext4_super_block fields as little-endian
+    - ext4: reset error code in ext4_find_entry in fallback
+    - ext4: fix race when setting the bitmap corrupted flag
+    - x86/gpu: reserve ICL's graphics stolen memory
+    - platform/x86: wmi: Do not mix pages and kmalloc
+    - platform/x86: ideapad-laptop: Apply no_hw_rfkill to Y20-15IKBM, too
+    - mm: move tlb_table_flush to tlb_flush_mmu_free
+    - mm/tlb, x86/mm: Support invalidating TLB caches for RCU_TABLE_FREE
+    - x86/speculation/l1tf: Fix overflow in l1tf_pfn_limit() on 32bit
+    - x86/speculation/l1tf: Fix off-by-one error when warning that system has too
+      much RAM
+    - x86/speculation/l1tf: Suggest what to do on systems with too much RAM
+    - x86/vdso: Fix vDSO build if a retpoline is emitted
+    - x86/process: Re-export start_thread()
+    - KVM: x86: ensure all MSRs can always be KVM_GET/SET_MSR'd
+    - KVM: x86: SVM: Call x86_spec_ctrl_set_guest/host() with interrupts disabled
+    - fuse: Don't access pipe->buffers without pipe_lock()
+    - fuse: fix initial parallel dirops
+    - fuse: fix double request_end()
+    - fuse: fix unlocked access to processing queue
+    - fuse: umount should wait for all requests
+    - fuse: Fix oops at process_init_reply()
+    - fuse: Add missed unlock_page() to fuse_readpages_fill()
+    - lib/vsprintf: Do not handle %pO[^F] as %px
+    - udl-kms: change down_interruptible to down
+    - udl-kms: handle allocation failure
+    - udl-kms: fix crash due to uninitialized memory
+    - udl-kms: avoid division
+    - b43legacy/leds: Ensure NUL-termination of LED name string
+    - b43/leds: Ensure NUL-termination of LED name string
+    - ASoC: dpcm: don't merge format from invalid codec dai
+    - ASoC: zte: Fix incorrect PCM format bit usages
+    - ASoC: sirf: Fix potential NULL pointer dereference
+    - ASoC: wm_adsp: Correct DSP pointer for preloader control
+    - soc: qcom: rmtfs-mem: fix memleak in probe error paths
+    - pinctrl: freescale: off by one in imx1_pinconf_group_dbg_show()
+    - scsi: qla2xxx: Fix stalled relogin
+    - x86/vdso: Fix lsl operand order
+    - x86/nmi: Fix NMI uaccess race against CR3 switching
+    - x86/irqflags: Mark native_restore_fl extern inline
+    - x86/spectre: Add missing family 6 check to microcode check
+    - x86/speculation/l1tf: Increase l1tf memory limit for Nehalem+
+    - hwmon: (nct6775) Fix potential Spectre v1
+    - x86/entry/64: Wipe KASAN stack shadow before rewind_stack_do_exit()
+    - x86: Allow generating user-space headers without a compiler
+    - s390/mm: fix addressing exception after suspend/resume
+    - s390/lib: use expoline for all bcr instructions
+    - s390: fix br_r1_trampoline for machines without exrl
+    - s390/qdio: reset old sbal_state flags
+    - s390/numa: move initial setup of node_to_cpumask_map
+    - s390/purgatory: Fix crash with expoline enabled
+    - s390/purgatory: Add missing FORCE to Makefile targets
+    - kprobes: Show blacklist addresses as same as kallsyms does
+    - kprobes: Replace %p with other pointer types
+    - kprobes/arm: Fix %p uses in error messages
+    - kprobes: Make list and blacklist root user read only
+    - MIPS: Correct the 64-bit DSP accumulator register size
+    - MIPS: memset.S: Fix byte_fixup for MIPSr6
+    - MIPS: Always use -march=<arch>, not -<arch> shortcuts
+    - MIPS: Change definition of cpu_relax() for Loongson-3
+    - MIPS: lib: Provide MIPS64r6 __multi3() for GCC < 7
+    - tpm: Return the actual size when receiving an unsupported command
+    - tpm: separate cmd_ready/go_idle from runtime_pm
+    - scsi: mpt3sas: Fix calltrace observed while running IO & reset
+    - scsi: mpt3sas: Fix _transport_smp_handler() error path
+    - scsi: sysfs: Introduce sysfs_{un,}break_active_protection()
+    - scsi: core: Avoid that SCSI device removal through sysfs triggers a deadlock
+    - iscsi target: fix session creation failure handling
+    - mtd: rawnand: hynix: Use ->exec_op() in hynix_nand_reg_write_op()
+    - mtd: rawnand: fsmc: Stop using chip->read_buf()
+    - mtd: rawnand: marvell: add suspend and resume hooks
+    - mtd: rawnand: qcom: wait for desc completion in all BAM channels
+    - clk: rockchip: fix clk_i2sout parent selection bits on rk3399
+    - clk: npcm7xx: fix memory allocation
+    - PM / clk: signedness bug in of_pm_clk_add_clks()
+    - power: generic-adc-battery: fix out-of-bounds write when copying channel
+      properties
+    - power: generic-adc-battery: check for duplicate properties copied from iio
+      channels
+    - watchdog: Mark watchdog touch functions as notrace
+    - cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status
+    - x86/dumpstack: Don't dump kernel memory based on usermode RIP
+    - Linux 4.18.6
+    - updateconfigs after v4.18.6 stable update
+
+  * random oopses on s390 systems using NVMe devices (LP: #1790480)
+    - s390/pci: fix out of bounds access during irq setup
+
+  * [18.10 FEAT] zcrypt DD: introduce APQN tags to support deterministic driver
+    binding (LP: #1784331)
+    - s390/zcrypt: code beautify
+    - s390/zcrypt: AP bus support for alternate driver(s)
+    - s390/zcrypt: hex string mask improvements for apmask and aqmask.
+
+  * performance drop with ATS enabled (LP: #1788097)
+    - powerpc/powernv: Fix concurrency issue with npu->mmio_atsd_usage
+
+  * Fix MCE handling for user access of poisoned device-dax mapping
+    (LP: #1774366)
+    - device-dax: Convert to vmf_insert_mixed and vm_fault_t
+    - device-dax: Enable page_mapping()
+    - device-dax: Set page->index
+    - filesystem-dax: Set page->index
+    - mm, madvise_inject_error: Disable MADV_SOFT_OFFLINE for ZONE_DEVICE pages
+    - mm, dev_pagemap: Do not clear ->mapping on final put
+    - mm, madvise_inject_error: Let memory_failure() optionally take a page
+      reference
+    - mm, memory_failure: Collect mapping size in collect_procs()
+    - filesystem-dax: Introduce dax_lock_mapping_entry()
+    - mm, memory_failure: Teach memory_failure() about dev_pagemap pages
+    - x86/mm/pat: Prepare {reserve, free}_memtype() for "decoy" addresses
+    - x86/memory_failure: Introduce {set, clear}_mce_nospec()
+    - libnvdimm, pmem: Restore page attributes when clearing errors
+
+  * Reconcile hns3 SAUCE patches with upstream (LP: #1787477)
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix comments for
+      hclge_get_ring_chain_from_mbx"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for using wrong mask and
+      shift in hclge_get_ring_chain_from_mbx"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for reset_level default
+      assignment probelm"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unnecessary ring
+      configuration operation while resetting"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix return value error in
+      hns3_reset_notify_down_enet"
+    - Revert "UBUNTU: SAUCE: net: hns3: Fix for phy link issue when using marvell
+      phy driver"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: separate roce from nic when
+      resetting"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: correct reset event status
+      register"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: prevent to request reset
+      frequently"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: reset net device with rtnl_lock"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify the order of initializeing
+      command queue register"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: prevent sending command during
+      global or core reset"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Use roce handle when calling roce
+      callback function"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove the warning when clear
+      reset cause"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix get_vector ops in
+      hclgevf_main module"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix warning bug when doing lp
+      selftest"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add configure for mac minimal
+      frame size"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for mailbox message truncated
+      problem"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for l4 checksum offload bug"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for waterline not setting
+      correctly"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for mac pause not disable in
+      pfc mode"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix tc setup when netdev is first
+      up"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add calling roce callback
+      function when link status change"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: optimize the process of notifying
+      roce client"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add pf reset for hip08 RoCE"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add SPDX tags to hns3 driver"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused struct member and
+      definition"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix mislead parameter name"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify inconsistent bit mask
+      macros"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: use decimal for bit offset
+      macros"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix unreasonable code comments"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove extra space and brackets"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: standardize the handle of return
+      value"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some redundant
+      assignments"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify hnae_ to hnae3_"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: use dma_zalloc_coherent instead
+      of kzalloc/dma_map_single"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: give default option while
+      dependency HNS3 set"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some unused members of
+      some structures"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove a redundant
+      hclge_cmd_csq_done"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: using modulo for cyclic counters
+      in hclge_cmd_send"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: simplify hclge_cmd_csq_clean"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some redundant
+      assignments"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove useless code in
+      hclge_cmd_send"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused
+      hclge_ring_to_dma_dir"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: use lower_32_bits and
+      upper_32_bits"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove back in struct hclge_hw"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: add unlikely for error check"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove the Redundant put_vector
+      in hns3_client_uninit"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: print the ret value in error
+      information"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: extraction an interface for state
+      state init|uninit"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused head file in
+      hnae3.c"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: add l4_type check for both ipv4
+      and ipv6"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: add vector status check before
+      free vector"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: rename the interface for
+      init_client_instance and uninit_client_instance"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove hclge_get_vector_index
+      from hclge_bind_ring_with_vector"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: RX BD information valid only in
+      last BD except VLD bit and buffer size"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: add support for serdes loopback
+      selftest"
+    - net: hns3: Updates RX packet info fetch in case of multi BD
+    - net: hns3: remove hclge_get_vector_index from hclge_bind_ring_with_vector
+    - net: hns3: rename the interface for init_client_instance and
+      uninit_client_instance
+    - net: hns3: add vector status check before free vector
+    - net: hns3: add l4_type check for both ipv4 and ipv6
+    - net: hns3: add unlikely for error check
+    - net: hns3: remove unused head file in hnae3.c
+    - net: hns3: extraction an interface for state init|uninit
+    - net: hns3: print the ret value in error information
+    - net: hns3: remove the Redundant put_vector in hns3_client_uninit
+    - net: hns3: remove back in struct hclge_hw
+    - net: hns3: use lower_32_bits and upper_32_bits
+    - net: hns3: remove unused hclge_ring_to_dma_dir
+    - net: hns3: remove useless code in hclge_cmd_send
+    - net: hns3: remove some redundant assignments
+    - net: hns3: simplify hclge_cmd_csq_clean
+    - net: hns3: remove a redundant hclge_cmd_csq_done
+    - net: hns3: remove some unused members of some structures
+    - net: hns3: give default option while dependency HNS3 set
+    - net: hns3: use dma_zalloc_coherent instead of kzalloc/dma_map_single
+    - net: hns3: modify hnae_ to hnae3_
+    - net: hns3: Fix tc setup when netdev is first up
+    - net: hns3: Fix for mac pause not disable in pfc mode
+    - net: hns3: Fix for waterline not setting correctly
+    - net: hns3: Fix for l4 checksum offload bug
+    - net: hns3: Fix for mailbox message truncated problem
+    - net: hns3: Add configure for mac minimal frame size
+    - net: hns3: Fix warning bug when doing lp selftest
+    - net: hns3: Fix get_vector ops in hclgevf_main module
+    - net: hns3: Remove the warning when clear reset cause
+    - net: hns3: Prevent sending command during global or core reset
+    - net: hns3: Modify the order of initializing command queue register
+    - net: hns3: Reset net device with rtnl_lock
+    - net: hns3: Prevent to request reset frequently
+    - net: hns3: Correct reset event status register
+    - net: hns3: Fix return value error in hns3_reset_notify_down_enet
+    - net: hns3: remove unnecessary ring configuration operation while resetting
+    - net: hns3: Fix for reset_level default assignment probelm
+    - net: hns3: Fix for using wrong mask and shift in
+      hclge_get_ring_chain_from_mbx
+    - net: hns3: Fix comments for hclge_get_ring_chain_from_mbx
+    - net: hns3: Remove some redundant assignments
+    - net: hns3: Standardize the handle of return value
+    - net: hns3: Remove extra space and brackets
+    - net: hns3: Correct unreasonable code comments
+    - net: hns3: Use decimal for bit offset macros
+    - net: hns3: Modify inconsistent bit mask macros
+    - net: hns3: Fix misleading parameter name
+    - net: hns3: Remove unused struct member and definition
+    - net: hns3: Add SPDX tags to HNS3 PF driver
+    - net: hns3: Add support for serdes loopback selftest
+    - net: hns3: Fix for phy link issue when using marvell phy driver
+
+  * [Regression] kernel crashdump fails on arm64 (LP: #1786878)
+    - arm64: export memblock_reserve()d regions via /proc/iomem
+    - drivers: acpi: add dependency of EFI for arm64
+    - efi/arm: preserve early mapping of UEFI memory map longer for BGRT
+    - efi/arm: map UEFI memory map even w/o runtime services enabled
+    - arm64: acpi: fix alignment fault in accessing ACPI
+    - [Config] CONFIG_ARCH_SUPPORTS_ACPI=y
+    - arm64: fix ACPI dependencies
+    - ACPI: fix menuconfig presentation of ACPI submenu
+
+  * TB 16 issue on Dell Lattitude 7490 with large amount of data (LP: #1785780)
+    - r8152: disable RX aggregation on new Dell TB16 dock
+
+  * Support Power Management for Thunderbolt Controller  (LP: #1789358)
+    - thunderbolt: Use 64-bit DMA mask if supported by the platform
+    - thunderbolt: Do not unnecessarily call ICM get route
+    - thunderbolt: No need to take tb->lock in domain suspend/complete
+    - thunderbolt: Use correct ICM commands in system suspend
+    - thunderbolt: Add support for runtime PM
+
+  * Enable AMD PCIe MP2 for AMDI0011 (LP: #1773940)
+    - SAUCE: i2c:amd I2C Driver based on PCI Interface for upcoming platform
+    - SAUCE: i2c:amd move out pointer in union i2c_event_base
+    - SAUCE: i2c:amd Depends on ACPI
+    - [Config] i2c: CONFIG_I2C_AMD_MP2=y on x86
+
+  * Microphone cannot be detected with front panel audio combo jack on HP Z8-G4
+    machine (LP: #1789145)
+    - ALSA: hda/realtek - Fix HP Headset Mic can't record
+
+  * Please enable CONFIG_PAGE_POISONING (LP: #1783651)
+    - [Config] Enable CONFIG_PAGE_POISONING configs
+
+  * Tango platform uses __initcall without further checks (LP: #1787945)
+    - [Config] disable ARCH_TANGO
+
+  * [18.10 FEAT] SMC-Direct (LP: #1786902)
+    - net/smc: determine port attributes independent from pnet table
+    - net/smc: add pnetid support
+    - net/smc: add base infrastructure for SMC-D and ISM
+    - net/smc: add pnetid support for SMC-D and ISM
+    - net/smc: add SMC-D support in CLC messages
+    - net/smc: add SMC-D support in data transfer
+    - net/smc: add SMC-D support in af_smc
+    - net/smc: add SMC-D diag support
+    - net/smc: provide smc mode in smc_diag.c
+    - net/smc: eliminate cursor read and write calls
+    - net/smc: add function to get link group from link
+    - net/smc: use DECLARE_BITMAP for rtokens_used_mask
+    - net/smc: remove local variable page in smc_rx_splice()
+    - net/smc: Remove a WARN_ON() statement
+    - net/smc: Simplify ib_post_(send|recv|srq_recv)() calls
+    - net/smc: fewer parameters for smc_llc_send_confirm_link()
+    - net/smc: use correct vlan gid of RoCE device
+    - net/smc: provide fallback reason code
+    - net/smc: improve delete link processing
+    - net: simplify sock_poll_wait
+    - net/smc: send response to test link signal
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations for CONFIG_CRYPTO_SPECK_NEON
+    - [Config] fix up annotatios for CONFIG_CRYPTO_SPECK
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 10 Sep 2018 07:08:38 -0500
+
+linux (4.18.0-7.8) cosmic; urgency=medium
+
+  * linux: 4.18.0-7.8 -proposed tracker (LP: #1789459)
+
+  * pmtu.sh fails on 4.18 kernel (LP: #1789436)
+    - SAUCE: Revert "vti6: fix PMTU caching and reporting on xmit"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 Aug 2018 11:08:51 -0500
+
+linux (4.18.0-6.7) cosmic; urgency=medium
+
+  * linux: 4.18.0-6.7 -proposed tracker (LP: #1788881)
+
+  * systemd 237-3ubuntu10 ADT test failure with linux 4.18.0-5.6 (LP: #1787440)
+    - Config: Disable BPF_JIT_ALWAYS_ON on i386
+
+  * execveat03 in ubuntu_ltp_syscalls failed on X/B (LP: #1786729)
+    - cap_inode_getsecurity: use d_find_any_alias() instead of d_find_alias()
+
+  * Cosmic update to v4.18.5 stable release (LP: #1788874)
+    - EDAC: Add missing MEM_LRDDR4 entry in edac_mem_types[]
+    - pty: fix O_CLOEXEC for TIOCGPTPEER
+    - mm: Allow non-direct-map arguments to free_reserved_area()
+    - x86/mm/init: Pass unconverted symbol addresses to free_init_pages()
+    - x86/mm/init: Add helper for freeing kernel image pages
+    - x86/mm/init: Remove freed kernel image areas from alias mapping
+    - powerpc64s: Show ori31 availability in spectre_v1 sysfs file not v2
+    - ext4: fix spectre gadget in ext4_mb_regular_allocator()
+    - drm/i915/kvmgt: Fix potential Spectre v1
+    - drm/amdgpu/pm: Fix potential Spectre v1
+    - parisc: Remove unnecessary barriers from spinlock.h
+    - parisc: Remove ordered stores from syscall.S
+    - PCI: Restore resized BAR state on resume
+    - PCI / ACPI / PM: Resume all bridges on suspend-to-RAM
+    - PCI: hotplug: Don't leak pci_slot on registration failure
+    - PCI: aardvark: Size bridges before resources allocation
+    - PCI: Skip MPS logic for Virtual Functions (VFs)
+    - PCI: pciehp: Fix use-after-free on unplug
+    - PCI: pciehp: Fix unprotected list iteration in IRQ handler
+    - i2c: core: ACPI: Properly set status byte to 0 for multi-byte writes
+    - i2c: imx: Fix race condition in dma read
+    - reiserfs: fix broken xattr handling (heap corruption, bad retval)
+    - Linux 4.18.5
+
+  * [18.10 FEAT] Add kernel config option "CONFIG_SCLP_OFB" (LP: #1787898)
+    - [Config] CONFIG_SCLP_OFB=y for s390x
+
+  * errors when scanning partition table of corrupted AIX disk (LP: #1787281)
+    - partitions/aix: fix usage of uninitialized lv_info and lvname structures
+    - partitions/aix: append null character to print data from disk
+
+  * Apply NVMe bugfix from Google that bjf asked for (LP: #1787635)
+    - nvme-pci: add a memory barrier to nvme_dbbuf_update_and_check_event
+
+  * ThinkPad systems have no HDMI sound when using the nvidia GPU (LP: #1787058)
+    - ACPI / OSI: Add OEM _OSI string to enable NVidia HDMI audio
+
+  * Cosmic update to v4.18.4 stable release (LP: #1788454)
+    - l2tp: use sk_dst_check() to avoid race on sk->sk_dst_cache
+    - net_sched: fix NULL pointer dereference when delete tcindex filter
+    - net_sched: Fix missing res info when create new tc_index filter
+    - r8169: don't use MSI-X on RTL8168g
+    - ALSA: hda - Sleep for 10ms after entering D3 on Conexant codecs
+    - ALSA: hda - Turn CX8200 into D3 as well upon reboot
+    - ALSA: vx222: Fix invalid endian conversions
+    - ALSA: virmidi: Fix too long output trigger loop
+    - ALSA: cs5535audio: Fix invalid endian conversion
+    - ALSA: dice: fix wrong copy to rx parameters for Alesis iO26
+    - ALSA: hda: Correct Asrock B85M-ITX power_save blacklist entry
+    - ALSA: memalloc: Don't exceed over the requested size
+    - ALSA: vxpocket: Fix invalid endian conversions
+    - ALSA: seq: Fix poll() error return
+    - media: gl861: fix probe of dvb_usb_gl861
+    - USB: serial: sierra: fix potential deadlock at close
+    - USB: serial: pl2303: add a new device id for ATEN
+    - USB: option: add support for DW5821e
+    - ACPI / PM: save NVS memory for ASUS 1025C laptop
+    - tty: serial: 8250: Revert NXP SC16C2552 workaround
+    - serial: 8250_exar: Read INT0 from slave device, too
+    - serial: 8250_dw: always set baud rate in dw8250_set_termios
+    - serial: 8250_dw: Add ACPI support for uart on Broadcom SoC
+    - uio: fix wrong return value from uio_mmap()
+    - misc: sram: fix resource leaks in probe error path
+    - Revert "uio: use request_threaded_irq instead"
+    - Bluetooth: avoid killing an already killed socket
+    - isdn: Disable IIOCDBGVAR
+    - net: sock_diag: Fix spectre v1 gadget in __sock_diag_cmd()
+    - hv/netvsc: Fix NULL dereference at single queue mode fallback
+    - r8169: don't use MSI-X on RTL8106e
+    - ip_vti: fix a null pointer deferrence when create vti fallback tunnel
+    - net: ethernet: mvneta: Fix napi structure mixup on armada 3700
+    - net: mvneta: fix mvneta_config_rss on armada 3700
+    - cls_matchall: fix tcf_unbind_filter missing
+    - Linux 4.18.4
+
+  * Cosmic update to v4.18.3 stable release (LP: #1788453)
+    - x86/speculation/l1tf: Exempt zeroed PTEs from inversion
+    - Linux 4.18.3
+
+  * Cosmic update to v4.18.2 stable release (LP: #1788452)
+    - x86/l1tf: Fix build error seen if CONFIG_KVM_INTEL is disabled
+    - x86: i8259: Add missing include file
+    - x86/hyper-v: Check for VP_INVAL in hyperv_flush_tlb_others()
+    - x86/platform/UV: Mark memblock related init code and data correctly
+    - x86/mm/pti: Clear Global bit more aggressively
+    - xen/pv: Call get_cpu_address_sizes to set x86_virt/phys_bits
+    - x86/mm: Disable ioremap free page handling on x86-PAE
+    - kbuild: verify that $DEPMOD is installed
+    - crypto: ccree - fix finup
+    - crypto: ccree - fix iv handling
+    - crypto: ccp - Check for NULL PSP pointer at module unload
+    - crypto: ccp - Fix command completion detection race
+    - crypto: x86/sha256-mb - fix digest copy in sha256_mb_mgr_get_comp_job_avx2()
+    - crypto: vmac - require a block cipher with 128-bit block size
+    - crypto: vmac - separate tfm and request context
+    - crypto: blkcipher - fix crash flushing dcache in error path
+    - crypto: ablkcipher - fix crash flushing dcache in error path
+    - crypto: skcipher - fix aligning block size in skcipher_copy_iv()
+    - crypto: skcipher - fix crash flushing dcache in error path
+    - ioremap: Update pgtable free interfaces with addr
+    - x86/mm: Add TLB purge to free pmd/pte page interfaces
+    - Linux 4.18.2
+
+  * Cosmic update to v4.18.2 stable release (LP: #1788452) // CVE-2018-9363
+    - Bluetooth: hidp: buffer overflow in hidp_process_report
+
+  * linux-cloud-tools-common: Ensure hv-kvp-daemon.service starts before
+    walinuxagent.service (LP: #1739107)
+    - [Debian] hyper-v -- Ensure that hv-kvp-daemon.service starts before
+      walinuxagent.service
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: ipvs: remove nbsp characters from Kconfig
+    - [Config] CONFIG_MPROFILE_KERNEL=y for ppc64el
+    - [Config] CONFIG_DRM_RCAR_LVDS=m for snapdragon
+    - [Config] CONFIG_MDIO_MSCC_MIIM=n for s390x
+    - [Config] CONFIG_NET_VENDOR_MICROSEMI=n, CONFIG_NET_VENDOR_NI=n for s390x
+    - [Config] update annotations following config review
+    - [Debian] set CROSS_COMPILE when generating kernel configs
+    - [Config] Disable the Speck cipher
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 24 Aug 2018 14:18:15 -0500
+
+linux (4.18.0-5.6) cosmic; urgency=medium
+
+  * Cosmic update to v4.18.1 stable release (LP: #1787264)
+    - x86/paravirt: Fix spectre-v2 mitigations for paravirt guests
+    - x86/speculation: Protect against userspace-userspace spectreRSB
+    - kprobes/x86: Fix %p uses in error messages
+    - x86/irqflags: Provide a declaration for native_save_fl
+    - x86/speculation/l1tf: Increase 32bit PAE __PHYSICAL_PAGE_SHIFT
+    - x86/speculation/l1tf: Change order of offset/type in swap entry
+    - x86/speculation/l1tf: Protect swap entries against L1TF
+    - x86/speculation/l1tf: Protect PROT_NONE PTEs against speculation
+    - x86/speculation/l1tf: Make sure the first page is always reserved
+    - x86/speculation/l1tf: Add sysfs reporting for l1tf
+    - x86/speculation/l1tf: Disallow non privileged high MMIO PROT_NONE mappings
+    - x86/speculation/l1tf: Limit swap file size to MAX_PA/2
+    - x86/bugs: Move the l1tf function and define pr_fmt properly
+    - sched/smt: Update sched_smt_present at runtime
+    - x86/smp: Provide topology_is_primary_thread()
+    - x86/topology: Provide topology_smt_supported()
+    - cpu/hotplug: Make bringup/teardown of smp threads symmetric
+    - cpu/hotplug: Split do_cpu_down()
+    - cpu/hotplug: Provide knobs to control SMT
+    - x86/cpu: Remove the pointless CPU printout
+    - x86/cpu/AMD: Remove the pointless detect_ht() call
+    - x86/cpu/common: Provide detect_ht_early()
+    - x86/cpu/topology: Provide detect_extended_topology_early()
+    - x86/cpu/intel: Evaluate smp_num_siblings early
+    - x86/CPU/AMD: Do not check CPUID max ext level before parsing SMP info
+    - x86/cpu/AMD: Evaluate smp_num_siblings early
+    - x86/apic: Ignore secondary threads if nosmt=force
+    - x86/speculation/l1tf: Extend 64bit swap file size limit
+    - x86/cpufeatures: Add detection of L1D cache flush support.
+    - x86/CPU/AMD: Move TOPOEXT reenablement before reading smp_num_siblings
+    - x86/speculation/l1tf: Protect PAE swap entries against L1TF
+    - x86/speculation/l1tf: Fix up pte->pfn conversion for PAE
+    - Revert "x86/apic: Ignore secondary threads if nosmt=force"
+    - cpu/hotplug: Boot HT siblings at least once
+    - x86/KVM: Warn user if KVM is loaded SMT and L1TF CPU bug being present
+    - x86/KVM/VMX: Add module argument for L1TF mitigation
+    - x86/KVM/VMX: Add L1D flush algorithm
+    - x86/KVM/VMX: Add L1D MSR based flush
+    - x86/KVM/VMX: Add L1D flush logic
+    - x86/KVM/VMX: Split the VMX MSR LOAD structures to have an host/guest numbers
+    - x86/KVM/VMX: Add find_msr() helper function
+    - x86/KVM/VMX: Separate the VMX AUTOLOAD guest/host number accounting
+    - x86/KVM/VMX: Extend add_atomic_switch_msr() to allow VMENTER only MSRs
+    - x86/KVM/VMX: Use MSR save list for IA32_FLUSH_CMD if required
+    - cpu/hotplug: Online siblings when SMT control is turned on
+    - x86/litf: Introduce vmx status variable
+    - x86/kvm: Drop L1TF MSR list approach
+    - x86/l1tf: Handle EPT disabled state proper
+    - x86/kvm: Move l1tf setup function
+    - x86/kvm: Add static key for flush always
+    - x86/kvm: Serialize L1D flush parameter setter
+    - x86/kvm: Allow runtime control of L1D flush
+    - cpu/hotplug: Expose SMT control init function
+    - cpu/hotplug: Set CPU_SMT_NOT_SUPPORTED early
+    - x86/bugs, kvm: Introduce boot-time control of L1TF mitigations
+    - Documentation: Add section about CPU vulnerabilities
+    - x86/speculation/l1tf: Unbreak !__HAVE_ARCH_PFN_MODIFY_ALLOWED architectures
+    - x86/KVM/VMX: Initialize the vmx_l1d_flush_pages' content
+    - Documentation/l1tf: Fix typos
+    - cpu/hotplug: detect SMT disabled by BIOS
+    - x86/KVM/VMX: Don't set l1tf_flush_l1d to true from vmx_l1d_flush()
+    - x86/KVM/VMX: Replace 'vmx_l1d_flush_always' with 'vmx_l1d_flush_cond'
+    - x86/KVM/VMX: Move the l1tf_flush_l1d test to vmx_l1d_flush()
+    - x86/irq: Demote irq_cpustat_t::__softirq_pending to u16
+    - x86/KVM/VMX: Introduce per-host-cpu analogue of l1tf_flush_l1d
+    - x86: Don't include linux/irq.h from asm/hardirq.h
+    - x86/irq: Let interrupt handlers set kvm_cpu_l1tf_flush_l1d
+    - x86/KVM/VMX: Don't set l1tf_flush_l1d from vmx_handle_external_intr()
+    - Documentation/l1tf: Remove Yonah processors from not vulnerable list
+    - x86/speculation: Simplify sysfs report of VMX L1TF vulnerability
+    - x86/speculation: Use ARCH_CAPABILITIES to skip L1D flush on vmentry
+    - KVM: VMX: Tell the nested hypervisor to skip L1D flush on vmentry
+    - cpu/hotplug: Fix SMT supported evaluation
+    - x86/speculation/l1tf: Invert all not present mappings
+    - x86/speculation/l1tf: Make pmd/pud_mknotpresent() invert
+    - x86/mm/pat: Make set_memory_np() L1TF safe
+    - x86/mm/kmmio: Make the tracer robust against L1TF
+    - tools headers: Synchronise x86 cpufeatures.h for L1TF additions
+    - x86/microcode: Allow late microcode loading with SMT disabled
+    - x86/smp: fix non-SMP broken build due to redefinition of
+      apic_id_is_primary_thread
+    - cpu/hotplug: Non-SMP machines do not make use of booted_once
+    - x86/init: fix build with CONFIG_SWAP=n
+    - Linux 4.18.1
+    - [Config] updateconfigs after v4.18.1 stable update
+
+  * Consider enabling CONFIG_NETWORK_PHY_TIMESTAMPING (LP: #1785816)
+    - [Config] Enable timestamping in network PHY devices
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_SYSCTL_SYSCALL=n
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 15 Aug 2018 14:20:59 -0500
+
+linux (4.18.0-4.5) cosmic; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 06 Aug 2018 13:54:02 -0500
+
+linux (4.18.0-3.4) cosmic; urgency=medium
+
+  * Suspend fails in Ubuntu and Kubuntu 18.04 but works fine in Ubuntu and
+    Kubuntu 17.10 (and on Kubuntu 18.04 using kernel 4.14.47) (LP: #1774950)
+    - ACPI / LPSS: Avoid PM quirks on suspend and resume from hibernation
+
+  * hinic interfaces aren't getting predictable names (LP: #1783138)
+    - hinic: Link the logical network device to the pci device in sysfs
+
+  * libvirtd is unable to configure bridge devices inside of LXD containers
+    (LP: #1784501)
+    - kernfs: allow creating kernfs objects with arbitrary uid/gid
+    - sysfs, kobject: allow creating kobject belonging to arbitrary users
+    - kobject: kset_create_and_add() - fetch ownership info from parent
+    - driver core: set up ownership of class devices in sysfs
+    - net-sysfs: require net admin in the init ns for setting tx_maxrate
+    - net-sysfs: make sure objects belong to container's owner
+    - net: create reusable function for getting ownership info of sysfs inodes
+    - bridge: make sure objects belong to container's owner
+    - sysfs: Fix regression when adding a file to an existing group
+
+  * locking sockets broken due to missing AppArmor socket mediation patches
+    (LP: #1780227)
+    - UBUNTU SAUCE: apparmor: fix apparmor mediating locking non-fs, unix sockets
+
+  * Update2 for ocxl driver (LP: #1781436)
+    - ocxl: Fix page fault handler in case of fault on dying process
+
+  * HDMI/DP audio can't work on the laptop of Dell Latitude 5495 (LP: #1782689)
+    - ALSA: hda: use PCI_BASE_CLASS_DISPLAY to replace PCI_CLASS_DISPLAY_VGA
+    - vga_switcheroo: set audio client id according to bound GPU id
+
+  * Allow Raven Ridge's audio controller to be runtime suspended (LP: #1782540)
+    - ALSA: hda: Add AZX_DCAPS_PM_RUNTIME for AMD Raven Ridge
+
+  * Invoking obsolete 'firmware_install' target breaks snap build (LP: #1782166)
+    - snapcraft.yaml: stop invoking the obsolete (and non-existing)
+      'firmware_install' target
+
+  * snapcraft.yaml: missing ubuntu-retpoline-extract-one script breaks the build
+    (LP: #1782116)
+    - snapcraft.yaml: copy retpoline-extract-one to scripts before build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 01 Aug 2018 08:49:40 -0500
+
+linux (4.18.0-2.3) cosmic; urgency=medium
+
+  * Kernel error "task zfs:pid blocked for more than 120 seconds" (LP: #1781364)
+    - SAUCE: (noup) zfs to 0.7.9-3ubuntu4
+
+  * [Regression] EXT4-fs error (device sda1): ext4_validate_inode_bitmap:99:
+    comm stress-ng: Corrupt inode bitmap (LP: #1780137)
+    - SAUCE: ext4: fix ext4_validate_inode_bitmap: comm stress-ng: Corrupt inode
+      bitmap
+
+  * Cloud-init causes potentially huge boot delays with 4.15 kernels
+    (LP: #1780062)
+    - random: Make getrandom() ready earlier
+
+  * hisi_sas_v3_hw: internal task abort: timeout and not done. (LP: #1777736)
+    - scsi: hisi_sas: Update a couple of register settings for v3 hw
+
+  * hisi_sas: Add missing PHY spinlock init (LP: #1777734)
+    - scsi: hisi_sas: Add missing PHY spinlock init
+
+  * hisi_sas: improve read performance by pre-allocating slot DMA buffers
+    (LP: #1777727)
+    - scsi: hisi_sas: Use dmam_alloc_coherent()
+    - scsi: hisi_sas: Pre-allocate slot DMA buffers
+
+  * hisi_sas: Failures during host reset (LP: #1777696)
+    - scsi: hisi_sas: Only process broadcast change in phy_bcast_v3_hw()
+    - scsi: hisi_sas: Fix the conflict between dev gone and host reset
+    - scsi: hisi_sas: Adjust task reject period during host reset
+    - scsi: hisi_sas: Add a flag to filter PHY events during reset
+    - scsi: hisi_sas: Release all remaining resources in clear nexus ha
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.9-3ubuntu2, zfs to 0.7.9-3ubuntu3
+    - SAUCE: mm: Fix exports that inadvertently make put_page() EXPORT_SYMBOL_GPL
+    - Enable zfs build
+    - SAUCE: Import aufs driver
+    - Revert "UBUNTU: [Config]: set CONFIG_EDAC_DEBUG=y for ARM64"
+    - [Config] retpoline -- review and accept retpoline changes
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc5
+  * Rebase to v4.18-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 24 Jul 2018 08:41:22 -0500
+
+linux (4.18.0-1.2) cosmic; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 09 Jul 2018 07:36:31 -0500
+
+linux (4.18.0-0.1) cosmic; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu -- disable vbox build
+    - Disable zfs build
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) ima: require secure_boot rules in lockdown mode
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) efi: Add EFI signature data types
+    - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) lockdown: fix coordination of kernel module signature
+      verification
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) efi: Don't print secure boot state from the efi stub
+    - SAUCE: (namespace) block_dev: Support checking inode permissions in
+      lookup_bdev()
+    - SAUCE: (namespace) block_dev: Check permissions towards block device inode
+      when mounting
+    - SAUCE: (namespace) mtd: Check permissions towards mtd block device inode
+      when mounting
+    - SAUCE: (namespace) ext4: Add support for unprivileged mounts from user
+      namespaces
+    - SAUCE: (namespace) ext4: Add module parameter to enable user namespace
+      mounts
+    - SAUCE: (namespace) block_dev: Forbid unprivileged mounting when device is
+      opened for writing
+    - SAUCE: Import aufs driver
+    - Update dropped.txt
+    - [Config] updateconfigs after 4.18-rc3 rebase
+    - SAUCE: (no-up): ASoC: Intel: bytcr-rt5660: Remove snd_soc_codec use for 4.18
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 06 Jul 2018 10:46:37 -0500
+
+linux (4.18.0-0.0) cosmic; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 03 Jul 2018 11:10:33 -0500
+
+linux (4.17.0-4.5) cosmic; urgency=medium
+
+  * linux: 4.17.0-4.5 -proposed tracker (LP: #1779399)
+
+  * Update to ocxl driver for 18.04.1 (LP: #1775786)
+    - powerpc: Add TIDR CPU feature for POWER9
+    - powerpc: Use TIDR CPU feature to control TIDR allocation
+    - powerpc: use task_pid_nr() for TID allocation
+    - ocxl: Rename pnv_ocxl_spa_remove_pe to clarify it's action
+    - ocxl: Expose the thread_id needed for wait on POWER9
+    - ocxl: Add an IOCTL so userspace knows what OCXL features are available
+    - ocxl: Document new OCXL IOCTLs
+    - ocxl: Fix missing unlock on error in afu_ioctl_enable_p9_wait()
+
+  * Please include ax88179_178a and r8152 modules in d-i udeb (LP: #1771823)
+    - [Config:] d-i: Add ax88179_178a and r8152 to nic-modules
+
+  * glibc pkeys test fail on powerpc (LP: #1776967)
+    - [Config] Temporarily disable CONFIG_PPC_MEM_KEYS
+
+  * After update to 4.13-43 Intel Graphics are Laggy (LP: #1773520)
+    - Revert "drm/i915/edp: Allow alternate fixed mode for eDP if available."
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.9-3ubuntu1, zfs to 0.7.9-3ubuntu1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 29 Jun 2018 13:37:52 -0500
+
+linux (4.17.0-3.4) cosmic; urgency=medium
+
+  * linux: 4.17.0-3.4 -proposed tracker (LP: #1779124)
+
+  * Cosmic update to v4.17.3 stable release (LP: #1778997)
+    - net: aquantia: fix unsigned numvecs comparison with less than zero
+    - bonding: re-evaluate force_primary when the primary slave name changes
+    - cdc_ncm: avoid padding beyond end of skb
+    - ipv6: allow PMTU exceptions to local routes
+    - net: dsa: add error handling for pskb_trim_rcsum
+    - net: phy: dp83822: use BMCR_ANENABLE instead of BMSR_ANEGCAPABLE for DP83620
+    - net/sched: act_simple: fix parsing of TCA_DEF_DATA
+    - tcp: verify the checksum of the first data segment in a new connection
+    - tls: fix use-after-free in tls_push_record
+    - tls: fix waitall behavior in tls_sw_recvmsg
+    - socket: close race condition between sock_close() and sockfs_setattr()
+    - udp: fix rx queue len reported by diag and proc interface
+    - net: in virtio_net_hdr only add VLAN_HLEN to csum_start if payload holds
+      vlan
+    - hv_netvsc: Fix a network regression after ifdown/ifup
+    - ACPICA: AML parser: attempt to continue loading table after error
+    - ext4: fix hole length detection in ext4_ind_map_blocks()
+    - ext4: update mtime in ext4_punch_hole even if no blocks are released
+    - ext4: do not allow external inodes for inline data
+    - ext4: bubble errors from ext4_find_inline_data_nolock() up to ext4_iget()
+    - ext4: correctly handle a zero-length xattr with a non-zero e_value_offs
+    - ext4: fix fencepost error in check for inode count overflow during resize
+    - driver core: Don't ignore class_dir_create_and_add() failure.
+    - Btrfs: allow empty subvol= again
+    - Btrfs: fix clone vs chattr NODATASUM race
+    - Btrfs: fix memory and mount leak in btrfs_ioctl_rm_dev_v2()
+    - btrfs: return error value if create_io_em failed in cow_file_range
+    - btrfs: scrub: Don't use inode pages for device replace
+    - ALSA: usb-audio: Disable the quirk for Nura headset
+    - ALSA: hda/conexant - Add fixup for HP Z2 G4 workstation
+    - ALSA: hda - Handle kzalloc() failure in snd_hda_attach_pcm_stream()
+    - ALSA: hda: add dock and led support for HP EliteBook 830 G5
+    - ALSA: hda: add dock and led support for HP ProBook 640 G4
+    - x86/MCE: Fix stack out-of-bounds write in mce-inject.c: Flags_read()
+    - smb3: fix various xid leaks
+    - smb3: on reconnect set PreviousSessionId field
+    - CIFS: 511c54a2f69195b28afb9dd119f03787b1625bb4 adds a check for session
+      expiry
+    - cifs: For SMB2 security informaion query, check for minimum sized security
+      descriptor instead of sizeof FileAllInformation class
+    - nbd: fix nbd device deletion
+    - nbd: update size when connected
+    - nbd: use bd_set_size when updating disk size
+    - blk-mq: reinit q->tag_set_list entry only after grace period
+    - bdi: Move cgroup bdi_writeback to a dedicated low concurrency workqueue
+    - cpufreq: Fix new policy initialization during limits updates via sysfs
+    - cpufreq: ti-cpufreq: Fix an incorrect error return value
+    - cpufreq: governors: Fix long idle detection logic in load calculation
+    - libata: zpodd: small read overflow in eject_tray()
+    - libata: Drop SanDisk SD7UB3Q*G1001 NOLPM quirk
+    - nvme/pci: Sync controller reset for AER slot_reset
+    - w1: mxc_w1: Enable clock before calling clk_get_rate() on it
+    - x86/vector: Fix the args of vector_alloc tracepoint
+    - x86/apic/vector: Prevent hlist corruption and leaks
+    - x86/apic: Provide apic_ack_irq()
+    - x86/ioapic: Use apic_ack_irq()
+    - x86/platform/uv: Use apic_ack_irq()
+    - irq_remapping: Use apic_ack_irq()
+    - genirq/generic_pending: Do not lose pending affinity update
+    - genirq/affinity: Defer affinity setting if irq chip is busy
+    - genirq/migration: Avoid out of line call if pending is not set
+    - x86/intel_rdt: Enable CMT and MBM on new Skylake stepping
+    - media: uvcvideo: Prevent setting unavailable flags
+    - media: rc: ensure input/lirc device can be opened after register
+    - iwlwifi: fw: harden page loading code
+    - orangefs: set i_size on new symlink
+    - orangefs: report attributes_mask and attributes for statx
+    - HID: intel_ish-hid: ipc: register more pm callbacks to support hibernation
+    - HID: wacom: Correct logical maximum Y for 2nd-gen Intuos Pro large
+    - vhost: fix info leak due to uninitialized memory
+    - mm, page_alloc: do not break __GFP_THISNODE by zonelist reset
+    - Linux 4.17.3
+
+  * Use-after-free in sk_peer_label (LP: #1778646)
+    - SAUCE: apparmor: fix use after free in sk_peer_label
+
+  * kernel: Fix memory leak on CCA and EP11 CPRB processing. (LP: #1775390)
+    - s390/zcrypt: Fix CCA and EP11 CPRB processing failure memory leak.
+
+  * Various fixes for CXL kernel module (LP: #1774471)
+    - cxl: Configure PSL to not use APC virtual machines
+    - cxl: Disable prefault_mode in Radix mode
+
+  * Bluetooth not working (LP: #1764645)
+    - Bluetooth: btusb: Apply QCA Rome patches for some ATH3012 models
+
+  * Fake SAS addresses for SATA disks on HiSilicon D05 are non-unique
+    (LP: #1776750)
+    - scsi: hisi_sas: make SAS address of SATA disks unique
+
+  * linux-snapdragon: wcn36xx: mac address generation on boot (LP: #1776491)
+    - [Config] arm64: snapdragon: WCN36XX_SNAPDRAGON_HACKS=y
+    - SAUCE: wcn36xx: read MAC from file or randomly generate one
+
+  * Lenovo V330 needs patch in ideapad_laptop module for rfkill (LP: #1774636)
+    - SAUCE: Add Lenovo V330 to the ideapad_laptop rfkill blacklist
+
+  * register on binfmt_misc may overflow and crash the system (LP: #1775856)
+    - fs/binfmt_misc.c: do not allow offset overflow
+
+  * Network installs fail on SocioNext board (LP: #1775884)
+    - net: socionext: reset hardware in ndo_stop
+    - net: netsec: enable tx-irq during open callback
+
+  * Fix several bugs in RDMA/hns driver (LP: #1770974)
+    - RDMA/hns: Drop local zgid in favor of core defined variable
+    - RDMA/hns: Add 64KB page size support for hip08
+    - RDMA/hns: Rename the idx field of db
+    - RDMA/hns: Modify uar allocation algorithm to avoid bitmap exhaust
+    - RDMA/hns: Increase checking CMQ status timeout value
+    - RDMA/hns: Add reset process for RoCE in hip08
+    - RDMA/hns: Fix the illegal memory operation when cross page
+    - RDMA/hns: Implement the disassociate_ucontext API
+
+  * powerpc/livepatch: Implement reliable stack tracing for the consistency
+    model (LP: #1771844)
+    - powerpc/livepatch: Implement reliable stack tracing for the consistency
+      model
+
+  * Adding back alx WoL feature (LP: #1772610)
+    - SAUCE: Revert "alx: remove WoL support"
+    - SAUCE: alx: add enable_wol paramenter
+
+  * Lancer A0 Asic HBA's won't boot with 18.04 (LP: #1768103)
+    - scsi: lpfc: Fix WQ/CQ creation for older asic's.
+    - scsi: lpfc: Fix 16gb hbas failing cq create.
+
+  * [LTCTest][OPAL][OP920] cpupower idle-info is not listing stop4 and stop5
+    idle states when all CORES are guarded (LP: #1771780)
+    - powerpc/powernv/cpuidle: Init all present cpus for deep states
+
+  * Huawei 25G/100G Network Adapters Unsupported (LP: #1770970)
+    - net-next/hinic: add pci device ids for 25ge and 100ge card
+
+  * Expose arm64 CPU topology to userspace (LP: #1770231)
+    - drivers: base: cacheinfo: move cache_setup_of_node()
+    - drivers: base: cacheinfo: setup DT cache properties early
+    - cacheinfo: rename of_node to fw_token
+    - arm64/acpi: Create arch specific cpu to acpi id helper
+    - ACPI/PPTT: Add Processor Properties Topology Table parsing
+    - [Config] CONFIG_ACPI_PPTT=y
+    - ACPI: Enable PPTT support on ARM64
+    - drivers: base cacheinfo: Add support for ACPI based firmware tables
+    - arm64: Add support for ACPI based firmware tables
+    - arm64: topology: rename cluster_id
+    - arm64: topology: enable ACPI/PPTT based CPU topology
+    - ACPI: Add PPTT to injectable table list
+    - arm64: topology: divorce MC scheduling domain from core_siblings
+
+  * Vcs-Git header on bionic linux source package points to zesty git tree
+    (LP: #1766055)
+    - [Packaging]: Update Vcs-Git
+
+  * Request to revert SAUCE patches in the 18.04 SRU and update with upstream
+    version (LP: #1768431)
+    - scsi: cxlflash: Handle spurious interrupts
+    - scsi: cxlflash: Remove commmands from pending list on timeout
+    - scsi: cxlflash: Synchronize reset and remove ops
+    - SAUCE: (no-up) cxlflash: OCXL diff between v2 and v3
+
+  * hisi_sas robustness fixes (LP: #1774466)
+    - scsi: hisi_sas: delete timer when removing hisi_sas driver
+    - scsi: hisi_sas: print device id for errors
+    - scsi: hisi_sas: Add some checks to avoid free'ing a sas_task twice
+    - scsi: hisi_sas: check host frozen before calling "done" function
+    - scsi: hisi_sas: check sas_dev gone earlier in hisi_sas_abort_task()
+    - scsi: hisi_sas: stop controller timer for reset
+    - scsi: hisi_sas: update PHY linkrate after a controller reset
+    - scsi: hisi_sas: change slot index allocation mode
+    - scsi: hisi_sas: Change common allocation mode of device id
+    - scsi: hisi_sas: Reset disks when discovered
+    - scsi: hisi_sas: Create a scsi_host_template per HW module
+    - scsi: hisi_sas: Init disks after controller reset
+    - scsi: hisi_sas: Try wait commands before before controller reset
+    - scsi: hisi_sas: Include TMF elements in struct hisi_sas_slot
+    - scsi: hisi_sas: Add v2 hw force PHY function for internal ATA command
+    - scsi: hisi_sas: Terminate STP reject quickly for v2 hw
+    - scsi: hisi_sas: Fix return value when get_free_slot() failed
+    - scsi: hisi_sas: Mark PHY as in reset for nexus reset
+
+  * hisi_sas: Support newer v3 hardware (LP: #1774467)
+    - scsi: hisi_sas: update RAS feature for later revision of v3 HW
+    - scsi: hisi_sas: check IPTT is valid before using it for v3 hw
+    - scsi: hisi_sas: fix PI memory size
+    - scsi: hisi_sas: config ATA de-reset as an constrained command for v3 hw
+    - scsi: hisi_sas: remove redundant handling to event95 for v3
+    - scsi: hisi_sas: add readl poll timeout helper wrappers
+    - scsi: hisi_sas: workaround a v3 hw hilink bug
+    - scsi: hisi_sas: Add LED feature for v3 hw
+
+  * hisi_sas: improve performance by optimizing DQ locking (LP: #1774472)
+    - scsi: hisi_sas: optimise the usage of DQ locking
+    - scsi: hisi_sas: relocate smp sg map
+    - scsi: hisi_sas: make return type of prep functions void
+    - scsi: hisi_sas: allocate slot buffer earlier
+    - scsi: hisi_sas: Don't lock DQ for complete task sending
+    - scsi: hisi_sas: Use device lock to protect slot alloc/free
+    - scsi: hisi_sas: add check of device in hisi_sas_task_exec()
+    - scsi: hisi_sas: fix a typo in hisi_sas_task_prep()
+
+  * FS-Cache: Assertion failed: FS-Cache: 6 == 5 is false (LP: #1774336)
+    - SAUCE: CacheFiles: fix a read_waiter/read_copier race
+
+  * enable mic-mute hotkey and led on Lenovo M820z and M920z (LP: #1774306)
+    - ALSA: hda/realtek - Enable mic-mute hotkey for several Lenovo AIOs
+
+  * hns3 driver updates (LP: #1768670)
+    - net: hns3: Remove error log when getting pfc stats fails
+    - net: hns3: fix to correctly fetch l4 protocol outer header
+    - net: hns3: Fixes the out of bounds access in hclge_map_tqp
+    - net: hns3: Fixes the error legs in hclge_init_ae_dev function
+    - net: hns3: fix for phy_addr error in hclge_mac_mdio_config
+    - net: hns3: Fix to support autoneg only for port attached with phy
+    - net: hns3: fix a dead loop in hclge_cmd_csq_clean
+    - net: hns3: Fix for packet loss due wrong filter config in VLAN tbls
+    - net: hns3: Remove packet statistics in the range of 8192~12287
+    - net: hns3: Add support of hardware rx-vlan-offload to HNS3 VF driver
+    - net: hns3: Fix for setting mac address when resetting
+    - net: hns3: remove add/del_tunnel_udp in hns3_enet module
+    - net: hns3: fix for cleaning ring problem
+    - net: hns3: refactor the loopback related function
+    - net: hns3: Fix for deadlock problem occurring when unregistering ae_algo
+    - net: hns3: Fix for the null pointer problem occurring when initializing
+      ae_dev failed
+    - net: hns3: Add a check for client instance init state
+    - net: hns3: Change return type of hnae3_register_ae_dev
+    - net: hns3: Change return type of hnae3_register_ae_algo
+    - net: hns3: Change return value in hnae3_register_client
+    - net: hns3: Fixes the back pressure setting when sriov is enabled
+    - net: hns3: Fix for fiber link up problem
+    - net: hns3: Add support of .sriov_configure in HNS3 driver
+    - net: hns3: Fixes the missing PCI iounmap for various legs
+    - net: hns3: Fixes error reported by Kbuild and internal review
+    - net: hns3: Fixes API to fetch ethernet header length with kernel default
+    - net: hns3: cleanup of return values in hclge_init_client_instance()
+    - net: hns3: Fix the missing client list node initialization
+    - net: hns3: Fix for hns3 module is loaded multiple times problem
+    - net: hns3: Use enums instead of magic number in hclge_is_special_opcode
+    - net: hns3: Fix for netdev not running problem after calling net_stop and
+      net_open
+    - net: hns3: Fixes kernel panic issue during rmmod hns3 driver
+    - net: hns3: Fix for CMDQ and Misc. interrupt init order problem
+    - net: hns3: Updates RX packet info fetch in case of multi BD
+    - net: hns3: Add support for tx_accept_tag2 and tx_accept_untag2 config
+    - net: hns3: Add STRP_TAGP field support for hardware revision 0x21
+    - net: hns3: Add support to enable TX/RX promisc mode for H/W rev(0x21)
+    - net: hns3: Fix for PF mailbox receving unknown message
+    - net: hns3: Fixes the state to indicate client-type initialization
+    - net: hns3: Fixes the init of the VALID BD info in the descriptor
+    - net: hns3: Removes unnecessary check when clearing TX/RX rings
+    - net: hns3: Clear TX/RX rings when stopping port & un-initializing client
+    - net: hns3: Remove unused led control code
+    - net: hns3: Adds support for led locate command for copper port
+    - net: hns3: Fixes initalization of RoCE handle and makes it conditional
+    - net: hns3: Disable vf vlan filter when vf vlan table is full
+    - net: hns3: Add support for IFF_ALLMULTI flag
+    - net: hns3: Add repeat address checking for setting mac address
+    - net: hns3: Fix setting mac address error
+    - net: hns3: Fix for service_task not running problem after resetting
+    - net: hns3: Fix for hclge_reset running repeatly problem
+    - net: hns3: Fix for phy not link up problem after resetting
+    - net: hns3: Add missing break in misc_irq_handle
+    - net: hns3: Fix for vxlan tx checksum bug
+    - net: hns3: Optimize the PF's process of updating multicast MAC
+    - net: hns3: Optimize the VF's process of updating multicast MAC
+    - SAUCE: {topost} net: hns3: add support for serdes loopback selftest
+    - SAUCE: {topost} net: hns3: RX BD information valid only in last BD except
+      VLD bit and buffer size
+    - SAUCE: {topost} net: hns3: remove hclge_get_vector_index from
+      hclge_bind_ring_with_vector
+    - SAUCE: {topost} net: hns3: rename the interface for init_client_instance and
+      uninit_client_instance
+    - SAUCE: {topost} net: hns3: add vector status check before free vector
+    - SAUCE: {topost} net: hns3: add l4_type check for both ipv4 and ipv6
+    - SAUCE: {topost} net: hns3: remove unused head file in hnae3.c
+    - SAUCE: {topost} net: hns3: extraction an interface for state state
+      init|uninit
+    - SAUCE: {topost} net: hns3: print the ret value in error information
+    - SAUCE: {topost} net: hns3: remove the Redundant put_vector in
+      hns3_client_uninit
+    - SAUCE: {topost} net: hns3: add unlikely for error check
+    - SAUCE: {topost} net: hns3: remove back in struct hclge_hw
+    - SAUCE: {topost} net: hns3: use lower_32_bits and upper_32_bits
+    - SAUCE: {topost} net: hns3: remove unused hclge_ring_to_dma_dir
+    - SAUCE: {topost} net: hns3: remove useless code in hclge_cmd_send
+    - SAUCE: {topost} net: hns3: remove some redundant assignments
+    - SAUCE: {topost} net: hns3: simplify hclge_cmd_csq_clean
+    - SAUCE: {topost} net: hns3: using modulo for cyclic counters in
+      hclge_cmd_send
+    - SAUCE: {topost} net: hns3: remove a redundant hclge_cmd_csq_done
+    - SAUCE: {topost} net: hns3: remove some unused members of some structures
+    - SAUCE: {topost} net: hns3: give default option while dependency HNS3 set
+    - SAUCE: {topost} net: hns3: use dma_zalloc_coherent instead of
+      kzalloc/dma_map_single
+    - SAUCE: {topost} net: hns3: modify hnae_ to hnae3_
+    - SAUCE: {topost} net: hns3: fix unused function warning in VF driver
+    - SAUCE: {topost} net: hns3: remove some redundant assignments
+    - SAUCE: {topost} net: hns3: standardize the handle of return value
+    - SAUCE: {topost} net: hns3: remove extra space and brackets
+    - SAUCE: {topost} net: hns3: fix unreasonable code comments
+    - SAUCE: {topost} net: hns3: use decimal for bit offset macros
+    - SAUCE: {topost} net: hns3: modify inconsistent bit mask macros
+    - SAUCE: {topost} net: hns3: fix mislead parameter name
+    - SAUCE: {topost} net: hns3: remove unused struct member and definition
+    - SAUCE: {topost} net: hns3: Add SPDX tags to hns3 driver
+    - SAUCE: {topost} net: hns3: Add pf reset for hip08 RoCE
+    - SAUCE: {topost} net: hns3: optimize the process of notifying roce client
+    - SAUCE: {topost} net: hns3: Add calling roce callback function when link
+      status change
+    - SAUCE: {topost} net: hns3: fix tc setup when netdev is first up
+    - SAUCE: {topost} net: hns3: fix for mac pause not disable in pfc mode
+    - SAUCE: {topost} net: hns3: fix for waterline not setting correctly
+    - SAUCE: {topost} net: hns3: fix for l4 checksum offload bug
+    - SAUCE: {topost} net: hns3: fix for mailbox message truncated problem
+    - SAUCE: {topost} net: hns3: Add configure for mac minimal frame size
+    - SAUCE: {topost} net: hns3: fix warning bug when doing lp selftest
+    - SAUCE: {topost} net: hns3: fix get_vector ops in hclgevf_main module
+    - SAUCE: {topost} net: hns3: remove the warning when clear reset cause
+    - SAUCE: {topost} net: hns3: Use roce handle when calling roce callback
+      function
+    - SAUCE: {topost} net: hns3: prevent sending command during global or core
+      reset
+    - SAUCE: {topost} net: hns3: modify the order of initializeing command queue
+      register
+    - SAUCE: {topost} net: hns3: reset net device with rtnl_lock
+    - SAUCE: {topost} net: hns3: prevent to request reset frequently
+    - SAUCE: {topost} net: hns3: correct reset event status register
+    - SAUCE: {topost} net: hns3: separate roce from nic when resetting
+    - SAUCE: net: hns3: Fix for phy link issue when using marvell phy driver
+    - SAUCE: {topost} net: hns3: fix return value error in
+      hns3_reset_notify_down_enet
+    - SAUCE: {topost} net: hns3: remove unnecessary ring configuration operation
+      while resetting
+    - SAUCE: {topost} net: hns3: fix for reset_level default assignment probelm
+    - SAUCE: {topost} net: hns3: fix for using wrong mask and shift in
+      hclge_get_ring_chain_from_mbx
+    - SAUCE: {topost} net: hns3: fix comments for hclge_get_ring_chain_from_mbx
+    - SAUCE: net: hns3: Fix for VF mailbox cannot receiving PF response
+    - SAUCE: net: hns3: Fix for VF mailbox receiving unknown message
+    - SAUCE: net: hns3: Optimize PF CMDQ interrupt switching process
+
+  * CVE-2018-7755
+    - SAUCE: floppy: Do not copy a kernel pointer to user memory in FDGETPRM ioctl
+
+  * Incorrect blacklist of bcm2835_wdt (LP: #1766052)
+    - [Packaging] Fix missing watchdog for Raspberry Pi
+
+  * kernel: Fix arch random implementation (LP: #1775391)
+    - s390/archrandom: Rework arch random implementation.
+
+  * [Ubuntu 1804][boston][ixgbe] EEH causes kernel BUG at /build/linux-
+    jWa1Fv/linux-4.15.0/drivers/pci/msi.c:352 (i2S) (LP: #1776389)
+    - ixgbe/ixgbevf: Free IRQ when PCI error recovery removes the device
+
+  * Cosmic update to v4.17.2 stable release (LP: #1779117)
+    - crypto: chelsio - request to HW should wrap
+    - blkdev_report_zones_ioctl(): Use vmalloc() to allocate large buffers
+    - KVM: X86: Fix reserved bits check for MOV to CR3
+    - KVM: x86: introduce linear_{read,write}_system
+    - kvm: fix typo in flag name
+    - kvm: nVMX: Enforce cpl=0 for VMX instructions
+    - KVM: x86: pass kvm_vcpu to kvm_read_guest_virt and
+      kvm_write_guest_virt_system
+    - kvm: x86: use correct privilege level for sgdt/sidt/fxsave/fxrstor access
+    - staging: android: ion: Switch to pr_warn_once in ion_buffer_destroy
+    - NFC: pn533: don't send USB data off of the stack
+    - usbip: vhci_sysfs: fix potential Spectre v1
+    - usb-storage: Add support for FL_ALWAYS_SYNC flag in the UAS driver
+    - usb-storage: Add compatibility quirk flags for G-Technologies G-Drive
+    - Input: xpad - add GPD Win 2 Controller USB IDs
+    - phy: qcom-qusb2: Fix crash if nvmem cell not specified
+    - usb: core: message: remove extra endianness conversion in
+      usb_set_isoch_delay
+    - usb: typec: wcove: Remove dependency on HW FSM
+    - usb: gadget: function: printer: avoid wrong list handling in printer_write()
+    - usb: gadget: udc: renesas_usb3: fix double phy_put()
+    - usb: gadget: udc: renesas_usb3: should remove debugfs
+    - usb: gadget: udc: renesas_usb3: should call pm_runtime_enable() before add
+      udc
+    - usb: gadget: udc: renesas_usb3: should call devm_phy_get() before add udc
+    - usb: gadget: udc: renesas_usb3: should fail if devm_phy_get() returns error
+    - usb: gadget: udc: renesas_usb3: disable the controller's irqs for
+      reconnecting
+    - serial: sh-sci: Stop using printk format %pCr
+    - tty/serial: atmel: use port->name as name in request_irq()
+    - serial: samsung: fix maxburst parameter for DMA transactions
+    - serial: 8250: omap: Fix idling of clocks for unused uarts
+    - vmw_balloon: fixing double free when batching mode is off
+    - doc: fix sysfs ABI documentation
+    - arm64: defconfig: Enable CONFIG_PINCTRL_MT7622 by default
+    - tty: pl011: Avoid spuriously stuck-off interrupts
+    - crypto: ccree - correct host regs offset
+    - Input: goodix - add new ACPI id for GPD Win 2 touch screen
+    - Input: elan_i2c - add ELAN0612 (Lenovo v330 14IKB) ACPI ID
+    - crypto: caam - strip input zeros from RSA input buffer
+    - crypto: caam - fix DMA mapping dir for generated IV
+    - crypto: caam - fix IV DMA mapping and updating
+    - crypto: caam/qi - fix IV DMA mapping and updating
+    - crypto: caam - fix size of RSA prime factor q
+    - crypto: cavium - Fix fallout from CONFIG_VMAP_STACK
+    - crypto: cavium - Limit result reading attempts
+    - crypto: vmx - Remove overly verbose printk from AES init routines
+    - crypto: vmx - Remove overly verbose printk from AES XTS init
+    - crypto: omap-sham - fix memleak
+    - Linux 4.17.2
+
+  * Cosmic update to v4.17.1 stable release (LP: #1779116)
+    - netfilter: nf_flow_table: attach dst to skbs
+    - bnx2x: use the right constant
+    - ip6mr: only set ip6mr_table from setsockopt when ip6mr_new_table succeeds
+    - ipv6: omit traffic class when calculating flow hash
+    - l2tp: fix refcount leakage on PPPoL2TP sockets
+    - netdev-FAQ: clarify DaveM's position for stable backports
+    - net: metrics: add proper netlink validation
+    - net/packet: refine check for priv area size
+    - rtnetlink: validate attributes in do_setlink()
+    - sctp: not allow transport timeout value less than HZ/5 for hb_timer
+    - team: use netdev_features_t instead of u32
+    - vrf: check the original netdevice for generating redirect
+    - net: dsa: b53: Fix for brcm tag issue in Cygnus SoC
+    - ipmr: fix error path when ipmr_new_table fails
+    - PCI: hv: Do not wait forever on a device that has disappeared
+    - Linux 4.17.1
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: crypto: thunderx_zip: Fix fallout from
+      CONFIG_VMAP_STACK"
+    - Revert "UBUNTU: SAUCE: cred: Add clone_cred() interface"
+    - SAUCE: apparmor: userspace queries
+    - SAUCE: apparmor: patch to provide compatibility with v2.x net rules
+    - SAUCE: apparmor: af_unix mediation
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 28 Jun 2018 08:03:32 -0500
+
+linux (4.17.0-2.3) cosmic; urgency=medium
+
+  * linux: 4.17.0-2.3 -proposed tracker (LP: #1776276)
+
+  * Miscellaneous Ubuntu changes
+    - Config: remove IrDA from annotations
+    - Config: remove scsi drivers from annotations
+    - Config: remove BT_HCIBTUART from annotations
+    - Config: pstore zlib support was renamed
+    - Config: disable NVRAM for armhf on annotations
+    - Config: Disable VT on s390x
+    - Config: Update SSB and B43/B44 options
+    - Config: some options not supported on some arches anymore
+    - Config: renamed and removed options
+    - Config: TCG_CRB is required for IMA on ACPI systems
+    - Config: EXTCON_AXP288 depends on X86
+    - Config: CONFIG_FSI depends on OF
+    - Config: DRM_RCAR_LVDS now depends on DRM
+    - CONFIG: Allow CONFIG_LEDS_MLXCPLD for i386
+    - Config: Enable HINIC on arm64
+    - Config: Set PPS and PTP_1588_CLOCK as y
+    - Config: Some NF_TABLES options are built-in now
+    - Config: GENERIC_CPU for ppc64el
+    - Config: KEXEC_FILE=n for s390x
+    - Config: CRYPTO_DEFLATE is needed by PSTORE_DEFLATE_COMPRESS
+    - Config: Disable STM32 support
+    - Config: Enable FORTIFY_SOURCE for armhf
+    - Config: use STRONG instead of AUTO for CC_STACKPROTECTOR
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.17
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Mon, 11 Jun 2018 15:22:10 -0300
+
+linux (4.17.0-1.2) cosmic; urgency=medium
+
+  [ Seth Forshee ]
+  * [Config] enable EDAC_DEBUG on ARM64 (LP: #1772516)
+    - [Config]: set CONFIG_EDAC_DEBUG=y for ARM64
+
+  * Ubuntu 18.04 kernel crashed while in degraded mode (LP: #1770849)
+    - SAUCE: powerpc/perf: Fix memory allocation for core-imc based on
+      num_possible_cpus()
+
+  * Integrated Webcam Realtek Integrated_Webcam_HD (0bda:58f4) not working in
+    DELL XPS 13 9370 with firmware 1.50 (LP: #1763748)
+    - SAUCE: media: uvcvideo: Support realtek's UVC 1.5 device
+
+  * Switch Build-Depends: transfig to fig2dev (LP: #1770770)
+    - [Config] update Build-Depends: transfig to fig2dev
+
+  * update-initramfs not adding i915 GuC firmware for Kaby Lake, firmware fails
+    to load (LP: #1728238)
+    - Revert "UBUNTU: SAUCE: (no-up) i915: Remove MODULE_FIRMWARE statements for
+      unreleased firmware"
+
+  * No driver for Huawei network adapters on arm64 (LP: #1769899)
+    - net-next/hinic: add arm64 support
+
+  * linux-snapdragon: reduce EPROBEDEFER noise during boot (LP: #1768761)
+    - [Config] snapdragon: DRM_I2C_ADV7511=y
+
+  * Add d-i support for Huawei NICs (LP: #1767490)
+    - d-i: add hinic to nic-modules udeb
+
+  * Acer Swift sf314-52 power button not managed  (LP: #1766054)
+    - SAUCE: platform/x86: acer-wmi: add another KEY_POWER keycode
+
+  * Include nfp driver in linux-modules (LP: #1768526)
+    - [Config] Add nfp.ko to generic inclusion list
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Import aufs driver
+    - [Config] Enable AUFS config options
+    - SAUCE: (efi-lockdown) Fix for module sig verification
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) efi: Don't print secure boot state from the efi stub
+    - [Config] CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y
+    - SAUCE: (efi-lockdown) really lock down kernel under EFI secure boot
+    - SAUCE: (noup) Update spl to 0.7.5-1ubuntu3, zfs to 0.7.5-1ubuntu17
+    - enable zfs build
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) ima: require secure_boot rules in
+      lockdown mode"
+    - Rebased to v4.17-rc6
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Tue, 22 May 2018 14:48:13 -0300
+
+linux (4.17.0-0.1) bionic; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.17-rc4
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Tue, 08 May 2018 16:38:51 -0300
+
+linux (4.17.0-0.0) bionic; urgency=medium
+
+  * Dummy entry.
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Fri, 27 Apr 2018 11:01:13 -0300
+
+linux (4.16.0-4.5) bionic; urgency=medium
+
+  * [18.04 FEAT] Add kvm_stat from kernel tree (LP: #1734130)
+    - tools/kvm_stat: Fix python3 syntax
+    - tools/kvm_stat: Don't use deprecated file()
+    - tools/kvm_stat: Remove unused function
+    - [Packaging] Add linux-tools-host package for VM host tools
+    - [Config] do_tools_host=true for amd64
+
+  * [Featire] CNL: Enable RAPL support (LP: #1685712)
+    - powercap: RAPL: Add support for Cannon Lake
+
+  * Bionic update to v4.16.2 stable release (LP: #1763388)
+    - sparc64: Oracle DAX driver depends on SPARC64
+    - arp: fix arp_filter on l3slave devices
+    - net: dsa: Discard frames from unused ports
+    - net/ipv6: Increment OUTxxx counters after netfilter hook
+    - net/sched: fix NULL dereference in the error path of tcf_bpf_init()
+    - pptp: remove a buggy dst release in pptp_connect()
+    - sctp: do not leak kernel memory to user space
+    - sctp: sctp_sockaddr_af must check minimal addr length for AF_INET6
+    - vlan: also check phy_driver ts_info for vlan's real device
+    - net: fool proof dev_valid_name()
+    - ip_tunnel: better validate user provided tunnel names
+    - ipv6: sit: better validate user provided tunnel names
+    - ip6_gre: better validate user provided tunnel names
+    - ip6_tunnel: better validate user provided tunnel names
+    - vti6: better validate user provided tunnel names
+    - net_sched: fix a missing idr_remove() in u32_delete_key()
+    - nfp: use full 40 bits of the NSP buffer address
+    - Linux 4.16.2
+
+  * sky2 gigabit ethernet driver sometimes stops working after lid-open resume
+    from sleep (88E8055) (LP: #1758507) // Bionic update to v4.16.2 stable
+    release (LP: #1763388)
+    - sky2: Increase D3 delay to sky2 stops working after suspend
+
+  * Merge the linux-snapdragon kernel into bionic master/snapdragon
+    (LP: #1763040)
+    - arm64: defconfig: enable REMOTEPROC
+    - arm64: defconfig: enable QCOM audio drivers for APQ8016 and DB410c
+    - kernel: configs; add distro.config
+    - arm64: configs: enable WCN36xx
+    - kernel: distro.config: enable debug friendly USB network adpater
+    - arm64: configs: enable QCOM Venus
+    - arm64: defconfig: Enable a53/apcs and avs
+    - arm64: defconfig: enable ondemand governor as default
+    - arm64: defconfig: enable QCOM_TSENS
+    - kernel: configs: enable dm_mod and dm_crypt
+    - Force the SMD regulator driver to be compiled-in
+    - arm64: defconfig: enable CFG80211_DEFAULT_PS by default
+    - arm64: configs: enable BT_QCOMSMD
+    - kernel: configs: add more USB net drivers
+    - arm64: defconfig: disable ANALOG_TV and DIGITAL_TV
+    - arm64: configs: Enable camera drivers
+    - kernel: configs: add freq stat to sysfs
+    - arm64: defconfig: enable CONFIG_USB_CONFIGFS_F_FS by default
+    - arm64: defconfig: Enable QRTR features
+    - kernel: configs: set USB_CONFIG_F_FS in distro.config
+    - kernel: distro.config: enable 'schedutil' CPUfreq governor
+    - kernel: distro.config: enable 'fq' and 'fq_codel' qdiscs
+    - kernel: distro.config: enable 'BBR' TCP congestion algorithm
+    - arm64: defconfig: enable LEDS_QCOM_LPG
+    - HACK: drm/msm/iommu: Remove runtime_put calls in map/unmap
+    - power: avs: Add support for CPR (Core Power Reduction)
+    - power: avs: cpr: Use raw mem access for qfprom
+    - power: avs: cpr: fix with new reg_sequence structures
+    - power: avs: cpr: Register with cpufreq-dt
+    - regulator: smd: Add floor and corner operations
+    - PM / OPP: Support adjusting OPP voltages at runtime
+    - PM / OPP: Drop RCU usage in dev_pm_opp_adjust_voltage()
+    - PM / OPP: HACK: Allow to set regulator without opp_list
+    - PM / OPP: Add a helper to get an opp regulator for device
+    - cpufreq: Add apq8016 to cpufreq-dt-platdev blacklist
+    - regulator: smd: Allow REGULATOR_QCOM_SMD_RPM=m
+    - ov5645: I2C address change
+    - i2c: Add Qualcomm Camera Control Interface driver
+    - camss: vfe: Skip first four frames from sensor
+    - camss: Do not register if no cameras are present
+    - i2c-qcom-cci: Fix run queue completion timeout
+    - i2c-qcom-cci: Fix I2C address bug
+    - media: ov5645: Fix I2C address
+    - drm/bridge/adv7511: Delay clearing of HPD interrupt status
+    - HACK: drm/msm/adv7511: Don't rely on interrupts for EDID parsing
+    - leds: Add driver for Qualcomm LPG
+    - wcn36xx: Fix warning due to duplicate scan_completed notification
+    - arm64: dts: Add CPR DT node for msm8916
+    - arm64: dts: add spmi-regulator nodes
+    - arm64: dts: msm8916: Add cpufreq support
+    - arm64: dts: msm8916: Add a shared CPU opp table
+    - arm64: dts: msm8916: Add cpu cooling maps
+    - arm64: dts: pm8916: Mark the s2 regulator as always-on
+    - arm64: dts: qcom: msm8916: Add msm8916 A53 PLL DT node
+    - arm64: dts: qcom: msm8916: Use the new APCS mailbox driver
+    - arm64: dts: qcom: msm8916: Add clock properties to the APCS node
+    - dt-bindings: media: Binding document for Qualcomm Camera Control Interface
+      driver
+    - MAINTAINERS: Add Qualcomm Camera Control Interface driver
+    - DT: leds: Add Qualcomm Light Pulse Generator binding
+    - arm64: dts: qcom: msm8996: Add mpp and lpg blocks
+    - arm64: dts: qcom: Add pwm node for pm8916
+    - arm64: dts: qcom: Add user LEDs on db820c
+    - arm64: dts: qcom: Add WiFI/BT LEDs on db820c
+    - ARM: dts: qcom: Add LPG node to pm8941
+    - ARM: dts: qcom: honami: Add LPG node and RGB LED
+    - arm64: dts: qcom: Add Camera Control Interface support
+    - arm64: dts: qcom: Add apps_iommu vfe child node
+    - arm64: dts: qcom: Add camss device node
+    - arm64: dts: qcom: Add ov5645 device nodes
+    - arm64: dts: msm8916: Fix camera sensors I2C addresses
+    - arm: dts: qcom: db410c: Enable PWM signal on MPP4
+    - packaging: arm64: add a uboot flavour - part1
+    - packaging: arm64: add a uboot flavour - part2
+    - packaging: arm64: add a uboot flavour - part3
+    - packaging: arm64: add a uboot flavour - part4
+    - packaging: arm64: add a uboot flavour - part5
+    - packaging: arm64: rename uboot flavour to snapdragon
+    - [Config] updateconfigs after qcomlt import
+    - [Config] arm64: snapdragon: COMMON_CLK_QCOM=y
+    - [Config] arm64: snapdragon: MSM_GCC_8916=y
+    - [Config] arm64: snapdragon: REGULATOR_FIXED_VOLTAGE=y
+    - [Config] arm64: snapdragon: PINCTRL_MSM8916=y
+    - [Config] arm64: snapdragon: HWSPINLOCK_QCOM=y
+    - [Config] arm64: snapdragon: SPMI=y, SPMI_MSM_PMIC_ARB=y
+    - [Config] arm64: snapdragon: REGMAP_SPMI=y, PINCTRL_QCOM_SPMI_PMIC=y
+    - [Config] arm64: snapdragon: REGULATOR_QCOM_SPMI=y
+    - [Config] arm64: snapdragon: MFD_SPMI_PMIC=y
+    - [Config] arm64: snapdragon: QCOM_SMEM=y
+    - [Config] arm64: snapdragon: RPMSG=y, RPMSG_QCOM_SMD=y
+    - [Config] arm64: snapdragon: QCOM_SMD_RPM=y, REGULATOR_QCOM_SMD_RPM=y
+    - [Config] arm64: snapdragon: QCOM_CLK_SMD_RPM=y
+    - [Config] arm64: snapdragon: QCOM_BAM_DMA=y
+    - [Config] arm64: snapdragon: QCOM_HIDMA=y, QCOM_HIDMA_MGMT=y
+    - [Config] arm64: snapdragon: QCOM_CPR=y
+    - [Config] arm64: snapdragon: QCOM_QFPROM=y, QCOM_TSENS=y
+    - [Config] arm64: snapdragon: MMC_SDHCI=y, MMC_SDHCI_PLTFM=y, MMC_SDHCI_MSM=y
+    - [Config] turn off DRM_MSM_REGISTER_LOGGING
+    - [Config] arm64: snapdragon: I2C_QUP=y
+    - [Config] arm64: snapdragon: SPI_QUP=y
+    - [Config] arm64: snapdragon: USB_ULPI_BUS=y, PHY_QCOM_USB_HS=y
+    - [Config] arm64: snapdragon: QCOM_APCS_IPC=y
+    - [Config] arm64: snapdragon: QCOM_WCNSS_CTRL=y
+    - [Config] arm64: snapdragon: QCOM_SMSM=y
+    - [Config] arm64: snapdragon: QCOM_SMP2P=y
+    - [Config] arm64: snapdragon: DRM_MSM=y
+    - [Config] arm64: snapdragon: SND_SOC=y
+    - [Config] arm64: snapdragon: QCOM_WCNSS_PIL=m
+    - [Config] arm64: snapdragon: INPUT_PM8941_PWRKEY=y
+    - [Config] arm64: snapdragon: MEDIA_SUBDRV_AUTOSELECT=y, VIDEO_OV5645=m
+    - [Config] arm64: snapdragon: SND_SOC_APQ8016_SBC=y, SND_SOC_LPASS_APQ8016=y
+    - [Config] arm64: snapdragon: SND_SOC_MSM8916_WCD_ANALOG=y,
+      SND_SOC_MSM8916_WCD_DIGITAL=y
+    - SAUCE: media: ov5645: skip address change if dt addr == default addr
+    - SAUCE: drm/msm/adv7511: wrap hacks under CONFIG_ADV7511_SNAPDRAGON_HACKS
+      #ifdefs
+    - [Config] arm64: snapdragon: ADV7511_SNAPDRAGON_HACKS=y
+    - [Packaging] fix up snapdragon abi paths
+
+  * LSM stacking patches for bionic (LP: #1763062)
+    - SAUCE: LSM stacking: procfs: add smack subdir to attrs
+    - SAUCE: LSM stacking: LSM: Manage credential security blobs
+    - SAUCE: LSM stacking: LSM: Manage file security blobs
+    - SAUCE: LSM stacking: LSM: Manage task security blobs
+    - SAUCE: LSM stacking: LSM: Manage remaining security blobs
+    - SAUCE: LSM stacking: LSM: General stacking
+    - SAUCE: LSM stacking: fixup initialize task->security
+    - SAUCE: LSM stacking: fixup: alloc_task_ctx is dead code
+    - SAUCE: LSM stacking: add support for stacking getpeersec_stream
+    - SAUCE: LSM stacking: add stacking support to apparmor network hooks
+    - SAUCE: LSM stacking: fixup apparmor stacking enablement
+    - SAUCE: LSM stacking: fixup stacking kconfig
+    - SAUCE: LSM stacking: allow selecting multiple LSMs using kernel boot params
+    - SAUCE: LSM stacking: provide prctl interface for setting context
+    - SAUCE: LSM stacking: inherit current display LSM
+    - SAUCE: LSM stacking: keep an index for each registered LSM
+    - SAUCE: LSM stacking: verify display LSM
+    - SAUCE: LSM stacking: provide a way to specify the default display lsm
+    - SAUCE: LSM stacking: make sure LSM blob align on 64 bit boundaries
+    - SAUCE: LSM stacking: add /proc/<pid>/attr/display_lsm
+    - SAUCE: LSM stacking: add Kconfig to set default display LSM
+    - SAUCE: LSM stacking: add configs for LSM stacking
+    - SAUCE: LSM stacking: add apparmor and selinux proc dirs
+    - SAUCE: LSM stacking: remove procfs context interface
+
+  * linux 4.13.0-13.14 ADT test failure with linux 4.13.0-13.14
+    (LP: #1720779) // LSM stacking patches for bionic (LP: #1763062)
+    - SAUCE: LSM stacking: check for invalid zero sized writes
+
+  * Support cq/rq record doorbell for RDMA on HSilicon hip08 systems
+    (LP: #1762755)
+    - RDMA/hns: Support rq record doorbell for the user space
+    - RDMA/hns: Support cq record doorbell for the user space
+    - RDMA/hns: Support rq record doorbell for kernel space
+    - RDMA/hns: Support cq record doorbell for kernel space
+    - RDMA/hns: Fix cqn type and init resp
+    - RDMA/hns: Fix init resp when alloc ucontext
+    - RDMA/hns: Fix cq record doorbell enable in kernel
+
+  * Replace LPC patchset with upstream version (LP: #1762758)
+    - Revert "UBUNTU: SAUCE: MAINTAINERS: Add maintainer for HiSilicon LPC driver"
+    - Revert "UBUNTU: SAUCE: HISI LPC: Add ACPI support"
+    - Revert "UBUNTU: SAUCE: ACPI / scan: do not enumerate Indirect IO host
+      children"
+    - Revert "UBUNTU: SAUCE: HISI LPC: Support the LPC host on Hip06/Hip07 with DT
+      bindings"
+    - Revert "UBUNTU: SAUCE: OF: Add missing I/O range exception for indirect-IO
+      devices"
+    - Revert "UBUNTU: SAUCE: PCI: Apply the new generic I/O management on PCI IO
+      hosts"
+    - Revert "UBUNTU: SAUCE: PCI: Add fwnode handler as input param of
+      pci_register_io_range()"
+    - Revert "UBUNTU: SAUCE: PCI: Remove unused __weak attribute in
+      pci_register_io_range()"
+    - Revert "UBUNTU: SAUCE: LIB: Introduce a generic PIO mapping method"
+    - lib: Add generic PIO mapping method
+    - PCI: Remove __weak tag from pci_register_io_range()
+    - PCI: Add fwnode handler as input param of pci_register_io_range()
+    - PCI: Apply the new generic I/O management on PCI IO hosts
+    - of: Add missing I/O range exception for indirect-IO devices
+    - HISI LPC: Support the LPC host on Hip06/Hip07 with DT bindings
+    - ACPI / scan: Rename acpi_is_serial_bus_slave() for more general use
+    - ACPI / scan: Do not enumerate Indirect IO host children
+    - HISI LPC: Add ACPI support
+    - MAINTAINERS: Add John Garry as maintainer for HiSilicon LPC driver
+
+  * Enable Tunneled Operations on POWER9 (LP: #1762448)
+    - powerpc/powernv: Enable tunneled operations
+    - cxl: read PHB indications from the device tree
+
+  * PSL traces reset after PERST for debug AFU image (LP: #1762462)
+    - cxl: Enable NORST bit in PSL_DEBUG register for PSL9
+
+  * NFS + sec=krb5 is broken (LP: #1759791)
+    - sunrpc: remove incorrect HMAC request initialization
+
+  * Raspberry Pi 3 microSD support missing from the installer (LP: #1729128)
+    - d-i: add bcm2835 to block-modules
+
+  * Backport USB core quirks (LP: #1762695)
+    - usb: core: Add "quirks" parameter for usbcore
+    - usb: core: Copy parameter string correctly and remove superfluous null check
+    - usb: core: Add USB_QUIRK_DELAY_CTRL_MSG to usbcore quirks
+
+  * [Ubuntu 18.04] cryptsetup: 'device-mapper: reload ioctl on  failed' when
+    setting up a second end-to-end encrypted disk (LP: #1762353)
+    - SAUCE: s390/crypto: Adjust s390 aes and paes cipher
+
+  * System Z {kernel} UBUNTU18.04 wrong kernel config (LP: #1762719)
+    - s390: move nobp parameter functions to nospec-branch.c
+    - s390: add automatic detection of the spectre defense
+    - s390: report spectre mitigation via syslog
+    - s390: add sysfs attributes for spectre
+    - [Config] CONFIG_EXPOLINE_AUTO=y, CONFIG_KERNEL_NOBP=n for s390
+    - s390: correct nospec auto detection init order
+
+  * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5715
+    - powerpc/64s: Wire up cpu_show_spectre_v2()
+
+  * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5753
+    - powerpc/64s: Wire up cpu_show_spectre_v1()
+
+  * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5754
+    - powerpc/rfi-flush: Move the logic to avoid a redo into the debugfs code
+    - powerpc/rfi-flush: Make it possible to call setup_rfi_flush() again
+    - powerpc/rfi-flush: Always enable fallback flush on pseries
+    - powerpc/rfi-flush: Differentiate enabled and patched flush types
+    - powerpc/rfi-flush: Call setup_rfi_flush() after LPM migration
+    - powerpc/64s: Move cpu_show_meltdown()
+    - powerpc/64s: Enhance the information in cpu_show_meltdown()
+    - powerpc/powernv: Use the security flags in pnv_setup_rfi_flush()
+    - powerpc/pseries: Use the security flags in pseries_setup_rfi_flush()
+
+  * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5715 //
+    CVE-2017-5753 // CVE-2017-5754
+    - powerpc/pseries: Add new H_GET_CPU_CHARACTERISTICS flags
+    - powerpc: Add security feature flags for Spectre/Meltdown
+    - powerpc/pseries: Set or clear security feature flags
+    - powerpc/powernv: Set or clear security feature flags
+
+  * Hisilicon network subsystem 3 support (LP: #1761610)
+    - net: hns3: export pci table of hclge and hclgevf to userspace
+    - d-i: Add hns3 drivers to nic-modules
+
+  * "ip a" command on a guest VM shows UNKNOWN status (LP: #1761534)
+    - virtio-net: Fix operstate for virtio when no VIRTIO_NET_F_STATUS
+
+  * perf vendor events arm64: Enable JSON events for ThunderX2 B0 (LP: #1760712)
+    - perf vendor events: Drop incomplete multiple mapfile support
+    - perf vendor events: Fix error code in json_events()
+    - perf vendor events: Drop support for unused topic directories
+    - perf vendor events: Add support for pmu events vendor subdirectory
+    - perf vendor events arm64: Relocate ThunderX2 JSON to cavium subdirectory
+    - perf vendor events arm64: Relocate Cortex A53 JSONs to arm subdirectory
+    - perf vendor events: Add support for arch standard events
+    - perf vendor events arm64: Add armv8-recommended.json
+    - perf vendor events arm64: Fixup ThunderX2 to use recommended events
+    - perf vendor events arm64: fixup A53 to use recommended events
+    - perf vendor events arm64: add HiSilicon hip08 JSON file
+    - perf vendor events arm64: Enable JSON events for ThunderX2 B0
+
+  * Warning "cache flush timed out!" seen when unloading the cxl driver
+    (LP: #1762367)
+    - cxl: Check if PSL data-cache is available before issue flush request
+
+  * Bionic update to v4.16.1 stable release (LP: #1763170)
+    - bitmap: fix memset optimization on big-endian systems
+    - USB: serial: ftdi_sio: add RT Systems VX-8 cable
+    - USB: serial: ftdi_sio: add support for Harman FirmwareHubEmulator
+    - USB: serial: cp210x: add ELDAT Easywave RX09 id
+    - serial: 8250: Add Nuvoton NPCM UART
+    - mei: remove dev_err message on an unsupported ioctl
+    - /dev/mem: Avoid overwriting "err" in read_mem()
+    - media: usbtv: prevent double free in error case
+    - parport_pc: Add support for WCH CH382L PCI-E single parallel port card.
+    - crypto: lrw - Free rctx->ext with kzfree
+    - crypto: ccp - Fill the result buffer only on digest, finup, and final ops
+    - crypto: talitos - don't persistently map req_ctx->hw_context and
+      req_ctx->buf
+    - crypto: inside-secure - fix clock management
+    - crypto: testmgr - Fix incorrect values in PKCS#1 test vector
+    - crypto: talitos - fix IPsec cipher in length
+    - crypto: ahash - Fix early termination in hash walk
+    - crypto: caam - Fix null dereference at error path
+    - crypto: ccp - return an actual key size from RSA max_size callback
+    - crypto: arm,arm64 - Fix random regeneration of S_shipped
+    - crypto: x86/cast5-avx - fix ECB encryption when long sg follows short one
+    - Bluetooth: hci_bcm: Add 6 new ACPI HIDs
+    - Btrfs: fix unexpected cow in run_delalloc_nocow
+    - siox: fix possible buffer overflow in device_add_store
+    - staging: comedi: ni_mio_common: ack ai fifo error interrupts.
+    - Revert "base: arch_topology: fix section mismatch build warnings"
+    - Input: ALPS - fix TrackStick detection on Thinkpad L570 and Latitude 7370
+    - Input: i8042 - add Lenovo ThinkPad L460 to i8042 reset list
+    - Input: i8042 - enable MUX on Sony VAIO VGN-CS series to fix touchpad
+    - vt: change SGR 21 to follow the standards
+    - Fix slab name "biovec-(1<<(21-12))"
+    - signal: Correct the offset of si_pkey and si_lower in struct siginfo on m68k
+    - Linux 4.16.1
+
+  * [18.04][config] regression: nvme and nvme_core couldn't be built as modules
+    starting 4.15-rc2 (LP: #1759893)
+    - SAUCE: Revert "lightnvm: include NVM Express driver if OCSSD is selected for
+      build"
+    - [Config] CONFIG_BLK_DEV_NMVE=m
+
+  * FFe: Enable configuring resume offset via sysfs (LP: #1760106)
+    - PM / hibernate: Make passing hibernate offsets more friendly
+
+  * Ubuntu18.04:POWER9:DD2.2 - Unable to start a KVM guest with default machine
+    type(pseries-bionic) complaining "KVM implementation does not support
+    Transactional Memory, try cap-htm=off" (kvm) (LP: #1752026)
+    - powerpc: Use feature bit for RTC presence rather than timebase presence
+    - powerpc: Book E: Remove unused CPU_FTR_L2CSR bit
+    - powerpc: Free up CPU feature bits on 64-bit machines
+    - powerpc: Add CPU feature bits for TM bug workarounds on POWER9 v2.2
+    - powerpc/powernv: Provide a way to force a core into SMT4 mode
+    - KVM: PPC: Book3S HV: Work around transactional memory bugs in POWER9
+    - KVM: PPC: Book3S HV: Work around XER[SO] bug in fake suspend mode
+    - KVM: PPC: Book3S HV: Work around TEXASR bug in fake suspend state
+
+  * [Feature][CFL][ICL] [CNL]Thunderbolt support (Titan Ridge) (LP: #1730775)
+    - thunderbolt: Resume control channel after hibernation image is created
+    - thunderbolt: Serialize PCIe tunnel creation with PCI rescan
+    - thunderbolt: Handle connecting device in place of host properly
+    - thunderbolt: Do not overwrite error code when domain adding fails
+    - thunderbolt: Wait a bit longer for root switch config space
+    - thunderbolt: Wait a bit longer for ICM to authenticate the active NVM
+    - thunderbolt: Handle rejected Thunderbolt devices
+    - thunderbolt: Factor common ICM add and update operations out
+    - thunderbolt: Correct function name in kernel-doc comment
+    - thunderbolt: Add tb_switch_get()
+    - thunderbolt: Add tb_switch_find_by_route()
+    - thunderbolt: Add tb_xdomain_find_by_route()
+    - thunderbolt: Add constant for approval timeout
+    - thunderbolt: Move driver ready handling to struct icm
+    - thunderbolt: Add 'boot' attribute for devices
+    - thunderbolt: Add support for preboot ACL
+    - thunderbolt: Introduce USB only (SL4) security level
+    - thunderbolt: Add support for Intel Titan Ridge
+
+  * QCA9377 requires more IRAM banks for its new firmware (LP: #1748345)
+    - ath10k: update the IRAM bank number for QCA9377
+
+  * Fix an issue that when system in S3, USB keyboard can't wake up the system.
+    (LP: #1759511)
+    - ACPI / PM: Allow deeper wakeup power states with no _SxD nor _SxW
+
+  * cxl: Fix timebase synchronization status on POWER9 missing (CAPI)
+    (LP: #1757228)
+    - cxl: Fix timebase synchronization status on P9
+
+  * [Feature]Update Ubuntu 18.04 lpfc FC driver with 32/64GB HBA support and bug
+    fixes (LP: #1752182)
+    - scsi: lpfc: Fix frequency of Release WQE CQEs
+    - scsi: lpfc: Increase CQ and WQ sizes for SCSI
+    - scsi: lpfc: move placement of target destroy on driver detach
+    - scsi: lpfc: correct debug counters for abort
+    - scsi: lpfc: Add WQ Full Logic for NVME Target
+    - scsi: lpfc: Fix PRLI handling when topology type changes
+    - scsi: lpfc: Fix IO failure during hba reset testing with nvme io.
+    - scsi: lpfc: Fix RQ empty firmware trap
+    - scsi: lpfc: Allow set of maximum outstanding SCSI cmd limit for a target
+    - scsi: lpfc: Fix soft lockup in lpfc worker thread during LIP testing
+    - scsi: lpfc: Fix issue_lip if link is disabled
+    - scsi: lpfc: Indicate CONF support in NVMe PRLI
+    - scsi: lpfc: Fix SCSI io host reset causing kernel crash
+    - scsi: lpfc: Validate adapter support for SRIU option
+    - scsi: lpfc: Fix header inclusion in lpfc_nvmet
+    - scsi: lpfc: Treat SCSI Write operation Underruns as an error
+    - scsi: lpfc: Fix nonrecovery of NVME controller after cable swap.
+    - scsi: lpfc: update driver version to 11.4.0.7
+    - scsi: lpfc: Update 11.4.0.7 modified files for 2018 Copyright
+    - scsi: lpfc: Rework lpfc to allow different sli4 cq and eq handlers
+    - scsi: lpfc: Rework sli4 doorbell infrastructure
+    - scsi: lpfc: Add SLI-4 if_type=6 support to the code base
+    - scsi: lpfc: Add push-to-adapter support to sli4
+    - scsi: lpfc: Add PCI Ids for if_type=6 hardware
+    - scsi: lpfc: Add 64G link speed support
+    - scsi: lpfc: Add if_type=6 support for cycling valid bits
+    - scsi: lpfc: Enable fw download on if_type=6 devices
+    - scsi: lpfc: Add embedded data pointers for enhanced performance
+    - scsi: lpfc: Fix nvme embedded io length on new hardware
+    - scsi: lpfc: Work around NVME cmd iu SGL type
+    - scsi: lpfc: update driver version to 12.0.0.0
+    - scsi: lpfc: Change Copyright of 12.0.0.0 modified files to 2018
+    - scsi: lpfc: use __raw_writeX on DPP copies
+    - scsi: lpfc: Add missing unlock in WQ full logic
+
+  * /dev/bcache/by-uuid links not created after reboot (LP: #1729145)
+    - SAUCE: (no-up) bcache: decouple emitting a cached_dev CHANGE uevent
+
+  * DKMS driver builds fail with: Cannot use CONFIG_STACK_VALIDATION=y, please
+    install libelf-dev, libelf-devel or elfutils-libelf-devel (LP: #1760876)
+    - [Packaging] include the retpoline extractor in the headers
+
+  * Use med_with_dipm SATA LPM to save more power for mobile platforms
+    (LP: #1759547)
+    - [Config] CONFIG_SATA_MOBILE_LPM_POLICY=3
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Only install cloud init files when do_tools_common=true
+    - SAUCE: Import aufs driver
+    - [Config] Enable AUFS config options
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 12 Apr 2018 09:30:56 -0500
+
+linux (4.16.0-3.4) bionic; urgency=medium
+
+  * Allow multiple mounts of zfs datasets (LP: #1759848)
+    - SAUCE: Allow mounting datasets more than once (LP: #1759848)
+
+  * zfs system process hung on container stop/delete (LP: #1754584)
+    - SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)
+    - Revert "UBUNTU: SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)"
+    - SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)
+
+  * ubuntu_zram_smoke test will cause soft lockup on Artful ThunderX ARM64
+    (LP: #1755073)
+    - SAUCE: crypto: thunderx_zip: Fix fallout from CONFIG_VMAP_STACK
+
+  * CAPI Flash (cxlflash) update (LP: #1752672)
+    - SAUCE: cxlflash: Preserve number of interrupts for master contexts
+    - SAUCE: cxlflash: Avoid clobbering context control register value
+    - SAUCE: cxlflash: Add argument identifier names
+    - SAUCE: cxlflash: Introduce OCXL backend
+    - SAUCE: cxlflash: Hardware AFU for OCXL
+    - SAUCE: cxlflash: Read host function configuration
+    - SAUCE: cxlflash: Setup function acTag range
+    - SAUCE: cxlflash: Read host AFU configuration
+    - SAUCE: cxlflash: Setup AFU acTag range
+    - SAUCE: cxlflash: Setup AFU PASID
+    - SAUCE: cxlflash: Adapter context support for OCXL
+    - SAUCE: cxlflash: Use IDR to manage adapter contexts
+    - SAUCE: cxlflash: Support adapter file descriptors for OCXL
+    - SAUCE: cxlflash: Support adapter context discovery
+    - SAUCE: cxlflash: Support image reload policy modification
+    - SAUCE: cxlflash: MMIO map the AFU
+    - SAUCE: cxlflash: Support starting an adapter context
+    - SAUCE: cxlflash: Support process specific mappings
+    - SAUCE: cxlflash: Support AFU state toggling
+    - SAUCE: cxlflash: Support reading adapter VPD data
+    - SAUCE: cxlflash: Setup function OCXL link
+    - SAUCE: cxlflash: Setup OCXL transaction layer
+    - SAUCE: cxlflash: Support process element lifecycle
+    - SAUCE: cxlflash: Support AFU interrupt management
+    - SAUCE: cxlflash: Support AFU interrupt mapping and registration
+    - SAUCE: cxlflash: Support starting user contexts
+    - SAUCE: cxlflash: Support adapter context polling
+    - SAUCE: cxlflash: Support adapter context reading
+    - SAUCE: cxlflash: Support adapter context mmap and release
+    - SAUCE: cxlflash: Support file descriptor mapping
+    - SAUCE: cxlflash: Introduce object handle fop
+    - SAUCE: cxlflash: Setup LISNs for user contexts
+    - SAUCE: cxlflash: Setup LISNs for master contexts
+    - SAUCE: cxlflash: Update synchronous interrupt status bits
+    - SAUCE: cxlflash: Introduce OCXL context state machine
+    - SAUCE: cxlflash: Register for translation errors
+    - SAUCE: cxlflash: Support AFU reset
+    - SAUCE: cxlflash: Enable OCXL operations
+
+  * [Artful][Wyse 3040] System hang when trying to enable an offlined CPU core
+    (LP: #1736393)
+    - SAUCE: drm/i915:Don't set chip specific data
+    - SAUCE: drm/i915: make previous commit affects Wyse 3040 only
+
+  * zed process consuming 100% cpu (LP: #1751796)
+    - SAUCE: Fix ioctl loop-spin in zed (LP: #1751796)
+
+  * Ubuntu18.04:PowerPC - Set Transparent Huge Pages (THP) by default to
+    "always" (LP: #1753708)
+    - Config: Set TRANSPARENT_HUGEPAGE_ALWAYS=y on ppc64el
+
+  * retpoline hints: primary infrastructure and initial hints (LP: #1758856)
+    - [Packaging] retpoline -- add safe usage hint support
+    - [Packaging] retpoline-check -- only report additions
+    - [Packaging] retpoline -- widen indirect call/jmp detection
+    - [Packaging] retpoline -- elide %rip relative indirections
+    - [Packaging] retpoline -- clear hint information from packages
+    - SAUCE: apm -- annotate indirect calls within
+      firmware_restrict_branch_speculation_{start,end}
+    - SAUCE: EFI -- annotate indirect calls within
+      firmware_restrict_branch_speculation_{start,end}
+    - SAUCE: early/late -- annotate indirect calls in early/late initialisation
+      code
+    - SAUCE: vga_set_mode -- avoid jump tables
+    - [Config] retpoine -- switch to new format
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] final-checks -- remove check for empty retpoline files
+    - [Packaging] skip cloud tools packaging when not building package
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.16
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 02 Apr 2018 16:15:36 -0500
+
+linux (4.16.0-2.3) bionic; urgency=medium
+
+  * devpts: handle bind-mounts (LP: #1755857)
+    - SAUCE: devpts: hoist out check for DEVPTS_SUPER_MAGIC
+    - SAUCE: devpts: resolve devpts bind-mounts
+    - SAUCE: devpts: comment devpts_mntget()
+    - SAUCE: selftests: add devpts selftests
+
+  * [bionic][arm64] d-i: add hisi_sas_v3_hw to scsi-modules (LP: #1756103)
+    - d-i: add hisi_sas_v3_hw to scsi-modules
+
+  * [Bionic][ARM64] PCI and SAS driver patches for hip08 SoCs (LP: #1756094)
+    - SAUCE: scsi: hisi_sas: config for hip08 ES
+    - SAUCE: scsi: hisi_sas: export device table of v3 hw to userspace
+
+  * s390/crypto: Fix kernel crash on aes_s390 module remove (LP: #1753424)
+    - SAUCE: s390/crypto: Fix kernel crash on aes_s390 module remove.
+
+  * Fix ARC hit rate (LP: #1755158)
+    - SAUCE: Fix ARC hit rate (LP: #1755158)
+
+  * ZFS setgid broken on 0.7 (LP: #1753288)
+    - SAUCE: Fix ZFS setgid
+
+  * CONFIG_EFI=y on armhf (LP: #1726362)
+    - [Config] CONFIG_EFI=y on armhf, reconcile secureboot EFI settings
+
+  * [Feature] Add xHCI debug device support in the driver (LP: #1730832)
+    - [Config] CONFIG_USB_XHCI_DBGCAP=y
+
+  * retpoline: ignore %cs:0xNNN constant indirections (LP: #1752655)
+    - [Packaging] retpoline -- elide %cs:0xNNNN constants on i386
+    - [Config] retpoline -- clean up i386 retpoline files
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] retpoline-extract: flag *0xNNN(%reg) branches
+    - [Config] fix up retpoline abi files
+    - [Config] fix up retpoline abi files
+    - d-i: Add netsec to nic-modules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.16-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 19 Mar 2018 14:09:49 -0500
+
+linux (4.16.0-1.2) bionic; urgency=medium
+
+  * Driver not found in Ubuntu kernel does not detect interface (LP: #1745927)
+    - d-i: add cxgb4 to nic-modules
+
+  * Support low-pin-count devices on Hisilicon SoCs (LP: #1677319)
+    - [Config] CONFIG_INDIRECT_PIO=y
+    - SAUCE: LIB: Introduce a generic PIO mapping method
+    - SAUCE: PCI: Remove unused __weak attribute in pci_register_io_range()
+    - SAUCE: PCI: Add fwnode handler as input param of pci_register_io_range()
+    - SAUCE: PCI: Apply the new generic I/O management on PCI IO hosts
+    - SAUCE: OF: Add missing I/O range exception for indirect-IO devices
+    - [Config] CONFIG_HISILICON_LPC=y
+    - SAUCE: HISI LPC: Support the LPC host on Hip06/Hip07 with DT bindings
+    - SAUCE: ACPI / scan: do not enumerate Indirect IO host children
+    - SAUCE: HISI LPC: Add ACPI support
+    - SAUCE: MAINTAINERS: Add maintainer for HiSilicon LPC driver
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: tools: use CC for linking acpi tools
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.16-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 28 Feb 2018 10:17:23 -0600
+
+linux (4.16.0-0.1) bionic; urgency=medium
+
+  * retpoline abi files are empty on i386 (LP: #1751021)
+    - [Packaging] retpoline-extract -- instantiate retpoline files for i386
+    - [Packaging] final-checks -- sanity checking ABI contents
+    - [Packaging] final-checks -- check for empty retpoline files
+
+  * Miscellaneous upstream changes
+    - disable vbox build
+    - Disable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.16-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 22 Feb 2018 08:58:57 -0600
+
+linux (4.16.0-0.0) bionic; urgency=medium
+
+  * Dummy entry
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 21 Feb 2018 14:33:13 -0600
+
+linux (4.15.0-10.11) bionic; urgency=medium
+
+  * linux: 4.15.0-10.11 -proposed tracker (LP: #1749250)
+
+  * "swiotlb: coherent allocation failed" dmesg spam with linux 4.15.0-9.10
+    (LP: #1749202)
+    - swiotlb: suppress warning when __GFP_NOWARN is set
+    - drm/ttm: specify DMA_ATTR_NO_WARN for huge page pools
+
+  * linux-tools: perf incorrectly linking libbfd (LP: #1748922)
+    - SAUCE: tools -- add ability to disable libbfd
+    - [Packaging] correct disablement of libbfd
+
+  * [Artful] Realtek ALC225: 2 secs noise when a headset plugged in
+    (LP: #1744058)
+    - ALSA: hda/realtek - update ALC225 depop optimize
+
+  * [Artful] Support headset mode for DELL WYSE (LP: #1723913)
+    - SAUCE: ALSA: hda/realtek - Add support headset mode for DELL WYSE
+
+  * headset mic can't be detected on two Dell machines (LP: #1748807)
+    - ALSA: hda/realtek - Support headset mode for ALC215/ALC285/ALC289
+    - ALSA: hda - Fix headset mic detection problem for two Dell machines
+
+  * Bionic update to v4.15.3 stable release (LP: #1749191)
+    - ip6mr: fix stale iterator
+    - net: igmp: add a missing rcu locking section
+    - qlcnic: fix deadlock bug
+    - qmi_wwan: Add support for Quectel EP06
+    - r8169: fix RTL8168EP take too long to complete driver initialization.
+    - tcp: release sk_frag.page in tcp_disconnect
+    - vhost_net: stop device during reset owner
+    - ipv6: addrconf: break critical section in addrconf_verify_rtnl()
+    - ipv6: change route cache aging logic
+    - Revert "defer call to mem_cgroup_sk_alloc()"
+    - net: ipv6: send unsolicited NA after DAD
+    - rocker: fix possible null pointer dereference in
+      rocker_router_fib_event_work
+    - tcp_bbr: fix pacing_gain to always be unity when using lt_bw
+    - cls_u32: add missing RCU annotation.
+    - ipv6: Fix SO_REUSEPORT UDP socket with implicit sk_ipv6only
+    - soreuseport: fix mem leak in reuseport_add_sock()
+    - net_sched: get rid of rcu_barrier() in tcf_block_put_ext()
+    - net: sched: fix use-after-free in tcf_block_put_ext
+    - media: mtk-vcodec: add missing MODULE_LICENSE/DESCRIPTION
+    - media: soc_camera: soc_scale_crop: add missing
+      MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - media: tegra-cec: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - gpio: uniphier: fix mismatch between license text and MODULE_LICENSE
+    - crypto: tcrypt - fix S/G table for test_aead_speed()
+    - Linux 4.15.3
+
+  * bnx2x_attn_int_deasserted3:4323 MC assert! (LP: #1715519) //
+    CVE-2018-1000026
+    - net: create skb_gso_validate_mac_len()
+    - bnx2x: disable GSO where gso_size is too big for hardware
+
+  * ethtool -p fails to light NIC LED on HiSilicon D05 systems (LP: #1748567)
+    - net: hns: add ACPI mode support for ethtool -p
+
+  * CVE-2017-5715 (Spectre v2 Intel)
+    - [Packaging] retpoline files must be sorted
+    - [Packaging] pull in retpoline files
+
+  * [Feature] PXE boot with Intel Omni-Path (LP: #1712031)
+    - d-i: Add hfi1 to nic-modules
+
+  * CVE-2017-5715 (Spectre v2 retpoline)
+    - [Packaging] retpoline -- add call site validation
+    - [Config] disable retpoline checks for first upload
+
+  * Do not duplicate changelog entries assigned to more than one bug or CVE
+    (LP: #1743383)
+    - [Packaging] git-ubuntu-log -- handle multiple bugs/cves better
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 13 Feb 2018 11:33:58 -0600
+
+linux (4.15.0-9.10) bionic; urgency=medium
+
+  * linux: 4.15.0-9.10 -proposed tracker (LP: #1748244)
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] tests -- remove gcc-multilib dependency for arm64
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 08 Feb 2018 11:25:04 -0600
+
+linux (4.15.0-8.9) bionic; urgency=medium
+
+  * linux: 4.15.0-8.9 -proposed tracker (LP: #1748075)
+
+  * Bionic update to v4.15.2 stable release (LP: #1748072)
+    - KVM: x86: Make indirect calls in emulator speculation safe
+    - KVM: VMX: Make indirect call speculation safe
+    - module/retpoline: Warn about missing retpoline in module
+    - x86/cpufeatures: Add CPUID_7_EDX CPUID leaf
+    - x86/cpufeatures: Add Intel feature bits for Speculation Control
+    - x86/cpufeatures: Add AMD feature bits for Speculation Control
+    - x86/msr: Add definitions for new speculation control MSRs
+    - x86/pti: Do not enable PTI on CPUs which are not vulnerable to Meltdown
+    - x86/cpufeature: Blacklist SPEC_CTRL/PRED_CMD on early Spectre v2 microcodes
+    - x86/speculation: Add basic IBPB (Indirect Branch Prediction Barrier) support
+    - x86/alternative: Print unadorned pointers
+    - x86/nospec: Fix header guards names
+    - x86/bugs: Drop one "mitigation" from dmesg
+    - x86/cpu/bugs: Make retpoline module warning conditional
+    - x86/cpufeatures: Clean up Spectre v2 related CPUID flags
+    - x86/retpoline: Simplify vmexit_fill_RSB()
+    - x86/speculation: Simplify indirect_branch_prediction_barrier()
+    - auxdisplay: img-ascii-lcd: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - iio: adc/accel: Fix up module licenses
+    - pinctrl: pxa: pxa2xx: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - ASoC: pcm512x: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - KVM: nVMX: Eliminate vmcs02 pool
+    - KVM: VMX: introduce alloc_loaded_vmcs
+    - objtool: Improve retpoline alternative handling
+    - objtool: Add support for alternatives at the end of a section
+    - objtool: Warn on stripped section symbol
+    - x86/mm: Fix overlap of i386 CPU_ENTRY_AREA with FIX_BTMAP
+    - x86/spectre: Check CONFIG_RETPOLINE in command line parser
+    - x86/entry/64: Remove the SYSCALL64 fast path
+    - x86/entry/64: Push extra regs right away
+    - x86/asm: Move 'status' from thread_struct to thread_info
+    - Documentation: Document array_index_nospec
+    - array_index_nospec: Sanitize speculative array de-references
+    - x86: Implement array_index_mask_nospec
+    - x86: Introduce barrier_nospec
+    - x86: Introduce __uaccess_begin_nospec() and uaccess_try_nospec
+    - x86/usercopy: Replace open coded stac/clac with __uaccess_{begin, end}
+    - x86/uaccess: Use __uaccess_begin_nospec() and uaccess_try_nospec
+    - x86/get_user: Use pointer masking to limit speculation
+    - x86/syscall: Sanitize syscall table de-references under speculation
+    - vfs, fdtable: Prevent bounds-check bypass via speculative execution
+    - nl80211: Sanitize array index in parse_txq_params
+    - x86/spectre: Report get_user mitigation for spectre_v1
+    - x86/spectre: Fix spelling mistake: "vunerable"-> "vulnerable"
+    - x86/cpuid: Fix up "virtual" IBRS/IBPB/STIBP feature bits on Intel
+    - x86/speculation: Use Indirect Branch Prediction Barrier in context switch
+    - x86/paravirt: Remove 'noreplace-paravirt' cmdline option
+    - KVM: VMX: make MSR bitmaps per-VCPU
+    - x86/kvm: Update spectre-v1 mitigation
+    - x86/retpoline: Avoid retpolines for built-in __init functions
+    - x86/spectre: Simplify spectre_v2 command line parsing
+    - x86/pti: Mark constant arrays as __initconst
+    - x86/speculation: Fix typo IBRS_ATT, which should be IBRS_ALL
+    - KVM/x86: Update the reverse_cpuid list to include CPUID_7_EDX
+    - KVM/x86: Add IBPB support
+    - KVM/VMX: Emulate MSR_IA32_ARCH_CAPABILITIES
+    - KVM/VMX: Allow direct access to MSR_IA32_SPEC_CTRL
+    - KVM/SVM: Allow direct access to MSR_IA32_SPEC_CTRL
+    - serial: core: mark port as initialized after successful IRQ change
+    - fpga: region: release of_parse_phandle nodes after use
+    - Linux 4.15.2
+
+  * Add support for the NIC on SynQuacer E-Series boards (LP: #1747792)
+    - net: phy: core: remove now uneeded disabling of interrupts
+    - [Config] CONFIG_NET_VENDOR_SOCIONEXT=y & CONFIG_SNI_NETSEC=m
+    - net: socionext: Add Synquacer NetSec driver
+    - net: socionext: include linux/io.h to fix build
+    - net: socionext: Fix error return code in netsec_netdev_open()
+
+  * [Artful/Bionic] [Config] enable EDAC_GHES for ARM64 (LP: #1747746)
+    - [Config] CONFIG_EDAC_GHES=y
+
+  * support thunderx2 vendor pmu events (LP: #1747523)
+    - perf pmu: Pass pmu as a parameter to get_cpuid_str()
+    - perf tools arm64: Add support for get_cpuid_str function.
+    - perf pmu: Add helper function is_pmu_core to detect PMU CORE devices
+    - perf vendor events arm64: Add ThunderX2 implementation defined pmu core
+      events
+    - perf pmu: Add check for valid cpuid in perf_pmu__find_map()
+
+  * linux 4.14.0-7.9 ADT test failure with linux 4.14.0-7.9 (LP: #1732463)
+    - SAUCE: mm: disable vma based swap readahead by default
+    - SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Fix CONFIG_PROFILE_ALL_BRANCHES annotations
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 07 Feb 2018 21:13:27 -0600
+
+linux (4.15.0-7.8) bionic; urgency=medium
+
+  * Bionic update to v4.15.1 stable release (LP: #1747169)
+    - Bluetooth: hci_serdev: Init hci_uart proto_lock to avoid oops
+    - tools/gpio: Fix build error with musl libc
+    - gpio: stmpe: i2c transfer are forbiden in atomic context
+    - gpio: Fix kernel stack leak to userspace
+    - ALSA: hda - Reduce the suspend time consumption for ALC256
+    - crypto: ecdh - fix typo in KPP dependency of CRYPTO_ECDH
+    - crypto: aesni - handle zero length dst buffer
+    - crypto: aesni - fix typo in generic_gcmaes_decrypt
+    - crypto: aesni - add wrapper for generic gcm(aes)
+    - crypto: aesni - Fix out-of-bounds access of the data buffer in generic-gcm-
+      aesni
+    - crypto: aesni - Fix out-of-bounds access of the AAD buffer in generic-gcm-
+      aesni
+    - crypto: inside-secure - fix hash when length is a multiple of a block
+    - crypto: inside-secure - avoid unmapping DMA memory that was not mapped
+    - crypto: sha3-generic - fixes for alignment and big endian operation
+    - crypto: af_alg - whitelist mask and type
+    - HID: wacom: EKR: ensure devres groups at higher indexes are released
+    - HID: wacom: Fix reporting of touch toggle (WACOM_HID_WD_MUTE_DEVICE) events
+    - power: reset: zx-reboot: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - gpio: iop: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - gpio: ath79: add missing MODULE_DESCRIPTION/LICENSE
+    - mtd: nand: denali_pci: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - igb: Free IRQs when device is hotplugged
+    - ima/policy: fix parsing of fsuuid
+    - scsi: aacraid: Fix udev inquiry race condition
+    - scsi: aacraid: Fix hang in kdump
+    - scsi: storvsc: missing error code in storvsc_probe()
+    - staging: lustre: separate a connection destroy from free struct kib_conn
+    - staging: ccree: NULLify backup_info when unused
+    - staging: ccree: fix fips event irq handling build
+    - tty: fix data race between tty_init_dev and flush of buf
+    - usb: option: Add support for FS040U modem
+    - USB: serial: pl2303: new device id for Chilitag
+    - USB: cdc-acm: Do not log urb submission errors on disconnect
+    - CDC-ACM: apply quirk for card reader
+    - USB: serial: io_edgeport: fix possible sleep-in-atomic
+    - usbip: prevent bind loops on devices attached to vhci_hcd
+    - usbip: list: don't list devices attached to vhci_hcd
+    - USB: serial: simple: add Motorola Tetra driver
+    - usb: f_fs: Prevent gadget unbind if it is already unbound
+    - usb: uas: unconditionally bring back host after reset
+    - usb/gadget: Fix "high bandwidth" check in usb_gadget_ep_match_desc()
+    - ANDROID: binder: remove waitqueue when thread exits.
+    - android: binder: use VM_ALLOC to get vm area
+    - mei: me: allow runtime pm for platform with D0i3
+    - serial: 8250_of: fix return code when probe function fails to get reset
+    - serial: 8250_uniphier: fix error return code in uniphier_uart_probe()
+    - serial: 8250_dw: Revert "Improve clock rate setting"
+    - serial: imx: Only wakeup via RTSDEN bit if the system has RTS/CTS
+    - spi: imx: do not access registers while clocks disabled
+    - iio: adc: stm32: fix scan of multiple channels with DMA
+    - iio: chemical: ccs811: Fix output of IIO_CONCENTRATION channels
+    - test_firmware: fix missing unlock on error in config_num_requests_store()
+    - Input: synaptics-rmi4 - unmask F03 interrupts when port is opened
+    - Input: synaptics-rmi4 - do not delete interrupt memory too early
+    - x86/efi: Clarify that reset attack mitigation needs appropriate userspace
+    - Linux 4.15.1
+
+  * Dell XPS 13 9360 bluetooth (Atheros) won't connect after resume
+    (LP: #1744712)
+    - Revert "Bluetooth: btusb: fix QCA Rome suspend/resume"
+    - Bluetooth: btusb: Restore QCA Rome suspend/resume fix with a "rewritten"
+      version
+
+  * apparmor profile load in stacked policy container fails (LP: #1746463)
+    - SAUCE: apparmor: fix display of .ns_name for containers
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 04 Feb 2018 11:56:32 +0100
+
+linux (4.15.0-6.7) bionic; urgency=low
+
+  * upload urgency should be medium by default (LP: #1745338)
+    - [Packaging] update urgency to medium by default
+
+  * Shutdown hang on 16.04 with iscsi targets (LP: #1569925)
+    - scsi: libiscsi: Allow sd_shutdown on bad transport
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.5-1ubuntu1, zfs to 0.7.5-1ubuntu1
+    - Revert "UBUNTU: SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM"
+    - Revert "UBUNTU: SAUCE: mm: disable vma based swap readahead by default"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 29 Jan 2018 08:47:07 -0600
+
+linux (4.15.0-5.6) bionic; urgency=low
+
+  * $(LOCAL_ENV_CC) and $(LOCAL_ENV_DISTCC_HOSTS) should be properly quoted
+    (LP: #1744077)
+    - [Debian] pass LOCAL_ENV_CC and LOCAL_ENV_DISTCC_HOSTS properly
+
+  * Missing install-time driver for QLogic QED 25/40/100Gb Ethernet NIC
+    (LP: #1743638)
+    - [d-i] Add qede to nic-modules udeb
+
+  * boot failure on AMD Raven + WesternXT (LP: #1742759)
+    - SAUCE: drm/amdgpu: add atpx quirk handling (v2)
+
+  * Unable to handle kernel NULL pointer dereference at isci_task_abort_task
+    (LP: #1726519)
+    - SAUCE: Revert "scsi: libsas: allow async aborts"
+
+  * Update Ubuntu-4.15.0 config to support Intel Atom devices (LP: #1739939)
+    - [Config] CONFIG_SERIAL_DEV_BUS=y, CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v4.15-rc7
+    - [Config] CONFIG_CPU_ISOLATION=y
+    - [Config] Update annotations following config review
+    - Revert "UBUNTU: SAUCE: Import aufs driver"
+    - SAUCE: Import aufs driver
+    - ubuntu: vbox -- update to 5.2.6-dfsg-1
+    - ubuntu: vbox: build fixes for 4.15
+    - ubuntu: vbox -- update to 5.2.6-dfsg-2
+    - hio: updates for timer api changes in 4.15
+    - enable hio build
+    - Rebase to v4.15-rc9
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc9
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 22 Jan 2018 10:16:05 -0600
+
+linux (4.15.0-4.5) bionic; urgency=low
+
+  * [0cf3:e010] QCA6174A XR failed to pair with bt 4.0 device  (LP: #1741166)
+    - SAUCE: Bluetooth: btusb: Add support for 0cf3:e010
+
+  * External HDMI monitor failed to show screen on Lenovo X1 series
+    (LP: #1738523)
+    - SAUCE: drm/i915: Disable writing of TMDS_OE on Lenovo ThinkPad X1 series
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] autoreconstruct - add resoration of execute permissions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 10 Jan 2018 10:24:22 -0600
+
+linux (4.15.0-3.4) bionic; urgency=low
+
+  * ubuntu/xr-usb-serial didn't get built in zesty and artful (LP: #1733281)
+    - SAUCE: make sure ubuntu/xr-usb-serial builds for x86
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 03 Jan 2018 20:20:43 -0600
+
+linux (4.15.0-2.3) bionic; urgency=low
+
+  * nvidia-graphics-drivers-384 384.90-0ubuntu6 ADT test failure with linux
+    4.15.0-1.2 (LP: #1737752)
+    - x86/mm: Unbreak modules that use the DMA API
+
+  * Ubuntu 17.10 corrupting BIOS - many LENOVO laptops models (LP: #1734147)
+    - [Config] CONFIG_SPI_INTEL_SPI_*=n
+
+  * power: commonise configs IBMVETH/IBMVSCSI and ensure both are in linux-image
+    and udebs (LP: #1521712)
+    - [Config] Include ibmvnic in nic-modules
+
+  * Enable arm64 emulation of removed ARMv7 instructions (LP: #1545542)
+    - [Config] Enable support for emulation of deprecated ARMv8 instructions
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl with 4.15 compat fix (LP:#1737761)
+    - Enable zfs build
+    - [Debian] add icp to zfs-modules.ignore
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 18 Dec 2017 09:27:13 -0600
+
+linux (4.15.0-1.2) bionic; urgency=low
+
+  * Disabling zfs does not always disable module checks for the zfs modules
+    (LP: #1737176)
+    - [Packaging] disable zfs module checks when zfs is disabled
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_UNWINDER_FRAME_POINTER=y for amd64
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 10 Dec 2017 22:07:19 -0600
+
+linux (4.15.0-0.1) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu: vbox -- update to 5.2.2-dfsg-2
+    - ubuntu: vbox: build fixes for 4.15
+    - disable hio build
+    - [Config] Update kernel lockdown options to fix build errors
+    - Disable zfs build
+    - SAUCE: Import aufs driver
+    - [Config] Enable AUFS config options
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 08 Dec 2017 13:55:42 -0600
+
+linux (4.14.0-11.13) bionic; urgency=low
+
+  * linux: 4.14.0-11.13 -proposed tracker (LP: #1736168)
+
+  * CVE-2017-1000405
+    - mm, thp: Do not make page table dirty unconditionally in touch_p[mu]d()
+
+  * linux 4.14.0-7.9 ADT test failure with linux 4.14.0-7.9 (LP: #1732463)
+    - SAUCE: mm: disable vma based swap readahead by default
+    - SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM
+
+  * Bionic update to v4.14.3 stable release (LP: #1735843)
+    - s390: fix transactional execution control register handling
+    - s390/noexec: execute kexec datamover without DAT
+    - s390/runtime instrumention: fix possible memory corruption
+    - s390/guarded storage: fix possible memory corruption
+    - s390/disassembler: add missing end marker for e7 table
+    - s390/disassembler: increase show_code buffer size
+    - ACPI / PM: Fix acpi_pm_notifier_lock vs flush_workqueue() deadlock
+    - ACPI / EC: Fix regression related to triggering source of EC event handling
+    - cpufreq: schedutil: Reset cached_raw_freq when not in sync with next_freq
+    - serdev: fix registration of second slave
+    - sched: Make resched_cpu() unconditional
+    - lib/mpi: call cond_resched() from mpi_powm() loop
+    - x86/boot: Fix boot failure when SMP MP-table is based at 0
+    - x86/decoder: Add new TEST instruction pattern
+    - x86/entry/64: Fix entry_SYSCALL_64_after_hwframe() IRQ tracing
+    - x86/entry/64: Add missing irqflags tracing to native_load_gs_index()
+    - perf/x86/intel: Hide TSX events when RTM is not supported
+    - arm64: Implement arch-specific pte_access_permitted()
+    - ARM: 8722/1: mm: make STRICT_KERNEL_RWX effective for LPAE
+    - ARM: 8721/1: mm: dump: check hardware RO bit for LPAE
+    - uapi: fix linux/tls.h userspace compilation error
+    - uapi: fix linux/rxrpc.h userspace compilation errors
+    - MIPS: cmpxchg64() and HAVE_VIRT_CPU_ACCOUNTING_GEN don't work for 32-bit SMP
+    - MIPS: ralink: Fix MT7628 pinmux
+    - MIPS: ralink: Fix typo in mt7628 pinmux function
+    - net: mvneta: fix handling of the Tx descriptor counter
+    - nbd: wait uninterruptible for the dead timeout
+    - nbd: don't start req until after the dead connection logic
+    - PM / OPP: Add missing of_node_put(np)
+    - PCI/ASPM: Account for downstream device's Port Common_Mode_Restore_Time
+    - PCI/ASPM: Use correct capability pointer to program LTR_L1.2_THRESHOLD
+    - PCI: hv: Use effective affinity mask
+    - PCI: Set Cavium ACS capability quirk flags to assert RR/CR/SV/UF
+    - PCI: Apply Cavium ThunderX ACS quirk to more Root Ports
+    - ALSA: hda: Add Raven PCI ID
+    - dm integrity: allow unaligned bv_offset
+    - dm cache: fix race condition in the writeback mode overwrite_bio
+      optimisation
+    - dm crypt: allow unaligned bv_offset
+    - dm zoned: ignore last smaller runt zone
+    - dm mpath: remove annoying message of 'blk_get_request() returned -11'
+    - dm bufio: fix integer overflow when limiting maximum cache size
+    - ovl: Put upperdentry if ovl_check_origin() fails
+    - dm: allocate struct mapped_device with kvzalloc
+    - sched/rt: Simplify the IPI based RT balancing logic
+    - MIPS: pci: Remove KERN_WARN instance inside the mt7620 driver
+    - dm: fix race between dm_get_from_kobject() and __dm_destroy()
+    - dm: discard support requires all targets in a table support discards
+    - MIPS: Fix odd fp register warnings with MIPS64r2
+    - MIPS: Fix MIPS64 FP save/restore on 32-bit kernels
+    - MIPS: dts: remove bogus bcm96358nb4ser.dtb from dtb-y entry
+    - MIPS: Fix an n32 core file generation regset support regression
+    - MIPS: BCM47XX: Fix LED inversion for WRT54GSv1
+    - MIPS: math-emu: Fix final emulation phase for certain instructions
+    - rt2x00usb: mark device removed when get ENOENT usb error
+    - mm/z3fold.c: use kref to prevent page free/compact race
+    - autofs: don't fail mount for transient error
+    - nilfs2: fix race condition that causes file system corruption
+    - fscrypt: lock mutex before checking for bounce page pool
+    - eCryptfs: use after free in ecryptfs_release_messaging()
+    - libceph: don't WARN() if user tries to add invalid key
+    - bcache: check ca->alloc_thread initialized before wake up it
+    - fs: guard_bio_eod() needs to consider partitions
+    - fanotify: fix fsnotify_prepare_user_wait() failure
+    - isofs: fix timestamps beyond 2027
+    - btrfs: change how we decide to commit transactions during flushing
+    - f2fs: expose some sectors to user in inline data or dentry case
+    - NFS: Fix typo in nomigration mount option
+    - NFS: Revert "NFS: Move the flock open mode check into nfs_flock()"
+    - nfs: Fix ugly referral attributes
+    - NFS: Avoid RCU usage in tracepoints
+    - NFS: revalidate "." etc correctly on "open".
+    - nfsd: deal with revoked delegations appropriately
+    - rtlwifi: rtl8192ee: Fix memory leak when loading firmware
+    - rtlwifi: fix uninitialized rtlhal->last_suspend_sec time
+    - iwlwifi: fix firmware names for 9000 and A000 series hw
+    - md: fix deadlock error in recent patch.
+    - md: don't check MD_SB_CHANGE_CLEAN in md_allow_write
+    - Bluetooth: btqcomsmd: Add support for BD address setup
+    - md/bitmap: revert a patch
+    - fsnotify: clean up fsnotify_prepare/finish_user_wait()
+    - fsnotify: pin both inode and vfsmount mark
+    - fsnotify: fix pinning group in fsnotify_prepare_user_wait()
+    - ata: fixes kernel crash while tracing ata_eh_link_autopsy event
+    - ext4: fix interaction between i_size, fallocate, and delalloc after a crash
+    - ext4: prevent data corruption with inline data + DAX
+    - ext4: prevent data corruption with journaling + DAX
+    - ALSA: pcm: update tstamp only if audio_tstamp changed
+    - ALSA: usb-audio: Add sanity checks to FE parser
+    - ALSA: usb-audio: Fix potential out-of-bound access at parsing SU
+    - ALSA: usb-audio: Add sanity checks in v2 clock parsers
+    - ALSA: timer: Remove kernel warning at compat ioctl error paths
+    - ALSA: hda/realtek - Fix ALC275 no sound issue
+    - ALSA: hda: Fix too short HDMI/DP chmap reporting
+    - ALSA: hda - Fix yet remaining issue with vmaster 0dB initialization
+    - ALSA: hda/realtek - Fix ALC700 family no sound issue
+    - ASoC: sun8i-codec: Invert Master / Slave condition
+    - ASoC: sun8i-codec: Fix left and right channels inversion
+    - ASoC: sun8i-codec: Set the BCLK divider
+    - mfd: lpc_ich: Avoton/Rangeley uses SPI_BYT method
+    - fix a page leak in vhost_scsi_iov_to_sgl() error recovery
+    - 9p: Fix missing commas in mount options
+    - fs/9p: Compare qid.path in v9fs_test_inode
+    - net/9p: Switch to wait_event_killable()
+    - scsi: qla2xxx: Suppress a kernel complaint in qla_init_base_qpair()
+    - scsi: sd_zbc: Fix sd_zbc_read_zoned_characteristics()
+    - scsi: lpfc: fix pci hot plug crash in timer management routines
+    - scsi: lpfc: fix pci hot plug crash in list_add call
+    - scsi: lpfc: Fix crash receiving ELS while detaching driver
+    - scsi: lpfc: Fix FCP hba_wqidx assignment
+    - scsi: lpfc: Fix oops if nvmet_fc_register_targetport fails
+    - iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref
+    - iscsi-target: Fix non-immediate TMR reference leak
+    - target: fix null pointer regression in core_tmr_drain_tmr_list
+    - target: fix buffer offset in core_scsi3_pri_read_full_status
+    - target: Fix QUEUE_FULL + SCSI task attribute handling
+    - target: Fix caw_sem leak in transport_generic_request_failure
+    - target: Fix quiese during transport_write_pending_qf endless loop
+    - target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK
+    - mtd: Avoid probe failures when mtd->dbg.dfs_dir is invalid
+    - mtd: nand: Export nand_reset() symbol
+    - mtd: nand: atmel: Actually use the PM ops
+    - mtd: nand: omap2: Fix subpage write
+    - mtd: nand: Fix writing mtdoops to nand flash.
+    - mtd: nand: mtk: fix infinite ECC decode IRQ issue
+    - mailbox: bcm-flexrm-mailbox: Fix FlexRM ring flush sequence
+    - p54: don't unregister leds when they are not initialized
+    - block: Fix a race between blk_cleanup_queue() and timeout handling
+    - raid1: prevent freeze_array/wait_all_barriers deadlock
+    - genirq: Track whether the trigger type has been set
+    - irqchip/gic-v3: Fix ppi-partitions lookup
+    - lockd: double unregister of inetaddr notifiers
+    - KVM: PPC: Book3S HV: Don't call real-mode XICS hypercall handlers if not
+      enabled
+    - KVM: nVMX: set IDTR and GDTR limits when loading L1 host state
+    - KVM: SVM: obey guest PAT
+    - kvm: vmx: Reinstate support for CPUs without virtual NMI
+    - dax: fix PMD faults on zero-length files
+    - dax: fix general protection fault in dax_alloc_inode
+    - SUNRPC: Fix tracepoint storage issues with svc_recv and svc_rqst_status
+    - clk: ti: dra7-atl-clock: fix child-node lookups
+    - libnvdimm, dimm: clear 'locked' status on successful DIMM enable
+    - libnvdimm, pfn: make 'resource' attribute only readable by root
+    - libnvdimm, namespace: fix label initialization to use valid seq numbers
+    - libnvdimm, region : make 'resource' attribute only readable by root
+    - libnvdimm, namespace: make 'resource' attribute only readable by root
+    - svcrdma: Preserve CB send buffer across retransmits
+    - IB/srpt: Do not accept invalid initiator port names
+    - IB/cm: Fix memory corruption in handling CM request
+    - IB/hfi1: Fix incorrect available receive user context count
+    - IB/srp: Avoid that a cable pull can trigger a kernel crash
+    - IB/core: Avoid crash on pkey enforcement failed in received MADs
+    - IB/core: Only maintain real QPs in the security lists
+    - NFC: fix device-allocation error return
+    - spi-nor: intel-spi: Fix broken software sequencing codes
+    - i40e: Use smp_rmb rather than read_barrier_depends
+    - igb: Use smp_rmb rather than read_barrier_depends
+    - igbvf: Use smp_rmb rather than read_barrier_depends
+    - ixgbevf: Use smp_rmb rather than read_barrier_depends
+    - i40evf: Use smp_rmb rather than read_barrier_depends
+    - fm10k: Use smp_rmb rather than read_barrier_depends
+    - ixgbe: Fix skb list corruption on Power systems
+    - parisc: Fix validity check of pointer size argument in new CAS
+      implementation
+    - powerpc: Fix boot on BOOK3S_32 with CONFIG_STRICT_KERNEL_RWX
+    - powerpc/mm/radix: Fix crashes on Power9 DD1 with radix MMU and STRICT_RWX
+    - powerpc/perf/imc: Use cpu_to_node() not topology_physical_package_id()
+    - powerpc/signal: Properly handle return value from uprobe_deny_signal()
+    - powerpc/64s: Fix masking of SRR1 bits on instruction fault
+    - powerpc/64s/radix: Fix 128TB-512TB virtual address boundary case allocation
+    - powerpc/64s/hash: Fix 512T hint detection to use >= 128T
+    - powerpc/64s/hash: Fix 128TB-512TB virtual address boundary case allocation
+    - powerpc/64s/hash: Fix fork() with 512TB process address space
+    - powerpc/64s/hash: Allow MAP_FIXED allocations to cross 128TB boundary
+    - media: Don't do DMA on stack for firmware upload in the AS102 driver
+    - media: rc: check for integer overflow
+    - media: rc: nec decoder should not send both repeat and keycode
+    - cx231xx-cards: fix NULL-deref on missing association descriptor
+    - media: v4l2-ctrl: Fix flags field on Control events
+    - media: venus: fix wrong size on dma_free
+    - media: venus: venc: fix bytesused v4l2_plane field
+    - media: venus: reimplement decoder stop command
+    - ARM64: dts: meson-gxl: Add alternate ARM Trusted Firmware reserved memory
+      zone
+    - iwlwifi: fix wrong struct for a000 device
+    - iwlwifi: add a new a000 device
+    - iwlwifi: pcie: sort IDs for the 9000 series for easier comparisons
+    - iwlwifi: add new cards for a000 series
+    - iwlwifi: add new cards for 8265 series
+    - iwlwifi: add new cards for 8260 series
+    - iwlwifi: fix PCI IDs and configuration mapping for 9000 series
+    - iwlwifi: mvm: support version 7 of the SCAN_REQ_UMAC FW command
+    - e1000e: Fix error path in link detection
+    - e1000e: Fix return value test
+    - e1000e: Separate signaling for link check/link up
+    - e1000e: Avoid receiver overrun interrupt bursts
+    - e1000e: fix buffer overrun while the I219 is processing DMA transactions
+    - Linux 4.14.3
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: s390/topology: don't inline cpu_to_node
+    - SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to 0.7.3-1ubuntu1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 04 Dec 2017 09:08:07 -0600
+
+linux (4.14.0-10.12) bionic; urgency=low
+
+  * linux: 4.14.0-10.12 -proposed tracker (LP: #1734901)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Enable the ACPI kernel debugger and acpidbg tool
+    - [Packaging] Include arch/arm64/kernel/ftrace-mod.o in headers package
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 Nov 2017 08:46:49 -0600
+
+linux (4.14.0-9.11) bionic; urgency=low
+
+  * linux: 4.14.0-9.11 -proposed tracker (LP: #1734728)
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to
+      0.7.3-1ubuntu1"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Nov 2017 12:44:48 -0600
+
+linux (4.14.0-8.10) bionic; urgency=low
+
+  * linux: 4.14.0-8.10 -proposed tracker (LP: #1734695)
+
+  * Bionic update to v4.14.2 stable release (LP: #1734694)
+    - bio: ensure __bio_clone_fast copies bi_partno
+    - af_netlink: ensure that NLMSG_DONE never fails in dumps
+    - vxlan: fix the issue that neigh proxy blocks all icmpv6 packets
+    - net: cdc_ncm: GetNtbFormat endian fix
+    - fealnx: Fix building error on MIPS
+    - net/sctp: Always set scope_id in sctp_inet6_skb_msgname
+    - ima: do not update security.ima if appraisal status is not INTEGRITY_PASS
+    - serial: omap: Fix EFR write on RTS deassertion
+    - serial: 8250_fintek: Fix finding base_port with activated SuperIO
+    - tpm-dev-common: Reject too short writes
+    - rcu: Fix up pending cbs check in rcu_prepare_for_idle
+    - mm/pagewalk.c: report holes in hugetlb ranges
+    - ocfs2: fix cluster hang after a node dies
+    - ocfs2: should wait dio before inode lock in ocfs2_setattr()
+    - ipmi: fix unsigned long underflow
+    - mm/page_alloc.c: broken deferred calculation
+    - mm/page_ext.c: check if page_ext is not prepared
+    - coda: fix 'kernel memory exposure attempt' in fsync
+    - ipmi: Prefer ACPI system interfaces over SMBIOS ones
+    - Linux 4.14.2
+
+  * Bionic update to v4.14.1 stable release (LP: #1734693)
+    - EDAC, sb_edac: Don't create a second memory controller if HA1 is not present
+    - dmaengine: dmatest: warn user when dma test times out
+    - media: imon: Fix null-ptr-deref in imon_probe
+    - media: dib0700: fix invalid dvb_detach argument
+    - crypto: dh - Fix double free of ctx->p
+    - crypto: dh - Don't permit 'p' to be 0
+    - crypto: dh - Don't permit 'key' or 'g' size longer than 'p'
+    - crypto: brcm - Explicity ACK mailbox message
+    - USB: early: Use new USB product ID and strings for DbC device
+    - USB: usbfs: compute urb->actual_length for isochronous
+    - USB: Add delay-init quirk for Corsair K70 LUX keyboards
+    - usb: gadget: f_fs: Fix use-after-free in ffs_free_inst
+    - USB: serial: metro-usb: stop I/O after failed open
+    - USB: serial: Change DbC debug device binding ID
+    - USB: serial: qcserial: add pid/vid for Sierra Wireless EM7355 fw update
+    - USB: serial: garmin_gps: fix I/O after failed probe and remove
+    - USB: serial: garmin_gps: fix memory leak on probe errors
+    - selftests/x86/protection_keys: Fix syscall NR redefinition warnings
+    - x86/MCE/AMD: Always give panic severity for UC errors in kernel context
+    - platform/x86: peaq-wmi: Add DMI check before binding to the WMI interface
+    - platform/x86: peaq_wmi: Fix missing terminating entry for peaq_dmi_table
+    - HID: cp2112: add HIDRAW dependency
+    - HID: wacom: generic: Recognize WACOM_HID_WD_PEN as a type of pen collection
+    - rpmsg: glink: Add missing MODULE_LICENSE
+    - staging: wilc1000: Fix bssid buffer offset in Txq
+    - staging: sm750fb: Fix parameter mistake in poke32
+    - staging: ccree: fix 64 bit scatter/gather DMA ops
+    - staging: greybus: spilib: fix use-after-free after deregistration
+    - staging: rtl8188eu: Revert 4 commits breaking ARP
+    - spi: fix use-after-free at controller deregistration
+    - sparc32: Add cmpxchg64().
+    - sparc64: mmu_context: Add missing include files
+    - sparc64: Fix page table walk for PUD hugepages
+    - Linux 4.14.1
+
+  * Set PANIC_TIMEOUT=10 on Power Systems (LP: #1730660)
+    - [Config]: Set PANIC_TIMEOUT=10 on ppc64el
+
+  * enable CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH easily confuse users
+    (LP: #1732627)
+    - [Config] CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH=n
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to 0.7.3-1ubuntu1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Nov 2017 07:43:44 -0600
+
+linux (4.14.0-7.9) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor: add base infastructure for socket mediation
+    - SAUCE: apparmor: af_unix mediation
+    - SAUCE: LSM stacking: procfs: add smack subdir to attrs
+    - SAUCE: LSM stacking: LSM: manage credential security blobs
+    - SAUCE: LSM stacking: LSM: Manage file security blobs
+    - SAUCE: LSM stacking: LSM: manage task security blobs
+    - SAUCE: LSM stacking: LSM: Infrastructure management of the remaining blobs
+    - SAUCE: LSM stacking: LSM: general but not extreme module stacking
+    - SAUCE: LSM stacking: LSM: Complete task_alloc hook
+    - SAUCE: LSM stacking: fixup procsfs: add smack subdir to attrs
+    - SAUCE: LSM stacking: fixup initialize task->security
+    - SAUCE: LSM stacking: fixup: alloc_task_ctx is dead code
+    - SAUCE: LSM stacking: add support for stacking getpeersec_stream
+    - SAUCE: LSM stacking: add stacking support to apparmor network hooks
+    - SAUCE: LSM stacking: fixup apparmor stacking enablement
+    - SAUCE: LSM stacking: fixup stacking kconfig
+    - SAUCE: LSM stacking: allow selecting multiple LSMs using kernel boot params
+    - SAUCE: LSM stacking: provide prctl interface for setting context
+    - SAUCE: LSM stacking: inherit current display LSM
+    - SAUCE: LSM stacking: keep an index for each registered LSM
+    - SAUCE: LSM stacking: verify display LSM
+    - SAUCE: LSM stacking: provide a way to specify the default display lsm
+    - SAUCE: LSM stacking: make sure LSM blob align on 64 bit boundaries
+    - SAUCE: LSM stacking: add /proc/<pid>/attr/display_lsm
+    - SAUCE: LSM stacking: add Kconfig to set default display LSM
+    - SAUCE: LSM stacking: add configs for LSM stacking
+    - SAUCE: LSM stacking: check for invalid zero sized writes
+    - [Config] Run updateconfigs after merging LSM stacking
+    - [Config] CONFIG_AMD_MEM_ENCRYPT=y
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 13 Nov 2017 08:12:08 -0600
+
+linux (4.14.0-6.8) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: add workarounds to enable ZFS for 4.14
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 06 Nov 2017 11:39:00 -0600
+
+linux (4.14.0-5.7) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Fix invocation of dh_prep for dbgsym packages
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 31 Oct 2017 07:07:23 -0500
+
+linux (4.14.0-4.5) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] virtualbox -- reduce in kernel module versions
+    - vbox-update: Fix up KERN_DIR definitions
+    - ubuntu: vbox -- update to 5.2.0-dfsg-2
+    - [Config] CONFIG_AMD_MEM_ENCRYPT=n
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 30 Oct 2017 13:29:20 -0500
+
+linux (4.14.0-3.4) artful; urgency=low
+
+  * Touchpad and TrackPoint Dose Not Work on Lenovo X1C6 and X280 (LP: #1723986)
+    - SAUCE: Input: synaptics-rmi4 - RMI4 can also use SMBUS version 3
+    - SAUCE: Input: synaptics - Lenovo X1 Carbon 5 should use SMBUS/RMI
+    - SAUCE: Input: synaptics - add Intertouch support on X1 Carbon 6th and X280
+
+  * powerpc/64s: Add workaround for P9 vector CI load issuenext (LP: #1721070)
+    - powerpc/64s: Add workaround for P9 vector CI load issue
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: staging: vboxvideo: Fix reporting invalid suggested-offset-properties
+    - [Config] CONFIG_DRM_VBOXVIDEO=m
+    - SAUCE: Import aufs driver
+    - [Config] Enable aufs
+    - [Config] Reorder annotations file after enabling aufs
+    - vbox-update: Disable imported vboxvideo module
+    - ubuntu: vbox -- update to 5.1.30-dfsg-1
+    - Enable vbox
+    - hio: Use correct sizes when initializing ssd_index_bits* arrays
+    - hio: Update io stat accounting for 4.14
+    - Enable hio
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc5
+  * Rebase to v4.14-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 23 Oct 2017 13:53:52 -0500
+
+linux (4.14.0-2.3) artful; urgency=low
+
+  * [Bug] USB controller failed to respond on Denverton after loading
+    intel_th_pci module (LP: #1715833)
+    - SAUCE: PCI: Disable broken RTIT_BAR of Intel TH
+
+  * CONFIG_DEBUG_FS is not enabled by "make zfcpdump_defconfig" with Ubuntu
+    17.10 (kernel 4.13) (LP: #1719290)
+    - SAUCE: s390: update zfcpdump_defconfig
+
+  * Add installer support for Broadcom BCM573xx network drivers. (LP: #1720466)
+    - d-i: Add bnxt_en to nic-modules.
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Update annotations for 4.14-rc2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc3
+  * Rebase to v4.14-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 11 Oct 2017 16:04:27 -0500
+
+linux (4.14.0-1.2) artful; urgency=low
+
+  * [Bug] USB 3.1 Gen2 works as 5Gbps (LP: #1720045)
+    - xhci: set missing SuperSpeedPlus Link Protocol bit in roothub descriptor
+
+  * Please make linux-libc-dev Provide: aufs-dev (LP: #1716091)
+    - [Packaging] Add aufs-dev to the Provides: for linux-libc-dev
+
+  * Upgrade to 4.13.0-11.12 in artful amd64 VM breaks display on wayland
+    (LP: #1718679)
+    - [Config] CONFIG_DRM_VBOXVIDEO=n
+
+  * ipmmu-vmsa driver breaks arm64 boots (LP: #1718734)
+    - [Config] Disable CONFIG_IPMMU_VMSA on arm64
+
+  * autopkgtest profile fails to build on armhf (LP: #1717920)
+    - [Packaging] autopkgtest -- disable d-i when dropping flavours
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_I2C_XLP9XX=m
+    - [Packaging] Use SRCPKGNAME rather than hard-coding the source package name
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 29 Sep 2017 09:09:11 -0400
+
+linux (4.14.0-0.1) artful; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - Disable vbox build
+    - Disable hio build
+    - Disable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 19 Sep 2017 20:22:29 -0500
+
+linux (4.13.0-11.12) artful; urgency=low
+
+  * linux: 4.13.0-11.12 -proposed tracker (LP: #1716699)
+
+  * kernel panic -not syncing: Fatal exception: panic_on_oops (LP: #1708399)
+    - s390/mm: fix local TLB flushing vs. detach of an mm address space
+    - s390/mm: fix race on mm->context.flush_mm
+
+  * CVE-2017-1000251
+    - Bluetooth: Properly check L2CAP config option output buffer length
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 12 Sep 2017 10:18:38 -0500
+
+linux (4.13.0-10.11) artful; urgency=low
+
+  * linux: 4.13.0-10.11 -proposed tracker (LP: #1716287)
+
+  * please add aufs-dkms to the Provides: for the kernel packages (LP: #1716093)
+    - [Packaging] Add aufs-dkms to the Provides: for kernel packages
+
+  * Artful update to v4.13.1 stable release (LP: #1716284)
+    - usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard
+    - USB: serial: option: add support for D-Link DWM-157 C1
+    - usb: Add device quirk for Logitech HD Pro Webcam C920-C
+    - usb:xhci:Fix regression when ATI chipsets detected
+    - USB: musb: fix external abort on suspend
+    - ANDROID: binder: add padding to binder_fd_array_object.
+    - ANDROID: binder: add hwbinder,vndbinder to BINDER_DEVICES.
+    - USB: core: Avoid race of async_completed() w/ usbdev_release()
+    - staging/rts5208: fix incorrect shift to extract upper nybble
+    - staging: ccree: save ciphertext for CTS IV
+    - staging: fsl-dpaa2/eth: fix off-by-one FD ctrl bitmaks
+    - iio: adc: ti-ads1015: fix incorrect data rate setting update
+    - iio: adc: ti-ads1015: fix scale information for ADS1115
+    - iio: adc: ti-ads1015: enable conversion when CONFIG_PM is not set
+    - iio: adc: ti-ads1015: avoid getting stale result after runtime resume
+    - iio: adc: ti-ads1015: don't return invalid value from buffer setup callbacks
+    - iio: adc: ti-ads1015: add adequate wait time to get correct conversion
+    - driver core: bus: Fix a potential double free
+    - HID: wacom: Do not completely map WACOM_HID_WD_TOUCHRINGSTATUS usage
+    - binder: free memory on error
+    - crypto: caam/qi - fix compilation with CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
+    - crypto: caam/qi - fix compilation with DEBUG enabled
+    - thunderbolt: Fix reset response_type
+    - fpga: altera-hps2fpga: fix multiple init of l3_remap_lock
+    - intel_th: pci: Add Cannon Lake PCH-H support
+    - intel_th: pci: Add Cannon Lake PCH-LP support
+    - ath10k: fix memory leak in rx ring buffer allocation
+    - drm/vgem: Pin our pages for dmabuf exports
+    - drm/ttm: Fix accounting error when fail to get pages for pool
+    - drm/dp/mst: Handle errors from drm_atomic_get_private_obj_state() correctly
+    - rtlwifi: rtl_pci_probe: Fix fail path of _rtl_pci_find_adapter
+    - Bluetooth: Add support of 13d3:3494 RTL8723BE device
+    - iwlwifi: pci: add new PCI ID for 7265D
+    - dlm: avoid double-free on error path in dlm_device_{register,unregister}
+    - mwifiex: correct channel stat buffer overflows
+    - MCB: add support for SC31 to mcb-lpc
+    - s390/mm: avoid empty zero pages for KVM guests to avoid postcopy hangs
+    - drm/nouveau/pci/msi: disable MSI on big-endian platforms by default
+    - drm/nouveau: Fix error handling in nv50_disp_atomic_commit
+    - workqueue: Fix flag collision
+    - ahci: don't use MSI for devices with the silly Intel NVMe remapping scheme
+    - cs5536: add support for IDE controller variant
+    - scsi: sg: protect against races between mmap() and SG_SET_RESERVED_SIZE
+    - scsi: sg: recheck MMAP_IO request length with lock held
+    - of/device: Prevent buffer overflow in of_device_modalias()
+    - rtlwifi: Fix memory leak when firmware request fails
+    - rtlwifi: Fix fallback firmware loading
+    - Linux 4.13.1
+
+  * Kernel has trouble recognizing Corsair Strafe RGB keyboard (LP: #1678477)
+    - usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard
+
+  * SRIOV: warning if unload VFs (LP: #1715073)
+    - PCI: Disable VF decoding before pcibios_sriov_disable() updates resources
+
+  * [Patch] network-i40e:NVM bug fixes (cherrypick from 4.14) (LP: #1715578)
+    - i40e: avoid NVM acquire deadlock during NVM update
+    - i40e: point wb_desc at the nvm_wb_desc during i40e_read_nvm_aq
+
+  * [P9,POwer NV] Perf PMU event : pm_br_2path and pm_ld_miss_l1 is counted
+    twice when perf stat is done (perf:) (LP: #1714571)
+    - perf vendor events powerpc: Remove duplicate events
+
+  * Unable to install Ubuntu on the NVMe disk under VMD PCI domain
+    (LP: #1703339)
+    - [Config] Include vmd in storage-core-modules udeb
+
+  * 17.10 fails to boot on POWER9 DD2.0 with Deep stop states (LP: #1715064)
+    - powerpc/powernv: Save/Restore additional SPRs for stop4 cpuidle
+    - powerpc/powernv: Clear PECE1 in LPCR via stop-api only on Hotplug
+    - SAUCE: powerpc/powernv: Clear LPCR[PECE1] via stop-api only for deep state
+      offline
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/seccomp: Support glibc 2.26 siginfo_t.h
+    - Revert "UBUNTU: SAUCE: Import aufs driver"
+    - SAUCE: Import aufs driver
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 10 Sep 2017 17:48:59 -0500
+
+linux (4.13.0-9.10) artful; urgency=low
+
+  * linux: 4.13.0-9.10 -proposed tracker (LP: #1715145)
+
+  * EDAC sbridge: Failed to register device with error -22. (LP: #1714112)
+    - [Config] CONFIG_EDAC_GHES=n
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu: vbox -- update to 5.1.26-dfsg-2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 05 Sep 2017 07:51:19 -0500
+
+linux (4.13.0-8.9) artful; urgency=low
+
+  * snapd 2.27.3+17.10 ADT test failure with linux 4.13.0-6.7 (LP: #1713103)
+    - SAUCE: apparmor: fix apparmorfs DAC access, permissions
+
+  * enable ARCH_SUNXI (and friends) in arm64 kernel .config (LP: #1701137)
+    - [Config] Enable CONFIG_ARCH_SUNXI and related options for arm64
+
+  * [Bug] Harrisonville: pnd2_edac always fail to load on B1 stepping
+    Harrisonville SDP (LP: #1709257)
+    - EDAC, pnd2: Build in a minimal sideband driver for Apollo Lake
+    - EDAC, pnd2: Mask off the lower four bits of a BAR
+    - EDAC, pnd2: Conditionally unhide/hide the P2SB PCI device to read BAR
+    - EDAC, pnd2: Properly toggle hidden state for P2SB PCI device
+    - SAUCE: i2c: i801: Restore the presence state of P2SB PCI device after
+      reading BAR
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: Import aufs driver"
+    - SAUCE: Import aufs driver
+    - SAUCE: selftests/powerpc: Disable some ptrace selftests
+    - [Config] CONFIG_CRYPTO_DEV_NITROX_CNN55XX=n for s390x
+    - [Config] CONFIG_I2C_SLAVE=n for amd64, i386, ppc64el
+    - [Config] Disable CONFIG_MDIO_* options for s390x
+    - [Config] CONFIG_SCSI_MQ_DEFAULT=n for s390x
+    - [Config] Update annotations for 4.13
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 31 Aug 2017 14:27:09 -0500
+
+linux (4.13.0-7.8) artful; urgency=low
+
+  * linux 4.12.0-11.12 ADT test failure with linux 4.12.0-11.12 (LP: #1710904)
+    - SAUCE: selftests/powerpc: Use snprintf to construct DSCR sysfs interface
+      paths
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: seccomp: log actions even when audit is disabled"
+
+  * Miscellaneous upstream changes
+    - seccomp: Provide matching filter for introspection
+    - seccomp: Sysctl to display available actions
+    - seccomp: Operation for checking if an action is available
+    - seccomp: Sysctl to configure actions that are allowed to be logged
+    - seccomp: Selftest for detection of filter flag support
+    - seccomp: Filter flag to log all actions except SECCOMP_RET_ALLOW
+    - seccomp: Action to log before allowing
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 28 Aug 2017 08:12:24 -0500
+
+linux (4.13.0-6.7) artful; urgency=low
+
+  * HID: multitouch: Support ALPS PTP Stick and Touchpad devices (LP: #1712481)
+    - SAUCE: HID: multitouch: Support ALPS PTP stick with pid 0x120A
+
+  * sort ABI files with C.UTF-8 locale (LP: #1712345)
+    - [Packaging] sort ABI files with C.UTF-8 locale
+
+  * igb: Support using Broadcom 54616 as PHY (LP: #1712024)
+    - SAUCE: igb: add support for using Broadcom 54616 as PHY
+
+  * RPT related fixes missing in Ubuntu 16.04.3 (LP: #1709220)
+    - powerpc/mm/radix: Improve _tlbiel_pid to be usable for PWC flushes
+    - powerpc/mm/radix: Improve TLB/PWC flushes
+    - powerpc/mm/radix: Avoid flushing the PWC on every flush_tlb_range
+
+  * Linux 4.12 refuses to load self-signed modules under Secure Boot with
+    properly enrolled keys (LP: #1712168)
+    - SAUCE: (efi-lockdown) MODSIGN: Fix module signature verification
+
+  * [17.10 FEAT] Enable NVMe driver - kernel (LP: #1708432)
+    - [Config] CONFIG_BLK_DEV_NVME=m for s390
+
+  * Artful: 4.12.0-11.12: Boot panic in vlv2_plat_configure_clock+0x3b/0xa0
+    (LP: #1711298)
+    - [Config] CONFIG_INTEL_ATOMISP=n
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor: af_unix mediation
+
+  * Miscellaneous upstream changes
+    - apparmor: Fix shadowed local variable in unpack_trans_table()
+    - apparmor: Fix logical error in verify_header()
+    - apparmor: Fix an error code in aafs_create()
+    - apparmor: Redundant condition: prev_ns. in [label.c:1498]
+    - apparmor: add the ability to mediate signals
+    - apparmor: add mount mediation
+    - apparmor: cleanup conditional check for label in label_print
+    - apparmor: add support for absolute root view based labels
+    - apparmor: make policy_unpack able to audit different info messages
+    - apparmor: add more debug asserts to apparmorfs
+    - apparmor: add base infastructure for socket mediation
+    - apparmor: move new_null_profile to after profile lookup fns()
+    - apparmor: fix race condition in null profile creation
+    - apparmor: ensure unconfined profiles have dfas initialized
+    - apparmor: fix incorrect type assignment when freeing proxies
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 23 Aug 2017 08:10:38 -0500
+
+linux (4.13.0-5.6) artful; urgency=low
+
+  * Ubuntu17.10 - perf: Update Power9 PMU event JSON files (LP: #1708630)
+    - perf pmu-events: Support additional POWER8+ PVR in mapfile
+    - perf vendor events: Add POWER9 PMU events
+    - perf vendor events: Add POWER9 PVRs to mapfile
+    - SAUCE: perf vendor events powerpc: remove suffix in mapfile
+    - SAUCE: perf vendor events powerpc: Update POWER9 events
+
+  * Disable CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE (LP: #1709171)
+    - [Config] CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=n for ppc64el
+
+  * Please only recommend or suggest initramfs-tools | linux-initramfs-tool for
+    kernels able to boot without initramfs (LP: #1700972)
+    - [Debian] Don't depend on initramfs-tools
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Import aufs driver
+    - SAUCE: aufs -- Add missing argument to loop_switch() call
+    - [Config] Enable aufs
+    - SAUCE: (noup) Update spl to 0.6.5.11-ubuntu1, zfs to 0.6.5.11-1ubuntu3
+    - Enable zfs build
+    - SAUCE: powerpc: Always initialize input array when calling epapr_hypercall()
+    - [Packaging] switch up to debhelper 9
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 15 Aug 2017 09:24:16 -0500
+
+linux (4.13.0-4.5) artful; urgency=low
+
+  * Lenovo Yoga 910 Sensors (LP: #1708120)
+    - SAUCE: (no-up) HID: Add quirk for Lenovo Yoga 910 with ITE Chips
+
+  * Unable to install Ubuntu on the NVMe disk under VMD PCI domain
+    (LP: #1703339)
+    - [Config] Add vmd driver to generic inclusion list
+
+  * Set CONFIG_SATA_HIGHBANK=y on armhf (LP: #1703430)
+    - [Config] CONFIG_SATA_HIGHBANK=y
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu: vbox -- update to 5.1.26-dfsg-1
+    - SAUCE: hio: Build fixes for 4.13
+    - Enable hio build
+    - SAUCE: (noup) Update spl to 0.6.5.11-1, zfs to 0.6.5.11-1ubuntu1
+    - [debian] use all rather than amd64 dkms debs for sync
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 08 Aug 2017 11:31:48 -0500
+
+linux (4.13.0-3.4) artful; urgency=low
+
+  * Adt tests of src:linux time out often on armhf lxc containers (LP: #1705495)
+    - [Packaging] tests -- reduce rebuild test to one flavour
+    - [Packaging] tests -- reduce rebuild test to one flavour -- use filter
+
+  * snapd 2.26.8+17.10 ADT test failure with linux 4.12.0-6.7 (LP: #1704158)
+    - SAUCE: virtio_net: Revert mergeable buffer handling rework
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 31 Jul 2017 10:08:16 -0500
+
+linux (4.13.0-2.3) artful; urgency=low
+
+  * Change CONFIG_IBMVETH to module (LP: #1704479)
+    - [Config] CONFIG_IBMVETH=m
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 24 Jul 2017 13:58:08 -0500
+
+linux (4.13.0-1.2) artful; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Support sphinx-based kernel documentation
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 20 Jul 2017 09:18:33 -0500
+
+linux (4.13.0-0.1) artful; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - Disable hio
+    - Disable zfs build
+    - ubuntu: vbox -- update to 5.1.24-dfsg-1
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 19 Jul 2017 15:09:31 -0500
+
+linux (4.12.0-7.8) artful; urgency=low
+
+  * ThunderX: soft lockup on 4.8+ kernels when running qemu-efi with vhost=on
+    (LP: #1673564)
+    - arm64: Add a facility to turn an ESR syndrome into a sysreg encoding
+    - KVM: arm/arm64: vgic-v3: Add accessors for the ICH_APxRn_EL2 registers
+    - KVM: arm64: Make kvm_condition_valid32() accessible from EL2
+    - KVM: arm64: vgic-v3: Add hook to handle guest GICv3 sysreg accesses at EL2
+    - KVM: arm64: vgic-v3: Add ICV_BPR1_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_IGRPEN1_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_IAR1_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_EOIR1_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_AP1Rn_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_HPPIR1_EL1 handler
+    - KVM: arm64: vgic-v3: Enable trapping of Group-1 system registers
+    - KVM: arm64: Enable GICv3 Group-1 sysreg trapping via command-line
+    - KVM: arm64: vgic-v3: Add ICV_BPR0_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_IGNREN0_EL1 handler
+    - KVM: arm64: vgic-v3: Add misc Group-0 handlers
+    - KVM: arm64: vgic-v3: Enable trapping of Group-0 system registers
+    - KVM: arm64: Enable GICv3 Group-0 sysreg trapping via command-line
+    - arm64: Add MIDR values for Cavium cn83XX SoCs
+    - arm64: Add workaround for Cavium Thunder erratum 30115
+    - KVM: arm64: vgic-v3: Add ICV_DIR_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_RPR_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_CTLR_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_PMR_EL1 handler
+    - KVM: arm64: Enable GICv3 common sysreg trapping via command-line
+    - KVM: arm64: vgic-v3: Log which GICv3 system registers are trapped
+    - KVM: arm64: Log an error if trapping a read-from-write-only GICv3 access
+    - KVM: arm64: Log an error if trapping a write-to-read-only GICv3 access
+
+  * hns: under heavy load, NIC may fail and require reboot (LP: #1704146)
+    - net: hns: Bugfix for Tx timeout handling in hns driver
+
+  * New ACPI identifiers for ThunderX SMMU (LP: #1703437)
+    - iommu/arm-smmu: Plumb in new ACPI identifiers
+
+  * Transparent hugepages should default to enabled=madvise (LP: #1703742)
+    - SAUCE: use CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y as default
+
+  * Artful update to v4.12.1 stable release (LP: #1703858)
+    - driver core: platform: fix race condition with driver_override
+    - RDMA/uverbs: Check port number supplied by user verbs cmds
+    - usb: dwc3: replace %p with %pK
+    - USB: serial: cp210x: add ID for CEL EM3588 USB ZigBee stick
+    - usb: usbip: set buffer pointers to NULL after free
+    - Add USB quirk for HVR-950q to avoid intermittent device resets
+    - usb: Fix typo in the definition of Endpoint[out]Request
+    - USB: core: fix device node leak
+    - USB: serial: option: add two Longcheer device ids
+    - USB: serial: qcserial: new Sierra Wireless EM7305 device ID
+    - xhci: Limit USB2 port wake support for AMD Promontory hosts
+    - gfs2: Fix glock rhashtable rcu bug
+    - Add "shutdown" to "struct class".
+    - tpm: Issue a TPM2_Shutdown for TPM2 devices.
+    - tpm: fix a kernel memory leak in tpm-sysfs.c
+    - powerpc/powernv: Fix CPU_HOTPLUG=n idle.c compile error
+    - x86/uaccess: Optimize copy_user_enhanced_fast_string() for short strings
+    - sched/fair, cpumask: Export for_each_cpu_wrap()
+    - sched/core: Implement new approach to scale select_idle_cpu()
+    - sched/numa: Use down_read_trylock() for the mmap_sem
+    - sched/numa: Override part of migrate_degrades_locality() when idle balancing
+    - sched/fair: Simplify wake_affine() for the single socket case
+    - sched/numa: Implement NUMA node level wake_affine()
+    - sched/fair: Remove effective_load()
+    - sched/numa: Hide numa_wake_affine() from UP build
+    - xen: avoid deadlock in xenbus driver
+    - crypto: drbg - Fixes panic in wait_for_completion call
+    - Linux 4.12.1
+
+  * cxlflash update request in the Xenial SRU stream (LP: #1702521)
+    - scsi: cxlflash: Combine the send queue locks
+    - scsi: cxlflash: Update cxlflash_afu_sync() to return errno
+    - scsi: cxlflash: Reset hardware queue context via specified register
+    - scsi: cxlflash: Schedule asynchronous reset of the host
+    - scsi: cxlflash: Handle AFU sync failures
+    - scsi: cxlflash: Track pending scsi commands in each hardware queue
+    - scsi: cxlflash: Flush pending commands in cleanup path
+    - scsi: cxlflash: Add scsi command abort handler
+    - scsi: cxlflash: Create character device to provide host management interface
+    - scsi: cxlflash: Separate AFU internal command handling from AFU sync
+      specifics
+    - scsi: cxlflash: Introduce host ioctl support
+    - scsi: cxlflash: Refactor AFU capability checking
+    - scsi: cxlflash: Support LUN provisioning
+    - scsi: cxlflash: Support AFU debug
+    - scsi: cxlflash: Support WS16 unmap
+    - scsi: cxlflash: Remove zeroing of private command data
+    - scsi: cxlflash: Update TMF command processing
+    - scsi: cxlflash: Avoid double free of character device
+    - scsi: cxlflash: Update send_tmf() parameters
+    - scsi: cxlflash: Update debug prints in reset handlers
+
+  * make snap-pkg support (LP: #1700747)
+    - make snap-pkg support
+
+  * Quirk for non-compliant PCI bridge on HiSilicon D05 board (LP: #1698706)
+    - SAUCE: PCI: Support hibmc VGA cards behind a misbehaving HiSilicon bridge
+
+  * arm64: fix crash reading /proc/kcore (LP: #1702749)
+    - fs/proc: kcore: use kcore_list type to check for vmalloc/module address
+    - arm64: mm: select CONFIG_ARCH_PROC_KCORE_TEXT
+
+  * Opal and POWER9 DD2 (LP: #1702159)
+    - SAUCE: powerpc/powernv: Tell OPAL about our MMU mode on POWER9
+
+  * Data corruption with hio driver  (LP: #1701316)
+    - SAUCE: hio: Fix incorrect use of enum req_opf values
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.6.5.10-1, zfs to 0.6.5.10-1ubuntu2
+    - snapcraft.yaml: Sync with xenial
+    - [Config] CONFIG_CAVIUM_ERRATUM_30115=y
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and
+      MokSBState"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 14 Jul 2017 15:25:41 -0500
+
+linux (4.12.0-6.7) artful; urgency=low
+
+  * update ENA driver to 1.2.0k from net-next (LP: #1701575)
+    - net: ena: change return value for unsupported features unsupported return
+      value
+    - net: ena: add hardware hints capability to the driver
+    - net: ena: change sizeof() argument to be the type pointer
+    - net: ena: add reset reason for each device FLR
+    - net: ena: add support for out of order rx buffers refill
+    - net: ena: allow the driver to work with small number of msix vectors
+    - net: ena: use napi_schedule_irqoff when possible
+    - net: ena: separate skb allocation to dedicated function
+    - net: ena: use lower_32_bits()/upper_32_bits() to split dma address
+    - net: ena: update driver's rx drop statistics
+    - net: ena: update ena driver to version 1.2.0
+
+  * APST gets enabled against explicit kernel option (LP: #1699004)
+    - nvme: explicitly disable APST on quirked devices
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: hio: Update to Huawei ES3000_V2 (2.1.0.40)
+    - SAUCE: hio updates for 4.12
+    - SAUCE: Enable hio build
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 05 Jul 2017 14:23:20 -0500
+
+linux (4.12.0-5.6) artful; urgency=low
+
+  * ERAT invalidate on context switch removal (LP: #1700819)
+    - powerpc: Only do ERAT invalidate on radix context switch on P9 DD1
+
+  * powerpc: Invalidate ERAT on powersave wakeup for POWER9 (LP: #1700521)
+    - SAUCE: powerpc: Invalidate ERAT on powersave wakeup for POWER9
+
+  * Miscellaneous Ubuntu changes
+    - d-i: Move qcom-emac from arm64 to shared nic-modules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 03 Jul 2017 07:52:02 -0500
+
+linux (4.12.0-4.5) artful; urgency=low
+
+  * aacraid driver may return uninitialized stack data to userspace
+    (LP: #1700077)
+    - SAUCE: scsi: aacraid: Don't copy uninitialized stack memory to userspace
+
+  * KILLER1435-S[0489:e0a2] BT cannot search BT 4.0 device (LP: #1699651)
+    - Bluetooth: btusb: Add support for 0489:e0a2 QCA_ROME device
+
+  * AACRAID for power9 platform (LP: #1689980)
+    - scsi: aacraid: Remove __GFP_DMA for raw srb memory
+    - scsi: aacraid: Fix DMAR issues with iommu=pt
+    - scsi: aacraid: Added 32 and 64 queue depth for arc natives
+    - scsi: aacraid: Set correct Queue Depth for HBA1000 RAW disks
+    - scsi: aacraid: Remove reset support from check_health
+    - scsi: aacraid: Change wait time for fib completion
+    - scsi: aacraid: Log count info of scsi cmds before reset
+    - scsi: aacraid: Print ctrl status before eh reset
+    - scsi: aacraid: Using single reset mask for IOP reset
+    - scsi: aacraid: Rework IOP reset
+    - scsi: aacraid: Add periodic checks to see IOP reset status
+    - scsi: aacraid: Rework SOFT reset code
+    - scsi: aacraid: Rework aac_src_restart
+    - scsi: aacraid: Use correct function to get ctrl health
+    - scsi: aacraid: Make sure ioctl returns on controller reset
+    - scsi: aacraid: Enable ctrl reset for both hba and arc
+    - scsi: aacraid: Add reset debugging statements
+    - scsi: aacraid: Remove reference to Series-9
+    - scsi: aacraid: Update driver version to 50834
+
+  * hibmc driver does not include "pci:" prefix in bus ID (LP: #1698700)
+    - SAUCE: drm: hibmc: Use set_busid function from drm core
+
+  * HiSilicon D05: installer doesn't appear on VGA (LP: #1698954)
+    - d-i: Add hibmc-drm to kernel-image udeb
+
+  * Fix /proc/cpuinfo revision for POWER9 DD2 (LP: #1698844)
+    - SAUCE: powerpc: Fix /proc/cpuinfo revision for POWER9 DD2
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_SATA_MV=n and CONFIG_GENERIC_PHY=n for s390x
+    - [Config] CONFIG_ATA=n for s390x
+    - [Config] Update annotations for 4.12
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 26 Jun 2017 11:27:29 -0500
+
+linux (4.12.0-3.4) artful; urgency=low
+
+  * Miscellaneous upstream changes
+    - ufs: fix the logics for tail relocation
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 19 Jun 2017 14:50:39 -0500
+
+linux (4.12.0-2.3) artful; urgency=low
+
+  * CVE-2014-9900
+    - SAUCE: (no-up) net: Zeroing the structure ethtool_wolinfo in
+      ethtool_get_wol()
+
+  * System doesn't boot properly on Gigabyte AM4 motherboards (AMD Ryzen)
+    (LP: #1671360)
+    - pinctrl/amd: Use regular interrupt instead of chained
+
+  * extend-diff-ignore should use exact matches (LP: #1693504)
+    - [Packaging] exact extend-diff-ignore matches
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: efi: Don't print secure boot state from the efi stub
+    - ubuntu: vbox -- Update to 5.1.22-dfsg-1
+    - SAUCE: vbox fixes for 4.12
+    - Re-enable virtualbox build
+    - [Config] CONFIG_ORANGEFS_FS=m
+    - SAUCE: (noup) Update spl to 0.6.5.9-1ubuntu2, zfs to 0.6.5.9-5ubuntu7
+    - Enable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc4
+  * Rebase to v4.12-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 11 Jun 2017 22:25:13 -0500
+
+linux (4.12.0-1.2) artful; urgency=low
+
+  * Enable Matrox driver for Ubuntu 16.04.3 (LP: #1693337)
+    - [Config] Enable CONFIG_DRM_MGAG200 as module
+
+  * Support low-pin-count devices on Hisilicon SoCs (LP: #1677319)
+    - [Config] CONFIG_LIBIO=y on arm64 only
+    - SAUCE: LIBIO: Introduce a generic PIO mapping method
+    - SAUCE: OF: Add missing I/O range exception for indirect-IO devices
+    - [Config] CONFIG_HISILICON_LPC=y
+    - SAUCE: LPC: Support the device-tree LPC host on Hip06/Hip07
+    - SAUCE: LIBIO: Support the dynamically logical PIO registration of ACPI host
+      I/O
+    - SAUCE: LPC: Add the ACPI LPC support
+    - SAUCE: PCI: Apply the new generic I/O management on PCI IO hosts
+    - SAUCE: PCI: Restore codepath for !CONFIG_LIBIO
+
+  * POWER9: Additional patches for TTY and CPU_IDLE (LP: #1674325)
+    - SAUCE: tty: Fix ldisc crash on reopened tty
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Add build-dep on libnuma-dev to enable 'perf bench numa'
+    - Rebase to v4.12-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 29 May 2017 20:56:29 -0500
+
+linux (4.12.0-0.1) artful; urgency=low
+
+  * please enable CONFIG_ARM64_LSE_ATOMICS (LP: #1691614)
+    - [Config] CONFIG_ARM64_LSE_ATOMICS=y
+
+  * [Regression] NUMA_BALANCING disabled on arm64 (LP: #1690914)
+    - [Config] CONFIG_NUMA_BALANCING{,_DEFAULT_ENABLED}=y on arm64
+
+  * exec'ing a setuid binary from a threaded program sometimes fails to setuid
+    (LP: #1672819)
+    - SAUCE: exec: ensure file system accounting in check_unsafe_exec is correct
+
+  * Miscellaneous Ubuntu changes
+    - Update find-missing-sauce.sh to compare to artful
+    - Update dropped.txt
+    - SAUCE: (efi-lockdown) efi: Add EFI_SECURE_BOOT bit
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/mem and /dev/kmem when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Add a sysrq option to exit secure boot mode
+    - SAUCE: (efi-lockdown) kexec: Disable at runtime if the kernel is locked down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) kexec_file: Disable at runtime if securelevel has been
+      set
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) asus-wmi: Restrict debugfs interface when the kernel
+      is locked down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Enable cold boot attack mitigation
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) scsi: Lock down the eata driver
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) efi: Add EFI signature data types
+    - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) efi: Add secure_boot state and status bit for
+      MokSBState
+    - SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and MokSBState
+    - [Config] Set values for UEFI secure boot lockdown options
+    - Disable virtualbox build
+    - Disable hio build
+    - SAUCE: securityfs: Replace CURRENT_TIME with current_time()
+    - Disable zfs build
+    - [Debian] Work out upstream tag for use with gen-auto-reconstruct
+    - SAUCE: Import aufs driver
+    - SAUCE: aufs -- Include linux/mm.h in fs/aufs/file.h
+    - [Config] Enable aufs
+    - SAUCE: perf callchain: Include errno.h on x86 unconditinally
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 21 May 2017 23:44:44 -0500
+
+linux (4.11.0-3.8) artful; urgency=low
+
+  [ Seth Forshee ]
+
+  * Release Tracking Bug
+    - LP: #1690999
+
+  * apparmor_parser hangs indefinitely when called by multiple threads
+    (LP: #1645037)
+    - SAUCE: apparmor: fix lock ordering for mkdir
+
+  * apparmor leaking securityfs pin count (LP: #1660846)
+    - SAUCE: apparmor: fix leak on securityfs pin count
+
+  * apparmor reference count leak when securityfs_setup_d_inode\ () fails
+    (LP: #1660845)
+    - SAUCE: apparmor: fix reference count leak when securityfs_setup_d_inode()
+      fails
+
+  * apparmor not checking error if security_pin_fs() fails (LP: #1660842)
+    - SAUCE: apparmor: fix not handling error case when securityfs_pin_fs() fails
+
+  * libvirt profile is blocking global setrlimit despite having no rlimit rule
+    (LP: #1679704)
+    - SAUCE: apparmor: fix complain mode failure for rlimit mediation
+    - apparmor: update auditing of rlimit check to provide capability information
+
+  * apparmor: does not provide a way to detect policy updataes (LP: #1678032)
+    - SAUCE: apparmor: add policy revision file interface
+
+  * apparmor does not make support of query data visible (LP: #1678023)
+    - SAUCE: apparmor: add label data availability to the feature set
+
+  * apparmor query interface does not make supported query info available
+    (LP: #1678030)
+    - SAUCE: apparmor: add information about the query inteface to the feature set
+
+  * change_profile incorrect when using namespaces with a compound stack
+    (LP: #1677959)
+    - SAUCE: apparmor: fix label parse for stacked labels
+
+  * Regression in 4.4.0-65-generic causes very frequent system crashes
+    (LP: #1669611)
+    - apparmor: sync of apparmor 3.6+ (17.04)
+
+  * Artful update to 4.11.1 stable release (LP: #1690814)
+    - dm ioctl: prevent stack leak in dm ioctl call
+    - drm/sti: fix GDP size to support up to UHD resolution
+    - power: supply: lp8788: prevent out of bounds array access
+    - brcmfmac: Ensure pointer correctly set if skb data location changes
+    - brcmfmac: Make skb header writable before use
+    - sparc64: fix fault handling in NGbzero.S and GENbzero.S
+    - refcount: change EXPORT_SYMBOL markings
+    - net: macb: fix phy interrupt parsing
+    - tcp: fix access to sk->sk_state in tcp_poll()
+    - geneve: fix incorrect setting of UDP checksum flag
+    - bpf: enhance verifier to understand stack pointer arithmetic
+    - bpf, arm64: fix jit branch offset related to ldimm64
+    - tcp: fix wraparound issue in tcp_lp
+    - net: ipv6: Do not duplicate DAD on link up
+    - net: usb: qmi_wwan: add Telit ME910 support
+    - tcp: do not inherit fastopen_req from parent
+    - ipv4, ipv6: ensure raw socket message is big enough to hold an IP header
+    - rtnetlink: NUL-terminate IFLA_PHYS_PORT_NAME string
+    - ipv6: initialize route null entry in addrconf_init()
+    - ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf
+    - tcp: randomize timestamps on syncookies
+    - bnxt_en: allocate enough space for ->ntp_fltr_bmap
+    - bpf: don't let ldimm64 leak map addresses on unprivileged
+    - net: mdio-mux: bcm-iproc: call mdiobus_free() in error path
+    - f2fs: sanity check segment count
+    - xen/arm,arm64: fix xen_dma_ops after 815dd18 "Consolidate get_dma_ops..."
+    - xen: Revert commits da72ff5bfcb0 and 72a9b186292d
+    - block: get rid of blk_integrity_revalidate()
+    - Linux 4.11.1
+
+  * Module signing exclusion for staging drivers does not work properly
+    (LP: #1690908)
+    - SAUCE: Fix module signing exclusion in package builds
+
+  * perf: qcom: Add L3 cache PMU driver (LP: #1689856)
+    - [Config] CONFIG_QCOM_L3_PMU=y
+    - perf: qcom: Add L3 cache PMU driver
+
+  * No PMU support for ACPI-based arm64 systems (LP: #1689661)
+    - drivers/perf: arm_pmu: rework per-cpu allocation
+    - drivers/perf: arm_pmu: manage interrupts per-cpu
+    - drivers/perf: arm_pmu: split irq request from enable
+    - drivers/perf: arm_pmu: remove pointless PMU disabling
+    - drivers/perf: arm_pmu: define armpmu_init_fn
+    - drivers/perf: arm_pmu: fold init into alloc
+    - drivers/perf: arm_pmu: factor out pmu registration
+    - drivers/perf: arm_pmu: simplify cpu_pmu_request_irqs()
+    - drivers/perf: arm_pmu: handle no platform_device
+    - drivers/perf: arm_pmu: rename irq request/free functions
+    - drivers/perf: arm_pmu: split cpu-local irq request/free
+    - drivers/perf: arm_pmu: move irq request/free into probe
+    - drivers/perf: arm_pmu: split out platform device probe logic
+    - arm64: add function to get a cpu's MADT GICC table
+    - [Config] CONFIG_ARM_PMU_ACPI=y
+    - drivers/perf: arm_pmu: add ACPI framework
+    - arm64: pmuv3: handle !PMUv3 when probing
+    - arm64: pmuv3: use arm_pmu ACPI framework
+
+  * Fix NVLINK2 TCE route (LP: #1690155)
+    - powerpc/powernv: Fix TCE kill on NVLink2
+
+  * CVE-2017-0605
+    - tracing: Use strlcpy() instead of strcpy() in __trace_find_cmdline()
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Restore powerpc arch to annotations file
+    - [Config] Disable runtime testing modules
+    - [Config] Disable drivers not needed on s390x
+    - [Config] Update annotations for 4.11
+    - [Config] updateconfigs after apparmor updates
+
+  * Miscellaneous upstream changes
+    - apparmor: use SHASH_DESC_ON_STACK
+    - apparmor: fix invalid reference to index variable of iterator line 836
+    - apparmor: fix parameters so that the permission test is bypassed at boot
+    - apparmor: Make path_max parameter readonly
+    - apparmorfs: Combine two function calls into one in aa_fs_seq_raw_abi_show()
+    - apparmorfs: Use seq_putc() in two functions
+    - apparmor: provide information about path buffer size at boot
+    - apparmor: add/use fns to print hash string hex value
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 16 May 2017 00:39:13 -0500
+
+linux (4.11.0-2.7) artful; urgency=low
+
+  * kernel-wedge fails in artful due to leftover squashfs-modules d-i files
+    (LP: #1688259)
+    - Remove squashfs-modules files from d-i
+    - [Config] as squashfs-modules is builtin kernel-image must Provides: it
+
+  * [Zesty] d-i: replace msm_emac with qcom_emac (LP: #1677297)
+    - Revert "UBUNTU: d-i: initrd needs msm_emac on amberwing platform."
+    - d-i: initrd needs qcom_emac on amberwing platform.
+
+  * update for V3 kernel bits and improved multiple fan slice support
+    (LP: #1470091)
+    - SAUCE: fan: tunnel multiple mapping mode (v3)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.6.5.9-1ubuntu1, zfs to 0.6.5.9-5ubuntu5
+    - Enable zfs
+    - SAUCE: fan: add VXLAN implementation
+    - SAUCE: (efi-lockdown) efi: Add EFI_SECURE_BOOT bit
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/mem and /dev/kmem when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Add a sysrq option to exit secure boot mode
+    - SAUCE: (efi-lockdown) kexec: Disable at runtime if the kernel is locked down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) kexec_file: Disable at runtime if securelevel has been
+      set
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) asus-wmi: Restrict debugfs interface when the kernel
+      is locked down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Enable cold boot attack mitigation
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) scsi: Lock down the eata driver
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Add EFI signature data types
+    - SAUCE: (efi-lockdown) Add an EFI signature blob parser and key loader.
+    - SAUCE: (efi-lockdown) KEYS: Add a system blacklist keyring
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Support not importing certs from db
+    - SAUCE: (efi-lockdown) MODSIGN: Don't try secure boot if EFI runtime is
+      disabled
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) efi: Add secure_boot state and status bit for
+      MokSBState
+    - SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and MokSBState
+    - [Config] Set values for UEFI secure boot lockdown options
+    - Update dropped.txt
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 05 May 2017 07:43:14 -0500
+
+linux (4.11.0-1.6) artful; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Use default compression for all packages
+    - SAUCE: (namespace) block_dev: Support checking inode permissions in
+      lookup_bdev()
+    - SAUCE: (namespace) block_dev: Check permissions towards block device inode
+      when mounting
+    - SAUCE: (namespace) mtd: Check permissions towards mtd block device inode
+      when mounting
+    - SAUCE: (namespace) fs: Allow superblock owner to change ownership of inodes
+    - SAUCE: (namespace) fs: Don't remove suid for CAP_FSETID for userns root
+    - SAUCE: (namespace) fs: Allow superblock owner to access do_remount_sb()
+    - SAUCE: (namespace) capabilities: Allow privileged user in s_user_ns to set
+      security.* xattrs
+    - SAUCE: (namespace) fs: Allow CAP_SYS_ADMIN in s_user_ns to freeze and thaw
+      filesystems
+    - SAUCE: (namespace) fuse: Add support for pid namespaces
+    - SAUCE: (namespace) fuse: Support fuse filesystems outside of init_user_ns
+    - SAUCE: (namespace) fuse: Restrict allow_other to the superblock's namespace
+      or a descendant
+    - SAUCE: (namespace) fuse: Allow user namespace mounts
+    - SAUCE: (namespace) ext4: Add support for unprivileged mounts from user
+      namespaces
+    - SAUCE: (namespace) evm: Don't update hmacs in user ns mounts
+    - SAUCE: (namespace) ext4: Add module parameter to enable user namespace
+      mounts
+    - SAUCE: (namespace) block_dev: Forbid unprivileged mounting when device is
+      opened for writing
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 26 Apr 2017 10:08:29 -0500
+
+linux (4.11.0-0.5) artful; urgency=low
+
+  * [Hyper-V][SAUCE] pci-hyperv: Use only 16 bit integer for PCI domain
+    (LP: #1684971)
+    - SAUCE: pci-hyperv: Use only 16 bit integer for PCI domain
+
+  * [Hyper-V] Ubuntu 14.04.2 LTS Generation 2 SCSI Errors on VSS Based Backups
+    (LP: #1470250)
+    - SAUCE: Tools: hv: vss: Thaw the filesystem and continue after freeze fails
+
+  * Enable virtual scsi server driver for Power (LP: #1615665)
+    - SAUCE: Return TCMU-generated sense data to fabric module
+
+  * include/linux/security.h header syntax error with !CONFIG_SECURITYFS
+    (LP: #1630990)
+    - SAUCE: (no-up) include/linux/security.h -- fix syntax error with
+      CONFIG_SECURITYFS=n
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Import aufs driver
+    - [Config] Enable aufs
+    - [Debian] Add script to update virtualbox
+    - ubuntu: vbox -- Update to 5.1.20-dfsg-2
+    - Enable vbox
+    - SAUCE: aufs -- Include linux/mm.h in fs/aufs/file.h
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 25 Apr 2017 13:42:54 -0500
+
+linux (4.11.0-0.4) zesty; urgency=low
+
+  * POWER9: Improve performance on memory management (LP: #1681429)
+    - SAUCE: powerpc/mm/radix: Don't do page walk cache flush when doing full mm
+      flush
+    - SAUCE: powerpc/mm/radix: Remove unnecessary ptesync
+
+  * Miscellaneous Ubuntu changes
+    - find-missing-sauce.sh
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 18 Apr 2017 08:19:43 -0500
+
+linux (4.11.0-0.3) zesty; urgency=low
+
+  * Disable CONFIG_HVC_UDBG on ppc64el (LP: #1680888)
+    - [Config] Disable CONFIG_HVC_UDBG on ppc64el
+
+  * smartpqi driver needed in initram disk and installer (LP: #1680156)
+    - [Config] Add smartpqi to d-i
+
+  * Disable CONFIG_SECURITY_SELINUX_DISABLE (LP: #1680315)
+    - [Config] CONFIG_SECURITY_SELINUX_DISABLE=n
+
+  * Miscellaneous Ubuntu changes
+    - [Config] flash-kernel should be a Breaks
+    - [Config] drop the info directory
+    - [Config] drop NOTES as obsolete
+    - [Config] drop changelog.historical as obsolete
+    - rebase to v4.11-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc6
+
+ -- Tim Gardner <tim.gardner@canonical.com>  Tue, 11 Apr 2017 07:16:52 -0600
+
+linux (4.11.0-0.2) zesty; urgency=low
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc5
+
+ -- Tim Gardner <tim.gardner@canonical.com>  Mon, 03 Apr 2017 08:26:07 +0100
+
+linux (4.11.0-0.1) zesty; urgency=low
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc4
+    - LP: #1591053
+
+ -- Tim Gardner <tim.gardner@canonical.com>  Mon, 20 Mar 2017 05:15:32 -0600
+
+linux (4.11.0-0.0) zesty; urgency=low
+
+  * dummy entry
+
+ -- Tim Gardner <tim.gardner@canonical.com>  Mon, 20 Mar 2017 05:15:32 -0600
--- linux-qcom-6.8.0.orig/debian.qcom/config/README.rst
+++ linux-qcom-6.8.0/debian.qcom/config/README.rst
@@ -0,0 +1,185 @@
+==================
+Config Annotations
+==================
+
+:Author: Andrea Righi
+
+Overview
+========
+
+Each Ubuntu kernel needs to maintain its own .config for each supported
+architecture and each flavour.
+
+Every time a new patch is applied or a kernel is rebased on top of a new
+one, we need to update the .config's accordingly (config options can be
+added, removed and also renamed).
+
+So, we need to make sure that some critical config options are always
+matching the desired value in order to have a functional kernel.
+
+State of the art
+================
+
+At the moment configs are maintained as a set of Kconfig chunks (inside
+`debian.<kernel>/config/`): a global one, plus per-arch / per-flavour
+chunks.
+
+In addition to that, we need to maintain also a file called
+'annotations'; the purpose of this file is to make sure that some
+critical config options are not silently removed or changed when the
+real .config is re-generated (for example after a rebase or after
+applying a new set of patches).
+
+The main problem with this approach is that, often, we have duplicate
+information that is stored both in the Kconfig chunks *and* in the
+annotations files and, at the same time, the whole .config's information
+is distributed between Kconfig chunks and annotations, making it hard to
+maintain, review and manage in general.
+
+Proposed solution
+=================
+
+The proposed solution is to store all the config information into the
+"annotations" format and get rid of the config chunks (basically the
+real .config's can be produced "compiling" annotations).
+
+Implementation
+==============
+
+To help the management of the annotations an helper script is provided
+(`debian/scripts/misc/annotations`):
+
+```
+usage: annotations [-h] [--version] [--file FILE] [--arch ARCH] [--flavour FLAVOUR] [--config CONFIG]
+                   (--query | --export | --import FILE | --update FILE | --check FILE)
+
+Manage Ubuntu kernel .config and annotations
+
+options:
+  -h, --help            show this help message and exit
+  --version, -v         show program's version number and exit
+  --file FILE, -f FILE  Pass annotations or .config file to be parsed
+  --arch ARCH, -a ARCH  Select architecture
+  --flavour FLAVOUR, -l FLAVOUR
+                        Select flavour (default is "generic")
+  --config CONFIG, -c CONFIG
+                        Select a specific config option
+
+Action:
+  --query, -q           Query annotations
+  --export, -e          Convert annotations to .config format
+  --import FILE, -i FILE
+                        Import a full .config for a specific arch and flavour into annotations
+  --update FILE, -u FILE
+                        Import a partial .config into annotations (only resync configs specified in FILE)
+  --check FILE, -k FILE
+                        Validate kernel .config with annotations
+```
+
+This script allows to query config settings (per arch/flavour/config),
+export them into the Kconfig format (generating the real .config files)
+and check if the final .config matches the rules defined in the
+annotations.
+
+Examples (annotations is defined as an alias to `debian/scripts/annotations`):
+
+ - Show settings for `CONFIG_DEBUG_INFO_BTF` for master kernel across all the
+   supported architectures and flavours:
+
+```
+$ annotations --query --config CONFIG_DEBUG_INFO_BTF
+{
+    "policy": {
+        "amd64": "y",
+        "arm64": "y",
+        "armhf": "n",
+        "ppc64el": "y",
+        "riscv64": "y",
+        "s390x": "y"
+    },
+    "note": "'Needs newer pahole for armhf'"
+}
+```
+
+ - Dump kernel .config for arm64 and flavour generic-64k:
+
+```
+$ annotations --arch arm64 --flavour generic-64k --export
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_COMPAT=y
+...
+```
+
+ - Update annotations file with a new kernel .config for amd64 flavour
+   generic:
+
+```
+$ annotations --arch amd64 --flavour generic --import build/.config
+```
+
+Moreover, an additional kernelconfig commands are provided
+(via debian/rules targets):
+ - `migrateconfigs`: automatically merge all the previous configs into
+   annotations (local changes still need to be committed)
+
+Annotations headers
+===================
+
+The main annotations file should contain a header to define the architectures
+and flavours that are supported.
+
+Here is the format of the header for the generic kernel:
+```
+# Menu: HEADER
+# FORMAT: 4
+# ARCH: amd64 arm64 armhf ppc64el riscv64 s390x
+# FLAVOUR: amd64-generic arm64-generic arm64-generic-64k armhf-generic armhf-generic-lpae ppc64el-generic riscv64-generic s390x-generic
+
+```
+
+Example header of a derivative (linux-aws):
+```
+# Menu: HEADER
+# FORMAT: 4
+# ARCH: amd64 arm64
+# FLAVOUR: amd64-aws arm64-aws
+# FLAVOUR_DEP: {'amd64-aws': 'amd64-generic', 'arm64-aws': 'arm64-generic'}
+
+include "../../debian.master/config/annotations"
+
+# Below you can define only the specific linux-aws configs that differ from linux generic
+
+```
+
+Pros and Cons
+=============
+
+ Pros:
+  - avoid duplicate information in .config's and annotations
+  - allow to easily define groups of config settings (for a specific
+    environment or feature, such as annotations.clouds, annotations.ubuntu,
+    annotations.snapd, etc.)
+  - config options are more accessible, easy to change and review
+  - we can easily document how config options are managed (and external
+    contributors won't be discouraged anymore when they need to to change a
+    config option)
+
+ Cons:
+  - potential regressions: the new tool/scripts can have potential bugs,
+    so we could experience regressions due to some missed config changes
+  - kernel team need to understand the new process (even if everything
+    is transparent, kernel cranking process is the same, there might be
+    corner cases that need to be addressed and resolved manually)
+
+TODO
+====
+
+ - Migrate all flavour and arch definitions into annotations (rather
+   than having this information defined in multiple places inside
+   debian/scripts); right now this information is "partially" migrated,
+   meaning that we need to define arches and flavours in the headers
+   section of annotations (so that the annotations tool can figure out
+   the list of supported arches and flavours), but arches and flavours
+   are still defined elsewhere, ideally we would like to have arches and
+   flavours defined only in one place: annotations.
--- linux-qcom-6.8.0.orig/debian.qcom/config/annotations
+++ linux-qcom-6.8.0/debian.qcom/config/annotations
@@ -0,0 +1,2046 @@
+# Menu: HEADER
+# FORMAT: 4
+# ARCH: arm64
+# FLAVOUR: arm64-qcom
+# FLAVOUR_DEP: {'arm64-qcom': 'arm64-generic'}
+
+include "../../debian.master/config/annotations"
+
+CONFIG_ARCH_MMAP_RND_BITS                       policy<{'arm64': '18'}>
+CONFIG_ARCH_MMAP_RND_BITS                       note<'LP: #1983357'>
+
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS                policy<{'arm64': '11'}>
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS                note<'LP: #1983357'>
+
+CONFIG_ARCH_ROCKCHIP                            policy<{'arm64': 'n'}>
+CONFIG_ARCH_ROCKCHIP                            note<'LP: #1825222'>
+
+CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT       policy<{'arm64': 'y'}>
+CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT       note<'LP: #2102032'>
+
+CONFIG_DRM_AMDGPU_CIK                           policy<{'arm64': '-'}>
+CONFIG_DRM_AMDGPU_CIK                           note<'for zesty'>
+
+CONFIG_EFI_ZBOOT                                policy<{'arm64': 'n'}>
+CONFIG_EFI_ZBOOT                                note<'we use arch/arm64/boot/Image.gz'>
+
+CONFIG_HSA_AMD_P2P                              policy<{'arm64': '-'}>
+CONFIG_HSA_AMD_P2P                              note<'LP: #1987394'>
+
+CONFIG_IPMMU_VMSA                               policy<{'arm64': '-'}>
+CONFIG_IPMMU_VMSA                               note<'LP: #1718734'>
+
+CONFIG_KERNEL_ZSTD                              policy<{'arm64': '-'}>
+CONFIG_KERNEL_ZSTD                              note<'we use arch/arm64/boot/Image.gz'>
+
+CONFIG_MMC_SDHCI                                policy<{'arm64': 'y'}>
+CONFIG_MMC_SDHCI                                note<'installation essential on omap/highbank'>
+
+CONFIG_MMC_SDHCI_PLTFM                          policy<{'arm64': 'y'}>
+CONFIG_MMC_SDHCI_PLTFM                          note<'boot essential on highbank'>
+
+CONFIG_NR_CPUS                                  policy<{'arm64': '256'}>
+CONFIG_NR_CPUS                                  note<'LP: #2042897 (arm64), LP: #1967889 (riscv64), LP: #1864198 (s390x)'>
+
+CONFIG_REGULATOR_FIXED_VOLTAGE                  policy<{'arm64': 'y'}>
+CONFIG_REGULATOR_FIXED_VOLTAGE                  note<'boot essential on arm'>
+
+CONFIG_SERIAL_SH_SCI                            policy<{'arm64': '-'}>
+CONFIG_SERIAL_SH_SCI                            note<'LP: #2022361'>
+
+CONFIG_SERIAL_SH_SCI_CONSOLE                    policy<{'arm64': '-'}>
+CONFIG_SERIAL_SH_SCI_CONSOLE                    note<'LP: #2022361'>
+
+CONFIG_SERIAL_SH_SCI_EARLYCON                   policy<{'arm64': '-'}>
+CONFIG_SERIAL_SH_SCI_EARLYCON                   note<'LP: #2022361'>
+
+CONFIG_SUN6I_RTC_CCU                            policy<{'arm64': '-'}>
+CONFIG_SUN6I_RTC_CCU                            note<'needed by Allwinner D1 pinctrl/gpio'>
+
+CONFIG_SYSFB_SIMPLEFB                           policy<{'arm64': 'n'}>
+CONFIG_SYSFB_SIMPLEFB                           note<'LP: #1965303'>
+
+
+# ---- Annotations without notes ----
+
+CONFIG_AHCI_IMX                                 policy<{'arm64': '-'}>
+CONFIG_AHCI_MTK                                 policy<{'arm64': '-'}>
+CONFIG_AHCI_MVEBU                               policy<{'arm64': '-'}>
+CONFIG_AHCI_QORIQ                               policy<{'arm64': '-'}>
+CONFIG_AHCI_SUNXI                               policy<{'arm64': '-'}>
+CONFIG_AHCI_TEGRA                               policy<{'arm64': '-'}>
+CONFIG_AHCI_XGENE                               policy<{'arm64': '-'}>
+CONFIG_AMLOGIC_THERMAL                          policy<{'arm64': '-'}>
+CONFIG_APPLE_ADMAC                              policy<{'arm64': '-'}>
+CONFIG_APPLE_AIC                                policy<{'arm64': '-'}>
+CONFIG_APPLE_DART                               policy<{'arm64': '-'}>
+CONFIG_APPLE_M1_CPU_PMU                         policy<{'arm64': '-'}>
+CONFIG_APPLE_MAILBOX                            policy<{'arm64': '-'}>
+CONFIG_APPLE_PMGR_PWRSTATE                      policy<{'arm64': '-'}>
+CONFIG_APPLE_RTKIT                              policy<{'arm64': '-'}>
+CONFIG_APPLE_SART                               policy<{'arm64': '-'}>
+CONFIG_APPLE_WATCHDOG                           policy<{'arm64': '-'}>
+CONFIG_ARCH_ACTIONS                             policy<{'arm64': 'n'}>
+CONFIG_ARCH_APPLE                               policy<{'arm64': 'n'}>
+CONFIG_ARCH_BERLIN                              policy<{'arm64': 'n'}>
+CONFIG_ARCH_BITMAIN                             policy<{'arm64': 'n'}>
+CONFIG_ARCH_FORCE_MAX_ORDER                     policy<{'arm64': '10'}>
+CONFIG_ARCH_HAS_RESET_CONTROLLER                policy<{'arm64': '-'}>
+CONFIG_ARCH_HISI                                policy<{'arm64': 'n'}>
+CONFIG_ARCH_INTEL_SOCFPGA                       policy<{'arm64': 'n'}>
+CONFIG_ARCH_K3                                  policy<{'arm64': 'n'}>
+CONFIG_ARCH_KEEMBAY                             policy<{'arm64': 'n'}>
+CONFIG_ARCH_LAYERSCAPE                          policy<{'arm64': '-'}>
+CONFIG_ARCH_LG1K                                policy<{'arm64': 'n'}>
+CONFIG_ARCH_MA35                                policy<{'arm64': 'n'}>
+CONFIG_ARCH_MEDIATEK                            policy<{'arm64': 'n'}>
+CONFIG_ARCH_MESON                               policy<{'arm64': 'n'}>
+CONFIG_ARCH_MVEBU                               policy<{'arm64': 'n'}>
+CONFIG_ARCH_MXC                                 policy<{'arm64': '-'}>
+CONFIG_ARCH_NPCM                                policy<{'arm64': 'n'}>
+CONFIG_ARCH_NXP                                 policy<{'arm64': 'n'}>
+CONFIG_ARCH_PENSANDO                            policy<{'arm64': 'n'}>
+CONFIG_ARCH_R8A774A1                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R8A774B1                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R8A774C0                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R8A774E1                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R8A77951                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R8A77960                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R8A77961                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R8A77965                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R8A77970                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R8A77980                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R8A77990                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R8A77995                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R8A779A0                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R8A779F0                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R8A779G0                            policy<{'arm64': '-'}>
+CONFIG_ARCH_R9A07G043                           policy<{'arm64': '-'}>
+CONFIG_ARCH_R9A07G044                           policy<{'arm64': '-'}>
+CONFIG_ARCH_R9A07G054                           policy<{'arm64': '-'}>
+CONFIG_ARCH_R9A08G045                           policy<{'arm64': '-'}>
+CONFIG_ARCH_R9A09G011                           policy<{'arm64': '-'}>
+CONFIG_ARCH_RCAR_GEN3                           policy<{'arm64': '-'}>
+CONFIG_ARCH_REALTEK                             policy<{'arm64': 'n'}>
+CONFIG_ARCH_RENESAS                             policy<{'arm64': 'n'}>
+CONFIG_ARCH_RZG2L                               policy<{'arm64': '-'}>
+CONFIG_ARCH_S32                                 policy<{'arm64': '-'}>
+CONFIG_ARCH_SEATTLE                             policy<{'arm64': 'n'}>
+CONFIG_ARCH_SPARX5                              policy<{'arm64': 'n'}>
+CONFIG_ARCH_SPRD                                policy<{'arm64': 'n'}>
+CONFIG_ARCH_STM32                               policy<{'arm64': 'n'}>
+CONFIG_ARCH_SUNXI                               policy<{'arm64': 'n'}>
+CONFIG_ARCH_SYNQUACER                           policy<{'arm64': 'n'}>
+CONFIG_ARCH_TEGRA                               policy<{'arm64': 'n'}>
+CONFIG_ARCH_TEGRA_132_SOC                       policy<{'arm64': '-'}>
+CONFIG_ARCH_TEGRA_186_SOC                       policy<{'arm64': '-'}>
+CONFIG_ARCH_TEGRA_194_SOC                       policy<{'arm64': '-'}>
+CONFIG_ARCH_TEGRA_210_SOC                       policy<{'arm64': '-'}>
+CONFIG_ARCH_TEGRA_234_SOC                       policy<{'arm64': '-'}>
+CONFIG_ARCH_THUNDER                             policy<{'arm64': 'n'}>
+CONFIG_ARCH_THUNDER2                            policy<{'arm64': 'n'}>
+CONFIG_ARCH_VEXPRESS                            policy<{'arm64': 'n'}>
+CONFIG_ARCH_VISCONTI                            policy<{'arm64': 'n'}>
+CONFIG_ARCH_XGENE                               policy<{'arm64': 'n'}>
+CONFIG_ARCH_ZYNQMP                              policy<{'arm64': 'n'}>
+CONFIG_ARC_EMAC_CORE                            policy<{'arm64': '-'}>
+CONFIG_ARMADA_37XX_CLK                          policy<{'arm64': '-'}>
+CONFIG_ARMADA_37XX_RWTM_MBOX                    policy<{'arm64': '-'}>
+CONFIG_ARMADA_37XX_WATCHDOG                     policy<{'arm64': '-'}>
+CONFIG_ARMADA_AP806_SYSCON                      policy<{'arm64': '-'}>
+CONFIG_ARMADA_AP_CPU_CLK                        policy<{'arm64': '-'}>
+CONFIG_ARMADA_AP_CP_HELPER                      policy<{'arm64': '-'}>
+CONFIG_ARMADA_CP110_SYSCON                      policy<{'arm64': '-'}>
+CONFIG_ARMADA_THERMAL                           policy<{'arm64': '-'}>
+CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM       policy<{'arm64': '-'}>
+CONFIG_ARM_APPLE_SOC_CPUFREQ                    policy<{'arm64': '-'}>
+CONFIG_ARM_ARMADA_37XX_CPUFREQ                  policy<{'arm64': '-'}>
+CONFIG_ARM_ARMADA_8K_CPUFREQ                    policy<{'arm64': '-'}>
+CONFIG_ARM_GIC_PM                               policy<{'arm64': '-'}>
+CONFIG_ARM_GIC_V3_ITS_FSL_MC                    policy<{'arm64': '-'}>
+CONFIG_ARM_IMX6Q_CPUFREQ                        policy<{'arm64': '-'}>
+CONFIG_ARM_IMX8M_DDRC_DEVFREQ                   policy<{'arm64': '-'}>
+CONFIG_ARM_IMX_BUS_DEVFREQ                      policy<{'arm64': '-'}>
+CONFIG_ARM_IMX_CPUFREQ_DT                       policy<{'arm64': '-'}>
+CONFIG_ARM_MEDIATEK_CCI_DEVFREQ                 policy<{'arm64': '-'}>
+CONFIG_ARM_MEDIATEK_CPUFREQ                     policy<{'arm64': '-'}>
+CONFIG_ARM_MEDIATEK_CPUFREQ_HW                  policy<{'arm64': '-'}>
+CONFIG_ARM_MHU                                  policy<{'arm64': 'y'}>
+CONFIG_ARM_QCOM_CPUFREQ_HW                      policy<{'arm64': 'y'}>
+CONFIG_ARM_RK3399_DMC_DEVFREQ                   policy<{'arm64': '-'}>
+CONFIG_ARM_SBSA_WATCHDOG                        policy<{'arm64': 'y'}>
+CONFIG_ARM_SCMI_CPUFREQ                         policy<{'arm64': 'y'}>
+CONFIG_ARM_SCMI_PERF_DOMAIN                     policy<{'arm64': 'y'}>
+CONFIG_ARM_SCMI_POWER_DOMAIN                    policy<{'arm64': 'y'}>
+CONFIG_ARM_SCPI_POWER_DOMAIN                    policy<{'arm64': 'y'}>
+CONFIG_ARM_SCPI_PROTOCOL                        policy<{'arm64': 'y'}>
+CONFIG_ARM_SMC_WATCHDOG                         policy<{'arm64': 'y'}>
+CONFIG_ARM_SMMU_QCOM_TBU                        policy<{'arm64': 'y'}>
+CONFIG_ARM_SP805_WATCHDOG                       policy<{'arm64': 'y'}>
+CONFIG_ARM_SUN8I_A33_MBUS_DEVFREQ               policy<{'arm64': '-'}>
+CONFIG_ARM_TEGRA124_CPUFREQ                     policy<{'arm64': '-'}>
+CONFIG_ARM_TEGRA186_CPUFREQ                     policy<{'arm64': '-'}>
+CONFIG_ARM_TEGRA194_CPUFREQ                     policy<{'arm64': '-'}>
+CONFIG_ARM_TEGRA20_CPUFREQ                      policy<{'arm64': '-'}>
+CONFIG_ARM_TEGRA_DEVFREQ                        policy<{'arm64': '-'}>
+CONFIG_ARM_TI_CPUFREQ                           policy<{'arm64': '-'}>
+CONFIG_ATH11K_COREDUMP                          policy<{'arm64': 'n'}>
+CONFIG_AX88179B                                 policy<{'arm64': 'y'}>
+CONFIG_AXI_DMAC                                 policy<{'arm64': '-'}>
+CONFIG_BACKLIGHT_QCOM_WLED                      policy<{'arm64': 'y'}>
+CONFIG_BCMDHD                                   policy<{'arm64': 'm'}>
+CONFIG_BCMDHD_FW_PATH                           policy<{'arm64': '"/lib/firmware/fw_bcmdhd.bin"'}>
+CONFIG_BCMDHD_NVRAM_PATH                        policy<{'arm64': '"/lib/firmware/nvram.txt"'}>
+CONFIG_BCMDHD_OOB                               policy<{'arm64': 'y'}>
+CONFIG_BCMDHD_PCIE                              policy<{'arm64': 'n'}>
+CONFIG_BCMDHD_SDIO                              policy<{'arm64': 'y'}>
+CONFIG_BCMDHD_SDIO_IRQ                          policy<{'arm64': 'n'}>
+CONFIG_BCMDHD_USB                               policy<{'arm64': 'n'}>
+CONFIG_BERLIN2_ADC                              policy<{'arm64': '-'}>
+CONFIG_CAN_BXCAN                                policy<{'arm64': '-'}>
+CONFIG_CAN_RCAR                                 policy<{'arm64': '-'}>
+CONFIG_CAN_RCAR_CANFD                           policy<{'arm64': '-'}>
+CONFIG_CAVIUM_CPT                               policy<{'arm64': '-'}>
+CONFIG_CEC_MESON_AO                             policy<{'arm64': '-'}>
+CONFIG_CEC_MESON_G12A_AO                        policy<{'arm64': '-'}>
+CONFIG_CEC_STM32                                policy<{'arm64': '-'}>
+CONFIG_CEC_TEGRA                                policy<{'arm64': '-'}>
+CONFIG_CHARGER_CPCAP                            policy<{'arm64': '-'}>
+CONFIG_CHARGER_SC2731                           policy<{'arm64': '-'}>
+CONFIG_CLKSRC_STM32_LP                          policy<{'arm64': '-'}>
+CONFIG_CLK_ACTIONS                              policy<{'arm64': '-'}>
+CONFIG_CLK_IMX8MM                               policy<{'arm64': '-'}>
+CONFIG_CLK_IMX8MN                               policy<{'arm64': '-'}>
+CONFIG_CLK_IMX8MP                               policy<{'arm64': '-'}>
+CONFIG_CLK_IMX8MQ                               policy<{'arm64': '-'}>
+CONFIG_CLK_IMX8QXP                              policy<{'arm64': '-'}>
+CONFIG_CLK_IMX8ULP                              policy<{'arm64': '-'}>
+CONFIG_CLK_IMX93                                policy<{'arm64': '-'}>
+CONFIG_CLK_INTEL_SOCFPGA                        policy<{'arm64': '-'}>
+CONFIG_CLK_INTEL_SOCFPGA64                      policy<{'arm64': '-'}>
+CONFIG_CLK_LS1028A_PLLDIG                       policy<{'arm64': '-'}>
+CONFIG_CLK_MA35D1                               policy<{'arm64': '-'}>
+CONFIG_CLK_OWL_S500                             policy<{'arm64': '-'}>
+CONFIG_CLK_OWL_S700                             policy<{'arm64': '-'}>
+CONFIG_CLK_OWL_S900                             policy<{'arm64': '-'}>
+CONFIG_CLK_PX30                                 policy<{'arm64': '-'}>
+CONFIG_CLK_QORIQ                                policy<{'arm64': '-'}>
+CONFIG_CLK_R8A774A1                             policy<{'arm64': '-'}>
+CONFIG_CLK_R8A774B1                             policy<{'arm64': '-'}>
+CONFIG_CLK_R8A774C0                             policy<{'arm64': '-'}>
+CONFIG_CLK_R8A774E1                             policy<{'arm64': '-'}>
+CONFIG_CLK_R8A7795                              policy<{'arm64': '-'}>
+CONFIG_CLK_R8A77960                             policy<{'arm64': '-'}>
+CONFIG_CLK_R8A77961                             policy<{'arm64': '-'}>
+CONFIG_CLK_R8A77965                             policy<{'arm64': '-'}>
+CONFIG_CLK_R8A77970                             policy<{'arm64': '-'}>
+CONFIG_CLK_R8A77980                             policy<{'arm64': '-'}>
+CONFIG_CLK_R8A77990                             policy<{'arm64': '-'}>
+CONFIG_CLK_R8A77995                             policy<{'arm64': '-'}>
+CONFIG_CLK_R8A779A0                             policy<{'arm64': '-'}>
+CONFIG_CLK_R8A779F0                             policy<{'arm64': '-'}>
+CONFIG_CLK_R8A779G0                             policy<{'arm64': '-'}>
+CONFIG_CLK_R9A07G043                            policy<{'arm64': '-'}>
+CONFIG_CLK_R9A07G044                            policy<{'arm64': '-'}>
+CONFIG_CLK_R9A07G054                            policy<{'arm64': '-'}>
+CONFIG_CLK_R9A08G045                            policy<{'arm64': '-'}>
+CONFIG_CLK_R9A09G011                            policy<{'arm64': '-'}>
+CONFIG_CLK_RCAR_CPG_LIB                         policy<{'arm64': '-'}>
+CONFIG_CLK_RCAR_GEN3_CPG                        policy<{'arm64': '-'}>
+CONFIG_CLK_RCAR_GEN4_CPG                        policy<{'arm64': '-'}>
+CONFIG_CLK_RCAR_USB2_CLOCK_SEL                  policy<{'arm64': '-'}>
+CONFIG_CLK_RENESAS                              policy<{'arm64': '-'}>
+CONFIG_CLK_RENESAS_CPG_MSSR                     policy<{'arm64': '-'}>
+CONFIG_CLK_RENESAS_DIV6                         policy<{'arm64': '-'}>
+CONFIG_CLK_RK3308                               policy<{'arm64': '-'}>
+CONFIG_CLK_RK3328                               policy<{'arm64': '-'}>
+CONFIG_CLK_RK3368                               policy<{'arm64': '-'}>
+CONFIG_CLK_RK3399                               policy<{'arm64': '-'}>
+CONFIG_CLK_RK3568                               policy<{'arm64': '-'}>
+CONFIG_CLK_RK3588                               policy<{'arm64': '-'}>
+CONFIG_CLK_RZG2L                                policy<{'arm64': '-'}>
+CONFIG_CLK_TEGRA_BPMP                           policy<{'arm64': '-'}>
+CONFIG_CLK_X1E80100_CAMCC                       policy<{'arm64': 'n'}>
+CONFIG_CLK_X1E80100_DISPCC                      policy<{'arm64': 'n'}>
+CONFIG_CLK_X1E80100_GCC                         policy<{'arm64': 'y'}>
+CONFIG_CLK_X1E80100_GPUCC                       policy<{'arm64': 'n'}>
+CONFIG_COMMON_CLK_A1_PERIPHERALS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_A1_PLL                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_APPLE_NCO                     policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_AXG                           policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_AXG_AUDIO                     policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_BM1880                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_CS2000_CP                     policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_FSL_FLEXSPI                   policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_FSL_SAI                       policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_G12A                          policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_GXBB                          policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_HI3516CV300                   policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_HI3519                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_HI3559A                       policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_HI3660                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_HI3670                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_HI3798CV200                   policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_HI6220                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_HI655X                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MEDIATEK                      policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MEDIATEK_FHCTL                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MESON_AO_CLKC                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MESON_CLKC_UTILS              policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MESON_CPU_DYNDIV              policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MESON_DUALDIV                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MESON_EE_CLKC                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MESON_MPLL                    policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MESON_PHASE                   policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MESON_PLL                     policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MESON_REGMAP                  policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MESON_SCLK_DIV                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MESON_VID_PLL_DIV             policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT2712                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT2712_BDPSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT2712_IMGSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT2712_JPGDECSYS              policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT2712_MFGCFG                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT2712_MMSYS                  policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT2712_VDECSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT2712_VENCSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6765                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6765_AUDIOSYS               policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6765_CAMSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6765_GCESYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6765_IMGSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6765_MFGSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6765_MIPI0ASYS              policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6765_MIPI0BSYS              policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6765_MIPI1ASYS              policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6765_MIPI1BSYS              policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6765_MIPI2ASYS              policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6765_MIPI2BSYS              policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6765_MMSYS                  policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6765_VCODECSYS              policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6779                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6779_AUDSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6779_CAMSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6779_IMGSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6779_IPESYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6779_MFGCFG                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6779_MMSYS                  policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6779_VDECSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6779_VENCSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6795                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6795_MFGCFG                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6795_MMSYS                  policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6795_VDECSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6795_VENCSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6797                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6797_IMGSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6797_MMSYS                  policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6797_VDECSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT6797_VENCSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT7622                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT7622_AUDSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT7622_ETHSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT7622_HIFSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT7981                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT7981_ETHSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT7986                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT7986_ETHSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT7988                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8167                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8167_AUDSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8167_IMGSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8167_MFGCFG                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8167_MMSYS                  policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8167_VDECSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8173                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8173_IMGSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8173_MMSYS                  policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8173_VDECSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8173_VENCSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8183                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8183_AUDIOSYS               policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8183_CAMSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8183_IMGSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8183_IPU_ADL                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8183_IPU_CONN               policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8183_IPU_CORE0              policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8183_IPU_CORE1              policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8183_MFGCFG                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8183_MMSYS                  policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8183_VDECSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8183_VENCSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8186                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8186_CAMSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8186_IMGSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8186_IMP_IIC_WRAP           policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8186_IPESYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8186_MCUSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8186_MDPSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8186_MFGCFG                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8186_MMSYS                  policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8186_VDECSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8186_VENCSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8186_WPESYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8188                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8188_ADSP_AUDIO26M          policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8188_CAMSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8188_IMGSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8188_IMP_IIC_WRAP           policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8188_IPESYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8188_MFGCFG                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8188_VDECSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8188_VDOSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8188_VENCSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8188_VPPSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8188_WPESYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8192                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8192_AUDSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8192_CAMSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8192_IMGSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8192_IMP_IIC_WRAP           policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8192_IPESYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8192_MDPSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8192_MFGCFG                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8192_MMSYS                  policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8192_MSDC                   policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8192_SCP_ADSP               policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8192_VDECSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8192_VENCSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195_APUSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195_AUDSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195_CAMSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195_IMGSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195_IMP_IIC_WRAP           policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195_IPESYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195_MFGCFG                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195_MSDC                   policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195_SCP_ADSP               policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195_VDECSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195_VDOSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195_VENCSYS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195_VPPSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8195_WPESYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8365                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8365_APU                    policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8365_CAM                    policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8365_MFG                    policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8365_MMSYS                  policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8365_VDEC                   policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8365_VENC                   policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8516                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_MT8516_AUDSYS                 policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_NUVOTON                       policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_PWM                           policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_QCOM                          policy<{'arm64': 'y'}>
+CONFIG_COMMON_CLK_ROCKCHIP                      policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_S4_PERIPHERALS                policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_S4_PLL                        policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_STM32MP                       policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_VISCONTI                      policy<{'arm64': '-'}>
+CONFIG_COMMON_CLK_ZYNQMP                        policy<{'arm64': '-'}>
+CONFIG_COMMON_RESET_HI3660                      policy<{'arm64': '-'}>
+CONFIG_COMMON_RESET_HI6220                      policy<{'arm64': '-'}>
+CONFIG_CRC7                                     policy<{'arm64': 'y'}>
+CONFIG_CRC_ITU_T                                policy<{'arm64': 'y'}>
+CONFIG_CRYPTO_DEV_ALLWINNER                     policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_CPT                           policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM                      policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API            policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_AHASH_API_DESC       policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_COMMON               policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API           policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC      policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_QI        policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_DEBUG                policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC                 policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD      policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD       policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_JR                   policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_PKC_API              policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_PRNG_API             policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE             policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_API              policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_TEST             policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM                policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4           policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_CTS       policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_KEEMBAY_OCS_AES_SM4_ECB       policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_KEEMBAY_OCS_ECC               policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_KEEMBAY_OCS_HCU               policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_KEEMBAY_OCS_HCU_HMAC_SHA224   policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_MARVELL                       policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_MARVELL_CESA                  policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_MXS_DCP                       policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_OCTEONTX2_CPT                 policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_OCTEONTX_CPT                  policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_ROCKCHIP                      policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_ROCKCHIP_DEBUG                policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_SA2UL                         policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_SAHARA                        policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_STM32_CRC                     policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_STM32_CRYP                    policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_STM32_HASH                    policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_SUN4I_SS                      policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_SUN4I_SS_DEBUG                policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_SUN4I_SS_PRNG                 policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_SUN8I_CE                      policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG                policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_SUN8I_CE_HASH                 policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_SUN8I_CE_PRNG                 policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_SUN8I_CE_TRNG                 policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_SUN8I_SS                      policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_SUN8I_SS_DEBUG                policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_SUN8I_SS_HASH                 policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_SUN8I_SS_PRNG                 policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_ZYNQMP_AES                    policy<{'arm64': '-'}>
+CONFIG_CRYPTO_DEV_ZYNQMP_SHA3                   policy<{'arm64': '-'}>
+CONFIG_DEBUG_KERNEL_DC                          policy<{'arm64': '-'}>
+CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI               policy<{'arm64': '-'}>
+CONFIG_DMA_SUN6I                                policy<{'arm64': '-'}>
+CONFIG_DPAA2_CONSOLE                            policy<{'arm64': '-'}>
+CONFIG_DPAA_ERRATUM_A050385                     policy<{'arm64': '-'}>
+CONFIG_DRM_AMDGPU                               policy<{'arm64': 'n'}>
+CONFIG_DRM_AMDGPU_SI                            policy<{'arm64': '-'}>
+CONFIG_DRM_AMDGPU_USERPTR                       policy<{'arm64': '-'}>
+CONFIG_DRM_AMDGPU_WERROR                        policy<{'arm64': '-'}>
+CONFIG_DRM_AMD_ACP                              policy<{'arm64': '-'}>
+CONFIG_DRM_AMD_DC                               policy<{'arm64': '-'}>
+CONFIG_DRM_AMD_DC_FP                            policy<{'arm64': '-'}>
+CONFIG_DRM_AMD_DC_SI                            policy<{'arm64': '-'}>
+CONFIG_DRM_AMD_SECURE_DISPLAY                   policy<{'arm64': '-'}>
+CONFIG_DRM_CDNS_MHDP8546_J721E                  policy<{'arm64': '-'}>
+CONFIG_DRM_DW_HDMI                              policy<{'arm64': '-'}>
+CONFIG_DRM_DW_HDMI_AHB_AUDIO                    policy<{'arm64': '-'}>
+CONFIG_DRM_DW_HDMI_CEC                          policy<{'arm64': '-'}>
+CONFIG_DRM_DW_HDMI_GP_AUDIO                     policy<{'arm64': '-'}>
+CONFIG_DRM_DW_HDMI_I2S_AUDIO                    policy<{'arm64': '-'}>
+CONFIG_DRM_DW_MIPI_DSI                          policy<{'arm64': '-'}>
+CONFIG_DRM_FSL_LDB                              policy<{'arm64': '-'}>
+CONFIG_DRM_IMX8QM_LDB                           policy<{'arm64': '-'}>
+CONFIG_DRM_IMX8QXP_LDB                          policy<{'arm64': '-'}>
+CONFIG_DRM_IMX8QXP_PIXEL_COMBINER               policy<{'arm64': '-'}>
+CONFIG_DRM_IMX8QXP_PIXEL_LINK                   policy<{'arm64': '-'}>
+CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI            policy<{'arm64': '-'}>
+CONFIG_DRM_IMX93_MIPI_DSI                       policy<{'arm64': '-'}>
+CONFIG_DRM_IMX_DCSS                             policy<{'arm64': '-'}>
+CONFIG_DRM_IMX_LCDC                             policy<{'arm64': '-'}>
+CONFIG_DRM_IMX_LCDIF                            policy<{'arm64': '-'}>
+CONFIG_DRM_IMX_LDB_HELPER                       policy<{'arm64': '-'}>
+CONFIG_DRM_KMB_DISPLAY                          policy<{'arm64': '-'}>
+CONFIG_DRM_MEDIATEK                             policy<{'arm64': '-'}>
+CONFIG_DRM_MEDIATEK_DP                          policy<{'arm64': '-'}>
+CONFIG_DRM_MEDIATEK_HDMI                        policy<{'arm64': '-'}>
+CONFIG_DRM_MESON                                policy<{'arm64': '-'}>
+CONFIG_DRM_MESON_DW_HDMI                        policy<{'arm64': '-'}>
+CONFIG_DRM_MESON_DW_MIPI_DSI                    policy<{'arm64': '-'}>
+CONFIG_DRM_MXS                                  policy<{'arm64': '-'}>
+CONFIG_DRM_MXSFB                                policy<{'arm64': '-'}>
+CONFIG_DRM_PANEL_NOVATEK_NT36672E               policy<{'arm64': 'm'}>
+CONFIG_DRM_RADEON                               policy<{'arm64': 'n'}>
+CONFIG_DRM_RADEON_USERPTR                       policy<{'arm64': '-'}>
+CONFIG_DRM_RCAR_CMM                             policy<{'arm64': '-'}>
+CONFIG_DRM_RCAR_DU                              policy<{'arm64': '-'}>
+CONFIG_DRM_RCAR_DW_HDMI                         policy<{'arm64': '-'}>
+CONFIG_DRM_RCAR_LVDS                            policy<{'arm64': '-'}>
+CONFIG_DRM_RCAR_MIPI_DSI                        policy<{'arm64': '-'}>
+CONFIG_DRM_RCAR_USE_CMM                         policy<{'arm64': '-'}>
+CONFIG_DRM_RCAR_USE_LVDS                        policy<{'arm64': '-'}>
+CONFIG_DRM_RCAR_USE_MIPI_DSI                    policy<{'arm64': '-'}>
+CONFIG_DRM_RCAR_VSP                             policy<{'arm64': '-'}>
+CONFIG_DRM_RCAR_WRITEBACK                       policy<{'arm64': '-'}>
+CONFIG_DRM_ROCKCHIP                             policy<{'arm64': '-'}>
+CONFIG_DRM_RZG2L_MIPI_DSI                       policy<{'arm64': '-'}>
+CONFIG_DRM_SHMOBILE                             policy<{'arm64': '-'}>
+CONFIG_DRM_SPRD                                 policy<{'arm64': '-'}>
+CONFIG_DRM_STM                                  policy<{'arm64': '-'}>
+CONFIG_DRM_STM_DSI                              policy<{'arm64': '-'}>
+CONFIG_DRM_SUN4I                                policy<{'arm64': '-'}>
+CONFIG_DRM_SUN6I_DSI                            policy<{'arm64': '-'}>
+CONFIG_DRM_SUN8I_DW_HDMI                        policy<{'arm64': '-'}>
+CONFIG_DRM_SUN8I_MIXER                          policy<{'arm64': '-'}>
+CONFIG_DRM_SUN8I_TCON_TOP                       policy<{'arm64': '-'}>
+CONFIG_DRM_TEGRA                                policy<{'arm64': '-'}>
+CONFIG_DRM_TEGRA_DEBUG                          policy<{'arm64': '-'}>
+CONFIG_DRM_TEGRA_STAGING                        policy<{'arm64': '-'}>
+CONFIG_DRM_ZYNQMP_DPSUB                         policy<{'arm64': '-'}>
+CONFIG_DVB_MAX_ADAPTERS                         policy<{'arm64': '16'}>
+CONFIG_DWMAC_IMX8                               policy<{'arm64': '-'}>
+CONFIG_DWMAC_MEDIATEK                           policy<{'arm64': '-'}>
+CONFIG_DWMAC_MESON                              policy<{'arm64': '-'}>
+CONFIG_DWMAC_ROCKCHIP                           policy<{'arm64': '-'}>
+CONFIG_DWMAC_SOCFPGA                            policy<{'arm64': '-'}>
+CONFIG_DWMAC_STM32                              policy<{'arm64': '-'}>
+CONFIG_DWMAC_SUN8I                              policy<{'arm64': '-'}>
+CONFIG_DWMAC_SUNXI                              policy<{'arm64': '-'}>
+CONFIG_DWMAC_TEGRA                              policy<{'arm64': '-'}>
+CONFIG_DWMAC_VISCONTI                           policy<{'arm64': '-'}>
+CONFIG_DW_APB_ICTL                              policy<{'arm64': '-'}>
+CONFIG_DW_APB_TIMER                             policy<{'arm64': '-'}>
+CONFIG_DW_APB_TIMER_OF                          policy<{'arm64': '-'}>
+CONFIG_EDAC_ALTERA                              policy<{'arm64': '-'}>
+CONFIG_EDAC_ALTERA_ETHERNET                     policy<{'arm64': '-'}>
+CONFIG_EDAC_ALTERA_NAND                         policy<{'arm64': '-'}>
+CONFIG_EDAC_ALTERA_OCRAM                        policy<{'arm64': '-'}>
+CONFIG_EDAC_ALTERA_QSPI                         policy<{'arm64': '-'}>
+CONFIG_EDAC_ALTERA_SDMMC                        policy<{'arm64': '-'}>
+CONFIG_EDAC_ALTERA_SDRAM                        policy<{'arm64': '-'}>
+CONFIG_EDAC_ALTERA_USB                          policy<{'arm64': '-'}>
+CONFIG_EDAC_LAYERSCAPE                          policy<{'arm64': '-'}>
+CONFIG_EDAC_NPCM                                policy<{'arm64': '-'}>
+CONFIG_EDAC_SYNOPSYS                            policy<{'arm64': '-'}>
+CONFIG_EDAC_VERSAL                              policy<{'arm64': '-'}>
+CONFIG_EDAC_ZYNQMP                              policy<{'arm64': '-'}>
+CONFIG_EINT_MTK                                 policy<{'arm64': '-'}>
+CONFIG_EMAC_ROCKCHIP                            policy<{'arm64': '-'}>
+CONFIG_EXTCON_RTK_TYPE_C                        policy<{'arm64': '-'}>
+CONFIG_FB_IMX                                   policy<{'arm64': '-'}>
+CONFIG_FB_PROVIDE_GET_FB_UNMAPPED_AREA          policy<{'arm64': '-'}>
+CONFIG_FB_SH_MOBILE_LCDC                        policy<{'arm64': '-'}>
+CONFIG_FB_XILINX                                policy<{'arm64': '-'}>
+CONFIG_FEC                                      policy<{'arm64': '-'}>
+CONFIG_FPGA_MGR_SOCFPGA                         policy<{'arm64': '-'}>
+CONFIG_FPGA_MGR_SOCFPGA_A10                     policy<{'arm64': '-'}>
+CONFIG_FPGA_MGR_STRATIX10_SOC                   policy<{'arm64': '-'}>
+CONFIG_FPGA_MGR_VERSAL_FPGA                     policy<{'arm64': '-'}>
+CONFIG_FPGA_MGR_ZYNQMP_FPGA                     policy<{'arm64': '-'}>
+CONFIG_FRAME_WARN                               policy<{'arm64': '2048'}>
+CONFIG_FSL_BMAN_TEST                            policy<{'arm64': '-'}>
+CONFIG_FSL_BMAN_TEST_API                        policy<{'arm64': '-'}>
+CONFIG_FSL_DPAA                                 policy<{'arm64': '-'}>
+CONFIG_FSL_DPAA2_ETH                            policy<{'arm64': '-'}>
+CONFIG_FSL_DPAA2_ETH_DCB                        policy<{'arm64': '-'}>
+CONFIG_FSL_DPAA2_PTP_CLOCK                      policy<{'arm64': '-'}>
+CONFIG_FSL_DPAA2_QDMA                           policy<{'arm64': '-'}>
+CONFIG_FSL_DPAA_CHECKING                        policy<{'arm64': '-'}>
+CONFIG_FSL_DPAA_ETH                             policy<{'arm64': '-'}>
+CONFIG_FSL_FMAN                                 policy<{'arm64': '-'}>
+CONFIG_FSL_GUTS                                 policy<{'arm64': '-'}>
+CONFIG_FSL_IFC                                  policy<{'arm64': '-'}>
+CONFIG_FSL_IMX8_DDR_PMU                         policy<{'arm64': '-'}>
+CONFIG_FSL_IMX9_DDR_PMU                         policy<{'arm64': '-'}>
+CONFIG_FSL_MC_BUS                               policy<{'arm64': '-'}>
+CONFIG_FSL_MC_DPIO                              policy<{'arm64': '-'}>
+CONFIG_FSL_MC_UAPI_SUPPORT                      policy<{'arm64': '-'}>
+CONFIG_FSL_QMAN_TEST                            policy<{'arm64': '-'}>
+CONFIG_FUEL_GAUGE_SC27XX                        policy<{'arm64': '-'}>
+CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT            policy<{'arm64': 'y'}>
+CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND           policy<{'arm64': '-'}>
+CONFIG_GENERIC_IRQ_IPI_MUX                      policy<{'arm64': '-'}>
+CONFIG_GH_VIRT_WATCHDOG                         policy<{'arm64': 'y'}>
+CONFIG_GPIO_ALTERA_A10SR                        policy<{'arm64': '-'}>
+CONFIG_GPIO_DAVINCI                             policy<{'arm64': '-'}>
+CONFIG_GPIO_EIC_SPRD                            policy<{'arm64': '-'}>
+CONFIG_GPIO_IMX_SCU                             policy<{'arm64': '-'}>
+CONFIG_GPIO_MPC8XXX                             policy<{'arm64': '-'}>
+CONFIG_GPIO_MVEBU                               policy<{'arm64': '-'}>
+CONFIG_GPIO_MXC                                 policy<{'arm64': '-'}>
+CONFIG_GPIO_NPCM_SGPIO                          policy<{'arm64': '-'}>
+CONFIG_GPIO_PCA953X                             policy<{'arm64': 'y'}>
+CONFIG_GPIO_PMIC_EIC_SPRD                       policy<{'arm64': '-'}>
+CONFIG_GPIO_RCAR                                policy<{'arm64': '-'}>
+CONFIG_GPIO_ROCKCHIP                            policy<{'arm64': '-'}>
+CONFIG_GPIO_RTD                                 policy<{'arm64': '-'}>
+CONFIG_GPIO_SL28CPLD                            policy<{'arm64': '-'}>
+CONFIG_GPIO_SPRD                                policy<{'arm64': '-'}>
+CONFIG_GPIO_TEGRA                               policy<{'arm64': '-'}>
+CONFIG_GPIO_TEGRA186                            policy<{'arm64': '-'}>
+CONFIG_GPIO_THUNDERX                            policy<{'arm64': '-'}>
+CONFIG_GPIO_VF610                               policy<{'arm64': '-'}>
+CONFIG_GPIO_VISCONTI                            policy<{'arm64': '-'}>
+CONFIG_GPIO_XGENE_SB                            policy<{'arm64': '-'}>
+CONFIG_GPIO_XLP                                 policy<{'arm64': '-'}>
+CONFIG_GPIO_ZYNQ                                policy<{'arm64': '-'}>
+CONFIG_GPIO_ZYNQMP_MODEPIN                      policy<{'arm64': '-'}>
+CONFIG_GUNYAH                                   policy<{'arm64': 'y'}>
+CONFIG_GUNYAH_DRIVERS                           policy<{'arm64': 'y'}>
+CONFIG_GUNYAH_IOEVENTFD                         policy<{'arm64': 'y'}>
+CONFIG_GUNYAH_IRQFD                             policy<{'arm64': 'y'}>
+CONFIG_GUNYAH_PLATFORM_HOOKS                    policy<{'arm64': 'y'}>
+CONFIG_GUNYAH_QCOM_PLATFORM                     policy<{'arm64': 'y'}>
+CONFIG_GUNYAH_VCPU                              policy<{'arm64': 'y'}>
+CONFIG_HAVE_KERNEL_GZIP                         policy<{'arm64': '-'}>
+CONFIG_HAVE_KERNEL_ZSTD                         policy<{'arm64': '-'}>
+CONFIG_HBMC_AM654                               policy<{'arm64': '-'}>
+CONFIG_HI3660_MBOX                              policy<{'arm64': '-'}>
+CONFIG_HI6220_MBOX                              policy<{'arm64': '-'}>
+CONFIG_HISILICON_IRQ_MBIGEN                     policy<{'arm64': '-'}>
+CONFIG_HISILICON_LPC                            policy<{'arm64': '-'}>
+CONFIG_HISI_DMA                                 policy<{'arm64': '-'}>
+CONFIG_HISI_THERMAL                             policy<{'arm64': '-'}>
+CONFIG_HSA_AMD                                  policy<{'arm64': '-'}>
+CONFIG_HSA_AMD_SVM                              policy<{'arm64': '-'}>
+CONFIG_HTE_TEGRA194                             policy<{'arm64': '-'}>
+CONFIG_HTE_TEGRA194_TEST                        policy<{'arm64': '-'}>
+CONFIG_HWSPINLOCK_OMAP                          policy<{'arm64': '-'}>
+CONFIG_HWSPINLOCK_QCOM                          policy<{'arm64': 'y'}>
+CONFIG_HWSPINLOCK_SPRD                          policy<{'arm64': '-'}>
+CONFIG_HWSPINLOCK_SUN6I                         policy<{'arm64': '-'}>
+CONFIG_HW_RANDOM_CAVIUM                         policy<{'arm64': '-'}>
+CONFIG_HW_RANDOM_HISI                           policy<{'arm64': '-'}>
+CONFIG_HW_RANDOM_HISTB                          policy<{'arm64': '-'}>
+CONFIG_HW_RANDOM_MESON                          policy<{'arm64': '-'}>
+CONFIG_HW_RANDOM_MTK                            policy<{'arm64': '-'}>
+CONFIG_HW_RANDOM_NPCM                           policy<{'arm64': '-'}>
+CONFIG_HW_RANDOM_OMAP                           policy<{'arm64': '-'}>
+CONFIG_HW_RANDOM_STM32                          policy<{'arm64': '-'}>
+CONFIG_HW_RANDOM_XGENE                          policy<{'arm64': '-'}>
+CONFIG_I2C_ALTERA                               policy<{'arm64': '-'}>
+CONFIG_I2C_APPLE                                policy<{'arm64': '-'}>
+CONFIG_I2C_DEMUX_PINCTRL                        policy<{'arm64': 'n'}>
+CONFIG_I2C_HIX5HD2                              policy<{'arm64': '-'}>
+CONFIG_I2C_IMX                                  policy<{'arm64': '-'}>
+CONFIG_I2C_IMX_LPI2C                            policy<{'arm64': '-'}>
+CONFIG_I2C_MESON                                policy<{'arm64': '-'}>
+CONFIG_I2C_MT65XX                               policy<{'arm64': '-'}>
+CONFIG_I2C_MUX                                  policy<{'arm64': 'y'}>
+CONFIG_I2C_MUX_PCA954x                          policy<{'arm64': 'y'}>
+CONFIG_I2C_MV64XXX                              policy<{'arm64': '-'}>
+CONFIG_I2C_NPCM                                 policy<{'arm64': '-'}>
+CONFIG_I2C_OMAP                                 policy<{'arm64': '-'}>
+CONFIG_I2C_OWL                                  policy<{'arm64': '-'}>
+CONFIG_I2C_PXA                                  policy<{'arm64': '-'}>
+CONFIG_I2C_PXA_SLAVE                            policy<{'arm64': '-'}>
+CONFIG_I2C_QUP                                  policy<{'arm64': 'y'}>
+CONFIG_I2C_RCAR                                 policy<{'arm64': '-'}>
+CONFIG_I2C_RIIC                                 policy<{'arm64': '-'}>
+CONFIG_I2C_RZV2M                                policy<{'arm64': '-'}>
+CONFIG_I2C_SH_MOBILE                            policy<{'arm64': '-'}>
+CONFIG_I2C_SPRD                                 policy<{'arm64': '-'}>
+CONFIG_I2C_STM32F4                              policy<{'arm64': '-'}>
+CONFIG_I2C_STM32F7                              policy<{'arm64': '-'}>
+CONFIG_I2C_SYNQUACER                            policy<{'arm64': '-'}>
+CONFIG_I2C_TEGRA                                policy<{'arm64': '-'}>
+CONFIG_I2C_TEGRA_BPMP                           policy<{'arm64': '-'}>
+CONFIG_I2C_VERSATILE                            policy<{'arm64': '-'}>
+CONFIG_I2C_XGENE_SLIMPRO                        policy<{'arm64': '-'}>
+CONFIG_I2C_XLP9XX                               policy<{'arm64': '-'}>
+CONFIG_IIO_STM32_LPTIMER_TRIGGER                policy<{'arm64': '-'}>
+CONFIG_IIO_STM32_TIMER_TRIGGER                  policy<{'arm64': '-'}>
+CONFIG_IMX2_WDT                                 policy<{'arm64': '-'}>
+CONFIG_IMX7D_ADC                                policy<{'arm64': '-'}>
+CONFIG_IMX7ULP_WDT                              policy<{'arm64': '-'}>
+CONFIG_IMX8MM_THERMAL                           policy<{'arm64': '-'}>
+CONFIG_IMX8M_BLK_CTRL                           policy<{'arm64': '-'}>
+CONFIG_IMX8QXP_ADC                              policy<{'arm64': '-'}>
+CONFIG_IMX93_ADC                                policy<{'arm64': '-'}>
+CONFIG_IMX9_BLK_CTRL                            policy<{'arm64': '-'}>
+CONFIG_IMX_DMA                                  policy<{'arm64': '-'}>
+CONFIG_IMX_DSP                                  policy<{'arm64': '-'}>
+CONFIG_IMX_DSP_REMOTEPROC                       policy<{'arm64': '-'}>
+CONFIG_IMX_GPCV2                                policy<{'arm64': '-'}>
+CONFIG_IMX_GPCV2_PM_DOMAINS                     policy<{'arm64': '-'}>
+CONFIG_IMX_INTMUX                               policy<{'arm64': '-'}>
+CONFIG_IMX_IRQSTEER                             policy<{'arm64': '-'}>
+CONFIG_IMX_MBOX                                 policy<{'arm64': '-'}>
+CONFIG_IMX_MU_MSI                               policy<{'arm64': '-'}>
+CONFIG_IMX_REMOTEPROC                           policy<{'arm64': '-'}>
+CONFIG_IMX_SCU                                  policy<{'arm64': '-'}>
+CONFIG_IMX_SCU_PD                               policy<{'arm64': '-'}>
+CONFIG_IMX_SC_THERMAL                           policy<{'arm64': '-'}>
+CONFIG_IMX_SC_WDT                               policy<{'arm64': '-'}>
+CONFIG_IMX_SDMA                                 policy<{'arm64': '-'}>
+CONFIG_IMX_THERMAL                              policy<{'arm64': '-'}>
+CONFIG_IMX_WEIM                                 policy<{'arm64': '-'}>
+CONFIG_INPUT_BBNSM_PWRKEY                       policy<{'arm64': '-'}>
+CONFIG_INPUT_HISI_POWERKEY                      policy<{'arm64': '-'}>
+CONFIG_INPUT_SC27XX_VIBRA                       policy<{'arm64': '-'}>
+CONFIG_INTEL_STRATIX10_RSU                      policy<{'arm64': '-'}>
+CONFIG_INTEL_STRATIX10_SERVICE                  policy<{'arm64': '-'}>
+CONFIG_INTERCONNECT_CLK                         policy<{'arm64': 'y'}>
+CONFIG_INTERCONNECT_IMX                         policy<{'arm64': '-'}>
+CONFIG_INTERCONNECT_IMX8MM                      policy<{'arm64': '-'}>
+CONFIG_INTERCONNECT_IMX8MN                      policy<{'arm64': '-'}>
+CONFIG_INTERCONNECT_IMX8MP                      policy<{'arm64': '-'}>
+CONFIG_INTERCONNECT_IMX8MQ                      policy<{'arm64': '-'}>
+CONFIG_INTERCONNECT_QCOM_BCM_VOTER              policy<{'arm64': 'y'}>
+CONFIG_INTERCONNECT_QCOM_QCS615                 policy<{'arm64': 'y'}>
+CONFIG_INTERCONNECT_QCOM_QCS8300                policy<{'arm64': 'y'}>
+CONFIG_INTERCONNECT_QCOM_RPMH                   policy<{'arm64': 'y'}>
+CONFIG_INTERCONNECT_QCOM_SA8775P                policy<{'arm64': 'y'}>
+CONFIG_INTERCONNECT_QCOM_SC7180                 policy<{'arm64': 'y'}>
+CONFIG_INTERCONNECT_QCOM_SC7280                 policy<{'arm64': 'y'}>
+CONFIG_INTERCONNECT_QCOM_SC8180X                policy<{'arm64': 'y'}>
+CONFIG_INTERCONNECT_QCOM_SC8280XP               policy<{'arm64': 'y'}>
+CONFIG_INTERCONNECT_QCOM_SDM845                 policy<{'arm64': 'y'}>
+CONFIG_INTERCONNECT_QCOM_SM8450                 policy<{'arm64': 'y'}>
+CONFIG_INTERCONNECT_QCOM_SM8550                 policy<{'arm64': 'y'}>
+CONFIG_INTERCONNECT_QCOM_SM8650                 policy<{'arm64': 'y'}>
+CONFIG_INTERCONNECT_QCOM_X1E80100               policy<{'arm64': 'y'}>
+CONFIG_IPMI_KCS_BMC                             policy<{'arm64': '-'}>
+CONFIG_IPMI_KCS_BMC_CDEV_IPMI                   policy<{'arm64': '-'}>
+CONFIG_IPMI_KCS_BMC_SERIO                       policy<{'arm64': '-'}>
+CONFIG_IPQ_APSS_6018                            policy<{'arm64': 'y'}>
+CONFIG_IPQ_APSS_PLL                             policy<{'arm64': 'y'}>
+CONFIG_IPQ_GCC_5332                             policy<{'arm64': 'y'}>
+CONFIG_IPQ_GCC_6018                             policy<{'arm64': 'y'}>
+CONFIG_IPQ_GCC_8074                             policy<{'arm64': 'y'}>
+CONFIG_IPQ_GCC_9574                             policy<{'arm64': 'y'}>
+CONFIG_IR_MESON                                 policy<{'arm64': '-'}>
+CONFIG_IR_MESON_TX                              policy<{'arm64': '-'}>
+CONFIG_IR_MTK                                   policy<{'arm64': '-'}>
+CONFIG_IR_SUNXI                                 policy<{'arm64': '-'}>
+CONFIG_K3_DMA                                   policy<{'arm64': '-'}>
+CONFIG_K3_RTI_WATCHDOG                          policy<{'arm64': '-'}>
+CONFIG_K3_THERMAL                               policy<{'arm64': '-'}>
+CONFIG_KASAN                                    policy<{'arm64': 'y'}>
+CONFIG_KASAN_EXTRA_INFO                         policy<{'arm64': 'n'}>
+CONFIG_KASAN_GENERIC                            policy<{'arm64': 'n'}>
+CONFIG_KASAN_HW_TAGS                            policy<{'arm64': 'y'}>
+CONFIG_KASAN_SW_TAGS                            policy<{'arm64': 'n'}>
+CONFIG_KASAN_VMALLOC                            policy<{'arm64': 'y'}>
+CONFIG_KCSAN                                    policy<{'arm64': '-'}>
+CONFIG_KEEMBAY_WATCHDOG                         policy<{'arm64': '-'}>
+CONFIG_KERNEL_GZIP                              policy<{'arm64': '-'}>
+CONFIG_KEYBOARD_IMX                             policy<{'arm64': '-'}>
+CONFIG_KEYBOARD_IMX_SC_KEY                      policy<{'arm64': '-'}>
+CONFIG_KEYBOARD_MT6779                          policy<{'arm64': '-'}>
+CONFIG_KEYBOARD_NVEC                            policy<{'arm64': '-'}>
+CONFIG_KEYBOARD_SNVS_PWRKEY                     policy<{'arm64': '-'}>
+CONFIG_KEYBOARD_SUN4I_LRADC                     policy<{'arm64': '-'}>
+CONFIG_KEYBOARD_TEGRA                           policy<{'arm64': '-'}>
+CONFIG_KHADAS_MCU_FAN_THERMAL                   policy<{'arm64': '-'}>
+CONFIG_KUNPENG_HCCS                             policy<{'arm64': '-'}>
+CONFIG_LEDS_SC27XX_BLTC                         policy<{'arm64': '-'}>
+CONFIG_LEDS_SUN50I_A100                         policy<{'arm64': '-'}>
+CONFIG_LEGACY_PTY_COUNT                         policy<{'arm64': '16'}>
+CONFIG_LOG_BUF_SHIFT                            policy<{'arm64': '17'}>
+CONFIG_LSM_MMAP_MIN_ADDR                        policy<{'arm64': '32768'}>
+CONFIG_LS_EXTIRQ                                policy<{'arm64': '-'}>
+CONFIG_LS_SCFG_MSI                              policy<{'arm64': '-'}>
+CONFIG_MARVELL_CN10K_DDR_PMU                    policy<{'arm64': '-'}>
+CONFIG_MARVELL_CN10K_TAD_PMU                    policy<{'arm64': '-'}>
+CONFIG_MARVELL_GTI_WDT                          policy<{'arm64': '-'}>
+CONFIG_MDIO_BUS_MUX_MESON_G12A                  policy<{'arm64': '-'}>
+CONFIG_MDIO_BUS_MUX_MESON_GXL                   policy<{'arm64': '-'}>
+CONFIG_MDIO_SUN4I                               policy<{'arm64': '-'}>
+CONFIG_MDIO_XGENE                               policy<{'arm64': '-'}>
+CONFIG_MEDIATEK_GE_SOC_PHY                      policy<{'arm64': 'n'}>
+CONFIG_MEDIATEK_MT6577_AUXADC                   policy<{'arm64': '-'}>
+CONFIG_MEDIATEK_WATCHDOG                        policy<{'arm64': '-'}>
+CONFIG_MESON_CANVAS                             policy<{'arm64': '-'}>
+CONFIG_MESON_CLK_MEASURE                        policy<{'arm64': '-'}>
+CONFIG_MESON_DDR_PMU                            policy<{'arm64': '-'}>
+CONFIG_MESON_EE_PM_DOMAINS                      policy<{'arm64': '-'}>
+CONFIG_MESON_GXBB_WATCHDOG                      policy<{'arm64': '-'}>
+CONFIG_MESON_GXL_PHY                            policy<{'arm64': '-'}>
+CONFIG_MESON_GX_PM_DOMAINS                      policy<{'arm64': '-'}>
+CONFIG_MESON_GX_SOCINFO                         policy<{'arm64': '-'}>
+CONFIG_MESON_IRQ_GPIO                           policy<{'arm64': '-'}>
+CONFIG_MESON_SARADC                             policy<{'arm64': '-'}>
+CONFIG_MESON_SECURE_PM_DOMAINS                  policy<{'arm64': '-'}>
+CONFIG_MESON_SM                                 policy<{'arm64': '-'}>
+CONFIG_MESON_WATCHDOG                           policy<{'arm64': '-'}>
+CONFIG_MFD_AC100                                policy<{'arm64': '-'}>
+CONFIG_MFD_ALTERA_A10SR                         policy<{'arm64': '-'}>
+CONFIG_MFD_ALTERA_SYSMGR                        policy<{'arm64': '-'}>
+CONFIG_MFD_AXP20X_RSB                           policy<{'arm64': '-'}>
+CONFIG_MFD_HI655X_PMIC                          policy<{'arm64': '-'}>
+CONFIG_MFD_I2C_PMIC                             policy<{'arm64': 'y'}>
+CONFIG_MFD_KHADAS_MCU                           policy<{'arm64': '-'}>
+CONFIG_MFD_NVEC                                 policy<{'arm64': '-'}>
+CONFIG_MFD_SC27XX_PMIC                          policy<{'arm64': '-'}>
+CONFIG_MFD_SL28CPLD                             policy<{'arm64': '-'}>
+CONFIG_MFD_SPMI_PMIC                            policy<{'arm64': 'y'}>
+CONFIG_MFD_STM32_LPTIMER                        policy<{'arm64': '-'}>
+CONFIG_MFD_STM32_TIMERS                         policy<{'arm64': '-'}>
+CONFIG_MFD_SUN4I_GPADC                          policy<{'arm64': '-'}>
+CONFIG_MFD_SUN6I_PRCM                           policy<{'arm64': '-'}>
+CONFIG_MFD_TI_AM335X_TSCADC                     policy<{'arm64': '-'}>
+CONFIG_MHI_EP_NET                               policy<{'arm64': 'n'}>
+CONFIG_MMC_BLOCK_MINORS                         policy<{'arm64': '32'}>
+CONFIG_MMC_CAVIUM_THUNDERX                      policy<{'arm64': '-'}>
+CONFIG_MMC_CQHCI                                policy<{'arm64': 'y'}>
+CONFIG_MMC_DW                                   policy<{'arm64': 'y'}>
+CONFIG_MMC_DW_EXYNOS                            policy<{'arm64': 'y'}>
+CONFIG_MMC_DW_HI3798CV200                       policy<{'arm64': 'y'}>
+CONFIG_MMC_DW_K3                                policy<{'arm64': 'y'}>
+CONFIG_MMC_DW_PLTFM                             policy<{'arm64': 'y'}>
+CONFIG_MMC_DW_ROCKCHIP                          policy<{'arm64': '-'}>
+CONFIG_MMC_MESON_GX                             policy<{'arm64': '-'}>
+CONFIG_MMC_MESON_MX_SDIO                        policy<{'arm64': '-'}>
+CONFIG_MMC_MTK                                  policy<{'arm64': 'y'}>
+CONFIG_MMC_MXC                                  policy<{'arm64': '-'}>
+CONFIG_MMC_OWL                                  policy<{'arm64': '-'}>
+CONFIG_MMC_SDHCI_ACPI                           policy<{'arm64': 'y'}>
+CONFIG_MMC_SDHCI_AM654                          policy<{'arm64': '-'}>
+CONFIG_MMC_SDHCI_CADENCE                        policy<{'arm64': 'y'}>
+CONFIG_MMC_SDHCI_ESDHC_IMX                      policy<{'arm64': '-'}>
+CONFIG_MMC_SDHCI_F_SDH30                        policy<{'arm64': 'y'}>
+CONFIG_MMC_SDHCI_MSM                            policy<{'arm64': 'y'}>
+CONFIG_MMC_SDHCI_NPCM                           policy<{'arm64': '-'}>
+CONFIG_MMC_SDHCI_OF_ARASAN                      policy<{'arm64': 'y'}>
+CONFIG_MMC_SDHCI_OF_DWCMSHC                     policy<{'arm64': 'y'}>
+CONFIG_MMC_SDHCI_OF_ESDHC                       policy<{'arm64': '-'}>
+CONFIG_MMC_SDHCI_OF_SPARX5                      policy<{'arm64': '-'}>
+CONFIG_MMC_SDHCI_PXAV3                          policy<{'arm64': '-'}>
+CONFIG_MMC_SDHCI_SPRD                           policy<{'arm64': '-'}>
+CONFIG_MMC_SDHCI_TEGRA                          policy<{'arm64': '-'}>
+CONFIG_MMC_SDHCI_XENON                          policy<{'arm64': 'y'}>
+CONFIG_MMC_SDHI                                 policy<{'arm64': '-'}>
+CONFIG_MMC_SDHI_INTERNAL_DMAC                   policy<{'arm64': '-'}>
+CONFIG_MMC_SDHI_SYS_DMAC                        policy<{'arm64': '-'}>
+CONFIG_MMC_SH_MMCIF                             policy<{'arm64': '-'}>
+CONFIG_MMC_SPI                                  policy<{'arm64': 'y'}>
+CONFIG_MMC_SUNXI                                policy<{'arm64': '-'}>
+CONFIG_MMC_TMIO_CORE                            policy<{'arm64': '-'}>
+CONFIG_MSM_GCC_8916                             policy<{'arm64': 'y'}>
+CONFIG_MSM_GCC_8994                             policy<{'arm64': 'y'}>
+CONFIG_MSM_GCC_8998                             policy<{'arm64': 'y'}>
+CONFIG_MSM_RDBG                                 policy<{'arm64': 'm'}>
+CONFIG_MST_IRQ                                  policy<{'arm64': '-'}>
+CONFIG_MT7622_WMAC                              policy<{'arm64': '-'}>
+CONFIG_MT798X_WMAC                              policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_ECC_MEDIATEK                    policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_FSL_IFC                         policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_GPMI_NAND                       policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_HISI504                         policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_MARVELL                         policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_MESON                           policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_MTK                             policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_MXC                             policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_OMAP2                           policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_OMAP_BCH                        policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_OMAP_BCH_BUILD                  policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_RENESAS                         policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_ROCKCHIP                        policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_STM32_FMC2                      policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_SUNXI                           policy<{'arm64': '-'}>
+CONFIG_MTD_NAND_TEGRA                           policy<{'arm64': '-'}>
+CONFIG_MTD_PARSER_TRX                           policy<{'arm64': '-'}>
+CONFIG_MTK_ADSP_IPC                             policy<{'arm64': '-'}>
+CONFIG_MTK_ADSP_MBOX                            policy<{'arm64': '-'}>
+CONFIG_MTK_CMDQ                                 policy<{'arm64': '-'}>
+CONFIG_MTK_CMDQ_MBOX                            policy<{'arm64': '-'}>
+CONFIG_MTK_CPUX_TIMER                           policy<{'arm64': '-'}>
+CONFIG_MTK_CQDMA                                policy<{'arm64': '-'}>
+CONFIG_MTK_DEVAPC                               policy<{'arm64': '-'}>
+CONFIG_MTK_HSDMA                                policy<{'arm64': '-'}>
+CONFIG_MTK_INFRACFG                             policy<{'arm64': '-'}>
+CONFIG_MTK_IOMMU                                policy<{'arm64': '-'}>
+CONFIG_MTK_LVTS_THERMAL                         policy<{'arm64': '-'}>
+CONFIG_MTK_LVTS_THERMAL_DEBUGFS                 policy<{'arm64': '-'}>
+CONFIG_MTK_MMSYS                                policy<{'arm64': '-'}>
+CONFIG_MTK_PMIC_WRAP                            policy<{'arm64': '-'}>
+CONFIG_MTK_REGULATOR_COUPLER                    policy<{'arm64': '-'}>
+CONFIG_MTK_SCP                                  policy<{'arm64': '-'}>
+CONFIG_MTK_SCPSYS                               policy<{'arm64': '-'}>
+CONFIG_MTK_SCPSYS_PM_DOMAINS                    policy<{'arm64': '-'}>
+CONFIG_MTK_SMI                                  policy<{'arm64': '-'}>
+CONFIG_MTK_SOC_THERMAL                          policy<{'arm64': '-'}>
+CONFIG_MTK_SVS                                  policy<{'arm64': '-'}>
+CONFIG_MTK_THERMAL                              policy<{'arm64': '-'}>
+CONFIG_MTK_TIMER                                policy<{'arm64': '-'}>
+CONFIG_MTK_UART_APDMA                           policy<{'arm64': '-'}>
+CONFIG_MVEBU_GICP                               policy<{'arm64': '-'}>
+CONFIG_MVEBU_ICU                                policy<{'arm64': '-'}>
+CONFIG_MVEBU_ODMI                               policy<{'arm64': '-'}>
+CONFIG_MVEBU_PIC                                policy<{'arm64': '-'}>
+CONFIG_MVEBU_SEI                                policy<{'arm64': '-'}>
+CONFIG_MVNETA                                   policy<{'arm64': '-'}>
+CONFIG_MVPP2                                    policy<{'arm64': '-'}>
+CONFIG_MVPP2_PTP                                policy<{'arm64': '-'}>
+CONFIG_MV_XOR                                   policy<{'arm64': '-'}>
+CONFIG_MXC_CLK                                  policy<{'arm64': '-'}>
+CONFIG_MXC_CLK_SCU                              policy<{'arm64': '-'}>
+CONFIG_MXS_DMA                                  policy<{'arm64': '-'}>
+CONFIG_NET_VENDOR_ACTIONS                       policy<{'arm64': '-'}>
+CONFIG_NET_VENDOR_ALLWINNER                     policy<{'arm64': '-'}>
+CONFIG_NET_VENDOR_MEDIATEK                      policy<{'arm64': '-'}>
+CONFIG_NET_XGENE                                policy<{'arm64': '-'}>
+CONFIG_NET_XGENE_V2                             policy<{'arm64': '-'}>
+CONFIG_NL80211_TESTMODE                         policy<{'arm64': 'y'}>
+CONFIG_NLS_DEFAULT                              policy<{'arm64': '"iso8859-1"'}>
+CONFIG_NODES_SHIFT                              policy<{'arm64': '4'}>
+CONFIG_NOUVEAU_PLATFORM_DRIVER                  policy<{'arm64': '-'}>
+CONFIG_NPCM7XX_KCS_IPMI_BMC                     policy<{'arm64': '-'}>
+CONFIG_NPCM7XX_TIMER                            policy<{'arm64': '-'}>
+CONFIG_NPCM7XX_WATCHDOG                         policy<{'arm64': '-'}>
+CONFIG_NPCM_ADC                                 policy<{'arm64': '-'}>
+CONFIG_NVEC_PAZ00                               policy<{'arm64': '-'}>
+CONFIG_NVEC_POWER                               policy<{'arm64': '-'}>
+CONFIG_NVMEM_APPLE_EFUSES                       policy<{'arm64': '-'}>
+CONFIG_NVMEM_IMX_IIM                            policy<{'arm64': '-'}>
+CONFIG_NVMEM_IMX_OCOTP                          policy<{'arm64': '-'}>
+CONFIG_NVMEM_IMX_OCOTP_ELE                      policy<{'arm64': '-'}>
+CONFIG_NVMEM_IMX_OCOTP_SCU                      policy<{'arm64': '-'}>
+CONFIG_NVMEM_LAYERSCAPE_SFP                     policy<{'arm64': '-'}>
+CONFIG_NVMEM_MESON_EFUSE                        policy<{'arm64': '-'}>
+CONFIG_NVMEM_MESON_MX_EFUSE                     policy<{'arm64': '-'}>
+CONFIG_NVMEM_MTK_EFUSE                          policy<{'arm64': '-'}>
+CONFIG_NVMEM_QCOM_QFPROM                        policy<{'arm64': 'y'}>
+CONFIG_NVMEM_ROCKCHIP_EFUSE                     policy<{'arm64': '-'}>
+CONFIG_NVMEM_ROCKCHIP_OTP                       policy<{'arm64': '-'}>
+CONFIG_NVMEM_SC27XX_EFUSE                       policy<{'arm64': '-'}>
+CONFIG_NVMEM_SNVS_LPGPR                         policy<{'arm64': '-'}>
+CONFIG_NVMEM_SPRD_EFUSE                         policy<{'arm64': '-'}>
+CONFIG_NVMEM_STM32_BSEC_OPTEE_TA                policy<{'arm64': '-'}>
+CONFIG_NVMEM_STM32_ROMEM                        policy<{'arm64': '-'}>
+CONFIG_NVMEM_SUNXI_SID                          policy<{'arm64': '-'}>
+CONFIG_NVMEM_ZYNQMP                             policy<{'arm64': '-'}>
+CONFIG_NVME_APPLE                               policy<{'arm64': '-'}>
+CONFIG_OF_DYNAMIC                               policy<{'arm64': '-'}>
+CONFIG_OF_OVERLAY                               policy<{'arm64': 'n'}>
+CONFIG_OF_RECONFIG_NOTIFIER_ERROR_INJECT        policy<{'arm64': '-'}>
+CONFIG_OF_RESOLVE                               policy<{'arm64': '-'}>
+CONFIG_OMAP2PLUS_MBOX                           policy<{'arm64': '-'}>
+CONFIG_OMAP_DM_TIMER                            policy<{'arm64': '-'}>
+CONFIG_OMAP_GPMC                                policy<{'arm64': '-'}>
+CONFIG_OMAP_GPMC_DEBUG                          policy<{'arm64': '-'}>
+CONFIG_OMAP_MBOX_KFIFO_SIZE                     policy<{'arm64': '-'}>
+CONFIG_OMAP_USB2                                policy<{'arm64': '-'}>
+CONFIG_OWL_DMA                                  policy<{'arm64': '-'}>
+CONFIG_OWL_EMAC                                 policy<{'arm64': '-'}>
+CONFIG_OWL_PM_DOMAINS                           policy<{'arm64': '-'}>
+CONFIG_OWL_PM_DOMAINS_HELPER                    policy<{'arm64': '-'}>
+CONFIG_OWL_TIMER                                policy<{'arm64': '-'}>
+CONFIG_PANIC_TIMEOUT                            policy<{'arm64': '-1'}>
+CONFIG_PATA_IMX                                 policy<{'arm64': '-'}>
+CONFIG_PCIE_APPLE                               policy<{'arm64': '-'}>
+CONFIG_PCIE_APPLE_MSI_DOORBELL_ADDR             policy<{'arm64': '-'}>
+CONFIG_PCIE_ARMADA_8K                           policy<{'arm64': '-'}>
+CONFIG_PCIE_HISI_STB                            policy<{'arm64': '-'}>
+CONFIG_PCIE_KEEMBAY                             policy<{'arm64': '-'}>
+CONFIG_PCIE_KEEMBAY_EP                          policy<{'arm64': '-'}>
+CONFIG_PCIE_KEEMBAY_HOST                        policy<{'arm64': '-'}>
+CONFIG_PCIE_LAYERSCAPE_GEN4                     policy<{'arm64': '-'}>
+CONFIG_PCIE_MEDIATEK                            policy<{'arm64': '-'}>
+CONFIG_PCIE_MEDIATEK_GEN3                       policy<{'arm64': '-'}>
+CONFIG_PCIE_MOBIVEIL_PLAT                       policy<{'arm64': '-'}>
+CONFIG_PCIE_QCOM_COMMON                         policy<{'arm64': 'y'}>
+CONFIG_PCIE_QCOM_EP                             policy<{'arm64': 'n'}>
+CONFIG_PCIE_RCAR_EP                             policy<{'arm64': '-'}>
+CONFIG_PCIE_RCAR_GEN4                           policy<{'arm64': '-'}>
+CONFIG_PCIE_RCAR_GEN4_EP                        policy<{'arm64': '-'}>
+CONFIG_PCIE_RCAR_GEN4_HOST                      policy<{'arm64': '-'}>
+CONFIG_PCIE_RCAR_HOST                           policy<{'arm64': '-'}>
+CONFIG_PCIE_ROCKCHIP                            policy<{'arm64': '-'}>
+CONFIG_PCIE_ROCKCHIP_DW_HOST                    policy<{'arm64': '-'}>
+CONFIG_PCIE_ROCKCHIP_EP                         policy<{'arm64': '-'}>
+CONFIG_PCIE_ROCKCHIP_HOST                       policy<{'arm64': '-'}>
+CONFIG_PCIE_TEGRA194                            policy<{'arm64': '-'}>
+CONFIG_PCIE_TEGRA194_EP                         policy<{'arm64': '-'}>
+CONFIG_PCIE_TEGRA194_HOST                       policy<{'arm64': '-'}>
+CONFIG_PCIE_VISCONTI_HOST                       policy<{'arm64': '-'}>
+CONFIG_PCIE_XILINX_CPM                          policy<{'arm64': '-'}>
+CONFIG_PCIE_XILINX_DMA_PL                       policy<{'arm64': '-'}>
+CONFIG_PCIE_XILINX_NWL                          policy<{'arm64': '-'}>
+CONFIG_PCI_AARDVARK                             policy<{'arm64': '-'}>
+CONFIG_PCI_BRIDGE_EMUL                          policy<{'arm64': '-'}>
+CONFIG_PCI_IMX6                                 policy<{'arm64': '-'}>
+CONFIG_PCI_IMX6_EP                              policy<{'arm64': '-'}>
+CONFIG_PCI_IMX6_HOST                            policy<{'arm64': '-'}>
+CONFIG_PCI_J721E                                policy<{'arm64': '-'}>
+CONFIG_PCI_J721E_EP                             policy<{'arm64': '-'}>
+CONFIG_PCI_J721E_HOST                           policy<{'arm64': '-'}>
+CONFIG_PCI_KEYSTONE                             policy<{'arm64': '-'}>
+CONFIG_PCI_KEYSTONE_EP                          policy<{'arm64': '-'}>
+CONFIG_PCI_KEYSTONE_HOST                        policy<{'arm64': '-'}>
+CONFIG_PCI_LAYERSCAPE                           policy<{'arm64': '-'}>
+CONFIG_PCI_LAYERSCAPE_EP                        policy<{'arm64': '-'}>
+CONFIG_PCI_PWRCTL                               policy<{'arm64': 'm'}>
+CONFIG_PCI_PWRCTL_PWRSEQ                        policy<{'arm64': 'm'}>
+CONFIG_PCI_TEGRA                                policy<{'arm64': '-'}>
+CONFIG_PCS_LYNX                                 policy<{'arm64': 'm'}>
+CONFIG_PECI_NPCM                                policy<{'arm64': '-'}>
+CONFIG_PHYLINK                                  policy<{'arm64': 'm'}>
+CONFIG_PHY_AM654_SERDES                         policy<{'arm64': '-'}>
+CONFIG_PHY_BERLIN_SATA                          policy<{'arm64': '-'}>
+CONFIG_PHY_BERLIN_USB                           policy<{'arm64': '-'}>
+CONFIG_PHY_FSL_IMX8MQ_USB                       policy<{'arm64': '-'}>
+CONFIG_PHY_FSL_IMX8M_PCIE                       policy<{'arm64': '-'}>
+CONFIG_PHY_FSL_LYNX_28G                         policy<{'arm64': '-'}>
+CONFIG_PHY_HI3660_USB                           policy<{'arm64': '-'}>
+CONFIG_PHY_HI3670_PCIE                          policy<{'arm64': '-'}>
+CONFIG_PHY_HI3670_USB                           policy<{'arm64': '-'}>
+CONFIG_PHY_HI6220_USB                           policy<{'arm64': '-'}>
+CONFIG_PHY_HISI_INNO_USB2                       policy<{'arm64': '-'}>
+CONFIG_PHY_HISTB_COMBPHY                        policy<{'arm64': '-'}>
+CONFIG_PHY_INTEL_KEEMBAY_EMMC                   policy<{'arm64': '-'}>
+CONFIG_PHY_INTEL_KEEMBAY_USB                    policy<{'arm64': '-'}>
+CONFIG_PHY_J721E_WIZ                            policy<{'arm64': '-'}>
+CONFIG_PHY_MESON8B_USB2                         policy<{'arm64': '-'}>
+CONFIG_PHY_MESON_AXG_MIPI_DPHY                  policy<{'arm64': '-'}>
+CONFIG_PHY_MESON_AXG_MIPI_PCIE_ANALOG           policy<{'arm64': '-'}>
+CONFIG_PHY_MESON_AXG_PCIE                       policy<{'arm64': '-'}>
+CONFIG_PHY_MESON_G12A_MIPI_DPHY_ANALOG          policy<{'arm64': '-'}>
+CONFIG_PHY_MESON_G12A_USB2                      policy<{'arm64': '-'}>
+CONFIG_PHY_MESON_G12A_USB3_PCIE                 policy<{'arm64': '-'}>
+CONFIG_PHY_MESON_GXL_USB2                       policy<{'arm64': '-'}>
+CONFIG_PHY_MIXEL_LVDS_PHY                       policy<{'arm64': '-'}>
+CONFIG_PHY_MIXEL_MIPI_DPHY                      policy<{'arm64': '-'}>
+CONFIG_PHY_MTK_DP                               policy<{'arm64': '-'}>
+CONFIG_PHY_MTK_HDMI                             policy<{'arm64': '-'}>
+CONFIG_PHY_MTK_MIPI_DSI                         policy<{'arm64': '-'}>
+CONFIG_PHY_MTK_PCIE                             policy<{'arm64': '-'}>
+CONFIG_PHY_MTK_TPHY                             policy<{'arm64': '-'}>
+CONFIG_PHY_MTK_UFS                              policy<{'arm64': '-'}>
+CONFIG_PHY_MTK_XSPHY                            policy<{'arm64': '-'}>
+CONFIG_PHY_MVEBU_A3700_COMPHY                   policy<{'arm64': '-'}>
+CONFIG_PHY_MVEBU_A3700_UTMI                     policy<{'arm64': '-'}>
+CONFIG_PHY_MVEBU_A38X_COMPHY                    policy<{'arm64': '-'}>
+CONFIG_PHY_MVEBU_CP110_COMPHY                   policy<{'arm64': '-'}>
+CONFIG_PHY_MVEBU_CP110_UTMI                     policy<{'arm64': '-'}>
+CONFIG_PHY_NXP_PTN3222                          policy<{'arm64': 'n'}>
+CONFIG_PHY_QCOM_QMP                             policy<{'arm64': 'y'}>
+CONFIG_PHY_QCOM_QMP_PCIE                        policy<{'arm64': 'y'}>
+CONFIG_PHY_QCOM_QMP_PCIE_8996                   policy<{'arm64': 'y'}>
+CONFIG_PHY_QCOM_QMP_UFS                         policy<{'arm64': 'y'}>
+CONFIG_PHY_QCOM_QMP_USB                         policy<{'arm64': 'y'}>
+CONFIG_PHY_QCOM_USB_SNPS_FEMTO_V2               policy<{'arm64': 'y'}>
+CONFIG_PHY_R8A779F0_ETHERNET_SERDES             policy<{'arm64': '-'}>
+CONFIG_PHY_RCAR_GEN2                            policy<{'arm64': '-'}>
+CONFIG_PHY_RCAR_GEN3_PCIE                       policy<{'arm64': '-'}>
+CONFIG_PHY_RCAR_GEN3_USB2                       policy<{'arm64': '-'}>
+CONFIG_PHY_RCAR_GEN3_USB3                       policy<{'arm64': '-'}>
+CONFIG_PHY_ROCKCHIP_DP                          policy<{'arm64': '-'}>
+CONFIG_PHY_ROCKCHIP_DPHY_RX0                    policy<{'arm64': '-'}>
+CONFIG_PHY_ROCKCHIP_EMMC                        policy<{'arm64': '-'}>
+CONFIG_PHY_ROCKCHIP_INNO_CSIDPHY                policy<{'arm64': '-'}>
+CONFIG_PHY_ROCKCHIP_INNO_DSIDPHY                policy<{'arm64': '-'}>
+CONFIG_PHY_ROCKCHIP_INNO_HDMI                   policy<{'arm64': '-'}>
+CONFIG_PHY_ROCKCHIP_INNO_USB2                   policy<{'arm64': '-'}>
+CONFIG_PHY_ROCKCHIP_NANENG_COMBO_PHY            policy<{'arm64': '-'}>
+CONFIG_PHY_ROCKCHIP_PCIE                        policy<{'arm64': '-'}>
+CONFIG_PHY_ROCKCHIP_SNPS_PCIE3                  policy<{'arm64': '-'}>
+CONFIG_PHY_ROCKCHIP_TYPEC                       policy<{'arm64': '-'}>
+CONFIG_PHY_ROCKCHIP_USB                         policy<{'arm64': '-'}>
+CONFIG_PHY_SPARX5_SERDES                        policy<{'arm64': '-'}>
+CONFIG_PHY_STM32_USBPHYC                        policy<{'arm64': '-'}>
+CONFIG_PHY_SUN4I_USB                            policy<{'arm64': '-'}>
+CONFIG_PHY_SUN50I_USB3                          policy<{'arm64': '-'}>
+CONFIG_PHY_SUN6I_MIPI_DPHY                      policy<{'arm64': '-'}>
+CONFIG_PHY_SUN9I_USB                            policy<{'arm64': '-'}>
+CONFIG_PHY_TEGRA194_P2U                         policy<{'arm64': '-'}>
+CONFIG_PHY_TEGRA_XUSB                           policy<{'arm64': '-'}>
+CONFIG_PHY_TI_GMII_SEL                          policy<{'arm64': '-'}>
+CONFIG_PHY_XGENE                                policy<{'arm64': '-'}>
+CONFIG_PHY_XILINX_ZYNQMP                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_AC5                              policy<{'arm64': '-'}>
+CONFIG_PINCTRL_AMLOGIC_C3                       policy<{'arm64': '-'}>
+CONFIG_PINCTRL_AMLOGIC_T7                       policy<{'arm64': '-'}>
+CONFIG_PINCTRL_APPLE_GPIO                       policy<{'arm64': '-'}>
+CONFIG_PINCTRL_ARMADA_37XX                      policy<{'arm64': '-'}>
+CONFIG_PINCTRL_ARMADA_AP806                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_ARMADA_CP110                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_AS370                            policy<{'arm64': '-'}>
+CONFIG_PINCTRL_BERLIN                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_BERLIN_BG4CT                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_BM1880                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_IMX                              policy<{'arm64': '-'}>
+CONFIG_PINCTRL_IMX8DXL                          policy<{'arm64': '-'}>
+CONFIG_PINCTRL_IMX8MM                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_IMX8MN                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_IMX8MP                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_IMX8MQ                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_IMX8QM                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_IMX8QXP                          policy<{'arm64': '-'}>
+CONFIG_PINCTRL_IMX8ULP                          policy<{'arm64': '-'}>
+CONFIG_PINCTRL_IMX93                            policy<{'arm64': '-'}>
+CONFIG_PINCTRL_IMXRT1050                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_IMXRT1170                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_IMX_SCU                          policy<{'arm64': '-'}>
+CONFIG_PINCTRL_IPQ5332                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_IPQ6018                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_IPQ8074                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_IPQ9574                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_KEEMBAY                          policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MESON                            policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MESON8_PMX                       policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MESON_A1                         policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MESON_AXG                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MESON_AXG_PMX                    policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MESON_G12A                       policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MESON_GXBB                       policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MESON_GXL                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MESON_S4                         policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MSM8916                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MSM8953                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MSM8976                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MSM8994                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MSM8996                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MSM8998                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_MT2712                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT6397                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT6765                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT6779                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT6795                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT6797                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT7622                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT7981                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT7986                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT8167                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT8173                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT8183                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT8186                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT8188                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT8192                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT8195                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT8365                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MT8516                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MTK                              policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MTK_MOORE                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MTK_PARIS                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MTK_V2                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_MVEBU                            policy<{'arm64': '-'}>
+CONFIG_PINCTRL_NPCM8XX                          policy<{'arm64': '-'}>
+CONFIG_PINCTRL_OWL                              policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A774A1                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A774B1                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A774C0                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A774E1                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A77951                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A77960                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A77961                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A77965                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A77970                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A77980                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A77990                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A77995                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A779A0                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A779F0                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_PFC_R8A779G0                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_QCM2290                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_QCOM_SPMI_PMIC                   policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_QCS404                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_QCS615                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_QCS8300                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_QCS8300_LPASS_LPI                policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_QDF2XXX                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_QDU1000                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_RENESAS                          policy<{'arm64': '-'}>
+CONFIG_PINCTRL_ROCKCHIP                         policy<{'arm64': '-'}>
+CONFIG_PINCTRL_RTD                              policy<{'arm64': '-'}>
+CONFIG_PINCTRL_RTD1315E                         policy<{'arm64': '-'}>
+CONFIG_PINCTRL_RTD1319D                         policy<{'arm64': '-'}>
+CONFIG_PINCTRL_RTD1619B                         policy<{'arm64': '-'}>
+CONFIG_PINCTRL_RZG2L                            policy<{'arm64': '-'}>
+CONFIG_PINCTRL_RZV2M                            policy<{'arm64': '-'}>
+CONFIG_PINCTRL_S32CC                            policy<{'arm64': '-'}>
+CONFIG_PINCTRL_S32G2                            policy<{'arm64': '-'}>
+CONFIG_PINCTRL_S700                             policy<{'arm64': '-'}>
+CONFIG_PINCTRL_S900                             policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SA7255P                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SA8775P                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SA8775P_LPASS_LPI                policy<{'arm64': 'm'}>
+CONFIG_PINCTRL_SA8797P                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SC7180                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SC7280                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SC8180X                          policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SC8280XP                         policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SDM660                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SDM670                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SDM845                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SH_PFC                           policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SM6115                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SM6125                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SM6350                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SM6375                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SM8150                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SM8250                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SM8350                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SM8450                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SM8550                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SM8650                           policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_SPRD                             policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SPRD_SC9860                      policy<{'arm64': '-'}>
+CONFIG_PINCTRL_STM32                            policy<{'arm64': '-'}>
+CONFIG_PINCTRL_STM32MP257                       policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN20I_D1                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN4I_A10                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN50I_A100                      policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN50I_A100_R                    policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN50I_A64                       policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN50I_A64_R                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN50I_H5                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN50I_H6                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN50I_H616                      policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN50I_H616_R                    policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN50I_H6_R                      policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN5I                            policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN6I_A31                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN6I_A31_R                      policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN8I_A23                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN8I_A23_R                      policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN8I_A33                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN8I_A83T                       policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN8I_A83T_R                     policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN8I_H3                         policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN8I_H3_R                       policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN8I_V3S                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN9I_A80                        policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUN9I_A80_R                      policy<{'arm64': '-'}>
+CONFIG_PINCTRL_SUNXI                            policy<{'arm64': '-'}>
+CONFIG_PINCTRL_TEGRA                            policy<{'arm64': '-'}>
+CONFIG_PINCTRL_TEGRA124                         policy<{'arm64': '-'}>
+CONFIG_PINCTRL_TEGRA194                         policy<{'arm64': '-'}>
+CONFIG_PINCTRL_TEGRA210                         policy<{'arm64': '-'}>
+CONFIG_PINCTRL_TEGRA234                         policy<{'arm64': '-'}>
+CONFIG_PINCTRL_TEGRA_XUSB                       policy<{'arm64': '-'}>
+CONFIG_PINCTRL_TMPV7700                         policy<{'arm64': '-'}>
+CONFIG_PINCTRL_VISCONTI                         policy<{'arm64': '-'}>
+CONFIG_PINCTRL_X1E80100                         policy<{'arm64': 'y'}>
+CONFIG_PINCTRL_ZYNQMP                           policy<{'arm64': '-'}>
+CONFIG_PM_AUTOSLEEP                             policy<{'arm64': 'y'}>
+CONFIG_PM_WAKELOCKS_LIMIT                       policy<{'arm64': '0'}>
+CONFIG_POWER_RESET_HISI                         policy<{'arm64': '-'}>
+CONFIG_POWER_RESET_LINKSTATION                  policy<{'arm64': '-'}>
+CONFIG_POWER_RESET_OCELOT_RESET                 policy<{'arm64': '-'}>
+CONFIG_POWER_RESET_ODROID_GO_ULTRA_POWEROFF     policy<{'arm64': '-'}>
+CONFIG_POWER_RESET_SC27XX                       policy<{'arm64': '-'}>
+CONFIG_POWER_SEQUENCING                         policy<{'arm64': 'm'}>
+CONFIG_POWER_SEQUENCING_QCOM_WCN                policy<{'arm64': 'm'}>
+CONFIG_PRU_REMOTEPROC                           policy<{'arm64': '-'}>
+CONFIG_PTP_QCOM_CLOCK_TSC                       policy<{'arm64': 'n'}>
+CONFIG_PWC_RZV2M                                policy<{'arm64': '-'}>
+CONFIG_PWM_APPLE                                policy<{'arm64': '-'}>
+CONFIG_PWM_BERLIN                               policy<{'arm64': '-'}>
+CONFIG_PWM_HIBVT                                policy<{'arm64': '-'}>
+CONFIG_PWM_IMX1                                 policy<{'arm64': '-'}>
+CONFIG_PWM_IMX27                                policy<{'arm64': '-'}>
+CONFIG_PWM_IMX_TPM                              policy<{'arm64': '-'}>
+CONFIG_PWM_KEEMBAY                              policy<{'arm64': '-'}>
+CONFIG_PWM_MEDIATEK                             policy<{'arm64': '-'}>
+CONFIG_PWM_MESON                                policy<{'arm64': '-'}>
+CONFIG_PWM_MTK_DISP                             policy<{'arm64': '-'}>
+CONFIG_PWM_OMAP_DMTIMER                         policy<{'arm64': '-'}>
+CONFIG_PWM_RCAR                                 policy<{'arm64': '-'}>
+CONFIG_PWM_RENESAS_TPU                          policy<{'arm64': '-'}>
+CONFIG_PWM_ROCKCHIP                             policy<{'arm64': '-'}>
+CONFIG_PWM_RZ_MTU3                              policy<{'arm64': '-'}>
+CONFIG_PWM_SL28CPLD                             policy<{'arm64': '-'}>
+CONFIG_PWM_SPRD                                 policy<{'arm64': '-'}>
+CONFIG_PWM_STM32                                policy<{'arm64': '-'}>
+CONFIG_PWM_STM32_LP                             policy<{'arm64': '-'}>
+CONFIG_PWM_SUN4I                                policy<{'arm64': '-'}>
+CONFIG_PWM_TEGRA                                policy<{'arm64': '-'}>
+CONFIG_PWM_TIECAP                               policy<{'arm64': '-'}>
+CONFIG_PWM_TIEHRPWM                             policy<{'arm64': '-'}>
+CONFIG_PWM_VISCONTI                             policy<{'arm64': '-'}>
+CONFIG_PXA168_ETH                               policy<{'arm64': '-'}>
+CONFIG_QCM_GCC_2290                             policy<{'arm64': 'y'}>
+CONFIG_QCOM_A53PLL                              policy<{'arm64': 'y'}>
+CONFIG_QCOM_AOSS_QMP                            policy<{'arm64': 'y'}>
+CONFIG_QCOM_APCS_IPC                            policy<{'arm64': 'y'}>
+CONFIG_QCOM_APR                                 policy<{'arm64': 'y'}>
+CONFIG_QCOM_BAM_DMA                             policy<{'arm64': 'y'}>
+CONFIG_QCOM_CLK_APCC_MSM8996                    policy<{'arm64': 'y'}>
+CONFIG_QCOM_CLK_APCS_MSM8916                    policy<{'arm64': 'y'}>
+CONFIG_QCOM_CLK_RPMH                            policy<{'arm64': 'y'}>
+CONFIG_QCOM_CLK_SMD_RPM                         policy<{'arm64': 'y'}>
+CONFIG_QCOM_CPR                                 policy<{'arm64': 'y'}>
+CONFIG_QCOM_CPUCP_MBOX                          policy<{'arm64': 'n'}>
+CONFIG_QCOM_DCC                                 policy<{'arm64': 'y'}>
+CONFIG_QCOM_DMABUF_HEAPS                        policy<{'arm64': 'y'}>
+CONFIG_QCOM_DMABUF_HEAPS_CARVEOUT               policy<{'arm64': 'n'}>
+CONFIG_QCOM_DMABUF_HEAPS_CMA                    policy<{'arm64': 'y'}>
+CONFIG_QCOM_DMABUF_HEAPS_PAGE_POOL_REFILL       policy<{'arm64': 'n'}>
+CONFIG_QCOM_DMABUF_HEAPS_SYSTEM                 policy<{'arm64': 'y'}>
+CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_SECURE          policy<{'arm64': 'y'}>
+CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_UNCACHED        policy<{'arm64': 'n'}>
+CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC            policy<{'arm64': 'y'}>
+CONFIG_QCOM_GENI_SE                             policy<{'arm64': 'y'}>
+CONFIG_QCOM_HFPLL                               policy<{'arm64': 'y'}>
+CONFIG_QCOM_HIDMA                               policy<{'arm64': 'y'}>
+CONFIG_QCOM_HIDMA_MGMT                          policy<{'arm64': 'y'}>
+CONFIG_QCOM_INLINE_CRYPTO_ENGINE                policy<{'arm64': 'y'}>
+CONFIG_QCOM_KVM_ENABLED                         policy<{'arm64': 'n'}>
+CONFIG_QCOM_MEMORY_DUMP_V2                      policy<{'arm64': 'y'}>
+CONFIG_QCOM_MEM_BUF                             policy<{'arm64': 'y'}>
+CONFIG_QCOM_MEM_BUF_DEV                         policy<{'arm64': 'y'}>
+CONFIG_QCOM_MINIDUMP                            policy<{'arm64': 'n'}>
+CONFIG_QCOM_MPM                                 policy<{'arm64': 'y'}>
+CONFIG_QCOM_PANEL_EVENT_NOTIFIER                policy<{'arm64': 'm'}>
+CONFIG_QCOM_PDR_HELPERS                         policy<{'arm64': 'y'}>
+CONFIG_QCOM_QMI_COOLING                         policy<{'arm64': 'm'}>
+CONFIG_QCOM_QMI_HELPERS                         policy<{'arm64': 'y'}>
+CONFIG_QCOM_QPS615_PCIE_SWITCH                  policy<{'arm64': 'y'}>
+CONFIG_QCOM_RPMPD                               policy<{'arm64': 'y'}>
+CONFIG_QCOM_RPROC_MINIDUMP                      policy<{'arm64': 'm'}>
+CONFIG_QCOM_SCM_ADDON                           policy<{'arm64': 'y'}>
+CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT           policy<{'arm64': '-'}>
+CONFIG_QCOM_SECURE_BUFFER                       policy<{'arm64': 'y'}>
+CONFIG_QCOM_SI_CORE                             policy<{'arm64': 'm'}>
+CONFIG_QCOM_SI_CORE_ADCI                        policy<{'arm64': 'n'}>
+CONFIG_QCOM_SI_CORE_MEM_OBJECT                  policy<{'arm64': 'm'}>
+CONFIG_QCOM_SI_CORE_WQ                          policy<{'arm64': 'y'}>
+CONFIG_QCOM_SI_CORE_XTS                         policy<{'arm64': 'm'}>
+CONFIG_QCOM_SMCINVOKE                           policy<{'arm64': '-'}>
+CONFIG_QCOM_SMD_RPM                             policy<{'arm64': 'y'}>
+CONFIG_QCOM_SMEM                                policy<{'arm64': 'y'}>
+CONFIG_QCOM_SMP2P                               policy<{'arm64': 'y'}>
+CONFIG_QCOM_SMP2P_SLEEPSTATE                    policy<{'arm64': 'm'}>
+CONFIG_QCOM_SMSM                                policy<{'arm64': 'y'}>
+CONFIG_QCOM_SOC_DEBUG                           policy<{'arm64': 'y'}>
+CONFIG_QCOM_SPMI_ADC5_GEN3                      policy<{'arm64': 'm'}>
+CONFIG_QCOM_SPMI_MBG_TM                         policy<{'arm64': 'm'}>
+CONFIG_QCOM_TZMEM                               policy<{'arm64': 'y'}>
+CONFIG_QCOM_TZMEM_MODE_GENERIC                  policy<{'arm64': 'n'}>
+CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE                policy<{'arm64': 'y'}>
+CONFIG_QCOM_WATCHDOG_BARK_TIME                  policy<{'arm64': '11000'}>
+CONFIG_QCOM_WATCHDOG_IPI_PING                   policy<{'arm64': 'y'}>
+CONFIG_QCOM_WATCHDOG_PET_TIME                   policy<{'arm64': '9360'}>
+CONFIG_QCOM_WDOG_BITE_EARLY_PANIC               policy<{'arm64': 'n'}>
+CONFIG_QCOM_WDT_CORE                            policy<{'arm64': 'y'}>
+CONFIG_QCS_CAMCC_615                            policy<{'arm64': 'm'}>
+CONFIG_QCS_DISPCC_615                           policy<{'arm64': 'm'}>
+CONFIG_QCS_GCC_404                              policy<{'arm64': 'y'}>
+CONFIG_QCS_GCC_615                              policy<{'arm64': 'y'}>
+CONFIG_QCS_GCC_8300                             policy<{'arm64': 'y'}>
+CONFIG_QCS_GPUCC_615                            policy<{'arm64': 'm'}>
+CONFIG_QCS_VIDEOCC_615                          policy<{'arm64': 'm'}>
+CONFIG_QORIQ_CPUFREQ                            policy<{'arm64': '-'}>
+CONFIG_QORIQ_THERMAL                            policy<{'arm64': '-'}>
+CONFIG_QTI_BCL_PMIC5                            policy<{'arm64': 'y'}>
+CONFIG_QTI_DEVFREQ_CDEV                         policy<{'arm64': 'm'}>
+CONFIG_QTI_TZ_LOG                               policy<{'arm64': 'm'}>
+CONFIG_RAVB                                     policy<{'arm64': '-'}>
+CONFIG_RCAR_DMAC                                policy<{'arm64': '-'}>
+CONFIG_RCAR_GEN3_THERMAL                        policy<{'arm64': '-'}>
+CONFIG_RCAR_REMOTEPROC                          policy<{'arm64': '-'}>
+CONFIG_RCAR_THERMAL                             policy<{'arm64': '-'}>
+CONFIG_RCU_CPU_STALL_TIMEOUT                    policy<{'arm64': '21'}>
+CONFIG_REGMAP_AC97                              policy<{'arm64': '-'}>
+CONFIG_REGMAP_SPMI                              policy<{'arm64': 'y'}>
+CONFIG_REGULATOR_ANATOP                         policy<{'arm64': '-'}>
+CONFIG_REGULATOR_DEBUG_CONTROL                  policy<{'arm64': 'y'}>
+CONFIG_REGULATOR_GPIO                           policy<{'arm64': 'y'}>
+CONFIG_REGULATOR_HI655X                         policy<{'arm64': '-'}>
+CONFIG_REGULATOR_MT6380                         policy<{'arm64': '-'}>
+CONFIG_REGULATOR_PROXY_CONSUMER                 policy<{'arm64': 'y'}>
+CONFIG_REGULATOR_PWM                            policy<{'arm64': 'y'}>
+CONFIG_REGULATOR_QCOM_PM8008                    policy<{'arm64': 'y'}>
+CONFIG_REGULATOR_QCOM_REFGEN                    policy<{'arm64': 'y'}>
+CONFIG_REGULATOR_QCOM_RPMH                      policy<{'arm64': 'y'}>
+CONFIG_REGULATOR_QCOM_SMD_RPM                   policy<{'arm64': 'y'}>
+CONFIG_REGULATOR_QCOM_SPMI                      policy<{'arm64': 'y'}>
+CONFIG_REGULATOR_QPNP_LCDB                      policy<{'arm64': 'y'}>
+CONFIG_REGULATOR_SC2731                         policy<{'arm64': '-'}>
+CONFIG_REGULATOR_STM32_BOOSTER                  policy<{'arm64': '-'}>
+CONFIG_REGULATOR_STM32_PWR                      policy<{'arm64': '-'}>
+CONFIG_REGULATOR_STM32_VREFBUF                  policy<{'arm64': '-'}>
+CONFIG_RENESAS_DMA                              policy<{'arm64': '-'}>
+CONFIG_RENESAS_ETHER_SWITCH                     policy<{'arm64': '-'}>
+CONFIG_RENESAS_GEN4_PTP                         policy<{'arm64': '-'}>
+CONFIG_RENESAS_IRQC                             policy<{'arm64': '-'}>
+CONFIG_RENESAS_OSTM                             policy<{'arm64': '-'}>
+CONFIG_RENESAS_RPCIF                            policy<{'arm64': '-'}>
+CONFIG_RENESAS_RZAWDT                           policy<{'arm64': '-'}>
+CONFIG_RENESAS_RZG2LWDT                         policy<{'arm64': '-'}>
+CONFIG_RENESAS_RZG2L_IRQC                       policy<{'arm64': '-'}>
+CONFIG_RENESAS_RZN1WDT                          policy<{'arm64': '-'}>
+CONFIG_RENESAS_USB_DMAC                         policy<{'arm64': '-'}>
+CONFIG_RENESAS_WDT                              policy<{'arm64': '-'}>
+CONFIG_RESET_A10SR                              policy<{'arm64': '-'}>
+CONFIG_RESET_BERLIN                             policy<{'arm64': '-'}>
+CONFIG_RESET_HISI                               policy<{'arm64': '-'}>
+CONFIG_RESET_IMX7                               policy<{'arm64': '-'}>
+CONFIG_RESET_MCHP_SPARX5                        policy<{'arm64': '-'}>
+CONFIG_RESET_MESON                              policy<{'arm64': '-'}>
+CONFIG_RESET_MESON_AUDIO_ARB                    policy<{'arm64': '-'}>
+CONFIG_RESET_NPCM                               policy<{'arm64': '-'}>
+CONFIG_RESET_NUVOTON_MA35D1                     policy<{'arm64': '-'}>
+CONFIG_RESET_RZG2L_USBPHY_CTRL                  policy<{'arm64': '-'}>
+CONFIG_RESET_SUNXI                              policy<{'arm64': '-'}>
+CONFIG_RESET_TEGRA_BPMP                         policy<{'arm64': '-'}>
+CONFIG_RESET_TI_SCI                             policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_ANALOGIX_DP                     policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_CDN_DP                          policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_DTPM                            policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_DW_HDMI                         policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_DW_MIPI_DSI                     policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_GRF                             policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_INNO_HDMI                       policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_IODOMAIN                        policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_IOMMU                           policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_LVDS                            policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_MBOX                            policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_PM_DOMAINS                      policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_RGB                             policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_RK3066_HDMI                     policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_SARADC                          policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_THERMAL                         policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_TIMER                           policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_VOP                             policy<{'arm64': '-'}>
+CONFIG_ROCKCHIP_VOP2                            policy<{'arm64': '-'}>
+CONFIG_RPMSG                                    policy<{'arm64': 'y'}>
+CONFIG_RPMSG_MTK_SCP                            policy<{'arm64': '-'}>
+CONFIG_RPMSG_QCOM_GLINK                         policy<{'arm64': 'y'}>
+CONFIG_RPMSG_QCOM_GLINK_RPM                     policy<{'arm64': 'y'}>
+CONFIG_RPMSG_QCOM_SMD                           policy<{'arm64': 'y'}>
+CONFIG_RST_RCAR                                 policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_ARMADA38X                        policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_BBNSM                            policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_FSL_FTM_ALARM                    policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_IMXDI                            policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_IMX_SC                           policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_MA35D1                           policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_MESON_VRTC                       policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_MT2712                           policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_MT7622                           policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_MV                               policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_MXC                              policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_MXC_V2                           policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_RTD119X                          policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_SC27XX                           policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_SH                               policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_SNVS                             policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_STM32                            policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_SUN6I                            policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_TEGRA                            policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_TI_K3                            policy<{'arm64': '-'}>
+CONFIG_RTC_DRV_XGENE                            policy<{'arm64': '-'}>
+CONFIG_RTD119X_WATCHDOG                         policy<{'arm64': '-'}>
+CONFIG_RZG2L_ADC                                policy<{'arm64': '-'}>
+CONFIG_RZG2L_THERMAL                            policy<{'arm64': '-'}>
+CONFIG_RZ_DMAC                                  policy<{'arm64': '-'}>
+CONFIG_RZ_MTU3                                  policy<{'arm64': '-'}>
+CONFIG_RZ_MTU3_CNT                              policy<{'arm64': '-'}>
+CONFIG_SATA_AHCI_SEATTLE                        policy<{'arm64': '-'}>
+CONFIG_SATA_RCAR                                policy<{'arm64': '-'}>
+CONFIG_SA_CAMCC_8775P                           policy<{'arm64': 'm'}>
+CONFIG_SA_DISPCC_8775P                          policy<{'arm64': 'm'}>
+CONFIG_SA_GCC_8775P                             policy<{'arm64': 'y'}>
+CONFIG_SA_VIDEOCC_8775P                         policy<{'arm64': 'm'}>
+CONFIG_SC27XX_ADC                               policy<{'arm64': '-'}>
+CONFIG_SCREEN_INFO                              policy<{'arm64': '-'}>
+CONFIG_SCSI_UFSHCD                              policy<{'arm64': 'y'}>
+CONFIG_SCSI_UFSHCD_PLATFORM                     policy<{'arm64': 'y'}>
+CONFIG_SCSI_UFS_HISI                            policy<{'arm64': '-'}>
+CONFIG_SCSI_UFS_MEDIATEK                        policy<{'arm64': '-'}>
+CONFIG_SCSI_UFS_QCOM                            policy<{'arm64': 'y'}>
+CONFIG_SCSI_UFS_RENESAS                         policy<{'arm64': '-'}>
+CONFIG_SCSI_UFS_SPRD                            policy<{'arm64': '-'}>
+CONFIG_SCSI_UFS_TI_J721E                        policy<{'arm64': '-'}>
+CONFIG_SC_CAMCC_7280                            policy<{'arm64': 'y'}>
+CONFIG_SC_DISPCC_7280                           policy<{'arm64': 'y'}>
+CONFIG_SC_GCC_7180                              policy<{'arm64': 'y'}>
+CONFIG_SC_GCC_7280                              policy<{'arm64': 'y'}>
+CONFIG_SC_GCC_8180X                             policy<{'arm64': 'y'}>
+CONFIG_SC_GCC_8280XP                            policy<{'arm64': 'y'}>
+CONFIG_SC_GPUCC_7280                            policy<{'arm64': 'y'}>
+CONFIG_SC_LPASS_CORECC_7280                     policy<{'arm64': 'y'}>
+CONFIG_SC_VIDEOCC_7280                          policy<{'arm64': 'y'}>
+CONFIG_SDM_DISPCC_845                           policy<{'arm64': 'y'}>
+CONFIG_SDM_GCC_845                              policy<{'arm64': 'y'}>
+CONFIG_SDM_GPUCC_845                            policy<{'arm64': 'y'}>
+CONFIG_SDM_VIDEOCC_845                          policy<{'arm64': 'y'}>
+CONFIG_SENSORS_EMC2305                          policy<{'arm64': 'y'}>
+CONFIG_SENSORS_SL28CPLD                         policy<{'arm64': '-'}>
+CONFIG_SENSORS_SPARX5                           policy<{'arm64': '-'}>
+CONFIG_SERIAL_8250_EM                           policy<{'arm64': '-'}>
+CONFIG_SERIAL_8250_EXAR                         policy<{'arm64': 'y'}>
+CONFIG_SERIAL_8250_MT6577                       policy<{'arm64': '-'}>
+CONFIG_SERIAL_8250_OMAP                         policy<{'arm64': '-'}>
+CONFIG_SERIAL_8250_OMAP_TTYO_FIXUP              policy<{'arm64': '-'}>
+CONFIG_SERIAL_8250_PERICOM                      policy<{'arm64': 'y'}>
+CONFIG_SERIAL_8250_TEGRA                        policy<{'arm64': '-'}>
+CONFIG_SERIAL_FSL_LINFLEXUART                   policy<{'arm64': 'y'}>
+CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE           policy<{'arm64': 'y'}>
+CONFIG_SERIAL_FSL_LPUART                        policy<{'arm64': 'y'}>
+CONFIG_SERIAL_FSL_LPUART_CONSOLE                policy<{'arm64': 'y'}>
+CONFIG_SERIAL_IMX                               policy<{'arm64': '-'}>
+CONFIG_SERIAL_IMX_CONSOLE                       policy<{'arm64': '-'}>
+CONFIG_SERIAL_IMX_EARLYCON                      policy<{'arm64': '-'}>
+CONFIG_SERIAL_MESON                             policy<{'arm64': '-'}>
+CONFIG_SERIAL_MESON_CONSOLE                     policy<{'arm64': '-'}>
+CONFIG_SERIAL_MVEBU_CONSOLE                     policy<{'arm64': '-'}>
+CONFIG_SERIAL_MVEBU_UART                        policy<{'arm64': '-'}>
+CONFIG_SERIAL_NUVOTON_MA35D1                    policy<{'arm64': '-'}>
+CONFIG_SERIAL_OWL                               policy<{'arm64': '-'}>
+CONFIG_SERIAL_OWL_CONSOLE                       policy<{'arm64': '-'}>
+CONFIG_SERIAL_QCOM_GENI                         policy<{'arm64': 'y'}>
+CONFIG_SERIAL_SAMSUNG                           policy<{'arm64': '-'}>
+CONFIG_SERIAL_SAMSUNG_CONSOLE                   policy<{'arm64': '-'}>
+CONFIG_SERIAL_SAMSUNG_UARTS                     policy<{'arm64': '-'}>
+CONFIG_SERIAL_SH_SCI_DMA                        policy<{'arm64': '-'}>
+CONFIG_SERIAL_SH_SCI_NR_UARTS                   policy<{'arm64': '-'}>
+CONFIG_SERIAL_STM32                             policy<{'arm64': '-'}>
+CONFIG_SERIAL_TEGRA                             policy<{'arm64': '-'}>
+CONFIG_SERIAL_TEGRA_TCU                         policy<{'arm64': '-'}>
+CONFIG_SERIAL_TEGRA_TCU_CONSOLE                 policy<{'arm64': '-'}>
+CONFIG_SERIAL_XILINX_PS_UART                    policy<{'arm64': 'y'}>
+CONFIG_SERIAL_XILINX_PS_UART_CONSOLE            policy<{'arm64': 'y'}>
+CONFIG_SERIO_AMBAKMI                            policy<{'arm64': 'y'}>
+CONFIG_SERIO_NVEC_PS2                           policy<{'arm64': '-'}>
+CONFIG_SERIO_SUN4I_PS2                          policy<{'arm64': '-'}>
+CONFIG_SH_ETH                                   policy<{'arm64': '-'}>
+CONFIG_SH_TIMER_CMT                             policy<{'arm64': '-'}>
+CONFIG_SH_TIMER_TMU                             policy<{'arm64': '-'}>
+CONFIG_SL28CPLD_WATCHDOG                        policy<{'arm64': '-'}>
+CONFIG_SLIC_DS26522                             policy<{'arm64': '-'}>
+CONFIG_SM_CAMCC_7150                            policy<{'arm64': 'n'}>
+CONFIG_SM_DISPCC_7150                           policy<{'arm64': 'n'}>
+CONFIG_SM_DISPCC_8250                           policy<{'arm64': 'y'}>
+CONFIG_SM_DISPCC_8650                           policy<{'arm64': 'y'}>
+CONFIG_SM_GCC_6115                              policy<{'arm64': 'y'}>
+CONFIG_SM_GCC_8150                              policy<{'arm64': 'y'}>
+CONFIG_SM_GCC_8250                              policy<{'arm64': 'y'}>
+CONFIG_SM_GCC_8350                              policy<{'arm64': 'y'}>
+CONFIG_SM_GCC_8450                              policy<{'arm64': 'y'}>
+CONFIG_SM_GCC_8550                              policy<{'arm64': 'y'}>
+CONFIG_SM_GCC_8650                              policy<{'arm64': 'y'}>
+CONFIG_SM_GPUCC_8150                            policy<{'arm64': 'y'}>
+CONFIG_SM_GPUCC_8250                            policy<{'arm64': 'y'}>
+CONFIG_SM_GPUCC_8650                            policy<{'arm64': 'y'}>
+CONFIG_SM_TCSRCC_8550                           policy<{'arm64': 'y'}>
+CONFIG_SM_TCSRCC_8650                           policy<{'arm64': 'y'}>
+CONFIG_SM_VIDEOCC_7150                          policy<{'arm64': 'n'}>
+CONFIG_SM_VIDEOCC_8250                          policy<{'arm64': 'y'}>
+CONFIG_SND_HDA_ALIGNED_MMIO                     policy<{'arm64': '-'}>
+CONFIG_SND_HDA_TEGRA                            policy<{'arm64': '-'}>
+CONFIG_SND_IMX_SOC                              policy<{'arm64': '-'}>
+CONFIG_SND_KIRKWOOD_SOC                         policy<{'arm64': '-'}>
+CONFIG_SND_KIRKWOOD_SOC_ARMADA370_DB            policy<{'arm64': '-'}>
+CONFIG_SND_MESON_AIU                            policy<{'arm64': '-'}>
+CONFIG_SND_MESON_AXG_FIFO                       policy<{'arm64': '-'}>
+CONFIG_SND_MESON_AXG_FRDDR                      policy<{'arm64': '-'}>
+CONFIG_SND_MESON_AXG_PDM                        policy<{'arm64': '-'}>
+CONFIG_SND_MESON_AXG_SOUND_CARD                 policy<{'arm64': '-'}>
+CONFIG_SND_MESON_AXG_SPDIFIN                    policy<{'arm64': '-'}>
+CONFIG_SND_MESON_AXG_SPDIFOUT                   policy<{'arm64': '-'}>
+CONFIG_SND_MESON_AXG_TDMIN                      policy<{'arm64': '-'}>
+CONFIG_SND_MESON_AXG_TDMOUT                     policy<{'arm64': '-'}>
+CONFIG_SND_MESON_AXG_TDM_FORMATTER              policy<{'arm64': '-'}>
+CONFIG_SND_MESON_AXG_TDM_INTERFACE              policy<{'arm64': '-'}>
+CONFIG_SND_MESON_AXG_TODDR                      policy<{'arm64': '-'}>
+CONFIG_SND_MESON_CARD_UTILS                     policy<{'arm64': '-'}>
+CONFIG_SND_MESON_CODEC_GLUE                     policy<{'arm64': '-'}>
+CONFIG_SND_MESON_G12A_TOACODEC                  policy<{'arm64': '-'}>
+CONFIG_SND_MESON_G12A_TOHDMITX                  policy<{'arm64': '-'}>
+CONFIG_SND_MESON_GX_SOUND_CARD                  policy<{'arm64': '-'}>
+CONFIG_SND_SOC_ALC5632                          policy<{'arm64': '-'}>
+CONFIG_SND_SOC_APPLE_MCA                        policy<{'arm64': '-'}>
+CONFIG_SND_SOC_AUDIO_PKT                        policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_DAVINCI_MCASP                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_FSL_ASOC_CARD                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_FSL_AUD2HTX                      policy<{'arm64': '-'}>
+CONFIG_SND_SOC_IMX_AUDIO_RPMSG                  policy<{'arm64': '-'}>
+CONFIG_SND_SOC_IMX_AUDMIX                       policy<{'arm64': '-'}>
+CONFIG_SND_SOC_IMX_CARD                         policy<{'arm64': '-'}>
+CONFIG_SND_SOC_IMX_ES8328                       policy<{'arm64': '-'}>
+CONFIG_SND_SOC_IMX_HDMI                         policy<{'arm64': '-'}>
+CONFIG_SND_SOC_IMX_PCM_DMA                      policy<{'arm64': '-'}>
+CONFIG_SND_SOC_IMX_PCM_RPMSG                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_IMX_RPMSG                        policy<{'arm64': '-'}>
+CONFIG_SND_SOC_IMX_SGTL5000                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_IMX_SPDIF                        policy<{'arm64': '-'}>
+CONFIG_SND_SOC_INTEL_KEEMBAY                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_J721E_EVM                        policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MEDIATEK                         policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MESON_T9015                      policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MSM_AUDIO_MEM                    policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_MSM_STUB                         policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_MT2701                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT6359                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT6359_ACCDET                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT6797                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT6797_MT6351                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT7986                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT7986_WM8960                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT8173                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT8183                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT8183_DA7219_MAX98357A          policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT8183_MT6358_TS3A227E_MAX98357A policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT8186                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT8186_MT6366_DA7219_MAX98357    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT8186_MT6366_RT1019_RT5682S     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT8188                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT8188_MT6359                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT8192                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT8192_MT6359_RT1015_RT5682      policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT8195                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_MT8195_MT6359                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_NAU8825                          policy<{'arm64': '-'}>
+CONFIG_SND_SOC_QCM6490                          policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_QCS9100                          policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_RCAR                             policy<{'arm64': '-'}>
+CONFIG_SND_SOC_RK3288_HDMI_ANALOG               policy<{'arm64': '-'}>
+CONFIG_SND_SOC_RK3399_GRU_SOUND                 policy<{'arm64': '-'}>
+CONFIG_SND_SOC_ROCKCHIP                         policy<{'arm64': '-'}>
+CONFIG_SND_SOC_ROCKCHIP_I2S                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_ROCKCHIP_I2S_TDM                 policy<{'arm64': '-'}>
+CONFIG_SND_SOC_ROCKCHIP_MAX98090                policy<{'arm64': '-'}>
+CONFIG_SND_SOC_ROCKCHIP_PDM                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_ROCKCHIP_RT5645                  policy<{'arm64': '-'}>
+CONFIG_SND_SOC_ROCKCHIP_SPDIF                   policy<{'arm64': '-'}>
+CONFIG_SND_SOC_RT1011                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_RT1015                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_RT1015P                          policy<{'arm64': '-'}>
+CONFIG_SND_SOC_RT5514                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_RT5514_SPI                       policy<{'arm64': '-'}>
+CONFIG_SND_SOC_RT5677                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_RT5677_SPI                       policy<{'arm64': '-'}>
+CONFIG_SND_SOC_RZ                               policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SH4_FSI                          policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SOF                              policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SOF_COMPRESS                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SOF_DEVELOPER_SUPPORT            policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SOF_IMX8                         policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SOF_IMX8M                        policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SOF_IMX8ULP                      policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SOF_IMX_COMMON                   policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SOF_IPC3                         policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SOF_MT8186                       policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SOF_MT8195                       policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SOF_MTK_COMMON                   policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SOF_OF_DEV                       policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SOF_XTENSA                       policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SPF_CORE                         policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_SPRD                             policy<{'arm64': '-'}>
+CONFIG_SND_SOC_SPRD_MCDT                        policy<{'arm64': '-'}>
+CONFIG_SND_SOC_STM32_DFSDM                      policy<{'arm64': '-'}>
+CONFIG_SND_SOC_STM32_I2S                        policy<{'arm64': '-'}>
+CONFIG_SND_SOC_STM32_SAI                        policy<{'arm64': '-'}>
+CONFIG_SND_SOC_STM32_SPDIFRX                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA                            policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA186_ASRC                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA186_DSPK                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA20_AC97                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA20_DAS                      policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA20_I2S                      policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA20_SPDIF                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA210_ADMAIF                  policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA210_ADX                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA210_AHUB                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA210_AMX                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA210_DMIC                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA210_I2S                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA210_MIXER                   policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA210_MVC                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA210_OPE                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA210_SFC                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA30_AHUB                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA30_I2S                      policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA_ALC5632                    policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA_AUDIO_GRAPH_CARD           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA_MACHINE_DRV                policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA_MAX98088                   policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA_MAX98090                   policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA_RT5631                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA_RT5640                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA_RT5677                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA_SGTL5000                   policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA_TRIMSLICE                  policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA_WM8753                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA_WM8903                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TEGRA_WM9712                     policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TI_EDMA_PCM                      policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TI_SDMA_PCM                      policy<{'arm64': '-'}>
+CONFIG_SND_SOC_TI_UDMA_PCM                      policy<{'arm64': '-'}>
+CONFIG_SND_SOC_WCD937X                          policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_WCD937X_SDW                      policy<{'arm64': 'm'}>
+CONFIG_SND_SOC_WM8994                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_WM9712                           policy<{'arm64': '-'}>
+CONFIG_SND_SOC_WM_HUBS                          policy<{'arm64': '-'}>
+CONFIG_SND_SUN4I_CODEC                          policy<{'arm64': '-'}>
+CONFIG_SND_SUN4I_I2S                            policy<{'arm64': '-'}>
+CONFIG_SND_SUN4I_SPDIF                          policy<{'arm64': '-'}>
+CONFIG_SND_SUN50I_CODEC_ANALOG                  policy<{'arm64': '-'}>
+CONFIG_SND_SUN50I_DMIC                          policy<{'arm64': '-'}>
+CONFIG_SND_SUN8I_ADDA_PR_REGMAP                 policy<{'arm64': '-'}>
+CONFIG_SND_SUN8I_CODEC                          policy<{'arm64': '-'}>
+CONFIG_SND_SUN8I_CODEC_ANALOG                   policy<{'arm64': '-'}>
+CONFIG_SNI_NETSEC                               policy<{'arm64': '-'}>
+CONFIG_SOCFPGA_FPGA_BRIDGE                      policy<{'arm64': '-'}>
+CONFIG_SOC_IMX8M                                policy<{'arm64': '-'}>
+CONFIG_SOC_IMX9                                 policy<{'arm64': '-'}>
+CONFIG_SOC_RENESAS                              policy<{'arm64': '-'}>
+CONFIG_SOC_TEGRA_CBB                            policy<{'arm64': '-'}>
+CONFIG_SOC_TEGRA_FLOWCTRL                       policy<{'arm64': '-'}>
+CONFIG_SOC_TEGRA_FUSE                           policy<{'arm64': '-'}>
+CONFIG_SOC_TEGRA_PMC                            policy<{'arm64': '-'}>
+CONFIG_SOC_TEGRA_POWERGATE_BPMP                 policy<{'arm64': '-'}>
+CONFIG_SPARX5_DCB                               policy<{'arm64': '-'}>
+CONFIG_SPARX5_SWITCH                            policy<{'arm64': '-'}>
+CONFIG_SPI_AMLOGIC_SPIFC_A1                     policy<{'arm64': '-'}>
+CONFIG_SPI_ARMADA_3700                          policy<{'arm64': '-'}>
+CONFIG_SPI_FSL_DSPI                             policy<{'arm64': '-'}>
+CONFIG_SPI_FSL_LPSPI                            policy<{'arm64': '-'}>
+CONFIG_SPI_FSL_QUADSPI                          policy<{'arm64': '-'}>
+CONFIG_SPI_HISI_SFC                             policy<{'arm64': '-'}>
+CONFIG_SPI_IMX                                  policy<{'arm64': '-'}>
+CONFIG_SPI_MESON_SPICC                          policy<{'arm64': '-'}>
+CONFIG_SPI_MESON_SPIFC                          policy<{'arm64': '-'}>
+CONFIG_SPI_MT65XX                               policy<{'arm64': '-'}>
+CONFIG_SPI_MTK_NOR                              policy<{'arm64': '-'}>
+CONFIG_SPI_MTK_SNFI                             policy<{'arm64': '-'}>
+CONFIG_SPI_NPCM_FIU                             policy<{'arm64': '-'}>
+CONFIG_SPI_NPCM_PSPI                            policy<{'arm64': '-'}>
+CONFIG_SPI_NXP_FLEXSPI                          policy<{'arm64': '-'}>
+CONFIG_SPI_OMAP24XX                             policy<{'arm64': '-'}>
+CONFIG_SPI_ORION                                policy<{'arm64': '-'}>
+CONFIG_SPI_QUP                                  policy<{'arm64': 'y'}>
+CONFIG_SPI_ROCKCHIP                             policy<{'arm64': '-'}>
+CONFIG_SPI_ROCKCHIP_SFC                         policy<{'arm64': '-'}>
+CONFIG_SPI_RPCIF                                policy<{'arm64': '-'}>
+CONFIG_SPI_RSPI                                 policy<{'arm64': '-'}>
+CONFIG_SPI_RZV2M_CSI                            policy<{'arm64': '-'}>
+CONFIG_SPI_SH_HSPI                              policy<{'arm64': '-'}>
+CONFIG_SPI_SH_MSIOF                             policy<{'arm64': '-'}>
+CONFIG_SPI_SLAVE_MT27XX                         policy<{'arm64': '-'}>
+CONFIG_SPI_SPRD                                 policy<{'arm64': '-'}>
+CONFIG_SPI_SPRD_ADI                             policy<{'arm64': '-'}>
+CONFIG_SPI_STM32                                policy<{'arm64': '-'}>
+CONFIG_SPI_STM32_QSPI                           policy<{'arm64': '-'}>
+CONFIG_SPI_SUN4I                                policy<{'arm64': '-'}>
+CONFIG_SPI_SUN6I                                policy<{'arm64': '-'}>
+CONFIG_SPI_SYNQUACER                            policy<{'arm64': '-'}>
+CONFIG_SPI_TEGRA114                             policy<{'arm64': '-'}>
+CONFIG_SPI_TEGRA20_SFLASH                       policy<{'arm64': '-'}>
+CONFIG_SPI_TEGRA20_SLINK                        policy<{'arm64': '-'}>
+CONFIG_SPI_TEGRA210_QUAD                        policy<{'arm64': '-'}>
+CONFIG_SPI_WPCM_FIU                             policy<{'arm64': '-'}>
+CONFIG_SPI_XLP                                  policy<{'arm64': '-'}>
+CONFIG_SPMI                                     policy<{'arm64': 'y'}>
+CONFIG_SPMI_MSM_PMIC_ARB                        policy<{'arm64': 'y'}>
+CONFIG_SPMI_MTK_PMIF                            policy<{'arm64': '-'}>
+CONFIG_SPRD_COMMON_CLK                          policy<{'arm64': '-'}>
+CONFIG_SPRD_DMA                                 policy<{'arm64': '-'}>
+CONFIG_SPRD_IOMMU                               policy<{'arm64': '-'}>
+CONFIG_SPRD_MBOX                                policy<{'arm64': '-'}>
+CONFIG_SPRD_SC9860_CLK                          policy<{'arm64': '-'}>
+CONFIG_SPRD_SC9863A_CLK                         policy<{'arm64': '-'}>
+CONFIG_SPRD_THERMAL                             policy<{'arm64': '-'}>
+CONFIG_SPRD_TIMER                               policy<{'arm64': '-'}>
+CONFIG_SPRD_UMS512_CLK                          policy<{'arm64': '-'}>
+CONFIG_SPRD_WATCHDOG                            policy<{'arm64': '-'}>
+CONFIG_STACKDEPOT_ALWAYS_INIT                   policy<{'arm64': 'y'}>
+CONFIG_STM32_ADC                                policy<{'arm64': '-'}>
+CONFIG_STM32_ADC_CORE                           policy<{'arm64': '-'}>
+CONFIG_STM32_DAC                                policy<{'arm64': '-'}>
+CONFIG_STM32_DAC_CORE                           policy<{'arm64': '-'}>
+CONFIG_STM32_DFSDM_ADC                          policy<{'arm64': '-'}>
+CONFIG_STM32_DFSDM_CORE                         policy<{'arm64': '-'}>
+CONFIG_STM32_DMA                                policy<{'arm64': '-'}>
+CONFIG_STM32_DMAMUX                             policy<{'arm64': '-'}>
+CONFIG_STM32_FMC2_EBI                           policy<{'arm64': '-'}>
+CONFIG_STM32_LPTIMER_CNT                        policy<{'arm64': '-'}>
+CONFIG_STM32_MDMA                               policy<{'arm64': '-'}>
+CONFIG_STM32_RPROC                              policy<{'arm64': '-'}>
+CONFIG_STM32_TIMER_CNT                          policy<{'arm64': '-'}>
+CONFIG_STM32_WATCHDOG                           policy<{'arm64': '-'}>
+CONFIG_STMP_DEVICE                              policy<{'arm64': '-'}>
+CONFIG_STM_PROTO_OST                            policy<{'arm64': 'm'}>
+CONFIG_STUB_CLK_HI3660                          policy<{'arm64': '-'}>
+CONFIG_STUB_CLK_HI6220                          policy<{'arm64': '-'}>
+CONFIG_ST_THERMAL                               policy<{'arm64': '-'}>
+CONFIG_ST_THERMAL_MEMMAP                        policy<{'arm64': '-'}>
+CONFIG_SUN20I_GPADC                             policy<{'arm64': '-'}>
+CONFIG_SUN20I_PPU                               policy<{'arm64': '-'}>
+CONFIG_SUN4I_EMAC                               policy<{'arm64': '-'}>
+CONFIG_SUN4I_GPADC                              policy<{'arm64': '-'}>
+CONFIG_SUN4I_TIMER                              policy<{'arm64': '-'}>
+CONFIG_SUN50I_A100_CCU                          policy<{'arm64': '-'}>
+CONFIG_SUN50I_A100_R_CCU                        policy<{'arm64': '-'}>
+CONFIG_SUN50I_A64_CCU                           policy<{'arm64': '-'}>
+CONFIG_SUN50I_DE2_BUS                           policy<{'arm64': '-'}>
+CONFIG_SUN50I_ERRATUM_UNKNOWN1                  policy<{'arm64': '-'}>
+CONFIG_SUN50I_H616_CCU                          policy<{'arm64': '-'}>
+CONFIG_SUN50I_H6_CCU                            policy<{'arm64': '-'}>
+CONFIG_SUN50I_H6_R_CCU                          policy<{'arm64': '-'}>
+CONFIG_SUN50I_IOMMU                             policy<{'arm64': '-'}>
+CONFIG_SUN6I_MSGBOX                             policy<{'arm64': '-'}>
+CONFIG_SUN6I_R_INTC                             policy<{'arm64': '-'}>
+CONFIG_SUN8I_DE2_CCU                            policy<{'arm64': '-'}>
+CONFIG_SUN8I_H3_CCU                             policy<{'arm64': '-'}>
+CONFIG_SUN8I_R_CCU                              policy<{'arm64': '-'}>
+CONFIG_SUN8I_THERMAL                            policy<{'arm64': '-'}>
+CONFIG_SUNXI_CCU                                policy<{'arm64': '-'}>
+CONFIG_SUNXI_MBUS                               policy<{'arm64': '-'}>
+CONFIG_SUNXI_NMI_INTC                           policy<{'arm64': '-'}>
+CONFIG_SUNXI_RSB                                policy<{'arm64': '-'}>
+CONFIG_SUNXI_SRAM                               policy<{'arm64': '-'}>
+CONFIG_SUNXI_WATCHDOG                           policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A774A1                            policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A774B1                            policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A774C0                            policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A774E1                            policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A7795                             policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A77960                            policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A77961                            policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A77965                            policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A77970                            policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A77980                            policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A77990                            policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A77995                            policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A779A0                            policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A779F0                            policy<{'arm64': '-'}>
+CONFIG_SYSC_R8A779G0                            policy<{'arm64': '-'}>
+CONFIG_SYSC_RCAR                                policy<{'arm64': '-'}>
+CONFIG_SYSC_RCAR_GEN4                           policy<{'arm64': '-'}>
+CONFIG_SYSFB                                    policy<{'arm64': '-'}>
+CONFIG_SYS_SUPPORTS_SH_CMT                      policy<{'arm64': '-'}>
+CONFIG_SYS_SUPPORTS_SH_TMU                      policy<{'arm64': '-'}>
+CONFIG_TCG_TIS_SYNQUACER                        policy<{'arm64': '-'}>
+CONFIG_TEE_STMM_EFI                             policy<{'arm64': 'n'}>
+CONFIG_TEGRA186_GPC_DMA                         policy<{'arm64': '-'}>
+CONFIG_TEGRA186_TIMER                           policy<{'arm64': '-'}>
+CONFIG_TEGRA20_APB_DMA                          policy<{'arm64': '-'}>
+CONFIG_TEGRA210_ADMA                            policy<{'arm64': '-'}>
+CONFIG_TEGRA210_EMC                             policy<{'arm64': '-'}>
+CONFIG_TEGRA210_EMC_TABLE                       policy<{'arm64': '-'}>
+CONFIG_TEGRA_ACONNECT                           policy<{'arm64': '-'}>
+CONFIG_TEGRA_AHB                                policy<{'arm64': '-'}>
+CONFIG_TEGRA_BPMP                               policy<{'arm64': '-'}>
+CONFIG_TEGRA_BPMP_THERMAL                       policy<{'arm64': '-'}>
+CONFIG_TEGRA_CLK_DFLL                           policy<{'arm64': '-'}>
+CONFIG_TEGRA_GMI                                policy<{'arm64': '-'}>
+CONFIG_TEGRA_HOST1X                             policy<{'arm64': '-'}>
+CONFIG_TEGRA_HOST1X_CONTEXT_BUS                 policy<{'arm64': '-'}>
+CONFIG_TEGRA_HOST1X_FIREWALL                    policy<{'arm64': '-'}>
+CONFIG_TEGRA_HSP_MBOX                           policy<{'arm64': '-'}>
+CONFIG_TEGRA_IOMMU_SMMU                         policy<{'arm64': '-'}>
+CONFIG_TEGRA_IVC                                policy<{'arm64': '-'}>
+CONFIG_TEGRA_MC                                 policy<{'arm64': '-'}>
+CONFIG_TEGRA_SOCTHERM                           policy<{'arm64': '-'}>
+CONFIG_TEGRA_TIMER                              policy<{'arm64': '-'}>
+CONFIG_TEGRA_WATCHDOG                           policy<{'arm64': '-'}>
+CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS      policy<{'arm64': '10000'}>
+CONFIG_THUNDERX2_PMU                            policy<{'arm64': '-'}>
+CONFIG_TIMER_IMX_SYS_CTR                        policy<{'arm64': '-'}>
+CONFIG_TI_AM335X_ADC                            policy<{'arm64': '-'}>
+CONFIG_TI_AM65_CPSW_QOS                         policy<{'arm64': '-'}>
+CONFIG_TI_AM65_CPSW_TAS                         policy<{'arm64': '-'}>
+CONFIG_TI_DAVINCI_MDIO                          policy<{'arm64': '-'}>
+CONFIG_TI_ECAP_CAPTURE                          policy<{'arm64': '-'}>
+CONFIG_TI_ICSSG_PRUETH                          policy<{'arm64': '-'}>
+CONFIG_TI_ICSS_IEP                              policy<{'arm64': '-'}>
+CONFIG_TI_K3_AM65_CPSW_NUSS                     policy<{'arm64': '-'}>
+CONFIG_TI_K3_AM65_CPSW_SWITCHDEV                policy<{'arm64': '-'}>
+CONFIG_TI_K3_AM65_CPTS                          policy<{'arm64': '-'}>
+CONFIG_TI_K3_CPPI_DESC_POOL                     policy<{'arm64': '-'}>
+CONFIG_TI_K3_DSP_REMOTEPROC                     policy<{'arm64': '-'}>
+CONFIG_TI_K3_PSIL                               policy<{'arm64': '-'}>
+CONFIG_TI_K3_R5_REMOTEPROC                      policy<{'arm64': '-'}>
+CONFIG_TI_K3_RINGACC                            policy<{'arm64': '-'}>
+CONFIG_TI_K3_SOCINFO                            policy<{'arm64': '-'}>
+CONFIG_TI_K3_UDMA                               policy<{'arm64': '-'}>
+CONFIG_TI_K3_UDMA_GLUE_LAYER                    policy<{'arm64': '-'}>
+CONFIG_TI_MESSAGE_MANAGER                       policy<{'arm64': '-'}>
+CONFIG_TI_PRUSS                                 policy<{'arm64': '-'}>
+CONFIG_TI_PRUSS_INTC                            policy<{'arm64': '-'}>
+CONFIG_TI_SCI_CLK                               policy<{'arm64': '-'}>
+CONFIG_TI_SCI_CLK_PROBE_FROM_FW                 policy<{'arm64': '-'}>
+CONFIG_TI_SCI_INTA_IRQCHIP                      policy<{'arm64': '-'}>
+CONFIG_TI_SCI_INTA_MSI_DOMAIN                   policy<{'arm64': '-'}>
+CONFIG_TI_SCI_INTR_IRQCHIP                      policy<{'arm64': '-'}>
+CONFIG_TI_SCI_PM_DOMAINS                        policy<{'arm64': '-'}>
+CONFIG_TI_SCI_PROTOCOL                          policy<{'arm64': '-'}>
+CONFIG_TI_SYSC                                  policy<{'arm64': '-'}>
+CONFIG_TI_SYSCON_CLK                            policy<{'arm64': '-'}>
+CONFIG_TOUCHSCREEN_GOODIX_BERLIN_I2C            policy<{'arm64': 'n'}>
+CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI            policy<{'arm64': 'n'}>
+CONFIG_TOUCHSCREEN_SUN4I                        policy<{'arm64': '-'}>
+CONFIG_TOUCHSCREEN_TI_AM335X_TSC                policy<{'arm64': '-'}>
+CONFIG_TURRIS_MOX_RWTM                          policy<{'arm64': '-'}>
+CONFIG_USB_CDNS3_IMX                            policy<{'arm64': '-'}>
+CONFIG_USB_CDNS3_TI                             policy<{'arm64': '-'}>
+CONFIG_USB_DWC3_AM62                            policy<{'arm64': '-'}>
+CONFIG_USB_DWC3_IMX8MP                          policy<{'arm64': '-'}>
+CONFIG_USB_DWC3_KEYSTONE                        policy<{'arm64': '-'}>
+CONFIG_USB_DWC3_MESON_G12A                      policy<{'arm64': '-'}>
+CONFIG_USB_DWC3_RTK                             policy<{'arm64': '-'}>
+CONFIG_USB_DWC3_XILINX                          policy<{'arm64': '-'}>
+CONFIG_USB_EHCI_HCD_NPCM7XX                     policy<{'arm64': '-'}>
+CONFIG_USB_EHCI_HCD_ORION                       policy<{'arm64': '-'}>
+CONFIG_USB_EHCI_TEGRA                           policy<{'arm64': '-'}>
+CONFIG_USB_EMXX                                 policy<{'arm64': '-'}>
+CONFIG_USB_F_QDSS                               policy<{'arm64': 'm'}>
+CONFIG_USB_HUB_USB5807                          policy<{'arm64': 'm'}>
+CONFIG_USB_MTU3                                 policy<{'arm64': '-'}>
+CONFIG_USB_MTU3_DEBUG                           policy<{'arm64': '-'}>
+CONFIG_USB_MTU3_DUAL_ROLE                       policy<{'arm64': '-'}>
+CONFIG_USB_MTU3_GADGET                          policy<{'arm64': '-'}>
+CONFIG_USB_MTU3_HOST                            policy<{'arm64': '-'}>
+CONFIG_USB_MUSB_MEDIATEK                        policy<{'arm64': '-'}>
+CONFIG_USB_MUSB_SUNXI                           policy<{'arm64': '-'}>
+CONFIG_USB_MXS_PHY                              policy<{'arm64': '-'}>
+CONFIG_USB_RENESAS_USB3                         policy<{'arm64': '-'}>
+CONFIG_USB_RENESAS_USBF                         policy<{'arm64': '-'}>
+CONFIG_USB_RENESAS_USBHS                        policy<{'arm64': '-'}>
+CONFIG_USB_RENESAS_USBHS_HCD                    policy<{'arm64': '-'}>
+CONFIG_USB_RENESAS_USBHS_UDC                    policy<{'arm64': '-'}>
+CONFIG_USB_RZV2M_USB3DRD                        policy<{'arm64': '-'}>
+CONFIG_USB_TEGRA_PHY                            policy<{'arm64': '-'}>
+CONFIG_USB_TEGRA_XUDC                           policy<{'arm64': '-'}>
+CONFIG_USB_XHCI_HISTB                           policy<{'arm64': '-'}>
+CONFIG_USB_XHCI_MTK                             policy<{'arm64': '-'}>
+CONFIG_USB_XHCI_MVEBU                           policy<{'arm64': '-'}>
+CONFIG_USB_XHCI_RCAR                            policy<{'arm64': '-'}>
+CONFIG_USB_XHCI_RZV2M                           policy<{'arm64': '-'}>
+CONFIG_USB_XHCI_TEGRA                           policy<{'arm64': '-'}>
+CONFIG_V4L2_H264                                policy<{'arm64': '-'}>
+CONFIG_V4L2_JPEG_HELPER                         policy<{'arm64': '-'}>
+CONFIG_V4L2_VP9                                 policy<{'arm64': '-'}>
+CONFIG_VFIO_FSL_MC                              policy<{'arm64': '-'}>
+CONFIG_VIDEO_ALLEGRO_DVT                        policy<{'arm64': '-'}>
+CONFIG_VIDEO_AMPHION_VPU                        policy<{'arm64': '-'}>
+CONFIG_VIDEO_CODA                               policy<{'arm64': '-'}>
+CONFIG_VIDEO_DW100                              policy<{'arm64': '-'}>
+CONFIG_VIDEO_HANTRO                             policy<{'arm64': '-'}>
+CONFIG_VIDEO_HANTRO_IMX8M                       policy<{'arm64': '-'}>
+CONFIG_VIDEO_HANTRO_ROCKCHIP                    policy<{'arm64': '-'}>
+CONFIG_VIDEO_HANTRO_SUNXI                       policy<{'arm64': '-'}>
+CONFIG_VIDEO_IMX7_CSI                           policy<{'arm64': '-'}>
+CONFIG_VIDEO_IMX8MQ_MIPI_CSI2                   policy<{'arm64': '-'}>
+CONFIG_VIDEO_IMX8_ISI                           policy<{'arm64': '-'}>
+CONFIG_VIDEO_IMX8_ISI_M2M                       policy<{'arm64': '-'}>
+CONFIG_VIDEO_IMX8_JPEG                          policy<{'arm64': '-'}>
+CONFIG_VIDEO_IMX_MIPI_CSIS                      policy<{'arm64': '-'}>
+CONFIG_VIDEO_IMX_PXP                            policy<{'arm64': '-'}>
+CONFIG_VIDEO_MEDIATEK_JPEG                      policy<{'arm64': '-'}>
+CONFIG_VIDEO_MEDIATEK_MDP                       policy<{'arm64': '-'}>
+CONFIG_VIDEO_MEDIATEK_MDP3                      policy<{'arm64': '-'}>
+CONFIG_VIDEO_MEDIATEK_VCODEC                    policy<{'arm64': '-'}>
+CONFIG_VIDEO_MEDIATEK_VPU                       policy<{'arm64': '-'}>
+CONFIG_VIDEO_MESON_GE2D                         policy<{'arm64': '-'}>
+CONFIG_VIDEO_MESON_VDEC                         policy<{'arm64': '-'}>
+CONFIG_VIDEO_NPCM_VCD_ECE                       policy<{'arm64': '-'}>
+CONFIG_VIDEO_QCOM_IRIS                          policy<{'arm64': 'm'}>
+CONFIG_VIDEO_RCAR_CSI2                          policy<{'arm64': '-'}>
+CONFIG_VIDEO_RCAR_DRIF                          policy<{'arm64': '-'}>
+CONFIG_VIDEO_RCAR_ISP                           policy<{'arm64': '-'}>
+CONFIG_VIDEO_RCAR_VIN                           policy<{'arm64': '-'}>
+CONFIG_VIDEO_RENESAS_FCP                        policy<{'arm64': '-'}>
+CONFIG_VIDEO_RENESAS_FDP1                       policy<{'arm64': '-'}>
+CONFIG_VIDEO_RENESAS_JPU                        policy<{'arm64': '-'}>
+CONFIG_VIDEO_RENESAS_VSP1                       policy<{'arm64': '-'}>
+CONFIG_VIDEO_ROCKCHIP_ISP1                      policy<{'arm64': '-'}>
+CONFIG_VIDEO_ROCKCHIP_RGA                       policy<{'arm64': '-'}>
+CONFIG_VIDEO_ROCKCHIP_VDEC                      policy<{'arm64': '-'}>
+CONFIG_VIDEO_RZG2L_CRU                          policy<{'arm64': '-'}>
+CONFIG_VIDEO_RZG2L_CSI2                         policy<{'arm64': '-'}>
+CONFIG_VIDEO_STM32_DCMI                         policy<{'arm64': '-'}>
+CONFIG_VIDEO_STM32_DCMIPP                       policy<{'arm64': '-'}>
+CONFIG_VIDEO_STM32_DMA2D                        policy<{'arm64': '-'}>
+CONFIG_VIDEO_SUN4I_CSI                          policy<{'arm64': '-'}>
+CONFIG_VIDEO_SUN6I_CSI                          policy<{'arm64': '-'}>
+CONFIG_VIDEO_SUN6I_ISP                          policy<{'arm64': '-'}>
+CONFIG_VIDEO_SUN6I_MIPI_CSI2                    policy<{'arm64': '-'}>
+CONFIG_VIDEO_SUN8I_A83T_MIPI_CSI2               policy<{'arm64': '-'}>
+CONFIG_VIDEO_SUN8I_DEINTERLACE                  policy<{'arm64': '-'}>
+CONFIG_VIDEO_SUN8I_ROTATE                       policy<{'arm64': '-'}>
+CONFIG_VIDEO_SUNXI                              policy<{'arm64': '-'}>
+CONFIG_VIDEO_SUNXI_CEDRUS                       policy<{'arm64': '-'}>
+CONFIG_VIDEO_TEGRA                              policy<{'arm64': '-'}>
+CONFIG_VIDEO_TEGRA_TPG                          policy<{'arm64': '-'}>
+CONFIG_VIDEO_TEGRA_VDE                          policy<{'arm64': '-'}>
+CONFIG_VIDEO_TI_CAL                             policy<{'arm64': '-'}>
+CONFIG_VIDEO_TI_CAL_MC                          policy<{'arm64': '-'}>
+CONFIG_VIDEO_TI_J721E_CSI2RX                    policy<{'arm64': '-'}>
+CONFIG_VIDEO_WAVE_VPU                           policy<{'arm64': '-'}>
+CONFIG_VISCONTI_WATCHDOG                        policy<{'arm64': '-'}>
+CONFIG_W1_MASTER_MXC                            policy<{'arm64': '-'}>
+CONFIG_WLAN_VENDOR_BCMDHD                       policy<{'arm64': 'y'}>
+CONFIG_XGENE_DMA                                policy<{'arm64': '-'}>
+CONFIG_XGENE_PMU                                policy<{'arm64': '-'}>
+CONFIG_XGENE_SLIMPRO_MBOX                       policy<{'arm64': '-'}>
+CONFIG_XILINX_AMS                               policy<{'arm64': '-'}>
+CONFIG_XLNX_EVENT_MANAGER                       policy<{'arm64': '-'}>
+CONFIG_XLNX_R5_REMOTEPROC                       policy<{'arm64': '-'}>
+CONFIG_ZYNQMP_FIRMWARE                          policy<{'arm64': '-'}>
+CONFIG_ZYNQMP_FIRMWARE_DEBUG                    policy<{'arm64': '-'}>
+CONFIG_ZYNQMP_IPI_MBOX                          policy<{'arm64': '-'}>
+CONFIG_ZYNQMP_PM_DOMAINS                        policy<{'arm64': '-'}>
+CONFIG_ZYNQMP_POWER                             policy<{'arm64': '-'}>
--- linux-qcom-6.8.0.orig/debian.qcom/control.d/flavour-control.stub
+++ linux-qcom-6.8.0/debian.qcom/control.d/flavour-control.stub
@@ -0,0 +1,120 @@
+# Items that get replaced:
+# FLAVOUR
+# DESC
+# ARCH
+# SUPPORTED
+# TARGET
+# BOOTLOADER
+# =PROVIDES=
+#
+# Items marked with =FOO= are optional
+#
+# This file describes the template for packages that are created for each flavour
+# in debian/control.d/vars.*
+#
+# This file gets edited in a couple of places. See the debian/control.stub rule in
+# debian/rules. PGGVER, ABINUM, and SRCPKGNAME are all converted in the
+# process of creating debian/control.
+#
+# The flavour specific strings (ARCH, DESC, etc) are converted using values from the various
+# flavour files in debian/control.d/vars.*
+#
+# XXX: Leave the blank line before the first package!!
+
+Package: linux-image=SIGN-ME-PKG=-PKGVER-ABINUM-FLAVOUR
+Build-Profiles: <!stage1>
+Architecture: ARCH
+Section: kernel
+Priority: optional
+Provides: linux-image, fuse-module, =PROVIDES=${linux:rprovides}
+Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-PKGVER-ABINUM-FLAVOUR
+Recommends: BOOTLOADER, initramfs-tools | linux-initramfs-tool
+Breaks: flash-kernel (<< 3.90ubuntu2) [arm64 armhf], s390-tools (<< 2.3.0-0ubuntu3) [s390x]
+Conflicts: linux-image=SIGN-PEER-PKG=-PKGVER-ABINUM-FLAVOUR
+Suggests: fdutils, SRCPKGNAME-tools, linux-headers-PKGVER-ABINUM-FLAVOUR
+Description: Linux kernel image for version PKGVER on DESC
+ This package contains the=SIGN-ME-TXT= Linux kernel image for version PKGVER on
+ DESC.
+ .
+ Supports SUPPORTED processors.
+ .
+ TARGET
+ .
+ You likely do not want to install this package directly. Instead, install
+ the linux-FLAVOUR meta-package, which will ensure that upgrades work
+ correctly, and that supporting packages are also installed.
+
+Package: linux-modules-PKGVER-ABINUM-FLAVOUR
+Build-Profiles: <!stage1>
+Architecture: ARCH
+Section: kernel
+Priority: optional
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Built-Using: ${linux:BuiltUsing}
+Description: Linux kernel modules for version PKGVER on DESC
+ Contains the corresponding System.map file, the modules built by the
+ packager, and scripts that try to ensure that the system is not left in an
+ unbootable state after an update.
+ .
+ Supports SUPPORTED processors.
+ .
+ TARGET
+ .
+ You likely do not want to install this package directly. Instead, install
+ the linux-FLAVOUR meta-package, which will ensure that upgrades work
+ correctly, and that supporting packages are also installed.
+
+Package: linux-headers-PKGVER-ABINUM-FLAVOUR
+Build-Profiles: <!stage1>
+Architecture: ARCH
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, SRCPKGNAME-headers-PKGVER-ABINUM, ${shlibs:Depends}
+Provides: linux-headers, linux-headers-3.0
+Description: Linux kernel headers for version PKGVER on DESC
+ This package provides kernel header files for version PKGVER on
+ DESC.
+ .
+ This is for sites that want the latest kernel headers.  Please read
+ /usr/share/doc/linux-headers-PKGVER-ABINUM/debian.README.gz for details.
+
+Package: SRCPKGNAME-lib-rust-PKGVER-ABINUM-FLAVOUR
+Build-Profiles: <!stage1>
+Architecture: arm64
+Multi-Arch: foreign
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, coreutils
+Description: Rust library files related to Linux kernel version PKGVER
+ This package provides kernel library files for version PKGVER, that allow to
+ compile out-of-tree kernel modules written in Rust.
+
+Package: linux-image=SIGN-ME-PKG=-PKGVER-ABINUM-FLAVOUR-dbgsym
+Build-Profiles: <!stage1>
+Architecture: ARCH
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}
+Provides: linux-debug
+Description: Linux kernel debug image for version PKGVER on DESC
+ This package provides the=SIGN-ME-TXT= kernel debug image for version PKGVER on
+ DESC.
+ .
+ This is for sites that wish to debug the kernel.
+ .
+ The kernel image contained in this package is NOT meant to boot from. It
+ is uncompressed, and unstripped. This package also includes the
+ unstripped modules.
+
+Package: linux-tools-PKGVER-ABINUM-FLAVOUR
+Build-Profiles: <!stage1>
+Architecture: ARCH
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, SRCPKGNAME-tools-PKGVER-ABINUM
+Description: Linux kernel version specific tools for version PKGVER-ABINUM
+ This package provides the architecture dependant parts for kernel
+ version locked tools (such as perf and x86_energy_perf_policy) for
+ version PKGVER-ABINUM on
+ =HUMAN=.
+
--- linux-qcom-6.8.0.orig/debian.qcom/control.d/vars.qcom
+++ linux-qcom-6.8.0/debian.qcom/control.d/vars.qcom
@@ -0,0 +1,6 @@
+arch="arm64"
+supported="Qualcomm SoC"
+target="Geared toward desktop and server systems."
+desc="=HUMAN= SMP"
+bootloader="grub-pc [amd64] | grub-efi-amd64 [amd64] | grub-efi-ia32 [amd64] | grub [amd64] | lilo [amd64] | flash-kernel [armhf arm64] | grub-efi-arm64 [arm64] | grub-efi-arm [armhf] | grub-ieee1275 [ppc64el]"
+provides="kvm-api-4, redhat-cluster-modules, ivtv-modules, virtualbox-guest-modules [amd64]"
--- linux-qcom-6.8.0.orig/debian.qcom/control.stub.in
+++ linux-qcom-6.8.0/debian.qcom/control.stub.in
@@ -0,0 +1,95 @@
+Source: SRCPKGNAME
+Section: devel
+Priority: optional
+Maintainer: Ubuntu Kernel Team <kernel-team@lists.ubuntu.com>
+Rules-Requires-Root: no
+Standards-Version: 3.9.4.0
+Build-Depends:
+ debhelper-compat (= 10),
+ cpio,
+ kmod <!stage1>,
+ makedumpfile [amd64] <!stage1>,
+ libcap-dev <!stage1>,
+ libelf-dev <!stage1>,
+ libnewt-dev <!stage1>,
+ libiberty-dev <!stage1>,
+ default-jdk-headless <!stage1>,
+ java-common <!stage1>,
+ rsync [!i386] <!stage1>,
+ libdw-dev <!stage1>,
+ libpci-dev <!stage1>,
+ pkg-config <!stage1>,
+ python3 <!stage1>,
+ python3-dev <!stage1>,
+ python3-setuptools <!stage1>,
+ flex <!stage1>,
+ bison <!stage1>,
+ libunwind8-dev [amd64 arm64 armhf ppc64el] <!stage1>,
+ liblzma-dev <!stage1>,
+ openssl <!stage1>,
+ libssl-dev <!stage1>,
+ libaudit-dev <!stage1>,
+ bc <!stage1>,
+ gawk <!stage1>,
+ libudev-dev <!stage1>,
+ autoconf <!stage1>,
+ automake <!stage1>,
+ libtool <!stage1>,
+ uuid-dev <!stage1>,
+ libnuma-dev [amd64 arm64 ppc64el s390x] <!stage1>,
+ libtraceevent-dev [amd64 arm64 armhf ppc64el s390x riscv64] <!stage1>,
+ libtracefs-dev [amd64 arm64 armhf ppc64el s390x riscv64] <!stage1>,
+ dkms <!stage1>,
+ dwarfdump <!stage1>,
+ curl <!stage1>,
+ zstd <!stage1>,
+ pahole [amd64 arm64 armhf ppc64el s390x riscv64] | dwarves (>= 1.21) [amd64 arm64 armhf ppc64el s390x riscv64] <!stage1>,
+ clang-18 [amd64 arm64 armhf ppc64el riscv64 s390x],
+ rustc [amd64 arm64 armhf ppc64el riscv64 s390x],
+ rust-src [amd64 arm64 armhf ppc64el riscv64 s390x],
+ rustfmt [amd64 arm64 armhf ppc64el riscv64 s390x],
+ bindgen-0.65 [amd64 arm64 armhf ppc64el riscv64 s390x],
+ libstdc++-dev,
+Build-Depends-Indep:
+ xmlto <!stage1>,
+ bzip2 <!stage1>,
+ sharutils <!stage1>,
+ asciidoc <!stage1>,
+ python3-docutils <!stage1>,
+Vcs-Git: git://git.launchpad.net/~canonical-kernel/ubuntu/+source/linux-qcom/+git/=SERIES=
+XS-Testsuite: autopkgtest
+#XS-Testsuite-Depends: gcc-4.7 binutils
+
+Package: SRCPKGNAME-headers-PKGVER-ABINUM
+Build-Profiles: <!stage1>
+Architecture: all
+Multi-Arch: foreign
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, coreutils
+Description: Header files related to Linux kernel version PKGVER
+ This package provides kernel header files for version PKGVER, for sites
+ that want the latest kernel headers. Please read
+ /usr/share/doc/SRCPKGNAME-headers-PKGVER-ABINUM/debian.README.gz for details
+
+Package: SRCPKGNAME-tools-PKGVER-ABINUM
+Build-Profiles: <!stage1>
+Architecture: arm64
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, ${shlibs:Depends}, linux-tools-common
+Description: Linux kernel version specific tools for version PKGVER-ABINUM
+ This package provides the architecture dependant parts for kernel
+ version locked tools (such as perf and x86_energy_perf_policy) for
+ version PKGVER-ABINUM on
+ =HUMAN=.
+ You probably want to install linux-tools-PKGVER-ABINUM-<flavour>.
+
+Package: linux-libc-dev-qcom
+Architecture: all
+Depends: ${misc:Depends}
+Description: Linux Kernel Headers for development
+ This package provides additional downstream headers from the Linux kernel.
+ These headers are used by the installed headers for GNU glibc and other system
+ libraries. They are NOT meant to be used to build third-party modules for
+ your kernel. Use SRCPKGNAME-headers-* packages for that.
--- linux-qcom-6.8.0.orig/debian.qcom/copyright
+++ linux-qcom-6.8.0/debian.qcom/copyright
@@ -0,0 +1,29 @@
+This is the Ubuntu prepackaged version of the Linux kernel.
+Linux was written by Linus Torvalds <Linus.Torvalds@cs.Helsinki.FI>
+and others.
+
+This package was put together by the Ubuntu Kernel Team, from
+sources retrieved from upstream linux git.
+The sources may be found at most Linux ftp sites, including 
+ftp://ftp.kernel.org/pub/linux/kernel/
+
+This package is currently maintained by the
+Ubuntu Kernel Team <ubuntu-kernel@lists.ubuntu.com>
+
+Linux is copyrighted by Linus Torvalds and others.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 dated June, 1991.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+On Ubuntu Linux systems, the complete text of the GNU General
+Public License v2 can be found in `/usr/share/common-licenses/GPL-2'.
--- linux-qcom-6.8.0.orig/debian.qcom/dkms-versions
+++ linux-qcom-6.8.0/debian.qcom/dkms-versions
@@ -0,0 +1,3 @@
+zfs-linux 2.2.2-0ubuntu9.2 modulename=zfs debpath=pool/universe/z/%package%/zfs-dkms_%version%_all.deb arch=amd64 arch=arm64 arch=ppc64el arch=s390x rprovides=spl-modules rprovides=spl-dkms rprovides=zfs-modules rprovides=zfs-dkms
+backport-iwlwifi-dkms 11510-0ubuntu1.1 modulename=iwlwifi debpath=pool/universe/b/%package%/backport-iwlwifi-dkms_%version%_all.deb arch=amd64 rprovides=iwlwifi-modules rprovides=backport-iwlwifi-dkms type=standalone
+v4l2loopback 0.12.7-2ubuntu5 modulename=v4l2loopback debpath=pool/universe/v/%package%/v4l2loopback-dkms_%version%_all.deb arch=amd64 rprovides=v4l2loopback-modules rprovides=v4l2loopback-dkms
--- linux-qcom-6.8.0.orig/debian.qcom/etc/update.conf
+++ linux-qcom-6.8.0/debian.qcom/etc/update.conf
@@ -0,0 +1,7 @@
+# WARNING: we do not create update.conf when we are not a
+# derivative. Various cranky components make use of this.
+# If we start unconditionally creating update.conf we need
+# to fix at least cranky close and cranky rebase.
+RELEASE_REPO=git://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/noble
+SOURCE_RELEASE_BRANCH=master-next
+DEBIAN_MASTER=debian.master
--- linux-qcom-6.8.0.orig/debian.qcom/linux-libc-dev-qcom.install
+++ linux-qcom-6.8.0/debian.qcom/linux-libc-dev-qcom.install
@@ -0,0 +1,21 @@
+include/uapi/sound/qcom/msm_audio.h                                   usr/include/sound/qcom/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_cpas.h        usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_cre.h         usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_custom.h      usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_defs.h        usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_fd.h          usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_icp.h         usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_isp.h         usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_isp_ife.h     usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_isp_sfe.h     usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_isp_tfe.h     usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_isp_vfe.h     usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_jpeg.h        usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_lrme.h        usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_ope.h         usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_req_mgr.h     usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_sensor.h      usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_sync.h        usr/include/camera/media/
+ubuntu/qcom/camera/camera/include/uapi/camera/media/cam_tfe.h         usr/include/camera/media/
+ubuntu/qcom/graphics/include/uapi/linux/msm_kgsl.h                    usr/include/linux/
+include/uapi/linux/smcinvoke.h                                        usr/include/linux/
--- linux-qcom-6.8.0.orig/debian.qcom/modprobe.d/common.conf
+++ linux-qcom-6.8.0/debian.qcom/modprobe.d/common.conf
@@ -0,0 +1,3 @@
+# LP:1434842 -- disable OSS drivers by default to allow pulseaudio to emulate
+blacklist snd-mixer-oss
+blacklist snd-pcm-oss
--- linux-qcom-6.8.0.orig/debian.qcom/reconstruct
+++ linux-qcom-6.8.0/debian.qcom/reconstruct
@@ -0,0 +1,86 @@
+# Recreate any symlinks created since the orig.
+[ ! -L 'include/dt-bindings/arm/qcom_dma_heap_dt_constants.h' ] && ln -sf '../../linux/qcom_dma_heap_dt_constants.h' 'include/dt-bindings/arm/qcom_dma_heap_dt_constants.h'
+chmod +x 'arch/mips/pci/pcie-octeon.c'
+chmod +x 'debian/cloud-tools/hv_get_dhcp_info'
+chmod +x 'debian/cloud-tools/hv_get_dns_info'
+chmod +x 'debian/cloud-tools/hv_set_ifconfig'
+chmod +x 'debian/rules'
+chmod +x 'debian/scripts/checks/final-checks'
+chmod +x 'debian/scripts/checks/module-signature-check'
+chmod +x 'debian/scripts/control-create'
+chmod +x 'debian/scripts/dkms-build'
+chmod +x 'debian/scripts/dkms-build--nvidia-N'
+chmod +x 'debian/scripts/dkms-build-configure--zfs'
+chmod +x 'debian/scripts/file-downloader'
+chmod +x 'debian/scripts/link-headers'
+chmod +x 'debian/scripts/link-lib-rust'
+chmod +x 'debian/scripts/misc/annotations'
+chmod +x 'debian/scripts/misc/find-missing-sauce.sh'
+chmod +x 'debian/scripts/misc/gen-auto-reconstruct'
+chmod +x 'debian/scripts/misc/git-ubuntu-log'
+chmod +x 'debian/scripts/misc/insert-changes'
+chmod +x 'debian/scripts/misc/insert-ubuntu-changes'
+chmod +x 'debian/scripts/misc/kernelconfig'
+chmod +x 'debian/scripts/module-inclusion'
+chmod +x 'debian/scripts/sign-module'
+chmod +x 'debian/templates/extra.postinst.in'
+chmod +x 'debian/templates/extra.postrm.in'
+chmod +x 'debian/templates/headers.postinst.in'
+chmod +x 'debian/templates/image.postinst.in'
+chmod +x 'debian/templates/image.postrm.in'
+chmod +x 'debian/templates/image.preinst.in'
+chmod +x 'debian/templates/image.prerm.in'
+chmod +x 'debian/tests-build/check-aliases'
+chmod +x 'debian/tests/rebuild'
+chmod +x 'debian/tests/ubuntu-regression-suite'
+chmod +x 'drivers/watchdog/f71808e_wdt.c'
+chmod +x 'tools/testing/selftests/gpio/gpio-aggregator.sh'
+chmod +x 'tools/testing/selftests/net/ipv6_route_update_soft_lockup.sh'
+chmod +x 'ubuntu/qcom/camera/sanitize_uapi.sh'
+chmod +x 'ubuntu/qcom/qps615/tc956x_qcom.c'
+# Remove any files deleted from the orig.
+rm -f 'arch/arm/kernel/pj4-cp0.c'
+rm -f 'arch/arm64/boot/dts/qcom/pm2250.dtsi'
+rm -f 'arch/arm64/boot/dts/qcom/sdm845-db845c-navigation-mezzanine.dts'
+rm -f 'arch/loongarch/include/asm/dma-direct.h'
+rm -f 'arch/loongarch/include/asm/qspinlock.h'
+rm -f 'arch/s390/kernel/earlypgm.S'
+rm -f 'arch/sparc/lib/cmpdi2.c'
+rm -f 'arch/sparc/lib/ucmpdi2.c'
+rm -f 'drivers/dax/pmem/Makefile'
+rm -f 'drivers/dax/pmem/pmem.c'
+rm -f 'drivers/gpu/drm/gma500/psb_lid.c'
+rm -f 'drivers/gpu/drm/msm/adreno/a2xx.xml.h'
+rm -f 'drivers/gpu/drm/msm/adreno/a3xx.xml.h'
+rm -f 'drivers/gpu/drm/msm/adreno/a4xx.xml.h'
+rm -f 'drivers/gpu/drm/msm/adreno/a5xx.xml.h'
+rm -f 'drivers/gpu/drm/msm/adreno/a6xx.xml.h'
+rm -f 'drivers/gpu/drm/msm/adreno/a6xx_gmu.xml.h'
+rm -f 'drivers/gpu/drm/msm/adreno/adreno_common.xml.h'
+rm -f 'drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h'
+rm -f 'drivers/gpu/drm/msm/disp/mdp4/mdp4.xml.h'
+rm -f 'drivers/gpu/drm/msm/disp/mdp5/mdp5.xml.h'
+rm -f 'drivers/gpu/drm/msm/disp/mdp_common.xml.h'
+rm -f 'drivers/gpu/drm/msm/dp/dp_parser.c'
+rm -f 'drivers/gpu/drm/msm/dp/dp_parser.h'
+rm -f 'drivers/gpu/drm/msm/dp/dp_power.c'
+rm -f 'drivers/gpu/drm/msm/dp/dp_power.h'
+rm -f 'drivers/gpu/drm/msm/dsi/dsi.xml.h'
+rm -f 'drivers/gpu/drm/msm/dsi/dsi_phy_10nm.xml.h'
+rm -f 'drivers/gpu/drm/msm/dsi/dsi_phy_14nm.xml.h'
+rm -f 'drivers/gpu/drm/msm/dsi/dsi_phy_20nm.xml.h'
+rm -f 'drivers/gpu/drm/msm/dsi/dsi_phy_28nm.xml.h'
+rm -f 'drivers/gpu/drm/msm/dsi/dsi_phy_28nm_8960.xml.h'
+rm -f 'drivers/gpu/drm/msm/dsi/dsi_phy_7nm.xml.h'
+rm -f 'drivers/gpu/drm/msm/dsi/sfpb.xml.h'
+rm -f 'drivers/gpu/drm/msm/hdmi/hdmi.xml.h'
+rm -f 'drivers/gpu/drm/msm/msm_gpummu.c'
+rm -f 'drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c'
+rm -f 'drivers/media/platform/qcom/camss/camss-vfe-170.c'
+rm -f 'include/linux/amd-pstate.h'
+rm -f 'include/linux/iio/adc/adi-axi-adc.h'
+rm -f 'net/bluetooth/a2mp.c'
+rm -f 'net/bluetooth/a2mp.h'
+rm -f 'net/bluetooth/amp.c'
+rm -f 'net/bluetooth/amp.h'
+exit 0
--- linux-qcom-6.8.0.orig/debian.qcom/rules.d/arm64.mk
+++ linux-qcom-6.8.0/debian.qcom/rules.d/arm64.mk
@@ -0,0 +1,18 @@
+human_arch	= ARMv8
+build_arch	= arm64
+defconfig	= defconfig
+flavours	= qcom
+build_image	= Image.gz
+kernel_file	= arch/$(build_arch)/boot/Image.gz
+install_file	= vmlinuz
+no_dumpfile	= true
+
+vdso		= vdso_install
+
+do_tools_usbip  = true
+do_tools_cpupower = true
+do_tools_perf   = true
+do_tools_perf_jvmti = true
+do_tools_bpftool = true
+
+do_dtbs		= true
--- linux-qcom-6.8.0.orig/debian.qcom/tracking-bug
+++ linux-qcom-6.8.0/debian.qcom/tracking-bug
@@ -0,0 +1 @@
+2116573 d2025.07.11-1
--- linux-qcom-6.8.0.orig/debian.qcom/variants
+++ linux-qcom-6.8.0/debian.qcom/variants
@@ -0,0 +1,2 @@
+-6.8
+--
--- linux-qcom-6.8.0.orig/debian/canonical-certs.pem
+++ linux-qcom-6.8.0/debian/canonical-certs.pem
@@ -0,0 +1,371 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            47:77:26:6d:ae:6c:57:73:eb:80:e2:96:dd:26:93:ff:e9:f5:62:5d
+        Signature Algorithm: sha512WithRSAEncryption
+        Issuer: CN=Canonical Ltd. Live Patch Signing 2025 Kmod
+        Validity
+            Not Before: May 16 09:07:40 2025 GMT
+            Not After : May 16 09:07:40 2050 GMT
+        Subject: CN=Canonical Ltd. Live Patch Signing 2025 Kmod
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (4096 bit)
+                Modulus:
+                    00:b8:a9:03:47:2e:7b:c6:86:16:f4:b7:a8:4d:3b:
+                    05:f6:c4:75:35:e9:22:8a:4e:40:06:89:15:7f:ad:
+                    99:bb:e6:90:93:61:c8:16:cf:2e:00:1b:81:36:fd:
+                    cc:31:7b:97:79:8d:5e:d2:4d:d3:2f:ab:35:2d:74:
+                    48:98:b3:d9:75:f9:bb:e1:f2:3f:6b:6d:dc:e4:bb:
+                    ee:f5:aa:f7:8a:8c:7a:a8:0b:df:b1:f8:d6:04:13:
+                    27:e9:1a:aa:c2:4d:d2:35:3a:bc:06:d7:83:7f:e8:
+                    c4:1c:63:8b:3a:ff:0e:0b:89:6e:4f:5f:ea:ad:78:
+                    df:37:ab:f9:55:1d:fb:6e:29:a4:22:43:d1:9b:12:
+                    1e:b2:84:23:1b:d2:38:91:b8:a8:6c:1c:59:3c:ff:
+                    4c:a9:18:ce:d0:7f:1d:ef:04:cf:8a:e8:29:b2:4b:
+                    68:0d:92:32:bc:9c:5d:8f:0a:d1:dd:4d:25:ba:3a:
+                    8c:6a:48:5b:1e:9c:01:10:99:c1:a7:34:ee:68:ec:
+                    a1:d3:26:be:45:c8:b4:97:ac:8a:aa:7e:13:a6:e5:
+                    43:f1:1b:3f:a1:80:0a:d2:a9:e7:f2:77:ca:e1:f5:
+                    29:36:df:75:8a:7e:02:d6:17:aa:46:12:b9:51:f0:
+                    6b:ca:22:f8:05:de:d6:02:47:76:0c:88:f1:c6:90:
+                    44:99:58:71:c7:62:1e:2b:94:c5:2b:8e:dc:ca:7b:
+                    a7:bd:cd:38:8f:4e:73:6d:b0:9b:4e:7c:12:1f:5c:
+                    c5:62:d6:82:c6:d2:78:09:52:dc:d7:78:2e:23:d0:
+                    63:1f:7d:77:91:c8:3f:66:7a:20:8a:cf:70:09:0f:
+                    a2:c0:82:a5:42:d9:be:dc:5f:78:73:f7:fa:3c:70:
+                    47:7b:39:77:89:5a:6f:ef:83:09:c9:1b:21:53:89:
+                    7c:10:bf:99:9c:05:39:32:1e:84:3b:a5:84:7e:ef:
+                    08:6d:b0:b0:31:61:d6:1a:aa:dd:7a:d6:10:02:e6:
+                    72:02:e5:40:bf:07:b9:cd:61:d1:55:04:9a:cd:02:
+                    73:41:c1:df:20:30:12:97:ca:a1:83:1a:97:8a:92:
+                    1c:47:5c:0a:60:da:41:3b:e6:0e:2c:82:ce:45:65:
+                    81:ba:45:a1:66:cc:ef:ab:65:5c:e5:a8:0c:86:dd:
+                    fc:86:54:f3:37:7c:89:a9:0c:fa:3a:da:82:c9:90:
+                    99:1e:1d:66:44:de:d3:c5:d4:0b:da:15:f8:d8:d4:
+                    63:2b:4e:6f:24:e9:c2:d7:74:9c:29:91:9f:25:39:
+                    8d:77:15:8c:cb:8e:ad:e3:80:0a:ea:79:04:72:9d:
+                    51:01:18:ae:35:51:ef:95:79:38:c4:db:99:50:47:
+                    62:38:e9
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Key Usage: 
+                Digital Signature
+            X509v3 Subject Key Identifier: 
+                D5:41:CE:F6:1D:C7:E7:93:B7:EB:7E:89:99:70:A2:EE:F0:B5:DC:8C
+            X509v3 Authority Key Identifier: 
+                D5:41:CE:F6:1D:C7:E7:93:B7:EB:7E:89:99:70:A2:EE:F0:B5:DC:8C
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.2312.16.1.2
+    Signature Algorithm: sha512WithRSAEncryption
+    Signature Value:
+        40:9d:5b:70:66:fe:9c:99:eb:ed:78:61:be:da:67:da:ac:80:
+        a8:c2:78:91:f8:90:11:be:9f:6a:e7:bf:79:dc:11:0c:c7:83:
+        e8:13:c4:1c:b6:fe:f0:e7:7d:1a:12:97:5d:19:56:9c:10:12:
+        1e:b9:19:88:30:95:c4:3b:2f:aa:91:6f:c1:9e:68:4a:f4:5c:
+        ef:a1:51:b5:a3:9b:58:3f:e2:ae:5c:29:a6:c4:30:fd:65:0b:
+        cc:8c:99:95:33:61:c6:07:fa:c3:bd:1a:57:80:e5:43:97:2e:
+        f3:5c:d6:1e:b7:23:9f:58:10:19:24:46:9e:f8:fd:2c:8e:88:
+        e7:ec:ef:15:4b:7a:6a:ce:b0:25:c0:01:c5:21:83:1a:d5:89:
+        0c:90:86:ad:d4:3e:6e:28:bf:6c:21:91:ff:b9:a9:ef:d4:ac:
+        de:7c:67:c1:e4:ed:75:26:15:ff:5d:67:39:24:2d:15:57:21:
+        09:76:e5:85:f3:45:e8:bf:b1:c0:39:2b:83:34:1a:f5:3f:1f:
+        ae:07:8c:82:1f:d4:dc:95:c0:4e:f3:7f:ac:db:8f:2c:db:a4:
+        d4:2a:4c:8c:de:e6:5b:84:fc:df:a3:74:d8:dc:9c:93:1f:5b:
+        c9:33:b5:b3:7d:2b:a4:4d:7a:bb:73:92:ff:8d:e9:9e:c7:a7:
+        d2:0d:83:bb:2c:2f:47:51:15:5c:6d:db:9a:d3:9e:6e:25:90:
+        01:e6:09:bd:a2:d0:1e:cf:a3:12:22:0d:56:70:bf:89:e4:be:
+        62:76:9c:d9:f5:c8:01:55:95:02:57:a1:67:59:88:97:57:f6:
+        bb:8d:c9:40:d5:e3:60:4f:43:dd:49:90:fa:a5:6d:08:96:b2:
+        4d:dd:a7:c6:e3:5c:06:ba:af:8c:30:9d:d5:a5:b0:ab:c4:e5:
+        f3:09:47:05:ba:9b:46:f4:26:70:3b:fa:da:a5:0a:47:ce:be:
+        43:87:eb:73:63:3b:cd:41:7a:78:a0:f6:7d:c5:37:fb:bb:26:
+        3b:b3:e7:44:49:06:8c:14:03:fc:b3:46:54:3b:0d:57:02:08:
+        99:79:68:a2:9c:62:95:4d:ac:8e:19:43:4e:8f:2d:52:fa:91:
+        ca:78:06:a2:b7:a3:66:6d:67:0b:13:ee:b1:01:38:e0:7c:ac:
+        9a:16:27:36:f1:45:83:5d:eb:d6:cd:65:3f:56:9a:d3:56:c4:
+        15:55:b2:64:ca:13:cb:31:1e:7e:03:85:68:61:40:02:99:4b:
+        25:01:68:8d:97:cc:39:1a:54:1b:e5:51:38:8e:ce:66:74:61:
+        5e:87:f4:31:7d:0d:be:9d:01:e1:b3:5c:bc:1a:d0:ea:5e:b2:
+        c8:ee:97:34:bc:9f:bb:98
+-----BEGIN CERTIFICATE-----
+MIIFejCCA2KgAwIBAgIUR3cmba5sV3PrgOKW3SaT/+n1Yl0wDQYJKoZIhvcNAQEN
+BQAwNjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTGl2ZSBQYXRjaCBTaWduaW5n
+IDIwMjUgS21vZDAgFw0yNTA1MTYwOTA3NDBaGA8yMDUwMDUxNjA5MDc0MFowNjE0
+MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTGl2ZSBQYXRjaCBTaWduaW5nIDIwMjUg
+S21vZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALipA0cue8aGFvS3
+qE07BfbEdTXpIopOQAaJFX+tmbvmkJNhyBbPLgAbgTb9zDF7l3mNXtJN0y+rNS10
+SJiz2XX5u+HyP2tt3OS77vWq94qMeqgL37H41gQTJ+kaqsJN0jU6vAbXg3/oxBxj
+izr/DguJbk9f6q143zer+VUd+24ppCJD0ZsSHrKEIxvSOJG4qGwcWTz/TKkYztB/
+He8Ez4roKbJLaA2SMrycXY8K0d1NJbo6jGpIWx6cARCZwac07mjsodMmvkXItJes
+iqp+E6blQ/EbP6GACtKp5/J3yuH1KTbfdYp+AtYXqkYSuVHwa8oi+AXe1gJHdgyI
+8caQRJlYccdiHiuUxSuO3Mp7p73NOI9Oc22wm058Eh9cxWLWgsbSeAlS3Nd4LiPQ
+Yx99d5HIP2Z6IIrPcAkPosCCpULZvtxfeHP3+jxwR3s5d4lab++DCckbIVOJfBC/
+mZwFOTIehDulhH7vCG2wsDFh1hqq3XrWEALmcgLlQL8Huc1h0VUEms0Cc0HB3yAw
+EpfKoYMal4qSHEdcCmDaQTvmDiyCzkVlgbpFoWbM76tlXOWoDIbd/IZU8zd8iakM
++jragsmQmR4dZkTe08XUC9oV+NjUYytObyTpwtd0nCmRnyU5jXcVjMuOreOACup5
+BHKdUQEYrjVR75V5OMTbmVBHYjjpAgMBAAGjfjB8MAwGA1UdEwEB/wQCMAAwCwYD
+VR0PBAQDAgeAMB0GA1UdDgQWBBTVQc72Hcfnk7frfomZcKLu8LXcjDAfBgNVHSME
+GDAWgBTVQc72Hcfnk7frfomZcKLu8LXcjDAfBgNVHSUEGDAWBggrBgEFBQcDAwYK
+KwYBBAGSCBABAjANBgkqhkiG9w0BAQ0FAAOCAgEAQJ1bcGb+nJnr7Xhhvtpn2qyA
+qMJ4kfiQEb6faue/edwRDMeD6BPEHLb+8Od9GhKXXRlWnBASHrkZiDCVxDsvqpFv
+wZ5oSvRc76FRtaObWD/irlwppsQw/WULzIyZlTNhxgf6w70aV4DlQ5cu81zWHrcj
+n1gQGSRGnvj9LI6I5+zvFUt6as6wJcABxSGDGtWJDJCGrdQ+bii/bCGR/7mp79Ss
+3nxnweTtdSYV/11nOSQtFVchCXblhfNF6L+xwDkrgzQa9T8frgeMgh/U3JXATvN/
+rNuPLNuk1CpMjN7mW4T836N02Nyckx9byTO1s30rpE16u3OS/43pnsen0g2Duywv
+R1EVXG3bmtOebiWQAeYJvaLQHs+jEiINVnC/ieS+Ynac2fXIAVWVAlehZ1mIl1f2
+u43JQNXjYE9D3UmQ+qVtCJayTd2nxuNcBrqvjDCd1aWwq8Tl8wlHBbqbRvQmcDv6
+2qUKR86+Q4frc2M7zUF6eKD2fcU3+7smO7PnREkGjBQD/LNGVDsNVwIImXloopxi
+lU2sjhlDTo8tUvqRyngGorejZm1nCxPusQE44HysmhYnNvFFg13r1s1lP1aa01bE
+FVWyZMoTyzEefgOFaGFAAplLJQFojZfMORpUG+VROI7OZnRhXof0MX0Nvp0B4bNc
+vBrQ6l6yyO6XNLyfu5g=
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            c7:7e:51:6a:1c:25:cd:40
+        Signature Algorithm: sha512WithRSAEncryption
+        Issuer: CN = Canonical Ltd. Live Patch Signing
+        Validity
+            Not Before: Jul 18 23:41:27 2016 GMT
+            Not After : Jul 16 23:41:27 2026 GMT
+        Subject: CN = Canonical Ltd. Live Patch Signing
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                RSA Public-Key: (4096 bit)
+                Modulus:
+                    00:bd:74:ee:72:b3:4a:ab:e6:31:e8:29:24:c2:bd:
+                    46:98:32:c0:39:ee:a3:fb:8a:ad:fe:ab:1a:5b:a3:
+                    2e:a1:80:db:79:61:9e:47:79:2c:75:57:a2:21:f0:
+                    93:f6:87:f2:9b:4b:9d:2f:b3:58:61:28:3c:41:70:
+                    13:16:a1:72:90:c9:d5:16:71:7c:e0:30:f9:28:5e:
+                    48:20:36:00:69:b7:59:9f:a3:ec:a8:eb:55:41:9f:
+                    38:1e:22:4a:57:20:f4:83:59:49:c5:00:93:d3:33:
+                    02:92:d1:fc:f0:84:3b:4a:5b:8f:b6:73:9a:89:fa:
+                    30:1e:e6:2a:68:f2:91:ef:59:57:3d:dc:1c:52:6f:
+                    5e:e6:9b:b5:b8:7c:98:c9:13:d1:39:68:01:67:91:
+                    e0:d3:67:72:16:0a:5e:16:83:45:31:4f:b5:2b:b3:
+                    f6:40:86:89:3a:84:6e:6f:16:61:bc:70:84:be:5a:
+                    13:36:7b:82:ea:07:19:fc:18:c1:16:c6:32:0b:7d:
+                    2c:6b:c4:21:b9:38:6b:31:dc:d9:0c:ad:56:40:68:
+                    7c:e3:c6:64:8e:bf:1c:e0:72:3e:6c:db:d2:73:79:
+                    da:d7:c5:2f:5d:04:7d:b0:07:1e:95:dd:2a:47:5e:
+                    bf:3e:3a:c8:66:f6:67:0f:d4:2a:f1:e2:71:59:d2:
+                    6c:7b:a0:37:ac:e6:97:80:30:13:97:48:d5:74:fc:
+                    38:68:e4:57:cb:99:69:5a:84:27:ac:98:51:e4:64:
+                    bd:91:62:e8:58:27:06:2a:b9:0b:b8:08:e5:e5:b4:
+                    51:a7:a2:10:df:4e:07:6c:a0:3b:96:f2:6e:df:75:
+                    8c:97:1e:64:a0:9a:86:9b:98:26:f9:d8:b7:de:5b:
+                    21:b7:af:89:01:a3:f7:98:6b:da:19:ba:86:ef:ef:
+                    f1:ce:bb:2f:89:ed:c0:b6:1b:e5:5b:f8:90:11:9a:
+                    52:93:e9:be:f7:35:b9:08:cb:ba:c3:ed:2f:73:af:
+                    cc:96:07:55:b5:de:f6:03:f6:f1:89:f9:21:40:76:
+                    c1:69:f2:61:cc:9a:94:df:9c:ec:6a:65:38:be:d1:
+                    4e:2a:87:c7:2f:3e:53:ae:8b:9f:54:a1:09:59:64:
+                    25:aa:a9:d8:44:a9:a8:a0:71:e1:32:aa:4c:32:fd:
+                    44:28:cc:9c:6f:8e:db:81:7e:6f:fa:00:56:c5:e5:
+                    03:46:63:fb:8e:71:8d:e3:13:91:9f:ac:60:3e:64:
+                    f3:df:25:34:09:fa:2d:96:9f:16:05:ea:93:f5:e6:
+                    00:08:27:32:7b:3c:bd:ee:70:24:6c:3b:55:e9:db:
+                    f4:10:2d:20:06:b4:ca:e9:29:65:55:ad:f6:52:54:
+                    5f:e5:a3
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Key Usage: 
+                Digital Signature
+            X509v3 Subject Key Identifier: 
+                14:DF:34:D1:A8:7C:F3:76:25:AB:EC:03:9E:F2:BF:52:12:49:B9:69
+            X509v3 Authority Key Identifier: 
+                keyid:14:DF:34:D1:A8:7C:F3:76:25:AB:EC:03:9E:F2:BF:52:12:49:B9:69
+
+    Signature Algorithm: sha512WithRSAEncryption
+         30:e7:48:02:37:e9:28:cf:04:a2:4d:5c:fa:d8:4e:c9:76:c7:
+         14:3f:bd:2c:51:3d:33:f0:1a:bc:49:f1:47:95:8f:69:d8:a9:
+         54:14:44:6c:4d:9f:55:82:08:1e:c6:5b:d5:91:d9:bc:2e:b0:
+         af:d6:25:65:74:96:aa:36:de:ae:31:a8:11:f2:a4:2c:5a:e1:
+         4f:73:f8:4a:c3:35:b0:76:96:71:f2:b5:7d:4b:75:ee:5d:bf:
+         86:a5:ba:0b:a9:52:cb:ec:ab:e5:23:4b:f2:74:55:28:17:1e:
+         b3:ac:27:ad:45:13:6e:69:b3:5a:be:42:36:29:48:db:e7:5c:
+         22:58:a0:90:82:2c:2a:21:2b:db:f4:64:b7:91:5d:1f:2c:48:
+         a4:1a:85:e3:86:a5:aa:19:cd:19:e8:a5:fb:a3:7b:94:77:48:
+         25:a4:cf:a0:cf:71:82:5c:6f:71:22:7c:d6:97:a0:53:bb:ec:
+         30:f6:cb:16:fb:7b:fd:16:94:7a:53:6e:bd:04:64:a2:01:10:
+         9f:f0:5b:b5:a6:73:41:9d:5f:6f:45:73:0d:05:f7:30:6d:39:
+         90:b6:7d:55:7d:4c:2f:ae:5f:38:56:2f:8b:df:f4:bf:12:06:
+         93:6e:0d:02:23:bf:71:91:57:88:e8:bd:62:72:99:00:40:29:
+         1e:c9:13:11:da:7e:8e:e1:d2:a5:0d:bf:f7:d6:ec:01:0d:89:
+         41:cd:d5:dc:d2:f7:5f:33:0d:4c:2f:85:b7:85:b7:81:e4:17:
+         29:f0:74:cf:0e:15:8c:1a:50:0b:08:63:1a:91:4f:e7:76:97:
+         f1:d4:3b:7e:72:d4:c5:45:58:0c:6a:e9:0d:f2:85:d8:91:1e:
+         37:bd:78:e3:39:4d:2e:fd:85:31:c1:a6:3b:6a:cc:2c:53:72:
+         1d:8e:7b:f0:e6:76:86:09:6f:1a:f3:e4:a1:e2:dd:76:5f:b0:
+         8c:e2:2a:54:5d:c1:88:49:90:10:15:42:7d:05:24:53:8c:54:
+         ff:48:18:1a:36:e3:31:d3:54:32:78:0d:fe:f2:3d:aa:0d:37:
+         15:84:b4:36:47:31:e8:85:6e:0b:58:38:ff:21:91:09:c9:a8:
+         43:a3:ea:60:cb:7e:ed:f7:41:6f:4e:91:c1:fd:77:46:e7:d4:
+         e7:86:c0:1b:fd:50:6c:aa:be:00:b3:63:02:ff:4e:c7:a5:57:
+         6e:29:64:e9:54:d5:30:63:38:5f:2d:5a:db:49:5f:14:14:22:
+         d2:81:1f:61:9e:ee:ee:16:66:d6:bc:bd:ac:1b:5c:fb:38:31:
+         95:33:2e:84:6e:7a:de:ee:b9:fc:97:17:06:13:bf:70:1c:6e:
+         76:ed:66:38:e2:70:08:00
+-----BEGIN CERTIFICATE-----
+MIIFODCCAyCgAwIBAgIJAMd+UWocJc1AMA0GCSqGSIb3DQEBDQUAMCwxKjAoBgNV
+BAMMIUNhbm9uaWNhbCBMdGQuIExpdmUgUGF0Y2ggU2lnbmluZzAeFw0xNjA3MTgy
+MzQxMjdaFw0yNjA3MTYyMzQxMjdaMCwxKjAoBgNVBAMMIUNhbm9uaWNhbCBMdGQu
+IExpdmUgUGF0Y2ggU2lnbmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
+ggIBAL107nKzSqvmMegpJMK9RpgywDnuo/uKrf6rGlujLqGA23lhnkd5LHVXoiHw
+k/aH8ptLnS+zWGEoPEFwExahcpDJ1RZxfOAw+SheSCA2AGm3WZ+j7KjrVUGfOB4i
+Slcg9INZScUAk9MzApLR/PCEO0pbj7Zzmon6MB7mKmjyke9ZVz3cHFJvXuabtbh8
+mMkT0TloAWeR4NNnchYKXhaDRTFPtSuz9kCGiTqEbm8WYbxwhL5aEzZ7guoHGfwY
+wRbGMgt9LGvEIbk4azHc2QytVkBofOPGZI6/HOByPmzb0nN52tfFL10EfbAHHpXd
+Kkdevz46yGb2Zw/UKvHicVnSbHugN6zml4AwE5dI1XT8OGjkV8uZaVqEJ6yYUeRk
+vZFi6FgnBiq5C7gI5eW0UaeiEN9OB2ygO5bybt91jJceZKCahpuYJvnYt95bIbev
+iQGj95hr2hm6hu/v8c67L4ntwLYb5Vv4kBGaUpPpvvc1uQjLusPtL3OvzJYHVbXe
+9gP28Yn5IUB2wWnyYcyalN+c7GplOL7RTiqHxy8+U66Ln1ShCVlkJaqp2ESpqKBx
+4TKqTDL9RCjMnG+O24F+b/oAVsXlA0Zj+45xjeMTkZ+sYD5k898lNAn6LZafFgXq
+k/XmAAgnMns8ve5wJGw7Venb9BAtIAa0yukpZVWt9lJUX+WjAgMBAAGjXTBbMAwG
+A1UdEwEB/wQCMAAwCwYDVR0PBAQDAgeAMB0GA1UdDgQWBBQU3zTRqHzzdiWr7AOe
+8r9SEkm5aTAfBgNVHSMEGDAWgBQU3zTRqHzzdiWr7AOe8r9SEkm5aTANBgkqhkiG
+9w0BAQ0FAAOCAgEAMOdIAjfpKM8Eok1c+thOyXbHFD+9LFE9M/AavEnxR5WPadip
+VBREbE2fVYIIHsZb1ZHZvC6wr9YlZXSWqjberjGoEfKkLFrhT3P4SsM1sHaWcfK1
+fUt17l2/hqW6C6lSy+yr5SNL8nRVKBces6wnrUUTbmmzWr5CNilI2+dcIligkIIs
+KiEr2/Rkt5FdHyxIpBqF44alqhnNGeil+6N7lHdIJaTPoM9xglxvcSJ81pegU7vs
+MPbLFvt7/RaUelNuvQRkogEQn/BbtaZzQZ1fb0VzDQX3MG05kLZ9VX1ML65fOFYv
+i9/0vxIGk24NAiO/cZFXiOi9YnKZAEApHskTEdp+juHSpQ2/99bsAQ2JQc3V3NL3
+XzMNTC+Ft4W3geQXKfB0zw4VjBpQCwhjGpFP53aX8dQ7fnLUxUVYDGrpDfKF2JEe
+N7144zlNLv2FMcGmO2rMLFNyHY578OZ2hglvGvPkoeLddl+wjOIqVF3BiEmQEBVC
+fQUkU4xU/0gYGjbjMdNUMngN/vI9qg03FYS0Nkcx6IVuC1g4/yGRCcmoQ6PqYMt+
+7fdBb06Rwf13RufU54bAG/1QbKq+ALNjAv9Ox6VXbilk6VTVMGM4Xy1a20lfFBQi
+0oEfYZ7u7hZm1ry9rBtc+zgxlTMuhG563u65/JcXBhO/cBxudu1mOOJwCAA=
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            e9:df:13:0f:92:92:a9:b7
+        Signature Algorithm: sha512WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Kernel Module Signing
+        Validity
+            Not Before: May 31 16:06:09 2016 GMT
+            Not After : May 29 16:06:09 2026 GMT
+        Subject: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Kernel Module Signing
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                RSA Public-Key: (4096 bit)
+                Modulus:
+                    00:b3:b0:4f:c6:0a:77:8b:f9:d1:53:33:34:d2:80:
+                    b5:63:6f:e1:f6:a2:83:99:d5:b6:b1:e4:99:91:fa:
+                    6c:19:c6:d0:91:2a:b9:7d:b5:98:a6:0d:28:01:b8:
+                    7c:8e:aa:38:ec:51:37:33:96:f0:b0:9b:8d:86:5f:
+                    67:23:69:2f:d7:c2:f3:fb:c5:d7:f9:04:ff:f2:e5:
+                    61:68:b7:29:b9:c6:8e:4b:4d:2d:8f:92:0c:00:b3:
+                    a3:d2:5a:08:64:cd:f2:09:0b:a5:0e:e6:64:75:d5:
+                    41:f4:4d:49:3a:0d:dc:b9:27:8e:c4:d6:b1:df:8f:
+                    6c:f0:e4:f7:31:cb:a9:04:a1:f9:a7:aa:15:da:59:
+                    03:4d:46:14:d0:dd:bf:e0:f5:9e:f0:71:0c:70:78:
+                    2b:08:fb:e0:b6:68:a4:74:12:9d:f7:f2:64:88:17:
+                    2a:8a:ed:1a:91:b5:6c:13:bd:4c:10:0a:0b:72:0b:
+                    90:db:7d:f3:78:44:4c:d2:a5:41:f7:1c:77:7d:5a:
+                    8a:54:bc:8f:fe:b7:ee:e1:bc:59:37:c4:d4:e8:14:
+                    d0:5b:42:9b:04:00:8e:6d:83:8a:25:21:5b:08:c4:
+                    7b:b2:d9:99:52:c9:5e:59:6d:c4:aa:52:59:e2:e4:
+                    2f:7e:7e:ac:05:01:99:bf:13:72:b7:45:c5:17:da:
+                    8a:d5:3e:71:73:2e:d8:aa:e6:eb:5a:d0:9a:c4:93:
+                    f3:be:eb:d2:47:25:34:16:29:fa:dd:9a:2f:b1:20:
+                    e5:41:4e:ed:ea:51:7c:23:80:ba:3d:b5:3a:0b:8c:
+                    9c:85:48:6c:3c:8b:29:2f:2f:12:c7:52:34:02:ea:
+                    0f:ac:53:23:3c:f8:3e:40:1b:30:63:e9:2d:e6:f6:
+                    58:cc:51:f9:eb:08:4a:b4:c7:16:80:d1:8b:c2:64:
+                    6a:71:a9:70:31:a4:a7:3a:c0:93:99:1b:0e:42:c1:
+                    00:6d:43:27:99:6c:e5:fd:23:16:c1:8e:b5:66:17:
+                    2b:4c:53:5a:6d:1e:96:16:13:6a:c6:d4:85:5b:74:
+                    2e:ce:7c:45:2f:ad:cb:75:9e:5e:91:bd:9a:6a:86:
+                    1a:06:bd:39:be:a3:50:56:ea:e1:f6:e3:95:69:d7:
+                    31:e4:66:f7:36:b5:51:c2:22:b4:9c:74:9c:44:0b:
+                    0e:16:5f:53:f0:23:c6:b9:40:bd:d6:b8:7d:1b:f6:
+                    73:f6:27:e7:c0:e3:65:a0:58:ab:5c:59:b7:80:8c:
+                    8c:04:b4:a9:ae:a0:51:40:10:3b:63:59:49:87:d1:
+                    9b:df:a3:8c:c4:2e:eb:70:c1:0a:18:1f:cb:22:c2:
+                    f2:4a:65:0d:e5:81:74:d8:ce:72:c6:35:be:ba:63:
+                    72:c4:f9
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Key Usage: 
+                Digital Signature
+            X509v3 Subject Key Identifier: 
+                88:F7:52:E5:60:A1:E0:73:7E:31:16:3A:46:6A:D7:B7:0A:85:0C:19
+            X509v3 Authority Key Identifier: 
+                keyid:88:F7:52:E5:60:A1:E0:73:7E:31:16:3A:46:6A:D7:B7:0A:85:0C:19
+
+    Signature Algorithm: sha512WithRSAEncryption
+         04:85:16:27:58:ba:71:28:57:86:7b:c2:83:db:e5:72:6f:1e:
+         b2:1c:63:b0:db:ad:c0:42:96:c0:4f:65:f6:35:4d:c0:07:0d:
+         46:be:d3:1e:ec:f1:22:18:2a:18:5d:bb:69:a6:a6:d4:0d:c3:
+         57:03:b9:e7:45:49:28:ca:6d:98:17:68:97:cb:7b:36:81:0a:
+         37:9e:34:79:f3:e1:0e:5b:77:43:bb:5a:a5:45:b7:16:50:86:
+         fd:12:a4:96:0f:15:19:09:1c:e1:fa:80:a5:80:09:be:bb:c8:
+         26:0b:3e:de:03:d2:c2:18:a4:8d:0d:de:c5:32:82:0b:fb:75:
+         55:66:1a:2a:bb:e4:bd:25:91:20:15:d4:be:b8:3f:53:e3:fb:
+         a8:c3:55:e3:d5:e7:82:18:95:df:39:09:a7:fc:89:6e:b4:1c:
+         aa:2d:e8:67:c2:0d:34:34:3e:f9:fa:0b:ce:81:92:11:ae:12:
+         0a:fe:35:63:ce:46:29:c4:2b:4f:cb:4e:05:0a:a1:11:e2:35:
+         f6:5a:5d:b5:e8:d2:6f:4c:fc:3d:24:a6:03:4b:dd:98:6b:f2:
+         71:58:16:1d:a5:25:ef:d9:06:7c:e8:db:7b:88:6a:89:5c:59:
+         01:92:64:db:44:08:63:6c:7c:32:d6:55:98:63:09:26:61:67:
+         0a:fe:5d:ee:fd:23:59:b3:4d:91:c1:4d:41:8b:cd:20:58:fa:
+         2d:45:e5:bd:1d:69:5c:03:a0:49:a6:97:54:13:b6:c9:e0:f8:
+         56:83:a1:2a:c3:f4:6c:fd:ab:20:ca:3d:9c:95:c0:cf:04:bb:
+         46:39:cf:34:81:65:45:27:64:01:7d:62:b3:b8:72:ea:10:d5:
+         0f:53:7d:39:88:25:09:6f:8c:bc:e0:49:bb:39:e2:0e:8d:cf:
+         56:4d:c1:82:6d:87:d2:e7:fc:c0:9f:a7:65:60:d2:6c:65:18:
+         59:38:6e:d0:9c:d7:c3:81:9a:9a:29:8f:83:84:c3:b5:44:ff:
+         28:ac:13:17:64:f2:26:13:d9:55:06:b7:69:68:7c:bf:ec:d1:
+         8c:ef:b7:da:76:e1:07:73:c6:31:62:31:cb:b6:e1:e7:7f:0c:
+         c3:f7:4c:52:be:25:36:8e:a1:bb:60:02:c3:cb:3e:6f:29:fc:
+         7f:6a:fa:f8:ec:0a:df:49:e2:57:0e:bc:bd:93:c3:1b:d5:36:
+         8a:ff:d8:1b:17:c7:1f:cb:69:00:d2:54:9e:ad:61:89:92:95:
+         11:f8:ea:17:83:9f:9b:09:7d:b8:94:a4:ea:f5:ae:ea:dc:dd:
+         62:b9:9e:68:9c:18:ec:19:c4:13:08:c8:b1:62:ab:8e:84:69:
+         11:3c:da:ea:0d:b7:22:bd
+-----BEGIN CERTIFICATE-----
+MIIF2jCCA8KgAwIBAgIJAOnfEw+Skqm3MA0GCSqGSIb3DQEBDQUAMH0xCzAJBgNV
+BAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEQMA4GA1UEBwwHRG91Z2xhczEX
+MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xLTArBgNVBAMMJENhbm9uaWNhbCBMdGQu
+IEtlcm5lbCBNb2R1bGUgU2lnbmluZzAeFw0xNjA1MzExNjA2MDlaFw0yNjA1Mjkx
+NjA2MDlaMH0xCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEQMA4G
+A1UEBwwHRG91Z2xhczEXMBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xLTArBgNVBAMM
+JENhbm9uaWNhbCBMdGQuIEtlcm5lbCBNb2R1bGUgU2lnbmluZzCCAiIwDQYJKoZI
+hvcNAQEBBQADggIPADCCAgoCggIBALOwT8YKd4v50VMzNNKAtWNv4faig5nVtrHk
+mZH6bBnG0JEquX21mKYNKAG4fI6qOOxRNzOW8LCbjYZfZyNpL9fC8/vF1/kE//Ll
+YWi3KbnGjktNLY+SDACzo9JaCGTN8gkLpQ7mZHXVQfRNSToN3LknjsTWsd+PbPDk
+9zHLqQSh+aeqFdpZA01GFNDdv+D1nvBxDHB4Kwj74LZopHQSnffyZIgXKortGpG1
+bBO9TBAKC3ILkNt983hETNKlQfccd31ailS8j/637uG8WTfE1OgU0FtCmwQAjm2D
+iiUhWwjEe7LZmVLJXlltxKpSWeLkL35+rAUBmb8TcrdFxRfaitU+cXMu2Krm61rQ
+msST877r0kclNBYp+t2aL7Eg5UFO7epRfCOAuj21OguMnIVIbDyLKS8vEsdSNALq
+D6xTIzz4PkAbMGPpLeb2WMxR+esISrTHFoDRi8JkanGpcDGkpzrAk5kbDkLBAG1D
+J5ls5f0jFsGOtWYXK0xTWm0elhYTasbUhVt0Ls58RS+ty3WeXpG9mmqGGga9Ob6j
+UFbq4fbjlWnXMeRm9za1UcIitJx0nEQLDhZfU/AjxrlAvda4fRv2c/Yn58DjZaBY
+q1xZt4CMjAS0qa6gUUAQO2NZSYfRm9+jjMQu63DBChgfyyLC8kplDeWBdNjOcsY1
+vrpjcsT5AgMBAAGjXTBbMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgeAMB0GA1Ud
+DgQWBBSI91LlYKHgc34xFjpGate3CoUMGTAfBgNVHSMEGDAWgBSI91LlYKHgc34x
+FjpGate3CoUMGTANBgkqhkiG9w0BAQ0FAAOCAgEABIUWJ1i6cShXhnvCg9vlcm8e
+shxjsNutwEKWwE9l9jVNwAcNRr7THuzxIhgqGF27aaam1A3DVwO550VJKMptmBdo
+l8t7NoEKN540efPhDlt3Q7tapUW3FlCG/RKklg8VGQkc4fqApYAJvrvIJgs+3gPS
+whikjQ3exTKCC/t1VWYaKrvkvSWRIBXUvrg/U+P7qMNV49XnghiV3zkJp/yJbrQc
+qi3oZ8INNDQ++foLzoGSEa4SCv41Y85GKcQrT8tOBQqhEeI19lpdtejSb0z8PSSm
+A0vdmGvycVgWHaUl79kGfOjbe4hqiVxZAZJk20QIY2x8MtZVmGMJJmFnCv5d7v0j
+WbNNkcFNQYvNIFj6LUXlvR1pXAOgSaaXVBO2yeD4VoOhKsP0bP2rIMo9nJXAzwS7
+RjnPNIFlRSdkAX1is7hy6hDVD1N9OYglCW+MvOBJuzniDo3PVk3Bgm2H0uf8wJ+n
+ZWDSbGUYWThu0JzXw4GamimPg4TDtUT/KKwTF2TyJhPZVQa3aWh8v+zRjO+32nbh
+B3PGMWIxy7bh538Mw/dMUr4lNo6hu2ACw8s+byn8f2r6+OwK30niVw68vZPDG9U2
+iv/YGxfHH8tpANJUnq1hiZKVEfjqF4Ofmwl9uJSk6vWu6tzdYrmeaJwY7BnEEwjI
+sWKrjoRpETza6g23Ir0=
+-----END CERTIFICATE-----
--- linux-qcom-6.8.0.orig/debian/canonical-revoked-certs.pem
+++ linux-qcom-6.8.0/debian/canonical-revoked-certs.pem
@@ -0,0 +1,688 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Apr 12 11:39:08 2012 GMT
+            Not After : Apr 11 11:39:08 2042 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:c9:5f:9b:62:8f:0b:b0:64:82:ac:be:c9:e2:62:
+                    e3:4b:d2:9f:1e:8a:d5:61:1a:2b:5d:38:f4:b7:ce:
+                    b9:9a:b8:43:b8:43:97:77:ab:4f:7f:0c:70:46:0b:
+                    fc:7f:6d:c6:6d:ea:80:5e:01:d2:b7:66:1e:87:de:
+                    0d:6d:d0:41:97:a8:a5:af:0c:63:4f:f7:7c:c2:52:
+                    cc:a0:31:a9:bb:89:5d:99:1e:46:6f:55:73:b9:76:
+                    69:ec:d7:c1:fc:21:d6:c6:07:e7:4f:bd:22:de:e4:
+                    a8:5b:2d:db:95:34:19:97:d6:28:4b:21:4c:ca:bb:
+                    1d:79:a6:17:7f:5a:f9:67:e6:5c:78:45:3d:10:6d:
+                    b0:17:59:26:11:c5:57:e3:7f:4e:82:ba:f6:2c:4e:
+                    c8:37:4d:ff:85:15:84:47:e0:ed:3b:7c:7f:bc:af:
+                    e9:01:05:a7:0c:6f:c3:e9:8d:a3:ce:be:a6:e3:cd:
+                    3c:b5:58:2c:9e:c2:03:1c:60:22:37:39:ff:41:02:
+                    c1:29:a4:65:51:ff:33:34:aa:42:15:f9:95:78:fc:
+                    2d:f5:da:8a:85:7c:82:9d:fb:37:2c:6b:a5:a8:df:
+                    7c:55:0b:80:2e:3c:b0:63:e1:cd:38:48:89:e8:14:
+                    06:0b:82:bc:fd:d4:07:68:1b:0f:3e:d9:15:dd:94:
+                    11:1b
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                61:48:2A:A2:83:0D:0A:B2:AD:5A:F1:0B:72:50:DA:90:33:DD:CE:F0
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        8f:8a:a1:06:1f:29:b7:0a:4a:d5:c5:fd:81:ab:25:ea:c0:7d:
+        e2:fc:6a:96:a0:79:93:67:ee:05:0e:25:12:25:e4:5a:f6:aa:
+        1a:f1:12:f3:05:8d:87:5e:f1:5a:5c:cb:8d:23:73:65:1d:15:
+        b9:de:22:6b:d6:49:67:c9:a3:c6:d7:62:4e:5c:b5:f9:03:83:
+        40:81:dc:87:9c:3c:3f:1c:0d:51:9f:94:65:0a:84:48:67:e4:
+        a2:f8:a6:4a:f0:e7:cd:cd:bd:94:e3:09:d2:5d:2d:16:1b:05:
+        15:0b:cb:44:b4:3e:61:42:22:c4:2a:5c:4e:c5:1d:a3:e2:e0:
+        52:b2:eb:f4:8b:2b:dc:38:39:5d:fb:88:a1:56:65:5f:2b:4f:
+        26:ff:06:78:10:12:eb:8c:5d:32:e3:c6:45:af:25:9b:a0:ff:
+        8e:ef:47:09:a3:e9:8b:37:92:92:69:76:7e:34:3b:92:05:67:
+        4e:b0:25:ed:bc:5e:5f:8f:b4:d6:ca:40:ff:e4:e2:31:23:0c:
+        85:25:ae:0c:55:01:ec:e5:47:5e:df:5b:bc:14:33:e3:c6:f5:
+        18:b6:d9:f7:dd:b3:b4:a1:31:d3:5a:5c:5d:7d:3e:bf:0a:e4:
+        e4:e8:b4:59:7d:3b:b4:8c:a3:1b:b5:20:a3:b9:3e:84:6f:8c:
+        21:00:c3:39
+-----BEGIN CERTIFICATE-----
+MIIEIDCCAwigAwIBAgIBATANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xMjA0MTIxMTM5MDhaFw00MjA0MTEx
+MTM5MDhaMH8xCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEXMBUG
+A1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MSswKQYD
+VQQDDCJDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nMIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyV+bYo8LsGSCrL7J4mLjS9KfHorVYRor
+XTj0t865mrhDuEOXd6tPfwxwRgv8f23GbeqAXgHSt2Yeh94NbdBBl6ilrwxjT/d8
+wlLMoDGpu4ldmR5Gb1VzuXZp7NfB/CHWxgfnT70i3uSoWy3blTQZl9YoSyFMyrsd
+eaYXf1r5Z+ZceEU9EG2wF1kmEcVX439Ogrr2LE7IN03/hRWER+DtO3x/vK/pAQWn
+DG/D6Y2jzr6m4808tVgsnsIDHGAiNzn/QQLBKaRlUf8zNKpCFfmVePwt9dqKhXyC
+nfs3LGulqN98VQuALjywY+HNOEiJ6BQGC4K8/dQHaBsPPtkV3ZQRGwIDAQABo4Gg
+MIGdMAwGA1UdEwEB/wQCMAAwHwYDVR0lBBgwFgYIKwYBBQUHAwMGCisGAQQBgjcK
+AwYwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRl
+MB0GA1UdDgQWBBRhSCqigw0Ksq1a8QtyUNqQM93O8DAfBgNVHSMEGDAWgBStkZkL
+wiqx9RcEjCO2ZVomjjRaYzANBgkqhkiG9w0BAQsFAAOCAQEAj4qhBh8ptwpK1cX9
+gasl6sB94vxqlqB5k2fuBQ4lEiXkWvaqGvES8wWNh17xWlzLjSNzZR0Vud4ia9ZJ
+Z8mjxtdiTly1+QODQIHch5w8PxwNUZ+UZQqESGfkovimSvDnzc29lOMJ0l0tFhsF
+FQvLRLQ+YUIixCpcTsUdo+LgUrLr9Isr3Dg5XfuIoVZlXytPJv8GeBAS64xdMuPG
+Ra8lm6D/ju9HCaPpizeSkml2fjQ7kgVnTrAl7bxeX4+01spA/+TiMSMMhSWuDFUB
+7OVHXt9bvBQz48b1GLbZ992ztKEx01pcXX0+vwrk5Oi0WX07tIyjG7Ugo7k+hG+M
+IQDDOQ==
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 2 (0x2)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Sep 26 21:52:11 2017 GMT
+            Not After : Sep 25 21:52:11 2047 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2017)
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:ef:9f:fa:9f:19:3a:9d:38:23:91:cc:c4:f9:42:
+                    e0:f8:54:12:82:dc:97:2c:d6:5b:c1:35:eb:ff:4a:
+                    74:06:b5:9d:32:aa:7b:f3:fc:31:5a:34:3e:a1:a4:
+                    44:db:7b:6d:16:af:35:76:e0:9b:99:ad:21:11:c6:
+                    12:4b:ae:24:8f:bb:d3:b2:00:fe:c5:1d:9b:3a:1a:
+                    4a:6c:ca:fa:16:37:85:22:f9:ff:22:fc:40:e0:58:
+                    35:c1:39:27:b4:c6:42:1a:96:d8:a5:c5:95:2e:f7:
+                    c5:1e:21:6e:36:84:f7:a9:a1:e1:f1:03:08:96:65:
+                    71:f8:eb:83:cf:82:f7:9a:44:58:72:00:14:39:29:
+                    4b:e9:78:2f:65:20:b3:80:76:3b:ba:0d:2d:46:f6:
+                    37:05:e7:05:fe:bd:6c:c7:a2:65:b5:06:6e:07:24:
+                    99:a1:c1:cf:e1:0e:5e:49:41:71:17:a8:50:e7:38:
+                    99:e5:6e:b6:db:9f:63:db:56:f4:9c:7d:89:f6:d2:
+                    03:6c:99:83:e0:99:23:39:36:bd:cb:b5:26:7c:7d:
+                    b0:c6:fe:82:7c:52:ed:f9:2c:8f:79:71:3d:a9:2f:
+                    b5:aa:7e:77:a0:fd:69:f9:97:10:a8:b2:c6:7d:88:
+                    9e:a2:19:bd:31:b8:02:2d:34:4d:9d:98:60:82:ad:
+                    04:ff
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                24:2A:DE:75:AC:4A:15:E5:0D:50:C8:4B:0D:45:FF:3E:AE:70:7A:03
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        00:b2:b7:57:b5:2b:5d:16:d3:04:88:6a:d7:77:d5:0d:89:f1:
+        d2:6e:11:d1:8e:f5:62:05:c4:6a:57:df:eb:d2:86:68:f2:fd:
+        a7:37:11:3c:f4:ce:5d:fe:32:5f:31:a2:6b:3a:da:28:c2:88:
+        fa:7f:70:b5:25:99:ea:27:9a:56:6a:9d:b2:0f:14:99:e2:b7:
+        c6:39:1e:8e:a7:76:31:d9:ed:c5:05:8d:48:ae:1b:68:18:14:
+        51:a1:7d:f6:c7:df:cb:9d:eb:a4:3b:0b:ff:c2:07:c5:42:bc:
+        0d:b2:11:fa:37:17:2b:1c:b5:84:48:2d:f9:31:4a:57:49:8e:
+        61:a6:82:11:06:4c:34:ea:9c:2a:47:4d:eb:e0:26:af:da:d2:
+        c2:08:a0:37:35:7b:73:71:de:0b:c4:ba:c8:34:de:20:04:03:
+        6f:46:26:0d:b9:91:02:5b:71:76:cc:45:e4:08:d0:a6:dd:a4:
+        50:d3:d9:04:91:2b:d9:5c:34:88:fc:c2:37:fd:c6:d4:3e:57:
+        f7:6b:ba:7b:d7:02:7a:84:0c:c8:c1:19:cc:bc:fa:52:d5:7f:
+        b3:35:c4:53:5d:70:0a:f6:44:60:8d:a9:11:7a:1b:7d:ae:7b:
+        20:5a:4c:8d:44:f6:c1:a9:61:cb:dc:cb:90:37:d5:28:24:73:
+        87:d0:e0:d8
+-----BEGIN CERTIFICATE-----
+MIIEKDCCAxCgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNzA5MjYyMTUyMTFaFw00NzA5MjUy
+MTUyMTFaMIGGMQswCQYDVQQGEwJHQjEUMBIGA1UECAwLSXNsZSBvZiBNYW4xFzAV
+BgNVBAoMDkNhbm9uaWNhbCBMdGQuMRQwEgYDVQQLDAtTZWN1cmUgQm9vdDEyMDAG
+A1UEAwwpQ2Fub25pY2FsIEx0ZC4gU2VjdXJlIEJvb3QgU2lnbmluZyAoMjAxNykw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvn/qfGTqdOCORzMT5QuD4
+VBKC3Jcs1lvBNev/SnQGtZ0yqnvz/DFaND6hpETbe20WrzV24JuZrSERxhJLriSP
+u9OyAP7FHZs6GkpsyvoWN4Ui+f8i/EDgWDXBOSe0xkIaltilxZUu98UeIW42hPep
+oeHxAwiWZXH464PPgveaRFhyABQ5KUvpeC9lILOAdju6DS1G9jcF5wX+vWzHomW1
+Bm4HJJmhwc/hDl5JQXEXqFDnOJnlbrbbn2PbVvScfYn20gNsmYPgmSM5Nr3LtSZ8
+fbDG/oJ8Uu35LI95cT2pL7Wqfneg/Wn5lxCossZ9iJ6iGb0xuAItNE2dmGCCrQT/
+AgMBAAGjgaAwgZ0wDAYDVR0TAQH/BAIwADAfBgNVHSUEGDAWBggrBgEFBQcDAwYK
+KwYBBAGCNwoDBjAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
+dGlmaWNhdGUwHQYDVR0OBBYEFCQq3nWsShXlDVDISw1F/z6ucHoDMB8GA1UdIwQY
+MBaAFK2RmQvCKrH1FwSMI7ZlWiaONFpjMA0GCSqGSIb3DQEBCwUAA4IBAQAAsrdX
+tStdFtMEiGrXd9UNifHSbhHRjvViBcRqV9/r0oZo8v2nNxE89M5d/jJfMaJrOtoo
+woj6f3C1JZnqJ5pWap2yDxSZ4rfGOR6Op3Yx2e3FBY1IrhtoGBRRoX32x9/Lneuk
+Owv/wgfFQrwNshH6NxcrHLWESC35MUpXSY5hpoIRBkw06pwqR03r4Cav2tLCCKA3
+NXtzcd4LxLrINN4gBANvRiYNuZECW3F2zEXkCNCm3aRQ09kEkSvZXDSI/MI3/cbU
+Plf3a7p71wJ6hAzIwRnMvPpS1X+zNcRTXXAK9kRgjakReht9rnsgWkyNRPbBqWHL
+3MuQN9UoJHOH0ODY
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 3 (0x3)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Oct 26 18:31:14 2018 GMT
+            Not After : Oct 24 18:31:14 2048 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (ESM 2018)
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:bf:6a:e5:6d:55:7a:ec:7a:11:37:45:9c:4c:8f:
+                    6b:2d:56:d3:74:2b:32:ac:84:2d:ba:cb:cc:ec:8d:
+                    92:22:69:48:a5:d4:f6:75:11:66:2f:cb:b2:fd:9e:
+                    56:ab:e6:f1:52:8e:75:3e:50:bd:25:b3:50:fc:ef:
+                    3d:76:f3:3f:7f:03:f6:e2:a1:25:69:5c:14:98:54:
+                    bd:11:bf:e9:a5:ac:46:91:4b:1d:de:b7:18:2b:c8:
+                    22:83:15:a7:4a:00:8d:9d:e4:c0:da:f7:41:02:fd:
+                    9f:5f:79:93:56:cc:86:e1:b5:e0:39:0e:3c:a2:5b:
+                    fe:c0:56:f0:92:50:5a:2b:67:67:93:56:d7:7a:75:
+                    99:6a:25:b4:63:a8:5f:69:7e:3a:49:58:2a:a7:80:
+                    f6:5a:b4:be:b2:be:a8:8c:45:41:c9:f2:fc:76:a8:
+                    65:ef:99:29:0d:c9:9c:54:6b:0a:f0:4a:0e:61:0d:
+                    ed:99:32:af:12:e2:12:7b:9f:7b:ec:05:c4:e0:b6:
+                    d5:c3:71:28:ae:dd:0b:ba:97:ad:68:0b:76:e9:bf:
+                    e7:01:7e:64:54:39:23:85:36:c8:9d:dd:27:a1:ff:
+                    df:46:36:14:7e:cb:cc:a1:cd:49:0b:6d:c2:0c:45:
+                    99:56:58:7c:87:0d:59:9a:dc:4a:39:3b:1d:d9:15:
+                    2e:b5
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                36:51:88:C1:D3:74:D6:B0:7C:3C:8F:24:0F:8E:F7:22:43:3D:6A:8B
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        4c:0f:cd:77:60:b4:6f:53:87:f3:3c:4f:e6:81:5f:a7:1c:cc:
+        60:29:b6:34:6c:4d:08:9b:e2:d2:bd:f6:17:1a:62:79:b8:17:
+        bc:a2:60:59:fd:03:51:c3:b7:6b:de:73:b3:48:95:f5:0b:aa:
+        b6:3c:b4:34:dc:1d:0b:c4:97:62:87:e7:48:d5:8f:c9:ea:e8:
+        91:8f:2a:40:cd:b7:b3:ee:b2:98:9e:fb:37:31:29:e6:8e:2f:
+        0a:39:99:1e:c6:aa:b8:05:62:85:d3:a8:3e:60:38:98:0f:f0:
+        fe:c7:ab:01:a5:6a:a5:7f:70:a6:26:94:76:23:2f:08:89:74:
+        97:c2:2a:ca:22:3e:7a:ea:22:22:08:07:f4:bb:f6:bc:69:9c:
+        4e:44:33:e2:8e:70:17:b0:9b:cb:33:94:66:6d:ff:9a:7d:e9:
+        50:b2:e8:90:14:e4:2b:91:cb:a0:c5:2e:0e:cf:19:ef:44:ef:
+        84:f0:bd:57:9e:26:c2:63:3d:df:fc:a1:84:de:5c:d7:5f:3b:
+        fb:94:61:f0:93:89:1f:cf:c3:b2:d1:90:97:35:7d:b9:8a:ad:
+        e6:05:f0:e8:3b:a1:7c:af:2b:c4:af:18:33:2e:5e:87:db:9d:
+        80:b5:04:fd:00:d0:60:ab:ff:85:77:0f:cb:47:22:c9:b2:85:
+        a8:48:16:e2
+-----BEGIN CERTIFICATE-----
+MIIELDCCAxSgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xODEwMjYxODMxMTRaFw00ODEwMjQx
+ODMxMTRaMIGKMQswCQYDVQQGEwJHQjEUMBIGA1UECAwLSXNsZSBvZiBNYW4xFzAV
+BgNVBAoMDkNhbm9uaWNhbCBMdGQuMRQwEgYDVQQLDAtTZWN1cmUgQm9vdDE2MDQG
+A1UEAwwtQ2Fub25pY2FsIEx0ZC4gU2VjdXJlIEJvb3QgU2lnbmluZyAoRVNNIDIw
+MTgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2rlbVV67HoRN0Wc
+TI9rLVbTdCsyrIQtusvM7I2SImlIpdT2dRFmL8uy/Z5Wq+bxUo51PlC9JbNQ/O89
+dvM/fwP24qElaVwUmFS9Eb/ppaxGkUsd3rcYK8gigxWnSgCNneTA2vdBAv2fX3mT
+VsyG4bXgOQ48olv+wFbwklBaK2dnk1bXenWZaiW0Y6hfaX46SVgqp4D2WrS+sr6o
+jEVByfL8dqhl75kpDcmcVGsK8EoOYQ3tmTKvEuISe5977AXE4LbVw3Eort0Lupet
+aAt26b/nAX5kVDkjhTbInd0nof/fRjYUfsvMoc1JC23CDEWZVlh8hw1ZmtxKOTsd
+2RUutQIDAQABo4GgMIGdMAwGA1UdEwEB/wQCMAAwHwYDVR0lBBgwFgYIKwYBBQUH
+AwMGCisGAQQBgjcKAwYwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVk
+IENlcnRpZmljYXRlMB0GA1UdDgQWBBQ2UYjB03TWsHw8jyQPjvciQz1qizAfBgNV
+HSMEGDAWgBStkZkLwiqx9RcEjCO2ZVomjjRaYzANBgkqhkiG9w0BAQsFAAOCAQEA
+TA/Nd2C0b1OH8zxP5oFfpxzMYCm2NGxNCJvi0r32FxpiebgXvKJgWf0DUcO3a95z
+s0iV9Quqtjy0NNwdC8SXYofnSNWPyerokY8qQM23s+6ymJ77NzEp5o4vCjmZHsaq
+uAVihdOoPmA4mA/w/serAaVqpX9wpiaUdiMvCIl0l8IqyiI+euoiIggH9Lv2vGmc
+TkQz4o5wF7CbyzOUZm3/mn3pULLokBTkK5HLoMUuDs8Z70TvhPC9V54mwmM93/yh
+hN5c1187+5Rh8JOJH8/DstGQlzV9uYqt5gXw6DuhfK8rxK8YMy5eh9udgLUE/QDQ
+YKv/hXcPy0ciybKFqEgW4g==
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 4 (0x4)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Sep 18 16:10:17 2019 GMT
+            Not After : Sep 16 16:10:17 2049 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2019)
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:e6:47:d8:75:e5:87:59:26:87:83:7d:5b:7a:b8:
+                    58:3d:7c:ef:36:f8:a0:7a:b7:14:56:58:7d:01:f1:
+                    1c:3b:8c:e6:5b:03:77:7d:a0:ed:47:0a:45:e6:75:
+                    5c:de:95:38:0d:38:fa:41:79:89:56:31:87:e7:a3:
+                    9a:36:70:b6:cf:24:2f:99:26:89:08:39:0e:14:c3:
+                    35:be:02:8b:52:e1:8e:7b:0c:a6:9d:78:ff:01:60:
+                    d7:f5:c3:d5:f0:5e:dc:e4:23:09:59:72:93:d3:b5:
+                    22:af:7c:cd:e0:84:0f:af:11:2d:bc:c6:72:42:af:
+                    ea:67:63:c4:10:41:78:02:80:62:0d:43:74:b4:1c:
+                    ed:50:d7:94:f1:b0:bb:f9:57:80:e4:69:0f:83:4b:
+                    a2:e6:2c:4a:9a:e1:7d:7c:62:19:29:27:97:1f:4c:
+                    f1:85:f0:39:f5:31:9f:3a:39:0e:d4:4d:07:3a:40:
+                    55:4b:a6:6c:9d:04:89:51:2d:7c:b0:ef:40:b5:42:
+                    29:16:cc:65:73:38:62:21:f6:e3:2c:17:50:9d:74:
+                    34:4e:df:7c:4a:33:a4:bb:40:cf:d5:e5:ed:05:07:
+                    cd:4c:f9:af:7f:a6:5c:b9:f7:c5:16:45:4e:44:40:
+                    d7:85:32:de:ac:e5:75:ad:9b:d7:c0:26:33:1f:77:
+                    a5:37
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                C0:74:6F:D6:C5:DA:3A:E8:27:86:46:51:AD:66:AE:47:FE:24:B3:E8
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        aa:12:6c:d1:9d:6a:da:f0:ec:7c:17:46:3b:57:b8:d6:76:5f:
+        24:e6:06:a2:0a:55:1f:2f:d3:5e:8f:de:cf:02:f2:ff:e0:dd:
+        d3:c7:bd:75:59:aa:cd:34:f3:28:80:73:cc:28:69:e7:a2:70:
+        88:a2:c7:dc:66:f0:92:0e:ff:64:bf:30:04:54:01:1b:96:ad:
+        15:c5:61:fd:32:61:d7:5e:b5:ba:91:fd:31:fc:6b:15:df:ee:
+        22:d9:e4:1f:f3:cc:8b:0c:9f:f5:e8:f7:e2:62:3f:40:52:c9:
+        f0:f1:1c:63:fc:6c:90:e1:5b:74:03:b9:df:d1:3e:a8:ec:db:
+        2b:6e:83:6f:9f:7f:ba:b4:79:fc:3d:e7:12:2f:4a:e7:17:8c:
+        2b:77:a5:90:74:3c:bd:cf:75:83:0d:1a:95:d5:56:ef:07:9b:
+        a6:b3:31:e3:8c:97:ce:68:11:b5:7b:25:03:72:1c:ea:67:e9:
+        7c:3e:73:c7:7c:3e:fc:f5:ae:8a:b2:07:0d:15:6a:66:09:d7:
+        23:b9:5d:80:7a:26:d6:b6:22:30:aa:84:af:c0:42:e9:75:c3:
+        59:ab:a3:84:87:6b:0c:b7:ab:4e:92:69:ae:2c:82:6f:ab:01:
+        24:ab:ff:78:6d:59:85:c2:3b:23:c0:bd:0d:d8:6e:3a:29:82:
+        e1:c4:5f:db
+-----BEGIN CERTIFICATE-----
+MIIEKDCCAxCgAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xOTA5MTgxNjEwMTdaFw00OTA5MTYx
+NjEwMTdaMIGGMQswCQYDVQQGEwJHQjEUMBIGA1UECAwLSXNsZSBvZiBNYW4xFzAV
+BgNVBAoMDkNhbm9uaWNhbCBMdGQuMRQwEgYDVQQLDAtTZWN1cmUgQm9vdDEyMDAG
+A1UEAwwpQ2Fub25pY2FsIEx0ZC4gU2VjdXJlIEJvb3QgU2lnbmluZyAoMjAxOSkw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDmR9h15YdZJoeDfVt6uFg9
+fO82+KB6txRWWH0B8Rw7jOZbA3d9oO1HCkXmdVzelTgNOPpBeYlWMYfno5o2cLbP
+JC+ZJokIOQ4UwzW+AotS4Y57DKadeP8BYNf1w9XwXtzkIwlZcpPTtSKvfM3ghA+v
+ES28xnJCr+pnY8QQQXgCgGINQ3S0HO1Q15TxsLv5V4DkaQ+DS6LmLEqa4X18Yhkp
+J5cfTPGF8Dn1MZ86OQ7UTQc6QFVLpmydBIlRLXyw70C1QikWzGVzOGIh9uMsF1Cd
+dDRO33xKM6S7QM/V5e0FB81M+a9/ply598UWRU5EQNeFMt6s5XWtm9fAJjMfd6U3
+AgMBAAGjgaAwgZ0wDAYDVR0TAQH/BAIwADAfBgNVHSUEGDAWBggrBgEFBQcDAwYK
+KwYBBAGCNwoDBjAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
+dGlmaWNhdGUwHQYDVR0OBBYEFMB0b9bF2jroJ4ZGUa1mrkf+JLPoMB8GA1UdIwQY
+MBaAFK2RmQvCKrH1FwSMI7ZlWiaONFpjMA0GCSqGSIb3DQEBCwUAA4IBAQCqEmzR
+nWra8Ox8F0Y7V7jWdl8k5gaiClUfL9Nej97PAvL/4N3Tx711WarNNPMogHPMKGnn
+onCIosfcZvCSDv9kvzAEVAEblq0VxWH9MmHXXrW6kf0x/GsV3+4i2eQf88yLDJ/1
+6PfiYj9AUsnw8Rxj/GyQ4Vt0A7nf0T6o7NsrboNvn3+6tHn8PecSL0rnF4wrd6WQ
+dDy9z3WDDRqV1VbvB5umszHjjJfOaBG1eyUDchzqZ+l8PnPHfD789a6KsgcNFWpm
+CdcjuV2AeibWtiIwqoSvwELpdcNZq6OEh2sMt6tOkmmuLIJvqwEkq/94bVmFwjsj
+wL0N2G46KYLhxF/b
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 6 (0x6)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Sep 23 19:29:32 2021 GMT
+            Not After : Sep 22 19:29:32 2051 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2021 v1)
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:aa:b8:34:5b:b6:ae:44:bf:41:e1:78:11:b9:7a:
+                    c8:88:b3:b0:26:50:10:9c:98:d1:f3:98:9f:23:50:
+                    64:f6:39:dd:50:3a:23:44:53:65:fc:f3:9f:f5:a5:
+                    8b:ae:8b:df:47:9f:e9:d5:a0:92:19:f1:21:ea:cc:
+                    59:3a:74:df:45:71:bc:de:64:15:a5:f6:db:ca:71:
+                    fa:19:d4:44:0d:12:ec:47:3a:43:e2:f2:dd:8b:fe:
+                    0d:7b:dc:4d:db:53:06:22:61:e5:8b:35:49:b6:33:
+                    c4:0a:69:5f:5b:81:09:84:6b:42:33:18:09:9d:a0:
+                    35:f7:9c:1e:de:6e:de:90:69:1a:e8:32:e4:49:ad:
+                    c3:31:e9:f8:4a:a2:28:1d:db:0d:29:b6:48:0a:44:
+                    93:86:41:62:8f:73:97:60:10:8a:74:46:66:55:fe:
+                    a0:95:35:9e:ef:9f:af:11:fa:5b:a3:7c:c2:35:64:
+                    11:67:28:1e:14:0a:7d:68:61:9c:cd:c7:46:39:30:
+                    31:79:94:56:b3:45:16:9a:b5:77:66:fe:41:43:0f:
+                    00:48:6e:99:dd:0c:d4:47:2c:86:8c:50:04:61:20:
+                    dd:aa:8e:73:4f:21:b4:ee:09:4d:d3:40:01:d0:f2:
+                    a7:5b:7d:05:3d:c1:e7:65:26:aa:8c:9a:58:5a:7c:
+                    6d:6f
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                A8:D5:4B:BB:38:25:CF:B9:4F:A1:3C:9F:8A:59:4A:19:5C:10:7B:8D
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        24:25:25:7e:01:a5:c8:3d:54:8c:1b:05:73:d1:06:d8:db:d4:
+        3a:71:d5:19:9d:97:1c:85:3c:ca:38:5a:0c:25:25:39:1a:67:
+        bc:6c:9d:98:6c:f3:7d:5f:b7:40:f9:73:a0:f5:7b:40:a8:66:
+        a5:f1:53:b1:78:80:24:3f:19:50:2f:02:09:ec:a1:8a:e6:0d:
+        df:c4:ae:24:9e:69:0d:5c:dc:44:4c:38:3a:53:4e:4b:a1:4b:
+        92:9f:43:a4:9d:1e:76:33:18:1b:bf:62:e5:f5:bc:93:3c:4e:
+        21:d5:5b:20:69:11:28:c1:c5:93:b5:8e:96:1d:1b:ca:72:79:
+        24:de:67:2a:50:9d:ce:8b:41:dd:3e:82:dd:a5:04:75:54:fb:
+        35:70:98:87:b4:f3:ea:41:23:23:80:0e:99:d7:03:16:ee:7e:
+        11:e2:c8:29:ab:73:c5:6d:5c:a8:2f:32:03:9f:8e:66:d6:cb:
+        54:84:55:75:ab:9a:dd:95:fd:05:1e:11:85:37:1e:63:d2:f4:
+        7f:34:64:32:a1:63:91:91:50:39:14:1a:ea:54:78:e6:0d:04:
+        23:c7:83:51:c5:25:27:07:6c:f8:65:b7:da:95:89:76:83:cc:
+        f3:7e:06:74:d3:6c:ef:e9:17:de:29:1e:ab:5c:d7:ec:df:f1:
+        98:b8:e9:66
+-----BEGIN CERTIFICATE-----
+MIIELTCCAxWgAwIBAgIBBjANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAgFw0yMTA5MjMxOTI5MzJaGA8yMDUxMDky
+MjE5MjkzMlowgYkxCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEX
+MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MTUw
+MwYDVQQDDCxDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nICgyMDIx
+IHYxKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKq4NFu2rkS/QeF4
+Ebl6yIizsCZQEJyY0fOYnyNQZPY53VA6I0RTZfzzn/Wli66L30ef6dWgkhnxIerM
+WTp030VxvN5kFaX228px+hnURA0S7Ec6Q+Ly3Yv+DXvcTdtTBiJh5Ys1SbYzxApp
+X1uBCYRrQjMYCZ2gNfecHt5u3pBpGugy5EmtwzHp+EqiKB3bDSm2SApEk4ZBYo9z
+l2AQinRGZlX+oJU1nu+frxH6W6N8wjVkEWcoHhQKfWhhnM3HRjkwMXmUVrNFFpq1
+d2b+QUMPAEhumd0M1EcshoxQBGEg3aqOc08htO4JTdNAAdDyp1t9BT3B52Umqoya
+WFp8bW8CAwEAAaOBoDCBnTAMBgNVHRMBAf8EAjAAMB8GA1UdJQQYMBYGCCsGAQUF
+BwMDBgorBgEEAYI3CgMGMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRl
+ZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUqNVLuzglz7lPoTyfillKGVwQe40wHwYD
+VR0jBBgwFoAUrZGZC8IqsfUXBIwjtmVaJo40WmMwDQYJKoZIhvcNAQELBQADggEB
+ACQlJX4Bpcg9VIwbBXPRBtjb1Dpx1RmdlxyFPMo4WgwlJTkaZ7xsnZhs831ft0D5
+c6D1e0CoZqXxU7F4gCQ/GVAvAgnsoYrmDd/EriSeaQ1c3ERMODpTTkuhS5KfQ6Sd
+HnYzGBu/YuX1vJM8TiHVWyBpESjBxZO1jpYdG8pyeSTeZypQnc6LQd0+gt2lBHVU
++zVwmIe08+pBIyOADpnXAxbufhHiyCmrc8VtXKgvMgOfjmbWy1SEVXWrmt2V/QUe
+EYU3HmPS9H80ZDKhY5GRUDkUGupUeOYNBCPHg1HFJScHbPhlt9qViXaDzPN+BnTT
+bO/pF94pHqtc1+zf8Zi46WY=
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 7 (0x7)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Sep 23 19:29:42 2021 GMT
+            Not After : Sep 22 19:29:42 2051 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2021 v2)
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:ba:06:8b:ee:58:b7:8b:49:7b:53:7a:d1:df:02:
+                    e3:f2:d8:b0:8c:03:5c:f4:2d:0b:d8:18:3b:23:fa:
+                    68:b0:e8:e9:9d:dc:a2:eb:5e:d3:06:a9:28:d4:9f:
+                    14:b6:1e:1c:1d:ef:69:0e:7f:44:f2:cc:4a:f1:b1:
+                    d0:71:30:6a:50:1e:b0:d3:f8:a4:19:d0:4a:f1:e3:
+                    eb:7a:e5:57:4c:a1:fb:d1:87:b9:48:e0:55:37:52:
+                    f9:de:99:2e:95:85:36:ce:d3:1d:67:2f:14:cb:7f:
+                    05:82:75:21:b6:aa:a5:14:ac:da:4a:f4:fe:fa:5c:
+                    33:49:3d:6f:de:fd:9d:75:ba:e2:c4:02:38:b5:69:
+                    f5:ff:a8:67:4b:3a:e0:34:f6:3b:07:03:a5:7e:59:
+                    6f:3a:d2:28:a4:2f:25:ac:d8:a9:1f:59:52:5d:24:
+                    36:58:51:b5:f0:12:a8:d3:78:56:57:b1:e0:a9:df:
+                    14:05:65:7c:b5:a5:00:f0:88:39:14:44:18:85:2d:
+                    0c:28:69:7b:b9:b4:1c:47:6f:43:66:4c:22:ad:f7:
+                    f6:19:75:e1:14:2c:0d:33:3f:c1:3f:fc:73:56:b2:
+                    68:05:b5:92:03:9b:65:6b:81:80:92:35:03:9b:66:
+                    68:58:c5:66:11:b6:8c:7f:05:09:9a:45:a6:0e:5e:
+                    5f:bf
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                4C:F0:46:89:2D:6F:D3:C9:A5:B0:3F:98:D8:45:F9:08:51:DC:6A:8C
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        93:9d:49:7d:9f:3e:3e:27:79:97:d9:c2:fc:0b:f7:30:b7:f4:
+        78:b2:c9:e4:5e:42:d3:27:26:70:cf:88:96:d1:f2:ea:a0:75:
+        7e:3c:f6:b7:d2:e7:95:30:e3:a6:67:a7:ee:b9:53:8f:fd:b2:
+        cb:db:e1:98:32:be:98:79:09:46:c6:63:6a:57:87:4d:b2:26:
+        46:f6:34:5e:18:75:ca:82:80:8e:33:c2:1d:c7:76:d7:14:57:
+        ef:2e:0e:9e:58:5c:81:8e:ed:53:2c:07:46:0a:8a:fc:2f:f5:
+        b2:c8:58:f5:fa:fa:bb:f9:7d:47:13:39:f0:f2:1c:15:9c:75:
+        90:40:bd:08:04:b3:6a:de:c2:cd:34:21:7e:ba:31:48:bc:a1:
+        23:bc:ee:93:b2:62:96:27:30:86:c2:d4:f7:b4:e6:3c:71:47:
+        37:84:ff:3d:0c:1e:ec:f3:0e:da:6b:dc:64:7a:b8:c0:7e:45:
+        13:09:bf:02:b3:b7:5b:6d:09:2d:6a:4e:0b:93:94:29:4c:a6:
+        c3:c7:05:fa:69:08:04:53:3c:4c:64:c0:7e:89:00:91:1b:a6:
+        c2:d7:ea:c4:db:86:38:fe:66:03:85:7b:fc:39:24:99:4c:2a:
+        3e:10:8b:91:c3:6e:20:9d:0c:ee:51:70:b5:98:58:f3:5c:ac:
+        16:98:7b:ce
+-----BEGIN CERTIFICATE-----
+MIIELTCCAxWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAgFw0yMTA5MjMxOTI5NDJaGA8yMDUxMDky
+MjE5Mjk0MlowgYkxCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEX
+MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MTUw
+MwYDVQQDDCxDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nICgyMDIx
+IHYyKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALoGi+5Yt4tJe1N6
+0d8C4/LYsIwDXPQtC9gYOyP6aLDo6Z3coute0wapKNSfFLYeHB3vaQ5/RPLMSvGx
+0HEwalAesNP4pBnQSvHj63rlV0yh+9GHuUjgVTdS+d6ZLpWFNs7THWcvFMt/BYJ1
+IbaqpRSs2kr0/vpcM0k9b979nXW64sQCOLVp9f+oZ0s64DT2OwcDpX5ZbzrSKKQv
+JazYqR9ZUl0kNlhRtfASqNN4Vlex4KnfFAVlfLWlAPCIORREGIUtDChpe7m0HEdv
+Q2ZMIq339hl14RQsDTM/wT/8c1ayaAW1kgObZWuBgJI1A5tmaFjFZhG2jH8FCZpF
+pg5eX78CAwEAAaOBoDCBnTAMBgNVHRMBAf8EAjAAMB8GA1UdJQQYMBYGCCsGAQUF
+BwMDBgorBgEEAYI3CgMGMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRl
+ZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUTPBGiS1v08mlsD+Y2EX5CFHcaowwHwYD
+VR0jBBgwFoAUrZGZC8IqsfUXBIwjtmVaJo40WmMwDQYJKoZIhvcNAQELBQADggEB
+AJOdSX2fPj4neZfZwvwL9zC39HiyyeReQtMnJnDPiJbR8uqgdX489rfS55Uw46Zn
+p+65U4/9ssvb4Zgyvph5CUbGY2pXh02yJkb2NF4YdcqCgI4zwh3HdtcUV+8uDp5Y
+XIGO7VMsB0YKivwv9bLIWPX6+rv5fUcTOfDyHBWcdZBAvQgEs2rews00IX66MUi8
+oSO87pOyYpYnMIbC1Pe05jxxRzeE/z0MHuzzDtpr3GR6uMB+RRMJvwKzt1ttCS1q
+TguTlClMpsPHBfppCARTPExkwH6JAJEbpsLX6sTbhjj+ZgOFe/w5JJlMKj4Qi5HD
+biCdDO5RcLWYWPNcrBaYe84=
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 8 (0x8)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Sep 23 19:30:02 2021 GMT
+            Not After : Sep 22 19:30:02 2051 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2021 v3)
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:d6:29:96:87:ae:07:42:45:bb:65:09:b2:9b:de:
+                    5d:8e:78:61:10:d5:6d:ae:ae:26:08:6a:06:ec:4a:
+                    dd:2b:e7:1a:a9:ad:78:e3:fc:cf:8f:d1:47:bd:1e:
+                    33:d8:7a:e3:66:9b:e9:73:c1:5f:42:e2:fe:bc:c3:
+                    41:f7:cd:d7:85:d7:42:c9:ea:31:e5:47:b1:93:5b:
+                    43:2b:07:51:b8:75:08:ad:0f:e7:0d:81:38:5a:21:
+                    df:b1:43:5b:db:37:c5:ac:aa:14:3a:33:19:6a:26:
+                    e0:05:fe:cd:41:31:af:5d:a8:ab:31:77:44:fc:da:
+                    00:e2:7a:44:33:c3:a7:ed:13:54:9f:19:5d:c9:98:
+                    a2:3b:af:4d:0d:87:29:9c:90:9e:42:9e:9a:06:6a:
+                    70:27:c5:aa:f7:a2:f2:88:e0:b9:66:9a:72:a0:f6:
+                    61:7e:30:8f:14:9f:44:0d:dd:54:ae:47:c8:82:ba:
+                    d2:b2:db:6f:24:c1:f4:0a:81:07:90:47:49:5f:57:
+                    d6:3f:bf:2a:73:98:f2:f6:24:1a:74:03:d7:35:f0:
+                    42:d8:14:c5:94:27:5d:3c:49:0c:b0:f0:7a:61:1b:
+                    d7:5a:e3:a3:40:57:e9:a4:07:ee:02:a3:32:27:94:
+                    bb:f3:36:c5:5f:ef:d3:07:04:3a:80:4c:9c:0a:b7:
+                    88:9f
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                10:04:37:BB:6D:E6:E4:69:B5:81:E6:1C:D6:6B:CE:3E:F4:ED:53:AF
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        3b:37:d6:a8:8d:cd:d2:df:13:35:ac:8c:92:d6:b0:ac:d1:38:
+        a8:00:97:47:59:b8:4a:84:8c:80:a5:1d:c7:29:bf:00:66:e5:
+        10:40:26:2e:31:f5:e1:13:c0:1b:29:f3:0b:7e:2d:71:d8:db:
+        e1:32:8f:79:8e:e3:97:0c:40:a9:a0:12:c1:fc:c2:50:88:72:
+        44:c5:bc:8b:45:6e:28:fd:d2:37:d6:db:17:cf:4e:61:33:08:
+        5a:5d:08:94:73:44:e2:76:00:44:1b:b8:00:a1:86:00:64:8a:
+        f1:42:32:3c:28:11:67:7c:8b:aa:06:34:74:58:e8:b3:3a:36:
+        8d:f6:04:5d:37:f5:66:52:c9:48:b0:a7:6f:34:09:dd:60:2a:
+        86:b9:14:f1:09:f6:06:16:56:e0:51:b1:e8:75:7f:fa:37:dc:
+        e0:98:a7:69:ae:7b:1a:73:89:0d:06:67:cc:01:ef:80:31:45:
+        9e:bb:03:2a:eb:89:70:d6:19:b2:c7:ce:bc:81:df:da:c8:6f:
+        a9:4b:2d:d7:a7:e1:af:c6:e8:fb:f0:61:c9:cd:d2:91:cd:8b:
+        c2:6c:ef:e0:b6:7f:f1:c4:81:f9:bb:76:9c:26:e3:fa:a1:a0:
+        cd:5e:05:de:ee:f9:1b:5b:50:0a:8b:0f:47:e3:90:32:ac:2a:
+        e7:65:02:80
+-----BEGIN CERTIFICATE-----
+MIIELTCCAxWgAwIBAgIBCDANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAgFw0yMTA5MjMxOTMwMDJaGA8yMDUxMDky
+MjE5MzAwMlowgYkxCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEX
+MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MTUw
+MwYDVQQDDCxDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nICgyMDIx
+IHYzKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANYploeuB0JFu2UJ
+spveXY54YRDVba6uJghqBuxK3SvnGqmteOP8z4/RR70eM9h642ab6XPBX0Li/rzD
+QffN14XXQsnqMeVHsZNbQysHUbh1CK0P5w2BOFoh37FDW9s3xayqFDozGWom4AX+
+zUExr12oqzF3RPzaAOJ6RDPDp+0TVJ8ZXcmYojuvTQ2HKZyQnkKemgZqcCfFqvei
+8ojguWaacqD2YX4wjxSfRA3dVK5HyIK60rLbbyTB9AqBB5BHSV9X1j+/KnOY8vYk
+GnQD1zXwQtgUxZQnXTxJDLDwemEb11rjo0BX6aQH7gKjMieUu/M2xV/v0wcEOoBM
+nAq3iJ8CAwEAAaOBoDCBnTAMBgNVHRMBAf8EAjAAMB8GA1UdJQQYMBYGCCsGAQUF
+BwMDBgorBgEEAYI3CgMGMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRl
+ZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUEAQ3u23m5Gm1geYc1mvOPvTtU68wHwYD
+VR0jBBgwFoAUrZGZC8IqsfUXBIwjtmVaJo40WmMwDQYJKoZIhvcNAQELBQADggEB
+ADs31qiNzdLfEzWsjJLWsKzROKgAl0dZuEqEjIClHccpvwBm5RBAJi4x9eETwBsp
+8wt+LXHY2+Eyj3mO45cMQKmgEsH8wlCIckTFvItFbij90jfW2xfPTmEzCFpdCJRz
+ROJ2AEQbuAChhgBkivFCMjwoEWd8i6oGNHRY6LM6No32BF039WZSyUiwp280Cd1g
+Koa5FPEJ9gYWVuBRseh1f/o33OCYp2muexpziQ0GZ8wB74AxRZ67AyrriXDWGbLH
+zryB39rIb6lLLden4a/G6PvwYcnN0pHNi8Js7+C2f/HEgfm7dpwm4/qhoM1eBd7u
++RtbUAqLD0fjkDKsKudlAoA=
+-----END CERTIFICATE-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 3 (0x3)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Mar  4 10:27:14 2020 GMT
+            Not After : Mar  3 10:27:14 2050 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (Ubuntu Core 2019)
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:b9:10:47:2e:75:5d:f3:10:23:bb:a0:75:d2:fa:
+                    02:2d:ff:22:df:c1:e6:cd:38:7c:36:0f:ae:74:15:
+                    6e:a5:34:52:2b:c3:a4:3a:60:d7:06:ee:1d:99:93:
+                    ff:66:91:a3:18:52:2c:8c:58:e6:b4:2f:4b:c5:fb:
+                    83:e6:f3:19:bd:1b:ca:23:ec:97:1f:d8:f1:9a:f1:
+                    04:da:da:10:04:53:4b:ec:1d:b6:26:47:7c:bb:8f:
+                    a7:0a:6e:2e:e8:91:e6:c4:bb:64:34:78:3c:fa:09:
+                    15:1c:8f:9e:eb:04:99:36:22:c6:8d:07:15:0f:b9:
+                    69:08:fa:ff:4b:45:bd:ba:2b:cd:01:0e:e7:01:23:
+                    c9:e5:7a:39:3b:91:b0:45:3c:d5:77:ba:ca:f9:29:
+                    3d:11:3f:1c:6b:5b:8e:6c:4b:3f:c9:29:05:cb:59:
+                    d6:b1:c1:c0:2d:56:88:70:27:fa:73:05:5c:c2:11:
+                    d4:27:11:f7:0b:c2:d5:68:d3:1a:cd:ed:d0:e4:10:
+                    ff:34:cb:b7:45:70:34:2c:23:53:b6:9c:30:70:b4:
+                    5c:d1:e2:64:18:82:8f:62:b1:5e:aa:0b:d4:89:f2:
+                    1c:53:c4:32:7d:ef:53:ee:9b:6e:02:ab:78:bd:25:
+                    67:8b:39:36:d8:84:3b:06:99:02:d6:75:73:4e:f2:
+                    f6:b9
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                C1:D5:7B:8F:6B:74:3F:23:EE:41:F4:F7:EE:29:2F:06:EE:CA:DF:B9
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        2d:b5:11:a8:d2:a0:af:81:a0:18:22:18:2c:08:d0:f4:63:e8:
+        8f:9a:f4:f5:20:dd:eb:22:77:19:9a:1a:09:3d:7f:aa:7d:c9:
+        81:bc:26:98:65:94:46:30:4b:c2:51:7c:f7:21:41:63:87:31:
+        fc:a4:c9:41:28:c7:2e:2a:2e:d8:a8:75:7a:72:77:3b:1b:9f:
+        72:15:0d:0c:96:8d:8b:51:f3:ce:37:b6:ca:9f:ca:59:40:4a:
+        fc:73:7a:94:12:99:aa:c2:8d:52:ce:91:19:2e:b4:da:ff:e5:
+        2c:67:74:d9:58:47:38:2f:61:88:c5:cf:a7:48:e1:08:ba:bc:
+        ec:d5:3a:47:d9:8c:dc:c3:bc:cb:98:2b:79:7a:02:46:ef:85:
+        19:2f:03:4b:05:84:eb:56:98:5f:6d:cf:a5:8b:a2:b6:e5:50:
+        51:7c:33:44:bd:7a:94:2e:0d:90:39:39:3e:62:60:ae:3a:e2:
+        f5:17:fa:f1:94:06:1d:ae:a3:f8:19:20:7f:4b:4c:07:c4:e6:
+        2d:0d:e5:94:84:51:6d:6f:0f:c4:c6:79:1d:f0:e8:0e:23:9e:
+        fd:f9:46:2c:b9:ec:97:38:56:7e:b8:13:f6:d2:e1:8e:a5:93:
+        02:7b:6e:dd:33:9a:bf:10:a8:1b:3d:fa:c4:f2:15:f0:27:73:
+        26:a6:94:d1
+-----BEGIN CERTIFICATE-----
+MIIENjCCAx6gAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAgFw0yMDAzMDQxMDI3MTRaGA8yMDUwMDMw
+MzEwMjcxNFowgZIxCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEX
+MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MT4w
+PAYDVQQDDDVDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nIChVYnVu
+dHUgQ29yZSAyMDE5KTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALkQ
+Ry51XfMQI7ugddL6Ai3/It/B5s04fDYPrnQVbqU0UivDpDpg1wbuHZmT/2aRoxhS
+LIxY5rQvS8X7g+bzGb0byiPslx/Y8ZrxBNraEARTS+wdtiZHfLuPpwpuLuiR5sS7
+ZDR4PPoJFRyPnusEmTYixo0HFQ+5aQj6/0tFvborzQEO5wEjyeV6OTuRsEU81Xe6
+yvkpPRE/HGtbjmxLP8kpBctZ1rHBwC1WiHAn+nMFXMIR1CcR9wvC1WjTGs3t0OQQ
+/zTLt0VwNCwjU7acMHC0XNHiZBiCj2KxXqoL1InyHFPEMn3vU+6bbgKreL0lZ4s5
+NtiEOwaZAtZ1c07y9rkCAwEAAaOBoDCBnTAMBgNVHRMBAf8EAjAAMB8GA1UdJQQY
+MBYGCCsGAQUFBwMDBgorBgEEAYI3CgMGMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM
+IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUwdV7j2t0PyPuQfT37ikv
+Bu7K37kwHwYDVR0jBBgwFoAUrZGZC8IqsfUXBIwjtmVaJo40WmMwDQYJKoZIhvcN
+AQELBQADggEBAC21EajSoK+BoBgiGCwI0PRj6I+a9PUg3esidxmaGgk9f6p9yYG8
+JphllEYwS8JRfPchQWOHMfykyUEoxy4qLtiodXpydzsbn3IVDQyWjYtR8843tsqf
+yllASvxzepQSmarCjVLOkRkutNr/5SxndNlYRzgvYYjFz6dI4Qi6vOzVOkfZjNzD
+vMuYK3l6AkbvhRkvA0sFhOtWmF9tz6WLorblUFF8M0S9epQuDZA5OT5iYK464vUX
++vGUBh2uo/gZIH9LTAfE5i0N5ZSEUW1vD8TGeR3w6A4jnv35Riy57Jc4Vn64E/bS
+4Y6lkwJ7bt0zmr8QqBs9+sTyFfAncyamlNE=
+-----END CERTIFICATE-----
--- linux-qcom-6.8.0.orig/debian/certs/canonical-livepatch-2025-all.pem
+++ linux-qcom-6.8.0/debian/certs/canonical-livepatch-2025-all.pem
@@ -0,0 +1,125 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            47:77:26:6d:ae:6c:57:73:eb:80:e2:96:dd:26:93:ff:e9:f5:62:5d
+        Signature Algorithm: sha512WithRSAEncryption
+        Issuer: CN=Canonical Ltd. Live Patch Signing 2025 Kmod
+        Validity
+            Not Before: May 16 09:07:40 2025 GMT
+            Not After : May 16 09:07:40 2050 GMT
+        Subject: CN=Canonical Ltd. Live Patch Signing 2025 Kmod
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (4096 bit)
+                Modulus:
+                    00:b8:a9:03:47:2e:7b:c6:86:16:f4:b7:a8:4d:3b:
+                    05:f6:c4:75:35:e9:22:8a:4e:40:06:89:15:7f:ad:
+                    99:bb:e6:90:93:61:c8:16:cf:2e:00:1b:81:36:fd:
+                    cc:31:7b:97:79:8d:5e:d2:4d:d3:2f:ab:35:2d:74:
+                    48:98:b3:d9:75:f9:bb:e1:f2:3f:6b:6d:dc:e4:bb:
+                    ee:f5:aa:f7:8a:8c:7a:a8:0b:df:b1:f8:d6:04:13:
+                    27:e9:1a:aa:c2:4d:d2:35:3a:bc:06:d7:83:7f:e8:
+                    c4:1c:63:8b:3a:ff:0e:0b:89:6e:4f:5f:ea:ad:78:
+                    df:37:ab:f9:55:1d:fb:6e:29:a4:22:43:d1:9b:12:
+                    1e:b2:84:23:1b:d2:38:91:b8:a8:6c:1c:59:3c:ff:
+                    4c:a9:18:ce:d0:7f:1d:ef:04:cf:8a:e8:29:b2:4b:
+                    68:0d:92:32:bc:9c:5d:8f:0a:d1:dd:4d:25:ba:3a:
+                    8c:6a:48:5b:1e:9c:01:10:99:c1:a7:34:ee:68:ec:
+                    a1:d3:26:be:45:c8:b4:97:ac:8a:aa:7e:13:a6:e5:
+                    43:f1:1b:3f:a1:80:0a:d2:a9:e7:f2:77:ca:e1:f5:
+                    29:36:df:75:8a:7e:02:d6:17:aa:46:12:b9:51:f0:
+                    6b:ca:22:f8:05:de:d6:02:47:76:0c:88:f1:c6:90:
+                    44:99:58:71:c7:62:1e:2b:94:c5:2b:8e:dc:ca:7b:
+                    a7:bd:cd:38:8f:4e:73:6d:b0:9b:4e:7c:12:1f:5c:
+                    c5:62:d6:82:c6:d2:78:09:52:dc:d7:78:2e:23:d0:
+                    63:1f:7d:77:91:c8:3f:66:7a:20:8a:cf:70:09:0f:
+                    a2:c0:82:a5:42:d9:be:dc:5f:78:73:f7:fa:3c:70:
+                    47:7b:39:77:89:5a:6f:ef:83:09:c9:1b:21:53:89:
+                    7c:10:bf:99:9c:05:39:32:1e:84:3b:a5:84:7e:ef:
+                    08:6d:b0:b0:31:61:d6:1a:aa:dd:7a:d6:10:02:e6:
+                    72:02:e5:40:bf:07:b9:cd:61:d1:55:04:9a:cd:02:
+                    73:41:c1:df:20:30:12:97:ca:a1:83:1a:97:8a:92:
+                    1c:47:5c:0a:60:da:41:3b:e6:0e:2c:82:ce:45:65:
+                    81:ba:45:a1:66:cc:ef:ab:65:5c:e5:a8:0c:86:dd:
+                    fc:86:54:f3:37:7c:89:a9:0c:fa:3a:da:82:c9:90:
+                    99:1e:1d:66:44:de:d3:c5:d4:0b:da:15:f8:d8:d4:
+                    63:2b:4e:6f:24:e9:c2:d7:74:9c:29:91:9f:25:39:
+                    8d:77:15:8c:cb:8e:ad:e3:80:0a:ea:79:04:72:9d:
+                    51:01:18:ae:35:51:ef:95:79:38:c4:db:99:50:47:
+                    62:38:e9
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Key Usage: 
+                Digital Signature
+            X509v3 Subject Key Identifier: 
+                D5:41:CE:F6:1D:C7:E7:93:B7:EB:7E:89:99:70:A2:EE:F0:B5:DC:8C
+            X509v3 Authority Key Identifier: 
+                D5:41:CE:F6:1D:C7:E7:93:B7:EB:7E:89:99:70:A2:EE:F0:B5:DC:8C
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.2312.16.1.2
+    Signature Algorithm: sha512WithRSAEncryption
+    Signature Value:
+        40:9d:5b:70:66:fe:9c:99:eb:ed:78:61:be:da:67:da:ac:80:
+        a8:c2:78:91:f8:90:11:be:9f:6a:e7:bf:79:dc:11:0c:c7:83:
+        e8:13:c4:1c:b6:fe:f0:e7:7d:1a:12:97:5d:19:56:9c:10:12:
+        1e:b9:19:88:30:95:c4:3b:2f:aa:91:6f:c1:9e:68:4a:f4:5c:
+        ef:a1:51:b5:a3:9b:58:3f:e2:ae:5c:29:a6:c4:30:fd:65:0b:
+        cc:8c:99:95:33:61:c6:07:fa:c3:bd:1a:57:80:e5:43:97:2e:
+        f3:5c:d6:1e:b7:23:9f:58:10:19:24:46:9e:f8:fd:2c:8e:88:
+        e7:ec:ef:15:4b:7a:6a:ce:b0:25:c0:01:c5:21:83:1a:d5:89:
+        0c:90:86:ad:d4:3e:6e:28:bf:6c:21:91:ff:b9:a9:ef:d4:ac:
+        de:7c:67:c1:e4:ed:75:26:15:ff:5d:67:39:24:2d:15:57:21:
+        09:76:e5:85:f3:45:e8:bf:b1:c0:39:2b:83:34:1a:f5:3f:1f:
+        ae:07:8c:82:1f:d4:dc:95:c0:4e:f3:7f:ac:db:8f:2c:db:a4:
+        d4:2a:4c:8c:de:e6:5b:84:fc:df:a3:74:d8:dc:9c:93:1f:5b:
+        c9:33:b5:b3:7d:2b:a4:4d:7a:bb:73:92:ff:8d:e9:9e:c7:a7:
+        d2:0d:83:bb:2c:2f:47:51:15:5c:6d:db:9a:d3:9e:6e:25:90:
+        01:e6:09:bd:a2:d0:1e:cf:a3:12:22:0d:56:70:bf:89:e4:be:
+        62:76:9c:d9:f5:c8:01:55:95:02:57:a1:67:59:88:97:57:f6:
+        bb:8d:c9:40:d5:e3:60:4f:43:dd:49:90:fa:a5:6d:08:96:b2:
+        4d:dd:a7:c6:e3:5c:06:ba:af:8c:30:9d:d5:a5:b0:ab:c4:e5:
+        f3:09:47:05:ba:9b:46:f4:26:70:3b:fa:da:a5:0a:47:ce:be:
+        43:87:eb:73:63:3b:cd:41:7a:78:a0:f6:7d:c5:37:fb:bb:26:
+        3b:b3:e7:44:49:06:8c:14:03:fc:b3:46:54:3b:0d:57:02:08:
+        99:79:68:a2:9c:62:95:4d:ac:8e:19:43:4e:8f:2d:52:fa:91:
+        ca:78:06:a2:b7:a3:66:6d:67:0b:13:ee:b1:01:38:e0:7c:ac:
+        9a:16:27:36:f1:45:83:5d:eb:d6:cd:65:3f:56:9a:d3:56:c4:
+        15:55:b2:64:ca:13:cb:31:1e:7e:03:85:68:61:40:02:99:4b:
+        25:01:68:8d:97:cc:39:1a:54:1b:e5:51:38:8e:ce:66:74:61:
+        5e:87:f4:31:7d:0d:be:9d:01:e1:b3:5c:bc:1a:d0:ea:5e:b2:
+        c8:ee:97:34:bc:9f:bb:98
+-----BEGIN CERTIFICATE-----
+MIIFejCCA2KgAwIBAgIUR3cmba5sV3PrgOKW3SaT/+n1Yl0wDQYJKoZIhvcNAQEN
+BQAwNjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTGl2ZSBQYXRjaCBTaWduaW5n
+IDIwMjUgS21vZDAgFw0yNTA1MTYwOTA3NDBaGA8yMDUwMDUxNjA5MDc0MFowNjE0
+MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTGl2ZSBQYXRjaCBTaWduaW5nIDIwMjUg
+S21vZDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALipA0cue8aGFvS3
+qE07BfbEdTXpIopOQAaJFX+tmbvmkJNhyBbPLgAbgTb9zDF7l3mNXtJN0y+rNS10
+SJiz2XX5u+HyP2tt3OS77vWq94qMeqgL37H41gQTJ+kaqsJN0jU6vAbXg3/oxBxj
+izr/DguJbk9f6q143zer+VUd+24ppCJD0ZsSHrKEIxvSOJG4qGwcWTz/TKkYztB/
+He8Ez4roKbJLaA2SMrycXY8K0d1NJbo6jGpIWx6cARCZwac07mjsodMmvkXItJes
+iqp+E6blQ/EbP6GACtKp5/J3yuH1KTbfdYp+AtYXqkYSuVHwa8oi+AXe1gJHdgyI
+8caQRJlYccdiHiuUxSuO3Mp7p73NOI9Oc22wm058Eh9cxWLWgsbSeAlS3Nd4LiPQ
+Yx99d5HIP2Z6IIrPcAkPosCCpULZvtxfeHP3+jxwR3s5d4lab++DCckbIVOJfBC/
+mZwFOTIehDulhH7vCG2wsDFh1hqq3XrWEALmcgLlQL8Huc1h0VUEms0Cc0HB3yAw
+EpfKoYMal4qSHEdcCmDaQTvmDiyCzkVlgbpFoWbM76tlXOWoDIbd/IZU8zd8iakM
++jragsmQmR4dZkTe08XUC9oV+NjUYytObyTpwtd0nCmRnyU5jXcVjMuOreOACup5
+BHKdUQEYrjVR75V5OMTbmVBHYjjpAgMBAAGjfjB8MAwGA1UdEwEB/wQCMAAwCwYD
+VR0PBAQDAgeAMB0GA1UdDgQWBBTVQc72Hcfnk7frfomZcKLu8LXcjDAfBgNVHSME
+GDAWgBTVQc72Hcfnk7frfomZcKLu8LXcjDAfBgNVHSUEGDAWBggrBgEFBQcDAwYK
+KwYBBAGSCBABAjANBgkqhkiG9w0BAQ0FAAOCAgEAQJ1bcGb+nJnr7Xhhvtpn2qyA
+qMJ4kfiQEb6faue/edwRDMeD6BPEHLb+8Od9GhKXXRlWnBASHrkZiDCVxDsvqpFv
+wZ5oSvRc76FRtaObWD/irlwppsQw/WULzIyZlTNhxgf6w70aV4DlQ5cu81zWHrcj
+n1gQGSRGnvj9LI6I5+zvFUt6as6wJcABxSGDGtWJDJCGrdQ+bii/bCGR/7mp79Ss
+3nxnweTtdSYV/11nOSQtFVchCXblhfNF6L+xwDkrgzQa9T8frgeMgh/U3JXATvN/
+rNuPLNuk1CpMjN7mW4T836N02Nyckx9byTO1s30rpE16u3OS/43pnsen0g2Duywv
+R1EVXG3bmtOebiWQAeYJvaLQHs+jEiINVnC/ieS+Ynac2fXIAVWVAlehZ1mIl1f2
+u43JQNXjYE9D3UmQ+qVtCJayTd2nxuNcBrqvjDCd1aWwq8Tl8wlHBbqbRvQmcDv6
+2qUKR86+Q4frc2M7zUF6eKD2fcU3+7smO7PnREkGjBQD/LNGVDsNVwIImXloopxi
+lU2sjhlDTo8tUvqRyngGorejZm1nCxPusQE44HysmhYnNvFFg13r1s1lP1aa01bE
+FVWyZMoTyzEefgOFaGFAAplLJQFojZfMORpUG+VROI7OZnRhXof0MX0Nvp0B4bNc
+vBrQ6l6yyO6XNLyfu5g=
+-----END CERTIFICATE-----
--- linux-qcom-6.8.0.orig/debian/certs/canonical-livepatch-all.pem
+++ linux-qcom-6.8.0/debian/certs/canonical-livepatch-all.pem
@@ -0,0 +1,121 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            c7:7e:51:6a:1c:25:cd:40
+        Signature Algorithm: sha512WithRSAEncryption
+        Issuer: CN = Canonical Ltd. Live Patch Signing
+        Validity
+            Not Before: Jul 18 23:41:27 2016 GMT
+            Not After : Jul 16 23:41:27 2026 GMT
+        Subject: CN = Canonical Ltd. Live Patch Signing
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                RSA Public-Key: (4096 bit)
+                Modulus:
+                    00:bd:74:ee:72:b3:4a:ab:e6:31:e8:29:24:c2:bd:
+                    46:98:32:c0:39:ee:a3:fb:8a:ad:fe:ab:1a:5b:a3:
+                    2e:a1:80:db:79:61:9e:47:79:2c:75:57:a2:21:f0:
+                    93:f6:87:f2:9b:4b:9d:2f:b3:58:61:28:3c:41:70:
+                    13:16:a1:72:90:c9:d5:16:71:7c:e0:30:f9:28:5e:
+                    48:20:36:00:69:b7:59:9f:a3:ec:a8:eb:55:41:9f:
+                    38:1e:22:4a:57:20:f4:83:59:49:c5:00:93:d3:33:
+                    02:92:d1:fc:f0:84:3b:4a:5b:8f:b6:73:9a:89:fa:
+                    30:1e:e6:2a:68:f2:91:ef:59:57:3d:dc:1c:52:6f:
+                    5e:e6:9b:b5:b8:7c:98:c9:13:d1:39:68:01:67:91:
+                    e0:d3:67:72:16:0a:5e:16:83:45:31:4f:b5:2b:b3:
+                    f6:40:86:89:3a:84:6e:6f:16:61:bc:70:84:be:5a:
+                    13:36:7b:82:ea:07:19:fc:18:c1:16:c6:32:0b:7d:
+                    2c:6b:c4:21:b9:38:6b:31:dc:d9:0c:ad:56:40:68:
+                    7c:e3:c6:64:8e:bf:1c:e0:72:3e:6c:db:d2:73:79:
+                    da:d7:c5:2f:5d:04:7d:b0:07:1e:95:dd:2a:47:5e:
+                    bf:3e:3a:c8:66:f6:67:0f:d4:2a:f1:e2:71:59:d2:
+                    6c:7b:a0:37:ac:e6:97:80:30:13:97:48:d5:74:fc:
+                    38:68:e4:57:cb:99:69:5a:84:27:ac:98:51:e4:64:
+                    bd:91:62:e8:58:27:06:2a:b9:0b:b8:08:e5:e5:b4:
+                    51:a7:a2:10:df:4e:07:6c:a0:3b:96:f2:6e:df:75:
+                    8c:97:1e:64:a0:9a:86:9b:98:26:f9:d8:b7:de:5b:
+                    21:b7:af:89:01:a3:f7:98:6b:da:19:ba:86:ef:ef:
+                    f1:ce:bb:2f:89:ed:c0:b6:1b:e5:5b:f8:90:11:9a:
+                    52:93:e9:be:f7:35:b9:08:cb:ba:c3:ed:2f:73:af:
+                    cc:96:07:55:b5:de:f6:03:f6:f1:89:f9:21:40:76:
+                    c1:69:f2:61:cc:9a:94:df:9c:ec:6a:65:38:be:d1:
+                    4e:2a:87:c7:2f:3e:53:ae:8b:9f:54:a1:09:59:64:
+                    25:aa:a9:d8:44:a9:a8:a0:71:e1:32:aa:4c:32:fd:
+                    44:28:cc:9c:6f:8e:db:81:7e:6f:fa:00:56:c5:e5:
+                    03:46:63:fb:8e:71:8d:e3:13:91:9f:ac:60:3e:64:
+                    f3:df:25:34:09:fa:2d:96:9f:16:05:ea:93:f5:e6:
+                    00:08:27:32:7b:3c:bd:ee:70:24:6c:3b:55:e9:db:
+                    f4:10:2d:20:06:b4:ca:e9:29:65:55:ad:f6:52:54:
+                    5f:e5:a3
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Key Usage: 
+                Digital Signature
+            X509v3 Subject Key Identifier: 
+                14:DF:34:D1:A8:7C:F3:76:25:AB:EC:03:9E:F2:BF:52:12:49:B9:69
+            X509v3 Authority Key Identifier: 
+                keyid:14:DF:34:D1:A8:7C:F3:76:25:AB:EC:03:9E:F2:BF:52:12:49:B9:69
+
+    Signature Algorithm: sha512WithRSAEncryption
+         30:e7:48:02:37:e9:28:cf:04:a2:4d:5c:fa:d8:4e:c9:76:c7:
+         14:3f:bd:2c:51:3d:33:f0:1a:bc:49:f1:47:95:8f:69:d8:a9:
+         54:14:44:6c:4d:9f:55:82:08:1e:c6:5b:d5:91:d9:bc:2e:b0:
+         af:d6:25:65:74:96:aa:36:de:ae:31:a8:11:f2:a4:2c:5a:e1:
+         4f:73:f8:4a:c3:35:b0:76:96:71:f2:b5:7d:4b:75:ee:5d:bf:
+         86:a5:ba:0b:a9:52:cb:ec:ab:e5:23:4b:f2:74:55:28:17:1e:
+         b3:ac:27:ad:45:13:6e:69:b3:5a:be:42:36:29:48:db:e7:5c:
+         22:58:a0:90:82:2c:2a:21:2b:db:f4:64:b7:91:5d:1f:2c:48:
+         a4:1a:85:e3:86:a5:aa:19:cd:19:e8:a5:fb:a3:7b:94:77:48:
+         25:a4:cf:a0:cf:71:82:5c:6f:71:22:7c:d6:97:a0:53:bb:ec:
+         30:f6:cb:16:fb:7b:fd:16:94:7a:53:6e:bd:04:64:a2:01:10:
+         9f:f0:5b:b5:a6:73:41:9d:5f:6f:45:73:0d:05:f7:30:6d:39:
+         90:b6:7d:55:7d:4c:2f:ae:5f:38:56:2f:8b:df:f4:bf:12:06:
+         93:6e:0d:02:23:bf:71:91:57:88:e8:bd:62:72:99:00:40:29:
+         1e:c9:13:11:da:7e:8e:e1:d2:a5:0d:bf:f7:d6:ec:01:0d:89:
+         41:cd:d5:dc:d2:f7:5f:33:0d:4c:2f:85:b7:85:b7:81:e4:17:
+         29:f0:74:cf:0e:15:8c:1a:50:0b:08:63:1a:91:4f:e7:76:97:
+         f1:d4:3b:7e:72:d4:c5:45:58:0c:6a:e9:0d:f2:85:d8:91:1e:
+         37:bd:78:e3:39:4d:2e:fd:85:31:c1:a6:3b:6a:cc:2c:53:72:
+         1d:8e:7b:f0:e6:76:86:09:6f:1a:f3:e4:a1:e2:dd:76:5f:b0:
+         8c:e2:2a:54:5d:c1:88:49:90:10:15:42:7d:05:24:53:8c:54:
+         ff:48:18:1a:36:e3:31:d3:54:32:78:0d:fe:f2:3d:aa:0d:37:
+         15:84:b4:36:47:31:e8:85:6e:0b:58:38:ff:21:91:09:c9:a8:
+         43:a3:ea:60:cb:7e:ed:f7:41:6f:4e:91:c1:fd:77:46:e7:d4:
+         e7:86:c0:1b:fd:50:6c:aa:be:00:b3:63:02:ff:4e:c7:a5:57:
+         6e:29:64:e9:54:d5:30:63:38:5f:2d:5a:db:49:5f:14:14:22:
+         d2:81:1f:61:9e:ee:ee:16:66:d6:bc:bd:ac:1b:5c:fb:38:31:
+         95:33:2e:84:6e:7a:de:ee:b9:fc:97:17:06:13:bf:70:1c:6e:
+         76:ed:66:38:e2:70:08:00
+-----BEGIN CERTIFICATE-----
+MIIFODCCAyCgAwIBAgIJAMd+UWocJc1AMA0GCSqGSIb3DQEBDQUAMCwxKjAoBgNV
+BAMMIUNhbm9uaWNhbCBMdGQuIExpdmUgUGF0Y2ggU2lnbmluZzAeFw0xNjA3MTgy
+MzQxMjdaFw0yNjA3MTYyMzQxMjdaMCwxKjAoBgNVBAMMIUNhbm9uaWNhbCBMdGQu
+IExpdmUgUGF0Y2ggU2lnbmluZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
+ggIBAL107nKzSqvmMegpJMK9RpgywDnuo/uKrf6rGlujLqGA23lhnkd5LHVXoiHw
+k/aH8ptLnS+zWGEoPEFwExahcpDJ1RZxfOAw+SheSCA2AGm3WZ+j7KjrVUGfOB4i
+Slcg9INZScUAk9MzApLR/PCEO0pbj7Zzmon6MB7mKmjyke9ZVz3cHFJvXuabtbh8
+mMkT0TloAWeR4NNnchYKXhaDRTFPtSuz9kCGiTqEbm8WYbxwhL5aEzZ7guoHGfwY
+wRbGMgt9LGvEIbk4azHc2QytVkBofOPGZI6/HOByPmzb0nN52tfFL10EfbAHHpXd
+Kkdevz46yGb2Zw/UKvHicVnSbHugN6zml4AwE5dI1XT8OGjkV8uZaVqEJ6yYUeRk
+vZFi6FgnBiq5C7gI5eW0UaeiEN9OB2ygO5bybt91jJceZKCahpuYJvnYt95bIbev
+iQGj95hr2hm6hu/v8c67L4ntwLYb5Vv4kBGaUpPpvvc1uQjLusPtL3OvzJYHVbXe
+9gP28Yn5IUB2wWnyYcyalN+c7GplOL7RTiqHxy8+U66Ln1ShCVlkJaqp2ESpqKBx
+4TKqTDL9RCjMnG+O24F+b/oAVsXlA0Zj+45xjeMTkZ+sYD5k898lNAn6LZafFgXq
+k/XmAAgnMns8ve5wJGw7Venb9BAtIAa0yukpZVWt9lJUX+WjAgMBAAGjXTBbMAwG
+A1UdEwEB/wQCMAAwCwYDVR0PBAQDAgeAMB0GA1UdDgQWBBQU3zTRqHzzdiWr7AOe
+8r9SEkm5aTAfBgNVHSMEGDAWgBQU3zTRqHzzdiWr7AOe8r9SEkm5aTANBgkqhkiG
+9w0BAQ0FAAOCAgEAMOdIAjfpKM8Eok1c+thOyXbHFD+9LFE9M/AavEnxR5WPadip
+VBREbE2fVYIIHsZb1ZHZvC6wr9YlZXSWqjberjGoEfKkLFrhT3P4SsM1sHaWcfK1
+fUt17l2/hqW6C6lSy+yr5SNL8nRVKBces6wnrUUTbmmzWr5CNilI2+dcIligkIIs
+KiEr2/Rkt5FdHyxIpBqF44alqhnNGeil+6N7lHdIJaTPoM9xglxvcSJ81pegU7vs
+MPbLFvt7/RaUelNuvQRkogEQn/BbtaZzQZ1fb0VzDQX3MG05kLZ9VX1ML65fOFYv
+i9/0vxIGk24NAiO/cZFXiOi9YnKZAEApHskTEdp+juHSpQ2/99bsAQ2JQc3V3NL3
+XzMNTC+Ft4W3geQXKfB0zw4VjBpQCwhjGpFP53aX8dQ7fnLUxUVYDGrpDfKF2JEe
+N7144zlNLv2FMcGmO2rMLFNyHY578OZ2hglvGvPkoeLddl+wjOIqVF3BiEmQEBVC
+fQUkU4xU/0gYGjbjMdNUMngN/vI9qg03FYS0Nkcx6IVuC1g4/yGRCcmoQ6PqYMt+
+7fdBb06Rwf13RufU54bAG/1QbKq+ALNjAv9Ox6VXbilk6VTVMGM4Xy1a20lfFBQi
+0oEfYZ7u7hZm1ry9rBtc+zgxlTMuhG563u65/JcXBhO/cBxudu1mOOJwCAA=
+-----END CERTIFICATE-----
--- linux-qcom-6.8.0.orig/debian/certs/ubuntu-drivers-all.pem
+++ linux-qcom-6.8.0/debian/certs/ubuntu-drivers-all.pem
@@ -0,0 +1,125 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            e9:df:13:0f:92:92:a9:b7
+        Signature Algorithm: sha512WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Kernel Module Signing
+        Validity
+            Not Before: May 31 16:06:09 2016 GMT
+            Not After : May 29 16:06:09 2026 GMT
+        Subject: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Kernel Module Signing
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                RSA Public-Key: (4096 bit)
+                Modulus:
+                    00:b3:b0:4f:c6:0a:77:8b:f9:d1:53:33:34:d2:80:
+                    b5:63:6f:e1:f6:a2:83:99:d5:b6:b1:e4:99:91:fa:
+                    6c:19:c6:d0:91:2a:b9:7d:b5:98:a6:0d:28:01:b8:
+                    7c:8e:aa:38:ec:51:37:33:96:f0:b0:9b:8d:86:5f:
+                    67:23:69:2f:d7:c2:f3:fb:c5:d7:f9:04:ff:f2:e5:
+                    61:68:b7:29:b9:c6:8e:4b:4d:2d:8f:92:0c:00:b3:
+                    a3:d2:5a:08:64:cd:f2:09:0b:a5:0e:e6:64:75:d5:
+                    41:f4:4d:49:3a:0d:dc:b9:27:8e:c4:d6:b1:df:8f:
+                    6c:f0:e4:f7:31:cb:a9:04:a1:f9:a7:aa:15:da:59:
+                    03:4d:46:14:d0:dd:bf:e0:f5:9e:f0:71:0c:70:78:
+                    2b:08:fb:e0:b6:68:a4:74:12:9d:f7:f2:64:88:17:
+                    2a:8a:ed:1a:91:b5:6c:13:bd:4c:10:0a:0b:72:0b:
+                    90:db:7d:f3:78:44:4c:d2:a5:41:f7:1c:77:7d:5a:
+                    8a:54:bc:8f:fe:b7:ee:e1:bc:59:37:c4:d4:e8:14:
+                    d0:5b:42:9b:04:00:8e:6d:83:8a:25:21:5b:08:c4:
+                    7b:b2:d9:99:52:c9:5e:59:6d:c4:aa:52:59:e2:e4:
+                    2f:7e:7e:ac:05:01:99:bf:13:72:b7:45:c5:17:da:
+                    8a:d5:3e:71:73:2e:d8:aa:e6:eb:5a:d0:9a:c4:93:
+                    f3:be:eb:d2:47:25:34:16:29:fa:dd:9a:2f:b1:20:
+                    e5:41:4e:ed:ea:51:7c:23:80:ba:3d:b5:3a:0b:8c:
+                    9c:85:48:6c:3c:8b:29:2f:2f:12:c7:52:34:02:ea:
+                    0f:ac:53:23:3c:f8:3e:40:1b:30:63:e9:2d:e6:f6:
+                    58:cc:51:f9:eb:08:4a:b4:c7:16:80:d1:8b:c2:64:
+                    6a:71:a9:70:31:a4:a7:3a:c0:93:99:1b:0e:42:c1:
+                    00:6d:43:27:99:6c:e5:fd:23:16:c1:8e:b5:66:17:
+                    2b:4c:53:5a:6d:1e:96:16:13:6a:c6:d4:85:5b:74:
+                    2e:ce:7c:45:2f:ad:cb:75:9e:5e:91:bd:9a:6a:86:
+                    1a:06:bd:39:be:a3:50:56:ea:e1:f6:e3:95:69:d7:
+                    31:e4:66:f7:36:b5:51:c2:22:b4:9c:74:9c:44:0b:
+                    0e:16:5f:53:f0:23:c6:b9:40:bd:d6:b8:7d:1b:f6:
+                    73:f6:27:e7:c0:e3:65:a0:58:ab:5c:59:b7:80:8c:
+                    8c:04:b4:a9:ae:a0:51:40:10:3b:63:59:49:87:d1:
+                    9b:df:a3:8c:c4:2e:eb:70:c1:0a:18:1f:cb:22:c2:
+                    f2:4a:65:0d:e5:81:74:d8:ce:72:c6:35:be:ba:63:
+                    72:c4:f9
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Key Usage: 
+                Digital Signature
+            X509v3 Subject Key Identifier: 
+                88:F7:52:E5:60:A1:E0:73:7E:31:16:3A:46:6A:D7:B7:0A:85:0C:19
+            X509v3 Authority Key Identifier: 
+                keyid:88:F7:52:E5:60:A1:E0:73:7E:31:16:3A:46:6A:D7:B7:0A:85:0C:19
+
+    Signature Algorithm: sha512WithRSAEncryption
+         04:85:16:27:58:ba:71:28:57:86:7b:c2:83:db:e5:72:6f:1e:
+         b2:1c:63:b0:db:ad:c0:42:96:c0:4f:65:f6:35:4d:c0:07:0d:
+         46:be:d3:1e:ec:f1:22:18:2a:18:5d:bb:69:a6:a6:d4:0d:c3:
+         57:03:b9:e7:45:49:28:ca:6d:98:17:68:97:cb:7b:36:81:0a:
+         37:9e:34:79:f3:e1:0e:5b:77:43:bb:5a:a5:45:b7:16:50:86:
+         fd:12:a4:96:0f:15:19:09:1c:e1:fa:80:a5:80:09:be:bb:c8:
+         26:0b:3e:de:03:d2:c2:18:a4:8d:0d:de:c5:32:82:0b:fb:75:
+         55:66:1a:2a:bb:e4:bd:25:91:20:15:d4:be:b8:3f:53:e3:fb:
+         a8:c3:55:e3:d5:e7:82:18:95:df:39:09:a7:fc:89:6e:b4:1c:
+         aa:2d:e8:67:c2:0d:34:34:3e:f9:fa:0b:ce:81:92:11:ae:12:
+         0a:fe:35:63:ce:46:29:c4:2b:4f:cb:4e:05:0a:a1:11:e2:35:
+         f6:5a:5d:b5:e8:d2:6f:4c:fc:3d:24:a6:03:4b:dd:98:6b:f2:
+         71:58:16:1d:a5:25:ef:d9:06:7c:e8:db:7b:88:6a:89:5c:59:
+         01:92:64:db:44:08:63:6c:7c:32:d6:55:98:63:09:26:61:67:
+         0a:fe:5d:ee:fd:23:59:b3:4d:91:c1:4d:41:8b:cd:20:58:fa:
+         2d:45:e5:bd:1d:69:5c:03:a0:49:a6:97:54:13:b6:c9:e0:f8:
+         56:83:a1:2a:c3:f4:6c:fd:ab:20:ca:3d:9c:95:c0:cf:04:bb:
+         46:39:cf:34:81:65:45:27:64:01:7d:62:b3:b8:72:ea:10:d5:
+         0f:53:7d:39:88:25:09:6f:8c:bc:e0:49:bb:39:e2:0e:8d:cf:
+         56:4d:c1:82:6d:87:d2:e7:fc:c0:9f:a7:65:60:d2:6c:65:18:
+         59:38:6e:d0:9c:d7:c3:81:9a:9a:29:8f:83:84:c3:b5:44:ff:
+         28:ac:13:17:64:f2:26:13:d9:55:06:b7:69:68:7c:bf:ec:d1:
+         8c:ef:b7:da:76:e1:07:73:c6:31:62:31:cb:b6:e1:e7:7f:0c:
+         c3:f7:4c:52:be:25:36:8e:a1:bb:60:02:c3:cb:3e:6f:29:fc:
+         7f:6a:fa:f8:ec:0a:df:49:e2:57:0e:bc:bd:93:c3:1b:d5:36:
+         8a:ff:d8:1b:17:c7:1f:cb:69:00:d2:54:9e:ad:61:89:92:95:
+         11:f8:ea:17:83:9f:9b:09:7d:b8:94:a4:ea:f5:ae:ea:dc:dd:
+         62:b9:9e:68:9c:18:ec:19:c4:13:08:c8:b1:62:ab:8e:84:69:
+         11:3c:da:ea:0d:b7:22:bd
+-----BEGIN CERTIFICATE-----
+MIIF2jCCA8KgAwIBAgIJAOnfEw+Skqm3MA0GCSqGSIb3DQEBDQUAMH0xCzAJBgNV
+BAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEQMA4GA1UEBwwHRG91Z2xhczEX
+MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xLTArBgNVBAMMJENhbm9uaWNhbCBMdGQu
+IEtlcm5lbCBNb2R1bGUgU2lnbmluZzAeFw0xNjA1MzExNjA2MDlaFw0yNjA1Mjkx
+NjA2MDlaMH0xCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEQMA4G
+A1UEBwwHRG91Z2xhczEXMBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xLTArBgNVBAMM
+JENhbm9uaWNhbCBMdGQuIEtlcm5lbCBNb2R1bGUgU2lnbmluZzCCAiIwDQYJKoZI
+hvcNAQEBBQADggIPADCCAgoCggIBALOwT8YKd4v50VMzNNKAtWNv4faig5nVtrHk
+mZH6bBnG0JEquX21mKYNKAG4fI6qOOxRNzOW8LCbjYZfZyNpL9fC8/vF1/kE//Ll
+YWi3KbnGjktNLY+SDACzo9JaCGTN8gkLpQ7mZHXVQfRNSToN3LknjsTWsd+PbPDk
+9zHLqQSh+aeqFdpZA01GFNDdv+D1nvBxDHB4Kwj74LZopHQSnffyZIgXKortGpG1
+bBO9TBAKC3ILkNt983hETNKlQfccd31ailS8j/637uG8WTfE1OgU0FtCmwQAjm2D
+iiUhWwjEe7LZmVLJXlltxKpSWeLkL35+rAUBmb8TcrdFxRfaitU+cXMu2Krm61rQ
+msST877r0kclNBYp+t2aL7Eg5UFO7epRfCOAuj21OguMnIVIbDyLKS8vEsdSNALq
+D6xTIzz4PkAbMGPpLeb2WMxR+esISrTHFoDRi8JkanGpcDGkpzrAk5kbDkLBAG1D
+J5ls5f0jFsGOtWYXK0xTWm0elhYTasbUhVt0Ls58RS+ty3WeXpG9mmqGGga9Ob6j
+UFbq4fbjlWnXMeRm9za1UcIitJx0nEQLDhZfU/AjxrlAvda4fRv2c/Yn58DjZaBY
+q1xZt4CMjAS0qa6gUUAQO2NZSYfRm9+jjMQu63DBChgfyyLC8kplDeWBdNjOcsY1
+vrpjcsT5AgMBAAGjXTBbMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgeAMB0GA1Ud
+DgQWBBSI91LlYKHgc34xFjpGate3CoUMGTAfBgNVHSMEGDAWgBSI91LlYKHgc34x
+FjpGate3CoUMGTANBgkqhkiG9w0BAQ0FAAOCAgEABIUWJ1i6cShXhnvCg9vlcm8e
+shxjsNutwEKWwE9l9jVNwAcNRr7THuzxIhgqGF27aaam1A3DVwO550VJKMptmBdo
+l8t7NoEKN540efPhDlt3Q7tapUW3FlCG/RKklg8VGQkc4fqApYAJvrvIJgs+3gPS
+whikjQ3exTKCC/t1VWYaKrvkvSWRIBXUvrg/U+P7qMNV49XnghiV3zkJp/yJbrQc
+qi3oZ8INNDQ++foLzoGSEa4SCv41Y85GKcQrT8tOBQqhEeI19lpdtejSb0z8PSSm
+A0vdmGvycVgWHaUl79kGfOjbe4hqiVxZAZJk20QIY2x8MtZVmGMJJmFnCv5d7v0j
+WbNNkcFNQYvNIFj6LUXlvR1pXAOgSaaXVBO2yeD4VoOhKsP0bP2rIMo9nJXAzwS7
+RjnPNIFlRSdkAX1is7hy6hDVD1N9OYglCW+MvOBJuzniDo3PVk3Bgm2H0uf8wJ+n
+ZWDSbGUYWThu0JzXw4GamimPg4TDtUT/KKwTF2TyJhPZVQa3aWh8v+zRjO+32nbh
+B3PGMWIxy7bh538Mw/dMUr4lNo6hu2ACw8s+byn8f2r6+OwK30niVw68vZPDG9U2
+iv/YGxfHH8tpANJUnq1hiZKVEfjqF4Ofmwl9uJSk6vWu6tzdYrmeaJwY7BnEEwjI
+sWKrjoRpETza6g23Ir0=
+-----END CERTIFICATE-----
--- linux-qcom-6.8.0.orig/debian/changelog
+++ linux-qcom-6.8.0/debian/changelog
@@ -0,0 +1,38887 @@
+linux-qcom (6.8.0-1054.54oem2) noble; urgency=medium
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] remove reconstruct"
+
+ -- Hui Wang <hui.wang@canonical.com>  Mon, 08 Sep 2025 19:05:04 +0800
+
+linux-qcom (6.8.0-1054.54oem1) noble; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+
+ -- Hui Wang <hui.wang@canonical.com>  Mon, 08 Sep 2025 17:07:45 +0800
+
+linux-qcom (6.8.0-1051.51oem3) noble; urgency=medium
+
+  * Unable to hear the audio playback clip from the RB8 hardware speakers with
+    Server & Desktop images
+    - ASoC: qcs9075-iq-evk: Enable audio on qcs9075-iq-evk
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update to Yocto GA 1.5
+    - SAUCE: firmware: qcom: si-core:  include <workqueue_types.h>
+    - SAUCE: sound/soc/qcom/qcm6490: suppress invalid dai id error
+    - SAUCE: partially revert "enable platform sound-dai"
+    - [Packaging] remove reconstruct
+
+  * Miscellaneous upstream changes
+    - PENDING: arm64: dts: qcom: Update the thermal sensor names
+    - PENDING: drivers: pinctrl: Add support for context save/restore
+    - PENDING: pinctrl: qcom: sa8775p: Add PM suspend callbacks
+    - PENDING: arm64: dts: qcom: qcs8300: Update carveouts
+    - QCLINUX: arm64: defconfigs: Enable SA8797P Pinctrl
+    - PENDING: pinctrl: qcom: Add TLMM Driver for SA8797p platform
+    - QCLINUX: iommu: Remove atomic allocation check to fix smmu mapping
+      failure
+    - QCLINUX: arm64: defconfig: Align Gen5auto configs with Gen4auto
+    - PENDING: arm64: dts: qcom: qcs9075-rb8: Set the BT bootstrap bin when
+      init Uart
+    - PENDING: arm64: dts: qcom: sa8775p: add GPDSP fastrpc-compute-cb nodes
+    - PENDING: misc: fastrpc: Add support for gpdsp remoteproc
+    - QCLINUX: arm64: defconfig: Enable Tracer Configs
+    - FROMLIST: soc: qcom: Add qcom_rproc_minidump module
+    - FROMLIST: remoteproc: qcom_q6v5_pas: Use qcom_rproc_minidump()
+    - FROMLIST: remoteproc: qcom: Remove minidump related data from
+      qcom_common.c
+    - FROMLIST: pstore/ram: Add ramoops information notifier support
+    - FROMLIST: soc: qcom: Add Qualcomm APSS minidump kernel driver
+    - QCLINUX: defconfig: Enable ebtables and netfilter configuration
+    - PENDING: drm/msm/dp: correct the configuration ctrl reg for streams
+    - UPSTREAM: arm64: dts: qcom: Fix max speed for usb_1 on qcs8300
+    - QCLINUX: arm64: configs: qcom_debug: Fix up order of CONFIGs
+    - PENDING: net: stmmac: Enable MMC counters for 25gmac
+    - PENDING: ASoC: qcom: q6prm: Add lpass mclk id support
+    - QCLINUX: firmware: qcom_scm_addon: Enable SCM for Memory Dump
+    - FROMLIST: wifi: ath11k: add function to get next srng desc
+    - PENDING: arm64: dts: qcom: sa8255p: Enable USB role switch
+    - QCLINUX: arm64: configs: qcom_debug: Enable PSTORE
+    - QCLINUX: arm64: configs: qcom_debug: Enable QCOM_MINIDUMP
+    - FROMLIST: wifi: ath11k: fix HTC rx insufficient length
+    - UPSTREAM: BACKPORT: arm64: dts: qcom: qcs6490-rb3gen2: Enable USB Type-C
+      display
+    - FROMLIST: wifi: ath11k: fix node corruption in ar->arvifs list
+    - PENDING: arm64: dts: qcom: Enable tsens and thermal for QCS615 SoC
+    - Revert "PENDING: net: stmmac: Create new mdio for every emac instance"
+    - QCLINUX: firmware: qcom_scm_addon: Update SCM call for Memory Dump
+    - PENDING: net: stmmac: Fix USXGMII link up sequence
+    - QCLINUX: arm64: configs: qcom_debug: Enable QCOM_MINIDUMP
+    - QCLINUX: ASoC: qcs9075: Add Stub AIF0 & AIF1
+    - QCLINUX: arm64: dts: qcom: Add mem-object node for si_core
+    - PENDING: firmware: qcom: Add si_core and si_core_xts
+    - QCLINUX: Disable QCOM_SMCINVOKE
+    - QCLINUX: Enable QCOM_SI_CORE and QCOM_SI_CORE_XTS
+    - PENDING: drivers: mailbox: ipcc: Add Deep Sleep support for qcom-ipcc
+      driver
+    - QCLINUX: arm64: dts: qcom: Fix issue of USB hub & DP not working
+      properly
+    - PENDING: net: PCS: Rework and expose qcom_xpcs_destroy function
+    - PENDING: net: stmmac: Use pcs_init and pcs_exit functions
+    - PENDING: iommu/arm-smmu: add ACTLR data and support for sa8797p
+    - PENDING: drm/msm/dpu: Correct the index of intf_6 vsync irq
+    - FROMLIST: PCI: Add support for PCIe wake interrupt
+    - PENDING: arm64: dts: qcom: sa8255p: Disable USB U1/U2 entry
+    - PENDING: net: phy: aquantia: Add polling for global status register
+      before checking for provision and firmware ID's
+    - PENDING: drm/msm/dp: Add the stream 2 and stream 3 clk for 4 MST
+    - PENDING: drm/msm/dp: add support for programming p2/p3 register block
+    - QCLINUX: arm64: dts: qcom: Add PCIe wake for HSP
+    - PENDING: drm/msm/dp: add support for programming mst2/mst3 register
+      block
+    - PENDING: drm/msm/dp: add catalog support for 4 streams MST
+    - PENDING: drm/msm/dp: add interface map needed to enable 4 streams
+    - PENDING: arm64/dts/qcom: add mst support for MST2/MST3 clk and registers
+    - PENDING: net: stmmac: Reset few of the IO macro registers to POR values
+      before programming
+    - PENDING: net: stmmac: Enable L2 split header support on XGMAC
+    - PENDING: net: pcs: Enable PCS Fusa Shared interrupt
+    - PENDING: net: stmmac: Enable safety interrupt only after PCS link up
+    - QCLINUX: ASoC: qcs8275: Add support for QCS8275 RB4
+    - QCLINUX: iommu/arm-smmu: Invoke pm runtime for context fault
+    - FROMGIT: serial: qcom-geni: Remove alias dependency from qcom serial
+      driver
+    - QCLINUX: Revert "serial: qcom-geni: fix receiver enable"
+    - QCLINUX: Revert "Revert "FROMLIST: arm64: dts: qcom: sa8775p: Add CPUs
+      to psci power domain""
+    - QCLINUX: arm64: qcom_defconfig: Enable EXT4_FS_SECURITY
+    - PENDING: scsi: ufs-qcom: Fix MCQ version handling to update CFG register
+    - PENDING: soc: qcom: qcom_stats: Add SMEM items for multiple subsystems
+    - PENDING: arm64: dts: qcom: sa7255p: Add PCIe EP nodes
+    - PENDING: arm64: dts: qcom: Revert uart0 support for qcs9075-iq-9075-evk
+    - PENDING: arm64: dts: qcom: qcs8300: Add gpu_speed_bin to qfprom node
+    - QCLINUX: tz_log: Revert "QCLINUX: qcom: tz_log: differentiate hlos and
+      hypversior of creating shmbridge"
+    - QCLINUX: tz_log: Revert "QCLINUX: qcom: tz_log: enable tz_log support
+      hypervisor"
+    - QCLINUX: smcinvoke: Revert "QCLINUX: smcinvoke: Add support hypervisor
+      of shmbridge"
+    - PENDING: coresight: fix NULL pointer issue when get CSR's name
+    - PENDING: arm64: dts: qcom: Add support for QCS8275 IQ8 EVK board
+    - QCLINUX:arm64: dts: qcom: Add eMMC support for qcs8300
+    - QCLINUX: dcc: Add Deep Sleep support for qcom-dcc driver
+    - QCLINUX: firmware: qcom_scm_addon: Add SCM call to init multi GPU
+      instance
+    - QCLINUX: firmware: qcom_scm_addon: Add interface to load CCU
+    - PENDING: Adapt to kennel v6.6.78, modify the corresponding driver
+      function interface
+    - FROMLIST: firmware: qcom_scm: Check for waitq state in
+      wait_for_completion
+    - PENDING: net: PCS: supply Tx to Rx loopback clock for HW configuration
+    - QCLINUX: arm64: dts: qcom: Add msm-id & board-id for qcs8275 IQ8
+    - PENDING: arm64: dts: qcom: Enable primary USB controller on QCS8275 RB4
+    - FROMLIST: arm64: dts: qcom: sa8775p: add support for video node
+    - FROMLIST: arm64: dts: qcom: sa8775p-ride: enable video
+    - FROMLIST: arm64: dts: qcom: qcs8300: add support for video node
+    - FROMLIST: arm64: dts: qcom: qcs8300-ride: enable video
+    - PENDING: drivers: pinctrl: Add suspend to RAM support
+    - Revert "QCLINUX: remoteproc: Panic on remoteproc crash"
+    - PENDING: drivers: char: add remote debugger driver support for GDSP
+    - PENDING: net: stmmac: Use generic PCS field and move pcs_pre_init before
+      Serdes powerup
+    - PENDING: arm64: dts: qcom: sa7255p: Enable uart12 in sa7255p
+    - PENDING: pinctrl: qcom: sa8797p: Add PM suspend callbacks
+    - QCLINUX: firmware: qcom: si-core: Switch to tzmem interfaces
+    - PENDING: arm64: dts: qcom: Add support for the IQ-9075-evk mezz
+    - PENDING: arm64: dts: qcom: tpm enablement for qcs9075-iq-9075-evk
+    - PENDING: i2c: qcom-geni: Defer i2c geni driver probe if firmware file
+      not found
+    - PENDING: arm64: dts: qcom: Enable USB2 controller on QCS8275 IQ8 EVK
+    - PENDING: arm64: dts: qcom: Add UFS support for QCS8275 IQ8 EVK
+    - PENDING: arm64: dts: qcom: Flatten USB DT node for USB2 on QCS9075 RB8
+      Platform
+    - QCLINUX: arm64: dts: qcom: Add audio mdf reserved memory for sa7255
+    - QCLINUX: firmware: Remove qtee_shmbridge driver
+    - QCLINUX: arm64: defconfig: qcom: Enable AMC6821 Sensor driver
+    - PENDING: arm64: qcs9075-evk: remove uart bt en and bootstrap pin in DTS
+    - PENDING: arm64: dts: qcom: Enable PCIe0 & PCIe1 for QCS8275 IQ8 EVK
+    - PENDING: arm64: dts: qcom: add gpio expander support for IQ8-8275-EVK
+    - PENDING: arm64: dts: qcom: Add support for remoteproc instances
+    - PENDING: arm64: dts: qcom: sa8775p: add rdbg nodes
+    - QCLINUX: arm64: dts: qcom: qcs8275: addons dt support for IQ8 QCS8275
+    - PENDING: arm64: dts: qcom: Flatten USB DT node
+    - PENDING: arm64: dts: qcom: qcs8300: Define interconnect bandwidth value
+    - PENDING: dt-bindings: arm: qcom: add the SoC ID for SA8650P
+    - PENDING: arm64: dts: qcom: add support for IQ8-8275-evk mezz board
+    - PENDING: arm64: dts: qcom: Enable BT on QCS8275 IQ8 EVK
+    - PENDING: arm64: dts: qcom: Enable ethernet on QCS8275 IQ8 EVK
+    - PENDING: arm64: dts: qcom: qcs8275: Enable gpi-dma node
+    - FROMGIT: arm64: dts: qcom: sa8775p: Add default pin configurations for
+      QUP SEs
+    - PENDING: arm64: dts: qcom: Add fan controller support for
+      qcs9075-iq-9075-evk
+    - QCLINUX: dcc: Add suspend to RAM support for qcom-dcc driver
+    - PENDING: drivers: mailbox: ipcc: Add suspend to RAM  support for qcom-
+      ipcc driver
+    - PENDING: net: stmmac: disable PCS interrupt if PCS
+    - PENDING: arm64: dts: qcom: Add DRD mode support
+    - QCLINUX: soc: qcom: Adapt smci header with latest copyright guidelines
+    - PENDING: arm64: dts: qcom: Flatten USB DT node
+    - QCLINUX: arm64: dts: qcom: Enable the second ethernet on QCS9075-IQ9
+      Mezz
+    - QCLINUX:arm64: dts: qcom: Add sdcard support for qcs9075 rb8
+    - PENDING: drm/bridge: lt9611uxc: extend mode valid checks
+    - PENDING: arm64: dts: qcom: Enable QPS615 on IQ8 EVK Mezz
+    - PENDING: driver: bluetooth: hci_qca: Disable hci_auto_off when BT_EN is
+      consistently pulled up by hardware
+    - PENDING: driver: bluetooth: hci_qca: fix ssr fail when BT_EN is
+      consistently pulled up by hardware
+    - PENDING: arm64: dts: qcom: Enable QPS615 on IQ-9075-evk mezz
+    - QCLINUX: arm64: dts: qcom: Add support for Eth0 and Eth1 on QPS615 for
+    - BACKPORT: PCI: of: Add of_pci_get_equalization_presets() API
+    - BACKPORT: PCI: dwc: Update pci->num_lanes to maximum supported link
+      width
+    - BACKPORT: PCI: Add lane equalization register offsets
+    - BACKPORT: PCI: dwc: Add support for configuring lane equalization
+      presets
+    - PENDING: PCI: qcom: Add equalization settings for 8.0 GT/s
+    - PENDING: arm64: dts: qcom: sa8775p: Add PCIe lane equalization preset
+      properties
+    - PENDING: arm64: dts: qcom: Make status disabled for remote endpoints on
+      mezz
+    - FROMLIST: PCI: dwc: Set PORT_LOGIC_LINK_WIDTH to one lane
+    - FROMLIST: phy: qcom: qmp-pcie: Update PHY settings for SA8775P
+    - PENDING: arm64: dts: qcom: Add support for QCS8275 IQ8 Pro SKU EVK board
+    - QCLINUX: arm64: dts: qcom: Add msm-id & board-id for QCS8275 IQ8 Pro SKU
+    - QCLINUX: arm64: dts: qcom: addons dt support for IQ8 QCS8275 Pro SKU
+    - PENDING: arm64: dts: qcom: add io expander support for IQ8-8275 Pro SKU
+    - PENDING: arm64: dts: qcom: Enable primary USB
+    - PENDING: arm64: dts: qcom: Add DRD mode support
+    - PENDING: arm64: dts: qcom: Enable USB2 controller
+    - QCLINUX: usb: dwc3: qcom: Fix calling of regulator get
+    - PENDING: arm64: dts: msm: Add UFS support for QCS8275 IQ8 Pro SKU EVK
+    - PENDING: arm64: dts: qcom: Update phy reset GPIO for Eth0 and Eth1 on
+    - PENDING: arm64: dts: qcom: Add wakeup source
+    - PENDING: arm64: dts: qcom: Add wakeup source
+    - PENDING: arm64: dts: qcom: Add usb conn gpio
+    - PENDING: arm64: dts: qcom: Add SD card support for QCS8275 IQ EVK
+    - PENDING: arm64: dts: qcom: Add SD card support for QCS8275 IQ8 Pro SKU
+    - PENDING: arm64: dts: qcom: Enable PCIe for QCS8275 IQ8 Pro SKU EVK
+    - PENDING: arm64: dts: qcom: Add wakeup source
+    - PENDING: arm64: dts: qcom: Enable vqmmc voltage switching for qcs9075
+      rb8
+    - PENDING: usb: typec: Add wakeup support from
+    - QCLINUX: arm64: dts: qcom: Fix eud ep in sa8775p-ride
+    - PENDING: misc: eud: Add High-Speed Phy control for EUD operations
+    - PENDING: misc: eud: Handle usb role switch notifications
+    - PENDING: misc: eud: Add an API to identify the role switch context
+    - PENDING: usb: dwc3: qcom: Handle Vbus OFF notification from EUD
+    - PENDING: arm64: dts: qcom: Add HS Phy node to EUD for SC7280
+    - PENDING: arm64: dts: qcom: Rearrange the role switch eps for QCM6490
+    - PENDING: arm64: dts: qcom: Rearrange the role switch for QCS6490 RB3Gen2
+    - PENDING: arm64: dts: qcom: Add status prop for ICE nodes
+    - PENDING: arm64: dts: qcom: Enable ICE node for eMMC
+    - PENDING: arm64: dts: qcom: tpm enablement for qcs8275-iq-8275-evk
+    - QCLINUX: arm64: dts: qcom: Disable eMMC ICE
+    - PENDING: arm64: dts: qcom: Add EEPROM support for IQ-9075-evk
+    - QCLINUX: net: stmmac: Add EEPROM support to driver
+    - kernel: arm64: dts: qcom: enable EEPROM Client Driver
+    - kernel: config: qcom: enable AT24 EEPROM driver
+    - arm64: dts: rubikpi: add RUBIK Pi related basic device tree
+    - arm64: dts: rubikpi: compatible with USB-A 2.0 port
+    - arm64: dts: rubikpi: enable USB3.0 HUB
+    - arm64: dts: rubikpi: enable M.2 port
+    - net: ax88179b: add driver
+    - arm64: dts: rubikpi: enable fan
+    - arm64: defconfig: enable ax88179b config
+    - wifi: ap6256: add driver
+    - arm64: dts: rubikpi: enable Wi-Fi
+    - arm64: dts: rubikpi3: enable bluetooth
+    - serial: qcom-geni: increase uart ports to 13
+    - arm64: dts: rubikpi: enable rtc to support time writing
+    - arm64: dts: rubikpi: camera: bringup imx219 and imx477
+    - drm/bridge: lt9611: rubikpi: enable hdmi out
+    - arm64: dts: rubikpi3: enable hdmi out interface
+    - ASoC: es8316: rubikpi: enable 3.5mm headphone jack
+    - arm64: dts: rubikpi3: enable 3.5mm headphone jack
+    - spi: spidev: add an entry for thundercomm,rubikpi
+    - arm64: dts: rubikpi: enable bus interface on 40 pin
+    - ASoC: qcom: qcm6490: rubikpi: enable HDMI OUT audio
+    - arm64: dts: rubikpi3: enable HDMI OUT audio
+    - arm64: dts: rubikpi3: Enable Bluetooth kernel driver
+    - drm/bridge: lt9611: rubikpi: fix the problem of hot plug failure
+    - arm64: dts: rubikpi3: modify the interrupt trigger mode of HDMI out
+    - arm64: dts: rubikpi: camera: Remove unnecessary gpio controls
+    - Ubuntu: [Config] update CONFIG options for Rubik Pi 3
+
+  [ Ubuntu: 6.8.0-64.67 ]
+
+  * noble/linux: 6.8.0-64.67 -proposed tracker (LP: #2114668)
+  * Unexpected system reboot at loading GUI session on some AMD platforms
+    (LP: #2112462)
+    - drm/amdgpu/hdp4: use memcfg register to post the write for HDP flush
+    - drm/amdgpu/hdp5: use memcfg register to post the write for HDP flush
+    - drm/amdgpu/hdp5.2: use memcfg register to post the write for HDP flush
+    - drm/amdgpu/hdp6: use memcfg register to post the write for HDP flush
+  * [UBUNTU 24.04] s390/pci: Fix immediate re-add of PCI function after remove
+    (LP: #2114174)
+    - s390/pci: rename lock member in struct zpci_dev
+    - s390/pci: introduce lock to synchronize state of zpci_dev's
+    - s390/pci: remove hotplug slot when releasing the device
+    - s390/pci: Remove redundant bus removal and disable from
+      zpci_release_device()
+    - s390/pci: Prevent self deletion in disable_slot()
+    - s390/pci: Allow re-add of a reserved but not yet removed device
+    - s390/pci: Serialize device addition and removal
+  * [UBUNTU 24.04] s390/pci: Fix immediate re-add of PCI function after remove
+    (LP: #2114174) // CVE-2025-37946
+    - s390/pci: Fix duplicate pci_dev_put() in disable_slot() when PF has
+      child VFs
+  * [UBUNTU 24.04] s390/pci: Fix immediate re-add of PCI function after remove
+    (LP: #2114174) // CVE-2025-37974
+    - s390/pci: Fix missing check for zpci_create_device() error return
+  * [UBUNTU 24.04] s390/pci: Fix immediate re-add of PCI function after remove
+    (LP: #2114174) // CVE-2024-56699
+    - s390/pci: Fix potential double remove of hotplug slot
+  * System will restart while resuming with SATA HDD or nvme installed with
+    password set (LP: #2110090)
+    - PCI: Explicitly put devices into D0 when initializing
+  * Noble update: upstream stable patchset 2025-06-12 (LP: #2114239)
+    - btrfs: fix assertion failure when splitting ordered extent after
+      transaction abort
+    - btrfs: fix use-after-free when attempting to join an aborted transaction
+    - arm64/mm: Ensure adequate HUGE_MAX_HSTATE
+    - exec: fix up /proc/pid/comm in the execveat(AT_EMPTY_PATH) case
+    - s390/stackleak: Use exrl instead of ex in __stackleak_poison()
+    - btrfs: fix data race when accessing the inode's disk_i_size at
+      btrfs_drop_extents()
+    - btrfs: convert BUG_ON in btrfs_reloc_cow_block() to proper error
+      handling
+    - sched: Don't try to catch up excess steal time.
+    - locking/ww_mutex/test: Use swap() macro
+    - lockdep: Fix upper limit for LOCKDEP_*_BITS configs
+    - x86/amd_nb: Restrict init function to AMD-based systems
+    - drm/virtio: New fence for every plane update
+    - drm: Add panel backlight quirks
+    - drm: panel-backlight-quirks: Add Framework 13 matte panel
+    - drm: panel-backlight-quirks: Add Framework 13 glossy and 2.8k panels
+    - nvkm/gsp: correctly advance the read pointer of GSP message queue
+    - nvkm: correctly calculate the available space of the GSP cmdq buffer
+    - drm/amd/display: Populate chroma prefetch parameters, DET buffer fix
+    - drm/amd/display: Overwriting dualDPP UBF values before usage
+    - printk: Fix signed integer overflow when defining LOG_BUF_LEN_MAX
+    - drm/connector: add mutex to protect ELD from concurrent access
+    - drm/bridge: anx7625: use eld_mutex to protect access to connector->eld
+    - drm/bridge: ite-it66121: use eld_mutex to protect access to
+      connector->eld
+    - drm/amd/display: use eld_mutex to protect access to connector->eld
+    - drm/exynos: hdmi: use eld_mutex to protect access to connector->eld
+    - drm/radeon: use eld_mutex to protect access to connector->eld
+    - drm/sti: hdmi: use eld_mutex to protect access to connector->eld
+    - drm/vc4: hdmi: use eld_mutex to protect access to connector->eld
+    - drm/amd/display: Fix Mode Cutoff in DSC Passthrough to DP2.1 Monitor
+    - drm/amdgpu: Don't enable sdma 4.4.5 CTXEMPTY interrupt
+    - drm/amdkfd: Queue interrupt work to different CPU
+    - drm/bridge: it6505: Change definition MAX_HDCP_DOWN_STREAM_COUNT
+    - drm/bridge: it6505: fix HDCP Bstatus check
+    - drm/bridge: it6505: fix HDCP encryption when R0 ready
+    - drm/bridge: it6505: fix HDCP CTS compare V matching
+    - drm/bridge: it6505: fix HDCP V match check is not performed correctly
+    - drm/bridge: it6505: fix HDCP CTS KSV list wait timer
+    - safesetid: check size of policy writes
+    - drm/amd/display: Increase sanitizer frame larger than limit when compile
+      testing with clang
+    - drm/amd/display: Limit Scaling Ratio on DCN3.01
+    - wifi: rtw89: add crystal_cap check to avoid setting as overflow value
+    - tun: fix group permission check
+    - mmc: core: Respect quirk_max_rate for non-UHS SDIO card
+    - mmc: sdhci-esdhc-imx: enable 'SDHCI_QUIRK_NO_LED' quirk for S32G
+    - wifi: brcmsmac: add gain range check to wlc_phy_iqcal_gainparams_nphy()
+    - tomoyo: don't emit warning in tomoyo_write_control()
+    - mfd: lpc_ich: Add another Gemini Lake ISA bridge PCI device-id
+    - wifi: rtw88: add __packed attribute to efuse layout struct
+    - clk: qcom: Make GCC_8150 depend on QCOM_GDSC
+    - HID: multitouch: Add quirk for Hantick 5288 touchpad
+    - HID: Wacom: Add PCI Wacom device support
+    - net/mlx5: use do_aux_work for PHC overflow checks
+    - wifi: brcmfmac: Check the return value of
+      of_property_read_string_index()
+    - wifi: iwlwifi: pcie: Add support for new device ids
+    - wifi: iwlwifi: avoid memory leak
+    - i2c: Force ELAN06FA touchpad I2C bus freq to 100KHz
+    - APEI: GHES: Have GHES honor the panic= setting
+    - Bluetooth: btusb: Add new VID/PID 13d3/3610 for MT7922
+    - Bluetooth: btusb: Add new VID/PID 13d3/3628 for MT7925
+    - Bluetooth: MGMT: Fix slab-use-after-free Read in
+      mgmt_remove_adv_monitor_sync
+    - net: wwan: iosm: Fix hibernation by re-binding the driver around it
+    - mmc: sdhci-msm: Correctly set the load for the regulator
+    - octeon_ep: update tx/rx stats locally for persistence
+    - tipc: re-order conditions in tipc_crypto_key_rcv()
+    - selftests/net/ipsec: Fix Null pointer dereference in rtattr_pack()
+    - x86/kexec: Allocate PGD for x86_64 transition page tables separately
+    - iommu/arm-smmu-qcom: add sdm670 adreno iommu compatible
+    - iommu/arm-smmu-v3: Clean up more on probe failure
+    - platform/x86: int3472: Check for adev == NULL
+    - platform/x86: acer-wmi: Add support for Acer PH14-51
+    - ASoC: soc-pcm: don't use soc_pcm_ret() on .prepare callback
+    - platform/x86: acer-wmi: Add support for Acer Predator PH16-72
+    - ASoC: amd: Add ACPI dependency to fix build error
+    - Input: allocate keycode for phone linking
+    - platform/x86: acer-wmi: add support for Acer Nitro AN515-58
+    - platform/x86: acer-wmi: Ignore AC events
+    - xfs: report realtime block quota limits on realtime directories
+    - xfs: don't over-report free space or inodes in statvfs
+    - tty: xilinx_uartps: split sysrq handling
+    - tty: vt: pass proper pointers from tioclinux()
+    - tty: Permit some TIOCL_SETSEL modes without CAP_SYS_ADMIN
+    - tty: Require CAP_SYS_ADMIN for all usages of TIOCL_SELMOUSEREPORT
+    - platform/x86: serdev_helpers: Check for serial_ctrl_uid == NULL
+    - nvme: handle connectivity loss in nvme_set_queue_count
+    - firmware: iscsi_ibft: fix ISCSI_IBFT Kconfig entry
+    - gpu: drm_dp_cec: fix broken CEC adapter properties check
+    - ice: put Rx buffers after being done with current frame
+    - ice: gather page_count()'s of each frag right before XDP prog call
+    - ice: stop storing XDP verdict within ice_rx_buf
+    - nvme-fc: use ctrl state getter
+    - net: bcmgenet: Correct overlaying of PHY and MAC Wake-on-LAN
+    - vmxnet3: Fix tx queue race condition with XDP
+    - tg3: Disable tg3 PCIe AER on system reboot
+    - udp: gso: do not drop small packets when PMTU reduces
+    - rxrpc: Fix the rxrpc_connection attend queue handling
+    - gpio: pca953x: Improve interrupt support
+    - net: atlantic: fix warning during hot unplug
+    - net: rose: lock the socket in rose_bind()
+    - ACPI: property: Fix return value for nval == 0 in acpi_data_prop_read()
+    - tun: revert fix group permission check
+    - net: sched: Fix truncation of offloaded action statistics
+    - rxrpc: Fix call state set to not include the SERVER_SECURING state
+    - cpufreq: s3c64xx: Fix compilation warning
+    - leds: lp8860: Write full EEPROM, not only half of it
+    - ALSA: hda/realtek: Enable Mute LED on HP Laptop 14s-fq1xxx
+    - drm/modeset: Handle tiled displays in pan_display_atomic.
+    - drm/client: Handle tiled displays better
+    - smb: client: fix order of arguments of tracepoints
+    - smb: client: change lease epoch type from unsigned int to __u16
+    - s390/futex: Fix FUTEX_OP_ANDN implementation
+    - arm64: Filter out SVE hwcaps when FEAT_SVE isn't implemented
+    - m68k: vga: Fix I/O defines
+    - fs/proc: do_task_stat: Fix ESP not readable during coredump
+    - binfmt_flat: Fix integer overflow bug on 32 bit systems
+    - accel/ivpu: Fix Qemu crash when running in passthrough
+    - arm64/kvm: Configure HYP TCR.PS/DS based on host stage1
+    - arm64/sme: Move storage of reg_smidr to __cpuinfo_store_cpu()
+    - KVM: arm64: timer: Always evaluate the need for a soft timer
+    - drm/rockchip: cdn-dp: Use drm_connector_helper_hpd_irq_event()
+    - arm64: dts: rockchip: increase gmac rx_delay on rk3399-puma
+    - remoteproc: omap: Handle ARM dma_iommu_mapping
+    - KVM: Explicitly verify target vCPU is online in kvm_get_vcpu()
+    - KVM: s390: vsie: fix some corner-cases when grabbing vsie pages
+    - ksmbd: fix integer overflows on 32 bit systems
+    - drm/amd/display: Optimize cursor position updates
+    - drm/amd/pm: Mark MM activity as unsupported
+    - drm/amdkfd: only flush the validate MES contex
+    - drm/i915/guc: Debug print LRC state entries only if the context is
+      pinned
+    - drm/i915: Fix page cleanup on DMA remap failure
+    - drm/komeda: Add check for komeda_get_layer_fourcc_list()
+    - drm/i915/dp: Iterate DSC BPP from high to low on all platforms
+    - drm/i915: Drop 64bpp YUV formats from ICL+ SDR planes
+    - drm/amd/display: Fix seamless boot sequence
+    - Bluetooth: L2CAP: accept zero as a special value for MTU auto-selection
+    - clk: sunxi-ng: a100: enable MMC clock reparenting
+    - clk: mmp2: call pm_genpd_init() only after genpd.name is set
+    - media: i2c: ds90ub960: Fix UB9702 refclk register access
+    - clk: qcom: clk-alpha-pll: fix alpha mode configuration
+    - clk: qcom: gcc-sm8550: Do not turn off PCIe GDSCs during gdsc_disable()
+    - clk: qcom: gcc-sm8650: Do not turn off PCIe GDSCs during gdsc_disable()
+    - clk: qcom: gcc-sm6350: Add missing parent_map for two clocks
+    - clk: qcom: dispcc-sm6350: Add missing parent_map for a clock
+    - clk: qcom: gcc-mdm9607: Fix cmd_rcgr offset for blsp1_uart6 rcg
+    - clk: qcom: clk-rpmh: prevent integer overflow in recalc_rate
+    - clk: mediatek: mt2701-vdec: fix conversion to mtk_clk_simple_probe
+    - clk: mediatek: mt2701-aud: fix conversion to mtk_clk_simple_probe
+    - clk: mediatek: mt2701-bdp: add missing dummy clk
+    - clk: mediatek: mt2701-img: add missing dummy clk
+    - clk: mediatek: mt2701-mm: add missing dummy clk
+    - blk-cgroup: Fix class @block_class's subsystem refcount leakage
+    - efi: libstub: Use '-std=gnu11' to fix build with GCC 15
+    - perf bench: Fix undefined behavior in cmpworker()
+    - scsi: ufs: core: Fix the HIGH/LOW_TEMP Bit Definitions
+    - of: Correct child specifier used as input of the 2nd nexus node
+    - of: Fix of_find_node_opts_by_path() handling of alias+path+options
+    - Input: bbnsm_pwrkey - add remove hook
+    - HID: hid-sensor-hub: don't use stale platform-data on remove
+    - ring-buffer: Do not allow events in NMI with generic atomic64 cmpxchg()
+    - atomic64: Use arch_spin_locks instead of raw_spin_locks
+    - wifi: rtlwifi: rtl8821ae: Fix media status report
+    - wifi: brcmfmac: fix NULL pointer dereference in brcmf_txfinalize()
+    - wifi: mt76: mt7921u: Add VID/PID for TP-Link TXE50UH
+    - wifi: rtw88: sdio: Fix disconnection after beacon loss
+    - wifi: mt76: mt7915: add module param to select 5 GHz or 6 GHz on MT7916
+    - usb: gadget: f_tcm: Translate error to sense
+    - usb: gadget: f_tcm: Decrement command ref count on cleanup
+    - usb: gadget: f_tcm: ep_autoconfig with fullspeed endpoint
+    - usb: gadget: f_tcm: Don't prepare BOT write request twice
+    - usbnet: ipheth: fix possible overflow in DPE length check
+    - usbnet: ipheth: use static NDP16 location in URB
+    - usbnet: ipheth: check that DPE points past NCM header
+    - usbnet: ipheth: refactor NCM datagram loop
+    - usbnet: ipheth: break up NCM header size computation
+    - usbnet: ipheth: fix DPE OoB read
+    - usbnet: ipheth: document scope of NCM implementation
+    - ASoC: acp: Support microphone from Lenovo Go S
+    - soc: qcom: socinfo: Avoid out of bounds read of serial number
+    - serial: sh-sci: Drop __initdata macro for port_cfg
+    - serial: sh-sci: Do not probe the serial port if its slot in sci_ports[]
+      is in use
+    - MIPS: Loongson64: remove ROM Size unit in boardinfo
+    - LoongArch: Extend the maximum number of watchpoints
+    - powerpc/pseries/eeh: Fix get PE state translation
+    - dm-crypt: don't update io->sector after kcryptd_crypt_write_io_submit()
+    - dm-crypt: track tag_offset in convert_context
+    - mips/math-emu: fix emulation of the prefx instruction
+    - MIPS: pci-legacy: Override pci_address_to_pio
+    - block: don't revert iter for -EIOCBQUEUED
+    - firmware: qcom: scm: Fix missing read barrier in qcom_scm_is_available()
+    - ALSA: hda/realtek: Enable headset mic on Positivo C6400
+    - ALSA: hda: Fix headset detection failure due to unstable sort
+    - ALSA: hda/realtek: Fix built-in mic on another ASUS VivoBook model
+    - ALSA: hda/realtek: Fix built-in mic breakage on ASUS VivoBook X515JA
+    - arm64: tegra: Fix Tegra234 PCIe interrupt-map
+    - PCI: endpoint: Finish virtual EP removal in pci_epf_remove_vepf()
+    - PCI: dwc: ep: Write BAR_MASK before iATU registers in pci_epc_set_bar()
+    - PCI: dwc: ep: Prevent changing BAR size/flags in pci_epc_set_bar()
+    - scsi: st: Don't set pos_unknown just after device recognition
+    - scsi: qla2xxx: Move FCE Trace buffer allocation to user control
+    - scsi: ufs: qcom: Fix crypto key eviction
+    - scsi: ufs: core: Fix use-after free in init error and remove paths
+    - scsi: storvsc: Set correct data length for sending SCSI command without
+      payload
+    - scsi: core: Do not retry I/Os during depopulation
+    - kbuild: Move -Wenum-enum-conversion to W=2
+    - rust: init: use explicit ABI to clean warning in future compilers
+    - x86/boot: Use '-std=gnu11' to fix build with GCC 15
+    - ubi: Add a check for ubi_num
+    - ARM: dts: dra7: Add bus_dma_limit for l4 cfg bus
+    - ARM: dts: ti/omap: gta04: fix pm issues caused by spi module
+    - arm64: dts: qcom: sm6115: Fix MPSS memory length
+    - arm64: dts: qcom: sm6115: Fix CDSP memory length
+    - arm64: dts: qcom: sm6115: Fix ADSP memory base and length
+    - arm64: dts: qcom: sm6350: Fix ADSP memory length
+    - arm64: dts: qcom: sm6350: Fix MPSS memory length
+    - arm64: dts: qcom: sm6350: Fix uart1 interconnect path
+    - arm64: dts: qcom: sm6375: Fix ADSP memory length
+    - arm64: dts: qcom: sm6375: Fix CDSP memory base and length
+    - arm64: dts: qcom: sm6375: Fix MPSS memory base and length
+    - arm64: dts: qcom: sm8350: Fix ADSP memory base and length
+    - arm64: dts: qcom: sm8350: Fix CDSP memory base and length
+    - arm64: dts: qcom: sm8350: Fix MPSS memory length
+    - arm64: dts: qcom: sm8450: Fix CDSP memory length
+    - arm64: dts: qcom: sm8450: Fix MPSS memory length
+    - arm64: dts: qcom: sm8550: Fix CDSP memory length
+    - arm64: dts: qcom: sm8550: Fix MPSS memory length
+    - arm64: dts: qcom: sm8450: add missing qcom,non-secure-domain property
+    - arm64: dts: qcom: sm8450: Fix ADSP memory base and length
+    - arm64: dts: qcom: sm8550: add missing qcom,non-secure-domain property
+    - arm64: dts: qcom: sm8550: Add dma-coherent property
+    - arm64: dts: qcom: sm8550: Fix ADSP memory base and length
+    - arm64: dts: qcom: sm8650: Fix CDSP memory length
+    - arm64: dts: qcom: sm8650: Fix MPSS memory length
+    - arm64: dts: qcom: sm8550: correct MDSS interconnects
+    - arm64: dts: qcom: sm8650: correct MDSS interconnects
+    - crypto: qce - fix priority to be less than ARMv8 CE
+    - arm64: tegra: Fix typo in Tegra234 dce-fabric compatible
+    - arm64: tegra: Disable Tegra234 sce-fabric node
+    - parisc: Temporarily disable jump label support
+    - pwm: microchip-core: fix incorrect comparison with max period
+    - xfs: Propagate errors from xfs_reflink_cancel_cow_range in
+      xfs_dax_write_iomap_end
+    - xfs: Add error handling for xfs_reflink_cancel_cow_range
+    - ACPI: PRM: Remove unnecessary strict handler address checks
+    - tpm: Change to kvalloc() in eventlog/acpi.c
+    - rv: Reset per-task monitors also for idle tasks
+    - hrtimers: Force migrate away hrtimers queued after
+      CPUHP_AP_HRTIMERS_DYING
+    - kfence: skip __GFP_THISNODE allocations on NUMA systems
+    - media: ccs: Clean up parsed CCS static data on parse failure
+    - mm/hugetlb: fix avoid_reserve to allow taking folio from subpool
+    - iio: light: as73211: fix channel handling in only-color triggered buffer
+    - soc: mediatek: mtk-devapc: Fix leaking IO map on error paths
+    - soc: mediatek: mtk-devapc: Fix leaking IO map on driver remove
+    - soc: qcom: smem_state: fix missing of_node_put in error path
+    - media: mmp: Bring back registration of the device
+    - media: mc: fix endpoint iteration
+    - media: nuvoton: Fix an error check in npcm_video_ece_init()
+    - media: imx296: Add standby delay during probe
+    - media: ov5640: fix get_light_freq on auto
+    - media: stm32: dcmipp: correct dma_set_mask_and_coherent mask value
+    - media: ccs: Fix CCS static data parsing for large block sizes
+    - media: ccs: Fix cleanup order in ccs_probe()
+    - media: i2c: ds90ub9x3: Fix extra fwnode_handle_put()
+    - media: i2c: ds90ub960: Fix use of non-existing registers on UB9702
+    - media: i2c: ds90ub960: Fix UB9702 VC map
+    - media: i2c: ds90ub960: Fix logging SP & EQ status only for UB9702
+    - media: uvcvideo: Fix crash during unbind if gpio unit is in use
+    - media: uvcvideo: Fix event flags in uvc_ctrl_send_events
+    - media: uvcvideo: Support partial control reads
+    - media: uvcvideo: Remove redundant NULL assignment
+    - media: uvcvideo: Refactor iterators
+    - media: uvcvideo: Only save async fh if success
+    - media: uvcvideo: Remove dangling pointers
+    - mm: kmemleak: fix upper boundary check for physical address objects
+    - mm/compaction: fix UBSAN shift-out-of-bounds warning
+    - ata: libata-sff: Ensure that we cannot write outside the allocated
+      buffer
+    - crypto: qce - fix goto jump in error path
+    - crypto: qce - unregister previously registered algos in error path
+    - nvmem: qcom-spmi-sdam: Set size in struct nvmem_config
+    - nvmem: core: improve range check for nvmem_cell_write()
+    - nvmem: imx-ocotp-ele: simplify read beyond device check
+    - nvmem: imx-ocotp-ele: fix MAC address byte order
+    - nvmem: imx-ocotp-ele: fix reading from non zero offset
+    - nvmem: imx-ocotp-ele: set word length to 1
+    - io_uring: fix multishots with selected buffers
+    - io_uring/net: don't retry connect operation on EPOLLERR
+    - selftests: mptcp: connect: -f: no reconnect
+    - pnfs/flexfiles: retry getting layout segment for reads
+    - ocfs2: fix incorrect CPU endianness conversion causing mount failure
+    - ocfs2: handle a symlink read error correctly
+    - nilfs2: fix possible int overflows in nilfs_fiemap()
+    - nfs: Make NFS_FSCACHE select NETFS_SUPPORT instead of depending on it
+    - NFSD: Encode COMPOUND operation status on page boundaries
+    - mailbox: tegra-hsp: Clear mailbox before using message
+    - NFC: nci: Add bounds checking in nci_hci_create_pipe()
+    - irqchip/apple-aic: Only handle PMC interrupt as FIQ when configured so
+    - mtd: onenand: Fix uninitialized retlen in do_otp_read()
+    - misc: misc_minor_alloc to use ida for all dynamic/misc dynamic minors
+    - char: misc: deallocate static minor in error path
+    - misc: fastrpc: Deregister device nodes properly in error scenarios
+    - misc: fastrpc: Fix registered buffer page address
+    - misc: fastrpc: Fix copy buffer page size
+    - net/ncsi: wait for the last response to Deselect Package before
+      configuring channel
+    - net: phy: c45-tjaxx: add delay between MDIO write and read in soft_reset
+    - maple_tree: simplify split calculation
+    - scripts/gdb: fix aarch64 userspace detection in get_current_task
+    - tracing/osnoise: Fix resetting of tracepoints
+    - rtla/osnoise: Distinguish missing workload option
+    - rtla: Add trace_instance_stop
+    - rtla/timerlat_hist: Stop timerlat tracer on signal
+    - rtla/timerlat_top: Stop timerlat tracer on signal
+    - pinctrl: samsung: fix fwnode refcount cleanup if
+      platform_get_irq_optional() fails
+    - ptp: Ensure info->enable callback is always set
+    - RDMA/mlx5: Fix a race for an ODP MR which leads to CQE with error
+    - rtc: zynqmp: Fix optional clock name property
+    - MIPS: ftrace: Declare ftrace_get_parent_ra_addr() as static
+    - xfs: avoid nested calls to __xfs_trans_commit
+    - xfs: don't lose solo superblock counter update transactions
+    - spi: atmel-quadspi: Create `atmel_qspi_ops` to support newer SoC
+      families
+    - spi: atmel-qspi: Memory barriers after memory-mapped I/O
+    - btrfs: avoid monopolizing a core when activating a swap file
+    - mptcp: prevent excessive coalescing on receive
+    - Revert "drm/amd/display: Fix green screen issue after suspend"
+    - statmount: let unset strings be empty
+    - arm64: dts: rockchip: add reset-names for combphy on rk3568
+    - ocfs2: check dir i_size in ocfs2_find_entry
+    - Upstream stable to v6.6.77, v6.12.14
+  * kvmppc_set_passthru_irq_hv: Could not assign IRQ map traces are seen when
+    pci device is attached to kvm guest when "xive=off" is set (LP: #2109951)
+    - KVM: PPC: Book3S HV: Fix IRQ map warnings with XICS on pSeries KVM Guest
+  * Latitude 5450 is experiencing packet loss on Ethernet in Ubuntu 22.04
+    (LP: #2106558)
+    - e1000e: change k1 configuration on MTP and later platforms
+  * cpufreq amd-pstate: cpuinfo_max_freq reports incorrect value
+    (LP: #2109609)
+    - SAUCE: Revert "Revert "cpufreq: amd-pstate: Fix the inconsistency in max
+      frequency units""
+  * Backport pci=config_acs parameter with fix commit (LP: #2100340)
+    - PCI: Extend ACS configurability
+    - PCI: Fix pci_enable_acs() support for the ACS quirks
+    - PCI/ACS: Fix 'pci=config_acs=' parameter
+  * [UBUNTU 24.04] s390/pci: Fix zpci_bus_is_isolated_vf() for non-VF
+    (LP: #2111599)
+    - s390/pci: Fix zpci_bus_is_isolated_vf() for non-VFs
+  * nvme/tcp hangs IO on arm (LP: #2106381)
+    - nvmet-tcp: Fix a possible sporadic response drops in weakly ordered arch
+  * CVE-2025-37750
+    - smb: client: fix UAF in decryption with multichannel
+  * CVE-2025-40364
+    - io_uring: fix io_req_prep_async with provided buffers
+  * CVE-2024-49887
+    - f2fs: fix to handle segment allocation failure correctly
+    - f2fs: fix to don't panic system for no free segment fault injection
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953)
+    - powerpc/book3s64/hugetlb: Fix disabling hugetlb when fadump is active
+    - dlm: fix srcu_read_lock() return type to int
+    - afs: Fix EEXIST error returned from afs_rmdir() to be ENOTEMPTY
+    - afs: Fix directory format encoding struct
+    - afs: Fix cleanup of immediately failed async calls
+    - fs: fix proc_handler for sysctl_nr_open
+    - block: retry call probe after request_module in blk_request_module
+    - pstore/blk: trivial typo fixes
+    - nvme: Add error check for xa_store in nvme_get_effects_log
+    - selftests/powerpc: Fix argument order to timer_sub()
+    - nvme: Add error path for xa_store in nvme_init_effects
+    - partitions: ldm: remove the initial kernel-doc notation
+    - select: Fix unbalanced user_access_end()
+    - nvme: fix bogus kzalloc() return check in nvme_init_effects_log()
+    - afs: Fix the fallback handling for the YFS.RemoveFile2 RPC call
+    - perf/core: Save raw sample data conditionally based on sample type
+    - sched/fair: Fix value reported by hot tasks pulled in /proc/schedstat
+    - x86/cpu: Enable SD_ASYM_PACKING for PKG domain on AMD
+    - x86/topology: Use x86_sched_itmt_flags for PKG domain unconditionally
+    - drm/msm/dp: set safe_to_exit_level before printing it
+    - drm/etnaviv: Fix page property being used for non writecombine buffers
+    - drm/amd/pm: Fix an error handling path in
+      vega10_enable_se_edc_force_stall_config()
+    - drm/rockchip: vop2: Fix cluster windows alpha ctrl regsiters offset
+    - drm/rockchip: vop2: Fix the mixer alpha setup for layer 0
+    - drm/rockchip: vop2: Fix the windows switch between different layers
+    - drm/rockchip: vop2: Check linear format for Cluster windows on rk3566/8
+    - drm/rockchip: vop2: include rockchip_drm_drv.h
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8150
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SC8180X
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8250
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8350
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8550
+    - drm/msm: Check return value of of_dma_configure()
+    - drm/bridge: it6505: Change definition of AUX_FIFO_MAX_SIZE
+    - drm/amdgpu: tear down ttm range manager for doorbell in
+      amdgpu_ttm_fini()
+    - genirq: Make handle_enforce_irqctx() unconditionally available
+    - wifi: ath11k: Fix unexpected return buffer manager error for
+      WCN6750/WCN6855
+    - wifi: rtlwifi: do not complete firmware loading needlessly
+    - wifi: rtlwifi: rtl8192se: rise completion of firmware loading as last
+      step
+    - wifi: rtlwifi: wait for firmware loading before releasing memory
+    - wifi: rtlwifi: fix init_sw_vars leak when probe fails
+    - wifi: rtlwifi: usb: fix workqueue leak when probe fails
+    - net_sched: sch_sfq: annotate data-races around q->perturb_period
+    - net_sched: sch_sfq: handle bigger packets
+    - spi: zynq-qspi: Add check for clk_enable()
+    - dt-bindings: mmc: controller: clarify the address-cells description
+    - of: remove internal arguments from of_property_for_each_u32()
+    - clk: fix an OF node reference leak in of_clk_get_parent_name()
+    - dt-bindings: leds: class-multicolor: Fix path to color definitions
+    - wifi: rtlwifi: destroy workqueue at rtl_deinit_core
+    - wifi: rtlwifi: pci: wait for firmware loading before releasing memory
+    - HID: multitouch: fix support for Goodix PID 0x01e9
+    - regulator: dt-bindings: mt6315: Drop regulator-compatible property
+    - wifi: brcmfmac: add missing header include for brcmf_dbg
+    - ACPI: fan: cleanup resources in the error path of .probe()
+    - cpupower: fix TSC MHz calculation
+    - dt-bindings: mfd: bd71815: Fix rsense and typos
+    - leds: netxbig: Fix an OF node reference leak in
+      netxbig_leds_get_of_pdata()
+    - inetpeer: remove create argument of inet_getpeer_v[46]()
+    - inetpeer: remove create argument of inet_getpeer()
+    - inetpeer: update inetpeer timestamp in inet_getpeer()
+    - inetpeer: do not get a refcount in inet_getpeer()
+    - pwm: stm32-lp: Add check for clk_enable()
+    - cpufreq: schedutil: Fix superfluous updates caused by need_freq_update
+    - gpio: pca953x: log an error when failing to get the reset GPIO
+    - cpufreq: qcom: Fix qcom_cpufreq_hw_recalc_rate() to query LUT if LMh IRQ
+      is not available
+    - cpufreq: qcom: Implement clk_ops::determine_rate() for qcom_cpufreq*
+      clocks
+    - clk: imx8mp: Fix clkout1/2 support
+    - dt-bindings: clock: sunxi: Export PLL_VIDEO_2X and PLL_MIPI
+    - clk: sunxi-ng: a64: drop redundant CLK_PLL_VIDEO0_2X and CLK_PLL_MIPI
+    - clk: sunxi-ng: a64: stop force-selecting PLL-MIPI as TCON0 parent
+    - regulator: of: Implement the unwind path of of_regulator_match()
+    - OPP: OF: Fix an OF node leak in _opp_add_static_v2()
+    - ipmi: ssif_bmc: Fix new request loss when bmc ready for a response
+    - wifi: ath12k: fix tx power, max reg power update to firmware
+    - clk: qcom: gcc-sdm845: Do not use shared clk_ops for QUPs
+    - HID: fix generic desktop D-Pad controls
+    - leds: cht-wcove: Use devm_led_classdev_register() to avoid memory leak
+    - mfd: syscon: Remove extern from function prototypes
+    - mfd: syscon: Add of_syscon_register_regmap() API
+    - mfd: syscon: Use scoped variables with memory allocators to simplify
+      error paths
+    - mfd: syscon: Fix race in device_node_get_regmap()
+    - samples/landlock: Fix possible NULL dereference in parse_path()
+    - wifi: wlcore: fix unbalanced pm_runtime calls
+    - wifi: mt76: mt7915: Fix mesh scan on MT7916 DBDC
+    - wifi: mac80211: fix tid removal during mesh forwarding
+    - wifi: mac80211: Fix common size calculation for ML element
+    - net/smc: fix data error when recvmsg with MSG_PEEK flag
+    - wifi: mt76: mt76u_vendor_request: Do not print error messages when
+      -EPROTO
+    - wifi: mt76: mt7921: fix using incorrect group cipher after
+      disconnection.
+    - wifi: mt76: mt7915: fix overflows seen when writing limit attributes
+    - wifi: mt76: mt7996: fix rx filter setting for bfee functionality
+    - wifi: mt76: mt7915: firmware restart on devices with a second pcie link
+    - wifi: mt76: connac: move mt7615_mcu_del_wtbl_all to connac
+    - wifi: mt76: mt7915: improve hardware restart reliability
+    - wifi: mt76: mt7915: fix omac index assignment after hardware reset
+    - wifi: mt76: mt7915: fix register mapping
+    - wifi: mt76: mt7996: fix register mapping
+    - wifi: mt76: mt7996: add max mpdu len capability
+    - wifi: mt76: mt7996: fix the capability of reception of EHT MU PPDU
+    - wifi: mt76: mt7996: fix HE Phy capability
+    - wifi: mt76: mt7996: fix incorrect indexing of MIB FW event
+    - wifi: mt76: mt7996: fix ldpc setting
+    - cpufreq: ACPI: Fix max-frequency computation
+    - selftests: timers: clocksource-switch: Adapt progress to kselftest
+      framework
+    - selftests: harness: fix printing of mismatch values in __EXPECT()
+    - wifi: cfg80211: adjust allocation of colocated AP data
+    - inet: ipmr: fix data-races
+    - clk: analogbits: Fix incorrect calculation of vco rate delta
+    - pwm: stm32: Add check for clk_enable()
+    - selftests/landlock: Fix error message
+    - net/mlxfw: Drop hard coded max FW flash image size
+    - octeon_ep: remove firmware stats fetch in ndo_get_stats64
+    - netfilter: nf_tables: fix set size with rbtree backend
+    - netfilter: nft_flow_offload: update tcp state flags under lock
+    - tcp_cubic: fix incorrect HyStart round start detection
+    - libbpf: don't adjust USDT semaphore address if .stapsdt.base addr is
+      missing
+    - tools/testing/selftests/bpf/test_tc_tunnel.sh: Fix wait for server bind
+    - libbpf: Fix segfault due to libelf functions not setting errno
+    - ASoC: sun4i-spdif: Add clock multiplier settings
+    - selftests/bpf: Fix fill_link_info selftest on powerpc
+    - crypto: caam - use JobR's space to access page 0 regs
+    - perf header: Fix one memory leakage in process_bpf_btf()
+    - perf header: Fix one memory leakage in process_bpf_prog_info()
+    - perf bpf: Fix two memory leakages when calling
+      perf_env__insert_bpf_prog_info()
+    - ASoC: renesas: rz-ssi: Use only the proper amount of dividers
+    - perf expr: Initialize is_test value in expr__ctx_new()
+    - ktest.pl: Remove unused declarations in run_bisect_test function
+    - crypto: hisilicon/sec2 - fix for aead icv error
+    - crypto: hisilicon/sec2 - fix for aead invalid authsize
+    - crypto: ixp4xx - fix OF node reference leaks in init_ixp_crypto()
+    - ALSA: seq: remove redundant 'tristate' for SND_SEQ_UMP_CLIENT
+    - ALSA: seq: Make dependency on UMP clearer
+    - padata: fix sysfs store callback check
+    - perf top: Don't complain about lack of vmlinux when not resolving some
+      kernel samples
+    - perf machine: Don't ignore _etext when not a text symbol
+    - perf namespaces: Introduce nsinfo__set_in_pidns()
+    - perf namespaces: Fixup the nsinfo__in_pidns() return type, its bool
+    - ASoC: Intel: avs: Prefix SKL/APL-specific members
+    - ASoC: Intel: avs: Abstract IPC handling
+    - ASoC: Intel: avs: Do not readq() u32 registers
+    - ASoC: Intel: avs: Fix theoretical infinite loop
+    - perf report: Fix misleading help message about --demangle
+    - pinctrl: stm32: Add check for clk_enable()
+    - pinctrl: amd: Take suspend type into consideration which pins are non-
+      wake
+    - bpf: tcp: Mark bpf_load_hdr_opt() arg2 as read-write
+    - ALSA: hda/realtek - Fixed headphone distorted sound on Acer Aspire
+      A115-31 laptop
+    - perf lock: Fix parse_lock_type which only retrieve one lock flag
+    - padata: add pd get/put refcnt helper
+    - cifs: Use cifs_autodisable_serverino() for disabling
+      CIFS_MOUNT_SERVER_INUM in readdir.c
+    - soc: atmel: fix device_node release in atmel_soc_device_init()
+    - ARM: at91: pm: change BU Power Switch to automatic mode
+    - arm64: dts: mediatek: mt8186: Move wakeup to MTU3 to get working suspend
+    - arm64: dts: mt8183: set DMIC one-wire mode on Damu
+    - arm64: dts: mediatek: mt8516: fix GICv2 range
+    - arm64: dts: mediatek: mt8516: fix wdt irq type
+    - arm64: dts: mediatek: mt8516: add i2c clock-div property
+    - arm64: dts: mediatek: mt8516: reserve 192 KiB for TF-A
+    - ARM: dts: stm32: Fix IPCC EXTI declaration on stm32mp151
+    - RDMA/mlx4: Avoid false error about access to uninitialized gids array
+    - arm64: dts: mediatek: mt8173-evb: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8173-elm: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8192-asurada: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8195-cherry: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8195-demo: Drop regulator-compatible property
+    - arm64: dts: mediatek: mt8173-elm: Fix MT6397 PMIC sub-node names
+    - arm64: dts: mediatek: mt8173-evb: Fix MT6397 PMIC sub-node names
+    - ARM: dts: aspeed: yosemite4: correct the compatible string of adm1272
+    - ARM: dts: aspeed: yosemite4: Add required properties for IOE on fan
+      boards
+    - ARM: dts: aspeed: yosemite4: correct the compatible string for max31790
+    - arm: dts: socfpga: use reset-name "stmmaceth-ocp" instead of "ahb"
+    - RDMA/rxe: Improve newline in printing messages
+    - RDMA/rxe: Fix mismatched max_msg_sz
+    - arm64: dts: mediatek: mt8183: kenzo: Support second source touchscreen
+    - arm64: dts: mediatek: mt8183: willow: Support second source touchscreen
+    - RDMA/srp: Fix error handling in srp_add_port
+    - arm64: dts: mediatek: mt8195: Remove suspend-breaking reset from pcie1
+    - ARM: dts: stm32: Deduplicate serial aliases and chosen node for
+      STM32MP15xx DHCOM SoM
+    - ARM: dts: stm32: Swap USART3 and UART8 alias on STM32MP15xx DHCOM SoM
+    - arm64: dts: mediatek: mt8183-kukui-jacuzzi: Drop pp3300_panel voltage
+      settings
+    - arm64: dts: qcom: msm8996-xiaomi-gemini: Fix LP5562 LED1 reg property
+    - arm64: dts: qcom: move common parts for sa8775p-ride variants into a
+      .dtsi
+    - arm64: dts: qcom: sa8775p: Update sleep_clk frequency
+    - arm64: dts: qcom: msm8996: Fix up USB3 interrupts
+    - arm64: dts: qcom: msm8994: Describe USB interrupts
+    - arm64: dts: qcom: sm7225-fairphone-fp4: Drop extra qcom,msm-id value
+    - arm64: dts: qcom: msm8916: correct sleep clock frequency
+    - arm64: dts: qcom: msm8939: correct sleep clock frequency
+    - arm64: dts: qcom: msm8994: correct sleep clock frequency
+    - arm64: dts: qcom: qcs404: correct sleep clock frequency
+    - arm64: dts: qcom: q[dr]u1000: correct sleep clock frequency
+    - arm64: dts: qcom: qrb4210-rb2: correct sleep clock frequency
+    - arm64: dts: qcom: sc7280: correct sleep clock frequency
+    - arm64: dts: qcom: sdx75: correct sleep clock frequency
+    - arm64: dts: qcom: sm4450: correct sleep clock frequency
+    - arm64: dts: qcom: sm6125: correct sleep clock frequency
+    - arm64: dts: qcom: sm6375: correct sleep clock frequency
+    - arm64: dts: qcom: sm8250: correct sleep clock frequency
+    - arm64: dts: qcom: sm8350: correct sleep clock frequency
+    - arm64: dts: qcom: sm8450: correct sleep clock frequency
+    - ARM: dts: microchip: sama5d27_wlsom1_ek: Add no-1-8-v property to sdmmc0
+      node
+    - arm64: dts: ti: k3-am62: Remove duplicate GICR reg
+    - arm64: dts: ti: k3-am62a: Remove duplicate GICR reg
+    - arm64: dts: allwinner: a64: explicitly assign clock parent for TCON0
+    - RDMA/bnxt_re: Fix to drop reference to the mmap entry in case of error
+    - ARM: omap1: Fix up the Retu IRQ on Nokia 770
+    - arm64: dts: qcom: sdm845-db845c-navigation-mezzanine: Convert mezzanine
+      riser to dtso
+    - arm64: dts: qcom: sdm845-db845c-navigation-mezzanine: remove disabled
+      ov7251 camera
+    - arm64: dts: qcom: sc7180-trogdor-quackingstick: add missing avee-supply
+    - arm64: dts: qcom: sc7180-*: Remove thermal zone polling delays
+    - arm64: dts: qcom: sc7180-trogdor-pompom: rename 5v-choke thermal zone
+    - arm64: dts: qcom: sc7180: change labels to lower-case
+    - arm64: dts: qcom: sc7180: fix psci power domain node names
+    - arm64: dts: qcom: sm8150-microsoft-surface-duo: fix typos in da7280
+      properties
+    - arm64: dts: qcom: sc8280xp: Fix up remoteproc register space sizes
+    - dts: arm64: mediatek: mt8195: Remove MT8183 compatible for OVL
+    - arm64: dts: mediatek: add per-SoC compatibles for keypad nodes
+    - arm64: dts: qcom: sdm845: Fix interrupt types of camss interrupts
+    - arm64: dts: qcom: sm8250: Fix interrupt types of camss interrupts
+    - ARM: dts: mediatek: mt7623: fix IR nodename
+    - fbdev: omapfb: Fix an OF node leak in dss_of_port_get_parent_device()
+    - arm64: tegra: Fix DMA ID for SPI2
+    - i3c: dw: Add hot-join support.
+    - RDMA/mlx5: Fix indirect mkey ODP page count
+    - of: reserved-memory: Do not make kmemleak ignore freed address
+    - efi: sysfb_efi: fix W=1 warnings when EFI is not set
+    - spi: omap2-mcspi: Correctly handle devm_clk_get_optional() errors
+    - media: rc: iguanair: handle timeouts
+    - media: lmedm04: Handle errors for lme2510_int_read
+    - PCI: endpoint: Destroy the EPC device in devm_pci_epc_destroy()
+    - media: marvell: Add check for clk_enable()
+    - media: i2c: imx290: Register 0x3011 varies between imx327 and imx290
+    - media: i2c: imx412: Add missing newline to prints
+    - media: i2c: ov9282: Correct the exposure offset
+    - media: mipi-csis: Add check for clk_enable()
+    - media: camif-core: Add check for clk_enable()
+    - media: uvcvideo: Propagate buf->error to userspace
+    - mtd: rawnand: brcmnand: fix status read of brcmnand_waitfunc
+    - mtd: hyperbus: hbmc-am654: fix an OF node reference leak
+    - media: nxp: imx8-isi: fix v4l2-compliance test errors
+    - watchdog: rti_wdt: Fix an OF node leak in rti_wdt_probe()
+    - staging: media: imx: fix OF node leak in imx_media_add_of_subdevs()
+    - media: dvb-usb-v2: af9035: fix ISO C90 compilation error on
+      af9035_i2c_master_xfer
+    - PCI: endpoint: pci-epf-test: Set dma_chan_rx pointer to NULL on error
+    - PCI: endpoint: pci-epf-test: Fix check for DMA MEMCPY test
+    - scsi: mpt3sas: Set ioc->manu_pg11.EEDPTagMode directly to 1
+    - scsi: ufs: bsg: Delete bsg_dev when setting up bsg fails
+    - ocfs2: mark dquot as inactive if failed to start trans while releasing
+      dquot
+    - module: Extend the preempt disabled section in
+      dereference_symbol_descriptor().
+    - serial: 8250: Adjust the timeout for FIFO mode
+    - NFSv4.2: fix COPY_NOTIFY xdr buf size calculation
+    - NFSv4.2: mark OFFLOAD_CANCEL MOVEABLE
+    - tools/bootconfig: Fix the wrong format specifier
+    - xfrm: replay: Fix the update of replay_esn->oseq_hi for GSO
+    - dmaengine: ti: edma: fix OF node reference leaks in edma_driver
+    - rtc: loongson: clear TOY_MATCH0_REG in loongson_rtc_isr()
+    - regulator: core: Add missing newline character
+    - gpio: mxc: remove dead code after switch to DT-only
+    - net: fec: implement TSO descriptor cleanup
+    - PM: hibernate: Add error handling for syscore_suspend()
+    - iavf: allow changing VLAN state without calling PF
+    - net: netdevsim: try to close UDP port harness races
+    - ptp: Properly handle compat ioctls
+    - net: stmmac: Limit the number of MTL queues to hardware capability
+    - net: stmmac: Limit FIFO size by hardware capability
+    - perf trace: Fix runtime error of index out of bounds
+    - Bluetooth: btnxpuart: Fix glitches seen in dual A2DP streaming
+    - vsock: Allow retrying on connect() failure
+    - bgmac: reduce max frame size to support just MTU 1500
+    - net: sh_eth: Fix missing rtnl lock in suspend/resume path
+    - genksyms: fix memory leak when the same symbol is added from source
+    - genksyms: fix memory leak when the same symbol is read from *.symref
+      file
+    - RISC-V: Mark riscv_v_init() as __init
+    - ASoC: rockchip: i2s_tdm: Re-add the set_sysclk callback
+    - io_uring/uring_cmd: use cached cmd_op in io_uring_cmd_sock()
+    - cifs: Fix getting and setting SACLs over SMB1
+    - kconfig: fix file name in warnings when loading KCONFIG_DEFCONFIG_LIST
+    - kconfig: fix memory leak in sym_warn_unmet_dep()
+    - hexagon: fix using plain integer as NULL pointer warning in cmpxchg
+    - hexagon: Fix unbalanced spinlock in die()
+    - f2fs: Introduce linear search for dentries
+    - Revert "SUNRPC: Reduce thread wake-up rate when receiving large RPC
+      messages"
+    - kbuild: switch from lz4c to lz4 for compression
+    - selftests/rseq: Fix handling of glibc without rseq support
+    - ktest.pl: Check kernelrelease return in get_version
+    - ALSA: usb-audio: Add delay quirk for iBasso DC07 Pro
+    - usb: gadget: f_tcm: Fix Get/SetInterface return value
+    - usb: dwc3-am62: Fix an OF node leak in phy_syscon_pll_refclk()
+    - usb: dwc3: core: Defer the probe until USB power supply ready
+    - usb: typec: tcpm: set SRC_SEND_CAPABILITIES timeout to
+      PD_T_SENDER_RESPONSE
+    - usb: typec: tcpci: Prevent Sink disconnection before vPpsShutdown in SPR
+      PPS
+    - btrfs: output the reason for open_ctree() failure
+    - s390: Add '-std=gnu11' to decompressor and purgatory CFLAGS
+    - LoongArch: Change 8 to 14 for LOONGARCH_MAX_{BRP,WRP}
+    - block: copy back bounce buffer to user-space correctly in case of split
+    - nvme-tcp: Fix I/O queue cpu spreading for multiple controllers
+    - sched/fair: Untangle NEXT_BUDDY and pick_next_task()
+    - sched: Fix race between yield_to() and try_to_wake_up()
+    - drm/v3d: Fix performance counter source settings on V3D 7.x
+    - drm/rockchip: vop2: fix rk3588 dp+dsi maxclk verification
+    - drm/rockchip: vop2: Set AXI id for rk3588
+    - drm/rockchip: vop2: Setup delay cycle for Esmart2/3
+    - drm/rockchip: vop2: Add check for 32 bpp format for rk3588
+    - drm/msm/dpu: provide DSPP and correct LM config for SDM670
+    - drm/msm/dpu: link DSPP_2/_3 blocks on SM8650
+    - drm/msm: don't clean up priv->kms prematurely
+    - drm/msm/mdp4: correct LCDC regulator name
+    - wifi: rtlwifi: rtl8821ae: phy: restore removed code to fix infinite loop
+    - selftests/bpf: Actuate tx_metadata_len in xdp_hw_metadata
+    - selftests: ktap_helpers: Fix uninitialized variable
+    - inet: constify inet_sk_bound_dev_eq() net parameter
+    - inet: constify 'struct net' parameter of various lookup helpers
+    - udp: constify 'struct net' parameter of socket lookups
+    - inet6: constify 'struct net' parameter of various lookup helpers
+    - ipv6: udp: constify 'struct net' parameter of socket lookups
+    - dt-bindings: clock: imx93: Drop IMX93_CLK_END macro definition
+    - dt-bindings: clock: Add i.MX91 clock support
+    - dt-bindings: clock: imx93: Add SPDIF IPG clk
+    - clk: imx93: Move IMX93_CLK_END macro to clk driver
+    - clk: imx: add i.MX91 clk
+    - clk: imx93: Add IMX93_CLK_SPDIF_IPG clock
+    - arm64: dts: imx93: Use IMX93_CLK_SPDIF_IPG as SPDIF IPG clock
+    - clk: imx: Apply some clks only for i.MX93
+    - wifi: rtw89: mcc: consider time limits not divisible by 1024
+    - wifi: iwlwifi: cleanup uefi variables loading
+    - wifi: iwlwifi: fw: read STEP table from correct UEFI var
+    - wifi: mt76: mt7996: fix overflows seen when writing limit attributes
+    - wifi: mt76: mt7996: fix definition of tx descriptor
+    - Bluetooth: btbcm: Fix NULL deref in btbcm_get_board_name()
+    - platform/mellanox: mlxbf-pmc: incorrect type in assignment
+    - platform/x86: x86-android-tablets: make platform data be static
+    - crypto: api - Fix boot-up self-test race
+    - pinctrl: nomadik: Add check for clk_enable()
+    - rhashtable: Fix potential deadlock by moving schedule_work outside lock
+    - crypto: iaa - Fix IAA disabling that occurs when sync_mode is set to
+      'async'
+    - perf maps: Fix display of kernel symbols
+    - perf MANIFEST: Add arch/*/include/uapi/asm/bpf_perf_event.h to the perf
+      tarball
+    - ALSA: hda: Fix compilation of snd_hdac_adsp_xxx() helpers
+    - tools: Sync if_xdp.h uapi tooling header
+    - rhashtable: Fix rhashtable_try_insert test
+    - ARM: dts: imx7-tqma7: add missing vs-supply for LM75A (rev. 01xxx)
+    - arm64: dts: renesas: rzg3s-smarc: Fix the debug serial alias
+    - arm64: dts: mediatek: mt8395-genio-1200-evk: Drop regulator-compatible
+      property
+    - arm64: dts: qcom: sm8550: correct sleep clock frequency
+    - arm64: dts: qcom: sm8650: correct sleep clock frequency
+    - arm64: dts: qcom: x1e80100: correct sleep clock frequency
+    - ARM: dts: microchip: sama5d29_curiosity: Add no-1-8-v property to sdmmc0
+      node
+    - RDMA/hns: Clean up the legacy CONFIG_INFINIBAND_HNS
+    - [Config] updateconfigs for INFINIBAND_HNS
+    - RDMA/cxgb4: Notify rdma stack for IB_EVENT_QP_LAST_WQE_REACHED event
+    - iommu: iommufd: fix WARNING in iommufd_device_unbind
+    - remoteproc: mtk_scp: Only populate devices for SCP cores
+    - PCI: imx6: Deassert apps_reset in imx_pcie_deassert_core_reset()
+    - PCI: dwc: Always stop link in the dw_pcie_suspend_noirq
+    - PCI: microchip: Add support for using either Root Port 1 or 2
+    - PCI: microchip: Set inbound address translation for coherent or non-
+      coherent mode
+    - erofs: get rid of erofs_{find,insert}_workgroup
+    - erofs: move erofs_workgroup operations into zdata.c
+    - erofs: sunset `struct erofs_workgroup`
+    - erofs: fix potential return value overflow of z_erofs_shrink_scan()
+    - tty: mips_ejtag_fdc: fix one more u8 warning
+    - xfrm: Add support for per cpu xfrm state handling.
+    - xfrm: Cache used outbound xfrm states at the policy.
+    - xfrm: Add an inbound percpu state cache.
+    - xfrm: Don't disable preemption while looking up cache state.
+    - idpf: add read memory barrier when checking descriptor done bit
+    - net/ncsi: use dev_set_mac_address() for Get MC MAC Address handling
+    - tools: ynl: c: correct reverse decode of empty attrs
+    - selftests: mptcp: extend CFLAGS to keep options from environment
+    - selftests: net/{lib,openvswitch}: extend CFLAGS to keep options from
+      environment
+    - net: ethtool: only allow set_rxnfc with rss + ring_cookie if driver opts
+      in
+    - ethtool: Fix set RXNFC command with symmetric RSS hash
+    - tools/power turbostat: Fix forked child affinity regression
+    - md: add a new callback pers->bitmap_sector()
+    - md/raid5: implement pers->bitmap_sector()
+    - xfs: check for dead buffers in xfs_buf_find_insert
+    - xfs: don't shut down the filesystem for media failures beyond end of log
+    - usb: dwc3: Skip resume if pm_runtime_set_active() fails
+    - clk: qcom: gcc-x1e80100: Do not turn off usb_2 controller GDSC
+    - xfrm: Add error handling when nla_put_u32() returns an error
+    - xfrm: Fix acquire state insertion.
+    - ethtool: Fix access to uninitialized fields in set RXNFC command
+    - ASoC: da7213: Initialize the mutex
+    - drm/amd/display: Add hubp cache reset when powergating
+    - KVM: x86: Plumb in the vCPU to kvm_x86_ops.hwapic_isr_update()
+    - ethtool: ntuple: fix rss + ring_cookie check
+    - Upstream stable to v6.6.76, v6.12.13
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57975
+    - btrfs: do proper folio cleanup when run_delalloc_nocow() failed
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21714
+    - RDMA/mlx5: Fix implicit ODP use after free
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21801
+    - net: ravb: Fix missing rtnl lock in suspend/resume path
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21809
+    - rxrpc, afs: Fix peer hash locking vs RCU callback
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58057
+    - idpf: convert workqueues to unbound
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57953
+    - rtc: tps6594: Fix integer overflow on 32bit systems
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57982
+    - xfrm: state: fix out-of-bounds read during lookup
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21721
+    - nilfs2: handle errors that nilfs_prepare_chunk() may return
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21722
+    - nilfs2: do not force clear folio if buffer is referenced
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21798
+    - firewire: test: Fix potential null dereference in firewire kunit test
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21723
+    - scsi: mpi3mr: Fix possible crash when setting up bsg fails
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21724
+    - iommufd/iova_bitmap: Fix shift-out-of-bounds in
+      iova_bitmap_offset_to_index()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21825
+    - bpf: Cancel the running bpf_timer through kworker for PREEMPT_RT
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57990
+    - wifi: mt76: mt7925: fix off by one in mt7925_load_clc()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57974
+    - udp: Deal with race between UDP socket address change and rehash
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57994
+    - ptr_ring: do not block hard interrupts in ptr_ring_resize_multiple()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57999
+    - powerpc/pseries/iommu: IOMMU incorrectly marks MMIO range in DDW
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58054
+    - staging: media: max96712: fix kernel oops when removing module
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58055
+    - usb: gadget: f_tcm: Don't free command immediately
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57979
+    - pps: Fix a use-after-free
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57980
+    - media: uvcvideo: Fix double free in error path
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58056
+    - remoteproc: core: Fix ida_free call while not allocated
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21705
+    - mptcp: handle fastopen disconnect correctly
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21707
+    - mptcp: consolidate suboption status
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57981
+    - usb: xhci: Fix NULL pointer dereference on certain command aborts
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21708
+    - net: usb: rtl8150: enable basic endpoint checking
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21826
+    - netfilter: nf_tables: reject mismatching sum of field_len with set key
+      length
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21808
+    - net: xdp: Disallow attaching device-bound programs in generic mode
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21710
+    - tcp: correct handling of extreme memory squeeze
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21715
+    - net: davicom: fix UAF in dm9000_drv_remove
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21716
+    - vxlan: Fix uninit-value in vxlan_vnifilter_dump()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21718
+    - net: rose: fix timer races against user threads
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21719
+    - ipmr: do not call mr_mfc_uses_dev() for unres entries
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21802
+    - net: hns3: fix oops when unload drivers paralleling
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58058
+    - ubifs: skip dumping tnc tree when zroot is null
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58069
+    - rtc: pcf85063: fix potential OOB write in PCF85063 NVMEM read
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21720
+    - xfrm: delete intermediate secpath entry in packet offload mode
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21803
+    - LoongArch: Fix warnings during S3 suspend
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21810
+    - driver core: class: Fix wild pointer dereferences in API
+      class_dev_iter_next()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21811
+    - nilfs2: protect access to buffers with no active references
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21804
+    - PCI: rcar-ep: Fix incorrect variable used when calling
+      devm_request_mem_region()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21829
+    - RDMA/rxe: Fix the warning "__rxe_cleanup+0x12c/0x170 [rdma_rxe]"
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57984
+    - i3c: dw: Fix use-after-free in dw_i3c_master driver due to race
+      condition
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58034
+    - memory: tegra20-emc: fix an OF node reference bug in
+      tegra_emc_find_node_by_ram_code()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57973
+    - rdma/cxgb4: Prevent potential integer overflow on 32bit
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21725
+    - smb: client: fix oops due to unset link speed
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21726
+    - padata: avoid UAF for reorder_work
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21727
+    - padata: fix UAF in padata_reorder
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21728
+    - bpf: Send signals asynchronously if !preemptible
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58070
+    - bpf: bpf_local_storage: Always use bpf_mem_alloc in PREEMPT_RT
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21711
+    - net/rose: prevent integer overflows in rose_setsockopt()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21799
+    - net: ethernet: ti: am65-cpsw: fix freeing IRQ in
+      am65_cpsw_nuss_remove_tx_chns()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21806
+    - net: let net.core.dev_weight always be non-zero
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21830
+    - landlock: Handle weird files
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21828
+    - wifi: mac80211: don't flush non-uploaded STAs
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58061
+    - wifi: mac80211: prohibit deactivating all links
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57993
+    - HID: hid-thrustmaster: Fix warning in thrustmaster_probe by adding
+      endpoint check
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21812
+    - ax25: rcu protect dev->ax25_ptr
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58071
+    - team: prevent adding a device which is already a team device lower
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58063
+    - wifi: rtlwifi: fix memory leaks and invalid access at probe error path
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58072
+    - wifi: rtlwifi: remove unused check_buddy_priv
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58053
+    - rxrpc: Fix handling of received connection abort
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57996
+    - net_sched: sch_sfq: don't allow 1 packet limit
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57997
+    - wifi: wcn36xx: fix channel survey memory allocation size
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58051
+    - ipmi: ipmb: Add check devm_kasprintf() returned value
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58068
+    - OPP: fix dev_pm_opp_find_bw_*() when bandwidth table not initialized
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57998
+    - OPP: add index check to assert to avoid buffer overflow in _read_freq()
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-58052
+    - drm/amdgpu: Fix potential NULL pointer dereference in
+      atomctrl_get_smc_sclk_range_table
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2024-57986
+    - HID: core: Fix assumption that Resolution Multipliers must be in Logical
+      Collections
+  * Noble update: upstream stable patchset 2025-05-29 (LP: #2111953) //
+    CVE-2025-21731
+    - nbd: don't allow reconnect after disconnect
+  * CVE-2025-37798
+    - sch_htb: make htb_qlen_notify() idempotent
+    - sch_htb: make htb_deactivate() idempotent
+    - sch_drr: make drr_qlen_notify() idempotent
+    - sch_hfsc: make hfsc_qlen_notify() idempotent
+    - sch_qfq: make qfq_qlen_notify() idempotent
+    - sch_ets: make est_qlen_notify() idempotent
+    - codel: remove sch->q.qlen check before qdisc_tree_reduce_backlog()
+  * CVE-2025-37997
+    - netfilter: ipset: fix region locking in hash types
+  * CVE-2025-22088
+    - RDMA/erdma: Prevent use-after-free in erdma_accept_newconn()
+  * CVE-2025-37890
+    - net_sched: hfsc: Fix a UAF vulnerability in class with netem as child
+      qdisc
+    - sch_hfsc: Fix qlen accounting bug when using peek in hfsc_enqueue()
+    - net_sched: hfsc: Address reentrant enqueue adding class to eltree twice
+  * raid1: Fix NULL pointer dereference in process_checks() (LP: #2112519)
+    - md/raid1: Add check for missing source disk in process_checks()
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - [Packaging] update annotations scripts
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 23 Jul 2025 18:48:06 +0900
+
+linux-qcom (6.8.0-1050.50) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1050.50 -proposed tracker (LP: #2116573)
+
+  * Incorrect graphics dtbo file used in case of qcs5430-fp(2p5|3)-addons-
+    rb3gen2-vision-mezz-ovl.dtb
+    - SAUCE: fix graphics DTBO for qcs5430-{fp2p5,fp3}-addons-rb3gen2-vision-
+      mezz
+
+  * [linux-libc-dev-qcom] Requires smcinvoke.h for securemsm build
+    - SAUCE: include linux/smcinvoke.h in linux-libc-dev-qcom package
+
+  * [QC] Kernel crash from libgbm - followup
+    - QCLINUX: iommu/arm-smmu: qcom: Fix arm_smmu_domain usage in fault
+      handler
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 11 Jul 2025 20:30:43 +0900
+
+linux-qcom (6.8.0-1049.49) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1049.49 -proposed tracker (LP: #2116298)
+
+  * [RB3] miscellanea/check_prerelease test failed
+    - [Packaging] remove uefi_signed=true
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 10 Jul 2025 10:20:07 +0900
+
+linux-qcom (6.8.0-1048.48) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1048.48 -proposed tracker (LP: #2116048)
+
+  * [RB3] [x04] deadlock in cam_mem_mgr_cleanup_table
+    - SAUCE: camera_kt: fix double locking in cleanup function
+
+  * CONFIG_MMAP_MIN_ADDR should 32768
+    - UBUNTU [Config] set CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 07 Jul 2025 17:39:47 +0900
+
+linux-qcom (6.8.0-1047.47) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1047.47 -proposed tracker (LP: #2115413)
+
+  * [RB3] ucsi_glink.pmic_glink_ucsi pmic_glink.ucsi.0: PPM init failed, stop
+    trying
+    - SAUCE: usb: dwc3: make sure reset is deasserted before enabling clocks
+
+  * [RB8][x03] qcom-sa8775p-lpass-lpi-pinctrl errors found in dmesg
+    - QCLINUX: arm64: dts: qcom: update lpi-quad pin functions for qcs9075-rb8
+
+  * [qcom] Qcom kernel crashes in virtual machine
+    - SAUCE: gunyah_qcom: check qcom,msm-id property before HW access
+
+  * [5430][x03] SoC id not known by qcom/socinfo.c kernel driver Edit
+    - QCLINUX: soc: qcom: socinfo: add QCS5430 SoC ID
+    - QCLINUX: dt-bindings: arm: qcom,ids: add SoC ID for QCS5430
+
+  * [RB3] Enable sound-dais in our kernel for ALSA
+    - ASoC: qcom: topology: validate the max_op_port value
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 26 Jun 2025 21:07:26 +0900
+
+linux-qcom (6.8.0-1046.46) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1046.46 -proposed tracker (LP: #2114979)
+
+  * [qcom] Qcom kernel crashes in virtual machine
+    - SAUCE: gunyah_qcom: check qcom,msm-id property before HW access
+
+  * [RB3] Plugged USB storage is not detected via type-c port after reboot
+    occasionally
+    - soc: qcom: pmic_glink: Fix possible race between rpmsg and pmicglink
+      probe
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 19 Jun 2025 22:04:02 +0900
+
+linux-qcom (6.8.0-1045.45) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1045.45 -proposed tracker (LP: #2114901)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update Ubuntu.md
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Config] add FLAVOUR_DEP
+    - [package] fix Vcs-Git
+    - SAUCE: arm64: dts: qcm6490: enable platform sound-dai
+    - SAUCE: ASoC: q6dsp: increase AR_MAX_MOD_LINKS
+    - SAUCE: arm64: dts: qcom fix interrupts arguments
+    - SAUCE: usb: dwc3: do not call dwc3_remove() when dwc3_qcom_probe_core()
+      fails
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 18 Jun 2025 23:42:59 +0900
+
+linux-qcom (6.8.0-1043.43) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1043.43 -proposed tracker (LP: #2112456)
+
+  * [5430] thermal_sys failed to bind errors found in dmesg
+    - SAUCE: comment out invalid cooling-maps
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs
+
+  [ Ubuntu: 6.8.0-62.65 ]
+
+  * noble/linux: 6.8.0-62.65 -proposed tracker (LP: #2110737)
+  * Rotate the Canonical Livepatch key (LP: #2111244)
+    - [Config] Prepare for Canonical Livepatch key rotation
+  * KVM bug causes Firecracker crash when it runs the vCPU for the first time
+    (LP: #2109859)
+    - vhost: return task creation error instead of NULL
+    - kvm: retry nx_huge_page_recovery_thread creation
+  * CVE-2025-2312 cifs.upcall could access incorrect kerberos credentials cache
+    (LP: #2099914) // CVE-2025-2312
+    - CIFS: New mount option for cifs.upcall namespace resolution
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640)
+    - ASoC: wm8994: Add depends on MFD core
+    - ASoC: samsung: Add missing selects for MFD_WM8994
+    - seccomp: Stub for !CONFIG_SECCOMP
+    - scsi: iscsi: Fix redundant response for ISCSI_UEVENT_GET_HOST_STATS request
+    - of/unittest: Add test that of_address_to_resource() fails on non-
+      translatable address
+    - irqchip/sunxi-nmi: Add missing SKIP_WAKE flag
+    - hwmon: (drivetemp) Set scsi command timeout to 10s
+    - ASoC: samsung: Add missing depends on I2C
+    - ata: libata-core: Set ATA_QCFLAG_RTF_FILLED in fill_result_tf()
+    - Revert "libfs: fix infinite directory reads for offset dir"
+    - libfs: Replace simple_offset end-of-directory detection
+    - Revert "HID: multitouch: Add support for lenovo Y9000P Touchpad"
+    - ALSA: usb-audio: Add delay quirk for USB Audio Device
+    - Input: xpad - add support for Nacon Pro Compact
+    - Input: atkbd - map F23 key to support default copilot shortcut
+    - Input: xpad - add unofficial Xbox 360 wireless receiver clone
+    - Input: xpad - add QH Electronics VID/PID
+    - Input: xpad - improve name of 8BitDo controller 2dc8:3106
+    - Input: xpad - add support for Nacon Evol-X Xbox One Controller
+    - Input: xpad - add support for wooting two he (arm)
+    - ASoC: codecs: es8316: Fix HW rate calculation for 48Mhz MCLK
+    - ASoC: cs42l43: Add codec force suspend/resume ops
+    - ALSA: hda/realtek: Fix volume adjustment issue on Lenovo ThinkBook 16P Gen5
+    - libfs: Return ENOSPC when the directory offset range is exhausted
+    - Revert "libfs: Add simple_offset_empty()"
+    - libfs: Use d_children list to iterate simple_offset directories
+    - wifi: rtl8xxxu: add more missing rtl8192cu USB IDs
+    - HID: wacom: Initialize brightness of LED trigger
+    - Upstream stable to v6.6.75, v6.12.12
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21689
+    - USB: serial: quatech2: fix null-ptr-deref in qt2_process_read_urb()
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21690
+    - scsi: storvsc: Ratelimit warning logs to prevent VM denial of service
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21691
+    - cachestat: fix page cache statistics permission checking
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21692
+    - net: sched: fix ets qdisc OOB Indexing
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2025-21699
+    - gfs2: Truncate address space when flipping GFS2_DIF_JDATA flag
+  * Noble update: upstream stable patchset 2025-04-29 (LP: #2109640) //
+    CVE-2024-50157
+    - RDMA/bnxt_re: Avoid CPU lockups due fifo occupancy check loop
+  * rtw89: Support hardware rfkill (LP: #2077384)
+    - wifi: rtw89: add support for hardware rfkill
+  * Introduce configfs-based interface for gpio-aggregator (LP: #2103496)
+    - gpio: introduce utilities for synchronous fake device creation
+    - bitmap: Define a cleanup function for bitmaps
+    - gpio: aggregator: simplify aggr_parse() with scoped bitmap
+    - gpio: aggregator: protect driver attr handlers against module unload
+    - gpio: aggregator: reorder functions to prepare for configfs introduction
+    - gpio: aggregator: unify function naming
+    - gpio: aggregator: add gpio_aggregator_{alloc, free}()
+    - gpio: aggregator: introduce basic configfs interface
+    - [Config] Enable DEV_SYNC_PROBE as module
+    - SAUCE: gpio: aggregator: Fix error code in gpio_aggregator_activate()
+    - gpio: aggregator: rename 'name' to 'key' in gpio_aggregator_parse()
+    - gpio: aggregator: expose aggregator created via legacy sysfs to configfs
+    - SAUCE: gpio: aggregator: fix "_sysfs" prefix check in
+      gpio_aggregator_make_group()
+    - SAUCE: gpio: aggregator: Fix gpio_aggregator_line_alloc() checking
+    - SAUCE: gpio: aggregator: Return an error if there are no GPIOs in
+      gpio_aggregator_parse()
+    - SAUCE: gpio: aggregator: Fix leak in gpio_aggregator_parse()
+    - gpio: aggregator: cancel deferred probe for devices created via configfs
+    - Documentation: gpio: document configfs interface for gpio-aggregator
+    - selftests: gpio: add test cases for gpio-aggregator
+    - SAUCE: selftests: gpio: gpio-aggregator: add a test case for _sysfs prefix
+      reservation
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449)
+    - net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()
+    - net: add exit_batch_rtnl() method
+    - gtp: use exit_batch_rtnl() method
+    - gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp().
+    - gtp: Suppress list corruption splat in gtp_net_exit_batch_rtnl().
+    - nfp: bpf: prevent integer overflow in nfp_bpf_event_output()
+    - net: xilinx: axienet: Fix IRQ coalescing packet count overflow
+    - net/mlx5: Fix RDMA TX steering prio
+    - net/mlx5e: Rely on reqid in IPsec tunnel mode
+    - net/mlx5e: Always start IPsec sequence number from 1
+    - drm/vmwgfx: Add new keep_resv BO param
+    - drm/v3d: Assign job pointer to NULL before signaling the fence
+    - soc: ti: pruss: Fix pruss APIs
+    - hwmon: (tmp513) Fix division of negative numbers
+    - i2c: mux: demux-pinctrl: check initial mux selection, too
+    - i2c: rcar: fix NACK handling when being a target
+    - hfs: Sanity check the root record
+    - fs: fix missing declaration of init_files
+    - kheaders: Ignore silly-rename files
+    - cachefiles: Parse the "secctx" immediately
+    - scsi: ufs: core: Honor runtime/system PM levels if set by host controller
+      drivers
+    - selftests: tc-testing: reduce rshift value
+    - ACPI: resource: acpi_dev_irq_override(): Check DMI match last
+    - poll_wait: add mb() to fix theoretical race between waitqueue_active() and
+      .poll()
+    - RDMA/bnxt_re: Fix to export port num to ib_query_qp
+    - nvmet: propagate npwg topology
+    - ALSA: hda/realtek: Add support for Ayaneo System using CS35L41 HDA
+    - i2c: atr: Fix client detach
+    - mptcp: be sure to send ack when mptcp-level window re-opens
+    - mptcp: fix spurious wake-up on under memory pressure
+    - selftests: mptcp: avoid spurious errors on disconnect
+    - net: ethernet: xgbe: re-add aneg to supported features in PHY quirks
+    - vsock/virtio: cancel close work in the destructor
+    - vsock: reset socket state when de-assigning the transport
+    - nouveau/fence: handle cross device fences properly
+    - irqchip: Plug a OF node reference leak in platform_irqchip_probe()
+    - irqchip/gic-v3: Handle CPU_PM_ENTER_FAILED correctly
+    - drm/i915/fb: Relax clear color alignment to 64 bytes
+    - drm/amdgpu: always sync the GFX pipe on ctx switch
+    - ocfs2: fix deadlock in ocfs2_get_system_file_inode
+    - nfsd: add list_head nf_gc to struct nfsd_file
+    - x86/xen: fix SLS mitigation in xen_hypercall_iret()
+    - efi/zboot: Limit compression options to GZIP and ZSTD
+    - [Config] updateconfigs for HAVE_KERNEL_(LZ4|LZMA|LZO|XZ)
+    - net: ravb: Fix max TX frame size for RZ/V2M
+    - net/mlx5: SF, Fix add port error handling
+    - drm/vmwgfx: Unreserve BO on error
+    - i2c: testunit: on errors, repeat NACK until STOP
+    - hwmon: (ltc2991) Fix mixed signed/unsigned in DIV_ROUND_CLOSEST
+    - fs/qnx6: Fix building with GCC 15
+    - gpio: sim: lock up configfs that an instantiated device depends on
+    - gpio: sim: lock hog configfs items if present
+    - platform/x86: ISST: Add Clearwater Forest to support list
+    - drm/nouveau/disp: Fix missing backlight control on Macbook 5,1
+    - net/ncsi: fix locking in Get MAC Address handling
+    - drm/amd/display: Do not elevate mem_type change to full update
+    - drm/xe: Mark ComputeCS read mode as UC on iGPU
+    - drm/amdgpu/smu13: update powersave optimizations
+    - drm/amdgpu: fix fw attestation for MP0_14_0_{2/3}
+    - drm/amdgpu: disable gfxoff with the compute workload on gfx12
+    - drm/amd/display: Fix PSR-SU not support but still call the
+      amdgpu_dm_psr_enable
+    - Upstream stable to v6.6.73, v6.6.74, v6.12.11
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21672
+    - afs: Fix merge preference rule failure condition
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21682
+    - eth: bnxt: always recalculate features after XDP clearing, fix null-deref
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-53124
+    - net: fix data-races around sk->sk_forward_alloc
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-57924
+    - fs: relax assertions on failure to encode file handles
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-57951
+    - hrtimers: Handle CPU state correctly on hotplug
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-57949
+    - irqchip/gic-v3-its: Don't enable interrupts in its_irq_set_vcpu_affinity()
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21668
+    - pmdomain: imx8mp-blk-ctrl: add missing loop break condition
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21684
+    - gpio: xilinx: Convert gpio_lock to raw spinlock
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21694
+    - fs/proc: fix softlockup in __read_vmcore (part 2)
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21665
+    - filemap: avoid truncating 64-bit offset to 32 bits
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21666
+    - vsock: prevent null-ptr-deref in vsock_*[has_data|has_space]
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21669
+    - vsock/virtio: discard packets if the transport changes
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21670
+    - vsock/bpf: return early if transport is not assigned
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21667
+    - iomap: avoid avoid truncating 64-bit offset to 32 bits
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2024-57948
+    - mac802154: check local interfaces before deleting sdata list
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21673
+    - smb: client: fix double free of TCP_Server_Info::hostname
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21697
+    - drm/v3d: Ensure job pointer is set to NULL after job completion
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21674
+    - net/mlx5e: Fix inversion dependency warning while enabling IPsec tunnel
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21675
+    - net/mlx5: Clear port select structure when fail to create
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21676
+    - net: fec: handle page_pool_dev_alloc_pages error
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21678
+    - gtp: Destroy device along with udp socket's netns dismantle.
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21680
+    - pktgen: Avoid out-of-bounds access in get_imix_entries
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21681
+    - openvswitch: fix lockup on tx to unregistering netdev with carrier
+  * Noble update: upstream stable patchset 2025-04-16 (LP: #2107449) //
+    CVE-2025-21683
+    - bpf: Fix bpf_sk_select_reuseport() memory leak
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update annotations scripts
+
+  [ Ubuntu: 6.8.0-60.63 ]
+
+  * noble/linux: 6.8.0-60.63 -proposed tracker (LP: #2107138)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2025.04.14)
+  * Missing upstream commits for LP: #2102181 (LP: #2107336)
+    - libperf cpumap: Add any, empty and min helpers
+    - libperf cpumap: Ensure empty cpumap is NULL from alloc
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770)
+    - memblock: use numa_valid_node() helper to check for invalid node ID
+    - jbd2: increase IO priority for writing revoke records
+    - jbd2: flush filesystem device before updating tail sequence
+    - dm array: fix unreleased btree blocks on closing a faulty array cursor
+    - dm array: fix cursor index when skipping across block boundaries
+    - exfat: fix the infinite loop in __exfat_free_cluster()
+    - erofs: fix PSI memstall accounting
+    - ASoC: rt722: add delay time to wait for the calibration procedure
+    - ASoC: mediatek: disable buffer pre-allocation
+    - selftests/alsa: Fix circular dependency involving global-timer
+    - ieee802154: ca8210: Add missing check for kfifo_alloc() in ca8210_probe()
+    - net: 802: LLC+SNAP OID:PID lookup on start of skb data
+    - tcp/dccp: complete lockless accesses to sk->sk_max_ack_backlog
+    - tcp/dccp: allow a connection when sk_max_ack_backlog is zero
+    - net: libwx: fix firmware mailbox abnormal return
+    - pds_core: limit loop over fw name list
+    - bnxt_en: Fix possible memory leak when hwrm_req_replace fails
+    - cxgb4: Avoid removal of uninserted tid
+    - ice: fix incorrect PHY settings for 100 GB/s
+    - igc: return early when failing to read EECD register
+    - tls: Fix tls_sw_sendmsg error handling
+    - eth: gve: use appropriate helper to set xdp_features
+    - Bluetooth: hci_sync: Fix not setting Random Address when required
+    - Bluetooth: MGMT: Fix Add Device to responding before completing
+    - Bluetooth: btnxpuart: Fix driver sending truncated data
+    - tcp: Annotate data-race around sk->sk_mark in tcp_v4_send_reset
+    - riscv: Fix early ftrace nop patching
+    - memblock tests: fix implicit declaration of function 'numa_valid_node'
+    - iio: imu: inv_icm42600: fix timestamps after suspend if sensor is on
+    - netfilter: nf_tables: imbalance in flowtable binding
+    - drm/mediatek: stop selecting foreign drivers
+    - [Config] updateconfigs for MTK_SMI
+    - drm/mediatek: Fix YCbCr422 color format issue for DP
+    - drm/mediatek: Fix mode valid issue for dp
+    - drm/mediatek: Add return value check when reading DPCD
+    - cpuidle: riscv-sbi: fix device node release in early exit of
+      for_each_possible_cpu
+    - scsi: ufs: qcom: Power off the PHY if it was already powered on in
+      ufs_qcom_power_up_sequence()
+    - dm-ebs: don't set the flag DM_TARGET_PASSES_INTEGRITY
+    - ksmbd: Implement new SMB3 POSIX type
+    - thermal: of: fix OF node leak in of_thermal_zone_find()
+    - smb: client: sync the root session and superblock context passwords before
+      automounting
+    - ACPI: resource: Add TongFang GM5HG0A to irq1_edge_low_force_override[]
+    - ACPI: resource: Add Asus Vivobook X1504VAP to irq1_level_low_skip_override[]
+    - drm/amd/display: increase MAX_SURFACES to the value supported by hw
+    - io_uring/timeout: fix multishot updates
+    - dm-verity FEC: Fix RS FEC repair for roots unaligned to block size (take 2)
+    - USB: serial: option: add MeiG Smart SRM815
+    - USB: serial: option: add Neoway N723-EA support
+    - staging: iio: ad9834: Correct phase range check
+    - staging: iio: ad9832: Correct phase range check
+    - usb-storage: Add max sectors quirk for Nokia 208
+    - USB: serial: cp210x: add Phoenix Contact UPS Device
+    - usb: dwc3: gadget: fix writing NYET threshold
+    - misc: microchip: pci1xxxx: Resolve return code mismatch during GPIO set
+      config
+    - tty: serial: 8250: Fix another runtime PM usage counter underflow
+    - usb: dwc3-am62: Disable autosuspend during remove
+    - USB: usblp: return error when setting unsupported protocol
+    - USB: core: Disable LPM only for non-suspended ports
+    - usb: fix reference leak in usb_new_device()
+    - usb: gadget: midi2: Reverse-select at the right place
+    - usb: chipidea: ci_hdrc_imx: decrement device's refcount in .remove() and in
+      the error path of .probe()
+    - usb: gadget: f_uac2: Fix incorrect setting of bNumEndpoints
+    - usb: typec: tcpm/tcpci_maxim: fix error code in
+      max_contaminant_read_resistance_kohm()
+    - usb: gadget: configfs: Ignore trailing LF for user strings to cdev
+    - iio: gyro: fxas21002c: Fix missing data update in trigger handler
+    - iio: adc: ti-ads124s08: Use gpiod_set_value_cansleep()
+    - iio: inkern: call iio_device_put() only on mapped devices
+    - iio: adc: ad7124: Disable all channels at probe time
+    - riscv: kprobes: Fix incorrect address calculation
+    - ARM: dts: imxrt1050: Fix clocks for mmc
+    - arm64: dts: rockchip: add hevc power domain clock to rk3328
+    - pmdomain: imx: gpcv2: Simplify with scoped for each OF child loop
+    - pmdomain: imx: gpcv2: fix an OF node reference leak in imx_gpcv2_probe()
+    - workqueue: Add rcu lock check at the end of work item execution
+    - workqueue: Update lock debugging code
+    - mm/hugetlb: enforce that PMD PT sharing has split PMD PT locks
+    - riscv: Fix text patching when IPI are used
+    - drm/mediatek: Only touch DISP_REG_OVL_PITCH_MSB if AFBC is supported
+    - ovl: pass realinode to ovl_encode_real_fh() instead of realdentry
+    - net: don't dump Tx and uninitialized NAPIs
+    - ice: fix max values for dpll pin phase adjust
+    - net: hns3: fixed reset failure issues caused by the incorrect reset type
+    - net: hns3: fix missing features due to dev->features configuration too early
+    - net: hns3: Resolved the issue that the debugfs query result is inconsistent.
+    - net: hns3: initialize reset_timer before hclgevf_misc_irq_init()
+    - mctp i3c: fix MCTP I3C driver multi-thread issue
+    - drm/mediatek: Move mtk_crtc_finish_page_flip() to ddp_cmdq_cb()
+    - drm/mediatek: Add support for 180-degree rotation in the display driver
+    - drm/mediatek: mtk_dsi: Add registers to pdata to fix MT8186/MT8188
+    - platform/x86: intel/pmc: Fix ioremap() of bad address
+    - riscv: module: remove relocation_head rel_entry member allocation
+    - cgroup/cpuset: Prevent leakage of isolated CPUs into sched domains
+    - fs: kill MNT_ONRB
+    - gpio: loongson: Fix Loongson-2K2000 ACPI GPIO register offset
+    - drm/amd/pm: fix BUG: scheduling while atomic
+    - drm/amdkfd: wq_release signals dma_fence only when available
+    - drm/amd/display: fix divide error in DM plane scale calcs
+    - drm/amd/display: fix page fault due to max surface definition mismatch
+    - serial: stm32: use port lock wrappers for break control
+    - usb: host: xhci-plat: set skip_phy_initialization if software node has
+      XHCI_SKIP_PHY_INIT property
+    - iio: imu: inv_icm42600: add register caching in the regmap
+    - iio: imu: inv_icm42600: fix spi burst write not supported
+    - Upstream stable to v6.6.71, v6.6.72, v6.12.10
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21659
+    - netdev: prevent accessing NAPI instances from another namespace
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21634
+    - cgroup/cpuset: remove kernfs active break
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21635
+    - rds: sysctl: rds_tcp_{rcv,snd}buf: avoid using current->nsproxy
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21643
+    - netfs: Fix kernel async DIO
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21649
+    - net: hns3: fix kernel crash when 1588 is sent on HIP08 devices
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21650
+    - net: hns3: fixed hclge_fetch_pf_reg accesses bar space out of bounds issue
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21651
+    - net: hns3: don't auto enable misc vector
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21654
+    - ovl: support encoding fid from inode with no alias
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57883
+    - mm: hugetlb: independent PMD page table shared count
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57888
+    - workqueue: Do not warn when cancelling WQ_MEM_RECLAIM work from
+      !WQ_MEM_RECLAIM worker
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21631
+    - block, bfq: fix waker_bfqq UAF after bfq_split_bfqq()
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21656
+    - hwmon: (drivetemp) Fix driver producing garbage data when SCSI errors occur
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21655
+    - io_uring/eventfd: ensure io_eventfd_signal() defers another RCU period
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57904
+    - iio: adc: at91: call input_free_device() on allocated iio_dev
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57906
+    - iio: adc: ti-ads8688: fix information leak in triggered buffer
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57907
+    - iio: adc: rockchip_saradc: fix information leak in triggered buffer
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57908
+    - iio: imu: kmx61: fix information leak in triggered buffer
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57910
+    - iio: light: vcnl4035: fix information leak in triggered buffer
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57911
+    - iio: dummy: iio_simply_dummy_buffer: fix information leak in triggered
+      buffer
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57912
+    - iio: pressure: zpa2326: fix information leak in triggered buffer
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57913
+    - usb: gadget: f_fs: Remove WARN_ON in functionfs_bind
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21632
+    - x86/fpu: Ensure shadow stack is active before "getting" registers
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57916
+    - misc: microchip: pci1xxxx: Resolve kernel panic during GPIO IRQ handling
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57917
+    - topology: Keep the cpumask unchanged when printing cpumap
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57939
+    - riscv: Fix sleeping in invalid context in die()
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21636
+    - sctp: sysctl: plpmtud_probe_interval: avoid using current->nsproxy
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21637
+    - sctp: sysctl: udp_port: avoid using current->nsproxy
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21638
+    - sctp: sysctl: auth_enable: avoid using current->nsproxy
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21639
+    - sctp: sysctl: rto_min/max: avoid using current->nsproxy
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21640
+    - sctp: sysctl: cookie_hmac_alg: avoid using current->nsproxy
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21642
+    - mptcp: sysctl: sched: avoid using current->nsproxy
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21664
+    - dm thin: make get_first_thin use rcu-safe list first function
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57945
+    - riscv: mm: Fix the out of bound issue of vmemmap address
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21660
+    - ksmbd: fix unexpectedly changed path in ksmbd_vfs_kern_path_locked
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21645
+    - platform/x86/amd/pmc: Only disable IRQ1 wakeup where i8042 actually enabled
+      it
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21646
+    - afs: Fix the maximum cell name length
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57925
+    - ksmbd: fix a missing return value check bug
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57926
+    - drm/mediatek: Set private->all_drm_private[i]->drm to NULL if mtk_drm_bind
+      returns err
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21662
+    - net/mlx5: Fix variable not being completed when function returns
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21663
+    - net: stmmac: dwmac-tegra: Read iommu stream id from device tree
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21647
+    - sched: sch_cake: add bounds checks to host bulk flow fairness counts
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21648
+    - netfilter: conntrack: clamp maximum hashtable size to INT_MAX
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21652
+    - ipvlan: Fix use-after-free in ipvlan_get_iflink().
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21658
+    - btrfs: avoid NULL pointer dereference if no valid extent tree
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2025-21653
+    - net_sched: cls_flow: validate TCA_FLOW_RSHIFT attribute
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-47736
+    - erofs: handle overlapped pclusters out of crafted images properly
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57940
+    - exfat: fix the infinite loop in exfat_readdir()
+  * Noble update: upstream stable patchset 2025-04-10 (LP: #2106770) //
+    CVE-2024-57929
+    - dm array: fix releasing a faulty array block twice in dm_array_cursor_end
+  * intel_idle: add Granite Rapids Xeon (D) support (LP: #2106638)
+    - intel_idle: add Granite Rapids Xeon support
+    - intel_idle: add Granite Rapids Xeon D support
+  * [SRU] Enable speaker/mic mute LEDs on Lenovo ideapad and thinkbook
+    (LP: #2106449)
+    - ALSA: hda: Support for Ideapad hotkey mute LEDs
+    - platform/x86:lenovo-wmi-hotkey-utilities.c: Support for mic and audio mute
+      LEDs
+    - [Config] Enable Lenovo wmi hotkey driver
+  * Backport "PCI: Wait for device readiness with Configuration RRS" to N/O
+    (LP: #2106251)
+    - PCI: Wait for device readiness with Configuration RRS
+    - PCI: Avoid FLR for Mediatek MT7922 WiFi
+  * Enable OOB P-state control for Intel Sierra Forest/Granite Rapids
+    (LP: #2106275)
+    - cpufreq: intel_pstate: Support Granite Rapids and Sierra Forest OOB mode
+  * mptcp BUG 'scheduling while atomic' in mptcp_pm_nl_append_new_local_addr
+    (LP: #2101120)
+    - mptcp: fix 'scheduling while atomic' in mptcp_pm_nl_append_new_local_addr
+  * CVE-2025-21971
+    - net_sched: Prevent creation of classes with TC_H_ROOT
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632)
+    - smb/client: rename cifs_ntsd to smb_ntsd
+    - smb/client: rename cifs_sid to smb_sid
+    - smb/client: rename cifs_acl to smb_acl
+    - smb/client: rename cifs_ace to smb_ace
+    - fs/smb/client: implement chmod() for SMB3 POSIX Extensions
+    - smb: client: stop flooding dmesg in smb2_calc_signature()
+    - media: uvcvideo: Force UVC version to 1.0a for 0408:4033
+    - Bluetooth: btusb: Add new VID/PID 13d3/3602 for MT7925
+    - watchdog: rzg2l_wdt: Remove reset de-assert from probe
+    - watchdog: rzg2l_wdt: Rely on the reset driver for doing proper reset
+    - watchdog: rzg2l_wdt: Power on the watchdog domain in the restart handler
+    - ALSA: ump: Use guard() for locking
+    - ALSA: ump: Don't open legacy substream for an inactive group
+    - scsi: mpi3mr: Use ida to manage mrioc ID
+    - scsi: mpi3mr: Start controller indexing from 0
+    - ACPI/IORT: Add PMCG platform information for HiSilicon HIP10/11
+    - ACPI/IORT: Add PMCG platform information for HiSilicon HIP09A
+    - x86/ptrace: Cleanup the definition of the pt_regs structure
+    - x86/ptrace: Add FRED additional information to the pt_regs structure
+    - Bluetooth: btusb: add callback function in btusb suspend/resume
+    - Bluetooth: btusb: mediatek: add callback function in btusb_disconnect
+    - platform/x86: mlx-platform: call pci_dev_put() to balance the refcount
+    - mmc: sdhci-msm: fix crypto key eviction
+    - tracing: Handle old buffer mappings for event strings and functions
+    - tracing: Fix trace_check_vprintf() when tp_printk is used
+    - tracing: Check "%s" dereference via the field and not the TP_printk format
+    - RDMA/bnxt_re: Allow MSN table capability check
+    - RDMA/bnxt_re: Remove always true dattr validity check
+    - RDMA/mlx5: Enforce same type port association for multiport RoCE
+    - RDMA/bnxt_re: Avoid initializing the software queue for user queues
+    - RDMA/bnxt_re: Avoid sending the modify QP workaround for latest adapters
+    - nvme-pci: 512 byte aligned dma pool segment quirk
+    - RDMA/bnxt_re: Fix the check for 9060 condition
+    - RDMA/bnxt_re: Add check for path mtu in modify_qp
+    - RDMA/bnxt_re: Fix reporting hw_ver in query_device
+    - RDMA/bnxt_re: Fix max_qp_wrs reported
+    - RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters
+    - RDMA/bnxt_re: Disable use of reserved wqes
+    - RDMA/bnxt_re: Add send queue size check for variable wqe
+    - RDMA/bnxt_re: Fix MSN table size for variable wqe mode
+    - drm/bridge: adv7511_audio: Update Audio InfoFrame properly
+    - net: dsa: microchip: Fix KSZ9477 set_ageing_time function
+    - net: dsa: microchip: Fix LAN937X set_ageing_time function
+    - RDMA/hns: Refactor mtr find
+    - RDMA/hns: Remove unused parameters and variables
+    - RDMA/hns: Fix mapping error of zero-hop WQE buffer
+    - RDMA/hns: Fix warning storm caused by invalid input in IO path
+    - RDMA/hns: Fix missing flush CQE for DWQE
+    - ip_tunnel: annotate data-races around t->parms.link
+    - ipv4: ip_tunnel: Unmask upper DSCP bits in ip_tunnel_bind_dev()
+    - ipv4: ip_tunnel: Unmask upper DSCP bits in ip_md_tunnel_xmit()
+    - ipv4: ip_tunnel: Unmask upper DSCP bits in ip_tunnel_xmit()
+    - net: Fix netns for ip_tunnel_init_flow()
+    - net/mlx5: DR, select MSIX vector 0 for completion queue creation
+    - net/mlx5e: macsec: Maintain TX SA from encoding_sa
+    - drm/i915/dg1: Fix power gate sequence.
+    - net: llc: reset skb->transport_header
+    - ALSA: usb-audio: US16x08: Initialize array before use
+    - eth: bcmsysport: fix call balance of priv->clk handling routines
+    - net: mv643xx_eth: fix an OF node reference leak
+    - net: sfc: Correct key_len for efx_tc_ct_zone_ht_params
+    - net: wwan: iosm: Properly check for valid exec stage in ipc_mmio_init()
+    - net: ti: icssg-prueth: Fix clearing of IEP_CMP_CFG registers during iep_init
+    - wifi: mac80211: wake the queues in case of failure in resume
+    - ALSA: hda/ca0132: Use standard HD-audio quirk matching helpers
+    - ALSA: hda/realtek: Add new alc2xx-fixup-headset-mic model
+    - sound: usb: enable DSD output for ddHiFi TC44C
+    - sound: usb: format: don't warn that raw DSD is unsupported
+    - bpf: fix potential error return
+    - ksmbd: retry iterate_dir in smb2_query_dir
+    - smb: client: destroy cfid_put_wq on module exit
+    - net: usb: qmi_wwan: add Telit FE910C04 compositions
+    - irqchip/gic: Correct declaration of *percpu_base pointer in union gic_base
+    - ARC: build: Try to guess GCC variant of cross compiler
+    - RDMA/bnxt_re: Fix the max WQE size for static WQE support
+    - modpost: fix input MODULE_DEVICE_TABLE() built for 64-bit on 32-bit host
+    - modpost: fix the missed iteration for the max bit in do_input()
+    - ALSA: seq: Check UMP support for midi_version change
+    - ALSA hda/realtek: Add quirk for Framework F111:000C
+    - kcov: mark in_softirq_really() as __always_inline
+    - scripts/sorttable: fix orc_sort_cmp() to maintain symmetry and transitivity
+    - sky2: Add device ID 11ab:4373 for Marvell 88E8075
+    - drm: adv7511: Drop dsi single lane support
+    - dt-bindings: display: adi,adv7533: Drop single lane support
+    - fs/proc/task_mmu: fix pagemap flags with PMD THP entries on 32bit
+    - mm/readahead: fix large folio support in async readahead
+    - mptcp: fix recvbuffer adjust on sleeping rcvmsg
+    - mptcp: don't always assume copied data in mptcp_cleanup_rbuf()
+    - RDMA/bnxt_re: Fix max SGEs for the Work Request
+    - scsi: hisi_sas: Remove redundant checks for automatic debugfs dump
+    - platform/x86: hp-wmi: Add thermal profile support for 8BAD boards
+    - platform/x86: hp-wmi: Fix platform profile option switch bug on Omen and
+      Victus laptops
+    - platform/x86: hp-wmi: Fix implementation of the platform_profile_omen_get
+      function
+    - platform/x86: hp-wmi: mark 8A15 board for timed OMEN thermal profile
+    - RDMA/core: Fix ENODEV error for iWARP test over vlan
+    - net: phy: micrel: Dynamically control external clock of KSZ PHY
+    - netdev-genl: avoid empty messages in napi get
+    - net: stmmac: restructure the error path of stmmac_probe_config_dt()
+    - net/mlx5e: Fix netif state handling
+    - net/mlx5e: Keep netdev when leave switchdev for devlink set legacy only
+    - drm/i915/cx0_phy: Fix C10 pll programming sequence
+    - RDMA/bnxt_re: Fix error recovery sequence
+    - btrfs: allow swap activation to be interruptible
+    - perf/x86/intel: Add Arrow Lake U support
+    - ALSA: hda: cs35l56: Remove calls to
+      cs35l56_force_sync_asp1_registers_from_cache()
+    - ALSA: hda/realtek - Add support for ASUS Zen AIO 27 Z272SD_A272SD audio
+    - spi: spi-cadence-qspi: Disable STIG mode for Altera SoCFPGA.
+    - ARC: build: disallow invalid PAE40 + 4K page config
+    - bpf: refactor bpf_helper_changes_pkt_data to use helper number
+    - bpf: consider that tail calls invalidate packet pointers
+    - maple_tree: reload mas before the second call for mas_empty_area
+    - io_uring/rw: fix downgraded mshot read
+    - wifi: iwlwifi: mvm: Fix __counted_by usage in cfg80211_wowlan_nd_*
+    - net: ethernet: ti: am65-cpsw: default to round-robin for host port receive
+    - gve: process XSK TX descriptors as part of RX NAPI
+    - gve: trigger RX NAPI instead of TX NAPI in gve_xsk_wakeup
+    - mm: reinstate ability to map write-sealed memfd mappings read-only
+    - Upstream stable to v6.6.70, v6.12.9
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57898
+    - wifi: cfg80211: clear link ID from bitmap during link delete after clean up
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57882
+    - mptcp: fix TCP options overflow.
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57884
+    - mm: vmscan: account for free pages to prevent infinite Loop in
+      throttle_direct_reclaim()
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57885
+    - mm/kmemleak: fix sleeping function called from invalid context at print
+      message
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57932
+    - gve: guard XDP xmit NDO on existence of xdp queues
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57933
+    - gve: guard XSK operations on the existence of queues
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57887
+    - drm: adv7511: Fix use-after-free in adv7533_attach_dsi()
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57938
+    - net/sctp: Prevent autoclose integer overflow in sctp_association_init()
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57889
+    - pinctrl: mcp23s08: Fix sleeping in atomic context due to regmap locking
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57890
+    - RDMA/uverbs: Prevent integer overflow issue
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57892
+    - ocfs2: fix slab-use-after-free due to dangling pointer dqi_priv
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57893
+    - ALSA: seq: oss: Fix races at processing SysEx messages
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57895
+    - ksmbd: set ATTR_CTIME flags when setting mtime
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57896
+    - btrfs: flush delalloc workers queue before stopping cleaner kthread during
+      unmount
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57897
+    - drm/amdkfd: Correct the migration DMA map direction
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57899
+    - wifi: mac80211: fix mbss changed flags corruption on 32 bit systems
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57900
+    - ila: serialize calls to nf_register_net_hooks()
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57901
+    - af_packet: fix vlan_get_protocol_dgram() vs MSG_PEEK
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57902
+    - af_packet: fix vlan_get_tci() vs MSG_PEEK
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57903
+    - net: restrict SO_REUSEPORT to inet sockets
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-36476
+    - RDMA/rtrs: Ensure 'ib_sge list' is accessible
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-39282
+    - net: wwan: t7xx: Fix FSM command timeout issue
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57801
+    - net/mlx5e: Skip restore TC rules for vport rep without loaded flag
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57802
+    - netrom: check buffer length before accessing it
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57841
+    - net: fix memory leak in tcp_conn_request()
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-57931
+    - selinux: ignore unknown extended permissions
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-56761
+    - x86/fred: Clear WFE in missing-ENDBRANCH #CPs
+  * Noble update: upstream stable patchset 2025-04-09 (LP: #2106632) //
+    CVE-2024-53179
+    - smb: client: fix use-after-free of signing key
+  * uprobe-related panics during profiling (LP: #2104210)
+    - uprobes: Fix race in uprobe_free_utask
+  * ubuntu_bpf failed to build on Noble / Oracular (LP: #2069407)
+    - selftests/bpf: Fix compilation failure when CONFIG_NET_FOU!=y
+  * nfsd hangs and never recovers after NFS4ERR_DELAY and a connection loss
+    (LP: #2103564)
+    - NFSD: Reset cb_seq_status after NFS4ERR_DELAY
+  * thermal: Fix temperature readings on intel hardware (LP: #2103427)
+    - thermal: intel: intel_tcc: Add model checks for temperature registers
+    - thermal: intel: intel_tcc_cooling: Use a model-specific bitmask for TCC
+      offset
+    - hwmon: (coretemp) Extend the bitmask to read temperature to 0xff
+  * [SRU] Fix Lenovo M70/90 gen6 micmute key and led (LP: #2101811)
+    - ALSA: hda/realtek - add supported Mic Mute LED for Lenovo platform
+    - ALSA: hda: realtek: fix incorrect IS_REACHABLE() usage
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869)
+    - ceph: allocate sparse_ext map only for sparse reads
+    - mm/vmstat: fix a W=1 clang compiler warning
+    - tcp_bpf: Charge receive socket buffer in bpf_tcp_ingress()
+    - tcp_bpf: Add sk_rmem_alloc related logic for tcp_bpf ingress redirection
+    - bpf: Check negative offsets in __bpf_skb_min_len()
+    - mtd: diskonchip: Cast an operand to prevent potential overflow
+    - mtd: rawnand: arasan: Fix double assertion of chip-select
+    - mtd: rawnand: arasan: Fix missing de-registration of NAND
+    - phy: qcom-qmp: Fix register name in RX Lane config of SC8280XP
+    - phy: core: Fix an OF node refcount leakage in _of_phy_get()
+    - phy: core: Fix an OF node refcount leakage in of_phy_provider_lookup()
+    - phy: core: Fix that API devm_phy_put() fails to release the phy
+    - phy: core: Fix that API devm_of_phy_provider_unregister() fails to
+      unregister the phy provider
+    - phy: core: Fix that API devm_phy_destroy() fails to destroy the phy
+    - phy: usb: Toggle the PHY power during init
+    - phy: rockchip: naneng-combphy: fix phy reset
+    - dmaengine: mv_xor: fix child node refcount handling in early exit
+    - dmaengine: dw: Select only supported masters for ACPI devices
+    - dmaengine: tegra: Return correct DMA status when paused
+    - dmaengine: fsl-edma: implement the cleanup path of fsl_edma3_attach_pd()
+    - dmaengine: apple-admac: Avoid accessing registers in probe
+    - stddef: make __struct_group() UAPI C++-friendly
+    - tracing/kprobe: Make trace_kprobe's module callback called after jump_label
+      update
+    - watchdog: it87_wdt: add PWRGD enable quirk for Qotom QCML04
+    - watchdog: mediatek: Add support for MT6735 TOPRGU/WDT
+    - scsi: qla1280: Fix hw revision numbering for ISP1020/1040
+    - udf: Skip parent dir link count update if corrupted
+    - ALSA: hda/conexant: fix Z60MR100 startup pop issue
+    - ALSA: sh: Use standard helper for buffer accesses
+    - smb: server: Fix building with GCC 15
+    - regmap: Use correct format specifier for logging range errors
+    - LoongArch: Fix reserving screen info memory for above-4G firmware
+    - LoongArch: BPF: Adjust the parameter of emit_jirl()
+    - platform/x86: asus-nb-wmi: Ignore unknown event 0xCF
+    - spi: intel: Add Panther Lake SPI controller support
+    - scsi: mpt3sas: Diag-Reset when Doorbell-In-Use bit is set during driver load
+      time
+    - scsi: storvsc: Do not flag MAINTENANCE_IN return of SRB_STATUS_DATA_OVERRUN
+      as an error
+    - spi: omap2-mcspi: Fix the IS_ERR() bug for devm_clk_get_optional_enabled()
+    - blk-mq: register cpuhp callback after hctx is added to xarray table
+    - blk-mq: move cpuhp callback registering out of q->sysfs_lock
+    - MIPS: Probe toolchain support of -msym32
+    - MIPS: mipsregs: Set proper ISA level for virt extensions
+    - freezer, sched: Report frozen tasks as 'D' instead of 'R'
+    - tracing: Constify string literal data member in struct trace_event_call
+    - io_uring/sqpoll: fix sqpoll error handling races
+    - i2c: microchip-core: actually use repeated sends
+    - i2c: imx: add imx7d compatible string for applying erratum ERR007805
+    - i2c: microchip-core: fix "ghost" detections
+    - btrfs: sysfs: fix direct super block member reads
+    - ALSA: sh: Fix wrong argument order for copy_from_iter()
+    - block: avoid to reuse `hctx` not removed from cpuhp callback list
+    - fork: avoid inappropriate uprobe access to invalid mm
+    - ASoC: SOF: Intel: hda-dai: Do not release the link DMA on STOP
+    - power: supply: bq24190: Fix BQ24296 Vbus regulator support
+    - udf: Verify inode link counts before performing rename
+    - ALSA: ump: Indicate the inactive group in legacy substream names
+    - ALSA: ump: Update legacy substream names upon FB info update
+    - scsi: mpi3mr: Synchronize access to ioctl data buffer
+    - scsi: mpi3mr: Handling of fault code for insufficient power
+    - objtool: Add bch2_trans_unlocked_error() to bcachefs noreturns
+    - dmaengine: loongson2-apb: Change GENMASK to GENMASK_ULL
+    - perf/x86/intel/ds: Add PEBS format 6
+    - btrfs: add and use helper to verify the calling task has locked the inode
+    - btrfs: fix race with memory mapped writes when activating swap file
+    - btrfs: fix swap file activation failure due to extents that used to be
+      shared
+    - ALSA: ump: Shut up truncated string warning
+    - Upstream stable to v6.6.69, v6.12.8
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56758
+    - btrfs: check folio mapping after unlock in relocate_one_folio()
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56759
+    - btrfs: fix use-after-free when COWing tree bock and tracing is enabled
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57806
+    - btrfs: fix transaction atomicity bug when enabling simple quotas
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57793
+    - virt: tdx-guest: Just leak decrypted memory on unrecoverable errors
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56764
+    - ublk: detach gendisk from ublk device if add_disk() fails
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57804
+    - scsi: mpi3mr: Fix corrupt config pages PHY state is switched in sysfs
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57792
+    - power: supply: gpio-charger: Fix set charge current limits
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56760
+    - PCI/MSI: Handle lack of irqdomain gracefully
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56763
+    - tracing: Prevent bad count for tracing_cpumask_write
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57946
+    - virtio-blk: don't keep queue frozen during system suspend
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-57807
+    - scsi: megaraid_sas: Fix for a potential deadlock
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56767
+    - dmaengine: at_xdmac: avoid null_prt_deref in at_xdmac_prep_dma_memset
+  * Noble update: upstream stable patchset 2025-03-22 (LP: #2103869) //
+    CVE-2024-56769
+    - media: dvb-frontends: dib3000mb: fix uninit-value in dib3000_write_reg
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266)
+    - usb: dwc2: gadget: Don't write invalid mapped sg entries into dma_desc with
+      iommu enabled
+    - PCI: vmd: Create domain symlink before pci_bus_add_devices()
+    - PCI: Add ACS quirk for Broadcom BCM5760X NIC
+    - usb: cdns3-ti: Add workaround for Errata i2409
+    - MIPS: Loongson64: DTS: Fix msi node for ls7a
+    - ASoC: Intel: sof_sdw: fix jack detection on ADL-N variant RVP
+    - ASoC: Intel: sof_sdw: add quirk for Dell SKU 0B8C
+    - usb: cdns3: Add quirk flag to enable suspend residency
+    - platform/x86: p2sb: Make p2sb_get_devfn() return void
+    - p2sb: Factor out p2sb_read_from_cache()
+    - p2sb: Introduce the global flag p2sb_hidden_by_bios
+    - p2sb: Move P2SB hide and unhide code to p2sb_scan_and_cache()
+    - p2sb: Do not scan and remove the P2SB device when it is unhidden
+    - i2c: pnx: Fix timeout in wait functions
+    - xfs: fix the contact address for the sysfs ABI documentation
+    - xfs: verify buffer, inode, and dquot items every tx commit
+    - xfs: use consistent uid/gid when grabbing dquots for inodes
+    - xfs: declare xfs_file.c symbols in xfs_file.h
+    - xfs: create a new helper to return a file's allocation unit
+    - xfs: Fix xfs_flush_unmap_range() range for RT
+    - xfs: Fix xfs_prepare_shift() range for RT
+    - xfs: convert comma to semicolon
+    - xfs: fix file_path handling in tracepoints
+    - xfs: remove unused parameter in macro XFS_DQUOT_LOGRES
+    - xfs: attr forks require attr, not attr2
+    - xfs: conditionally allow FS_XFLAG_REALTIME changes if S_DAX is set
+    - xfs: Fix the owner setting issue for rmap query in xfs fsmap
+    - xfs: use XFS_BUF_DADDR_NULL for daddrs in getfsmap code
+    - xfs: take m_growlock when running growfsrt
+    - xfs: reset rootdir extent size hint after growfsrt
+    - tools: hv: change permissions of NetworkManager configuration file
+    - cxl/pci: Fix potential bogus return value upon successful probing
+    - cxl/region: Fix region creation for greater than x2 switches
+    - net/smc: check sndbuf_space again after NOSPACE flag is set in smc_poll
+    - ionic: use ee->offset when returning sprom data
+    - net: renesas: rswitch: rework ts tags management
+    - net: hinic: Fix cleanup in create_rxqs/txqs()
+    - net: ethernet: bgmac-platform: fix an OF node reference leak
+    - ipvs: Fix clamp() of ip_vs_conn_tab on small memory systems
+    - netfilter: ipset: Fix for recursive locking warning
+    - selftests: openvswitch: fix tcpdump execution
+    - net: mdiobus: fix an OF node reference leak
+    - mmc: sdhci-tegra: Remove SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC quirk
+    - mmc: mtk-sd: disable wakeup in .remove() and in the error path of .probe()
+    - EDAC/amd64: Simplify ECC check on unified memory controllers
+    - chelsio/chtls: prevent potential integer overflow on 32bit
+    - i2c: riic: Always round-up when calculating bus period
+    - efivarfs: Fix error on non-existent file
+    - hexagon: Disable constant extender optimization for LLVM prior to 19.1.0
+    - USB: serial: option: add TCL IK512 MBIM & ECM
+    - USB: serial: option: add MeiG Smart SLM770A
+    - USB: serial: option: add Netprisma LCUK54 modules for WWAN Ready
+    - USB: serial: option: add MediaTek T7XX compositions
+    - USB: serial: option: add Telit FE910C04 rmnet compositions
+    - thunderbolt: Improve redrive mode handling
+    - drm/panel: novatek-nt35950: fix return value check in nt35950_probe()
+    - i915/guc: Reset engine utilization buffer before registration
+    - i915/guc: Ensure busyness counter increases motonically
+    - i915/guc: Accumulate active runtime on gt reset
+    - hwmon: (tmp513) Fix interpretation of values of Shunt Voltage and Limit
+      Registers
+    - hwmon: (tmp513) Fix Current Register value interpretation
+    - hwmon: (tmp513) Fix interpretation of values of Temperature Result and Limit
+      Registers
+    - zram: refuse to use zero sized block device as backing device
+    - zram: fix uninitialized ZRAM not releasing backing device
+    - zram: fix potential UAF of zram table
+    - vmalloc: fix accounting with i915
+    - btrfs: tree-checker: reject inline extent items with 0 ref count
+    - smb: client: fix TCP timers deadlock after rmmod
+    - tracing: Fix test_event_printk() to process entire print argument
+    - tracing: Add missing helper functions in event pointer dereference check
+    - tracing: Add "%s" check in test_event_printk()
+    - tracing: Have process_string() also allow arrays
+    - selftests/memfd: run sysctl tests when PID namespace support is enabled
+    - selftests/bpf: Use asm constraint "m" for LoongArch
+    - io_uring: Fix registered ring file refcount leak
+    - NFS/pnfs: Fix a live lock between recalled layouts and layoutget
+    - of/irq: Fix interrupt-map cell length check in of_irq_parse_imap_parent()
+    - of/irq: Fix using uninitialized variable @addr_len in API of_irq_parse_one()
+    - nilfs2: fix buffer head leaks in calls to truncate_inode_pages()
+    - udmabuf: also check for F_SEAL_FUTURE_WRITE
+    - of: Fix error path in of_parse_phandle_with_args_map()
+    - of: Fix refcount leakage for OF node returned by __of_get_dma_parent()
+    - ceph: validate snapdirname option length when mounting
+    - ceph: improve error handling and short/overflow-read logic in
+      __ceph_sync_read()
+    - ceph: fix memory leaks in __ceph_sync_read()
+    - epoll: Add synchronous wakeup support for ep_poll_callback
+    - io_uring/rw: avoid punting to io-wq directly
+    - drm/amdgpu: Handle NULL bo->tbo.resource (again) in amdgpu_vm_bo_update
+    - xfs: sb_spino_align is not verified
+    - xfs: fix sparse inode limits on runt AG
+    - xfs: fix sb_spino_align checks for large fsblock sizes
+    - xfs: fix zero byte checking in the superblock scrubber
+    - netdev: fix repeated netlink messages in queue dump
+    - team: Fix feature exposure when no ports are present
+    - can: m_can: fix missed interrupts with m_can_pci
+    - netdev-genl: avoid empty messages in queue dump
+    - KVM: arm64: Do not allow ID_AA64MMFR0_EL1.ASIDbits to be overridden
+    - KVM: arm64: Fix set_id_regs selftest for ASIDBITS becoming unwritable
+    - net: mctp: handle skb cleanup on sock_queue failures
+    - xhci: retry Stop Endpoint on buggy NEC controllers
+    - usb: xhci: Limit Stop Endpoint retries
+    - usb: xhci: Avoid queuing redundant Stop Endpoint commands
+    - xhci: Turn NEC specific quirk for handling Stop Endpoint errors generic
+    - thunderbolt: Add support for Intel Panther Lake-M/P
+    - thunderbolt: Don't display nvm_version unless upgrade supported
+    - drm/panel: st7701: Add prepare_prev_first flag to drm_panel
+    - drm/panel: synaptics-r63353: Fix regulator unbalance
+    - drm/amdgpu/nbio7.11: fix IP version check
+    - drm/amdgpu/nbio7.7: fix IP version check
+    - fgraph: Still initialize idle shadow stacks when starting
+    - x86/hyperv: Fix hv tsc page based sched_clock for hibernation
+    - ocfs2: fix the space leak in LA when releasing LA
+    - of: property: fw_devlink: Do not use interrupt-parent directly
+    - of: address: Preserve the flags portion on 1:1 dma-ranges mapping
+    - Upstream stable to v6.6.68, v6.12.7
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56710
+    - ceph: fix memory leak in ceph_direct_read_write()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-53685
+    - ceph: give up on paths longer than PATH_MAX
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-54193
+    - accel/ivpu: Fix WARN in ivpu_ipc_send_receive_internal()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-54455
+    - accel/ivpu: Fix general protection fault in ivpu_bo_list()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-53690
+    - nilfs2: prevent use of deleted inode
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56709
+    - io_uring: check if iowq is killed before queuing
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-55881
+    - KVM: x86: Play nice with protected guests in complete_hypercall_exit()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-55916
+    - Drivers: hv: util: Avoid accessing a ringbuffer not initialized yet
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56369
+    - drm/modes: Avoid divide by zero harder in drm_mode_vrefresh()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56372
+    - net: tun: fix tun_napi_alloc_frags()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56715
+    - ionic: Fix netdev notifier unregister on failure
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56716
+    - netdevsim: prevent bad user input in nsim_dev_health_break_write()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56717
+    - net: mscc: ocelot: fix incorrect IFH SRC_PORT field in
+      ocelot_ifh_set_basic()
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-57791
+    - net/smc: check return value of sock_recvmsg when draining clc data
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-47408
+    - net/smc: check smcd_v2_ext_offset when receiving proposal msg
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-49568
+    - net/smc: check v2_ext_offset/eid_cnt/ism_gid_cnt when receiving proposal msg
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-49571
+    - net/smc: check iparea_offset and ipv6_prefixes_cnt when receiving proposal
+      msg
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-56718
+    - net/smc: protect link down work from execute after lgr freed
+  * Noble update: upstream stable patchset 2025-03-14 (LP: #2102266) //
+    CVE-2024-41013
+    - xfs: don't walk off the end of a directory data block
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181)
+    - perf/x86/intel/ds: Unconditionally drain PEBS DS when changing PEBS_DATA_CFG
+    - ksmbd: fix racy issue from session lookup and expire
+    - splice: do not checksum AF_UNIX sockets
+    - tcp: check space before adding MPTCP SYN options
+    - ALSA: usb-audio: Add implicit feedback quirk for Yamaha THR5
+    - usb: host: max3421-hcd: Correctly abort a USB request.
+    - ata: sata_highbank: fix OF node reference leak in highbank_initialize_phys()
+    - usb: dwc2: Fix HCD resume
+    - usb: dwc2: hcd: Fix GetPortStatus & SetPortFeature
+    - usb: dwc2: Fix HCD port connection race
+    - scsi: ufs: core: Update compl_time_stamp_local_clock after completing a cqe
+    - usb: gadget: midi2: Fix interpretation of is_midi1 bits
+    - usb: ehci-hcd: fix call balance of clocks handling routines
+    - usb: typec: anx7411: fix fwnode_handle reference leak
+    - usb: typec: anx7411: fix OF node reference leaks in
+      anx7411_typec_switch_probe()
+    - usb: dwc3: xilinx: make sure pipe clock is deselected in usb2 only mode
+    - drm/i915: Fix memory leak by correcting cache object name in error handler
+    - xfs: update btree keys correctly when _insrec splits an inode root block
+    - xfs: don't drop errno values when we fail to ficlone the entire range
+    - xfs: return from xfs_symlink_verify early on V4 filesystems
+    - xfs: fix scrub tracepoints when inode-rooted btrees are involved
+    - xfs: only run precommits once per transaction object
+    - bpf: Check size for BTF-based ctx access of pointer members
+    - bpf: Fix theoretical prog_array UAF in __uprobe_perf_func()
+    - bpf,perf: Fix invalid prog_array access in perf_event_detach_bpf_prog
+    - bpf, sockmap: Fix update element with same
+    - wifi: mac80211: init cnt before accessing elem in
+      ieee80211_copy_mbssid_beacon
+    - wifi: mac80211: clean up 'ret' in sta_link_apply_parameters()
+    - wifi: mac80211: fix station NSS capability initialization order
+    - batman-adv: Do not send uninitialized TT changes
+    - batman-adv: Remove uninitialized data in full table TT response
+    - batman-adv: Do not let TT changes list grows indefinitely
+    - wifi: cfg80211: sme: init n_channels before channels[] access
+    - selftests: mlxsw: sharedbuffer: Remove h1 ingress test case
+    - selftests: mlxsw: sharedbuffer: Remove duplicate test cases
+    - selftests: mlxsw: sharedbuffer: Ensure no extra packets are counted
+    - ptp: kvm: x86: Return EOPNOTSUPP instead of ENODEV from kvm_arch_ptp_init()
+    - net: mscc: ocelot: fix memory leak on ocelot_port_add_txtstamp_skb()
+    - net: mscc: ocelot: improve handling of TX timestamp for unknown skb
+    - net: mscc: ocelot: ocelot->ts_id_lock and ocelot_port->tx_skbs.lock are IRQ-
+      safe
+    - net: mscc: ocelot: be resilient to loss of PTP packets during transmission
+    - net: mscc: ocelot: perform error cleanup in ocelot_hwstamp_set()
+    - spi: aspeed: Fix an error handling path in aspeed_spi_[read|write]_user()
+    - net: sparx5: fix FDMA performance issue
+    - net: sparx5: fix the maximum frame length register
+    - ACPI: resource: Fix memory resource type union access
+    - cxgb4: use port number to set mac addr
+    - qca_spi: Fix clock speed for multiple QCA7000
+    - qca_spi: Make driver probing reliable
+    - ASoC: amd: yc: Fix the wrong return value
+    - Documentation: PM: Clarify pm_runtime_resume_and_get() return value
+    - net: renesas: rswitch: fix race window between tx start and complete
+    - net: renesas: rswitch: fix leaked pointer on error path
+    - net: renesas: rswitch: handle stop vs interrupt race
+    - net: dsa: felix: fix stuck CPU-injected packets with short taprio windows
+    - netem: Update sch->q.qlen before qdisc_tree_reduce_backlog()
+    - bonding: Fix feature propagation of NETIF_F_GSO_ENCAP_ALL
+    - team: Fix feature propagation of NETIF_F_GSO_ENCAP_ALL
+    - ACPICA: events/evxfregn: don't release the ContextMutex that was never
+      acquired
+    - Bluetooth: iso: Fix recursive locking warning
+    - Bluetooth: SCO: Add support for 16 bits transparent voice setting
+    - net: renesas: rswitch: fix initial MPIC register setting
+    - net: dsa: microchip: KSZ9896 register regmap alignment to 32 bit boundaries
+    - blk-iocost: Avoid using clamp() on inuse in __propagate_weights()
+    - kselftest/arm64: abi: fix SVCR detection
+    - KVM: arm64: Disable MPAM visibility by default and ignore VMM writes
+    - selftests/bpf: remove use of __xlated()
+    - xen/netfront: fix crash when removing device
+    - x86: make get_cpu_vendor() accessible from Xen code
+    - objtool/x86: allow syscall instruction
+    - x86/static-call: provide a way to do very early static-call updates
+    - x86/xen: don't do PV iret hypercall through hypercall page
+    - x86/xen: add central hypercall functions
+    - x86/xen: fix xen_hypercall_hvm() to not clobber %rbx
+    - x86/xen: add FRAME_END to xen_hypercall_hvm()
+    - x86/xen: use new hypercall functions instead of hypercall page
+    - x86/xen: remove hypercall page
+    - x86/static-call: fix 32-bit build
+    - x86/asm: Make serialize() always_inline
+    - x86/static-call: Remove early_boot_irqs_disabled check to fix Xen PVH dom0
+    - serial: sh-sci: Check if TX data was written to device in .tx_empty()
+    - gpio: ljca: Initialize num before accessing item in ljca_gpio_config
+    - ALSA: hda/realtek: Fix headset mic on Acer Nitro 5
+    - drm/amdkfd: Use device based logging for errors
+    - drm/amdkfd: pause autosuspend when creating pdd
+    - drm/amdkfd: fixed page fault when enable MES shader debugger
+    - drm/i915/color: Stop using non-posted DSB writes for legacy LUT
+    - drm/amd/pm: Set SMU v13.0.7 default workload type
+    - xfs: return a 64-bit block count from xfs_btree_count_blocks
+    - perf machine: Initialize machine->env to address a segfault
+    - bnxt_en: Fix GSO type for HW GRO packets on 5750X chips
+    - net: renesas: rswitch: fix possible early skb release
+    - Bluetooth: Improve setsockopt() handling of malformed user input
+    - libperf: evlist: Fix --cpu argument on hybrid platform
+    - selftests: netfilter: Stabilize rpath.sh
+    - net, team, bonding: Add netdev_base_features helper
+    - bonding: Fix initial {vlan,mpls}_feature set in bond_compute_features
+    - team: Fix initial vlan_feature set in __team_compute_features
+    - drm/xe: fix the ERR_PTR() returned on failure to allocate tiny pt
+    - Upstream stable to v6.6.67, v6.12.6
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56652
+    - drm/xe/reg_sr: Remove register pool
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-54460
+    - Bluetooth: iso: Fix circular lock in iso_listen_bis
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-57879
+    - Bluetooth: iso: Always release hdev at the end of iso_listen_bis
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56656
+    - bnxt_en: Fix aggregation ID mask to prevent oops on 5760X chips
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-53125
+    - bpf: sync_linked_regs() must preserve subreg_def
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56654
+    - Bluetooth: hci_event: Fix using rcu_read_(un)lock while iterating
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56770
+    - net/sched: netem: account for backlog updates from child qdisc
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-54683
+    - netfilter: IDLETIMER: Fix for possible ABBA deadlock
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-55639
+    - net: renesas: rswitch: avoid use-after-put for a device tree node
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56657
+    - ALSA: control: Avoid WARN() for symlink errors
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56659
+    - net: lapb: increase LAPB_HEADER_LEN
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56660
+    - net/mlx5: DR, prevent potential error pointer dereference
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56662
+    - acpi: nfit: vmalloc-out-of-bounds Read in acpi_nfit_ctl
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56664
+    - bpf, sockmap: Fix race between element replace and close()
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56667
+    - drm/i915: Fix NULL pointer dereference in capture_engine
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56670
+    - usb: gadget: u_serial: Fix the issue that gs_start_io crashed due to
+      accessing null pointer
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-53687
+    - riscv: Fix IPIs usage in kfence_protect_page()
+  * Noble update: upstream stable patchset 2025-03-13 (LP: #2102181) //
+    CVE-2024-56675
+    - bpf: Fix UAF via mismatching bpf_prog/attachment RCU flavors
+  * Noble update: upstream stable patchset 2025-02-04 (LP: #2097393)
+    - selftests: net: Remove executable bits from library scripts
+  * CVE-2024-56653
+    - Bluetooth: btmtk: avoid UAF in btmtk_process_coredump
+
+  [ Ubuntu: 6.8.0-58.60 ]
+
+  * noble/linux: 6.8.0-58.60 -proposed tracker (LP: #2102529)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2025.03.17)
+  * wdat_wdt.ko should be pulled in by linux-image-virtual (LP: #2098554)
+    - [Packaging]: wdat_wdt.ko is moved from "linux-modules-extra-*-generic" to
+      "linux-modules-*-generic"
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118)
+    - openrisc: Use asm-generic's version of fix_to_virt() & virt_to_fix()
+    - iTCO_wdt: mask NMI_NOW bit for update_no_reboot_bit() call
+    - watchdog: xilinx_wwdt: Calculate max_hw_heartbeat_ms using clock frequency
+    - watchdog: apple: Actually flush writes after requesting watchdog restart
+    - watchdog: mediatek: Make sure system reset gets asserted in
+      mtk_wdt_restart()
+    - can: gs_usb: add VID/PID for Xylanta SAINT3 product family
+    - can: gs_usb: add usb endpoint address detection at driver probe step
+    - can: sun4i_can: sun4i_can_err(): call can_change_state() even if cf is NULL
+    - can: m_can: m_can_handle_lec_err(): fix {rx,tx}_errors statistics
+    - can: ifi_canfd: ifi_canfd_handle_lec_err(): fix {rx,tx}_errors statistics
+    - can: hi311x: hi3110_can_ist(): fix {rx,tx}_errors statistics
+    - can: sja1000: sja1000_err(): fix {rx,tx}_errors statistics
+    - can: sun4i_can: sun4i_can_err(): fix {rx,tx}_errors statistics
+    - can: ems_usb: ems_usb_rx_err(): fix {rx,tx}_errors statistics
+    - can: f81604: f81604_handle_can_bus_errors(): fix {rx,tx}_errors statistics
+    - ipvs: fix UB due to uninitialized stack access in ip_vs_protocol_init()
+    - selftests: hid: fix typo and exit code
+    - ptp: Add error handling for adjfine callback in ptp_clock_adjtime
+    - net/sched: tbf: correct backlog statistic for GSO packets
+    - net: hsr: fix fill_frame_info() regression vs VLAN packets
+    - platform/x86: asus-wmi: add support for vivobook fan profiles
+    - platform/x86: asus-wmi: Fix inconsistent use of thermal policies
+    - platform/x86: asus-wmi: Ignore return value when writing thermal policy
+    - net/smc: mark optional smcd_ops and check for support when called
+    - net/smc: add operations to merge sndbuf with peer DMB
+    - net/smc: {at|de}tach sndbuf to peer DMB if supported
+    - net/smc: refactoring initialization of smc sock
+    - net/qed: allow old cards not supporting "num_images" to work
+    - ixgbevf: stop attempting IPSEC offload on Mailbox API 1.5
+    - ixgbe: downgrade logging of unsupported VF API version to debug
+    - net: sched: fix erspan_opt settings in cls_flower
+    - netfilter: nft_set_hash: skip duplicated elements pending gc run
+    - netfilter: nft_set_hash: unaligned atomic read on struct nft_set_ext
+    - ethtool: Fix wrong mod state in case of verbose and no_mask bitset
+    - mlxsw: spectrum_acl_flex_keys: Constify struct mlxsw_afk_element_inst
+    - mlxsw: spectrum_acl_flex_keys: Use correct key block on Spectrum-4
+    - net/mlx5e: Remove workaround to avoid syndrome for internal port
+    - xhci: Allow RPM on the USB controller (1022:43f7) by default
+    - gpio: grgpio: use a helper variable to store the address of ofdev->dev
+    - usb: dwc3: gadget: Rewrite endpoint allocation flow
+    - usb: dwc3: ep0: Don't reset resource alloc flag (including ep0)
+    - usb: dwc3: ep0: Don't clear ep0 DWC3_EP_TRANSFER_STARTED
+    - mmc: mtk-sd: use devm_mmc_alloc_host
+    - mmc: mtk-sd: Fix error handle of probe function
+    - mmc: mtk-sd: fix devm_clk_get_optional usage
+    - mmc: mtk-sd: Fix MMC_CAP2_CRYPTO flag setting
+    - zram: do not mark idle slots that cannot be idle
+    - zram: clear IDLE flag in mark_idle()
+    - powerpc/vdso: Refactor CFLAGS for CVDSO build
+    - powerpc/vdso: Drop -mstack-protector-guard flags in 32-bit files with clang
+    - ntp: Remove invalid cast in time offset math
+    - driver core: Add FWLINK_FLAG_IGNORE to completely ignore a fwnode link
+    - driver core: fw_devlink: Stop trying to optimize cycle detection logic
+    - drivers: core: fix device leak in __fw_devlink_relax_cycles()
+    - i3c: master: support to adjust first broadcast address speed
+    - i3c: master: svc: use slow speed for first broadcast address
+    - i3c: master: svc: Modify enabled_events bit 7:0 to act as IBI enable counter
+    - i3c: master: Replace hard code 2 with macro I3C_ADDR_SLOT_STATUS_BITS
+    - i3c: master: Extend address status bit to 4 and add
+      I3C_ADDR_SLOT_EXT_DESIRED
+    - i3c: master: Fix dynamic address leak when 'assigned-address' is present
+    - i3c: master: Fix missing 'ret' assignment in set_speed()
+    - drm/bridge: it6505: update usleep_range for RC circuit charge time
+    - drm/bridge: it6505: Fix inverted reset polarity
+    - scsi: ufs: core: Always initialize the UIC done completion
+    - scsi: ufs: core: Add ufshcd_send_bsg_uic_cmd() for UFS BSG
+    - bpf, vsock: Fix poll() missing a queue
+    - bpf, vsock: Invoke proto::close on close()
+    - xsk: always clear DMA mapping information when unmapping the pool
+    - bpftool: fix potential NULL pointer dereferencing in prog_dump()
+    - drm/sti: Add __iomem for mixer_dbg_mxn's parameter
+    - ALSA: seq: ump: Use automatic cleanup of kfree()
+    - ALSA: ump: Update substream name from assigned FB names
+    - ALSA: seq: ump: Fix seq port updates per FB info notify
+    - ALSA: usb-audio: Notify xrun for low-latency mode
+    - tools: Override makefile ARCH variable if defined, but empty
+    - ASoC: SOF: ipc3-topology: Convert the topology pin index to ALH dai index
+    - ASoC: SOF: ipc3-topology: fix resource leaks in
+      sof_ipc3_widget_setup_comp_dai()
+    - bpf: Fix narrow scalar spill onto 64-bit spilled scalar slots
+    - scsi: scsi_debug: Fix hrtimer support for ndelay
+    - ASoC: mediatek: mt8188-mt6359: Remove hardcoded dmic codec
+    - drm/v3d: Enable Performance Counters before clearing them
+    - scatterlist: fix incorrect func name in kernel-doc
+    - iio: magnetometer: yas530: use signed integer type for clamp limits
+    - bpf: Handle BPF_EXIST and BPF_NOEXIST for LPM trie
+    - bpf: Remove unnecessary kfree(im_node) in lpm_trie_update_elem
+    - bpf: Handle in-place update for full LPM trie correctly
+    - bpf: Fix exact match conditions in trie_get_next_key()
+    - x86/CPU/AMD: WARN when setting EFER.AUTOIBRS if and only if the WRMSR fails
+    - watchdog: rti: of: honor timeout-sec property
+    - can: mcp251xfd: mcp251xfd_get_tef_len(): work around erratum DS80000789E 6.
+    - tracing: Fix cmp_entries_dup() to respect sort() comparison rules
+    - arm64: Ensure bits ASID[15:8] are masked out when the kernel uses 8-bit
+      ASIDs
+    - ALSA: usb-audio: add mixer mapping for Corsair HS80
+    - ALSA: hda/realtek: Enable mute and micmute LED on HP ProBook 430 G8
+    - ALSA: hda/realtek: Add support for Samsung Galaxy Book3 360 (NP730QFG)
+    - scsi: qla2xxx: Fix abort in bsg timeout
+    - scsi: qla2xxx: Fix NVMe and NPIV connect issue
+    - scsi: qla2xxx: Supported speed displayed incorrectly for VPorts
+    - scsi: qla2xxx: Remove check req_sg_cnt should be equal to rsp_sg_cnt
+    - scsi: ufs: core: Add missing post notify for power mode change
+    - fs/smb/client: cifs_prime_dcache() for SMB3 POSIX reparse points
+    - drm/dp_mst: Verify request type in the corresponding down message reply
+    - drm/amdgpu/hdp5.2: do a posting read when flushing HDP
+    - modpost: Add .irqentry.text to OTHER_SECTIONS
+    - x86/kexec: Restore GDT on return from ::preserve_context kexec
+    - dma-buf: fix dma_fence_array_signaled v4
+    - dma-fence: Fix reference leak on fence merge failure path
+    - dma-fence: Use kernel's sort for merging fences
+    - regmap: detach regmap from dev on regmap_exit
+    - mmc: sdhci-pci: Add DMI quirk for missing CD GPIO on Vexia Edu Atla 10
+      tablet
+    - mmc: core: Further prevent card detect during shutdown
+    - ocfs2: update seq_file index in ocfs2_dlm_seq_next
+    - lib: stackinit: hide never-taken branch from compiler
+    - kasan: make report_lock a raw spinlock
+    - x86/mm: Add _PAGE_NOPTISHADOW bit to avoid updating userspace page tables
+    - epoll: annotate racy check
+    - kselftest/arm64: Log fp-stress child startup errors to stdout
+    - btrfs: avoid unnecessary device path update for the same device
+    - btrfs: do not clear read-only when adding sprout device
+    - kselftest/arm64: Don't leak pipe fds in pac.exec_sign_all()
+    - hwmon: (nct6775) Add 665-ACE/600M-CL to ASUS WMI monitoring list
+    - ACPI: x86: Make UART skip quirks work on PCI UARTs without an UID
+    - perf/x86/amd: Warn only on new bits set
+    - spi: spi-fsl-lpspi: Adjust type of scldiv
+    - HID: add per device quirk to force bind to hid-generic
+    - media: uvcvideo: RealSense D421 Depth module metadata
+    - media: uvcvideo: Add a quirk for the Kaiweets KTI-W02 infrared camera
+    - media: cx231xx: Add support for Dexatek USB Video Grabber 1d19:6108
+    - mmc: core: Add SD card quirk for broken poweroff notification
+    - mmc: sdhci-esdhc-imx: enable quirks SDHCI_QUIRK_NO_LED
+    - regmap: maple: Provide lockdep (sub)class for maple tree's internal lock
+    - selftests/resctrl: Protect against array overflow when reading strings
+    - drm/vc4: hdmi: Avoid log spam for audio start failure
+    - drm/vc4: hvs: Set AXI panic modes for the HVS
+    - drm: panel-orientation-quirks: Add quirk for AYA NEO 2 model
+    - drm: panel-orientation-quirks: Add quirk for AYA NEO Founder edition
+    - drm: panel-orientation-quirks: Add quirk for AYA NEO GEEK
+    - drm/bridge: it6505: Enable module autoloading
+    - drm/mcde: Enable module autoloading
+    - drm/radeon/r600_cs: Fix possible int overflow in r600_packet3_check()
+    - drm/display: Fix building with GCC 15
+    - ALSA: hda: Use own quirk lookup helper
+    - ALSA: hda/conexant: Use the new codec SSID matching
+    - r8169: don't apply UDP padding quirk on RTL8126A
+    - samples/bpf: Fix a resource leak
+    - net: fec_mpc52xx_phy: Use %pa to format resource_size_t
+    - net: ethernet: fs_enet: Use %pa to format resource_size_t
+    - net/sched: cbs: Fix integer overflow in cbs_set_port_rate()
+    - Bluetooth: L2CAP: handle NULL sock pointer in l2cap_sock_alloc
+    - wifi: ath5k: add PCI ID for SX76X
+    - wifi: ath5k: add PCI ID for Arcadyan devices
+    - fanotify: allow reporting errors on failure to open fd
+    - drm/panel: simple: Add Microchip AC69T88A LVDS Display panel
+    - net: sfp: change quirks for Alcatel Lucent G-010S-P
+    - net: stmmac: Programming sequence for VLAN packets with split header
+    - drm/sched: memset() 'job' in drm_sched_job_init()
+    - amdgpu/uvd: get ring reference from rq scheduler
+    - drm/amdgpu: don't access invalid sched
+    - drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts for vega20_ih
+    - drm/amdgpu: Dereference the ATCS ACPI buffer
+    - netlink: specs: Add missing bitset attrs to ethtool spec
+    - drm/amdgpu: refine error handling in amdgpu_ttm_tt_pin_userptr
+    - fsl/fman: Validate cell-index value obtained from Device Tree
+    - drm/amdgpu: skip amdgpu_device_cache_pci_state under sriov
+    - ALSA: usb-audio: Make mic volume workarounds globally applicable
+    - wifi: ipw2x00: libipw_rx_any(): fix bad alignment
+    - dsa: qca8k: Use nested lock to avoid splat
+    - Bluetooth: btusb: Add RTL8852BE device 0489:e123 to device tables
+    - Bluetooth: Add new quirks for ATS2851
+    - Bluetooth: Support new quirks for ATS2851
+    - Bluetooth: Set quirks for ATS2851
+    - ASoC: hdmi-codec: reorder channel allocation list
+    - rocker: fix link status detection in rocker_carrier_init()
+    - net/neighbor: clear error in case strict check is not set
+    - netpoll: Use rcu_access_pointer() in __netpoll_setup
+    - pinctrl: freescale: fix COMPILE_TEST error with PINCTRL_IMX_SCU
+    - tracing/ftrace: disable preemption in syscall probe
+    - tracing: Use atomic64_inc_return() in trace_clock_counter()
+    - tools/rtla: fix collision with glibc sched_attr/sched_set_attr
+    - rtla/timerlat: Make timerlat_top_cpu->*_count unsigned long long
+    - scsi: ufs: core: Make DMA mask configuration more flexible
+    - scsi: lpfc: Call lpfc_sli4_queue_unset() in restart and rmmod paths
+    - clk: qcom: rcg2: add clk_rcg2_shared_floor_ops
+    - clk: qcom: rpmh: add support for SAR2130P
+    - clk: qcom: tcsrcc-sm8550: add SAR2130P support
+    - scsi: st: Don't modify unknown block number in MTIOCGET
+    - scsi: st: Add MTIOCGET and MTLOAD to ioctls allowed after device reset
+    - pinctrl: qcom-pmic-gpio: add support for PM8937
+    - pinctrl: qcom: spmi-mpp: Add PM8937 compatible
+    - thermal/drivers/qcom/tsens-v1: Add support for MSM8937 tsens
+    - nvdimm: rectify the illogical code within nd_dax_probe()
+    - smb: client: memcpy() with surrounding object base address
+    - verification/dot2: Improve dot parser robustness
+    - KMSAN: uninit-value in inode_go_dump (5)
+    - PCI: qcom: Add support for IPQ9574
+    - PCI: vmd: Add DID 8086:B06F and 8086:B60B for Intel client SKUs
+    - PCI: vmd: Set devices to D0 before enabling PM L1 Substates
+    - PCI: Detect and trust built-in Thunderbolt chips
+    - PCI: Add 'reset_subordinate' to reset hierarchy below bridge
+    - PCI: Add ACS quirk for Wangxun FF5xxx NICs
+    - f2fs: print message if fscorrupted was found in f2fs_new_node_page()
+    - ACPI: x86: Add skip i2c clients quirk for Acer Iconia One 8 A1-840
+    - ACPI: x86: Clean up Asus entries in acpi_quirk_skip_dmi_ids[]
+    - fs/ntfs3: Fix case when unmarked clusters intersect with zone
+    - usb: chipidea: udc: handle USB Error Interrupt if IOC not set
+    - iio: light: ltr501: Add LTER0303 to the supported devices
+    - ASoC: amd: yc: fix internal mic on Redmi G 2022
+    - drm/amdgpu/vcn: reset fw_shared when VCPU buffers corrupted on vcn v4.0.3
+    - drm/amdgpu/vcn: reset fw_shared under SRIOV
+    - ASoC: amd: yc: Add quirk for microphone on Lenovo Thinkpad T14s Gen 6
+      21M1CTO1WW
+    - misc: eeprom: eeprom_93cx6: Add quirk for extra read clock cycle
+    - rtc: cmos: avoid taking rtc_lock for extended period of time
+    - serial: 8250_dw: Add Sophgo SG2044 quirk
+    - smb: client: don't try following DFS links in cifs_tree_connect()
+    - setlocalversion: work around "git describe" performance
+    - sched/core: Remove the unnecessary need_resched() check in nohz_csd_func()
+    - sched/fair: Check idle_cpu() before need_resched() to detect ilb CPU turning
+      busy
+    - sched/core: Prevent wakeup of ksoftirqd during idle load balance
+    - btrfs: fix missing snapshot drew unlock when root is dead during swap
+      activation
+    - clk: en7523: Initialize num before accessing hws in en7523_register_clocks()
+    - tracing/eprobe: Fix to release eprobe when failed to add dyn_event
+    - x86: Fix build regression with CONFIG_KEXEC_JUMP enabled
+    - Revert "unicode: Don't special case ignorable code points"
+    - vfio/mlx5: Align the page tracking max message size with the device
+      capability
+    - selftests/ftrace: adjust offset for kprobe syntax error test
+    - KVM: x86/mmu: Ensure that kvm_release_pfn_clean() takes exact pfn from
+      kvm_faultin_pfn()
+    - jffs2: Fix rtime decompressor
+    - mm/damon/vaddr: fix issue in damon_va_evenly_split_region()
+    - iio: invensense: fix multiple odr switch when FIFO is off
+    - ocfs2: Revert "ocfs2: fix the la space leak when unmounting an ocfs2 volume"
+    - ALSA: hda: Fix build error without CONFIG_SND_DEBUG
+    - usb: dwc3: ep0: Don't reset resource alloc flag
+    - ALSA: usb-audio: Update UMP group attributes for GTB blocks, too
+    - platform/x86: asus-wmi: Fix thermal profile initialization
+    - i3c: master: svc: fix possible assignment of the same address to two devices
+    - btrfs: drop unused parameter file_offset from
+      btrfs_encoded_read_regular_fill_pages()
+    - md/raid5: Wait sync io to finish before changing group cnt
+    - media: platform: rga: fix 32-bit DMA limitation
+    - net: phy: dp83869: fix status reporting for 1000base-x autonegotiation
+    - remoteproc: qcom_q6v5_pas: disable auto boot for wpss
+    - mtd: spinand: winbond: Fix 512GW and 02JW OOB layout
+    - PCI: Pass domain number to pci_bus_release_domain_nr() explicitly
+    - dt-bindings: net: fec: add pps channel property
+    - net: fec: refactor PPS channel configuration
+    - net: fec: make PPS channel configurable
+    - drm/xe/xe_guc_ads: save/restore OA registers and allowlist regs
+    - drm/xe/migrate: use XE_BO_FLAG_PAGETABLE
+    - drm/amd: Add some missing straps from NBIO 7.11.0
+    - drm/amd: Fix initialization mistake for NBIO 7.11 devices
+    - drm/amdgpu/pm: Don't use OD table on Arcturus
+    - drm/amd/pm: Remove arcturus min power limit
+    - drm/amd/display: update pipe selection policy to check head pipe
+    - drm/amd/display: Remove PIPE_DTO_SRC_SEL programming from set_dtbclk_dto
+    - Revert "drm/xe/xe_guc_ads: save/restore OA registers and allowlist regs"
+    - ipv6: avoid possible NULL deref in modify_prefix_route()
+    - net: phy: microchip: Reset LAN88xx PHY to ensure clean link state on
+      LAN7800/7850
+    - ice: fix PHY Clock Recovery availability check
+    - vsock/test: fix failures due to wrong SO_RCVLOWAT parameter
+    - vsock/test: fix parameter types in SO_VM_SOCKETS_* calls
+    - mmc: core Convert UNSTUFF_BITS macro to inline function
+    - mmc: sd: SDUC Support Recognition
+    - mmc: core: Adjust ACMD22 to SDUC
+    - mmc: core: Use GFP_NOIO in ACMD22
+    - f2fs: clean up w/ F2FS_{BLK_TO_BYTES,BTYES_TO_BLK}
+    - f2fs: fix to adjust appropriate length for fiemap
+    - f2fs: fix to requery extent which cross boundary of inquiry
+    - drm/amd/display: calculate final viewport before TAP optimization
+    - drm/amd/display: Ignore scalar validation failure if pipe is phantom
+    - pmdomain: core: Add missing put_device()
+    - pmdomain: core: Fix error path in pm_genpd_init() when ida alloc fails
+    - pmdomain: core: add dummy release function to genpd device
+    - bpf: Ensure reg is PTR_TO_STACK in process_iter_arg
+    - bpf: Don't mark STACK_INVALID as STACK_MISC in mark_stack_slot_misc
+    - LoongArch: KVM: Protect kvm_check_requests() with SRCU
+    - net :mana :Request a V2 response version for MANA_QUERY_GF_STAT
+    - ALSA: usb-audio: Add extra PID for RME Digiface USB
+    - ALSA: hda/realtek: fix micmute LEDs don't work on HP Laptops
+    - scsi: ufs: pltfrm: Disable runtime PM during removal of glue drivers
+    - io_uring/cmd: document some uring_cmd related helpers
+    - io_uring: Change res2 parameter type in io_uring_cmd_done
+    - selftests/damon: add _damon_sysfs.py to TEST_FILES
+    - drm/amd/display: Correct prefetch calculation
+    - drm/amd/amdgpu: allow use kiq to do hdp flush under sriov
+    - drm/amdgpu/hdp6.0: do a posting read when flushing HDP
+    - drm/amdgpu/hdp4.0: do a posting read when flushing HDP
+    - drm/amdgpu/hdp5.0: do a posting read when flushing HDP
+    - x86/cpu/intel: Switch to new Intel CPU model defines
+    - x86/cpu/intel: Drop stray FAM6 check with new Intel CPU model defines
+    - x86/cpu: Add Lunar Lake to list of CPUs with a broken MONITOR implementation
+    - mm/damon: fix order of arguments in damos_before_apply tracepoint
+    - mm: respect mmap hint address when aligning for THP
+    - scsi: ufs: pltfrm: Drop PM runtime reference count after ufshcd_remove()
+    - memblock: allow zero threshold in validate_numa_converage()
+    - s390/pci: Sort PCI functions prior to creating virtual busses
+    - s390/pci: Use topology ID for multi-function devices
+    - s390/pci: Ignore RID for isolated VFs
+    - s390/pci: Fix SR-IOV for PFs initially in standby
+    - s390/pci: Pull search for parent PF out of zpci_iov_setup_virtfn()
+    - s390/pci: Fix handling of isolated VFs
+    - ext4: partial zero eof block on unaligned inode size extension
+    - crypto: ecdsa - Convert byte arrays with key coordinates to digits
+    - crypto: ecc - Prevent ecc_digits_from_bytes from reading too many bytes
+    - crypto: ecdsa - Rename keylen to bufsize where necessary
+    - crypto: ecdsa - Use ecc_digits_from_bytes to convert signature
+    - crypto: ecdsa - Avoid signed integer overflow on signature decoding
+    - ACPI: video: force native for Apple MacbookPro11,2 and Air7,2
+    - cleanup: Adjust scoped_guard() macros to avoid potential warning
+    - gpio: free irqs that are still requested when the chip is being removed
+    - media: uvcvideo: Force UVC version to 1.0a for 0408:4035
+    - media: uvcvideo: Force UVC version to 1.0a for 0408:4033
+    - wifi: mac80211: export ieee80211_purge_tx_queue() for drivers
+    - drm/amd/display: skip disable CRTC in seemless bootup case
+    - drm/amd/display: disable SG displays on cyan skillfish
+    - wifi: mac80211: Add non-atomic station iterator
+    - accel/qaic: Add AIC080 support
+    - mptcp: annotate data-races around subflow->fully_established
+    - net/tcp: Add missing lockdep annotations for TCP-AO hlist traversals
+    - drm/amd/display: Prune Invalid Modes For HDMI Output
+    - i2c: i801: Add support for Intel Arrow Lake-H
+    - i2c: i801: Add support for Intel Panther Lake
+    - Bluetooth: hci_conn: Reduce hci_conn_drop() calls in two functions
+    - Bluetooth: btusb: Add new VID/PID 13d3/3602 for MT7925
+    - Bluetooth: btusb: Add USB HW IDs for MT7921/MT7922/MT7925
+    - Bluetooth: btusb: Add new VID/PID 0489/e111 for MT7925
+    - Bluetooth: btusb: Add new VID/PID 0489/e124 for MT7925
+    - Bluetooth: btusb: Add 3 HWIDs for MT7925
+    - rtla/timerlat: Make timerlat_hist_cpu->*_count unsigned long long
+    - ring-buffer: Correct stale comments related to non-consuming readers
+    - ring-buffer: Limit time with disabled interrupts in rb_check_pages()
+    - scsi: lpfc: Check SLI_ACTIVE flag in FDMI cmpl before submitting follow up
+      FDMI
+    - scsi: lpfc: Prevent NDLP reference count underflow in dev_loss_tmo callback
+    - clk: qcom: clk-alpha-pll: Add support for zonda ole pll configure
+    - clk: qcom: clk-alpha-pll: Add NSS HUAYRA ALPHA PLL support for ipq9574
+    - mailbox: pcc: Check before sending MCTP PCC response ACK
+    - remoteproc: qcom: pas: Add support for SA8775p ADSP, CDSP and GPDSP
+    - remoteproc: qcom: pas: enable SAR2130P audio DSP support
+    - fs/ntfs3: Implement fallocate for compressed files
+    - fs/ntfs3: Fix warning in ni_fiemap
+    - regulator: qcom-rpmh: Update ranges for FTSMPS525
+    - usb: chipidea: add CI_HDRC_HAS_SHORT_PKT_LIMIT flag
+    - usb: chipidea: udc: limit usb request length to max 16KB
+    - usb: chipidea: udc: create bounce buffer for problem sglist entries if
+      possible
+    - iio: adc: ad7192: Convert from of specific to fwnode property handling
+    - iio: adc: ad7192: properly check spi_get_device_match_data()
+    - usb: typec: ucsi: add callback for connector status updates
+    - usb: typec: ucsi: glink: move GPIO reading into connector_status callback
+    - usb: typec: ucsi: add update_connector callback
+    - usb: typec: ucsi: glink: set orientation aware if supported
+    - usb: typec: ucsi: glink: be more precise on orientation-aware ports
+    - usb: typec: ucsi: glink: fix off-by-one in connector_status
+    - usb: typec: ucsi: Set orientation as none when connector is unplugged
+    - nvme: use helper nvme_ctrl_state in nvme_keep_alive_finish function
+    - Revert "nvme: make keep-alive synchronous operation"
+    - irqchip/gic-v3-its: Avoid explicit cpumask allocation on stack
+    - irqchip/gicv3-its: Add workaround for hip09 ITS erratum 162100801
+    - [Config] updateconfigs for HISILICON_ERRATUM_162100801
+    - drm/amd/display: Add option to retrieve detile buffer size
+    - btrfs: drop unused parameter options from open_ctree()
+    - btrfs: drop unused parameter data from btrfs_fill_super()
+    - btrfs: fix mount failure due to remount races
+    - net/mlx5: unique names for per device caches
+    - s390/pci: Fix leak of struct zpci_dev when zpci_add_device() fails
+    - ALSA: hda/realtek: Fix spelling mistake "Firelfy" -> "Firefly"
+    - softirq: Allow raising SCHED_SOFTIRQ from SMP-call-function on RT kernel
+    - Upstream stable to v6.6.65, v6.6.66, v6.12.4, v6.12.5
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-41932
+    - sched: fix warning in sched_setaffinity
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57872
+    - scsi: ufs: pltfrm: Dellocate HBA during ufshcd_pltfrm_remove()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56588
+    - scsi: hisi_sas: Create all dump files during debugfs initialization
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-47794
+    - bpf: Prevent tailcall infinite loop caused by freplace
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56599
+    - wifi: ath10k: avoid NULL pointer error during sdio remove
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56607
+    - wifi: ath12k: fix atomic calls in ath12k_mac_op_set_bitrate_mask()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56608
+    - drm/amd/display: Fix out-of-bounds access in 'dcn21_link_encoder_create'
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56609
+    - wifi: rtw88: use ieee80211_purge_tx_queue() to purge TX skb
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56782
+    - ACPI: x86: Add adev NULL check to acpi_quirk_skip_serdev_enumeration()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-48876
+    - stackdepot: fix stack_depot_save_flags() in NMI context
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56620
+    - scsi: ufs: qcom: Only free platform MSIs when ESI is enabled
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56621
+    - scsi: ufs: core: Cancel RTC work during ufshcd_remove()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-49569
+    - nvme-rdma: unquiesce admin_q before destroy it
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56632
+    - nvme-tcp: fix the memleak while create new ctrl failed
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56647
+    - net: Fix icmp host relookup triggering ip_rt_bug
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56775
+    - drm/amd/display: Fix handling of plane refcount
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56561
+    - PCI: endpoint: Fix PCI domain ID release in pci_epc_destroy()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56550
+    - s390/stacktrace: Use break instead of return statement
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56771
+    - mtd: spinand: winbond: Fix 512GW, 01GW, 01JW and 02JW ECC information
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56568
+    - iommu/arm-smmu: Defer probe of clients after smmu device bound
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56772
+    - kunit: string-stream: Fix a UAF bug in kunit_init_suite()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56773
+    - kunit: Fix potential null dereference in kunit_device_driver_test()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56580
+    - media: qcom: camss: fix error path on configuration of power domains
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57850
+    - jffs2: Prevent rtime decompress memory corruption
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56583
+    - sched/deadline: Fix warning in migrate_enable for boosted tasks
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56611
+    - mm/mempolicy: fix migrate_to_node() assuming there is at least one VMA in a
+      MM
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56613
+    - sched/numa: fix memory leak due to the overwritten vma->numab_state
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56584
+    - io_uring/tctx: work around xa_store() allocation error issue
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56781
+    - powerpc/prom_init: Fixup missing powermac #size-cells
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56785
+    - MIPS: Loongson64: DTS: Really fix PCIe port nodes for ls7a
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56585
+    - LoongArch: Fix sleeping in atomic context for PREEMPT_RT
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-41935
+    - f2fs: fix to shrink read extent node in batches
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-43098
+    - i3c: Use i3cdev->desc->info instead of calling i3c_device_get_info() to
+      avoid deadlock
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-45828
+    - i3c: mipi-i3c-hci: Mask ring interrupts before ring stop request
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56586
+    - f2fs: fix f2fs_bug_on when uninstalling filesystem call f2fs_evict_inode.
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56587
+    - leds: class: Protect brightness_show() with led_cdev->led_access mutex
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56786
+    - bpf: put bpf_link's program when link is safe to be deallocated
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-47141
+    - pinmux: Use sequential access to access desc->pinmux data
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56589
+    - scsi: hisi_sas: Add cond_resched() for no forced preemption model
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56590
+    - Bluetooth: hci_core: Fix not checking skb length on hci_acldata_packet
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56592
+    - bpf: Call free_htab_elem() after htab_unlock_bucket()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56593
+    - wifi: brcmfmac: Fix oops due to NULL pointer dereference in
+      brcmf_sdiod_sglist_rw()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56594
+    - drm/amdgpu: set the right AMDGPU sg segment limitation
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57843
+    - virtio-net: fix overflow inside virtnet_rq_alloc
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56596
+    - jfs: fix array-index-out-of-bounds in jfs_readdir
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56597
+    - jfs: fix shift-out-of-bounds in dbSplit
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-47143
+    - dma-debug: fix a possible deadlock on radix_lock
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56601
+    - net: inet: do not leave a dangling sk pointer in inet_create()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56602
+    - net: ieee802154: do not leave a dangling sk pointer in ieee802154_create()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56603
+    - net: af_can: do not leave a dangling sk pointer in can_create()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56604
+    - Bluetooth: RFCOMM: avoid leaving dangling sk pointer in rfcomm_sock_alloc()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56605
+    - Bluetooth: L2CAP: do not leave dangling sk pointer on error in
+      l2cap_sock_create()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56606
+    - af_packet: avoid erroring out after sock_init_data() in packet_create()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-47809
+    - dlm: fix possible lkb_resource null dereference
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-48873
+    - wifi: rtw89: check return value of ieee80211_probereq_get() for RNR
+  * Missing support for USB-C Apple Magic Trackpad (LP: #2098063) // Noble
+    update: upstream stable patchset 2025-03-12 (LP: #2102118)
+    - HID: magicmouse: Apple Magic Trackpad 2 USB-C driver support
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56787
+    - soc: imx8m: Probe the SoC driver as platform driver
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56610
+    - kcsan: Turn report_filterlist_lock into a raw_spinlock
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-48875
+    - btrfs: don't take dev_replace rwsem on task already holding it
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57849
+    - s390/cpum_sf: Handle CPU hotplug remove during sampling
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57876
+    - drm/dp_mst: Fix resetting msg rx state after topology removal
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56616
+    - drm/dp_mst: Fix MST sideband message body length check
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-48881
+    - bcache: revert replacing IS_ERR_OR_NULL with IS_ERR again
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56619
+    - nilfs2: fix potential out-of-bounds memory access in nilfs_find_entry()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56622
+    - scsi: ufs: core: sysfs: Prevent div by zero
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56623
+    - scsi: qla2xxx: Fix use after free on unload
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-57874
+    - arm64: ptrace: fix partial SETREGSET for NT_ARM_TAGGED_ADDR_CTRL
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56625
+    - can: dev: can_set_termination(): allow sleeping GPIOs
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56626
+    - ksmbd: fix Out-of-Bounds Write in ksmbd_vfs_stream_write
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56628
+    - LoongArch: Add architecture specific huge_pte_clear()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56629
+    - HID: wacom: fix when get product name maybe null pointer
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56630
+    - ocfs2: free inode when ocfs2_get_init_inode() fails
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56631
+    - scsi: sg: Fix slab-use-after-free read in sg_release()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-50051
+    - spi: mpc52xx: Add cancel_work_sync before module remove
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56633
+    - tcp_bpf: Fix the sk_mem_uncharge logic in tcp_bpf_sendmsg
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56565
+    - f2fs: fix to drop all discards after creating snapshot on lvm device
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56634
+    - gpio: grgpio: Add NULL check in grgpio_probe
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56635
+    - net: avoid potential UAF in default_operstate()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56636
+    - geneve: do not assume mac header is set in geneve_xmit_skb()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56637
+    - netfilter: ipset: Hold module reference while requesting a module
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56638
+    - netfilter: nft_inner: incorrect percpu area handling under softirq
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-52332
+    - igb: Fix potential invalid memory access in igb_init_module()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56640
+    - net/smc: fix LGR and link use-after-free issue
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56641
+    - net/smc: initialize close_work early to avoid warning
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56643
+    - dccp: Fix memory leak in dccp_feat_change_recv
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56644
+    - net/ipv6: release expired exception dst cached in socket
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56645
+    - can: j1939: j1939_session_new(): fix skb reference counting
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56648
+    - net: hsr: avoid potential out-of-bound access in fill_frame_info()
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56649
+    - net: enetc: Do not configure preemptible TCs if SIs do not support
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56783
+    - netfilter: nft_socket: remove WARN_ON_ONCE on maximum cgroup level
+  * Noble update: upstream stable patchset 2025-03-12 (LP: #2102118) //
+    CVE-2024-56650
+    - netfilter: x_tables: fix LED ID check in led_tg_check()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915)
+    - wifi: radiotap: Avoid -Wflex-array-member-not-at-end warnings
+    - ASoC: codecs: rt5640: Always disable IRQs from rt5640_cancel_work()
+    - ASoC: Intel: bytcr_rt5640: Add support for non ACPI instantiated codec
+    - ASoC: Intel: bytcr_rt5640: Add DMI quirk for Vexia Edu Atla 10 tablet
+    - ASoC: Intel: sst: Support LPE0F28 ACPI HID
+    - wifi: iwlwifi: mvm: Use the sync timepoint API in suspend
+    - mac80211: fix user-power when emulating chanctx
+    - usb: add support for new USB device ID 0x17EF:0x3098 for the r8152 driver
+    - selftests/watchdog-test: Fix system accidentally reset after watchdog-test
+    - ALSA: hda/realtek: Add subwoofer quirk for Infinix ZERO BOOK 13
+    - x86/amd_nb: Fix compile-testing without CONFIG_AMD_NB
+    - bpf: fix filed access without lock
+    - net: usb: qmi_wwan: add Quectel RG650V
+    - soc: qcom: Add check devm_kasprintf() returned value
+    - firmware: arm_scmi: Reject clear channel request on A2P
+    - regulator: rk808: Add apply_bit for BUCK3 on RK809
+    - platform/x86: dell-smbios-base: Extends support to Alienware products
+    - platform/x86: dell-wmi-base: Handle META key Lock/Unlock events
+    - ASoC: tas2781: Add new driver version for tas2563 & tas2781 qfn chip
+    - tools/lib/thermal: Remove the thermal.h soft link when doing make clean
+    - can: j1939: fix error in J1939 documentation.
+    - platform/x86: thinkpad_acpi: Fix for ThinkPad's with ECFW showing incorrect
+      fan speed
+    - ASoC: amd: yc: Support dmic on another model of Lenovo Thinkpad E14 Gen 6
+    - ASoC: stm: Prevent potential division by zero in stm32_sai_mclk_round_rate()
+    - ASoC: stm: Prevent potential division by zero in stm32_sai_get_clk_div()
+    - drm: panel-orientation-quirks: Make Lenovo Yoga Tab 3 X90F DMI match less
+      strict
+    - proc/softirqs: replace seq_printf with seq_put_decimal_ull_width
+    - ASoC: audio-graph-card2: Purge absent supplies for device tree nodes
+    - LoongArch: Define a default value for VM_DATA_DEFAULT_FLAGS
+    - ALSA: usb-audio: Fix Yamaha P-125 Quirk Entry
+    - ARM: 9420/1: smp: Fix SMP for xip kernels
+    - ipmr: Fix access to mfc_cache_list without lock held
+    - mptcp: fix possible integer overflow in mptcp_reset_tout_timer
+    - arm64: probes: Disable kprobes/uprobes on MOPS instructions
+    - kselftest/arm64: mte: fix printf type warnings about __u64
+    - kselftest/arm64: mte: fix printf type warnings about longs
+    - s390/cio: Do not unregister the subchannel based on DNV
+    - s390/pageattr: Implement missing kernel_page_present()
+    - ext4: avoid remount errors with 'abort' mount option
+    - mips: asm: fix warning when disabling MIPS_FP_SUPPORT
+    - m68k: mvme147: Fix SCSI controller IRQ numbers
+    - m68k: mvme147: Reinstate early console
+    - arm64: fix .data.rel.ro size assertion when CONFIG_LTO_CLANG
+    - acpi/arm64: Adjust error handling procedure in gtdt_parse_timer_block()
+    - cachefiles: Fix missing pos updates in cachefiles_ondemand_fd_write_iter()
+    - block: fix bio_split_rw_at to take zone_write_granularity into account
+    - s390/syscalls: Avoid creation of arch/arch/ directory
+    - ext4: remove calls to to set/clear the folio error flag
+    - ext4: pipeline buffer reads in mext_page_mkuptodate()
+    - ext4: remove array of buffer_heads from mext_page_mkuptodate()
+    - ext4: fix race in buffer_head read fault injection
+    - nvme-pci: reverse request order in nvme_queue_rqs
+    - virtio_blk: reverse request order in virtio_queue_rqs
+    - crypto: qat - remove check after debugfs_create_dir()
+    - firmware: google: Unregister driver_info on failure
+    - crypto: qat - remove faulty arbiter config reset
+    - thermal: core: Initialize thermal zones before registering them
+    - EDAC/fsl_ddr: Fix bad bit shift operations
+    - EDAC/skx_common: Differentiate memory error sources
+    - EDAC/{skx_common,i10nm}: Fix incorrect far-memory error source indicator
+    - crypto: cavium - Fix the if condition to exit loop after timeout
+    - amd-pstate: Set min_perf to nominal_perf for active mode performance gov
+    - crypto: hisilicon/qm - disable same error report before resetting
+    - crypto: inside-secure - Fix the return value of safexcel_xcbcmac_cra_init()
+    - doc: rcu: update printed dynticks counter bits
+    - hwmon: (pmbus_core) Allow to hook PMBUS_SMBALERT_MASK
+    - hwmon: (pmbus/core) clear faults after setting smbalert mask
+    - hwmon: (nct6775-core) Fix overflows seen when writing limit attributes
+    - ACPI: CPPC: Fix _CPC register setting issue
+    - crypto: caam - add error check to caam_rsa_set_priv_key_form
+    - crypto: cavium - Fix an error handling path in cpt_ucode_load_fw()
+    - rcuscale: Do a proper cleanup if kfree_scale_init() fails
+    - tools/lib/thermal: Make more generic the command encoding function
+    - thermal/lib: Fix memory leak on error in thermal_genl_auto()
+    - x86/unwind/orc: Fix unwind for newly forked tasks
+    - time: Partially revert cleanup on msecs_to_jiffies() documentation
+    - time: Fix references to _msecs_to_jiffies() handling of values
+    - kcsan, seqlock: Support seqcount_latch_t
+    - kcsan, seqlock: Fix incorrect assumption in read_seqbegin()
+    - clocksource/drivers:sp804: Make user selectable
+    - clocksource/drivers/timer-ti-dm: Fix child node refcount handling
+    - spi: spi-fsl-lpspi: Use IRQF_NO_AUTOEN flag in request_irq()
+    - microblaze: Export xmb_manager functions
+    - arm64: dts: mt8195: Fix dtbs_check error for mutex node
+    - arm64: dts: mt8195: Fix dtbs_check error for infracfg_ao node
+    - soc: ti: smartreflex: Use IRQF_NO_AUTOEN flag in request_irq()
+    - arm64: dts: qcom: sm6350: Fix GPU frequencies missing on some speedbins
+    - ARM: dts: microchip: sam9x60: Add missing property atmel,usart-mode
+    - mmc: mmc_spi: drop buggy snprintf()
+    - openrisc: Implement fixmap to fix earlycon
+    - efi/libstub: fix efi_parse_options() ignoring the default command line
+    - tpm: fix signed/unsigned bug when checking event logs
+    - media: i2c: ds90ub960: Fix missing return check on ub960_rxport_read call
+    - arm64: dts: mt8183: krane: Fix the address of eeprom at i2c4
+    - arm64: dts: mt8183: kukui: Fix the address of eeprom at i2c4
+    - arm64: dts: mediatek: mt8173-elm-hana: Add vdd-supply to second source
+      trackpad
+    - Revert "cgroup: Fix memory leak caused by missing cgroup_bpf_offline"
+    - cgroup/bpf: only cgroup v2 can be attached by bpf programs
+    - regulator: rk808: Restrict DVS GPIOs to the RK808 variant only
+    - arm64: dts: mt8183: fennel: add i2c2's i2c-scl-internal-delay-ns
+    - arm64: dts: mt8183: burnet: add i2c2's i2c-scl-internal-delay-ns
+    - arm64: dts: mt8183: cozmo: add i2c2's i2c-scl-internal-delay-ns
+    - arm64: dts: mt8183: Damu: add i2c2's i2c-scl-internal-delay-ns
+    - pwm: imx27: Workaround of the pwm output bug when decrease the duty cycle
+    - ARM: dts: cubieboard4: Fix DCDC5 regulator constraints
+    - arm64: dts: ti: k3-j7200: use ti,j7200-padconf compatible
+    - arm64: dts: ti: k3-j7200: Fix register map for main domain pmx
+    - arm64: dts: ti: k3-j7200: Fix clock ids for MCSPI instances
+    - arm64: dts: ti: k3-j721e: Fix clock IDs for MCSPI instances
+    - arm64: dts: ti: k3-j721s2: Fix clock IDs for MCSPI instances
+    - um: Unconditionally call unflatten_device_tree()
+    - x86/of: Unconditionally call unflatten_and_copy_device_tree()
+    - of/fdt: add dt_phys arg to early_init_dt_scan and early_init_dt_verify
+    - riscv: Fix wrong usage of __pa() on a fixmap address
+    - pmdomain: ti-sci: Add missing of_node_put() for args.np
+    - spi: tegra210-quad: Avoid shift-out-of-bounds
+    - spi: zynqmp-gqspi: Undo runtime PM changes at driver exit time​
+    - regmap: irq: Set lockdep class for hierarchical IRQ domains
+    - arm64: dts: renesas: hihope: Drop #sound-dai-cells
+    - arm64: dts: mediatek: Add ADC node on MT6357, MT6358, MT6359 PMICs
+    - arm64: dts: mediatek: mt6358: fix dtbs_check error
+    - arm64: dts: mediatek: mt8183-kukui-jacuzzi: Fix DP bridge supply names
+    - arm64: dts: mediatek: mt8183-kukui-jacuzzi: Add supplies for fixed
+      regulators
+    - selftests/resctrl: Split fill_buf to allow tests finer-grained control
+    - selftests/resctrl: Refactor fill_buf functions
+    - selftests/resctrl: Fix memory overflow due to unhandled wraparound
+    - selftests/resctrl: Protect against array overrun during iMC config parsing
+    - arm64: dts: rockchip: correct analog audio name on Indiedroid Nova
+    - platform/x86: panasonic-laptop: Return errno correctly in show callback
+    - drm/mm: Mark drm_mm_interval_tree*() functions with __maybe_unused
+    - drm/vc4: hvs: Don't write gamma luts on 2711
+    - drm/vc4: hvs: Fix dlist debug not resetting the next entry pointer
+    - drm/vc4: hvs: Remove incorrect limit from hvs_dlist debugfs function
+    - drm/vc4: hvs: Correct logic on stopping an HVS channel
+    - drm/omap: Fix possible NULL dereference
+    - drm/omap: Fix locking in omap_gem_new_dmabuf()
+    - wifi: p54: Use IRQF_NO_AUTOEN flag in request_irq()
+    - wifi: mwifiex: Use IRQF_NO_AUTOEN flag in request_irq()
+    - drm/imx/dcss: Use IRQF_NO_AUTOEN flag in request_irq()
+    - drm/imx/ipuv3: Use IRQF_NO_AUTOEN flag in request_irq()
+    - drm/v3d: Address race-condition in MMU flush
+    - wifi: ath10k: fix invalid VHT parameters in supported_vht_mcs_rate_nss1
+    - wifi: ath10k: fix invalid VHT parameters in supported_vht_mcs_rate_nss2
+    - dt-bindings: vendor-prefixes: Add NeoFidelity, Inc
+    - ASoC: fsl_micfil: fix regmap_write_bits usage
+    - ASoC: dt-bindings: mt6359: Update generic node name and dmic-mode
+    - drm/bridge: anx7625: Drop EDID cache on bridge power off
+    - drm/bridge: it6505: Drop EDID cache on bridge power off
+    - libbpf: Fix expected_attach_type set handling in program load callback
+    - libbpf: Fix output .symtab byte-order during linking
+    - bpf: Fix the xdp_adjust_tail sample prog issue
+    - wifi: ath11k: Fix CE offset address calculation for WCN6750 in SSR
+    - ice: consistently use q_idx in ice_vc_cfg_qs_msg()
+    - drm/vc4: Match drm_dev_enter and exit calls in vc4_hvs_atomic_flush
+    - libbpf: fix sym_is_subprog() logic for weak global subprogs
+    - ASoC: rt722-sdca: Remove logically deadcode in rt722-sdca.c
+    - libbpf: never interpret subprogs in .text as entry programs
+    - netdevsim: copy addresses for both in and out paths
+    - drm/bridge: tc358767: Fix link properties discovery
+    - selftests/bpf: Fix msg_verify_data in test_sockmap
+    - selftests/bpf: Fix txmsg_redir of test_txmsg_pull in test_sockmap
+    - drm: fsl-dcu: enable PIXCLK on LS1021A
+    - drm/msm/dpu: on SDM845 move DSPP_3 to LM_5 block
+    - drm/msm/dpu: drop LM_3 / LM_4 on SDM845
+    - drm/msm/dpu: drop LM_3 / LM_4 on MSM8998
+    - selftests/bpf: fix test_spin_lock_fail.c's global vars usage
+    - drm/panfrost: Remove unused id_mask from struct panfrost_model
+    - bpf, arm64: Remove garbage frame for struct_ops trampoline
+    - drm/msm/adreno: Use IRQF_NO_AUTOEN flag in request_irq()
+    - drm/msm/gpu: Check the status of registration to PM QoS
+    - drm/etnaviv: Request pages from DMA32 zone on addressing_limited
+    - drm/etnaviv: hold GPU lock across perfmon sampling
+    - wifi: wfx: Fix error handling in wfx_core_init()
+    - drm/msm/dpu: cast crtc_clk calculation to u64 in _dpu_core_perf_calc_clk()
+    - bpf, bpftool: Fix incorrect disasm pc
+    - drm/vkms: Drop unnecessary call to drm_crtc_cleanup()
+    - drm: use ATOMIC64_INIT() for atomic64_t
+    - netfilter: nf_tables: avoid false-positive lockdep splat on rule deletion
+    - netfilter: nf_tables: must hold rcu read lock while iterating expression
+      type list
+    - netfilter: nf_tables: skip transaction if update object is not implemented
+    - netfilter: nf_tables: must hold rcu read lock while iterating object type
+      list
+    - netlink: typographical error in nlmsg_type constants definition
+    - selftests/bpf: Add txmsg_pass to pull/push/pop in test_sockmap
+    - selftests/bpf: Fix SENDPAGE data logic in test_sockmap
+    - selftests/bpf: Fix total_bytes in msg_loop_rx in test_sockmap
+    - selftests/bpf: Add push/pop checking for msg_verify_data in test_sockmap
+    - bpf, sockmap: Several fixes to bpf_msg_push_data
+    - bpf, sockmap: Fix sk_msg_reset_curr
+    - sock_diag: add module pointer to "struct sock_diag_handler"
+    - sock_diag: allow concurrent operations
+    - sock_diag: allow concurrent operation in sock_diag_rcv_msg()
+    - net: use unrcu_pointer() helper
+    - selftests: net: really check for bg process completion
+    - drm/amdkfd: Fix wrong usage of INIT_WORK()
+    - bpf: Force uprobe bpf program to always return 0
+    - net: rfkill: gpio: Add check for clk_enable()
+    - netpoll: Use rcu_access_pointer() in netpoll_poll_lock
+    - wireguard: selftests: load nf_conntrack if not present
+    - cppc_cpufreq: Use desired perf if feedback ctrs are 0 or unchanged
+    - clk: mediatek: drop two dead config options
+    - [Config] drop COMMON_CLK_MT8195_AUDSYS and COMMON_CLK_MT8195_MSDC
+    - trace/trace_event_perf: remove duplicate samples on the first tracepoint
+      event
+    - pinctrl: zynqmp: drop excess struct member description
+    - scsi: hisi_sas: Enable all PHYs that are not disabled by user during
+      controller reset
+    - mfd: tps65010: Use IRQF_NO_AUTOEN flag in request_irq() to fix race
+    - mfd: da9052-spi: Change read-mask to write-mask
+    - cpufreq: loongson2: Unregister platform_driver on failure
+    - powerpc/fadump: Refactor and prepare fadump_cma_init for late init
+    - mtd: hyperbus: rpc-if: Add missing MODULE_DEVICE_TABLE
+    - mtd: rawnand: atmel: Fix possible memory leak
+    - mtd: rawnand: fix double free in atmel_pmecc_create_user()
+    - mtd: spi-nor: spansion: Use nor->addr_nbytes in octal DTR mode in
+      RD_ANY_REG_OP
+    - RDMA/hns: Fix an AEQE overflow error caused by untimely update of eq_db_ci
+    - RDMA/hns: Use dev_* printings in hem code instead of ibdev_*
+    - RDMA/bnxt_re: Check cqe flags to know imm_data vs inv_irkey
+    - clk: sunxi-ng: d1: Fix PLL_AUDIO0 preset
+    - clk: renesas: rzg2l: Fix FOUTPOSTDIV clk
+    - RDMA/rxe: Set queue pair cur_qp_state when being queried
+    - RISC-V: KVM: Fix APLIC in_clrip and clripnum write emulation
+    - clk: imx: lpcg-scu: SW workaround for errata (e10858)
+    - clk: imx: fracn-gppll: correct PLL initialization flow
+    - clk: imx: fracn-gppll: fix pll power up
+    - clk: imx: clk-scu: fix clk enable state save and restore
+    - clk: imx: imx8-acm: Fix return value check in
+      clk_imx_acm_attach_pm_domains()
+    - iommu/vt-d: Fix checks and print in dmar_fault_dump_ptes()
+    - iommu/vt-d: Fix checks and print in pgtable_walk()
+    - checkpatch: check for missing Fixes tags
+    - checkpatch: always parse orig_commit in fixes tag
+    - mfd: rt5033: Fix missing regmap_del_irq_chip()
+    - fs/proc/kcore.c: fix coccinelle reported ERROR instances
+    - scsi: fusion: Remove unused variable 'rc'
+    - scsi: sg: Enable runtime power management
+    - x86/tdx: Introduce wrappers to read and write TD metadata
+    - x86/tdx: Rename tdx_parse_tdinfo() to tdx_setup()
+    - x86/tdx: Dynamically disable SEPT violations from causing #VEs
+    - RDMA/hns: Fix out-of-order issue of requester when setting FENCE
+    - cpufreq: CPPC: Fix wrong return value in cppc_get_cpu_cost()
+    - cpufreq: CPPC: Fix wrong return value in cppc_get_cpu_power()
+    - dax: delete a stale directory pmem
+    - KVM: PPC: Book3S HV: Stop using vc->dpdes for nested KVM guests
+    - KVM: PPC: Book3S HV: Avoid returning to nested hypervisor on pending
+      doorbells
+    - powerpc/sstep: make emulate_vsx_load and emulate_vsx_store static
+    - powerpc/kexec: Fix return of uninitialized variable
+    - IB/mlx5: Allocate resources just before first QP/SRQ is created
+    - clk: ralink: mtmips: fix clock plan for Ralink SoC RT3883
+    - clk: ralink: mtmips: remove duplicated 'xtal' clock for Ralink SoC RT3883
+    - dt-bindings: clock: axi-clkgen: include AXI clk
+    - clk: clk-axi-clkgen: make sure to enable the AXI bus clock
+    - arm64: dts: qcom: sc8180x: Add a SoC-specific compatible to cpufreq-hw
+    - pinctrl: k210: Undef K210_PC_DEFAULT
+    - smb: cached directories can be more than root file handle
+    - mailbox: arm_mhuv2: clean up loop in get_irq_chan_comb()
+    - perf cs-etm: Don't flush when packet_queue fills up
+    - gfs2: Get rid of gfs2_glock_queue_put in signal_our_withdraw
+    - gfs2: Replace gfs2_glock_queue_put with gfs2_glock_put_async
+    - gfs2: Rename GLF_VERIFY_EVICT to GLF_VERIFY_DELETE
+    - gfs2: Allow immediate GLF_VERIFY_DELETE work
+    - gfs2: Fix unlinked inode cleanup
+    - perf stat: Close cork_fd when create_perf_stat_counter() failed
+    - perf stat: Fix affinity memory leaks on error path
+    - perf trace: Keep exited threads for summary
+    - perf test attr: Add back missing topdown events
+    - f2fs: compress: fix inconsistent update of i_blocks in
+      release_compress_blocks and reserve_compress_blocks
+    - perf probe: Fix libdw memory leak
+    - perf probe: Correct demangled symbols in C++ program
+    - rust: macros: fix documentation of the paste! macro
+    - PCI: cpqphp: Use PCI_POSSIBLE_ERROR() to check config reads
+    - PCI: cpqphp: Fix PCIBIOS_* return value confusion
+    - perf ftrace latency: Fix unit on histogram first entry when using --use-nsec
+    - f2fs: fix the wrong f2fs_bug_on condition in f2fs_do_replace_block
+    - f2fs: check curseg->inited before write_sum_page in change_curseg
+    - f2fs: fix to avoid use GC_AT when setting gc_mode as GC_URGENT_LOW or
+      GC_URGENT_MID
+    - PCI: cadence: Extract link setup sequence from cdns_pcie_host_setup()
+    - PCI: cadence: Set cdns_pcie_host_init() global
+    - PCI: j721e: Add reset GPIO to struct j721e_pcie
+    - PCI: j721e: Use T_PERST_CLK_US macro
+    - PCI: j721e: Add suspend and resume support
+    - PCI: j721e: Deassert PERST# after a delay of PCIE_T_PVPERL_MS milliseconds
+    - f2fs: fix to avoid forcing direct write to use buffered IO on inline_data
+      inode
+    - perf trace: avoid garbage when not printing a trace event's arguments
+    - m68k: mcfgpio: Fix incorrect register offset for CONFIG_M5441x
+    - m68k: coldfire/device.c: only build FEC when HW macros are defined
+    - perf list: Fix topic and pmu_name argument order
+    - perf trace: Fix tracing itself, creating feedback loops
+    - perf trace: Do not lose last events in a race
+    - perf trace: Avoid garbage when not printing a syscall's arguments
+    - remoteproc: qcom: pas: add minidump_id to SM8350 resources
+    - rpmsg: glink: use only lower 16-bits of param2 for CMD_OPEN name length
+    - remoteproc: qcom_q6v5_mss: Re-order writes to the IMEM region
+    - nfsd: restore callback functionality for NFSv4.0
+    - NFSD: Cap the number of bytes copied by nfs4_reset_recoverydir()
+    - NFSD: Fix nfsd4_shutdown_copy()
+    - hwmon: (tps23861) Fix reporting of negative temperatures
+    - vdpa/mlx5: Fix suboptimal range on iotlb iteration
+    - selftests/mount_setattr: Fix failures on 64K PAGE_SIZE kernels
+    - gpio: zevio: Add missed label initialisation
+    - fs_parser: update mount_api doc to match function signature
+    - LoongArch: Fix build failure with GCC 15 (-std=gnu23)
+    - LoongArch: BPF: Sign-extend return values
+    - power: supply: core: Remove might_sleep() from power_supply_put()
+    - power: supply: bq27xxx: Fix registers of bq27426
+    - power: supply: rt9471: Fix wrong WDT function regfield declaration
+    - power: supply: rt9471: Use IC status regfield to report real charger status
+    - net: usb: lan78xx: Fix memory leak on device unplug by freeing PHY device
+    - tg3: Set coherent DMA mask bits to 31 for BCM57766 chipsets
+    - net: usb: lan78xx: Fix refcounting and autosuspend on invalid WoL
+      configuration
+    - net: microchip: vcap: Add typegroup table terminators in kunit tests
+    - net/ipv6: delete temporary address if mngtmpaddr is removed or unmanaged
+    - net: mdio-ipq4019: add missing error check
+    - marvell: pxa168_eth: fix call balance of pep->clk handling routines
+    - net: stmmac: dwmac-socfpga: Set RX watchdog interrupt as broken
+    - octeontx2-af: RPM: Fix mismatch in lmac type
+    - octeontx2-af: RPM: Fix low network performance
+    - octeontx2-pf: Reset MAC stats during probe
+    - octeontx2-af: RPM: fix stale RSFEC counters
+    - octeontx2-af: RPM: fix stale FCFEC counters
+    - octeontx2-af: Quiesce traffic before NIX block reset
+    - spi: atmel-quadspi: Fix register name in verbose logging function
+    - net: hsr: fix hsr_init_sk() vs network/transport headers.
+    - bnxt_en: Reserve rings after PCIe AER recovery if NIC interface is down
+    - bnxt_en: Refactor bnxt_ptp_init()
+    - bnxt_en: Unregister PTP during PCI shutdown and suspend
+    - llc: Improve setsockopt() handling of malformed user input
+    - rxrpc: Improve setsockopt() handling of malformed user input
+    - tcp: Fix use-after-free of nreq in reqsk_timer_handler().
+    - ip6mr: fix tables suspicious RCU usage
+    - ipmr: fix tables suspicious RCU usage
+    - iio: light: al3010: Fix an error handling path in al3010_probe()
+    - usb: using mutex lock and supporting O_NONBLOCK flag in iowarrior_read()
+    - usb: yurex: make waiting on yurex_write interruptible
+    - USB: chaoskey: fail open after removal
+    - USB: chaoskey: Fix possible deadlock chaoskey_list_lock
+    - misc: apds990x: Fix missing pm_runtime_disable()
+    - counter: stm32-timer-cnt: Add check for clk_enable()
+    - counter: ti-ecap-capture: Add check for clk_enable()
+    - ALSA: hda/realtek: Update ALC256 depop procedure
+    - drm/radeon: add helper rdev_to_drm(rdev)
+    - drm/radeon: change rdev->ddev to rdev_to_drm(rdev)
+    - drm/radeon: Fix spurious unplug event on radeon HDMI
+    - apparmor: fix 'Do simple duplicate message elimination'
+    - ASoC: amd: yc: Fix for enabling DMIC on acp6x via _DSD entry
+    - gfs2: Don't set GLF_LOCK in gfs2_dispose_glock_lru
+    - gfs2: Remove and replace gfs2_glock_queue_work
+    - f2fs: fix fiemap failure issue when page size is 16KB
+    - usb: ehci-spear: fix call balance of sehci clk handling routines
+    - ALSA: usb-audio: Fix a DMA to stack memory bug
+    - ASoC: Intel: sst: Fix used of uninitialized ctx to log an error
+    - soc: qcom: socinfo: fix revision check in qcom_socinfo_probe()
+    - ext4: supress data-race warnings in ext4_free_inodes_{count,set}()
+    - ext4: fix FS_IOC_GETFSMAP handling
+    - jfs: xattr: check invalid xattr size more strictly
+    - ASoC: amd: yc: Add a quirk for microfone on Lenovo ThinkPad P14s Gen 5
+      21MES00B00
+    - ASoC: codecs: Fix atomicity violation in snd_soc_component_get_drvdata()
+    - perf/x86/intel/pt: Fix buffer full but size is 0 case
+    - crypto: x86/aegis128 - access 32-bit arguments as 32-bit
+    - KVM: x86/mmu: Skip the "try unsync" path iff the old SPTE was a leaf SPTE
+    - powerpc/pseries: Fix KVM guest detection for disabling hardlockup detector
+    - KVM: arm64: vgic-v3: Sanitise guest writes to GICR_INVLPIR
+    - KVM: arm64: Ignore PMCNTENSET_EL0 while checking for overflow status
+    - KVM: arm64: vgic-its: Clear ITE when DISCARD frees an ITE
+    - KVM: arm64: vgic-its: Add a data length check in vgic_its_save_*
+    - KVM: arm64: vgic-its: Clear DTE when MAPD unmaps a device
+    - fsnotify: fix sending inotify event with unexpected filename
+    - tty: ldsic: fix tty_ldisc_autoload sysctl's proc_handler
+    - locking/lockdep: Avoid creating new name string literals in
+      lockdep_set_subclass()
+    - tools/nolibc: s390: include std.h
+    - pinctrl: qcom: spmi: fix debugfs drive strength
+    - dt-bindings: iio: dac: ad3552r: fix maximum spi speed
+    - exfat: fix uninit-value in __exfat_get_dentry_set
+    - Bluetooth: Fix type of len in rfcomm_sock_getsockopt{,_old}()
+    - Compiler Attributes: disable __counted_by for clang < 19.1.3
+    - usb: xhci: Fix TD invalidation under pending Set TR Dequeue
+    - ARM: dts: omap36xx: declare 1GHz OPP as turbo again
+    - wifi: brcmfmac: release 'root' node in all execution paths
+    - Revert "usb: gadget: composite: fix OS descriptors w_value logic"
+    - gpio: exar: set value when external pull-up or pull-down is present
+    - spi: Fix acpi deferred irq probe
+    - cpufreq: mediatek-hw: Fix wrong return value in mtk_cpufreq_get_cpu_power()
+    - cifs: support mounting with alternate password to allow password rotation
+    - parisc/ftrace: Fix function graph tracing disablement
+    - platform/chrome: cros_ec_typec: fix missing fwnode reference decrement
+    - ubi: wl: Put source PEB into correct list if trying locking LEB failed
+    - dt-bindings: serial: rs485: Fix rs485-rts-delay property
+    - serial: 8250_fintek: Add support for F81216E
+    - serial: 8250: omap: Move pm_runtime_get_sync
+    - iio: gts: Fix uninitialized symbol 'ret'
+    - ublk: fix ublk_ch_mmap() for 64K page size
+    - arm64: tls: Fix context-switching of tpidrro_el0 when kpti is enabled
+    - block: fix missing dispatching request when queue is started or unquiesced
+    - block: fix ordering between checking QUEUE_FLAG_QUIESCED request adding
+    - block: fix ordering between checking BLK_MQ_S_STOPPED request adding
+    - blk-mq: Make blk_mq_quiesce_tagset() hold the tag list mutex less long
+    - HID: wacom: Interpret tilt data from Intuos Pro BT as signed values
+    - soc: fsl: rcpm: fix missing of_node_put() in copy_ippdexpcr1_setting()
+    - media: v4l2-core: v4l2-dv-timings: check cvt/gtf result
+    - ALSA: ump: Fix evaluation of MIDI 1.0 FB info
+    - ALSA: hda/realtek: Update ALC225 depop procedure
+    - ALSA: hda/realtek: Fixup ALC225 depop procedure
+    - ALSA: hda/realtek: Set PCBeep to default value for ALC274
+    - ALSA: hda/realtek: Fix Internal Speaker and Mic boost of Infinix Y4 Max
+    - ALSA: hda/realtek: Apply quirk for Medion E15433
+    - smb3: request handle caching when caching directories
+    - smb: client: handle max length for SMB symlinks
+    - cifs: Add tracing for the cifs_tcon struct refcounting
+    - usb: dwc3: gadget: Fix checking for number of TRBs left
+    - ublk: fix error code for unsupported command
+    - lib: string_helpers: silence snprintf() output truncation warning
+    - um: Fix the return value of elf_core_copy_task_fpregs
+    - um: Always dump trace for specified task in show_stack
+    - rtc: st-lpc: Use IRQF_NO_AUTOEN flag in request_irq()
+    - rtc: abx80x: Fix WDT bit position of the status register
+    - ubi: fastmap: wl: Schedule fm_work if wear-leveling pool is empty
+    - ubifs: Correct the total block count by deducting journal reservation
+    - jffs2: fix use of uninitialized variable
+    - rtc: rzn1: fix BCD to rtc_time conversion errors
+    - nvme-multipath: prepare for "queue-depth" iopolicy
+    - nvme-multipath: implement "queue-depth" iopolicy
+    - nvme-multipath: avoid hang on inaccessible namespaces
+    - nvme/multipath: Fix RCU list traversal to use SRCU primitive
+    - block: return unsigned int from bdev_io_min
+    - 9p/xen: fix init sequence
+    - perf/arm-smmuv3: Fix lockdep assert in ->event_init()
+    - perf/arm-cmn: Ensure port and device id bits are set properly
+    - smb: client: disable directory caching when dir_cache_timeout is zero
+    - cifs: Fix parsing native symlinks relative to the export
+    - cifs: Fix parsing reparse point with native symlink in SMB1 non-UNICODE
+      session
+    - rtc: ab-eoz9: don't fail temperature reads on undervoltage notification
+    - init/modpost: conditionally check section mismatch to __meminit*
+    - Rename .data.unlikely to .data..unlikely
+    - Rename .data.once to .data..once to fix resetting WARN*_ONCE
+    - modpost: remove incorrect code in do_eisa_entry()
+    - cifs: during remount, make sure passwords are in sync
+    - cifs: unlock on error in smb3_reconfigure()
+    - nfs: ignore SB_RDONLY when mounting nfs
+    - SUNRPC: timeout and cancel TLS handshake with -ETIMEDOUT
+    - xfs: remove unknown compat feature check in superblock write validation
+    - btrfs: don't loop for nowait writes when checking for cross references
+    - md/md-bitmap: Add missing destroy_work_on_stack()
+    - arm64: dts: allwinner: pinephone: Add mount matrix to accelerometer
+    - arm64: dts: freescale: imx8mm-verdin: Fix SD regulator startup delay
+    - arm64: dts: ti: k3-am62-verdin: Fix SD regulator startup delay
+    - media: i2c: dw9768: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - arm64: dts: freescale: imx8mp-verdin: Fix SD regulator startup delay
+    - media: imx-jpeg: Fix potential error pointer dereference in detach_pm()
+    - media: verisilicon: av1: Fix reference video buffer pointer assignment
+    - media: platform: exynos4-is: Fix an OF node reference leak in
+      fimc_md_is_isp_available
+    - media: amphion: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - media: venus: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - media: gspca: ov534-ov772x: Fix off-by-one error in set_frame_rate()
+    - media: uvcvideo: Stop stream during unregister
+    - maple_tree: refine mas_store_root() on storing NULL
+    - vmstat: call fold_vm_zone_numa_events() before show per zone NUMA event
+    - zram: clear IDLE flag after recompression
+    - iommu/io-pgtable-arm: Fix stage-2 map/unmap for concatenated tables
+    - leds: lp55xx: Remove redundant test for invalid channel number
+    - clk: qcom: gcc-qcs404: fix initial rate of GPLL3
+    - ARM: 9429/1: ioremap: Sync PGDs for VMALLOC shadow
+    - ARM: 9430/1: entry: Do a dummy read from VMAP shadow
+    - ARM: 9431/1: mm: Pair atomic_set_release() with _read_acquire()
+    - ceph: extract entity name from device id
+    - util_macros.h: fix/rework find_closest() macros
+    - scsi: ufs: exynos: Fix hibern8 notify callbacks
+    - i3c: master: svc: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - PCI: keystone: Set mode as Root Complex for "ti,keystone-pcie" compatible
+    - PCI: keystone: Add link up check to ks_pcie_other_map_bus()
+    - PCI: endpoint: Clear secondary (not primary) EPC in pci_epc_remove_epf()
+    - fs/proc/kcore.c: Clear ret value in read_kcore_iter after successful
+      iov_iter_zero
+    - thermal: int3400: Fix reading of current_uuid for active policy
+    - leds: flash: mt6360: Fix device_for_each_child_node() refcounting in error
+      paths
+    - ovl: properly handle large files in ovl_security_fileattr
+    - dm: Fix typo in error message
+    - dm thin: Add missing destroy_work_on_stack()
+    - PCI: of_property: Assign PCI instead of CPU bus address to dynamic PCI nodes
+    - PCI: rockchip-ep: Fix address translation unit programming
+    - iio: accel: kx022a: Fix raw read format
+    - iio: Fix fwnode_handle in __fwnode_iio_channel_get_by_name()
+    - iio: gts: fix infinite loop for gain_to_scaletables()
+    - powerpc: Fix stack protector Kconfig test for clang
+    - powerpc: Adjust adding stack protector flags to KBUILD_CLAGS for clang
+    - udmabuf: use vmf_insert_pfn and VM_PFNMAP for handling mmap
+    - drm/mediatek: Fix child node refcount handling in early exit
+    - drm/etnaviv: flush shader L1 cache after user commandstream
+    - drm: xlnx: zynqmp_dpsub: fix hotplug detection
+    - drm/amdkfd: Use the correct wptr size
+    - drm/amd/pm: update current_socclk and current_uclk in gpu_metrics on smu
+      v13.0.7
+    - posix-timers: Target group sigqueue to current task only if not exiting
+    - wifi: cfg80211: Add wiphy_delayed_work_pending()
+    - wifi: mac80211: Convert color collision detection to wiphy work
+    - spi: stm32: fix missing device mode capability in stm32mp25
+    - usb: typec: use cleanup facility for 'altmodes_node'
+    - platform/x86: ideapad-laptop: add missing Ideapad Pro 5 fn keys
+    - integrity: Avoid -Wflex-array-member-not-at-end warnings
+    - integrity: Use static_assert() to check struct sizes
+    - ASoC: max9768: Fix event generation for playback mute
+    - ARM: 9434/1: cfi: Fix compilation corner case
+    - drm/amd/display: Skip Invalid Streams from DSC Policy
+    - drm/amd/display: Fix DSC-re-computing
+    - drm/amd/display: Fix incorrect DSC recompute trigger
+    - s390/facilities: Fix warning about shadow of global variable
+    - cachefiles: Fix incorrect length return value in
+      cachefiles_ondemand_fd_write_iter()
+    - thermal: core: Drop thermal_zone_device_is_enabled()
+    - thermal: core: Synchronize suspend-prepare and post-suspend actions
+    - thermal: core: Rearrange PM notification code
+    - thermal: core: Represent suspend-related thermal zone flags as bits
+    - thermal: core: Mark thermal zones as initializing to start with
+    - thermal: core: Fix race between zone registration and system suspend
+    - crypto: qat - Fix missing destroy_workqueue in adf_init_aer()
+    - sched/cpufreq: Ensure sd is rebuilt for EAS check
+    - cleanup: Remove address space of returned pointer
+    - ARM: dts: renesas: genmai: Fix partition size for QSPI NOR Flash
+    - arm64: dts: mediatek: mt8395-genio-1200-evk: Fix dtbs_check error for phy
+    - scripts/kernel-doc: Do not track section counter across processed files
+    - arm64: dts: qcom: x1e80100: Resize GIC Redistributor register region
+    - scripts/kernel-doc: add modeline for vim users
+    - scripts/kernel-doc: simplify function printing
+    - scripts/kernel-doc: separate out function signature
+    - scripts/kernel-doc: simplify signature printing
+    - doc: kerneldoc.py: fix indentation
+    - kernel-doc: allow object-like macros in ReST output
+    - arm64: dts: mediatek: mt8188: Fix USB3 PHY port default status
+    - arm64: dts: rockchip: Remove 'enable-active-low' from two boards
+    - arm64: dts: qcom: x1e80100: Update C4/C5 residency/exit numbers
+    - dt-bindings: cache: qcom,llcc: Fix X1E80100 reg entries
+    - pwm: Assume a disabled PWM to emit a constant inactive output
+    - drm/imagination: Convert to use time_before macro
+    - drm/imagination: Use pvr_vm_context_get()
+    - drm/v3d: Flush the MMU before we supply more memory to the binner
+    - drm/amdgpu: Fix JPEG v4.0.3 register write
+    - ASoC: fsl-asoc-card: Add missing handling of {hp,mic}-dt-gpios
+    - wifi: rtl8xxxu: Perform update_beacon_work when beaconing is enabled
+    - selftests/bpf: netns_new() and netns_free() helpers.
+    - selftests/bpf: Fix backtrace printing for selftests crashes
+    - selftests/bpf: add missing header include for htons
+    - drm/vc4: hdmi: Increase audio MAI fifo dreq threshold
+    - drm/vc4: Introduce generation number enum
+    - drm/vc4: Match drm_dev_enter and exit calls in vc4_hvs_lut_load
+    - drm/vc4: Correct generation check in vc4_hvs_lut_load
+    - bpf: Tighten tail call checks for lingering locks, RCU, preempt_disable
+    - drm/panfrost: Add missing OPP table refcnt decremental
+    - selftests: netfilter: Fix missing return values in conntrack_dump_flush
+    - Bluetooth: btintel: Do no pass vendor events to stack
+    - Bluetooth: btbcm: fix missing of_node_put() in btbcm_get_board_name()
+    - Bluetooth: ISO: Use kref to track lifetime of iso_conn
+    - Bluetooth: ISO: Do not emit LE PA Create Sync if previous is pending
+    - Bluetooth: hci_conn: Use __counted_by() to avoid -Wfamnae warning
+    - Bluetooth: hci_conn: Use struct_size() in hci_le_big_create_sync()
+    - Bluetooth: ISO: Do not emit LE BIG Create Sync if previous is pending
+    - Bluetooth: ISO: Send BIG Create Sync via hci_sync
+    - Bluetooth: iso: Fix circular lock in iso_conn_big_sync
+    - net: txgbe: remove GPIO interrupt controller
+    - net: txgbe: fix null pointer to pcs
+    - RDMA/core: Provide rdma_user_mmap_disassociate() to disassociate mmap pages
+    - RDMA/hns: Disassociate mmap pages for all uctx when HW is being reset
+    - iommu/amd: Remove amd_iommu_domain_update() from page table freeing
+    - iommu/amd/pgtbl_v2: Take protection domain lock before invalidating TLB
+    - RDMA/hns: Fix flush cqe error when racing with destroy qp
+    - RDMA/hns: Modify debugfs name
+    - leds: max5970: Fix unreleased fwnode_handle in probe function
+    - kasan: move checks to do_strncpy_from_user
+    - kunit: skb: use "gfp" variable instead of hardcoding GFP_KERNEL
+    - RDMA/hns: Fix different dgids mapping to the same dip_idx
+    - RDMA/hns: Fix accessing invalid dip_ctx during destroying QP
+    - rust: kernel: add srctree-relative doclinks
+    - rust: kernel: fix THIS_MODULE header path in ThisModule doc comment
+    - i3c: master: Remove i3c_dev_disable_ibi_locked(olddev) on device hotjoin
+    - remoteproc: qcom: pas: Remove subdevs on the error path of adsp_probe()
+    - remoteproc: qcom: adsp: Remove subdevs on the error path of adsp_probe()
+    - nfsd: Revert "nfsd: release svc_expkey/svc_export with rcu_work"
+    - f2fs: clean up val{>>,<<}F2FS_BLKSIZE_BITS
+    - f2fs: fix to do cast in F2FS_{BLK_TO_BYTES, BTYES_TO_BLK} to avoid overflow
+    - vfio/mlx5: Fix unwind flows in mlx5vf_pci_save/resume_device_data()
+    - exfat: fix file being changed by unaligned direct write
+    - bnxt_en: Set backplane link modes correctly for ethtool
+    - devres: Fix page faults when tracing devres from unloaded modules
+    - usb: gadget: uvc: wake pump everytime we update the free list
+    - drm/xe/ufence: Wake up waiters after setting ufence->signalled
+    - net_sched: sch_fq: don't follow the fast path if Tx is behind now
+    - ASoC: da7213: Populate max_register to regmap_config
+    - KVM: x86: switch hugepage recovery thread to vhost_task
+    - kvm: defer huge page recovery vhost task to later
+    - KVM: x86/mmu: Ensure NX huge page recovery thread is alive before waking
+    - KVM: arm64: Change kvm_handle_mmio_return() return polarity
+    - dt-bindings: pinctrl: samsung: Fix interrupt constraint for variants with
+      fallbacks
+    - xhci: Fix control transfer error on Etron xHCI host
+    - xhci: Combine two if statements for Etron xHCI host
+    - xhci: Don't perform Soft Retry for Etron xHCI host
+    - xhci: Don't issue Reset Device command to Etron xHCI host
+    - mtd: spi-nor: core: replace dummy buswidth from addr to data
+    - Revert "mtd: spi-nor: core: replace dummy buswidth from addr to data"
+    - RISC-V: Scalar unaligned access emulated on hotplug CPUs
+    - serial: amba-pl011: Fix RX stall when DMA is used
+    - serial: amba-pl011: fix build regression
+    - i40e: Fix handling changed priv flags
+    - netdev-genl: Hold rcu_read_lock in napi_get
+    - usb: misc: ljca: set small runtime autosuspend delay
+    - usb: misc: ljca: move usb_autopm_put_interface() after wait for response
+    - blk-mq: add non_owner variant of start_freeze/unfreeze queue APIs
+    - block: model freeze & enter queue as lock for supporting lockdep
+    - block: always verify unfreeze lock on the owner task
+    - x86/Documentation: Update algo in init_size description of boot protocol
+    - kbuild: deb-pkg: Don't fail if modules.order is missing
+    - tools/power turbostat: Fix trailing '\n' parsing
+    - block: don't verify IO lock for freeze/unfreeze in elevator_init_mq()
+    - zram: permit only one post-processing operation at a time
+    - perf jevents: Don't stop at the first matched pmu when searching a events
+      table
+    - docs: media: update location of the media patches
+    - Revert "KVM: VMX: Move LOAD_IA32_PERF_GLOBAL_CTRL errata handling out of
+      setup_vmcs_config()"
+    - soc: fsl: cpm1: qmc: Fix blank line and spaces
+    - soc: fsl: cpm1: qmc: Re-order probe() operations
+    - soc: fsl: cpm1: qmc: Introduce qmc_init_resource() and its CPM1 version
+    - soc: fsl: cpm1: qmc: Introduce qmc_{init,exit}_xcc() and their CPM1 version
+    - soc: fsl: cpm1: qmc: Set the ret error code on platform_get_irq() failure
+    - x86/mm: Carve out INVLPG inline asm for use by others
+    - ALSA: hda/realtek: Enable mic on Vaio VJFH52
+    - ALSA: hda/realtek: Enable speaker pins for Medion E15443 platform
+    - ALSA: hda/realtek: fix mute/micmute LEDs don't work for EliteBook X G1i
+    - usb: dwc3: gadget: Add missing check for single port RAM in TxFIFO resizing
+      logic
+    - sched: Initialize idle tasks only once
+    - Upstream stable to v6.6.64, v6.11.11, v6.12.1, v6.12.2, v6.12.3
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53222
+    - zram: fix NULL pointer in comp_algorithm_show()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53169
+    - nvme-fabrics: fix kernel crash while shutting down controller
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56721
+    - x86/CPU/AMD: Terminate the erratum_1386_microcode array
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53187
+    - io_uring: check for overflows in io_pin_pages
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53147
+    - exfat: fix out-of-bounds access of directory entries
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53196
+    - KVM: arm64: Don't retire aborted MMIO instruction
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56685
+    - ASoC: mediatek: Check num_codecs is not zero to avoid panic during probe
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53201
+    - drm/amd/display: Fix null check for pipe_ctx->plane_state in
+      dcn20_program_pipe
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53203
+    - usb: typec: fix potential array underflow in ucsi_ccg_sync_control()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53209
+    - bnxt_en: Fix receive ring space parameters when XDP is active
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56742
+    - vfio/mlx5: Fix an unwind issue in mlx5vf_add_migration_pages()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53216
+    - nfsd: release svc_expkey/svc_export with rcu_work
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53219
+    - virtiofs: use pages instead of pointer for kernel direct IO
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53221
+    - f2fs: fix null-ptr-deref in f2fs_submit_page_bio()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53228
+    - riscv: kvm: Fix out-of-bounds array access
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53232
+    - iommu/s390: Implement blocking domain
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53236
+    - xsk: Free skb when TX metadata options are invalid
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56703
+    - ipv6: Fix soft lockups in fib6_select_path under high next hop churn
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56540
+    - accel/ivpu: Prevent recovery invocation during probe and resume
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53163
+    - crypto: qat/qat_420xx - fix off by one in uof_get_name()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56755
+    - netfs/fscache: Add a memory barrier for FSCACHE_VOLUME_CREATING
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56549
+    - cachefiles: Fix NULL pointer dereference in object->file
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56551
+    - drm/amdgpu: fix usage slab after free
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56776
+    - drm/sti: avoid potential dereference of error pointers
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56777
+    - drm/sti: avoid potential dereference of error pointers in
+      sti_gdp_atomic_check
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56778
+    - drm/sti: avoid potential dereference of error pointers in
+      sti_hqvdp_atomic_check
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56557
+    - iio: adc: ad7923: Fix buffer overflow for tx_buf and ring_xfer
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56779
+    - nfsd: fix nfs4_openowner leak when concurrent nfsd4_open occur
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56558
+    - nfsd: make sure exp active before svc_export_show
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56562
+    - i3c: master: Fix miss free init_dyn_addr at i3c_master_put_i3c_addrs()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56566
+    - mm/slub: Avoid list corruption when removing a slab from the full list
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-57838
+    - s390/entry: Mark IRQ entries to fix stack depot warnings
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56567
+    - ad7780: fix division by zero in ad7780_write_raw()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56569
+    - ftrace: Fix regression with module command in stack_trace_filter
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56570
+    - ovl: Filter invalid inodes with missing lookup function
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56572
+    - media: platform: allegro-dvt: Fix possible memory leak in
+      allocate_buffers_internal()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56573
+    - efi/libstub: Free correct pointer on failure
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56574
+    - media: ts2020: fix null-ptr-deref in ts2020_probe()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56575
+    - media: imx-jpeg: Ensure power suppliers be suspended before detach them
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56576
+    - media: i2c: tc358743: Fix crash in the probe error path when using polling
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56577
+    - media: mtk-jpeg: Fix null-ptr-deref during unload module
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56578
+    - media: imx-jpeg: Set video drvdata before register video device
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56579
+    - media: amphion: Set video drvdata before register video device
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56581
+    - btrfs: ref-verify: fix use-after-free after invalid ref action
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56774
+    - btrfs: add a sanity check for btrfs root in btrfs_search_slot()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56780
+    - quota: flush quota_release_work upon quota writeback
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53168
+    - sunrpc: fix one UAF issue caused by sunrpc kernel tcp socket
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56688
+    - sunrpc: clear XPRT_SOCK_UPD_TIMEOUT when reset transport
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56729
+    - smb: Initialize cfid->tcon before performing network ops
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56704
+    - 9p/xen: fix release of IRQ
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53171
+    - ubifs: authentication: Fix use-after-free in ubifs_tnc_end_commit
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53172
+    - ubi: fastmap: Fix duplicate slab cache names while attaching
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56739
+    - rtc: check if __rtc_read_time was successful in rtc_timer_do_work()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53173
+    - NFSv4.0: Fix a use-after-free problem in the asynchronous open()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53145
+    - um: Fix potential integer overflow during physmem setup
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53174
+    - SUNRPC: make sure cache entry active before cache_show
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53146
+    - NFSD: Prevent a potential integer overflow
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53175
+    - ipc: fix memleak if msg_init_ns failed in create_ipc_ns
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56692
+    - f2fs: fix to do sanity check on node blkaddr in truncate_node()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56698
+    - usb: dwc3: gadget: Fix looping of queued SG entries
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56687
+    - usb: musb: Fix hardware lockup on first Rx endpoint request
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53176
+    - smb: During unmount, ensure all cached dir instances drop their dentry
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53177
+    - smb: prevent use-after-free due to open_cached_dir error paths
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53178
+    - smb: Don't leak cfid when reconnect races with open_cached_dir
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53180
+    - ALSA: pcm: Add sanity NULL check for the default mmap fault handler
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56700
+    - media: wl128x: Fix atomicity violation in fmc_send_cmd()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2022-49034
+    - sh: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53181
+    - um: vector: Do not use drvdata in release
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53183
+    - um: net: Do not use drvdata in release
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53184
+    - um: ubd: Do not use drvdata in release
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53185
+    - smb: client: fix NULL ptr deref in crypto_aead_setkey()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53188
+    - wifi: ath12k: fix crash when unbinding
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53190
+    - wifi: rtlwifi: Drastically reduce the attempts to read efuse in case of
+      failures
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53191
+    - wifi: ath12k: fix warning when unbinding
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56741
+    - apparmor: test: Fix memory leak for aa_unpack_strdup()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53148
+    - comedi: Flush partial mappings in error case
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53194
+    - PCI: Fix use-after-free of slot->bus on hot remove
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53195
+    - KVM: arm64: Get rid of userspace_irqchip_in_use
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53197
+    - ALSA: usb-audio: Fix potential out-of-bound accesses for Extigy and Mbox
+      devices
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-42122
+    - drm/amd/display: Add NULL pointer check for kzalloc
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-49906
+    - drm/amd/display: Check null pointer before try to access it
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53150
+    - ALSA: usb-audio: Fix out of bounds reads when finding clock sources
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53198
+    - xen: Fix the issue of resource not being properly released in
+      xenbus_dev_probe()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-41014
+    - xfs: add bounds checking to xlog_recover_process_data
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53200
+    - drm/amd/display: Fix null check for pipe_ctx->plane_state in hwss_setup_dpp
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53202
+    - firmware_loader: Fix possible resource leak in fw_log_firmware_info()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53208
+    - Bluetooth: MGMT: Fix slab-use-after-free Read in set_powered_sync
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53210
+    - s390/iucv: MSG_PEEK causes memory leak in iucv_sock_destruct()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53213
+    - net: usb: lan78xx: Fix double free issue with interrupt buffer allocation
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53214
+    - vfio/pci: Properly hide first-in-list PCIe extended capability
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53215
+    - svcrdma: fix miss destroy percpu_counter in svc_rdma_proc_init()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53217
+    - NFSD: Prevent NULL dereference in nfsd4_process_cb_update()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56689
+    - PCI: endpoint: epf-mhi: Avoid NULL dereference if DT lacks 'mmio'
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53151
+    - svcrdma: Address an integer overflow
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53218
+    - f2fs: fix race in concurrent f2fs_stop_gc_thread
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56744
+    - f2fs: fix to avoid potential deadlock in f2fs_record_stop_reason()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53220
+    - f2fs: fix to account dirty data in __get_secs_required()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56745
+    - PCI: Fix reset_method_store() memory leak
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53223
+    - clk: ralink: mtmips: fix clocks probe order in oldest ralink SoCs
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53154
+    - clk: clk-apple-nco: Add NULL check in applnco_probe
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53224
+    - RDMA/mlx5: Move events notifier registration to be after device registration
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56746
+    - fbdev: sh7760fb: Fix a possible memory leak in sh7760fb_alloc_mem()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53155
+    - ocfs2: fix uninitialized value in ocfs2_file_read_iter()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53226
+    - RDMA/hns: Fix NULL pointer derefernce in hns_roce_map_mr_sg()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56747
+    - scsi: qedi: Fix a possible memory leak in qedi_alloc_and_init_sb()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56748
+    - scsi: qedf: Fix a possible memory leak in qedf_alloc_and_init_sb()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53229
+    - RDMA/rxe: Fix the qp flush warnings in req
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56722
+    - RDMA/hns: Fix cpu stuck caused by printings during reset
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53230
+    - cpufreq: CPPC: Fix possible null-ptr-deref for cppc_get_cpu_cost()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53231
+    - cpufreq: CPPC: Fix possible null-ptr-deref for cpufreq_cpu_get_raw()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56701
+    - powerpc/pseries: Fix dtl_access_lock to be a rw_semaphore
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56678
+    - powerpc/mm/fault: Fix kfence page fault reporting
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56677
+    - powerpc/fadump: Move fadump_cma_init to setup_arch() after initmem_init()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56723
+    - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for PMIC devices
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56724
+    - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for TMU device
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56691
+    - mfd: intel_soc_pmic_bxtwc: Use IRQ domain for USB Type-C device
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53233
+    - unicode: Fix utf8_load() error path
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56694
+    - bpf: fix recursive lock when verdict program return SK_PASS
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53234
+    - erofs: handle NONHEAD !delta[1] lclusters gracefully
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53239
+    - ALSA: 6fire: Release resources at card release
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56531
+    - ALSA: caiaq: Use snd_card_free_when_closed() at disconnection
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56532
+    - ALSA: us122l: Use snd_card_free_when_closed() at disconnection
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56533
+    - ALSA: usx2y: Use snd_card_free_when_closed() at disconnection
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56751
+    - ipv6: release nexthop on device removal
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56720
+    - bpf, sockmap: Several fixes to bpf_msg_pop_data
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56538
+    - drm: zynqmp_kms: Unplug DRM device before removal
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56752
+    - drm/nouveau/gr/gf100: Fix missing unlock in gf100_gr_chan_new()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56725
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_dcbnl.c
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56707
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_dmac_flt.c
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56726
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in cn10k.c
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56727
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_flows.c
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56728
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_ethtool.c
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56679
+    - octeontx2-pf: handle otx2_mbox_get_rsp errors in otx2_common.c
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56539
+    - wifi: mwifiex: Fix memcpy() field-spanning write warning in
+      mwifiex_config_scan()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56543
+    - wifi: ath12k: Skip Rx TID cleanup for self peer
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56683
+    - drm/vc4: hdmi: Avoid hang with debug registers when suspended
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56545
+    - HID: hyperv: streamline driver probe to avoid devres issues
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56705
+    - media: atomisp: Add check for rgby_data memory allocation failure
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53157
+    - firmware: arm_scpi: Check the DVFS OPP count returned by the firmware
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53158
+    - soc: qcom: geni-se: fix array underflow in geni_se_clk_tbl_get()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56546
+    - drivers: soc: xilinx: add the missing kfree in xlnx_add_cb_for_suspend()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56681
+    - crypto: bcm - add error check in the ahash_hmac_init function
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53160
+    - rcu/kvfree: Fix data-race in __mod_timer / kvfree_call_rcu
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56708
+    - EDAC/igen6: Avoid segmentation fault on module unload
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56690
+    - crypto: pcrypt - Call crypto layer directly when padata_do_parallel() return
+      -EBUSY
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53161
+    - EDAC/bluefield: Fix potential integer overflow
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53162
+    - crypto: qat/qat_4xxx - fix off by one in uof_get_name()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56754
+    - crypto: caam - Fix the pointer passed to caam_qi_shutdown()
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56548
+    - hfsplus: don't query the device logical block size multiple times
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56756
+    - nvme-pci: fix freeing of the HMB descriptor table
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-53142
+    - initramfs: avoid filename buffer overrun
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-56693
+    - brd: defer automatic disk creation until module initialization succeeds
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-44955
+    - drm/amd/display: Don't refer to dc_sink in is_dsc_need_re_compute
+  * Noble update: upstream stable patchset 2025-03-11 (LP: #2101915) //
+    CVE-2024-49899
+    - drm/amd/display: Initialize denominators' default to 1
+  * Noble update: upstream stable patchset 2025-03-06 (LP: #2101042)
+    - sctp: fix possible UAF in sctp_v6_available()
+    - net: vertexcom: mse102x: Fix tx_bytes calculation
+    - drm/rockchip: vop: Fix a dereferenced before check warning
+    - mptcp: error out earlier on disconnect
+    - mptcp: cope racing subflow creation in mptcp_rcv_space_adjust
+    - net/mlx5: fs, lock FTE when checking if active
+    - net/mlx5e: kTLS, Fix incorrect page refcounting
+    - net/mlx5e: clear xdp features on non-uplink representors
+    - net/mlx5e: CT: Fix null-ptr-deref in add rule err flow
+    - virtio/vsock: Fix accept_queue memory leak
+    - Bluetooth: btintel: Direct exception event to bluetooth stack
+    - net: sched: cls_u32: Fix u32's systematic failure to free IDR entries for
+      hnodes.
+    - samples: pktgen: correct dev to DEV
+    - net: stmmac: dwmac-mediatek: Fix inverted handling of mediatek,mac-wol
+    - net: Make copy_safe_from_sockptr() match documentation
+    - stmmac: dwmac-intel-plat: fix call balance of tx_clk handling routines
+    - net: ti: icssg-prueth: Fix 1 PPS sync
+    - bonding: add ns target multicast address to slave device
+    - ARM: 9419/1: mm: Fix kernel memory mapping for xip kernels
+    - x86/mm: Fix a kdump kernel failure on SME system when CONFIG_IMA_KEXEC=y
+    - mm: fix NULL pointer dereference in alloc_pages_bulk_noprof
+    - ocfs2: uncache inode which has failed entering the group
+    - vdpa: solidrun: Fix UB bug with devres
+    - vdpa/mlx5: Fix PA offset with unaligned starting iotlb map
+    - vp_vdpa: fix id_table array not null terminated error
+    - ima: fix buffer overrun in ima_eventdigest_init_common
+    - KVM: nVMX: Treat vpid01 as current if L2 is active, but with VPID disabled
+    - KVM: x86: Unconditionally set irr_pending when updating APICv state
+    - KVM: VMX: Bury Intel PT virtualization (guest/host mode) behind
+      CONFIG_BROKEN
+    - nilfs2: fix null-ptr-deref in block_touch_buffer tracepoint
+    - nommu: pass NULL argument to vma_iter_prealloc()
+    - ALSA: hda/realtek - Fixed Clevo platform headset Mic issue
+    - ocfs2: fix UBSAN warning in ocfs2_verify_volume()
+    - nilfs2: fix null-ptr-deref in block_dirty_buffer tracepoint
+    - LoongArch: Fix early_numa_add_cpu() usage for FDT systems
+    - LoongArch: Disable KASAN if PGDIR_SIZE is too large for cpu_vabits
+    - LoongArch: Make KASAN work with 5-level page-tables
+    - Revert "mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K"
+    - mmc: sunxi-mmc: Fix A100 compatible description
+    - drm/bridge: tc358768: Fix DSI command tx
+    - pmdomain: imx93-blk-ctrl: correct remove path
+    - nouveau: fw: sync dma after setup is called.
+    - drm/amd: Fix initialization mistake for NBIO 7.7.0
+    - drm/amd/display: Adjust VSDB parser for replay feature
+    - lib/buildid: Fix build ID parsing logic
+    - media: dvbdev: fix the logic when DVB_DYNAMIC_MINORS is not set
+    - mptcp: add userspace_pm_lookup_addr_by_id helper
+    - mptcp: update local address flags when setting it
+    - mptcp: hold pm lock when deleting entry
+    - mptcp: drop lookup_by_id in lookup_addr
+    - mptcp: pm: use _rcu variant under rcu_read_lock
+    - mm: avoid unsafe VMA hook invocation when error arises on mmap hook
+    - mm: unconditionally close VMAs on error
+    - mm: refactor map_deny_write_exec()
+    - mm: refactor arch_calc_vm_flag_bits() and arm64 MTE handling
+    - mm: resolve faulty mmap_region() error path behaviour
+    - net/mlx5: Fix msix vectors to respect platform limit
+    - vsock: Fix sk_error_queue memory leak
+    - virtio/vsock: Improve MSG_ZEROCOPY error handling
+    - net: phylink: ensure PHY momentary link-fails are handled
+    - drm/vmwgfx: avoid null_ptr_deref in vmw_framebuffer_surface_create_handle
+    - ARM: fix cacheflush with PAN
+    - drm/amd/display: Run idle optimizations at end of vblank handler
+    - drm/amd/display: Change some variable name of psr
+    - x86/CPU/AMD: Clear virtualized VMLOAD/VMSAVE on Zen4 client
+    - x86/stackprotector: Work around strict Clang TLS symbol requirements
+    - sched/task_stack: fix object_is_on_stack() for KASAN tagged pointers
+    - fs/proc/task_mmu: prevent integer overflow in pagemap_scan_get_args()
+    - mm/mremap: fix address wraparound in move_page_tables()
+    - KVM: selftests: Disable strict aliasing
+    - mm: page_alloc: move mlocked flag clearance into free_pages_prepare()
+    - LoongArch: Add WriteCombine shadow mapping in KASAN
+    - drm/xe: handle flat ccs during hibernation on igpu
+    - pmdomain: arm: Use FLAG_DEV_NAME_FW to ensure unique names
+    - pmdomain: core: Add GENPD_FLAG_DEV_NAME_FW flag
+    - nouveau: handle EBUSY and EAGAIN for GSP aux errors.
+    - nouveau/dp: handle retries for AUX CH transfers with GSP.
+    - drm/amdgpu: fix check in gmc_v9_0_get_vm_pte()
+    - drm/amdgpu: Fix video caps for H264 and HEVC encode maximum size
+    - drm/amd/pm: print pp_dpm_mclk in ascending order on SMU v14.0.0
+    - drm/amd/display: Handle dml allocation failure to avoid crash
+    - drm/amd/display: Fix failure to read vram info due to static BP_RESULT
+    - drm/xe: Restore system memory GGTT mappings
+    - drm/xe: improve hibernation on igpu
+    - net: sched: u32: Add test case for systematic hnode IDR leaks
+    - Upstream stable to v6.6.63, v6.11.10
+  * Noble update: upstream stable patchset 2025-03-04 (LP: #2100894)
+    - 9p: v9fs_fid_find: also lookup by inode if not found dentry
+    - 9p: Avoid creating multiple slab caches with the same name
+    - selftests/bpf: Verify that sync_linked_regs preserves subreg_def
+    - irqchip/ocelot: Fix trigger register address
+    - nvme: tcp: avoid race between queue_lock lock and destroy
+    - block: Fix elevator_get_default() checking for NULL q->tag_set
+    - HID: multitouch: Add support for B2402FVA track point
+    - HID: multitouch: Add quirk for HONOR MagicBook Art 14 touchpad
+    - iommu/arm-smmu: Clarify MMU-500 CPRE workaround
+    - nvme: disable CC.CRIME (NVME_CC_CRIME)
+    - bpf: use kvzmalloc to allocate BPF verifier environment
+    - crypto: api - Fix liveliness check in crypto_alg_tested
+    - crypto: marvell/cesa - Disable hash algorithms
+    - sound: Make CONFIG_SND depend on INDIRECT_IOMEM instead of UML
+    - drm/vmwgfx: Limit display layout ioctl array size to
+      VMWGFX_NUM_DISPLAY_UNITS
+    - RDMA/siw: Add sendpage_ok() check to disable MSG_SPLICE_PAGES
+    - nvme-multipath: defer partition scanning
+    - drm/amdkfd: Accounting pdd vram_usage for svm
+    - powerpc/powernv: Free name on error in opal_event_init()
+    - net: phy: mdio-bcm-unimac: Add BCM6846 support
+    - nvme-loop: flush off pending I/O while shutting down loop controller
+    - smb: client: Fix use-after-free of network namespace.
+    - nvme/host: Fix RCU list traversal to use SRCU primitive
+    - vDPA/ifcvf: Fix pci_read_config_byte() return code handling
+    - bpf: Add sk_is_inet and IS_ICSK check in tls_sw_has_ctx_tx/rx
+    - bpf: Fix mismatched RCU unlock flavour in bpf_out_neigh_v6
+    - ASoC: amd: yc: Add quirk for ASUS Vivobook S15 M3502RA
+    - ASoC: amd: yc: Fix non-functional mic on ASUS E1404FA
+    - fs: Fix uninitialized value issue in from_kuid and from_kgid
+    - HID: multitouch: Add quirk for Logitech Bolt receiver w/ Casa touchpad
+    - HID: lenovo: Add support for Thinkpad X1 Tablet Gen 3 keyboard
+    - RISCV: KVM: use raw_spinlock for critical section in imsic
+    - ASoC: rt722-sdca: increase clk_stop_timeout to fix clock stop issue
+    - LoongArch: Use "Exception return address" to comment ERA
+    - ASoC: fsl_micfil: Add sample rate constraint
+    - net: usb: qmi_wwan: add Fibocom FG132 0x0112 composition
+    - bpf: Check validity of link->type in bpf_link_show_fdinfo()
+    - mm: support order-1 folios in the page cache
+    - mm: always initialise folio->_deferred_list
+    - mm: refactor folio_undo_large_rmappable()
+    - mm/thp: fix deferred split unqueue naming and locking
+    - 9p: fix slab cache name creation for real
+    - nvmet-passthru: clear EUID/NGUID/UUID while using loop target
+    - pinctrl: intel: platform: Add Panther Lake to the list of supported
+    - s390/ap: Fix CCA crypto card behavior within protected execution environment
+    - selftests/bpf: Assert link info uprobe_multi count & path_size if unset
+    - ALSA: hda/tas2781: Add new quirk for Lenovo, ASUS, Dell projects
+    - drm/xe/query: Increase timestamp width
+    - nvme: make keep-alive synchronous operation
+    - samples/landlock: Fix port parsing in sandboxer
+    - ASoC: Intel: avs: Update stream status in a separate thread
+    - ASoC: codecs: Fix error handling in aw_dev_get_dsp_status function
+    - netfs: Downgrade i_rwsem for a buffered write
+    - afs: Fix lock recursion
+    - HID: i2c-hid: Delayed i2c resume wakeup for 0x0d42 Goodix touchpad
+    - LoongArch: KVM: Mark hrtimer to expire in hard interrupt context
+    - drm/xe: Don't restart parallel queues multiple times on GT reset
+    - Upstream stable to v6.6.62, v6.11.9
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292)
+    - arm64: dts: rockchip: Fix rt5651 compatible value on rk3399-eaidk-610
+    - arm64: dts: rockchip: Fix rt5651 compatible value on rk3399-sapphire-
+      excavator
+    - arm64: dts: rockchip: Remove hdmi's 2nd interrupt on rk3328
+    - arm64: dts: rockchip: Fix wakeup prop names on PineNote BT node
+    - arm64: dts: rockchip: Fix reset-gpios property on brcm BT nodes
+    - arm64: dts: rockchip: fix i2c2 pinctrl-names property on anbernic-rg353p/v
+    - arm64: dts: rockchip: Fix bluetooth properties on rk3566 box demo
+    - arm64: dts: rockchip: Fix bluetooth properties on Rock960 boards
+    - arm64: dts: rockchip: Add DTS for FriendlyARM NanoPi R2S Plus
+    - arm64: dts: rockchip: Remove undocumented supports-emmc property
+    - arm64: dts: rockchip: Remove #cooling-cells from fan on Theobroma lion
+    - arm64: dts: rockchip: Fix LED triggers on rk3308-roc-cc
+    - arm64: dts: rockchip: remove num-slots property from rk3328-nanopi-r2s-plus
+    - arm64: dts: imx8-ss-vpu: Fix imx8qm VPU IRQs
+    - arm64: dts: imx8mp: correct sdhc ipg clk
+    - arm64: dts: rockchip: remove orphaned pinctrl-names from pinephone pro
+    - ARM: dts: rockchip: fix rk3036 acodec node
+    - ARM: dts: rockchip: drop grf reference from rk3036 hdmi
+    - ARM: dts: rockchip: Fix the spi controller on rk3036
+    - ARM: dts: rockchip: Fix the realtek audio codec on rk3036-kylin
+    - arm64: dts: rockchip: Correct GPIO polarity on brcm BT nodes
+    - sunrpc: handle -ENOTCONN in xs_tcp_setup_socket()
+    - NFSv3: only use NFS timeout for MOUNT when protocols are compatible
+    - nfs: avoid i_lock contention in nfs_clear_invalid_mapping
+    - net: enetc: set MAC address to the VF net_device
+    - dt-bindings: net: xlnx,axi-ethernet: Correct phy-mode property value
+    - can: c_can: fix {rx,tx}_errors statistics
+    - can: c_can: c_can_handle_bus_err(): update statistics if skb allocation
+      fails
+    - ice: change q_index variable type to s16 to store -1 value
+    - e1000e: Remove Meteor Lake SMBUS workarounds
+    - net: phy: ti: add PHY_RST_AFTER_CLK_EN flag
+    - net: stmmac: Fix unbalanced IRQ wake disable warning on single irq case
+    - netfilter: nf_tables: pass nft_chain to destroy function, not nft_ctx
+    - netfilter: nf_tables: wait for rcu grace period on net_device removal
+    - netfilter: nf_tables: do not defer rule destruction via call_rcu
+    - net: arc: rockchip: fix emac mdio node support
+    - drivers: net: ionic: add missed debugfs cleanup to ionic_probe() error path
+    - Revert "ALSA: hda/conexant: Mute speakers at suspend / shutdown"
+    - media: stb0899_algo: initialize cfr before using it
+    - media: dvb_frontend: don't play tricks with underflow values
+    - media: adv7604: prevent underflow condition when reporting colorspace
+    - scsi: sd_zbc: Use kvzalloc() to allocate REPORT ZONES buffer
+    - ALSA: firewire-lib: fix return value on fail in amdtp_tscm_init()
+    - tools/lib/thermal: Fix sampling handler context ptr
+    - thermal/of: support thermal zones w/o trips subnode
+    - ASoC: SOF: sof-client-probes-ipc4: Set param_size extension bits
+    - media: pulse8-cec: fix data timestamp at pulse8_setup()
+    - media: v4l2-ctrls-api: fix error handling for v4l2_g_ctrl()
+    - can: m_can: m_can_close(): don't call free_irq() for IRQ-less devices
+    - can: mcp251xfd: mcp251xfd_get_tef_len(): fix length calculation
+    - can: mcp251xfd: mcp251xfd_ring_alloc(): fix coalescing configuration when
+      switching CAN modes
+    - ksmbd: count all requests in req_running counter
+    - ksmbd: fix broken transfers when exceeding max simultaneous operations
+    - pwm: imx-tpm: Use correct MODULO value for EPWM mode
+    - rpmsg: glink: Handle rejected intent request better
+    - drm/amdgpu: Adjust debugfs eviction and IB access permissions
+    - drm/amdgpu: Adjust debugfs register access permissions
+    - drm/amdgpu: Fix DPX valid mode check on GC 9.4.3
+    - thermal/drivers/qcom/lmh: Remove false lockdep backtrace
+    - dm cache: correct the number of origin blocks to match the target length
+    - dm cache: optimize dirty bit checking with find_next_bit when resizing
+    - dm-unstriped: cast an operand to sector_t to prevent potential uint32_t
+      overflow
+    - ALSA: usb-audio: Add quirk for HP 320 FHD Webcam
+    - net: wwan: t7xx: Fix off-by-one error in t7xx_dpmaif_rx_buf_alloc()
+    - mptcp: use sock_kfree_s instead of kfree
+    - arm64: Kconfig: Make SME depend on BROKEN for now
+    - [Config] updateconfigs for ARM64_SME
+    - arm64: smccc: Remove broken support for SMCCCv1.3 SVE discard hint
+    - Revert "wifi: mac80211: fix RCU list iterations"
+    - i2c: designware: do not hold SCL low when I2C_DYNAMIC_TAR_UPDATE is not set
+    - fs/proc: fix compile warning about variable 'vmcore_mmap_ops'
+    - usb: dwc3: fix fault at system suspend if device was already runtime
+      suspended
+    - USB: serial: qcserial: add support for Sierra Wireless EM86xx
+    - USB: serial: option: add Fibocom FG132 0x0112 composition
+    - USB: serial: option: add Quectel RG650V
+    - irqchip/gic-v3: Force propagation of the active state with a read-back
+    - ucounts: fix counter leak in inc_rlimit_get_ucounts()
+    - ASoC: amd: yc: fix internal mic on Xiaomi Book Pro 14 2022
+    - arm64: dts: rockchip: Designate Turing RK1's system power controller
+    - EDAC/qcom: Make irq configuration optional
+    - arm64: dts: rockchip: Drop regulator-init-microvolt from two boards
+    - net: dpaa_eth: print FD status in CPU endianness in dpaa_eth_fd tracepoint
+    - virtio_net: Sync rss config to device when virtnet_probe
+    - drm/xe: Set mask bits for CCS_MODE register
+    - drm/amd/display: Fix brightness level not retained over reboot
+    - drm/imagination: Add a per-file PVR context list
+    - mptcp: no admin perm to list endpoints
+    - btrfs: fix the length of reserved qgroup to free
+    - btrfs: fix per-subvolume RO/RW flags with new mount API
+    - clk: qcom: gcc-x1e80100: Fix USB MP SS1 PHY GDSC pwrsts flags
+    - clk: qcom: clk-alpha-pll: Fix pll post div mask when width is not set
+    - objpool: fix to make percpu slot allocation more robust
+    - mm/damon/core: handle zero {aggregation,ops_update} intervals
+    - mm/damon/core: handle zero schemes apply interval
+    - mm/mlock: set the correct prev on failure
+    - clk: qcom: gcc-x1e80100: Fix halt_check for pipediv2 clocks
+    - staging: vchiq_arm: Get the rid off struct vchiq_2835_state
+    - staging: vchiq_arm: Use devm_kzalloc() for vchiq_arm_state allocation
+    - drm/xe/guc/ct: Flush g2h worker in case of g2h response timeout
+    - drm/xe: Move LNL scheduling WA to xe_device.h
+    - drm/xe/ufence: Flush xe ordered_wq in case of ufence timeout
+    - drm/xe/guc/tlb: Flush g2h worker in case of tlb timeout
+    - xtensa: Emulate one-byte cmpxchg
+    - Upstream stable to v6.6.61, v6.11.8
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50270
+    - mm/damon/core: avoid overflow in damon_feed_loop_next_input()
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50274
+    - idpf: avoid vport access in idpf_get_link_ksettings
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53067
+    - scsi: ufs: core: Start the RTC update work later
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53084
+    - drm/imagination: Break an object reference loop
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53085
+    - tpm: Lock TPM chip in tpm_pm_suspend() first
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53086
+    - drm/xe: Drop VM dma-resv lock on xe_sync_in_fence_get failure in exec IOCTL
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53087
+    - drm/xe: Fix possible exec queue leak in exec IOCTL
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50288
+    - media: vivid: fix buffer overwrite when using > 32 buffers
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50289
+    - media: av7110: fix a spectre vulnerability
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53062
+    - media: mgb4: protect driver against spectre
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50291
+    - media: dvb-core: add missing buffer index check
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50297
+    - net: xilinx: axienet: Enqueue Tx packets in dql before dmaengine starts
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50267
+    - USB: serial: io_edgeport: fix use after free in debug printk
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50268
+    - usb: typec: fix potential out of bounds in ucsi_ccg_update_set_new_cam_cmd()
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53083
+    - usb: typec: qcom-pmic: init value of hdr_len/txbuf_len earlier
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50269
+    - usb: musb: sunxi: Fix accessing an released usb phy
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50271
+    - signal: restore the override_rlimit logic
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50272
+    - filemap: Fix bounds checking in filemap_read()
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50273
+    - btrfs: reinitialize delayed ref list after deleting it from the list
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50275
+    - arm64/sve: Discard stale CPU state when handling SVE traps
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50276
+    - net: vertexcom: mse102x: Fix possible double free of TX skb
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53066
+    - nfs: Fix KMSAN warning in decode_getfattr_attrs()
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50278
+    - dm cache: fix potential out-of-bounds access on the first resume
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50279
+    - dm cache: fix out-of-bounds access to the dirty bitset when resizing
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50280
+    - dm cache: fix flushing uninitialized delayed_work on cache_ctr error
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53060
+    - drm/amdgpu: prevent NULL pointer dereference if ATIF is not supported
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50282
+    - drm/amdgpu: add missing size check in amdgpu_debugfs_gprwave_read()
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50283
+    - ksmbd: fix slab-use-after-free in smb3_preauth_hash_rsp
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50284
+    - ksmbd: Fix the missing xa_store error check
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50285
+    - ksmbd: check outstanding simultaneous SMB operations
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50286
+    - ksmbd: fix slab-use-after-free in ksmbd_smb2_session_create
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50287
+    - media: v4l2-tpg: prevent the risk of a division by zero
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50290
+    - media: cx24116: prevent overflows on SNR calculus
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53061
+    - media: s5p-jpeg: prevent buffer overflows
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53081
+    - media: ar0521: don't overflow when checking PLL values
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50292
+    - ASoC: stm32: spdifrx: fix dma channel release in stm32_spdifrx_remove
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50294
+    - rxrpc: Fix missing locking causing hanging calls
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50295
+    - net: arc: fix the device for dma_map_single/dma_unmap_single
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53082
+    - virtio_net: Add hash_key_length check
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50296
+    - net: hns3: fix kernel crash when uninstalling driver
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53088
+    - i40e: fix race condition by adding filter's intermediate sync state
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50298
+    - net: enetc: allocate vf_state during PF probes
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50299
+    - sctp: properly validate chunk size in sctp_sf_ootb()
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50300
+    - regulator: rtq2208: Fix uninitialized use of regulator_config
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-50301
+    - security/keys: fix slab-out-of-bounds in key_task_permission
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53072
+    - platform/x86/amd/pmc: Detect when STB is not available
+  * Noble update: upstream stable patchset 2025-02-27 (LP: #2100292) //
+    CVE-2024-53068
+    - firmware: arm_scmi: Fix slab-use-after-free in scmi_bus_notifier()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996)
+    - Input: xpad - sort xpad_device by vendor and product ID
+    - Input: xpad - add support for 8BitDo Ultimate 2C Wireless Controller
+    - cgroup: Fix potential overflow issue when checking max_depth
+    - spi: geni-qcom: Fix boot warning related to pm_runtime and devres
+    - wifi: iwlegacy: Fix "field-spanning write" warning in il_enqueue_hcmd()
+    - mac80211: MAC80211_MESSAGE_TRACING should depend on TRACING
+    - wifi: mac80211: skip non-uploaded keys in ieee80211_iter_keys
+    - wifi: ath11k: Fix invalid ring usage in full monitor mode
+    - wifi: brcm80211: BRCM_TRACING should depend on TRACING
+    - RDMA/cxgb4: Dump vendor specific QP details
+    - RDMA/mlx5: Round max_rd_atomic/max_dest_rd_atomic up instead of down
+    - RDMA/bnxt_re: Fix the usage of control path spin locks
+    - RDMA/bnxt_re: synchronize the qp-handle table array
+    - RDMA/bnxt_re: Fix the locking while accessing the QP table
+    - wifi: iwlwifi: mvm: disconnect station vifs if recovery failed
+    - wifi: iwlwifi: mvm: don't add default link in fw restart flow
+    - ASoC: cs42l51: Fix some error handling paths in cs42l51_probe()
+    - net: stmmac: dwmac4: Fix high address display by updating reg_space[] from
+      register values
+    - net: stmmac: fix TSO DMA API usage causing oops
+    - gtp: allow -1 to be specified as file description from userspace
+    - bpf: Force checkpoint when jmp history is too long
+    - net: skip offload for NETIF_F_IPV6_CSUM if ipv6 header contains extension
+    - net: reenable NETIF_F_IPV6_CSUM offload for BIG TCP packets
+    - mlxsw: spectrum_ptp: Add missing verification before pushing Tx header
+    - bpf, test_run: Fix LIVE_FRAME frame update after a page has been recycled
+    - iomap: improve shared block detection in iomap_unshare_iter
+    - iomap: don't bother unsharing delalloc extents
+    - iomap: share iomap_unshare_iter predicate code with fsdax
+    - fsdax: remove zeroing code from dax_unshare_iter
+    - iomap: turn iomap_want_unshare_iter into an inline function
+    - kasan: Fix Software Tag-Based KASAN with GCC
+    - firmware: arm_sdei: Fix the input parameter of cpuhp_remove_state()
+    - afs: Fix missing subdir edit when renamed between parent dirs
+    - smb: client: set correct device number on nfs reparse points
+    - cxl/events: Fix Trace DRAM Event Record
+    - fs/ntfs3: Fix warning possible deadlock in ntfs_set_state
+    - fs/ntfs3: Stale inode instead of bad
+    - scsi: scsi_transport_fc: Allow setting rport state to current state
+    - cifs: Fix creating native symlinks pointing to current or parent directory
+    - thermal: intel: int340x: processor: Remove MMIO RAPL CPU hotplug support
+    - thermal: intel: int340x: processor: Add MMIO RAPL PL4 support
+    - net: amd: mvme147: Fix probe banner message
+    - NFS: remove revoked delegation from server's delegation list
+    - misc: sgi-gru: Don't disable preemption in GRU driver
+    - usb: gadget: dummy_hcd: Switch to hrtimer transfer scheduler
+    - usb: gadget: dummy_hcd: Set transfer interval to 1 microframe
+    - usb: gadget: dummy_hcd: execute hrtimer callback in softirq context
+    - USB: gadget: dummy-hcd: Fix "task hung" problem
+    - ALSA: usb-audio: Add quirks for Dell WD19 dock
+    - usbip: tools: Fix detach_port() invalid port error path
+    - usb: phy: Fix API devm_usb_put_phy() can not release the phy
+    - usb: typec: fix unreleased fwnode_handle in typec_port_register_altmodes()
+    - usb: typec: qcom-pmic-typec: use fwnode_handle_put() to release fwnodes
+    - xhci: Fix Link TRB DMA in command ring stopped completion event
+    - xhci: Use pm_runtime_get to prevent RPM on unsupported systems
+    - Revert "driver core: Fix uevent_show() vs driver detach race"
+    - iio: light: veml6030: fix microlux value calculation
+    - RISC-V: ACPI: fix early_ioremap to early_memremap
+    - tools/mm: -Werror fixes in page-types/slabinfo
+    - tools/mm: fix compile error
+    - thunderbolt: Honor TMU requirements in the domain when setting TMU mode
+    - mmc: sdhci-pci-gli: GL9767: Fix low power mode on the set clock function
+    - mmc: sdhci-pci-gli: GL9767: Fix low power mode in the SD Express process
+    - block: fix sanity checks in blk_rq_map_user_bvec
+    - cgroup/bpf: use a dedicated workqueue for cgroup bpf destruction
+    - phy: freescale: imx8m-pcie: Do CMN_RST just before PHY PLL lock check
+    - riscv: vdso: Prevent the compiler from inserting calls to memset()
+    - Input: edt-ft5x06 - fix regmap leak when probe fails
+    - ALSA: hda/realtek: Limit internal Mic boost on Dell platform
+    - riscv: efi: Set NX compat flag in PE/COFF header
+    - riscv: Use '%u' to format the output of 'cpu'
+    - riscv: Remove unused GENERATING_ASM_OFFSETS
+    - riscv: Remove duplicated GET_RM
+    - cxl/port: Fix cxl_bus_rescan() vs bus_rescan_devices()
+    - cxl/acpi: Ensure ports ready at cxl_acpi_probe() return
+    - mei: use kvmalloc for read buffer
+    - mm/page_alloc: let GFP_ATOMIC order-0 allocs access highatomic reserves
+    - x86/traps: Enable UBSAN traps on x86
+    - x86/traps: move kmsan check after instrumentation_begin
+    - kasan: remove vmalloc_percpu test
+    - vmscan,migrate: fix page count imbalance on node stats when demoting pages
+    - io_uring: always lock __io_cqring_overflow_flush
+    - mm: huge_memory: add vma_thp_disabled() and thp_disabled_by_hw()
+    - mm: don't install PMD mappings when THPs are disabled by the hw/process/vma
+    - perf trace: Fix non-listed archs in the syscalltbl routines
+    - dpll: add Embedded SYNC feature for a pin
+    - ice: add callbacks for Embedded SYNC enablement on dpll pins
+    - bpf: Add bpf_mem_alloc_check_size() helper
+    - net: ethernet: mtk_wed: fix path of MT7988 WO firmware
+    - drm/mediatek: ovl: Remove the color format comment for ovl_fmt_convert()
+    - drm/mediatek: Fix get efuse issue for MT8188 DPTX
+    - ACPI: resource: Fold Asus Vivobook Pro N6506M* DMI quirks together
+    - powercap: intel_rapl_msr: Add PL4 support for Arrowlake-U
+    - usb: typec: qcom-pmic-typec: fix missing fwnode removal in error path
+    - mm: shrinker: avoid memleak in alloc_shrinker_info
+    - firmware: microchip: auto-update: fix poll_complete() to not report spurious
+      timeout errors
+    - soc: qcom: pmic_glink: Handle GLINK intent allocation rejections
+    - cxl/port: Fix CXL port initialization order when the subsystem is built-in
+    - btrfs: merge btrfs_orig_bbio_end_io() into btrfs_bio_end_io()
+    - posix-cpu-timers: Clear TICK_DEP_BIT_POSIX_TIMER on clone
+    - mm/ksm: remove redundant code in ksm_fork
+    - nvme: re-fix error-handling for io_uring nvme-passthrough
+    - btrfs: fix extent map merging not happening for adjacent extents
+    - btrfs: fix defrag not merging contiguous extents due to merged extent maps
+    - mm, mmap: limit THP alignment of anonymous mappings to PMD-aligned sizes
+    - mm: multi-gen LRU: ignore non-leaf pmd_young for force_scan=true
+    - mm: multi-gen LRU: remove MM_LEAF_OLD and MM_NONLEAF_TOTAL stats
+    - mm: shrink skip folio mapped by an exiting process
+    - mm: multi-gen LRU: use {ptep,pmdp}_clear_young_notify()
+    - drm/i915: Skip programming FIA link enable bits for MTL+
+    - drm/i915/display: WA for Re-initialize dispcnlunitt1 xosc clock
+    - drm/i915/dp: Clear VSC SDP during post ddi disable routine
+    - drm/i915/pps: Disable DPLS_GATING around pps sequence
+    - drm/i915: move rawclk from runtime to display runtime info
+    - drm/xe/display: drop unused rawclk_freq and RUNTIME_INFO()
+    - drm/xe: Support 'nomodeset' kernel command-line option
+    - drm/xe/xe2hpg: Introduce performance tuning changes for Xe2_HPG
+    - drm/amdgpu/swsmu: fix ordering for setting workload_mask
+    - drm/amdgpu/swsmu: default to fullscreen 3D profile for dGPUs
+    - drm/amdgpu: handle default profile on on devices without fullscreen 3D
+    - MIPS: export __cmpxchg_small()
+    - rcu/kvfree: Add kvfree_rcu_barrier() API
+    - rcu/kvfree: Refactor kvfree_rcu_queue_batch()
+    - Upstream stable to v6.6.60, v6.11.7
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53050
+    - drm/i915/hdcp: Add encoder check in hdcp2_get_capability
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53051
+    - drm/i915/hdcp: Add encoder check in intel_hdcp_get_capability
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50303
+    - resource,kexec: walk_system_ram_res_rev must retain resource flags
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50263
+    - fork: only invoke khugepaged, ksm hooks if no error
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50220
+    - fork: do not invoke uffd on fork if error occurs
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50221
+    - drm/amd/pm: Vangogh: Fix kernel memory out of bounds write
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53053
+    - scsi: ufs: core: Fix another deadlock during RTC update
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50225
+    - btrfs: fix error propagation of split bios
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50230
+    - nilfs2: fix kernel bug due to missing clearing of checked flag
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50238
+    - phy: qcom: qmp-usbc: fix NULL-deref on runtime suspend
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53044
+    - net/sched: sch_api: fix xa_insert() error path in tcf_block_get_ext()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50304
+    - ipv4: ip_tunnel: Fix suspicious RCU usage warning in ip_tunnel_find()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53048
+    - ice: fix crash on probe for DPLL enabled E810 LOM
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53045
+    - ASoC: dapm: fix bounds checker error in dapm_widget_list_create
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53055
+    - wifi: iwlwifi: mvm: fix 6 GHz scan construction
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53046
+    - arm64: dts: imx8ulp: correct the flexspi compatible string
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53052
+    - io_uring/rw: fix missing NOWAIT check for O_DIRECT start write
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50215
+    - nvmet-auth: assign dh_key to NULL after kfree_sensitive
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50216
+    - xfs: fix finding a last resort AG in xfs_filestream_pick_ag
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53043
+    - mctp i2c: handle NULL header address
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50218
+    - ocfs2: pass u64 to ocfs2_truncate_inline maybe overflow
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53047
+    - mptcp: init: protect sched with rcu_read_lock
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50222
+    - iov_iter: fix copy_page_from_iter_atomic() if KMAP_LOCAL_FORCE_MAP
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50223
+    - sched/numa: Fix the potential null pointer dereference in task_numa_work()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50224
+    - spi: spi-fsl-dspi: Fix crash when not using GPIO chip select
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50226
+    - cxl/port: Fix use-after-free, permit out-of-order decoder shutdown
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50231
+    - iio: gts-helper: Fix memory leaks in iio_gts_build_avail_scale_table()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53076
+    - iio: gts-helper: Fix memory leaks for the error path of
+      iio_gts_build_avail_scale_table()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50232
+    - iio: adc: ad7124: fix division by zero in ad7124_set_channel_odr()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50234
+    - wifi: iwlegacy: Clear stale interrupts before resuming device
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50235
+    - wifi: cfg80211: clear wdev->cqm_config pointer on free
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50236
+    - wifi: ath10k: Fix memory leak in management tx
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50237
+    - wifi: mac80211: do not pass a stopped vif to the driver in .get_txpower
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50239
+    - phy: qcom: qmp-usb-legacy: fix NULL-deref on runtime suspend
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50240
+    - phy: qcom: qmp-usb: fix NULL-deref on runtime suspend
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50242
+    - fs/ntfs3: Additional check in ntfs_file_release
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50243
+    - fs/ntfs3: Fix general protection fault in run_is_mapped_full
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50244
+    - fs/ntfs3: Additional check in ni_clear()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50245
+    - fs/ntfs3: Fix possible deadlock in mi_read
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50246
+    - fs/ntfs3: Add rough attr alloc_size check
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50247
+    - fs/ntfs3: Check if more than chunk-size bytes are written
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50250
+    - fsdax: dax_unshare_iter needs to copy entire blocks
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50251
+    - netfilter: nft_payload: sanitize offset and length before calling
+      skb_checksum()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50252
+    - mlxsw: spectrum_ipip: Fix memory leak when changing remote IPv6 address
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50255
+    - Bluetooth: hci: fix null-ptr-deref in hci_read_supported_codecs
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50257
+    - netfilter: Fix use-after-free in get_info()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50258
+    - net: fix crash when config small gso_max_size/gso_ipv4_max_size
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50262
+    - bpf: Fix out-of-bounds write in trie_get_next_key()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50259
+    - netdevsim: Add trailing zero to terminate the string in
+      nsim_nexthop_bucket_activity_write()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53042
+    - ipv4: ip_tunnel: Fix suspicious RCU usage warning in ip_tunnel_init_flow()
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53058
+    - net: stmmac: TSO: Fix unbalanced DMA map/unmap for non-paged SKB data
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-50261
+    - macsec: Fix use-after-free while sending the offloading packet
+  * Noble update: upstream stable patchset 2025-02-25 (LP: #2099996) //
+    CVE-2024-53059
+    - wifi: iwlwifi: mvm: Fix response handling in iwl_mvm_send_recovery_cmd()
+  * Noble update: upstream stable patchset 2025-02-07 (LP: #2097575)
+    - irqchip/gic-v3-its: Fix VSYNC referencing an unmapped VPE on GIC v4.1
+    - xfs: fix error returns from xfs_bmapi_write
+    - xfs: fix xfs_bmap_add_extent_delay_real for partial conversions
+    - xfs: remove a racy if_bytes check in xfs_reflink_end_cow_extent
+    - xfs: require XFS_SB_FEAT_INCOMPAT_LOG_XATTRS for attr log intent item
+      recovery
+    - xfs: check opcode and iovec count match in xlog_recover_attri_commit_pass2
+    - xfs: fix missing check for invalid attr flags
+    - xfs: check shortform attr entry flags specifically
+    - xfs: validate recovered name buffers when recovering xattr items
+    - xfs: enforce one namespace per attribute
+    - xfs: revert commit 44af6c7e59b12
+    - xfs: use dontcache for grabbing inodes during scrub
+    - xfs: match lock mode in xfs_buffered_write_iomap_begin()
+    - xfs: make the seq argument to xfs_bmapi_convert_delalloc() optional
+    - xfs: make xfs_bmapi_convert_delalloc() to allocate the target offset
+    - xfs: convert delayed extents to unwritten when zeroing post eof blocks
+    - xfs: allow symlinks with short remote targets
+    - xfs: make sure sb_fdblocks is non-negative
+    - xfs: fix unlink vs cluster buffer instantiation race
+    - xfs: fix freeing speculative preallocations for preallocated files
+    - xfs: allow unlinked symlinks and dirs with zero size
+    - xfs: restrict when we try to align cow fork delalloc to cowextsz hints
+    - selftests: mptcp: join: change capture/checksum as bool
+    - selftests: mptcp: join: test for prohibited MPC to port-based endp
+    - selftests: mptcp: remove duplicated variables
+    - iio: accel: bma400: Fix uninitialized variable field_value in tap event
+      handling.
+    - bpf: Make sure internal and UAPI bpf_redirect flags don't overlap
+    - bpf: devmap: provide rxq after redirect
+    - cpufreq/amd-pstate: Fix amd_pstate mode switch on shared memory systems
+    - lib/Kconfig.debug: fix grammar in RUST_BUILD_ASSERT_ALLOW
+    - bpf: Fix memory leak in bpf_core_apply
+    - RDMA/bnxt_re: Fix a possible memory leak
+    - RDMA/bnxt_re: Fix incorrect AVID type in WQE structure
+    - RDMA/bnxt_re: Add a check for memory allocation
+    - x86/resctrl: Avoid overflow in MB settings in bw_validate()
+    - ARM: dts: bcm2837-rpi-cm3-io3: Fix HDMI hpd-gpio pin
+    - bpf: Add cookie to perf_event bpf_link_info records
+    - bpf: fix unpopulated name_len field in perf_event link info
+    - selftests/bpf: Add cookies check for perf_event fill_link_info test
+    - selftests/bpf: fix perf_event link info name_len assertion
+    - s390/pci: Handle PCI error codes other than 0x3a
+    - bpf: fix kfunc btf caching for modules
+    - iio: frequency: {admv4420,adrf6780}: format Kconfig entries
+    - iio: frequency: admv4420: fix missing select REMAP_SPI in Kconfig
+    - drm/vmwgfx: Handle possible ENOMEM in vmw_stdu_connector_atomic_check
+    - selftests/bpf: Fix cross-compiling urandom_read
+    - task_work: Add TWA_NMI_CURRENT as an additional notify mode.
+    - sched/core: Disable page allocation in task_tick_mm_cid()
+    - ALSA: hda/cs8409: Fix possible NULL dereference
+    - firmware: arm_scmi: Fix the double free in scmi_debugfs_common_setup()
+    - RDMA/cxgb4: Fix RDMA_CM_EVENT_UNREACHABLE error for iWARP
+    - RDMA/irdma: Fix misspelling of "accept*"
+    - RDMA/srpt: Make slab cache names unique
+    - ipv4: give an IPv4 dev to blackhole_netdev
+    - RDMA/bnxt_re: Fix the max CQ WQEs for older adapters
+    - RDMA/bnxt_re: Fix out of bound check
+    - RDMA/bnxt_re: Return more meaningful error
+    - RDMA/bnxt_re: Fix a bug while setting up Level-2 PBL pages
+    - RDMA/bnxt_re: Fix the GID table length
+    - accel/qaic: Fix the for loop used to walk SG table
+    - drm/msm/dpu: make sure phys resources are properly initialized
+    - drm/msm/dpu: check for overflow in _dpu_crtc_setup_lm_bounds()
+    - drm/msm/dsi: improve/fix dsc pclk calculation
+    - drm/msm/dsi: fix 32-bit signed integer extension in pclk_rate calculation
+    - drm/msm: Avoid NULL dereference in msm_disp_state_print_regs()
+    - drm/msm: Allocate memory for disp snapshot with kvzalloc()
+    - firmware: arm_scmi: Queue in scmi layer for mailbox implementation
+    - net/smc: Fix memory leak when using percpu refs
+    - net: usb: usbnet: fix race in probe failure
+    - net: stmmac: dwmac-tegra: Fix link bring-up sequence
+    - octeontx2-af: Fix potential integer overflows on integer shifts
+    - drm/amd/amdgpu: Fix double unlock in amdgpu_mes_add_ring
+    - macsec: don't increment counters for an unrelated SA
+    - netdevsim: use cond_resched() in nsim_dev_trap_report_work()
+    - net: ethernet: aeroflex: fix potential memory leak in
+      greth_start_xmit_gbit()
+    - net/smc: Fix searching in list of known pnetids in smc_pnet_add_pnetid
+    - net: xilinx: axienet: fix potential memory leak in axienet_start_xmit()
+    - bpf: Fix truncation bug in coerce_reg_to_size_sx()
+    - irqchip/renesas-rzg2l: Fix missing put_device
+    - drm/msm/dpu: don't always program merge_3d block
+    - net: bcmasp: fix potential memory leak in bcmasp_xmit()
+    - tcp/dccp: Don't use timer_pending() in reqsk_queue_unlink().
+    - net: dsa: mv88e6xxx: Fix the max_vid definition for the MV88E6361
+    - genetlink: hold RCU in genlmsg_mcast()
+    - ravb: Remove setting of RX software timestamp
+    - net: ravb: Only advertise Rx/Tx timestamps if hardware supports it
+    - scsi: target: core: Fix null-ptr-deref in target_alloc_device()
+    - smb: client: fix possible double free in smb2_set_ea()
+    - smb: client: fix OOBs when building SMB2_IOCTL request
+    - usb: typec: altmode should keep reference to parent
+    - s390: Initialize psw mask in perf_arch_fetch_caller_regs()
+    - bpf: Fix link info netfilter flags to populate defrag flag
+    - vmxnet3: Fix packet corruption in vmxnet3_xdp_xmit_frame
+    - net/mlx5: Check for invalid vector index on EQ creation
+    - net/mlx5: Fix command bitmask initialization
+    - net/mlx5: Unregister notifier on eswitch init failure
+    - bpf, sockmap: SK_DROP on attempted redirects of unsupported af_vsock
+    - vsock: Update rx_bytes on read_skb()
+    - vsock: Update msg_count on read_skb()
+    - bpf, vsock: Drop static vsock_bpf_prot initialization
+    - riscv, bpf: Make BPF_CMPXCHG fully ordered
+    - nvme-pci: fix race condition between reset and nvme_dev_disable()
+    - bpf: Fix iter/task tid filtering
+    - cdrom: Avoid barrier_nospec() in cdrom_ioctl_media_changed()
+    - khugepaged: inline hpage_collapse_alloc_folio()
+    - khugepaged: convert alloc_charge_hpage to alloc_charge_folio
+    - khugepaged: remove hpage from collapse_file()
+    - mm: khugepaged: fix the arguments order in khugepaged_collapse_file trace
+      point
+    - iio: adc: ti-lmp92064: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - xhci: dbgtty: remove kfifo_out() wrapper
+    - xhci: dbgtty: use kfifo from tty_port struct
+    - xhci: dbc: honor usb transfer size boundaries.
+    - usb: gadget: f_uac2: fix non-newline-terminated function name
+    - usb: gadget: f_uac2: fix return value for UAC2_ATTRIBUTE_STRING store
+    - XHCI: Separate PORT and CAPs macros into dedicated file
+    - usb: dwc3: core: Fix system suspend on TI AM62 platforms
+    - tracing/fprobe-event: cleanup: Fix a wrong comment in fprobe event
+    - tracing/probes: cleanup: Set trace_probe::nr_args at trace_probe_init
+    - tracing/probes: Support $argN in return probe (kprobe and fprobe)
+    - uprobes: encapsulate preparation of uprobe args buffer
+    - uprobes: prepare uprobe args buffer lazily
+    - uprobes: prevent mutex_lock() under rcu_read_lock()
+    - uprobe: avoid out-of-bounds memory access of fetching args
+    - exec: don't WARN for racy path_noexec check
+    - ASoC: amd: yc: Add quirk for HP Dragonfly pro one
+    - ASoC: codecs: lpass-rx-macro: add missing CDC_RX_BCL_VBAT_RF_PROC2 to
+      default regs values
+    - ASoC: fsl_sai: Enable 'FIFO continue on error' FCONT bit
+    - arm64: Force position-independent veneers
+    - udf: refactor udf_current_aext() to handle error
+    - udf: refactor udf_next_aext() to handle error
+    - udf: refactor inode_bmap() to handle error
+    - udf: fix uninit-value use in udf_get_fileshortad
+    - ASoC: qcom: sm8250: add qrb4210-rb2-sndcard compatible string
+    - cifs: Validate content of NFS reparse point buffer
+    - platform/x86: dell-sysman: add support for alienware products
+    - LoongArch: Don't crash in stack_top() for tasks without vDSO
+    - jfs: Fix sanity check in dbMount
+    - tracing/probes: Fix MAX_TRACE_ARGS limit handling
+    - tracing: Consider the NULL character when validating the event length
+    - xfrm: extract dst lookup parameters into a struct
+    - xfrm: respect ip protocols rules criteria when performing dst lookups
+    - netfilter: bpf: must hold reference on net namespace
+    - net/sun3_82586: fix potential memory leak in sun3_82586_send_packet()
+    - net: plip: fix break; causing plip to never transmit
+    - octeon_ep: Implement helper for iterating packets in Rx queue
+    - octeon_ep: Add SKB allocation failures handling in __octep_oq_process_rx()
+    - net: dsa: mv88e6xxx: Fix error when setting port policy on mv88e6393x
+    - fsl/fman: Save device references taken in mac_probe()
+    - fsl/fman: Fix refcount handling of fman-related devices
+    - netfilter: xtables: fix typo causing some targets not to load on IPv6
+    - net: wwan: fix global oob in wwan_rtnl_policy
+    - net/sched: adjust device watchdog timer to detect stopped queue at right
+      time
+    - net: fix races in netdev_tx_sent_queue()/dev_watchdog()
+    - net: usb: usbnet: fix name regression
+    - bpf: Add MEM_WRITE attribute
+    - bpf: Fix overloading of MEM_UNINIT's meaning
+    - bpf: Remove MEM_UNINIT from skb/xdp MTU helpers
+    - net/sched: act_api: deny mismatched skip_sw/skip_hw flags for actions
+      created by classifiers
+    - net: sched: fix use-after-free in taprio_change()
+    - net: sched: use RCU read-side critical section in taprio_dump()
+    - posix-clock: posix-clock: Fix unbalanced locking in pc_clock_settime()
+    - Bluetooth: SCO: Fix UAF on sco_sock_timeout
+    - Bluetooth: ISO: Fix UAF on iso_sock_timeout
+    - bpf,perf: Fix perf_event_detach_bpf_prog error handling
+    - net: dsa: mv88e6xxx: group cycle counter coefficients
+    - net: dsa: mv88e6xxx: read cycle counter period from hardware
+    - net: dsa: mv88e6xxx: support 4000ps cycle counter period
+    - ASoC: dt-bindings: davinci-mcasp: Fix interrupts property
+    - ASoC: dt-bindings: davinci-mcasp: Fix interrupt properties
+    - ASoC: loongson: Fix component check failed on FDT systems
+    - ASoC: max98388: Fix missing increment of variable slot_found
+    - ASoC: rsnd: Fix probe failure on HiHope boards due to endpoint parsing
+    - ASoC: fsl_micfil: Add a flag to distinguish with different volume control
+      types
+    - ALSA: firewire-lib: Avoid division by zero in apply_constraint_to_size()
+    - powercap: dtpm_devfreq: Fix error check against dev_pm_qos_add_request()
+    - nfsd: cancel nfsd_shrinker_work using sync mode in nfs4_state_shutdown_net
+    - ALSA: hda/realtek: Update default depop procedure
+    - smb: client: Handle kstrdup failures for passwords
+    - cpufreq: CPPC: fix perf_to_khz/khz_to_perf conversion exception
+    - btrfs: fix passing 0 to ERR_PTR in btrfs_search_dir_index_item()
+    - btrfs: zoned: fix zone unusable accounting for freed reserved extent
+    - ACPI: resource: Add LG 16T90SP to irq1_level_low_skip_override[]
+    - ACPI: PRM: Find EFI_MEMORY_RUNTIME block for PRM handler and context
+    - ACPI: button: Add DMI quirk for Samsung Galaxy Book2 to fix initial lid
+      detection issue
+    - nilfs2: fix kernel bug due to missing clearing of buffer delay flag
+    - openat2: explicitly return -E2BIG for (usize > PAGE_SIZE)
+    - KVM: nSVM: Ignore nCR3[4:0] when loading PDPTEs from memory
+    - KVM: arm64: Fix shift-out-of-bounds bug
+    - KVM: arm64: Don't eagerly teardown the vgic on init error
+    - x86/lam: Disable ADDRESS_MASKING in most cases
+    - [Config] disable ADDRESS_MASKING
+    - ALSA: hda/tas2781: select CRC32 instead of CRC32_SARWATE
+    - ALSA: hda/realtek: Add subwoofer quirk for Acer Predator G9-593
+    - LoongArch: Get correct cores_per_package for SMT systems
+    - LoongArch: Enable IRQ if do_ale() triggered in irq-enabled context
+    - LoongArch: Make KASAN usable for variable cpu_vabits
+    - xfrm: fix one more kernel-infoleak in algo dumping
+    - hv_netvsc: Fix VF namespace also in synthetic NIC NETDEV_REGISTER event
+    - drm/amd/display: Disable PSR-SU on Parade 08-01 TCON too
+    - selinux: improve error checking in sel_write_load()
+    - net: phy: dp83822: Fix reset pin definitions
+    - ata: libata: Set DID_TIME_OUT for commands that actually timed out
+    - ASoC: qcom: Fix NULL Dereference in asoc_qcom_lpass_cpu_platform_probe()
+    - platform/x86: dell-wmi: Ignore suspend notifications
+    - ACPI: PRM: Clean up guid type in struct prm_handler_info
+    - tracing: probes: Fix to zero initialize a local variable
+    - task_work: make TWA_NMI_CURRENT handling conditional on IRQ_WORK
+    - xfrm: validate new SA's prefixlen using SA family when sel.family is unset
+    - bpf: Use raw_spinlock_t in ringbuf
+    - reset: starfive: jh71x0: Fix accessing the empty member on JH7110 SoC
+    - bpf: Fix unpopulated path_size when uprobe_multi fields unset
+    - RDMA/bnxt_re: Fix incorrect dereference of srq in async event
+    - RDMA/bnxt_re: Get the toggle bits from SRQ events
+    - RDMA/bnxt_re: Change the sequence of updating the CQ toggle value
+    - drm/msm/dpu: move CRTC resource assignment to dpu_encoder_virt_atomic_check
+    - ring-buffer: Fix reader locking when changing the sub buffer order
+    - drm/msm/dpu: Don't always set merge_3d pending flush
+    - drm/msm/a6xx+: Insert a fence wait before SMMU table update
+    - drm/xe: Take job list lock in xe_sched_add_pending_job
+    - drm/xe: Use bookkeep slots for external BO's in exec IOCTL
+    - net: ethernet: mtk_eth_soc: fix memory corruption during fq dma init
+    - net/mlx5e: Don't call cleanup on profile rollback failure
+    - bpf: Fix print_reg_state's constant scalar dump
+    - fsnotify: optimize the case of no parent watcher
+    - fsnotify: Avoid data race between fsnotify_recalc_mask() and
+      fsnotify_object_watched()
+    - drm/xe/mcr: Use Xe2_LPM steering tables for Xe2_HPM
+    - objpool: fix choosing allocation for percpu slots
+    - bnxt_en: replace ptp_lock with irqsave variant
+    - bpf, arm64: Fix address emission with tag-based KASAN enabled
+    - net: dsa: microchip: disable EEE for KSZ879x/KSZ877x/KSZ876x
+    - ASoC: topology: Bump minimal topology ABI version
+    - fbdev: wm8505fb: select CONFIG_FB_IOMEM_FOPS
+    - btrfs: qgroup: set a more sane default value for subtree drop threshold
+    - btrfs: clear force-compress on remount when compress mount option is given
+    - x86/amd_nb: Add new PCI IDs for AMD family 1Ah model 60h-70h
+    - x86/amd_nb: Add new PCI ID for AMD family 1Ah model 20h
+    - btrfs: reject ro->rw reconfiguration if there are hard ro requirements
+    - xfs: don't fail repairs on metadata files with no attr fork
+    - drm/bridge: Fix assignment of the of_node of the parent to aux bridge
+    - platform/x86/intel/pmc: Fix pmc_core_iounmap to call iounmap for valid
+      addresses
+    - fgraph: Fix missing unlock in register_ftrace_graph()
+    - fgraph: Change the name of cpuhp state to "fgraph:online"
+    - ASoC: SOF: Intel: hda: Always clean up link DMA during stop
+    - ASoC: dapm: avoid container_of() to get component
+    - ASoC: qcom: sc7280: Fix missing Soundwire runtime stream alloc
+    - ASoC: qcom: sdm845: add missing soundwire runtime stream alloc
+    - soundwire: intel_ace2x: Send PDI stream number during prepare
+    - x86: support user address masking instead of non-speculative conditional
+    - ASoC: qcom: Select missing common Soundwire module code on SDM845
+    - SAUCE: Revert "iio: adc: ti-lmp92064: add missing select
+      IIO_(TRIGGERED_)BUFFER in Kconfig"
+    - Upstream stable to v6.6.58, v6.6.59, v6.11.6
+  * CVE-2025-21756
+    - vsock: Keep the binding until socket destruction
+    - vsock: Orphan socket after transport release
+  * Fix NIC name changes for ice (LP: #2100264)
+    - ice: Remove ndo_get_phys_port_name
+  * CVE-2024-50256
+    - netfilter: nf_reject_ipv6: fix potential crash in nf_send_reset6()
+  * CVE-2025-21702
+    - pfifo_tail_enqueue: Drop new packet when sch->limit == 0
+  * CVE-2024-50167
+    - be2net: fix potential memory leak in be_xmit()
+  * Fix line-out playback on some platforms with Cirrus Logic “Dolphin” hardware
+    (LP: #2099880)
+    - ALSA: hda/cirrus: Correct the full scale volume set logic
+  * Enable Large Language Model (LLM) workloads using Intel NPU (LP: #2098972)
+    - accel/ivpu: Increase DMA address range
+  * Patchset for TUXEDO devices (LP: #2098104)
+    - wifi: ath12k: add fallback board name without variant while searching
+      board-2.bin
+    - wifi: ath12k: remove unused ATH12K_BD_IE_BOARD_EXT
+    - wifi: ath12k: add support to search regdb data in board-2.bin for WCN7850
+    - wifi: ath12k: support default regdb while searching board-2.bin for WCN7850
+    - ACPI: resource: Use IRQ override on Maibenben X565
+    - ACPI: resource: Do IRQ override on TongFang GXxHRXx and GMxHGxx
+    - ALSA: hda/realtek: Fix headset mic on TUXEDO Gemini 17 Gen3
+    - ALSA: hda/realtek: Fix headset mic on TUXEDO Stellaris 16 Gen6 mb1
+    - PCI: Avoid putting some root ports into D3 on TUXEDO Sirius Gen1
+    - nvme-pci: Add TUXEDO InfinityFlex to Samsung sleep quirk
+    - nvme-pci: Add TUXEDO IBP Gen9 to Samsung sleep quirk
+  * Introduce and use sendpages_ok() instead of sendpage_ok() in nvme-tcp and
+    drbd (LP: #2093871)
+    - net: introduce helper sendpages_ok()
+    - nvme-tcp: use sendpages_ok() instead of sendpage_ok()
+    - drbd: use sendpages_ok() instead of sendpage_ok()
+  * CVE-2024-56765
+    - powerpc/pseries/vas: Add close() callback in vas_vm_ops struct
+  * CVE-2025-21700
+    - net: sched: Disallow replacing of child qdisc from one parent to another
+  * CVE-2024-56615
+    - bpf: fix OOB devmap writes when deleting elements
+  * CVE-2024-56651
+    - can: hi311x: hi3110_can_ist(): fix potential use-after-free
+  * CVE-2024-56627
+    - ksmbd: fix Out-of-Bounds Read in ksmbd_vfs_stream_read
+  * CVE-2024-56600
+    - net: inet6: do not leave a dangling sk pointer in inet6_create()
+  * CVE-2024-56661
+    - tipc: fix NULL deref in cleanup_bearer()
+  * CVE-2024-56642
+    - tipc: Fix use-after-free of kernel socket in cleanup_bearer().
+  * CVE-2024-53227
+    - scsi: bfa: Fix use-after-free in bfad_im_module_exit()
+  * CVE-2024-53237
+    - Bluetooth: fix use-after-free in device_for_each_child()
+  * CVE-2024-53166
+    - block, bfq: fix bfqq uaf in bfq_limit_depth()
+  * CVE-2024-50265
+    - ocfs2: remove entry once instead of null-ptr-dereference in
+      ocfs2_xa_remove()
+  * CVE-2024-50249
+    - ACPI: CPPC: Make rmw_lock a raw_spin_lock
+  * iBFT iSCSI out-of-bounds shift UBSAN warning (LP: #2097824)
+    - iscsi_ibft: Fix UBSAN shift-out-of-bounds warning in ibft_attr_show_nic()
+  * [Ubuntu 24.04] MultiVM - L2 guest(s) running stress-ng getting stuck at
+    booting after triggering crash (LP: #2077722)
+    - KVM: PPC: Book3S HV: Mask off LPCR_MER for a vCPU before running it to avoid
+      spurious interrupts
+  * btrfs will WARN_ON() in btrfs_remove_qgroup() unnecessarily (LP: #2091719)
+    - btrfs: improve the warning and error message for btrfs_remove_qgroup()
+  * CVE-2024-50248
+    - ntfs3: Add bounds checking to mi_enum_attr()
+    - fs/ntfs3: Sequential field availability check in mi_enum_attr()
+  * CVE-2025-21701
+    - net: avoid race between device unregistration and ethnl ops
+  * CVE-2024-57798
+    - drm/dp_mst: Ensure mst_primary pointer is valid in
+      drm_dp_mst_handle_up_req()
+  * CVE-2024-56672
+    - blk-cgroup: Fix UAF in blkcg_unpin_online()
+  * CVE-2024-56658
+    - net: defer final 'struct net' free in netns dismantle
+  * CVE-2024-56598
+    - jfs: array-index-out-of-bounds fix in dtReadFirst
+  * CVE-2024-56595
+    - jfs: add a check to prevent array-index-out-of-bounds in dbAdjTree
+  * CVE-2024-53140
+    - netlink: terminate outstanding dump on socket close
+  * CVE-2024-53063
+    - media: dvbdev: prevent the risk of out of memory access
+  * CVE-2024-50302
+    - HID: core: zero-initialize the report buffer
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 04 Jun 2025 20:20:57 +0900
+
+linux-qcom (6.8.0-1042.42) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1042.42 -proposed tracker (LP: #2112174)
+
+  * Miscellaneous Ubuntu changes
+    - [configs] change CONFIG_HWSPINLOCK_QCOM to y
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 30 May 2025 17:59:33 +0900
+
+linux-qcom (6.8.0-1041.41) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1041.41 -proposed tracker (LP: #2111886)
+
+  * [RB3][x02] spf core errors found in dmesg
+    - SAUCE: qcom: spf-core: use pr_info() for successful logs
+
+  * [RB3][x03] va_macro error found in dmesg
+    - SAUCE: ASoC: lpass-va-macro: change dt entry missing to dev_info()
+
+  * [RB8][x02] spmi errors found in dmesg
+    - SAUCE: arm64: sa8775: remove allow-set-time property from rtc
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: switch WIFI firmware to *.mbn from *.mdt
+
+  * Miscellaneous upstream changes
+    - msm: camera: icp: Remove Redundant Structure Field
+    - msm: camera: uapi: Adding flex array support to fix UBSAN kernel panic
+    - PENDING: rpmsg: glink: do not serve intent request if no callback present
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 28 May 2025 16:55:09 +0900
+
+linux-qcom (6.8.0-1040.40) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1040.40 -proposed tracker (LP: #2110187)
+
+  * "[6490][x02] tc956x_pci-eth errors found in dmesg"
+    - Ubuntu: SAUCE: change phy detection log-level from alert to info
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: follow-up renaming from qcs9075-rb8 to qcs9075-iq-9075-evk
+
+  * Miscellaneous upstream changes
+    - PENDING: qcom: ice: Add ice probe
+    - PENDING: arm64: dts: qcom: Rename qcs9075-rb8 to qcs9075-iq-9075-evk
+    - QCLINUX: arm64: dts: qcom: qcs9075-addons: Rename rb8 to iq-9075-evk
+    - PENDING: tty: serial: qcom-geni-serial: fix CTS control for UART in loopback
+      mode
+    - QCLINUX: arm64: deconfig: enable CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT
+    - PENDING: misc: fastrpc: Remove PD status check
+    - Revert "FROMLIST: arm64: dts: qcom: sa8775p: Add CPUs to psci power domain"
+    - Revert "BACKPORT: UPSTREAM: arm64: dts: qcom: sa8775p: add CPU idle states"
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 09 May 2025 17:00:23 +0900
+
+linux-qcom (6.8.0-1039.39) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1039.39 -proposed tracker (LP: #2108955)
+
+  * [RB8][x02] hd3ss3220 not boud to the device
+    - Revert "usb: dwc3: core: set force_gen1 bit in USB31 devices if max speed is
+      SS"
+
+  * "[RB8][x02] The firmware for i2c_qcom_geni (qupv3fw.elf) not in
+    initramfs" // "[RB8][x02] qcom_geni_serial errors found in dmesg"
+    - SAUCE: qcom-geni-se.c: add MODULE_FIRMWARE() to copy firmware to initrd
+
+  * Miscellaneous upstream changes
+    - kgsl: Read DDR type from device tree node
+    - qcom: qtee_shmbridge: change pr_err() to pr_info() for bridge size
+    - qcom: qtee_shmbridge: change pr_err() to pr_info() for bridge size
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 24 Apr 2025 12:47:31 +0900
+
+linux-qcom (6.8.0-1038.38) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1038.38 -proposed tracker (LP: #2107286)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.qcom/dkms-versions -- update from kernel-versions
+      (main/d2025.04.13)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: fix firmware for rb8
+
+  * Miscellaneous upstream changes
+    - kgsl: Fix UBSAN warning in kgsl_get_page_size
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 14 Apr 2025 02:26:32 +0900
+
+linux-qcom (6.8.0-1037.37) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1037.37 -proposed tracker (LP: #2106781)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: add QCS6490 industrical kit dt to compiled-dtb.dtb
+    - [Config] Disable CONFIG_DRM_MSM_VALIDATE_XML
+
+  * Miscellaneous upstream changes
+    - QCLINUX: arm64: dts: qcom: qcm6490-graphics: Don't disable drm gpu/gmu nodes
+    - QCLINUX: arm64: dts: qcom: qcs9100-graphics: Don't disable drm gpu/gmu nodes
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 11 Apr 2025 08:22:42 +0900
+
+linux-qcom (6.8.0-1036.36) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1036.36 -proposed tracker (LP: #2105444)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.qcom/dkms-versions -- update from kernel-versions
+      (main/d2025.03.31)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Add Makefile code to apply overlays for GA1.4
+    - [Packaging] build zfs
+
+  * Miscellaneous upstream changes
+    - PENDING: drm/msm/dsi: Add DSI support for SA8775P
+    - PENDING: drm/msm/dsi: add DSI PHY configuration for SA8775P
+    - QCLINUX: Revert "PENDING: drm/bridge: anx7625: Fix circular dependency"
+    - PENDING: arm64: dts: qcom: sa8775p: add DSI CTRL and PHY support
+    - PENDING: ASoC: dt-bindings: q6dsp: Add High Speed Audio DAI ID support for
+      MI2S and TDM
+    - PENDING: net: pcs: Add 5G baseR changes in PCS driver
+    - PENDING: net: stmmac: Add support for 5GbaseR to configure mac
+    - PENDING: ASoC: qcom: q6dsp: Add SDR High speed DAI support for MI2S and TDM
+    - PENDING: ASoC: qcom: qcm9100: Add machine driver for qcs9100-ride and
+      qcs9075-rb8 boards
+    - PENDING: net: phy: aquantia: Add support for 5GbaseR
+    - PENDING: arm64: dts: qcom: sa8775p: add anx7625 DSI to DP bridge nodes
+    - PENDING: drm/bridge: anx7625: vote for pm runtime during bridge attach
+    - PENDING: drm/bridge: anx7625: update bridge_ops and sink detect logic
+    - PENDING: arm64: defconfig: qcom_gen5auto: Enable TSC
+    - PENDING: arm64: dts: qcom: qcs8300: Add support for camss
+    - PENDING: media: qcom: camss: Add support for camss driver on qcs8300
+    - PENDING: media: qcom: camss: add TPG support on camss for qcs8300
+    - PENDING: net: stmmac: Enable PTP Packet id based timestamping
+    - PENDING: net: PCS: Call PCS link up sequence for 10GBASER
+    - PENDING: net: stmmac: Add support for 10GBASER mode within Mac link up
+    - PENDING: ARM: dts: msm: Add RPMh stats for 8255p
+    - QCLINUX: arm64: dts: qcom: Update the DAI ID for SDR High Speed dailinks
+    - QCLINUX: Revert "PENDING: tty: serial: qcom-geni-serial: Increase Rx buffer
+      size"
+    - UPSTREAM: BACKPORT: arm64: dts: qcm6490: Add interconnect for CDSP
+      remoteproc
+    - BACKPORT: FROMLIST: remoteproc: qcom: Add iommu map_unmap helper function
+    - BACKPORT: FROMLIST: remoteproc: qcom: Add helper function to support IOMMU
+      devmem translation
+    - BACKPORT: FROMLIST: remoteproc: qcom: Add support to parse qcom,devmem
+      property
+    - BACKPORT: FROMLIST: remoteproc: qcom: Add support of SHM bridge to enable
+      memory protection
+    - BACKPORT: FROMLIST: remoteproc: qcom: Enable map/unmap and SHM bridge
+      support
+    - QCLINUX: drm/msm: Remove changes made to prevent gpu probe
+    - FROMLIST: arm64: dts: qcom: sa8775p: Add gpu and gmu nodes
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Don't disable drm gpu/gmu nodes
+    - QCLINUX: arm64: dts: qcom: qcs615: addons: Add coresight nodes
+    - PENDING: arm64: dts: qcom: sa8255p: Update hysteresis to 10degC
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add EL2 dtb support
+    - QCLINUX: arm64: dts: qcom: qcs615: addons: Add memory dump table
+    - QCLINUX: arm64: defconfig: qcom: Enable QCS9100 machine driver config
+    - PENDING: arm64: dts: qcom: sa7255p: Disable USB U1/U2 entry
+    - FROMGIT: arm64: dts: qcom: sc8280xp: Disable USB U1/U2 entry
+    - FROMGIT: arm64: dts: qcom: sc8180x: Disable USB U1/U2 entry
+    - PENDING: Coresight: Add an integer array to tmc driver data
+    - PENDING: pinctrl: qcom: fix sa8775p lpass lpi quad pinctrl setting
+    - FROMLIST: arm64: dts: qcom: sa8775p: Remove extra entries from the iommus
+      property
+    - QCLINUX: arm64: dts: qcom: add hs0 mi2s dai for qcs9075-rb8
+    - QCLINUX: arm64: dts: qcom: qcs615: addons: Enable DCC
+    - PENDING: usb: dwc3: qcom: Adding GPIO-based regulator functionality for VBUS
+    - PENDING: arm64: dts: configs: Enable HD3SS322 USB Type-C DRP port controller
+      driver on QCS9075 RB8
+    - PENDING: arm64: dts: qcom: Flatten USB DT node for USB0 on QCS9075 RB8
+      Platform
+    - PENDING: arm64: dts: qcom: Add DRD mode support for USB0 on QCS9075 RB8
+    - PENDING: arm64: dts: qcom: Flatten USB DT node for USB1 on QCS9075 RB8
+      Platform
+    - PENDING: arm64: dts: qcom: Add host mode support for USB1 on QCS9075 RB8
+    - FROMLIST: dt-bindings: clock: Add Qualcomm QCS615 Camera clock controller
+    - FROMLIST: clk: qcom: camcc-qcs615: Add QCS615 camera clock controller driver
+    - FROMLIST: dt-bindings: clock: Add Qualcomm QCS615 Display clock controller
+    - FROMLIST: clk: qcom: dispcc-qcs615: Add QCS615 display clock controller
+      driver
+    - FROMLIST: dt-bindings: clock: Add Qualcomm QCS615 Graphics clock controller
+    - FROMLIST: clk: qcom: gpucc-qcs615: Add QCS615 graphics clock controller
+      driver
+    - FROMLIST: dt-bindings: clock: Add Qualcomm QCS615 Video clock controller
+    - FROMLIST: clk: qcom: videocc-qcs615: Add QCS615 video clock controller
+      driver
+    - FROMLIST: arm64: defconfig: Enable QCS615 clock controllers
+    - PENDING: ASoC: qcom: q6dsp: Update formats and max rate for Primary i2s
+    - QCLINUX: arm64: defconfigs: Disable TBU support
+    - FROMLIST: arm64: dts: qcom: sa8775p-ride: Add firmware-name in BT node
+    - QCLINUX: Revert "PENDING: arm64: qcs9075-rb8: disable uart bt en pin in DTS"
+    - FROMLIST: arm64: dts: qcom: sa8775p: Remove cdsp compute-cb@10
+    - FROMLIST: arm64: dts: qcom: qcs8300-ride: Add firmware-name in BT node
+    - PENDING: arm64: dts: qcom: qcs8300: enable DSI-DP bridge port on QCS8300
+    - PENDING: driver: bluetooth: hci_qca: fix SSR unable to wake up bug
+    - QCLINUX: arm64: deconfig: Enable QCS615 clock controllers
+    - FROMLIST: arm64: dts: qcom: Add clock nodes for multimedia clock
+    - FROMLIST: arm64: dts: qcom: Add cpu scaling clock node
+    - QCLINUX: ASoC: qcom: common: Add qcom_snd_parse_of_v2 support
+    - QCLINUX: arm64: defconfigs: Enable CONFIG_PM_DEBUG
+    - PENDING: serial: qcom-geni: Optimize qcom_geni_uart_ports and increase UART
+      ports to 5
+    - QCLINUX: firmware: qcom_tzmem: Use ns_vmid_num to set self owner bit
+    - QCLINUX: arm64: dts: qcom: sa8775p: Fix cdsp1 node properties
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add EL2 dtb support for ride board
+    - PENDING: ASoC: qcom: q6dsp: Update rates for Primary i2s rx
+    - QCLINUX: arm64: dts: Remove unused pcie1 QPS615 phy node for QEP8121
+    - PENDING: arm64: dts: qcom: qcs9075: Add displayport1 device node
+    - PENDING: serial: qcom-geni-serial: Enable support for
+    - PENDING: net: stmmac: dwmac-qcom-ethqos: Configure host DMA width for
+      SA8797P
+    - QCLINUX: arm64: dts: Replace AQR113c phy with RTL8211 phy
+    - QCLINUX: arm64: defconfig: enable Novatek NT36672E and Lontium lt9611UXC
+      configs
+    - PENDING: net: stmmac: Fix NULL pointer access for GPTP packets
+    - PENDING: arm64: dts: qcom: qcs9075: Change phy-mode to SGMII
+    - QCLINUX: ASoC: qcom: qcm6490: Use qcom_snd_parse_of_v2 to support common
+      dailink data
+    - PENDING: ASoC: qcom: qcm9100: Fix the dapm routings for qcs8300
+    - QCLINUX: duplicate msm/ to msm_default/
+    - QCLINUX: Add support to compile msm_display.ko
+    - Ubuntu: [Config] update CONFIGs for GA 1.4
+
+  [ Ubuntu: 6.8.0-56.58 ]
+
+  * noble/linux: 6.8.0-56.58 -proposed tracker (LP: #2098244)
+  * Noble update: upstream stable patchset 2024-07-19 (LP: #2073603)
+    - Revert "drm: Make drivers depends on DRM_DW_HDMI"
+    - Revert "UBUNTU: [Config] Drivers now depend on DRM_DW_HDMI"
+  * drm/amd/display: Add check for granularity in dml ceil/floor helpers
+    (LP: #2098080)
+    - drm/amd/display: Add check for granularity in dml ceil/floor helpers
+  * optimized default EPP for GNR family (LP: #2097554)
+    - cpufreq: intel_pstate: Update Balance-performance EPP for Granite Rapids
+  * Incorrect LAPIC/x2APIC parsing order (LP: #2097455)
+    - x86/acpi: Fix LAPIC/x2APIC parsing order
+  * MGLRU: page allocation failure on NUMA-enabled systems (LP: #2097214)
+    - mm/vmscan: wake up flushers conditionally to avoid cgroup OOM
+  * Upstream commit 65357e2c164a: "RDMA/mana_ib: set node_guid" applied
+    incorrectly (LP: #2096885)
+    - Revert "RDMA/mana_ib: set node_guid"
+  * AppArmor early policy load not funcitoning (LP: #2095370)
+    - SAUCE: Revert "UBUNTU: SAUCE: apparmor4.0.0 [67/90]: userns - add the
+      ability to reference a global variable for a feature value"
+  * apparmor unconfined profile blocks pivot_root (LP: #2067900)
+    - SAUCE: Revert "UBUNTU: SAUCE: apparmor4.0.0 [81/90]: apparmor: convert easy
+      uses of unconfined() to label_mediates()"
+  * CVE-2024-50117
+    - drm/amd: Guard against bad data for ATIF ACPI method
+  * CVE-2024-56582
+    - btrfs: fix use-after-free in btrfs_encoded_read_endio()
+  * CVE-2024-53165
+    - sh: intc: Fix use-after-free bug in register_intc_controller()
+  * CVE-2024-53156
+    - wifi: ath9k: add range check for conn_rsp_epid in htc_connect_service()
+  * CVE-2024-56663
+    - wifi: nl80211: fix NL80211_ATTR_MLO_LINK_ID off-by-one
+  * CVE-2024-56614
+    - xsk: fix OOB map writes when deleting elements
+  * VM boots slowly with large-BAR GPU Passthrough due to pci/probe.c redundancy
+    (LP: #2097389)
+    - PCI: Batch BAR sizing operations
+  * Noble update: upstream stable patchset 2025-02-04 (LP: #2097393)
+    - Revert "PCI/MSI: Provide stubs for IMS functions"
+    - gfs2: Revert "introduce qd_bh_get_or_undo"
+    - gfs2: qd_check_sync cleanups
+    - gfs2: Revert "ignore negated quota changes"
+    - Revert "powerpc/ps3_defconfig: Disable PPC64_BIG_ENDIAN_ELF_ABI_V2"
+    - tracing: Have saved_cmdlines arrays all in one allocation
+    - spi: spi-fsl-lpspi: remove redundant spi_controller_put call
+    - ata: ahci: Add mask_port_map module parameter
+    - ASoC: tas2781: mark dvc_tlv with __maybe_unused
+    - scsi: sd: Do not repeat the starting disk message
+    - bootconfig: Fix the kerneldoc of _xbc_exit()
+    - perf sched: Move start_work_mutex and work_done_wait_mutex initialization to
+      perf_sched__replay()
+    - perf sched: Fix memory leak in perf_sched__map()
+    - perf sched: Move curr_thread initialization to perf_sched__map()
+    - perf sched: Move curr_pid and cpu_last_switched initialization to
+      perf_sched__{lat|map|replay}()
+    - libsubcmd: Don't free the usage string
+    - selftests: Introduce Makefile variable to list shared bash scripts
+    - jbd2: fix kernel-doc for j_transaction_overhead_buffers
+    - lib/build_OID_registry: avoid non-destructive substitution for Perl < 5.13.2
+      compat
+    - drm/amd/display: Remove a redundant check in authenticated_dp
+    - drm/amd/display: Revert "Check HDCP returned status"
+    - zram: don't free statically defined names
+    - x86/amd_nb: Add new PCI IDs for AMD family 0x1a
+    - rtnetlink: change nlk->cb_mutex role
+    - rtnetlink: add RTNL_FLAG_DUMP_UNLOCKED flag
+    - mpls: no longer hold RTNL in mpls_netconf_dump_devconf()
+    - phonet: no longer hold RTNL in route_dumpit()
+    - rcu/nocb: Make IRQs disablement symmetric
+    - HID: asus: add ROG Ally N-Key ID and keycodes
+    - HID: asus: add ROG Z13 lightbar
+    - hid-asus: add ROG Ally X prod ID to quirk list
+    - scsi: Revert "scsi: sd: Do not repeat the starting disk message"
+    - btrfs: fix uninitialized pointer free in add_inode_ref()
+    - btrfs: fix uninitialized pointer free on read_alloc_one_name() error
+    - ksmbd: fix user-after-free from session log off
+    - ALSA: hda/conexant - Fix audio routing for HP EliteOne 1000 G2
+    - mptcp: pm: fix UaF read in mptcp_pm_nl_rm_addr_or_subflow
+    - net: enetc: remove xdp_drops statistic from enetc_xdp_drop()
+    - net: enetc: block concurrent XDP transmissions during ring reconfiguration
+    - net: enetc: disable Tx BD rings after they are empty
+    - net: enetc: disable NAPI after all rings are disabled
+    - net: enetc: add missing static descriptor and inline keyword
+    - posix-clock: Fix missing timespec64 check in pc_clock_settime()
+    - udp: Compute L4 checksum as usual when not segmenting the skb
+    - arm64: probes: Remove broken LDR (literal) uprobe support
+    - arm64: probes: Fix simulate_ldr*_literal()
+    - arm64: probes: Fix uprobes for big-endian kernels
+    - net: macb: Avoid 20s boot delay by skipping MDIO bus registration for fixed-
+      link PHY
+    - net: microchip: vcap api: Fix memory leaks in vcap_api_encode_rule_test()
+    - maple_tree: correct tree corruption on spanning store
+    - nilfs2: propagate directory read errors from nilfs_find_entry()
+    - fat: fix uninitialized variable
+    - mm/mremap: fix move_normal_pmd/retract_page_tables race
+    - mm/swapfile: skip HugeTLB pages for unuse_vma
+    - mm/damon/tests/sysfs-kunit.h: fix memory leak in
+      damon_sysfs_test_add_targets()
+    - tcp: fix mptcp DSS corruption due to large pmtu xmit
+    - net: fec: Move `fec_ptp_read()` to the top of the file
+    - net: fec: Remove duplicated code
+    - mptcp: prevent MPC handshake on port-based signal endpoints
+    - iommu/vt-d: Fix incorrect pci_for_each_dma_alias() for non-PCI devices
+    - s390/sclp: Deactivate sclp after all its users
+    - s390/sclp_vt220: Convert newlines to CRLF instead of LFCR
+    - KVM: s390: gaccess: Check if guest address is in memslot
+    - KVM: s390: Change virtual to physical address access in diag 0x258 handler
+    - x86/cpufeatures: Define X86_FEATURE_AMD_IBPB_RET
+    - x86/cpufeatures: Add a IBPB_NO_RET BUG flag
+    - x86/entry: Have entry_ibpb() invalidate return predictions
+    - x86/bugs: Skip RSB fill at VMEXIT
+    - x86/bugs: Do not use UNTRAIN_RET with IBPB on entry
+    - fgraph: Use CPU hotplug mechanism to initialize idle shadow stacks
+    - blk-rq-qos: fix crash on rq_qos_wait vs. rq_qos_wake_function race
+    - io_uring/sqpoll: close race on waiting for sqring entries
+    - blk-mq: setup queue ->tag_set before initializing hctx
+    - ublk: don't allow user copy for unprivileged device
+    - selftest: hid: add the missing tests directory
+    - Input: xpad - add support for MSI Claw A1M
+    - scsi: mpi3mr: Correct a test in mpi3mr_sas_port_add()
+    - scsi: mpi3mr: Validate SAS port assignments
+    - scsi: ufs: core: Set SDEV_OFFLINE when UFS is shut down
+    - scsi: ufs: core: Fix the issue of ICU failure
+    - scsi: ufs: core: Requeue aborted request
+    - drm/radeon: Fix encoder->possible_clones
+    - drm/i915/dp_mst: Handle error during DSC BW overhead/slice calculation
+    - drm/i915/dp_mst: Don't require DSC hblank quirk for a non-DSC compatible
+      mode
+    - drm/xe/xe_sync: initialise ufence.signalled
+    - drm/xe/ufence: ufence can be signaled right after wait_woken
+    - drm/vmwgfx: Cleanup kms setup without 3d
+    - drm/vmwgfx: Handle surface check failure correctly
+    - drm/amdgpu/pm: Fix code alignment issue
+    - drm/amdgpu/smu13: always apply the powersave optimization
+    - drm/amdgpu/swsmu: Only force workload setup on init
+    - iio: dac: ad5770r: add missing select REGMAP_SPI in Kconfig
+    - iio: dac: ltc1660: add missing select REGMAP_SPI in Kconfig
+    - iio: dac: stm32-dac-core: add missing select REGMAP_MMIO in Kconfig
+    - iio: adc: ti-ads8688: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: hid-sensors: Fix an error handling path in
+      _hid_sensor_set_report_latency()
+    - iio: light: veml6030: fix ALS sensor resolution
+    - iio: light: veml6030: fix IIO device retrieval from embedded device
+    - iio: light: opt3001: add missing full-scale range value
+    - iio: amplifiers: ada4250: add missing select REGMAP_SPI in Kconfig
+    - iio: frequency: adf4377: add missing select REMAP_SPI in Kconfig
+    - iio: light: bu27008: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: resolver: ad2s1210 add missing select REGMAP in Kconfig
+    - iio: pressure: bm1390: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: dac: ad5766: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: proximity: mb1232: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: dac: ad3552r: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: adc: ti-lmp92064: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: adc: ti-lmp92064: add missing select REGMAP_SPI in Kconfig
+    - iio: adc: ti-ads124s08: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - iio: resolver: ad2s1210: add missing select (TRIGGERED_)BUFFER in Kconfig
+    - iio: accel: kx022a: add missing select IIO_(TRIGGERED_)BUFFER in Kconfig
+    - Bluetooth: Call iso_exit() on module unload
+    - Bluetooth: Remove debugfs directory on module init failure
+    - Bluetooth: ISO: Fix multiple init when debugfs is disabled
+    - Bluetooth: btusb: Fix not being able to reconnect after suspend
+    - Bluetooth: btusb: Fix regression with fake CSR controllers 0a12:0001
+    - vt: prevent kernel-infoleak in con_font_get()
+    - xhci: tegra: fix checked USB2 port number
+    - xhci: Fix incorrect stream context type macro
+    - xhci: Mitigate failed set dequeue pointer commands
+    - USB: serial: option: add support for Quectel EG916Q-GL
+    - USB: serial: option: add Telit FN920C04 MBIM compositions
+    - usb: typec: qcom-pmic-typec: fix sink status being overwritten with RP_DEF
+    - usb: dwc3: Wait for EndXfer completion before restoring GUSB2PHYCFG
+    - misc: microchip: pci1xxxx: add support for NVMEM_DEVID_AUTO for EEPROM
+      device
+    - misc: microchip: pci1xxxx: add support for NVMEM_DEVID_AUTO for OTP device
+    - serial: imx: Update mctrl old_status on RTSD interrupt
+    - parport: Proper fix for array out-of-bounds access
+    - x86/resctrl: Annotate get_mem_config() functions as __init
+    - x86/apic: Always explicitly disarm TSC-deadline timer
+    - x86/CPU/AMD: Only apply Zenbleed fix for Zen2 during late microcode load
+    - x86/entry_32: Do not clobber user EFLAGS.ZF
+    - x86/entry_32: Clear CPU buffers after register restore in NMI return
+    - tty: n_gsm: Fix use-after-free in gsm_cleanup_mux
+    - x86/bugs: Use code segment selector for VERW operand
+    - pinctrl: intel: platform: fix error path in device_for_each_child_node()
+    - pinctrl: ocelot: fix system hang on level based interrupts
+    - pinctrl: stm32: check devm_kasprintf() returned value
+    - pinctrl: apple: check devm_kasprintf() returned value
+    - irqchip/gic-v4: Don't allow a VMOVP on a dying VPE
+    - irqchip/sifive-plic: Unmask interrupt in plic_irq_enable()
+    - serial: qcom-geni: fix polled console initialisation
+    - serial: qcom-geni: revert broken hibernation support
+    - serial: qcom-geni: fix shutdown race
+    - serial: qcom-geni: fix dma rx cancellation
+    - serial: qcom-geni: fix receiver enable
+    - mm: vmscan.c: fix OOM on swap stress test
+    - ALSA: hda/conexant - Use cached pin control for Node 0x1d on HP EliteOne
+      1000 G2
+    - Upstream stable to v6.6.57, v6.11.5
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301)
+    - Revert "perf callchain: Fix stitch LBR memory leaks"
+    - ASoC: amd: acp: add ZSC control register programming sequence
+    - virtio: rename virtio_config_enabled to virtio_config_core_enabled
+    - virtio: allow driver to disable the configure change notification
+    - virtio-net: synchronize operstate with admin state on up/down
+    - virtio-net: synchronize probe with ndo_set_features
+    - wifi: rtw89: limit the PPDU length for VHT rate to 0x40000
+    - af_unix: Don't call skb_get() for OOB skb.
+    - af_unix: Remove single nest in manage_oob().
+    - af_unix: Rename unlinked_skb in manage_oob().
+    - af_unix: Move spin_lock() in manage_oob().
+    - iommu/amd: Move allocation of the top table into v1_alloc_pgtable
+    - iommu/amd: Set the pgsize_bitmap correctly
+    - drm/xe: Move and export xe_hw_engine lookup.
+    - drm/msm/dp: rename wide_bus_en to wide_bus_supported
+    - drm/msm/dp: enable widebus on all relevant chipsets
+    - bpf, arm64: Fix tailcall hierarchy
+    - libbpf: Don't take direct pointers into BTF data from st_ops
+    - s390/entry: Move early program check handler to entry.S
+    - selftests/bpf: fix to avoid __msg tag de-duplication by clang
+    - libbpf: Ensure new BTF objects inherit input endianness
+    - PCI: dwc: ep: Rename dw_pcie_ep_exit() to dw_pcie_ep_deinit()
+    - PCI: qcom-ep: Enable controller resources like PHY only after refclk is
+      available
+    - net: ravb: Fix maximum TX frame size for GbEth devices
+    - ravb: Make it clear the information relates to maximum frame size
+    - net: ravb: Fix R-Car RX frame size limit
+    - netfilter: nf_tables: missing objects with no memcg accounting
+    - PCI: dra7xx: Fix error handling when IRQ request fails in probe
+    - KVM: x86: Re-split x2APIC ICR into ICR+ICR2 for AMD (x2AVIC)
+    - intel_idle: fix ACPI _CST matching for newer Xeon platforms
+    - wifi: mt76: mt7925: fix a potential association failure upon resuming
+    - cifs: Remove intermediate object of failed create reparse call
+    - drm/amd/display: Disable replay if VRR capability is false
+    - drm/amd/display: Fix VRR cannot enable
+    - l2tp: free sessions using rcu
+    - net: skbuff: sprinkle more __GFP_NOWARN on ingress allocs
+    - nvme: fix metadata handling in nvme-passthrough
+    - wifi: wilc1000: Do not operate uninitialized hardware during suspend/resume
+    - x86/apic: Remove logical destination mode for 64-bit
+    - pmdomain: core: Use dev_name() instead of kobject_get_path() in debugfs
+    - drm/xe: Name and document Wa_14019789679
+    - drm/xe: Add timeout to preempt fences
+    - drm/amd/display: Fix possible overflow in integer multiplication
+    - ext4: fix error message when rejecting the default hash
+    - power: supply: Drop use_cnt check from power_supply_property_is_writeable()
+    - ALSA: hda/realtek: fix mute/micmute LED for HP mt645 G8
+    - drm/xe: Generate oob before compiling anything
+    - clk: qcom: gcc-sc8180x: Register QUPv3 RCGs for DFS on sc8180x
+    - drm/amd/display: Restore Optimized pbn Value if Failed to Disable DSC
+    - Revert "drm/amd/display: Skip Recompute DSC Params if no Stream on Link"
+    - pmdomain: core: Reduce debug summary table width
+    - fs/ntfs3: Do not call file_modified if collapse range failed
+    - fs/ntfs3: Optimize large writes into sparse file
+    - fs/ntfs3: Fix sparse warning in ni_fiemap
+    - fs/ntfs3: Refactor enum_rstbl to suppress static checker
+    - virtio_console: fix misc probe bugs
+    - ntfs3: Change to non-blocking allocation in ntfs_d_hash
+    - bpf: Call the missed btf_record_free() when map creation fails
+    - selftests/bpf: Fix ARG_PTR_TO_LONG {half-,}uninitialized test
+    - bpf: Check percpu map value size first
+    - s390/facility: Disable compile time optimization for decompressor code
+    - s390/mm: Add cond_resched() to cmm_alloc/free_pages()
+    - bpf, x64: Fix a jit convergence issue
+    - ext4: nested locking for xattr inode
+    - s390/cpum_sf: Remove WARN_ON_ONCE statements
+    - ktest.pl: Avoid false positives with grub2 skip regex
+    - soundwire: intel_bus_common: enable interrupts before exiting reset
+    - PCI: Add function 0 DMA alias quirk for Glenfly Arise chip
+    - clk: bcm: bcm53573: fix OF node leak in init
+    - PCI: Add ACS quirk for Qualcomm SA8775P
+    - i2c: i801: Use a different adapter-name for IDF adapters
+    - PCI: Mark Creative Labs EMU20k2 INTx masking as broken
+    - RISC-V: Don't have MAX_PHYSMEM_BITS exceed phys_addr_t
+    - mfd: intel_soc_pmic_chtwc: Make Lenovo Yoga Tab 3 X90F DMI match less strict
+    - mfd: intel-lpss: Add Intel Arrow Lake-H LPSS PCI IDs
+    - mfd: intel-lpss: Rename SPI intel_lpss_platform_info structs
+    - mfd: intel-lpss: Add Intel Panther Lake LPSS PCI IDs
+    - riscv: Omit optimized string routines when using KASAN
+    - riscv: avoid Imbalance in RAS
+    - RDMA/mlx5: Enforce umem boundaries for explicit ODP page faults
+    - PCI: qcom: Disable mirroring of DBI and iATU register space in BAR region
+    - PCI: endpoint: Assign PCI domain number for endpoint controllers
+    - soundwire: cadence: re-check Peripheral status with delayed_work
+    - riscv/kexec_file: Fix relocation type R_RISCV_ADD16 and R_RISCV_SUB16
+      unknown
+    - media: videobuf2-core: clear memory related fields in
+      __vb2_plane_dmabuf_put()
+    - remoteproc: imx_rproc: Use imx specific hook for find_loaded_rsc_table
+    - usb: chipidea: udc: enable suspend interrupt after usb reset
+    - usb: dwc2: Adjust the timing of USB Driver Interrupt Registration in the
+      Crashkernel Scenario
+    - xhci: dbc: Fix STALL transfer event handling
+    - usb: host: xhci-plat: Parse xhci-missing_cas_quirk and apply quirk
+    - comedi: ni_routing: tools: Check when the file could not be opened
+    - LoongArch: Fix memleak in pci_acpi_scan_root()
+    - netfilter: nf_nat: don't try nat source port reallocation for reverse dir
+      clash
+    - netfilter: nf_reject: Fix build warning when CONFIG_BRIDGE_NETFILTER=n
+    - tools/iio: Add memory allocation failure check for trigger_name
+    - staging: vme_user: added bound check to geoid
+    - driver core: bus: Return -EIO instead of 0 when show/store invalid bus
+      attribute
+    - scsi: lpfc: Add ELS_RSP cmd to the list of WQEs to flush in
+      lpfc_els_flush_cmd()
+    - scsi: lpfc: Revise TRACE_EVENT log flag severities from KERN_ERR to
+      KERN_WARNING
+    - NFSD: Mark filecache "down" if init fails
+    - nfsd: nfsd_destroy_serv() must call svc_destroy() even if nfsd_startup_net()
+      failed
+    - ice: set correct dst VSI in only LAN filters
+    - ice: clear port vlan config during reset
+    - ice: disallow DPLL_PIN_STATE_SELECTABLE for dpll output pins
+    - ice: fix VLAN replay after reset
+    - SUNRPC: Fix integer overflow in decode_rc_list()
+    - tcp: fix to allow timestamp undo if no retransmits were sent
+    - tcp: fix tcp_enter_recovery() to zero retrans_stamp when it's safe
+    - tcp: fix TFO SYN_RECV to not zero retrans_stamp with retransmits out
+    - rxrpc: Fix uninitialised variable in rxrpc_send_data()
+    - selftests: net: no_forwarding: fix VID for $swp2 in one_bridge_two_pvids()
+      test
+    - Bluetooth: btusb: Don't fail external suspend requests
+    - net: phy: bcm84881: Fix some error handling paths
+    - Revert "net: stmmac: set PP_FLAG_DMA_SYNC_DEV only if XDP is enabled"
+    - net: ethernet: adi: adin1110: Fix some error handling path in
+      adin1110_read_fifo()
+    - net: dsa: b53: fix jumbo frame mtu check
+    - net: dsa: b53: fix max MTU for 1g switches
+    - net: dsa: b53: fix max MTU for BCM5325/BCM5365
+    - net: dsa: b53: allow lower MTUs on BCM5325/5365
+    - net: dsa: b53: fix jumbo frames on 10/100 ports
+    - drm/nouveau: pass cli to nouveau_channel_new() instead of drm+device
+    - nouveau/dmem: Fix privileged error in copy engine channel
+    - gpio: aspeed: Add the flush write to ensure the write complete.
+    - gpio: aspeed: Use devm_clk api to manage clock source
+    - powercap: intel_rapl_tpmi: Ignore minor version change
+    - ice: Fix netif_is_ice() in Safe Mode
+    - ice: Flush FDB entries before reset
+    - e1000e: change I219 (19) devices to ADP
+    - net: ibm: emac: mal: fix wrong goto
+    - btrfs: zoned: fix missing RCU locking in error message when loading zone
+      info
+    - sctp: ensure sk_state is set to CLOSED if hashing fails in sctp_listen_start
+    - netfilter: fib: check correct rtable in vrf setups
+    - net: ibm: emac: mal: add dcr_unmap to _remove
+    - net: dsa: refuse cross-chip mirroring operations
+    - rtnetlink: Add bulk registration helpers for rtnetlink message handlers.
+    - vxlan: Handle error of rtnl_register_module().
+    - bridge: Handle error of rtnl_register_module().
+    - mctp: Handle error of rtnl_register_module().
+    - mpls: Handle error of rtnl_register_module().
+    - phonet: Handle error of rtnl_register_module().
+    - rcu/nocb: Fix rcuog wake-up from offline softirq
+    - x86/amd_nb: Add new PCI IDs for AMD family 1Ah model 60h
+    - HID: multitouch: Add support for lenovo Y9000P Touchpad
+    - hwmon: intel-m10-bmc-hwmon: relabel Columbiaville to CVL Die Temperature
+    - hwmon: (tmp513) Add missing dependency on REGMAP_I2C
+    - hwmon: (mc34vr500) Add missing dependency on REGMAP_I2C
+    - hwmon: (adm9240) Add missing dependency on REGMAP_I2C
+    - hwmon: (adt7470) Add missing dependency on REGMAP_I2C
+    - hwmon: (ltc2991) Add missing dependency on REGMAP_I2C
+    - HID: plantronics: Workaround for an unexcepted opposite volume key
+    - Revert "usb: yurex: Replace snprintf() with the safer scnprintf() variant"
+    - usb: dwc3: core: Stop processing of pending events if controller is halted
+    - usb: xhci: Fix problem with xhci resume from suspend
+    - usb: storage: ignore bogus device raised by JieLi BR21 USB sound chip
+    - usb: dwc3: re-enable runtime PM after failed resume
+    - usb: gadget: core: force synchronous registration
+    - hid: intel-ish-hid: Fix uninitialized variable 'rv' in
+      ish_fw_xfer_direct_dma
+    - ACPI: resource: Make Asus ExpertBook B2402 matches cover more models
+    - ACPI: resource: Make Asus ExpertBook B2502 matches cover more models
+    - drm/amdkfd: Fix an eviction fence leak
+    - drm/amd/display: fix hibernate entry for DCN35+
+    - drm/xe/guc_submit: fix xa_store() error checking
+    - drm/i915/hdcp: fix connector refcounting
+    - drm/xe/ct: fix xa_store() error checking
+    - scsi: ufs: Use pre-calculated offsets in ufshcd_init_lrb()
+    - mmc: sdhci-of-dwcmshc: Prevent stale command interrupt handling
+    - mptcp: fallback when MPTCP opts are dropped after 1st data
+    - ata: libata: avoid superfluous disk spin down + spin up during hibernation
+    - OPP: fix error code in dev_pm_opp_set_config()
+    - net: dsa: lan9303: ensure chip reset and wait for READY status
+    - mptcp: pm: do not remove closing subflows
+    - powercap: intel_rapl_tpmi: Fix bogus register reading
+    - selftests/mm: fix incorrect buffer->mirror size in hmm2 double_map test
+    - selftests/rseq: Fix mm_cid test failure
+    - btrfs: split remaining space to discard in chunks
+    - btrfs: add cancellation points to trim loops
+    - fs/proc/kcore.c: allow translation of physical memory addresses
+    - io_uring/rw: fix cflags posting for single issue multishot read
+    - Upstream stable to v6.6.56, v6.11.1, v6.11.2, v6.11.3, v6.11.4
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50182
+    - secretmem: disable memfd_secret() if arch cannot set direct map
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50019
+    - kthread: unpark only parked kthread
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50096
+    - nouveau/dmem: Fix vulnerability in migrate_to_ram upon copy error
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50020
+    - ice: Fix improper handling of refcount in ice_sriov_set_msix_vec_count()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50021
+    - ice: Fix improper handling of refcount in ice_dpll_init_rclk_pins()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50022
+    - device-dax: correct pgoff align in dax_set_mapping()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50185
+    - mptcp: handle consistently DSS corruption
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50023
+    - net: phy: Remove LED entry from LEDs list on unregister
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50024
+    - net: Fix an unsafe loop on the list
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50186
+    - net: explicitly clear the sk pointer, when pf->create fails
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50025
+    - scsi: fnic: Move flush_work initialization out of if block
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50026
+    - scsi: wd33c93: Don't use stale scsi_pointer value
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50027
+    - thermal: core: Free tzp copy along with the thermal zone
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50028
+    - thermal: core: Reference count the zone in thermal_zone_get_by_id()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50029
+    - Bluetooth: hci_conn: Fix UAF in hci_enhanced_setup_sync
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50030
+    - drm/xe/ct: prevent UAF in send_recv()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50187
+    - drm/vc4: Stop the active perfmon before being destroyed
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50031
+    - drm/v3d: Stop the active perfmon before being destroyed
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50189
+    - HID: amd_sfh: Switch to device-managed dmam_alloc_coherent()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50033
+    - slip: make slhc_remember() more robust against malicious packets
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50035
+    - ppp: fix ppp_async_encode() illegal access
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50036
+    - net: do not delay dst_entries_add() in dst_release()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50038
+    - netfilter: xtables: avoid NFPROTO_UNSPEC where needed
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50039
+    - net/sched: accept TCA_STAB only for root qdisc
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50040
+    - igb: Do not bring the device up after non-fatal error
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50041
+    - i40e: Fix macvlan leak by synchronizing access to mac_filter_hash
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50042
+    - ice: Fix increasing MSI-X on VF
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50093
+    - thermal: intel: int340x: processor: Fix warning during module unload
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50044
+    - Bluetooth: RFCOMM: FIX possible deadlock in rfcomm_sk_state_change
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50045
+    - netfilter: br_netfilter: fix panic with metadata_dst skb
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50188
+    - net: phy: dp83869: fix memory corruption when enabling fiber
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50046
+    - NFSv4: Prevent NULL-pointer dereference in nfs42_complete_copies()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50180
+    - fbdev: sisfb: Fix strbuf array overflow
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50047
+    - smb: client: fix UAF in async decryption
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50048
+    - fbcon: Fix a NULL pointer dereference issue in fbcon_putcs
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50049
+    - drm/amd/display: Check null pointer before dereferencing se
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50090
+    - drm/xe/oa: Fix overflow in oa batch buffer
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50183
+    - scsi: lpfc: Ensure DA_ID handling completion before deleting an NPIV
+      instance
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50055
+    - driver core: bus: Fix double free in driver API bus_register()
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50056
+    - usb: gadget: uvc: Fix ERR_PTR dereference in uvc_v4l2.c
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50184
+    - virtio_pmem: Check device status before requesting flush
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50057
+    - usb: typec: tipd: Free IRQ only if it was requested before
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50058
+    - serial: protect uart_port_dtr_rts() in uart_shutdown() too
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50181
+    - clk: imx: Remove CLK_SET_PARENT_GATE for DRAM mux for i.MX7D
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50059
+    - ntb: ntb_hw_switchtec: Fix use after free vulnerability in
+      switchtec_ntb_remove due to race condition
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50060
+    - io_uring: check if we need to reschedule during overflow flush
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50061
+    - i3c: master: cdns: Fix use after free vulnerability in cdns_i3c_master
+      Driver Due to Race Condition
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50062
+    - RDMA/rtrs-srv: Avoid null pointer deref during path establishment
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50095
+    - RDMA/mad: Improve handling of timed out WRs of mad agent
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50063
+    - bpf: Prevent tail call between progs attached to different hooks
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50191
+    - ext4: don't set SB_RDONLY after filesystem errors
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50064
+    - zram: free secondary algorithms names
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50089
+    - unicode: Don't special case ignorable code points
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49865
+    - drm/xe/vm: move xa_alloc to prevent UAF
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49968
+    - ext4: filesystems without casefold feature cannot be mounted with siphash
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49893
+    - drm/amd/display: Check stream_status before it is used
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49972
+    - drm/amd/display: Deallocate DML memory if allocation fails
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49914
+    - drm/amd/display: Add null check for pipe_ctx->plane_state in
+      dcn20_program_pipe
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49920
+    - drm/amd/display: Check null pointers before multiple uses
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-49921
+    - drm/amd/display: Check null pointers before used
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-50009
+    - cpufreq: amd-pstate: add check for cpufreq_cpu_get's return value
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-47726
+    - f2fs: fix to wait dio completion
+  * Noble update: upstream stable patchset 2025-02-03 (LP: #2097301) //
+    CVE-2024-47711
+    - af_unix: Don't return OOB skb in manage_oob().
+  * CVE-2024-53170
+    - block: fix uaf for flush rq while iterating tags
+  * CVE-2024-50148
+    - Bluetooth: bnep: fix wild-memory-access in proto_unregister
+  * CVE-2024-50134
+    - drm/vboxvideo: Replace fake VLA at end of vbva_mouse_pointer_shape with real
+      VLA
+  * CVE-2024-50171
+    - net: systemport: fix potential memory leak in bcm_sysport_xmit()
+  * CVE-2024-50229
+    - nilfs2: fix potential deadlock with newly created symlinks
+  * CVE-2024-50233
+    - staging: iio: frequency: ad9832: fix division by zero in
+      ad9832_calc_freqreg()
+  * [Lenovo Ubuntu 24.04 Bug] dmesg show "spi-nor: probe of spi0.0 failed with
+    error -95" (LP: #2070339)
+    - mtd: core: Don't fail mtd_otp_nvmem_add() if OTP is unsupported
+    - mtd: core: Align comment with an action in mtd_otp_nvmem_add()
+  * python perf module missing in realtime kernel (LP: #2089411)
+    - [Packaging] linux-tools: Add missing python perf symlink
+    - [Packaging] linux-tools: Fix python perf library packaging
+    - [Packaging] linux-tools: Fall back to old python perf path
+  * CVE-2024-53104
+    - media: uvcvideo: Skip parsing frames of type UVC_VS_UNDEFINED in
+      uvc_parse_format
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 31 Mar 2025 03:30:47 +0900
+
+linux-qcom (6.8.0-1035.35) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1034.34 -proposed tracker (LP: #2103614)
+
+  * [RB8] iris_vpu module crashes the kernel
+    - Ubuntu: [Config] enable CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
+
+  * Miscellaneous upstream changes
+    - kgsl: Add support for using compatible string "qcom,kgsl"
+    - ARM: dts: msm: Don't allow drm driver probe kgsl nodes
+    - QCLINUX: drm/msm: Remove changes made to prevent gpu probe
+    - FROMLIST: arm64: dts: qcom: sa8775p: Add gpu and gmu nodes
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Don't disable drm gpu/gmu nodes
+    - BACKPORT: arm64: dts: qcom: sc7280: don't enable GPU on unsupported devices
+    - QCLINUX: arm64: deconfig: enable CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT
+    - QCLINUX: Add support to compile msm_display.ko
+    - Ubuntu: [Config] enable CONFIG_FW_DEVLINK_SYNC_STATE_TIMEOUT
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 19 Mar 2025 23:02:25 +0900
+
+linux-qcom (6.8.0-1033.33) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1033.33 -proposed tracker (LP: #2101706)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: arm64: dts: disable iris_vpu on RB8 board for now
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Sun, 09 Mar 2025 13:41:59 +0900
+
+linux-qcom (6.8.0-1032.32) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1032.32 -proposed tracker (LP: #2100991)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: build camera drivers for qcm6490/qcs9100 separately
+    - SAUCE: ubuntu/qcom/camera: replace strlcpy() with strscpy() (take 2)
+    - SAUCE: ubuntu/qcom/camera: use sizeof() instead of V4L2_SUBDEV_NAME_SIZE
+      (take 2)
+    - SAUCE: ubuntu/qcom/camera: remove camera_banner
+    - SAUCE: ubuntu/qcom: add missing inclusion
+    - SAUCE: hack modpost to allow multiple exports
+    - SAUCE: fix phy-mode for RB8 board
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 06 Mar 2025 11:34:29 +0900
+
+linux-qcom (6.8.0-1031.31) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1031.31 -proposed tracker (LP: #2099991)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: add qcs9075-addons-rb8-ovl.dtb
+
+  * Miscellaneous upstream changes
+    - PENDING: arm64: dts: qcom: qcs9075: Enable ethernet on QCS9075 RB8
+    - video: driver: fix life cycle of a buffer shared across multiple clients
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Tue, 25 Feb 2025 23:33:35 +0900
+
+linux-qcom (6.8.0-1030.30) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1030.30 -proposed tracker (LP: #2098733)
+
+  * "[RB3] tc956x_pci-eth errors found in dmesg"
+    - SAUCE: ubuntu/qcom/qps615: suppress false alerts
+    - SAUCE: ubuntu/qcom/qps615: use INFO level for logging
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: import external DT from GA 1.3.1
+    - SAUCE: Add Makefile code to apply overlays for GA1.2
+    - SAUCE: ubuntu/qcom/graphics: import qcm6490 graphics driver code from
+      GA1.3.1
+    - SAUCE: ubuntu/qcom/camera: import qcm6490 camera driver code from GA1.3.1
+    - SAUCE: ubuntu/qcom/qps615: import ethernet driver from GA1.3.1
+    - SAUCE: ubuntu/qcom/video: import video driver from GA 1.3.1
+    - SAUCE: ubuntu/qcom: build external drivers
+    - SAUCE: ubuntu/qcom/camera: fix build warnings and errors
+    - SAUCE: rename qcom,phy-rst-gpio to qcom,phy-rst-gpio-id
+    - SAUCE: suppress unneeded build logs
+    - SAUCE: ubuntu/qcom: suppress Wno-enum-int-mismatch warning
+    - SAUCE: ubuntu/qcom/graphics: change strtobool() to kstrtobool()
+    - SAUCE: ubuntu/qcom/graphics: dynamically allocate the kgsl-pool shrinker for
+      kernel>=6.7
+    - SAUCE: ubuntu/qcom/camera: remove unused camera_banner
+    - SAUCE: ubuntu/qcom/camera: use sizeof() instead of V4L2_SUBDEV_NAME_SIZE
+    - SAUCE: ubuntu/qcom/camera: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/video: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: auto-load module
+    - SAUCE: ubuntu/qcom: add missing inclusion
+    - SAUCE: disable downstream display driver
+    - [Config] update config options for GA 1.3.2
+    - SAUCE: import external DT from GA 1.3.2
+    - SAUCE: merge two msm-camera.h
+    - [Packaging] update contents of linux-libc-dev-qcom package
+
+  * Miscellaneous upstream changes
+    - PENDING: arm64: dts: qcom: sa8255p-ride: Disable aoss_qmp
+    - FROMLIST: clk: qcom: Update the support for alpha mode configuration
+    - FROMLIST: clk: qcom: clk-alpha-pll: Add support for dynamic update for
+      slewing PLLs
+    - FROMLIST: phy: qcom: qmp-usbc: Add qmp configuration for QCS615
+    - FROMLIST: mmc: sdhci-msm: Enable MMC_CAP_AGGRESSIVE_PM for qualcomm
+      controllers
+    - QCLINUX: arm64: defconfig: Enable Ftrace for Gen5 Auto targets
+    - FROMLIST: net: stmmac: dwmac-qcom-ethqos: add support for EMAC on qcs615
+      platforms
+    - FROMLIST: arm64: dts: qcom: qcs615: add ethernet node
+    - FROMLIST: arm64: dts: qcom: qcs615-ride: Enable ethernet node
+    - FROMLIST: net: stmmac: qcom-ethqos: Enable RX programmable swap on qcs615
+    - FROMLIST: arm64: dts: qcom: qcs615-ride: Enable RX programmable swap on
+      qcs615-ride
+    - PENDING: net: stmmac: Create new mdio for every emac instance
+    - PENDING: arm64: dts: qcom: Add coresight nodes for QCS615
+    - PENDING: media: qcom: camss: Add support for camss driver on sa8775p
+    - PENDING: arm64: dts: qcom: sa8775p: Add support for camss
+    - PENDING: add TPG driver on camss for sa8775p
+    - QCLINUX: arm64: defconfig: Enable GS_USB
+    - QCLINUX: firmware: qcom_scm: Set SHE scm to atomic
+    - PENDING: ptp: qcom: Add support for Time Stamp Counter(TSC) driver
+    - PENDING: ptp: ptp_qcom_tsc: Add nsecs support for adjtime
+    - QCLINUX: arm64: dts: qcom: add lpi-quad mi2s/tdm dai for qcs9075-rb8
+    - PENDING: clk: qcom: videocc-sa8775p: Add HW_CTRL for video_cc_mvs0_gdsc
+    - QCLINUX: arm64: qcs9075-rb8: disable uart bt en pin in DTS
+    - FROMGIT: arm64: dts: qcom: sa8775p: Disable USB U1/U2 entry
+    - QCLINUX: arm64: defconfig: Enable MHI driver for Gen5auto targets
+    - QCLINUX: arm64: dts: qcom: add support for GPIO expander on rb8 board
+    - PENDING: net: PCS: Fix USXGMII reset sequence to poll for proper bit
+    - PENDING: drm/msm/dpu: remove duplicate formats from wb_formats list
+    - BACKPORT: UPSTREAM: phy: add NXP PTN3222 eUSB2 to USB2 redriver
+    - QCLINUX: ASoC: qcom: qdsp6: Increase the timeout to 20 secs
+    - Revert "PENDING: arm64: dts: qcom: qcs9075: Update memory map for qcs9075"
+    - PENDING: arm64: dts: qcom: qcs9xxx: Update memory map for qcs9xxx boards
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Tue, 18 Feb 2025 17:04:47 +0900
+
+linux-qcom (6.8.0-1029.29) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1028.28 -proposed tracker (LP: #2098058)
+
+  * Add list of source files to linux-buildinfo (LP: #2086606)
+    - [Packaging] Add list of used source files to buildinfo package
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: disable downstream display driver
+
+  * Miscellaneous upstream changes
+    - kernel: Enable upstream display on qcm6490 rgb3gen2
+
+  [ Ubuntu: 6.8.0-54.56 ]
+
+  * CVE-2025-0927
+    - SAUCE: fs: hfs/hfsplus: add key_len boundary check to hfs_bnode_read_key
+
+  [ Ubuntu: 6.8.0-53.55 ]
+
+  * noble/linux: 6.8.0-53.55 -proposed tracker (LP: #2093677)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2025.01.13)
+  * generate and ship vmlinux.h to allow packages to build BPF CO-RE
+    (LP: #2050083)
+    - [Packaging] add linux-bpf-dev package
+    - [Packaging] do not attempt to generate BTF header on armhf
+  * Unable to boot as a guest on VMware ESX (LP: #2091941)
+    - ptp/vmware: Use VMware hypercall API
+    - input/vmmouse: Use VMware hypercall API
+    - drm/vmwgfx: Use VMware hypercall API
+    - x86/vmware: Use VMware hypercall API
+    - x86/vmware: Correct macro names
+    - x86/vmware: Remove legacy VMWARE_HYPERCALL* macros
+  * When /dev/vmbus/hv_kvp is not present, disable hv-kvp-daemon (LP: #2091744)
+    - [Packaging] disable hv-kvp-daemon if needed
+  * Backport "netkit: Add option for scrubbing skb meta data" to 6.8
+    (LP: #2091184)
+    - netkit: Add option for scrubbing skb meta data
+  * KVM: Cache CPUID at KVM.ko module init to reduce latency of VM-Enter and VM-
+    Exit (LP: #2093146)
+    - KVM: x86: Cache CPUID.0xD XSTATE offsets+sizes during module init
+  * [SRU] add support of QCA BT 0489:e0fc (LP: #2085406)
+    - Bluetooth: btusb: add Foxconn 0xe0fc for Qualcomm WCN785x
+  * ice driver RTNL assertion failed warning on shutdown/reboot (LP: #2091107)
+    - ice: Remove and readd netdev during devlink reload
+  * vfio_pci soft lockup on VM start while using PCIe passthrough (LP: #2089306)
+    - SAUCE: Revert "vfio/pci: Insert full vma on mmap'd MMIO fault"
+    - SAUCE: Revert "vfio/pci: Use unmap_mapping_range()"
+  * [SRU] Fix error of resume on rtl8168fp (LP: #2087507)
+    - r8169: avoid unsolicited interrupts
+  * [SRU] power: intel_pstate: HWP interrupt support for maximum ratio changed
+    (LP: #2090852)
+    - x86/cpufeatures: Add HWP highest perf change feature flag
+    - cpufreq: intel_pstate: Support highest performance change interrupt
+  * Noble update: upstream stable patchset 2024-11-29 (LP: #2089884)
+    - static_call: Handle module init failure correctly in
+      static_call_del_module()
+    - static_call: Replace pointless WARN_ON() in static_call_module_notify()
+    - jump_label: Simplify and clarify static_key_fast_inc_cpus_locked()
+    - jump_label: Fix static_key_slow_dec() yet again
+    - scsi: st: Fix input/output error on empty drive reset
+    - scsi: pm8001: Do not overwrite PCI queue mapping
+    - drm/amdgpu: Fix get each xcp macro
+    - mailbox: rockchip: fix a typo in module autoloading
+    - mailbox: bcm2835: Fix timeout during suspend mode
+    - ceph: remove the incorrect Fw reference check when dirtying pages
+    - ieee802154: Fix build error
+    - net: sparx5: Fix invalid timestamps
+    - net/mlx5: Fix error path in multi-packet WQE transmit
+    - net/mlx5: Added cond_resched() to crdump collection
+    - net/mlx5e: Fix NULL deref in mlx5e_tir_builder_alloc()
+    - net/mlx5e: Fix crash caused by calling __xfrm_state_delete() twice
+    - netfilter: uapi: NFTA_FLOWTABLE_HOOK is NLA_NESTED
+    - net: ieee802154: mcr20a: Use IRQF_NO_AUTOEN flag in request_irq()
+    - net: wwan: qcom_bam_dmux: Fix missing pm_runtime_disable()
+    - selftests: netfilter: Fix nft_audit.sh for newer nft binaries
+    - netfilter: nf_tables: prevent nf_skb_duplicated corruption
+    - Bluetooth: MGMT: Fix possible crash on mgmt_index_removed
+    - Bluetooth: MGMT: Fix possible deadlocks
+    - Bluetooth: L2CAP: Fix uaf in l2cap_connect
+    - Bluetooth: hci_core: Fix calling mgmt_device_connected
+    - Bluetooth: btmrvl: Use IRQF_NO_AUTOEN flag in request_irq()
+    - net: Add netif_get_gro_max_size helper for GRO
+    - net: Fix gso_features_check to check for both dev->gso_{ipv4_,}max_size
+    - net: ethernet: lantiq_etop: fix memory disclosure
+    - net: fec: Restart PPS after link state change
+    - net: fec: Reload PTP registers after link-state change
+    - net: avoid potential underflow in qdisc_pkt_len_init() with UFO
+    - net: add more sanity checks to qdisc_pkt_len_init()
+    - net: stmmac: dwmac4: extend timeout for VLAN Tag register busy bit check
+    - ipv4: ip_gre: Fix drops of small packets in ipgre_xmit
+    - net: test for not too small csum_start in virtio_net_hdr_to_skb()
+    - ppp: do not assume bh is held in ppp_channel_bridge_input()
+    - iomap: constrain the file range passed to iomap_file_unshare
+    - dt-bindings: net: xlnx,axi-ethernet: Add missing reg minItems
+    - sctp: set sk_state back to CLOSED if autobind fails in sctp_listen_start
+    - i2c: xiic: improve error message when transfer fails to start
+    - i2c: xiic: Try re-initialization on bus busy timeout
+    - loop: don't set QUEUE_FLAG_NOMERGES
+    - ASoC: atmel: mchp-pdmc: Skip ALSA restoration if substream runtime is
+      uninitialized
+    - ALSA: mixer_oss: Remove some incorrect kfree_const() usages
+    - ALSA: hda/realtek: Fix the push button function for the ALC257
+    - ALSA: hda/generic: Unconditionally prefer preferred_dacs pairs
+    - ASoC: imx-card: Set card.owner to avoid a warning calltrace if SND=m
+    - cifs: Fix buffer overflow when parsing NFS reparse points
+    - cifs: Do not convert delimiter when parsing NFS-style symlinks
+    - ALSA: gus: Fix some error handling paths related to get_bpos() usage
+    - ALSA: hda/conexant: Fix conflicting quirk for System76 Pangolin
+    - wifi: ath9k: fix possible integer overflow in ath9k_get_et_stats()
+    - wifi: rtw89: avoid to add interface to list twice when SER
+    - wifi: ath9k_htc: Use __skb_set_length() for resetting urb before resubmit
+    - crypto: x86/sha256 - Add parentheses around macros' single arguments
+    - crypto: octeontx - Fix authenc setkey
+    - crypto: octeontx2 - Fix authenc setkey
+    - ice: Adjust over allocation of memory in ice_sched_add_root_node() and
+      ice_sched_add_node()
+    - wifi: iwlwifi: mvm: Fix a race in scan abort flow
+    - wifi: iwlwifi: mvm: drop wrong STA selection in TX
+    - wifi: cfg80211: Set correct chandef when starting CAC
+    - net/xen-netback: prevent UAF in xenvif_flush_hash()
+    - net: hisilicon: hip04: fix OF node leak in probe()
+    - net: hisilicon: hns_dsaf_mac: fix OF node leak in hns_mac_get_info()
+    - net: hisilicon: hns_mdio: fix OF node leak in probe()
+    - ACPI: PAD: fix crash in exit_round_robin()
+    - ACPICA: Fix memory leak if acpi_ps_get_next_namepath() fails
+    - ACPICA: Fix memory leak if acpi_ps_get_next_field() fails
+    - e1000e: avoid failing the system during pm_suspend
+    - wifi: mt76: mt7915: disable tx worker during tx BA session enable/disable
+    - net: sched: consistently use rcu_replace_pointer() in taprio_change()
+    - Bluetooth: btusb: Add Realtek RTL8852C support ID 0x0489:0xe122
+    - Bluetooth: btrtl: Set msft ext address filter quirk for RTL8852B
+    - ACPI: video: Add force_vendor quirk for Panasonic Toughbook CF-18
+    - ACPI: CPPC: Add support for setting EPP register in FFH
+    - blk_iocost: fix more out of bound shifts
+    - wifi: ath12k: fix array out-of-bound access in SoC stats
+    - wifi: ath11k: fix array out-of-bound access in SoC stats
+    - wifi: rtw88: select WANT_DEV_COREDUMP
+    - ACPI: EC: Do not release locks during operation region accesses
+    - ACPICA: check null return of ACPI_ALLOCATE_ZEROED() in
+      acpi_db_convert_to_package()
+    - tipc: guard against string buffer overrun
+    - net: mvpp2: Increase size of queue_name buffer
+    - bnxt_en: Extend maximum length of version string by 1 byte
+    - ipv4: Check !in_dev earlier for ioctl(SIOCSIFADDR).
+    - wifi: rtw89: correct base HT rate mask for firmware
+    - ipv4: Mask upper DSCP bits and ECN bits in NETLINK_FIB_LOOKUP family
+    - net: atlantic: Avoid warning about potential string truncation
+    - crypto: simd - Do not call crypto_alloc_tfm during registration
+    - netpoll: Ensure clean state on setup failures
+    - tcp: avoid reusing FIN_WAIT2 when trying to find port in connect() process
+    - wifi: iwlwifi: mvm: use correct key iteration
+    - wifi: iwlwifi: mvm: avoid NULL pointer dereference
+    - ACPICA: iasl: handle empty connection_node
+    - proc: add config & param to block forcing mem writes
+    - [Config] updateconfigs to select PROC_MEM_ALWAYS_FORCE
+    - drivers/perf: arm_spe: Use perf_allow_kernel() for permissions
+    - can: netlink: avoid call to do_set_data_bittiming callback with stale
+      can_priv::ctrlmode
+    - wifi: mt76: mt7915: add dummy HW offload of IEEE 802.11 fragmentation
+    - wifi: mt76: mt7915: hold dev->mt76.mutex while disabling tx worker
+    - wifi: mwifiex: Fix memcpy() field-spanning write warning in
+      mwifiex_cmd_802_11_scan_ext()
+    - nfp: Use IRQF_NO_AUTOEN flag in request_irq()
+    - ALSA: usb-audio: Add input value sanity checks for standard types
+    - x86/ioapic: Handle allocation failures gracefully
+    - ALSA: usb-audio: Define macros for quirk table entries
+    - ALSA: usb-audio: Replace complex quirk lines with macros
+    - ALSA: usb-audio: Add logitech Audio profile quirk
+    - ASoC: codecs: wsa883x: Handle reading version failure
+    - tools/x86/kcpuid: Protect against faulty "max subleaf" values
+    - x86/pkeys: Add PKRU as a parameter in signal handling functions
+    - x86/pkeys: Restore altstack access in sigreturn()
+    - x86/kexec: Add EFI config table identity mapping for kexec kernel
+    - ALSA: asihpi: Fix potential OOB array access
+    - ALSA: hdsp: Break infinite MIDI input flush loop
+    - tools/nolibc: powerpc: limit stack-protector workaround to GCC
+    - selftests/nolibc: avoid passing NULL to printf("%s")
+    - x86/syscall: Avoid memcpy() for ia32 syscall_get_arguments()
+    - hwmon: (nct6775) add G15CF to ASUS WMI monitoring list
+    - fbdev: efifb: Register sysfs groups through driver core
+    - fbdev: pxafb: Fix possible use after free in pxafb_task()
+    - rcuscale: Provide clear error when async specified without primitives
+    - power: reset: brcmstb: Do not go into infinite loop if reset fails
+    - iommu/vt-d: Always reserve a domain ID for identity setup
+    - iommu/vt-d: Fix potential lockup if qi_submit_sync called with 0 count
+    - drm/stm: Avoid use-after-free issues with crtc and plane
+    - drm/amdgpu: disallow multiple BO_HANDLES chunks in one submit
+    - drm/amdgpu: prevent BO_HANDLES error from being overwritten
+    - drm/amdkfd: amdkfd_free_gtt_mem clear the correct pointer
+    - drm/amd/display: Add null check for top_pipe_to_program in
+      commit_planes_for_stream
+    - ata: pata_serverworks: Do not use the term blacklist
+    - ata: sata_sil: Rename sil_blacklist to sil_quirks
+    - HID: Ignore battery for all ELAN I2C-HID devices
+    - drm/amd/display: Handle null 'stream_status' in
+      'planes_changed_for_existing_stream'
+    - drm/amd/display: Check null pointers before using dc->clk_mgr
+    - drm/amd/display: Add null check for 'afb' in
+      amdgpu_dm_plane_handle_cursor_update (v2)
+    - drm/amd/display: fix double free issue during amdgpu module unload
+    - jfs: UBSAN: shift-out-of-bounds in dbFindBits
+    - jfs: Fix uaf in dbFreeBits
+    - jfs: check if leafidx greater than num leaves per dmap tree
+    - scsi: smartpqi: correct stream detection
+    - drm/msm/adreno: Assign msm_gpu->pdev earlier to avoid nullptrs
+    - jfs: Fix uninit-value access of new_ea in ea_buffer
+    - drm/amdgpu: add raven1 gfxoff quirk
+    - drm/amdgpu: enable gfxoff quirk on HP 705G4
+    - drm/amdkfd: Fix resource leak in criu restore queue
+    - HID: multitouch: Add support for Thinkpad X12 Gen 2 Kbd Portfolio
+    - platform/x86: touchscreen_dmi: add nanote-next quirk
+    - drm/stm: ltdc: reset plane transparency after plane disable
+    - drm/amd/display: Check stream before comparing them
+    - drm/amd/display: Check link_res->hpo_dp_link_enc before using it
+    - drm/amd/display: Fix index out of bounds in DCN30 degamma hardware format
+      translation
+    - drm/amd/display: Fix index out of bounds in degamma hardware format
+      translation
+    - drm/amd/display: Fix index out of bounds in DCN30 color transformation
+    - drm/amd/display: Avoid overflow assignment in link_dp_cts
+    - drm/amd/display: Initialize get_bytes_per_element's default to 1
+    - drm/printer: Allow NULL data in devcoredump printer
+    - perf,x86: avoid missing caller address in stack traces captured in uprobe
+    - scsi: lpfc: Update PRLO handling in direct attached topology
+    - drm/amdgpu: fix unchecked return value warning for amdgpu_gfx
+    - perf: Fix event_function_call() locking
+    - scsi: NCR5380: Initialize buffer for MSG IN and STATUS transfers
+    - drm/radeon/r100: Handle unknown family in r100_cp_init_microcode()
+    - drm/amdgpu: Block MMR_READ IOCTL in reset
+    - drm/amdgpu/gfx9: use rlc safe mode for soft recovery
+    - drm/amd/pm: ensure the fw_info is not null before using it
+    - of/irq: Refer to actual buffer size in of_irq_parse_one()
+    - powerpc/pseries: Use correct data types from pseries_hp_errorlog struct
+    - drm/amdgpu/gfx11: use rlc safe mode for soft recovery
+    - drm/amdgpu/gfx10: use rlc safe mode for soft recovery
+    - platform/x86: lenovo-ymc: Ignore the 0x0 state
+    - ksmbd: add refcnt to ksmbd_conn struct
+    - ksmbd: fix use-after-free in SMB request handling
+    - bpf: Make the pointer returned by iter next method valid
+    - ext4: ext4_search_dir should return a proper error
+    - ext4: avoid use-after-free in ext4_ext_show_leaf()
+    - ext4: fix i_data_sem unlock order in ext4_ind_migrate()
+    - bpftool: Fix undefined behavior caused by shifting into the sign bit
+    - iomap: handle a post-direct I/O invalidate race in
+      iomap_write_delalloc_release
+    - bpftool: Fix undefined behavior in qsort(NULL, 0, ...)
+    - spi: spi-imx: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - spi: spi-cadence: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - spi: spi-cadence: Fix missing spi_controller_is_target() check
+    - selftest: hid: add missing run-hid-tools-tests.sh
+    - spi: s3c64xx: fix timeout counters in flush_fifo
+    - selftests: breakpoints: use remaining time to check if suspend succeed
+    - accel/ivpu: Add missing MODULE_FIRMWARE metadata
+    - spi: rpc-if: Add missing MODULE_DEVICE_TABLE
+    - perf: Really fix event_function_call() locking
+    - selftests: vDSO: fix vDSO name for powerpc
+    - selftests: vDSO: fix vdso_config for powerpc
+    - selftests: vDSO: fix vDSO symbols lookup for powerpc64
+    - powerpc/vdso: Flag VDSO64 entry points as functions
+    - selftests/mm: fix charge_reserved_hugetlb.sh test
+    - powerpc/vdso: Fix VDSO data access when running in a non-root time namespace
+    - selftests: vDSO: fix ELF hash table entry size for s390x
+    - selftests: vDSO: fix vdso_config for s390
+    - Revert "ALSA: hda: Conditionally use snooping for AMD HDMI"
+    - platform/x86: ISST: Fix the KASAN report slab-out-of-bounds bug
+    - i2c: stm32f7: Do not prepare/unprepare clock during runtime suspend/resume
+    - i2c: qcom-geni: Use IRQF_NO_AUTOEN flag in request_irq()
+    - i2c: xiic: Wait for TX empty to avoid missed TX NAKs
+    - media: i2c: ar0521: Use cansleep version of gpiod_set_value()
+    - i2c: xiic: Fix pm_runtime_set_suspended() with runtime pm enabled
+    - i2c: designware: fix controller is holding SCL low while ENABLE bit is
+      disabled
+    - rust: sync: require `T: Sync` for `LockedBy::access`
+    - ovl: fail if trusted xattrs are needed but caller lacks permission
+    - firmware: tegra: bpmp: Drop unused mbox_client_to_bpmp()
+    - memory: tegra186-emc: drop unused to_tegra186_emc()
+    - dt-bindings: clock: exynos7885: Fix duplicated binding
+    - spi: bcm63xx: Fix module autoloading
+    - spi: bcm63xx: Fix missing pm_runtime_disable()
+    - power: supply: hwmon: Fix missing temp1_max_alarm attribute
+    - perf/core: Fix small negative period being ignored
+    - parisc: Fix itlb miss handler for 64-bit programs
+    - drm/mediatek: ovl_adaptor: Add missing of_node_put()
+    - drm: Consistently use struct drm_mode_rect for FB_DAMAGE_CLIPS
+    - ALSA: hda/tas2781: Add new quirk for Lenovo Y990 Laptop
+    - ALSA: core: add isascii() check to card ID generator
+    - ALSA: usb-audio: Add delay quirk for VIVO USB-C HEADSET
+    - ALSA: usb-audio: Add native DSD support for Luxman D-08u
+    - ALSA: line6: add hw monitor volume control to POD HD500X
+    - ALSA: hda/realtek: Add quirk for Huawei MateBook 13 KLV-WX9
+    - ALSA: hda/realtek: Add a quirk for HP Pavilion 15z-ec200
+    - ext4: correct encrypted dentry name hash when not casefolded
+    - ext4: fix slab-use-after-free in ext4_split_extent_at()
+    - ext4: propagate errors from ext4_find_extent() in ext4_insert_range()
+    - ext4: fix incorrect tid assumption in ext4_fc_mark_ineligible()
+    - ext4: dax: fix overflowing extents beyond inode size when partially writing
+    - ext4: fix incorrect tid assumption in __jbd2_log_wait_for_space()
+    - ext4: drop ppath from ext4_ext_replay_update_ex() to avoid double-free
+    - ext4: aovid use-after-free in ext4_ext_insert_extent()
+    - ext4: fix double brelse() the buffer of the extents path
+    - ext4: fix timer use-after-free on failed mount
+    - ext4: update orig_path in ext4_find_extent()
+    - ext4: fix incorrect tid assumption in ext4_wait_for_tail_page_commit()
+    - ext4: fix incorrect tid assumption in jbd2_journal_shrink_checkpoint_list()
+    - ext4: fix fast commit inode enqueueing during a full journal commit
+    - ext4: use handle to mark fc as ineligible in __track_dentry_update()
+    - ext4: mark fc as ineligible using an handle in ext4_xattr_set()
+    - parisc: Fix 64-bit userspace syscall path
+    - parisc: Allow mmap(MAP_STACK) memory to automatically expand upwards
+    - parisc: Fix stack start for ADDR_NO_RANDOMIZE personality
+    - drm/rockchip: vop: clear DMA stop bit on RK3066
+    - of: address: Report error on resource bounds overflow
+    - of/irq: Support #msi-cells=<0> in of_msi_get_domain
+    - drm: omapdrm: Add missing check for alloc_ordered_workqueue
+    - resource: fix region_intersects() vs add_memory_driver_managed()
+    - jbd2: stop waiting for space when jbd2_cleanup_journal_tail() returns error
+    - jbd2: correctly compare tids with tid_geq function in jbd2_fc_begin_commit
+    - mm: krealloc: consider spare memory for __GFP_ZERO
+    - mm: krealloc: Fix MTE false alarm in __do_krealloc
+    - ocfs2: fix the la space leak when unmounting an ocfs2 volume
+    - ocfs2: fix uninit-value in ocfs2_get_block()
+    - ocfs2: reserve space for inline xattr before attaching reflink tree
+    - ocfs2: cancel dqi_sync_work before freeing oinfo
+    - ocfs2: remove unreasonable unlock in ocfs2_read_blocks
+    - ocfs2: fix null-ptr-deref when journal load failed.
+    - ocfs2: fix possible null-ptr-deref in ocfs2_set_buffer_uptodate
+    - arm64: fix selection of HAVE_DYNAMIC_FTRACE_WITH_ARGS
+    - arm64: Subscribe Microsoft Azure Cobalt 100 to erratum 3194386
+    - riscv: define ILLEGAL_POINTER_VALUE for 64bit
+    - [Config] updateconfigs to set ILLEGAL_POINTER_VALUE for riscv64
+    - exfat: fix memory leak in exfat_load_bitmap()
+    - perf python: Disable -Wno-cast-function-type-mismatch if present on clang
+    - perf hist: Update hist symbol when updating maps
+    - nfsd: fix delegation_blocked() to block correctly for at least 30 seconds
+    - nfsd: map the EBADMSG to nfserr_io to avoid warning
+    - NFSD: Fix NFSv4's PUTPUBFH operation
+    - i3c: master: svc: Fix use after free vulnerability in svc_i3c_master Driver
+      Due to Race Condition
+    - RDMA/mana_ib: use the correct page size for mapping user-mode doorbell page
+    - riscv: Fix kernel stack size when KASAN is enabled
+    - aoe: fix the potential use-after-free problem in more places
+    - media: ov5675: Fix power on/off delay timings
+    - clk: rockchip: fix error for unknown clocks
+    - remoteproc: k3-r5: Fix error handling when power-up failed
+    - clk: qcom: dispcc-sm8250: use CLK_SET_RATE_PARENT for branch clocks
+    - media: sun4i_csi: Implement link validate for sun4i_csi subdev
+    - clk: qcom: gcc-sm8450: Do not turn off PCIe GDSCs during gdsc_disable()
+    - media: uapi/linux/cec.h: cec_msg_set_reply_to: zero flags
+    - clk: qcom: clk-rpmh: Fix overflow in BCM vote
+    - clk: samsung: exynos7885: Update CLKS_NR_FSYS after bindings fix
+    - clk: qcom: gcc-sm8150: De-register gcc_cpuss_ahb_clk_src
+    - media: venus: fix use after free bug in venus_remove due to race condition
+    - clk: qcom: gcc-sm8250: Do not turn off PCIe GDSCs during gdsc_disable()
+    - media: qcom: camss: Remove use_count guard in stop_streaming
+    - media: qcom: camss: Fix ordering of pm_runtime_enable
+    - clk: qcom: gcc-sc8180x: Fix the sdcc2 and sdcc4 clocks freq table
+    - clk: qcom: clk-alpha-pll: Fix CAL_L_VAL override for LUCID EVO PLL
+    - smb: client: use actual path when queryfs
+    - smb3: fix incorrect mode displayed for read-only files
+    - iio: magnetometer: ak8975: Fix reading for ak099xx sensors
+    - vrf: revert "vrf: Remove unnecessary RCU-bh critical section"
+    - gso: fix udp gso fraglist segmentation after pull from frag_list
+    - tomoyo: fallback to realpath if symlink's pathname does not exist
+    - net: stmmac: Fix zero-division error when disabling tc cbs
+    - rtc: at91sam9: fix OF node leak in probe() error path
+    - Input: adp5589-keys - fix NULL pointer dereference
+    - Input: adp5589-keys - fix adp5589_gpio_get_value()
+    - cachefiles: fix dentry leak in cachefiles_open_file()
+    - btrfs: fix a NULL pointer dereference when failed to start a new trasacntion
+    - btrfs: send: fix invalid clone operation for file that got its size
+      decreased
+    - btrfs: wait for fixup workers before stopping cleaner kthread during umount
+    - cpufreq: Avoid a bad reference count on CPU node
+    - gpio: davinci: fix lazy disable
+    - net: pcs: xpcs: fix the wrong register that was written back
+    - Bluetooth: hci_event: Align BR/EDR JUST_WORKS paring with LE
+    - mac802154: Fix potential RCU dereference issue in mac802154_scan_worker
+    - ceph: fix cap ref leak via netfs init_request
+    - tracing/hwlat: Fix a race during cpuhp processing
+    - tracing/timerlat: Drop interface_lock in stop_kthread()
+    - tracing/timerlat: Fix a race during cpuhp processing
+    - tracing/timerlat: Fix duplicated kthread creation due to CPU online/offline
+    - rtla: Fix the help text in osnoise and timerlat top tools
+    - drm/i915/gem: fix bitwise and logical AND mixup
+    - drm/sched: Add locking to drm_sched_entity_modify_sched
+    - drm/amd/display: Add HDR workaround for specific eDP
+    - cpufreq: intel_pstate: Make hwp_notify_lock a raw spinlock
+    - kconfig: qconf: fix buffer overflow in debug links
+    - platform/x86: x86-android-tablets: Fix use after free on
+      platform_device_register() errors
+    - i2c: core: Lock address during client device instantiation
+    - i2c: synquacer: Remove a clk reference from struct synquacer_i2c
+    - i2c: synquacer: Deal with optional PCLK correctly
+    - arm64: cputype: Add Neoverse-N3 definitions
+    - arm64: errata: Expand speculative SSBS workaround once more
+    - io_uring/net: harden multishot termination case for recv
+    - uprobes: fix kernel info leak via "[uprobes]" vma
+    - mm: z3fold: deprecate CONFIG_Z3FOLD
+    - [Config] updateconfigs for deprecated CONFIG_Z3FOLD
+    - drm/amd/display: Allow backlight to go below
+      `AMDGPU_DM_DEFAULT_MIN_BACKLIGHT`
+    - build-id: require program headers to be right after ELF header
+    - lib/buildid: harden build ID parsing logic
+    - sched: psi: fix bogus pressure spikes from aggregation race
+    - net: mana: Enable MANA driver on ARM64 with 4K page size
+    - net: mana: Add support for page sizes other than 4KB on ARM64
+    - [Config] updateconfigs for MICROSOFT_MANA
+    - RDMA/mana_ib: use the correct page table index based on hardware page size
+    - media: imx335: Fix reset-gpio handling
+    - remoteproc: k3-r5: Acquire mailbox handle during probe routine
+    - remoteproc: k3-r5: Delay notification of wakeup event
+    - dt-bindings: clock: qcom: Add missing UFS QREF clocks
+    - dt-bindings: clock: qcom: Add GPLL9 support on gcc-sc8180x
+    - iio: pressure: bmp280: Improve indentation and line wrapping
+    - iio: pressure: bmp280: Use BME prefix for BME280 specifics
+    - iio: pressure: bmp280: Fix regmap for BMP280 device
+    - iio: pressure: bmp280: Fix waiting time for BMP3xx configuration
+    - r8169: Fix spelling mistake: "tx_underun" -> "tx_underrun"
+    - r8169: add tally counter fields added with RTL8125
+    - clk: qcom: gcc-sc8180x: Add GPLL9 support
+    - ACPI: battery: Simplify battery hook locking
+    - ACPI: battery: Fix possible crash when unregistering a battery hook
+    - btrfs: drop the backref cache during relocation if we commit
+    - drm/rockchip: vop: enable VOP_FEATURE_INTERNAL_RGB on RK3066
+    - rxrpc: Fix a race between socket set up and I/O thread creation
+    - vhost/scsi: null-ptr-dereference in vhost_scsi_get_req()
+    - crypto: octeontx* - Select CRYPTO_AUTHENC
+    - drm/amd/display: Revert Avoid overflow assignment
+    - perf report: Fix segfault when 'sym' sort key is not used
+    - drm/amd/display: enable_hpo_dp_link_output: Check link_res->hpo_dp_link_enc
+      before using it
+    - Revert "ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path"
+    - perf python: Allow checking for the existence of warning options in clang
+    - drm/i915/dp: Fix AUX IO power enabling for eDP PSR
+    - drm/amd/display: handle nulled pipe context in DCE110's set_drr()
+    - selftests: netfilter: Add missing return value
+    - afs: Fix the setting of the server responding flag
+    - net: dsa: improve shutdown sequence
+    - bridge: mcast: Fail MDB get request on empty entry
+    - net/ncsi: Disable the ncsi work before freeing the associated structure
+    - drm/xe: Restore pci state upon resume
+    - drm/xe: Resume TDR after GT reset
+    - drm/xe: Prevent null pointer access in xe_migrate_copy
+    - fs/inode: Prevent dump_mapping() accessing invalid dentry.d_name.name
+    - ACPI: resource: Skip IRQ override on Asus Vivobook Go E1404GAB
+    - nvme-keyring: restrict match length for version '1' identifiers
+    - nvme-tcp: sanitize TLS key handling
+    - nvme-fabrics: typo in nvmf_parse_key()
+    - nvme-tcp: check for invalidated or revoked key
+    - net: fec: don't save PTP state if PTP is unsupported
+    - wifi: mac80211: fix RCU list iterations
+    - netdev-genl: Set extack and fix error on napi-get
+    - block: fix integer overflow in BLKSECDISCARD
+    - arm64: trans_pgd: mark PTEs entries as valid to avoid dead kexec()
+    - net: phy: Check for read errors in SIOCGMIIREG
+    - wifi: rtw89: avoid reading out of bounds when loading TX power FW elements
+    - x86/bugs: Add missing NO_SSB flag
+    - x86/bugs: Fix handling when SRSO mitigation is disabled
+    - net: napi: Prevent overflow of napi_defer_hard_irqs
+    - crypto: hisilicon - fix missed error branch
+    - ALSA: usb-audio: Add quirk for RME Digiface USB
+    - ALSA: usb-audio: Add mixer quirk for RME Digiface USB
+    - ALSA: control: Use automatic cleanup of kfree()
+    - ALSA: control: Fix unannotated kfree() cleanup
+    - ALSA: control: Use guard() for locking
+    - ALSA: control: Take power_ref lock primarily
+    - x86/mm/ident_map: Use gbpages only where full GB page should be mapped.
+    - ASoC: Intel: boards: always check the result of
+      acpi_dev_get_first_match_dev()
+    - rcu-tasks: Add data to eliminate RCU-tasks/do_exit() deadlocks
+    - rcu-tasks: Initialize data to eliminate RCU-tasks/do_exit() deadlocks
+    - rcu-tasks: Fix access non-existent percpu rtpcp variable in
+      rcu_tasks_need_gpcb()
+    - pmdomain: core: Don't hold the genpd-lock when calling dev_pm_domain_set()
+    - iommu/vt-d: Unconditionally flush device TLB for pasid table updates
+    - iommu/arm-smmu-v3: Do not use devm for the cd table allocations
+    - drm/amd/display: Pass non-null to dcn20_validate_apply_pipe_split_flags
+    - drm/amd/display: Check null pointers before using them
+    - drm/amd/display: Add null check for head_pipe in
+      dcn201_acquire_free_pipe_for_layer
+    - drm/amd/display: Add null check for head_pipe in
+      dcn32_acquire_idle_pipe_for_head_pipe_in_layer
+    - drm/amd/display: Add NULL check for clk_mgr and clk_mgr->funcs in
+      dcn30_init_hw
+    - drm/amd/display: Add NULL check for clk_mgr in dcn32_init_hw
+    - drm/amd/display: Use gpuvm_min_page_size_kbytes for DML2 surfaces
+    - scsi: smartpqi: Add new controller PCI IDs
+    - drm/amd/display: Add NULL check for function pointer in
+      dcn20_set_output_transfer_func
+    - drm/amd/display: Add NULL check for function pointer in
+      dcn32_set_output_transfer_func
+    - scsi: smartpqi: add new controller PCI IDs
+    - drm/amd/display: Check null-initialized variables
+    - drm/amd/display: Check phantom_stream before it is used
+    - drm/amdgpu/gfx9: properly handle error ints on all pipes
+    - scsi: lpfc: Validate hdwq pointers before dereferencing in reset/errata
+      paths
+    - scsi: lpfc: Fix unsolicited FLOGI kref imbalance when in direct attached
+      topology
+    - drm/amdgpu: check PS, WS index
+    - drm/amdgpu: fix wrong sizeof argument
+    - drm/amdgpu: fix unchecked return value warning for amdgpu_atombios
+    - drm/amdgpu/gfx11: enter safe mode before touching CP_INT_CNTL
+    - drm/xe: Invert page fault queue head / tail
+    - drm/xe: Add helper macro to loop each DSS
+    - drm/xe: fix multicast support for Xe_LP platforms
+    - drm/xe: Use topology to determine page fault queue size
+    - drm/xe: Drop warn on xe_guc_pc_gucrc_disable in guc pc fini
+    - ovl: fsync after metadata copy-up
+    - HID: i2c-hid: ensure various commands do not interfere with each other
+    - platform/mellanox: mlxbf-pmc: Replace uintN_t with kernel-style types
+    - platform/mellanox: mlxbf-pmc: Cleanup signed/unsigned mix-up
+    - platform/mellanox: mlxbf-pmc: fix signedness bugs
+    - platform/mellanox: mlxbf-pmc: fix lockdep warning
+    - bpf: Fix a sdiv overflow issue
+    - ALSA: control: Fix power_ref lock order for compat code, too
+    - perf callchain: Fix stitch LBR memory leaks
+    - drm/xe: fixup xe_alloc_pf_queue
+    - drm/xe: Fix memory leak on xe_alloc_pf_queue failure
+    - nvme-tcp: fix link failure for TCP auth
+    - f2fs: fix zoned block device information initialization
+    - f2fs: add write priority option based on zone UFS
+    - f2fs: make BG GC more aggressive for zoned devices
+    - f2fs: introduce migration_window_granularity
+    - f2fs: increase BG GC migration window granularity when boosted for zoned
+      devices
+    - f2fs: do FG_GC when GC boosting is required for zoned devices
+    - f2fs: forcibly migrate to secure space for zoned device file pinning
+    - mm, slub: avoid zeroing kmalloc redzone
+    - drm/v3d: Prevent out of bounds access in performance query extensions
+    - ext4: fix access to uninitialised lock in fc replay path
+    - ext4: fix off by one issue in alloc_flex_gd()
+    - scripts/gdb: add iteration function for rbtree
+    - scripts/gdb: fix lx-mounts command error
+    - sched/deadline: Comment sched_dl_entity::dl_server variable
+    - sched/core: Add clearing of ->dl_server in put_prev_task_balance()
+    - sched/core: Clear prev->dl_server in CFS pick fast path
+    - drivers/perf: riscv: Align errno for unsupported perf event
+    - ACPI: resource: Remove duplicate Asus E1504GAB IRQ override
+    - ACPI: resource: Loosen the Asus E1404GAB DMI match to also cover the E1404GA
+    - ACPI: resource: Add Asus Vivobook X1704VAP to irq1_level_low_skip_override[]
+    - ACPI: resource: Add Asus ExpertBook B2502CVA to
+      irq1_level_low_skip_override[]
+    - firmware/sysfb: Disable sysfb for firmware buffers with unknown parent
+    - close_range(): fix the logics in descriptor table trimming
+    - drm/sched: Fix dynamic job-flow control race
+    - drm/sched: Always wake up correct scheduler in drm_sched_entity_push_job
+    - drm/sched: Always increment correct scheduler score
+    - drm/xe: Delete unused GuC submission_state.suspend
+    - drm/xe: Use ordered wq for preempt fence waiting
+    - drm/xe: fix UAF around queue destruction
+    - sunrpc: change sp_nrthreads from atomic_t to unsigned int.
+    - NFSD: Async COPY result needs to return a write verifier
+    - NFSD: Limit the number of concurrent async COPY operations
+    - NFSD: Initialize struct nfsd4_copy earlier
+    - NFSD: Never decrement pending_async_copies on error
+    - drm/sched: revert "Always increment correct scheduler score"
+    - ALSA: control: Fix leftover snd_power_unref()
+    - Upstream stable to v6.6.55, v6.10.14
+  * By always inlining _compound_head(), clone() sees 3%+ performance increase
+    (LP: #2089327)
+    - mm: always inline _compound_head() with
+      CONFIG_HUGETLB_PAGE_OPTIMIZE_VMEMMAP=y
+  * Random flickering with Intel i915 (Comet Lake and Kaby Lake) on Linux 6.8+
+    (LP: #2086587)
+    - SAUCE: iommu/intel: disable DMAR for KBL and CML integrated gfx
+  * Add list of source files to linux-buildinfo (LP: #2086606)
+    - [Packaging] Sort build dependencies alphabetically
+    - [Packaging] Add list of used source files to buildinfo package
+  * UFS: uspi->s_3apb UBSAN: shift-out-of-bounds (LP: #2087853)
+    - ufs: ufs_sb_private_info: remove unused s_{2, 3}apb fields
+  * Mute/mic LEDs don't function on HP EliteBook 645 G10 (LP: #2087983)
+    - ALSA: hda/realtek: fix mute/micmute LEDs for a HP EliteBook 645 G10
+  * Noble update: upstream stable patchset 2024-11-22 (LP: #2089340)
+    - EDAC/synopsys: Fix ECC status and IRQ control race condition
+    - EDAC/synopsys: Fix error injection on Zynq UltraScale+
+    - wifi: rtw88: always wait for both firmware loading attempts
+    - crypto: xor - fix template benchmarking
+    - ACPI: PMIC: Remove unneeded check in tps68470_pmic_opregion_probe()
+    - wifi: brcmfmac: export firmware interface functions
+    - wifi: brcmfmac: introducing fwil query functions
+    - wifi: ath9k: Remove error checks when creating debugfs entries
+    - wifi: ath12k: fix BSS chan info request WMI command
+    - wifi: ath12k: match WMI BSS chan info structure with firmware definition
+    - wifi: ath12k: fix invalid AMPDU factor calculation in
+      ath12k_peer_assoc_h_he()
+    - net: stmmac: dwmac-loongson: Init ref and PTP clocks rate
+    - arm64: signal: Fix some under-bracketed UAPI macros
+    - wifi: rtw88: remove CPT execution branch never used
+    - RISC-V: KVM: Fix sbiret init before forwarding to userspace
+    - RISC-V: KVM: Allow legacy PMU access from guest
+    - RISC-V: KVM: Fix to allow hpmcounter31 from the guest
+    - mount: handle OOM on mnt_warn_timestamp_expiry
+    - ARM: 9410/1: vfp: Use asm volatile in fmrx/fmxr macros
+    - powercap: intel_rapl: Fix off by one in get_rpi()
+    - kselftest/arm64: signal: fix/refactor SVE vector length enumeration
+    - drivers/perf: Fix ali_drw_pmu driver interrupt status clearing
+    - wifi: mac80211: don't use rate mask for offchannel TX either
+    - wifi: iwlwifi: remove AX101, AX201 and AX203 support from LNL
+    - wifi: iwlwifi: config: label 'gl' devices as discrete
+    - wifi: iwlwifi: mvm: increase the time between ranging measurements
+    - padata: Honor the caller's alignment in case of chunk_size 0
+    - drivers/perf: hisi_pcie: Record hardware counts correctly
+    - drivers/perf: hisi_pcie: Fix TLP headers bandwidth counting
+    - kselftest/arm64: Actually test SME vector length changes via sigreturn
+    - can: j1939: use correct function name in comment
+    - ACPI: CPPC: Fix MASK_VAL() usage
+    - netfilter: nf_tables: elements with timeout below CONFIG_HZ never expire
+    - netfilter: nf_tables: reject element expiration with no timeout
+    - netfilter: nf_tables: reject expiration higher than timeout
+    - netfilter: nf_tables: remove annotation to access set timeout while holding
+      lock
+    - perf/arm-cmn: Improve debugfs pretty-printing for large configs
+    - perf/arm-cmn: Refactor node ID handling. Again.
+    - perf/arm-cmn: Fix CCLA register offset
+    - perf/arm-cmn: Ensure dtm_idx is big enough
+    - cpufreq: ti-cpufreq: Introduce quirks to handle syscon fails appropriately
+    - wifi: mt76: mt7915: fix oops on non-dbdc mt7986
+    - wifi: mt76: mt7996: use hweight16 to get correct tx antenna
+    - wifi: mt76: mt7996: fix traffic delay when switching back to working channel
+    - wifi: mt76: mt7996: fix wmm set of station interface to 3
+    - wifi: mt76: mt7996: fix HE and EHT beamforming capabilities
+    - wifi: mt76: mt7996: fix EHT beamforming capability check
+    - x86/sgx: Fix deadlock in SGX NUMA node search
+    - pm:cpupower: Add missing powercap_set_enabled() stub function
+    - crypto: hisilicon/hpre - mask cluster timeout error
+    - crypto: hisilicon/qm - reset device before enabling it
+    - crypto: hisilicon/qm - inject error before stopping queue
+    - wifi: mt76: mt7603: fix mixed declarations and code
+    - wifi: cfg80211: fix UBSAN noise in cfg80211_wext_siwscan()
+    - wifi: mt76: mt7915: fix rx filter setting for bfee functionality
+    - wifi: mt76: mt7996: ensure 4-byte alignment for beacon commands
+    - wifi: mt76: mt7996: fix uninitialized TLV data
+    - wifi: cfg80211: fix two more possible UBSAN-detected off-by-one errors
+    - wifi: mac80211: use two-phase skb reclamation in ieee80211_do_stop()
+    - wifi: wilc1000: fix potential RCU dereference issue in
+      wilc_parse_join_bss_param
+    - Bluetooth: hci_core: Fix sending MGMT_EV_CONNECT_FAILED
+    - Bluetooth: hci_sync: Ignore errors from HCI_OP_REMOTE_NAME_REQ_CANCEL
+    - sock_map: Add a cond_resched() in sock_hash_free()
+    - can: bcm: Clear bo->bcm_proc_read after remove_proc_entry().
+    - can: m_can: enable NAPI before enabling interrupts
+    - can: m_can: m_can_close(): stop clocks after device has been shut down
+    - Bluetooth: btusb: Fix not handling ZPL/short-transfer
+    - bareudp: Pull inner IP header in bareudp_udp_encap_recv().
+    - bareudp: Pull inner IP header on xmit.
+    - net: enetc: Use IRQF_NO_AUTOEN flag in request_irq()
+    - net: ipv6: rpl_iptunnel: Fix memory leak in rpl_input
+    - net: tipc: avoid possible garbage value
+    - ipv6: avoid possible NULL deref in rt6_uncached_list_flush_dev()
+    - ublk: move zone report data out of request pdu
+    - nbd: fix race between timeout and normal completion
+    - block, bfq: fix possible UAF for bfqq->bic with merge chain
+    - block, bfq: choose the last bfqq from merge chain in bfq_setup_cooperator()
+    - block, bfq: don't break merge chain in bfq_split_bfqq()
+    - cachefiles: Fix non-taking of sb_writers around set/removexattr
+    - erofs: fix incorrect symlink detection in fast symlink
+    - block, bfq: fix uaf for accessing waker_bfqq after splitting
+    - block, bfq: fix procress reference leakage for bfqq in merge chain
+    - io_uring/io-wq: do not allow pinning outside of cpuset
+    - io_uring/io-wq: inherit cpuset of cgroup in io worker
+    - block: fix potential invalid pointer dereference in blk_add_partition
+    - spi: ppc4xx: handle irq_of_parse_and_map() errors
+    - arm64: dts: exynos: exynos7885-jackpotlte: Correct RAM amount to 4GB
+    - arm64: dts: mediatek: mt8186: Fix supported-hw mask for GPU OPPs
+    - firmware: arm_scmi: Fix double free in OPTEE transport
+    - spi: ppc4xx: Avoid returning 0 when failed to parse and map IRQ
+    - regulator: Return actual error in of_regulator_bulk_get_all()
+    - arm64: dts: renesas: r9a07g043u: Correct GICD and GICR sizes
+    - arm64: dts: renesas: r9a07g054: Correct GICD and GICR sizes
+    - arm64: dts: renesas: r9a07g044: Correct GICD and GICR sizes
+    - ARM: dts: microchip: sam9x60: Fix rtc/rtt clocks
+    - arm64: dts: rockchip: Correct vendor prefix for Hardkernel ODROID-M1
+    - arm64: dts: ti: k3-j721e-sk: Fix reversed C6x carveout locations
+    - arm64: dts: ti: k3-j721e-beagleboneai64: Fix reversed C6x carveout locations
+    - spi: bcmbca-hsspi: Fix missing pm_runtime_disable()
+    - ARM: dts: microchip: sama7g5: Fix RTT clock
+    - ARM: dts: imx7d-zii-rmu2: fix Ethernet PHY pinctrl property
+    - ARM: versatile: fix OF node leak in CPUs prepare
+    - reset: berlin: fix OF node leak in probe() error path
+    - reset: k210: fix OF node leak in probe() error path
+    - clocksource/drivers/qcom: Add missing iounmap() on errors in
+      msm_dt_timer_init()
+    - arm64: dts: mediatek: mt8195: Correct clock order for dp_intf*
+    - x86/mm: Use IPIs to synchronize LAM enablement
+    - ASoC: rt5682s: Return devm_of_clk_add_hw_provider to transfer the error
+    - ASoC: tas2781: remove unused acpi_subysystem_id
+    - ASoC: tas2781: Use of_property_read_reg()
+    - ASoC: tas2781-i2c: Drop weird GPIO code
+    - ASoC: tas2781-i2c: Get the right GPIO line
+    - selftests/ftrace: Add required dependency for kprobe tests
+    - ALSA: hda: cs35l41: fix module autoloading
+    - m68k: Fix kernel_clone_args.flags in m68k_clone()
+    - ASoC: loongson: fix error release
+    - hwmon: (max16065) Fix overflows seen when writing limits
+    - hwmon: (max16065) Remove use of i2c_match_id()
+    - hwmon: (max16065) Fix alarm attributes
+    - mtd: slram: insert break after errors in parsing the map
+    - hwmon: (ntc_thermistor) fix module autoloading
+    - power: supply: axp20x_battery: Remove design from min and max voltage
+    - power: supply: max17042_battery: Fix SOC threshold calc w/ no current sense
+    - fbdev: hpfb: Fix an error handling path in hpfb_dio_probe()
+    - iommu/amd: Do not set the D bit on AMD v2 table entries
+    - mtd: powernv: Add check devm_kasprintf() returned value
+    - rcu/nocb: Fix RT throttling hrtimer armed from offline CPU
+    - mtd: rawnand: mtk: Use for_each_child_of_node_scoped()
+    - mtd: rawnand: mtk: Factorize out the logic cleaning mtk chips
+    - mtd: rawnand: mtk: Fix init error path
+    - iommu/arm-smmu-qcom: hide last LPASS SMMU context bank from linux
+    - iommu/arm-smmu-qcom: Work around SDM845 Adreno SMMU w/ 16K pages
+    - iommu/arm-smmu-qcom: apply num_context_bank fixes for SDM630 / SDM660
+    - pmdomain: core: Harden inter-column space in debug summary
+    - drm/stm: Fix an error handling path in stm_drm_platform_probe()
+    - drm/stm: ltdc: check memory returned by devm_kzalloc()
+    - drm/amd/display: Add null check for set_output_gamma in
+      dcn30_set_output_transfer_func
+    - drm/amdgpu: properly handle vbios fake edid sizing
+    - drm/radeon: properly handle vbios fake edid sizing
+    - scsi: smartpqi: revert propagate-the-multipath-failure-to-SML-quickly
+    - scsi: NCR5380: Check for phase match during PDMA fixup
+    - drm/amd/amdgpu: Properly tune the size of struct
+    - drm/rockchip: vop: Allow 4096px width scaling
+    - drm/rockchip: dw_hdmi: Fix reading EDID when using a forced mode
+    - drm/radeon/evergreen_cs: fix int overflow errors in cs track offsets
+    - drm/bridge: lontium-lt8912b: Validate mode in drm_bridge_funcs::mode_valid()
+    - drm/vc4: hdmi: Handle error case of pm_runtime_resume_and_get
+    - scsi: elx: libefc: Fix potential use after free in efc_nport_vport_del()
+    - jfs: fix out-of-bounds in dbNextAG() and diAlloc()
+    - drm/mediatek: Fix missing configuration flags in mtk_crtc_ddp_config()
+    - drm/mediatek: Use spin_lock_irqsave() for CRTC event lock
+    - powerpc/8xx: Fix initial memory mapping
+    - powerpc/8xx: Fix kernel vs user address comparison
+    - powerpc/vdso: Inconditionally use CFUNC macro
+    - drm/msm: Fix incorrect file name output in adreno_request_fw()
+    - drm/msm/a5xx: disable preemption in submits by default
+    - drm/msm/a5xx: properly clear preemption records on resume
+    - drm/msm/a5xx: fix races in preemption evaluation stage
+    - drm/msm/a5xx: workaround early ring-buffer emptiness check
+    - ipmi: docs: don't advertise deprecated sysfs entries
+    - drm/msm/dsi: correct programming sequence for SM8350 / SM8450
+    - drm/msm: fix %s null argument error
+    - drivers:drm:exynos_drm_gsc:Fix wrong assignment in gsc_bind()
+    - xen: use correct end address of kernel for conflict checking
+    - HID: wacom: Support sequence numbers smaller than 16-bit
+    - HID: wacom: Do not warn about dropped packets for first packet
+    - ata: libata: Clear DID_TIME_OUT for ATA PT commands with sense data
+    - minmax: avoid overly complex min()/max() macro arguments in xen
+    - xen: introduce generic helper checking for memory map conflicts
+    - xen: move max_pfn in xen_memory_setup() out of function scope
+    - xen: add capability to remap non-RAM pages to different PFNs
+    - xen: tolerate ACPI NVS memory overlapping with Xen allocated memory
+    - xen/swiotlb: add alignment check for dma buffers
+    - xen/swiotlb: fix allocated size
+    - tpm: Clean up TPM space after command failure
+    - sched/fair: Make SCHED_IDLE entity be preempted in strict hierarchy
+    - selftests/bpf: Workaround strict bpf_lsm return value check.
+    - selftests/bpf: Fix error linking uprobe_multi on mips
+    - bpf: Use -Wno-error in certain tests when building with GCC
+    - bpf: Disable some `attribute ignored' warnings in GCC
+    - bpf: Temporarily define BPF_NO_PRESEVE_ACCESS_INDEX for GCC
+    - selftests/bpf: Add CFLAGS per source file and runner
+    - selftests/bpf: Fix wrong binary in Makefile log output
+    - tools/runqslower: Fix LDFLAGS and add LDLIBS support
+    - selftests/bpf: Use pid_t consistently in test_progs.c
+    - selftests/bpf: Fix compile error from rlim_t in sk_storage_map.c
+    - selftests/bpf: Fix error compiling bpf_iter_setsockopt.c with musl libc
+    - selftests/bpf: Drop unneeded error.h includes
+    - selftests/bpf: Fix missing ARRAY_SIZE() definition in bench.c
+    - selftests/bpf: Fix missing UINT_MAX definitions in benchmarks
+    - selftests/bpf: Fix missing BUILD_BUG_ON() declaration
+    - selftests/bpf: Replace CHECK with ASSERT_* in ns_current_pid_tgid test
+    - selftests/bpf: Refactor out some functions in ns_current_pid_tgid test
+    - selftests/bpf: Add a cgroup prog bpf_get_ns_current_pid_tgid() test
+    - selftests/bpf: Fix include of <sys/fcntl.h>
+    - selftests/bpf: Fix compiling parse_tcp_hdr_opt.c with musl-libc
+    - selftests/bpf: Fix compiling kfree_skb.c with musl-libc
+    - selftests/bpf: Fix compiling flow_dissector.c with musl-libc
+    - selftests/bpf: Fix compiling tcp_rtt.c with musl-libc
+    - selftests/bpf: Fix compiling core_reloc.c with musl-libc
+    - selftests/bpf: Fix errors compiling lwt_redirect.c with musl libc
+    - selftests/bpf: Fix errors compiling decap_sanity.c with musl libc
+    - selftests/bpf: Fix errors compiling cg_storage_multi.h with musl libc
+    - selftests/bpf: Fix arg parsing in veristat, test_progs
+    - selftests/bpf: Fix error compiling test_lru_map.c
+    - selftests/bpf: Fix C++ compile error from missing _Bool type
+    - selftests/bpf: Fix flaky selftest lwt_redirect/lwt_reroute
+    - selftests/bpf: Fix redefinition errors compiling lwt_reroute.c
+    - selftests/bpf: Fix compile if backtrace support missing in libc
+    - selftests/bpf: Fix error compiling tc_redirect.c with musl libc
+    - samples/bpf: Fix compilation errors with cf-protection option
+    - bpf: correctly handle malformed BPF_CORE_TYPE_ID_LOCAL relos
+    - xz: cleanup CRC32 edits from 2018
+    - kthread: fix task state in kthread worker if being frozen
+    - ext4: clear EXT4_GROUP_INFO_WAS_TRIMMED_BIT even mount with discard
+    - smackfs: Use rcu_assign_pointer() to ensure safe assignment in smk_set_cipso
+    - ext4: avoid buffer_head leak in ext4_mark_inode_used()
+    - ext4: avoid potential buffer_head leak in __ext4_new_inode()
+    - ext4: avoid negative min_clusters in find_group_orlov()
+    - ext4: return error on ext4_find_inline_entry
+    - ext4: avoid OOB when system.data xattr changes underneath the filesystem
+    - ext4: check stripe size compatibility on remount as well
+    - sched/numa: Fix the vma scan starving issue
+    - nilfs2: fix potential null-ptr-deref in nilfs_btree_insert()
+    - nilfs2: determine empty node blocks as corrupted
+    - nilfs2: fix potential oob read in nilfs_btree_check_delete()
+    - bpf: Fix bpf_strtol and bpf_strtoul helpers for 32bit
+    - bpf: Fix helper writes to read-only maps
+    - bpf: Improve check_raw_mode_ok test for MEM_UNINIT-tagged types
+    - bpf: Zero former ARG_PTR_TO_{LONG,INT} args in case of error
+    - perf mem: Free the allocated sort string, fixing a leak
+    - perf inject: Fix leader sampling inserting additional samples
+    - perf report: Fix --total-cycles --stdio output error
+    - perf sched timehist: Fix missing free of session in perf_sched__timehist()
+    - perf stat: Display iostat headers correctly
+    - perf sched timehist: Fixed timestamp error when unable to confirm event
+      sched_in time
+    - perf time-utils: Fix 32-bit nsec parsing
+    - clk: imx: clk-audiomix: Correct parent clock for earc_phy and audpll
+    - clk: imx: imx6ul: fix default parent for enet*_ref_sel
+    - clk: imx: composite-8m: Less function calls in __imx8m_clk_hw_composite()
+      after error detection
+    - clk: imx: composite-8m: Enable gate clk with mcore_booted
+    - clk: imx: composite-93: keep root clock on when mcore enabled
+    - clk: imx: composite-7ulp: Check the PCC present bit
+    - clk: imx: fracn-gppll: fix fractional part of PLL getting lost
+    - clk: imx: imx8mp: fix clock tree update of TF-A managed clocks
+    - clk: imx: imx8qxp: Register dc0_bypass0_clk before disp clk
+    - clk: imx: imx8qxp: Parent should be initialized earlier than the clock
+    - remoteproc: imx_rproc: Correct ddr alias for i.MX8M
+    - remoteproc: imx_rproc: Initialize workqueue earlier
+    - clk: rockchip: Set parent rate for DCLK_VOP clock on RK3228
+    - clk: qcom: dispcc-sm8550: fix several supposed typos
+    - clk: qcom: dispcc-sm8550: use rcg2_ops for mdss_dptx1_aux_clk_src
+    - clk: qcom: dispcc-sm8650: Update the GDSC flags
+    - clk: qcom: dispcc-sm8550: use rcg2_shared_ops for ESC RCGs
+    - leds: bd2606mvv: Fix device child node usage in bd2606mvv_probe()
+    - pinctrl: ti: iodelay: Use scope based of_node_put() cleanups
+    - pinctrl: ti: ti-iodelay: Fix some error handling paths
+    - Input: ilitek_ts_i2c - avoid wrong input subsystem sync
+    - Input: ilitek_ts_i2c - add report id message validation
+    - drivers: media: dvb-frontends/rtl2832: fix an out-of-bounds write error
+    - drivers: media: dvb-frontends/rtl2830: fix an out-of-bounds write error
+    - PCI: Wait for Link before restoring Downstream Buses
+    - firewire: core: correct range of block for case of switch statement
+    - PCI: keystone: Fix if-statement expression in ks_pcie_quirk()
+    - clk: qcom: ipq5332: Register gcc_qdss_tsctr_clk_src
+    - clk: qcom: dispcc-sm8250: use special function for Lucid 5LPE PLL
+    - leds: leds-pca995x: Add support for NXP PCA9956B
+    - leds: pca995x: Use device_for_each_child_node() to access device child nodes
+    - leds: pca995x: Fix device child node usage in pca995x_probe()
+    - x86/PCI: Check pcie_find_root_port() return for NULL
+    - nvdimm: Fix devs leaks in scan_labels()
+    - PCI: xilinx-nwl: Fix register misspelling
+    - PCI: xilinx-nwl: Clean up clock on probe failure/removal
+    - media: platform: rzg2l-cru: rzg2l-csi2: Add missing MODULE_DEVICE_TABLE
+    - RDMA/iwcm: Fix WARNING:at_kernel/workqueue.c:#check_flush_dependency
+    - pinctrl: single: fix missing error code in pcs_probe()
+    - clk: at91: sama7g5: Allocate only the needed amount of memory for PLLs
+    - media: mediatek: vcodec: Fix H264 multi stateless decoder smatch warning
+    - media: mediatek: vcodec: Fix VP8 stateless decoder smatch warning
+    - media: mediatek: vcodec: Fix H264 stateless decoder smatch warning
+    - RDMA/rtrs: Reset hb_missed_cnt after receiving other traffic from peer
+    - RDMA/rtrs-clt: Reset cid to con_num - 1 to stay in bounds
+    - clk: ti: dra7-atl: Fix leak of of_nodes
+    - clk: starfive: Use pm_runtime_resume_and_get to fix pm_runtime_get_sync()
+      usage
+    - clk: rockchip: rk3588: Fix 32k clock name for pmu_24m_32k_100m_src_p
+    - nfsd: remove unneeded EEXIST error check in nfsd_do_file_acquire
+    - nfsd: fix refcount leak when file is unhashed after being found
+    - pinctrl: mvebu: Fix devinit_dove_pinctrl_probe function
+    - IB/core: Fix ib_cache_setup_one error flow cleanup
+    - PCI: kirin: Fix buffer overflow in kirin_pcie_parse_port()
+    - RDMA/erdma: Return QP state in erdma_query_qp
+    - RDMA/mlx5: Limit usage of over-sized mkeys from the MR cache
+    - watchdog: imx_sc_wdt: Don't disable WDT in suspend
+    - RDMA/hns: Don't modify rq next block addr in HIP09 QPC
+    - RDMA/hns: Fix Use-After-Free of rsv_qp on HIP08
+    - RDMA/hns: Fix the overflow risk of hem_list_calc_ba_range()
+    - RDMA/hns: Fix spin_unlock_irqrestore() called with IRQs enabled
+    - RDMA/hns: Fix VF triggering PF reset in abnormal interrupt handler
+    - RDMA/hns: Fix 1bit-ECC recovery address in non-4K OS
+    - RDMA/hns: Optimize hem allocation performance
+    - RDMA/hns: Fix restricted __le16 degrades to integer issue
+    - RDMA/mlx5: Obtain upper net device only when needed
+    - riscv: Fix fp alignment bug in perf_callchain_user()
+    - RDMA/cxgb4: Added NULL check for lookup_atid
+    - RDMA/irdma: fix error message in irdma_modify_qp_roce()
+    - ntb: intel: Fix the NULL vs IS_ERR() bug for debugfs_create_dir()
+    - ntb_perf: Fix printk format
+    - ntb: Force physically contiguous allocation of rx ring buffers
+    - nfsd: call cache_put if xdr_reserve_space returns NULL
+    - nfsd: return -EINVAL when namelen is 0
+    - crypto: caam - Pad SG length when allocating hash edesc
+    - crypto: powerpc/p10-aes-gcm - Disable CRYPTO_AES_GCM_P10
+    - f2fs: atomic: fix to avoid racing w/ GC
+    - f2fs: reduce expensive checkpoint trigger frequency
+    - f2fs: fix to avoid racing in between read and OPU dio write
+    - f2fs: Create COW inode from parent dentry for atomic write
+    - f2fs: fix to wait page writeback before setting gcing flag
+    - f2fs: atomic: fix to truncate pagecache before on-disk metadata truncation
+    - f2fs: support .shutdown in f2fs_sops
+    - f2fs: fix to avoid use-after-free in f2fs_stop_gc_thread()
+    - f2fs: compress: don't redirty sparse cluster during {,de}compress
+    - f2fs: prevent atomic file from being dirtied before commit
+    - f2fs: get rid of online repaire on corrupted directory
+    - f2fs: fix to don't set SB_RDONLY in f2fs_handle_critical_error()
+    - spi: atmel-quadspi: Undo runtime PM changes at driver exit time
+    - spi: spi-fsl-lpspi: Undo runtime PM changes at driver exit time
+    - lib/sbitmap: define swap_lock as raw_spinlock_t
+    - spi: atmel-quadspi: Avoid overwriting delay register settings
+    - nvme-multipath: system fails to create generic nvme device
+    - iio: adc: ad7606: fix oversampling gpio array
+    - iio: adc: ad7606: fix standby gpio state to match the documentation
+    - driver core: Fix error handling in driver API device_rename()
+    - ABI: testing: fix admv8818 attr description
+    - iio: chemical: bme680: Fix read/write ops to device by adding mutexes
+    - iio: magnetometer: ak8975: drop incorrect AK09116 compatible
+    - dt-bindings: iio: asahi-kasei,ak8975: drop incorrect AK09116 compatible
+    - driver core: Fix a potential null-ptr-deref in module_add_driver()
+    - serial: 8250: omap: Cleanup on error in request_irq
+    - coresight: tmc: sg: Do not leak sg_table
+    - interconnect: icc-clk: Add missed num_nodes initialization
+    - cxl/pci: Fix to record only non-zero ranges
+    - vhost_vdpa: assign irq bypass producer token correctly
+    - ep93xx: clock: Fix off by one in ep93xx_div_recalc_rate()
+    - Revert "dm: requeue IO if mapping table not yet available"
+    - net: xilinx: axienet: Schedule NAPI in two steps
+    - net: xilinx: axienet: Fix packet counting
+    - netfilter: nf_reject_ipv6: fix nf_reject_ip6_tcphdr_put()
+    - net: seeq: Fix use after free vulnerability in ether3 Driver Due to Race
+      Condition
+    - net: ipv6: select DST_CACHE from IPV6_RPL_LWTUNNEL
+    - tcp: check skb is non-NULL in tcp_rto_delta_us()
+    - net: qrtr: Update packets cloning when broadcasting
+    - bonding: Fix unnecessary warnings and logs from bond_xdp_get_xmit_slave()
+    - virtio_net: Fix mismatched buf address when unmapping for small packets
+    - netfilter: nf_tables: Keep deleted flowtable hooks until after RCU
+    - netfilter: ctnetlink: compile ctnetlink_label_size with
+      CONFIG_NF_CONNTRACK_EVENTS
+    - netfilter: nf_tables: use rcu chain hook list iterator from netlink dump
+      path
+    - io_uring/sqpoll: do not allow pinning outside of cpuset
+    - io_uring: check for presence of task_work rather than TIF_NOTIFY_SIGNAL
+    - mm: call the security_mmap_file() LSM hook in remap_file_pages()
+    - drm/amd/display: Fix Synaptics Cascaded Panamera DSC Determination
+    - Revert "net: libwx: fix alloc msix vectors failed"
+    - xen: move checks for e820 conflicts further up
+    - xen: allow mapping ACPI data using a different physical address
+    - io_uring/sqpoll: retain test for whether the CPU is valid
+    - io_uring/sqpoll: do not put cpumask on stack
+    - Remove *.orig pattern from .gitignore
+    - PCI: Revert to the original speed after PCIe failed link retraining
+    - PCI: Clear the LBMS bit after a link retrain
+    - PCI: dra7xx: Fix threaded IRQ request for "dra7xx-pcie-main" IRQ
+    - PCI: imx6: Fix missing call to phy_power_off() in error handling
+    - PCI: Correct error reporting with PCIe failed link retraining
+    - PCI: Use an error code with PCIe failed link retraining
+    - PCI: xilinx-nwl: Fix off-by-one in INTx IRQ handler
+    - Revert "soc: qcom: smd-rpm: Match rpmsg channel instead of compatible"
+    - ASoC: rt5682: Return devm_of_clk_add_hw_provider to transfer the error
+    - soc: fsl: cpm1: tsa: Fix tsa_write8()
+    - soc: versatile: integrator: fix OF node leak in probe() error path
+    - Revert "media: tuners: fix error return code of
+      hybrid_tuner_request_state()"
+    - iommufd: Protect against overflow of ALIGN() during iova allocation
+    - Input: adp5588-keys - fix check on return code
+    - Input: i8042 - add TUXEDO Stellaris 16 Gen5 AMD to i8042 quirk table
+    - Input: i8042 - add TUXEDO Stellaris 15 Slim Gen6 AMD to i8042 quirk table
+    - Input: i8042 - add another board name for TUXEDO Stellaris Gen5 AMD line
+    - KVM: arm64: Add memory length checks and remove inline in do_ffa_mem_xfer
+    - KVM: x86: Enforce x2APIC's must-be-zero reserved ICR bits
+    - KVM: x86: Move x2APIC ICR helper above kvm_apic_write_nodecode()
+    - KVM: Use dedicated mutex to protect kvm_usage_count to avoid deadlock
+    - drm/amd/display: Add HDMI DSC native YCbCr422 support
+    - drm/amd/display: Round calculated vtotal
+    - drm/amd/display: Validate backlight caps are sane
+    - KEYS: prevent NULL pointer dereference in find_asymmetric_key()
+    - powerpc/atomic: Use YZ constraints for DS-form instructions
+    - fs: Create a generic is_dot_dotdot() utility
+    - ksmbd: make __dir_empty() compatible with POSIX
+    - ksmbd: allow write with FILE_APPEND_DATA
+    - ksmbd: handle caseless file creation
+    - ata: libata-scsi: Fix ata_msense_control() CDL page reporting
+    - scsi: sd: Fix off-by-one error in sd_read_block_characteristics()
+    - scsi: ufs: qcom: Update MODE_MAX cfg_bw value
+    - scsi: mac_scsi: Revise printk(KERN_DEBUG ...) messages
+    - scsi: mac_scsi: Refactor polling loop
+    - scsi: mac_scsi: Disallow bus errors during PDMA send
+    - can: esd_usb: Remove CAN_CTRLMODE_3_SAMPLES for CAN-USB/3-FD
+    - wifi: rtw88: Fix USB/SDIO devices not transmitting beacons
+    - usbnet: fix cyclical race on disconnect with work queue
+    - USB: appledisplay: close race between probe and completion handler
+    - USB: misc: cypress_cy7c63: check for short transfer
+    - USB: class: CDC-ACM: fix race between get_serial and set_serial
+    - usb: cdnsp: Fix incorrect usb_request status
+    - usb: dwc2: drd: fix clock gating on USB role switch
+    - bus: integrator-lm: fix OF node leak in probe()
+    - bus: mhi: host: pci_generic: Fix the name for the Telit FE990A
+    - firmware_loader: Block path traversal
+    - tty: rp2: Fix reset with non forgiving PCIe host bridges
+    - xhci: Set quirky xHC PCI hosts to D3 _after_ stopping and freeing them.
+    - serial: qcom-geni: fix fifo polling timeout
+    - crypto: ccp - Properly unregister /dev/sev on sev PLATFORM_STATUS failure
+    - drbd: Fix atomicity violation in drbd_uuid_set_bm()
+    - drbd: Add NULL check for net_conf to prevent dereference in state validation
+    - ACPI: sysfs: validate return type of _STR method
+    - ACPI: resource: Add another DMI match for the TongFang GMxXGxx
+    - efistub/tpm: Use ACPI reclaim memory for event log to avoid corruption
+    - perf/x86/intel/pt: Fix sampling synchronization
+    - wifi: mt76: mt7921: Check devm_kasprintf() returned value
+    - wifi: mt76: mt7915: check devm_kasprintf() returned value
+    - wifi: mt76: mt7996: fix NULL pointer dereference in mt7996_mcu_sta_bfer_he
+    - wifi: rtw88: 8821cu: Remove VID/PID 0bda:c82c
+    - wifi: rtw88: 8822c: Fix reported RX band width
+    - wifi: mt76: mt7615: check devm_kasprintf() returned value
+    - debugobjects: Fix conditions in fill_pool()
+    - btrfs: tree-checker: fix the wrong output of data backref objectid
+    - btrfs: always update fstrim_range on failure in FITRIM ioctl
+    - f2fs: fix several potential integer overflows in file offsets
+    - f2fs: prevent possible int overflow in dir_block_index()
+    - f2fs: avoid potential int overflow in sanity_check_area_boundary()
+    - f2fs: Require FMODE_WRITE for atomic write ioctls
+    - f2fs: fix to check atomic_file in f2fs ioctl interfaces
+    - hwrng: mtk - Use devm_pm_runtime_enable
+    - hwrng: bcm2835 - Add missing clk_disable_unprepare in bcm2835_rng_init
+    - hwrng: cctrng - Add missing clk_disable_unprepare in cctrng_resume
+    - arm64: esr: Define ESR_ELx_EC_* constants as UL
+    - arm64: errata: Enable the AC03_CPU_38 workaround for ampere1a
+    - arm64: dts: rockchip: Raise Pinebook Pro's panel backlight PWM frequency
+    - arm64: dts: qcom: sa8775p: Mark APPS and PCIe SMMUs as DMA coherent
+    - arm64: dts: rockchip: Correct the Pinebook Pro battery design capacity
+    - vfs: fix race between evice_inodes() and find_inode()&iput()
+    - fs: Fix file_set_fowner LSM hook inconsistencies
+    - nfs: fix memory leak in error path of nfs4_do_reclaim
+    - EDAC/igen6: Fix conversion of system address to physical memory address
+    - icmp: change the order of rate limits
+    - cpuidle: riscv-sbi: Use scoped device node handling to fix missing
+      of_node_put
+    - padata: use integer wrap around to prevent deadlock on seq_nr overflow
+    - spi: fspi: involve lut_num for struct nxp_fspi_devtype_data
+    - ARM: dts: imx6ul-geam: fix fsl,pins property in tscgrp pinctrl
+    - soc: versatile: realview: fix memory leak during device remove
+    - soc: versatile: realview: fix soc_dev leak during device remove
+    - USB: misc: yurex: fix race between read and write
+    - xhci: Add a quirk for writing ERST in high-low order
+    - usb: xhci: fix loss of data on Cadence xHC
+    - pps: remove usage of the deprecated ida_simple_xx() API
+    - pps: add an error check in parport_attach
+    - serial: don't use uninitialized value in uart_poll_init()
+    - x86/idtentry: Incorporate definitions/declarations of the FRED entries
+    - x86/entry: Remove unwanted instrumentation in common_interrupt()
+    - lib/bitmap: add bitmap_{read,write}()
+    - btrfs: subpage: fix the bitmap dump which can cause bitmap corruption
+    - btrfs: fix race setting file private on concurrent lseek using same fd
+    - dt-bindings: spi: nxp-fspi: support i.MX93 and i.MX95
+    - dt-bindings: spi: nxp-fspi: add imx8ulp support
+    - thunderbolt: Improve DisplayPort tunnel setup process to be more robust
+    - bpf: lsm: Set bpf_lsm_blob_sizes.lbs_task to 0
+    - dm-verity: restart or panic on an I/O error
+    - lockdep: fix deadlock issue between lockdep and rcu
+    - mm: only enforce minimum stack gap size if it's sensible
+    - spi: fspi: add support for imx8ulp
+    - module: Fix KCOV-ignored file name
+    - mm/damon/vaddr: protect vma traversal in __damon_va_thre_regions() with rcu
+      read lock
+    - i2c: aspeed: Update the stop sw state when the bus recovery occurs
+    - i2c: isch: Add missed 'else'
+    - Documentation: KVM: fix warning in "make htmldocs"
+    - bpf: Fix use-after-free in bpf_uprobe_multi_link_attach()
+    - wifi: brcmfmac: add linefeed at end of file
+    - x86/tdx: Fix "in-kernel MMIO" check
+    - spi: atmel-quadspi: Fix wrong register value written to MR
+    - Revert: "dm-verity: restart or panic on an I/O error"
+    - wifi: ath11k: use work queue to process beacon tx event
+    - crypto: qat - disable IOV in adf_dev_stop()
+    - crypto: qat - fix recovery flow for VFs
+    - crypto: qat - ensure correct order in VF restarting handler
+    - crypto: iaa - Fix potential use after free bug
+    - autofs: fix missing fput for FSCONFIG_SET_FD
+    - arm64: smp: smp_send_stop() and crash_smp_send_stop() should try non-NMI
+      first
+    - thermal: core: Fold two functions into their respective callers
+    - thermal: core: Fix rounding of delay jiffies
+    - perf/dwc_pcie: Fix registration issue in multi PCIe controller instances
+    - perf/dwc_pcie: Always register for PCIe bus notifier
+    - ACPI: video: force native for some T2 macbooks
+    - ACPI: video: force native for Apple MacbookPro9,2
+    - wifi: cfg80211: fix bug of mapping AF3x to incorrect User Priority
+    - wifi: mac80211: fix the comeback long retry times
+    - ACPICA: Implement ACPI_WARNING_ONCE and ACPI_ERROR_ONCE
+    - ACPICA: executer/exsystem: Don't nag user about every Stall() violating the
+      spec
+    - netfilter: nft_dynset: annotate data-races around set timeout
+    - wifi: mt76: mt7921: fix wrong UNII-4 freq range check for the channel usage
+    - crypto: ccp - do not request interrupt on cmd completion when irqs disabled
+    - wifi: mt76: connac: fix checksum offload fields of connac3 RXD
+    - net: hsr: Use the seqnr lock for frames received via interlink port.
+    - crypto: n2 - Set err to EINVAL if snprintf fails for hmac
+    - firmware: qcom: scm: Disable SDI and write no dump to dump mode
+    - arm64: dts: renesas: r9a08g045: Correct GICD and GICR sizes
+    - arm64: tegra: Correct location of power-sensors for IGX Orin
+    - arm64: dts: ti: k3-am654-idk: Fix dtbs_check warning in ICSSG dmas
+    - selftests/ftrace: Fix eventfs ownership testcase to find mount point
+    - iommu/amd: Introduce struct protection_domain.pd_mode
+    - iommu/amd: Allocate the page table root using GFP_KERNEL
+    - iommu/amd: Convert comma to semicolon
+    - platform/x86: ideapad-laptop: Make the scope_guard() clear of its scope
+    - kselftest: dt: Ignore nodes that have ancestors disabled
+    - bpf, x64: Fix tailcall hierarchy
+    - bpf, lsm: Add check for BPF LSM return value
+    - bpf: Fix compare error in function retval_range_within
+    - bpf: Fail verification for sign-extension of packet data/data_end/data_meta
+    - selftests/bpf: Support checks against a regular expression
+    - selftests/bpf: no need to track next_match_pos in struct test_loader
+    - selftests/bpf: extract test_loader->expect_msgs as a data structure
+    - selftests/bpf: allow checking xlated programs in verifier_* tests
+    - selftests/bpf: __arch_* macro to limit test cases to specific archs
+    - libbpf: Fix bpf_object__open_skeleton()'s mishandling of options
+    - s390/ap: Fix deadlock caused by recursive lock of the AP bus scan mutex
+    - sched/deadline: Fix schedstats vs deadline servers
+    - perf scripts python cs-etm: Restore first sample log in verbose mode
+    - perf lock contention: Change stack_id type to s32
+    - quota: avoid missing put_quota_format when DQUOT_SUSPENDED is passed
+    - media: staging: media: starfive: camss: Drop obsolete return value
+      documentation
+    - leds: gpio: Set num_leds after allocation
+    - iommufd/selftest: Fix buffer read overrrun in the dirty test
+    - iommufd: Check the domain owner of the parent before creating a nesting
+      domain
+    - RDMA/mlx5: Fix counter update on MR cache mkey creation
+    - RDMA/mlx5: Drop redundant work canceling from clean_keys()
+    - RDMA/mlx5: Fix MR cache temp entries cleanup
+    - RDMA/hns: Fix ah error counter in sw stat not increasing
+    - Coresight: Set correct cs_mode for TPDM to fix disable issue
+    - Coresight: Set correct cs_mode for dummy source to fix disable issue
+    - interconnect: qcom: sm8250: Enable sync_state
+    - vdpa/mlx5: Fix invalid mr resource destroy
+    - net: stmmac: set PP_FLAG_DMA_SYNC_DEV only if XDP is enabled
+    - selftests: netfilter: Avoid hanging ipvs.sh
+    - io_uring/rw: treat -EOPNOTSUPP for IOCB_NOWAIT like -EAGAIN
+    - mm: migrate: annotate data-race in migrate_folio_unmap()
+    - selftests/bpf: correctly move 'log' upon successful match
+    - soc: fsl: cpm1: qmc: Update TRNSYNC only in transparent mode
+    - drm/amdgpu/vcn: enable AV1 on both instances
+    - drm/amd/display: Clean up dsc blocks in accelerated mode
+    - drm/amd/display: Skip to enable dsc if it has been off
+    - arm64: dts: mediatek: mt8195-cherry: Mark USB 3.0 on xhci1 as disabled
+    - usb: xHCI: add XHCI_RESET_ON_RESUME quirk for Phytium xHCI host
+    - serial: qcom-geni: fix false console tx restart
+    - crypto: qcom-rng - fix support for ACPI-based systems
+    - ACPI: resource: Do IRQ override on MECHREV GM7XG0M
+    - perf/x86/intel: Allow to setup LBR for counting event for BPF
+    - f2fs: check discard support for conventional zones
+    - netfs: Delete subtree of 'fs/netfs' when netfs module exits
+    - md: Don't flush sync_work in md_write_start()
+    - tools/nolibc: include arch.h from string.h
+    - KVM: x86: Make x2APIC ID 100% readonly
+    - x86/mm/cpa: Warn for set_memory_XXcrypted() VMM fails
+    - x86/mm: Make x86_platform.guest.enc_status_change_*() return an error
+    - x86/tdx: Account shared memory
+    - x86/mm: Add callbacks to prepare encrypted memory for kexec
+    - x86/tdx: Convert shared memory back to private on kexec
+    - soc: qcom: geni-se: add GP_LENGTH/IRQ_EN_SET/IRQ_EN_CLEAR registers
+    - serial: qcom-geni: fix arg types for qcom_geni_serial_poll_bit()
+    - serial: qcom-geni: introduce qcom_geni_serial_poll_bitfield()
+    - idpf: stop using macros for accessing queue descriptors
+    - fs_parse: add uid & gid option option parsing helpers
+    - compiler.h: specify correct attribute for .rodata..c_jump_table
+    - exfat: resolve memory leak from exfat_create_upcase_table()
+    - s390/ftrace: Avoid calling unwinder in ftrace_return_address()
+    - fbdev: xen-fbfront: Assign fb_info->device
+    - [Config] update configs for CONFIG_CRYPTO_AES_GCM_P10
+    - Upstream stable to v6.6.54, v6.10.13
+  * Backport some AppArmor complain-mode profile bugfixes from Oracular
+    (LP: #2086210)
+    - SAUCE: apparmor4.0.0 [94/99]: apparmor: allocate xmatch for nullpdf inside
+      aa_alloc_null
+    - SAUCE: apparmor4.0.0 [95/99]: apparmor: properly handle cx/px lookup failure
+      for complain mode profiles
+  * Noble update: upstream stable patchset 2024-11-08 (LP: #2087519)
+    - ASoC: SOF: mediatek: Add missing board compatible
+    - ASoC: mediatek: mt8188: Mark AFE_DAC_CON0 register as volatile
+    - ASoC: allow module autoloading for table db1200_pids
+    - ASoC: allow module autoloading for table board_ids
+    - scsi: lpfc: Fix overflow build issue
+    - pinctrl: at91: make it work with current gpiolib
+    - hwmon: (asus-ec-sensors) remove VRM temp X570-E GAMING
+    - microblaze: don't treat zero reserved memory regions as error
+    - platform/x86: x86-android-tablets: Make Lenovo Yoga Tab 3 X90F DMI match
+      less strict
+    - net: ftgmac100: Ensure tx descriptor updates are visible
+    - LoongArch: Define ARCH_IRQ_INIT_FLAGS as IRQ_NOPROBE
+    - wifi: iwlwifi: lower message level for FW buffer destination
+    - wifi: iwlwifi: mvm: fix iwl_mvm_scan_fits() calculation
+    - wifi: iwlwifi: mvm: fix iwl_mvm_max_scan_ie_fw_cmd_room()
+    - wifi: iwlwifi: mvm: pause TCM when the firmware is stopped
+    - wifi: iwlwifi: mvm: don't wait for tx queues if firmware is dead
+    - wifi: mac80211: free skb on error path in ieee80211_beacon_get_ap()
+    - wifi: iwlwifi: clear trans->state earlier upon error
+    - can: mcp251xfd: mcp251xfd_ring_init(): check TX-coalescing configuration
+    - ASoC: Intel: soc-acpi-cht: Make Lenovo Yoga Tab 3 X90F DMI match less strict
+    - ASoC: intel: fix module autoloading
+    - ASoC: google: fix module autoloading
+    - ASoC: tda7419: fix module autoloading
+    - ASoC: fix module autoloading
+    - spi: spidev: Add an entry for elgin,jg10309-01
+    - ASoC: amd: yc: Add a quirk for MSI Bravo 17 (D7VEK)
+    - ALSA: hda: add HDMI codec ID for Intel PTL
+    - drm: komeda: Fix an issue related to normalized zpos
+    - spi: bcm63xx: Enable module autoloading
+    - smb: client: fix hang in wait_for_response() for negproto
+    - x86/hyperv: Set X86_FEATURE_TSC_KNOWN_FREQ when Hyper-V provides frequency
+    - tools: hv: rm .*.cmd when make clean
+    - spi: spidev: Add missing spi_device_id for jg10309-01
+    - ocfs2: add bounds checking to ocfs2_xattr_find_entry()
+    - ocfs2: strict bound check before memcmp in ocfs2_xattr_find_entry()
+    - drm: Use XArray instead of IDR for minors
+    - accel: Use XArray instead of IDR for minors
+    - drm: Expand max DRM device number to full MINORBITS
+    - powercap/intel_rapl: Add support for AMD family 1Ah
+    - netfilter: nft_socket: make cgroupsv2 matching work with namespaces
+    - netfilter: nft_socket: Fix a NULL vs IS_ERR() bug in
+      nft_socket_cgroup_subtree_level()
+    - nvme-pci: qdepth 1 quirk
+    - x86/mm: Switch to new Intel CPU model defines
+    - can: mcp251xfd: properly indent labels
+    - can: mcp251xfd: move mcp251xfd_timestamp_start()/stop() into
+      mcp251xfd_chip_start/stop()
+    - USB: serial: pl2303: add device id for Macrosilicon MS3020
+    - USB: usbtmc: prevent kernel-usb-infoleak
+    - platform/x86: asus-wmi: Fix spurious rfkill on UX8406MA
+    - ASoC: mediatek: mt8188-mt6359: Modify key
+    - clk: qcom: gcc-sm8650: Don't use shared clk_ops for QUPs
+    - ice: check for XDP rings instead of bpf program when unconfiguring
+    - powercap/intel_rapl: Fix the energy-pkg event for AMD CPUs
+    - powercap: intel_rapl: Change an error pointer to NULL
+    - Upstream stable to v6.6.53, v6.10.12
+
+  [ Ubuntu: 6.8.0-52.53 ]
+
+  * noble/linux: 6.8.0-52.53 -proposed tracker (LP: #2093521)
+  * CVE-2024-53164
+    - net: sched: fix ordering of qlen adjustment
+  * CVE-2024-53141
+    - netfilter: ipset: add missing range check in bitmap_ip_uadt
+  * CVE-2024-53103
+    - hv_sock: Initializing vsk->trans to NULL to prevent a dangling pointer
+
+  [ Ubuntu: 6.8.0-51.52 ]
+
+  * noble/linux: 6.8.0-51.52 -proposed tracker (LP: #2090369)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+    - [Packaging] update variants
+  * MGLRU: kswapd uses 100% CPU when MGLRU is enabled and under memory pressure
+    (LP: #2087886)
+    - mm/mglru: only clear kswapd_failures if reclaimable
+  * CVE-2024-50264
+    - vsock/virtio: Initialization of the dangling pointer occurring in vsk->trans
+  * CVE-2024-53057
+    - net/sched: stop qdisc_tree_reduce_backlog on TC_H_ROOT
+  * CVE-2024-49967
+    - ext4: no need to continue when the number of entries is 1
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 12 Feb 2025 21:04:42 +0900
+
+linux-qcom (6.8.0-1027.27) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1027.27 -proposed tracker (LP: #2097551)
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 07 Feb 2025 00:20:45 +0900
+
+linux-qcom (6.8.0-1025.25) noble; urgency=medium
+
+  * noble/linux-qcom: 6.8.0-1025.25 -proposed tracker (LP: #2097247)
+    - [Packaging] switch from jammy to noble
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 03 Feb 2025 22:35:26 +0900
+
+linux-qcom (6.8.0-1023.23) jammy; urgency=medium
+
+  * jammy/linux-qcom: 6.8.0-1023.23 -proposed tracker (LP: #2097246)
+
+  * Miscellaneous upstream changes
+    - PENDING: iommu/arm-smmu: add ACTLR data and support for sa7255p
+    - QCLINUX: arm64: dts: qcom: Enable gpu tsens mitigation for sa8775p variants
+    - PENDING: arm64: dts: qcom: sa8255p: Add ICE node
+    - QCLINUX: arm64: defconfigs: Enable PCIe EP configuration
+    - QCLINUX: firmware: qtee_shmbridge: Fix stubs
+    - FROMLIST: firmware: qcom: scm: add a call for deriving the software secret
+    - FROMLIST: firmware: qcom: scm: add calls for creating, preparing and
+      importing keys
+    - QCLINUX: arm64: qcom_defconfig: enable SHM Bridge support for the TZ memory
+      allocator
+    - QCLINUX: firmware: qtee_shmbrige: Disable bridge enablement call
+    - PENDING: firmware: qcom_tzmem: Add register/deregister interfaces
+    - PENDING: firmware: qcom: tz_log: Migrate to qcom_tzmem interfaces
+    - PENDING: soc: qcom: memory_dump: Use qcom_tzmem interfaces
+    - PENDING: arm64: defconfig: qcom: Enable MMC crypto
+    - QCLINUX: soc: qcom: smem: Switch partitions to xarray
+    - QCLINUX: soc: qcom: smem: Ignore multi remote host partitions
+    - PENDING: arm64: dts: qcom: sa8255p: Add PCIe EP nodes
+    - PENDING: qcom: ice: enable ufs clock scaling
+    - PENDING: arm64: dts: qcom: qcs9075-rb8: Add PON resin support
+    - PENDING: arm64: dts: qcom: Add duplicate funnel device
+    - PENDING: clk: qcom: videocc-sa8775p: Remove HW_CTRL for video_cc_mvs0_gdsc
+    - PENDING: arm64: dts: qcom: Add cpufreq_hw support on sa7255p
+    - QCLINUX: ASoC: qcom: qdsp6: msm_audio_mem: Fix excessive logging in
+      msm_audio_mem_ioctl fun
+    - BACKPORT: FROMLIST: arm64: dts: qcom: qcs9100: Update memory map for QCS9100
+      Ride and QCS9100 Ride Rev3
+    - QCLINUX: firmware: qcom_scm: Fix indentation for ice scm calls
+    - FROMLIST: PCI: epf-mhi: Update device id for SA8775P
+    - FROMLIST: bus: mhi: host: pci_generic: Add supoprt for SA8775P target
+    - QCLINUX: usb: dwc3: qcom: export core_exit_mode and free_event_buffers
+    - FROMLIST: net: Add MHI Endpoint network driver
+    - PENDING: arm64: dts: qcom: Add MXC power domain to camcc node on QCS8300
+    - PENDING: arm64: dts: qcom: sa7255p: Add pcie nodes
+    - PENDING: net: phy: aquantia: AQR113c fix up PMA capabilities
+    - QCLINUX: arm64: dts: qcom: Add nodes for Data Capture and Compare
+    - QCLINUX: arm64: dts: qcom: Update the size for swao-etf node
+    - PENDING: thermal: qcom: add support for nsp1 qmi tmd devices
+    - PENDING: arm64: dts: qcom: Disable idle injection cooling device for cpu0
+    - QCLINUX: arm64: dts: qcom: Enable cdsp qmi tmd devices for sa8775p variants
+    - QCLINUX: arm64: dts: qcom: use 2nd trip for gpu passive cooling mitigation
+    - PENDING: net: stmmac: Add sa8797p support within ethqos driver
+    - PENDING: net: stmmac: Add 4k Virtualization support to Emac registers
+    - PENDING: net: stmmac: Add IO macro configuration for USXGMII
+    - PENDING: arm64: dts: qcom: Enable EUD on QCS9075 RB8
+    - PENDING: arm64: dts: qcom: sa7255p: Add ICE node
+    - QCLINUX: arm64: defconfig: enable scmi-cpufreq and cpucp mbox
+    - PENDING: net: stmmac: Add Qcom specific changes for HDMA
+    - QCLINUX: arm64: defconfigs: Enable MHI configs for PCIE RC and EP
+    - FROMLIST: drm/msm/dpu: fix the intf_type of MST interfaces
+    - FROMLIST: drm/msm/dp: split msm_dp_panel_read_sink_caps() into two parts
+    - FROMLIST: drm/msm/dp: add a helper to read mst caps for dp_panel
+    - FROMLIST: drm/msm/dp: remove dp_display's dp_mode and use dp_panel's instead
+    - FROMLIST: drm/msm/dp: break up dp_display_enable into two parts
+    - FROMLIST: drm/msm/dp: re-arrange dp_display_disable() into functional parts
+    - FROMLIST: drm/msm/dp: allow dp_ctrl stream APIs to use any panel passed to
+      it
+    - PENDING: net: stmmac: Add missing 25GMAC link capabilities
+    - PENDING: phy: qcom: qmp: Add default Type-C reverse orientation flag
+    - PENDING: net: stmmac: Move desc cache compute within HDMA
+    - PENDING: net: PCS: Add Qualcomm XPCS driver
+    - PENDING: arm64: dts: qcom: qcs8300: add support for steam 1
+    - FROMLIST: nvmem: qfprom: Add constraint read for some SoCs
+    - FROMLIST: arm64/dts/qcom: add mst support for stream 1 clk
+    - FROMLIST: drm/msm/dp: move the pixel clock control to its own API
+    - PENDING: net: stmmac: Use new Qualcomm XPCS driver
+    - QCLINUX: arm64: defconfig: Remove HVC console for Gen5auto targets
+    - PENDING: ASoC: codecs: wcd937x: fix aux playback issue
+    - FROMLIST: arm64: dts: qcom: sa8775p: Add CPUs to psci power domain
+    - QCLINUX: arm64: dts: qcom: Disable HCI uart for Industrial mezz kit
+    - PENDING: soc: qcom: smcinvoke: Remove mem-buf dependency for PVM
+    - QCLINUX: ASoC: qcom: qcm6490: fix the probe defer issue
+    - FROMLIST: drm/msm/dp: split dp_ctrl_off() into stream and link parts
+    - FROMLIST: drm/msm/dp: make bridge helpers use dp_display to allow re-use
+    - FROMLIST: drm/msm/dp: separate dp_display_prepare() into its own API
+    - FROMLIST: drm/msm/dp: introduce stream_id for each DP panel
+    - FROMLIST: drm/msm/dp: convert dp_display_set_mode() to use dp_panel argument
+    - FROMLIST: drm/msm/dp: add support for programming p1 register block
+    - FROMLIST: drm/msm/dp: use stream_id to change offsets in dp_catalog
+    - FROMLIST: drm/msm/dp: add support to send ACT packets for MST
+    - FROMLIST: drm/msm/dp: add support to program mst support in mainlink
+    - FROMLIST: drm/msm/dp: no need to update tu calculation for mst
+    - FROMLIST: drm/msm/dp: add support for mst channel slot allocation
+    - FROMLIST: drm/msm/dp: add support to send vcpf packets in dp controller
+    - FROMLIST: drm/msm/dp: always program MST_FIFO_CONSTANT_FILL for MST
+    - FROMLIST: drm/msm/dp: abstract out the dp_display stream helpers to accept a
+      panel
+    - FROMLIST: drm/msm/dp: move link related operations to dp_display_unprepare()
+    - FROMLIST: drm/msm/dp: replace power_on with active_stream_cnt for dp_display
+    - FROMLIST: drm/msm/dp: make the SST bridge disconnected when
+    - PENDING: drm/msm/dp: make the mst disable call separate
+    - FROMLIST: drm/msm/dp: add an API to initialize MST on sink side
+    - FROMLIST: drm/msm/dp: skip reading the EDID for MST cases
+    - FROMLIST: drm/msm/dp: add dp_display_get_panel() to initialize DP panel
+    - FROMLIST: drm/msm/dp: add dp_mst_drm to manage DP MST bridge operations
+    - FROMLIST: drm/msm/dp: add connector abstraction for DP MST
+    - FROMLIST: drm/msm/dp: add irq hpd callback for dp mst
+    - PENDING: drm/msm/dp: use the max_streams from dp catalog
+    - FROMLIST: drm/msm/dp: add support to re-use and clear the panel edid
+    - FROMLIST: drm/msm/dp: add a mst session mutex to protect bridge ops
+    - FROMLIST: drm/msm/dp: propagate hpd state changes to dp mst module
+    - PENDING: drm/msm/dp: make the changes for hpd to work
+    - FROMLIST: drm/msm: add support for non-blocking commits
+    - FROMLIST: drm/msm: initialize DRM MST encoders for DP controllers
+    - FROMLIST: drm/msm/dp: initialize dp_mst module for each DP MST controller
+    - FROMLIST: drm/msm: add a stream to intf map for DP controller
+    - FROMLIST: drm/msm/dpu: use msm_dp_get_mst_intf_id() to get the intf id
+    - FROMLIST: drm/msm/dp: populate the max_streams for sa8775 mst controller
+    - PENDING: drm/msm/dpu: make max h_display split to 2560 to allow 4 streams
+    - PENDING: drm/msm/dp: populate the max streams for DP1
+    - FROMLIST: drm: allow encoder mode_set even when connectors change for crtc
+    - PENDING: drm/msm/dp: fix up the hpd state machine for mst cases
+    - PENDING: drm/msm/dp: use stream id for streams clk on
+    - PENDING: drm/msm/dp: populate the max_streams for qcs8300
+    - FROMLIST: arm64/dts/qcom: add mst support for stream 0 clk
+    - FROMLIST: irqchip: gic-v3: Handle failure case of CPU enters low power state
+    - PENDING: arm64: dts: qcom: qcs8300: Fix quirks being added to usb node
+    - QCLINUX: arm64: dts: qcom: remove unused tlmm gpio entry
+    - FROMLIST: Revert "PENDING: Bluetooth: hci_sync: Fix disconnect
+    - PENDING: arm64: dts: qcom: Add L3 interconnect device for QCS8300
+    - PENDING: arm64: dts: qcom: Add static vote for QCS8300
+    - QCLINUX: arm64: defconfig: Enable additional debug configs for gen5auto
+    - QCLINUX: arm64: dts: qcom: Add reserved regions
+    - PENDING: arm64: dts: qcom: qcs8300: Add support to scale DDR/L3
+    - PENDING: arm64: dts: qcom: qcs8300: Add LMH interrupts for cpufreq_hw node
+    - PENDING: clk: qcom: gdsc: Increase the GDSC status poll timeout
+    - QCLINUX: firmware: shmbridge/tzmem: Improve error reporting
+    - QCLINUX: ASoC: qcom: qdsp6: Increase the timeout to 5 secs
+    - PENDING: net: stmmac: enable SGMII loopback for DMA reset
+    - QCLINUX: arm64: dts: qcom: Add addons support for QCS615 RIDE
+    - QCLINUX: arm64: dts: qcom: Add board-id and msm-id for QCS615
+    - QCLINUX: arm64: deconfig: enable clock controller, interconnect and pinctrl
+      for QCS615
+    - BACKPORT: FROMGIT: clk: qcom: rpmhcc: Add support for QCS615 Clocks
+    - BACKPORT: FROMGIT: clk: qcom: gcc: Add support for QCS615 GCC clocks
+    - FROMLIST: pinctrl: qcom: correct the ngpios entry for QCS615
+    - PENDING: net: stmmac: Support 10GBaseR iomacro configuration
+    - QCLINUX: arm64: defconfig: enable carveout heaps
+    - FROMLIST: misc: fastrpc: Fix race condition in MUNMAP
+    - PENDING: net: PCS: Add 10GBaseR support in XPCS driver
+    - PENDING: arm64: dts: qcom: qcs9075: Update memory map for qcs9075
+    - Ubuntu: [Config] update CONFIG options for Yocto GA 1.3.1
+    - drm/i915: convert remaining intel_dp_vsc_sdp_pack
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 03 Feb 2025 17:53:58 +0900
+
+linux-qcom (6.8.0-1019.19) jammy; urgency=medium
+
+  * jammy/linux-qcom: 6.8.0-1019.19 -proposed tracker (LP: #2095417)
+
+  * "[RB3] tc956x_pci-eth errors found in dmesg"
+    - SAUCE: ubuntu/qcom/qps615: suppress false alerts
+    - SAUCE: ubuntu/qcom/qps615: use INFO level for logging
+
+  * [RB3] drm sde error/ msm-dsi-error found in dmesg
+    - SAUCE: do not show error on EPROBE_DEFER
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: import external DT from GA 1.3
+    - SAUCE: Add Makefile code to apply overlays for GA1.2
+    - SAUCE: ubuntu/qcom/display: import qcm6490 display code from GA1.3
+    - SAUCE: ubuntu/qcom/graphics: import qcm6490 graphics driver code from GA1.3
+    - SAUCE: ubuntu/qcom/camera: import qcm6490 camera driver code from GA1.3
+    - SAUCE: ubuntu/qcom/qps615: import ethernet driver from GA1.3
+    - SAUCE: ubuntu/qcom/video: import video driver from GA 1.3
+    - SAUCE: ubuntu/qcom: build external drivers
+    - SAUCE: ubuntu/qcom/camera: fix build warnings and errors
+    - SAUCE: suppress unneeded build logs
+    - SAUCE: ubuntu/qcom: suppress Wno-enum-int-mismatch warning
+    - SAUCE: ubuntu/qcom/graphics: change strtobool() to kstrtobool()
+    - SAUCE: ubuntu/qcom/graphics: dynamically allocate the kgsl-pool shrinker for
+      kernel>=6.7
+    - SAUCE: ubuntu/qcom/camera: remove unused camera_banner
+    - SAUCE: ubuntu/qcom/camera: use sizeof() instead of V4L2_SUBDEV_NAME_SIZE
+    - SAUCE: ubuntu/qcom/camera: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/video: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: auto-load module
+    - SAUCE: ubuntu/qcom: add missing inclusion
+    - SAUCE: ubuntu/qcom/display: Rename min_buffers_needed to min_queued_buffers
+    - SAUCE: ubuntu/qcom: remove DRM_UNLOCKED
+    - SAUCE: ubuntu/qcom/display: suppress EPROBE_DEFER error log
+    - SAUCE: Add Makefile code to apply qcs5430 overlays for GA1.2
+    - SAUCE: rename qcom,phy-rst-gpio to qcom,phy-rst-gpio-id
+    - SAUCE: comment out BUILD_TIMESTAMP
+    - SAUCE: add more DT to combined-dtb.dtb
+
+  * Miscellaneous upstream changes
+    - PENDING: usb: typec: ucsi_glink: Search current directory for headers
+    - PENDING: iommu/arm-smmu-qcom: Add SA8255p SMMUv2
+    - FROMLIST: usb: misc: qcom_eud: Access mode manager through secure calls
+    - FROMLIST: arm64: dts: qcom: sc7280: Update eud compatible string
+    - PENDING: arm64: dts: qcom: sa8775p: Add EUD dt node
+    - QCLINUX: arm64: dts: qcom: Add DT configuration
+    - PENDING: phy: qcom: Add support for eDP PHY on qcs8300
+    - UPSTREAM: wifi: ath11k: fix connection failure due to unexpected peer delete
+    - PENDING: arm64: dts: qcom: sa8775p-ride: Enable gpi-dma and qup node
+    - FROMLIST: wifi: ath11k: enable fw_wmi_diag_event hw param for WCN6750
+    - PENDING: Bluetooth: mgmt: Verify cmd pending status before removing it
+    - QCLINUX: firmware: qcom_scm: Add new scm to update Camera QoS
+    - QCLINUX: arm64: defconfig: Enable usb5807 driver
+    - QCLINUX: arm64: defconfigs: Add configs for Auto targets
+    - PENDING: drm/msm/dpu: Add QCS8300 support
+    - PENDING: arm64: dts: qcom: qcs8300: Add CDSP and ADSP fastrpc nodes
+    - PENDING: net: stmmac: Add the missing programming sequence for Split header
+      feature
+    - QCLINUX: firmware: qcom_scm_addon: Fix qcom_she_op missing arginfo and res
+    - UPSTREAM: arm64: mm: Batch dsb and isb when populating pgtables
+    - UPSTREAM: arm64: mm: Don't remap pgtables for allocate vs populate
+    - PENDING: drm/msm/dp: Add DisplayPort controller for QCS8300
+    - PENDING: arm64: dts: qcom: sa8775p: Enable EUD function
+    - PENDING: arm64: dts: qcom: qcs8300: Add BWMON instances
+    - PENDING: Bluetooth: mgmt: Verify command pending status before removing it
+    - PENDING: pinctrl: qcom: Add qcs8300 lpass lpi pinctrl driver
+    - QCLINUX: ASoC: qcm6490: Add sound card support for QCS8300
+    - QCLINUX: qcom: qtee_shmbridge: Register dma bridge
+    - PENDING: drm/msm: mdss: Add QCS8300 support
+    - QCLINUX: arm64: deconfig: qcom: disable CONFIG_ARM_SCMI_CPUFREQ
+    - PENDING: net: phy: aquantia: Fix aquantia driver to support 2.5Gbps
+    - QCLINUX: arm64: defconfig: Enable LPASS LPI QCS8300 pinctrl
+    - PENDING: arm64: dts: qcom: Add on-board PMICs for qcs8300
+    - PENDING: arm64: dts: qcom: Add PMIC GPIO devices for qcs8300
+    - PENDING: arm64: dts: qcom: Add PMIC RTC device for qcs8300
+    - PENDING: arm64: dts: qcom: qcs8300-ride: Add Bluetooth support
+    - PENDING: arm64: dts: qcom: sa8775p: Enable high bandwidth for hs isoc eps
+    - PENDING: arm64: dts: qcom: sa8255p-ride: Disable USB wakeup capability
+    - PENDING: usb: dwc3: Update nominal max votes for qcom usb
+    - PENDING: tty: serial: qcom-geni-serial: Increase Rx buffer size
+    - PENDING: arm64: dts: qcom: qcs8300: add display dt nodes
+    - QCLINUX: ARM64: configs: Remove Gunyah in-tree drivers
+    - PENDING: arm64: dts: qcom: qcs8300: Add gpr device tree node for ADSP
+    - QCLINUX: arm64: dts: qcom: qcs8300: Add lpass_tlmm node for lpi pinctrl
+    - QCLINUX: arm64: dts: qcom: qcs8300: Add sound node for qcs8300 ridesx target
+    - PENDING: arm64: dts: qcom: qcs8300: Add DisplayPort device node
+    - PENDING: usb: dwc3: Reserve Higher Bandwidth for HS Periodic EPs
+    - QCLINUX: arm64: defconfig: Add configs for Gen5auto targets
+    - QCLINUX: soc: qcom: Fix showing watchdog device attr "disable"
+    - PENDING: QCLINUX: arm64: PCI: qcom: Add support for QCS8300 SoC
+    - QCLINUX: secure-buffer: Minor cleanup
+    - PENDING: phy: qcom-qmp-pcie: add dual lane PHY support for QCS8300
+    - PENDING: pinctrl: qcom: add tlmm driver for sa7255p platform
+    - QCLINUX: arm64: defconfigs: Enable SA7255P Pinctrl
+    - PENDING: ARM64: dts: qcom: Update camera PIL memory to 7MB
+    - PENDING: arm64: dts: qcom: Add dcvsh interrupts
+    - QCLINUX: arm64: dts: qcom: addons: Add TGU components
+    - PENDING: arm64: dts: qcom: Add lpass_stm device
+    - PENDING: arm64: dts: qcom: qcs8300: Add EUD dt node
+    - QCLINUX: arm64: configs: Disable the console for perf build
+    - PENDING: arm64: dts: qcom: qcs8300: enable pcie0 for QCS8300
+    - PENDING: arm64: dts: qcom: qcs8300: Correct IRQ number of EL2 non-secure
+      physical timer
+    - PENDING: QCLINUX: arm64: dts: add pmu node for WCN6855
+    - PENDING: arm64: dts: qcom: qcs8300: add Watchdog
+    - QCLINUX: dcc: Configure the correct bit for MEM_MAP_VER3
+    - QCLINUX: arm64: defconfig: Enable EFI runtime service
+    - QCLINUX: rpmsg: glink: Get reference of channel objects in rx path
+    - PENDING: arm64: dts: qcom: Add support for SA7255p Ride platform
+    - PENDING: arm64: dts: qcom: sa7255p: Add UFS node
+    - PENDING: arm64: dts: qcom: sa7255p: Add USB nodes
+    - QCLINUX: arm64: dts: qcom: Add/Modify board-id and msm-id for V1,v2 and V3
+    - PENDING: arm64: dts: qcom: add the PCIE SMMU node
+    - PENDING: arm64: dts: qcom: Add nodes for Data Capture and Compare
+    - QCLINUX: secure-buffer: Roll-back failed assigns
+    - QCLINUX: dma-heap: qcom: Reclaim pages we failed to hyp-assign
+    - QCLINUX: arm64: dts: qcom: sa8775p: add ride r3 addons dts support
+    - QCLINUX: arm64: dts: qcom: qcs9100: add addons ride dts support
+    - PENDING: pinctrl: qcom: add pdc wakeup irq map for sa7255p
+    - PENDING: slimbus: messaging: Free transaction ID in delayed interrupt
+      scenario
+    - PENDING: clk: qcom: videocc-sa8775p: Increase mvs0c divider to div-3
+    - PENDING: arm64: dts: qcom: Add support for tsens and thermal for SA7255p
+    - PENDING: net: stmmac: dwmac-qcom-ethqos: Add ethernet support for sa8620
+    - PENDING: net: stmmac: Fix SPH feature to support AV packets
+    - PENDING: arm64: dts: qcom: sa8255p: Add PCIe nodes
+    - PENDING: arm64: dts: qcom: Add PCIe SMMU node for SA7255P
+    - QCLINUX: arm64: dts: qcom: addons: Correct the dcc version
+    - QCLINUX: Revert "PENDING: net: phy: aquantia: Fix aquantia driver to
+    - QCLINUX: arm64: dts: qcom: addons: add periphid for TGU
+    - PENDING: arm64: dts: qcom: Add the Adreno SMMU node for SA7255P
+    - QCLINUX: arm64: defconfig: Enable Intel IXGBE driver
+    - PENDING: dt-bindings: arm: qcom,ids: add SoC ID for SA7255P
+    - PENDING: soc: qcom: socinfo: add support for SA7255P SoC
+    - PENDING: arm64: dts: qcom: qcs8300: enable pcie1 for QCS8300
+    - PENDING: arm64: dts: qcom: add support for ipcc
+    - PENDING: arm64: dts: qcom: Add WDT device node for SA7255
+    - PENDING: arm64: dts: qcom: sa8775p: Enable DPTX1 on MDSS0 for SA8775P target
+    - PENDING: arm64: dts: qcom: sa8775p: Enable DPTX1 on MDSS0 for SA8775P target
+    - QCLINUX: arm64: deconfig: enable dm-verity configs
+    - QCLINUX: arm64: deconfig: qcom: disable SOC_DEBUG CONFIG
+    - QCLINUX: arm64: dts: qcom: qcs6490-addons-rb3gen2: Enable camera subsystem
+    - FROMLIST: arm64: dts: qcom: Disable TPDM_GCC for QCS8300
+    - QCLINUX: arm64: defconfig: Enable Aquantia Phy
+    - PENDING: arm64: dts: qcom: sc7280: Update camss driver properties
+    - QCLINUX: usb: dwc3: qcom: Add shutdown callback for qcom wrapper
+    - QCLINUX: drivers: thermal: Add dummy set hysteresis operation for all
+      sensors
+    - PENDING: arm64: dts: qcom: sa7255p: Enable i2c15 for audio
+    - QCLINUX: arm64: deconfig: qcom: enable IOMMU_DEFAULT_DMA_LAZY
+    - PENDING: arm64: dts: qcom: qcs8300: update videocc compatible
+    - PENDING: arm64: dts: qcom: qcs8300: add rdbg nodes
+    - PENDING: arm64: dts: qcom: qcs8300: add TRNG node
+    - QCLINUX: arm64: dts: qcom: Add msm-id/board-id for SA7255P
+    - PENDING: arm64: dts: qcom: sa8775p: Define interconnect bandwidth value in
+      dtsi
+    - PENDING: arm64: qcom: dts: Add psci sys_reset2 modes for SA8255P & SA7255P
+    - PENDING: Bluetooth: Increase settling time for baudrate change VSC
+    - QCLINUX: arm64: dts: qcom: Enable TPM device
+    - PENDING: arm64: dts: qcom: qcs8300: add ICE node
+    - BACKPORT: Bluetooth: MGMT: Fix possible crash on mgmt_index_removed
+    - QCLINUX: arm64: dts: qcom: qcs6490-rb3gen2: Move the msm-id and board-id
+    - QCLINUX: arm64: defconfigs: Add configs for Auto targets
+    - FROMLIST: wifi: ath11k: Fix unexpected return buffer manager error for
+      WCN6750/WCN6855
+    - PENDING: soc: qcom: qup_fw: QUP SE Firmware load from Linux
+    - FROMLIST: arm64: dts: qcom: qcs8300: Add PMU support for QCS8300
+    - BACKPORT: FROMLIST: io_uring: Do not set iowait before sleeping
+    - PENDING: dt-bindings: arm: qcom,ids: add SoC ID for SA8797P
+    - PENDING: soc: qcom: socinfo: add support for SA8797P SoC
+    - PENDING: arm64: dts: qcom: qcs8300: Add tz-log node
+    - QCLINUX: arm64: dts: qcom: qcs8300: add dcodec and macro clk
+    - QCLINUX: ASoC: qcm6490: Add AIF3 and AIF4 for qcs8300
+    - PENDING: arm64: dts: qcom: qcs8300: Add spi dev node for qcs8300 ridesx
+      target
+    - PENDING: arm64: dts: qcom: qcs8300: Enable i2c15 node for qcs8300 ridesx
+      target
+    - QCLINUX: arm64: dts: qcom: qcs8300: Enable HS MI2S
+    - PENDING: arm64: dts: qcom: qcs8300: Add shmbridge and smcinvoke nodes
+    - PENDING: arm64: dts: qcom: qcs8300-addons: Add CMA heap
+    - PENDING: drivers: char: fix rdbg driver init sequence
+    - PENDING: arm64: dts: qcom: qcs8300: add QCrypto nodes
+    - QCLINUX: arm64: dts: qcom: addons: Enable mem-buf and secure-buffer for
+      qcs8300
+    - PENDING: clk: qcom: common: Add support to attach multiple power domains
+    - PENDING: clk: qcom: gdsc: Add support to link multiple PDs as GDSC parents
+    - PENDING: clk: qcom: camcc-sa8775p: Add support to attach multiple pds
+    - PENDING: arm64: dts: qcom: Add MXC power domain to camcc node on SA8775P
+    - PENDING: arm64: qcom: dts: qcs8300: Add psci sys_reset2 modes
+    - FROMLIST: dt-bindings: arm: qcom,ids: add SoC ID for QCS9075
+    - FROMLIST: soc: qcom: socinfo: add QCS9075 SoC ID
+    - FROMLIST: arm64: dts: qcom: Add support for QCS9075 RB8
+    - FROMLIST: arm64: dts: qcom: Add support for QCS9075 Ride & Ride-r3
+    - QCLINUX: arm64: dts: qcom: Add msm-id & board-id for qcs9075-rb8
+    - QCLINUX: arm64: dts: qcom: qcs9075: Add msm-id & board-id for ride/ride-r3
+    - PENDING: ARM: dts: qcom: Add ADC thermistor support for SA8775P
+    - PENDING: arm64: dts: qcom: qcs8300: Add adsp memory-region and vmids
+    - PENDING: arm64: dts: qcom: qcs9075-rb8: Add support for remoteproc instances
+    - PENDING: arm64: dts: qcom: qcs9075-rb8: Enable llcc node
+    - FROMLIST: net: stmmac: Add snps_id, dev_id to struct plat_stmmacenet_data
+    - FROMLIST: net: stmmac: Integrate dw25gmac into stmmac hwif handling
+    - QCLINUX:arm64:defconfigs: Enable NO_HZ_FULL for better rcu performance
+    - PENDING: serial: qcom-geni: Support of uart firmware load from Linux
+    - PENDING: spi: geni-qcom: Load spi Firmware from driver probe
+    - PENDING: i2c: qcom-geni: Load i2c Firmware from driver probe
+    - PENDING: arm64: dts: qcom: Disable USB U1/U2 entry for QCS9100/QCS8300
+    - FROMLIST: net: stmmac: Add basic dw25gmac support in stmmac core
+    - QCLINUX: arm64: dts: qcom: qcs9100: Enable DISPLAY-PORT
+    - PENDING: misc: fastrpc: Add support for invoke v2
+    - PENDING: wifi: ath11k: fix wrong overriding for VHT Beamformee STS
+      Capability
+    - QCLINUX: arm64: dts: qcom: Add QPS615 and PHY devicetree config for RC0 for
+      RB3Gen2 ia-mezz
+    - QCLINUX: arm64: dts: qcom: Add support for Eth0 and Eth1 on QPS615 for
+      RB3Gen2 ia-mezz
+    - QCLINUX: arm64: dts: qcom: Add QPS615 and PHY devicestree config for RC1 for
+      RB3gen2 IPC board
+    - QCLINUX: arm64: dts: qcom: Add QPS615 Ethernet support for RC1 for RB3gen2
+      IPC board
+    - PENDING: ARM: dts: qcom: Add support for PMIC peripherals for qcs8300
+    - PENDING: arm64: dts: qcom: sa8775p: Add dma heap for cdsp_secure_heap_mem
+    - PENDING: spi: spi-geni-qcom: Add immediate DMA support
+    - PENDING: arm64: dts: qcom: qcs8300: Add dma heap for cdsp_secure_heap_mem
+    - QCLINUX: ASoC: qcs9100: add HDMI/DP Jack
+    - QCLINUX: arm64: dts: qcom: qcs6490-rb3gen2: disable camss driver
+    - PENDING: net: stmmac: pass stmmac_priv in some callbacks
+    - FROMLIST: arm64: dts: qcom: sa8775p: Update iommu-map entry
+    - PENDING: Bluetooth: clear cmd_sync_work_list when power off
+    - QCLINUX: dma-heap: qcom: Snapshot of dma-buf-carveout-heap
+    - PENDING: clk: qcom: Add support for qdss_xo clock for QCS8300
+    - PENDING: arm64: dts: qcom: Fix dr_mode for secondary port
+    - PENDING: arm64: qcs9075-rb8: Enable PCIe0 & PCIe1 nodes
+    - BACKPORT: PCI: Add ACS quirk for Qualcomm SA8775P
+    - PENDING: Bluetooth: hci_sync: Fix disconnect complete event timeout issue
+    - PENDING: arm64: dts: qcom: qcs8300: Delete duplicate cdsp fastrpc nodes
+    - BACKPORT: PCI: qcom-ep: Add HDMA support for SA8775P SoC
+    - QCLINUX: arm64: defconfigs: convert usb configs to module
+    - PENDING: arm64: dts: qcom: sa8775p: Define interconnect bandwidth value in
+      dtsi
+    - PENDING: arm64: dts: qcom: Enable cpu idle injection for cpu tsens for
+      qcs9100
+    - PENDING: pinctrl: sa8775p: Enable egpio function for pingroups
+    - PENDING: arm64: dts: qcom: Memory map for qcs8300 v1 approved
+    - PENDING: arm-smmu-qcom: program actlr earlier in init to include GPU and GMU
+    - QCLINUX: arm64: defconfig: qcom: Enable EMC2305 Sensor driver
+    - QCLINUX: arm64: dts: qcom: qcs9075: Add support for rb8 addons
+    - QCLINUX: arm64: dts: qcom: qcs9075: Add support for ride/ride-r3 addons
+    - PENDING: arm64: dts: qcom: Add wlan support for qcs9075-rb8
+    - PENDING: arm64: qcs9075-rb8: Config BT bootstrap pin in DTS
+    - FROMLIST: qcom: llcc/edac: Correct interrupt enable register configuration
+    - PENDING: arm64: dts: qcom: Enable cpu idle injection for cpu tsens for
+      qcs9075
+    - QCLINUX: arm64: dts: qcom: Fix dr_mode for non-primary ports
+    - QCLINUX: arm64: dts: qcom: qcs6490-rb3gen2: disable camss driver
+    - BACKPORT: PCI: epf-mhi: Add "pci_epf_mhi_" prefix to the function names
+    - QCLINUX: rpmsg: Align channel objects reference in rx path
+    - QCLINUX: arm64: dts: qcom: qcs6490-addons-rb3gen2: Enable camera subsystem"
+    - PENDING: qcom: ice: Remove ice probe
+    - PENDING: arm64: dts: qcom: qcs9100-rb8: QUP Firmware load from Linux
+    - QCLINUX: arm64: dts: qcom: Enable usb controller on QCS9075 RB8
+    - QCLINUX: arm64: dts: qcom: qcs9075: Add UFS support for QCS9075 RB8
+    - PENDING: arm64: dts: qcom: qcs9075: Add displayport device node
+    - QCLINUX: arm64: dts: qcom: add audio support for qcs9075-rb8
+    - QCLINUX: ASoC: qcm6490: Add support for QCS9075 RB8
+    - QCLINUX: clk: qcom: videocc-sa8775: disable HW CTRL for video GDSC
+    - PENDING: arm64: dts: qcom: update power-domain for display-controller
+    - PENDING: hwmon: Add I2C detection and initialization for EMC2303
+    - BACKPORT: FROMLIST: arm64: dts: qcom: qcs9100: Update memory map  for
+      QCS9100 Ride and QCS9100 Ride Rev3
+    - FROMLIST: usb: misc: usb5807: Add driver
+    - PENDING: USB: Adapt USB5807 driver for IPC hardware design
+    - PENDING: wifi: ath11k: add support for MU EDCA
+    - PENDING: ARM: dts: qcom: Update thermal zone names for qcs8300
+    - PENDING: pinctrl: qcs8300: Update function and group binding
+    - QCLINUX: drm/msm: Avoid probing gpu device
+    - QCLINUX: arm64: dts: qcom: qcs6490-rb3gen2: enable camera sensor
+    - PENDING: arm64: dts: qcom: qcs8300: Add capacity and DPC properties
+    - Revert: ICE eMMC and probe
+    - QCLINUX: arm64: defconfig: Enable GPUCC SA8775P driver as static module
+    - Ubuntu: [Config] update CONFIG options for GA 1.3
+    - Ubuntu: [Config] change CONFIG_USB_DWC3 to y
+    - Ubuntu: [Config] change CONFIG_SENSORS_EMC2305 to y
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 22 Jan 2025 07:54:04 +0900
+
+linux-qcom (6.8.0-1018.18) jammy; urgency=medium
+
+  * "[Canonical][RB3] [ftmdaemon] WlanSetPhyRFMode fail by ftmdaemon tool"
+    - [Config] Enable CONFIG_NL80211_TESTMODE
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 19 Dec 2024 21:02:17 +0900
+
+linux-qcom (6.8.0-1017.17) jammy; urgency=medium
+
+  * Miscellaneous upstream changes
+    - scsi: ufs: qcom: revive the enabled check in ufs_qcom_host_clk_get()
+    - Revert "usb: typec: fsa4480: Relax CHIP_ID check"
+    - Revert "usb: typec: fsa4480: Check if the chip is really there"
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Tue, 17 Dec 2024 04:05:48 +0900
+
+linux-qcom (6.8.0-1016.16) jammy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Add Makefile code to apply qcs5430 overlays for GA1.2
+
+  * Miscellaneous upstream changes
+    - msm: camera: isp: Fix warnings
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Tue, 10 Dec 2024 15:45:41 +0900
+
+linux-qcom (6.8.0-1015.15) jammy; urgency=medium
+
+  * Noble update: upstream stable patchset 2024-10-02 (LP: #2083488)
+    - [Config] Update CONFIG_SCREEN_INFO
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+
+  * [RB3] CONFIG_KASAN_GENERIC report potential memory bug in tc956x_pcie_eth
+    - SAUCE: ubuntu/qcom/qps615: suppress KASAN error
+
+  * Miscellaneous Ubuntu changes
+    - [Config] set CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND
+
+  [ Ubuntu: 6.8.0-50.51 ]
+
+  * noble/linux: 6.8.0-50.51 -proposed tracker (LP: #2086301)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2024.10.28)
+  * Noble update: upstream stable patchset 2024-10-31 (LP: #2086138)
+    - device property: Add cleanup.h based fwnode_handle_put() scope based
+      cleanup.
+    - device property: Introduce device_for_each_child_node_scoped()
+    - iio: adc: ad7124: Switch from of specific to fwnode based property handling
+    - ksmbd: override fsids for share path check
+    - ksmbd: override fsids for smb2_query_info()
+    - usbnet: ipheth: remove extraneous rx URB length check
+    - usbnet: ipheth: drop RX URBs with no payload
+    - usbnet: ipheth: do not stop RX on failing RX callback
+    - usbnet: ipheth: fix carrier detection in modes 1 and 4
+    - net: ethernet: use ip_hdrlen() instead of bit shift
+    - drm: panel-orientation-quirks: Add quirk for Ayn Loki Zero
+    - drm: panel-orientation-quirks: Add quirk for Ayn Loki Max
+    - net: phy: vitesse: repair vsc73xx autonegotiation
+    - powerpc/mm: Fix boot warning with hugepages and CONFIG_DEBUG_VIRTUAL
+    - wifi: mt76: mt7921: fix NULL pointer access in mt7921_ipv6_addr_change
+    - net: hns3: use correct release function during uninitialization
+    - btrfs: update target inode's ctime on unlink
+    - Input: ads7846 - ratelimit the spi_sync error message
+    - Input: synaptics - enable SMBus for HP Elitebook 840 G2
+    - HID: multitouch: Add support for GT7868Q
+    - scripts: kconfig: merge_config: config files: add a trailing newline
+    - platform/surface: aggregator_registry: Add Support for Surface Pro 10
+    - platform/surface: aggregator_registry: Add support for Surface Laptop Go 3
+    - drm/msm/adreno: Fix error return if missing firmware-name
+    - Input: i8042 - add Fujitsu Lifebook E756 to i8042 quirk table
+    - smb/server: fix return value of smb2_open()
+    - NFSv4: Fix clearing of layout segments in layoutreturn
+    - NFS: Avoid unnecessary rescanning of the per-server delegation list
+    - platform/x86: panasonic-laptop: Fix SINF array out of bounds accesses
+    - platform/x86: panasonic-laptop: Allocate 1 entry extra in the sinf array
+    - mptcp: pm: Fix uaf in __timer_delete_sync
+    - arm64: dts: rockchip: fix eMMC/SPI corruption when audio has been used on
+      RK3399 Puma
+    - arm64: dts: rockchip: override BIOS_DISABLE signal via GPIO hog on RK3399
+      Puma
+    - minmax: reduce min/max macro expansion in atomisp driver
+    - net: tighten bad gso csum offset check in virtio_net_hdr
+    - dm-integrity: fix a race condition when accessing recalc_sector
+    - x86/hyperv: fix kexec crash due to VP assist page corruption
+    - mm: avoid leaving partial pfn mappings around in error case
+    - arm64: dts: rockchip: fix PMIC interrupt pin in pinctrl for ROCK Pi E
+    - drm/amd/display: Disable error correction if it's not supported
+    - drm/amd/display: Fix FEC_READY write on DP LT
+    - eeprom: digsy_mtc: Fix 93xx46 driver probe failure
+    - cxl/core: Fix incorrect vendor debug UUID define
+    - selftests/bpf: Support SOCK_STREAM in unix_inet_redir_to_connected()
+    - hwmon: (pmbus) Conditionally clear individual status bits for pmbus rev >=
+      1.2
+    - ice: Fix lldp packets dropping after changing the number of channels
+    - ice: fix accounting for filters shared by multiple VSIs
+    - ice: fix VSI lists confusion when adding VLANs
+    - igb: Always call igb_xdp_ring_update_tail() under Tx lock
+    - net/mlx5: Update the list of the PCI supported devices
+    - net/mlx5e: Add missing link modes to ptys2ethtool_map
+    - net/mlx5e: Add missing link mode to ptys2ext_ethtool_map
+    - net/mlx5: Explicitly set scheduling element and TSAR type
+    - net/mlx5: Add missing masks and QoS bit masks for scheduling elements
+    - net/mlx5: Correct TASR typo into TSAR
+    - net/mlx5: Verify support for scheduling element and TSAR type
+    - net/mlx5: Fix bridge mode operations when there are no VFs
+    - fou: fix initialization of grc
+    - octeontx2-af: Modify SMQ flush sequence to drop packets
+    - net: ftgmac100: Enable TX interrupt to avoid TX timeout
+    - selftests: net: csum: Fix checksums for packets with non-zero padding
+    - netfilter: nft_socket: fix sk refcount leaks
+    - net: dsa: felix: ignore pending status of TAS module when it's disabled
+    - net: dpaa: Pad packets to ETH_ZLEN
+    - tracing/osnoise: Fix build when timerlat is not enabled
+    - spi: nxp-fspi: fix the KASAN report out-of-bounds bug
+    - drm/syncobj: Fix syncobj leak in drm_syncobj_eventfd_ioctl
+    - dma-buf: heaps: Fix off-by-one in CMA heap fault handler
+    - drm/nouveau/fb: restore init() for ramgp102
+    - drm/amdgpu/atomfirmware: Silence UBSAN warning
+    - drm/amd/amdgpu: apply command submission parser for JPEG v1
+    - spi: geni-qcom: Undo runtime PM changes at driver exit time
+    - spi: geni-qcom: Fix incorrect free_irq() sequence
+    - drm/i915/guc: prevent a possible int overflow in wq offsets
+    - ASoC: codecs: avoid possible garbage value in peb2466_reg_read()
+    - cifs: Fix signature miscalculation
+    - pinctrl: meteorlake: Add Arrow Lake-H/U ACPI ID
+    - ASoC: meson: axg-card: fix 'use-after-free'
+    - drm/mediatek: Set sensible cursor width/height values to fix crash
+    - Input: edt-ft5x06 - add support for FocalTech FT5452 and FT8719
+    - Input: edt-ft5x06 - add support for FocalTech FT8201
+    - cgroup/cpuset: Eliminate unncessary sched domains rebuilds in hotplug
+    - spi: zynqmp-gqspi: Scale timeout by data size
+    - drm/xe: use devm instead of drmm for managed bo
+    - net: libwx: fix number of Rx and Tx descriptors
+    - clocksource: hyper-v: Use lapic timer in a TDX VM without paravisor
+    - bcachefs: Fix bch2_extents_match() false positive
+    - bcachefs: Don't delete open files in online fsck
+    - firmware: qcom: uefisecapp: Fix deadlock in qcuefi_acquire()
+    - riscv: dts: starfive: jh7110-common: Fix lower rate of CPUfreq by setting
+      PLL0 rate to 1.5GHz
+    - cxl: Restore XOR'd position bits during address translation
+    - netlink: specs: mptcp: fix port endianness
+    - drm/amd/display: Avoid race between dcn10_set_drr() and dc_state_destruct()
+    - drm/amd/display: Avoid race between dcn35_set_drr() and dc_state_destruct()
+    - drm/amd/amdgpu: apply command submission parser for JPEG v2+
+    - drm/xe/client: fix deadlock in show_meminfo()
+    - drm/xe/client: remove bogus rcu list usage
+    - drm/xe/client: add missing bo locking in show_meminfo()
+    - tracing/kprobes: Fix build error when find_module() is not available
+    - drm/xe/display: fix compat IS_DISPLAY_STEP() range end
+    - Upstream stable to v6.6.52, v6.10.11
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849)
+    - KVM: SVM: fix emulation of msr reads/writes of MSR_FS_BASE and MSR_GS_BASE
+    - KVM: SVM: Don't advertise Bus Lock Detect to guest if SVM support is missing
+    - ALSA: hda/conexant: Add pincfg quirk to enable top speakers on Sirius
+      devices
+    - ALSA: hda/realtek: add patch for internal mic in Lenovo V145
+    - ALSA: hda/realtek: Support mute LED on HP Laptop 14-dq2xxx
+    - ksmbd: Unlock on in ksmbd_tcp_set_interfaces()
+    - ata: libata: Fix memory leak for error path in ata_host_alloc()
+    - irqchip/gic-v2m: Fix refcount leak in gicv2m_of_init()
+    - x86/kaslr: Expose and use the end of the physical memory address space
+    - nvme-pci: Add sleep quirk for Samsung 990 Evo
+    - rust: types: Make Opaque::get const
+    - rust: macros: provide correct provenance when constructing THIS_MODULE
+    - Revert "Bluetooth: MGMT/SMP: Fix address type when using SMP over BREDR/LE"
+    - Bluetooth: MGMT: Ignore keys being loaded with invalid type
+    - mmc: core: apply SD quirks earlier during probe
+    - mmc: dw_mmc: Fix IDMAC operation with pages bigger than 4K
+    - mmc: sdhci-of-aspeed: fix module autoloading
+    - mmc: cqhci: Fix checking of CQHCI_HALT state
+    - fuse: update stats for pages in dropped aux writeback list
+    - fuse: use unsigned type for getxattr/listxattr size truncation
+    - fuse: fix memory leak in fuse_create_open
+    - clk: starfive: jh7110-sys: Add notifier for PLL0 clock
+    - clk: qcom: clk-alpha-pll: Fix the pll post div mask
+    - clk: qcom: clk-alpha-pll: Fix the trion pll postdiv set rate API
+    - kexec_file: fix elfcorehdr digest exclusion when CONFIG_CRASH_HOTPLUG=y
+    - tracing: Avoid possible softlockup in tracing_iter_reset()
+    - tracing/timerlat: Add interface_lock around clearing of kthread in
+      stop_kthread()
+    - net: mctp-serial: Fix missing escapes on transmit
+    - x86/fpu: Avoid writing LBR bit to IA32_XSS unless supported
+    - x86/apic: Make x2apic_disable() work correctly
+    - drm/i915: Do not attempt to load the GSC multiple times
+    - ALSA: control: Apply sanity check of input values for user elements
+    - ALSA: hda: Add input value sanity checks to HDMI channel map controls
+    - wifi: ath12k: fix uninitialize symbol error on ath12k_peer_assoc_h_he()
+    - smack: unix sockets: fix accept()ed socket label
+    - bpf, verifier: Correct tail_call_reachable for bpf prog
+    - accel/habanalabs/gaudi2: unsecure edma max outstanding register
+    - irqchip/armada-370-xp: Do not allow mapping IRQ 0 and 1
+    - af_unix: Remove put_pid()/put_cred() in copy_peercred().
+    - x86/kmsan: Fix hook for unaligned accesses
+    - iommu: sun50i: clear bypass register
+    - netfilter: nf_conncount: fix wrong variable type
+    - fs/ntfs3: One more reason to mark inode bad
+    - riscv: kprobes: Use patch_text_nosync() for insn slots
+    - media: vivid: fix wrong sizeimage value for mplane
+    - leds: spi-byte: Call of_node_put() on error path
+    - wifi: brcmsmac: advertise MFP_CAPABLE to enable WPA3
+    - usb: uas: set host status byte on data completion error
+    - drm/amd/display: Check HDCP returned status
+    - drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts
+    - media: vivid: don't set HDMI TX controls if there are no HDMI outputs
+    - vfio/spapr: Always clear TCEs before unsetting the window
+    - ice: Check all ice_vsi_rebuild() errors in function
+    - Input: ili210x - use kvmalloc() to allocate buffer for firmware update
+    - media: qcom: camss: Add check for v4l2_fwnode_endpoint_parse
+    - pcmcia: Use resource_size function on resource object
+    - drm/amdgpu: check for LINEAR_ALIGNED correctly in check_tiling_flags_gfx6
+    - can: m_can: Release irq on error in m_can_open
+    - can: mcp251xfd: fix ring configuration when switching from CAN-CC to CAN-FD
+      mode
+    - rust: kbuild: fix export of bss symbols
+    - cifs: Fix FALLOC_FL_ZERO_RANGE to preflush buffered part of target region
+    - igb: Fix not clearing TimeSync interrupts for 82580
+    - platform/x86: dell-smbios: Fix error path in dell_smbios_init()
+    - regulator: core: Stub devm_regulator_bulk_get_const() if !CONFIG_REGULATOR
+    - can: kvaser_pciefd: Skip redundant NULL pointer check in ISR
+    - can: kvaser_pciefd: Remove unnecessary comment
+    - can: kvaser_pciefd: Rename board_irq to pci_irq
+    - can: kvaser_pciefd: Move reset of DMA RX buffers to the end of the ISR
+    - can: kvaser_pciefd: Use a single write when releasing RX buffers
+    - Bluetooth: qca: If memdump doesn't work, re-enable IBS
+    - Bluetooth: hci_sync: Introduce hci_cmd_sync_run/hci_cmd_sync_run_once
+    - Bluetooth: MGMT: Fix not generating command complete for MGMT_OP_DISCONNECT
+    - igc: Unlock on error in igc_io_resume()
+    - ice: do not bring the VSI up, if it was down before the XDP setup
+    - usbnet: modern method to get random MAC
+    - bpf, net: Fix a potential race in do_sock_getsockopt()
+    - bareudp: Fix device stats updates.
+    - r8152: fix the firmware doesn't work
+    - net: bridge: br_fdb_external_learn_add(): always set EXT_LEARN
+    - net: dsa: vsc73xx: fix possible subblocks range of CAPT block
+    - selftests: net: enable bind tests
+    - firmware: cs_dsp: Don't allow writes to read-only controls
+    - phy: zynqmp: Take the phy mutex in xlate
+    - ASoC: topology: Properly initialize soc_enum values
+    - dm init: Handle minors larger than 255
+    - iommu/vt-d: Handle volatile descriptor status read
+    - cgroup: Protect css->cgroup write under css_set_lock
+    - devres: Initialize an uninitialized struct member
+    - virtio_ring: fix KMSAN error for premapped mode
+    - crypto: qat - fix unintentional re-enabling of error interrupts
+    - ASoc: TAS2781: replace beXX_to_cpup with get_unaligned_beXX for potentially
+      broken alignment
+    - libbpf: Add NULL checks to bpf_object__{prev_map,next_map}
+    - drm/amdgpu: Set no_hw_access when VF request full GPU fails
+    - ext4: fix possible tid_t sequence overflows
+    - jbd2: avoid mount failed when commit block is partial submitted
+    - dma-mapping: benchmark: Don't starve others when doing the test
+    - drm/amdgpu: reject gang submit on reserved VMIDs
+    - smp: Add missing destroy_work_on_stack() call in smp_call_on_cpu()
+    - fs/ntfs3: Check more cases when directory is corrupted
+    - btrfs: replace BUG_ON with ASSERT in walk_down_proc()
+    - cxl/region: Verify target positions using the ordered target list
+    - riscv: set trap vector earlier
+    - tcp: Don't drop SYN+ACK for simultaneous connect().
+    - net: dpaa: avoid on-stack arrays of NR_CPUS elements
+    - LoongArch: Use correct API to map cmdline in relocate_kernel()
+    - regmap: maple: work around gcc-14.1 false-positive warning
+    - vfs: Fix potential circular locking through setxattr() and removexattr()
+    - i3c: master: svc: resend target address when get NACK
+    - kselftests: dmabuf-heaps: Ensure the driver name is null-terminated
+    - btrfs: initialize location to fix -Wmaybe-uninitialized in
+      btrfs_lookup_dentry()
+    - s390/vmlinux.lds.S: Move ro_after_init section behind rodata section
+    - usbnet: ipheth: race between ipheth_close and error handling
+    - spi: spi-fsl-lpspi: limit PRESCALE bit in TCR register
+    - ata: pata_macio: Use WARN instead of BUG
+    - NFSv4: Add missing rescheduling points in
+      nfs_client_return_marked_delegations
+    - ACPI: CPPC: Add helper to get the highest performance value
+    - cpufreq: amd-pstate: Enable amd-pstate preferred core support
+    - cpufreq: amd-pstate: fix the highest frequency issue which limits
+      performance
+    - tcp: process the 3rd ACK with sk_socket for TFO/MPTCP
+    - iio: buffer-dmaengine: fix releasing dma channel on error
+    - iio: fix scale application in iio_convert_raw_to_processed_unlocked
+    - iio: adc: ad7124: fix config comparison
+    - iio: adc: ad7606: remove frstdata check for serial mode
+    - iio: adc: ad7124: fix chip ID mismatch
+    - usb: dwc3: core: update LC timer as per USB Spec V3.2
+    - usb: cdns2: Fix controller reset issue
+    - usb: dwc3: Avoid waking up gadget during startxfer
+    - nvmem: Fix return type of devm_nvmem_device_get() in kerneldoc
+    - Drivers: hv: vmbus: Fix rescind handling in uio_hv_generic
+    - clocksource/drivers/imx-tpm: Fix return -ETIME when delta exceeds INT_MAX
+    - clocksource/drivers/imx-tpm: Fix next event not taking effect sometime
+    - clocksource/drivers/timer-of: Remove percpu irq related code
+    - uprobes: Use kzalloc to allocate xol area
+    - Revert "mm: skip CMA pages when they are not available"
+    - workqueue: wq_watchdog_touch is always called with valid CPU
+    - workqueue: Improve scalability of workqueue watchdog touch
+    - ACPI: processor: Return an error if acpi_processor_get_info() fails in
+      processor_add()
+    - ACPI: processor: Fix memory leaks in error paths of processor_add()
+    - arm64: acpi: Move get_cpu_for_acpi_id() to a header
+    - can: mcp251xfd: mcp251xfd_handle_rxif_ring_uinc(): factor out in separate
+      function
+    - can: mcp251xfd: rx: prepare to workaround broken RX FIFO head index erratum
+    - can: mcp251xfd: clarify the meaning of timestamp
+    - can: mcp251xfd: rx: add workaround for erratum DS80000789E 6 of mcp2518fd
+    - drm/amd: Add gfx12 swizzle mode defs
+    - drm/amdgpu: handle gfx12 in amdgpu_display_verify_sizes
+    - ata: libata-scsi: Remove redundant sense_buffer memsets
+    - ata: libata-scsi: Check ATA_QCFLAG_RTF_FILLED before using result_tf
+    - crypto: starfive - Align rsa input data to 32-bit
+    - crypto: starfive - Fix nent assignment in rsa dec
+    - clk: qcom: ipq9574: Update the alpha PLL type for GPLLs
+    - powerpc/64e: remove unused IBM HTW code
+    - powerpc/64e: split out nohash Book3E 64-bit code
+    - powerpc/64e: Define mmu_pte_psize static
+    - powerpc/vdso: Don't discard rela sections
+    - ASoC: tegra: Fix CBB error during probe()
+    - nvme-pci: allocate tagset on reset if necessary
+    - ASoc: SOF: topology: Clear SOF link platform name upon unload
+    - ASoC: sunxi: sun4i-i2s: fix LRCLK polarity in i2s mode
+    - clk: qcom: gcc-sm8550: Don't use parking clk_ops for QUPs
+    - clk: qcom: gcc-sm8550: Don't park the USB RCG at registration time
+    - drm/i915/fence: Mark debug_fence_init_onstack() with __maybe_unused
+    - drm/i915/fence: Mark debug_fence_free() with __maybe_unused
+    - gpio: rockchip: fix OF node leak in probe()
+    - gpio: modepin: Enable module autoloading
+    - riscv: Fix toolchain vector detection
+    - riscv: Do not restrict memory size because of linear mapping on nommu
+    - membarrier: riscv: Add full memory barrier in switch_mm()
+    - [Config] updateconfigs for ARCH_HAS_MEMBARRIER_CALLBACKS
+    - x86/mm: Fix PTI for i386 some more
+    - btrfs: fix race between direct IO write and fsync when using same fd
+    - spi: spi-fsl-lpspi: Fix off-by-one in prescale max
+    - ALSA: hda/realtek: Enable Mute Led for HP Victus 15-fb1xxx
+    - ALSA: hda/realtek - Fix inactive headset mic jack for ASUS Vivobook 15
+      X1504VAP
+    - fuse: clear PG_uptodate when using a stolen page
+    - riscv: misaligned: remove CONFIG_RISCV_M_MODE specific code
+    - parisc: Delay write-protection until mark_rodata_ro() call
+    - pinctrl: qcom: x1e80100: Bypass PDC wakeup parent for now
+    - maple_tree: remove rcu_read_lock() from mt_validate()
+    - Revert "wifi: ath11k: restore country code during resume"
+    - btrfs: qgroup: don't use extent changeset when not needed
+    - btrfs: zoned: handle broken write pointer on zones
+    - drm/xe/gsc: Do not attempt to load the GSC multiple times
+    - drm/amdgpu: always allocate cleared VRAM for GEM allocations
+    - drm/amd/display: Lock DC and exit IPS when changing backlight
+    - ALSA: hda/realtek: extend quirks for Clevo V5[46]0
+    - cgroup/cpuset: Delay setting of CS_CPU_EXCLUSIVE until valid partition
+    - virt: sev-guest: Mark driver struct with __refdata to prevent section
+      mismatch
+    - media: b2c2: flexcop-usb: fix flexcop_usb_memory_req
+    - gve: Add adminq mutex lock
+    - wifi: rtw89: wow: prevent to send unexpected H2C during download Firmware
+    - drm/amdgpu: add missing error handling in function
+      amdgpu_gmc_flush_gpu_tlb_pasid
+    - crypto: qat - initialize user_input.lock for rate_limiting
+    - locking: Add rwsem_assert_held() and rwsem_assert_held_write()
+    - fs: don't copy to userspace under namespace semaphore
+    - fs: relax permissions for statmount()
+    - seccomp: release task filters when the task exits
+    - drm/amdgpu/display: handle gfx12 in amdgpu_dm_plane_format_mod_supported
+    - can: m_can: Remove m_can_rx_peripheral indirection
+    - can: m_can: Do not cancel timer from within timer
+    - mm: Provide a means of invalidation without using launder_folio
+    - cifs: Fix copy offload to flush destination region
+    - hwmon: ltc2991: fix register bits defines
+    - scripts: fix gfp-translate after ___GFP_*_BITS conversion to an enum
+    - ptp: ocp: convert serial ports to array
+    - ptp: ocp: adjust sysfs entries to expose tty information
+    - ice: check ICE_VSI_DOWN under rtnl_lock when preparing for reset
+    - ice: remove ICE_CFG_BUSY locking from AF_XDP code
+    - net: xilinx: axienet: Fix race in axienet_stop
+    - iommu/vt-d: Remove control over Execute-Requested requests
+    - block: don't call bio_uninit from bio_endio
+    - tracing/kprobes: Add symbol counting check when module loads
+    - perf/x86/intel: Hide Topdown metrics events if the feature is not enumerated
+    - PCI: qcom: Override NO_SNOOP attribute for SA8775P RC
+    - staging: vchiq_core: Bubble up wait_event_interruptible() return value
+    - watchdog: imx7ulp_wdt: keep already running watchdog enabled
+    - btrfs: slightly loosen the requirement for qgroup removal
+    - drm/amdgpu: add PSP RAS address query command
+    - drm/amdgpu: add mutex to protect ras shared memory
+    - s390/boot: Do not assume the decompressor range is reserved
+    - drm/amdgpu: Fix two reset triggered in a row
+    - drm/amdgpu: Add reset_context flag for host FLR
+    - drm/amdgpu: Fix amdgpu_device_reset_sriov retry logic
+    - fs: only copy to userspace on success in listmount()
+    - iio: adc: ad7124: fix DT configuration parsing
+    - nvmem: u-boot-env: error if NVMEM device is too small
+    - mm: zswap: rename is_zswap_enabled() to zswap_is_enabled()
+    - mm/memcontrol: respect zswap.writeback setting from parent cg too
+    - path: add cleanup helper
+    - fs: simplify error handling
+    - fs: relax permissions for listmount()
+    - hid: bpf: add BPF_JIT dependency
+    - net/mlx5e: SHAMPO, Use KSMs instead of KLMs
+    - net/mlx5e: SHAMPO, Fix page leak
+    - drm/xe/xe2: Add workaround 14021402888
+    - drm/xe/xe2lpg: Extend workaround 14021402888
+    - clk: qcom: gcc-x1e80100: Fix USB 0 and 1 PHY GDSC pwrsts flags
+    - clk: qcom: gcc-x1e80100: Don't use parking clk_ops for QUPs
+    - nouveau: fix the fwsec sb verification register.
+    - riscv: Add tracepoints for SBI calls and returns
+    - riscv: Improve sbi_ecall() code generation by reordering arguments
+    - riscv: Fix RISCV_ALTERNATIVE_EARLY
+    - cifs: Fix zero_point init on inode initialisation
+    - nvme: rename nvme_sc_to_pr_err to nvme_status_to_pr_err
+    - nvme: fix status magic numbers
+    - nvme: rename CDR/MORE/DNR to NVME_STATUS_*
+    - nvmet: Identify-Active Namespace ID List command should reject invalid nsid
+    - drm/i915/display: Add mechanism to use sink model when applying quirk
+    - drm/i915/display: Increase Fast Wake Sync length as a quirk
+    - LoongArch: Use accessors to page table entries instead of direct dereference
+    - Upstream stable to v6.6.51, v6.10.10
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46823
+    - kunit/overflow: Fix UB in overflow_allocation_test
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46834
+    - ethtool: fail closed if we can't get max channel used in indirection tables
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46751
+    - btrfs: don't BUG_ON() when 0 reference count at btrfs_lookup_extent_info()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46753
+    - btrfs: handle errors from btrfs_dec_ref() properly
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46841
+    - btrfs: don't BUG_ON on ENOMEM from btrfs_lookup_extent_info() in
+      walk_down_proc()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46754
+    - bpf: Remove tst_run from lwt_seg6local_prog_ops.
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46824
+    - iommufd: Require drivers to supply the cache_invalidate_user ops
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46842
+    - scsi: lpfc: Handle mailbox timeouts in lpfc_get_sfp_info
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46766
+    - ice: move netif_queue_set_napi to rtnl-protected sections
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46772
+    - drm/amd/display: Check denominator crb_pipes before used
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46774
+    - powerpc/rtas: Prevent Spectre v1 gadget construction in sys_rtas()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46775
+    - drm/amd/display: Validate function returns
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46778
+    - drm/amd/display: Check UnboundedRequestEnabled's value
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46779
+    - drm/imagination: Free pvr_vm_gpuva after unlink
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46792
+    - riscv: misaligned: Restrict user access to kernel memory
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46793
+    - ASoC: Intel: Boards: Fix NULL pointer deref in BYT/CHT boards harder
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46735
+    - ublk_drv: fix NULL pointer dereference in ublk_ctrl_start_recovery()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46737
+    - nvmet-tcp: fix kernel crash if commands allocation fails
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46822
+    - arm64: acpi: Harden get_cpu_for_acpi_id() against missing CPU entry
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46713
+    - perf/aux: Fix AUX buffer serialization
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46739
+    - uio_hv_generic: Fix kernel NULL pointer dereference in hv_uio_rescind
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46740
+    - binder: fix UAF caused by offsets overwrite
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46741
+    - misc: fastrpc: Fix double free of 'buf' in error path
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47663
+    - staging: iio: frequency: ad9834: Validate frequency parameter value
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46832
+    - MIPS: cevt-r4k: Don't call get_c0_compare_int if timer irq is installed
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47668
+    - lib/generic-radix-tree.c: Fix rare race in __genradix_ptr_alloc()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46744
+    - Squashfs: sanity check symbolic link size
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46745
+    - Input: uinput - reject requests with unreasonable number of slots
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46746
+    - HID: amd_sfh: free driver_data after destroying hid device
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47664
+    - spi: hisi-kunpeng: Add verification for the max_frequency provided by the
+      firmware
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47665
+    - i3c: mipi-i3c-hci: Error out instead on BUG_ON() in IBI DMA setup
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46749
+    - Bluetooth: btnxpuart: Fix Null pointer dereference in btnxpuart_flush()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46750
+    - PCI: Add missing bridge lock to pci_bus_lock()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46752
+    - btrfs: replace BUG_ON() with error handling at update_ref_for_cow()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46840
+    - btrfs: clean up our handling of refs == 0 in snapshot delete
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46755
+    - wifi: mwifiex: Do not return unused priv in mwifiex_get_priv_by_id()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47666
+    - scsi: pm80xx: Set phy->enable_completion only when we wait for it
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46843
+    - scsi: ufs: core: Remove SCSI host only if added
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46760
+    - wifi: rtw88: usb: schedule rx work after everything is set up
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46761
+    - pci/hotplug/pnv_php: Fix hotplug driver crash on Powernv
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46844
+    - um: line: always fill *error_out in setup_one_line()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46762
+    - xen: privcmd: Fix possible access to a freed kirqfd instance
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46763
+    - fou: Fix null-ptr-deref in GRO.
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46765
+    - ice: protect XDP configuration with a mutex
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46767
+    - net: phy: Fix missing of_node_put() for leds
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46768
+    - hwmon: (hp-wmi-sensors) Check if WMI event data exists
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46770
+    - ice: Add netif_device_attach/detach into PF reset flow
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46771
+    - can: bcm: Remove proc entry when dev is unregistered.
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46773
+    - drm/amd/display: Check denominator pbn_div before used
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47667
+    - PCI: keystone: Add workaround for Errata #i2037 (AM65x SR 1.0)
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46835
+    - drm/amdgpu: Fix smatch static checker warning
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46776
+    - drm/amd/display: Run DC_LOG_DC after checking link->link_enc
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46836
+    - usb: gadget: aspeed_udc: validate endpoint index for ast udc
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46777
+    - udf: Avoid excessive partition lengths
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46825
+    - wifi: iwlwifi: mvm: use IWL_FW_CHECK for link ID check
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46826
+    - ELF: fix kernel.randomize_va_space double read
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46827
+    - wifi: ath12k: fix firmware crash due to invalid peer nss
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-47669
+    - nilfs2: fix state management in error path of log writing function
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46780
+    - nilfs2: protect references to superblock parameters exposed in sysfs
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46781
+    - nilfs2: fix missing cleanup on rollforward recovery error
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46828
+    - sched: sch_cake: fix bulk flow accounting logic for host fairness
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46782
+    - ila: call nf_unregister_net_hooks() sooner
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46783
+    - tcp_bpf: fix return value of tcp_bpf_sendmsg()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46784
+    - net: mana: Fix error handling in mana_create_txq/rxq's NAPI cleanup
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46785
+    - eventfs: Use list_del_rcu() for SRCU protected list variable
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46786
+    - fscache: delete fscache_cookie_lru_timer when fscache exits to avoid UAF
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46787
+    - userfaultfd: fix checks for huge PMDs
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46838
+    - userfaultfd: don't BUG_ON() if khugepaged yanks our page table
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46845
+    - tracing/timerlat: Only clear timer if a kthread exists
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46788
+    - tracing/osnoise: Use a cpumask to know what threads are kthreads
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46846
+    - spi: rockchip: Resolve unbalanced runtime PM / system PM handling
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46847
+    - mm: vmalloc: ensure vmap_block is initialised before adding to queue
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46791
+    - can: mcp251x: fix deadlock if an interrupt occurs during mcp251x_open
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46829
+    - rtmutex: Drop rt_mutex::wait_lock before scheduling
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46848
+    - perf/x86/intel: Limit the period on Haswell
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46794
+    - x86/tdx: Fix data leak in mmio_read()
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46795
+    - ksmbd: unset the binding mark of a reused connection
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46797
+    - powerpc/qspinlock: Fix deadlock in MCS queue
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46830
+    - KVM: x86: Acquire kvm->srcu when handling KVM_SET_VCPU_EVENTS
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46798
+    - ASoC: dapm: Fix UAF for snd_soc_pcm_runtime object
+  * Noble update: upstream stable patchset 2024-10-29 (LP: #2085849) //
+    CVE-2024-46831
+    - net: microchip: vcap: Fix use-after-free error in kunit test
+  * Navi24 RX6300 light up issue on 6.8 kernel (LP: #2084513)
+    - drm/amd/display: Ensure populate uclk in bb construction
+  * Noble update: upstream stable patchset 2024-10-18 (LP: #2084941)
+    - 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
+    - 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
+    - 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)
+    - 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/amdkfd: Check debug trap enable before write dbg_ev_file
+    - 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
+    - btrfs: factor out stripe length calculation into a helper
+    - btrfs: scrub: update last_physical after scrubbing one stripe
+    - btrfs: fix qgroup reserve leaks in cow_file_range
+    - virtio-net: check feature before configuring the vq coalescing command
+    - drm/amd/display: Handle the case which quad_part is equal 0
+    - drm/amdgpu: Handle sg size limit for contiguous allocation
+    - drm/amd/pm: fix uninitialized variable warning for smu_v13
+    - drm/amdgpu: fix uninitialized scalar variable warning
+    - drm/amd/display: Ensure array index tg_inst won't be -1
+    - drm/amd/display: handle invalid connector indices
+    - drm/amd/display: Increase MAX_LINKS by 2
+    - drm/amd/display: Stop amdgpu_dm initialize when link nums greater than
+      max_links
+    - drm/amd/display: Fix incorrect size calculation for loop
+    - drm/amd/display: Use kcalloc() instead of kzalloc()
+    - drm/amd/display: Add missing NULL pointer check within
+      dpcd_extend_address_range
+    - drm/amd/display: Release state memory if amdgpu_dm_create_color_properties
+      fail
+    - drm/amd/display: Check link_index before accessing dc->links[]
+    - drm/amd/display: Add otg_master NULL check within
+      resource_log_pipe_topology_update
+    - drm/amd/display: Release clck_src memory if clk_src_construct fails
+    - drm/amd/display: Fix writeback job lock evasion within dm_crtc_high_irq
+    - drm/xe: Demote CCS_MODE info to debug only
+    - drm/drm-bridge: Drop conditionals around of_node pointers
+    - drm/amdgpu: fix uninitialized variable warning for amdgpu_xgmi
+    - drm/amdgpu: fix uninitialized variable warning for jpeg_v4
+    - drm/amdgpu: Fix uninitialized variable warning in amdgpu_info_ioctl
+    - wifi: ath12k: initialize 'ret' in ath12k_dp_rxdma_ring_sel_config_wcn7850()
+    - drm/amdgpu/pm: Check input value for power profile setting on smu11, smu13
+      and smu14
+    - drm/xe: Fix the warning conditions
+    - drm/amd/display: Fix pipe addition logic in calc_blocks_to_ungate DCN35
+    - wifi: cfg80211: restrict operation during radar detection
+    - remoteproc: qcom_q6v5_pas: Add hwspinlock bust on stop
+    - tcp: annotate data-races around tw->tw_ts_recent and tw->tw_ts_recent_stamp
+    - drm/xe: Don't overmap identity VRAM mapping
+    - net: tcp/dccp: prepare for tw_timer un-pinning
+    - drm/xe: Ensure caller uses sole domain for xe_force_wake_assert_held
+    - drm/xe: Check valid domain is passed in xe_force_wake_ref
+    - thermal: trip: Use READ_ONCE() for lockless access to trip properties
+    - drm/xe: Add GuC state asserts to deregister_exec_queue
+    - drm/amdgpu: fix overflowed constant warning in mmhub_set_clockgating()
+    - drm/amd/display: Remove register from DCN35 DMCUB diagnostic collection
+    - drm/amd/display: Disable DMCUB timeout for DCN35
+    - drm/amd/display: Avoid overflow from uint32_t to uint8_t
+    - pinctrl: core: reset gpio_device in loop in pinctrl_pins_show()
+    - Upstream stable to v6.6.50, v6.10.9
+  * CVE-2024-46747
+    - HID: cougar: fix slab-out-of-bounds Read in cougar_report_fixup
+  * CVE-2024-46725
+    - drm/amdgpu: Fix out-of-bounds write warning
+  * CVE-2024-46724
+    - drm/amdgpu: Fix out-of-bounds read of df_v1_7_channel_number
+  * [SRU] Fix AST DP output after resume (LP: #2083022)
+    - drm/ast: Inline drm_simple_encoder_init()
+    - drm/ast: Implement atomic enable/disable for encoders
+    - drm/ast: Program mode for AST DP in atomic_mode_set
+    - drm/ast: Move mode-setting code into mode_set_nofb CRTC helper
+    - drm/ast: Handle primary-plane format setup in atomic_update
+    - drm/ast: Remove gamma LUT updates from DPMS code
+    - drm/ast: Only set VGA SCREEN_DISABLE bit in CRTC code
+    - drm/ast: Inline ast_crtc_dpms() into callers
+    - drm/ast: Use drm_atomic_helper_commit_tail() helper
+  * UBSAN array-index-out-of-bounds reported with N-6.8 on P9 node baltar
+    (LP: #2078038)
+    - scripts/kernel-doc: reindent
+    - compiler_types: add Endianness-dependent __counted_by_{le, be}
+    - scsi: aacraid: union aac_init: Replace 1-element array with flexible array
+    - scsi: aacraid: struct aac_ciss_phys_luns_resp: Replace 1-element array with
+      flexible array
+    - scsi: aacraid: Rearrange order of struct aac_srb_unit
+    - scsi: aacraid: struct {user, }sgmap{, 64, raw}: Replace 1-element arrays
+      with flexible arrays
+  * r8169: transmit queue 0 timed out error when re-plugging the Ethernet cable
+    (LP: #2084526)
+    - r8169: disable ALDPS per default for RTL8125
+  * [SRU] cpufreq: intel_pstate: Support Emerald Rapids OOB mode (LP: #2084834)
+    - cpufreq: intel_pstate: Support Emerald Rapids OOB mode
+  * CVE-2024-46723
+    - drm/amdgpu: fix ucode out-of-bounds read warning
+  * CVE-2024-46743
+    - of/irq: Prevent device address out-of-bounds read in interrupt map walk
+  * CVE-2024-46757
+    - hwmon: (nct6775-core) Fix underflows seen when writing limit attributes
+  * [SRU] Ubuntu 24.04 - GPU cannot be installed with DL380a Gen12 (2P, SRF-SP)
+    (LP: #2081079)
+    - perf/x86/uncore: Save the unit control address of all units
+    - perf/x86/uncore: Support per PMU cpumask
+    - perf/x86/uncore: Retrieve the unit ID from the unit control RB tree
+    - perf/x86/uncore: Apply the unit control RB tree to MMIO uncore units
+    - perf/x86/uncore: Apply the unit control RB tree to MSR uncore units
+    - perf/x86/uncore: Apply the unit control RB tree to PCI uncore units
+    - perf/x86/uncore: Cleanup unused unit structure
+    - perf/x86/intel/uncore: Support HBM and CXL PMON counters
+  * Noble update: upstream stable patchset 2024-10-11 (LP: #2084225)
+    - ALSA: seq: Skip event type filtering for UMP events
+    - LoongArch: Remove the unused dma-direct.h
+    - btrfs: fix a use-after-free when hitting errors inside btrfs_submit_chunk()
+    - btrfs: run delayed iputs when flushing delalloc
+    - smb/client: avoid dereferencing rdata=NULL in smb2_new_read_req()
+    - pinctrl: rockchip: correct RK3328 iomux width flag for GPIO2-B pins
+    - pinctrl: single: fix potential NULL dereference in pcs_get_function()
+    - wifi: wfx: repair open network AP mode
+    - wifi: mwifiex: duplicate static structs used in driver instances
+    - net: mana: Fix race of mana_hwc_post_rx_wqe and new hwc response
+    - mptcp: close subflow when receiving TCP+FIN
+    - mptcp: sched: check both backup in retrans
+    - mptcp: pm: reuse ID 0 after delete and re-add
+    - mptcp: pm: skip connecting to already established sf
+    - mptcp: pm: reset MPC endp ID when re-added
+    - mptcp: pm: send ACK on an active subflow
+    - mptcp: pm: do not remove already closed subflows
+    - mptcp: pm: fix ID 0 endp usage after multiple re-creations
+    - mptcp: pm: ADD_ADDR 0 is not a new address
+    - selftests: mptcp: join: check removing ID 0 endpoint
+    - selftests: mptcp: join: no extra msg if no counter
+    - selftests: mptcp: join: check re-re-adding ID 0 endp
+    - drm/amdgpu/swsmu: always force a state reprogram on init
+    - drm/vmwgfx: Fix prime with external buffers
+    - usb: typec: fix up incorrectly backported "usb: typec: tcpm: unregister
+      existing source caps before re-registration"
+    - ASoC: amd: acp: fix module autoloading
+    - ASoC: SOF: amd: Fix for acp init sequence
+    - pinctrl: mediatek: common-v2: Fix broken bias-disable for
+      PULL_PU_PD_RSEL_TYPE
+    - pinctrl: starfive: jh7110: Correct the level trigger configuration of iev
+      register
+    - ovl: pass string to ovl_parse_layer()
+    - ovl: fix wrong lowerdir number check for parameter Opt_lowerdir
+    - ovl: ovl_parse_param_lowerdir: Add missed '\n' for pr_err
+    - mm: Fix missing folio invalidation calls during truncation
+    - cifs: Fix FALLOC_FL_PUNCH_HOLE support
+    - selinux,smack: don't bypass permissions check in inode_setsecctx hook
+    - iommufd: Do not allow creating areas without READ or WRITE
+    - phy: fsl-imx8mq-usb: fix tuning parameter name
+    - dmaengine: dw-edma: Fix unmasking STOP and ABORT interrupts for HDMA
+    - dmaengine: dw-edma: Do not enable watermark interrupts for HDMA
+    - phy: xilinx: phy-zynqmp: Fix SGMII linkup failure on resume
+    - dmaengine: dw: Add peripheral bus width verification
+    - dmaengine: dw: Add memory bus width verification
+    - Bluetooth: btnxpuart: Resolve TX timeout error in power save stress test
+    - Bluetooth: btnxpuart: Handle FW Download Abort scenario
+    - Bluetooth: btnxpuart: Fix random crash seen while removing driver
+    - Bluetooth: hci_core: Fix not handling hibernation actions
+    - iommu: Do not return 0 from map_pages if it doesn't do anything
+    - netfilter: nf_tables: restore IP sanity checks for netdev/egress
+    - wifi: iwlwifi: fw: fix wgds rev 3 exact size
+    - ethtool: check device is present when getting link settings
+    - netfilter: nf_tables_ipv6: consider network offset in netdev/egress
+      validation
+    - selftests: forwarding: no_forwarding: Down ports on cleanup
+    - selftests: forwarding: local_termination: Down ports on cleanup
+    - bonding: implement xdo_dev_state_free and call it after deletion
+    - bonding: extract the use of real_device into local variable
+    - bonding: change ipsec_lock from spin lock to mutex
+    - gtp: fix a potential NULL pointer dereference
+    - sctp: fix association labeling in the duplicate COOKIE-ECHO case
+    - drm/amd/display: avoid using null object of framebuffer
+    - net: busy-poll: use ktime_get_ns() instead of local_clock()
+    - nfc: pn533: Add poll mod list filling check
+    - soc: qcom: cmd-db: Map shared memory as WC, not WB
+    - soc: qcom: pmic_glink: Actually communicate when remote goes down
+    - soc: qcom: pmic_glink: Fix race during initialization
+    - cdc-acm: Add DISABLE_ECHO quirk for GE HealthCare UI Controller
+    - scsi: sd: Ignore command SYNCHRONIZE CACHE error if format in progress
+    - USB: serial: option: add MeiG Smart SRM825L
+    - ARM: dts: imx6dl-yapp43: Increase LED current to match the yapp4 HW design
+    - usb: dwc3: omap: add missing depopulate in probe error path
+    - usb: dwc3: core: Prevent USB core invalid event buffer address access
+    - usb: dwc3: st: fix probed platform device ref count on probe error path
+    - usb: dwc3: st: add missing depopulate in probe error path
+    - usb: core: sysfs: Unmerge @usb3_hardware_lpm_attr_group in
+      remove_power_attributes()
+    - usb: cdnsp: fix incorrect index in cdnsp_get_hw_deq function
+    - usb: cdnsp: fix for Link TRB with TC
+    - ARM: dts: omap3-n900: correct the accelerometer orientation
+    - arm64: dts: imx8mp-beacon-kit: Fix Stereo Audio on WM8962
+    - arm64: dts: imx93: add nvmem property for fec1
+    - arm64: dts: imx93: add nvmem property for eqos
+    - arm64: dts: imx93: update default value for snps,clk-csr
+    - arm64: dts: freescale: imx93-tqma9352: fix CMA alloc-ranges
+    - arm64: dts: freescale: imx93-tqma9352-mba93xxla: fix typo
+    - scsi: aacraid: Fix double-free on probe failure
+    - apparmor: fix policy_unpack_test on big endian systems
+    - mptcp: pr_debug: add missing \n at the end
+    - mptcp: make pm_remove_addrs_and_subflows static
+    - mptcp: pm: fix RM_ADDR ID for the initial subflow
+    - mptcp: avoid duplicated SUB_CLOSED events
+    - drm/i915/dsi: Make Lenovo Yoga Tab 3 X90F DMI match less strict
+    - drm/vmwgfx: Prevent unmapping active read buffers
+    - drm/vmwgfx: Disable coherent dumb buffers without 3d
+    - firmware/sysfb: Set firmware-framebuffer parent device
+    - firmware/sysfb: Create firmware device only for enabled PCI devices
+    - video/aperture: optionally match the device in sysfb_disable()
+    - drm/xe: Prepare display for D3Cold
+    - drm/xe/display: Make display suspend/resume work on discrete
+    - drm/xe/vm: Simplify if condition
+    - drm/xe/exec_queue: Rename xe_exec_queue::compute to xe_exec_queue::lr
+    - drm/xe: prevent UAF around preempt fence
+    - pinctrl: qcom: x1e80100: Update PDC hwirq map
+    - ASoC: SOF: amd: move iram-dram fence register programming sequence
+    - nfsd: ensure that nfsd4_fattr_args.context is zeroed out
+    - backing-file: convert to using fops->splice_write
+    - pinctrl: qcom: x1e80100: Fix special pin offsets
+    - afs: Fix post-setattr file edit to do truncation correctly
+    - netfs: Fix netfs_release_folio() to say no if folio dirty
+    - netfs: Fix missing iterator reset on retry of short read
+    - dmaengine: ti: omap-dma: Initialize sglen after allocation
+    - pktgen: use cpus_read_lock() in pg_net_init()
+    - net_sched: sch_fq: fix incorrect behavior for small weights
+    - tcp: fix forever orphan socket caused by tcp_abort
+    - drm/xe/hwmon: Fix WRITE_I1 param from u32 to u16
+    - usb: typec: fsa4480: Relax CHIP_ID check
+    - firmware: qcom: scm: Mark get_wq_ctx() as atomic call
+    - usb: gadget: uvc: queue pump work in uvcg_video_enable()
+    - usb: dwc3: xilinx: add missing depopulate in probe error path
+    - usb: typec: ucsi: Move unregister out of atomic section
+    - firmware: microchip: fix incorrect error report of programming:timeout on
+      success
+    - Upstream stable to v6.6.49, v6.10.8
+  * Fix blank screen on external display after reconnecting the USB type-C
+    (LP: #2081786) // Noble update: upstream stable patchset 2024-10-11
+    (LP: #2084225)
+    - drm/i915/display: add intel_display -> drm_device backpointer
+    - drm/i915/display: add generic to_intel_display() macro
+    - drm/i915/dp_mst: Fix MST state after a sink reset
+  * Noble update: upstream stable patchset 2024-10-09 (LP: #2084005)
+    - tty: serial: fsl_lpuart: mark last busy before uart_add_one_port
+    - tty: atmel_serial: use the correct RTS flag.
+    - Revert "ACPI: EC: Evaluate orphan _REG under EC device"
+    - Revert "misc: fastrpc: Restrict untrusted app to attach to privileged PD"
+    - Revert "usb: typec: tcpm: clear pd_event queue in PORT_RESET"
+    - selinux: revert our use of vma_is_initial_heap()
+    - fuse: Initialize beyond-EOF page contents before setting uptodate
+    - char: xillybus: Don't destroy workqueue from work item running on it
+    - char: xillybus: Refine workqueue handling
+    - char: xillybus: Check USB endpoints when probing device
+    - ALSA: usb-audio: Add delay quirk for VIVO USB-C-XE710 HEADSET
+    - ALSA: usb-audio: Support Yamaha P-125 quirk entry
+    - xhci: Fix Panther point NULL pointer deref at full-speed re-enumeration
+    - thunderbolt: Mark XDomain as unplugged when router is removed
+    - ALSA: hda/tas2781: fix wrong calibrated data order
+    - s390/dasd: fix error recovery leading to data corruption on ESE devices
+    - KVM: s390: fix validity interception issue when gisa is switched off
+    - riscv: change XIP's kernel_map.size to be size of the entire kernel
+    - i2c: tegra: Do not mark ACPI devices as irq safe
+    - ACPICA: Add a depth argument to acpi_execute_reg_methods()
+    - ACPI: EC: Evaluate _REG outside the EC scope more carefully
+    - arm64: ACPI: NUMA: initialize all values of acpi_early_node_map to
+      NUMA_NO_NODE
+    - dm resume: don't return EINVAL when signalled
+    - dm persistent data: fix memory allocation failure
+    - fs/ntfs3: add prefix to bitmap_size() and use BITS_TO_U64()
+    - s390/cio: rename bitmap_size() -> idset_bitmap_size()
+    - btrfs: rename bitmap_set_bits() -> btrfs_bitmap_set_bits()
+    - bitmap: introduce generic optimized bitmap_size()
+    - fix bitmap corruption on close_range() with CLOSE_RANGE_UNSHARE
+    - i2c: qcom-geni: Add missing geni_icc_disable in geni_i2c_runtime_resume
+    - rtla/osnoise: Prevent NULL dereference in error handling
+    - net: mana: Fix RX buf alloc_size alignment and atomic op panic
+    - net: mana: Fix doorbell out of order violation and avoid unnecessary
+      doorbell rings
+    - wifi: brcmfmac: cfg80211: Handle SSID based pmksa deletion
+    - selinux: fix potential counting error in avc_add_xperms_decision()
+    - selinux: add the processing of the failure of avc_add_xperms_decision()
+    - mm/memory-failure: use raw_spinlock_t in struct memory_failure_cpu
+    - btrfs: tree-checker: reject BTRFS_FT_UNKNOWN dir type
+    - btrfs: zoned: properly take lock to read/update block group's zoned
+      variables
+    - btrfs: tree-checker: add dev extent item checks
+    - drm/amdgpu: Actually check flags for all context ops.
+    - memcg_write_event_control(): fix a user-triggerable oops
+    - drm/amdgpu/jpeg2: properly set atomics vmid field
+    - drm/amdgpu/jpeg4: properly set atomics vmid field
+    - s390/uv: Panic for set and remove shared access UVC errors
+    - bpf: Fix updating attached freplace prog in prog_array map
+    - igc: Fix packet still tx after gate close by reducing i226 MAC retry buffer
+    - igc: Fix qbv_config_change_errors logics
+    - igc: Fix reset adapter logics when tx mode change
+    - net/mlx5e: Take state lock during tx timeout reporter
+    - net/mlx5e: Correctly report errors for ethtool rx flows
+    - net: axienet: Fix register defines comment description
+    - net: dsa: vsc73xx: pass value in phy_write operation
+    - net: dsa: vsc73xx: use read_poll_timeout instead delay loop
+    - net: dsa: vsc73xx: check busy flag in MDIO operations
+    - net: ethernet: mtk_wed: fix use-after-free panic in
+      mtk_wed_setup_tc_block_cb()
+    - mlxbf_gige: disable RX filters until RX path initialized
+    - mptcp: correct MPTCP_SUBFLOW_ATTR_SSN_OFFSET reserved size
+    - tcp: Update window clamping condition
+    - netfilter: allow ipv6 fragments to arrive on different devices
+    - netfilter: flowtable: initialise extack before use
+    - netfilter: nf_queue: drop packets with cloned unconfirmed conntracks
+    - netfilter: nf_tables: Audit log dump reset after the fact
+    - netfilter: nf_tables: Introduce nf_tables_getobj_single
+    - netfilter: nf_tables: Add locking for NFT_MSG_GETOBJ_RESET requests
+    - vsock: fix recursive ->recvmsg calls
+    - selftests: net: lib: ignore possible errors
+    - selftests: net: lib: kill PIDs before del netns
+    - net: hns3: fix wrong use of semaphore up
+    - net: hns3: use the user's cfg after reset
+    - net: hns3: fix a deadlock problem when config TC during resetting
+    - gpio: mlxbf3: Support shutdown() function
+    - ALSA: hda/realtek: Fix noise from speakers on Lenovo IdeaPad 3 15IAU7
+    - rust: work around `bindgen` 0.69.0 issue
+    - rust: suppress error messages from CONFIG_{RUSTC,BINDGEN}_VERSION_TEXT
+    - rust: fix the default format for CONFIG_{RUSTC,BINDGEN}_VERSION_TEXT
+    - cpu/SMT: Enable SMT only if a core is online
+    - powerpc/topology: Check if a core is online
+    - arm64: Fix KASAN random tag seed initialization
+    - block: Fix lockdep warning in blk_mq_mark_tag_wait
+    - wifi: ath12k: Add missing qmi_txn_cancel() calls
+    - quota: Remove BUG_ON from dqget()
+    - riscv: blacklist assembly symbols for kprobe
+    - kernfs: fix false-positive WARN(nr_mmapped) in kernfs_drain_open_files
+    - media: pci: cx23885: check cx23885_vdev_init() return
+    - fs: binfmt_elf_efpic: don't use missing interpreter's properties
+    - scsi: lpfc: Initialize status local variable in lpfc_sli4_repost_sgl_list()
+    - media: drivers/media/dvb-core: copy user arrays safely
+    - wifi: iwlwifi: mvm: avoid garbage iPN
+    - net/sun3_82586: Avoid reading past buffer in debug output
+    - drm/lima: set gp bus_stop bit before hard reset
+    - gpio: sysfs: extend the critical section for unregistering sysfs devices
+    - hrtimer: Select housekeeping CPU during migration
+    - virtiofs: forbid newlines in tags
+    - accel/habanalabs: fix debugfs files permissions
+    - clocksource/drivers/arm_global_timer: Guard against division by zero
+    - tick: Move got_idle_tick away from common flags
+    - netlink: hold nlk->cb_mutex longer in __netlink_dump_start()
+    - md: clean up invalid BUG_ON in md_ioctl
+    - x86: Increase brk randomness entropy for 64-bit systems
+    - memory: stm32-fmc2-ebi: check regmap_read return value
+    - parisc: Use irq_enter_rcu() to fix warning at kernel/context_tracking.c:367
+    - rxrpc: Don't pick values out of the wire header when setting up security
+    - f2fs: stop checkpoint when get a out-of-bounds segment
+    - powerpc/boot: Handle allocation failure in simple_realloc()
+    - powerpc/boot: Only free if realloc() succeeds
+    - btrfs: delayed-inode: drop pointless BUG_ON in __btrfs_remove_delayed_item()
+    - btrfs: defrag: change BUG_ON to assertion in btrfs_defrag_leaves()
+    - btrfs: change BUG_ON to assertion when checking for delayed_node root
+    - btrfs: push errors up from add_async_extent()
+    - btrfs: handle invalid root reference found in may_destroy_subvol()
+    - btrfs: send: handle unexpected data in header buffer in begin_cmd()
+    - btrfs: send: handle unexpected inode in header process_recorded_refs()
+    - btrfs: change BUG_ON to assertion in tree_move_down()
+    - btrfs: delete pointless BUG_ON check on quota root in
+      btrfs_qgroup_account_extent()
+    - f2fs: fix to do sanity check in update_sit_entry
+    - usb: gadget: fsl: Increase size of name buffer for endpoints
+    - nvme: clear caller pointer on identify failure
+    - Bluetooth: bnep: Fix out-of-bound access
+    - firmware: cirrus: cs_dsp: Initialize debugfs_root to invalid
+    - rtc: nct3018y: fix possible NULL dereference
+    - net: hns3: add checking for vf id of mailbox
+    - nvmet-tcp: do not continue for invalid icreq
+    - NFS: avoid infinite loop in pnfs_update_layout.
+    - openrisc: Call setup_memory() earlier in the init sequence
+    - s390/iucv: fix receive buffer virtual vs physical address confusion
+    - irqchip/renesas-rzg2l: Do not set TIEN and TINT source at the same time
+    - platform/x86: lg-laptop: fix %s null argument warning
+    - usb: dwc3: core: Skip setting event buffers for host only controllers
+    - irqchip/gic-v3-its: Remove BUG_ON in its_vpe_irq_domain_alloc
+    - ext4: set the type of max_zeroout to unsigned int to avoid overflow
+    - nvmet-rdma: fix possible bad dereference when freeing rsps
+    - selftests/bpf: Fix a few tests for GCC related warnings.
+    - Revert "bpf, sockmap: Prevent lock inversion deadlock in map delete elem"
+    - nvme: use srcu for iterating namespace list
+    - drm/amdgpu: fix dereference null return value for the function
+      amdgpu_vm_pt_parent
+    - hrtimer: Prevent queuing of hrtimer without a function callback
+    - nvme: fix namespace removal list
+    - gtp: pull network headers in gtp_dev_xmit()
+    - riscv: entry: always initialize regs->a0 to -ENOSYS
+    - smb3: fix lock breakage for cached writes
+    - dm suspend: return -ERESTARTSYS instead of -EINTR
+    - selftests: memfd_secret: don't build memfd_secret test on unsupported arches
+    - mm/vmalloc: fix page mapping if vm_area_alloc_pages() with high order
+      fallback to order 0
+    - btrfs: send: allow cloning non-aligned extent if it ends at i_size
+    - drm/amd/amdgpu: command submission parser for JPEG
+    - platform/surface: aggregator: Fix warning when controller is destroyed in
+      probe
+    - ALSA: hda/tas2781: Use correct endian conversion
+    - Bluetooth: hci_core: Fix LE quote calculation
+    - Bluetooth: SMP: Fix assumption of Central always being Initiator
+    - net: mscc: ocelot: use ocelot_xmit_get_vlan_info() also for FDMA and
+      register injection
+    - net: mscc: ocelot: fix QoS class for injected packets with "ocelot-8021q"
+    - net: mscc: ocelot: serialize access to the injection/extraction groups
+    - tc-testing: don't access non-existent variable on exception
+    - selftests: udpgro: report error when receive failed
+    - tcp/dccp: bypass empty buckets in inet_twsk_purge()
+    - tcp/dccp: do not care about families in inet_twsk_purge()
+    - tcp: prevent concurrent execution of tcp_sk_exit_batch
+    - net: mctp: test: Use correct skb for route input check
+    - kcm: Serialise kcm_sendmsg() for the same socket.
+    - netfilter: nft_counter: Disable BH in nft_counter_offload_stats().
+    - netfilter: nft_counter: Synchronize nft_counter_reset() against reader.
+    - ip6_tunnel: Fix broken GRO
+    - bonding: fix bond_ipsec_offload_ok return type
+    - bonding: fix null pointer deref in bond_ipsec_offload_ok
+    - bonding: fix xfrm real_dev null pointer dereference
+    - bonding: fix xfrm state handling when clearing active slave
+    - ice: fix page reuse when PAGE_SIZE is over 8k
+    - ice: fix ICE_LAST_OFFSET formula
+    - ice: fix truesize operations for PAGE_SIZE >= 8192
+    - dpaa2-switch: Fix error checking in dpaa2_switch_seed_bp()
+    - igb: cope with large MAX_SKB_FRAGS
+    - net: dsa: mv88e6xxx: Fix out-of-bound access
+    - udp: fix receiving fraglist GSO packets
+    - ipv6: fix possible UAF in ip6_finish_output2()
+    - ipv6: prevent possible UAF in ip6_xmit()
+    - bnxt_en: Fix double DMA unmapping for XDP_REDIRECT
+    - netfilter: flowtable: validate vlan header
+    - octeontx2-af: Fix CPT AF register offset calculation
+    - net: xilinx: axienet: Always disable promiscuous mode
+    - net: xilinx: axienet: Fix dangling multicast addresses
+    - net: ovs: fix ovs_drop_reasons error
+    - drm/msm/dpu: don't play tricks with debug macros
+    - drm/msm/dp: fix the max supported bpp logic
+    - drm/msm/dpu: split dpu_encoder_wait_for_event into two functions
+    - drm/msm/dpu: capture snapshot on the first commit_done timeout
+    - drm/msm/dpu: move dpu_encoder's connector assignment to atomic_enable()
+    - drm/msm/dp: reset the link phy params before link training
+    - drm/msm/dpu: cleanup FB if dpu_format_populate_layout fails
+    - drm/msm/dpu: take plane rotation into account for wide planes
+    - drm/msm: fix the highest_bank_bit for sc7180
+    - mmc: mmc_test: Fix NULL dereference on allocation failure
+    - Bluetooth: MGMT: Add error handling to pair_device()
+    - scsi: core: Fix the return value of scsi_logical_block_count()
+    - ksmbd: the buffer of smb2 query dir response has at least 1 byte
+    - drm/amdgpu: Validate TA binary size
+    - net: dsa: microchip: fix PTP config failure when using multiple ports
+    - MIPS: Loongson64: Set timer mode in cpu-probe
+    - HID: wacom: Defer calculation of resolution until resolution_code is known
+    - Input: i8042 - add forcenorestore quirk to leave controller untouched even
+      on s3
+    - Input: i8042 - use new forcenorestore quirk to replace old buggy quirk
+      combination
+    - cxgb4: add forgotten u64 ivlan cast before shift
+    - KVM: arm64: Make ICC_*SGI*_EL1 undef in the absence of a vGICv3
+    - mmc: mtk-sd: receive cmd8 data when hs400 tuning fail
+    - mmc: dw_mmc: allow biu and ciu clocks to defer
+    - smb3: fix broken cached reads when posix locks
+    - pmdomain: imx: scu-pd: Remove duplicated clocks
+    - pmdomain: imx: wait SSAR when i.MX93 power domain on
+    - nouveau/firmware: use dma non-coherent allocator
+    - mptcp: pm: re-using ID of unused removed ADD_ADDR
+    - mptcp: pm: re-using ID of unused removed subflows
+    - mptcp: pm: re-using ID of unused flushed subflows
+    - mptcp: pm: remove mptcp_pm_remove_subflow()
+    - mptcp: pm: only mark 'subflow' endp as available
+    - mptcp: pm: only decrement add_addr_accepted for MPJ req
+    - mptcp: pm: check add_addr_accept_max before accepting new ADD_ADDR
+    - mptcp: pm: only in-kernel cannot have entries with ID 0
+    - mptcp: pm: fullmesh: select the right ID later
+    - mptcp: pm: avoid possible UaF when selecting endp
+    - selftests: mptcp: join: validate fullmesh endp on 1st sf
+    - selftests: mptcp: join: restrict fullmesh endp on 1st sf
+    - selftests: mptcp: join: check re-using ID of closed subflow
+    - tcp: do not export tcp_twsk_purge()
+    - drm/msm/mdss: specify cfg bandwidth for SDM670
+    - drm/panel: nt36523: Set 120Hz fps for xiaomi,elish panels
+    - igc: Fix qbv tx latency by setting gtxoffset
+    - ALSA: timer: Relax start tick time check for slave timer elements
+    - bpf: Fix a kernel verifier crash in stacksafe()
+    - selftests/bpf: Add a test to verify previous stacksafe() fix
+    - Revert "s390/dasd: Establish DMA alignment"
+    - Input: MT - limit max slots
+    - tools: move alignment-related macros to new <linux/align.h>
+    - Revert "serial: 8250_omap: Set the console genpd always on if no console
+      suspend"
+    - usb: misc: ljca: Add Lunar Lake ljca GPIO HID to ljca_gpio_hids[]
+    - usb: xhci: Check for xhci->interrupters being allocated in
+      xhci_mem_clearup()
+    - vfs: Don't evict inode under the inode lru traversing context
+    - tracing: Return from tracing_buffers_read() if the file has been closed
+    - mm: fix endless reclaim on machines with unaccepted memory
+    - fs/netfs/fscache_cookie: add missing "n_accesses" check
+    - mm/numa: no task_numa_fault() call if PMD is changed
+    - mm/numa: no task_numa_fault() call if PTE is changed
+    - btrfs: check delayed refs when we're checking if a ref exists
+    - drm/amd/display: Adjust cursor position
+    - drm/amd/display: fix s2idle entry for DCN3.5+
+    - drm/amd/display: Enable otg synchronization logic for DCN321
+    - drm/amd/display: fix cursor offset on rotation 180
+    - netfs: Fault in smaller chunks for non-large folio mappings
+    - libfs: fix infinite directory reads for offset dir
+    - kallsyms: Avoid weak references for kallsyms symbols
+    - kbuild: avoid unneeded kallsyms step 3
+    - kbuild: refactor variables in scripts/link-vmlinux.sh
+    - kbuild: remove PROVIDE() for kallsyms symbols
+    - kallsyms: get rid of code for absolute kallsyms
+    - [Config] Remove CONFIG_KALLSYMS_BASE_RELATIVE
+    - kallsyms: Do not cleanup .llvm.<hash> suffix before sorting symbols
+    - bpf: Replace deprecated strncpy with strscpy
+    - kallsyms: replace deprecated strncpy with strscpy
+    - kallsyms: rework symbol lookup return codes
+    - kallsyms: Match symbols exactly with CONFIG_LTO_CLANG
+    - drm/v3d: Fix out-of-bounds read in `v3d_csd_job_run()`
+    - drm/amd/display: Don't register panel_power_savings on OLED panels
+    - wifi: ath12k: use 128 bytes aligned iova in transmit path for WCN7850
+    - kbuild: merge temporary vmlinux for BTF and kallsyms
+    - kbuild: avoid scripts/kallsyms parsing /dev/null
+    - Bluetooth: HCI: Invert LE State quirk to be opt-out rather then opt-in
+    - net/mlx5: Fix IPsec RoCE MPV trace call
+    - selftests: udpgro: no need to load xdp for gro
+    - ice: use internal pf id instead of function number
+    - drm/msm/dpu: limit QCM2290 to RGB formats only
+    - drm/msm/dpu: relax YUV requirements
+    - spi: spi-cadence-quadspi: Fix OSPI NOR failures during system resume
+    - drm/xe/display: stop calling domains_driver_remove twice
+    - drm/xe: Fix opregion leak
+    - drm/xe/mmio: move mmio_fini over to devm
+    - drm/xe: reset mmio mappings with devm
+    - drm/xe: Fix tile fini sequence
+    - drm/xe: Fix missing workqueue destroy in xe_gt_pagefault
+    - drm/xe: Free job before xe_exec_queue_put
+    - thermal/debugfs: Fix the NULL vs IS_ERR() confusion in debugfs_create_dir()
+    - nvme: move stopping keep-alive into nvme_uninit_ctrl()
+    - drm/amdgpu/sdma5.2: limit wptr workaround to sdma 5.2.1
+    - s390/ap: Refine AP bus bindings complete processing
+    - net: ngbe: Fix phy mode set to external phy
+    - iommufd/device: Fix hwpt at err_unresv in iommufd_device_do_replace()
+    - cgroup/cpuset: fix panic caused by partcmd_update
+    - cgroup/cpuset: Clear effective_xcpus on cpus_allowed clearing only if
+      cpus.exclusive not set
+    - of: Introduce for_each_*_child_of_node_scoped() to automate of_node_put()
+      handling
+    - thermal: of: Fix OF node leak in thermal_of_trips_init() error path
+    - thermal: of: Fix OF node leak in thermal_of_zone_register()
+    - thermal: of: Fix OF node leak in of_thermal_zone_find() error paths
+    - Upstream stable to v6.6.48, v6.10.7
+  * Unable to list directories using CIFS on 6.8 kernel (LP: #2082423) // Noble
+    update: upstream stable patchset 2024-10-09 (LP: #2084005)
+    - smb: client: ignore unhandled reparse tags
+  * CVE-2024-46759
+    - hwmon: (adc128d818) Fix underflows seen when writing limit attributes
+  * CVE-2024-46758
+    - hwmon: (lm95234) Fix underflows seen when writing limit attributes
+  * CVE-2024-46756
+    - hwmon: (w83627ehf) Fix underflows seen when writing limit attributes
+  * CVE-2024-46738
+    - VMCI: Fix use-after-free when removing resource in vmci_resource_remove()
+  * CVE-2024-46722
+    - drm/amdgpu: fix mc_data out-of-bounds read warning
+  * LXD fan bridge causes blocked tasks (LP: #2064176)
+    - SAUCE: fan: release rcu_read_lock on skb discard path
+    - SAUCE: fan: fix racy device stat update
+  * x86/CPU/AMD: Add models 0x10-0x1f to the Zen5 range (LP: #2081863)
+    - x86/CPU/AMD: Add models 0x60-0x6f to the Zen5 range
+  * UBSAN: array-index-out-of-bounds in module mt76 (LP: #2081785)
+    - wifi: mt76: mt7925: fix a potential array-index-out-of-bounds issue for clc
+  * The system hangs after resume with thunderbolt monitor(AMD GPU [1002:1900])
+    (LP: #2083182)
+    - SAUCE: drm/amd/display: Fix system hang while resume with TBT monitor
+  * [SRU] GPU: support additional device ids for DG2 driver (LP: #2083701)
+    - drm/i915: Add new PCI IDs to DG2 platform in driver
+  * [SRU]Intel Arrow Lake IBECC feature backport request for ubuntu 22.04.5 and
+    24.04.1 server (LP: #2077861)
+    - EDAC/igen6: Add Intel Arrow Lake-U/H SoCs support
+  * Noble update: upstream stable patchset 2024-10-07 (LP: #2083794)
+    - ASoC: topology: Clean up route loading
+    - ASoC: topology: Fix route memory corruption
+    - LoongArch: Define __ARCH_WANT_NEW_STAT in unistd.h
+    - sunrpc: don't change ->sv_stats if it doesn't exist
+    - nfsd: stop setting ->pg_stats for unused stats
+    - sunrpc: pass in the sv_stats struct through svc_create_pooled
+    - sunrpc: remove ->pg_stats from svc_program
+    - nfsd: remove nfsd_stats, make th_cnt a global counter
+    - nfsd: make svc_stat per-network namespace instead of global
+    - mm: gup: stop abusing try_grab_folio
+    - nvme/pci: Add APST quirk for Lenovo N60z laptop
+    - genirq/cpuhotplug: Skip suspended interrupts when restoring affinity
+    - genirq/cpuhotplug: Retry with cpu_online_mask when migration fails
+    - quota: Detect loops in quota tree
+    - bpf: Replace bpf_lpm_trie_key 0-length array with flexible array
+    - fs: Annotate struct file_handle with __counted_by() and use struct_size()
+    - mISDN: fix MISDN_TIME_STAMP handling
+    - mm/page_table_check: support userfault wr-protect entries
+    - bpf, net: Use DEV_STAT_INC()
+    - f2fs: fix to do sanity check on F2FS_INLINE_DATA flag in inode during GC
+    - f2fs: fix to cover read extent cache access with lock
+    - fou: remove warn in gue_gro_receive on unsupported protocol
+    - jfs: fix null ptr deref in dtInsertEntry
+    - jfs: Fix shift-out-of-bounds in dbDiscardAG
+    - fs/ntfs3: Do copy_to_user out of run_lock
+    - ALSA: usb: Fix UBSAN warning in parse_audio_unit()
+    - binfmt_flat: Fix corruption when not offsetting data start
+    - mm/debug_vm_pgtable: drop RANDOM_ORVALUE trick
+    - KVM: arm64: Don't defer TLB invalidation when zapping table entries
+    - KVM: arm64: Don't pass a TLBI level hint when zapping table entries
+    - drm/amd/display: Defer handling mst up request in resume
+    - drm/amd/display: Guard cursor idle reallow by DC debug option
+    - drm/amd/display: Separate setting and programming of cursor
+    - drm/amd/display: Prevent IPX From Link Detect and Set Mode
+    - ASoC: cs35l56: Patch CS35L56_IRQ1_MASK_18 to the default value
+    - platform/x86/amd/pmf: Fix to Update HPD Data When ALS is Disabled
+    - platform/x86: ideapad-laptop: introduce a generic notification chain
+    - platform/x86: ideapad-laptop: move ymc_trigger_ec from lenovo-ymc
+    - platform/x86: ideapad-laptop: add a mutex to synchronize VPC commands
+    - drm/amd/display: Solve mst monitors blank out problem after resume
+    - drm/amdgpu/display: Fix null pointer dereference in
+      dc_stream_program_cursor_position
+    - Upstream stable to v6.6.47, v6.10.6
+  * Noble update: upstream stable patchset 2024-10-04 (LP: #2083656)
+    - irqchip/mbigen: Fix mbigen node address layout
+    - platform/x86/intel/ifs: Initialize union ifs_status to zero
+    - jump_label: Fix the fix, brown paper bags galore
+    - x86/mm: Fix pti_clone_pgtable() alignment assumption
+    - x86/mm: Fix pti_clone_entry_text() for i386
+    - smb: client: move most of reparse point handling code to common file
+    - smb: client: set correct d_type for reparse DFS/DFSR and mount point
+    - smb: client: handle lack of FSCTL_GET_REPARSE_POINT support
+    - sctp: Fix null-ptr-deref in reuseport_add_sock().
+    - net: usb: qmi_wwan: fix memory leak for not ip packets
+    - net: bridge: mcast: wait for previous gc cycles when removing port
+    - net: linkwatch: use system_unbound_wq
+    - ice: Fix reset handler
+    - Bluetooth: l2cap: always unlock channel in l2cap_conless_channel()
+    - Bluetooth: hci_sync: avoid dup filtering when passive scanning with adv
+      monitor
+    - net/smc: add the max value of fallback reason count
+    - net: dsa: bcm_sf2: Fix a possible memory leak in bcm_sf2_mdio_register()
+    - l2tp: fix lockdep splat
+    - net: bcmgenet: Properly overlay PHY and MAC Wake-on-LAN capabilities
+    - net: fec: Stop PPS on driver remove
+    - gpio: prevent potential speculation leaks in gpio_device_get_desc()
+    - hwmon: corsair-psu: add USB id of HX1200i Series 2023 psu
+    - rcutorture: Fix rcu_torture_fwd_cb_cr() data race
+    - md: do not delete safemode_timer in mddev_suspend
+    - md/raid5: avoid BUG_ON() while continue reshape after reassembling
+    - block: change rq_integrity_vec to respect the iterator
+    - rcu: Fix rcu_barrier() VS post CPUHP_TEARDOWN_CPU invocation
+    - clocksource/drivers/sh_cmt: Address race condition for clock events
+    - ACPI: battery: create alarm sysfs attribute atomically
+    - ACPI: SBS: manage alarm sysfs attribute through psy core
+    - xen: privcmd: Switch from mutex to spinlock for irqfds
+    - wifi: nl80211: disallow setting special AP channel widths
+    - wifi: ath12k: fix memory leak in ath12k_dp_rx_peer_frag_setup()
+    - net/mlx5e: SHAMPO, Fix invalid WQ linked list unlink
+    - selftests/bpf: Fix send_signal test with nested CONFIG_PARAVIRT
+    - af_unix: Don't retry after unix_state_lock_nested() in
+      unix_stream_connect().
+    - PCI: Add Edimax Vendor ID to pci_ids.h
+    - udf: prevent integer overflow in udf_bitmap_free_blocks()
+    - wifi: nl80211: don't give key data to userspace
+    - can: mcp251xfd: tef: prepare to workaround broken TEF FIFO tail index
+      erratum
+    - can: mcp251xfd: tef: update workaround for erratum DS80000789E 6 of
+      mcp2518fd
+    - net: stmmac: qcom-ethqos: enable SGMII loopback during DMA reset on
+      sa8775p-ride-r3
+    - btrfs: do not clear page dirty inside extent_write_locked_range()
+    - btrfs: fix invalid mapping of extent xarray state
+    - btrfs: fix bitmap leak when loading free space cache on duplicate entry
+    - Bluetooth: btnxpuart: Shutdown timer and prevent rearming when driver
+      unloading
+    - drm/amd/display: Add delay to improve LTTPR UHBR interop
+    - drm/amdgpu: fix potential resource leak warning
+    - drm/amdgpu/pm: Fix the param type of set_power_profile_mode
+    - drm/amdgpu/pm: Fix the null pointer dereference for smu7
+    - drm/amdgpu: Fix the null pointer dereference to ras_manager
+    - drm/amdgpu/pm: Fix the null pointer dereference in apply_state_adjust_rules
+    - drm/admgpu: fix dereferencing null pointer context
+    - drm/amdgpu: Add lock around VF RLCG interface
+    - drm/amd/pm: Fix the null pointer dereference for vega10_hwmgr
+    - media: amphion: Remove lock in s_ctrl callback
+    - drm/amd/display: Add null checker before passing variables
+    - media: uvcvideo: Ignore empty TS packets
+    - media: uvcvideo: Fix the bandwdith quirk on USB 3.x
+    - media: xc2028: avoid use-after-free in load_firmware_cb()
+    - ext4: fix uninitialized variable in ext4_inlinedir_to_tree
+    - jbd2: avoid memleak in jbd2_journal_write_metadata_buffer
+    - s390/sclp: Prevent release of buffer in I/O
+    - SUNRPC: Fix a race to wake a sync task
+    - profiling: remove profile=sleep support
+    - scsi: mpt3sas: Avoid IOMMU page faults on REPORT ZONES
+    - irqchip/meson-gpio: Convert meson_gpio_irq_controller::lock to
+      'raw_spinlock_t'
+    - irqchip/loongarch-cpu: Fix return value of lpic_gsi_to_irq()
+    - sched/cputime: Fix mul_u64_u64_div_u64() precision for cputime
+    - net: drop bad gso csum_start and offset in virtio_net_hdr
+    - arm64: Add Neoverse-V2 part
+    - arm64: barrier: Restore spec_bar() macro
+    - arm64: cputype: Add Cortex-X4 definitions
+    - arm64: cputype: Add Neoverse-V3 definitions
+    - arm64: errata: Add workaround for Arm errata 3194386 and 3312417
+    - arm64: cputype: Add Cortex-X3 definitions
+    - arm64: cputype: Add Cortex-A720 definitions
+    - arm64: cputype: Add Cortex-X925 definitions
+    - arm64: errata: Unify speculative SSBS errata logic
+    - [Config] Set ARM64_ERRATUM_3194386=y
+    - arm64: errata: Expand speculative SSBS workaround
+    - arm64: cputype: Add Cortex-X1C definitions
+    - arm64: cputype: Add Cortex-A725 definitions
+    - arm64: errata: Expand speculative SSBS workaround (again)
+    - i2c: smbus: Improve handling of stuck alerts
+    - ASoC: codecs: wcd938x-sdw: Correct Soundwire ports mask
+    - ASoC: codecs: wsa881x: Correct Soundwire ports mask
+    - ASoC: codecs: wsa883x: parse port-mapping information
+    - ASoC: codecs: wsa883x: Correct Soundwire ports mask
+    - ASoC: codecs: wsa884x: parse port-mapping information
+    - ASoC: codecs: wsa884x: Correct Soundwire ports mask
+    - ASoC: sti: add missing probe entry for player and reader
+    - spi: spidev: Add missing spi_device_id for bh2228fv
+    - ASoC: SOF: Remove libraries from topology lookups
+    - i2c: smbus: Send alert notifications to all devices if source not found
+    - bpf: kprobe: remove unused declaring of bpf_kprobe_override
+    - kprobes: Fix to check symbol prefixes correctly
+    - i2c: qcom-geni: Add missing clk_disable_unprepare in geni_i2c_runtime_resume
+    - i2c: qcom-geni: Add missing geni_icc_disable in geni_i2c_runtime_resume
+    - spi: spi-fsl-lpspi: Fix scldiv calculation
+    - ALSA: usb-audio: Re-add ScratchAmp quirk entries
+    - ASoC: meson: axg-fifo: fix irq scheduling issue with PREEMPT_RT
+    - cifs: cifs_inval_name_dfs_link_error: correct the check for fullpath
+    - module: warn about excessively long module waits
+    - module: make waiting for a concurrent module loader interruptible
+    - drm/i915/gem: Fix Virtual Memory mapping boundaries calculation
+    - drm/amd/display: Skip Recompute DSC Params if no Stream on Link
+    - drm/amdgpu: Forward soft recovery errors to userspace
+    - drm/i915/gem: Adjust vma offset for framebuffer mmap offset
+    - drm/client: fix null pointer dereference in drm_client_modeset_probe
+    - ALSA: line6: Fix racy access to midibuf
+    - ALSA: hda: Add HP MP9 G4 Retail System AMS to force connect list
+    - ALSA: hda/realtek: Add Framework Laptop 13 (Intel Core Ultra) to quirks
+    - ALSA: hda/hdmi: Yet more pin fix for HP EliteDesk 800 G4
+    - usb: vhci-hcd: Do not drop references before new references are gained
+    - USB: serial: debug: do not echo input by default
+    - usb: gadget: core: Check for unset descriptor
+    - usb: gadget: midi2: Fix the response for FB info with block 0xff
+    - usb: gadget: u_serial: Set start_delayed during suspend
+    - usb: gadget: u_audio: Check return codes from usb_ep_enable and
+      config_ep_by_speed.
+    - scsi: mpi3mr: Avoid IOMMU page faults on REPORT ZONES
+    - scsi: ufs: core: Do not set link to OFF state while waking up from
+      hibernation
+    - scsi: ufs: core: Fix hba->last_dme_cmd_tstamp timestamp updating logic
+    - tick/broadcast: Move per CPU pointer access into the atomic section
+    - vhost-vdpa: switch to use vmf_insert_pfn() in the fault handler
+    - ntp: Clamp maxerror and esterror to operating range
+    - clocksource: Scale the watchdog read retries automatically
+    - clocksource: Fix brown-bag boolean thinko in cs_watchdog_read()
+    - driver core: Fix uevent_show() vs driver detach race
+    - tracefs: Fix inode allocation
+    - tracefs: Use generic inode RCU for synchronizing freeing
+    - ntp: Safeguard against time_constant overflow
+    - timekeeping: Fix bogus clock_was_set() invocation in do_adjtimex()
+    - serial: core: check uartclk for zero to avoid divide by zero
+    - memcg: protect concurrent access to mem_cgroup_idr
+    - parisc: fix unaligned accesses in BPF
+    - parisc: fix a possible DMA corruption
+    - ASoC: amd: yc: Add quirk entry for OMEN by HP Gaming Laptop 16-n0xxx
+    - kcov: properly check for softirq context
+    - irqchip/xilinx: Fix shift out of bounds
+    - genirq/irqdesc: Honor caller provided affinity in alloc_desc()
+    - LoongArch: Enable general EFI poweroff method
+    - power: supply: qcom_battmgr: return EAGAIN when firmware service is not up
+    - power: supply: axp288_charger: Fix constant_charge_voltage writes
+    - power: supply: axp288_charger: Round constant_charge_voltage writes down
+    - tracing: Fix overflow in get_free_elt()
+    - padata: Fix possible divide-by-0 panic in padata_mt_helper()
+    - smb3: fix setting SecurityFlags when encryption is required
+    - eventfs: Don't return NULL in eventfs_create_dir()
+    - eventfs: Use SRCU for freeing eventfs_inodes
+    - selftests: mm: add s390 to ARCH check
+    - btrfs: avoid using fixed char array size for tree names
+    - x86/paravirt: Fix incorrect virt spinlock setting on bare metal
+    - x86/mtrr: Check if fixed MTRRs exist before saving them
+    - sched/smt: Introduce sched_smt_present_inc/dec() helper
+    - sched/smt: Fix unbalance sched_smt_present dec/inc
+    - sched/core: Introduce sched_set_rq_on/offline() helper
+    - sched/core: Fix unbalance set_rq_online/offline() in sched_cpu_deactivate()
+    - drm/bridge: analogix_dp: properly handle zero sized AUX transactions
+    - drm/dp_mst: Skip CSN if topology probing is not done yet
+    - drm/lima: Mark simple_ondemand governor as softdep
+    - drm/mgag200: Set DDC timeout in milliseconds
+    - drm/mgag200: Bind I2C lifetime to DRM device
+    - drm/radeon: Remove __counted_by from StateArray.states[]
+    - mptcp: fully established after ADD_ADDR echo on MPJ
+    - mptcp: pm: deny endp with signal + subflow + port
+    - block: use the right type for stub rq_integrity_vec()
+    - btrfs: fix corruption after buffer fault in during direct IO append write
+    - tools headers arm64: Sync arm64's cputype.h with the kernel sources
+    - mm/hugetlb: fix potential race in __update_and_free_hugetlb_folio()
+    - xfs: fix log recovery buffer allocation for the legacy h_size fixup
+    - mptcp: pm: reduce indentation blocks
+    - mptcp: pm: don't try to create sf if alloc failed
+    - mptcp: pm: do not ignore 'subflow' if 'signal' flag is also set
+    - selftests: mptcp: join: ability to invert ADD_ADDR check
+    - selftests: mptcp: join: test both signal & subflow
+    - Revert "selftests: mptcp: simult flows: mark 'unbalanced' tests as flaky"
+    - btrfs: fix double inode unlock for direct IO sync writes
+    - perf/x86/intel/cstate: Switch to new Intel CPU model defines
+    - perf/x86/intel/cstate: Add Arrowlake support
+    - perf/x86/intel/cstate: Add Lunarlake support
+    - perf/x86/intel/cstate: Add pkg C2 residency counter for Sierra Forest
+    - platform/x86: intel-vbtn: Protect ACPI notify handler against recursion
+    - perf/x86/amd: Use try_cmpxchg() in events/amd/{un,}core.c
+    - perf/x86/intel: Support the PEBS event mask
+    - perf/x86: Support counter mask
+    - perf/x86: Fix smp_processor_id()-in-preemptible warnings
+    - virtio-net: unbreak vq resizing when coalescing is not negotiated
+    - net: dsa: microchip: Fix Wake-on-LAN check to not return an error
+    - net: dsa: microchip: disable EEE for KSZ8567/KSZ9567/KSZ9896/KSZ9897.
+    - regmap: kunit: Use a KUnit action to call regmap_exit()
+    - regmap: kunit: Replace a kmalloc/kfree() pair with KUnit-managed alloc
+    - regmap: kunit: Fix memory leaks in gen_regmap() and gen_raw_regmap()
+    - debugobjects: Annotate racy debug variables
+    - nvme: apple: fix device reference counting
+    - cpufreq: amd-pstate: Allow users to write 'default' EPP string
+    - cpufreq: amd-pstate: auto-load pstate driver by default
+    - soc: qcom: icc-bwmon: Allow for interrupts to be shared across instances
+    - ACPI: resource: Skip IRQ override on Asus Vivobook Pro N6506MU
+    - ACPI: resource: Skip IRQ override on Asus Vivobook Pro N6506MJ
+    - thermal: intel: hfi: Give HFI instances package scope
+    - wifi: ath12k: fix race due to setting ATH12K_FLAG_EXT_IRQ_ENABLED too early
+    - wifi: rtlwifi: handle return value of usb init TX/RX
+    - wifi: rtw89: pci: fix RX tag race condition resulting in wrong RX length
+    - wifi: mac80211: fix NULL dereference at band check in starting tx ba session
+    - bpf: add missing check_func_arg_reg_off() to prevent out-of-bounds memory
+      accesses
+    - mlxsw: pci: Lock configuration space of upstream bridge during reset
+    - btrfs: do not BUG_ON() when freeing tree block after error
+    - btrfs: reduce nesting for extent processing at btrfs_lookup_extent_info()
+    - btrfs: fix data race when accessing the last_trans field of a root
+    - drm/xe/preempt_fence: enlarge the fence critical section
+    - drm/amd/display: Handle HPD_IRQ for internal link
+    - drm/amd/amdkfd: Fix a resource leak in svm_range_validate_and_map()
+    - drm/xe/xe_guc_submit: Fix exec queue stop race condition
+    - drm/amd/display: Add null checks for 'stream' and 'plane' before
+      dereferencing
+    - drm/amd/display: Wake DMCUB before sending a command for replay feature
+    - drm/amd/display: reduce ODM slice count to initial new dc state only when
+      needed
+    - of: Add cleanup.h based auto release via __free(device_node) markings
+    - media: i2c: ov5647: replacing of_node_put with __free(device_node)
+    - drm/amd/display: Fix null pointer deref in dcn20_resource.c
+    - ext4: sanity check for NULL pointer after ext4_force_shutdown
+    - mm, slub: do not call do_slab_free for kfence object
+    - ASoC: cs35l56: Revert support for dual-ownership of ASP registers
+    - drm/atomic: allow no-op FB_ID updates for async flips
+    - drm/amd/display: Replace dm_execute_dmub_cmd with
+      dc_wake_and_execute_dmub_cmd
+    - drm/xe/rtp: Fix off-by-one when processing rules
+    - drm/xe: Use dma_fence_chain_free in chain fence unused as a sync
+    - drm/xe/hwmon: Fix PL1 disable flow in xe_hwmon_power_max_write
+    - drm/xe: Move lrc snapshot capturing to xe_lrc.c
+    - drm/xe: Minor cleanup in LRC handling
+    - drm/test: fix the gem shmem test to map the sg table.
+    - usb: typec: pd: no opencoding of FIELD_GET
+    - usb: typec: fsa4480: Check if the chip is really there
+    - PM: runtime: Simplify pm_runtime_get_if_active() usage
+    - scsi: ufs: core: Fix deadlock during RTC update
+    - serial: sc16is7xx: fix invalid FIFO access with special register set
+    - tracing: Have format file honor EVENT_FILE_FL_FREED
+    - mm: list_lru: fix UAF for memory cgroup
+    - net/tcp: Disable TCP-AO static key after RCU grace period
+    - Revert "drm/amd/display: Handle HPD_IRQ for internal link"
+    - idpf: fix memleak in vport interrupt configuration
+    - drm/amd/display: Add null check in resource_log_pipe_topology_update
+    - Upstream stable to v6.6.46, v6.10.5
+  * Noble update: upstream stable patchset 2024-10-02 (LP: #2083488)
+    - sysctl: allow change system v ipc sysctls inside ipc namespace
+    - sysctl: allow to change limits for posix messages queues
+    - sysctl: treewide: drop unused argument ctl_table_root::set_ownership(table)
+    - ext4: factor out a common helper to query extent map
+    - ext4: check the extent status again before inserting delalloc block
+    - leds: trigger: Store brightness set by led_trigger_event()
+    - leds: trigger: Call synchronize_rcu() before calling trig->activate()
+    - KVM: VMX: Move posted interrupt descriptor out of VMX code
+    - fbdev/vesafb: Replace references to global screen_info by local pointer
+    - video: Add helpers for decoding screen_info
+    - [Config] Update CONFIG_SCREEN_INFO
+    - video: Provide screen_info_get_pci_dev() to find screen_info's PCI device
+    - firmware/sysfb: Update screen_info for relocated EFI framebuffers
+    - mm: page_alloc: control latency caused by zone PCP draining
+    - mm/page_alloc: fix pcp->count race between drain_pages_zone() vs
+      __rmqueue_pcplist()
+    - f2fs: fix to avoid use SSR allocate when do defragment
+    - f2fs: assign CURSEG_ALL_DATA_ATGC if blkaddr is valid
+    - dmaengine: fsl-edma: add address for channel mux register in fsl_edma_chan
+    - dmaengine: fsl-edma: add i.MX8ULP edma support
+    - perf: imx_perf: fix counter start and config sequence
+    - MIPS: Loongson64: DTS: Fix PCIe port nodes for ls7a
+    - MIPS: dts: loongson: Fix liointc IRQ polarity
+    - MIPS: dts: loongson: Fix ls2k1000-rtc interrupt
+    - ARM: 9406/1: Fix callchain_trace() return value
+    - HID: amd_sfh: Move sensor discovery before HID device initialization
+    - perf tool: fix dereferencing NULL al->maps
+    - drm/nouveau: prime: fix refcount underflow
+    - drm/vmwgfx: Fix overlay when using Screen Targets
+    - drm/vmwgfx: Trigger a modeset when the screen moves
+    - sched: act_ct: take care of padding in struct zones_ht_key
+    - wifi: cfg80211: fix reporting failed MLO links status with
+      cfg80211_connect_done
+    - net: phy: realtek: add support for RTL8366S Gigabit PHY
+    - ALSA: hda: conexant: Fix headset auto detect fail in the polling mode
+    - Bluetooth: btintel: Fail setup on error
+    - Bluetooth: hci_sync: Fix suspending with wrong filter policy
+    - tcp: annotate data-races around tp->window_clamp
+    - tcp: Adjust clamping window for applications specifying SO_RCVBUF
+    - net: axienet: start napi before enabling Rx/Tx
+    - rtnetlink: Don't ignore IFLA_TARGET_NETNSID when ifname is specified in
+      rtnl_dellink().
+    - i915/perf: Remove code to update PWR_CLK_STATE for gen12
+    - ice: respect netif readiness in AF_XDP ZC related ndo's
+    - ice: don't busy wait for Rx queue disable in ice_qp_dis()
+    - ice: replace synchronize_rcu with synchronize_net
+    - ice: add missing WRITE_ONCE when clearing ice_rx_ring::xdp_prog
+    - drm/i915/hdcp: Fix HDCP2_STREAM_STATUS macro
+    - net: mvpp2: Don't re-use loop iterator
+    - net: phy: micrel: Fix the KSZ9131 MDI-X status issue
+    - ALSA: hda: Conditionally use snooping for AMD HDMI
+    - netfilter: iptables: Fix null-ptr-deref in iptable_nat_table_init().
+    - netfilter: iptables: Fix potential null-ptr-deref in
+      ip6table_nat_table_init().
+    - net/mlx5: Always drain health in shutdown callback
+    - net/mlx5: Fix error handling in irq_pool_request_irq
+    - net/mlx5: Lag, don't use the hardcoded value of the first port
+    - net/mlx5: Fix missing lock on sync reset reload
+    - net/mlx5e: Require mlx5 tc classifier action support for IPsec prio
+      capability
+    - net/mlx5e: Fix CT entry update leaks of modify header context
+    - net/mlx5e: Add a check for the return value from mlx5_port_set_eth_ptys
+    - igc: Fix double reset adapter triggered from a single taprio cmd
+    - ipv6: fix ndisc_is_useropt() handling for PIO
+    - perf: riscv: Fix selecting counters in legacy mode
+    - riscv/mm: Add handling for VM_FAULT_SIGSEGV in mm_fault_error()
+    - riscv: Fix linear mapping checks for non-contiguous memory regions
+    - arm64: jump_label: Ensure patched jump_labels are visible to all CPUs
+    - rust: SHADOW_CALL_STACK is incompatible with Rust
+    - platform/chrome: cros_ec_proto: Lock device when updating MKBP version
+    - HID: wacom: Modify pen IDs
+    - btrfs: zoned: fix zone_unusable accounting on making block group read-write
+      again
+    - btrfs: do not subtract delalloc from avail bytes
+    - protect the fetch of ->fd[fd] in do_dup2() from mispredictions
+    - mptcp: sched: check both directions for backup
+    - ALSA: usb-audio: Correct surround channels in UAC1 channel map
+    - ALSA: hda/realtek: Add quirk for Acer Aspire E5-574G
+    - ALSA: seq: ump: Optimize conversions from SysEx to UMP
+    - Revert "ALSA: firewire-lib: obsolete workqueue for period update"
+    - Revert "ALSA: firewire-lib: operate for period elapse event in process
+      context"
+    - drm/vmwgfx: Fix a deadlock in dma buf fence polling
+    - drm/virtio: Fix type of dma-fence context variable
+    - drm/i915: Fix possible int overflow in skl_ddi_calculate_wrpll()
+    - net: usb: sr9700: fix uninitialized variable use in sr_mdio_read
+    - r8169: don't increment tx_dropped in case of NETDEV_TX_BUSY
+    - mptcp: fix user-space PM announced address accounting
+    - mptcp: distinguish rcv vs sent backup flag in requests
+    - mptcp: fix NL PM announced address accounting
+    - mptcp: mib: count MPJ with backup flag
+    - mptcp: fix bad RCVPRUNED mib accounting
+    - mptcp: pm: only set request_bkup flag when sending MP_PRIO
+    - mptcp: fix duplicate data handling
+    - selftests: mptcp: always close input's FD if opened
+    - selftests: mptcp: join: validate backup in MPJ
+    - selftests: mptcp: join: check backup support in signal endp
+    - mm/huge_memory: mark racy access onhuge_anon_orders_always
+    - mm: fix khugepaged activation policy
+    - x86/cpu/vfm: Add/initialize x86_vfm field to struct cpuinfo_x86
+    - perf/x86/intel: Switch to new Intel CPU model defines
+    - perf/x86/intel: Add a distinct name for Granite Rapids
+    - drm/gpuvm: fix missing dependency to DRM_EXEC
+    - netlink: specs: correct the spec of ethtool
+    - ethtool: rss: echo the context number back
+    - wifi: cfg80211: correct S1G beacon length calculation
+    - ethtool: fix setting key and resetting indir at once
+    - ice: modify error handling when setting XSK pool in ndo_bpf
+    - ice: toggle netif_carrier when setting up XSK pool
+    - ice: improve updating ice_{t,r}x_ring::xsk_pool
+    - ice: xsk: fix txq interrupt mapping
+    - drm/atomic: Allow userspace to use explicit sync with atomic async flips
+    - drm/atomic: Allow userspace to use damage clips with async flips
+    - riscv/purgatory: align riscv_kernel_entry
+    - perf arch events: Fix duplicate RISC-V SBI firmware event name
+    - RISC-V: Enable the IPI before workqueue_online_cpu()
+    - ceph: force sending a cap update msg back to MDS for revoke op
+    - drm/vmwgfx: Remove unused code
+    - drm/vmwgfx: Fix handling of dumb buffers
+    - drm/v3d: Prevent out of bounds access in performance query extensions
+    - drm/v3d: Fix potential memory leak in the timestamp extension
+    - drm/v3d: Fix potential memory leak in the performance extension
+    - drm/v3d: Validate passed in drm syncobj handles in the timestamp extension
+    - drm/v3d: Validate passed in drm syncobj handles in the performance extension
+    - nouveau: set placement to original placement on uvmm validate.
+    - wifi: ath12k: fix soft lockup on suspend
+    - mptcp: pm: fix backup support in signal endpoints
+    - selftests: mptcp: fix error path
+    - Upstream stable to v6.6.45, v6.10.4
+  * [SRU] Fix AST DP output after resume (LP: #2083022) // Noble update:
+    upstream stable patchset 2024-10-02 (LP: #2083488)
+    - drm/ast: astdp: Wake up during connector status detection
+    - drm/ast: Fix black screen after resume
+  * [SRU]Fail to locate the LED of NVME disk behind  Intel VMD (LP: #2077287) //
+    Noble update: upstream stable patchset 2024-10-02 (LP: #2083488)
+    - PCI: pciehp: Retain Power Indicator bits for userspace indicators
+  * Noble update: upstream stable patchset 2024-09-30 (LP: #2083196)
+    - powerpc/configs: Update defconfig with now user-visible CONFIG_FSL_IFC
+    - spi: spi-microchip-core: Fix the number of chip selects supported
+    - spi: atmel-quadspi: Add missing check for clk_prepare
+    - EDAC, i10nm: make skx_common.o a separate module
+    - rcu/tasks: Fix stale task snaphot for Tasks Trace
+    - platform/chrome: cros_ec_debugfs: fix wrong EC message version
+    - ubd: refactor the interrupt handler
+    - ubd: untagle discard vs write zeroes not support handling
+    - block: initialize integrity buffer to zero before writing it to media
+    - x86/kconfig: Add as-instr64 macro to properly evaluate AS_WRUSS
+    - hfsplus: fix to avoid false alarm of circular locking
+    - x86/of: Return consistent error type from x86_of_pci_irq_enable()
+    - x86/pci/intel_mid_pci: Fix PCIBIOS_* return code handling
+    - x86/pci/xen: Fix PCIBIOS_* return code handling
+    - x86/platform/iosf_mbi: Convert PCIBIOS_* return codes to errnos
+    - cgroup/cpuset: Prevent UAF in proc_cpuset_show()
+    - hwmon: (adt7475) Fix default duty on fan is disabled
+    - block: Call .limit_depth() after .hctx has been set
+    - block/mq-deadline: Fix the tag reservation code
+    - md: Don't wait for MD_RECOVERY_NEEDED for HOT_REMOVE_DISK ioctl
+    - pwm: stm32: Always do lazy disabling
+    - nvmet-auth: fix nvmet_auth hash error handling
+    - drm/meson: fix canvas release in bind function
+    - pwm: atmel-tcb: Fix race condition and convert to guards
+    - hwmon: (max6697) Fix underflow when writing limit attributes
+    - hwmon: (max6697) Fix swapped temp{1,8} critical alarms
+    - arm64: dts: qcom: sc8180x: Correct PCIe slave ports
+    - arm64: dts: qcom: sc8180x: add power-domain to UFS PHY
+    - arm64: dts: qcom: sdm845: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm6115: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm6350: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm8250: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm8350: add power-domain to UFS PHY
+    - arm64: dts: qcom: sm8450: add power-domain to UFS PHY
+    - arm64: dts: qcom: msm8996-xiaomi-common: drop excton from the USB PHY
+    - arm64: dts: qcom: sdm850-lenovo-yoga-c630: fix IPA firmware path
+    - arm64: dts: qcom: msm8998: enable adreno_smmu by default
+    - soc: qcom: pmic_glink: Handle the return value of pmic_glink_init
+    - soc: qcom: rpmh-rsc: Ensure irqs aren't disabled by rpmh_rsc_send_data()
+      callers
+    - arm64: dts: rockchip: Add sdmmc related properties on rk3308-rock-pi-s
+    - arm64: dts: rockchip: Add pinctrl for UART0 to rk3308-rock-pi-s
+    - arm64: dts: rockchip: Add mdio and ethernet-phy nodes to rk3308-rock-pi-s
+    - arm64: dts: rockchip: Update WIFi/BT related nodes on rk3308-rock-pi-s
+    - arm64: dts: qcom: msm8996: specify UFS core_clk frequencies
+    - arm64: dts: qcom: sa8775p: mark ethernet devices as DMA-coherent
+    - soc: xilinx: rename cpu_number1 to dummy_cpu_number
+    - ARM: dts: sunxi: remove duplicated entries in makefile
+    - ARM: dts: stm32: Add arm,no-tick-in-suspend to STM32MP15xx STGEN timer
+    - arm64: dts: qcom: qrb4210-rb2: make L9A always-on
+    - cpufreq: ti-cpufreq: Handle deferred probe with dev_err_probe()
+    - OPP: ti: Fix ti_opp_supply_probe wrong return values
+    - memory: fsl_ifc: Make FSL_IFC config visible and selectable
+    - arm64: dts: ti: k3-am62x: Drop McASP AFIFOs
+    - arm64: dts: ti: k3-am625-beagleplay: Drop McASP AFIFOs
+    - arm64: dts: ti: k3-am62-verdin: Drop McASP AFIFOs
+    - arm64: dts: qcom: qdu1000: Add secure qfprom node
+    - soc: qcom: icc-bwmon: Fix refcount imbalance seen during bwmon_remove
+    - soc: qcom: pdr: protect locator_addr with the main mutex
+    - soc: qcom: pdr: fix parsing of domains lists
+    - arm64: dts: rockchip: Increase VOP clk rate on RK3328
+    - arm64: dts: amlogic: sm1: fix spdif compatibles
+    - ARM: dts: imx6qdl-kontron-samx6i: fix phy-mode
+    - ARM: dts: imx6qdl-kontron-samx6i: fix PHY reset
+    - ARM: dts: imx6qdl-kontron-samx6i: fix board reset
+    - ARM: dts: imx6qdl-kontron-samx6i: fix SPI0 chip selects
+    - ARM: dts: imx6qdl-kontron-samx6i: fix PCIe reset polarity
+    - arm64: dts: mediatek: mt8195: Fix GPU thermal zone name for SVS
+    - arm64: dts: mediatek: mt8183-kukui: Drop bogus output-enable property
+    - arm64: dts: mediatek: mt8192-asurada: Add off-on-delay-us for
+      pp3300_mipibrdg
+    - arm64: dts: mediatek: mt7622: fix "emmc" pinctrl mux
+    - arm64: dts: mediatek: mt8183-kukui: Fix the value of `dlg,jack-det-rate`
+      mismatch
+    - arm64: dts: mediatek: mt8183-kukui-jacuzzi: Add ports node for anx7625
+    - arm64: dts: amlogic: gx: correct hdmi clocks
+    - arm64: dts: amlogic: add power domain to hdmitx
+    - arm64: dts: amlogic: setup hdmi system clock
+    - arm64: dts: rockchip: Drop invalid mic-in-differential on rk3568-rock-3a
+    - arm64: dts: rockchip: Fix mic-in-differential usage on rk3566-roc-pc
+    - arm64: dts: rockchip: Fix mic-in-differential usage on rk3568-evb1-v10
+    - arm64: dts: renesas: r8a779a0: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r8a779f0: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r8a779g0: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r9a07g043u: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r9a07g044: Add missing hypervisor virtual timer IRQ
+    - arm64: dts: renesas: r9a07g054: Add missing hypervisor virtual timer IRQ
+    - m68k: atari: Fix TT bootup freeze / unexpected (SCU) interrupt messages
+    - arm64: dts: imx8mp: Fix pgc_mlmix location
+    - arm64: dts: imx8mp: add HDMI power-domains
+    - arm64: dts: imx8mp: Fix pgc vpu locations
+    - x86/xen: Convert comma to semicolon
+    - arm64: dts: rockchip: Add missing power-domains for rk356x vop_mmu
+    - arm64: dts: rockchip: fix regulator name for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: fix usb regulator for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: fix pmu_io supply for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: remove unused usb2 nodes for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: disable display subsystem for Lunzn Fastrhino R6xS
+    - arm64: dts: rockchip: fixes PHY reset for Lunzn Fastrhino R68S
+    - arm64: dts: qcom: sm6350: Add missing qcom,non-secure-domain property
+    - cpufreq/amd-pstate: Fix the scaling_max_freq setting on shared memory CPPC
+      systems
+    - m68k: cmpxchg: Fix return value for default case in __arch_xchg()
+    - ARM: spitz: fix GPIO assignment for backlight
+    - vmlinux.lds.h: catch .bss..L* sections into BSS")
+    - firmware: turris-mox-rwtm: Do not complete if there are no waiters
+    - firmware: turris-mox-rwtm: Fix checking return value of
+      wait_for_completion_timeout()
+    - firmware: turris-mox-rwtm: Initialize completion before mailbox
+    - wifi: brcmsmac: LCN PHY code is used for BCM4313 2G-only device
+    - wifi: ath12k: Correct 6 GHz frequency value in rx status
+    - wifi: ath12k: Fix tx completion ring (WBM2SW) setup failure
+    - bpftool: Un-const bpf_func_info to fix it for llvm 17 and newer
+    - selftests/bpf: Fix prog numbers in test_sockmap
+    - net: esp: cleanup esp_output_tail_tcp() in case of unsupported ESPINTCP
+    - wifi: ath12k: change DMA direction while mapping reinjected packets
+    - wifi: ath12k: fix invalid memory access while processing fragmented packets
+    - wifi: ath12k: fix firmware crash during reo reinject
+    - wifi: ath11k: fix wrong definition of CE ring's base address
+    - wifi: ath12k: fix wrong definition of CE ring's base address
+    - tcp: add tcp_done_with_error() helper
+    - tcp: fix race in tcp_write_err()
+    - tcp: fix races in tcp_v[46]_err()
+    - net/smc: set rmb's SG_MAX_SINGLE_ALLOC limitation only when
+      CONFIG_ARCH_NO_SG_CHAIN is defined
+    - selftests/bpf: Check length of recv in test_sockmap
+    - udf: Fix lock ordering in udf_evict_inode()
+    - lib: objagg: Fix general protection fault
+    - mlxsw: spectrum_acl_erp: Fix object nesting warning
+    - mlxsw: spectrum_acl: Fix ACL scale regression and firmware errors
+    - perf/x86: Serialize set_attr_rdpmc()
+    - jump_label: Fix concurrency issues in static_key_slow_dec()
+    - wifi: ath11k: fix wrong handling of CCMP256 and GCMP ciphers
+    - wifi: cfg80211: fix typo in cfg80211_calculate_bitrate_he()
+    - wifi: cfg80211: handle 2x996 RU allocation in
+      cfg80211_calculate_bitrate_he()
+    - udf: Fix bogus checksum computation in udf_rename()
+    - net: fec: Refactor: #define magic constants
+    - net: fec: Fix FEC_ECR_EN1588 being cleared on link-down
+    - libbpf: Checking the btf_type kind when fixing variable offsets
+    - xfrm: Fix unregister netdevice hang on hardware offload.
+    - ipvs: Avoid unnecessary calls to skb_is_gso_sctp
+    - netfilter: nf_tables: rise cap on SELinux secmark context
+    - wifi: rtw89: 8852b: fix definition of KIP register number
+    - wifi: rtl8xxxu: 8188f: Limit TX power index
+    - xfrm: Export symbol xfrm_dev_state_delete.
+    - bpftool: Mount bpffs when pinmaps path not under the bpffs
+    - perf/x86/intel/pt: Fix pt_topa_entry_for_page() address calculation
+    - perf: Fix perf_aux_size() for greater-than 32-bit size
+    - perf: Prevent passing zero nr_pages to rb_alloc_aux()
+    - perf: Fix default aux_watermark calculation
+    - perf/x86/intel/cstate: Fix Alderlake/Raptorlake/Meteorlake
+    - wifi: rtw89: Fix array index mistake in rtw89_sta_info_get_iter()
+    - xfrm: fix netdev reference count imbalance
+    - xfrm: call xfrm_dev_policy_delete when kill policy
+    - wifi: virt_wifi: avoid reporting connection success with wrong SSID
+    - gss_krb5: Fix the error handling path for crypto_sync_skcipher_setkey
+    - wifi: virt_wifi: don't use strlen() in const context
+    - locking/rwsem: Add __always_inline annotation to __down_write_common() and
+      inlined callers
+    - selftests/bpf: Close fd in error path in drop_on_reuseport
+    - selftests/bpf: Null checks for links in bpf_tcp_ca
+    - selftests/bpf: Close obj in error path in xdp_adjust_tail
+    - selftests/resctrl: Convert perror() to ksft_perror() or ksft_print_msg()
+    - selftests/resctrl: Fix closing IMC fds on error and open-code R+W instead of
+      loops
+    - bpf: annotate BTF show functions with __printf
+    - bna: adjust 'name' buf size of bna_tcb and bna_ccb structures
+    - bpf: Eliminate remaining "make W=1" warnings in kernel/bpf/btf.o
+    - bpf: Fix null pointer dereference in resolve_prog_type() for
+      BPF_PROG_TYPE_EXT
+    - selftests: forwarding: devlink_lib: Wait for udev events after reloading
+    - Bluetooth: hci_bcm4377: Use correct unit for timeouts
+    - Bluetooth: btintel: Refactor btintel_set_ppag()
+    - Bluetooth: btnxpuart: Add handling for boot-signature timeout errors
+    - xdp: fix invalid wait context of page_pool_destroy()
+    - net: bridge: mst: Check vlan state for egress decision
+    - drm/rockchip: vop2: Fix the port mux of VP2
+    - drm/arm/komeda: Fix komeda probe failing if there are no links in the
+      secondary pipeline
+    - drm/amdkfd: Fix CU Masking for GFX 9.4.3
+    - drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_dcs_write_seq()
+    - drm/mipi-dsi: Fix theoretical int overflow in mipi_dsi_generic_write_seq()
+    - drm/amd/pm: Fix aldebaran pcie speed reporting
+    - drm/amdgpu: Fix memory range calculation
+    - drm/amdgpu: Check if NBIO funcs are NULL in amdgpu_device_baco_exit
+    - drm/amdgpu: Remove GC HW IP 9.3.0 from noretry=1
+    - drm/panel: himax-hx8394: Handle errors from mipi_dsi_dcs_set_display_on()
+      better
+    - drm/panel: boe-tv101wum-nl6: If prepare fails, disable GPIO before
+      regulators
+    - drm/panel: boe-tv101wum-nl6: Check for errors on the NOP in prepare()
+    - drm/bridge: Fixed a DP link training bug
+    - drm/bridge: it6505: fix hibernate to resume no display issue
+    - media: pci: ivtv: Add check for DMA map result
+    - media: imon: Fix race getting ictx->lock
+    - media: i2c: Fix imx412 exposure control
+    - media: v4l: async: Fix NULL pointer dereference in adding ancillary links
+    - s390/mm: Convert make_page_secure to use a folio
+    - s390/mm: Convert gmap_make_secure to use a folio
+    - s390/uv: Don't call folio_wait_writeback() without a folio reference
+    - media: mediatek: vcodec: Handle invalid decoder vsi
+    - x86/shstk: Make return uprobe work with shadow stack
+    - ipmi: ssif_bmc: prevent integer overflow on 32bit systems
+    - saa7134: Unchecked i2c_transfer function result fixed
+    - media: i2c: imx219: fix msr access command sequence
+    - media: uvcvideo: Disable autosuspend for Insta360 Link
+    - media: uvcvideo: Quirk for invalid dev_sof in Logitech C922
+    - media: uvcvideo: Add quirk for invalid dev_sof in Logitech C920
+    - media: uvcvideo: Override default flags
+    - drm: zynqmp_dpsub: Fix an error handling path in zynqmp_dpsub_probe()
+    - drm: zynqmp_kms: Fix AUX bus not getting unregistered
+    - media: rcar-vin: Fix YUYV8_1X16 handling for CSI-2
+    - media: rcar-csi2: Disable runtime_pm in probe error
+    - media: rcar-csi2: Cleanup subdevice in remove()
+    - media: renesas: vsp1: Fix _irqsave and _irq mix
+    - media: renesas: vsp1: Store RPF partition configuration per RPF instance
+    - drm/mediatek: Add missing plane settings when async update
+    - drm/mediatek: Use 8-bit alpha in ETHDR
+    - drm/mediatek: Fix XRGB setting error in OVL
+    - drm/mediatek: Fix XRGB setting error in Mixer
+    - drm/mediatek: Fix destination alpha error in OVL
+    - drm/mediatek: Turn off the layers with zero width or height
+    - drm/mediatek: Add OVL compatible name for MT8195
+    - media: imx-jpeg: Drop initial source change event if capture has been setup
+    - leds: trigger: Unregister sysfs attributes before calling deactivate()
+    - drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC
+    - drm/msm/dpu: drop validity checks for clear_pending_flush() ctl op
+    - perf test: Make test_arm_callgraph_fp.sh more robust
+    - perf pmus: Fixes always false when compare duplicates aliases
+    - perf report: Fix condition in sort__sym_cmp()
+    - drm/etnaviv: fix DMA direction handling for cached RW buffers
+    - drm/qxl: Add check for drm_cvt_mode
+    - Revert "leds: led-core: Fix refcount leak in of_led_get()"
+    - drm/mediatek: Remove less-than-zero comparison of an unsigned value
+    - ext4: fix infinite loop when replaying fast_commit
+    - drm/mediatek/dp: switch to ->edid_read callback
+    - drm/mediatek/dp: Fix spurious kfree()
+    - media: venus: flush all buffers in output plane streamoff
+    - perf intel-pt: Fix aux_watermark calculation for 64-bit size
+    - perf intel-pt: Fix exclude_guest setting
+    - mfd: rsmu: Split core code into separate module
+    - mfd: omap-usb-tll: Use struct_size to allocate tll
+    - xprtrdma: Fix rpcrdma_reqs_reset()
+    - SUNRPC: avoid soft lockup when transmitting UDP to reachable server.
+    - NFSv4.1 another fix for EXCHGID4_FLAG_USE_PNFS_DS for DS server
+    - ext4: don't track ranges in fast_commit if inode has inlined data
+    - ext4: avoid writing unitialized memory to disk in EA inodes
+    - leds: flash: leds-qcom-flash: Test the correct variable in init
+    - sparc64: Fix incorrect function signature and add prototype for
+      prom_cif_init
+    - SUNRPC: Fixup gss_status tracepoint error output
+    - iio: Fix the sorting functionality in iio_gts_build_avail_time_table
+    - PCI: Fix resource double counting on remove & rescan
+    - PCI: keystone: Relocate ks_pcie_set/clear_dbi_mode()
+    - PCI: keystone: Don't enable BAR 0 for AM654x
+    - PCI: keystone: Fix NULL pointer dereference in case of DT error in
+      ks_pcie_setup_rc_app_regs()
+    - PCI: rcar: Demote WARN() to dev_warn_ratelimited() in rcar_pcie_wakeup()
+    - scsi: ufs: mcq: Fix missing argument 'hba' in MCQ_OPR_OFFSET_n
+    - clk: qcom: gcc-sc7280: Update force mem core bit for UFS ICE clock
+    - clk: qcom: camcc-sc7280: Add parent dependency to all camera GDSCs
+    - iio: frequency: adrf6780: rm clk provider include
+    - coresight: Fix ref leak when of_coresight_parse_endpoint() fails
+    - RDMA/mlx5: Set mkeys for dmabuf at PAGE_SIZE
+    - ASoc: tas2781: Enable RCA-based playback without DSP firmware download
+    - ASoC: cs35l56: Accept values greater than 0 as IRQ numbers
+    - usb: typec-mux: nb7vpq904m: unregister typec switch on probe error and
+      remove
+    - RDMA/cache: Release GID table even if leak is detected
+    - clk: qcom: gpucc-sm8350: Park RCG's clk source at XO during disable
+    - clk: qcom: gcc-sa8775p: Update the GDSC wait_val fields and flags
+    - clk: qcom: gpucc-sa8775p: Remove the CLK_IS_CRITICAL and ALWAYS_ON flags
+    - clk: qcom: gpucc-sa8775p: Park RCG's clk source at XO during disable
+    - clk: qcom: gpucc-sa8775p: Update wait_val fields for GPU GDSC's
+    - interconnect: qcom: qcm2290: Fix mas_snoc_bimc RPM master ID
+    - Input: qt1050 - handle CHIP_ID reading error
+    - RDMA/mlx4: Fix truncated output warning in mad.c
+    - RDMA/mlx4: Fix truncated output warning in alias_GUID.c
+    - RDMA/mlx5: Use sq timestamp as QP timestamp when RoCE is disabled
+    - RDMA/rxe: Don't set BTH_ACK_MASK for UC or UD QPs
+    - ASoC: qcom: Adjust issues in case of DT error in
+      asoc_qcom_lpass_cpu_platform_probe()
+    - scsi: lpfc: Fix a possible null pointer dereference
+    - hwrng: core - Fix wrong quality calculation at hw rng registration
+    - powerpc/prom: Add CPU info to hardware description string later
+    - ASoC: max98088: Check for clk_prepare_enable() error
+    - mtd: make mtd_test.c a separate module
+    - RDMA/device: Return error earlier if port in not valid
+    - Input: elan_i2c - do not leave interrupt disabled on suspend failure
+    - ASoC: amd: Adjust error handling in case of absent codec device
+    - PCI: endpoint: Clean up error handling in vpci_scan_bus()
+    - PCI: endpoint: Fix error handling in epf_ntb_epc_cleanup()
+    - vhost/vsock: always initialize seqpacket_allow
+    - net: missing check virtio
+    - nvmem: rockchip-otp: set add_legacy_fixed_of_cells config option
+    - crypto: qat - extend scope of lock in adf_cfg_add_key_value_param()
+    - clk: qcom: kpss-xcc: Return of_clk_add_hw_provider to transfer the error
+    - clk: qcom: Park shared RCGs upon registration
+    - clk: en7523: fix rate divider for slic and spi clocks
+    - MIPS: Octeron: remove source file executable bit
+    - PCI: qcom-ep: Disable resources unconditionally during PERST# assert
+    - PCI: dwc: Fix index 0 incorrectly being interpreted as a free ATU slot
+    - powerpc/xmon: Fix disassembly CPU feature checks
+    - macintosh/therm_windtunnel: fix module unload.
+    - RDMA/hns: Check atomic wr length
+    - RDMA/hns: Fix unmatch exception handling when init eq table fails
+    - RDMA/hns: Fix missing pagesize and alignment check in FRMR
+    - RDMA/hns: Fix shift-out-bounds when max_inline_data is 0
+    - RDMA/hns: Fix undifined behavior caused by invalid max_sge
+    - RDMA/hns: Fix insufficient extend DB for VFs.
+    - iommu/vt-d: Fix identity map bounds in si_domain_init()
+    - RDMA/core: Remove NULL check before dev_{put, hold}
+    - RDMA: Fix netdev tracker in ib_device_set_netdev
+    - bnxt_re: Fix imm_data endianness
+    - netfilter: ctnetlink: use helper function to calculate expect ID
+    - netfilter: nf_set_pipapo: fix initial map fill
+    - ipvs: properly dereference pe in ip_vs_add_service
+    - gve: Fix XDP TX completion handling when counters overflow
+    - net: flow_dissector: use DEBUG_NET_WARN_ON_ONCE
+    - ipv4: Fix incorrect TOS in route get reply
+    - ipv4: Fix incorrect TOS in fibmatch route get reply
+    - net: dsa: mv88e6xxx: Limit chip-wide frame size config to CPU ports
+    - net: dsa: b53: Limit chip-wide jumbo frame config to CPU ports
+    - fs/ntfs3: Merge synonym COMPRESSION_UNIT and NTFS_LZNT_CUNIT
+    - fs/ntfs3: Fix transform resident to nonresident for compressed files
+    - fs/ntfs3: Deny getting attr data block in compressed frame
+    - fs/ntfs3: Missed NI_FLAG_UPDATE_PARENT setting
+    - fs/ntfs3: Fix getting file type
+    - fs/ntfs3: Add missing .dirty_folio in address_space_operations
+    - pinctrl: rockchip: update rk3308 iomux routes
+    - pinctrl: core: fix possible memory leak when pinctrl_enable() fails
+    - pinctrl: single: fix possible memory leak when pinctrl_enable() fails
+    - pinctrl: ti: ti-iodelay: fix possible memory leak when pinctrl_enable()
+      fails
+    - pinctrl: freescale: mxs: Fix refcount of child
+    - fs/ntfs3: Replace inode_trylock with inode_lock
+    - fs/ntfs3: Correct undo if ntfs_create_inode failed
+    - fs/ntfs3: Drop stray '\' (backslash) in formatting string
+    - fs/ntfs3: Fix field-spanning write in INDEX_HDR
+    - pinctrl: renesas: r8a779g0: Fix CANFD5 suffix
+    - pinctrl: renesas: r8a779g0: Fix FXR_TXEN[AB] suffixes
+    - pinctrl: renesas: r8a779g0: Fix (H)SCIF1 suffixes
+    - pinctrl: renesas: r8a779g0: Fix (H)SCIF3 suffixes
+    - pinctrl: renesas: r8a779g0: Fix IRQ suffixes
+    - pinctrl: renesas: r8a779g0: FIX PWM suffixes
+    - pinctrl: renesas: r8a779g0: Fix TCLK suffixes
+    - pinctrl: renesas: r8a779g0: Fix TPU suffixes
+    - fs/proc/task_mmu: indicate PM_FILE for PMD-mapped file THP
+    - fs/proc/task_mmu.c: add_to_pagemap: remove useless parameter addr
+    - fs/proc/task_mmu: don't indicate PM_MMAP_EXCLUSIVE without PM_PRESENT
+    - fs/proc/task_mmu: properly detect PM_MMAP_EXCLUSIVE per page of PMD-mapped
+      THPs
+    - nilfs2: avoid undefined behavior in nilfs_cnt32_ge macro
+    - rtc: interface: Add RTC offset to alarm after fix-up
+    - fs/ntfs3: Fix the format of the "nocase" mount option
+    - fs/ntfs3: Missed error return
+    - fs/ntfs3: Keep runs for $MFT::$ATTR_DATA and $MFT::$ATTR_BITMAP
+    - powerpc/8xx: fix size given to set_huge_pte_at()
+    - s390/dasd: fix error checks in dasd_copy_pair_store()
+    - sbitmap: use READ_ONCE to access map->word
+    - sbitmap: fix io hung due to race on sbitmap_word::cleared
+    - LoongArch: Check TIF_LOAD_WATCH to enable user space watchpoint
+    - landlock: Don't lose track of restrictions on cred_transfer
+    - hugetlb: force allocating surplus hugepages on mempolicy allowed nodes
+    - mm/hugetlb: fix possible recursive locking detected warning
+    - mm/mglru: fix div-by-zero in vmpressure_calc_level()
+    - mm: mmap_lock: replace get_memcg_path_buf() with on-stack buffer
+    - mm/mglru: fix overshooting shrinker memory
+    - x86/efistub: Avoid returning EFI_SUCCESS on error
+    - x86/efistub: Revert to heap allocated boot_params for PE entrypoint
+    - exfat: fix potential deadlock on __exfat_get_dentry_set
+    - dt-bindings: thermal: correct thermal zone node name limit
+    - tick/broadcast: Make takeover of broadcast hrtimer reliable
+    - net: netconsole: Disable target before netpoll cleanup
+    - af_packet: Handle outgoing VLAN packets without hardware offloading
+    - btrfs: fix extent map use-after-free when adding pages to compressed bio
+    - kernel: rerun task_work while freezing in get_signal()
+    - ipv4: fix source address selection with route leak
+    - ipv6: take care of scope when choosing the src addr
+    - NFSD: Support write delegations in LAYOUTGET
+    - sched/fair: set_load_weight() must also call reweight_task() for SCHED_IDLE
+      tasks
+    - fuse: verify {g,u}id mount options correctly
+    - ata: libata-scsi: Fix offsets for the fixed format sense data
+    - char: tpm: Fix possible memory leak in tpm_bios_measurements_open()
+    - media: venus: fix use after free in vdec_close
+    - ata: libata-scsi: Do not overwrite valid sense data when CK_COND=1
+    - hfs: fix to initialize fields of hfs_inode_info after hfs_alloc_inode()
+    - ext2: Verify bitmap and itable block numbers before using them
+    - io_uring/io-wq: limit retrying worker initialisation
+    - drm/gma500: fix null pointer dereference in cdv_intel_lvds_get_modes
+    - drm/gma500: fix null pointer dereference in psb_intel_lvds_get_modes
+    - scsi: qla2xxx: Fix optrom version displayed in FDMI
+    - drm/amd/display: Check for NULL pointer
+    - apparmor: use kvfree_sensitive to free data->data
+    - cifs: fix potential null pointer use in destroy_workqueue in init_cifs error
+      path
+    - cifs: fix reconnect with SMB1 UNIX Extensions
+    - cifs: mount with "unix" mount option for SMB1 incorrectly handled
+    - task_work: s/task_work_cancel()/task_work_cancel_func()/
+    - task_work: Introduce task_work_cancel() again
+    - udf: Avoid using corrupted block bitmap buffer
+    - m68k: amiga: Turn off Warp1260 interrupts during boot
+    - ext4: check dot and dotdot of dx_root before making dir indexed
+    - ext4: make sure the first directory block is not a hole
+    - io_uring: tighten task exit cancellations
+    - trace/pid_list: Change gfp flags in pid_list_fill_irq()
+    - selftests/landlock: Add cred_transfer test
+    - wifi: mwifiex: Fix interface type change
+    - wifi: rtw88: usb: Fix disconnection after beacon loss
+    - drivers: soc: xilinx: check return status of get_api_version()
+    - leds: ss4200: Convert PCIBIOS_* return codes to errnos
+    - leds: mt6360: Fix memory leak in mt6360_init_isnk_properties()
+    - media: imx-pxp: Fix ERR_PTR dereference in pxp_probe()
+    - jbd2: make jbd2_journal_get_max_txn_bufs() internal
+    - jbd2: precompute number of transaction descriptor blocks
+    - jbd2: avoid infinite transaction commit loop
+    - media: uvcvideo: Fix integer overflow calculating timestamp
+    - KVM: VMX: Split out the non-virtualization part of vmx_interrupt_blocked()
+    - KVM: nVMX: Request immediate exit iff pending nested event needs injection
+    - ALSA: ump: Don't update FB name for static blocks
+    - ALSA: ump: Force 1 Group for MIDI1 FBs
+    - ALSA: usb-audio: Fix microphone sound on HD webcam.
+    - ALSA: usb-audio: Move HD Webcam quirk to the right place
+    - ALSA: usb-audio: Add a quirk for Sonix HD USB Camera
+    - tools/memory-model: Fix bug in lock.cat
+    - hwrng: amd - Convert PCIBIOS_* return codes to errnos
+    - parisc: Fix warning at drivers/pci/msi/msi.h:121
+    - PCI: hv: Return zero, not garbage, when reading PCI_INTERRUPT_PIN
+    - PCI: dw-rockchip: Fix initial PERST# GPIO value
+    - PCI: rockchip: Use GPIOD_OUT_LOW flag while requesting ep_gpio
+    - PCI: loongson: Enable MSI in LS7A Root Complex
+    - binder: fix hang of unregistered readers
+    - hostfs: fix dev_t handling
+    - efi/libstub: Zero initialize heap allocated struct screen_info
+    - fs/ntfs3: Update log->page_{mask,bits} if log->page_size changed
+    - scsi: qla2xxx: Return ENOBUFS if sg_cnt is more than one for ELS cmds
+    - ASoC: fsl: fsl_qmc_audio: Check devm_kasprintf() returned value
+    - f2fs: fix to force buffered IO on inline_data inode
+    - f2fs: fix to don't dirty inode for readonly filesystem
+    - f2fs: fix return value of f2fs_convert_inline_inode()
+    - f2fs: use meta inode for GC of atomic file
+    - f2fs: use meta inode for GC of COW file
+    - clk: davinci: da8xx-cfgchip: Initialize clk_init_data before use
+    - ubi: eba: properly rollback inside self_check_eba
+    - block: fix deadlock between sd_remove & sd_release
+    - mm: fix old/young bit handling in the faulting path
+    - decompress_bunzip2: fix rare decompression failure
+    - kbuild: Fix '-S -c' in x86 stack protector scripts
+    - ASoC: SOF: ipc4-topology: Preserve the DMA Link ID for ChainDMA on unprepare
+    - ASoC: amd: yc: Support mic on Lenovo Thinkpad E16 Gen 2
+    - kobject_uevent: Fix OOB access within zap_modalias_env()
+    - gve: Fix an edge case for TSO skb validity check
+    - ice: Add a per-VF limit on number of FDIR filters
+    - devres: Fix devm_krealloc() wasting memory
+    - devres: Fix memory leakage caused by driver API devm_free_percpu()
+    - irqdomain: Fixed unbalanced fwnode get and put
+    - irqchip/imx-irqsteer: Handle runtime power management correctly
+    - mm/numa_balancing: teach mpol_to_str about the balancing mode
+    - rtc: cmos: Fix return value of nvmem callbacks
+    - scsi: lpfc: Allow DEVICE_RECOVERY mode after RSCN receipt if in PRLI_ISSUE
+      state
+    - scsi: qla2xxx: During vport delete send async logout explicitly
+    - scsi: qla2xxx: Unable to act on RSCN for port online
+    - scsi: qla2xxx: Fix for possible memory corruption
+    - scsi: qla2xxx: Use QP lock to search for bsg
+    - scsi: qla2xxx: Reduce fabric scan duplicate code
+    - scsi: qla2xxx: Fix flash read failure
+    - scsi: qla2xxx: Complete command early within lock
+    - scsi: qla2xxx: validate nvme_local_port correctly
+    - perf: Fix event leak upon exit
+    - perf: Fix event leak upon exec and file release
+    - perf stat: Fix the hard-coded metrics calculation on the hybrid
+    - perf/x86/intel/uncore: Fix the bits of the CHA extended umask for SPR
+    - perf/x86/intel/ds: Fix non 0 retire latency on Raptorlake
+    - perf/x86/intel/pt: Fix topa_entry base length
+    - perf/x86/intel/pt: Fix a topa_entry base address calculation
+    - drm/i915/gt: Do not consider preemption during execlists_dequeue for gen8
+    - drm/amdgpu/sdma5.2: Update wptr registers as well as doorbell
+    - drm/udl: Remove DRM_CONNECTOR_POLL_HPD
+    - drm/dp_mst: Fix all mstb marked as not probed after suspend/resume
+    - drm/amdgpu: reset vm state machine after gpu reset(vram lost)
+    - drm/amd/amdgpu: Fix uninitialized variable warnings
+    - drm/i915/dp: Reset intel_dp->link_trained before retraining the link
+    - drm/i915/dp: Don't switch the LTTPR mode on an active link
+    - rtc: isl1208: Fix return value of nvmem callbacks
+    - rtc: abx80x: Fix return value of nvmem callback on read
+    - watchdog/perf: properly initialize the turbo mode timestamp and rearm
+      counter
+    - platform: mips: cpu_hwmon: Disable driver on unsupported hardware
+    - RDMA/iwcm: Fix a use-after-free related to destroying CM IDs
+    - selftests/sigaltstack: Fix ppc64 GCC build
+    - dm-verity: fix dm_is_verity_target() when dm-verity is builtin
+    - rbd: don't assume rbd_is_lock_owner() for exclusive mappings
+    - remoteproc: stm32_rproc: Fix mailbox interrupts queuing
+    - remoteproc: imx_rproc: Skip over memory region when node value is NULL
+    - remoteproc: imx_rproc: Fix refcount mistake in imx_rproc_addr_init
+    - MIPS: dts: loongson: Add ISA node
+    - MIPS: ip30: ip30-console: Add missing include
+    - MIPS: dts: loongson: Fix GMAC phy node
+    - MIPS: Loongson64: env: Hook up Loongsson-2K
+    - MIPS: Loongson64: Remove memory node for builtin-dtb
+    - MIPS: Loongson64: reset: Prioritise firmware service
+    - MIPS: Loongson64: Test register availability before use
+    - drm/etnaviv: don't block scheduler when GPU is still active
+    - drm/panfrost: Mark simple_ondemand governor as softdep
+    - rbd: rename RBD_LOCK_STATE_RELEASING and releasing_wait
+    - rbd: don't assume RBD_LOCK_STATE_LOCKED for exclusive mappings
+    - lib/build_OID_registry: don't mention the full path of the script in output
+    - video: logo: Drop full path of the input filename in generated file
+    - Bluetooth: btusb: Add RTL8852BE device 0489:e125 to device tables
+    - Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x13d3:0x3591
+    - minmax: scsi: fix mis-use of 'clamp()' in sr.c
+    - mm/mglru: fix ineffective protection calculation
+    - PCI/DPC: Fix use-after-free on concurrent DPC and hot-removal
+    - f2fs: fix to truncate preallocated blocks in f2fs_file_open()
+    - kdb: address -Wformat-security warnings
+    - kdb: Use the passed prompt in kdb_position_cursor()
+    - dmaengine: ti: k3-udma: Fix BCHAN count with UHC and HC channels
+    - phy: cadence-torrent: Check return value on register read
+    - phy: zynqmp: Enable reference clock correctly
+    - um: time-travel: fix time-travel-start option
+    - um: time-travel: fix signal blocking race/hang
+    - f2fs: fix start segno of large section
+    - watchdog: rzg2l_wdt: Use pm_runtime_resume_and_get()
+    - watchdog: rzg2l_wdt: Check return status of pm_runtime_put()
+    - f2fs: fix to update user block counts in block_operations()
+    - kbuild: avoid build error when single DTB is turned into composite DTB
+    - selftests/bpf: fexit_sleep: Fix stack allocation for arm64
+    - libbpf: Fix no-args func prototype BTF dumping syntax
+    - af_unix: Disable MSG_OOB handling for sockets in sockmap/sockhash
+    - dma: fix call order in dmam_free_coherent
+    - bpf, events: Use prog to emit ksymbol event for main program
+    - tools/resolve_btfids: Fix comparison of distinct pointer types warning in
+      resolve_btfids
+    - MIPS: SMP-CPS: Fix address for GCR_ACCESS register for CM3 and later
+    - ipv4: Fix incorrect source address in Record Route option
+    - net: bonding: correctly annotate RCU in bond_should_notify_peers()
+    - ice: Fix recipe read procedure
+    - netfilter: nft_set_pipapo_avx2: disable softinterrupts
+    - net: stmmac: Correct byte order of perfect_match
+    - net: nexthop: Initialize all fields in dumped nexthops
+    - bpf: Fix a segment issue when downgrading gso_size
+    - apparmor: Fix null pointer deref when receiving skb during sock creation
+    - powerpc: fix a file leak in kvm_vcpu_ioctl_enable_cap()
+    - lirc: rc_dev_get_from_fd(): fix file leak
+    - auxdisplay: ht16k33: Drop reference after LED registration
+    - ASoC: SOF: imx8m: Fix DSP control regmap retrieval
+    - spi: microchip-core: fix the issues in the isr
+    - spi: microchip-core: defer asserting chip select until just before write to
+      TX FIFO
+    - spi: microchip-core: only disable SPI controller when register value change
+      requires it
+    - spi: microchip-core: fix init function not setting the master and motorola
+      modes
+    - spi: microchip-core: ensure TX and RX FIFOs are empty at start of a transfer
+    - nvme-pci: Fix the instructions for disabling power management
+    - ASoC: sof: amd: fix for firmware reload failure in Vangogh platform
+    - spi: spidev: add correct compatible for Rohm BH2228FV
+    - ASoC: Intel: use soc_intel_is_byt_cr() only when IOSF_MBI is reachable
+    - ASoC: TAS2781: Fix tasdev_load_calibrated_data()
+    - ceph: fix incorrect kmalloc size of pagevec mempool
+    - s390/pci: Refactor arch_setup_msi_irqs()
+    - s390/pci: Allow allocation of more than 1 MSI interrupt
+    - s390/cpum_cf: Fix endless loop in CF_DIAG event stop
+    - iommu: sprd: Avoid NULL deref in sprd_iommu_hw_en
+    - io_uring: fix io_match_task must_hold
+    - nvme-pci: add missing condition check for existence of mapped data
+    - fs: don't allow non-init s_user_ns for filesystems without FS_USERNS_MOUNT
+    - md/raid0: don't free conf on raid0_run failure
+    - md/raid1: don't free conf on raid0_run failure
+    - io_uring: Fix probe of disabled operations
+    - cgroup/cpuset: Optimize isolated partition only generate_sched_domains()
+      calls
+    - cgroup/cpuset: Fix remote root partition creation problem
+    - x86/syscall: Mark exit[_group] syscall handlers __noreturn
+    - perf: arm_pmuv3: Avoid assigning fixed cycle counter with threshold
+    - md/raid5: recheck if reshape has finished with device_lock held
+    - hwmon: (ltc2991) re-order conditions to fix off by one bug
+    - arm64: smp: Fix missing IPI statistics
+    - arm64: dts: qcom: sc7280: Remove CTS/RTS configuration
+    - ARM: dts: qcom: msm8226-microsoft-common: Enable smbb explicitly
+    - OPP: Fix missing cleanup on error in _opp_attach_genpd()
+    - arm64: dts: qcom: sc8280xp-*: Remove thermal zone polling delays
+    - arm64: dts: ti: k3-am62-main: Fix the reg-range for main_pktdma
+    - arm64: dts: ti: k3-am62a-main: Fix the reg-range for main_pktdma
+    - arm64: dts: ti: k3-am62p-main: Fix the reg-range for main_pktdma
+    - arm64: dts: ti: k3-am62a7: Drop McASP AFIFOs
+    - arm64: dts: ti: k3-am62p5: Drop McASP AFIFOs
+    - arm64: dts: ti: k3-am62p5-sk: Fix pinmux for McASP1 TX
+    - arm64: dts: qcom: sc7180-trogdor: Disable pwmleds node where unused
+    - arm64: dts: mediatek: mt8192: Fix GPU thermal zone name for SVS
+    - arm64: dts: mediatek: mt8183-pico6: Fix wake-on-X event node names
+    - arm64: dts: renesas: r9a08g045: Add missing hypervisor virtual timer IRQ
+    - cpufreq/amd-pstate-ut: Convert nominal_freq to khz during comparisons
+    - wifi: mac80211: cancel multi-link reconf work on disconnect
+    - wifi: ath11k: refactor setting country code logic
+    - wifi: ath11k: restore country code during resume
+    - net: ethernet: cortina: Restore TSO support
+    - tcp: fix races in tcp_abort()
+    - hns3: avoid linking objects into multiple modules
+    - sched/core: Move preempt_model_*() helpers from sched.h to preempt.h
+    - sched/core: Drop spinlocks on contention iff kernel is preemptible
+    - net: dsa: ksz_common: Allow only up to two HSR HW offloaded ports for
+      KSZ9477
+    - libbpf: Skip base btf sanity checks
+    - wifi: mac80211: add ieee80211_tdls_sta_link_id()
+    - wifi: iwlwifi: fix iwl_mvm_get_valid_rx_ant()
+    - wifi: ath12k: advertise driver capabilities for MBSSID and EMA
+    - riscv, bpf: Fix out-of-bounds issue when preparing trampoline image
+    - perf/x86/amd/uncore: Avoid PMU registration if counters are unavailable
+    - perf/x86/amd/uncore: Fix DF and UMC domain identification
+    - NFSD: Fix nfsdcld warning
+    - net: page_pool: fix warning code
+    - bpf, arm64: Fix trampoline for BPF_TRAMP_F_CALL_ORIG
+    - Bluetooth: hci_event: Set QoS encryption from BIGInfo report
+    - Bluetooth: hci_core, hci_sync: cleanup struct discovery_state
+    - Bluetooth: Fix usage of __hci_cmd_sync_status
+    - tcp: Don't access uninit tcp_rsk(req)->ao_keyid in
+      tcp_create_openreq_child().
+    - drm/panel: ilitek-ili9882t: If prepare fails, disable GPIO before regulators
+    - drm/panel: ilitek-ili9882t: Check for errors on the NOP in prepare()
+    - drm/amd/display: Move 'struct scaler_data' off stack
+    - media: i2c: hi846: Fix V4L2_SUBDEV_FORMAT_TRY get_selection()
+    - drm/msm/dpu: fix encoder irq wait skip
+    - drm/msm/dpu: drop duplicate drm formats from wb2_formats arrays
+    - drm/msm/dp: fix runtime_pm handling in dp_wait_hpd_asserted
+    - perf maps: Switch from rbtree to lazily sorted array for addresses
+    - perf maps: Fix use after free in __maps__fixup_overlap_and_insert
+    - drm/bridge: samsung-dsim: Set P divider based on min/max of fin pll
+    - drm/i915/psr: Print Panel Replay status instead of frame lock status
+    - drm/mediatek: Set DRM mode configs accordingly
+    - drm/msm/dsi: set video mode widebus enable bit when widebus is enabled
+    - tools/perf: Fix the string match for "/tmp/perf-$PID.map" files in dso__load
+    - drm/amd/display: Add null check before access structs
+    - nfs: pass explicit offset/count to trace events
+    - PCI: endpoint: pci-epf-test: Make use of cached 'epc_features' in
+      pci_epf_test_core_init()
+    - PCI: tegra194: Set EP alignment restriction for inbound ATU
+    - riscv: smp: fail booting up smp if inconsistent vlen is detected
+    - clk: meson: s4: fix fixed_pll_dco clock
+    - clk: meson: s4: fix pwm_j_div parent clock
+    - usb: typec-mux: ptn36502: unregister typec switch on probe error and remove
+    - mtd: spi-nor: winbond: fix w25q128 regression
+    - iommufd/selftest: Fix dirty bitmap tests with u8 bitmaps
+    - iommufd/selftest: Fix iommufd_test_dirty() to handle <u8 bitmaps
+    - iommufd/selftest: Add tests for <= u8 bitmap sizes
+    - iommufd/selftest: Fix tests to use MOCK_PAGE_SIZE based buffer sizes
+    - iommufd/iova_bitmap: Check iova_bitmap_done() after set ahead
+    - clk: qcom: gcc-x1e80100: Fix halt_check for all pipe clocks
+    - dm-raid: Fix WARN_ON_ONCE check for sync_thread in raid_resume
+    - kvm: s390: Reject memory region operations for ucontrol VMs
+    - eeprom: ee1004: Call i2c_new_scanned_device to instantiate thermal sensor
+    - clk: qcom: gcc-x1e80100: Set parent rate for USB3 sec and tert PHY pipe clks
+    - workqueue: Introduce from_work() helper for cleaner callback declarations
+    - RDMA/hns: Fix mbx timing out before CMD execution is completed
+    - crypto: mxs-dcp - Ensure payload is zero when using key slot
+    - RDMA/mana_ib: Enable RoCE on port 1
+    - RDMA/mana_ib: set node_guid
+    - rtc: tps6594: Fix memleak in probe
+    - selftests/damon/access_memory: use user-defined region size
+    - md-cluster: fix hanging issue while a new disk adding
+    - power: supply: ab8500: Fix error handling when calling
+      iio_read_channel_processed()
+    - power: supply: ingenic: Fix some error handling paths in
+      ingenic_battery_get_property()
+    - remoteproc: mediatek: Don't attempt to remap l1tcm memory if missing
+    - remoteproc: k3-r5: Fix IPC-only mode detection
+    - mailbox: imx: fix TXDB_V2 channel race condition
+    - mailbox: mtk-cmdq: Move devm_mbox_controller_register() after
+      devm_pm_runtime_enable()
+    - mm: huge_memory: use !CONFIG_64BIT to relax huge page alignment on 32 bit
+      machines
+    - mm/huge_memory: avoid PMD-size page cache if needed
+    - thermal/drivers/broadcom: Fix race between removal and clock disable
+    - workqueue: Always queue work items to the newest PWQ for order workqueues
+    - ipv6: fix source address selection with route leak
+    - drm/xe: Use write-back caching mode for system memory on DGFX
+    - md/raid5: fix spares errors about rcu usage
+    - media: stm32: dcmipp: correct error handling in dcmipp_create_subdevs
+    - tpm_tis_spi: add missing attpm20p SPI device ID entry
+    - sysctl: always initialize i_uid/i_gid
+    - media: i2c: Kconfig: Fix missing firmware upload config select
+    - genirq: Set IRQF_COND_ONESHOT in request_irq()
+    - cpufreq: qcom-nvmem: fix memory leaks in probe error paths
+    - leds: triggers: Flush pending brightness before activating trigger
+    - media: i2c: alvium: Move V4L2_CID_GAIN to V4L2_CID_ANALOG_GAIN
+    - KVM: nVMX: Add a helper to get highest pending from Posted Interrupt vector
+    - KVM: nVMX: Check for pending posted interrupts when looking for nested
+      events
+    - ALSA: hda/realtek: cs35l41: Fixup remaining asus strix models
+    - fbdev: vesafb: Detect VGA compatibility from screen info's VESA attributes
+    - drm/fbdev-dma: Fix framebuffer mode for big endian devices
+    - xhci: Apply XHCI_RESET_TO_DEFAULT quirk to TGL
+    - dmaengine: fsl-edma: clean up unused "fsl,imx8qm-adma" compatible string
+    - dmaengine: fsl-edma: change the memory access from local into remote mode in
+      i.MX 8QM
+    - clk: samsung: fix getting Exynos4 fin_pll rate from external clocks
+    - bus: mhi: ep: Do not allocate memory for MHI objects from DMA zone
+    - ASoC: SOF: ipc4-topology: Use correct queue_id for requesting input pin
+      format
+    - arch: um: rust: Use the generated target.json again
+    - f2fs: fix null reference error when checking end of zone
+    - selftests: forwarding: skip if kernel not support setting bridge fdb
+      learning limit
+    - xsk: Require XDP_UMEM_TX_METADATA_LEN to actuate tx_metadata_len
+    - drm/xe/exec: Fix minor bug related to xe_sync_entry_cleanup
+    - thermal: trip: Split thermal_zone_device_set_mode()
+    - apparmor: unpack transition table if dfa is not present
+    - i3c: mipi-i3c-hci: Fix number of DAT/DCT entries for HCI versions < 1.1
+    - selinux,smack: remove the capability checks in the removexattr hooks
+    - selftests/bpf: DENYLIST.aarch64: Skip fexit_sleep again
+    - nilfs2: handle inconsistent state in nilfs_btnode_create_block()
+    - Upstream stable to v6.6.44, v6.10.3
+  * Noble update: upstream stable patchset 2024-09-30 (LP: #2083196) //
+    CVE-2024-42284
+    - tipc: Return non-zero value from tipc_udp_addr2str() on error
+  * CVE-2024-44987
+    - ipv6: prevent UAF in ip6_send_skb()
+  * CVE-2024-42301
+    - dev/parport: fix the array out-of-bounds risk
+  * CVE-2024-44998
+    - atm: idt77252: prevent use after free in dequeue_rx()
+
+  [ Ubuntu: 6.8.0-49.49 ]
+
+  * noble/linux: 6.8.0-49.49 -proposed tracker (LP: #2085942)
+  * CVE-2024-46800
+    - sch/netem: fix use after free in netem_dequeue
+  * mm/folios: xfs hangs with hung task timeouts with corrupted folio pointer
+    lists (LP: #2085495)
+    - lib/xarray: introduce a new helper xas_get_order
+    - mm/filemap: return early if failed to allocate memory for split
+    - mm/filemap: optimize filemap folio adding
+  * CVE-2024-43882
+    - exec: Fix ToCToU between perm check and set-uid/gid usage
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 04 Dec 2024 13:04:13 +0900
+
+linux-qcom (6.8.0-1014.14) jammy; urgency=medium
+
+  * [RB3] CONFIG_KASAN_GENERIC report potential memory bug in tc956x_pcie_eth
+    - SAUCE: ubuntu/qcom/qps615: suppress KASAN error
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: arm64: dts: qcom: remove redundant code in qcs6490.dtsi
+
+  * Miscellaneous upstream changes
+    - QCLINUX: data-eth: qps615: Properly set HW address assign type property
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 24 Oct 2024 22:10:11 +0900
+
+linux-qcom (6.8.0-1013.13) jammy; urgency=medium
+
+  * "[RB3] tc956x_pci-eth errors found in dmesg"
+    - SAUCE: ubuntu/qcom/qps615: suppress false alerts
+    - SAUCE: ubuntu/qcom/qps615: use INFO level for logging
+
+  * [RB3] drm sde error/ msm-dsi-error found in dmesg
+    - SAUCE: do not show error on EPROBE_DEFER
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: arm64: dts: qcom: enable WIFI
+    - SAUCE: import external DT from GA 1.2
+    - SAUCE: Add Makefile code to apply overlays for GA1.2
+    - SAUCE: ubuntu/qcom/display: import qcm6490 display code from GA1.2
+    - SAUCE: ubuntu/qcom/graphics: import qcm6490 graphics driver code from GA1.2
+    - SAUCE: ubuntu/qcom/camera: import qcm6490 camera driver code from GA1.2
+    - SAUCE: ubuntu/qcom/qps615: import ethernet driver from GA1.2
+    - SAUCE: ubuntu/qcom/video: import video driver from GA 1.2
+    - SAUCE: ubuntu/qcom/touch: import touch driver from GA 1.2
+    - SAUCE: ubuntu/qcom: build external drivers
+    - SAUCE: ubuntu/qcom/camera: fix build warnings and errors
+    - SAUCE: suppress unneeded build logs
+    - SAUCE: ubuntu/qcom: suppress warning and error
+    - SAUCE: ubuntu/qcom/graphics: change strtobool() to kstrtobool()
+    - SAUCE: ubuntu/qcom/graphics: dynamically allocate the kgsl-pool shrinker for
+      kernel>=6.7
+    - SAUCE: ubuntu/qcom/camera: remove unused camera_banner
+    - SAUCE: ubuntu/qcom/camera: use sizeof() instead of V4L2_SUBDEV_NAME_SIZE
+    - SAUCE: ubuntu/qcom/camera: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/video: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/touch: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: auto-load module
+    - SAUCE: ubuntu/qcom: add missing inclusion
+    - SAUCE: ubuntu/qcom/display: Rename min_buffers_needed to min_queued_buffers
+    - SAUCE: ubuntu/qcom: remove DRM_UNLOCKED
+    - SAUCE: ubuntu/qcom/display: suppress EPROBE_DEFER error log
+    - SAUCE: rename qcom,phy-rst-gpio to qcom,phy-rst-gpio-id
+    - SAUCE: Revert "PENDING: arm64: dts: qcom: qcs6490-rb3gen2: Enable IMX577
+      camera sensor"
+    - SAUCE: ASoC: wsa883x:  suppress noisy pr_err
+
+  * Miscellaneous upstream changes
+    - Revert "rpmsg: glink: Introduce packet tracepoints"
+    - PENDING: arm64: dts: qcom: sa8775p: add TBU support
+    - QCLINUX: coresight: add etr ATID filter function support
+    - PENDING: ASOC: WSA883X: Add swr slave dev number kcontrol
+    - FROMLIST: arm64: dts: qcom: sc7280: Add PCIe0 node
+    - QCLINUX: arm64: defconfig: qcom: Enable BT_BNEP
+    - QCLINUX: arm64: dts: qcom: sa8775p-ride: add board id and msm id support
+    - PENDING: coresight: tmc: Fix byte-cntr irq count mismatch issue
+    - QCLINUX: arm64: qcom_debug: Enable ATH trace
+    - QCLINUX: arm64: dts: qcom: sa8775p: Disable gunyah watchdog
+    - PENDING: arm64: dts: qcom: sa8775p: Add tz-log node
+    - QCLINUX: arm64: defconfig: qcom: Enable UINPUT
+    - PENDING: arm64: dts: qcom: sa8775: add QCrypto nodes
+    - PENDING: arm64: dts: qcom: sa8775p: add coresight components
+    - QCLINUX: arm64: dts: qcom: sa8775p: addons: add coresight components
+    - QCLINUX: net: can: Add support for mcp25xxfd driver
+    - BACKPORT: FROMLIST: wifi: ath11k: Add firmware coredump collection support
+    - QCLINUX: arm64: defconfig: Enable ATH reg setting
+    - PENDING: media: qcom: camss: Designate lite subdevices in resources
+    - PENDING: thermal: qcom: Add support for MBG Temp monitor
+    - FROMLIST: soc: qcom: icc-bwmon: Allow for interrupts to be shared across
+      instances
+    - PENDING: dt-bindings: iio: Add ADC5 GEN3 Channel macros
+    - PENDING: arm64: dts: qcom: sa8775p: Add cpu and llcc BWMON
+    - QCLINUX: ASoC: qcom: qcm6490: Add sound card compatible for qcs6490 rb3gen2
+      mezzanine boards
+    - QCLINUX: arm64: dts: qcom: qcm6490-rb3: Add uart4 node for RB3GEN2 video-
+      mezz
+    - BACKPORT: FROMLIST: iio: adc: Add support for QCOM PMIC5 Gen3 ADC
+    - PENDING: arm64: dts: qcom: sc7280: Add support for camss
+    - PENDING: arm64: dts: qcom: sa8775p: add remaining coresight components
+    - QCLINUX: arm64: dts: qcom: Remove iommu enc dec data from venus node
+    - PENDING: ARM: dts: qcom: Add support for MBG TM for pm8775
+    - PENDING: dt-bindings: clock: qcom: Add qdss_xo clock SA8775P
+    - PENDING: clk: qcom: Add support for qdss_xo clock for SA8775P
+    - PENDING: arm64: dts: qcom: sa8775p: add dma-coherent for smmu
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add dcc device tree node
+    - QCLINUX: arm64: dts: qcom: Add memory dump table on SA8775p
+    - PENDING: arm64: dts: qcom: sa8775p: Add fastrpc nsession property
+    - PENDING: arm64: dts: qcom: qcs6490-rb3gen2: Enable IMX577 camera sensor
+    - PENDING: i2c: Enable IMX577 camera sensor for qcm6490
+    - QCLINUX: arm64: defconfig: qcom: Enable IMX577 module support
+    - QCLINUX: arm64: qcom_debug: Enable ath11k coredump
+    - QCLINUX: ASoC: qcom: qcm6490: Update widgets for rb3gen2-ia-mezz board
+    - PENDING: misc: dcc: Fix invalid character issue
+    - QCLINUX: ASoC: qcm6490: Add sound card support for QCS9100
+    - PENDING: arm64: dts: qcom: sa8775p: add NSP0 fastrpc-compute-cb nodes
+    - QCLINUX: arm64: dts: qcom: Add board-id and msm-id for Rb3Gen2
+    - PENDING: arm64: dts: qcom: sa8775p: Add QFPROM node
+    - PENDING: arm64: dts: qcom: sa8775p: Correct the device name for TPDM and CTI
+    - QCLINUX: arm64: defconfig: Update memory configs
+    - PENDING: arm64: dts: qcom: sa8775p: Add memory region for audioPD
+    - FROMLIST: coresight: Add support to get preferred id for system trace
+      sources
+    - FROMLIST: coresight: dummy: Add reserve atid support for dummy source
+    - QCLINUX: virt: gunyah: Zero state_data after vcpu_run
+    - QCLINUX: arm64: defconfig: qcom: Enable MBG TM and ADC5 Gen3
+    - QCLINUX: arm64: dts: qcom: sa8775p: addons: Correct the device name for
+    - QCLINUX: arm64: dts: qcom: Add trace-id of modem_diag for qcm6490
+    - PENDING: misc: fastrpc: Fix registered buffer page address
+    - PENDING: arm64: dts: qcom: qcm6490: Use existing tcsr_2 node from sc7280
+    - PENDING: pinctrl: qcom: Add sa8775p lpass lpi pinctrl driver
+    - PENDING: opp: add a new helper set_opp api
+    - PENDING: can: mcp251xfd: enable CAN transceiver using gpio_0
+    - PENDING: arm64: config: Enable MCP251x CAN Device
+    - QCLINUX: ASoC: codecs: msm-stub: Add AIF2 dai support for LPI MI2S interface
+    - PENDING: arm64: dts: qcom: Add MCP251xFD CAN Controller
+    - PENDING: firmware: arm_scmi: add qcom smc xport descriptor
+    - QCLINUX: arm64: dts: qcom: sa8775p: Remove status override for watchdog node
+    - PENDING: arm64: dts: qcom: sc7280: Add device name for CTIs
+    - QCLINUX: arm64: defconfig: Enable LPASS LPI SA8775P pinctrl
+    - PENDING: crypto: qce - Add command descriptor support for crypto driver
+    - QCLINUX: usb: dwc3: core: Set driver data before core init
+    - QCLINUX: ASoC: qcom: qcm6490: Remove LPASS_CDC_DMA_TX3 dai id from
+      qcm6490_snd_init
+    - QCLINUX: ASoC: codecs: wcd937x: Add conditional regulator control for
+      wcd937x
+    - QCLINUX: coresight: tpdm: Correct the TPDA Key
+    - QCLINUX: arm64: dts: qcom: Bringup wcd9375 headphone on rb3gen2-ia-mezz
+      board
+    - PENDING: soc: qcom: socinfo: add SoC Info support for QCS9100 platform
+    - PENDING: dt-bindings: arm: qcom,ids: Add SoC ID for QCS9100
+    - PENDING: arm64: dts: qcom: sa8775p: Add gpr device tree node for ADSP
+    - PENDING: soc: qcom: socinfo: add SoC Info support for QCM6490 and QCS6490
+      platform
+    - PENDING: dt-bindings: arm: qcom,ids: Add SoC ID for QCM6490 and QCS6490
+    - PENDING: pinctrl: sa8775p: Update function and group binding
+    - QCLINUX: ASoC: qcom: qcm6490: Add AIF2 dapm pinctrl widget for QCS9100
+    - PENDING: arm64: dts: qcom: sa8775p: Add TCSR halt register space
+    - QCLINUX: soc: qcom: Update soc wdt node only for sc7280
+    - PENDING: arm64: qcom: dts: sa8775p: Add psci sys_reset2 modes
+    - QCLINUX: soc: qcom: Add documentation to align with code
+    - PENDING: arm64: dts: qcom: sa8775p: add rdbg nodes
+    - PENDING: gunyah: Add support for tracking Guest VM run time
+    - QCLINUX: arm64: dts: qcom: Add qcm6490 IDP dts file
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add lpass_tlmm node for lpi pinctrl
+    - PENDING: drivers: char: add remote debugger driver support for cDSP1
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add sound node for qcs9100 ridesx target
+    - PENDING: coresight: tmc: Remove duplicated ETR disable HW
+    - PENDING: arm64: dts: qcom: sc7280: Add msr properties to TPDMs
+    - QCLINUX: arm64: dts: qcom: Enable the uart for Rb3gen2-IA-MEZZ board
+    - QCLINUX: arm64: dts: qcom: Bring up LED-GPIO for Rb3gen2-IA-MEZZ board
+    - PENDING: ARM: dts: qcom: sa8775p: Update VADC interrupt-name
+    - QCLINUX: arm64: dts: qcom: Bring up I2C switch for Rb3gen2-IA-MEZZ board
+    - QCLINUX: arm64: deconfig: qcom: Enable vfio driver
+    - QCLINUX: arm64: deconfig: qcom: Enable mhi_bus_ep driver
+    - FROMLIST: iommu/arm-smmu-qcom: NULL pointer check for driver data
+    - QCLINUX: Revert "QCLINUX: net: can: Add support for mcp25xxfd driver"
+    - QCLINUX: qcom: tz_log: enable tz_log support hypervisor
+    - QCLINUX: coresight: Use desc name to get the CSR node
+    - QCLINUX: arm64: dts: qcom: Bring up TPM for Rb3gen2-IA-MEZZ board
+    - QCLINUX: arm64: defconfig: Enable NULL TTY for VM's
+    - QCLINUX: arm64: deconfig: qcom: disable smccc_trng driver
+    - QCLINUX: coresight: Enable ETR ATID filter for remote-etm
+    - PENDING: coresight: Disable RTB for coresight-stm
+    - PENDING: arm64: dts: qcom: sa8775p: Add protection-domain support for APM
+      and PRM
+    - PENDING: wifi: ath11k: fix vmalloc-out-of-bounds
+    - PENDING: arm64: dts: qcom: qcs6490-rb3gen2: Update the io-channels
+    - QCLINUX: arm64: defconfig: Remove unused VM config
+    - QCLINUX: coresight: Add extended CTI support
+    - QCLINUX: coresight: Remote-etm can probe successfully without ATID
+    - PENDING: iommu/arm-smmu-qcom: Fix compilation error
+    - QCLINUX: arm64: defconfig: Update VM memory and cpu configs
+    - QCLINUX: firmware: qcom_scm_addon:  Add qcom_she_op and
+      qcom_scm_ddrbw_profiler scm calls
+    - FROMLIST: arm64: dts: qcom: sa8775p: Add capacity and DPC properties
+    - QCLINUX: arm64: dts: restore wlan_ce_mem node
+    - QCLINUX: clk: qcom: dispcc1-sa8775p: Reparent dptx crypto RCG's to XO
+    - PENDING: arm64: dts: qcom: sa8775p: Correct the names of TPDMs
+    - PENDING: ath11k: Send pdev suspend before sending qmi mode off
+    - PENDING: dt-bindings: arm: qcom: add the SoC ID for SA8255P
+    - PENDING: soc: qcom: socinfo: add support for SA8255P
+    - PENDING: ARM64: dts: qcom: sa8775p: change camera PIL memory to 7MB
+    - PENDING: iommu/arm-smmu: add ACTLR data and support for sa8775p
+    - PENDING: arm64: dts: qcom: Add L3 interconnect device for SA8775P
+    - PENDING: interconnect: qcom: Add EPSS L3 support on SA8775P
+    - PENDING: usb: dwc3: Redesign flattening implementation
+    - PENDING: pinctrl: sa8775p: Add support for SA8255p SoC
+    - QCLINUX: smcinvoke: Add support hypervisor of shmbridge
+    - BACKPORT: wifi: mac80211: track capability/opmode NSS separately
+    - QCLINUX: drm/msm: Avoid probing gpu device
+    - QCLINUX: arm64: dts: qcom: sa8775p: addons: Enable byte-cntr for ETR1
+    - dt-bindings: net: Document QCA808x PHYs
+    - PENDING: dt-bindings: arm: qcom,ids: add SoC ID for QCS8300/QCS8275
+    - PENDING: soc: qcom: socinfo: add QCS8300/QCS8275 SoC ID
+    - PENDING: dt-bindings: pinctrl: describe qcs8300-tlmm
+    - PENDING: dt-bindings: qcom,pdc: document QCS8300 Power Domain Controller
+    - PENDING: arm64: dts: qcom: Add L3/DDR freq scaling from cpufreq on SA8775P
+    - QCLINUX: arm64: defconfig: qcom: Enable WLAN debug configs
+    - PENDING: pinctrl: qcom: add the tlmm driver for QCS8300 platforms
+    - FROMLIST: arm64: dts: qcom: sa8775p-ride: Add QCS9100 compatible
+    - PENDING: dt-bindings: clock: qcom: Add GCC clocks for QCS8300
+    - PENDING: clk: qcom: Add support for Global Clock Controller on QCS8300
+    - PENDING: dt-bindings: interconnect: Add Qualcomm QCS8300 DT bindings
+    - QCLINUX: arm64: defconfig: enable arm64 pmem
+    - PENDING: interconnect: qcom: add QCS8300 interconnect provider driver
+    - PENDING: dt-bindings: clock: qcom: Add GPU clocks for QCS8300
+    - PENDING: dt-bindings: power: qcom,rpmpd: document qcs8300
+    - PENDING: arm64: dts: qcom: Add static vote for SA8775P
+    - PENDING: arm64: dts: qcom: add initial support for QCS8300 DTSI
+    - PENDING: arm64: dts: qcom: add base QCS8300 RIDE dts
+    - QCLINUX: arm64: dts: qcom: Add addons support for QCS8300
+    - PENDING: arm64: dts: qcom: qcs8300: Add IMEM, PIL info and download mode
+      region
+    - QCLINUX: arm64: dts: qcom: qcs8300: define kaslr offset and mem dump table
+      regions
+    - QCLINUX: arm64: dts: qcom: qcs8300: addons: Add CSR device
+    - QCLINUX: arm64: deconfig: enable clock controller, interconnect and pinctrl
+      for QCS8300
+    - PENDING: soc: qcom: llcc: add errata to get bank num
+    - PENDING: soc: qcom: llcc: Add llcc configuration support for the QCS8300
+      platform
+    - PENDING:arm64: dts: qcom: qcs8300: Add qmp device nodes
+    - PENDING: arm64: dts: qcom: qcs8300: Add llcc support for the QCS8300
+      platform
+    - PENDING: drivers: phy: qualcomm: qmp-ufs qcs8300 compatible
+    - PENDING: dt-bindings: clock: qcom: Add CAMCC clocks for QCS8300
+    - QCLINUX: arm64: dts: qcom: Add qcs5430 dts support
+    - PENDING: arm64: dts: qcom: qcs8300: Add interconnect device nodes
+    - PENDING: arm64: dts: qcom: qcs8300: Add support for cpufreq hw
+    - QCLINUX: arm64: defconfig: Add Aquantia AQR115C config
+    - PENDING: net: stmmac: dwmac-qcom-ethqos: add support for emac4 on qcs8300
+      platforms
+    - PENDING: arm64: dts: qcom: qcs8300: add the SGMII PHY node
+    - FROMGIT: Bluetooth: SMP: Fix assumption of Central always being Initiator
+    - QCLINUX: arm64: dts: qcom: qcs8300: Add dma-buf heaps support
+    - PENDING: arm64: dts: qcom: qcs8300: add rpmhpd dts node
+    - PENDING: arm64: dts: qcom: qcs8300: Add regulators dts node
+    - PENDING: phy: qcom: add support for SGMII SerDes PHY on qcs8300 platform
+    - PENDING: clk: qcom: Add support for Camera Clock Controller on QCS8300
+    - PENDING: clk: qcom: Add support for GPU Clock Controller on QCS8300
+    - PENDING: arm64: dts: qcom: qcs8300: add coresight components
+    - QCLINUX: arm64: dts: qcom: qcs8300: Add dcc device tree node
+    - PENDING: arm64: dts: qcom: qcs8300: add the first 1Gb ethernet interface
+    - PENDING: arm64: dts: qcom: qcs8300-ride: enable the SerDes PHY
+    - PENDING: arm64: dts: qcom: qcs8300-ride: add pin functions for ethernet0
+    - PENDING: arm64: dts: qcom: qcs8300-ride: enable ethernet0
+    - PENDING: arm64: dts: qcom: qcs8300: add UFS nodes
+    - PENDING: arm64: dts: qcom: qcs8300: add the pcie smmu node
+    - PENDING: arm64: dts: qcom: qcs8300-ride: Add ufs mem
+    - PENDING: dmaengine: qcom: bam_dma: Correct descriptor FIFO size
+    - PENDING: arm64: dts: qcom: qcs8300: Add clock controllers support
+    - PENDING: remoteproc: qcom: pas: Add QCS8300 CDSP support
+    - PENDING: remoteproc: qcom: disable remoteproc auto boot for wpss
+    - PENDING: ARM: dt: add extended SPI specifier
+    - PENDING: arm64: dts: qcom: Add support for SA8255p Ride platform
+    - PENDING: arm64: dts: QCS8300: Add device node for gfx_smmu
+    - FROMLIST: misc: fastrpc: Add support for multiple PD from one process
+    - PENDING: arm64: dts: qcom: qcs8300: add CDSP support
+    - PENDING: arm64: dts: qcom: qcs8300-ride: enable CDSP for QCS8300
+    - PENDING: phy: qcom: Add support for eDP PHY on sa8775p
+    - PENDING: arm64: dts: qcom: qcs8300: add ADSP GPDSP support
+    - PENDING: arm64: dts: qcom: qcs8300-ride: enable ADSP GPDSP for QCS8300
+    - PENDING: arm64: dts: qcom: qcs8300: Add spmi bus
+    - QCLINUX: arm64: dts: qcom: qcs8300: addons: Add memory dump table
+    - PENDING: clk: qcom: gcc-qcs8300: Fixup the copyright
+    - PENDING: drm/msm/dp: Add DisplayPort controller for SA8775P
+    - PENDING: arm64: dts: qcom: mark ethernet devices as DMA-coherent
+    - PENDING: arm64: dts: qcom: sa8255p: enable safety IRQ
+    - PENDING: remoteproc: qcom: pas: Add QCS8300 ADSP GPDSP support
+    - FROMLIST: misc: fastrpc: Save actual DMA size in fastrpc_map structure
+    - FROMLIST: misc: fastrpc: Fix fastrpc_map_lookup operation
+    - FROMLIST: misc: fastrpc: Skip reference for DMA handles
+    - PENDING: phy: qcom: qmp: Add qmp conifguration for QCS8300
+    - PENDING: drm/msm: mdss: Add SA8775P support
+    - PENDING: drm/msm/dpu: Add SA8775P support
+    - QCLINUX: arm64: dts: qcom: qcm6490-rb3: Add uart4 node for RB3GEN2 vision-
+      mezz
+    - PENDING: arm64: dts: qcom: qcs8300: add "clock-names" property
+    - PENDING:wifi: ath11k: support DBS and DFS compatibility
+    - PENDING: pmdomain: qcom: rpmhpd: Add qcs8300 power domains
+    - QCLINUX: arm64: defconfig: Revert Add Aquantia AQR115C config
+    - QCLINUX: qcom: tz_log: differentiate hlos and hypversior of creating
+      shmbridge
+    - BACKPORT: FROMGIT: soc: qcom: smp2p: Introduce tracepoint support
+    - FROMLIST: wifi: ath11k: Fix double free issue during SRNG deinit
+    - PENDING: arm64: dts: qcom: Add support for usb nodes on QCS8300
+    - PENDING: arm64: dts: qcom: sa8775p: add display dt nodes
+    - QCLINUX: coresight: Correct the loglevel of the log info
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add spi dev node for qcs100 ridesx
+      target
+    - PENDING: arm64: dts: qcom: qcs8300: Add QUPv3 configuration
+    - PENDING: arm64: dts: qcom: sa8775p: Add DisplayPort device node
+    - PENDING: arm64: dts: qcom: Enable USB controllers for QCS8300
+    - PENDING: smcinvoke: Decrement the server object ref count in mutex context
+    - QCLINUX: defconfig: Enable SKBEDIT AND CLS TC utilities
+    - PENDING: coresight: tmc: flush remaining data when ETR is disabled
+    - QCLINUX: Revert "drivers: core: synchronize really_probe() and dev_uevent()"
+    - PENDING: drm/bridge: anx7625: change the gpio_set_value API
+    - PENDING: Bluetooth: mgmt: Verify cmd pending status before removing it
+    - PENDING: remoteproc: qcom: pas: fix QCS8300 GPDSP support
+    - PENDING: Bluetooth: mgmt: Verify command pending status before removing it
+    - QCLINUX: arm64: dts: qcom: sa8775p: Enable HS MI2S
+    - QCLINUX: ASoC: qcm6490: Add AIF0 and AIF3 for qcs9100
+    - QCLINUX: ASoC: codecs: msm-stub: Add AIF0 and AIF3 DAIs
+    - QCLINUX: ASoC: qcm6490: add macro and dcodec clk for qcs9100
+    - QCLINUX: arm64: dts: qcom: sa8775p: add dcodec and macro clk
+    - QCLINUX: arm64: dts: qcom: Add HSP dts support
+    - QCLINUX: arm64: dts: qcom: Add HSP BT dts support
+    - QCLINUX: arm64: dts: qcom: Disable MPSS on HSP dts
+    - QCLINUX: arm64: dts: qcom: Add PCIe node on HSP
+    - PENDING: arm64: dts: qcom: sc7280: add ICE node
+    - PENDING: qcom: ice: Remove ice probe
+    - QCLINUX: mmc: host: support wrapped keys in mmc
+    - PENDING: mmc: host: add support to derive software secret
+    - PENDING: mmc: host: add support for generate, import and prepare keys
+    - PENDING: mmc: host: wrapped keys support in mmc qcom
+    - PENDING: mmc: host: implement derive sw secret vop in mmc qcom
+    - PENDING: mmc: host: support for generate, import and prepare key
+    - PENDING: arm64: defconfig: qcom: Enable MMC crypto
+    - QCLINUX: net: qrtr: mhi: synchronize qrtr and mhi preparation
+    - PENDING: ath11k: Fix CE offset address calculation for WCN6750 in SSR
+    - QCLINUX: rpmsg: glink: multi enter for unregister path
+    - PENDING: arm64: dts: qcom: sa8775p: Update memory map for SA8775P
+    - Ubuntu: [Config] update CONFIG options for GA 1.2
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 18 Oct 2024 18:49:17 +0900
+
+linux-qcom (6.8.0-1012.12) jammy; urgency=medium
+
+  * perf build disables tracepoint support (LP: #2076190)
+    - [Packaging] add libtraceevent as dependency
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 04 Oct 2024 12:13:50 +0900
+
+linux-qcom (6.8.0-1011.11) jammy; urgency=medium
+
+  * "[RB3] tc956x_pci-eth errors found in dmesg"
+    - SAUCE: ubuntu/qcom/qps615: suppress false alerts
+    - SAUCE: ubuntu/qcom/qps615: use INFO level for logging
+
+  * "[RB3] slim-ngd-ctrl error found in dmesg"
+    - SAUCE: qcom-ngd-ctrl: suppress "QMI handle is NULL" error
+    - SAUCE: qcom-ngd-ctrl: fix race condition for completion
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] remove modules-extra package
+
+  [ Ubuntu: 6.8.0-48.48 ]
+
+  * noble/linux: 6.8.0-48.48 -proposed tracker (LP: #2082437)
+  * [SRU][Noble] Bad EPP defaults cause performance regressions on select Intel
+    CPUs (LP: #2077470)
+    - x86/cpu/vfm: Update arch/x86/include/asm/intel-family.h
+    - cpufreq: intel_pstate: Allow model specific EPPs
+    - cpufreq: intel_pstate: Update default EPPs for Meteor Lake
+    - cpufreq: intel_pstate: Switch to new Intel CPU model defines
+    - cpufreq: intel_pstate: Update Meteor Lake EPPs
+    - cpufreq: intel_pstate: Use Meteor Lake EPPs for Arrow Lake
+    - cpufreq: intel_pstate: Update Balance performance EPP for Emerald Rapids
+  * power: Enable intel_rapl driver (LP: #2078834)
+    - powercap: intel_rapl: Add support for ArrowLake-H platform
+  * x86/vmware: Add TDX hypercall support (LP: #2077729)
+    - x86/vmware: Introduce VMware hypercall API
+    - x86/vmware: Add TDX hypercall support
+  * Guest crashes post migration with migrate_misplaced_folio+0x4cc/0x5d0
+    (LP: #2076866)
+    - mm/mempolicy: use numa_node_id() instead of cpu_to_node()
+    - mm/numa_balancing: allow migrate on protnone reference with
+      MPOL_PREFERRED_MANY policy
+    - mm: convert folio_estimated_sharers() to folio_likely_mapped_shared()
+    - mm: factor out the numa mapping rebuilding into a new helper
+    - mm: support multi-size THP numa balancing
+    - mm/migrate: make migrate_misplaced_folio() return 0 on success
+    - mm/migrate: move NUMA hinting fault folio isolation + checks under PTL
+    - mm: fix possible OOB in numa_rebuild_large_mapping()
+  * Add 'mm: hold PTL from the first PTE while reclaiming a large folio' to fix
+    L2 Guest hang during LTP Test (LP: #2076147)
+    - mm: hold PTL from the first PTE while reclaiming a large folio
+  * KOP L2 guest fails to boot with 1 core - SMT8 topology (LP: #2070329)
+    - KVM: PPC: Book3S HV nestedv2: Add DPDES support in helper library for Guest
+      state buffer
+    - KVM: PPC: Book3S HV nestedv2: Fix doorbell emulation
+  * L2 Guest migration: continuously dumping while running NFS guest migration
+    (LP: #2076406)
+    - KVM: PPC: Book3S HV: Fix the set_one_reg for MMCR3
+    - KVM: PPC: Book3S HV: Fix the get_one_reg of SDAR
+    - KVM: PPC: Book3S HV: Add one-reg interface for DEXCR register
+    - KVM: PPC: Book3S HV nestedv2: Keep nested guest DEXCR in sync
+    - KVM: PPC: Book3S HV: Add one-reg interface for HASHKEYR register
+    - KVM: PPC: Book3S HV nestedv2: Keep nested guest HASHKEYR in sync
+    - KVM: PPC: Book3S HV: Add one-reg interface for HASHPKEYR register
+    - KVM: PPC: Book3S HV nestedv2: Keep nested guest HASHPKEYR in sync
+  * perf build disables tracepoint support (LP: #2076190)
+    - [Packaging] perf: reenable libtraceevent
+  * Please backport the more restrictive XSAVES deactivation for  Zen1/2 arch
+    (LP: #2077321)
+    - x86/CPU/AMD: Improve the erratum 1386 workaround
+  * Fix alsa scarlett2 driver in 6.8  (LP: #2076402)
+    - ALSA: scarlett2: Move initialisation code lower in the source
+    - ALSA: scarlett2: Implement handling of the ACK notification
+  * rtw89: reset IDMEM mode to prevent download firmware failure (LP: #2077396)
+    - wifi: rtw89: 885xb: reset IDMEM mode to prevent download firmware failure
+  * CVE-2024-43858
+    - jfs: Fix array-index-out-of-bounds in diFree
+  * CVE-2024-42280
+    - mISDN: Fix a use after free in hfcmulti_tx()
+  * CVE-2024-42271
+    - net/iucv: fix use after free in iucv_sock_close()
+  * [Ubuntu-24.04] FADump with recommended crash size is making the L1 hang
+    (LP: #2060039)
+    - powerpc/64s/radix/kfence: map __kfence_pool at page granularity
+  * Noble update: upstream stable patchset 2024-09-09 (LP: #2079945)
+    - ocfs2: add bounds checking to ocfs2_check_dir_entry()
+    - jfs: don't walk off the end of ealist
+    - fs/ntfs3: Add a check for attr_names and oatbl
+    - fs/ntfs3: Validate ff offset
+    - usb: gadget: midi2: Fix incorrect default MIDI2 protocol setup
+    - ALSA: hda/realtek: Enable headset mic on Positivo SU C1400
+    - ALSA: hda/realtek: Fix the speaker output on Samsung Galaxy Book Pro 360
+    - arm64: dts: qcom: qrb4210-rb2: switch I2C2 to i2c-gpio
+    - arm64: dts: qcom: msm8996: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: sm6350: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: ipq6018: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: sdm630: Disable SS instance in Parkmode for USB
+    - ALSA: pcm_dmaengine: Don't synchronize DMA channel when DMA is paused
+    - ALSA: seq: ump: Skip useless ports for static blocks
+    - filelock: Fix fcntl/close race recovery compat path
+    - tun: add missing verification for short frame
+    - tap: add missing verification for short frame
+    - s390/mm: Fix VM_FAULT_HWPOISON handling in do_exception()
+    - ALSA: hda/tas2781: Add new quirk for Lenovo Hera2 Laptop
+    - arm64: dts: qcom: sc7180: Disable SuperSpeed instances in park mode
+    - arm64: dts: qcom: sc7280: Disable SuperSpeed instances in park mode
+    - arm64: dts: qcom: qrb2210-rb1: switch I2C2 to i2c-gpio
+    - arm64: dts: qcom: msm8998: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: ipq8074: Disable SS instance in Parkmode for USB
+    - arm64: dts: qcom: sdm845: Disable SS instance in Parkmode for USB
+    - Upstream stable to v6.6.43, v6.9.12
+  * Noble update: upstream stable patchset 2024-09-02 (LP: #2078304)
+    - filelock: Remove locks reliably when fcntl/close race is detected
+    - scsi: core: alua: I/O errors for ALUA state transitions
+    - scsi: sr: Fix unintentional arithmetic wraparound
+    - scsi: qedf: Don't process stag work during unload and recovery
+    - scsi: qedf: Wait for stag work during unload
+    - scsi: qedf: Set qed_slowpath_params to zero before use
+    - efi/libstub: zboot.lds: Discard .discard sections
+    - ACPI: EC: Abort address space access upon error
+    - ACPI: EC: Avoid returning AE_OK on errors in address space handler
+    - tools/power/cpupower: Fix Pstate frequency reporting on AMD Family 1Ah CPUs
+    - wifi: mac80211: mesh: init nonpeer_pm to active by default in mesh sdata
+    - wifi: mac80211: apply mcast rate only if interface is up
+    - wifi: mac80211: handle tasklet frames before stopping
+    - wifi: cfg80211: fix 6 GHz scan request building
+    - wifi: iwlwifi: mvm: d3: fix WoWLAN command version lookup
+    - wifi: iwlwifi: mvm: remove stale STA link data during restart
+    - wifi: iwlwifi: mvm: Handle BIGTK cipher in kek_kck cmd
+    - wifi: iwlwifi: mvm: handle BA session teardown in RF-kill
+    - wifi: iwlwifi: mvm: properly set 6 GHz channel direct probe option
+    - wifi: iwlwifi: mvm: Fix scan abort handling with HW rfkill
+    - wifi: mac80211: fix UBSAN noise in ieee80211_prep_hw_scan()
+    - selftests: cachestat: Fix build warnings on ppc64
+    - selftests/openat2: Fix build warnings on ppc64
+    - selftests/futex: pass _GNU_SOURCE without a value to the compiler
+    - of/irq: Factor out parsing of interrupt-map parent phandle+args from
+      of_irq_parse_raw()
+    - Input: silead - Always support 10 fingers
+    - net: ipv6: rpl_iptunnel: block BH in rpl_output() and rpl_input()
+    - ila: block BH in ila_output()
+    - arm64: armv8_deprecated: Fix warning in isndep cpuhp starting process
+    - null_blk: fix validation of block size
+    - kconfig: gconf: give a proper initial state to the Save button
+    - kconfig: remove wrong expr_trans_bool()
+    - input: Add event code for accessibility key
+    - input: Add support for "Do Not Disturb"
+    - HID: Ignore battery for ELAN touchscreens 2F2C and 4116
+    - NFSv4: Fix memory leak in nfs4_set_security_label
+    - nfs: propagate readlink errors in nfs_symlink_filler
+    - nfs: Avoid flushing many pages with NFS_FILE_SYNC
+    - nfs: don't invalidate dentries on transient errors
+    - cachefiles: add consistency check for copen/cread
+    - cachefiles: Set object to close if ondemand_id < 0 in copen
+    - cachefiles: make on-demand read killable
+    - fs/file: fix the check in find_next_fd()
+    - mei: demote client disconnect warning on suspend to debug
+    - iomap: Fix iomap_adjust_read_range for plen calculation
+    - drm/exynos: dp: drop driver owner initialization
+    - drm: panel-orientation-quirks: Add quirk for Aya Neo KUN
+    - drm/mediatek: Call drm_atomic_helper_shutdown() at shutdown time
+    - nvme: avoid double free special payload
+    - nvmet: always initialize cqe.result
+    - ALSA: hda: cs35l56: Fix lifecycle of codec pointer
+    - wifi: cfg80211: wext: add extra SIOCSIWSCAN data check
+    - ALSA: hda/realtek: Support Lenovo Thinkbook 16P Gen 5
+    - KVM: PPC: Book3S HV: Prevent UAF in kvm_spapr_tce_attach_iommu_group()
+    - drm/vmwgfx: Fix missing HYPERVISOR_GUEST dependency
+    - ALSA: hda/realtek: Add more codec ID to no shutup pins list
+    - spi: Fix OCTAL mode support
+    - cpumask: limit FORCE_NR_CPUS to just the UP case
+    - [Config] Remove FORCE_NR_CPUS
+    - selftests: openvswitch: Set value to nla flags.
+    - drm/amdgpu: Indicate CU havest info to CP
+    - ALSA: hda: cs35l56: Select SERIAL_MULTI_INSTANTIATE
+    - mips: fix compat_sys_lseek syscall
+    - Input: elantech - fix touchpad state on resume for Lenovo N24
+    - Input: i8042 - add Ayaneo Kun to i8042 quirk table
+    - ASoC: rt722-sdca-sdw: add silence detection register as volatile
+    - Input: xpad - add support for ASUS ROG RAIKIRI PRO
+    - ASoC: topology: Fix references to freed memory
+    - ASoC: topology: Do not assign fields that are already set
+    - bytcr_rt5640 : inverse jack detect for Archos 101 cesium
+    - ALSA: dmaengine: Synchronize dma channel after drop()
+    - ASoC: ti: davinci-mcasp: Set min period size using FIFO config
+    - ASoC: ti: omap-hdmi: Fix too long driver name
+    - ASoC: SOF: sof-audio: Skip unprepare for in-use widgets on error rollback
+    - ASoC: rt722-sdca-sdw: add debounce time for type detection
+    - nvme: fix NVME_NS_DEAC may incorrectly identifying the disk as EXT_LBA.
+    - Input: ads7846 - use spi_device_id table
+    - can: kvaser_usb: fix return value for hif_usb_send_regout
+    - gpio: pca953x: fix pca953x_irq_bus_sync_unlock race
+    - octeontx2-pf: Fix coverity and klockwork issues in octeon PF driver
+    - s390/sclp: Fix sclp_init() cleanup on failure
+    - platform/mellanox: nvsw-sn2201: Add check for platform_device_add_resources
+    - platform/x86: wireless-hotkey: Add support for LG Airplane Button
+    - platform/x86: lg-laptop: Remove LGEX0815 hotkey handling
+    - platform/x86: lg-laptop: Change ACPI device id
+    - platform/x86: lg-laptop: Use ACPI device handle when evaluating WMAB/WMBB
+    - btrfs: qgroup: fix quota root leak after quota disable failure
+    - ibmvnic: Add tx check to prevent skb leak
+    - ALSA: PCM: Allow resume only for suspended streams
+    - ALSA: hda/relatek: Enable Mute LED on HP Laptop 15-gw0xxx
+    - ALSA: dmaengine_pcm: terminate dmaengine before synchronize
+    - ASoC: amd: yc: Fix non-functional mic on ASUS M5602RA
+    - net: usb: qmi_wwan: add Telit FN912 compositions
+    - net: mac802154: Fix racy device stats updates by DEV_STATS_INC() and
+      DEV_STATS_ADD()
+    - powerpc/pseries: Whitelist dtl slub object for copying to userspace
+    - powerpc/eeh: avoid possible crash when edev->pdev changes
+    - scsi: libsas: Fix exp-attached device scan after probe failure scanned in
+      again after probe failed
+    - tee: optee: ffa: Fix missing-field-initializers warning
+    - Bluetooth: hci_core: cancel all works upon hci_unregister_dev()
+    - Bluetooth: btnxpuart: Enable Power Save feature on startup
+    - bluetooth/l2cap: sync sock recv cb and release
+    - erofs: ensure m_llen is reset to 0 if metadata is invalid
+    - drm/amd/display: Add refresh rate range check
+    - drm/amd/display: Account for cursor prefetch BW in DML1 mode support
+    - drm/amd/display: Fix refresh rate range for some panel
+    - drm/radeon: check bo_va->bo is non-NULL before using it
+    - fs: better handle deep ancestor chains in is_subdir()
+    - wifi: iwlwifi: properly set WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK
+    - drivers/perf: riscv: Reset the counter to hpmevent mapping while starting
+      cpus
+    - riscv: stacktrace: fix usage of ftrace_graph_ret_addr()
+    - spi: imx: Don't expect DMA for i.MX{25,35,50,51,53} cspi devices
+    - ksmbd: return FILE_DEVICE_DISK instead of super magic
+    - ASoC: SOF: Intel: hda-pcm: Limit the maximum number of periods by
+      MAX_BDL_ENTRIES
+    - selftest/timerns: fix clang build failures for abs() calls
+    - selftests/vDSO: fix clang build errors and warnings
+    - hfsplus: fix uninit-value in copy_name
+    - selftests/bpf: Extend tcx tests to cover late tcx_entry release
+    - spi: mux: set ctlr->bits_per_word_mask
+    - ALSA: hda: Use imply for suggesting CONFIG_SERIAL_MULTI_INSTANTIATE
+    - [Config] Update CONFIG_SERIAL_MULTI_INSTANTIATE
+    - cifs: fix noisy message on copy_file_range
+    - Bluetooth: L2CAP: Fix deadlock
+    - of/irq: Disable "interrupt-map" parsing for PASEMI Nemo
+    - wifi: cfg80211: wext: set ssids=NULL for passive scans
+    - wifi: mac80211: disable softirqs for queued frame handling
+    - wifi: iwlwifi: mvm: don't wake up rx_sync_waitq upon RFKILL
+    - cachefiles: fix slab-use-after-free in fscache_withdraw_volume()
+    - cachefiles: fix slab-use-after-free in cachefiles_withdraw_cookie()
+    - btrfs: ensure fast fsync waits for ordered extents after a write failure
+    - PNP: Hide pnp_bus_type from the non-PNP code
+    - ACPI: AC: Properly notify powermanagement core about changes
+    - selftests/overlayfs: Fix build error on ppc64
+    - nvme-fabrics: use reserved tag for reg read/write command
+    - LoongArch: Fix GMAC's phy-mode definitions in dts
+    - io_uring: fix possible deadlock in io_register_iowq_max_workers()
+    - vfio: Create vfio_fs_type with inode per device
+    - vfio/pci: Use unmap_mapping_range()
+    - parport: amiga: Mark driver struct with __refdata to prevent section
+      mismatch
+    - drm: renesas: shmobile: Call drm_atomic_helper_shutdown() at shutdown time
+    - vfio/pci: Insert full vma on mmap'd MMIO fault
+    - ALSA: hda: cs35l41: Support Lenovo Thinkbook 16P Gen 5
+    - ALSA: hda: cs35l41: Support Lenovo Thinkbook 13x Gen 4
+    - ALSA: hda/realtek: Support Lenovo Thinkbook 13x Gen 4
+    - wifi: mac80211: Avoid address calculations via out of bounds array indexing
+    - drm/amd/display: change dram_clock_latency to 34us for dcn35
+    - closures: Change BUG_ON() to WARN_ON()
+    - ASoC: codecs: ES8326: Solve headphone detection issue
+    - ASoC: Intel: avs: Fix route override
+    - net: mvpp2: fill-in dev_port attribute
+    - btrfs: scrub: handle RST lookup error correctly
+    - clk: qcom: apss-ipq-pll: remove 'config_ctl_hi_val' from Stromer pll configs
+    - drm/amd/display: Update efficiency bandwidth for dcn351
+    - drm/amd/display: Fix array-index-out-of-bounds in dml2/FCLKChangeSupport
+    - btrfs: fix uninitialized return value in the ref-verify tool
+    - spi: davinci: Unset POWERDOWN bit when releasing resources
+    - mm: page_ref: remove folio_try_get_rcu()
+    - ALSA: hda: cs35l41: Fix swapped l/r audio channels for Lenovo ThinBook 13x
+      Gen4
+    - netfs, fscache: export fscache_put_volume() and add fscache_try_get_volume()
+    - Upstream stable to v6.6.42, v6.9.11
+  * CVE-2024-27022
+    - Revert "Revert "fork: defer linking file vma until vma is fully
+      initialized""
+  * UBSAN: array-index-out-of-bounds in /build/linux-Z1RxaK/linux-
+    6.8.0/drivers/gpu/drm/amd/amdgpu/../pm/powerplay/hwmgr/processpptables.c:124
+    9:61 (LP: #2078041)
+    - drm/amdgpu/pptable: convert some variable sized arrays to [] style
+    - drm/amdgpu: convert some variable sized arrays to [] style
+    - drm/amdgpu/pptable: Fix UBSAN array-index-out-of-bounds
+  * alsa: Headphone and Speaker couldn't output sound intermittently
+    (LP: #2077690)
+    - ALSA: hda/realtek - Fixed ALC256 headphone no sound
+    - ALSA: hda/realtek - FIxed ALC285 headphone no sound
+  * Fix ethernet performance on JSL and EHL (LP: #2077858)
+    - intel_idle: Disable promotion to C1E on Jasper Lake and Elkhart Lake
+  * Noble update: upstream stable patchset 2024-08-29 (LP: #2078289)
+    - Revert "usb: xhci: prevent potential failure in handle_tx_event() for
+      Transfer events without TRB"
+    - Compiler Attributes: Add __uninitialized macro
+    - mm: prevent derefencing NULL ptr in pfn_section_valid()
+    - scsi: ufs: core: Fix ufshcd_clear_cmd racing issue
+    - scsi: ufs: core: Fix ufshcd_abort_one racing issue
+    - vfio/pci: Init the count variable in collecting hot-reset devices
+    - cachefiles: propagate errors from vfs_getxattr() to avoid infinite loop
+    - cachefiles: stop sending new request when dropping object
+    - cachefiles: cancel all requests for the object that is being dropped
+    - cachefiles: wait for ondemand_object_worker to finish when dropping object
+    - cachefiles: cyclic allocation of msg_id to avoid reuse
+    - cachefiles: add missing lock protection when polling
+    - dsa: lan9303: Fix mapping between DSA port number and PHY address
+    - filelock: fix potential use-after-free in posix_lock_inode
+    - fs/dcache: Re-use value stored to dentry->d_flags instead of re-reading
+    - vfs: don't mod negative dentry count when on shrinker list
+    - net: bcmasp: Fix error code in probe()
+    - tcp: fix incorrect undo caused by DSACK of TLP retransmit
+    - bpf: Fix too early release of tcx_entry
+    - net: phy: microchip: lan87xx: reinit PHY after cable test
+    - skmsg: Skip zero length skb in sk_msg_recvmsg
+    - octeontx2-af: Fix incorrect value output on error path in
+      rvu_check_rsrc_availability()
+    - net: fix rc7's __skb_datagram_iter()
+    - i40e: Fix XDP program unloading while removing the driver
+    - net: ethernet: lantiq_etop: fix double free in detach
+    - bpf: fix order of args in call to bpf_map_kvcalloc
+    - bpf: make timer data struct more generic
+    - bpf: replace bpf_timer_init with a generic helper
+    - bpf: Fail bpf_timer_cancel when callback is being cancelled
+    - net: ethernet: mtk-star-emac: set mac_managed_pm when probing
+    - ppp: reject claimed-as-LCP but actually malformed packets
+    - ethtool: netlink: do not return SQI value if link is down
+    - udp: Set SOCK_RCU_FREE earlier in udp_lib_get_port().
+    - net, sunrpc: Remap EPERM in case of connection failure in
+      xs_tcp_setup_socket
+    - s390: Mark psw in __load_psw_mask() as __unitialized
+    - arm64: dts: qcom: sc8180x: Fix LLCC reg property again
+    - firmware: cs_dsp: Fix overflow checking of wmfw header
+    - firmware: cs_dsp: Return error if block header overflows file
+    - firmware: cs_dsp: Validate payload length before processing block
+    - firmware: cs_dsp: Prevent buffer overrun when processing V2 alg headers
+    - ASoC: SOF: Intel: hda: fix null deref on system suspend entry
+    - firmware: cs_dsp: Use strnlen() on name fields in V1 wmfw files
+    - ARM: davinci: Convert comma to semicolon
+    - octeontx2-af: replace cpt slot with lf id on reg write
+    - octeontx2-af: fix a issue with cpt_lf_alloc mailbox
+    - octeontx2-af: fix detection of IP layer
+    - octeontx2-af: fix issue with IPv6 ext match for RSS
+    - octeontx2-af: fix issue with IPv4 match for RSS
+    - cifs: fix setting SecurityFlags to true
+    - Revert "sched/fair: Make sure to try to detach at least one movable task"
+    - tcp: avoid too many retransmit packets
+    - net: ks8851: Fix deadlock with the SPI chip variant
+    - net: ks8851: Fix potential TX stall after interface reopen
+    - USB: serial: option: add Telit generic core-dump composition
+    - USB: serial: option: add Telit FN912 rmnet compositions
+    - USB: serial: option: add Fibocom FM350-GL
+    - USB: serial: option: add support for Foxconn T99W651
+    - USB: serial: option: add Netprisma LCUK54 series modules
+    - USB: serial: option: add Rolling RW350-GL variants
+    - USB: serial: mos7840: fix crash on resume
+    - USB: Add USB_QUIRK_NO_SET_INTF quirk for START BP-850k
+    - usb: dwc3: pci: add support for the Intel Panther Lake
+    - usb: gadget: configfs: Prevent OOB read/write in usb_string_copy()
+    - USB: core: Fix duplicate endpoint bug by clearing reserved bits in the
+      descriptor
+    - misc: microchip: pci1xxxx: Fix return value of nvmem callbacks
+    - hpet: Support 32-bit userspace
+    - xhci: always resume roothubs if xHC was reset during resume
+    - s390/mm: Add NULL pointer check to crst_table_free() base_crst_free()
+    - mm: vmalloc: check if a hash-index is in cpu_possible_mask
+    - mm/filemap: skip to create PMD-sized page cache if needed
+    - mm/filemap: make MAX_PAGECACHE_ORDER acceptable to xarray
+    - ksmbd: discard write access to the directory open
+    - iio: trigger: Fix condition for own trigger
+    - arm64: dts: qcom: sa8775p: Correct IRQ number of EL2 non-secure physical
+      timer
+    - arm64: dts: qcom: sc8280xp-x13s: fix touchscreen power on
+    - nvmem: rmem: Fix return value of rmem_read()
+    - nvmem: meson-efuse: Fix return value of nvmem callbacks
+    - nvmem: core: only change name to fram for current attribute
+    - platform/x86: toshiba_acpi: Fix array out-of-bounds access
+    - tty: serial: ma35d1: Add a NULL check for of_node
+    - ALSA: hda/realtek: add quirk for Clevo V5[46]0TU
+    - ALSA: hda/realtek: Enable Mute LED on HP 250 G7
+    - ALSA: hda/realtek: Limit mic boost on VAIO PRO PX
+    - Fix userfaultfd_api to return EINVAL as expected
+    - pmdomain: qcom: rpmhpd: Skip retention level for Power Domains
+    - libceph: fix race between delayed_work() and ceph_monc_stop()
+    - ACPI: processor_idle: Fix invalid comparison with insertion sort for latency
+    - cpufreq: ACPI: Mark boost policy as enabled when setting boost
+    - cpufreq: Allow drivers to advertise boost enabled
+    - wireguard: selftests: use acpi=off instead of -no-acpi for recent QEMU
+    - wireguard: allowedips: avoid unaligned 64-bit memory accesses
+    - wireguard: queueing: annotate intentional data race in cpu round robin
+    - wireguard: send: annotate intentional data race in checking empty queue
+    - misc: fastrpc: Fix DSP capabilities request
+    - misc: fastrpc: Avoid updating PD type for capability request
+    - misc: fastrpc: Copy the complete capability structure to user
+    - misc: fastrpc: Fix memory leak in audio daemon attach operation
+    - misc: fastrpc: Fix ownership reassignment of remote heap
+    - misc: fastrpc: Restrict untrusted app to attach to privileged PD
+    - mm/shmem: disable PMD-sized page cache if needed
+    - mm/damon/core: merge regions aggressively when max_nr_regions is unmet
+    - selftests/net: fix gro.c compilation failure due to non-existent
+      opt_ipproto_off
+    - ext4: avoid ptr null pointer dereference
+    - sched: Move psi_account_irqtime() out of update_rq_clock_task() hotpath
+    - i2c: rcar: bring hardware to known state when probing
+    - i2c: mark HostNotify target address as used
+    - i2c: rcar: ensure Gen3+ reset does not disturb local targets
+    - i2c: testunit: avoid re-issued work after read message
+    - i2c: rcar: clear NO_RXDMA flag after resetting
+    - x86/bhi: Avoid warning in #DB handler due to BHI mitigation
+    - kbuild: Make ld-version.sh more robust against version string changes
+    - spi: axi-spi-engine: fix sleep calculation
+    - minixfs: Fix minixfs_rename with HIGHMEM
+    - bpf: Defer work in bpf_timer_cancel_and_free
+    - netfilter: nf_tables: prefer nft_chain_validate
+    - arm64: dts: qcom: x1e80100-*: Allocate some CMA buffers
+    - arm64: dts: qcom: sm6115: add iommu for sdhc_1
+    - arm64: dts: qcom: qdu1000: Fix LLCC reg property
+    - net: ethtool: Fix RSS setting
+    - nilfs2: fix kernel bug on rename operation of broken directory
+    - cachestat: do not flush stats in recency check
+    - mm: fix crashes from deferred split racing folio migration
+    - nvmem: core: limit cell sysfs permissions to main attribute ones
+    - serial: imx: ensure RTS signal is not left active after shutdown
+    - mmc: sdhci: Fix max_seg_size for 64KiB PAGE_SIZE
+    - mmc: davinci_mmc: Prevent transmitted data size from exceeding sgm's length
+    - mm/readahead: limit page cache size in page_cache_ra_order()
+    - Revert "dt-bindings: cache: qcom,llcc: correct QDU1000 reg entries"
+    - sched/deadline: Fix task_struct reference leak
+    - Upstream stable to v6.6.40, v6.6.41, v6.9.10
+  * [SRU][HPE 24.04] Intel FVL NIC FW flash fails with inbox driver, causing
+    driver not detected (LP: #2076675) // Noble update: upstream stable patchset
+    2024-08-29 (LP: #2078289)
+    - i40e: fix: remove needless retries of NVM update
+  * CVE-2024-41022
+    - drm/amdgpu: Fix signedness bug in sdma_v4_0_process_trap_irq()
+  *  Deadlock occurs while suspending md raid  (LP: #2073695)
+    - md: change the return value type of md_write_start to void
+    - md: fix deadlock between mddev_suspend and flush bio
+  * Lenovo X12 Detachable Gen 2 unresponsive under light load (LP: #2076361)
+    - drm/i915: Enable Wa_16019325821
+    - drm/i915/guc: Add support for w/a KLVs
+    - drm/i915/guc: Enable Wa_14019159160
+  * Regression: unable to reach low idle states on Tiger Lake (LP: #2072679)
+    - SAUCE: PCI: ASPM: Allow OS to configure ASPM where BIOS is incapable of
+    - SAUCE: PCI: vmd: Let OS control ASPM for devices under VMD domain
+  * Noble update: upstream stable patchset 2024-08-22 (LP: #2077600)
+    - locking/mutex: Introduce devm_mutex_init()
+    - leds: an30259a: Use devm_mutex_init() for mutex initialization
+    - crypto: hisilicon/debugfs - Fix debugfs uninit process issue
+    - drm/lima: fix shared irq handling on driver remove
+    - powerpc: Avoid nmi_enter/nmi_exit in real mode interrupt.
+    - media: dvb: as102-fe: Fix as10x_register_addr packing
+    - media: dvb-usb: dib0700_devices: Add missing release_firmware()
+    - IB/core: Implement a limit on UMAD receive List
+    - scsi: qedf: Make qedf_execute_tmf() non-preemptible
+    - selftests/bpf: adjust dummy_st_ops_success to detect additional error
+    - selftests/bpf: do not pass NULL for non-nullable params in dummy_st_ops
+    - selftests/bpf: dummy_st_ops should reject 0 for non-nullable params
+    - RISC-V: KVM: Fix the initial sample period value
+    - crypto: aead,cipher - zeroize key buffer after use
+    - media: mediatek: vcodec: Only free buffer VA that is not NULL
+    - drm/amdgpu: Fix uninitialized variable warnings
+    - drm/amdgpu: Initialize timestamp for some legacy SOCs
+    - drm/amd/display: Check index msg_id before read or write
+    - drm/amd/display: Check pipe offset before setting vblank
+    - drm/amd/display: Skip finding free audio for unknown engine_id
+    - drm/amd/display: Fix uninitialized variables in DM
+    - drm/amdgpu: fix uninitialized scalar variable warning
+    - drm/amdgpu: fix the warning about the expression (int)size - len
+    - media: dw2102: Don't translate i2c read into write
+    - riscv: Apply SiFive CIP-1200 workaround to single-ASID sfence.vma
+    - sctp: prefer struct_size over open coded arithmetic
+    - firmware: dmi: Stop decoding on broken entry
+    - Input: ff-core - prefer struct_size over open coded arithmetic
+    - wifi: mt76: replace skb_put with skb_put_zero
+    - wifi: mt76: mt7996: add sanity checks for background radar trigger
+    - thermal/drivers/mediatek/lvts_thermal: Check NULL ptr on lvts_data
+    - media: dvb-frontends: tda18271c2dd: Remove casting during div
+    - media: s2255: Use refcount_t instead of atomic_t for num_channels
+    - media: dvb-frontends: tda10048: Fix integer overflow
+    - i2c: i801: Annotate apanel_addr as __ro_after_init
+    - powerpc/64: Set _IO_BASE to POISON_POINTER_DELTA not 0 for CONFIG_PCI=n
+    - orangefs: fix out-of-bounds fsid access
+    - kunit: Fix timeout message
+    - powerpc/xmon: Check cpu id in commands "c#", "dp#" and "dx#"
+    - selftests/net: fix uninitialized variables
+    - igc: fix a log entry using uninitialized netdev
+    - bpf: Avoid uninitialized value in BPF_CORE_READ_BITFIELD
+    - serial: imx: Raise TX trigger level to 8
+    - jffs2: Fix potential illegal address access in jffs2_free_inode
+    - s390/pkey: Wipe sensitive data on failure
+    - btrfs: scrub: initialize ret in scrub_simple_mirror() to fix compilation
+      warning
+    - cdrom: rearrange last_media_change check to avoid unintentional overflow
+    - tools/power turbostat: Remember global max_die_id
+    - vhost: Use virtqueue mutex for swapping worker
+    - vhost: Release worker mutex during flushes
+    - vhost_task: Handle SIGKILL by flushing work and exiting
+    - mac802154: fix time calculation in ieee802154_configure_durations()
+    - net: phy: phy_device: Fix PHY LED blinking code comment
+    - UPSTREAM: tcp: fix DSACK undo in fast recovery to call tcp_try_to_open()
+    - net/mlx5: E-switch, Create ingress ACL when needed
+    - net/mlx5e: Add mqprio_rl cleanup and free in mlx5e_priv_cleanup()
+    - Bluetooth: hci_event: Fix setting of unicast qos interval
+    - Bluetooth: Ignore too large handle values in BIG
+    - Bluetooth: ISO: Check socket flag instead of hcon
+    - bluetooth/hci: disallow setting handle bigger than HCI_CONN_HANDLE_MAX
+    - KVM: s390: fix LPSWEY handling
+    - e1000e: Fix S0ix residency on corporate systems
+    - gpiolib: of: fix lookup quirk for MIPS Lantiq
+    - net: allow skb_datagram_iter to be called from any context
+    - net: txgbe: initialize num_q_vectors for MSI/INTx interrupts
+    - net: ntb_netdev: Move ntb_netdev_rx_handler() to call netif_rx() from
+      __netif_rx()
+    - gpio: mmio: do not calculate bgpio_bits via "ngpios"
+    - wifi: wilc1000: fix ies_len type in connect path
+    - riscv: kexec: Avoid deadlock in kexec crash path
+    - netfilter: nf_tables: unconditionally flush pending work before notifier
+    - bonding: Fix out-of-bounds read in bond_option_arp_ip_targets_set()
+    - selftests: fix OOM in msg_zerocopy selftest
+    - selftests: make order checking verbose in msg_zerocopy selftest
+    - inet_diag: Initialize pad field in struct inet_diag_req_v2
+    - mlxsw: core_linecards: Fix double memory deallocation in case of invalid INI
+      file
+    - gpiolib: of: add polarity quirk for TSC2005
+    - cpu: Fix broken cmdline "nosmp" and "maxcpus=0"
+    - platform/x86: toshiba_acpi: Fix quickstart quirk handling
+    - Revert "igc: fix a log entry using uninitialized netdev"
+    - nilfs2: fix inode number range checks
+    - nilfs2: add missing check for inode numbers on directory entries
+    - mm: optimize the redundant loop of mm_update_owner_next()
+    - mm: avoid overflows in dirty throttling logic
+    - btrfs: fix adding block group to a reclaim list and the unused list during
+      reclaim
+    - scsi: mpi3mr: Use proper format specifier in mpi3mr_sas_port_add()
+    - Bluetooth: hci_bcm4377: Fix msgid release
+    - Bluetooth: qca: Fix BT enable failure again for QCA6390 after warm reboot
+    - can: kvaser_usb: Explicitly initialize family in leafimx driver_info struct
+    - fsnotify: Do not generate events for O_PATH file descriptors
+    - Revert "mm/writeback: fix possible divide-by-zero in wb_dirty_limits(),
+      again"
+    - drm/nouveau: fix null pointer dereference in nouveau_connector_get_modes
+    - drm/amdgpu/atomfirmware: silence UBSAN warning
+    - drm: panel-orientation-quirks: Add quirk for Valve Galileo
+    - clk: qcom: gcc-ipq9574: Add BRANCH_HALT_VOTED flag
+    - clk: sunxi-ng: common: Don't call hw_to_ccu_common on hw without common
+    - powerpc/pseries: Fix scv instruction crash with kexec
+    - powerpc/64s: Fix unnecessary copy to 0 when kernel is booted at address 0
+    - mtd: rawnand: Ensure ECC configuration is propagated to upper layers
+    - mtd: rawnand: Fix the nand_read_data_op() early check
+    - mtd: rawnand: Bypass a couple of sanity checks during NAND identification
+    - mtd: rawnand: rockchip: ensure NVDDR timings are rejected
+    - net: stmmac: dwmac-qcom-ethqos: fix error array size
+    - arm64: dts: rockchip: Fix the DCDC_REG2 minimum voltage on Quartz64 Model B
+    - media: dw2102: fix a potential buffer overflow
+    - clk: qcom: gcc-sm6350: Fix gpll6* & gpll7 parents
+    - clk: qcom: clk-alpha-pll: set ALPHA_EN bit for Stromer Plus PLLs
+    - clk: mediatek: mt8183: Only enable runtime PM on mt8183-mfgcfg
+    - i2c: pnx: Fix potential deadlock warning from del_timer_sync() call in isr
+    - fs/ntfs3: Mark volume as dirty if xattr is broken
+    - ALSA: hda/realtek: Enable headset mic of JP-IK LEAP W502 with ALC897
+    - vhost-scsi: Handle vhost_vq_work_queue failures for events
+    - nvme-multipath: find NUMA path only for online numa-node
+    - dma-mapping: benchmark: avoid needless copy_to_user if benchmark fails
+    - connector: Fix invalid conversion in cn_proc.h
+    - nvme: adjust multiples of NVME_CTRL_PAGE_SIZE in offset
+    - regmap-i2c: Subtract reg size from max_write
+    - platform/x86: touchscreen_dmi: Add info for GlobalSpace SolT IVW 11.6"
+      tablet
+    - platform/x86: touchscreen_dmi: Add info for the EZpad 6s Pro
+    - nvmet: fix a possible leak when destroy a ctrl during qp establishment
+    - kbuild: fix short log for AS in link-vmlinux.sh
+    - nfc/nci: Add the inconsistency check between the input data length and count
+    - spi: cadence: Ensure data lines set to low during dummy-cycle period
+    - ALSA: ump: Set default protocol when not given explicitly
+    - drm/amdgpu: silence UBSAN warning
+    - null_blk: Do not allow runt zone with zone capacity smaller then zone size
+    - nilfs2: fix incorrect inode allocation from reserved inodes
+    - leds: mlxreg: Use devm_mutex_init() for mutex initialization
+    - net: dql: Avoid calling BUG() when WARN() is enough
+    - drm/xe: Add outer runtime_pm protection to xe_live_ktest@xe_dma_buf
+    - bpf: mark bpf_dummy_struct_ops.test_1 parameter as nullable
+    - drm/amdgpu: fix double free err_addr pointer warnings
+    - drm/amd/display: Fix overlapping copy within dml_core_mode_programming
+    - drm/amd/display: update pipe topology log to support subvp
+    - drm/amd/display: Do not return negative stream id for array
+    - drm/amd/display: ASSERT when failing to find index by plane/stream id
+    - usb: xhci: prevent potential failure in handle_tx_event() for Transfer
+      events without TRB
+    - media: i2c: st-mipid02: Use the correct div function
+    - media: tc358746: Use the correct div_ function
+    - crypto: hisilicon/sec2 - fix for register offset
+    - s390/pkey: Use kfree_sensitive() to fix Coccinelle warnings
+    - s390/pkey: Wipe copies of clear-key structures on failure
+    - s390/pkey: Wipe copies of protected- and secure-keys
+    - wifi: cfg80211: restrict NL80211_ATTR_TXQ_QUANTUM values
+    - wifi: mac80211: fix BSS_CHANGED_UNSOL_BCAST_PROBE_RESP
+    - net: txgbe: remove separate irq request for MSI and INTx
+    - net: txgbe: add extra handle for MSI/INTx into thread irq handle
+    - net: txgbe: free isb resources at the right time
+    - btrfs: always do the basic checks for btrfs_qgroup_inherit structure
+    - net: phy: aquantia: add missing include guards
+    - drm/fbdev-generic: Fix framebuffer on big endian devices
+    - net: stmmac: enable HW-accelerated VLAN stripping for gmac4 only
+    - net: rswitch: Avoid use-after-free in rswitch_poll()
+    - ice: use proper macro for testing bit
+    - drm/xe/mcr: Avoid clobbering DSS steering
+    - tcp: Don't flag tcp_sk(sk)->rx_opt.saw_unknown for TCP AO.
+    - btrfs: zoned: fix calc_available_free_space() for zoned mode
+    - btrfs: fix folio refcount in __alloc_dummy_extent_buffer()
+    - Bluetooth: Add quirk to ignore reserved PHY bits in LE Extended Adv Report
+    - drm/xe: fix error handling in xe_migrate_update_pgtables
+    - drm/ttm: Always take the bo delayed cleanup path for imported bos
+    - fs: don't misleadingly warn during thaw operations
+    - drm/amdkfd: Let VRAM allocations go to GTT domain on small APUs
+    - drm/amdgpu: correct hbm field in boot status
+    - Upstream stable to v6.6.38, v6.6.39, v6.9.9
+  * Panels show garbage or flickering when i915.psr2 enabled (LP: #2069993)
+    - SAUCE: drm/i915/display/psr: add a psr2 disable quirk table
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x4d_0x10_0x93_0x15
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x30_0xe4_0x8b_0x07
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x30_0xe4_0x78_0x07
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x30_0xe4_0x8c_0x07
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x06_0xaf_0x9a_0xf9
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x4d_0x10_0x8f_0x15
+    - SAUCE: drm/i915/display/psr: disable psr2 for panel_0x06_0xaf_0xa3_0xc3
+  * Random flickering with Intel i915 (Gen9 GPUs in 6th-8th gen CPUs) on Linux
+    6.8 (LP: #2062951)
+    - SAUCE: iommu/intel: disable DMAR for SKL integrated gfx
+  * [SRU][22.04.5]: mpi3mr driver update (LP: #2073583)
+    - scsi: mpi3mr: HDB allocation and posting for hardware and firmware buffers
+    - scsi: mpi3mr: Trigger support
+    - scsi: mpi3mr: Add ioctl support for HDB
+    - scsi: mpi3mr: Support PCI Error Recovery callback handlers
+    - scsi: mpi3mr: Prevent PCI writes from driver during PCI error recovery
+    - scsi: mpi3mr: Driver version update
+  * Fix power consumption while using HW accelerated video decode on AMD
+    platforms (LP: #2073282)
+    - drm/amdgpu/vcn: identify unified queue in sw init
+    - drm/amdgpu/vcn: not pause dpg for unified queue
+  * Noble update: upstream stable patchset 2024-08-09 (LP: #2076435)
+    - usb: typec: ucsi: Never send a lone connector change ack
+    - usb: typec: ucsi: Ack also failed Get Error commands
+    - Input: ili210x - fix ili251x_read_touch_data() return value
+    - pinctrl: fix deadlock in create_pinctrl() when handling -EPROBE_DEFER
+    - pinctrl: rockchip: fix pinmux bits for RK3328 GPIO2-B pins
+    - pinctrl: rockchip: fix pinmux bits for RK3328 GPIO3-B pins
+    - pinctrl: rockchip: use dedicated pinctrl type for RK3328
+    - pinctrl: rockchip: fix pinmux reset in rockchip_pmx_set
+    - MIPS: pci: lantiq: restore reset gpio polarity
+    - ASoC: rockchip: i2s-tdm: Fix trcm mode by setting clock on right mclk
+    - ASoC: mediatek: mt8183-da7219-max98357: Fix kcontrol name collision
+    - ASoC: atmel: atmel-classd: Re-add dai_link->platform to fix card init
+    - workqueue: Increase worker desc's length to 32
+    - ASoC: q6apm-lpass-dai: close graph on prepare errors
+    - bpf: Add missed var_off setting in set_sext32_default_val()
+    - bpf: Add missed var_off setting in coerce_subreg_to_size_sx()
+    - s390/pci: Add missing virt_to_phys() for directed DIBV
+    - ASoC: amd: acp: add a null check for chip_pdev structure
+    - ASoC: amd: acp: remove i2s configuration check in acp_i2s_probe()
+    - ASoC: fsl-asoc-card: set priv->pdev before using it
+    - net: dsa: microchip: fix initial port flush problem
+    - openvswitch: get related ct labels from its master if it is not confirmed
+    - mlxsw: spectrum_buffers: Fix memory corruptions on Spectrum-4 systems
+    - ibmvnic: Free any outstanding tx skbs during scrq reset
+    - net: phy: micrel: add Microchip KSZ 9477 to the device table
+    - net: dsa: microchip: use collision based back pressure mode
+    - ice: Rebuild TC queues on VSI queue reconfiguration
+    - xdp: Remove WARN() from __xdp_reg_mem_model()
+    - netfilter: fix undefined reference to 'netfilter_lwtunnel_*' when
+      CONFIG_SYSCTL=n
+    - btrfs: use NOFS context when getting inodes during logging and log replay
+    - Fix race for duplicate reqsk on identical SYN
+    - ALSA: seq: Fix missing channel at encoding RPN/NRPN MIDI2 messages
+    - net: dsa: microchip: fix wrong register write when masking interrupt
+    - sparc: fix old compat_sys_select()
+    - sparc: fix compat recv/recvfrom syscalls
+    - parisc: use correct compat recv/recvfrom syscalls
+    - powerpc: restore some missing spu syscalls
+    - tcp: fix tcp_rcv_fastopen_synack() to enter TCP_CA_Loss for failed TFO
+    - ALSA: seq: Fix missing MSB in MIDI2 SPP conversion
+    - netfilter: nf_tables: fully validate NFT_DATA_VALUE on store to data
+      registers
+    - net: mana: Fix possible double free in error handling path
+    - drm/panel: ilitek-ili9881c: Fix warning with GPIO controllers that sleep
+    - vduse: validate block features only with block devices
+    - vduse: Temporarily fail if control queue feature requested
+    - x86/fpu: Fix AMD X86_BUG_FXSAVE_LEAK fixup
+    - mtd: partitions: redboot: Added conversion of operands to a larger type
+    - wifi: ieee80211: check for NULL in ieee80211_mle_size_ok()
+    - bpf: Mark bpf prog stack with kmsan_unposion_memory in interpreter mode
+    - RDMA/restrack: Fix potential invalid address access
+    - net/iucv: Avoid explicit cpumask var allocation on stack
+    - net/dpaa2: Avoid explicit cpumask var allocation on stack
+    - crypto: ecdh - explicitly zeroize private_key
+    - ALSA: emux: improve patch ioctl data validation
+    - media: dvbdev: Initialize sbuf
+    - irqchip/loongson: Select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP for
+      IRQ_LOONGARCH_CPU
+    - soc: ti: wkup_m3_ipc: Send NULL dummy message instead of pointer message
+    - gfs2: Fix NULL pointer dereference in gfs2_log_flush
+    - drm/radeon/radeon_display: Decrease the size of allocated memory
+    - nvme: fixup comment for nvme RDMA Provider Type
+    - drm/panel: simple: Add missing display timing flags for KOE TX26D202VM0BWA
+    - gpio: davinci: Validate the obtained number of IRQs
+    - RISC-V: fix vector insn load/store width mask
+    - drm/amdgpu: Fix pci state save during mode-1 reset
+    - riscv: stacktrace: convert arch_stack_walk() to noinstr
+    - gpiolib: cdev: Disallow reconfiguration without direction (uAPI v1)
+    - randomize_kstack: Remove non-functional per-arch entropy filtering
+    - x86: stop playing stack games in profile_pc()
+    - parisc: use generic sys_fanotify_mark implementation
+    - Revert "MIPS: pci: lantiq: restore reset gpio polarity"
+    - pinctrl: qcom: spmi-gpio: drop broken pm8008 support
+    - ocfs2: fix DIO failure due to insufficient transaction credits
+    - nfs: drop the incorrect assertion in nfs_swap_rw()
+    - mm: fix incorrect vbq reference in purge_fragmented_block
+    - mmc: sdhci-pci-o2micro: Convert PCIBIOS_* return codes to errnos
+    - mmc: sdhci-brcmstb: check R1_STATUS for erase/trim/discard
+    - mmc: sdhci-pci: Convert PCIBIOS_* return codes to errnos
+    - mmc: sdhci: Do not invert write-protect twice
+    - mmc: sdhci: Do not lock spinlock around mmc_gpio_get_ro()
+    - iio: xilinx-ams: Don't include ams_ctrl_channels in scan_mask
+    - counter: ti-eqep: enable clock at probe
+    - kbuild: doc: Update default INSTALL_MOD_DIR from extra to updates
+    - kbuild: Fix build target deb-pkg: ln: failed to create hard link
+    - i2c: testunit: don't erase registers after STOP
+    - i2c: testunit: discard write requests while old command is running
+    - ata: libata-core: Fix null pointer dereference on error
+    - ata,scsi: libata-core: Do not leak memory for ata_port struct members
+    - iio: adc: ad7266: Fix variable checking bug
+    - iio: accel: fxls8962af: select IIO_BUFFER & IIO_KFIFO_BUF
+    - iio: chemical: bme680: Fix pressure value output
+    - iio: chemical: bme680: Fix calibration data variable
+    - iio: chemical: bme680: Fix overflows in compensate() functions
+    - iio: chemical: bme680: Fix sensor data read operation
+    - net: usb: ax88179_178a: improve link status logs
+    - usb: gadget: printer: SS+ support
+    - usb: gadget: printer: fix races against disable
+    - usb: musb: da8xx: fix a resource leak in probe()
+    - usb: atm: cxacru: fix endpoint checking in cxacru_bind()
+    - usb: dwc3: core: remove lock of otg mode during gadget suspend/resume to
+      avoid deadlock
+    - usb: gadget: aspeed_udc: fix device address configuration
+    - usb: typec: ucsi: glink: fix child node release in probe function
+    - usb: ucsi: stm32: fix command completion handling
+    - usb: dwc3: core: Add DWC31 version 2.00a controller
+    - usb: dwc3: core: Workaround for CSR read timeout
+    - Revert "serial: core: only stop transmit when HW fifo is empty"
+    - serial: 8250_omap: Implementation of Errata i2310
+    - serial: imx: set receiver level before starting uart
+    - serial: core: introduce uart_port_tx_limited_flags()
+    - serial: bcm63xx-uart: fix tx after conversion to uart_port_tx_limited()
+    - tty: mcf: MCF54418 has 10 UARTS
+    - net: can: j1939: Initialize unused data in j1939_send_one()
+    - net: can: j1939: recover socket queue on CAN bus error during BAM
+      transmission
+    - net: can: j1939: enhanced error handling for tightly received RTS messages
+      in xtp_rx_rts_session_new
+    - PCI/MSI: Fix UAF in msi_capability_init
+    - cpufreq: intel_pstate: Use HWP to initialize ITMT if CPPC is missing
+    - irqchip/loongson-eiointc: Use early_cpu_to_node() instead of cpu_to_node()
+    - cpu/hotplug: Fix dynstate assignment in __cpuhp_setup_state_cpuslocked()
+    - irqchip/loongson-liointc: Set different ISRs for different cores
+    - kbuild: Install dtb files as 0644 in Makefile.dtbinst
+    - sh: rework sync_file_range ABI
+    - btrfs: zoned: fix initial free space detection
+    - csky, hexagon: fix broken sys_sync_file_range
+    - hexagon: fix fadvise64_64 calling conventions
+    - drm/drm_file: Fix pid refcounting race
+    - drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_ld_modes
+    - drm/fbdev-dma: Only set smem_start is enable per module option
+    - drm/amdgpu: avoid using null object of framebuffer
+    - drm/i915/gt: Fix potential UAF by revoke of fence registers
+    - drm/nouveau/dispnv04: fix null pointer dereference in nv17_tv_get_hd_modes
+    - drm/amd/display: Send DP_TOTAL_LTTPR_CNT during detection if LTTPR is
+      present
+    - drm/amdgpu/atomfirmware: fix parsing of vram_info
+    - batman-adv: Don't accept TT entries for out-of-spec VIDs
+    - can: mcp251xfd: fix infinite loop when xmit fails
+    - ata: ahci: Clean up sysfs file on error
+    - ata: libata-core: Fix double free on error
+    - ftruncate: pass a signed offset
+    - syscalls: fix compat_sys_io_pgetevents_time64 usage
+    - syscalls: fix sys_fanotify_mark prototype
+    - Revert "cpufreq: amd-pstate: Fix the inconsistency in max frequency units"
+    - mm/page_alloc: Separate THP PCP into movable and non-movable categories
+    - arm64: dts: rockchip: Fix SD NAND and eMMC init on rk3308-rock-pi-s
+    - arm64: dts: rockchip: Rename LED related pinctrl nodes on rk3308-rock-pi-s
+    - arm64: dts: rockchip: Fix the value of `dlg,jack-det-rate` mismatch on
+      rk3399-gru
+    - ARM: dts: rockchip: rk3066a: add #sound-dai-cells to hdmi node
+    - arm64: dts: rockchip: make poweroff(8) work on Radxa ROCK 5A
+    - arm64: dts: rockchip: fix PMIC interrupt pin on ROCK Pi E
+    - arm64: dts: rockchip: Add sound-dai-cells for RK3368
+    - cxl/region: Move cxl_dpa_to_region() work to the region driver
+    - cxl/region: Avoid null pointer dereference in region lookup
+    - cxl/region: check interleave capability
+    - serial: imx: only set receiver level if it is zero
+    - serial: 8250_omap: Fix Errata i2310 with RX FIFO level check
+    - tracing/net_sched: NULL pointer dereference in perf_trace_qdisc_reset()
+    - pwm: stm32: Improve precision of calculation in .apply()
+    - pwm: stm32: Fix for settings using period > UINT32_MAX
+    - pwm: stm32: Calculate prescaler with a division instead of a loop
+    - pwm: stm32: Refuse too small period requests
+    - ASoC: cs42l43: Increase default type detect time and button delay
+    - ASoC: amd: acp: move chip->flag variable assignment
+    - bonding: fix incorrect software timestamping report
+    - mlxsw: pci: Fix driver initialization with Spectrum-4
+    - vxlan: Pull inner IP header in vxlan_xmit_one().
+    - ASoC: mediatek: mt8195: Add platform entry for ETDM1_OUT_BE dai link
+    - af_unix: Stop recv(MSG_PEEK) at consumed OOB skb.
+    - af_unix: Don't stop recv(MSG_DONTWAIT) if consumed OOB skb is at the head.
+    - af_unix: Don't stop recv() at consumed ex-OOB skb.
+    - af_unix: Fix wrong ioctl(SIOCATMARK) when consumed OOB skb is at the head.
+    - bpf: Take return from set_memory_ro() into account with bpf_prog_lock_ro()
+    - bpf: Take return from set_memory_rox() into account with
+      bpf_jit_binary_lock_ro()
+    - drm/xe: Fix potential integer overflow in page size calculation
+    - drm/xe: Add a NULL check in xe_ttm_stolen_mgr_init
+    - drm/amd/display: correct hostvm flag
+    - drm/amd/display: Skip pipe if the pipe idx not set properly
+    - bpf: Add a check for struct bpf_fib_lookup size
+    - drm/xe/xe_devcoredump: Check NULL before assignments
+    - iommu/arm-smmu-v3: Do not allow a SVA domain to be set on the wrong PASID
+    - evm: Enforce signatures on unsupported filesystem for EVM_INIT_X509
+    - drm/xe: Check pat.ops before dumping PAT settings
+    - nvmet: do not return 'reserved' for empty TSAS values
+    - nvmet: make 'tsas' attribute idempotent for RDMA
+    - iommu/amd: Fix GT feature enablement again
+    - gpiolib: cdev: Ignore reconfiguration without direction
+    - kasan: fix bad call to unpoison_slab_object
+    - mm/memory: don't require head page for do_set_pmd()
+    - SUNRPC: Fix backchannel reply, again
+    - Revert "usb: gadget: u_ether: Re-attach netif device to mirror detachment"
+    - Revert "usb: gadget: u_ether: Replace netif_stop_queue with
+      netif_device_detach"
+    - tty: serial: 8250: Fix port count mismatch with the device
+    - tty: mxser: Remove __counted_by from mxser_board.ports[]
+    - nvmet-fc: Remove __counted_by from nvmet_fc_tgt_queue.fod[]
+    - ata: libata-core: Add ATA_HORKAGE_NOLPM for all Crucial BX SSD1 models
+    - bcachefs: Fix sb_field_downgrade validation
+    - bcachefs: Fix sb-downgrade validation
+    - bcachefs: Fix bch2_sb_downgrade_update()
+    - bcachefs: Fix setting of downgrade recovery passes/errors
+    - bcachefs: btree_gc can now handle unknown btrees
+    - pwm: stm32: Fix calculation of prescaler
+    - pwm: stm32: Fix error message to not describe the previous error path
+    - cxl/region: Convert cxl_pmem_region_alloc to scope-based resource management
+    - cxl/mem: Fix no cxl_nvd during pmem region auto-assembling
+    - arm64: dts: rockchip: Fix the i2c address of es8316 on Cool Pi 4B
+    - netfs: Fix netfs_page_mkwrite() to check folio->mapping is valid
+    - netfs: Fix netfs_page_mkwrite() to flush conflicting data, not wait
+    - Upstream stable to v6.6.37, v6.9.8
+  * [UBUNTU 22.04] s390/cpum_cf: make crypto counters upward compatible
+    (LP: #2074380)
+    - s390/cpum_cf: make crypto counters upward compatible across machine types
+  * CVE-2024-45016
+    - netem: fix return value if duplicate enqueue fails
+
+  [ Ubuntu: 6.8.0-45.45 ]
+
+  * noble/linux: 6.8.0-45.45 -proposed tracker (LP: #2078100)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/s2024.08.05)
+  * Noble update: upstream stable patchset 2024-08-09 (LP: #2076435) //
+    CVE-2024-41009
+    - bpf: Fix overrunning reservations in ringbuf
+  * CVE-2024-42160
+    - f2fs: check validation of fault attrs in f2fs_build_fault_attr()
+    - f2fs: Add inline to f2fs_build_fault_attr() stub
+  * Noble update: upstream stable patchset 2024-08-22 (LP: #2077600) //
+    CVE-2024-42224
+    - net: dsa: mv88e6xxx: Correct check for empty list
+  * Noble update: upstream stable patchset 2024-08-22 (LP: #2077600) //
+    CVE-2024-42154
+    - tcp_metrics: validate source addr length
+  * CVE-2024-42228
+    - drm/amdgpu: Using uninitialized value *size when calling amdgpu_vce_cs_reloc
+  * CVE-2024-42159
+    - scsi: mpi3mr: Sanitise num_phys
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 03 Oct 2024 23:24:01 +0900
+
+linux-qcom (6.8.0-1010.10) jammy; urgency=medium
+
+  * jammy/linux-qcom: 6.8.0-1010.10 -proposed tracker (LP: #2081038)
+
+  * Disable PCI_DYNAMIC_OF_NODES in Ubuntu (LP: #2074376)
+    - [Config] Disable PCI_DYNAMIC_OF_NODES
+
+  * Reenable CONFIG_UBSAN for noble (LP: #2076650)
+    - [Config] Remove CONFIG_UBSAN_SANITIZE_ALL
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update update.conf
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] create linux-libc-dev-qcom package
+    - SAUCE: rdbg: include <linux/platform_device.h>
+    - SAUCE: add empty dkms-versions
+
+  * Miscellaneous upstream changes
+    - Ubuntu: [Config] enable more CONFIG options based on GA 1.1
+
+  [ Ubuntu: 6.8.0-44.44 ]
+
+  * noble/linux: 6.8.0-44.44 -proposed tracker (LP: #2076647)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2024.08.05)
+  * Disable PCI_DYNAMIC_OF_NODES in Ubuntu (LP: #2074376)
+    - [Config] Disable PCI_DYNAMIC_OF_NODES
+  * [SRU] Turbostat support for Arrow Lake H (LP: #2074372)
+    - tools/power turbostat: Enhance ARL/LNL support
+    - x86/cpu: Add model number for another Intel Arrow Lake mobile processor
+    - tools/power turbostat: Add ARL-H support
+  * Noble update: upstream stable patchset 2024-07-30 (LP: #2075154)
+    - fs/writeback: bail out if there is no more inodes for IO and queued once
+    - padata: Disable BH when taking works lock on MT path
+    - crypto: hisilicon/sec - Fix memory leak for sec resource release
+    - crypto: hisilicon/qm - Add the err memory release process to qm uninit
+    - io_uring/sqpoll: work around a potential audit memory leak
+    - rcutorture: Fix rcu_torture_one_read() pipe_count overflow comment
+    - rcutorture: Make stall-tasks directly exit when rcutorture tests end
+    - rcutorture: Fix invalid context warning when enable srcu barrier testing
+    - block/ioctl: prefer different overflow check
+    - ssb: Fix potential NULL pointer dereference in ssb_device_uevent()
+    - selftests/bpf: Prevent client connect before server bind in
+      test_tc_tunnel.sh
+    - selftests/bpf: Fix flaky test btf_map_in_map/lookup_update
+    - batman-adv: bypass empty buckets in batadv_purge_orig_ref()
+    - wifi: ath9k: work around memset overflow warning
+    - af_packet: avoid a false positive warning in packet_setsockopt()
+    - ACPI: x86: Add PNP_UART1_SKIP quirk for Lenovo Blade2 tablets
+    - drop_monitor: replace spin_lock by raw_spin_lock
+    - scsi: qedi: Fix crash while reading debugfs attribute
+    - net: sfp: add quirk for ATS SFP-GE-T 1000Base-TX module
+    - net/sched: fix false lockdep warning on qdisc root lock
+    - kselftest: arm64: Add a null pointer check
+    - net: dsa: realtek: keep default LED state in rtl8366rb
+    - netpoll: Fix race condition in netpoll_owner_active
+    - wifi: mt76: mt7921s: fix potential hung tasks during chip recovery
+    - HID: Add quirk for Logitech Casa touchpad
+    - HID: asus: fix more n-key report descriptors if n-key quirked
+    - ACPI: video: Add backlight=native quirk for Lenovo Slim 7 16ARH7
+    - Bluetooth: ath3k: Fix multiple issues reported by checkpatch.pl
+    - drm/amd/display: Exit idle optimizations before HDCP execution
+    - platform/x86: toshiba_acpi: Add quirk for buttons on Z830
+    - ASoC: Intel: sof_sdw: add JD2 quirk for HP Omen 14
+    - ASoC: Intel: sof_sdw: add quirk for Dell SKU 0C0F
+    - drm/lima: add mask irq callback to gp and pp
+    - drm/lima: mask irqs in timeout path before hard reset
+    - ALSA: hda/realtek: Add quirks for Lenovo 13X
+    - powerpc/pseries: Enforce hcall result buffer validity and size
+    - media: intel/ipu6: Fix build with !ACPI
+    - media: mtk-vcodec: potential null pointer deference in SCP
+    - powerpc/io: Avoid clang null pointer arithmetic warnings
+    - platform/x86: p2sb: Don't init until unassigned resources have been assigned
+    - power: supply: cros_usbpd: provide ID table for avoiding fallback match
+    - iommu/arm-smmu-v3: Free MSIs in case of ENOMEM
+    - ext4: fix uninitialized ratelimit_state->lock access in __ext4_fill_super()
+    - kprobe/ftrace: bail out if ftrace was killed
+    - usb: gadget: uvc: configfs: ensure guid to be valid before set
+    - f2fs: remove clear SB_INLINECRYPT flag in default_options
+    - usb: misc: uss720: check for incompatible versions of the Belkin F5U002
+    - Avoid hw_desc array overrun in dw-axi-dmac
+    - usb: dwc3: pci: Don't set "linux,phy_charger_detect" property on Lenovo Yoga
+      Tab2 1380
+    - usb: typec: ucsi_glink: drop special handling for CCI_BUSY
+    - udf: udftime: prevent overflow in udf_disk_stamp_to_time()
+    - PCI/PM: Avoid D3cold for HP Pavilion 17 PC/1972 PCIe Ports
+    - f2fs: don't set RO when shutting down f2fs
+    - MIPS: Octeon: Add PCIe link status check
+    - serial: imx: Introduce timeout when waiting on transmitter empty
+    - serial: exar: adding missing CTI and Exar PCI ids
+    - usb: gadget: function: Remove usage of the deprecated ida_simple_xx() API
+    - tty: add the option to have a tty reject a new ldisc
+    - vfio/pci: Collect hot-reset devices to local buffer
+    - cpufreq: amd-pstate: fix memory leak on CPU EPP exit
+    - ACPI: EC: Install address space handler at the namespace root
+    - PCI: Do not wait for disconnected devices when resuming
+    - ALSA: hda: cs35l41: Possible null pointer dereference in
+      cs35l41_hda_unbind()
+    - ALSA: seq: ump: Fix missing System Reset message handling
+    - MIPS: Routerboard 532: Fix vendor retry check code
+    - mips: bmips: BCM6358: make sure CBR is correctly set
+    - tracing: Build event generation tests only as modules
+    - ALSA: hda/realtek: Remove Framework Laptop 16 from quirks
+    - ALSA/hda: intel-dsp-config: Document AVS as dsp_driver option
+    - ice: avoid IRQ collision to fix init failure on ACPI S3 resume
+    - btrfs: zoned: allocate dummy checksums for zoned NODATASUM writes
+    - net: mvpp2: use slab_build_skb for oversized frames
+    - cipso: fix total option length computation
+    - ALSA: hda: cs35l56: Component should be unbound before deconstruction
+    - ALSA: hda: tas2781: Component should be unbound before deconstruction
+    - bpf: Avoid splat in pskb_pull_reason
+    - ALSA: hda/realtek: Enable headset mic on IdeaPad 330-17IKB 81DM
+    - netrom: Fix a memory leak in nr_heartbeat_expiry()
+    - ipv6: prevent possible NULL deref in fib6_nh_init()
+    - ipv6: prevent possible NULL dereference in rt6_probe()
+    - xfrm6: check ip6_dst_idev() return value in xfrm6_get_saddr()
+    - netns: Make get_net_ns() handle zero refcount net
+    - qca_spi: Make interrupt remembering atomic
+    - net: lan743x: disable WOL upon resume to restore full data path operation
+    - net: lan743x: Support WOL at both the PHY and MAC appropriately
+    - net: phy: mxl-gpy: Remove interrupt mask clearing from config_init
+    - net/sched: act_api: fix possible infinite loop in tcf_idr_check_alloc()
+    - tipc: force a dst refcount before doing decryption
+    - sched: act_ct: add netns into the key of tcf_ct_flow_table
+    - ptp: fix integer overflow in max_vclocks_store
+    - selftests: openvswitch: Use bash as interpreter
+    - net: stmmac: No need to calculate speed divider when offload is disabled
+    - virtio_net: checksum offloading handling fix
+    - virtio_net: fixing XDP for fully checksummed packets handling
+    - octeontx2-pf: Add error handling to VLAN unoffload handling
+    - octeontx2-pf: Fix linking objects into multiple modules
+    - netfilter: ipset: Fix suspicious rcu_dereference_protected()
+    - seg6: fix parameter passing when calling NF_HOOK() in End.DX4 and End.DX6
+      behaviors
+    - netfilter: move the sysctl nf_hooks_lwtunnel into the netfilter core
+    - ice: Fix VSI list rule with ICE_SW_LKUP_LAST type
+    - bnxt_en: Restore PTP tx_avail count in case of skb_pad() error
+    - net: usb: rtl8150 fix unintiatilzed variables in rtl8150_get_link_ksettings
+    - RDMA/bnxt_re: Fix the max msix vectors macro
+    - spi: cs42l43: Correct SPI root clock speed
+    - RDMA/rxe: Fix responder length checking for UD request packets
+    - regulator: core: Fix modpost error "regulator_get_regmap" undefined
+    - dmaengine: idxd: Fix possible Use-After-Free in irq_process_work_list
+    - dmaengine: ioatdma: Fix leaking on version mismatch
+    - dmaengine: ioatdma: Fix error path in ioat3_dma_probe()
+    - dmaengine: ioatdma: Fix kmemleak in ioat_pci_probe()
+    - dmaengine: fsl-edma: avoid linking both modules
+    - dmaengine: ioatdma: Fix missing kmem_cache_destroy()
+    - regulator: bd71815: fix ramp values
+    - thermal/drivers/mediatek/lvts_thermal: Return error in case of invalid efuse
+      data
+    - arm64: dts: imx8mp: Fix TC9595 input clock on DH i.MX8M Plus DHCOM SoM
+    - arm64: dts: freescale: imx8mp-venice-gw73xx-2x: fix BT shutdown GPIO
+    - arm64: dts: imx93-11x11-evk: Remove the 'no-sdio' property
+    - arm64: dts: freescale: imx8mm-verdin: enable hysteresis on slow input pin
+    - ACPICA: Revert "ACPICA: avoid Info: mapping multiple BARs. Your kernel is
+      fine."
+    - spi: spi-imx: imx51: revert burst length calculation back to bits_per_word
+    - io_uring/rsrc: fix incorrect assignment of iter->nr_segs in io_import_fixed
+    - firmware: psci: Fix return value from psci_system_suspend()
+    - RDMA/mlx5: Fix unwind flow as part of mlx5_ib_stage_init_init
+    - RDMA/mlx5: Add check for srq max_sge attribute
+    - RDMA/mana_ib: Ignore optional access flags for MRs
+    - ACPI: EC: Evaluate orphan _REG under EC device
+    - arm64: defconfig: enable the vf610 gpio driver
+    - ext4: avoid overflow when setting values via sysfs
+    - ext4: fix slab-out-of-bounds in ext4_mb_find_good_group_avg_frag_lists()
+    - net: stmmac: Assign configured channel value to EXTTS event
+    - net: usb: ax88179_178a: improve reset check
+    - net: do not leave a dangling sk pointer, when socket creation fails
+    - btrfs: retry block group reclaim without infinite loop
+    - scsi: ufs: core: Free memory allocated for model before reinit
+    - cifs: fix typo in module parameter enable_gcm_256
+    - LoongArch: Fix watchpoint setting error
+    - LoongArch: Trigger user-space watchpoints correctly
+    - LoongArch: Fix multiple hardware watchpoint issues
+    - KVM: Fix a data race on last_boosted_vcpu in kvm_vcpu_on_spin()
+    - KVM: arm64: Disassociate vcpus from redistributor region on teardown
+    - KVM: x86: Always sync PIR to IRR prior to scanning I/O APIC routes
+    - RDMA/rxe: Fix data copy for IB_SEND_INLINE
+    - RDMA/mlx5: Remove extra unlock on error path
+    - RDMA/mlx5: Follow rb_key.ats when creating new mkeys
+    - ovl: fix encoding fid for lower only root
+    - ALSA: hda/realtek: Limit mic boost on N14AP7
+    - ALSA: hda/realtek: Add quirk for Lenovo Yoga Pro 7 14AHP9
+    - drm/i915/mso: using joiner is not possible with eDP MSO
+    - drm/radeon: fix UBSAN warning in kv_dpm.c
+    - drm/amdgpu: fix UBSAN warning in kv_dpm.c
+    - dt-bindings: dma: fsl-edma: fix dma-channels constraints
+    - ocfs2: fix NULL pointer dereference in ocfs2_journal_dirty()
+    - ocfs2: fix NULL pointer dereference in ocfs2_abort_trigger()
+    - gcov: add support for GCC 14
+    - kcov: don't lose track of remote references during softirqs
+    - efi/x86: Free EFI memory map only when installing a new one.
+    - serial: 8250_dw: Revert "Move definitions to the shared header"
+    - mm: mmap: allow for the maximum number of bits for randomizing mmap_base by
+      default
+    - tcp: clear tp->retrans_stamp in tcp_rcv_fastopen_synack()
+    - mm/page_table_check: fix crash on ZONE_DEVICE
+    - i2c: ocores: set IACK bit after core is enabled
+    - dt-bindings: i2c: atmel,at91sam: correct path to i2c-controller schema
+    - dt-bindings: i2c: google,cros-ec-i2c-tunnel: correct path to i2c-controller
+      schema
+    - spi: stm32: qspi: Fix dual flash mode sanity test in stm32_qspi_setup()
+    - arm64: dts: imx8qm-mek: fix gpio number for reg_usdhc2_vmmc
+    - spi: stm32: qspi: Clamp stm32_qspi_get_mode() output to CCR_BUSWIDTH_4
+    - perf: script: add raw|disasm arguments to --insn-trace option
+    - nbd: Improve the documentation of the locking assumptions
+    - nbd: Fix signal handling
+    - tracing: Add MODULE_DESCRIPTION() to preemptirq_delay_test
+    - x86/cpu/vfm: Add new macros to work with (vendor/family/model) values
+    - x86/cpu: Fix x86_match_cpu() to match just X86_VENDOR_INTEL
+    - drm/amd/display: revert Exit idle optimizations before HDCP execution
+    - ASoC: Intel: sof-sdw: really remove FOUR_SPEAKER quirk
+    - net/sched: unregister lockdep keys in qdisc_create/qdisc_alloc error path
+    - kprobe/ftrace: fix build error due to bad function definition
+    - hid: asus: asus_report_fixup: fix potential read out of bounds
+    - Revert "mm: mmap: allow for the maximum number of bits for randomizing
+      mmap_base by default"
+    - platform/chrome: cros_usbpd_logger: provide ID table for avoiding fallback
+      match
+    - platform/chrome: cros_usbpd_notify: provide ID table for avoiding fallback
+      match
+    - ubsan: Avoid i386 UBSAN handler crashes with Clang
+    - arm64: defconfig: select INTERCONNECT_QCOM_SM6115 as built-in
+    - bpf: Avoid kfree_rcu() under lock in bpf_lpm_trie.
+    - devlink: use kvzalloc() to allocate devlink instance resources
+    - wifi: rtw89: 8852c: add quirk to set PCI BER for certain platforms
+    - clocksource: Make watchdog and suspend-timing multiplication overflow safe
+    - ACPI: resource: Do IRQ override on GMxBGxx (XMG APEX 17 M23)
+    - wifi: ath12k: add string type to search board data in board-2.bin for
+      WCN7850
+    - wifi: ath12k: add firmware-2.bin support
+    - wifi: ath12k: fix kernel crash during resume
+    - arm64/sysreg: Update PIE permission encodings
+    - ACPI: resource: Skip IRQ override on Asus Vivobook Pro N6506MV
+    - wifi: ath12k: fix the problem that down grade phy mode operation
+    - bpf: avoid uninitialized warnings in verifier_global_subprogs.c
+    - selftests: net: fix timestamp not arriving in cmsg_time.sh
+    - net: ena: Add validation for completion descriptors consistency
+    - drm/amd/display: Workaround register access in idle race with cursor
+    - cgroup/cpuset: Make cpuset hotplug processing synchronous
+    - platform/x86: x86-android-tablets: Unregister devices in reverse order
+    - platform/x86: x86-android-tablets: Add Lenovo Yoga Tablet 2 Pro 1380F/L data
+    - ALSA: hda/realtek: Add quirks for HP Omen models using CS35L41
+    - ext4: fold quota accounting into ext4_xattr_inode_lookup_create()
+    - ext4: do not create EA inode under buffer lock
+    - f2fs: fix to detect inconsistent nat entry during truncation
+    - usb: typec: ucsi_glink: rework quirks implementation
+    - xhci: remove XHCI_TRUST_TX_LENGTH quirk
+    - clk: Add a devm variant of clk_rate_exclusive_get()
+    - clk: Provide !COMMON_CLK dummy for devm_clk_rate_exclusive_get()
+    - i2c: lpi2c: Avoid calling clk_get_rate during transfer
+    - cxl: Add post-reset warning if reset results in loss of previously committed
+      HDM decoders
+    - OPP: Fix required_opp_tables for multiple genpds using same table
+    - wifi: iwlwifi: mvm: fix ROC version check
+    - wifi: mac80211: Recalc offload when monitor stop
+    - ice: fix 200G link speed message log
+    - ice: implement AQ download pkg retry
+    - bpf: Fix reg_set_min_max corruption of fake_reg
+    - ALSA: hda: cs35l41: Component should be unbound before deconstruction
+    - netdev-genl: fix error codes when outputting XDP features
+    - arm64: dts: freescale: imx8mm-verdin: Fix GPU speed
+    - phy: qcom-qmp: qserdes-txrx: Add missing registers offsets
+    - phy: qcom-qmp: pcs: Add missing v6 N4 register offsets
+    - phy: qcom: qmp-combo: Switch from V6 to V6 N4 register offsets
+    - powerpc/crypto: Add generated P8 asm to .gitignore
+    - spi: Exctract spi_dev_check_cs() helper
+    - spi: Fix SPI slave probe failure
+    - net: phy: dp83tg720: wake up PHYs in managed mode
+    - net: phy: dp83tg720: get master/slave configuration in link down state
+    - RDMA/mlx5: Ensure created mkeys always have a populated rb_key
+    - drm/amdgpu: fix locking scope when flushing tlb
+    - drm/amd/display: Remove redundant idle optimization check
+    - drm/amd/display: Attempt to avoid empty TUs when endpoint is DPIA
+    - ata: ahci: Do not enable LPM if no LPM states are supported by the HBA
+    - dmaengine: xilinx: xdma: Fix data synchronisation in xdma_channel_isr()
+    - net/tcp_ao: Don't leak ao_info on error-path
+    - mm: shmem: fix getting incorrect lruvec when replacing a shmem folio
+    - selftests: mptcp: print_test out of verify_listener_events
+    - selftests: mptcp: userspace_pm: fixed subtest names
+    - ima: Avoid blocking in RCU read-side critical section
+    - virt: guest_memfd: fix reference leak on hwpoisoned page
+    - thermal: int340x: processor_thermal: Support shared interrupts
+    - thermal: core: Change PM notifier priority to the minimum
+    - wifi: ath12k: check M3 buffer size as well whey trying to reuse it
+    - Upstream stable to v6.6.36, v6.9.7
+  * [SRU] Add Dynamic Tuning Technology (DTT)  support for Lunar Lake
+    (LP: #2073961)
+    - thermal: int340x: processor_thermal: Add Lunar Lake-M PCI ID
+  * Kubuntu 24.04 freezes after plugging in ethernet cable (LP: #2073358)
+    - e1000e: move force SMBUS near the end of enable_ulp function
+    - e1000e: fix force smbus during suspend flow
+  * Noble update: upstream stable patchset 2024-07-25 (LP: #2074091)
+    - wifi: mac80211: mesh: Fix leak of mesh_preq_queue objects
+    - wifi: mac80211: Fix deadlock in ieee80211_sta_ps_deliver_wakeup()
+    - wifi: cfg80211: fully move wiphy work to unbound workqueue
+    - wifi: cfg80211: Lock wiphy in cfg80211_get_station
+    - wifi: cfg80211: pmsr: use correct nla_get_uX functions
+    - wifi: iwlwifi: mvm: don't initialize csa_work twice
+    - wifi: iwlwifi: mvm: revert gen2 TX A-MPDU size to 64
+    - wifi: iwlwifi: mvm: set properly mac header
+    - wifi: iwlwifi: dbg_ini: move iwl_dbg_tlv_free outside of debugfs ifdef
+    - wifi: iwlwifi: mvm: check n_ssids before accessing the ssids
+    - wifi: iwlwifi: mvm: don't read past the mfuart notifcation
+    - wifi: mac80211: correctly parse Spatial Reuse Parameter Set element
+    - scsi: ufs: mcq: Fix error output and clean up ufshcd_mcq_abort()
+    - RISC-V: KVM: No need to use mask when hart-index-bit is 0
+    - RISC-V: KVM: Fix incorrect reg_subtype labels in
+      kvm_riscv_vcpu_set_reg_isa_ext function
+    - ax25: Fix refcount imbalance on inbound connections
+    - ax25: Replace kfree() in ax25_dev_free() with ax25_dev_put()
+    - net/ncsi: Fix the multi thread manner of NCSI driver
+    - net: phy: micrel: fix KSZ9477 PHY issues after suspend/resume
+    - bpf: Fix a potential use-after-free in bpf_link_free()
+    - KVM: SEV-ES: Disallow SEV-ES guests when X86_FEATURE_LBRV is absent
+    - KVM: SEV-ES: Delegate LBR virtualization to the processor
+    - vmxnet3: disable rx data ring on dma allocation failure
+    - ipv6: ioam: block BH from ioam6_output()
+    - ipv6: sr: block BH in seg6_output_core() and seg6_input_core()
+    - net: tls: fix marking packets as decrypted
+    - bpf: Set run context for rawtp test_run callback
+    - octeontx2-af: Always allocate PF entries from low prioriy zone
+    - net/smc: avoid overwriting when adjusting sock bufsizes
+    - net: phy: Micrel KSZ8061: fix errata solution not taking effect problem
+    - net: sched: sch_multiq: fix possible OOB write in multiq_tune()
+    - vxlan: Fix regression when dropping packets due to invalid src addresses
+    - tcp: count CLOSE-WAIT sockets for TCP_MIB_CURRESTAB
+    - mptcp: count CLOSE-WAIT sockets for MPTCP_MIB_CURRESTAB
+    - net/mlx5: Stop waiting for PCI if pci channel is offline
+    - net/mlx5: Always stop health timer during driver removal
+    - net/mlx5: Fix tainted pointer delete is case of flow rules creation fail
+    - net/sched: taprio: always validate TCA_TAPRIO_ATTR_PRIOMAP
+    - ptp: Fix error message on failed pin verification
+    - ice: fix iteration of TLVs in Preserved Fields Area
+    - ice: remove af_xdp_zc_qps bitmap
+    - ice: add flag to distinguish reset from .ndo_bpf in XDP rings config
+    - net: wwan: iosm: Fix tainted pointer delete is case of region creation fail
+    - af_unix: Set sk->sk_state under unix_state_lock() for truly disconencted
+      peer.
+    - af_unix: Annodate data-races around sk->sk_state for writers.
+    - af_unix: Annotate data-race of sk->sk_state in unix_inq_len().
+    - af_unix: Annotate data-races around sk->sk_state in unix_write_space() and
+      poll().
+    - af_unix: Annotate data-race of sk->sk_state in unix_stream_connect().
+    - af_unix: Annotate data-races around sk->sk_state in sendmsg() and recvmsg().
+    - af_unix: Annotate data-race of sk->sk_state in unix_stream_read_skb().
+    - af_unix: Annotate data-races around sk->sk_state in UNIX_DIAG.
+    - af_unix: Annotate data-races around sk->sk_sndbuf.
+    - af_unix: Annotate data-race of net->unx.sysctl_max_dgram_qlen.
+    - af_unix: Use unix_recvq_full_lockless() in unix_stream_connect().
+    - af_unix: Use skb_queue_empty_lockless() in unix_release_sock().
+    - af_unix: Use skb_queue_len_lockless() in sk_diag_show_rqlen().
+    - af_unix: Annotate data-race of sk->sk_shutdown in sk_diag_fill().
+    - ipv6: fix possible race in __fib6_drop_pcpu_from()
+    - net: ethtool: fix the error condition in ethtool_get_phy_stats_ethtool()
+    - selftests/mm: log a consistent test name for check_compaction
+    - irqchip/riscv-intc: Allow large non-standard interrupt number
+    - irqchip/riscv-intc: Introduce Andes hart-level interrupt controller
+    - eventfs: Update all the eventfs_inodes from the events descriptor
+    - io_uring/rsrc: don't lock while !TASK_RUNNING
+    - io_uring: check for non-NULL file pointer in io_file_can_poll()
+    - USB: class: cdc-wdm: Fix CPU lockup caused by excessive log messages
+    - USB: xen-hcd: Traverse host/ when CONFIG_USB_XEN_HCD is selected
+    - usb: typec: tcpm: fix use-after-free case in tcpm_register_source_caps
+    - usb: typec: tcpm: Ignore received Hard Reset in TOGGLING state
+    - mei: me: release irq in mei_me_pci_resume error path
+    - tty: n_tty: Fix buffer offsets when lookahead is used
+    - serial: port: Don't block system suspend even if bytes are left to xmit
+    - landlock: Fix d_parent walk
+    - jfs: xattr: fix buffer overflow for invalid xattr
+    - xhci: Set correct transferred length for cancelled bulk transfers
+    - xhci: Apply reset resume quirk to Etron EJ188 xHCI host
+    - xhci: Handle TD clearing for multiple streams case
+    - xhci: Apply broken streams quirk to Etron EJ188 xHCI host
+    - thunderbolt: debugfs: Fix margin debugfs node creation condition
+    - scsi: core: Disable CDL by default
+    - scsi: mpi3mr: Fix ATA NCQ priority support
+    - scsi: mpt3sas: Avoid test/set_bit() operating in non-allocated memory
+    - scsi: sd: Use READ(16) when reading block zero on large capacity disks
+    - gve: Clear napi->skb before dev_kfree_skb_any()
+    - powerpc/uaccess: Fix build errors seen with GCC 13/14
+    - HID: nvidia-shield: Add missing check for input_ff_create_memless
+    - cxl/test: Add missing vmalloc.h for tools/testing/cxl/test/mem.c
+    - cxl/region: Fix memregion leaks in devm_cxl_add_region()
+    - cachefiles: add output string to cachefiles_obj_[get|put]_ondemand_fd
+    - cachefiles: remove requests from xarray during flushing requests
+    - cachefiles: add spin_lock for cachefiles_ondemand_info
+    - cachefiles: fix slab-use-after-free in cachefiles_ondemand_get_fd()
+    - cachefiles: fix slab-use-after-free in cachefiles_ondemand_daemon_read()
+    - cachefiles: remove err_put_fd label in cachefiles_ondemand_daemon_read()
+    - cachefiles: never get a new anonymous fd if ondemand_id is valid
+    - cachefiles: defer exposing anon_fd until after copy_to_user() succeeds
+    - cachefiles: flush all requests after setting CACHEFILES_DEAD
+    - selftests/ftrace: Fix to check required event file
+    - clk: sifive: Do not register clkdevs for PRCI clocks
+    - NFSv4.1 enforce rootpath check in fs_location query
+    - SUNRPC: return proper error from gss_wrap_req_priv
+    - NFS: add barriers when testing for NFS_FSDATA_BLOCKED
+    - selftests/tracing: Fix event filter test to retry up to 10 times
+    - nvme: fix nvme_pr_* status code parsing
+    - drm/panel: sitronix-st7789v: Add check for of_drm_get_panel_orientation
+    - platform/x86: dell-smbios: Fix wrong token data in sysfs
+    - gpio: tqmx86: fix typo in Kconfig label
+    - gpio: tqmx86: introduce shadow register for GPIO output value
+    - gpio: tqmx86: store IRQ trigger type and unmask status separately
+    - gpio: tqmx86: fix broken IRQ_TYPE_EDGE_BOTH interrupt type
+    - HID: core: remove unnecessary WARN_ON() in implement()
+    - iommu/amd: Fix sysfs leak in iommu init
+    - iommu: Return right value in iommu_sva_bind_device()
+    - io_uring/io-wq: Use set_bit() and test_bit() at worker->flags
+    - io_uring/io-wq: avoid garbage value of 'match' in io_wq_enqueue()
+    - HID: logitech-dj: Fix memory leak in logi_dj_recv_switch_to_dj_mode()
+    - drm/vmwgfx: Refactor drm connector probing for display modes
+    - drm/vmwgfx: Filter modes which exceed graphics memory
+    - drm/vmwgfx: 3D disabled should not effect STDU memory limits
+    - drm/vmwgfx: Remove STDU logic from generic mode_valid function
+    - drm/vmwgfx: Don't memcmp equivalent pointers
+    - af_unix: Annotate data-race of sk->sk_state in unix_accept().
+    - modpost: do not warn about missing MODULE_DESCRIPTION() for vmlinux.o
+    - net: sfp: Always call `sfp_sm_mod_remove()` on remove
+    - net: hns3: fix kernel crash problem in concurrent scenario
+    - net: hns3: add cond_resched() to hns3 ring buffer init process
+    - liquidio: Adjust a NULL pointer handling path in lio_vf_rep_copy_packet
+    - net: stmmac: dwmac-qcom-ethqos: Configure host DMA width
+    - drm/komeda: check for error-valued pointer
+    - drm/bridge/panel: Fix runtime warning on panel bridge release
+    - tcp: fix race in tcp_v6_syn_recv_sock()
+    - net dsa: qca8k: fix usages of device_get_named_child_node()
+    - geneve: Fix incorrect inner network header offset when innerprotoinherit is
+      set
+    - net/mlx5e: Fix features validation check for tunneled UDP (non-VXLAN)
+      packets
+    - Bluetooth: fix connection setup in l2cap_connect
+    - netfilter: nft_inner: validate mandatory meta and payload
+    - netfilter: ipset: Fix race between namespace cleanup and gc in the list:set
+      type
+    - x86/asm: Use %c/%n instead of %P operand modifier in asm templates
+    - x86/uaccess: Fix missed zeroing of ia32 u64 get_user() range checking
+    - scsi: ufs: core: Quiesce request queues before checking pending cmds
+    - net: pse-pd: Use EOPNOTSUPP error code instead of ENOTSUPP
+    - gve: ignore nonrelevant GSO type bits when processing TSO headers
+    - net: stmmac: replace priv->speed with the portTransmitRate from the tc-cbs
+      parameters
+    - block: sed-opal: avoid possible wrong address reference in
+      read_sed_opal_key()
+    - block: fix request.queuelist usage in flush
+    - nvmet-passthru: propagate status from id override functions
+    - net/ipv6: Fix the RT cache flush via sysctl using a previous delay
+    - net: bridge: mst: pass vlan group directly to br_mst_vlan_set_state
+    - net: bridge: mst: fix suspicious rcu usage in br_mst_set_state
+    - ionic: fix use after netif_napi_del()
+    - af_unix: Read with MSG_PEEK loops if the first unread byte is OOB
+    - bnxt_en: Adjust logging of firmware messages in case of released token in
+      __hwrm_send()
+    - misc: microchip: pci1xxxx: fix double free in the error handling of
+      gp_aux_bus_probe()
+    - ksmbd: move leading slash check to smb2_get_name()
+    - ksmbd: fix missing use of get_write in in smb2_set_ea()
+    - x86/boot: Don't add the EFI stub to targets, again
+    - iio: adc: ad9467: fix scan type sign
+    - iio: dac: ad5592r: fix temperature channel scaling value
+    - iio: invensense: fix odr switching to same value
+    - iio: imu: inv_icm42600: delete unneeded update watermark call
+    - drivers: core: synchronize really_probe() and dev_uevent()
+    - parisc: Try to fix random segmentation faults in package builds
+    - ACPI: x86: Force StorageD3Enable on more products
+    - drm/exynos/vidi: fix memory leak in .get_modes()
+    - drm/exynos: hdmi: report safe 640x480 mode as a fallback when no EDID found
+    - mptcp: ensure snd_una is properly initialized on connect
+    - mptcp: pm: inc RmAddr MIB counter once per RM_ADDR ID
+    - mptcp: pm: update add_addr counters after connect
+    - clkdev: Update clkdev id usage to allow for longer names
+    - irqchip/gic-v3-its: Fix potential race condition in its_vlpi_prop_update()
+    - x86/kexec: Fix bug with call depth tracking
+    - x86/amd_nb: Check for invalid SMN reads
+    - perf/core: Fix missing wakeup when waiting for context reference
+    - perf auxtrace: Fix multiple use of --itrace option
+    - riscv: fix overlap of allocated page and PTR_ERR
+    - tracing/selftests: Fix kprobe event name test for .isra. functions
+    - kheaders: explicitly define file modes for archived headers
+    - null_blk: Print correct max open zones limit in null_init_zoned_dev()
+    - sock_map: avoid race between sock_map_close and sk_psock_put
+    - dma-buf: handle testing kthreads creation failure
+    - vmci: prevent speculation leaks by sanitizing event in event_deliver()
+    - spmi: hisi-spmi-controller: Do not override device identifier
+    - knfsd: LOOKUP can return an illegal error value
+    - fs/proc: fix softlockup in __read_vmcore
+    - ocfs2: use coarse time for new created files
+    - ocfs2: fix races between hole punching and AIO+DIO
+    - PCI: rockchip-ep: Remove wrong mask on subsys_vendor_id
+    - dmaengine: axi-dmac: fix possible race in remove()
+    - remoteproc: k3-r5: Wait for core0 power-up before powering up core1
+    - remoteproc: k3-r5: Do not allow core1 to power up before core0 via sysfs
+    - iio: adc: axi-adc: make sure AXI clock is enabled
+    - iio: invensense: fix interrupt timestamp alignment
+    - riscv: rewrite __kernel_map_pages() to fix sleeping in invalid context
+    - rtla/timerlat: Simplify "no value" printing on top
+    - rtla/auto-analysis: Replace \t with spaces
+    - drm/i915/gt: Disarm breadcrumbs if engines are already idle
+    - drm/shmem-helper: Fix BUG_ON() on mmap(PROT_WRITE, MAP_PRIVATE)
+    - drm/i915/dpt: Make DPT object unshrinkable
+    - drm/i915: Fix audio component initialization
+    - intel_th: pci: Add Meteor Lake-S support
+    - pmdomain: ti-sci: Fix duplicate PD referrals
+    - btrfs: zoned: fix use-after-free due to race with dev replace
+    - xfs: fix imprecise logic in xchk_btree_check_block_owner
+    - xfs: fix scrub stats file permissions
+    - xfs: fix SEEK_HOLE/DATA for regions with active COW extents
+    - xfs: shrink failure needs to hold AGI buffer
+    - xfs: ensure submit buffers on LSN boundaries in error handlers
+    - xfs: allow sunit mount option to repair bad primary sb stripe values
+    - xfs: don't use current->journal_info
+    - xfs: allow cross-linking special files without project quota
+    - swiotlb: Enforce page alignment in swiotlb_alloc()
+    - swiotlb: Reinstate page-alignment for mappings >= PAGE_SIZE
+    - swiotlb: extend buffer pre-padding to alloc_align_mask if necessary
+    - tick/nohz_full: Don't abuse smp_call_function_single() in
+      tick_setup_device()
+    - mm/huge_memory: don't unpoison huge_zero_folio
+    - serial: 8250_pxa: Configure tx_loadsz to match FIFO IRQ level
+    - Revert "fork: defer linking file vma until vma is fully initialized"
+    - remoteproc: k3-r5: Jump to error handling labels in start/stop errors
+    - greybus: Fix use-after-free bug in gb_interface_release due to race
+      condition.
+    - ima: Fix use-after-free on a dentry's dname.name
+    - serial: core: Add UPIO_UNKNOWN constant for unknown port type
+    - serial: port: Introduce a common helper to read properties
+    - serial: 8250_dw: Switch to use uart_read_port_properties()
+    - serial: 8250_dw: Replace ACPI device check by a quirk
+    - serial: 8250_dw: Don't use struct dw8250_data outside of 8250_dw
+    - usb-storage: alauda: Check whether the media is initialized
+    - misc: microchip: pci1xxxx: Fix a memory leak in the error handling of
+      gp_aux_bus_probe()
+    - i2c: at91: Fix the functionality flags of the slave-only interface
+    - i2c: designware: Fix the functionality flags of the slave-only interface
+    - zap_pid_ns_processes: clear TIF_NOTIFY_SIGNAL along with TIF_SIGPENDING
+    - wifi: ath11k: fix WCN6750 firmware crash caused by 17 num_vdevs
+    - cpufreq: amd-pstate: Unify computation of
+      {max,min,nominal,lowest_nonlinear}_freq
+    - cpufreq: amd-pstate: Add quirk for the pstate CPPC capabilities missing
+    - cpufreq: amd-pstate: remove global header file
+    - virtio_net: fix possible dim status unrecoverable
+    - net: ethernet: mtk_eth_soc: handle dma buffer size soc specific
+    - ice: fix reads from NVM Shadow RAM on E830 and E825-C devices
+    - ice: map XDP queues to vectors in ice_vsi_map_rings_to_vectors()
+    - x86/cpu: Get rid of an unnecessary local variable in get_cpu_address_sizes()
+    - x86/cpu: Provide default cache line size if not enumerated
+    - selftests/mm: ksft_exit functions do not return
+    - selftests/mm: compaction_test: fix bogus test success and reduce probability
+      of OOM-killer invocation
+    - .editorconfig: remove trim_trailing_whitespace option
+    - kcov, usb: disable interrupts in kcov_remote_start_usb_softirq
+    - ata: libata-scsi: Set the RMB bit only for removable media devices
+    - powerpc/85xx: fix compile error without CONFIG_CRASH_DUMP
+    - kselftest/alsa: Ensure _GNU_SOURCE is defined
+    - thermal: core: Do not fail cdev registration because of invalid initial
+      state
+    - Bluetooth: hci_sync: Fix not using correct handle
+    - net/sched: initialize noop_qdisc owner
+    - tcp: use signed arithmetic in tcp_rtx_probe0_timed_out()
+    - drm/nouveau: don't attempt to schedule hpd_work on headless cards
+    - drm/xe/xe_gt_idle: use GT forcewake domain assertion
+    - drm/xe: flush engine buffers before signalling user fence on all engines
+    - drm/xe: Remove mem_access from guc_pc calls
+    - drm/xe: move disable_c6 call
+    - bnxt_en: Cap the size of HWRM_PORT_PHY_QCFG forwarded response
+    - iio: imu: bmi323: Fix trigger notification in case of error
+    - iio: pressure: bmp280: Fix BMP580 temperature reading
+    - iio: temperature: mlx90635: Fix ERR_PTR dereference in mlx90635_probe()
+    - thermal: ACPI: Invalidate trip points with temperature of 0 or below
+    - x86/mm/numa: Use NUMA_NO_NODE when calling memblock_set_node()
+    - memblock: make memblock_set_node() also warn about use of MAX_NUMNODES
+    - perf script: Show also errors for --insn-trace option
+    - wifi: cfg80211: validate HE operation element parsing
+    - wifi: rtlwifi: Ignore IEEE80211_CONF_CHANGE_RETRY_LIMITS
+    - locking/atomic: scripts: fix ${atomic}_sub_and_test() kerneldoc
+    - ata: ahci: Do not apply Intel PCS quirk on Intel Alder Lake
+    - ata: libata-core: Add ATA_HORKAGE_NOLPM for Apacer AS340
+    - ata: libata-core: Add ATA_HORKAGE_NOLPM for Crucial CT240BX500SSD1
+    - ata: libata-core: Add ATA_HORKAGE_NOLPM for AMD Radeon S3 SSD
+    - kexec: fix the unexpected kexec_dprintk() macro
+    - ocfs2: update inode fsync transaction id in ocfs2_unlink and ocfs2_link
+    - dm-integrity: set discard_granularity to logical block size
+    - drm/bridge: aux-hpd-bridge: correct devm_drm_dp_hpd_bridge_add() stub
+    - iio: temperature: mcp9600: Fix temperature reading for negative values
+    - drm/mst: Fix NULL pointer dereference at drm_dp_add_payload_part2
+    - riscv: force PAGE_SIZE linear mapping if debug_pagealloc is enabled
+    - drm/xe: Properly handle alloc_guc_id() failure
+    - wifi: iwlwifi: mvm: support iwl_dev_tx_power_cmd_v8
+    - wifi: iwlwifi: mvm: fix a crash on 7265
+    - mei: vsc: Fix wrong invocation of ACPI SID method
+    - Upstream stable to v6.6.35, v6.9.6
+  * [SRU] Add support for intel trace hub for last platforms (LP: #2073926) //
+    Noble update: upstream stable patchset 2024-07-25 (LP: #2074091)
+    - intel_th: pci: Add Granite Rapids support
+    - intel_th: pci: Add Granite Rapids SOC support
+    - intel_th: pci: Add Sapphire Rapids SOC support
+    - intel_th: pci: Add Lunar Lake support
+  * Fix L2CAP/LE/CPU/BV-02-C bluetooth certification failure (LP: #2072858) //
+    Noble update: upstream stable patchset 2024-07-25 (LP: #2074091)
+    - Bluetooth: L2CAP: Fix rejecting L2CAP_CONN_PARAM_UPDATE_REQ
+  * Noble update: upstream stable patchset 2024-07-22 (LP: #2073788)
+    - drm/i915/hwmon: Get rid of devm
+    - afs: Don't cross .backup mountpoint from backup volume
+    - erofs: avoid allocating DEFLATE streams before mounting
+    - vxlan: Fix regression when dropping packets due to invalid src addresses
+    - drm/sun4i: hdmi: Convert encoder to atomic
+    - drm/sun4i: hdmi: Move mode_set into enable
+    - f2fs: fix to do sanity check on i_xattr_nid in sanity_check_inode()
+    - media: lgdt3306a: Add a check against null-pointer-def
+    - drm/amdgpu: add error handle to avoid out-of-bounds
+    - wifi: rtw89: correct aSIFSTime for 6GHz band
+    - ata: pata_legacy: make legacy_exit() work again
+    - fsverity: use register_sysctl_init() to avoid kmemleak warning
+    - proc: Move fdinfo PTRACE_MODE_READ check into the inode .permission
+      operation
+    - platform/chrome: cros_ec: Handle events during suspend after resume
+      completion
+    - thermal/drivers/qcom/lmh: Check for SCM availability at probe
+    - soc: qcom: rpmh-rsc: Enhance check for VRM in-flight request
+    - ACPI: resource: Do IRQ override on TongFang GXxHRXx and GMxHGxx
+    - arm64: tegra: Correct Tegra132 I2C alias
+    - arm64: dts: qcom: qcs404: fix bluetooth device address
+    - md/raid5: fix deadlock that raid5d() wait for itself to clear
+      MD_SB_CHANGE_PENDING
+    - wifi: rtl8xxxu: Fix the TX power of RTL8192CU, RTL8723AU
+    - wifi: rtlwifi: rtl8192de: Fix 5 GHz TX power
+    - wifi: rtlwifi: rtl8192de: Fix low speed with WPA3-SAE
+    - wifi: rtlwifi: rtl8192de: Fix endianness issue in RX path
+    - arm64: dts: qcom: sc8280xp: add missing PCIe minimum OPP
+    - arm64: dts: hi3798cv200: fix the size of GICR
+    - arm64: dts: ti: verdin-am62: Set memory size to 2gb
+    - media: mc: Fix graph walk in media_pipeline_start
+    - media: mc: mark the media devnode as registered from the, start
+    - media: mxl5xx: Move xpt structures off stack
+    - media: v4l2-core: hold videodev_lock until dev reg, finishes
+    - media: v4l: async: Properly re-initialise notifier entry in unregister
+    - media: v4l: async: Don't set notifier's V4L2 device if registering fails
+    - media: v4l: async: Fix notifier list entry init
+    - mmc: core: Add mmc_gpiod_set_cd_config() function
+    - mmc: sdhci: Add support for "Tuning Error" interrupts
+    - mmc: sdhci-acpi: Sort DMI quirks alphabetically
+    - mmc: sdhci-acpi: Fix Lenovo Yoga Tablet 2 Pro 1380 sdcard slot not working
+    - mmc: sdhci-acpi: Disable write protect detection on Toshiba WT10-A
+    - mmc: sdhci-acpi: Add quirk to enable pull-up on the card-detect GPIO on Asus
+      T100TA
+    - drm/fbdev-generic: Do not set physical framebuffer address
+    - fbdev: savage: Handle err return when savagefb_check_var failed
+    - drm/amdgpu/atomfirmware: add intergrated info v2.3 table
+    - 9p: add missing locking around taking dentry fid list
+    - drm/amd: Fix shutdown (again) on some SMU v13.0.4/11 platforms
+    - Revert "drm/amdkfd: fix gfx_target_version for certain 11.0.3 devices"
+    - KVM: SVM: WARN on vNMI + NMI window iff NMIs are outright masked
+    - KVM: arm64: Fix AArch32 register narrowing on userspace write
+    - KVM: arm64: Allow AArch32 PSTATE.M to be restored as System mode
+    - KVM: arm64: AArch32: Fix spurious trapping of conditional instructions
+    - LoongArch: Add all CPUs enabled by fdt to NUMA node 0
+    - LoongArch: Override higher address bits in JUMP_VIRT_ADDR
+    - clk: bcm: dvp: Assign ->num before accessing ->hws
+    - clk: bcm: rpi: Assign ->num before accessing ->hws
+    - clk: qcom: clk-alpha-pll: fix rate setting for Stromer PLLs
+    - crypto: ecdsa - Fix module auto-load on add-key
+    - crypto: ecrdsa - Fix module auto-load on add_key
+    - crypto: qat - Fix ADF_DEV_RESET_SYNC memory leak
+    - kbuild: Remove support for Clang's ThinLTO caching
+    - mm: fix race between __split_huge_pmd_locked() and GUP-fast
+    - filemap: add helper mapping_max_folio_size()
+    - iomap: fault in smaller chunks for non-large folio mappings
+    - i2c: acpi: Unbind mux adapters before delete
+    - HID: i2c-hid: elan: fix reset suspend current leakage
+    - scsi: core: Handle devices which return an unusually large VPD page count
+    - net/ipv6: Fix route deleting failure when metric equals 0
+    - net/9p: fix uninit-value in p9_client_rpc()
+    - mm/ksm: fix ksm_pages_scanned accounting
+    - mm/ksm: fix ksm_zero_pages accounting
+    - kmsan: do not wipe out origin when doing partial unpoisoning
+    - tpm_tis: Do *not* flush uninitialized work
+    - intel_th: pci: Add Meteor Lake-S CPU support
+    - rtla/timerlat: Fix histogram report when a cpu count is 0
+    - sparc64: Fix number of online CPUs
+    - mm/cma: drop incorrect alignment check in cma_init_reserved_mem
+    - mm/hugetlb: pass correct order_per_bit to cma_declare_contiguous_nid
+    - mm: /proc/pid/smaps_rollup: avoid skipping vma after getting mmap_lock again
+    - mm/vmalloc: fix vmalloc which may return null if called with __GFP_NOFAIL
+    - selftests/mm: compaction_test: fix incorrect write of zero to nr_hugepages
+    - selftests/mm: fix build warnings on ppc64
+    - watchdog: rti_wdt: Set min_hw_heartbeat_ms to accommodate a safety margin
+    - bonding: fix oops during rmmod
+    - wifi: ath10k: fix QCOM_RPROC_COMMON dependency
+    - kdb: Fix buffer overflow during tab-complete
+    - kdb: Use format-strings rather than '\0' injection in kdb_read()
+    - kdb: Fix console handling when editing and tab-completing commands
+    - kdb: Merge identical case statements in kdb_read()
+    - kdb: Use format-specifiers rather than memset() for padding in kdb_read()
+    - sparc: move struct termio to asm/termios.h
+    - drm/amdkfd: handle duplicate BOs in reserve_bo_and_cond_vms
+    - ext4: Fixes len calculation in mpage_journal_page_buffers
+    - ext4: set type of ac_groups_linear_remaining to __u32 to avoid overflow
+    - ext4: fix mb_cache_entry's e_refcnt leak in ext4_xattr_block_cache_find()
+    - riscv: dts: starfive: Remove PMIC interrupt info for Visionfive 2 board
+    - ARM: dts: samsung: smdkv310: fix keypad no-autorepeat
+    - ARM: dts: samsung: smdk4412: fix keypad no-autorepeat
+    - ARM: dts: samsung: exynos4412-origen: fix keypad no-autorepeat
+    - parisc: Define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+    - parisc: Define sigset_t in parisc uapi header
+    - s390/ap: Fix crash in AP internal function modify_bitmap()
+    - s390/cpacf: Split and rework cpacf query functions
+    - s390/cpacf: Make use of invalid opcode produce a link error
+    - i3c: master: svc: fix invalidate IBI type and miss call client IBI handler
+    - genirq/irqdesc: Prevent use-after-free in irq_find_at_or_after()
+    - ASoC: SOF: ipc4-topology: Fix input format query of process modules without
+      base extension
+    - ALSA: ump: Don't clear bank selection after sending a program change
+    - ALSA: ump: Don't accept an invalid UMP protocol number
+    - EDAC/amd64: Convert PCIBIOS_* return codes to errnos
+    - EDAC/igen6: Convert PCIBIOS_* return codes to errnos
+    - nfs: fix undefined behavior in nfs_block_bits()
+    - NFS: Fix READ_PLUS when server doesn't support OP_READ_PLUS
+    - eventfs: Fix a possible null pointer dereference in eventfs_find_events()
+    - eventfs: Keep the directories from having the same inode number as files
+    - tracefs: Clear EVENT_INODE flag in tracefs_drop_inode()
+    - btrfs: fix crash on racing fsync and size-extending write into prealloc
+    - btrfs: fix leak of qgroup extent records after transaction abort
+    - ALSA: seq: Fix incorrect UMP type for system messages
+    - powerpc/bpf: enforce full ordering for ATOMIC operations with BPF_FETCH
+    - smb: client: fix deadlock in smb2_find_smb_tcon()
+    - smp: Provide 'setup_max_cpus' definition on UP too
+    - drm/xe/bb: assert width in xe_bb_create_job()
+    - crypto: starfive - Do not free stack buffer
+    - btrfs: qgroup: fix initialization of auto inherit array
+    - wifi: rtl8xxxu: enable MFP support with security flag of RX descriptor
+    - media: mgb4: Fix double debugfs remove
+    - media: ov2740: Fix LINK_FREQ and PIXEL_RATE control value reporting
+    - firmware: qcom_scm: disable clocks if qcom_scm_bw_enable() fails
+    - LoongArch: Fix built-in DTB detection
+    - LoongArch: Fix entry point in kernel image header
+    - clk: qcom: apss-ipq-pll: use stromer ops for IPQ5018 to fix boot failure
+    - net/tcp: Don't consider TCP_CLOSE in TCP_AO_ESTABLISHED
+    - selftests: net: lib: support errexit with busywait
+    - selftests: net: lib: avoid error removing empty netns name
+    - cpufreq: amd-pstate: Fix the inconsistency in max frequency units
+    - mm/memory-failure: fix handling of dissolved but not taken off from buddy
+      pages
+    - selftests/mm: compaction_test: fix bogus test success on Aarch64
+    - irqchip/riscv-intc: Prevent memory leak when riscv_intc_init_common() fails
+    - Revert "perf record: Reduce memory for recording PERF_RECORD_LOST_SAMPLES
+      event"
+    - hwmon: (ltc2992) Fix memory leak in ltc2992_parse_dt()
+    - riscv: enable HAVE_ARCH_HUGE_VMAP for XIP kernel
+    - btrfs: qgroup: update rescan message levels and error codes
+    - btrfs: qgroup: fix qgroup id collision across mounts
+    - btrfs: cache folio size and shift in extent_buffer
+    - btrfs: protect folio::private when attaching extent buffer folios
+    - bpf: fix multi-uprobe PID filtering logic
+    - powerpc/64/bpf: fix tail calls for PCREL addressing
+    - nilfs2: fix potential kernel bug due to lack of writeback flag waiting
+    - nilfs2: fix nilfs_empty_dir() misjudgment and long loop on I/O errors
+    - Upstream stable to v6.6.34, v6.9.5
+  * Noble update: upstream stable patchset 2024-07-19 (LP: #2073603)
+    - perf record: Delete session after stopping sideband thread
+    - perf probe: Add missing libgen.h header needed for using basename()
+    - iio: core: Leave private pointer NULL when no private data supplied
+    - greybus: lights: check return of get_channel_from_mode
+    - phy: qcom: qmp-combo: fix duplicate return in qmp_v4_configure_dp_phy
+    - f2fs: multidev: fix to recognize valid zero block address
+    - f2fs: fix to wait on page writeback in __clone_blkaddrs()
+    - fpga: manager: add owner module and take its refcount
+    - fpga: bridge: add owner module and take its refcount
+    - counter: linux/counter.h: fix Excess kernel-doc description warning
+    - perf annotate: Get rid of duplicate --group option item
+    - usb: typec: ucsi: always register a link to USB PD device
+    - usb: typec: ucsi: simplify partner's PD caps registration
+    - perf stat: Do not fail on metrics on s390 z/VM systems
+    - soundwire: cadence: fix invalid PDI offset
+    - dmaengine: idma64: Add check for dma_set_max_seg_size
+    - firmware: dmi-id: add a release callback function
+    - perf annotate: Fix annotation_calc_lines() to pass correct address to
+      get_srcline()
+    - serial: max3100: Lock port->lock when calling uart_handle_cts_change()
+    - serial: max3100: Update uart_driver_registered on driver removal
+    - serial: max3100: Fix bitwise types
+    - greybus: arche-ctrl: move device table to its right location
+    - PCI: tegra194: Fix probe path for Endpoint mode
+    - serial: sc16is7xx: add proper sched.h include for sched_set_fifo()
+    - module: don't ignore sysfs_create_link() failures
+    - interconnect: qcom: qcm2290: Fix mas_snoc_bimc QoS port assignment
+    - arm64: dts: meson: fix S4 power-controller node
+    - perf tests: Make "test data symbol" more robust on Neoverse N1
+    - perf tests: Apply attributes to all events in object code reading test
+    - perf record: Fix debug message placement for test consumption
+    - dt-bindings: PCI: rcar-pci-host: Add missing IOMMU properties
+    - perf bench uprobe: Remove lib64 from libc.so.6 binary path
+    - f2fs: compress: fix to relocate check condition in
+      f2fs_{release,reserve}_compress_blocks()
+    - f2fs: compress: fix to relocate check condition in
+      f2fs_ioc_{,de}compress_file()
+    - f2fs: fix to relocate check condition in f2fs_fallocate()
+    - f2fs: fix to check pinfile flag in f2fs_move_file_range()
+    - iio: adc: stm32: Fixing err code to not indicate success
+    - riscv: dts: starfive: visionfive 2: Remove non-existing TDM hardware
+    - coresight: etm4x: Fix unbalanced pm_runtime_enable()
+    - perf docs: Document bpf event modifier
+    - perf test shell arm_coresight: Increase buffer size for Coresight basic
+      tests
+    - iio: pressure: dps310: support negative temperature values
+    - iio: buffer-dmaengine: export buffer alloc and free functions
+    - iio: add the IIO backend framework
+    - [CONFIG] Update CONFIG_IIO_BACKEND
+    - iio: adc: ad9467: convert to backend framework
+    - [Config] Update CONFIG_AD9467
+    - iio: adc: adi-axi-adc: move to backend framework
+    - [Config] Update CONFIG_ADI_AXI_ADC
+    - iio: adc: adi-axi-adc: only error out in major version mismatch
+    - coresight: etm4x: Do not hardcode IOMEM access for register restore
+    - coresight: etm4x: Do not save/restore Data trace control registers
+    - coresight: etm4x: Safe access for TRCQCLTR
+    - coresight: etm4x: Fix access to resource selector registers
+    - vfio/pci: fix potential memory leak in vfio_intx_enable()
+    - fpga: region: add owner module and take its refcount
+    - udf: Remove GFP_NOFS allocation in udf_expand_file_adinicb()
+    - udf: Convert udf_expand_file_adinicb() to use a folio
+    - microblaze: Remove gcc flag for non existing early_printk.c file
+    - microblaze: Remove early printk call from cpuinfo-static.c
+    - PCI: Wait for Link Training==0 before starting Link retrain
+    - perf intel-pt: Fix unassigned instruction op (discovered by MemorySanitizer)
+    - leds: pwm: Disable PWM when going to suspend
+    - ovl: remove upper umask handling from ovl_create_upper()
+    - PCI: of_property: Return error for int_map allocation failure
+    - VMCI: Fix an error handling path in vmci_guest_probe_device()
+    - dt-bindings: pinctrl: mediatek: mt7622: fix array properties
+    - pinctrl: qcom: pinctrl-sm7150: Fix sdc1 and ufs special pins regs
+    - watchdog: cpu5wdt.c: Fix use-after-free bug caused by cpu5wdt_trigger
+    - watchdog: bd9576: Drop "always-running" property
+    - watchdog: sa1100: Fix PTR_ERR_OR_ZERO() vs NULL check in sa1100dog_probe()
+    - dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: fix msm899[68] power-domains
+    - dt-bindings: phy: qcom,usb-snps-femto-v2: use correct fallback for sc8180x
+    - dmaengine: idxd: Avoid unnecessary destruction of file_ida
+    - usb: gadget: u_audio: Fix race condition use of controls after free during
+      gadget unbind.
+    - usb: gadget: u_audio: Clear uac pointer when freed.
+    - stm class: Fix a double free in stm_register_device()
+    - ppdev: Add an error check in register_device
+    - i2c: cadence: Avoid fifo clear after start
+    - i2c: synquacer: Fix an error handling path in synquacer_i2c_probe()
+    - perf bench internals inject-build-id: Fix trap divide when collecting just
+      one DSO
+    - perf ui browser: Don't save pointer to stack memory
+    - extcon: max8997: select IRQ_DOMAIN instead of depending on it
+    - dt-bindings: spmi: hisilicon,hisi-spmi-controller: fix binding references
+    - PCI/EDR: Align EDR_PORT_DPC_ENABLE_DSM with PCI Firmware r3.3
+    - PCI/EDR: Align EDR_PORT_LOCATE_DSM with PCI Firmware r3.3
+    - f2fs: support printk_ratelimited() in f2fs_printk()
+    - f2fs: use BLKS_PER_SEG, BLKS_PER_SEC, and SEGS_PER_SEC
+    - f2fs: separate f2fs_gc_range() to use GC for a range
+    - f2fs: kill heap-based allocation
+    - f2fs: support file pinning for zoned devices
+    - f2fs: fix block migration when section is not aligned to pow2
+    - perf ui browser: Avoid SEGV on title
+    - perf report: Avoid SEGV in report__setup_sample_type()
+    - perf thread: Fixes to thread__new() related to initializing comm
+    - perf symbols: Fix ownership of string in dso__load_vmlinux()
+    - f2fs: compress: fix to update i_compr_blocks correctly
+    - f2fs: deprecate io_bits
+    - f2fs: introduce get_available_block_count() for cleanup
+    - f2fs: compress: fix error path of inc_valid_block_count()
+    - f2fs: compress: fix to cover {reserve,release}_compress_blocks() w/ cp_rwsem
+      lock
+    - f2fs: fix to release node block count in error path of f2fs_new_node_page()
+    - f2fs: compress: don't allow unaligned truncation on released compress inode
+    - serial: sh-sci: protect invalidating RXDMA on shutdown
+    - libsubcmd: Fix parse-options memory leak
+    - perf daemon: Fix file leak in daemon_session__control
+    - f2fs: fix to add missing iput() in gc_data_segment()
+    - usb: fotg210: Add missing kernel doc description
+    - perf stat: Don't display metric header for non-leader uncore events
+    - perf tools: Use pmus to describe type from attribute
+    - perf tools: Add/use PMU reverse lookup from config to name
+    - perf pmu: Assume sysfs events are always the same case
+    - perf pmu: Count sys and cpuid JSON events separately
+    - LoongArch: Fix callchain parse error with kernel tracepoint events again
+    - s390/vdso64: filter out munaligned-symbols flag for vdso
+    - s390/vdso: Generate unwind information for C modules
+    - s390/vdso: Create .build-id links for unstripped vdso files
+    - s390/vdso: Use standard stack frame layout
+    - s390/ipl: Fix incorrect initialization of len fields in nvme reipl block
+    - s390/ipl: Fix incorrect initialization of nvme dump block
+    - s390/boot: Remove alt_stfle_fac_list from decompressor
+    - dt-bindings: PCI: rockchip,rk3399-pcie: Add missing maxItems to ep-gpios
+    - gpiolib: acpi: Fix failed in acpi_gpiochip_find() by adding parent node
+      match
+    - eventfs: Do not differentiate the toplevel events directory
+    - eventfs: Create eventfs_root_inode to store dentry
+    - eventfs/tracing: Add callback for release of an eventfs_inode
+    - eventfs: Free all of the eventfs_inode after RCU
+    - eventfs: Have "events" directory get permissions from its parent
+    - dt-bindings: adc: axi-adc: update bindings for backend framework
+    - dt-bindings: adc: axi-adc: add clocks property
+    - Input: ims-pcu - fix printf string overflow
+    - mmc: sdhci_am654: Add tuning algorithm for delay chain
+    - mmc: sdhci_am654: Write ITAPDLY for DDR52 timing
+    - mmc: sdhci_am654: Add OTAP/ITAP delay enable
+    - mmc: sdhci_am654: Add ITAPDLYSEL in sdhci_j721e_4bit_set_clock
+    - mmc: sdhci_am654: Fix ITAPDLY for HS400 timing
+    - Input: pm8xxx-vibrator - correct VIB_MAX_LEVELS calculation
+    - media: v4l: Don't turn on privacy LED if streamon fails
+    - media: ov2680: Clear the 'ret' variable on success
+    - media: ov2680: Allow probing if link-frequencies is absent
+    - media: ov2680: Do not fail if data-lanes property is absent
+    - drm/msm/dsi: Print dual-DSI-adjusted pclk instead of original mode pclk
+    - drm/msm/dpu: Always flush the slave INTF on the CTL
+    - drm/mediatek: dp: Fix mtk_dp_aux_transfer return value
+    - drm/meson: gate px_clk when setting rate
+    - um: Fix return value in ubd_init()
+    - um: vector: fix bpfflash parameter evaluation
+    - fs/ntfs3: Check 'folio' pointer for NULL
+    - fs/ntfs3: Use 64 bit variable to avoid 32 bit overflow
+    - fs/ntfs3: Use variable length array instead of fixed size
+    - drm/msm/dpu: Add callback function pointer check before its call
+    - drm/bridge: tc358775: fix support for jeida-18 and jeida-24
+    - media: stk1160: fix bounds checking in stk1160_copy_video()
+    - Input: cyapa - add missing input core locking to suspend/resume functions
+    - drm/amdgpu: init microcode chip name from ip versions
+    - drm/amdgpu: Fix buffer size in gfx_v9_4_3_init_ cp_compute_microcode() and
+      rlc_microcode()
+    - media: mediatek: vcodec: fix possible unbalanced PM counter
+    - tools/arch/x86/intel_sdsi: Fix maximum meter bundle length
+    - tools/arch/x86/intel_sdsi: Fix meter_show display
+    - tools/arch/x86/intel_sdsi: Fix meter_certificate decoding
+    - platform/x86: thinkpad_acpi: Take hotkey_mutex during hotkey_exit()
+    - media: flexcop-usb: fix sanity check of bNumEndpoints
+    - powerpc/pseries: Add failure related checks for h_get_mpp and h_get_ppp
+    - um: Fix the -Wmissing-prototypes warning for __switch_mm
+    - um: Fix the -Wmissing-prototypes warning for get_thread_reg
+    - um: Fix the declaration of kasan_map_memory
+    - cxl/trace: Correct DPA field masks for general_media & dram events
+    - cxl/region: Fix cxlr_pmem leaks
+    - media: sunxi: a83-mips-csi2: also select GENERIC_PHY
+    - media: cec: cec-adap: always cancel work in cec_transmit_msg_fh
+    - media: cec: cec-api: add locking in cec_release()
+    - media: cec: core: avoid recursive cec_claim_log_addrs
+    - media: cec: core: avoid confusing "transmit timed out" message
+    - Revert "drm/bridge: ti-sn65dsi83: Fix enable error path"
+    - drm: zynqmp_dpsub: Always register bridge
+    - selftests/powerpc/dexcr: Add -no-pie to hashchk tests
+    - drm/msm/a6xx: Avoid a nullptr dereference when speedbin setting fails
+    - ASoC: tas2781: Fix a warning reported by robot kernel test
+    - null_blk: Fix the WARNING: modpost: missing MODULE_DESCRIPTION()
+    - ALSA: hda/cs_dsp_ctl: Use private_free for control cleanup
+    - ALSA: hda: cs35l56: Fix lifetime of cs_dsp instance
+    - ASoC: mediatek: mt8192: fix register configuration for tdm
+    - drm/nouveau: use tile_mode and pte_kind for VM_BIND bo allocations
+    - blk-cgroup: fix list corruption from resetting io stat
+    - blk-cgroup: fix list corruption from reorder of WRITE ->lqueued
+    - blk-cgroup: Properly propagate the iostat update up the hierarchy
+    - regulator: bd71828: Don't overwrite runtime voltages
+    - xen/x86: add extra pages to unpopulated-alloc if available
+    - perf/arm-dmc620: Fix lockdep assert in ->event_init()
+    - x86/kconfig: Select ARCH_WANT_FRAME_POINTERS again when
+      UNWINDER_FRAME_POINTER=y
+    - [Config] Update CONFIG_ARCH_WANT_FRAME_POINTERS
+    - net: Always descend into dsa/ folder with CONFIG_NET_DSA enabled
+    - ipv6: sr: fix missing sk_buff release in seg6_input_core
+    - selftests: net: kill smcrouted in the cleanup logic in amt.sh
+    - nfc: nci: Fix uninit-value in nci_rx_work
+    - ASoC: tas2552: Add TX path for capturing AUDIO-OUT data
+    - ASoC: tas2781: Fix wrong loading calibrated data sequence
+    - NFSv4: Fixup smatch warning for ambiguous return
+    - nfs: keep server info for remounts
+    - sunrpc: fix NFSACL RPC retry on soft mount
+    - rpcrdma: fix handling for RDMA_CM_EVENT_DEVICE_REMOVAL
+    - regulator: pickable ranges: don't always cache vsel
+    - regulator: tps6287x: Force writing VSEL bit
+    - af_unix: Update unix_sk(sk)->oob_skb under sk_receive_queue lock.
+    - ipv6: sr: fix memleak in seg6_hmac_init_algo
+    - regulator: tps6594-regulator: Correct multi-phase configuration
+    - tcp: Fix shift-out-of-bounds in dctcp_update_alpha().
+    - pNFS/filelayout: fixup pNfs allocation modes
+    - openvswitch: Set the skbuff pkt_type for proper pmtud support.
+    - arm64: asm-bug: Add .align 2 to the end of __BUG_ENTRY
+    - rv: Update rv_en(dis)able_monitor doc to match kernel-doc
+    - net: lan966x: Remove ptp traps in case the ptp is not enabled.
+    - virtio: delete vq in vp_find_vqs_msix() when request_irq() fails
+    - i3c: master: svc: change ENXIO to EAGAIN when IBI occurs during start frame
+    - Revert "ixgbe: Manual AN-37 for troublesome link partners for X550 SFI"
+    - net: fec: avoid lock evasion when reading pps_enable
+    - tls: fix missing memory barrier in tls_init
+    - net: relax socket state check at accept time.
+    - nfc: nci: Fix handling of zero-length payload packets in nci_rx_work()
+    - drivers/xen: Improve the late XenStore init protocol
+    - ice: Interpret .set_channels() input differently
+    - kasan, fortify: properly rename memintrinsics
+    - tracing/probes: fix error check in parse_btf_field()
+    - tpm_tis_spi: Account for SPI header when allocating TPM SPI xfer buffer
+    - netfilter: nfnetlink_queue: acquire rcu_read_lock() in
+      instance_destroy_rcu()
+    - netfilter: ipset: Add list flush to cancel_gc
+    - netfilter: nft_payload: restore vlan q-in-q match support
+    - spi: Don't mark message DMA mapped when no transfer in it is
+    - dma-mapping: benchmark: fix up kthread-related error handling
+    - dma-mapping: benchmark: fix node id validation
+    - dma-mapping: benchmark: handle NUMA_NO_NODE correctly
+    - nvme-multipath: fix io accounting on failover
+    - nvmet: fix ns enable/disable possible hang
+    - drm/amd/display: Enable colorspace property for MST connectors
+    - net: phy: micrel: set soft_reset callback to genphy_soft_reset for KSZ8061
+    - net/mlx5: Lag, do bond only if slaves agree on roce state
+    - net/mlx5: Fix MTMP register capability offset in MCAM register
+    - net/mlx5: Use mlx5_ipsec_rx_status_destroy to correctly delete status rules
+    - net/mlx5e: Fix IPsec tunnel mode offload feature check
+    - net/mlx5e: Use rx_missed_errors instead of rx_dropped for reporting buffer
+      exhaustion
+    - net/mlx5e: Fix UDP GSO for encapsulated packets
+    - dma-buf/sw-sync: don't enable IRQ from sync_print_obj()
+    - bpf: Fix potential integer overflow in resolve_btfids
+    - ALSA: jack: Use guard() for locking
+    - ALSA: core: Remove debugfs at disconnection
+    - ALSA: hda/realtek: Adjust G814JZR to use SPI init for amp
+    - enic: Validate length of nl attributes in enic_set_vf_port
+    - af_unix: Annotate data-race around unix_sk(sk)->addr.
+    - af_unix: Read sk->sk_hash under bindlock during bind().
+    - Octeontx2-pf: Free send queue buffers incase of leaf to inner
+    - net: usb: smsc95xx: fix changing LED_SEL bit value updated from EEPROM
+    - ASoC: cs42l43: Only restrict 44.1kHz for the ASP
+    - bpf: Allow delete from sockmap/sockhash only if update is allowed
+    - net:fec: Add fec_enet_deinit()
+    - net: micrel: Fix lan8841_config_intr after getting out of sleep mode
+    - ice: fix accounting if a VLAN already exists
+    - selftests: mptcp: simult flows: mark 'unbalanced' tests as flaky
+    - selftests: mptcp: add ms units for tc-netem delay
+    - selftests: mptcp: join: mark 'fail' tests as flaky
+    - ALSA: seq: Fix missing bank setup between MIDI1/MIDI2 UMP conversion
+    - ALSA: seq: Don't clear bank selection at event -> UMP MIDI2 conversion
+    - net: ti: icssg-prueth: Fix start counter for ft1 filter
+    - netfilter: nft_payload: skbuff vlan metadata mangle support
+    - netfilter: tproxy: bail out if IP has been disabled on the device
+    - netfilter: nft_fib: allow from forward/input without iif selector
+    - net/sched: taprio: make q->picos_per_byte available to fill_sched_entry()
+    - net/sched: taprio: extend minimum interval restriction to entire cycle too
+    - kconfig: fix comparison to constant symbols, 'm', 'n'
+    - drm/i915/guc: avoid FIELD_PREP warning
+    - kheaders: use `command -v` to test for existence of `cpio`
+    - spi: stm32: Don't warn about spurious interrupts
+    - net: dsa: microchip: fix RGMII error in KSZ DSA driver
+    - net: ena: Reduce lines with longer column width boundary
+    - net: ena: Fix redundant device NUMA node override
+    - ipvlan: Dont Use skb->sk in ipvlan_process_v{4,6}_outbound
+    - ALSA: seq: Fix yet another spot for system message conversion
+    - powerpc/pseries/lparcfg: drop error message from guest name lookup
+    - drm/panel: sitronix-st7789v: fix timing for jt240mhqs_hwt_ek_e3 panel
+    - drm/panel: sitronix-st7789v: tweak timing for jt240mhqs_hwt_ek_e3 panel
+    - drm/panel: sitronix-st7789v: fix display size for jt240mhqs_hwt_ek_e3 panel
+    - hwmon: (intel-m10-bmc-hwmon) Fix multiplier for N6000 board power sensor
+    - hwmon: (shtc1) Fix property misspelling
+    - ALSA: seq: ump: Fix swapped song position pointer data
+    - ALSA: timer: Set lower bound of start tick time
+    - x86/efistub: Omit physical KASLR when memory reservations exist
+    - efi: libstub: only free priv.runtime_map when allocated
+    - x86/pci: Skip early E820 check for ECAM region
+    - KVM: x86: Don't advertise guest.MAXPHYADDR as host.MAXPHYADDR in CPUID
+    - genirq/cpuhotplug, x86/vector: Prevent vector leak during CPU offline
+    - platform/x86/intel/tpmi: Handle error from tpmi_process_info()
+    - platform/x86/intel-uncore-freq: Don't present root domain on error
+    - perf sched timehist: Fix -g/--call-graph option failure
+    - f2fs: write missing last sum blk of file pinning section
+    - f2fs: use f2fs_{err,info}_ratelimited() for cleanup
+    - SUNRPC: Fix loop termination condition in gss_free_in_token_pages()
+    - riscv: prevent pt_regs corruption for secondary idle threads
+    - riscv: stacktrace: fixed walk_stackframe()
+    - perf build: Fix out of tree build related to installation of sysreg-defs
+    - dt-bindings: pinctrl: qcom: update functions to match with driver
+    - usb: typec: ucsi: allow non-partner GET_PDOS for Qualcomm devices
+    - perf report: Fix PAI counter names for s390 virtual machines
+    - PCI: dwc: ep: Fix DBI access failure for drivers requiring refclk from host
+    - perf map: Remove kernel map before updating start and end addresses
+    - riscv: dts: starfive: visionfive 2: Remove non-existing I2S hardware
+    - pinctrl: renesas: rzg2l: Limit 2.5V power supply to Ethernet interfaces
+    - riscv: Flush the instruction cache during SMP bringup
+    - usb: xhci: check if 'requested segments' exceeds ERST capacity
+    - spmi: pmic-arb: Replace three IS_ERR() calls by null pointer checks in
+      spmi_pmic_arb_probe()
+    - perf symbols: Remove map from list before updating addresses
+    - perf symbols: Update kcore map before merging in remaining symbols
+    - s390/ftrace: Use unwinder instead of __builtin_return_address()
+    - s390/stacktrace: Merge perf_callchain_user() and arch_stack_walk_user()
+    - s390/stacktrace: Skip first user stack frame
+    - s390/stacktrace: Improve detection of invalid instruction pointers
+    - s390/vdso: Introduce and use struct stack_frame_vdso_wrapper
+    - s390/stackstrace: Detect vdso stack frames
+    - s390/ap: Fix bind complete udev event sent after each AP bus scan
+    - ocfs2: correctly use ocfs2_find_next_zero_bit()
+    - mailbox: mtk-cmdq: Fix pm_runtime_get_sync() warning in mbox shutdown
+    - Input: ioc3kbd - add device table
+    - phy: qcom: qmp-combo: fix sm8650 voltage swing table
+    - media: ti: j721e-csi2rx: Fix races while restarting DMA
+    - drm/msm/dpu: Allow configuring multiple active DSC blocks
+    - drm: Make drivers depends on DRM_DW_HDMI
+    - [Config] Drivers now depend on DRM_DW_HDMI
+    - string: Prepare to merge strscpy_kunit.c into string_kunit.c
+    - string: Prepare to merge strcat KUnit tests into string_kunit.c
+    - drm/msm/adreno: fix CP cycles stat retrieval on a7xx
+    - printk: Fix LOG_CPU_MAX_BUF_SHIFT when BASE_SMALL is enabled
+    - powerpc/bpf/32: Fix failing test_bpf tests
+    - KVM: PPC: Book3S HV nestedv2: Cancel pending DEC exception
+    - KVM: PPC: Book3S HV nestedv2: Fix an error handling path in
+      gs_msg_ops_kvmhv_nestedv2_config_fill_info()
+    - KVM: arm64: Destroy mpidr_data for 'late' vCPU creation
+    - Bluetooth: ISO: Handle PA sync when no BIGInfo reports are generated
+    - Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init()
+    - ubsan: Restore dependency on ARCH_HAS_UBSAN
+    - selftests: forwarding: Have RET track kselftest framework constants
+    - selftests: forwarding: Convert log_test() to recognize RET values
+    - selftests: net: Unify code of busywait() and slowwait()
+    - selftests/net: use tc rule to filter the na packet
+    - virtio_balloon: Give the balloon its own wakeup source
+    - riscv: cpufeature: Fix thead vector hwcap removal
+    - riscv: cpufeature: Fix extension subset checking
+    - riscv: selftests: Add hwprobe binaries to .gitignore
+    - idpf: Interpret .set_channels() input differently
+    - null_blk: fix null-ptr-dereference while configuring 'power' and
+      'submit_queues'
+    - netfs: Fix setting of BDP_ASYNC from iocb flags
+    - cifs: Set zero_point in the copy_file_range() and remap_file_range()
+    - cifs: Fix missing set of remote_i_size
+    - selftests: net: lib: set 'i' as local
+    - nvme: fix multipath batched completion accounting
+    - netkit: Fix setting mac address in l2 mode
+    - netkit: Fix pkt_type override upon netkit pass verdict
+    - null_blk: Fix return value of nullb_device_power_store()
+    - idpf: don't enable NAPI and interrupts prior to allocating Rx buffers
+    - selftests: mptcp: join: mark 'fastclose' tests as flaky
+    - drm/xe: Add dbg messages on the suspend resume functions.
+    - drm/xe: check pcode init status only on root gt of root tile
+    - drm/xe: Change pcode timeout to 50msec while polling again
+    - drm/xe: Only use reserved BCS instances for usm migrate exec queue
+    - sd: also set max_user_sectors when setting max_sectors
+    - block: stack max_user_sectors
+    - ipv6: introduce dst_rt6_info() helper
+    - inet: introduce dst_rtable() helper
+    - net: fix __dst_negative_advice() race
+    - ice: fix 200G PHY types to link speed mapping
+    - x86/topology/intel: Unlock CPUID before evaluating anything
+    - Upstream stable to v6.6.33, v6.9.4
+  * Reenable CONFIG_UBSAN for noble (LP: #2076650)
+    - ubsan: Remove CONFIG_UBSAN_SANITIZE_ALL
+    - [Config] Remove CONFIG_UBSAN_SANITIZE_ALL
+  * Dangling symlink to linux-lib-rust when Rust is disabled (LP: #2072592)
+    - [Packaging] Check do_lib_rust before linking Rust lib files
+  * kdump doesn't work with UEFI secure boot and kernel lockdown enabled on
+    ARM64 (LP: #2033007)
+    - [Config]: Enable CONFIG_KEXEC_IMAGE_VERIFY_SIG on arm64
+  * net/sched: Fix conntrack use-after-free (LP: #2073092)
+    - net/sched: Fix UAF when resolving a clash
+  * No sound on Huawei Matebook D14  AMD since Linux 6.8.0-38 [regression]
+    (LP: #2073049)
+    - ASoC: amd: acp: fix for acp platform device creation failure
+  * i915: Fixup regressions introduced with enabling single CCS engine
+    (LP: #2072755)
+    - drm/i915/gt: Fix CCS id's calculation for CCS mode setting
+  * [Ubuntu 24.04] FW1060.00 (NH1060_026) sosreport is running to Kernel OOPS
+    crash (LP: #2070358)
+    - nfsd: initialise nfsd_info.mutex early.
+  * 6.8 generic & amdpgu / polaris (LP: #2072428)
+    - drm/amdgpu: Adjust logic in amdgpu_device_partner_bandwidth()
+  * md: nvme over tcp with a striped underlying md raid device leads to data
+    corruption (LP: #2075110)
+    - md/md-bitmap: fix writing non bitmap pages
+  * Linux 6.8 fails to boot on ARM64 if any param is more than 146 chars
+    (LP: #2069534)
+    - SAUCE: arm64: v6.8: cmdline param >= 146 chars kills kernel
+  * CVE-2024-39484
+    - mmc: davinci: Don't strip remove function when driver is builtin
+  * CVE-2024-39292
+    - um: Add winch to winch_handlers before registering winch IRQ
+  * Miscellaneous upstream changes
+    - bnx2x: Fix multiple UBSAN array-index-out-of-bounds
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 18 Sep 2024 21:04:33 +0900
+
+linux-qcom (6.8.0-1009.9) jammy; urgency=medium
+
+  * [RB3] Kernel call trace while inserting storage to type-c USB port
+    - SAUCE: usb3: dwc3-qcom: Fix calltrace for USB host mode
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 02 Sep 2024 10:37:50 +0900
+
+linux-qcom (6.8.0-1008.8) jammy; urgency=medium
+
+  * [RB3] drm sde error/ msm-dsi-error found in dmesg
+    - SAUCE: do not show error on EPROBE_DEFER
+
+  * [RB3] slim-ngd-ctrl error found in dmesg
+    - SAUCE: dma: qcom: bam_dma: set DMA_PRIVATE
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: generate combined-dtb.dtb at compile time
+    - SAUCE: rename qcom,phy-rst-gpio to qcom,phy-rst-gpio-id
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 21 Aug 2024 03:11:39 +0900
+
+linux-qcom (6.8.0-1007.7) jammy; urgency=medium
+
+  * [RB3] gpi 900000.dma-controller error found in dmesg
+    - dmaengine: qcom: gpi: set DMA_PRIVATE flag
+
+  * [RB3] btfm_slime error message found in dmesg
+    - SAUCE: ubuntu/qcom: fix bogus error message
+
+  * [RB3] Bluetooth device is not detected
+    - SAUCE: Set local-bd-address to fix bluetooth detection
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: ubuntu/qcom/video: import video driver from GA 1.1
+    - SAUCE: ubuntu/qcom/touch: import touch driver from GA 1.1
+    - SAUCE: ubuntu/qcom/video: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/touch: replace strlcpy() with strscpy()
+    - SAUCE: build video and touch external drivers
+
+  [ Ubuntu: 6.8.0-40.40 ]
+
+  * noble/linux: 6.8.0-40.40 -proposed tracker (LP: #2072201)
+  * FPS of glxgear with fullscreen is too low on MTL platform (LP: #2069380)
+    - drm/i915: Bypass LMEMBAR/GTTMMADR for MTL stolen memory access
+  * a critical typo in the code managing the ASPM  settings for PCI Express
+    devices (LP: #2071889)
+    - PCI/ASPM: Restore parent state to parent, child state to child
+  * [UBUNTU 24.04] IOMMU DMA mode changed in kernel config causes massive
+    throughput degradation for PCI-related network workloads (LP: #2071471)
+    - [Config] Set IOMMU_DEFAULT_DMA_STRICT=n and IOMMU_DEFAULT_DMA_LAZY=yes for
+      s390x
+  * UBSAN: array-index-out-of-bounds in
+    /build/linux-D15vQj/linux-6.5.0/drivers/md/bcache/bset.c:1098:3
+    (LP: #2039368)
+    - bcache: fix variable length array abuse in btree_iter
+  * Mute/mic LEDs and speaker no function on EliteBook 645/665 G11
+    (LP: #2071296)
+    - ALSA: hda/realtek: fix mute/micmute LEDs don't work for EliteBook 645/665
+      G11.
+  * failed to enable IPU6 camera sensor on kernel >= 6.8: ivsc_ace
+    intel_vsc-5db76cf6-0a68-4ed6-9b78-0361635e2447: switch camera to host
+    failed: -110 (LP: #2067364)
+    - mei: vsc: Don't stop/restart mei device during system suspend/resume
+    - SAUCE: media: ivsc: csi: don't count privacy on as error
+    - SAUCE: media: ivsc: csi: add separate lock for v4l2 control handler
+    - SAUCE: media: ivsc: csi: remove privacy status in struct mei_csi
+    - SAUCE: mei: vsc: Enhance IVSC chipset stability during warm reboot
+    - SAUCE: mei: vsc: Enhance SPI transfer of IVSC rom
+    - SAUCE: mei: vsc: Utilize the appropriate byte order swap function
+    - SAUCE: mei: vsc: Prevent timeout error with added delay post-firmware
+      download
+  * failed to probe camera sensor on Dell XPS 9315: ov01a10 i2c-OVTI01A0:00:
+    failed to check hwcfg: -22 (LP: #2070251)
+    - ACPI: utils: Make acpi_handle_path() not static
+    - ACPI: property: Ignore bad graph port nodes on Dell XPS 9315
+    - ACPI: property: Polish ignoring bad data nodes
+    - ACPI: scan: Ignore camera graph port nodes on all Dell Tiger, Alder and
+      Raptor Lake models
+  * Update amd_sfh for AMD strix series (LP: #2058331)
+    - HID: amd_sfh: Increase sensor command timeout
+    - HID: amd_sfh: Improve boot time when SFH is available
+    - HID: amd_sfh: Extend MP2 register access to SFH
+    - HID: amd_sfh: Set the AMD SFH driver to depend on x86
+  * RFIM and SAGV Linux Support for G10 models (LP: #2070158)
+    - drm/i915/display: Add meaningful traces for QGV point info error handling
+    - drm/i915/display: Extract code required to calculate max qgv/psf gv point
+    - drm/i915/display: extract code to prepare qgv points mask
+    - drm/i915/display: Disable SAGV on bw init, to force QGV point recalculation
+    - drm/i915/display: handle systems with duplicate psf gv points
+    - drm/i915/display: force qgv check after the hw state readout
+  * Update amd-pmf for AMD strix series (LP: #2058330)
+    - platform/x86/amd/pmf: Differentiate PMF ACPI versions
+    - platform/x86/amd/pmf: Disable debugfs support for querying power thermals
+    - platform/x86/amd/pmf: Add support to get sbios requests in PMF driver
+    - platform/x86/amd/pmf: Add support to notify sbios heart beat event
+    - platform/x86/amd/pmf: Add support to get APTS index numbers for static
+      slider
+    - platform/x86/amd/pmf: Add support to get sps default APTS index values
+    - platform/x86/amd/pmf: Update sps power thermals according to the platform-
+      profiles
+  * noble:linux: ADT ubuntu-regression-suite misses fakeroot dependency
+    (LP: #2070042)
+    - [DEP-8] Add missing fakeroot dependency
+  * Noble update: v6.8.12 upstream stable release (LP: #2071621)
+    - sunrpc: use the struct net as the svc proc private
+    - x86/tsc: Trust initial offset in architectural TSC-adjust MSRs
+    - selftests/ftrace: Fix BTFARG testcase to check fprobe is enabled correctly
+    - ftrace: Fix possible use-after-free issue in ftrace_location()
+    - Revert "arm64: fpsimd: Implement lazy restore for kernel mode FPSIMD"
+    - arm64/fpsimd: Avoid erroneous elide of user state reload
+    - Reapply "arm64: fpsimd: Implement lazy restore for kernel mode FPSIMD"
+    - tty: n_gsm: fix missing receive state reset after mode switch
+    - speakup: Fix sizeof() vs ARRAY_SIZE() bug
+    - serial: sc16is7xx: fix bug in sc16is7xx_set_baud() when using prescaler
+    - serial: 8250_bcm7271: use default_mux_rate if possible
+    - serial: 8520_mtk: Set RTS on shutdown for Rx in-band wakeup
+    - Input: try trimming too long modalias strings
+    - io_uring: fail NOP if non-zero op flags is passed in
+    - Revert "r8169: don't try to disable interrupts if NAPI is, scheduled
+      already"
+    - r8169: Fix possible ring buffer corruption on fragmented Tx packets.
+    - ring-buffer: Fix a race between readers and resize checks
+    - net: mana: Fix the extra HZ in mana_hwc_send_request
+    - tools/latency-collector: Fix -Wformat-security compile warns
+    - tools/nolibc/stdlib: fix memory error in realloc()
+    - net: ti: icssg_prueth: Fix NULL pointer dereference in prueth_probe()
+    - net: lan966x: remove debugfs directory in probe() error path
+    - net: smc91x: Fix m68k kernel compilation for ColdFire CPU
+    - nilfs2: fix use-after-free of timer for log writer thread
+    - nilfs2: fix unexpected freezing of nilfs_segctor_sync()
+    - nilfs2: fix potential hang in nilfs_detach_log_writer()
+    - fs/ntfs3: Remove max link count info display during driver init
+    - fs/ntfs3: Taking DOS names into account during link counting
+    - fs/ntfs3: Fix case when index is reused during tree transformation
+    - fs/ntfs3: Break dir enumeration if directory contents error
+    - ksmbd: avoid to send duplicate oplock break notifications
+    - ksmbd: ignore trailing slashes in share paths
+    - ALSA: core: Fix NULL module pointer assignment at card init
+    - ALSA: Fix deadlocks with kctl removals at disconnection
+    - KEYS: asymmetric: Add missing dependency on CRYPTO_SIG
+    - [Config] updateconfigs for CRYPTO_SIG
+    - KEYS: asymmetric: Add missing dependencies of FIPS_SIGNATURE_SELFTEST
+    - HID: nintendo: Fix N64 controller being identified as mouse
+    - dmaengine: xilinx: xdma: Clarify kdoc in XDMA driver
+    - wifi: mac80211: don't use rate mask for scanning
+    - wifi: mac80211: ensure beacon is non-S1G prior to extracting the beacon
+      timestamp field
+    - wifi: cfg80211: fix the order of arguments for trace events of the tx_rx_evt
+      class
+    - dt-bindings: rockchip: grf: Add missing type to 'pcie-phy' node
+    - HID: mcp-2221: cancel delayed_work only when CONFIG_IIO is enabled
+    - net: usb: qmi_wwan: add Telit FN920C04 compositions
+    - drm/amd/display: Set color_mgmt_changed to true on unsuspend
+    - drm/amdgpu: Update BO eviction priorities
+    - drm/amd/pm: Restore config space after reset
+    - drm/amdkfd: Add VRAM accounting for SVM migration
+    - drm/amdgpu: Fix the ring buffer size for queue VM flush
+    - Revert "net: txgbe: fix i2c dev name cannot match clkdev"
+    - Revert "net: txgbe: fix clk_name exceed MAX_DEV_ID limits"
+    - cpu: Ignore "mitigations" kernel parameter if CPU_MITIGATIONS=n
+    - LoongArch: Lately init pmu after smp is online
+    - drm/etnaviv: fix tx clock gating on some GC7000 variants
+    - selftests: sud_test: return correct emulated syscall value on RISC-V
+    - riscv: thead: Rename T-Head PBMT to MAE
+    - [Config] updateconfigs for ERRATA_THEAD_MAE
+    - riscv: T-Head: Test availability bit before enabling MAE errata
+    - sched/isolation: Fix boot crash when maxcpus < first housekeeping CPU
+    - ASoC: Intel: bytcr_rt5640: Apply Asus T100TA quirk to Asus T100TAM too
+    - regulator: irq_helpers: duplicate IRQ name
+    - ALSA: hda: cs35l56: Exit cache-only after cs35l56_wait_for_firmware_boot()
+    - ASoC: SOF: ipc4-pcm: Use consistent name for snd_sof_pcm_stream pointer
+    - ASoC: SOF: ipc4-pcm: Use consistent name for sof_ipc4_timestamp_info pointer
+    - ASoC: SOF: ipc4-pcm: Introduce generic sof_ipc4_pcm_stream_priv
+    - ASoC: SOF: pcm: Restrict DSP D0i3 during S0ix to IPC3
+    - ASoC: acp: Support microphone from device Acer 315-24p
+    - ASoC: rt5645: Fix the electric noise due to the CBJ contacts floating
+    - ASoC: dt-bindings: rt5645: add cbj sleeve gpio property
+    - ASoC: rt722-sdca: modify channel number to support 4 channels
+    - ASoC: rt722-sdca: add headset microphone vrefo setting
+    - regulator: qcom-refgen: fix module autoloading
+    - regulator: vqmmc-ipq4019: fix module autoloading
+    - ASoC: cs35l41: Update DSP1RX5/6 Sources for DSP config
+    - ASoC: rt715: add vendor clear control register
+    - ASoC: rt715-sdca: volume step modification
+    - KVM: selftests: Add test for uaccesses to non-existent vgic-v2 CPUIF
+    - Input: xpad - add support for ASUS ROG RAIKIRI
+    - btrfs: take the cleaner_mutex earlier in qgroup disable
+    - EDAC/versal: Do not register for NOC errors
+    - fpga: dfl-pci: add PCI subdevice ID for Intel D5005 card
+    - bpf, x86: Fix PROBE_MEM runtime load check
+    - ALSA: emu10k1: make E-MU FPGA writes potentially more reliable
+    - softirq: Fix suspicious RCU usage in __do_softirq()
+    - platform/x86: ISST: Add Grand Ridge to HPM CPU list
+    - ASoC: da7219-aad: fix usage of device_get_named_child_node()
+    - ASoC: cs35l56: fix usages of device_get_named_child_node()
+    - ALSA: hda: intel-dsp-config: harden I2C/I2S codec detection
+    - Input: amimouse - mark driver struct with __refdata to prevent section
+      mismatch
+    - drm/amdgpu: Fix VRAM memory accounting
+    - drm/amd/display: Ensure that dmcub support flag is set for DCN20
+    - drm/amd/display: Add dtbclk access to dcn315
+    - drm/amd/display: Allocate zero bw after bw alloc enable
+    - drm/amd/display: Add VCO speed parameter for DCN31 FPU
+    - drm/amd/display: Fix DC mode screen flickering on DCN321
+    - drm/amd/display: Disable seamless boot on 128b/132b encoding
+    - drm/amdkfd: Flush the process wq before creating a kfd_process
+    - x86/mm: Remove broken vsyscall emulation code from the page fault code
+    - nvme: find numa distance only if controller has valid numa id
+    - nvmet-auth: return the error code to the nvmet_auth_host_hash() callers
+    - nvmet-auth: replace pr_debug() with pr_err() to report an error.
+    - nvme: cancel pending I/O if nvme controller is in terminal state
+    - nvmet-tcp: fix possible memory leak when tearing down a controller
+    - nvmet: fix nvme status code when namespace is disabled
+    - nvme-tcp: strict pdu pacing to avoid send stalls on TLS
+    - epoll: be better about file lifetimes
+    - nvmet: prevent sprintf() overflow in nvmet_subsys_nsid_exists()
+    - openpromfs: finish conversion to the new mount API
+    - crypto: bcm - Fix pointer arithmetic
+    - firmware: qcom: qcm: fix unused qcom_scm_qseecom_allowlist
+    - mm/slub, kunit: Use inverted data to corrupt kmem cache
+    - firmware: raspberrypi: Use correct device for DMA mappings
+    - ecryptfs: Fix buffer size for tag 66 packet
+    - nilfs2: fix out-of-range warning
+    - parisc: add missing export of __cmpxchg_u8()
+    - crypto: ccp - drop platform ifdef checks
+    - crypto: x86/nh-avx2 - add missing vzeroupper
+    - crypto: x86/sha256-avx2 - add missing vzeroupper
+    - crypto: x86/sha512-avx2 - add missing vzeroupper
+    - s390/cio: fix tracepoint subchannel type field
+    - io_uring: use the right type for work_llist empty check
+    - rcu-tasks: Fix show_rcu_tasks_trace_gp_kthread buffer overflow
+    - rcu: Fix buffer overflow in print_cpu_stall_info()
+    - ARM: configs: sunxi: Enable DRM_DW_HDMI
+    - jffs2: prevent xattr node from overflowing the eraseblock
+    - libfs: Re-arrange locking in offset_iterate_dir()
+    - libfs: Define a minimum directory offset
+    - libfs: Add simple_offset_empty()
+    - maple_tree: Add mtree_alloc_cyclic()
+    - libfs: Convert simple directory offsets to use a Maple Tree
+    - libfs: Fix simple_offset_rename_exchange()
+    - libfs: Add simple_offset_rename() API
+    - shmem: Fix shmem_rename2()
+    - io-wq: write next_work before dropping acct_lock
+    - mm/userfaultfd: Do not place zeropages when zeropages are disallowed
+    - s390/mm: Re-enable the shared zeropage for !PV and !skeys KVM guests
+    - crypto: octeontx2 - add missing check for dma_map_single
+    - crypto: qat - improve error message in adf_get_arbiter_mapping()
+    - crypto: qat - improve error logging to be consistent across features
+    - soc: qcom: pmic_glink: don't traverse clients list without a lock
+    - soc: qcom: pmic_glink: notify clients about the current state
+    - firmware: qcom: scm: Fix __scm and waitq completion variable initialization
+    - soc: mediatek: cmdq: Fix typo of CMDQ_JUMP_RELATIVE
+    - null_blk: Fix missing mutex_destroy() at module removal
+    - crypto: qat - validate slices count returned by FW
+    - hwrng: stm32 - use logical OR in conditional
+    - hwrng: stm32 - put IP into RPM suspend on failure
+    - hwrng: stm32 - repair clock handling
+    - kunit/fortify: Fix mismatched kvalloc()/vfree() usage
+    - io_uring/net: remove dependency on REQ_F_PARTIAL_IO for sr->done_io
+    - io_uring/net: fix sendzc lazy wake polling
+    - soc: qcom: pmic_glink: Make client-lock non-sleeping
+    - lkdtm: Disable CFI checking for perms functions
+    - md: fix resync softlockup when bitmap size is less than array size
+    - crypto: qat - specify firmware files for 402xx
+    - block: refine the EOF check in blkdev_iomap_begin
+    - block: fix and simplify blkdevparts= cmdline parsing
+    - block: support to account io_ticks precisely
+    - wifi: ath10k: poll service ready message before failing
+    - wifi: brcmfmac: pcie: handle randbuf allocation failure
+    - wifi: ath11k: don't force enable power save on non-running vdevs
+    - bpftool: Fix missing pids during link show
+    - libbpf: Prevent null-pointer dereference when prog to load has no BTF
+    - wifi: ath12k: use correct flag field for 320 MHz channels
+    - wifi: mt76: mt7915: workaround too long expansion sparse warnings
+    - x86/boot: Ignore relocations in .notes sections in walk_relocs() too
+    - wifi: ieee80211: fix ieee80211_mle_basic_sta_prof_size_ok()
+    - wifi: iwlwifi: mvm: Do not warn on invalid link on scan complete
+    - wifi: iwlwifi: mvm: allocate STA links only for active links
+    - wifi: mac80211: don't select link ID if not provided in scan request
+    - wifi: iwlwifi: implement can_activate_links callback
+    - wifi: iwlwifi: mvm: fix active link counting during recovery
+    - wifi: iwlwifi: mvm: select STA mask only for active links
+    - wifi: iwlwifi: reconfigure TLC during HW restart
+    - wifi: iwlwifi: mvm: fix check in iwl_mvm_sta_fw_id_mask
+    - sched/fair: Add EAS checks before updating root_domain::overutilized
+    - ACPI: bus: Indicate support for _TFP thru _OSC
+    - ACPI: bus: Indicate support for more than 16 p-states thru _OSC
+    - ACPI: bus: Indicate support for the Generic Event Device thru _OSC
+    - ACPI: Fix Generic Initiator Affinity _OSC bit
+    - ACPI: bus: Indicate support for IRQ ResourceSource thru _OSC
+    - enetc: avoid truncating error message
+    - qed: avoid truncating work queue length
+    - mlx5: avoid truncating error message
+    - mlx5: stop warning for 64KB pages
+    - bitops: add missing prototype check
+    - dlm: fix user space lock decision to copy lvb
+    - wifi: carl9170: re-fix fortified-memset warning
+    - bpftool: Mount bpffs on provided dir instead of parent dir
+    - bpf: Pack struct bpf_fib_lookup
+    - bpf: prevent r10 register from being marked as precise
+    - x86/microcode/AMD: Avoid -Wformat warning with clang-15
+    - scsi: ufs: qcom: Perform read back after writing reset bit
+    - scsi: ufs: qcom: Perform read back after writing REG_UFS_SYS1CLK_1US
+    - scsi: ufs: qcom: Perform read back after writing unipro mode
+    - scsi: ufs: qcom: Perform read back after writing CGC enable
+    - scsi: ufs: cdns-pltfrm: Perform read back after writing HCLKDIV
+    - scsi: ufs: core: Perform read back after writing UTP_TASK_REQ_LIST_BASE_H
+    - scsi: ufs: core: Perform read back after disabling interrupts
+    - scsi: ufs: core: Perform read back after disabling UIC_COMMAND_COMPL
+    - ACPI: LPSS: Advertise number of chip selects via property
+    - EDAC/skx_common: Allow decoding of SGX addresses
+    - locking/atomic/x86: Correct the definition of __arch_try_cmpxchg128()
+    - irqchip/alpine-msi: Fix off-by-one in allocation error path
+    - irqchip/loongson-pch-msi: Fix off-by-one on allocation error path
+    - ACPI: disable -Wstringop-truncation
+    - gfs2: Don't forget to complete delayed withdraw
+    - gfs2: Fix "ignore unlock failures after withdraw"
+    - arm64: Remove unnecessary irqflags alternative.h include
+    - x86/boot/64: Clear most of CR4 in startup_64(), except PAE, MCE and LA57
+    - selftests/bpf: Fix umount cgroup2 error in test_sockmap
+    - tcp: increase the default TCP scaling ratio
+    - cpufreq: exit() callback is optional
+    - x86/pat: Introduce lookup_address_in_pgd_attr()
+    - x86/pat: Restructure _lookup_address_cpa()
+    - x86/pat: Fix W^X violation false-positives when running as Xen PV guest
+    - udp: Avoid call to compute_score on multiple sites
+    - openrisc: traps: Don't send signals to kernel mode threads
+    - cppc_cpufreq: Fix possible null pointer dereference
+    - wifi: iwlwifi: mvm: init vif works only once
+    - scsi: libsas: Fix the failure of adding phy with zero-address to port
+    - scsi: hpsa: Fix allocation size for Scsi_Host private data
+    - x86/purgatory: Switch to the position-independent small code model
+    - wifi: ath12k: fix out-of-bound access of qmi_invoke_handler()
+    - thermal/drivers/mediatek/lvts_thermal: Add coeff for mt8192
+    - thermal/drivers/tsens: Fix null pointer dereference
+    - dt-bindings: thermal: loongson,ls2k-thermal: Add Loongson-2K0500 compatible
+    - dt-bindings: thermal: loongson,ls2k-thermal: Fix incorrect compatible
+      definition
+    - wifi: ath10k: Fix an error code problem in
+      ath10k_dbg_sta_write_peer_debug_trigger()
+    - gfs2: Remove ill-placed consistency check
+    - gfs2: Fix potential glock use-after-free on unmount
+    - gfs2: finish_xmote cleanup
+    - gfs2: do_xmote fixes
+    - thermal/debugfs: Avoid excessive updates of trip point statistics
+    - selftests/bpf: Fix a fd leak in error paths in open_netns
+    - scsi: ufs: core: mcq: Fix ufshcd_mcq_sqe_search()
+    - cpufreq: brcmstb-avs-cpufreq: ISO C90 forbids mixed declarations
+    - wifi: ath10k: populate board data for WCN3990
+    - net: dsa: mv88e6xxx: Add support for model-specific pre- and post-reset
+      handlers
+    - net: dsa: mv88e6xxx: Avoid EEPROM timeout without EEPROM on 88E6250-family
+      switches
+    - tcp: avoid premature drops in tcp_add_backlog()
+    - thermal/debugfs: Create records for cdev states as they get used
+    - thermal/debugfs: Pass cooling device state to thermal_debug_cdev_add()
+    - pwm: sti: Prepare removing pwm_chip from driver data
+    - pwm: sti: Simplify probe function using devm functions
+    - drivers/perf: hisi_pcie: Fix out-of-bound access when valid event group
+    - drivers/perf: hisi: hns3: Fix out-of-bound access when valid event group
+    - drivers/perf: hisi: hns3: Actually use devm_add_action_or_reset()
+    - net: give more chances to rcu in netdev_wait_allrefs_any()
+    - macintosh/via-macii: Fix "BUG: sleeping function called from invalid
+      context"
+    - wifi: carl9170: add a proper sanity check for endpoints
+    - bpf: Fix verifier assumptions about socket->sk
+    - selftests/bpf: Run cgroup1_hierarchy test in own mount namespace
+    - wifi: ar5523: enable proper endpoint verification
+    - pwm: Drop useless member .of_pwm_n_cells of struct pwm_chip
+    - pwm: Let the of_xlate callbacks accept references without period
+    - pwm: Drop duplicate check against chip->npwm in of_pwm_xlate_with_flags()
+    - pwm: Reorder symbols in core.c
+    - pwm: Provide an inline function to get the parent device of a given chip
+    - pwm: meson: Change prototype of a few helpers to prepare further changes
+    - pwm: meson: Make use of pwmchip_parent() accessor
+    - pwm: meson: Add check for error from clk_round_rate()
+    - pwm: meson: Use mul_u64_u64_div_u64() for frequency calculating
+    - bpf: Add BPF_PROG_TYPE_CGROUP_SKB attach type enforcement in BPF_LINK_CREATE
+    - sh: kprobes: Merge arch_copy_kprobe() into arch_prepare_kprobe()
+    - Revert "sh: Handle calling csum_partial with misaligned data"
+    - wifi: mt76: mt7603: fix tx queue of loopback packets
+    - wifi: mt76: mt7603: add wpdma tx eof flag for PSE client reset
+    - wifi: mt76: mt7996: fix size of txpower MCU command
+    - wifi: mt76: mt7925: ensure 4-byte alignment for suspend & wow command
+    - wifi: mt76: mt7996: fix uninitialized variable in mt7996_irq_tasklet()
+    - wifi: mt76: mt7996: fix potential memory leakage when reading chip
+      temperature
+    - libbpf: Fix error message in attach_kprobe_multi
+    - wifi: nl80211: Avoid address calculations via out of bounds array indexing
+    - wifi: rtw89: wow: refine WoWLAN flows of HCI interrupts and low power mode
+    - selftests/binderfs: use the Makefile's rules, not Make's implicit rules
+    - selftests/resctrl: fix clang build failure: use LOCAL_HDRS
+    - selftests: default to host arch for LLVM builds
+    - kunit: Fix kthread reference
+    - kunit: unregister the device on error
+    - kunit: bail out early in __kunit_test_suites_init() if there are no suites
+      to test
+    - selftests/bpf: Fix pointer arithmetic in test_xdp_do_redirect
+    - HID: intel-ish-hid: ipc: Add check for pci_alloc_irq_vectors
+    - scsi: bfa: Ensure the copied buf is NUL terminated
+    - scsi: qedf: Ensure the copied buf is NUL terminated
+    - scsi: qla2xxx: Fix debugfs output for fw_resource_count
+    - gpio: nuvoton: Fix sgpio irq handle error
+    - x86/numa: Fix SRAT lookup of CFMWS ranges with numa_fill_memblks()
+    - wifi: mwl8k: initialize cmd->addr[] properly
+    - HID: amd_sfh: Handle "no sensors" in PM operations
+    - usb: aqc111: stop lying about skb->truesize
+    - net: usb: sr9700: stop lying about skb->truesize
+    - m68k: Fix spinlock race in kernel thread creation
+    - m68k: mac: Fix reboot hang on Mac IIci
+    - dm-delay: fix workqueue delay_timer race
+    - dm-delay: fix hung task introduced by kthread mode
+    - dm-delay: fix max_delay calculations
+    - ptp: ocp: fix DPLL functions
+    - net: ipv6: fix wrong start position when receive hop-by-hop fragment
+    - eth: sungem: remove .ndo_poll_controller to avoid deadlocks
+    - selftests: net: add missing config for amt.sh
+    - selftests: net: move amt to socat for better compatibility
+    - net: ethernet: mediatek: split tx and rx fields in mtk_soc_data struct
+    - net: ethernet: mediatek: use ADMAv1 instead of ADMAv2.0 on MT7981 and MT7986
+    - ice: Fix package download algorithm
+    - net: ethernet: cortina: Locking fixes
+    - af_unix: Fix data races in unix_release_sock/unix_stream_sendmsg
+    - net: usb: smsc95xx: stop lying about skb->truesize
+    - net: openvswitch: fix overwriting ct original tuple for ICMPv6
+    - ipv6: sr: add missing seg6_local_exit
+    - ipv6: sr: fix incorrect unregister order
+    - ipv6: sr: fix invalid unregister error path
+    - net/mlx5: Fix peer devlink set for SF representor devlink port
+    - net/mlx5: Reload only IB representors upon lag disable/enable
+    - net/mlx5: Add a timeout to acquire the command queue semaphore
+    - net/mlx5: Discard command completions in internal error
+    - s390/bpf: Emit a barrier for BPF_FETCH instructions
+    - riscv, bpf: make some atomic operations fully ordered
+    - ax25: Use kernel universal linked list to implement ax25_dev_list
+    - ax25: Fix reference count leak issues of ax25_dev
+    - ax25: Fix reference count leak issue of net_device
+    - dpll: fix return value check for kmemdup
+    - net: fec: remove .ndo_poll_controller to avoid deadlocks
+    - mptcp: SO_KEEPALIVE: fix getsockopt support
+    - mptcp: cleanup writer wake-up
+    - mptcp: avoid some duplicate code in socket option handling
+    - mptcp: implement TCP_NOTSENT_LOWAT support
+    - mptcp: cleanup SOL_TCP handling
+    - mptcp: fix full TCP keep-alive support
+    - net: stmmac: Offload queueMaxSDU from tc-taprio
+    - net: stmmac: est: Per Tx-queue error count for HLBF
+    - net: stmmac: Report taprio offload status
+    - net: stmmac: move the EST lock to struct stmmac_priv
+    - net: micrel: Fix receiving the timestamp in the frame for lan8841
+    - Bluetooth: compute LE flow credits based on recvbuf space
+    - Bluetooth: qca: Fix error code in qca_read_fw_build_info()
+    - Bluetooth: ISO: Add hcon for listening bis sk
+    - Bluetooth: ISO: Clean up returns values in iso_connect_ind()
+    - Bluetooth: ISO: Make iso_get_sock_listen generic
+    - Bluetooth: Remove usage of the deprecated ida_simple_xx() API
+    - Bluetooth: hci_event: Remove code to removed CONFIG_BT_HS
+    - Bluetooth: HCI: Remove HCI_AMP support
+    - ice: make ice_vsi_cfg_rxq() static
+    - ice: make ice_vsi_cfg_txq() static
+    - overflow: Change DEFINE_FLEX to take __counted_by member
+    - Bluetooth: hci_conn, hci_sync: Use __counted_by() to avoid -Wfamnae warnings
+    - Bluetooth: hci_core: Fix not handling hdev->le_num_of_adv_sets=1
+    - drm/bridge: Fix improper bridge init order with pre_enable_prev_first
+    - drm/ci: update device type for volteer devices
+    - drm/nouveau/dp: Fix incorrect return code in r535_dp_aux_xfer()
+    - drm/omapdrm: Fix console by implementing fb_dirty
+    - drm/omapdrm: Fix console with deferred ops
+    - printk: Let no_printk() use _printk()
+    - dev_printk: Add and use dev_no_printk()
+    - drm/lcdif: Do not disable clocks on already suspended hardware
+    - drm/dp: Don't attempt AUX transfers when eDP panels are not powered
+    - drm/panel: atna33xc20: Fix unbalanced regulator in the case HPD doesn't
+      assert
+    - drm/amd/display: Fix potential index out of bounds in color transformation
+      function
+    - drm/amd/display: Remove redundant condition in dcn35_calc_blocks_to_gate()
+    - ASoC: Intel: Disable route checks for Skylake boards
+    - ASoC: Intel: avs: ssm4567: Do not ignore route checks
+    - mtd: core: Report error if first mtd_otp_size() call fails in
+      mtd_otp_nvmem_add()
+    - mtd: rawnand: hynix: fixed typo
+    - drm/imagination: avoid -Woverflow warning
+    - ASoC: mediatek: Assign dummy when codec not specified for a DAI link
+    - drm/panel: ltk050h3146w: add MIPI_DSI_MODE_VIDEO to LTK050H3148W flags
+    - drm/panel: ltk050h3146w: drop duplicate commands from LTK050H3148W init
+    - fbdev: shmobile: fix snprintf truncation
+    - ASoC: kirkwood: Fix potential NULL dereference
+    - drm/meson: vclk: fix calculation of 59.94 fractional rates
+    - drm/mediatek: Add 0 size check to mtk_drm_gem_obj
+    - drm/mediatek: Init `ddp_comp` with devm_kcalloc()
+    - ASoC: SOF: Intel: hda-dai: fix channel map configuration for aggregated
+      dailink
+    - powerpc/fsl-soc: hide unused const variable
+    - ASoC: SOF: Intel: mtl: Correct rom_status_reg
+    - ASoC: SOF: Intel: lnl: Correct rom_status_reg
+    - ASoC: SOF: Intel: mtl: Disable interrupts when firmware boot failed
+    - ASoC: SOF: Intel: mtl: Implement firmware boot state check
+    - fbdev: sisfb: hide unused variables
+    - selftests: cgroup: skip test_cgcore_lesser_ns_open when cgroup2 mounted
+      without nsdelegate
+    - ASoC: Intel: avs: Restore stream decoupling on prepare
+    - ASoC: Intel: avs: Fix ASRC module initialization
+    - ASoC: Intel: avs: Fix potential integer overflow
+    - ASoC: Intel: avs: Test result of avs_get_module_entry()
+    - media: ngene: Add dvb_ca_en50221_init return value check
+    - staging: media: starfive: Remove links when unregistering devices
+    - media: rcar-vin: work around -Wenum-compare-conditional warning
+    - media: radio-shark2: Avoid led_names truncations
+    - drm: bridge: cdns-mhdp8546: Fix possible null pointer dereference
+    - platform/x86: xiaomi-wmi: Fix race condition when reporting key events
+    - drm/msm/dp: allow voltage swing / pre emphasis of 3
+    - drm/msm/dp: Avoid a long timeout for AUX transfer if nothing connected
+    - media: ipu3-cio2: Request IRQ earlier
+    - media: dt-bindings: ovti,ov2680: Fix the power supply names
+    - media: i2c: et8ek8: Don't strip remove function when driver is builtin
+    - media: v4l2-subdev: Fix stream handling for crop API
+    - fbdev: sh7760fb: allow modular build
+    - media: atomisp: ssh_css: Fix a null-pointer dereference in
+      load_video_binaries
+    - drm/arm/malidp: fix a possible null pointer dereference
+    - drm: vc4: Fix possible null pointer dereference
+    - ASoC: tracing: Export SND_SOC_DAPM_DIR_OUT to its value
+    - drm/bridge: anx7625: Don't log an error when DSI host can't be found
+    - drm/bridge: icn6211: Don't log an error when DSI host can't be found
+    - drm/bridge: lt8912b: Don't log an error when DSI host can't be found
+    - drm/bridge: lt9611: Don't log an error when DSI host can't be found
+    - drm/bridge: lt9611uxc: Don't log an error when DSI host can't be found
+    - drm/bridge: tc358775: Don't log an error when DSI host can't be found
+    - drm/bridge: dpc3433: Don't log an error when DSI host can't be found
+    - drm/panel: novatek-nt35950: Don't log an error when DSI host can't be found
+    - drm/bridge: anx7625: Update audio status while detecting
+    - drm/panel: simple: Add missing Innolux G121X1-L03 format, flags, connector
+    - ALSA: hda: cs35l41: Remove Speaker ID for Lenovo Legion slim 7 16ARHA7
+    - drm/mipi-dsi: use correct return type for the DSC functions
+    - media: uvcvideo: Add quirk for Logitech Rally Bar
+    - drm/rockchip: vop2: Do not divide height twice for YUV
+    - drm/edid: Parse topology block for all DispID structure v1.x
+    - media: cadence: csi2rx: configure DPHY before starting source stream
+    - clk: samsung: exynosautov9: fix wrong pll clock id value
+    - RDMA/mlx5: Uncacheable mkey has neither rb_key or cache_ent
+    - RDMA/mlx5: Change check for cacheable mkeys
+    - RDMA/mlx5: Adding remote atomic access flag to updatable flags
+    - clk: mediatek: pllfh: Don't log error for missing fhctl node
+    - iommu: Undo pasid attachment only for the devices that have succeeded
+    - RDMA/hns: Fix return value in hns_roce_map_mr_sg
+    - RDMA/hns: Fix deadlock on SRQ async events.
+    - RDMA/hns: Fix UAF for cq async event
+    - RDMA/hns: Fix GMV table pagesize
+    - RDMA/hns: Use complete parentheses in macros
+    - RDMA/hns: Modify the print level of CQE error
+    - clk: mediatek: mt8365-mm: fix DPI0 parent
+    - clk: rs9: fix wrong default value for clock amplitude
+    - clk: qcom: clk-alpha-pll: remove invalid Stromer register offset
+    - RDMA/rxe: Fix seg fault in rxe_comp_queue_pkt
+    - RDMA/rxe: Allow good work requests to be executed
+    - RDMA/rxe: Fix incorrect rxe_put in error path
+    - IB/mlx5: Use __iowrite64_copy() for write combining stores
+    - clk: renesas: r8a779a0: Fix CANFD parent clock
+    - clk: renesas: r9a07g043: Add clock and reset entry for PLIC
+    - lib/test_hmm.c: handle src_pfns and dst_pfns allocation failure
+    - mm/ksm: fix ksm exec support for prctl
+    - clk: qcom: dispcc-sm8450: fix DisplayPort clocks
+    - clk: qcom: dispcc-sm6350: fix DisplayPort clocks
+    - clk: qcom: dispcc-sm8550: fix DisplayPort clocks
+    - clk: qcom: dispcc-sm8650: fix DisplayPort clocks
+    - clk: qcom: mmcc-msm8998: fix venus clock issue
+    - x86/insn: Fix PUSH instruction in x86 instruction decoder opcode map
+    - x86/insn: Add VEX versions of VPDPBUSD, VPDPBUSDS, VPDPWSSD and VPDPWSSDS
+    - ext4: avoid excessive credit estimate in ext4_tmpfile()
+    - RDMA/mana_ib: Introduce helpers to create and destroy mana queues
+    - RDMA/mana_ib: Use struct mana_ib_queue for CQs
+    - RDMA/mana_ib: boundary check before installing cq callbacks
+    - virt: acrn: stop using follow_pfn
+    - drivers/virt/acrn: fix PFNMAP PTE checks in acrn_vm_ram_map()
+    - sunrpc: removed redundant procp check
+    - nfsd: don't create nfsv4recoverydir in nfsdfs when not used.
+    - ext4: fix potential unnitialized variable
+    - ext4: remove the redundant folio_wait_stable()
+    - clk: qcom: Fix SC_CAMCC_8280XP dependencies
+    - [Config] updateconfigs for SC_CAMCC_8280XP
+    - clk: qcom: Fix SM_GPUCC_8650 dependencies
+    - [Config] updateconfigs for SM_GPUCC_8650
+    - clk: qcom: apss-ipq-pll: fix PLL rate for IPQ5018
+    - of: module: add buffer overflow check in of_modalias()
+    - bnxt_re: avoid shift undefined behavior in bnxt_qplib_alloc_init_hwq
+    - SUNRPC: Fix gss_free_in_token_pages()
+    - selftests/damon/_damon_sysfs: check errors from nr_schemes file reads
+    - selftests/kcmp: remove unused open mode
+    - RDMA/IPoIB: Fix format truncation compilation errors
+    - RDMA/cma: Fix kmemleak in rdma_core observed during blktests nvme/rdma use
+      siw
+    - samples/landlock: Fix incorrect free in populate_ruleset_net
+    - tracing/user_events: Prepare find/delete for same name events
+    - tracing/user_events: Fix non-spaced field matching
+    - modules: Drop the .export_symbol section from the final modules
+    - net: bridge: xmit: make sure we have at least eth header len bytes
+    - selftests: net: bridge: increase IGMP/MLD exclude timeout membership
+      interval
+    - net: bridge: mst: fix vlan use-after-free
+    - net: qrtr: ns: Fix module refcnt
+    - selftests/net/lib: no need to record ns name if it already exist
+    - idpf: don't skip over ethtool tcp-data-split setting
+    - netrom: fix possible dead-lock in nr_rt_ioctl()
+    - af_packet: do not call packet_read_pending() from tpacket_destruct_skb()
+    - sched/fair: Allow disabling sched_balance_newidle with
+      sched_relax_domain_level
+    - sched/core: Fix incorrect initialization of the 'burst' parameter in
+      cpu_max_write()
+    - net: wangxun: fix to change Rx features
+    - net: wangxun: match VLAN CTAG and STAG features
+    - net: txgbe: move interrupt codes to a separate file
+    - net: txgbe: use irq_domain for interrupt controller
+    - net: txgbe: fix to control VLAN strip
+    - l2tp: fix ICMP error handling for UDP-encap sockets
+    - io_uring/net: ensure async prep handlers always initialize ->done_io
+    - pwm: Fix setting period with #pwm-cells = <1> and of_pwm_single_xlate()
+    - net: txgbe: fix to clear interrupt status after handling IRQ
+    - net: txgbe: fix GPIO interrupt blocking
+    - Linux 6.8.12
+  * Noble update: v6.8.11 upstream stable release (LP: #2070355)
+    - drm/amd/display: Fix division by zero in setup_dsc_config
+    - net: ks8851: Fix another TX stall caused by wrong ISR flag handling
+    - ice: pass VSI pointer into ice_vc_isvalid_q_id
+    - ice: remove unnecessary duplicate checks for VF VSI ID
+    - Bluetooth: L2CAP: Fix slab-use-after-free in l2cap_connect()
+    - Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init()
+    - KEYS: trusted: Fix memory leak in tpm2_key_encode()
+    - erofs: get rid of erofs_fs_context
+    - erofs: reliably distinguish block based and fscache mode
+    - binder: fix max_thread type inconsistency
+    - usb: dwc3: Wait unconditionally after issuing EndXfer command
+    - net: usb: ax88179_178a: fix link status when link is set to down/up
+    - usb: typec: ucsi: displayport: Fix potential deadlock
+    - usb: typec: tipd: fix event checking for tps25750
+    - usb: typec: tipd: fix event checking for tps6598x
+    - serial: kgdboc: Fix NMI-safety problems from keyboard reset code
+    - remoteproc: mediatek: Make sure IPI buffer fits in L2TCM
+    - KEYS: trusted: Do not use WARN when encode fails
+    - admin-guide/hw-vuln/core-scheduling: fix return type of PR_SCHED_CORE_GET
+    - docs: kernel_include.py: Cope with docutils 0.21
+    - Docs/admin-guide/mm/damon/usage: fix wrong example of DAMOS filter matching
+      sysfs file
+    - block: add a disk_has_partscan helper
+    - block: add a partscan sysfs attribute for disks
+    - Linux 6.8.11
+  * Noble update: v6.8.10 upstream stable release (LP: #2070349)
+    - rust: module: place generated init_module() function in .init.text
+    - rust: macros: fix soundness issue in `module!` macro
+    - wifi: nl80211: don't free NULL coalescing rule
+    - pinctrl: pinctrl-aspeed-g6: Fix register offset for pinconf of GPIOR-T
+    - pinctrl/meson: fix typo in PDM's pin name
+    - pinctrl: core: delete incorrect free in pinctrl_enable()
+    - pinctrl: mediatek: paris: Fix PIN_CONFIG_INPUT_SCHMITT_ENABLE readback
+    - pinctrl: mediatek: paris: Rework support for
+      PIN_CONFIG_{INPUT,OUTPUT}_ENABLE
+    - sunrpc: add a struct rpc_stats arg to rpc_create_args
+    - nfs: expose /proc/net/sunrpc/nfs in net namespaces
+    - nfs: make the rpc_stat per net namespace
+    - nfs: Handle error of rpc_proc_register() in nfs_net_init().
+    - pinctrl: baytrail: Fix selecting gpio pinctrl state
+    - power: rt9455: hide unused rt9455_boost_voltage_values
+    - power: supply: mt6360_charger: Fix of_match for usb-otg-vbus regulator
+    - pinctrl: devicetree: fix refcount leak in pinctrl_dt_to_map()
+    - nfsd: rename NFSD_NET_* to NFSD_STATS_*
+    - nfsd: expose /proc/net/sunrpc/nfsd in net namespaces
+    - nfsd: make all of the nfsd stats per-network namespace
+    - NFSD: add support for CB_GETATTR callback
+    - NFSD: Fix nfsd4_encode_fattr4() crasher
+    - regulator: mt6360: De-capitalize devicetree regulator subnodes
+    - regulator: change stubbed devm_regulator_get_enable to return Ok
+    - regulator: change devm_regulator_get_enable_optional() stub to return Ok
+    - bpf, kconfig: Fix DEBUG_INFO_BTF_MODULES Kconfig definition
+    - bpf, skmsg: Fix NULL pointer dereference in sk_psock_skb_ingress_enqueue
+    - regmap: Add regmap_read_bypassed()
+    - ASoC: SOF: Intel: add default firmware library path for LNL
+    - nvme: fix warn output about shared namespaces without CONFIG_NVME_MULTIPATH
+    - bpf: Fix a verifier verbose message
+    - spi: axi-spi-engine: use common AXI macros
+    - spi: axi-spi-engine: fix version format string
+    - spi: hisi-kunpeng: Delete the dump interface of data registers in debugfs
+    - bpf, arm64: Fix incorrect runtime stats
+    - riscv, bpf: Fix incorrect runtime stats
+    - ASoC: Intel: avs: Set name of control as in topology
+    - ASoC: codecs: wsa881x: set clk_stop_mode1 flag
+    - s390/mm: Fix storage key clearing for guest huge pages
+    - s390/mm: Fix clearing storage keys for huge pages
+    - arm32, bpf: Reimplement sign-extension mov instruction
+    - xdp: use flags field to disambiguate broadcast redirect
+    - efi/unaccepted: touch soft lockup during memory accept
+    - ice: ensure the copied buf is NUL terminated
+    - bna: ensure the copied buf is NUL terminated
+    - octeontx2-af: avoid off-by-one read from userspace
+    - thermal/debugfs: Free all thermal zone debug memory on zone removal
+    - thermal/debugfs: Fix two locking issues with thermal zone debug
+    - nsh: Restore skb->{protocol,data,mac_header} for outer header in
+      nsh_gso_segment().
+    - net l2tp: drop flow hash on forward
+    - thermal/debugfs: Prevent use-after-free from occurring after cdev removal
+    - s390/vdso: Add CFI for RA register to asm macro vdso_func
+    - Fix a potential infinite loop in extract_user_to_sg()
+    - ALSA: emu10k1: fix E-MU card dock presence monitoring
+    - ALSA: emu10k1: factor out snd_emu1010_load_dock_firmware()
+    - ALSA: emu10k1: move the whole GPIO event handling to the workqueue
+    - ALSA: emu10k1: fix E-MU dock initialization
+    - net: qede: sanitize 'rc' in qede_add_tc_flower_fltr()
+    - net: qede: use return from qede_parse_flow_attr() for flower
+    - net: qede: use return from qede_parse_flow_attr() for flow_spec
+    - net: qede: use return from qede_parse_actions()
+    - vxlan: Fix racy device stats updates.
+    - vxlan: Add missing VNI filter counter update in arp_reduce().
+    - ASoC: meson: axg-fifo: use FIELD helpers
+    - ASoC: meson: axg-fifo: use threaded irq to check periods
+    - ASoC: meson: axg-card: make links nonatomic
+    - ASoC: meson: axg-tdm-interface: manage formatters in trigger
+    - ASoC: meson: cards: select SND_DYNAMIC_MINORS
+    - ALSA: hda: intel-sdw-acpi: fix usage of device_get_named_child_node()
+    - s390/cio: Ensure the copied buf is NUL terminated
+    - cxgb4: Properly lock TX queue for the selftest.
+    - net: dsa: mv88e6xxx: Fix number of databases for 88E6141 / 88E6341
+    - drm/amdgpu: fix doorbell regression
+    - spi: fix null pointer dereference within spi_sync
+    - net: bridge: fix multicast-to-unicast with fraglist GSO
+    - net: core: reject skb_copy(_expand) for fraglist GSO skbs
+    - rxrpc: Clients must accept conn from any address
+    - tipc: fix a possible memleak in tipc_buf_append
+    - vxlan: Pull inner IP header in vxlan_rcv().
+    - s390/qeth: Fix kernel panic after setting hsuid
+    - drm/panel: ili9341: Correct use of device property APIs
+    - [Config] updateconfigs for DRM_PANEL_ILITEK_ILI9341
+    - drm/panel: ili9341: Respect deferred probe
+    - drm/panel: ili9341: Use predefined error codes
+    - ipv4: Fix uninit-value access in __ip_make_skb()
+    - net: gro: fix udp bad offset in socket lookup by adding
+      {inner_}network_offset to napi_gro_cb
+    - net: gro: add flush check in udp_gro_receive_segment
+    - drm/xe/display: Fix ADL-N detection
+    - clk: qcom: smd-rpm: Restore msm8976 num_clk
+    - clk: sunxi-ng: h6: Reparent CPUX during PLL CPUX rate change
+    - powerpc/pseries: make max polling consistent for longer H_CALLs
+    - powerpc/pseries/iommu: LPAR panics during boot up with a frozen PE
+    - EDAC/versal: Do not log total error counts
+    - swiotlb: initialise restricted pool list_head when SWIOTLB_DYNAMIC=y
+    - KVM: arm64: vgic-v2: Check for non-NULL vCPU in vgic_v2_parse_attr()
+    - exfat: fix timing of synchronizing bitmap and inode
+    - firmware: microchip: don't unconditionally print validation success
+    - scsi: ufs: core: Fix MCQ MAC configuration
+    - scsi: lpfc: Move NPIV's transport unregistration to after resource clean up
+    - scsi: lpfc: Remove IRQF_ONESHOT flag from threaded IRQ handling
+    - scsi: lpfc: Update lpfc_ramp_down_queue_handler() logic
+    - scsi: lpfc: Replace hbalock with ndlp lock in lpfc_nvme_unregister_port()
+    - scsi: lpfc: Release hbalock before calling lpfc_worker_wake_up()
+    - scsi: lpfc: Use a dedicated lock for ras_fwlog state
+    - gfs2: Fix invalid metadata access in punch_hole
+    - fs/9p: fix uninitialized values during inode evict
+    - wifi: mac80211: fix ieee80211_bss_*_flags kernel-doc
+    - wifi: cfg80211: fix rdev_dump_mpp() arguments order
+    - wifi: mac80211: fix prep_connection error path
+    - wifi: iwlwifi: read txq->read_ptr under lock
+    - wifi: iwlwifi: mvm: guard against invalid STA ID on removal
+    - net: mark racy access on sk->sk_rcvbuf
+    - drm/xe: Fix END redefinition
+    - scsi: mpi3mr: Avoid memcpy field-spanning write WARNING
+    - scsi: bnx2fc: Remove spin_lock_bh while releasing resources after upload
+    - btrfs: return accurate error code on open failure in open_fs_devices()
+    - drm/amdkfd: Check cgroup when returning DMABuf info
+    - drm/amdkfd: range check cp bad op exception interrupts
+    - bpf: Check bloom filter map value size
+    - selftests/ftrace: Fix event filter target_func selection
+    - kbuild: Disable KCSAN for autogenerated *.mod.c intermediaries
+    - ASoC: SOF: Intel: hda-dsp: Skip IMR boot on ACE platforms in case of S3
+      suspend
+    - regulator: tps65132: Add of_match table
+    - OSS: dmasound/paula: Mark driver struct with __refdata to prevent section
+      mismatch
+    - scsi: ufs: core: WLUN suspend dev/link state error recovery
+    - scsi: libsas: Align SMP request allocation to ARCH_DMA_MINALIGN
+    - scsi: ufs: core: Fix MCQ mode dev command timeout
+    - ALSA: line6: Zero-initialize message buffers
+    - block: fix overflow in blk_ioctl_discard()
+    - ASoC: codecs: ES8326: Solve error interruption issue
+    - ASoC: codecs: ES8326: modify clock table
+    - net: bcmgenet: Reset RBUF on first open
+    - vboxsf: explicitly deny setlease attempts
+    - ata: sata_gemini: Check clk_enable() result
+    - firewire: ohci: mask bus reset interrupts between ISR and bottom half
+    - tools/power turbostat: Fix added raw MSR output
+    - tools/power turbostat: Increase the limit for fd opened
+    - tools/power turbostat: Fix Bzy_MHz documentation typo
+    - tools/power turbostat: Do not print negative LPI residency
+    - tools/power turbostat: Expand probe_intel_uncore_frequency()
+    - tools/power turbostat: Print ucode revision only if valid
+    - tools/power turbostat: Fix warning upon failed /dev/cpu_dma_latency read
+    - btrfs: make btrfs_clear_delalloc_extent() free delalloc reserve
+    - btrfs: always clear PERTRANS metadata during commit
+    - memblock tests: fix undefined reference to `early_pfn_to_nid'
+    - memblock tests: fix undefined reference to `panic'
+    - memblock tests: fix undefined reference to `BIT'
+    - nouveau/gsp: Avoid addressing beyond end of rpc->entries
+    - scsi: target: Fix SELinux error when systemd-modules loads the target module
+    - scsi: hisi_sas: Handle the NCQ error returned by D2H frame
+    - blk-iocost: avoid out of bounds shift
+    - accel/ivpu: Remove d3hot_after_power_off WA
+    - accel/ivpu: Improve clarity of MMU error messages
+    - accel/ivpu: Fix missed error message after VPU rename
+    - platform/x86: acer-wmi: Add support for Acer PH18-71
+    - gpu: host1x: Do not setup DMA for virtual devices
+    - MIPS: scall: Save thread_info.syscall unconditionally on entry
+    - tools/power/turbostat: Fix uncore frequency file string
+    - net: add copy_safe_from_sockptr() helper
+    - nfc: llcp: fix nfc_llcp_setsockopt() unsafe copies
+    - drm/amdgpu: Refine IB schedule error logging
+    - drm/amd/display: add DCN 351 version for microcode load
+    - drm/amdgpu: add smu 14.0.1 discovery support
+    - drm/amdgpu: implement IRQ_STATE_ENABLE for SDMA v4.4.2
+    - drm/amd/display: Skip on writeback when it's not applicable
+    - drm/amd/pm: fix the high voltage issue after unload
+    - drm/amdgpu: Fix VCN allocation in CPX partition
+    - amd/amdkfd: sync all devices to wait all processes being evicted
+    - selftests: timers: Fix valid-adjtimex signed left-shift undefined behavior
+    - Drivers: hv: vmbus: Leak pages if set_memory_encrypted() fails
+    - Drivers: hv: vmbus: Track decrypted status in vmbus_gpadl
+    - hv_netvsc: Don't free decrypted memory
+    - uio_hv_generic: Don't free decrypted memory
+    - Drivers: hv: vmbus: Don't free ring buffers that couldn't be re-encrypted
+    - drm/xe/xe_migrate: Cast to output precision before multiplying operands
+    - drm/xe: Label RING_CONTEXT_CONTROL as masked
+    - smb3: fix broken reconnect when password changing on the server by allowing
+      password rotation
+    - iommu: mtk: fix module autoloading
+    - fs/9p: only translate RWX permissions for plain 9P2000
+    - fs/9p: translate O_TRUNC into OTRUNC
+    - fs/9p: fix the cache always being enabled on files with qid flags
+    - 9p: explicitly deny setlease attempts
+    - powerpc/crypto/chacha-p10: Fix failure on non Power10
+    - gpio: wcove: Use -ENOTSUPP consistently
+    - gpio: crystalcove: Use -ENOTSUPP consistently
+    - clk: Don't hold prepare_lock when calling kref_put()
+    - fs/9p: remove erroneous nlink init from legacy stat2inode
+    - fs/9p: drop inodes immediately on non-.L too
+    - gpio: lpc32xx: fix module autoloading
+    - drm/nouveau/dp: Don't probe eDP ports twice harder
+    - platform/x86/amd: pmf: Decrease error message to debug
+    - platform/x86: ISST: Add Granite Rapids-D to HPM CPU list
+    - drm/radeon: silence UBSAN warning (v3)
+    - net:usb:qmi_wwan: support Rolling modules
+    - blk-iocost: do not WARN if iocg was already offlined
+    - SUNRPC: add a missing rpc_stat for TCP TLS
+    - qibfs: fix dentry leak
+    - xfrm: Preserve vlan tags for transport mode software GRO
+    - ARM: 9381/1: kasan: clear stale stack poison
+    - tcp: defer shutdown(SEND_SHUTDOWN) for TCP_SYN_RECV sockets
+    - tcp: Use refcount_inc_not_zero() in tcp_twsk_unique().
+    - Bluetooth: Fix use-after-free bugs caused by sco_sock_timeout
+    - Bluetooth: msft: fix slab-use-after-free in msft_do_close()
+    - arm64: dts: mediatek: mt8183-pico6: Fix bluetooth node
+    - Bluetooth: HCI: Fix potential null-ptr-deref
+    - Bluetooth: l2cap: fix null-ptr-deref in l2cap_chan_timeout
+    - net: ks8851: Queue RX packets in IRQ handler instead of disabling BHs
+    - rtnetlink: Correct nested IFLA_VF_VLAN_LIST attribute validation
+    - hwmon: (corsair-cpro) Use a separate buffer for sending commands
+    - hwmon: (corsair-cpro) Use complete_all() instead of complete() in
+      ccp_raw_event()
+    - hwmon: (corsair-cpro) Protect ccp->wait_input_report with a spinlock
+    - phonet: fix rtm_phonet_notify() skb allocation
+    - netlink: specs: Add missing bridge linkinfo attrs
+    - nfc: nci: Fix kcov check in nci_rx_work()
+    - net: bridge: fix corrupted ethernet header on multicast-to-unicast
+    - ipv6: Fix potential uninit-value access in __ip6_make_skb()
+    - selftests: test_bridge_neigh_suppress.sh: Fix failures due to duplicate MAC
+    - rxrpc: Fix the names of the fields in the ACK trailer struct
+    - rxrpc: Fix congestion control algorithm
+    - rxrpc: Only transmit one ACK per jumbo packet received
+    - dt-bindings: net: mediatek: remove wrongly added clocks and SerDes
+    - ipv6: fib6_rules: avoid possible NULL dereference in fib6_rule_action()
+    - net-sysfs: convert dev->operstate reads to lockless ones
+    - hsr: Simplify code for announcing HSR nodes timer setup
+    - ipv6: annotate data-races around cnf.disable_ipv6
+    - ipv6: prevent NULL dereference in ip6_output()
+    - net/smc: fix neighbour and rtable leak in smc_ib_find_route()
+    - net: hns3: using user configure after hardware reset
+    - net: hns3: direct return when receive a unknown mailbox message
+    - net: hns3: change type of numa_node_mask as nodemask_t
+    - net: hns3: release PTP resources if pf initialization failed
+    - net: hns3: use appropriate barrier function after setting a bit value
+    - net: hns3: fix port vlan filter not disabled issue
+    - net: hns3: fix kernel crash when devlink reload during initialization
+    - net: dsa: mv88e6xxx: add phylink_get_caps for the mv88e6320/21 family
+    - drm/meson: dw-hdmi: power up phy on device init
+    - drm/meson: dw-hdmi: add bandgap setting for g12
+    - drm/connector: Add \n to message about demoting connector force-probes
+    - dm/amd/pm: Fix problems with reboot/shutdown for some SMU 13.0.4/13.0.11
+      users
+    - gpiolib: cdev: Fix use after free in lineinfo_changed_notify
+    - gpiolib: cdev: fix uninitialised kfifo
+    - drm/amdgpu: Fix comparison in amdgpu_res_cpu_visible
+    - drm/amdgpu: once more fix the call oder in amdgpu_ttm_move() v2
+    - firewire: nosy: ensure user_length is taken into account when fetching
+      packet contents
+    - Reapply "drm/qxl: simplify qxl_fence_wait"
+    - usb: typec: ucsi: Check for notifications after init
+    - usb: typec: ucsi: Fix connector check on init
+    - usb: Fix regression caused by invalid ep0 maxpacket in virtual SuperSpeed
+      device
+    - usb: ohci: Prevent missed ohci interrupts
+    - USB: core: Fix access violation during port device removal
+    - usb: gadget: composite: fix OS descriptors w_value logic
+    - usb: gadget: uvc: use correct buffer size when parsing configfs lists
+    - usb: gadget: f_fs: Fix race between aio_cancel() and AIO request complete
+    - usb: gadget: f_fs: Fix a race condition when processing setup packets.
+    - usb: xhci-plat: Don't include xhci.h
+    - usb: dwc3: core: Prevent phy suspend during init
+    - usb: typec: tcpm: clear pd_event queue in PORT_RESET
+    - usb: typec: tcpm: unregister existing source caps before re-registration
+    - usb: typec: tcpm: Check for port partner validity before consuming it
+    - ALSA: hda/realtek: Fix mute led of HP Laptop 15-da3001TU
+    - ALSA: hda/realtek: Fix conflicting PCI SSID 17aa:386f for Lenovo Legion
+      models
+    - firewire: ohci: fulfill timestamp for some local asynchronous transaction
+    - mm/slub: avoid zeroing outside-object freepointer for single free
+    - btrfs: add missing mutex_unlock in btrfs_relocate_sys_chunks()
+    - btrfs: set correct ram_bytes when splitting ordered extent
+    - btrfs: qgroup: do not check qgroup inherit if qgroup is disabled
+    - btrfs: make sure that WRITTEN is set on all metadata blocks
+    - maple_tree: fix mas_empty_area_rev() null pointer dereference
+    - mm/slab: make __free(kfree) accept error pointers
+    - mptcp: ensure snd_nxt is properly initialized on connect
+    - mptcp: only allow set existing scheduler for net.mptcp.scheduler
+    - workqueue: Fix selection of wake_cpu in kick_pool()
+    - dt-bindings: iio: health: maxim,max30102: fix compatible check
+    - iio:imu: adis16475: Fix sync mode setting
+    - iio: pressure: Fixes BME280 SPI driver data
+    - iio: pressure: Fixes SPI support for BMP3xx devices
+    - iio: accel: mxc4005: Interrupt handling fixes
+    - iio: accel: mxc4005: Reset chip on probe() and resume()
+    - kmsan: compiler_types: declare __no_sanitize_or_inline
+    - e1000e: change usleep_range to udelay in PHY mdic access
+    - tipc: fix UAF in error path
+    - xtensa: fix MAKE_PC_FROM_RA second argument
+    - net: bcmgenet: synchronize EXT_RGMII_OOB_CTRL access
+    - net: bcmgenet: synchronize use of bcmgenet_set_rx_mode()
+    - net: bcmgenet: synchronize UMAC_CMD access
+    - ASoC: tegra: Fix DSPK 16-bit playback
+    - ASoC: ti: davinci-mcasp: Fix race condition during probe
+    - dyndbg: fix old BUG_ON in >control parser
+    - slimbus: qcom-ngd-ctrl: Add timeout for wait operation
+    - clk: samsung: Revert "clk: Use device_get_match_data()"
+    - clk: sunxi-ng: common: Support minimum and maximum rate
+    - clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI
+    - mei: me: add lunar lake point M DID
+    - drm/nouveau/firmware: Fix SG_DEBUG error with nvkm_firmware_ctor()
+    - Revert "drm/nouveau/firmware: Fix SG_DEBUG error with nvkm_firmware_ctor()"
+    - drm/amdkfd: don't allow mapping the MMIO HDP page with large pages
+    - drm/ttm: Print the memory decryption status just once
+    - drm/vmwgfx: Fix Legacy Display Unit
+    - drm/vmwgfx: Fix invalid reads in fence signaled events
+    - drm/imagination: Ensure PVR_MIPS_PT_PAGE_COUNT is never zero
+    - drm/amd/display: Fix idle optimization checks for multi-display and dual eDP
+    - drm/nouveau/gsp: Use the sg allocator for level 2 of radix3
+    - drm/i915/gt: Automate CCS Mode setting during engine resets
+    - drm/i915/bios: Fix parsing backlight BDB data
+    - drm/amd/display: Handle Y carry-over in VCP X.Y calculation
+    - drm/amd/display: Fix incorrect DSC instance for MST
+    - arm64: dts: qcom: sa8155p-adp: fix SDHC2 CD pin configuration
+    - iommu/arm-smmu: Use the correct type in nvidia_smmu_context_fault()
+    - net: fix out-of-bounds access in ops_init
+    - hwmon: (pmbus/ucd9000) Increase delay from 250 to 500us
+    - misc/pvpanic-pci: register attributes via pci_driver
+    - x86/apic: Don't access the APIC when disabling x2APIC
+    - selftests/mm: fix powerpc ARCH check
+    - mm: use memalloc_nofs_save() in page_cache_ra_order()
+    - mm/userfaultfd: reset ptes when close() for wr-protected ones
+    - iommu/amd: Enhance def_domain_type to handle untrusted device
+    - fs/proc/task_mmu: fix loss of young/dirty bits during pagemap scan
+    - fs/proc/task_mmu: fix uffd-wp confusion in pagemap_scan_pmd_entry()
+    - nvme-pci: Add quirk for broken MSIs
+    - regulator: core: fix debugfs creation regression
+    - spi: microchip-core-qspi: fix setting spi bus clock rate
+    - ksmbd: off ipv6only for both ipv4/ipv6 binding
+    - ksmbd: avoid to send duplicate lease break notifications
+    - ksmbd: do not grant v2 lease if parent lease key and epoch are not set
+    - tracefs: Reset permissions on remount if permissions are options
+    - tracefs: Still use mount point as default permissions for instances
+    - eventfs: Do not treat events directory different than other directories
+    - Bluetooth: qca: fix invalid device address check
+    - Bluetooth: qca: fix wcn3991 device address check
+    - Bluetooth: qca: add missing firmware sanity checks
+    - Bluetooth: qca: fix NVM configuration parsing
+    - Bluetooth: qca: generalise device address check
+    - Bluetooth: qca: fix info leak when fetching board id
+    - Bluetooth: qca: fix info leak when fetching fw build id
+    - Bluetooth: qca: fix firmware check error path
+    - keys: Fix overwrite of key expiration on instantiation
+    - Linux 6.8.10
+  * Noble update: v6.8.9 upstream stable release (LP: #2070337)
+    - cifs: Fix reacquisition of volume cookie on still-live connection
+    - smb: client: fix rename(2) regression against samba
+    - cifs: reinstate original behavior again for forceuid/forcegid
+    - HID: intel-ish-hid: ipc: Fix dev_err usage with uninitialized dev->devc
+    - HID: logitech-dj: allow mice to use all types of reports
+    - arm64: dts: rockchip: set PHY address of MT7531 switch to 0x1f
+    - arm64: dts: rockchip: enable internal pull-up on Q7_USB_ID for RK3399 Puma
+    - arm64: dts: rockchip: fix alphabetical ordering RK3399 puma
+    - arm64: dts: rockchip: enable internal pull-up on PCIE_WAKE# for RK3399 Puma
+    - arm64: dts: rockchip: Fix the i2c address of es8316 on Cool Pi CM5
+    - arm64: dts: rockchip: Remove unsupported node from the Pinebook Pro dts
+    - arm64: dts: mediatek: mt8183: Add power-domains properity to mfgcfg
+    - arm64: dts: mediatek: mt8192: Add missing gce-client-reg to mutex
+    - arm64: dts: mediatek: mt8195: Add missing gce-client-reg to vpp/vdosys
+    - arm64: dts: mediatek: mt8195: Add missing gce-client-reg to mutex
+    - arm64: dts: mediatek: mt8195: Add missing gce-client-reg to mutex1
+    - arm64: dts: mediatek: cherry: Describe CPU supplies
+    - arm64: dts: mediatek: mt8192-asurada: Update min voltage constraint for
+      MT6315
+    - arm64: dts: mediatek: mt8195-cherry: Update min voltage constraint for
+      MT6315
+    - arm64: dts: mediatek: mt8183-kukui: Use default min voltage for MT6358
+    - arm64: dts: mediatek: mt7622: fix clock controllers
+    - arm64: dts: mediatek: mt7622: fix IR nodename
+    - arm64: dts: mediatek: mt7622: fix ethernet controller "compatible"
+    - arm64: dts: mediatek: mt7622: drop "reset-names" from thermal block
+    - arm64: dts: mediatek: mt7986: reorder properties
+    - arm64: dts: mediatek: mt7986: drop invalid properties from ethsys
+    - arm64: dts: mediatek: mt7986: drop "#reset-cells" from Ethernet controller
+    - arm64: dts: mediatek: mt7986: reorder nodes
+    - arm64: dts: mediatek: mt7986: drop invalid thermal block clock
+    - arm64: dts: mediatek: mt7986: prefix BPI-R3 cooling maps with "map-"
+    - arm64: dts: mediatek: mt2712: fix validation errors
+    - arm64: dts: rockchip: mark system power controller and fix typo on
+      orangepi-5-plus
+    - arm64: dts: rockchip: regulator for sd needs to be always on for BPI-R2Pro
+    - block: fix module reference leakage from bdev_open_by_dev error path
+    - arm64: dts: qcom: Fix type of "wdog" IRQs for remoteprocs
+    - arm64: dts: qcom: x1e80100: Fix the compatible for cluster idle states
+    - arm64: dts: qcom: sc8180x: Fix ss_phy_irq for secondary USB controller
+    - gpio: tangier: Use correct type for the IRQ chip data
+    - ARC: [plat-hsdk]: Remove misplaced interrupt-cells property
+    - wifi: mac80211: clean up assignments to pointer cache.
+    - wifi: mac80211: split mesh fast tx cache into local/proxied/forwarded
+    - wifi: iwlwifi: mvm: remove old PASN station when adding a new one
+    - wifi: iwlwifi: mvm: return uid from iwl_mvm_build_scan_cmd
+    - drm/gma500: Remove lid code
+    - wifi: mac80211_hwsim: init peer measurement result
+    - wifi: mac80211: remove link before AP
+    - wifi: mac80211: fix unaligned le16 access
+    - net: libwx: fix alloc msix vectors failed
+    - vxlan: drop packets from invalid src-address
+    - net: bcmasp: fix memory leak when bringing down interface
+    - mlxsw: core: Unregister EMAD trap using FORWARD action
+    - mlxsw: core_env: Fix driver initialization with old firmware
+    - mlxsw: pci: Fix driver initialization with old firmware
+    - ARM: dts: microchip: at91-sama7g5ek: Replace regulator-suspend-voltage with
+      the valid property
+    - icmp: prevent possible NULL dereferences from icmp_build_probe()
+    - bridge/br_netlink.c: no need to return void function
+    - bnxt_en: refactor reset close code
+    - bnxt_en: Fix the PCI-AER routines
+    - bnxt_en: Fix error recovery for 5760X (P7) chips
+    - cxl/core: Fix potential payload size confusion in cxl_mem_get_poison()
+    - net: dsa: mv88e6xx: fix supported_interfaces setup in
+      mv88e6250_phylink_get_caps()
+    - NFC: trf7970a: disable all regulators on removal
+    - netfs: Fix writethrough-mode error handling
+    - ax25: Fix netdev refcount issue
+    - soc: mediatek: mtk-svs: Append "-thermal" to thermal zone names
+    - tools: ynl: don't ignore errors in NLMSG_DONE messages
+    - net: usb: ax88179_178a: stop lying about skb->truesize
+    - tcp: Fix Use-After-Free in tcp_ao_connect_init
+    - net: gtp: Fix Use-After-Free in gtp_dellink
+    - net: phy: mediatek-ge-soc: follow netdev LED trigger semantics
+    - gpio: tegra186: Fix tegra186_gpio_is_accessible() check
+    - drm/xe: Remove sysfs only once on action add failure
+    - drm/xe: call free_gsc_pkt only once on action add failure
+    - Bluetooth: hci_event: Use HCI error defines instead of magic values
+    - Bluetooth: hci_conn: Only do ACL connections sequentially
+    - Bluetooth: Remove pending ACL connection attempts
+    - Bluetooth: hci_conn: Always use sk_timeo as conn_timeout
+    - Bluetooth: hci_conn: Fix UAF Write in __hci_acl_create_connection_sync
+    - Bluetooth: hci_sync: Add helper functions to manipulate cmd_sync queue
+    - Bluetooth: hci_sync: Attempt to dequeue connection attempt
+    - Bluetooth: ISO: Reassemble PA data for bcast sink
+    - Bluetooth: hci_sync: Use advertised PHYs on hci_le_ext_create_conn_sync
+    - Bluetooth: btusb: Fix triggering coredump implementation for QCA
+    - Bluetooth: hci_event: Fix sending HCI_OP_READ_ENC_KEY_SIZE
+    - Bluetooth: MGMT: Fix failing to MGMT_OP_ADD_UUID/MGMT_OP_REMOVE_UUID
+    - Bluetooth: btusb: mediatek: Fix double free of skb in coredump
+    - Bluetooth: hci_sync: Using hci_cmd_sync_submit when removing Adv Monitor
+    - Bluetooth: qca: set power_ctrl_enabled on NULL returned by
+      gpiod_get_optional()
+    - ipvs: Fix checksumming on GSO of SCTP packets
+    - net: openvswitch: Fix Use-After-Free in ovs_ct_exit
+    - mlxsw: Use refcount_t for reference counting
+    - mlxsw: spectrum_acl_tcam: Fix race in region ID allocation
+    - mlxsw: spectrum_acl_tcam: Fix race during rehash delayed work
+    - mlxsw: spectrum_acl_tcam: Fix possible use-after-free during activity update
+    - mlxsw: spectrum_acl_tcam: Fix possible use-after-free during rehash
+    - mlxsw: spectrum_acl_tcam: Rate limit error message
+    - mlxsw: spectrum_acl_tcam: Fix memory leak during rehash
+    - mlxsw: spectrum_acl_tcam: Fix warning during rehash
+    - mlxsw: spectrum_acl_tcam: Fix incorrect list API usage
+    - mlxsw: spectrum_acl_tcam: Fix memory leak when canceling rehash work
+    - eth: bnxt: fix counting packets discarded due to OOM and netpoll
+    - ARM: dts: imx6ull-tarragon: fix USB over-current polarity
+    - netfilter: nf_tables: honor table dormant flag from netdev release event
+      path
+    - net: phy: dp83869: Fix MII mode failure
+    - net: ti: icssg-prueth: Fix signedness bug in prueth_init_rx_chns()
+    - i40e: Do not use WQ_MEM_RECLAIM flag for workqueue
+    - i40e: Report MFS in decimal base instead of hex
+    - iavf: Fix TC config comparison with existing adapter TC config
+    - ice: fix LAG and VF lock dependency in ice_reset_vf()
+    - net: ethernet: ti: am65-cpts: Fix PTPv1 message type on TX packets
+    - octeontx2-af: fix the double free in rvu_npc_freemem()
+    - dpll: check that pin is registered in __dpll_pin_unregister()
+    - dpll: fix dpll_pin_on_pin_register() for multiple parent pins
+    - tls: fix lockless read of strp->msg_ready in ->poll
+    - af_unix: Suppress false-positive lockdep splat for spin_lock() in
+      __unix_gc().
+    - netfs: Fix the pre-flush when appending to a file in writethrough mode
+    - drm/amd/display: Check DP Alt mode DPCS state via DMUB
+    - Revert "drm/amd/display: fix USB-C flag update after enc10 feature init"
+    - xhci: move event processing for one interrupter to a separate function
+    - usb: xhci: correct return value in case of STS_HCE
+    - KVM: x86/pmu: Zero out PMU metadata on AMD if PMU is disabled
+    - KVM: x86/pmu: Set enable bits for GP counters in PERF_GLOBAL_CTRL at "RESET"
+    - drm: add drm_gem_object_is_shared_for_memory_stats() helper
+    - drm/amdgpu: add shared fdinfo stats
+    - drm/amdgpu: fix visible VRAM handling during faults
+    - Revert "UBUNTU: SAUCE: selftests/seccomp: fix check of fds being assigned"
+    - selftests/seccomp: user_notification_addfd check nextfd is available
+    - selftests/seccomp: Change the syscall used in KILL_THREAD test
+    - selftests/seccomp: Handle EINVAL on unshare(CLONE_NEWPID)
+    - x86/CPU/AMD: Add models 0x10-0x1f to the Zen5 range
+    - x86/cpu: Fix check for RDPKRU in __show_regs()
+    - rust: phy: implement `Send` for `Registration`
+    - rust: kernel: require `Send` for `Module` implementations
+    - rust: don't select CONSTRUCTORS
+    - [Config] updateconfigs to drop CONSTRUCTORS for rust
+    - rust: init: remove impl Zeroable for Infallible
+    - rust: make mutually exclusive with CFI_CLANG
+    - kbuild: rust: remove unneeded `@rustc_cfg` to avoid ICE
+    - kbuild: rust: force `alloc` extern to allow "empty" Rust files
+    - rust: remove `params` from `module` macro example
+    - Bluetooth: Fix type of len in {l2cap,sco}_sock_getsockopt_old()
+    - Bluetooth: btusb: Add Realtek RTL8852BE support ID 0x0bda:0x4853
+    - Bluetooth: qca: fix NULL-deref on non-serdev suspend
+    - Bluetooth: qca: fix NULL-deref on non-serdev setup
+    - mtd: rawnand: qcom: Fix broken OP_RESET_DEVICE command in
+      qcom_misc_cmd_type_exec()
+    - mm/hugetlb: fix missing hugetlb_lock for resv uncharge
+    - mmc: sdhci-msm: pervent access to suspended controller
+    - mmc: sdhci-of-dwcmshc: th1520: Increase tuning loop count to 128
+    - mm: create FOLIO_FLAG_FALSE and FOLIO_TYPE_OPS macros
+    - mm: support page_mapcount() on page_has_type() pages
+    - mm/hugetlb: fix DEBUG_LOCKS_WARN_ON(1) when dissolve_free_hugetlb_folio()
+    - smb: client: Fix struct_group() usage in __packed structs
+    - smb3: missing lock when picking channel
+    - smb3: fix lock ordering potential deadlock in cifs_sync_mid_result
+    - btrfs: fallback if compressed IO fails for ENOSPC
+    - btrfs: fix wrong block_start calculation for btrfs_drop_extent_map_range()
+    - btrfs: scrub: run relocation repair when/only needed
+    - btrfs: fix information leak in btrfs_ioctl_logical_to_ino()
+    - x86/tdx: Preserve shared bit on mprotect()
+    - cpu: Re-enable CPU mitigations by default for !X86 architectures
+    - [Config] updateconfigs for CPU_MITIGATIONS
+    - eeprom: at24: fix memory corruption race condition
+    - LoongArch: Fix callchain parse error with kernel tracepoint events
+    - LoongArch: Fix access error when read fault on a write-only VMA
+    - arm64: dts: qcom: sc8280xp: add missing PCIe minimum OPP
+    - arm64: dts: qcom: sm8450: Fix the msi-map entries
+    - arm64: dts: rockchip: enable internal pull-up for Q7_THRM# on RK3399 Puma
+    - dmaengine: Revert "dmaengine: pl330: issue_pending waits until WFP state"
+    - dmaengine: xilinx: xdma: Fix wrong offsets in the buffers addresses in dma
+      descriptor
+    - dmaengine: xilinx: xdma: Fix synchronization issue
+    - drm/amdgpu/sdma5.2: use legacy HDP flush for SDMA2/3
+    - drm/amdgpu: Assign correct bits for SDMA HDP flush
+    - drm/atomic-helper: fix parameter order in drm_format_conv_state_copy() call
+    - drm/amdgpu/pm: Remove gpu_od if it's an empty directory
+    - drm/amdgpu/umsch: don't execute umsch test when GPU is in reset/suspend
+    - drm/amdgpu: Fix leak when GPU memory allocation fails
+    - drm/amdkfd: Fix rescheduling of restore worker
+    - drm/amdkfd: Fix eviction fence handling
+    - irqchip/gic-v3-its: Prevent double free on error
+    - ACPI: CPPC: Use access_width over bit_width for system memory accesses
+    - ACPI: CPPC: Fix bit_offset shift in MASK_VAL() macro
+    - ACPI: CPPC: Fix access width used for PCC registers
+    - net/mlx5e: Advertise mlx5 ethernet driver updates sk_buff md_dst for MACsec
+    - ethernet: Add helper for assigning packet type when dest address does not
+      match device address
+    - net: b44: set pause params only when interface is up
+    - macsec: Enable devices to advertise whether they update sk_buff md_dst
+      during offloads
+    - macsec: Detect if Rx skb is macsec-related for offloading devices that
+      update md_dst
+    - stackdepot: respect __GFP_NOLOCKDEP allocation flag
+    - fbdev: fix incorrect address computation in deferred IO
+    - udp: preserve the connected status if only UDP cmsg
+    - mtd: limit OTP NVMEM cell parse to non-NAND devices
+    - mtd: diskonchip: work around ubsan link failure
+    - firmware: qcom: uefisecapp: Fix memory related IO errors and crashes
+    - phy: qcom: qmp-combo: Fix register base for QSERDES_DP_PHY_MODE
+    - phy: qcom: qmp-combo: Fix VCO div offset on v3
+    - mm: turn folio_test_hugetlb into a PageType
+    - mm: zswap: fix shrinker NULL crash with cgroup_disable=memory
+    - dmaengine: owl: fix register access functions
+    - dmaengine: tegra186: Fix residual calculation
+    - idma64: Don't try to serve interrupts when device is powered off
+    - soundwire: amd: fix for wake interrupt handling for clockstop mode
+    - phy: marvell: a3700-comphy: Fix hardcoded array size
+    - phy: freescale: imx8m-pcie: fix pcie link-up instability
+    - phy: rockchip-snps-pcie3: fix bifurcation on rk3588
+    - phy: rockchip-snps-pcie3: fix clearing PHP_GRF_PCIESEL_CON bits
+    - phy: rockchip: naneng-combphy: Fix mux on rk3588
+    - phy: qcom: m31: match requested regulator name with dt schema
+    - dmaengine: idxd: Convert spinlock to mutex to lock evl workqueue
+    - dmaengine: idxd: Fix oops during rmmod on single-CPU platforms
+    - riscv: Fix TASK_SIZE on 64-bit NOMMU
+    - riscv: Fix loading 64-bit NOMMU kernels past the start of RAM
+    - phy: ti: tusb1210: Resolve charger-det crash if charger psy is unregistered
+    - dt-bindings: eeprom: at24: Fix ST M24C64-D compatible schema
+    - sched/eevdf: Always update V if se->on_rq when reweighting
+    - sched/eevdf: Fix miscalculation in reweight_entity() when se is not curr
+    - riscv: hwprobe: fix invalid sign extension for RISCV_HWPROBE_EXT_ZVFHMIN
+    - RISC-V: selftests: cbo: Ensure asm operands match constraints, take 2
+    - phy: qcom: qmp-combo: fix VCO div offset on v5_5nm and v6
+    - bounds: Use the right number of bits for power-of-two CONFIG_NR_CPUS
+    - Bluetooth: hci_sync: Fix UAF in hci_acl_create_conn_sync
+    - Bluetooth: hci_sync: Fix UAF on create_le_conn_complete
+    - Bluetooth: hci_sync: Fix UAF on hci_abort_conn_sync
+    - Linux 6.8.9
+  * amdgpu hangs on DCN 3.5 at bootup: RIP:
+    0010:dcn35_clk_mgr_construct+0x183/0x2210 [amdgpu] (LP: #2066233)
+    - drm/amd/display: Atom Integrated System Info v2_2 for DCN35
+  * [MTL] ACPI: PM: s2idle: Backport Linux ACPI s2idle patches to fix
+    suspend/resume issue (LP: #2069231)
+    - ACPI: PM: s2idle: Enable Low-Power S0 Idle MSFT UUID for non-AMD systems
+    - ACPI: PM: s2idle: Evaluate all Low-Power S0 Idle _DSM functions
+  * Removing legacy virtio-pci devices causes kernel panic (LP: #2067862)
+    - virtio-pci: Check if is_avq is NULL
+  * Mute/mic LEDs no function on ProBook 445/465 G11 (LP: #2069664)
+    - ALSA: hda/realtek: fix mute/micmute LEDs don't work for ProBook 445/465 G11.
+  * Mute/mic LEDs no function on  ProBook 440/460 G11 (LP: #2067669)
+    - ALSA: hda/realtek: fix mute/micmute LEDs don't work for ProBook 440/460 G11.
+  * rtw89_8852ce - Lost WIFI connection after suspend  (LP: #2065128)
+    - wifi: rtw89: reset AFEDIG register in power off sequence
+    - wifi: rtw89: 8852c: refine power sequence to imporve power consumption
+  * CVE-2024-25742
+    - x86/sev: Harden #VC instruction emulation somewhat
+    - x86/sev: Check for MWAITX and MONITORX opcodes in the #VC handler
+  * Noble update: v6.8.9 upstream stable release (LP: #2070337) //
+    CVE-2024-35984
+    - i2c: smbus: fix NULL function pointer dereference
+  * Noble update: v6.8.9 upstream stable release (LP: #2070337) //
+    CVE-2024-35990
+    - dma: xilinx_dpdma: Fix locking
+  * Noble update: v6.8.9 upstream stable release (LP: #2070337) //
+    CVE-2024-35997
+    - HID: i2c-hid: remove I2C_HID_READ_PENDING flag to prevent lock-up
+  * CVE-2024-36016
+    - tty: n_gsm: fix possible out-of-bounds in gsm0_receive()
+  * CVE-2024-36008
+    - ipv4: check for NULL idev in ip_route_use_hint()
+  * CVE-2024-35992
+    - phy: marvell: a3700-comphy: Fix out of bounds read
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 12 Aug 2024 10:40:26 +0900
+
+linux-qcom (6.8.0-1006.6) jammy; urgency=medium
+
+  * [qcom alpha] Suppress noisy logs
+    - SAUCE: ubuntu/qcom/wlan: supress noisy logs
+    - SAUCE: ubuntu/qcom/wlan: supress noisy logs (take 2)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: ubuntu/qcom/wlan: import wlan qclacld driver code from GA1.1
+    - SAUCE: ubuntu/qcom/display: import qcm6490 display code from GA1.1
+    - SAUCE: ubuntu/qcom/graphics: import qcm6490 graphics driver code from GA1.1
+    - SAUCE: ubuntu/qcom/camera: import qcm6490 camera driver code from GA1.1
+    - SAUCE: ubuntu/qcom/bt: import qcm6490 bluetooth driver from GA1.1
+    - SAUCE: ubuntu/qcom/qps615: import ethernet driver from GA1.1
+    - SAUCE: ubuntu/qcom: build external drivers
+    - SAUCE: ubuntu/qcom: suppress warning and error
+    - SAUCE: ubuntu/qcom/wlan: fix build warnings and errors in WLAN driver
+    - SAUCE: ubuntu/qcom/graphics: change strtobool() to kstrtobool()
+    - SAUCE: ubuntu/qcom/graphics: dynamically allocate the kgsl-pool shrinker for
+      kernel>=6.7
+    - SAUCE: ubuntu/qcom/camera: remove unused camera_banner
+    - SAUCE: ubuntu/qcom/camera: use sizeof() instead of V4L2_SUBDEV_NAME_SIZE
+    - SAUCE: ubuntu/qcom/camera: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: replace strlcpy() with strscpy()
+    - SAUCE: ubuntu/qcom/qps615: auto-load module
+    - SAUCE: ubuntu/qcom: add missing inclusion
+    - SAUCE: ubuntu/qcom/display: Rename min_buffers_needed to min_queued_buffers
+    - SAUCE: ubuntu/qcom: remove DRM_UNLOCKED
+    - SAUCE: ubuntu/qcom/display: suppress EPROBE_DEFER error log
+    - SAUCE: qcom/bt: support uevent module loading
+    - SAUCE: qcom/bt: add sentinel to MODULE_DEVICE_TABLE()
+    - SAUCE: import external DT from GA 1.1
+    - SAUCE: Add Makefile code to apply overlays for GA1
+
+  * Miscellaneous upstream changes
+    - QCLINUX: regulator: qcom-rpmh-regulator: Add debug-regulator support
+    - PENDING: arm64: dts: qcom: qcs8550-rb5gen2: enable PMIC Volume and Power
+      buttons
+    - FROMLIST: dt-bindings: arm: qcom,ids: Add SoC ID for SM8650P
+    - FROMLIST: soc: qcom: socinfo: Add SM8650P SoC ID table entry
+    - PENDING: slimbus: messaging: use memcpy_fromio for io mapped memory
+    - FROMLIST: arm64: dts: qcom: sm8650p: introduce sm8650p dtsi
+    - FROMLIST: arm64: dts: qcom: add base AIM500 dtsi
+    - FROMLIST: arm64: dts: qcom: add AIM500 AIoT
+    - PENDING: arm64: qcom: dts: qcs8550: Add modem rproc node
+    - QCLINUX: soc: qcom: f_qdss: Initialize qdss channel with NULL
+    - PENDING: misc: fastrpc: Check for static PD status
+    - QCLINUX: soc: qcom: Use SoC watchdog when Linux boots in hyp mode
+    - QCLINUX: arm64: dts: qcom: qcm6490: Leave SoC watchdog enabled
+    - QCLINUX: arm64: Enable watchdog configuration through sysfs
+    - QCLINUX: soc: qcom: Make SoC debug module as builtin module
+    - FROMLIST: soc: qcom: aoss: Add tracepoints in qmp_send()
+    - PENDING: arm64: dts: qcom: sc7280: Add gpio for sec MI2S mclk
+    - QCLINUX: arm64: dts: qcom: Add addons support for AIM500 AIoT
+    - QCLINUX: arm64: defconfig: qcom: enable SM8650 related config
+    - QCLINUX: arm64: dts: qcom: aim300: Add board-id and msm-id support
+    - PENDING: misc: fastrpc: Fix use after free on devices
+    - PENDING: arm64: dts: qcom: qcs8550-rb5gen2: Add definition for three LEDs
+    - PENDING: arm64: dts: qcom: qcs8550-rb5gen2: Add definitions for flash leds
+    - PENDING: iommu/arm-smmu-qcom: Fix an empty list_head accessing
+    - PENDING: trece: buses: Change __assign_str to __assign_str_len
+    - PENDING: spi: spi-geni-qcom: add trace log support
+    - Revert "QCLINUX: arm64: configs: qcom_defconfig: Disable NVMEM_REBOOT_MODE"
+    - PENDING: i2c: i2c-qcom-geni: Add trace log support
+    - PENDING: arm64: dts: qcom: sm8550: add slimbus DT node
+    - PENDING: arm64: dts: qcm6490: Disable nvmem-reboot-mode
+    - QCLINUX: usb: dwc3: Initialize variable ret to 0
+    - QCLINUX: usb: dwc3: qcom: Take wakelock to block pm suspend in autosleep
+    - PENDING: soc: qcom: memory_dump: initialize initialized value
+    - PENDING: arm64: dts: qcom: qcs6490-rb3gen2: disable ipa node on qcs6490
+    - PENDING: arm64: dts: qcom: Enable PCIe1 on aim500
+    - QCLINUX: arm64: dts: qcom: Add support for qps615 switch
+    - QCLINUX: arm64: defconfig: Enable ARM64_VA=39
+    - PENDING: arm64: dts: qcom: qcs6490-rb3gen2: Modify DVT device USB2
+    - QCLINUX: virt: gunyah: Use kvcalloc for tracking large number of pages
+    - PENDING: firmware: Error handling in qcom_scm_prepare_ice_key
+    - PENDING: arm64: dts: qcom: sa8775p: Add UART node
+    - QCLINUX: arm64: dts: qcom: Rename regulators for QCM6490
+    - PENDING: power: supply: qcom_battmgr: Add support to configure USB ICL
+    - QCLINUX: soc: qcom: Don't assume that soc watchdog is enabled by default
+    - PENDING: arm64: dts: Add missing clkreq pin configuration
+    - PENDING: arm64: dts: qcom: sa8775p: Add GPI configuration
+    - QCLINUX: arm64: dts: qcom: Add board-id and msm-id for Rb3Gen2
+    - QCLINUX: arm64: defconfig: Add AQC107 config
+    - QCLINUX: usb: dwc3: qcom: Avoid PM Resume if device is RT suspended
+    - PENDING: Bluetooth: Increase settling time for baudrate change VSC
+    - PENDING: remoteproc: qcom: pas: Add SA8775p remoteproc support
+    - PENDING: arm64: dts: qcom: sa8775p: add ADSP and CDSP support
+    - QCLINUX: arm64: dts: qcom: sa8775p: add addons dts support for sa8775p
+    - PENDING: arm64: dts: qcom: sa8775p: enable CDSP for SA8775p
+    - PENDING: remoteproc: qcom: pas: Add SA8775p CDSP1 remoteproc support
+    - PENDING: arm64: dts: qcom: sa8775p: add CDSP1 support
+    - PENDING: arm64: dts: qcom: sa8775p: enable CDSP1 for SA8775p
+    - PENDING: dt-bindings: mailbox: qcom-ipcc: Add GPDSP0 and GPDSP1 client
+    - PENDING: remoteproc: qcom: pas: Add SA8775p GPDSP0 and GPDSP1 remoteproc
+      support
+    - PENDING: arm64: dts: qcom: sa8775p: add GPDSP0 and GPDSP1 support
+    - QCLINUX: arm64: defconfig: Enable STMMAC eth and Marvell phy config
+    - PENDING: uapi: add userspace interface file to uapi
+    - PENDING: soc: qcom: llcc: add llcc config support for SA8775p platform
+    - PENDING: arm64: dts: qcom: sa8775p: Add llcc support for SA8775p platform
+    - PENDING: arm64: dts: qcom: sa8775p-ride: Enable llcc function
+    - QCLINUX: arm64: defconfig: qcom: Enable i3c support
+    - PENDING: soc: qcom: smem: Add boundary checks for partitions
+    - PENDING: crypto: qce - Fetch interconnect bandwidth value from dtsi
+    - PENDING: arm64: dts: qcom: sc7280: Define interconnect bandwidth value in
+      dtsi
+    - QCLINUX: rpmsg: glink: replace deprecated 'strcpy' with 'strscpy'
+    - QCLINUX: arm64: defconfig: enable configs required for kubernetes
+    - PENDING: slimbus: ngd: Add check before memory free
+    - QCLINUX: arm64: dts: qcom: sa8775p: add dma-buf heaps
+    - QCLINUX: arm64: dts: qcom: sa8775p: add secure buffer device
+    - QCLINUX: arm64: dts: qcom: sa8775p: add mem-buf device
+    - QCLINUX: arm64: dts: qcm6490-addons: Update memory dump table
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add gunyah watchdog support
+    - PENDING: pcie: Save & restore configuration space for qps615
+    - QCLINUX: thermal: qcom: Add support to update tsens trip based on nvmem data
+    - PENDING: arm64: dts: qcom: sa8775p: Add IMEM and PIL info region
+    - QCLINUX: arm64: dts: qcom: sa8775p: define kaslr offset and mem dump table
+      regions
+    - QCLINUX: arm64: dts: qcom: sa8775p-ride: Add board-id and msm-id support
+    - QCLINUX: arm64: dts: qcom: sa8775p: Add shmbridge and smcinvoke nodes
+    - FROMLIST: arm64: dts: qcom: qcm8550: introduce qcs8550 dtsi
+    - PENDING: arm64: qcom: dts: qcs8550: Update included dtsi name for rb5gen2
+    - QCLINUX: arm64: dts: qcom: qcs8550: update qcs8550 addons dtsi file name
+    - PENDING: arm64: dts: qcom: sa8775p: enable ADSP and GPDSP for SA8775p
+    - PENDING: USB: pci-quirks: skip usb_early_handoff for Renesas PCI USB
+    - PENDING: coresight-tmc-etf: fix failure to disable/enable ETF after reading
+    - QCLINUX: PCI: qcom: Enable powering up upd controller
+    - QCLINUX: ASoC: qcm6490: Update channel slot number for slimbus codec dai
+    - PENDING: arm64: dts: qcom: aim500: Add more reserved gpio pins
+    - PENDING: soc: qcom: ice: Handle ice probe return
+    - PENDING: usb: dwc3: core: Handle failure of get sync during cable disconnect
+    - PENDING: arm64: dts: qcom: sa8775p: Enable smp2p-sleepstate
+    - QCLINUX: clk: qcom: gcc-sa8775p: Remove the HW control clocks on SA8775P
+    - PENDING: iris: Disable slice mode for VBR rate control
+    - PENDING: usb: dwc3: qcom: Introduce post-connection done vendor hook
+    - PENDING: misc: fastrpc: Add support for cdsp1 remoteproc
+    - QCLINUX: arm64: dts: qcom: Enable tsens dynamic trip update for qcm6490
+    - PENDING: crypto: qce - Bam crash during suspend-shutdown scenario
+    - PENDING: arm64: dts: qcom: sa8775p-ride: add Bluetooth support
+    - PENDING: arm64: dts: qcom: sa8775p: add CDSP1 fastrpc-compute-cb nodes
+    - PENDING: dt-bindings: clock: qcom: Add SA8775P video clock controller
+    - PENDING: clk: qcom: Add support for Video clock controller on SA8775P
+    - PENDING: dt-bindings: clock: qcom: Add SA8775P camera controller
+    - PENDING: clk: qcom: Add support for Camera Clock Controller on SA8775P
+    - PENDING: dt-bindings: clock: qcom: Add SA8775P display controller
+    - PENDING: clk: qcom: Add support for Display Controllers on SA8775P
+    - PENDING: clk: qcom: Remove the CLK_IS_CRITICAL flag for SA8775P
+    - QCLINUX: arm64: defconfig: enable Clock controllers SA8775P
+    - PENDING: arm64: dts: qcom: sa8775p: add clock controllers support
+    - QCLINUX: arm64: dts: qcs5430-rb3: Enable PCIE1
+    - FROMLIST: PCI: hold the rescan mutex when scanning for the first time
+    - FROMLIST: PCI/pwrctl: reuse the OF node for power controlled devices
+    - FROMLIST: PCI/pwrctl: create platform devices for child OF nodes of the port
+      node
+    - FROMLIST: PCI/pwrctl: add PCI power control core code
+    - FROMLIST: power: sequencing: implement the pwrseq core
+    - FROMLIST: power: pwrseq: add a driver for the PMU module on the QCom WCN
+      chipsets
+    - FROMLIST: PCI/pwrctl: add a PCI power control driver for power sequenced
+      devices
+    - PENDING: PCI/pwrctl: enable power control for WCN6855
+    - PENDING: power: pwrseq: add WCN6855 PMU support
+    - PENDING: arm64: dts: qcom: sa8775p-ride: add pmu node for WCN6855
+    - PENDING: Bluetooth: hci_qca: Drop unused event during BT on
+    - config: enable PCA953x PCA954x and ANX7625 driver
+    - PENDING: drm/bridge: anx7625: Fix circular dependency
+    - PENDING: iris: devicetree: remove iommu and video enc dec nodes
+    - PENDING: videocc: remove HW_CTRL from mvs0 gdsc
+    - PENDING: interconnect: qcom: sa8775p: enable qos programming
+    - PENDING: arm64: dts: qcom: sa8775p: Add reg field & clocks to program QoS
+    - PENDING: arm64: dts: qcom: Add SD Card node for qcm6490-rb3
+    - QCLINUX: arm64: dts: qcom: qcs6490: Add PCIe bridge and endpoint nodes
+    - QCLINUX: arm64: dts: qcom:Add QPS615 and PHY devicestree config
+    - QCLINUX: arm64: configs: qcom_defconfig: Enable NVMEM_REBOOT_MODE
+    - QCLINUX: arm64: defconfig: qcom: Disable ASPM
+    - PENDING: usb: dwc3: qcom: Check if driver is resumed before reg access
+    - PENDING: arm64: dts: qcom: sa8775p-ride: Change swctrl-gpios in BT
+    - PENDING: arm64: dts: qcom: sa8775p-pmics: enable rtc
+    - QCLINUX: arm64: dts: qcom: sa8775p-addons: Add CMA heap
+    - QCLINUX: arm64: defconfig: Enable vsock support
+    - QCLINUX: arm64: defconfig: Host kernel accelerator for virtio net
+    - QCLINUX: arm64: defconfig: Enable required virtio configs for VM
+    - QCLINUX: arm64: defconfig: Enable watchdog drivers for VM
+    - FROMLIST: drivers: qcom: icc-bwmon: Change zone1_thres_count to 3
+    - PENDING: crypto: qce - remove return values from qce_crypto_probe()
+    - thermal: re-add thermal_zone_set_trip()
+    - thermal: tsens: remove use of thermal_zone_device_exec()
+    - Revert "net: phylink: remove .validate() method"
+    - Ubuntu [Config] update configs for GA 1.1
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Tue, 23 Jul 2024 17:25:21 +0900
+
+linux-qcom (6.8.0-1005.5) jammy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] drop getabis data
+
+  * [RB3] Kernel back trace while audio play
+    - Revert "ASoC: qcom: Move Soundwire runtime stream alloc to soundcards"
+
+  * [qcom alpha] Suppress noisy logs
+    - SAUCE: ubuntu/qcom/wlan: supress noisy logs (take 2)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: qcom/bt: support uevent module loading
+    - SAUCE: qcom/bt: add sentinel to MODULE_DEVICE_TABLE()
+
+  [ Ubuntu: 6.8.0-38.38 ]
+
+  * noble/linux: 6.8.0-38.38 -proposed tracker (LP: #2068318)
+  * race_sched in ubuntu_stress_smoke_test will cause kernel panic on 6.8 with
+    Azure Standard_A2_v2 instance (LP: #2068024)
+    - sched/eevdf: Prevent vlag from going out of bounds in reweight_eevdf()
+  * Noble: btrfs: re-introduce 'norecovery' mount option (LP: #2068591)
+    - btrfs: re-introduce 'norecovery' mount option
+  * Fix system hang while entering suspend with AMD Navi3x graphics
+    (LP: #2063417)
+    - drm/amdgpu/mes: fix use-after-free issue
+  * Noble update: v6.8.8 upstream stable release (LP: #2068087)
+    - io_uring: Fix io_cqring_wait() not restoring sigmask on get_timespec64()
+      failure
+    - drm/i915/cdclk: Fix voltage_level programming edge case
+    - Revert "vmgenid: emit uevent when VMGENID updates"
+    - SUNRPC: Fix rpcgss_context trace event acceptor field
+    - selftests/ftrace: Limit length in subsystem-enable tests
+    - random: handle creditable entropy from atomic process context
+    - scsi: core: Fix handling of SCMD_FAIL_IF_RECOVERING
+    - net: usb: ax88179_178a: avoid writing the mac address before first reading
+    - btrfs: do not wait for short bulk allocation
+    - btrfs: zoned: do not flag ZEROOUT on non-dirty extent buffer
+    - r8169: fix LED-related deadlock on module removal
+    - r8169: add missing conditional compiling for call to r8169_remove_leds
+    - scsi: ufs: qcom: Add missing interconnect bandwidth values for Gear 5
+    - netfilter: nf_tables: Fix potential data-race in __nft_expr_type_get()
+    - netfilter: nf_tables: Fix potential data-race in __nft_obj_type_get()
+    - netfilter: br_netfilter: skip conntrack input hook for promisc packets
+    - netfilter: nft_set_pipapo: constify lookup fn args where possible
+    - netfilter: nft_set_pipapo: walk over current view on netlink dump
+    - netfilter: flowtable: validate pppoe header
+    - netfilter: flowtable: incorrect pppoe tuple
+    - af_unix: Call manage_oob() for every skb in unix_stream_read_generic().
+    - af_unix: Don't peek OOB data without MSG_OOB.
+    - net: sparx5: flower: fix fragment flags handling
+    - net/mlx5: Lag, restore buckets number to default after hash LAG deactivation
+    - net/mlx5: Restore mistakenly dropped parts in register devlink flow
+    - net/mlx5e: Prevent deadlock while disabling aRFS
+    - net: change maximum number of UDP segments to 128
+    - octeontx2-pf: fix FLOW_DIS_IS_FRAGMENT implementation
+    - selftests/tcp_ao: Make RST tests less flaky
+    - selftests/tcp_ao: Zero-init tcp_ao_info_opt
+    - selftests/tcp_ao: Fix fscanf() call for format-security
+    - selftests/tcp_ao: Printing fixes to confirm with format-security
+    - net: stmmac: Apply half-duplex-less constraint for DW QoS Eth only
+    - net: stmmac: Fix max-speed being ignored on queue re-init
+    - net: stmmac: Fix IP-cores specific MAC capabilities
+    - ice: tc: check src_vsi in case of traffic from VF
+    - ice: tc: allow zero flags in parsing tc flower
+    - ice: Fix checking for unsupported keys on non-tunnel device
+    - tun: limit printing rate when illegal packet received by tun dev
+    - net: dsa: mt7530: fix mirroring frames received on local port
+    - net: dsa: mt7530: fix port mirroring for MT7988 SoC switch
+    - s390/ism: Properly fix receive message buffer allocation
+    - netfilter: nf_tables: missing iterator type in lookup walk
+    - netfilter: nf_tables: restore set elements when delete set fails
+    - gpiolib: swnode: Remove wrong header inclusion
+    - netfilter: nf_tables: fix memleak in map from abort path
+    - net/sched: Fix mirred deadlock on device recursion
+    - net: ethernet: mtk_eth_soc: fix WED + wifi reset
+    - ravb: Group descriptor types used in Rx ring
+    - net: ravb: Count packets instead of descriptors in R-Car RX path
+    - net: ravb: Allow RX loop to move past DMA mapping errors
+    - net: ethernet: ti: am65-cpsw-nuss: cleanup DMA Channels before using them
+    - NFSD: fix endianness issue in nfsd4_encode_fattr4
+    - RDMA/rxe: Fix the problem "mutex_destroy missing"
+    - RDMA/cm: Print the old state when cm_destroy_id gets timeout
+    - RDMA/mlx5: Fix port number for counter query in multi-port configuration
+    - perf annotate: Make sure to call symbol__annotate2() in TUI
+    - perf lock contention: Add a missing NULL check
+    - s390/qdio: handle deferred cc1
+    - s390/cio: fix race condition during online processing
+    - iommufd: Add missing IOMMUFD_DRIVER kconfig for the selftest
+    - iommufd: Add config needed for iommufd_fail_nth
+    - drm: nv04: Fix out of bounds access
+    - drm/v3d: Don't increment `enabled_ns` twice
+    - userfaultfd: change src_folio after ensuring it's unpinned in UFFDIO_MOVE
+    - thunderbolt: Introduce tb_port_reset()
+    - thunderbolt: Introduce tb_path_deactivate_hop()
+    - thunderbolt: Make tb_switch_reset() support Thunderbolt 2, 3 and USB4
+      routers
+    - thunderbolt: Reset topology created by the boot firmware
+    - drm/panel: visionox-rm69299: don't unregister DSI device
+    - drm/radeon: make -fstrict-flex-arrays=3 happy
+    - ALSA: hda/realtek: Fix volumn control of ThinkBook 16P Gen4
+    - thermal/debugfs: Add missing count increment to thermal_debug_tz_trip_up()
+    - platform/x86/amd/pmc: Extend Framework 13 quirk to more BIOSes
+    - interconnect: qcom: x1e80100: Remove inexistent ACV_PERF BCM
+    - interconnect: Don't access req_list while it's being manipulated
+    - clk: Remove prepare_lock hold assertion in __clk_release()
+    - clk: Initialize struct clk_core kref earlier
+    - clk: Get runtime PM before walking tree during disable_unused
+    - clk: Get runtime PM before walking tree for clk_summary
+    - clk: mediatek: Do a runtime PM get on controllers during probe
+    - clk: mediatek: mt7988-infracfg: fix clocks for 2nd PCIe port
+    - selftests/powerpc/papr-vpd: Fix missing variable initialization
+    - x86/bugs: Fix BHI retpoline check
+    - x86/cpufeatures: Fix dependencies for GFNI, VAES, and VPCLMULQDQ
+    - block: propagate partition scanning errors to the BLKRRPART ioctl
+    - net/mlx5: E-switch, store eswitch pointer before registering devlink_param
+    - ALSA: seq: ump: Fix conversion from MIDI2 to MIDI1 UMP messages
+    - ALSA: hda/tas2781: correct the register for pow calibrated data
+    - ALSA: hda/realtek: Add quirks for Huawei Matebook D14 NBLB-WAX9N
+    - ALSA: hda/realtek - Enable audio jacks of Haier Boyue G42 with ALC269VC
+    - usb: misc: onboard_usb_hub: Disable the USB hub clock on failure
+    - misc: rtsx: Fix rts5264 driver status incorrect when card removed
+    - thunderbolt: Avoid notify PM core about runtime PM resume
+    - thunderbolt: Fix wake configurations after device unplug
+    - thunderbolt: Do not create DisplayPort tunnels on adapters of the same
+      router
+    - comedi: vmk80xx: fix incomplete endpoint checking
+    - serial: mxs-auart: add spinlock around changing cts state
+    - serial/pmac_zilog: Remove flawed mitigation for rx irq flood
+    - serial: 8250_dw: Revert: Do not reclock if already at correct rate
+    - serial: stm32: Return IRQ_NONE in the ISR if no handling happend
+    - serial: stm32: Reset .throttled state in .startup()
+    - serial: core: Fix regression when runtime PM is not enabled
+    - serial: core: Clearing the circular buffer before NULLifying it
+    - serial: core: Fix missing shutdown and startup for serial base port
+    - USB: serial: option: add Fibocom FM135-GL variants
+    - USB: serial: option: add support for Fibocom FM650/FG650
+    - USB: serial: option: add Lonsung U8300/U9300 product
+    - USB: serial: option: support Quectel EM060K sub-models
+    - USB: serial: option: add Rolling RW101-GL and RW135-GL support
+    - USB: serial: option: add Telit FN920C04 rmnet compositions
+    - Revert "usb: cdc-wdm: close race between read and workqueue"
+    - usb: dwc2: host: Fix dereference issue in DDMA completion flow.
+    - usb: Disable USB3 LPM at shutdown
+    - usb: gadget: f_ncm: Fix UAF ncm object at re-bind after usb ep transport
+      error
+    - usb: typec: tcpm: Correct the PDO counting in pd_set
+    - mei: me: disable RPL-S on SPS and IGN firmwares
+    - speakup: Avoid crash on very long word
+    - fs: sysfs: Fix reference leak in sysfs_break_active_protection()
+    - sched: Add missing memory barrier in switch_mm_cid
+    - KVM: x86: Snapshot if a vCPU's vendor model is AMD vs. Intel compatible
+    - KVM: x86/pmu: Disable support for adaptive PEBS
+    - KVM: x86/pmu: Do not mask LVTPC when handling a PMI on AMD platforms
+    - KVM: x86/mmu: x86: Don't overflow lpage_info when checking attributes
+    - KVM: x86/mmu: Write-protect L2 SPTEs in TDP MMU when clearing dirty status
+    - arm64/head: Disable MMU at EL2 before clearing HCR_EL2.E2H
+    - arm64: hibernate: Fix level3 translation fault in swsusp_save()
+    - init/main.c: Fix potential static_command_line memory overflow
+    - mm/madvise: make MADV_POPULATE_(READ|WRITE) handle VM_FAULT_RETRY properly
+    - mm/userfaultfd: allow hugetlb change protection upon poison entry
+    - mm,swapops: update check in is_pfn_swap_entry for hwpoison entries
+    - mm/memory-failure: fix deadlock when hugetlb_optimize_vmemmap is enabled
+    - mm/shmem: inline shmem_is_huge() for disabled transparent hugepages
+    - fuse: fix leaked ENOSYS error on first statx call
+    - drm/amdkfd: Fix memory leak in create_process failure
+    - drm/amdgpu: remove invalid resource->start check v2
+    - drm/ttm: stop pooling cached NUMA pages v2
+    - drm/xe: Fix bo leak in intel_fb_bo_framebuffer_init
+    - drm/vmwgfx: Fix prime import/export
+    - drm/vmwgfx: Sort primary plane formats by order of preference
+    - drm/vmwgfx: Fix crtc's atomic check conditional
+    - nouveau: fix instmem race condition around ptr stores
+    - bootconfig: use memblock_free_late to free xbc memory to buddy
+    - Squashfs: check the inode number is not the invalid value of zero
+    - nilfs2: fix OOB in nilfs_set_de_type
+    - fork: defer linking file vma until vma is fully initialized
+    - net: dsa: mt7530: fix improper frames on all 25MHz and 40MHz XTAL MT7530
+    - net: dsa: mt7530: fix enabling EEE on MT7531 switch on all boards
+    - ksmbd: fix slab-out-of-bounds in smb2_allocate_rsp_buf
+    - ksmbd: validate request buffer size in smb2_allocate_rsp_buf()
+    - ksmbd: clear RENAME_NOREPLACE before calling vfs_rename
+    - ksmbd: common: use struct_group_attr instead of struct_group for
+      network_open_info
+    - thunderbolt: Reset only non-USB4 host routers in resume
+    - Linux 6.8.8
+  * Fix inaudible HDMI/DP audio on USB-C MST dock (LP: #2064689)
+    - drm/i915/audio: Fix audio time stamp programming for DP
+  * Add Cirrus Logic CS35L56 amplifier support (LP: #2062135)
+    - ALSA: hda: realtek: Re-work CS35L41 fixups to re-use for other amps
+    - ALSA: hda/realtek: Add quirks for HP G11 Laptops using CS35L56
+  * net:fib_rule_tests.sh in ubuntu_kselftests_net fails on Noble (LP: #2066332)
+    - Revert "UBUNTU: SAUCE: selftests: net: fix "from" match test in
+      fib_rule_tests.sh"
+  * mtk_t7xx WWAN module fails to probe with: Invalid device status 0x1
+    (LP: #2049358)
+    - Revert "UBUNTU: SAUCE: net: wwan: t7xx: PCIe reset rescan"
+    - Revert "UBUNTU: SAUCE: net: wwan: t7xx: Add AP CLDMA"
+    - net: wwan: t7xx: Add AP CLDMA
+    - wwan: core: Add WWAN fastboot port type
+    - net: wwan: t7xx: Add sysfs attribute for device state machine
+    - net: wwan: t7xx: Infrastructure for early port configuration
+    - net: wwan: t7xx: Add fastboot WWAN port
+  * Pull-request to address TPM bypass issue (LP: #2037688)
+    - [Config]: Configure TPM drivers as builtins for arm64 in annotations
+  * re-enable Ubuntu FAN in the Noble kernel (LP: #2064508)
+    - SAUCE: fan: add VXLAN implementation
+    - SAUCE: fan: Fix NULL pointer dereference
+    - SAUCE: fan: support vxlan strict length validation
+  * update for V3 kernel bits and improved multiple fan slice support
+    (LP: #1470091) // re-enable Ubuntu FAN in the Noble kernel (LP: #2064508)
+    - SAUCE: fan: tunnel multiple mapping mode (v3)
+  * TCP memory  leak, slow network (arm64) (LP: #2045560)
+    - net: make SK_MEMORY_PCPU_RESERV tunable
+    - net: fix sk_memory_allocated_{add|sub} vs softirqs
+  * panel flickering after the i915.psr2 is enabled (LP: #2046315)
+    - drm/i915/alpm: Add ALPM register definitions
+    - drm/i915/psr: Add alpm_parameters struct
+    - drm/i915/alpm: Calculate ALPM Entry check
+    - drm/i915/alpm: Alpm aux wake configuration for lnl
+    - drm/i915/display: Make intel_dp_aux_fw_sync_len available for PSR code
+    - drm/i915/psr: Improve fast and IO wake lines calculation
+    - drm/i915/psr: Calculate IO wake and fast wake lines for DISPLAY_VER < 12
+    - drm/i915/display: Increase number of fast wake precharge pulses
+  * I2C HID device sometimes fails to initialize causing touchpad to not work
+    (LP: #2061040)
+    - HID: i2c-hid: Revert to await reset ACK before reading report descriptor
+  * Fix the RTL8852CE BT FW Crash based on SER false alarm (LP: #2060904)
+    - wifi: rtw89: disable txptctrl IMR to avoid flase alarm
+    - wifi: rtw89: pci: correct TX resource checking for PCI DMA channel of
+      firmware command
+  * [X13s] Fingerprint reader is not working (LP: #2065376)
+    - SAUCE: arm64: dts: qcom: sc8280xp: Add USB DWC3 Multiport controller
+    - SAUCE: arm64: dts: qcom: sc8280xp-x13s: enable USB MP and fingerprint reader
+  * Fix random HuC/GuC initialization failure of Intel i915 driver
+    (LP: #2061049)
+    - drm/i915/huc: Allow for very slow HuC loading
+  * Add support of TAS2781 amp of audio (LP: #2064064)
+    - ALSA: hda/tas2781: Add new vendor_id and subsystem_id to support ThinkPad
+      ICE-1
+  * Noble update: v6.8.7 upstream stable release (LP: #2065912)
+    - smb3: fix Open files on server counter going negative
+    - ata: libata-core: Allow command duration limits detection for ACS-4 drives
+    - ata: libata-scsi: Fix ata_scsi_dev_rescan() error path
+    - drm/amdgpu/vpe: power on vpe when hw_init
+    - batman-adv: Avoid infinite loop trying to resize local TT
+    - ceph: redirty page before returning AOP_WRITEPAGE_ACTIVATE
+    - ceph: switch to use cap_delay_lock for the unlink delay list
+    - virtio_net: Do not send RSS key if it is not supported
+    - arm64: tlb: Fix TLBI RANGE operand
+    - ARM: dts: imx7s-warp: Pass OV2680 link-frequencies
+    - raid1: fix use-after-free for original bio in raid1_write_request()
+    - ring-buffer: Only update pages_touched when a new page is touched
+    - Bluetooth: Fix memory leak in hci_req_sync_complete()
+    - drm/amd/pm: fixes a random hang in S4 for SMU v13.0.4/11
+    - platform/chrome: cros_ec_uart: properly fix race condition
+    - ACPI: scan: Do not increase dep_unmet for already met dependencies
+    - PM: s2idle: Make sure CPUs will wakeup directly on resume
+    - media: cec: core: remove length check of Timer Status
+    - btrfs: tests: allocate dummy fs_info and root in test_find_delalloc()
+    - ARM: OMAP2+: fix bogus MMC GPIO labels on Nokia N8x0
+    - ARM: OMAP2+: fix N810 MMC gpiod table
+    - mmc: omap: fix broken slot switch lookup
+    - mmc: omap: fix deferred probe
+    - mmc: omap: restore original power up/down steps
+    - ARM: OMAP2+: fix USB regression on Nokia N8x0
+    - firmware: arm_ffa: Fix the partition ID check in ffa_notification_info_get()
+    - firmware: arm_scmi: Make raw debugfs entries non-seekable
+    - cxl/mem: Fix for the index of Clear Event Record Handle
+    - cxl/core/regs: Fix usage of map->reg_type in cxl_decode_regblock() before
+      assigned
+    - arm64: dts: freescale: imx8mp-venice-gw72xx-2x: fix USB vbus regulator
+    - arm64: dts: freescale: imx8mp-venice-gw73xx-2x: fix USB vbus regulator
+    - drm/msm: Add newlines to some debug prints
+    - drm/msm/dpu: don't allow overriding data from catalog
+    - drm/msm/dpu: make error messages at dpu_core_irq_register_callback() more
+      sensible
+    - dt-bindings: display/msm: sm8150-mdss: add DP node
+    - arm64: dts: imx8-ss-conn: fix usdhc wrong lpcg clock order
+    - cxl/core: Fix initialization of mbox_cmd.size_out in get event
+    - Revert "drm/qxl: simplify qxl_fence_wait"
+    - nouveau: fix function cast warning
+    - drm/msm/adreno: Set highest_bank_bit for A619
+    - scsi: hisi_sas: Modify the deadline for ata_wait_after_reset()
+    - scsi: qla2xxx: Fix off by one in qla_edif_app_getstats()
+    - net: openvswitch: fix unwanted error log on timeout policy probing
+    - u64_stats: fix u64_stats_init() for lockdep when used repeatedly in one file
+    - xsk: validate user input for XDP_{UMEM|COMPLETION}_FILL_RING
+    - octeontx2-pf: Fix transmit scheduler resource leak
+    - block: fix q->blkg_list corruption during disk rebind
+    - lib: checksum: hide unused expected_csum_ipv6_magic[]
+    - geneve: fix header validation in geneve[6]_xmit_skb
+    - s390/ism: fix receive message buffer allocation
+    - bnxt_en: Fix possible memory leak in bnxt_rdma_aux_device_init()
+    - bnxt_en: Fix error recovery for RoCE ulp client
+    - bnxt_en: Reset PTP tx_avail after possible firmware reset
+    - ACPI: bus: allow _UID matching for integer zero
+    - base/node / ACPI: Enumerate node access class for 'struct access_coordinate'
+    - ACPI: HMAT: Introduce 2 levels of generic port access class
+    - ACPI: HMAT / cxl: Add retrieval of generic port coordinates for both access
+      classes
+    - cxl: Split out combine_coordinates() for common shared usage
+    - cxl: Split out host bridge access coordinates
+    - cxl: Remove checking of iter in cxl_endpoint_get_perf_coordinates()
+    - cxl: Fix retrieving of access_coordinates in PCIe path
+    - net: ks8851: Inline ks8851_rx_skb()
+    - net: ks8851: Handle softirqs at the end of IRQ thread to fix hang
+    - af_unix: Clear stale u->oob_skb.
+    - octeontx2-af: Fix NIX SQ mode and BP config
+    - ipv6: fib: hide unused 'pn' variable
+    - ipv4/route: avoid unused-but-set-variable warning
+    - ipv6: fix race condition between ipv6_get_ifaddr and ipv6_del_addr
+    - pds_core: use pci_reset_function for health reset
+    - pds_core: Fix pdsc_check_pci_health function to use work thread
+    - Bluetooth: ISO: Align broadcast sync_timeout with connection timeout
+    - Bluetooth: ISO: Don't reject BT_ISO_QOS if parameters are unset
+    - Bluetooth: hci_sync: Use QoS to determine which PHY to scan
+    - Bluetooth: hci_sync: Fix using the same interval and window for Coded PHY
+    - Bluetooth: SCO: Fix not validating setsockopt user input
+    - Bluetooth: RFCOMM: Fix not validating setsockopt user input
+    - Bluetooth: L2CAP: Fix not validating setsockopt user input
+    - Bluetooth: ISO: Fix not validating setsockopt user input
+    - Bluetooth: hci_sock: Fix not validating setsockopt user input
+    - Bluetooth: l2cap: Don't double set the HCI_CONN_MGMT_CONNECTED bit
+    - netfilter: complete validation of user input
+    - net/mlx5: SF, Stop waiting for FW as teardown was called
+    - net/mlx5: Register devlink first under devlink lock
+    - net/mlx5: offset comp irq index in name by one
+    - net/mlx5: Properly link new fs rules into the tree
+    - net/mlx5: Correctly compare pkt reformat ids
+    - net/mlx5e: RSS, Block changing channels number when RXFH is configured
+    - net/mlx5e: Fix mlx5e_priv_init() cleanup flow
+    - net/mlx5e: HTB, Fix inconsistencies with QoS SQs number
+    - net/mlx5e: Do not produce metadata freelist entries in Tx port ts WQE xmit
+    - net: sparx5: fix wrong config being used when reconfiguring PCS
+    - Revert "s390/ism: fix receive message buffer allocation"
+    - net: dsa: mt7530: trap link-local frames regardless of ST Port State
+    - af_unix: Do not use atomic ops for unix_sk(sk)->inflight.
+    - af_unix: Fix garbage collector racing against connect()
+    - net: ena: Fix potential sign extension issue
+    - net: ena: Wrong missing IO completions check order
+    - net: ena: Fix incorrect descriptor free behavior
+    - net: ena: Set tx_info->xdpf value to NULL
+    - drm/xe/display: Fix double mutex initialization
+    - drm/xe/hwmon: Cast result to output precision on left shift of operand
+    - tracing: hide unused ftrace_event_id_fops
+    - iommu/vt-d: Fix wrong use of pasid config
+    - iommu/vt-d: Allocate local memory for page request queue
+    - iommu/vt-d: Fix WARN_ON in iommu probe path
+    - io_uring: refactor DEFER_TASKRUN multishot checks
+    - io_uring: disable io-wq execution of multishot NOWAIT requests
+    - btrfs: qgroup: correctly model root qgroup rsv in convert
+    - btrfs: qgroup: fix qgroup prealloc rsv leak in subvolume operations
+    - btrfs: record delayed inode root in transaction
+    - btrfs: qgroup: convert PREALLOC to PERTRANS after record_root_in_trans
+    - io_uring/net: restore msg_control on sendzc retry
+    - kprobes: Fix possible use-after-free issue on kprobe registration
+    - fs/proc: remove redundant comments from /proc/bootconfig
+    - fs/proc: Skip bootloader comment if no embedded kernel parameters
+    - scsi: sg: Avoid sg device teardown race
+    - scsi: sg: Avoid race in error handling & drop bogus warn
+    - accel/ivpu: Check return code of ipc->lock init
+    - accel/ivpu: Fix PCI D0 state entry in resume
+    - accel/ivpu: Put NPU back to D3hot after failed resume
+    - accel/ivpu: Return max freq for DRM_IVPU_PARAM_CORE_CLOCK_RATE
+    - accel/ivpu: Fix deadlock in context_xa
+    - drm/vmwgfx: Enable DMA mappings with SEV
+    - drm/i915/vrr: Disable VRR when using bigjoiner
+    - drm/amdkfd: Reset GPU on queue preemption failure
+    - drm/ast: Fix soft lockup
+    - drm/panfrost: Fix the error path in panfrost_mmu_map_fault_addr()
+    - drm/client: Fully protect modes[] with dev->mode_config.mutex
+    - drm/msm/dp: fix runtime PM leak on disconnect
+    - drm/msm/dp: fix runtime PM leak on connect failure
+    - drm/amdgpu/umsch: reinitialize write pointer in hw init
+    - arm64: dts: imx8qm-ss-dma: fix can lpcg indices
+    - arm64: dts: imx8-ss-dma: fix can lpcg indices
+    - arm64: dts: imx8-ss-dma: fix adc lpcg indices
+    - arm64: dts: imx8-ss-conn: fix usb lpcg indices
+    - arm64: dts: imx8-ss-dma: fix pwm lpcg indices
+    - arm64: dts: imx8-ss-lsio: fix pwm lpcg indices
+    - arm64: dts: imx8-ss-dma: fix spi lpcg indices
+    - vhost: Add smp_rmb() in vhost_vq_avail_empty()
+    - vhost: Add smp_rmb() in vhost_enable_notify()
+    - perf/x86: Fix out of range data
+    - x86/cpu: Actually turn off mitigations by default for
+      SPECULATION_MITIGATIONS=n
+    - selftests/timers/posix_timers: Reimplement check_timer_distribution()
+    - selftests: timers: Fix posix_timers ksft_print_msg() warning
+    - selftests: timers: Fix abs() warning in posix_timers test
+    - selftests: kselftest: Mark functions that unconditionally call exit() as
+      __noreturn
+    - x86/apic: Force native_apic_mem_read() to use the MOV instruction
+    - irqflags: Explicitly ignore lockdep_hrtimer_exit() argument
+    - selftests: kselftest: Fix build failure with NOLIBC
+    - kernfs: annotate different lockdep class for of->mutex of writable files
+    - x86/bugs: Fix return type of spectre_bhi_state()
+    - x86/bugs: Fix BHI documentation
+    - x86/bugs: Cache the value of MSR_IA32_ARCH_CAPABILITIES
+    - x86/bugs: Rename various 'ia32_cap' variables to 'x86_arch_cap_msr'
+    - x86/bugs: Fix BHI handling of RRSBA
+    - x86/bugs: Clarify that syscall hardening isn't a BHI mitigation
+    - x86/bugs: Remove CONFIG_BHI_MITIGATION_AUTO and spectre_bhi=auto
+    - [Config] updateconfigs to remove obsolete SPECTRE_BHI_AUTO
+    - x86/bugs: Replace CONFIG_SPECTRE_BHI_{ON,OFF} with
+      CONFIG_MITIGATION_SPECTRE_BHI
+    - [Config] updateconfigs to enable new MITIGATION_SPECTRE_BHI
+    - drm/i915/cdclk: Fix CDCLK programming order when pipes are active
+    - drm/i915/psr: Disable PSR when bigjoiner is used
+    - drm/i915: Disable port sync when bigjoiner is used
+    - drm/i915: Disable live M/N updates when using bigjoiner
+    - drm/amdgpu: Reset dGPU if suspend got aborted
+    - drm/amdgpu: always force full reset for SOC21
+    - drm/amdgpu: fix incorrect number of active RBs for gfx11
+    - drm/amdgpu: differentiate external rev id for gfx 11.5.0
+    - drm/amd/display: Program VSC SDP colorimetry for all DP sinks >= 1.4
+    - drm/amd/display: Set VSC SDP Colorimetry same way for MST and SST
+    - drm/amd/display: Do not recursively call manual trigger programming
+    - drm/amd/display: Return max resolution supported by DWB
+    - drm/amd/display: always reset ODM mode in context when adding first plane
+    - drm/amd/display: fix disable otg wa logic in DCN316
+    - Linux 6.8.7
+  * Noble update: v6.8.6 upstream stable release (LP: #2065899)
+    - amdkfd: use calloc instead of kzalloc to avoid integer overflow
+    - wifi: ath9k: fix LNA selection in ath_ant_try_scan()
+    - wifi: rtw89: fix null pointer access when abort scan
+    - bnx2x: Fix firmware version string character counts
+    - net: stmmac: dwmac-starfive: Add support for JH7100 SoC
+    - net: phy: phy_device: Prevent nullptr exceptions on ISR
+    - wifi: rtw89: pci: validate RX tag for RXQ and RPQ
+    - wifi: rtw89: pci: enlarge RX DMA buffer to consider size of RX descriptor
+    - VMCI: Fix memcpy() run-time warning in dg_dispatch_as_host()
+    - wifi: iwlwifi: pcie: Add the PCI device id for new hardware
+    - arm64: dts: qcom: qcm6490-idp: Add definition for three LEDs
+    - net: dsa: qca8k: put MDIO controller OF node if unavailable
+    - arm64: dts: qcom: qrb2210-rb1: disable cluster power domains
+    - printk: For @suppress_panic_printk check for other CPU in panic
+    - panic: Flush kernel log buffer at the end
+    - dump_stack: Do not get cpu_sync for panic CPU
+    - wifi: iwlwifi: pcie: Add new PCI device id and CNVI
+    - cpuidle: Avoid potential overflow in integer multiplication
+    - ARM: dts: rockchip: fix rk3288 hdmi ports node
+    - ARM: dts: rockchip: fix rk322x hdmi ports node
+    - arm64: dts: rockchip: fix rk3328 hdmi ports node
+    - arm64: dts: rockchip: fix rk3399 hdmi ports node
+    - net: add netdev_lockdep_set_classes() to virtual drivers
+    - arm64: dts: qcom: qcs6490-rb3gen2: Declare GCC clocks protected
+    - pmdomain: ti: Add a null pointer check to the omap_prm_domain_init
+    - pmdomain: imx8mp-blk-ctrl: imx8mp_blk: Add fdcc clock to hdmimix domain
+    - ACPI: resource: Add IRQ override quirk for ASUS ExpertBook B2502FBA
+    - ionic: set adminq irq affinity
+    - net: skbuff: add overflow debug check to pull/push helpers
+    - firmware: tegra: bpmp: Return directly after a failed kzalloc() in
+      get_filename()
+    - wifi: brcmfmac: Add DMI nvram filename quirk for ACEPC W5 Pro
+    - wifi: mt76: mt7915: add locking for accessing mapped registers
+    - wifi: mt76: mt7996: disable AMSDU for non-data frames
+    - wifi: mt76: mt7996: add locking for accessing mapped registers
+    - ACPI: x86: Move acpi_quirk_skip_serdev_enumeration() out of
+      CONFIG_X86_ANDROID_TABLETS
+    - ACPI: x86: Add DELL0501 handling to acpi_quirk_skip_serdev_enumeration()
+    - pstore/zone: Add a null pointer check to the psz_kmsg_read
+    - tools/power x86_energy_perf_policy: Fix file leak in get_pkg_num()
+    - net: pcs: xpcs: Return EINVAL in the internal methods
+    - dma-direct: Leak pages on dma_set_decrypted() failure
+    - wifi: ath11k: decrease MHI channel buffer length to 8KB
+    - iommu/arm-smmu-v3: Hold arm_smmu_asid_lock during all of attach_dev
+    - cpufreq: Don't unregister cpufreq cooling on CPU hotplug
+    - overflow: Allow non-type arg to type_max() and type_min()
+    - wifi: iwlwifi: Add missing MODULE_FIRMWARE() for *.pnvm
+    - wifi: cfg80211: check A-MSDU format more carefully
+    - btrfs: handle chunk tree lookup error in btrfs_relocate_sys_chunks()
+    - btrfs: export: handle invalid inode or root reference in btrfs_get_parent()
+    - btrfs: send: handle path ref underflow in header iterate_inode_ref()
+    - ice: use relative VSI index for VFs instead of PF VSI number
+    - net/smc: reduce rtnl pressure in smc_pnet_create_pnetids_list()
+    - netdev: let netlink core handle -EMSGSIZE errors
+    - Bluetooth: btintel: Fix null ptr deref in btintel_read_version
+    - Bluetooth: btmtk: Add MODULE_FIRMWARE() for MT7922
+    - Bluetooth: Add new quirk for broken read key length on ATS2851
+    - drm/vc4: don't check if plane->state->fb == state->fb
+    - drm/ci: uprev mesa version: fix kdl commit fetch
+    - drm/amdgpu: Skip do PCI error slot reset during RAS recovery
+    - Input: synaptics-rmi4 - fail probing if memory allocation for "phys" fails
+    - drm: panel-orientation-quirks: Add quirk for GPD Win Mini
+    - ASoC: SOF: amd: Optimize quirk for Valve Galileo
+    - drm/ttm: return ENOSPC from ttm_bo_mem_space v3
+    - scsi: ufs: qcom: Avoid re-init quirk when gears match
+    - drm/amd/display: increased min_dcfclk_mhz and min_fclk_mhz
+    - pinctrl: renesas: checker: Limit cfg reg enum checks to provided IDs
+    - sysv: don't call sb_bread() with pointers_lock held
+    - scsi: lpfc: Fix possible memory leak in lpfc_rcv_padisc()
+    - drm/amd/display: Disable idle reallow as part of command/gpint execution
+    - isofs: handle CDs with bad root inode but good Joliet root directory
+    - ASoC: Intel: sof_rt5682: dmi quirk cleanup for mtl boards
+    - ASoC: Intel: common: DMI remap for rebranded Intel NUC M15 (LAPRC710)
+      laptops
+    - rcu/nocb: Fix WARN_ON_ONCE() in the rcu_nocb_bypass_lock()
+    - rcu-tasks: Repair RCU Tasks Trace quiescence check
+    - Julia Lawall reported this null pointer dereference, this should fix it.
+    - media: sta2x11: fix irq handler cast
+    - ALSA: firewire-lib: handle quirk to calculate payload quadlets as data block
+      counter
+    - drm/panel: simple: Add BOE BP082WX1-100 8.2" panel
+    - x86/vdso: Fix rethunk patching for vdso-image-{32,64}.o
+    - ASoC: Intel: avs: Populate board selection with new I2S entries
+    - ext4: add a hint for block bitmap corrupt state in mb_groups
+    - ext4: forbid commit inconsistent quota data when errors=remount-ro
+    - drm/amd/display: Fix nanosec stat overflow
+    - accel/habanalabs: increase HL_MAX_STR to 64 bytes to avoid warnings
+    - i2c: designware: Fix RX FIFO depth define on Wangxun 10Gb NIC
+    - HID: input: avoid polling stylus battery on Chromebook Pompom
+    - drm/amd/amdgpu: Fix potential ioremap() memory leaks in amdgpu_device_init()
+    - drm: Check output polling initialized before disabling
+    - drm: Check polling initialized before enabling in
+      drm_helper_probe_single_connector_modes
+    - SUNRPC: increase size of rpc_wait_queue.qlen from unsigned short to unsigned
+      int
+    - PCI: Disable D3cold on Asus B1400 PCI-NVMe bridge
+    - Revert "ACPI: PM: Block ASUS B1400CEAE from suspend to idle by default"
+    - libperf evlist: Avoid out-of-bounds access
+    - crypto: iaa - Fix async_disable descriptor leak
+    - input/touchscreen: imagis: Correct the maximum touch area value
+    - drivers/perf: hisi: Enable HiSilicon Erratum 162700402 quirk for HIP09
+    - block: prevent division by zero in blk_rq_stat_sum()
+    - RDMA/cm: add timeout to cm_destroy_id wait
+    - Input: imagis - use FIELD_GET where applicable
+    - Input: allocate keycode for Display refresh rate toggle
+    - platform/x86: acer-wmi: Add support for Acer PH16-71
+    - platform/x86: acer-wmi: Add predator_v4 module parameter
+    - platform/x86: touchscreen_dmi: Add an extra entry for a variant of the Chuwi
+      Vi8 tablet
+    - perf/x86/amd/lbr: Discard erroneous branch entries
+    - ALSA: hda/realtek: Add quirk for Lenovo Yoga 9 14IMH9
+    - ktest: force $buildonly = 1 for 'make_warnings_file' test type
+    - Input: xpad - add support for Snakebyte GAMEPADs
+    - ring-buffer: use READ_ONCE() to read cpu_buffer->commit_page in concurrent
+      environment
+    - tools: iio: replace seekdir() in iio_generic_buffer
+    - bus: mhi: host: Add MHI_PM_SYS_ERR_FAIL state
+    - kernfs: RCU protect kernfs_nodes and avoid kernfs_idr_lock in
+      kernfs_find_and_get_node_by_id()
+    - usb: typec: ucsi: Add qcm6490-pmic-glink as needing PDOS quirk
+    - thunderbolt: Calculate DisplayPort tunnel bandwidth after DPRX capabilities
+      read
+    - usb: gadget: uvc: refactor the check for a valid buffer in the pump worker
+    - usb: gadget: uvc: mark incomplete frames with UVC_STREAM_ERR
+    - usb: typec: ucsi: Limit read size on v1.2
+    - serial: 8250_of: Drop quirk fot NPCM from 8250_port
+    - thunderbolt: Keep the domain powered when USB4 port is in redrive mode
+    - usb: typec: tcpci: add generic tcpci fallback compatible
+    - usb: sl811-hcd: only defined function checkdone if QUIRK2 is defined
+    - ASoC: amd: yc: Fix non-functional mic on ASUS M7600RE
+    - thermal/of: Assume polling-delay(-passive) 0 when absent
+    - ASoC: soc-core.c: Skip dummy codec when adding platforms
+    - x86/xen: attempt to inflate the memory balloon on PVH
+    - fbdev: viafb: fix typo in hw_bitblt_1 and hw_bitblt_2
+    - io_uring: clear opcode specific data for an early failure
+    - modpost: fix null pointer dereference
+    - drivers/nvme: Add quirks for device 126f:2262
+    - fbmon: prevent division by zero in fb_videomode_from_videomode()
+    - ALSA: hda/realtek: Add quirks for some Clevo laptops
+    - drm/amdgpu: Init zone device and drm client after mode-1 reset on reload
+    - gcc-plugins/stackleak: Avoid .head.text section
+    - media: mediatek: vcodec: Fix oops when HEVC init fails
+    - media: mediatek: vcodec: adding lock to protect decoder context list
+    - media: mediatek: vcodec: adding lock to protect encoder context list
+    - randomize_kstack: Improve entropy diffusion
+    - platform/x86/intel/hid: Don't wake on 5-button releases
+    - platform/x86: intel-vbtn: Update tablet mode switch at end of probe
+    - nouveau: fix devinit paths to only handle display on GSP.
+    - Bluetooth: btintel: Fixe build regression
+    - net: mpls: error out if inner headers are not set
+    - VMCI: Fix possible memcpy() run-time warning in
+      vmci_datagram_invoke_guest_handler()
+    - x86/vdso: Fix rethunk patching for vdso-image-x32.o too
+    - Revert "drm/amd/amdgpu: Fix potential ioremap() memory leaks in
+      amdgpu_device_init()"
+    - Linux 6.8.6
+  * Noble update: v6.8.5 upstream stable release (LP: #2065400)
+    - scripts/bpf_doc: Use silent mode when exec make cmd
+    - xsk: Don't assume metadata is always requested in TX completion
+    - s390/bpf: Fix bpf_plt pointer arithmetic
+    - bpf, arm64: fix bug in BPF_LDX_MEMSX
+    - dma-buf: Fix NULL pointer dereference in sanitycheck()
+    - arm64: bpf: fix 32bit unconditional bswap
+    - nfc: nci: Fix uninit-value in nci_dev_up and nci_ntf_packet
+    - nfsd: Fix error cleanup path in nfsd_rename()
+    - tools: ynl: fix setting presence bits in simple nests
+    - mlxbf_gige: stop PHY during open() error paths
+    - wifi: iwlwifi: mvm: pick the version of SESSION_PROTECTION_NOTIF
+    - wifi: iwlwifi: mvm: rfi: fix potential response leaks
+    - wifi: iwlwifi: mvm: include link ID when releasing frames
+    - ALSA: hda: cs35l56: Set the init_done flag before component_add()
+    - ice: Refactor FW data type and fix bitmap casting issue
+    - ice: fix memory corruption bug with suspend and rebuild
+    - ixgbe: avoid sleeping allocation in ixgbe_ipsec_vf_add_sa()
+    - igc: Remove stale comment about Tx timestamping
+    - drm/xe: Remove unused xe_bo->props struct
+    - drm/xe: Add exec_queue.sched_props.job_timeout_ms
+    - drm/xe/guc_submit: use jiffies for job timeout
+    - drm/xe/queue: fix engine_class bounds check
+    - drm/xe/device: fix XE_MAX_GT_PER_TILE check
+    - drm/xe/device: fix XE_MAX_TILES_PER_DEVICE check
+    - dpll: indent DPLL option type by a tab
+    - s390/qeth: handle deferred cc1
+    - net: hsr: hsr_slave: Fix the promiscuous mode in offload mode
+    - tcp: properly terminate timers for kernel sockets
+    - net: wwan: t7xx: Split 64bit accesses to fix alignment issues
+    - drm/rockchip: vop2: Remove AR30 and AB30 format support
+    - selftests: vxlan_mdb: Fix failures with old libnet
+    - gpiolib: Fix debug messaging in gpiod_find_and_request()
+    - ACPICA: debugger: check status of acpi_evaluate_object() in
+      acpi_db_walk_for_fields()
+    - net: hns3: fix index limit to support all queue stats
+    - net: hns3: fix kernel crash when devlink reload during pf initialization
+    - net: hns3: mark unexcuted loopback test result as UNEXECUTED
+    - tls: recv: process_rx_list shouldn't use an offset with kvec
+    - tls: adjust recv return with async crypto and failed copy to userspace
+    - tls: get psock ref after taking rxlock to avoid leak
+    - mlxbf_gige: call request_irq() after NAPI initialized
+    - drm/amd/display: Update P010 scaling cap
+    - drm/amd/display: Send DTBCLK disable message on first commit
+    - bpf: Protect against int overflow for stack access size
+    - cifs: Fix duplicate fscache cookie warnings
+    - netfilter: nf_tables: reject destroy command to remove basechain hooks
+    - netfilter: nf_tables: reject table flag and netdev basechain updates
+    - netfilter: nf_tables: skip netdev hook unregistration if table is dormant
+    - iommu: Validate the PASID in iommu_attach_device_pasid()
+    - net: bcmasp: Bring up unimac after PHY link up
+    - net: lan743x: Add set RFE read fifo threshold for PCI1x1x chips
+    - Octeontx2-af: fix pause frame configuration in GMP mode
+    - inet: inet_defrag: prevent sk release while still in use
+    - drm/i915: Stop doing double audio enable/disable on SDVO and g4x+ DP
+    - drm/i915/display: Disable AuxCCS framebuffers if built for Xe
+    - drm/i915/xelpg: Extend some workarounds/tuning to gfx version 12.74
+    - drm/i915/mtl: Update workaround 14018575942
+    - drm/i915: Do not print 'pxp init failed with 0' when it succeed
+    - dm integrity: fix out-of-range warning
+    - modpost: do not make find_tosym() return NULL
+    - kbuild: make -Woverride-init warnings more consistent
+    - mm/treewide: replace pud_large() with pud_leaf()
+    - Revert "x86/mm/ident_map: Use gbpages only where full GB page should be
+      mapped."
+    - gpio: cdev: sanitize the label before requesting the interrupt
+    - RISC-V: KVM: Fix APLIC setipnum_le/be write emulation
+    - RISC-V: KVM: Fix APLIC in_clrip[x] read emulation
+    - KVM: arm64: Fix host-programmed guest events in nVHE
+    - KVM: arm64: Fix out-of-IPA space translation fault handling
+    - selinux: avoid dereference of garbage after mount failure
+    - r8169: fix issue caused by buggy BIOS on certain boards with RTL8168d
+    - x86/cpufeatures: Add CPUID_LNX_5 to track recently added Linux-defined word
+    - x86/bpf: Fix IP after emitting call depth accounting
+    - Revert "Bluetooth: hci_qca: Set BDA quirk bit if fwnode exists in DT"
+    - arm64: dts: qcom: sc7180-trogdor: mark bluetooth address as broken
+    - Bluetooth: qca: fix device-address endianness
+    - Bluetooth: add quirk for broken address properties
+    - Bluetooth: hci_event: set the conn encrypted before conn establishes
+    - Bluetooth: Fix TOCTOU in HCI debugfs implementation
+    - netfilter: nf_tables: release batch on table validation from abort path
+    - netfilter: nf_tables: release mutex after nft_gc_seq_end from abort path
+    - selftests: mptcp: join: fix dev in check_endpoint
+    - net/rds: fix possible cp null dereference
+    - net: usb: ax88179_178a: avoid the interface always configured as random
+      address
+    - net: mana: Fix Rx DMA datasize and skb_over_panic
+    - vsock/virtio: fix packet delivery to tap device
+    - netfilter: nf_tables: reject new basechain after table flag update
+    - netfilter: nf_tables: flush pending destroy work before exit_net release
+    - netfilter: nf_tables: Fix potential data-race in __nft_flowtable_type_get()
+    - netfilter: nf_tables: discard table flag update with pending basechain
+      deletion
+    - netfilter: validate user input for expected length
+    - vboxsf: Avoid an spurious warning if load_nls_xxx() fails
+    - bpf, sockmap: Prevent lock inversion deadlock in map delete elem
+    - mptcp: prevent BPF accessing lowat from a subflow socket.
+    - x86/retpoline: Do the necessary fixup to the Zen3/4 srso return thunk for
+      !SRSO
+    - KVM: arm64: Use TLBI_TTL_UNKNOWN in __kvm_tlb_flush_vmid_range()
+    - KVM: arm64: Ensure target address is granule-aligned for range TLBI
+    - net/sched: act_skbmod: prevent kernel-infoleak
+    - net: dsa: sja1105: Fix parameters order in sja1110_pcs_mdio_write_c45()
+    - net/sched: fix lockdep splat in qdisc_tree_reduce_backlog()
+    - net: stmmac: fix rx queue priority assignment
+    - net: phy: micrel: lan8814: Fix when enabling/disabling 1-step timestamping
+    - net: txgbe: fix i2c dev name cannot match clkdev
+    - net: fec: Set mac_managed_pm during probe
+    - net: phy: micrel: Fix potential null pointer dereference
+    - net: dsa: mv88e6xxx: fix usable ports on 88e6020
+    - selftests: net: gro fwd: update vxlan GRO test expectations
+    - gro: fix ownership transfer
+    - idpf: fix kernel panic on unknown packet types
+    - ice: fix enabling RX VLAN filtering
+    - i40e: Fix VF MAC filter removal
+    - tcp: Fix bind() regression for v6-only wildcard and v4-mapped-v6 non-
+      wildcard addresses.
+    - erspan: make sure erspan_base_hdr is present in skb->head
+    - selftests: reuseaddr_conflict: add missing new line at the end of the output
+    - tcp: Fix bind() regression for v6-only wildcard and v4(-mapped-v6) non-
+      wildcard addresses.
+    - ax25: fix use-after-free bugs caused by ax25_ds_del_timer
+    - e1000e: Workaround for sporadic MDI error on Meteor Lake systems
+    - ipv6: Fix infinite recursion in fib6_dump_done().
+    - mlxbf_gige: stop interface during shutdown
+    - r8169: skip DASH fw status checks when DASH is disabled
+    - udp: do not accept non-tunnel GSO skbs landing in a tunnel
+    - udp: do not transition UDP GRO fraglist partial checksums to unnecessary
+    - udp: prevent local UDP tunnel packets from being GROed
+    - octeontx2-af: Fix issue with loading coalesced KPU profiles
+    - octeontx2-pf: check negative error code in otx2_open()
+    - octeontx2-af: Add array index check
+    - i40e: fix i40e_count_filters() to count only active/new filters
+    - i40e: fix vf may be used uninitialized in this function warning
+    - i40e: Enforce software interrupt during busy-poll exit
+    - drm/amd: Flush GFXOFF requests in prepare stage
+    - e1000e: Minor flow correction in e1000_shutdown function
+    - e1000e: move force SMBUS from enable ulp function to avoid PHY loss issue
+    - mean_and_variance: Drop always failing tests
+    - net: ravb: Let IP-specific receive function to interrogate descriptors
+    - net: ravb: Always process TX descriptor ring
+    - net: ravb: Always update error counters
+    - KVM: SVM: Use unsigned integers when dealing with ASIDs
+    - KVM: SVM: Add support for allowing zero SEV ASIDs
+    - selftests: mptcp: connect: fix shellcheck warnings
+    - selftests: mptcp: use += operator to append strings
+    - mptcp: don't account accept() of non-MPC client as fallback to TCP
+    - 9p: Fix read/write debug statements to report server reply
+    - ASoC: wm_adsp: Fix missing mutex_lock in wm_adsp_write_ctl()
+    - ASoC: cs42l43: Correct extraction of data pointer in suspend/resume
+    - riscv: mm: Fix prototype to avoid discarding const
+    - riscv: hwprobe: do not produce frtace relocation
+    - drivers/perf: riscv: Disable PERF_SAMPLE_BRANCH_* while not supported
+    - block: count BLK_OPEN_RESTRICT_WRITES openers
+    - RISC-V: Update AT_VECTOR_SIZE_ARCH for new AT_MINSIGSTKSZ
+    - ASoC: amd: acp: fix for acp pdm configuration check
+    - regmap: maple: Fix cache corruption in regcache_maple_drop()
+    - ALSA: hda: cs35l56: Add ACPI device match tables
+    - drm/panfrost: fix power transition timeout warnings
+    - nouveau/uvmm: fix addr/range calcs for remap operations
+    - drm/prime: Unbreak virtgpu dma-buf export
+    - ASoC: rt5682-sdw: fix locking sequence
+    - ASoC: rt711-sdca: fix locking sequence
+    - ASoC: rt711-sdw: fix locking sequence
+    - ASoC: rt712-sdca-sdw: fix locking sequence
+    - ASoC: rt722-sdca-sdw: fix locking sequence
+    - ASoC: ops: Fix wraparound for mask in snd_soc_get_volsw
+    - spi: s3c64xx: Extract FIFO depth calculation to a dedicated macro
+    - spi: s3c64xx: sort headers alphabetically
+    - spi: s3c64xx: explicitly include <linux/bits.h>
+    - spi: s3c64xx: remove else after return
+    - spi: s3c64xx: define a magic value
+    - spi: s3c64xx: allow full FIFO masks
+    - spi: s3c64xx: determine the fifo depth only once
+    - spi: s3c64xx: Use DMA mode from fifo size
+    - ASoC: amd: acp: fix for acp_init function error handling
+    - regmap: maple: Fix uninitialized symbol 'ret' warnings
+    - ata: sata_sx4: fix pdc20621_get_from_dimm() on 64-bit
+    - scsi: mylex: Fix sysfs buffer lengths
+    - scsi: sd: Unregister device if device_add_disk() failed in sd_probe()
+    - Revert "ALSA: emu10k1: fix synthesizer sample playback position and caching"
+    - drm/i915/dp: Fix DSC state HW readout for SST connectors
+    - cifs: Fix caching to try to do open O_WRONLY as rdwr on server
+    - spi: mchp-pci1xxx: Fix a possible null pointer dereference in
+      pci1xxx_spi_probe
+    - s390/pai: fix sampling event removal for PMU device driver
+    - thermal: gov_power_allocator: Allow binding without cooling devices
+    - thermal: gov_power_allocator: Allow binding without trip points
+    - drm/i915/gt: Limit the reserved VM space to only the platforms that need it
+    - ata: sata_mv: Fix PCI device ID table declaration compilation warning
+    - ASoC: SOF: amd: fix for false dsp interrupts
+    - SUNRPC: Fix a slow server-side memory leak with RPC-over-TCP
+    - riscv: use KERN_INFO in do_trap
+    - riscv: Fix warning by declaring arch_cpu_idle() as noinstr
+    - riscv: Disable preemption when using patch_map()
+    - nfsd: hold a lighter-weight client reference over CB_RECALL_ANY
+    - lib/stackdepot: move stack_record struct definition into the header
+    - stackdepot: rename pool_index to pool_index_plus_1
+    - x86/retpoline: Add NOENDBR annotation to the SRSO dummy return thunk
+    - Revert "drm/amd/display: Send DTBCLK disable message on first commit"
+    - gpio: cdev: check for NULL labels when sanitizing them for irqs
+    - gpio: cdev: fix missed label sanitizing in debounce_setup()
+    - ksmbd: don't send oplock break if rename fails
+    - ksmbd: validate payload size in ipc response
+    - ksmbd: do not set SMB2_GLOBAL_CAP_ENCRYPTION for SMB 3.1.1
+    - ALSA: hda: Add pplcllpl/u members to hdac_ext_stream
+    - ALSA: hda/realtek - Fix inactive headset mic jack
+    - ALSA: hda/realtek: Add sound quirks for Lenovo Legion slim 7 16ARHA7 models
+    - ALSA: hda/realtek: cs35l41: Support ASUS ROG G634JYR
+    - ALSA: hda/realtek: Update Panasonic CF-SZ6 quirk to support headset with
+      microphone
+    - io_uring/kbuf: get rid of lower BGID lists
+    - io_uring/kbuf: get rid of bl->is_ready
+    - io_uring/kbuf: protect io_buffer_list teardown with a reference
+    - io_uring/rw: don't allow multishot reads without NOWAIT support
+    - io_uring: use private workqueue for exit work
+    - io_uring/kbuf: hold io_buffer_list reference over mmap
+    - ASoC: SOF: Add dsp_max_burst_size_in_ms member to snd_sof_pcm_stream
+    - ASoC: SOF: ipc4-topology: Save the DMA maximum burst size for PCMs
+    - ASoC: SOF: Intel: hda-pcm: Use dsp_max_burst_size_in_ms to place constraint
+    - ASoC: SOF: Intel: hda: Implement get_stream_position (Linear Link Position)
+    - ASoC: SOF: Intel: mtl/lnl: Use the generic get_stream_position callback
+    - ASoC: SOF: Introduce a new callback pair to be used for PCM delay reporting
+    - ASoC: SOF: Intel: Set the dai/host get frame/byte counter callbacks
+    - ASoC: SOF: Intel: hda-common-ops: Do not set the get_stream_position
+      callback
+    - ASoC: SOF: ipc4-pcm: Use the snd_sof_pcm_get_dai_frame_counter() for
+      pcm_delay
+    - ASoC: SOF: Remove the get_stream_position callback
+    - ASoC: SOF: ipc4-pcm: Move struct sof_ipc4_timestamp_info definition locally
+    - ASoC: SOF: ipc4-pcm: Combine the SOF_IPC4_PIPE_PAUSED cases in pcm_trigger
+    - ASoC: SOF: ipc4-pcm: Invalidate the stream_start_offset in PAUSED state
+    - ASoC: SOF: sof-pcm: Add pointer callback to sof_ipc_pcm_ops
+    - ASoC: SOF: ipc4-pcm: Correct the delay calculation
+    - ASoC: SOF: Intel: hda: Compensate LLP in case it is not reset
+    - driver core: Introduce device_link_wait_removal()
+    - of: dynamic: Synchronize of_changeset_destroy() with the devlink removals
+    - of: module: prevent NULL pointer dereference in vsnprintf()
+    - x86/mm/pat: fix VM_PAT handling in COW mappings
+    - x86/mce: Make sure to grab mce_sysfs_mutex in set_bank()
+    - x86/coco: Require seeding RNG with RDRAND on CoCo systems
+    - perf/x86/intel/ds: Don't clear ->pebs_data_cfg for the last PEBS event
+    - riscv: Fix vector state restore in rt_sigreturn()
+    - arm64/ptrace: Use saved floating point state type to determine SVE layout
+    - mm/secretmem: fix GUP-fast succeeding on secretmem folios
+    - selftests/mm: include strings.h for ffsl
+    - s390/entry: align system call table on 8 bytes
+    - riscv: Fix spurious errors from __get/put_kernel_nofault
+    - riscv: process: Fix kernel gp leakage
+    - smb: client: fix UAF in smb2_reconnect_server()
+    - smb: client: guarantee refcounted children from parent session
+    - smb: client: refresh referral without acquiring refpath_lock
+    - smb: client: handle DFS tcons in cifs_construct_tcon()
+    - smb: client: serialise cifs_construct_tcon() with cifs_mount_mutex
+    - smb3: retrying on failed server close
+    - smb: client: fix potential UAF in cifs_debug_files_proc_show()
+    - smb: client: fix potential UAF in cifs_stats_proc_write()
+    - smb: client: fix potential UAF in cifs_stats_proc_show()
+    - smb: client: fix potential UAF in cifs_dump_full_key()
+    - smb: client: fix potential UAF in smb2_is_valid_oplock_break()
+    - smb: client: fix potential UAF in smb2_is_valid_lease_break()
+    - smb: client: fix potential UAF in is_valid_oplock_break()
+    - smb: client: fix potential UAF in smb2_is_network_name_deleted()
+    - smb: client: fix potential UAF in cifs_signal_cifsd_for_reconnect()
+    - drm/i915/mst: Limit MST+DSC to TGL+
+    - drm/i915/mst: Reject FEC+MST on ICL
+    - drm/i915/dp: Fix the computation for compressed_bpp for DISPLAY < 13
+    - drm/i915/gt: Disable HW load balancing for CCS
+    - drm/i915/gt: Do not generate the command streamer for all the CCS
+    - drm/i915/gt: Enable only one CCS for compute workload
+    - drm/xe: Use ring ops TLB invalidation for rebinds
+    - drm/xe: Rework rebinding
+    - Revert "x86/mpparse: Register APIC address only once"
+    - bpf: put uprobe link's path and task in release callback
+    - bpf: support deferring bpf_link dealloc to after RCU grace period
+    - efi/libstub: Add generic support for parsing mem_encrypt=
+    - x86/boot: Move mem_encrypt= parsing to the decompressor
+    - x86/sme: Move early SME kernel encryption handling into .head.text
+    - x86/sev: Move early startup code into .head.text section
+    - Linux 6.8.5
+  * CVE-2024-26926
+    - binder: check offset alignment in binder_get_object()
+  * CVE-2024-26922
+    - drm/amdgpu: validate the parameters of bo mapping operations more clearly
+  * CVE-2024-26924
+    - netfilter: nft_set_pipapo: do not free live element
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 05 Jul 2024 13:25:34 +0900
+
+linux-qcom (6.8.0-1004.4) jammy; urgency=medium
+
+  * [RB3] bluetooth hci0 failure found in dmesg
+    - SAUCE: bluetooth/hci_qca: fix timing
+
+  * ftrace:test.d--dynevent--add_remove_btfarg.tc in ubuntu_kselftests_ftrace
+    failed on some architectures (LP: #2067291)
+    - selftests/ftrace: Fix BTFARG testcase to check fprobe is enabled correctly
+
+  [ Ubuntu: 6.8.0-35.35 ]
+
+  * noble/linux: 6.8.0-35.35 -proposed tracker (LP: #2065886)
+  * CVE-2024-21823
+    - VFIO: Add the SPR_DSA and SPR_IAX devices to the denylist
+    - dmaengine: idxd: add a new security check to deal with a hardware erratum
+    - dmaengine: idxd: add a write() method for applications to submit work
+
+  [ Ubuntu: 6.8.0-34.34 ]
+
+  * noble/linux: 6.8.0-34.34 -proposed tracker (LP: #2065167)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2024.04.29)
+
+  [ Ubuntu: 6.8.0-32.32 ]
+
+  * noble/linux: 6.8.0-32.32 -proposed tracker (LP: #2064344)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] drop getabis data
+    - [Packaging] update variants
+    - [Packaging] update annotations scripts
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/2024.04.29)
+  * Enable Nezha board (LP: #1975592)
+    - [Config] Enable CONFIG_REGULATOR_FIXED_VOLTAGE on riscv64
+  * Enable Nezha board (LP: #1975592) // Enable StarFive VisionFive 2 board
+    (LP: #2013232)
+    - [Config] Enable CONFIG_SERIAL_8250_DW on riscv64
+  * RISC-V kernel config is out of sync with other archs (LP: #1981437)
+    - [Config] Sync riscv64 config with other architectures
+  * obsolete out-of-tree ivsc dkms in favor of in-tree one (LP: #2061747)
+    - ACPI: scan: Defer enumeration of devices with a _DEP pointing to IVSC device
+    - Revert "mei: vsc: Call wake_up() in the threaded IRQ handler"
+    - mei: vsc: Unregister interrupt handler for system suspend
+    - media: ipu-bridge: Add ov01a10 in Dell XPS 9315
+    - SAUCE: media: ipu-bridge: Support more sensors
+  * Fix after-suspend-mediacard/sdhc-insert test failed (LP: #2042500)
+    - PCI/ASPM: Move pci_configure_ltr() to aspm.c
+    - PCI/ASPM: Always build aspm.c
+    - PCI/ASPM: Move pci_save_ltr_state() to aspm.c
+    - PCI/ASPM: Save L1 PM Substates Capability for suspend/resume
+    - PCI/ASPM: Call pci_save_ltr_state() from pci_save_pcie_state()
+    - PCI/ASPM: Disable L1 before configuring L1 Substates
+    - PCI/ASPM: Update save_state when configuration changes
+  * RTL8852BE fw security fail then lost WIFI function during suspend/resume
+    cycle (LP: #2063096)
+    - wifi: rtw89: download firmware with five times retry
+  * intel_rapl_common: Add support for ARL and LNL (LP: #2061953)
+    - powercap: intel_rapl: Add support for Lunar Lake-M paltform
+    - powercap: intel_rapl: Add support for Arrow Lake
+  * Kernel panic during checkbox stress_ng_test on Grace running noble 6.8
+    (arm64+largemem) kernel (LP: #2058557)
+    - aio: Fix null ptr deref in aio_complete() wakeup
+  * Avoid creating non-working backlight sysfs knob from ASUS board
+    (LP: #2060422)
+    - platform/x86: asus-wmi: Consider device is absent when the read is ~0
+  * Include cifs.ko in linux-modules package (LP: #2042546)
+    - [Packaging] Replace fs/cifs with fs/smb/client in inclusion list
+  * Add Real-time Linux Analysis tool (rtla) to linux-tools (LP: #2059080)
+    - SAUCE: rtla: fix deb build
+    - [Packaging] add Real-time Linux Analysis tool (rtla) to linux-tools
+    - [Packaging] update dependencies for rtla
+  * Noble update: v6.8.4 upstream stable release (LP: #2060533)
+    - Revert "workqueue: Shorten events_freezable_power_efficient name"
+    - Revert "workqueue: Don't call cpumask_test_cpu() with -1 CPU in
+      wq_update_node_max_active()"
+    - Revert "workqueue: Implement system-wide nr_active enforcement for unbound
+      workqueues"
+    - Revert "workqueue: Introduce struct wq_node_nr_active"
+    - Revert "workqueue: RCU protect wq->dfl_pwq and implement accessors for it"
+    - Revert "workqueue: Make wq_adjust_max_active() round-robin pwqs while
+      activating"
+    - Revert "workqueue: Move nr_active handling into helpers"
+    - Revert "workqueue: Replace pwq_activate_inactive_work() with
+      [__]pwq_activate_work()"
+    - Revert "workqueue: Factor out pwq_is_empty()"
+    - Revert "workqueue: Move pwq->max_active to wq->max_active"
+    - Revert "workqueue.c: Increase workqueue name length"
+    - Linux 6.8.4
+  * Noble update: v6.8.3 upstream stable release (LP: #2060531)
+    - drm/vmwgfx: Unmap the surface before resetting it on a plane state
+    - wifi: brcmfmac: Fix use-after-free bug in brcmf_cfg80211_detach
+    - wifi: brcmfmac: avoid invalid list operation when vendor attach fails
+    - media: staging: ipu3-imgu: Set fields before media_entity_pads_init()
+    - arm64: dts: qcom: sc7280: Add additional MSI interrupts
+    - remoteproc: virtio: Fix wdg cannot recovery remote processor
+    - clk: qcom: gcc-sdm845: Add soft dependency on rpmhpd
+    - smack: Set SMACK64TRANSMUTE only for dirs in smack_inode_setxattr()
+    - smack: Handle SMACK64TRANSMUTE in smack_inode_setsecurity()
+    - arm: dts: marvell: Fix maxium->maxim typo in brownstone dts
+    - drm/vmwgfx: Fix possible null pointer derefence with invalid contexts
+    - arm64: dts: qcom: sm8450-hdk: correct AMIC4 and AMIC5 microphones
+    - serial: max310x: fix NULL pointer dereference in I2C instantiation
+    - drm/vmwgfx: Fix the lifetime of the bo cursor memory
+    - pci_iounmap(): Fix MMIO mapping leak
+    - media: xc4000: Fix atomicity violation in xc4000_get_frequency
+    - media: mc: Add local pad to pipeline regardless of the link state
+    - media: mc: Fix flags handling when creating pad links
+    - media: nxp: imx8-isi: Check whether crossbar pad is non-NULL before access
+    - media: mc: Add num_links flag to media_pad
+    - media: mc: Rename pad variable to clarify intent
+    - media: mc: Expand MUST_CONNECT flag to always require an enabled link
+    - media: nxp: imx8-isi: Mark all crossbar sink pads as MUST_CONNECT
+    - md: use RCU lock to protect traversal in md_spares_need_change()
+    - KVM: Always flush async #PF workqueue when vCPU is being destroyed
+    - arm64: dts: qcom: sm8550-qrd: correct WCD9385 TX port mapping
+    - arm64: dts: qcom: sm8550-mtp: correct WCD9385 TX port mapping
+    - cpufreq: amd-pstate: Fix min_perf assignment in amd_pstate_adjust_perf()
+    - thermal/intel: Fix intel_tcc_get_temp() to support negative CPU temperature
+    - powercap: intel_rapl: Fix a NULL pointer dereference
+    - powercap: intel_rapl: Fix locking in TPMI RAPL
+    - powercap: intel_rapl_tpmi: Fix a register bug
+    - powercap: intel_rapl_tpmi: Fix System Domain probing
+    - powerpc/smp: Adjust nr_cpu_ids to cover all threads of a core
+    - powerpc/smp: Increase nr_cpu_ids to include the boot CPU
+    - sparc64: NMI watchdog: fix return value of __setup handler
+    - sparc: vDSO: fix return value of __setup handler
+    - selftests/mqueue: Set timeout to 180 seconds
+    - pinctrl: qcom: sm8650-lpass-lpi: correct Kconfig name
+    - ext4: correct best extent lstart adjustment logic
+    - drm/amdgpu/display: Address kdoc for 'is_psr_su' in 'fill_dc_dirty_rects'
+    - block: Clear zone limits for a non-zoned stacked queue
+    - kasan/test: avoid gcc warning for intentional overflow
+    - bounds: support non-power-of-two CONFIG_NR_CPUS
+    - fat: fix uninitialized field in nostale filehandles
+    - fuse: fix VM_MAYSHARE and direct_io_allow_mmap
+    - mfd: twl: Select MFD_CORE
+    - ubifs: Set page uptodate in the correct place
+    - ubi: Check for too small LEB size in VTBL code
+    - ubi: correct the calculation of fastmap size
+    - ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path
+    - mtd: rawnand: meson: fix scrambling mode value in command macro
+    - md/md-bitmap: fix incorrect usage for sb_index
+    - x86/nmi: Fix the inverse "in NMI handler" check
+    - parisc/unaligned: Rewrite 64-bit inline assembly of emulate_ldd()
+    - parisc: Avoid clobbering the C/B bits in the PSW with tophys and tovirt
+      macros
+    - parisc: Fix ip_fast_csum
+    - parisc: Fix csum_ipv6_magic on 32-bit systems
+    - parisc: Fix csum_ipv6_magic on 64-bit systems
+    - parisc: Strip upper 32 bit of sum in csum_ipv6_magic for 64-bit builds
+    - md/raid5: fix atomicity violation in raid5_cache_count
+    - iio: adc: rockchip_saradc: fix bitmask for channels on SARADCv2
+    - iio: adc: rockchip_saradc: use mask for write_enable bitfield
+    - docs: Restore "smart quotes" for quotes
+    - cpufreq: Limit resolving a frequency to policy min/max
+    - PM: suspend: Set mem_sleep_current during kernel command line setup
+    - vfio/pds: Always clear the save/restore FDs on reset
+    - clk: qcom: gcc-ipq5018: fix terminating of frequency table arrays
+    - clk: qcom: gcc-ipq6018: fix terminating of frequency table arrays
+    - clk: qcom: gcc-ipq8074: fix terminating of frequency table arrays
+    - clk: qcom: gcc-ipq9574: fix terminating of frequency table arrays
+    - clk: qcom: camcc-sc8280xp: fix terminating of frequency table arrays
+    - clk: qcom: mmcc-apq8084: fix terminating of frequency table arrays
+    - clk: qcom: mmcc-msm8974: fix terminating of frequency table arrays
+    - usb: xhci: Add error handling in xhci_map_urb_for_dma
+    - powerpc/fsl: Fix mfpmr build errors with newer binutils
+    - USB: serial: ftdi_sio: add support for GMC Z216C Adapter IR-USB
+    - USB: serial: add device ID for VeriFone adapter
+    - USB: serial: cp210x: add ID for MGP Instruments PDS100
+    - wifi: mac80211: track capability/opmode NSS separately
+    - USB: serial: option: add MeiG Smart SLM320 product
+    - KVM: x86/xen: inject vCPU upcall vector when local APIC is enabled
+    - USB: serial: cp210x: add pid/vid for TDK NC0110013M and MM0110113M
+    - PM: sleep: wakeirq: fix wake irq warning in system suspend
+    - mmc: tmio: avoid concurrent runs of mmc_request_done()
+    - fuse: replace remaining make_bad_inode() with fuse_make_bad()
+    - fuse: fix root lookup with nonzero generation
+    - fuse: don't unhash root
+    - usb: typec: ucsi: Clean up UCSI_CABLE_PROP macros
+    - usb: dwc3-am62: fix module unload/reload behavior
+    - usb: dwc3-am62: Disable wakeup at remove
+    - serial: core: only stop transmit when HW fifo is empty
+    - serial: Lock console when calling into driver before registration
+    - btrfs: qgroup: always free reserved space for extent records
+    - btrfs: fix off-by-one chunk length calculation at contains_pending_extent()
+    - wifi: rtw88: Add missing VID/PIDs for 8811CU and 8821CU
+    - docs: Makefile: Add dependency to $(YNL_INDEX) for targets other than
+      htmldocs
+    - PCI/PM: Drain runtime-idle callbacks before driver removal
+    - PCI/DPC: Quirk PIO log size for Intel Raptor Lake Root Ports
+    - Revert "Revert "md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d""
+    - md: don't clear MD_RECOVERY_FROZEN for new dm-raid until resume
+    - md: export helpers to stop sync_thread
+    - md: export helper md_is_rdwr()
+    - md: add a new helper reshape_interrupted()
+    - dm-raid: really frozen sync_thread during suspend
+    - md/dm-raid: don't call md_reap_sync_thread() directly
+    - dm-raid: add a new helper prepare_suspend() in md_personality
+    - dm-raid456, md/raid456: fix a deadlock for dm-raid456 while io concurrent
+      with reshape
+    - dm-raid: fix lockdep waring in "pers->hot_add_disk"
+    - powerpc: xor_vmx: Add '-mhard-float' to CFLAGS
+    - mac802154: fix llsec key resources release in mac802154_llsec_key_del
+    - mm: swap: fix race between free_swap_and_cache() and swapoff()
+    - mmc: core: Fix switch on gp3 partition
+    - Bluetooth: btnxpuart: Fix btnxpuart_close
+    - leds: trigger: netdev: Fix kernel panic on interface rename trig notify
+    - drm/etnaviv: Restore some id values
+    - landlock: Warn once if a Landlock action is requested while disabled
+    - io_uring: fix mshot read defer taskrun cqe posting
+    - hwmon: (amc6821) add of_match table
+    - io_uring: fix io_queue_proc modifying req->flags
+    - ext4: fix corruption during on-line resize
+    - nvmem: meson-efuse: fix function pointer type mismatch
+    - slimbus: core: Remove usage of the deprecated ida_simple_xx() API
+    - phy: tegra: xusb: Add API to retrieve the port number of phy
+    - usb: gadget: tegra-xudc: Fix USB3 PHY retrieval logic
+    - speakup: Fix 8bit characters from direct synth
+    - debugfs: fix wait/cancellation handling during remove
+    - PCI/AER: Block runtime suspend when handling errors
+    - io_uring/net: correctly handle multishot recvmsg retry setup
+    - io_uring: fix mshot io-wq checks
+    - PCI: qcom: Disable ASPM L0s for sc8280xp, sa8540p and sa8295p
+    - sparc32: Fix parport build with sparc32
+    - nfs: fix UAF in direct writes
+    - NFS: Read unlock folio on nfs_page_create_from_folio() error
+    - kbuild: Move -Wenum-{compare-conditional,enum-conversion} into W=1
+    - PCI: qcom: Enable BDF to SID translation properly
+    - PCI: dwc: endpoint: Fix advertised resizable BAR size
+    - PCI: hv: Fix ring buffer size calculation
+    - cifs: prevent updating file size from server if we have a read/write lease
+    - cifs: allow changing password during remount
+    - thermal/drivers/mediatek: Fix control buffer enablement on MT7896
+    - vfio/pci: Disable auto-enable of exclusive INTx IRQ
+    - vfio/pci: Lock external INTx masking ops
+    - vfio/platform: Disable virqfds on cleanup
+    - vfio/platform: Create persistent IRQ handlers
+    - vfio/fsl-mc: Block calling interrupt handler without trigger
+    - tpm,tpm_tis: Avoid warning splat at shutdown
+    - ksmbd: replace generic_fillattr with vfs_getattr
+    - ksmbd: retrieve number of blocks using vfs_getattr in
+      set_file_allocation_info
+    - platform/x86/intel/tpmi: Change vsec offset to u64
+    - io_uring/rw: return IOU_ISSUE_SKIP_COMPLETE for multishot retry
+    - io_uring: clean rings on NO_MMAP alloc fail
+    - ring-buffer: Do not set shortest_full when full target is hit
+    - ring-buffer: Fix full_waiters_pending in poll
+    - ring-buffer: Use wait_event_interruptible() in ring_buffer_wait()
+    - tracing/ring-buffer: Fix wait_on_pipe() race
+    - dlm: fix user space lkb refcounting
+    - soc: fsl: qbman: Always disable interrupts when taking cgr_lock
+    - soc: fsl: qbman: Use raw spinlock for cgr_lock
+    - s390/zcrypt: fix reference counting on zcrypt card objects
+    - drm/probe-helper: warn about negative .get_modes()
+    - drm/panel: do not return negative error codes from drm_panel_get_modes()
+    - drm/exynos: do not return negative values from .get_modes()
+    - drm/imx/ipuv3: do not return negative values from .get_modes()
+    - drm/vc4: hdmi: do not return negative values from .get_modes()
+    - clocksource/drivers/timer-riscv: Clear timer interrupt on timer
+      initialization
+    - memtest: use {READ,WRITE}_ONCE in memory scanning
+    - Revert "block/mq-deadline: use correct way to throttling write requests"
+    - lsm: use 32-bit compatible data types in LSM syscalls
+    - lsm: handle the NULL buffer case in lsm_fill_user_ctx()
+    - f2fs: mark inode dirty for FI_ATOMIC_COMMITTED flag
+    - f2fs: truncate page cache before clearing flags when aborting atomic write
+    - nilfs2: fix failure to detect DAT corruption in btree and direct mappings
+    - nilfs2: prevent kernel bug at submit_bh_wbc()
+    - cifs: make sure server interfaces are requested only for SMB3+
+    - cifs: reduce warning log level for server not advertising interfaces
+    - cifs: open_cached_dir(): add FILE_READ_EA to desired access
+    - mtd: rawnand: Fix and simplify again the continuous read derivations
+    - mtd: rawnand: Add a helper for calculating a page index
+    - mtd: rawnand: Ensure all continuous terms are always in sync
+    - mtd: rawnand: Constrain even more when continuous reads are enabled
+    - cpufreq: dt: always allocate zeroed cpumask
+    - io_uring/futex: always remove futex entry for cancel all
+    - io_uring/waitid: always remove waitid entry for cancel all
+    - x86/CPU/AMD: Update the Zenbleed microcode revisions
+    - ksmbd: fix slab-out-of-bounds in smb_strndup_from_utf16()
+    - net: esp: fix bad handling of pages from page_pool
+    - NFSD: Fix nfsd_clid_class use of __string_len() macro
+    - drm/i915: Add missing ; to __assign_str() macros in tracepoint code
+    - net: hns3: tracing: fix hclgevf trace event strings
+    - cxl/trace: Properly initialize cxl_poison region name
+    - ksmbd: fix potencial out-of-bounds when buffer offset is invalid
+    - virtio: reenable config if freezing device failed
+    - LoongArch: Change __my_cpu_offset definition to avoid mis-optimization
+    - LoongArch: Define the __io_aw() hook as mmiowb()
+    - LoongArch/crypto: Clean up useless assignment operations
+    - wireguard: netlink: check for dangling peer via is_dead instead of empty
+      list
+    - wireguard: netlink: access device through ctx instead of peer
+    - wireguard: selftests: set RISCV_ISA_FALLBACK on riscv{32,64}
+    - ahci: asm1064: asm1166: don't limit reported ports
+    - drm/amd/display: Change default size for dummy plane in DML2
+    - drm/amdgpu: amdgpu_ttm_gart_bind set gtt bound flag
+    - drm/amdgpu/pm: Fix NULL pointer dereference when get power limit
+    - drm/amdgpu/pm: Check the validity of overdiver power limit
+    - drm/amd/display: Override min required DCFCLK in dml1_validate
+    - drm/amd/display: Allow dirty rects to be sent to dmub when abm is active
+    - drm/amd/display: Init DPPCLK from SMU on dcn32
+    - drm/amd/display: Update odm when ODM combine is changed on an otg master
+      pipe with no plane
+    - drm/amd/display: Fix idle check for shared firmware state
+    - drm/amd/display: Amend coasting vtotal for replay low hz
+    - drm/amd/display: Lock all enabled otg pipes even with no planes
+    - drm/amd/display: Implement wait_for_odm_update_pending_complete
+    - drm/amd/display: Return the correct HDCP error code
+    - drm/amd/display: Add a dc_state NULL check in dc_state_release
+    - drm/amd/display: Fix noise issue on HDMI AV mute
+    - dm snapshot: fix lockup in dm_exception_table_exit
+    - x86/pm: Work around false positive kmemleak report in msr_build_context()
+    - wifi: brcmfmac: add per-vendor feature detection callback
+    - wifi: brcmfmac: cfg80211: Use WSEC to set SAE password
+    - wifi: brcmfmac: Demote vendor-specific attach/detach messages to info
+    - drm/ttm: Make sure the mapped tt pages are decrypted when needed
+    - drm/amd/display: Unify optimize_required flags and VRR adjustments
+    - drm/amd/display: Add more checks for exiting idle in DC
+    - btrfs: add set_folio_extent_mapped() helper
+    - btrfs: replace sb::s_blocksize by fs_info::sectorsize
+    - btrfs: add helpers to get inode from page/folio pointers
+    - btrfs: add helpers to get fs_info from page/folio pointers
+    - btrfs: add helper to get fs_info from struct inode pointer
+    - btrfs: qgroup: validate btrfs_qgroup_inherit parameter
+    - vfio: Introduce interface to flush virqfd inject workqueue
+    - vfio/pci: Create persistent INTx handler
+    - drm/bridge: add ->edid_read hook and drm_bridge_edid_read()
+    - drm/bridge: lt8912b: use drm_bridge_edid_read()
+    - drm/bridge: lt8912b: clear the EDID property on failures
+    - drm/bridge: lt8912b: do not return negative values from .get_modes()
+    - drm/amd/display: Remove pixle rate limit for subvp
+    - drm/amd/display: Revert Remove pixle rate limit for subvp
+    - workqueue: Shorten events_freezable_power_efficient name
+    - drm/amd/display: Use freesync when `DRM_EDID_FEATURE_CONTINUOUS_FREQ` found
+    - netfilter: nf_tables: reject constant set with timeout
+    - Revert "crypto: pkcs7 - remove sha1 support"
+    - x86/efistub: Call mixed mode boot services on the firmware's stack
+    - ASoC: amd: yc: Revert "Fix non-functional mic on Lenovo 21J2"
+    - ASoC: amd: yc: Revert "add new YC platform variant (0x63) support"
+    - Fix memory leak in posix_clock_open()
+    - wifi: rtw88: 8821cu: Fix connection failure
+    - x86/Kconfig: Remove CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT
+    - x86/sev: Fix position dependent variable references in startup code
+    - clocksource/drivers/arm_global_timer: Fix maximum prescaler value
+    - ARM: 9352/1: iwmmxt: Remove support for PJ4/PJ4B cores
+    - ARM: 9359/1: flush: check if the folio is reserved for no-mapping addresses
+    - entry: Respect changes to system call number by trace_sys_enter()
+    - swiotlb: Fix double-allocation of slots due to broken alignment handling
+    - swiotlb: Honour dma_alloc_coherent() alignment in swiotlb_alloc()
+    - swiotlb: Fix alignment checks when both allocation and DMA masks are present
+    - iommu/dma: Force swiotlb_max_mapping_size on an untrusted device
+    - printk: Update @console_may_schedule in console_trylock_spinning()
+    - irqchip/renesas-rzg2l: Flush posted write in irq_eoi()
+    - irqchip/renesas-rzg2l: Rename rzg2l_tint_eoi()
+    - irqchip/renesas-rzg2l: Rename rzg2l_irq_eoi()
+    - irqchip/renesas-rzg2l: Prevent spurious interrupts when setting trigger type
+    - kprobes/x86: Use copy_from_kernel_nofault() to read from unsafe address
+    - efi/libstub: fix efi_random_alloc() to allocate memory at alloc_min or
+      higher address
+    - x86/mpparse: Register APIC address only once
+    - x86/fpu: Keep xfd_state in sync with MSR_IA32_XFD
+    - efi: fix panic in kdump kernel
+    - pwm: img: fix pwm clock lookup
+    - selftests/mm: Fix build with _FORTIFY_SOURCE
+    - btrfs: handle errors returned from unpin_extent_cache()
+    - btrfs: fix warning messages not printing interval at unpin_extent_range()
+    - btrfs: do not skip re-registration for the mounted device
+    - mfd: intel-lpss: Switch to generalized quirk table
+    - mfd: intel-lpss: Introduce QUIRK_CLOCK_DIVIDER_UNITY for XPS 9530
+    - drm/i915: Replace a memset() with zero initialization
+    - drm/i915: Try to preserve the current shared_dpll for fastset on type-c
+      ports
+    - drm/i915: Include the PLL name in the debug messages
+    - drm/i915: Suppress old PLL pipe_mask checks for MG/TC/TBT PLLs
+    - crypto: iaa - Fix nr_cpus < nr_iaa case
+    - drm/amd/display: Prevent crash when disable stream
+    - ALSA: hda/tas2781: remove digital gain kcontrol
+    - ALSA: hda/tas2781: add locks to kcontrols
+    - mm: zswap: fix writeback shinker GFP_NOIO/GFP_NOFS recursion
+    - init: open /initrd.image with O_LARGEFILE
+    - x86/efistub: Add missing boot_params for mixed mode compat entry
+    - efi/libstub: Cast away type warning in use of max()
+    - x86/efistub: Reinstate soft limit for initrd loading
+    - prctl: generalize PR_SET_MDWE support check to be per-arch
+    - ARM: prctl: reject PR_SET_MDWE on pre-ARMv6
+    - tmpfs: fix race on handling dquot rbtree
+    - btrfs: validate device maj:min during open
+    - btrfs: fix race in read_extent_buffer_pages()
+    - btrfs: zoned: don't skip block groups with 100% zone unusable
+    - btrfs: zoned: use zone aware sb location for scrub
+    - btrfs: zoned: fix use-after-free in do_zone_finish()
+    - wifi: mac80211: check/clear fast rx for non-4addr sta VLAN changes
+    - wifi: cfg80211: add a flag to disable wireless extensions
+    - wifi: iwlwifi: mvm: disable MLO for the time being
+    - wifi: iwlwifi: fw: don't always use FW dump trig
+    - wifi: iwlwifi: mvm: handle debugfs names more carefully
+    - Revert "drm/amd/display: Fix sending VSC (+ colorimetry) packets for DP/eDP
+      displays without PSR"
+    - fbdev: Select I/O-memory framebuffer ops for SBus
+    - exec: Fix NOMMU linux_binprm::exec in transfer_args_to_stack()
+    - hexagon: vmlinux.lds.S: handle attributes section
+    - mm: cachestat: fix two shmem bugs
+    - selftests/mm: sigbus-wp test requires UFFD_FEATURE_WP_HUGETLBFS_SHMEM
+    - selftests/mm: fix ARM related issue with fork after pthread_create
+    - mmc: sdhci-omap: re-tuning is needed after a pm transition to support emmc
+      HS200 mode
+    - mmc: core: Initialize mmc_blk_ioc_data
+    - mmc: core: Avoid negative index with array access
+    - sdhci-of-dwcmshc: disable PM runtime in dwcmshc_remove()
+    - block: Do not force full zone append completion in req_bio_endio()
+    - thermal: devfreq_cooling: Fix perf state when calculate dfc res_util
+    - Revert "thermal: core: Don't update trip points inside the hysteresis range"
+    - nouveau/dmem: handle kcalloc() allocation failure
+    - net: ll_temac: platform_get_resource replaced by wrong function
+    - net: wan: framer: Add missing static inline qualifiers
+    - net: phy: qcom: at803x: fix kernel panic with at8031_probe
+    - drm/xe/query: fix gt_id bounds check
+    - drm/dp: Fix divide-by-zero regression on DP MST unplug with nouveau
+    - drm/vmwgfx: Create debugfs ttm_resource_manager entry only if needed
+    - drm/amdkfd: fix TLB flush after unmap for GFX9.4.2
+    - drm/amdgpu: fix deadlock while reading mqd from debugfs
+    - drm/amd/display: Remove MPC rate control logic from DCN30 and above
+    - drm/amd/display: Set DCN351 BB and IP the same as DCN35
+    - drm/i915/hwmon: Fix locking inversion in sysfs getter
+    - drm/i915/vma: Fix UAF on destroy against retire race
+    - drm/i915/bios: Tolerate devdata==NULL in
+      intel_bios_encoder_supports_dp_dual_mode()
+    - drm/i915/vrr: Generate VRR "safe window" for DSB
+    - drm/i915/dsi: Go back to the previous INIT_OTP/DISPLAY_ON order, mostly
+    - drm/i915/dsb: Fix DSB vblank waits when using VRR
+    - drm/i915: Do not match JSL in ehl_combo_pll_div_frac_wa_needed()
+    - drm/i915: Pre-populate the cursor physical dma address
+    - drm/i915/gt: Reset queue_priority_hint on parking
+    - drm/amd/display: Fix bounds check for dcn35 DcfClocks
+    - Bluetooth: hci_sync: Fix not checking error on hci_cmd_sync_cancel_sync
+    - mtd: spinand: Add support for 5-byte IDs
+    - Revert "usb: phy: generic: Get the vbus supply"
+    - usb: cdc-wdm: close race between read and workqueue
+    - usb: misc: ljca: Fix double free in error handling path
+    - USB: UAS: return ENODEV when submit urbs fail with device not attached
+    - vfio/pds: Make sure migration file isn't accessed after reset
+    - ring-buffer: Make wake once of ring_buffer_wait() more robust
+    - btrfs: fix extent map leak in unexpected scenario at unpin_extent_cache()
+    - ALSA: sh: aica: reorder cleanup operations to avoid UAF bugs
+    - scsi: ufs: qcom: Provide default cycles_in_1us value
+    - scsi: sd: Fix TCG OPAL unlock on system resume
+    - scsi: core: Fix unremoved procfs host directory regression
+    - staging: vc04_services: changen strncpy() to strscpy_pad()
+    - staging: vc04_services: fix information leak in create_component()
+    - genirq: Introduce IRQF_COND_ONESHOT and use it in pinctrl-amd
+    - usb: dwc3: Properly set system wakeup
+    - USB: core: Fix deadlock in usb_deauthorize_interface()
+    - USB: core: Add hub_get() and hub_put() routines
+    - USB: core: Fix deadlock in port "disable" sysfs attribute
+    - usb: dwc2: host: Fix remote wakeup from hibernation
+    - usb: dwc2: host: Fix hibernation flow
+    - usb: dwc2: host: Fix ISOC flow in DDMA mode
+    - usb: dwc2: gadget: Fix exiting from clock gating
+    - usb: dwc2: gadget: LPM flow fix
+    - usb: udc: remove warning when queue disabled ep
+    - usb: typec: ucsi: Fix race between typec_switch and role_switch
+    - usb: typec: tcpm: fix double-free issue in tcpm_port_unregister_pd()
+    - usb: typec: tcpm: Correct port source pdo array in pd_set callback
+    - usb: typec: tcpm: Update PD of Type-C port upon pd_set
+    - usb: typec: Return size of buffer if pd_set operation succeeds
+    - usb: typec: ucsi: Clear EVENT_PENDING under PPM lock
+    - usb: typec: ucsi: Ack unsupported commands
+    - usb: typec: ucsi_acpi: Refactor and fix DELL quirk
+    - usb: typec: ucsi: Clear UCSI_CCI_RESET_COMPLETE before reset
+    - scsi: qla2xxx: Prevent command send on chip reset
+    - scsi: qla2xxx: Fix N2N stuck connection
+    - scsi: qla2xxx: Split FCE|EFT trace control
+    - scsi: qla2xxx: Update manufacturer detail
+    - scsi: qla2xxx: NVME|FCP prefer flag not being honored
+    - scsi: qla2xxx: Fix command flush on cable pull
+    - scsi: qla2xxx: Fix double free of the ha->vp_map pointer
+    - scsi: qla2xxx: Fix double free of fcport
+    - scsi: qla2xxx: Change debug message during driver unload
+    - scsi: qla2xxx: Delay I/O Abort on PCI error
+    - x86/bugs: Fix the SRSO mitigation on Zen3/4
+    - crash: use macro to add crashk_res into iomem early for specific arch
+    - drm/amd/display: fix IPX enablement
+    - x86/bugs: Use fixed addressing for VERW operand
+    - Revert "x86/bugs: Use fixed addressing for VERW operand"
+    - usb: dwc3: pci: Drop duplicate ID
+    - scsi: lpfc: Correct size for cmdwqe/rspwqe for memset()
+    - scsi: lpfc: Correct size for wqe for memset()
+    - scsi: libsas: Add a helper sas_get_sas_addr_and_dev_type()
+    - scsi: libsas: Fix disk not being scanned in after being removed
+    - perf/x86/amd/core: Update and fix stalled-cycles-* events for Zen 2 and
+      later
+    - x86/sev: Skip ROM range scans and validation for SEV-SNP guests
+    - tools/resolve_btfids: fix build with musl libc
+    - drm/amdgpu: fix use-after-free bug
+    - drm/sched: fix null-ptr-deref in init entity
+    - Linux 6.8.3
+    - [Config] updateconfigs following v6.8.3 import
+  * Noble update: v6.8.3 upstream stable release (LP: #2060531) //
+    [Ubuntu-24.04] Hugepage memory is not getting released even after destroying
+    the guest! (LP: #2062556)
+    - block: Fix page refcounts for unaligned buffers in __bio_release_pages()
+  *  [SPR][EMR][GNR] TDX: efi: TD Measurement support for kernel cmdline/initrd
+    sections from EFI stub  (LP: #2060130)
+    - efi/libstub: Use TPM event typedefs from the TCG PC Client spec
+    - efi/tpm: Use symbolic GUID name from spec for final events table
+    - efi/libstub: Add Confidential Computing (CC) measurement typedefs
+    - efi/libstub: Measure into CC protocol if TCG2 protocol is absent
+    - efi/libstub: Add get_event_log() support for CC platforms
+    - x86/efistub: Remap kernel text read-only before dropping NX attribute
+  * Fix acpi_power_meter accessing IPMI region before it's ready (LP: #2059263)
+    - ACPI: IPMI: Add helper to wait for when SMI is selected
+    - hwmon: (acpi_power_meter) Ensure IPMI space handler is ready on Dell systems
+  * Drop fips-checks script from trees (LP: #2055083)
+    - [Packaging] Remove fips-checks script
+  * alsa/realtek: adjust max output valume for headphone on 2 LG machines
+    (LP: #2058573)
+    - ALSA: hda/realtek: fix the hp playback volume issue for LG machines
+  * Noble update: v6.8.2 upstream stable release (LP: #2060097)
+    - do_sys_name_to_handle(): use kzalloc() to fix kernel-infoleak
+    - workqueue.c: Increase workqueue name length
+    - workqueue: Move pwq->max_active to wq->max_active
+    - workqueue: Factor out pwq_is_empty()
+    - workqueue: Replace pwq_activate_inactive_work() with [__]pwq_activate_work()
+    - workqueue: Move nr_active handling into helpers
+    - workqueue: Make wq_adjust_max_active() round-robin pwqs while activating
+    - workqueue: RCU protect wq->dfl_pwq and implement accessors for it
+    - workqueue: Introduce struct wq_node_nr_active
+    - workqueue: Implement system-wide nr_active enforcement for unbound
+      workqueues
+    - workqueue: Don't call cpumask_test_cpu() with -1 CPU in
+      wq_update_node_max_active()
+    - iomap: clear the per-folio dirty bits on all writeback failures
+    - fs: Fix rw_hint validation
+    - io_uring: remove looping around handling traditional task_work
+    - io_uring: remove unconditional looping in local task_work handling
+    - s390/dasd: Use dev_*() for device log messages
+    - s390/dasd: fix double module refcount decrement
+    - fs/hfsplus: use better @opf description
+    - md: fix kmemleak of rdev->serial
+    - rcu/exp: Fix RCU expedited parallel grace period kworker allocation failure
+      recovery
+    - rcu/exp: Handle RCU expedited grace period kworker allocation failure
+    - fs/select: rework stack allocation hack for clang
+    - block: fix deadlock between bd_link_disk_holder and partition scan
+    - md: Don't clear MD_CLOSING when the raid is about to stop
+    - kunit: Setup DMA masks on the kunit device
+    - ovl: Always reject mounting over case-insensitive directories
+    - kunit: test: Log the correct filter string in executor_test
+    - lib/cmdline: Fix an invalid format specifier in an assertion msg
+    - lib: memcpy_kunit: Fix an invalid format specifier in an assertion msg
+    - time: test: Fix incorrect format specifier
+    - rtc: test: Fix invalid format specifier.
+    - net: test: Fix printf format specifier in skb_segment kunit test
+    - drm/xe/tests: Fix printf format specifiers in xe_migrate test
+    - drm: tests: Fix invalid printf format specifiers in KUnit tests
+    - md/raid1: factor out helpers to add rdev to conf
+    - md/raid1: record nonrot rdevs while adding/removing rdevs to conf
+    - md/raid1: fix choose next idle in read_balance()
+    - io_uring/net: unify how recvmsg and sendmsg copy in the msghdr
+    - io_uring/net: move receive multishot out of the generic msghdr path
+    - io_uring/net: fix overflow check in io_recvmsg_mshot_prep()
+    - nvme: host: fix double-free of struct nvme_id_ns in ns_update_nuse()
+    - aoe: fix the potential use-after-free problem in aoecmd_cfg_pkts
+    - x86/mm: Ensure input to pfn_to_kaddr() is treated as a 64-bit type
+    - x86/resctrl: Remove hard-coded memory bandwidth limit
+    - x86/resctrl: Read supported bandwidth sources from CPUID
+    - x86/resctrl: Implement new mba_MBps throttling heuristic
+    - x86/sme: Fix memory encryption setting if enabled by default and not
+      overridden
+    - timekeeping: Fix cross-timestamp interpolation on counter wrap
+    - timekeeping: Fix cross-timestamp interpolation corner case decision
+    - timekeeping: Fix cross-timestamp interpolation for non-x86
+    - x86/asm: Remove the __iomem annotation of movdir64b()'s dst argument
+    - sched/fair: Take the scheduling domain into account in select_idle_smt()
+    - sched/fair: Take the scheduling domain into account in select_idle_core()
+    - wifi: ath10k: fix NULL pointer dereference in
+      ath10k_wmi_tlv_op_pull_mgmt_tx_compl_ev()
+    - wifi: b43: Stop/wake correct queue in DMA Tx path when QoS is disabled
+    - wifi: b43: Stop/wake correct queue in PIO Tx path when QoS is disabled
+    - wifi: b43: Stop correct queue in DMA worker when QoS is disabled
+    - wifi: b43: Disable QoS for bcm4331
+    - wifi: wilc1000: fix declarations ordering
+    - wifi: wilc1000: fix RCU usage in connect path
+    - wifi: ath11k: add support to select 6 GHz regulatory type
+    - wifi: ath11k: store cur_regulatory_info for each radio
+    - wifi: ath11k: fix a possible dead lock caused by ab->base_lock
+    - wifi: rtl8xxxu: add cancel_work_sync() for c2hcmd_work
+    - wifi: wilc1000: do not realloc workqueue everytime an interface is added
+    - wifi: wilc1000: fix multi-vif management when deleting a vif
+    - wifi: mwifiex: debugfs: Drop unnecessary error check for
+      debugfs_create_dir()
+    - ARM: dts: renesas: r8a73a4: Fix external clocks and clock rate
+    - arm64: dts: qcom: x1e80100: drop qcom,drv-count
+    - arm64: dts: qcom: sc8180x: Hook up VDD_CX as GCC parent domain
+    - arm64: dts: qcom: sc8180x: Fix up big CPU idle state entry latency
+    - arm64: dts: qcom: sc8180x: Add missing CPU off state
+    - arm64: dts: qcom: sc8180x: Fix eDP PHY power-domains
+    - arm64: dts: qcom: sc8180x: Don't hold MDP core clock at FMAX
+    - arm64: dts: qcom: sc8180x: Require LOW_SVS vote for MMCX if DISPCC is on
+    - arm64: dts: qcom: sc8180x: Add missing CPU<->MDP_CFG path
+    - arm64: dts: qcom: sc8180x: Shrink aoss_qmp register space size
+    - cpufreq: brcmstb-avs-cpufreq: add check for cpufreq_cpu_get's return value
+    - cpufreq: mediatek-hw: Wait for CPU supplies before probing
+    - sock_diag: annotate data-races around sock_diag_handlers[family]
+    - inet_diag: annotate data-races around inet_diag_table[]
+    - bpftool: Silence build warning about calloc()
+    - selftests/bpf: Fix potential premature unload in bpf_testmod
+    - libbpf: Apply map_set_def_max_entries() for inner_maps on creation
+    - selftest/bpf: Add map_in_maps with BPF_MAP_TYPE_PERF_EVENT_ARRAY values
+    - bpftool: Fix wrong free call in do_show_link
+    - wifi: ath12k: Fix issues in channel list update
+    - selftests/bpf: Fix the flaky tc_redirect_dtime test
+    - selftests/bpf: Wait for the netstamp_needed_key static key to be turned on
+    - wifi: cfg80211: add RNR with reporting AP information
+    - wifi: mac80211: use deflink and fix typo in link ID check
+    - wifi: iwlwifi: change link id in time event to s8
+    - af_unix: Annotate data-race of gc_in_progress in wait_for_unix_gc().
+    - arm64: dts: qcom: sm8450: Add missing interconnects to serial
+    - soc: qcom: socinfo: rename PM2250 to PM4125
+    - arm64: dts: qcom: sc7280: Add static properties to cryptobam
+    - arm64: dts: qcom: qcm6490-fairphone-fp5: Add missing reserved-memory
+    - arm64: dts: qcom: sdm845-oneplus-common: improve DAI node naming
+    - arm64: dts: qcom: rename PM2250 to PM4125
+    - cpufreq: mediatek-hw: Don't error out if supply is not found
+    - libbpf: Fix faccessat() usage on Android
+    - libbpf: fix __arg_ctx type enforcement for perf_event programs
+    - pmdomain: qcom: rpmhpd: Drop SA8540P gfx.lvl
+    - arm64: dts: qcom: sa8540p: Drop gfx.lvl as power-domain for gpucc
+    - arm64: dts: renesas: r8a779g0: Restore sort order
+    - arm64: dts: renesas: r8a779g0: Add missing SCIF_CLK2
+    - selftests/bpf: Disable IPv6 for lwt_redirect test
+    - arm64: dts: imx8mm-kontron: Disable pullups for I2C signals on OSM-S i.MX8MM
+    - arm64: dts: imx8mm-kontron: Disable pullups for I2C signals on SL/BL i.MX8MM
+    - arm64: dts: imx8mm-kontron: Disable pullups for onboard UART signals on BL
+      OSM-S board
+    - arm64: dts: imx8mm-kontron: Disable pullups for onboard UART signals on BL
+      board
+    - arm64: dts: imx8mm-kontron: Disable pull resistors for SD card signals on BL
+      OSM-S board
+    - arm64: dts: imx8mm-kontron: Disable pull resistors for SD card signals on BL
+      board
+    - arm64: dts: imx8mm-kontron: Fix interrupt for RTC on OSM-S i.MX8MM module
+    - arm64: dts: imx8qm: Align edma3 power-domains resources indentation
+    - arm64: dts: imx8qm: Correct edma3 power-domains and interrupt numbers
+    - libbpf: Add missing LIBBPF_API annotation to libbpf_set_memlock_rlim API
+    - wifi: ath9k: delay all of ath9k_wmi_event_tasklet() until init is complete
+    - wifi: ath11k: change to move WMI_VDEV_PARAM_SET_HEMU_MODE before
+      WMI_PEER_ASSOC_CMDID
+    - wifi: ath12k: fix fetching MCBC flag for QCN9274
+    - wifi: iwlwifi: mvm: report beacon protection failures
+    - wifi: iwlwifi: dbg-tlv: ensure NUL termination
+    - wifi: iwlwifi: acpi: fix WPFC reading
+    - wifi: iwlwifi: mvm: initialize rates in FW earlier
+    - wifi: iwlwifi: fix EWRD table validity check
+    - wifi: iwlwifi: mvm: d3: fix IPN byte order
+    - wifi: iwlwifi: always have 'uats_enabled'
+    - wifi: iwlwifi: mvm: fix the TLC command after ADD_STA
+    - wifi: iwlwifi: read BIOS PNVM only for non-Intel SKU
+    - gpio: vf610: allow disabling the vf610 driver
+    - selftests/bpf: trace_helpers.c: do not use poisoned type
+    - bpf: make sure scalar args don't accept __arg_nonnull tag
+    - bpf: don't emit warnings intended for global subprogs for static subprogs
+    - arm64: dts: imx8mm-venice-gw71xx: fix USB OTG VBUS
+    - pwm: atmel-hlcdc: Fix clock imbalance related to suspend support
+    - net: blackhole_dev: fix build warning for ethh set but not used
+    - spi: consolidate setting message->spi
+    - spi: move split xfers for CS_WORD emulation
+    - arm64: dts: ti: k3-am62p5-sk: Enable CPSW MDIO node
+    - arm64: dts: ti: k3-j721s2: Fix power domain for VTM node
+    - arm64: dts: ti: k3-j784s4: Fix power domain for VTM node
+    - wifi: ath11k: initialize rx_mcs_80 and rx_mcs_160 before use
+    - wifi: libertas: fix some memleaks in lbs_allocate_cmd_buffer()
+    - arm64: dts: ti: k3-am69-sk: remove assigned-clock-parents for unused VP
+    - libbpf: fix return value for PERF_EVENT __arg_ctx type fix up check
+    - arm64: dts: ti: k3-am62p-mcu/wakeup: Disable MCU and wakeup R5FSS nodes
+    - arm64: dts: qcom: x1e80100-qcp: Fix supplies for LDOs 3E and 2J
+    - libbpf: Use OPTS_SET() macro in bpf_xdp_query()
+    - wifi: wfx: fix memory leak when starting AP
+    - arm64: dts: qcom: qcm2290: declare VLS CLAMP register for USB3 PHY
+    - arm64: dts: qcom: sm6115: declare VLS CLAMP register for USB3 PHY
+    - arm64: dts: qcom: sm8650: Fix UFS PHY clocks
+    - wifi: ath12k: fix incorrect logic of calculating vdev_stats_id
+    - printk: nbcon: Relocate 32bit seq macros
+    - printk: ringbuffer: Do not skip non-finalized records with prb_next_seq()
+    - printk: Wait for all reserved records with pr_flush()
+    - printk: Add this_cpu_in_panic()
+    - printk: ringbuffer: Cleanup reader terminology
+    - printk: ringbuffer: Skip non-finalized records in panic
+    - printk: Disable passing console lock owner completely during panic()
+    - pwm: sti: Fix capture for st,pwm-num-chan < st,capture-num-chan
+    - tools/resolve_btfids: Refactor set sorting with types from btf_ids.h
+    - tools/resolve_btfids: Fix cross-compilation to non-host endianness
+    - wifi: iwlwifi: support EHT for WH
+    - wifi: iwlwifi: properly check if link is active
+    - wifi: iwlwifi: mvm: fix erroneous queue index mask
+    - wifi: iwlwifi: mvm: don't set the MFP flag for the GTK
+    - wifi: iwlwifi: mvm: don't set replay counters to 0xff
+    - s390/pai: fix attr_event_free upper limit for pai device drivers
+    - s390/vdso: drop '-fPIC' from LDFLAGS
+    - arm64: dts: qcom: qcm6490-idp: Correct the voltage setting for vph_pwr
+    - arm64: dts: qcom: qcs6490-rb3gen2: Correct the voltage setting for vph_pwr
+    - selftests: forwarding: Add missing config entries
+    - selftests: forwarding: Add missing multicast routing config entries
+    - arm64: dts: qcom: sm6115: drop pipe clock selection
+    - ipv6: mcast: remove one synchronize_net() barrier in ipv6_mc_down()
+    - arm64: dts: mt8183: Move CrosEC base detection node to kukui-based DTs
+    - arm64: dts: mediatek: mt7986: fix reference to PWM in fan node
+    - arm64: dts: mediatek: mt7986: drop crypto's unneeded/invalid clock name
+    - arm64: dts: mediatek: mt7986: fix SPI bus width properties
+    - arm64: dts: mediatek: mt7986: fix SPI nodename
+    - arm64: dts: mediatek: mt7986: drop "#clock-cells" from PWM
+    - arm64: dts: mediatek: mt7986: add "#reset-cells" to infracfg
+    - arm64: dts: mediatek: mt8192-asurada: Remove CrosEC base detection node
+    - arm64: dts: mediatek: mt8192: fix vencoder clock name
+    - arm64: dts: mediatek: mt8186: fix VENC power domain clocks
+    - arm64: dts: mediatek: mt7622: add missing "device_type" to memory nodes
+    - can: m_can: Start/Cancel polling timer together with interrupts
+    - wifi: iwlwifi: mvm: Fix the listener MAC filter flags
+    - bpf: Mark bpf_spin_{lock,unlock}() helpers with notrace correctly
+    - arm64: dts: qcom: sdm845: Use the Low Power Island CX/MX for SLPI
+    - soc: qcom: llcc: Check return value on Broadcast_OR reg read
+    - ARM: dts: qcom: msm8974: correct qfprom node size
+    - arm64: dts: mediatek: mt8186: Add missing clocks to ssusb power domains
+    - arm64: dts: mediatek: mt8186: Add missing xhci clock to usb controllers
+    - arm64: dts: ti: am65x: Fix dtbs_install for Rocktech OLDI overlay
+    - cpufreq: qcom-hw: add CONFIG_COMMON_CLK dependency
+    - wifi: wilc1000: prevent use-after-free on vif when cleaning up all
+      interfaces
+    - pwm: dwc: use pm_sleep_ptr() macro
+    - arm64: dts: ti: k3-am69-sk: fix PMIC interrupt number
+    - arm64: dts: ti: k3-j721e-sk: fix PMIC interrupt number
+    - arm64: dts: ti: k3-am62-main: disable usb lpm
+    - ACPI: processor_idle: Fix memory leak in acpi_processor_power_exit()
+    - bus: tegra-aconnect: Update dependency to ARCH_TEGRA
+    - iommu/amd: Mark interrupt as managed
+    - wifi: brcmsmac: avoid function pointer casts
+    - arm64: dts: qcom: sdm845-db845c: correct PCIe wake-gpios
+    - arm64: dts: qcom: sm8150: correct PCIe wake-gpios
+    - powercap: dtpm_cpu: Fix error check against freq_qos_add_request()
+    - net: ena: Remove ena_select_queue
+    - arm64: dts: ti: k3-j7200-common-proc-board: Modify Pinmux for wkup_uart0 and
+      mcu_uart0
+    - arm64: dts: ti: k3-j7200-common-proc-board: Remove clock-frequency from
+      mcu_uart0
+    - arm64: dts: ti: k3-j721s2-common-proc-board: Remove Pinmux for CTS and RTS
+      in wkup_uart0
+    - arm64: dts: ti: k3-j784s4-evm: Remove Pinmux for CTS and RTS in wkup_uart0
+    - arm64: dts: ti: k3-am64-main: Fix ITAP/OTAP values for MMC
+    - arm64: dts: mt8195-cherry-tomato: change watchdog reset boot flow
+    - arm64: dts: ti: Add common1 register space for AM65x SoC
+    - arm64: dts: ti: Add common1 register space for AM62x SoC
+    - firmware: arm_scmi: Fix double free in SMC transport cleanup path
+    - wifi: cfg80211: set correct param change count in ML element
+    - arm64: dts: ti: k3-j721e: Fix mux-reg-masks in hbmc_mux
+    - arm64: dts: ti: k3-j784s4-main: Fix mux-reg-masks in serdes_ln_ctrl
+    - arm64: dts: ti: k3-am62p: Fix memory ranges for DMSS
+    - wifi: wilc1000: revert reset line logic flip
+    - ARM: dts: arm: realview: Fix development chip ROM compatible value
+    - memory: tegra: Correct DLA client names
+    - wifi: mt76: mt7996: fix fw loading timeout
+    - wifi: mt76: mt7925: fix connect to 80211b mode fail in 2Ghz band
+    - wifi: mt76: mt7925: fix SAP no beacon issue in 5Ghz and 6Ghz band
+    - wifi: mt76: mt7925: fix mcu query command fail
+    - wifi: mt76: mt7925: fix wmm queue mapping
+    - wifi: mt76: mt7925: fix fw download fail
+    - wifi: mt76: mt7925: fix WoW failed in encrypted mode
+    - wifi: mt76: mt7925: fix the wrong header translation config
+    - wifi: mt76: mt7925: add flow to avoid chip bt function fail
+    - wifi: mt76: mt7925: add support to set ifs time by mcu command
+    - wifi: mt76: mt7925: update PCIe DMA settings
+    - wifi: mt76: mt7996: check txs format before getting skb by pid
+    - wifi: mt76: mt7996: fix TWT issues
+    - wifi: mt76: mt7996: fix incorrect interpretation of EHT MCS caps
+    - wifi: mt76: mt7996: fix HE beamformer phy cap for station vif
+    - wifi: mt76: mt7996: fix efuse reading issue
+    - wifi: mt76: mt7996: fix HIF_TXD_V2_1 value
+    - wifi: mt76: mt792x: fix ethtool warning
+    - wifi: mt76: mt7921e: fix use-after-free in free_irq()
+    - wifi: mt76: mt7925e: fix use-after-free in free_irq()
+    - wifi: mt76: mt7921: fix incorrect type conversion for CLC command
+    - wifi: mt76: mt792x: fix a potential loading failure of the 6Ghz channel
+      config from ACPI
+    - wifi: mt76: fix the issue of missing txpwr settings from ch153 to ch177
+    - arm64: dts: renesas: rzg2l: Add missing interrupts to IRQC nodes
+    - arm64: dts: renesas: r9a08g045: Add missing interrupts to IRQC node
+    - arm64: dts: renesas: rzg3s-smarc-som: Guard Ethernet IRQ GPIO hogs
+    - arm64: dts: renesas: r8a779a0: Correct avb[01] reg sizes
+    - arm64: dts: renesas: r8a779g0: Correct avb[01] reg sizes
+    - net: mctp: copy skb ext data when fragmenting
+    - pstore: inode: Only d_invalidate() is needed
+    - arm64: dts: allwinner: h6: Add RX DMA channel for SPDIF
+    - ARM: dts: imx6dl-yapp4: Fix typo in the QCA switch register address
+    - ARM: dts: imx6dl-yapp4: Move the internal switch PHYs under the switch node
+    - arm64: dts: imx8mp: Set SPI NOR to max 40 MHz on Data Modul i.MX8M Plus eDM
+      SBC
+    - arm64: dts: imx8mp-evk: Fix hdmi@3d node
+    - regulator: userspace-consumer: add module device table
+    - gpiolib: Pass consumer device through to core in
+      devm_fwnode_gpiod_get_index()
+    - arm64: dts: marvell: reorder crypto interrupts on Armada SoCs
+    - ACPI: resource: Do IRQ override on Lunnen Ground laptops
+    - ACPI: resource: Add MAIBENBEN X577 to irq1_edge_low_force_override
+    - ACPI: scan: Fix device check notification handling
+    - arm64: dts: rockchip: add missing interrupt-names for rk356x vdpu
+    - arm64: dts: rockchip: fix reset-names for rk356x i2s2 controller
+    - arm64: dts: rockchip: drop rockchip,trcm-sync-tx-only from rk3588 i2s
+    - objtool: Fix UNWIND_HINT_{SAVE,RESTORE} across basic blocks
+    - x86, relocs: Ignore relocations in .notes section
+    - SUNRPC: fix a memleak in gss_import_v2_context
+    - SUNRPC: fix some memleaks in gssx_dec_option_array
+    - arm64: dts: qcom: sm8550: Fix SPMI channels size
+    - arm64: dts: qcom: sm8650: Fix SPMI channels size
+    - mmc: wmt-sdmmc: remove an incorrect release_mem_region() call in the .remove
+      function
+    - ACPI: CPPC: enable AMD CPPC V2 support for family 17h processors
+    - btrfs: fix race when detecting delalloc ranges during fiemap
+    - wifi: rtw88: 8821cu: Fix firmware upload fail
+    - wifi: rtw88: 8821c: Fix beacon loss and disconnect
+    - wifi: rtw88: 8821c: Fix false alarm count
+    - wifi: brcm80211: handle pmk_op allocation failure
+    - riscv: dts: starfive: jh7100: fix root clock names
+    - PCI: Make pci_dev_is_disconnected() helper public for other drivers
+    - iommu/vt-d: Don't issue ATS Invalidation request when device is disconnected
+    - iommu/vt-d: Use rbtree to track iommu probed devices
+    - iommu/vt-d: Improve ITE fault handling if target device isn't present
+    - iommu/vt-d: Use device rbtree in iopf reporting path
+    - iommu: Add static iommu_ops->release_domain
+    - iommu/vt-d: Fix NULL domain on device release
+    - igc: Fix missing time sync events
+    - igb: Fix missing time sync events
+    - ice: fix stats being updated by way too large values
+    - Bluetooth: Remove HCI_POWER_OFF_TIMEOUT
+    - Bluetooth: mgmt: Remove leftover queuing of power_off work
+    - Bluetooth: Remove superfluous call to hci_conn_check_pending()
+    - Bluetooth: Remove BT_HS
+    - Bluetooth: hci_event: Fix not indicating new connection for BIG Sync
+    - Bluetooth: hci_qca: don't use IS_ERR_OR_NULL() with gpiod_get_optional()
+    - Bluetooth: hci_core: Cancel request on command timeout
+    - Bluetooth: hci_sync: Fix overwriting request callback
+    - Bluetooth: hci_h5: Add ability to allocate memory for private data
+    - Bluetooth: btrtl: fix out of bounds memory access
+    - Bluetooth: hci_core: Fix possible buffer overflow
+    - Bluetooth: msft: Fix memory leak
+    - Bluetooth: btusb: Fix memory leak
+    - Bluetooth: af_bluetooth: Fix deadlock
+    - Bluetooth: fix use-after-free in accessing skb after sending it
+    - sr9800: Add check for usbnet_get_endpoints
+    - s390/cache: prevent rebuild of shared_cpu_list
+    - bpf: Fix DEVMAP_HASH overflow check on 32-bit arches
+    - bpf: Fix hashtab overflow check on 32-bit arches
+    - bpf: Fix stackmap overflow check on 32-bit arches
+    - net: dsa: microchip: make sure drive strength configuration is not lost by
+      soft reset
+    - dpll: spec: use proper enum for pin capabilities attribute
+    - iommu: Fix compilation without CONFIG_IOMMU_INTEL
+    - ipv6: fib6_rules: flush route cache when rule is changed
+    - net: ip_tunnel: make sure to pull inner header in ip_tunnel_rcv()
+    - octeontx2-af: Fix devlink params
+    - net: phy: fix phy_get_internal_delay accessing an empty array
+    - dpll: fix dpll_xa_ref_*_del() for multiple registrations
+    - net: hns3: fix wrong judgment condition issue
+    - net: hns3: fix kernel crash when 1588 is received on HIP08 devices
+    - net: hns3: fix port duplex configure error in IMP reset
+    - Bluetooth: Fix eir name length
+    - net: phy: dp83822: Fix RGMII TX delay configuration
+    - erofs: fix lockdep false positives on initializing erofs_pseudo_mnt
+    - OPP: debugfs: Fix warning around icc_get_name()
+    - tcp: fix incorrect parameter validation in the do_tcp_getsockopt() function
+    - ipmr: fix incorrect parameter validation in the ip_mroute_getsockopt()
+      function
+    - l2tp: fix incorrect parameter validation in the pppol2tp_getsockopt()
+      function
+    - udp: fix incorrect parameter validation in the udp_lib_getsockopt() function
+    - net: kcm: fix incorrect parameter validation in the kcm_getsockopt) function
+    - net/x25: fix incorrect parameter validation in the x25_getsockopt() function
+    - devlink: Fix length of eswitch inline-mode
+    - r8152: fix unknown device for choose_configuration
+    - nfp: flower: handle acti_netdevs allocation failure
+    - bpf: hardcode BPF_PROG_PACK_SIZE to 2MB * num_possible_nodes()
+    - dm raid: fix false positive for requeue needed during reshape
+    - dm: call the resume method on internal suspend
+    - fbdev/simplefb: change loglevel when the power domains cannot be parsed
+    - drm/tegra: dsi: Add missing check for of_find_device_by_node
+    - drm/tegra: dpaux: Fix PM disable depth imbalance in tegra_dpaux_probe
+    - drm/tegra: dsi: Fix some error handling paths in tegra_dsi_probe()
+    - drm/tegra: dsi: Fix missing pm_runtime_disable() in the error handling path
+      of tegra_dsi_probe()
+    - drm/tegra: hdmi: Fix some error handling paths in tegra_hdmi_probe()
+    - drm/tegra: rgb: Fix some error handling paths in tegra_dc_rgb_probe()
+    - drm/tegra: rgb: Fix missing clk_put() in the error handling paths of
+      tegra_dc_rgb_probe()
+    - drm/tegra: output: Fix missing i2c_put_adapter() in the error handling paths
+      of tegra_output_probe()
+    - drm/rockchip: inno_hdmi: Fix video timing
+    - drm: Don't treat 0 as -1 in drm_fixp2int_ceil
+    - drm/vkms: Avoid reading beyond LUT array
+    - drm/vmwgfx: fix a memleak in vmw_gmrid_man_get_node
+    - drm/rockchip: lvds: do not overwrite error code
+    - drm/rockchip: lvds: do not print scary message when probing defer
+    - drm/panel-edp: use put_sync in unprepare
+    - drm/lima: fix a memleak in lima_heap_alloc
+    - ASoC: amd: acp: Add missing error handling in sof-mach
+    - ASoC: SOF: amd: Fix memory leak in amd_sof_acp_probe()
+    - ASoC: SOF: core: Skip firmware test for custom loaders
+    - ASoC: SOF: amd: Compute file paths on firmware load
+    - soundwire: stream: add missing const to Documentation
+    - dmaengine: tegra210-adma: Update dependency to ARCH_TEGRA
+    - media: tc358743: register v4l2 async device only after successful setup
+    - media: cadence: csi2rx: use match fwnode for media link
+    - PCI/DPC: Print all TLP Prefixes, not just the first
+    - perf record: Fix possible incorrect free in record__switch_output()
+    - perf record: Check conflict between '--timestamp-filename' option and pipe
+      mode before recording
+    - HID: lenovo: Add middleclick_workaround sysfs knob for cptkbd
+    - drm/amd/display: Fix a potential buffer overflow in 'dp_dsc_clock_en_read()'
+    - perf pmu: Treat the msr pmu as software
+    - crypto: qat - avoid memcpy() overflow warning
+    - ALSA: hda: cs35l41: Set Channel Index correctly when system is missing _DSD
+    - drm/amd/display: Fix potential NULL pointer dereferences in
+      'dcn10_set_output_transfer_func()'
+    - ASoC: sh: rz-ssi: Fix error message print
+    - drm/vmwgfx: Fix vmw_du_get_cursor_mob fencing of newly-created MOBs
+    - clk: renesas: r8a779g0: Fix PCIe clock name
+    - pinctrl: renesas: rzg2l: Fix locking in rzg2l_dt_subnode_to_map()
+    - pinctrl: renesas: r8a779g0: Add missing SCIF_CLK2 pin group/function
+    - clk: samsung: exynos850: Propagate SPI IPCLK rate change
+    - media: v4l2: cci: print leading 0 on error
+    - perf evsel: Fix duplicate initialization of data->id in
+      evsel__parse_sample()
+    - perf bpf: Clean up the generated/copied vmlinux.h
+    - clk: meson: Add missing clocks to axg_clk_regmaps
+    - media: em28xx: annotate unchecked call to media_device_register()
+    - media: v4l2-tpg: fix some memleaks in tpg_alloc
+    - media: v4l2-mem2mem: fix a memleak in v4l2_m2m_register_entity
+    - media: dt-bindings: techwell,tw9900: Fix port schema ref
+    - mtd: spinand: esmt: Extend IDs to 5 bytes
+    - media: edia: dvbdev: fix a use-after-free
+    - pinctrl: mediatek: Drop bogus slew rate register range for MT8186
+    - pinctrl: mediatek: Drop bogus slew rate register range for MT8192
+    - drm/amdgpu: Fix potential out-of-bounds access in
+      'amdgpu_discovery_reg_base_init()'
+    - clk: qcom: reset: Commonize the de/assert functions
+    - clk: qcom: reset: Ensure write completion on reset de/assertion
+    - quota: Fix potential NULL pointer dereference
+    - quota: Fix rcu annotations of inode dquot pointers
+    - quota: Properly annotate i_dquot arrays with __rcu
+    - ASoC: Intel: ssp-common: Add stub for sof_ssp_get_codec_name
+    - PCI/P2PDMA: Fix a sleeping issue in a RCU read section
+    - PCI: switchtec: Fix an error handling path in switchtec_pci_probe()
+    - crypto: xilinx - call finalize with bh disabled
+    - drivers/ps3: select VIDEO to provide cmdline functions
+    - perf thread_map: Free strlist on normal path in thread_map__new_by_tid_str()
+    - perf srcline: Add missed addr2line closes
+    - dt-bindings: msm: qcom, mdss: Include ommited fam-b compatible
+    - drm/msm/dpu: fix the programming of INTF_CFG2_DATA_HCTL_EN
+    - drm/msm/dpu: Only enable DSC_MODE_MULTIPLEX if dsc_merge is enabled
+    - drm/radeon/ni: Fix wrong firmware size logging in ni_init_microcode()
+    - drm/amd/display: fix NULL checks for adev->dm.dc in amdgpu_dm_fini()
+    - clk: renesas: r8a779g0: Correct PFC/GPIO parent clocks
+    - clk: renesas: r8a779f0: Correct PFC/GPIO parent clock
+    - clk: renesas: r9a07g04[34]: Use SEL_SDHI1_STS status configuration for SD1
+      mux
+    - ALSA: seq: fix function cast warnings
+    - perf expr: Fix "has_event" function for metric style events
+    - perf stat: Avoid metric-only segv
+    - perf metric: Don't remove scale from counts
+    - ASoC: meson: aiu: fix function pointer type mismatch
+    - ASoC: meson: t9015: fix function pointer type mismatch
+    - powerpc: Force inlining of arch_vmap_p{u/m}d_supported()
+    - ASoC: SOF: Add some bounds checking to firmware data
+    - drm: ci: use clk_ignore_unused for apq8016
+    - NTB: fix possible name leak in ntb_register_device()
+    - media: cedrus: h265: Fix configuring bitstream size
+    - media: sun8i-di: Fix coefficient writes
+    - media: sun8i-di: Fix power on/off sequences
+    - media: sun8i-di: Fix chroma difference threshold
+    - staging: media: starfive: Set 16 bpp for capture_raw device
+    - media: imx: csc/scaler: fix v4l2_ctrl_handler memory leak
+    - media: go7007: add check of return value of go7007_read_addr()
+    - media: pvrusb2: remove redundant NULL check
+    - media: videobuf2: Add missing doc comment for waiting_in_dqbuf
+    - media: pvrusb2: fix pvr2_stream_callback casts
+    - clk: qcom: dispcc-sdm845: Adjust internal GDSC wait times
+    - drm/amd/display: Add 'replay' NULL check in 'edp_set_replay_allow_active()'
+    - drm/panel: boe-tv101wum-nl6: make use of prepare_prev_first
+    - drm/msm/dpu: finalise global state object
+    - drm/mediatek: dsi: Fix DSI RGB666 formats and definitions
+    - PCI: Mark 3ware-9650SE Root Port Extended Tags as broken
+    - drm/bridge: adv7511: fix crash on irq during probe
+    - pinctrl: renesas: Allow the compiler to optimize away sh_pfc_pm
+    - clk: hisilicon: hi3519: Release the correct number of gates in
+      hi3519_clk_unregister()
+    - clk: hisilicon: hi3559a: Fix an erroneous devm_kfree()
+    - clk: mediatek: mt8135: Fix an error handling path in
+      clk_mt8135_apmixed_probe()
+    - clk: mediatek: mt7622-apmixedsys: Fix an error handling path in
+      clk_mt8135_apmixed_probe()
+    - clk: mediatek: mt8183: Correct parent of CLK_INFRA_SSPM_32K_SELF
+    - clk: mediatek: mt7981-topckgen: flag SGM_REG_SEL as critical
+    - drm/tegra: put drm_gem_object ref on error in tegra_fb_create
+    - tty: mips_ejtag_fdc: Fix passing incompatible pointer type warning
+    - media: ivsc: csi: Swap SINK and SOURCE pads
+    - media: i2c: imx290: Fix IMX920 typo
+    - mfd: syscon: Call of_node_put() only when of_parse_phandle() takes a ref
+    - mfd: altera-sysmgr: Call of_node_put() only when of_parse_phandle() takes a
+      ref
+    - perf print-events: make is_event_supported() more robust
+    - crypto: arm/sha - fix function cast warnings
+    - crypto: ccp - Avoid discarding errors in psp_send_platform_access_msg()
+    - crypto: qat - remove unused macros in qat_comp_alg.c
+    - crypto: qat - removed unused macro in adf_cnv_dbgfs.c
+    - crypto: qat - avoid division by zero
+    - crypto: qat - remove double initialization of value
+    - crypto: qat - fix ring to service map for dcc in 4xxx
+    - crypto: qat - fix ring to service map for dcc in 420xx
+    - crypto: jitter - fix CRYPTO_JITTERENTROPY help text
+    - drm/tidss: Fix initial plane zpos values
+    - drm/tidss: Fix sync-lost issue with two displays
+    - clk: imx: imx8mp: Fix SAI_MCLK_SEL definition
+    - mtd: maps: physmap-core: fix flash size larger than 32-bit
+    - mtd: rawnand: lpc32xx_mlc: fix irq handler prototype
+    - mtd: rawnand: brcmnand: exec_op helper functions return type fixes
+    - ASoC: meson: axg-tdm-interface: fix mclk setup without mclk-fs
+    - ASoC: meson: axg-tdm-interface: add frame rate constraint
+    - drm/msm/a6xx: specify UBWC config for sc7180
+    - drm/msm/a7xx: Fix LLC typo
+    - dt-bindings: arm-smmu: fix SM8[45]50 GPU SMMU if condition
+    - perf pmu: Fix a potential memory leak in perf_pmu__lookup()
+    - HID: amd_sfh: Update HPD sensor structure elements
+    - HID: amd_sfh: Avoid disabling the interrupt
+    - drm/amdgpu: Fix missing break in ATOM_ARG_IMM Case of atom_get_src_int()
+    - media: pvrusb2: fix uaf in pvr2_context_set_notify
+    - media: dvb-frontends: avoid stack overflow warnings with clang
+    - media: go7007: fix a memleak in go7007_load_encoder
+    - media: ttpci: fix two memleaks in budget_av_attach
+    - media: mediatek: vcodec: avoid -Wcast-function-type-strict warning
+    - arm64: ftrace: Don't forbid CALL_OPS+CC_OPTIMIZE_FOR_SIZE with Clang
+    - drm/tests: helpers: Include missing drm_drv header
+    - drm/amd/pm: Fix esm reg mask use to get pcie speed
+    - gpio: nomadik: fix offset bug in nmk_pmx_set()
+    - drm/mediatek: Fix a null pointer crash in mtk_drm_crtc_finish_page_flip
+    - mfd: cs42l43: Fix wrong register defaults
+    - powerpc/32: fix ADB_CUDA kconfig warning
+    - powerpc/pseries: Fix potential memleak in papr_get_attr()
+    - powerpc/hv-gpci: Fix the H_GET_PERF_COUNTER_INFO hcall return value checks
+    - clk: qcom: gcc-ipq5018: fix 'enable_reg' offset of 'gcc_gmac0_sys_clk'
+    - clk: qcom: gcc-ipq5018: fix 'halt_reg' offset of 'gcc_pcie1_pipe_clk'
+    - clk: qcom: gcc-ipq5018: fix register offset for GCC_UBI0_AXI_ARES reset
+    - perf vendor events amd: Fix Zen 4 cache latency events
+    - drm/msm/dpu: allow certain formats for CDM for DP
+    - drm/msm/dpu: add division of drm_display_mode's hskew parameter
+    - media: usbtv: Remove useless locks in usbtv_video_free()
+    - drm/xe: Fix ref counting leak on page fault
+    - drm/xe: Replace 'grouped target' in Makefile with pattern rule
+    - lib/stackdepot: fix first entry having a 0-handle
+    - lib/stackdepot: off by one in depot_fetch_stack()
+    - modules: wait do_free_init correctly
+    - mfd: cs42l43: Fix wrong GPIO_FN_SEL and SPI_CLK_CONFIG1 defaults
+    - power: supply: mm8013: fix "not charging" detection
+    - powerpc/embedded6xx: Fix no previous prototype for avr_uart_send() etc.
+    - powerpc/4xx: Fix warp_gpio_leds build failure
+    - RISC-V: KVM: Forward SEED CSR access to user space
+    - leds: aw2013: Unlock mutex before destroying it
+    - leds: sgm3140: Add missing timer cleanup and flash gpio control
+    - backlight: hx8357: Fix potential NULL pointer dereference
+    - backlight: ktz8866: Correct the check for of_property_read_u32
+    - backlight: lm3630a: Initialize backlight_properties on init
+    - backlight: lm3630a: Don't set bl->props.brightness in get_brightness
+    - backlight: da9052: Fully initialize backlight_properties during probe
+    - backlight: lm3639: Fully initialize backlight_properties during probe
+    - backlight: lp8788: Fully initialize backlight_properties during probe
+    - sparc32: Use generic cmpdi2/ucmpdi2 variants
+    - mtd: maps: sun_uflash: Declare uflash_devinit static
+    - sparc32: Do not select GENERIC_ISA_DMA
+    - sparc32: Fix section mismatch in leon_pci_grpci
+    - clk: Fix clk_core_get NULL dereference
+    - clk: zynq: Prevent null pointer dereference caused by kmalloc failure
+    - PCI: brcmstb: Fix broken brcm_pcie_mdio_write() polling
+    - cifs: Fix writeback data corruption
+    - ALSA: hda/realtek: fix ALC285 issues on HP Envy x360 laptops
+    - ALSA: hda/tas2781: use dev_dbg in system_resume
+    - ALSA: hda/tas2781: add lock to system_suspend
+    - ALSA: hda/tas2781: do not reset cur_* values in runtime_suspend
+    - ALSA: hda/tas2781: do not call pm_runtime_force_* in system_resume/suspend
+    - ALSA: hda/tas2781: restore power state after system_resume
+    - ALSA: scarlett2: Fix Scarlett 4th Gen 4i4 low-voltage detection
+    - ALSA: scarlett2: Fix Scarlett 4th Gen autogain status values
+    - ALSA: scarlett2: Fix Scarlett 4th Gen input gain range
+    - ALSA: scarlett2: Fix Scarlett 4th Gen input gain range again
+    - mips: cm: Convert __mips_cm_l2sync_phys_base() to weak function
+    - platform/x86/intel/pmc/lnl: Remove SSRAM support
+    - platform/x86/intel/pmc/arl: Put GNA device in D3
+    - platform/x86/amd/pmf: Do not use readl() for policy buffer access
+    - ALSA: usb-audio: Stop parsing channels bits when all channels are found.
+    - phy: qcom: qmp-usb: split USB-C PHY driver
+    - phy: qcom: qmp-usbc: add support for the Type-C handling
+    - phy: qcom: qmp-usbc: handle CLAMP register in a correct way
+    - scsi: hisi_sas: Fix a deadlock issue related to automatic dump
+    - RDMA/irdma: Remove duplicate assignment
+    - RDMA/srpt: Do not register event handler until srpt device is fully setup
+    - f2fs: compress: fix to guarantee persisting compressed blocks by CP
+    - f2fs: compress: fix to cover normal cluster write with cp_rwsem
+    - f2fs: compress: fix to check unreleased compressed cluster
+    - f2fs: compress: fix to avoid inconsistence bewteen i_blocks and dnode
+    - f2fs: fix to remove unnecessary f2fs_bug_on() to avoid panic
+    - f2fs: zone: fix to wait completion of last bio in zone correctly
+    - f2fs: fix NULL pointer dereference in f2fs_submit_page_write()
+    - f2fs: compress: fix to cover f2fs_disable_compressed_file() w/ i_sem
+    - f2fs: fix to avoid potential panic during recovery
+    - scsi: csiostor: Avoid function pointer casts
+    - i3c: dw: Disable IBI IRQ depends on hot-join and SIR enabling
+    - RDMA/hns: Fix mis-modifying default congestion control algorithm
+    - RDMA/device: Fix a race between mad_client and cm_client init
+    - RDMA/rtrs-clt: Check strnlen return len in sysfs mpath_policy_store()
+    - scsi: bfa: Fix function pointer type mismatch for hcb_qe->cbfn
+    - f2fs: fix to create selinux label during whiteout initialization
+    - f2fs: compress: fix to check zstd compress level correctly in mount option
+    - net: sunrpc: Fix an off by one in rpc_sockaddr2uaddr()
+    - NFSv4.2: fix nfs4_listxattr kernel BUG at mm/usercopy.c:102
+    - NFSv4.2: fix listxattr maximum XDR buffer size
+    - f2fs: compress: fix to check compress flag w/ .i_sem lock
+    - f2fs: check number of blocks in a current section
+    - watchdog: starfive: Check pm_runtime_enabled() before decrementing usage
+      counter
+    - watchdog: stm32_iwdg: initialize default timeout
+    - f2fs: fix to use correct segment type in f2fs_allocate_data_block()
+    - f2fs: ro: compress: fix to avoid caching unaligned extent
+    - RDMA/mana_ib: Fix bug in creation of dma regions
+    - RDMA/mana_ib: Introduce mdev_to_gc helper function
+    - RDMA/mana_ib: Introduce mana_ib_get_netdev helper function
+    - RDMA/mana_ib: Introduce mana_ib_install_cq_cb helper function
+    - RDMA/mana_ib: Use virtual address in dma regions for MRs
+    - Input: iqs7222 - add support for IQS7222D v1.1 and v1.2
+    - NFS: Fix nfs_netfs_issue_read() xarray locking for writeback interrupt
+    - NFS: Fix an off by one in root_nfs_cat()
+    - NFSv4.1/pnfs: fix NFS with TLS in pnfs
+    - ACPI: HMAT: Remove register of memory node for generic target
+    - f2fs: compress: relocate some judgments in f2fs_reserve_compress_blocks
+    - f2fs: compress: fix reserve_cblocks counting error when out of space
+    - f2fs: fix to truncate meta inode pages forcely
+    - f2fs: zone: fix to remove pow2 check condition for zoned block device
+    - cxl: Fix the incorrect assignment of SSLBIS entry pointer initial location
+    - perf/x86/amd/core: Avoid register reset when CPU is dead
+    - afs: Revert "afs: Hide silly-rename files from userspace"
+    - afs: Don't cache preferred address
+    - afs: Fix occasional rmdir-then-VNOVNODE with generic/011
+    - f2fs: fix to avoid use-after-free issue in f2fs_filemap_fault
+    - nfs: fix panic when nfs4_ff_layout_prepare_ds() fails
+    - ovl: relax WARN_ON in ovl_verify_area()
+    - io_uring/net: correct the type of variable
+    - remoteproc: stm32: Fix incorrect type in assignment for va
+    - remoteproc: stm32: Fix incorrect type assignment returned by
+      stm32_rproc_get_loaded_rsc_tablef
+    - iio: pressure: mprls0025pa fix off-by-one enum
+    - usb: phy: generic: Get the vbus supply
+    - tty: vt: fix 20 vs 0x20 typo in EScsiignore
+    - serial: max310x: fix syntax error in IRQ error message
+    - tty: serial: samsung: fix tx_empty() to return TIOCSER_TEMT
+    - arm64: dts: broadcom: bcmbca: bcm4908: drop invalid switch cells
+    - coresight: Fix issue where a source device's helpers aren't disabled
+    - coresight: etm4x: Set skip_power_up in etm4_init_arch_data function
+    - xhci: Add interrupt pending autoclear flag to each interrupter
+    - xhci: make isoc_bei_interval variable interrupter specific.
+    - xhci: remove unnecessary event_ring_deq parameter from xhci_handle_event()
+    - xhci: update event ring dequeue pointer position to controller correctly
+    - coccinelle: device_attr_show: Remove useless expression STR
+    - kconfig: fix infinite loop when expanding a macro at the end of file
+    - iio: gts-helper: Fix division loop
+    - bus: mhi: ep: check the correct variable in mhi_ep_register_controller()
+    - hwtracing: hisi_ptt: Move type check to the beginning of
+      hisi_ptt_pmu_event_init()
+    - rtc: mt6397: select IRQ_DOMAIN instead of depending on it
+    - rtc: max31335: fix interrupt status reg
+    - serial: 8250_exar: Don't remove GPIO device on suspend
+    - staging: greybus: fix get_channel_from_mode() failure path
+    - mei: vsc: Call wake_up() in the threaded IRQ handler
+    - mei: vsc: Don't use sleeping condition in wait_event_timeout()
+    - usb: gadget: net2272: Use irqflags in the call to net2272_probe_fin
+    - char: xilinx_hwicap: Fix NULL vs IS_ERR() bug
+    - x86/hyperv: Use per cpu initial stack for vtl context
+    - ASoC: tlv320adc3xxx: Don't strip remove function when driver is builtin
+    - thermal/drivers/mediatek/lvts_thermal: Fix a memory leak in an error
+      handling path
+    - thermal/drivers/qoriq: Fix getting tmu range
+    - io_uring: don't save/restore iowait state
+    - spi: lpspi: Avoid potential use-after-free in probe()
+    - spi: Restore delays for non-GPIO chip select
+    - ASoC: rockchip: i2s-tdm: Fix inaccurate sampling rates
+    - nouveau: reset the bo resource bus info after an eviction
+    - tcp: Fix NEW_SYN_RECV handling in inet_twsk_purge()
+    - rds: tcp: Fix use-after-free of net in reqsk_timer_handler().
+    - octeontx2-af: Use matching wake_up API variant in CGX command interface
+    - s390/vtime: fix average steal time calculation
+    - net/sched: taprio: proper TCA_TAPRIO_TC_ENTRY_INDEX check
+    - devlink: Fix devlink parallel commands processing
+    - riscv: Only check online cpus for emulated accesses
+    - soc: fsl: dpio: fix kcalloc() argument order
+    - cpufreq: Fix per-policy boost behavior on SoCs using cpufreq_boost_set_sw()
+    - io_uring: Fix release of pinned pages when __io_uaddr_map fails
+    - tcp: Fix refcnt handling in __inet_hash_connect().
+    - vmxnet3: Fix missing reserved tailroom
+    - hsr: Fix uninit-value access in hsr_get_node()
+    - net: txgbe: fix clk_name exceed MAX_DEV_ID limits
+    - spi: spi-mem: add statistics support to ->exec_op() calls
+    - spi: Fix error code checking in spi_mem_exec_op()
+    - nvme: fix reconnection fail due to reserved tag allocation
+    - drm/xe: Invalidate userptr VMA on page pin fault
+    - drm/xe: Skip VMAs pin when requesting signal to the last XE_EXEC
+    - net: mediatek: mtk_eth_soc: clear MAC_MCR_FORCE_LINK only when MAC is up
+    - net: ethernet: mtk_eth_soc: fix PPE hanging issue
+    - io_uring: fix poll_remove stalled req completion
+    - ASoC: SOF: amd: Move signed_fw_image to struct acp_quirk_entry
+    - ASoC: SOF: amd: Skip IRAM/DRAM size modification for Steam Deck OLED
+    - riscv: Fix compilation error with FAST_GUP and rv32
+    - xen/evtchn: avoid WARN() when unbinding an event channel
+    - xen/events: increment refcnt only if event channel is refcounted
+    - packet: annotate data-races around ignore_outgoing
+    - xfrm: Allow UDP encapsulation only in offload modes
+    - net: veth: do not manipulate GRO when using XDP
+    - net: dsa: mt7530: prevent possible incorrect XTAL frequency selection
+    - spi: spi-imx: fix off-by-one in mx51 CPU mode burst length
+    - drm: Fix drm_fixp2int_round() making it add 0.5
+    - virtio: uapi: Drop __packed attribute in linux/virtio_pci.h
+    - vdpa_sim: reset must not run
+    - vdpa/mlx5: Allow CVQ size changes
+    - virtio: packed: fix unmap leak for indirect desc table
+    - net: move dev->state into net_device_read_txrx group
+    - wireguard: receive: annotate data-race around receiving_counter.counter
+    - rds: introduce acquire/release ordering in acquire/release_in_xmit()
+    - hsr: Handle failures in module init
+    - ipv4: raw: Fix sending packets from raw sockets via IPsec tunnels
+    - nouveau/gsp: don't check devinit disable on GSP.
+    - ceph: stop copying to iter at EOF on sync reads
+    - net: phy: fix phy_read_poll_timeout argument type in genphy_loopback
+    - dm-integrity: fix a memory leak when rechecking the data
+    - net/bnx2x: Prevent access to a freed page in page_pool
+    - devlink: fix port new reply cmd type
+    - octeontx2: Detect the mbox up or down message via register
+    - octeontx2-pf: Wait till detach_resources msg is complete
+    - octeontx2-pf: Use default max_active works instead of one
+    - octeontx2-pf: Send UP messages to VF only when VF is up.
+    - octeontx2-af: Use separate handlers for interrupts
+    - drm/amdgpu: add MMHUB 3.3.1 support
+    - drm/amdgpu: fix mmhub client id out-of-bounds access
+    - drm/amdgpu: drop setting buffer funcs in sdma442
+    - netfilter: nft_set_pipapo: release elements in clone only from destroy path
+    - netfilter: nf_tables: do not compare internal table flags on updates
+    - rcu: add a helper to report consolidated flavor QS
+    - net: report RCU QS on threaded NAPI repolling
+    - bpf: report RCU QS in cpumap kthread
+    - net: dsa: mt7530: fix link-local frames that ingress vlan filtering ports
+    - net: dsa: mt7530: fix handling of all link-local frames
+    - netfilter: nf_tables: Fix a memory leak in nf_tables_updchain
+    - spi: spi-mt65xx: Fix NULL pointer access in interrupt handler
+    - selftests: forwarding: Fix ping failure due to short timeout
+    - dm io: Support IO priority
+    - dm-integrity: align the outgoing bio in integrity_recheck
+    - x86/efistub: Clear decompressor BSS in native EFI entrypoint
+    - x86/efistub: Don't clear BSS twice in mixed mode
+    - printk: Adjust mapping for 32bit seq macros
+    - printk: Use prb_first_seq() as base for 32bit seq macros
+    - Linux 6.8.2
+    - [Config] updateconfig following v6.8.2 import
+  * Provide python perf module (LP: #2051560)
+    - [Packaging] enable perf python module
+    - [Packaging] provide a wrapper module for python-perf
+  * To support AMD Adaptive Backlight Management (ABM) for power profiles daemon
+    >= 2.0 (LP: #2056716)
+    - drm/amd/display: add panel_power_savings sysfs entry to eDP connectors
+    - drm/amdgpu: respect the abmlevel module parameter value if it is set
+  * Miscellaneous Ubuntu changes
+    - [Config] Disable StarFive JH7100 support
+    - [Config] Disable Renesas RZ/Five support
+    - [Config] Disable BINFMT_FLAT for riscv64
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Mon, 03 Jun 2024 17:15:49 +0900
+
+linux-qcom (6.8.0-1003.3) jammy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - Fix PCIe bus error
+    - Fix GPU regression
+    - Fix qps615 firmware load
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Fri, 10 May 2024 14:41:07 +0900
+
+linux-qcom (6.8.0-1002.2) jammy; urgency=medium
+
+  [ Ubuntu: 6.8.0-31.31 ]
+
+  * noble/linux: 6.8.0-31.31 -proposed tracker (LP: #2062933)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.04.04)
+
+  [ Ubuntu: 6.8.0-30.30 ]
+
+  * noble/linux: 6.8.0-30.30 -proposed tracker (LP: #2061893)
+  * System unstable, kernel ring buffer flooded with "BUG: Bad page state in
+    process swapper/0" (LP: #2056706)
+    - xen-netfront: Add missing skb_mark_for_recycle
+
+  [ Ubuntu: 6.8.0-29.29 ]
+
+  * noble/linux: 6.8.0-29.29 -proposed tracker (LP: #2061888)
+  * [24.04 FEAT] [SEC2353] zcrypt: extend error recovery to deal with device
+    scans (LP: #2050019)
+    - s390/zcrypt: harmonize debug feature calls and defines
+    - s390/zcrypt: introduce dynamic debugging for AP and zcrypt code
+    - s390/pkey: harmonize pkey s390 debug feature calls
+    - s390/pkey: introduce dynamic debugging for pkey
+    - s390/ap: add debug possibility for AP messages
+    - s390/zcrypt: add debug possibility for CCA and EP11 messages
+    - s390/ap: rearm APQNs bindings complete completion
+    - s390/ap: clarify AP scan bus related functions and variables
+    - s390/ap: rework ap_scan_bus() to return true on config change
+    - s390/ap: introduce mutex to lock the AP bus scan
+    - s390/zcrypt: introduce retries on in-kernel send CPRB functions
+    - s390/zcrypt: improve zcrypt retry behavior
+    - s390/pkey: improve pkey retry behavior
+  * [24.04 FEAT] Memory hotplug vmem pages (s390x) (LP: #2051835)
+    - mm/memory_hotplug: introduce MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers
+    - s390/mm: allocate vmemmap pages from self-contained memory range
+    - s390/sclp: remove unhandled memory notifier type
+    - s390/mm: implement MEM_PREPARE_ONLINE/MEM_FINISH_OFFLINE notifiers
+    - s390: enable MHP_MEMMAP_ON_MEMORY
+    - [Config] enable CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE and
+      CONFIG_MHP_MEMMAP_ON_MEMORY for s390x
+
+  [ Ubuntu: 6.8.0-28.28 ]
+
+  * noble/linux: 6.8.0-28.28 -proposed tracker (LP: #2061867)
+  * linux-gcp 6.8.0-1005.5 (+ others) Noble kernel regression iwth new apparmor
+    profiles/features (LP: #2061851)
+    - SAUCE: apparmor4.0.0 [92/90]: fix address mapping for recvfrom
+
+  [ Ubuntu: 6.8.0-25.25 ]
+
+  * noble/linux: 6.8.0-25.25 -proposed tracker (LP: #2061083)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.04.04)
+  * Apply mitigations for the native BHI hardware vulnerabilty (LP: #2060909)
+    - x86/cpufeatures: Add new word for scattered features
+    - x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file
+    - x86/syscall: Don't force use of indirect calls for system calls
+    - x86/bhi: Add support for clearing branch history at syscall entry
+    - x86/bhi: Define SPEC_CTRL_BHI_DIS_S
+    - x86/bhi: Enumerate Branch History Injection (BHI) bug
+    - x86/bhi: Add BHI mitigation knob
+    - x86/bhi: Mitigate KVM by default
+    - KVM: x86: Add BHI_NO
+    - x86: set SPECTRE_BHI_ON as default
+    - [Config] enable spectre_bhi=auto by default
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [01/90]: LSM stacking v39: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [02/90]: LSM stacking v39: SM: Infrastructure
+      management of the sock security
+    - SAUCE: apparmor4.0.0 [03/90]: LSM stacking v39: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [04/90]: LSM stacking v39: IMA: avoid label collisions
+      with stacked LSMs
+    - SAUCE: apparmor4.0.0 [05/90]: LSM stacking v39: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [06/90]: LSM stacking v39: LSM: Add lsmblob_to_secctx
+      hook
+    - SAUCE: apparmor4.0.0 [07/90]: LSM stacking v39: Audit: maintain an lsmblob
+      in audit_context
+    - SAUCE: apparmor4.0.0 [08/90]: LSM stacking v39: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [09/90]: LSM stacking v39: Audit: Update shutdown LSM
+      data
+    - SAUCE: apparmor4.0.0 [10/90]: LSM stacking v39: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [11/90]: LSM stacking v39: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [12/90]: LSM stacking v39: Audit: use an lsmblob in
+      audit_names
+    - SAUCE: apparmor4.0.0 [13/90]: LSM stacking v39: LSM: Create new
+      security_cred_getlsmblob LSM hook
+    - SAUCE: apparmor4.0.0 [14/90]: LSM stacking v39: Audit: Change context data
+      from secid to lsmblob
+    - SAUCE: apparmor4.0.0 [15/90]: LSM stacking v39: Netlabel: Use lsmblob for
+      audit data
+    - SAUCE: apparmor4.0.0 [16/90]: LSM stacking v39: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [17/90]: LSM stacking v39: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [18/90]: LSM stacking v39: LSM: Use lsmcontext in
+      security_lsmblob_to_secctx
+    - SAUCE: apparmor4.0.0 [19/90]: LSM stacking v39: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [20/90]: LSM stacking v39: LSM: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [21/90]: LSM stacking v39: LSM:
+      security_lsmblob_to_secctx module selection
+    - SAUCE: apparmor4.0.0 [22/90]: LSM stacking v39: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [23/90]: LSM stacking v39: Audit: Allow multiple
+      records in an audit_buffer
+    - SAUCE: apparmor4.0.0 [24/90]: LSM stacking v39: Audit: Add record for
+      multiple task security contexts
+    - SAUCE: apparmor4.0.0 [25/90]: LSM stacking v39: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [26/90]: LSM stacking v39: Audit: Add record for
+      multiple object contexts
+    - SAUCE: apparmor4.0.0 [27/90]: LSM stacking v39: LSM: Remove unused
+      lsmcontext_init()
+    - SAUCE: apparmor4.0.0 [28/90]: LSM stacking v39: LSM: Improve logic in
+      security_getprocattr
+    - SAUCE: apparmor4.0.0 [29/90]: LSM stacking v39: LSM: secctx provider check
+      on release
+    - SAUCE: apparmor4.0.0 [31/90]: LSM stacking v39: LSM: Exclusive secmark usage
+    - SAUCE: apparmor4.0.0 [32/90]: LSM stacking v39: LSM: Identify which LSM
+      handles the context string
+    - SAUCE: apparmor4.0.0 [33/90]: LSM stacking v39: AppArmor: Remove the
+      exclusive flag
+    - SAUCE: apparmor4.0.0 [34/90]: LSM stacking v39: LSM: Add mount opts blob
+      size tracking
+    - SAUCE: apparmor4.0.0 [35/90]: LSM stacking v39: LSM: allocate mnt_opts blobs
+      instead of module specific data
+    - SAUCE: apparmor4.0.0 [36/90]: LSM stacking v39: LSM: Infrastructure
+      management of the key security blob
+    - SAUCE: apparmor4.0.0 [37/90]: LSM stacking v39: LSM: Infrastructure
+      management of the mnt_opts security blob
+    - SAUCE: apparmor4.0.0 [38/90]: LSM stacking v39: LSM: Correct handling of
+      ENOSYS in inode_setxattr
+    - SAUCE: apparmor4.0.0 [39/90]: LSM stacking v39: LSM: Remove lsmblob
+      scaffolding
+    - SAUCE: apparmor4.0.0 [40/90]: LSM stacking v39: LSM: Allow reservation of
+      netlabel
+    - SAUCE: apparmor4.0.0 [41/90]: LSM stacking v39: LSM: restrict
+      security_cred_getsecid() to a single LSM
+    - SAUCE: apparmor4.0.0 [42/90]: LSM stacking v39: Smack: Remove
+      LSM_FLAG_EXCLUSIVE
+    - SAUCE: apparmor4.0.0 [43/90]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0
+      [12/95]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [44/90]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [45/90]: add unpriviled user ns mediation
+    - SAUCE: apparmor4.0.0 [46/90]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [47/90]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [48/90]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [49/90]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [50/90]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/90]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/90]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/90]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [54/90]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [55/90]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [56/90]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [57/90]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [58/90]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [59/90]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [60/90]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [61/90]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [62/90]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [63/90]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [64/90]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [65/90] v6.8 prompt:fixup interruptible
+    - SAUCE: apparmor4.0.0 [69/90]: add io_uring mediation
+    - SAUCE: apparmor4.0.0 [70/90]: apparmor: fix oops when racing to retrieve
+      notification
+    - SAUCE: apparmor4.0.0 [71/90]: apparmor: fix notification header size
+    - SAUCE: apparmor4.0.0 [72/90]: apparmor: fix request field from a prompt
+      reply that denies all access
+    - SAUCE: apparmor4.0.0 [73/90]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+    - SAUCE: apparmor4.0.0 [74/90]: apparmor: cleanup attachment perm lookup to
+      use lookup_perms()
+    - SAUCE: apparmor4.0.0 [75/90]: apparmor: remove redundant unconfined check.
+    - SAUCE: apparmor4.0.0 [76/90]: apparmor: switch signal mediation to using
+      RULE_MEDIATES
+    - SAUCE: apparmor4.0.0 [77/90]: apparmor: ensure labels with more than one
+      entry have correct flags
+    - SAUCE: apparmor4.0.0 [78/90]: apparmor: remove explicit restriction that
+      unconfined cannot use change_hat
+    - SAUCE: apparmor4.0.0 [79/90]: apparmor: cleanup: refactor file_perm() to
+      provide semantics of some checks
+    - SAUCE: apparmor4.0.0 [80/90]: apparmor: carry mediation check on label
+    - SAUCE: apparmor4.0.0 [81/90]: apparmor: convert easy uses of unconfined() to
+      label_mediates()
+    - SAUCE: apparmor4.0.0 [82/90]: apparmor: add additional flags to extended
+      permission.
+    - SAUCE: apparmor4.0.0 [83/90]: apparmor: add support for profiles to define
+      the kill signal
+    - SAUCE: apparmor4.0.0 [84/90]: apparmor: fix x_table_lookup when stacking is
+      not the first entry
+    - SAUCE: apparmor4.0.0 [85/90]: apparmor: allow profile to be transitioned
+      when a user ns is created
+    - SAUCE: apparmor4.0.0 [86/90]: apparmor: add ability to mediate caps with
+      policy state machine
+    - SAUCE: apparmor4.0.0 [87/90]: fixup notify
+    - SAUCE: apparmor4.0.0 [88/90]: apparmor: add fine grained ipv4/ipv6 mediation
+    - SAUCE: apparmor4.0.0 [89/90]:apparmor: disable tailglob responses for now
+    - SAUCE: apparmor4.0.0 [90/90]: apparmor: Fix notify build warnings
+    - SAUCE: apparmor4.0.0: fix reserved mem for when we save ipv6 addresses
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [66/90]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [67/90]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [68/90]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+  * [MTL] x86: Fix Cache info sysfs is not populated (LP: #2049793)
+    - SAUCE: cacheinfo: Check for null last-level cache info
+    - SAUCE: cacheinfo: Allocate memory for memory if not done from the primary
+      CPU
+    - SAUCE: x86/cacheinfo: Delete global num_cache_leaves
+    - SAUCE: x86/cacheinfo: Clean out init_cache_level()
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor4.0.0: LSM stacking v39: fix build error with
+      CONFIG_SECURITY=n
+    - [Config] toolchain version update
+
+  [ Ubuntu: 6.8.0-22.22 ]
+
+  * noble/linux: 6.8.0-22.22 -proposed tracker (LP: #2060238)
+
+  [ Ubuntu: 6.8.0-21.21 ]
+
+  * noble/linux: 6.8.0-21.21 -proposed tracker (LP: #2060225)
+  * Miscellaneous Ubuntu changes
+    - [Config] update toolchain version in annotations
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 01 May 2024 13:45:36 +0900
+
+linux-qcom (6.8.0-1001.1) jammy; urgency=medium
+
+  * Import GA1
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Tue, 09 Apr 2024 01:46:04 +0900
+
+linux-qcom (6.8.0-1000.0) jammy; urgency=medium
+
+  [ Ubuntu: 6.8.0-20.20 ]
+
+  * noble/linux: 6.8.0-20.20 -proposed tracker (LP: #2058221)
+  * Noble update: v6.8.1 upstream stable release (LP: #2058224)
+    - x86/mmio: Disable KVM mitigation when X86_FEATURE_CLEAR_CPU_BUF is set
+    - Documentation/hw-vuln: Add documentation for RFDS
+    - x86/rfds: Mitigate Register File Data Sampling (RFDS)
+    - KVM/x86: Export RFDS_NO and RFDS_CLEAR to guests
+    - Linux 6.8.1
+  * Autopkgtest failures on amd64 (LP: #2048768)
+    - [Packaging] update to clang-18
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor4.0.0: LSM stacking v39: fix build error with
+      CONFIG_SECURITY=n
+    - [Config] amd64: MITIGATION_RFDS=y
+
+  [ Ubuntu: 6.8.0-19.19 ]
+
+  * noble/linux: 6.8.0-19.19 -proposed tracker (LP: #2057910)
+  * Miscellaneous Ubuntu changes
+    - [Packaging] re-introduce linux-doc as an empty package
+
+  [ Ubuntu: 6.8.0-18.18 ]
+
+  * noble/linux: 6.8.0-18.18 -proposed tracker (LP: #2057456)
+  * Miscellaneous Ubuntu changes
+    - [Packaging] drop dependency on libclang-17
+
+  [ Ubuntu: 6.8.0-17.17 ]
+
+  * noble/linux: 6.8.0-17.17 -proposed tracker (LP: #2056745)
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] Add debian/control sanity check"
+
+  [ Ubuntu: 6.8.0-16.16 ]
+
+  * noble/linux: 6.8.0-16.16 -proposed tracker (LP: #2056738)
+  * left-over ceph debugging printks (LP: #2056616)
+    - Revert "UBUNTU: SAUCE: ceph: make sure all the files successfully put before
+      unmounting"
+  * qat: Improve error recovery flows (LP: #2056354)
+    - crypto: qat - add heartbeat error simulator
+    - crypto: qat - disable arbitration before reset
+    - crypto: qat - update PFVF protocol for recovery
+    - crypto: qat - re-enable sriov after pf reset
+    - crypto: qat - add fatal error notification
+    - crypto: qat - add auto reset on error
+    - crypto: qat - limit heartbeat notifications
+    - crypto: qat - improve aer error reset handling
+    - crypto: qat - change SLAs cleanup flow at shutdown
+    - crypto: qat - resolve race condition during AER recovery
+    - Documentation: qat: fix auto_reset section
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [01/87]: LSM stacking v39: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [02/87]: LSM stacking v39: SM: Infrastructure
+      management of the sock security
+    - SAUCE: apparmor4.0.0 [03/87]: LSM stacking v39: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [04/87]: LSM stacking v39: IMA: avoid label collisions
+      with stacked LSMs
+    - SAUCE: apparmor4.0.0 [05/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [06/87]: LSM stacking v39: LSM: Add lsmblob_to_secctx
+      hook
+    - SAUCE: apparmor4.0.0 [07/87]: LSM stacking v39: Audit: maintain an lsmblob
+      in audit_context
+    - SAUCE: apparmor4.0.0 [08/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [09/87]: LSM stacking v39: Audit: Update shutdown LSM
+      data
+    - SAUCE: apparmor4.0.0 [10/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [11/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [12/87]: LSM stacking v39: Audit: use an lsmblob in
+      audit_names
+    - SAUCE: apparmor4.0.0 [13/87]: LSM stacking v39: LSM: Create new
+      security_cred_getlsmblob LSM hook
+    - SAUCE: apparmor4.0.0 [14/87]: LSM stacking v39: Audit: Change context data
+      from secid to lsmblob
+    - SAUCE: apparmor4.0.0 [15/87]: LSM stacking v39: Netlabel: Use lsmblob for
+      audit data
+    - SAUCE: apparmor4.0.0 [16/87]: LSM stacking v39: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [17/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [18/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_lsmblob_to_secctx
+    - SAUCE: apparmor4.0.0 [19/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [20/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [21/87]: LSM stacking v39: LSM:
+      security_lsmblob_to_secctx module selection
+    - SAUCE: apparmor4.0.0 [22/87]: LSM stacking v39: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [23/87]: LSM stacking v39: Audit: Allow multiple
+      records in an audit_buffer
+    - SAUCE: apparmor4.0.0 [24/87]: LSM stacking v39: Audit: Add record for
+      multiple task security contexts
+    - SAUCE: apparmor4.0.0 [25/87]: LSM stacking v39: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [26/87]: LSM stacking v39: Audit: Add record for
+      multiple object contexts
+    - SAUCE: apparmor4.0.0 [27/87]: LSM stacking v39: LSM: Remove unused
+      lsmcontext_init()
+    - SAUCE: apparmor4.0.0 [28/87]: LSM stacking v39: LSM: Improve logic in
+      security_getprocattr
+    - SAUCE: apparmor4.0.0 [29/87]: LSM stacking v39: LSM: secctx provider check
+      on release
+    - SAUCE: apparmor4.0.0 [31/87]: LSM stacking v39: LSM: Exclusive secmark usage
+    - SAUCE: apparmor4.0.0 [32/87]: LSM stacking v39: LSM: Identify which LSM
+      handles the context string
+    - SAUCE: apparmor4.0.0 [33/87]: LSM stacking v39: AppArmor: Remove the
+      exclusive flag
+    - SAUCE: apparmor4.0.0 [34/87]: LSM stacking v39: LSM: Add mount opts blob
+      size tracking
+    - SAUCE: apparmor4.0.0 [35/87]: LSM stacking v39: LSM: allocate mnt_opts blobs
+      instead of module specific data
+    - SAUCE: apparmor4.0.0 [36/87]: LSM stacking v39: LSM: Infrastructure
+      management of the key security blob
+    - SAUCE: apparmor4.0.0 [37/87]: LSM stacking v39: LSM: Infrastructure
+      management of the mnt_opts security blob
+    - SAUCE: apparmor4.0.0 [38/87]: LSM stacking v39: LSM: Correct handling of
+      ENOSYS in inode_setxattr
+    - SAUCE: apparmor4.0.0 [39/87]: LSM stacking v39: LSM: Remove lsmblob
+      scaffolding
+    - SAUCE: apparmor4.0.0 [40/87]: LSM stacking v39: LSM: Allow reservation of
+      netlabel
+    - SAUCE: apparmor4.0.0 [41/87]: LSM stacking v39: LSM: restrict
+      security_cred_getsecid() to a single LSM
+    - SAUCE: apparmor4.0.0 [42/87]: LSM stacking v39: Smack: Remove
+      LSM_FLAG_EXCLUSIVE
+    - SAUCE: apparmor4.0.0 [43/87]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0
+      [12/95]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [44/87]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [45/87]: add unpriviled user ns mediation
+    - SAUCE: apparmor4.0.0 [46/87]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [47/87]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [48/87]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [49/87]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [50/87]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/87]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/87]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/87]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [54/87]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [55/87]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [56/87]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [57/87]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [58/87]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [59/87]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [60/87]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [61/87]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [62/87]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [63/87]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [64/87]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [65/87] v6.8 prompt:fixup interruptible
+    - SAUCE: apparmor4.0.0 [69/87]: add io_uring mediation
+    - SAUCE: apparmor4.0.0 [70/87]: apparmor: fix oops when racing to retrieve
+      notification
+    - SAUCE: apparmor4.0.0 [71/87]: apparmor: fix notification header size
+    - SAUCE: apparmor4.0.0 [72/87]: apparmor: fix request field from a prompt
+      reply that denies all access
+    - SAUCE: apparmor4.0.0 [73/87]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+    - SAUCE: apparmor4.0.0 [74/87]: apparmor: cleanup attachment perm lookup to
+      use lookup_perms()
+    - SAUCE: apparmor4.0.0 [75/87]: apparmor: remove redundant unconfined check.
+    - SAUCE: apparmor4.0.0 [76/87]: apparmor: switch signal mediation to using
+      RULE_MEDIATES
+    - SAUCE: apparmor4.0.0 [77/87]: apparmor: ensure labels with more than one
+      entry have correct flags
+    - SAUCE: apparmor4.0.0 [78/87]: apparmor: remove explicit restriction that
+      unconfined cannot use change_hat
+    - SAUCE: apparmor4.0.0 [79/87]: apparmor: cleanup: refactor file_perm() to
+      provide semantics of some checks
+    - SAUCE: apparmor4.0.0 [80/87]: apparmor: carry mediation check on label
+    - SAUCE: apparmor4.0.0 [81/87]: apparmor: convert easy uses of unconfined() to
+      label_mediates()
+    - SAUCE: apparmor4.0.0 [82/87]: apparmor: add additional flags to extended
+      permission.
+    - SAUCE: apparmor4.0.0 [83/87]: apparmor: add support for profiles to define
+      the kill signal
+    - SAUCE: apparmor4.0.0 [84/87]: apparmor: fix x_table_lookup when stacking is
+      not the first entry
+    - SAUCE: apparmor4.0.0 [85/87]: apparmor: allow profile to be transitioned
+      when a user ns is created
+    - SAUCE: apparmor4.0.0 [86/87]: apparmor: add ability to mediate caps with
+      policy state machine
+    - SAUCE: apparmor4.0.0 [87/87]: fixup notify
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [66/87]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [67/87]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [68/87]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+  * Enable lowlatency settings in the generic kernel (LP: #2051342)
+    - [Config] enable low-latency settings
+  * hwmon: (coretemp) Fix core count limitation (LP: #2056126)
+    - hwmon: (coretemp) Introduce enum for attr index
+    - hwmon: (coretemp) Remove unnecessary dependency of array index
+    - hwmon: (coretemp) Replace sensor_device_attribute with device_attribute
+    - hwmon: (coretemp) Remove redundant pdata->cpu_map[]
+    - hwmon: (coretemp) Abstract core_temp helpers
+    - hwmon: (coretemp) Split package temp_data and core temp_data
+    - hwmon: (coretemp) Remove redundant temp_data->is_pkg_data
+    - hwmon: (coretemp) Use dynamic allocated memory for core temp_data
+  * Miscellaneous Ubuntu changes
+    - [Config] Disable CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION
+    - [Packaging] remove debian/scripts/misc/arch-has-odm-enabled.sh
+    - rebase on v6.8
+    - [Config] toolchain version update
+  * Miscellaneous upstream changes
+    - crypto: qat - add fatal error notify method
+  * Rebase on v6.8
+
+  [ Ubuntu: 6.8.0-15.15 ]
+
+  * noble/linux: 6.8.0-15.15 -proposed tracker (LP: #2055871)
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.8-rc7
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] Transition laptop-23.10 to generic"
+  * Rebase on v6.8-rc7
+
+  [ Ubuntu: 6.8.0-14.14 ]
+
+  * noble/linux: 6.8.0-14.14 -proposed tracker (LP: #2055551)
+  * Please change CONFIG_CONSOLE_LOGLEVEL_QUIET to 3 (LP: #2049390)
+    - [Config] reduce verbosity when booting in quiet mode
+  * linux: please move erofs.ko (CONFIG_EROFS for EROFS support) from linux-
+    modules-extra to linux-modules (LP: #2054809)
+    - UBUNTU [Packaging]: Include erofs in linux-modules instead of linux-modules-
+      extra
+  * linux: please move dmi-sysfs.ko (CONFIG_DMI_SYSFS for SMBIOS support) from
+    linux-modules-extra to linux-modules (LP: #2045561)
+    - [Packaging] Move dmi-sysfs.ko into linux-modules
+  * Enable CONFIG_INTEL_IOMMU_DEFAULT_ON and
+    CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON (LP: #1951440)
+    - [Config] enable Intel DMA remapping by default
+  * disable Intel DMA remapping by default (LP: #1971699)
+    - [Config] update tracking bug for CONFIG_INTEL_IOMMU_DEFAULT_ON
+  * Packaging resync (LP: #1786013)
+    - debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.02.29)
+  * Miscellaneous Ubuntu changes
+    - SAUCE: modpost: Replace 0-length array with flex-array member
+    - [packaging] do not include debian/ directory in a binary package
+    - [packaging] remove debian/stamps/keep-dir
+
+  [ Ubuntu: 6.8.0-13.13 ]
+
+  * noble/linux: 6.8.0-13.13 -proposed tracker (LP: #2055421)
+  * Packaging resync (LP: #1786013)
+    - debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.02.29)
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.8-rc6
+    - [Config] updateconfifs following v6.8-rc6 rebase
+  * Rebase on v6.8-rc6
+
+  [ Ubuntu: 6.8.0-12.12 ]
+
+  * linux-tools-common: man page of usbip[d] is misplaced (LP: #2054094)
+    - [Packaging] rules: Put usbip manpages in the correct directory
+  * Validate connection interval to pass Bluetooth Test Suite (LP: #2052005)
+    - Bluetooth: Enforce validation on max value of connection interval
+  * Turning COMPAT_32BIT_TIME off on s390x (LP: #2038583)
+    - [Config] Turn off 31-bit COMPAT on s390x
+  * Don't produce linux-source binary package (LP: #2043994)
+    - [Packaging] Add debian/control sanity check
+  * Don't produce linux-*-source-<version> package (LP: #2052439)
+    - [Packaging] Move linux-source package stub to debian/control.d
+    - [Packaging] Build linux-source package only for the main kernel
+  * Don't produce linux-*-cloud-tools-common, linux-*-tools-common and
+    linux-*-tools-host binary packages (LP: #2048183)
+    - [Packaging] Move indep tools package stubs to debian/control.d
+    - [Packaging] Build indep tools packages only for the main kernel
+  * Enable CONFIG_INTEL_IOMMU_DEFAULT_ON and
+    CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON (LP: #1951440)
+    - [Config] enable Intel DMA remapping by default
+  * disable Intel DMA remapping by default (LP: #1971699)
+    - [Config] update tracking bug for CONFIG_INTEL_IOMMU_DEFAULT_ON
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Transition laptop-23.10 to generic
+
+  [ Ubuntu: 6.8.0-11.11 ]
+
+  * noble/linux: 6.8.0-11.11 -proposed tracker (LP: #2053094)
+  * Miscellaneous Ubuntu changes
+    - [Packaging] riscv64: disable building unnecessary binary debs
+
+  [ Ubuntu: 6.8.0-10.10 ]
+
+  * noble/linux: 6.8.0-10.10 -proposed tracker (LP: #2053015)
+  * Miscellaneous Ubuntu changes
+    - [Packaging] add Rust build-deps for riscv64
+  * Miscellaneous upstream changes
+    - Revert "Revert "UBUNTU: [Packaging] temporarily disable Rust dependencies on
+      riscv64""
+
+  [ Ubuntu: 6.8.0-9.9 ]
+
+  * noble/linux: 6.8.0-9.9 -proposed tracker (LP: #2052945)
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] temporarily disable Rust dependencies on
+      riscv64"
+
+  [ Ubuntu: 6.8.0-8.8 ]
+
+  * noble/linux: 6.8.0-8.8 -proposed tracker (LP: #2052918)
+  * Miscellaneous Ubuntu changes
+    - [Packaging] riscv64: enable linux-libc-dev build
+    - v6.8-rc4 rebase
+  * Rebase on v6.8-rc4
+
+  [ Ubuntu: 6.8.0-7.7 ]
+
+  * noble/linux: 6.8.0-7.7 -proposed tracker (LP: #2052691)
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [01/87]: LSM stacking v39: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [02/87]: LSM stacking v39: SM: Infrastructure
+      management of the sock security
+    - SAUCE: apparmor4.0.0 [03/87]: LSM stacking v39: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [04/87]: LSM stacking v39: IMA: avoid label collisions
+      with stacked LSMs
+    - SAUCE: apparmor4.0.0 [05/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [06/87]: LSM stacking v39: LSM: Add lsmblob_to_secctx
+      hook
+    - SAUCE: apparmor4.0.0 [07/87]: LSM stacking v39: Audit: maintain an lsmblob
+      in audit_context
+    - SAUCE: apparmor4.0.0 [08/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [09/87]: LSM stacking v39: Audit: Update shutdown LSM
+      data
+    - SAUCE: apparmor4.0.0 [10/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [11/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [12/87]: LSM stacking v39: Audit: use an lsmblob in
+      audit_names
+    - SAUCE: apparmor4.0.0 [13/87]: LSM stacking v39: LSM: Create new
+      security_cred_getlsmblob LSM hook
+    - SAUCE: apparmor4.0.0 [14/87]: LSM stacking v39: Audit: Change context data
+      from secid to lsmblob
+    - SAUCE: apparmor4.0.0 [15/87]: LSM stacking v39: Netlabel: Use lsmblob for
+      audit data
+    - SAUCE: apparmor4.0.0 [16/87]: LSM stacking v39: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [17/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [18/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_lsmblob_to_secctx
+    - SAUCE: apparmor4.0.0 [19/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [20/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [21/87]: LSM stacking v39: LSM:
+      security_lsmblob_to_secctx module selection
+    - SAUCE: apparmor4.0.0 [22/87]: LSM stacking v39: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [23/87]: LSM stacking v39: Audit: Allow multiple
+      records in an audit_buffer
+    - SAUCE: apparmor4.0.0 [24/87]: LSM stacking v39: Audit: Add record for
+      multiple task security contexts
+    - SAUCE: apparmor4.0.0 [25/87]: LSM stacking v39: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [26/87]: LSM stacking v39: Audit: Add record for
+      multiple object contexts
+    - SAUCE: apparmor4.0.0 [27/87]: LSM stacking v39: LSM: Remove unused
+      lsmcontext_init()
+    - SAUCE: apparmor4.0.0 [28/87]: LSM stacking v39: LSM: Improve logic in
+      security_getprocattr
+    - SAUCE: apparmor4.0.0 [29/87]: LSM stacking v39: LSM: secctx provider check
+      on release
+    - SAUCE: apparmor4.0.0 [31/87]: LSM stacking v39: LSM: Exclusive secmark usage
+    - SAUCE: apparmor4.0.0 [32/87]: LSM stacking v39: LSM: Identify which LSM
+      handles the context string
+    - SAUCE: apparmor4.0.0 [33/87]: LSM stacking v39: AppArmor: Remove the
+      exclusive flag
+    - SAUCE: apparmor4.0.0 [34/87]: LSM stacking v39: LSM: Add mount opts blob
+      size tracking
+    - SAUCE: apparmor4.0.0 [35/87]: LSM stacking v39: LSM: allocate mnt_opts blobs
+      instead of module specific data
+    - SAUCE: apparmor4.0.0 [36/87]: LSM stacking v39: LSM: Infrastructure
+      management of the key security blob
+    - SAUCE: apparmor4.0.0 [37/87]: LSM stacking v39: LSM: Infrastructure
+      management of the mnt_opts security blob
+    - SAUCE: apparmor4.0.0 [38/87]: LSM stacking v39: LSM: Correct handling of
+      ENOSYS in inode_setxattr
+    - SAUCE: apparmor4.0.0 [39/87]: LSM stacking v39: LSM: Remove lsmblob
+      scaffolding
+    - SAUCE: apparmor4.0.0 [40/87]: LSM stacking v39: LSM: Allow reservation of
+      netlabel
+    - SAUCE: apparmor4.0.0 [41/87]: LSM stacking v39: LSM: restrict
+      security_cred_getsecid() to a single LSM
+    - SAUCE: apparmor4.0.0 [42/87]: LSM stacking v39: Smack: Remove
+      LSM_FLAG_EXCLUSIVE
+    - SAUCE: apparmor4.0.0 [43/87]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0
+      [12/95]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [44/87]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [45/87]: add unpriviled user ns mediation
+    - SAUCE: apparmor4.0.0 [46/87]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [47/87]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [48/87]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [49/87]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [50/87]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/87]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/87]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/87]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [54/87]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [55/87]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [56/87]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [57/87]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [58/87]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [59/87]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [60/87]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [61/87]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [62/87]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [63/87]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [64/87]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [65/87] v6.8 prompt:fixup interruptible
+    - SAUCE: apparmor4.0.0 [69/87]: add io_uring mediation
+    - SAUCE: apparmor4.0.0 [70/87]: apparmor: fix oops when racing to retrieve
+      notification
+    - SAUCE: apparmor4.0.0 [71/87]: apparmor: fix notification header size
+    - SAUCE: apparmor4.0.0 [72/87]: apparmor: fix request field from a prompt
+      reply that denies all access
+    - SAUCE: apparmor4.0.0 [73/87]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+    - SAUCE: apparmor4.0.0 [74/87]: apparmor: cleanup attachment perm lookup to
+      use lookup_perms()
+    - SAUCE: apparmor4.0.0 [75/87]: apparmor: remove redundant unconfined check.
+    - SAUCE: apparmor4.0.0 [76/87]: apparmor: switch signal mediation to using
+      RULE_MEDIATES
+    - SAUCE: apparmor4.0.0 [77/87]: apparmor: ensure labels with more than one
+      entry have correct flags
+    - SAUCE: apparmor4.0.0 [78/87]: apparmor: remove explicit restriction that
+      unconfined cannot use change_hat
+    - SAUCE: apparmor4.0.0 [79/87]: apparmor: cleanup: refactor file_perm() to
+      provide semantics of some checks
+    - SAUCE: apparmor4.0.0 [80/87]: apparmor: carry mediation check on label
+    - SAUCE: apparmor4.0.0 [81/87]: apparmor: convert easy uses of unconfined() to
+      label_mediates()
+    - SAUCE: apparmor4.0.0 [82/87]: apparmor: add additional flags to extended
+      permission.
+    - SAUCE: apparmor4.0.0 [83/87]: apparmor: add support for profiles to define
+      the kill signal
+    - SAUCE: apparmor4.0.0 [84/87]: apparmor: fix x_table_lookup when stacking is
+      not the first entry
+    - SAUCE: apparmor4.0.0 [85/87]: apparmor: allow profile to be transitioned
+      when a user ns is created
+    - SAUCE: apparmor4.0.0 [86/87]: apparmor: add ability to mediate caps with
+      policy state machine
+    - SAUCE: apparmor4.0.0 [87/87]: fixup notify
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [66/87]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [67/87]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [68/87]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+
+  [ Ubuntu: 6.8.0-6.6 ]
+
+  * noble/linux: 6.8.0-6.6 -proposed tracker (LP: #2052592)
+  * Packaging resync (LP: #1786013)
+    - debian.master/dkms-versions -- update from kernel-versions
+      (main/d2024.02.07)
+    - [Packaging] update variants
+  * FIPS kernels should default to fips mode (LP: #2049082)
+    - SAUCE: Enable fips mode by default, in FIPS kernels only
+  * Fix snapcraftyaml.yaml for jammy:linux-raspi (LP: #2051468)
+    - [Packaging] Remove old snapcraft.yaml
+  * Azure: Fix regression introduced in LP: #2045069 (LP: #2052453)
+    - hv_netvsc: Register VF in netvsc_probe if NET_DEVICE_REGISTER missed
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Remove in-tree abi checks
+    - [Packaging] drop abi files with clean
+    - [Packaging] Remove do_full_source variable (fixup)
+    - [Packaging] Remove update-dkms-versions and move dkms-versions
+    - [Config] updateconfigs following v6.8-rc3 rebase
+    - [packaging] rename to linux
+    - [packaging] rebase on v6.8-rc3
+    - [packaging] disable signing for ppc64el
+  * Rebase on v6.8-rc3
+
+  [ Ubuntu: 6.8.0-5.5 ]
+
+  * noble/linux-unstable: 6.8.0-5.5 -proposed tracker (LP: #2052136)
+  * Miscellaneous upstream changes
+    - Revert "mm/sparsemem: fix race in accessing memory_section->usage"
+
+  [ Ubuntu: 6.8.0-4.4 ]
+
+  * noble/linux-unstable: 6.8.0-4.4 -proposed tracker (LP: #2051502)
+  * Migrate from fbdev drivers to simpledrm and DRM fbdev emulation layer
+    (LP: #1965303)
+    - [Config] enable simpledrm and DRM fbdev emulation layer
+  * Miscellaneous Ubuntu changes
+    - [Config] toolchain update
+  * Miscellaneous upstream changes
+    - rust: upgrade to Rust 1.75.0
+
+  [ Ubuntu: 6.8.0-3.3 ]
+
+  * noble/linux-unstable: 6.8.0-3.3 -proposed tracker (LP: #2051488)
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [43/87]: LSM stacking v39: UBUNTU: SAUCE: apparmor4.0.0
+      [12/95]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [44/87]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [45/87]: add unpriviled user ns mediation
+    - SAUCE: apparmor4.0.0 [46/87]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [47/87]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [48/87]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [49/87]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [50/87]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/87]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/87]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/87]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [54/87]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [55/87]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [56/87]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [57/87]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [58/87]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [59/87]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [60/87]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [61/87]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [62/87]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [63/87]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [64/87]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [69/87]: add io_uring mediation
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+  * apparmor restricts read access of user namespace mediation sysctls to root
+    (LP: #2040194)
+    - SAUCE: apparmor4.0.0 [73/87]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+  * AppArmor spams kernel log with assert when auditing (LP: #2040192)
+    - SAUCE: apparmor4.0.0 [72/87]: apparmor: fix request field from a prompt
+      reply that denies all access
+  * apparmor notification files verification (LP: #2040250)
+    - SAUCE: apparmor4.0.0 [71/87]: apparmor: fix notification header size
+  * apparmor oops when racing to retrieve a notification (LP: #2040245)
+    - SAUCE: apparmor4.0.0 [70/87]: apparmor: fix oops when racing to retrieve
+      notification
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [66/87]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [67/87]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [68/87]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor4.0.0 [01/87]: LSM stacking v39: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [02/87]: LSM stacking v39: SM: Infrastructure
+      management of the sock security
+    - SAUCE: apparmor4.0.0 [03/87]: LSM stacking v39: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [04/87]: LSM stacking v39: IMA: avoid label collisions
+      with stacked LSMs
+    - SAUCE: apparmor4.0.0 [05/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [06/87]: LSM stacking v39: LSM: Add lsmblob_to_secctx
+      hook
+    - SAUCE: apparmor4.0.0 [07/87]: LSM stacking v39: Audit: maintain an lsmblob
+      in audit_context
+    - SAUCE: apparmor4.0.0 [08/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [09/87]: LSM stacking v39: Audit: Update shutdown LSM
+      data
+    - SAUCE: apparmor4.0.0 [10/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [11/87]: LSM stacking v39: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [12/87]: LSM stacking v39: Audit: use an lsmblob in
+      audit_names
+    - SAUCE: apparmor4.0.0 [13/87]: LSM stacking v39: LSM: Create new
+      security_cred_getlsmblob LSM hook
+    - SAUCE: apparmor4.0.0 [14/87]: LSM stacking v39: Audit: Change context data
+      from secid to lsmblob
+    - SAUCE: apparmor4.0.0 [15/87]: LSM stacking v39: Netlabel: Use lsmblob for
+      audit data
+    - SAUCE: apparmor4.0.0 [16/87]: LSM stacking v39: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [17/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [18/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_lsmblob_to_secctx
+    - SAUCE: apparmor4.0.0 [19/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [20/87]: LSM stacking v39: LSM: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [21/87]: LSM stacking v39: LSM:
+      security_lsmblob_to_secctx module selection
+    - SAUCE: apparmor4.0.0 [22/87]: LSM stacking v39: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [23/87]: LSM stacking v39: Audit: Allow multiple
+      records in an audit_buffer
+    - SAUCE: apparmor4.0.0 [24/87]: LSM stacking v39: Audit: Add record for
+      multiple task security contexts
+    - SAUCE: apparmor4.0.0 [25/87]: LSM stacking v39: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [26/87]: LSM stacking v39: Audit: Add record for
+      multiple object contexts
+    - SAUCE: apparmor4.0.0 [27/87]: LSM stacking v39: LSM: Remove unused
+      lsmcontext_init()
+    - SAUCE: apparmor4.0.0 [28/87]: LSM stacking v39: LSM: Improve logic in
+      security_getprocattr
+    - SAUCE: apparmor4.0.0 [29/87]: LSM stacking v39: LSM: secctx provider check
+      on release
+    - SAUCE: apparmor4.0.0 [30/87]: LSM stacking v39: LSM: Single calls in
+      socket_getpeersec hooks
+    - SAUCE: apparmor4.0.0 [31/87]: LSM stacking v39: LSM: Exclusive secmark usage
+    - SAUCE: apparmor4.0.0 [32/87]: LSM stacking v39: LSM: Identify which LSM
+      handles the context string
+    - SAUCE: apparmor4.0.0 [33/87]: LSM stacking v39: AppArmor: Remove the
+      exclusive flag
+    - SAUCE: apparmor4.0.0 [34/87]: LSM stacking v39: LSM: Add mount opts blob
+      size tracking
+    - SAUCE: apparmor4.0.0 [35/87]: LSM stacking v39: LSM: allocate mnt_opts blobs
+      instead of module specific data
+    - SAUCE: apparmor4.0.0 [36/87]: LSM stacking v39: LSM: Infrastructure
+      management of the key security blob
+    - SAUCE: apparmor4.0.0 [37/87]: LSM stacking v39: LSM: Infrastructure
+      management of the mnt_opts security blob
+    - SAUCE: apparmor4.0.0 [38/87]: LSM stacking v39: LSM: Correct handling of
+      ENOSYS in inode_setxattr
+    - SAUCE: apparmor4.0.0 [39/87]: LSM stacking v39: LSM: Remove lsmblob
+      scaffolding
+    - SAUCE: apparmor4.0.0 [40/87]: LSM stacking v39: LSM: Allow reservation of
+      netlabel
+    - SAUCE: apparmor4.0.0 [41/87]: LSM stacking v39: LSM: restrict
+      security_cred_getsecid() to a single LSM
+    - SAUCE: apparmor4.0.0 [42/87]: LSM stacking v39: Smack: Remove
+      LSM_FLAG_EXCLUSIVE
+    - SAUCE: apparmor4.0.0 [65/87] v6.8 prompt:fixup interruptible
+    - SAUCE: apparmor4.0.0 [74/87]: apparmor: cleanup attachment perm lookup to
+      use lookup_perms()
+    - SAUCE: apparmor4.0.0 [75/87]: apparmor: remove redundant unconfined check.
+    - SAUCE: apparmor4.0.0 [76/87]: apparmor: switch signal mediation to using
+      RULE_MEDIATES
+    - SAUCE: apparmor4.0.0 [77/87]: apparmor: ensure labels with more than one
+      entry have correct flags
+    - SAUCE: apparmor4.0.0 [78/87]: apparmor: remove explicit restriction that
+      unconfined cannot use change_hat
+    - SAUCE: apparmor4.0.0 [79/87]: apparmor: cleanup: refactor file_perm() to
+      provide semantics of some checks
+    - SAUCE: apparmor4.0.0 [80/87]: apparmor: carry mediation check on label
+    - SAUCE: apparmor4.0.0 [81/87]: apparmor: convert easy uses of unconfined() to
+      label_mediates()
+    - SAUCE: apparmor4.0.0 [82/87]: apparmor: add additional flags to extended
+      permission.
+    - SAUCE: apparmor4.0.0 [83/87]: apparmor: add support for profiles to define
+      the kill signal
+    - SAUCE: apparmor4.0.0 [84/87]: apparmor: fix x_table_lookup when stacking is
+      not the first entry
+    - SAUCE: apparmor4.0.0 [85/87]: apparmor: allow profile to be transitioned
+      when a user ns is created
+    - SAUCE: apparmor4.0.0 [86/87]: apparmor: add ability to mediate caps with
+      policy state machine
+    - SAUCE: apparmor4.0.0 [87/87]: fixup notify
+    - [Config] updateconfigs following v6.8-rc2 rebase
+
+  [ Ubuntu: 6.8.0-2.2 ]
+
+  * noble/linux-unstable: 6.8.0-2.2 -proposed tracker (LP: #2051110)
+  * Miscellaneous Ubuntu changes
+    - [Config] toolchain update
+    - [Config] enable Rust
+
+  [ Ubuntu: 6.8.0-1.1 ]
+
+  * noble/linux-unstable: 6.8.0-1.1 -proposed tracker (LP: #2051102)
+  * Miscellaneous Ubuntu changes
+    - [packaging] move to v6.8-rc1
+    - [Config] updateconfigs following v6.8-rc1 rebase
+    - SAUCE: export file_close_fd() instead of close_fd_get_file()
+    - SAUCE: cpufreq: s/strlcpy/strscpy/
+    - debian/dkms-versions -- temporarily disable zfs dkms
+    - debian/dkms-versions -- temporarily disable ipu6 and isvsc dkms
+    - debian/dkms-versions -- temporarily disable v4l2loopback
+
+  [ Ubuntu: 6.8.0-0.0 ]
+
+  * Empty entry.
+
+  [ Ubuntu: 6.7.0-7.7 ]
+
+  * noble/linux-unstable: 6.7.0-7.7 -proposed tracker (LP: #2049357)
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+  * Miscellaneous Ubuntu changes
+    - [Packaging] re-enable signing for s390x and ppc64el
+
+  [ Ubuntu: 6.7.0-6.6 ]
+
+  * Empty entry.
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 27 Mar 2024 23:23:18 +0900
+
+linux-qcom (6.7.0-1012.12) jammy; urgency=medium
+
+  * [qcom alpha] Suppress noisy logs
+    - SAUCE: icnss2: supress noisy logs
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: update apply overlay application for pre-GA
+    - SAUCE: update graphics DT overlay to pre-GA
+    - SAUCE: update display DT overlay to pre-GA
+    - SAUCE: update camera overlay to pre-GA
+    - SAUCE: update bluetooth DT overlay to pre-GA
+    - SAUCE: update wlan DT overlay to pre-GA
+    - [config] Disable CONFIG_EFI_ZBOOT
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 21 Mar 2024 02:17:22 +0900
+
+linux-qcom (6.7.0-1011.11) jammy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: update wlan qclacld driver code to pre-GA
+    - SAUCE: update qcm6490 display code to pre-GA
+    - SAUCE: fix build warnings and errors in WLAN driver
+    - SAUCE: import qcm6490 graphics driver code
+    - SAUCE: dynamically allocate the kgsl-pool shrinker for kernel>=6.7
+    - SAUCE: change strtobool() to kstrtobool()
+    - SAUCE: update qcm6490 camera driver code to pre-GA
+    - SAUCE: use sizeof() instead of V4L2_SUBDEV_NAME_SIZE
+    - SAUCE: remove unused camera_banner
+    - Config: Update config after applying Pre-GA patches
+    - Packaging: Update module list after merging pre-ga patches
+
+  * Miscellaneous upstream changes
+    - QCLINUX: arm64: defconfig: qcom: Enable UVC/UAC related configs
+    - FROMGIT: scsi: ufs: qcom: Add support to Configure
+      PA_VS_CORE_CLK_40NS_CYCLES
+    - FROMLIST: iommu/arm-smmu: add ACTLR data and support for SC7280
+    - FROMLIST: iommu/arm-smmu: re-enable context caching in smmu reset operation
+    - PENDING: soundwire: qcom: add channel mask port configuration for soundwire
+      master
+    - PENDING: dt-bindings: soundwire: qcom: Document the port channel mask
+      property
+    - PENDING: arm64: dts: qcom: sc7280: add channel mask ports for tx soundwire
+    - FROMGIT: iio: adc: Add PM7325 PMIC7 ADC bindings
+    - PENDING: iris: fix LTR_COUNT configuration to firmware
+    - PENDING: i2c: i2c-qcom-geni: Add Multi EE feature support
+    - FROMLIST: dt-bindings: misc: qcom,dcc: Add the dtschema
+    - PENDING: ASoC: qcom: qcm6490: Fix clock freq for mi2s and tdm
+    - FROMLIST: misc: dcc: Add driver support for Data Capture and Compare
+      unit(DCC)
+    - PENDING: misc: fastrpc: Release PDR handle
+    - QCLINUX: arm64: configs: qcom: Enable TRACE_MMIO_ACCESS
+    - PENDING: arm64: dts: qcom: sc7280: Correct the compatible of dcc
+    - QCLINUX: arm64: defconfig: Enable DCC config
+    - QCLINUX: arm64: defconfig: qcom: Disable DEBUG_INFO_REDUCED
+    - PENDING: scsi: ufs: host: Bugfix evict key call in ufs host
+    - FROMLIST: soc: qcom: ice: support for hardware wrapped keys
+    - PENDING: iris: change the default value of HEADER_MODE config
+    - QCLINUX: ASoC: qcom: audio-pkt: avoid duplicate sysfs during ssr
+    - QCLINUX: ASoC: qcom: qdsp6: Add support to create CMA heap
+    - QCLINUX: soc: qcom: Implement a driver to write kaslr addr to imem
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Add reserved memory for audio ml
+    - QCLINUX: arm64: defconfig: Enable smp2p_sleepstate
+    - FROMGIT: dt-bindings: soc: qcom,aoss-qmp: document the SM8560 Always-On
+      Subsystem side channel
+    - FROMGIT: dt-bindings: interconnect: qcom-bwmon: document SM8650 BWMONs
+    - FROMGIT: dt-bindings: usb: qcom,dwc3: document the SM8560 SuperSpeed DWC3
+      USB controller
+    - FROMGIT: dt-bindings: dma: qcom,gpi: document the SM8650 GPI DMA Engine
+    - FROMGIT: dt-bindings: crypto: qcom,inline-crypto-engine: document the SM8650
+      ICE
+    - FROMGIT: dt-bindings: qcom,pdc: Add compatible for SM8550
+    - FROMGIT: arm64: dts: qcom: sm8550: add TRNG node
+    - FROMGIT: dt-bindings: qcom,pdc: document the SM8650 Power Domain Controller
+    - FROMGIT: dt-bindings: soc: qcom: pmic-glink: document SM8650 compatible
+    - FROMGIT: dt-bindings: crypto: qcom,prng: document SM8650
+    - FROMGIT: dt-bindings: firmware: qcom,scm: document SM8650 SCM Firmware
+      Interface
+    - FROMGIT: dt-bindings: iommu: arm,smmu: document the SM8650 System MMU
+    - FROMGIT: dt-bindings: thermal: qcom-tsens: document the SM8650 Temperature
+      Sensor
+    - FROMGIT: dt-bindings: clock: qcom: document the SM8650 TCSR Clock Controller
+    - FROMGIT: dt-bindings: clock: qcom: document the SM8650 General Clock
+      Controller
+    - FROMGIT: dt-bindings: clock: qcom: document the SM8650 Display Clock
+      Controller
+    - FROMGIT: dt-bindings: clock: qcom: document the SM8650 GPU Clock Controller
+    - FROMGIT: clk: qcom: add the SM8650 Global Clock Controller driver, part 1
+    - FROMGIT: clk: qcom: add the SM8650 Global Clock Controller driver, part 2
+    - FROMGIT: clk: qcom: add the SM8650 TCSR Clock Controller driver
+    - FROMGIT: clk: qcom: add the SM8650 Display Clock Controller driver
+    - FROMGIT: clk: qcom: add the SM8650 GPU Clock Controller driver
+    - FROMGIT: clk: qcom: rpmh: add clocks for SM8650
+    - FROMGIT: dt-bindings: interconnect: document the RPMh Network-On-Chip
+      Interconnect in Qualcomm SM8650 SoC
+    - FROMGIT: interconnect: qcom: introduce RPMh Network-On-Chip Interconnect on
+      SM8650 SoC
+    - FROMGIT: dt-bindings: cache: qcom,llcc: Document the SM8650 Last Level Cache
+      Controller
+    - FROMGIT: soc: qcom: llcc: Add configuration data for SM8650
+    - FROMGIT: drm/msm/dpu: enable smartdma on sm8350
+    - FROMGIT: drm/msm/dpu: enable SmartDMA on SM8450
+    - FROMGIT: drm/msm/dpu: populate SSPP scaler block version
+    - FROMGIT: drm/msm/dpu: Drop unused get_scaler_ver callback from SSPP
+    - FROMGIT: drm/msm/dpu: Drop unused qseed_type from catalog dpu_caps
+    - FROMGIT: drm/msm/dpu: drop the `id' field from DPU_HW_SUBBLK_INFO
+    - FROMGIT: drm/msm/dpu: drop the `smart_dma_priority' field from struct
+      dpu_sspp_sub_blks
+    - FROMGIT: drm/msm/dpu: deduplicate some (most) of SSPP sub-blocks
+    - FROMGIT: drm/msm/dpu: drop DPU_HW_SUBBLK_INFO macro
+    - FROMGIT: drm/msm/dpu: rewrite scaler and CSC presense checks
+    - FROMGIT: drm/msm/dpu: merge DPU_SSPP_SCALER_QSEED3, QSEED3LITE, QSEED4
+    - FROMGIT: drm/msm/gpu: drop duplicating VIG feature masks
+    - FROMGIT: dt-bindings: display: msm-dsi-phy-7nm: document the SM8650 DSI PHY
+    - FROMGIT: dt-bindings: display: msm-dsi-controller-main: document the SM8650
+      DSI Controller
+    - FROMGIT: dt-bindings: display: msm: document the SM8650 DPU
+    - FROMGIT: dt-bindings: display: msm: document the SM8650 Mobile Display
+      Subsystem
+    - FROMGIT: drm/msm/dpu: add support for SM8650 DPU
+    - FROMGIT: drm/msm: mdss: add support for SM8650
+    - FROMGIT: drm/msm: dsi: add support for DSI-PHY on SM8650
+    - FROMGIT: drm/msm: dsi: add support for DSI 2.8.0
+    - FROMGIT: dt-bindings: phy: qcom,sc8280xp-qmp-ufs-phy: document the SM8650
+      QMP UFS PHY
+    - FROMGIT: dt-bindings: phy: qcom,sc8280xp-qmp-pcie-phy: document the SM8650
+      QMP PCIe PHYs
+    - FROMGIT: dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy: document the
+      SM8650 QMP USB/DP Combo PHY
+    - FROMGIT: dt-bindings: phy: qcom,snps-eusb2: document the SM8650 Synopsys
+      eUSB2 PHY
+    - FROMGIT: phy: qcom: qmp-ufs: add QMP UFS PHY tables for SM8650
+    - FROMGIT: phy: qcom: qmp-pcie: add QMP PCIe PHY tables for SM8650
+    - FROMGIT: phy: qcom: qmp-combo: add QMP USB3/DP PHY tables for SM8650
+    - FROMGIT: dt-bindings: pinctrl: document the SM8650 Top Level Mode
+      Multiplexer
+    - FROMGIT: pinctrl: qcom: handle intr_target_reg wakeup_present/enable bits
+    - FROMGIT: pinctrl: qcom: sm8650-lpass-lpi: add SM8650 LPASS
+    - FROMGIT: pinctrl: qcom: Introduce the SM8650 Top Level Mode Multiplexer
+      driver
+    - FROMGIT: dt-bindings: arm: qcom,ids: Add SoC ID for SM8650
+    - FROMGIT: soc: qcom: socinfo: Add SM8650 SoC ID table entry
+    - FROMGIT: dt-bindings: arm: qcom: document SM8650 and the reference boards
+    - FROMGIT: arm64: dts: qcom: add initial SM8650 dtsi
+    - FROMGIT: arm64: dts: qcom: pm8550ve: make PMK8550VE SID configurable
+    - FROMGIT: arm64: dts: qcom: sm8650: add initial SM8650 MTP dts
+    - FROMGIT: arm64: dts: qcom: sm8650: add initial SM8650 QRD dts
+    - FROMGIT: arm64: dts: qcom: sm8650: add interconnect dependent device nodes
+    - FROMGIT: arm64: dts: qcom: sm8650-mtp: add interconnect dependent device
+      nodes
+    - FROMGIT: arm64: dts: qcom: sm8650-qrd: add interconnect dependent device
+      nodes
+    - FROMGIT: dt-bindings: clock: qcom: Document the SM8650 RPMH Clock Controller
+    - QCLINUX: ASoC: qcm6490: Initialize slimbus dais
+    - QCLINUX: arm64: dts: qcom: qcm6490-rb3: Add sound node for RB3 Gen2 nav mezz
+    - PENDING: videocc: enable HW_CTRL for mvs0 gdsc
+    - PENDING: iris: switch vcodec gdsc mode before handling vcodec clocks
+    - PENDING: arm64: dts: qcom: qcm6490-rb3g2: Add PCIe nodes
+    - QCLINUX: dt-bindings: pci: qps615: Add qps615 QCOM PCIe switch
+    - QCLINUX: arm64: dts: qcm6490-rb3: Add support for qps615 switch
+    - QCLINUX: pci: controller: misc: Add qcom qps615 switch driver
+    - QCLINUX: soc: qcom: Register a panic_notifier to cause wdt bite on panic
+    - PENDING: arm64: boot: dts: qcm6490: Add CMA heap for smcinvoke
+    - PENDING: soundwire: qcom: Add support for multiple sample rates
+    - PENDING: ASoC: codecs: lpass: Add macro and dcodec clock disable in suspend
+    - QCLINUX: arm64: defconfig: qcom: Enable CONFIG_SCHED_DEBUG
+    - PENDING: iris: fix bitrate mode setting to firmware
+    - PENDING: i2c: i2c-qcom-geni: Correct I2C TRE sequence
+    - QCLINUX: Revert "QCLINUX: soc: qcom: smcinvoke: Add hardcoded mem-buf API
+      values"
+    - PENDING: dt-bindings: phy: qcom,qmp: Add PCIe qcom,refclk-always-on property
+    - PENDING: phy: qcom-qmp-pcie: Add endpoint refclk control register offset
+    - BACKPORT: FROMGIT: dt-bindings: power: rpmpd: Update part number to X1E80100
+    - FROMGIT: pmdomain: qcom: rpmhpd: Update part number to X1E80100
+    - FROMGIT: dt-bindings: pinctrl: qcom: Add X1E80100 pinctrl
+    - FROMGIT: pinctrl: qcom: Add X1E80100 pinctrl driver
+    - BACKPORT: FROMGIT: dt-bindings: cache: qcom,llcc: Add X1E80100 compatible
+    - FROMGIT: dt-bindings: arm: qcom-soc: extend pattern for matching existing
+      SoCs
+    - FROMGIT: dt-bindings: arm: qcom-soc: extend pattern matching for X1E80100
+      SoC
+    - FROMGIT: dt-bindings: firmware: qcom,scm: document SCM on X1E80100 SoCs
+    - FROMGIT: dt-bindings: clock: qcom: Add X1E80100 GCC clocks
+    - FROMGIT: dt-bindings: clock: qcom-rpmhcc: Add RPMHCC bindings for X1E80100
+    - FROMGIT: clk: qcom: Add Global Clock controller (GCC) driver for X1E80100
+    - FROMGIT: clk: qcom: rpmh: Add support for X1E80100 rpmh clocks
+    - FROMGIT: dt-bindings: arm: cpus: Add qcom,oryon compatible
+    - FROMGIT: dt-bindings: arm: qcom: Document X1E80100 SoC and boards
+    - FROMGIT: dt-bindings: arm-smmu: Add compatible for X1E80100 SoC
+    - FROMGIT: dt-bindings: dma: qcom: gpi: add compatible for X1E80100
+    - FROMGIT: dt-bindings: interrupt-controller: qcom,pdc: document pdc on
+      X1E80100
+    - FROMGIT: dt-bindings: interconnect: Add Qualcomm X1E80100 SoC
+    - FROMGIT: interconnect: qcom: Add X1E80100 interconnect provider driver
+    - FROMGIT: arm64: dts: qcom: Add base X1E80100 dtsi and the QCP dts
+    - UPSTREAM: arm64: dts: qcom: x1e80100: Add Compute Reference Device
+    - QCLINUX: Add audio support for rb3gen2 video mezzanine boards
+    - PENDING: phy: qcom-qmp-pcie: Add support for keeping refclk always on
+    - QCLINUX: arm64: configs: qcom: Disable QCOM_FORCE_WDOG_BITE_ON_PANIC
+    - QCLINUX: arm64: configs: qcom: Enable QCOM_SOC_DEBUG driver
+    - Revert "QCLINUX: virt: gunyah: Write KASLR addr to IMEM"
+    - PENDING: Revert "PENDING: soc: qcom: smcinvoke: Add custom CMA heap support"
+    - PENDING: ASoC: qcom: q6dsp: Add support for multiple sample rates
+    - PENDING: i2c: i2c-qcom-geni: Add support to identify NACK in GSI Mode
+    - PENDING: pinctrl: qcom: lpass-lpi: Add suspend and resume runtime pm ops
+    - PENDING: arm64: dts: qcom: Enable support for pcie1 clocks on rb3 board
+    - QCLINUX: arm64: defconfig: qcom: Add support for NB7VPQ904M on AIM300
+    - QCLINUX: arm64: defconfig: qcom: Enable PCIe related configs
+    - QCLINUX: arm64: defconfig: qcom: Auto update configs
+    - QCLINUX: arm64: defconfig: qcom: Enable MODULE_SIG config
+    - PENDING: arm64: dts: qcom: Enable and update ipa to load gsi fw
+    - PENDING: drivers: smp2p: Add snapshot of smp2p_sleepstate driver
+    - PENDING: ARM: msm: Add support for smp2p_sleepstate
+    - QCLINUX: Revert "QCLINUX: arm64: dts: qcm6490-rb3: Add support for PM8008
+      PMIC"
+    - PENDING: firmware: shmbridge: Set dma capabilities 32bit by default
+    - PENDING: arm64: dts: qcom: qcm6490-addons: Enable smp2p-sleepstate
+    - PENDING: soc: qcom: qmi_encdec: out of bound check for input buffer
+    - PENDING: iris: configure work mode to STAGE 1 in CBR use case
+    - FROMLIST: arm64: dts: qcom: sc7280: Add additional MSI interrupts
+    - QCLINUX: soc: glink_altmode: Add API to notify hpd-irq & orientation
+    - PENDING: arm64: dts: qcom: sm8550: Add dma-coherent property
+    - QCLINUX: arm64: defconfig: qcom: Enable testmode config for QCM6490
+    - FROMGIT: arm64: dts: qcom: pm8550: drop PWM address/size cells
+    - FROMLIST: dt-bindings: arm: qcom: Document QCM8550, QCS8550 SoC and board
+    - FROMLIST: dt-bindings: arm: qcom,ids: add SoC ID for QCM8550 and QCS8550
+    - FROMLIST: soc: qcom: socinfo: add SoC Info support for QCM8550 and QCS8550
+      platform
+    - FROMGIT: ASoC: dt-bindings: qcom,sm8250: add SM8550 sound card
+    - FROMLIST: arm64: dts: qcom: qcm8550: introduce qcm8550 dtsi
+    - FROMLIST: arm64: dts: qcom: add base AIM300 dtsi
+    - FROMLIST: arm64: dts: qcom: aim300: add AIM300 AIoT
+    - FROMGIT: arm64: dts: qcom: sm8550: Add GPU nodes
+    - QCLINUX: arm64: defconfig: Add VM configs for qcm6490
+    - FROMLIST: misc: fastrpc: Mark all sessions as invalid in cb_remove
+    - PENDING: wil6210: Drop unicast sub frame if part of a multicast amsdu
+    - QCLINUX: arm64: defconfig: Add support for USB mouse&keyboard on AIM300
+    - QCLINUX: arm64: defconfig: Add qcom vm configs
+    - QCLINUX: dt-bindings: arm: qcom: Add X1E80100 addons support
+    - QCLINUX: arm64: defconfig: Add configs for Radar enumeration over USB
+    - QCLINUX: arm64: dts: qcm6490-idp: Add label for pmic-glink DT node
+    - PENDING: iris: replace dev_info with dev_dbg
+    - PENDING: iris: add support for dynamic resolution flag
+    - FROMLIST: media: v4l2-ctrls: add encoder maximum bitrate control
+    - QCLINUX: arm64: dts: Add x1e80100-addons CRD and QCP
+    - QCLINUX: arm64: defconfig: Enable X1E80100 base configs
+    - QCLINUX: arm64: defconfig: qcom: enable SM8550 GPUCC/CAMCC
+    - QCLINUX: arm64: dts: qcm6490-addons: Add label for pmic-glink DT node
+    - FROMGIT: soc: qcom: add ADSP PDCharger ULOG driver
+    - PENDING: soc: qcom: add snapshot for panel event notifier
+    - QCLINUX: arm64: defconfig: enable panel_event_notifier
+    - PENDING: iris: add new rate control type MBR for encoder
+    - QCLINUX: arm64: defconfig: qcom: enable flash led device
+    - PENDING: qcom: defconfig: enable module compilation of videoCC 8550
+    - PENDING: arm64: boot: dts: Add Support for nb7vpq904m on QCM6490 RB3
+    - QCLINUX: dt-bindings: arm: qcom: Add QCS8550 addons support
+    - PENDING:arm64:defconfig:add realtek config
+    - FROMLIST: phy: qcom: qmp-pcie: Update PCIe1 PHY settings for SM8550
+    - FROMLIST: arm64: dts: qcom: sm8550: Increase supported MSI interrupts
+    - FROMLIST: phy: qcom: qmp-pcie: Update PCIe0 PHY settings for SM8550
+    - FROMLIST: arm64: dts: qcom: aim300: Enable PCIe0 for WLAN
+    - PENDING: arm64: dts: qcom: aim300: Add smmu id for each BDF
+    - QCLINUX: arm64: dts: qcom: Add addons support for AIM300 AIOT
+    - QCLINUX: arm64: dts: qcom: aim300: Add support for qps615 switch
+    - PENDING: arm64: dts: qcom: qcs8550: overwrite video attribute in qcs8550
+    - PENDING: arm64: dts: qcom: sm8550: fix this issue of ICE HW generate key
+    - PENDING: arm64: dts: qcom: sm8550: add iris DT node
+    - FROMGIT: ufs: core: Add CPU latency QoS support for ufs driver
+    - QCLINUX: arm64: defconfig: Prune qcom_defconfig
+    - QCLINUX: arm64: defconfig: enable displayport config
+    - QCLINUX: arm64: dts: qcom: qcm6490-rb3: Add sound node for RB3 Gen2 video
+      mezz
+    - QCLINUX: dt-bindings: soc: qcom: Add secure buffer doc
+    - PENDING: slimbus: qcom-ngd-ctrl: Add null check for dma descriptor
+    - PENDING: slimbus: qcom-ngd-ctrl: Add timeout for wait operation
+    - QCLINUX: ASoC: codecs: msm-stub: Add input and output dapm widget
+    - QCLINUX: ASoC: qcom: qcm6490: Modify dapm routings for pinctrl widget
+    - QCLINUX: arm64: defconfig: qcom: Enable CEC support
+    - PENDING: arm64: dts: qcom: aim300: update PIL firmware path and name
+    - PENDING: arm64: dts: qcom: Disable the lpasscc node on qcm6490
+    - PENDING: dt-bindings: arm: qcom: Document rb5gen2-hdk board
+    - PENDING: arm64: dts: qcom: Add initial support for rb5gen2 SOM
+    - QCLINUX: arm64: dts: qcom: Add tz-log node
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Update the MI2S pinctrl name
+    - PENDING: arm64: dts: qcom: Add initial support for rb5gen2 HDK board
+    - QCLINUX: arm64: dts: qcom: Add board-id and msm-id for qcs8550-rb5gen2-HDK
+    - PENDING: iris: add to support max input buffer count
+    - PENDING: iris: update firmware path for SM8550
+    - FROMLIST: coresight: etm4x: Set skip_power_up in etm4_init_arch_data
+      function
+    - FROMGIT: coresight-tpdm: Remove the unnecessary lock
+    - FROMGIT: dt-bindings: arm: Add support for DSB element size
+    - FROMGIT: coresight-tpdm: Introduce TPDM subtype to TPDM driver
+    - FROMGIT: coresight-tpda: Add DSB dataset support
+    - FROMGIT: coresight-tpdm: Initialize DSB subunit configuration
+    - FROMGIT: coresight-tpdm: Add reset node to TPDM node
+    - FROMGIT: coresight-tpdm: Add nodes to set trigger timestamp and type
+    - FROMGIT: coresight-tpdm: Add node to set dsb programming mode
+    - PENDING: ASoC: dt-bindings: qcom,lpass-rx-macro: Document the rx_mclk muxsel
+      property
+    - PENDING: dt-bindings: soc: qcom: Add documentation for memory-dump
+    - FROMGIT: coresight-tpdm: Add nodes for dsb edge control
+    - FROMGIT: coresight-tpdm: Add nodes to configure pattern match output
+    - FROMGIT: coresight-tpdm: Add nodes for timestamp request
+    - FROMGIT: dt-bindings: arm: Add support for DSB MSR register
+    - FROMLIST: coresight: core: Add device name support
+    - FROMGIT: coresight-tpdm: Add nodes for dsb msr support
+    - FROMGIT: coresight-tpdm: Correct the property name of MSR number
+    - FROMLIST: coresight-tpdm: Optimize the store function of tpdm simple dataset
+    - FROMLIST: coresight-tpdm: Optimize the useage of tpdm_has_dsb_dataset
+    - FROMLIST: dt-bindings: arm: qcom,coresight-tpdm: Add support for CMB element
+      size
+    - FROMLIST: coresight-tpdm: Add CMB dataset support
+    - FROMLIST: coresight-tpda: Add support to configure CMB element
+    - FROMLIST: coresight-tpdm: Add support to configure CMB
+    - FROMLIST: coresight-tpdm: Add pattern registers support for CMB
+    - FROMLIST: coresight-tpdm: Add timestamp control register support for the CMB
+    - FROMLIST: dt-bindings: arm: qcom,coresight-tpdm: Add support for TPDM CMB
+      MSR register
+    - FROMLIST: coresight-tpdm: Add msr register support for CMB
+    - QCLINUX: arm64: defconfig: Align qcm6490 configs
+    - QCLINUX: arm64: defconfig: Enable zram for qcm6490
+    - QCLINUX: arm64: defconfig: Enable UIO for qcm6490
+    - PENDING: soundwire: stream: Skip asynchronous mode support
+    - PENDING: ASoC: codec: lpass-rx-macro: Add native sample rate headset
+      playback support
+    - PENDING: ASoC: qcom: q6dsp: Update channels and max rate for TDM
+    - QCLINUX: arm64: dts: qcom: qcm6490-rb3: Add MI2S Data1 line support
+    - QCLINUX: ASoC: qcom: qcm6490: Remove clock set in machine driver
+    - QCLINUX: ASoC: codecs: Update channels and sample rate for stub codec
+    - QCLINUX: drivers: soc: qcom: Add support for qcom secure buffer driver
+    - QCLINUX: drivers: dma-buf: heaps: Use hyp_assign_table implementation
+    - QCLINUX: arm64: configs: qcom: Enable secure buffer driver
+    - PENDING: ASoC: qcom: q6dsp: Add support for multiple sample rates
+    - PENDING: slimbus: qcom-ngd-ctrl: Reduce autosuspend delay to 100msec
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Disable drm gpu/gmu nodes
+    - PENDING: arm64: dts: qcom: qcm6490: Add vi-feedback dai-link for qcm6490 idp
+      & rb3 platform
+    - PENDING: ASoC: qcom: qcm6490: Add handling for WSA Codec DMA TX
+    - PENDING: dt-bindings: wsa883x: Document port mapping property
+    - PENDING: ASoC: wsa883x: Add Speaker Protection Support
+    - PENDING: soundwire: qcom: Update Port Reading logic from DT node
+    - PENDING: ASoC: wsa883x: Add Get temperature control
+    - FROMLIST: dt-bindings: arm: Add device-name in the coresight components
+    - PENDING: arm64: dts: qcom: Add label for timer node
+    - PENDING: Revert "silmbus: ngd: register controller after power up."
+    - PENDING: arm64: dts: qcom: qcm6490: Add rx-mclk and rx-npl clock support
+    - PENDING: soc: qcom: Add snapshot of memory dump driver
+    - PENDING: dt-bindings: soc: qcom: Add memory dump table bindings
+    - FROMLIST: soc: qcom: mdt_loader: Add Upperbounds check for program header
+      access
+    - PENDING: slimbus: qcom-ngd-ctrl: validate dma descriptor tx base address
+    - PENDING: gunyah: vm_mgr: Add lent memory
+    - PENDING: iris: fix sfr handling logic
+    - QCLINUX: arm64: defconfig: qcom: Enable USB Audio/MIDI driver
+    - PENDING: iris: fix logic to switch gdsc mode
+    - PENDING: slimbus: stream: Fix null pointer dereference of stream
+    - PENDING: slimbus: qcom-ngd-ctrl: Synchronize suspend/resume routine with
+      mutex
+    - PENDING: slimbus: qcom-ngd-ctrl: Return for channel disconnect/removal
+      during SSR
+    - PENDING: slimbus: qcom-ngd-ctrl: Handle race condition between SSR and qmi
+      request
+    - PENDING: slimbus: qcom-ngd-ctrl: Re-order platform driver registration
+    - PENDING: shmbridge/tz_log/smcinvoke: Adapt generic VMID/PERM entries
+    - PENDING: slimbus: qcom-ngd-ctrl: enable/disable ngd interrupt in runtime ops
+    - PENDING: slimbus: qcom-ngd-ctrl: Move qmi_handle_release to
+      QCOM_SSR_AFTER_SHUTDOWN
+    - PENDING: slimbus: qcom-ngd-ctrl: Avoid deadlock in SSR/PDR path
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Add the secure-buffer device
+    - PENDING: ASoC: codecs: lpass-va-macro: Add sleep after digitial unmute to
+      avoid pop issue
+    - PENDING: crypto: qce - Implement suspend/resume for crypto driver
+    - PENDING: slimbus: qcom-ngd-ctrl: Register QMI service once resources are
+      available
+    - PENDING: slimbus: qcom-ngd: Handle SSR and xfer message scenario
+    - UPSTREAM: regulator: qcom-rpmh: extend to support multiple linear voltage
+      ranges
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Add dummy msm_gpu node
+    - QCLINUX: arm64: dts: qcm6490-addons: Add nodes for memory dump
+    - QCLINUX: arm64: defconfig: Enable memory dump
+    - Revert "ASoC: codecs: wsa883x: make use of new mute_unmute_on_trigger flag"
+    - UPSTREAM: regulator: qcom-rpmh: add support for pm8010 regulators
+    - UPSTREAM: regulator: dt-bindings: qcom,rpmh: add compatible for pm8010
+    - PENDING: slimbus: qcom-ngd-ctrl: Return from cb if TX capability exchange
+      timeout
+    - QCLINUX: arm64: configs: qcom: Enable EFI_DISABLE_RUNTIME
+    - QCLINUX: ASoC: qcom: qdsp6: Cleanup APM during audio_pkt release
+    - PENDING: iris: fix min and max fps values in enum_frameintervals
+    - QCLINUX: arm64: dts: qcm6490-addons: Add label for typec-retimer
+    - PENDING: dt-bindings: soc: qcom: Replace "_" with "-" for memory dump
+    - FROMLIST: remoteproc: qcom: probe all child devices
+    - PENDING: misc: fastrpc: Fix memory corruption in DSP capabilities
+    - PENDING: iommu/arm-smmu-qcom: Fix use-after-free issue in qcom_smmu_create()
+    - QCLINUX: Revert "FROMLIST: sched/pelt: Introduce PELT multiplier"
+    - FROMLIST: sched/pelt: Introduce PELT multiplier
+    - FROMLIST: firmware/psci: Move psci_init_system_suspend() to late_initcall()
+    - FROMGIT: arm64: dts: qcom: sc7280: Add static properties to cryptobam
+    - QCLINUX: arm64: defconfig: Enable autosleep and wakelocks
+    - BACKPORT: FROMLIST: arm64: dts: qcom: sc7280: Add power-domains for cpuidle
+      states
+    - BACKPORT: FROMLIST: arm64: dts: qcom: sc7280: Update domain-idle-states for
+      cluster sleep
+    - PENDING: firmware: shmbridge: Defer probe if qcom_scm is not up
+    - Revert "PENDING: wil6210: Drop unicast sub frame if part of a multicast
+      amsdu"
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Sat, 16 Mar 2024 13:26:39 +0800
+
+linux-qcom (6.7.0-1010.10) jammy; urgency=medium
+
+  * Add camera driver
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Thu, 08 Feb 2024 10:48:07 +0900
+
+linux-qcom (6.7.0-1009.9) jammy; urgency=medium
+
+  * Enable display driver
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 07 Feb 2024 01:13:11 +0900
+
+linux-qcom (6.7.0-1008.8) jammy; urgency=medium
+
+  * Enable wlan driver
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Wed, 24 Jan 2024 14:53:34 +0900
+
+linux-qcom (6.7.0-1007.7) jammy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] sync
+    - Revert "arm64: dts: qcom: sc7280: Add power-domains for cpuidle states"
+
+ -- Masahiro Yamada <masahiro.yamada@canonical.com>  Tue, 16 Jan 2024 13:01:33 +0900
+
+linux-qcom (6.7.0-1005.5) jammy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: drivers: dma-buf: qcom: adjust shrinker since api changed
+    - SAUCE: firmware: qcom_scm: fix building error
+    - [Config]: enable kconfigs in the qcom_addons of alpha release
+    - [Packaging]: update abi after kconfig is changed
+
+ -- Hui Wang <hui.wang@canonical.com>  Sat, 13 Jan 2024 18:58:00 +0800
+
+linux-qcom (6.7.0-1004.4) jammy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config]: Update annotations after merge alpha patches
+    - [Packaging]: Update abi
+
+  * Miscellaneous upstream changes
+    - FROMLIST: dma-heap: Add proper kref handling on dma-buf heaps
+    - FROMLIST: dma-heap: Provide accessors so that in-kernel drivers can allocate
+      dmabufs from specific heaps
+    - QCLINUX: arm64: defconfig: qcom: Enable POWERCAP, IDLE_INJECT and
+      CPU_IDLE_THERMAL
+    - PENDING: arm64: dts: qcom: qcm6490: add fastrpc nodes
+    - PENDING: misc: fastrpc: Avoid ref count increment for invoke context
+    - PENDING: dt-bindings: soc: qcom,apr: Add audio-pkt and spf-core compatible
+      support
+    - PENDING: ASoC: dt-bindings: Add compatible for wcd9370 codec
+    - PENDING: arm64: dts: qcom: qcm6490: Add memory region for audioPD
+    - FROMLIST: soc: qcom: llcc: Fix dis_cap_alloc and retain_on_pc configuration
+    - FROMLIST: arm64: dts: qcom: sc7280: Add capacity and DPC properties
+    - FROMLIST: iommu: Allow passing custom allocators to pgtable drivers
+    - FROMLIST: iommu: Extend LPAE page table format to support custom allocators
+    - QCLINUX: dt-bindings: qcom: Add IMEM nodes
+    - PENDING: clk: qcom: camcc-sc7280: Add parent dependency to all camera GDSCs
+    - PENDING: dt-bindings: media: Add sm8550 dt schema
+    - PENDING: MAINTAINERS: Add Qualcomm Iris video accelerator driver
+    - PENDING: iris: register video device to platform driver
+    - PENDING: iris: initialize power resources
+    - PENDING: iris: introduce state machine for iris core
+    - PENDING: iris: introduce shared queues for host and firmware communication
+    - PENDING: iris: add PIL functionality for video firmware
+    - PENDING: iris: introduce packetization layer for creating HFI packets
+    - PENDING: iris: add video processing unit(VPU) specific register handling
+    - PENDING: iris: introduce platform specific capabilities for core and
+      instance
+    - PENDING: iris: implement iris v4l2 file ops
+    - PENDING: iris: add handling for interrupt service routine(ISR) invoked by
+      hardware
+    - PENDING: iris: implement iris v4l2_ctrl_ops and prepare capabilities
+    - PENDING: iris: introduce memory pool for buffer management
+    - PENDING: iris: implement vb2_ops queue setup
+    - PENDING: iris: introduce and implement iris vb2 mem ops
+    - PENDING: iris: implement HFI to queue and release buffers
+    - PENDING: iris: add video hardware internal buffer count and size calculation
+    - PENDING: iris: implement internal buffer management
+    - PENDING: iris: introduce instance states
+    - PENDING: iris: implement iris v4l2 ioctl ops supported by decoder
+    - PENDING: iris: subscribe input and output properties to firmware
+    - PENDING: iris: subscribe src change and handle firmware responses
+    - PENDING: iris: implement vb2 streaming ops on capture and output planes
+    - QCLINUX: arm64: configs: qcom: Enable QCOM_WDT_CORE
+    - QCLINUX: arm64: configs: qcom: Enable PANIC ON BITE
+    - QCLINUX: soc: qcom: Add support for watchdog framework
+    - PENDING: iris: implement vb2 ops for buf_queue and firmware response
+    - PENDING: iris: add instance sub states and implement DRC and Drain sequence
+    - PENDING: iris: implement power management
+    - FROMLIST: docs: gunyah: Introduce Gunyah Hypervisor
+    - FROMLIST: dt-bindings: Add binding for gunyah hypervisor
+    - FROMLIST: gunyah: Common types and error codes for Gunyah hypercalls
+    - FROMLIST: arm-smmu: Add iommu support to share pgtable
+    - PENDING: iris: register video encoder device to platform driver
+    - FROMLIST: virt: gunyah: Add hypercalls to identify Gunyah
+    - FROMLIST: virt: gunyah: msgq: Add hypercalls to send and receive messages
+    - FROMLIST: mailbox: Add Gunyah message queue mailbox
+    - FROMLIST: gunyah: rsc_mgr: Add resource manager RPC core
+    - FROMLIST: gunyah: rsc_mgr: Add VM lifecycle RPC
+    - FROMLIST: gunyah: vm_mgr: Introduce basic VM Manager
+    - FROMLIST: gunyah: rsc_mgr: Add RPC for sharing memory
+    - FROMLIST: gunyah: vm_mgr: Add/remove user memory regions
+    - FROMLIST: gunyah: vm_mgr: Add ioctls to support basic non-proxy VM boot
+    - FROMLIST: samples: Add sample userspace Gunyah VM Manager
+    - FROMLIST: gunyah: rsc_mgr: Add platform ops on mem_lend/mem_reclaim
+    - FROMLIST: virt: gunyah: Add Qualcomm Gunyah platform ops
+    - FROMLIST: docs: gunyah: Document Gunyah VM Manager
+    - FROMLIST: virt: gunyah: Translate gh_rm_hyp_resource into gunyah_resource
+    - FROMLIST: gunyah: vm_mgr: Add framework for VM Functions
+    - FROMLIST: virt: gunyah: Add resource tickets
+    - FROMLIST: virt: gunyah: Add IO handlers
+    - FROMLIST: virt: gunyah: Add proxy-scheduled vCPUs
+    - FROMLIST: virt: gunyah: Add hypercalls for sending doorbell
+    - FROMLIST: virt: gunyah: Add irqfd interface
+    - FROMLIST: virt: gunyah: Add ioeventfd
+    - FROMLIST: MAINTAINERS: Add Gunyah hypervisor drivers section
+    - PENDING: iris: add platform specific instance capabilities for encoder
+    - PENDING: iris: implement iris v4l2 ioctl ops supported by encoder
+    - PENDING: iris: add vb2 streaming and buffer ops for encoder
+    - PENDING: iris: add power management for encoder
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Add node for gh_watchdog
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Add node for IMEM
+    - QCLINUX: dt-bindings: watchdog: Add qcom,gh-watchdog
+    - QCLINUX: virt: gunyah: Gunyah virtual watchdog driver
+    - QCLINUX: virt: gunyah: Write KASLR addr to IMEM
+    - QCLINUX: arm64: configs: qcom: Enable GH_VIRT_WATCHDOG
+    - PENDING: misc: fastrpc: Redesign remote heap management
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: Disable wdt-sc7280
+    - PENDING: dt-bindings: media: Add qcm6490 dt schema
+    - PENDING: ASoC: dt-bindings: Add compatibles for qcm6490
+    - PENDING: arm64: dts: qcom: qcm6490: update venus node
+    - PENDING: qcom: defconfig: auto update of defconfig
+    - PENDING: qcom: defconfig: enable module compilation of iris
+    - PENDING: videocc: remove HW_CTRL from mvs0 gdsc
+    - FROMLIST: scsi: ufs: qcom: dt-bindings: Add SC7280 compatible string
+    - PENDING: iris: change interconnect name and correct few api
+    - PENDING: iris: add qcm6490 platform support
+    - PENDING: iris: add internal buffer calculation for iris2
+    - PENDING: iris: add power up/down sequence and bandwidth calculation
+    - FROMLIST: stm: class: Add MIPI OST protocol support
+    - PENDING: arm64: dts: qcom: qcm6490: Enable remoteprocs for RB3 Gen2
+    - FROMLIST: MAINTAINERS: Add the entry for DCC(Data Capture and Compare)
+      driver support
+    - PENDING: regulator: add a regulator driver for the PM8008 PMIC
+    - QCLINUX: drivers: regulator: Add snapshot of qpnp-lcdb regulator driver
+    - QCLINUX: mfd: introduce I2C PMIC controller
+    - FROMLIST: arm64: dts: qcom: sc7280: Add slimbus DT node
+    - QCLINUX: arm64: defconfig: disable display configs
+    - PENDING: ASoC: qcom: qcm6490: Add machine driver
+    - PENDING: arm64: dts: Increase min voltage of l1b and l10c rails
+    - QCLINUX: arm64: configs: Sort entries in qcom_addons
+    - QCLINUX: regulator: add debug control library
+    - QCLINUX: regulator: add proxy consumer library
+    - FROMGIT: arm64: dts: qcom: sc7280: add TRNG node
+    - QCLINUX: dt-bindings: arm: qcom: Add QCM6490 addons support
+    - QCLINUX: arm64: dts: qcom: qcm6490: Add addons support for RB3
+    - PENDING: arm64: qcom: dts: Enable pmk8350 RTC for qcm6490-idp
+    - PENDING: arm64: dts: qcom: sc7280: Add cti nodes
+    - PENDING: arm64: dts: qcom: qcm6490: overwrite video attribute in qcm6490
+    - QCLINUX: defconfig: Enable qcom-wled & qpnp-lcdb-regulator for qcm6490
+    - QCLINUX: pinctrl: qcom: spmi-gpio: Add PM7325b support
+    - PENDING: iris: update video firmware path for qcm6490
+    - QCLINUX: backlight: qcom-wled: Add support for PM7325b compatible
+    - QCLINUX: dt-bindings: backlight: qcom-wled: Add PM7325B support
+    - QCLINUX: arm64: dts: qcom: Add support for PM7325b PMIC
+    - QCLINUX: soc: qcom: apr: GPR support for audioreach solution
+    - PENDING: ASoC: codecs: lpass-macro: Add support for channel map mixer
+      control
+    - PENDING: ASoC: codecs: wcd937x: Add wcd937x codec driver
+    - PENDING: ASoC: dt-bindings: Add property to support cpu dai with dummy ops
+    - FROMLIST: dma-buf: heaps: Introduce cma_heap_add() for non-default CMA heap
+    - FROMLIST: drm/drm_mode_object: increase max objects to accommodate new color
+      props
+    - PENDING: arm64: qcom: dts: qcm6490-idp: Add BT node
+    - PENDING: misc: fastrpc: Fix DSP capabilities request
+    - PENDING: arm64: dts: qcom: qcm6490-idp: Add definition for three LEDs
+    - PENDING: arm64: qcom: dts: Support refgen regulator for qcm6490
+    - FROMGIT: scsi: ufs: ufs-sysfs: Expose UFS power info
+    - QCLINUX: defconfig: Enable LEICA regulator and proxy-consumer
+    - QCLINUX: defconfig: Enable refgen regulator for qcm6490
+    - PENDING: arm64: qcom: dts: qcm6490-rb3: Add BT node
+    - PENDING: arm64: dts: qcom: qcm6490-idp: add die temp ADC channel
+    - PENDING: defconfig: enable VADC, LPG and SPMI-TEMP-ALARM driver
+    - QCLINUX: ASoC: dt-bindings: qcom,spf-core-platform: Add msm audio mem for
+      spf core platform
+    - FROMLIST: iommu/arm-smmu: introduction of ACTLR for custom prefetcher
+      settings
+    - FROMLIST: iommu/arm-smmu: add ACTLR data and support for SM8550
+    - PENDING: ASoC: qcom: qdsp6: Add support for cpu dai with dummy ops
+    - PENDING: arm64: dts: qcom: qcm6490: Add gpr device tree node for ADSP
+    - QCLINUX: ASoC: qcom: qdsp6: Add spf-core, audio-pkt and msm-audio driver
+      support
+    - PENDING: arm64: dts: qcom: qcm6490-addons: Add shmbridge node
+    - PENDING: firmware: qcom: Add tz_log debug driver support
+    - PENDING: dt-bindings: firmware: Add tz-log doc
+    - PENDING: dt-bindings: soc: qcom: Add shmbridge doc
+    - PENDING: arm64: dts: qcom: qcm6490-addons: Add tz-log node
+    - PENDING: firmware: shmbridge: Add new driver support
+    - PENDING: arm64: dts: qcom: qcm6490: Add WSA codec macro for qcm6490 SoC
+    - PENDING: arm64: qcom: dts: qcm6490-rb3: Add remoteproc nodes
+    - QCLINUX: remoteproc: qcom: pas: disable auto boot for wpss
+    - PENDING: Bluetooth: hci_qca: Set BDA quirk bit if fwnode exists in DT
+    - PENDING: arm64: dts: qcom: qcm6490-idp: Add wcd9370 codec device tree node
+    - QCLINUX: arm64: dts: qcom: Add support for PM8008 PMIC
+    - QCLINUX: arm64: dts: qcom: Add PM7325b PMIC support for qcm6490-idp
+    - QCLINUX: arm64: defconfig: Enable QDSS configs
+    - QCLINUX: arm64: defconfig: qcom: Enable BT_RFCOMM
+    - QCLINUX: dt-bindings: arm: msm: Add remote debugger doc
+    - FROMLIST: usb: dwc3: qcom: Rename dwc3 platform_device reference
+    - FROMLIST: usb: dwc3: qcom: Merge resources from urs_usb device
+    - FROMLIST: usb: dwc3: Expose core driver as library
+    - FROMLIST: usb: dwc3: Override end of dwc3 memory resource
+    - FROMLIST: usb: dwc3: qcom: Add dwc3 core reference in driver state
+    - FROMLIST: usb: dwc3: qcom: Instantiate dwc3 core directly
+    - FROMLIST: usb: dwc3: qcom: Inline the qscratch constants
+    - QCLINUX: arm64: defconfig: qcom: Add USB defconfigs in qcom_defconfig
+    - FROMLIST: usb: dwc3: qcom: Flatten the Qualcomm dwc3 binding and
+      implementation
+    - FROMLIST: usb: dwc3: core: Register vendor hooks for dwc3-qcom
+    - FROMLIST: usb: dwc3: qcom: Enable autosuspend for host mode
+    - FROMLIST: usb: dwc3: core: Skip set_mode notification if cable is
+      disconnected
+    - PENDING: arm64: dts: qcom: qcm6490-idp: Enable pmic-glink and clients
+    - PENDING: arm64: dts: qcom: qcm6490: Add VMID for adsp mem heap
+    - FROMLIST: dt-bindings: input: qcom,pm8xxx-vib: add new SPMI vibrator module
+    - QCLINUX: drivers: char: add remote debugger driver
+    - PENDING: arm64: dts: qcom: qcm6490-idp: enable pon_key and pon_resin key
+    - QCLINUX: arm64: defconfig: Enable Audio support configs for QCM6490
+    - PENDING: arm64: dts: qcom: Flatten USB DT node for QCM6490
+    - PENDING: arm64: boot: dts: Add Type-c orientation support for QCM6490 IDP
+    - QCLINUX: arm64: dts: qcom: qcm6490: Add dt nodes for audio memory, audio-pkt
+      router and spf
+    - PENDING: arm64: dts: qcom: qcm6490-rb3: add die temp ADC channel
+    - PENDING: arm64: dts: qcom: qcm6490-rb3: Add definition for three LEDs
+    - PENDING: arm64: dts: qcom: qcm6490-idp: Add sound node for qcm6490 idp
+      platform
+    - PENDING: arm64: dts: qcom: qcm6490-rb3: Add sound node for RB3 Gen2
+    - PENDING: misc: fastrpc: Add support for unsigned PD
+    - PENDING: arm64: dts: qcm6490-idp: orientation-gpio support in pmic-glink
+    - QCLINUX: dt-bindings: qcom: Add msm stub audio codec documentation
+    - QCLINUX: arm64: dts: qcom: Add bindings for qcom-i2c-pmic and PM8008 devices
+    - FROMLIST: input: pm8xxx-vib: refactor to easily support new SPMI vibrator
+    - QCLINUX: arm64: defconfig: Add RDBG support for qcom_addons_debug
+    - PENDING: misc: fastrpc: Add static PD restart support
+    - PENDING: arm64: dts: qcom: qcm6490-rb3: Enable pmic-glink and clients
+    - QCLINUX: arm64: dts: qcm6490-rb3: Add support for PM8008 PMIC
+    - PENDING: dt-bindings: soc: qcom: Add mem-buf doc
+    - PENDING: drivers: soc: qcom: Add mem_buf driver support
+    - QCLINUX: arm64: configs: qcom: Enable QTEE_SHM_BRIDGE
+    - QCLINUX: arm64: configs: qcom: Enable CONFIG_QTI_TZ_LOG
+    - PENDING: firmware: shmbridge: Drop KP memory protection
+    - QCLINUX: arm64: configs: qcom: Enable PANIC_ON_OOPS
+    - FROMLIST: input: pm8xxx-vibrator: add new SPMI vibrator support
+    - PENDING: arm64: dts: qcom: qcm6490: Add mem-buf device nodes
+    - QCLINUX: arm64: defconfig: qcom: Enable mem-buf
+    - PENDING: dt-bindings: arm: msm: Add dmabuf heaps doc
+    - QCLINUX: drivers: dma-buf: Add QCOM Heaps
+    - FROMLIST: dt-bindings: iommu: Add Translation Buffer Unit bindings
+    - BACKPORT: FROMLIST: iommu/arm-smmu-qcom: Add support for TBUs
+    - FROMLIST: iommu/arm-smmu-qcom: Add Qualcomm TBU driver
+    - PENDING: iris: Fix copy of vb2 buf details to iris buf
+    - PENDING: misc: fastrpc: Pass proper arguments to scm call
+    - QCLINUX: drivers: dma-buf: heaps: Remove support for unused heaps and add
+      replacement for hyp_assign_table api
+    - QCLINUX: dt-bindings: arm: qcom: Add dt-bindings soft link for devicetree
+      constants
+    - FROMLIST: iommu/arm-smmu: Allow using a threaded handler for context
+      interrupts
+    - BACKPORT: FROMLIST: iommu/arm-smmu-qcom: Use a custom context fault handler
+      for sdm845
+    - PENDING: arm64: dts: qcom: sc7280: Add TBU support
+    - PENDING: arm64: dts: qcom: qcm6490-rb3: enable pon_key pon_resin & rtc
+    - QCLINUX: arm64: defconfig: qcom: Enable TBU support
+    - PENDING: iris: add support to set MAX input buffer count to firmware
+    - QCLINUX: dt-bindings: arm: qcom: Correct the symlink for
+      qcom_dma_heap_dt_constants
+    - QCLINUX: arm64: dts: qcom: qcm6490: Add dma-buf heaps support
+    - QCLINUX: arm64: defconfig: qcom: Enable QCOM Heaps
+    - PENDING: arm64: dts: qcom: qm6490-addons: Add smcinvoke node
+    - PENDING: dt-bindings: firmware: Add smcinvoke doc
+    - QCLINUX: defconfig: Enable ufs bsg node
+    - PENDING: iris: add cache management operation
+    - PENDING: dt-bindings: firmware: smcinvoke: Add memory-region
+    - PENDING: arm64: dts: qcm6490: Add memory-region for smcinvoke
+    - PENDING: dt-bindings: interconnect: Add QCOM_ICC_TAG_PERF_MODE macro
+    - FROMGIT: dt-bindings: phy: Add QMP UFS PHY comptible for SC7280
+    - PENDING: soc: qcom: Add smcinvoke driver support
+    - PENDING: soc: qcom: smcinvoke: Add custom CMA heap support
+    - PENDING: interconnect: qcom: Add support for PERF_MODE on RPMh targets
+    - QCLINUX: arm64: configs: qcom: Enable QCOM_SMCINVOKE
+    - PENDING: arm64: dts: qcom: qcm6490: Add dma-coherent property
+    - PENDING: interconnect: qcom: icc-rpmh: Add QoS config support
+    - PENDING: interconnect: qcom: sc7280: enable qos programming
+    - PENDING: arm64: dts: qcm6490-rb3: Increase min voltage of l1b & l10c rail
+    - PENDING: usb: dwc3: qcom: De-assert BCR upon resume
+    - PENDING: arm64: dts: qcom: sc7280: Add clocks for QOS programming
+    - QCLINUX: arm64: dts: qcom: qcm6490-idp: Add MI2S and TDM dai-link support
+    - PENDING: ASoC: qdsp6: q6apm: Add mi2s and tdm audio support
+    - PENDING: dt-bindings: Document the qcom,prmcc_clk property
+    - QCLINUX: ASoC: codecs: Add msm stub codec for audio usecase
+    - PENDING: iris: update output crop offset calculation for encoder
+    - QCLINUX: arm64: defconfig: qcom: Enable MSM_STUB config for QCM6490
+    - QCLINUX: arm64: dts: qcom: qcm6490-addons: add rdbg nodes
+    - FROMLIST: blk-crypto: add basic hardware-wrapped key support
+    - FROMLIST: blk-crypto: show supported key types in sysfs
+    - FROMLIST: blk-crypto: add ioctls to create and prepare hardware-wrapped keys
+    - PENDING: arm64: dts: qcom: sc7280: add ICE node
+    - QCLINUX: dt-bindings: pinctrl: qcom-pmic-gpio: Add pm7325b support
+    - FROMLIST: dt-bindings: crypto: ice: document the hwkm property
+    - PENDING: arm64: dts: qcm6490-rb3: Add LDO vibrator support
+    - QCLINUX: defconfig: Enable ldo vibrator driver config for qcm6490
+    - QCLINUX: arm64: defconfig: qcom: enable ICE driver
+    - QCLINUX: remoteproc: qcom: pas: Enable auto boot for wpss
+    - PENDING: ASoC: qcom: qdsp6: q6prm: Update the TDM clock id values
+    - QCLINUX: arm64: dts: qcom: qcm6490-rb3: Add MI2S and TDM dai-link support
+    - PENDING: misc: fastrpc: Add rpdev check in device_open
+    - FROMLIST: fscrypt: add support for hardware-wrapped keys
+    - FROMLIST: ice, ufs, mmc: use blk_crypto_key for program_key
+    - FROMLIST: qcom_scm: scm call for deriving a software secret
+    - FROMLIST: soc: qcom: ice: add hwkm support in ice
+    - FROMLIST: soc: qcom: ice: support for hardware wrapped keys
+    - QCLINUX: firmware: qcom_scm_addon: Add function qcom_scm_spin_cpu
+    - FROMLIST: ufs: core: support wrapped keys in ufs core
+    - FROMLIST: ufs: host: wrapped keys support in ufs qcom
+    - FROMGIT: dt-bindings: crypto: qcom-qce: document the SM8650 crypto engine
+    - FROMLIST: rpmsg: glink: smem: validate index before fifo read write
+    - PENDING: iris: update set bitrate api
+    - QCLINUX: arm64: defconfig: qcom: enable CRYPTO_USER_API
+    - FROMLIST: dt-bindings: crypto: qcom-qce: document the SC7280 crypto engine
+    - FROMLIST: arm64: dts: qcom: sc7280: add QCrypto nodes
+    - PENDING: iris: fix checks while handling the output buffers
+    - FROMLIST: qcom_scm: scm call for create, prepare and import keys
+    - FROMLIST: ufs: core: add support for generate, import and prepare keys
+    - FROMLIST: soc: qcom: support for generate, import and prepare key
+    - FROMLIST: ufs: host: support for generate, import and prepare key
+    - QCLINUX: arm64: defconfig: qcom: Enable KPROBE
+    - PENDING: iris: replace do_div with div64_u64
+    - PENDING: iris: fix rotation angle configuration to firmware
+    - QCLINUX: dt-bindings: arm: Add mezz board support on QCM6490
+    - PENDING: dt-bindings: arm: qcom: Add rb3gen2 mezzanine board support on
+      QCM6490
+    - PENDING: arm64: dts: qcom: Add qcm6490 rb3gen2 mezzanine board support
+    - FROMLIST: sched/pelt: Introduce PELT multiplier
+    - PENDING: wil6210: Drop plaintext frames on secure network
+    - PENDING: wil6210: check integrity of received AMSDU packets
+    - QCLINUX: arm64: dts: qcom: qcm6490: Add rb3gen2 board support
+    - QCLINUX: remoteproc: Panic on remoteproc crash
+    - QCLINUX: Add audio support for rb3gen2 vision mezzanine boards
+    - PENDING: arm64: dts: qcom: Flatten USB DT node on QCM6490 RB3 Platform
+    - PENDING: arm64: boot: dts: Add Type-c orientation support for QCM6490 RB3
+    - PENDING: firmware: qcom_scm: Make smcinvoke scm calls non-atomic
+    - PENDING: soc: qcom: ice: fix return value as per qcom-scm driver change
+    - PENDING: soc: qcom: ice: bugfix for HWKMv1 targets
+    - PENDING: firmware: qcom_smc-smc: Use qtee_shmbridge if available
+    - PENDING: include: linux: qtee_shmbridge: Add additional stubs
+    - PENDING: usb: dwc3: Add vendor hook for run_stop notification
+    - PENDING: arm64: dts: qcm6490-rb3: Update compatible string of pmic-glink
+    - PENDING: iris: add bit depth source change event for avc decoder
+    - QCLINUX: soc: qcom: smcinvoke: Add hardcoded mem-buf API values
+    - FROMLIST: soc: qcom: ice: bugfix for HWKMv1 targets
+    - FROMLIST: firmware: qcom_scm: scm call for deriving a software secret
+    - PENDING: firmware: qcom_scm: add FBE SCM calls with shmbridge
+    - QCLINUX: drivers: dmabuf: heaps: Remove alias for qcom system heap
+    - PENDING: iris: fix out of boundary hfi queue access
+    - QCLINUX: arm64: defconfig: Prune qcom_defconfig
+    - Revert "arm64: dts: qcom: sc7280: switch USB+DP QMP PHY to new style of
+      bindings"
+    - PENDING: arm64: dts: qcom: Add remote endpoints for QMP and USB nodes
+    - Revert "PENDING: wil6210: Drop plaintext frames on secure network"
+    - Revert "PENDING: wil6210: check integrity of received AMSDU packets"
+
+ -- Hui Wang <hui.wang@canonical.com>  Thu, 11 Jan 2024 14:22:29 +0800
+
+linux-qcom (6.7.0-1003.3) jammy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] remove helper scripts
+
+  * Miscellaneous Ubuntu changes
+    - Config: fix the environment for building in jammy
+    - [Packaging]: Update getabis for jammy
+    - [Config]: update annotations
+    - [Config]: Update config after cranky close
+    - [Packaging]: Update modules
+
+ -- Hui Wang <hui.wang@canonical.com>  Wed, 10 Jan 2024 22:28:08 +0800
+
+linux-qcom (6.7.0-1001.1) jammy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update Ubuntu.md
+    - [Packaging] update update.conf
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Init linux-qcom kernel creation
+    - Config: compose the init kconfig for linux-qcom
+    - [Packaing] adjust kernel modules
+    - Config: cleanup by running check-config
+
+  * Miscellaneous upstream changes
+    - QCLINUX: arm64: defconfig: Add qcom configs
+    - QCLINUX: arm64: dts: qcom: qcm6490: Add qcm6490 board support
+    - QCLINUX: arm64: defconfig: Enable dmabuf heaps for qcm6490
+    - QCLINUX: arm64: defconfig: qcom: Enable FTRACE
+    - QCLINUX: arm64: defconfig: Add DWC3_QCOM support in qcom_defconfig
+    - QCLINUX: arm64: defconfig: qcom: Enable zram
+    - QCLINUX: Revert "QCLINUX: arm64: dts: qcom: qcm6490: Add qcm6490 board
+      support"
+    - FROMLIST: arm64: dts: qcom: Add qcm6490 dts file
+    - QCLINUX: arm64: dts: qcom: Add qcm6490 addons support
+    - QCLINUX: arm64: dts: qcom: Add board-id and msm-id for QCM6490
+    - FROMLIST: dt-bindings: arm: qcom: Add QCM6490 IDP board
+    - PENDING: arm64: dts: qcom: Remove voltage vote support for UFS
+    - QCLINUX: arm64: defconfig: Enable Config for Phy and Controller
+    - PENDING: arm64: dts: qcm6490: Remove voltage voting for USB rails
+    - QCLINUX: arm64: dts: qcom: qcm6490: disable sdhc1 for ufs target
+    - QCLINUX: arm64: defconfig: Enable memory features
+    - FROMLIST: arm64: dts: qcom: sc7280: Add UFS nodes for sc7280 soc
+    - PENDING: arm64: dts: qcom: qcm6490: Add UFS nodes
+    - QCLINUX: arm64: defconfig: qcom: Enable SLAB_FREELIST_RANDOM
+    - QCLINUX: arm64: defconfig: qcom: Enable FORTIFY_SOURCE
+    - QCLINUX: arm64: dts: qcom: qcm6490: FIX: qcm6490 addons
+    - QCLINUX: arm64: defconfig: qcom: Disable DEVMEM and STRICT_DEVMEM
+    - PENDING: remoteproc: qcom: pas: Add ADSP, CDSP and WPSS support on SC7280
+      SoC
+    - PENDING: arm64: dts: qcom: qcm6490: Add ADSP, CDSP remoteproc support
+    - PENDING: arm64: dts: qcom: qcm6490: Update WPSS node to use PAS
+    - PENDING: dt-bindings: remoteproc: qcom: Add SC7280 ADSP, CDSP and WPSS
+      support
+    - PENDING: arm64: dts: qcom: qcm6490: Enable ADSP, CDSP, MPSS and WPSS support
+    - QCLINUX: arm64: defconfig: qcom: Enable SECURITY_SELINUX and
+      SECURITY_NETWORK
+    - QCLINUX: arm64: defconfig: qcom: Enable HARDENED_USERCOPY
+    - QCLINUX: arm64: defconfig: qcom: Enable SLAB_FREELIST_HARDENED
+    - QCLINUX: arm64: defconfig: qcom: Enable ARM64_SW_TTBR0_PAN
+    - PENDING: clk: qcom: gcc: Enable the force mem core for UFS ICE clock
+    - PENDING: arm64: dts: qcom: qcm6490: Add gpio-reserved-ranges
+    - FROMGIT: misc: fastrpc: Free DMA handles for RPC calls with no arguments
+    - PENDING: dt-bindings: clock: Add "qcom,adsp-skip-pll" property
+    - PENDING: clk: qcom: lpassaudiocc: Add support to skip PLL configuration
+    - QCLINUX: firmware: qcom_scm: provisioning addon scm call
+    - QCLINUX: arm64: defconfig: qcom: Auto update configs
+    - PENDING: dt-bindings: arm: qcom: Add QCM6490 RB3 board
+    - PENDING: arm64: dts: qcom: Add qcm6490 rb3 support
+    - QCLINUX: arm64: dts: qcom: Add board-id and msm-id for qcm6490-rb3
+    - PENDING: arm64: dts: qcm6490: Update the protected clocks for QCM6490
+    - QCLINUX: arm64: defconfig: Add clock controller configs for SC7280
+    - QCLINUX: arm64: configs: qcom: Disable CONFIG_QCOM_WDT
+    - FROMGIT: misc: fastrpc: Clean buffers on remote invocation failures
+    - QCLINUX: arm64: configs: qcom: Enable QCOM_SCM_ADDON
+    - QCLINUX: arm64: defconfig: qcom: Enable UCLAMP and SCHEDSTATS
+    - PENDING: arm64: dts: qcom: Remove voltage vote support for UFS
+    - PENDING: arm64: dts: qcm6490-rb3: Remove voltage voting for USB rails
+    - PENDING: arm64: dts: qcom: Add UFS nodes for qcm6490-rb3
+    - PENDING: arm64: dts: qcom: qcm6490: add phandle & modify adsp node
+    - PENDING: arm64: dts: qcom: sc7280: Add interconnect paths to UFSHC
+    - QCLINUX: arm64: defconfig: qcom: Enable bootconfig
+    - PENDING: arm64: dts: qcom: qcm6490: update memory map
+    - FROMLIST: arm64: dts: qcom: Update memorymap for qcm6490
+    - QCLINUX: arm64: dts: qcom: qcm6490: disable video fw attribute in qcm6490
+
+ -- Hui Wang <hui.wang@canonical.com>  Fri, 15 Dec 2023 08:12:34 +0800
+
+linux-qcom (6.7.0-1000.0) jammy; urgency=medium
+
+  * Init creation of linux-qcom
+
+ -- Hui Wang <hui.wang@canonical.com>  Wed, 13 Dec 2023 21:37:16 +0800
+
+linux-unstable (6.7.0-3.3) noble; urgency=medium
+
+  * noble/linux-unstable: 6.7.0-3.3 -proposed tracker (LP: #2046060)
+
+  * enable CONFIG_INTEL_TDX_HOST in linux >= 6.7 for noble (LP: #2046040)
+    - [Config] enable CONFIG_INTEL_TDX_HOST
+
+  * linux tools packages for derived kernels refuse to install simultaneously
+    due to libcpupower name collision (LP: #2035971)
+    - [Packaging] Statically link libcpupower into cpupower tool
+
+  * make lazy RCU a boot time option (LP: #2045492)
+    - SAUCE: rcu: Provide a boot time parameter to control lazy RCU
+
+  * Build failure if run in a console (LP: #2044512)
+    - [Packaging] Fix kernel module compression failures
+
+  * Turning COMPAT_32BIT_TIME off on arm64 (64k & derivatives) (LP: #2038582)
+    - [Config] y2038: Turn off COMPAT and COMPAT_32BIT_TIME on arm64 64k
+
+  * Turning COMPAT_32BIT_TIME off on riscv64 (LP: #2038584)
+    - [Config] y2038: Disable COMPAT_32BIT_TIME on riscv64
+
+  * Turning COMPAT_32BIT_TIME off on ppc64el (LP: #2038587)
+    - [Config] y2038: Disable COMPAT and COMPAT_32BIT_TIME on ppc64le
+
+  * [UBUNTU 23.04] Kernel config option missing for s390x PCI passthrough
+    (LP: #2042853)
+    - [Config] CONFIG_VFIO_PCI_ZDEV_KVM=y
+
+  * back-out zstd module compression automatic for backports (LP: #2045593)
+    - [Packaging] make ZSTD module compression conditional
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Remove do_full_source variable
+    - [Packaging] Remove obsolete config handling
+    - [Packaging] Remove support for sub-flavors
+    - [Packaging] Remove old linux-libc-dev version hack
+    - [Packaging] Remove obsolete scripts
+    - [Packaging] Remove README.inclusion-list
+    - [Packaging] make $(stampdir)/stamp-build-perarch depend on build-arch
+    - [Packaging] Enable rootless builds
+    - [Packaging] Allow to run debian/rules without (fake)root
+    - [Packaging] remove unneeded trailing slash for INSTALL_MOD_PATH
+    - [Packaging] override KERNELRELEASE instead of KERNELVERSION
+    - [Config] update toolchain versions in annotations
+    - [Packaging] drop useless linux-doc
+    - [Packaging] scripts: Rewrite insert-ubuntu-changes in Python
+    - [Packaging] enable riscv64 builds
+    - [Packaging] remove the last sub-flavours bit
+    - [Packaging] check debian.env to determine do_libc_dev_package
+    - [Packaging] remove debian.*/variants
+    - [Packaging] remove do_libc_dev_package variable
+    - [Packaging] move linux-libc-dev.stub to debian/control.d/
+    - [Packaging] Update check to build linux-libc-dev to the source package name
+    - [Packaging] rules: Remove startnewrelease target
+    - [Packaging] Remove debian/commit-templates
+    - [Config] update annotations after rebase to v6.7-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.7-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 11 Dec 2023 15:56:11 +0100
+
+linux-unstable (6.7.0-2.2) noble; urgency=medium
+
+  * noble/linux-unstable: 6.7.0-2.2 -proposed tracker (LP: #2045107)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] re-enable Rust
+    - [Config] enable Rust in annotations
+    - [Packaging] Remove do_enforce_all variable
+    - [Config] disable Softlogic 6x10 capture card driver on armhf
+    - [Packaging] disable Rust support
+    - [Config] update annotations after rebase to v6.7-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.7-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 29 Nov 2023 07:51:17 +0100
+
+linux-unstable (6.7.0-1.1) noble; urgency=medium
+
+  * noble/linux-unstable: 6.7.0-1.1 -proposed tracker (LP: #2044069)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update annotations scripts
+    - [Packaging] update helper scripts
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations after rebase to v6.7-rc2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.7-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 21 Nov 2023 10:45:24 +0100
+
+linux-unstable (6.7.0-0.0) noble; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 21 Nov 2023 07:26:46 +0100
+
+linux-unstable (6.6.0-12.12) noble; urgency=medium
+
+  * noble/linux-unstable: 6.6.0-12.12 -proposed tracker (LP: #2043664)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] temporarily disable zfs dkms
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 16 Nov 2023 10:20:26 +0100
+
+linux-unstable (6.6.0-11.11) noble; urgency=medium
+
+  * noble/linux-unstable: 6.6.0-11.11 -proposed tracker (LP: #2043480)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+    - [Packaging] resync update-dkms-versions helper
+    - [Packaging] update variants
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.11.14)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move to Noble
+    - [Config] toolchain version update
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 15 Nov 2023 14:50:40 +0100
+
+linux-unstable (6.6.0-10.10) noble; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-10.10 -proposed tracker (LP: #2043088)
+
+  * Bump arm64's CONFIG_NR_CPUS to 512 (LP: #2042897)
+    - [Config] Bump CONFIG_NR_CPUS to 512 for arm64
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Include a note for the NR_CPUS setting on riscv64
+    - SAUCE: apparmor4.0.0 [83/83]: Fix inode_init for changed prototype
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 09 Nov 2023 12:05:11 +0200
+
+linux-unstable (6.6.0-9.9) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-9.9 -proposed tracker (LP: #2041852)
+
+  * Switch IMA default hash to sha256 (LP: #2041735)
+    - [Config] Switch IMA_DEFAULT_HASH from sha1 to sha256
+
+  * apparmor restricts read access of user namespace mediation sysctls to root
+    (LP: #2040194)
+    - SAUCE: apparmor4.0.0 [82/82]: apparmor: open userns related sysctl so lxc
+      can check if restriction are in place
+
+  * AppArmor spams kernel log with assert when auditing (LP: #2040192)
+    - SAUCE: apparmor4.0.0 [81/82]: apparmor: fix request field from a prompt
+      reply that denies all access
+
+  * apparmor notification files verification (LP: #2040250)
+    - SAUCE: apparmor4.0.0 [80/82]: apparmor: fix notification header size
+
+  * apparmor oops when racing to retrieve a notification (LP: #2040245)
+    - SAUCE: apparmor4.0.0 [79/82]: apparmor: fix oops when racing to retrieve
+      notification
+
+  * Disable restricting unprivileged change_profile by default, due to LXD
+    latest/stable not yet compatible with this new apparmor feature
+    (LP: #2038567)
+    - SAUCE: apparmor4.0.0 [78/82]: apparmor: Make
+      apparmor_restrict_unprivileged_unconfined opt-in
+
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [01/82]: add/use fns to print hash string hex value
+    - SAUCE: apparmor4.0.0 [02/82]: rename SK_CTX() to aa_sock and make it an
+      inline fn
+    - SAUCE: apparmor4.0.0 [03/82]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor4.0.0 [04/82]: add user namespace creation mediation
+    - SAUCE: apparmor4.0.0 [05/82]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor4.0.0 [06/82]: af_unix mediation
+    - SAUCE: apparmor4.0.0 [07/82]: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor4.0.0 [08/82]: Stacking v38: LSM: Identify modules by more
+      than name
+    - SAUCE: apparmor4.0.0 [09/82]: Stacking v38: LSM: Add an LSM identifier for
+      external use
+    - SAUCE: apparmor4.0.0 [10/82]: Stacking v38: LSM: Identify the process
+      attributes for each module
+    - SAUCE: apparmor4.0.0 [11/82]: Stacking v38: LSM: Maintain a table of LSM
+      attribute data
+    - SAUCE: apparmor4.0.0 [12/82]: Stacking v38: proc: Use lsmids instead of lsm
+      names for attrs
+    - SAUCE: apparmor4.0.0 [13/82]: Stacking v38: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor4.0.0 [14/82]: Stacking v38: LSM: Infrastructure management
+      of the sock security
+    - SAUCE: apparmor4.0.0 [15/82]: Stacking v38: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor4.0.0 [16/82]: Stacking v38: LSM: provide lsm name and id
+      slot mappings
+    - SAUCE: apparmor4.0.0 [17/82]: Stacking v38: IMA: avoid label collisions with
+      stacked LSMs
+    - SAUCE: apparmor4.0.0 [18/82]: Stacking v38: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor4.0.0 [19/82]: Stacking v38: LSM: Use lsmblob in
+      security_kernel_act_as
+    - SAUCE: apparmor4.0.0 [20/82]: Stacking v38: LSM: Use lsmblob in
+      security_secctx_to_secid
+    - SAUCE: apparmor4.0.0 [21/82]: Stacking v38: LSM: Use lsmblob in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [22/82]: Stacking v38: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor4.0.0 [23/82]: Stacking v38: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor4.0.0 [24/82]: Stacking v38: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor4.0.0 [25/82]: Stacking v38: LSM: Use lsmblob in
+      security_cred_getsecid
+    - SAUCE: apparmor4.0.0 [26/82]: Stacking v38: LSM: Specify which LSM to
+      display
+    - SAUCE: apparmor4.0.0 [28/82]: Stacking v38: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor4.0.0 [29/82]: Stacking v38: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor4.0.0 [30/82]: Stacking v38: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor4.0.0 [31/82]: Stacking v38: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor4.0.0 [32/82]: Stacking v38: LSM: security_secid_to_secctx in
+      netlink netfilter
+    - SAUCE: apparmor4.0.0 [33/82]: Stacking v38: NET: Store LSM netlabel data in
+      a lsmblob
+    - SAUCE: apparmor4.0.0 [34/82]: Stacking v38: binder: Pass LSM identifier for
+      confirmation
+    - SAUCE: apparmor4.0.0 [35/82]: Stacking v38: LSM: security_secid_to_secctx
+      module selection
+    - SAUCE: apparmor4.0.0 [36/82]: Stacking v38: Audit: Keep multiple LSM data in
+      audit_names
+    - SAUCE: apparmor4.0.0 [37/82]: Stacking v38: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor4.0.0 [38/82]: Stacking v38: LSM: Add a function to report
+      multiple LSMs
+    - SAUCE: apparmor4.0.0 [39/82]: Stacking v38: Audit: Allow multiple records in
+      an audit_buffer
+    - SAUCE: apparmor4.0.0 [40/82]: Stacking v38: Audit: Add record for multiple
+      task security contexts
+    - SAUCE: apparmor4.0.0 [41/82]: Stacking v38: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor4.0.0 [42/82]: Stacking v38: Audit: Add record for multiple
+      object contexts
+    - SAUCE: apparmor4.0.0 [43/82]: Stacking v38: netlabel: Use a struct lsmblob
+      in audit data
+    - SAUCE: apparmor4.0.0 [44/82]: Stacking v38: LSM: Removed scaffolding
+      function lsmcontext_init
+    - SAUCE: apparmor4.0.0 [45/82]: Stacking v38: AppArmor: Remove the exclusive
+      flag
+    - SAUCE: apparmor4.0.0 [46/82]: combine common_audit_data and
+      apparmor_audit_data
+    - SAUCE: apparmor4.0.0 [47/82]: setup slab cache for audit data
+    - SAUCE: apparmor4.0.0 [48/82]: rename audit_data->label to
+      audit_data->subj_label
+    - SAUCE: apparmor4.0.0 [49/82]: pass cred through to audit info.
+    - SAUCE: apparmor4.0.0 [50/82]: Improve debug print infrastructure
+    - SAUCE: apparmor4.0.0 [51/82]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor4.0.0 [52/82]: enable userspace upcall for mediation
+    - SAUCE: apparmor4.0.0 [53/82]: cache buffers on percpu list if there is lock
+      contention
+    - SAUCE: apparmor4.0.0 [54/82]: advertise availability of exended perms
+    - SAUCE: apparmor4.0.0 [56/82]: cleanup: provide separate audit messages for
+      file and policy checks
+    - SAUCE: apparmor4.0.0 [57/82]: prompt - lock down prompt interface
+    - SAUCE: apparmor4.0.0 [58/82]: prompt - ref count pdb
+    - SAUCE: apparmor4.0.0 [59/82]: prompt - allow controlling of caching of a
+      prompt response
+    - SAUCE: apparmor4.0.0 [60/82]: prompt - add refcount to audit_node in prep or
+      reuse and delete
+    - SAUCE: apparmor4.0.0 [61/82]: prompt - refactor to moving caching to
+      uresponse
+    - SAUCE: apparmor4.0.0 [62/82]: prompt - Improve debug statements
+    - SAUCE: apparmor4.0.0 [63/82]: prompt - fix caching
+    - SAUCE: apparmor4.0.0 [64/82]: prompt - rework build to use append fn, to
+      simplify adding strings
+    - SAUCE: apparmor4.0.0 [65/82]: prompt - refcount notifications
+    - SAUCE: apparmor4.0.0 [66/82]: prompt - add the ability to reply with a
+      profile name
+    - SAUCE: apparmor4.0.0 [67/82]: prompt - fix notification cache when updating
+    - SAUCE: apparmor4.0.0 [68/82]: prompt - add tailglob on name for cache
+      support
+    - SAUCE: apparmor4.0.0 [69/82]: prompt - allow profiles to set prompts as
+      interruptible
+    - SAUCE: apparmor4.0.0 [74/82]: advertise disconnected.path is available
+    - SAUCE: apparmor4.0.0 [75/82]: fix invalid reference on profile->disconnected
+    - SAUCE: apparmor4.0.0 [76/82]: add io_uring mediation
+    - SAUCE: apparmor4.0.0 [77/82]: apparmor: Fix regression in mount mediation
+
+  * update apparmor and LSM stacking patch set (LP: #2028253) // [FFe]
+    apparmor-4.0.0-alpha2 for unprivileged user namespace restrictions in mantic
+    (LP: #2032602)
+    - SAUCE: apparmor4.0.0 [70/82]: prompt - add support for advanced filtering of
+      notifications
+    - SAUCE: apparmor4.0.0 [71/82]: userns - add the ability to reference a global
+      variable for a feature value
+    - SAUCE: apparmor4.0.0 [72/82]: userns - make it so special unconfined
+      profiles can mediate user namespaces
+    - SAUCE: apparmor4.0.0 [73/82]: userns - allow restricting unprivileged
+      change_profile
+
+  * LSM stacking and AppArmor for 6.2: additional fixes (LP: #2017903) // update
+    apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [55/82]: fix profile verification and enable it
+
+  * udev fails to make prctl() syscall with apparmor=0 (as used by maas by
+    default) (LP: #2016908) // update apparmor and LSM stacking patch set
+    (LP: #2028253)
+    - SAUCE: apparmor4.0.0 [27/82]: Stacking v38: Fix prctl() syscall with
+      apparmor=0
+
+  * Miscellaneous Ubuntu changes
+    - [Config] SECURITY_APPARMOR_RESTRICT_USERNS=y
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 03 Nov 2023 11:59:12 +0100
+
+linux-unstable (6.6.0-8.8) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-8.8 -proposed tracker (LP: #2040243)
+
+  * Miscellaneous Ubuntu changes
+    - abi: gc reference to phy-rtk-usb2/phy-rtk-usb3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 24 Oct 2023 10:55:34 +0200
+
+linux-unstable (6.6.0-7.7) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-7.7 -proposed tracker (LP: #2040147)
+
+  * test_021_aslr_dapper_libs from ubuntu_qrt_kernel_security failed on K-5.19 /
+    J-OEM-6.1 / J-6.2 AMD64 (LP: #1983357)
+    - [Config]: set ARCH_MMAP_RND_{COMPAT_, }BITS to the maximum
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs following v6.6-rc7 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 23 Oct 2023 11:51:14 +0200
+
+linux-unstable (6.6.0-6.6) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-6.6 -proposed tracker (LP: #2039780)
+
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.6-rc6
+    - [Config] updateconfigs following v6.6-rc6 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.6-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 19 Oct 2023 12:09:16 +0200
+
+linux-unstable (6.6.0-5.5) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-5.5 -proposed tracker (LP: #2038899)
+
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.6-rc5
+    - [Config] updateconfigs following v6.6-rc5 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.6-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 10 Oct 2023 11:18:41 +0200
+
+linux-unstable (6.6.0-4.4) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-4.4 -proposed tracker (LP: #2038423)
+
+  * Miscellaneous Ubuntu changes
+    - rebase on v6.6-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.6-rc4
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 04 Oct 2023 11:16:25 +0200
+
+linux-unstable (6.6.0-3.3) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.6.0-3.3 -proposed tracker (LP: #2037622)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs following v6.6-rc3 rebase
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: enforce rust availability only on x86_64"
+    - arm64: rust: Enable Rust support for AArch64
+    - arm64: rust: Enable PAC support for Rust.
+    - arm64: Restrict Rust support to little endian only.
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 28 Sep 2023 10:45:38 +0200
+
+linux-unstable (6.6.0-2.2) mantic; urgency=medium
+
+  * Miscellaneous upstream changes
+    - UBUBNTU: [Config] build all COMEDI drivers as modules
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 18 Sep 2023 14:42:56 +0200
+
+linux-unstable (6.6.0-1.1) mantic; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move linux to linux-unstable
+    - [Packaging] rebase on v6.6-rc1
+    - [Config] updateconfigs following v6.6-rc1 rebase
+    - [packaging] skip ABI, modules and retpoline checks
+    - update dropped.txt
+    - [Config] SHIFT_FS FTBFS with Linux 6.6, disable it
+    - [Config] DELL_UART_BACKLIGHT FTBFS with Linux 6.6, disable it
+    - [Packaging] debian/dkms-versions: temporarily disable dkms
+    - [Packaging] temporarily disable signing for s390x
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.6-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 15 Sep 2023 14:42:18 +0200
+
+linux-unstable (6.6.0-0.0) mantic; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 14 Sep 2023 15:03:19 +0200
+
+linux (6.5.0-5.5) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-5.5 -proposed tracker (LP: #2034546)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.08.23)
+
+
+linux (6.5.0-4.4) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-4.4 -proposed tracker (LP: #2034042)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.08.23)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 04 Sep 2023 16:55:44 +0200
+
+linux (6.5.0-3.3) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-3.3 -proposed tracker (LP: #2033904)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.08.23)
+
+  * [23.10] Please test secure-boot and lockdown on the early 6.5 kernel (s390x)
+    (LP: #2026833)
+    - [Packaging] re-enable signing for s390x
+
+  * Miscellaneous upstream changes
+    - module/decompress: use vmalloc() for zstd decompression workspace
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 01 Sep 2023 16:15:33 +0200
+
+linux (6.5.0-2.2) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-2.2 -proposed tracker (LP: #2033240)
+
+  * Soundwire support for Dell SKU0C87 devices (LP: #2029281)
+    - SAUCE: ASoC: Intel: soc-acpi: add support for Dell SKU0C87 devices
+
+  * Fix numerous AER related issues (LP: #2033025)
+    - SAUCE: PCI/AER: Disable AER service during suspend, again
+    - SAUCE: PCI/DPC: Disable DPC service during suspend, again
+
+  * Support Realtek RTL8852CE WiFi 6E/BT Combo (LP: #2025672)
+    - wifi: rtw89: debug: Fix error handling in rtw89_debug_priv_btc_manual_set()
+    - Bluetooth: btrtl: Load FW v2 otherwise FW v1 for RTL8852C
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Aug 2023 08:53:19 +0200
+
+linux (6.5.0-1.1) mantic; urgency=medium
+
+  * mantic/linux: 6.5.0-1.1 -proposed tracker (LP: #2032750)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync update-dkms-versions helper
+    - [Packaging] update variants
+    - debian/dkms-versions -- update from kernel-versions (main/d2023.07.26)
+
+  * ceph: support idmapped mounts (LP: #2032959)
+    - SAUCE: libceph: add spinlock around osd->o_requests
+    - SAUCE: libceph: define struct ceph_sparse_extent and add some helpers
+    - SAUCE: libceph: new sparse_read op, support sparse reads on msgr2 crc
+      codepath
+    - SAUCE: libceph: support sparse reads on msgr2 secure codepath
+    - SAUCE: libceph: add sparse read support to msgr1
+    - SAUCE: libceph: add sparse read support to OSD client
+    - SAUCE: ceph: add new mount option to enable sparse reads
+    - SAUCE: ceph: preallocate inode for ops that may create one
+    - SAUCE: ceph: make ceph_msdc_build_path use ref-walk
+    - SAUCE: libceph: add new iov_iter-based ceph_msg_data_type and
+      ceph_osd_data_type
+    - SAUCE: ceph: use osd_req_op_extent_osd_iter for netfs reads
+    - SAUCE: ceph: fscrypt_auth handling for ceph
+    - SAUCE: ceph: implement -o test_dummy_encryption mount option
+    - SAUCE: ceph: add fscrypt ioctls and ceph.fscrypt.auth vxattr
+    - SAUCE: ceph: make ioctl cmds more readable in debug log
+    - SAUCE: ceph: add base64 endcoding routines for encrypted names
+    - SAUCE: ceph: encode encrypted name in ceph_mdsc_build_path and dentry
+      release
+    - SAUCE: ceph: send alternate_name in MClientRequest
+    - SAUCE: ceph: decode alternate_name in lease info
+    - SAUCE: ceph: set DCACHE_NOKEY_NAME flag in ceph_lookup/atomic_open()
+    - SAUCE: ceph: make d_revalidate call fscrypt revalidator for encrypted
+      dentries
+    - SAUCE: ceph: add helpers for converting names for userland presentation
+    - SAUCE: ceph: make ceph_fill_trace and ceph_get_name decrypt names
+    - SAUCE: ceph: pass the request to parse_reply_info_readdir()
+    - SAUCE: ceph: add support to readdir for encrypted names
+    - SAUCE: ceph: create symlinks with encrypted and base64-encoded targets
+    - SAUCE: ceph: add some fscrypt guardrails
+    - SAUCE: ceph: allow encrypting a directory while not having Ax caps
+    - SAUCE: ceph: mark directory as non-complete after loading key
+    - SAUCE: ceph: size handling in MClientRequest, cap updates and inode traces
+    - SAUCE: ceph: handle fscrypt fields in cap messages from MDS
+    - SAUCE: ceph: add infrastructure for file encryption and decryption
+    - SAUCE: libceph: add CEPH_OSD_OP_ASSERT_VER support
+    - SAUCE: libceph: allow ceph_osdc_new_request to accept a multi-op read
+    - SAUCE: ceph: add object version support for sync read
+    - SAUCE: ceph: add truncate size handling support for fscrypt
+    - SAUCE: ceph: don't use special DIO path for encrypted inodes
+    - SAUCE: ceph: align data in pages in ceph_sync_write
+    - SAUCE: ceph: add read/modify/write to ceph_sync_write
+    - SAUCE: ceph: add encryption support to writepage and writepages
+    - SAUCE: ceph: plumb in decryption during reads
+    - SAUCE: ceph: invalidate pages when doing direct/sync writes
+    - SAUCE: ceph: add support for encrypted snapshot names
+    - SAUCE: ceph: prevent snapshot creation in encrypted locked directories
+    - SAUCE: ceph: update documentation regarding snapshot naming limitations
+    - SAUCE: ceph: drop messages from MDS when unmounting
+    - SAUCE: ceph: wait for OSD requests' callbacks to finish when unmounting
+    - SAUCE: ceph: fix updating i_truncate_pagecache_size for fscrypt
+    - SAUCE: ceph: switch ceph_lookup/atomic_open() to use new fscrypt helper
+    - SAUCE: libceph: do not include crypto/algapi.h
+    - SAUCE: rbd: bump RBD_MAX_PARENT_CHAIN_LEN to 128
+    - SAUCE: ceph: dump info about cap flushes when we're waiting too long for
+      them
+    - SAUCE: mm: BUG if filemap_alloc_folio gives us a folio with a non-NULL
+      ->private
+    - SAUCE: ceph: make sure all the files successfully put before unmounting
+    - SAUCE: ceph: BUG if MDS changed truncate_seq with client caps still
+      outstanding
+    - SAUCE: ceph: add the *_client debug macros support
+    - SAUCE: ceph: pass the mdsc to several helpers
+    - SAUCE: ceph: rename _to_client() to _to_fs_client()
+    - SAUCE: ceph: move mdsmap.h to fs/ceph/
+    - SAUCE: ceph: add ceph_inode_to_client() helper support
+    - SAUCE: ceph: print the client global_id in all the debug logs
+    - SAUCE: ceph: make the members in struct ceph_mds_request_args_ext an union
+    - SAUCE: ceph: make num_fwd and num_retry to __u32
+    - SAUCE: fs: export mnt_idmap_get/mnt_idmap_put
+    - SAUCE: ceph: stash idmapping in mdsc request
+    - SAUCE: ceph: handle idmapped mounts in create_request_message()
+    - SAUCE: ceph: add enable_unsafe_idmap module parameter
+    - SAUCE: ceph: pass an idmapping to mknod/symlink/mkdir
+    - SAUCE: ceph: allow idmapped getattr inode op
+    - SAUCE: ceph: allow idmapped permission inode op
+    - SAUCE: ceph: pass idmap to __ceph_setattr
+    - SAUCE: ceph: allow idmapped setattr inode op
+    - SAUCE: ceph/acl: allow idmapped set_acl inode op
+    - SAUCE: ceph/file: allow idmapped atomic_open inode op
+    - SAUCE: ceph: allow idmapped mounts
+
+  * Got soft lockup CPU if dell_uart_backlight is probed (LP: #2032174)
+    - SAUCE: platform/x86: dell-uart-backlight: replace chars_in_buffer() with
+      flush_chars()
+
+  * Fix ACPI TAD  on some Intel based systems (LP: #2032767)
+    - ACPI: TAD: Install SystemCMOS address space handler for ACPI000E
+
+  * Fix unreliable ethernet cable detection on I219 NIC (LP: #2028122)
+    - e1000e: Use PME poll to circumvent unreliable ACPI wake
+
+  * Fix panel brightness issues on HP laptops (LP: #2032704)
+    - ACPI: video: Put ACPI video and its child devices into D0 on boot
+
+  * FATAL:credentials.cc(127)] Check failed: . : Permission denied (13)
+    (LP: #2017980)
+    - [Config] disable CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+
+  * Support initrdless boot on default qemu virt models and openstack
+    (LP: #2030745)
+    - [Config] set VIRTIO_BLK=y for default qemu/openstack boot
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] rust: use Rust 1.68.2
+    - [Packaging] depend on clang/libclang-15 for Rust
+    - [Config] update toolchain versions in annotations
+    - [Config] update annotations after rebase to v6.5-rc6
+    - [Config] update toolchain version in annotations
+    - [Packaging] temporarily disable Rust support
+    - [Packaging] temporarily disable signing for ppc64el
+    - [Packaging] temporarily disable signing for s390x
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 24 Aug 2023 17:47:10 +0200
+
+linux (6.5.0-0.0) mantic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 23 Aug 2023 08:14:48 +0200
+
+linux-unstable (6.5.0-4.4) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.5.0-4.4 -proposed tracker (LP: #2029086)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Add .NOTPARALLEL
+    - [Packaging] Remove meaningless $(header_arch)
+    - [Packaging] Fix File exists error in install-arch-headers
+    - [Packaging] clean debian/linux-* directories
+    - [Packaging] remove hmake
+    - [Packaging] install headers to debian/linux-libc-dev directly
+    - [Config] define CONFIG options for arm64 instead of arm64-generic
+    - [Config] update annotations after rebase to v6.5-rc4
+    - [Packaging] temporarily disable Rust support
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 31 Jul 2023 08:41:59 +0200
+
+linux-unstable (6.5.0-3.3) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.5.0-3.3 -proposed tracker (LP: #2028779)
+
+  * enable Rust support in the kernel (LP: #2007654)
+    - SAUCE: rust: support rustc-1.69.0
+    - [Packaging] depend on rustc-1.69.0
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync update-dkms-versions helper
+    - [Packaging] resync getabis
+
+  * Fix UBSAN in Intel EDAC driver (LP: #2028746)
+    - EDAC/i10nm: Skip the absent memory controllers
+
+  * Ship kernel modules Zstd compressed (LP: #2028568)
+    - SAUCE: Support but do not require compressed modules
+    - [Config] Enable support for ZSTD compressed modules
+    - [Packaging] ZSTD compress modules
+
+  * update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor3.2.0 [02/60]: rename SK_CTX() to aa_sock and make it an
+      inline fn
+    - SAUCE: apparmor3.2.0 [05/60]: Add sysctls for additional controls of unpriv
+      userns restrictions
+    - SAUCE: apparmor3.2.0 [08/60]: Stacking v38: LSM: Identify modules by more
+      than name
+    - SAUCE: apparmor3.2.0 [09/60]: Stacking v38: LSM: Add an LSM identifier for
+      external use
+    - SAUCE: apparmor3.2.0 [10/60]: Stacking v38: LSM: Identify the process
+      attributes for each module
+    - SAUCE: apparmor3.2.0 [11/60]: Stacking v38: LSM: Maintain a table of LSM
+      attribute data
+    - SAUCE: apparmor3.2.0 [12/60]: Stacking v38: proc: Use lsmids instead of lsm
+      names for attrs
+    - SAUCE: apparmor3.2.0 [13/60]: Stacking v38: integrity: disassociate
+      ima_filter_rule from security_audit_rule
+    - SAUCE: apparmor3.2.0 [14/60]: Stacking v38: LSM: Infrastructure management
+      of the sock security
+    - SAUCE: apparmor3.2.0 [15/60]: Stacking v38: LSM: Add the lsmblob data
+      structure.
+    - SAUCE: apparmor3.2.0 [16/60]: Stacking v38: LSM: provide lsm name and id
+      slot mappings
+    - SAUCE: apparmor3.2.0 [17/60]: Stacking v38: IMA: avoid label collisions with
+      stacked LSMs
+    - SAUCE: apparmor3.2.0 [18/60]: Stacking v38: LSM: Use lsmblob in
+      security_audit_rule_match
+    - SAUCE: apparmor3.2.0 [19/60]: Stacking v38: LSM: Use lsmblob in
+      security_kernel_act_as
+    - SAUCE: apparmor3.2.0 [20/60]: Stacking v38: LSM: Use lsmblob in
+      security_secctx_to_secid
+    - SAUCE: apparmor3.2.0 [21/60]: Stacking v38: LSM: Use lsmblob in
+      security_secid_to_secctx
+    - SAUCE: apparmor3.2.0 [22/60]: Stacking v38: LSM: Use lsmblob in
+      security_ipc_getsecid
+    - SAUCE: apparmor3.2.0 [23/60]: Stacking v38: LSM: Use lsmblob in
+      security_current_getsecid
+    - SAUCE: apparmor3.2.0 [24/60]: Stacking v38: LSM: Use lsmblob in
+      security_inode_getsecid
+    - SAUCE: apparmor3.2.0 [25/60]: Stacking v38: LSM: Use lsmblob in
+      security_cred_getsecid
+    - SAUCE: apparmor3.2.0 [26/60]: Stacking v38: LSM: Specify which LSM to
+      display
+    - SAUCE: apparmor3.2.0 [28/60]: Stacking v38: LSM: Ensure the correct LSM
+      context releaser
+    - SAUCE: apparmor3.2.0 [29/60]: Stacking v38: LSM: Use lsmcontext in
+      security_secid_to_secctx
+    - SAUCE: apparmor3.2.0 [30/60]: Stacking v38: LSM: Use lsmcontext in
+      security_inode_getsecctx
+    - SAUCE: apparmor3.2.0 [31/60]: Stacking v38: Use lsmcontext in
+      security_dentry_init_security
+    - SAUCE: apparmor3.2.0 [32/60]: Stacking v38: LSM: security_secid_to_secctx in
+      netlink netfilter
+    - SAUCE: apparmor3.2.0 [33/60]: Stacking v38: NET: Store LSM netlabel data in
+      a lsmblob
+    - SAUCE: apparmor3.2.0 [34/60]: Stacking v38: binder: Pass LSM identifier for
+      confirmation
+    - SAUCE: apparmor3.2.0 [35/60]: Stacking v38: LSM: security_secid_to_secctx
+      module selection
+    - SAUCE: apparmor3.2.0 [36/60]: Stacking v38: Audit: Keep multiple LSM data in
+      audit_names
+    - SAUCE: apparmor3.2.0 [37/60]: Stacking v38: Audit: Create audit_stamp
+      structure
+    - SAUCE: apparmor3.2.0 [38/60]: Stacking v38: LSM: Add a function to report
+      multiple LSMs
+    - SAUCE: apparmor3.2.0 [39/60]: Stacking v38: Audit: Allow multiple records in
+      an audit_buffer
+    - SAUCE: apparmor3.2.0 [40/60]: Stacking v38: Audit: Add record for multiple
+      task security contexts
+    - SAUCE: apparmor3.2.0 [41/60]: Stacking v38: audit: multiple subject lsm
+      values for netlabel
+    - SAUCE: apparmor3.2.0 [42/60]: Stacking v38: Audit: Add record for multiple
+      object contexts
+    - SAUCE: apparmor3.2.0 [43/60]: Stacking v38: netlabel: Use a struct lsmblob
+      in audit data
+    - SAUCE: apparmor3.2.0 [44/60]: Stacking v38: LSM: Removed scaffolding
+      function lsmcontext_init
+    - SAUCE: apparmor3.2.0 [45/60]: Stacking v38: AppArmor: Remove the exclusive
+      flag
+    - SAUCE: apparmor3.2.0 [46/60]: combine common_audit_data and
+      apparmor_audit_data
+    - SAUCE: apparmor3.2.0 [47/60]: setup slab cache for audit data
+    - SAUCE: apparmor3.2.0 [48/60]: rename audit_data->label to
+      audit_data->subj_label
+    - SAUCE: apparmor3.2.0 [49/60]: pass cred through to audit info.
+    - SAUCE: apparmor3.2.0 [50/60]: Improve debug print infrastructure
+    - SAUCE: apparmor3.2.0 [51/60]: add the ability for profiles to have a
+      learning cache
+    - SAUCE: apparmor3.2.0 [52/60]: enable userspace upcall for mediation
+    - SAUCE: apparmor3.2.0 [53/60]: cache buffers on percpu list if there is lock
+      contention
+    - SAUCE: apparmor3.2.0 [55/60]: advertise availability of exended perms
+    - SAUCE: apparmor3.2.0 [60/60]: [Config] enable
+      CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+
+  * LSM stacking and AppArmor for 6.2: additional fixes (LP: #2017903) // update
+    apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor3.2.0 [57/60]: fix profile verification and enable it
+
+  * udev fails to make prctl() syscall with apparmor=0 (as used by maas by
+    default) (LP: #2016908) // update apparmor and LSM stacking patch set
+    (LP: #2028253)
+    - SAUCE: apparmor3.2.0 [27/60]: Stacking v38: Fix prctl() syscall with
+      apparmor=0
+
+  * kinetic: apply new apparmor and LSM stacking patch set (LP: #1989983) //
+    update apparmor and LSM stacking patch set (LP: #2028253)
+    - SAUCE: apparmor3.2.0 [01/60]: add/use fns to print hash string hex value
+    - SAUCE: apparmor3.2.0 [03/60]: patch to provide compatibility with v2.x net
+      rules
+    - SAUCE: apparmor3.2.0 [04/60]: add user namespace creation mediation
+    - SAUCE: apparmor3.2.0 [06/60]: af_unix mediation
+    - SAUCE: apparmor3.2.0 [07/60]: Add fine grained mediation of posix mqueues
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Use consistent llvm/clang for rust
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 28 Jul 2023 07:44:20 +0200
+
+linux-unstable (6.5.0-2.2) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.5.0-2.2 -proposed tracker (LP: #2027953)
+
+  * Remove non-LPAE kernel flavor (LP: #2025265)
+    - [Packaging] Rename armhf generic-lpae flavor to generic
+
+  * Please enable Renesas RZ platform serial installer (LP: #2022361)
+    - [Config] enable hihope RZ/G2M serial console
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] snap: Remove old configs handling
+    - [Packaging] checks/final-checks: Remove old configs handling
+    - [Packaging] checks/final-checks: check existance of Makefile first
+    - [Packaging] checks/final-checks: Fix shellcheck issues
+    - [Packaging] add libstdc++-dev to the build dependencies
+    - [Config] update annotations after rebase to v6.5-rc2
+
+  * Miscellaneous upstream changes
+    - kbuild: rust: avoid creating temporary files
+    - rust: fix bindgen build error with UBSAN_BOUNDS_STRICT
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 18 Jul 2023 10:14:14 +0200
+
+linux-unstable (6.5.0-1.1) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.5.0-1.1 -proposed tracker (LP: #2026689)
+
+  * CVE-2023-31248
+    - netfilter: nf_tables: do not ignore genmask when looking up chain by id
+
+  * CVE-2023-35001
+    - netfilter: nf_tables: prevent OOB access in nft_byteorder_eval
+
+  * HDMI output with More than one child device for port B in VBT error
+    (LP: #2025195)
+    - SAUCE: drm/i915/quirks: Add multiple VBT quirk for HP ZBook Power G10
+
+  * CVE-2023-2640 // CVE-2023-32629
+    - SAUCE: overlayfs: default to userxattr when mounted from non initial user
+      namespace
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync update-dkms-versions helper
+
+  * enable Rust support in the kernel (LP: #2007654)
+    - SAUCE: btf, scripts: rust: drop is_rust_module.sh
+    - [Packaging] add rust dependencies
+
+  * CVE-2023-2612
+    - SAUCE: shiftfs: prevent lock unbalance in shiftfs_create_object()
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: shiftfs: support linux 6.5
+    - [Config] update annotations after rebase to v6.5-rc1
+    - [Config] temporarily disable Rust
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.5-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 10 Jul 2023 09:15:26 +0200
+
+linux-unstable (6.5.0-0.0) mantic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 05 Jul 2023 12:48:39 +0200
+
+linux-unstable (6.4.0-8.8) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-8.8 -proposed tracker (LP: #2025018)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update toolchain version (gcc) in annotations
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 26 Jun 2023 09:14:02 +0200
+
+linux-unstable (6.4.0-7.7) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-7.7 -proposed tracker (LP: #2024338)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 19 Jun 2023 08:51:27 +0200
+
+linux-unstable (6.4.0-6.6) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-6.6 -proposed tracker (LP: #2023966)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update annotations scripts
+
+  * enable multi-gen LRU by default (LP: #2023629)
+    - [Config] enable multi-gen LRU by default
+
+  * Fix Monitor lost after replug WD19TBS to SUT port with VGA/DVI to type-C
+    dongle (LP: #2021949)
+    - thunderbolt: Do not touch CL state configuration during discovery
+    - thunderbolt: Increase DisplayPort Connection Manager handshake timeout
+
+  * Neuter signing tarballs (LP: #2012776)
+    - [Packaging] remove the signing tarball support
+
+  * Enable Tracing Configs for OSNOISE and TIMERLAT (LP: #2018591)
+    - [Config] Enable OSNOISE_TRACER and TIMERLAT_TRACER configs
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Add CONFIG_AS_HAS_NON_CONST_LEB128 on riscv64
+    - [Packaging] introduce do_lib_rust and enable it only on generic amd64
+    - [Config] update annotations after rebase to v6.4-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 15 Jun 2023 20:11:07 +0200
+
+linux-unstable (6.4.0-5.5) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-5.5 -proposed tracker (LP: #2022886)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] update getabis to support linux-unstable
+    - UBUNTU [Config]: disable hibernation on riscv64
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 06 Jun 2023 08:18:01 +0200
+
+linux-unstable (6.4.0-4.4) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-4.4 -proposed tracker (LP: #2021597)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] udpate annotations after rebase to v6.4-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 30 May 2023 11:55:41 +0200
+
+linux-unstable (6.4.0-3.3) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-3.3 -proposed tracker (LP: #2021497)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+    - [Packaging] resync getabis
+
+  * support python < 3.9 with annotations (LP: #2020531)
+    - [Packaging] kconfig/annotations.py: support older way of merging dicts
+
+  * generate linux-lib-rust only on amd64 (LP: #2020356)
+    - [Packaging] generate linux-lib-rust only on amd64
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: never drop configs that have notes different than
+      the parent
+    - [Config] drop CONFIG_SMBFS_COMMON from annotations
+    - [Packaging] perf: build without libtraceevent
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 30 May 2023 08:38:10 +0200
+
+linux-unstable (6.4.0-2.2) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-2.2 -proposed tracker (LP: #2020330)
+
+  * Computer with Intel Atom CPU will  not boot with Kernel 6.2.0-20
+    (LP: #2017444)
+    - [Config]: Disable CONFIG_INTEL_ATOMISP
+
+  * Fix NVME storage with RAID ON disappeared under Dell factory WINPE
+    environment (LP: #2011768)
+    - SAUCE: PCI: vmd: Reset VMD config register between soft reboots
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Drop support of old config handling
+    - [Config] update annotations after rebase to v6.4-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 22 May 2023 11:22:14 +0200
+
+linux-unstable (6.4.0-1.1) mantic; urgency=medium
+
+  * mantic/linux-unstable: 6.4.0-1.1 -proposed tracker (LP: #2019965)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - [Packaging] update helper scripts
+
+  * Kernel 6.1 bumped the disk consumption on default images by 15%
+    (LP: #2015867)
+    - [Packaging] introduce a separate linux-lib-rust package
+
+  * Miscellaneous Ubuntu changes
+    - [Config] enable CONFIG_BLK_DEV_UBLK on amd64
+    - [Packaging] annotations: use python3 in the shebang
+    - SAUCE: blk-throttle: Fix io statistics for cgroup v1
+    - [Packaging] move to v6.4 and rename to linux-unstable
+    - [Config] update annotations after rebase to v6.4-rc1
+    - [Packaging] temporarily disable perf
+    - [Packaging] temporarily disable bpftool
+    - [Config] ppc64el: reduce CONFIG_ARCH_FORCE_MAX_ORDER from 9 to 8
+    - SAUCE: perf: explicitly disable libtraceevent
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.4-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 18 May 2023 07:34:09 +0200
+
+linux-unstable (6.4.0-0.0) mantic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 17 May 2023 15:29:25 +0200
+
+linux-unstable (6.3.0-2.2) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.3.0-2.2 -proposed tracker (LP: #2017788)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move python3-dev to build-depends
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 26 Apr 2023 21:52:12 +0200
+
+linux-unstable (6.3.0-1.1) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.3.0-1.1 -proposed tracker (LP: #2017776)
+
+  * RFC: virtio and virtio-scsi should be built in (LP: #1685291)
+    - [Config] Mark CONFIG_SCSI_VIRTIO built-in
+
+  * Debian autoreconstruct Fix restoration of execute permissions (LP: #2015498)
+    - [Debian] autoreconstruct - fix restoration of execute permissions
+
+  * [SRU][Jammy] CONFIG_PCI_MESON is not enabled (LP: #2007745)
+    - [Config] arm64: Enable PCI_MESON module
+
+  * vmd may fail to create sysfs entry while `pci_rescan_bus()` called in some
+    other drivers like wwan (LP: #2011389)
+    - SAUCE: PCI: vmd: guard device addition and removal
+
+  * Lunar update: v6.2.9 upstream stable release (LP: #2016877)
+    - [Config] ppc64: updateconfigs following v6.2.9 stable updates
+
+  * Lunar update: v6.2.8 upstream stable release (LP: #2016876)
+    - [Config] ppc64: updateconfigs following v6.2.8 stable updates
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Move final-checks script to debian/scripts/checks
+    - [Packaging] checks/final-checks: Honor 'do_skip_checks'
+    - [Packaging] Drop wireguard DKMS
+    - [Packaging] Remove update-version-dkms
+    - [Packaging] debian/rules: Add DKMS info to 'printenv' output
+    - [Packaging] ignore KBUILD_VERBOSE in arch-has-odm-enabled.sh
+    - SAUCE: shiftfs: support linux 6.3
+    - [Packaging] move to v6.3 and rename to linux-unstable
+    - [Config] latency-related optimizations
+    - [Config] update annotations after rebase to v6.3
+    - [Packaging] temporarily disable dkms
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 26 Apr 2023 14:53:52 +0200
+
+linux-unstable (6.3.0-0.0) lunar; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 25 Apr 2023 10:24:12 +0200
+
+linux (6.2.0-21.21) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-21.21 -proposed tracker (LP: #2016249)
+
+  * efivarfs:efivarfs.sh in ubuntu_kernel_selftests crash L-6.2 ARM64 node
+    dazzle (rcu_preempt detected stalls) (LP: #2015741)
+    - efi/libstub: smbios: Use length member instead of record struct size
+    - arm64: efi: Use SMBIOS processor version to key off Ampere quirk
+    - efi/libstub: smbios: Drop unused 'recsize' parameter
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/bpf: ignore pointer types check with clang
+    - SAUCE: selftests/bpf: avoid conflicting data types in profiler.inc.h
+    - [Packaging] get rid of unnecessary artifacts in linux-headers
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: Revert "efi: random: refresh non-volatile random seed
+      when RNG is initialized""
+    - Revert "UBUNTU: SAUCE: Revert "efi: random: fix NULL-deref when refreshing
+      seed""
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 14 Apr 2023 12:11:49 +0200
+
+linux (6.2.0-20.20) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-20.20 -proposed tracker (LP: #2015429)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * FTBFS with different dkms or when makeflags are set (LP: #2015361)
+    - [Packaging] FTBFS with different dkms or when makeflags are set
+
+  * expoline.o is packaged unconditionally for s390x (LP: #2013209)
+    - [Packaging] Copy expoline.o only when produced by the build
+
+  * net:l2tp.sh failure with lunar:linux 6.2 (LP: #2013014)
+    - SAUCE: l2tp: generate correct module alias strings
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: prevent duplicate include lines
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 06 Apr 2023 08:33:14 +0200
+
+linux (6.2.0-19.19) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-19.19 -proposed tracker (LP: #2012488)
+
+  * Neuter signing tarballs (LP: #2012776)
+    - [Packaging] neuter the signing tarball
+
+  * LSM stacking and AppArmor refresh for 6.2 kernel (LP: #2012136)
+    - Revert "UBUNTU: [Config] define CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS"
+    - Revert "UBUNTU: SAUCE: apparmor: add user namespace creation mediation"
+    - Revert "UBUNTU: SAUCE: apparmor: Add fine grained mediation of posix
+      mqueues"
+    - Revert "UBUNTU: SAUCE: Revert "apparmor: make __aa_path_perm() static""
+    - Revert "UBUNTU: SAUCE: LSM: Specify which LSM to display (using struct cred
+      as input)"
+    - Revert "UBUNTU: SAUCE: apparmor: Fix build error, make sk parameter const"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in smk_netlbl_mls()"
+    - Revert "UBUNTU: SAUCE: LSM: change ima_read_file() to use lsmblob"
+    - Revert "UBUNTU: SAUCE: apparmor: rename kzfree() to kfree_sensitive()"
+    - Revert "UBUNTU: SAUCE: AppArmor: Remove the exclusive flag"
+    - Revert "UBUNTU: SAUCE: LSM: Add /proc attr entry for full LSM context"
+    - Revert "UBUNTU: SAUCE: Audit: Fix incorrect static inline function
+      declration."
+    - Revert "UBUNTU: SAUCE: Audit: Fix for missing NULL check"
+    - Revert "UBUNTU: SAUCE: Audit: Add a new record for multiple object LSM
+      attributes"
+    - Revert "UBUNTU: SAUCE: Audit: Add new record for multiple process LSM
+      attributes"
+    - Revert "UBUNTU: SAUCE: NET: Store LSM netlabel data in a lsmblob"
+    - Revert "UBUNTU: SAUCE: LSM: security_secid_to_secctx in netlink netfilter"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmcontext in security_inode_getsecctx"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmcontext in security_secid_to_secctx"
+    - Revert "UBUNTU: SAUCE: LSM: Ensure the correct LSM context releaser"
+    - Revert "UBUNTU: SAUCE: LSM: Specify which LSM to display"
+    - Revert "UBUNTU: SAUCE: IMA: Change internal interfaces to use lsmblobs"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_cred_getsecid"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_inode_getsecid"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_task_getsecid"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_ipc_getsecid"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_secid_to_secctx"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_secctx_to_secid"
+    - Revert "UBUNTU: SAUCE: net: Prepare UDS for security module stacking"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_kernel_act_as"
+    - Revert "UBUNTU: SAUCE: LSM: Use lsmblob in security_audit_rule_match"
+    - Revert "UBUNTU: SAUCE: LSM: Create and manage the lsmblob data structure."
+    - Revert "UBUNTU: SAUCE: LSM: Infrastructure management of the sock security"
+    - Revert "UBUNTU: SAUCE: apparmor: LSM stacking: switch from SK_CTX() to
+      aa_sock()"
+    - Revert "UBUNTU: SAUCE: apparmor: rename aa_sock() to aa_unix_sk()"
+    - Revert "UBUNTU: SAUCE: apparmor: disable showing the mode as part of a secid
+      to secctx"
+    - Revert "UBUNTU: SAUCE: apparmor: fix use after free in sk_peer_label"
+    - Revert "UBUNTU: SAUCE: apparmor: af_unix mediation"
+    - Revert "UBUNTU: SAUCE: apparmor: patch to provide compatibility with v2.x
+      net rules"
+    - Revert "UBUNTU: SAUCE: apparmor: add/use fns to print hash string hex value"
+    - SAUCE: apparmor: rename SK_CTX() to aa_sock and make it an inline fn
+    - SAUCE: apparmor: Add sysctls for additional controls of unpriv userns
+      restrictions
+    - SAUCE: Stacking v38: LSM: Identify modules by more than name
+    - SAUCE: Stacking v38: LSM: Add an LSM identifier for external use
+    - SAUCE: Stacking v38: LSM: Identify the process attributes for each module
+    - SAUCE: Stacking v38: LSM: Maintain a table of LSM attribute data
+    - SAUCE: Stacking v38: proc: Use lsmids instead of lsm names for attrs
+    - SAUCE: Stacking v38: integrity: disassociate ima_filter_rule from
+      security_audit_rule
+    - SAUCE: Stacking v38: LSM: Infrastructure management of the sock security
+    - SAUCE: Stacking v38: LSM: Add the lsmblob data structure.
+    - SAUCE: Stacking v38: LSM: provide lsm name and id slot mappings
+    - SAUCE: Stacking v38: IMA: avoid label collisions with stacked LSMs
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_audit_rule_match
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_kernel_act_as
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_secctx_to_secid
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_secid_to_secctx
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_ipc_getsecid
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_current_getsecid
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_inode_getsecid
+    - SAUCE: Stacking v38: LSM: Use lsmblob in security_cred_getsecid
+    - SAUCE: Stacking v38: LSM: Specify which LSM to display
+    - SAUCE: Stacking v38: LSM: Ensure the correct LSM context releaser
+    - SAUCE: Stacking v38: LSM: Use lsmcontext in security_secid_to_secctx
+    - SAUCE: Stacking v38: LSM: Use lsmcontext in security_inode_getsecctx
+    - SAUCE: Stacking v38: Use lsmcontext in security_dentry_init_security
+    - SAUCE: Stacking v38: LSM: security_secid_to_secctx in netlink netfilter
+    - SAUCE: Stacking v38: NET: Store LSM netlabel data in a lsmblob
+    - SAUCE: Stacking v38: binder: Pass LSM identifier for confirmation
+    - SAUCE: Stacking v38: LSM: security_secid_to_secctx module selection
+    - SAUCE: Stacking v38: Audit: Keep multiple LSM data in audit_names
+    - SAUCE: Stacking v38: Audit: Create audit_stamp structure
+    - SAUCE: Stacking v38: LSM: Add a function to report multiple LSMs
+    - SAUCE: Stacking v38: Audit: Allow multiple records in an audit_buffer
+    - SAUCE: Stacking v38: Audit: Add record for multiple task security contexts
+    - SAUCE: Stacking v38: audit: multiple subject lsm values for netlabel
+    - SAUCE: Stacking v38: Audit: Add record for multiple object contexts
+    - SAUCE: Stacking v38: netlabel: Use a struct lsmblob in audit data
+    - SAUCE: Stacking v38: LSM: Removed scaffolding function lsmcontext_init
+    - SAUCE: Stacking v38: AppArmor: Remove the exclusive flag
+    - SAUCE: apparmor: combine common_audit_data and apparmor_audit_data
+    - SAUCE: apparmor: setup slab cache for audit data
+    - SAUCE: apparmor: rename audit_data->label to audit_data->subj_label
+    - SAUCE: apparmor: pass cred through to audit info.
+    - SAUCE: apparmor: Improve debug print infrastructure
+    - SAUCE: apparmor: add the ability for profiles to have a learning cache
+    - SAUCE: apparmor: enable userspace upcall for mediation
+    - SAUCE: apparmor: cache buffers on percpu list if there is lock contention
+    - SAUCE: apparmor: fix policy_compat permission remap with extended
+      permissions
+    - SAUCE: apparmor: advertise availability of exended perms
+    - [Config] define CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+
+  * kinetic: apply new apparmor and LSM stacking patch set (LP: #1989983) // LSM
+    stacking and AppArmor refresh for 6.2 kernel (LP: #2012136)
+    - SAUCE: apparmor: add/use fns to print hash string hex value
+    - SAUCE: apparmor: patch to provide compatibility with v2.x net rules
+    - SAUCE: apparmor: add user namespace creation mediation
+    - SAUCE: apparmor: af_unix mediation
+    - SAUCE: apparmor: Add fine grained mediation of posix mqueues
+
+  * devlink_port_split from ubuntu_kernel_selftests.net fails on hirsute
+    (KeyError: 'flavour') (LP: #1937133)
+    - selftests: net: devlink_port_split.py: skip test if no suitable device
+      available
+
+  * NFS deathlock with last Kernel 5.4.0-144.161 and 5.15.0-67.74 (LP: #2009325)
+    - NFS: Correct timing for assigning access cache timestamp
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Sat, 25 Mar 2023 07:37:30 +0100
+
+linux (6.2.0-18.18) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-18.18 -proposed tracker (LP: #2011750)
+
+  * lunar/linux 6.2 fails to boot on arm64 (LP: #2011748)
+    - SAUCE: Revert "efi: random: fix NULL-deref when refreshing seed"
+    - SAUCE: Revert "efi: random: refresh non-volatile random seed when RNG is
+      initialized"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 15 Mar 2023 23:54:18 +0100
+
+linux (6.2.0-17.17) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-17.17 -proposed tracker (LP: #2011593)
+
+  * lunar/linux 6.2 fails to boot on ppc64el (LP: #2011413)
+    - SAUCE: Revert "powerpc: remove STACK_FRAME_OVERHEAD"
+    - SAUCE: Revert "powerpc/pseries: hvcall stack frame overhead"
+
+  * Speaker / Audio/Mic mute LED don't work on a HP platform (LP: #2011379)
+    - SAUCE: ALSA: hda/realtek: fix speaker, mute/micmute LEDs not work on a HP
+      platform
+
+  * Some QHD panels fail to refresh when PSR2 enabled (LP: #2009014)
+    - SAUCE: drm/i915/psr: Use calculated io and fast wake lines
+
+  * Lunar update: v6.2.6 upstream stable release (LP: #2011431)
+    - tpm: disable hwrng for fTPM on some AMD designs
+    - wifi: cfg80211: Partial revert "wifi: cfg80211: Fix use after free for wext"
+    - staging: rtl8192e: Remove function ..dm_check_ac_dc_power calling a script
+    - staging: rtl8192e: Remove call_usermodehelper starting RadioPower.sh
+    - Linux 6.2.6
+
+  * Lunar update: v6.2.5 upstream stable release (LP: #2011430)
+    - net/sched: Retire tcindex classifier
+    - auxdisplay: hd44780: Fix potential memory leak in hd44780_remove()
+    - fs/jfs: fix shift exponent db_agl2size negative
+    - driver: soc: xilinx: fix memory leak in xlnx_add_cb_for_notify_event()
+    - f2fs: don't rely on F2FS_MAP_* in f2fs_iomap_begin
+    - f2fs: fix to avoid potential deadlock
+    - objtool: Fix memory leak in create_static_call_sections()
+    - soc: mediatek: mtk-pm-domains: Allow mt8186 ADSP default power on
+    - soc: qcom: socinfo: Fix soc_id order
+    - memory: renesas-rpc-if: Split-off private data from struct rpcif
+    - memory: renesas-rpc-if: Move resource acquisition to .probe()
+    - soc: mediatek: mtk-svs: Enable the IRQ later
+    - pwm: sifive: Always let the first pwm_apply_state succeed
+    - pwm: stm32-lp: fix the check on arr and cmp registers update
+    - f2fs: introduce trace_f2fs_replace_atomic_write_block
+    - f2fs: clear atomic_write_task in f2fs_abort_atomic_write()
+    - soc: mediatek: mtk-svs: restore default voltages when svs_init02() fail
+    - soc: mediatek: mtk-svs: reset svs when svs_resume() fail
+    - soc: mediatek: mtk-svs: Use pm_runtime_resume_and_get() in svs_init01()
+    - f2fs: fix to do sanity check on extent cache correctly
+    - fs: f2fs: initialize fsdata in pagecache_write()
+    - f2fs: allow set compression option of files without blocks
+    - f2fs: fix to abort atomic write only during do_exist()
+    - um: vector: Fix memory leak in vector_config
+    - ubi: ensure that VID header offset + VID header size <= alloc, size
+    - ubifs: Fix build errors as symbol undefined
+    - ubifs: Fix memory leak in ubifs_sysfs_init()
+    - ubifs: Rectify space budget for ubifs_symlink() if symlink is encrypted
+    - ubifs: Rectify space budget for ubifs_xrename()
+    - ubifs: Fix wrong dirty space budget for dirty inode
+    - ubifs: do_rename: Fix wrong space budget when target inode's nlink > 1
+    - ubifs: Reserve one leb for each journal head while doing budget
+    - ubi: Fix use-after-free when volume resizing failed
+    - ubi: Fix unreferenced object reported by kmemleak in ubi_resize_volume()
+    - ubifs: Fix memory leak in alloc_wbufs()
+    - ubi: Fix possible null-ptr-deref in ubi_free_volume()
+    - ubifs: Re-statistic cleaned znode count if commit failed
+    - ubifs: dirty_cow_znode: Fix memleak in error handling path
+    - ubifs: ubifs_writepage: Mark page dirty after writing inode failed
+    - ubifs: ubifs_releasepage: Remove ubifs_assert(0) to valid this process
+    - ubi: fastmap: Fix missed fm_anchor PEB in wear-leveling after disabling
+      fastmap
+    - ubi: Fix UAF wear-leveling entry in eraseblk_count_seq_show()
+    - ubi: ubi_wl_put_peb: Fix infinite loop when wear-leveling work failed
+    - f2fs: fix to handle F2FS_IOC_START_ATOMIC_REPLACE in f2fs_compat_ioctl()
+    - f2fs: fix to avoid potential memory corruption in __update_iostat_latency()
+    - f2fs: fix to update age extent correctly during truncation
+    - f2fs: fix to update age extent in f2fs_do_zero_range()
+    - soc: qcom: stats: Populate all subsystem debugfs files
+    - f2fs: introduce IS_F2FS_IPU_* macro
+    - f2fs: fix to set ipu policy
+    - ext4: use ext4_fc_tl_mem in fast-commit replay path
+    - ext4: don't show commit interval if it is zero
+    - netfilter: nf_tables: allow to fetch set elements when table has an owner
+    - x86: um: vdso: Add '%rcx' and '%r11' to the syscall clobber list
+    - um: virtio_uml: free command if adding to virtqueue failed
+    - um: virtio_uml: mark device as unregistered when breaking it
+    - um: virtio_uml: move device breaking into workqueue
+    - um: virt-pci: properly remove PCI device from bus
+    - f2fs: synchronize atomic write aborts
+    - watchdog: rzg2l_wdt: Issue a reset before we put the PM clocks
+    - watchdog: rzg2l_wdt: Handle TYPE-B reset for RZ/V2M
+    - watchdog: at91sam9_wdt: use devm_request_irq to avoid missing free_irq() in
+      error path
+    - watchdog: Fix kmemleak in watchdog_cdev_register
+    - watchdog: pcwd_usb: Fix attempting to access uninitialized memory
+    - watchdog: sbsa_wdog: Make sure the timeout programming is within the limits
+    - netfilter: ctnetlink: fix possible refcount leak in
+      ctnetlink_create_conntrack()
+    - netfilter: conntrack: fix rmmod double-free race
+    - netfilter: ip6t_rpfilter: Fix regression with VRF interfaces
+    - netfilter: ebtables: fix table blob use-after-free
+    - netfilter: xt_length: use skb len to match in length_mt6
+    - netfilter: ctnetlink: make event listener tracking global
+    - netfilter: x_tables: fix percpu counter block leak on error path when
+      creating new netns
+    - swiotlb: mark swiotlb_memblock_alloc() as __init
+    - ptp: vclock: use mutex to fix "sleep on atomic" bug
+    - drm/i915: move a Kconfig symbol to unbreak the menu presentation
+    - ipv6: Add lwtunnel encap size of all siblings in nexthop calculation
+    - drm/i915/xelpmp: Consider GSI offset when doing MCR lookups
+    - octeontx2-pf: Recalculate UDP checksum for ptp 1-step sync packet
+    - net: sunhme: Fix region request
+    - sctp: add a refcnt in sctp_stream_priorities to avoid a nested loop
+    - octeontx2-pf: Use correct struct reference in test condition
+    - net: fix __dev_kfree_skb_any() vs drop monitor
+    - 9p/xen: fix version parsing
+    - 9p/xen: fix connection sequence
+    - 9p/rdma: unmap receive dma buffer in rdma_request()/post_recv()
+    - spi: tegra210-quad: Fix validate combined sequence
+    - mlx5: fix skb leak while fifo resync and push
+    - mlx5: fix possible ptp queue fifo use-after-free
+    - net/mlx5: ECPF, wait for VF pages only after disabling host PFs
+    - net/mlx5e: Verify flow_source cap before using it
+    - net/mlx5: Geneve, Fix handling of Geneve object id as error code
+    - ext4: fix incorrect options show of original mount_opt and extend mount_opt2
+    - nfc: fix memory leak of se_io context in nfc_genl_se_io
+    - net/sched: transition act_pedit to rcu and percpu stats
+    - net/sched: act_pedit: fix action bind logic
+    - net/sched: act_mpls: fix action bind logic
+    - net/sched: act_sample: fix action bind logic
+    - net: dsa: seville: ignore mscc-miim read errors from Lynx PCS
+    - net: dsa: felix: fix internal MDIO controller resource length
+    - ARM: dts: aspeed: p10bmc: Update battery node name
+    - ARM: dts: spear320-hmi: correct STMPE GPIO compatible
+    - tcp: tcp_check_req() can be called from process context
+    - vc_screen: modify vcs_size() handling in vcs_read()
+    - spi: tegra210-quad: Fix iterator outside loop
+    - rtc: sun6i: Always export the internal oscillator
+    - genirq/ipi: Fix NULL pointer deref in irq_data_get_affinity_mask()
+    - scsi: ipr: Work around fortify-string warning
+    - scsi: mpi3mr: Fix an issue found by KASAN
+    - scsi: mpi3mr: Use number of bits to manage bitmap sizes
+    - rtc: allow rtc_read_alarm without read_alarm callback
+    - io_uring: fix size calculation when registering buf ring
+    - loop: loop_set_status_from_info() check before assignment
+    - ASoC: adau7118: don't disable regulators on device unbind
+    - ASoC: apple: mca: Fix final status read on SERDES reset
+    - ASoC: apple: mca: Fix SERDES reset sequence
+    - ASoC: apple: mca: Improve handling of unavailable DMA channels
+    - nvme: bring back auto-removal of deleted namespaces during sequential scan
+    - nvme-tcp: don't access released socket during error recovery
+    - nvme-fabrics: show well known discovery name
+    - ASoC: zl38060 add gpiolib dependency
+    - ASoC: mediatek: mt8195: add missing initialization
+    - thermal: intel: quark_dts: fix error pointer dereference
+    - thermal: intel: BXT_PMIC: select REGMAP instead of depending on it
+    - cpufreq: apple-soc: Fix an IS_ERR() vs NULL check
+    - tracing: Add NULL checks for buffer in ring_buffer_free_read_page()
+    - kernel/printk/index.c: fix memory leak with using debugfs_lookup()
+    - firmware/efi sysfb_efi: Add quirk for Lenovo IdeaPad Duet 3
+    - bootconfig: Increase max nodes of bootconfig from 1024 to 8192 for DCC
+      support
+    - mfd: arizona: Use pm_runtime_resume_and_get() to prevent refcnt leak
+    - IB/hfi1: Update RMT size calculation
+    - iommu: Remove deferred attach check from __iommu_detach_device()
+    - PCI/ACPI: Account for _S0W of the target bridge in acpi_pci_bridge_d3()
+    - media: uvcvideo: Remove format descriptions
+    - media: uvcvideo: Handle cameras with invalid descriptors
+    - media: uvcvideo: Handle errors from calls to usb_string
+    - media: uvcvideo: Quirk for autosuspend in Logitech B910 and C910
+    - media: uvcvideo: Silence memcpy() run-time false positive warnings
+    - USB: fix memory leak with using debugfs_lookup()
+    - cacheinfo: Fix shared_cpu_map to handle shared caches at different levels
+    - usb: fotg210: List different variants
+    - dt-bindings: usb: Add device id for Genesys Logic hub controller
+    - staging: emxx_udc: Add checks for dma_alloc_coherent()
+    - tty: fix out-of-bounds access in tty_driver_lookup_tty()
+    - tty: serial: fsl_lpuart: disable the CTS when send break signal
+    - serial: sc16is7xx: setup GPIO controller later in probe
+    - mei: bus-fixup:upon error print return values of send and receive
+    - tools/iio/iio_utils:fix memory leak
+    - bus: mhi: ep: Fix the debug message for MHI_PKT_TYPE_RESET_CHAN_CMD cmd
+    - iio: accel: mma9551_core: Prevent uninitialized variable in
+      mma9551_read_status_word()
+    - iio: accel: mma9551_core: Prevent uninitialized variable in
+      mma9551_read_config_word()
+    - media: uvcvideo: Add GUID for BGRA/X 8:8:8:8
+    - soundwire: bus_type: Avoid lockdep assert in sdw_drv_probe()
+    - PCI/portdrv: Prevent LS7A Bus Master clearing on shutdown
+    - PCI: loongson: Prevent LS7A MRRS increases
+    - staging: pi433: fix memory leak with using debugfs_lookup()
+    - USB: dwc3: fix memory leak with using debugfs_lookup()
+    - USB: chipidea: fix memory leak with using debugfs_lookup()
+    - USB: ULPI: fix memory leak with using debugfs_lookup()
+    - USB: uhci: fix memory leak with using debugfs_lookup()
+    - USB: sl811: fix memory leak with using debugfs_lookup()
+    - USB: fotg210: fix memory leak with using debugfs_lookup()
+    - USB: isp116x: fix memory leak with using debugfs_lookup()
+    - USB: isp1362: fix memory leak with using debugfs_lookup()
+    - USB: gadget: gr_udc: fix memory leak with using debugfs_lookup()
+    - USB: gadget: bcm63xx_udc: fix memory leak with using debugfs_lookup()
+    - USB: gadget: lpc32xx_udc: fix memory leak with using debugfs_lookup()
+    - USB: gadget: pxa25x_udc: fix memory leak with using debugfs_lookup()
+    - USB: gadget: pxa27x_udc: fix memory leak with using debugfs_lookup()
+    - usb: host: xhci: mvebu: Iterate over array indexes instead of using pointer
+      math
+    - USB: ene_usb6250: Allocate enough memory for full object
+    - usb: uvc: Enumerate valid values for color matching
+    - usb: gadget: uvc: Make bSourceID read/write
+    - PCI: Align extra resources for hotplug bridges properly
+    - PCI: Take other bus devices into account when distributing resources
+    - PCI: Distribute available resources for root buses, too
+    - tty: pcn_uart: fix memory leak with using debugfs_lookup()
+    - misc: vmw_balloon: fix memory leak with using debugfs_lookup()
+    - drivers: base: component: fix memory leak with using debugfs_lookup()
+    - drivers: base: dd: fix memory leak with using debugfs_lookup()
+    - kernel/fail_function: fix memory leak with using debugfs_lookup()
+    - PCI: loongson: Add more devices that need MRRS quirk
+    - PCI: Add ACS quirk for Wangxun NICs
+    - PCI: pciehp: Add Qualcomm quirk for Command Completed erratum
+    - phy: rockchip-typec: Fix unsigned comparison with less than zero
+    - RDMA/cma: Distinguish between sockaddr_in and sockaddr_in6 by size
+    - soundwire: cadence: Remove wasted space in response_buf
+    - soundwire: cadence: Drain the RX FIFO after an IO timeout
+    - eth: fealnx: bring back this old driver
+    - net: tls: avoid hanging tasks on the tx_lock
+    - x86/resctl: fix scheduler confusion with 'current'
+    - vDPA/ifcvf: decouple hw features manipulators from the adapter
+    - vDPA/ifcvf: decouple config space ops from the adapter
+    - vDPA/ifcvf: alloc the mgmt_dev before the adapter
+    - vDPA/ifcvf: decouple vq IRQ releasers from the adapter
+    - vDPA/ifcvf: decouple config IRQ releaser from the adapter
+    - vDPA/ifcvf: decouple vq irq requester from the adapter
+    - vDPA/ifcvf: decouple config/dev IRQ requester and vectors allocator from the
+      adapter
+    - vDPA/ifcvf: ifcvf_request_irq works on ifcvf_hw
+    - vDPA/ifcvf: manage ifcvf_hw in the mgmt_dev
+    - vDPA/ifcvf: allocate the adapter in dev_add()
+    - drm/display/dp_mst: Add drm_atomic_get_old_mst_topology_state()
+    - drm/display/dp_mst: Fix down/up message handling after sink disconnect
+    - drm/display/dp_mst: Fix down message handling after a packet reception error
+    - drm/display/dp_mst: Fix payload addition on a disconnected sink
+    - drm/i915/dp_mst: Add the MST topology state for modesetted CRTCs
+    - drm/display/dp_mst: Handle old/new payload states in drm_dp_remove_payload()
+    - drm/i915/dp_mst: Fix payload removal during output disabling
+    - drm/i915: Fix system suspend without fbdev being initialized
+    - media: uvcvideo: Fix race condition with usb_kill_urb
+    - arm64: efi: Make efi_rt_lock a raw_spinlock
+    - usb: gadget: uvc: fix missing mutex_unlock() if kstrtou8() fails
+    - Linux 6.2.5
+
+  * Lunar update: v6.2.4 upstream stable release (LP: #2011428)
+    - Revert "blk-cgroup: synchronize pd_free_fn() from blkg_free_workfn() and
+      blkcg_deactivate_policy()"
+    - Revert "blk-cgroup: dropping parent refcount after pd_free_fn() is done"
+    - Linux 6.2.4
+
+  * Lunar update: v6.2.3 upstream stable release (LP: #2011425)
+    - HID: asus: use spinlock to protect concurrent accesses
+    - HID: asus: use spinlock to safely schedule workers
+    - iommu/amd: Fix error handling for pdev_pri_ats_enable()
+    - iommu/amd: Skip attach device domain is same as new domain
+    - iommu/amd: Improve page fault error reporting
+    - iommu: Attach device group to old domain in error path
+    - powerpc/mm: Rearrange if-else block to avoid clang warning
+    - ata: ahci: Revert "ata: ahci: Add Tiger Lake UP{3,4} AHCI controller"
+    - ARM: OMAP2+: Fix memory leak in realtime_counter_init()
+    - arm64: dts: qcom: qcs404: use symbol names for PCIe resets
+    - arm64: dts: qcom: msm8996-tone: Fix USB taking 6 minutes to wake up
+    - arm64: dts: qcom: sm6115: Fix UFS node
+    - arm64: dts: qcom: sm6115: Provide xo clk to rpmcc
+    - arm64: dts: qcom: sm8150-kumano: Panel framebuffer is 2.5k instead of 4k
+    - arm64: dts: qcom: pmi8950: Correct rev_1250v channel label to mv
+    - arm64: dts: qcom: sm6350: Fix up the ramoops node
+    - arm64: dts: qcom: sdm670-google-sargo: keep pm660 ldo8 on
+    - arm64: dts: qcom: Re-enable resin on MSM8998 and SDM845 boards
+    - arm64: dts: qcom: sm8350-sagami: Configure SLG51000 PMIC on PDX215
+    - arm64: dts: qcom: sm8350-sagami: Add GPIO line names for PMIC GPIOs
+    - arm64: dts: qcom: sm8350-sagami: Rectify GPIO keys
+    - arm64: dts: qcom: sm6350-lena: Flatten gpio-keys pinctrl state
+    - arm64: dts: qcom: sm6125: Reorder HSUSB PHY clocks to match bindings
+    - arm64: dts: qcom: sm6125-seine: Clean up gpio-keys (volume down)
+    - arm64: dts: imx8m: Align SoC unique ID node unit address
+    - ARM: zynq: Fix refcount leak in zynq_early_slcr_init
+    - fs: dlm: fix return value check in dlm_memory_init()
+    - arm64: dts: mediatek: mt8195: Add power domain to U3PHY1 T-PHY
+    - arm64: dts: mediatek: mt8183: Fix systimer 13 MHz clock description
+    - arm64: dts: mediatek: mt8192: Fix systimer 13 MHz clock description
+    - arm64: dts: mediatek: mt8195: Fix systimer 13 MHz clock description
+    - arm64: dts: mediatek: mt8186: Fix systimer 13 MHz clock description
+    - arm64: dts: qcom: sdm845-db845c: fix audio codec interrupt pin name
+    - arm64: dts: qcom: sdm845-xiaomi-beryllium: fix audio codec interrupt pin
+      name
+    - x86/acpi/boot: Do not register processors that cannot be onlined for x2APIC
+    - arm64: dts: qcom: sc7180: correct SPMI bus address cells
+    - arm64: dts: qcom: sc7280: correct SPMI bus address cells
+    - arm64: dts: qcom: sc8280xp: correct SPMI bus address cells
+    - arm64: dts: qcom: sm8450: correct Soundwire wakeup interrupt name
+    - arm64: dts: qcom: sdm845: make DP node follow the schema
+    - arm64: dts: qcom: msm8996-oneplus-common: drop vdda-supply from DSI PHY
+    - arm64: dts: qcom: sc8280xp: Vote for CX in USB controllers
+    - arm64: dts: meson-gxl: jethub-j80: Fix WiFi MAC address node
+    - arm64: dts: meson-gxl: jethub-j80: Fix Bluetooth MAC node name
+    - arm64: dts: meson-axg: jethub-j1xx: Fix MAC address node names
+    - arm64: dts: meson-gx: Fix Ethernet MAC address unit name
+    - arm64: dts: meson-g12a: Fix internal Ethernet PHY unit name
+    - arm64: dts: meson-gx: Fix the SCPI DVFS node name and unit address
+    - cpuidle, intel_idle: Fix CPUIDLE_FLAG_IRQ_ENABLE *again*
+    - arm64: dts: ti: k3-am62-main: Fix clocks for McSPI
+    - arm64: tegra: Fix duplicate regulator on Jetson TX1
+    - arm64: dts: qcom: msm8992-bullhead: Fix cont_splash_mem size
+    - arm64: dts: qcom: msm8992-bullhead: Disable dfps_data_mem
+    - arm64: dts: qcom: msm8956: use SoC-specific compat for tsens
+    - arm64: dts: qcom: ipq8074: correct USB3 QMP PHY-s clock output names
+    - arm64: dts: qcom: ipq8074: fix Gen2 PCIe QMP PHY
+    - arm64: dts: qcom: ipq8074: fix Gen3 PCIe QMP PHY
+    - arm64: dts: qcom: ipq8074: correct Gen2 PCIe ranges
+    - arm64: dts: qcom: ipq8074: fix Gen3 PCIe node
+    - arm64: dts: qcom: ipq8074: correct PCIe QMP PHY output clock names
+    - arm64: dts: meson: remove CPU opps below 1GHz for G12A boards
+    - ARM: OMAP1: call platform_device_put() in error case in
+      omap1_dm_timer_init()
+    - arm64: dts: mediatek: mt8192: Mark scp_adsp clock as broken
+    - ARM: bcm2835_defconfig: Enable the framebuffer
+    - ARM: s3c: fix s3c64xx_set_timer_source prototype
+    - arm64: dts: ti: k3-j7200: Fix wakeup pinmux range
+    - ARM: dts: exynos: correct wr-active property in Exynos3250 Rinato
+    - ARM: imx: Call ida_simple_remove() for ida_simple_get
+    - arm64: dts: amlogic: meson-gx: fix SCPI clock dvfs node name
+    - arm64: dts: amlogic: meson-axg: fix SCPI clock dvfs node name
+    - arm64: dts: amlogic: meson-gx: add missing SCPI sensors compatible
+    - arm64: dts: amlogic: meson-axg-jethome-jethub-j1xx: fix supply name of USB
+      controller node
+    - arm64: dts: amlogic: meson-gxl-s905d-sml5442tw: drop invalid clock-names
+      property
+    - arm64: dts: amlogic: meson-gx: add missing unit address to rng node name
+    - arm64: dts: amlogic: meson-gxl-s905w-jethome-jethub-j80: fix invalid rtc
+      node name
+    - arm64: dts: amlogic: meson-axg-jethome-jethub-j1xx: fix invalid rtc node
+      name
+    - arm64: dts: amlogic: meson-gxl: add missing unit address to eth-phy-mux node
+      name
+    - arm64: dts: amlogic: meson-gx-libretech-pc: fix update button name
+    - arm64: dts: amlogic: meson-sm1-bananapi-m5: fix adc keys node names
+    - arm64: dts: amlogic: meson-gxl-s905d-phicomm-n1: fix led node name
+    - arm64: dts: amlogic: meson-gxbb-kii-pro: fix led node name
+    - arm64: dts: amlogic: meson-g12b-odroid-go-ultra: fix rk818 pmic properties
+    - arm64: dts: amlogic: meson-sm1-odroid-hc4: fix active fan thermal trip
+    - locking/rwsem: Disable preemption in all down_read*() and up_read() code
+      paths
+    - arm64: tegra: Mark host1x as dma-coherent on Tegra194/234
+    - arm64: dts: renesas: beacon-renesom: Fix gpio expander reference
+    - arm64: dts: meson: radxa-zero: allow usb otg mode
+    - arm64: dts: meson: bananapi-m5: switch VDDIO_C pin to OPEN_DRAIN
+    - ARM: dts: sun8i: nanopi-duo2: Fix regulator GPIO reference
+    - ublk_drv: remove nr_aborted_queues from ublk_device
+    - ublk_drv: don't probe partitions if the ubq daemon isn't trusted
+    - ARM: dts: imx7s: correct iomuxc gpr mux controller cells
+    - sbitmap: remove redundant check in __sbitmap_queue_get_batch
+    - sbitmap: correct wake_batch recalculation to avoid potential IO hung
+    - arm64: dts: mt8195: Fix CPU map for single-cluster SoC
+    - arm64: dts: mt8192: Fix CPU map for single-cluster SoC
+    - arm64: dts: mt8186: Fix CPU map for single-cluster SoC
+    - arm64: dts: mediatek: mt7622: Add missing pwm-cells to pwm node
+    - arm64: dts: mediatek: mt8186: Fix watchdog compatible
+    - arm64: dts: mediatek: mt8195: Fix watchdog compatible
+    - arm64: dts: mediatek: mt7986: Fix watchdog compatible
+    - ARM: dts: stm32: Update part number NVMEM description on stm32mp131
+    - arm64: dts: qcom: sm8450-nagara: Correct firmware paths
+    - blk-mq: avoid sleep in blk_mq_alloc_request_hctx
+    - blk-mq: remove stale comment for blk_mq_sched_mark_restart_hctx
+    - blk-mq: wait on correct sbitmap_queue in blk_mq_mark_tag_wait
+    - blk-mq: Fix potential io hung for shared sbitmap per tagset
+    - blk-mq: correct stale comment of .get_budget
+    - arm64: dts: qcom: msm8996: support using GPLL0 as kryocc input
+    - arm64: dts: qcom: msm8996 switch from RPM_SMD_BB_CLK1 to RPM_SMD_XO_CLK_SRC
+    - arm64: dts: qcom: sm8350: drop incorrect cells from serial
+    - arm64: dts: qcom: sm8450: drop incorrect cells from serial
+    - arm64: dts: qcom: msm8992-lg-bullhead: Correct memory overlaps with the SMEM
+      and MPSS memory regions
+    - arm64: dts: qcom: msm8953: correct TLMM gpio-ranges
+    - arm64: dts: qcom: sm6115: correct TLMM gpio-ranges
+    - arm64: dts: qcom: msm8992-lg-bullhead: Enable regulators
+    - s390/dasd: Fix potential memleak in dasd_eckd_init()
+    - io_uring,audit: don't log IORING_OP_MADVISE
+    - sched/rt: pick_next_rt_entity(): check list_entry
+    - perf/x86/intel/ds: Fix the conversion from TSC to perf time
+    - x86/perf/zhaoxin: Add stepping check for ZXC
+    - KEYS: asymmetric: Fix ECDSA use via keyctl uapi
+    - block: ublk: check IO buffer based on flag need_get_data
+    - arm64: dts: qcom: pmk8350: Use the correct PON compatible
+    - erofs: relinquish volume with mutex held
+    - block: sync mixed merged request's failfast with 1st bio's
+    - block: Fix io statistics for cgroup in throttle path
+    - block: bio-integrity: Copy flags when bio_integrity_payload is cloned
+    - block: use proper return value from bio_failfast()
+    - wifi: mt76: mt7915: add missing of_node_put()
+    - wifi: mt76: mt7921s: fix slab-out-of-bounds access in sdio host
+    - wifi: mt76: mt7915: fix mt7915_rate_txpower_get() resource leaks
+    - wifi: mt76: mt7996: fix insecure data handling of mt7996_mcu_ie_countdown()
+    - wifi: mt76: mt7996: fix insecure data handling of
+      mt7996_mcu_rx_radar_detected()
+    - wifi: mt76: mt7996: fix integer handling issue of mt7996_rf_regval_set()
+    - wifi: mt76: mt7915: check return value before accessing free_block_num
+    - wifi: mt76: mt7996: check return value before accessing free_block_num
+    - wifi: mt76: mt7915: drop always true condition of __mt7915_reg_addr()
+    - wifi: mt76: mt7996: drop always true condition of __mt7996_reg_addr()
+    - wifi: mt76: mt7996: fix endianness warning in mt7996_mcu_sta_he_tlv
+    - wifi: mt76: mt76x0: fix oob access in mt76x0_phy_get_target_power
+    - wifi: mt76: mt7996: fix unintended sign extension of mt7996_hw_queue_read()
+    - wifi: mt76: mt7915: fix unintended sign extension of mt7915_hw_queue_read()
+    - wifi: mt76: fix coverity uninit_use_in_call in
+      mt76_connac2_reverse_frag0_hdr_trans()
+    - wifi: mt76: mt7921: resource leaks at mt7921_check_offload_capability()
+    - wifi: rsi: Fix memory leak in rsi_coex_attach()
+    - wifi: rtlwifi: rtl8821ae: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: rtlwifi: rtl8188ee: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: rtlwifi: rtl8723be: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: iwlegacy: common: don't call dev_kfree_skb() under spin_lock_irqsave()
+    - wifi: libertas: fix memory leak in lbs_init_adapter()
+    - wifi: rtl8xxxu: Fix assignment to bit field priv->pi_enabled
+    - wifi: rtl8xxxu: Fix assignment to bit field priv->cck_agc_report_type
+    - wifi: rtl8xxxu: don't call dev_kfree_skb() under spin_lock_irqsave()
+    - wifi: rtw89: 8852c: rfk: correct DACK setting
+    - wifi: rtw89: 8852c: rfk: correct DPK settings
+    - wifi: rtlwifi: Fix global-out-of-bounds bug in
+      _rtl8812ae_phy_set_txpower_limit()
+    - libbpf: Fix single-line struct definition output in btf_dump
+    - libbpf: Fix btf__align_of() by taking into account field offsets
+    - wifi: ipw2x00: don't call dev_kfree_skb() under spin_lock_irqsave()
+    - wifi: ipw2200: fix memory leak in ipw_wdev_init()
+    - wifi: wilc1000: fix potential memory leak in wilc_mac_xmit()
+    - wifi: wilc1000: add missing unregister_netdev() in wilc_netdev_ifc_init()
+    - wifi: brcmfmac: fix potential memory leak in brcmf_netdev_start_xmit()
+    - wifi: brcmfmac: unmap dma buffer in brcmf_msgbuf_alloc_pktid()
+    - wifi: libertas_tf: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: libertas: if_usb: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: libertas: main: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: libertas: cmdresp: don't call kfree_skb() under spin_lock_irqsave()
+    - wifi: wl3501_cs: don't call kfree_skb() under spin_lock_irqsave()
+    - libbpf: Fix invalid return address register in s390
+    - crypto: x86/ghash - fix unaligned access in ghash_setkey()
+    - crypto: ux500 - update debug config after ux500 cryp driver removal
+    - ACPICA: Drop port I/O validation for some regions
+    - genirq: Fix the return type of kstat_cpu_irqs_sum()
+    - rcu-tasks: Improve comments explaining tasks_rcu_exit_srcu purpose
+    - rcu-tasks: Remove preemption disablement around srcu_read_[un]lock() calls
+    - rcu-tasks: Fix synchronize_rcu_tasks() VS zap_pid_ns_processes()
+    - lib/mpi: Fix buffer overrun when SG is too long
+    - crypto: ccp - Avoid page allocation failure warning for SEV_GET_ID2
+    - platform/chrome: cros_ec_typec: Update port DP VDO
+    - ACPICA: nsrepair: handle cases without a return value correctly
+    - libbpf: Fix map creation flags sanitization
+    - bpf_doc: Fix build error with older python versions
+    - selftests/xsk: print correct payload for packet dump
+    - selftests/xsk: print correct error codes when exiting
+    - arm64/cpufeature: Fix field sign for DIT hwcap detection
+    - arm64/sysreg: Fix errors in 32 bit enumeration values
+    - kselftest/arm64: Fix syscall-abi for systems without 128 bit SME
+    - workqueue: Protects wq_unbound_cpumask with wq_pool_attach_mutex
+    - s390/early: fix sclp_early_sccb variable lifetime
+    - s390/vfio-ap: fix an error handling path in vfio_ap_mdev_probe_queue()
+    - x86/signal: Fix the value returned by strict_sas_size()
+    - thermal/drivers/tsens: Drop msm8976-specific defines
+    - thermal/drivers/tsens: Sort out msm8976 vs msm8956 data
+    - thermal/drivers/tsens: fix slope values for msm8939
+    - thermal/drivers/tsens: limit num_sensors to 9 for msm8939
+    - wifi: rtw89: fix potential leak in rtw89_append_probe_req_ie()
+    - wifi: rtw89: Add missing check for alloc_workqueue
+    - wifi: rtl8xxxu: Fix memory leaks with RTL8723BU, RTL8192EU
+    - wifi: orinoco: check return value of hermes_write_wordrec()
+    - wifi: rtw88: Use rtw_iterate_vifs() for rtw_vif_watch_dog_iter()
+    - wifi: rtw88: Use non-atomic sta iterator in rtw_ra_mask_info_update()
+    - thermal/drivers/imx_sc_thermal: Fix the loop condition
+    - wifi: ath9k: htc_hst: free skb in ath9k_htc_rx_msg() if there is no callback
+      function
+    - wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
+    - wifi: ath9k: Fix potential stack-out-of-bounds write in
+      ath9k_wmi_rsp_callback()
+    - wifi: ath11k: Fix memory leak in ath11k_peer_rx_frag_setup
+    - wifi: cfg80211: Fix extended KCK key length check in
+      nl80211_set_rekey_data()
+    - ACPI: battery: Fix missing NUL-termination with large strings
+    - selftests/bpf: Fix build errors if CONFIG_NF_CONNTRACK=m
+    - crypto: ccp - Failure on re-initialization due to duplicate sysfs filename
+    - crypto: essiv - Handle EBUSY correctly
+    - crypto: seqiv - Handle EBUSY correctly
+    - powercap: fix possible name leak in powercap_register_zone()
+    - bpf: Fix state pruning for STACK_DYNPTR stack slots
+    - bpf: Fix missing var_off check for ARG_PTR_TO_DYNPTR
+    - bpf: Fix partial dynptr stack slot reads/writes
+    - x86/microcode: Add a parameter to microcode_check() to store CPU
+      capabilities
+    - x86/microcode: Check CPU capabilities after late microcode update correctly
+    - x86/microcode: Adjust late loading result reporting message
+    - net: ethernet: ti: am65-cpsw/cpts: Fix CPTS release action
+    - selftests/bpf: Fix vmtest static compilation error
+    - crypto: xts - Handle EBUSY correctly
+    - leds: led-class: Add missing put_device() to led_put()
+    - drm/nouveau/disp: Fix nvif_outp_acquire_dp() argument size
+    - s390/bpf: Add expoline to tail calls
+    - wifi: iwlwifi: mei: fix compilation errors in rfkill()
+    - kselftest/arm64: Fix enumeration of systems without 128 bit SME
+    - can: rcar_canfd: Fix R-Car V3U CAN mode selection
+    - can: rcar_canfd: Fix R-Car V3U GAFLCFG field accesses
+    - selftests/bpf: Initialize tc in xdp_synproxy
+    - crypto: ccp - Flush the SEV-ES TMR memory before giving it to firmware
+    - bpftool: profile online CPUs instead of possible
+    - wifi: mt76: mt7921: fix deadlock in mt7921_abort_roc
+    - wifi: mt76: mt7915: call mt7915_mcu_set_thermal_throttling() only after
+      init_work
+    - wifi: mt76: mt7915: rework mt7915_mcu_set_thermal_throttling
+    - wifi: mt76: mt7915: rework mt7915_thermal_temp_store()
+    - wifi: mt76: mt7921: fix channel switch fail in monitor mode
+    - wifi: mt76: mt7996: fix chainmask calculation in mt7996_set_antenna()
+    - wifi: mt76: mt7996: update register for CFEND_RATE
+    - wifi: mt76: connac: fix POWER_CTRL command name typo
+    - wifi: mt76: mt7921: fix invalid remain_on_channel duration
+    - wifi: mt76: mt7915: fix memory leak in mt7915_mcu_exit
+    - wifi: mt76: mt7996: fix memory leak in mt7996_mcu_exit
+    - wifi: mt76: dma: fix memory leak running mt76_dma_tx_cleanup
+    - wifi: mt76: fix switch default case in mt7996_reverse_frag0_hdr_trans
+    - wifi: mt76: mt7915: fix WED TxS reporting
+    - wifi: mt76: add memory barrier to SDIO queue kick
+    - wifi: mt76: mt7996: rely on mt76_connac2_mac_tx_rate_val
+    - net/mlx5: Enhance debug print in page allocation failure
+    - irqchip: Fix refcount leak in platform_irqchip_probe
+    - irqchip/alpine-msi: Fix refcount leak in alpine_msix_init_domains
+    - irqchip/irq-mvebu-gicp: Fix refcount leak in mvebu_gicp_probe
+    - irqchip/ti-sci: Fix refcount leak in ti_sci_intr_irq_domain_probe
+    - s390/mem_detect: fix detect_memory() error handling
+    - s390/vmem: fix empty page tables cleanup under KASAN
+    - s390/boot: cleanup decompressor header files
+    - s390/mem_detect: rely on diag260() if sclp_early_get_memsize() fails
+    - s390/boot: fix mem_detect extended area allocation
+    - net: add sock_init_data_uid()
+    - tun: tun_chr_open(): correctly initialize socket uid
+    - tap: tap_open(): correctly initialize socket uid
+    - rxrpc: Fix overwaking on call poking
+    - OPP: fix error checking in opp_migrate_dentry()
+    - cpufreq: davinci: Fix clk use after free
+    - Bluetooth: hci_conn: Refactor hci_bind_bis() since it always succeeds
+    - Bluetooth: L2CAP: Fix potential user-after-free
+    - Bluetooth: hci_qca: get wakeup status from serdev device handle
+    - net: ipa: generic command param fix
+    - s390: vfio-ap: tighten the NIB validity check
+    - s390/ap: fix status returned by ap_aqic()
+    - s390/ap: fix status returned by ap_qact()
+    - libbpf: Fix alen calculation in libbpf_nla_dump_errormsg()
+    - xen/grant-dma-iommu: Implement a dummy probe_device() callback
+    - rds: rds_rm_zerocopy_callback() correct order for list_add_tail()
+    - crypto: rsa-pkcs1pad - Use akcipher_request_complete
+    - m68k: /proc/hardware should depend on PROC_FS
+    - RISC-V: time: initialize hrtimer based broadcast clock event device
+    - clocksource/drivers/riscv: Patch riscv_clock_next_event() jump before first
+      use
+    - wifi: iwl3945: Add missing check for create_singlethread_workqueue
+    - wifi: iwl4965: Add missing check for create_singlethread_workqueue()
+    - wifi: brcmfmac: Rename Cypress 89459 to BCM4355
+    - wifi: brcmfmac: pcie: Add IDs/properties for BCM4355
+    - wifi: brcmfmac: pcie: Add IDs/properties for BCM4377
+    - wifi: brcmfmac: pcie: Perform correct BCM4364 firmware selection
+    - wifi: mwifiex: fix loop iterator in mwifiex_update_ampdu_txwinsize()
+    - wifi: rtw89: fix parsing offset for MCC C2H
+    - selftests/bpf: Fix out-of-srctree build
+    - ACPI: resource: Add IRQ overrides for MAINGEAR Vector Pro 2 models
+    - ACPI: resource: Do IRQ override on all TongFang GMxRGxx
+    - crypto: octeontx2 - Fix objects shared between several modules
+    - crypto: crypto4xx - Call dma_unmap_page when done
+    - vfio/ccw: remove WARN_ON during shutdown
+    - wifi: mac80211: move color collision detection report in a delayed work
+    - wifi: mac80211: make rate u32 in sta_set_rate_info_rx()
+    - wifi: mac80211: fix non-MLO station association
+    - wifi: mac80211: Don't translate MLD addresses for multicast
+    - wifi: mac80211: avoid u32_encode_bits() warning
+    - wifi: mac80211: fix off-by-one link setting
+    - tools/lib/thermal: Fix thermal_sampling_exit()
+    - thermal/drivers/hisi: Drop second sensor hi3660
+    - selftests/bpf: Fix map_kptr test.
+    - wifi: mac80211: pass 'sta' to ieee80211_rx_data_set_sta()
+    - bpf: Zeroing allocated object from slab in bpf memory allocator
+    - selftests/bpf: Fix xdp_do_redirect on s390x
+    - can: esd_usb: Move mislocated storage of SJA1000_ECC_SEG bits in case of a
+      bus error
+    - can: esd_usb: Make use of can_change_state() and relocate checking skb for
+      NULL
+    - xsk: check IFF_UP earlier in Tx path
+    - LoongArch, bpf: Use 4 instructions for function address in JIT
+    - bpf: Fix global subprog context argument resolution logic
+    - irqchip/irq-brcmstb-l2: Set IRQ_LEVEL for level triggered interrupts
+    - irqchip/irq-bcm7120-l2: Set IRQ_LEVEL for level triggered interrupts
+    - net/smc: fix potential panic dues to unprotected smc_llc_srv_add_link()
+    - net/smc: fix application data exception
+    - selftests/net: Interpret UDP_GRO cmsg data as an int value
+    - l2tp: Avoid possible recursive deadlock in l2tp_tunnel_register()
+    - net: bcmgenet: fix MoCA LED control
+    - net: lan966x: Fix possible deadlock inside PTP
+    - net/mlx4_en: Introduce flexible array to silence overflow warning
+    - net/mlx5e: Align IPsec ASO result memory to be as required by hardware
+    - selftest: fib_tests: Always cleanup before exit
+    - sefltests: netdevsim: wait for devlink instance after netns removal
+    - drm: Fix potential null-ptr-deref due to drmm_mode_config_init()
+    - drm/fourcc: Add missing big-endian XRGB1555 and RGB565 formats
+    - drm/bridge: ti-sn65dsi83: Fix delay after reset deassert to match spec
+    - drm: mxsfb: DRM_IMX_LCDIF should depend on ARCH_MXC
+    - drm: mxsfb: DRM_MXSFB should depend on ARCH_MXS || ARCH_MXC
+    - drm/bridge: megachips: Fix error handling in i2c_register_driver()
+    - drm/vkms: Fix memory leak in vkms_init()
+    - drm/vkms: Fix null-ptr-deref in vkms_release()
+    - drm/modes: Use strscpy() to copy command-line mode name
+    - drm/vc4: dpi: Fix format mapping for RGB565
+    - drm/bridge: it6505: Guard bridge power in IRQ handler
+    - drm: tidss: Fix pixel format definition
+    - gpu: ipu-v3: common: Add of_node_put() for reference returned by
+      of_graph_get_port_by_id()
+    - drm/ast: Init iosys_map pointer as I/O memory for damage handling
+    - drm/vc4: drop all currently held locks if deadlock happens
+    - hwmon: (ftsteutates) Fix scaling of measurements
+    - drm/msm/dpu: check for null return of devm_kzalloc() in dpu_writeback_init()
+    - drm/msm/hdmi: Add missing check for alloc_ordered_workqueue
+    - pinctrl: qcom: pinctrl-msm8976: Correct function names for wcss pins
+    - pinctrl: stm32: Fix refcount leak in stm32_pctrl_get_irq_domain
+    - pinctrl: rockchip: Fix refcount leak in rockchip_pinctrl_parse_groups
+    - drm/vc4: hvs: Configure the HVS COB allocations
+    - drm/vc4: hvs: Set AXI panic modes
+    - drm/vc4: hvs: SCALER_DISPBKGND_AUTOHS is only valid on HVS4
+    - drm/vc4: hvs: Correct interrupt masking bit assignment for HVS5
+    - drm/vc4: hvs: Fix colour order for xRGB1555 on HVS5
+    - drm/vc4: hdmi: Correct interlaced timings again
+    - drm/msm: clean event_thread->worker in case of an error
+    - drm/panel-edp: fix name for IVO product id 854b
+    - scsi: qla2xxx: Fix exchange oversubscription
+    - scsi: qla2xxx: Fix exchange oversubscription for management commands
+    - scsi: qla2xxx: edif: Fix clang warning
+    - ASoC: fsl_sai: initialize is_dsp_mode flag
+    - drm/bridge: tc358767: Set default CLRSIPO count
+    - drm/msm/adreno: Fix null ptr access in adreno_gpu_cleanup()
+    - ALSA: hda/ca0132: minor fix for allocation size
+    - drm/amdgpu: Use the sched from entity for amdgpu_cs trace
+    - drm/msm/gem: Add check for kmalloc
+    - drm/msm/dpu: Disallow unallocated resources to be returned
+    - drm/bridge: lt9611: fix sleep mode setup
+    - drm/bridge: lt9611: fix HPD reenablement
+    - drm/bridge: lt9611: fix polarity programming
+    - drm/bridge: lt9611: fix programming of video modes
+    - drm/bridge: lt9611: fix clock calculation
+    - drm/bridge: lt9611: pass a pointer to the of node
+    - regulator: tps65219: use IS_ERR() to detect an error pointer
+    - drm/mipi-dsi: Fix byte order of 16-bit DCS set/get brightness
+    - drm: exynos: dsi: Fix MIPI_DSI*_NO_* mode flags
+    - drm/msm/dsi: Allow 2 CTRLs on v2.5.0
+    - scsi: ufs: exynos: Fix DMA alignment for PAGE_SIZE != 4096
+    - drm/msm/dpu: sc7180: add missing WB2 clock control
+    - drm/msm: use strscpy instead of strncpy
+    - drm/msm/dpu: Add check for cstate
+    - drm/msm/dpu: Add check for pstates
+    - drm/msm/mdp5: Add check for kzalloc
+    - habanalabs: bugs fixes in timestamps buff alloc
+    - pinctrl: bcm2835: Remove of_node_put() in bcm2835_of_gpio_ranges_fallback()
+    - pinctrl: mediatek: Initialize variable pullen and pullup to zero
+    - pinctrl: mediatek: Initialize variable *buf to zero
+    - gpu: host1x: Fix mask for syncpoint increment register
+    - gpu: host1x: Don't skip assigning syncpoints to channels
+    - drm/tegra: firewall: Check for is_addr_reg existence in IMM check
+    - drm/i915/mtl: Add initial gt workarounds
+    - drm/i915/xehp: GAM registers don't need to be re-applied on engine resets
+    - pinctrl: renesas: rzg2l: Fix configuring the GPIO pins as interrupts
+    - drm/i915/xehp: Annotate a couple more workaround registers as MCR
+    - drm/msm/dpu: set pdpu->is_rt_pipe early in dpu_plane_sspp_atomic_update()
+    - drm/mediatek: dsi: Reduce the time of dsi from LP11 to sending cmd
+    - drm/mediatek: Use NULL instead of 0 for NULL pointer
+    - drm/mediatek: Drop unbalanced obj unref
+    - drm/mediatek: mtk_drm_crtc: Add checks for devm_kcalloc
+    - drm/mediatek: Clean dangling pointer on bind error path
+    - ASoC: soc-compress.c: fixup private_data on snd_soc_new_compress()
+    - dt-bindings: display: mediatek: Fix the fallback for mediatek,mt8186-disp-
+      ccorr
+    - gpio: pca9570: rename platform_data to chip_data
+    - gpio: vf610: connect GPIO label to dev name
+    - ASoC: topology: Properly access value coming from topology file
+    - spi: dw_bt1: fix MUX_MMIO dependencies
+    - ASoC: mchp-spdifrx: fix controls which rely on rsr register
+    - ASoC: mchp-spdifrx: fix return value in case completion times out
+    - ASoC: mchp-spdifrx: fix controls that works with completion mechanism
+    - ASoC: mchp-spdifrx: disable all interrupts in mchp_spdifrx_dai_remove()
+    - dm: improve shrinker debug names
+    - regmap: apply reg_base and reg_downshift for single register ops
+    - accel: fix CONFIG_DRM dependencies
+    - ASoC: rsnd: fixup #endif position
+    - ASoC: mchp-spdifrx: Fix uninitialized use of mr in mchp_spdifrx_hw_params()
+    - ASoC: dt-bindings: meson: fix gx-card codec node regex
+    - regulator: tps65219: use generic set_bypass()
+    - hwmon: (asus-ec-sensors) add missing mutex path
+    - hwmon: (ltc2945) Handle error case in ltc2945_value_store
+    - ALSA: hda: Fix the control element identification for multiple codecs
+    - drm/amdgpu: fix enum odm_combine_mode mismatch
+    - scsi: mpt3sas: Fix a memory leak
+    - scsi: aic94xx: Add missing check for dma_map_single()
+    - HID: multitouch: Add quirks for flipped axes
+    - HID: retain initial quirks set up when creating HID devices
+    - ASoC: qcom: q6apm-lpass-dai: unprepare stream if its already prepared
+    - ASoC: qcom: q6apm-dai: fix race condition while updating the position
+      pointer
+    - ASoC: qcom: q6apm-dai: Add SNDRV_PCM_INFO_BATCH flag
+    - ASoC: codecs: lpass: register mclk after runtime pm
+    - ASoC: codecs: lpass: fix incorrect mclk rate
+    - drm/amd/display: don't call dc_interrupt_set() for disabled crtcs
+    - HID: logitech-hidpp: Hard-code HID++ 1.0 fast scroll support
+    - spi: bcm63xx-hsspi: Fix multi-bit mode setting
+    - hwmon: (mlxreg-fan) Return zero speed for broken fan
+    - ASoC: tlv320adcx140: fix 'ti,gpio-config' DT property init
+    - dm: remove flush_scheduled_work() during local_exit()
+    - nfs4trace: fix state manager flag printing
+    - NFS: fix disabling of swap
+    - drm/i915/pvc: Implement recommended caching policy
+    - drm/i915/pvc: Annotate two more workaround/tuning registers as MCR
+    - drm/i915: Fix GEN8_MISCCPCTL
+    - spi: synquacer: Fix timeout handling in synquacer_spi_transfer_one()
+    - ASoC: soc-dapm.h: fixup warning struct snd_pcm_substream not declared
+    - HID: bigben: use spinlock to protect concurrent accesses
+    - HID: bigben_worker() remove unneeded check on report_field
+    - HID: bigben: use spinlock to safely schedule workers
+    - hid: bigben_probe(): validate report count
+    - ALSA: hda/hdmi: Register with vga_switcheroo on Dual GPU Macbooks
+    - drm/shmem-helper: Fix locking for drm_gem_shmem_get_pages_sgt()
+    - NFSD: enhance inter-server copy cleanup
+    - NFSD: fix leaked reference count of nfsd4_ssc_umount_item
+    - nfsd: fix race to check ls_layouts
+    - nfsd: clean up potential nfsd_file refcount leaks in COPY codepath
+    - NFSD: fix problems with cleanup on errors in nfsd4_copy
+    - nfsd: fix courtesy client with deny mode handling in nfs4_upgrade_open
+    - nfsd: don't fsync nfsd_files on last close
+    - NFSD: copy the whole verifier in nfsd_copy_write_verifier
+    - cifs: Fix lost destroy smbd connection when MR allocate failed
+    - cifs: Fix warning and UAF when destroy the MR list
+    - cifs: use tcon allocation functions even for dummy tcon
+    - gfs2: jdata writepage fix
+    - perf llvm: Fix inadvertent file creation
+    - leds: led-core: Fix refcount leak in of_led_get()
+    - leds: is31fl319x: Wrap mutex_destroy() for devm_add_action_or_rest()
+    - leds: simatic-ipc-leds-gpio: Make sure we have the GPIO providing driver
+    - tools/tracing/rtla: osnoise_hist: use total duration for average calculation
+    - perf inject: Use perf_data__read() for auxtrace
+    - perf intel-pt: Do not try to queue auxtrace data on pipe
+    - perf stat: Hide invalid uncore event output for aggr mode
+    - perf jevents: Correct bad character encoding
+    - perf test bpf: Skip test if kernel-debuginfo is not present
+    - perf tools: Fix auto-complete on aarch64
+    - perf stat: Avoid merging/aggregating metric counts twice
+    - sparc: allow PM configs for sparc32 COMPILE_TEST
+    - selftests: find echo binary to use -ne options
+    - selftests/ftrace: Fix bash specific "==" operator
+    - selftests: use printf instead of echo -ne
+    - perf record: Fix segfault with --overwrite and --max-size
+    - printf: fix errname.c list
+    - perf tests stat_all_metrics: Change true workload to sleep workload for
+      system wide check
+    - objtool: add UACCESS exceptions for __tsan_volatile_read/write
+    - selftests/ftrace: Fix probepoint testcase to ignore __pfx_* symbols
+    - sysctl: fix proc_dobool() usability
+    - mfd: rk808: Re-add rk808-clkout to RK818
+    - mfd: cs5535: Don't build on UML
+    - mfd: pcf50633-adc: Fix potential memleak in pcf50633_adc_async_read()
+    - dmaengine: idxd: Set traffic class values in GRPCFG on DSA 2.0
+    - RDMA/erdma: Fix refcount leak in erdma_mmap
+    - dmaengine: HISI_DMA should depend on ARCH_HISI
+    - RDMA/hns: Fix refcount leak in hns_roce_mmap
+    - iio: light: tsl2563: Do not hardcode interrupt trigger type
+    - usb: gadget: fusb300_udc: free irq on the error path in fusb300_probe()
+    - i2c: designware: fix i2c_dw_clk_rate() return size to be u32
+    - i2c: qcom-geni: change i2c_master_hub to static
+    - soundwire: cadence: Don't overflow the command FIFOs
+    - driver core: fix potential null-ptr-deref in device_add()
+    - kobject: Fix slab-out-of-bounds in fill_kobj_path()
+    - alpha/boot/tools/objstrip: fix the check for ELF header
+    - media: uvcvideo: Check for INACTIVE in uvc_ctrl_is_accessible()
+    - media: uvcvideo: Implement mask for V4L2_CTRL_TYPE_MENU
+    - media: uvcvideo: Refactor uvc_ctrl_mappings_uvcXX
+    - media: uvcvideo: Refactor power_line_frequency_controls_limited
+    - coresight: etm4x: Fix accesses to TRCSEQRSTEVR and TRCSEQSTR
+    - coresight: cti: Prevent negative values of enable count
+    - coresight: cti: Add PM runtime call in enable_store
+    - usb: typec: intel_pmc_mux: Don't leak the ACPI device reference count
+    - PCI/IOV: Enlarge virtfn sysfs name buffer
+    - PCI: switchtec: Return -EFAULT for copy_to_user() errors
+    - PCI: endpoint: pci-epf-vntb: Add epf_ntb_mw_bar_clear() num_mws kernel-doc
+    - hwtracing: hisi_ptt: Only add the supported devices to the filters list
+    - tty: serial: fsl_lpuart: disable Rx/Tx DMA in lpuart32_shutdown()
+    - tty: serial: fsl_lpuart: clear LPUART Status Register in lpuart32_shutdown()
+    - serial: tegra: Add missing clk_disable_unprepare() in tegra_uart_hw_init()
+    - Revert "char: pcmcia: cm4000_cs: Replace mdelay with usleep_range in
+      set_protocol"
+    - eeprom: idt_89hpesx: Fix error handling in idt_init()
+    - applicom: Fix PCI device refcount leak in applicom_init()
+    - firmware: stratix10-svc: add missing gen_pool_destroy() in
+      stratix10_svc_drv_probe()
+    - firmware: stratix10-svc: fix error handle while alloc/add device failed
+    - VMCI: check context->notify_page after call to get_user_pages_fast() to
+      avoid GPF
+    - mei: pxp: Use correct macros to initialize uuid_le
+    - misc/mei/hdcp: Use correct macros to initialize uuid_le
+    - misc: fastrpc: Fix an error handling path in fastrpc_rpmsg_probe()
+    - iommu/exynos: Fix error handling in exynos_iommu_init()
+    - driver core: fix resource leak in device_add()
+    - driver core: location: Free struct acpi_pld_info *pld before return false
+    - drivers: base: transport_class: fix possible memory leak
+    - drivers: base: transport_class: fix resource leak when
+      transport_add_device() fails
+    - firmware: dmi-sysfs: Fix null-ptr-deref in dmi_sysfs_register_handle
+    - selftests: iommu: Fix test_cmd_destroy_access() call in user_copy
+    - iommufd: Add three missing structures in ucmd_buffer
+    - fotg210-udc: Add missing completion handler
+    - dmaengine: dw-edma: Fix missing src/dst address of interleaved xfers
+    - fpga: microchip-spi: move SPI I/O buffers out of stack
+    - fpga: microchip-spi: rewrite status polling in a time measurable way
+    - usb: early: xhci-dbc: Fix a potential out-of-bound memory access
+    - tty: serial: fsl_lpuart: Fix the wrong RXWATER setting for rx dma case
+    - RDMA/cxgb4: add null-ptr-check after ip_dev_find()
+    - usb: musb: mediatek: don't unregister something that wasn't registered
+    - usb: gadget: configfs: Restrict symlink creation is UDC already binded
+    - phy: mediatek: remove temporary variable @mask_
+    - PCI: mt7621: Delay phy ports initialization
+    - iommu/vt-d: Set No Execute Enable bit in PASID table entry
+    - power: supply: remove faulty cooling logic
+    - RDMA/siw: Fix user page pinning accounting
+    - RDMA/cxgb4: Fix potential null-ptr-deref in pass_establish()
+    - usb: max-3421: Fix setting of I/O pins
+    - RDMA/irdma: Cap MSIX used to online CPUs + 1
+    - serial: fsl_lpuart: fix RS485 RTS polariy inverse issue
+    - tty: serial: imx: disable Ageing Timer interrupt request irq
+    - driver core: fw_devlink: Add DL_FLAG_CYCLE support to device links
+    - driver core: fw_devlink: Don't purge child fwnode's consumer links
+    - driver core: fw_devlink: Allow marking a fwnode link as being part of a
+      cycle
+    - driver core: fw_devlink: Consolidate device link flag computation
+    - driver core: fw_devlink: Improve check for fwnode with no device/driver
+    - driver core: fw_devlink: Make cycle detection more robust
+    - mtd: mtdpart: Don't create platform device that'll never probe
+    - usb: host: fsl-mph-dr-of: reuse device_set_of_node_from_dev
+    - dmaengine: dw-edma: Fix readq_ch() return value truncation
+    - PCI: Fix dropping valid root bus resources with .end = zero
+    - phy: rockchip-typec: fix tcphy_get_mode error case
+    - PCI: qcom: Fix host-init error handling
+    - iw_cxgb4: Fix potential NULL dereference in c4iw_fill_res_cm_id_entry()
+    - iommu: Fix error unwind in iommu_group_alloc()
+    - iommu/amd: Do not identity map v2 capable device when snp is enabled
+    - dmaengine: sf-pdma: pdma_desc memory leak fix
+    - dmaengine: dw-axi-dmac: Do not dereference NULL structure
+    - dmaengine: ptdma: check for null desc before calling pt_cmd_callback
+    - iommu/vt-d: Fix error handling in sva enable/disable paths
+    - iommu/vt-d: Allow to use flush-queue when first level is default
+    - RDMA/rxe: Cleanup mr_check_range
+    - RDMA/rxe: Move rxe_map_mr_sg to rxe_mr.c
+    - RDMA-rxe: Isolate mr code from atomic_reply()
+    - RDMA-rxe: Isolate mr code from atomic_write_reply()
+    - RDMA/rxe: Cleanup page variables in rxe_mr.c
+    - RDMA/rxe: Replace rxe_map and rxe_phys_buf by xarray
+    - Subject: RDMA/rxe: Handle zero length rdma
+    - RDMA/mana_ib: Fix a bug when the PF indicates more entries for registering
+      memory on first packet
+    - RDMA/rxe: Fix missing memory barriers in rxe_queue.h
+    - IB/hfi1: Fix math bugs in hfi1_can_pin_pages()
+    - IB/hfi1: Fix sdma.h tx->num_descs off-by-one errors
+    - Revert "remoteproc: qcom_q6v5_mss: map/unmap metadata region before/after
+      use"
+    - remoteproc: qcom_q6v5_mss: Use a carveout to authenticate modem headers
+    - media: ti: cal: fix possible memory leak in cal_ctx_create()
+    - media: platform: ti: Add missing check for devm_regulator_get
+    - media: imx: imx7-media-csi: fix missing clk_disable_unprepare() in
+      imx7_csi_init()
+    - powerpc: Remove linker flag from KBUILD_AFLAGS
+    - s390/vdso: Drop '-shared' from KBUILD_CFLAGS_64
+    - builddeb: clean generated package content
+    - media: max9286: Fix memleak in max9286_v4l2_register()
+    - media: ov2740: Fix memleak in ov2740_init_controls()
+    - media: ov5675: Fix memleak in ov5675_init_controls()
+    - media: i2c: tc358746: fix missing return assignment
+    - media: i2c: tc358746: fix ignoring read error in g_register callback
+    - media: i2c: tc358746: fix possible endianness issue
+    - media: ov5640: Fix soft reset sequence and timings
+    - media: ov5640: Handle delays when no reset_gpio set
+    - media: mc: Get media_device directly from pad
+    - media: i2c: ov772x: Fix memleak in ov772x_probe()
+    - media: i2c: imx219: Split common registers from mode tables
+    - media: i2c: imx219: Fix binning for RAW8 capture
+    - media: platform: mtk-mdp3: Fix return value check in mdp_probe()
+    - media: camss: csiphy-3ph: avoid undefined behavior
+    - media: platform: mtk-mdp3: fix Kconfig dependencies
+    - media: v4l2-jpeg: correct the skip count in jpeg_parse_app14_data
+    - media: v4l2-jpeg: ignore the unknown APP14 marker
+    - media: hantro: Fix JPEG encoder ENUM_FRMSIZE on RK3399
+    - media: imx-jpeg: Apply clk_bulk api instead of operating specific clk
+    - media: amphion: correct the unspecified color space
+    - media: drivers/media/v4l2-core/v4l2-h264 : add detection of null pointers
+    - media: rc: Fix use-after-free bugs caused by ene_tx_irqsim()
+    - media: atomisp: fix videobuf2 Kconfig depenendency
+    - media: atomisp: Only set default_run_mode on first open of a stream/asd
+    - media: i2c: ov7670: 0 instead of -EINVAL was returned
+    - media: usb: siano: Fix use after free bugs caused by do_submit_urb
+    - media: saa7134: Use video_unregister_device for radio_dev
+    - rpmsg: glink: Avoid infinite loop on intent for missing channel
+    - rpmsg: glink: Release driver_override
+    - ARM: OMAP2+: omap4-common: Fix refcount leak bug
+    - arm64: dts: qcom: msm8996: Add additional A2NoC clocks
+    - udf: Define EFSCORRUPTED error code
+    - context_tracking: Fix noinstr vs KASAN
+    - exit: Detect and fix irq disabled state in oops
+    - ARM: dts: exynos: Use Exynos5420 compatible for the MIPI video phy
+    - fs: Use CHECK_DATA_CORRUPTION() when kernel bugs are detected
+    - blk-iocost: fix divide by 0 error in calc_lcoefs()
+    - blk-cgroup: dropping parent refcount after pd_free_fn() is done
+    - blk-cgroup: synchronize pd_free_fn() from blkg_free_workfn() and
+      blkcg_deactivate_policy()
+    - trace/blktrace: fix memory leak with using debugfs_lookup()
+    - btrfs: scrub: improve tree block error reporting
+    - arm64: zynqmp: Enable hs termination flag for USB dwc3 controller
+    - cpuidle, intel_idle: Fix CPUIDLE_FLAG_INIT_XSTATE
+    - x86/fpu: Don't set TIF_NEED_FPU_LOAD for PF_IO_WORKER threads
+    - cpuidle: drivers: firmware: psci: Dont instrument suspend code
+    - cpuidle: lib/bug: Disable rcu_is_watching() during WARN/BUG
+    - perf/x86/intel/uncore: Add Meteor Lake support
+    - wifi: ath9k: Fix use-after-free in ath9k_hif_usb_disconnect()
+    - wifi: ath11k: fix monitor mode bringup crash
+    - wifi: brcmfmac: Fix potential stack-out-of-bounds in brcmf_c_preinit_dcmds()
+    - rcu: Make RCU_LOCKDEP_WARN() avoid early lockdep checks
+    - rcu: Suppress smp_processor_id() complaint in
+      synchronize_rcu_expedited_wait()
+    - srcu: Delegate work to the boot cpu if using SRCU_SIZE_SMALL
+    - rcu-tasks: Make rude RCU-Tasks work well with CPU hotplug
+    - rcu-tasks: Handle queue-shrink/callback-enqueue race condition
+    - wifi: ath11k: debugfs: fix to work with multiple PCI devices
+    - thermal: intel: Fix unsigned comparison with less than zero
+    - timers: Prevent union confusion from unexpected restart_syscall()
+    - x86/bugs: Reset speculation control settings on init
+    - bpftool: Always disable stack protection for BPF objects
+    - wifi: brcmfmac: ensure CLM version is null-terminated to prevent stack-out-
+      of-bounds
+    - wifi: rtw89: fix assignation of TX BD RAM table
+    - wifi: mt7601u: fix an integer underflow
+    - inet: fix fast path in __inet_hash_connect()
+    - ice: restrict PTP HW clock freq adjustments to 100, 000, 000 PPB
+    - ice: add missing checks for PF vsi type
+    - Compiler attributes: GCC cold function alignment workarounds
+    - ACPI: Don't build ACPICA with '-Os'
+    - bpf, docs: Fix modulo zero, division by zero, overflow, and underflow
+    - thermal: intel: intel_pch: Add support for Wellsburg PCH
+    - clocksource: Suspend the watchdog temporarily when high read latency
+      detected
+    - crypto: hisilicon: Wipe entire pool on error
+    - net: bcmgenet: Add a check for oversized packets
+    - m68k: Check syscall_trace_enter() return code
+    - s390/mm,ptdump: avoid Kasan vs Memcpy Real markers swapping
+    - netfilter: nf_tables: NULL pointer dereference in nf_tables_updobj()
+    - can: isotp: check CAN address family in isotp_bind()
+    - gcc-plugins: drop -std=gnu++11 to fix GCC 13 build
+    - tools/power/x86/intel-speed-select: Add Emerald Rapid quirk
+    - platform/x86: dell-ddv: Add support for interface version 3
+    - wifi: mt76: dma: free rx_head in mt76_dma_rx_cleanup
+    - ACPI: video: Fix Lenovo Ideapad Z570 DMI match
+    - net/mlx5: fw_tracer: Fix debug print
+    - coda: Avoid partial allocation of sig_inputArgs
+    - uaccess: Add minimum bounds check on kernel buffer size
+    - s390/idle: mark arch_cpu_idle() noinstr
+    - time/debug: Fix memory leak with using debugfs_lookup()
+    - PM: domains: fix memory leak with using debugfs_lookup()
+    - PM: EM: fix memory leak with using debugfs_lookup()
+    - Bluetooth: Fix issue with Actions Semi ATS2851 based devices
+    - Bluetooth: btusb: Add new PID/VID 0489:e0f2 for MT7921
+    - Bluetooth: btusb: Add VID:PID 13d3:3529 for Realtek RTL8821CE
+    - wifi: rtw89: debug: avoid invalid access on RTW89_DBG_SEL_MAC_30
+    - hv_netvsc: Check status in SEND_RNDIS_PKT completion message
+    - s390/kfence: fix page fault reporting
+    - devlink: Fix TP_STRUCT_entry in trace of devlink health report
+    - scm: add user copy checks to put_cmsg()
+    - drm: panel-orientation-quirks: Add quirk for Lenovo Yoga Tab 3 X90F
+    - drm: panel-orientation-quirks: Add quirk for DynaBook K50
+    - drm/amd/display: Reduce expected sdp bandwidth for dcn321
+    - drm/amd/display: Revert Reduce delay when sink device not able to ACK 00340h
+      write
+    - drm/amd/display: Fix potential null-deref in dm_resume
+    - drm/omap: dsi: Fix excessive stack usage
+    - HID: Add Mapping for System Microphone Mute
+    - drm/tiny: ili9486: Do not assume 8-bit only SPI controllers
+    - drm/amd/display: Defer DIG FIFO disable after VID stream enable
+    - drm/radeon: free iio for atombios when driver shutdown
+    - drm/amd: Avoid BUG() for case of SRIOV missing IP version
+    - drm/amdkfd: Page aligned memory reserve size
+    - scsi: lpfc: Fix use-after-free KFENCE violation during sysfs firmware write
+    - Revert "fbcon: don't lose the console font across generic->chip driver
+      switch"
+    - drm/amd: Avoid ASSERT for some message failures
+    - drm: amd: display: Fix memory leakage
+    - drm/amd/display: fix mapping to non-allocated address
+    - HID: uclogic: Add frame type quirk
+    - HID: uclogic: Add battery quirk
+    - HID: uclogic: Add support for XP-PEN Deco Pro SW
+    - HID: uclogic: Add support for XP-PEN Deco Pro MW
+    - drm/msm/dsi: Add missing check for alloc_ordered_workqueue
+    - drm: rcar-du: Add quirk for H3 ES1.x pclk workaround
+    - drm: rcar-du: Fix setting a reserved bit in DPLLCR
+    - drm/drm_print: correct format problem
+    - drm/amd/display: Set hvm_enabled flag for S/G mode
+    - drm/client: Test for connectors before sending hotplug event
+    - habanalabs: extend fatal messages to contain PCI info
+    - habanalabs: fix bug in timestamps registration code
+    - docs/scripts/gdb: add necessary make scripts_gdb step
+    - drm/msm/dpu: Add DSC hardware blocks to register snapshot
+    - ASoC: soc-compress: Reposition and add pcm_mutex
+    - ASoC: kirkwood: Iterate over array indexes instead of using pointer math
+    - regulator: max77802: Bounds check regulator id against opmode
+    - regulator: s5m8767: Bounds check id indexing into arrays
+    - Revert "drm/amdgpu: TA unload messages are not actually sent to psp when
+      amdgpu is uninstalled"
+    - drm/amd/display: fix FCLK pstate change underflow
+    - gfs2: Improve gfs2_make_fs_rw error handling
+    - hwmon: (coretemp) Simplify platform device handling
+    - hwmon: (nct6775) Directly call ASUS ACPI WMI method
+    - hwmon: (nct6775) B650/B660/X670 ASUS boards support
+    - pinctrl: at91: use devm_kasprintf() to avoid potential leaks
+    - drm/amd/display: Do not commit pipe when updating DRR
+    - scsi: snic: Fix memory leak with using debugfs_lookup()
+    - scsi: ufs: core: Fix device management cmd timeout flow
+    - HID: logitech-hidpp: Don't restart communication if not necessary
+    - drm/amd/display: Enable P-state validation checks for DCN314
+    - drm: panel-orientation-quirks: Add quirk for Lenovo IdeaPad Duet 3 10IGL5
+    - drm/amd/display: Disable HUBP/DPP PG on DCN314 for now
+    - drm/amd/display: disable SubVP + DRR to prevent underflow
+    - dm thin: add cond_resched() to various workqueue loops
+    - dm cache: add cond_resched() to various workqueue loops
+    - nfsd: zero out pointers after putting nfsd_files on COPY setup error
+    - nfsd: don't hand out delegation on setuid files being opened for write
+    - cifs: prevent data race in smb2_reconnect()
+    - drm/i915/mtl: Correct implementation of Wa_18018781329
+    - drm/shmem-helper: Revert accidental non-GPL export
+    - driver core: fw_devlink: Avoid spurious error message
+    - wifi: rtl8xxxu: fixing transmisison failure for rtl8192eu
+    - firmware: coreboot: framebuffer: Ignore reserved pixel color bits
+    - block: don't allow multiple bios for IOCB_NOWAIT issue
+    - block: clear bio->bi_bdev when putting a bio back in the cache
+    - block: be a bit more careful in checking for NULL bdev while polling
+    - rtc: pm8xxx: fix set-alarm race
+    - ipmi: ipmb: Fix the MODULE_PARM_DESC associated to 'retry_time_ms'
+    - ipmi:ssif: resend_msg() cannot fail
+    - ipmi_ssif: Rename idle state and check
+    - ipmi:ssif: Add a timer between request retries
+    - io_uring: Replace 0-length array with flexible array
+    - io_uring: use user visible tail in io_uring_poll()
+    - io_uring: handle TIF_NOTIFY_RESUME when checking for task_work
+    - io_uring: add a conditional reschedule to the IOPOLL cancelation loop
+    - io_uring: add reschedule point to handle_tw_list()
+    - io_uring/rsrc: disallow multi-source reg buffers
+    - io_uring: remove MSG_NOSIGNAL from recvmsg
+    - io_uring/poll: allow some retries for poll triggering spuriously
+    - io_uring: fix fget leak when fs don't support nowait buffered read
+    - s390/extmem: return correct segment type in __segment_load()
+    - s390: discard .interp section
+    - s390/kprobes: fix irq mask clobbering on kprobe reenter from post_handler
+    - s390/kprobes: fix current_kprobe never cleared after kprobes reenter
+    - KVM: s390: disable migration mode when dirty tracking is disabled
+    - cifs: improve checking of DFS links over STATUS_OBJECT_NAME_INVALID
+    - cifs: Fix uninitialized memory read in smb3_qfs_tcon()
+    - cifs: Fix uninitialized memory reads for oparms.mode
+    - cifs: fix mount on old smb servers
+    - cifs: introduce cifs_io_parms in smb2_async_writev()
+    - cifs: split out smb3_use_rdma_offload() helper
+    - cifs: don't try to use rdma offload on encrypted connections
+    - cifs: Check the lease context if we actually got a lease
+    - cifs: return a single-use cfid if we did not get a lease
+    - scsi: mpi3mr: Fix missing mrioc->evtack_cmds initialization
+    - scsi: mpi3mr: Fix issues in mpi3mr_get_all_tgt_info()
+    - scsi: mpi3mr: Remove unnecessary memcpy() to alltgt_info->dmi
+    - btrfs: hold block group refcount during async discard
+    - btrfs: sysfs: update fs features directory asynchronously
+    - locking/rwsem: Prevent non-first waiter from spinning in down_write()
+      slowpath
+    - ksmbd: fix wrong data area length for smb2 lock request
+    - ksmbd: do not allow the actual frame length to be smaller than the rfc1002
+      length
+    - ksmbd: fix possible memory leak in smb2_lock()
+    - torture: Fix hang during kthread shutdown phase
+    - ARM: dts: exynos: correct HDMI phy compatible in Exynos4
+    - io_uring: mark task TASK_RUNNING before handling resume/task work
+    - hfs: fix missing hfs_bnode_get() in __hfs_bnode_create
+    - fs: hfsplus: fix UAF issue in hfsplus_put_super
+    - exfat: fix reporting fs error when reading dir beyond EOF
+    - exfat: fix unexpected EOF while reading dir
+    - exfat: redefine DIR_DELETED as the bad cluster number
+    - exfat: fix inode->i_blocks for non-512 byte sector size device
+    - fs: dlm: start midcomms before scand
+    - fs: dlm: fix use after free in midcomms commit
+    - fs: dlm: be sure to call dlm_send_queue_flush()
+    - fs: dlm: fix race setting stop tx flag
+    - fs: dlm: don't set stop rx flag after node reset
+    - fs: dlm: move sending fin message into state change handling
+    - fs: dlm: send FIN ack back in right cases
+    - f2fs: fix information leak in f2fs_move_inline_dirents()
+    - f2fs: retry to update the inode page given data corruption
+    - f2fs: fix cgroup writeback accounting with fs-layer encryption
+    - f2fs: fix kernel crash due to null io->bio
+    - f2fs: Revert "f2fs: truncate blocks in batch in __complete_revoke_list()"
+    - ocfs2: fix defrag path triggering jbd2 ASSERT
+    - ocfs2: fix non-auto defrag path not working issue
+    - fs/cramfs/inode.c: initialize file_ra_state
+    - selftests/landlock: Skip overlayfs tests when not supported
+    - selftests/landlock: Test ptrace as much as possible with Yama
+    - udf: Truncate added extents on failed expansion
+    - udf: Do not bother merging very long extents
+    - udf: Do not update file length for failed writes to inline files
+    - udf: Preserve link count of system files
+    - udf: Detect system inodes linked into directory hierarchy
+    - udf: Fix file corruption when appending just after end of preallocated
+      extent
+    - md: don't update recovery_cp when curr_resync is ACTIVE
+    - KVM: Destroy target device if coalesced MMIO unregistration fails
+    - KVM: VMX: Fix crash due to uninitialized current_vmcs
+    - KVM: Register /dev/kvm as the _very_ last thing during initialization
+    - KVM: x86: Purge "highest ISR" cache when updating APICv state
+    - KVM: x86: Blindly get current x2APIC reg value on "nodecode write" traps
+    - KVM: x86: Don't inhibit APICv/AVIC on xAPIC ID "change" if APIC is disabled
+    - KVM: x86: Don't inhibit APICv/AVIC if xAPIC ID mismatch is due to 32-bit ID
+    - KVM: SVM: Flush the "current" TLB when activating AVIC
+    - KVM: SVM: Process ICR on AVIC IPI delivery failure due to invalid target
+    - KVM: SVM: Don't put/load AVIC when setting virtual APIC mode
+    - KVM: x86: Inject #GP if WRMSR sets reserved bits in APIC Self-IPI
+    - KVM: x86: Inject #GP on x2APIC WRMSR that sets reserved bits 63:32
+    - KVM: SVM: Fix potential overflow in SEV's send|receive_update_data()
+    - KVM: SVM: hyper-v: placate modpost section mismatch error
+    - selftests: x86: Fix incorrect kernel headers search path
+    - x86/virt: Force GIF=1 prior to disabling SVM (for reboot flows)
+    - x86/crash: Disable virt in core NMI crash handler to avoid double shootdown
+    - x86/reboot: Disable virtualization in an emergency if SVM is supported
+    - x86/reboot: Disable SVM, not just VMX, when stopping CPUs
+    - x86/kprobes: Fix __recover_optprobed_insn check optimizing logic
+    - x86/kprobes: Fix arch_check_optimized_kprobe check within optimized_kprobe
+      range
+    - x86/microcode/amd: Remove load_microcode_amd()'s bsp parameter
+    - x86/microcode/AMD: Add a @cpu parameter to the reloading functions
+    - x86/microcode/AMD: Fix mixed steppings support
+    - x86/speculation: Allow enabling STIBP with legacy IBRS
+    - Documentation/hw-vuln: Document the interaction between IBRS and STIBP
+    - virt/sev-guest: Return -EIO if certificate buffer is not large enough
+    - brd: mark as nowait compatible
+    - brd: return 0/-error from brd_insert_page()
+    - brd: check for REQ_NOWAIT and set correct page allocation mask
+    - ima: fix error handling logic when file measurement failed
+    - ima: Align ima_file_mmap() parameters with mmap_file LSM hook
+    - selftests/powerpc: Fix incorrect kernel headers search path
+    - selftests/ftrace: Fix eprobe syntax test case to check filter support
+    - selftests: sched: Fix incorrect kernel headers search path
+    - selftests: core: Fix incorrect kernel headers search path
+    - selftests: pid_namespace: Fix incorrect kernel headers search path
+    - selftests: arm64: Fix incorrect kernel headers search path
+    - selftests: clone3: Fix incorrect kernel headers search path
+    - selftests: pidfd: Fix incorrect kernel headers search path
+    - selftests: membarrier: Fix incorrect kernel headers search path
+    - selftests: kcmp: Fix incorrect kernel headers search path
+    - selftests: media_tests: Fix incorrect kernel headers search path
+    - selftests: gpio: Fix incorrect kernel headers search path
+    - selftests: filesystems: Fix incorrect kernel headers search path
+    - selftests: user_events: Fix incorrect kernel headers search path
+    - selftests: ptp: Fix incorrect kernel headers search path
+    - selftests: sync: Fix incorrect kernel headers search path
+    - selftests: rseq: Fix incorrect kernel headers search path
+    - selftests: move_mount_set_group: Fix incorrect kernel headers search path
+    - selftests: mount_setattr: Fix incorrect kernel headers search path
+    - selftests: perf_events: Fix incorrect kernel headers search path
+    - selftests: ipc: Fix incorrect kernel headers search path
+    - selftests: futex: Fix incorrect kernel headers search path
+    - selftests: drivers: Fix incorrect kernel headers search path
+    - selftests: dmabuf-heaps: Fix incorrect kernel headers search path
+    - selftests: vm: Fix incorrect kernel headers search path
+    - selftests: seccomp: Fix incorrect kernel headers search path
+    - irqdomain: Fix association race
+    - irqdomain: Fix disassociation race
+    - irqdomain: Look for existing mapping only once
+    - irqdomain: Drop bogus fwspec-mapping error handling
+    - irqdomain: Refactor __irq_domain_alloc_irqs()
+    - irqdomain: Fix mapping-creation race
+    - irqdomain: Fix domain registration race
+    - crypto: qat - fix out-of-bounds read
+    - mm/damon/paddr: fix missing folio_put()
+    - ALSA: ice1712: Do not left ice->gpio_mutex locked in aureon_add_controls()
+    - ALSA: hda/realtek: Add quirk for HP EliteDesk 800 G6 Tower PC
+    - jbd2: fix data missing when reusing bh which is ready to be checkpointed
+    - ext4: optimize ea_inode block expansion
+    - ext4: refuse to create ea block when umounted
+    - cxl/pmem: Fix nvdimm registration races
+    - Input: exc3000 - properly stop timer on shutdown
+    - mtd: spi-nor: sfdp: Fix index value for SCCR dwords
+    - mtd: spi-nor: spansion: Consider reserved bits in CFR5 register
+    - dm: send just one event on resize, not two
+    - dm: add cond_resched() to dm_wq_work()
+    - dm: add cond_resched() to dm_wq_requeue_work()
+    - wifi: rtw88: use RTW_FLAG_POWERON flag to prevent to power on/off twice
+    - wifi: rtl8xxxu: Use a longer retry limit of 48
+    - wifi: ath11k: allow system suspend to survive ath11k
+    - wifi: cfg80211: Fix use after free for wext
+    - wifi: cfg80211: Set SSID if it is not already set
+    - cpuidle: add ARCH_SUSPEND_POSSIBLE dependencies
+    - qede: fix interrupt coalescing configuration
+    - thermal: intel: powerclamp: Fix cur_state for multi package system
+    - dm flakey: fix logic when corrupting a bio
+    - dm cache: free background tracker's queued work in btracker_destroy
+    - dm flakey: don't corrupt the zero page
+    - dm flakey: fix a bug with 32-bit highmem systems
+    - hwmon: (peci/cputemp) Fix off-by-one in coretemp_label allocation
+    - hwmon: (nct6775) Fix incorrect parenthesization in nct6775_write_fan_div()
+    - spi: intel: Check number of chip selects after reading the descriptor
+    - ARM: dts: qcom: sdx65: Add Qcom SMMU-500 as the fallback for IOMMU node
+    - ARM: dts: qcom: sdx55: Add Qcom SMMU-500 as the fallback for IOMMU node
+    - ARM: dts: exynos: correct TMU phandle in Exynos4210
+    - ARM: dts: exynos: correct TMU phandle in Exynos4
+    - ARM: dts: exynos: correct TMU phandle in Odroid XU3 family
+    - ARM: dts: exynos: correct TMU phandle in Exynos5250
+    - ARM: dts: exynos: correct TMU phandle in Odroid XU
+    - ARM: dts: exynos: correct TMU phandle in Odroid HC1
+    - arm64: acpi: Fix possible memory leak of ffh_ctxt
+    - arm64: mm: hugetlb: Disable HUGETLB_PAGE_OPTIMIZE_VMEMMAP
+    - arm64: Reset KASAN tag in copy_highpage with HW tags only
+    - fuse: add inode/permission checks to fileattr_get/fileattr_set
+    - rbd: avoid use-after-free in do_rbd_add() when rbd_dev_create() fails
+    - ceph: update the time stamps and try to drop the suid/sgid
+    - regulator: core: Use ktime_get_boottime() to determine how long a regulator
+      was off
+    - panic: fix the panic_print NMI backtrace setting
+    - mm/hwpoison: convert TTU_IGNORE_HWPOISON to TTU_HWPOISON
+    - genirq/msi, platform-msi: Ensure that MSI descriptors are unreferenced
+    - genirq/msi: Take the per-device MSI lock before validating the control
+      structure
+    - spi: spi-sn-f-ospi: fix duplicate flag while assigning to mode_bits
+    - alpha: fix FEN fault handling
+    - dax/kmem: Fix leak of memory-hotplug resources
+    - mips: fix syscall_get_nr
+    - media: ipu3-cio2: Fix PM runtime usage_count in driver unbind
+    - remoteproc/mtk_scp: Move clk ops outside send_lock
+    - vfio: Fix NULL pointer dereference caused by uninitialized group->iommufd
+    - docs: gdbmacros: print newest record
+    - mm: memcontrol: deprecate charge moving
+    - mm/thp: check and bail out if page in deferred queue already
+    - ktest.pl: Give back console on Ctrt^C on monitor
+    - kprobes: Fix to handle forcibly unoptimized kprobes on freeing_list
+    - ktest.pl: Fix missing "end_monitor" when machine check fails
+    - ktest.pl: Add RUN_TIMEOUT option with default unlimited
+    - memory tier: release the new_memtier in find_create_memory_tier()
+    - ring-buffer: Handle race between rb_move_tail and rb_check_pages
+    - tools/bootconfig: fix single & used for logical condition
+    - tracing/eprobe: Fix to add filter on eprobe description in README file
+    - iommu/amd: Add a length limitation for the ivrs_acpihid command-line
+      parameter
+    - scsi: aacraid: Allocate cmd_priv with scsicmd
+    - scsi: qla2xxx: Fix link failure in NPIV environment
+    - scsi: qla2xxx: Check if port is online before sending ELS
+    - scsi: qla2xxx: Fix DMA-API call trace on NVMe LS requests
+    - scsi: qla2xxx: Remove unintended flag clearing
+    - scsi: qla2xxx: Fix erroneous link down
+    - scsi: qla2xxx: Remove increment of interface err cnt
+    - scsi: ses: Don't attach if enclosure has no components
+    - scsi: ses: Fix slab-out-of-bounds in ses_enclosure_data_process()
+    - scsi: ses: Fix possible addl_desc_ptr out-of-bounds accesses
+    - scsi: ses: Fix possible desc_ptr out-of-bounds accesses
+    - scsi: ses: Fix slab-out-of-bounds in ses_intf_remove()
+    - RISC-V: add a spin_shadow_stack declaration
+    - riscv: Avoid enabling interrupts in die()
+    - riscv: mm: fix regression due to update_mmu_cache change
+    - riscv: jump_label: Fixup unaligned arch_static_branch function
+    - riscv: ftrace: Fixup panic by disabling preemption
+    - riscv, mm: Perform BPF exhandler fixup on page fault
+    - riscv: ftrace: Remove wasted nops for !RISCV_ISA_C
+    - riscv: ftrace: Reduce the detour code size to half
+    - MIPS: DTS: CI20: fix otg power gpio
+    - PCI/PM: Observe reset delay irrespective of bridge_d3
+    - PCI: Unify delay handling for reset and resume
+    - PCI: hotplug: Allow marking devices as disconnected during bind/unbind
+    - PCI: Avoid FLR for AMD FCH AHCI adapters
+    - PCI/DPC: Await readiness of secondary bus after reset
+    - bus: mhi: ep: Only send -ENOTCONN status if client driver is available
+    - bus: mhi: ep: Move chan->lock to the start of processing queued ch ring
+    - bus: mhi: ep: Save channel state locally during suspend and resume
+    - iommufd: Make sure to zero vfio_iommu_type1_info before copying to user
+    - iommufd: Do not add the same hwpt to the ioas->hwpt_list twice
+    - iommu/vt-d: Avoid superfluous IOTLB tracking in lazy mode
+    - iommu/vt-d: Fix PASID directory pointer coherency
+    - vfio/type1: exclude mdevs from VFIO_UPDATE_VADDR
+    - vfio/type1: prevent underflow of locked_vm via exec()
+    - vfio/type1: track locked_vm per dma
+    - vfio/type1: restore locked_vm
+    - drm/amd: Fix initialization for nbio 7.5.1
+    - drm/i915/quirks: Add inverted backlight quirk for HP 14-r206nv
+    - drm/radeon: Fix eDP for single-display iMac11,2
+    - drm/i915: Don't use stolen memory for ring buffers with LLC
+    - drm/i915: Don't use BAR mappings for ring buffers with LLC
+    - drm/gud: Fix UBSAN warning
+    - drm/edid: fix AVI infoframe aspect ratio handling
+    - drm/edid: fix parsing of 3D modes from HDMI VSDB
+    - qede: avoid uninitialized entries in coal_entry array
+    - brd: use radix_tree_maybe_preload instead of radix_tree_preload
+    - net: avoid double iput when sock_alloc_file fails
+    - Linux 6.2.3
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations after applying 6.2.3 stable patches
+    - [Config] update annotations after applying 6.2.6 stable patches
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 14 Mar 2023 16:43:44 +0100
+
+linux (6.2.0-16.16) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-16.16 -proposed tracker (LP: #2009914)
+
+  * linux-libc-dev is no longer multi-arch safe (LP: #2009355)
+    - Revert "UBUNTU: [Packaging] install headers to debian/linux-libc-dev
+      directly"
+
+  * linux: CONFIG_SERIAL_8250_MID=y (LP: #2009283)
+    - [Config] enable CONFIG_SERIAL_8250_MID=y
+
+  * cpufreq: intel_pstate: Update Balance performance EPP for Sapphire Rapids
+    (LP: #2008519)
+    - cpufreq: intel_pstate: Adjust balance_performance EPP for Sapphire Rapids
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 10 Mar 2023 18:34:28 +0100
+
+linux (6.2.0-15.15) lunar; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: document annotations headers
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 10 Mar 2023 07:36:59 +0100
+
+linux (6.2.0-14.14) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-14.14 -proposed tracker (LP: #2009856)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] rust: add rust build dependencies to all arches
+    - [Packaging] Support skipped dkms modules
+    - [Packaging] actually enforce set -e in dkms-build--nvidia-N
+    - [Packaging] Preserve the correct log file variable value
+    - [Packaging] update getabis
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 09 Mar 2023 16:40:36 +0100
+
+linux (6.2.0-13.13) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-13.13 -proposed tracker (LP: #2009704)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * mt7921: add support of MTFG table (LP: #2009642)
+    - wifi: mt76: mt7921: add support to update fw capability with MTFG table
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Mar 2023 14:40:25 +0100
+
+linux (6.2.0-12.12) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-12.12 -proposed tracker (LP: #2009698)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: enforce rust availability only on x86_64
+    - [Config] update CONFIG_RUST_IS_AVAILABLE
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Mar 2023 12:50:15 +0100
+
+linux (6.2.0-11.11) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-11.11 -proposed tracker (LP: #2009697)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] do not stop the build if rust is not available
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Mar 2023 12:24:55 +0100
+
+linux (6.2.0-10.10) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-10.10 -proposed tracker (LP: #2009673)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * enable Rust support in the kernel (LP: #2007654)
+    - [Packaging] propagate makefile variables to kernelconfig
+    - SAUCE: rust: fix regexp in scripts/is_rust_module.sh
+    - SAUCE: scripts: rust: drop is_rust_module.sh
+    - SAUCE: rust: allow to use INIT_STACK_ALL_ZERO
+    - SAUCE: scripts: Exclude Rust CUs with pahole
+    - SAUCE: modpost: support arbitrary symbol length in modversion
+    - SAUCE: allows to enable Rust with modversions
+    - SAUCE: rust: properly detect the version of libclang used by bindgen
+    - [Packaging] rust: add the proper make flags to enable rust support
+    - [Packaging] add rust dependencies
+    - [Packaging] bpftool: always use vmlinux to generate headers
+    - [Packaging] run rustavailable target as debugging before build
+    - [Config] enable Rust support
+
+  * Fail to output sound to external monitor which connects via docking station
+    (LP: #2009024)
+    - [Config] Enable CONFIG_SND_HDA_INTEL_HDMI_SILENT_STREAM
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Makefile: replace rsync with tar
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Mar 2023 12:01:56 +0100
+
+linux (6.2.0-1.1) lunar; urgency=medium
+
+  * lunar/linux: 6.2.0-1.1 -proposed tracker (LP: #2009621)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * kinetic: apply new apparmor and LSM stacking patch set (LP: #1989983)
+    - SAUCE: apparmor: Add fine grained mediation of posix mqueues
+    - SAUCE: apparmor: add user namespace creation mediation
+
+  * Lunar update: v6.2.2 upstream stable release (LP: #2009358)
+    - ALSA: hda: cs35l41: Correct error condition handling
+    - crypto: arm64/sm4-gcm - Fix possible crash in GCM cryption
+    - bpf: bpf_fib_lookup should not return neigh in NUD_FAILED state
+    - vc_screen: don't clobber return value in vcs_read
+    - drm/amd/display: Move DCN314 DOMAIN power control to DMCUB
+    - drm/amd/display: Properly reuse completion structure
+    - scripts/tags.sh: fix incompatibility with PCRE2
+    - wifi: rtw88: usb: Set qsel correctly
+    - wifi: rtw88: usb: send Zero length packets if necessary
+    - wifi: rtw88: usb: drop now unnecessary URB size check
+    - usb: dwc3: pci: add support for the Intel Meteor Lake-M
+    - USB: serial: option: add support for VW/Skoda "Carstick LTE"
+    - usb: gadget: u_serial: Add null pointer check in gserial_resume
+    - arm64: dts: uniphier: Fix property name in PXs3 USB node
+    - usb: typec: pd: Remove usb_suspend_supported sysfs from sink PDO
+    - USB: core: Don't hold device lock while reading the "descriptors" sysfs file
+    - Linux 6.2.2
+
+  * Lunar update: v6.2.1 upstream stable release (LP: #2009127)
+    - uaccess: Add speculation barrier to copy_from_user()
+    - x86/alternatives: Introduce int3_emulate_jcc()
+    - x86/alternatives: Teach text_poke_bp() to patch Jcc.d32 instructions
+    - x86/static_call: Add support for Jcc tail-calls
+    - HID: mcp-2221: prevent UAF in delayed work
+    - wifi: mwifiex: Add missing compatible string for SD8787
+    - audit: update the mailing list in MAINTAINERS
+    - platform/x86/amd/pmf: Add depends on CONFIG_POWER_SUPPLY
+    - platform/x86: nvidia-wmi-ec-backlight: Add force module parameter
+    - ext4: Fix function prototype mismatch for ext4_feat_ktype
+    - randstruct: disable Clang 15 support
+    - bpf: add missing header file include
+    - Linux 6.2.1
+
+  * Fix mediatek wifi driver crash when loading wrong SAR table (LP: #2009118)
+    - wifi: mt76: mt7921: fix error code of return in mt7921_acpi_read
+
+  * overlayfs mounts as R/O over idmapped mount (LP: #2009065)
+    - SAUCE: overlayfs: handle idmapped mounts in ovl_do_(set|remove)xattr
+
+  * RaptorLake: Fix the Screen is shaking by onboard HDMI port in mirror mode
+    (LP: #1993561)
+    - drm/i915/display: Drop check for doublescan mode in modevalid
+    - drm/i915/display: Prune Interlace modes for Display >=12
+
+  * screen flicker after PSR2 enabled (LP: #2007516)
+    - SAUCE: drm/i915/display/psr: Disable PSR2 sel fetch on panel SHP 5457
+
+  * [23.04 FEAT] Support for new IBM Z Hardware (IBM z16) - Reset DAT-Protection
+    facility support (LP: #1982378)
+    - s390/mm: add support for RDP (Reset DAT-Protection)
+
+  * [23.04 FEAT] zcrypt DD: AP command filtering (LP: #2003637)
+    - s390/zcrypt: introduce ctfm field in struct CPRBX
+
+  * rtcpie in timers from ubuntu_kernel_selftests randomly failing
+    (LP: #1814234)
+    - SAUCE: selftest: rtcpie: Force passing unreliable subtest
+
+  * [23.04 FEAT] Support for List-Directed IPL and re-IPL from ECKD DASD
+    (LP: #2003394)
+    - s390/ipl: add DEFINE_GENERIC_LOADPARM()
+    - s390/ipl: add loadparm parameter to eckd ipl/reipl data
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: drm/i915/sseu: fix max_subslices array-index-out-of-bounds access
+    - SAUCE: mtd: spi-nor: Fix shift-out-of-bounds in spi_nor_set_erase_type
+    - SAUCE: Revert "fbdev: Make registered_fb[] private to fbmem.c"
+    - [Packaging] disable signing for ppc64el
+    - [Config] define CONFIG_SECURITY_APPARMOR_RESTRICT_USERNS
+    - SAUCE: Revert "arm64/fpsimd: Make kernel_neon_ API _GPL"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 07 Mar 2023 18:45:31 +0100
+
+linux (6.2.0-0.0) lunar; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 03 Mar 2023 08:42:43 +0100
+
+linux-unstable (6.2.0-10.10) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-10.10 -proposed tracker (LP: #2007818)
+
+  * Built-in camera device dies after runtime suspended (LP: #2007530)
+    - SAUCE: usb: xhci: Workaround for runpm issue on AMD xHC
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations after rebase to v6.2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 20 Feb 2023 10:36:20 +0100
+
+linux-unstable (6.2.0-9.9) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-9.9 -proposed tracker (LP: #2007069)
+
+  * Move kernel ADT tests to python3 (LP: #2004429)
+    - [Debian] Use a python3 compatable kernel-testing repo
+
+  * Mediatek FM350-GL wwan module failed to init: Invalid device status 0x1
+    (LP: #2002089)
+    - SAUCE: Revert "net: wwan: t7xx: Add AP CLDMA"
+    - SAUCE: net: wwan: t7xx: Add AP CLDMA
+    - SAUCE: net: wwan: t7xx: Infrastructure for early port configuration
+    - SAUCE: net: wwan: t7xx: PCIe reset rescan
+    - SAUCE: net: wwan: t7xx: Enable devlink based fw flashing and coredump
+      collection
+    - SAUCE: net: wwan: t7xx: Devlink documentation
+
+  * LXD containers using shiftfs on ZFS or TMPFS broken on 5.15.0-48.54
+    (LP: #1990849)
+    - SAUCE: shiftfs: fix -EOVERFLOW inside the container
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: do not drop undefined configs in derivatives
+    - [Packaging]: annotations: fix _remove_entry() logic
+    - [Packaging] rsync no longer available on lunar
+    - [Packaging] annotations: Handle single-line annoation rules
+    - [Packaging] annotations: Preserve single-line annotation rules
+    - [Packaging] annotations: Fix linter errors
+    - [Packaging] annotations: Clean up policy writes
+    - [Packaging] annotations: Handle tabs in annotations file
+    - [Packaging] annotations: Fail on invalid lines
+    - [Packaging] annotations: Write out annotations with notes first
+    - [Packaging] annotations: Check validity of FLAVOUR_DEP
+    - [Config] update annotations to split configs with/without notes
+    - [Packaging] annotations: various code cleanups
+    - [Config] update annotations after rebase to v6.2-rc8
+
+  * Miscellaneous upstream changes
+    - selftests/net: mv bpf/nat6to4.c to net folder
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc8
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 13 Feb 2023 09:32:18 +0100
+
+linux-unstable (6.2.0-8.8) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-8.8 -proposed tracker (LP: #2004229)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] re-enable signing for ppc64el and s390x
+    - SAUCE: s390/decompressor: specify __decompress() buf len to avoid overflow
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 31 Jan 2023 08:21:21 +0100
+
+linux-unstable (6.2.0-7.7) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-7.7 -proposed tracker (LP: #2004142)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 30 Jan 2023 10:23:15 +0100
+
+linux-unstable (6.2.0-6.6) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-6.6 -proposed tracker (LP: #2004138)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] debian/rules: Bring back 'editconfigs'
+    - [Packaging] debian/rules: 1-maintainer.mk -- Use make's if-else
+    - [Packaging] annotations: make sure to always drop undefined configs
+    - [Config] update annotations after rebase to v6.2-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 30 Jan 2023 09:20:26 +0100
+
+linux-unstable (6.2.0-5.5) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-5.5 -proposed tracker (LP: #2003682)
+
+  * [23.04] Kernel 6.2 does not boot on s390x (LP: #2003348)
+    - SAUCE Revert "zstd: import usptream v1.5.2"
+    - SAUCE: Revert "zstd: Move zstd-common module exports to
+      zstd_common_module.c"
+
+  * Revoke & rotate to new signing key (LP: #2002812)
+    - [Packaging] Revoke and rotate to new signing key
+
+  * CVE-2023-0179
+    - netfilter: nft_payload: incorrect arithmetics when fetching VLAN header bits
+
+  * [23.04] net/smc: Alibaba patches about tunable buffer sizes may cause errors
+    and need to be removed (kernel 6.2) (LP: #2003547)
+    - SAUCE: Revert "net/smc: Unbind r/w buffer size from clcsock and make them
+      tunable"
+    - SAUCE: Revert "net/smc: Introduce a specific sysctl for TEST_LINK time"
+
+  * 5.15 stuck at boot on c4.large (LP: #1956780)
+    - SAUCE: Revert "PCI/MSI: Mask MSI-X vectors only on success"
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] scripts/misc/kernelconfig: Disable config checks for mainline
+      builds
+    - [Packaging] annotations: add CONFIG_GCC_VERSION to the list of ignored
+      configs
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 23 Jan 2023 08:20:26 +0100
+
+linux-unstable (6.2.0-4.4) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-4.4 -proposed tracker (LP: #2003051)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] add python3 as a build dependency
+    - [Packaging] scripts/misc/kernelconfig: Rewrite
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 17 Jan 2023 09:18:54 +0100
+
+linux-unstable (6.2.0-3.3) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-3.3 -proposed tracker (LP: #2002939)
+
+  * Enable kernel config for P2PDMA (LP: #1987394)
+    - [Config] Enable CONFIG_HSA_AMD_P2P
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (no-up) Remove obj- += foo.o hack
+    - SAUCE: (no-up) re-add ubuntu/ directory
+    - [Config] enable EFI handover protocol
+    - [Packaging] Fix module-check error when modules are compressed
+    - SAUCE: (no-up) do not remove debian directory by 'make mrproper'
+    - [Packaging] debian/rules: Drop AUTOBUILD
+    - [Packaging] debian/rules: Drop NOKERNLOG and PRINTSHAS env variables
+    - [Packaging] debian/rules: Replace skip<foo> variables with skip_checks
+    - [Packaging] checks/retpoline-check: Make 'skipretpoline' argument optional
+    - [Packaging] checks/module-signature-check: Add 'skip_checks' argument
+    - [Packaging] debian/rules: Rename 'skip_dbg' to 'do_dbgsym_package'
+    - [Packaging] debian/rules: Rename 'skip_checks' to 'do_skip_checks'
+    - [Packaging] debian/rules: Rename 'full_build' to 'do_full_build'
+    - [Packaging] debian/rules: Fix PPA debug package builds
+    - [Packaging] debian/rules: Remove debug package install directory earlier
+    - [Packaging] debian/rules: Remove unnecessary 'lockme_<foo>' variables
+    - [Packaging] debian/rules: Remove unused target 'diffupstream'
+    - [Packaging] debian/rules: Mark PHONY targets individually
+    - [Packaging] debian/rules: Clean up 'help' target output
+    - [Packaging] debian/rules: Clean up 'printenv' target output
+    - [Packaging] debian/rules: Add missing 'do_<foo>' variables to 'printenv'
+    - [Config] update annotations after rebase to v6.2-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 16 Jan 2023 16:01:40 +0100
+
+linux-unstable (6.2.0-2.2) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-2.2 -proposed tracker (LP: #2001892)
+
+  * Soundwire support for the Intel RPL Gen 0C40/0C11 platforms (LP: #2000030)
+    - SAUCE: ASoC: Intel: soc-acpi: add configuration for variant of 0C40 product
+    - SAUCE: ASoC: Intel: soc-acpi: add configuration for variant of 0C11 product
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update toolchain version in annotations
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] Support skipped dkms modules"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 05 Jan 2023 09:19:55 +0100
+
+linux-unstable (6.2.0-1.1) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.2.0-1.1 -proposed tracker (LP: #2000904)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: remove configs that are undefined across all
+      arches/flavours
+    - SAUCE: Revert "apparmor: make __aa_path_perm() static"
+    - [Packaging] abi-check: ignore failures when abi check is skipped
+    - [Packaging] temporarily disable zfs dkms
+    - [Config] update annotations after rebase to 6.2-rc1
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 04 Jan 2023 12:08:32 +0100
+
+linux-unstable (6.2.0-0.0) lunar; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Sun, 01 Jan 2023 10:16:00 +0100
+
+linux (6.1.0-11.11) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-11.11 -proposed tracker (LP: #2000704)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Lunar update: v6.1.1 upstream stable release (LP: #2000706)
+    - x86/vdso: Conditionally export __vdso_sgx_enter_enclave()
+    - libbpf: Fix uninitialized warning in btf_dump_dump_type_data
+    - PCI: mt7621: Add sentinel to quirks table
+    - mips: ralink: mt7621: define MT7621_SYSC_BASE with __iomem
+    - mips: ralink: mt7621: soc queries and tests as functions
+    - mips: ralink: mt7621: do not use kzalloc too early
+    - irqchip/ls-extirq: Fix endianness detection
+    - udf: Discard preallocation before extending file with a hole
+    - udf: Fix preallocation discarding at indirect extent boundary
+    - udf: Do not bother looking for prealloc extents if i_lenExtents matches
+      i_size
+    - udf: Fix extending file within last block
+    - usb: gadget: uvc: Prevent buffer overflow in setup handler
+    - USB: serial: option: add Quectel EM05-G modem
+    - USB: serial: cp210x: add Kamstrup RF sniffer PIDs
+    - USB: serial: f81232: fix division by zero on line-speed change
+    - USB: serial: f81534: fix division by zero on line-speed change
+    - xhci: Apply XHCI_RESET_TO_DEFAULT quirk to ADL-N
+    - staging: r8188eu: fix led register settings
+    - igb: Initialize mailbox message for VF reset
+    - usb: typec: ucsi: Resume in separate work
+    - usb: dwc3: pci: Update PCIe device ID for USB3 controller on CPU sub-system
+      for Raptor Lake
+    - cifs: fix oops during encryption
+    - KEYS: encrypted: fix key instantiation with user-provided data
+    - Linux 6.1.1
+
+  * Expose built-in trusted and revoked certificates (LP: #1996892)
+    - [Packaging] Expose built-in trusted and revoked certificates
+
+  * Fix System cannot detect bluetooth after running suspend stress test
+    (LP: #1998727)
+    - wifi: rtw88: 8821c: enable BT device recovery mechanism
+
+  * Gnome doesn't run smooth when performing normal usage with RPL-P CPU
+    (LP: #1998419)
+    - drm/i915/rpl-p: Add stepping info
+
+  * Mute/mic LEDs no function on a HP platfrom (LP: #1998882)
+    - ALSA: hda/realtek: fix mute/micmute LEDs for a HP ProBook
+
+  * Add additional Mediatek MT7922 BT device ID (LP: #1998885)
+    - Bluetooth: btusb: Add a new VID/PID 0489/e0f2 for MT7922
+
+  * Support Icicle Kit reference design v2022.10 (LP: #1993148)
+    - SAUCE: riscv: dts: microchip: Disable PCIe on the Icicle Kit
+
+  * Add iommu passthrough quirk for Intel IPU6 on RaptorLake (LP: #1989041)
+    - SAUCE: iommu: intel-ipu: use IOMMU passthrough mode for Intel IPUs on Raptor
+      Lake
+
+  * Enable Intel FM350 wwan CCCI driver port logging (LP: #1997686)
+    - net: wwan: t7xx: use union to group port type specific data
+    - net: wwan: t7xx: Add port for modem logging
+
+  * TEE Support for CCP driver (LP: #1991608)
+    - crypto: ccp - Add support for TEE for PCI ID 0x14CA
+
+  * Kinetic update: v5.19.17 upstream stable release (LP: #1994179)
+    - Revert "fs: check FMODE_LSEEK to control internal pipe splicing"
+    - kbuild: Add skip_encoding_btf_enum64 option to pahole
+
+  * Kinetic update: v5.19.15 upstream stable release (LP: #1994078)
+    - Revert "clk: ti: Stop using legacy clkctrl names for omap4 and 5"
+
+  * support independent clock and LED GPIOs for Intel IPU6 platforms
+    (LP: #1989046)
+    - SAUCE: platform/x86: int3472: support independent clock and LED GPIOs
+
+  * Kernel livepatch support for for s390x (LP: #1639924)
+    - [Config] Enable EXPOLINE_EXTERN on s390x
+
+  * Kinetic update: v5.19.7 upstream stable release (LP: #1988733)
+    - Revert "PCI/portdrv: Don't disable AER reporting in
+      get_port_device_capability()"
+
+  * Kinetic update: v5.19.3 upstream stable release (LP: #1987345)
+    - Revert "mm: kfence: apply kmemleak_ignore_phys on early allocated pool"
+
+  * Fix non-working e1000e device after resume (LP: #1951861)
+    - SAUCE: Revert "e1000e: Add polling mechanism to indicate CSME DPG exit"
+
+  * Add additional Mediatek MT7921 WiFi/BT device IDs (LP: #1937004)
+    - SAUCE: Bluetooth: btusb: Add support for Foxconn Mediatek Chip
+
+  * Fix system sleep on TGL systems with Intel ME (LP: #1919321)
+    - SAUCE: PCI: Serialize TGL e1000e PM ops
+
+  * Fix broken e1000e device after S3 (LP: #1897755)
+    - SAUCE: e1000e: Increase polling timeout on MDIC ready bit
+
+  * Fix unusable USB hub on Dell TB16 after S3 (LP: #1855312)
+    - SAUCE: USB: core: Make port power cycle a seperate helper function
+    - SAUCE: USB: core: Attempt power cycle port when it's in eSS.Disabled state
+
+  * Set explicit CC in the headers package (LP: #1999750)
+    - [Packaging] Set explicit CC in the headers package
+
+  * commit cf58599cded35cf4affed1e659c0e2c742d3fda7 seems to be missing in
+    kinetic master to remove "hio" reference from Makefile (LP: #1999556)
+    - SAUCE: remove leftover reference to ubuntu/hio driver
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] kernelconfig: always complete all config checks
+    - [Packaging] annotations: unify same rule across all flavour within the same
+      arch
+    - [Config] annotations: compact annotations file
+    - [Config] disable EFI_ZBOOT
+    - SAUCE: input: i8042: fix section mismatch warning
+    - debian/dkms-versions -- re-enable zfs
+    - [Packaging] old-kernelconfig: update config-check path
+    - [Packaging] update getabis
+    - [Packaging] update Ubuntu.md
+
+  * Miscellaneous upstream changes
+    - Revert "drm/i915/opregion: check port number bounds for SWSCI display power
+      state"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 30 Dec 2022 11:23:16 +0100
+
+linux (6.1.0-10.10) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-10.10 -proposed tracker (LP: #1999569)
+
+  * Soundwire support for the Intel RPL Gen platforms (LP: #1997944)
+    - ASoC: Intel: sof_sdw: Add support for SKU 0C10 product
+    - ASoC: Intel: soc-acpi: add SKU 0C10 SoundWire configuration
+    - ASoC: Intel: sof_sdw: Add support for SKU 0C40 product
+    - ASoC: Intel: soc-acpi: add SKU 0C40 SoundWire configuration
+    - ASoC: Intel: sof_sdw: Add support for SKU 0C4F product
+    - ASoC: rt1318: Add RT1318 SDCA vendor-specific driver
+    - ASoC: intel: sof_sdw: add rt1318 codec support.
+    - ASoC: Intel: sof_sdw: Add support for SKU 0C11 product
+    - ASoC: Intel: soc-acpi: add SKU 0C11 SoundWire configuration
+    - SAUCE: ASoC: Intel: soc-acpi: update codec addr on 0C11/0C4F product
+    - [Config] enable CONFIG_SND_SOC_RT1318_SDW
+
+  * Virtual GPU driver packaging regression (LP: #1996112)
+    - [Packaging] Reintroduce VM DRM drivers into modules
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 13 Dec 2022 22:14:08 +0100
+
+linux (6.1.0-9.9) lunar; urgency=medium
+
+  * Empty entry (ABI bump)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 13 Dec 2022 21:31:08 +0100
+
+linux (6.1.0-3.3) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-3.3 -proposed tracker (LP: #1999534)
+
+  * [DEP-8] Run ADT regression suite for lowlatency kernels Jammy and later
+    (LP: #1999528)
+    - [DEP-8] Fix regression suite to run on lowlatency
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: do not add constraints on toolchain versions
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 13 Dec 2022 16:45:59 +0100
+
+linux (6.1.0-2.2) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-2.2 -proposed tracker (LP: #1999411)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: do not enforce toolchain versions
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 12 Dec 2022 17:05:59 +0100
+
+linux (6.1.0-1.1) lunar; urgency=medium
+
+  * lunar/linux: 6.1.0-1.1 -proposed tracker (LP: #1999373)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] annotations: set and delete configs from command line
+    - [Packaging] migrateconfigs: ignore README.rst if it doesn't exist
+    - [Packaging] migrate-annotations: properly determine arches in derivatives
+    - [Packaging] annotations: allow to set note to config options directly
+    - [Packaging] annotations: assume --query as default command
+    - [Packaging] annotations: allow to query using CONFIG_<option> or <option>
+    - [Packaging] annotations: support flavour inheritance
+    - [Packaging] annotations: properly merge configs with includes
+    - [Packaging] annotations: accept config options with or without CONFIG_
+      prefix
+    - [Packaging] annotations: clarify error message with --import
+    - [Packaging] annotations: properly support multiple levels of inclusion
+    - [Packaging] annotations: catch syntax errors in annotations
+    - [Packaging] kernelconfig: report arch and flavour in config-check log
+    - [Packaging] annotations: prevent generating .pyc files on import
+    - [Packaging] annotations: prevent python broken pipe errors
+    - [Packaging] annotations: allow to specify --write and --note at the same
+      time
+    - [Packaging] annotations: add an option to enable config autocompletion in
+      bash
+    - [Packaging] annotations: introduce --source
+    - [Packaging] annotations: add missing CONFIG_ prefix in main()
+    - [Packaging] Remove obsolete etc/kernelconfig
+    - [Packaging] Rewrite debian/scripts/abi-check in Python
+    - [Packaging] Simplify debian/scripts/module-check
+    - [Packaging] Clean up debian/scripts/module-check
+    - [Packaging] Move checker scripts to debian/scripts/checks
+    - [Packaging] mark phony targets
+    - [Packaging] Make the compiler for fix-filenames explicit
+    - [Packaging] add -rR MAKEFLAGS to clear implicit rules
+    - [Packaging] use dpkg-parsechangelog to get package name and series
+    - [Packaging] simplify revision/release
+    - [Packaging] simplify custom_override
+    - [Packaging] Remove meaningless code in install-arch-headers
+    - [Packaging] use olddefconfig in stamp-prepare-tree
+    - [Packaging] use parralel builds in more places
+    - [Packaging] install headers to debian/linux-libc-dev directly
+    - [Packaging] simplify abinum and uploadnum definitions
+    - [Packaging] Remove unused INSTALL_FW_PATH
+    - [Packaging] Merge install commands
+    - [Config] clean up deprecated notes in annotations
+    - [Packaging] automatically apply changes to annotations and drop
+      importconfigs
+    - [Packaging] kernelconfig: drop listnewconfigs
+    - [Packaging] annotations: do not hijack CONFIGS/* to update annotations
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 12 Dec 2022 10:05:03 +0100
+
+linux (6.1.0-0.0) lunar; urgency=medium
+
+  * Empty entry
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 12 Dec 2022 09:42:01 +0100
+
+linux-unstable (6.1.0-9.9) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-9.9 -proposed tracker (LP: #1998078)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Set ARM64_ERRATUM_2077057=y
+    - SAUCE: add python cached bytecode to .gitignore
+    - [Packaging] config-check: ignore values that are not defined in annotations
+    - [Packaging] config-check: do not strictly enforce CONFIG_CC_VERSION_TEXT
+    - [Packaging] config-check: support annotations format 4
+    - [Packaging] introduce annotations script
+    - [Packaging] add a README.rst to document the new annotations schema
+    - [Packaging] kernelconfig: automatically generate configs from annotations
+    - [Packaging] drop deprecated script tristate.sh
+    - [Packaging] use annotations to generate initial configs check them
+    - [Packaging] simplify kernelconfig
+    - [Packaging] kernelconfig: always keep configs
+    - [Packaging] kernelconfig: provide listnewconfigs
+    - [Packaging] kernelconfig: introduce importconfigs
+    - [Packaging] snap: support new annotations with snapcraft
+    - [Packaging] final-checks: support new annotations
+    - [Packaging] introduce migrate-annotations
+    - [Packaging] re-introduce previous kernelconfig as old-kernelconfig
+    - [Packaging] provide migrateconfigs debian/rules target
+    - [Packaging] correctly propagate errors during updateconfigs
+    - [Packaging] annotations: report failed config checks in alphabetic order
+    - [Config] merge configs into annotations
+    - [Config] udpate annotations after rebase to v6.1-rc7
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Nov 2022 11:25:44 +0100
+
+linux-unstable (6.1.0-8.8) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-8.8 -proposed tracker (LP: #1997357)
+
+  *  Fibocom WWAN FM350-GL suspend error (notebook not suspend) (LP: #1990700)
+    - net: wwan: t7xx: Add AP CLDMA
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v6.1-rc6
+    - [Config] update configs following v6.1-rc6 rebase
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs following v6.1-rc6 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 22 Nov 2022 11:56:26 +0100
+
+linux-unstable (6.1.0-7.7) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-7.7 -proposed tracker (LP: #1996731)
+
+  * Miscellaneous Ubuntu changes
+    - ppc64el: remove missing module
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 16 Nov 2022 11:37:05 +0100
+
+linux-unstable (6.1.0-6.6) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-6.6 -proposed tracker (LP: #1996616)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs following v6.1-rc5 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 15 Nov 2022 15:55:33 +0100
+
+linux-unstable (6.1.0-5.5) lunar; urgency=medium
+
+  * lunar/linux-unstable: 6.1.0-5.5 -proposed tracker (LP: #1995875)
+
+  * Please have linux-tools-common Provide: bpftool (LP: #1981089)
+    - [Packaging] let linux-tools-common provides bpftool
+
+  * Miscellaneous Ubuntu changes
+    - packaging: switch to lunar series
+    - Rebase to v6.1-rc4
+    - [Config] toolchian update
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc4
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 07 Nov 2022 16:43:21 +0100
+
+linux-unstable (6.1.0-4.4) lunar; urgency=medium
+
+  * kinetic/linux-unstable: 6.1.0-4.4 -proposed tracker (LP: #1995500)
+
+  * Fix ath11k deadlock on WCN6855 (LP: #1995041)
+    - SAUCE: wifi: ath11k: avoid deadlock during regulatory update in
+      ath11k_regd_update()
+
+  * Bump (kernel) '-mtune' to z16 / arch14 with 23.04 (LP: #1982833)
+    - [Config] Enable mtune z16
+
+  * armhf kernel compiled with gcc-12 fails to boot on pi 3/2 (LP: #1993120)
+    - [Packaging] Support arch-specific compilers in updateconfigs
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs after rebase to 6.1-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 03 Nov 2022 14:00:41 +0100
+
+linux-unstable (6.1.0-3.3) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.1.0-3.3 -proposed tracker (LP: #1994037)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Support skipped dkms modules
+    - [Config] update configs after rebase to 6.1-rc2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 24 Oct 2022 15:53:11 +0200
+
+linux-unstable (6.1.0-2.2) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.1.0-2.2 -proposed tracker (LP: #1993350)
+
+  * Populating Hyper-V MSR for Ubuntu 13.10 (LP: #1193172)
+    - SAUCE: (no-up) hv: Supply vendor ID and package ABI
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: perf tools: Fix man page build wrt perf-arm-coresight.txt
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 18 Oct 2022 23:02:31 +0200
+
+linux-unstable (6.1.0-1.1) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.1.0-1.1 -proposed tracker (LP: #1993118)
+
+  * Raise CONFIG_NR_CPUS (LP: #1967889)
+    - [Config] Raise riscv64 CONFIG_NR_CPUS to 32
+
+  * rcu_sched detected stalls on CPUs/tasks (LP: #1967130)
+    - [Config] Disable VMAP_STACK on riscv64
+
+  * Disable sv57 as the userspace is not ready (LP: #1991790)
+    - SAUCE: riscv: mm: Force disable sv57
+
+  * earlyconsole prints question marks on 5.19.0-1002-generic (LP: #1988984)
+    - [Config] Set CONFIG_PWM_SIFIVE=m for riscv64
+
+  * RCU stalls (LP: #1991951)
+    - [Config] Harmonize RCU_CPU_STALL_TIMEOUT
+
+  * backport dkms fixes to build modules correctly for hwe-5.19+ kernels with
+    custom compiler (LP: #1991664)
+    - [Packaging] use versioned gcc-12
+    - [Packaging] Update configs with versioned compiler version
+
+  * FTBFS on kinetic (LP: #1990964)
+    - SAUCE: uapi: Fixup strace compile error
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] sameport -- add support for sameport versioning
+    - [Packaging] move to kernel 6.1
+    - SAUCE: platform/x86: dell-uart-backlight: remove
+      acpi_video_set_dmi_backlight_type()
+    - SAUCE: shiftfs: support kernel 6.1
+    - [Config] update configs and annotations after rebase to 6.1-rc1
+    - debian/dkms-versions -- temporarily disable dkms builds
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.1-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 18 Oct 2022 17:21:43 +0200
+
+linux-unstable (6.1.0-0.0) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 17 Oct 2022 08:57:58 +0200
+
+linux-unstable (6.0.0-9.9) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-9.9 -proposed tracker (LP: #1991521)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update toolchain configs after rebase to 6.0
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 03 Oct 2022 15:51:57 +0200
+
+linux-unstable (6.0.0-8.8) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-8.8 -proposed tracker (LP: #1990101)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 20 Sep 2022 10:22:14 +0200
+
+linux-unstable (6.0.0-7.7) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-7.7 -proposed tracker (LP: #1989331)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+    - [Packaging] resync getabis
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Please enable CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU (LP: #1980861)
+    - [Config] Switch from DECOMP_SINGLE to DECOMP_MULTI_PERCPU
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Pass kernel build_arch to dkms
+    - [Packaging[ get rid of unnecessary 'set -x'
+    - [Config] update configs and annotations after rebase to 6.0-rc5
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 12 Sep 2022 14:03:55 +0200
+
+linux-unstable (6.0.0-6.6) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-6.6 -proposed tracker (LP: #1988706)
+
+  * Support Intel TDX guest attestation driver (LP: #1988120)
+    - SAUCE: x86/tdx: Add TDX Guest attestation interface driver
+    - SAUCE: selftests: tdx: Test GetReport TDX attestation feature
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] temporarily disable signing for ppc64el and s390x
+    - [Config] enable security-related configs
+    - [Config] update toolchain versions
+    - [Packaging] fix URLs used to retrieve kernel ABI
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 05 Sep 2022 16:59:40 +0200
+
+linux-unstable (6.0.0-5.5) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-5.5 -proposed tracker (LP: #1988019)
+
+  * LSM: Configuring Too Many LSMs Causes Kernel Panic on Boot (LP: #1987998)
+    - SAUCE: LSM: Change Landlock from LSMBLOB_NEEDED to LSMBLOB_NOT_NEEDED
+
+  * RISC-V kernel config is out of sync with other archs (LP: #1981437)
+    - [Config] Align riscv64 CONFIG_LSM with other architectures
+    - [Config] Enable CONFIG_DRM_RCAR_USE_LVDS for riscv64
+    - [Config] Enable CONFIG_DTPM for riscv64
+    - [Config] Set CONFIG_MTD_RAW_NAND=m for riscv64
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging]: always use fully qualified <triplet>-gcc-VER toolchain
+    - [Packaging] use unversioned default gcc
+    - [Packaging] Remove circular dependency between image & modules
+    - [Config] update configs after rebase to 6.0-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 29 Aug 2022 09:18:39 +0200
+
+linux-unstable (6.0.0-4.4) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-4.4 -proposed tracker (LP: #1987517)
+
+  * Fix invalid MAC address after hotplug tbt dock (LP: #1942999)
+    - SAUCE: igc: wait for the MAC copy when enabled MAC passthrough
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] getabis: Add modules.builtin to the ABI
+
+  * Miscellaneous upstream changes
+    - perf tools: Fix compile error for x86
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 24 Aug 2022 15:10:24 +0200
+
+linux-unstable (6.0.0-3.3) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-3.3 -proposed tracker (LP: #1987241)
+
+  * [22.04 FEAT] Deactivitate  CONFIG_QETH_OSX kernel config option
+    (LP: #1959890)
+    - [Config] disable CONFIG_QETH_OSX on s390x
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Make stamp-install-<flavor> target reentrant
+    - [Config] update toolchain version
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 22 Aug 2022 09:09:26 +0200
+
+linux-unstable (6.0.0-2.2) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-2.2 -proposed tracker (LP: #1986844)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "perf tools: Use Python devtools for version autodetection
+      rather than runtime"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 17 Aug 2022 19:40:07 +0200
+
+linux-unstable (6.0.0-1.1) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 6.0.0-1.1 -proposed tracker (LP: #1986784)
+
+  * refactoring of overlayfs fix to properly support shiftfs (LP: #1983640)
+    - SAUCE: for aufs mmap: print the virtual file path
+    - SAUCE: overlayfs: fix incorrect mnt_id of files opened from map_files
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move to kernel 6.0
+    - [Config] update configs and annotations after rebase to 6.0-rc1
+    - [Packaging] temporarily disable dkms
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v6.0-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 17 Aug 2022 16:56:18 +0200
+
+linux-unstable (6.0.0-0.0) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 17 Aug 2022 10:23:42 +0200
+
+linux (5.19.0-15.15) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-15.15 -proposed tracker (LP: #1983335)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations to support both gcc-11 and gcc-12
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 02 Aug 2022 09:23:01 +0200
+
+linux (5.19.0-14.14) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-14.14 -proposed tracker (LP: #1983273)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] module-signature-check: Check debian.<foo>/signature-inclusion
+    - [Packaging] Introduce debian/scripts/sign-module
+    - SAUCE: Switch to using debian/scripts/sign-module
+    - [Config] update configs/annotations after rebase to 5.19
+    - [Config] update configs after moving to gcc-12
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging]: always use fully qualified <triplet>-gcc-VER
+      toolchain"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 01 Aug 2022 17:19:01 +0200
+
+linux (5.19.0-13.13) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-13.13 -proposed tracker (LP: #1983033)
+
+  * network-manager/1.36.4-2ubuntu1 ADT test failure with linux/5.15.0-28.29
+    (LP: #1971418)
+    - Revert "rfkill: make new event layout opt-in"
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Tighten up LP bug links in annotations
+    - [Config] Use mark<ENFORCED> for CONFIG_DEVTMPFS
+    - [Config] Use flag<DEPRECATED> for CONFIG_HIPPI
+    - [Config] Use note<> for CONFIG_XEN_ACPI_PROCESSOR
+    - [Config] Fix DM_VERITY_VERIFY_ROOTHASH_SIG_SECONDARY_KEYRING annotation
+    - [Config] Fix CONFIG_CPU_LITTLE_ENDIAN annotation
+    - SAUCE: x86/bugs: Do not enable IBPB at firmware entry when IBPB is not
+      available
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 28 Jul 2022 17:04:33 +0200
+
+linux (5.19.0-12.12) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-12.12 -proposed tracker (LP: #1982741)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging]: always use fully qualified <triplet>-gcc-VER toolchain
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 26 Jul 2022 15:07:13 +0200
+
+linux (5.19.0-11.11) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-11.11 -proposed tracker (LP: #1982726)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * GPIO character device v1 API not enabled in kernel (LP: #1953613)
+    - [Config] Enable CONFIG_GPIO_CDEV_V1
+
+  * Use kernel-testing repo from launchpad for ADT tests (LP: #1968016)
+    - [Debian] Use kernel-testing repo from launchpad
+
+  * Support AMD P-State cpufreq control mechanism (LP: #1956509)
+    - [Config] enable X86_AMD_PSTATE as built-in on amd64
+
+  * PCIE LnkCtl ASPM not enabled under VMD mode for Alder Lake platforms
+    (LP: #1942160)
+    - SAUCE: PCI/ASPM: Enable ASPM for links under VMD domain
+    - SAUCE: PCI/ASPM: Enable LTR for endpoints behind VMD
+    - SAUCE: vmd: fixup bridge ASPM by driver name instead
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Double the speed of updateconfigs
+    - Remove ubuntu/hio driver
+    - [Config] update config after rebase to 5.19-rc8
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc8
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 25 Jul 2022 08:54:21 +0200
+
+linux (5.19.0-10.10) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-10.10 -proposed tracker (LP: #1982013)
+
+  * enable config for fixing 5.17 kernel won't load mok (LP: #1972802)
+    - [Config] enable configs for fixing kernel won't load mok
+
+  * RISC-V kernel config is out of sync with other archs (LP: #1981437)
+    - [Config] Disable CONFIG_CXL_MEM_RAW_COMMANDS on riscv64
+    - [Config] Disable CONFIG_EROFS_FS_ZIP_LZMA on riscv64
+    - [Config] Disable CONFIG_FONT_6x8 on riscv64
+    - [Config] Disable CONFIG_NTFS3_64BIT_CLUSTER on riscv64
+    - [Config] Disable CONFIG_SCSI_IZIP_EPP16 on riscv64
+    - [Config] Disable CONFIG_SCSI_UFS_HWMON on riscv64
+    - [Config] Disable CONFIG_SPI_AX88796C_COMPRESSION on riscv64
+    - [Config] Disable CONFIG_VIDEO_ZORAN on riscv64
+    - [Config] Enable CONFIG_BPF_KPROBE_OVERRIDE on riscv64
+    - [Config] Enable CONFIG_CACHEFILES_ERROR_INJECTION on riscv64
+    - [Config] Enable CONFIG_DRM_AMD_DC_SI on riscv64
+    - [Config] Enable CONFIG_NUMA_BALANCING on riscv64
+    - [Config] Enable CONFIG_PROC_VMCORE_DEVICE_DUMP on riscv64
+    - [Config] Enable CONFIG_WLAN_VENDOR_MICROCHIP on riscv64
+    - [Config] Set CONFIG_MHI_WWAN_CTRL=m on riscv64
+    - [Config] Set CONFIG_NFC_S3FWRN82_UART=m on riscv64
+    - [Config] Enable CONFIG_EFIVAR_FS on riscv64
+    - [Config] Enable CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES on riscv64
+    - [Config] Enable CONFIG_STRICT_DEVMEM on riscv64
+    - [Config] Enable CONFIG_VMAP_STACK on riscv64
+    - [Config] Enable CONFIG_KEXEC_FILE on riscv64
+    - [Config] Set CONFIG_MTD_PSTORE=m on riscv64
+    - [Config] Set CONFIG_KFENCE_SAMPLE_INTERVAL=0 on riscv64
+    - [Config] Enable CONFIG_KEXEC_FILE on s390x
+
+  * Ubuntu 22.04 and 20.04 DPC Fixes for Failure Cases of DownPort Containment
+    events (LP: #1965241)
+    - Enable config option CONFIG_PCIE_EDR
+    - Correct CONFIG_PCIE_EDR annotation on arm64
+
+  * config CONFIG_HISI_PMU for  kunpeng920 (LP: #1956086)
+    - [Config] CONFIG_HISI_PMU=m
+
+  * Skip setting ethernet LED on Dell EMC board (LP: #1971667)
+    - SAUCE: net: phy: marvell: Skip setting LED on Dell EMC board
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] ignore warnings from the output of ld.bfd
+    - [Packaging] Fix bashism in dkms-build script
+    - [Packaging] Always catch errors in dkms-build scripts
+    - [Packaging] Fix dkms builds with linker @module.mod files
+    - [Packaging] mark dkms-build-configure--zfs executable
+    - [Config] update configs and annotations after rebase to 5.19-rc7
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 18 Jul 2022 23:45:28 +0200
+
+linux (5.19.0-9.9) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-9.9 -proposed tracker (LP: #1980622)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update config after rebase to 5.19-rc5
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 04 Jul 2022 12:05:04 +0200
+
+linux (5.19.0-8.8) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-8.8 -proposed tracker (LP: #1980482)
+
+  * temporarily disable CONFIG_X86_KERNEL_IBT (LP: #1980484)
+    - [Config] temporarily disable CONFIG_X86_KERNEL_IBT
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 01 Jul 2022 11:58:56 +0200
+
+linux (5.19.0-7.7) kinetic; urgency=medium
+
+  * kinetic/linux: 5.19.0-7.7 -proposed tracker (LP: #1980056)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * RISC-V enables CONFIG_COMPAT in the unstable branch (LP: #1980061)
+    - [Config] Disable CONFIG_COMPAT on RISC-V
+
+  * No RISC-V configuration in the unstable tree (LP: #1979647)
+    - [Config] Merge riscv64 config and annotations
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 28 Jun 2022 12:25:48 +0200
+
+linux (5.19.0-6.6) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 28 Jun 2022 07:50:17 +0200
+
+linux-unstable (5.19.0-6.6) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-6.6 -proposed tracker (LP: #1979948)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Remove 'family=ubuntu' concept
+    - [Packaging] final-checks: Remove useless sourcing of kernelconfig
+    - [Config] update config after rebase to 5.19-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 27 Jun 2022 09:16:40 +0200
+
+linux-unstable (5.19.0-5.5) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-5.5 -proposed tracker (LP: #1979611)
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] temporarily disable signing for ppc64el and
+      s390x"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 23 Jun 2022 11:13:32 +0200
+
+linux-unstable (5.19.0-4.4) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-4.4 -proposed tracker (LP: #1979177)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs after rebase to 5.19-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 20 Jun 2022 09:02:58 +0200
+
+linux-unstable (5.19.0-3.3) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-3.3 -proposed tracker (LP: #1978439)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations for 5.19
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.19-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 13 Jun 2022 07:16:32 +0200
+
+linux-unstable (5.19.0-2.2) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.19.0-2.2 -proposed tracker (LP: #1978313)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 10 Jun 2022 15:17:20 +0200
+
+linux-unstable (5.19.0-1.1) kinetic; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * linux: Staging modules should be unsigned (LP: #1642368)
+    - [Packaging] Move and update signature inclusion list
+    - [Packaging] Strip signatures from untrusted staging modules
+    - [Packaging] Add module-signature-check
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to 5.19-rc1
+    - [Packaging] move to kernel 5.19
+    - [Packaging] workaround missing python3-dev dependency
+    - SAUCE: Revert "perf tools: Use Python devtools for version autodetection
+      rather than runtime"
+    - SAUCE: watchdog: gxp: Add missing MODULE_LICENSE
+    - [Packaging] add python3-dev as build dependency
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 10 Jun 2022 14:43:46 +0200
+
+linux-unstable (5.19.0-0.0) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 09 Jun 2022 12:13:06 +0200
+
+linux (5.18.0-6.6) kinetic; urgency=medium
+
+  * kinetic/linux: 5.18.0-6.6 -proposed tracker (LP: #1976327)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] temporarily disable signing for ppc64el and s390x
+    - [Config] update toolchain versions
+    - [Config] enable CONFIG_X86_KERNEL_IBT
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 31 May 2022 11:05:51 +0200
+
+linux (5.18.0-5.5) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 23 May 2022 16:59:47 +0200
+
+linux-unstable (5.18.0-5.5) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-5.5 -proposed tracker (LP: #1975458)
+
+  * enable CONFIG_DEVTMPFS_SAFE (LP: #1974442)
+    - [Config] enable CONFIG_DEVTMPFS_SAFE
+
+  * build backport-iwlwifi-dkms as linux-modules-iwlwifi-ABI (LP: #1969434)
+    - [Packaging] drop do_<mod> arch specific configs
+
+  * prevent kernel panic with overlayfs + shiftfs (LP: #1973620)
+    - SAUCE: overlayfs: prevent dereferencing struct file in ovl_vm_prfile_set()
+
+  * linux-image-5.0.0-35-generic breaks checkpointing of container
+    (LP: #1857257) // re-apply missing overlayfs SAUCE patch (LP: #1967924)
+    - SAUCE: overlayfs: fix incorrect mnt_id of files opened from map_files
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 23 May 2022 11:21:38 +0200
+
+linux-unstable (5.18.0-4.4) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-4.4 -proposed tracker (LP: #1973587)
+
+  * build backport-iwlwifi-dkms as linux-modules-iwlwifi-ABI (LP: #1969434)
+    - [Packaging] support standalone dkms module builds
+
+  * Enable speakup kernel modules to allow the speakup screen reader to function
+    (LP: #1967702)
+    - [Config] CONFIG_SPEAKUP=m for all but s390x
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] temporarily disable v4l2loopback"
+    - Revert "UBUNTU: [Packaging] temporarily disable zfs"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 16 May 2022 14:15:35 +0200
+
+linux-unstable (5.18.0-3.3) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-3.3 -proposed tracker (LP: #1972162)
+
+  * disable Intel DMA remapping by default (LP: #1971699)
+    - Revert "UBUNTU: [Config] enable Intel DMA remapping options by default"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 May 2022 12:15:39 +0200
+
+linux-unstable (5.18.0-2.2) kinetic; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-2.2 -proposed tracker (LP: #1971340)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs after rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 03 May 2022 12:24:49 +0200
+
+linux-unstable (5.18.0-1.1) kinetic; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 03 May 2022 09:38:06 +0200
+
+linux-unstable (5.18.0-1.1) jammy; urgency=medium
+
+  * kinetic/linux-unstable: 5.18.0-1.1 -proposed tracker (LP: #1969476)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to 5.18
+    - [Packaging] temporarily disable zfs
+    - [Packaging] temporarily disable v4l2loopback
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.18-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 27 Apr 2022 20:26:42 +0200
+
+linux-unstable (5.18.0-0.0) jammy; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 19 Apr 2022 16:20:00 +0200
+
+linux-unstable (5.17.0-8.8) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-8.8 -proposed tracker (LP: #1969016)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 14 Apr 2022 10:30:39 +0200
+
+linux-unstable (5.17.0-7.7) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-7.7 -proposed tracker (LP: #1968988)
+
+  * zfcpdump-kernel update to v5.15 (LP: #1965766)
+    - SAUCE: Audit: Fix incorrect static inline function declration.
+
+  * intel_iommu breaks Intel IPU6 camera: isys port open ready failed -16
+    (LP: #1958004)
+    - SAUCE: iommu: intel-ipu: use IOMMU passthrough mode for Intel IPUs
+
+  * Jammy update: v5.17.3 upstream stable release (LP: #1968986)
+    - lib/logic_iomem: correct fallback config references
+    - um: fix and optimize xor select template for CONFIG64 and timetravel mode
+    - rtc: wm8350: Handle error for wm8350_register_irq
+    - net: dsa: felix: fix possible NULL pointer dereference
+    - mm: kfence: fix objcgs vector allocation
+    - KVM: x86/pmu: Use different raw event masks for AMD and Intel
+    - KVM: SVM: Fix kvm_cache_regs.h inclusions for is_guest_mode()
+    - KVM: x86/svm: Clear reserved bits written to PerfEvtSeln MSRs
+    - KVM: x86/pmu: Fix and isolate TSX-specific performance event logic
+    - KVM: x86/emulator: Emulate RDPID only if it is enabled in guest
+    - drm: Add orientation quirk for GPD Win Max
+    - Bluetooth: hci_sync: Fix compilation warning
+    - ath5k: fix OOB in ath5k_eeprom_read_pcal_info_5111
+    - Bluetooth: fix null ptr deref on hci_sync_conn_complete_evt
+    - drm/amd/display: Add signal type check when verify stream backends same
+    - drm/amdkfd: enable heavy-weight TLB flush on Arcturus
+    - drm/edid: remove non_desktop quirk for HPN-3515 and LEN-B800.
+    - drm/edid: improve non-desktop quirk logging
+    - Bluetooth: hci_event: Ignore multiple conn complete events
+    - drm/amd/amdgpu/amdgpu_cs: fix refcount leak of a dma_fence obj
+    - drm/amd/display: Fix memory leak
+    - drm/amd/display: Use PSR version selected during set_psr_caps
+    - usb: gadget: tegra-xudc: Do not program SPARAM
+    - usb: gadget: tegra-xudc: Fix control endpoint's definitions
+    - usb: cdnsp: fix cdnsp_decode_trb function to properly handle ret value
+    - ptp: replace snprintf with sysfs_emit
+    - Bluetooth: hci_sync: Fix queuing commands when HCI_UNREGISTER is set
+    - selftests, xsk: Fix bpf_res cleanup test
+    - net/mlx5e: TC, Hold sample_attr on stack instead of pointer
+    - drm/amdkfd: Don't take process mutex for svm ioctls
+    - drm/amdkfd: Ensure mm remain valid in svm deferred_list work
+    - drm/amdkfd: svm range restore work deadlock when process exit
+    - drm/amdgpu: Fix an error message in rmmod
+    - mlxsw: spectrum: Guard against invalid local ports
+    - RDMA/rtrs-clt: Do stop and failover outside reconnect work.
+    - powerpc/xive: Export XIVE IPI information for online-only processors.
+    - powerpc: dts: t104xrdb: fix phy type for FMAN 4/5
+    - ath11k: fix kernel panic during unload/load ath11k modules
+    - ath11k: pci: fix crash on suspend if board file is not found
+    - ath11k: mhi: use mhi_sync_power_up()
+    - net/smc: Send directly when TCP_CORK is cleared
+    - drm/bridge: Add missing pm_runtime_put_sync
+    - bpf: Make dst_port field in struct bpf_sock 16-bit wide
+    - scsi: mvsas: Replace snprintf() with sysfs_emit()
+    - scsi: bfa: Replace snprintf() with sysfs_emit()
+    - drm/v3d: fix missing unlock
+    - power: supply: axp20x_battery: properly report current when discharging
+    - mt76: mt7921: fix crash when startup fails.
+    - mt76: dma: initialize skip_unmap in mt76_dma_rx_fill
+    - i40e: Add sending commands in atomic context
+    - cfg80211: don't add non transmitted BSS to 6GHz scanned channels
+    - libbpf: Fix build issue with llvm-readelf
+    - ipv6: make mc_forwarding atomic
+    - ref_tracker: implement use-after-free detection
+    - net: initialize init_net earlier
+    - powerpc: Set crashkernel offset to mid of RMA region
+    - drm/amdgpu: Fix recursive locking warning
+    - scsi: smartpqi: Fix rmmod stack trace
+    - scsi: smartpqi: Fix kdump issue when controller is locked up
+    - PCI: aardvark: Fix support for MSI interrupts
+    - kvm: selftests: aarch64: fix assert in gicv3_access_reg
+    - kvm: selftests: aarch64: pass vgic_irq guest args as a pointer
+    - kvm: selftests: aarch64: fix the failure check in
+      kvm_set_gsi_routing_irqchip_check
+    - kvm: selftests: aarch64: fix some vgic related comments
+    - kvm: selftests: aarch64: use a tighter assert in vgic_poke_irq()
+    - iommu/arm-smmu-v3: fix event handling soft lockup
+    - usb: ehci: add pci device support for Aspeed platforms
+    - KVM: arm64: Do not change the PMU event filter after a VCPU has run
+    - libbpf: Fix accessing syscall arguments on powerpc
+    - libbpf: Fix accessing the first syscall argument on arm64
+    - libbpf: Fix accessing the first syscall argument on s390
+    - PCI: endpoint: Fix alignment fault error in copy tests
+    - tcp: Don't acquire inet_listen_hashbucket::lock with disabled BH.
+    - PCI: pciehp: Add Qualcomm quirk for Command Completed erratum
+    - scsi: mpi3mr: Fix deadlock while canceling the fw event
+    - scsi: mpi3mr: Fix reporting of actual data transfer size
+    - scsi: mpi3mr: Fix memory leaks
+    - powerpc/set_memory: Avoid spinlock recursion in change_page_attr()
+    - power: supply: axp288-charger: Set Vhold to 4.4V
+    - drm/sprd: fix potential NULL dereference
+    - drm/sprd: check the platform_get_resource() return value
+    - drm/amd/display: reset lane settings after each PHY repeater LT
+    - net/mlx5e: Disable TX queues before registering the netdev
+    - HID: apple: Report Magic Keyboard 2021 battery over USB
+    - HID: apple: Report Magic Keyboard 2021 with fingerprint reader battery over
+      USB
+    - usb: dwc3: pci: Set the swnode from inside dwc3_pci_quirks()
+    - iwlwifi: mvm: Correctly set fragmented EBS
+    - iwlwifi: fix small doc mistake for iwl_fw_ini_addr_val
+    - iwlwifi: mvm: move only to an enabled channel
+    - ipv6: annotate some data-races around sk->sk_prot
+    - drm/msm/dsi: Remove spurious IRQF_ONESHOT flag
+    - x86/mce: Work around an erratum on fast string copy instructions
+    - rtw89: fix RCU usage in rtw89_core_txq_push()
+    - ath11k: Fix frames flush failure caused by deadlock
+    - ipv4: Invalidate neighbour for broadcast address upon address addition
+    - rtw88: change rtw_info() to proper message level
+    - dm ioctl: prevent potential spectre v1 gadget
+    - dm: requeue IO if mapping table not yet available
+    - drm/amdkfd: make CRAT table missing message informational only
+    - vfio/pci: Stub vfio_pci_vga_rw when !CONFIG_VFIO_PCI_VGA
+    - scsi: pm8001: Fix pm80xx_pci_mem_copy() interface
+    - scsi: pm8001: Fix pm8001_mpi_task_abort_resp()
+    - scsi: pm8001: Fix tag values handling
+    - scsi: pm8001: Fix task leak in pm8001_send_abort_all()
+    - scsi: pm8001: Fix tag leaks on error
+    - scsi: pm8001: Fix memory leak in pm8001_chip_fw_flash_update_req()
+    - mt76: mt7915: fix injected MPDU transmission to not use HW A-MSDU
+    - mctp: make __mctp_dev_get() take a refcount hold
+    - powerpc/64s/hash: Make hash faults work in NMI context
+    - mt76: mt7615: Fix assigning negative values to unsigned variable
+    - power: supply: axp288_charger: Use acpi_quirk_skip_acpi_ac_and_battery()
+    - power: supply: axp288_fuel_gauge: Use acpi_quirk_skip_acpi_ac_and_battery()
+    - scsi: aha152x: Fix aha152x_setup() __setup handler return value
+    - scsi: hisi_sas: Free irq vectors in order for v3 HW
+    - scsi: hisi_sas: Limit users changing debugfs BIST count value
+    - net/smc: correct settings of RMB window update limit
+    - mips: ralink: fix a refcount leak in ill_acc_of_setup()
+    - iavf: stop leaking iavf_status as "errno" values
+    - macvtap: advertise link netns via netlink
+    - platform/x86: thinkpad_acpi: Add dual fan probe
+    - tuntap: add sanity checks about msg_controllen in sendmsg
+    - Bluetooth: mediatek: fix the conflict between mtk and msft vendor event
+    - Bluetooth: Fix not checking for valid hdev on bt_dev_{info,warn,err,dbg}
+    - Bluetooth: use memset avoid memory leaks
+    - bnxt_en: Eliminate unintended link toggle during FW reset
+    - PCI: endpoint: Fix misused goto label
+    - MIPS: fix fortify panic when copying asm exception handlers
+    - powerpc/code-patching: Pre-map patch area
+    - powerpc/64e: Tie PPC_BOOK3E_64 to PPC_FSL_BOOK3E
+    - powerpc/secvar: fix refcount leak in format_show()
+    - scsi: libfc: Fix use after free in fc_exch_abts_resp()
+    - platform/x86: x86-android-tablets: Depend on EFI and SPI
+    - can: isotp: set default value for N_As to 50 micro seconds
+    - can: etas_es58x: es58x_fd_rx_event_msg(): initialize rx_event_msg before
+      calling es58x_check_msg_len()
+    - riscv: Fixed misaligned memory access. Fixed pointer comparison.
+    - net: account alternate interface name memory
+    - net: limit altnames to 64k total
+    - net/mlx5e: Remove overzealous validations in netlink EEPROM query
+    - platform/x86: hp-wmi: Fix SW_TABLET_MODE detection method
+    - platform/x86: hp-wmi: Fix 0x05 error code reported by several WMI calls
+    - net: sfp: add 2500base-X quirk for Lantech SFP module
+    - usb: dwc3: omap: fix "unbalanced disables for smps10_out1" on omap5evm
+    - xen/usb: harden xen_hcd against malicious backends
+    - mt76: fix monitor mode crash with sdio driver
+    - xtensa: fix DTC warning unit_address_format
+    - iwlwifi: mei: fix building iwlmei
+    - MIPS: ingenic: correct unit node address
+    - Bluetooth: Fix use after free in hci_send_acl
+    - netfilter: conntrack: revisit gc autotuning
+    - netlabel: fix out-of-bounds memory accesses
+    - ceph: fix inode reference leakage in ceph_get_snapdir()
+    - ceph: fix memory leak in ceph_readdir when note_last_dentry returns error
+    - lib/Kconfig.debug: add ARCH dependency for FUNCTION_ALIGN option
+    - init/main.c: return 1 from handled __setup() functions
+    - minix: fix bug when opening a file with O_DIRECT
+    - clk: si5341: fix reported clk_rate when output divider is 2
+    - clk: mediatek: Fix memory leaks on probe
+    - staging: vchiq_arm: Avoid NULL ptr deref in vchiq_dump_platform_instances
+    - staging: vchiq_core: handle NULL result of find_service_by_handle
+    - phy: amlogic: phy-meson-gxl-usb2: fix shared reset controller use
+    - phy: amlogic: meson8b-usb2: Use dev_err_probe()
+    - phy: amlogic: meson8b-usb2: fix shared reset control use
+    - clk: rockchip: drop CLK_SET_RATE_PARENT from dclk_vop* on rk3568
+    - cpufreq: CPPC: Fix performance/frequency conversion
+    - opp: Expose of-node's name in debugfs
+    - staging: wfx: apply the necessary SDIO quirks for the Silabs WF200
+    - staging: wfx: fix an error handling in wfx_init_common()
+    - w1: w1_therm: fixes w1_seq for ds28ea00 sensors
+    - NFSv4.2: fix reference count leaks in _nfs42_proc_copy_notify()
+    - NFSv4: Protect the state recovery thread against direct reclaim
+    - habanalabs: fix possible memory leak in MMU DR fini
+    - habanalabs: reject host map with mmu disabled
+    - habanalabs/gaudi: handle axi errors from NIC engines
+    - xen: delay xen_hvm_init_time_ops() if kdump is boot on vcpu>=32
+    - clk: ti: Preserve node in ti_dt_clocks_register()
+    - clk: Enforce that disjoints limits are invalid
+    - SUNRPC/xprt: async tasks mustn't block waiting for memory
+    - SUNRPC: remove scheduling boost for "SWAPPER" tasks.
+    - NFS: swap IO handling is slightly different for O_DIRECT IO
+    - NFS: swap-out must always use STABLE writes.
+    - x86: Annotate call_on_stack()
+    - x86/Kconfig: Do not allow CONFIG_X86_X32_ABI=y with llvm-objcopy
+    - serial: samsung_tty: do not unlock port->lock for uart_write_wakeup()
+    - virtio_console: eliminate anonymous module_init & module_exit
+    - jfs: prevent NULL deref in diFree
+    - SUNRPC: Fix socket waits for write buffer space
+    - NFS: nfsiod should not block forever in mempool_alloc()
+    - NFS: Avoid writeback threads getting stuck in mempool_alloc()
+    - selftests: net: Add tls config dependency for tls selftests
+    - parisc: Fix CPU affinity for Lasi, WAX and Dino chips
+    - parisc: Fix patch code locking and flushing
+    - mm: fix race between MADV_FREE reclaim and blkdev direct IO read
+    - drm/amdgpu: fix off by one in amdgpu_gfx_kiq_acquire()
+    - Drivers: hv: vmbus: Fix initialization of device object in
+      vmbus_device_register()
+    - Drivers: hv: vmbus: Fix potential crash on module unload
+    - netfilter: bitwise: fix reduce comparisons
+    - Revert "NFSv4: Handle the special Linux file open access mode"
+    - NFSv4: fix open failure with O_ACCMODE flag
+    - scsi: core: scsi_logging: Fix a BUG
+    - scsi: sr: Fix typo in CDROM(CLOSETRAY|EJECT) handling
+    - scsi: core: Fix sbitmap depth in scsi_realloc_sdev_budget_map()
+    - scsi: zorro7xx: Fix a resource leak in zorro7xx_remove_one()
+    - vdpa: mlx5: prevent cvq work from hogging CPU
+    - net: sfc: add missing xdp queue reinitialization
+    - net/tls: fix slab-out-of-bounds bug in decrypt_internal
+    - vrf: fix packet sniffing for traffic originating from ip tunnels
+    - skbuff: fix coalescing for page_pool fragment recycling
+    - Revert "net: dsa: stop updating master MTU from master.c"
+    - ice: Clear default forwarding VSI during VSI release
+    - ice: Fix MAC address setting
+    - mctp: Fix check for dev_hard_header() result
+    - mctp: Use output netdev to allocate skb headroom
+    - net: ipv4: fix route with nexthop object delete warning
+    - net: stmmac: Fix unset max_speed difference between DT and non-DT platforms
+    - drm/imx: imx-ldb: Check for null pointer after calling kmemdup
+    - drm/imx: Fix memory leak in imx_pd_connector_get_modes
+    - drm/imx: dw_hdmi-imx: Fix bailout in error cases of probe
+    - regulator: rtq2134: Fix missing active_discharge_on setting
+    - spi: rpc-if: Fix RPM imbalance in probe error path
+    - regulator: atc260x: Fix missing active_discharge_on setting
+    - arch/arm64: Fix topology initialization for core scheduling
+    - bnxt_en: Synchronize tx when xdp redirects happen on same ring
+    - bnxt_en: reserve space inside receive page for skb_shared_info
+    - bnxt_en: Prevent XDP redirect from running when stopping TX queue
+    - sfc: Do not free an empty page_ring
+    - RDMA/mlx5: Don't remove cache MRs when a delay is needed
+    - RDMA/mlx5: Add a missing update of cache->last_add
+    - IB/cm: Cancel mad on the DREQ event when the state is MRA_REP_RCVD
+    - cifs: fix potential race with cifsd thread
+    - IB/rdmavt: add lock to call to rvt_error_qp to prevent a race condition
+    - sctp: count singleton chunks in assoc user stats
+    - dpaa2-ptp: Fix refcount leak in dpaa2_ptp_probe
+    - ice: Set txq_teid to ICE_INVAL_TEID on ring creation
+    - ice: Do not skip not enabled queues in ice_vc_dis_qs_msg
+    - ipv6: Fix stats accounting in ip6_pkt_drop
+    - ice: synchronize_rcu() when terminating rings
+    - ice: xsk: fix VSI state check in ice_xsk_wakeup()
+    - ice: clear cmd_type_offset_bsz for TX rings
+    - net: openvswitch: don't send internal clone attribute to the userspace.
+    - net: ethernet: mv643xx: Fix over zealous checking of_get_mac_address()
+    - net: openvswitch: fix leak of nested actions
+    - rxrpc: fix a race in rxrpc_exit_net()
+    - net: sfc: fix using uninitialized xdp tx_queue
+    - net: phy: mscc-miim: reject clause 45 register accesses
+    - qede: confirm skb is allocated before using
+    - spi: bcm-qspi: fix MSPI only access with bcm_qspi_exec_mem_op()
+    - drm/amd/display: Fix for dmub outbox notification enable
+    - drm/amd/display: Remove redundant dsc power gating from init_hw
+    - bpf: Support dual-stack sockets in bpf_tcp_check_syncookie
+    - drbd: Fix five use after free bugs in get_initial_state
+    - scsi: sd: sd_read_cpr() requires VPD pages
+    - scsi: ufs: ufshpb: Fix a NULL check on list iterator
+    - io_uring: nospec index for tags on files update
+    - io_uring: don't touch scm_fp_list after queueing skb
+    - SUNRPC: Handle ENOMEM in call_transmit_status()
+    - SUNRPC: Handle low memory situations in call_status()
+    - SUNRPC: svc_tcp_sendmsg() should handle errors from xdr_alloc_bvec()
+    - iommu/omap: Fix regression in probe for NULL pointer dereference
+    - perf unwind: Don't show unwind error messages when augmenting frame pointer
+      stack
+    - perf: arm-spe: Fix perf report --mem-mode
+    - perf tools: Fix perf's libperf_print callback
+    - perf session: Remap buf if there is no space for event
+    - arm64: Add part number for Arm Cortex-A78AE
+    - scsi: mpt3sas: Fix use after free in _scsih_expander_node_remove()
+    - scsi: ufs: ufs-pci: Add support for Intel MTL
+    - Revert "mmc: sdhci-xenon: fix annoying 1.8V regulator warning"
+    - mmc: block: Check for errors after write on SPI
+    - mmc: mmci: stm32: correctly check all elements of sg list
+    - mmc: renesas_sdhi: special 4tap settings only apply to HS400
+    - mmc: renesas_sdhi: don't overwrite TAP settings when HS400 tuning is
+      complete
+    - mmc: core: Fixup support for writeback-cache for eMMC and SD
+    - lz4: fix LZ4_decompress_safe_partial read out of bound
+    - highmem: fix checks in __kmap_local_sched_{in,out}
+    - mmmremap.c: avoid pointless invalidate_range_start/end on mremap(old_size=0)
+    - mm/mempolicy: fix mpol_new leak in shared_policy_replace
+    - io_uring: don't check req->file in io_fsync_prep()
+    - io_uring: defer splice/tee file validity check until command issue
+    - io_uring: implement compat handling for IORING_REGISTER_IOWQ_AFF
+    - io_uring: fix race between timeout flush and removal
+    - x86/pm: Save the MSR validity status at context setup
+    - x86/speculation: Restore speculation related MSRs during S3 resume
+    - perf/x86/intel: Update the FRONTEND MSR mask on Sapphire Rapids
+    - btrfs: fix qgroup reserve overflow the qgroup limit
+    - btrfs: zoned: traverse devices under chunk_mutex in btrfs_can_activate_zone
+    - btrfs: remove device item and update super block in the same transaction
+    - btrfs: avoid defragging extents whose next extents are not targets
+    - btrfs: prevent subvol with swapfile from being deleted
+    - spi: core: add dma_map_dev for __spi_unmap_msg()
+    - cifs: force new session setup and tcon for dfs
+    - qed: fix ethtool register dump
+    - arm64: patch_text: Fixup last cpu should be master
+    - RDMA/hfi1: Fix use-after-free bug for mm struct
+    - drbd: fix an invalid memory access caused by incorrect use of list iterator
+    - gpio: Restrict usage of GPIO chip irq members before initialization
+    - x86/msi: Fix msi message data shadow struct
+    - x86/mm/tlb: Revert retpoline avoidance approach
+    - perf/x86/intel: Don't extend the pseudo-encoding to GP counters
+    - ata: sata_dwc_460ex: Fix crash due to OOB write
+    - perf: qcom_l2_pmu: fix an incorrect NULL check on list iterator
+    - perf/core: Inherit event_caps
+    - irqchip/gic-v3: Fix GICR_CTLR.RWP polling
+    - fbdev: Fix unregistering of framebuffers without device
+    - amd/display: set backlight only if required
+    - drm/panel: ili9341: fix optional regulator handling
+    - drm/amd/display: Fix by adding FPU protection for dcn30_internal_validate_bw
+    - drm/amdgpu/display: change pipe policy for DCN 2.1
+    - drm/amdgpu/smu10: fix SoC/fclk units in auto mode
+    - drm/amdgpu/vcn: Fix the register setting for vcn1
+    - drm/nouveau/pmu: Add missing callbacks for Tegra devices
+    - drm/amdkfd: Create file descriptor after client is added to smi_clients list
+    - drm/amdgpu: don't use BACO for reset in S3
+    - SUNRPC: Ensure we flush any closed sockets before xs_xprt_free()
+    - Revert "ACPI: processor: idle: Only flush cache on entering C3"
+    - drm/amdkfd: Fix variable set but not used warning
+    - net/smc: send directly on setting TCP_NODELAY
+    - Revert "selftests: net: Add tls config dependency for tls selftests"
+    - bpf: Make remote_port field in struct bpf_sk_lookup 16-bit wide
+    - selftests/bpf: Fix u8 narrow load checks for bpf_sk_lookup remote_port
+    - bpf: Treat bpf_sk_lookup remote_port as a 2-byte field
+    - perf build: Don't use -ffat-lto-objects in the python feature test when
+      building with clang-13
+    - perf python: Fix probing for some clang command line options
+    - tools build: Filter out options and warnings not supported by clang
+    - tools build: Use $(shell ) instead of `` to get embedded libperl's ccopts
+    - dmaengine: Revert "dmaengine: shdma: Fix runtime PM imbalance on error"
+    - KVM: avoid NULL pointer dereference in kvm_dirty_ring_push
+    - Drivers: hv: vmbus: Replace smp_store_mb() with virt_store_mb()
+    - powerpc: Fix virt_addr_valid() for 64-bit Book3E & 32-bit
+    - Revert "powerpc: Set max_mapnr correctly"
+    - x86/bug: Prevent shadowing in __WARN_FLAGS
+    - objtool: Fix SLS validation for kcov tail-call replacement
+    - sched/core: Fix forceidle balancing
+    - sched: Teach the forced-newidle balancer about CPU affinity limitation.
+    - x86,static_call: Fix __static_call_return0 for i386
+    - x86/extable: Prefer local labels in .set directives
+    - irqchip/gic-v4: Wait for GICR_VPENDBASER.Dirty to clear before descheduling
+    - powerpc/64: Fix build failure with allyesconfig in book3s_64_entry.S
+    - irqchip/gic, gic-v3: Prevent GSI to SGI translations
+    - mm/sparsemem: fix 'mem_section' will never be NULL gcc 12 warning
+    - static_call: Don't make __static_call_return0 static
+    - io_uring: move read/write file prep state into actual opcode handler
+    - io_uring: propagate issue_flags state down to file assignment
+    - io_uring: defer file assignment
+    - io_uring: drop the old style inflight file tracking
+    - Linux 5.17.3
+
+  * Jammy update: v5.17.2 upstream stable release Edit (LP: #1968984)
+    - Revert "swiotlb: rework "fix info leak with DMA_FROM_DEVICE""
+    - USB: serial: pl2303: add IBM device IDs
+    - dt-bindings: usb: hcd: correct usb-device path
+    - USB: serial: pl2303: fix GS type detection
+    - USB: serial: simple: add Nokia phone driver
+    - mm: kfence: fix missing objcg housekeeping for SLAB
+    - locking/lockdep: Avoid potential access of invalid memory in lock_class
+    - drm/amdgpu: move PX checking into amdgpu_device_ip_early_init
+    - drm/amdgpu: only check for _PR3 on dGPUs
+    - iommu/iova: Improve 32-bit free space estimate
+    - block: flush plug based on hardware and software queue order
+    - block: ensure plug merging checks the correct queue at least once
+    - usb: typec: tipd: Forward plug orientation to typec subsystem
+    - USB: usb-storage: Fix use of bitfields for hardware data in ene_ub6250.c
+    - xhci: fix garbage USBSTS being logged in some cases
+    - xhci: fix runtime PM imbalance in USB2 resume
+    - xhci: make xhci_handshake timeout for xhci_reset() adjustable
+    - xhci: fix uninitialized string returned by xhci_decode_ctrl_ctx()
+    - mei: me: disable driver on the ign firmware
+    - mei: me: add Alder Lake N device id.
+    - mei: avoid iterator usage outside of list_for_each_entry
+    - bus: mhi: pci_generic: Add mru_default for Quectel EM1xx series
+    - bus: mhi: Fix pm_state conversion to string
+    - bus: mhi: Fix MHI DMA structure endianness
+    - docs: sphinx/requirements: Limit jinja2<3.1
+    - coresight: Fix TRCCONFIGR.QE sysfs interface
+    - coresight: syscfg: Fix memleak on registration failure in
+      cscfg_create_device
+    - dt-bindings: iio: adc: zynqmp_ams: Add clock entry
+    - iio: adc: xilinx-ams: Fix single channel switching sequence
+    - iio: accel: mma8452: use the correct logic to get mma8452_data
+    - iio: adc: aspeed: Add divider flag to fix incorrect voltage reading.
+    - iio: imu: st_lsm6dsx: use dev_to_iio_dev() to get iio_dev struct
+    - iio: afe: rescale: use s64 for temporary scale calculations
+    - iio: adc: xilinx-ams: Fixed missing PS channels
+    - iio: adc: xilinx-ams: Fixed wrong sequencer register settings
+    - iio: inkern: apply consumer scale on IIO_VAL_INT cases
+    - iio: inkern: apply consumer scale when no channel scale is available
+    - iio: inkern: make a best effort on offset calculation
+    - greybus: svc: fix an error handling bug in gb_svc_hello()
+    - clk: rockchip: re-add rational best approximation algorithm to the
+      fractional divider
+    - clk: uniphier: Fix fixed-rate initialization
+    - ptrace: Check PTRACE_O_SUSPEND_SECCOMP permission on PTRACE_SEIZE
+    - cifs: truncate the inode and mapping when we simulate fcollapse
+    - cifs: fix handlecache and multiuser
+    - cifs: we do not need a spinlock around the tree access during umount
+    - KEYS: fix length validation in keyctl_pkey_params_get_2()
+    - KEYS: asymmetric: enforce that sig algo matches key algo
+    - KEYS: asymmetric: properly validate hash_algo and encoding
+    - Documentation: add link to stable release candidate tree
+    - Documentation: update stable tree link
+    - firmware: stratix10-svc: add missing callback parameter on RSU
+    - firmware: sysfb: fix platform-device leak in error path
+    - HID: intel-ish-hid: Use dma_alloc_coherent for firmware update
+    - SUNRPC: avoid race between mod_timer() and del_timer_sync()
+    - SUNRPC: Do not dereference non-socket transports in sysfs
+    - NFS: NFSv2/v3 clients should never be setting NFS_CAP_XATTR
+    - NFSD: prevent underflow in nfssvc_decode_writeargs()
+    - NFSD: prevent integer overflow on 32 bit systems
+    - f2fs: fix to unlock page correctly in error path of is_alive()
+    - f2fs: quota: fix loop condition at f2fs_quota_sync()
+    - f2fs: fix to do sanity check on .cp_pack_total_block_count
+    - remoteproc: Fix count check in rproc_coredump_write()
+    - mm/mlock: fix two bugs in user_shm_lock()
+    - pinctrl: ingenic: Fix regmap on X series SoCs
+    - pinctrl: samsung: drop pin banks references on error paths
+    - net: bnxt_ptp: fix compilation error
+    - spi: mxic: Fix the transmit path
+    - mtd: spi-nor: Skip erase logic when SPI_NOR_NO_ERASE is set
+    - mtd: rawnand: protect access to rawnand devices while in suspend
+    - can: ems_usb: ems_usb_start_xmit(): fix double dev_kfree_skb() in error path
+    - can: m_can: m_can_tx_handler(): fix use after free of skb
+    - can: usb_8dev: usb_8dev_start_xmit(): fix double dev_kfree_skb() in error
+      path
+    - jffs2: fix use-after-free in jffs2_clear_xattr_subsystem
+    - jffs2: fix memory leak in jffs2_do_mount_fs
+    - jffs2: fix memory leak in jffs2_scan_medium
+    - mm: fs: fix lru_cache_disabled race in bh_lru
+    - mm: don't skip swap entry even if zap_details specified
+    - mm/pages_alloc.c: don't create ZONE_MOVABLE beyond the end of a node
+    - mm: invalidate hwpoison page cache page in fault path
+    - mempolicy: mbind_range() set_policy() after vma_merge()
+    - scsi: core: sd: Add silence_suspend flag to suppress some PM messages
+    - scsi: ufs: Fix runtime PM messages never-ending cycle
+    - scsi: scsi_transport_fc: Fix FPIN Link Integrity statistics counters
+    - scsi: libsas: Fix sas_ata_qc_issue() handling of NCQ NON DATA commands
+    - qed: display VF trust config
+    - qed: validate and restrict untrusted VFs vlan promisc mode
+    - riscv: dts: canaan: Fix SPI3 bus width
+    - riscv: Fix fill_callchain return value
+    - riscv: Increase stack size under KASAN
+    - RISC-V: Declare per cpu boot data as static
+    - Revert "Input: clear BTN_RIGHT/MIDDLE on buttonpads"
+    - cifs: do not skip link targets when an I/O fails
+    - cifs: fix incorrect use of list iterator after the loop
+    - cifs: prevent bad output lengths in smb2_ioctl_query_info()
+    - cifs: fix NULL ptr dereference in smb2_ioctl_query_info()
+    - ALSA: cs4236: fix an incorrect NULL check on list iterator
+    - ALSA: hda: Avoid unsol event during RPM suspending
+    - ALSA: pcm: Fix potential AB/BA lock with buffer_mutex and mmap_lock
+    - ALSA: hda/realtek: Fix audio regression on Mi Notebook Pro 2020
+    - rtc: mc146818-lib: fix locking in mc146818_set_time
+    - rtc: pl031: fix rtc features null pointer dereference
+    - io_uring: ensure that fsnotify is always called
+    - ocfs2: fix crash when mount with quota enabled
+    - drm/simpledrm: Add "panel orientation" property on non-upright mounted LCD
+      panels
+    - mm: madvise: skip unmapped vma holes passed to process_madvise
+    - mm: madvise: return correct bytes advised with process_madvise
+    - Revert "mm: madvise: skip unmapped vma holes passed to process_madvise"
+    - mm,hwpoison: unmap poisoned page before invalidation
+    - mm: only re-generate demotion targets when a numa node changes its N_CPU
+      state
+    - mm/kmemleak: reset tag when compare object pointer
+    - dm stats: fix too short end duration_ns when using precise_timestamps
+    - dm: fix use-after-free in dm_cleanup_zoned_dev()
+    - dm: interlock pending dm_io and dm_wait_for_bios_completion
+    - dm: fix double accounting of flush with data
+    - dm integrity: set journal entry unused when shrinking device
+    - tracing: Have trace event string test handle zero length strings
+    - drbd: fix potential silent data corruption
+    - can: isotp: sanitize CAN ID checks in isotp_bind()
+    - PCI: fu740: Force 2.5GT/s for initial device probe
+    - arm64: signal: nofpsimd: Do not allocate fp/simd context when not available
+    - arm64: Do not defer reserve_crashkernel() for platforms with no DMA memory
+      zones
+    - arm64: dts: qcom: sm8250: Fix MSI IRQ for PCIe1 and PCIe2
+    - arm64: dts: ti: k3-am65: Fix gic-v3 compatible regs
+    - arm64: dts: ti: k3-j721e: Fix gic-v3 compatible regs
+    - arm64: dts: ti: k3-j7200: Fix gic-v3 compatible regs
+    - arm64: dts: ti: k3-am64: Fix gic-v3 compatible regs
+    - arm64: dts: ti: k3-j721s2: Fix gic-v3 compatible regs
+    - ASoC: SOF: Intel: Fix NULL ptr dereference when ENOMEM
+    - mmc: core: use sysfs_emit() instead of sprintf()
+    - Revert "ACPI: Pass the same capabilities to the _OSC regardless of the query
+      flag"
+    - ACPI: properties: Consistently return -ENOENT if there are no more
+      references
+    - coredump: Also dump first pages of non-executable ELF libraries
+    - ext4: fix ext4_fc_stats trace point
+    - ext4: fix fs corruption when tring to remove a non-empty directory with IO
+      error
+    - ext4: make mb_optimize_scan option work with set/unset mount cmd
+    - ext4: make mb_optimize_scan performance mount option work with extents
+    - samples/landlock: Fix path_list memory leak
+    - landlock: Use square brackets around "landlock-ruleset"
+    - mailbox: tegra-hsp: Flush whole channel
+    - btrfs: zoned: put block group after final usage
+    - block: fix rq-qos breakage from skipping rq_qos_done_bio()
+    - block: limit request dispatch loop duration
+    - block: don't merge across cgroup boundaries if blkcg is enabled
+    - drm/edid: check basic audio support on CEA extension block
+    - fbdev: Hot-unplug firmware fb devices on forced removal
+    - video: fbdev: sm712fb: Fix crash in smtcfb_read()
+    - video: fbdev: atari: Atari 2 bpp (STe) palette bugfix
+    - rfkill: make new event layout opt-in
+    - ARM: dts: at91: sama7g5: Remove unused properties in i2c nodes
+    - ARM: dts: at91: sama5d2: Fix PMERRLOC resource size
+    - ARM: dts: exynos: fix UART3 pins configuration in Exynos5250
+    - ARM: dts: exynos: add missing HDMI supplies on SMDK5250
+    - ARM: dts: exynos: add missing HDMI supplies on SMDK5420
+    - mgag200 fix memmapsl configuration in GCTL6 register
+    - carl9170: fix missing bit-wise or operator for tx_params
+    - pstore: Don't use semaphores in always-atomic-context code
+    - thermal: int340x: Increase bitmap size
+    - lib/raid6/test: fix multiple definition linking error
+    - exec: Force single empty string when argv is empty
+    - crypto: rsa-pkcs1pad - only allow with rsa
+    - crypto: rsa-pkcs1pad - correctly get hash from source scatterlist
+    - crypto: rsa-pkcs1pad - restore signature length check
+    - crypto: rsa-pkcs1pad - fix buffer overread in pkcs1pad_verify_complete()
+    - bcache: fixup multiple threads crash
+    - PM: domains: Fix sleep-in-atomic bug caused by genpd_debug_remove()
+    - DEC: Limit PMAX memory probing to R3k systems
+    - media: gpio-ir-tx: fix transmit with long spaces on Orange Pi PC
+    - media: omap3isp: Use struct_group() for memcpy() region
+    - media: venus: vdec: fixed possible memory leak issue
+    - media: venus: hfi_cmds: List HDR10 property as unsupported for v1 and v3
+    - media: venus: venc: Fix h264 8x8 transform control
+    - media: davinci: vpif: fix unbalanced runtime PM get
+    - media: davinci: vpif: fix unbalanced runtime PM enable
+    - media: davinci: vpif: fix use-after-free on driver unbind
+    - mips: Always permit to build u-boot images
+    - btrfs: zoned: mark relocation as writing
+    - btrfs: extend locking to all space_info members accesses
+    - btrfs: verify the tranisd of the to-be-written dirty extent buffer
+    - xtensa: define update_mmu_tlb function
+    - xtensa: fix stop_machine_cpuslocked call in patch_text
+    - xtensa: fix xtensa_wsr always writing 0
+    - KVM: s390x: fix SCK locking
+    - drm/syncobj: flatten dma_fence_chains on transfer
+    - drm/nouveau/backlight: Fix LVDS backlight detection on some laptops
+    - drm/nouveau/backlight: Just set all backlight types as RAW
+    - drm/fb-helper: Mark screen buffers in system memory with FBINFO_VIRTFB
+    - brcmfmac: firmware: Allocate space for default boardrev in nvram
+    - brcmfmac: pcie: Release firmwares in the brcmf_pcie_setup error path
+    - brcmfmac: pcie: Declare missing firmware files in pcie.c
+    - brcmfmac: pcie: Replace brcmf_pcie_copy_mem_todev with memcpy_toio
+    - brcmfmac: pcie: Fix crashes due to early IRQs
+    - drm/i915/opregion: check port number bounds for SWSCI display power state
+    - drm/i915/gem: add missing boundary check in vm_access
+    - PCI: imx6: Allow to probe when dw_pcie_wait_for_link() fails
+    - PCI: pciehp: Clear cmd_busy bit in polling mode
+    - PCI: xgene: Revert "PCI: xgene: Use inbound resources for setup"
+    - PCI: xgene: Revert "PCI: xgene: Fix IB window setup"
+    - regulator: qcom_smd: fix for_each_child.cocci warnings
+    - selinux: access superblock_security_struct in LSM blob way
+    - selinux: check return value of sel_make_avc_files
+    - crypto: ccp - Ensure psp_ret is always init'd in
+      __sev_platform_init_locked()
+    - crypto: qat - fix a signedness bug in get_service_enabled()
+    - hwrng: cavium - HW_RANDOM_CAVIUM should depend on ARCH_THUNDER
+    - crypto: sun8i-ss - really disable hash on A80
+    - crypto: kdf - Select hmac in addition to sha256
+    - crypto: qat - fix access to PFVF interrupt registers for GEN4
+    - crypto: authenc - Fix sleep in atomic context in decrypt_tail
+    - crypto: octeontx2 - select CONFIG_NET_DEVLINK
+    - crypto: mxs-dcp - Fix scatterlist processing
+    - selinux: Fix selinux_sb_mnt_opts_compat()
+    - thermal: int340x: Check for NULL after calling kmemdup()
+    - crypto: octeontx2 - remove CONFIG_DM_CRYPT check
+    - spi: tegra114: Add missing IRQ check in tegra_spi_probe
+    - spi: tegra210-quad: Fix missin IRQ check in tegra_qspi_probe
+    - perf: MARVELL_CN10K_TAD_PMU should depend on ARCH_THUNDER
+    - selftests/sgx: Fix NULL-pointer-dereference upon early test failure
+    - selftests/sgx: Do not attempt enclave build without valid enclave
+    - selftests/sgx: Ensure enclave data available during debug print
+    - stack: Constrain and fix stack offset randomization with Clang builds
+    - arm64/mm: avoid fixmap race condition when create pud mapping
+    - security: add sctp_assoc_established hook
+    - blk-cgroup: set blkg iostat after percpu stat aggregation
+    - selftests/x86: Add validity check and allow field splitting
+    - selftests/sgx: Treat CC as one argument
+    - crypto: rockchip - ECB does not need IV
+    - block: update io_ticks when io hang
+    - audit: log AUDIT_TIME_* records only from rules
+    - EVM: fix the evm= __setup handler return value
+    - crypto: ccree - don't attempt 0 len DMA mappings
+    - crypto: hisilicon/sec - fix the aead software fallback for engine
+    - spi: pxa2xx-pci: Balance reference count for PCI DMA device
+    - hwmon: (pmbus) Add mutex to regulator ops
+    - hwmon: (sch56xx-common) Replace WDOG_ACTIVE with WDOG_HW_RUNNING
+    - nvme: cleanup __nvme_check_ids
+    - nvme: fix the check for duplicate unique identifiers
+    - block: don't delete queue kobject before its children
+    - PM: hibernate: fix __setup handler error handling
+    - PM: suspend: fix return value of __setup handler
+    - spi: spi-zynqmp-gqspi: Handle error for dma_set_mask
+    - hwrng: atmel - disable trng on failure path
+    - crypto: sun8i-ss - call finalize with bh disabled
+    - crypto: sun8i-ce - call finalize with bh disabled
+    - crypto: amlogic - call finalize with bh disabled
+    - crypto: gemini - call finalize with bh disabled
+    - crypto: vmx - add missing dependencies
+    - clocksource/drivers/timer-ti-dm: Fix regression from errata i940 fix
+    - clocksource/drivers/exynos_mct: Handle DTS with higher number of interrupts
+    - clocksource/drivers/timer-microchip-pit64b: Use notrace
+    - clocksource/drivers/timer-of: Check return value of of_iomap in
+      timer_of_base_init()
+    - arm64: prevent instrumentation of bp hardening callbacks
+    - perf/arm-cmn: Hide XP PUB events for CMN-600
+    - perf/arm-cmn: Update watchpoint format
+    - KEYS: trusted: Fix trusted key backends when building as module
+    - KEYS: trusted: Avoid calling null function trusted_key_exit
+    - ACPI: APEI: fix return value of __setup handlers
+    - crypto: ccp - ccp_dmaengine_unregister release dma channels
+    - crypto: ccree - Fix use after free in cc_cipher_exit()
+    - crypto: qat - fix initialization of pfvf cap_msg structures
+    - crypto: qat - fix initialization of pfvf rts_map_msg structures
+    - hwrng: nomadik - Change clk_disable to clk_disable_unprepare
+    - hwmon: (pmbus) Add Vin unit off handling
+    - clocksource: acpi_pm: fix return value of __setup handler
+    - io_uring: don't check unrelated req->open.how in accept request
+    - io_uring: terminate manual loop iterator loop correctly for non-vecs
+    - watch_queue: Fix NULL dereference in error cleanup
+    - watch_queue: Actually free the watch
+    - f2fs: fix to enable ATGC correctly via gc_idle sysfs interface
+    - sched/debug: Remove mpol_get/put and task_lock/unlock from sched_show_numa
+    - sched/core: Export pelt_thermal_tp
+    - sched/sugov: Ignore 'busy' filter when rq is capped by uclamp_max
+    - sched/uclamp: Fix iowait boost escaping uclamp restriction
+    - rseq: Remove broken uapi field layout on 32-bit little endian
+    - perf/core: Fix address filter parser for multiple filters
+    - perf/x86/intel/pt: Fix address filter config for 32-bit kernel
+    - sched/fair: Improve consistency of allowed NUMA balance calculations
+    - f2fs: fix missing free nid in f2fs_handle_failed_inode
+    - ext4: fix remount with 'abort' option
+    - nfsd: more robust allocation failure handling in nfsd_file_cache_init
+    - sched/cpuacct: Fix charge percpu cpuusage
+    - sched/rt: Plug rt_mutex_setprio() vs push_rt_task() race
+    - f2fs: fix to avoid potential deadlock
+    - btrfs: fix unexpected error path when reflinking an inline extent
+    - iomap: Fix iomap_invalidatepage tracepoint
+    - fs: erofs: add sanity check for kobject in erofs_unregister_sysfs
+    - f2fs: fix compressed file start atomic write may cause data corruption
+    - cifs: use a different reconnect helper for non-cifsd threads
+    - selftests, x86: fix how check_cc.sh is being invoked
+    - drivers/base/memory: add memory block to memory group after registration
+      succeeded
+    - kunit: make kunit_test_timeout compatible with comment
+    - pinctrl: samsung: Remove EINT handler for Exynos850 ALIVE and CMGP gpios
+    - media: staging: media: zoran: fix usage of vb2_dma_contig_set_max_seg_size
+    - media: camss: csid-170: fix non-10bit formats
+    - media: camss: csid-170: don't enable unused irqs
+    - media: camss: csid-170: set the right HALT_CMD when disabled
+    - media: camss: vfe-170: fix "VFE halt timeout" error
+    - media: staging: media: imx: imx7-mipi-csis: Make subdev name unique
+    - media: v4l2-mem2mem: Apply DST_QUEUE_OFF_BASE on MMAP buffers across ioctls
+    - media: mtk-vcodec: potential dereference of null pointer
+    - media: imx: imx8mq-mipi-csi2: remove wrong irq config write operation
+    - media: imx: imx8mq-mipi_csi2: fix system resume
+    - media: bttv: fix WARNING regression on tunerless devices
+    - media: atmel: atmel-sama7g5-isc: fix ispck leftover
+    - ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively
+    - ASoC: codecs: Check for error pointer after calling devm_regmap_init_mmio
+    - ASoC: xilinx: xlnx_formatter_pcm: Handle sysclk setting
+    - ASoC: simple-card-utils: Set sysclk on all components
+    - memory: tegra20-emc: Correct memory device mask
+    - media: coda: Fix missing put_device() call in coda_get_vdoa_data
+    - media: meson: vdec: potential dereference of null pointer
+    - media: hantro: Fix overfill bottom register field name
+    - media: ov6650: Fix set format try processing path
+    - media: v4l: Avoid unaligned access warnings when printing 4cc modifiers
+    - media: ov5648: Don't pack controls struct
+    - media: ov2740: identify module after subdev initialisation
+    - media: aspeed: Correct value for h-total-pixels
+    - video: fbdev: matroxfb: set maxvram of vbG200eW to the same as vbG200 to
+      avoid black screen
+    - video: fbdev: controlfb: Fix COMPILE_TEST build
+    - video: fbdev: smscufx: Fix null-ptr-deref in ufx_usb_probe()
+    - video: fbdev: atmel_lcdfb: fix an error code in atmel_lcdfb_probe()
+    - video: fbdev: fbcvt.c: fix printing in fb_cvt_print_name()
+    - ARM: dts: Fix OpenBMC flash layout label addresses
+    - ASoC: max98927: add missing header file
+    - arm64: dts: qcom: sc7280: Fix gmu unit address
+    - firmware: qcom: scm: Remove reassignment to desc following initializer
+    - ARM: dts: qcom: ipq4019: fix sleep clock
+    - soc: qcom: rpmpd: Check for null return of devm_kcalloc
+    - soc: qcom: ocmem: Fix missing put_device() call in of_get_ocmem
+    - soc: qcom: aoss: Fix missing put_device call in qmp_get
+    - soc: qcom: aoss: remove spurious IRQF_ONESHOT flags
+    - arm64: dts: qcom: sdm845: fix microphone bias properties and values
+    - arm64: dts: qcom: sm8250: fix PCIe bindings to follow schema
+    - arm64: dts: qcom: msm8916-j5: Fix typo
+    - arm64: dts: broadcom: bcm4908: use proper TWD binding
+    - arm64: dts: qcom: sm8150: Correct TCS configuration for apps rsc
+    - arm64: dts: qcom: sm8350: Correct TCS configuration for apps rsc
+    - arm64: dts: qcom: sm8450: Update cpuidle states parameters
+    - arm64: dts: qcom: msm8994: Provide missing "xo_board" and "sleep_clk" to GCC
+    - arm64: dts: qcom: ipq6018: fix usb reference period
+    - firmware: ti_sci: Fix compilation failure when CONFIG_TI_SCI_PROTOCOL is not
+      defined
+    - soc: ti: wkup_m3_ipc: Fix IRQ check in wkup_m3_ipc_probe
+    - cpuidle: qcom-spm: Check if any CPU is managed by SPM
+    - ARM: dts: sun8i: v3s: Move the csi1 block to follow address order
+    - ARM: dts: stm32: fix AV96 board SAI2 pin muxing on stm32mp15
+    - vsprintf: Fix potential unaligned access
+    - ARM: dts: qcom: sdx55: Fix the address used for PCIe EP local addr space
+    - ARM: dts: imx: Add missing LVDS decoder on M53Menlo
+    - media: mexon-ge2d: fixup frames size in registers
+    - media: video/hdmi: handle short reads of hdmi info frame.
+    - media: ti-vpe: cal: Fix a NULL pointer dereference in
+      cal_ctx_v4l2_init_formats()
+    - media: em28xx: initialize refcount before kref_get
+    - media: uapi: Init VP9 stateless decode params
+    - media: usb: go7007: s2250-board: fix leak in probe()
+    - media: cedrus: H265: Fix neighbour info buffer size
+    - media: cedrus: h264: Fix neighbour info buffer size
+    - arm64: dts: ti: k3-j721s2-mcu-wakeup: Fix the interrupt-parent for
+      wkup_gpioX instances
+    - ASoC: codecs: rx-macro: fix accessing compander for aux
+    - ASoC: codecs: rx-macro: fix accessing array out of bounds for enum type
+    - ASoC: codecs: va-macro: fix accessing array out of bounds for enum type
+    - ASoC: codecs: wc938x: fix accessing array out of bounds for enum type
+    - ASoC: codecs: wcd938x: fix kcontrol max values
+    - ASoC: codecs: wcd934x: fix kcontrol max values
+    - ASoC: codecs: wcd934x: fix return value of wcd934x_rx_hph_mode_put
+    - media: v4l2-core: Initialize h264 scaling matrix
+    - media: hantro: sunxi: Fix VP9 steps
+    - media: ov5640: Fix set format, v4l2_mbus_pixelcode not updated
+    - selftests: vm: remove dependecy from internal kernel macros
+    - selftests/lkdtm: Add UBSAN config
+    - vsprintf: Fix %pK with kptr_restrict == 0
+    - uaccess: fix nios2 and microblaze get_user_8()
+    - ASoC: rt5663: check the return value of devm_kzalloc() in rt5663_parse_dp()
+    - ASoC: acp: check the return value of devm_kzalloc() in
+      acp_legacy_dai_links_create()
+    - soc: mediatek: pm-domains: Add wakeup capacity support in power domain
+    - mmc: sdhci_am654: Fix the driver data of AM64 SoC
+    - ASoC: ti: davinci-i2s: Add check for clk_enable()
+    - ALSA: spi: Add check for clk_enable()
+    - arm64: dts: ns2: Fix spi-cpol and spi-cpha property
+    - arm64: dts: broadcom: Fix sata nodename
+    - printk: fix return value of printk.devkmsg __setup handler
+    - ASoC: mxs-saif: Handle errors for clk_enable
+    - ASoC: atmel_ssc_dai: Handle errors for clk_enable
+    - ASoC: dwc-i2s: Handle errors for clk_enable
+    - ASoC: soc-compress: prevent the potentially use of null pointer
+    - media: i2c: Fix pixel array positions in ov8865
+    - memory: emif: Add check for setup_interrupts
+    - memory: emif: check the pointer temp in get_device_details()
+    - ALSA: firewire-lib: fix uninitialized flag for AV/C deferred transaction
+    - arm64: dts: rockchip: Fix SDIO regulator supply properties on rk3399-firefly
+    - m68k: coldfire/device.c: only build for MCF_EDMA when h/w macros are defined
+    - media: stk1160: If start stream fails, return buffers with
+      VB2_BUF_STATE_QUEUED
+    - media: vidtv: Check for null return of vzalloc
+    - ASoC: cs35l41: Fix GPIO2 configuration
+    - ASoC: cs35l41: Fix max number of TX channels
+    - ASoC: atmel: Add missing of_node_put() in at91sam9g20ek_audio_probe
+    - ASoC: wm8350: Handle error for wm8350_register_irq
+    - ASoC: fsi: Add check for clk_enable
+    - video: fbdev: omapfb: Add missing of_node_put() in dvic_probe_of
+    - media: saa7134: fix incorrect use to determine if list is empty
+    - ivtv: fix incorrect device_caps for ivtvfb
+    - ASoC: atmel: Fix error handling in snd_proto_probe
+    - ASoC: rockchip: i2s: Fix missing clk_disable_unprepare() in
+      rockchip_i2s_probe
+    - ASoC: SOF: Add missing of_node_put() in imx8m_probe
+    - ASoC: mediatek: mt8192-mt6359: Fix error handling in mt8192_mt6359_dev_probe
+    - ASoC: rk817: Fix missing clk_disable_unprepare() in rk817_platform_probe
+    - ASoC: dmaengine: do not use a NULL prepare_slave_config() callback
+    - ASoC: mxs: Fix error handling in mxs_sgtl5000_probe
+    - ASoC: fsl_spdif: Disable TX clock when stop
+    - ASoC: imx-es8328: Fix error return code in imx_es8328_probe()
+    - ASoC: SOF: Intel: enable DMI L1 for playback streams
+    - ASoC: msm8916-wcd-digital: Fix missing clk_disable_unprepare() in
+      msm8916_wcd_digital_probe
+    - mmc: davinci_mmc: Handle error for clk_enable
+    - rtla/osnoise: Fix osnoise hist stop tracing message
+    - ASoC: rockchip: Fix PM usage reference of rockchip_i2s_tdm_resume
+    - ASoC: atmel: Fix error handling in sam9x5_wm8731_driver_probe
+    - ASoC: msm8916-wcd-analog: Fix error handling in pm8916_wcd_analog_spmi_probe
+    - ASoC: mediatek: mt8195: Fix error handling in
+      mt8195_mt6359_rt1019_rt5682_dev_probe
+    - ASoC: codecs: wcd934x: Add missing of_node_put() in wcd934x_codec_parse_data
+    - ASoC: amd: Fix reference to PCM buffer address
+    - ARM: configs: multi_v5_defconfig: re-enable CONFIG_V4L_PLATFORM_DRIVERS
+    - ARM: configs: multi_v5_defconfig: re-enable DRM_PANEL and FB_xxx
+    - drm/bridge: sn65dsi83: Fix an error handling path in sn65dsi83_probe()
+    - drm/meson: osd_afbcd: Add an exit callback to struct meson_afbcd_ops
+    - drm/meson: Fix error handling when afbcd.ops->init fails
+    - drm/bridge: Fix free wrong object in sii8620_init_rcp_input_dev
+    - drm/bridge: Add missing pm_runtime_disable() in __dw_mipi_dsi_probe
+    - drm/bridge: nwl-dsi: Fix PM disable depth imbalance in nwl_dsi_probe
+    - drm: bridge: adv7511: Fix ADV7535 HPD enablement
+    - ath11k: add missing of_node_put() to avoid leak
+    - ath10k: fix memory overwrite of the WoWLAN wakeup packet pattern
+    - drm/v3d/v3d_drv: Check for error num after setting mask
+    - Bluetooth: hci_sync: unlock on error in hci_inquiry_result_with_rssi_evt()
+    - ath11k: free peer for station when disconnect from AP for QCA6390/WCN6855
+    - drm/panfrost: Check for error num after setting mask
+    - bpftool: Fix error check when calling hashmap__new()
+    - libbpf: Fix possible NULL pointer dereference when destroying skeleton
+    - bpftool: Only set obj->skeleton on complete success
+    - ath11k: fix error code in ath11k_qmi_assign_target_mem_chunk()
+    - udmabuf: validate ubuf->pagecount
+    - bpf: Fix UAF due to race between btf_try_get_module and load_module
+    - drm/selftests/test-drm_dp_mst_helper: Fix memory leak in
+      sideband_msg_req_encode_decode
+    - drm/locking: fix drm_modeset_acquire_ctx kernel-doc
+    - selftests: bpf: Fix bind on used port
+    - Bluetooth: btintel: Fix WBS setting for Intel legacy ROM products
+    - Bluetooth: hci_serdev: call init_rwsem() before p->open()
+    - Bluetooth: mt7921s: fix firmware coredump retrieve
+    - Bluetooth: mt7921s: fix bus hang with wrong privilege
+    - Bluetooth: btmtksdio: refactor btmtksdio_runtime_[suspend|resume]()
+    - Bluetooth: mt7921s: fix btmtksdio_[drv|fw]_pmctrl()
+    - Bluetooth: btmtksdio: mask out interrupt status
+    - mtd: onenand: Check for error irq
+    - mtd: rawnand: gpmi: fix controller timings setting
+    - selftests, xsk: Fix rx_full stats test
+    - drm/edid: Don't clear formats if using deep color
+    - drm/edid: Split deep color modes between RGB and YUV444
+    - ionic: fix type complaint in ionic_dev_cmd_clean()
+    - ionic: start watchdog after all is setup
+    - ionic: Don't send reset commands if FW isn't running
+    - ionic: fix up printing of timeout error
+    - ionic: Correctly print AQ errors if completions aren't received
+    - net: dsa: Move VLAN filtering syncing out of dsa_switch_bridge_leave
+    - net: dsa: Avoid cross-chip syncing of VLAN filtering
+    - Bluetooth: hci_event: Fix HCI_EV_VENDOR max_len
+    - drm/nouveau/acr: Fix undefined behavior in nvkm_acr_hsfw_load_bl()
+    - drm/amd/display: Call dc_stream_release for remove link enc assignment
+    - drm/amd/display: Fix a NULL pointer dereference in
+      amdgpu_dm_connector_add_common_modes()
+    - drm/amd/pm: return -ENOTSUPP if there is no get_dpm_ultimate_freq function
+    - net: phy: at803x: move page selection fix to config_init
+    - selftests/bpf/test_xdp_redirect_multi: use temp netns for testing
+    - ath9k_htc: fix uninit value bugs
+    - ath11k: set WMI_PEER_40MHZ while peer assoc for 6 GHz
+    - RDMA/core: Set MR type in ib_reg_user_mr
+    - KVM: PPC: Fix vmx/vsx mixup in mmio emulation
+    - selftests/net: timestamping: Fix bind_phc check
+    - rtw88: check for validity before using a pointer
+    - rtw88: fix idle mode flow for hw scan
+    - rtw88: fix memory overrun and memory leak during hw_scan
+    - drm/bridge: lt9611: Fix an error handling path in lt9611_probe()
+    - i40e: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
+    - i40e: respect metadata on XSK Rx to skb
+    - ice: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
+    - ice: respect metadata on XSK Rx to skb
+    - igc: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
+    - ixgbe: pass bi->xdp to ixgbe_construct_skb_zc() directly
+    - ixgbe: don't reserve excessive XDP_PACKET_HEADROOM on XSK Rx to skb
+    - ixgbe: respect metadata on XSK Rx to skb
+    - power: reset: gemini-poweroff: Fix IRQ check in gemini_poweroff_probe
+    - ray_cs: Check ioremap return value
+    - powerpc: dts: t1040rdb: fix ports names for Seville Ethernet switch
+    - KVM: PPC: Book3S HV: Check return value of kvmppc_radix_init
+    - powerpc/perf: Don't use perf_hw_context for trace IMC PMU
+    - mt76: connac: fix sta_rec_wtbl tag len
+    - mt76: mt7915: use proper aid value in mt7915_mcu_wtbl_generic_tlv in sta
+      mode
+    - mt76: mt7915: use proper aid value in mt7915_mcu_sta_basic_tlv
+    - mt76: mt76_connac: fix MCU_CE_CMD_SET_ROC definition error
+    - mt76: mt7921: set EDCA parameters with the MCU CE command
+    - mt76: mt7921: do not always disable fw runtime-pm
+    - mt76: mt7921: fix a leftover race in runtime-pm
+    - mt76: mt7615: fix a leftover race in runtime-pm
+    - mt76: mt7915: fix ht mcs in mt7915_mac_add_txs_skb()
+    - mt76: mt7921: fix ht mcs in mt7921_mac_add_txs_skb()
+    - mt76: mt7921s: fix mt7921s_mcu_[fw|drv]_pmctrl
+    - mt76: mt7921e: fix possible probe failure after reboot
+    - mt76: mt7603: check sta_rates pointer in mt7603_sta_rate_tbl_update
+    - mt76: mt7615: check sta_rates pointer in mt7615_sta_rate_tbl_update
+    - mt76: mt7915: fix possible memory leak in mt7915_mcu_add_sta
+    - mt76: mt7921s: fix a possible memory leak in mt7921_load_patch
+    - mt76: mt7915: fix mcs_map in mt7915_mcu_set_sta_he_mcs()
+    - mt76: mt7915: fix the nss setting in bitrates
+    - ptp: unregister virtual clocks when unregistering physical clock.
+    - net: dsa: mv88e6xxx: Enable port policy support on 6097
+    - bpf: Fix a btf decl_tag bug when tagging a function
+    - mac80211: limit bandwidth in HE capabilities
+    - scripts/dtc: Call pkg-config POSIXly correct
+    - livepatch: Fix build failure on 32 bits processors
+    - net: asix: add proper error handling of usb read errors
+    - i2c: bcm2835: Fix the error handling in 'bcm2835_i2c_probe()'
+    - mtd: mchp23k256: Add SPI ID table
+    - mtd: mchp48l640: Add SPI ID table
+    - selftests/bpf: Extract syscall wrapper
+    - selftests/bpf: Use "__se_" prefix on architectures without syscall wrapper
+    - igc: avoid kernel warning when changing RX ring parameters
+    - igb: refactor XDP registration
+    - drm/amdgpu: Don't offset by 2 in FRU EEPROM
+    - PCI: aardvark: Fix reading MSI interrupt number
+    - PCI: aardvark: Fix reading PCI_EXP_RTSTA_PME bit on emulated bridge
+    - RDMA/rxe: Check the last packet by RXE_END_MASK
+    - libbpf: Fix signedness bug in btf_dump_array_data()
+    - libbpf: Fix riscv register names
+    - cxl/core: Fix cxl_probe_component_regs() error message
+    - tools/testing/cxl: Fix root port to host bridge assignment
+    - cxl/regs: Fix size of CXL Capability Header Register
+    - Netvsc: Call hv_unmap_memory() in the netvsc_device_remove()
+    - net:enetc: allocate CBD ring data memory using DMA coherent methods
+    - libbpf: Fix compilation warning due to mismatched printf format
+    - rtw88: fix use after free in rtw_hw_scan_update_probe_req()
+    - drm/bridge: dw-hdmi: use safe format when first in bridge chain
+    - power: supply: ab8500: Swap max and overvoltage
+    - libbpf: Fix libbpf.map inheritance chain for LIBBPF_0.7.0
+    - libbpf: Use dynamically allocated buffer when receiving netlink messages
+    - power: supply: ab8500: Fix memory leak in ab8500_fg_sysfs_init
+    - HID: i2c-hid: fix GET/SET_REPORT for unnumbered reports
+    - iommu/ipmmu-vmsa: Check for error num after setting mask
+    - drm/bridge: anx7625: Fix overflow issue on reading EDID
+    - ath11k: fix uninitialized rate_idx in ath11k_dp_tx_update_txcompl()
+    - i2c: pasemi: Drop I2C classes from platform driver variant
+    - bpftool: Fix the error when lookup in no-btf maps
+    - drm/amd/pm: enable pm sysfs write for one VF mode
+    - drm/amd/display: Add affected crtcs to atomic state for dsc mst unplug
+    - bpftool: Fix pretty print dump for maps without BTF loaded
+    - libbpf: Fix memleak in libbpf_netlink_recv()
+    - IB/cma: Allow XRC INI QPs to set their local ACK timeout
+    - cxl/core/port: Rename bus.c to port.c
+    - cxl/port: Hold port reference until decoder release
+    - dax: make sure inodes are flushed before destroy cache
+    - selftests: mptcp: add csum mib check for mptcp_connect
+    - iwlwifi: mvm: Don't call iwl_mvm_sta_from_mac80211() with NULL sta
+    - iwlwifi: mvm: don't iterate unadded vifs when handling FW SMPS req
+    - iwlwifi: mvm: align locking in D3 test debugfs
+    - iwlwifi: yoyo: remove DBGI_SRAM address reset writing
+    - iwlwifi: yoyo: Avoid using dram data if allocation failed
+    - iwlwifi: mvm: fix off by one in iwl_mvm_stat_iterator_all_macs()
+    - iwlwifi: Fix -EIO error code that is never returned
+    - iwlwifi: mvm: Fix an error code in iwl_mvm_up()
+    - mtd: rawnand: pl353: Set the nand chip node as the flash node
+    - drm/msm/dp: do not initialize phy until plugin interrupt received
+    - drm/msm/dp: populate connector of struct dp_panel
+    - drm/msm/dp: stop link training after link training 2 failed
+    - drm/msm/dp: always add fail-safe mode into connector mode list
+    - drm/msm/dsi: Use "ref" fw clock instead of global name for VCO parent
+    - drm/msm/dsi/phy: fix 7nm v4.0 settings for C-PHY mode
+    - drm/msm/dpu: add DSPP blocks teardown
+    - drm/msm/dpu: fix dp audio condition
+    - drm/msm/dpu: remove msm_dp cached in dpu_encoder_virt
+    - drm/msm/dp: fix panel bridge attachment
+    - i40e: remove dead stores on XSK hotpath
+    - ath11k: Invalidate cached reo ring entry before accessing it
+    - mips: Enable KCSAN
+    - dm crypt: fix get_key_size compiler warning if !CONFIG_KEYS
+    - vfio/pci: fix memory leak during D3hot to D0 transition
+    - vfio/pci: wake-up devices around reset functions
+    - scsi: fnic: Fix a tracing statement
+    - scsi: pm8001: Fix command initialization in pm80XX_send_read_log()
+    - scsi: pm8001: Fix command initialization in pm8001_chip_ssp_tm_req()
+    - scsi: pm8001: Fix payload initialization in pm80xx_set_thermal_config()
+    - scsi: pm8001: Fix le32 values handling in
+      pm80xx_set_sas_protocol_timer_config()
+    - scsi: pm8001: Fix payload initialization in pm80xx_encrypt_update()
+    - scsi: pm8001: Fix le32 values handling in pm80xx_chip_ssp_io_req()
+    - scsi: pm8001: Fix le32 values handling in pm80xx_chip_sata_req()
+    - scsi: pm8001: Fix NCQ NON DATA command task initialization
+    - scsi: pm8001: Fix NCQ NON DATA command completion handling
+    - scsi: pm8001: Fix abort all task initialization
+    - mt76: do not always copy ethhdr in reverse_frag0_hdr_trans
+    - mt76: fix endianness errors in reverse_frag0_hdr_trans
+    - mt76: mt7921s: fix missing fc type/sub-type for 802.11 pkts
+    - net: dsa: realtek-smi: fix kdoc warnings
+    - net: dsa: realtek-smi: move to subdirectory
+    - RDMA/mlx5: Fix the flow of a miss in the allocation of a cache ODP MR
+    - drm/amd/display: Remove vupdate_int_entry definition
+    - TOMOYO: fix __setup handlers return values
+    - power: supply: sbs-charger: Don't cancel work that is not initialized
+    - mt76: mt7915: enlarge wcid size to 544
+    - mt76: mt7915: fix the muru tlv issue
+    - drm/dp: Fix OOB read when handling Post Cursor2 register
+    - ext2: correct max file size computing
+    - drm/tegra: Fix reference leak in tegra_dsi_ganged_probe
+    - power: supply: bq24190_charger: Fix bq24190_vbus_is_enabled() wrong false
+      return
+    - scsi: hisi_sas: Change permission of parameter prot_mask
+    - drm/bridge: cdns-dsi: Make sure to to create proper aliases for dt
+    - bpf, arm64: Call build_prologue() first in first JIT pass
+    - bpf, arm64: Feed byte-offset into bpf line info
+    - xsk: Fix race at socket teardown
+    - RDMA/irdma: Fix netdev notifications for vlan's
+    - RDMA/irdma: Fix Passthrough mode in VM
+    - RDMA/irdma: Remove incorrect masking of PD
+    - libbpf: Fix BPF_MAP_TYPE_PERF_EVENT_ARRAY auto-pinning
+    - gpu: host1x: Fix an error handling path in 'host1x_probe()'
+    - gpu: host1x: Fix a memory leak in 'host1x_remove()'
+    - libbpf: Skip forward declaration when counting duplicated type names
+    - powerpc/mm/numa: skip NUMA_NO_NODE onlining in parse_numa_properties()
+    - powerpc/Makefile: Don't pass -mcpu=powerpc64 when building 32-bit
+    - KVM: x86: Fix emulation in writing cr8
+    - KVM: x86/emulator: Defer not-present segment check in
+      __load_segment_descriptor()
+    - KVM: SVM: Exit to userspace on ENOMEM/EFAULT GHCB errors
+    - hv_balloon: rate-limit "Unhandled message" warning
+    - KVM: arm64: Enable Cortex-A510 erratum 2077057 by default
+    - i2c: xiic: Make bus names unique
+    - net: phy: micrel: Fix concurrent register access
+    - Bluetooth: hci_sync: fix undefined return of hci_disconnect_all_sync()
+    - Bluetooth: Fix skb allocation in mgmt_remote_name() &
+      mgmt_device_connected()
+    - power: supply: wm8350-power: Handle error for wm8350_register_irq
+    - power: supply: wm8350-power: Add missing free in free_charger_irq
+    - IB/hfi1: Allow larger MTU without AIP
+    - RDMA/core: Fix ib_qp_usecnt_dec() called when error
+    - PCI: Reduce warnings on possible RW1C corruption
+    - net: axienet: fix RX ring refill allocation failure handling
+    - drm/msm/a6xx: Fix missing ARRAY_SIZE() check
+    - mips: DEC: honor CONFIG_MIPS_FP_SUPPORT=n
+    - MIPS: Sanitise Cavium switch cases in TLB handler synthesizers
+    - powerpc/sysdev: fix incorrect use to determine if list is empty
+    - powerpc/64s: Don't use DSISR for SLB faults
+    - mfd: mc13xxx: Add check for mc13xxx_irq_request
+    - libbpf: Unmap rings when umem deleted
+    - selftests/bpf: Make test_lwt_ip_encap more stable and faster
+    - platform/x86: huawei-wmi: check the return value of device_create_file()
+    - scsi: mpt3sas: Fix incorrect 4GB boundary check
+    - powerpc: 8xx: fix a return value error in mpc8xx_pic_init
+    - xtensa: add missing XCHAL_HAVE_WINDOWED check
+    - iwlwifi: pcie: fix SW error MSI-X mapping
+    - vxcan: enable local echo for sent CAN frames
+    - ath10k: Fix error handling in ath10k_setup_msa_resources
+    - mips: cdmm: Fix refcount leak in mips_cdmm_phys_base
+    - MIPS: RB532: fix return value of __setup handler
+    - MIPS: pgalloc: fix memory leak caused by pgd_free()
+    - mtd: rawnand: atmel: fix refcount issue in atmel_nand_controller_init
+    - power: ab8500_chargalg: Use CLOCK_MONOTONIC
+    - RDMA/irdma: Prevent some integer underflows
+    - Revert "RDMA/core: Fix ib_qp_usecnt_dec() called when error"
+    - RDMA/mlx5: Fix memory leak in error flow for subscribe event routine
+    - bpf, sockmap: Fix memleak in sk_psock_queue_msg
+    - bpf, sockmap: Fix memleak in tcp_bpf_sendmsg while sk msg is full
+    - bpf, sockmap: Fix more uncharged while msg has more_data
+    - bpf, sockmap: Fix double uncharge the mem of sk_msg
+    - samples/bpf, xdpsock: Fix race when running for fix duration of time
+    - USB: storage: ums-realtek: fix error code in rts51x_read_mem()
+    - drm/amd/display: Fix double free during GPU reset on DC streams
+    - RDMA/rxe: Change variable and function argument to proper type
+    - RDMA/rxe: Fix ref error in rxe_av.c
+    - powerpc/xive: fix return value of __setup handler
+    - powerpc/time: Fix KVM host re-arming a timer beyond decrementer range
+    - drm/i915/display: Fix HPD short pulse handling for eDP
+    - drm/i915/display: Do not re-enable PSR after it was marked as not reliable
+    - netfilter: flowtable: Fix QinQ and pppoe support for inet table
+    - mt76: mt7921: fix mt7921_queues_acq implementation
+    - can: isotp: return -EADDRNOTAVAIL when reading from unbound socket
+    - can: isotp: support MSG_TRUNC flag when reading from socket
+    - bareudp: use ipv6_mod_enabled to check if IPv6 enabled
+    - PCI: imx6: Invoke the PHY exit function after PHY power off
+    - PCI: imx6: Assert i.MX8MM CLKREQ# even if no device present
+    - ibmvnic: fix race between xmit and reset
+    - af_unix: Fix some data-races around unix_sk(sk)->oob_skb.
+    - selftests/bpf: Fix error reporting from sock_fields programs
+    - Bluetooth: hci_uart: add missing NULL check in h5_enqueue
+    - Bluetooth: call hci_le_conn_failed with hdev lock in hci_le_conn_failed
+    - Bluetooth: btmtksdio: Fix kernel oops in btmtksdio_interrupt
+    - RDMA/nldev: Prevent underflow in nldev_stat_set_counter_dynamic_doit()
+    - ipv4: Fix route lookups when handling ICMP redirects and PMTU updates
+    - mptcp: Fix crash due to tcp_tsorted_anchor was initialized before release
+      skb
+    - af_netlink: Fix shift out of bounds in group mask calculation
+    - i2c: meson: Fix wrong speed use from probe
+    - netfilter: conntrack: Add and use nf_ct_set_auto_assign_helper_warned()
+    - i2c: mux: demux-pinctrl: do not deactivate a master that is not active
+    - powerpc/pseries: Fix use after free in remove_phb_dynamic()
+    - ax25: Fix refcount leaks caused by ax25_cb_del()
+    - ax25: Fix NULL pointer dereferences in ax25 timers
+    - drm/i915: Fix renamed struct field
+    - selftests/bpf/test_lirc_mode2.sh: Exit with proper code
+    - bpftool: Fix print error when show bpf map
+    - PCI: Avoid broken MSI on SB600 USB devices
+    - net: bcmgenet: Use stronger register read/writes to assure ordering
+    - tcp: ensure PMTU updates are processed during fastopen
+    - openvswitch: always update flow key after nat
+    - net: dsa: fix panic on shutdown if multi-chip tree failed to probe
+    - net: wwan: qcom_bam_dmux: fix wrong pointer passed to IS_ERR()
+    - tipc: fix the timer expires after interval 100ms
+    - mfd: asic3: Add missing iounmap() on error asic3_mfd_probe
+    - ice: fix 'scheduling while atomic' on aux critical err interrupt
+    - ice: don't allow to run ice_send_event_to_aux() in atomic ctx
+    - drivers: ethernet: cpsw: fix panic when interrupt coaleceing is set via
+      ethtool
+    - kernel/resource: fix kfree() of bootmem memory again
+    - clk: renesas: r9a07g044: Update multiplier and divider values for PLL2/3
+    - staging: r8188eu: release_firmware is not called if allocation fails
+    - mxser: fix xmit_buf leak in activate when LSR == 0xff
+    - fsi: scom: Fix error handling
+    - fsi: scom: Remove retries in indirect scoms
+    - pwm: lpc18xx-sct: Initialize driver data and hardware before pwmchip_add()
+    - pps: clients: gpio: Propagate return value from pps_gpio_probe
+    - fsi: Aspeed: Fix a potential double free
+    - misc: alcor_pci: Fix an error handling path
+    - cpufreq: qcom-cpufreq-nvmem: fix reading of PVS Valid fuse
+    - soundwire: intel: fix wrong register name in intel_shim_wake
+    - clk: qcom: ipq8074: fix PCI-E clock oops
+    - dmaengine: idxd: restore traffic class defaults after wq reset
+    - iio: mma8452: Fix probe failing when an i2c_device_id is used
+    - staging: qlge: add unregister_netdev in qlge_probe
+    - serial: 8250_aspeed_vuart: add PORT_ASPEED_VUART port type
+    - staging:iio:adc:ad7280a: Fix handing of device address bit reversing.
+    - clk: renesas: r8a779f0: Fix RSW2 clock divider
+    - pinctrl: renesas: r8a77470: Reduce size for narrow VIN1 channel
+    - pinctrl: renesas: checker: Fix miscalculation of number of states
+    - clk: qcom: ipq8074: Use floor ops for SDCC1 clock
+    - phy: dphy: Correct lpx parameter and its derivatives(ta_{get,go,sure})
+    - phy: phy-brcm-usb: fixup BCM4908 support
+    - serial: 8250_mid: Balance reference count for PCI DMA device
+    - serial: 8250_lpss: Balance reference count for PCI DMA device
+    - NFS: Use of mapping_set_error() results in spurious errors
+    - serial: 8250: Fix race condition in RTS-after-send handling
+    - iio: adc: Add check for devm_request_threaded_irq
+    - habanalabs: Add check for pci_enable_device
+    - NFS: Return valid errors from nfs2/3_decode_dirent()
+    - staging: r8188eu: fix endless loop in recv_func
+    - dma-debug: fix return value of __setup handlers
+    - clk: imx7d: Remove audio_mclk_root_clk
+    - clk: imx: off by one in imx_lpcg_parse_clks_from_dt()
+    - clk: at91: sama7g5: fix parents of PDMCs' GCLK
+    - clk: qcom: clk-rcg2: Update logic to calculate D value for RCG
+    - clk: qcom: clk-rcg2: Update the frac table for pixel clock
+    - clk: starfive: jh7100: Don't round divisor up twice
+    - clk: starfive: jh7100: Handle audio_div clock properly
+    - dmaengine: hisi_dma: fix MSI allocate fail when reload hisi_dma
+    - remoteproc: qcom: Fix missing of_node_put in adsp_alloc_memory_region
+    - remoteproc: qcom_wcnss: Add missing of_node_put() in
+      wcnss_alloc_memory_region
+    - remoteproc: qcom_q6v5_mss: Fix some leaks in q6v5_alloc_memory_region
+    - nvdimm/region: Fix default alignment for small regions
+    - clk: actions: Terminate clk_div_table with sentinel element
+    - clk: loongson1: Terminate clk_div_table with sentinel element
+    - clk: hisilicon: Terminate clk_div_table with sentinel element
+    - clk: clps711x: Terminate clk_div_table with sentinel element
+    - clk: Fix clk_hw_get_clk() when dev is NULL
+    - clk: tegra: tegra124-emc: Fix missing put_device() call in
+      emc_ensure_emc_driver
+    - mailbox: imx: fix crash in resume on i.mx8ulp
+    - NFS: remove unneeded check in decode_devicenotify_args()
+    - staging: mt7621-dts: fix LEDs and pinctrl on GB-PC1 devicetree
+    - staging: mt7621-dts: fix formatting
+    - staging: mt7621-dts: fix pinctrl properties for ethernet
+    - staging: mt7621-dts: fix GB-PC2 devicetree
+    - pinctrl: ocelot: fix confops resource index
+    - pinctrl: ocelot: fix duplicate debugfs entry
+    - pinctrl: mediatek: Fix missing of_node_put() in mtk_pctrl_init
+    - pinctrl: mediatek: paris: Fix PIN_CONFIG_BIAS_* readback
+    - pinctrl: mediatek: paris: Fix "argument" argument type for mtk_pinconf_get()
+    - pinctrl: mediatek: paris: Fix pingroup pin config state readback
+    - pinctrl: mediatek: paris: Skip custom extra pin config dump for virtual
+      GPIOs
+    - pinctrl: ocelot: Fix interrupt parsing
+    - pinctrl: microchip-sgpio: lock RMW access
+    - pinctrl: nomadik: Add missing of_node_put() in nmk_pinctrl_probe
+    - pinctrl/rockchip: Add missing of_node_put() in rockchip_pinctrl_probe
+    - clk: visconti: prevent array overflow in visconti_clk_register_gates()
+    - tty: hvc: fix return value of __setup handler
+    - kgdboc: fix return value of __setup handler
+    - serial: 8250: fix XOFF/XON sending when DMA is used
+    - virt: acrn: obtain pa from VMA with PFNMAP flag
+    - virt: acrn: fix a memory leak in acrn_dev_ioctl()
+    - kgdbts: fix return value of __setup handler
+    - firmware: google: Properly state IOMEM dependency
+    - driver core: dd: fix return value of __setup handler
+    - perf test arm64: Test unwinding using fame-pointer (fp) mode
+    - jfs: fix divide error in dbNextAG
+    - SUNRPC/call_alloc: async tasks mustn't block waiting for memory
+    - SUNRPC: improve 'swap' handling: scheduling and PF_MEMALLOC
+    - SUNRPC: Don't call connect() more than once on a TCP socket
+    - perf parse-events: Move slots only with topdown
+    - netfilter: egress: Report interface as outgoing
+    - netfilter: nf_conntrack_tcp: preserve liberal flag in tcp options
+    - SUNRPC don't resend a task on an offlined transport
+    - NFSv4.1: don't retry BIND_CONN_TO_SESSION on session error
+    - kdb: Fix the putarea helper function
+    - perf stat: Fix forked applications enablement of counters
+    - net: stmmac: dwmac-qcom-ethqos: Enable RGMII functional clock on resume
+    - clk: qcom: gcc-msm8994: Fix gpll4 width
+    - vsock/virtio: initialize vdev->priv before using VQs
+    - vsock/virtio: read the negotiated features before using VQs
+    - vsock/virtio: enable VQs early on probe
+    - clk: Initialize orphan req_rate
+    - xen: fix is_xen_pmu()
+    - net: enetc: report software timestamping via SO_TIMESTAMPING
+    - net: hns3: fix bug when PF set the duplicate MAC address for VFs
+    - net: hns3: fix port base vlan add fail when concurrent with reset
+    - net: hns3: add vlan list lock to protect vlan list
+    - net: hns3: refine the process when PF set VF VLAN
+    - net: phy: broadcom: Fix brcm_fet_config_init()
+    - selftests: test_vxlan_under_vrf: Fix broken test case
+    - NFS: Don't loop forever in nfs_do_recoalesce()
+    - libperf tests: Fix typo in perf_evlist__open() failure error messages
+    - net: hns3: fix ethtool tx copybreak buf size indicating not aligned issue
+    - net: hns3: add max order judgement for tx spare buffer
+    - net: hns3: clean residual vf config after disable sriov
+    - net: hns3: add netdev reset check for hns3_set_tunable()
+    - net: hns3: add NULL pointer check for hns3_set/get_ringparam()
+    - net: hns3: fix phy can not link up when autoneg off and reset
+    - net: sparx5: depends on PTP_1588_CLOCK_OPTIONAL
+    - qlcnic: dcb: default to returning -EOPNOTSUPP
+    - net/x25: Fix null-ptr-deref caused by x25_disconnect
+    - net: sparx5: switchdev: fix possible NULL pointer dereference
+    - octeontx2-af: initialize action variable
+    - selftests: tls: skip cmsg_to_pipe tests with TLS=n
+    - net/sched: act_ct: fix ref leak when switching zones
+    - NFSv4/pNFS: Fix another issue with a list iterator pointing to the head
+    - net: dsa: bcm_sf2_cfp: fix an incorrect NULL check on list iterator
+    - fs: fd tables have to be multiples of BITS_PER_LONG
+    - lib/test: use after free in register_test_dev_kmod()
+    - fs: fix fd table size alignment properly
+    - LSM: general protection fault in legacy_parse_param
+    - regulator: rpi-panel: Handle I2C errors/timing to the Atmel
+    - crypto: hisilicon/qm - cleanup warning in qm_vf_read_qos
+    - crypto: octeontx2 - CN10K CPT to RNM workaround
+    - gcc-plugins/stackleak: Exactly match strings instead of prefixes
+    - rcu: Kill rnp->ofl_seq and use only rcu_state.ofl_lock for exclusion
+    - pinctrl: npcm: Fix broken references to chip->parent_device
+    - rcu: Mark writes to the rcu_segcblist structure's ->flags field
+    - block: throttle split bio in case of iops limit
+    - memstick/mspro_block: fix handling of read-only devices
+    - block/bfq_wf2q: correct weight to ioprio
+    - crypto: xts - Add softdep on ecb
+    - crypto: hisilicon/sec - not need to enable sm4 extra mode at HW V3
+    - block, bfq: don't move oom_bfqq
+    - selinux: use correct type for context length
+    - powercap/dtpm_cpu: Reset per_cpu variable in the release function
+    - arm64: module: remove (NOLOAD) from linker script
+    - selinux: allow FIOCLEX and FIONCLEX with policy capability
+    - loop: use sysfs_emit() in the sysfs xxx show()
+    - Fix incorrect type in assignment of ipv6 port for audit
+    - irqchip/qcom-pdc: Fix broken locking
+    - irqchip/nvic: Release nvic_base upon failure
+    - fs/binfmt_elf: Fix AT_PHDR for unusual ELF files
+    - hwrng: cavium - fix NULL but dereferenced coccicheck error
+    - bfq: fix use-after-free in bfq_dispatch_request
+    - ACPICA: Avoid walking the ACPI Namespace if it is not there
+    - ACPI / x86: Add skip i2c clients quirk for Nextbook Ares 8
+    - ACPI / x86: Add skip i2c clients quirk for Lenovo Yoga Tablet 1050F/L
+    - lib/raid6/test/Makefile: Use $(pound) instead of \# for Make 4.3
+    - Revert "Revert "block, bfq: honor already-setup queue merges""
+    - ACPI/APEI: Limit printable size of BERT table data
+    - PM: core: keep irq flags in device_pm_check_callbacks()
+    - parisc: Fix non-access data TLB cache flush faults
+    - parisc: Fix handling off probe non-access faults
+    - nvme-tcp: lockdep: annotate in-kernel sockets
+    - spi: tegra20: Use of_device_get_match_data()
+    - spi: fsi: Implement a timeout for polling status
+    - atomics: Fix atomic64_{read_acquire,set_release} fallbacks
+    - locking/lockdep: Iterate lock_classes directly when reading lockdep files
+    - ext4: correct cluster len and clusters changed accounting in ext4_mb_mark_bb
+    - ext4: fix ext4_mb_mark_bb() with flex_bg with fast_commit
+    - sched/tracing: Report TASK_RTLOCK_WAIT tasks as TASK_UNINTERRUPTIBLE
+    - ext4: don't BUG if someone dirty pages without asking ext4 first
+    - f2fs: fix to do sanity check on curseg->alloc_type
+    - NFSD: Fix nfsd_breaker_owns_lease() return values
+    - f2fs: don't get FREEZE lock in f2fs_evict_inode in frozen fs
+    - btrfs: harden identification of a stale device
+    - btrfs: make search_csum_tree return 0 if we get -EFBIG
+    - btrfs: handle csum lookup errors properly on reads
+    - btrfs: do not double complete bio on errors during compressed reads
+    - btrfs: do not clean up repair bio if submit fails
+    - f2fs: use spin_lock to avoid hang
+    - f2fs: compress: fix to print raw data size in error path of lz4
+      decompression
+    - Adjust cifssb maximum read size
+    - ntfs: add sanity check on allocation size
+    - media: staging: media: zoran: move videodev alloc
+    - media: staging: media: zoran: calculate the right buffer number for
+      zoran_reap_stat_com
+    - media: staging: media: zoran: fix various V4L2 compliance errors
+    - media: atmel: atmel-isc-base: report frame sizes as full supported range
+    - media: ir_toy: free before error exiting
+    - ASoC: sh: rz-ssi: Make the data structures available before registering the
+      handlers
+    - ASoC: cs42l42: Report full jack status when plug is detected
+    - ASoC: SOF: Intel: match sdw version on link_slaves_found
+    - media: imx-jpeg: Prevent decoding NV12M jpegs into single-planar buffers
+    - ASoC: SOF: Intel: hda: Remove link assignment limitation
+    - media: iommu/mediatek-v1: Free the existed fwspec if the master dev already
+      has
+    - media: iommu/mediatek: Return ENODEV if the device is NULL
+    - media: iommu/mediatek: Add device_link between the consumer and the larb
+      devices
+    - video: fbdev: nvidiafb: Use strscpy() to prevent buffer overflow
+    - video: fbdev: w100fb: Reset global state
+    - video: fbdev: cirrusfb: check pixclock to avoid divide by zero
+    - video: fbdev: omapfb: acx565akm: replace snprintf with sysfs_emit
+    - ARM: dts: qcom: fix gic_irq_domain_translate warnings for msm8960
+    - ARM: dts: bcm2837: Add the missing L1/L2 cache information
+    - ASoC: madera: Add dependencies on MFD
+    - media: atomisp_gmin_platform: Add DMI quirk to not turn AXP ELDO2 regulator
+      off on some boards
+    - media: atomisp: fix dummy_ptr check to avoid duplicate active_bo
+    - ARM: ftrace: avoid redundant loads or clobbering IP
+    - ALSA: hda: Fix driver index handling at re-binding
+    - ARM: dts: imx7: Use audio_mclk_post_div instead audio_mclk_root_clk
+    - arm64: defconfig: build imx-sdma as a module
+    - video: fbdev: omapfb: panel-dsi-cm: Use sysfs_emit() instead of snprintf()
+    - video: fbdev: omapfb: panel-tpo-td043mtea1: Use sysfs_emit() instead of
+      snprintf()
+    - video: fbdev: udlfb: replace snprintf in show functions with sysfs_emit
+    - ARM: dts: bcm2711: Add the missing L1/L2 cache information
+    - ASoC: soc-core: skip zero num_dai component in searching dai name
+    - ASoC: Intel: sof_es8336: add quirk for Huawei D15 2021
+    - media: imx-jpeg: fix a bug of accessing array out of bounds
+    - media: cx88-mpeg: clear interrupt status register before streaming video
+    - ASoC: rt5682s: Fix the wrong jack type detected
+    - ARM: tegra: transformer: Drop reg-shift for Tegra HS UART
+    - uaccess: fix type mismatch warnings from access_ok()
+    - lib/test_lockup: fix kernel pointer check for separate address spaces
+    - ARM: tegra: tamonten: Fix I2C3 pad setting
+    - ARM: mmp: Fix failure to remove sram device
+    - ASoC: amd: vg: fix for pm resume callback sequence
+    - ASoC: amd: vangogh: fix uninitialized symbol warning in machine driver
+    - video: fbdev: sm712fb: Fix crash in smtcfb_write()
+    - media: i2c: ov5648: Fix lockdep error
+    - media: Revert "media: em28xx: add missing em28xx_close_extension"
+    - media: hdpvr: initialize dev->worker at hdpvr_register_videodev
+    - ASoC: SOF: debug: clarify operator precedence
+    - ASoC: Intel: sof_sdw: fix quirks for 2022 HP Spectre x360 13"
+    - ASoC: SOF: Intel: hda: retrieve DMIC number for I2S boards
+    - ALSA: intel-nhlt: add helper to detect SSP link mask
+    - ALSA: intel-dsp-config: add more ACPI HIDs for ES83x6 devices
+    - ASoC: Intel: soc-acpi: add more ACPI HIDs for ES83x6 devices
+    - ALSA: intel-dspconfig: add ES8336 support for CNL
+    - ASoC: Intel: Revert "ASoC: Intel: sof_es8336: add quirk for Huawei D15 2021"
+    - ASoC: Intel: sof_es8336: log all quirks
+    - tracing: Have TRACE_DEFINE_ENUM affect trace event types as well
+    - mmc: host: Return an error when ->enable_sdio_irq() ops is missing
+    - ASoC: mediatek: Fix error handling in mt8183_da7219_max98357_dev_probe
+    - media: atomisp: fix bad usage at error handling logic
+    - ALSA: hda/realtek: Add alc256-samsung-headphone fixup
+    - KVM: SVM: Allow AVIC support on system w/ physical APIC ID > 255
+    - KVM: x86: Reinitialize context if host userspace toggles EFER.LME
+    - KVM: x86/mmu: Use common TDP MMU zap helper for MMU notifier unmap hook
+    - KVM: x86/mmu: Move "invalid" check out of kvm_tdp_mmu_get_root()
+    - KVM: x86/mmu: Zap _all_ roots when unmapping gfn range in TDP MMU
+    - KVM: x86/mmu: Check for present SPTE when clearing dirty bit in TDP MMU
+    - KVM: x86: hyper-v: Drop redundant 'ex' parameter from kvm_hv_send_ipi()
+    - KVM: x86: hyper-v: Drop redundant 'ex' parameter from kvm_hv_flush_tlb()
+    - KVM: x86: hyper-v: Fix the maximum number of sparse banks for XMM fast TLB
+      flush hypercalls
+    - KVM: x86: hyper-v: HVCALL_SEND_IPI_EX is an XMM fast hypercall
+    - powerpc/kasan: Fix early region not updated correctly
+    - powerpc/tm: Fix more userspace r13 corruption
+    - powerpc/lib/sstep: Fix 'sthcx' instruction
+    - powerpc/lib/sstep: Fix build errors with newer binutils
+    - powerpc: Add set_memory_{p/np}() and remove set_memory_attr()
+    - powerpc: Fix build errors with newer binutils
+    - drm/dp: Fix off-by-one in register cache size
+    - drm/i915: Treat SAGV block time 0 as SAGV disabled
+    - drm/i915: Fix PSF GV point mask when SAGV is not possible
+    - drm/i915: Reject unsupported TMDS rates on ICL+
+    - scsi: qla2xxx: Refactor asynchronous command initialization
+    - scsi: qla2xxx: Implement ref count for SRB
+    - scsi: qla2xxx: Fix stuck session in gpdb
+    - scsi: qla2xxx: Fix warning message due to adisc being flushed
+    - scsi: qla2xxx: Fix scheduling while atomic
+    - scsi: qla2xxx: Fix premature hw access after PCI error
+    - scsi: qla2xxx: Fix wrong FDMI data for 64G adapter
+    - scsi: qla2xxx: Fix warning for missing error code
+    - scsi: qla2xxx: Fix device reconnect in loop topology
+    - scsi: qla2xxx: edif: Fix clang warning
+    - scsi: qla2xxx: Fix T10 PI tag escape and IP guard options for 28XX adapters
+    - scsi: qla2xxx: Add devids and conditionals for 28xx
+    - scsi: qla2xxx: Check for firmware dump already collected
+    - scsi: qla2xxx: Suppress a kernel complaint in qla_create_qpair()
+    - scsi: qla2xxx: Fix disk failure to rediscover
+    - scsi: qla2xxx: Fix incorrect reporting of task management failure
+    - scsi: qla2xxx: Fix hang due to session stuck
+    - scsi: qla2xxx: Fix laggy FC remote port session recovery
+    - scsi: qla2xxx: Fix missed DMA unmap for NVMe ls requests
+    - scsi: qla2xxx: Fix crash during module load unload test
+    - scsi: qla2xxx: Fix N2N inconsistent PLOGI
+    - scsi: qla2xxx: Fix stuck session of PRLI reject
+    - scsi: qla2xxx: Reduce false trigger to login
+    - scsi: qla2xxx: Use correct feature type field during RFF_ID processing
+    - platform: chrome: Split trace include file
+    - MIPS: crypto: Fix CRC32 code
+    - KVM: x86: Check lapic_in_kernel() before attempting to set a SynIC irq
+    - KVM: x86: Avoid theoretical NULL pointer dereference in
+      kvm_irq_delivery_to_apic_fast()
+    - KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC wasn't activated
+    - KVM: x86/mmu: do compare-and-exchange of gPTE via the user address
+    - KVM: Prevent module exit until all VMs are freed
+    - KVM: x86: fix sending PV IPI
+    - KVM: SVM: fix panic on out-of-bounds guest IRQ
+    - KVM: avoid double put_page with gfn-to-pfn cache
+    - ubifs: rename_whiteout: Fix double free for whiteout_ui->data
+    - ubifs: Fix deadlock in concurrent rename whiteout and inode writeback
+    - ubifs: Add missing iput if do_tmpfile() failed in rename whiteout
+    - ubifs: Rename whiteout atomically
+    - ubifs: Fix 'ui->dirty' race between do_tmpfile() and writeback work
+    - ubifs: Rectify space amount budget for mkdir/tmpfile operations
+    - ubifs: setflags: Make dirtied_ino_d 8 bytes aligned
+    - ubifs: Fix read out-of-bounds in ubifs_wbuf_write_nolock()
+    - ubifs: Fix to add refcount once page is set private
+    - ubifs: rename_whiteout: correct old_dir size computing
+    - nvme: allow duplicate NSIDs for private namespaces
+    - nvme: fix the read-only state for zoned namespaces with unsupposed features
+    - wireguard: queueing: use CFI-safe ptr_ring cleanup function
+    - wireguard: socket: free skb in send6 when ipv6 is disabled
+    - wireguard: socket: ignore v6 endpoints when ipv6 is disabled
+    - XArray: Fix xas_create_range() when multi-order entry present
+    - can: mcba_usb: mcba_usb_start_xmit(): fix double dev_kfree_skb in error path
+    - can: mcba_usb: properly check endpoint type
+    - can: mcp251xfd: mcp251xfd_register_get_dev_id(): fix return of error value
+    - XArray: Include bitmap.h from xarray.h
+    - XArray: Update the LRU list in xas_split()
+    - modpost: restore the warning message for missing symbol versions
+    - rtc: gamecube: Fix refcount leak in gamecube_rtc_read_offset_from_sram
+    - rtc: check if __rtc_read_time was successful
+    - loop: fix ioctl calls using compat_loop_info
+    - gfs2: gfs2_setattr_size error path fix
+    - gfs2: Fix gfs2_file_buffered_write endless loop workaround
+    - gfs2: Make sure FITRIM minlen is rounded up to fs block size
+    - net: hns3: fix the concurrency between functions reading debugfs
+    - net: hns3: fix software vlan talbe of vlan 0 inconsistent with hardware
+    - rxrpc: fix some null-ptr-deref bugs in server_key.c
+    - rxrpc: Fix call timer start racing with call destruction
+    - mailbox: imx: fix wakeup failure from freeze mode
+    - crypto: x86/poly1305 - Fixup SLS
+    - crypto: arm/aes-neonbs-cbc - Select generic cbc and aes
+    - watch_queue: Free the page array when watch_queue is dismantled
+    - pinctrl: pinconf-generic: Print arguments for bias-pull-*
+    - watchdog: rti-wdt: Add missing pm_runtime_disable() in probe function
+    - net: sparx5: uses, depends on BRIDGE or !BRIDGE
+    - pinctrl: nuvoton: npcm7xx: Rename DS() macro to DSTR()
+    - pinctrl: nuvoton: npcm7xx: Use %zu printk format for ARRAY_SIZE()
+    - ASoC: rockchip: i2s_tdm: Fixup config for SND_SOC_DAIFMT_DSP_A/B
+    - ASoC: mediatek: mt6358: add missing EXPORT_SYMBOLs
+    - ubi: Fix race condition between ctrl_cdev_ioctl and ubi_cdev_ioctl
+    - ARM: iop32x: offset IRQ numbers by 1
+    - block: Fix the maximum minor value is blk_alloc_ext_minor()
+    - block: restore the old set_task_ioprio() behaviour wrt PF_EXITING
+    - Revert "virtio-pci: harden INTX interrupts"
+    - Revert "virtio_pci: harden MSI-X interrupts"
+    - virtio: use virtio_device_ready() in virtio_device_restore()
+    - io_uring: remove poll entry from list when canceling all
+    - io_uring: bump poll refs to full 31-bits
+    - io_uring: fix memory leak of uid in files registration
+    - riscv module: remove (NOLOAD)
+    - ACPI: CPPC: Avoid out of bounds access when parsing _CPC data
+    - vhost: handle error while adding split ranges to iotlb
+    - spi: Fix Tegra QSPI example
+    - platform/chrome: cros_ec_typec: Check for EC device
+    - platform/x86: asus-wmi: Fix regression when probing for fan curve control
+    - can: isotp: restore accidentally removed MSG_PEEK feature
+    - proc: bootconfig: Add null pointer check
+    - x86/fpu/xstate: Fix the ARCH_REQ_XCOMP_PERM implementation
+    - x86/sev: Unroll string mmio with CC_ATTR_GUEST_UNROLL_STRING_IO
+    - drm/connector: Fix typo in documentation
+    - scsi: qla2xxx: Add qla2x00_async_done() for async routines
+    - staging: mt7621-dts: fix pinctrl-0 items to be size-1 items on ethernet
+    - docs: fix 'make htmldocs' warning in SCTP.rst
+    - arm64: mm: Drop 'const' from conditional arm64_dma_phys_limit definition
+    - ASoC: soc-compress: Change the check for codec_dai
+    - KVM: x86: SVM: fix avic spec based definitions again
+    - ax25: fix UAF bug in ax25_send_control()
+    - Reinstate some of "swiotlb: rework "fix info leak with DMA_FROM_DEVICE""
+    - tracing: Have type enum modifications copy the strings
+    - mips: Enable KCSAN - take 2
+    - net: add skb_set_end_offset() helper
+    - mm/mmap: return 1 from stack_guard_gap __setup() handler
+    - ARM: 9187/1: JIVE: fix return value of __setup handler
+    - mm/memcontrol: return 1 from cgroup.memory __setup() handler
+    - mm/usercopy: return 1 from hardened_usercopy __setup() handler
+    - af_unix: Support POLLPRI for OOB.
+    - libbpf: Define BTF_KIND_* constants in btf.h to avoid compilation errors
+    - bpf: Adjust BPF stack helper functions to accommodate skip > 0
+    - bpf: Fix comment for helper bpf_current_task_under_cgroup()
+    - nbd: fix possible overflow on 'first_minor' in nbd_dev_add()
+    - mmc: rtsx: Use pm_runtime_{get,put}() to handle runtime PM
+    - dt-bindings: mtd: nand-controller: Fix the reg property description
+    - dt-bindings: mtd: nand-controller: Fix a comment in the examples
+    - dt-bindings: spi: mxic: The interrupt property is not mandatory
+    - media: dt-binding: media: hynix,hi846: use $defs/port-base port description
+    - media: dt-bindings: media: hynix,hi846: add link-frequencies description
+    - dt-bindings: memory: mtk-smi: Rename clock to clocks
+    - dt-bindings: memory: mtk-smi: No need mediatek,larb-id for mt8167
+    - dt-bindings: memory: mtk-smi: Correct minItems to 2 for the gals clocks
+    - dt-bindings: pinctrl: mt8195: fix bias-pull-{up,down} checks
+    - dt-bindings: pinctrl: pinctrl-microchip-sgpio: Fix example
+    - ubi: fastmap: Return error code if memory allocation fails in add_aeb()
+    - net: preserve skb_end_offset() in skb_unclone_keeptruesize()
+    - ASoC: SOF: Intel: Fix build error without SND_SOC_SOF_PCI_DEV
+    - ASoC: topology: Allow TLV control to be either read or write
+    - perf vendor events: Update metrics for SkyLake Server
+    - media: ov6650: Add try support to selection API operations
+    - media: ov6650: Fix crop rectangle affected by set format
+    - pinctrl: canonical rsel resistance selection property
+    - spi: mediatek: support tick_delay without enhance_timing
+    - ARM: dts: spear1340: Update serial node properties
+    - ARM: dts: spear13xx: Update SPI dma properties
+    - arm64: dts: ls1043a: Update i2c dma properties
+    - arm64: dts: ls1046a: Update i2c node dma properties
+    - um: Fix uml_mconsole stop/go
+    - docs: sysctl/kernel: add missing bit to panic_print
+    - xsk: Do not write NULL in SW ring at allocation failure
+    - ice: xsk: Fix indexing in ice_tx_xsk_pool()
+    - vdpa/mlx5: Avoid processing works if workqueue was destroyed
+    - openvswitch: Fixed nd target mask field in the flow dump.
+    - torture: Make torture.sh help message match reality
+    - n64cart: convert bi_disk to bi_bdev->bd_disk fix build
+    - Revert "nbd: fix possible overflow on 'first_minor' in nbd_dev_add()"
+    - mmc: rtsx: Let MMC core handle runtime PM
+    - mmc: rtsx: Fix build errors/warnings for unused variable
+    - coredump: Snapshot the vmas in do_coredump
+    - coredump: Remove the WARN_ON in dump_vma_snapshot
+    - coredump/elf: Pass coredump_params into fill_note_info
+    - coredump: Use the vma snapshot in fill_files_note
+    - Linux 5.17.2
+
+  * Jammy update: v5.17.1 upstream stable release (LP: #1968982)
+    - tpm: Fix error handling in async work
+    - Bluetooth: btusb: Add another Realtek 8761BU
+    - llc: fix netdevice reference leaks in llc_ui_bind()
+    - ASoC: sti: Fix deadlock via snd_pcm_stop_xrun() call
+    - ALSA: oss: Fix PCM OSS buffer allocation overflow
+    - ALSA: usb-audio: add mapping for new Corsair Virtuoso SE
+    - ALSA: hda/realtek: Add quirk for Clevo NP70PNJ
+    - ALSA: hda/realtek: Add quirk for Clevo NP50PNJ
+    - ALSA: hda/realtek - Fix headset mic problem for a HP machine with alc671
+    - ALSA: hda/realtek: Add quirk for ASUS GA402
+    - ALSA: pcm: Fix races among concurrent hw_params and hw_free calls
+    - ALSA: pcm: Fix races among concurrent read/write and buffer changes
+    - ALSA: pcm: Fix races among concurrent prepare and hw_params/hw_free calls
+    - ALSA: pcm: Fix races among concurrent prealloc proc writes
+    - ALSA: pcm: Add stream lock during PCM reset ioctl operations
+    - ALSA: usb-audio: Add mute TLV for playback volumes on RODE NT-USB
+    - ALSA: cmipci: Restore aux vol on suspend/resume
+    - ALSA: pci: fix reading of swapped values from pcmreg in AC97 codec
+    - drivers: net: xgene: Fix regression in CRC stripping
+    - netfilter: nf_tables: initialize registers in nft_do_chain()
+    - netfilter: nf_tables: validate registers coming from userspace.
+    - ACPI / x86: Work around broken XSDT on Advantech DAC-BJ01 board
+    - ACPI: battery: Add device HID and quirk for Microsoft Surface Go 3
+    - ACPI: video: Force backlight native for Clevo NL5xRU and NL5xNU
+    - crypto: qat - disable registration of algorithms
+    - Bluetooth: btusb: Add one more Bluetooth part for the Realtek RTL8852AE
+    - Bluetooth: hci_sync: Add a new quirk to skip HCI_FLT_CLEAR_ALL
+    - Bluetooth: btusb: Use quirk to skip HCI_FLT_CLEAR_ALL on fake CSR
+      controllers
+    - Revert "ath: add support for special 0x0 regulatory domain"
+    - drm/virtio: Ensure that objs is not NULL in virtio_gpu_array_put_free()
+    - jbd2: fix use-after-free of transaction_t race
+    - rcu: Don't deboost before reporting expedited quiescent state
+    - uaccess: fix integer overflow on access_ok()
+    - mac80211: fix potential double free on mesh join
+    - tpm: fix reference counting for struct tpm_chip
+    - tpm: use try_get_ops() in tpm-space.c
+    - wcn36xx: Differentiate wcn3660 from wcn3620
+    - m68k: fix access_ok for coldfire
+    - nds32: fix access_ok() checks in get/put_user
+    - drm/msm/gpu: Fix crash on devices without devfreq support (v2)
+    - llc: only change llc->dev when bind() succeeds
+    - Linux 5.17.1
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: shiftfs: always rely on init_user_ns
+    - [Config] update configs and annotations after stable updates
+    - SAUCE: sfc: The size of the RX recycle ring should be more flexible
+    - [Packaging] remove references to lowlatency flavor
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 14 Apr 2022 08:45:40 +0200
+
+linux-unstable (5.17.0-6.6) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-6.6 -proposed tracker (LP: #1965731)
+
+  * dependency on crda obsolete according to Debian (LP: #1958918)
+    - [Packaging] switch dependency from crda to wireless-regdb
+
+  * Miscellaneous Ubuntu changes
+    - [Config] disable CONFIG_SYSFB_SIMPLEFB on amd64
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.17
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 21 Mar 2022 09:46:03 +0100
+
+linux-unstable (5.17.0-5.5) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-5.5 -proposed tracker (LP: #1964766)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync dkms-build{,--nvidia-N} from LRMv5
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to v5.17-rc8
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.17-rc8
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 14 Mar 2022 13:15:50 +0100
+
+linux-unstable (5.17.0-4.4) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-4.4 -proposed tracker (LP: #1963880)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.17-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 07 Mar 2022 10:20:48 +0100
+
+linux-unstable (5.17.0-3.3) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-3.3 -proposed tracker (LP: #1962450)
+
+  * 5.15 stuck at boot on c4.large (LP: #1956780)
+    - Revert "PCI/MSI: Mask MSI-X vectors only on success"
+
+  * [22.04 FEAT] KVM: Enable storage key checking for intercepted instruction
+    handled by userspace (LP: #1933179)
+    - s390/uaccess: Add copy_from/to_user_key functions
+    - KVM: s390: Honor storage keys when accessing guest memory
+    - KVM: s390: handle_tprot: Honor storage keys
+    - KVM: s390: Add optional storage key checking to MEMOP IOCTL
+    - KVM: s390: Add vm IOCTL for key checked guest absolute memory access
+    - KVM: s390: Rename existing vcpu memop functions
+    - KVM: s390: Update api documentation for memop ioctl
+    - KVM: s390: Clarify key argument for MEM_OP in api docs
+    - KVM: s390: Add missing vm MEM_OP size check
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.17-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Feb 2022 09:42:32 +0100
+
+linux-unstable (5.17.0-2.2) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.17.0-2.2 -proposed tracker (LP: #1962137)
+
+  * CVE-2022-25636
+    - netfilter: nf_tables_offload: incorrect flow offload action array size
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+    - [Packaging] update Ubuntu.md
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Jammy update: v5.15.22 upstream stable release (LP: #1960516)
+    - Revert "ASoC: mediatek: Check for error clk pointer"
+    - [Config] disable FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION
+
+  * Jammy update: v5.15.20 upstream stable release (LP: #1960509)
+    - Revert "UBUNTU: SAUCE: Revert "e1000e: Additional PHY power saving in S0ix""
+
+  * Jammy update: v5.15.19 upstream stable release (LP: #1959879)
+    - drm/etnaviv: relax submit size limits
+
+  * Jammy update: v5.15.17 upstream stable release (LP: #1959376)
+    - net: dsa: hellcreek: Allow PTP P2P measurements on blocked ports
+    - rtw88: add quirk to disable pci caps on HP 250 G7 Notebook PC
+    - ASoC: mediatek: Check for error clk pointer
+    - regulator: da9121: Prevent current limit change when enabled
+    - ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream
+    - drm/etnaviv: limit submit sizes
+    - Bluetooth: hci_sync: Fix not setting adv set duration
+    - net: axienet: Wait for PhyRstCmplt after core reset
+
+  * rtw88_8821ce causes freeze (LP: #1927808) // Jammy update: v5.15.17 upstream
+    stable release (LP: #1959376)
+    - rtw88: Disable PCIe ASPM while doing NAPI poll on 8821CE
+
+  * Jammy update: v5.15.15 upstream stable release (LP: #1958418)
+    - Bluetooth: btusb: Add support for Foxconn MT7922A
+    - Bluetooth: btbcm: disable read tx power for MacBook Air 8,1 and 8,2
+    - platform/x86/intel: hid: add quirk to support Surface Go 3
+
+  * Support USB4 DP alt mode for AMD Yellow Carp graphics card (LP: #1953008)
+    - SAUCE: drm/amd/display: Fixup previous PSR policy commit
+
+  * alsa/sdw: add sdw audio machine driver for several ADL machines
+    (LP: #1951563)
+    - ASoC: Intel: sof_sdw: Add support for SKU 0B11 product
+    - ASoC: Intel: sof_sdw: Add support for SKU 0B13 product
+    - ASoC: Intel: sof_sdw: Add support for SKU 0B29 product
+    - ASoC: Intel: sof_sdw: Add support for SKU 0B12 product
+
+  * Improve performance and idle power consumption (LP: #1941893)
+    - x86: ACPI: cstate: Optimize C3 entry on AMD CPUs
+
+  * Fix spurious wakeup caused by Intel 7560 WWAN (LP: #1956443)
+    - net: wwan: iosm: Keep device at D0 for s2idle case
+
+  * Jammy update: v5.15.13 upstream stable release (LP: #1956926)
+    - scsi: lpfc: Terminate string in lpfc_debugfs_nvmeio_trc_write()
+    - net/mlx5: Fix tc max supported prio for nic mode
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Update dependency of pahole / dwarves
+    - [packaging] unhook lowlatency flavours from the build
+    - [Packaging] use default zstd compression
+    - [Packaging] do not use compression for image packages
+    - [Packaging] use xz compression for ddebs
+    - SAUCE: Makefile: Remove inclusion of lbm header files
+    - SAUCE: Makefile: Fix compiler warnings
+    - [Config] drop unused lowlatency configs
+    - [Config] update configs and annotations after rebase to v5.17-rc5
+
+  * Miscellaneous upstream changes
+    - Revert "rtw88: Disable PCIe ASPM while doing NAPI poll on 8821CE"
+    - MAINTAINERS: Add scripts/pahole-flags.sh to BPF section
+    - kbuild: Add CONFIG_PAHOLE_VERSION
+    - lib/Kconfig.debug: Use CONFIG_PAHOLE_VERSION
+    - lib/Kconfig.debug: Allow BTF + DWARF5 with pahole 1.21+
+    - Revert "UBUNTU: [Packaging] temporarily disable zfs"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 24 Feb 2022 09:41:40 +0100
+
+linux-unstable (5.17.0-1.1) jammy; urgency=medium
+
+  * Rebase to 5.17-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 21 Feb 2022 08:22:18 +0100
+
+linux-unstable (5.17.0-0.0) jammy; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 28 Jan 2022 17:14:13 +0100
+
+linux (5.15.0-18.18) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-18.18 -proposed tracker (LP: #1958638)
+
+  * CVE-2021-4155
+    - xfs: map unwritten blocks in XFS_IOC_{ALLOC, FREE}SP just like fallocate
+
+  * CVE-2022-0185
+    - SAUCE: vfs: test that one given mount param is not larger than PAGE_SIZE
+
+  * [UBUNTU 20.04] KVM hardware diagnose data improvements for guest kernel -
+    kernel part (LP: #1953334)
+    - KVM: s390: add debug statement for diag 318 CPNC data
+
+  * OOB write on BPF_RINGBUF (LP: #1956585)
+    - SAUCE: bpf: prevent helper argument PTR_TO_ALLOC_MEM to have offset other
+      than 0
+
+  * Miscellaneous Ubuntu changes
+    - [Config] re-enable shiftfs
+    - [SAUCE] shiftfs: support kernel 5.15
+    - [Config] update toolchain versions
+
+  * Miscellaneous upstream changes
+    - vfs: fs_context: fix up param length parsing in legacy_parse_param
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 21 Jan 2022 13:32:27 +0100
+
+linux (5.15.0-17.17) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-17.17 -proposed tracker (LP: #1957809)
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 13 Jan 2022 17:11:21 +0100
+
+linux (5.15.0-16.16) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-16.16 -proposed tracker (LP: #1956820)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * 5.15 stuck at boot on c4.large (LP: #1956780)
+    - Revert "PCI/MSI: Mask MSI-X vectors only on success"
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] temporarily disable signed v4l2loopback"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Sat, 08 Jan 2022 10:57:58 +0100
+
+linux (5.15.0-15.15) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-15.15 -proposed tracker (LP: #1956314)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * rtw88_8821ce causes freeze (LP: #1927808)
+    - rtw88: Disable PCIe ASPM while doing NAPI poll on 8821CE
+
+  * alsa/sdw: fix the  audio sdw codec parsing logic in the acpi table
+    (LP: #1955686)
+    - ALSA: hda: intel-sdw-acpi: go through HDAS ACPI at max depth of 2
+    - ALSA: hda: intel-sdw-acpi: harden detection of controller
+
+  * Got black screen when resume from s2idle with AMD dGPU (LP: #1955790)
+    - SAUCE: drm/amdgpu: put SMU into proper state on runpm suspending for BOCO
+      capable platform
+    - SAUCE: drm/amdgpu: always reset the asic in suspend (v2)
+
+  *  Fix USB3 detection on HP dock (LP: #1955443)
+    - usb: hub: Add delay for SuperSpeed hub resume to let links transit to U0
+
+  * support signed v4l2loopback dkms build (LP: #1938531)
+    - enable v4l2loopback builds on amd64 kernels
+    - support v4l2loopback dkms build
+
+  * Jammy update: v5.15.12 upstream stable release (LP: #1956305)
+    - arm64: vdso32: require CROSS_COMPILE_COMPAT for gcc+bfd
+    - net: usb: lan78xx: add Allied Telesis AT29M2-AF
+    - ext4: prevent partial update of the extent blocks
+    - ext4: check for out-of-order index extents in ext4_valid_extent_entries()
+    - ext4: check for inconsistent extents between index and leaf block
+    - selftests: KVM: Fix non-x86 compiling
+    - HID: holtek: fix mouse probing
+    - HID: potential dereference of null pointer
+    - NFSD: Fix READDIR buffer overflow
+    - PM: sleep: Fix error handling in dpm_prepare()
+    - arm64: dts: allwinner: orangepi-zero-plus: fix PHY mode
+    - bus: sunxi-rsb: Fix shutdown
+    - spi: change clk_disable_unprepare to clk_unprepare
+    - ucounts: Fix rlimit max values check
+    - drm/mediatek: hdmi: Perform NULL pointer check for mtk_hdmi_conf
+    - ASoC: meson: aiu: fifo: Add missing dma_coerce_mask_and_coherent()
+    - RDMA/hns: Fix RNR retransmission issue for HIP08
+    - IB/qib: Fix memory leak in qib_user_sdma_queue_pkts()
+    - RDMA/hns: Replace kfree() with kvfree()
+    - netfilter: nf_tables: fix use-after-free in nft_set_catchall_destroy()
+    - netfilter: fix regression in looped (broad|multi)cast's MAC handling
+    - ARM: dts: imx6qdl-wandboard: Fix Ethernet support
+    - ice: Use xdp_buf instead of rx_buf for xsk zero-copy
+    - ice: xsk: return xsk buffers back to pool when cleaning the ring
+    - net: marvell: prestera: fix incorrect return of port_find
+    - net: marvell: prestera: fix incorrect structure access
+    - qlcnic: potential dereference null pointer of rx_queue->page_ring
+    - tcp: move inet->rx_dst_ifindex to sk->sk_rx_dst_ifindex
+    - ipv6: move inet6_sk(sk)->rx_dst_cookie to sk->sk_rx_dst_cookie
+    - inet: fully convert sk->sk_rx_dst to RCU rules
+    - net: accept UFOv6 packages in virtio_net_hdr_to_skb
+    - net: skip virtio_net_hdr_set_proto if protocol already set
+    - igb: fix deadlock caused by taking RTNL in RPM resume path
+    - ipmi: Fix UAF when uninstall ipmi_si and ipmi_msghandler module
+    - gpio: virtio: remove timeout
+    - bonding: fix ad_actor_system option setting to default
+    - fjes: Check for error irq
+    - drivers: net: smc911x: Check for error irq
+    - net: ks8851: Check for error irq
+    - sfc: Check null pointer of rx_queue->page_ring
+    - sfc: falcon: Check null pointer of rx_queue->page_ring
+    - asix: fix uninit-value in asix_mdio_read()
+    - asix: fix wrong return value in asix_check_host_enable()
+    - io_uring: zero iocb->ki_pos for stream file types
+    - veth: ensure skb entering GRO are not cloned.
+    - net: stmmac: ptp: fix potentially overflowing expression
+    - net: bridge: Use array_size() helper in copy_to_user()
+    - net: bridge: fix ioctl old_deviceless bridge argument
+    - r8152: fix the force speed doesn't work for RTL8156
+    - net: stmmac: dwmac-visconti: Fix value of ETHER_CLK_SEL_FREQ_SEL_2P5M
+    - pinctrl: bcm2835: Change init order for gpio hogs
+    - hwmon: (lm90) Fix usage of CONFIG2 register in detect function
+    - hwmon: (lm90) Prevent integer overflow/underflow in hysteresis calculations
+    - hwmon: (lm90) Introduce flag indicating extended temperature support
+    - hwmon: (lm90) Add basic support for TI TMP461
+    - hwmon: (lm90) Drop critical attribute support for MAX6654
+    - ARM: 9160/1: NOMMU: Reload __secondary_data after PROCINFO_INITFUNC
+    - uapi: Fix undefined __always_inline on non-glibc systems
+    - compiler.h: Fix annotation macro misplacement with Clang
+    - platform/x86/intel: Remove X86_PLATFORM_DRIVERS_INTEL
+    - kernel/crash_core: suppress unknown crashkernel parameter warning
+    - Revert "x86/boot: Pull up cmdline preparation and early param parsing"
+    - x86/boot: Move EFI range reservation after cmdline parsing
+    - ALSA: jack: Check the return value of kstrdup()
+    - ALSA: drivers: opl3: Fix incorrect use of vp->state
+    - ALSA: rawmidi - fix the uninitalized user_pversion
+    - ALSA: hda/hdmi: Disable silent stream on GLK
+    - ALSA: hda/realtek: Amp init fixup for HP ZBook 15 G6
+    - ALSA: hda/realtek: Add new alc285-hp-amp-init model
+    - ALSA: hda/realtek: fix mute/micmute LEDs for a HP ProBook
+    - ALSA: hda/realtek: Fix quirk for Clevo NJ51CU
+    - ASoC: meson: aiu: Move AIU_I2S_MISC hold setting to aiu-fifo-i2s
+    - ASoC: tegra: Add DAPM switches for headphones and mic jack
+    - ASoC: tegra: Restore headphones jack name on Nyan Big
+    - Input: atmel_mxt_ts - fix double free in mxt_read_info_block
+    - ipmi: bail out if init_srcu_struct fails
+    - ipmi: ssif: initialize ssif_info->client early
+    - ipmi: fix initialization when workqueue allocation fails
+    - parisc: Correct completer in lws start
+    - parisc: Fix mask used to select futex spinlock
+    - tee: handle lookup of shm with reference count 0
+    - x86/pkey: Fix undefined behaviour with PKRU_WD_BIT
+    - platform/x86: amd-pmc: only use callbacks for suspend
+    - platform/x86: intel_pmc_core: fix memleak on registration failure
+    - KVM: x86: Always set kvm_run->if_flag
+    - KVM: x86/mmu: Don't advance iterator after restart due to yielding
+    - KVM: nVMX: Synthesize TRIPLE_FAULT for L2 if emulation is required
+    - KVM: VMX: Always clear vmx->fail on emulation_required
+    - KVM: VMX: Wake vCPU when delivering posted IRQ even if vCPU == this vCPU
+    - pinctrl: stm32: consider the GPIO offset to expose all the GPIO lines
+    - gpio: dln2: Fix interrupts when replugging the device
+    - mmc: sdhci-tegra: Fix switch to HS400ES mode
+    - mmc: meson-mx-sdhc: Set MANUAL_STOP for multi-block SDIO commands
+    - mmc: core: Disable card detect during shutdown
+    - mmc: mmci: stm32: clear DLYB_CR after sending tuning command
+    - ARM: 9169/1: entry: fix Thumb2 bug in iWMMXt exception handling
+    - ksmbd: fix error code in ndr_read_int32()
+    - ksmbd: fix uninitialized symbol 'pntsd_size'
+    - ksmbd: disable SMB2_GLOBAL_CAP_ENCRYPTION for SMB 3.1.1
+    - mac80211: fix locking in ieee80211_start_ap error path
+    - mm: mempolicy: fix THP allocations escaping mempolicy restrictions
+    - mm, hwpoison: fix condition in free hugetlb page path
+    - mm/hwpoison: clear MF_COUNT_INCREASED before retrying get_any_page()
+    - mm/damon/dbgfs: protect targets destructions with kdamond_lock
+    - tee: optee: Fix incorrect page free bug
+    - f2fs: fix to do sanity check on last xattr entry in __f2fs_setxattr()
+    - netfs: fix parameter of cleanup()
+    - KVM: VMX: Fix stale docs for kvm-intel.emulate_invalid_guest_state
+    - arm64: dts: lx2160a: fix scl-gpios property name
+    - kfence: fix memory leak when cat kfence objects
+    - Input: iqs626a - prohibit inlining of channel parsing functions
+    - Input: elants_i2c - do not check Remark ID on eKTH3900/eKTH5312
+    - Input: goodix - add id->model mapping for the "9111" model
+    - ASoC: tas2770: Fix setting of high sample rates
+    - ASoC: SOF: Intel: pci-tgl: add new ADL-P variant
+    - ASoC: SOF: Intel: pci-tgl: add ADL-N support
+    - ASoC: rt5682: fix the wrong jack type detected
+    - pinctrl: mediatek: fix global-out-of-bounds issue
+    - hwmom: (lm90) Fix citical alarm status for MAX6680/MAX6681
+    - hwmon: (lm90) Do not report 'busy' status bit as alarm
+    - r8152: sync ocp base
+    - ax25: NPD bug when detaching AX25 device
+    - hamradio: defer ax25 kfree after unregister_netdev
+    - hamradio: improve the incomplete fix to avoid NPD
+    - tun: avoid double free in tun_free_netdev
+    - phonet/pep: refuse to enable an unbound pipe
+    - Linux 5.15.12
+
+  * Thinkpad E14 Gen2: Kernel panic with trackpad and trackpoint enabled
+    (LP: #1945590) // Jammy update: v5.15.12 upstream stable release
+    (LP: #1956305)
+    - Input: elantech - fix stack out of bound access in
+      elantech_change_report_id()
+
+  * Jammy update: v5.15.11 upstream stable release (LP: #1956302)
+    - reset: tegra-bpmp: Revert Handle errors in BPMP response
+    - KVM: VMX: clear vmx_x86_ops.sync_pir_to_irr if APICv is disabled
+    - KVM: selftests: Make sure kvm_create_max_vcpus test won't hit RLIMIT_NOFILE
+    - KVM: downgrade two BUG_ONs to WARN_ON_ONCE
+    - x86/kvm: remove unused ack_notifier callbacks
+    - KVM: X86: Fix tlb flush for tdp in kvm_invalidate_pcid()
+    - mac80211: fix rate control for retransmitted frames
+    - mac80211: fix regression in SSN handling of addba tx
+    - mac80211: mark TX-during-stop for TX in in_reconfig
+    - mac80211: send ADDBA requests using the tid/queue of the aggregation session
+    - mac80211: validate extended element ID is present
+    - firmware: arm_scpi: Fix string overflow in SCPI genpd driver
+    - bpf: Fix kernel address leakage in atomic fetch
+    - bpf, selftests: Add test case for atomic fetch on spilled pointer
+    - bpf: Fix signed bounds propagation after mov32
+    - bpf: Make 32->64 bounds propagation slightly more robust
+    - bpf, selftests: Add test case trying to taint map value pointer
+    - bpf: Fix kernel address leakage in atomic cmpxchg's r0 aux reg
+    - bpf, selftests: Update test case for atomic cmpxchg on r0 with pointer
+    - vduse: fix memory corruption in vduse_dev_ioctl()
+    - vduse: check that offset is within bounds in get_config()
+    - virtio_ring: Fix querying of maximum DMA mapping size for virtio device
+    - vdpa: check that offsets are within bounds
+    - s390/entry: fix duplicate tracking of irq nesting level
+    - recordmcount.pl: look for jgnop instruction as well as bcrl on s390
+    - arm64: dts: ten64: remove redundant interrupt declaration for gpio-keys
+    - ceph: fix up non-directory creation in SGID directories
+    - dm btree remove: fix use after free in rebalance_children()
+    - audit: improve robustness of the audit queue handling
+    - btrfs: convert latest_bdev type to btrfs_device and rename
+    - btrfs: use latest_dev in btrfs_show_devname
+    - btrfs: update latest_dev when we create a sprout device
+    - btrfs: remove stale comment about the btrfs_show_devname
+    - scsi: ufs: core: Retry START_STOP on UNIT_ATTENTION
+    - arm64: dts: rockchip: remove mmc-hs400-enhanced-strobe from rk3399-khadas-
+      edge
+    - arm64: dts: rockchip: fix rk3308-roc-cc vcc-sd supply
+    - arm64: dts: rockchip: fix rk3399-leez-p710 vcc3v3-lan supply
+    - arm64: dts: rockchip: fix audio-supply for Rock Pi 4
+    - arm64: dts: rockchip: fix poweroff on helios64
+    - dmaengine: idxd: add halt interrupt support
+    - dmaengine: idxd: fix calling wq quiesce inside spinlock
+    - mac80211: track only QoS data frames for admission control
+    - tee: amdtee: fix an IS_ERR() vs NULL bug
+    - ceph: fix duplicate increment of opened_inodes metric
+    - ceph: initialize pathlen variable in reconnect_caps_cb
+    - ARM: socfpga: dts: fix qspi node compatible
+    - arm64: dts: imx8mq: remove interconnect property from lcdif
+    - clk: Don't parent clks until the parent is fully registered
+    - soc: imx: Register SoC device only on i.MX boards
+    - iwlwifi: mvm: don't crash on invalid rate w/o STA
+    - virtio: always enter drivers/virtio/
+    - virtio/vsock: fix the transport to work with VMADDR_CID_ANY
+    - vdpa: Consider device id larger than 31
+    - Revert "drm/fb-helper: improve DRM fbdev emulation device names"
+    - selftests: net: Correct ping6 expected rc from 2 to 1
+    - s390/kexec_file: fix error handling when applying relocations
+    - sch_cake: do not call cake_destroy() from cake_init()
+    - inet_diag: fix kernel-infoleak for UDP sockets
+    - netdevsim: don't overwrite read only ethtool parms
+    - selftests: icmp_redirect: pass xfail=0 to log_test()
+    - net: hns3: fix use-after-free bug in hclgevf_send_mbx_msg
+    - net: hns3: fix race condition in debugfs
+    - selftests: Add duplicate config only for MD5 VRF tests
+    - selftests: Fix raw socket bind tests with VRF
+    - selftests: Fix IPv6 address bind tests
+    - dmaengine: idxd: fix missed completion on abort path
+    - dmaengine: st_fdma: fix MODULE_ALIAS
+    - drm: simpledrm: fix wrong unit with pixel clock
+    - net/sched: sch_ets: don't remove idle classes from the round-robin list
+    - selftests/net: toeplitz: fix udp option
+    - net: dsa: mv88e6xxx: Unforce speed & duplex in mac_link_down()
+    - selftest/net/forwarding: declare NETIFS p9 p10
+    - mptcp: never allow the PM to close a listener subflow
+    - drm/ast: potential dereference of null pointer
+    - drm/i915/display: Fix an unsigned subtraction which can never be negative.
+    - mac80211: agg-tx: don't schedule_and_wake_txq() under sta->lock
+    - cfg80211: Acquire wiphy mutex on regulatory work
+    - mac80211: fix lookup when adding AddBA extension element
+    - net: stmmac: fix tc flower deletion for VLAN priority Rx steering
+    - flow_offload: return EOPNOTSUPP for the unsupported mpls action type
+    - rds: memory leak in __rds_conn_create()
+    - ice: Use div64_u64 instead of div_u64 in adjfine
+    - ice: Don't put stale timestamps in the skb
+    - drm/amd/display: Set exit_optimized_pwr_state for DCN31
+    - drm/amd/pm: fix a potential gpu_metrics_table memory leak
+    - mptcp: remove tcp ulp setsockopt support
+    - mptcp: clear 'kern' flag from fallback sockets
+    - mptcp: fix deadlock in __mptcp_push_pending()
+    - soc/tegra: fuse: Fix bitwise vs. logical OR warning
+    - igb: Fix removal of unicast MAC filters of VFs
+    - igbvf: fix double free in `igbvf_probe`
+    - igc: Fix typo in i225 LTR functions
+    - ixgbe: Document how to enable NBASE-T support
+    - ixgbe: set X550 MDIO speed before talking to PHY
+    - netdevsim: Zero-initialize memory for new map's value in function
+      nsim_bpf_map_alloc
+    - net/packet: rx_owner_map depends on pg_vec
+    - net: stmmac: dwmac-rk: fix oob read in rk_gmac_setup
+    - sfc_ef100: potential dereference of null pointer
+    - dsa: mv88e6xxx: fix debug print for SPEED_UNFORCED
+    - net: Fix double 0x prefix print in SKB dump
+    - net/smc: Prevent smc_release() from long blocking
+    - net: systemport: Add global locking for descriptor lifecycle
+    - sit: do not call ipip6_dev_free() from sit_init_net()
+    - afs: Fix mmap
+    - arm64: kexec: Fix missing error code 'ret' warning in load_other_segments()
+    - bpf: Fix extable fixup offset.
+    - bpf, selftests: Fix racing issue in btf_skc_cls_ingress test
+    - powerpc/85xx: Fix oops when CONFIG_FSL_PMC=n
+    - USB: gadget: bRequestType is a bitfield, not a enum
+    - Revert "usb: early: convert to readl_poll_timeout_atomic()"
+    - KVM: x86: Drop guest CPUID check for host initiated writes to
+      MSR_IA32_PERF_CAPABILITIES
+    - tty: n_hdlc: make n_hdlc_tty_wakeup() asynchronous
+    - USB: NO_LPM quirk Lenovo USB-C to Ethernet Adapher(RTL8153-04)
+    - usb: dwc2: fix STM ID/VBUS detection startup delay in dwc2_driver_probe
+    - PCI/MSI: Clear PCI_MSIX_FLAGS_MASKALL on error
+    - PCI/MSI: Mask MSI-X vectors only on success
+    - usb: xhci-mtk: fix list_del warning when enable list debug
+    - usb: xhci: Extend support for runtime power management for AMD's Yellow
+      carp.
+    - usb: cdnsp: Fix incorrect status for control request
+    - usb: cdnsp: Fix incorrect calling of cdnsp_died function
+    - usb: cdnsp: Fix issue in cdnsp_log_ep trace event
+    - usb: cdnsp: Fix lack of spin_lock_irqsave/spin_lock_restore
+    - usb: typec: tcpm: fix tcpm unregister port but leave a pending timer
+    - usb: gadget: u_ether: fix race in setting MAC address in setup phase
+    - USB: serial: cp210x: fix CP2105 GPIO registration
+    - USB: serial: option: add Telit FN990 compositions
+    - selinux: fix sleeping function called from invalid context
+    - btrfs: fix memory leak in __add_inode_ref()
+    - btrfs: fix double free of anon_dev after failure to create subvolume
+    - btrfs: check WRITE_ERR when trying to read an extent buffer
+    - btrfs: fix missing blkdev_put() call in btrfs_scan_one_device()
+    - zonefs: add MODULE_ALIAS_FS
+    - iocost: Fix divide-by-zero on donation from low hweight cgroup
+    - serial: 8250_fintek: Fix garbled text for console
+    - timekeeping: Really make sure wall_to_monotonic isn't positive
+    - cifs: sanitize multiple delimiters in prepath
+    - locking/rtmutex: Fix incorrect condition in rtmutex_spin_on_owner()
+    - riscv: dts: unleashed: Add gpio card detect to mmc-spi-slot
+    - riscv: dts: unmatched: Add gpio card detect to mmc-spi-slot
+    - perf inject: Fix segfault due to close without open
+    - perf inject: Fix segfault due to perf_data__fd() without open
+    - libata: if T_LENGTH is zero, dma direction should be DMA_NONE
+    - powerpc/module_64: Fix livepatching for RO modules
+    - drm/amdgpu: correct register access for RLC_JUMP_TABLE_RESTORE
+    - drm/amdgpu: don't override default ECO_BITs setting
+    - drm/amd/pm: fix reading SMU FW version from amdgpu_firmware_info on YC
+    - Revert "can: m_can: remove support for custom bit timing"
+    - can: m_can: make custom bittiming fields const
+    - can: m_can: pci: use custom bit timings for Elkhart Lake
+    - ARM: dts: imx6ull-pinfunc: Fix CSI_DATA07__ESAI_TX0 pad name
+    - xsk: Do not sleep in poll() when need_wakeup set
+    - mptcp: add missing documented NL params
+    - bpf, x64: Factor out emission of REX byte in more cases
+    - bpf: Fix extable address check.
+    - USB: core: Make do_proc_control() and do_proc_bulk() killable
+    - media: mxl111sf: change mutex_init() location
+    - fuse: annotate lock in fuse_reverse_inval_entry()
+    - ovl: fix warning in ovl_create_real()
+    - scsi: scsi_debug: Don't call kcalloc() if size arg is zero
+    - scsi: scsi_debug: Fix type in min_t to avoid stack OOB
+    - scsi: scsi_debug: Sanity check block descriptor length in resp_mode_select()
+    - io-wq: remove spurious bit clear on task_work addition
+    - io-wq: check for wq exit after adding new worker task_work
+    - rcu: Mark accesses to rcu_state.n_force_qs
+    - io-wq: drop wqe lock before creating new worker
+    - bus: ti-sysc: Fix variable set but not used warning for reinit_modules
+    - selftests/damon: test debugfs file reads/writes with huge count
+    - Revert "xsk: Do not sleep in poll() when need_wakeup set"
+    - xen/blkfront: harden blkfront against event channel storms
+    - xen/netfront: harden netfront against event channel storms
+    - xen/console: harden hvc_xen against event channel storms
+    - xen/netback: fix rx queue stall detection
+    - xen/netback: don't queue unlimited number of packages
+    - Linux 5.15.11
+
+  * Jammy update: v5.15.10 upstream stable release (LP: #1956301)
+    - nfc: fix segfault in nfc_genl_dump_devices_done
+    - hwmon: (corsair-psu) fix plain integer used as NULL pointer
+    - RDMA: Fix use-after-free in rxe_queue_cleanup
+    - RDMA/mlx5: Fix releasing unallocated memory in dereg MR flow
+    - mtd: rawnand: Fix nand_erase_op delay
+    - mtd: rawnand: Fix nand_choose_best_timings() on unsupported interface
+    - inet: use #ifdef CONFIG_SOCK_RX_QUEUE_MAPPING consistently
+    - dt-bindings: media: nxp,imx7-mipi-csi2: Drop bad if/then schema
+    - clk: qcom: sm6125-gcc: Swap ops of ice and apps on sdcc1
+    - perf bpf_skel: Do not use typedef to avoid error on old clang
+    - netfs: Fix lockdep warning from taking sb_writers whilst holding mmap_lock
+    - RDMA/irdma: Fix a user-after-free in add_pble_prm
+    - RDMA/irdma: Fix a potential memory allocation issue in
+      'irdma_prm_add_pble_mem()'
+    - RDMA/irdma: Report correct WC errors
+    - RDMA/irdma: Don't arm the CQ more than two times if no CE for this CQ
+    - ice: fix FDIR init missing when reset VF
+    - vmxnet3: fix minimum vectors alloc issue
+    - i2c: virtio: fix completion handling
+    - drm/msm: Fix null ptr access msm_ioctl_gem_submit()
+    - drm/msm/a6xx: Fix uinitialized use of gpu_scid
+    - drm/msm/dsi: set default num_data_lanes
+    - drm/msm/dp: Avoid unpowered AUX xfers that caused crashes
+    - KVM: arm64: Save PSTATE early on exit
+    - s390/test_unwind: use raw opcode instead of invalid instruction
+    - Revert "tty: serial: fsl_lpuart: drop earlycon entry for i.MX8QXP"
+    - net/mlx4_en: Update reported link modes for 1/10G
+    - loop: Use pr_warn_once() for loop_control_remove() warning
+    - ALSA: hda: Add Intel DG2 PCI ID and HDMI codec vid
+    - ALSA: hda/hdmi: fix HDA codec entry table order for ADL-P
+    - parisc/agp: Annotate parisc agp init functions with __init
+    - i2c: rk3x: Handle a spurious start completion interrupt flag
+    - net: netlink: af_netlink: Prevent empty skb by adding a check on len.
+    - drm/amdgpu: cancel the correct hrtimer on exit
+    - drm/amdgpu: check atomic flag to differeniate with legacy path
+    - drm/amd/display: Fix for the no Audio bug with Tiled Displays
+    - drm/amdkfd: fix double free mem structure
+    - drm/amd/display: add connector type check for CRC source set
+    - drm/amdkfd: process_info lock not needed for svm
+    - tracing: Fix a kmemleak false positive in tracing_map
+    - staging: most: dim2: use device release method
+    - fuse: make sure reclaim doesn't write the inode
+    - perf inject: Fix itrace space allowed for new attributes
+    - Linux 5.15.10
+
+  * Jammy update: v5.15.9 upstream stable release (LP: #1955161)
+    - netfilter: selftest: conntrack_vrf.sh: fix file permission
+    - Linux 5.15.9
+
+  * [SRU][I/J/OEM-5.13/OEM-5.14] Fix pci port lost when hotplug dock
+    (LP: #1954646)
+    - PCI: Re-enable Downstream Port LTR after reset or hotplug
+
+  * Add support for NVIDIA EC backlight (LP: #1953286)
+    - platform/x86: Add driver for ACPI WMAA EC-based backlight control
+    - platform/x86: Remove "WMAA" from identifier names in wmaa-backlight-wmi.c
+    - platform/x86: Rename wmaa-backlight-wmi to nvidia-wmi-ec-backlight
+    - [Config] NVIDIA_WMI_EC_BACKLIGHT=m
+
+  * Improve USB Type-C support (LP: #1950974)
+    - usb: typec: ucsi: Always cancel the command if PPM reports BUSY condition
+    - usb: typec: ucsi: Don't stop alt mode registration on busy condition
+    - usb: typec: ucsi: Add polling mechanism for partner tasks like alt mode
+      checking
+    - usb: typec: ucsi: acpi: Reduce the command completion timeout
+    - usb: typec: ucsi: Check the partner alt modes always if there is PD contract
+    - usb: typec: ucsi: Read the PDOs in separate work
+    - usb: typec: ucsi: Better fix for missing unplug events issue
+
+  *  Fix power button wakeup with shared IRQs on AMD platforms (LP: #1953540)
+    - pinctrl: amd: Fix wakeups when IRQ is shared with SCI
+
+  * AMD: Suspend not working when some cores are disabled through cpufreq
+    (LP: #1954930)
+    - ACPI: processor idle: Allow playing dead in C3 state
+
+  * Jammy update: v5.15.8 upstream stable release (LP: #1954931)
+    - Revert "UBUNTU: SAUCE: selftests: fib_tests: assign address to dummy1 for
+      rp_filter tests"
+    - usb: gadget: uvc: fix multiple opens
+    - HID: quirks: Add quirk for the Microsoft Surface 3 type-cover
+    - HID: google: add eel USB id
+    - HID: intel-ish-hid: ipc: only enable IRQ wakeup when requested
+    - HID: add hid_is_usb() function to make it simpler for USB detection
+    - HID: add USB_HID dependancy to hid-prodikeys
+    - HID: add USB_HID dependancy to hid-chicony
+    - HID: add USB_HID dependancy on some USB HID drivers
+    - HID: bigbenff: prevent null pointer dereference
+    - HID: wacom: fix problems when device is not a valid USB device
+    - HID: check for valid USB device for many HID drivers
+    - mtd: dataflash: Add device-tree SPI IDs
+    - mmc: spi: Add device-tree SPI IDs
+    - HID: sony: fix error path in probe
+    - HID: Ignore battery for Elan touchscreen on Asus UX550VE
+    - platform/x86/intel: hid: add quirk to support Surface Go 3
+    - nft_set_pipapo: Fix bucket load in AVX2 lookup routine for six 8-bit groups
+    - IB/hfi1: Insure use of smp_processor_id() is preempt disabled
+    - IB/hfi1: Fix early init panic
+    - IB/hfi1: Fix leak of rcvhdrtail_dummy_kvaddr
+    - can: kvaser_usb: get CAN clock frequency from device
+    - can: kvaser_pciefd: kvaser_pciefd_rx_error_frame(): increase correct
+      stats->{rx,tx}_errors counter
+    - can: sja1000: fix use after free in ems_pcmcia_add_card()
+    - can: pch_can: pch_can_rx_normal: fix use after free
+    - can: m_can: m_can_read_fifo: fix memory leak in error branch
+    - can: m_can: pci: fix incorrect reference clock rate
+    - can: m_can: pci: fix iomap_read_fifo() and iomap_write_fifo()
+    - can: m_can: Disable and ignore ELO interrupt
+    - net: dsa: mv88e6xxx: fix "don't use PHY_DETECT on internal PHY's"
+    - net: dsa: mv88e6xxx: allow use of PHYs on CPU and DSA ports
+    - x86/sme: Explicitly map new EFI memmap table as encrypted
+    - platform/x86: amd-pmc: Fix s2idle failures on certain AMD laptops
+    - nfc: fix potential NULL pointer deref in nfc_genl_dump_ses_done
+    - selftests: netfilter: add a vrf+conntrack testcase
+    - vrf: don't run conntrack on vrf with !dflt qdisc
+    - bpf, x86: Fix "no previous prototype" warning
+    - bpf, sockmap: Attach map progs to psock early for feature probes
+    - bpf: Make sure bpf_disable_instrumentation() is safe vs preemption.
+    - bpf: Fix the off-by-two error in range markings
+    - ice: ignore dropped packets during init
+    - ethtool: do not perform operations on net devices being unregistered
+    - bonding: make tx_rebalance_counter an atomic
+    - nfp: Fix memory leak in nfp_cpp_area_cache_add()
+    - udp: using datalen to cap max gso segments
+    - netfilter: nft_exthdr: break evaluation if setting TCP option fails
+    - netfilter: conntrack: annotate data-races around ct->timeout
+    - iavf: restore MSI state on reset
+    - iavf: Fix reporting when setting descriptor count
+    - IB/hfi1: Correct guard on eager buffer deallocation
+    - devlink: fix netns refcount leak in devlink_nl_cmd_reload()
+    - net: bcm4908: Handle dma_set_coherent_mask error codes
+    - net: dsa: mv88e6xxx: error handling for serdes_power functions
+    - net: dsa: felix: Fix memory leak in felix_setup_mmio_filtering
+    - net/sched: fq_pie: prevent dismantle issue
+    - net: mvpp2: fix XDP rx queues registering
+    - KVM: x86: Don't WARN if userspace mucks with RCX during string I/O exit
+    - KVM: x86: Ignore sparse banks size for an "all CPUs", non-sparse IPI req
+    - KVM: x86: Wait for IPIs to be delivered when handling Hyper-V TLB flush
+      hypercall
+    - timers: implement usleep_idle_range()
+    - mm/damon/core: fix fake load reports due to uninterruptible sleeps
+    - mm/slub: fix endianness bug for alloc/free_traces attributes
+    - mm: bdi: initialize bdi_min_ratio when bdi is unregistered
+    - ALSA: ctl: Fix copy of updated id with element read/write
+    - ALSA: hda/realtek - Add headset Mic support for Lenovo ALC897 platform
+    - ALSA: hda/realtek: Fix quirk for TongFang PHxTxX1
+    - ALSA: pcm: oss: Fix negative period/buffer sizes
+    - ALSA: pcm: oss: Limit the period size to 16MB
+    - ALSA: pcm: oss: Handle missing errors in snd_pcm_oss_change_params*()
+    - cifs: Fix crash on unload of cifs_arc4.ko
+    - scsi: qla2xxx: Format log strings only if needed
+    - btrfs: clear extent buffer uptodate when we fail to write it
+    - btrfs: fix re-dirty process of tree-log nodes
+    - btrfs: replace the BUG_ON in btrfs_del_root_ref with proper error handling
+    - btrfs: free exchange changeset on failures
+    - perf intel-pt: Fix some PGE (packet generation enable/control flow packets)
+      usage
+    - perf intel-pt: Fix sync state when a PSB (synchronization) packet is found
+    - perf intel-pt: Fix intel_pt_fup_event() assumptions about setting state type
+    - perf intel-pt: Fix state setting when receiving overflow (OVF) packet
+    - perf intel-pt: Fix next 'err' value, walking trace
+    - perf intel-pt: Fix missing 'instruction' events with 'q' option
+    - perf intel-pt: Fix error timestamp setting on the decoder error path
+    - md: fix update super 1.0 on rdev size change
+    - nfsd: fix use-after-free due to delegation race
+    - nfsd: Fix nsfd startup race (again)
+    - tracefs: Have new files inherit the ownership of their parent
+    - selftests: KVM: avoid failures due to reserved HyperTransport region
+    - hwmon: (pwm-fan) Ensure the fan going on in .probe()
+    - mmc: renesas_sdhi: initialize variable properly when tuning
+    - clk: qcom: regmap-mux: fix parent clock lookup
+    - thermal: int340x: Fix VCoRefLow MMIO bit offset for TGL
+    - drm/syncobj: Deal with signalled fences in drm_syncobj_find_fence.
+    - libata: add horkage for ASMedia 1092
+    - io_uring: ensure task_work gets run as part of cancelations
+    - wait: add wake_up_pollfree()
+    - binder: use wake_up_pollfree()
+    - signalfd: use wake_up_pollfree()
+    - aio: keep poll requests on waitqueue until completed
+    - aio: fix use-after-free due to missing POLLFREE handling
+    - tracefs: Set all files to the same group ownership as the mount option
+    - i2c: mpc: Use atomic read and fix break condition
+    - block: fix ioprio_get(IOPRIO_WHO_PGRP) vs setuid(2)
+    - scsi: pm80xx: Do not call scsi_remove_host() in pm8001_alloc()
+    - scsi: scsi_debug: Fix buffer size of REPORT ZONES command
+    - ALSA: usb-audio: Reorder snd_djm_devices[] entries
+    - qede: validate non LSO skb length
+    - PM: runtime: Fix pm_runtime_active() kerneldoc comment
+    - ASoC: rt5682: Fix crash due to out of scope stack vars
+    - ASoC: qdsp6: q6routing: Fix return value from msm_routing_put_audio_mixer
+    - ASoC: codecs: wsa881x: fix return values from kcontrol put
+    - ASoC: codecs: wcd934x: handle channel mappping list correctly
+    - ASoC: codecs: wcd934x: return correct value from mixer put
+    - RDMA/hns: Do not halt commands during reset until later
+    - RDMA/hns: Do not destroy QP resources in the hw resetting phase
+    - hwmon: (dell-smm) Fix warning on /proc/i8k creation error
+    - clk: imx: use module_platform_driver
+    - clk: qcom: clk-alpha-pll: Don't reconfigure running Trion
+    - i40e: Fix failed opcode appearing if handling messages from VF
+    - i40e: Fix pre-set max number of queues for VF
+    - mtd: rawnand: fsmc: Take instruction delay into account
+    - mtd: rawnand: fsmc: Fix timing computation
+    - bpf, sockmap: Re-evaluate proto ops when psock is removed from sockmap
+    - i40e: Fix NULL pointer dereference in i40e_dbg_dump_desc
+    - Revert "PCI: aardvark: Fix support for PCI_ROM_ADDRESS1 on emulated bridge"
+    - drm/amd/display: Fix DPIA outbox timeout after S3/S4/reset
+    - perf tools: Fix SMT detection fast read path
+    - Documentation/locking/locktypes: Update migrate_disable() bits.
+    - dt-bindings: net: Reintroduce PHY no lane swap binding
+    - tools build: Remove needless libpython-version feature check that breaks
+      test-all fast path
+    - net: cdc_ncm: Allow for dwNtbOutMaxSize to be unset or zero
+    - net: altera: set a couple error code in probe()
+    - net: fec: only clear interrupt of handling queue in fec_enet_rx_queue()
+    - net, neigh: clear whole pneigh_entry at alloc time
+    - net/qla3xxx: fix an error code in ql_adapter_up()
+    - selftests/fib_tests: Rework fib_rp_filter_test()
+    - USB: gadget: detect too-big endpoint 0 requests
+    - USB: gadget: zero allocate endpoint 0 buffers
+    - Revert "usb: dwc3: dwc3-qcom: Enable tx-fifo-resize property by default"
+    - usb: core: config: fix validation of wMaxPacketValue entries
+    - usb: core: config: using bit mask instead of individual bits
+    - xhci: avoid race between disable slot command and host runtime suspend
+    - iio: gyro: adxrs290: fix data signedness
+    - iio: trigger: Fix reference counting
+    - iio: trigger: stm32-timer: fix MODULE_ALIAS
+    - iio: stk3310: Don't return error code in interrupt handler
+    - iio: mma8452: Fix trigger reference couting
+    - iio: ltr501: Don't return error code in trigger handler
+    - iio: kxsd9: Don't return error code in trigger handler
+    - iio: itg3200: Call iio_trigger_notify_done() on error
+    - iio: dln2-adc: Fix lockdep complaint
+    - iio: dln2: Check return value of devm_iio_trigger_register()
+    - iio: at91-sama5d2: Fix incorrect sign extension
+    - iio: adc: stm32: fix a current leak by resetting pcsel before disabling vdda
+    - iio: adc: axp20x_adc: fix charging current reporting on AXP22x
+    - iio: ad7768-1: Call iio_trigger_notify_done() on error
+    - iio: accel: kxcjk-1013: Fix possible memory leak in probe and remove
+    - nvmem: eeprom: at25: fix FRAM byte_len
+    - bus: mhi: pci_generic: Fix device recovery failed issue
+    - bus: mhi: core: Add support for forced PM resume
+    - csky: fix typo of fpu config macro
+    - irqchip/aspeed-scu: Replace update_bits with write_bits.
+    - irqchip/armada-370-xp: Fix return value of armada_370_xp_msi_alloc()
+    - irqchip/armada-370-xp: Fix support for Multi-MSI interrupts
+    - aio: Fix incorrect usage of eventfd_signal_allowed()
+    - irqchip/irq-gic-v3-its.c: Force synchronisation when issuing INVALL
+    - irqchip: nvic: Fix offset for Interrupt Priority Offsets
+    - misc: fastrpc: fix improper packet size calculation
+    - clocksource/drivers/dw_apb_timer_of: Fix probe failure
+    - bpf: Add selftests to cover packet access corner cases
+    - Linux 5.15.8
+
+  * Can't read/write SD card after running CPU offline test in 5.11.0 and 5.13.0
+    (LP: #1951784) // Jammy update: v5.15.8 upstream stable release
+    (LP: #1954931)
+    - misc: rtsx: Avoid mangling IRQ during runtime PM
+
+  * Enable Landlock by default (LP: #1953192)
+    - [Config] Enable Landlock by default
+
+  * Add s0i3 RTC wake up for AMD systems (LP: #1950013)
+    - platform/x86: amd-pmc: Export Idlemask values based on the APU
+    - platform/x86: amd-pmc: adjust arguments for `amd_pmc_send_cmd`
+    - platform/x86: amd-pmc: Add special handling for timer based S0i3 wakeup
+
+  * Fix runtime power management on USB controller with XHCI_RESET_ON_RESUME
+    flag (LP: #1954369)
+    - SAUCE: xhci: Remove CONFIG_USB_DEFAULT_PERSIST to prevent xHCI from runtime
+      suspending
+
+  * Fix System hangs on black screen when reboot (LP: #1949321)
+    - drm/i915/hdmi: convert intel_hdmi_to_dev to intel_hdmi_to_i915
+    - drm/i915: Don't request GMBUS to generate irqs when called while irqs are
+      off
+    - drm/i915/hdmi: Turn DP++ TMDS output buffers back on in encoder->shutdown()
+
+  * require CAP_NET_ADMIN to attach N_HCI ldisc (LP: #1949516)
+    - Bluetooth: hci_ldisc: require CAP_NET_ADMIN to attach N_HCI ldisc
+
+  * mt7921e: Failed to start WM firmware (LP: #1954300)
+    - SAUCE: Bluetooth: btusb: Handle download_firmware failure cases
+    - SAUCE: Bluetooth: btusb: Return error code when getting patch status failed
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Add list of built-in modules to the ABI
+    - [Packaging] abi-check: Process modules.builtin
+    - SAUCE: allow to use __wake_up_pollfree() from GPL modules
+    - [Packaging] enforce xz compression for debs
+    - [Config] update config after v5.15.12
+    - [Packaging] temporarily disable signed v4l2loopback
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 04 Jan 2022 11:22:10 +0100
+
+linux (5.15.0-14.14) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-14.14 -proposed tracker (LP: #1954627)
+
+  * Jammy update: v5.15.7 upstream stable release (LP: #1953731)
+    - ALSA: usb-audio: Restrict rates for the shared clocks
+    - ALSA: usb-audio: Rename early_playback_start flag with lowlatency_playback
+    - ALSA: usb-audio: Disable low-latency playback for free-wheel mode
+    - ALSA: usb-audio: Disable low-latency mode for implicit feedback sync
+    - ALSA: usb-audio: Check available frames for the next packet size
+    - ALSA: usb-audio: Add spinlock to stop_urbs()
+    - ALSA: usb-audio: Improved lowlatency playback support
+    - ALSA: usb-audio: Avoid killing in-flight URBs during draining
+    - ALSA: usb-audio: Fix packet size calculation regression
+    - ALSA: usb-audio: Less restriction for low-latency playback mode
+    - ALSA: usb-audio: Switch back to non-latency mode at a later point
+    - ALSA: usb-audio: Don't start stream for capture at prepare
+    - gfs2: release iopen glock early in evict
+    - gfs2: Fix length of holes reported at end-of-file
+    - powerpc/pseries/ddw: Revert "Extend upper limit for huge DMA window for
+      persistent memory"
+    - powerpc/pseries/ddw: Do not try direct mapping with persistent memory and
+      one window
+    - drm/sun4i: fix unmet dependency on RESET_CONTROLLER for PHY_SUN6I_MIPI_DPHY
+    - mac80211: do not access the IV when it was stripped
+    - mac80211: fix throughput LED trigger
+    - x86/hyperv: Move required MSRs check to initial platform probing
+    - net/smc: Transfer remaining wait queue entries during fallback
+    - atlantic: Fix OOB read and write in hw_atl_utils_fw_rpc_wait
+    - net: return correct error code
+    - pinctrl: qcom: fix unmet dependencies on GPIOLIB for GPIOLIB_IRQCHIP
+    - platform/x86: dell-wmi-descriptor: disable by default
+    - platform/x86: thinkpad_acpi: Add support for dual fan control
+    - platform/x86: thinkpad_acpi: Fix WWAN device disabled issue after S3 deep
+    - s390/setup: avoid using memblock_enforce_memory_limit
+    - btrfs: silence lockdep when reading chunk tree during mount
+    - btrfs: check-integrity: fix a warning on write caching disabled disk
+    - thermal: core: Reset previous low and high trip during thermal zone init
+    - scsi: iscsi: Unblock session then wake up error handler
+    - drm/amd/pm: Remove artificial freq level on Navi1x
+    - drm/amd/amdkfd: Fix kernel panic when reset failed and been triggered again
+    - drm/amd/amdgpu: fix potential memleak
+    - ata: ahci: Add Green Sardine vendor ID as board_ahci_mobile
+    - ata: libahci: Adjust behavior when StorageD3Enable _DSD is set
+    - ethernet: hisilicon: hns: hns_dsaf_misc: fix a possible array overflow in
+      hns_dsaf_ge_srst_by_port()
+    - ipv6: check return value of ipv6_skip_exthdr
+    - net: tulip: de4x5: fix the problem that the array 'lp->phy[8]' may be out of
+      bound
+    - net: ethernet: dec: tulip: de4x5: fix possible array overflows in
+      type3_infoblock()
+    - perf sort: Fix the 'weight' sort key behavior
+    - perf sort: Fix the 'ins_lat' sort key behavior
+    - perf sort: Fix the 'p_stage_cyc' sort key behavior
+    - perf inject: Fix ARM SPE handling
+    - perf hist: Fix memory leak of a perf_hpp_fmt
+    - perf report: Fix memory leaks around perf_tip()
+    - tracing: Don't use out-of-sync va_list in event printing
+    - net/smc: Avoid warning of possible recursive locking
+    - ACPI: Add stubs for wakeup handler functions
+    - net/tls: Fix authentication failure in CCM mode
+    - vrf: Reset IPCB/IP6CB when processing outbound pkts in vrf dev xmit
+    - kprobes: Limit max data_size of the kretprobe instances
+    - ALSA: hda/cs8409: Set PMSG_ON earlier inside cs8409 driver
+    - rt2x00: do not mark device gone on EPROTO errors during start
+    - ipmi: Move remove_work to dedicated workqueue
+    - cpufreq: Fix get_cpu_device() failure in add_cpu_dev_symlink()
+    - iwlwifi: mvm: retry init flow if failed
+    - dma-buf: system_heap: Use 'for_each_sgtable_sg' in pages free flow
+    - s390/pci: move pseudo-MMIO to prevent MIO overlap
+    - fget: check that the fd still exists after getting a ref to it
+    - sata_fsl: fix UAF in sata_fsl_port_stop when rmmod sata_fsl
+    - sata_fsl: fix warning in remove_proc_entry when rmmod sata_fsl
+    - scsi: lpfc: Fix non-recovery of remote ports following an unsolicited LOGO
+    - scsi: ufs: ufs-pci: Add support for Intel ADL
+    - ipv6: fix memory leak in fib6_rule_suppress
+    - drm/amd/display: Allow DSC on supported MST branch devices
+    - drm/i915/dp: Perform 30ms delay after source OUI write
+    - KVM: fix avic_set_running for preemptable kernels
+    - KVM: Disallow user memslot with size that exceeds "unsigned long"
+    - KVM: x86/mmu: Fix TLB flush range when handling disconnected pt
+    - KVM: Ensure local memslot copies operate on up-to-date arch-specific data
+    - KVM: x86: ignore APICv if LAPIC is not enabled
+    - KVM: nVMX: Emulate guest TLB flush on nested VM-Enter with new vpid12
+    - KVM: nVMX: Flush current VPID (L1 vs. L2) for KVM_REQ_TLB_FLUSH_GUEST
+    - KVM: nVMX: Abide to KVM_REQ_TLB_FLUSH_GUEST request on nested vmentry/vmexit
+    - KVM: VMX: prepare sync_pir_to_irr for running with APICv disabled
+    - KVM: x86: Use a stable condition around all VT-d PI paths
+    - KVM: MMU: shadow nested paging does not have PKU
+    - KVM: arm64: Avoid setting the upper 32 bits of TCR_EL2 and CPTR_EL2 to 1
+    - KVM: X86: Use vcpu->arch.walk_mmu for kvm_mmu_invlpg()
+    - KVM: x86: check PIR even for vCPUs with disabled APICv
+    - tracing/histograms: String compares should not care about signed values
+    - net: dsa: mv88e6xxx: Fix application of erratum 4.8 for 88E6393X
+    - net: dsa: mv88e6xxx: Drop unnecessary check in
+      mv88e6393x_serdes_erratum_4_6()
+    - net: dsa: mv88e6xxx: Save power by disabling SerDes trasmitter and receiver
+    - net: dsa: mv88e6xxx: Add fix for erratum 5.2 of 88E6393X family
+    - net: dsa: mv88e6xxx: Fix inband AN for 2500base-x on 88E6393X family
+    - net: dsa: mv88e6xxx: Link in pcs_get_state() if AN is bypassed
+    - wireguard: selftests: increase default dmesg log size
+    - wireguard: allowedips: add missing __rcu annotation to satisfy sparse
+    - wireguard: selftests: actually test for routing loops
+    - wireguard: selftests: rename DEBUG_PI_LIST to DEBUG_PLIST
+    - wireguard: device: reset peer src endpoint when netns exits
+    - wireguard: receive: use ring buffer for incoming handshakes
+    - wireguard: receive: drop handshakes if queue lock is contended
+    - wireguard: ratelimiter: use kvcalloc() instead of kvzalloc()
+    - i2c: stm32f7: flush TX FIFO upon transfer errors
+    - i2c: stm32f7: recover the bus on access timeout
+    - i2c: stm32f7: stop dma transfer in case of NACK
+    - i2c: cbus-gpio: set atomic transfer callback
+    - natsemi: xtensa: fix section mismatch warnings
+    - tcp: fix page frag corruption on page fault
+    - net: qlogic: qlcnic: Fix a NULL pointer dereference in
+      qlcnic_83xx_add_rings()
+    - net: mpls: Fix notifications when deleting a device
+    - siphash: use _unaligned version by default
+    - arm64: ftrace: add missing BTIs
+    - iwlwifi: fix warnings produced by kernel debug options
+    - net/mlx5e: IPsec: Fix Software parser inner l3 type setting in case of
+      encapsulation
+    - net/mlx4_en: Fix an use-after-free bug in mlx4_en_try_alloc_resources()
+    - selftests: net: Correct case name
+    - net: dsa: b53: Add SPI ID table
+    - mt76: mt7915: fix NULL pointer dereference in mt7915_get_phy_mode
+    - ASoC: tegra: Fix wrong value type in ADMAIF
+    - ASoC: tegra: Fix wrong value type in I2S
+    - ASoC: tegra: Fix wrong value type in DMIC
+    - ASoC: tegra: Fix wrong value type in DSPK
+    - ASoC: tegra: Fix kcontrol put callback in ADMAIF
+    - ASoC: tegra: Fix kcontrol put callback in I2S
+    - ASoC: tegra: Fix kcontrol put callback in DMIC
+    - ASoC: tegra: Fix kcontrol put callback in DSPK
+    - ASoC: tegra: Fix kcontrol put callback in AHUB
+    - rxrpc: Fix rxrpc_peer leak in rxrpc_look_up_bundle()
+    - rxrpc: Fix rxrpc_local leak in rxrpc_lookup_peer()
+    - ALSA: intel-dsp-config: add quirk for CML devices based on ES8336 codec
+    - net: stmmac: Avoid DMA_CHAN_CONTROL write if no Split Header support
+    - net: usb: lan78xx: lan78xx_phy_init(): use PHY_POLL instead of "0" if no IRQ
+      is available
+    - net: marvell: mvpp2: Fix the computation of shared CPUs
+    - dpaa2-eth: destroy workqueue at the end of remove function
+    - octeontx2-af: Fix a memleak bug in rvu_mbox_init()
+    - net: annotate data-races on txq->xmit_lock_owner
+    - ipv4: convert fib_num_tclassid_users to atomic_t
+    - net/smc: fix wrong list_del in smc_lgr_cleanup_early
+    - net/rds: correct socket tunable error in rds_tcp_tune()
+    - net/smc: Keep smc_close_final rc during active close
+    - drm/msm/a6xx: Allocate enough space for GMU registers
+    - drm/msm: Do hw_init() before capturing GPU state
+    - drm/vc4: kms: Wait for the commit before increasing our clock rate
+    - drm/vc4: kms: Fix return code check
+    - drm/vc4: kms: Add missing drm_crtc_commit_put
+    - drm/vc4: kms: Clear the HVS FIFO commit pointer once done
+    - drm/vc4: kms: Don't duplicate pending commit
+    - drm/vc4: kms: Fix previous HVS commit wait
+    - atlantic: Increase delay for fw transactions
+    - atlatnic: enable Nbase-t speeds with base-t
+    - atlantic: Fix to display FW bundle version instead of FW mac version.
+    - atlantic: Add missing DIDs and fix 115c.
+    - Remove Half duplex mode speed capabilities.
+    - atlantic: Fix statistics logic for production hardware
+    - atlantic: Remove warn trace message.
+    - KVM: x86/mmu: Skip tlb flush if it has been done in zap_gfn_range()
+    - KVM: x86/mmu: Pass parameter flush as false in
+      kvm_tdp_mmu_zap_collapsible_sptes()
+    - drm/msm/devfreq: Fix OPP refcnt leak
+    - drm/msm: Fix mmap to include VM_IO and VM_DONTDUMP
+    - drm/msm: Fix wait_fence submitqueue leak
+    - drm/msm: Restore error return on invalid fence
+    - ASoC: rk817: Add module alias for rk817-codec
+    - iwlwifi: Fix memory leaks in error handling path
+    - KVM: X86: Fix when shadow_root_level=5 && guest root_level<4
+    - KVM: SEV: initialize regions_list of a mirror VM
+    - net/mlx5e: Fix missing IPsec statistics on uplink representor
+    - net/mlx5: Move MODIFY_RQT command to ignore list in internal error state
+    - net/mlx5: E-switch, Respect BW share of the new group
+    - net/mlx5: E-Switch, fix single FDB creation on BlueField
+    - net/mlx5: E-Switch, Check group pointer before reading bw_share value
+    - KVM: x86/pmu: Fix reserved bits for AMD PerfEvtSeln register
+    - KVM: VMX: Set failure code in prepare_vmcs02()
+    - mctp: Don't let RTM_DELROUTE delete local routes
+    - Revert "drm/i915: Implement Wa_1508744258"
+    - io-wq: don't retry task_work creation failure on fatal conditions
+    - x86/sev: Fix SEV-ES INS/OUTS instructions for word, dword, and qword
+    - x86/entry: Add a fence for kernel entry SWAPGS in paranoid_entry()
+    - x86/entry: Use the correct fence macro after swapgs in kernel CR3
+    - x86/xen: Add xenpv_restore_regs_and_return_to_usermode()
+    - preempt/dynamic: Fix setup_preempt_mode() return value
+    - sched/uclamp: Fix rq->uclamp_max not set on first enqueue
+    - KVM: SEV: Return appropriate error codes if SEV-ES scratch setup fails
+    - KVM: x86/mmu: Rename slot_handle_leaf to slot_handle_level_4k
+    - KVM: x86/mmu: Remove spurious TLB flushes in TDP MMU zap collapsible path
+    - net/mlx5e: Rename lro_timeout to packet_merge_timeout
+    - net/mlx5e: Rename TIR lro functions to TIR packet merge functions
+    - net/mlx5e: Sync TIR params updates against concurrent create/modify
+    - serial: 8250_bcm7271: UART errors after resuming from S2
+    - parisc: Fix KBUILD_IMAGE for self-extracting kernel
+    - parisc: Fix "make install" on newer debian releases
+    - parisc: Mark cr16 CPU clocksource unstable on all SMP machines
+    - vgacon: Propagate console boot parameters before calling `vc_resize'
+    - xhci: Fix commad ring abort, write all 64 bits to CRCR register.
+    - USB: NO_LPM quirk Lenovo Powered USB-C Travel Hub
+    - usb: typec: tcpm: Wait in SNK_DEBOUNCED until disconnect
+    - usb: cdns3: gadget: fix new urb never complete if ep cancel previous
+      requests
+    - usb: cdnsp: Fix a NULL pointer dereference in cdnsp_endpoint_init()
+    - x86/tsc: Add a timer to make sure TSC_adjust is always checked
+    - x86/tsc: Disable clocksource watchdog for TSC on qualified platorms
+    - x86/64/mm: Map all kernel memory into trampoline_pgd
+    - tty: serial: msm_serial: Deactivate RX DMA for polling support
+    - serial: pl011: Add ACPI SBSA UART match id
+    - serial: tegra: Change lower tolerance baud rate limit for tegra20 and
+      tegra30
+    - serial: core: fix transmit-buffer reset and memleak
+    - serial: 8250_pci: Fix ACCES entries in pci_serial_quirks array
+    - serial: 8250_pci: rewrite pericom_do_set_divisor()
+    - serial: 8250: Fix RTS modem control while in rs485 mode
+    - serial: liteuart: Fix NULL pointer dereference in ->remove()
+    - serial: liteuart: fix use-after-free and memleak on unbind
+    - serial: liteuart: fix minor-number leak on probe errors
+    - ipmi: msghandler: Make symbol 'remove_work_wq' static
+    - Linux 5.15.7
+
+  * Updates to ib_peer_memory requested by Nvidia (LP: #1947206)
+    - SAUCE: RDMA/core: Updated ib_peer_memory
+    - SAUCE: RDMA/core: ib_peer_memory fix build errors
+
+  * Jammy update: v5.15.6 upstream stable release (LP: #1953370)
+    - scsi: sd: Fix sd_do_mode_sense() buffer length handling
+    - ACPI: Get acpi_device's parent from the parent field
+    - ACPI: CPPC: Add NULL pointer check to cppc_get_perf()
+    - USB: serial: pl2303: fix GC type detection
+    - USB: serial: option: add Telit LE910S1 0x9200 composition
+    - USB: serial: option: add Fibocom FM101-GL variants
+    - usb: dwc2: gadget: Fix ISOC flow for elapsed frames
+    - usb: dwc2: hcd_queue: Fix use of floating point literal
+    - usb: dwc3: leave default DMA for PCI devices
+    - usb: dwc3: core: Revise GHWPARAMS9 offset
+    - usb: dwc3: gadget: Ignore NoStream after End Transfer
+    - usb: dwc3: gadget: Check for L1/L2/U3 for Start Transfer
+    - usb: dwc3: gadget: Fix null pointer exception
+    - net: usb: Correct PHY handling of smsc95xx
+    - net: nexthop: fix null pointer dereference when IPv6 is not enabled
+    - usb: chipidea: ci_hdrc_imx: fix potential error pointer dereference in probe
+    - usb: typec: fusb302: Fix masking of comparator and bc_lvl interrupts
+    - usb: xhci: tegra: Check padctrl interrupt presence in device tree
+    - usb: hub: Fix usb enumeration issue due to address0 race
+    - usb: hub: Fix locking issues with address0_mutex
+    - binder: fix test regression due to sender_euid change
+    - ALSA: ctxfi: Fix out-of-range access
+    - ALSA: hda/realtek: Add quirk for ASRock NUC Box 1100
+    - ALSA: hda/realtek: Fix LED on HP ProBook 435 G7
+    - media: cec: copy sequence field for the reply
+    - Revert "parisc: Fix backtrace to always include init funtion names"
+    - HID: wacom: Use "Confidence" flag to prevent reporting invalid contacts
+    - staging/fbtft: Fix backlight
+    - staging: greybus: Add missing rwsem around snd_ctl_remove() calls
+    - staging: rtl8192e: Fix use after free in _rtl92e_pci_disconnect()
+    - staging: r8188eu: Use kzalloc() with GFP_ATOMIC in atomic context
+    - staging: r8188eu: Fix breakage introduced when 5G code was removed
+    - staging: r8188eu: use GFP_ATOMIC under spinlock
+    - staging: r8188eu: fix a memory leak in rtw_wx_read32()
+    - fuse: release pipe buf after last use
+    - xen: don't continue xenstore initialization in case of errors
+    - xen: detect uninitialized xenbus in xenbus_init
+    - io_uring: correct link-list traversal locking
+    - io_uring: fail cancellation for EXITING tasks
+    - io_uring: fix link traversal locking
+    - drm/amdgpu: IH process reset count when restart
+    - drm/amdgpu/pm: fix powerplay OD interface
+    - drm/nouveau: recognise GA106
+    - ksmbd: downgrade addition info error msg to debug in smb2_get_info_sec()
+    - ksmbd: contain default data stream even if xattr is empty
+    - ksmbd: fix memleak in get_file_stream_info()
+    - KVM: PPC: Book3S HV: Prevent POWER7/8 TLB flush flushing SLB
+    - tracing/uprobe: Fix uprobe_perf_open probes iteration
+    - tracing: Fix pid filtering when triggers are attached
+    - mmc: sdhci-esdhc-imx: disable CMDQ support
+    - mmc: sdhci: Fix ADMA for PAGE_SIZE >= 64KiB
+    - mdio: aspeed: Fix "Link is Down" issue
+    - arm64: mm: Fix VM_BUG_ON(mm != &init_mm) for trans_pgd
+    - cpufreq: intel_pstate: Fix active mode offline/online EPP handling
+    - powerpc/32: Fix hardlockup on vmap stack overflow
+    - iomap: Fix inline extent handling in iomap_readpage
+    - NFSv42: Fix pagecache invalidation after COPY/CLONE
+    - PCI: aardvark: Deduplicate code in advk_pcie_rd_conf()
+    - PCI: aardvark: Implement re-issuing config requests on CRS response
+    - PCI: aardvark: Simplify initialization of rootcap on virtual bridge
+    - PCI: aardvark: Fix link training
+    - drm/amd/display: Fix OLED brightness control on eDP
+    - proc/vmcore: fix clearing user buffer by properly using clear_user()
+    - ASoC: SOF: Intel: hda: fix hotplug when only codec is suspended
+    - netfilter: ctnetlink: fix filtering with CTA_TUPLE_REPLY
+    - netfilter: ctnetlink: do not erase error code with EINVAL
+    - netfilter: ipvs: Fix reuse connection if RS weight is 0
+    - netfilter: flowtable: fix IPv6 tunnel addr match
+    - media: v4l2-core: fix VIDIOC_DQEVENT handling on non-x86
+    - firmware: arm_scmi: Fix null de-reference on error path
+    - ARM: dts: BCM5301X: Fix I2C controller interrupt
+    - ARM: dts: BCM5301X: Add interrupt properties to GPIO node
+    - ARM: dts: bcm2711: Fix PCIe interrupts
+    - ASoC: qdsp6: q6routing: Conditionally reset FrontEnd Mixer
+    - ASoC: qdsp6: q6asm: fix q6asm_dai_prepare error handling
+    - ASoC: topology: Add missing rwsem around snd_ctl_remove() calls
+    - ASoC: codecs: wcd938x: fix volatile register range
+    - ASoC: codecs: wcd934x: return error code correctly from hw_params
+    - ASoC: codecs: lpass-rx-macro: fix HPHR setting CLSH mask
+    - net: ieee802154: handle iftypes as u32
+    - firmware: arm_scmi: Fix base agent discover response
+    - firmware: arm_scmi: pm: Propagate return value to caller
+    - ASoC: stm32: i2s: fix 32 bits channel length without mclk
+    - NFSv42: Don't fail clone() unless the OP_CLONE operation failed
+    - ARM: socfpga: Fix crash with CONFIG_FORTIRY_SOURCE
+    - drm/nouveau/acr: fix a couple NULL vs IS_ERR() checks
+    - scsi: qla2xxx: edif: Fix off by one bug in qla_edif_app_getfcinfo()
+    - scsi: mpt3sas: Fix kernel panic during drive powercycle test
+    - scsi: mpt3sas: Fix system going into read-only mode
+    - scsi: mpt3sas: Fix incorrect system timestamp
+    - drm/vc4: fix error code in vc4_create_object()
+    - drm/aspeed: Fix vga_pw sysfs output
+    - net: marvell: prestera: fix brige port operation
+    - net: marvell: prestera: fix double free issue on err path
+    - HID: input: Fix parsing of HID_CP_CONSUMER_CONTROL fields
+    - HID: input: set usage type to key on keycode remap
+    - HID: magicmouse: prevent division by 0 on scroll
+    - iavf: Prevent changing static ITR values if adaptive moderation is on
+    - iavf: Fix refreshing iavf adapter stats on ethtool request
+    - iavf: Fix VLAN feature flags after VFR
+    - x86/pvh: add prototype for xen_pvh_init()
+    - xen/pvh: add missing prototype to header
+    - ALSA: intel-dsp-config: add quirk for JSL devices based on ES8336 codec
+    - mptcp: fix delack timer
+    - mptcp: use delegate action to schedule 3rd ack retrans
+    - af_unix: fix regression in read after shutdown
+    - firmware: smccc: Fix check for ARCH_SOC_ID not implemented
+    - ipv6: fix typos in __ip6_finish_output()
+    - nfp: checking parameter process for rx-usecs/tx-usecs is invalid
+    - net: stmmac: retain PTP clock time during SIOCSHWTSTAMP ioctls
+    - net: ipv6: add fib6_nh_release_dsts stub
+    - net: nexthop: release IPv6 per-cpu dsts when replacing a nexthop group
+    - ice: fix vsi->txq_map sizing
+    - ice: avoid bpf_prog refcount underflow
+    - scsi: core: sysfs: Fix setting device state to SDEV_RUNNING
+    - scsi: scsi_debug: Zero clear zones at reset write pointer
+    - erofs: fix deadlock when shrink erofs slab
+    - i2c: virtio: disable timeout handling
+    - net/smc: Ensure the active closing peer first closes clcsock
+    - mlxsw: spectrum: Protect driver from buggy firmware
+    - net: ipa: directly disable ipa-setup-ready interrupt
+    - net: ipa: separate disabling setup from modem stop
+    - net: ipa: kill ipa_cmd_pipeline_clear()
+    - net: marvell: mvpp2: increase MTU limit when XDP enabled
+    - cpufreq: intel_pstate: Add Ice Lake server to out-of-band IDs
+    - nvmet-tcp: fix incomplete data digest send
+    - drm/hyperv: Fix device removal on Gen1 VMs
+    - arm64: uaccess: avoid blocking within critical sections
+    - net/ncsi : Add payload to be 32-bit aligned to fix dropped packets
+    - PM: hibernate: use correct mode for swsusp_close()
+    - drm/amd/display: Fix DPIA outbox timeout after GPU reset
+    - drm/amd/display: Set plane update flags for all planes in reset
+    - tcp_cubic: fix spurious Hystart ACK train detections for not-cwnd-limited
+      flows
+    - lan743x: fix deadlock in lan743x_phy_link_status_change()
+    - net: phylink: Force link down and retrigger resolve on interface change
+    - net: phylink: Force retrigger in case of latched link-fail indicator
+    - net/smc: Fix NULL pointer dereferencing in smc_vlan_by_tcpsk()
+    - net/smc: Fix loop in smc_listen
+    - nvmet: use IOCB_NOWAIT only if the filesystem supports it
+    - igb: fix netpoll exit with traffic
+    - MIPS: loongson64: fix FTLB configuration
+    - MIPS: use 3-level pgtable for 64KB page size on MIPS_VA_BITS_48
+    - tls: splice_read: fix record type check
+    - tls: splice_read: fix accessing pre-processed records
+    - tls: fix replacing proto_ops
+    - net: stmmac: Disable Tx queues when reconfiguring the interface
+    - net/sched: sch_ets: don't peek at classes beyond 'nbands'
+    - ethtool: ioctl: fix potential NULL deref in ethtool_set_coalesce()
+    - net: vlan: fix underflow for the real_dev refcnt
+    - net/smc: Don't call clcsock shutdown twice when smc shutdown
+    - net: hns3: fix VF RSS failed problem after PF enable multi-TCs
+    - net: hns3: fix incorrect components info of ethtool --reset command
+    - net: mscc: ocelot: don't downgrade timestamping RX filters in SIOCSHWTSTAMP
+    - net: mscc: ocelot: correctly report the timestamping RX filters in ethtool
+    - locking/rwsem: Make handoff bit handling more consistent
+    - perf: Ignore sigtrap for tracepoints destined for other tasks
+    - sched/scs: Reset task stack state in bringup_cpu()
+    - iommu/rockchip: Fix PAGE_DESC_HI_MASKs for RK3568
+    - iommu/vt-d: Fix unmap_pages support
+    - f2fs: quota: fix potential deadlock
+    - f2fs: set SBI_NEED_FSCK flag when inconsistent node block found
+    - riscv: dts: microchip: fix board compatible
+    - riscv: dts: microchip: drop duplicated MMC/SDHC node
+    - cifs: nosharesock should not share socket with future sessions
+    - ceph: properly handle statfs on multifs setups
+    - iommu/amd: Clarify AMD IOMMUv2 initialization messages
+    - vdpa_sim: avoid putting an uninitialized iova_domain
+    - vhost/vsock: fix incorrect used length reported to the guest
+    - ksmbd: Fix an error handling path in 'smb2_sess_setup()'
+    - tracing: Check pid filtering when creating events
+    - cifs: nosharesock should be set on new server
+    - io_uring: fix soft lockup when call __io_remove_buffers
+    - firmware: arm_scmi: Fix type error assignment in voltage protocol
+    - firmware: arm_scmi: Fix type error in sensor protocol
+    - docs: accounting: update delay-accounting.rst reference
+    - blk-mq: cancel blk-mq dispatch work in both blk_cleanup_queue and
+      disk_release()
+    - block: avoid to quiesce queue in elevator_init_mq
+    - drm/amdgpu/gfx10: add wraparound gpu counter check for APUs as well
+    - drm/amdgpu/gfx9: switch to golden tsc registers for renoir+
+    - Linux 5.15.6
+
+  * Fix bogus HDMI audio interface  (LP: #1953208)
+    - ALSA: hda/hdmi: Consider ELD is invalid when no SAD is present
+
+  * Miscellaneous Ubuntu changes
+    - [Config] re-enabled UBSAN without TRAP
+    - SAUCE: ipv6: fix NULL pointer dereference in ip6_output()
+    - SAUCE: RDMA/core: Introduce peer memory interface
+    - [Config] toolchain version update
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] Temporarily disable signing for ppc64el and s390x"
+    - Revert "UBUNTU: SAUCE: vt -- maintain bootloader screen mode and content
+      until vt switch"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 13 Dec 2021 12:13:17 +0100
+
+linux (5.15.0-13.13) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-13.13 -proposed tracker (LP: #1952583)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync update-dkms-versions helper
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Jammy update: v5.15.5 upstream stable release (LP: #1952579)
+    - arm64: zynqmp: Do not duplicate flash partition label property
+    - arm64: zynqmp: Fix serial compatible string
+    - clk: sunxi-ng: Unregister clocks/resets when unbinding
+    - ARM: dts: sunxi: Fix OPPs node name
+    - arm64: dts: allwinner: h5: Fix GPU thermal zone node name
+    - arm64: dts: allwinner: a100: Fix thermal zone node name
+    - staging: wfx: ensure IRQ is ready before enabling it
+    - ARM: dts: BCM5301X: Fix nodes names
+    - ARM: dts: BCM5301X: Fix MDIO mux binding
+    - ARM: dts: NSP: Fix mpcore, mmc node names
+    - arm64: dts: broadcom: bcm4908: Move reboot syscon out of bus
+    - scsi: pm80xx: Fix memory leak during rmmod
+    - scsi: lpfc: Fix list_add() corruption in lpfc_drain_txq()
+    - ASoC: mediatek: mt8195: Add missing of_node_put()
+    - arm64: dts: rockchip: Disable CDN DP on Pinebook Pro
+    - arm64: dts: hisilicon: fix arm,sp805 compatible string
+    - RDMA/bnxt_re: Check if the vlan is valid before reporting
+    - bus: ti-sysc: Add quirk handling for reinit on context lost
+    - bus: ti-sysc: Use context lost quirk for otg
+    - usb: musb: tusb6010: check return value after calling
+      platform_get_resource()
+    - usb: typec: tipd: Remove WARN_ON in tps6598x_block_read
+    - ARM: dts: ux500: Skomer regulator fixes
+    - staging: rtl8723bs: remove possible deadlock when disconnect (v2)
+    - staging: rtl8723bs: remove a second possible deadlock
+    - staging: rtl8723bs: remove a third possible deadlock
+    - ARM: BCM53016: Specify switch ports for Meraki MR32
+    - arm64: dts: qcom: msm8998: Fix CPU/L2 idle state latency and residency
+    - arm64: dts: qcom: ipq6018: Fix qcom,controlled-remotely property
+    - arm64: dts: qcom: ipq8074: Fix qcom,controlled-remotely property
+    - arm64: dts: qcom: sdm845: Fix qcom,controlled-remotely property
+    - arm64: dts: freescale: fix arm,sp805 compatible string
+    - arm64: dts: ls1012a: Add serial alias for ls1012a-rdb
+    - RDMA/rxe: Separate HW and SW l/rkeys
+    - ASoC: SOF: Intel: hda-dai: fix potential locking issue
+    - scsi: core: Fix scsi_mode_sense() buffer length handling
+    - ALSA: usb-audio: disable implicit feedback sync for Behringer UFX1204 and
+      UFX1604
+    - clk: imx: imx6ul: Move csi_sel mux to correct base register
+    - ASoC: es8316: Use IRQF_NO_AUTOEN when requesting the IRQ
+    - ASoC: rt5651: Use IRQF_NO_AUTOEN when requesting the IRQ
+    - ASoC: nau8824: Add DMI quirk mechanism for active-high jack-detect
+    - scsi: advansys: Fix kernel pointer leak
+    - scsi: smartpqi: Add controller handshake during kdump
+    - arm64: dts: imx8mm-kontron: Fix reset delays for ethernet PHY
+    - ALSA: intel-dsp-config: add quirk for APL/GLK/TGL devices based on ES8336
+      codec
+    - ASoC: Intel: soc-acpi: add missing quirk for TGL SDCA single amp
+    - ASoC: Intel: sof_sdw: add missing quirk for Dell SKU 0A45
+    - firmware_loader: fix pre-allocated buf built-in firmware use
+    - HID: multitouch: disable sticky fingers for UPERFECT Y
+    - ALSA: usb-audio: Add support for the Pioneer DJM 750MK2 Mixer/Soundcard
+    - ARM: dts: omap: fix gpmc,mux-add-data type
+    - usb: host: ohci-tmio: check return value after calling
+      platform_get_resource()
+    - ASoC: rt5682: fix a little pop while playback
+    - ARM: dts: ls1021a: move thermal-zones node out of soc/
+    - ARM: dts: ls1021a-tsn: use generic "jedec,spi-nor" compatible for flash
+    - ALSA: ISA: not for M68K
+    - iommu/vt-d: Do not falsely log intel_iommu is unsupported kernel option
+    - tty: tty_buffer: Fix the softlockup issue in flush_to_ldisc
+    - MIPS: sni: Fix the build
+    - scsi: scsi_debug: Fix out-of-bound read in resp_readcap16()
+    - scsi: scsi_debug: Fix out-of-bound read in resp_report_tgtpgs()
+    - scsi: target: Fix ordered tag handling
+    - scsi: target: Fix alua_tg_pt_gps_count tracking
+    - iio: imu: st_lsm6dsx: Avoid potential array overflow in st_lsm6dsx_set_odr()
+    - RDMA/core: Use kvzalloc when allocating the struct ib_port
+    - scsi: lpfc: Fix use-after-free in lpfc_unreg_rpi() routine
+    - scsi: lpfc: Fix link down processing to address NULL pointer dereference
+    - scsi: lpfc: Allow fabric node recovery if recovery is in progress before
+      devloss
+    - memory: tegra20-emc: Add runtime dependency on devfreq governor module
+    - powerpc/5200: dts: fix memory node unit name
+    - ARM: dts: qcom: fix memory and mdio nodes naming for RB3011
+    - arm64: dts: qcom: Fix node name of rpm-msg-ram device nodes
+    - ALSA: gus: fix null pointer dereference on pointer block
+    - ALSA: usb-audio: fix null pointer dereference on pointer cs_desc
+    - clk: at91: sama7g5: remove prescaler part of master clock
+    - iommu/dart: Initialize DART_STREAMS_ENABLE
+    - powerpc/dcr: Use cmplwi instead of 3-argument cmpli
+    - powerpc/8xx: Fix Oops with STRICT_KERNEL_RWX without DEBUG_RODATA_TEST
+    - sh: check return code of request_irq
+    - maple: fix wrong return value of maple_bus_init().
+    - f2fs: fix up f2fs_lookup tracepoints
+    - f2fs: fix to use WHINT_MODE
+    - f2fs: fix wrong condition to trigger background checkpoint correctly
+    - sh: fix kconfig unmet dependency warning for FRAME_POINTER
+    - sh: math-emu: drop unused functions
+    - sh: define __BIG_ENDIAN for math-emu
+    - f2fs: compress: disallow disabling compress on non-empty compressed file
+    - f2fs: fix incorrect return value in f2fs_sanity_check_ckpt()
+    - clk: ingenic: Fix bugs with divided dividers
+    - clk/ast2600: Fix soc revision for AHB
+    - clk: qcom: gcc-msm8996: Drop (again) gcc_aggre1_pnoc_ahb_clk
+    - KVM: arm64: Fix host stage-2 finalization
+    - mips: BCM63XX: ensure that CPU_SUPPORTS_32BIT_KERNEL is set
+    - MIPS: boot/compressed/: add __bswapdi2() to target for ZSTD decompression
+    - sched/core: Mitigate race cpus_share_cache()/update_top_cache_domain()
+    - sched/fair: Prevent dead task groups from regaining cfs_rq's
+    - perf/x86/vlbr: Add c->flags to vlbr event constraints
+    - blkcg: Remove extra blkcg_bio_issue_init
+    - tracing/histogram: Do not copy the fixed-size char array field over the
+      field size
+    - perf bpf: Avoid memory leak from perf_env__insert_btf()
+    - perf bench futex: Fix memory leak of perf_cpu_map__new()
+    - perf tests: Remove bash construct from record+zstd_comp_decomp.sh
+    - drm/nouveau: hdmigv100.c: fix corrupted HDMI Vendor InfoFrame
+    - bpf: Fix inner map state pruning regression.
+    - samples/bpf: Fix summary per-sec stats in xdp_sample_user
+    - samples/bpf: Fix incorrect use of strlen in xdp_redirect_cpu
+    - selftests: net: switch to socat in the GSO GRE test
+    - net/ipa: ipa_resource: Fix wrong for loop range
+    - tcp: Fix uninitialized access in skb frags array for Rx 0cp.
+    - tracing: Add length protection to histogram string copies
+    - nl80211: fix radio statistics in survey dump
+    - mac80211: fix monitor_sdata RCU/locking assertions
+    - net: ipa: HOLB register sometimes must be written twice
+    - net: ipa: disable HOLB drop when updating timer
+    - selftests: gpio: fix gpio compiling error
+    - net: bnx2x: fix variable dereferenced before check
+    - bnxt_en: reject indirect blk offload when hw-tc-offload is off
+    - tipc: only accept encrypted MSG_CRYPTO msgs
+    - sock: fix /proc/net/sockstat underflow in sk_clone_lock()
+    - net/smc: Make sure the link_id is unique
+    - NFSD: Fix exposure in nfsd4_decode_bitmap()
+    - iavf: Fix return of set the new channel count
+    - iavf: check for null in iavf_fix_features
+    - iavf: free q_vectors before queues in iavf_disable_vf
+    - iavf: don't clear a lock we don't hold
+    - iavf: Fix failure to exit out from last all-multicast mode
+    - iavf: prevent accidental free of filter structure
+    - iavf: validate pointers
+    - iavf: Fix for the false positive ASQ/ARQ errors while issuing VF reset
+    - iavf: Fix for setting queues to 0
+    - iavf: Restore VLAN filters after link down
+    - bpf: Fix toctou on read-only map's constant scalar tracking
+    - MIPS: generic/yamon-dt: fix uninitialized variable error
+    - mips: bcm63xx: add support for clk_get_parent()
+    - mips: lantiq: add support for clk_get_parent()
+    - gpio: rockchip: needs GENERIC_IRQ_CHIP to fix build errors
+    - platform/x86: hp_accel: Fix an error handling path in 'lis3lv02d_probe()'
+    - platform/x86: think-lmi: Abort probe on analyze failure
+    - udp: Validate checksum in udp_read_sock()
+    - btrfs: make 1-bit bit-fields of scrub_page unsigned int
+    - RDMA/core: Set send and receive CQ before forwarding to the driver
+    - net/mlx5e: kTLS, Fix crash in RX resync flow
+    - net/mlx5e: Wait for concurrent flow deletion during neigh/fib events
+    - net/mlx5: E-Switch, Fix resetting of encap mode when entering switchdev
+    - net/mlx5e: nullify cq->dbg pointer in mlx5_debug_cq_remove()
+    - net/mlx5: Update error handler for UCTX and UMEM
+    - net/mlx5: E-Switch, rebuild lag only when needed
+    - net/mlx5e: CT, Fix multiple allocations and memleak of mod acts
+    - net/mlx5: Lag, update tracker when state change event received
+    - net/mlx5: E-Switch, return error if encap isn't supported
+    - scsi: ufs: core: Improve SCSI abort handling
+    - scsi: core: sysfs: Fix hang when device state is set via sysfs
+    - scsi: ufs: core: Fix task management completion timeout race
+    - scsi: ufs: core: Fix another task management completion race
+    - net: mvmdio: fix compilation warning
+    - net: sched: act_mirred: drop dst for the direction from egress to ingress
+    - net: dpaa2-eth: fix use-after-free in dpaa2_eth_remove
+    - net: virtio_net_hdr_to_skb: count transport header in UFO
+    - i40e: Fix correct max_pkt_size on VF RX queue
+    - i40e: Fix NULL ptr dereference on VSI filter sync
+    - i40e: Fix changing previously set num_queue_pairs for PFs
+    - i40e: Fix ping is lost after configuring ADq on VF
+    - RDMA/mlx4: Do not fail the registration on port stats
+    - i40e: Fix warning message and call stack during rmmod i40e driver
+    - i40e: Fix creation of first queue by omitting it if is not power of two
+    - i40e: Fix display error code in dmesg
+    - NFC: reorganize the functions in nci_request
+    - NFC: reorder the logic in nfc_{un,}register_device
+    - NFC: add NCI_UNREG flag to eliminate the race
+    - e100: fix device suspend/resume
+    - ptp: ocp: Fix a couple NULL vs IS_ERR() checks
+    - tools build: Fix removal of feature-sync-compare-and-swap feature detection
+    - riscv: fix building external modules
+    - KVM: PPC: Book3S HV: Use GLOBAL_TOC for kvmppc_h_set_dabr/xdabr()
+    - powerpc: clean vdso32 and vdso64 directories
+    - powerpc/pseries: rename numa_dist_table to form2_distances
+    - powerpc/pseries: Fix numa FORM2 parsing fallback code
+    - pinctrl: qcom: sdm845: Enable dual edge errata
+    - pinctrl: qcom: sm8350: Correct UFS and SDC offsets
+    - perf/x86/intel/uncore: Fix filter_tid mask for CHA events on Skylake Server
+    - perf/x86/intel/uncore: Fix IIO event constraints for Skylake Server
+    - perf/x86/intel/uncore: Fix IIO event constraints for Snowridge
+    - s390/kexec: fix return code handling
+    - blk-cgroup: fix missing put device in error path from blkg_conf_pref()
+    - dmaengine: remove debugfs #ifdef
+    - tun: fix bonding active backup with arp monitoring
+    - Revert "mark pstore-blk as broken"
+    - pstore/blk: Use "%lu" to format unsigned long
+    - hexagon: export raw I/O routines for modules
+    - hexagon: clean up timer-regs.h
+    - tipc: check for null after calling kmemdup
+    - ipc: WARN if trying to remove ipc object which is absent
+    - shm: extend forced shm destroy to support objects from several IPC nses
+    - mm: kmemleak: slob: respect SLAB_NOLEAKTRACE flag
+    - hugetlb, userfaultfd: fix reservation restore on userfaultfd error
+    - kmap_local: don't assume kmap PTEs are linear arrays in memory
+    - mm/damon/dbgfs: use '__GFP_NOWARN' for user-specified size buffer allocation
+    - mm/damon/dbgfs: fix missed use of damon_dbgfs_lock
+    - x86/boot: Pull up cmdline preparation and early param parsing
+    - x86/sgx: Fix free page accounting
+    - x86/hyperv: Fix NULL deref in set_hv_tscchange_cb() if Hyper-V setup fails
+    - KVM: x86: Assume a 64-bit hypercall for guests with protected state
+    - KVM: x86: Fix uninitialized eoi_exit_bitmap usage in vcpu_load_eoi_exitmap()
+    - KVM: x86/mmu: include EFER.LMA in extended mmu role
+    - KVM: x86/xen: Fix get_attr of KVM_XEN_ATTR_TYPE_SHARED_INFO
+    - powerpc/signal32: Fix sigset_t copy
+    - powerpc/xive: Change IRQ domain to a tree domain
+    - powerpc/8xx: Fix pinned TLBs with CONFIG_STRICT_KERNEL_RWX
+    - Revert "drm/i915/tgl/dsi: Gate the ddi clocks after pll mapping"
+    - Revert "parisc: Reduce sigreturn trampoline to 3 instructions"
+    - ata: libata: improve ata_read_log_page() error message
+    - ata: libata: add missing ata_identify_page_supported() calls
+    - scsi: qla2xxx: Fix mailbox direction flags in qla2xxx_get_adapter_id()
+    - pinctrl: ralink: include 'ralink_regs.h' in 'pinctrl-mt7620.c'
+    - s390/setup: avoid reserving memory above identity mapping
+    - s390/boot: simplify and fix kernel memory layout setup
+    - s390/vdso: filter out -mstack-guard and -mstack-size
+    - s390/kexec: fix memory leak of ipl report buffer
+    - s390/dump: fix copying to user-space of swapped kdump oldmem
+    - block: Check ADMIN before NICE for IOPRIO_CLASS_RT
+    - fbdev: Prevent probing generic drivers if a FB is already registered
+    - KVM: SEV: Disallow COPY_ENC_CONTEXT_FROM if target has created vCPUs
+    - KVM: nVMX: don't use vcpu->arch.efer when checking host state on nested
+      state load
+    - drm/cma-helper: Release non-coherent memory with dma_free_noncoherent()
+    - printk: restore flushing of NMI buffers on remote CPUs after NMI backtraces
+    - udf: Fix crash after seekdir
+    - spi: fix use-after-free of the add_lock mutex
+    - net: stmmac: socfpga: add runtime suspend/resume callback for stratix10
+      platform
+    - Drivers: hv: balloon: Use VMBUS_RING_SIZE() wrapper for dm_ring_size
+    - btrfs: fix memory ordering between normal and ordered work functions
+    - fs: handle circular mappings correctly
+    - net: stmmac: Fix signed/unsigned wreckage
+    - parisc/sticon: fix reverse colors
+    - cfg80211: call cfg80211_stop_ap when switch from P2P_GO type
+    - mac80211: fix radiotap header generation
+    - mac80211: drop check for DONT_REORDER in __ieee80211_select_queue
+    - drm/amd/display: Update swizzle mode enums
+    - drm/amd/display: Limit max DSC target bpp for specific monitors
+    - drm/i915/guc: Fix outstanding G2H accounting
+    - drm/i915/guc: Don't enable scheduling on a banned context, guc_id invalid,
+      not registered
+    - drm/i915/guc: Workaround reset G2H is received after schedule done G2H
+    - drm/i915/guc: Don't drop ce->guc_active.lock when unwinding context
+    - drm/i915/guc: Unwind context requests in reverse order
+    - drm/udl: fix control-message timeout
+    - drm/prime: Fix use after free in mmap with drm_gem_ttm_mmap
+    - drm/nouveau: Add a dedicated mutex for the clients list
+    - drm/nouveau: use drm_dev_unplug() during device removal
+    - drm/nouveau: clean up all clients on device removal
+    - drm/i915/dp: Ensure sink rate values are always valid
+    - drm/i915/dp: Ensure max link params are always valid
+    - drm/i915: Fix type1 DVI DP dual mode adapter heuristic for modern platforms
+    - drm/amdgpu: fix set scaling mode Full/Full aspect/Center not works on vga
+      and dvi connectors
+    - drm/amd/pm: avoid duplicate powergate/ungate setting
+    - signal: Implement force_fatal_sig
+    - exit/syscall_user_dispatch: Send ordinary signals on failure
+    - signal/powerpc: On swapcontext failure force SIGSEGV
+    - signal/s390: Use force_sigsegv in default_trap_handler
+    - signal/sparc32: Exit with a fatal signal when try_to_clear_window_buffer
+      fails
+    - signal/sparc32: In setup_rt_frame and setup_fram use force_fatal_sig
+    - signal/vm86_32: Properly send SIGSEGV when the vm86 state cannot be saved.
+    - signal/x86: In emulate_vsyscall force a signal instead of calling do_exit
+    - signal: Replace force_sigsegv(SIGSEGV) with force_fatal_sig(SIGSEGV)
+    - signal: Don't always set SA_IMMUTABLE for forced signals
+    - signal: Replace force_fatal_sig with force_exit_sig when in doubt
+    - hugetlbfs: flush TLBs correctly after huge_pmd_unshare
+    - RDMA/netlink: Add __maybe_unused to static inline in C file
+    - bpf: Forbid bpf_ktime_get_coarse_ns and bpf_timer_* in tracing progs
+    - selinux: fix NULL-pointer dereference when hashtab allocation fails
+    - ASoC: DAPM: Cover regression by kctl change notification fix
+    - ASoC: rsnd: fixup DMAEngine API
+    - usb: max-3421: Use driver data instead of maintaining a list of bound
+      devices
+    - ice: Fix VF true promiscuous mode
+    - ice: Delete always true check of PF pointer
+    - fs: export an inode_update_time helper
+    - btrfs: update device path inode time instead of bd_inode
+    - net: add and use skb_unclone_keeptruesize() helper
+    - x86/Kconfig: Fix an unused variable error in dell-smm-hwmon
+    - ALSA: hda: hdac_ext_stream: fix potential locking issues
+    - ALSA: hda: hdac_stream: fix potential locking issue in
+      snd_hdac_stream_assign()
+    - Linux 5.15.5
+
+  * Fix non-working e1000e device after resume (LP: #1951861)
+    - SAUCE: Revert "e1000e: Additional PHY power saving in S0ix"
+    - SAUCE: Revert "e1000e: Add polling mechanism to indicate CSME DPG exit"
+    - SAUCE: Revert "e1000e: Add handshake with the CSME to support S0ix"
+
+  * [SRU][I/OEM-5.13/OEM-5.14] Add MAC passthrough support for more Lenovo docks
+    (LP: #1951767)
+    - net: usb: r8152: Add MAC passthrough support for more Lenovo Docks
+
+  * [amdgpu] USB4 support for DP tunneling (LP: #1951868)
+    - drm/amd/display: Support for DMUB HPD interrupt handling
+    - drm/amd/display: Update link encoder object creation.
+    - drm/amd/display: USB4 DPIA enumeration and AUX Tunneling
+    - drm/amd/display: Support for DMUB HPD and HPD RX interrupt handling
+    - drm/amd/display: Set DPIA link endpoint type
+    - drm/amd/display: Stub out DPIA link training call
+    - drm/amd/display: Add stub to get DPIA tunneling device data
+    - drm/amd/display: Skip DPCD read for DPTX-to-DPIA hop
+    - drm/amd/display: Train DPIA links with fallback
+    - drm/amd/display: Implement DPIA training loop
+    - drm/amd/display: Implement DPIA link configuration
+    - drm/amd/display: Implement DPIA clock recovery phase
+    - drm/amd/display: Implement DPIA equalisation phase
+    - drm/amd/display: Implement end of training for hop in DPIA display path
+    - drm/amd/display: Support for SET_CONFIG processing with DMUB
+    - drm/amd/display: isolate link training setting override to its own function
+    - drm/amd/display: Read USB4 DP tunneling data from DPCD.
+    - drm/amd/display: Add dpia debug options
+    - drm/amd/display: Support for SET_CONFIG processing with DMUB
+    - drm/amd/display: Add DPCD writes at key points
+    - drm/amd/display: Fix DIG_HPD_SELECT for USB4 display endpoints.
+    - drm/amd/display: Add helper for blanking all dp displays
+    - drm/amd/display: Fix link training fallback logic
+    - drm/amd/display: Add debug flags for USB4 DP link training.
+    - drm/amd/display: Fix dynamic link encoder access.
+    - drm/amd/display: Fix concurrent dynamic encoder assignment
+    - drm/amd/display: Fix dynamic encoder reassignment
+    - drm/amd/display: Fix for access for ddc pin and aux engine.
+    - drm/amd/display: Deadlock/HPD Status/Crash Bug Fix
+    - drm/amd/display: Fix USB4 Aux via DMUB terminate unexpectedly
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Rewrite debian/scripts/module-check in Python
+    - [Config] update config and annotations after applying v5.15.5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 29 Nov 2021 09:25:37 +0100
+
+linux (5.15.0-12.12) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-12.12 -proposed tracker (LP: #1951810)
+
+  * Jammy update: v5.15.4 upstream stable release (LP: #1951820)
+    - string: uninline memcpy_and_pad
+    - Revert "drm: fb_helper: improve CONFIG_FB dependency"
+    - Revert "drm: fb_helper: fix CONFIG_FB dependency"
+    - KVM: Fix steal time asm constraints
+    - btrfs: introduce btrfs_is_data_reloc_root
+    - btrfs: zoned: add a dedicated data relocation block group
+    - btrfs: zoned: only allow one process to add pages to a relocation inode
+    - btrfs: zoned: use regular writes for relocation
+    - btrfs: check for relocation inodes on zoned btrfs in should_nocow
+    - btrfs: zoned: allow preallocation for relocation inodes
+    - fortify: Explicitly disable Clang support
+    - block: Add a helper to validate the block size
+    - loop: Use blk_validate_block_size() to validate block size
+    - Bluetooth: btusb: Add support for TP-Link UB500 Adapter
+    - parisc/entry: fix trace test in syscall exit path
+    - PCI/MSI: Deal with devices lying about their MSI mask capability
+    - PCI: Add MSI masking quirk for Nvidia ION AHCI
+    - perf/core: Avoid put_page() when GUP fails
+    - thermal: Fix NULL pointer dereferences in of_thermal_ functions
+    - Revert "ACPI: scan: Release PM resources blocked by unused objects"
+    - Linux 5.15.4
+
+  * Jammy update: v5.15.3 upstream stable release (LP: #1951822)
+    - xhci: Fix USB 3.1 enumeration issues by increasing roothub power-on-good
+      delay
+    - usb: xhci: Enable runtime-pm by default on AMD Yellow Carp platform
+    - Input: iforce - fix control-message timeout
+    - Input: elantench - fix misreporting trackpoint coordinates
+    - Input: i8042 - Add quirk for Fujitsu Lifebook T725
+    - libata: fix read log timeout value
+    - ocfs2: fix data corruption on truncate
+    - scsi: scsi_ioctl: Validate command size
+    - scsi: core: Avoid leaving shost->last_reset with stale value if EH does not
+      run
+    - scsi: core: Remove command size deduction from scsi_setup_scsi_cmnd()
+    - scsi: lpfc: Don't release final kref on Fport node while ABTS outstanding
+    - scsi: lpfc: Fix FCP I/O flush functionality for TMF routines
+    - scsi: qla2xxx: Fix crash in NVMe abort path
+    - scsi: qla2xxx: Fix kernel crash when accessing port_speed sysfs file
+    - scsi: qla2xxx: Fix use after free in eh_abort path
+    - ce/gf100: fix incorrect CE0 address calculation on some GPUs
+    - char: xillybus: fix msg_ep UAF in xillyusb_probe()
+    - mmc: mtk-sd: Add wait dma stop done flow
+    - mmc: dw_mmc: Dont wait for DRTO on Write RSP error
+    - exfat: fix incorrect loading of i_blocks for large files
+    - io-wq: remove worker to owner tw dependency
+    - parisc: Fix set_fixmap() on PA1.x CPUs
+    - parisc: Fix ptrace check on syscall return
+    - tpm: Check for integer overflow in tpm2_map_response_body()
+    - firmware/psci: fix application of sizeof to pointer
+    - crypto: s5p-sss - Add error handling in s5p_aes_probe()
+    - media: rkvdec: Do not override sizeimage for output format
+    - media: ite-cir: IR receiver stop working after receive overflow
+    - media: rkvdec: Support dynamic resolution changes
+    - media: ir-kbd-i2c: improve responsiveness of hauppauge zilog receivers
+    - media: v4l2-ioctl: Fix check_ext_ctrls
+    - ALSA: hda/realtek: Fix mic mute LED for the HP Spectre x360 14
+    - ALSA: hda/realtek: Add a quirk for HP OMEN 15 mute LED
+    - ALSA: hda/realtek: Add quirk for Clevo PC70HS
+    - ALSA: hda/realtek: Headset fixup for Clevo NH77HJQ
+    - ALSA: hda/realtek: Add a quirk for Acer Spin SP513-54N
+    - ALSA: hda/realtek: Add quirk for ASUS UX550VE
+    - ALSA: hda/realtek: Add quirk for HP EliteBook 840 G7 mute LED
+    - ALSA: ua101: fix division by zero at probe
+    - ALSA: 6fire: fix control and bulk message timeouts
+    - ALSA: line6: fix control and interrupt message timeouts
+    - ALSA: mixer: oss: Fix racy access to slots
+    - ALSA: mixer: fix deadlock in snd_mixer_oss_set_volume
+    - ALSA: usb-audio: Line6 HX-Stomp XL USB_ID for 48k-fixed quirk
+    - ALSA: usb-audio: Add registration quirk for JBL Quantum 400
+    - ALSA: hda: Free card instance properly at probe errors
+    - ALSA: synth: missing check for possible NULL after the call to kstrdup
+    - ALSA: pci: rme: Fix unaligned buffer addresses
+    - ALSA: PCM: Fix NULL dereference at mmap checks
+    - ALSA: timer: Fix use-after-free problem
+    - ALSA: timer: Unconditionally unlink slave instances, too
+    - Revert "ext4: enforce buffer head state assertion in ext4_da_map_blocks"
+    - ext4: fix lazy initialization next schedule time computation in more
+      granular unit
+    - ext4: ensure enough credits in ext4_ext_shift_path_extents
+    - ext4: refresh the ext4_ext_path struct after dropping i_data_sem.
+    - fuse: fix page stealing
+    - x86/sme: Use #define USE_EARLY_PGTABLE_L5 in mem_encrypt_identity.c
+    - x86/cpu: Fix migration safety with X86_BUG_NULL_SEL
+    - x86/irq: Ensure PI wakeup handler is unregistered before module unload
+    - x86/iopl: Fake iopl(3) CLI/STI usage
+    - btrfs: clear MISSING device status bit in btrfs_close_one_device
+    - btrfs: fix lost error handling when replaying directory deletes
+    - btrfs: call btrfs_check_rw_degradable only if there is a missing device
+    - KVM: x86/mmu: Drop a redundant, broken remote TLB flush
+    - KVM: VMX: Unregister posted interrupt wakeup handler on hardware unsetup
+    - KVM: PPC: Tick accounting should defer vtime accounting 'til after IRQ
+      handling
+    - ia64: kprobes: Fix to pass correct trampoline address to the handler
+    - selinux: fix race condition when computing ocontext SIDs
+    - ipmi:watchdog: Set panic count to proper value on a panic
+    - md/raid1: only allocate write behind bio for WriteMostly device
+    - hwmon: (pmbus/lm25066) Add offset coefficients
+    - regulator: s5m8767: do not use reset value as DVS voltage if GPIO DVS is
+      disabled
+    - regulator: dt-bindings: samsung,s5m8767: correct s5m8767,pmic-buck-default-
+      dvs-idx property
+    - EDAC/sb_edac: Fix top-of-high-memory value for Broadwell/Haswell
+    - mwifiex: fix division by zero in fw download path
+    - ath6kl: fix division by zero in send path
+    - ath6kl: fix control-message timeout
+    - ath10k: fix control-message timeout
+    - ath10k: fix division by zero in send path
+    - PCI: Mark Atheros QCA6174 to avoid bus reset
+    - rtl8187: fix control-message timeouts
+    - evm: mark evm_fixmode as __ro_after_init
+    - ifb: Depend on netfilter alternatively to tc
+    - platform/surface: aggregator_registry: Add support for Surface Laptop Studio
+    - mt76: mt7615: fix skb use-after-free on mac reset
+    - HID: surface-hid: Use correct event registry for managing HID events
+    - HID: surface-hid: Allow driver matching for target ID 1 devices
+    - wcn36xx: Fix HT40 capability for 2Ghz band
+    - wcn36xx: Fix tx_status mechanism
+    - wcn36xx: Fix (QoS) null data frame bitrate/modulation
+    - PM: sleep: Do not let "syscore" devices runtime-suspend during system
+      transitions
+    - mwifiex: Read a PCI register after writing the TX ring write pointer
+    - mwifiex: Try waking the firmware until we get an interrupt
+    - libata: fix checking of DMA state
+    - dma-buf: fix and rework dma_buf_poll v7
+    - wcn36xx: handle connection loss indication
+    - rsi: fix occasional initialisation failure with BT coex
+    - rsi: fix key enabled check causing unwanted encryption for vap_id > 0
+    - rsi: fix rate mask set leading to P2P failure
+    - rsi: Fix module dev_oper_mode parameter description
+    - perf/x86/intel/uncore: Support extra IMC channel on Ice Lake server
+    - perf/x86/intel/uncore: Fix invalid unit check
+    - perf/x86/intel/uncore: Fix Intel ICX IIO event constraints
+    - RDMA/qedr: Fix NULL deref for query_qp on the GSI QP
+    - ASoC: tegra: Set default card name for Trimslice
+    - ASoC: tegra: Restore AC97 support
+    - signal: Remove the bogus sigkill_pending in ptrace_stop
+    - memory: renesas-rpc-if: Correct QSPI data transfer in Manual mode
+    - signal/mips: Update (_save|_restore)_fp_context to fail with -EFAULT
+    - soc: samsung: exynos-pmu: Fix compilation when nothing selects
+      CONFIG_MFD_CORE
+    - soc: fsl: dpio: replace smp_processor_id with raw_smp_processor_id
+    - soc: fsl: dpio: use the combined functions to protect critical zone
+    - mtd: rawnand: socrates: Keep the driver compatible with on-die ECC engines
+    - mctp: handle the struct sockaddr_mctp padding fields
+    - power: supply: max17042_battery: Prevent int underflow in set_soc_threshold
+    - power: supply: max17042_battery: use VFSOC for capacity when no rsns
+    - iio: core: fix double free in iio_device_unregister_sysfs()
+    - iio: core: check return value when calling dev_set_name()
+    - KVM: arm64: Extract ESR_ELx.EC only
+    - KVM: x86: Fix recording of guest steal time / preempted status
+    - KVM: x86: Add helper to consolidate core logic of SET_CPUID{2} flows
+    - KVM: nVMX: Query current VMCS when determining if MSR bitmaps are in use
+    - KVM: nVMX: Handle dynamic MSR intercept toggling
+    - can: peak_usb: always ask for BERR reporting for PCAN-USB devices
+    - can: mcp251xfd: mcp251xfd_irq(): add missing
+      can_rx_offload_threaded_irq_finish() in case of bus off
+    - can: j1939: j1939_tp_cmd_recv(): ignore abort message in the BAM transport
+    - can: j1939: j1939_can_recv(): ignore messages with invalid source address
+    - can: j1939: j1939_tp_cmd_recv(): check the dst address of TP.CM_BAM
+    - iio: adc: tsc2046: fix scan interval warning
+    - powerpc/85xx: Fix oops when mpc85xx_smp_guts_ids node cannot be found
+    - io_uring: honour zeroes as io-wq worker limits
+    - ring-buffer: Protect ring_buffer_reset() from reentrancy
+    - serial: core: Fix initializing and restoring termios speed
+    - ifb: fix building without CONFIG_NET_CLS_ACT
+    - xen/balloon: add late_initcall_sync() for initial ballooning done
+    - ovl: fix use after free in struct ovl_aio_req
+    - ovl: fix filattr copy-up failure
+    - PCI: pci-bridge-emul: Fix emulation of W1C bits
+    - PCI: cadence: Add cdns_plat_pcie_probe() missing return
+    - cxl/pci: Fix NULL vs ERR_PTR confusion
+    - PCI: aardvark: Do not clear status bits of masked interrupts
+    - PCI: aardvark: Fix checking for link up via LTSSM state
+    - PCI: aardvark: Do not unmask unused interrupts
+    - PCI: aardvark: Fix reporting Data Link Layer Link Active
+    - PCI: aardvark: Fix configuring Reference clock
+    - PCI: aardvark: Fix return value of MSI domain .alloc() method
+    - PCI: aardvark: Read all 16-bits from PCIE_MSI_PAYLOAD_REG
+    - PCI: aardvark: Fix support for bus mastering and PCI_COMMAND on emulated
+      bridge
+    - PCI: aardvark: Fix support for PCI_BRIDGE_CTL_BUS_RESET on emulated bridge
+    - PCI: aardvark: Set PCI Bridge Class Code to PCI Bridge
+    - PCI: aardvark: Fix support for PCI_ROM_ADDRESS1 on emulated bridge
+    - quota: check block number when reading the block in quota file
+    - quota: correct error number in free_dqentry()
+    - cifs: To match file servers, make sure the server hostname matches
+    - cifs: set a minimum of 120s for next dns resolution
+    - mfd: simple-mfd-i2c: Select MFD_CORE to fix build error
+    - pinctrl: core: fix possible memory leak in pinctrl_enable()
+    - coresight: cti: Correct the parameter for pm_runtime_put
+    - coresight: trbe: Fix incorrect access of the sink specific data
+    - coresight: trbe: Defer the probe on offline CPUs
+    - iio: buffer: check return value of kstrdup_const()
+    - iio: buffer: Fix memory leak in iio_buffers_alloc_sysfs_and_mask()
+    - iio: buffer: Fix memory leak in __iio_buffer_alloc_sysfs_and_mask()
+    - iio: buffer: Fix memory leak in iio_buffer_register_legacy_sysfs_groups()
+    - drivers: iio: dac: ad5766: Fix dt property name
+    - iio: dac: ad5446: Fix ad5622_write() return value
+    - iio: ad5770r: make devicetree property reading consistent
+    - Documentation:devicetree:bindings:iio:dac: Fix val
+    - USB: serial: keyspan: fix memleak on probe errors
+    - serial: 8250: fix racy uartclk update
+    - ksmbd: set unique value to volume serial field in FS_VOLUME_INFORMATION
+    - io-wq: serialize hash clear with wakeup
+    - serial: 8250: Fix reporting real baudrate value in c_ospeed field
+    - Revert "serial: 8250: Fix reporting real baudrate value in c_ospeed field"
+    - most: fix control-message timeouts
+    - USB: iowarrior: fix control-message timeouts
+    - USB: chipidea: fix interrupt deadlock
+    - power: supply: max17042_battery: Clear status bits in interrupt handler
+    - component: do not leave master devres group open after bind
+    - dma-buf: WARN on dmabuf release with pending attachments
+    - drm: panel-orientation-quirks: Update the Lenovo Ideapad D330 quirk (v2)
+    - drm: panel-orientation-quirks: Add quirk for KD Kurio Smart C15200 2-in-1
+    - drm: panel-orientation-quirks: Add quirk for the Samsung Galaxy Book 10.6
+    - Bluetooth: sco: Fix lock_sock() blockage by memcpy_from_msg()
+    - Bluetooth: fix use-after-free error in lock_sock_nested()
+    - Bluetooth: call sock_hold earlier in sco_conn_del
+    - drm/panel-orientation-quirks: add Valve Steam Deck
+    - rcutorture: Avoid problematic critical section nesting on PREEMPT_RT
+    - platform/x86: wmi: do not fail if disabling fails
+    - drm/amdgpu: move iommu_resume before ip init/resume
+    - MIPS: lantiq: dma: add small delay after reset
+    - MIPS: lantiq: dma: reset correct number of channel
+    - locking/lockdep: Avoid RCU-induced noinstr fail
+    - net: sched: update default qdisc visibility after Tx queue cnt changes
+    - rcu-tasks: Move RTGS_WAIT_CBS to beginning of rcu_tasks_kthread() loop
+    - smackfs: Fix use-after-free in netlbl_catmap_walk()
+    - ath11k: Align bss_chan_info structure with firmware
+    - crypto: aesni - check walk.nbytes instead of err
+    - x86/mm/64: Improve stack overflow warnings
+    - x86: Increase exception stack sizes
+    - mwifiex: Run SET_BSS_MODE when changing from P2P to STATION vif-type
+    - mwifiex: Properly initialize private structure on interface type changes
+    - spi: Check we have a spi_device_id for each DT compatible
+    - fscrypt: allow 256-bit master keys with AES-256-XTS
+    - drm/amdgpu: Fix MMIO access page fault
+    - drm/amd/display: Fix null pointer dereference for encoders
+    - selftests: net: fib_nexthops: Wait before checking reported idle time
+    - ath11k: Avoid reg rules update during firmware recovery
+    - ath11k: add handler for scan event WMI_SCAN_EVENT_DEQUEUED
+    - ath11k: Change DMA_FROM_DEVICE to DMA_TO_DEVICE when map reinjected packets
+    - ath10k: high latency fixes for beacon buffer
+    - octeontx2-pf: Enable promisc/allmulti match MCAM entries.
+    - media: mt9p031: Fix corrupted frame after restarting stream
+    - media: netup_unidvb: handle interrupt properly according to the firmware
+    - media: atomisp: Fix error handling in probe
+    - media: stm32: Potential NULL pointer dereference in dcmi_irq_thread()
+    - media: uvcvideo: Set capability in s_param
+    - media: uvcvideo: Return -EIO for control errors
+    - media: uvcvideo: Set unique vdev name based in type
+    - media: vidtv: Fix memory leak in remove
+    - media: s5p-mfc: fix possible null-pointer dereference in s5p_mfc_probe()
+    - media: s5p-mfc: Add checking to s5p_mfc_probe().
+    - media: videobuf2: rework vb2_mem_ops API
+    - media: imx: set a media_device bus_info string
+    - media: rcar-vin: Use user provided buffers when starting
+    - media: mceusb: return without resubmitting URB in case of -EPROTO error.
+    - ia64: don't do IA64_CMPXCHG_DEBUG without CONFIG_PRINTK
+    - rtw88: fix RX clock gate setting while fifo dump
+    - brcmfmac: Add DMI nvram filename quirk for Cyberbook T116 tablet
+    - media: rcar-csi2: Add checking to rcsi2_start_receiver()
+    - ipmi: Disable some operations during a panic
+    - fs/proc/uptime.c: Fix idle time reporting in /proc/uptime
+    - kselftests/sched: cleanup the child processes
+    - ACPICA: Avoid evaluating methods too early during system resume
+    - cpufreq: Make policy min/max hard requirements
+    - ice: Move devlink port to PF/VF struct
+    - media: imx-jpeg: Fix possible null pointer dereference
+    - media: ipu3-imgu: imgu_fmt: Handle properly try
+    - media: ipu3-imgu: VIDIOC_QUERYCAP: Fix bus_info
+    - media: usb: dvd-usb: fix uninit-value bug in dibusb_read_eeprom_byte()
+    - net-sysfs: try not to restart the syscall if it will fail eventually
+    - drm/amdkfd: rm BO resv on validation to avoid deadlock
+    - tracefs: Have tracefs directories not set OTH permission bits by default
+    - tracing: Disable "other" permission bits in the tracefs files
+    - ath: dfs_pattern_detector: Fix possible null-pointer dereference in
+      channel_detector_create()
+    - KVM: arm64: Propagate errors from __pkvm_prot_finalize hypercall
+    - mmc: moxart: Fix reference count leaks in moxart_probe
+    - iov_iter: Fix iov_iter_get_pages{,_alloc} page fault return value
+    - ACPI: battery: Accept charges over the design capacity as full
+    - ACPI: scan: Release PM resources blocked by unused objects
+    - drm/amd/display: fix null pointer deref when plugging in display
+    - drm/amdkfd: fix resume error when iommu disabled in Picasso
+    - net: phy: micrel: make *-skew-ps check more lenient
+    - leaking_addresses: Always print a trailing newline
+    - thermal/core: Fix null pointer dereference in thermal_release()
+    - drm/msm: prevent NULL dereference in msm_gpu_crashstate_capture()
+    - thermal/drivers/tsens: Add timeout to get_temp_tsens_valid
+    - block: bump max plugged deferred size from 16 to 32
+    - floppy: fix calling platform_device_unregister() on invalid drives
+    - md: update superblock after changing rdev flags in state_store
+    - memstick: r592: Fix a UAF bug when removing the driver
+    - locking/rwsem: Disable preemption for spinning region
+    - lib/xz: Avoid overlapping memcpy() with invalid input with in-place
+      decompression
+    - lib/xz: Validate the value before assigning it to an enum variable
+    - workqueue: make sysfs of unbound kworker cpumask more clever
+    - tracing/cfi: Fix cmp_entries_* functions signature mismatch
+    - mt76: mt7915: fix an off-by-one bound check
+    - mwl8k: Fix use-after-free in mwl8k_fw_state_machine()
+    - iwlwifi: change all JnP to NO-160 configuration
+    - block: remove inaccurate requeue check
+    - media: allegro: ignore interrupt if mailbox is not initialized
+    - drm/amdgpu/pm: properly handle sclk for profiling modes on vangogh
+    - nvmet: fix use-after-free when a port is removed
+    - nvmet-rdma: fix use-after-free when a port is removed
+    - nvmet-tcp: fix use-after-free when a port is removed
+    - nvme: drop scan_lock and always kick requeue list when removing namespaces
+    - samples/bpf: Fix application of sizeof to pointer
+    - arm64: vdso32: suppress error message for 'make mrproper'
+    - PM: hibernate: Get block device exclusively in swsusp_check()
+    - selftests: kvm: fix mismatched fclose() after popen()
+    - selftests/bpf: Fix perf_buffer test on system with offline cpus
+    - iwlwifi: mvm: disable RX-diversity in powersave
+    - smackfs: use __GFP_NOFAIL for smk_cipso_doi()
+    - ARM: clang: Do not rely on lr register for stacktrace
+    - gre/sit: Don't generate link-local addr if addr_gen_mode is
+      IN6_ADDR_GEN_MODE_NONE
+    - can: bittiming: can_fixup_bittiming(): change type of tseg1 and alltseg to
+      unsigned int
+    - gfs2: Cancel remote delete work asynchronously
+    - gfs2: Fix glock_hash_walk bugs
+    - ARM: 9136/1: ARMv7-M uses BE-8, not BE-32
+    - tools/latency-collector: Use correct size when writing queue_full_warning
+    - vrf: run conntrack only in context of lower/physdev for locally generated
+      packets
+    - net: annotate data-race in neigh_output()
+    - ACPI: AC: Quirk GK45 to skip reading _PSR
+    - ACPI: resources: Add one more Medion model in IRQ override quirk
+    - btrfs: reflink: initialize return value to 0 in btrfs_extent_same()
+    - btrfs: do not take the uuid_mutex in btrfs_rm_device
+    - spi: bcm-qspi: Fix missing clk_disable_unprepare() on error in
+      bcm_qspi_probe()
+    - wcn36xx: Correct band/freq reporting on RX
+    - wcn36xx: Fix packet drop on resume
+    - Revert "wcn36xx: Enable firmware link monitoring"
+    - ftrace: do CPU checking after preemption disabled
+    - inet: remove races in inet{6}_getname()
+    - x86/hyperv: Protect set_hv_tscchange_cb() against getting preempted
+    - drm/amd/display: dcn20_resource_construct reduce scope of FPU enabled
+    - perf/x86/intel: Fix ICL/SPR INST_RETIRED.PREC_DIST encodings
+    - parisc: fix warning in flush_tlb_all
+    - task_stack: Fix end_of_stack() for architectures with upwards-growing stack
+    - erofs: don't trigger WARN() when decompression fails
+    - parisc/unwind: fix unwinder when CONFIG_64BIT is enabled
+    - parisc/kgdb: add kgdb_roundup() to make kgdb work with idle polling
+    - netfilter: conntrack: set on IPS_ASSURED if flows enters internal stream
+      state
+    - selftests/bpf: Fix strobemeta selftest regression
+    - fbdev/efifb: Release PCI device's runtime PM ref during FB destroy
+    - drm/bridge: anx7625: Propagate errors from sp_tx_rst_aux()
+    - perf/x86/intel/uncore: Fix Intel SPR CHA event constraints
+    - perf/x86/intel/uncore: Fix Intel SPR IIO event constraints
+    - perf/x86/intel/uncore: Fix Intel SPR M2PCIE event constraints
+    - perf/x86/intel/uncore: Fix Intel SPR M3UPI event constraints
+    - drm/bridge: it66121: Initialize {device,vendor}_ids
+    - drm/bridge: it66121: Wait for next bridge to be probed
+    - Bluetooth: fix init and cleanup of sco_conn.timeout_work
+    - libbpf: Don't crash on object files with no symbol tables
+    - Bluetooth: hci_uart: fix GPF in h5_recv
+    - rcu: Fix existing exp request check in sync_sched_exp_online_cleanup()
+    - MIPS: lantiq: dma: fix burst length for DEU
+    - x86/xen: Mark cpu_bringup_and_idle() as dead_end_function
+    - objtool: Handle __sanitize_cov*() tail calls
+    - net/mlx5: Publish and unpublish all devlink parameters at once
+    - drm/v3d: fix wait for TMU write combiner flush
+    - crypto: sm4 - Do not change section of ck and sbox
+    - virtio-gpu: fix possible memory allocation failure
+    - lockdep: Let lock_is_held_type() detect recursive read as read
+    - net: net_namespace: Fix undefined member in key_remove_domain()
+    - net: phylink: don't call netif_carrier_off() with NULL netdev
+    - drm: bridge: it66121: Fix return value it66121_probe
+    - spi: Fixed division by zero warning
+    - cgroup: Make rebind_subsystems() disable v2 controllers all at once
+    - wcn36xx: Fix Antenna Diversity Switching
+    - wilc1000: fix possible memory leak in cfg_scan_result()
+    - Bluetooth: btmtkuart: fix a memleak in mtk_hci_wmt_sync
+    - drm/amdgpu: Fix crash on device remove/driver unload
+    - drm/amd/display: Pass display_pipe_params_st as const in DML
+    - drm/amdgpu: move amdgpu_virt_release_full_gpu to fini_early stage
+    - crypto: caam - disable pkc for non-E SoCs
+    - crypto: qat - power up 4xxx device
+    - Bluetooth: hci_h5: Fix (runtime)suspend issues on RTL8723BS HCIs
+    - bnxt_en: Check devlink allocation and registration status
+    - qed: Don't ignore devlink allocation failures
+    - rxrpc: Fix _usecs_to_jiffies() by using usecs_to_jiffies()
+    - mptcp: do not shrink snd_nxt when recovering
+    - fortify: Fix dropped strcpy() compile-time write overflow check
+    - mac80211: twt: don't use potentially unaligned pointer
+    - cfg80211: always free wiphy specific regdomain
+    - net/mlx5: Accept devlink user input after driver initialization complete
+    - net: dsa: rtl8366rb: Fix off-by-one bug
+    - net: dsa: rtl8366: Fix a bug in deleting VLANs
+    - bpf/tests: Fix error in tail call limit tests
+    - ath11k: fix some sleeping in atomic bugs
+    - ath11k: Avoid race during regd updates
+    - ath11k: fix packet drops due to incorrect 6 GHz freq value in rx status
+    - ath11k: Fix memory leak in ath11k_qmi_driver_event_work
+    - gve: DQO: avoid unused variable warnings
+    - ath10k: Fix missing frame timestamp for beacon/probe-resp
+    - ath10k: sdio: Add missing BH locking around napi_schdule()
+    - drm/ttm: stop calling tt_swapin in vm_access
+    - arm64: mm: update max_pfn after memory hotplug
+    - drm/amdgpu: fix warning for overflow check
+    - libbpf: Fix skel_internal.h to set errno on loader retval < 0
+    - media: em28xx: add missing em28xx_close_extension
+    - media: meson-ge2d: Fix rotation parameter changes detection in
+      'ge2d_s_ctrl()'
+    - media: cxd2880-spi: Fix a null pointer dereference on error handling path
+    - media: ttusb-dec: avoid release of non-acquired mutex
+    - media: dvb-usb: fix ununit-value in az6027_rc_query
+    - media: imx258: Fix getting clock frequency
+    - media: v4l2-ioctl: S_CTRL output the right value
+    - media: mtk-vcodec: venc: fix return value when start_streaming fails
+    - media: TDA1997x: handle short reads of hdmi info frame.
+    - media: mtk-vpu: Fix a resource leak in the error handling path of
+      'mtk_vpu_probe()'
+    - media: imx-jpeg: Fix the error handling path of 'mxc_jpeg_probe()'
+    - media: i2c: ths8200 needs V4L2_ASYNC
+    - media: sun6i-csi: Allow the video device to be open multiple times
+    - media: radio-wl1273: Avoid card name truncation
+    - media: si470x: Avoid card name truncation
+    - media: tm6000: Avoid card name truncation
+    - media: cx23885: Fix snd_card_free call on null card pointer
+    - media: atmel: fix the ispck initialization
+    - scs: Release kasan vmalloc poison in scs_free process
+    - kprobes: Do not use local variable when creating debugfs file
+    - crypto: ecc - fix CRYPTO_DEFAULT_RNG dependency
+    - drm: fb_helper: fix CONFIG_FB dependency
+    - cpuidle: Fix kobject memory leaks in error paths
+    - media: em28xx: Don't use ops->suspend if it is NULL
+    - ath10k: Don't always treat modem stop events as crashes
+    - ath9k: Fix potential interrupt storm on queue reset
+    - PM: EM: Fix inefficient states detection
+    - x86/insn: Use get_unaligned() instead of memcpy()
+    - EDAC/amd64: Handle three rank interleaving mode
+    - rcu: Always inline rcu_dynticks_task*_{enter,exit}()
+    - rcu: Fix rcu_dynticks_curr_cpu_in_eqs() vs noinstr
+    - netfilter: nft_dynset: relax superfluous check on set updates
+    - media: venus: fix vpp frequency calculation for decoder
+    - media: dvb-frontends: mn88443x: Handle errors of clk_prepare_enable()
+    - crypto: ccree - avoid out-of-range warnings from clang
+    - crypto: qat - detect PFVF collision after ACK
+    - crypto: qat - disregard spurious PFVF interrupts
+    - hwrng: mtk - Force runtime pm ops for sleep ops
+    - ima: fix deadlock when traversing "ima_default_rules".
+    - b43legacy: fix a lower bounds test
+    - b43: fix a lower bounds test
+    - gve: Recover from queue stall due to missed IRQ
+    - gve: Track RX buffer allocation failures
+    - mmc: sdhci-omap: Fix NULL pointer exception if regulator is not configured
+    - mmc: sdhci-omap: Fix context restore
+    - memstick: avoid out-of-range warning
+    - memstick: jmb38x_ms: use appropriate free function in jmb38x_ms_alloc_host()
+    - net, neigh: Fix NTF_EXT_LEARNED in combination with NTF_USE
+    - hwmon: Fix possible memleak in __hwmon_device_register()
+    - hwmon: (pmbus/lm25066) Let compiler determine outer dimension of
+      lm25066_coeff
+    - ath10k: fix max antenna gain unit
+    - kernel/sched: Fix sched_fork() access an invalid sched_task_group
+    - net: fealnx: fix build for UML
+    - net: intel: igc_ptp: fix build for UML
+    - net: tulip: winbond-840: fix build for UML
+    - tcp: switch orphan_count to bare per-cpu counters
+    - crypto: octeontx2 - set assoclen in aead_do_fallback()
+    - thermal/core: fix a UAF bug in __thermal_cooling_device_register()
+    - drm/msm/dsi: do not enable irq handler before powering up the host
+    - drm/msm: Fix potential Oops in a6xx_gmu_rpmh_init()
+    - drm/msm: potential error pointer dereference in init()
+    - drm/msm: unlock on error in get_sched_entity()
+    - drm/msm: fix potential NULL dereference in cleanup
+    - drm/msm: uninitialized variable in msm_gem_import()
+    - net: stream: don't purge sk_error_queue in sk_stream_kill_queues()
+    - thermal/drivers/qcom/lmh: make QCOM_LMH depends on QCOM_SCM
+    - mailbox: Remove WARN_ON for async_cb.cb in cmdq_exec_done
+    - media: ivtv: fix build for UML
+    - media: ir_toy: assignment to be16 should be of correct type
+    - mmc: mxs-mmc: disable regulator on error and in the remove function
+    - io-wq: Remove duplicate code in io_workqueue_create()
+    - block: ataflop: fix breakage introduced at blk-mq refactoring
+    - platform/x86: thinkpad_acpi: Fix bitwise vs. logical warning
+    - mailbox: mtk-cmdq: Validate alias_id on probe
+    - mailbox: mtk-cmdq: Fix local clock ID usage
+    - ACPI: PM: Turn off unused wakeup power resources
+    - ACPI: PM: Fix sharing of wakeup power resources
+    - drm/amdkfd: Fix an inappropriate error handling in allloc memory of gpu
+    - mt76: mt7921: fix endianness in mt7921_mcu_tx_done_event
+    - mt76: mt7915: fix endianness warning in mt7915_mac_add_txs_skb
+    - mt76: mt7921: fix endianness warning in mt7921_update_txs
+    - mt76: mt7615: fix endianness warning in mt7615_mac_write_txwi
+    - mt76: mt7915: fix info leak in mt7915_mcu_set_pre_cal()
+    - mt76: connac: fix mt76_connac_gtk_rekey_tlv usage
+    - mt76: fix build error implicit enumeration conversion
+    - mt76: mt7921: fix survey-dump reporting
+    - mt76: mt76x02: fix endianness warnings in mt76x02_mac.c
+    - mt76: mt7921: Fix out of order process by invalid event pkt
+    - mt76: mt7915: fix potential overflow of eeprom page index
+    - mt76: mt7915: fix bit fields for HT rate idx
+    - mt76: mt7921: fix dma hang in rmmod
+    - mt76: connac: fix GTK rekey offload failure on WPA mixed mode
+    - mt76: overwrite default reg_ops if necessary
+    - mt76: mt7921: report HE MU radiotap
+    - mt76: mt7921: fix firmware usage of RA info using legacy rates
+    - mt76: mt7921: fix kernel warning from cfg80211_calculate_bitrate
+    - mt76: mt7921: always wake device if necessary in debugfs
+    - mt76: mt7915: fix hwmon temp sensor mem use-after-free
+    - mt76: mt7615: fix hwmon temp sensor mem use-after-free
+    - mt76: mt7915: fix possible infinite loop release semaphore
+    - mt76: mt7921: fix retrying release semaphore without end
+    - mt76: mt7615: fix monitor mode tear down crash
+    - mt76: connac: fix possible NULL pointer dereference in
+      mt76_connac_get_phy_mode_v2
+    - mt76: mt7915: fix sta_rec_wtbl tag len
+    - mt76: mt7915: fix muar_idx in mt7915_mcu_alloc_sta_req()
+    - rsi: stop thread firstly in rsi_91x_init() error handling
+    - mwifiex: Send DELBA requests according to spec
+    - iwlwifi: mvm: reset PM state on unsuccessful resume
+    - iwlwifi: pnvm: don't kmemdup() more than we have
+    - iwlwifi: pnvm: read EFI data only if long enough
+    - net: enetc: unmap DMA in enetc_send_cmd()
+    - phy: micrel: ksz8041nl: do not use power down mode
+    - nbd: Fix use-after-free in pid_show
+    - nvme-rdma: fix error code in nvme_rdma_setup_ctrl
+    - PM: hibernate: fix sparse warnings
+    - clocksource/drivers/timer-ti-dm: Select TIMER_OF
+    - x86/sev: Fix stack type check in vc_switch_off_ist()
+    - drm/msm: Fix potential NULL dereference in DPU SSPP
+    - drm/msm/dsi: fix wrong type in msm_dsi_host
+    - crypto: tcrypt - fix skcipher multi-buffer tests for 1420B blocks
+    - smackfs: use netlbl_cfg_cipsov4_del() for deleting cipso_v4_doi
+    - KVM: selftests: Fix nested SVM tests when built with clang
+    - libbpf: Fix memory leak in btf__dedup()
+    - bpftool: Avoid leaking the JSON writer prepared for program metadata
+    - libbpf: Fix overflow in BTF sanity checks
+    - libbpf: Fix BTF header parsing checks
+    - mt76: mt7615: mt7622: fix ibss and meshpoint
+    - s390/gmap: validate VMA in __gmap_zap()
+    - s390/gmap: don't unconditionally call pte_unmap_unlock() in __gmap_zap()
+    - s390/mm: validate VMA in PGSTE manipulation functions
+    - s390/mm: fix VMA and page table handling code in storage key handling
+      functions
+    - s390/uv: fully validate the VMA before calling follow_page()
+    - KVM: s390: pv: avoid double free of sida page
+    - KVM: s390: pv: avoid stalls for kvm_s390_pv_init_vm
+    - irq: mips: avoid nested irq_enter()
+    - net: dsa: avoid refcount warnings when ->port_{fdb,mdb}_del returns error
+    - ARM: 9142/1: kasan: work around LPAE build warning
+    - ath10k: fix module load regression with iram-recovery feature
+    - block: ataflop: more blk-mq refactoring fixes
+    - blk-cgroup: synchronize blkg creation against policy deactivation
+    - libbpf: Fix off-by-one bug in bpf_core_apply_relo()
+    - tpm: fix Atmel TPM crash caused by too frequent queries
+    - tpm_tis_spi: Add missing SPI ID
+    - libbpf: Fix endianness detection in BPF_CORE_READ_BITFIELD_PROBED()
+    - tcp: don't free a FIN sk_buff in tcp_remove_empty_skb()
+    - tracing: Fix missing trace_boot_init_histograms kstrdup NULL checks
+    - cpufreq: intel_pstate: Fix cpu->pstate.turbo_freq initialization
+    - spi: spi-rpc-if: Check return value of rpcif_sw_init()
+    - samples/kretprobes: Fix return value if register_kretprobe() failed
+    - KVM: s390: Fix handle_sske page fault handling
+    - libertas_tf: Fix possible memory leak in probe and disconnect
+    - libertas: Fix possible memory leak in probe and disconnect
+    - wcn36xx: add proper DMA memory barriers in rx path
+    - wcn36xx: Fix discarded frames due to wrong sequence number
+    - bpf: Avoid races in __bpf_prog_run() for 32bit arches
+    - bpf: Fixes possible race in update_prog_stats() for 32bit arches
+    - wcn36xx: Channel list update before hardware scan
+    - drm/amdgpu: fix a potential memory leak in amdgpu_device_fini_sw()
+    - drm/amdgpu/gmc6: fix DMA mask from 44 to 40 bits
+    - selftests/bpf: Fix fd cleanup in sk_lookup test
+    - selftests/bpf: Fix memory leak in test_ima
+    - sctp: allow IP fragmentation when PLPMTUD enters Error state
+    - sctp: reset probe_timer in sctp_transport_pl_update
+    - sctp: subtract sctphdr len in sctp_transport_pl_hlen
+    - sctp: return true only for pathmtu update in sctp_transport_pl_toobig
+    - net: amd-xgbe: Toggle PLL settings during rate change
+    - ipmi: kcs_bmc: Fix a memory leak in the error handling path of
+      'kcs_bmc_serio_add_device()'
+    - nfp: fix NULL pointer access when scheduling dim work
+    - nfp: fix potential deadlock when canceling dim work
+    - net: phylink: avoid mvneta warning when setting pause parameters
+    - net: bridge: fix uninitialized variables when BRIDGE_CFM is disabled
+    - selftests: net: bridge: update IGMP/MLD membership interval value
+    - crypto: pcrypt - Delay write to padata->info
+    - selftests/bpf: Fix fclose/pclose mismatch in test_progs
+    - udp6: allow SO_MARK ctrl msg to affect routing
+    - ibmvnic: don't stop queue in xmit
+    - ibmvnic: Process crqs after enabling interrupts
+    - ibmvnic: delay complete()
+    - selftests: mptcp: fix proto type in link_failure tests
+    - skmsg: Lose offset info in sk_psock_skb_ingress
+    - cgroup: Fix rootcg cpu.stat guest double counting
+    - bpf: Fix propagation of bounds from 64-bit min/max into 32-bit and var_off.
+    - bpf: Fix propagation of signed bounds from 64-bit min/max into 32-bit.
+    - of: unittest: fix EXPECT text for gpio hog errors
+    - cpufreq: Fix parameter in parse_perf_domain()
+    - staging: r8188eu: fix memory leak in rtw_set_key
+    - arm64: dts: meson: sm1: add Ethernet PHY reset line for ODROID-C4/HC4
+    - iio: st_sensors: disable regulators after device unregistration
+    - RDMA/rxe: Fix wrong port_cap_flags
+    - ARM: dts: BCM5301X: Fix memory nodes names
+    - arm64: dts: broadcom: bcm4908: Fix UART clock name
+    - clk: mvebu: ap-cpu-clk: Fix a memory leak in error handling paths
+    - scsi: pm80xx: Fix lockup in outbound queue management
+    - scsi: qla2xxx: edif: Use link event to wake up app
+    - scsi: lpfc: Fix NVMe I/O failover to non-optimized path
+    - ARM: s3c: irq-s3c24xx: Fix return value check for s3c24xx_init_intc()
+    - arm64: dts: rockchip: Fix GPU register width for RK3328
+    - ARM: dts: qcom: msm8974: Add xo_board reference clock to DSI0 PHY
+    - RDMA/bnxt_re: Fix query SRQ failure
+    - arm64: dts: ti: k3-j721e-main: Fix "max-virtual-functions" in PCIe EP nodes
+    - arm64: dts: ti: k3-j721e-main: Fix "bus-range" upto 256 bus number for PCIe
+    - arm64: dts: ti: j7200-main: Fix "vendor-id"/"device-id" properties of pcie
+      node
+    - arm64: dts: ti: j7200-main: Fix "bus-range" upto 256 bus number for PCIe
+    - arm64: dts: meson-g12a: Fix the pwm regulator supply properties
+    - arm64: dts: meson-g12b: Fix the pwm regulator supply properties
+    - arm64: dts: meson-sm1: Fix the pwm regulator supply properties
+    - bus: ti-sysc: Fix timekeeping_suspended warning on resume
+    - ARM: dts: at91: tse850: the emac<->phy interface is rmii
+    - arm64: dts: qcom: sc7180: Base dynamic CPU power coefficients in reality
+    - soc: qcom: llcc: Disable MMUHWT retention
+    - arm64: dts: qcom: sc7280: fix display port phy reg property
+    - scsi: dc395: Fix error case unwinding
+    - MIPS: loongson64: make CPU_LOONGSON64 depends on MIPS_FP_SUPPORT
+    - JFS: fix memleak in jfs_mount
+    - pinctrl: renesas: rzg2l: Fix missing port register 21h
+    - ASoC: wcd9335: Use correct version to initialize Class H
+    - arm64: dts: qcom: msm8916: Fix Secondary MI2S bit clock
+    - arm64: dts: renesas: beacon: Fix Ethernet PHY mode
+    - iommu/mediatek: Fix out-of-range warning with clang
+    - arm64: dts: qcom: pm8916: Remove wrong reg-names for rtc@6000
+    - iommu/dma: Fix sync_sg with swiotlb
+    - iommu/dma: Fix arch_sync_dma for map
+    - ALSA: hda: Reduce udelay() at SKL+ position reporting
+    - ALSA: hda: Use position buffer for SKL+ again
+    - ALSA: usb-audio: Fix possible race at sync of urb completions
+    - soundwire: debugfs: use controller id and link_id for debugfs
+    - power: reset: at91-reset: check properly the return value of devm_of_iomap
+    - scsi: ufs: core: Fix ufshcd_probe_hba() prototype to match the definition
+    - scsi: ufs: core: Stop clearing UNIT ATTENTIONS
+    - scsi: megaraid_sas: Fix concurrent access to ISR between IRQ polling and
+      real interrupt
+    - scsi: pm80xx: Fix misleading log statement in pm8001_mpi_get_nvmd_resp()
+    - driver core: Fix possible memory leak in device_link_add()
+    - arm: dts: omap3-gta04a4: accelerometer irq fix
+    - ASoC: SOF: topology: do not power down primary core during topology removal
+    - iio: st_pressure_spi: Add missing entries SPI to device ID table
+    - soc/tegra: Fix an error handling path in tegra_powergate_power_up()
+    - memory: fsl_ifc: fix leak of irq and nand_irq in fsl_ifc_ctrl_probe
+    - clk: at91: check pmc node status before registering syscore ops
+    - powerpc/mem: Fix arch/powerpc/mm/mem.c:53:12: error: no previous prototype
+      for 'create_section_mapping'
+    - video: fbdev: chipsfb: use memset_io() instead of memset()
+    - powerpc: fix unbalanced node refcount in check_kvm_guest()
+    - powerpc/paravirt: correct preempt debug splat in vcpu_is_preempted()
+    - serial: 8250_dw: Drop wrong use of ACPI_PTR()
+    - usb: gadget: hid: fix error code in do_config()
+    - power: supply: rt5033_battery: Change voltage values to µV
+    - power: supply: max17040: fix null-ptr-deref in max17040_probe()
+    - scsi: csiostor: Uninitialized data in csio_ln_vnp_read_cbfn()
+    - RDMA/mlx4: Return missed an error if device doesn't support steering
+    - usb: musb: select GENERIC_PHY instead of depending on it
+    - staging: most: dim2: do not double-register the same device
+    - staging: ks7010: select CRYPTO_HASH/CRYPTO_MICHAEL_MIC
+    - RDMA/core: Set sgtable nents when using ib_dma_virt_map_sg()
+    - dyndbg: make dyndbg a known cli param
+    - powerpc/perf: Fix cycles/instructions as PM_CYC/PM_INST_CMPL in power10
+    - pinctrl: renesas: checker: Fix off-by-one bug in drive register check
+    - ARM: dts: stm32: Reduce DHCOR SPI NOR frequency to 50 MHz
+    - ARM: dts: stm32: fix STUSB1600 Type-C irq level on stm32mp15xx-dkx
+    - ARM: dts: stm32: fix SAI sub nodes register range
+    - ARM: dts: stm32: fix AV96 board SAI2 pin muxing on stm32mp15
+    - ASoC: cs42l42: Always configure both ASP TX channels
+    - ASoC: cs42l42: Correct some register default values
+    - ASoC: cs42l42: Defer probe if request_threaded_irq() returns EPROBE_DEFER
+    - soc: qcom: rpmhpd: Make power_on actually enable the domain
+    - soc: qcom: socinfo: add two missing PMIC IDs
+    - iio: buffer: Fix double-free in iio_buffers_alloc_sysfs_and_mask()
+    - usb: typec: STUSB160X should select REGMAP_I2C
+    - iio: adis: do not disabe IRQs in 'adis_init()'
+    - soundwire: bus: stop dereferencing invalid slave pointer
+    - scsi: ufs: ufshcd-pltfrm: Fix memory leak due to probe defer
+    - scsi: lpfc: Wait for successful restart of SLI3 adapter during host sg_reset
+    - serial: imx: fix detach/attach of serial console
+    - usb: dwc2: drd: fix dwc2_force_mode call in dwc2_ovr_init
+    - usb: dwc2: drd: fix dwc2_drd_role_sw_set when clock could be disabled
+    - usb: dwc2: drd: reset current session before setting the new one
+    - powerpc/booke: Disable STRICT_KERNEL_RWX, DEBUG_PAGEALLOC and KFENCE
+    - usb: dwc3: gadget: Skip resizing EP's TX FIFO if already resized
+    - firmware: qcom_scm: Fix error retval in __qcom_scm_is_call_available()
+    - soc: qcom: rpmhpd: fix sm8350_mxc's peer domain
+    - soc: qcom: apr: Add of_node_put() before return
+    - arm64: dts: qcom: pmi8994: Fix "eternal"->"external" typo in WLED node
+    - arm64: dts: qcom: sdm845: Use RPMH_CE_CLK macro directly
+    - arm64: dts: qcom: sdm845: Fix Qualcomm crypto engine bus clock
+    - pinctrl: equilibrium: Fix function addition in multiple groups
+    - ASoC: topology: Fix stub for snd_soc_tplg_component_remove()
+    - phy: qcom-qusb2: Fix a memory leak on probe
+    - phy: ti: gmii-sel: check of_get_address() for failure
+    - phy: qcom-qmp: another fix for the sc8180x PCIe definition
+    - phy: qcom-snps: Correct the FSEL_MASK
+    - phy: Sparx5 Eth SerDes: Fix return value check in sparx5_serdes_probe()
+    - serial: xilinx_uartps: Fix race condition causing stuck TX
+    - clk: at91: sam9x60-pll: use DIV_ROUND_CLOSEST_ULL
+    - clk: at91: clk-master: check if div or pres is zero
+    - clk: at91: clk-master: fix prescaler logic
+    - HID: u2fzero: clarify error check and length calculations
+    - HID: u2fzero: properly handle timeouts in usb_submit_urb
+    - powerpc/nohash: Fix __ptep_set_access_flags() and ptep_set_wrprotect()
+    - powerpc/book3e: Fix set_memory_x() and set_memory_nx()
+    - powerpc/44x/fsp2: add missing of_node_put
+    - powerpc/xmon: fix task state output
+    - ALSA: oxfw: fix functional regression for Mackie Onyx 1640i in v5.14 or
+      later
+    - iommu/dma: Fix incorrect error return on iommu deferred attach
+    - powerpc: Don't provide __kernel_map_pages() without
+      ARCH_SUPPORTS_DEBUG_PAGEALLOC
+    - ASoC: cs42l42: Correct configuring of switch inversion from ts-inv
+    - RDMA/hns: Fix initial arm_st of CQ
+    - RDMA/hns: Modify the value of MAX_LP_MSG_LEN to meet hardware compatibility
+    - ASoC: rsnd: Fix an error handling path in 'rsnd_node_count()'
+    - serial: cpm_uart: Protect udbg definitions by CONFIG_SERIAL_CPM_CONSOLE
+    - virtio_ring: check desc == NULL when using indirect with packed
+    - vdpa/mlx5: Fix clearing of VIRTIO_NET_F_MAC feature bit
+    - mips: cm: Convert to bitfield API to fix out-of-bounds access
+    - power: supply: bq27xxx: Fix kernel crash on IRQ handler register error
+    - RDMA/core: Require the driver to set the IOVA correctly during rereg_mr
+    - apparmor: fix error check
+    - rpmsg: Fix rpmsg_create_ept return when RPMSG config is not defined
+    - mtd: rawnand: intel: Fix potential buffer overflow in probe
+    - nfsd: don't alloc under spinlock in rpc_parse_scope_id
+    - rtc: ds1302: Add SPI ID table
+    - rtc: ds1390: Add SPI ID table
+    - rtc: pcf2123: Add SPI ID table
+    - remoteproc: imx_rproc: Fix TCM io memory type
+    - i2c: i801: Use PCI bus rescan mutex to protect P2SB access
+    - dmaengine: idxd: move out percpu_ref_exit() to ensure it's outside
+      submission
+    - rtc: mcp795: Add SPI ID table
+    - Input: ariel-pwrbutton - add SPI device ID table
+    - i2c: mediatek: fixing the incorrect register offset
+    - NFS: Default change_attr_type to NFS4_CHANGE_TYPE_IS_UNDEFINED
+    - NFS: Don't set NFS_INO_DATA_INVAL_DEFER and NFS_INO_INVALID_DATA
+    - NFS: Ignore the directory size when marking for revalidation
+    - NFS: Fix dentry verifier races
+    - pnfs/flexfiles: Fix misplaced barrier in nfs4_ff_layout_prepare_ds
+    - drm/bridge/lontium-lt9611uxc: fix provided connector suport
+    - drm/plane-helper: fix uninitialized variable reference
+    - PCI: aardvark: Don't spam about PIO Response Status
+    - PCI: aardvark: Fix preserving PCI_EXP_RTCTL_CRSSVE flag on emulated bridge
+    - opp: Fix return in _opp_add_static_v2()
+    - NFS: Fix deadlocks in nfs_scan_commit_list()
+    - sparc: Add missing "FORCE" target when using if_changed
+    - fs: orangefs: fix error return code of orangefs_revalidate_lookup()
+    - Input: st1232 - increase "wait ready" timeout
+    - drm/bridge: nwl-dsi: Add atomic_get_input_bus_fmts
+    - mtd: spi-nor: hisi-sfc: Remove excessive clk_disable_unprepare()
+    - PCI: uniphier: Serialize INTx masking/unmasking and fix the bit operation
+    - mtd: rawnand: arasan: Prevent an unsupported configuration
+    - mtd: core: don't remove debugfs directory if device is in use
+    - remoteproc: Fix a memory leak in an error handling path in
+      'rproc_handle_vdev()'
+    - rtc: rv3032: fix error handling in rv3032_clkout_set_rate()
+    - dmaengine: at_xdmac: call at_xdmac_axi_config() on resume path
+    - dmaengine: at_xdmac: fix AT_XDMAC_CC_PERID() macro
+    - dmaengine: stm32-dma: fix stm32_dma_get_max_width
+    - NFS: Fix up commit deadlocks
+    - NFS: Fix an Oops in pnfs_mark_request_commit()
+    - Fix user namespace leak
+    - auxdisplay: img-ascii-lcd: Fix lock-up when displaying empty string
+    - auxdisplay: ht16k33: Connect backlight to fbdev
+    - auxdisplay: ht16k33: Fix frame buffer device blanking
+    - soc: fsl: dpaa2-console: free buffer before returning from
+      dpaa2_console_read
+    - netfilter: nfnetlink_queue: fix OOB when mac header was cleared
+    - dmaengine: dmaengine_desc_callback_valid(): Check for `callback_result`
+    - dmaengine: tegra210-adma: fix pm runtime unbalance
+    - dmanegine: idxd: fix resource free ordering on driver removal
+    - dmaengine: idxd: reconfig device after device reset command
+    - signal/sh: Use force_sig(SIGKILL) instead of do_group_exit(SIGKILL)
+    - m68k: set a default value for MEMORY_RESERVE
+    - watchdog: f71808e_wdt: fix inaccurate report in WDIOC_GETTIMEOUT
+    - ar7: fix kernel builds for compiler test
+    - scsi: target: core: Remove from tmr_list during LUN unlink
+    - scsi: qla2xxx: Relogin during fabric disturbance
+    - scsi: qla2xxx: Fix gnl list corruption
+    - scsi: qla2xxx: Turn off target reset during issue_lip
+    - scsi: qla2xxx: edif: Fix app start fail
+    - scsi: qla2xxx: edif: Fix app start delay
+    - scsi: qla2xxx: edif: Flush stale events and msgs on session down
+    - scsi: qla2xxx: edif: Increase ELS payload
+    - scsi: qla2xxx: edif: Fix EDIF bsg
+    - NFSv4: Fix a regression in nfs_set_open_stateid_locked()
+    - dmaengine: idxd: fix resource leak on dmaengine driver disable
+    - i2c: xlr: Fix a resource leak in the error handling path of
+      'xlr_i2c_probe()'
+    - gpio: realtek-otto: fix GPIO line IRQ offset
+    - xen-pciback: Fix return in pm_ctrl_init()
+    - nbd: fix max value for 'first_minor'
+    - nbd: fix possible overflow for 'first_minor' in nbd_dev_add()
+    - io-wq: fix max-workers not correctly set on multi-node system
+    - net: davinci_emac: Fix interrupt pacing disable
+    - kselftests/net: add missed icmp.sh test to Makefile
+    - kselftests/net: add missed setup_loopback.sh/setup_veth.sh to Makefile
+    - kselftests/net: add missed SRv6 tests
+    - kselftests/net: add missed vrf_strict_mode_test.sh test to Makefile
+    - kselftests/net: add missed toeplitz.sh/toeplitz_client.sh to Makefile
+    - ethtool: fix ethtool msg len calculation for pause stats
+    - openrisc: fix SMP tlb flush NULL pointer dereference
+    - net: vlan: fix a UAF in vlan_dev_real_dev()
+    - net: dsa: felix: fix broken VLAN-tagged PTP under VLAN-aware bridge
+    - ice: Fix replacing VF hardware MAC to existing MAC filter
+    - ice: Fix not stopping Tx queues for VFs
+    - kdb: Adopt scheduler's task classification
+    - ACPI: PMIC: Fix intel_pmic_regs_handler() read accesses
+    - PCI: j721e: Fix j721e_pcie_probe() error path
+    - nvdimm/btt: do not call del_gendisk() if not needed
+    - scsi: bsg: Fix errno when scsi_bsg_register_queue() fails
+    - scsi: ufs: ufshpb: Use proper power management API
+    - scsi: ufs: core: Fix NULL pointer dereference
+    - scsi: ufs: ufshpb: Properly handle max-single-cmd
+    - drm/nouveau/svm: Fix refcount leak bug and missing check against null bug
+    - nvdimm/pmem: cleanup the disk if pmem_release_disk() is yet assigned
+    - block/ataflop: use the blk_cleanup_disk() helper
+    - block/ataflop: add registration bool before calling del_gendisk()
+    - block/ataflop: provide a helper for cleanup up an atari disk
+    - ataflop: remove ataflop_probe_lock mutex
+    - PCI: Do not enable AtomicOps on VFs
+    - cpufreq: intel_pstate: Clear HWP desired on suspend/shutdown and offline
+    - net: phy: fix duplex out of sync problem while changing settings
+    - block: fix device_add_disk() kobject_create_and_add() error handling
+    - drm/ttm: remove ttm_bo_vm_insert_huge()
+    - bonding: Fix a use-after-free problem when bond_sysfs_slave_add() failed
+    - octeontx2-pf: select CONFIG_NET_DEVLINK
+    - ALSA: memalloc: Catch call with NULL snd_dma_buffer pointer
+    - mfd: core: Add missing of_node_put for loop iteration
+    - mfd: cpcap: Add SPI device ID table
+    - mfd: sprd: Add SPI device ID table
+    - mfd: altera-sysmgr: Fix a mistake caused by resource_size conversion
+    - ACPI: PM: Fix device wakeup power reference counting error
+    - libbpf: Fix lookup_and_delete_elem_flags error reporting
+    - selftests/bpf/xdp_redirect_multi: Put the logs to tmp folder
+    - selftests/bpf/xdp_redirect_multi: Use arping to accurate the arp number
+    - selftests/bpf/xdp_redirect_multi: Give tcpdump a chance to terminate cleanly
+    - selftests/bpf/xdp_redirect_multi: Limit the tests in netns
+    - drm: fb_helper: improve CONFIG_FB dependency
+    - Revert "drm/imx: Annotate dma-fence critical section in commit path"
+    - drm/amdgpu/powerplay: fix sysfs_emit/sysfs_emit_at handling
+    - can: etas_es58x: es58x_rx_err_msg(): fix memory leak in error path
+    - can: mcp251xfd: mcp251xfd_chip_start(): fix error handling for
+      mcp251xfd_chip_rx_int_enable()
+    - mm/zsmalloc.c: close race window between zs_pool_dec_isolated() and
+      zs_unregister_migration()
+    - zram: off by one in read_block_state()
+    - perf bpf: Add missing free to bpf_event__print_bpf_prog_info()
+    - llc: fix out-of-bound array index in llc_sk_dev_hash()
+    - nfc: pn533: Fix double free when pn533_fill_fragment_skbs() fails
+    - litex_liteeth: Fix a double free in the remove function
+    - arm64: arm64_ftr_reg->name may not be a human-readable string
+    - arm64: pgtable: make __pte_to_phys/__phys_to_pte_val inline functions
+    - bpf, sockmap: Remove unhash handler for BPF sockmap usage
+    - bpf, sockmap: Fix race in ingress receive verdict with redirect to self
+    - bpf: sockmap, strparser, and tls are reusing qdisc_skb_cb and colliding
+    - bpf, sockmap: sk_skb data_end access incorrect when src_reg = dst_reg
+    - dmaengine: stm32-dma: fix burst in case of unaligned memory address
+    - dmaengine: stm32-dma: avoid 64-bit division in stm32_dma_get_max_width
+    - gve: Fix off by one in gve_tx_timeout()
+    - drm/i915/fb: Fix rounding error in subsampled plane size calculation
+    - init: make unknown command line param message clearer
+    - seq_file: fix passing wrong private data
+    - drm/amdgpu: fix uvd crash on Polaris12 during driver unloading
+    - net: dsa: mv88e6xxx: Don't support >1G speeds on 6191X on ports other than
+      10
+    - net/sched: sch_taprio: fix undefined behavior in ktime_mono_to_any
+    - net: hns3: fix ROCE base interrupt vector initialization bug
+    - net: hns3: fix pfc packet number incorrect after querying pfc parameters
+    - net: hns3: fix kernel crash when unload VF while it is being reset
+    - net: hns3: allow configure ETS bandwidth of all TCs
+    - net: stmmac: allow a tc-taprio base-time of zero
+    - net: ethernet: ti: cpsw_ale: Fix access to un-initialized memory
+    - net: marvell: mvpp2: Fix wrong SerDes reconfiguration order
+    - vsock: prevent unnecessary refcnt inc for nonblocking connect
+    - net/smc: fix sk_refcnt underflow on linkdown and fallback
+    - cxgb4: fix eeprom len when diagnostics not implemented
+    - selftests/net: udpgso_bench_rx: fix port argument
+    - thermal: int340x: fix build on 32-bit targets
+    - smb3: do not error on fsync when readonly
+    - ARM: 9155/1: fix early early_iounmap()
+    - ARM: 9156/1: drop cc-option fallbacks for architecture selection
+    - parisc: Fix backtrace to always include init funtion names
+    - parisc: Flush kernel data mapping in set_pte_at() when installing pte for
+      user page
+    - MIPS: fix duplicated slashes for Platform file path
+    - MIPS: fix *-pkg builds for loongson2ef platform
+    - MIPS: Fix assembly error from MIPSr2 code used within MIPS_ISA_ARCH_LEVEL
+    - x86/mce: Add errata workaround for Skylake SKX37
+    - PCI/MSI: Move non-mask check back into low level accessors
+    - PCI/MSI: Destroy sysfs before freeing entries
+    - KVM: x86: move guest_pv_has out of user_access section
+    - posix-cpu-timers: Clear task::posix_cputimers_work in copy_process()
+    - irqchip/sifive-plic: Fixup EOI failed when masked
+    - f2fs: should use GFP_NOFS for directory inodes
+    - f2fs: include non-compressed blocks in compr_written_block
+    - f2fs: fix UAF in f2fs_available_free_memory
+    - ceph: fix mdsmap decode when there are MDS's beyond max_mds
+    - erofs: fix unsafe pagevec reuse of hooked pclusters
+    - drm/i915/guc: Fix blocked context accounting
+    - block: Hold invalidate_lock in BLKDISCARD ioctl
+    - block: Hold invalidate_lock in BLKZEROOUT ioctl
+    - block: Hold invalidate_lock in BLKRESETZONE ioctl
+    - ksmbd: Fix buffer length check in fsctl_validate_negotiate_info()
+    - ksmbd: don't need 8byte alignment for request length in ksmbd_check_message
+    - dmaengine: ti: k3-udma: Set bchan to NULL if a channel request fail
+    - dmaengine: ti: k3-udma: Set r/tchan or rflow to NULL if request fail
+    - dmaengine: bestcomm: fix system boot lockups
+    - net, neigh: Enable state migration between NUD_PERMANENT and NTF_USE
+    - 9p/net: fix missing error check in p9_check_errors
+    - mm/filemap.c: remove bogus VM_BUG_ON
+    - memcg: prohibit unconditional exceeding the limit of dying tasks
+    - mm, oom: pagefault_out_of_memory: don't force global OOM for dying tasks
+    - mm, oom: do not trigger out_of_memory from the #PF
+    - mm, thp: lock filemap when truncating page cache
+    - mm, thp: fix incorrect unmap behavior for private pages
+    - mfd: dln2: Add cell for initializing DLN2 ADC
+    - video: backlight: Drop maximum brightness override for brightness zero
+    - bcache: fix use-after-free problem in bcache_device_free()
+    - bcache: Revert "bcache: use bvec_virt"
+    - PM: sleep: Avoid calling put_device() under dpm_list_mtx
+    - s390/cpumf: cpum_cf PMU displays invalid value after hotplug remove
+    - s390/cio: check the subchannel validity for dev_busid
+    - s390/tape: fix timer initialization in tape_std_assign()
+    - s390/ap: Fix hanging ioctl caused by orphaned replies
+    - s390/cio: make ccw_device_dma_* more robust
+    - remoteproc: elf_loader: Fix loading segment when is_iomem true
+    - remoteproc: Fix the wrong default value of is_iomem
+    - remoteproc: imx_rproc: Fix ignoring mapping vdev regions
+    - remoteproc: imx_rproc: Fix rsc-table name
+    - mtd: rawnand: fsmc: Fix use of SM ORDER
+    - mtd: rawnand: ams-delta: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: xway: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: mpc5121: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: gpio: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: pasemi: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: orion: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: plat_nand: Keep the driver compatible with on-die ECC engines
+    - mtd: rawnand: au1550nd: Keep the driver compatible with on-die ECC engines
+    - powerpc/vas: Fix potential NULL pointer dereference
+    - powerpc/bpf: Fix write protecting JIT code
+    - powerpc/32e: Ignore ESR in instruction storage interrupt handler
+    - powerpc/powernv/prd: Unregister OPAL_MSG_PRD2 notifier during module unload
+    - powerpc/security: Use a mutex for interrupt exit code patching
+    - powerpc/64s/interrupt: Fix check_return_regs_valid() false positive
+    - powerpc/pseries/mobility: ignore ibm, platform-facilities updates
+    - powerpc/85xx: fix timebase sync issue when CONFIG_HOTPLUG_CPU=n
+    - drm/sun4i: Fix macros in sun8i_csc.h
+    - PCI: Add PCI_EXP_DEVCTL_PAYLOAD_* macros
+    - PCI: aardvark: Fix PCIe Max Payload Size setting
+    - SUNRPC: Partial revert of commit 6f9f17287e78
+    - drm/amd/display: Look at firmware version to determine using dmub on dcn21
+    - media: vidtv: move kfree(dvb) to vidtv_bridge_dev_release()
+    - cifs: fix memory leak of smb3_fs_context_dup::server_hostname
+    - ath10k: fix invalid dma_addr_t token assignment
+    - mmc: moxart: Fix null pointer dereference on pointer host
+    - selftests/x86/iopl: Adjust to the faked iopl CLI/STI usage
+    - selftests/bpf: Fix also no-alu32 strobemeta selftest
+    - arch/cc: Introduce a function to check for confidential computing features
+    - x86/sev: Add an x86 version of cc_platform_has()
+    - x86/sev: Make the #VC exception stacks part of the default stacks storage
+    - media: videobuf2: always set buffer vb2 pointer
+    - media: videobuf2-dma-sg: Fix buf->vb NULL pointer dereference
+    - Linux 5.15.3
+
+  * kernel panic: NULL pointer dereference in wb_timer_f() (LP: #1947557) //
+    Jammy update: v5.15.3 upstream stable release (LP: #1951822)
+    - blk-wbt: prevent NULL pointer dereference in wb_timer_fn
+
+  * Medion Notebook Keyboard not working (LP: #1909814) // Jammy update: v5.15.3
+    upstream stable release (LP: #1951822)
+    - ACPI: resources: Add DMI-based legacy IRQ override quirk
+
+  * Enable CONFIG_INTEL_IOMMU_DEFAULT_ON and
+    CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON on jammy 5.15 (LP: #1951440)
+    - [Config] enable Intel DMA remapping options by default
+
+  * Thinkpad E14 Gen2: Kernel panic with trackpad and trackpoint enabled
+    (LP: #1945590)
+    - SAUCE: Input: elantech - Fix stack out of bound access in
+      elantech_change_report_id()
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: LSM: Specify which LSM to display (using struct cred as input)
+    - SAUCE: selftests/seccomp: fix check of fds being assigned
+    - [Config] enable SUNRPC_DISABLE_INSECURE_ENCTYPES
+    - [Config] updateconfigs following v5.15.3, v5.15.4 import
+
+  * Miscellaneous upstream changes
+    - binder: use cred instead of task for selinux checks
+    - binder: use cred instead of task for getsecid
+    - Revert "UBUNTU: SAUCE: storvsc: use small sg_tablesize on x86"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 22 Nov 2021 13:14:15 +0100
+
+linux (5.15.0-11.11) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-11.11 -proposed tracker (LP: #1950948)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * OOPs on boot: invalid opcode: 0000 [#1] SMP NOPTI (LP: #1942215)
+    - SAUCE: ACPICA: prevent out-of-bound access with buggy DSDT
+    - [Config] disable UBSAN
+    - SAUCE: ACPICA: avoid accessing operands out-of-bounds
+
+  * Jammy update: v5.15.2 upstream stable release (LP: #1950949)
+    - KVM: x86: avoid warning with -Wbitwise-instead-of-logical
+    - Revert "x86/kvm: fix vcpu-id indexed array sizes"
+    - usb: ehci: handshake CMD_RUN instead of STS_HALT
+    - usb: gadget: Mark USB_FSL_QE broken on 64-bit
+    - usb: musb: Balance list entry in musb_gadget_queue
+    - usb-storage: Add compatibility quirk flags for iODD 2531/2541
+    - Revert "proc/wchan: use printk format instead of lookup_symbol_name()"
+    - binder: use euid from cred instead of using task
+    - binder: don't detect sender/target during buffer cleanup
+    - kfence: always use static branches to guard kfence_alloc()
+    - kfence: default to dynamic branch instead of static keys mode
+    - btrfs: fix lzo_decompress_bio() kmap leakage
+    - staging: rtl8712: fix use-after-free in rtl8712_dl_fw
+    - isofs: Fix out of bound access for corrupted isofs image
+    - comedi: dt9812: fix DMA buffers on stack
+    - comedi: ni_usb6501: fix NULL-deref in command paths
+    - comedi: vmk80xx: fix transfer-buffer overflows
+    - comedi: vmk80xx: fix bulk-buffer overflow
+    - comedi: vmk80xx: fix bulk and interrupt message timeouts
+    - staging: r8712u: fix control-message timeout
+    - staging: rtl8192u: fix control-message timeouts
+    - staging: r8188eu: fix memleak in rtw_wx_set_enc_ext
+    - media: staging/intel-ipu3: css: Fix wrong size comparison imgu_css_fw_init
+    - rsi: fix control-message timeout
+    - Linux 5.15.2
+
+  * reuseport_bpf_numa in net from ubuntu_kernel_selftests fails on ppc64le
+    (LP: #1867570)
+    - selftests/net: Fix reuseport_bpf_numa by skipping unavailable nodes
+
+  * Miscellaneous Ubuntu changes
+    - packaging: switch getabis to the linux package name
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (no-up) rename the adv7511 drm driver to adv7511_drm"
+    - Revert "UBUNTU: SAUCE: drm/i915/dp: Use max params for older panels"
+    - Revert "UBUNTU: SAUCE: i915: Fix build error due to missing struct
+      definition"
+    - selftests/core: fix conflicting types compile error for close_range()
+    - selftests: net: test_vxlan_under_vrf: fix HV connectivity test
+    - Revert "UBUNTU: SAUCE: ACPICA: prevent out-of-bound access with buggy DSDT"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 15 Nov 2021 10:12:47 +0100
+
+linux (5.15.0-10.10) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-10.10 -proposed tracker (LP: #1950133)
+
+  * Jammy update: v5.15.1 upstream stable release (LP: #1950131)
+    - sfc: Fix reading non-legacy supported link modes
+    - media: firewire: firedtv-avc: fix a buffer overflow in avc_ca_pmt()
+    - Revert "xhci: Set HCD flag to defer primary roothub registration"
+    - Revert "usb: core: hcd: Add support for deferring roothub registration"
+    - drm/amdkfd: fix boot failure when iommu is disabled in Picasso.
+    - Revert "soc: imx: gpcv2: move reset assert after requesting domain power up"
+    - ARM: 9120/1: Revert "amba: make use of -1 IRQs warn"
+    - Revert "wcn36xx: Disable bmps when encryption is disabled"
+    - drm/amdgpu: revert "Add autodump debugfs node for gpu reset v8"
+    - drm/amd/display: Revert "Directly retrain link from debugfs"
+    - Revert "drm/i915/gt: Propagate change in error status to children on unhold"
+    - ALSA: usb-audio: Add quirk for Audient iD14
+    - Linux 5.15.1
+
+  * Miscellaneous Ubuntu changes
+    - packaging: fixup previous ABI/spin to -9.9
+    - [Packaging] Drop unused d-i build-deps and packaging
+    - [Packaging] Drop now unsupported d-i/ input files
+
+  * Miscellaneous upstream changes
+    - selftests: net: properly support IPv6 in GSO GRE test
+    - signal: Add SA_IMMUTABLE to ensure forced siganls do not get changed
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 08 Nov 2021 14:43:24 +0100
+
+linux (5.15.0-9.9) jammy; urgency=medium
+
+  * jammy/linux: 5.15.0-1.1 -proposed tracker (LP: #1949876)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+    - [Packaging] update Ubuntu.md
+
+  * Add F81966 watchdog support (LP: #1949063)
+    - SAUCE: ODM: watchdog: f71808e_wdt: Add F81966 support
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Rewrite debian/scripts/misc/insert-changes.pl in Python
+    - [Packaging] change source package name to linux
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 04 Nov 2021 18:47:19 +0100
+
+linux (5.15.0-0.0) jammy; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 04 Nov 2021 16:47:16 +0100
+
+linux-unstable (5.15.0-8.8) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.15.0-8.8 -proposed tracker (LP: #1949436)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Drop "UBUNTU: SAUCE: cachefiles: Page leaking in
+    cachefiles_read_backing_file while vmscan is active" (LP: #1947709)
+    - Revert "UBUNTU: SAUCE: cachefiles: Page leaking in
+      cachefiles_read_backing_file while vmscan is active"
+
+  * Add l2tp.sh in net from ubuntu_kernel_selftests back (LP: #1934293)
+    - Revert "UBUNTU: SAUCE: selftests/net -- disable l2tp.sh test"
+
+  * Check for changes relevant for security certifications (LP: #1945989)
+    - [Packaging] Add fips-checks as part of finalchecks
+
+  * Add final-checks to check certificates (LP: #1947174)
+    - [Packaging] Add system trusted and revocation keys final check
+
+  * Can only reach PC3 when ethernet is plugged r8169 (LP: #1946433)
+    - r8169: Enable chip-specific ASPM regardless of PCIe ASPM status
+    - PCI/ASPM: Introduce a new helper to report ASPM capability
+    - r8169: Implement dynamic ASPM mechanism
+
+  * rtw89 kernel module for Realtek 8852 wifi is missing (LP: #1945967)
+    - rtw89: add Realtek 802.11ax driver
+    - rtw89: Remove redundant check of ret after call to rtw89_mac_enable_bb_rf
+    - rtw89: fix return value check in rtw89_cam_send_sec_key_cmd()
+    - rtw89: remove unneeded semicolon
+    - [Config] RTW89=m
+
+  * Fix A yellow screen pops up in an instant (< 1 second) and then disappears
+    before loading the system (LP: #1945932)
+    - drm/i915: Stop force enabling pipe bottom color gammma/csc
+
+  * disable CONFIG_KFENCE_STATIC_KEYS in linux 5.15 (LP: #1948038)
+    - [Config] disable CONFIG_KFENCE_STATIC_KEYS
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Remove old and unused firmware helper scripts
+    - [Packaging] Replace Perl oneliner with Bash statements
+    - rebase to v5.15
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 02 Nov 2021 08:29:45 +0100
+
+linux-unstable (5.15.0-7.7) jammy; urgency=medium
+
+  * jammy/linux-unstable: 5.15.0-7.7 -proposed tracker (LP: #1948770)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Temporarily disable signing for ppc64el and s390x
+    - packaging: switch release to Jammy
+    - rebase to v5.15-rc7
+    - [Config] GCC version update
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 26 Oct 2021 11:38:14 +0200
+
+linux-unstable (5.15.0-6.6) jammy; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-6.6 -proposed tracker (LP: #1947565)
+
+  * [impish] Remove the downstream xr-usb-uart driver (LP: #1945938)
+    - SAUCE: xr-usb-serial: remove driver
+    - [Config] update modules list
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.15-rc6
+    - [Config] update config & annotations following v5.15-rc6 rebase
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: xr-usb-serial: switch to tty_alloc_driver() and
+      tty_driver_kref_put()"
+    - Revert "UBUNTU: SAUCE: xr-usb-serial: update return code for
+      xr_usb_serial_tty_write_room() and xr_usb_serial_tty_chars_in_buffer()"
+    - Revert "UBUNTU: [Packaging] FTBFS: disable zfs"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 18 Oct 2021 12:24:45 +0200
+
+linux-unstable (5.15.0-5.5) impish; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-5.5 -proposed tracker (LP: #1946338)
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.15-rc5
+    - [Config] FB_SIMPLE=m
+    - [Config] update annotations
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 11 Oct 2021 12:14:02 +0200
+
+linux-unstable (5.15.0-4.4) impish; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-4.4 -proposed tracker (LP: #1945953)
+
+  * Fix missing HDMI audio on Intel RKL (LP: #1945556)
+    - drm/i915/audio: Use BIOS provided value for RKL HDA link
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: media: atomisp: add missing return type (fix -Werror=return-type)
+    - SAUCE: xr-usb-serial: switch to tty_alloc_driver() and tty_driver_kref_put()
+    - rebase to v5.15-rc4
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] FTBFS: disable INTEL_ATOMISP"
+    - Revert "UBUNTU: [Config] FTBFS: disable xr-usb-serial"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc4
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 04 Oct 2021 10:52:41 +0200
+
+linux-unstable (5.15.0-3.3) impish; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-3.3 -proposed tracker (LP: #1944944)
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.15-rc3
+    - [Config] updateconfigs following v5.15-rc3 rebase
+    - [Packaging] correctly evaluate release in update-dkms-versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 27 Sep 2021 16:48:03 +0200
+
+linux-unstable (5.15.0-2.2) impish; urgency=medium
+
+  * impish/linux-unstable: 5.15.0-2.2 -proposed tracker (LP: #1944423)
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.15-rc2
+    - [Config] updateconfigs following v5.15-rc2 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc2
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 21 Sep 2021 11:46:59 +0200
+
+linux-unstable (5.15.0-1.1) impish; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - debian/dkms-versions -- update from kernel-versions (main/master)
+
+  *  LRMv5: switch primary version handling to kernel-versions data set
+    (LP: #1928921)
+    - [Packaging] switch to kernel-versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] remove remaining references to ports
+    - [Packaging] drop x32 architecture configs
+    - [Config] mark CONFIG_BPF_UNPRIV_DEFAULT_OFF enforced
+    - [Packaging] bump kernel version to 5.15
+    - rebase to v5.15-rc1
+    - [Config] updateconfigs following v5.15-rc1 rebase
+    - [Config] FTBFS: disable INTEL_ATOMISP
+    - [Config] FTBFS: disable xr-usb-serial
+    - [Packaging] FTBFS: disable zfs
+
+  * Miscellaneous upstream changes
+    - Revert "r8169: avoid link-up interrupt issue on RTL8106e if user enables
+      ASPM"
+    - Revert "UBUNTU: SAUCE: RDMA/core: Introduce peer memory interface"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.15-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 17 Sep 2021 11:42:25 +0200
+
+linux-unstable (5.15.0-0.0) impish; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 15 Sep 2021 11:54:10 +0200
+
+linux-unstable (5.14.0-9.9) impish; urgency=medium
+
+  * impish/linux-unstable: 5.14.0-9.9 -proposed tracker (LP: #1943022)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] NVIDIA -- Add the NVIDIA 470 driver
+    - [Packaging] NVIDIA: transition -460 and -465 to -470, transition -460-server
+      to -470-server
+
+  * Miscellaneous upstream changes
+    - vt_kdsetmode: extend console locking
+    - Bluetooth: btusb: check conditions before enabling USB ALT 3 for WBS
+    - net: dsa: mt7530: fix VLAN traffic leaks again
+    - btrfs: fix NULL pointer dereference when deleting device by invalid id
+    - Revert "floppy: reintroduce O_NDELAY fix"
+    - fscrypt: add fscrypt_symlink_getattr() for computing st_size
+    - ext4: report correct st_size for encrypted symlinks
+    - f2fs: report correct st_size for encrypted symlinks
+    - ubifs: report correct st_size for encrypted symlinks
+    - net: don't unconditionally copy_from_user a struct ifreq for socket ioctls
+    - audit: move put_tree() to avoid trim_trees refcount underflow and UAF
+    - Linux 5.14.1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 08 Sep 2021 12:20:18 +0200
+
+linux-unstable (5.14.0-8.8) impish; urgency=medium
+
+  * impish/linux-unstable: 5.14.0-8.8 -proposed tracker (LP: #1941887)
+
+  * Fix  Intel AC9560 BT function cannot turn on if BT turn off before S3 entry
+    (LP: #1941696)
+    - SAUCE: Bluetooth: btusb: add a reject table to disable msft
+
+  *  Add USB4 support for AMD SoC (LP: #1941036)
+    - thunderbolt: Add vendor specific NHI quirk for auto-clearing interrupt
+      status
+    - thunderbolt: Handle ring interrupt by reading interrupt status register
+    - thunderbolt: Do not read control adapter config space
+    - thunderbolt: Fix port linking by checking all adapters
+
+  * Support builtin revoked certificates (LP: #1932029)
+    - [Config] Enforce SYSTEM_TRUSTED_KEYS and SYSTEM_REVOCATION_KEYS
+
+  * GPIO error logs in start and dmesg after update of kernel (LP: #1937897)
+    - ODM: mfd: Check AAEON BFPI version before adding device
+
+  * initramfs-tools & kernel: use zstd as the default compression method
+    (LP: #1931725)
+    - [Config] enforce ZSTD compression
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.14
+    - [Config] RESET_MCHP_SPARX5 depends on ARCH_SPARX5
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] FTBFS: disable zfs"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 30 Aug 2021 12:57:19 +0200
+
+linux-unstable (5.14.0-7.7) impish; urgency=medium
+
+  * Please enable CONFIG_UBSAN_BOUNDS (LP: #1914685)
+    - [Config] Enable CONFIG_UBSAN_BOUNDS
+
+  * CONFIG_HARDENED_USERCOPY_FALLBACK should be disabled (LP: #1855340)
+    - [Config] Disable CONFIG_HARDENED_USERCOPY_FALLBACK
+
+  * fs: removing mandatory locks (LP: #1940392)
+    - [Config] Disable CONFIG_MANDATORY_FILE_LOCKING
+
+  * Fix kernel panic caused by legacy devices on AMD platforms (LP: #1936682)
+    - SAUCE: iommu/amd: Keep swiotlb enabled to ensure devices with 32bit DMA
+      still work
+
+  * ALSA: hda/cs8409: Add support for dolphin (LP: #1939541)
+    - ALSA: hda/cirrus: Move CS8409 HDA bridge to separate module
+    - ALSA: hda/cs8409: Move arrays of configuration to a new file
+    - ALSA: hda/cs8409: Use enums for register names and coefficients
+    - ALSA: hda/cs8409: Mask all CS42L42 interrupts on initialization
+    - ALSA: hda/cs8409: Reduce HS pops/clicks for Cyborg
+    - ALSA: hda/cs8409: Disable unnecessary Ring Sense for Cyborg/Warlock/Bullseye
+    - ALSA: hda/cs8409: Disable unsolicited responses during suspend
+    - ALSA: hda/cs8409: Disable unsolicited response for the first boot
+    - ALSA: hda/cs8409: Mask CS42L42 wake events
+    - ALSA: hda/cs8409: Simplify CS42L42 jack detect.
+    - ALSA: hda/cs8409: Prevent I2C access during suspend time
+    - ALSA: hda/cs8409: Generalize volume controls
+    - ALSA: hda/cs8409: Dont disable I2C clock between consecutive accesses
+    - ALSA: hda/cs8409: Avoid setting the same I2C address for every access
+    - ALSA: hda/cs8409: Avoid re-setting the same page as the last access
+    - ALSA: hda/cs8409: Support i2c bulk read/write functions
+    - ALSA: hda/cs8409: Separate CS8409, CS42L42 and project functions
+    - ALSA: hda/cs8409: Move codec properties to its own struct
+    - ALSA: hda/cs8409: Support multiple sub_codecs for Suspend/Resume/Unsol
+      events
+    - ALSA: hda/cs8409: Add Support to disable jack type detection for CS42L42
+    - ALSA: hda/cs8409: Add support for dolphin
+    - ALSA: hda/cs8409: Enable Full Scale Volume for Line Out Codec on Dolphin
+    - ALSA: hda/cs8409: Set fixed sample rate of 48kHz for CS42L42
+    - ALSA: hda/cs8409: Use timeout rather than retries for I2C transaction waits
+    - ALSA: hda/cs8409: Remove unnecessary delays
+    - ALSA: hda/cs8409: Follow correct CS42L42 power down sequence for suspend
+    - ALSA: hda/cs8409: Unmute/Mute codec when stream starts/stops
+    - ALSA: hda/cs8409: Prevent pops and clicks during suspend
+    - SAUCE: ALSA: hda/cs8409: Prevent pops and clicks during reboot
+    - [Config] Enable Cirrus Logic HDA bridge support
+
+  * e1000e: add handshake with the Intel CSME to support S0ix (LP: #1937252)
+    - SAUCE: e1000e: Add handshake with the CSME to support S0ix
+    - SAUCE: e1000e: Add polling mechanism to indicate CSME DPG exit
+    - SAUCE: e1000e: Additional PHY power saving in S0ix
+
+  * AMDGPU: Fix System hang after resume from suspend (LP: #1940204)
+    - SAUCE: drm/amdgpu: disable BACO support for 699F:C7 polaris12 SKU
+      temporarily
+
+  * [Regression] Audio card [8086:9d71] not detected after upgrade from linux
+    5.4 to 5.8 (LP: #1915117)
+    - [Config] set CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to y
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.14-rc7
+    - [Config] updateconfigs following 5.14-rc7 rebase
+    - [Config] Enable CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT
+    - [Config] annotations: set CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT to y
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] annotations: set
+      CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to y"
+    - Revert "UBUNTU: [Config] set CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to
+      y"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 24 Aug 2021 10:32:31 +0200
+
+linux-unstable (5.14.0-6.6) impish; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - no changes upload (to avoid picking up libc6 from -proposed)
+
+  * No changes upload (to avoid picking up libc6 from -proposed)
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 18 Aug 2021 13:41:16 +0200
+
+linux-unstable (5.14.0-5.5) impish; urgency=medium
+
+  * disable “CONFIG_HISI_DMA” config for ubuntu version (LP: #1936771)
+    - [Config] Disable CONFIG_HISI_DMA
+
+  * Dell XPS 17 (9710) PCI/internal sound card not detected  (LP: #1935850)
+    - ASoC: Intel: sof_sdw: include rt711.h for RT711 JD mode
+    - ASoC: Intel: sof_sdw: add quirk for Dell XPS 9710
+
+  * [regression] USB device is not detected during boot (LP: #1939638)
+    - SAUCE: Revert "usb: core: reduce power-on-good delay time of root hub"
+
+  * armhf build failure (LP: #1939308)
+    - SAUCE: arm: Fix instruction set selection for GCC 11
+
+  * REGRESSION: shiftfs lets sendfile fail with EINVAL (LP: #1939301)
+    - SAUCE: shiftfs: fix sendfile() invocations
+
+  * Wobbly graphics on built-in display since linux-image-5.11.0-22-generic
+    (LP: #1936708)
+    - SAUCE: drm/i915/dp: Use max params for older panels
+
+  * [SRU][H/OEM-5.10/OEM-5.13/U] Fix system hang after unplug tbt dock
+    (LP: #1938689)
+    - SAUCE: igc: fix page fault when thunderbolt is unplugged
+
+  * e1000e blocks the boot process when it tried to write checksum to its NVM
+    (LP: #1936998)
+    - SAUCE: e1000e: Do not take care about recovery NVM checksum
+
+  * [Regression] Audio card [8086:9d71] not detected after upgrade from linux
+    5.4 to 5.8 (LP: #1915117)
+    - [Config] set CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to y
+    - [Config] annotations: set CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC to y
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs following 5.14-rc6 rebase
+    - rebase to v5.14-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 17 Aug 2021 17:49:15 +0200
+
+linux-unstable (5.14.0-4.4) impish; urgency=medium
+
+  * impish/linux-unstable: 5.14.0-4.4 -proposed tracker (LP: #1938566)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous upstream changes
+    - Revert "riscv: Get CPU manufacturer information"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 03 Aug 2021 14:50:27 +0200
+
+linux-unstable (5.14.0-3.3) impish; urgency=medium
+
+  * Add additional Mediatek MT7921 WiFi/BT device IDs (LP: #1937004)
+    - SAUCE: Bluetooth: btusb: Add Mediatek MT7921 support for Foxconn
+    - SAUCE: Bluetooth: btusb: Add Mediatek MT7921 support for IMC Network
+    - SAUCE: Bluetooth: btusb: Add support for Foxconn Mediatek Chip
+
+  * Fix display output on HP hybrid GFX laptops (LP: #1936296)
+    - drm/i915: Invoke another _DSM to enable MUX on HP Workstation laptops
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.14-rc3
+    - [Config] updateconfigs following 5.14-rc3 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 26 Jul 2021 12:52:38 +0200
+
+linux-unstable (5.14.0-2.2) impish; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: xr-usb-serial: update return code for xr_usb_serial_tty_write_room()
+      and xr_usb_serial_tty_chars_in_buffer()
+    - SAUCE: platform/x86: dell-uart-backlight: update return code for
+      uart_chars_in_buffer(()
+    - [Config] updateconfigs following 5.14-rc2 rebase
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] FTBFS: disable ubuntu/xr-usb-serial"
+    - Revert "UBUNTU: [Config] FTBFS: disable DELL_UART_BACKLIGHT"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc2
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 22 Jul 2021 11:03:28 +0200
+
+linux-unstable (5.14.0-1.1) impish; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] bump kernel version to 5.14
+    - [Config] updateconfigs following 5.14-rc1 rebase
+    - [Config] update annotations
+    - [Packaging] FTBFS: disable zfs
+    - [Config] FTBFS: disable DELL_UART_BACKLIGHT
+    - [Config] FTBFS: disable ubuntu/xr-usb-serial
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] update variants"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.14-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 16 Jul 2021 15:20:04 +0200
+
+linux-unstable (5.14.0-0.0) impish; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 13 Jul 2021 12:15:35 +0200
+
+linux (5.13.0-11.11) impish; urgency=medium
+
+  * impish/linux: 5.13.0-11.11 -proposed tracker (LP: #1933854)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Support builtin revoked certificates (LP: #1932029)
+    - [Packaging] build canonical-revoked-certs.pem from branch/arch certs
+    - [Packaging] Revoke 2012 UEFI signing certificate as built-in
+    - [Config] Configure CONFIG_SYSTEM_REVOCATION_KEYS with revoked keys
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Change source package name to linux
+
+  * Miscellaneous upstream changes
+    - mm/page_alloc: Correct return value of populated elements if bulk array is
+      populated
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 29 Jun 2021 07:50:25 +0200
+
+linux (5.13.0-10.10) impish; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Jun 2021 08:40:05 +0200
+
+linux-unstable (5.13.0-10.10) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-10.10 -proposed tracker (LP: #1933795)
+
+  * Pixel format change broken for Elgato Cam Link 4K (LP: #1932367)
+    - media: uvcvideo: Fix pixel format change for Elgato Cam Link 4K
+
+  * initramfs-tools & kernel: use zstd as the default compression method
+    (LP: #1931725)
+    - s390/decompressor: correct BOOT_HEAP_SIZE condition
+    - s390/boot: add zstd support
+    - [Packaging] use ZSTD to compress s390 kernels
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: tls: fix chacha+bidir tests
+    - SAUCE: selftests: icmp_redirect: support expected failures
+    - [Config] update configs and annotations after rebase to 5.13
+
+  * Miscellaneous upstream changes
+    - tls: prevent oversized sendfile() hangs by ignoring MSG_MORE
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 28 Jun 2021 08:40:05 +0200
+
+linux-unstable (5.13.0-9.9) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-9.9 -proposed tracker (LP: #1933070)
+
+  * Add support for selective build of special drivers (LP: #1912789)
+    - [Packaging] Add support for ODM drivers
+    - [Packaging] Turn on ODM support for amd64
+    - [Packaging] Fix ODM support in actual build
+    - [Packaging] Fix ODM DRIVERS Kconfig
+
+  * Add support for IO functions of AAEON devices (LP: #1929504)
+    - ODM: [Config] update config for AAEON devices
+    - ODM: hwmon: add driver for AAEON devices
+    - ODM: leds: add driver for AAEON devices
+    - ODM: watchdog: add driver for AAEON devices
+    - ODM: gpio: add driver for AAEON devices
+    - ODM: mfd: Add support for IO functions of AAEON devices
+
+  * Disable hv-kvp-daemon.service on certain instance types (LP: #1932081)
+    - [Packaging]: Add kernel command line condition to hv-kvp-daemon service
+
+  * Fix non-working GPU on Some HP desktops (LP: #1931147)
+    - PCI: Coalesce host bridge contiguous apertures
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: seccomp: bump up timeout to 5min
+    - SAUCE: Revert "net/tls(TLS_SW): Add selftest for 'chunked' sendfile test"
+    - [Config] update annotations after rebase to 5.13-rc7
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 21 Jun 2021 10:55:36 +0200
+
+linux-unstable (5.13.0-8.8) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-8.8 -proposed tracker (LP: #1932018)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * initramfs-tools & kernel: use zstd as the default compression method
+    (LP: #1931725)
+    - [Config] use ZSTD to compress amd64 kernels
+
+  * Miscellaneous Ubuntu changes
+    - [Config] enable signing for ppc64el
+    - SAUCE: powerpc: Fix initrd corruption with relative jump labels
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 15 Jun 2021 15:07:34 +0200
+
+linux-unstable (5.13.0-7.7) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-7.7 -proposed tracker (LP: #1931840)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+    - [Packaging] resync getabis
+    - [Packaging] update helper scripts
+    - update dkms package versions
+
+  * Intel ADL-S graphics feature enabling (LP: #1931240)
+    - SAUCE: drm/i915/adl_s: ADL-S platform Update PCI ids for Mobile BGA
+
+  * Kernel package builds running out of space on builders (LP: #1930713)
+    - [Config] CONFIG_DEBUG_INFO_COMPRESSED=n
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] remove nvidia dkms build support
+    - [Config] remove now unsued do_dkms_nvidia* build variables
+    - [Config] enable signing for s390x
+    - [Config] update annotations after configs review
+    - [Config] update toolchain versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 14 Jun 2021 11:53:08 +0200
+
+linux-unstable (5.13.0-6.6) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-6.6 -proposed tracker (LP: #1931071)
+
+  * Kernel package builds running out of space on builders (LP: #1930713)
+    - [Debian] use stamps for flavour install targets
+    - [Debian] run install-$(flavour) targets during build phase
+    - [Debian] remove dh_testroot from install targets
+    - [Debian] dkms-build -- use fakeroot if not running as root
+    - [Debian] exclude $(DEBIAN)/__abi.current from linux-source
+
+  * [UBUNTU 21.04] tools/kvm_stat: Add restart delay (LP: #1921870)
+    - [Debian] install kvm_stat systemd service
+
+  * Debugging symbols (dbgsym) packages are missing GDB kernel scripts
+    (LP: #1928715)
+    - [Packaging] Build and include GDB Python scripts into debug packages
+
+  * Can't detect intel wifi 6235 (LP: #1920180)
+    - SAUCE: iwlwifi: add new pci id for 6235
+
+  * Select correct boot VGA when BIOS doesn't do it properly (LP: #1929217)
+    - vgaarb: Use ACPI HID name to find integrated GPU
+
+  * Fix kernel panic on Intel Bluetooth (LP: #1928838)
+    - Bluetooth: Shutdown controller after workqueues are flushed or cancelled
+
+  * build module CONFIG_SND_SOC_INTEL_SOUNDWIRE_SOF_MACH=m for 5.11,  5.13-rc2
+    and later (LP: #1921632)
+    - [Config] enable soundwire audio mach driver
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_SND_SOC_RT1308 can only be enabled on amd64
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 07 Jun 2021 10:45:13 +0200
+
+linux-unstable (5.13.0-5.5) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-5.5 -proposed tracker (LP: #1930205)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Config] set CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 31 May 2021 12:32:38 +0200
+
+linux-unstable (5.13.0-4.4) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-4.4 -proposed tracker (LP: #1929404)
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Support importing mokx keys into revocation list from the mok table
+    (LP: #1928679)
+    - SAUCE: integrity: add informational messages when revoking certs
+
+  * Support importing mokx keys into revocation list from the mok table
+    (LP: #1928679) // CVE-2020-26541 when certificates are revoked via
+    MokListXRT.
+    - SAUCE: integrity: Load mokx certs from the EFI MOK config table
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Temporarily disable signing for ppc64el and s390x
+    - SAUCE: Revert "UBUNTU: SAUCE: overlayfs: Be more careful about copying up
+      sxid files"
+    - SAUCE: Revert "UBUNTU: SAUCE: overlayfs: Propogate nosuid from lower and
+      upper mounts"
+    - SAUCE: Revert "UBUNTU: SAUCE: overlayfs: Enable user namespace mounts"
+    - SAUCE: Revert "UBUNTU: SAUCE: overlayfs: ensure mounter privileges when
+      reading directories"
+    - SAUCE: Revert "UBUNTU: SAUCE: fs: Move SB_I_NOSUID to the top of s_iflags"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 24 May 2021 13:06:17 +0200
+
+linux-unstable (5.13.0-3.3) impish; urgency=medium
+
+  * impish/linux-unstable: 5.13.0-3.3 -proposed tracker (LP: #1928655)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 17 May 2021 11:55:02 +0200
+
+linux-unstable (5.13.0-2.2) impish; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] enable CONFIG_DEBUG_INFO_COMPRESSED
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] temporarily disable BPF JIT"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Fri, 14 May 2021 09:19:02 +0200
+
+linux-unstable (5.13.0-1.1) impish; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.13-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 12 May 2021 11:35:23 +0200
+
+linux-unstable (5.13.0-0.0) impish; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 11 May 2021 08:40:09 +0200
+
+linux-unstable (5.12.0-11.11) impish; urgency=medium
+
+  * Impish update: v5.12.1 upstream stable release (LP: #1927094)
+    - net: hso: fix NULL-deref on disconnect regression
+    - USB: CDC-ACM: fix poison/unpoison imbalance
+    - iwlwifi: Fix softirq/hardirq disabling in iwl_pcie_gen2_enqueue_hcmd()
+    - cfg80211: fix locking in netlink owner interface destruction
+    - mei: me: add Alder Lake P device id.
+    - Linux 5.12.1
+
+  * Packaging resync (LP: #1786013) // Impish update: v5.12.1 upstream stable
+    release (LP: #1927094)
+    - update dkms package versions
+
+  * Gigabyte R120-T33 (ARM ThunderX SoC) fails to boot in ACPI mode
+    (LP: #1925075) // Impish update: v5.12.1 upstream stable release
+    (LP: #1927094)
+    - ACPI: GTDT: Don't corrupt interrupt mappings on watchdow probe failure
+
+  * Fix kernel panic at boot on dual GFX systems (LP: #1926792) // Impish
+    update: v5.12.1 upstream stable release (LP: #1927094)
+    - drm/amdgpu: Register VGA clients after init can no longer fail
+
+  * On TGL platforms screen shows garbage when browsing website by scrolling
+    mouse (LP: #1926579) // Impish update: v5.12.1 upstream stable release
+    (LP: #1927094)
+    - SAUCE: drm/i915/display: Disable PSR2 if TGL Display stepping is B1 from A0
+
+  * CirrusLogic: Cracking noises appears in built-in speaker when output volume
+    is set >80% (LP: #1924997) // Impish update: v5.12.1 upstream stable release
+    (LP: #1927094)
+    - SAUCE: ALSA: hda/cirrus: Use CS8409 Equalizer to fix abnormal sounds on
+      Bullseye
+
+  * Enable mute/micmute LEDs and limit mic boost on EliteBook 845 G8
+    (LP: #1925415) // Impish update: v5.12.1 upstream stable release
+    (LP: #1927094)
+    - ALSA: hda/realtek: Enable mute/micmute LEDs and limit mic boost on EliteBook
+      845 G8
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: PCI: Disable broken RTIT_BAR of Intel TH"
+    - Revert "UBUNTU: [Config] temporarily disable ZFS"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 04 May 2021 18:35:54 +0200
+
+linux-unstable (5.12.0-10.10) impish; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Drop versioned ABI directory names
+    - [Packaging] getabis: Download ABIs into an unversioned directory
+    - [Packaging] final-checks: Handle unversioned ABI directories
+    - bump to impish
+    - [Config] GCC version update
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 29 Apr 2021 12:27:20 +0200
+
+linux-unstable (5.12.0-9.9) impish; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 26 Apr 2021 11:14:16 -0500
+
+linux-unstable (5.12.0-8.8) hirsute; urgency=medium
+
+  * CVE-2021-3492
+    - SAUCE: shiftfs: free allocated memory in shiftfs_btrfs_ioctl_fd_replace()
+      error paths
+    - SAUCE: shiftfs: handle copy_to_user() return values correctly
+
+  * Fix no picture from HDMI when it's plugged after boot (LP: #1924238)
+    - drm/i915/display: Handle lane polarity for DDI port
+
+  * hirsute beta desktop AMD64 ISO kernel panic on boot when booting using UEFI
+    (LP: #1922403)
+    - SAUCE: efifb: Check efifb_pci_dev before using it
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v5.12-rc8
+    - [Config] updateconfigs following 5.12-rc8 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc8
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 19 Apr 2021 11:37:27 +0200
+
+linux-unstable (5.12.0-7.7) hirsute; urgency=medium
+
+  * drm/i915: Drop force_probe requirement for Rocket Lake (LP: #1905466)
+    - drm/i915/rkl: Remove require_force_probe protection
+
+  * HP m400 cartridges fail to find NIC when deploying hirsute (LP: #1918793)
+    - PCI: xgene: Fix cfg resource mapping
+
+  * Update - Fix no screen show on display after S3 on CML-R  (LP: #1922768)
+    - drm/i915/gen9bc: Handle TGP PCH during suspend/resume
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: RDMA/core: Introduce peer memory interface
+    - Rebase to v5.12-rc7
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 12 Apr 2021 11:48:07 +0200
+
+linux-unstable (5.12.0-6.6) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * i915 doesn't support some high pixel clock 4k * 60Hz monitors (LP: #1922372)
+    - drm/i915/vbt: update DP max link rate table
+
+  * Tegra "mmc0: Timeout waiting for hardware interrupt" (LP: #1921140)
+    - SAUCE: mmc: host: Add required callbacks to set/clear CQE_EN bit
+
+  * Enable ath11k debugfs/tracing (LP: #1922033)
+    - [Config] enable ath11k debugfs/tracing
+
+  * Fix mic on P620 after S3 resume (LP: #1921757)
+    - ALSA: usb-audio: Carve out connector value checking into a helper
+    - ALSA: usb-audio: Check connector value on resume
+
+  * Miscellaneous Ubuntu changes
+    - [Config] amd64,arm64: build KFENCE support but disable it by default
+      (KFENCE_SAMPLE_INTERVAL=0)
+    - Rebase to v5.12-rc6
+
+  * Miscellaneous upstream changes
+    - drm/dp: add MSO related DPCD registers
+    - drm/i915/edp: reject modes with dimensions other than fixed mode
+    - drm/i915/edp: always add fixed mode to probed modes in ->get_modes()
+    - drm/i915/edp: read sink MSO configuration for eDP 1.4+
+    - drm/i915/reg: add stream splitter configuration definitions
+    - drm/i915/mso: add splitter state readout for platforms that support it
+    - drm/i915/mso: add splitter state check
+    - drm/i915/edp: modify fixed and downclock modes for MSO
+    - drm/i915/edp: enable eDP MSO during link training
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Wed, 07 Apr 2021 11:42:55 +0200
+
+linux-unstable (5.12.0-5.5) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * alsa/realtek: extend the delay time in the  determine_headset_type for a
+    Dell AIO (LP: #1920747)
+    - SAUCE: ALSA: hda/realtek: fix a determine_headset_type issue for a Dell AIO
+
+  * power off stress test will hang on the TGL machines (LP: #1919930)
+    - SAUCE: ASoC: SOF: Intel: TGL: set shutdown callback to hda_dsp_shutdown
+    - [Config] set SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1 to n
+
+  * lockdown on power (LP: #1855668)
+    - SAUCE: (lockdown) powerpc: lock down kernel in secure boot mode
+
+  * Miscellaneous Ubuntu changes
+    - [Config] arm64 -- unify build_image and kernel_file values
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - SAUCE: xr-usb-serial: clean up indentation
+    - SAUCE: xr-usb-serial: clean up build warnings
+    - SAUCE: apparmor: Fix build error, make sk parameter const
+    - Rebase to v5.12-rc5
+    - [Config] updateconfigs following v5.12-rc5 rebase
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (lockdown) s390: Lock down the kernel when the IPL
+      secure flag is set"
+    - Revert "UBUNTU: SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to
+      indicate secure boot mode"
+    - Revert "UBUNTU: SAUCE: (lockdown) powerpc: lock down kernel in secure boot
+      mode"
+    - Revert "UBUNTU: SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic"
+    - Revert "UBUNTU: SAUCE: (lockdown) arm64: Allow locking down the kernel under
+      EFI secure boot"
+    - Revert "UBUNTU: SAUCE: (lockdown) KEYS: Make use of platform keyring for
+      module signature verify"
+    - Revert "UBUNTU: SAUCE: (lockdown) efi: Lock down the kernel if booted in
+      secure boot mode"
+    - Revert "UBUNTU: SAUCE: (lockdown) security: lockdown: expose a hook to lock
+      the kernel down"
+    - Revert "UBUNTU: SAUCE: (lockdown) Make get_cert_list() use
+      efi_status_to_str() to print error messages."
+    - Revert "UBUNTU: SAUCE: (lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err()."
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 29 Mar 2021 12:59:38 +0200
+
+linux-unstable (5.12.0-4.4) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Fix broken efifb on graphics device without driver (LP: #1914411)
+    - SAUCE: efifb: Ensure graphics device for efifb stays at PCI D0
+
+  * Fix system sleep on TGL systems with Intel ME (LP: #1919321)
+    - SAUCE: PCI: Serialize TGL e1000e PM ops
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v5.12-rc4
+    - [Config] updateconfigs following v5.12-rc4 rebase
+
+  * Miscellaneous upstream changes
+    - riscv: dts: fu740: fix cache-controller interrupts
+    - riscv: sifive: fu740: cpu{1, 2, 3, 4} set compatible to sifive, u74-mc
+    - riscv: sifive: unmatched: update for 16GB rev3
+    - riscv: Add 3 SBI wrapper functions to get cpu manufacturer information
+    - riscv: Get CPU manufacturer information
+    - riscv: Introduce alternative mechanism to apply errata solution
+    - riscv: sifive: apply errata "cip-453" patch
+    - clk: sifive: Add pcie_aux clock in prci driver for PCIe driver
+    - clk: sifive: Use reset-simple in prci driver for PCIe driver
+    - MAINTAINERS: Add maintainers for SiFive FU740 PCIe driver
+    - dt-bindings: PCI: Add SiFive FU740 PCIe host controller
+    - PCI: designware: Add SiFive FU740 PCIe host controller driver
+    - riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc4
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 22 Mar 2021 12:43:14 +0100
+
+linux-unstable (5.12.0-3.3) hirsute; urgency=medium
+
+  *  riscv: revert SiFive Unleashed CPUFreq (LP: #1917433)
+    - SAUCE: Revert "SiFive Unleashed CPUFreq"
+
+  * Dell Precision 5550 takes up to 10 seconds to respond when coming out of
+    sleep (LP: #1919123)
+    - SAUCE: Input: i8042 - add dmi quirk
+
+  * LRMv4: switch to signing nvidia modules via the Ubuntu Modules signing key
+    (LP: #1918134)
+    - [Packaging] sync dkms-build et al from LRMv4
+
+  * curtin: install flash-kernel in arm64 UEFI unexpected (LP: #1918427)
+    - [Packaging] Allow grub-efi-arm* to satisfy recommends on ARM
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Enable Tegra support in arm64 for NVIDIA Jetson (LP: #1918471)
+    - [Config] enable ARCH_TEGRA and all Tegra SOC's
+    - [Packaging] include modern Tegra modules
+
+  * Cirrus Audio Codec CS8409/CS42L42: Input Device does not switch to headset
+    Mic when a headset is inserted (LP: #1918378)
+    - SAUCE: ALSA: hda/cirrus: Fix Headset Mic volume control name
+
+  * Cirrus Audio Codec CS8409/CS42L42 support (LP: #1916554)
+    - ALSA: hda/cirrus: Increase AUTO_CFG_MAX_INS from 8 to 18
+    - ALSA: hda/cirrus: Add support for CS8409 HDA bridge and CS42L42 companion
+      codec.
+    - ALSA: hda/cirrus: Add jack detect interrupt support from CS42L42 companion
+      codec.
+    - ALSA: hda/cirrus: Add Headphone and Headset MIC Volume Control
+
+  * drm/i915: Drop force_probe requirement for JSL (LP: #1917843)
+    - SAUCE: drm/i915: Drop require_force_probe from JSL
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Skip d-i code if udebs are disabled
+    - [Packaging] Disable udebs if $DEBIAN/d-i doesn't exist
+    - [Packaging] remove dh-systemd build dependency
+    - [Config] fix several annotaions with enforcement typos
+    - [Config] refresh annotations
+    - [Config] updateconfigs following v5.12-rc3 rebase
+    - annotations: fixup after v5.12-rc3 rebase
+    - Rebase to v5.12-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 16 Mar 2021 18:43:03 +0100
+
+linux-unstable (5.12.0-2.2) hirsute; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v5.12-rc2
+    - [Config] updateconfigs following v5.12-rc2 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc2
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 08 Mar 2021 11:22:04 +0100
+
+linux-unstable (5.12.0-1.1) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Support no udeb profile (LP: #1916095)
+    - [Packaging] replace custom filter script with dctrl-tools
+    - [Packaging] correctly implement noudeb build profiles.
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] dkms-versions -- remove nvidia-graphics-drivers-440-server
+    - [Debian] run ubuntu-regression-suite for linux-unstable
+    - [Packaging] remove Provides: aufs-dkms
+    - [Config] update config and annotations following v5.12-rc1 rebase
+    - [Config] disable nvidia and nvidia_server builds
+    - [Config] temporarily disable ZFS
+    - temporarily disable modules check
+    - annotations: s390: temporarily remove CONFIG_KMSG_IDS
+    - [Config] amd64: FTBFS: disable HIO
+    - [Config] FTBFS: disable SHIFT_FS
+    - [Config] s390: temporarily remove CONFIG_KMSG_IDS
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] disable nvidia and nvidia_server builds"
+    - Revert "UBUNTU: SAUCE: s390: kernel message catalog"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.12-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 04 Mar 2021 18:26:12 +0100
+
+linux-unstable (5.12.0-0.0) hirsute; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 04 Mar 2021 18:17:32 +0100
+
+linux-unstable (5.11.0-10.11) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Support CML-S CPU + TGP PCH (LP: #1909457)
+    - drm/i915/rkl: new rkl ddc map for different PCH
+    - SAUCE: drm/i915/gen9_bc : Add TGP PCH support
+
+  * Use DCPD to control HP DreamColor panel (LP: #1911001)
+    - SAUCE: drm/dp: Another HP DreamColor panel brigntness fix
+
+  * Update nvidia dkms build for module linker script changes
+    - [Packaging] build-dkms--nvidia-N -- Update for preprocessed module linker
+      script
+
+  * Please trust Canonical Livepatch Service kmod signing key (LP: #1898716)
+    - [Config] enable CONFIG_MODVERSIONS=y
+    - [Packaging] build canonical-certs.pem from branch/arch certs
+    - [Config] add Canonical Livepatch Service key to SYSTEM_TRUSTED_KEYS
+    - [Config] add ubuntu-drivers key to SYSTEM_TRUSTED_KEYS
+
+  * Miscellaneous Ubuntu changes
+    - [Config] re-enable nvidia dkms
+    - SAUCE: selftests: memory-hotplug: bump timeout to 10min
+    - [Debian] update-aufs.sh -- Don't apply tmpfs-idr.patch
+    - [Config] Update configs
+    - [Config] disable nvidia and nvidia_server builds
+    - SAUCE: Import aufs driver
+    - [Config] CONFIG_AUFS_FS=n
+    - [Config] refresh annotations file
+    - [Config] set CONFIG_MIPI_I3C_HCI=m consistently
+    - [Config] set CONFIG_PINCTRL_MSM8953=m on armhf generic-lpae
+    - [Packaging] Change source package name to linux-unstable
+    - [Config] update LD_VERSION in config due to toolchain update
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: tmpfs: Don't use 64-bit inodes by defulat with 32-bit
+      ino_t"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 22 Feb 2021 07:18:07 +0100
+
+linux-unstable (5.11.0-9.10) hirsute; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 22 Feb 2021 07:02:45 +0100
+
+linux (5.11.0-9.10) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs/annotations after rebase to 5.11
+    - zfs-modules.ignore: add zzstd
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 15 Feb 2021 16:29:36 +0100
+
+linux (5.11.0-8.9) hirsute; urgency=medium
+
+  * Missing device id for Intel TGL-H ISH [8086:43fc] in intel-ish-hid driver
+    (LP: #1914543)
+    - SAUCE: HID: intel-ish-hid: ipc: Add Tiger Lake H PCI device ID
+
+  *  Add support for new Realtek ethernet NIC (LP: #1914604)
+    - r8169: Add support for another RTL8168FP
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: tmpfs: Don't use 64-bit inodes by defulat with 32-bit ino_t
+    - [Config] Set CONFIG_TMPFS_INODE64=n for s390x
+    - [Config] re-enable ZFS
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 08 Feb 2021 11:56:23 +0100
+
+linux (5.11.0-7.8) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  *  Boot fails: failed to validate module [nls_iso8859_1] BTF: -22
+    (LP: #1911359)
+    - SAUCE: x86/entry: build thunk_$(BITS) only if CONFIG_PREEMPTION=y
+
+  * Remove scary stack trace from Realtek WiFi driver (LP: #1913263)
+    - rtw88: reduce the log level for failure of tx report
+
+  * Fix unexpected AER/DPC on PCH400 and PCH500 (LP: #1913691)
+    - Revert "UBUNTU: SAUCE: PCI: Enable ACS quirk on all CML root ports"
+    - Revert "UBUNTU: SAUCE: PCI: Enable ACS quirk on CML root port"
+    - SAUCE: PCI/AER: Disable AER interrupt during suspend
+    - SAUCE: PCI/DPC: Disable DPC interrupt during suspend
+
+  * switch to an autogenerated nvidia series based core via dkms-versions
+    (LP: #1912803)
+    - [Packaging] nvidia -- use dkms-versions to define versions built
+    - [Packaging] update-version-dkms -- maintain flags fields
+
+  * Introduce the new NVIDIA 460-server series and update the 460 series
+    (LP: #1913200)
+    - [Config] dkms-versions -- add the 460-server nvidia driver
+
+  * Fix the video can't output through WD19TB connected with TGL platform during
+    cold-boot (LP: #1910211)
+    - SAUCE: drm/i915/dp: Prevent setting LTTPR mode if no LTTPR is detected
+
+  * Stop using get_scalar_status command in Dell AIO uart backlight driver
+    (LP: #1865402)
+    - SAUCE: platform/x86: dell-uart-backlight: add get_display_mode command
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/seccomp: Accept any valid fd in user_notification_addfd
+    - [Packaging] Don't disable CONFIG_DEBUG_INFO in headers packages
+    - [Config] update configs/annotations after rebase to 5.11-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 01 Feb 2021 10:27:52 +0100
+
+linux (5.11.0-6.7) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Prevent thermal shutdown during boot process (LP: #1906168)
+    - thermal/drivers/acpi: Use hot and critical ops
+    - thermal/core: Remove notify ops
+    - thermal: int340x: Fix unexpected shutdown at critical temperature
+    - thermal: intel: pch: Fix unexpected shutdown at critical temperature
+
+  * riscv: backport support for SiFive Unmatched (LP: #1910965)
+    - RISC-V: Update l2 cache DT documentation to add support for SiFive FU740
+    - RISC-V: sifive_l2_cache: Update L2 cache driver to support SiFive FU740
+    - dt-bindings: riscv: Update DT binding docs to support SiFive FU740 SoC
+    - riscv: dts: add initial support for the SiFive FU740-C000 SoC
+    - dt-bindings: riscv: Update YAML doc to support SiFive HiFive Unmatched board
+    - riscv: dts: add initial board data for the SiFive HiFive Unmatched
+    - PCI: microsemi: Add host driver for Microsemi PCIe controller
+    - Microsemi PCIe expansion board DT entry.
+    - SiFive Unleashed CPUFreq
+    - SiFive HiFive Unleashed: Add PWM LEDs (D1, D2, D3, D4)
+
+  * initramfs unpacking failed (LP: #1835660)
+    - lib/decompress_unlz4.c: correctly handle zero-padding around initrds.
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to 5.11-rc5
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 25 Jan 2021 09:31:31 +0100
+
+linux (5.11.0-5.6) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update config and annotations after rebase to 5.11-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 18 Jan 2021 10:46:10 +0100
+
+linux (5.11.0-4.5) hirsute; urgency=medium
+
+  *  Boot fails: failed to validate module [nls_iso8859_1] BTF: -22
+    (LP: #1911359)
+    - SAUCE: x86/entry: build thunk_$(BITS) only if CONFIG_PREEMPTION=y
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 14 Jan 2021 12:53:26 +0100
+
+linux (5.11.0-3.4) hirsute; urgency=medium
+
+  *  Boot fails: failed to validate module [nls_iso8859_1] BTF: -22
+    (LP: #1911359)
+    - bpf: Allow empty module BTFs
+    - libbpf: Allow loading empty BTFs
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 14 Jan 2021 07:43:45 +0100
+
+linux (5.11.0-2.3) hirsute; urgency=medium
+
+  * DMI entry syntax fix for Pegatron / ByteSpeed C15B (LP: #1910639)
+    - Input: i8042 - unbreak Pegatron C15B
+
+  * SYNA30B4:00 06CB:CE09 Mouse  on HP EliteBook 850 G7 not working at all
+    (LP: #1908992)
+    - HID: multitouch: Enable multi-input for Synaptics pointstick/touchpad device
+
+  * debian/scripts/file-downloader does not handle positive failures correctly
+    (LP: #1878897)
+    - [Packaging] file-downloader not handling positive failures correctly
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * CVE-2021-1052 // CVE-2021-1053
+    - [Packaging] NVIDIA -- Add the NVIDIA 460 driver
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Remove nvidia-455 dkms build
+    - SAUCE: ALSA: hda/realtek: fix right sounds and mute/micmute LEDs for HP
+      machines
+    - [Config] update configs and annotations after rebase to 5.11-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 11 Jan 2021 09:52:27 +0100
+
+linux (5.11.0-1.2) hirsute; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 07 Jan 2021 16:57:01 +0100
+
+linux (5.11.0-0.1) hirsute; urgency=medium
+
+  * dep-8 ubuntu-regression-suite tests are not run for all linux-hwe-* kernels
+    (LP: #1908529)
+    - [dep-8] Allow all hwe kernels
+
+  * Fix reading speed and duplex sysfs on igc device (LP: #1906851)
+    - igc: Report speed and duplex as unknown when device is runtime suspended
+
+  * rtwpci driver blocks the system to enter PC10, stuck at PC3 (LP: #1907200)
+    - SAUCE: rtw88: 8723de: let cpu enter c10
+
+  * [21.04 FEAT] Deactivate CONFIG_QETH_OSN kernel config option (LP: #1906370)
+    - [Config] Deactivate CONFIG_QETH_OSN kernel config option
+
+  * Add dpcd backlight control for 0x4c83 0x4f41 (LP: #1905663)
+    - SAUCE: drm/dp: Add dpcd backlight control for 0x4c83 0x4f41
+
+  * disable building bpf selftests (LP: #1908144)
+    - SAUCE: selftests/bpf: Clarify build error if no vmlinux
+    - SAUCE: selftests: Skip BPF selftests by default
+    - disable building bpf selftests (no VMLINUX_BTF)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - [Config] update configs and annotations after rebase to v5.11-rc1
+    - hio: fix build error with kernel 5.11
+    - SAUCE: shiftfs: fix build error with 5.11
+    - [Config] temporarily disable ZFS
+    - check-aliases: do not error if modules.alias does not exist
+    - ppc64el: don't build stripped vdso
+
+  * Miscellaneous upstream changes
+    - irq: export irq_check_status_bit
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.11-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 04 Jan 2021 09:17:48 +0100
+
+linux (5.11.0-0.0) hirsute; urgency=medium
+
+  * Empty entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 30 Dec 2020 09:04:41 +0100
+
+linux (5.10.0-9.10) hirsute; urgency=medium
+
+  * Use INTx for Pericom USB controllers (LP: #1906839)
+    - PCI: Disable MSI for Pericom PCIe-USB adapter
+
+  * disable building bpf selftests (LP: #1908144)
+    - SAUCE: selftests/bpf: clarify build error if no vmlinux
+    - SAUCE: selftests: Skip BPF seftests by default
+    - disable building bpf selftests (no VMLINUX_BTF)
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Enable CONFIG_BPF_LSM
+
+  * Miscellaneous upstream changes
+    - Revert "md: change mddev 'chunk_sectors' from int to unsigned"
+    - Revert "dm raid: fix discard limits for raid1 and raid10"
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 15 Dec 2020 10:16:14 +0100
+
+linux (5.10.0-8.9) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Fix bpf selftest compilation with clang 11
+    - bpf: Fix selftest compilation on clang 11
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update configs and annotations after rebase to v5.10
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 14 Dec 2020 08:57:57 +0100
+
+linux (5.10.0-7.8) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Fix linux-libc-dev build for hirsute forward port kernels (LP: #1904067)
+    - [Debian] Build linux-libc-dev for debian.master* branches
+
+  * Update kernel packaging to support forward porting kernels (LP: #1902957)
+    - [Debian] Update for leader included in BACKPORT_SUFFIX
+
+  * Introduce the new NVIDIA 455 series (LP: #1897751)
+    - [Packaging] NVIDIA -- Add signed modules for the 455 driver
+
+  * 5.10 kernel fails to boot with secure boot disabled (LP: #1904906)
+    - [Config] CONFIG_RCU_SCALE_TEST=n
+
+  * Miscellaneous Ubuntu changes
+    - [Config] s390x: disable GPIO_CDEV
+    - [Config] ARM_CMN=m
+    - [Config] disable GPIO_CDEV_V1
+    - [Config] Reorder annotations after 5.10-rc6 rebase
+    - [Packaging] Remove nvidia-435 dkms build
+    - [Packaging] Change source package name to linux
+    - [Config] Update configs and annotations after rebase to v5.10-rc7
+    - SAUCE: Revert "mm/filemap: add static for function
+      __add_to_page_cache_locked"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 07 Dec 2020 00:15:20 -0600
+
+linux (5.10.0-6.7) hirsute; urgency=medium
+
+  * Empty entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 06 Dec 2020 22:13:46 -0600
+
+linux-5.10 (5.10.0-6.7) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Avoid double newline when running insertchanges (LP: #1903293)
+    - [Packaging] insertchanges: avoid double newline
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging]: linux-modules should depend on linux-image
+    - [Packaging]: linux-image should suggest linux-modules-extra
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 30 Nov 2020 07:47:34 +0100
+
+linux-5.10 (5.10.0-5.6) hirsute; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] add CONFIG_INFINIBAND_VIRT_DMA
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 23 Nov 2020 13:17:44 +0100
+
+linux-5.10 (5.10.0-4.5) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] reduce the size required to build packages
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 16 Nov 2020 08:33:54 +0100
+
+linux-5.10 (5.10.0-3.4) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * e1000e: fix issues with S0ix (LP: #1902687)
+    - SAUCE: e1000e: fix S0ix flow to allow S0i3.2 subset entry
+    - SAUCE: e1000e: allow turning s0ix flows on for systems with ME
+    - SAUCE: e1000e: Add Dell's Comet Lake systems into s0ix heuristics
+    - SAUCE: e1000e: Add more Dell CML systems into s0ix heuristics
+    - [Config] Update CONFIG_E1000E for ppc64el in annotations
+
+  * perf: Add support for Rocket Lake (LP: #1902004)
+    - SAUCE: perf/x86/intel: Add Rocket Lake CPU support
+    - SAUCE: perf/x86/cstate: Add Rocket Lake CPU support
+    - SAUCE: perf/x86/msr: Add Rocket Lake CPU support
+    - SAUCE: perf/x86/intel/uncore: Add Rocket Lake support
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Disable CONFIG_CRYPTO_USER_API_ENABLE_OBSOLETE
+    - [Config] update CONFIG_MST_IRQ after rebase to 5.10-rc3
+    - [Config] drop obsolete SND_SST_IPC options
+    - [Config] re-enable ZFS
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 Nov 2020 09:37:08 +0100
+
+linux-5.10 (5.10.0-2.3) hirsute; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Switch arm64 default cpufreq governor to ondemand
+    - [Debian] Include scripts/module.lds from builddir in headers package
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 03 Nov 2020 21:01:52 -0600
+
+linux-5.10 (5.10.0-1.2) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Fix non-working Intel NVMe after S3 (LP: #1900847)
+    - SAUCE: PCI: Enable ACS quirk on all CML root ports
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] move to hirsute
+    - [Config] Update configs and annotations after rebase to 5.10-rc2
+    - [Config] Update numerous configs to conform with policy
+    - [Config] Switch default CPUFreq governer for arm64/armhf to schedultil
+    - [Config] Temporarily disable DEBUG_INFO_BTF for armhf
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 02 Nov 2020 13:18:27 -0600
+
+linux-5.10 (5.10.0-0.1) hirsute; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Update configs and annotations for v5.10-rc1
+    - SAUCE: platform/x86: dell-uart-backlight: rename kzfree() to
+      kfree_sensitive()
+    - SAUCE: apparmor: rename kzfree() to kfree_sensitive()
+    - SAUCE: LSM: change ima_read_file() to use lsmblob
+    - SAUCE: LSM: Use lsmblob in smk_netlbl_mls()
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Packaging] Change source package name to linux-5.10"
+    - s390: correct __bootdata / __bootdata_preserved macros
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.10-rc1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 27 Oct 2020 16:57:07 +0100
+
+linux-5.10 (5.10.0-0.0) groovy; urgency=medium
+
+  * Empty entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 26 Oct 2020 14:55:48 +0100
+
+linux-5.9 (5.9.0-2.3) groovy; urgency=medium
+
+  * Fix system reboot when disconnecting WiFi (LP: #1899726)
+    - iwlwifi: msix: limit max RX queues for 9000 family
+
+  * booting linux-generic-lpae armhf kernel under qemu results in relocation out
+    of range, and thus no modules can be loaded (LP: #1899519)
+    - [Config] armhf: ARM_MODULE_PLTS=y
+
+  * Fix broken MSI interrupt after HDA controller was suspended (LP: #1899586)
+    - ALSA: hda: fix jack detection with Realtek codecs when in D3
+
+  * CVE-2020-16119
+    - SAUCE: dccp: avoid double free of ccid on child socket
+
+  * python3-venv is gone (LP: #1896801)
+    - SAUCE: doc: remove python3-venv dependency
+
+  * *-tools-common packages descriptions have typo "PGKVER" (LP: #1898903)
+    - [Packaging] Fix typo in -tools template s/PGKVER/PKGVER/
+
+  * Enable brightness control on HP DreamColor panel (LP: #1898865)
+    - SAUCE: drm/i915/dpcd_bl: Skip testing control capability with force DPCD
+      quirk
+    - SAUCE: drm/dp: HP DreamColor panel brigntness fix
+
+  * HP Zbook Studio G7 boots into corrupted screen with PSR featured panel
+    (LP: #1897501)
+    - SAUCE: drm/i915/psr: allow overriding PSR disable param by quirk
+    - SAUCE: drm/dp: add DP_QUIRK_FORCE_PSR_CHIP_DEFAULT quirk to CMN prod-ID
+      19-15
+
+  * Fix broken e1000e device after S3 (LP: #1897755)
+    - SAUCE: e1000e: Increase polling timeout on MDIC ready bit
+
+  * Wakeup the system by touching the touchpad (LP: #1888331)
+    - HID: i2c-hid: Enable wakeup capability from Suspend-to-Idle
+
+  * Enable LTR for endpoints behind VMD (LP: #1896598)
+    - SAUCE: PCI/ASPM: Enable LTR for endpoints behind VMD
+
+  * [SRU] [Focal/OEM-5.6/Groovy]Fix AMD usb host controller lost after stress S3
+    (LP: #1893914)
+    - SAUCE: xhci: workaround for S3 issue on AMD SNPS 3.0 xHC
+
+  * debian/rules editconfigs does not work on s390x to change s390x only configs
+    (LP: #1863116)
+    - [Packaging] kernelconfig -- only update/edit configurations on architectures
+      we have compiler support
+
+  * Fix non-working NVMe after S3 (LP: #1895718)
+    - SAUCE: PCI: Enable ACS quirk on CML root port
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: bpf: Check CONFIG_BPF option for resolve_btfids
+    - SAUCE: tools resolve_btfids: Always force HOSTARCH
+    - packaging: arm64: add a 64KB mem pages flavour called 'generic-64k'
+    - packaging: arm64: generic-64k: skip ABI, modules and retpoline checks
+    - SAUCE: drm/i915/display: Fix null deref in intel_psr_atomic_check()
+    - [Config] Update toolchain versions
+    - [Config] Refresh annotations
+    - Add ubuntu-host module
+    - CONFIG_UBUNTU_HOST=m
+    - SAUCE: apparmor: drop prefixing abs root labels with '='
+    - SAUCE: apparmor: disable showing the mode as part of a secid to secctx
+    - SAUCE: apparmor: rename aa_sock() to aa_unix_sk()
+    - SAUCE: apparmor: LSM stacking: switch from SK_CTX() to aa_sock()
+    - SAUCE: LSM: Infrastructure management of the sock security
+    - SAUCE: LSM: Create and manage the lsmblob data structure.
+    - SAUCE: LSM: Use lsmblob in security_audit_rule_match
+    - SAUCE: LSM: Use lsmblob in security_kernel_act_as
+    - SAUCE: net: Prepare UDS for security module stacking
+    - SAUCE: LSM: Use lsmblob in security_secctx_to_secid
+    - SAUCE: LSM: Use lsmblob in security_secid_to_secctx
+    - SAUCE: LSM: Use lsmblob in security_ipc_getsecid
+    - SAUCE: LSM: Use lsmblob in security_task_getsecid
+    - SAUCE: LSM: Use lsmblob in security_inode_getsecid
+    - SAUCE: LSM: Use lsmblob in security_cred_getsecid
+    - SAUCE: IMA: Change internal interfaces to use lsmblobs
+    - SAUCE: LSM: Specify which LSM to display
+    - SAUCE: LSM: Ensure the correct LSM context releaser
+    - SAUCE: LSM: Use lsmcontext in security_secid_to_secctx
+    - SAUCE: LSM: Use lsmcontext in security_inode_getsecctx
+    - SAUCE: LSM: security_secid_to_secctx in netlink netfilter
+    - SAUCE: NET: Store LSM netlabel data in a lsmblob
+    - SAUCE: LSM: Verify LSM display sanity in binder
+    - SAUCE: Audit: Add new record for multiple process LSM attributes
+    - SAUCE: Audit: Add a new record for multiple object LSM
+    - SAUCE: LSM: Add /proc attr entry for full LSM context
+    - SAUCE: AppArmor: Remove the exclusive flag
+    - SAUCE: Audit: Fix for missing NULL check
+
+  * Miscellaneous upstream changes
+    - tty: hvcs: Don't NULL tty->driver_data until hvcs_cleanup()
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.9
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 14 Oct 2020 13:31:18 -0500
+
+linux-5.9 (5.9.0-1.2) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Update configs after rebase to 5.9-rc6
+    - SAUCE: dax: Fix compilation for CONFIG_DAX && !CONFIG_FS_DAX
+    - SAUCE: bpf: Use --no-fail option if CONFIG_BPF is not enabled
+    - SAUCE: tools resolve_btfids: Always force HOSTARCH
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.9-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 21 Sep 2020 14:39:34 -0500
+
+linux-5.9 (5.9.0-0.1) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Update configs and annotations for v5.9-rc1
+    - SAUCE: i915: Fix build error due to missing struct definition
+    - hio -- Update blk_queue_split() calls for changes in 5.9-rc1
+    - hio -- Updates for move of make_request_fn to struct block_device_operations
+    - [Config] Disable zfs dkms build
+    - [Config] Disable nvidia dkms build
+    - [Config] Disable nvidia server dkms builds
+    - SAUCE: remoteproc: qcom: Use div_u64() for 64-bit division
+    - SAUCE: PCI/ASPM: Enable ASPM for links under VMD domain
+    - [Packaging] Bind hv_vss_daemon startup to hv_vss device
+    - [Packaging] bind hv_fcopy_daemon startup to hv_fcopy device
+    - [Config] Re-enable UEFI signing for arm64
+    - SAUCE: Revert "UBUNTU: SAUCE: export __get_vm_area_caller() and map_kernel_range()"
+    - [Config] Set the default CPU governor to ONDEMAND
+    - [Packaging] update variants
+    - [Packaging] update helper scripts
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.9-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 17 Sep 2020 15:01:21 -0500
+
+linux-5.9 (5.9.0-0.0) groovy; urgency=medium
+
+  * Empty entry
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 18 Aug 2020 16:48:03 -0500
+
+linux (5.8.0-16.17) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-16.17 -proposed tracker (LP: #1891233)
+
+  * Miscellaneous Ubuntu changes
+    - hio -- Update to use bio_{start,end}_io_acct with 5.8+
+    - Enable hio driver
+    - [Packaging] Temporarily disable building doc package contents
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 11 Aug 2020 15:32:58 -0500
+
+linux (5.8.0-15.16) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-15.16 -proposed tracker (LP: #1891177)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Documentation: import error c_funcptr_sig_re, c_sig_re (sphinx-
+      doc/sphinx@0f49e30c)
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 11 Aug 2020 09:29:58 -0500
+
+linux (5.8.0-14.15) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-14.15 -proposed tracker (LP: #1891085)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * msg_zerocopy.sh in net from ubuntu_kernel_selftests failed (LP: #1812620)
+    - selftests/net: relax cpu affinity requirement in msg_zerocopy test
+
+  * Fix missing HDMI/DP Audio on an HP Desktop (LP: #1890441)
+    - ALSA: hda/hdmi: Add quirk to force connectivity
+
+  * Add initial audio support for Lenovo ThinkStation P620 (LP: #1890317)
+    - ALSA: usb-audio: Add support for Lenovo ThinkStation P620
+
+  * Fix IOMMU error on AMD Radeon Pro W5700 (LP: #1890306)
+    - PCI: Mark AMD Navi10 GPU rev 0x00 ATS as broken
+
+  * Enlarge hisi_sec2 capability (LP: #1890222)
+    - crypto: hisilicon - update SEC driver module parameter
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Re-enable signing for ppc64el
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 10 Aug 2020 15:26:46 -0500
+
+linux (5.8.0-13.14) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Remove i386 configs
+    - SAUCE: apply a workaround to re-enable CONFIG_CRYPTO_AEGIS128_SIMD
+    - SAUCE: export __get_vm_area_caller() and map_kernel_range()
+    - [Config] drop CONFIG_BINFMT_AOUT enforcement
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] disable CONFIG_CRYPTO_AEGIS128_SIMD"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 04 Aug 2020 09:51:50 +0200
+
+linux (5.8.0-12.13) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-12.13 -proposed tracker (LP: #1889481)
+
+  * Fix right speaker of HP laptop (LP: #1889375)
+    - SAUCE: hda/realtek: Fix right speaker of HP laptop
+
+  * blk_update_request error when mount nvme partition (LP: #1872383)
+    - SAUCE: nvme-pci: prevent SK hynix PC400 from using Write Zeroes command
+
+  * Add support for Atlantic NIC firmware v4 (LP: #1886908)
+    - Revert "UBUNTU: SAUCE: net: atlantic: Add support for firmware v4"
+    - net: atlantic: align return value of ver_match function with function name
+    - net: atlantic: add support for FW 4.x
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Fix debian/tests for linux-5.8 -> linux rename
+    - SAUCE: selftests/powerpc: return skip code for spectre_v2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 29 Jul 2020 16:58:47 -0500
+
+linux (5.8.0-11.12) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-11.12 -proposed tracker (LP: #1889336)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] dwarves is not required for linux-libc-dev or stage1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 Jul 2020 22:33:24 -0500
+
+linux (5.8.0-10.11) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-10.11 -proposed tracker (LP: #1889316)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Add more packages to Build-Depends-Indep for docs
+    - [Debian] Specify python executable in kmake
+    - [Debian] Don't treat warnings as errors during perf builds
+    - [Config] Disable signing for ppc64el
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 Jul 2020 17:09:52 -0500
+
+linux (5.8.0-9.10) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-9.10 -proposed tracker (LP: #1889140)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Fix s390x compile error on F32 utils/stat-display.c
+    - [Packaging] Add python3-venv to Build-Depends-Indep
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Jul 2020 21:01:46 -0500
+
+linux (5.8.0-8.9) groovy; urgency=medium
+
+  * groovy/linux: 5.8.0-8.9 -proposed tracker (LP: #1889104)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - update dkms package versions
+    - [Packaging] update variants
+
+  * Introduce the new NVIDIA 450-server and the 450 UDA series (LP: #1887674)
+    - [Packaging] NVIDIA -- Add signed modules for 450 450-server
+
+  * Introduce the new NVIDIA 418-server and 440-server series, and update the
+    current NVIDIA drivers (LP: #1881137)
+    - [packaging] add signed modules for the 418-server and the 440-server
+      flavours
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "radix-tree: Use local_lock for protection"
+    - [Config] CONFIG_DEBUG_INFO_COMPRESSED=n
+    - [Config] disable CONFIG_CRYPTO_AEGIS128_SIMD
+    - [Config] Enable nvidia dkms build
+
+  * Miscellaneous upstream changes
+    - usbip: tools: fix build error for multiple definition
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Jul 2020 11:18:12 -0500
+
+linux (5.8.0-7.8) groovy; urgency=medium
+
+  * Empty entry
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Jul 2020 09:22:19 +0200
+
+linux-5.8 (5.8.0-7.8) groovy; urgency=medium
+
+  * soc/amd/renoir: detect dmic from acpi table (LP: #1887734)
+    - ASoC: amd: add logic to check dmic hardware runtime
+    - ASoC: amd: add ACPI dependency check
+    - ASoC: amd: fixed kernel warnings
+
+  * linux 4.15.0-109-generic network DoS regression vs -108 (LP: #1886668)
+    - SAUCE: Revert "netprio_cgroup: Fix unlimited memory leak of v2 cgroups"
+
+  * Add support for Atlantic NIC firmware v4 (LP: #1886908)
+    - SAUCE: net: atlantic: Add support for firmware v4
+
+  * MGA G200e doesn't work under GDM Wayland (LP: #1886140)
+    - drm/mgag200: Remove HW cursor
+    - drm/mgag200: Clean up mga_set_start_address()
+    - drm/mgag200: Clean up mga_crtc_do_set_base()
+    - drm/mgag200: Move mode-setting code into separate helper function
+    - drm/mgag200: Split MISC register update into PLL selection, SYNC and I/O
+    - drm/mgag200: Update mode registers after plane registers
+    - drm/mgag200: Set pitch in a separate helper function
+    - drm/mgag200: Set primary plane's format in separate helper function
+    - drm/mgag200: Move TAGFIFO reset into separate function
+    - drm/mgag200: Move hiprilvl setting into separate functions
+    - drm/mgag200: Move register initialization into separate function
+    - drm/mgag200: Remove out-commented suspend/resume helpers
+    - drm/mgag200: Use simple-display data structures
+    - drm/mgag200: Convert to simple KMS helper
+    - drm/mgag200: Replace VRAM helpers with SHMEM helpers
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: s390/bpf: fix sign extension in branch_ku
+    - SAUCE: selftests: net: ip_defrag: modprobe missing nf_defrag_ipv6 support
+    - SAUCE: selftests: fib_nexthop_multiprefix: fix cleanup() netns deletion
+    - [packaging] debhelper-compat (= 10) (and retire debian/compat)
+    - [Config] Update configs after rebase to 5.8-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 20 Jul 2020 09:55:47 +0200
+
+linux-5.8 (5.8.0-6.7) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * perf build broken after updating to bintuils 2.34.90.20200706-1ubuntu1
+    (LP: #1887397)
+    - SAUCE: libtraceevent: Strip symbol version from nm output
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 13 Jul 2020 14:07:53 -0500
+
+linux-5.8 (5.8.0-5.6) groovy; urgency=medium
+
+  * linux-libc-dev broken for crossbuilding, Multi-Arch:same violation
+    (LP: #1886188)
+    - [Packaging] Produce linux-libc-deb package for riscv64
+    - [Debian] Disallow building linux-libc-dev from linux-riscv
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "UBUNTU: SAUCE: test_bpf: remove expected fail for Ctx heavy
+      transformations test on s390"
+    - SAUCE: Revert "test_bpf: flag tests that cannot be jited on s390"
+    - [Config] Update configs (gcc update)
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 13 Jul 2020 08:42:14 +0200
+
+linux-5.8 (5.8.0-4.5) groovy; urgency=medium
+
+  * Add generic LED class support for audio LED (LP: #1885896)
+    - ALSA: hda: generic: Always call led-trigger for mic mute LED
+    - ALSA: hda: generic: Add a helper for mic-mute LED with LED classdev
+    - ALSA: hda/realtek: Convert to cdev-variant of mic-mute LED controls
+    - ALSA: hda/conexant: Convert to cdev-variant of mic-mute LED controls
+    - ALSA: hda/sigmatel: Convert to cdev-variant of mic-mute LED controls
+    - ALSA: hda: generic: Drop unused snd_hda_gen_fixup_micmute_led()
+    - ALSA: hda: generic: Drop the old mic-mute LED hook
+    - ALSA: hda: generic: Add vmaster mute LED helper
+    - ALSA: hda/realtek: Use the new vmaster mute LED helper
+    - ALSA: hda/conexant: Use the new vmaster mute LED helper
+    - ALSA: hda/sigmatel: Use the new vmaster mute LED helper
+    - ALSA: hda/realtek: Unify LED helper code
+    - ALSA: hda: Let LED cdev handling suspend/resume
+
+  * seccomp_bpf fails on powerpc (LP: #1885757)
+    - SAUCE: selftests/seccomp: fix ptrace tests on powerpc
+
+  * CVE-2020-11935
+    - SAUCE: aufs: do not call i_readcount_inc()
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Update aufs to 5.x-rcN 20200622
+    - [Config] Update configs to set CONFIG_SND_HDA_GENERIC_LEDS value
+    - [Config] CONFIG_SECURITY_DMESG_RESTRICT=y
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 06 Jul 2020 08:14:28 -0500
+
+linux-5.8 (5.8.0-3.4) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - update dkms package versions
+
+  * lxc 1:4.0.2-0ubuntu1 ADT test failure with linux-5.8 5.8.0-1.2
+    (LP: #1884635)
+    - SAUCE: overlayfs: fix faulty rebase
+
+  * shiftfs: O_TMPFILE reports ESTALE (LP: #1872757)
+    - SAUCE: shiftfs: prevent ESTALE for LOOKUP_JUMP lookups
+
+  * shiftfs: fix btrfs regression (LP: #1884767)
+    - SAUCE: Revert "UBUNTU: SAUCE: shiftfs: fix dentry revalidation"
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_DEBUG_INFO_COMPRESSED=y
+    - SAUCE: regulator: rename da903x to da903x-regulator
+    - [Config] Add da903x to modules.ignore
+    - [Config] Update configs for rebase to 5.8-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 29 Jun 2020 08:48:25 -0500
+
+linux-5.8 (5.8.0-2.3) groovy; urgency=medium
+
+  * Support Audio Mute LED for two new HP laptops (LP: #1884251)
+    - ALSA: hda/realtek: Add mute LED and micmute LED support for HP systems
+
+  * CVE-2019-16089
+    - SAUCE: nbd_genl_status: null check for nla_nest_start
+
+  * tpm: fix TIS locality timeout problems (LP: #1881710)
+    - SAUCE: tpm: fix TIS locality timeout problems
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: security,perf: Allow further restriction of perf_event_open
+    - [Config] CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
+    - [Config] Update configs and annotations for 5.8-rc2
+    - [Config] Enable zfs
+    - [Config] Enable CONFIG_DEBUG_INFO_BTF
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 22 Jun 2020 15:05:54 -0500
+
+linux-5.8 (5.8.0-1.2) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Support linux-x.y in udeb package names
+    - [Packaging] Use SRCPKGNAME for udeb packages
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 17 Jun 2020 19:34:32 -0500
+
+linux-5.8 (5.8.0-0.1) groovy; urgency=medium
+
+  * Docker registry doesn't stay up and keeps restarting (LP: #1879690)
+    - Revert "UBUNTU: SAUCE: overlayfs: use shiftfs hacks only with shiftfs as underlay"
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Update source package name to linux-5.8
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - SAUCE: (lockdown) powerpc: lock down kernel in secure boot mode
+    - SAUCE: Import aufs driver
+    - [Config] Update configs for v5.8-rc1
+    - [Config] Update annotations for v5.8-rc1 config changes
+    - SAUCE: shiftfs -- Fix build errors from missing fiemap definitions
+    - Disable hio driver
+
+  * Miscellaneous upstream changes
+    - acpi: disallow loading configfs acpi tables when locked down
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.8-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 17 Jun 2020 11:54:24 -0500
+
+linux-5.8 (5.8.0-0.0) groovy; urgency=medium
+
+  * Empty entry
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 14 Jun 2020 22:40:35 -0500
+
+linux-5.7 (5.7.0-8.9) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Enforce all config annotations (LP: #1879327)
+    - [Config]: do not enforce CONFIG_VERSION_SIGNATURE
+    - [Config]: prepare to enforce all
+    - [Config]: enforce all config options
+
+  * Miscellaneous Ubuntu changes
+    - [Config]: annotations review after 5.7 rebase
+    - [Config] annotations: IXP4XX* depends on ARCH_IXP4XX
+    - [Config] THERMAL_GOV_POWER_ALLOCATOR=y
+    - [Config] annotations: SOC_CAMERA is marked as BROKEN
+    - [Config] annotations: NFSD_V4_2_INTER_SSC depends on NFS_FS=y
+    - [Config] annotations: CRYPTO_DEV_CHELSIO_TLS depends on legacy (and largely
+      unmantained) TLS_TOE
+    - [Config] annotations: SERIO_OLPC_APSP depends on ARCH_MMP
+    - [Config] RTW88_DEBUG=y
+    - [Config] annotations: ISDN_CAPI is a bool, and BT_CMTP depends on  it
+    - [Config] annotations SND_SOC_SOF_DEVELOPER_SUPPORT depends on
+      SND_SOC_SOF_DEVELOPER_SUPPORT
+    - [Config] annotations: SND_SOC_SOF_BAYTRAIL_SUPPORT is mutually exclusive
+      with SND_SST_ATOM_HIFI2_PLATFORM_ACPI
+    - [Config] annotations: DEBUG_IMX_UART_PORT is defined only any
+      DEBUG_IMX*_UART is enabled
+    - [Config] annotations: HW_RANDOM_IMX_RNGC depends on SOC_IMX25
+    - [Config] annotations: armhf: VIRTUALIZATION support was removed for arm32
+    - [Config] annotations: arm64: remove DEBUG_ALIGN_RODATA
+    - [Config] annotations: ppc64: DATA_SHIFT defaults to PPC_PAGE_SHIFT
+    - [Config] arm64: enforce ARM64_USE_LSE_ATOMICS
+    - [Config] s390x: MOST is not set
+    - [Config] s390x: BCM84881_PHY is not set
+    - [Config] s390x: XILINX_LL_TEMAC is not set
+    - [Config] s390x: PHY_INTEL_EMMC requires GENERIC_PHY (off by default on
+      s390x)
+    - [Config] s390x: CHECK_STACK conflicts with VMAP_STACK
+    - [Config] annotations: s390x: NODES_SHIFT=1
+    - [Config] annotations: import new symbols
+    - [Config] annotations: remove unmatched menu and options
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Fri, 12 Jun 2020 12:03:01 +0200
+
+linux-5.7 (5.7.0-7.8) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+    - [Packaging] update helper scripts
+
+  * [UBUNTU 20.04] s390x/pci: fix linking between PF and VF for multifunction
+    devices (LP: #1879704)
+    - PCI/IOV: Introduce pci_iov_sysfs_link() function
+    - s390/pci: create links between PFs and VFs
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Disable UEFI signing for arm64
+    - Rebase to v5.7.1
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7.1
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 08 Jun 2020 11:16:58 +0200
+
+linux-5.7 (5.7.0-6.7) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - update dkms package versions
+
+  * shiftfs: fix btrfs snapshot deletion (LP: #1879688)
+    - SAUCE: shiftfs: let userns root destroy subvolumes from other users
+
+  * seccomp_benchmark times out on eoan (LP: #1881576)
+    - SAUCE: selftests/seccomp: use 90s as timeout
+
+  * Realtek 8723DE [10ec:d723] subsystem [10ec:d738]  disconnects unsolicitedly
+    when Bluetooth is paired: Reason: 23=IEEE8021X_FAILED (LP: #1878147)
+    - SAUCE: Revert "UBUNTU: SAUCE: rtw88: Move driver IQK to set channel before
+      association for 11N chip"
+    - SAUCE: Revert "UBUNTU: SAUCE: rtw88: fix rate for a while after being
+      connected"
+    - SAUCE: Revert "UBUNTU: SAUCE: rtw88: No retry and report for auth and assoc"
+    - SAUCE: Revert "UBUNTU: SAUCE: rtw88: 8723d: Add coex support"
+    - rtw88: 8723d: Add coex support
+    - SAUCE: rtw88: coex: 8723d: set antanna control owner
+    - SAUCE: rtw88: coex: 8723d: handle BT inquiry cases
+    - SAUCE: rtw88: fix EAPOL 4-way failure by finish IQK earlier
+
+  * ASoC/amd: add audio driver for amd renoir (LP: #1881046)
+    - ASoC: amd: add Renoir ACP3x IP register header
+    - ASoC: amd: add Renoir ACP PCI driver
+    - ASoC: amd: add acp init/de-init functions
+    - ASoC: amd: create acp3x pdm platform device
+    - ASoC: amd: add ACP3x PDM platform driver
+    - ASoC: amd: irq handler changes for ACP3x PDM dma driver
+    - ASoC: amd: add acp3x pdm driver dma ops
+    - ASoC: amd: add ACP PDM DMA driver dai ops
+    - ASoC: amd: add Renoir ACP PCI driver PM ops
+    - ASoC: amd: add ACP PDM DMA driver pm ops
+    - ASoC: amd: enable Renoir acp3x drivers build
+    - ASoC: amd: create platform devices for Renoir
+    - ASoC: amd: RN machine driver using dmic
+    - ASoC: amd: enable build for RN machine driver
+    - ASoC: amd: fix kernel warning
+    - ASoC: amd: refactoring dai_hw_params() callback
+    - ASoC: amd: return error when acp de-init fails
+    - [Config]: enable amd renoir ASoC audio
+
+  * Slow send speed with Intel I219-V on Ubuntu 18.04.1 (LP: #1802691)
+    - e1000e: Disable TSO for buffer overrun workaround
+
+  * Fix incorrect speed/duplex when I210 device is runtime suspended
+    (LP: #1880656)
+    - igb: Report speed and duplex as unknown when device is runtime suspended
+
+  * Fix Pericom USB controller OHCI/EHCI PME# defect (LP: #1879321)
+    - serial: 8250_pci: Move Pericom IDs to pci_ids.h
+    - PCI: Avoid Pericom USB controller OHCI/EHCI PME# defect
+
+  * [UBUNTU 20.04] s390x/pci: enumerate pci functions per physical adapter
+    (LP: #1874056)
+    - s390/pci: Expose new port attribute for PCIe functions
+    - s390/pci: adaptation of iommu to multifunction
+    - s390/pci: define kernel parameters for PCI multifunction
+    - s390/pci: define RID and RID available
+    - s390/pci: create zPCI bus
+    - s390/pci: adapt events for zbus
+    - s390/pci: Handling multifunctions
+    - s390/pci: Do not disable PF when VFs exist
+    - s390/pci: Documentation for zPCI
+    - s390/pci: removes wrong PCI multifunction assignment
+
+  * add 16-bit width registers support for EEPROM at24 device (LP: #1876699)
+    - regmap-i2c: add 16-bit width registers support
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Enable virtualbox guest and shared-folder modules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 01 Jun 2020 16:11:24 -0500
+
+linux-5.7 (5.7.0-5.6) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * [UBUNTU 20.04] PSI generates overhead on s390x (LP: #1876044)
+    - Ubuntu: [Config] CONFIG_PSI is enabled by default, but creates additional
+      overhead on s390x, hence should be disabled by default on s390x only.
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v5.7-rc7
+    - [Config] ppc64el: disable STRICT_KERNEL_RWX
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 25 May 2020 11:44:09 +0200
+
+linux-5.7 (5.7.0-4.5) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * update-initramfs complains of missing amdgpu firmware files (LP: #1873325)
+    - SAUCE: drm/amdgpu: Remove unreleased arcturus and navi12 firmware from
+      modinfo
+
+  * Support DMIC micmute LED on HP platforms (LP: #1876859)
+    - ALSA: hda/realtek - Introduce polarity for micmute LED GPIO
+    - ALSA: hda/realtek - Enable micmute LED on and HP system
+    - ALSA: hda/realtek - Add LED class support for micmute LED
+    - ALSA: hda/realtek - Fix unused variable warning w/o
+      CONFIG_LEDS_TRIGGER_AUDIO
+    - ASoC: SOF: Update correct LED status at the first time usage of
+      update_mute_led()
+
+  * Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW),
+    REV=0x354 [8086:a0f0] subsystem id [1a56:1651] wireless adapter not found
+    due to firmware crash (LP: #1874685)
+    - SAUCE: iwlwifi: pcie: handle QuZ configs with killer NICs as well
+
+  * rtkit-daemon[*]: Failed to make ourselves RT: Operation not permitted after
+    upgrade to 20.04 (LP: #1875665)
+    - [Config] Turn off CONFIG_RT_GROUP_SCHED everywhere
+
+  * Unable to handle kernel pointer dereference in virtual kernel address space
+    on Eoan (LP: #1876645)
+    - SAUCE: overlayfs: fix shitfs special-casing
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: skip building selftest 'runqslower' if kernel not built
+    - Rebase to v5.7-rc6
+    - [Config] updateconfigs after 5.7-rc6 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7-rc6
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 18 May 2020 11:27:25 +0200
+
+linux-5.7 (5.7.0-3.4) groovy; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7-rc5
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * getitimer returns it_value=0 erroneously (LP: #1349028)
+    - [Config] CONTEXT_TRACKING_FORCE policy should be unset
+
+  * lockdown on power (LP: #1855668) // Ubuntu Kernel Support for OpenPOWER NV
+    Secure & Trusted Boot (LP: #1866909)
+    - [Config] Enable configs for OpenPOWER NV Secure & Trusted Boot
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Import aufs driver
+    - [Config] Enable aufs
+    - [Config] annotations: remove SND_SOC_SOF_HDA_COMMON_HDMI_CODEC
+    - [Config] Remove CONFIG_SND_HDA_INTEL_DETECT_DMIC from annotations
+    - [Debian] final-checks -- Do not remove ~* from abi
+    - [Config] Enable 5-level page table support for x86
+    - [Config] updateconfigs after 5.7-rc5 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 11 May 2020 10:25:42 +0200
+
+linux-5.7 (5.7.0-2.3) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - update dkms package versions
+    - [Packaging] update helper scripts
+
+  * ASUS T100HAN boots to a blank screen with a cursor [i965: Failed to submit
+    batchbuffer: Input/output error] (LP: #1860754)
+    - [Config] CONFIG_PMIC_OPREGION=y and CONFIG_GPIO_CRYSTAL_COVE=y for amd64
+
+  * ubuntu/focal64 fails to mount Vagrant shared folders  (LP: #1873506)
+    - [Packaging] Move virtualbox modules to linux-modules
+    - [Packaging] Remove vbox and zfs modules from generic.inclusion-list
+
+  * built-using constraints preventing uploads (LP: #1875601)
+    - temporarily drop Built-Using data
+
+  * dkms artifacts may expire from the pool (LP: #1850958)
+    - [Packaging] autoreconstruct -- manage executable debian files
+    - [packaging] handle downloads from the librarian better
+
+  * Add signed modules for the 435 NVIDIA driver (LP: #1875888)
+    - [Packaging] NVIDIA -- add signed modules for the 435 NVIDIA driver
+
+  * [Selftests] Apply various fixes and improvements (LP: #1870543)
+    - SAUCE: selftests/seccomp -- Disable timeout for seccomp tests
+
+  * [17.04 FEAT] Integrate kernel message catalogue for s390x into Ubuntu
+    distribution (LP: #1628889)
+    - SAUCE: s390: kernel message catalog
+
+  * Overlayfs in user namespace leaks directory content of inaccessible
+    directories (LP: #1793458) // CVE-2018-6559
+    - SAUCE: overlayfs: ensure mounter privileges when reading directories
+
+  * suspend only works once on ThinkPad X1 Carbon gen 7 (LP: #1865570)
+    - SAUCE: e1000e: Disable s0ix flow for X1 Carbon 7th
+
+  * [ICL] TC port in legacy/static mode can't be detected due TCCOLD
+    (LP: #1868936)
+    - drm/i915/display: Move out code to return the digital_port of the aux ch
+    - drm/i915/display: Add intel_legacy_aux_to_power_domain()
+    - drm/i915/display: Split hsw_power_well_enable() into two
+    - drm/i915/tc/icl: Implement TC cold sequences
+    - drm/i915/tc: Skip ref held check for TC legacy aux power wells
+    - drm/i915/tc/tgl: Implement TC cold sequences
+    - drm/i915/tc: Catch TC users accessing FIA registers without enable aux
+    - drm/i915/tc: Do not warn when aux power well of static TC ports timeout
+
+  * Touchpad doesn't work on Dell Inspiron 7000 2-in-1 (LP: #1851901)
+    - Revert "UBUNTU: SAUCE: mfd: intel-lpss: add quirk for Dell XPS 13 7390
+      2-in-1"
+
+  * 'Elan touchpad' not detected on 'Lenovo ThinkBook 15 IIL' (LP: #1861610)
+    - SAUCE: Input: elan_i2c - add more hardware ID for Lenovo laptop
+
+  * linux-image-5.0.0-35-generic breaks checkpointing of container
+    (LP: #1857257)
+    - SAUCE: overlayfs: use shiftfs hacks only with shiftfs as underlay
+
+  * alsa/sof: kernel oops on the machine without Intel hdmi audio codec (a
+    regression in the  asoc machine driver) (LP: #1874359)
+    - ASoC: intel/skl/hda - fix oops on systems without i915 audio codec
+
+  * Add debian/rules targets to compile/run kernel selftests (LP: #1874286)
+    - [Packaging] add support to compile/run selftests
+
+  * 5.4.0-24.28 does not seem to apply rtprio, whereas -21 does. (LP: #1873315)
+    - [Config] lowlatency: turn off RT_GROUP_SCHED
+
+  * alsa/sof: external mic can't be deteced on Lenovo and HP laptops
+    (LP: #1872569)
+    - SAUCE: ASoC: intel/skl/hda - set autosuspend timeout for hda codecs
+
+  * shiftfs: O_TMPFILE reports ESTALE (LP: #1872757)
+    - SAUCE: shiftfs: fix dentry revalidation
+
+  * shiftfs: broken shiftfs nesting (LP: #1872094)
+    - SAUCE: shiftfs: record correct creator credentials
+
+  * lockdown on power (LP: #1855668)
+    - SAUCE: (lockdown) powerpc: lock down kernel in secure boot mode
+
+  * Add support for Realtek 8723DE wireless adapter (LP: #1780590)
+    - SAUCE: rtw88: add adaptivity support for EU/JP regulatory
+    - SAUCE: rtw88: update tx descriptor of mgmt and rsvd page packets
+    - SAUCE: rtw88: sar: dump sar information via debugfs
+    - SAUCE: rtw88: 8723d: add IQ calibration
+    - SAUCE: rtw88: 8723d: Add power tracking
+    - SAUCE: rtw88: 8723d: implement flush queue
+    - SAUCE: rtw88: 8723d: set ltecoex register address in chip_info
+    - SAUCE: rtw88: 8723d: Add coex support
+    - SAUCE: rtw88: 8723d: Add shutdown callback to disable BT USB suspend
+
+  * Fix authentication fail on Realtek WiFi 8723de (LP: #1871300)
+    - SAUCE: rtw88: No retry and report for auth and assoc
+    - SAUCE: rtw88: fix rate for a while after being connected
+    - SAUCE: rtw88: Move driver IQK to set channel before association for 11N chip
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: rtw88: fix 'const' mismatch in power suequence hooks
+    - SAUCE: rtw88: fix 'const' mismatch in
+      __priority_queue_cfg_legacy()/__priority_queue_cfg()
+    - [Config] RTW88=m
+    - SAUCE: (lockdown) Revert carried-forward lockdown patches
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - [Config] Add back CONFIG_LOCK_DOWN_IN_SECURE_BOOT annotation for ppc64el
+    - [Config] CONFIG_RT_GROUP_SCHED=y
+    - [Packaging] Include modules.builtin.modinfo in linux-modules
+    - SAUCE: LSM: Infrastructure management of the sock security
+    - SAUCE: Fix-up af_unix mediation for sock infrastructure management
+    - SAUCE: Revert "apparmor: Allow filtering based on secmark policy"
+    - SAUCE: Revert "apparmor: Parse secmark policy"
+    - SAUCE: Revert "apparmor: Add a wildcard secid"
+    - SAUCE: Revert "apparmor: fixup secid map conversion to using IDR"
+    - SAUCE: Revert "apparmor: Use an IDR to allocate apparmor secids"
+    - SAUCE: Revert "apparmor: add support for mapping secids and using secctxes"
+    - Update dropped.txt for restored apparmor patches
+    - Remove lockdown patches from dropped.txt
+    - SAUCE: powerpc/ima: require IMA module signatures only if MODULE_SIG is not
+      enabled
+    - SAUCE: selftests/ftrace: Use printf instead of echo in kprobe syntax error
+      tests
+    - SAUCE: selftests/net -- disable l2tp.sh test
+    - SAUCE: selftests/net -- disable timeout
+    - SAUCE: tools: hv: Update shebang to use python3 instead of python
+    - Remove dropped.txt
+    - [Packaging] move linux-doc and linux-libc-dev stubs to debian.master
+    - [Debian] Support generating configs for riscv64
+    - [Config] CONFIG_KMSG_IDS=y for s390x
+    - [Packaging] add libcap-dev dependency
+    - [Config] CONFIG_AD5770R=m
+    - [Config] CONFIG_AL3010=m
+    - [Config] CONFIG_APPLE_MFI_FASTCHARGE=m
+    - [Config] CONFIG_BAREUDP=m
+    - [Config] CONFIG_CRYPTO_DEV_OCTEONTX_CPT=m
+    - [Config] CONFIG_CRYPTO_DEV_ZYNQMP_AES=m
+    - [Config] CONFIG_DRM_DISPLAY_CONNECTOR=m
+    - [Config] CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
+    - [Config] CONFIG_DRM_PANEL_ELIDA_KD35T133=m
+    - [Config] CONFIG_DRM_PANEL_FEIXIN_K101_IM2BA02=m
+    - [Config] CONFIG_DRM_PANEL_NOVATEK_NT35510=m
+    - [Config] CONFIG_DRM_PANEL_SAMSUNG_S6E88A0_AMS452EF01=m
+    - [Config] CONFIG_DRM_PARADE_PS8640=m
+    - [Config] CONFIG_DRM_SIMPLE_BRIDGE=m
+    - [Config] CONFIG_DRM_TIDSS=m
+    - [Config] CONFIG_DRM_TI_TPD12S015=m
+    - [Config] CONFIG_DRM_TOSHIBA_TC358768=m
+    - [Config] CONFIG_EDAC_DMC520=m
+    - [Config] CONFIG_EXFAT_FS=m
+    - [Config] CONFIG_GP2AP002=m
+    - [Config] CONFIG_GPIO_MLXBF2=m
+    - [Config] CONFIG_HID_GLORIOUS=m
+    - [Config] CONFIG_HID_MCP2221=m
+    - [Config] CONFIG_HMC425=m
+    - [Config] CONFIG_ICP10100=m
+    - [Config] CONFIG_IMX8MM_THERMAL=m
+    - [Config] CONFIG_IMX_SC_THERMAL=m
+    - [Config] CONFIG_INTERCONNECT_QCOM_OSM_L3=m
+    - [Config] CONFIG_INTERCONNECT_QCOM_SC7180=m
+    - [Config] CONFIG_K3_RTI_WATCHDOG=m
+    - [Config] CONFIG_MDIO_IPQ8064=m
+    - [Config] CONFIG_MDIO_MVUSB=m
+    - [Config] CONFIG_MHI_BUS=m
+    - [Config] CONFIG_OCTEONTX2_VF=m
+    - [Config] CONFIG_PHY_CADENCE_TORRENT=m
+    - [Config] CONFIG_PHY_QCOM_USB_HS_28NM=m
+    - [Config] CONFIG_PHY_QCOM_USB_SS=m
+    - [Config] CONFIG_PINCTRL_DA9062=m
+    - [Config] CONFIG_PINCTRL_IPQ6018=m
+    - [Config] CONFIG_PTP_1588_CLOCK_IDT82P33=m
+    - [Config] CONFIG_PTP_1588_CLOCK_VMW=m
+    - [Config] CONFIG_QCOM_IPA=m
+    - [Config] CONFIG_REGULATOR_MP5416=m
+    - [Config] CONFIG_REGULATOR_MP886X=m
+    - [Config] CONFIG_RN5T618_ADC=m
+    - [Config] CONFIG_RTC_DRV_MT2712=m
+    - [Config] CONFIG_RTC_DRV_RC5T619=m
+    - [Config] CONFIG_SC_MSS_7180=m
+    - [Config] CONFIG_SENSORS_AXI_FAN_CONTROL=m
+    - [Config] CONFIG_SM_GCC_8250=m
+    - [Config] CONFIG_SND_BCM63XX_I2S_WHISTLER=m
+    - [Config] CONFIG_SND_MESON_AIU=m
+    - [Config] CONFIG_SND_MESON_G12A_TOACODEC=m
+    - [Config] CONFIG_SND_MESON_GX_SOUND_CARD=m
+    - [Config] CONFIG_SND_SOC_AMD_RV_RT5682_MACH=m
+    - [Config] CONFIG_SND_SOC_INTEL_SOF_PCM512x_MACH=m
+    - [Config] CONFIG_SND_SOC_MESON_T9015=m
+    - [Config] CONFIG_SND_SOC_RT5682_SDW=m
+    - [Config] CONFIG_SND_SOC_TLV320ADCX140=m
+    - [Config] CONFIG_SPI_FSI=m
+    - [Config] CONFIG_SPI_MTK_NOR=m
+    - [Config] CONFIG_SPI_MUX=m
+    - [Config] CONFIG_SPRD_THERMAL=m
+    - [Config] CONFIG_SURFACE_3_POWER_OPREGION=m
+    - [Config] CONFIG_TINYDRM_ILI9486=m
+    - [Config] CONFIG_TI_K3_AM65_CPSW_NUSS=m
+    - [Config] CONFIG_TYPEC_MUX_INTEL_PMC=m
+    - [Config] CONFIG_UACCE=m
+    - [Config] CONFIG_UNIPHIER_XDMAC=m
+    - [Config] CONFIG_USB_MAX3420_UDC=m
+    - [Config] CONFIG_USB_RAW_GADGET=m
+    - [Config] CONFIG_VHOST_VDPA=m
+    - [Config] CONFIG_VIDEO_IMX219=m
+    - [Config] CONFIG_VIDEO_SUN8I_ROTATE=m
+    - [Config] CONFIG_VIRTIO_VDPA=m
+    - [Config] CONFIG_MOST_COMPONENTS=m
+    - [Config] CONFIG_MFD_IQS62X=m
+    - packaging: getabis: switch to ckt-ppa:bootstrap/linux-5.7
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: rtw88: add rtw_read8_mask and rtw_read16_mask"
+    - Revert "UBUNTU: SAUCE: drm/i915/fbc: disable framebuffer compression on
+      IceLake"
+    - Revert "UBUNTU: SAUCE: platform/x86: dell-uart-backlight: move retry block"
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 04 May 2020 10:48:48 +0200
+
+linux-5.7 (5.7.0-1.2) groovy; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: hio: pass make_request ptr directly to blk_alloc_queue()
+    - SAUCE: hio: locally define disk_map_sector_rcu()
+    - SAUCE: hio: Revert "block: unexport disk_map_sector_rcu"
+    - SAUCE: hio: include <linux/part_stat.h>
+    - [Config] amd64: i386: HIO=m
+    - [Config] updateconfigs after 5.7-rc3 rebase
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 27 Apr 2020 11:31:38 +0200
+
+linux-5.7 (5.7.0-0.1) groovy; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after rebase to 5.7-rc1
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.7-rc1
+  * Rebase to v5.7-rc2
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 16 Apr 2020 11:53:58 +0200
+
+linux-5.7 (5.7.0-0.0) focal; urgency=medium
+
+  * Dummy entry
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Thu, 16 Apr 2020 11:53:58 +0200
+
+linux-5.6 (5.6.0-7.7) focal; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - update dkms package versions
+
+  * Kernel Oops - general protection fault: 0000 [#1] SMP PTI after
+    disconnecting thunderbolt docking station (LP: #1864754)
+    - SAUCE: ptp: free ptp clock properly
+
+  * swap storms kills interactive use (LP: #1861359)
+    - SAUCE: mm/page_alloc.c: disable memory reclaim watermark boosting by default
+
+  * sysfs: incorrect network device permissions on network namespace change
+    (LP: #1865359)
+    - sysfs: add sysfs_file_change_owner()
+    - sysfs: add sysfs_link_change_owner()
+    - sysfs: add sysfs_group{s}_change_owner()
+    - sysfs: add sysfs_change_owner()
+    - device: add device_change_owner()
+    - drivers/base/power: add dpm_sysfs_change_owner()
+    - net-sysfs: add netdev_change_owner()
+    - net-sysfs: add queue_change_owner()
+    - net: fix sysfs permssions when device changes network namespace
+    - sysfs: fix static inline declaration of sysfs_groups_change_owner()
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after rebase to 5.6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 31 Mar 2020 10:45:09 +0200
+
+linux-5.6 (5.6.0-6.6) focal; urgency=medium
+
+  * suspend only works once on ThinkPad X1 Carbon gen 7 (LP: #1865570)
+    - SAUCE: e1000e: Disable s0ix flow for X1 Carbon 7th
+
+  *  Make Dell WD19 dock more reliable after suspend (LP: #1868217)
+    - xhci: Ensure link state is U3 after setting USB_SS_PORT_LS_U3
+    - xhci: Wait until link state trainsits to U0 after setting USB_SS_PORT_LS_U0
+    - xhci: Finetune host initiated USB3 rootport link suspend and resume
+
+  * update-version-dkms doesn't add a BugLink (LP: #1867790)
+    - [Packaging] Add BugLink to update-version-dkms commit
+
+  * Add support for Realtek 8723DE wireless adapter (LP: #1780590)
+    - SAUCE: rtw88: add regulatory process strategy for different chipset
+    - SAUCE: rtw88: support dynamic user regulatory setting
+    - SAUCE: rtw88: Use secondary channel offset enumeration
+    - SAUCE: rtw88: 8822c: modify rf protection setting
+    - SAUCE: rtw88: disable TX-AMSDU on 2.4G band
+    - SAUCE: Revert "rtw88: disable TX-AMSDU on 2.4G band"
+    - SAUCE: rtw88: disable TX-AMSDU on 2.4G band
+    - SAUCE: rtw88: remove unused parameter vif in rtw_lps_pg_info_get()
+    - SAUCE: rtw88: add rtw_read8_mask and rtw_read16_mask
+    - SAUCE: rtw88: pci: 8822c should set clock delay to zero
+    - SAUCE: rtw88: move rtw_enter_ips() to the last when config
+    - SAUCE: rtw88: avoid holding mutex for cancel_delayed_work_sync()
+    - SAUCE: rtw88: add ciphers to suppress error message
+    - SAUCE: rtw88: 8822c: update power sequence to v16
+    - SAUCE: rtw88: Fix incorrect beamformee role setting
+    - SAUCE: rtw88: don't hold all IRQs disabled for PS operations
+    - SAUCE: rtw88: extract alloc rsvd_page and h2c skb routines
+    - SAUCE: rtw88: associate reserved pages with each vif
+    - SAUCE: rtw88: add adaptivity support for EU/JP regulatory
+    - SAUCE: rtw88: 8723d: Add basic chip capabilities
+    - SAUCE: rtw88: 8723d: add beamform wrapper functions
+    - SAUCE: rtw88: 8723d: Add power sequence
+    - SAUCE: rtw88: 8723d: Add RF read/write ops
+    - SAUCE: rtw88: 8723d: Add mac/bb/rf/agc/power_limit tables
+    - SAUCE: rtw88: 8723d: Add cfg_ldo25 to control LDO25
+    - SAUCE: rtw88: 8723d: Add new chip op efuse_grant() to control efuse access
+    - SAUCE: rtw88: 8723d: Add read_efuse to recognize efuse info from map
+    - SAUCE: rtw88: add legacy firmware download for 8723D devices
+    - SAUCE: rtw88: no need to send additional information to legacy firmware
+    - SAUCE: rtw88: 8723d: Add mac power-on/-off function
+    - SAUCE: rtw88: decompose while(1) loop of power sequence polling command
+    - SAUCE: rtw88: 8723d: 11N chips don't support H2C queue
+    - SAUCE: rtw88: 8723d: implement set_tx_power_index ops
+    - SAUCE: rtw88: 8723d: Organize chip TX/RX FIFO
+    - SAUCE: rtw88: 8723d: initialize mac/bb/rf basic functions
+    - SAUCE: rtw88: 8723d: Add DIG parameter
+    - SAUCE: rtw88: 8723d: Add query_rx_desc
+    - SAUCE: rtw88: 8723d: Add set_channel
+    - SAUCE: rtw88: handle C2H_CCX_TX_RPT to know if packet TX'ed successfully
+    - SAUCE: rtw88: 8723d: 11N chips don't support LDPC
+    - SAUCE: rtw88: set default port to firmware
+    - SAUCE: rtw88: update tx descriptor of mgmt and rsvd page packets
+    - SAUCE: rtw88: sar: add SAR of TX power limit
+    - SAUCE: rtw88: sar: Load static SAR table from ACPI WRDS method
+    - SAUCE: rtw88: sar: Load dynamic SAR table from ACPI methods
+    - SAUCE: rtw88: sar: apply dynamic SAR table to tx power limit
+    - SAUCE: rtw88: sar: add sar_work to poll if dynamic SAR table is changed
+    - SAUCE: rtw88: sar: dump sar information via debugfs
+    - SAUCE: rtw88: 8723d: Add chip_ops::false_alarm_statistics
+    - SAUCE: rtw88: 8723d: Set IG register for CCK rate
+    - SAUCE: rtw88: 8723d: add interface configurations table
+    - SAUCE: rtw88: 8723d: Add LC calibration
+    - SAUCE: rtw88: 8723d: add IQ calibration
+    - SAUCE: rtw88: 8723d: Add power tracking
+    - SAUCE: rtw88: 8723d: Add shutdown callback to disable BT USB suspend
+    - SAUCE: rtw88: 8723d: implement flush queue
+    - SAUCE: rtw88: 8723d: set ltecoex register address in chip_info
+    - SAUCE: rtw88: 8723d: Add coex support
+    - SAUCE: rtw88: fill zeros to words 0x06 and 0x07 of security cam entry
+    - SAUCE: rtw88: 8723d: Add 8723DE to Kconfig and Makefile
+    - [Config] CONFIG_RTW88_8723DE=y
+
+  * [Ubuntu 20.04] Unset HIBERNATION and PM kernel config options for focal
+    (LP: #1867753)
+    - [Config] CONFIG_HIBERNATION=n and CONFIG_PM=n for s390x
+
+  * [20.04 FEAT] Base KVM setup for secure guests - kernel part (LP: #1835531)
+    - s390/protvirt: introduce host side setup
+    - s390/protvirt: add ultravisor initialization
+    - s390/mm: provide memory management functions for protected KVM guests
+    - s390/mm: add (non)secure page access exceptions handlers
+    - s390/protvirt: Add sysfs firmware interface for Ultravisor information
+    - KVM: s390/interrupt: do not pin adapter interrupt pages
+    - KVM: s390: protvirt: Add UV debug trace
+    - KVM: s390: add new variants of UV CALL
+    - KVM: s390: protvirt: Add initial vm and cpu lifecycle handling
+    - KVM: s390: protvirt: Secure memory is not mergeable
+    - KVM: s390/mm: Make pages accessible before destroying the guest
+    - KVM: s390: protvirt: Handle SE notification interceptions
+    - KVM: s390: protvirt: Instruction emulation
+    - KVM: s390: protvirt: Implement interrupt injection
+    - KVM: s390: protvirt: Add SCLP interrupt handling
+    - KVM: s390: protvirt: Handle spec exception loops
+    - KVM: s390: protvirt: Add new gprs location handling
+    - KVM: S390: protvirt: Introduce instruction data area bounce buffer
+    - KVM: s390: protvirt: handle secure guest prefix pages
+    - KVM: s390/mm: handle guest unpin events
+    - KVM: s390: protvirt: Write sthyi data to instruction data area
+    - KVM: s390: protvirt: STSI handling
+    - KVM: s390: protvirt: disallow one_reg
+    - KVM: s390: protvirt: Do only reset registers that are accessible
+    - KVM: s390: protvirt: Only sync fmt4 registers
+    - KVM: s390: protvirt: Add program exception injection
+    - KVM: s390: protvirt: UV calls in support of diag308 0, 1
+    - KVM: s390: protvirt: Report CPU state to Ultravisor
+    - KVM: s390: protvirt: Support cmd 5 operation state
+    - KVM: s390: protvirt: Mask PSW interrupt bits for interception 104 and 112
+    - KVM: s390: protvirt: do not inject interrupts after start
+    - KVM: s390: protvirt: Add UV cpu reset calls
+    - DOCUMENTATION: Protected virtual machine introduction and IPL
+    - KVM: s390: protvirt: introduce and enable KVM_CAP_S390_PROTECTED
+    - KVM: s390: protvirt: Add KVM api documentation
+    - mm/gup/writeback: add callbacks for inaccessible pages
+
+  * All PS/2 ports on PS/2 Serial add-in bracket are not working after S3
+    (LP: #1866734)
+    - SAUCE: Input: i8042 - fix the selftest retry logic
+
+  * Sys oopsed with sysfs test in ubuntu_stress_smoke_test on X-hwe ARM64
+    (LP: #1866772)
+    - ACPI: sysfs: copy ACPI data using io memory copying
+
+  * Miscellaneous Ubuntu changes
+    - hio -- remove duplicated MODULE_DEVICE_TABLE declaration
+    - SAUCE: r8169: disable ASPM L1.1
+    - [Config] update annotations from configs
+    - [Config] update configs after annotation file review
+    - SAUCE: Revert "tools/power turbostat: Fix 32-bit capabilities warning"
+
+  * Miscellaneous upstream changes
+    - drm/i915: Fix eDP DPCD aux max backlight calculations
+    - drm/dp: Introduce EDID-based quirks
+    - drm/i915: Force DPCD backlight mode on X1 Extreme 2nd Gen 4K AMOLED panel
+    - drm/i915: Force DPCD backlight mode for some Dell CML 2020 panels
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 25 Mar 2020 18:09:13 +0100
+
+linux-5.6 (5.6.0-5.5) focal; urgency=medium
+
+  * please help enable CONFIG_EROFS_FS_ZIP (LP: #1867099)
+    - [Config] CONFIG_EROFS_FS_ZIP=y
+    - [Config] CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT=1
+
+  * Miscellaneous Ubuntu changes
+    - Config: Fix SND_HDA_PREALLOC_SIZE annotations
+    - Config: Fix DATA_SHIFT annotations
+    - Config: remove ANDROID_VSOC from annotations
+    - Config: remove arm arch from annotations
+    - Config: Update SOC_R8A7796X annotations
+    - Config: Update CLK_R8A7796X annotations
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.6-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 18 Mar 2020 17:25:30 +0100
+
+linux-5.6 (5.6.0-4.4) focal; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+    - [Packaging] update helper scripts
+
+  * Add sysfs attribute to show remapped NVMe (LP: #1863621)
+    - SAUCE: ata: ahci: Add sysfs attribute to show remapped NVMe device count
+
+  * [20.04 FEAT] Compression improvements in Linux kernel (LP: #1830208)
+    - [Config] Introducing s390x specific kernel config option CONFIG_ZLIB_DFLTCC
+
+  * [UBUNTU 20.04] s390x/pci: increase CONFIG_PCI_NR_FUNCTIONS to 512 in kernel
+    config (LP: #1866056)
+    - [Config] Increase CONFIG_PCI_NR_FUNCTIONS from 64 to 512 starting with focal
+      on s390x
+
+  * CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set (LP: #1865332)
+    - [Config] CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+
+  * [UBUNTU 20.04] Enable CONFIG_NET_SWITCHDEV in kernel config for s390x
+    starting with focal (LP: #1865452)
+    - [Config] Enable CONFIG_NET_SWITCHDEV in kernel config for s390x starting
+      with focal
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "UBUNTU: SAUCE: blk/core: Gracefully handle unset
+      make_request_fn"
+    - [Packaging] prevent duplicated entries in modules.ignore
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.6-rc5
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 Mar 2020 09:42:06 +0100
+
+linux-5.6 (5.6.0-3.3) focal; urgency=medium
+
+  * nsleep-lat / set-timer-lat / inconsistency-check / raw_skew from timer in
+    ubuntu_kernel_selftests timeout on 5.3 / 5.4 (LP: #1864626)
+    - selftests/timers: Turn off timeout setting
+
+  * Update kernel options CONFIG_NR_CPUS and CONFIG_NUMA_EMU for focal
+    (LP: #1864198)
+    - Ubuntu: [Config] Update kernel options CONFIG_NR_CPUS and CONFIG_NUMA_EMU
+
+  * alsa/hda/realtek: fix a mute led regression on Lenovo X1 Carbon
+    (LP: #1864576)
+    - SAUCE: ALSA: hda/realtek - Fix a regression for mute led on Lenovo Carbon X1
+
+  * r8152 init may take up to 40 seconds at initialization with Dell WD19/WD19DC
+    during hotplug (LP: #1864284)
+    - UBUNTU SAUCE: r8151: check disconnect status after long sleep
+
+  * Another Dell AIO backlight issue (LP: #1863880)
+    - SAUCE: platform/x86: dell-uart-backlight: move retry block
+
+  * Backport GetFB2 ioctl (LP: #1863874)
+    - SAUCE: drm: Add getfb2 ioctl
+
+  * Focal Fossa (20.04) feature request - Enable CONFIG_X86_UV (LP: #1863810)
+    - [Config] CONFIG_X86_UV=y
+
+  * Miscellaneous Ubuntu changes
+    - debian: remove snapdragon config, rules and flavour
+    - remove snapdragon abi files
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.6-rc4
+
+  * Miscellaneous upstream changes
+    - updateconfigs following snapdragon removal
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 04 Mar 2020 08:21:10 +0100
+
+linux-5.6 (5.6.0-2.2) focal; urgency=medium
+
+  * Sometimes can't adjust brightness on Dell AIO (LP: #1862885)
+    - SAUCE: platform/x86: dell-uart-backlight: increase retry times
+
+  * Dell XPS 13 (7390) Display Flickering - 19.10  (LP: #1849947)
+    - SAUCE: drm/i915: Disable PSR by default on all platforms
+
+  * Miscellaneous Ubuntu changes
+    - [debian] ignore missing wireguard module
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) s390: Lock down the kernel when the IPL secure flag is set
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - [Config] CONFIG_LOCK_DOWN_IN_SECURE_BOOT=y
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.6-rc3
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (lockdown) s390/ipl: lockdown kernel when booted
+      secure"
+    - Revert "UBUNTU: SAUCE: (lockdown) KEYS: Make use of platform keyring for
+      module signature verify"
+    - Revert "UBUNTU: SAUCE: (lockdown) Add a SysRq option to lift kernel
+      lockdown"
+    - Revert "UBUNTU: SAUCE: (lockdown) security: lockdown: expose a hook to lock
+      the kernel down"
+    - Revert "UBUNTU: SAUCE: (lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err()."
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 24 Feb 2020 18:57:22 +0100
+
+linux-5.6 (5.6.0-1.1) focal; urgency=medium
+
+  *  Integrate Intel SGX driver into linux-azure (LP: #1844245)
+    - [Packaging] Add systemd service to load intel_sgx
+
+  * QAT drivers for C3XXX and C62X not included as modules (LP: #1845959)
+    - [Config] CRYPTO_DEV_QAT_C3XXX=m, CRYPTO_DEV_QAT_C62X=m and
+      CRYPTO_DEV_QAT_DH895xCC=m
+
+  * 5.4.0-11 crash on cryptsetup open (LP: #1860231)
+    - SAUCE: blk/core: Gracefully handle unset make_request_fn
+
+  * multi-zone raid0 corruption (LP: #1850540)
+    - SAUCE: md/raid0: Use kernel specific layout
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - update dropped.txt after rebase to v5.6-rc1
+    - [Config] updateconfigs after rebase to 5.6-rc1
+    - hio -- proc_create() requires a "struct proc_ops" in 5.6
+    - SAUCE: arm: fix build error in kvm tracepoint
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: [Config] Disable the uselib system call"
+    - Revert "UBUNTU: [Config] Disable legacy PTY naming"
+    - Revert "UBUNTU: [Config] Enforce filtered access to iomem"
+    - Revert "UBUNTU: [Config] Enable notifier call chain validations"
+    - Revert "UBUNTU: [Config] Enable scatterlist validation"
+    - Revert "UBUNTU: [Config] Enable cred sanity checks"
+    - Revert "UBUNTU: [Config] Enable linked list manipulation checks"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.6-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 13 Feb 2020 17:20:27 +0100
+
+linux-5.6 (5.6.0-0.0) focal; urgency=medium
+
+  * Dummy entry
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 10 Feb 2020 11:06:18 +0100
+
+linux-5.5 (5.5.0-7.8) focal; urgency=medium
+
+  * CONFIG_USELIB should be disabled (LP: #1855341)
+    - [Config] Disable the uselib system call
+
+  * CONFIG_LEGACY_PTYS should be disabled (LP: #1855339)
+    - [Config] Disable legacy PTY naming
+
+  * CONFIG_IO_STRICT_DEVMEM should be enabled (LP: #1855338)
+    - [Config] Enforce filtered access to iomem
+
+  * CONFIG_DEBUG_NOTIFIERS should be enabled (LP: #1855337)
+    - [Config] Enable notifier call chain validations
+
+  * CONFIG_DEBUG_SG should be enabled (LP: #1855336)
+    - [Config] Enable scatterlist validation
+
+  * CONFIG_DEBUG_CREDENTIALS should be enabled (LP: #1855335)
+    - [Config] Enable cred sanity checks
+
+  * CONFIG_DEBUG_LIST should be enabled (LP: #1855334)
+    - [Config] Enable linked list manipulation checks
+
+  * shiftfs: prevent lower dentries from going negative during unlink
+    (LP: #1860041)
+    - SAUCE: shiftfs: prevent lower dentries from going negative during unlink
+
+  * [SRU][B/OEM-B/OEM-OSP1/D/E/Unstable] UBUNTU: SAUCE: Use native backlight on
+    Lenovo E41-25/45 (LP: #1859561)
+    - SAUCE: ACPI: video: Use native backlight on Lenovo E41-25/45
+
+  * USB key cannot be detected by hotplug on Sunix USB Type-A 3.1 Gen 2 card
+    [1b21:2142]  (LP: #1858988)
+    - SAUCE: PCI: Avoid ASMedia XHCI USB PME# from D0 defect
+
+  * Dell AIO can't adjust brightness (LP: #1858761)
+    - SAUCE: platform/x86: dell-uart-backlight: add retry for get scalar status
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Fix typo in annotations file
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 27 Jan 2020 11:39:38 +0100
+
+linux-5.5 (5.5.0-6.7) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Update ubuntu-regression-suite dependency to python2
+    - [Packaging] Fix ubuntu-regression-suite python dependency for hwe kernel
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.5-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 20 Jan 2020 10:16:01 +0100
+
+linux-5.5 (5.5.0-5.6) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.5-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 13 Jan 2020 15:50:12 +0100
+
+linux-5.5 (5.5.0-4.5) focal; urgency=medium
+
+  * linux build and autopkg tests need to use python2 instead of python
+    (LP: #1858487)
+    - [Packaging] Remove python-dev build dependency
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Jan 2020 16:00:26 +0100
+
+linux-5.5 (5.5.0-3.4) focal; urgency=medium
+
+  * [SRU][B/OEM-B/OEM-OSP1/D/E/F] Add LG I2C touchscreen multitouch support
+    (LP: #1857541)
+    - SAUCE: HID: multitouch: Add LG MELF0410 I2C touchscreen support
+
+  * Make vfio-pci built-in or xhci_hcd optional (LP: #1770845)
+    - [Config]: built-in VFIO_PCI for amd64
+
+  * multi-zone raid0 corruption (LP: #1850540)
+    - SAUCE: md/raid0: Link to wiki with guidance on multi-zone RAID0 layout
+      migration
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update variants
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Change source package to linux-5.5
+    - [Packaging] Don't use SRCPKGNAME for linux-libc-dev
+    - [Packaging] Remove linux-source-3 Provides: from linux-source
+    - [Packaging] Fix linux-doc in linux-image Suggests:
+    - [Debian] Read variants list into a variable
+    - [Packaging] Generate linux-libc-dev package only for primary variant
+    - [Packaging] Generate linux-doc for only the primary variant
+    - [Debian] Update linux source package name in debian/tests/*
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.5-rc3
+    - [Config] disable PCI_MESON
+    - [Config] Add pinctrl-equilibrium to modules.ignore
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.5-rc5
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Wed, 08 Jan 2020 11:28:43 +0100
+
+linux-5.5 (5.5.0-2.3) focal; urgency=medium
+
+  * Empty entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 17 Dec 2019 22:33:59 -0600
+
+linux (5.5.0-2.3) focal; urgency=medium
+
+  * Support DPCD aux brightness control (LP: #1856134)
+    - SAUCE: drm/i915: Fix eDP DPCD aux max backlight calculations
+    - SAUCE: drm/i915: Assume 100% brightness when not in DPCD control mode
+    - SAUCE: drm/i915: Fix DPCD register order in intel_dp_aux_enable_backlight()
+    - SAUCE: drm/i915: Auto detect DPCD backlight support by default
+    - SAUCE: drm/i915: Force DPCD backlight mode on X1 Extreme 2nd Gen 4K AMOLED
+      panel
+    - USUNTU: SAUCE: drm/i915: Force DPCD backlight mode on Dell Precision 4K sku
+
+  * change kconfig of the soundwire bus driver from y to m (LP: #1855685)
+    - [Config]: SOUNDWIRE=m
+
+  * Fix unusable USB hub on Dell TB16 after S3 (LP: #1855312)
+    - SAUCE: USB: core: Make port power cycle a seperate helper function
+    - SAUCE: USB: core: Attempt power cycle port when it's in eSS.Disabled state
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] add python depends to ubuntu-regression-suite
+    - SAUCE: selftests: net: tls: remove recv_rcvbuf test
+    - update dkms package versions
+
+  * Miscellaneous upstream changes
+    - [Config] updateconfigs after rebase to 5.5-rc2
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Tue, 17 Dec 2019 16:02:43 +0100
+
+linux (5.5.0-1.2) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] disable nvidia dkms build
+    - [Config] disable virtualbox dkms build
+    - [Config] disable zfs dkms build
+    - update dropped.txt after rebase to v5.5-rc1
+    - SAUCE: (lockdown) Make get_cert_list() not complain about cert lists that
+      aren't present.
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - SAUCE: (lockdown) s390/ipl: lockdown kernel when booted secure
+    - [Config] Enable lockdown under secure boot
+    - update dkms package versions
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Thu, 12 Dec 2019 16:54:41 +0100
+
+linux (5.5.0-0.1) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after rebase to 5.5-rc1
+
+   [ Upstream Kernel Changes ]
+
+   * Rebase to v5.5-rc1
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 Dec 2019 19:03:35 +0100
+
+linux (5.5.0-0.0) focal; urgency=medium
+
+  * Dummy entry.
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 09 Dec 2019 15:14:37 +0100
+
+linux (5.4.0-8.11) focal; urgency=medium
+
+  * focal/linux: 5.4.0-8.9 -proposed tracker (LP: #1855448)
+
+  * update ENA driver for DIMLIB dynamic interrupt moderation (LP: #1853180)
+    - SAUCE: net: ena: fix issues in setting interrupt moderation params in
+      ethtool
+    - SAUCE: net: ena: fix too long default tx interrupt moderation interval
+
+  * Kernel build log filled with "/bin/bash: line 5: warning: command
+    substitution: ignored null byte in input" (LP: #1853843)
+    - [Debian] Fix warnings when checking for modules signatures
+
+  * hwe-edge kernel 5.3.0-23.25 kernel does not boot on Precision 5720 AIO
+    (LP: #1852581)
+    - [Packaging] Fix module signing with older modinfo
+
+  * Fix MST support on Ice Lake (LP: #1854432)
+    - drm/i915: fix port checks for MST support on gen >= 11
+
+  * headphone has noise as not mute on dell machines with alc236/256
+    (LP: #1854401)
+    - SAUCE: ALSA: hda/realtek - Dell headphone has noise on unmute for ALC236
+
+  * [CML-S62] Need enable intel_pmc_core driver patch for Comet lake- S 6+2
+    (LP: #1847450)
+    - SAUCE: platform/x86: intel_pmc_core: Add Comet Lake (CML) platform support
+      to intel_pmc_core driver
+
+  * CVE-2019-14901
+    - SAUCE: mwifiex: Fix heap overflow in mmwifiex_process_tdls_action_frame()
+
+  * CVE-2019-14896 // CVE-2019-14897
+    - SAUCE: libertas: Fix two buffer overflows at parsing bss descriptor
+
+  * CVE-2019-14895
+    - SAUCE: mwifiex: fix possible heap overflow in mwifiex_process_country_ie()
+
+  * [CML-S62] Need enable intel_rapl patch support for Comet lake- S 6+2
+    (LP: #1847454)
+    - powercap/intel_rapl: add support for CometLake Mobile
+    - powercap/intel_rapl: add support for Cometlake desktop
+
+  * External microphone can't work on some dell machines with the codec alc256
+    or alc236 (LP: #1853791)
+    - SAUCE: ALSA: hda/realtek - Move some alc256 pintbls to fallback table
+    - SAUCE: ALSA: hda/realtek - Move some alc236 pintbls to fallback table
+
+  * remount of multilower moved pivoted-root overlayfs root, results in I/O
+    errors on some modified files (LP: #1824407)
+    - SAUCE: ovl: fix lookup failure on multi lower squashfs
+
+  * [CML-S62] Need enable turbostat patch support for Comet lake- S 6+2
+    (LP: #1847451)
+    - SAUCE: tools/power turbostat: Add Cometlake support
+
+  * CONFIG_ARCH_ROCKCHIP is not set in ubuntu 18.04 aarch64,arm64 (LP: #1825222)
+    - [Config] Enable ROCKCHIP support for arm64
+
+  * [broadwell-rt286, playback] Since Linux 5.2rc2 audio playback no longer
+    works on Dell Venue 11 Pro 7140 (LP: #1846539)
+    - SAUCE: ASoC: SOF: Intel: Broadwell: clarify mutual exclusion with legacy
+      driver
+
+  * i40e: general protection fault in i40e_config_vf_promiscuous_mode
+    (LP: #1852663)
+    - SAUCE: i40e Fix GPF when deleting VMs
+
+  * libbpf check_abi fails on ppc64el (LP: #1854974)
+    - libbpf: Fix readelf output parsing on powerpc with recent binutils
+
+  * CVE-2019-19050
+    - crypto: user - fix memory leak in crypto_reportstat
+
+  * Make hotplugging docking station to Thunderbolt port more reliable
+    (LP: #1853991)
+    - PCI/PM: Add pcie_wait_for_link_delay()
+    - PCI/PM: Add missing link delays required by the PCIe spec
+
+  * i915: Display flickers (monitor loses signal briefly) during "flickerfree"
+    boot, while showing the BIOS logo on a black background (LP: #1836858)
+    - [Config] FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER=y
+
+  * [CML] New device id's for CMP-H (LP: #1846335)
+    - i2c: i801: Add support for Intel Comet Lake PCH-H
+    - mtd: spi-nor: intel-spi: Add support for Intel Comet Lake-H SPI serial flash
+    - mfd: intel-lpss: Add Intel Comet Lake PCH-H PCI IDs
+
+  * Focal update: v5.4.2 upstream stable release (LP: #1855326)
+    - io_uring: async workers should inherit the user creds
+    - net: separate out the msghdr copy from ___sys_{send,recv}msg()
+    - net: disallow ancillary data for __sys_{send,recv}msg_file()
+    - crypto: inside-secure - Fix stability issue with Macchiatobin
+    - driver core: platform: use the correct callback type for bus_find_device
+    - usb: dwc2: use a longer core rest timeout in dwc2_core_reset()
+    - staging: wilc1000: fix illegal memory access in wilc_parse_join_bss_param()
+    - staging: rtl8192e: fix potential use after free
+    - staging: rtl8723bs: Drop ACPI device ids
+    - staging: rtl8723bs: Add 024c:0525 to the list of SDIO device-ids
+    - USB: serial: ftdi_sio: add device IDs for U-Blox C099-F9P
+    - mei: bus: prefix device names on bus with the bus name
+    - mei: me: add comet point V device id
+    - thunderbolt: Power cycle the router if NVM authentication fails
+    - x86/fpu: Don't cache access to fpu_fpregs_owner_ctx
+    - gve: Fix the queue page list allocated pages count
+    - macvlan: schedule bc_work even if error
+    - mdio_bus: don't use managed reset-controller
+    - net: dsa: sja1105: fix sja1105_parse_rgmii_delays()
+    - net: macb: add missed tasklet_kill
+    - net: psample: fix skb_over_panic
+    - net: sched: fix `tc -s class show` no bstats on class with nolock subqueues
+    - openvswitch: fix flow command message size
+    - sctp: Fix memory leak in sctp_sf_do_5_2_4_dupcook
+    - slip: Fix use-after-free Read in slip_open
+    - sctp: cache netns in sctp_ep_common
+    - openvswitch: drop unneeded BUG_ON() in ovs_flow_cmd_build_info()
+    - openvswitch: remove another BUG_ON()
+    - net/tls: take into account that bpf_exec_tx_verdict() may free the record
+    - net/tls: free the record on encryption error
+    - net: skmsg: fix TLS 1.3 crash with full sk_msg
+    - selftests/tls: add a test for fragmented messages
+    - net/tls: remove the dead inplace_crypto code
+    - net/tls: use sg_next() to walk sg entries
+    - selftests: bpf: test_sockmap: handle file creation failures gracefully
+    - selftests: bpf: correct perror strings
+    - tipc: fix link name length check
+    - selftests: pmtu: use -oneline for ip route list cache
+    - r8169: fix jumbo configuration for RTL8168evl
+    - r8169: fix resume on cable plug-in
+    - ext4: add more paranoia checking in ext4_expand_extra_isize handling
+    - Revert "jffs2: Fix possible null-pointer dereferences in
+      jffs2_add_frag_to_fragtree()"
+    - crypto: talitos - Fix build error by selecting LIB_DES
+    - HID: core: check whether Usage Page item is after Usage ID items
+    - platform/x86: hp-wmi: Fix ACPI errors caused by too small buffer
+    - platform/x86: hp-wmi: Fix ACPI errors caused by passing 0 as input size
+    - Linux 5.4.2
+
+  * no HDMI video output since GDM greeter after linux-oem-osp1 version
+    5.0.0-1026 (LP: #1852386)
+    - drm/i915: Add new CNL PCH ID seen on a CML platform
+    - SAUCE: drm/i915: Fix detection for a CMP-V PCH
+
+  * Please add patch fixing RK818 ID detection (LP: #1853192)
+    - SAUCE: mfd: rk808: Fix RK818 ID template
+
+  * Raydium Touchscreen on ThinkPad L390 does not work (LP: #1849721)
+    - HID: i2c-hid: fix no irq after reset on raydium 3118
+
+  * Touchpad doesn't work on Dell Inspiron 7000 2-in-1 (LP: #1851901)
+    - Revert "UBUNTU: SAUCE: mfd: intel-lpss: add quirk for Dell XPS 13 7390
+      2-in-1"
+    - lib: devres: add a helper function for ioremap_uc
+    - mfd: intel-lpss: Use devm_ioremap_uc for MMIO
+
+  * Lenovo dock MAC Address pass through doesn't work in Ubuntu  (LP: #1827961)
+    - r8152: Add macpassthru support for ThinkPad Thunderbolt 3 Dock Gen 2
+
+  * Disable unreliable HPET on CFL-H system (LP: #1852216)
+    - SAUCE: x86/intel: Disable HPET on Intel Coffe Lake H platforms
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] Enable virtualbox dkms build
+    - [Config] update annotations to match current configs
+    - SAUCE: Add exfat module to signature inclusion list
+
+  * Miscellaneous upstream changes
+    - Bluetooth: Fix invalid-free in bcsp_close()
+    - ath9k_hw: fix uninitialized variable data
+    - ath10k: Fix a NULL-ptr-deref bug in ath10k_usb_alloc_urb_from_pipe
+    - ath10k: Fix HOST capability QMI incompatibility
+    - ath10k: restore QCA9880-AR1A (v1) detection
+    - Revert "Bluetooth: hci_ll: set operational frequency earlier"
+    - Revert "dm crypt: use WQ_HIGHPRI for the IO and crypt workqueues"
+    - md/raid10: prevent access of uninitialized resync_pages offset
+    - x86/insn: Fix awk regexp warnings
+    - x86/speculation: Fix incorrect MDS/TAA mitigation status
+    - x86/speculation: Fix redundant MDS mitigation message
+    - nbd: prevent memory leak
+    - x86/stackframe/32: Repair 32-bit Xen PV
+    - x86/xen/32: Make xen_iret_crit_fixup() independent of frame layout
+    - x86/xen/32: Simplify ring check in xen_iret_crit_fixup()
+    - x86/doublefault/32: Fix stack canaries in the double fault handler
+    - x86/pti/32: Size initial_page_table correctly
+    - x86/cpu_entry_area: Add guard page for entry stack on 32bit
+    - x86/entry/32: Fix IRET exception
+    - x86/entry/32: Use %ss segment where required
+    - x86/entry/32: Move FIXUP_FRAME after pushing %fs in SAVE_ALL
+    - x86/entry/32: Unwind the ESPFIX stack earlier on exception entry
+    - x86/entry/32: Fix NMI vs ESPFIX
+    - selftests/x86/mov_ss_trap: Fix the SYSENTER test
+    - selftests/x86/sigreturn/32: Invalidate DS and ES when abusing the kernel
+    - x86/pti/32: Calculate the various PTI cpu_entry_area sizes correctly, make
+      the CPU_ENTRY_AREA_PAGES assert precise
+    - x86/entry/32: Fix FIXUP_ESPFIX_STACK with user CR3
+    - futex: Prevent robust futex exit race
+    - ALSA: usb-audio: Fix NULL dereference at parsing BADD
+    - ALSA: usb-audio: Fix Scarlett 6i6 Gen 2 port data
+    - media: vivid: Set vid_cap_streaming and vid_out_streaming to true
+    - media: vivid: Fix wrong locking that causes race conditions on streaming
+      stop
+    - media: usbvision: Fix invalid accesses after device disconnect
+    - media: usbvision: Fix races among open, close, and disconnect
+    - cpufreq: Add NULL checks to show() and store() methods of cpufreq
+    - futex: Move futex exit handling into futex code
+    - futex: Replace PF_EXITPIDONE with a state
+    - exit/exec: Seperate mm_release()
+    - futex: Split futex_mm_release() for exit/exec
+    - futex: Set task::futex_state to DEAD right after handling futex exit
+    - futex: Mark the begin of futex exit explicitly
+    - futex: Sanitize exit state handling
+    - futex: Provide state handling for exec() as well
+    - futex: Add mutex around futex exit
+    - futex: Provide distinct return value when owner is exiting
+    - futex: Prevent exit livelock
+    - media: uvcvideo: Fix error path in control parsing failure
+    - media: b2c2-flexcop-usb: add sanity checking
+    - media: cxusb: detect cxusb_ctrl_msg error in query
+    - media: imon: invalid dereference in imon_touch_event
+    - media: mceusb: fix out of bounds read in MCE receiver buffer
+    - ALSA: hda - Disable audio component for legacy Nvidia HDMI codecs
+    - USBIP: add config dependency for SGL_ALLOC
+    - usbip: tools: fix fd leakage in the function of read_attr_usbip_status
+    - usbip: Fix uninitialized symbol 'nents' in stub_recv_cmd_submit()
+    - usb-serial: cp201x: support Mark-10 digital force gauge
+    - USB: chaoskey: fix error case of a timeout
+    - appledisplay: fix error handling in the scheduled work
+    - USB: serial: mos7840: add USB ID to support Moxa UPort 2210
+    - USB: serial: mos7720: fix remote wakeup
+    - USB: serial: mos7840: fix remote wakeup
+    - USB: serial: option: add support for DW5821e with eSIM support
+    - USB: serial: option: add support for Foxconn T77W968 LTE modules
+    - staging: comedi: usbduxfast: usbduxfast_ai_cmdtest rounding error
+    - powerpc/book3s64: Fix link stack flush on context switch
+    - KVM: PPC: Book3S HV: Flush link stack on guest exit to host kernel
+    - Linux 5.4.1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 06 Dec 2019 15:53:53 -0600
+
+linux (5.4.0-7.8) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/bpf: Comment out BPF_CORE_READ's which cause clang to
+      segfault
+    - Update nvidia-430 to nvidia-440
+    - [Config] Enable nvidia dkms build
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 25 Nov 2019 15:02:30 +0100
+
+linux (5.4.0-6.7) focal; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.4-rc8
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc7
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 18 Nov 2019 12:08:01 +0100
+
+linux (5.4.0-5.6) focal; urgency=medium
+
+  * refcount underflow and type confusion in shiftfs (LP: #1850867) //
+    CVE-2019-15793
+    - SAUCE: shiftfs: Correct id translation for lower fs operations
+
+  * refcount underflow and type confusion in shiftfs (LP: #1850867) //
+    CVE-2019-15792
+    - SAUCE: shiftfs: prevent type confusion
+
+  * refcount underflow and type confusion in shiftfs (LP: #1850867) //
+    CVE-2019-15791
+    - SAUCE: shiftfs: Fix refcount underflow in btrfs ioctl handling
+
+  * Some EFI systems fail to boot in efi_init() when booted via maas
+    (LP: #1851810)
+    - SAUCE: efi: efi_get_memory_map -- increase map headroom
+
+  * seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test (LP: #1849281)
+    - SAUCE: seccomp: rework define for SECCOMP_USER_NOTIF_FLAG_CONTINUE
+    - SAUCE: seccomp: avoid overflow in implicit constant conversion
+
+  * dkms artifacts may expire from the pool (LP: #1850958)
+    - [Packaging] dkms -- try launchpad librarian for pool downloads
+    - [Packaging] dkms -- dkms-build quieten wget verbiage
+
+  * tsc marked unstable after entered PC10 on Intel CoffeeLake (LP: #1840239)
+    - SAUCE: x86/intel: Disable HPET on Intel Coffe Lake platforms
+    - SAUCE: x86/intel: Disable HPET on Intel Ice Lake platforms
+
+  * shiftfs: prevent exceeding project quotas (LP: #1849483)
+    - SAUCE: shiftfs: drop CAP_SYS_RESOURCE from effective capabilities
+
+  * shiftfs: fix fallocate() (LP: #1849482)
+    - SAUCE: shiftfs: setup correct s_maxbytes limit
+
+  * The alsa hda driver is not loaded due to the missing of PCIID for Comet
+    Lake-S [8086:a3f0] (LP: #1852070)
+    - SAUCE: ALSA: hda: Add Cometlake-S PCI ID
+
+  * Can't adjust brightness on DELL UHD dGPU AIO (LP: #1813877)
+    - SAUCE: platform/x86: dell-uart-backlight: add missing status command
+    - SAUCE: platform/x86: dell-uart-backlight: load driver by scalar status
+    - SAUCE: platform/x86: dell-uart-backlight: add force parameter
+    - SAUCE: platform/x86: dell-uart-backlight: add quirk for old platforms
+
+  * s_iflags overlap prevents unprivileged overlayfs mounts (LP: #1851677)
+    - SAUCE: fs: Move SB_I_NOSUID to the top of s_iflags
+
+  * ubuntu-aufs-modified mmap_region() breaks refcounting in overlayfs/shiftfs
+    error path (LP: #1850994) // CVE-2019-15794
+    - SAUCE: shiftfs: Restore vm_file value when lower fs mmap fails
+    - SAUCE: ovl: Restore vm_file value when lower fs mmap fails
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Convert update-aufs.sh to use aufs5
+    - SAUCE: import aufs driver
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 13 Nov 2019 11:56:35 -0800
+
+linux (5.4.0-4.5) focal; urgency=medium
+
+  * High power consumption using 5.0.0-25-generic (LP: #1840835)
+    - PCI: Add a helper to check Power Resource Requirements _PR3 existence
+    - ALSA: hda: Allow HDA to be runtime suspended when dGPU is not bound to a
+      driver
+    - PCI: Fix missing inline for pci_pr3_present()
+
+  * Fix signing of staging modules in eoan (LP: #1850234)
+    - [Packaging] Leave unsigned modules unsigned after adding .gnu_debuglink
+
+  * [20.04 FEAT] Set Architecture Level (ALS) to z13 (LP: #1837525)
+    - [Config] s390x bump march to z13, with tune to z15
+
+  * Miscellaneous Ubuntu changes
+    - [Debian]: do not skip tests for linux-hwe-edge
+    - update dkms package versions
+    - [Config] re-enable zfs
+    - [Config] rename module virtio_fs to virtiofs
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc6
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 04 Nov 2019 15:12:02 +0100
+
+linux (5.4.0-3.4) focal; urgency=medium
+
+  * seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test (LP: #1849281)
+    - SAUCE: seccomp: fix SECCOMP_USER_NOTIF_FLAG_CONTINUE test
+
+  * cloudimg: no iavf/i40evf module so no network available with SR-IOV enabled
+    cloud (LP: #1848481)
+    - [Packaging] include iavf/i40evf in generic
+
+  * CVE-2019-17666
+    - SAUCE: rtlwifi: Fix potential overflow on P2P code
+
+  * Change Config Option CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE for s390x from yes
+    to no (LP: #1848492)
+    - [Config] Change Config Option CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE for s390x
+      from yes to no
+
+  * Add Intel Comet Lake ethernet support (LP: #1848555)
+    - SAUCE: e1000e: Add support for Comet Lake
+
+  * seccomp: add SECCOMP_USER_NOTIF_FLAG_CONTINUE    (LP: #1847744)
+    - SAUCE: seccomp: add SECCOMP_USER_NOTIF_FLAG_CONTINUE
+    - SAUCE: seccomp: test SECCOMP_USER_NOTIF_FLAG_CONTINUE
+
+  * drm/i915: Fix the issue of "azx_get_response timeout" for hdmi audio on ICL
+    platforms (LP: #1847192)
+    - SAUCE: drm/i915: Fix audio power up sequence for gen10+ display
+    - SAUCE: drm/i915: extend audio CDCLK>=2*BCLK constraint to more platforms
+
+  * PM / hibernate: fix potential memory corruption (LP: #1847118)
+    - SAUCE: PM / hibernate: memory_bm_find_bit -- tighten node optimisation
+
+  * [regression] NoNewPrivileges incompatible with Apparmor (LP: #1844186)
+    - SAUCE: apparmor: fix nnp subset test for unconfined
+
+  * overlayfs: allow with shiftfs as underlay (LP: #1846272)
+    - SAUCE: overlayfs: allow with shiftfs as underlay
+
+  * eoan: alsa/sof: Enable SOF_HDA link and codec (LP: #1848490)
+    - [Config] Fix SOF Kconfig options
+
+  * linux won't build when new virtualbox version is present on the archive
+    (LP: #1848788)
+    - [Packaging]: download virtualbox from sources
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations from configs
+    - [Config] updateconfigs after rebase to 5.4-rc5
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 29 Oct 2019 12:01:27 -0500
+
+linux (5.4.0-2.3) eoan; urgency=medium
+
+  * Add installer support for iwlmvm adapters (LP: #1848236)
+    - d-i: Add iwlmvm to nic-modules
+
+  * shiftfs: rework how shiftfs opens files (LP: #1846265)
+    - SAUCE: shiftfs: rework how shiftfs opens files
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.4-rc4
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc4
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 21 Oct 2019 17:31:26 +0200
+
+linux (5.4.0-1.2) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] updateconfigs after rebase to 5.4-rc3
+    - [Config] add flexfb, fbtft_device and rio500 to modules.ignore
+    - [Config] amd64: ignore fbtft and all dependent modules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc3
+
+ -- Andrea Righi <andrea.righi@canonical.com>  Mon, 14 Oct 2019 19:48:52 +0200
+
+linux (5.4.0-0.1) eoan; urgency=medium
+
+  * Enable the Dragonboards out of Eoan/master arm64 kernel (LP: #1846704)
+    - [Packaging] arm64: snapdragon: introduce a snapdragon flavour
+    - [Packaging] arm64: snapdragon: switch kernel format to Image
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8916=y
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8994=y
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8996=y
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_MSM8998=y
+    - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_RPMH=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_BAM_DMA=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_HIDMA_MGMT=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_HIDMA=y
+    - [Config] arm64: snapdragon: CONFIG_COMMON_CLK_QCOM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_RPMH=y
+    - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8916=y
+    - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8994=y
+    - [Config] arm64: snapdragon: CONFIG_MSM_MMCC_8996=y
+    - [Config] arm64: snapdragon: CONFIG_MSM_GCC_8998=y
+    - [Config] arm64: snapdragon: CONFIG_HWSPINLOCK_QCOM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_APCS_IPC=y
+    - [Config] arm64: snapdragon: CONFIG_RPMSG_QCOM_GLINK_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_GENI_SE=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_SMEM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_SMD_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_SMP2P=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_SMSM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_QFPROM=y
+    - [Config] arm64: snapdragon: CONFIG_SERIAL_QCOM_GENI=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_TSENS=y
+    - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_SMD_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_SMD_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_RPMSG_QCOM_SMD=y
+    - [Config] arm64: snapdragon: CONFIG_MFD_QCOM_RPM=y
+    - [Config] arm64: snapdragon: CONFIG_SCSI_UFSHCD=y
+    - [Config] arm64: snapdragon: CONFIG_SCSI_UFSHCD_PLATFORM=y
+    - [Config] arm64: snapdragon: CONFIG_SCSI_UFS_HISI=y
+    - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI=y
+    - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI_PLTFM=y
+    - [Config] arm64: snapdragon: CONFIG_MMC_SDHCI_MSM=y
+    - [Config] arm64: snapdragon: CONFIG_REGULATOR_QCOM_SPMI=y
+    - [Config] arm64: snapdragon: CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
+    - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_USB_HS=y
+    - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_QMP=y
+    - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_UFS=y
+    - [Config] arm64: snapdragon: CONFIG_PHY_QCOM_USB_HSIC=y
+    - [Config] arm64: snapdragon: CONFIG_USB_CHIPIDEA_OF=y
+    - [Config] arm64: snapdragon: CONFIG_USB_EHCI_HCD_PLATFORM=y
+    - [Config] arm64: snapdragon: CONFIG_EXTCON_USB_GPIO=y
+    - [Config] arm64: snapdragon: CONFIG_REGULATOR_FIXED_VOLTAGE=y
+    - [Config] arm64: snapdragon: CONFIG_LEDS_GPIO=y
+    - [Config] arm64: snapdragon: CONFIG_USB_HSIC_USB3503=y
+    - [Config] arm64: snapdragon: CONFIG_USB_NET_DRIVERS=y
+    - [Config] arm64: snapdragon: CONFIG_USB_OTG=y
+    - [Config] arm64: snapdragon: CONFIG_USB_XHCI_PLATFORM=y
+    - [Config] arm64: snapdragon: CONFIG_USB_OHCI_HCD_PLATFORM=y
+    - [Config] arm64: snapdragon: CONFIG_USB_MUSB_HDRC=y
+    - [Config] arm64: snapdragon: CONFIG_USB_DWC3=y
+    - [Config] arm64: snapdragon: CONFIG_USB_DWC3_PCI=y
+    - [Config] arm64: snapdragon: CONFIG_USB_DWC3_OF_SIMPLE=y
+    - [Config] arm64: snapdragon: CONFIG_USB_DWC3_QCOM=y
+    - [Config] arm64: snapdragon: CONFIG_LEDS_PWM=y
+    - [Config] arm64: snapdragon: CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+    - [Config] arm64: snapdragon: CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_A53PLL=y
+    - [Config] arm64: snapdragon: CONFIG_QCOM_CLK_APCS_MSM8916=y
+    - [Config] arm64: snapdragon: CONFIG_NLS_ISO8859_1=y
+    - [Config] arm64: snapdragon: CONFIG_USB_USBNET=y
+    - [Config] arm64: snapdragon: CONFIG_CRYPTO_DEV_QCOM_RNG=y
+    - [Config] arm64: snapdragon: CONFIG_POWER_RESET_QCOM_PON=y
+    - [Config] arm64: snapdragon: CONFIG_INPUT_PM8941_PWRKEY=y
+    - [Config] arm64: snapdragon: CONFIG_KEYBOARD_GPIO=y
+    - [Config] arm64: snapdragon: CONFIG_RTC_DRV_PM8XXX=y
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after rebase to 5.4-rc2
+    - SAUCE: (lockdown) Make get_cert_list() not complain about cert lists that
+      aren't present.
+    - SAUCE: (lockdown) Add efi_status_to_str() and rework efi_status_to_err().
+    - SAUCE: (lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (lockdown) security: lockdown: expose a hook to lock the kernel down
+    - SAUCE: (lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure boot
+      mode
+    - SAUCE: (lockdown) efi: Lock down the kernel if booted in secure boot mode
+    - SAUCE: (lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (lockdown) KEYS: Make use of platform keyring for module signature
+      verify
+    - SAUCE: (lockdown) arm64: Allow locking down the kernel under EFI secure boot
+    - SAUCE: (lockdown) security: lockdown: Make
+      CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT more generic
+    - SAUCE: (lockdown) s390/ipl: lockdown kernel when booted secure
+    - [Config] Enable lockdown under secure boot
+    - SAUCE: import aufs driver
+    - SAUCE: aufs: rwsem owner changed to atmoic_long_t in 5.3
+    - SAUCE: aufs: add "WITH Linux-syscall-note" to SPDX tag of uapi headers
+    - [Config] enable aufs
+    - update dkms package versions
+    - [Config] disable zfs
+    - [Config] disable nvidia dkms build
+    - [Config] disable virtualbox dkms build
+    - [Debian] Generate stub reconstruct for -rc kernels
+    - Revert "UBUNTU: SAUCE: (namespace) block_dev: Forbid unprivileged mounting
+      when device is opened for writing"
+    - Revert "UBUNTU: SAUCE: (namespace) ext4: Add module parameter to enable user
+      namespace mounts"
+    - Revert "UBUNTU: SAUCE: (namespace) ext4: Add support for unprivileged mounts
+      from user namespaces"
+    - Revert "UBUNTU: SAUCE: (namespace) mtd: Check permissions towards mtd block
+      device inode when mounting"
+    - Revert "UBUNTU: SAUCE: (namespace) block_dev: Check permissions towards
+      block device inode when mounting"
+    - Revert "UBUNTU: SAUCE: (namespace) block_dev: Support checking inode
+      permissions in lookup_bdev()"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.4-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 11 Oct 2019 16:42:41 -0500
+
+linux (5.4.0-0.0) eoan; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 08 Oct 2019 09:59:00 -0500
+
+linux (5.3.0-17.18) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-17.18 -proposed tracker (LP: #1846641)
+
+  * CVE-2019-17056
+    - nfc: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-17055
+    - mISDN: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-17054
+    - appletalk: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-17053
+    - ieee802154: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-17052
+    - ax25: enforce CAP_NET_RAW for raw sockets
+
+  * CVE-2019-15098
+    - ath6kl: fix a NULL-ptr-deref bug in ath6kl_usb_alloc_urb_from_pipe()
+
+  * xHCI on AMD Stoney Ridge cannot detect USB 2.0 or 1.1 devices.
+    (LP: #1846470)
+    - x86/PCI: Avoid AMD FCH XHCI USB PME# from D0 defect
+
+  * Re-enable linux-libc-dev build on i386 (LP: #1846508)
+    - [Packaging] Build only linux-libc-dev for i386
+    - [Debian] final-checks -- ignore archtictures with no binaries
+
+  * arm64: loop on boot after installing linux-generic-hwe-18.04-edge/bionic-
+    proposed (LP: #1845820)
+    - [Config] Disable CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
+
+  * Revert ESE DASD discard support (LP: #1846219)
+    - SAUCE: Revert "s390/dasd: Add discard support for ESE volumes"
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 03 Oct 2019 16:57:05 -0500
+
+linux (5.3.0-16.17) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-16.17 -proposed tracker (LP: #1846204)
+
+  * zfs fails to build on s390x  with debug symbols enabled (LP: #1846143)
+    - SAUCE: s390: Mark atomic const ops always inline
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 01 Oct 2019 07:46:43 -0500
+
+linux (5.3.0-15.16) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-15.16 -proposed tracker (LP: #1845987)
+
+  * Drop i386 build for 19.10 (LP: #1845714)
+    - [Packaging] Remove x32 arch references from control files
+    - [Debian] final-checks -- Get arch list from debian/control
+
+  * ZFS kernel modules lack debug symbols (LP: #1840704)
+    - [Debian] Fix conditional for setting zfs debug package path
+
+  * Use pyhon3-sphinx instead of python-sphinx for building html docs
+    (LP: #1845808)
+    - [Packaging] Update sphinx build dependencies to python3 packages
+
+  * Kernel panic with 19.10 beta image (LP: #1845454)
+    - efi/tpm: Don't access event->count when it isn't mapped.
+    - efi/tpm: don't traverse an event log with no events
+    - efi/tpm: only set efi_tpm_final_log_size after successful event log parsing
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 30 Sep 2019 11:57:20 -0500
+
+linux (5.3.0-14.15) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-14.15 -proposed tracker (LP: #1845728)
+
+  * Drop i386 build for 19.10 (LP: #1845714)
+    - [Debian] Remove support for producing i386 kernels
+    - [Debian] Don't use CROSS_COMPILE for i386 configs
+
+  * udevadm trigger will fail when trying to add /sys/devices/vio/
+    (LP: #1845572)
+    - SAUCE: powerpc/vio: drop bus_type from parent device
+
+  * Trying to online dasd drive results in invalid input/output from the kernel
+    on z/VM (LP: #1845323)
+    - SAUCE: s390/dasd: Fix error handling during online processing
+
+  * intel-lpss driver conflicts with write-combining MTRR region (LP: #1845584)
+    - SAUCE: mfd: intel-lpss: add quirk for Dell XPS 13 7390 2-in-1
+
+  * Support Hi1620 zip hw accelerator (LP: #1845355)
+    - [Config] Enable HiSilicon QM/ZIP as modules
+    - crypto: hisilicon - add queue management driver for HiSilicon QM module
+    - crypto: hisilicon - add hardware SGL support
+    - crypto: hisilicon - add HiSilicon ZIP accelerator support
+    - crypto: hisilicon - add SRIOV support for ZIP
+    - Documentation: Add debugfs doc for hisi_zip
+    - crypto: hisilicon - add debugfs for ZIP and QM
+    - MAINTAINERS: add maintainer for HiSilicon QM and ZIP controller driver
+    - crypto: hisilicon - fix kbuild warnings
+    - crypto: hisilicon - add dependency for CRYPTO_DEV_HISI_ZIP
+    - crypto: hisilicon - init curr_sgl_dma to fix compile warning
+    - crypto: hisilicon - add missing single_release
+    - crypto: hisilicon - fix error handle in hisi_zip_create_req_q
+    - crypto: hisilicon - Fix warning on printing %p with dma_addr_t
+    - crypto: hisilicon - Fix return value check in hisi_zip_acompress()
+    - crypto: hisilicon - avoid unused function warning
+
+  * SafeSetID LSM should be built but disabled by default (LP: #1845391)
+    - LSM: SafeSetID: Stop releasing uninitialized ruleset
+    - [Config] Build SafeSetID LSM but don't enable it by default
+
+  * CONFIG_LSM should not specify loadpin since it is not built (LP: #1845383)
+    - [Config] loadpin shouldn't be in CONFIG_LSM
+
+  * Add new pci-id's for CML-S, ICL (LP: #1845317)
+    - drm/i915/icl: Add missing device ID
+    - drm/i915/cml: Add Missing PCI IDs
+
+  * Thunderbolt support for ICL (LP: #1844680)
+    - thunderbolt: Correct path indices for PCIe tunnel
+    - thunderbolt: Move NVM upgrade support flag to struct icm
+    - thunderbolt: Use 32-bit writes when writing ring producer/consumer
+    - thunderbolt: Do not fail adding switch if some port is not implemented
+    - thunderbolt: Hide switch attributes that are not set
+    - thunderbolt: Expose active parts of NVM even if upgrade is not supported
+    - thunderbolt: Add support for Intel Ice Lake
+    - ACPI / property: Add two new Thunderbolt property GUIDs to the list
+
+  * Ubuntu 19.10 -  Additional PCI patch and fix (LP: #1844668)
+    - s390/pci: fix MSI message data
+
+  * Enhanced Hardware Support - Finalize Naming (LP: #1842774)
+    - s390: add support for IBM z15 machines
+    - [Config] CONFIG_MARCH_Z15=n, CONFIG_TUNE_Z15=n
+
+  * Eoan update: v5.3.1 upstream stable release (LP: #1845642)
+    - USB: usbcore: Fix slab-out-of-bounds bug during device reset
+    - media: tm6000: double free if usb disconnect while streaming
+    - phy: renesas: rcar-gen3-usb2: Disable clearing VBUS in over-current
+    - ip6_gre: fix a dst leak in ip6erspan_tunnel_xmit
+    - net/sched: fix race between deactivation and dequeue for NOLOCK qdisc
+    - net_sched: let qdisc_put() accept NULL pointer
+    - udp: correct reuseport selection with connected sockets
+    - xen-netfront: do not assume sk_buff_head list is empty in error handling
+    - net: dsa: Fix load order between DSA drivers and taggers
+    - net: stmmac: Hold rtnl lock in suspend/resume callbacks
+    - KVM: coalesced_mmio: add bounds checking
+    - Documentation: sphinx: Add missing comma to list of strings
+    - firmware: google: check if size is valid when decoding VPD data
+    - serial: sprd: correct the wrong sequence of arguments
+    - tty/serial: atmel: reschedule TX after RX was started
+    - nl80211: Fix possible Spectre-v1 for CQM RSSI thresholds
+    - Revert "arm64: Remove unnecessary ISBs from set_{pte,pmd,pud}"
+    - ovl: fix regression caused by overlapping layers detection
+    - phy: qcom-qmp: Correct ready status, again
+    - floppy: fix usercopy direction
+    - media: technisat-usb2: break out of loop at end of buffer
+    - Linux 5.3.1
+
+  * ZFS kernel modules lack debug symbols (LP: #1840704)
+    - [Debian]: Remove hardcoded $(pkgdir) in debug symbols handling
+    - [Debian]: Handle debug symbols for modules in extras too
+    - [Debian]: Check/link modules with debug symbols after DKMS modules
+    - [Debian]: Warn about modules without debug symbols
+    - [Debian]: dkms-build: new parameter for debug package directory
+    - [Debian]: dkms-build: zfs: support for debug symbols
+    - [Debian]: dkms-build: Avoid executing post-processor scripts twice
+    - [Debian]: dkms-build: Move zfs special-casing into configure script
+
+  * /proc/self/maps paths missing on live session (was vlc won't start; eoan
+    19.10 & bionic 18.04 ubuntu/lubuntu/kubuntu/xubuntu/ubuntu-mate dailies)
+    (LP: #1842382)
+    - SAUCE: Revert "UBUNTU: SAUCE: shiftfs: enable overlayfs on shiftfs"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 27 Sep 2019 16:08:06 -0500
+
+linux (5.3.0-13.14) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-13.14 -proposed tracker (LP: #1845105)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Remove binutils-dev build dependency
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 23 Sep 2019 19:26:43 -0500
+
+linux (5.3.0-12.13) eoan; urgency=medium
+
+  * Change kernel compression method to improve boot speed (LP: #1840934)
+    - [Packaging] Add lz4 build dependency for s390x
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Remove spl and zfs source
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 17 Sep 2019 13:36:26 +0200
+
+linux (5.3.0-11.12) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-11.12 -proposed tracker (LP: #1844144)
+
+  *  Suspend to RAM(S3) does not wake up for latest megaraid and mpt3sas
+    adapters(SAS3.5 onwards) (LP: #1838751)
+    - PCI: Restore Resizable BAR size bits correctly for 1MB BARs
+
+  * s390/setup: Actually init kernel lock down (LP: #1843961)
+    - SAUCE: (lockdown) s390/setup: Actually init kernel lock down
+
+  * cherrypick has_sipl fix (LP: #1843960)
+    - SAUCE: s390/sclp: Fix bit checked for has_sipl
+
+  * Change kernel compression method to improve boot speed (LP: #1840934)
+    - [Config]: Switch kernel compression from LZO to LZ4 on s390x
+
+  * Installation fails on eoan/PowerVM : missing /dev/nvram (LP: #1837726)
+    - [Config] CONFIG_NVRAM=y for ppc64el
+
+  * Miscellaneous Ubuntu changes
+    - [Config]: remove nvram from ppc64el modules ABI
+    - [Config] Update annotations for recent config changes
+    - SAUCE: sched: Add __ASSEMBLY__ guards around struct clone_args
+    - SAUCE: i2c: qcom-geni: Disable DMA processing on the Lenovo Yoga C630
+    - SAUCE: arm64: dts: qcom: Add Lenovo Yoga C630
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 16 Sep 2019 16:18:27 +0200
+
+linux (5.3.0-10.11) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-10.11 -proposed tracker (LP: #1843232)
+
+  * No sound inputs from the external microphone and headset on a Dell machine
+    (LP: #1842265)
+    - SAUCE: ALSA: hda - Expand pin_match function to match upcoming new tbls
+    - SAUCE: ALSA: hda - Define a fallback_pin_fixup_tbl for alc269 family
+
+  * Horizontal corrupted line at top of screen caused by framebuffer compression
+    (LP: #1840236)
+    - SAUCE: drm/i915/fbc: disable framebuffer compression on IceLake
+
+  * Add bpftool to linux-tools-common (LP: #1774815)
+    - [Debian] package bpftool in linux-tools-common
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc8
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 09 Sep 2019 10:00:41 +0200
+
+linux (5.3.0-9.10) eoan; urgency=medium
+
+  * eoan/linux: 5.3.0-9.10 -proposed tracker (LP: #1842393)
+
+  * shiftfs: mark kmem_cache as reclaimable (LP: #1842059)
+    - SAUCE: shiftfs: mark slab objects SLAB_RECLAIM_ACCOUNT
+
+  * shiftfs: drop entries from cache on unlink (LP: #1841977)
+    - SAUCE: shiftfs: fix buggy unlink logic
+
+  * Fix touchpad IRQ storm after S3 (LP: #1841396)
+    - pinctrl: intel: remap the pin number to gpio offset for irq enabled pin
+
+  * Please include DTBs for arm64 laptops (LP: #1842050)
+    - arm64: dts: qcom: Add Lenovo Miix 630
+    - arm64: dts: qcom: Add HP Envy x2
+    - arm64: dts: qcom: Add Asus NovaGo TP370QL
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: import aufs driver
+    - [Packaging]: ignore vbox modules when vbox is disabled
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc7
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Tue, 03 Sep 2019 10:27:33 +0200
+
+linux (5.3.0-8.9) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+
+  * Change kernel compression method to improve boot speed (LP: #1840934)
+    - [Config] change kernel compression method to improve boot speed
+    - [Packaging] add build dependencies for compression algorithms
+
+  * realtek r8822be kernel module fails after update to linux kernel-headers
+    5.0.0-21 (LP: #1838133)
+    - rtw88: Fix misuse of GENMASK macro
+    - rtw88: pci: Rearrange the memory usage for skb in RX ISR
+    - rtw88: pci: Use DMA sync instead of remapping in RX ISR
+    - rtw88: debug: dump tx power indexes in use
+    - rtw88: use txpwr_lmt_cfg_pair struct, not arrays
+    - rtw88: pci: remove set but not used variable 'ip_sel'
+    - rtw88: allow c2h operation in irq context
+    - rtw88: enclose c2h cmd handle with mutex
+    - rtw88: add BT co-existence support
+    - SAUCE: rtw88: pci: enable MSI interrupt
+
+  * VIMC module not available (CONFIG_VIDEO_VIMC not set) (LP: #1831482)
+    - [Config] Enable VIMC module
+
+  * Goodix touchpad may drop first input event (LP: #1840075)
+    - Revert "UBUNTU: SAUCE: i2c: designware: add G3 3590 into i2c quirk"
+    - Revert "UBUNTU: SAUCE: i2c: designware: add Inpiron 7591 into i2c quirk"
+    - Revert "UBUNTU: SAUCE: i2c: designware: add Inpiron/Vostro 7590 into i2c
+      quirk"
+    - Revert "UBUNTU: SAUCE: i2c: designware: Add disable runtime pm quirk"
+    - mfd: intel-lpss: Remove D3cold delay
+
+  * Include Sunix serial/parallel driver (LP: #1826716)
+    - serial: 8250_pci: Add support for Sunix serial boards
+    - parport: parport_serial: Add support for Sunix Multi I/O boards
+
+  * enable lockdown on s390x when Secure IPL is performed (LP: #1839622)
+    - SAUCE: (lockdown) s390/ipl: lockdown kernel when booted secure
+    - Ubuntu: [Config] Enable CONFIG_LOCK_DOWN_KERNEL on s390x.
+
+  * UBUNTU: SAUCE: shiftfs: pass correct point down (LP: #1837231)
+    - SAUCE: shiftfs: pass correct point down
+
+  * shiftfs: add O_DIRECT support (LP: #1837223)
+    - SAUCE: shiftfs: add O_DIRECT support
+
+  * Miscellaneous Ubuntu changes
+    - [Config] enable secureboot signing on s390x
+    - [Config] CONFIG_TEST_BLACKHOLE_DEV=m
+    - SAUCE: selftests: fib_tests: assign address to dummy1 for rp_filter tests
+    - [Debian] disable dkms builds for autopktest rebuilds
+    - update dkms package versions
+    - [Config] updateconfigs after v5.3-rc6 rebase
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 26 Aug 2019 10:09:42 +0200
+
+linux (5.3.0-7.8) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+
+  * Miscellaneous Ubuntu changes
+    - [Config] updateconfigs after v5.3-rc5 rebase
+    - remove missing module after updateconfigs
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc5
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 19 Aug 2019 15:31:24 +0200
+
+linux (5.3.0-6.7) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/bpf: prevent headers to be compiled as C code
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 14 Aug 2019 13:25:01 -0500
+
+linux (5.3.0-5.6) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Config] enable zfs build
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 13 Aug 2019 09:16:06 -0500
+
+linux (5.3.0-4.5) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync getabis
+    - [Packaging] update helper scripts
+
+  * bcache: bch_allocator_thread(): hung task timeout (LP: #1784665) // Tight
+    timeout for bcache removal causes spurious failures (LP: #1796292)
+    - SAUCE: bcache: fix deadlock in bcache_allocator
+
+  * shiftfs: allow overlayfs (LP: #1838677)
+    - SAUCE: shiftfs: enable overlayfs on shiftfs
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "kbuild: modpost: do not parse unnecessary rules for vmlinux
+      modpost"
+    - update dkms package versions
+    - enable nvidia dkms build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 12 Aug 2019 10:41:27 -0500
+
+linux (5.3.0-3.4) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - SAUCE: aufs: add "WITH Linux-syscall-note" to SPDX tag of uapi headers
+    - [Config] add mux-* to modules.ignore
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc3
+
+ -- Paolo Pisati <paolo.pisati@canonical.com>  Mon, 05 Aug 2019 18:17:09 +0200
+
+linux (5.3.0-2.3) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] add build dependincy on fontconfig
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 29 Jul 2019 12:18:46 -0400
+
+linux (5.3.0-1.2) eoan; urgency=medium
+
+  * System does not auto detect disconnection of external monitor (LP: #1835001)
+    - SAUCE: drm/i915: Add support for retrying hotplug
+    - SAUCE: drm/i915: Enable hotplug retry
+
+  * Please enable CONFIG_SCSI_UFS_QCOM as a module on arm64 (LP: #1837332)
+    - [Config] Enable CONFIG_SCSI_UFS_QCOM as a module on arm64.
+
+  * Add arm64 CONFIG_ARCH_MESON=y and related configs Edit (LP: #1820530)
+    - [Config] enable ARCH_MESON
+    - remove missing module
+    - [Config] update annotations after enabling ARCH_MESON for arm64
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: KVM: PPC: comment implicit fallthrough
+    - update dkms package versions
+    - [Config] enable vbox dkms build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 28 Jul 2019 23:10:16 -0400
+
+linux (5.3.0-0.1) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and
+      KEXEC_SIG_FORCE
+    - SAUCE: (efi-lockdown) kexec_file: Restrict at runtime if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) lockdown: Print current->comm in restriction messages
+    - SAUCE: (efi-lockdown) kexec: Allow kexec_file() with appropriate IMA policy
+      when locked down
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation
+      defined
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) KEYS: Make use of platform keyring for module
+      signature verify
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) furter KEXEC_VERIFY_SIG -> KEXEC_SIG updates
+    - SAUCE: (efi-lockdown) arm64: add kernel config option to lock down when in
+      Secure Boot mode
+    - SAUCE: import aufs driver
+    - SAUCE: aufs: rwsem owner changed to atmoic_long_t in 5.3
+    - [Config] disable zfs dkms build
+    - [Config] disable nvidia dkms build
+    - [Config] disable vbox dkms build
+    - SAUCE: perf diff: use llabs for s64 vaules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.3-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 23 Jul 2019 21:45:44 -0500
+
+linux (5.3.0-0.0) eoan; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 22 Jul 2019 10:19:04 -0500
+
+linux (5.2.0-9.10) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * input/mouse: alps trackpoint-only device doesn't work (LP: #1836752)
+    - SAUCE: Input: alps - don't handle ALPS cs19 trackpoint-only device
+    - SAUCE: Input: alps - fix a mismatch between a condition check and its
+      comment
+
+  * System does not auto detect disconnection of external monitor (LP: #1835001)
+    - SAUCE: drm/i915: Add support for retrying hotplug
+    - SAUCE: drm/i915: Enable hotplug retry
+
+  * alsa/hdmi: add icelake hdmi audio support for a Dell machine (LP: #1836916)
+    - SAUCE: ALSA: hda/hdmi - Remove duplicated define
+    - SAUCE: ALSA: hda/hdmi - Fix i915 reverse port/pin mapping
+
+  * First click on Goodix touchpad doesn't be recognized after runtime suspended
+    (LP: #1836836)
+    - SAUCE: i2c: designware: add G3 3590 into i2c quirk
+
+  * ixgbe{vf} - Physical Function gets IRQ when VF checks link state
+    (LP: #1836760)
+    - ixgbevf: Use cached link state instead of re-reading the value for ethtool
+
+  * Doing multiple squashfs (and other loop?) mounts in parallel breaks
+    (LP: #1836914)
+    - SAUCE: Revert "loop: Don't change loop device under exclusive opener"
+
+  * hibmc-drm Causes Unreadable Display for Huawei amd64 Servers (LP: #1762940)
+    - SAUCE: Make CONFIG_DRM_HISI_HIBMC depend on ARM64
+    - [Config] Set CONFIG_DRM_HISI_HIBMC to arm64 only
+    - [Config] add hibmc-drm to modules.ignore
+
+  * hda/realtek: can't detect external mic on a Dell machine (LP: #1836755)
+    - ALSA: hda/realtek: apply ALC891 headset fixup to one Dell machine
+
+  * Enable Armada SOCs and MVPP2 NIC driver for disco/generic arm64
+    (LP: #1835054)
+    - [Config] Enable Armada SOCs and MVPP2 NIC driver for disco/generic arm64
+
+  * Unhide Nvidia HDA audio controller (LP: #1836308)
+    - PCI: Enable NVIDIA HDA controllers
+
+  * Intel ethernet I219 may wrongly detect connection speed as 10Mbps
+    (LP: #1836177)
+    - e1000e: Make watchdog use delayed work
+
+  * Sometimes touchpad(goodix) can't use tap function (LP: #1836020)
+    - SAUCE: i2c: designware: add Inpiron/Vostro 7590 into i2c quirk
+    - SAUCE: i2c: designware: add Inpiron 7591 into i2c quirk
+
+  * Intel ethernet I219 has slow RX speed (LP: #1836152)
+    - e1000e: add workaround for possible stalled packet
+    - e1000e: disable force K1-off feature
+
+  * bcache: risk of data loss on I/O errors in backing or caching devices
+    (LP: #1829563)
+    - Revert "bcache: set CACHE_SET_IO_DISABLE in bch_cached_dev_error()"
+
+  * bnx2x driver causes 100% CPU load (LP: #1832082)
+    - bnx2x: Prevent ptp_task to be rescheduled indefinitely
+
+  * fcf-protection=none patch with new version
+    - Revert "UBUNTU: SAUCE: kbuild: add -fcf-protection=none to retpoline flags"
+    - SAUCE: kbuild: add -fcf-protection=none when using retpoline flags
+
+  * CVE-2019-12614
+    - powerpc/pseries/dlpar: Fix a missing check in dlpar_parse_cc_property()
+
+  * Eoan update: v5.2.1 upstream stable release (LP: #1836622)
+    - crypto: lrw - use correct alignmask
+    - crypto: talitos - rename alternative AEAD algos.
+    - fscrypt: don't set policy for a dead directory
+    - udf: Fix incorrect final NOT_ALLOCATED (hole) extent length
+    - media: stv0297: fix frequency range limit
+    - ALSA: usb-audio: Fix parse of UAC2 Extension Units
+    - ALSA: hda/realtek - Headphone Mic can't record after S3
+    - tpm: Actually fail on TPM errors during "get random"
+    - tpm: Fix TPM 1.2 Shutdown sequence to prevent future TPM operations
+    - block: fix .bi_size overflow
+    - block, bfq: NULL out the bic when it's no longer valid
+    - perf intel-pt: Fix itrace defaults for perf script
+    - perf auxtrace: Fix itrace defaults for perf script
+    - perf intel-pt: Fix itrace defaults for perf script intel-pt documentation
+    - perf pmu: Fix uncore PMU alias list for ARM64
+    - perf thread-stack: Fix thread stack return from kernel for kernel-only case
+    - perf header: Assign proper ff->ph in perf_event__synthesize_features()
+    - x86/ptrace: Fix possible spectre-v1 in ptrace_get_debugreg()
+    - x86/tls: Fix possible spectre-v1 in do_get_thread_area()
+    - Documentation: Add section about CPU vulnerabilities for Spectre
+    - Documentation/admin: Remove the vsyscall=native documentation
+    - mwifiex: Don't abort on small, spec-compliant vendor IEs
+    - USB: serial: ftdi_sio: add ID for isodebug v1
+    - USB: serial: option: add support for GosunCn ME3630 RNDIS mode
+    - Revert "serial: 8250: Don't service RX FIFO if interrupts are disabled"
+    - p54usb: Fix race between disconnect and firmware loading
+    - usb: gadget: f_fs: data_len used before properly set
+    - usb: gadget: ether: Fix race between gether_disconnect and rx_submit
+    - usb: dwc2: use a longer AHB idle timeout in dwc2_core_reset()
+    - usb: renesas_usbhs: add a workaround for a race condition of workqueue
+    - drivers/usb/typec/tps6598x.c: fix portinfo width
+    - drivers/usb/typec/tps6598x.c: fix 4CC cmd write
+    - p54: fix crash during initialization
+    - staging: comedi: dt282x: fix a null pointer deref on interrupt
+    - staging: wilc1000: fix error path cleanup in wilc_wlan_initialize()
+    - staging: bcm2835-camera: Restore return behavior of ctrl_set_bitrate()
+    - staging: comedi: amplc_pci230: fix null pointer deref on interrupt
+    - staging: mt7621-pci: fix PCIE_FTS_NUM_LO macro
+    - HID: Add another Primax PIXART OEM mouse quirk
+    - lkdtm: support llvm-objcopy
+    - binder: fix memory leak in error path
+    - binder: return errors from buffer copy functions
+    - iio: adc: stm32-adc: add missing vdda-supply
+    - coresight: Potential uninitialized variable in probe()
+    - coresight: etb10: Do not call smp_processor_id from preemptible
+    - coresight: tmc-etr: Do not call smp_processor_id() from preemptible
+    - coresight: tmc-etr: alloc_perf_buf: Do not call smp_processor_id from
+      preemptible
+    - coresight: tmc-etf: Do not call smp_processor_id from preemptible
+    - carl9170: fix misuse of device driver API
+    - Revert "x86/build: Move _etext to actual end of .text"
+    - VMCI: Fix integer overflow in VMCI handle arrays
+    - staging: vchiq_2835_arm: revert "quit using custom down_interruptible()"
+    - staging: vchiq: make wait events interruptible
+    - staging: vchiq: revert "switch to wait_for_completion_killable"
+    - staging: fsl-dpaa2/ethsw: fix memory leak of switchdev_work
+    - staging: bcm2835-camera: Replace spinlock protecting context_map with mutex
+    - staging: bcm2835-camera: Ensure all buffers are returned on disable
+    - staging: bcm2835-camera: Remove check of the number of buffers supplied
+    - staging: bcm2835-camera: Handle empty EOS buffers whilst streaming
+    - staging: rtl8712: reduce stack usage, again
+    - Linux 5.2.1
+    - [Config] updateconfigs after v5.2.1 stable update
+
+  * fcf-protection=none patch with upstream version
+    - Revert "UBUNTU: SAUCE: add -fcf-protection=none to retpoline flags"
+    - SAUCE: kbuild: add -fcf-protection=none to retpoline flags
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/ftrace: avoid failure when trying to probe a notrace
+      function
+    - SAUCE: selftests/powerpc/ptrace: fix build failure
+    - update dkms package versions
+    - [Packaging] add zlua to zfs-modules.ignore
+    - update dkms package versions
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 19 Jul 2019 15:04:45 -0500
+
+linux (5.2.0-8.9) eoan; urgency=medium
+
+  * linux: 5.2.0-8.9 -proposed tracker (LP: #1835700)
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] replace zfs and spl build with zfs 0.8.1-1ubuntu1
+    - SAUCE: test_bpf: remove expected fail for Ctx heavy transformations test on
+      s390
+    - SAUCE: add -fcf-protection=none to retpoline flags
+    - SAUCE: usbip: ensure strings copied using strncpy are null-terminated
+    - SAUCE: usbip: add -Wno-address-of-packed-member to EXTRA_CFLAGS
+    - SAUCE: perf jvmti: ensure strncpy result is null-terminated
+    - update dkms package versions
+    - add removed zfs modules to modules.ignore
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 08 Jul 2019 07:13:41 -0500
+
+linux (5.2.0-7.8) eoan; urgency=medium
+
+  * Kernel panic upon resetting ixgbe SR-IOV VFIO virtual function using 5.0
+    kernel (LP: #1829652)
+    - SAUCE: ixgbe: Avoid NULL pointer dereference with VF on non-IPsec hw
+
+  * Hi1620 driver updates from upstream 5.2 merge window (LP: #1830815)
+    - net: hns3: initialize CPU reverse mapping
+    - net: hns3: refine the flow director handle
+    - net: hns3: add aRFS support for PF
+    - net: hns3: fix for FEC configuration
+    - RDMA/hns: Remove unnecessary print message in aeq
+    - RDMA/hns: Update CQE specifications
+    - RDMA/hns: Move spin_lock_irqsave to the correct place
+    - RDMA/hns: Remove jiffies operation in disable interrupt context
+    - RDMA/hns: Replace magic numbers with #defines
+    - net: hns3: fix compile warning without CONFIG_RFS_ACCEL
+    - net: hns3: fix for HNS3_RXD_GRO_SIZE_M macro
+    - net: hns3: add support for dump firmware statistics by debugfs
+    - net: hns3: use HCLGE_STATE_NIC_REGISTERED to indicate PF NIC client has
+      registered
+    - net: hns3: use HCLGE_STATE_ROCE_REGISTERED to indicate PF ROCE client has
+      registered
+    - net: hns3: use HCLGEVF_STATE_NIC_REGISTERED to indicate VF NIC client has
+      registered
+    - net: hns3: modify hclge_init_client_instance()
+    - net: hns3: modify hclgevf_init_client_instance()
+    - net: hns3: add handshake with hardware while doing reset
+    - net: hns3: stop schedule reset service while unloading driver
+    - net: hns3: adjust hns3_uninit_phy()'s location in the hns3_client_uninit()
+    - net: hns3: fix a memory leak issue for hclge_map_unmap_ring_to_vf_vector
+    - RDMA/hns: Bugfix for posting multiple srq work request
+    - net: hns3: remove redundant core reset
+    - net: hns3: don't configure new VLAN ID into VF VLAN table when it's full
+    - net: hns3: fix VLAN filter restore issue after reset
+    - net: hns3: set the port shaper according to MAC speed
+    - net: hns3: add a check to pointer in error_detected and slot_reset
+    - net: hns3: set ops to null when unregister ad_dev
+    - net: hns3: add handling of two bits in MAC tunnel interrupts
+    - net: hns3: remove setting bit of reset_requests when handling mac tunnel
+      interrupts
+    - net: hns3: add opcode about query and clear RAS & MSI-X to special opcode
+    - net: hns3: delay and separate enabling of NIC and ROCE HW errors
+    - RDMA/hns: fix inverted logic of readl read and shift
+    - RDMA/hns: Bugfix for filling the sge of srq
+    - net: hns3: log detail error info of ROCEE ECC and AXI errors
+    - net: hns3: fix wrong size of mailbox responding data
+    - net: hns3: make HW GRO handling compliant with SW GRO
+    - net: hns3: replace numa_node_id with numa_mem_id for buffer reusing
+    - net: hns3: refactor hns3_get_new_int_gl function
+    - net: hns3: trigger VF reset if a VF has an over_8bd_nfe_err
+    - net: hns3: delete the redundant user NIC codes
+    - net: hns3: small changes for magic numbers
+    - net: hns3: use macros instead of magic numbers
+    - net: hns3: refactor PF/VF RSS hash key configuration
+    - net: hns3: some modifications to simplify and optimize code
+    - net: hns3: fix some coding style issues
+    - net: hns3: delay setting of reset level for hw errors until slot_reset is
+      called
+    - net: hns3: fix avoid unnecessary resetting for the H/W errors which do not
+      require reset
+    - net: hns3: process H/W errors occurred before HNS dev initialization
+    - net: hns3: add recovery for the H/W errors occurred before the HNS dev
+      initialization
+    - net: hns3: some changes of MSI-X bits in PPU(RCB)
+    - net: hns3: extract handling of mpf/pf msi-x errors into functions
+    - net: hns3: clear restting state when initializing HW device
+    - net: hns3: free irq when exit from abnormal branch
+    - net: hns3: fix for dereferencing before null checking
+    - net: hns3: fix for skb leak when doing selftest
+    - net: hns3: delay ring buffer clearing during reset
+    - net: hns3: some variable modification
+    - net: hns3: fix dereference of ae_dev before it is null checked
+    - scsi: hisi_sas: Delete PHY timers when rmmod or probe failed
+    - scsi: hisi_sas: Fix the issue of argument mismatch of printing ecc errors
+    - scsi: hisi_sas: Reduce HISI_SAS_SGE_PAGE_CNT in size
+    - scsi: hisi_sas: Change the type of some numbers to unsigned
+    - scsi: hisi_sas: Ignore the error code between phy down to phy up
+    - scsi: hisi_sas: Disable stash for v3 hw
+    - net: hns3: Add missing newline at end of file
+    - RDMa/hns: Don't stuck in endless timeout loop
+
+  * Sometimes touchpad automatically trigger double click (LP: #1833484)
+    - SAUCE: i2c: designware: Add disable runtime pm quirk
+
+  * Add pointstick support on HP ZBook 17 G5 (LP: #1833387)
+    - Revert "HID: multitouch: Support ALPS PTP stick with pid 0x120A"
+
+  * depmod may prefer unsigned l-r-m nvidia modules to signed modules
+    (LP: #1834479)
+    - [Packaging] dkms-build--nvidia-N -- clean up unsigned ko files
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/powerpc: disable signal_fuzzer test
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 01 Jul 2019 07:22:18 -0500
+
+linux (5.2.0-6.7) eoan; urgency=medium
+
+  * hinic: fix oops due to race in set_rx_mode (LP: #1832048)
+    - hinic: fix a bug in set rx mode
+
+  * Miscellaneous Ubuntu changes
+    - rebase to v5.2-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 23 Jun 2019 23:36:11 -0500
+
+linux (5.2.0-5.6) eoan; urgency=medium
+
+  * QCA9377 isn't being recognized sometimes (LP: #1757218)
+    - SAUCE: USB: Disable USB2 LPM at shutdown
+
+  * shiftfs: allow changing ro/rw for subvolumes (LP: #1832316)
+    - SAUCE: shiftfs: allow changing ro/rw for subvolumes
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - [Packaging] replace nvidia-418 dkms build with nvidia-430
+    - SAUCE: import aufs driver
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 17 Jun 2019 15:04:12 -0500
+
+linux (5.2.0-4.5) eoan; urgency=medium
+
+  * arm64: cma_alloc errors at boot (LP: #1823753)
+    - [Config] Bump CMA_SIZE_MBYTES to 32 on arm64
+    - dma-contiguous: add dma_{alloc,free}_contiguous() helpers
+    - dma-contiguous: use fallback alloc_pages for single pages
+    - dma-contiguous: fix !CONFIG_DMA_CMA version of dma_{alloc,
+      free}_contiguous()
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_MFD_TQMX86=n for s390x
+    - [Config] CONFIG_GPIO_AMD_FCH=n for s390x
+    - [Config] CONFIG_BACKLIGHT_CLASS_DEVICE=n on s390x
+    - [Config] CONFIG_LCD_CLASS_DEVICE=n for s390x
+    - [Config] CONFIG_DRM_ETNAVIV=m for armhf generic-lpae
+    - [Config] CONFIG_DRM_NOUVEAU_SVM=n
+    - [Config] CONFIG_HWMON=n for s390x
+    - [Config] CONFIG_NEW_LEDS=n for s390x
+    - [Config] CONFIG_MTD_NAND_OMAP2=y for armhf
+    - [Config] CONFIG_VOP_BUS=n for non-amd64 arches
+    - [Config] CONFIG_TI_CPSW_PHY_SEL=n
+    - [Config] CONFIG_INTERCONNECT=n for s390x
+    - [Config] CONFIG_SCSI_GDTH=n for s390x
+    - [Config] CONFIG_PACKING=n for s390x
+    - [Config] CONFIG_ARCH_MILBEAUT=y for armhf
+    - [Config] update annotations following config review
+    - update dkms package versions
+    - [Config] enable nvidia dkms build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 10 Jun 2019 07:00:11 -0500
+
+linux (5.2.0-3.4) eoan; urgency=medium
+
+  * [18.04/18.10] File libperf-jvmti.so is missing in linux-tools-common deb on
+    Ubuntu (LP: #1761379)
+    - [Packaging] Support building libperf-jvmti.so
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Revert "bpf, selftest: test global data/bss/rodata sections"
+    - update dkms package versions
+    - [Config] enable zfs
+    - rebase to v5.2-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 02 Jun 2019 21:48:50 -0500
+
+linux (5.2.0-2.3) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: perf arm64: Fix mksyscalltbl when system kernel headers are ahead of
+      the kernel
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 May 2019 07:12:39 -0500
+
+linux (5.2.0-1.2) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_INTEGRITY_PLATFORM_KEYRING=y
+    - update dkms package versions
+    - [Config] enable vbox dkms build
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 May 2019 21:11:27 -0500
+
+linux (5.2.0-0.1) eoan; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: import aufs driver
+    - [Packaging] disable ZFS
+    - [Packaging] disable nvidia
+    - [Packaging] dkms-build -- expand paths searched for make.log files
+    - add virtualbox-guest-dkms dkms package build
+    - enable vbox dkms build for amd64 and i386
+    - update dkms package versions
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and
+      KEXEC_SIG_FORCE
+    - SAUCE: (efi-lockdown) kexec_file: Restrict at runtime if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) lockdown: Print current->comm in restriction messages
+    - SAUCE: (efi-lockdown) kexec: Allow kexec_file() with appropriate IMA policy
+      when locked down
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) KEYS: Make use of platform keyring for module
+      signature verify
+    - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation
+      defined
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) furter KEXEC_VERIFY_SIG -> KEXEC_SIG updates
+    - SAUCE: (efi-lockdown) arm64: add kernel config option to lock down when in
+      Secure Boot mode
+    - update dkms package versions
+    - [Config] disable vbox build
+    - SAUCE: s390: mark __cpacf_check_opcode() and cpacf_query_func() as
+      __always_inline
+    - SAUCE: IB/mlx5: use size_t instead of u64 when dividing
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.2-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 21 May 2019 11:18:43 -0500
+
+linux (5.2.0-0.0) eoan; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 21 May 2019 07:34:43 -0500
+
+linux (5.1.0-2.2) eoan; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+
+  * Eoan update: v5.1.2 upstream stable release (LP: #1829050)
+    - x86/msr-index: Cleanup bit defines
+    - x86/speculation: Consolidate CPU whitelists
+    - x86/speculation/mds: Add basic bug infrastructure for MDS
+    - x86/speculation/mds: Add BUG_MSBDS_ONLY
+    - x86/kvm: Expose X86_FEATURE_MD_CLEAR to guests
+    - x86/speculation/mds: Add mds_clear_cpu_buffers()
+    - x86/speculation/mds: Clear CPU buffers on exit to user
+    - x86/kvm/vmx: Add MDS protection when L1D Flush is not active
+    - x86/speculation/mds: Conditionally clear CPU buffers on idle entry
+    - x86/speculation/mds: Add mitigation control for MDS
+    - x86/speculation/mds: Add sysfs reporting for MDS
+    - x86/speculation/mds: Add mitigation mode VMWERV
+    - Documentation: Move L1TF to separate directory
+    - Documentation: Add MDS vulnerability documentation
+    - x86/speculation/mds: Add mds=full,nosmt cmdline option
+    - x86/speculation: Move arch_smt_update() call to after mitigation decisions
+    - x86/speculation/mds: Add SMT warning message
+    - x86/speculation/mds: Fix comment
+    - x86/speculation/mds: Print SMT vulnerable on MSBDS with mitigations off
+    - cpu/speculation: Add 'mitigations=' cmdline option
+    - x86/speculation: Support 'mitigations=' cmdline option
+    - powerpc/speculation: Support 'mitigations=' cmdline option
+    - s390/speculation: Support 'mitigations=' cmdline option
+    - x86/speculation/mds: Add 'mitigations=' support for MDS
+    - x86/mds: Add MDSUM variant to the MDS documentation
+    - Documentation: Correct the possible MDS sysfs values
+    - x86/speculation/mds: Fix documentation typo
+    - Linux 5.1.2
+
+  * Eoan update: v5.1.1 upstream stable release (LP: #1829046)
+    - Drivers: hv: vmbus: Remove the undesired put_cpu_ptr() in hv_synic_cleanup()
+    - ubsan: Fix nasty -Wbuiltin-declaration-mismatch GCC-9 warnings
+    - staging: greybus: power_supply: fix prop-descriptor request size
+    - staging: wilc1000: Avoid GFP_KERNEL allocation from atomic context.
+    - staging: most: cdev: fix chrdev_region leak in mod_exit
+    - staging: most: sound: pass correct device when creating a sound card
+    - usb: dwc3: Allow building USB_DWC3_QCOM without EXTCON
+    - usb: dwc3: Fix default lpm_nyet_threshold value
+    - USB: serial: f81232: fix interrupt worker not stop
+    - USB: cdc-acm: fix unthrottle races
+    - usb-storage: Set virt_boundary_mask to avoid SG overflows
+    - genirq: Prevent use-after-free and work list corruption
+    - intel_th: pci: Add Comet Lake support
+    - iio: adc: qcom-spmi-adc5: Fix of-based module autoloading
+    - cpufreq: armada-37xx: fix frequency calculation for opp
+    - ACPI / LPSS: Use acpi_lpss_* instead of acpi_subsys_* functions for
+      hibernate
+    - soc: sunxi: Fix missing dependency on REGMAP_MMIO
+    - scsi: lpfc: change snprintf to scnprintf for possible overflow
+    - scsi: qla2xxx: Fix incorrect region-size setting in optrom SYSFS routines
+    - scsi: qla2xxx: Set remote port devloss timeout to 0
+    - scsi: qla2xxx: Fix device staying in blocked state
+    - Bluetooth: hidp: fix buffer overflow
+    - Bluetooth: Align minimum encryption key size for LE and BR/EDR connections
+    - Bluetooth: Fix not initializing L2CAP tx_credits
+    - Bluetooth: hci_bcm: Fix empty regulator supplies for Intel Macs
+    - UAS: fix alignment of scatter/gather segments
+    - ASoC: Intel: avoid Oops if DMA setup fails
+    - i3c: Fix a shift wrap bug in i3c_bus_set_addr_slot_status()
+    - locking/futex: Allow low-level atomic operations to return -EAGAIN
+    - arm64: futex: Bound number of LDXR/STXR loops in FUTEX_WAKE_OP
+    - Linux 5.1.1
+
+  * shiftfs: lock security sensitive superblock flags (LP: #1827122)
+    - SAUCE: shiftfs: lock down certain superblock flags
+
+  * Please package libbpf (which is done out of the kernel src) in Debian [for
+    19.10] (LP: #1826410)
+    - SAUCE: tools -- fix add ability to disable libbfd
+
+  * ratelimit cma_alloc messages (LP: #1828092)
+    - SAUCE: cma: ratelimit cma_alloc error messages
+
+  * Headphone jack switch sense is inverted: plugging in headphones disables
+    headphone output (LP: #1824259)
+    - ASoC: rt5645: Headphone Jack sense inverts on the LattePanda board
+
+  * There are 4 HDMI/Displayport audio output listed in sound setting without
+    attach any HDMI/DP monitor (LP: #1827967)
+    - ALSA: hda/hdmi - Read the pin sense from register when repolling
+    - ALSA: hda/hdmi - Consider eld_valid when reporting jack event
+
+  * CONFIG_LOG_BUF_SHIFT set to 14 is too low on arm64 (LP: #1824864)
+    - [Config] CONFIG_LOG_BUF_SHIFT=18 on all 64bit arches
+
+  * CTAUTO:DevOps:860.50:devops4fp1:Error occurred during LINUX Dmesg error
+    Checking for all LINUX clients for devops4p10 (LP: #1766201)
+    - SAUCE: integrity: downgrade error to warning
+
+  * linux-buildinfo: pull out ABI information into its own package
+    (LP: #1806380)
+    - [Packaging] autoreconstruct -- base tag is always primary mainline version
+
+  * [SRU] Please sync vbox modules from virtualbox 6.0.6 on next kernel update
+    (LP: #1825210)
+    - vbox-update: updates for renamed makefiles
+    - ubuntu: vbox -- update to 6.0.6-dfsg-1
+
+  * autofs kernel module missing (LP: #1824333)
+    - [Config] Update autofs4 path in inclusion list
+
+  * The Realtek card reader does not enter PCIe 1.1/1.2 (LP: #1825487)
+    - SAUCE: misc: rtsx: Fixed rts5260 power saving parameter and sd glitch
+
+  * CVE-2019-3874
+    - sctp: implement memory accounting on tx path
+    - sctp: implement memory accounting on rx path
+
+  * apparmor does not start in Disco LXD containers (LP: #1824812)
+    - SAUCE: shiftfs: use separate llseek method for directories
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] autoreconstruct -- remove for -rc kernels
+    - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation
+      defined
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) furter KEXEC_VERIFY_SIG -> KEXEC_SIG updates
+    - [Config] (efi-lockdown): update configs after efi lockdown patch refresh
+    - [Packaging] don't delete efi_parser.c
+    - vbox-update -- do not fix up KERN_DIR or KBUILD_EXTMOD
+    - ubuntu: vbox -- update to 6.0.6-dfsg-2
+    - add nvidia-418 dkms build
+    - remove virtualbox guest drivers
+    - [Packaging] dkms-build -- expand paths searched for make.log files
+    - add virtualbox-guest-dkms dkms package build
+    - enable vbox dkms build for amd64 and i386
+    - [Config] update configs for v5.1(-rc7)? rebase
+    - update dkms package versions
+    - Add the ability to lock down access to the running kernel image
+    - Enforce module signatures if the kernel is locked down
+    - Restrict /dev/{mem,kmem,port} when the kernel is locked down
+    - kexec_load: Disable at runtime if the kernel is locked down
+    - Copy secure_boot flag in boot params across kexec reboot
+    - kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE
+    - kexec_file: Restrict at runtime if the kernel is locked down
+    - hibernate: Disable when the kernel is locked down
+    - uswsusp: Disable when the kernel is locked down
+    - PCI: Lock down BAR access when the kernel is locked down
+    - x86: Lock down IO port access when the kernel is locked down
+    - x86/msr: Restrict MSR access when the kernel is locked down
+    - ACPI: Limit access to custom_method when the kernel is locked down
+    - acpi: Ignore acpi_rsdp kernel param when the kernel has been locked down
+    - acpi: Disable ACPI table override if the kernel is locked down
+    - acpi: Disable APEI error injection if the kernel is locked down
+    - Prohibit PCMCIA CIS storage when the kernel is locked down
+    - Lock down TIOCSSERIAL
+    - Lock down module params that specify hardware parameters (eg. ioport)
+    - x86/mmiotrace: Lock down the testmmiotrace module
+    - Lock down /proc/kcore
+    - Lock down kprobes
+    - bpf: Restrict kernel image access functions when the kernel is locked down
+    - Lock down perf
+    - debugfs: Restrict debugfs when the kernel is locked down
+    - lockdown: Print current->comm in restriction messages
+    - kexec: Allow kexec_file() with appropriate IMA policy when locked down
+    - Make get_cert_list() not complain about cert lists that aren't present.
+    - Add efi_status_to_str() and rework efi_status_to_err().
+    - Make get_cert_list() use efi_status_to_str() to print error messages.
+    - efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode
+    - efi: Lock down the kernel if booted in secure boot mode
+    - KEYS: Make use of platform keyring for module signature verify
+
+  * Miscellaneous upstream changes
+    - ALSA: hdea/realtek - Headset fixup for System76 Gazelle (gaze14)
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 14 May 2019 12:32:56 -0500
+
+linux (5.1.0-1.1) eoan; urgency=medium
+
+  * bionic: fork out linux-snapdragon into its own topic kernel (LP: #1820868)
+    - [Packaging]: really drop snapdragon
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: fix vbox use of MAP_SHARED
+    - SAUCE: fix vbox use of vm_fault_t
+    - [Packaging] disable ZFS
+    - [Packaging] disable nvidia
+    - SAUCE: perf annotate: Fix build on 32 bit for BPF annotation
+    - [Config]: updateconfig after rebase to v5.1-rc
+    - [Config]: build ETNAVIV only on arm platforms
+    - [Config]: Disable CMA on non-arm platforms
+    - [Config]: MMC_CQHCI is needed by some built-in drivers
+    - [Config]: a.out support has been deprecated
+    - [Config]: R3964 was marked as BROKEN
+    - [Config]: Add SENSIRION_SGP30 module
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: tools: lib/bpf -- add generated headers to search
+      path"
+    - Revert "UBUNTU: SAUCE: btqcomsmd: introduce BT_QCOMSMD_HACK"
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Thu, 25 Apr 2019 10:03:25 -0300
+
+linux (5.1.0-0.0) eoan; urgency=medium
+
+  * Dummy entry.
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Thu, 25 Apr 2019 09:49:47 -0300
+
+linux (5.0.0-13.14) disco; urgency=medium
+
+  * linux: 5.0.0-13.14 -proposed tracker (LP: #1824819)
+
+  * Display only has 640x480 (LP: #1824677)
+    - Revert "UBUNTU: SAUCE: drm/nouveau: Disable nouveau driver by default"
+
+  * shiftfs: use after free when checking mount options (LP: #1824735)
+    - SAUCE: shiftfs: prevent use-after-free when verifying mount options
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 15 Apr 2019 09:11:23 -0500
+
+linux (5.0.0-12.13) disco; urgency=medium
+
+  * linux: 5.0.0-12.13 -proposed tracker (LP: #1824726)
+
+  * Linux 5.0 black screen on boot, display flickers (i915 regression with
+    certain laptop panels) (LP: #1824216)
+    - drm/i915/dp: revert back to max link rate and lane count on eDP
+
+  * kernel BUG at fs/attr.c:287 when using shiftfs (LP: #1824717)
+    - SAUCE: shiftfs: fix passing of attrs to underaly for setattr
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 14 Apr 2019 13:38:05 -0500
+
+linux (5.0.0-11.12) disco; urgency=medium
+
+  * linux: 5.0.0-11.12 -proposed tracker (LP: #1824383)
+
+  * hns3: PPU_PF_ABNORMAL_INT_ST over_8bd_no_fe found [error status=0x1]
+    (LP: #1824194)
+    - net: hns3: fix for not calculating tx bd num correctly
+
+  * disco: unable to use iptables/enable ufw under -virtual kernel
+    (LP: #1823862)
+    - [Packaging] add bpfilter to linux-modules
+
+  * Make shiftfs a module rather than built-in (LP: #1824354)
+    - [Config] CONFIG_SHIFT_FS=m
+
+  * shiftfs: chown sets untranslated ids in lower fs (LP: #1824350)
+    - SAUCE: shiftfs: use translated ids when chaning lower fs attrs
+
+  * [Hyper-V] KVP daemon fails to start on first boot of disco VM (LP: #1820063)
+    - [Packaging] bind hv_kvp_daemon startup to hv_kvp device
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 11 Apr 2019 10:17:19 -0500
+
+linux (5.0.0-10.11) disco; urgency=medium
+
+  * linux: 5.0.0-10.11 -proposed tracker (LP: #1823936)
+
+  * Apparmor enforcement failure in lxc selftests (LP: #1823379)
+    - SAUCE: apparmor: Restore Y/N in /sys for apparmor's "enabled"
+
+  * systemd cause kernel trace "BUG: unable to handle kernel paging request at
+    6db23a14" on Cosmic i386 (LP: #1813244)
+    - openvswitch: fix flow actions reallocation
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 09 Apr 2019 08:30:38 -0500
+
+linux (5.0.0-9.10) disco; urgency=medium
+
+  * linux: 5.0.0-9.10 -proposed tracker (LP: #1823228)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] resync git-ubuntu-log
+    - [Packaging] update helper scripts
+    - [Packaging] resync retpoline extraction
+
+  * Huawei Hi1822 NIC has poor performance (LP: #1820187)
+    - net-next/hinic: replace disable_irq_nosync/enable_irq
+
+  * Add uid shifting overlay filesystem (shiftfs) (LP: #1823186)
+    - shiftfs: uid/gid shifting bind mount
+    - shiftfs: rework and extend
+    - shiftfs: support some btrfs ioctls
+    - [Config] enable shiftfs
+
+  * Cannot boot or install - have to use nomodeset (LP: #1821820)
+    - Revert "drm/i915/fbdev: Actually configure untiled displays"
+
+  * Disco update: v5.0.6 upstream stable release (LP: #1823060)
+    - netfilter: nf_tables: fix set double-free in abort path
+    - dccp: do not use ipv6 header for ipv4 flow
+    - genetlink: Fix a memory leak on error path
+    - gtp: change NET_UDP_TUNNEL dependency to select
+    - ipv6: make ip6_create_rt_rcu return ip6_null_entry instead of NULL
+    - mac8390: Fix mmio access size probe
+    - mISDN: hfcpci: Test both vendor & device ID for Digium HFC4S
+    - net: aquantia: fix rx checksum offload for UDP/TCP over IPv6
+    - net: datagram: fix unbounded loop in __skb_try_recv_datagram()
+    - net/packet: Set __GFP_NOWARN upon allocation in alloc_pg_vec
+    - net: phy: meson-gxl: fix interrupt support
+    - net: rose: fix a possible stack overflow
+    - net: stmmac: fix memory corruption with large MTUs
+    - net-sysfs: call dev_hold if kobject_init_and_add success
+    - net: usb: aqc111: Extend HWID table by QNAP device
+    - packets: Always register packet sk in the same order
+    - rhashtable: Still do rehash when we get EEXIST
+    - sctp: get sctphdr by offset in sctp_compute_cksum
+    - sctp: use memdup_user instead of vmemdup_user
+    - tcp: do not use ipv6 header for ipv4 flow
+    - tipc: allow service ranges to be connect()'ed on RDM/DGRAM
+    - tipc: change to check tipc_own_id to return in tipc_net_stop
+    - tipc: fix cancellation of topology subscriptions
+    - tun: properly test for IFF_UP
+    - vrf: prevent adding upper devices
+    - vxlan: Don't call gro_cells_destroy() before device is unregistered
+    - thunderx: enable page recycling for non-XDP case
+    - thunderx: eliminate extra calls to put_page() for pages held for recycling
+    - net: dsa: mv88e6xxx: fix few issues in mv88e6390x_port_set_cmode
+    - net: mii: Fix PAUSE cap advertisement from linkmode_adv_to_lcl_adv_t()
+      helper
+    - net: phy: don't clear BMCR in genphy_soft_reset
+    - r8169: fix cable re-plugging issue
+    - ila: Fix rhashtable walker list corruption
+    - tun: add a missing rcu_read_unlock() in error path
+    - powerpc/fsl: Fix the flush of branch predictor.
+    - Btrfs: fix incorrect file size after shrinking truncate and fsync
+    - btrfs: remove WARN_ON in log_dir_items
+    - btrfs: don't report readahead errors and don't update statistics
+    - btrfs: Fix bound checking in qgroup_trace_new_subtree_blocks
+    - btrfs: Avoid possible qgroup_rsv_size overflow in
+      btrfs_calculate_inode_block_rsv_size
+    - Btrfs: fix assertion failure on fsync with NO_HOLES enabled
+    - locks: wake any locks blocked on request before deadlock check
+    - tracing: initialize variable in create_dyn_event()
+    - ARM: imx6q: cpuidle: fix bug that CPU might not wake up at expected time
+    - powerpc: bpf: Fix generation of load/store DW instructions
+    - vfio: ccw: only free cp on final interrupt
+    - NFS: Fix nfs4_lock_state refcounting in nfs4_alloc_{lock,unlock}data()
+    - NFS: fix mount/umount race in nlmclnt.
+    - NFSv4.1 don't free interrupted slot on open
+    - net: dsa: qca8k: remove leftover phy accessors
+    - ALSA: rawmidi: Fix potential Spectre v1 vulnerability
+    - ALSA: seq: oss: Fix Spectre v1 vulnerability
+    - ALSA: pcm: Fix possible OOB access in PCM oss plugins
+    - ALSA: pcm: Don't suspend stream in unrecoverable PCM state
+    - ALSA: hda/realtek - Fixed Headset Mic JD not stable
+    - ALSA: hda/realtek: merge alc_fixup_headset_jack to alc295_fixup_chromebook
+    - ALSA: hda/realtek - Add support headset mode for DELL WYSE AIO
+    - ALSA: hda/realtek - Add support headset mode for New DELL WYSE NB
+    - ALSA: hda/realtek: Enable headset MIC of Acer AIO with ALC286
+    - ALSA: hda/realtek: Enable headset MIC of Acer Aspire Z24-890 with ALC286
+    - ALSA: hda/realtek - Add support for Acer Aspire E5-523G/ES1-432 headset mic
+    - ALSA: hda/realtek: Enable ASUS X441MB and X705FD headset MIC with ALC256
+    - ALSA: hda/realtek: Enable headset mic of ASUS P5440FF with ALC256
+    - ALSA: hda/realtek: Enable headset MIC of ASUS X430UN and X512DK with ALC256
+    - ALSA: hda/realtek - Fix speakers on Acer Predator Helios 500 Ryzen laptops
+    - kbuild: modversions: Fix relative CRC byte order interpretation
+    - fs/open.c: allow opening only regular files during execve()
+    - ocfs2: fix inode bh swapping mixup in ocfs2_reflink_inodes_lock
+    - scsi: sd: Fix a race between closing an sd device and sd I/O
+    - scsi: sd: Quiesce warning if device does not report optimal I/O size
+    - scsi: zfcp: fix rport unblock if deleted SCSI devices on Scsi_Host
+    - scsi: zfcp: fix scsi_eh host reset with port_forced ERP for non-NPIV FCP
+      devices
+    - drm/rockchip: vop: reset scale mode when win is disabled
+    - tty/serial: atmel: Add is_half_duplex helper
+    - tty/serial: atmel: RS485 HD w/DMA: enable RX after TX is stopped
+    - tty: mxs-auart: fix a potential NULL pointer dereference
+    - tty: atmel_serial: fix a potential NULL pointer dereference
+    - tty: serial: qcom_geni_serial: Initialize baud in qcom_geni_console_setup
+    - staging: comedi: ni_mio_common: Fix divide-by-zero for DIO cmdtest
+    - staging: olpc_dcon_xo_1: add missing 'const' qualifier
+    - staging: speakup_soft: Fix alternate speech with other synths
+    - staging: vt6655: Remove vif check from vnt_interrupt
+    - staging: vt6655: Fix interrupt race condition on device start up.
+    - staging: erofs: fix to handle error path of erofs_vmap()
+    - staging: erofs: fix error handling when failed to read compresssed data
+    - staging: erofs: keep corrupted fs from crashing kernel in erofs_readdir()
+    - serial: max310x: Fix to avoid potential NULL pointer dereference
+    - serial: mvebu-uart: Fix to avoid a potential NULL pointer dereference
+    - serial: sh-sci: Fix setting SCSCR_TIE while transferring data
+    - USB: serial: cp210x: add new device id
+    - USB: serial: ftdi_sio: add additional NovaTech products
+    - USB: serial: mos7720: fix mos_parport refcount imbalance on error path
+    - USB: serial: option: set driver_info for SIM5218 and compatibles
+    - USB: serial: option: add support for Quectel EM12
+    - USB: serial: option: add Olicard 600
+    - ACPI / CPPC: Fix guaranteed performance handling
+    - Disable kgdboc failed by echo space to /sys/module/kgdboc/parameters/kgdboc
+    - fs/proc/proc_sysctl.c: fix NULL pointer dereference in put_links
+    - drivers/block/zram/zram_drv.c: fix idle/writeback string compare
+    - blk-mq: fix sbitmap ws_active for shared tags
+    - cpufreq: intel_pstate: Also use CPPC nominal_perf for base_frequency
+    - cpufreq: scpi: Fix use after free
+    - drm/vgem: fix use-after-free when drm_gem_handle_create() fails
+    - drm/vkms: fix use-after-free when drm_gem_handle_create() fails
+    - drm/i915: Mark AML 0x87CA as ULX
+    - drm/i915/gvt: Fix MI_FLUSH_DW parsing with correct index check
+    - drm/i915/icl: Fix the TRANS_DDI_FUNC_CTL2 bitfield macro
+    - gpio: exar: add a check for the return value of ida_simple_get fails
+    - gpio: adnp: Fix testing wrong value in adnp_gpio_direction_input
+    - phy: sun4i-usb: Support set_mode to USB_HOST for non-OTG PHYs
+    - usb: mtu3: fix EXTCON dependency
+    - USB: gadget: f_hid: fix deadlock in f_hidg_write()
+    - usb: common: Consider only available nodes for dr_mode
+    - mm/memory.c: fix modifying of page protection by insert_pfn()
+    - usb: host: xhci-rcar: Add XHCI_TRUST_TX_LENGTH quirk
+    - xhci: Fix port resume done detection for SS ports with LPM enabled
+    - usb: xhci: dbc: Don't free all memory with spinlock held
+    - xhci: Don't let USB3 ports stuck in polling state prevent suspend
+    - usb: cdc-acm: fix race during wakeup blocking TX traffic
+    - usb: typec: tcpm: Try PD-2.0 if sink does not respond to 3.0 source-caps
+    - usb: typec: Fix unchecked return value
+    - mm/hotplug: fix offline undo_isolate_page_range()
+    - mm: add support for kmem caches in DMA32 zone
+    - iommu/io-pgtable-arm-v7s: request DMA32 memory, and improve debugging
+    - mm: mempolicy: make mbind() return -EIO when MPOL_MF_STRICT is specified
+    - mm/debug.c: fix __dump_page when mapping->host is not set
+    - mm/memory_hotplug.c: fix notification in offline error path
+    - mm/page_isolation.c: fix a wrong flag in set_migratetype_isolate()
+    - mm/migrate.c: add missing flush_dcache_page for non-mapped page migrate
+    - perf pmu: Fix parser error for uncore event alias
+    - perf intel-pt: Fix TSC slip
+    - objtool: Query pkg-config for libelf location
+    - powerpc/pseries/energy: Use OF accessor functions to read ibm,drc-indexes
+    - powerpc/64: Fix memcmp reading past the end of src/dest
+    - powerpc/pseries/mce: Fix misleading print for TLB mutlihit
+    - watchdog: Respect watchdog cpumask on CPU hotplug
+    - cpu/hotplug: Prevent crash when CPU bringup fails on CONFIG_HOTPLUG_CPU=n
+    - x86/smp: Enforce CONFIG_HOTPLUG_CPU when SMP=y
+    - KVM: Reject device ioctls from processes other than the VM's creator
+    - KVM: x86: Emulate MSR_IA32_ARCH_CAPABILITIES on AMD hosts
+    - KVM: x86: update %rip after emulating IO
+    - bpf: do not restore dst_reg when cur_state is freed
+    - mt76x02u: use usb_bulk_msg to upload firmware
+    - Linux 5.0.6
+
+  * RDMA/hns updates for disco (LP: #1822897)
+    - RDMA/hns: Fix the bug with updating rq head pointer when flush cqe
+    - RDMA/hns: Bugfix for the scene without receiver queue
+    - RDMA/hns: Add constraint on the setting of local ACK timeout
+    - RDMA/hns: Modify the pbl ba page size for hip08
+    - RDMA/hns: RDMA/hns: Assign rq head pointer when enable rq record db
+    - RDMA/hns: Add the process of AEQ overflow for hip08
+    - RDMA/hns: Add SCC context allocation support for hip08
+    - RDMA/hns: Add SCC context clr support for hip08
+    - RDMA/hns: Add timer allocation support for hip08
+    - RDMA/hns: Remove set but not used variable 'rst'
+    - RDMA/hns: Make some function static
+    - RDMA/hns: Fix the Oops during rmmod or insmod ko when reset occurs
+    - RDMA/hns: Fix the chip hanging caused by sending mailbox&CMQ during reset
+    - RDMA/hns: Fix the chip hanging caused by sending doorbell during reset
+    - RDMA/hns: Limit minimum ROCE CQ depth to 64
+    - RDMA/hns: Fix the state of rereg mr
+    - RDMA/hns: Set allocated memory to zero for wrid
+    - RDMA/hns: Delete useful prints for aeq subtype event
+    - RDMA/hns: Configure capacity of hns device
+    - RDMA/hns: Modify qp&cq&pd specification according to UM
+    - RDMA/hns: Bugfix for set hem of SCC
+    - RDMA/hns: Use GFP_ATOMIC in hns_roce_v2_modify_qp
+
+  * autopkgtests run too often, too much and don't skip enough (LP: #1823056)
+    - Set +x on rebuild testcase.
+    - Skip rebuild test, for regression-suite deps.
+    - Make ubuntu-regression-suite skippable on unbootable kernels.
+    - make rebuild use skippable error codes when skipping.
+    - Only run regression-suite, if requested to.
+
+  * touchpad not working on lenovo yoga 530 (LP: #1787775)
+    - Revert "UBUNTU: SAUCE: i2c:amd Depends on ACPI"
+    - Revert "UBUNTU: SAUCE: i2c:amd move out pointer in union i2c_event_base"
+    - i2c: add extra check to safe DMA buffer helper
+    - i2c: Add drivers for the AMD PCIe MP2 I2C controller
+    - [Config] Update config for AMD MP2 I2C driver
+
+  * Detect SMP PHY control command errors (LP: #1822680)
+    - scsi: libsas: Check SMP PHY control function result
+
+  * disable a.out support (LP: #1818552)
+    - [Config] Disable a.out support
+    - [Config] remove binfmt_aout from abi for i386 lowlatency
+
+  * bionic: fork out linux-snapdragon into its own topic kernel (LP: #1820868)
+    - [Packaging] remove snapdragon flavour support
+    - Revert "UBUNTU: SAUCE: (snapdragon) drm/msm/adv7511: wrap hacks under
+      CONFIG_ADV7511_SNAPDRAGON_HACKS #ifdefs"
+    - Revert "UBUNTU: SAUCE: (snapdragon) media: ov5645: skip address change if dt
+      addr == default addr"
+    - Revert "UBUNTU: SAUCE: (snapdragon) DT: leds: Add Qualcomm Light Pulse
+      Generator binding"
+    - Revert "UBUNTU: SAUCE: (snapdragon) MAINTAINERS: Add Qualcomm Camera Control
+      Interface driver"
+    - Revert "UBUNTU: SAUCE: (snapdragon) dt-bindings: media: Binding document for
+      Qualcomm Camera Control Interface driver"
+    - Revert "UBUNTU: SAUCE: (snapdragon) leds: Add driver for Qualcomm LPG"
+    - Revert "UBUNTU: SAUCE: (snapdragon) HACK: drm/msm/adv7511: Don't rely on
+      interrupts for EDID parsing"
+    - Revert "UBUNTU: SAUCE: (snapdragon) drm/bridge/adv7511: Delay clearing of
+      HPD interrupt status"
+    - Revert "UBUNTU: SAUCE: (snapdragon) media: ov5645: Fix I2C address"
+    - Revert "UBUNTU: SAUCE: (snapdragon) i2c-qcom-cci: Fix I2C address bug"
+    - Revert "UBUNTU: SAUCE: (snapdragon) i2c-qcom-cci: Fix run queue completion
+      timeout"
+    - Revert "UBUNTU: SAUCE: (snapdragon) camss: Do not register if no cameras are
+      present"
+    - Revert "UBUNTU: SAUCE: (snapdragon) i2c: Add Qualcomm Camera Control
+      Interface driver"
+    - Revert "UBUNTU: SAUCE: (snapdragon) ov5645: I2C address change"
+    - Revert "UBUNTU: SAUCE: (snapdragon) regulator: smd: Allow
+      REGULATOR_QCOM_SMD_RPM=m"
+    - Revert "UBUNTU: SAUCE: (snapdragon) cpufreq: Add apq8016 to cpufreq-dt-
+      platdev blacklist"
+    - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: Add a helper to get an opp
+      regulator for device"
+    - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: HACK: Allow to set regulator
+      without opp_list"
+    - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: Drop RCU usage in
+      dev_pm_opp_adjust_voltage()"
+    - Revert "UBUNTU: SAUCE: (snapdragon) PM / OPP: Support adjusting OPP voltages
+      at runtime"
+    - Revert "UBUNTU: SAUCE: (snapdragon) regulator: smd: Add floor and corner
+      operations"
+    - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: cpr: Register with cpufreq-
+      dt"
+    - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: cpr: fix with new
+      reg_sequence structures"
+    - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: cpr: Use raw mem access for
+      qfprom"
+    - Revert "UBUNTU: SAUCE: (snapdragon) power: avs: Add support for CPR (Core
+      Power Reduction)"
+    - Revert "UBUNTU: SAUCE: (snapdragon) HACK: drm/msm/iommu: Remove runtime_put
+      calls in map/unmap"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable LEDS_QCOM_LPG"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable 'BBR' TCP
+      congestion algorithm"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable 'fq' and
+      'fq_codel' qdiscs"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable
+      'schedutil' CPUfreq governor"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: set USB_CONFIG_F_FS in
+      distro.config"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable
+      CONFIG_USB_CONFIGFS_F_FS by default"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: add freq stat to sysfs"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: Enable camera drivers"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: disable ANALOG_TV and
+      DIGITAL_TV"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: add more USB net
+      drivers"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: enable BT_QCOMSMD"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable
+      CFG80211_DEFAULT_PS by default"
+    - Revert "UBUNTU: SAUCE: (snapdragon) Force the SMD regulator driver to be
+      compiled-in"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs: enable dm_mod and
+      dm_crypt"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: Enable a53/apcs and
+      avs"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: enable QCOM Venus"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: distro.config: enable debug
+      friendly USB network adpater"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: configs: enable WCN36xx"
+    - Revert "UBUNTU: SAUCE: (snapdragon) kernel: configs; add distro.config"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable QCOM audio
+      drivers for APQ8016 and DB410c"
+    - Revert "UBUNTU: SAUCE: (snapdragon) arm64: defconfig: enable REMOTEPROC"
+    - [Config] fix abi for remove i2c-qcom-cci module
+    - [Config] update annotations
+    - [Config] update configs following snapdragon removal
+
+  * Disco update: v5.0.5 upstream stable release (LP: #1822671)
+    - Revert "ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec"
+    - ALSA: hda - add Lenovo IdeaCentre B550 to the power_save_blacklist
+    - ALSA: firewire-motu: use 'version' field of unit directory to identify model
+    - mmc: pxamci: fix enum type confusion
+    - mmc: alcor: fix DMA reads
+    - mmc: mxcmmc: "Revert mmc: mxcmmc: handle highmem pages"
+    - mmc: renesas_sdhi: limit block count to 16 bit for old revisions
+    - drm/amdgpu: fix invalid use of change_bit
+    - drm/vmwgfx: Don't double-free the mode stored in par->set_mode
+    - drm/vmwgfx: Return 0 when gmrid::get_node runs out of ID's
+    - iommu/amd: fix sg->dma_address for sg->offset bigger than PAGE_SIZE
+    - iommu/iova: Fix tracking of recently failed iova address
+    - libceph: wait for latest osdmap in ceph_monc_blacklist_add()
+    - udf: Fix crash on IO error during truncate
+    - mips: loongson64: lemote-2f: Add IRQF_NO_SUSPEND to "cascade" irqaction.
+    - MIPS: Ensure ELF appended dtb is relocated
+    - MIPS: Fix kernel crash for R6 in jump label branch function
+    - powerpc/vdso64: Fix CLOCK_MONOTONIC inconsistencies across Y2038
+    - powerpc/security: Fix spectre_v2 reporting
+    - net/mlx5: Fix DCT creation bad flow
+    - scsi: core: Avoid that a kernel warning appears during system resume
+    - scsi: qla2xxx: Fix FC-AL connection target discovery
+    - scsi: ibmvscsi: Protect ibmvscsi_head from concurrent modificaiton
+    - scsi: ibmvscsi: Fix empty event pool access during host removal
+    - futex: Ensure that futex address is aligned in handle_futex_death()
+    - perf probe: Fix getting the kernel map
+    - objtool: Move objtool_file struct off the stack
+    - irqchip/gic-v3-its: Fix comparison logic in lpi_range_cmp
+    - clocksource/drivers/riscv: Fix clocksource mask
+    - ALSA: ac97: Fix of-node refcount unbalance
+    - ext4: fix NULL pointer dereference while journal is aborted
+    - ext4: fix data corruption caused by unaligned direct AIO
+    - ext4: brelse all indirect buffer in ext4_ind_remove_space()
+    - media: v4l2-ctrls.c/uvc: zero v4l2_event
+    - Bluetooth: hci_uart: Check if socket buffer is ERR_PTR in h4_recv_buf()
+    - Bluetooth: Fix decrementing reference count twice in releasing socket
+    - Bluetooth: hci_ldisc: Initialize hci_dev before open()
+    - Bluetooth: hci_ldisc: Postpone HCI_UART_PROTO_READY bit set in
+      hci_uart_set_proto()
+    - drm/vkms: Fix flush_work() without INIT_WORK().
+    - RDMA/cma: Rollback source IP address if failing to acquire device
+    - f2fs: fix to avoid deadlock of atomic file operations
+    - aio: simplify - and fix - fget/fput for io_submit()
+    - netfilter: ebtables: remove BUGPRINT messages
+    - loop: access lo_backing_file only when the loop device is Lo_bound
+    - x86/unwind: Handle NULL pointer calls better in frame unwinder
+    - x86/unwind: Add hardcoded ORC entry for NULL
+    - locking/lockdep: Add debug_locks check in __lock_downgrade()
+    - ALSA: hda - Record the current power state before suspend/resume calls
+    - ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec
+    - Linux 5.0.5
+
+  * hisi_sas updates for disco (LP: #1822385)
+    - scsi: hisi_sas: send primitive NOTIFY to SSP situation only
+    - scsi: hisi_sas: shutdown axi bus to avoid exception CQ returned
+    - scsi: hisi_sas: remove the check of sas_dev status in
+      hisi_sas_I_T_nexus_reset()
+    - scsi: hisi_sas: Remove unused parameter of function hisi_sas_alloc()
+    - scsi: hisi_sas: Reject setting programmed minimum linkrate > 1.5G
+    - scsi: hisi_sas: Fix losing directly attached disk when hot-plug
+    - scsi: hisi_sas: Correct memory allocation size for DQ debugfs
+    - scsi: hisi_sas: Some misc tidy-up
+    - scsi: hisi_sas: Fix to only call scsi_get_prot_op() for non-NULL scsi_cmnd
+    - scsi: hisi_sas: Add missing seq_printf() call in hisi_sas_show_row_32()
+    - scsi: hisi_sas: Add support for DIX feature for v3 hw
+    - scsi: hisi_sas: Add manual trigger for debugfs dump
+    - scsi: hisi_sas: change queue depth from 512 to 4096
+    - scsi: hisi_sas: Issue internal abort on all relevant queues
+    - scsi: hisi_sas: Use pci_irq_get_affinity() for v3 hw as experimental
+    - scsi: hisi_sas: Do some more tidy-up
+    - scsi: hisi_sas: Change return variable type in phy_up_v3_hw()
+    - scsi: hisi_sas: Fix a timeout race of driver internal and SMP IO
+    - scsi: hisi_sas: print PHY RX errors count for later revision of v3 hw
+    - scsi: hisi_sas: Set PHY linkrate when disconnected
+    - scsi: hisi_sas: Send HARD RESET to clear the previous affiliation of STP
+      target port
+    - scsi: hisi_sas: Change SERDES_CFG init value to increase reliability of
+      HiLink
+    - scsi: hisi_sas: Add softreset in hisi_sas_I_T_nexus_reset()
+
+  * [Patch][Raven 2] kernel 5.0.0 cannot boot because of psp response
+    (LP: #1822267)
+    - drm/amdgpu/psp: Fix can't detect psp INVOKE command failed
+    - drm/amdgpu/psp: ignore psp response status
+
+  * 3b080b2564287be91605bfd1d5ee985696e61d3c in ubuntu_btrfs_kernel_fixes
+    triggers system hang on i386 (LP: #1812845)
+    - btrfs: raid56: properly unmap parity page in finish_parity_scrub()
+
+  * enable CONFIG_DRM_BOCHS (LP: #1795857)
+    - [Config] Reenable DRM_BOCHS as module
+
+  * [Dell Precision 7530/5530 with Nvidia Quadro P1000] Live USB freezes or
+    cannot complete install when nouveau driver is loaded (crashing in GP100
+    code) (LP: #1822026)
+    - SAUCE: drm/nouveau: Disable nouveau driver by default
+
+  * Need to add Intel CML related pci-id's (LP: #1821863)
+    - drm/i915/cml: Add CML PCI IDS
+    - drm/i915/cml: Introduce Comet Lake PCH
+
+  * ARM: Add support for the SDEI interface (LP: #1822005)
+    - ACPI / APEI: Don't wait to serialise with oops messages when panic()ing
+    - ACPI / APEI: Remove silent flag from ghes_read_estatus()
+    - ACPI / APEI: Switch estatus pool to use vmalloc memory
+    - ACPI / APEI: Make hest.c manage the estatus memory pool
+    - ACPI / APEI: Make estatus pool allocation a static size
+    - ACPI / APEI: Don't store CPER records physical address in struct ghes
+    - ACPI / APEI: Remove spurious GHES_TO_CLEAR check
+    - ACPI / APEI: Don't update struct ghes' flags in read/clear estatus
+    - ACPI / APEI: Generalise the estatus queue's notify code
+    - ACPI / APEI: Don't allow ghes_ack_error() to mask earlier errors
+    - ACPI / APEI: Move NOTIFY_SEA between the estatus-queue and NOTIFY_NMI
+    - ACPI / APEI: Switch NOTIFY_SEA to use the estatus queue
+    - KVM: arm/arm64: Add kvm_ras.h to collect kvm specific RAS plumbing
+    - arm64: KVM/mm: Move SEA handling behind a single 'claim' interface
+    - ACPI / APEI: Move locking to the notification helper
+    - ACPI / APEI: Let the notification helper specify the fixmap slot
+    - ACPI / APEI: Pass ghes and estatus separately to avoid a later copy
+    - ACPI / APEI: Make GHES estatus header validation more user friendly
+    - ACPI / APEI: Split ghes_read_estatus() to allow a peek at the CPER length
+    - ACPI / APEI: Only use queued estatus entry during in_nmi_queue_one_entry()
+    - ACPI / APEI: Use separate fixmap pages for arm64 NMI-like notifications
+    - firmware: arm_sdei: Add ACPI GHES registration helper
+    - ACPI / APEI: Add support for the SDEI GHES Notification type
+
+  * CVE-2019-9857
+    - inotify: Fix fsnotify_mark refcount leak in inotify_update_existing_watch()
+
+  * scsi: libsas: Support SATA PHY connection rate unmatch fixing during
+    discovery (LP: #1821408)
+    - scsi: libsas: Support SATA PHY connection rate unmatch fixing during
+      discovery
+
+  * Qualcomm Atheros QCA9377 wireless does not work (LP: #1818204)
+    - platform/x86: ideapad-laptop: Add Ideapad 530S-14ARR to no_hw_rfkill list
+
+  * Lenovo ideapad 330-15ICH Wifi rfkill hard blocked (LP: #1811815)
+    - platform/x86: ideapad: Add ideapad 330-15ICH to no_hw_rfkill
+
+  * hid-sensor-hub spamming dmesg in 4.20 (LP: #1818547)
+    - HID: Increase maximum report size allowed by hid_field_extract()
+
+  * [disco] [5.0.0-7.8] can't mount guest cifs share (LP: #1821053)
+    - cifs: allow guest mounts to work for smb3.11
+    - SMB3: Fix SMB3.1.1 guest mounts to Samba
+
+  * Add HiSilicon SoC quirk for cpufreq (LP: #1821620)
+    - ACPI / CPPC: Add a helper to get desired performance
+    - cpufreq / cppc: Work around for Hisilicon CPPC cpufreq
+
+  * Disco update: v5.0.4 upstream stable release (LP: #1821607)
+    - 9p: use inode->i_lock to protect i_size_write() under 32-bit
+    - 9p/net: fix memory leak in p9_client_create
+    - ASoC: fsl_esai: fix register setting issue in RIGHT_J mode
+    - ASoC: codecs: pcm186x: fix wrong usage of DECLARE_TLV_DB_SCALE()
+    - ASoC: codecs: pcm186x: Fix energysense SLEEP bit
+    - iio: adc: exynos-adc: Fix NULL pointer exception on unbind
+    - iio: adc: exynos-adc: Use proper number of channels for Exynos4x12
+    - mei: hbm: clean the feature flags on link reset
+    - mei: bus: move hw module get/put to probe/release
+    - stm class: Prevent division by zero
+    - stm class: Fix an endless loop in channel allocation
+    - crypto: caam - fix hash context DMA unmap size
+    - crypto: ccree - fix missing break in switch statement
+    - crypto: caam - fixed handling of sg list
+    - crypto: caam - fix DMA mapping of stack memory
+    - crypto: ccree - fix free of unallocated mlli buffer
+    - crypto: ccree - unmap buffer before copying IV
+    - crypto: ccree - don't copy zero size ciphertext
+    - crypto: cfb - add missing 'chunksize' property
+    - crypto: cfb - remove bogus memcpy() with src == dest
+    - crypto: ofb - fix handling partial blocks and make thread-safe
+    - crypto: ahash - fix another early termination in hash walk
+    - crypto: rockchip - fix scatterlist nents error
+    - crypto: rockchip - update new iv to device in multiple operations
+    - dax: Flush partial PMDs correctly
+    - nfit: Fix nfit_intel_shutdown_status() command submission
+    - nfit: acpi_nfit_ctl(): Check out_obj->type in the right place
+    - acpi/nfit: Fix bus command validation
+    - nfit/ars: Attempt a short-ARS whenever the ARS state is idle at boot
+    - nfit/ars: Attempt short-ARS even in the no_init_ars case
+    - libnvdimm/label: Clear 'updating' flag after label-set update
+    - libnvdimm, pfn: Fix over-trim in trim_pfn_device()
+    - libnvdimm/pmem: Honor force_raw for legacy pmem regions
+    - libnvdimm: Fix altmap reservation size calculation
+    - fix cgroup_do_mount() handling of failure exits
+    - crypto: aead - set CRYPTO_TFM_NEED_KEY if ->setkey() fails
+    - crypto: aegis - fix handling chunked inputs
+    - crypto: arm/crct10dif - revert to C code for short inputs
+    - crypto: arm64/aes-neonbs - fix returning final keystream block
+    - crypto: arm64/crct10dif - revert to C code for short inputs
+    - crypto: hash - set CRYPTO_TFM_NEED_KEY if ->setkey() fails
+    - crypto: morus - fix handling chunked inputs
+    - crypto: pcbc - remove bogus memcpy()s with src == dest
+    - crypto: skcipher - set CRYPTO_TFM_NEED_KEY if ->setkey() fails
+    - crypto: testmgr - skip crc32c context test for ahash algorithms
+    - crypto: x86/aegis - fix handling chunked inputs and MAY_SLEEP
+    - crypto: x86/aesni-gcm - fix crash on empty plaintext
+    - crypto: x86/morus - fix handling chunked inputs and MAY_SLEEP
+    - crypto: arm64/aes-ccm - fix logical bug in AAD MAC handling
+    - crypto: arm64/aes-ccm - fix bugs in non-NEON fallback routine
+    - CIFS: Fix leaking locked VFS cache pages in writeback retry
+    - CIFS: Do not reset lease state to NONE on lease break
+    - CIFS: Do not skip SMB2 message IDs on send failures
+    - CIFS: Fix read after write for files with read caching
+    - smb3: make default i/o size for smb3 mounts larger
+    - tracing: Use strncpy instead of memcpy for string keys in hist triggers
+    - tracing: Do not free iter->trace in fail path of tracing_open_pipe()
+    - tracing/perf: Use strndup_user() instead of buggy open-coded version
+    - vmw_balloon: release lock on error in vmballoon_reset()
+    - xen: fix dom0 boot on huge systems
+    - ACPI / device_sysfs: Avoid OF modalias creation for removed device
+    - mmc: sdhci-esdhc-imx: fix HS400 timing issue
+    - mmc: renesas_sdhi: Fix card initialization failure in high speed mode
+    - mmc:fix a bug when max_discard is 0
+    - spi: ti-qspi: Fix mmap read when more than one CS in use
+    - spi: pxa2xx: Setup maximum supported DMA transfer length
+    - spi: omap2-mcspi: Fix DMA and FIFO event trigger size mismatch
+    - spi: spi-gpio: fix SPI_CS_HIGH capability
+    - regulator: s2mps11: Fix steps for buck7, buck8 and LDO35
+    - regulator: max77620: Initialize values for DT properties
+    - regulator: s2mpa01: Fix step values for some LDOs
+    - mt76: fix corrupted software generated tx CCMP PN
+    - clocksource/drivers/exynos_mct: Move one-shot check from tick clear to ISR
+    - clocksource/drivers/exynos_mct: Clear timer interrupt when shutdown
+    - clocksource/drivers/arch_timer: Workaround for Allwinner A64 timer
+      instability
+    - s390: vfio_ap: link the vfio_ap devices to the vfio_ap bus subsystem
+    - s390/setup: fix early warning messages
+    - s390/virtio: handle find on invalid queue gracefully
+    - scsi: virtio_scsi: don't send sc payload with tmfs
+    - scsi: aacraid: Fix performance issue on logical drives
+    - scsi: sd: Optimal I/O size should be a multiple of physical block size
+    - scsi: target/iscsi: Avoid iscsit_release_commands_from_conn() deadlock
+    - scsi: qla2xxx: Fix LUN discovery if loop id is not assigned yet by firmware
+    - scsi: qla2xxx: Avoid PCI IRQ affinity mapping when multiqueue is not
+      supported
+    - scsi: qla2xxx: Use complete switch scan for RSCN events
+    - fs/devpts: always delete dcache dentry-s in dput()
+    - splice: don't merge into linked buffers
+    - ovl: During copy up, first copy up data and then xattrs
+    - ovl: Do not lose security.capability xattr over metadata file copy-up
+    - m68k: Add -ffreestanding to CFLAGS
+    - Btrfs: setup a nofs context for memory allocation at btrfs_create_tree()
+    - Btrfs: setup a nofs context for memory allocation at __btrfs_set_acl
+    - btrfs: scrub: fix circular locking dependency warning
+    - btrfs: drop the lock on error in btrfs_dev_replace_cancel
+    - btrfs: ensure that a DUP or RAID1 block group has exactly two stripes
+    - btrfs: init csum_list before possible free
+    - Btrfs: fix corruption reading shared and compressed extents after hole
+      punching
+    - Btrfs: fix deadlock between clone/dedupe and rename
+    - soc: qcom: rpmh: Avoid accessing freed memory from batch API
+    - libertas_tf: don't set URB_ZERO_PACKET on IN USB transfer
+    - irqchip/gic-v3-its: Avoid parsing _indirect_ twice for Device table
+    - irqchip/brcmstb-l2: Use _irqsave locking variants in non-interrupt code
+    - x86/kprobes: Prohibit probing on optprobe template code
+    - cpufreq: kryo: Release OPP tables on module removal
+    - cpufreq: tegra124: add missing of_node_put()
+    - cpufreq: pxa2xx: remove incorrect __init annotation
+    - ext4: fix check of inode in swap_inode_boot_loader
+    - ext4: cleanup pagecache before swap i_data
+    - mm: hwpoison: fix thp split handing in soft_offline_in_use_page()
+    - mm/vmalloc: fix size check for remap_vmalloc_range_partial()
+    - mm/memory.c: do_fault: avoid usage of stale vm_area_struct
+    - kernel/sysctl.c: add missing range check in do_proc_dointvec_minmax_conv
+    - nvmem: core: don't check the return value of notifier chain call
+    - device property: Fix the length used in PROPERTY_ENTRY_STRING()
+    - intel_th: Don't reference unassigned outputs
+    - parport_pc: fix find_superio io compare code, should use equal test.
+    - i2c: tegra: fix maximum transfer size
+    - i2c: tegra: update maximum transfer size
+    - media: i2c: ov5640: Fix post-reset delay
+    - gpio: pca953x: Fix dereference of irq data in shutdown
+    - ext4: update quota information while swapping boot loader inode
+    - ext4: add mask of ext4 flags to swap
+    - ext4: fix crash during online resizing
+    - dma: Introduce dma_max_mapping_size()
+    - swiotlb: Introduce swiotlb_max_mapping_size()
+    - swiotlb: Add is_swiotlb_active() function
+    - PCI/ASPM: Use LTR if already enabled by platform
+    - PCI/DPC: Fix print AER status in DPC event handling
+    - PCI: qcom: Don't deassert reset GPIO during probe
+    - PCI: dwc: skip MSI init if MSIs have been explicitly disabled
+    - PCI: pci-bridge-emul: Create per-bridge copy of register behavior
+    - PCI: pci-bridge-emul: Extend pci_bridge_emul_init() with flags
+    - IB/hfi1: Close race condition on user context disable and close
+    - IB/rdmavt: Fix loopback send with invalidate ordering
+    - IB/rdmavt: Fix concurrency panics in QP post_send and modify to error
+    - cxl: Wrap iterations over afu slices inside 'afu_list_lock'
+    - ext2: Fix underflow in ext2_max_size()
+    - clk: uniphier: Fix update register for CPU-gear
+    - clk: clk-twl6040: Fix imprecise external abort for pdmclk
+    - clk: samsung: exynos5: Fix possible NULL pointer exception on
+      platform_device_alloc() failure
+    - clk: samsung: exynos5: Fix kfree() of const memory on setting
+      driver_override
+    - clk: ingenic: Fix round_rate misbehaving with non-integer dividers
+    - clk: ingenic: Fix doc of ingenic_cgu_div_info
+    - usb: chipidea: tegra: Fix missed ci_hdrc_remove_device()
+    - usb: typec: tps6598x: handle block writes separately with plain-I2C adapters
+    - dmaengine: usb-dmac: Make DMAC system sleep callbacks explicit
+    - serial: uartps: Fix stuck ISR if RX disabled with non-empty FIFO
+    - serial: 8250_of: assume reg-shift of 2 for mrvl,mmp-uart
+    - serial: 8250_pci: Fix number of ports for ACCES serial cards
+    - serial: 8250_pci: Have ACCES cards that use the four port Pericom PI7C9X7954
+      chip use the pci_pericom_setup()
+    - jbd2: clear dirty flag when revoking a buffer from an older transaction
+    - jbd2: fix compile warning when using JBUFFER_TRACE
+    - selinux: add the missing walk_size + len check in selinux_sctp_bind_connect
+    - security/selinux: fix SECURITY_LSM_NATIVE_LABELS on reused superblock
+    - powerpc/32: Clear on-stack exception marker upon exception return
+    - powerpc/wii: properly disable use of BATs when requested.
+    - powerpc/powernv: Make opal log only readable by root
+    - powerpc/83xx: Also save/restore SPRG4-7 during suspend
+    - powerpc/kvm: Save and restore host AMR/IAMR/UAMOR
+    - powerpc/powernv: Don't reprogram SLW image on every KVM guest entry/exit
+    - powerpc/64s/hash: Fix assert_slb_presence() use of the slbfee. instruction
+    - powerpc: Fix 32-bit KVM-PR lockup and host crash with MacOS guest
+    - powerpc/ptrace: Simplify vr_get/set() to avoid GCC warning
+    - powerpc/hugetlb: Don't do runtime allocation of 16G pages in LPAR
+      configuration
+    - powerpc/smp: Fix NMI IPI timeout
+    - powerpc/smp: Fix NMI IPI xmon timeout
+    - powerpc/traps: fix recoverability of machine check handling on book3s/32
+    - powerpc/traps: Fix the message printed when stack overflows
+    - ARM: s3c24xx: Fix boolean expressions in osiris_dvs_notify
+    - arm64: Fix HCR.TGE status for NMI contexts
+    - arm64: debug: Don't propagate UNKNOWN FAR into si_code for debug signals
+    - arm64: debug: Ensure debug handlers check triggering exception level
+    - arm64: KVM: Fix architecturally invalid reset value for FPEXC32_EL2
+    - Revert "KVM/MMU: Flush tlb directly in the kvm_zap_gfn_range()"
+    - ipmi_si: Fix crash when using hard-coded device
+    - ipmi_si: fix use-after-free of resource->name
+    - dm: fix to_sector() for 32bit
+    - dm integrity: limit the rate of error messages
+    - media: cx25840: mark pad sig_types to fix cx231xx init
+    - mfd: sm501: Fix potential NULL pointer dereference
+    - cpcap-charger: generate events for userspace
+    - cpuidle: governor: Add new governors to cpuidle_governors again
+    - NFS: Fix I/O request leakages
+    - NFS: Fix an I/O request leakage in nfs_do_recoalesce
+    - NFS: Don't recoalesce on error in nfs_pageio_complete_mirror()
+    - nfsd: fix performance-limiting session calculation
+    - nfsd: fix memory corruption caused by readdir
+    - nfsd: fix wrong check in write_v4_end_grace()
+    - NFSv4.1: Reinitialise sequence results before retransmitting a request
+    - svcrpc: fix UDP on servers with lots of threads
+    - PM / wakeup: Rework wakeup source timer cancellation
+    - PM / OPP: Update performance state when freq == old_freq
+    - bcache: treat stale && dirty keys as bad keys
+    - bcache: use (REQ_META|REQ_PRIO) to indicate bio for metadata
+    - stable-kernel-rules.rst: add link to networking patch queue
+    - vt: perform safe console erase in the right order
+    - x86/unwind/orc: Fix ORC unwind table alignment
+    - perf intel-pt: Fix CYC timestamp calculation after OVF
+    - perf tools: Fix split_kallsyms_for_kcore() for trampoline symbols
+    - perf auxtrace: Define auxtrace record alignment
+    - perf intel-pt: Fix overlap calculation for padding
+    - perf/x86/intel/uncore: Fix client IMC events return huge result
+    - perf intel-pt: Fix divide by zero when TSC is not available
+    - md: Fix failed allocation of md_register_thread
+    - x86/kvmclock: set offset for kvm unstable clock
+    - x86/ftrace: Fix warning and considate ftrace_jmp_replace() and
+      ftrace_call_replace()
+    - tpm/tpm_crb: Avoid unaligned reads in crb_recv()
+    - tpm: Unify the send callback behaviour
+    - rcu: Do RCU GP kthread self-wakeup from softirq and interrupt
+    - media: imx: prpencvf: Stop upstream before disabling IDMA channel
+    - media: lgdt330x: fix lock status reporting
+    - media: sun6i: Fix CSI regmap's max_register
+    - media: uvcvideo: Avoid NULL pointer dereference at the end of streaming
+    - media: vimc: Add vimc-streamer for stream control
+    - media: imx-csi: Input connections to CSI should be optional
+    - media: imx: csi: Disable CSI immediately after last EOF
+    - media: imx: csi: Stop upstream before disabling IDMA channel
+    - drm/fb-helper: generic: Fix drm_fbdev_client_restore()
+    - drm/radeon/evergreen_cs: fix missing break in switch statement
+    - drm/amd/powerplay: correct power reading on fiji
+    - drm/amd/display: don't call dm_pp_ function from an fpu block
+    - KVM: Call kvm_arch_memslots_updated() before updating memslots
+    - KVM: VMX: Compare only a single byte for VMCS' "launched" in vCPU-run
+    - KVM: VMX: Zero out *all* general purpose registers after VM-Exit
+    - KVM: x86/mmu: Detect MMIO generation wrap in any address space
+    - KVM: x86/mmu: Do not cache MMIO accesses while memslots are in flux
+    - KVM: nVMX: Sign extend displacements of VMX instr's mem operands
+    - KVM: nVMX: Apply addr size mask to effective address for VMX instructions
+    - KVM: nVMX: Ignore limit checks on VMX instructions using flat segments
+    - KVM: nVMX: Check a single byte for VMCS "launched" in nested early checks
+    - net: dsa: lantiq_gswip: fix use-after-free on failed probe
+    - net: dsa: lantiq_gswip: fix OF child-node lookups
+    - s390/setup: fix boot crash for machine without EDAT-1
+    - SUNRPC: Prevent thundering herd when the socket is not connected
+    - SUNRPC: Fix up RPC back channel transmission
+    - SUNRPC: Respect RPC call timeouts when retrying transmission
+    - Linux 5.0.4
+    - [Config] update configs for 5.0.4 stable update
+
+  * New Intel Wireless-AC 9260 [8086:2526] card not correctly probed in Ubuntu
+    system (LP: #1821271)
+    - iwlwifi: add new card for 9260 series
+
+  * [CONFIG] please enable highdpi font FONT_TER16x32 (LP: #1819881)
+    - [Config]: enable highdpi Terminus 16x32 font support
+
+  * [SRU][B/B-OEM/C/D] Fix AMD IOMMU NULL dereference (LP: #1820990)
+    - iommu/amd: Fix NULL dereference bug in match_hid_uid
+
+  * some codecs stop working after S3 (LP: #1820930)
+    - ALSA: hda - Enforces runtime_resume after S3 and S4 for each codec
+    - ALSA: hda - Don't trigger jackpoll_work in azx_resume
+
+  * tcm_loop.ko: move from modules-extra into main modules package
+    (LP: #1817786)
+    - [Packaging] move tcm_loop.lo to main linux-modules package
+
+  * C++ demangling support missing from perf (LP: #1396654)
+    - [Packaging] fix a mistype
+
+  * r8169 doesn't get woken up by ethernet cable plugging, no PME generated
+    (LP: #1817676)
+    - PCI: pciehp: Disable Data Link Layer State Changed event on suspend
+
+  * Disco update: v5.0.3 upstream stable release (LP: #1821074)
+    - connector: fix unsafe usage of ->real_parent
+    - fou, fou6: avoid uninit-value in gue_err() and gue6_err()
+    - gro_cells: make sure device is up in gro_cells_receive()
+    - ipv4/route: fail early when inet dev is missing
+    - l2tp: fix infoleak in l2tp_ip6_recvmsg()
+    - lan743x: Fix RX Kernel Panic
+    - lan743x: Fix TX Stall Issue
+    - net: hsr: fix memory leak in hsr_dev_finalize()
+    - net/hsr: fix possible crash in add_timer()
+    - net: sit: fix UBSAN Undefined behaviour in check_6rd
+    - net/x25: fix use-after-free in x25_device_event()
+    - net/x25: reset state in x25_connect()
+    - pptp: dst_release sk_dst_cache in pptp_sock_destruct
+    - ravb: Decrease TxFIFO depth of Q3 and Q2 to one
+    - route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race
+    - rxrpc: Fix client call queueing, waiting for channel
+    - sctp: remove sched init from sctp_stream_init
+    - tcp: do not report TCP_CM_INQ of 0 for closed connections
+    - tcp: Don't access TCP_SKB_CB before initializing it
+    - tcp: handle inet_csk_reqsk_queue_add() failures
+    - vxlan: Fix GRO cells race condition between receive and link delete
+    - vxlan: test dev->flags & IFF_UP before calling gro_cells_receive()
+    - net/mlx4_core: Fix reset flow when in command polling mode
+    - net/mlx4_core: Fix locking in SRIOV mode when switching between events and
+      polling
+    - net/mlx4_core: Fix qp mtt size calculation
+    - net: dsa: mv88e6xxx: Set correct interface mode for CPU/DSA ports
+    - vsock/virtio: fix kernel panic from virtio_transport_reset_no_sock
+    - net: sched: flower: insert new filter to idr after setting its mask
+    - f2fs: wait on atomic writes to count F2FS_CP_WB_DATA
+    - perf/x86: Fixup typo in stub functions
+    - ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against
+      Liquid Saffire 56
+    - ALSA: firewire-motu: fix construction of PCM frame for capture direction
+    - ALSA: hda: Extend i915 component bind timeout
+    - ALSA: hda - add more quirks for HP Z2 G4 and HP Z240
+    - ALSA: hda/realtek: Enable audio jacks of ASUS UX362FA with ALC294
+    - ALSA: hda/realtek - Reduce click noise on Dell Precision 5820 headphone
+    - ALSA: hda/realtek: Enable headset MIC of Acer TravelMate X514-51T with
+      ALC255
+    - perf/x86/intel: Fix memory corruption
+    - perf/x86/intel: Make dev_attr_allow_tsx_force_abort static
+    - It's wrong to add len to sector_nr in raid10 reshape twice
+    - drm: Block fb changes for async plane updates
+    - Linux 5.0.3
+
+  * Disco update: v5.0.2 upstream stable release (LP: #1820318)
+    - media: uvcvideo: Fix 'type' check leading to overflow
+    - Input: wacom_serial4 - add support for Wacom ArtPad II tablet
+    - Input: elan_i2c - add id for touchpad found in Lenovo s21e-20
+    - iscsi_ibft: Fix missing break in switch statement
+    - scsi: aacraid: Fix missing break in switch statement
+    - x86/PCI: Fixup RTIT_BAR of Intel Denverton Trace Hub
+    - arm64: dts: zcu100-revC: Give wifi some time after power-on
+    - arm64: dts: hikey: Give wifi some time after power-on
+    - arm64: dts: hikey: Revert "Enable HS200 mode on eMMC"
+    - ARM: dts: exynos: Fix pinctrl definition for eMMC RTSN line on Odroid X2/U3
+    - ARM: dts: exynos: Add minimal clkout parameters to Exynos3250 PMU
+    - ARM: dts: exynos: Fix max voltage for buck8 regulator on Odroid XU3/XU4
+    - drm: disable uncached DMA optimization for ARM and arm64
+    - media: Revert "media: rc: some events are dropped by userspace"
+    - Revert "PCI/PME: Implement runtime PM callbacks"
+    - bpf: Stop the psock parser before canceling its work
+    - gfs2: Fix missed wakeups in find_insert_glock
+    - staging: erofs: keep corrupted fs from crashing kernel in erofs_namei()
+    - staging: erofs: compressed_pages should not be accessed again after freed
+    - scripts/gdb: replace flags (MS_xyz -> SB_xyz)
+    - ath9k: Avoid OF no-EEPROM quirks without qca,no-eeprom
+    - perf/x86/intel: Make cpuc allocations consistent
+    - perf/x86/intel: Generalize dynamic constraint creation
+    - x86: Add TSX Force Abort CPUID/MSR
+    - perf/x86/intel: Implement support for TSX Force Abort
+    - Linux 5.0.2
+
+  * Linux security module stacking support
+    - LSM: Introduce LSM_FLAG_LEGACY_MAJOR
+    - LSM: Provide separate ordered initialization
+    - LSM: Plumb visibility into optional "enabled" state
+    - LSM: Lift LSM selection out of individual LSMs
+    - LSM: Build ordered list of LSMs to initialize
+    - LSM: Introduce CONFIG_LSM
+    - LSM: Introduce "lsm=" for boottime LSM selection
+    - LSM: Tie enabling logic to presence in ordered list
+    - LSM: Prepare for reorganizing "security=" logic
+    - LSM: Refactor "security=" in terms of enable/disable
+    - LSM: Separate idea of "major" LSM from "exclusive" LSM
+    - apparmor: Remove SECURITY_APPARMOR_BOOTPARAM_VALUE
+    - selinux: Remove SECURITY_SELINUX_BOOTPARAM_VALUE
+    - LSM: Add all exclusive LSMs to ordered initialization
+    - LSM: Split LSM preparation from initialization
+    - LoadPin: Initialize as ordered LSM
+    - Yama: Initialize as ordered LSM
+    - LSM: Introduce enum lsm_order
+    - capability: Initialize as LSM_ORDER_FIRST
+    - procfs: add smack subdir to attrs
+    - Smack: Abstract use of cred security blob
+    - SELinux: Abstract use of cred security blob
+    - SELinux: Remove cred security blob poisoning
+    - SELinux: Remove unused selinux_is_enabled
+    - AppArmor: Abstract use of cred security blob
+    - TOMOYO: Abstract use of cred security blob
+    - Infrastructure management of the cred security blob
+    - SELinux: Abstract use of file security blob
+    - Smack: Abstract use of file security blob
+    - LSM: Infrastructure management of the file security
+    - SELinux: Abstract use of inode security blob
+    - Smack: Abstract use of inode security blob
+    - LSM: Infrastructure management of the inode security
+    - LSM: Infrastructure management of the task security
+    - SELinux: Abstract use of ipc security blobs
+    - Smack: Abstract use of ipc security blobs
+    - LSM: Infrastructure management of the ipc security blob
+    - TOMOYO: Update LSM flags to no longer be exclusive
+    - LSM: generalize flag passing to security_capable
+    - LSM: Make lsm_early_cred() and lsm_early_task() local functions.
+    - LSM: Make some functions static
+    - apparmor: Adjust offset when accessing task blob.
+    - LSM: Ignore "security=" when "lsm=" is specified
+    - LSM: Update list of SECURITYFS users in Kconfig
+    - apparmor: delete the dentry in aafs_remove() to avoid a leak
+    - apparmor: fix double free when unpack of secmark rules fails
+    - SAUCE: LSM: Infrastructure management of the sock security
+    - SAUCE: LSM: Limit calls to certain module hooks
+    - SAUCE: LSM: Special handling for secctx lsm hooks
+    - SAUCE: LSM: Specify which LSM to display with /proc/self/attr/display
+    - SAUCE: Fix-up af_unix mediation for sock infrastructure management
+    - SAUCE: Revert "apparmor: Fix warning about unused function
+      apparmor_ipv6_postroute"
+    - SAUCE: Revert "apparmor: fix checkpatch error in Parse secmark policy"
+    - SAUCE: Revert "apparmor: add #ifdef checks for secmark filtering"
+    - SAUCE: Revert "apparmor: Allow filtering based on secmark policy"
+    - SAUCE: Revert "apparmor: Parse secmark policy"
+    - SAUCE: Revert "apparmor: Add a wildcard secid"
+    - SAUCE: Revert "apparmor: fix bad debug check in apparmor_secid_to_secctx()"
+    - SAUCE: Revert "apparmor: fixup secid map conversion to using IDR"
+    - SAUCE: Revert "apparmor: Use an IDR to allocate apparmor secids"
+    - SAUCE: Revert "apparmor: Fix memory leak of rule on error exit path"
+    - SAUCE: Revert "apparmor: modify audit rule support to support profile
+      stacks"
+    - SAUCE: Revert "apparmor: Add support for audit rule filtering"
+    - SAUCE: Revert "apparmor: add the ability to get a task's secid"
+    - SAUCE: Revert "apparmor: add support for mapping secids and using secctxes"
+    - SAUCE: apparmor: add proc subdir to attrs
+    - SAUCE: apparmor: add an apparmorfs entry to access current attrs
+    - SAUCE: apparmor: update flags to no longer be exclusive
+    - SAUCE: update configs and annotations for LSM stacking
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_EARLY_PRINTK_USB_XDBC=y
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - [Config] CONFIG_RANDOM_TRUST_CPU=y
+    - [Config] refresh annotations for recent config changes
+    - ubuntu: vbox -- update to 6.0.4-dfsg-7
+    - Revert "UBUNTU: SAUCE: i2c:amd I2C Driver based on PCI Interface for
+      upcoming platform"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 04 Apr 2019 14:49:59 -0500
+
+linux (5.0.0-8.9) disco; urgency=medium
+
+  * linux: 5.0.0-8.9 -proposed tracker (LP: #1819759)
+
+  * hisi_sas: add debugfs support (LP: #1819500)
+    - scsi: hisi_sas: Create root and device debugfs directories
+    - scsi: hisi_sas: Alloc debugfs snapshot buffer memory for all registers
+    - scsi: hisi_sas: Take debugfs snapshot for all regs
+    - scsi: hisi_sas: Debugfs global register create file and add file operations
+    - scsi: hisi_sas: Add debugfs for port registers
+    - scsi: hisi_sas: Add debugfs CQ file and add file operations
+    - scsi: hisi_sas: Add debugfs DQ file and add file operations
+    - scsi: hisi_sas: Add debugfs IOST file and add file operations
+    - scsi: hisi_sas: No need to check return value of debugfs_create functions
+    - scsi: hisi_sas: Fix type casting and missing static qualifier in debugfs
+      code
+    - scsi: hisi_sas: Add debugfs ITCT file and add file operations
+
+  * [disco] hns driver updates from 5.1 merge window (LP: #1819535)
+    - net: hns: Use struct_size() in devm_kzalloc()
+    - net: hns3: modify enet reinitialization interface
+    - net: hns3: remove unused member in struct hns3_enet_ring
+    - net: hns3: remove unnecessary hns3_adjust_tqps_num
+    - net: hns3: reuse reinitialization interface in the hns3_set_channels
+    - net: hns3: add interface hclge_tm_bp_setup
+    - net: hns3: modify parameter checks in the hns3_set_channels
+    - net: hns3: remove redundant codes in hclge_knic_setup
+    - net: hns3: fix user configuration loss for ethtool -L
+    - net: hns3: adjust the use of alloc_tqps and num_tqps
+    - net: hns3: fix wrong combined count returned by ethtool -l
+    - net: hns3: do reinitialization while ETS configuration changed
+    - net: hns3: add HNAE3_RESTORE_CLIENT interface in enet module
+    - net: hns3: add calling roce callback function when link status change
+    - net: hns3: add rx multicast packets statistic
+    - net: hns3: refactor the statistics updating for netdev
+    - net: hns3: fix rss configuration lost problem when setting channel
+    - net: hns3: fix for shaper not setting when TC num changes
+    - net: hns3: fix bug of ethtool_ops.get_channels for VF
+    - net: hns3: clear param in ring when free ring
+    - net: hns3: Change fw error code NOT_EXEC to NOT_SUPPORTED
+    - net: hns3: do not return GE PFC setting err when initializing
+    - net: hns3: add ETS TC weight setting in SSU module
+    - net: hns3: add statistics for PFC frames and MAC control frames
+    - net: hns3: fix PFC not setting problem for DCB module
+    - net: hns3: don't update packet statistics for packets dropped by hardware
+    - net: hns3: clear pci private data when unload hns3 driver
+    - net: hns3: add error handling in hclge_ieee_setets
+    - net: hns3: fix return value handle issue for hclge_set_loopback()
+    - net: hns3: fix broadcast promisc issue for revision 0x20
+    - net: hns3: After setting the loopback, add the status of getting MAC
+    - net: hns3: do reinitialization while mqprio configuration changed
+    - net: hns3: remove dcb_ops->map_update in hclge_dcb
+    - net: hns3: call hns3_nic_set_real_num_queue with netdev down
+    - net: hns3: add 8 BD limit for tx flow
+    - net: hns3: add initialization for nic state
+    - net: hns3: don't allow vf to enable promisc mode
+    - net: hns3: reuse the definition of l3 and l4 header info union
+    - net: hns3: fix VF dump register issue
+    - net: hns3: use the correct interface to stop|open port
+    - net: hns3: change hnae3_register_ae_dev() to int
+    - net: hns3: only support tc 0 for VF
+    - net: hns3: Fix NULL deref when unloading driver
+    - net: hns3: fix netif_napi_del() not do problem when unloading
+    - net: hns3: fix for rss result nonuniform
+    - net: hns3: fix improper error handling in the hclge_init_ae_dev()
+    - net: hns3: fix an issue for hclgevf_ae_get_hdev
+    - net: hns3: stop sending keep alive msg to PF when VF is resetting
+    - net: hns3: keep flow director state unchanged when reset
+    - net: hns3: Check for allocation failure
+    - net: hns3: fix a code style issue for hns3_update_new_int_gl()
+    - net: hns3: fix an issue for hns3_update_new_int_gl
+    - net: hns3: Modify parameter type from int to bool in set_gro_en
+    - net: hns3: code optimization for hclge_rx_buffer_calc
+    - net: hns3: add hclge_cmd_check_retval() to parse comman's return value
+    - net: hns3: move some set_bit statement into hclge_prepare_mac_addr
+    - net: hns3: fix a wrong checking in the hclge_tx_buffer_calc()
+    - net: hns3: fix the problem that the supported port is empty
+    - net: hns3: optimize the maximum TC macro
+    - net: hns3: don't allow user to change vlan filter state
+    - net: hns3: modify the upper limit judgment condition
+    - net: hns3: MAC table entry count function increases operation 0 value
+      protection measures
+    - net: hns3: make function hclge_set_all_vf_rst() static
+    - net: hns3: add pointer checking at the beginning of the exported functions.
+    - net: hns3: Check variable is valid before assigning it to another
+    - net: hns3: convert mac advertize and supported from u32 to link mode
+    - net: hns3: fix port info query issue for copper port
+    - net: hns3: modify print message of ssu common ecc errors
+    - net: hns3: some bugfix of ppu(rcb) ras errors
+    - net: hns3: enable 8~11th bit of mac common msi-x error
+    - net: hns3: fix 6th bit of ppp mpf abnormal errors
+    - net: hns3: Record VF unicast and multicast tables
+    - net: hns3: Record VF vlan tables
+    - net: hns3: uninitialize command queue while unloading PF driver
+    - net: hns3: clear command queue's registers when unloading VF driver
+    - net: hns3: add xps setting support for hns3 driver
+    - net: hns3: avoid mult + div op in critical data path
+    - net: hns3: limit some variable scope in critical data path
+    - net: hns3: remove some ops in struct hns3_nic_ops
+    - net: hns3: add unlikely for error handling in data path
+    - net: hns3: replace hnae3_set_bit and hnae3_set_field in data path
+    - net: hns3: remove hnae3_get_bit in data path
+    - net: hns3: add support to config depth for tx|rx ring separately
+    - net: hns3: enable VF VLAN filter for each VF when initializing
+    - net: hns3: fix get VF RSS issue
+    - net: hns3: fix setting of the hns reset_type for rdma hw errors
+    - net: hns3: fix improper error handling for hns3_client_start
+    - net: hns: use struct_size() in devm_kzalloc()
+    - net: hns3: Fix a logical vs bitwise typo
+    - net: hns3: add dma_rmb() for rx description
+    - net: hns3: fix to stop multiple HNS reset due to the AER changes
+
+  * Build Nvidia drivers in conjunction with kernel (LP: #1764792)
+    - [Packaging] dkms-build -- support building against packages in PPAs
+    - [Packaging] dkms-build: do not redownload files on subsequent passes
+    - [Packaging] dkms-build -- elide partial Built-Using information
+    - [Packaging] dkms-build -- remove retpoline data from final binary packages
+    - [Packaging] dkms-build--nvidia* -- check gcc version against primary build
+    - [Packaging] dkms-build -- add support for unversioned overrides
+    - [Packaging] dkms-build--nvidia-* -- convert to generic -N form
+    - [Packaging] fix-filenames -- handle exact string removal
+    - [Packaging] dkms-build--nvidia-N -- remove GCC versions
+
+  * Disco update: v5.0.1 upstream stable release (LP: #1819515)
+    - cpufreq: Use struct kobj_attribute instead of struct global_attr
+    - staging: erofs: fix mis-acted TAIL merging behavior
+    - binder: create node flag to request sender's security context
+    - USB: serial: option: add Telit ME910 ECM composition
+    - USB: serial: cp210x: add ID for Ingenico 3070
+    - USB: serial: ftdi_sio: add ID for Hjelmslund Electronics USB485
+    - driver core: Postpone DMA tear-down until after devres release
+    - staging: erofs: fix fast symlink w/o xattr when fs xattr is on
+    - staging: erofs: fix memleak of inode's shared xattr array
+    - staging: erofs: fix race of initializing xattrs of a inode at the same time
+    - staging: erofs: fix illegal address access under memory pressure
+    - staging: comedi: ni_660x: fix missing break in switch statement
+    - staging: wilc1000: fix to set correct value for 'vif_num'
+    - staging: android: ion: fix sys heap pool's gfp_flags
+    - staging: android: ashmem: Don't call fallocate() with ashmem_mutex held.
+    - staging: android: ashmem: Avoid range_alloc() allocation with ashmem_mutex
+      held.
+    - ip6mr: Do not call __IP6_INC_STATS() from preemptible context
+    - net: dsa: mv88e6xxx: add call to mv88e6xxx_ports_cmode_init to probe for new
+      DSA framework
+    - net: dsa: mv88e6xxx: handle unknown duplex modes gracefully in
+      mv88e6xxx_port_set_duplex
+    - net: dsa: mv8e6xxx: fix number of internal PHYs for 88E6x90 family
+    - net: mscc: Enable all ports in QSGMII
+    - net: sched: put back q.qlen into a single location
+    - net-sysfs: Fix mem leak in netdev_register_kobject
+    - qmi_wwan: Add support for Quectel EG12/EM12
+    - sctp: call iov_iter_revert() after sending ABORT
+    - team: Free BPF filter when unregistering netdev
+    - tipc: fix RDM/DGRAM connect() regression
+    - x86/CPU/AMD: Set the CPB bit unconditionally on F17h
+    - x86/boot/compressed/64: Do not read legacy ROM on EFI system
+    - tracing: Fix event filters and triggers to handle negative numbers
+    - xhci: tegra: Prevent error pointer dereference
+    - usb: xhci: Fix for Enabling USB ROLE SWITCH QUIRK on
+      INTEL_SUNRISEPOINT_LP_XHCI
+    - applicom: Fix potential Spectre v1 vulnerabilities
+    - alpha: wire up io_pgetevents system call
+    - MIPS: irq: Allocate accurate order pages for irq stack
+    - aio: Fix locking in aio_poll()
+    - xtensa: fix get_wchan
+    - gnss: sirf: fix premature wakeup interrupt enable
+    - USB: serial: cp210x: fix GPIO in autosuspend
+    - Revert "selftests: firmware: add CONFIG_FW_LOADER_USER_HELPER_FALLBACK to
+      config"
+    - Revert "selftests: firmware: remove use of non-standard diff -Z option"
+    - selftests: firmware: fix verify_reqs() return value
+    - Bluetooth: btrtl: Restore old logic to assume firmware is already loaded
+    - Bluetooth: Fix locking in bt_accept_enqueue() for BH context
+    - Linux 5.0.1
+
+  * sky2 ethernet card doesn't work after returning from suspend
+    (LP: #1807259) // sky2 ethernet card link not up after suspend
+    (LP: #1809843) // Disco update: v5.0.1 upstream stable release
+    (LP: #1819515)
+    - sky2: Disable MSI on Dell Inspiron 1545 and Gateway P-79
+
+  * tls selftest failures/hangs on i386 (LP: #1813607)
+    - [Config] CONFIG_TLS=n for i386
+
+  * CVE-2019-8980
+    - exec: Fix mem leak in kernel_read_file
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: net: Use 'ipproto ipv6-icmp' to match ICMPv6 headers
+    - [Config] enable nvidia build
+    - [Config] update gcc version to 8.3
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: selftests: pmtu: disable accept_dad for tests"
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Tue, 12 Mar 2019 16:15:44 -0300
+
+linux (5.0.0-7.8) disco; urgency=medium
+
+  * linux: 5.0.0-7.8 -proposed tracker (LP: #1818519)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * unnecessary request_queue freeze (LP: #1815733)
+    - block: avoid setting nr_requests to current value
+    - block: avoid setting none scheduler if it's already none
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: net: Don't fail test_vxlan_under_vrf on xfail
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 04 Mar 2019 08:46:10 -0600
+
+linux (5.0.0-6.7) disco; urgency=medium
+
+  * linux: 5.0.0-6.7 -proposed tracker (LP: #1817585)
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+    - [Packaging] resync getabis
+
+  * installer does not support iSCSI iBFT (LP: #1817321)
+    - d-i: add iscsi_ibft to scsi-modules
+
+  * Silent "Unknown key" message when pressing keyboard backlight hotkey
+    (LP: #1817063)
+    - platform/x86: dell-wmi: Ignore new keyboard backlight change event
+
+  * Fix I219 doesn't get woken up after plugging ethernet cable (LP: #1817058)
+    - e1000e: Disable runtime PM on CNP+
+
+  * efi/arm/arm64: Allow SetVirtualAddressMap() to be omitted (LP: #1814982)
+    - efi/arm/arm64: Allow SetVirtualAddressMap() to be omitted
+
+  * CVE-2019-3460
+    - Bluetooth: Check L2CAP option sizes returned from l2cap_get_conf_opt
+
+  * CVE-2019-3459
+    - Bluetooth: Verify that l2cap_get_conf_opt provides large enough buffer
+
+  * kernel net tls selftest fails on 5.0 (LP: #1816716)
+    - SAUCE: Revert "selftests/tls: Add test for recv(PEEK) spanning across
+      multiple records"
+
+  * Please enable CONFIG_DMA_CMA=y on arm64 (LP: #1803206)
+    - [Config] annotations -- enforce CONFIG_DMA_CMA and update notes
+
+  * [19.04 FEAT] [LS1801] PCI Virtual function enablement (LP: #1814684)
+    - s390/pci: map IOV resources
+    - s390/pci: improve bar check
+
+  * glibc 2.28-0ubuntu1 ADT test failure with linux 5.0.0-1.2 (LP: #1813060)
+    - SAUCE: prevent a glibc test failure when looking for obsolete types on
+      headers
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Enforce CONFIG_ZCRYPT_MULTIDEVNODES in annotations
+    - SAUCE: selftests: pmtu: disable accept_dad for tests
+    - SAUCE: arm64: add kernel config option to lock down when in Secure Boot mode
+    - SAUCE: selftests: net: Make test for VXLAN underlay in non-default VRF an
+      expected failure
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 25 Feb 2019 09:37:36 -0600
+
+linux (5.0.0-5.6) disco; urgency=medium
+
+  * [ALSA] [PATCH] System76 darp5 and oryp5 fixups (LP: #1815831)
+    - ALSA: hda/realtek - Headset microphone and internal speaker support for
+      System76 oryp5
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Fix aufs menus in annotations file
+    - [Config] CONFIG_SAMPLE_TRACE_PRINTK=m
+    - [Config] Update annotations based on configs
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 18 Feb 2019 10:04:11 +0100
+
+linux (5.0.0-4.5) disco; urgency=medium
+
+  * linux-buildinfo: pull out ABI information into its own package
+    (LP: #1806380)
+    - [Packaging] autoreconstruct -- base tag is always primary mainline version
+
+  * [Packaging] Allow overlay of config annotations (LP: #1752072)
+    - [Packaging] config-check: Add an include directive
+
+  * Miscellaneous Ubuntu changes
+    - hio -- stub out BIOVEC_PHYS_MERGEABLE for 4.20+
+    - hio -- replace use of do_gettimeofday()
+    - hio -- part_round_stats() removed in 5.0
+    - hio -- device_add_disk() grew a 'groups' argument in 4.20
+    - enable hio build
+    - Revert "UBUNTU: [Packaging] autoreconstruct -- base tag is always primary
+      mainline version"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 12 Feb 2019 08:15:32 -0600
+
+linux (5.0.0-3.4) disco; urgency=medium
+
+  * CONFIG_TEST_BPF is disabled (LP: #1813955)
+    - [Config]: Reenable TEST_BPF
+
+  * Ignore "incomplete report" from Elan touchpanels (LP: #1813733)
+    - HID: i2c-hid: Ignore input report if there's no data present on Elan
+      touchpanels
+
+  * SecureBoot support for arm64 (LP: #1804481)
+    - Build signed kernels for arm64
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests: net: fix "from" match test in fib_rule_tests.sh
+    - [Config] CONFIG_PCMCIA=n for arm64 and s390x
+    - [Config] CONFIG_SERIAL_SC16IS7XX=n for s390x
+    - [Config] disable I2C TPM drivers for s390x
+    - [Config] CONFIG_RAPIDIO=n for s390x
+    - [Config] CONFIG_DMADEVICES=n for s390x
+    - [Config] disable gpio drivers for s390x
+    - [Config] CONFIG_SENSORS_OCC_P8_I2C=m for ppc64el
+    - [Config] disable I2C hardware drivers for s390x
+    - [Config] CONFIG_I3C=n for s390x
+    - [Config] CONFIG_SERIO=n for s390x
+    - [Config] disable misc drivers for s390x
+    - [Config] disable EEPROM drivers for s390x
+    - [Config] disable MFD drivers for s390x
+    - [Config] CONFIG_NVMEM=n for s390x
+    - [Config] CONFIG_MLXSW_I2C=n for s390x
+    - [Config] CONFIG_NET_VENDOR_MICROCHIP=n for s390x
+    - [Config] CONFIG_PPP=n for s390x
+    - [Config] CONFIG_PCCARD=n for s390x
+    - [Config] CONFIG_PCI_MESON=y
+    - [Config] CONFIG_SCSI_MYRB=n for s390x
+    - [Config] CONFIG_REGULATOR=n for s390x
+    - [Config] CONFIG_ZIIRAVE_WATCHDOG=n for s390x
+    - [Config] CONFIG_NCSI_OEM_CMD_GET_MAC=y
+    - [Config] update annotations following config review
+    - [Packaging] remove handoff check for uefi signing
+    - [Packaging] decompress gzipped efi images in signing tarball
+    - vbox-update: allow leading whitespace when fixing up KERN_DIR
+    - ubuntu: vbox -- update to 6.0.4-dfsg-3
+    - vbox: remove remount check in sf_read_super_aux()
+    - enable vbox build
+    - [Config] CONFIG_ANDROID_BINDER_DEVICES=""
+    - SAUCE: import aufs driver
+    - [Config]: Enable aufs
+    - [Config] relocate aufs annotations to menu
+    - [Config] remove unmatched configs from annotations
+    - [Config] fix up abi for removed modules
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) module: remove support for having IMA validate modules
+    - SAUCE: (efi-lockdown) Move EFI signature blob parser to shared location
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - [Config] (efi-lockdown) enable importing of efi certificates for module sig
+      verification
+
+  * Miscellaneous upstream changes
+    - binder: fix CONFIG_ANDROID_BINDER_DEVICES
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 05 Feb 2019 14:26:12 -0600
+
+linux (5.0.0-2.3) disco; urgency=medium
+
+  * kernel oops in bcache module (LP: #1793901)
+    - SAUCE: bcache: never writeback a discard operation
+
+  * Enable sound card power saving by default (LP: #1804265)
+    - [Config] CONFIG_SND_HDA_POWER_SAVE_DEFAULT=1
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: selftests: disable some failing networking tests"
+    - SAUCE: ashmem: turn into module
+    - SAUCE: binder: turn into module
+    - SAUCE: binder: give binder_alloc its own debug mask file
+    - [Config] enable binder and ashmem as modules
+    - SAUCE: selftests: net: replace AF_MAX with INT_MAX in socket.c
+    - SAUCE: selftests/ftrace: Fix tab expansion in trace_marker snapshot trigger
+      test
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 29 Jan 2019 06:57:32 -0600
+
+linux (5.0.0-1.2) disco; urgency=medium
+
+  * Fix non-working QCA Rome Bluetooth after S3 (LP: #1812812)
+    - USB: Add new USB LPM helpers
+    - USB: Consolidate LPM checks to avoid enabling LPM twice
+
+  * bluetooth controller not detected with 4.15 kernel (LP: #1810797)
+    - SAUCE: btqcomsmd: introduce BT_QCOMSMD_HACK
+    - [Config] arm64: snapdragon: BT_QCOMSMD_HACK=y
+
+  * [19.04 FEAT| Enable virtio-gpu for s390x (LP: #1799467)
+    - [Config] enable virtio-gpu for s390x
+
+  * Crash on "ip link add foo type ipip" (LP: #1811803)
+    - SAUCE: fan: Fix NULL pointer dereference
+
+  * Fix not working Goodix touchpad (LP: #1811929)
+    - HID: i2c-hid: Disable runtime PM on Goodix touchpad
+
+  * Miscellaneous Ubuntu changes
+    - update dkms package versions
+    - enable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 22 Jan 2019 13:56:17 -0600
+
+linux (5.0.0-0.1) disco; urgency=medium
+
+  * Build Nvidia drivers in conjunction with kernel (LP: #1764792)
+    - [Packaging] dkms -- add per package post-process step
+    - [Packaging] dkms -- switch to a consistent build prefix length and strip
+    - [Packaging] nvidia -- build and sign nvidia packages and ship signatures
+    - [Packaging] nvidia -- make nvidia package version explicit
+
+  * Add support for ALC3277 codec on new Dell edge gateways (LP: #1807334)
+    - [Config] CONFIG_SND_SOC_INTEL_KBL_RT5660_MACH=m
+
+  * RTL8822BE WiFi Disabled in Kernel 4.18.0-12 (LP: #1806472)
+    - [Config] CONFIG_RTLWIFI_DEBUG_ST=n
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu -- disable vbox build
+    - ubuntu -- disable hio build
+    - Disable zfs build
+    - SAUCE: import aufs driver
+    - update dkms package versions
+    - [Config] disable aufs config options
+    - [Config] disable nvidia build
+    - update dropped.txt
+    - [Packaging] disable nvidia dkms builds for mainline
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) debugfs: avoid EPERM when no open file operation
+      defined
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - [Config] set config options for efi lockdown
+    - Revert "UBUNTU: SAUCE: import aufs driver"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v5.0-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 17 Jan 2019 12:31:29 -0600
+
+linux (5.0.0-0.0) disco; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 16 Jan 2019 14:48:05 -0600
+
+linux (4.20.0-2.3) disco; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.20
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 03 Jan 2019 12:11:43 -0600
+
+linux (4.20.0-1.2) disco; urgency=medium
+
+  * Packaging resync (LP: #1786013)
+    - [Packaging] update helper scripts
+
+  * Power leakage at S5 with Qualcomm Atheros QCA9377 802.11ac Wireless Network
+    Adapter (LP: #1805607)
+    - SAUCE: ath10k: provide reset function for QCA9377 chip
+
+  * zfs/spl build in conjunction with the kernel from DKMS source (LP: #1807378)
+    - [Packaging] dkms -- dkms package build packaging support
+    - [Packaging] dkms -- save build objects artifacts for validation
+    - [Packaging] dkms -- add general Built-Using: support
+    - [Packaging] simplify Provides comma handling
+    - [Packaging] zfs/spl -- remove packaging support for incorporated source
+    - [Packaging] zfs/spl -- remove incorporated source
+    - [Packaging] zfs/spl -- build via dkms
+    - [Packaging] zfs/spl -- make zfs package version explicit
+    - [Packaging] update-version-dkms -- sync archive versions to package
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] update-version-dkms -- fix getting distrbution from changelog
+    - update dkms package versions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.20-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 11 Dec 2018 11:33:08 -0600
+
+linux (4.20.0-0.1) disco; urgency=medium
+
+  * Overlayfs in user namespace leaks directory content of inaccessible
+    directories (LP: #1793458) // CVE-2018-6559
+    - Revert "ovl: relax permission checking on underlying layers"
+    - SAUCE: overlayfs: ensure mounter privileges when reading directories
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) efi: Add EFI signature data types
+    - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) Fix for module sig verification
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: Import aufs driver
+    - ubuntu: vbox -- update to 5.2.22-dfsg-2
+    - ubuntu -- disable vbox build
+    - ubuntu -- disable hio build
+    - Disable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.20-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 07 Dec 2018 07:13:42 -0600
+
+linux (4.20.0-0.0) disco; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 06 Dec 2018 10:20:19 -0600
+
+linux (4.19.0-8.9) disco; urgency=medium
+
+  * linux: 4.19.0-8.9 -proposed tracker (LP: #1806952)
+
+  * Workaround CSS timeout on AMD SNPS 3.0 xHC (LP: #1806838)
+    - xhci: workaround CSS timeout on AMD SNPS 3.0 xHC
+
+  * Fix Intel I210 doesn't work when ethernet cable gets plugged (LP: #1806818)
+    - igb: Fix an issue that PME is not enabled during runtime suspend
+
+  * The line-out on the Dell Dock station can't work (LP: #1806532)
+    - ALSA: usb-audio: Add vendor and product name for Dell WD19 Dock
+
+  * CVE-2018-19407
+    - KVM: X86: Fix scan ioapic use-before-initialization
+
+  * PC SN720 NVMe WDC 256GB consumes more power in S2Idle than during long idle
+    (LP: #1805775)
+    - SAUCE: pci/nvme: prevent WDC PC SN720 NVMe from entering D3 and being
+      disabled
+
+  * Disco update: 4.19.6 upstream stable release (LP: #1806909)
+    - HID: steam: remove input device when a hid client is running.
+    - efi/libstub: arm: support building with clang
+    - usb: core: Fix hub port connection events lost
+    - usb: dwc3: gadget: fix ISOC TRB type on unaligned transfers
+    - usb: dwc3: gadget: Properly check last unaligned/zero chain TRB
+    - usb: dwc3: core: Clean up ULPI device
+    - usb: dwc3: Fix NULL pointer exception in dwc3_pci_remove()
+    - xhci: Fix leaking USB3 shared_hcd at xhci removal
+    - xhci: handle port status events for removed USB3 hcd
+    - xhci: Add check for invalid byte size error when UAS devices are connected.
+    - usb: xhci: fix uninitialized completion when USB3 port got wrong status
+    - usb: xhci: fix timeout for transition from RExit to U0
+    - xhci: Add quirk to workaround the errata seen on Cavium Thunder-X2 Soc
+    - usb: xhci: Prevent bus suspend if a port connect change or polling state is
+      detected
+    - ALSA: oss: Use kvzalloc() for local buffer allocations
+    - MAINTAINERS: Add Sasha as a stable branch maintainer
+    - Documentation/security-bugs: Clarify treatment of embargoed information
+    - Documentation/security-bugs: Postpone fix publication in exceptional cases
+    - mmc: sdhci-pci: Try "cd" for card-detect lookup before using NULL
+    - mmc: sdhci-pci: Workaround GLK firmware failing to restore the tuning value
+    - gpio: don't free unallocated ida on gpiochip_add_data_with_key() error path
+    - iwlwifi: fix wrong WGDS_WIFI_DATA_SIZE
+    - iwlwifi: mvm: support sta_statistics() even on older firmware
+    - iwlwifi: mvm: fix regulatory domain update when the firmware starts
+    - iwlwifi: mvm: don't use SAR Geo if basic SAR is not used
+    - brcmfmac: fix reporting support for 160 MHz channels
+    - opp: ti-opp-supply: Dynamically update u_volt_min
+    - opp: ti-opp-supply: Correct the supply in _get_optimal_vdd_voltage call
+    - tools/power/cpupower: fix compilation with STATIC=true
+    - v9fs_dir_readdir: fix double-free on p9stat_read error
+    - selinux: Add __GFP_NOWARN to allocation at str_read()
+    - Input: synaptics - avoid using uninitialized variable when probing
+    - bfs: add sanity check at bfs_fill_super()
+    - sctp: clear the transport of some out_chunk_list chunks in
+      sctp_assoc_rm_peer
+    - gfs2: Don't leave s_fs_info pointing to freed memory in init_sbd
+    - llc: do not use sk_eat_skb()
+    - mm: don't warn about large allocations for slab
+    - mm/memory.c: recheck page table entry with page table lock held
+    - tcp: do not release socket ownership in tcp_close()
+    - drm/fb-helper: Blacklist writeback when adding connectors to fbdev
+    - drm/amdgpu: Add missing firmware entry for HAINAN
+    - drm/vc4: Set ->legacy_cursor_update to false when doing non-async updates
+    - drm/amdgpu: Fix oops when pp_funcs->switch_power_profile is unset
+    - drm/i915: Disable LP3 watermarks on all SNB machines
+    - drm/ast: change resolution may cause screen blurred
+    - drm/ast: fixed cursor may disappear sometimes
+    - drm/ast: Remove existing framebuffers before loading driver
+    - can: flexcan: Unlock the MB unconditionally
+    - can: dev: can_get_echo_skb(): factor out non sending code to
+      __can_get_echo_skb()
+    - can: dev: __can_get_echo_skb(): replace struct can_frame by canfd_frame to
+      access frame length
+    - can: dev: __can_get_echo_skb(): Don't crash the kernel if can_priv::echo_skb
+      is accessed out of bounds
+    - can: dev: __can_get_echo_skb(): print error message, if trying to echo non
+      existing skb
+    - can: rx-offload: introduce can_rx_offload_get_echo_skb() and
+      can_rx_offload_queue_sorted() functions
+    - can: rx-offload: rename can_rx_offload_irq_queue_err_skb() to
+      can_rx_offload_queue_tail()
+    - can: flexcan: use can_rx_offload_queue_sorted() for flexcan_irq_bus_*()
+    - can: flexcan: handle tx-complete CAN frames via rx-offload infrastructure
+    - can: raw: check for CAN FD capable netdev in raw_sendmsg()
+    - can: hi311x: Use level-triggered interrupt
+    - can: flexcan: Always use last mailbox for TX
+    - can: flexcan: remove not needed struct flexcan_priv::tx_mb and struct
+      flexcan_priv::tx_mb_idx
+    - ACPICA: AML interpreter: add region addresses in global list during
+      initialization
+    - IB/hfi1: Eliminate races in the SDMA send error path
+    - fsnotify: generalize handling of extra event flags
+    - fanotify: fix handling of events on child sub-directory
+    - pinctrl: meson: fix pinconf bias disable
+    - pinctrl: meson: fix gxbb ao pull register bits
+    - pinctrl: meson: fix gxl ao pull register bits
+    - pinctrl: meson: fix meson8 ao pull register bits
+    - pinctrl: meson: fix meson8b ao pull register bits
+    - tools/testing/nvdimm: Fix the array size for dimm devices.
+    - scsi: lpfc: fix remoteport access
+    - scsi: hisi_sas: Remove set but not used variable 'dq_list'
+    - KVM: PPC: Move and undef TRACE_INCLUDE_PATH/FILE
+    - cpufreq: imx6q: add return value check for voltage scale
+    - rtc: cmos: Do not export alarm rtc_ops when we do not support alarms
+    - rtc: pcf2127: fix a kmemleak caused in pcf2127_i2c_gather_write
+    - crypto: simd - correctly take reqsize of wrapped skcipher into account
+    - floppy: fix race condition in __floppy_read_block_0()
+    - powerpc/io: Fix the IO workarounds code to work with Radix
+    - sched/fair: Fix cpu_util_wake() for 'execl' type workloads
+    - perf/x86/intel/uncore: Add more IMC PCI IDs for KabyLake and CoffeeLake CPUs
+    - block: copy ioprio in __bio_clone_fast() and bounce
+    - SUNRPC: Fix a bogus get/put in generic_key_to_expire()
+    - riscv: add missing vdso_install target
+    - RISC-V: Silence some module warnings on 32-bit
+    - drm/amdgpu: fix bug with IH ring setup
+    - kdb: Use strscpy with destination buffer size
+    - NFSv4: Fix an Oops during delegation callbacks
+    - powerpc/numa: Suppress "VPHN is not supported" messages
+    - efi/arm: Revert deferred unmap of early memmap mapping
+    - z3fold: fix possible reclaim races
+    - mm, memory_hotplug: check zone_movable in has_unmovable_pages
+    - tmpfs: make lseek(SEEK_DATA/SEK_HOLE) return ENXIO with a negative offset
+    - mm, page_alloc: check for max order in hot path
+    - dax: Avoid losing wakeup in dax_lock_mapping_entry
+    - include/linux/pfn_t.h: force '~' to be parsed as an unary operator
+    - tty: wipe buffer.
+    - tty: wipe buffer if not echoing data
+    - gfs2: Fix iomap buffer head reference counting bug
+    - rcu: Make need_resched() respond to urgent RCU-QS needs
+    - media: ov5640: Re-work MIPI startup sequence
+    - media: ov5640: Fix timings setup code
+    - media: ov5640: fix exposure regression
+    - media: ov5640: fix auto gain & exposure when changing mode
+    - media: ov5640: fix wrong binning value in exposure calculation
+    - media: ov5640: fix auto controls values when switching to manual mode
+    - Linux 4.19.6
+
+  * linux-buildinfo: pull out ABI information into its own package
+    (LP: #1806380)
+    - [Packaging] limit preparation to linux-libc-dev in headers
+    - [Packaging] commonise debhelper invocation
+    - [Packaging] ABI -- accumulate abi information at the end of the build
+    - [Packaging] buildinfo -- add basic build information
+    - [Packaging] buildinfo -- add firmware information to the flavour ABI
+    - [Packaging] buildinfo -- add compiler information to the flavour ABI
+    - [Packaging] buildinfo -- add buildinfo support to getabis
+    - [Packaging] getabis -- handle all known package combinations
+    - [Packaging] getabis -- support parsing a simple version
+
+  * linux packages should own /usr/lib/linux/triggers (LP: #1770256)
+    - [Packaging] own /usr/lib/linux/triggers
+
+  * Miscellaneous upstream changes
+    - blk-mq: fix corruption with direct issue
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 05 Dec 2018 09:18:30 -0600
+
+linux (4.19.0-7.8) disco; urgency=medium
+
+  * linux: 4.19.0-7.8 -proposed tracker (LP: #1805465)
+
+  * Fix and issue that LG I2C touchscreen stops working after reboot
+    (LP: #1805085)
+    - HID: i2c-hid: Disable runtime PM for LG touchscreen
+
+  * click/pop noise in the headphone on several lenovo laptops (LP: #1805079) //
+    click/pop noise in the headphone on several lenovo laptops (LP: #1805079)
+    - ALSA: hda/realtek - fix the pop noise on headphone for lenovo laptops
+
+  * Regression: hinic performance degrades over time (LP: #1805248)
+    - Revert "net-next/hinic: add checksum offload and TSO support"
+
+  * Disco update: 4.19.5 upstream stable release (LP: #1805461)
+    - drm/i915: Replace some PAGE_SIZE with I915_GTT_PAGE_SIZE
+    - cifs: don't dereference smb_file_target before null check
+    - cifs: fix return value for cifs_listxattr
+    - arm64: kprobe: make page to RO mode when allocate it
+    - block: brd: associate with queue until adding disk
+    - net: hns3: bugfix for rtnl_lock's range in the hclgevf_reset()
+    - net: hns3: bugfix for rtnl_lock's range in the hclge_reset()
+    - net: hns3: bugfix for handling mailbox while the command queue reinitialized
+    - net: hns3: bugfix for the initialization of command queue's spin lock
+    - ixgbe: fix MAC anti-spoofing filter after VFLR
+    - reiserfs: propagate errors from fill_with_dentries() properly
+    - hfs: prevent btree data loss on root split
+    - hfsplus: prevent btree data loss on root split
+    - perf unwind: Take pgoff into account when reporting elf to libdwfl
+    - um: Give start_idle_thread() a return code
+    - drm/edid: Add 6 bpc quirk for BOE panel.
+    - afs: Handle EIO from delivery function
+    - platform/x86: intel_telemetry: report debugfs failure
+    - clk: fixed-rate: fix of_node_get-put imbalance
+    - perf symbols: Set PLT entry/header sizes properly on Sparc
+    - fs/exofs: fix potential memory leak in mount option parsing
+    - clk: samsung: exynos5420: Enable PERIS clocks for suspend
+    - apparmor: Fix uninitialized value in aa_split_fqname
+    - x86/earlyprintk: Add a force option for pciserial device
+    - platform/x86: acerhdf: Add BIOS entry for Gateway LT31 v1.3307
+    - clk: meson-axg: pcie: drop the mpll3 clock parent
+    - arm64: percpu: Initialize ret in the default case
+    - clk: meson: clk-pll: drop CLK_GET_RATE_NOCACHE where unnecessary
+    - clk: renesas: r9a06g032: Fix UART34567 clock rate
+    - clk: ti: fix OF child-node lookup
+    - serial: sh-sci: Fix receive on SCIFA/SCIFB variants with DMA
+    - netfilter: ipv6: fix oops when defragmenting locally generated fragments
+    - netfilter: bridge: define INT_MIN & INT_MAX in userspace
+    - s390/decompressor: add missing FORCE to build targets
+    - s390/vdso: add missing FORCE to build targets
+    - HID: i2c-hid: Add a small delay after sleep command for Raydium touchpanel
+    - Revert "HID: add NOGET quirk for Eaton Ellipse MAX UPS"
+    - HID: alps: allow incoming reports when only the trackstick is opened
+    - Revert "netfilter: nft_numgen: add map lookups for numgen random operations"
+    - netfilter: ipset: list:set: Decrease refcount synchronously on deletion and
+      replace
+    - netfilter: ipset: actually allow allowable CIDR 0 in hash:net,port,net
+    - netfilter: ipset: fix ip_set_list allocation failure
+    - s390/mm: fix mis-accounting of pgtable_bytes
+    - s390/mm: Fix ERROR: "__node_distance" undefined!
+    - bpf: fix bpf_prog_get_info_by_fd to return 0 func_lens for unpriv
+    - netfilter: ipset: Correct rcu_dereference() call in ip_set_put_comment()
+    - netfilter: xt_IDLETIMER: add sysfs filename checking routine
+    - netfilter: ipset: Fix calling ip_set() macro at dumping
+    - netfilter: nft_compat: ebtables 'nat' table is normal chain type
+    - s390/qeth: fix HiperSockets sniffer
+    - s390/qeth: unregister netdevice only when registered
+    - net: hns3: Fix for out-of-bounds access when setting pfc back pressure
+    - hwmon: (ibmpowernv) Remove bogus __init annotations
+    - ARM: dts: imx6sll: fix typo for fsl,imx6sll-i2c node
+    - ARM: dts: fsl: Fix improperly quoted stdout-path values
+    - Revert "drm/exynos/decon5433: implement frame counter"
+    - arm64: dts: renesas: r8a7795: add missing dma-names on hscif2
+    - arm64: dts: renesas: condor: switch from EtherAVB to GEther
+    - xen/grant-table: Fix incorrect gnttab_dma_free_pages() pr_debug message
+    - clk: fixed-factor: fix of_node_get-put imbalance
+    - mtd: nand: Fix nanddev_pos_next_page() kernel-doc header
+    - lib/raid6: Fix arm64 test build
+    - drm/amd/display: Stop leaking planes
+    - block: Clear kernel memory before copying to user
+    - drm/amd/display: Drop reusing drm connector for MST
+    - drm/amd/amdgpu/dm: Fix dm_dp_create_fake_mst_encoder()
+    - s390/perf: Change CPUM_CF return code in event init function
+    - ceph: quota: fix null pointer dereference in quota check
+    - of/device: Really only set bus DMA mask when appropriate
+    - nvme: make sure ns head inherits underlying device limits
+    - i2c: omap: Enable for ARCH_K3
+    - i2c: qcom-geni: Fix runtime PM mismatch with child devices
+    - sched/core: Take the hotplug lock in sched_init_smp()
+    - perf tools: Fix undefined symbol scnprintf in libperf-jvmti.so
+    - perf tools: Do not zero sample_id_all for group members
+    - ice: Fix dead device link issue with flow control
+    - ice: Fix the bytecount sent to netdev_tx_sent_queue
+    - ice: Change req_speeds to be u16
+    - i40e: restore NETIF_F_GSO_IPXIP[46] to netdev features
+    - qed: Fix memory/entry leak in qed_init_sp_request()
+    - qed: Fix blocking/unlimited SPQ entries leak
+    - qed: Fix SPQ entries not returned to pool in error flows
+    - qed: Fix potential memory corruption
+    - net: stmmac: Fix RX packet size > 8191
+    - net: aquantia: fix potential IOMMU fault after driver unbind
+    - net: aquantia: fixed enable unicast on 32 macvlan
+    - net: aquantia: invalid checksumm offload implementation
+    - kbuild: deb-pkg: fix too low build version number
+    - Revert "scripts/setlocalversion: git: Make -dirty check more robust"
+    - SUNRPC: drop pointless static qualifier in xdr_get_next_encode_buffer()
+    - x86/mm: Move LDT remap out of KASLR region on 5-level paging
+    - x86/ldt: Unmap PTEs for the slot before freeing LDT pages
+    - x86/ldt: Remove unused variable in map_ldt_struct()
+    - media: v4l: event: Add subscription to list before calling "add" operation
+    - MIPS: OCTEON: cavium_octeon_defconfig: re-enable OCTEON USB driver
+    - RISC-V: Fix raw_copy_{to,from}_user()
+    - uio: Fix an Oops on load
+    - ALSA: hda/realtek - Add quirk entry for HP Pavilion 15
+    - ALSA: hda/ca0132 - Call pci_iounmap() instead of iounmap()
+    - can: kvaser_usb: Fix accessing freed memory in kvaser_usb_start_xmit()
+    - can: kvaser_usb: Fix potential uninitialized variable use
+    - usb: cdc-acm: add entry for Hiro (Conexant) modem
+    - USB: Wait for extra delay time after USB_PORT_FEAT_RESET for quirky hub
+    - usb: quirks: Add delay-init quirk for Corsair K70 LUX RGB
+    - misc: atmel-ssc: Fix section annotation on atmel_ssc_get_driver_data
+    - USB: misc: appledisplay: add 20" Apple Cinema Display
+    - gnss: serial: fix synchronous write timeout
+    - gnss: sirf: fix synchronous write timeout
+    - mtd: rawnand: atmel: fix OF child-node lookup
+    - drivers/misc/sgi-gru: fix Spectre v1 vulnerability
+    - ACPI / platform: Add SMB0001 HID to forbidden_id_list
+    - HID: uhid: forbid UHID_CREATE under KERNEL_DS or elevated privileges
+    - HID: Add quirk for Primax PIXART OEM mice
+    - HID: Add quirk for Microsoft PIXART OEM mouse
+    - libceph: fall back to sendmsg for slab pages
+    - mt76x0: run vco calibration for each channel configuration
+    - Linux 4.19.5
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: Build signed kernels for arm64"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 27 Nov 2018 10:38:34 -0600
+
+linux (4.19.0-6.7) disco; urgency=medium
+
+  * linux: 4.19.0-6.7 -proposed tracker (LP: #1805195)
+
+  * SecureBoot support for arm64 (LP: #1804481)
+    - Build signed kernels for arm64
+
+  * Add pointstick support for Cirque Touchpad (LP: #1805081)
+    - HID: multitouch: Add pointstick support for Cirque Touchpad
+
+  * Power consumption during s2idle is higher than long idle (Intel SSDPEKKF)
+    (LP: #1804588)
+    - SAUCE: pci: prevent Intel NVMe SSDPEKKF from entering D3
+    - SAUCE: nvme: add quirk to not call disable function when suspending
+
+  * Disco update: 4.19.4 upstream stable release (LP: #1805159)
+    - flow_dissector: do not dissect l4 ports for fragments
+    - ibmvnic: fix accelerated VLAN handling
+    - ip_tunnel: don't force DF when MTU is locked
+    - ipv6: fix a dst leak when removing its exception
+    - ipv6: Fix PMTU updates for UDP/raw sockets in presence of VRF
+    - net: bcmgenet: protect stop from timeout
+    - net-gro: reset skb->pkt_type in napi_reuse_skb()
+    - sctp: not allow to set asoc prsctp_enable by sockopt
+    - tcp: Fix SOF_TIMESTAMPING_RX_HARDWARE to use the latest timestamp during TCP
+      coalescing
+    - tg3: Add PHY reset for 5717/5719/5720 in change ring and flow control paths
+    - tipc: don't assume linear buffer when reading ancillary data
+    - tipc: fix lockdep warning when reinitilaizing sockets
+    - tuntap: fix multiqueue rx
+    - net: systemport: Protect stop from timeout
+    - net/sched: act_pedit: fix memory leak when IDR allocation fails
+    - net: sched: cls_flower: validate nested enc_opts_policy to avoid warning
+    - tipc: fix link re-establish failure
+    - net/mlx5e: Don't match on vlan non-existence if ethertype is wildcarded
+    - net/mlx5e: Claim TC hw offloads support only under a proper build config
+    - net/mlx5e: Adjust to max number of channles when re-attaching
+    - net/mlx5e: RX, verify received packet size in Linear Striding RQ
+    - Revert "sctp: remove sctp_transport_pmtu_check"
+    - net/mlx5e: Always use the match level enum when parsing TC rule match
+    - net/mlx5e: Fix selftest for small MTUs
+    - net/mlx5e: Removed unnecessary warnings in FEC caps query
+    - inet: frags: better deal with smp races
+    - l2tp: fix a sock refcnt leak in l2tp_tunnel_register
+    - net/mlx5: IPSec, Fix the SA context hash key
+    - net/mlx5e: IPoIB, Reset QP after channels are closed
+    - net: dsa: mv88e6xxx: Fix clearing of stats counters
+    - net: phy: realtek: fix RTL8201F sysfs name
+    - sctp: define SCTP_SS_DEFAULT for Stream schedulers
+    - net: qualcomm: rmnet: Fix incorrect assignment of real_dev
+    - net: dsa: microchip: initialize mutex before use
+    - sctp: fix strchange_flags name for Stream Change Event
+    - net: phy: mdio-gpio: Fix working over slow can_sleep GPIOs
+    - sctp: not increase stream's incnt before sending addstrm_in request
+    - mlxsw: spectrum: Fix IP2ME CPU policer configuration
+    - net: smsc95xx: Fix MTU range
+    - rxrpc: Fix lockup due to no error backoff after ack transmit error
+    - usbnet: smsc95xx: disable carrier check while suspending
+    - Revert "x86/speculation: Enable cross-hyperthread spectre v2 STIBP
+      mitigation"
+    - Linux 4.19.4
+
+  * Disco update: 4.19.3 upstream stable release (LP: #1805158)
+    - powerpc/traps: restore recoverability of machine_check interrupts
+    - powerpc/64/module: REL32 relocation range check
+    - powerpc/mm: Fix page table dump to work on Radix
+    - powerpc/mm: fix always true/false warning in slice.c
+    - drm/amd/display: fix bug of accessing invalid memory
+    - Input: wm97xx-ts - fix exit path
+    - powerpc/Makefile: Fix PPC_BOOK3S_64 ASFLAGS
+    - powerpc/eeh: Fix possible null deref in eeh_dump_dev_log()
+    - tty: check name length in tty_find_polling_driver()
+    - tracing/kprobes: Check the probe on unloaded module correctly
+    - drm/nouveau/secboot/acr: fix memory leak
+    - drm/amdgpu/powerplay: fix missing break in switch statements
+    - ARM: imx_v6_v7_defconfig: Select CONFIG_TMPFS_POSIX_ACL
+    - powerpc/nohash: fix undefined behaviour when testing page size support
+    - drm/msm/gpu: fix parameters in function msm_gpu_crashstate_capture
+    - drm/msm/disp/dpu: Use proper define for drm_encoder_init() 'encoder_type'
+    - drm/msm: dpu: Allow planes to extend past active display
+    - powerpc/mm: Don't report hugepage tables as memory leaks when using kmemleak
+    - drm/omap: fix memory barrier bug in DMM driver
+    - drm/amd/display: Raise dispclk value for dce120 by 15%
+    - drm/amd/display: fix gamma not being applied
+    - drm/hisilicon: hibmc: Do not carry error code in HiBMC framebuffer pointer
+    - media: pci: cx23885: handle adding to list failure
+    - media: coda: don't overwrite h.264 profile_idc on decoder instance
+    - MIPS: kexec: Mark CPU offline before disabling local IRQ
+    - powerpc/boot: Ensure _zimage_start is a weak symbol
+    - powerpc/memtrace: Remove memory in chunks
+    - MIPS/PCI: Call pcie_bus_configure_settings() to set MPS/MRRS
+    - staging: erofs: fix a missing endian conversion
+    - serial: 8250_of: Fix for lack of interrupt support
+    - sc16is7xx: Fix for multi-channel stall
+    - media: tvp5150: fix width alignment during set_selection()
+    - powerpc/selftests: Wait all threads to join
+    - staging:iio:ad7606: fix voltage scales
+    - drm: rcar-du: Update Gen3 output limitations
+    - drm/amdgpu: Fix SDMA TO after GPU reset v3
+    - staging: most: video: fix registration of an empty comp core_component
+    - 9p locks: fix glock.client_id leak in do_lock
+    - udf: Prevent write-unsupported filesystem to be remounted read-write
+    - ARM: dts: imx6ull: keep IMX6UL_ prefix for signals on both i.MX6UL and
+      i.MX6ULL
+    - media: ov5640: fix mode change regression
+    - 9p: clear dangling pointers in p9stat_free
+    - drm/amdgpu: fix integer overflow test in amdgpu_bo_list_create()
+    - media: ov5640: fix restore of last mode set
+    - cdrom: fix improper type cast, which can leat to information leak.
+    - ovl: fix error handling in ovl_verify_set_fh()
+    - ovl: fix recursive oi->lock in ovl_link()
+    - ovl: check whiteout in ovl_create_over_whiteout()
+    - ovl: automatically enable redirect_dir on metacopy=on
+    - serial: sh-sci: Fix could not remove dev_attr_rx_fifo_timeout
+    - scsi: qla2xxx: Fix incorrect port speed being set for FC adapters
+    - scsi: qla2xxx: Fix process response queue for ISP26XX and above
+    - scsi: qla2xxx: Remove stale debug trace message from tcm_qla2xxx
+    - scsi: qla2xxx: Fix early srb free on abort
+    - scsi: qla2xxx: shutdown chip if reset fail
+    - scsi: qla2xxx: Reject bsg request if chip is down.
+    - scsi: qla2xxx: Fix re-using LoopID when handle is in use
+    - scsi: qla2xxx: Fix for double free of SRB structure
+    - scsi: qla2xxx: Fix NVMe session hang on unload
+    - scsi: qla2xxx: Fix NVMe Target discovery
+    - scsi: qla2xxx: Fix duplicate switch database entries
+    - scsi: qla2xxx: Fix driver hang when FC-NVMe LUNs are configured
+    - vfs: fix FIGETBSZ ioctl on an overlayfs file
+    - fuse: Fix use-after-free in fuse_dev_do_read()
+    - fuse: Fix use-after-free in fuse_dev_do_write()
+    - fuse: fix blocked_waitq wakeup
+    - fuse: set FR_SENT while locked
+    - drm/msm: fix OF child-node lookup
+    - arm64: dts: stratix10: Support Ethernet Jumbo frame
+    - arm64: dts: stratix10: fix multicast filtering
+    - clk: meson-gxbb: set fclk_div3 as CLK_IS_CRITICAL
+    - clk: meson: axg: mark fdiv2 and fdiv3 as critical
+    - zram: close udev startup race condition as default groups
+    - MIPS: Loongson-3: Fix CPU UART irq delivery problem
+    - MIPS: Loongson-3: Fix BRIDGE irq delivery problem
+    - xtensa: add NOTES section to the linker script
+    - xtensa: make sure bFLT stack is 16 byte aligned
+    - xtensa: fix boot parameters address translation
+    - um: Drop own definition of PTRACE_SYSEMU/_SINGLESTEP
+    - clk: s2mps11: Fix matching when built as module and DT node contains
+      compatible
+    - clk: at91: Fix division by zero in PLL recalc_rate()
+    - clk: sunxi-ng: h6: fix bus clocks' divider position
+    - clk: rockchip: fix wrong mmc sample phase shift for rk3328
+    - clk: rockchip: Fix static checker warning in rockchip_ddrclk_get_parent call
+    - libceph: bump CEPH_MSG_MAX_DATA_LEN
+    - Revert "ceph: fix dentry leak in splice_dentry()"
+    - thermal: core: Fix use-after-free in thermal_cooling_device_destroy_sysfs
+    - mach64: fix display corruption on big endian machines
+    - mach64: fix image corruption due to reading accelerator registers
+    - acpi/nfit, x86/mce: Handle only uncorrectable machine checks
+    - acpi/nfit, x86/mce: Validate a MCE's address before using it
+    - acpi, nfit: Fix ARS overflow continuation
+    - reset: hisilicon: fix potential NULL pointer dereference
+    - crypto: hisilicon - Fix NULL dereference for same dst and src
+    - crypto: hisilicon - Fix reference after free of memories on error path
+    - vhost/scsi: truncate T10 PI iov_iter to prot_bytes
+    - scsi: qla2xxx: Initialize port speed to avoid setting lower speed
+    - SCSI: fix queue cleanup race before queue initialization is done
+    - Revert "powerpc/8xx: Use L1 entry APG to handle _PAGE_ACCESSED for
+      CONFIG_SWAP"
+    - soc: ti: QMSS: Fix usage of irq_set_affinity_hint
+    - ocfs2: fix a misuse a of brelse after failing ocfs2_check_dir_entry
+    - ocfs2: free up write context when direct IO failed
+    - mm: thp: relax __GFP_THISNODE for MADV_HUGEPAGE mappings
+    - memory_hotplug: cond_resched in __remove_pages
+    - netfilter: conntrack: fix calculation of next bucket number in early_drop
+    - ARM: 8809/1: proc-v7: fix Thumb annotation of cpu_v7_hvc_switch_mm
+    - bonding/802.3ad: fix link_failure_count tracking
+    - mtd: spi-nor: cadence-quadspi: Return error code in
+      cqspi_direct_read_execute()
+    - mtd: nand: Fix nanddev_neraseblocks()
+    - mtd: docg3: don't set conflicting BCH_CONST_PARAMS option
+    - hwmon: (core) Fix double-free in __hwmon_device_register()
+    - perf cs-etm: Correct CPU mode for samples
+    - perf stat: Handle different PMU names with common prefix
+    - perf callchain: Honour the ordering of PERF_CONTEXT_{USER,KERNEL,etc}
+    - perf intel-pt/bts: Calculate cpumode for synthesized samples
+    - perf intel-pt: Insert callchain context into synthesized callchains
+    - of, numa: Validate some distance map rules
+    - x86/cpu/vmware: Do not trace vmware_sched_clock()
+    - x86/hyper-v: Enable PIT shutdown quirk
+    - termios, tty/tty_baudrate.c: fix buffer overrun
+    - arch/alpha, termios: implement BOTHER, IBSHIFT and termios2
+    - watchdog/core: Add missing prototypes for weak functions
+    - btrfs: fix pinned underflow after transaction aborted
+    - Btrfs: fix missing data checksums after a ranged fsync (msync)
+    - Btrfs: fix cur_offset in the error case for nocow
+    - Btrfs: fix infinite loop on inode eviction after deduplication of eof block
+    - Btrfs: fix data corruption due to cloning of eof block
+    - btrfs: tree-checker: Fix misleading group system information
+    - clockevents/drivers/i8253: Add support for PIT shutdown quirk
+    - ext4: add missing brelse() update_backups()'s error path
+    - ext4: add missing brelse() in set_flexbg_block_bitmap()'s error path
+    - ext4: add missing brelse() add_new_gdb_meta_bg()'s error path
+    - ext4: avoid potential extra brelse in setup_new_flex_group_blocks()
+    - ext4: missing !bh check in ext4_xattr_inode_write()
+    - ext4: fix possible inode leak in the retry loop of ext4_resize_fs()
+    - ext4: avoid buffer leak on shutdown in ext4_mark_iloc_dirty()
+    - ext4: avoid buffer leak in ext4_orphan_add() after prior errors
+    - ext4: fix missing cleanup if ext4_alloc_flex_bg_array() fails while resizing
+    - ext4: avoid possible double brelse() in add_new_gdb() on error path
+    - ext4: fix possible leak of sbi->s_group_desc_leak in error path
+    - ext4: fix possible leak of s_journal_flag_rwsem in error path
+    - ext4: fix buffer leak in ext4_xattr_get_block() on error path
+    - ext4: release bs.bh before re-using in ext4_xattr_block_find()
+    - ext4: fix buffer leak in ext4_xattr_move_to_block() on error path
+    - ext4: fix buffer leak in ext4_expand_extra_isize_ea() on error path
+    - ext4: fix buffer leak in __ext4_read_dirblock() on error path
+    - mount: Prevent MNT_DETACH from disconnecting locked mounts
+    - mnt: fix __detach_mounts infinite loop
+    - uapi: fix linux/kfd_ioctl.h userspace compilation errors
+    - ARM: cpuidle: Don't register the driver when back-end init returns -ENXIO
+    - kdb: use correct pointer when 'btc' calls 'btt'
+    - kdb: print real address of pointers instead of hashed addresses
+    - sunrpc: correct the computation for page_ptr when truncating
+    - NFSv4: Don't exit the state manager without clearing
+      NFS4CLNT_MANAGER_RUNNING
+    - nfsd: COPY and CLONE operations require the saved filehandle to be set
+    - rtc: hctosys: Add missing range error reporting
+    - fuse: fix use-after-free in fuse_direct_IO()
+    - fuse: fix leaked notify reply
+    - fuse: fix possibly missed wake-up after abort
+    - selinux: check length properly in SCTP bind hook
+    - gfs2: Put bitmap buffers in put_super
+    - gfs2: Fix metadata read-ahead during truncate (2)
+    - libata: blacklist SAMSUNG MZ7TD256HAFV-000L9 SSD
+    - crypto: user - fix leaking uninitialized memory to userspace
+    - lib/ubsan.c: don't mark __ubsan_handle_builtin_unreachable as noreturn
+    - hugetlbfs: fix kernel BUG at fs/hugetlbfs/inode.c:444!
+    - mm/swapfile.c: use kvzalloc for swap_info_struct allocation
+    - efi/arm/libstub: Pack FDT after populating it
+    - mm: don't reclaim inodes with many attached pages
+    - scripts/spdxcheck.py: make python3 compliant
+    - drm/rockchip: Allow driver to be shutdown on reboot/kexec
+    - drm/amdgpu: Fix typo in amdgpu_vmid_mgr_init
+    - drm/amdgpu: add missing CHIP_HAINAN in amdgpu_ucode_get_load_type
+    - drm/amdgpu: Suppress keypresses from ACPI_VIDEO events
+    - drm/nouveau: Check backlight IDs are >= 0, not > 0
+    - drm/nouveau: Fix nv50_mstc->best_encoder()
+    - drm/amd/powerplay: Enable/Disable NBPSTATE on On/OFF of UVD
+    - drm/etnaviv: fix bogus fence complete check in timeout handler
+    - drm/dp_mst: Check if primary mstb is null
+    - drm: panel-orientation-quirks: Add quirk for Acer One 10 (S1003)
+    - drm/i915/dp: Link train Fallback on eDP only if fallback link BW can fit
+      panel's native mode
+    - drm/i915: Use the correct crtc when sanitizing plane mapping
+    - drm/i915: Restore vblank interrupts earlier
+    - drm/i915: Don't unset intel_connector->mst_port
+    - drm/i915: Skip vcpi allocation for MSTB ports that are gone
+    - drm/i915: Large page offsets for pread/pwrite
+    - drm/i915/dp: Fix link retraining comment in intel_dp_long_pulse()
+    - drm/i915/dp: Restrict link retrain workaround to external monitors
+    - drm/i915/icl: Fix the macros for DFLEXDPMLE register bits
+    - drm/i915/hdmi: Add HDMI 2.0 audio clock recovery N values
+    - drm/i915: Mark up GTT sizes as u64
+    - drm/i915: Fix error handling for the NV12 fb dimensions check
+    - drm/i915: Fix ilk+ watermarks when disabling pipes
+    - drm/i915: Compare user's 64b GTT offset even on 32b
+    - drm/i915: Don't oops during modeset shutdown after lpe audio deinit
+    - drm/i915: Mark pin flags as u64
+    - drm/i915/ringbuffer: Delay after EMIT_INVALIDATE for gen4/gen5
+    - drm/i915/execlists: Force write serialisation into context image vs
+      execution
+    - drm/i915: Fix possible race in intel_dp_add_mst_connector()
+    - drm/i915: Fix NULL deref when re-enabling HPD IRQs on systems with MST
+    - drm/i915: Fix hpd handling for pins with two encoders
+    - CONFIG_XEN_PV breaks xen_create_contiguous_region on ARM
+    - Revert "ACPICA: AML interpreter: add region addresses in global list during
+      initialization"
+    - Linux 4.19.3
+
+  * glibc 2.28-0ubuntu1 ADT test failure with linux 4.19.0-5.6 (LP: #1805154)
+    - SAUCE: Revert "x86: vdso: Use $LD instead of $CC to link"
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.12-1ubuntu1, zfs to 0.7.12-1ubuntu1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 26 Nov 2018 11:44:00 -0600
+
+linux (4.19.0-5.6) disco; urgency=medium
+
+  * crash in ENA driver on removing an interface (LP: #1802341)
+    - SAUCE: net: ena: fix crash during ena_remove()
+
+  * Ubuntu 18.04.1 - [s390x] Kernel panic while stressing network bonding
+    (LP: #1797367)
+    - s390/qeth: sanitize strings in debug messages
+
+  * Disco update: 4.19.2 upstream stable release (LP: #1803410)
+    - bpf: fix partial copy of map_ptr when dst is scalar
+    - MIPS: VDSO: Reduce VDSO_RANDOMIZE_SIZE to 64MB for 64bit
+    - gpio: mxs: Get rid of external API call
+    - mtd: rawnand: marvell: fix the IRQ handler complete() condition
+    - mtd: maps: gpio-addr-flash: Fix ioremapped size
+    - mtd: spi-nor: fsl-quadspi: fix read error for flash size larger than 16MB
+    - mtd: spi-nor: intel-spi: Add support for Intel Ice Lake SPI serial flash
+    - mtd: spi-nor: fsl-quadspi: Don't let -EINVAL on the bus
+    - spi: spi-mem: Adjust op len based on message/transfer size limitations
+    - spi: bcm-qspi: switch back to reading flash using smaller chunks
+    - spi: bcm-qspi: fix calculation of address length
+    - bcache: trace missed reading by cache_missed
+    - bcache: fix ioctl in flash device
+    - bcache: correct dirty data statistics
+    - bcache: fix miss key refill->end in writeback
+    - hwmon: (pmbus) Fix page count auto-detection.
+    - jffs2: free jffs2_sb_info through jffs2_kill_sb()
+    - block: setup bounce bio_sets properly
+    - block: make sure discard bio is aligned with logical block size
+    - block: make sure writesame bio is aligned with logical block size
+    - cpufreq: conservative: Take limits changes into account properly
+    - dma-mapping: fix panic caused by passing empty cma command line argument
+    - pcmcia: Implement CLKRUN protocol disabling for Ricoh bridges
+    - ACPI / OSL: Use 'jiffies' as the time bassis for acpi_os_get_timer()
+    - ACPICA: AML interpreter: add region addresses in global list during
+      initialization
+    - ACPICA: AML Parser: fix parse loop to correctly skip erroneous extended
+      opcodes
+    - acpi, nfit: Fix Address Range Scrub completion tracking
+    - kprobes/x86: Use preempt_enable() in optimized_callback()
+    - mailbox: PCC: handle parse error
+    - parisc: Fix address in HPMC IVA
+    - parisc: Fix map_pages() to not overwrite existing pte entries
+    - parisc: Fix exported address of os_hpmc handler
+    - ALSA: hda - Add quirk for ASUS G751 laptop
+    - ALSA: hda - Fix headphone pin config for ASUS G751
+    - ALSA: hda - Add mic quirk for the Lenovo G50-30 (17aa:3905)
+    - ALSA: hda: Add 2 more models to the power_save blacklist
+    - ALSA: ca0106: Disable IZD on SB0570 DAC to fix audio pops
+    - ALSA: hda - Fix incorrect clearance of thinkpad_acpi hooks
+    - x86/speculation: Enable cross-hyperthread spectre v2 STIBP mitigation
+    - x86/xen: Fix boot loader version reported for PVH guests
+    - x86/corruption-check: Fix panic in memory_corruption_check() when boot
+      option without value is provided
+    - x86/kvm/nVMX: allow bare VMXON state migration
+    - x86/mm/pat: Disable preemption around __flush_tlb_all()
+    - x86/numa_emulation: Fix uniform-split numa emulation
+    - ARM: dts: exynos: Disable pull control for MAX8997 interrupts on Origen
+    - net: socionext: Reset tx queue in ndo_stop
+    - net: loopback: clear skb->tstamp before netif_rx()
+    - locking/lockdep: Fix debug_locks off performance problem
+    - netfilter: xt_nat: fix DNAT target for shifted portmap ranges
+    - ataflop: fix error handling during setup
+    - swim: fix cleanup on setup error
+    - arm64: cpufeature: ctr: Fix cpu capability check for late CPUs
+    - hv_netvsc: fix vf serial matching with pci slot info
+    - nfp: devlink port split support for 1x100G CXP NIC
+    - tun: Consistently configure generic netdev params via rtnetlink
+    - s390/sthyi: Fix machine name validity indication
+    - hwmon: (pwm-fan) Set fan speed to 0 on suspend
+    - lightnvm: pblk: fix race on sysfs line state
+    - lightnvm: pblk: fix two sleep-in-atomic-context bugs
+    - lightnvm: pblk: fix race condition on metadata I/O
+    - spi: spi-ep93xx: Use dma_data_direction for ep93xx_spi_dma_{finish,prepare}
+    - perf tools: Free temporary 'sys' string in read_event_files()
+    - perf tools: Cleanup trace-event-info 'tdata' leak
+    - perf tools: Free 'printk' string in parse_ftrace_printk()
+    - perf strbuf: Match va_{add,copy} with va_end
+    - cpupower: Fix coredump on VMWare
+    - bcache: Populate writeback_rate_minimum attribute
+    - mmc: sdhci-pci-o2micro: Add quirk for O2 Micro dev 0x8620 rev 0x01
+    - sdhci: acpi: add free_slot callback
+    - mtd: rawnand: denali: set SPARE_AREA_SKIP_BYTES register to 8 if unset
+    - iwlwifi: pcie: avoid empty free RB queue
+    - iwlwifi: mvm: clear HW_RESTART_REQUESTED when stopping the interface
+    - iwlwifi: mvm: check for n_profiles validity in EWRD ACPI
+    - x86/olpc: Indicate that legacy PC XO-1 platform should not register RTC
+    - wlcore: Fix BUG with clear completion on timeout
+    - ACPI/PPTT: Handle architecturally unknown cache types
+    - ACPI / PM: LPIT: Register sysfs attributes based on FADT
+    - ACPI / processor: Fix the return value of acpi_processor_ids_walk()
+    - cpufreq: dt: Try freeing static OPPs only if we have added them
+    - x86/intel_rdt: Show missing resctrl mount options
+    - mtd: rawnand: atmel: Fix potential NULL pointer dereference
+    - nvme: call nvme_complete_rq when nvmf_check_ready fails for mpath I/O
+    - ath10k: fix tx status flag setting for management frames
+    - signal: Introduce COMPAT_SIGMINSTKSZ for use in compat_sys_sigaltstack
+    - ice: fix changing of ring descriptor size (ethtool -G)
+    - ice: update fw version check logic
+    - net: hns3: Fix for packet buffer setting bug
+    - Bluetooth: btbcm: Add entry for BCM4335C0 UART bluetooth
+    - Bluetooth: hci_qca: Remove hdev dereference in qca_close().
+    - x86: boot: Fix EFI stub alignment
+    - net: hns3: Add nic state check before calling netif_tx_wake_queue
+    - net: hns3: Fix ets validate issue
+    - pinctrl: sunxi: fix 'pctrl->functions' allocation in
+      sunxi_pinctrl_build_state
+    - pinctrl: qcom: spmi-mpp: Fix err handling of pmic_mpp_set_mux
+    - brcmfmac: fix for proper support of 160MHz bandwidth
+    - net: hns3: Check hdev state when getting link status
+    - net: hns3: Set STATE_DOWN bit of hdev state when stopping net
+    - net: phy: phylink: ensure the carrier is off when starting phylink
+    - block, bfq: correctly charge and reset entity service in all cases
+    - arm64: entry: Allow handling of undefined instructions from EL1
+    - kprobes: Return error if we fail to reuse kprobe instead of BUG_ON()
+    - spi: gpio: No MISO does not imply no RX
+    - ACPI / LPSS: Add alternative ACPI HIDs for Cherry Trail DMA controllers
+    - pinctrl: qcom: spmi-mpp: Fix drive strength setting
+    - bpf/verifier: fix verifier instability
+    - failover: Add missing check to validate 'slave_dev' in
+      net_failover_slave_unregister
+    - perf tests: Fix record+probe_libc_inet_pton.sh without ping's debuginfo
+    - pinctrl: spmi-mpp: Fix pmic_mpp_config_get() to be compliant
+    - pinctrl: ssbi-gpio: Fix pm8xxx_pin_config_get() to be compliant
+    - net: hns3: Preserve vlan 0 in hardware table
+    - net: hns3: Fix ping exited problem when doing lp selftest
+    - net: hns3: Fix for vf vlan delete failed problem
+    - net: dsa: mv88e6xxx: Fix writing to a PHY page.
+    - mt76x2u: run device cleanup routine if resume fails
+    - rsi: fix memory alignment issue in ARM32 platforms
+    - libertas_tf: prevent underflow in process_cmdrequest()
+    - iwlwifi: mvm: fix BAR seq ctrl reporting
+    - gpio: brcmstb: allow 0 width GPIO banks
+    - ixgbe: disallow IPsec Tx offload when in SR-IOV mode
+    - ixgbevf: VF2VF TCP RSS
+    - wil6210: fix RX buffers release and unmap
+    - ath10k: schedule hardware restart if WMI command times out
+    - libata: Apply NOLPM quirk for SAMSUNG MZ7TD256HAFV-000L9
+    - thermal: rcar_thermal: Prevent doing work after unbind
+    - thermal: da9062/61: Prevent hardware access during system suspend
+    - cifs: fix a credits leak for compund commands
+    - cgroup, netclassid: add a preemption point to write_classid
+    - net: stmmac: dwmac-sun8i: fix OF child-node lookup
+    - f2fs: fix to account IO correctly for cgroup writeback
+    - MD: Memory leak when flush bio size is zero
+    - md: fix memleak for mempool
+    - of: Add missing exports of node name compare functions
+    - scsi: esp_scsi: Track residual for PIO transfers
+    - scsi: ufs: Schedule clk gating work on correct queue
+    - UAPI: ndctl: Fix g++-unsupported initialisation in headers
+    - KVM: nVMX: Clear reserved bits of #DB exit qualification
+    - scsi: megaraid_sas: fix a missing-check bug
+    - RDMA/core: Do not expose unsupported counters
+    - RDMA/cm: Respect returned status of cm_init_av_by_path
+    - IB/ipoib: Clear IPCB before icmp_send
+    - RDMA/bnxt_re: Avoid accessing nq->bar_reg_iomem in failure case
+    - RDMA/bnxt_re: Fix recursive lock warning in debug kernel
+    - usb: host: ohci-at91: fix request of irq for optional gpio
+    - PCI: mediatek: Fix mtk_pcie_find_port() endpoint/port matching logic
+    - PCI: cadence: Use AXI region 0 to signal interrupts from EP
+    - usb: typec: tcpm: Report back negotiated PPS voltage and current
+    - tpm: suppress transmit cmd error logs when TPM 1.2 is disabled/deactivated
+    - f2fs: clear PageError on the read path
+    - Drivers: hv: vmbus: Use cpumask_var_t for on-stack cpu mask
+    - VMCI: Resource wildcard match fixed
+    - PCI / ACPI: Enable wake automatically for power managed bridges
+    - xprtrdma: Reset credit grant properly after a disconnect
+    - irqchip/pdc: Setup all edge interrupts as rising edge at GIC
+    - usb: dwc2: fix call to vbus supply exit routine, call it unlocked
+    - usb: dwc2: fix a race with external vbus supply
+    - usb: gadget: udc: atmel: handle at91sam9rl PMC
+    - ext4: fix argument checking in EXT4_IOC_MOVE_EXT
+    - MD: fix invalid stored role for a disk
+    - PCI: cadence: Correct probe behaviour when failing to get PHY
+    - nvmem: check the return value of nvmem_add_cells()
+    - xhci: Avoid USB autosuspend when resuming USB2 ports.
+    - scsi: qla2xxx: Fix recursive mailbox timeout
+    - f2fs: fix to recover inode's crtime during POR
+    - f2fs: fix to recover inode's i_flags during POR
+    - PCI/MSI: Warn and return error if driver enables MSI/MSI-X twice
+    - coresight: etb10: Fix handling of perf mode
+    - PCI: dwc: pci-dra7xx: Enable errata i870 for both EP and RC mode
+    - crypto: caam - fix implicit casts in endianness helpers
+    - usb: chipidea: Prevent unbalanced IRQ disable
+    - Smack: ptrace capability use fixes
+    - driver/dma/ioat: Call del_timer_sync() without holding prep_lock
+    - ASoC: AMD: Fix capture unstable in beginning for some runs
+    - firmware: coreboot: Unmap ioregion after device population
+    - IB/ipoib: Use dev_port to expose network interface port numbers
+    - IB/mlx5: Allow transition of DCI QP to reset
+    - uio: ensure class is registered before devices
+    - scsi: lpfc: Correct soft lockup when running mds diagnostics
+    - scsi: lpfc: Correct race with abort on completion path
+    - f2fs: avoid sleeping under spin_lock
+    - f2fs: report error if quota off error during umount
+    - signal: Always deliver the kernel's SIGKILL and SIGSTOP to a pid namespace
+      init
+    - f2fs: fix to flush all dirty inodes recovered in readonly fs
+    - mfd: menelaus: Fix possible race condition and leak
+    - dmaengine: dma-jz4780: Return error if not probed from DT
+    - IB/rxe: fix for duplicate request processing and ack psns
+    - ALSA: hda: Check the non-cached stream buffers more explicitly
+    - cpupower: Fix AMD Family 0x17 msr_pstate size
+    - Revert "f2fs: fix to clear PG_checked flag in set_page_dirty()"
+    - f2fs: fix missing up_read
+    - f2fs: fix to recover cold bit of inode block during POR
+    - f2fs: fix to account IO correctly
+    - OPP: Free OPP table properly on performance state irregularities
+    - ARM: dts: exynos: Convert exynos5250.dtsi to opp-v2 bindings
+    - ARM: dts: exynos: Mark 1 GHz CPU OPP as suspend OPP on Exynos5250
+    - xen-swiotlb: use actually allocated size on check physical continuous
+    - tpm: Restore functionality to xen vtpm driver.
+    - xen/blkfront: avoid NULL blkfront_info dereference on device removal
+    - xen/balloon: Support xend-based toolstack
+    - xen: fix race in xen_qlock_wait()
+    - xen: make xen_qlock_wait() nestable
+    - xen/pvh: increase early stack size
+    - xen/pvh: don't try to unplug emulated devices
+    - libertas: don't set URB_ZERO_PACKET on IN USB transfer
+    - usbip:vudc: BUG kmalloc-2048 (Not tainted): Poison overwritten
+    - usb: typec: tcpm: Fix APDO PPS order checking to be based on voltage
+    - usb: gadget: udc: renesas_usb3: Fix b-device mode for "workaround"
+    - mt76: mt76x2: fix multi-interface beacon configuration
+    - iwlwifi: mvm: check return value of rs_rate_from_ucode_rate()
+    - net/ipv4: defensive cipso option parsing
+    - dmaengine: ppc4xx: fix off-by-one build failure
+    - scsi: sched/wait: Add wait_event_lock_irq_timeout for TASK_UNINTERRUPTIBLE
+      usage
+    - scsi: target: Fix target_wait_for_sess_cmds breakage with active signals
+    - libnvdimm: Hold reference on parent while scheduling async init
+    - libnvdimm, region: Fail badblocks listing for inactive regions
+    - libnvdimm, pmem: Fix badblocks population for 'raw' namespaces
+    - ASoC: intel: skylake: Add missing break in skl_tplg_get_token()
+    - ASoC: sta32x: set ->component pointer in private struct
+    - IB/mlx5: Fix MR cache initialization
+    - IB/rxe: Revise the ib_wr_opcode enum
+    - jbd2: fix use after free in jbd2_log_do_checkpoint()
+    - gfs2_meta: ->mount() can get NULL dev_name
+    - ext4: fix EXT4_IOC_SWAP_BOOT
+    - ext4: initialize retries variable in ext4_da_write_inline_data_begin()
+    - ext4: fix setattr project check in fssetxattr ioctl
+    - ext4: propagate error from dquot_initialize() in EXT4_IOC_FSSETXATTR
+    - ext4: fix use-after-free race in ext4_remount()'s error path
+    - selinux: fix mounting of cgroup2 under older policies
+    - HID: wacom: Work around HID descriptor bug in DTK-2451 and DTH-2452
+    - HID: hiddev: fix potential Spectre v1
+    - EDAC, amd64: Add Family 17h, models 10h-2fh support
+    - EDAC, {i7core,sb,skx}_edac: Fix uncorrected error counting
+    - EDAC, skx_edac: Fix logical channel intermediate decoding
+    - ARM: dts: dra7: Fix up unaligned access setting for PCIe EP
+    - PCI/ASPM: Fix link_state teardown on device removal
+    - PCI: Add Device IDs for Intel GPU "spurious interrupt" quirk
+    - signal/GenWQE: Fix sending of SIGKILL
+    - signal: Guard against negative signal numbers in copy_siginfo_from_user32
+    - crypto: lrw - Fix out-of bounds access on counter overflow
+    - crypto: tcrypt - fix ghash-generic speed test
+    - crypto: aesni - don't use GFP_ATOMIC allocation if the request doesn't cross
+      a page in gcm
+    - crypto: morus/generic - fix for big endian systems
+    - crypto: aegis/generic - fix for big endian systems
+    - crypto: speck - remove Speck
+    - mm: /proc/pid/smaps_rollup: fix NULL pointer deref in smaps_pte_range()
+    - userfaultfd: disable irqs when taking the waitqueue lock
+    - ima: fix showing large 'violations' or 'runtime_measurements_count'
+    - ima: open a new file instance if no read permissions
+    - hugetlbfs: dirty pages as they are added to pagecache
+    - mm/rmap: map_pte() was not handling private ZONE_DEVICE page properly
+    - mm/hmm: fix race between hmm_mirror_unregister() and mmu_notifier callback
+    - KVM: arm/arm64: Ensure only THP is candidate for adjustment
+    - KVM: arm64: Fix caching of host MDCR_EL2 value
+    - kbuild: fix kernel/bounds.c 'W=1' warning
+    - iio: ad5064: Fix regulator handling
+    - iio: adc: imx25-gcq: Fix leak of device_node in mx25_gcq_setup_cfgs()
+    - iio: adc: at91: fix acking DRDY irq on simple conversions
+    - iio: adc: at91: fix wrong channel number in triggered buffer mode
+    - w1: omap-hdq: fix missing bus unregister at removal
+    - smb3: allow stats which track session and share reconnects to be reset
+    - smb3: do not attempt cifs operation in smb3 query info error path
+    - smb3: on kerberos mount if server doesn't specify auth type use krb5
+    - printk: Fix panic caused by passing log_buf_len to command line
+    - genirq: Fix race on spurious interrupt detection
+    - tpm: fix response size validation in tpm_get_random()
+    - NFC: nfcmrvl_uart: fix OF child-node lookup
+    - NFSv4.1: Fix the r/wsize checking
+    - nfs: Fix a missed page unlock after pg_doio()
+    - nfsd: correctly decrement odstate refcount in error path
+    - nfsd: Fix an Oops in free_session()
+    - lockd: fix access beyond unterminated strings in prints
+    - dm ioctl: harden copy_params()'s copy_from_user() from malicious users
+    - dm zoned: fix metadata block ref counting
+    - dm zoned: fix various dmz_get_mblock() issues
+    - media: ov7670: make "xclk" clock optional
+    - fsnotify: Fix busy inodes during unmount
+    - powerpc64/module elfv1: Set opd addresses after module relocation
+    - powerpc/msi: Fix compile error on mpc83xx
+    - powerpc/tm: Fix HFSCR bit for no suspend case
+    - powerpc/64s/hash: Do not use PPC_INVALIDATE_ERAT on CPUs before POWER9
+    - MIPS: OCTEON: fix out of bounds array access on CN68XX
+    - rtc: ds1307: fix ds1339 wakealarm support
+    - rtc: cmos: Fix non-ACPI undefined reference to `hpet_rtc_interrupt'
+    - rtc: cmos: Remove the `use_acpi_alarm' module parameter for !ACPI
+    - power: supply: twl4030-charger: fix OF sibling-node lookup
+    - ocxl: Fix access to the AFU Descriptor Data
+    - iommu/arm-smmu: Ensure that page-table updates are visible before TLBI
+    - TC: Set DMA masks for devices
+    - net: bcmgenet: fix OF child-node lookup
+    - media: v4l2-tpg: fix kernel oops when enabling HFLIP and OSD
+    - Revert "media: dvbsky: use just one mutex for serializing device R/W ops"
+    - kgdboc: Passing ekgdboc to command line causes panic
+    - remoteproc: qcom: q6v5: Propagate EPROBE_DEFER
+    - media: cec: make cec_get_edid_spa_location() an inline function
+    - media: cec: integrate cec_validate_phys_addr() in cec-api.c
+    - xen: fix xen_qlock_wait()
+    - xen: remove size limit of privcmd-buf mapping interface
+    - xen-blkfront: fix kernel panic with negotiate_mq error path
+    - media: cec: add new tx/rx status bits to detect aborts/timeouts
+    - media: cec: fix the Signal Free Time calculation
+    - media: cec: forgot to cancel delayed work
+    - media: em28xx: use a default format if TRY_FMT fails
+    - media: tvp5150: avoid going past array on v4l2_querymenu()
+    - media: em28xx: fix input name for Terratec AV 350
+    - media: em28xx: make v4l2-compliance happier by starting sequence on zero
+    - media: em28xx: fix handler for vidioc_s_input()
+    - media: adv7604: when the EDID is cleared, unconfigure CEC as well
+    - media: adv7842: when the EDID is cleared, unconfigure CEC as well
+    - drm/mediatek: fix OF sibling-node lookup
+    - media: media colorspaces*.rst: rename AdobeRGB to opRGB
+    - media: replace ADOBERGB by OPRGB
+    - media: hdmi.h: rename ADOBE_RGB to OPRGB and ADOBE_YCC to OPYCC
+    - arm64: lse: remove -fcall-used-x0 flag
+    - rpmsg: smd: fix memory leak on channel create
+    - Cramfs: fix abad comparison when wrap-arounds occur
+    - ARM: dts: socfpga: Fix SDRAM node address for Arria10
+    - arm64: dts: stratix10: Correct System Manager register size
+    - soc: qcom: rmtfs-mem: Validate that scm is available
+    - soc/tegra: pmc: Fix child-node lookup
+    - selftests/ftrace: Fix synthetic event test to delete event correctly
+    - selftests/powerpc: Fix ptrace tm failure
+    - tracing: Return -ENOENT if there is no target synthetic event
+    - btrfs: qgroup: Avoid calling qgroup functions if qgroup is not enabled
+    - btrfs: Handle owner mismatch gracefully when walking up tree
+    - btrfs: locking: Add extra check in btrfs_init_new_buffer() to avoid deadlock
+    - btrfs: fix error handling in free_log_tree
+    - btrfs: fix error handling in btrfs_dev_replace_start
+    - btrfs: Enhance btrfs_trim_fs function to handle error better
+    - btrfs: Ensure btrfs_trim_fs can trim the whole filesystem
+    - btrfs: iterate all devices during trim, instead of fs_devices::alloc_list
+    - btrfs: don't attempt to trim devices that don't support it
+    - btrfs: keep trim from interfering with transaction commits
+    - btrfs: wait on caching when putting the bg cache
+    - Btrfs: don't clean dirty pages during buffered writes
+    - btrfs: release metadata before running delayed refs
+    - btrfs: protect space cache inode alloc with GFP_NOFS
+    - btrfs: reset max_extent_size on clear in a bitmap
+    - btrfs: make sure we create all new block groups
+    - Btrfs: fix warning when replaying log after fsync of a tmpfile
+    - Btrfs: fix wrong dentries after fsync of file that got its parent replaced
+    - btrfs: qgroup: Dirty all qgroups before rescan
+    - Btrfs: fix null pointer dereference on compressed write path error
+    - Btrfs: fix assertion on fsync of regular file when using no-holes feature
+    - Btrfs: fix deadlock when writing out free space caches
+    - btrfs: reset max_extent_size properly
+    - btrfs: set max_extent_size properly
+    - btrfs: don't use ctl->free_space for max_extent_size
+    - btrfs: only free reserved extent if we didn't insert it
+    - btrfs: fix insert_reserved error handling
+    - btrfs: don't run delayed_iputs in commit
+    - btrfs: move the dio_sem higher up the callchain
+    - Btrfs: fix use-after-free during inode eviction
+    - Btrfs: fix use-after-free when dumping free space
+    - net: sched: Remove TCA_OPTIONS from policy
+    - vt: fix broken display when running aptitude
+    - bpf: wait for running BPF programs when updating map-in-map
+    - vga_switcheroo: Fix missing gpu_bound call at audio client registration
+    - MD: fix invalid stored role for a disk - try2
+    - Linux 4.19.2
+
+  * [FEAT] Guest-dedicated Crypto Adapters (LP: #1787405)
+    - KVM: s390: vsie: simulate VCPU SIE entry/exit
+    - KVM: s390: introduce and use KVM_REQ_VSIE_RESTART
+    - KVM: s390: refactor crypto initialization
+    - s390: vfio-ap: base implementation of VFIO AP device driver
+    - s390: vfio-ap: register matrix device with VFIO mdev framework
+    - s390: vfio-ap: sysfs interfaces to configure adapters
+    - s390: vfio-ap: sysfs interfaces to configure domains
+    - s390: vfio-ap: sysfs interfaces to configure control domains
+    - s390: vfio-ap: sysfs interface to view matrix mdev matrix
+    - KVM: s390: interface to clear CRYCB masks
+    - s390: vfio-ap: implement mediated device open callback
+    - s390: vfio-ap: implement VFIO_DEVICE_GET_INFO ioctl
+    - s390: vfio-ap: zeroize the AP queues
+    - s390: vfio-ap: implement VFIO_DEVICE_RESET ioctl
+    - KVM: s390: Clear Crypto Control Block when using vSIE
+    - KVM: s390: vsie: Do the CRYCB validation first
+    - KVM: s390: vsie: Make use of CRYCB FORMAT2 clear
+    - KVM: s390: vsie: Allow CRYCB FORMAT-2
+    - KVM: s390: vsie: allow CRYCB FORMAT-1
+    - KVM: s390: vsie: allow CRYCB FORMAT-0
+    - KVM: s390: vsie: allow guest FORMAT-0 CRYCB on host FORMAT-1
+    - KVM: s390: vsie: allow guest FORMAT-1 CRYCB on host FORMAT-2
+    - KVM: s390: vsie: allow guest FORMAT-0 CRYCB on host FORMAT-2
+    - KVM: s390: device attrs to enable/disable AP interpretation
+    - KVM: s390: CPU model support for AP virtualization
+    - s390: doc: detailed specifications for AP virtualization
+    - KVM: s390: fix locking for crypto setting error path
+    - KVM: s390: Tracing APCB changes
+    - s390: vfio-ap: setup APCB mask using KVM dedicated function
+    - [Config:] Enable CONFIG_S390_AP_IOMMU and set CONFIG_VFIO_AP to module.
+
+  * Bypass of mount visibility through userns + mount propagation (LP: #1789161)
+    - mount: Retest MNT_LOCKED in do_umount
+    - mount: Don't allow copying MNT_UNBINDABLE|MNT_LOCKED mounts
+
+  *  CVE-2018-18955: nested user namespaces with more than five extents
+    incorrectly grant privileges over inode (LP: #1801924) // CVE-2018-18955
+    - userns: also map extents in the reverse map to kernel IDs
+
+  * kdump fail due to an IRQ storm (LP: #1797990)
+    - SAUCE: x86/PCI: Export find_cap() to be used in early PCI code
+    - SAUCE: x86/quirks: Add parameter to clear MSIs early on boot
+    - SAUCE: x86/quirks: Scan all busses for early PCI quirks
+
+  * Disable LPM for Raydium Touchscreens (LP: #1802248)
+    - USB: quirks: Add no-lpm quirk for Raydium touchscreens
+
+  * Power consumption during s2idle is higher than long idle(sk hynix)
+    (LP: #1801875)
+    - SAUCE: pci: prevent sk hynix nvme from entering D3
+    - SAUCE: nvme: add quirk to not call disable function when suspending
+
+  * Disco update: v4.19.1 upstream stable release (LP: #1801739)
+    - bridge: do not add port to router list when receives query with source
+      0.0.0.0
+    - ipv6/ndisc: Preserve IPv6 control buffer if protocol error handlers are
+      called
+    - net/mlx5e: fix csum adjustments caused by RXFCS
+    - net: sched: gred: pass the right attribute to gred_change_table_def()
+    - net: stmmac: Fix stmmac_mdio_reset() when building stmmac as modules
+    - net: udp: fix handling of CHECKSUM_COMPLETE packets
+    - Revert "net: simplify sock_poll_wait"
+    - rtnetlink: Disallow FDB configuration for non-Ethernet device
+    - vhost: Fix Spectre V1 vulnerability
+    - bonding: fix length of actor system
+    - openvswitch: Fix push/pop ethernet validation
+    - net/ipv6: Allow onlink routes to have a device mismatch if it is the default
+      route
+    - net/smc: fix smc_buf_unuse to use the lgr pointer
+    - mlxsw: spectrum_switchdev: Don't ignore deletions of learned MACs
+    - mlxsw: core: Fix devlink unregister flow
+    - net: drop skb on failure in ip_check_defrag()
+    - net: Properly unlink GRO packets on overflow.
+    - r8169: fix broken Wake-on-LAN from S5 (poweroff)
+    - Revert "be2net: remove desc field from be_eq_obj"
+    - sctp: check policy more carefully when getting pr status
+    - sparc64: Export __node_distance.
+    - sparc64: Make corrupted user stacks more debuggable.
+    - sparc64: Wire up compat getpeername and getsockname.
+    - net: bridge: remove ipv6 zero address check in mcast queries
+    - Linux 4.19.1
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.11-1ubuntu1, zfs to 0.7.11-3ubuntu1
+    - [Config] updateconfigs after 4.19.2 stable update
+    - [Config] Disable unneded options for s390
+    - [Config] Update annotations for 4.19
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 15 Nov 2018 09:55:37 -0800
+
+linux (4.19.0-4.5) disco; urgency=medium
+
+  * Add checksum offload and TSO support for HiNIC adapters (LP: #1800664)
+    - net-next/hinic: add checksum offload and TSO support
+
+  * [Bionic][Cosmic] Fix to ipmi to support vendor specific messages greater
+    than 255 bytes (LP: #1799794)
+    - ipmi:ssif: Add support for multi-part transmit messages > 2 parts
+
+  * Packaging resync (LP: #1786013)
+    - [Package] add support for specifying the primary makefile
+
+  * Update ENA driver to version 2.0.1K (LP: #1798182)
+    - net: ena: minor performance improvement
+    - net: ena: complete host info to match latest ENA spec
+    - net: ena: introduce Low Latency Queues data structures according to ENA spec
+    - net: ena: add functions for handling Low Latency Queues in ena_com
+    - net: ena: add functions for handling Low Latency Queues in ena_netdev
+    - net: ena: use CSUM_CHECKED device indication to report skb's checksum status
+    - net: ena: explicit casting and initialization, and clearer error handling
+    - net: ena: limit refill Rx threshold to 256 to avoid latency issues
+    - net: ena: change rx copybreak default to reduce kernel memory pressure
+    - net: ena: remove redundant parameter in ena_com_admin_init()
+    - net: ena: update driver version to 2.0.1
+    - net: ena: fix indentations in ena_defs for better readability
+    - net: ena: Fix Kconfig dependency on X86
+    - net: ena: enable Low Latency Queues
+    - net: ena: fix compilation error in xtensa architecture
+
+  * [Bionic][Cosmic]  ipmi: Fix timer race with module unload (LP: #1799281)
+    - ipmi: Fix timer race with module unload
+
+  * Overlayfs in user namespace leaks directory content of inaccessible
+    directories (LP: #1793458) // CVE-2018-6559
+    - SAUCE: overlayfs: ensure mounter privileges when reading directories
+
+  * not able to unwind the stack from within __kernel_clock_gettime in the Linux
+    vDSO (LP: #1797963)
+    - powerpc/vdso: Correct call frame information
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Don't print secure boot state
+      from the efi stub"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Make get_cert_list() use
+      efi_status_to_str() to print error messages."
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err()."
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Make get_cert_list() not complain
+      about cert lists that aren't present."
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable
+      to be suppressed"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI
+      Secure Boot"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add EFI signature data types"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time
+      addition of keys to secondary keyring"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in
+      secure boot mode"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to
+      indicate secure boot mode"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Copy secure_boot flag in boot params
+      across kexec reboot"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down perf"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) bpf: Restrict kernel image access
+      functions when the kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down kprobes"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down /proc/kcore"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the
+      testmmiotrace module"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down module params that specify
+      hardware parameters (eg. ioport)"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Lock down TIOCSSERIAL"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) acpi: Disable APEI error injection if
+      the kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) acpi: Disable ACPI table override if
+      the kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param
+      when the kernel has been locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) ACPI: Limit access to custom_method
+      when the kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) x86: Lock down IO port access when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) PCI: Lock down BAR access when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is
+      locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) hibernate: Disable when the kernel is
+      locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Enforce module signatures if the
+      kernel is locked down"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Add a SysRq option to lift kernel
+      lockdown"
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) Add the ability to lock down access to
+      the running kernel image"
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) efi: Add EFI signature data types
+    - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) efi/x86: Call efi_parse_options() from efi_main()
+    - SAUCE: (efi-lockdown) Fix for module sig verification
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) module: remove support for having IMA validate modules
+    - [Packaging] generate Vcs-Git url from changelog
+    - [Config] CONFIG_SCSI_MQ_DEFAULT=y
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 02 Nov 2018 14:22:55 -0500
+
+linux (4.19.0-3.4) cosmic; urgency=medium
+
+  * Support Edge Gateway's Bluetooth LED (LP: #1798332)
+    - SAUCE: Bluetooth: Support for LED on Edge Gateways
+
+  * Support Edge Gateway's WIFI LED (LP: #1798330)
+    - SAUCE: mwifiex: Switch WiFi LED state according to the device status
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.19
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 22 Oct 2018 09:13:39 -0500
+
+linux (4.19.0-2.3) cosmic; urgency=medium
+
+  * fscache: bad refcounting in fscache_op_complete leads to OOPS (LP: #1797314)
+    - SAUCE: fscache: Fix race in decrementing refcount of op->npages
+
+  * Provide mode where all vCPUs on a core must be the same VM (LP: #1792957)
+    - KVM: PPC: Book3S HV: Provide mode where all vCPUs on a core must be the same
+      VM
+
+  * The front MIC can't work on the Lenovo M715 (LP: #1797292)
+    - ALSA: hda/realtek - Fix the problem of the front MIC on the Lenovo M715
+
+  * arm64: snapdragon: WARNING: CPU: 0 PID: 1 at drivers/irqchip/irq-gic.c:1016
+    gic_irq_domain_translate (LP: #1797143)
+    - SAUCE: arm64: dts: msm8916: camms: fix gic_irq_domain_translate warnings
+
+  * Dell new AIO requires a new uart backlight driver (LP: #1727235)
+    - SAUCE: platform/x86: dell-uart-backlight: new backlight driver for DELL AIO
+    - updateconfigs for Dell UART backlight driver
+
+  * Please make CONFIG_PWM_LPSS_PCI and CONFIG_PWM_LPSS_PLATFORM built in to
+    make brightness adjustment working on various BayTrail/CherryTrail-based
+    devices (LP: #1783964)
+    - [Config]: Make PWM_LPSS_* built-in
+
+  * check and fix zkey required kernel modules locations in debs, udebs, and
+    initramfs (LP: #1794346)
+    - [Config] add s390 crypto modules to crypt-modules udeb
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_VBOXGUEST=n
+    - ubuntu: vbox -- update to 5.2.18-dfsg-2
+    - ubuntu: enable vbox build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.19-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 15 Oct 2018 10:52:04 -0500
+
+linux (4.19.0-1.2) cosmic; urgency=medium
+
+  * Page leaking in cachefiles_read_backing_file while vmscan is active
+    (LP: #1793430)
+    - SAUCE: cachefiles: Page leaking in cachefiles_read_backing_file while vmscan
+      is active
+
+  * SRU: Enable middle button of touchpad on ThinkPad P72 (LP: #1793463)
+    - Input: elantech - enable middle button of touchpad on ThinkPad P72
+
+  * Improvements to the kernel source package preparation (LP: #1793461)
+    - [Packaging] startnewrelease: add support for backport kernels
+
+  * Fix unusable NVIDIA GPU after S3 (LP: #1793338)
+    - SAUCE: PCI: Reprogram bridge prefetch registers on resume
+
+  * Error reported when creating ZFS pool with "-t" option, despite successful
+    pool creation (LP: #1769937)
+    - SAUCE: (noup) Update zfs to 0.7.9-3ubuntu6
+
+  * device hotplug of vfio devices can lead to deadlock in vfio_pci_release
+    (LP: #1792099)
+    - SAUCE: vfio -- release device lock before userspace requests
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] retpoline -- fix temporary filenaming
+    - CONFIG_BCH_CONST_PARAMS=n
+    - Packaging: final-checks: remove trailing backport suffix
+    - SAUCE: import aufs driver
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.19-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 25 Sep 2018 16:32:24 -0500
+
+linux (4.19.0-0.1) cosmic; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu -- disable vbox build
+    - Disable zfs build
+    - SAUCE: Import aufs driver
+    - Update dropped.txt
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.19-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 13 Sep 2018 07:54:47 -0500
+
+linux (4.19.0-0.0) cosmic; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 13 Sep 2018 06:44:09 -0500
+
+linux (4.18.0-8.9) cosmic; urgency=medium
+
+  * linux: 4.18.0-8.9 -proposed tracker (LP: #1791663)
+
+  * Cosmic update to v4.18.7 stable release (LP: #1791660)
+    - rcu: Make expedited GPs handle CPU 0 being offline
+    - net: 6lowpan: fix reserved space for single frames
+    - net: mac802154: tx: expand tailroom if necessary
+    - 9p/net: Fix zero-copy path in the 9p virtio transport
+    - spi: davinci: fix a NULL pointer dereference
+    - spi: pxa2xx: Add support for Intel Ice Lake
+    - spi: spi-fsl-dspi: Fix imprecise abort on VF500 during probe
+    - spi: cadence: Change usleep_range() to udelay(), for atomic context
+    - mmc: block: Fix unsupported parallel dispatch of requests
+    - mmc: renesas_sdhi_internal_dmac: mask DMAC interrupts
+    - mmc: renesas_sdhi_internal_dmac: fix #define RST_RESERVED_BITS
+    - readahead: stricter check for bdi io_pages
+    - block: fix infinite loop if the device loses discard capability
+    - block: blk_init_allocated_queue() set q->fq as NULL in the fail case
+    - block: really disable runtime-pm for blk-mq
+    - blkcg: Introduce blkg_root_lookup()
+    - block: Introduce blk_exit_queue()
+    - block: Ensure that a request queue is dissociated from the cgroup controller
+    - apparmor: fix bad debug check in apparmor_secid_to_secctx()
+    - dma-buf: Move BUG_ON from _add_shared_fence to _add_shared_inplace
+    - libertas: fix suspend and resume for SDIO connected cards
+    - media: Revert "[media] tvp5150: fix pad format frame height"
+    - mailbox: xgene-slimpro: Fix potential NULL pointer dereference
+    - Replace magic for trusting the secondary keyring with #define
+    - Fix kexec forbidding kernels signed with keys in the secondary keyring to
+      boot
+    - powerpc/fadump: handle crash memory ranges array index overflow
+    - powerpc/64s: Fix page table fragment refcount race vs speculative references
+    - powerpc/pseries: Fix endianness while restoring of r3 in MCE handler.
+    - powerpc/pkeys: Give all threads control of their key permissions
+    - powerpc/pkeys: Deny read/write/execute by default
+    - powerpc/pkeys: key allocation/deallocation must not change pkey registers
+    - powerpc/pkeys: Save the pkey registers before fork
+    - powerpc/pkeys: Fix calculation of total pkeys.
+    - powerpc/pkeys: Preallocate execute-only key
+    - powerpc/nohash: fix pte_access_permitted()
+    - powerpc64/ftrace: Include ftrace.h needed for enable/disable calls
+    - powerpc/powernv/pci: Work around races in PCI bridge enabling
+    - cxl: Fix wrong comparison in cxl_adapter_context_get()
+    - IB/mlx5: Honor cnt_set_id_valid flag instead of set_id
+    - IB/mlx5: Fix leaking stack memory to userspace
+    - IB/srpt: Fix srpt_cm_req_recv() error path (1/2)
+    - IB/srpt: Fix srpt_cm_req_recv() error path (2/2)
+    - IB/srpt: Support HCAs with more than two ports
+    - overflow.h: Add arithmetic shift helper
+    - RDMA/mlx5: Fix shift overflow in mlx5_ib_create_wq
+    - ib_srpt: Fix a use-after-free in srpt_close_ch()
+    - ib_srpt: Fix a use-after-free in __srpt_close_all_ch()
+    - RDMA/rxe: Set wqe->status correctly if an unexpected response is received
+    - 9p: fix multiple NULL-pointer-dereferences
+    - fs/9p/xattr.c: catch the error of p9_client_clunk when setting xattr failed
+    - 9p/virtio: fix off-by-one error in sg list bounds check
+    - net/9p/client.c: version pointer uninitialized
+    - net/9p/trans_fd.c: fix race-condition by flushing workqueue before the
+      kfree()
+    - dm integrity: change 'suspending' variable from bool to int
+    - dm thin: stop no_space_timeout worker when switching to write-mode
+    - dm cache metadata: save in-core policy_hint_size to on-disk superblock
+    - dm cache metadata: set dirty on all cache blocks after a crash
+    - dm crypt: don't decrease device limits
+    - dm writecache: fix a crash due to reading past end of dirty_bitmap
+    - uart: fix race between uart_put_char() and uart_shutdown()
+    - Drivers: hv: vmbus: Fix the offer_in_progress in vmbus_process_offer()
+    - Drivers: hv: vmbus: Reset the channel callback in vmbus_onoffer_rescind()
+    - iio: sca3000: Fix missing return in switch
+    - iio: ad9523: Fix displayed phase
+    - iio: ad9523: Fix return value for ad952x_store()
+    - extcon: Release locking when sending the notification of connector state
+    - eventpoll.h: wrap casts in () properly
+    - vmw_balloon: fix inflation of 64-bit GFNs
+    - vmw_balloon: do not use 2MB without batching
+    - vmw_balloon: VMCI_DOORBELL_SET does not check status
+    - vmw_balloon: fix VMCI use when balloon built into kernel
+    - rtc: omap: fix resource leak in registration error path
+    - rtc: omap: fix potential crash on power off
+    - tracing: Do not call start/stop() functions when tracing_on does not change
+    - tracing/blktrace: Fix to allow setting same value
+    - printk/tracing: Do not trace printk_nmi_enter()
+    - livepatch: Validate module/old func name length
+    - uprobes: Use synchronize_rcu() not synchronize_sched()
+    - mfd: hi655x: Fix regmap area declared size for hi655x
+    - ovl: fix wrong use of impure dir cache in ovl_iterate()
+    - ACPICA: AML Parser: skip opcodes that open a scope upon parse failure
+    - ACPICA: Clear status of all events when entering sleep states
+    - drivers/block/zram/zram_drv.c: fix bug storing backing_dev
+    - sched: idle: Avoid retaining the tick when it has been stopped
+    - cpuidle: menu: Handle stopped tick more aggressively
+    - cpufreq: governor: Avoid accessing invalid governor_data
+    - PM / sleep: wakeup: Fix build error caused by missing SRCU support
+    - ALSA: ac97: fix device initialization in the compat layer
+    - ALSA: ac97: fix check of pm_runtime_get_sync failure
+    - ALSA: ac97: fix unbalanced pm_runtime_enable
+    - i2c: designware: Re-init controllers with pm_disabled set on resume
+    - KVM: VMX: fixes for vmentry_l1d_flush module parameter
+    - KVM: PPC: Book3S: Fix guest DMA when guest partially backed by THP pages
+    - xtensa: limit offsets in __loop_cache_{all,page}
+    - xtensa: increase ranges in ___invalidate_{i,d}cache_all
+    - block, bfq: return nbytes and not zero from struct cftype .write() method
+    - pnfs/blocklayout: off by one in bl_map_stripe()
+    - nfsd: fix leaked file lock with nfs exported overlayfs
+    - NFSv4 client live hangs after live data migration recovery
+    - NFSv4: Fix locking in pnfs_generic_recover_commit_reqs
+    - NFSv4: Fix a sleep in atomic context in nfs4_callback_sequence()
+    - ARM: tegra: Fix Tegra30 Cardhu PCA954x reset
+    - ARM: dts: am57xx-idk: Enable dual role for USB2 port
+    - pwm: omap-dmtimer: Return -EPROBE_DEFER if no dmtimer platform data
+    - mm/tlb: Remove tlb_remove_table() non-concurrent condition
+    - iommu/ipmmu-vmsa: Don't register as BUS IOMMU if machine doesn't have IPMMU-
+      VMSA
+    - iommu/vt-d: Add definitions for PFSID
+    - iommu/vt-d: Fix dev iotlb pfsid use
+    - sys: don't hold uts_sem while accessing userspace memory
+    - userns: move user access out of the mutex
+    - ubifs: Fix memory leak in lprobs self-check
+    - Revert "UBIFS: Fix potential integer overflow in allocation"
+    - ubifs: Check data node size before truncate
+    - ubifs: xattr: Don't operate on deleted inodes
+    - ubifs: Fix directory size calculation for symlinks
+    - ubifs: Fix synced_i_size calculation for xattr inodes
+    - pwm: tiehrpwm: Don't use emulation mode bits to control PWM output
+    - pwm: tiehrpwm: Fix disabling of output of PWMs
+    - fb: fix lost console when the user unplugs a USB adapter
+    - udlfb: fix semaphore value leak
+    - udlfb: fix display corruption of the last line
+    - udlfb: don't switch if we are switching to the same videomode
+    - udlfb: set optimal write delay
+    - udlfb: make a local copy of fb_ops
+    - udlfb: handle allocation failure
+    - udlfb: set line_length in dlfb_ops_set_par
+    - getxattr: use correct xattr length
+    - libnvdimm: Use max contiguous area for namespace size
+    - libnvdimm: fix ars_status output length calculation
+    - bcache: release dc->writeback_lock properly in bch_writeback_thread()
+    - kconfig: fix "Can't open ..." in parallel build
+    - perf auxtrace: Fix queue resize
+    - crypto: vmx - Fix sleep-in-atomic bugs
+    - crypto: aesni - Use unaligned loads from gcm_context_data
+    - crypto: arm64/sm4-ce - check for the right CPU feature bit
+    - crypto: caam - fix DMA mapping direction for RSA forms 2 & 3
+    - crypto: caam/jr - fix descriptor DMA unmapping
+    - crypto: caam/qi - fix error path in xts setkey
+    - fs/quota: Fix spectre gadget in do_quotactl
+    - udf: Fix mounting of Win7 created UDF filesystems
+    - cpuidle: menu: Retain tick when shallow state is selected
+    - arm64: mm: always enable CONFIG_HOLES_IN_ZONE
+    - Linux 4.18.7
+
+  * CVE-2017-5715
+    - s390: detect etoken facility
+    - KVM: s390: add etoken support for guests
+
+  * Missing Intel GPU pci-id's (LP: #1789924)
+    - drm/i915/whl: Introducing Whiskey Lake platform
+    - drm/i915/aml: Introducing Amber Lake platform
+    - drm/i915/cfl: Add a new CFL PCI ID.
+
+  * [18.10 FEAT] Add kernel config options for SMC-R/D (LP: #1789934)
+    - s390/ism: add device driver for internal shared memory
+    - CONFIG_ISM=y for s390
+
+  * Cosmic update to v4.18.6 stable release (LP: #1791105)
+    - PATCH scripts/kernel-doc
+    - scripts/kernel-doc: Escape all literal braces in regexes
+    - scsi: libsas: dynamically allocate and free ata host
+    - xprtrdma: Fix disconnect regression
+    - mei: don't update offset in write
+    - cifs: add missing support for ACLs in SMB 3.11
+    - CIFS: fix uninitialized ptr deref in smb2 signing
+    - cifs: add missing debug entries for kconfig options
+    - cifs: use a refcount to protect open/closing the cached file handle
+    - cifs: check kmalloc before use
+    - smb3: enumerating snapshots was leaving part of the data off end
+    - smb3: Do not send SMB3 SET_INFO if nothing changed
+    - smb3: don't request leases in symlink creation and query
+    - smb3: fill in statfs fsid and correct namelen
+    - btrfs: use correct compare function of dirty_metadata_bytes
+    - btrfs: don't leak ret from do_chunk_alloc
+    - Btrfs: fix mount failure after fsync due to hard link recreation
+    - Btrfs: fix btrfs_write_inode vs delayed iput deadlock
+    - Btrfs: fix send failure when root has deleted files still open
+    - Btrfs: send, fix incorrect file layout after hole punching beyond eof
+    - hwmon: (k10temp) 27C Offset needed for Threadripper2
+    - bpf, arm32: fix stack var offset in jit
+    - regulator: arizona-ldo1: Use correct device to get enable GPIO
+    - iommu/arm-smmu: Error out only if not enough context interrupts
+    - printk: Split the code for storing a message into the log buffer
+    - printk: Create helper function to queue deferred console handling
+    - printk/nmi: Prevent deadlock when accessing the main log buffer in NMI
+    - kprobes/arm64: Fix %p uses in error messages
+    - arm64: Fix mismatched cache line size detection
+    - arm64: Handle mismatched cache type
+    - arm64: mm: check for upper PAGE_SHIFT bits in pfn_valid()
+    - arm64: dts: rockchip: corrected uart1 clock-names for rk3328
+    - KVM: arm/arm64: Fix potential loss of ptimer interrupts
+    - KVM: arm/arm64: Fix lost IRQs from emulated physcial timer when blocked
+    - KVM: arm/arm64: Skip updating PMD entry if no change
+    - KVM: arm/arm64: Skip updating PTE entry if no change
+    - s390/kvm: fix deadlock when killed by oom
+    - perf kvm: Fix subcommands on s390
+    - stop_machine: Reflow cpu_stop_queue_two_works()
+    - stop_machine: Atomically queue and wake stopper threads
+    - ext4: check for NUL characters in extended attribute's name
+    - ext4: use ext4_warning() for sb_getblk failure
+    - ext4: sysfs: print ext4_super_block fields as little-endian
+    - ext4: reset error code in ext4_find_entry in fallback
+    - ext4: fix race when setting the bitmap corrupted flag
+    - x86/gpu: reserve ICL's graphics stolen memory
+    - platform/x86: wmi: Do not mix pages and kmalloc
+    - platform/x86: ideapad-laptop: Apply no_hw_rfkill to Y20-15IKBM, too
+    - mm: move tlb_table_flush to tlb_flush_mmu_free
+    - mm/tlb, x86/mm: Support invalidating TLB caches for RCU_TABLE_FREE
+    - x86/speculation/l1tf: Fix overflow in l1tf_pfn_limit() on 32bit
+    - x86/speculation/l1tf: Fix off-by-one error when warning that system has too
+      much RAM
+    - x86/speculation/l1tf: Suggest what to do on systems with too much RAM
+    - x86/vdso: Fix vDSO build if a retpoline is emitted
+    - x86/process: Re-export start_thread()
+    - KVM: x86: ensure all MSRs can always be KVM_GET/SET_MSR'd
+    - KVM: x86: SVM: Call x86_spec_ctrl_set_guest/host() with interrupts disabled
+    - fuse: Don't access pipe->buffers without pipe_lock()
+    - fuse: fix initial parallel dirops
+    - fuse: fix double request_end()
+    - fuse: fix unlocked access to processing queue
+    - fuse: umount should wait for all requests
+    - fuse: Fix oops at process_init_reply()
+    - fuse: Add missed unlock_page() to fuse_readpages_fill()
+    - lib/vsprintf: Do not handle %pO[^F] as %px
+    - udl-kms: change down_interruptible to down
+    - udl-kms: handle allocation failure
+    - udl-kms: fix crash due to uninitialized memory
+    - udl-kms: avoid division
+    - b43legacy/leds: Ensure NUL-termination of LED name string
+    - b43/leds: Ensure NUL-termination of LED name string
+    - ASoC: dpcm: don't merge format from invalid codec dai
+    - ASoC: zte: Fix incorrect PCM format bit usages
+    - ASoC: sirf: Fix potential NULL pointer dereference
+    - ASoC: wm_adsp: Correct DSP pointer for preloader control
+    - soc: qcom: rmtfs-mem: fix memleak in probe error paths
+    - pinctrl: freescale: off by one in imx1_pinconf_group_dbg_show()
+    - scsi: qla2xxx: Fix stalled relogin
+    - x86/vdso: Fix lsl operand order
+    - x86/nmi: Fix NMI uaccess race against CR3 switching
+    - x86/irqflags: Mark native_restore_fl extern inline
+    - x86/spectre: Add missing family 6 check to microcode check
+    - x86/speculation/l1tf: Increase l1tf memory limit for Nehalem+
+    - hwmon: (nct6775) Fix potential Spectre v1
+    - x86/entry/64: Wipe KASAN stack shadow before rewind_stack_do_exit()
+    - x86: Allow generating user-space headers without a compiler
+    - s390/mm: fix addressing exception after suspend/resume
+    - s390/lib: use expoline for all bcr instructions
+    - s390: fix br_r1_trampoline for machines without exrl
+    - s390/qdio: reset old sbal_state flags
+    - s390/numa: move initial setup of node_to_cpumask_map
+    - s390/purgatory: Fix crash with expoline enabled
+    - s390/purgatory: Add missing FORCE to Makefile targets
+    - kprobes: Show blacklist addresses as same as kallsyms does
+    - kprobes: Replace %p with other pointer types
+    - kprobes/arm: Fix %p uses in error messages
+    - kprobes: Make list and blacklist root user read only
+    - MIPS: Correct the 64-bit DSP accumulator register size
+    - MIPS: memset.S: Fix byte_fixup for MIPSr6
+    - MIPS: Always use -march=<arch>, not -<arch> shortcuts
+    - MIPS: Change definition of cpu_relax() for Loongson-3
+    - MIPS: lib: Provide MIPS64r6 __multi3() for GCC < 7
+    - tpm: Return the actual size when receiving an unsupported command
+    - tpm: separate cmd_ready/go_idle from runtime_pm
+    - scsi: mpt3sas: Fix calltrace observed while running IO & reset
+    - scsi: mpt3sas: Fix _transport_smp_handler() error path
+    - scsi: sysfs: Introduce sysfs_{un,}break_active_protection()
+    - scsi: core: Avoid that SCSI device removal through sysfs triggers a deadlock
+    - iscsi target: fix session creation failure handling
+    - mtd: rawnand: hynix: Use ->exec_op() in hynix_nand_reg_write_op()
+    - mtd: rawnand: fsmc: Stop using chip->read_buf()
+    - mtd: rawnand: marvell: add suspend and resume hooks
+    - mtd: rawnand: qcom: wait for desc completion in all BAM channels
+    - clk: rockchip: fix clk_i2sout parent selection bits on rk3399
+    - clk: npcm7xx: fix memory allocation
+    - PM / clk: signedness bug in of_pm_clk_add_clks()
+    - power: generic-adc-battery: fix out-of-bounds write when copying channel
+      properties
+    - power: generic-adc-battery: check for duplicate properties copied from iio
+      channels
+    - watchdog: Mark watchdog touch functions as notrace
+    - cdrom: Fix info leak/OOB read in cdrom_ioctl_drive_status
+    - x86/dumpstack: Don't dump kernel memory based on usermode RIP
+    - Linux 4.18.6
+    - updateconfigs after v4.18.6 stable update
+
+  * random oopses on s390 systems using NVMe devices (LP: #1790480)
+    - s390/pci: fix out of bounds access during irq setup
+
+  * [18.10 FEAT] zcrypt DD: introduce APQN tags to support deterministic driver
+    binding (LP: #1784331)
+    - s390/zcrypt: code beautify
+    - s390/zcrypt: AP bus support for alternate driver(s)
+    - s390/zcrypt: hex string mask improvements for apmask and aqmask.
+
+  * performance drop with ATS enabled (LP: #1788097)
+    - powerpc/powernv: Fix concurrency issue with npu->mmio_atsd_usage
+
+  * Fix MCE handling for user access of poisoned device-dax mapping
+    (LP: #1774366)
+    - device-dax: Convert to vmf_insert_mixed and vm_fault_t
+    - device-dax: Enable page_mapping()
+    - device-dax: Set page->index
+    - filesystem-dax: Set page->index
+    - mm, madvise_inject_error: Disable MADV_SOFT_OFFLINE for ZONE_DEVICE pages
+    - mm, dev_pagemap: Do not clear ->mapping on final put
+    - mm, madvise_inject_error: Let memory_failure() optionally take a page
+      reference
+    - mm, memory_failure: Collect mapping size in collect_procs()
+    - filesystem-dax: Introduce dax_lock_mapping_entry()
+    - mm, memory_failure: Teach memory_failure() about dev_pagemap pages
+    - x86/mm/pat: Prepare {reserve, free}_memtype() for "decoy" addresses
+    - x86/memory_failure: Introduce {set, clear}_mce_nospec()
+    - libnvdimm, pmem: Restore page attributes when clearing errors
+
+  * Reconcile hns3 SAUCE patches with upstream (LP: #1787477)
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix comments for
+      hclge_get_ring_chain_from_mbx"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for using wrong mask and
+      shift in hclge_get_ring_chain_from_mbx"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for reset_level default
+      assignment probelm"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unnecessary ring
+      configuration operation while resetting"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix return value error in
+      hns3_reset_notify_down_enet"
+    - Revert "UBUNTU: SAUCE: net: hns3: Fix for phy link issue when using marvell
+      phy driver"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: separate roce from nic when
+      resetting"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: correct reset event status
+      register"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: prevent to request reset
+      frequently"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: reset net device with rtnl_lock"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify the order of initializeing
+      command queue register"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: prevent sending command during
+      global or core reset"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Use roce handle when calling roce
+      callback function"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove the warning when clear
+      reset cause"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix get_vector ops in
+      hclgevf_main module"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix warning bug when doing lp
+      selftest"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add configure for mac minimal
+      frame size"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for mailbox message truncated
+      problem"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for l4 checksum offload bug"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for waterline not setting
+      correctly"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix for mac pause not disable in
+      pfc mode"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix tc setup when netdev is first
+      up"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add calling roce callback
+      function when link status change"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: optimize the process of notifying
+      roce client"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add pf reset for hip08 RoCE"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: Add SPDX tags to hns3 driver"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused struct member and
+      definition"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix mislead parameter name"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify inconsistent bit mask
+      macros"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: use decimal for bit offset
+      macros"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: fix unreasonable code comments"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove extra space and brackets"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: standardize the handle of return
+      value"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some redundant
+      assignments"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: modify hnae_ to hnae3_"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: use dma_zalloc_coherent instead
+      of kzalloc/dma_map_single"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: give default option while
+      dependency HNS3 set"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some unused members of
+      some structures"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove a redundant
+      hclge_cmd_csq_done"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: using modulo for cyclic counters
+      in hclge_cmd_send"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: simplify hclge_cmd_csq_clean"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove some redundant
+      assignments"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove useless code in
+      hclge_cmd_send"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused
+      hclge_ring_to_dma_dir"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: use lower_32_bits and
+      upper_32_bits"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove back in struct hclge_hw"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: add unlikely for error check"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove the Redundant put_vector
+      in hns3_client_uninit"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: print the ret value in error
+      information"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: extraction an interface for state
+      state init|uninit"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove unused head file in
+      hnae3.c"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: add l4_type check for both ipv4
+      and ipv6"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: add vector status check before
+      free vector"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: rename the interface for
+      init_client_instance and uninit_client_instance"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: remove hclge_get_vector_index
+      from hclge_bind_ring_with_vector"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: RX BD information valid only in
+      last BD except VLD bit and buffer size"
+    - Revert "UBUNTU: SAUCE: {topost} net: hns3: add support for serdes loopback
+      selftest"
+    - net: hns3: Updates RX packet info fetch in case of multi BD
+    - net: hns3: remove hclge_get_vector_index from hclge_bind_ring_with_vector
+    - net: hns3: rename the interface for init_client_instance and
+      uninit_client_instance
+    - net: hns3: add vector status check before free vector
+    - net: hns3: add l4_type check for both ipv4 and ipv6
+    - net: hns3: add unlikely for error check
+    - net: hns3: remove unused head file in hnae3.c
+    - net: hns3: extraction an interface for state init|uninit
+    - net: hns3: print the ret value in error information
+    - net: hns3: remove the Redundant put_vector in hns3_client_uninit
+    - net: hns3: remove back in struct hclge_hw
+    - net: hns3: use lower_32_bits and upper_32_bits
+    - net: hns3: remove unused hclge_ring_to_dma_dir
+    - net: hns3: remove useless code in hclge_cmd_send
+    - net: hns3: remove some redundant assignments
+    - net: hns3: simplify hclge_cmd_csq_clean
+    - net: hns3: remove a redundant hclge_cmd_csq_done
+    - net: hns3: remove some unused members of some structures
+    - net: hns3: give default option while dependency HNS3 set
+    - net: hns3: use dma_zalloc_coherent instead of kzalloc/dma_map_single
+    - net: hns3: modify hnae_ to hnae3_
+    - net: hns3: Fix tc setup when netdev is first up
+    - net: hns3: Fix for mac pause not disable in pfc mode
+    - net: hns3: Fix for waterline not setting correctly
+    - net: hns3: Fix for l4 checksum offload bug
+    - net: hns3: Fix for mailbox message truncated problem
+    - net: hns3: Add configure for mac minimal frame size
+    - net: hns3: Fix warning bug when doing lp selftest
+    - net: hns3: Fix get_vector ops in hclgevf_main module
+    - net: hns3: Remove the warning when clear reset cause
+    - net: hns3: Prevent sending command during global or core reset
+    - net: hns3: Modify the order of initializing command queue register
+    - net: hns3: Reset net device with rtnl_lock
+    - net: hns3: Prevent to request reset frequently
+    - net: hns3: Correct reset event status register
+    - net: hns3: Fix return value error in hns3_reset_notify_down_enet
+    - net: hns3: remove unnecessary ring configuration operation while resetting
+    - net: hns3: Fix for reset_level default assignment probelm
+    - net: hns3: Fix for using wrong mask and shift in
+      hclge_get_ring_chain_from_mbx
+    - net: hns3: Fix comments for hclge_get_ring_chain_from_mbx
+    - net: hns3: Remove some redundant assignments
+    - net: hns3: Standardize the handle of return value
+    - net: hns3: Remove extra space and brackets
+    - net: hns3: Correct unreasonable code comments
+    - net: hns3: Use decimal for bit offset macros
+    - net: hns3: Modify inconsistent bit mask macros
+    - net: hns3: Fix misleading parameter name
+    - net: hns3: Remove unused struct member and definition
+    - net: hns3: Add SPDX tags to HNS3 PF driver
+    - net: hns3: Add support for serdes loopback selftest
+    - net: hns3: Fix for phy link issue when using marvell phy driver
+
+  * [Regression] kernel crashdump fails on arm64 (LP: #1786878)
+    - arm64: export memblock_reserve()d regions via /proc/iomem
+    - drivers: acpi: add dependency of EFI for arm64
+    - efi/arm: preserve early mapping of UEFI memory map longer for BGRT
+    - efi/arm: map UEFI memory map even w/o runtime services enabled
+    - arm64: acpi: fix alignment fault in accessing ACPI
+    - [Config] CONFIG_ARCH_SUPPORTS_ACPI=y
+    - arm64: fix ACPI dependencies
+    - ACPI: fix menuconfig presentation of ACPI submenu
+
+  * TB 16 issue on Dell Lattitude 7490 with large amount of data (LP: #1785780)
+    - r8152: disable RX aggregation on new Dell TB16 dock
+
+  * Support Power Management for Thunderbolt Controller  (LP: #1789358)
+    - thunderbolt: Use 64-bit DMA mask if supported by the platform
+    - thunderbolt: Do not unnecessarily call ICM get route
+    - thunderbolt: No need to take tb->lock in domain suspend/complete
+    - thunderbolt: Use correct ICM commands in system suspend
+    - thunderbolt: Add support for runtime PM
+
+  * Enable AMD PCIe MP2 for AMDI0011 (LP: #1773940)
+    - SAUCE: i2c:amd I2C Driver based on PCI Interface for upcoming platform
+    - SAUCE: i2c:amd move out pointer in union i2c_event_base
+    - SAUCE: i2c:amd Depends on ACPI
+    - [Config] i2c: CONFIG_I2C_AMD_MP2=y on x86
+
+  * Microphone cannot be detected with front panel audio combo jack on HP Z8-G4
+    machine (LP: #1789145)
+    - ALSA: hda/realtek - Fix HP Headset Mic can't record
+
+  * Please enable CONFIG_PAGE_POISONING (LP: #1783651)
+    - [Config] Enable CONFIG_PAGE_POISONING configs
+
+  * Tango platform uses __initcall without further checks (LP: #1787945)
+    - [Config] disable ARCH_TANGO
+
+  * [18.10 FEAT] SMC-Direct (LP: #1786902)
+    - net/smc: determine port attributes independent from pnet table
+    - net/smc: add pnetid support
+    - net/smc: add base infrastructure for SMC-D and ISM
+    - net/smc: add pnetid support for SMC-D and ISM
+    - net/smc: add SMC-D support in CLC messages
+    - net/smc: add SMC-D support in data transfer
+    - net/smc: add SMC-D support in af_smc
+    - net/smc: add SMC-D diag support
+    - net/smc: provide smc mode in smc_diag.c
+    - net/smc: eliminate cursor read and write calls
+    - net/smc: add function to get link group from link
+    - net/smc: use DECLARE_BITMAP for rtokens_used_mask
+    - net/smc: remove local variable page in smc_rx_splice()
+    - net/smc: Remove a WARN_ON() statement
+    - net/smc: Simplify ib_post_(send|recv|srq_recv)() calls
+    - net/smc: fewer parameters for smc_llc_send_confirm_link()
+    - net/smc: use correct vlan gid of RoCE device
+    - net/smc: provide fallback reason code
+    - net/smc: improve delete link processing
+    - net: simplify sock_poll_wait
+    - net/smc: send response to test link signal
+
+  * Miscellaneous Ubuntu changes
+    - [Config] update annotations for CONFIG_CRYPTO_SPECK_NEON
+    - [Config] fix up annotatios for CONFIG_CRYPTO_SPECK
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 10 Sep 2018 07:08:38 -0500
+
+linux (4.18.0-7.8) cosmic; urgency=medium
+
+  * linux: 4.18.0-7.8 -proposed tracker (LP: #1789459)
+
+  * pmtu.sh fails on 4.18 kernel (LP: #1789436)
+    - SAUCE: Revert "vti6: fix PMTU caching and reporting on xmit"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 Aug 2018 11:08:51 -0500
+
+linux (4.18.0-6.7) cosmic; urgency=medium
+
+  * linux: 4.18.0-6.7 -proposed tracker (LP: #1788881)
+
+  * systemd 237-3ubuntu10 ADT test failure with linux 4.18.0-5.6 (LP: #1787440)
+    - Config: Disable BPF_JIT_ALWAYS_ON on i386
+
+  * execveat03 in ubuntu_ltp_syscalls failed on X/B (LP: #1786729)
+    - cap_inode_getsecurity: use d_find_any_alias() instead of d_find_alias()
+
+  * Cosmic update to v4.18.5 stable release (LP: #1788874)
+    - EDAC: Add missing MEM_LRDDR4 entry in edac_mem_types[]
+    - pty: fix O_CLOEXEC for TIOCGPTPEER
+    - mm: Allow non-direct-map arguments to free_reserved_area()
+    - x86/mm/init: Pass unconverted symbol addresses to free_init_pages()
+    - x86/mm/init: Add helper for freeing kernel image pages
+    - x86/mm/init: Remove freed kernel image areas from alias mapping
+    - powerpc64s: Show ori31 availability in spectre_v1 sysfs file not v2
+    - ext4: fix spectre gadget in ext4_mb_regular_allocator()
+    - drm/i915/kvmgt: Fix potential Spectre v1
+    - drm/amdgpu/pm: Fix potential Spectre v1
+    - parisc: Remove unnecessary barriers from spinlock.h
+    - parisc: Remove ordered stores from syscall.S
+    - PCI: Restore resized BAR state on resume
+    - PCI / ACPI / PM: Resume all bridges on suspend-to-RAM
+    - PCI: hotplug: Don't leak pci_slot on registration failure
+    - PCI: aardvark: Size bridges before resources allocation
+    - PCI: Skip MPS logic for Virtual Functions (VFs)
+    - PCI: pciehp: Fix use-after-free on unplug
+    - PCI: pciehp: Fix unprotected list iteration in IRQ handler
+    - i2c: core: ACPI: Properly set status byte to 0 for multi-byte writes
+    - i2c: imx: Fix race condition in dma read
+    - reiserfs: fix broken xattr handling (heap corruption, bad retval)
+    - Linux 4.18.5
+
+  * [18.10 FEAT] Add kernel config option "CONFIG_SCLP_OFB" (LP: #1787898)
+    - [Config] CONFIG_SCLP_OFB=y for s390x
+
+  * errors when scanning partition table of corrupted AIX disk (LP: #1787281)
+    - partitions/aix: fix usage of uninitialized lv_info and lvname structures
+    - partitions/aix: append null character to print data from disk
+
+  * Apply NVMe bugfix from Google that bjf asked for (LP: #1787635)
+    - nvme-pci: add a memory barrier to nvme_dbbuf_update_and_check_event
+
+  * ThinkPad systems have no HDMI sound when using the nvidia GPU (LP: #1787058)
+    - ACPI / OSI: Add OEM _OSI string to enable NVidia HDMI audio
+
+  * Cosmic update to v4.18.4 stable release (LP: #1788454)
+    - l2tp: use sk_dst_check() to avoid race on sk->sk_dst_cache
+    - net_sched: fix NULL pointer dereference when delete tcindex filter
+    - net_sched: Fix missing res info when create new tc_index filter
+    - r8169: don't use MSI-X on RTL8168g
+    - ALSA: hda - Sleep for 10ms after entering D3 on Conexant codecs
+    - ALSA: hda - Turn CX8200 into D3 as well upon reboot
+    - ALSA: vx222: Fix invalid endian conversions
+    - ALSA: virmidi: Fix too long output trigger loop
+    - ALSA: cs5535audio: Fix invalid endian conversion
+    - ALSA: dice: fix wrong copy to rx parameters for Alesis iO26
+    - ALSA: hda: Correct Asrock B85M-ITX power_save blacklist entry
+    - ALSA: memalloc: Don't exceed over the requested size
+    - ALSA: vxpocket: Fix invalid endian conversions
+    - ALSA: seq: Fix poll() error return
+    - media: gl861: fix probe of dvb_usb_gl861
+    - USB: serial: sierra: fix potential deadlock at close
+    - USB: serial: pl2303: add a new device id for ATEN
+    - USB: option: add support for DW5821e
+    - ACPI / PM: save NVS memory for ASUS 1025C laptop
+    - tty: serial: 8250: Revert NXP SC16C2552 workaround
+    - serial: 8250_exar: Read INT0 from slave device, too
+    - serial: 8250_dw: always set baud rate in dw8250_set_termios
+    - serial: 8250_dw: Add ACPI support for uart on Broadcom SoC
+    - uio: fix wrong return value from uio_mmap()
+    - misc: sram: fix resource leaks in probe error path
+    - Revert "uio: use request_threaded_irq instead"
+    - Bluetooth: avoid killing an already killed socket
+    - isdn: Disable IIOCDBGVAR
+    - net: sock_diag: Fix spectre v1 gadget in __sock_diag_cmd()
+    - hv/netvsc: Fix NULL dereference at single queue mode fallback
+    - r8169: don't use MSI-X on RTL8106e
+    - ip_vti: fix a null pointer deferrence when create vti fallback tunnel
+    - net: ethernet: mvneta: Fix napi structure mixup on armada 3700
+    - net: mvneta: fix mvneta_config_rss on armada 3700
+    - cls_matchall: fix tcf_unbind_filter missing
+    - Linux 4.18.4
+
+  * Cosmic update to v4.18.3 stable release (LP: #1788453)
+    - x86/speculation/l1tf: Exempt zeroed PTEs from inversion
+    - Linux 4.18.3
+
+  * Cosmic update to v4.18.2 stable release (LP: #1788452)
+    - x86/l1tf: Fix build error seen if CONFIG_KVM_INTEL is disabled
+    - x86: i8259: Add missing include file
+    - x86/hyper-v: Check for VP_INVAL in hyperv_flush_tlb_others()
+    - x86/platform/UV: Mark memblock related init code and data correctly
+    - x86/mm/pti: Clear Global bit more aggressively
+    - xen/pv: Call get_cpu_address_sizes to set x86_virt/phys_bits
+    - x86/mm: Disable ioremap free page handling on x86-PAE
+    - kbuild: verify that $DEPMOD is installed
+    - crypto: ccree - fix finup
+    - crypto: ccree - fix iv handling
+    - crypto: ccp - Check for NULL PSP pointer at module unload
+    - crypto: ccp - Fix command completion detection race
+    - crypto: x86/sha256-mb - fix digest copy in sha256_mb_mgr_get_comp_job_avx2()
+    - crypto: vmac - require a block cipher with 128-bit block size
+    - crypto: vmac - separate tfm and request context
+    - crypto: blkcipher - fix crash flushing dcache in error path
+    - crypto: ablkcipher - fix crash flushing dcache in error path
+    - crypto: skcipher - fix aligning block size in skcipher_copy_iv()
+    - crypto: skcipher - fix crash flushing dcache in error path
+    - ioremap: Update pgtable free interfaces with addr
+    - x86/mm: Add TLB purge to free pmd/pte page interfaces
+    - Linux 4.18.2
+
+  * Cosmic update to v4.18.2 stable release (LP: #1788452) // CVE-2018-9363
+    - Bluetooth: hidp: buffer overflow in hidp_process_report
+
+  * linux-cloud-tools-common: Ensure hv-kvp-daemon.service starts before
+    walinuxagent.service (LP: #1739107)
+    - [Debian] hyper-v -- Ensure that hv-kvp-daemon.service starts before
+      walinuxagent.service
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: ipvs: remove nbsp characters from Kconfig
+    - [Config] CONFIG_MPROFILE_KERNEL=y for ppc64el
+    - [Config] CONFIG_DRM_RCAR_LVDS=m for snapdragon
+    - [Config] CONFIG_MDIO_MSCC_MIIM=n for s390x
+    - [Config] CONFIG_NET_VENDOR_MICROSEMI=n, CONFIG_NET_VENDOR_NI=n for s390x
+    - [Config] update annotations following config review
+    - [Debian] set CROSS_COMPILE when generating kernel configs
+    - [Config] Disable the Speck cipher
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 24 Aug 2018 14:18:15 -0500
+
+linux (4.18.0-5.6) cosmic; urgency=medium
+
+  * Cosmic update to v4.18.1 stable release (LP: #1787264)
+    - x86/paravirt: Fix spectre-v2 mitigations for paravirt guests
+    - x86/speculation: Protect against userspace-userspace spectreRSB
+    - kprobes/x86: Fix %p uses in error messages
+    - x86/irqflags: Provide a declaration for native_save_fl
+    - x86/speculation/l1tf: Increase 32bit PAE __PHYSICAL_PAGE_SHIFT
+    - x86/speculation/l1tf: Change order of offset/type in swap entry
+    - x86/speculation/l1tf: Protect swap entries against L1TF
+    - x86/speculation/l1tf: Protect PROT_NONE PTEs against speculation
+    - x86/speculation/l1tf: Make sure the first page is always reserved
+    - x86/speculation/l1tf: Add sysfs reporting for l1tf
+    - x86/speculation/l1tf: Disallow non privileged high MMIO PROT_NONE mappings
+    - x86/speculation/l1tf: Limit swap file size to MAX_PA/2
+    - x86/bugs: Move the l1tf function and define pr_fmt properly
+    - sched/smt: Update sched_smt_present at runtime
+    - x86/smp: Provide topology_is_primary_thread()
+    - x86/topology: Provide topology_smt_supported()
+    - cpu/hotplug: Make bringup/teardown of smp threads symmetric
+    - cpu/hotplug: Split do_cpu_down()
+    - cpu/hotplug: Provide knobs to control SMT
+    - x86/cpu: Remove the pointless CPU printout
+    - x86/cpu/AMD: Remove the pointless detect_ht() call
+    - x86/cpu/common: Provide detect_ht_early()
+    - x86/cpu/topology: Provide detect_extended_topology_early()
+    - x86/cpu/intel: Evaluate smp_num_siblings early
+    - x86/CPU/AMD: Do not check CPUID max ext level before parsing SMP info
+    - x86/cpu/AMD: Evaluate smp_num_siblings early
+    - x86/apic: Ignore secondary threads if nosmt=force
+    - x86/speculation/l1tf: Extend 64bit swap file size limit
+    - x86/cpufeatures: Add detection of L1D cache flush support.
+    - x86/CPU/AMD: Move TOPOEXT reenablement before reading smp_num_siblings
+    - x86/speculation/l1tf: Protect PAE swap entries against L1TF
+    - x86/speculation/l1tf: Fix up pte->pfn conversion for PAE
+    - Revert "x86/apic: Ignore secondary threads if nosmt=force"
+    - cpu/hotplug: Boot HT siblings at least once
+    - x86/KVM: Warn user if KVM is loaded SMT and L1TF CPU bug being present
+    - x86/KVM/VMX: Add module argument for L1TF mitigation
+    - x86/KVM/VMX: Add L1D flush algorithm
+    - x86/KVM/VMX: Add L1D MSR based flush
+    - x86/KVM/VMX: Add L1D flush logic
+    - x86/KVM/VMX: Split the VMX MSR LOAD structures to have an host/guest numbers
+    - x86/KVM/VMX: Add find_msr() helper function
+    - x86/KVM/VMX: Separate the VMX AUTOLOAD guest/host number accounting
+    - x86/KVM/VMX: Extend add_atomic_switch_msr() to allow VMENTER only MSRs
+    - x86/KVM/VMX: Use MSR save list for IA32_FLUSH_CMD if required
+    - cpu/hotplug: Online siblings when SMT control is turned on
+    - x86/litf: Introduce vmx status variable
+    - x86/kvm: Drop L1TF MSR list approach
+    - x86/l1tf: Handle EPT disabled state proper
+    - x86/kvm: Move l1tf setup function
+    - x86/kvm: Add static key for flush always
+    - x86/kvm: Serialize L1D flush parameter setter
+    - x86/kvm: Allow runtime control of L1D flush
+    - cpu/hotplug: Expose SMT control init function
+    - cpu/hotplug: Set CPU_SMT_NOT_SUPPORTED early
+    - x86/bugs, kvm: Introduce boot-time control of L1TF mitigations
+    - Documentation: Add section about CPU vulnerabilities
+    - x86/speculation/l1tf: Unbreak !__HAVE_ARCH_PFN_MODIFY_ALLOWED architectures
+    - x86/KVM/VMX: Initialize the vmx_l1d_flush_pages' content
+    - Documentation/l1tf: Fix typos
+    - cpu/hotplug: detect SMT disabled by BIOS
+    - x86/KVM/VMX: Don't set l1tf_flush_l1d to true from vmx_l1d_flush()
+    - x86/KVM/VMX: Replace 'vmx_l1d_flush_always' with 'vmx_l1d_flush_cond'
+    - x86/KVM/VMX: Move the l1tf_flush_l1d test to vmx_l1d_flush()
+    - x86/irq: Demote irq_cpustat_t::__softirq_pending to u16
+    - x86/KVM/VMX: Introduce per-host-cpu analogue of l1tf_flush_l1d
+    - x86: Don't include linux/irq.h from asm/hardirq.h
+    - x86/irq: Let interrupt handlers set kvm_cpu_l1tf_flush_l1d
+    - x86/KVM/VMX: Don't set l1tf_flush_l1d from vmx_handle_external_intr()
+    - Documentation/l1tf: Remove Yonah processors from not vulnerable list
+    - x86/speculation: Simplify sysfs report of VMX L1TF vulnerability
+    - x86/speculation: Use ARCH_CAPABILITIES to skip L1D flush on vmentry
+    - KVM: VMX: Tell the nested hypervisor to skip L1D flush on vmentry
+    - cpu/hotplug: Fix SMT supported evaluation
+    - x86/speculation/l1tf: Invert all not present mappings
+    - x86/speculation/l1tf: Make pmd/pud_mknotpresent() invert
+    - x86/mm/pat: Make set_memory_np() L1TF safe
+    - x86/mm/kmmio: Make the tracer robust against L1TF
+    - tools headers: Synchronise x86 cpufeatures.h for L1TF additions
+    - x86/microcode: Allow late microcode loading with SMT disabled
+    - x86/smp: fix non-SMP broken build due to redefinition of
+      apic_id_is_primary_thread
+    - cpu/hotplug: Non-SMP machines do not make use of booted_once
+    - x86/init: fix build with CONFIG_SWAP=n
+    - Linux 4.18.1
+    - [Config] updateconfigs after v4.18.1 stable update
+
+  * Consider enabling CONFIG_NETWORK_PHY_TIMESTAMPING (LP: #1785816)
+    - [Config] Enable timestamping in network PHY devices
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_SYSCTL_SYSCALL=n
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 15 Aug 2018 14:20:59 -0500
+
+linux (4.18.0-4.5) cosmic; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 06 Aug 2018 13:54:02 -0500
+
+linux (4.18.0-3.4) cosmic; urgency=medium
+
+  * Suspend fails in Ubuntu and Kubuntu 18.04 but works fine in Ubuntu and
+    Kubuntu 17.10 (and on Kubuntu 18.04 using kernel 4.14.47) (LP: #1774950)
+    - ACPI / LPSS: Avoid PM quirks on suspend and resume from hibernation
+
+  * hinic interfaces aren't getting predictable names (LP: #1783138)
+    - hinic: Link the logical network device to the pci device in sysfs
+
+  * libvirtd is unable to configure bridge devices inside of LXD containers
+    (LP: #1784501)
+    - kernfs: allow creating kernfs objects with arbitrary uid/gid
+    - sysfs, kobject: allow creating kobject belonging to arbitrary users
+    - kobject: kset_create_and_add() - fetch ownership info from parent
+    - driver core: set up ownership of class devices in sysfs
+    - net-sysfs: require net admin in the init ns for setting tx_maxrate
+    - net-sysfs: make sure objects belong to container's owner
+    - net: create reusable function for getting ownership info of sysfs inodes
+    - bridge: make sure objects belong to container's owner
+    - sysfs: Fix regression when adding a file to an existing group
+
+  * locking sockets broken due to missing AppArmor socket mediation patches
+    (LP: #1780227)
+    - UBUNTU SAUCE: apparmor: fix apparmor mediating locking non-fs, unix sockets
+
+  * Update2 for ocxl driver (LP: #1781436)
+    - ocxl: Fix page fault handler in case of fault on dying process
+
+  * HDMI/DP audio can't work on the laptop of Dell Latitude 5495 (LP: #1782689)
+    - ALSA: hda: use PCI_BASE_CLASS_DISPLAY to replace PCI_CLASS_DISPLAY_VGA
+    - vga_switcheroo: set audio client id according to bound GPU id
+
+  * Allow Raven Ridge's audio controller to be runtime suspended (LP: #1782540)
+    - ALSA: hda: Add AZX_DCAPS_PM_RUNTIME for AMD Raven Ridge
+
+  * Invoking obsolete 'firmware_install' target breaks snap build (LP: #1782166)
+    - snapcraft.yaml: stop invoking the obsolete (and non-existing)
+      'firmware_install' target
+
+  * snapcraft.yaml: missing ubuntu-retpoline-extract-one script breaks the build
+    (LP: #1782116)
+    - snapcraft.yaml: copy retpoline-extract-one to scripts before build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 01 Aug 2018 08:49:40 -0500
+
+linux (4.18.0-2.3) cosmic; urgency=medium
+
+  * Kernel error "task zfs:pid blocked for more than 120 seconds" (LP: #1781364)
+    - SAUCE: (noup) zfs to 0.7.9-3ubuntu4
+
+  * [Regression] EXT4-fs error (device sda1): ext4_validate_inode_bitmap:99:
+    comm stress-ng: Corrupt inode bitmap (LP: #1780137)
+    - SAUCE: ext4: fix ext4_validate_inode_bitmap: comm stress-ng: Corrupt inode
+      bitmap
+
+  * Cloud-init causes potentially huge boot delays with 4.15 kernels
+    (LP: #1780062)
+    - random: Make getrandom() ready earlier
+
+  * hisi_sas_v3_hw: internal task abort: timeout and not done. (LP: #1777736)
+    - scsi: hisi_sas: Update a couple of register settings for v3 hw
+
+  * hisi_sas: Add missing PHY spinlock init (LP: #1777734)
+    - scsi: hisi_sas: Add missing PHY spinlock init
+
+  * hisi_sas: improve read performance by pre-allocating slot DMA buffers
+    (LP: #1777727)
+    - scsi: hisi_sas: Use dmam_alloc_coherent()
+    - scsi: hisi_sas: Pre-allocate slot DMA buffers
+
+  * hisi_sas: Failures during host reset (LP: #1777696)
+    - scsi: hisi_sas: Only process broadcast change in phy_bcast_v3_hw()
+    - scsi: hisi_sas: Fix the conflict between dev gone and host reset
+    - scsi: hisi_sas: Adjust task reject period during host reset
+    - scsi: hisi_sas: Add a flag to filter PHY events during reset
+    - scsi: hisi_sas: Release all remaining resources in clear nexus ha
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.9-3ubuntu2, zfs to 0.7.9-3ubuntu3
+    - SAUCE: mm: Fix exports that inadvertently make put_page() EXPORT_SYMBOL_GPL
+    - Enable zfs build
+    - SAUCE: Import aufs driver
+    - Revert "UBUNTU: [Config]: set CONFIG_EDAC_DEBUG=y for ARM64"
+    - [Config] retpoline -- review and accept retpoline changes
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc5
+  * Rebase to v4.18-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 24 Jul 2018 08:41:22 -0500
+
+linux (4.18.0-1.2) cosmic; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 09 Jul 2018 07:36:31 -0500
+
+linux (4.18.0-0.1) cosmic; urgency=medium
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu -- disable vbox build
+    - Disable zfs build
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) Add a SysRq option to lift kernel lockdown
+    - SAUCE: (efi-lockdown) ima: require secure_boot rules in lockdown mode
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/{mem,kmem,port} when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) kexec_load: Disable at runtime if the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86/msr: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Lock down module params that specify hardware
+      parameters (eg. ioport)
+    - SAUCE: (efi-lockdown) x86/mmiotrace: Lock down the testmmiotrace module
+    - SAUCE: (efi-lockdown) Lock down /proc/kcore
+    - SAUCE: (efi-lockdown) Lock down kprobes
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) Lock down perf
+    - SAUCE: (efi-lockdown) debugfs: Restrict debugfs when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) efi: Add EFI signature data types
+    - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - SAUCE: (efi-lockdown) Make get_cert_list() not complain about cert lists
+      that aren't present.
+    - SAUCE: (efi-lockdown) Add efi_status_to_str() and rework
+      efi_status_to_err().
+    - SAUCE: (efi-lockdown) Make get_cert_list() use efi_status_to_str() to print
+      error messages.
+    - SAUCE: (efi-lockdown) lockdown: fix coordination of kernel module signature
+      verification
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) efi: Don't print secure boot state from the efi stub
+    - SAUCE: (namespace) block_dev: Support checking inode permissions in
+      lookup_bdev()
+    - SAUCE: (namespace) block_dev: Check permissions towards block device inode
+      when mounting
+    - SAUCE: (namespace) mtd: Check permissions towards mtd block device inode
+      when mounting
+    - SAUCE: (namespace) ext4: Add support for unprivileged mounts from user
+      namespaces
+    - SAUCE: (namespace) ext4: Add module parameter to enable user namespace
+      mounts
+    - SAUCE: (namespace) block_dev: Forbid unprivileged mounting when device is
+      opened for writing
+    - SAUCE: Import aufs driver
+    - Update dropped.txt
+    - [Config] updateconfigs after 4.18-rc3 rebase
+    - SAUCE: (no-up): ASoC: Intel: bytcr-rt5660: Remove snd_soc_codec use for 4.18
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.18-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 06 Jul 2018 10:46:37 -0500
+
+linux (4.18.0-0.0) cosmic; urgency=medium
+
+  * Dummy entry.
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 03 Jul 2018 11:10:33 -0500
+
+linux (4.17.0-4.5) cosmic; urgency=medium
+
+  * linux: 4.17.0-4.5 -proposed tracker (LP: #1779399)
+
+  * Update to ocxl driver for 18.04.1 (LP: #1775786)
+    - powerpc: Add TIDR CPU feature for POWER9
+    - powerpc: Use TIDR CPU feature to control TIDR allocation
+    - powerpc: use task_pid_nr() for TID allocation
+    - ocxl: Rename pnv_ocxl_spa_remove_pe to clarify it's action
+    - ocxl: Expose the thread_id needed for wait on POWER9
+    - ocxl: Add an IOCTL so userspace knows what OCXL features are available
+    - ocxl: Document new OCXL IOCTLs
+    - ocxl: Fix missing unlock on error in afu_ioctl_enable_p9_wait()
+
+  * Please include ax88179_178a and r8152 modules in d-i udeb (LP: #1771823)
+    - [Config:] d-i: Add ax88179_178a and r8152 to nic-modules
+
+  * glibc pkeys test fail on powerpc (LP: #1776967)
+    - [Config] Temporarily disable CONFIG_PPC_MEM_KEYS
+
+  * After update to 4.13-43 Intel Graphics are Laggy (LP: #1773520)
+    - Revert "drm/i915/edp: Allow alternate fixed mode for eDP if available."
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.9-3ubuntu1, zfs to 0.7.9-3ubuntu1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 29 Jun 2018 13:37:52 -0500
+
+linux (4.17.0-3.4) cosmic; urgency=medium
+
+  * linux: 4.17.0-3.4 -proposed tracker (LP: #1779124)
+
+  * Cosmic update to v4.17.3 stable release (LP: #1778997)
+    - net: aquantia: fix unsigned numvecs comparison with less than zero
+    - bonding: re-evaluate force_primary when the primary slave name changes
+    - cdc_ncm: avoid padding beyond end of skb
+    - ipv6: allow PMTU exceptions to local routes
+    - net: dsa: add error handling for pskb_trim_rcsum
+    - net: phy: dp83822: use BMCR_ANENABLE instead of BMSR_ANEGCAPABLE for DP83620
+    - net/sched: act_simple: fix parsing of TCA_DEF_DATA
+    - tcp: verify the checksum of the first data segment in a new connection
+    - tls: fix use-after-free in tls_push_record
+    - tls: fix waitall behavior in tls_sw_recvmsg
+    - socket: close race condition between sock_close() and sockfs_setattr()
+    - udp: fix rx queue len reported by diag and proc interface
+    - net: in virtio_net_hdr only add VLAN_HLEN to csum_start if payload holds
+      vlan
+    - hv_netvsc: Fix a network regression after ifdown/ifup
+    - ACPICA: AML parser: attempt to continue loading table after error
+    - ext4: fix hole length detection in ext4_ind_map_blocks()
+    - ext4: update mtime in ext4_punch_hole even if no blocks are released
+    - ext4: do not allow external inodes for inline data
+    - ext4: bubble errors from ext4_find_inline_data_nolock() up to ext4_iget()
+    - ext4: correctly handle a zero-length xattr with a non-zero e_value_offs
+    - ext4: fix fencepost error in check for inode count overflow during resize
+    - driver core: Don't ignore class_dir_create_and_add() failure.
+    - Btrfs: allow empty subvol= again
+    - Btrfs: fix clone vs chattr NODATASUM race
+    - Btrfs: fix memory and mount leak in btrfs_ioctl_rm_dev_v2()
+    - btrfs: return error value if create_io_em failed in cow_file_range
+    - btrfs: scrub: Don't use inode pages for device replace
+    - ALSA: usb-audio: Disable the quirk for Nura headset
+    - ALSA: hda/conexant - Add fixup for HP Z2 G4 workstation
+    - ALSA: hda - Handle kzalloc() failure in snd_hda_attach_pcm_stream()
+    - ALSA: hda: add dock and led support for HP EliteBook 830 G5
+    - ALSA: hda: add dock and led support for HP ProBook 640 G4
+    - x86/MCE: Fix stack out-of-bounds write in mce-inject.c: Flags_read()
+    - smb3: fix various xid leaks
+    - smb3: on reconnect set PreviousSessionId field
+    - CIFS: 511c54a2f69195b28afb9dd119f03787b1625bb4 adds a check for session
+      expiry
+    - cifs: For SMB2 security informaion query, check for minimum sized security
+      descriptor instead of sizeof FileAllInformation class
+    - nbd: fix nbd device deletion
+    - nbd: update size when connected
+    - nbd: use bd_set_size when updating disk size
+    - blk-mq: reinit q->tag_set_list entry only after grace period
+    - bdi: Move cgroup bdi_writeback to a dedicated low concurrency workqueue
+    - cpufreq: Fix new policy initialization during limits updates via sysfs
+    - cpufreq: ti-cpufreq: Fix an incorrect error return value
+    - cpufreq: governors: Fix long idle detection logic in load calculation
+    - libata: zpodd: small read overflow in eject_tray()
+    - libata: Drop SanDisk SD7UB3Q*G1001 NOLPM quirk
+    - nvme/pci: Sync controller reset for AER slot_reset
+    - w1: mxc_w1: Enable clock before calling clk_get_rate() on it
+    - x86/vector: Fix the args of vector_alloc tracepoint
+    - x86/apic/vector: Prevent hlist corruption and leaks
+    - x86/apic: Provide apic_ack_irq()
+    - x86/ioapic: Use apic_ack_irq()
+    - x86/platform/uv: Use apic_ack_irq()
+    - irq_remapping: Use apic_ack_irq()
+    - genirq/generic_pending: Do not lose pending affinity update
+    - genirq/affinity: Defer affinity setting if irq chip is busy
+    - genirq/migration: Avoid out of line call if pending is not set
+    - x86/intel_rdt: Enable CMT and MBM on new Skylake stepping
+    - media: uvcvideo: Prevent setting unavailable flags
+    - media: rc: ensure input/lirc device can be opened after register
+    - iwlwifi: fw: harden page loading code
+    - orangefs: set i_size on new symlink
+    - orangefs: report attributes_mask and attributes for statx
+    - HID: intel_ish-hid: ipc: register more pm callbacks to support hibernation
+    - HID: wacom: Correct logical maximum Y for 2nd-gen Intuos Pro large
+    - vhost: fix info leak due to uninitialized memory
+    - mm, page_alloc: do not break __GFP_THISNODE by zonelist reset
+    - Linux 4.17.3
+
+  * Use-after-free in sk_peer_label (LP: #1778646)
+    - SAUCE: apparmor: fix use after free in sk_peer_label
+
+  * kernel: Fix memory leak on CCA and EP11 CPRB processing. (LP: #1775390)
+    - s390/zcrypt: Fix CCA and EP11 CPRB processing failure memory leak.
+
+  * Various fixes for CXL kernel module (LP: #1774471)
+    - cxl: Configure PSL to not use APC virtual machines
+    - cxl: Disable prefault_mode in Radix mode
+
+  * Bluetooth not working (LP: #1764645)
+    - Bluetooth: btusb: Apply QCA Rome patches for some ATH3012 models
+
+  * Fake SAS addresses for SATA disks on HiSilicon D05 are non-unique
+    (LP: #1776750)
+    - scsi: hisi_sas: make SAS address of SATA disks unique
+
+  * linux-snapdragon: wcn36xx: mac address generation on boot (LP: #1776491)
+    - [Config] arm64: snapdragon: WCN36XX_SNAPDRAGON_HACKS=y
+    - SAUCE: wcn36xx: read MAC from file or randomly generate one
+
+  * Lenovo V330 needs patch in ideapad_laptop module for rfkill (LP: #1774636)
+    - SAUCE: Add Lenovo V330 to the ideapad_laptop rfkill blacklist
+
+  * register on binfmt_misc may overflow and crash the system (LP: #1775856)
+    - fs/binfmt_misc.c: do not allow offset overflow
+
+  * Network installs fail on SocioNext board (LP: #1775884)
+    - net: socionext: reset hardware in ndo_stop
+    - net: netsec: enable tx-irq during open callback
+
+  * Fix several bugs in RDMA/hns driver (LP: #1770974)
+    - RDMA/hns: Drop local zgid in favor of core defined variable
+    - RDMA/hns: Add 64KB page size support for hip08
+    - RDMA/hns: Rename the idx field of db
+    - RDMA/hns: Modify uar allocation algorithm to avoid bitmap exhaust
+    - RDMA/hns: Increase checking CMQ status timeout value
+    - RDMA/hns: Add reset process for RoCE in hip08
+    - RDMA/hns: Fix the illegal memory operation when cross page
+    - RDMA/hns: Implement the disassociate_ucontext API
+
+  * powerpc/livepatch: Implement reliable stack tracing for the consistency
+    model (LP: #1771844)
+    - powerpc/livepatch: Implement reliable stack tracing for the consistency
+      model
+
+  * Adding back alx WoL feature (LP: #1772610)
+    - SAUCE: Revert "alx: remove WoL support"
+    - SAUCE: alx: add enable_wol paramenter
+
+  * Lancer A0 Asic HBA's won't boot with 18.04 (LP: #1768103)
+    - scsi: lpfc: Fix WQ/CQ creation for older asic's.
+    - scsi: lpfc: Fix 16gb hbas failing cq create.
+
+  * [LTCTest][OPAL][OP920] cpupower idle-info is not listing stop4 and stop5
+    idle states when all CORES are guarded (LP: #1771780)
+    - powerpc/powernv/cpuidle: Init all present cpus for deep states
+
+  * Huawei 25G/100G Network Adapters Unsupported (LP: #1770970)
+    - net-next/hinic: add pci device ids for 25ge and 100ge card
+
+  * Expose arm64 CPU topology to userspace (LP: #1770231)
+    - drivers: base: cacheinfo: move cache_setup_of_node()
+    - drivers: base: cacheinfo: setup DT cache properties early
+    - cacheinfo: rename of_node to fw_token
+    - arm64/acpi: Create arch specific cpu to acpi id helper
+    - ACPI/PPTT: Add Processor Properties Topology Table parsing
+    - [Config] CONFIG_ACPI_PPTT=y
+    - ACPI: Enable PPTT support on ARM64
+    - drivers: base cacheinfo: Add support for ACPI based firmware tables
+    - arm64: Add support for ACPI based firmware tables
+    - arm64: topology: rename cluster_id
+    - arm64: topology: enable ACPI/PPTT based CPU topology
+    - ACPI: Add PPTT to injectable table list
+    - arm64: topology: divorce MC scheduling domain from core_siblings
+
+  * Vcs-Git header on bionic linux source package points to zesty git tree
+    (LP: #1766055)
+    - [Packaging]: Update Vcs-Git
+
+  * Request to revert SAUCE patches in the 18.04 SRU and update with upstream
+    version (LP: #1768431)
+    - scsi: cxlflash: Handle spurious interrupts
+    - scsi: cxlflash: Remove commmands from pending list on timeout
+    - scsi: cxlflash: Synchronize reset and remove ops
+    - SAUCE: (no-up) cxlflash: OCXL diff between v2 and v3
+
+  * hisi_sas robustness fixes (LP: #1774466)
+    - scsi: hisi_sas: delete timer when removing hisi_sas driver
+    - scsi: hisi_sas: print device id for errors
+    - scsi: hisi_sas: Add some checks to avoid free'ing a sas_task twice
+    - scsi: hisi_sas: check host frozen before calling "done" function
+    - scsi: hisi_sas: check sas_dev gone earlier in hisi_sas_abort_task()
+    - scsi: hisi_sas: stop controller timer for reset
+    - scsi: hisi_sas: update PHY linkrate after a controller reset
+    - scsi: hisi_sas: change slot index allocation mode
+    - scsi: hisi_sas: Change common allocation mode of device id
+    - scsi: hisi_sas: Reset disks when discovered
+    - scsi: hisi_sas: Create a scsi_host_template per HW module
+    - scsi: hisi_sas: Init disks after controller reset
+    - scsi: hisi_sas: Try wait commands before before controller reset
+    - scsi: hisi_sas: Include TMF elements in struct hisi_sas_slot
+    - scsi: hisi_sas: Add v2 hw force PHY function for internal ATA command
+    - scsi: hisi_sas: Terminate STP reject quickly for v2 hw
+    - scsi: hisi_sas: Fix return value when get_free_slot() failed
+    - scsi: hisi_sas: Mark PHY as in reset for nexus reset
+
+  * hisi_sas: Support newer v3 hardware (LP: #1774467)
+    - scsi: hisi_sas: update RAS feature for later revision of v3 HW
+    - scsi: hisi_sas: check IPTT is valid before using it for v3 hw
+    - scsi: hisi_sas: fix PI memory size
+    - scsi: hisi_sas: config ATA de-reset as an constrained command for v3 hw
+    - scsi: hisi_sas: remove redundant handling to event95 for v3
+    - scsi: hisi_sas: add readl poll timeout helper wrappers
+    - scsi: hisi_sas: workaround a v3 hw hilink bug
+    - scsi: hisi_sas: Add LED feature for v3 hw
+
+  * hisi_sas: improve performance by optimizing DQ locking (LP: #1774472)
+    - scsi: hisi_sas: optimise the usage of DQ locking
+    - scsi: hisi_sas: relocate smp sg map
+    - scsi: hisi_sas: make return type of prep functions void
+    - scsi: hisi_sas: allocate slot buffer earlier
+    - scsi: hisi_sas: Don't lock DQ for complete task sending
+    - scsi: hisi_sas: Use device lock to protect slot alloc/free
+    - scsi: hisi_sas: add check of device in hisi_sas_task_exec()
+    - scsi: hisi_sas: fix a typo in hisi_sas_task_prep()
+
+  * FS-Cache: Assertion failed: FS-Cache: 6 == 5 is false (LP: #1774336)
+    - SAUCE: CacheFiles: fix a read_waiter/read_copier race
+
+  * enable mic-mute hotkey and led on Lenovo M820z and M920z (LP: #1774306)
+    - ALSA: hda/realtek - Enable mic-mute hotkey for several Lenovo AIOs
+
+  * hns3 driver updates (LP: #1768670)
+    - net: hns3: Remove error log when getting pfc stats fails
+    - net: hns3: fix to correctly fetch l4 protocol outer header
+    - net: hns3: Fixes the out of bounds access in hclge_map_tqp
+    - net: hns3: Fixes the error legs in hclge_init_ae_dev function
+    - net: hns3: fix for phy_addr error in hclge_mac_mdio_config
+    - net: hns3: Fix to support autoneg only for port attached with phy
+    - net: hns3: fix a dead loop in hclge_cmd_csq_clean
+    - net: hns3: Fix for packet loss due wrong filter config in VLAN tbls
+    - net: hns3: Remove packet statistics in the range of 8192~12287
+    - net: hns3: Add support of hardware rx-vlan-offload to HNS3 VF driver
+    - net: hns3: Fix for setting mac address when resetting
+    - net: hns3: remove add/del_tunnel_udp in hns3_enet module
+    - net: hns3: fix for cleaning ring problem
+    - net: hns3: refactor the loopback related function
+    - net: hns3: Fix for deadlock problem occurring when unregistering ae_algo
+    - net: hns3: Fix for the null pointer problem occurring when initializing
+      ae_dev failed
+    - net: hns3: Add a check for client instance init state
+    - net: hns3: Change return type of hnae3_register_ae_dev
+    - net: hns3: Change return type of hnae3_register_ae_algo
+    - net: hns3: Change return value in hnae3_register_client
+    - net: hns3: Fixes the back pressure setting when sriov is enabled
+    - net: hns3: Fix for fiber link up problem
+    - net: hns3: Add support of .sriov_configure in HNS3 driver
+    - net: hns3: Fixes the missing PCI iounmap for various legs
+    - net: hns3: Fixes error reported by Kbuild and internal review
+    - net: hns3: Fixes API to fetch ethernet header length with kernel default
+    - net: hns3: cleanup of return values in hclge_init_client_instance()
+    - net: hns3: Fix the missing client list node initialization
+    - net: hns3: Fix for hns3 module is loaded multiple times problem
+    - net: hns3: Use enums instead of magic number in hclge_is_special_opcode
+    - net: hns3: Fix for netdev not running problem after calling net_stop and
+      net_open
+    - net: hns3: Fixes kernel panic issue during rmmod hns3 driver
+    - net: hns3: Fix for CMDQ and Misc. interrupt init order problem
+    - net: hns3: Updates RX packet info fetch in case of multi BD
+    - net: hns3: Add support for tx_accept_tag2 and tx_accept_untag2 config
+    - net: hns3: Add STRP_TAGP field support for hardware revision 0x21
+    - net: hns3: Add support to enable TX/RX promisc mode for H/W rev(0x21)
+    - net: hns3: Fix for PF mailbox receving unknown message
+    - net: hns3: Fixes the state to indicate client-type initialization
+    - net: hns3: Fixes the init of the VALID BD info in the descriptor
+    - net: hns3: Removes unnecessary check when clearing TX/RX rings
+    - net: hns3: Clear TX/RX rings when stopping port & un-initializing client
+    - net: hns3: Remove unused led control code
+    - net: hns3: Adds support for led locate command for copper port
+    - net: hns3: Fixes initalization of RoCE handle and makes it conditional
+    - net: hns3: Disable vf vlan filter when vf vlan table is full
+    - net: hns3: Add support for IFF_ALLMULTI flag
+    - net: hns3: Add repeat address checking for setting mac address
+    - net: hns3: Fix setting mac address error
+    - net: hns3: Fix for service_task not running problem after resetting
+    - net: hns3: Fix for hclge_reset running repeatly problem
+    - net: hns3: Fix for phy not link up problem after resetting
+    - net: hns3: Add missing break in misc_irq_handle
+    - net: hns3: Fix for vxlan tx checksum bug
+    - net: hns3: Optimize the PF's process of updating multicast MAC
+    - net: hns3: Optimize the VF's process of updating multicast MAC
+    - SAUCE: {topost} net: hns3: add support for serdes loopback selftest
+    - SAUCE: {topost} net: hns3: RX BD information valid only in last BD except
+      VLD bit and buffer size
+    - SAUCE: {topost} net: hns3: remove hclge_get_vector_index from
+      hclge_bind_ring_with_vector
+    - SAUCE: {topost} net: hns3: rename the interface for init_client_instance and
+      uninit_client_instance
+    - SAUCE: {topost} net: hns3: add vector status check before free vector
+    - SAUCE: {topost} net: hns3: add l4_type check for both ipv4 and ipv6
+    - SAUCE: {topost} net: hns3: remove unused head file in hnae3.c
+    - SAUCE: {topost} net: hns3: extraction an interface for state state
+      init|uninit
+    - SAUCE: {topost} net: hns3: print the ret value in error information
+    - SAUCE: {topost} net: hns3: remove the Redundant put_vector in
+      hns3_client_uninit
+    - SAUCE: {topost} net: hns3: add unlikely for error check
+    - SAUCE: {topost} net: hns3: remove back in struct hclge_hw
+    - SAUCE: {topost} net: hns3: use lower_32_bits and upper_32_bits
+    - SAUCE: {topost} net: hns3: remove unused hclge_ring_to_dma_dir
+    - SAUCE: {topost} net: hns3: remove useless code in hclge_cmd_send
+    - SAUCE: {topost} net: hns3: remove some redundant assignments
+    - SAUCE: {topost} net: hns3: simplify hclge_cmd_csq_clean
+    - SAUCE: {topost} net: hns3: using modulo for cyclic counters in
+      hclge_cmd_send
+    - SAUCE: {topost} net: hns3: remove a redundant hclge_cmd_csq_done
+    - SAUCE: {topost} net: hns3: remove some unused members of some structures
+    - SAUCE: {topost} net: hns3: give default option while dependency HNS3 set
+    - SAUCE: {topost} net: hns3: use dma_zalloc_coherent instead of
+      kzalloc/dma_map_single
+    - SAUCE: {topost} net: hns3: modify hnae_ to hnae3_
+    - SAUCE: {topost} net: hns3: fix unused function warning in VF driver
+    - SAUCE: {topost} net: hns3: remove some redundant assignments
+    - SAUCE: {topost} net: hns3: standardize the handle of return value
+    - SAUCE: {topost} net: hns3: remove extra space and brackets
+    - SAUCE: {topost} net: hns3: fix unreasonable code comments
+    - SAUCE: {topost} net: hns3: use decimal for bit offset macros
+    - SAUCE: {topost} net: hns3: modify inconsistent bit mask macros
+    - SAUCE: {topost} net: hns3: fix mislead parameter name
+    - SAUCE: {topost} net: hns3: remove unused struct member and definition
+    - SAUCE: {topost} net: hns3: Add SPDX tags to hns3 driver
+    - SAUCE: {topost} net: hns3: Add pf reset for hip08 RoCE
+    - SAUCE: {topost} net: hns3: optimize the process of notifying roce client
+    - SAUCE: {topost} net: hns3: Add calling roce callback function when link
+      status change
+    - SAUCE: {topost} net: hns3: fix tc setup when netdev is first up
+    - SAUCE: {topost} net: hns3: fix for mac pause not disable in pfc mode
+    - SAUCE: {topost} net: hns3: fix for waterline not setting correctly
+    - SAUCE: {topost} net: hns3: fix for l4 checksum offload bug
+    - SAUCE: {topost} net: hns3: fix for mailbox message truncated problem
+    - SAUCE: {topost} net: hns3: Add configure for mac minimal frame size
+    - SAUCE: {topost} net: hns3: fix warning bug when doing lp selftest
+    - SAUCE: {topost} net: hns3: fix get_vector ops in hclgevf_main module
+    - SAUCE: {topost} net: hns3: remove the warning when clear reset cause
+    - SAUCE: {topost} net: hns3: Use roce handle when calling roce callback
+      function
+    - SAUCE: {topost} net: hns3: prevent sending command during global or core
+      reset
+    - SAUCE: {topost} net: hns3: modify the order of initializeing command queue
+      register
+    - SAUCE: {topost} net: hns3: reset net device with rtnl_lock
+    - SAUCE: {topost} net: hns3: prevent to request reset frequently
+    - SAUCE: {topost} net: hns3: correct reset event status register
+    - SAUCE: {topost} net: hns3: separate roce from nic when resetting
+    - SAUCE: net: hns3: Fix for phy link issue when using marvell phy driver
+    - SAUCE: {topost} net: hns3: fix return value error in
+      hns3_reset_notify_down_enet
+    - SAUCE: {topost} net: hns3: remove unnecessary ring configuration operation
+      while resetting
+    - SAUCE: {topost} net: hns3: fix for reset_level default assignment probelm
+    - SAUCE: {topost} net: hns3: fix for using wrong mask and shift in
+      hclge_get_ring_chain_from_mbx
+    - SAUCE: {topost} net: hns3: fix comments for hclge_get_ring_chain_from_mbx
+    - SAUCE: net: hns3: Fix for VF mailbox cannot receiving PF response
+    - SAUCE: net: hns3: Fix for VF mailbox receiving unknown message
+    - SAUCE: net: hns3: Optimize PF CMDQ interrupt switching process
+
+  * CVE-2018-7755
+    - SAUCE: floppy: Do not copy a kernel pointer to user memory in FDGETPRM ioctl
+
+  * Incorrect blacklist of bcm2835_wdt (LP: #1766052)
+    - [Packaging] Fix missing watchdog for Raspberry Pi
+
+  * kernel: Fix arch random implementation (LP: #1775391)
+    - s390/archrandom: Rework arch random implementation.
+
+  * [Ubuntu 1804][boston][ixgbe] EEH causes kernel BUG at /build/linux-
+    jWa1Fv/linux-4.15.0/drivers/pci/msi.c:352 (i2S) (LP: #1776389)
+    - ixgbe/ixgbevf: Free IRQ when PCI error recovery removes the device
+
+  * Cosmic update to v4.17.2 stable release (LP: #1779117)
+    - crypto: chelsio - request to HW should wrap
+    - blkdev_report_zones_ioctl(): Use vmalloc() to allocate large buffers
+    - KVM: X86: Fix reserved bits check for MOV to CR3
+    - KVM: x86: introduce linear_{read,write}_system
+    - kvm: fix typo in flag name
+    - kvm: nVMX: Enforce cpl=0 for VMX instructions
+    - KVM: x86: pass kvm_vcpu to kvm_read_guest_virt and
+      kvm_write_guest_virt_system
+    - kvm: x86: use correct privilege level for sgdt/sidt/fxsave/fxrstor access
+    - staging: android: ion: Switch to pr_warn_once in ion_buffer_destroy
+    - NFC: pn533: don't send USB data off of the stack
+    - usbip: vhci_sysfs: fix potential Spectre v1
+    - usb-storage: Add support for FL_ALWAYS_SYNC flag in the UAS driver
+    - usb-storage: Add compatibility quirk flags for G-Technologies G-Drive
+    - Input: xpad - add GPD Win 2 Controller USB IDs
+    - phy: qcom-qusb2: Fix crash if nvmem cell not specified
+    - usb: core: message: remove extra endianness conversion in
+      usb_set_isoch_delay
+    - usb: typec: wcove: Remove dependency on HW FSM
+    - usb: gadget: function: printer: avoid wrong list handling in printer_write()
+    - usb: gadget: udc: renesas_usb3: fix double phy_put()
+    - usb: gadget: udc: renesas_usb3: should remove debugfs
+    - usb: gadget: udc: renesas_usb3: should call pm_runtime_enable() before add
+      udc
+    - usb: gadget: udc: renesas_usb3: should call devm_phy_get() before add udc
+    - usb: gadget: udc: renesas_usb3: should fail if devm_phy_get() returns error
+    - usb: gadget: udc: renesas_usb3: disable the controller's irqs for
+      reconnecting
+    - serial: sh-sci: Stop using printk format %pCr
+    - tty/serial: atmel: use port->name as name in request_irq()
+    - serial: samsung: fix maxburst parameter for DMA transactions
+    - serial: 8250: omap: Fix idling of clocks for unused uarts
+    - vmw_balloon: fixing double free when batching mode is off
+    - doc: fix sysfs ABI documentation
+    - arm64: defconfig: Enable CONFIG_PINCTRL_MT7622 by default
+    - tty: pl011: Avoid spuriously stuck-off interrupts
+    - crypto: ccree - correct host regs offset
+    - Input: goodix - add new ACPI id for GPD Win 2 touch screen
+    - Input: elan_i2c - add ELAN0612 (Lenovo v330 14IKB) ACPI ID
+    - crypto: caam - strip input zeros from RSA input buffer
+    - crypto: caam - fix DMA mapping dir for generated IV
+    - crypto: caam - fix IV DMA mapping and updating
+    - crypto: caam/qi - fix IV DMA mapping and updating
+    - crypto: caam - fix size of RSA prime factor q
+    - crypto: cavium - Fix fallout from CONFIG_VMAP_STACK
+    - crypto: cavium - Limit result reading attempts
+    - crypto: vmx - Remove overly verbose printk from AES init routines
+    - crypto: vmx - Remove overly verbose printk from AES XTS init
+    - crypto: omap-sham - fix memleak
+    - Linux 4.17.2
+
+  * Cosmic update to v4.17.1 stable release (LP: #1779116)
+    - netfilter: nf_flow_table: attach dst to skbs
+    - bnx2x: use the right constant
+    - ip6mr: only set ip6mr_table from setsockopt when ip6mr_new_table succeeds
+    - ipv6: omit traffic class when calculating flow hash
+    - l2tp: fix refcount leakage on PPPoL2TP sockets
+    - netdev-FAQ: clarify DaveM's position for stable backports
+    - net: metrics: add proper netlink validation
+    - net/packet: refine check for priv area size
+    - rtnetlink: validate attributes in do_setlink()
+    - sctp: not allow transport timeout value less than HZ/5 for hb_timer
+    - team: use netdev_features_t instead of u32
+    - vrf: check the original netdevice for generating redirect
+    - net: dsa: b53: Fix for brcm tag issue in Cygnus SoC
+    - ipmr: fix error path when ipmr_new_table fails
+    - PCI: hv: Do not wait forever on a device that has disappeared
+    - Linux 4.17.1
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: crypto: thunderx_zip: Fix fallout from
+      CONFIG_VMAP_STACK"
+    - Revert "UBUNTU: SAUCE: cred: Add clone_cred() interface"
+    - SAUCE: apparmor: userspace queries
+    - SAUCE: apparmor: patch to provide compatibility with v2.x net rules
+    - SAUCE: apparmor: af_unix mediation
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 28 Jun 2018 08:03:32 -0500
+
+linux (4.17.0-2.3) cosmic; urgency=medium
+
+  * linux: 4.17.0-2.3 -proposed tracker (LP: #1776276)
+
+  * Miscellaneous Ubuntu changes
+    - Config: remove IrDA from annotations
+    - Config: remove scsi drivers from annotations
+    - Config: remove BT_HCIBTUART from annotations
+    - Config: pstore zlib support was renamed
+    - Config: disable NVRAM for armhf on annotations
+    - Config: Disable VT on s390x
+    - Config: Update SSB and B43/B44 options
+    - Config: some options not supported on some arches anymore
+    - Config: renamed and removed options
+    - Config: TCG_CRB is required for IMA on ACPI systems
+    - Config: EXTCON_AXP288 depends on X86
+    - Config: CONFIG_FSI depends on OF
+    - Config: DRM_RCAR_LVDS now depends on DRM
+    - CONFIG: Allow CONFIG_LEDS_MLXCPLD for i386
+    - Config: Enable HINIC on arm64
+    - Config: Set PPS and PTP_1588_CLOCK as y
+    - Config: Some NF_TABLES options are built-in now
+    - Config: GENERIC_CPU for ppc64el
+    - Config: KEXEC_FILE=n for s390x
+    - Config: CRYPTO_DEFLATE is needed by PSTORE_DEFLATE_COMPRESS
+    - Config: Disable STM32 support
+    - Config: Enable FORTIFY_SOURCE for armhf
+    - Config: use STRONG instead of AUTO for CC_STACKPROTECTOR
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.17
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Mon, 11 Jun 2018 15:22:10 -0300
+
+linux (4.17.0-1.2) cosmic; urgency=medium
+
+  [ Seth Forshee ]
+  * [Config] enable EDAC_DEBUG on ARM64 (LP: #1772516)
+    - [Config]: set CONFIG_EDAC_DEBUG=y for ARM64
+
+  * Ubuntu 18.04 kernel crashed while in degraded mode (LP: #1770849)
+    - SAUCE: powerpc/perf: Fix memory allocation for core-imc based on
+      num_possible_cpus()
+
+  * Integrated Webcam Realtek Integrated_Webcam_HD (0bda:58f4) not working in
+    DELL XPS 13 9370 with firmware 1.50 (LP: #1763748)
+    - SAUCE: media: uvcvideo: Support realtek's UVC 1.5 device
+
+  * Switch Build-Depends: transfig to fig2dev (LP: #1770770)
+    - [Config] update Build-Depends: transfig to fig2dev
+
+  * update-initramfs not adding i915 GuC firmware for Kaby Lake, firmware fails
+    to load (LP: #1728238)
+    - Revert "UBUNTU: SAUCE: (no-up) i915: Remove MODULE_FIRMWARE statements for
+      unreleased firmware"
+
+  * No driver for Huawei network adapters on arm64 (LP: #1769899)
+    - net-next/hinic: add arm64 support
+
+  * linux-snapdragon: reduce EPROBEDEFER noise during boot (LP: #1768761)
+    - [Config] snapdragon: DRM_I2C_ADV7511=y
+
+  * Add d-i support for Huawei NICs (LP: #1767490)
+    - d-i: add hinic to nic-modules udeb
+
+  * Acer Swift sf314-52 power button not managed  (LP: #1766054)
+    - SAUCE: platform/x86: acer-wmi: add another KEY_POWER keycode
+
+  * Include nfp driver in linux-modules (LP: #1768526)
+    - [Config] Add nfp.ko to generic inclusion list
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Import aufs driver
+    - [Config] Enable AUFS config options
+    - SAUCE: (efi-lockdown) Fix for module sig verification
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) efi: Add an EFI_SECURE_BOOT flag to indicate secure
+      boot mode
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) efi: Don't print secure boot state from the efi stub
+    - [Config] CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT=y
+    - SAUCE: (efi-lockdown) really lock down kernel under EFI secure boot
+    - SAUCE: (noup) Update spl to 0.7.5-1ubuntu3, zfs to 0.7.5-1ubuntu17
+    - enable zfs build
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) ima: require secure_boot rules in
+      lockdown mode"
+    - Rebased to v4.17-rc6
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Tue, 22 May 2018 14:48:13 -0300
+
+linux (4.17.0-0.1) bionic; urgency=medium
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.17-rc4
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Tue, 08 May 2018 16:38:51 -0300
+
+linux (4.17.0-0.0) bionic; urgency=medium
+
+  * Dummy entry.
+
+ -- Thadeu Lima de Souza Cascardo <cascardo@canonical.com>  Fri, 27 Apr 2018 11:01:13 -0300
+
+linux (4.16.0-4.5) bionic; urgency=medium
+
+  * [18.04 FEAT] Add kvm_stat from kernel tree (LP: #1734130)
+    - tools/kvm_stat: Fix python3 syntax
+    - tools/kvm_stat: Don't use deprecated file()
+    - tools/kvm_stat: Remove unused function
+    - [Packaging] Add linux-tools-host package for VM host tools
+    - [Config] do_tools_host=true for amd64
+
+  * [Featire] CNL: Enable RAPL support (LP: #1685712)
+    - powercap: RAPL: Add support for Cannon Lake
+
+  * Bionic update to v4.16.2 stable release (LP: #1763388)
+    - sparc64: Oracle DAX driver depends on SPARC64
+    - arp: fix arp_filter on l3slave devices
+    - net: dsa: Discard frames from unused ports
+    - net/ipv6: Increment OUTxxx counters after netfilter hook
+    - net/sched: fix NULL dereference in the error path of tcf_bpf_init()
+    - pptp: remove a buggy dst release in pptp_connect()
+    - sctp: do not leak kernel memory to user space
+    - sctp: sctp_sockaddr_af must check minimal addr length for AF_INET6
+    - vlan: also check phy_driver ts_info for vlan's real device
+    - net: fool proof dev_valid_name()
+    - ip_tunnel: better validate user provided tunnel names
+    - ipv6: sit: better validate user provided tunnel names
+    - ip6_gre: better validate user provided tunnel names
+    - ip6_tunnel: better validate user provided tunnel names
+    - vti6: better validate user provided tunnel names
+    - net_sched: fix a missing idr_remove() in u32_delete_key()
+    - nfp: use full 40 bits of the NSP buffer address
+    - Linux 4.16.2
+
+  * sky2 gigabit ethernet driver sometimes stops working after lid-open resume
+    from sleep (88E8055) (LP: #1758507) // Bionic update to v4.16.2 stable
+    release (LP: #1763388)
+    - sky2: Increase D3 delay to sky2 stops working after suspend
+
+  * Merge the linux-snapdragon kernel into bionic master/snapdragon
+    (LP: #1763040)
+    - arm64: defconfig: enable REMOTEPROC
+    - arm64: defconfig: enable QCOM audio drivers for APQ8016 and DB410c
+    - kernel: configs; add distro.config
+    - arm64: configs: enable WCN36xx
+    - kernel: distro.config: enable debug friendly USB network adpater
+    - arm64: configs: enable QCOM Venus
+    - arm64: defconfig: Enable a53/apcs and avs
+    - arm64: defconfig: enable ondemand governor as default
+    - arm64: defconfig: enable QCOM_TSENS
+    - kernel: configs: enable dm_mod and dm_crypt
+    - Force the SMD regulator driver to be compiled-in
+    - arm64: defconfig: enable CFG80211_DEFAULT_PS by default
+    - arm64: configs: enable BT_QCOMSMD
+    - kernel: configs: add more USB net drivers
+    - arm64: defconfig: disable ANALOG_TV and DIGITAL_TV
+    - arm64: configs: Enable camera drivers
+    - kernel: configs: add freq stat to sysfs
+    - arm64: defconfig: enable CONFIG_USB_CONFIGFS_F_FS by default
+    - arm64: defconfig: Enable QRTR features
+    - kernel: configs: set USB_CONFIG_F_FS in distro.config
+    - kernel: distro.config: enable 'schedutil' CPUfreq governor
+    - kernel: distro.config: enable 'fq' and 'fq_codel' qdiscs
+    - kernel: distro.config: enable 'BBR' TCP congestion algorithm
+    - arm64: defconfig: enable LEDS_QCOM_LPG
+    - HACK: drm/msm/iommu: Remove runtime_put calls in map/unmap
+    - power: avs: Add support for CPR (Core Power Reduction)
+    - power: avs: cpr: Use raw mem access for qfprom
+    - power: avs: cpr: fix with new reg_sequence structures
+    - power: avs: cpr: Register with cpufreq-dt
+    - regulator: smd: Add floor and corner operations
+    - PM / OPP: Support adjusting OPP voltages at runtime
+    - PM / OPP: Drop RCU usage in dev_pm_opp_adjust_voltage()
+    - PM / OPP: HACK: Allow to set regulator without opp_list
+    - PM / OPP: Add a helper to get an opp regulator for device
+    - cpufreq: Add apq8016 to cpufreq-dt-platdev blacklist
+    - regulator: smd: Allow REGULATOR_QCOM_SMD_RPM=m
+    - ov5645: I2C address change
+    - i2c: Add Qualcomm Camera Control Interface driver
+    - camss: vfe: Skip first four frames from sensor
+    - camss: Do not register if no cameras are present
+    - i2c-qcom-cci: Fix run queue completion timeout
+    - i2c-qcom-cci: Fix I2C address bug
+    - media: ov5645: Fix I2C address
+    - drm/bridge/adv7511: Delay clearing of HPD interrupt status
+    - HACK: drm/msm/adv7511: Don't rely on interrupts for EDID parsing
+    - leds: Add driver for Qualcomm LPG
+    - wcn36xx: Fix warning due to duplicate scan_completed notification
+    - arm64: dts: Add CPR DT node for msm8916
+    - arm64: dts: add spmi-regulator nodes
+    - arm64: dts: msm8916: Add cpufreq support
+    - arm64: dts: msm8916: Add a shared CPU opp table
+    - arm64: dts: msm8916: Add cpu cooling maps
+    - arm64: dts: pm8916: Mark the s2 regulator as always-on
+    - arm64: dts: qcom: msm8916: Add msm8916 A53 PLL DT node
+    - arm64: dts: qcom: msm8916: Use the new APCS mailbox driver
+    - arm64: dts: qcom: msm8916: Add clock properties to the APCS node
+    - dt-bindings: media: Binding document for Qualcomm Camera Control Interface
+      driver
+    - MAINTAINERS: Add Qualcomm Camera Control Interface driver
+    - DT: leds: Add Qualcomm Light Pulse Generator binding
+    - arm64: dts: qcom: msm8996: Add mpp and lpg blocks
+    - arm64: dts: qcom: Add pwm node for pm8916
+    - arm64: dts: qcom: Add user LEDs on db820c
+    - arm64: dts: qcom: Add WiFI/BT LEDs on db820c
+    - ARM: dts: qcom: Add LPG node to pm8941
+    - ARM: dts: qcom: honami: Add LPG node and RGB LED
+    - arm64: dts: qcom: Add Camera Control Interface support
+    - arm64: dts: qcom: Add apps_iommu vfe child node
+    - arm64: dts: qcom: Add camss device node
+    - arm64: dts: qcom: Add ov5645 device nodes
+    - arm64: dts: msm8916: Fix camera sensors I2C addresses
+    - arm: dts: qcom: db410c: Enable PWM signal on MPP4
+    - packaging: arm64: add a uboot flavour - part1
+    - packaging: arm64: add a uboot flavour - part2
+    - packaging: arm64: add a uboot flavour - part3
+    - packaging: arm64: add a uboot flavour - part4
+    - packaging: arm64: add a uboot flavour - part5
+    - packaging: arm64: rename uboot flavour to snapdragon
+    - [Config] updateconfigs after qcomlt import
+    - [Config] arm64: snapdragon: COMMON_CLK_QCOM=y
+    - [Config] arm64: snapdragon: MSM_GCC_8916=y
+    - [Config] arm64: snapdragon: REGULATOR_FIXED_VOLTAGE=y
+    - [Config] arm64: snapdragon: PINCTRL_MSM8916=y
+    - [Config] arm64: snapdragon: HWSPINLOCK_QCOM=y
+    - [Config] arm64: snapdragon: SPMI=y, SPMI_MSM_PMIC_ARB=y
+    - [Config] arm64: snapdragon: REGMAP_SPMI=y, PINCTRL_QCOM_SPMI_PMIC=y
+    - [Config] arm64: snapdragon: REGULATOR_QCOM_SPMI=y
+    - [Config] arm64: snapdragon: MFD_SPMI_PMIC=y
+    - [Config] arm64: snapdragon: QCOM_SMEM=y
+    - [Config] arm64: snapdragon: RPMSG=y, RPMSG_QCOM_SMD=y
+    - [Config] arm64: snapdragon: QCOM_SMD_RPM=y, REGULATOR_QCOM_SMD_RPM=y
+    - [Config] arm64: snapdragon: QCOM_CLK_SMD_RPM=y
+    - [Config] arm64: snapdragon: QCOM_BAM_DMA=y
+    - [Config] arm64: snapdragon: QCOM_HIDMA=y, QCOM_HIDMA_MGMT=y
+    - [Config] arm64: snapdragon: QCOM_CPR=y
+    - [Config] arm64: snapdragon: QCOM_QFPROM=y, QCOM_TSENS=y
+    - [Config] arm64: snapdragon: MMC_SDHCI=y, MMC_SDHCI_PLTFM=y, MMC_SDHCI_MSM=y
+    - [Config] turn off DRM_MSM_REGISTER_LOGGING
+    - [Config] arm64: snapdragon: I2C_QUP=y
+    - [Config] arm64: snapdragon: SPI_QUP=y
+    - [Config] arm64: snapdragon: USB_ULPI_BUS=y, PHY_QCOM_USB_HS=y
+    - [Config] arm64: snapdragon: QCOM_APCS_IPC=y
+    - [Config] arm64: snapdragon: QCOM_WCNSS_CTRL=y
+    - [Config] arm64: snapdragon: QCOM_SMSM=y
+    - [Config] arm64: snapdragon: QCOM_SMP2P=y
+    - [Config] arm64: snapdragon: DRM_MSM=y
+    - [Config] arm64: snapdragon: SND_SOC=y
+    - [Config] arm64: snapdragon: QCOM_WCNSS_PIL=m
+    - [Config] arm64: snapdragon: INPUT_PM8941_PWRKEY=y
+    - [Config] arm64: snapdragon: MEDIA_SUBDRV_AUTOSELECT=y, VIDEO_OV5645=m
+    - [Config] arm64: snapdragon: SND_SOC_APQ8016_SBC=y, SND_SOC_LPASS_APQ8016=y
+    - [Config] arm64: snapdragon: SND_SOC_MSM8916_WCD_ANALOG=y,
+      SND_SOC_MSM8916_WCD_DIGITAL=y
+    - SAUCE: media: ov5645: skip address change if dt addr == default addr
+    - SAUCE: drm/msm/adv7511: wrap hacks under CONFIG_ADV7511_SNAPDRAGON_HACKS
+      #ifdefs
+    - [Config] arm64: snapdragon: ADV7511_SNAPDRAGON_HACKS=y
+    - [Packaging] fix up snapdragon abi paths
+
+  * LSM stacking patches for bionic (LP: #1763062)
+    - SAUCE: LSM stacking: procfs: add smack subdir to attrs
+    - SAUCE: LSM stacking: LSM: Manage credential security blobs
+    - SAUCE: LSM stacking: LSM: Manage file security blobs
+    - SAUCE: LSM stacking: LSM: Manage task security blobs
+    - SAUCE: LSM stacking: LSM: Manage remaining security blobs
+    - SAUCE: LSM stacking: LSM: General stacking
+    - SAUCE: LSM stacking: fixup initialize task->security
+    - SAUCE: LSM stacking: fixup: alloc_task_ctx is dead code
+    - SAUCE: LSM stacking: add support for stacking getpeersec_stream
+    - SAUCE: LSM stacking: add stacking support to apparmor network hooks
+    - SAUCE: LSM stacking: fixup apparmor stacking enablement
+    - SAUCE: LSM stacking: fixup stacking kconfig
+    - SAUCE: LSM stacking: allow selecting multiple LSMs using kernel boot params
+    - SAUCE: LSM stacking: provide prctl interface for setting context
+    - SAUCE: LSM stacking: inherit current display LSM
+    - SAUCE: LSM stacking: keep an index for each registered LSM
+    - SAUCE: LSM stacking: verify display LSM
+    - SAUCE: LSM stacking: provide a way to specify the default display lsm
+    - SAUCE: LSM stacking: make sure LSM blob align on 64 bit boundaries
+    - SAUCE: LSM stacking: add /proc/<pid>/attr/display_lsm
+    - SAUCE: LSM stacking: add Kconfig to set default display LSM
+    - SAUCE: LSM stacking: add configs for LSM stacking
+    - SAUCE: LSM stacking: add apparmor and selinux proc dirs
+    - SAUCE: LSM stacking: remove procfs context interface
+
+  * linux 4.13.0-13.14 ADT test failure with linux 4.13.0-13.14
+    (LP: #1720779) // LSM stacking patches for bionic (LP: #1763062)
+    - SAUCE: LSM stacking: check for invalid zero sized writes
+
+  * Support cq/rq record doorbell for RDMA on HSilicon hip08 systems
+    (LP: #1762755)
+    - RDMA/hns: Support rq record doorbell for the user space
+    - RDMA/hns: Support cq record doorbell for the user space
+    - RDMA/hns: Support rq record doorbell for kernel space
+    - RDMA/hns: Support cq record doorbell for kernel space
+    - RDMA/hns: Fix cqn type and init resp
+    - RDMA/hns: Fix init resp when alloc ucontext
+    - RDMA/hns: Fix cq record doorbell enable in kernel
+
+  * Replace LPC patchset with upstream version (LP: #1762758)
+    - Revert "UBUNTU: SAUCE: MAINTAINERS: Add maintainer for HiSilicon LPC driver"
+    - Revert "UBUNTU: SAUCE: HISI LPC: Add ACPI support"
+    - Revert "UBUNTU: SAUCE: ACPI / scan: do not enumerate Indirect IO host
+      children"
+    - Revert "UBUNTU: SAUCE: HISI LPC: Support the LPC host on Hip06/Hip07 with DT
+      bindings"
+    - Revert "UBUNTU: SAUCE: OF: Add missing I/O range exception for indirect-IO
+      devices"
+    - Revert "UBUNTU: SAUCE: PCI: Apply the new generic I/O management on PCI IO
+      hosts"
+    - Revert "UBUNTU: SAUCE: PCI: Add fwnode handler as input param of
+      pci_register_io_range()"
+    - Revert "UBUNTU: SAUCE: PCI: Remove unused __weak attribute in
+      pci_register_io_range()"
+    - Revert "UBUNTU: SAUCE: LIB: Introduce a generic PIO mapping method"
+    - lib: Add generic PIO mapping method
+    - PCI: Remove __weak tag from pci_register_io_range()
+    - PCI: Add fwnode handler as input param of pci_register_io_range()
+    - PCI: Apply the new generic I/O management on PCI IO hosts
+    - of: Add missing I/O range exception for indirect-IO devices
+    - HISI LPC: Support the LPC host on Hip06/Hip07 with DT bindings
+    - ACPI / scan: Rename acpi_is_serial_bus_slave() for more general use
+    - ACPI / scan: Do not enumerate Indirect IO host children
+    - HISI LPC: Add ACPI support
+    - MAINTAINERS: Add John Garry as maintainer for HiSilicon LPC driver
+
+  * Enable Tunneled Operations on POWER9 (LP: #1762448)
+    - powerpc/powernv: Enable tunneled operations
+    - cxl: read PHB indications from the device tree
+
+  * PSL traces reset after PERST for debug AFU image (LP: #1762462)
+    - cxl: Enable NORST bit in PSL_DEBUG register for PSL9
+
+  * NFS + sec=krb5 is broken (LP: #1759791)
+    - sunrpc: remove incorrect HMAC request initialization
+
+  * Raspberry Pi 3 microSD support missing from the installer (LP: #1729128)
+    - d-i: add bcm2835 to block-modules
+
+  * Backport USB core quirks (LP: #1762695)
+    - usb: core: Add "quirks" parameter for usbcore
+    - usb: core: Copy parameter string correctly and remove superfluous null check
+    - usb: core: Add USB_QUIRK_DELAY_CTRL_MSG to usbcore quirks
+
+  * [Ubuntu 18.04] cryptsetup: 'device-mapper: reload ioctl on  failed' when
+    setting up a second end-to-end encrypted disk (LP: #1762353)
+    - SAUCE: s390/crypto: Adjust s390 aes and paes cipher
+
+  * System Z {kernel} UBUNTU18.04 wrong kernel config (LP: #1762719)
+    - s390: move nobp parameter functions to nospec-branch.c
+    - s390: add automatic detection of the spectre defense
+    - s390: report spectre mitigation via syslog
+    - s390: add sysfs attributes for spectre
+    - [Config] CONFIG_EXPOLINE_AUTO=y, CONFIG_KERNEL_NOBP=n for s390
+    - s390: correct nospec auto detection init order
+
+  * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5715
+    - powerpc/64s: Wire up cpu_show_spectre_v2()
+
+  * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5753
+    - powerpc/64s: Wire up cpu_show_spectre_v1()
+
+  * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5754
+    - powerpc/rfi-flush: Move the logic to avoid a redo into the debugfs code
+    - powerpc/rfi-flush: Make it possible to call setup_rfi_flush() again
+    - powerpc/rfi-flush: Always enable fallback flush on pseries
+    - powerpc/rfi-flush: Differentiate enabled and patched flush types
+    - powerpc/rfi-flush: Call setup_rfi_flush() after LPM migration
+    - powerpc/64s: Move cpu_show_meltdown()
+    - powerpc/64s: Enhance the information in cpu_show_meltdown()
+    - powerpc/powernv: Use the security flags in pnv_setup_rfi_flush()
+    - powerpc/pseries: Use the security flags in pseries_setup_rfi_flush()
+
+  * Additional spectre and meltdown patches (LP: #1760099) // CVE-2017-5715 //
+    CVE-2017-5753 // CVE-2017-5754
+    - powerpc/pseries: Add new H_GET_CPU_CHARACTERISTICS flags
+    - powerpc: Add security feature flags for Spectre/Meltdown
+    - powerpc/pseries: Set or clear security feature flags
+    - powerpc/powernv: Set or clear security feature flags
+
+  * Hisilicon network subsystem 3 support (LP: #1761610)
+    - net: hns3: export pci table of hclge and hclgevf to userspace
+    - d-i: Add hns3 drivers to nic-modules
+
+  * "ip a" command on a guest VM shows UNKNOWN status (LP: #1761534)
+    - virtio-net: Fix operstate for virtio when no VIRTIO_NET_F_STATUS
+
+  * perf vendor events arm64: Enable JSON events for ThunderX2 B0 (LP: #1760712)
+    - perf vendor events: Drop incomplete multiple mapfile support
+    - perf vendor events: Fix error code in json_events()
+    - perf vendor events: Drop support for unused topic directories
+    - perf vendor events: Add support for pmu events vendor subdirectory
+    - perf vendor events arm64: Relocate ThunderX2 JSON to cavium subdirectory
+    - perf vendor events arm64: Relocate Cortex A53 JSONs to arm subdirectory
+    - perf vendor events: Add support for arch standard events
+    - perf vendor events arm64: Add armv8-recommended.json
+    - perf vendor events arm64: Fixup ThunderX2 to use recommended events
+    - perf vendor events arm64: fixup A53 to use recommended events
+    - perf vendor events arm64: add HiSilicon hip08 JSON file
+    - perf vendor events arm64: Enable JSON events for ThunderX2 B0
+
+  * Warning "cache flush timed out!" seen when unloading the cxl driver
+    (LP: #1762367)
+    - cxl: Check if PSL data-cache is available before issue flush request
+
+  * Bionic update to v4.16.1 stable release (LP: #1763170)
+    - bitmap: fix memset optimization on big-endian systems
+    - USB: serial: ftdi_sio: add RT Systems VX-8 cable
+    - USB: serial: ftdi_sio: add support for Harman FirmwareHubEmulator
+    - USB: serial: cp210x: add ELDAT Easywave RX09 id
+    - serial: 8250: Add Nuvoton NPCM UART
+    - mei: remove dev_err message on an unsupported ioctl
+    - /dev/mem: Avoid overwriting "err" in read_mem()
+    - media: usbtv: prevent double free in error case
+    - parport_pc: Add support for WCH CH382L PCI-E single parallel port card.
+    - crypto: lrw - Free rctx->ext with kzfree
+    - crypto: ccp - Fill the result buffer only on digest, finup, and final ops
+    - crypto: talitos - don't persistently map req_ctx->hw_context and
+      req_ctx->buf
+    - crypto: inside-secure - fix clock management
+    - crypto: testmgr - Fix incorrect values in PKCS#1 test vector
+    - crypto: talitos - fix IPsec cipher in length
+    - crypto: ahash - Fix early termination in hash walk
+    - crypto: caam - Fix null dereference at error path
+    - crypto: ccp - return an actual key size from RSA max_size callback
+    - crypto: arm,arm64 - Fix random regeneration of S_shipped
+    - crypto: x86/cast5-avx - fix ECB encryption when long sg follows short one
+    - Bluetooth: hci_bcm: Add 6 new ACPI HIDs
+    - Btrfs: fix unexpected cow in run_delalloc_nocow
+    - siox: fix possible buffer overflow in device_add_store
+    - staging: comedi: ni_mio_common: ack ai fifo error interrupts.
+    - Revert "base: arch_topology: fix section mismatch build warnings"
+    - Input: ALPS - fix TrackStick detection on Thinkpad L570 and Latitude 7370
+    - Input: i8042 - add Lenovo ThinkPad L460 to i8042 reset list
+    - Input: i8042 - enable MUX on Sony VAIO VGN-CS series to fix touchpad
+    - vt: change SGR 21 to follow the standards
+    - Fix slab name "biovec-(1<<(21-12))"
+    - signal: Correct the offset of si_pkey and si_lower in struct siginfo on m68k
+    - Linux 4.16.1
+
+  * [18.04][config] regression: nvme and nvme_core couldn't be built as modules
+    starting 4.15-rc2 (LP: #1759893)
+    - SAUCE: Revert "lightnvm: include NVM Express driver if OCSSD is selected for
+      build"
+    - [Config] CONFIG_BLK_DEV_NMVE=m
+
+  * FFe: Enable configuring resume offset via sysfs (LP: #1760106)
+    - PM / hibernate: Make passing hibernate offsets more friendly
+
+  * Ubuntu18.04:POWER9:DD2.2 - Unable to start a KVM guest with default machine
+    type(pseries-bionic) complaining "KVM implementation does not support
+    Transactional Memory, try cap-htm=off" (kvm) (LP: #1752026)
+    - powerpc: Use feature bit for RTC presence rather than timebase presence
+    - powerpc: Book E: Remove unused CPU_FTR_L2CSR bit
+    - powerpc: Free up CPU feature bits on 64-bit machines
+    - powerpc: Add CPU feature bits for TM bug workarounds on POWER9 v2.2
+    - powerpc/powernv: Provide a way to force a core into SMT4 mode
+    - KVM: PPC: Book3S HV: Work around transactional memory bugs in POWER9
+    - KVM: PPC: Book3S HV: Work around XER[SO] bug in fake suspend mode
+    - KVM: PPC: Book3S HV: Work around TEXASR bug in fake suspend state
+
+  * [Feature][CFL][ICL] [CNL]Thunderbolt support (Titan Ridge) (LP: #1730775)
+    - thunderbolt: Resume control channel after hibernation image is created
+    - thunderbolt: Serialize PCIe tunnel creation with PCI rescan
+    - thunderbolt: Handle connecting device in place of host properly
+    - thunderbolt: Do not overwrite error code when domain adding fails
+    - thunderbolt: Wait a bit longer for root switch config space
+    - thunderbolt: Wait a bit longer for ICM to authenticate the active NVM
+    - thunderbolt: Handle rejected Thunderbolt devices
+    - thunderbolt: Factor common ICM add and update operations out
+    - thunderbolt: Correct function name in kernel-doc comment
+    - thunderbolt: Add tb_switch_get()
+    - thunderbolt: Add tb_switch_find_by_route()
+    - thunderbolt: Add tb_xdomain_find_by_route()
+    - thunderbolt: Add constant for approval timeout
+    - thunderbolt: Move driver ready handling to struct icm
+    - thunderbolt: Add 'boot' attribute for devices
+    - thunderbolt: Add support for preboot ACL
+    - thunderbolt: Introduce USB only (SL4) security level
+    - thunderbolt: Add support for Intel Titan Ridge
+
+  * QCA9377 requires more IRAM banks for its new firmware (LP: #1748345)
+    - ath10k: update the IRAM bank number for QCA9377
+
+  * Fix an issue that when system in S3, USB keyboard can't wake up the system.
+    (LP: #1759511)
+    - ACPI / PM: Allow deeper wakeup power states with no _SxD nor _SxW
+
+  * cxl: Fix timebase synchronization status on POWER9 missing (CAPI)
+    (LP: #1757228)
+    - cxl: Fix timebase synchronization status on P9
+
+  * [Feature]Update Ubuntu 18.04 lpfc FC driver with 32/64GB HBA support and bug
+    fixes (LP: #1752182)
+    - scsi: lpfc: Fix frequency of Release WQE CQEs
+    - scsi: lpfc: Increase CQ and WQ sizes for SCSI
+    - scsi: lpfc: move placement of target destroy on driver detach
+    - scsi: lpfc: correct debug counters for abort
+    - scsi: lpfc: Add WQ Full Logic for NVME Target
+    - scsi: lpfc: Fix PRLI handling when topology type changes
+    - scsi: lpfc: Fix IO failure during hba reset testing with nvme io.
+    - scsi: lpfc: Fix RQ empty firmware trap
+    - scsi: lpfc: Allow set of maximum outstanding SCSI cmd limit for a target
+    - scsi: lpfc: Fix soft lockup in lpfc worker thread during LIP testing
+    - scsi: lpfc: Fix issue_lip if link is disabled
+    - scsi: lpfc: Indicate CONF support in NVMe PRLI
+    - scsi: lpfc: Fix SCSI io host reset causing kernel crash
+    - scsi: lpfc: Validate adapter support for SRIU option
+    - scsi: lpfc: Fix header inclusion in lpfc_nvmet
+    - scsi: lpfc: Treat SCSI Write operation Underruns as an error
+    - scsi: lpfc: Fix nonrecovery of NVME controller after cable swap.
+    - scsi: lpfc: update driver version to 11.4.0.7
+    - scsi: lpfc: Update 11.4.0.7 modified files for 2018 Copyright
+    - scsi: lpfc: Rework lpfc to allow different sli4 cq and eq handlers
+    - scsi: lpfc: Rework sli4 doorbell infrastructure
+    - scsi: lpfc: Add SLI-4 if_type=6 support to the code base
+    - scsi: lpfc: Add push-to-adapter support to sli4
+    - scsi: lpfc: Add PCI Ids for if_type=6 hardware
+    - scsi: lpfc: Add 64G link speed support
+    - scsi: lpfc: Add if_type=6 support for cycling valid bits
+    - scsi: lpfc: Enable fw download on if_type=6 devices
+    - scsi: lpfc: Add embedded data pointers for enhanced performance
+    - scsi: lpfc: Fix nvme embedded io length on new hardware
+    - scsi: lpfc: Work around NVME cmd iu SGL type
+    - scsi: lpfc: update driver version to 12.0.0.0
+    - scsi: lpfc: Change Copyright of 12.0.0.0 modified files to 2018
+    - scsi: lpfc: use __raw_writeX on DPP copies
+    - scsi: lpfc: Add missing unlock in WQ full logic
+
+  * /dev/bcache/by-uuid links not created after reboot (LP: #1729145)
+    - SAUCE: (no-up) bcache: decouple emitting a cached_dev CHANGE uevent
+
+  * DKMS driver builds fail with: Cannot use CONFIG_STACK_VALIDATION=y, please
+    install libelf-dev, libelf-devel or elfutils-libelf-devel (LP: #1760876)
+    - [Packaging] include the retpoline extractor in the headers
+
+  * Use med_with_dipm SATA LPM to save more power for mobile platforms
+    (LP: #1759547)
+    - [Config] CONFIG_SATA_MOBILE_LPM_POLICY=3
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] Only install cloud init files when do_tools_common=true
+    - SAUCE: Import aufs driver
+    - [Config] Enable AUFS config options
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 12 Apr 2018 09:30:56 -0500
+
+linux (4.16.0-3.4) bionic; urgency=medium
+
+  * Allow multiple mounts of zfs datasets (LP: #1759848)
+    - SAUCE: Allow mounting datasets more than once (LP: #1759848)
+
+  * zfs system process hung on container stop/delete (LP: #1754584)
+    - SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)
+    - Revert "UBUNTU: SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)"
+    - SAUCE: Fix non-prefaulted page deadlock (LP: #1754584)
+
+  * ubuntu_zram_smoke test will cause soft lockup on Artful ThunderX ARM64
+    (LP: #1755073)
+    - SAUCE: crypto: thunderx_zip: Fix fallout from CONFIG_VMAP_STACK
+
+  * CAPI Flash (cxlflash) update (LP: #1752672)
+    - SAUCE: cxlflash: Preserve number of interrupts for master contexts
+    - SAUCE: cxlflash: Avoid clobbering context control register value
+    - SAUCE: cxlflash: Add argument identifier names
+    - SAUCE: cxlflash: Introduce OCXL backend
+    - SAUCE: cxlflash: Hardware AFU for OCXL
+    - SAUCE: cxlflash: Read host function configuration
+    - SAUCE: cxlflash: Setup function acTag range
+    - SAUCE: cxlflash: Read host AFU configuration
+    - SAUCE: cxlflash: Setup AFU acTag range
+    - SAUCE: cxlflash: Setup AFU PASID
+    - SAUCE: cxlflash: Adapter context support for OCXL
+    - SAUCE: cxlflash: Use IDR to manage adapter contexts
+    - SAUCE: cxlflash: Support adapter file descriptors for OCXL
+    - SAUCE: cxlflash: Support adapter context discovery
+    - SAUCE: cxlflash: Support image reload policy modification
+    - SAUCE: cxlflash: MMIO map the AFU
+    - SAUCE: cxlflash: Support starting an adapter context
+    - SAUCE: cxlflash: Support process specific mappings
+    - SAUCE: cxlflash: Support AFU state toggling
+    - SAUCE: cxlflash: Support reading adapter VPD data
+    - SAUCE: cxlflash: Setup function OCXL link
+    - SAUCE: cxlflash: Setup OCXL transaction layer
+    - SAUCE: cxlflash: Support process element lifecycle
+    - SAUCE: cxlflash: Support AFU interrupt management
+    - SAUCE: cxlflash: Support AFU interrupt mapping and registration
+    - SAUCE: cxlflash: Support starting user contexts
+    - SAUCE: cxlflash: Support adapter context polling
+    - SAUCE: cxlflash: Support adapter context reading
+    - SAUCE: cxlflash: Support adapter context mmap and release
+    - SAUCE: cxlflash: Support file descriptor mapping
+    - SAUCE: cxlflash: Introduce object handle fop
+    - SAUCE: cxlflash: Setup LISNs for user contexts
+    - SAUCE: cxlflash: Setup LISNs for master contexts
+    - SAUCE: cxlflash: Update synchronous interrupt status bits
+    - SAUCE: cxlflash: Introduce OCXL context state machine
+    - SAUCE: cxlflash: Register for translation errors
+    - SAUCE: cxlflash: Support AFU reset
+    - SAUCE: cxlflash: Enable OCXL operations
+
+  * [Artful][Wyse 3040] System hang when trying to enable an offlined CPU core
+    (LP: #1736393)
+    - SAUCE: drm/i915:Don't set chip specific data
+    - SAUCE: drm/i915: make previous commit affects Wyse 3040 only
+
+  * zed process consuming 100% cpu (LP: #1751796)
+    - SAUCE: Fix ioctl loop-spin in zed (LP: #1751796)
+
+  * Ubuntu18.04:PowerPC - Set Transparent Huge Pages (THP) by default to
+    "always" (LP: #1753708)
+    - Config: Set TRANSPARENT_HUGEPAGE_ALWAYS=y on ppc64el
+
+  * retpoline hints: primary infrastructure and initial hints (LP: #1758856)
+    - [Packaging] retpoline -- add safe usage hint support
+    - [Packaging] retpoline-check -- only report additions
+    - [Packaging] retpoline -- widen indirect call/jmp detection
+    - [Packaging] retpoline -- elide %rip relative indirections
+    - [Packaging] retpoline -- clear hint information from packages
+    - SAUCE: apm -- annotate indirect calls within
+      firmware_restrict_branch_speculation_{start,end}
+    - SAUCE: EFI -- annotate indirect calls within
+      firmware_restrict_branch_speculation_{start,end}
+    - SAUCE: early/late -- annotate indirect calls in early/late initialisation
+      code
+    - SAUCE: vga_set_mode -- avoid jump tables
+    - [Config] retpoine -- switch to new format
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] final-checks -- remove check for empty retpoline files
+    - [Packaging] skip cloud tools packaging when not building package
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.16
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 02 Apr 2018 16:15:36 -0500
+
+linux (4.16.0-2.3) bionic; urgency=medium
+
+  * devpts: handle bind-mounts (LP: #1755857)
+    - SAUCE: devpts: hoist out check for DEVPTS_SUPER_MAGIC
+    - SAUCE: devpts: resolve devpts bind-mounts
+    - SAUCE: devpts: comment devpts_mntget()
+    - SAUCE: selftests: add devpts selftests
+
+  * [bionic][arm64] d-i: add hisi_sas_v3_hw to scsi-modules (LP: #1756103)
+    - d-i: add hisi_sas_v3_hw to scsi-modules
+
+  * [Bionic][ARM64] PCI and SAS driver patches for hip08 SoCs (LP: #1756094)
+    - SAUCE: scsi: hisi_sas: config for hip08 ES
+    - SAUCE: scsi: hisi_sas: export device table of v3 hw to userspace
+
+  * s390/crypto: Fix kernel crash on aes_s390 module remove (LP: #1753424)
+    - SAUCE: s390/crypto: Fix kernel crash on aes_s390 module remove.
+
+  * Fix ARC hit rate (LP: #1755158)
+    - SAUCE: Fix ARC hit rate (LP: #1755158)
+
+  * ZFS setgid broken on 0.7 (LP: #1753288)
+    - SAUCE: Fix ZFS setgid
+
+  * CONFIG_EFI=y on armhf (LP: #1726362)
+    - [Config] CONFIG_EFI=y on armhf, reconcile secureboot EFI settings
+
+  * [Feature] Add xHCI debug device support in the driver (LP: #1730832)
+    - [Config] CONFIG_USB_XHCI_DBGCAP=y
+
+  * retpoline: ignore %cs:0xNNN constant indirections (LP: #1752655)
+    - [Packaging] retpoline -- elide %cs:0xNNNN constants on i386
+    - [Config] retpoline -- clean up i386 retpoline files
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] retpoline-extract: flag *0xNNN(%reg) branches
+    - [Config] fix up retpoline abi files
+    - [Config] fix up retpoline abi files
+    - d-i: Add netsec to nic-modules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.16-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 19 Mar 2018 14:09:49 -0500
+
+linux (4.16.0-1.2) bionic; urgency=medium
+
+  * Driver not found in Ubuntu kernel does not detect interface (LP: #1745927)
+    - d-i: add cxgb4 to nic-modules
+
+  * Support low-pin-count devices on Hisilicon SoCs (LP: #1677319)
+    - [Config] CONFIG_INDIRECT_PIO=y
+    - SAUCE: LIB: Introduce a generic PIO mapping method
+    - SAUCE: PCI: Remove unused __weak attribute in pci_register_io_range()
+    - SAUCE: PCI: Add fwnode handler as input param of pci_register_io_range()
+    - SAUCE: PCI: Apply the new generic I/O management on PCI IO hosts
+    - SAUCE: OF: Add missing I/O range exception for indirect-IO devices
+    - [Config] CONFIG_HISILICON_LPC=y
+    - SAUCE: HISI LPC: Support the LPC host on Hip06/Hip07 with DT bindings
+    - SAUCE: ACPI / scan: do not enumerate Indirect IO host children
+    - SAUCE: HISI LPC: Add ACPI support
+    - SAUCE: MAINTAINERS: Add maintainer for HiSilicon LPC driver
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: tools: use CC for linking acpi tools
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.16-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 28 Feb 2018 10:17:23 -0600
+
+linux (4.16.0-0.1) bionic; urgency=medium
+
+  * retpoline abi files are empty on i386 (LP: #1751021)
+    - [Packaging] retpoline-extract -- instantiate retpoline files for i386
+    - [Packaging] final-checks -- sanity checking ABI contents
+    - [Packaging] final-checks -- check for empty retpoline files
+
+  * Miscellaneous upstream changes
+    - disable vbox build
+    - Disable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.16-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 22 Feb 2018 08:58:57 -0600
+
+linux (4.16.0-0.0) bionic; urgency=medium
+
+  * Dummy entry
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 21 Feb 2018 14:33:13 -0600
+
+linux (4.15.0-10.11) bionic; urgency=medium
+
+  * linux: 4.15.0-10.11 -proposed tracker (LP: #1749250)
+
+  * "swiotlb: coherent allocation failed" dmesg spam with linux 4.15.0-9.10
+    (LP: #1749202)
+    - swiotlb: suppress warning when __GFP_NOWARN is set
+    - drm/ttm: specify DMA_ATTR_NO_WARN for huge page pools
+
+  * linux-tools: perf incorrectly linking libbfd (LP: #1748922)
+    - SAUCE: tools -- add ability to disable libbfd
+    - [Packaging] correct disablement of libbfd
+
+  * [Artful] Realtek ALC225: 2 secs noise when a headset plugged in
+    (LP: #1744058)
+    - ALSA: hda/realtek - update ALC225 depop optimize
+
+  * [Artful] Support headset mode for DELL WYSE (LP: #1723913)
+    - SAUCE: ALSA: hda/realtek - Add support headset mode for DELL WYSE
+
+  * headset mic can't be detected on two Dell machines (LP: #1748807)
+    - ALSA: hda/realtek - Support headset mode for ALC215/ALC285/ALC289
+    - ALSA: hda - Fix headset mic detection problem for two Dell machines
+
+  * Bionic update to v4.15.3 stable release (LP: #1749191)
+    - ip6mr: fix stale iterator
+    - net: igmp: add a missing rcu locking section
+    - qlcnic: fix deadlock bug
+    - qmi_wwan: Add support for Quectel EP06
+    - r8169: fix RTL8168EP take too long to complete driver initialization.
+    - tcp: release sk_frag.page in tcp_disconnect
+    - vhost_net: stop device during reset owner
+    - ipv6: addrconf: break critical section in addrconf_verify_rtnl()
+    - ipv6: change route cache aging logic
+    - Revert "defer call to mem_cgroup_sk_alloc()"
+    - net: ipv6: send unsolicited NA after DAD
+    - rocker: fix possible null pointer dereference in
+      rocker_router_fib_event_work
+    - tcp_bbr: fix pacing_gain to always be unity when using lt_bw
+    - cls_u32: add missing RCU annotation.
+    - ipv6: Fix SO_REUSEPORT UDP socket with implicit sk_ipv6only
+    - soreuseport: fix mem leak in reuseport_add_sock()
+    - net_sched: get rid of rcu_barrier() in tcf_block_put_ext()
+    - net: sched: fix use-after-free in tcf_block_put_ext
+    - media: mtk-vcodec: add missing MODULE_LICENSE/DESCRIPTION
+    - media: soc_camera: soc_scale_crop: add missing
+      MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - media: tegra-cec: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - gpio: uniphier: fix mismatch between license text and MODULE_LICENSE
+    - crypto: tcrypt - fix S/G table for test_aead_speed()
+    - Linux 4.15.3
+
+  * bnx2x_attn_int_deasserted3:4323 MC assert! (LP: #1715519) //
+    CVE-2018-1000026
+    - net: create skb_gso_validate_mac_len()
+    - bnx2x: disable GSO where gso_size is too big for hardware
+
+  * ethtool -p fails to light NIC LED on HiSilicon D05 systems (LP: #1748567)
+    - net: hns: add ACPI mode support for ethtool -p
+
+  * CVE-2017-5715 (Spectre v2 Intel)
+    - [Packaging] retpoline files must be sorted
+    - [Packaging] pull in retpoline files
+
+  * [Feature] PXE boot with Intel Omni-Path (LP: #1712031)
+    - d-i: Add hfi1 to nic-modules
+
+  * CVE-2017-5715 (Spectre v2 retpoline)
+    - [Packaging] retpoline -- add call site validation
+    - [Config] disable retpoline checks for first upload
+
+  * Do not duplicate changelog entries assigned to more than one bug or CVE
+    (LP: #1743383)
+    - [Packaging] git-ubuntu-log -- handle multiple bugs/cves better
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 13 Feb 2018 11:33:58 -0600
+
+linux (4.15.0-9.10) bionic; urgency=medium
+
+  * linux: 4.15.0-9.10 -proposed tracker (LP: #1748244)
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] tests -- remove gcc-multilib dependency for arm64
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 08 Feb 2018 11:25:04 -0600
+
+linux (4.15.0-8.9) bionic; urgency=medium
+
+  * linux: 4.15.0-8.9 -proposed tracker (LP: #1748075)
+
+  * Bionic update to v4.15.2 stable release (LP: #1748072)
+    - KVM: x86: Make indirect calls in emulator speculation safe
+    - KVM: VMX: Make indirect call speculation safe
+    - module/retpoline: Warn about missing retpoline in module
+    - x86/cpufeatures: Add CPUID_7_EDX CPUID leaf
+    - x86/cpufeatures: Add Intel feature bits for Speculation Control
+    - x86/cpufeatures: Add AMD feature bits for Speculation Control
+    - x86/msr: Add definitions for new speculation control MSRs
+    - x86/pti: Do not enable PTI on CPUs which are not vulnerable to Meltdown
+    - x86/cpufeature: Blacklist SPEC_CTRL/PRED_CMD on early Spectre v2 microcodes
+    - x86/speculation: Add basic IBPB (Indirect Branch Prediction Barrier) support
+    - x86/alternative: Print unadorned pointers
+    - x86/nospec: Fix header guards names
+    - x86/bugs: Drop one "mitigation" from dmesg
+    - x86/cpu/bugs: Make retpoline module warning conditional
+    - x86/cpufeatures: Clean up Spectre v2 related CPUID flags
+    - x86/retpoline: Simplify vmexit_fill_RSB()
+    - x86/speculation: Simplify indirect_branch_prediction_barrier()
+    - auxdisplay: img-ascii-lcd: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - iio: adc/accel: Fix up module licenses
+    - pinctrl: pxa: pxa2xx: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - ASoC: pcm512x: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - KVM: nVMX: Eliminate vmcs02 pool
+    - KVM: VMX: introduce alloc_loaded_vmcs
+    - objtool: Improve retpoline alternative handling
+    - objtool: Add support for alternatives at the end of a section
+    - objtool: Warn on stripped section symbol
+    - x86/mm: Fix overlap of i386 CPU_ENTRY_AREA with FIX_BTMAP
+    - x86/spectre: Check CONFIG_RETPOLINE in command line parser
+    - x86/entry/64: Remove the SYSCALL64 fast path
+    - x86/entry/64: Push extra regs right away
+    - x86/asm: Move 'status' from thread_struct to thread_info
+    - Documentation: Document array_index_nospec
+    - array_index_nospec: Sanitize speculative array de-references
+    - x86: Implement array_index_mask_nospec
+    - x86: Introduce barrier_nospec
+    - x86: Introduce __uaccess_begin_nospec() and uaccess_try_nospec
+    - x86/usercopy: Replace open coded stac/clac with __uaccess_{begin, end}
+    - x86/uaccess: Use __uaccess_begin_nospec() and uaccess_try_nospec
+    - x86/get_user: Use pointer masking to limit speculation
+    - x86/syscall: Sanitize syscall table de-references under speculation
+    - vfs, fdtable: Prevent bounds-check bypass via speculative execution
+    - nl80211: Sanitize array index in parse_txq_params
+    - x86/spectre: Report get_user mitigation for spectre_v1
+    - x86/spectre: Fix spelling mistake: "vunerable"-> "vulnerable"
+    - x86/cpuid: Fix up "virtual" IBRS/IBPB/STIBP feature bits on Intel
+    - x86/speculation: Use Indirect Branch Prediction Barrier in context switch
+    - x86/paravirt: Remove 'noreplace-paravirt' cmdline option
+    - KVM: VMX: make MSR bitmaps per-VCPU
+    - x86/kvm: Update spectre-v1 mitigation
+    - x86/retpoline: Avoid retpolines for built-in __init functions
+    - x86/spectre: Simplify spectre_v2 command line parsing
+    - x86/pti: Mark constant arrays as __initconst
+    - x86/speculation: Fix typo IBRS_ATT, which should be IBRS_ALL
+    - KVM/x86: Update the reverse_cpuid list to include CPUID_7_EDX
+    - KVM/x86: Add IBPB support
+    - KVM/VMX: Emulate MSR_IA32_ARCH_CAPABILITIES
+    - KVM/VMX: Allow direct access to MSR_IA32_SPEC_CTRL
+    - KVM/SVM: Allow direct access to MSR_IA32_SPEC_CTRL
+    - serial: core: mark port as initialized after successful IRQ change
+    - fpga: region: release of_parse_phandle nodes after use
+    - Linux 4.15.2
+
+  * Add support for the NIC on SynQuacer E-Series boards (LP: #1747792)
+    - net: phy: core: remove now uneeded disabling of interrupts
+    - [Config] CONFIG_NET_VENDOR_SOCIONEXT=y & CONFIG_SNI_NETSEC=m
+    - net: socionext: Add Synquacer NetSec driver
+    - net: socionext: include linux/io.h to fix build
+    - net: socionext: Fix error return code in netsec_netdev_open()
+
+  * [Artful/Bionic] [Config] enable EDAC_GHES for ARM64 (LP: #1747746)
+    - [Config] CONFIG_EDAC_GHES=y
+
+  * support thunderx2 vendor pmu events (LP: #1747523)
+    - perf pmu: Pass pmu as a parameter to get_cpuid_str()
+    - perf tools arm64: Add support for get_cpuid_str function.
+    - perf pmu: Add helper function is_pmu_core to detect PMU CORE devices
+    - perf vendor events arm64: Add ThunderX2 implementation defined pmu core
+      events
+    - perf pmu: Add check for valid cpuid in perf_pmu__find_map()
+
+  * linux 4.14.0-7.9 ADT test failure with linux 4.14.0-7.9 (LP: #1732463)
+    - SAUCE: mm: disable vma based swap readahead by default
+    - SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Fix CONFIG_PROFILE_ALL_BRANCHES annotations
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 07 Feb 2018 21:13:27 -0600
+
+linux (4.15.0-7.8) bionic; urgency=medium
+
+  * Bionic update to v4.15.1 stable release (LP: #1747169)
+    - Bluetooth: hci_serdev: Init hci_uart proto_lock to avoid oops
+    - tools/gpio: Fix build error with musl libc
+    - gpio: stmpe: i2c transfer are forbiden in atomic context
+    - gpio: Fix kernel stack leak to userspace
+    - ALSA: hda - Reduce the suspend time consumption for ALC256
+    - crypto: ecdh - fix typo in KPP dependency of CRYPTO_ECDH
+    - crypto: aesni - handle zero length dst buffer
+    - crypto: aesni - fix typo in generic_gcmaes_decrypt
+    - crypto: aesni - add wrapper for generic gcm(aes)
+    - crypto: aesni - Fix out-of-bounds access of the data buffer in generic-gcm-
+      aesni
+    - crypto: aesni - Fix out-of-bounds access of the AAD buffer in generic-gcm-
+      aesni
+    - crypto: inside-secure - fix hash when length is a multiple of a block
+    - crypto: inside-secure - avoid unmapping DMA memory that was not mapped
+    - crypto: sha3-generic - fixes for alignment and big endian operation
+    - crypto: af_alg - whitelist mask and type
+    - HID: wacom: EKR: ensure devres groups at higher indexes are released
+    - HID: wacom: Fix reporting of touch toggle (WACOM_HID_WD_MUTE_DEVICE) events
+    - power: reset: zx-reboot: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - gpio: iop: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - gpio: ath79: add missing MODULE_DESCRIPTION/LICENSE
+    - mtd: nand: denali_pci: add missing MODULE_DESCRIPTION/AUTHOR/LICENSE
+    - igb: Free IRQs when device is hotplugged
+    - ima/policy: fix parsing of fsuuid
+    - scsi: aacraid: Fix udev inquiry race condition
+    - scsi: aacraid: Fix hang in kdump
+    - scsi: storvsc: missing error code in storvsc_probe()
+    - staging: lustre: separate a connection destroy from free struct kib_conn
+    - staging: ccree: NULLify backup_info when unused
+    - staging: ccree: fix fips event irq handling build
+    - tty: fix data race between tty_init_dev and flush of buf
+    - usb: option: Add support for FS040U modem
+    - USB: serial: pl2303: new device id for Chilitag
+    - USB: cdc-acm: Do not log urb submission errors on disconnect
+    - CDC-ACM: apply quirk for card reader
+    - USB: serial: io_edgeport: fix possible sleep-in-atomic
+    - usbip: prevent bind loops on devices attached to vhci_hcd
+    - usbip: list: don't list devices attached to vhci_hcd
+    - USB: serial: simple: add Motorola Tetra driver
+    - usb: f_fs: Prevent gadget unbind if it is already unbound
+    - usb: uas: unconditionally bring back host after reset
+    - usb/gadget: Fix "high bandwidth" check in usb_gadget_ep_match_desc()
+    - ANDROID: binder: remove waitqueue when thread exits.
+    - android: binder: use VM_ALLOC to get vm area
+    - mei: me: allow runtime pm for platform with D0i3
+    - serial: 8250_of: fix return code when probe function fails to get reset
+    - serial: 8250_uniphier: fix error return code in uniphier_uart_probe()
+    - serial: 8250_dw: Revert "Improve clock rate setting"
+    - serial: imx: Only wakeup via RTSDEN bit if the system has RTS/CTS
+    - spi: imx: do not access registers while clocks disabled
+    - iio: adc: stm32: fix scan of multiple channels with DMA
+    - iio: chemical: ccs811: Fix output of IIO_CONCENTRATION channels
+    - test_firmware: fix missing unlock on error in config_num_requests_store()
+    - Input: synaptics-rmi4 - unmask F03 interrupts when port is opened
+    - Input: synaptics-rmi4 - do not delete interrupt memory too early
+    - x86/efi: Clarify that reset attack mitigation needs appropriate userspace
+    - Linux 4.15.1
+
+  * Dell XPS 13 9360 bluetooth (Atheros) won't connect after resume
+    (LP: #1744712)
+    - Revert "Bluetooth: btusb: fix QCA Rome suspend/resume"
+    - Bluetooth: btusb: Restore QCA Rome suspend/resume fix with a "rewritten"
+      version
+
+  * apparmor profile load in stacked policy container fails (LP: #1746463)
+    - SAUCE: apparmor: fix display of .ns_name for containers
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 04 Feb 2018 11:56:32 +0100
+
+linux (4.15.0-6.7) bionic; urgency=low
+
+  * upload urgency should be medium by default (LP: #1745338)
+    - [Packaging] update urgency to medium by default
+
+  * Shutdown hang on 16.04 with iscsi targets (LP: #1569925)
+    - scsi: libiscsi: Allow sd_shutdown on bad transport
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.5-1ubuntu1, zfs to 0.7.5-1ubuntu1
+    - Revert "UBUNTU: SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM"
+    - Revert "UBUNTU: SAUCE: mm: disable vma based swap readahead by default"
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 29 Jan 2018 08:47:07 -0600
+
+linux (4.15.0-5.6) bionic; urgency=low
+
+  * $(LOCAL_ENV_CC) and $(LOCAL_ENV_DISTCC_HOSTS) should be properly quoted
+    (LP: #1744077)
+    - [Debian] pass LOCAL_ENV_CC and LOCAL_ENV_DISTCC_HOSTS properly
+
+  * Missing install-time driver for QLogic QED 25/40/100Gb Ethernet NIC
+    (LP: #1743638)
+    - [d-i] Add qede to nic-modules udeb
+
+  * boot failure on AMD Raven + WesternXT (LP: #1742759)
+    - SAUCE: drm/amdgpu: add atpx quirk handling (v2)
+
+  * Unable to handle kernel NULL pointer dereference at isci_task_abort_task
+    (LP: #1726519)
+    - SAUCE: Revert "scsi: libsas: allow async aborts"
+
+  * Update Ubuntu-4.15.0 config to support Intel Atom devices (LP: #1739939)
+    - [Config] CONFIG_SERIAL_DEV_BUS=y, CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
+
+  * Miscellaneous Ubuntu changes
+    - Rebase to v4.15-rc7
+    - [Config] CONFIG_CPU_ISOLATION=y
+    - [Config] Update annotations following config review
+    - Revert "UBUNTU: SAUCE: Import aufs driver"
+    - SAUCE: Import aufs driver
+    - ubuntu: vbox -- update to 5.2.6-dfsg-1
+    - ubuntu: vbox: build fixes for 4.15
+    - ubuntu: vbox -- update to 5.2.6-dfsg-2
+    - hio: updates for timer api changes in 4.15
+    - enable hio build
+    - Rebase to v4.15-rc9
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc9
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 22 Jan 2018 10:16:05 -0600
+
+linux (4.15.0-4.5) bionic; urgency=low
+
+  * [0cf3:e010] QCA6174A XR failed to pair with bt 4.0 device  (LP: #1741166)
+    - SAUCE: Bluetooth: btusb: Add support for 0cf3:e010
+
+  * External HDMI monitor failed to show screen on Lenovo X1 series
+    (LP: #1738523)
+    - SAUCE: drm/i915: Disable writing of TMDS_OE on Lenovo ThinkPad X1 series
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] autoreconstruct - add resoration of execute permissions
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 10 Jan 2018 10:24:22 -0600
+
+linux (4.15.0-3.4) bionic; urgency=low
+
+  * ubuntu/xr-usb-serial didn't get built in zesty and artful (LP: #1733281)
+    - SAUCE: make sure ubuntu/xr-usb-serial builds for x86
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 03 Jan 2018 20:20:43 -0600
+
+linux (4.15.0-2.3) bionic; urgency=low
+
+  * nvidia-graphics-drivers-384 384.90-0ubuntu6 ADT test failure with linux
+    4.15.0-1.2 (LP: #1737752)
+    - x86/mm: Unbreak modules that use the DMA API
+
+  * Ubuntu 17.10 corrupting BIOS - many LENOVO laptops models (LP: #1734147)
+    - [Config] CONFIG_SPI_INTEL_SPI_*=n
+
+  * power: commonise configs IBMVETH/IBMVSCSI and ensure both are in linux-image
+    and udebs (LP: #1521712)
+    - [Config] Include ibmvnic in nic-modules
+
+  * Enable arm64 emulation of removed ARMv7 instructions (LP: #1545542)
+    - [Config] Enable support for emulation of deprecated ARMv8 instructions
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl with 4.15 compat fix (LP:#1737761)
+    - Enable zfs build
+    - [Debian] add icp to zfs-modules.ignore
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 18 Dec 2017 09:27:13 -0600
+
+linux (4.15.0-1.2) bionic; urgency=low
+
+  * Disabling zfs does not always disable module checks for the zfs modules
+    (LP: #1737176)
+    - [Packaging] disable zfs module checks when zfs is disabled
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_UNWINDER_FRAME_POINTER=y for amd64
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 10 Dec 2017 22:07:19 -0600
+
+linux (4.15.0-0.1) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu: vbox -- update to 5.2.2-dfsg-2
+    - ubuntu: vbox: build fixes for 4.15
+    - disable hio build
+    - [Config] Update kernel lockdown options to fix build errors
+    - Disable zfs build
+    - SAUCE: Import aufs driver
+    - [Config] Enable AUFS config options
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.15-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 08 Dec 2017 13:55:42 -0600
+
+linux (4.14.0-11.13) bionic; urgency=low
+
+  * linux: 4.14.0-11.13 -proposed tracker (LP: #1736168)
+
+  * CVE-2017-1000405
+    - mm, thp: Do not make page table dirty unconditionally in touch_p[mu]d()
+
+  * linux 4.14.0-7.9 ADT test failure with linux 4.14.0-7.9 (LP: #1732463)
+    - SAUCE: mm: disable vma based swap readahead by default
+    - SAUCE: mm: fix memory hotplug in ZONE_HIGHMEM
+
+  * Bionic update to v4.14.3 stable release (LP: #1735843)
+    - s390: fix transactional execution control register handling
+    - s390/noexec: execute kexec datamover without DAT
+    - s390/runtime instrumention: fix possible memory corruption
+    - s390/guarded storage: fix possible memory corruption
+    - s390/disassembler: add missing end marker for e7 table
+    - s390/disassembler: increase show_code buffer size
+    - ACPI / PM: Fix acpi_pm_notifier_lock vs flush_workqueue() deadlock
+    - ACPI / EC: Fix regression related to triggering source of EC event handling
+    - cpufreq: schedutil: Reset cached_raw_freq when not in sync with next_freq
+    - serdev: fix registration of second slave
+    - sched: Make resched_cpu() unconditional
+    - lib/mpi: call cond_resched() from mpi_powm() loop
+    - x86/boot: Fix boot failure when SMP MP-table is based at 0
+    - x86/decoder: Add new TEST instruction pattern
+    - x86/entry/64: Fix entry_SYSCALL_64_after_hwframe() IRQ tracing
+    - x86/entry/64: Add missing irqflags tracing to native_load_gs_index()
+    - perf/x86/intel: Hide TSX events when RTM is not supported
+    - arm64: Implement arch-specific pte_access_permitted()
+    - ARM: 8722/1: mm: make STRICT_KERNEL_RWX effective for LPAE
+    - ARM: 8721/1: mm: dump: check hardware RO bit for LPAE
+    - uapi: fix linux/tls.h userspace compilation error
+    - uapi: fix linux/rxrpc.h userspace compilation errors
+    - MIPS: cmpxchg64() and HAVE_VIRT_CPU_ACCOUNTING_GEN don't work for 32-bit SMP
+    - MIPS: ralink: Fix MT7628 pinmux
+    - MIPS: ralink: Fix typo in mt7628 pinmux function
+    - net: mvneta: fix handling of the Tx descriptor counter
+    - nbd: wait uninterruptible for the dead timeout
+    - nbd: don't start req until after the dead connection logic
+    - PM / OPP: Add missing of_node_put(np)
+    - PCI/ASPM: Account for downstream device's Port Common_Mode_Restore_Time
+    - PCI/ASPM: Use correct capability pointer to program LTR_L1.2_THRESHOLD
+    - PCI: hv: Use effective affinity mask
+    - PCI: Set Cavium ACS capability quirk flags to assert RR/CR/SV/UF
+    - PCI: Apply Cavium ThunderX ACS quirk to more Root Ports
+    - ALSA: hda: Add Raven PCI ID
+    - dm integrity: allow unaligned bv_offset
+    - dm cache: fix race condition in the writeback mode overwrite_bio
+      optimisation
+    - dm crypt: allow unaligned bv_offset
+    - dm zoned: ignore last smaller runt zone
+    - dm mpath: remove annoying message of 'blk_get_request() returned -11'
+    - dm bufio: fix integer overflow when limiting maximum cache size
+    - ovl: Put upperdentry if ovl_check_origin() fails
+    - dm: allocate struct mapped_device with kvzalloc
+    - sched/rt: Simplify the IPI based RT balancing logic
+    - MIPS: pci: Remove KERN_WARN instance inside the mt7620 driver
+    - dm: fix race between dm_get_from_kobject() and __dm_destroy()
+    - dm: discard support requires all targets in a table support discards
+    - MIPS: Fix odd fp register warnings with MIPS64r2
+    - MIPS: Fix MIPS64 FP save/restore on 32-bit kernels
+    - MIPS: dts: remove bogus bcm96358nb4ser.dtb from dtb-y entry
+    - MIPS: Fix an n32 core file generation regset support regression
+    - MIPS: BCM47XX: Fix LED inversion for WRT54GSv1
+    - MIPS: math-emu: Fix final emulation phase for certain instructions
+    - rt2x00usb: mark device removed when get ENOENT usb error
+    - mm/z3fold.c: use kref to prevent page free/compact race
+    - autofs: don't fail mount for transient error
+    - nilfs2: fix race condition that causes file system corruption
+    - fscrypt: lock mutex before checking for bounce page pool
+    - eCryptfs: use after free in ecryptfs_release_messaging()
+    - libceph: don't WARN() if user tries to add invalid key
+    - bcache: check ca->alloc_thread initialized before wake up it
+    - fs: guard_bio_eod() needs to consider partitions
+    - fanotify: fix fsnotify_prepare_user_wait() failure
+    - isofs: fix timestamps beyond 2027
+    - btrfs: change how we decide to commit transactions during flushing
+    - f2fs: expose some sectors to user in inline data or dentry case
+    - NFS: Fix typo in nomigration mount option
+    - NFS: Revert "NFS: Move the flock open mode check into nfs_flock()"
+    - nfs: Fix ugly referral attributes
+    - NFS: Avoid RCU usage in tracepoints
+    - NFS: revalidate "." etc correctly on "open".
+    - nfsd: deal with revoked delegations appropriately
+    - rtlwifi: rtl8192ee: Fix memory leak when loading firmware
+    - rtlwifi: fix uninitialized rtlhal->last_suspend_sec time
+    - iwlwifi: fix firmware names for 9000 and A000 series hw
+    - md: fix deadlock error in recent patch.
+    - md: don't check MD_SB_CHANGE_CLEAN in md_allow_write
+    - Bluetooth: btqcomsmd: Add support for BD address setup
+    - md/bitmap: revert a patch
+    - fsnotify: clean up fsnotify_prepare/finish_user_wait()
+    - fsnotify: pin both inode and vfsmount mark
+    - fsnotify: fix pinning group in fsnotify_prepare_user_wait()
+    - ata: fixes kernel crash while tracing ata_eh_link_autopsy event
+    - ext4: fix interaction between i_size, fallocate, and delalloc after a crash
+    - ext4: prevent data corruption with inline data + DAX
+    - ext4: prevent data corruption with journaling + DAX
+    - ALSA: pcm: update tstamp only if audio_tstamp changed
+    - ALSA: usb-audio: Add sanity checks to FE parser
+    - ALSA: usb-audio: Fix potential out-of-bound access at parsing SU
+    - ALSA: usb-audio: Add sanity checks in v2 clock parsers
+    - ALSA: timer: Remove kernel warning at compat ioctl error paths
+    - ALSA: hda/realtek - Fix ALC275 no sound issue
+    - ALSA: hda: Fix too short HDMI/DP chmap reporting
+    - ALSA: hda - Fix yet remaining issue with vmaster 0dB initialization
+    - ALSA: hda/realtek - Fix ALC700 family no sound issue
+    - ASoC: sun8i-codec: Invert Master / Slave condition
+    - ASoC: sun8i-codec: Fix left and right channels inversion
+    - ASoC: sun8i-codec: Set the BCLK divider
+    - mfd: lpc_ich: Avoton/Rangeley uses SPI_BYT method
+    - fix a page leak in vhost_scsi_iov_to_sgl() error recovery
+    - 9p: Fix missing commas in mount options
+    - fs/9p: Compare qid.path in v9fs_test_inode
+    - net/9p: Switch to wait_event_killable()
+    - scsi: qla2xxx: Suppress a kernel complaint in qla_init_base_qpair()
+    - scsi: sd_zbc: Fix sd_zbc_read_zoned_characteristics()
+    - scsi: lpfc: fix pci hot plug crash in timer management routines
+    - scsi: lpfc: fix pci hot plug crash in list_add call
+    - scsi: lpfc: Fix crash receiving ELS while detaching driver
+    - scsi: lpfc: Fix FCP hba_wqidx assignment
+    - scsi: lpfc: Fix oops if nvmet_fc_register_targetport fails
+    - iscsi-target: Make TASK_REASSIGN use proper se_cmd->cmd_kref
+    - iscsi-target: Fix non-immediate TMR reference leak
+    - target: fix null pointer regression in core_tmr_drain_tmr_list
+    - target: fix buffer offset in core_scsi3_pri_read_full_status
+    - target: Fix QUEUE_FULL + SCSI task attribute handling
+    - target: Fix caw_sem leak in transport_generic_request_failure
+    - target: Fix quiese during transport_write_pending_qf endless loop
+    - target: Avoid early CMD_T_PRE_EXECUTE failures during ABORT_TASK
+    - mtd: Avoid probe failures when mtd->dbg.dfs_dir is invalid
+    - mtd: nand: Export nand_reset() symbol
+    - mtd: nand: atmel: Actually use the PM ops
+    - mtd: nand: omap2: Fix subpage write
+    - mtd: nand: Fix writing mtdoops to nand flash.
+    - mtd: nand: mtk: fix infinite ECC decode IRQ issue
+    - mailbox: bcm-flexrm-mailbox: Fix FlexRM ring flush sequence
+    - p54: don't unregister leds when they are not initialized
+    - block: Fix a race between blk_cleanup_queue() and timeout handling
+    - raid1: prevent freeze_array/wait_all_barriers deadlock
+    - genirq: Track whether the trigger type has been set
+    - irqchip/gic-v3: Fix ppi-partitions lookup
+    - lockd: double unregister of inetaddr notifiers
+    - KVM: PPC: Book3S HV: Don't call real-mode XICS hypercall handlers if not
+      enabled
+    - KVM: nVMX: set IDTR and GDTR limits when loading L1 host state
+    - KVM: SVM: obey guest PAT
+    - kvm: vmx: Reinstate support for CPUs without virtual NMI
+    - dax: fix PMD faults on zero-length files
+    - dax: fix general protection fault in dax_alloc_inode
+    - SUNRPC: Fix tracepoint storage issues with svc_recv and svc_rqst_status
+    - clk: ti: dra7-atl-clock: fix child-node lookups
+    - libnvdimm, dimm: clear 'locked' status on successful DIMM enable
+    - libnvdimm, pfn: make 'resource' attribute only readable by root
+    - libnvdimm, namespace: fix label initialization to use valid seq numbers
+    - libnvdimm, region : make 'resource' attribute only readable by root
+    - libnvdimm, namespace: make 'resource' attribute only readable by root
+    - svcrdma: Preserve CB send buffer across retransmits
+    - IB/srpt: Do not accept invalid initiator port names
+    - IB/cm: Fix memory corruption in handling CM request
+    - IB/hfi1: Fix incorrect available receive user context count
+    - IB/srp: Avoid that a cable pull can trigger a kernel crash
+    - IB/core: Avoid crash on pkey enforcement failed in received MADs
+    - IB/core: Only maintain real QPs in the security lists
+    - NFC: fix device-allocation error return
+    - spi-nor: intel-spi: Fix broken software sequencing codes
+    - i40e: Use smp_rmb rather than read_barrier_depends
+    - igb: Use smp_rmb rather than read_barrier_depends
+    - igbvf: Use smp_rmb rather than read_barrier_depends
+    - ixgbevf: Use smp_rmb rather than read_barrier_depends
+    - i40evf: Use smp_rmb rather than read_barrier_depends
+    - fm10k: Use smp_rmb rather than read_barrier_depends
+    - ixgbe: Fix skb list corruption on Power systems
+    - parisc: Fix validity check of pointer size argument in new CAS
+      implementation
+    - powerpc: Fix boot on BOOK3S_32 with CONFIG_STRICT_KERNEL_RWX
+    - powerpc/mm/radix: Fix crashes on Power9 DD1 with radix MMU and STRICT_RWX
+    - powerpc/perf/imc: Use cpu_to_node() not topology_physical_package_id()
+    - powerpc/signal: Properly handle return value from uprobe_deny_signal()
+    - powerpc/64s: Fix masking of SRR1 bits on instruction fault
+    - powerpc/64s/radix: Fix 128TB-512TB virtual address boundary case allocation
+    - powerpc/64s/hash: Fix 512T hint detection to use >= 128T
+    - powerpc/64s/hash: Fix 128TB-512TB virtual address boundary case allocation
+    - powerpc/64s/hash: Fix fork() with 512TB process address space
+    - powerpc/64s/hash: Allow MAP_FIXED allocations to cross 128TB boundary
+    - media: Don't do DMA on stack for firmware upload in the AS102 driver
+    - media: rc: check for integer overflow
+    - media: rc: nec decoder should not send both repeat and keycode
+    - cx231xx-cards: fix NULL-deref on missing association descriptor
+    - media: v4l2-ctrl: Fix flags field on Control events
+    - media: venus: fix wrong size on dma_free
+    - media: venus: venc: fix bytesused v4l2_plane field
+    - media: venus: reimplement decoder stop command
+    - ARM64: dts: meson-gxl: Add alternate ARM Trusted Firmware reserved memory
+      zone
+    - iwlwifi: fix wrong struct for a000 device
+    - iwlwifi: add a new a000 device
+    - iwlwifi: pcie: sort IDs for the 9000 series for easier comparisons
+    - iwlwifi: add new cards for a000 series
+    - iwlwifi: add new cards for 8265 series
+    - iwlwifi: add new cards for 8260 series
+    - iwlwifi: fix PCI IDs and configuration mapping for 9000 series
+    - iwlwifi: mvm: support version 7 of the SCAN_REQ_UMAC FW command
+    - e1000e: Fix error path in link detection
+    - e1000e: Fix return value test
+    - e1000e: Separate signaling for link check/link up
+    - e1000e: Avoid receiver overrun interrupt bursts
+    - e1000e: fix buffer overrun while the I219 is processing DMA transactions
+    - Linux 4.14.3
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: s390/topology: don't inline cpu_to_node
+    - SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to 0.7.3-1ubuntu1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 04 Dec 2017 09:08:07 -0600
+
+linux (4.14.0-10.12) bionic; urgency=low
+
+  * linux: 4.14.0-10.12 -proposed tracker (LP: #1734901)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Enable the ACPI kernel debugger and acpidbg tool
+    - [Packaging] Include arch/arm64/kernel/ftrace-mod.o in headers package
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 28 Nov 2017 08:46:49 -0600
+
+linux (4.14.0-9.11) bionic; urgency=low
+
+  * linux: 4.14.0-9.11 -proposed tracker (LP: #1734728)
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to
+      0.7.3-1ubuntu1"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Nov 2017 12:44:48 -0600
+
+linux (4.14.0-8.10) bionic; urgency=low
+
+  * linux: 4.14.0-8.10 -proposed tracker (LP: #1734695)
+
+  * Bionic update to v4.14.2 stable release (LP: #1734694)
+    - bio: ensure __bio_clone_fast copies bi_partno
+    - af_netlink: ensure that NLMSG_DONE never fails in dumps
+    - vxlan: fix the issue that neigh proxy blocks all icmpv6 packets
+    - net: cdc_ncm: GetNtbFormat endian fix
+    - fealnx: Fix building error on MIPS
+    - net/sctp: Always set scope_id in sctp_inet6_skb_msgname
+    - ima: do not update security.ima if appraisal status is not INTEGRITY_PASS
+    - serial: omap: Fix EFR write on RTS deassertion
+    - serial: 8250_fintek: Fix finding base_port with activated SuperIO
+    - tpm-dev-common: Reject too short writes
+    - rcu: Fix up pending cbs check in rcu_prepare_for_idle
+    - mm/pagewalk.c: report holes in hugetlb ranges
+    - ocfs2: fix cluster hang after a node dies
+    - ocfs2: should wait dio before inode lock in ocfs2_setattr()
+    - ipmi: fix unsigned long underflow
+    - mm/page_alloc.c: broken deferred calculation
+    - mm/page_ext.c: check if page_ext is not prepared
+    - coda: fix 'kernel memory exposure attempt' in fsync
+    - ipmi: Prefer ACPI system interfaces over SMBIOS ones
+    - Linux 4.14.2
+
+  * Bionic update to v4.14.1 stable release (LP: #1734693)
+    - EDAC, sb_edac: Don't create a second memory controller if HA1 is not present
+    - dmaengine: dmatest: warn user when dma test times out
+    - media: imon: Fix null-ptr-deref in imon_probe
+    - media: dib0700: fix invalid dvb_detach argument
+    - crypto: dh - Fix double free of ctx->p
+    - crypto: dh - Don't permit 'p' to be 0
+    - crypto: dh - Don't permit 'key' or 'g' size longer than 'p'
+    - crypto: brcm - Explicity ACK mailbox message
+    - USB: early: Use new USB product ID and strings for DbC device
+    - USB: usbfs: compute urb->actual_length for isochronous
+    - USB: Add delay-init quirk for Corsair K70 LUX keyboards
+    - usb: gadget: f_fs: Fix use-after-free in ffs_free_inst
+    - USB: serial: metro-usb: stop I/O after failed open
+    - USB: serial: Change DbC debug device binding ID
+    - USB: serial: qcserial: add pid/vid for Sierra Wireless EM7355 fw update
+    - USB: serial: garmin_gps: fix I/O after failed probe and remove
+    - USB: serial: garmin_gps: fix memory leak on probe errors
+    - selftests/x86/protection_keys: Fix syscall NR redefinition warnings
+    - x86/MCE/AMD: Always give panic severity for UC errors in kernel context
+    - platform/x86: peaq-wmi: Add DMI check before binding to the WMI interface
+    - platform/x86: peaq_wmi: Fix missing terminating entry for peaq_dmi_table
+    - HID: cp2112: add HIDRAW dependency
+    - HID: wacom: generic: Recognize WACOM_HID_WD_PEN as a type of pen collection
+    - rpmsg: glink: Add missing MODULE_LICENSE
+    - staging: wilc1000: Fix bssid buffer offset in Txq
+    - staging: sm750fb: Fix parameter mistake in poke32
+    - staging: ccree: fix 64 bit scatter/gather DMA ops
+    - staging: greybus: spilib: fix use-after-free after deregistration
+    - staging: rtl8188eu: Revert 4 commits breaking ARP
+    - spi: fix use-after-free at controller deregistration
+    - sparc32: Add cmpxchg64().
+    - sparc64: mmu_context: Add missing include files
+    - sparc64: Fix page table walk for PUD hugepages
+    - Linux 4.14.1
+
+  * Set PANIC_TIMEOUT=10 on Power Systems (LP: #1730660)
+    - [Config]: Set PANIC_TIMEOUT=10 on ppc64el
+
+  * enable CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH easily confuse users
+    (LP: #1732627)
+    - [Config] CONFIG_SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH=n
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.7.3-1ubuntu1, zfs to 0.7.3-1ubuntu1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 27 Nov 2017 07:43:44 -0600
+
+linux (4.14.0-7.9) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor: add base infastructure for socket mediation
+    - SAUCE: apparmor: af_unix mediation
+    - SAUCE: LSM stacking: procfs: add smack subdir to attrs
+    - SAUCE: LSM stacking: LSM: manage credential security blobs
+    - SAUCE: LSM stacking: LSM: Manage file security blobs
+    - SAUCE: LSM stacking: LSM: manage task security blobs
+    - SAUCE: LSM stacking: LSM: Infrastructure management of the remaining blobs
+    - SAUCE: LSM stacking: LSM: general but not extreme module stacking
+    - SAUCE: LSM stacking: LSM: Complete task_alloc hook
+    - SAUCE: LSM stacking: fixup procsfs: add smack subdir to attrs
+    - SAUCE: LSM stacking: fixup initialize task->security
+    - SAUCE: LSM stacking: fixup: alloc_task_ctx is dead code
+    - SAUCE: LSM stacking: add support for stacking getpeersec_stream
+    - SAUCE: LSM stacking: add stacking support to apparmor network hooks
+    - SAUCE: LSM stacking: fixup apparmor stacking enablement
+    - SAUCE: LSM stacking: fixup stacking kconfig
+    - SAUCE: LSM stacking: allow selecting multiple LSMs using kernel boot params
+    - SAUCE: LSM stacking: provide prctl interface for setting context
+    - SAUCE: LSM stacking: inherit current display LSM
+    - SAUCE: LSM stacking: keep an index for each registered LSM
+    - SAUCE: LSM stacking: verify display LSM
+    - SAUCE: LSM stacking: provide a way to specify the default display lsm
+    - SAUCE: LSM stacking: make sure LSM blob align on 64 bit boundaries
+    - SAUCE: LSM stacking: add /proc/<pid>/attr/display_lsm
+    - SAUCE: LSM stacking: add Kconfig to set default display LSM
+    - SAUCE: LSM stacking: add configs for LSM stacking
+    - SAUCE: LSM stacking: check for invalid zero sized writes
+    - [Config] Run updateconfigs after merging LSM stacking
+    - [Config] CONFIG_AMD_MEM_ENCRYPT=y
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 13 Nov 2017 08:12:08 -0600
+
+linux (4.14.0-6.8) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: add workarounds to enable ZFS for 4.14
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 06 Nov 2017 11:39:00 -0600
+
+linux (4.14.0-5.7) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Fix invocation of dh_prep for dbgsym packages
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 31 Oct 2017 07:07:23 -0500
+
+linux (4.14.0-4.5) bionic; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - [Packaging] virtualbox -- reduce in kernel module versions
+    - vbox-update: Fix up KERN_DIR definitions
+    - ubuntu: vbox -- update to 5.2.0-dfsg-2
+    - [Config] CONFIG_AMD_MEM_ENCRYPT=n
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 30 Oct 2017 13:29:20 -0500
+
+linux (4.14.0-3.4) artful; urgency=low
+
+  * Touchpad and TrackPoint Dose Not Work on Lenovo X1C6 and X280 (LP: #1723986)
+    - SAUCE: Input: synaptics-rmi4 - RMI4 can also use SMBUS version 3
+    - SAUCE: Input: synaptics - Lenovo X1 Carbon 5 should use SMBUS/RMI
+    - SAUCE: Input: synaptics - add Intertouch support on X1 Carbon 6th and X280
+
+  * powerpc/64s: Add workaround for P9 vector CI load issuenext (LP: #1721070)
+    - powerpc/64s: Add workaround for P9 vector CI load issue
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: staging: vboxvideo: Fix reporting invalid suggested-offset-properties
+    - [Config] CONFIG_DRM_VBOXVIDEO=m
+    - SAUCE: Import aufs driver
+    - [Config] Enable aufs
+    - [Config] Reorder annotations file after enabling aufs
+    - vbox-update: Disable imported vboxvideo module
+    - ubuntu: vbox -- update to 5.1.30-dfsg-1
+    - Enable vbox
+    - hio: Use correct sizes when initializing ssd_index_bits* arrays
+    - hio: Update io stat accounting for 4.14
+    - Enable hio
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc5
+  * Rebase to v4.14-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 23 Oct 2017 13:53:52 -0500
+
+linux (4.14.0-2.3) artful; urgency=low
+
+  * [Bug] USB controller failed to respond on Denverton after loading
+    intel_th_pci module (LP: #1715833)
+    - SAUCE: PCI: Disable broken RTIT_BAR of Intel TH
+
+  * CONFIG_DEBUG_FS is not enabled by "make zfcpdump_defconfig" with Ubuntu
+    17.10 (kernel 4.13) (LP: #1719290)
+    - SAUCE: s390: update zfcpdump_defconfig
+
+  * Add installer support for Broadcom BCM573xx network drivers. (LP: #1720466)
+    - d-i: Add bnxt_en to nic-modules.
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Update annotations for 4.14-rc2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc3
+  * Rebase to v4.14-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 11 Oct 2017 16:04:27 -0500
+
+linux (4.14.0-1.2) artful; urgency=low
+
+  * [Bug] USB 3.1 Gen2 works as 5Gbps (LP: #1720045)
+    - xhci: set missing SuperSpeedPlus Link Protocol bit in roothub descriptor
+
+  * Please make linux-libc-dev Provide: aufs-dev (LP: #1716091)
+    - [Packaging] Add aufs-dev to the Provides: for linux-libc-dev
+
+  * Upgrade to 4.13.0-11.12 in artful amd64 VM breaks display on wayland
+    (LP: #1718679)
+    - [Config] CONFIG_DRM_VBOXVIDEO=n
+
+  * ipmmu-vmsa driver breaks arm64 boots (LP: #1718734)
+    - [Config] Disable CONFIG_IPMMU_VMSA on arm64
+
+  * autopkgtest profile fails to build on armhf (LP: #1717920)
+    - [Packaging] autopkgtest -- disable d-i when dropping flavours
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_I2C_XLP9XX=m
+    - [Packaging] Use SRCPKGNAME rather than hard-coding the source package name
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 29 Sep 2017 09:09:11 -0400
+
+linux (4.14.0-0.1) artful; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - Disable vbox build
+    - Disable hio build
+    - Disable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.14-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 19 Sep 2017 20:22:29 -0500
+
+linux (4.13.0-11.12) artful; urgency=low
+
+  * linux: 4.13.0-11.12 -proposed tracker (LP: #1716699)
+
+  * kernel panic -not syncing: Fatal exception: panic_on_oops (LP: #1708399)
+    - s390/mm: fix local TLB flushing vs. detach of an mm address space
+    - s390/mm: fix race on mm->context.flush_mm
+
+  * CVE-2017-1000251
+    - Bluetooth: Properly check L2CAP config option output buffer length
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 12 Sep 2017 10:18:38 -0500
+
+linux (4.13.0-10.11) artful; urgency=low
+
+  * linux: 4.13.0-10.11 -proposed tracker (LP: #1716287)
+
+  * please add aufs-dkms to the Provides: for the kernel packages (LP: #1716093)
+    - [Packaging] Add aufs-dkms to the Provides: for kernel packages
+
+  * Artful update to v4.13.1 stable release (LP: #1716284)
+    - usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard
+    - USB: serial: option: add support for D-Link DWM-157 C1
+    - usb: Add device quirk for Logitech HD Pro Webcam C920-C
+    - usb:xhci:Fix regression when ATI chipsets detected
+    - USB: musb: fix external abort on suspend
+    - ANDROID: binder: add padding to binder_fd_array_object.
+    - ANDROID: binder: add hwbinder,vndbinder to BINDER_DEVICES.
+    - USB: core: Avoid race of async_completed() w/ usbdev_release()
+    - staging/rts5208: fix incorrect shift to extract upper nybble
+    - staging: ccree: save ciphertext for CTS IV
+    - staging: fsl-dpaa2/eth: fix off-by-one FD ctrl bitmaks
+    - iio: adc: ti-ads1015: fix incorrect data rate setting update
+    - iio: adc: ti-ads1015: fix scale information for ADS1115
+    - iio: adc: ti-ads1015: enable conversion when CONFIG_PM is not set
+    - iio: adc: ti-ads1015: avoid getting stale result after runtime resume
+    - iio: adc: ti-ads1015: don't return invalid value from buffer setup callbacks
+    - iio: adc: ti-ads1015: add adequate wait time to get correct conversion
+    - driver core: bus: Fix a potential double free
+    - HID: wacom: Do not completely map WACOM_HID_WD_TOUCHRINGSTATUS usage
+    - binder: free memory on error
+    - crypto: caam/qi - fix compilation with CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
+    - crypto: caam/qi - fix compilation with DEBUG enabled
+    - thunderbolt: Fix reset response_type
+    - fpga: altera-hps2fpga: fix multiple init of l3_remap_lock
+    - intel_th: pci: Add Cannon Lake PCH-H support
+    - intel_th: pci: Add Cannon Lake PCH-LP support
+    - ath10k: fix memory leak in rx ring buffer allocation
+    - drm/vgem: Pin our pages for dmabuf exports
+    - drm/ttm: Fix accounting error when fail to get pages for pool
+    - drm/dp/mst: Handle errors from drm_atomic_get_private_obj_state() correctly
+    - rtlwifi: rtl_pci_probe: Fix fail path of _rtl_pci_find_adapter
+    - Bluetooth: Add support of 13d3:3494 RTL8723BE device
+    - iwlwifi: pci: add new PCI ID for 7265D
+    - dlm: avoid double-free on error path in dlm_device_{register,unregister}
+    - mwifiex: correct channel stat buffer overflows
+    - MCB: add support for SC31 to mcb-lpc
+    - s390/mm: avoid empty zero pages for KVM guests to avoid postcopy hangs
+    - drm/nouveau/pci/msi: disable MSI on big-endian platforms by default
+    - drm/nouveau: Fix error handling in nv50_disp_atomic_commit
+    - workqueue: Fix flag collision
+    - ahci: don't use MSI for devices with the silly Intel NVMe remapping scheme
+    - cs5536: add support for IDE controller variant
+    - scsi: sg: protect against races between mmap() and SG_SET_RESERVED_SIZE
+    - scsi: sg: recheck MMAP_IO request length with lock held
+    - of/device: Prevent buffer overflow in of_device_modalias()
+    - rtlwifi: Fix memory leak when firmware request fails
+    - rtlwifi: Fix fallback firmware loading
+    - Linux 4.13.1
+
+  * Kernel has trouble recognizing Corsair Strafe RGB keyboard (LP: #1678477)
+    - usb: quirks: add delay init quirk for Corsair Strafe RGB keyboard
+
+  * SRIOV: warning if unload VFs (LP: #1715073)
+    - PCI: Disable VF decoding before pcibios_sriov_disable() updates resources
+
+  * [Patch] network-i40e:NVM bug fixes (cherrypick from 4.14) (LP: #1715578)
+    - i40e: avoid NVM acquire deadlock during NVM update
+    - i40e: point wb_desc at the nvm_wb_desc during i40e_read_nvm_aq
+
+  * [P9,POwer NV] Perf PMU event : pm_br_2path and pm_ld_miss_l1 is counted
+    twice when perf stat is done (perf:) (LP: #1714571)
+    - perf vendor events powerpc: Remove duplicate events
+
+  * Unable to install Ubuntu on the NVMe disk under VMD PCI domain
+    (LP: #1703339)
+    - [Config] Include vmd in storage-core-modules udeb
+
+  * 17.10 fails to boot on POWER9 DD2.0 with Deep stop states (LP: #1715064)
+    - powerpc/powernv: Save/Restore additional SPRs for stop4 cpuidle
+    - powerpc/powernv: Clear PECE1 in LPCR via stop-api only on Hotplug
+    - SAUCE: powerpc/powernv: Clear LPCR[PECE1] via stop-api only for deep state
+      offline
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: selftests/seccomp: Support glibc 2.26 siginfo_t.h
+    - Revert "UBUNTU: SAUCE: Import aufs driver"
+    - SAUCE: Import aufs driver
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 10 Sep 2017 17:48:59 -0500
+
+linux (4.13.0-9.10) artful; urgency=low
+
+  * linux: 4.13.0-9.10 -proposed tracker (LP: #1715145)
+
+  * EDAC sbridge: Failed to register device with error -22. (LP: #1714112)
+    - [Config] CONFIG_EDAC_GHES=n
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu: vbox -- update to 5.1.26-dfsg-2
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 05 Sep 2017 07:51:19 -0500
+
+linux (4.13.0-8.9) artful; urgency=low
+
+  * snapd 2.27.3+17.10 ADT test failure with linux 4.13.0-6.7 (LP: #1713103)
+    - SAUCE: apparmor: fix apparmorfs DAC access, permissions
+
+  * enable ARCH_SUNXI (and friends) in arm64 kernel .config (LP: #1701137)
+    - [Config] Enable CONFIG_ARCH_SUNXI and related options for arm64
+
+  * [Bug] Harrisonville: pnd2_edac always fail to load on B1 stepping
+    Harrisonville SDP (LP: #1709257)
+    - EDAC, pnd2: Build in a minimal sideband driver for Apollo Lake
+    - EDAC, pnd2: Mask off the lower four bits of a BAR
+    - EDAC, pnd2: Conditionally unhide/hide the P2SB PCI device to read BAR
+    - EDAC, pnd2: Properly toggle hidden state for P2SB PCI device
+    - SAUCE: i2c: i801: Restore the presence state of P2SB PCI device after
+      reading BAR
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: Import aufs driver"
+    - SAUCE: Import aufs driver
+    - SAUCE: selftests/powerpc: Disable some ptrace selftests
+    - [Config] CONFIG_CRYPTO_DEV_NITROX_CNN55XX=n for s390x
+    - [Config] CONFIG_I2C_SLAVE=n for amd64, i386, ppc64el
+    - [Config] Disable CONFIG_MDIO_* options for s390x
+    - [Config] CONFIG_SCSI_MQ_DEFAULT=n for s390x
+    - [Config] Update annotations for 4.13
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 31 Aug 2017 14:27:09 -0500
+
+linux (4.13.0-7.8) artful; urgency=low
+
+  * linux 4.12.0-11.12 ADT test failure with linux 4.12.0-11.12 (LP: #1710904)
+    - SAUCE: selftests/powerpc: Use snprintf to construct DSCR sysfs interface
+      paths
+
+  * Miscellaneous Ubuntu changes
+    - Revert "UBUNTU: SAUCE: seccomp: log actions even when audit is disabled"
+
+  * Miscellaneous upstream changes
+    - seccomp: Provide matching filter for introspection
+    - seccomp: Sysctl to display available actions
+    - seccomp: Operation for checking if an action is available
+    - seccomp: Sysctl to configure actions that are allowed to be logged
+    - seccomp: Selftest for detection of filter flag support
+    - seccomp: Filter flag to log all actions except SECCOMP_RET_ALLOW
+    - seccomp: Action to log before allowing
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 28 Aug 2017 08:12:24 -0500
+
+linux (4.13.0-6.7) artful; urgency=low
+
+  * HID: multitouch: Support ALPS PTP Stick and Touchpad devices (LP: #1712481)
+    - SAUCE: HID: multitouch: Support ALPS PTP stick with pid 0x120A
+
+  * sort ABI files with C.UTF-8 locale (LP: #1712345)
+    - [Packaging] sort ABI files with C.UTF-8 locale
+
+  * igb: Support using Broadcom 54616 as PHY (LP: #1712024)
+    - SAUCE: igb: add support for using Broadcom 54616 as PHY
+
+  * RPT related fixes missing in Ubuntu 16.04.3 (LP: #1709220)
+    - powerpc/mm/radix: Improve _tlbiel_pid to be usable for PWC flushes
+    - powerpc/mm/radix: Improve TLB/PWC flushes
+    - powerpc/mm/radix: Avoid flushing the PWC on every flush_tlb_range
+
+  * Linux 4.12 refuses to load self-signed modules under Secure Boot with
+    properly enrolled keys (LP: #1712168)
+    - SAUCE: (efi-lockdown) MODSIGN: Fix module signature verification
+
+  * [17.10 FEAT] Enable NVMe driver - kernel (LP: #1708432)
+    - [Config] CONFIG_BLK_DEV_NVME=m for s390
+
+  * Artful: 4.12.0-11.12: Boot panic in vlv2_plat_configure_clock+0x3b/0xa0
+    (LP: #1711298)
+    - [Config] CONFIG_INTEL_ATOMISP=n
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: apparmor: af_unix mediation
+
+  * Miscellaneous upstream changes
+    - apparmor: Fix shadowed local variable in unpack_trans_table()
+    - apparmor: Fix logical error in verify_header()
+    - apparmor: Fix an error code in aafs_create()
+    - apparmor: Redundant condition: prev_ns. in [label.c:1498]
+    - apparmor: add the ability to mediate signals
+    - apparmor: add mount mediation
+    - apparmor: cleanup conditional check for label in label_print
+    - apparmor: add support for absolute root view based labels
+    - apparmor: make policy_unpack able to audit different info messages
+    - apparmor: add more debug asserts to apparmorfs
+    - apparmor: add base infastructure for socket mediation
+    - apparmor: move new_null_profile to after profile lookup fns()
+    - apparmor: fix race condition in null profile creation
+    - apparmor: ensure unconfined profiles have dfas initialized
+    - apparmor: fix incorrect type assignment when freeing proxies
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 23 Aug 2017 08:10:38 -0500
+
+linux (4.13.0-5.6) artful; urgency=low
+
+  * Ubuntu17.10 - perf: Update Power9 PMU event JSON files (LP: #1708630)
+    - perf pmu-events: Support additional POWER8+ PVR in mapfile
+    - perf vendor events: Add POWER9 PMU events
+    - perf vendor events: Add POWER9 PVRs to mapfile
+    - SAUCE: perf vendor events powerpc: remove suffix in mapfile
+    - SAUCE: perf vendor events powerpc: Update POWER9 events
+
+  * Disable CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE (LP: #1709171)
+    - [Config] CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=n for ppc64el
+
+  * Please only recommend or suggest initramfs-tools | linux-initramfs-tool for
+    kernels able to boot without initramfs (LP: #1700972)
+    - [Debian] Don't depend on initramfs-tools
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Import aufs driver
+    - SAUCE: aufs -- Add missing argument to loop_switch() call
+    - [Config] Enable aufs
+    - SAUCE: (noup) Update spl to 0.6.5.11-ubuntu1, zfs to 0.6.5.11-1ubuntu3
+    - Enable zfs build
+    - SAUCE: powerpc: Always initialize input array when calling epapr_hypercall()
+    - [Packaging] switch up to debhelper 9
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 15 Aug 2017 09:24:16 -0500
+
+linux (4.13.0-4.5) artful; urgency=low
+
+  * Lenovo Yoga 910 Sensors (LP: #1708120)
+    - SAUCE: (no-up) HID: Add quirk for Lenovo Yoga 910 with ITE Chips
+
+  * Unable to install Ubuntu on the NVMe disk under VMD PCI domain
+    (LP: #1703339)
+    - [Config] Add vmd driver to generic inclusion list
+
+  * Set CONFIG_SATA_HIGHBANK=y on armhf (LP: #1703430)
+    - [Config] CONFIG_SATA_HIGHBANK=y
+
+  * Miscellaneous Ubuntu changes
+    - ubuntu: vbox -- update to 5.1.26-dfsg-1
+    - SAUCE: hio: Build fixes for 4.13
+    - Enable hio build
+    - SAUCE: (noup) Update spl to 0.6.5.11-1, zfs to 0.6.5.11-1ubuntu1
+    - [debian] use all rather than amd64 dkms debs for sync
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc4
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 08 Aug 2017 11:31:48 -0500
+
+linux (4.13.0-3.4) artful; urgency=low
+
+  * Adt tests of src:linux time out often on armhf lxc containers (LP: #1705495)
+    - [Packaging] tests -- reduce rebuild test to one flavour
+    - [Packaging] tests -- reduce rebuild test to one flavour -- use filter
+
+  * snapd 2.26.8+17.10 ADT test failure with linux 4.12.0-6.7 (LP: #1704158)
+    - SAUCE: virtio_net: Revert mergeable buffer handling rework
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 31 Jul 2017 10:08:16 -0500
+
+linux (4.13.0-2.3) artful; urgency=low
+
+  * Change CONFIG_IBMVETH to module (LP: #1704479)
+    - [Config] CONFIG_IBMVETH=m
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 24 Jul 2017 13:58:08 -0500
+
+linux (4.13.0-1.2) artful; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Support sphinx-based kernel documentation
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Thu, 20 Jul 2017 09:18:33 -0500
+
+linux (4.13.0-0.1) artful; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - Disable hio
+    - Disable zfs build
+    - ubuntu: vbox -- update to 5.1.24-dfsg-1
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.13-rc1
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 19 Jul 2017 15:09:31 -0500
+
+linux (4.12.0-7.8) artful; urgency=low
+
+  * ThunderX: soft lockup on 4.8+ kernels when running qemu-efi with vhost=on
+    (LP: #1673564)
+    - arm64: Add a facility to turn an ESR syndrome into a sysreg encoding
+    - KVM: arm/arm64: vgic-v3: Add accessors for the ICH_APxRn_EL2 registers
+    - KVM: arm64: Make kvm_condition_valid32() accessible from EL2
+    - KVM: arm64: vgic-v3: Add hook to handle guest GICv3 sysreg accesses at EL2
+    - KVM: arm64: vgic-v3: Add ICV_BPR1_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_IGRPEN1_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_IAR1_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_EOIR1_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_AP1Rn_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_HPPIR1_EL1 handler
+    - KVM: arm64: vgic-v3: Enable trapping of Group-1 system registers
+    - KVM: arm64: Enable GICv3 Group-1 sysreg trapping via command-line
+    - KVM: arm64: vgic-v3: Add ICV_BPR0_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_IGNREN0_EL1 handler
+    - KVM: arm64: vgic-v3: Add misc Group-0 handlers
+    - KVM: arm64: vgic-v3: Enable trapping of Group-0 system registers
+    - KVM: arm64: Enable GICv3 Group-0 sysreg trapping via command-line
+    - arm64: Add MIDR values for Cavium cn83XX SoCs
+    - arm64: Add workaround for Cavium Thunder erratum 30115
+    - KVM: arm64: vgic-v3: Add ICV_DIR_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_RPR_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_CTLR_EL1 handler
+    - KVM: arm64: vgic-v3: Add ICV_PMR_EL1 handler
+    - KVM: arm64: Enable GICv3 common sysreg trapping via command-line
+    - KVM: arm64: vgic-v3: Log which GICv3 system registers are trapped
+    - KVM: arm64: Log an error if trapping a read-from-write-only GICv3 access
+    - KVM: arm64: Log an error if trapping a write-to-read-only GICv3 access
+
+  * hns: under heavy load, NIC may fail and require reboot (LP: #1704146)
+    - net: hns: Bugfix for Tx timeout handling in hns driver
+
+  * New ACPI identifiers for ThunderX SMMU (LP: #1703437)
+    - iommu/arm-smmu: Plumb in new ACPI identifiers
+
+  * Transparent hugepages should default to enabled=madvise (LP: #1703742)
+    - SAUCE: use CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y as default
+
+  * Artful update to v4.12.1 stable release (LP: #1703858)
+    - driver core: platform: fix race condition with driver_override
+    - RDMA/uverbs: Check port number supplied by user verbs cmds
+    - usb: dwc3: replace %p with %pK
+    - USB: serial: cp210x: add ID for CEL EM3588 USB ZigBee stick
+    - usb: usbip: set buffer pointers to NULL after free
+    - Add USB quirk for HVR-950q to avoid intermittent device resets
+    - usb: Fix typo in the definition of Endpoint[out]Request
+    - USB: core: fix device node leak
+    - USB: serial: option: add two Longcheer device ids
+    - USB: serial: qcserial: new Sierra Wireless EM7305 device ID
+    - xhci: Limit USB2 port wake support for AMD Promontory hosts
+    - gfs2: Fix glock rhashtable rcu bug
+    - Add "shutdown" to "struct class".
+    - tpm: Issue a TPM2_Shutdown for TPM2 devices.
+    - tpm: fix a kernel memory leak in tpm-sysfs.c
+    - powerpc/powernv: Fix CPU_HOTPLUG=n idle.c compile error
+    - x86/uaccess: Optimize copy_user_enhanced_fast_string() for short strings
+    - sched/fair, cpumask: Export for_each_cpu_wrap()
+    - sched/core: Implement new approach to scale select_idle_cpu()
+    - sched/numa: Use down_read_trylock() for the mmap_sem
+    - sched/numa: Override part of migrate_degrades_locality() when idle balancing
+    - sched/fair: Simplify wake_affine() for the single socket case
+    - sched/numa: Implement NUMA node level wake_affine()
+    - sched/fair: Remove effective_load()
+    - sched/numa: Hide numa_wake_affine() from UP build
+    - xen: avoid deadlock in xenbus driver
+    - crypto: drbg - Fixes panic in wait_for_completion call
+    - Linux 4.12.1
+
+  * cxlflash update request in the Xenial SRU stream (LP: #1702521)
+    - scsi: cxlflash: Combine the send queue locks
+    - scsi: cxlflash: Update cxlflash_afu_sync() to return errno
+    - scsi: cxlflash: Reset hardware queue context via specified register
+    - scsi: cxlflash: Schedule asynchronous reset of the host
+    - scsi: cxlflash: Handle AFU sync failures
+    - scsi: cxlflash: Track pending scsi commands in each hardware queue
+    - scsi: cxlflash: Flush pending commands in cleanup path
+    - scsi: cxlflash: Add scsi command abort handler
+    - scsi: cxlflash: Create character device to provide host management interface
+    - scsi: cxlflash: Separate AFU internal command handling from AFU sync
+      specifics
+    - scsi: cxlflash: Introduce host ioctl support
+    - scsi: cxlflash: Refactor AFU capability checking
+    - scsi: cxlflash: Support LUN provisioning
+    - scsi: cxlflash: Support AFU debug
+    - scsi: cxlflash: Support WS16 unmap
+    - scsi: cxlflash: Remove zeroing of private command data
+    - scsi: cxlflash: Update TMF command processing
+    - scsi: cxlflash: Avoid double free of character device
+    - scsi: cxlflash: Update send_tmf() parameters
+    - scsi: cxlflash: Update debug prints in reset handlers
+
+  * make snap-pkg support (LP: #1700747)
+    - make snap-pkg support
+
+  * Quirk for non-compliant PCI bridge on HiSilicon D05 board (LP: #1698706)
+    - SAUCE: PCI: Support hibmc VGA cards behind a misbehaving HiSilicon bridge
+
+  * arm64: fix crash reading /proc/kcore (LP: #1702749)
+    - fs/proc: kcore: use kcore_list type to check for vmalloc/module address
+    - arm64: mm: select CONFIG_ARCH_PROC_KCORE_TEXT
+
+  * Opal and POWER9 DD2 (LP: #1702159)
+    - SAUCE: powerpc/powernv: Tell OPAL about our MMU mode on POWER9
+
+  * Data corruption with hio driver  (LP: #1701316)
+    - SAUCE: hio: Fix incorrect use of enum req_opf values
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.6.5.10-1, zfs to 0.6.5.10-1ubuntu2
+    - snapcraft.yaml: Sync with xenial
+    - [Config] CONFIG_CAVIUM_ERRATUM_30115=y
+
+  * Miscellaneous upstream changes
+    - Revert "UBUNTU: SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and
+      MokSBState"
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 14 Jul 2017 15:25:41 -0500
+
+linux (4.12.0-6.7) artful; urgency=low
+
+  * update ENA driver to 1.2.0k from net-next (LP: #1701575)
+    - net: ena: change return value for unsupported features unsupported return
+      value
+    - net: ena: add hardware hints capability to the driver
+    - net: ena: change sizeof() argument to be the type pointer
+    - net: ena: add reset reason for each device FLR
+    - net: ena: add support for out of order rx buffers refill
+    - net: ena: allow the driver to work with small number of msix vectors
+    - net: ena: use napi_schedule_irqoff when possible
+    - net: ena: separate skb allocation to dedicated function
+    - net: ena: use lower_32_bits()/upper_32_bits() to split dma address
+    - net: ena: update driver's rx drop statistics
+    - net: ena: update ena driver to version 1.2.0
+
+  * APST gets enabled against explicit kernel option (LP: #1699004)
+    - nvme: explicitly disable APST on quirked devices
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: hio: Update to Huawei ES3000_V2 (2.1.0.40)
+    - SAUCE: hio updates for 4.12
+    - SAUCE: Enable hio build
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 05 Jul 2017 14:23:20 -0500
+
+linux (4.12.0-5.6) artful; urgency=low
+
+  * ERAT invalidate on context switch removal (LP: #1700819)
+    - powerpc: Only do ERAT invalidate on radix context switch on P9 DD1
+
+  * powerpc: Invalidate ERAT on powersave wakeup for POWER9 (LP: #1700521)
+    - SAUCE: powerpc: Invalidate ERAT on powersave wakeup for POWER9
+
+  * Miscellaneous Ubuntu changes
+    - d-i: Move qcom-emac from arm64 to shared nic-modules
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 03 Jul 2017 07:52:02 -0500
+
+linux (4.12.0-4.5) artful; urgency=low
+
+  * aacraid driver may return uninitialized stack data to userspace
+    (LP: #1700077)
+    - SAUCE: scsi: aacraid: Don't copy uninitialized stack memory to userspace
+
+  * KILLER1435-S[0489:e0a2] BT cannot search BT 4.0 device (LP: #1699651)
+    - Bluetooth: btusb: Add support for 0489:e0a2 QCA_ROME device
+
+  * AACRAID for power9 platform (LP: #1689980)
+    - scsi: aacraid: Remove __GFP_DMA for raw srb memory
+    - scsi: aacraid: Fix DMAR issues with iommu=pt
+    - scsi: aacraid: Added 32 and 64 queue depth for arc natives
+    - scsi: aacraid: Set correct Queue Depth for HBA1000 RAW disks
+    - scsi: aacraid: Remove reset support from check_health
+    - scsi: aacraid: Change wait time for fib completion
+    - scsi: aacraid: Log count info of scsi cmds before reset
+    - scsi: aacraid: Print ctrl status before eh reset
+    - scsi: aacraid: Using single reset mask for IOP reset
+    - scsi: aacraid: Rework IOP reset
+    - scsi: aacraid: Add periodic checks to see IOP reset status
+    - scsi: aacraid: Rework SOFT reset code
+    - scsi: aacraid: Rework aac_src_restart
+    - scsi: aacraid: Use correct function to get ctrl health
+    - scsi: aacraid: Make sure ioctl returns on controller reset
+    - scsi: aacraid: Enable ctrl reset for both hba and arc
+    - scsi: aacraid: Add reset debugging statements
+    - scsi: aacraid: Remove reference to Series-9
+    - scsi: aacraid: Update driver version to 50834
+
+  * hibmc driver does not include "pci:" prefix in bus ID (LP: #1698700)
+    - SAUCE: drm: hibmc: Use set_busid function from drm core
+
+  * HiSilicon D05: installer doesn't appear on VGA (LP: #1698954)
+    - d-i: Add hibmc-drm to kernel-image udeb
+
+  * Fix /proc/cpuinfo revision for POWER9 DD2 (LP: #1698844)
+    - SAUCE: powerpc: Fix /proc/cpuinfo revision for POWER9 DD2
+
+  * Miscellaneous Ubuntu changes
+    - [Config] CONFIG_SATA_MV=n and CONFIG_GENERIC_PHY=n for s390x
+    - [Config] CONFIG_ATA=n for s390x
+    - [Config] Update annotations for 4.12
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 26 Jun 2017 11:27:29 -0500
+
+linux (4.12.0-3.4) artful; urgency=low
+
+  * Miscellaneous upstream changes
+    - ufs: fix the logics for tail relocation
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc6
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 19 Jun 2017 14:50:39 -0500
+
+linux (4.12.0-2.3) artful; urgency=low
+
+  * CVE-2014-9900
+    - SAUCE: (no-up) net: Zeroing the structure ethtool_wolinfo in
+      ethtool_get_wol()
+
+  * System doesn't boot properly on Gigabyte AM4 motherboards (AMD Ryzen)
+    (LP: #1671360)
+    - pinctrl/amd: Use regular interrupt instead of chained
+
+  * extend-diff-ignore should use exact matches (LP: #1693504)
+    - [Packaging] exact extend-diff-ignore matches
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: efi: Don't print secure boot state from the efi stub
+    - ubuntu: vbox -- Update to 5.1.22-dfsg-1
+    - SAUCE: vbox fixes for 4.12
+    - Re-enable virtualbox build
+    - [Config] CONFIG_ORANGEFS_FS=m
+    - SAUCE: (noup) Update spl to 0.6.5.9-1ubuntu2, zfs to 0.6.5.9-5ubuntu7
+    - Enable zfs build
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc4
+  * Rebase to v4.12-rc5
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 11 Jun 2017 22:25:13 -0500
+
+linux (4.12.0-1.2) artful; urgency=low
+
+  * Enable Matrox driver for Ubuntu 16.04.3 (LP: #1693337)
+    - [Config] Enable CONFIG_DRM_MGAG200 as module
+
+  * Support low-pin-count devices on Hisilicon SoCs (LP: #1677319)
+    - [Config] CONFIG_LIBIO=y on arm64 only
+    - SAUCE: LIBIO: Introduce a generic PIO mapping method
+    - SAUCE: OF: Add missing I/O range exception for indirect-IO devices
+    - [Config] CONFIG_HISILICON_LPC=y
+    - SAUCE: LPC: Support the device-tree LPC host on Hip06/Hip07
+    - SAUCE: LIBIO: Support the dynamically logical PIO registration of ACPI host
+      I/O
+    - SAUCE: LPC: Add the ACPI LPC support
+    - SAUCE: PCI: Apply the new generic I/O management on PCI IO hosts
+    - SAUCE: PCI: Restore codepath for !CONFIG_LIBIO
+
+  * POWER9: Additional patches for TTY and CPU_IDLE (LP: #1674325)
+    - SAUCE: tty: Fix ldisc crash on reopened tty
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Add build-dep on libnuma-dev to enable 'perf bench numa'
+    - Rebase to v4.12-rc3
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc3
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Mon, 29 May 2017 20:56:29 -0500
+
+linux (4.12.0-0.1) artful; urgency=low
+
+  * please enable CONFIG_ARM64_LSE_ATOMICS (LP: #1691614)
+    - [Config] CONFIG_ARM64_LSE_ATOMICS=y
+
+  * [Regression] NUMA_BALANCING disabled on arm64 (LP: #1690914)
+    - [Config] CONFIG_NUMA_BALANCING{,_DEFAULT_ENABLED}=y on arm64
+
+  * exec'ing a setuid binary from a threaded program sometimes fails to setuid
+    (LP: #1672819)
+    - SAUCE: exec: ensure file system accounting in check_unsafe_exec is correct
+
+  * Miscellaneous Ubuntu changes
+    - Update find-missing-sauce.sh to compare to artful
+    - Update dropped.txt
+    - SAUCE: (efi-lockdown) efi: Add EFI_SECURE_BOOT bit
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/mem and /dev/kmem when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Add a sysrq option to exit secure boot mode
+    - SAUCE: (efi-lockdown) kexec: Disable at runtime if the kernel is locked down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) kexec_file: Disable at runtime if securelevel has been
+      set
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) asus-wmi: Restrict debugfs interface when the kernel
+      is locked down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Enable cold boot attack mitigation
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) scsi: Lock down the eata driver
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) KEYS: Allow unrestricted boot-time addition of keys to
+      secondary keyring
+    - SAUCE: (efi-lockdown) efi: Add EFI signature data types
+    - SAUCE: (efi-lockdown) efi: Add an EFI signature blob parser
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Allow the "db" UEFI variable to be suppressed
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) efi: Add secure_boot state and status bit for
+      MokSBState
+    - SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and MokSBState
+    - [Config] Set values for UEFI secure boot lockdown options
+    - Disable virtualbox build
+    - Disable hio build
+    - SAUCE: securityfs: Replace CURRENT_TIME with current_time()
+    - Disable zfs build
+    - [Debian] Work out upstream tag for use with gen-auto-reconstruct
+    - SAUCE: Import aufs driver
+    - SAUCE: aufs -- Include linux/mm.h in fs/aufs/file.h
+    - [Config] Enable aufs
+    - SAUCE: perf callchain: Include errno.h on x86 unconditinally
+
+  [ Upstream Kernel Changes ]
+
+  * Rebase to v4.12-rc2
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Sun, 21 May 2017 23:44:44 -0500
+
+linux (4.11.0-3.8) artful; urgency=low
+
+  [ Seth Forshee ]
+
+  * Release Tracking Bug
+    - LP: #1690999
+
+  * apparmor_parser hangs indefinitely when called by multiple threads
+    (LP: #1645037)
+    - SAUCE: apparmor: fix lock ordering for mkdir
+
+  * apparmor leaking securityfs pin count (LP: #1660846)
+    - SAUCE: apparmor: fix leak on securityfs pin count
+
+  * apparmor reference count leak when securityfs_setup_d_inode\ () fails
+    (LP: #1660845)
+    - SAUCE: apparmor: fix reference count leak when securityfs_setup_d_inode()
+      fails
+
+  * apparmor not checking error if security_pin_fs() fails (LP: #1660842)
+    - SAUCE: apparmor: fix not handling error case when securityfs_pin_fs() fails
+
+  * libvirt profile is blocking global setrlimit despite having no rlimit rule
+    (LP: #1679704)
+    - SAUCE: apparmor: fix complain mode failure for rlimit mediation
+    - apparmor: update auditing of rlimit check to provide capability information
+
+  * apparmor: does not provide a way to detect policy updataes (LP: #1678032)
+    - SAUCE: apparmor: add policy revision file interface
+
+  * apparmor does not make support of query data visible (LP: #1678023)
+    - SAUCE: apparmor: add label data availability to the feature set
+
+  * apparmor query interface does not make supported query info available
+    (LP: #1678030)
+    - SAUCE: apparmor: add information about the query inteface to the feature set
+
+  * change_profile incorrect when using namespaces with a compound stack
+    (LP: #1677959)
+    - SAUCE: apparmor: fix label parse for stacked labels
+
+  * Regression in 4.4.0-65-generic causes very frequent system crashes
+    (LP: #1669611)
+    - apparmor: sync of apparmor 3.6+ (17.04)
+
+  * Artful update to 4.11.1 stable release (LP: #1690814)
+    - dm ioctl: prevent stack leak in dm ioctl call
+    - drm/sti: fix GDP size to support up to UHD resolution
+    - power: supply: lp8788: prevent out of bounds array access
+    - brcmfmac: Ensure pointer correctly set if skb data location changes
+    - brcmfmac: Make skb header writable before use
+    - sparc64: fix fault handling in NGbzero.S and GENbzero.S
+    - refcount: change EXPORT_SYMBOL markings
+    - net: macb: fix phy interrupt parsing
+    - tcp: fix access to sk->sk_state in tcp_poll()
+    - geneve: fix incorrect setting of UDP checksum flag
+    - bpf: enhance verifier to understand stack pointer arithmetic
+    - bpf, arm64: fix jit branch offset related to ldimm64
+    - tcp: fix wraparound issue in tcp_lp
+    - net: ipv6: Do not duplicate DAD on link up
+    - net: usb: qmi_wwan: add Telit ME910 support
+    - tcp: do not inherit fastopen_req from parent
+    - ipv4, ipv6: ensure raw socket message is big enough to hold an IP header
+    - rtnetlink: NUL-terminate IFLA_PHYS_PORT_NAME string
+    - ipv6: initialize route null entry in addrconf_init()
+    - ipv6: reorder ip6_route_dev_notifier after ipv6_dev_notf
+    - tcp: randomize timestamps on syncookies
+    - bnxt_en: allocate enough space for ->ntp_fltr_bmap
+    - bpf: don't let ldimm64 leak map addresses on unprivileged
+    - net: mdio-mux: bcm-iproc: call mdiobus_free() in error path
+    - f2fs: sanity check segment count
+    - xen/arm,arm64: fix xen_dma_ops after 815dd18 "Consolidate get_dma_ops..."
+    - xen: Revert commits da72ff5bfcb0 and 72a9b186292d
+    - block: get rid of blk_integrity_revalidate()
+    - Linux 4.11.1
+
+  * Module signing exclusion for staging drivers does not work properly
+    (LP: #1690908)
+    - SAUCE: Fix module signing exclusion in package builds
+
+  * perf: qcom: Add L3 cache PMU driver (LP: #1689856)
+    - [Config] CONFIG_QCOM_L3_PMU=y
+    - perf: qcom: Add L3 cache PMU driver
+
+  * No PMU support for ACPI-based arm64 systems (LP: #1689661)
+    - drivers/perf: arm_pmu: rework per-cpu allocation
+    - drivers/perf: arm_pmu: manage interrupts per-cpu
+    - drivers/perf: arm_pmu: split irq request from enable
+    - drivers/perf: arm_pmu: remove pointless PMU disabling
+    - drivers/perf: arm_pmu: define armpmu_init_fn
+    - drivers/perf: arm_pmu: fold init into alloc
+    - drivers/perf: arm_pmu: factor out pmu registration
+    - drivers/perf: arm_pmu: simplify cpu_pmu_request_irqs()
+    - drivers/perf: arm_pmu: handle no platform_device
+    - drivers/perf: arm_pmu: rename irq request/free functions
+    - drivers/perf: arm_pmu: split cpu-local irq request/free
+    - drivers/perf: arm_pmu: move irq request/free into probe
+    - drivers/perf: arm_pmu: split out platform device probe logic
+    - arm64: add function to get a cpu's MADT GICC table
+    - [Config] CONFIG_ARM_PMU_ACPI=y
+    - drivers/perf: arm_pmu: add ACPI framework
+    - arm64: pmuv3: handle !PMUv3 when probing
+    - arm64: pmuv3: use arm_pmu ACPI framework
+
+  * Fix NVLINK2 TCE route (LP: #1690155)
+    - powerpc/powernv: Fix TCE kill on NVLink2
+
+  * CVE-2017-0605
+    - tracing: Use strlcpy() instead of strcpy() in __trace_find_cmdline()
+
+  * Miscellaneous Ubuntu changes
+    - [Config] Restore powerpc arch to annotations file
+    - [Config] Disable runtime testing modules
+    - [Config] Disable drivers not needed on s390x
+    - [Config] Update annotations for 4.11
+    - [Config] updateconfigs after apparmor updates
+
+  * Miscellaneous upstream changes
+    - apparmor: use SHASH_DESC_ON_STACK
+    - apparmor: fix invalid reference to index variable of iterator line 836
+    - apparmor: fix parameters so that the permission test is bypassed at boot
+    - apparmor: Make path_max parameter readonly
+    - apparmorfs: Combine two function calls into one in aa_fs_seq_raw_abi_show()
+    - apparmorfs: Use seq_putc() in two functions
+    - apparmor: provide information about path buffer size at boot
+    - apparmor: add/use fns to print hash string hex value
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 16 May 2017 00:39:13 -0500
+
+linux (4.11.0-2.7) artful; urgency=low
+
+  * kernel-wedge fails in artful due to leftover squashfs-modules d-i files
+    (LP: #1688259)
+    - Remove squashfs-modules files from d-i
+    - [Config] as squashfs-modules is builtin kernel-image must Provides: it
+
+  * [Zesty] d-i: replace msm_emac with qcom_emac (LP: #1677297)
+    - Revert "UBUNTU: d-i: initrd needs msm_emac on amberwing platform."
+    - d-i: initrd needs qcom_emac on amberwing platform.
+
+  * update for V3 kernel bits and improved multiple fan slice support
+    (LP: #1470091)
+    - SAUCE: fan: tunnel multiple mapping mode (v3)
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: (noup) Update spl to 0.6.5.9-1ubuntu1, zfs to 0.6.5.9-5ubuntu5
+    - Enable zfs
+    - SAUCE: fan: add VXLAN implementation
+    - SAUCE: (efi-lockdown) efi: Add EFI_SECURE_BOOT bit
+    - SAUCE: (efi-lockdown) Add the ability to lock down access to the running
+      kernel image
+    - SAUCE: (efi-lockdown) efi: Lock down the kernel if booted in secure boot
+      mode
+    - SAUCE: (efi-lockdown) Enforce module signatures if the kernel is locked down
+    - SAUCE: (efi-lockdown) Restrict /dev/mem and /dev/kmem when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Add a sysrq option to exit secure boot mode
+    - SAUCE: (efi-lockdown) kexec: Disable at runtime if the kernel is locked down
+    - SAUCE: (efi-lockdown) Copy secure_boot flag in boot params across kexec
+      reboot
+    - SAUCE: (efi-lockdown) kexec_file: Disable at runtime if securelevel has been
+      set
+    - SAUCE: (efi-lockdown) hibernate: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) uswsusp: Disable when the kernel is locked down
+    - SAUCE: (efi-lockdown) PCI: Lock down BAR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) x86: Lock down IO port access when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) x86: Restrict MSR access when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) asus-wmi: Restrict debugfs interface when the kernel
+      is locked down
+    - SAUCE: (efi-lockdown) ACPI: Limit access to custom_method when the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Ignore acpi_rsdp kernel param when the kernel
+      has been locked down
+    - SAUCE: (efi-lockdown) acpi: Disable ACPI table override if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) acpi: Disable APEI error injection if the kernel is
+      locked down
+    - SAUCE: (efi-lockdown) Enable cold boot attack mitigation
+    - SAUCE: (efi-lockdown) bpf: Restrict kernel image access functions when the
+      kernel is locked down
+    - SAUCE: (efi-lockdown) scsi: Lock down the eata driver
+    - SAUCE: (efi-lockdown) Prohibit PCMCIA CIS storage when the kernel is locked
+      down
+    - SAUCE: (efi-lockdown) Lock down TIOCSSERIAL
+    - SAUCE: (efi-lockdown) Add EFI signature data types
+    - SAUCE: (efi-lockdown) Add an EFI signature blob parser and key loader.
+    - SAUCE: (efi-lockdown) KEYS: Add a system blacklist keyring
+    - SAUCE: (efi-lockdown) MODSIGN: Import certificates from UEFI Secure Boot
+    - SAUCE: (efi-lockdown) MODSIGN: Support not importing certs from db
+    - SAUCE: (efi-lockdown) MODSIGN: Don't try secure boot if EFI runtime is
+      disabled
+    - SAUCE: (efi-lockdown) efi: Sanitize boot_params in efi stub
+    - SAUCE: (efi-lockdown) efi: Add secure_boot state and status bit for
+      MokSBState
+    - SAUCE: (efi-lockdown) efi: Add sysctls for secureboot and MokSBState
+    - [Config] Set values for UEFI secure boot lockdown options
+    - Update dropped.txt
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Fri, 05 May 2017 07:43:14 -0500
+
+linux (4.11.0-1.6) artful; urgency=low
+
+  * Miscellaneous Ubuntu changes
+    - [Debian] Use default compression for all packages
+    - SAUCE: (namespace) block_dev: Support checking inode permissions in
+      lookup_bdev()
+    - SAUCE: (namespace) block_dev: Check permissions towards block device inode
+      when mounting
+    - SAUCE: (namespace) mtd: Check permissions towards mtd block device inode
+      when mounting
+    - SAUCE: (namespace) fs: Allow superblock owner to change ownership of inodes
+    - SAUCE: (namespace) fs: Don't remove suid for CAP_FSETID for userns root
+    - SAUCE: (namespace) fs: Allow superblock owner to access do_remount_sb()
+    - SAUCE: (namespace) capabilities: Allow privileged user in s_user_ns to set
+      security.* xattrs
+    - SAUCE: (namespace) fs: Allow CAP_SYS_ADMIN in s_user_ns to freeze and thaw
+      filesystems
+    - SAUCE: (namespace) fuse: Add support for pid namespaces
+    - SAUCE: (namespace) fuse: Support fuse filesystems outside of init_user_ns
+    - SAUCE: (namespace) fuse: Restrict allow_other to the superblock's namespace
+      or a descendant
+    - SAUCE: (namespace) fuse: Allow user namespace mounts
+    - SAUCE: (namespace) ext4: Add support for unprivileged mounts from user
+      namespaces
+    - SAUCE: (namespace) evm: Don't update hmacs in user ns mounts
+    - SAUCE: (namespace) ext4: Add module parameter to enable user namespace
+      mounts
+    - SAUCE: (namespace) block_dev: Forbid unprivileged mounting when device is
+      opened for writing
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Wed, 26 Apr 2017 10:08:29 -0500
+
+linux (4.11.0-0.5) artful; urgency=low
+
+  * [Hyper-V][SAUCE] pci-hyperv: Use only 16 bit integer for PCI domain
+    (LP: #1684971)
+    - SAUCE: pci-hyperv: Use only 16 bit integer for PCI domain
+
+  * [Hyper-V] Ubuntu 14.04.2 LTS Generation 2 SCSI Errors on VSS Based Backups
+    (LP: #1470250)
+    - SAUCE: Tools: hv: vss: Thaw the filesystem and continue after freeze fails
+
+  * Enable virtual scsi server driver for Power (LP: #1615665)
+    - SAUCE: Return TCMU-generated sense data to fabric module
+
+  * include/linux/security.h header syntax error with !CONFIG_SECURITYFS
+    (LP: #1630990)
+    - SAUCE: (no-up) include/linux/security.h -- fix syntax error with
+      CONFIG_SECURITYFS=n
+
+  * Miscellaneous Ubuntu changes
+    - SAUCE: Import aufs driver
+    - [Config] Enable aufs
+    - [Debian] Add script to update virtualbox
+    - ubuntu: vbox -- Update to 5.1.20-dfsg-2
+    - Enable vbox
+    - SAUCE: aufs -- Include linux/mm.h in fs/aufs/file.h
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc8
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 25 Apr 2017 13:42:54 -0500
+
+linux (4.11.0-0.4) zesty; urgency=low
+
+  * POWER9: Improve performance on memory management (LP: #1681429)
+    - SAUCE: powerpc/mm/radix: Don't do page walk cache flush when doing full mm
+      flush
+    - SAUCE: powerpc/mm/radix: Remove unnecessary ptesync
+
+  * Miscellaneous Ubuntu changes
+    - find-missing-sauce.sh
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc7
+
+ -- Seth Forshee <seth.forshee@canonical.com>  Tue, 18 Apr 2017 08:19:43 -0500
+
+linux (4.11.0-0.3) zesty; urgency=low
+
+  * Disable CONFIG_HVC_UDBG on ppc64el (LP: #1680888)
+    - [Config] Disable CONFIG_HVC_UDBG on ppc64el
+
+  * smartpqi driver needed in initram disk and installer (LP: #1680156)
+    - [Config] Add smartpqi to d-i
+
+  * Disable CONFIG_SECURITY_SELINUX_DISABLE (LP: #1680315)
+    - [Config] CONFIG_SECURITY_SELINUX_DISABLE=n
+
+  * Miscellaneous Ubuntu changes
+    - [Config] flash-kernel should be a Breaks
+    - [Config] drop the info directory
+    - [Config] drop NOTES as obsolete
+    - [Config] drop changelog.historical as obsolete
+    - rebase to v4.11-rc6
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc6
+
+ -- Tim Gardner <tim.gardner@canonical.com>  Tue, 11 Apr 2017 07:16:52 -0600
+
+linux (4.11.0-0.2) zesty; urgency=low
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc5
+
+ -- Tim Gardner <tim.gardner@canonical.com>  Mon, 03 Apr 2017 08:26:07 +0100
+
+linux (4.11.0-0.1) zesty; urgency=low
+
+  [ Upstream Kernel Changes ]
+
+  * rebase to v4.11-rc4
+    - LP: #1591053
+
+ -- Tim Gardner <tim.gardner@canonical.com>  Mon, 20 Mar 2017 05:15:32 -0600
+
+linux (4.11.0-0.0) zesty; urgency=low
+
+  * dummy entry
+
+ -- Tim Gardner <tim.gardner@canonical.com>  Mon, 20 Mar 2017 05:15:32 -0600
--- linux-qcom-6.8.0.orig/debian/cloud-tools/hv_get_dhcp_info
+++ linux-qcom-6.8.0/debian/cloud-tools/hv_get_dhcp_info
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+# This example script retrieves the DHCP state of a given interface.
+# In the interest of keeping the KVP daemon code free of distro specific
+# information; the kvp daemon code invokes this external script to gather
+# DHCP setting for the specific interface.
+#
+# Input: Name of the interface
+#
+# Output: The script prints the string "Enabled" to stdout to indicate
+#	that DHCP is enabled on the interface. If DHCP is not enabled,
+#	the script prints the string "Disabled" to stdout.
+#
+# Each Distro is expected to implement this script in a distro specific
+# fashion. 
+
+#set -x
+
+IF_FILE="/etc/network/interfaces"
+NMCMD="nmcli"
+
+function checknetworkmanager {
+	#Assumes if $NMCMD exists, inteface exists and interface is not
+	#  in $IF_FILE then dhcp is being used by NM
+        if  hash $NMCMD >/dev/null 2>&1  ; then
+                if  $NMCMD  dev status |grep -q $1  ; then
+                        echo "Enabled"
+                else
+                        echo "Disabled"
+                fi
+        else
+                #Give up
+                echo "Disabled"
+        fi
+}
+
+if [ -z $1 ]  ; then echo "Disabled"; exit; fi
+
+if [ -e $IF_FILE ]; then
+	if grep -v -e "^#" $IF_FILE|grep -q $1 ; then
+		#interface exists so
+		if grep -q -e $1\.\*dhcp $IF_FILE; then 
+			echo "Enabled"; exit;
+		else
+			echo "Disabled"; exit;
+		fi
+	else
+		checknetworkmanager $1
+		exit
+	fi
+else
+	checknetworkmanager $1
+	exit
+fi
+
--- linux-qcom-6.8.0.orig/debian/cloud-tools/hv_get_dns_info
+++ linux-qcom-6.8.0/debian/cloud-tools/hv_get_dns_info
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+# This example script parses /etc/resolv.conf to retrive DNS information.
+# In the interest of keeping the KVP daemon code free of distro specific
+# information; the kvp daemon code invokes this external script to gather
+# DNS information.
+# This script is expected to print the nameserver values to stdout.
+# Each Distro is expected to implement this script in a distro specific
+# fashion. For instance on Distros that ship with Network Manager enabled,
+# this script can be based on the Network Manager APIs for retrieving DNS
+# entries.
+
+cat /etc/resolv.conf 2>/dev/null | awk '/^nameserver/ { print $2 }'
--- linux-qcom-6.8.0.orig/debian/cloud-tools/hv_set_ifconfig
+++ linux-qcom-6.8.0/debian/cloud-tools/hv_set_ifconfig
@@ -0,0 +1,288 @@
+#!/usr/bin/python3
+#
+# hv_set_ifconfig <config> -- take the hv_kvp_daemon generated configuration
+#                             file and apply it to the Ubuntu configuration.
+#
+
+# CONFIG example:
+# HWADDR=11:22:33:44:55:66
+# DEVICE=foo1
+# DHCP=yes
+
+# CONFIG example:
+# HWADDR=11:22:33:44:55:66
+# DEVICE=foo1
+# IPADDR=192.168.99.10
+# GATEWAY=192.168.99.1
+# DNS1=192.168.88.250
+# IPADDR2=192.168.99.11
+# IPV6ADDR=2001:DB8:99::10
+# IPV6NETMASK=64
+# IPV6_DEFAULTGW=2001:DB8:99::10
+
+# set interfaces in hv_kvp_daemon style
+import fileinput
+import sys
+import errno
+import os
+import shutil
+import tempfile
+import subprocess
+
+if_filename="/etc/network/interfaces"
+
+# Drop our output (XXX?)
+sys.stdout = open(os.devnull, 'w')
+sys.stderr = open(os.devnull, 'w')
+
+# Confirm we can open the network configuration.
+try:
+    if_file=open(if_filename,"r+")
+except IOError as e:
+    exit(e.errno)
+else:
+    if_file.close()
+
+# Usage: hv_set_ifconfig <config>
+if len(sys.argv) != 2 :
+    exit(errno.EINVAL)
+
+#
+# Here is the format of the ip configuration file:
+#
+# HWADDR=macaddr
+# DEVICE=interface name
+# BOOTPROTO=<protocol> (where <protocol> is "dhcp" if DHCP is configured
+#                       or "none" if no boot-time protocol should be used)
+#
+# IPADDR0=ipaddr1
+# IPADDR1=ipaddr2
+# IPADDRx=ipaddry (where y = x + 1)
+#
+# NETMASK0=netmask1
+# NETMASKx=netmasky (where y = x + 1)
+#
+# GATEWAY=ipaddr1
+# GATEWAYx=ipaddry (where y = x + 1)
+#
+# DNSx=ipaddrx (where first DNS address is tagged as DNS1 etc)
+#
+# IPV6 addresses will be tagged as IPV6ADDR, IPV6 gateway will be
+# tagged as IPV6_DEFAULTGW and IPV6 NETMASK will be tagged as
+# IPV6NETMASK.
+#
+
+kvp=dict(line.strip().split("=") for line in fileinput.input())
+
+# Setting the hwaddress to something azure is not expecting is fatal
+# to networking.
+if not "HWADDR" in kvp :
+    exit(errno.EPROTO)
+
+# Confirm we have a device specified.
+if not "DEVICE" in kvp :
+    exit(1)
+
+autolist = []
+output=[]
+basename=kvp["DEVICE"]
+
+# DNS entries will go with the first interface and there can be a max
+# of three.  These will be emitted with the first interface.
+dns = []
+for count in (1, 2, 3):
+    key = "DNS" + str(count)
+    if key in kvp:
+        dns += [kvp[key]]
+dns_emitted = False
+
+# IPV4 may either be dhcp or static.
+if ("DHCP" in kvp and kvp["DHCP"] == "yes") or \
+   ("BOOTPROTO" in kvp and kvp["BOOTPROTO"] == "dhcp"):
+    autolist.append(basename)
+    output += ["iface " + basename  + " inet dhcp"]
+    output += [""]
+else:
+    # Matchup the interface specific lines
+
+    # No real max for the number of interface + aliases ...
+    # only required is the address (but mate everything up that comes in.
+
+    # IPv4 -- ensure we sort by numeric suffixes.
+    v4names = [ int(name[6:]) for name in kvp.keys() if name.startswith("IPADDR") ]
+    v4names.sort()
+
+    for if_count in v4names:
+        ifname = basename
+        which = str(if_count)
+
+        if if_count:
+            ifname += ":" + str(if_count)
+            which_gw = which
+        else:
+            which_gw = ""
+
+        if not ifname in autolist:
+            autolist += [ifname]
+
+        output += [ "iface " + ifname + " inet static" ]
+        output += [ "\t" + "address " + kvp["IPADDR" + which] ]
+        if "NETMASK" + which in kvp:
+            output += [ "\tnetmask " + kvp["NETMASK" + which] ]
+        if "GATEWAY" + which_gw in kvp:
+            output += ["\tgateway " + kvp["GATEWAY" + which_gw]]
+
+        if not dns_emitted:
+            dns_emitted = True
+            output += ["\tdns-nameservers " + ' '.join(dns)]
+        output += [""]
+
+# IPv6 requires a netmask
+# If an ipv6 exists, you'll want to turn off /proc/sys/net/ipv6/conf/all/autoconf with
+# echo 0 > /proc/sys/net/ipv6/conf/all/autoconf
+v6names = [ int(name[8:]) for name in kvp.keys() if name.startswith("IPV6ADDR") ]
+v6names.sort()
+
+for if6_count in v6names:
+    ifname = basename
+    which = str(if6_count)
+
+    if if6_count:
+        ifname += ":" + str(if6_count)
+        which_gw = which
+    else:
+        which_gw = ""
+
+    if not ifname in autolist:
+        autolist += [ifname]
+
+    if "IPV6NETMASK" + which in kvp:
+        output += [ "iface " + ifname + " inet6 static"]
+        output += [ "\taddress " + kvp["IPV6ADDR" + which]]
+        output += [ "\tnetmask " + kvp["IPV6NETMASK" + which]]
+        if "IPV6_DEFAULTGW" + which_gw in kvp:
+            output += [ "\tgateway " + kvp["IPV6_DEFAULTGW" + which_gw] ]
+        if not dns_emitted:
+            dns_emitted = True
+            output += ["\tdns-nameservers " + ' '.join(dns)]
+        output += [""]
+
+# Mark this new interface for automatic up.
+if len(autolist):
+    output = ["auto "+" ".join(autolist)] + output
+
+print("===================================")
+print(output)
+print("===================================")
+
+
+# Time to clean out the existing interface file
+
+# Markers.
+start_mark = "# The following stanza(s) added by hv_set_ifconfig"
+end_mark = "#End of hv_set_ifconfig stanzas"
+
+f=open(if_filename,"r")
+flines=f.readlines()
+f.close()
+newfile=[]
+pitchstanza=0
+inastanza=0
+stanza=[]
+prev_line=None
+for line in flines:
+    if line.startswith("auto"):
+        if inastanza:
+            if not pitchstanza:
+                newfile.extend(stanza)
+            stanza=[]
+        inastanza=0
+        newline=""
+        autoline=line.strip().split(" ")
+        for word in autoline:
+            if (not word == basename) and (not word.startswith(basename+":")):
+                newline+=word + " "
+        newline = newline.strip()
+        if not newline == "auto":
+            newfile += [newline.strip()]
+    elif line.startswith(("iface","mapping","source")):
+        '''Read a stanza'''
+        '''A Stanza can also start with allow- ie allow-hotplug'''
+        if inastanza:
+            if not pitchstanza:
+                newfile.extend(stanza)
+            stanza=[]
+        inastanza=1
+        pitchstanza=0
+        autoline=line.strip().split(" ")
+        for word in autoline:
+            if (word == basename) or (word.startswith(basename+":")):
+                pitchstanza=1
+        if not pitchstanza:
+            stanza+=[line.strip()]
+    elif line.strip() in (start_mark, end_mark):
+        if inastanza:
+            if not pitchstanza:
+                newfile.extend(stanza)
+            stanza=[]
+        inastanza = 0
+        pitchstanza = 0
+        # Deduplicate markers.
+        if line != prev_line:
+            newfile += [line.strip()]
+    else:
+        if inastanza:
+            if not pitchstanza:
+                stanza+=[line.strip()]
+        else:
+            if not pitchstanza:
+                newfile += [line.strip()]
+    prev_line=line
+
+# Include pending stanza if any.
+if inastanza and not pitchstanza:
+    newfile.extend(stanza)
+
+
+def emit(line):
+    print(line)
+    output = line + "\n"
+    os.write(fd, output.encode('utf-8'))
+
+# Insert the new output at the end and inside the existing markers if found.
+emitted = False
+fd, path = tempfile.mkstemp()
+for line in newfile:
+    if line == end_mark:
+        emit("\n".join(output))
+        emitted = True
+    emit(line)
+if not emitted:
+    emit(start_mark)
+    emit("\n".join(output))
+    emit(end_mark)
+os.close(fd)
+
+shutil.copy(path,if_filename)
+os.chmod(if_filename,0o644)
+
+#print("TMPFILE is at: " + path)
+#print("Copied file is at: " + if_filename)
+
+try:
+    retcode = subprocess.call("ifdown "+basename , shell=True)
+    if retcode < 0:
+        print("Child was terminated by signal", -retcode, file=sys.stderr)
+    else:
+        print("Child returned", retcode, file=sys.stderr)
+except OSError as e:
+    print("Execution failed:", e, file=sys.stderr)
+
+try:
+    retcode = subprocess.call("ifup "+basename , shell=True)
+    if retcode < 0:
+        print("Child was terminated by signal", -retcode, file=sys.stderr)
+    else:
+        print("Child returned", retcode, file=sys.stderr)
+except OSError as e:
+    print("Execution failed:", e, file=sys.stderr)
--- linux-qcom-6.8.0.orig/debian/control
+++ linux-qcom-6.8.0/debian/control
@@ -0,0 +1,229 @@
+Source: linux-qcom
+Section: devel
+Priority: optional
+Maintainer: Ubuntu Kernel Team <kernel-team@lists.ubuntu.com>
+XSC-Ubuntu-Compatible-Signing: ubuntu/4 pro/3
+Rules-Requires-Root: no
+Standards-Version: 3.9.4.0
+Build-Depends:
+ gcc-13, gcc-13-aarch64-linux-gnu [arm64] <cross>, gcc-13-arm-linux-gnueabihf [armhf] <cross>, gcc-13-powerpc64le-linux-gnu [ppc64el] <cross>, gcc-13-riscv64-linux-gnu [riscv64] <cross>, gcc-13-s390x-linux-gnu [s390x] <cross>, gcc-13-x86-64-linux-gnu [amd64] <cross>,
+ debhelper-compat (= 10),
+ cpio,
+ kmod <!stage1>,
+ makedumpfile [amd64] <!stage1>,
+ libcap-dev <!stage1>,
+ libelf-dev <!stage1>,
+ libnewt-dev <!stage1>,
+ libiberty-dev <!stage1>,
+ default-jdk-headless <!stage1>,
+ java-common <!stage1>,
+ rsync [!i386] <!stage1>,
+ libdw-dev <!stage1>,
+ libpci-dev <!stage1>,
+ pkg-config <!stage1>,
+ python3 <!stage1>,
+ python3-dev <!stage1>,
+ python3-setuptools <!stage1>,
+ flex <!stage1>,
+ bison <!stage1>,
+ libunwind8-dev [amd64 arm64 armhf ppc64el] <!stage1>,
+ liblzma-dev <!stage1>,
+ openssl <!stage1>,
+ libssl-dev <!stage1>,
+ libaudit-dev <!stage1>,
+ bc <!stage1>,
+ gawk <!stage1>,
+ libudev-dev <!stage1>,
+ autoconf <!stage1>,
+ automake <!stage1>,
+ libtool <!stage1>,
+ uuid-dev <!stage1>,
+ libnuma-dev [amd64 arm64 ppc64el s390x] <!stage1>,
+ libtraceevent-dev [amd64 arm64 armhf ppc64el s390x riscv64] <!stage1>,
+ libtracefs-dev [amd64 arm64 armhf ppc64el s390x riscv64] <!stage1>,
+ dkms <!stage1>,
+ dwarfdump <!stage1>,
+ curl <!stage1>,
+ zstd <!stage1>,
+ pahole [amd64 arm64 armhf ppc64el s390x riscv64] | dwarves (>= 1.21) [amd64 arm64 armhf ppc64el s390x riscv64] <!stage1>,
+ clang-18 [amd64 arm64 armhf ppc64el riscv64 s390x],
+ rustc [amd64 arm64 armhf ppc64el riscv64 s390x],
+ rust-src [amd64 arm64 armhf ppc64el riscv64 s390x],
+ rustfmt [amd64 arm64 armhf ppc64el riscv64 s390x],
+ bindgen-0.65 [amd64 arm64 armhf ppc64el riscv64 s390x],
+ libstdc++-dev,
+Build-Depends-Indep:
+ xmlto <!stage1>,
+ bzip2 <!stage1>,
+ sharutils <!stage1>,
+ asciidoc <!stage1>,
+ python3-docutils <!stage1>,
+Vcs-Git: git://git.launchpad.net/~canonical-kernel/ubuntu/+source/linux-qcom/+git/noble
+XS-Testsuite: autopkgtest
+#XS-Testsuite-Depends: gcc-4.7 binutils
+
+Package: linux-qcom-headers-6.8.0-1054
+Build-Profiles: <!stage1>
+Architecture: all
+Multi-Arch: foreign
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, coreutils
+Description: Header files related to Linux kernel version 6.8.0
+ This package provides kernel header files for version 6.8.0, for sites
+ that want the latest kernel headers. Please read
+ /usr/share/doc/linux-qcom-headers-6.8.0-1054/debian.README.gz for details
+
+Package: linux-qcom-tools-6.8.0-1054
+Build-Profiles: <!stage1>
+Architecture: arm64
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, ${shlibs:Depends}, linux-tools-common
+Description: Linux kernel version specific tools for version 6.8.0-1054
+ This package provides the architecture dependant parts for kernel
+ version locked tools (such as perf and x86_energy_perf_policy) for
+ version 6.8.0-1054 on
+ .
+ You probably want to install linux-tools-6.8.0-1054-<flavour>.
+
+Package: linux-libc-dev-qcom
+Architecture: all
+Depends: ${misc:Depends}
+Description: Linux Kernel Headers for development
+ This package provides additional downstream headers from the Linux kernel.
+ These headers are used by the installed headers for GNU glibc and other system
+ libraries. They are NOT meant to be used to build third-party modules for
+ your kernel. Use linux-qcom-headers-* packages for that.
+
+
+Package: linux-image-6.8.0-1054-qcom
+Build-Profiles: <!stage1>
+Architecture: arm64
+Section: kernel
+Priority: optional
+Provides: linux-image, fuse-module, kvm-api-4, redhat-cluster-modules, ivtv-modules, virtualbox-guest-modules [amd64], ${linux:rprovides}
+Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-6.8.0-1054-qcom
+Recommends: grub-pc [amd64] | grub-efi-amd64 [amd64] | grub-efi-ia32 [amd64] | grub [amd64] | lilo [amd64] | flash-kernel [armhf arm64] | grub-efi-arm64 [arm64] | grub-efi-arm [armhf] | grub-ieee1275 [ppc64el], initramfs-tools | linux-initramfs-tool
+Breaks: flash-kernel (<< 3.90ubuntu2) [arm64 armhf], s390-tools (<< 2.3.0-0ubuntu3) [s390x]
+Conflicts: linux-image-unsigned-6.8.0-1054-qcom
+Suggests: fdutils, linux-qcom-tools, linux-headers-6.8.0-1054-qcom
+Description: Linux kernel image for version 6.8.0 on  SMP
+ This package contains the Linux kernel image for version 6.8.0 on
+  SMP.
+ .
+ Supports Qualcomm SoC processors.
+ .
+ Geared toward desktop and server systems.
+ .
+ You likely do not want to install this package directly. Instead, install
+ the linux-qcom meta-package, which will ensure that upgrades work
+ correctly, and that supporting packages are also installed.
+
+Package: linux-modules-6.8.0-1054-qcom
+Build-Profiles: <!stage1>
+Architecture: arm64
+Section: kernel
+Priority: optional
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Built-Using: ${linux:BuiltUsing}
+Description: Linux kernel modules for version 6.8.0 on  SMP
+ Contains the corresponding System.map file, the modules built by the
+ packager, and scripts that try to ensure that the system is not left in an
+ unbootable state after an update.
+ .
+ Supports Qualcomm SoC processors.
+ .
+ Geared toward desktop and server systems.
+ .
+ You likely do not want to install this package directly. Instead, install
+ the linux-qcom meta-package, which will ensure that upgrades work
+ correctly, and that supporting packages are also installed.
+
+Package: linux-headers-6.8.0-1054-qcom
+Build-Profiles: <!stage1>
+Architecture: arm64
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, linux-qcom-headers-6.8.0-1054, ${shlibs:Depends}
+Provides: linux-headers, linux-headers-3.0
+Description: Linux kernel headers for version 6.8.0 on  SMP
+ This package provides kernel header files for version 6.8.0 on
+  SMP.
+ .
+ This is for sites that want the latest kernel headers.  Please read
+ /usr/share/doc/linux-headers-6.8.0-1054/debian.README.gz for details.
+
+Package: linux-qcom-lib-rust-6.8.0-1054-qcom
+Build-Profiles: <!stage1>
+Architecture: arm64
+Multi-Arch: foreign
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, coreutils
+Description: Rust library files related to Linux kernel version 6.8.0
+ This package provides kernel library files for version 6.8.0, that allow to
+ compile out-of-tree kernel modules written in Rust.
+
+Package: linux-image-6.8.0-1054-qcom-dbgsym
+Build-Profiles: <!stage1>
+Architecture: arm64
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}
+Provides: linux-debug
+Description: Linux kernel debug image for version 6.8.0 on  SMP
+ This package provides the kernel debug image for version 6.8.0 on
+  SMP.
+ .
+ This is for sites that wish to debug the kernel.
+ .
+ The kernel image contained in this package is NOT meant to boot from. It
+ is uncompressed, and unstripped. This package also includes the
+ unstripped modules.
+
+Package: linux-tools-6.8.0-1054-qcom
+Build-Profiles: <!stage1>
+Architecture: arm64
+Section: devel
+Priority: optional
+Depends: ${misc:Depends}, linux-qcom-tools-6.8.0-1054
+Description: Linux kernel version specific tools for version 6.8.0-1054
+ This package provides the architecture dependant parts for kernel
+ version locked tools (such as perf and x86_energy_perf_policy) for
+ version 6.8.0-1054 on
+ .
+
+
+Package: linux-buildinfo-6.8.0-1054-qcom
+Build-Profiles: <!stage1>
+Architecture: arm64
+Section: kernel
+Priority: optional
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Built-Using: ${linux:BuiltUsing}
+Description: Linux kernel buildinfo for version 6.8.0 on  SMP
+ This package contains the Linux kernel buildinfo for version 6.8.0 on
+  SMP.
+ .
+ You likely do not want to install this package.
+
+
+Package: linux-modules-iwlwifi-6.8.0-1054-qcom
+Build-Profiles: <!stage1>
+Architecture: arm64
+Section: kernel
+Priority: optional
+Depends:
+ ${misc:Depends},
+ linux-image-6.8.0-1054-qcom | linux-image-unsigned-6.8.0-1054-qcom,
+Built-Using: ${linux:BuiltUsing}
+Description: Linux kernel iwlwifi modules for version 6.8.0-1054
+ This package provides the Linux kernel iwlwifi modules for version
+ 6.8.0-1054.
+ .
+ You likely do not want to install this package directly. Instead, install the
+ one of the linux-modules-iwlwifi-qcom* meta-packages,
+ which will ensure that upgrades work correctly, and that supporting packages are
+ also installed.
+
--- linux-qcom-6.8.0.orig/debian/control.d/flavour-buildinfo.stub
+++ linux-qcom-6.8.0/debian/control.d/flavour-buildinfo.stub
@@ -0,0 +1,14 @@
+
+Package: linux-buildinfo-PKGVER-ABINUM-FLAVOUR
+Build-Profiles: <!stage1>
+Architecture: ARCH
+Section: kernel
+Priority: optional
+Depends: ${misc:Depends}, ${shlibs:Depends}
+Built-Using: ${linux:BuiltUsing}
+Description: Linux kernel buildinfo for version PKGVER on DESC
+ This package contains the Linux kernel buildinfo for version PKGVER on
+ DESC.
+ .
+ You likely do not want to install this package.
+
--- linux-qcom-6.8.0.orig/debian/control.d/flavour-module.stub
+++ linux-qcom-6.8.0/debian/control.d/flavour-module.stub
@@ -0,0 +1,19 @@
+
+Package: linux-modules-MODULE-PKGVER-ABINUM-FLAVOUR
+Build-Profiles: <!stage1>
+Architecture: ARCH
+Section: kernel
+Priority: optional
+Depends:
+ ${misc:Depends},
+ linux-image-PKGVER-ABINUM-FLAVOUR | linux-image-unsigned-PKGVER-ABINUM-FLAVOUR,
+Built-Using: ${linux:BuiltUsing}
+Description: Linux kernel MODULE modules for version PKGVER-ABINUM
+ This package provides the Linux kernel MODULE modules for version
+ PKGVER-ABINUM.
+ .
+ You likely do not want to install this package directly. Instead, install the
+ one of the linux-modules-MODULE-FLAVOUR* meta-packages,
+ which will ensure that upgrades work correctly, and that supporting packages are
+ also installed.
+
--- linux-qcom-6.8.0.orig/debian/control.d/linux-bpf-dev.stub
+++ linux-qcom-6.8.0/debian/control.d/linux-bpf-dev.stub
@@ -0,0 +1,7 @@
+Package: linux-bpf-dev
+Architecture: amd64 armhf arm64 i386 ppc64el riscv64 s390x
+Depends: ${misc:Depends}
+Multi-Arch: same
+Description: Headers for BPF development
+ The vmlinux.h header is provided to allow userspace to build BPF CO-RE
+ programs targeting the packaged kernel.
--- linux-qcom-6.8.0.orig/debian/control.d/linux-cloud-tools-common.stub
+++ linux-qcom-6.8.0/debian/control.d/linux-cloud-tools-common.stub
@@ -0,0 +1,10 @@
+Package: linux-cloud-tools-common
+Build-Profiles: <!stage1>
+Architecture: all
+Multi-Arch: foreign
+Section: kernel
+Priority: optional
+Depends: ${misc:Depends}
+Description: Linux kernel version specific cloud tools for version PKGVER
+ This package provides the architecture independent parts for kernel
+ version locked tools for cloud tools for version PKGVER.
--- linux-qcom-6.8.0.orig/debian/control.d/linux-doc.stub
+++ linux-qcom-6.8.0/debian/control.d/linux-doc.stub
@@ -0,0 +1,8 @@
+Package: linux-doc
+Build-Profiles: <!stage1>
+Architecture: all
+Section: doc
+Priority: optional
+Description: Linux kernel specific documentation for version PKGVER
+ This package is deprecated and it is temporarily provided only for
+ compatibility reasons. It will be dropped in the future.
--- linux-qcom-6.8.0.orig/debian/control.d/linux-libc-dev.stub
+++ linux-qcom-6.8.0/debian/control.d/linux-libc-dev.stub
@@ -0,0 +1,12 @@
+Package: linux-libc-dev
+Architecture: amd64 armhf arm64 i386 ppc64el riscv64 s390x
+Depends: ${misc:Depends}
+Conflicts: linux-kernel-headers
+Replaces: linux-kernel-headers
+Provides: linux-kernel-headers, aufs-dev
+Multi-Arch: same
+Description: Linux Kernel Headers for development
+ This package provides headers from the Linux kernel.  These headers
+ are used by the installed headers for GNU glibc and other system
+ libraries. They are NOT meant to be used to build third-party modules for
+ your kernel. Use SRCPKGNAME-headers-* packages for that.
--- linux-qcom-6.8.0.orig/debian/control.d/linux-source.stub
+++ linux-qcom-6.8.0/debian/control.d/linux-source.stub
@@ -0,0 +1,23 @@
+Package: linux-source-PKGVER
+Build-Profiles: <!stage1>
+Architecture: all
+Section: devel
+Priority: optional
+Provides: linux-source
+Depends: ${misc:Depends}, binutils, bzip2, coreutils
+Recommends: libc-dev, gcc, make
+Suggests: libncurses-dev | ncurses-dev, kernel-package, libqt3-dev
+Description: Linux kernel source for version PKGVER with Ubuntu patches
+ This package provides the source code for the Linux kernel version
+ PKGVER.
+ .
+ This package is mainly meant for other packages to use, in order to build
+ custom flavours.
+ .
+ If you wish to use this package to create a custom Linux kernel, then it
+ is suggested that you investigate the package kernel-package, which has
+ been designed to ease the task of creating kernel image packages.
+ .
+ If you are simply trying to build third-party modules for your kernel,
+ you do not want this package. Install the appropriate linux-headers
+ package instead.
--- linux-qcom-6.8.0.orig/debian/control.d/linux-tools-common.stub
+++ linux-qcom-6.8.0/debian/control.d/linux-tools-common.stub
@@ -0,0 +1,12 @@
+Package: linux-tools-common
+Build-Profiles: <!stage1>
+Architecture: all
+Multi-Arch: foreign
+Section: kernel
+Priority: optional
+Provides: bpftool
+Depends: ${misc:Depends}, lsb-release, hwdata
+Description: Linux kernel version specific tools for version PKGVER
+ This package provides the architecture independent parts for kernel
+ version locked tools (such as perf and x86_energy_perf_policy) for
+ version PKGVER.
--- linux-qcom-6.8.0.orig/debian/control.d/linux-tools-host.stub
+++ linux-qcom-6.8.0/debian/control.d/linux-tools-host.stub
@@ -0,0 +1,9 @@
+Package: linux-tools-host
+Build-Profiles: <!stage1>
+Architecture: all
+Multi-Arch: foreign
+Section: kernel
+Priority: optional
+Depends: ${misc:Depends}, python3
+Description: Linux kernel VM host tools
+ This package provides kernel tools useful for VM hosts.
--- linux-qcom-6.8.0.orig/debian/copyright
+++ linux-qcom-6.8.0/debian/copyright
@@ -0,0 +1,29 @@
+This is the Ubuntu prepackaged version of the Linux kernel.
+Linux was written by Linus Torvalds <Linus.Torvalds@cs.Helsinki.FI>
+and others.
+
+This package was put together by the Ubuntu Kernel Team, from
+sources retrieved from upstream linux git.
+The sources may be found at most Linux ftp sites, including 
+ftp://ftp.kernel.org/pub/linux/kernel/
+
+This package is currently maintained by the
+Ubuntu Kernel Team <ubuntu-kernel@lists.ubuntu.com>
+
+Linux is copyrighted by Linus Torvalds and others.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 dated June, 1991.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+On Ubuntu Linux systems, the complete text of the GNU General
+Public License v2 can be found in `/usr/share/common-licenses/GPL-2'.
--- linux-qcom-6.8.0.orig/debian/debian.env
+++ linux-qcom-6.8.0/debian/debian.env
@@ -0,0 +1 @@
+DEBIAN=debian.qcom
--- linux-qcom-6.8.0.orig/debian/gbp.conf
+++ linux-qcom-6.8.0/debian/gbp.conf
@@ -0,0 +1,2 @@
+[buildpackage]
+debian-tag = Ubuntu-%(version)s
--- linux-qcom-6.8.0.orig/debian/linux-cloud-tools-common.hv-fcopy-daemon.service
+++ linux-qcom-6.8.0/debian/linux-cloud-tools-common.hv-fcopy-daemon.service
@@ -0,0 +1,14 @@
+# On Azure/Hyper-V systems start the hv_fcopy_daemon
+#
+# author "Andy Whitcroft <apw@canonical.com>"
+[Unit]
+Description=Hyper-V File Copy Protocol Daemon
+ConditionVirtualization=microsoft
+ConditionPathExists=/dev/vmbus/hv_fcopy
+BindsTo=sys-devices-virtual-misc-vmbus\x21hv_fcopy.device
+
+[Service]
+ExecStart=/usr/sbin/hv_fcopy_daemon -n
+
+[Install]
+WantedBy=multi-user.target
--- linux-qcom-6.8.0.orig/debian/linux-cloud-tools-common.hv-fcopy-daemon.udev
+++ linux-qcom-6.8.0/debian/linux-cloud-tools-common.hv-fcopy-daemon.udev
@@ -0,0 +1 @@
+SUBSYSTEM=="misc", KERNEL=="vmbus/hv_fcopy", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hv-fcopy-daemon.service"
--- linux-qcom-6.8.0.orig/debian/linux-cloud-tools-common.hv-fcopy-daemon.upstart
+++ linux-qcom-6.8.0/debian/linux-cloud-tools-common.hv-fcopy-daemon.upstart
@@ -0,0 +1,22 @@
+# On Azure/Hyper-V systems start the hv_fcopy_daemon
+#
+description "Hyper-V File Copy Protocol Daemon"
+author "Andy Whitcroft <apw@canonical.com>"
+
+start on runlevel [2345]
+stop on runlevel [!2345]
+console log
+
+pre-start script
+        if [ -e "/etc/default/hv-kvp-daemon-init" ]; then
+                . /etc/default/hv-kvp-daemon-init
+        fi
+        [ "$RUN_FCOPY_DAEMON" -eq 0 ] && { stop; exit 0; }
+	if [ -d /sys/class/dmi/id/. ]; then
+		read company </sys/class/dmi/id/sys_vendor
+		read product </sys/class/dmi/id/product_name
+		[ "$company:$product" = 'Microsoft Corporation:Virtual Machine' ] || { stop; exit 0; }
+	fi
+end script
+
+exec /usr/sbin/hv_fcopy_daemon -n
--- linux-qcom-6.8.0.orig/debian/linux-cloud-tools-common.hv-kvp-daemon.service
+++ linux-qcom-6.8.0/debian/linux-cloud-tools-common.hv-kvp-daemon.service
@@ -0,0 +1,20 @@
+# On Azure/Hyper-V systems start the hv_kvp_daemon
+#
+# author "Andy Whitcroft <apw@canonical.com>"
+[Unit]
+Description=Hyper-V KVP Protocol Daemon
+ConditionVirtualization=microsoft
+ConditionKernelCommandLine=!snapd_recovery_mode
+DefaultDependencies=no
+BindsTo=sys-devices-virtual-misc-vmbus\x21hv_kvp.device
+After=sys-devices-virtual-misc-vmbus\x21hv_kvp.device systemd-remount-fs.service
+Before=shutdown.target cloud-init-local.service walinuxagent.service
+Conflicts=shutdown.target
+RequiresMountsFor=/var/lib/hyperv
+ConditionPathExists=/dev/vmbus/hv_kvp
+
+[Service]
+ExecStart=/usr/sbin/hv_kvp_daemon -n
+
+[Install]
+WantedBy=multi-user.target
--- linux-qcom-6.8.0.orig/debian/linux-cloud-tools-common.hv-kvp-daemon.udev
+++ linux-qcom-6.8.0/debian/linux-cloud-tools-common.hv-kvp-daemon.udev
@@ -0,0 +1 @@
+SUBSYSTEM=="misc", KERNEL=="vmbus/hv_kvp", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hv-kvp-daemon.service"
--- linux-qcom-6.8.0.orig/debian/linux-cloud-tools-common.hv-kvp-daemon.upstart
+++ linux-qcom-6.8.0/debian/linux-cloud-tools-common.hv-kvp-daemon.upstart
@@ -0,0 +1,22 @@
+# On Azure/Hyper-V systems start the hv_kvp_daemon
+#
+description "Hyper-V KVP Protocol Daemon"
+author "Adam Conrad <adconrad@canonical.com>"
+
+start on runlevel [2345]
+stop on runlevel [!2345]
+console log
+
+pre-start script
+        if [ -e "/etc/default/hv-kvp-daemon-init" ]; then
+                . /etc/default/hv-kvp-daemon-init
+        fi
+        [ "$RUN_KVP_DAEMON" = 0 ] && { stop; exit 0; }
+	if [ -d /sys/class/dmi/id/. ]; then
+		read company </sys/class/dmi/id/sys_vendor
+		read product </sys/class/dmi/id/product_name
+		[ "$company:$product" = 'Microsoft Corporation:Virtual Machine' ] || { stop; exit 0; }
+	fi
+end script
+
+exec /usr/sbin/hv_kvp_daemon -n
--- linux-qcom-6.8.0.orig/debian/linux-cloud-tools-common.hv-vss-daemon.service
+++ linux-qcom-6.8.0/debian/linux-cloud-tools-common.hv-vss-daemon.service
@@ -0,0 +1,14 @@
+# On Azure/Hyper-V systems start the hv_vss_daemon
+#
+# author "Andy Whitcroft <apw@canonical.com>"
+[Unit]
+Description=Hyper-V VSS Protocol Daemon
+ConditionVirtualization=microsoft
+ConditionPathExists=/dev/vmbus/hv_vss
+BindsTo=sys-devices-virtual-misc-vmbus\x21hv_vss.device
+
+[Service]
+ExecStart=/usr/sbin/hv_vss_daemon -n
+
+[Install]
+WantedBy=multi-user.target
--- linux-qcom-6.8.0.orig/debian/linux-cloud-tools-common.hv-vss-daemon.udev
+++ linux-qcom-6.8.0/debian/linux-cloud-tools-common.hv-vss-daemon.udev
@@ -0,0 +1 @@
+SUBSYSTEM=="misc", KERNEL=="vmbus/hv_vss", TAG+="systemd", ENV{SYSTEMD_WANTS}+="hv-vss-daemon.service"
--- linux-qcom-6.8.0.orig/debian/linux-cloud-tools-common.hv-vss-daemon.upstart
+++ linux-qcom-6.8.0/debian/linux-cloud-tools-common.hv-vss-daemon.upstart
@@ -0,0 +1,22 @@
+# On Azure/Hyper-V systems start the hv_vss_daemon
+#
+description "Hyper-V VSS Protocol Daemon"
+author "Ben Howard <ben.howard@canonical.com>"
+
+start on runlevel [2345]
+stop on runlevel [!2345]
+console log
+
+pre-start script
+        if [ -e "/etc/default/hv-kvp-daemon-init" ]; then
+                . /etc/default/hv-kvp-daemon-init
+        fi
+        [ "$RUN_VSS_DAEMON" -eq 0 ] && { stop; exit 0; }
+	if [ -d /sys/class/dmi/id/. ]; then
+		read company </sys/class/dmi/id/sys_vendor
+		read product </sys/class/dmi/id/product_name
+		[ "$company:$product" = 'Microsoft Corporation:Virtual Machine' ] || { stop; exit 0; }
+	fi
+end script
+
+exec /usr/sbin/hv_vss_daemon -n
--- linux-qcom-6.8.0.orig/debian/linux-cloud-tools-common.intel-sgx-load-module.service
+++ linux-qcom-6.8.0/debian/linux-cloud-tools-common.intel-sgx-load-module.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Install SGX kernel module
+DefaultDependencies=false
+ConditionVirtualization=microsoft
+
+[Service]
+Type=oneshot
+RemainAfterExit=true
+ExecStart=/sbin/modprobe intel_sgx
+ExecStop=/sbin/modprobe -r intel_sgx
+
+[Install]
+WantedBy=multi-user.target
--- linux-qcom-6.8.0.orig/debian/revoked-certs/canonical-uefi-2012-all.pem
+++ linux-qcom-6.8.0/debian/revoked-certs/canonical-uefi-2012-all.pem
@@ -0,0 +1,86 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Apr 12 11:39:08 2012 GMT
+            Not After : Apr 11 11:39:08 2042 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:c9:5f:9b:62:8f:0b:b0:64:82:ac:be:c9:e2:62:
+                    e3:4b:d2:9f:1e:8a:d5:61:1a:2b:5d:38:f4:b7:ce:
+                    b9:9a:b8:43:b8:43:97:77:ab:4f:7f:0c:70:46:0b:
+                    fc:7f:6d:c6:6d:ea:80:5e:01:d2:b7:66:1e:87:de:
+                    0d:6d:d0:41:97:a8:a5:af:0c:63:4f:f7:7c:c2:52:
+                    cc:a0:31:a9:bb:89:5d:99:1e:46:6f:55:73:b9:76:
+                    69:ec:d7:c1:fc:21:d6:c6:07:e7:4f:bd:22:de:e4:
+                    a8:5b:2d:db:95:34:19:97:d6:28:4b:21:4c:ca:bb:
+                    1d:79:a6:17:7f:5a:f9:67:e6:5c:78:45:3d:10:6d:
+                    b0:17:59:26:11:c5:57:e3:7f:4e:82:ba:f6:2c:4e:
+                    c8:37:4d:ff:85:15:84:47:e0:ed:3b:7c:7f:bc:af:
+                    e9:01:05:a7:0c:6f:c3:e9:8d:a3:ce:be:a6:e3:cd:
+                    3c:b5:58:2c:9e:c2:03:1c:60:22:37:39:ff:41:02:
+                    c1:29:a4:65:51:ff:33:34:aa:42:15:f9:95:78:fc:
+                    2d:f5:da:8a:85:7c:82:9d:fb:37:2c:6b:a5:a8:df:
+                    7c:55:0b:80:2e:3c:b0:63:e1:cd:38:48:89:e8:14:
+                    06:0b:82:bc:fd:d4:07:68:1b:0f:3e:d9:15:dd:94:
+                    11:1b
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                61:48:2A:A2:83:0D:0A:B2:AD:5A:F1:0B:72:50:DA:90:33:DD:CE:F0
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        8f:8a:a1:06:1f:29:b7:0a:4a:d5:c5:fd:81:ab:25:ea:c0:7d:
+        e2:fc:6a:96:a0:79:93:67:ee:05:0e:25:12:25:e4:5a:f6:aa:
+        1a:f1:12:f3:05:8d:87:5e:f1:5a:5c:cb:8d:23:73:65:1d:15:
+        b9:de:22:6b:d6:49:67:c9:a3:c6:d7:62:4e:5c:b5:f9:03:83:
+        40:81:dc:87:9c:3c:3f:1c:0d:51:9f:94:65:0a:84:48:67:e4:
+        a2:f8:a6:4a:f0:e7:cd:cd:bd:94:e3:09:d2:5d:2d:16:1b:05:
+        15:0b:cb:44:b4:3e:61:42:22:c4:2a:5c:4e:c5:1d:a3:e2:e0:
+        52:b2:eb:f4:8b:2b:dc:38:39:5d:fb:88:a1:56:65:5f:2b:4f:
+        26:ff:06:78:10:12:eb:8c:5d:32:e3:c6:45:af:25:9b:a0:ff:
+        8e:ef:47:09:a3:e9:8b:37:92:92:69:76:7e:34:3b:92:05:67:
+        4e:b0:25:ed:bc:5e:5f:8f:b4:d6:ca:40:ff:e4:e2:31:23:0c:
+        85:25:ae:0c:55:01:ec:e5:47:5e:df:5b:bc:14:33:e3:c6:f5:
+        18:b6:d9:f7:dd:b3:b4:a1:31:d3:5a:5c:5d:7d:3e:bf:0a:e4:
+        e4:e8:b4:59:7d:3b:b4:8c:a3:1b:b5:20:a3:b9:3e:84:6f:8c:
+        21:00:c3:39
+-----BEGIN CERTIFICATE-----
+MIIEIDCCAwigAwIBAgIBATANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xMjA0MTIxMTM5MDhaFw00MjA0MTEx
+MTM5MDhaMH8xCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEXMBUG
+A1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MSswKQYD
+VQQDDCJDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nMIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyV+bYo8LsGSCrL7J4mLjS9KfHorVYRor
+XTj0t865mrhDuEOXd6tPfwxwRgv8f23GbeqAXgHSt2Yeh94NbdBBl6ilrwxjT/d8
+wlLMoDGpu4ldmR5Gb1VzuXZp7NfB/CHWxgfnT70i3uSoWy3blTQZl9YoSyFMyrsd
+eaYXf1r5Z+ZceEU9EG2wF1kmEcVX439Ogrr2LE7IN03/hRWER+DtO3x/vK/pAQWn
+DG/D6Y2jzr6m4808tVgsnsIDHGAiNzn/QQLBKaRlUf8zNKpCFfmVePwt9dqKhXyC
+nfs3LGulqN98VQuALjywY+HNOEiJ6BQGC4K8/dQHaBsPPtkV3ZQRGwIDAQABo4Gg
+MIGdMAwGA1UdEwEB/wQCMAAwHwYDVR0lBBgwFgYIKwYBBQUHAwMGCisGAQQBgjcK
+AwYwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRl
+MB0GA1UdDgQWBBRhSCqigw0Ksq1a8QtyUNqQM93O8DAfBgNVHSMEGDAWgBStkZkL
+wiqx9RcEjCO2ZVomjjRaYzANBgkqhkiG9w0BAQsFAAOCAQEAj4qhBh8ptwpK1cX9
+gasl6sB94vxqlqB5k2fuBQ4lEiXkWvaqGvES8wWNh17xWlzLjSNzZR0Vud4ia9ZJ
+Z8mjxtdiTly1+QODQIHch5w8PxwNUZ+UZQqESGfkovimSvDnzc29lOMJ0l0tFhsF
+FQvLRLQ+YUIixCpcTsUdo+LgUrLr9Isr3Dg5XfuIoVZlXytPJv8GeBAS64xdMuPG
+Ra8lm6D/ju9HCaPpizeSkml2fjQ7kgVnTrAl7bxeX4+01spA/+TiMSMMhSWuDFUB
+7OVHXt9bvBQz48b1GLbZ992ztKEx01pcXX0+vwrk5Oi0WX07tIyjG7Ugo7k+hG+M
+IQDDOQ==
+-----END CERTIFICATE-----
--- linux-qcom-6.8.0.orig/debian/revoked-certs/canonical-uefi-2017-all.pem
+++ linux-qcom-6.8.0/debian/revoked-certs/canonical-uefi-2017-all.pem
@@ -0,0 +1,86 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 2 (0x2)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Sep 26 21:52:11 2017 GMT
+            Not After : Sep 25 21:52:11 2047 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2017)
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:ef:9f:fa:9f:19:3a:9d:38:23:91:cc:c4:f9:42:
+                    e0:f8:54:12:82:dc:97:2c:d6:5b:c1:35:eb:ff:4a:
+                    74:06:b5:9d:32:aa:7b:f3:fc:31:5a:34:3e:a1:a4:
+                    44:db:7b:6d:16:af:35:76:e0:9b:99:ad:21:11:c6:
+                    12:4b:ae:24:8f:bb:d3:b2:00:fe:c5:1d:9b:3a:1a:
+                    4a:6c:ca:fa:16:37:85:22:f9:ff:22:fc:40:e0:58:
+                    35:c1:39:27:b4:c6:42:1a:96:d8:a5:c5:95:2e:f7:
+                    c5:1e:21:6e:36:84:f7:a9:a1:e1:f1:03:08:96:65:
+                    71:f8:eb:83:cf:82:f7:9a:44:58:72:00:14:39:29:
+                    4b:e9:78:2f:65:20:b3:80:76:3b:ba:0d:2d:46:f6:
+                    37:05:e7:05:fe:bd:6c:c7:a2:65:b5:06:6e:07:24:
+                    99:a1:c1:cf:e1:0e:5e:49:41:71:17:a8:50:e7:38:
+                    99:e5:6e:b6:db:9f:63:db:56:f4:9c:7d:89:f6:d2:
+                    03:6c:99:83:e0:99:23:39:36:bd:cb:b5:26:7c:7d:
+                    b0:c6:fe:82:7c:52:ed:f9:2c:8f:79:71:3d:a9:2f:
+                    b5:aa:7e:77:a0:fd:69:f9:97:10:a8:b2:c6:7d:88:
+                    9e:a2:19:bd:31:b8:02:2d:34:4d:9d:98:60:82:ad:
+                    04:ff
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                24:2A:DE:75:AC:4A:15:E5:0D:50:C8:4B:0D:45:FF:3E:AE:70:7A:03
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        00:b2:b7:57:b5:2b:5d:16:d3:04:88:6a:d7:77:d5:0d:89:f1:
+        d2:6e:11:d1:8e:f5:62:05:c4:6a:57:df:eb:d2:86:68:f2:fd:
+        a7:37:11:3c:f4:ce:5d:fe:32:5f:31:a2:6b:3a:da:28:c2:88:
+        fa:7f:70:b5:25:99:ea:27:9a:56:6a:9d:b2:0f:14:99:e2:b7:
+        c6:39:1e:8e:a7:76:31:d9:ed:c5:05:8d:48:ae:1b:68:18:14:
+        51:a1:7d:f6:c7:df:cb:9d:eb:a4:3b:0b:ff:c2:07:c5:42:bc:
+        0d:b2:11:fa:37:17:2b:1c:b5:84:48:2d:f9:31:4a:57:49:8e:
+        61:a6:82:11:06:4c:34:ea:9c:2a:47:4d:eb:e0:26:af:da:d2:
+        c2:08:a0:37:35:7b:73:71:de:0b:c4:ba:c8:34:de:20:04:03:
+        6f:46:26:0d:b9:91:02:5b:71:76:cc:45:e4:08:d0:a6:dd:a4:
+        50:d3:d9:04:91:2b:d9:5c:34:88:fc:c2:37:fd:c6:d4:3e:57:
+        f7:6b:ba:7b:d7:02:7a:84:0c:c8:c1:19:cc:bc:fa:52:d5:7f:
+        b3:35:c4:53:5d:70:0a:f6:44:60:8d:a9:11:7a:1b:7d:ae:7b:
+        20:5a:4c:8d:44:f6:c1:a9:61:cb:dc:cb:90:37:d5:28:24:73:
+        87:d0:e0:d8
+-----BEGIN CERTIFICATE-----
+MIIEKDCCAxCgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNzA5MjYyMTUyMTFaFw00NzA5MjUy
+MTUyMTFaMIGGMQswCQYDVQQGEwJHQjEUMBIGA1UECAwLSXNsZSBvZiBNYW4xFzAV
+BgNVBAoMDkNhbm9uaWNhbCBMdGQuMRQwEgYDVQQLDAtTZWN1cmUgQm9vdDEyMDAG
+A1UEAwwpQ2Fub25pY2FsIEx0ZC4gU2VjdXJlIEJvb3QgU2lnbmluZyAoMjAxNykw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvn/qfGTqdOCORzMT5QuD4
+VBKC3Jcs1lvBNev/SnQGtZ0yqnvz/DFaND6hpETbe20WrzV24JuZrSERxhJLriSP
+u9OyAP7FHZs6GkpsyvoWN4Ui+f8i/EDgWDXBOSe0xkIaltilxZUu98UeIW42hPep
+oeHxAwiWZXH464PPgveaRFhyABQ5KUvpeC9lILOAdju6DS1G9jcF5wX+vWzHomW1
+Bm4HJJmhwc/hDl5JQXEXqFDnOJnlbrbbn2PbVvScfYn20gNsmYPgmSM5Nr3LtSZ8
+fbDG/oJ8Uu35LI95cT2pL7Wqfneg/Wn5lxCossZ9iJ6iGb0xuAItNE2dmGCCrQT/
+AgMBAAGjgaAwgZ0wDAYDVR0TAQH/BAIwADAfBgNVHSUEGDAWBggrBgEFBQcDAwYK
+KwYBBAGCNwoDBjAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
+dGlmaWNhdGUwHQYDVR0OBBYEFCQq3nWsShXlDVDISw1F/z6ucHoDMB8GA1UdIwQY
+MBaAFK2RmQvCKrH1FwSMI7ZlWiaONFpjMA0GCSqGSIb3DQEBCwUAA4IBAQAAsrdX
+tStdFtMEiGrXd9UNifHSbhHRjvViBcRqV9/r0oZo8v2nNxE89M5d/jJfMaJrOtoo
+woj6f3C1JZnqJ5pWap2yDxSZ4rfGOR6Op3Yx2e3FBY1IrhtoGBRRoX32x9/Lneuk
+Owv/wgfFQrwNshH6NxcrHLWESC35MUpXSY5hpoIRBkw06pwqR03r4Cav2tLCCKA3
+NXtzcd4LxLrINN4gBANvRiYNuZECW3F2zEXkCNCm3aRQ09kEkSvZXDSI/MI3/cbU
+Plf3a7p71wJ6hAzIwRnMvPpS1X+zNcRTXXAK9kRgjakReht9rnsgWkyNRPbBqWHL
+3MuQN9UoJHOH0ODY
+-----END CERTIFICATE-----
--- linux-qcom-6.8.0.orig/debian/revoked-certs/canonical-uefi-2018-all.pem
+++ linux-qcom-6.8.0/debian/revoked-certs/canonical-uefi-2018-all.pem
@@ -0,0 +1,86 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 3 (0x3)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Oct 26 18:31:14 2018 GMT
+            Not After : Oct 24 18:31:14 2048 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (ESM 2018)
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:bf:6a:e5:6d:55:7a:ec:7a:11:37:45:9c:4c:8f:
+                    6b:2d:56:d3:74:2b:32:ac:84:2d:ba:cb:cc:ec:8d:
+                    92:22:69:48:a5:d4:f6:75:11:66:2f:cb:b2:fd:9e:
+                    56:ab:e6:f1:52:8e:75:3e:50:bd:25:b3:50:fc:ef:
+                    3d:76:f3:3f:7f:03:f6:e2:a1:25:69:5c:14:98:54:
+                    bd:11:bf:e9:a5:ac:46:91:4b:1d:de:b7:18:2b:c8:
+                    22:83:15:a7:4a:00:8d:9d:e4:c0:da:f7:41:02:fd:
+                    9f:5f:79:93:56:cc:86:e1:b5:e0:39:0e:3c:a2:5b:
+                    fe:c0:56:f0:92:50:5a:2b:67:67:93:56:d7:7a:75:
+                    99:6a:25:b4:63:a8:5f:69:7e:3a:49:58:2a:a7:80:
+                    f6:5a:b4:be:b2:be:a8:8c:45:41:c9:f2:fc:76:a8:
+                    65:ef:99:29:0d:c9:9c:54:6b:0a:f0:4a:0e:61:0d:
+                    ed:99:32:af:12:e2:12:7b:9f:7b:ec:05:c4:e0:b6:
+                    d5:c3:71:28:ae:dd:0b:ba:97:ad:68:0b:76:e9:bf:
+                    e7:01:7e:64:54:39:23:85:36:c8:9d:dd:27:a1:ff:
+                    df:46:36:14:7e:cb:cc:a1:cd:49:0b:6d:c2:0c:45:
+                    99:56:58:7c:87:0d:59:9a:dc:4a:39:3b:1d:d9:15:
+                    2e:b5
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                36:51:88:C1:D3:74:D6:B0:7C:3C:8F:24:0F:8E:F7:22:43:3D:6A:8B
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        4c:0f:cd:77:60:b4:6f:53:87:f3:3c:4f:e6:81:5f:a7:1c:cc:
+        60:29:b6:34:6c:4d:08:9b:e2:d2:bd:f6:17:1a:62:79:b8:17:
+        bc:a2:60:59:fd:03:51:c3:b7:6b:de:73:b3:48:95:f5:0b:aa:
+        b6:3c:b4:34:dc:1d:0b:c4:97:62:87:e7:48:d5:8f:c9:ea:e8:
+        91:8f:2a:40:cd:b7:b3:ee:b2:98:9e:fb:37:31:29:e6:8e:2f:
+        0a:39:99:1e:c6:aa:b8:05:62:85:d3:a8:3e:60:38:98:0f:f0:
+        fe:c7:ab:01:a5:6a:a5:7f:70:a6:26:94:76:23:2f:08:89:74:
+        97:c2:2a:ca:22:3e:7a:ea:22:22:08:07:f4:bb:f6:bc:69:9c:
+        4e:44:33:e2:8e:70:17:b0:9b:cb:33:94:66:6d:ff:9a:7d:e9:
+        50:b2:e8:90:14:e4:2b:91:cb:a0:c5:2e:0e:cf:19:ef:44:ef:
+        84:f0:bd:57:9e:26:c2:63:3d:df:fc:a1:84:de:5c:d7:5f:3b:
+        fb:94:61:f0:93:89:1f:cf:c3:b2:d1:90:97:35:7d:b9:8a:ad:
+        e6:05:f0:e8:3b:a1:7c:af:2b:c4:af:18:33:2e:5e:87:db:9d:
+        80:b5:04:fd:00:d0:60:ab:ff:85:77:0f:cb:47:22:c9:b2:85:
+        a8:48:16:e2
+-----BEGIN CERTIFICATE-----
+MIIELDCCAxSgAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xODEwMjYxODMxMTRaFw00ODEwMjQx
+ODMxMTRaMIGKMQswCQYDVQQGEwJHQjEUMBIGA1UECAwLSXNsZSBvZiBNYW4xFzAV
+BgNVBAoMDkNhbm9uaWNhbCBMdGQuMRQwEgYDVQQLDAtTZWN1cmUgQm9vdDE2MDQG
+A1UEAwwtQ2Fub25pY2FsIEx0ZC4gU2VjdXJlIEJvb3QgU2lnbmluZyAoRVNNIDIw
+MTgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2rlbVV67HoRN0Wc
+TI9rLVbTdCsyrIQtusvM7I2SImlIpdT2dRFmL8uy/Z5Wq+bxUo51PlC9JbNQ/O89
+dvM/fwP24qElaVwUmFS9Eb/ppaxGkUsd3rcYK8gigxWnSgCNneTA2vdBAv2fX3mT
+VsyG4bXgOQ48olv+wFbwklBaK2dnk1bXenWZaiW0Y6hfaX46SVgqp4D2WrS+sr6o
+jEVByfL8dqhl75kpDcmcVGsK8EoOYQ3tmTKvEuISe5977AXE4LbVw3Eort0Lupet
+aAt26b/nAX5kVDkjhTbInd0nof/fRjYUfsvMoc1JC23CDEWZVlh8hw1ZmtxKOTsd
+2RUutQIDAQABo4GgMIGdMAwGA1UdEwEB/wQCMAAwHwYDVR0lBBgwFgYIKwYBBQUH
+AwMGCisGAQQBgjcKAwYwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVk
+IENlcnRpZmljYXRlMB0GA1UdDgQWBBQ2UYjB03TWsHw8jyQPjvciQz1qizAfBgNV
+HSMEGDAWgBStkZkLwiqx9RcEjCO2ZVomjjRaYzANBgkqhkiG9w0BAQsFAAOCAQEA
+TA/Nd2C0b1OH8zxP5oFfpxzMYCm2NGxNCJvi0r32FxpiebgXvKJgWf0DUcO3a95z
+s0iV9Quqtjy0NNwdC8SXYofnSNWPyerokY8qQM23s+6ymJ77NzEp5o4vCjmZHsaq
+uAVihdOoPmA4mA/w/serAaVqpX9wpiaUdiMvCIl0l8IqyiI+euoiIggH9Lv2vGmc
+TkQz4o5wF7CbyzOUZm3/mn3pULLokBTkK5HLoMUuDs8Z70TvhPC9V54mwmM93/yh
+hN5c1187+5Rh8JOJH8/DstGQlzV9uYqt5gXw6DuhfK8rxK8YMy5eh9udgLUE/QDQ
+YKv/hXcPy0ciybKFqEgW4g==
+-----END CERTIFICATE-----
--- linux-qcom-6.8.0.orig/debian/revoked-certs/canonical-uefi-2019-all.pem
+++ linux-qcom-6.8.0/debian/revoked-certs/canonical-uefi-2019-all.pem
@@ -0,0 +1,86 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 4 (0x4)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Sep 18 16:10:17 2019 GMT
+            Not After : Sep 16 16:10:17 2049 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2019)
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:e6:47:d8:75:e5:87:59:26:87:83:7d:5b:7a:b8:
+                    58:3d:7c:ef:36:f8:a0:7a:b7:14:56:58:7d:01:f1:
+                    1c:3b:8c:e6:5b:03:77:7d:a0:ed:47:0a:45:e6:75:
+                    5c:de:95:38:0d:38:fa:41:79:89:56:31:87:e7:a3:
+                    9a:36:70:b6:cf:24:2f:99:26:89:08:39:0e:14:c3:
+                    35:be:02:8b:52:e1:8e:7b:0c:a6:9d:78:ff:01:60:
+                    d7:f5:c3:d5:f0:5e:dc:e4:23:09:59:72:93:d3:b5:
+                    22:af:7c:cd:e0:84:0f:af:11:2d:bc:c6:72:42:af:
+                    ea:67:63:c4:10:41:78:02:80:62:0d:43:74:b4:1c:
+                    ed:50:d7:94:f1:b0:bb:f9:57:80:e4:69:0f:83:4b:
+                    a2:e6:2c:4a:9a:e1:7d:7c:62:19:29:27:97:1f:4c:
+                    f1:85:f0:39:f5:31:9f:3a:39:0e:d4:4d:07:3a:40:
+                    55:4b:a6:6c:9d:04:89:51:2d:7c:b0:ef:40:b5:42:
+                    29:16:cc:65:73:38:62:21:f6:e3:2c:17:50:9d:74:
+                    34:4e:df:7c:4a:33:a4:bb:40:cf:d5:e5:ed:05:07:
+                    cd:4c:f9:af:7f:a6:5c:b9:f7:c5:16:45:4e:44:40:
+                    d7:85:32:de:ac:e5:75:ad:9b:d7:c0:26:33:1f:77:
+                    a5:37
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                C0:74:6F:D6:C5:DA:3A:E8:27:86:46:51:AD:66:AE:47:FE:24:B3:E8
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        aa:12:6c:d1:9d:6a:da:f0:ec:7c:17:46:3b:57:b8:d6:76:5f:
+        24:e6:06:a2:0a:55:1f:2f:d3:5e:8f:de:cf:02:f2:ff:e0:dd:
+        d3:c7:bd:75:59:aa:cd:34:f3:28:80:73:cc:28:69:e7:a2:70:
+        88:a2:c7:dc:66:f0:92:0e:ff:64:bf:30:04:54:01:1b:96:ad:
+        15:c5:61:fd:32:61:d7:5e:b5:ba:91:fd:31:fc:6b:15:df:ee:
+        22:d9:e4:1f:f3:cc:8b:0c:9f:f5:e8:f7:e2:62:3f:40:52:c9:
+        f0:f1:1c:63:fc:6c:90:e1:5b:74:03:b9:df:d1:3e:a8:ec:db:
+        2b:6e:83:6f:9f:7f:ba:b4:79:fc:3d:e7:12:2f:4a:e7:17:8c:
+        2b:77:a5:90:74:3c:bd:cf:75:83:0d:1a:95:d5:56:ef:07:9b:
+        a6:b3:31:e3:8c:97:ce:68:11:b5:7b:25:03:72:1c:ea:67:e9:
+        7c:3e:73:c7:7c:3e:fc:f5:ae:8a:b2:07:0d:15:6a:66:09:d7:
+        23:b9:5d:80:7a:26:d6:b6:22:30:aa:84:af:c0:42:e9:75:c3:
+        59:ab:a3:84:87:6b:0c:b7:ab:4e:92:69:ae:2c:82:6f:ab:01:
+        24:ab:ff:78:6d:59:85:c2:3b:23:c0:bd:0d:d8:6e:3a:29:82:
+        e1:c4:5f:db
+-----BEGIN CERTIFICATE-----
+MIIEKDCCAxCgAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xOTA5MTgxNjEwMTdaFw00OTA5MTYx
+NjEwMTdaMIGGMQswCQYDVQQGEwJHQjEUMBIGA1UECAwLSXNsZSBvZiBNYW4xFzAV
+BgNVBAoMDkNhbm9uaWNhbCBMdGQuMRQwEgYDVQQLDAtTZWN1cmUgQm9vdDEyMDAG
+A1UEAwwpQ2Fub25pY2FsIEx0ZC4gU2VjdXJlIEJvb3QgU2lnbmluZyAoMjAxOSkw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDmR9h15YdZJoeDfVt6uFg9
+fO82+KB6txRWWH0B8Rw7jOZbA3d9oO1HCkXmdVzelTgNOPpBeYlWMYfno5o2cLbP
+JC+ZJokIOQ4UwzW+AotS4Y57DKadeP8BYNf1w9XwXtzkIwlZcpPTtSKvfM3ghA+v
+ES28xnJCr+pnY8QQQXgCgGINQ3S0HO1Q15TxsLv5V4DkaQ+DS6LmLEqa4X18Yhkp
+J5cfTPGF8Dn1MZ86OQ7UTQc6QFVLpmydBIlRLXyw70C1QikWzGVzOGIh9uMsF1Cd
+dDRO33xKM6S7QM/V5e0FB81M+a9/ply598UWRU5EQNeFMt6s5XWtm9fAJjMfd6U3
+AgMBAAGjgaAwgZ0wDAYDVR0TAQH/BAIwADAfBgNVHSUEGDAWBggrBgEFBQcDAwYK
+KwYBBAGCNwoDBjAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2Vy
+dGlmaWNhdGUwHQYDVR0OBBYEFMB0b9bF2jroJ4ZGUa1mrkf+JLPoMB8GA1UdIwQY
+MBaAFK2RmQvCKrH1FwSMI7ZlWiaONFpjMA0GCSqGSIb3DQEBCwUAA4IBAQCqEmzR
+nWra8Ox8F0Y7V7jWdl8k5gaiClUfL9Nej97PAvL/4N3Tx711WarNNPMogHPMKGnn
+onCIosfcZvCSDv9kvzAEVAEblq0VxWH9MmHXXrW6kf0x/GsV3+4i2eQf88yLDJ/1
+6PfiYj9AUsnw8Rxj/GyQ4Vt0A7nf0T6o7NsrboNvn3+6tHn8PecSL0rnF4wrd6WQ
+dDy9z3WDDRqV1VbvB5umszHjjJfOaBG1eyUDchzqZ+l8PnPHfD789a6KsgcNFWpm
+CdcjuV2AeibWtiIwqoSvwELpdcNZq6OEh2sMt6tOkmmuLIJvqwEkq/94bVmFwjsj
+wL0N2G46KYLhxF/b
+-----END CERTIFICATE-----
--- linux-qcom-6.8.0.orig/debian/revoked-certs/canonical-uefi-2021v1-all.pem
+++ linux-qcom-6.8.0/debian/revoked-certs/canonical-uefi-2021v1-all.pem
@@ -0,0 +1,86 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 6 (0x6)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Sep 23 19:29:32 2021 GMT
+            Not After : Sep 22 19:29:32 2051 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2021 v1)
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:aa:b8:34:5b:b6:ae:44:bf:41:e1:78:11:b9:7a:
+                    c8:88:b3:b0:26:50:10:9c:98:d1:f3:98:9f:23:50:
+                    64:f6:39:dd:50:3a:23:44:53:65:fc:f3:9f:f5:a5:
+                    8b:ae:8b:df:47:9f:e9:d5:a0:92:19:f1:21:ea:cc:
+                    59:3a:74:df:45:71:bc:de:64:15:a5:f6:db:ca:71:
+                    fa:19:d4:44:0d:12:ec:47:3a:43:e2:f2:dd:8b:fe:
+                    0d:7b:dc:4d:db:53:06:22:61:e5:8b:35:49:b6:33:
+                    c4:0a:69:5f:5b:81:09:84:6b:42:33:18:09:9d:a0:
+                    35:f7:9c:1e:de:6e:de:90:69:1a:e8:32:e4:49:ad:
+                    c3:31:e9:f8:4a:a2:28:1d:db:0d:29:b6:48:0a:44:
+                    93:86:41:62:8f:73:97:60:10:8a:74:46:66:55:fe:
+                    a0:95:35:9e:ef:9f:af:11:fa:5b:a3:7c:c2:35:64:
+                    11:67:28:1e:14:0a:7d:68:61:9c:cd:c7:46:39:30:
+                    31:79:94:56:b3:45:16:9a:b5:77:66:fe:41:43:0f:
+                    00:48:6e:99:dd:0c:d4:47:2c:86:8c:50:04:61:20:
+                    dd:aa:8e:73:4f:21:b4:ee:09:4d:d3:40:01:d0:f2:
+                    a7:5b:7d:05:3d:c1:e7:65:26:aa:8c:9a:58:5a:7c:
+                    6d:6f
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                A8:D5:4B:BB:38:25:CF:B9:4F:A1:3C:9F:8A:59:4A:19:5C:10:7B:8D
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        24:25:25:7e:01:a5:c8:3d:54:8c:1b:05:73:d1:06:d8:db:d4:
+        3a:71:d5:19:9d:97:1c:85:3c:ca:38:5a:0c:25:25:39:1a:67:
+        bc:6c:9d:98:6c:f3:7d:5f:b7:40:f9:73:a0:f5:7b:40:a8:66:
+        a5:f1:53:b1:78:80:24:3f:19:50:2f:02:09:ec:a1:8a:e6:0d:
+        df:c4:ae:24:9e:69:0d:5c:dc:44:4c:38:3a:53:4e:4b:a1:4b:
+        92:9f:43:a4:9d:1e:76:33:18:1b:bf:62:e5:f5:bc:93:3c:4e:
+        21:d5:5b:20:69:11:28:c1:c5:93:b5:8e:96:1d:1b:ca:72:79:
+        24:de:67:2a:50:9d:ce:8b:41:dd:3e:82:dd:a5:04:75:54:fb:
+        35:70:98:87:b4:f3:ea:41:23:23:80:0e:99:d7:03:16:ee:7e:
+        11:e2:c8:29:ab:73:c5:6d:5c:a8:2f:32:03:9f:8e:66:d6:cb:
+        54:84:55:75:ab:9a:dd:95:fd:05:1e:11:85:37:1e:63:d2:f4:
+        7f:34:64:32:a1:63:91:91:50:39:14:1a:ea:54:78:e6:0d:04:
+        23:c7:83:51:c5:25:27:07:6c:f8:65:b7:da:95:89:76:83:cc:
+        f3:7e:06:74:d3:6c:ef:e9:17:de:29:1e:ab:5c:d7:ec:df:f1:
+        98:b8:e9:66
+-----BEGIN CERTIFICATE-----
+MIIELTCCAxWgAwIBAgIBBjANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAgFw0yMTA5MjMxOTI5MzJaGA8yMDUxMDky
+MjE5MjkzMlowgYkxCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEX
+MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MTUw
+MwYDVQQDDCxDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nICgyMDIx
+IHYxKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKq4NFu2rkS/QeF4
+Ebl6yIizsCZQEJyY0fOYnyNQZPY53VA6I0RTZfzzn/Wli66L30ef6dWgkhnxIerM
+WTp030VxvN5kFaX228px+hnURA0S7Ec6Q+Ly3Yv+DXvcTdtTBiJh5Ys1SbYzxApp
+X1uBCYRrQjMYCZ2gNfecHt5u3pBpGugy5EmtwzHp+EqiKB3bDSm2SApEk4ZBYo9z
+l2AQinRGZlX+oJU1nu+frxH6W6N8wjVkEWcoHhQKfWhhnM3HRjkwMXmUVrNFFpq1
+d2b+QUMPAEhumd0M1EcshoxQBGEg3aqOc08htO4JTdNAAdDyp1t9BT3B52Umqoya
+WFp8bW8CAwEAAaOBoDCBnTAMBgNVHRMBAf8EAjAAMB8GA1UdJQQYMBYGCCsGAQUF
+BwMDBgorBgEEAYI3CgMGMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRl
+ZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUqNVLuzglz7lPoTyfillKGVwQe40wHwYD
+VR0jBBgwFoAUrZGZC8IqsfUXBIwjtmVaJo40WmMwDQYJKoZIhvcNAQELBQADggEB
+ACQlJX4Bpcg9VIwbBXPRBtjb1Dpx1RmdlxyFPMo4WgwlJTkaZ7xsnZhs831ft0D5
+c6D1e0CoZqXxU7F4gCQ/GVAvAgnsoYrmDd/EriSeaQ1c3ERMODpTTkuhS5KfQ6Sd
+HnYzGBu/YuX1vJM8TiHVWyBpESjBxZO1jpYdG8pyeSTeZypQnc6LQd0+gt2lBHVU
++zVwmIe08+pBIyOADpnXAxbufhHiyCmrc8VtXKgvMgOfjmbWy1SEVXWrmt2V/QUe
+EYU3HmPS9H80ZDKhY5GRUDkUGupUeOYNBCPHg1HFJScHbPhlt9qViXaDzPN+BnTT
+bO/pF94pHqtc1+zf8Zi46WY=
+-----END CERTIFICATE-----
--- linux-qcom-6.8.0.orig/debian/revoked-certs/canonical-uefi-2021v2-all.pem
+++ linux-qcom-6.8.0/debian/revoked-certs/canonical-uefi-2021v2-all.pem
@@ -0,0 +1,86 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 7 (0x7)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Sep 23 19:29:42 2021 GMT
+            Not After : Sep 22 19:29:42 2051 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2021 v2)
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:ba:06:8b:ee:58:b7:8b:49:7b:53:7a:d1:df:02:
+                    e3:f2:d8:b0:8c:03:5c:f4:2d:0b:d8:18:3b:23:fa:
+                    68:b0:e8:e9:9d:dc:a2:eb:5e:d3:06:a9:28:d4:9f:
+                    14:b6:1e:1c:1d:ef:69:0e:7f:44:f2:cc:4a:f1:b1:
+                    d0:71:30:6a:50:1e:b0:d3:f8:a4:19:d0:4a:f1:e3:
+                    eb:7a:e5:57:4c:a1:fb:d1:87:b9:48:e0:55:37:52:
+                    f9:de:99:2e:95:85:36:ce:d3:1d:67:2f:14:cb:7f:
+                    05:82:75:21:b6:aa:a5:14:ac:da:4a:f4:fe:fa:5c:
+                    33:49:3d:6f:de:fd:9d:75:ba:e2:c4:02:38:b5:69:
+                    f5:ff:a8:67:4b:3a:e0:34:f6:3b:07:03:a5:7e:59:
+                    6f:3a:d2:28:a4:2f:25:ac:d8:a9:1f:59:52:5d:24:
+                    36:58:51:b5:f0:12:a8:d3:78:56:57:b1:e0:a9:df:
+                    14:05:65:7c:b5:a5:00:f0:88:39:14:44:18:85:2d:
+                    0c:28:69:7b:b9:b4:1c:47:6f:43:66:4c:22:ad:f7:
+                    f6:19:75:e1:14:2c:0d:33:3f:c1:3f:fc:73:56:b2:
+                    68:05:b5:92:03:9b:65:6b:81:80:92:35:03:9b:66:
+                    68:58:c5:66:11:b6:8c:7f:05:09:9a:45:a6:0e:5e:
+                    5f:bf
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                4C:F0:46:89:2D:6F:D3:C9:A5:B0:3F:98:D8:45:F9:08:51:DC:6A:8C
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        93:9d:49:7d:9f:3e:3e:27:79:97:d9:c2:fc:0b:f7:30:b7:f4:
+        78:b2:c9:e4:5e:42:d3:27:26:70:cf:88:96:d1:f2:ea:a0:75:
+        7e:3c:f6:b7:d2:e7:95:30:e3:a6:67:a7:ee:b9:53:8f:fd:b2:
+        cb:db:e1:98:32:be:98:79:09:46:c6:63:6a:57:87:4d:b2:26:
+        46:f6:34:5e:18:75:ca:82:80:8e:33:c2:1d:c7:76:d7:14:57:
+        ef:2e:0e:9e:58:5c:81:8e:ed:53:2c:07:46:0a:8a:fc:2f:f5:
+        b2:c8:58:f5:fa:fa:bb:f9:7d:47:13:39:f0:f2:1c:15:9c:75:
+        90:40:bd:08:04:b3:6a:de:c2:cd:34:21:7e:ba:31:48:bc:a1:
+        23:bc:ee:93:b2:62:96:27:30:86:c2:d4:f7:b4:e6:3c:71:47:
+        37:84:ff:3d:0c:1e:ec:f3:0e:da:6b:dc:64:7a:b8:c0:7e:45:
+        13:09:bf:02:b3:b7:5b:6d:09:2d:6a:4e:0b:93:94:29:4c:a6:
+        c3:c7:05:fa:69:08:04:53:3c:4c:64:c0:7e:89:00:91:1b:a6:
+        c2:d7:ea:c4:db:86:38:fe:66:03:85:7b:fc:39:24:99:4c:2a:
+        3e:10:8b:91:c3:6e:20:9d:0c:ee:51:70:b5:98:58:f3:5c:ac:
+        16:98:7b:ce
+-----BEGIN CERTIFICATE-----
+MIIELTCCAxWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAgFw0yMTA5MjMxOTI5NDJaGA8yMDUxMDky
+MjE5Mjk0MlowgYkxCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEX
+MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MTUw
+MwYDVQQDDCxDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nICgyMDIx
+IHYyKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALoGi+5Yt4tJe1N6
+0d8C4/LYsIwDXPQtC9gYOyP6aLDo6Z3coute0wapKNSfFLYeHB3vaQ5/RPLMSvGx
+0HEwalAesNP4pBnQSvHj63rlV0yh+9GHuUjgVTdS+d6ZLpWFNs7THWcvFMt/BYJ1
+IbaqpRSs2kr0/vpcM0k9b979nXW64sQCOLVp9f+oZ0s64DT2OwcDpX5ZbzrSKKQv
+JazYqR9ZUl0kNlhRtfASqNN4Vlex4KnfFAVlfLWlAPCIORREGIUtDChpe7m0HEdv
+Q2ZMIq339hl14RQsDTM/wT/8c1ayaAW1kgObZWuBgJI1A5tmaFjFZhG2jH8FCZpF
+pg5eX78CAwEAAaOBoDCBnTAMBgNVHRMBAf8EAjAAMB8GA1UdJQQYMBYGCCsGAQUF
+BwMDBgorBgEEAYI3CgMGMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRl
+ZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUTPBGiS1v08mlsD+Y2EX5CFHcaowwHwYD
+VR0jBBgwFoAUrZGZC8IqsfUXBIwjtmVaJo40WmMwDQYJKoZIhvcNAQELBQADggEB
+AJOdSX2fPj4neZfZwvwL9zC39HiyyeReQtMnJnDPiJbR8uqgdX489rfS55Uw46Zn
+p+65U4/9ssvb4Zgyvph5CUbGY2pXh02yJkb2NF4YdcqCgI4zwh3HdtcUV+8uDp5Y
+XIGO7VMsB0YKivwv9bLIWPX6+rv5fUcTOfDyHBWcdZBAvQgEs2rews00IX66MUi8
+oSO87pOyYpYnMIbC1Pe05jxxRzeE/z0MHuzzDtpr3GR6uMB+RRMJvwKzt1ttCS1q
+TguTlClMpsPHBfppCARTPExkwH6JAJEbpsLX6sTbhjj+ZgOFe/w5JJlMKj4Qi5HD
+biCdDO5RcLWYWPNcrBaYe84=
+-----END CERTIFICATE-----
--- linux-qcom-6.8.0.orig/debian/revoked-certs/canonical-uefi-2021v3-all.pem
+++ linux-qcom-6.8.0/debian/revoked-certs/canonical-uefi-2021v3-all.pem
@@ -0,0 +1,86 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 8 (0x8)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Sep 23 19:30:02 2021 GMT
+            Not After : Sep 22 19:30:02 2051 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2021 v3)
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:d6:29:96:87:ae:07:42:45:bb:65:09:b2:9b:de:
+                    5d:8e:78:61:10:d5:6d:ae:ae:26:08:6a:06:ec:4a:
+                    dd:2b:e7:1a:a9:ad:78:e3:fc:cf:8f:d1:47:bd:1e:
+                    33:d8:7a:e3:66:9b:e9:73:c1:5f:42:e2:fe:bc:c3:
+                    41:f7:cd:d7:85:d7:42:c9:ea:31:e5:47:b1:93:5b:
+                    43:2b:07:51:b8:75:08:ad:0f:e7:0d:81:38:5a:21:
+                    df:b1:43:5b:db:37:c5:ac:aa:14:3a:33:19:6a:26:
+                    e0:05:fe:cd:41:31:af:5d:a8:ab:31:77:44:fc:da:
+                    00:e2:7a:44:33:c3:a7:ed:13:54:9f:19:5d:c9:98:
+                    a2:3b:af:4d:0d:87:29:9c:90:9e:42:9e:9a:06:6a:
+                    70:27:c5:aa:f7:a2:f2:88:e0:b9:66:9a:72:a0:f6:
+                    61:7e:30:8f:14:9f:44:0d:dd:54:ae:47:c8:82:ba:
+                    d2:b2:db:6f:24:c1:f4:0a:81:07:90:47:49:5f:57:
+                    d6:3f:bf:2a:73:98:f2:f6:24:1a:74:03:d7:35:f0:
+                    42:d8:14:c5:94:27:5d:3c:49:0c:b0:f0:7a:61:1b:
+                    d7:5a:e3:a3:40:57:e9:a4:07:ee:02:a3:32:27:94:
+                    bb:f3:36:c5:5f:ef:d3:07:04:3a:80:4c:9c:0a:b7:
+                    88:9f
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                10:04:37:BB:6D:E6:E4:69:B5:81:E6:1C:D6:6B:CE:3E:F4:ED:53:AF
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        3b:37:d6:a8:8d:cd:d2:df:13:35:ac:8c:92:d6:b0:ac:d1:38:
+        a8:00:97:47:59:b8:4a:84:8c:80:a5:1d:c7:29:bf:00:66:e5:
+        10:40:26:2e:31:f5:e1:13:c0:1b:29:f3:0b:7e:2d:71:d8:db:
+        e1:32:8f:79:8e:e3:97:0c:40:a9:a0:12:c1:fc:c2:50:88:72:
+        44:c5:bc:8b:45:6e:28:fd:d2:37:d6:db:17:cf:4e:61:33:08:
+        5a:5d:08:94:73:44:e2:76:00:44:1b:b8:00:a1:86:00:64:8a:
+        f1:42:32:3c:28:11:67:7c:8b:aa:06:34:74:58:e8:b3:3a:36:
+        8d:f6:04:5d:37:f5:66:52:c9:48:b0:a7:6f:34:09:dd:60:2a:
+        86:b9:14:f1:09:f6:06:16:56:e0:51:b1:e8:75:7f:fa:37:dc:
+        e0:98:a7:69:ae:7b:1a:73:89:0d:06:67:cc:01:ef:80:31:45:
+        9e:bb:03:2a:eb:89:70:d6:19:b2:c7:ce:bc:81:df:da:c8:6f:
+        a9:4b:2d:d7:a7:e1:af:c6:e8:fb:f0:61:c9:cd:d2:91:cd:8b:
+        c2:6c:ef:e0:b6:7f:f1:c4:81:f9:bb:76:9c:26:e3:fa:a1:a0:
+        cd:5e:05:de:ee:f9:1b:5b:50:0a:8b:0f:47:e3:90:32:ac:2a:
+        e7:65:02:80
+-----BEGIN CERTIFICATE-----
+MIIELTCCAxWgAwIBAgIBCDANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAgFw0yMTA5MjMxOTMwMDJaGA8yMDUxMDky
+MjE5MzAwMlowgYkxCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEX
+MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MTUw
+MwYDVQQDDCxDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nICgyMDIx
+IHYzKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANYploeuB0JFu2UJ
+spveXY54YRDVba6uJghqBuxK3SvnGqmteOP8z4/RR70eM9h642ab6XPBX0Li/rzD
+QffN14XXQsnqMeVHsZNbQysHUbh1CK0P5w2BOFoh37FDW9s3xayqFDozGWom4AX+
+zUExr12oqzF3RPzaAOJ6RDPDp+0TVJ8ZXcmYojuvTQ2HKZyQnkKemgZqcCfFqvei
+8ojguWaacqD2YX4wjxSfRA3dVK5HyIK60rLbbyTB9AqBB5BHSV9X1j+/KnOY8vYk
+GnQD1zXwQtgUxZQnXTxJDLDwemEb11rjo0BX6aQH7gKjMieUu/M2xV/v0wcEOoBM
+nAq3iJ8CAwEAAaOBoDCBnTAMBgNVHRMBAf8EAjAAMB8GA1UdJQQYMBYGCCsGAQUF
+BwMDBgorBgEEAYI3CgMGMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRl
+ZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUEAQ3u23m5Gm1geYc1mvOPvTtU68wHwYD
+VR0jBBgwFoAUrZGZC8IqsfUXBIwjtmVaJo40WmMwDQYJKoZIhvcNAQELBQADggEB
+ADs31qiNzdLfEzWsjJLWsKzROKgAl0dZuEqEjIClHccpvwBm5RBAJi4x9eETwBsp
+8wt+LXHY2+Eyj3mO45cMQKmgEsH8wlCIckTFvItFbij90jfW2xfPTmEzCFpdCJRz
+ROJ2AEQbuAChhgBkivFCMjwoEWd8i6oGNHRY6LM6No32BF039WZSyUiwp280Cd1g
+Koa5FPEJ9gYWVuBRseh1f/o33OCYp2muexpziQ0GZ8wB74AxRZ67AyrriXDWGbLH
+zryB39rIb6lLLden4a/G6PvwYcnN0pHNi8Js7+C2f/HEgfm7dpwm4/qhoM1eBd7u
++RtbUAqLD0fjkDKsKudlAoA=
+-----END CERTIFICATE-----
--- linux-qcom-6.8.0.orig/debian/revoked-certs/canonical-uefi-uc2019-all.pem
+++ linux-qcom-6.8.0/debian/revoked-certs/canonical-uefi-uc2019-all.pem
@@ -0,0 +1,86 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 3 (0x3)
+        Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C = GB, ST = Isle of Man, L = Douglas, O = Canonical Ltd., CN = Canonical Ltd. Master Certificate Authority
+        Validity
+            Not Before: Mar  4 10:27:14 2020 GMT
+            Not After : Mar  3 10:27:14 2050 GMT
+        Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (Ubuntu Core 2019)
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:b9:10:47:2e:75:5d:f3:10:23:bb:a0:75:d2:fa:
+                    02:2d:ff:22:df:c1:e6:cd:38:7c:36:0f:ae:74:15:
+                    6e:a5:34:52:2b:c3:a4:3a:60:d7:06:ee:1d:99:93:
+                    ff:66:91:a3:18:52:2c:8c:58:e6:b4:2f:4b:c5:fb:
+                    83:e6:f3:19:bd:1b:ca:23:ec:97:1f:d8:f1:9a:f1:
+                    04:da:da:10:04:53:4b:ec:1d:b6:26:47:7c:bb:8f:
+                    a7:0a:6e:2e:e8:91:e6:c4:bb:64:34:78:3c:fa:09:
+                    15:1c:8f:9e:eb:04:99:36:22:c6:8d:07:15:0f:b9:
+                    69:08:fa:ff:4b:45:bd:ba:2b:cd:01:0e:e7:01:23:
+                    c9:e5:7a:39:3b:91:b0:45:3c:d5:77:ba:ca:f9:29:
+                    3d:11:3f:1c:6b:5b:8e:6c:4b:3f:c9:29:05:cb:59:
+                    d6:b1:c1:c0:2d:56:88:70:27:fa:73:05:5c:c2:11:
+                    d4:27:11:f7:0b:c2:d5:68:d3:1a:cd:ed:d0:e4:10:
+                    ff:34:cb:b7:45:70:34:2c:23:53:b6:9c:30:70:b4:
+                    5c:d1:e2:64:18:82:8f:62:b1:5e:aa:0b:d4:89:f2:
+                    1c:53:c4:32:7d:ef:53:ee:9b:6e:02:ab:78:bd:25:
+                    67:8b:39:36:d8:84:3b:06:99:02:d6:75:73:4e:f2:
+                    f6:b9
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: critical
+                CA:FALSE
+            X509v3 Extended Key Usage: 
+                Code Signing, 1.3.6.1.4.1.311.10.3.6
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                C1:D5:7B:8F:6B:74:3F:23:EE:41:F4:F7:EE:29:2F:06:EE:CA:DF:B9
+            X509v3 Authority Key Identifier: 
+                AD:91:99:0B:C2:2A:B1:F5:17:04:8C:23:B6:65:5A:26:8E:34:5A:63
+    Signature Algorithm: sha256WithRSAEncryption
+    Signature Value:
+        2d:b5:11:a8:d2:a0:af:81:a0:18:22:18:2c:08:d0:f4:63:e8:
+        8f:9a:f4:f5:20:dd:eb:22:77:19:9a:1a:09:3d:7f:aa:7d:c9:
+        81:bc:26:98:65:94:46:30:4b:c2:51:7c:f7:21:41:63:87:31:
+        fc:a4:c9:41:28:c7:2e:2a:2e:d8:a8:75:7a:72:77:3b:1b:9f:
+        72:15:0d:0c:96:8d:8b:51:f3:ce:37:b6:ca:9f:ca:59:40:4a:
+        fc:73:7a:94:12:99:aa:c2:8d:52:ce:91:19:2e:b4:da:ff:e5:
+        2c:67:74:d9:58:47:38:2f:61:88:c5:cf:a7:48:e1:08:ba:bc:
+        ec:d5:3a:47:d9:8c:dc:c3:bc:cb:98:2b:79:7a:02:46:ef:85:
+        19:2f:03:4b:05:84:eb:56:98:5f:6d:cf:a5:8b:a2:b6:e5:50:
+        51:7c:33:44:bd:7a:94:2e:0d:90:39:39:3e:62:60:ae:3a:e2:
+        f5:17:fa:f1:94:06:1d:ae:a3:f8:19:20:7f:4b:4c:07:c4:e6:
+        2d:0d:e5:94:84:51:6d:6f:0f:c4:c6:79:1d:f0:e8:0e:23:9e:
+        fd:f9:46:2c:b9:ec:97:38:56:7e:b8:13:f6:d2:e1:8e:a5:93:
+        02:7b:6e:dd:33:9a:bf:10:a8:1b:3d:fa:c4:f2:15:f0:27:73:
+        26:a6:94:d1
+-----BEGIN CERTIFICATE-----
+MIIENjCCAx6gAwIBAgIBAzANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMCR0Ix
+FDASBgNVBAgMC0lzbGUgb2YgTWFuMRAwDgYDVQQHDAdEb3VnbGFzMRcwFQYDVQQK
+DA5DYW5vbmljYWwgTHRkLjE0MDIGA1UEAwwrQ2Fub25pY2FsIEx0ZC4gTWFzdGVy
+IENlcnRpZmljYXRlIEF1dGhvcml0eTAgFw0yMDAzMDQxMDI3MTRaGA8yMDUwMDMw
+MzEwMjcxNFowgZIxCzAJBgNVBAYTAkdCMRQwEgYDVQQIDAtJc2xlIG9mIE1hbjEX
+MBUGA1UECgwOQ2Fub25pY2FsIEx0ZC4xFDASBgNVBAsMC1NlY3VyZSBCb290MT4w
+PAYDVQQDDDVDYW5vbmljYWwgTHRkLiBTZWN1cmUgQm9vdCBTaWduaW5nIChVYnVu
+dHUgQ29yZSAyMDE5KTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALkQ
+Ry51XfMQI7ugddL6Ai3/It/B5s04fDYPrnQVbqU0UivDpDpg1wbuHZmT/2aRoxhS
+LIxY5rQvS8X7g+bzGb0byiPslx/Y8ZrxBNraEARTS+wdtiZHfLuPpwpuLuiR5sS7
+ZDR4PPoJFRyPnusEmTYixo0HFQ+5aQj6/0tFvborzQEO5wEjyeV6OTuRsEU81Xe6
+yvkpPRE/HGtbjmxLP8kpBctZ1rHBwC1WiHAn+nMFXMIR1CcR9wvC1WjTGs3t0OQQ
+/zTLt0VwNCwjU7acMHC0XNHiZBiCj2KxXqoL1InyHFPEMn3vU+6bbgKreL0lZ4s5
+NtiEOwaZAtZ1c07y9rkCAwEAAaOBoDCBnTAMBgNVHRMBAf8EAjAAMB8GA1UdJQQY
+MBYGCCsGAQUFBwMDBgorBgEEAYI3CgMGMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NM
+IEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUwdV7j2t0PyPuQfT37ikv
+Bu7K37kwHwYDVR0jBBgwFoAUrZGZC8IqsfUXBIwjtmVaJo40WmMwDQYJKoZIhvcN
+AQELBQADggEBAC21EajSoK+BoBgiGCwI0PRj6I+a9PUg3esidxmaGgk9f6p9yYG8
+JphllEYwS8JRfPchQWOHMfykyUEoxy4qLtiodXpydzsbn3IVDQyWjYtR8843tsqf
+yllASvxzepQSmarCjVLOkRkutNr/5SxndNlYRzgvYYjFz6dI4Qi6vOzVOkfZjNzD
+vMuYK3l6AkbvhRkvA0sFhOtWmF9tz6WLorblUFF8M0S9epQuDZA5OT5iYK464vUX
++vGUBh2uo/gZIH9LTAfE5i0N5ZSEUW1vD8TGeR3w6A4jnv35Riy57Jc4Vn64E/bS
+4Y6lkwJ7bt0zmr8QqBs9+sTyFfAncyamlNE=
+-----END CERTIFICATE-----
--- linux-qcom-6.8.0.orig/debian/rules
+++ linux-qcom-6.8.0/debian/rules
@@ -0,0 +1,241 @@
+#!/usr/bin/make -f
+#
+# $(DEBIAN)/rules for Ubuntu linux
+#
+# Use this however you want, just give credit where credit is due.
+#
+# Copyright (c) 2007 Ben Collins <bcollins@ubuntu.com>
+#
+
+# Do not use make's built-in rules and variables
+# (this increases performance and avoids hard-to-debug behaviour)
+MAKEFLAGS += -rR
+
+# Allow to run debian/rules directly without root
+export DEB_RULES_REQUIRES_ROOT := no
+
+.NOTPARALLEL:
+
+DEBIAN=$(shell awk -F= '($$1 == "DEBIAN") { print $$2 }' <debian/debian.env)
+
+# dpkg-buildpackage passes options that are incomptatible
+# with the kernel build.
+unexport CFLAGS
+unexport LDFLAGS
+
+export LC_ALL=C
+export SHELL=/bin/bash -e
+
+# Where do we find the common configuration.
+export DROOT=debian
+
+# Temporary workaround to fix build issues if only python2 runtime is installed
+# (without python3-dev).
+export PYTHON=python3
+
+# Common variables for all architectures
+include $(DROOT)/rules.d/0-common-vars.mk
+
+# Pull in some arch specific stuff
+-include $(DEBIAN)/rules.d/$(arch).mk
+
+# Pull in some branch specific stuff
+-include $(DEBIAN)/rules.d/hooks.mk
+
+# Maintainer targets
+include $(DROOT)/rules.d/1-maintainer.mk
+
+do_linux_tools=$(sort $(filter-out false,$(do_tools_usbip) $(do_tools_cpupower) $(do_tools_perf) $(do_tools_bpftool) $(do_tools_x86)))
+do_cloud_tools=$(sort $(filter-out false,$(do_tools_hyperv)))
+do_tools_perf_jvmti?=false
+do_tools_perf_python?=false
+
+# Indep tools packages may only be built for the main linux source package
+ifeq ($(src_pkg_name),linux)
+	do_tools_common = true
+	do_tools_host = true
+endif
+
+# The linux-source package may only be built for the linux source package
+# We need to explicitly turn this off here to override any (incorrect)
+# statement in any of the above included makefile snippets
+ifneq ($(src_pkg_name),linux)
+	do_source_package = false
+endif
+
+# Default settings for DKMS modules.
+$(foreach _m,$(all_dkms_modules), \
+  $(eval do_$(_m) ?= $(if $(filter $(_m),$(filter-out $(dkms_exclude),$(dkms_include) $(subst any,$(_m),$(subst $(arch),$(_m),$(dkms_$(_m)_archs))))),true,false)) \
+)
+
+# Don't build tools in a cross compile environment.
+ifneq ($(DEB_HOST_ARCH),$(DEB_BUILD_ARCH))
+	do_tools=false
+endif
+
+# Are any of the kernel signing options enabled.
+any_signed=$(sort $(filter-out false,$(uefi_signed) $(opal_signed) $(sipl_signed)))
+ifeq ($(any_signed),true)
+bin_pkg_name=$(bin_pkg_name_unsigned)
+else
+bin_pkg_name=$(bin_pkg_name_signed)
+endif
+
+# Stages -- support both DEB_STAGE=stage1 and DEB_BUILD_PROFILE=bootstrap
+ifeq ($(DEB_STAGE),stage1)
+    DEB_BUILD_PROFILES=stage1
+endif
+ifneq ($(DEB_BUILD_PROFILE),)
+    DEB_BUILD_PROFILES=$(DEB_BUILD_PROFILE)
+endif
+ifneq ($(filter stage1,$(DEB_BUILD_PROFILES)),)
+    do_tools=false
+    do_source_package=false
+    do_flavour_image_package=false
+    do_flavour_header_package=false
+endif
+
+# autopkgtest -- rebuild support
+#  - only build the first flavour on the assumption it is representative
+#  - disable dkms builds as the versions used may have been deleted
+ifneq ($(filter autopkgtest,$(DEB_BUILD_PROFILES)),)
+	flavours := $(firstword $(flavours))
+$(foreach _m,$(all_dkms_modules),$(eval do_$(_m) = false))
+endif
+
+# Being used to build a mainline build -- turn off things which do not work.
+ifeq ($(do_mainline_build),true)
+	do_extras_package=false
+	do_tools=false
+	no_dumpfile=1
+$(foreach _m,$(all_dkms_modules),$(eval do_$(_m) = false))
+	do_skip_checks=true
+endif
+
+# Disable tools build and packaging if do_tools != true
+ifneq ($(do_tools),true)
+	do_linux_tools=
+	do_cloud_tools=
+	do_tools_common=
+	do_tools_host=
+endif
+
+# Either tools package needs the common source preparation
+do_any_tools=$(sort $(filter-out false,$(do_linux_tools) $(do_cloud_tools)))
+
+# Debian Build System targets
+.PHONY: binary
+binary: binary-indep binary-arch
+
+.PHONY: build
+build: build-arch build-indep
+
+.PHONY: clean
+clean: debian/control debian/canonical-certs.pem debian/canonical-revoked-certs.pem
+	dh_testdir
+	dh_testroot
+	dh_clean
+
+	# normal build junk
+	rm -rf $(DEBIAN)/abi
+	rm -rf $(builddir) $(stampdir)
+	rm -rf debian/linux-*/
+
+	cp $(DEBIAN)/changelog debian/changelog
+
+	# Install the copyright information.
+	cp $(DEBIAN)/copyright debian/copyright
+
+	# If we have a reconstruct script use it.
+	[ -f $(DEBIAN)/reconstruct ] && bash $(DEBIAN)/reconstruct || true
+
+	# Remove generated intermediate files
+	rm -f $(DROOT)/control.stub $(DEBIAN)/control.stub
+	rm -f $(DROOT)/scripts/fix-filenames
+
+.PHONY: distclean
+distclean: clean
+	rm -rf $(DROOT)/control debian/changelog \
+		debian/control debian/control.stub debian/copyright
+
+# Builds the image, arch headers and debug packages
+include $(DROOT)/rules.d/2-binary-arch.mk
+
+# Builds the source and linux-headers indep packages
+include $(DROOT)/rules.d/3-binary-indep.mk
+
+# Various checks to be performed on builds
+include $(DROOT)/rules.d/4-checks.mk
+
+control_files := $(DEBIAN)/control.stub.in
+ifeq ($(src_pkg_name),linux)
+	control_files += debian/control.d/linux-libc-dev.stub
+	control_files += debian/control.d/linux-tools-common.stub
+	control_files += debian/control.d/linux-cloud-tools-common.stub
+	control_files += debian/control.d/linux-tools-host.stub
+	control_files += debian/control.d/linux-source.stub
+	control_files += debian/control.d/linux-doc.stub
+	control_files += debian/control.d/linux-bpf-dev.stub
+endif
+
+# Calculate Ubuntu Compatible Signing levels
+UBUNTU_COMPATIBLE_SIGNING=$(shell grep -qx ' *Subject: C = GB, ST = Isle of Man, O = Canonical Ltd., OU = Secure Boot, CN = Canonical Ltd. Secure Boot Signing (2021 v3)' debian/canonical-revoked-certs.pem && echo ubuntu/4 pro/3)
+
+# Misc stuff
+.PHONY: $(DEBIAN)/control.stub
+$(DEBIAN)/control.stub: 				\
+		$(DROOT)/scripts/control-create		\
+		$(control_files)			\
+		debian/canonical-revoked-certs.pem	\
+		$(DROOT)/control.d/flavour-module.stub	\
+		$(DEBIAN)/changelog			\
+		$(wildcard $(DEBIAN)/control.d/*)
+	for i in $(control_files); do                                           \
+	  cat $$i;                                                              \
+	  echo "";                                                              \
+	done | sed -e 's/PKGVER/$(release)/g'                                   \
+	        -e 's/ABINUM/$(abinum)/g'                                       \
+		-e 's/SRCPKGNAME/$(src_pkg_name)/g'                             \
+		-e 's/=HUMAN=/$(human_arch)/g'                                  \
+		-e 's/=SERIES=/$(series)/g'                                     \
+		-e 's|\(^Maintainer:.*\)|\1\nXSC-Ubuntu-Compatible-Signing: $(UBUNTU_COMPATIBLE_SIGNING)|g' \
+		-e 's/\(^Build-Depends:$$\)/\1\n$(GCC_BUILD_DEPENDS)/g'         \
+	  > $(DEBIAN)/control.stub;
+	flavours="$(sort $(wildcard $(DEBIAN)/control.d/vars.*))";\
+	for i in $$flavours; do							\
+	  $(SHELL) $(DROOT)/scripts/control-create $$i "$(any_signed)" |	\
+		sed -e 's/PKGVER/$(release)/g'                                  \
+		-e 's/ABINUM/$(abinum)/g'                                       \
+		-e 's/SRCPKGNAME/$(src_pkg_name)/g'                             \
+		-e 's/=HUMAN=/$(human_arch)/g'                                  \
+		-e 's/=SERIES=/$(series)/g'                                     \
+		>> $(DEBIAN)/control.stub;                                      \
+	done
+
+.PHONY: debian/control
+debian/control: $(DEBIAN)/control.stub
+	cp $(DEBIAN)/control.stub debian/control
+
+debian/canonical-certs.pem: $(wildcard $(DROOT)/certs/*-all.pem) $(wildcard $(DROOT)/certs/*-$(arch).pem) $(wildcard $(DEBIAN)/certs/*-all.pem) $(wildcard $(DEBIAN)/certs/*-$(arch).pem)
+	for cert in $(sort $(notdir $^));					\
+	do									\
+		for dir in $(DEBIAN) $(DROOT);					\
+		do								\
+			if [ -f "$$dir/certs/$$cert" ]; then			\
+				cat "$$dir/certs/$$cert";			\
+				break;						\
+			fi;							\
+		done;								\
+	done >"$@"
+
+debian/canonical-revoked-certs.pem: $(wildcard $(DROOT)/revoked-certs/*-all.pem) $(wildcard $(DROOT)/revoked-certs/*-$(arch).pem) $(wildcard $(DEBIAN)/revoked-certs/*-all.pem) $(wildcard $(DEBIAN)/revoked-certs/*-$(arch).pem)
+	for cert in $(sort $(notdir $^));					\
+	do									\
+		for dir in $(DEBIAN) $(DROOT);					\
+		do								\
+			if [ -f "$$dir/revoked-certs/$$cert" ]; then		\
+				cat "$$dir/revoked-certs/$$cert";		\
+				break;						\
+			fi;							\
+		done;								\
+	done >"$@"
--- linux-qcom-6.8.0.orig/debian/rules.d/0-common-vars.mk
+++ linux-qcom-6.8.0/debian/rules.d/0-common-vars.mk
@@ -0,0 +1,269 @@
+# Used when you need to 'escape' a comma.
+comma = ,
+empty :=
+space := $(empty) $(empty)
+
+#
+# The source package name will be the first token from $(DEBIAN)/changelog
+#
+src_pkg_name := $(shell dpkg-parsechangelog -l$(DEBIAN)/changelog -S source)
+
+# Get the series
+series := $(shell dpkg-parsechangelog -l$(DEBIAN)/changelog -S distribution | sed -e 's/-\(security\|updates\|proposed\)$$//')
+
+# Get some version info
+version := $(shell dpkg-parsechangelog -l$(DEBIAN)/changelog -S version)
+revision ?= $(lastword $(subst -,$(space),$(version)))
+release := $(patsubst %-$(revision),%,$(version))
+
+prev_fullver ?= $(shell dpkg-parsechangelog -l$(DEBIAN)/changelog -o1 -c1 -S version)
+prev_revision := $(lastword 0.0 $(subst -,$(space),$(prev_fullver)))
+
+# Get upstream version info
+upstream_version := $(shell sed -n 's/^VERSION = \(.*\)$$/\1/p' Makefile)
+upstream_patchlevel := $(shell sed -n 's/^PATCHLEVEL = \(.*\)$$/\1/p' Makefile)
+upstream_tag := "v$(upstream_version).$(upstream_patchlevel)"
+
+# Get the kernels own extra version to be added to the release signature.
+raw_kernelversion=$(shell make kernelversion)
+
+packages_enabled := $(shell dh_listpackages 2>/dev/null)
+define if_package
+$(if $(filter $(1),$(packages_enabled)),$(2))
+endef
+
+stamp = [ -d $(dir $@) ] || mkdir $(dir $@); touch $@
+
+#
+# do_full_build -- are we doing a full buildd style build, i.e., are we
+#                  building in a PPA
+#
+ifeq ($(wildcard /CurrentlyBuilding),)
+	do_full_build ?= false
+else
+	do_full_build ?= true
+endif
+
+#
+# The debug packages are ginormous, so you probably want to skip
+# building them (as a developer).
+#
+do_dbgsym_package = true
+ifeq ($(do_full_build),false)
+	do_dbgsym_package = false
+endif
+ifeq ($(filter $(DEB_BUILD_OPTIONS),noautodbgsym),noautodbgsym)
+	# Disable debug package builds if we're building in a PPA that has the
+	# 'Build debug symbols' option disabled
+	do_dbgsym_package = false
+endif
+
+abinum		:= $(firstword $(subst .,$(space),$(revision)))
+prev_abinum	:= $(firstword $(subst .,$(space),$(prev_revision)))
+abi_release	:= $(release)-$(abinum)
+
+uploadnum	:= $(patsubst $(abinum).%,%,$(revision))
+ifneq ($(do_full_build),false)
+  uploadnum	:= $(uploadnum)-Ubuntu
+endif
+
+DEB_HOST_MULTIARCH = $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
+DEB_HOST_GNU_TYPE  = $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE = $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+DEB_HOST_ARCH = $(shell dpkg-architecture -qDEB_HOST_ARCH)
+DEB_BUILD_ARCH = $(shell dpkg-architecture -qDEB_BUILD_ARCH)
+
+#
+# Detect invocations of the form 'fakeroot debian/rules binary arch=armhf'
+# within an x86'en schroot. This only gets you part of the way since the
+# packaging phase fails, but you can at least compile the kernel quickly.
+#
+arch := $(DEB_HOST_ARCH)
+CROSS_COMPILE ?= $(DEB_HOST_GNU_TYPE)-
+
+#
+# Set consistent toolchain
+# If a given kernel wants to change this, they can do so via their own
+# $(DEBIAN)/rules.d/hooks.mk and $(DEBIAN)/rules.d/$(arch).mk files
+#
+export gcc?=gcc-13
+GCC_BUILD_DEPENDS=\ $(gcc), $(gcc)-aarch64-linux-gnu [arm64] <cross>, $(gcc)-arm-linux-gnueabihf [armhf] <cross>, $(gcc)-powerpc64le-linux-gnu [ppc64el] <cross>, $(gcc)-riscv64-linux-gnu [riscv64] <cross>, $(gcc)-s390x-linux-gnu [s390x] <cross>, $(gcc)-x86-64-linux-gnu [amd64] <cross>,
+
+abidir		:= $(CURDIR)/$(DEBIAN)/__abi.current/$(arch)
+commonconfdir	:= $(CURDIR)/$(DEBIAN)/config
+archconfdir	:= $(CURDIR)/$(DEBIAN)/config/$(arch)
+sharedconfdir	:= $(CURDIR)/debian.master/config
+builddir	:= $(CURDIR)/debian/build
+stampdir	:= $(CURDIR)/debian/stamps
+
+#
+# The binary package name always starts with linux-image-$KVER-$ABI.$UPLOAD_NUM. There
+# are places that you'll find linux-image hard coded, but I guess thats OK since the
+# assumption that the binary package always starts with linux-image will never change.
+#
+bin_pkg_name_signed=linux-image-$(abi_release)
+bin_pkg_name_unsigned=linux-image-unsigned-$(abi_release)
+mods_pkg_name=linux-modules-$(abi_release)
+mods_extra_pkg_name=linux-modules-extra-$(abi_release)
+bldinfo_pkg_name=linux-buildinfo-$(abi_release)
+hdrs_pkg_name=linux-headers-$(abi_release)
+rust_pkg_name=$(src_pkg_name)-lib-rust-$(abi_release)
+indep_hdrs_pkg_name=$(src_pkg_name)-headers-$(abi_release)
+indep_lib_rust_pkg_name=$(src_pkg_name)-lib-rust-$(abi_release)
+
+#
+# Similarly with the linux-source package, you need not build it as a developer. Its
+# somewhat I/O intensive and utterly useless.
+#
+do_source_package=true
+do_source_package_content=true
+ifeq ($(do_full_build),false)
+do_source_package_content=false
+endif
+
+# common headers normally is built as an indep package, but may be arch
+do_common_headers_indep=true
+
+# build tools
+ifneq ($(wildcard $(CURDIR)/tools),)
+	ifeq ($(do_tools),)
+		ifneq ($(DEB_BUILD_GNU_TYPE),$(DEB_HOST_GNU_TYPE))
+			do_tools=false
+		endif
+	endif
+	do_tools?=true
+else
+	do_tools?=false
+endif
+tools_pkg_name=$(src_pkg_name)-tools-$(abi_release)
+tools_common_pkg_name=linux-tools-common
+tools_flavour_pkg_name=linux-tools-$(abi_release)
+cloud_pkg_name=$(src_pkg_name)-cloud-tools-$(abi_release)
+cloud_common_pkg_name=linux-cloud-tools-common
+cloud_flavour_pkg_name=linux-cloud-tools-$(abi_release)
+hosttools_pkg_name=linux-tools-host
+
+# The general flavour specific image package.
+do_flavour_image_package=true
+
+# The general flavour specific header package.
+do_flavour_header_package=true
+
+# DTBs
+do_dtbs=false
+
+# ZSTD compressed kernel modules
+do_zstd_ko=true
+ifeq ($(series),jammy)
+do_zstd_ko=
+endif
+
+# Support parallel=<n> in DEB_BUILD_OPTIONS (see #209008)
+#
+# These 2 environment variables set the -j value of the kernel build. For example,
+# CONCURRENCY_LEVEL=16 fakeroot $(DEBIAN)/rules binary-debs
+# or
+# DEB_BUILD_OPTIONS=parallel=16 fakeroot $(DEBIAN)/rules binary-debs
+#
+# The default is to use the number of CPUs.
+#
+COMMA=,
+DEB_BUILD_OPTIONS_PARA = $(subst parallel=,,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS))))
+ifneq (,$(DEB_BUILD_OPTIONS_PARA))
+  CONCURRENCY_LEVEL := $(DEB_BUILD_OPTIONS_PARA)
+endif
+
+ifeq ($(CONCURRENCY_LEVEL),)
+  # Check the environment
+  CONCURRENCY_LEVEL := $(shell echo $$CONCURRENCY_LEVEL)
+  # No? Then build with the number of CPUs on the host.
+  ifeq ($(CONCURRENCY_LEVEL),)
+      CONCURRENCY_LEVEL := $(shell expr `getconf _NPROCESSORS_ONLN` \* 1)
+  endif
+  # Oh hell, give 'em one
+  ifeq ($(CONCURRENCY_LEVEL),)
+    CONCURRENCY_LEVEL := 1
+  endif
+endif
+
+conc_level		= -j$(CONCURRENCY_LEVEL)
+
+PYTHON ?= $(firstword $(wildcard /usr/bin/python3) $(wildcard /usr/bin/python2) $(wildcard /usr/bin/python))
+
+HOSTCC ?= $(DEB_BUILD_GNU_TYPE)-$(gcc)
+
+# target_flavour is filled in for each step
+kmake = make ARCH=$(build_arch) \
+	CROSS_COMPILE=$(CROSS_COMPILE) \
+	HOSTCC=$(HOSTCC) \
+	CC=$(CROSS_COMPILE)$(gcc) \
+	BINDGEN=bindgen-0.65 \
+	KERNELRELEASE=$(abi_release)-$(target_flavour) \
+	CONFIG_DEBUG_SECTION_MISMATCH=y \
+	KBUILD_BUILD_VERSION="$(uploadnum)" \
+	CFLAGS_MODULE="-DPKG_ABI=$(abinum)" \
+	PYTHON=$(PYTHON)
+ifneq ($(LOCAL_ENV_CC),)
+kmake += CC="$(LOCAL_ENV_CC)" DISTCC_HOSTS="$(LOCAL_ENV_DISTCC_HOSTS)"
+endif
+
+# Locking is required in parallel builds to prevent loss of contents
+# of the debian/files.
+lockme = flock -w 60 $(CURDIR)/debian/.LOCK
+
+# Don't fail if a link already exists.
+LN = ln -sf
+
+# Checks if a var is overriden by the custom rules. Called with var and
+# flavour as arguments.
+custom_override = $(or $($(1)_$(2)),$($(1)))
+
+# selftests that Ubuntu cares about
+ubuntu_selftests = breakpoints cpu-hotplug efivarfs memfd memory-hotplug mount net ptrace seccomp timers powerpc user ftrace
+
+# DKMS
+all_dkms_modules =
+
+subst_paired = $(subst $(firstword $(subst =, ,$(1))),$(lastword $(subst =, ,$(1))),$(2))
+recursive_call = $(if $(2),$(call recursive_call,$(1),$(wordlist 2,$(words $(2)),$(2)),$(call $(1),$(firstword $(2)),$(3))),$(3))
+
+$(foreach _line,$(shell gawk '{ OFS = "!"; $$1 = $$1; print }' $(DEBIAN)/dkms-versions), \
+  $(eval _params = $(subst !, ,$(_line))) \
+  $(eval _deb_pkgname = $(firstword $(_params))) \
+  $(eval _deb_version = $(word 2,$(_params))) \
+  $(if $(filter modulename=%,$(_params)), \
+    $(eval _m = $(word 2,$(subst =, ,$(filter modulename=%,$(_params))))) \
+    , \
+    $(info modulename for $(_deb_pkgname) not specified in dkms-versions. Assume $(_deb_pkgname).) \
+    $(eval _m = $(_deb_pkgname)) \
+  ) \
+  $(eval all_dkms_modules += $(_m)) \
+  $(eval dkms_$(_m)_version = $(_deb_version)) \
+  $(foreach _p,$(patsubst debpath=%,%,$(filter debpath=%,$(_params))), \
+    $(eval dkms_$(_m)_debpath += $(strip \
+      $(call recursive_call,subst_paired, \
+        %module%=$(_m) \
+        %package%=$(_deb_pkgname) \
+        %version%=$(lastword $(subst :, ,$(_deb_version))) \
+        , \
+        $(_p) \
+      ) \
+    )) \
+  ) \
+  $(if $(dkms_$(_m)_debpath),,$(error debpath for $(_deb_pkgname) not specified.)) \
+  $(if $(filter arch=%,$(_params)), \
+    $(eval dkms_$(_m)_archs = $(patsubst arch=%,%,$(filter arch=%,$(_params)))) \
+    , \
+    $(eval dkms_$(_m)_archs = any) \
+  ) \
+  $(eval dkms_$(_m)_rprovides = $(patsubst rprovides=%,%,$(filter rprovides=%,$(_params)))) \
+  $(eval dkms_$(_m)_type = $(word 1,$(patsubst type=%,%,$(filter type=%,$(_params))) built-in)) \
+  $(eval all_$(dkms_$(_m)_type)_dkms_modules += $(_m)) \
+  $(if $(filter standalone,$(dkms_$(_m)_type)), \
+    $(eval dkms_$(_m)_pkg_name = linux-modules-$(_m)-$(abi_release)) \
+    $(eval dkms_$(_m)_subdir = ubuntu) \
+    , \
+    $(eval dkms_$(_m)_pkg_name = $(mods_pkg_name)) \
+    $(eval dkms_$(_m)_subdir = kernel) \
+  ) \
+)
--- linux-qcom-6.8.0.orig/debian/rules.d/1-maintainer.mk
+++ linux-qcom-6.8.0/debian/rules.d/1-maintainer.mk
@@ -0,0 +1,135 @@
+# The following targets are for the maintainer only! do not run if you don't
+# know what they do.
+
+.PHONY: help
+help:
+	@echo "These are the targets in addition to the normal $(DEBIAN) ones:"
+	@echo
+	@echo "  printenv            : Print some variables used in the build"
+	@echo "  updateconfigs       : Update core arch configs"
+	@echo "  defaultconfigs      : Update core arch configs using defaults"
+	@echo "  genconfigs          : Generate core arch configs in CONFIGS/*"
+	@echo "  editconfigs         : Edit core arch configs"
+	@echo "  printchanges        : Print the current changelog entries (from git)"
+	@echo "  insertchanges       : Insert current changelog entries (from git)"
+	@echo "  compileselftests    : Only compile the selftests listed on ubuntu_selftests variable"
+	@echo "  runselftests        : Run the selftests listed on ubuntu_selftests variable"
+	@echo
+	@echo "Environment variables:"
+	@echo
+	@echo "  CONCURRENCY_LEVEL=X : Use -jX for kernel compile"
+
+.PHONY: printdebian
+printdebian:
+	@echo "$(DEBIAN)"
+
+configs-targets := updateconfigs defaultconfigs genconfigs editconfigs
+
+.PHONY: $(configs-targets)
+$(configs-targets):
+	dh_testdir
+	kmake='$(kmake)' skip_checks=$(do_skip_checks) conc_level=$(conc_level) \
+		$(SHELL) $(DROOT)/scripts/misc/kernelconfig $@
+
+.PHONY: printenv
+printenv:
+	@dh_testdir
+	@echo "src_pkg_name              = $(src_pkg_name)"
+	@echo "series                    = $(series)"
+	@echo "release                   = $(release)"
+	@echo "revision                  = $(revision)"
+	@echo "uploadnum                 = $(uploadnum)"
+	@echo "prev_revision             = $(prev_revision)"
+	@echo "abinum                    = $(abinum)"
+	@echo "upstream_tag              = $(upstream_tag)"
+	@echo "flavours                  = $(flavours)"
+	@echo "bin_pkg_name              = $(bin_pkg_name)"
+	@echo "hdr_pkg_name              = $(hdrs_pkg_name)"
+	@echo "rust_pkg_name             = $(rust_pkg_name)"
+	@echo "ubuntu_selftests          = $(ubuntu_selftests)"
+	@echo "arch                      = $(arch)"
+	@echo "kmake                     = $(kmake)"
+	@echo
+	@echo "CONCURRENCY_LEVEL         = $(CONCURRENCY_LEVEL)"
+	@echo "DEB_HOST_GNU_TYPE         = $(DEB_HOST_GNU_TYPE)"
+	@echo "DEB_BUILD_GNU_TYPE        = $(DEB_BUILD_GNU_TYPE)"
+	@echo "DEB_HOST_ARCH             = $(DEB_HOST_ARCH)"
+	@echo "DEB_BUILD_ARCH            = $(DEB_BUILD_ARCH)"
+	@echo
+	@echo "any_signed                = $(any_signed)"
+	@echo " uefi_signed              = $(uefi_signed)"
+	@echo " opal_signed              = $(opal_signed)"
+	@echo " sipl_signed              = $(sipl_signed)"
+	@echo
+	@echo "do_skip_checks            = $(do_skip_checks)"
+	@echo "do_full_build             = $(do_full_build)"
+	@echo "do_mainline_build         = $(do_mainline_build)"
+	@echo "do_dbgsym_package         = $(do_dbgsym_package)"
+	@echo "do_dtbs                   = $(do_dtbs)"
+	@echo "do_source_package         = $(do_source_package)"
+	@echo "do_source_package_content = $(do_source_package_content)"
+	@echo "do_extras_package         = $(do_extras_package)"
+	@echo "do_flavour_image_package  = $(do_flavour_image_package)"
+	@echo "do_flavour_header_package = $(do_flavour_header_package)"
+	@echo "do_common_headers_indep   = $(do_common_headers_indep)"
+	@echo "do_lib_rust               = $(do_lib_rust)"
+	@echo "do_tools                  = $(do_tools)"
+	@echo "do_tools_common           = $(do_tools_common)"
+	@echo "do_any_tools              = $(do_any_tools)"
+	@echo "do_linux_tools            = $(do_linux_tools)"
+	@echo " do_tools_acpidbg         = $(do_tools_acpidbg)"
+	@echo " do_tools_bpftool         = $(do_tools_bpftool)"
+	@echo " do_tools_cpupower        = $(do_tools_cpupower)"
+	@echo " do_tools_host            = $(do_tools_host)"
+	@echo " do_tools_perf            = $(do_tools_perf)"
+	@echo " do_tools_perf_jvmti      = $(do_tools_perf_jvmti)"
+	@echo " do_tools_perf_python     = $(do_tools_perf_python)"
+	@echo " do_tools_usbip           = $(do_tools_usbip)"
+	@echo " do_tools_x86             = $(do_tools_x86)"
+	@echo "do_cloud_tools            = $(do_cloud_tools)"
+	@echo " do_tools_hyperv          = $(do_tools_hyperv)"
+	@echo
+	@echo "all_dkms_modules          = $(all_dkms_modules)"
+	@$(foreach mod,$(all_dkms_modules),$(foreach var,$(do_$(mod)),\
+		printf " %-24s = %s\n" "do_$(mod)" "$(var)";))
+
+.PHONY: printchanges
+printchanges:
+	@baseCommit=$$(git log --pretty=format:'%H %s' | \
+		gawk '/UBUNTU: '".*Ubuntu-.*`echo $(prev_fullver) | sed 's/+/\\\\+/'`"'(~.*)?$$/ { print $$1; exit }'); \
+	if [ -z "$$baseCommit" ]; then \
+		echo "WARNING: couldn't find a commit for the previous version. Using the lastest one." >&2; \
+		baseCommit=$$(git log --pretty=format:'%H %s' | \
+			gawk '/UBUNTU:\s*Ubuntu-.*$$/ { print $$1; exit }'); \
+	fi; \
+	git log "$$baseCommit"..HEAD | \
+	$(DROOT)/scripts/misc/git-ubuntu-log
+
+.PHONY: insertchanges
+insertchanges: autoreconstruct finalchecks
+	$(DROOT)/scripts/misc/insert-changes $(DROOT) $(DEBIAN)
+
+.PHONY: autoreconstruct
+autoreconstruct:
+	# No need for reconstruct for -rc kernels since we don't upload an
+	# orig tarball, so just remove it.
+	if grep -q "^EXTRAVERSION = -rc[0-9]\+$$" Makefile; then \
+		echo "exit 0" >$(DEBIAN)/reconstruct; \
+	else \
+		$(DROOT)/scripts/misc/gen-auto-reconstruct $(upstream_tag) $(DEBIAN)/reconstruct $(DROOT)/source/options; \
+	fi
+
+.PHONY: finalchecks
+finalchecks: debian/control
+	$(DROOT)/scripts/checks/final-checks "$(DEBIAN)" "$(prev_fullver)" $(do_skip_checks)
+
+.PHONY: compileselftests
+compileselftests:
+	# a loop is needed here to fail on errors
+	for test in $(ubuntu_selftests); do \
+		$(kmake) -C tools/testing/selftests TARGETS="$$test"; \
+	done;
+
+.PHONY: runselftests
+runselftests:
+	$(kmake) -C tools/testing/selftests TARGETS="$(ubuntu_selftests)" run_tests
--- linux-qcom-6.8.0.orig/debian/rules.d/2-binary-arch.mk
+++ linux-qcom-6.8.0/debian/rules.d/2-binary-arch.mk
@@ -0,0 +1,803 @@
+# We don't want make removing intermediary stamps
+.SECONDARY :
+
+# TODO this is probably wrong, and should be using $(DEB_HOST_MULTIARCH)
+shlibdeps_opts = $(if $(CROSS_COMPILE),-- -l$(CROSS_COMPILE:%-=/usr/%)/lib)
+
+debian/scripts/fix-filenames: debian/scripts/fix-filenames.c
+	$(HOSTCC) $^ -o $@
+
+$(stampdir)/stamp-prepare-%: config-prepare-check-%
+	@echo Debug: $@
+	$(stamp)
+
+$(stampdir)/stamp-prepare-tree-%: target_flavour = $*
+$(stampdir)/stamp-prepare-tree-%: debian/scripts/fix-filenames
+	@echo Debug: $@
+	install -d $(builddir)/build-$*
+	touch $(builddir)/build-$*/ubuntu-build
+	python3 debian/scripts/misc/annotations --export --arch $(arch) --flavour $(target_flavour) > $(builddir)/build-$*/.config
+	sed -i 's/.*CONFIG_VERSION_SIGNATURE.*/CONFIG_VERSION_SIGNATURE="Ubuntu $(release)-$(revision)-$* $(raw_kernelversion)"/' $(builddir)/build-$*/.config
+	find $(builddir)/build-$* -name "*.ko" | xargs rm -f
+	$(kmake) O=$(builddir)/build-$* $(conc_level) rustavailable || true
+	$(kmake) O=$(builddir)/build-$* $(conc_level) olddefconfig
+	$(stamp)
+
+# Used by developers as a shortcut to prepare a tree for compilation.
+prepare-%: $(stampdir)/stamp-prepare-%
+	@echo Debug: $@
+# Used by developers to allow efficient pre-building without fakeroot.
+build-%: $(stampdir)/stamp-install-%
+	@echo Debug: $@
+
+# Do the actual build, including image and modules
+$(stampdir)/stamp-build-%: target_flavour = $*
+$(stampdir)/stamp-build-%: bldimg = $(call custom_override,build_image,$*)
+$(stampdir)/stamp-build-%: $(stampdir)/stamp-prepare-%
+	@echo Debug: $@ build_image $(build_image) bldimg $(bldimg)
+	$(kmake) O=$(builddir)/build-$* $(conc_level) $(bldimg) modules $(if $(filter true,$(do_dtbs)),dtbs)
+
+ifeq ($(do_dbgsym_package),true)
+	# The target scripts_gdb is part of "all", so we need to call it manually
+	if grep -q CONFIG_GDB_SCRIPTS=y $(builddir)/build-$*/.config; then \
+		$(kmake) O=$(builddir)/build-$* $(conc_level) scripts_gdb ; \
+	fi
+endif
+
+	# Collect the list of kernel source files used for this build. Need to do this early before
+	# modules are stripped. Fail if the resulting file is empty.
+	find $(builddir)/build-$* -name vmlinux -o -name \*.ko -exec dwarfdump -i {} \; | \
+		grep -E 'DW_AT_(call|decl)_file' | sed -n 's|.*\s/|/|p' | sort -u > \
+		$(builddir)/build-$*/sources.list
+	test -s $(builddir)/build-$*/sources.list
+
+	$(stamp)
+
+define build_dkms_sign =
+	$(shell set -x; if grep -q CONFIG_MODULE_SIG=y $(1)/.config; then
+			echo $(1)/scripts/sign-file $(MODHASHALGO) $(MODSECKEY) $(MODPUBKEY);
+		else
+			echo "-";
+		fi
+	)
+endef
+define build_dkms =
+	rc=0; unset MAKEFLAGS; ARCH=$(build_arch) CROSS_COMPILE=$(CROSS_COMPILE) $(SHELL) $(DROOT)/scripts/dkms-build $(dkms_dir) $(abi_release)-$* '$(call build_dkms_sign,$(builddir)/build-$*)' $(1) $(2) $(3) $(4) $(5) || rc=$$?; if [ "$$rc" = "9" -o "$$rc" = "77" ]; then echo do_$(4)_$*=false >> $(builddir)/skipped-dkms.mk; rc=0; fi; if [ "$$rc" != "0" ]; then exit $$rc; fi
+endef
+
+define install_control =
+	for which in $(3);							\
+	do									\
+		template="$(DROOT)/templates/$(2).$$which.in";			\
+		script="$(DROOT)/$(1).$$which";					\
+		sed -e 's/@abiname@/$(abi_release)/g'				\
+		    -e 's/@localversion@/-$*/g'					\
+		    -e 's/@image-stem@/$(instfile)/g'				\
+			<"$$template" >"$$script";				\
+	done
+endef
+
+# Ensure the directory prefix is exactly 140 characters long so pathnames are the
+# exact same length in any binary files produced by the builds.  These will be
+# commonised later.
+dkms_20d=....................
+dkms_140d=$(dkms_20d)$(dkms_20d)$(dkms_20d)$(dkms_20d)$(dkms_20d)$(dkms_20d)$(dkms_20d)
+dkms_140c=$(shell echo '$(dkms_140d)' | sed -e 's/\./_/g')
+define dkms_dir_prefix =
+$(shell echo $(1)/$(dkms_140c) | \
+	sed -e 's/\($(dkms_140d)\).*/\1/' -e 's/^\(.*\)....$$/\1dkms/')
+endef
+
+# Install the finished build
+$(stampdir)/stamp-install-%: pkgdir_bin = $(CURDIR)/debian/$(bin_pkg_name)-$*
+$(stampdir)/stamp-install-%: pkgdir = $(CURDIR)/debian/$(mods_pkg_name)-$*
+$(stampdir)/stamp-install-%: pkgdir_ex = $(CURDIR)/debian/$(mods_extra_pkg_name)-$*
+$(stampdir)/stamp-install-%: pkgdir_bldinfo = $(CURDIR)/debian/$(bldinfo_pkg_name)-$*
+$(stampdir)/stamp-install-%: bindoc = $(pkgdir)/usr/share/doc/$(bin_pkg_name)-$*
+$(stampdir)/stamp-install-%: dbgpkgdir = $(CURDIR)/debian/$(bin_pkg_name)-$*-dbgsym
+$(stampdir)/stamp-install-%: signingv = $(CURDIR)/debian/$(bin_pkg_name)-signing/$(release)-$(revision)
+$(stampdir)/stamp-install-%: toolspkgdir = $(CURDIR)/debian/$(tools_flavour_pkg_name)-$*
+$(stampdir)/stamp-install-%: cloudpkgdir = $(CURDIR)/debian/$(cloud_flavour_pkg_name)-$*
+$(stampdir)/stamp-install-%: basepkg = $(hdrs_pkg_name)
+$(stampdir)/stamp-install-%: baserustpkg = $(rust_pkg_name)
+$(stampdir)/stamp-install-%: indeppkg = $(indep_hdrs_pkg_name)
+$(stampdir)/stamp-install-%: kernfile = $(call custom_override,kernel_file,$*)
+$(stampdir)/stamp-install-%: instfile = $(call custom_override,install_file,$*)
+$(stampdir)/stamp-install-%: hdrdir = $(CURDIR)/debian/$(basepkg)-$*/usr/src/$(basepkg)-$*
+$(stampdir)/stamp-install-%: rustdir = $(CURDIR)/debian/$(baserustpkg)-$*/usr/src/$(baserustpkg)-$*
+$(stampdir)/stamp-install-%: target_flavour = $*
+$(stampdir)/stamp-install-%: MODHASHALGO=sha512
+$(stampdir)/stamp-install-%: MODSECKEY=$(builddir)/build-$*/certs/signing_key.pem
+$(stampdir)/stamp-install-%: MODPUBKEY=$(builddir)/build-$*/certs/signing_key.x509
+$(stampdir)/stamp-install-%: build_dir=$(builddir)/build-$*
+$(stampdir)/stamp-install-%: dkms_dir=$(call dkms_dir_prefix,$(builddir)/build-$*)
+$(foreach _m,$(all_dkms_modules), \
+  $(eval $$(stampdir)/stamp-install-%: enable_$(_m) = $$(filter true,$$(call custom_override,do_$(_m),$$*))) \
+  $(eval $$(stampdir)/stamp-install-%: dkms_$(_m)_pkgdir = $$(CURDIR)/debian/$(dkms_$(_m)_pkg_name)-$$*) \
+)
+$(stampdir)/stamp-install-%: dbgpkgdir_dkms = $(if $(filter true,$(do_dbgsym_package)),$(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/kernel,"")
+$(stampdir)/stamp-install-%: $(stampdir)/stamp-build-% $(stampdir)/stamp-install-headers
+	@echo Debug: $@ kernel_file $(kernel_file) kernfile $(kernfile) install_file $(install_file) instfile $(instfile)
+	dh_testdir
+	dh_prep -p$(bin_pkg_name)-$*
+	dh_prep -p$(mods_pkg_name)-$*
+	dh_prep -p$(hdrs_pkg_name)-$*
+ifeq ($(do_lib_rust),true)
+	dh_prep -p$(rust_pkg_name)-$*
+endif
+	$(foreach _m,$(all_standalone_dkms_modules), \
+	  $(if $(enable_$(_m)),dh_prep -p$(dkms_$(_m)_pkg_name)-$*;)\
+	)
+ifeq ($(do_dbgsym_package),true)
+	dh_prep -p$(bin_pkg_name)-$*-dbgsym
+endif
+ifeq ($(do_extras_package),true)
+	dh_prep -p$(mods_extra_pkg_name)-$*
+endif
+
+	# The main image
+	# compress_file logic required because not all architectures
+	# generate a zImage automatically out of the box
+ifeq ($(compress_file),)
+	install -m600 -D $(builddir)/build-$*/$(kernfile) \
+		$(pkgdir_bin)/boot/$(instfile)-$(abi_release)-$*
+else
+	install -d $(pkgdir_bin)/boot
+	gzip -c9v $(builddir)/build-$*/$(kernfile) > \
+		$(pkgdir_bin)/boot/$(instfile)-$(abi_release)-$*
+	chmod 600 $(pkgdir_bin)/boot/$(instfile)-$(abi_release)-$*
+endif
+	install -d $(pkgdir)/boot
+	install -m644 $(builddir)/build-$*/.config \
+		$(pkgdir)/boot/config-$(abi_release)-$*
+	install -m600 $(builddir)/build-$*/System.map \
+		$(pkgdir)/boot/System.map-$(abi_release)-$*
+
+ifeq ($(do_dtbs),true)
+	$(kmake) O=$(builddir)/build-$* $(conc_level) dtbs_install \
+		INSTALL_DTBS_PATH=$(pkgdir)/lib/firmware/$(abi_release)-$*/device-tree
+endif
+
+ifeq ($(no_dumpfile),)
+	makedumpfile -g $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* \
+		-x $(builddir)/build-$*/vmlinux
+	chmod 0600 $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$*
+endif
+
+	$(kmake) O=$(builddir)/build-$* $(conc_level) modules_install $(vdso) \
+		INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$(pkgdir)
+
+	#
+	# Build module blacklists:
+	#  - blacklist all watchdog drivers (LP:1432837)
+	#
+	install -d $(pkgdir)/lib/modprobe.d
+	echo "# Kernel supplied blacklist for $(src_pkg_name) $(abi_release)-$* $(arch)" \
+		>$(pkgdir)/lib/modprobe.d/blacklist_$(src_pkg_name)_$(abi_release)-$*.conf
+	for conf in $(arch)-$* $(arch) common.conf; do \
+		if [ -f $(DEBIAN)/modprobe.d/$$conf ]; then \
+			echo "# modprobe.d/$$conf"; \
+			cat $(DEBIAN)/modprobe.d/$$conf; \
+		fi; \
+	done >>$(pkgdir)/lib/modprobe.d/blacklist_$(src_pkg_name)_$(abi_release)-$*.conf
+	echo "# Autogenerated watchdog blacklist" \
+		>>$(pkgdir)/lib/modprobe.d/blacklist_$(src_pkg_name)_$(abi_release)-$*.conf
+	ls -1 $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/watchdog/ | \
+		grep -v '^bcm2835_wdt$$' | \
+		sed -e 's/^/blacklist /' -e 's/.ko$$//' | \
+		sort -u \
+		>>$(pkgdir)/lib/modprobe.d/blacklist_$(src_pkg_name)_$(abi_release)-$*.conf
+
+ifeq ($(do_extras_package),true)
+	#
+	# Remove all modules not in the inclusion list.
+	#
+	if [ -f $(DEBIAN)/control.d/$(target_flavour).inclusion-list ] ; then \
+		/sbin/depmod -v -b $(pkgdir) $(abi_release)-$* | \
+			sed -e "s@$(pkgdir)/lib/modules/$(abi_release)-$*/kernel/@@g" | \
+			awk '{ print $$1 " " $$NF}' >$(build_dir)/module-inclusion.depmap; \
+		mkdir -p $(pkgdir_ex)/lib/modules/$(abi_release)-$*; \
+		mv $(pkgdir)/lib/modules/$(abi_release)-$*/kernel \
+			$(pkgdir_ex)/lib/modules/$(abi_release)-$*/kernel; \
+		$(SHELL) $(DROOT)/scripts/module-inclusion --master \
+			$(pkgdir_ex)/lib/modules/$(abi_release)-$*/kernel \
+			$(pkgdir)/lib/modules/$(abi_release)-$*/kernel \
+			$(DEBIAN)/control.d/$(target_flavour).inclusion-list \
+			$(build_dir)/module-inclusion.depmap 2>&1 | \
+				tee $(target_flavour).inclusion-list.log; \
+		/sbin/depmod -b $(pkgdir) -ea -F $(pkgdir)/boot/System.map-$(abi_release)-$* \
+			$(abi_release)-$* 2>&1 |tee $(target_flavour).depmod.log; \
+		if [ `grep -c 'unknown symbol' $(target_flavour).depmod.log` -gt 0 ]; then \
+			echo "EE: Unresolved module dependencies in base package!"; \
+			exit 1; \
+		fi \
+	fi
+endif
+
+ifeq ($(no_dumpfile),)
+	makedumpfile -g $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* \
+		-x $(builddir)/build-$*/vmlinux
+	chmod 0600 $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$*
+endif
+	rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/build
+	rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/source
+
+	# Some initramfs-tools specific modules
+	install -d $(pkgdir)/lib/modules/$(abi_release)-$*/initrd
+	if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/video/vesafb.ko ]; then\
+	  $(LN) $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/video/vesafb.ko \
+		$(pkgdir)/lib/modules/$(abi_release)-$*/initrd/; \
+	fi
+
+	echo "interest linux-update-$(abi_release)-$*" >"$(DROOT)/$(bin_pkg_name)-$*.triggers"
+	install -d $(pkgdir_bin)/usr/lib/linux/triggers
+	$(call install_control,$(bin_pkg_name)-$*,image,postinst postrm preinst prerm)
+	install -d $(pkgdir)/usr/lib/linux/triggers
+	$(call install_control,$(mods_pkg_name)-$*,extra,postinst postrm)
+ifeq ($(do_extras_package),true)
+	# Install the postinit/postrm scripts in the extras package.
+	if [ -f $(DEBIAN)/control.d/$(target_flavour).inclusion-list ] ; then	\
+		install -d $(pkgdir_ex)/usr/lib/linux/triggers; \
+		$(call install_control,$(mods_extra_pkg_name)-$*,extra,postinst postrm); \
+	fi
+endif
+	$(foreach _m,$(all_standalone_dkms_modules), \
+	  $(if $(enable_$(_m)), \
+	    install -d $(dkms_$(_m)_pkgdir)/usr/lib/linux/triggers; \
+	    $(call install_control,$(dkms_$(_m)_pkg_name)-$*,extra,postinst postrm); \
+	  ) \
+	)
+
+ifeq ($(do_dbgsym_package),true)
+	# Debug image is simple
+	install -m644 -D $(builddir)/build-$*/vmlinux \
+		$(dbgpkgdir)/usr/lib/debug/boot/vmlinux-$(abi_release)-$*
+	if [ -d $(builddir)/build-$*/scripts/gdb/linux ]; then \
+		install -m644 -D $(builddir)/build-$*/vmlinux-gdb.py \
+			$(dbgpkgdir)/usr/share/gdb/auto-load/boot/vmlinux-$(abi_release)-$*/vmlinuz-$(abi_release)-$*-gdb.py; \
+		install -m644 -D $(builddir)/build-$*/scripts/gdb/linux/* \
+			--target-directory=$(dbgpkgdir)/usr/share/gdb/auto-load/boot/vmlinux-$(abi_release)-$*/scripts/gdb/linux; \
+	fi
+	$(kmake) O=$(builddir)/build-$* modules_install $(vdso) \
+		INSTALL_MOD_PATH=$(dbgpkgdir)/usr/lib/debug
+	# Add .gnu_debuglink sections only after all/DKMS modules are built.
+	rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/build
+	rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/source
+	rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/modules.*
+	rm -fr $(dbgpkgdir)/usr/lib/debug/lib/firmware
+endif
+ifeq ($(do_tools_bpftool),true)
+	cp $(builddir)/build-$*/vmlinux tools/bpf/bpftool/
+endif
+
+	# The flavour specific headers image
+	# TODO: Would be nice if we didn't have to dupe the original builddir
+	install -d -m755 $(hdrdir)
+	cp $(builddir)/build-$*/.config $(hdrdir)
+	chmod 644 $(hdrdir)/.config
+	$(kmake) O=$(hdrdir) -j1 syncconfig prepare scripts
+	# Makefile may need per-arch-flavour CC settings, which are
+	# normally set via $(kmake) during build
+	rm -f $(hdrdir)/Makefile
+	cp -a $(indep_hdrdir)/Makefile $(hdrdir)/Makefile
+	sed -i 's|\(^HOSTCC	= \)gcc$$|\1$(gcc)|' $(hdrdir)/Makefile
+	sed -i 's|\(^CC		= $$(CROSS_COMPILE)\)gcc$$|\1$(gcc)|' $(hdrdir)/Makefile
+	# Quick check for successful substitutions
+	grep '^HOSTCC	.*$(gcc)$$' $(hdrdir)/Makefile
+	grep '^CC	.*$(gcc)$$' $(hdrdir)/Makefile
+	rm -rf $(hdrdir)/include2 $(hdrdir)/source
+	# Copy over the compilation version.
+	cp "$(builddir)/build-$*/include/generated/compile.h" \
+		"$(hdrdir)/include/generated/compile.h"
+	# Add UTS_UBUNTU_RELEASE_ABI since UTS_RELEASE is difficult to parse.
+	echo "#define UTS_UBUNTU_RELEASE_ABI $(abinum)" >> $(hdrdir)/include/generated/utsrelease.h
+	# powerpc kernel arch seems to need some .o files for external module linking. Add them in.
+ifeq ($(build_arch),powerpc)
+	mkdir -p $(hdrdir)/arch/powerpc/lib
+	cp $(builddir)/build-$*/arch/powerpc/lib/*.o $(hdrdir)/arch/powerpc/lib
+endif
+ifeq ($(build_arch),s390)
+	if [ -n "$$(find $(builddir)/build-$*/arch/s390/lib/expoline -maxdepth 1 -name '*.o' -print -quit)" ]; then \
+		mkdir -p $(hdrdir)/arch/s390/lib/expoline/; \
+		cp $(builddir)/build-$*/arch/s390/lib/expoline/*.o $(hdrdir)/arch/s390/lib/expoline/; \
+	fi
+endif
+	# Copy over scripts/module.lds for building external modules
+	cp $(builddir)/build-$*/scripts/module.lds $(hdrdir)/scripts
+	# Script to symlink everything up
+	$(SHELL) $(DROOT)/scripts/link-headers "$(hdrdir)" "$(indeppkg)" "$*"
+	# The build symlink
+	install -d debian/$(basepkg)-$*/lib/modules/$(abi_release)-$*
+	$(LN) /usr/src/$(basepkg)-$* \
+		debian/$(basepkg)-$*/lib/modules/$(abi_release)-$*/build
+	# And finally the symvers
+	install -m644 $(builddir)/build-$*/Module.symvers \
+		$(hdrdir)/Module.symvers
+
+	# Now the header scripts
+	$(call install_control,$(hdrs_pkg_name)-$*,headers,postinst)
+
+	# At the end of the package prep, call the tests
+	DPKG_ARCH="$(arch)" KERN_ARCH="$(build_arch)" FLAVOUR="$*"	\
+	 VERSION="$(abi_release)" REVISION="$(revision)"		\
+	 PREV_REVISION="$(prev_revision)" ABI_NUM="$(abinum)"		\
+	 PREV_ABI_NUM="$(prev_abinum)" BUILD_DIR="$(builddir)/build-$*"	\
+	 INSTALL_DIR="$(pkgdir)" SOURCE_DIR="$(CURDIR)"			\
+	 run-parts -v $(DROOT)/tests-build
+
+	#
+	# Remove files which are generated at installation by postinst,
+	# except for modules.order and modules.builtin
+	#
+	# NOTE: need to keep this list in sync with postrm
+	#
+	mkdir $(pkgdir)/lib/modules/$(abi_release)-$*/_
+	mv $(pkgdir)/lib/modules/$(abi_release)-$*/modules.order \
+		$(pkgdir)/lib/modules/$(abi_release)-$*/_
+	if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin ] ; then \
+	    mv $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin \
+		$(pkgdir)/lib/modules/$(abi_release)-$*/_; \
+	fi
+	if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin.modinfo ] ; then \
+	    mv $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin.modinfo \
+		$(pkgdir)/lib/modules/$(abi_release)-$*/_; \
+	fi
+	rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.*
+	mv $(pkgdir)/lib/modules/$(abi_release)-$*/_/* \
+		$(pkgdir)/lib/modules/$(abi_release)-$*
+	rmdir $(pkgdir)/lib/modules/$(abi_release)-$*/_
+
+ifeq ($(do_linux_tools),true)
+	# Create the linux-tools tool links
+	install -d $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+ifeq ($(do_tools_usbip),true)
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/usbip $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/usbipd $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+endif
+ifeq ($(do_tools_acpidbg),true)
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/acpidbg $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+endif
+ifeq ($(do_tools_cpupower),true)
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/cpupower $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+endif
+ifeq ($(do_tools_rtla),true)
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/rtla $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+endif
+ifeq ($(do_tools_perf),true)
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/perf $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+ifeq ($(do_tools_perf_jvmti),true)
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/libperf-jvmti.so $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+endif
+ifeq ($(do_tools_perf_python),true)
+	# Link the subdirectory that contains the .so rather than the file itself. Its name is
+	# pseudo-random and can't be determined easily and reliably.
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/lib $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+endif
+endif
+ifeq ($(do_tools_bpftool),true)
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/bpftool $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+endif
+ifeq ($(do_tools_x86),true)
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/x86_energy_perf_policy $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/turbostat $(toolspkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+endif
+endif
+ifeq ($(do_cloud_tools),true)
+ifeq ($(do_tools_hyperv),true)
+	# Create the linux-hyperv tool links
+	install -d $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/hv_kvp_daemon $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/hv_vss_daemon $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/hv_fcopy_daemon $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+	$(LN) ../../$(src_pkg_name)-tools-$(abi_release)/lsvmbus $(cloudpkgdir)/usr/lib/linux-tools/$(abi_release)-$*
+endif
+endif
+
+	# Build a temporary "installed headers" directory.
+	install -d $(dkms_dir) $(dkms_dir)/headers $(dkms_dir)/build $(dkms_dir)/source
+	cp -rp "$(hdrdir)" "$(indep_hdrdir)" "$(dkms_dir)/headers"
+
+	$(foreach _m,$(all_dkms_modules), \
+	  $(if $(enable_$(_m)), \
+	    $(call build_dkms,$(dkms_$(_m)_pkg_name)-$*,$(dkms_$(_m)_pkgdir)/lib/modules/$(abi_release)-$*/$(dkms_$(_m)_subdir),$(dbgpkgdir_dkms),$(_m),$(dkms_$(_m)_debpath)); \
+	  ) \
+	)
+
+
+ifeq ($(do_dbgsym_package),true)
+	# Add .gnu_debuglink sections to each stripped .ko
+	# pointing to unstripped verson
+	find $(pkgdir) \
+	  $(if $(filter true,$(do_extras_package)),$(pkgdir_ex)) \
+	  -name '*.ko' | while read path_module ; do \
+		module="/lib/modules/$${path_module#*/lib/modules/}"; \
+		if [[ -f "$(dbgpkgdir)/usr/lib/debug/$$module" ]] ; then \
+			while IFS= read -r -d '' signature < <(tail -c 28 "$$path_module"); do \
+				break; \
+			done; \
+			$(CROSS_COMPILE)objcopy \
+				--add-gnu-debuglink=$(dbgpkgdir)/usr/lib/debug/$$module \
+				$$path_module; \
+			if grep -q CONFIG_MODULE_SIG=y $(builddir)/build-$*/.config && \
+			   [ "$$signature" = $$'~Module signature appended~\n' ]; then \
+				$(builddir)/build-$*/scripts/sign-file $(MODHASHALGO) \
+					$(MODSECKEY) \
+					$(MODPUBKEY) \
+					$$path_module; \
+			fi; \
+		else \
+			echo "WARNING: Missing debug symbols for module '$$module'."; \
+		fi; \
+	done
+endif
+
+	# Build the final ABI information.
+	install -d $(abidir)
+	sed -e 's/^\(.\+\)[[:space:]]\+\(.\+\)[[:space:]]\(.\+\)$$/\3 \2 \1/'	\
+		$(builddir)/build-$*/Module.symvers | sort > $(abidir)/$*
+
+	# Build the final ABI modules information.
+	find $(pkgdir_bin) $(pkgdir) $(pkgdir_ex) \( -name '*.ko' -o -name '*.ko.*' \) | \
+		sed -e 's/.*\/\([^\/]*\)\.ko.*/\1/' | sort > $(abidir)/$*.modules
+
+	# Build the final ABI built-in modules information.
+	if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin ] ; then \
+		sed -e 's/.*\/\([^\/]*\)\.ko/\1/' $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin | \
+			sort > $(abidir)/$*.modules.builtin; \
+	fi
+
+	# Build the final ABI firmware information.
+	find $(pkgdir_bin) $(pkgdir) $(pkgdir_ex) -name \*.ko | \
+	while read ko; do \
+		/sbin/modinfo $$ko | grep ^firmware || true; \
+	done | sort -u >$(abidir)/$*.fwinfo
+
+	# Build the final ABI built-in firmware information.
+	if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin.modinfo ] ; then \
+		cat $(pkgdir)/lib/modules/$(abi_release)-$*/modules.builtin.modinfo | \
+			tr '\0' '\n' | sed -n 's/^.*firmware=/firmware: /p' | \
+			sort -u > $(abidir)/$*.fwinfo.builtin; \
+	fi
+
+	# Build the final ABI compiler information.
+	ko=$$(find $(pkgdir_bin) $(pkgdir) $(pkgdir_ex) -name \*.ko | head -1); \
+	readelf -p .comment "$$ko" | gawk ' \
+		($$1 == "[") { \
+			printf("%s", $$3); \
+			for (n=4; n<=NF; n++) { \
+				printf(" %s", $$n); \
+			} \
+			print "" \
+		}' | sort -u >$(abidir)/$*.compiler
+
+	# Build the buildinfo package content.
+	install -d $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*
+	install -m644 $(builddir)/build-$*/.config \
+		$(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/config
+	install -m644 $(abidir)/$* \
+		$(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/abi
+	install -m644 $(abidir)/$*.modules \
+		$(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/modules
+	install -m644 $(abidir)/$*.fwinfo \
+		$(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/fwinfo
+	install -m644 $(abidir)/$*.compiler \
+		$(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/compiler
+	if [ -f $(abidir)/$*.modules.builtin ] ; then \
+		install -m644 $(abidir)/$*.modules.builtin \
+			$(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/modules.builtin; \
+	fi
+	if [ -f $(abidir)/$*.fwinfo.builtin ] ; then \
+		install -m644 $(abidir)/$*.fwinfo.builtin \
+			$(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/fwinfo.builtin; \
+	fi
+	install -m644 $(DROOT)/canonical-certs.pem $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/canonical-certs.pem
+	install -m644 $(DROOT)/canonical-revoked-certs.pem $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/canonical-revoked-certs.pem
+	# List of source files used for this build
+	install -m644 $(builddir)/build-$*/sources.list $(pkgdir_bldinfo)/usr/lib/linux/$(abi_release)-$*/sources
+
+	# Get rid of .o and .cmd artifacts in headers
+	find $(hdrdir) -name \*.o -or -name \*.cmd -exec rm -f {} \;
+	# Strip .so files (e.g., rust/libmacros.so) to reduce size even more
+	find $(hdrdir) -name libmacros.so -exec strip -s {} \;
+
+ifeq ($(do_lib_rust),true)
+	# Generate Rust lib files
+	install -d -m755 $(rustdir)
+	mv $(hdrdir)/rust $(rustdir)
+	# Generate symlink for Rust lib directory in headers
+	$(SHELL) $(DROOT)/scripts/link-lib-rust "$(hdrdir)" "$(indeppkg)" "$*"
+endif
+
+ifneq ($(do_full_build),false)
+	# Clean out this flavours build directory.
+	rm -rf $(builddir)/build-$*
+endif
+	$(call if_package, linux-libc-dev-$*, \
+		cp $(DEBIAN)/linux-libc-dev-$*.install debian/; \
+		dh_prep -p linux-libc-dev-$*; \
+		dh_install -p linux-libc-dev-$*)
+	$(stamp)
+
+headers_tmp := $(CURDIR)/debian/tmp-headers
+headers_dir := $(CURDIR)/debian/linux-libc-dev
+
+.PHONY: install-arch-headers
+install-arch-headers:
+	@echo Debug: $@
+	dh_testdir
+	dh_testroot
+	$(call if_package, linux-libc-dev, dh_prep -plinux-libc-dev)
+	rm -rf $(headers_tmp) $(headers_dir)
+	$(kmake) O=$(headers_tmp) INSTALL_HDR_PATH=$(headers_dir)/usr $(conc_level) headers_install
+	mkdir $(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH)
+	mv $(headers_dir)/usr/include/asm $(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH)/
+	rm -rf $(headers_tmp)
+
+define dh_all
+	dh_installchangelogs -p$(1)
+	dh_installdocs -p$(1)
+	dh_compress -p$(1)
+	# Compress kernel modules, on mantic+
+	$(if $(do_zstd_ko),find debian/$(1) -name '*.ko' -print0 | xargs -0 -n1 -P $(CONCURRENCY_LEVEL) -r zstd -19 --quiet --rm, true)
+	dh_fixperms -p$(1) -X/boot/
+	dh_shlibdeps -p$(1) $(shlibdeps_opts)
+	dh_installdeb -p$(1)
+	dh_installdebconf -p$(1)
+	$(lockme) dh_gencontrol -p$(1) -- -Vlinux:rprovides='$(rprovides)' $(2)
+	dh_md5sums -p$(1)
+	dh_builddeb -p$(1)
+endef
+define newline
+
+
+endef
+define dh_all_inline
+        $(subst ${newline},; \${newline},$(call dh_all,$(1),$(2)))
+endef
+
+.PHONY: binary-arch-headers
+binary-arch-headers: install-arch-headers
+	@echo Debug: $@
+	dh_testdir
+	dh_testroot
+	$(call if_package, linux-libc-dev, $(call dh_all,linux-libc-dev))
+
+-include $(builddir)/skipped-dkms.mk
+binary-%: pkgimg = $(bin_pkg_name)-$*
+binary-%: pkgimg_mods = $(mods_pkg_name)-$*
+binary-%: pkgimg_ex = $(mods_extra_pkg_name)-$*
+binary-%: pkgdir_ex = $(CURDIR)/debian/$(extra_pkg_name)-$*
+binary-%: pkgbldinfo = $(bldinfo_pkg_name)-$*
+binary-%: pkghdr = $(hdrs_pkg_name)-$*
+binary-%: pkgrust = $(rust_pkg_name)-$*
+binary-%: dbgpkg = $(bin_pkg_name)-$*-dbgsym
+binary-%: dbgpkgdir = $(CURDIR)/debian/$(bin_pkg_name)-$*-dbgsym
+binary-%: pkgtools = $(tools_flavour_pkg_name)-$*
+binary-%: pkgcloud = $(cloud_flavour_pkg_name)-$*
+$(foreach _m,$(all_dkms_modules), \
+  $(eval binary-%: enable_$(_m) = $$(filter true,$$(call custom_override,do_$(_m),$$*))) \
+)
+binary-%: rprovides = $(foreach _m,$(all_built-in_dkms_modules),$(if $(enable_$(_m)),$(foreach _r,$(dkms_$(_m)_rprovides),$(_r)$(comma) )))
+binary-%: target_flavour = $*
+binary-%: checks-%
+	@echo Debug: $@
+	dh_testdir
+	dh_testroot
+
+	$(call dh_all,$(pkgimg)) -- -Znone
+	$(call dh_all,$(pkgimg_mods))$(if $(do_zstd_ko), -- -Znone)
+
+ifeq ($(do_extras_package),true)
+  ifeq ($(ship_extras_package),false)
+	# If $(ship_extras_package) is explicitly set to false, then do not
+	# construct the linux-image-extra package; instead just log all of the
+	# "extra" modules which were pointlessly built yet won't be shipped.
+	find $(pkgdir_ex) -name '*.ko' | sort \
+		| sed 's|^$(pkgdir_ex)/|NOT-SHIPPED |' \
+		| tee -a $(target_flavour).not-shipped.log;
+  else
+	if [ -f $(DEBIAN)/control.d/$(target_flavour).inclusion-list ] ; then \
+		$(call dh_all_inline,$(pkgimg_ex))$(if $(do_zstd_ko), -- -Znone); \
+	fi
+  endif
+endif
+
+	$(foreach _m,$(all_standalone_dkms_modules), \
+	  $(if $(enable_$(_m)),$(call dh_all,$(dkms_$(_m)_pkg_name)-$*)$(if $(do_zstd_ko), -- -Znone);)\
+	)
+
+	$(call dh_all,$(pkgbldinfo))
+	$(call dh_all,$(pkghdr))
+ifeq ($(do_lib_rust),true)
+	$(call dh_all,$(pkgrust))
+endif
+
+ifeq ($(do_dbgsym_package),true)
+	$(call dh_all,$(dbgpkg)) -- -Zxz
+
+	# Hokay...here's where we do a little twiddling...
+	# Renaming the debug package prevents it from getting into
+	# the primary archive, and therefore prevents this very large
+	# package from being mirrored. It is instead, through some
+	# archive admin hackery, copied to http://ddebs.ubuntu.com.
+	#
+	mv ../$(dbgpkg)_$(release)-$(revision)_$(arch).deb \
+		../$(dbgpkg)_$(release)-$(revision)_$(arch).ddeb
+	$(lockme) sed -i '/^$(dbgpkg)_/s/\.deb /.ddeb /' debian/files
+	# Now, the package wont get into the archive, but it will get put
+	# into the debug system.
+
+	# Clean out the debugging package source directory.
+	rm -rf $(dbgpkgdir)
+endif
+
+ifeq ($(do_linux_tools),true)
+	$(call dh_all,$(pkgtools))
+endif
+ifeq ($(do_cloud_tools),true)
+	$(call dh_all,$(pkgcloud))
+endif
+ifeq ($(do_tools_bpftool),true)
+	$(call if_package, linux-bpf-dev, $(call dh_all,linux-bpf-dev))
+endif
+	$(call if_package, linux-libc-dev-$*, $(call dh_all,linux-libc-dev-$*))
+
+#
+# per-architecture packages
+#
+builddirpa = $(builddir)/tools-perarch
+
+$(stampdir)/stamp-prepare-perarch:
+	@echo Debug: $@
+ifeq ($(do_any_tools),true)
+	rm -rf $(builddirpa)
+	install -d $(builddirpa)
+	rsync -a --exclude debian --exclude debian.master --exclude $(DEBIAN) --exclude .git -a ./ $(builddirpa)/
+endif
+	$(stamp)
+
+$(stampdir)/stamp-build-perarch: $(stampdir)/stamp-prepare-perarch install-arch-headers build-arch
+	@echo Debug: $@
+ifeq ($(do_linux_tools),true)
+ifeq ($(do_tools_usbip),true)
+	chmod 755 $(builddirpa)/tools/usb/usbip/autogen.sh
+	cd $(builddirpa)/tools/usb/usbip && ./autogen.sh
+	chmod 755 $(builddirpa)/tools/usb/usbip/configure
+	cd $(builddirpa)/tools/usb/usbip && ./configure --prefix=$(builddirpa)/tools/usb/usbip/bin
+	cd $(builddirpa)/tools/usb/usbip && make install CFLAGS="-g -O2 -static" CROSS_COMPILE=$(CROSS_COMPILE)
+endif
+ifeq ($(do_tools_acpidbg),true)
+	cd $(builddirpa)/tools/power/acpi && make clean && make CFLAGS="-g -O2 -static -I$(builddirpa)/include" CROSS_COMPILE=$(CROSS_COMPILE) acpidbg
+endif
+ifeq ($(do_tools_rtla),true)
+	cd $(builddirpa)/tools/tracing/rtla && make clean && make CFLAGS='-g -O -Wall -I/usr/include/tracefs -I/usr/include/traceevent -DVERSION="\"6.8.1\""' static
+endif
+ifeq ($(do_tools_cpupower),true)
+	make -C $(builddirpa)/tools/power/cpupower \
+		CROSS_COMPILE=$(CROSS_COMPILE) \
+		CROSS=$(CROSS_COMPILE) \
+		STATIC=true \
+		CPUFREQ_BENCH=false
+endif
+ifeq ($(do_tools_perf),true)
+	cd $(builddirpa) && $(kmake) $(defconfig)
+	mv $(builddirpa)/.config $(builddirpa)/.config.old
+	sed -e 's/^# \(CONFIG_MODVERSIONS\) is not set$$/\1=y/' \
+	  -e 's/.*CONFIG_LOCALVERSION_AUTO.*/# CONFIG_LOCALVERSION_AUTO is not set/' \
+	  $(builddirpa)/.config.old > $(builddirpa)/.config
+	cd $(builddirpa) && $(kmake) syncconfig
+	cd $(builddirpa) && $(kmake) prepare
+	cd $(builddirpa)/tools/perf && \
+		$(kmake) prefix=/usr HAVE_CPLUS_DEMANGLE_SUPPORT=1 CROSS_COMPILE=$(CROSS_COMPILE) NO_LIBPERL=1 WERROR=0
+endif
+ifeq ($(do_tools_bpftool),true)
+	mv $(builddirpa)/tools/bpf/bpftool/vmlinux $(builddirpa)/vmlinux
+	$(kmake) CROSS_COMPILE=$(CROSS_COMPILE) -C $(builddirpa)/tools/bpf/bpftool
+ifneq ($(do_tools_bpftool_stub),true)
+	$(builddirpa)/tools/bpf/bpftool/bpftool btf dump file $(builddirpa)/vmlinux format c > $(builddirpa)/vmlinux.h
+else
+	echo '#error "Kernel does not support CONFIG_DEBUG_INFO_BTF"' > $(builddirpa)/vmlinux.h
+endif
+	rm -f $(builddirpa)/vmlinux
+endif
+ifeq ($(do_tools_x86),true)
+	cd $(builddirpa)/tools/power/x86/x86_energy_perf_policy && make CROSS_COMPILE=$(CROSS_COMPILE)
+	cd $(builddirpa)/tools/power/x86/turbostat && make CROSS_COMPILE=$(CROSS_COMPILE)
+endif
+endif
+ifeq ($(do_cloud_tools),true)
+ifeq ($(do_tools_hyperv),true)
+	cd $(builddirpa)/tools/hv && make CFLAGS="-I$(headers_dir)/usr/include -I$(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH)" CROSS_COMPILE=$(CROSS_COMPILE) hv_kvp_daemon hv_vss_daemon hv_fcopy_daemon
+endif
+endif
+	$(stamp)
+
+.PHONY: install-perarch
+install-perarch: toolspkgdir = $(CURDIR)/debian/$(tools_pkg_name)
+install-perarch: cloudpkgdir = $(CURDIR)/debian/$(cloud_pkg_name)
+install-perarch: $(stampdir)/stamp-build-perarch
+	@echo Debug: $@
+	# Add the tools.
+ifeq ($(do_linux_tools),true)
+	install -d $(toolspkgdir)/usr/lib
+	install -d $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release)
+ifeq ($(do_tools_usbip),true)
+	install -m755 $(addprefix $(builddirpa)/tools/usb/usbip/bin/sbin/, usbip usbipd) \
+		$(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release)
+endif
+ifeq ($(do_tools_acpidbg),true)
+	install -m755 $(builddirpa)/tools/power/acpi/acpidbg \
+		$(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release)
+endif
+ifeq ($(do_tools_cpupower),true)
+	install -m755 $(builddirpa)/tools/power/cpupower/cpupower \
+		$(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release)
+endif
+ifeq ($(do_tools_rtla),true)
+	install -m755 $(builddirpa)/tools/tracing/rtla/rtla-static \
+		$(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release)/rtla
+endif
+ifeq ($(do_tools_perf),true)
+	install -m755 $(builddirpa)/tools/perf/perf $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release)
+ifeq ($(do_tools_perf_jvmti),true)
+	install -m755 $(builddirpa)/tools/perf/libperf-jvmti.so $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release)
+endif
+ifeq ($(do_tools_perf_python),true)
+	install -d $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release)/lib
+	install -m644 $(builddirpa)/tools/perf/python/perf.*.so $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release)/lib
+endif
+endif
+ifeq ($(do_tools_bpftool),true)
+	install -m755 $(builddirpa)/tools/bpf/bpftool/bpftool $(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release)
+endif
+ifeq ($(do_tools_bpftool),true)
+	install -d -m755 $(CURDIR)/debian/linux-bpf-dev/usr/include/$(DEB_HOST_MULTIARCH)/linux/
+	install -m644 $(builddirpa)/vmlinux.h $(CURDIR)/debian/linux-bpf-dev/usr/include/$(DEB_HOST_MULTIARCH)/linux/vmlinux.h
+endif
+ifeq ($(do_tools_x86),true)
+	install -m755 \
+		$(addprefix $(builddirpa)/tools/power/x86/, x86_energy_perf_policy/x86_energy_perf_policy turbostat/turbostat) \
+		$(toolspkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release)
+endif
+endif
+ifeq ($(do_cloud_tools),true)
+ifeq ($(do_tools_hyperv),true)
+	install -d $(cloudpkgdir)/usr/lib
+	install -d $(cloudpkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release)
+	install -m755 $(addprefix $(builddirpa)/tools/hv/, hv_kvp_daemon hv_vss_daemon hv_fcopy_daemon lsvmbus) \
+		$(cloudpkgdir)/usr/lib/$(src_pkg_name)-tools-$(abi_release)
+endif
+endif
+
+.PHONY: binary-perarch
+binary-perarch: toolspkg = $(tools_pkg_name)
+binary-perarch: cloudpkg = $(cloud_pkg_name)
+binary-perarch: install-perarch
+	@echo Debug: $@
+ifeq ($(do_linux_tools),true)
+	$(call dh_all,$(toolspkg))
+endif
+ifeq ($(do_cloud_tools),true)
+	$(call dh_all,$(cloudpkg))
+endif
+
+.PHONY: binary-debs
+binary-debs: binary-perarch $(addprefix binary-,$(flavours))
+	@echo Debug: $@
+
+build-arch-deps-$(do_flavour_image_package) += $(addprefix $(stampdir)/stamp-install-,$(flavours))
+
+.PHONY: build-arch
+build-arch: $(build-arch-deps-true)
+	@echo Debug: $@
+
+binary-arch-deps-$(do_flavour_image_package) += binary-debs
+binary-arch-deps-true += binary-arch-headers
+ifneq ($(do_common_headers_indep),true)
+binary-arch-deps-$(do_flavour_header_package) += binary-headers
+endif
+
+.PHONY: binary-arch
+binary-arch: $(binary-arch-deps-true)
+	@echo Debug: $@
+
--- linux-qcom-6.8.0.orig/debian/rules.d/3-binary-indep.mk
+++ linux-qcom-6.8.0/debian/rules.d/3-binary-indep.mk
@@ -0,0 +1,213 @@
+.PHONY: build-indep
+build-indep:
+	@echo Debug: $@
+
+# The binary-indep dependency chain is:
+#
+# install-headers <- install-source <- install-tools <- install-indep <- binary-indep
+# install-headers <- binary-headers
+#
+indep_hdrpkg = $(indep_hdrs_pkg_name)
+indep_hdrdir = $(CURDIR)/debian/$(indep_hdrpkg)/usr/src/$(indep_hdrpkg)
+
+$(stampdir)/stamp-install-headers: $(stampdir)/stamp-prepare-indep
+	@echo Debug: $@
+	dh_testdir
+
+ifeq ($(do_flavour_header_package),true)
+	install -d $(indep_hdrdir)
+	find . -path './debian' -prune -o -path './$(DEBIAN)' -prune \
+	  -o -path './include/*' -prune \
+	  -o -path './scripts/*' -prune -o -type f \
+	  \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \
+	     -name '*.sh' -o -name '*.pl' -o -name '*.lds' \) \
+	  -print | cpio -pd --preserve-modification-time $(indep_hdrdir)
+	cp -a scripts include $(indep_hdrdir)
+	(find arch -name include -type d -print | \
+		xargs -n1 -i: find : -type f) | \
+		cpio -pd --preserve-modification-time $(indep_hdrdir)
+	# Do not ship .o and .cmd artifacts in headers
+	find $(indep_hdrdir) -name \*.o -or -name \*.cmd -exec rm -f {} \;
+endif
+	$(stamp)
+
+srcpkg = linux-source-$(release)
+srcdir = $(CURDIR)/debian/$(srcpkg)/usr/src/$(srcpkg)
+balldir = $(CURDIR)/debian/$(srcpkg)/usr/src/$(srcpkg)/$(srcpkg)
+install-source: $(stampdir)/stamp-prepare-indep
+	@echo Debug: $@
+ifeq ($(do_source_package),true)
+
+	install -d $(srcdir)
+ifeq ($(do_source_package_content),true)
+	find . -path './debian' -prune -o -path './$(DEBIAN)' -prune -o \
+		-path './.*' -prune -o -print | \
+		cpio -pd --preserve-modification-time $(balldir)
+	(cd $(srcdir); tar cf - $(srcpkg)) | bzip2 -9c > \
+		$(srcdir)/$(srcpkg).tar.bz2
+	rm -rf $(balldir)
+	$(LN) $(srcpkg)/$(srcpkg).tar.bz2 $(srcdir)/..
+endif
+endif
+
+.PHONY: install-tools
+install-tools: toolspkg = $(tools_common_pkg_name)
+install-tools: toolsbin = $(CURDIR)/debian/$(toolspkg)/usr/bin
+install-tools: toolssbin = $(CURDIR)/debian/$(toolspkg)/usr/sbin
+install-tools: toolsman = $(CURDIR)/debian/$(toolspkg)/usr/share/man
+install-tools: toolspython = $(CURDIR)/debian/$(toolspkg)/usr/lib/python3/dist-packages
+install-tools: toolsbashcomp = $(CURDIR)/debian/$(toolspkg)/usr/share/bash-completion/completions
+install-tools: hosttoolspkg = $(hosttools_pkg_name)
+install-tools: hosttoolsbin = $(CURDIR)/debian/$(hosttoolspkg)/usr/bin
+install-tools: hosttoolsman = $(CURDIR)/debian/$(hosttoolspkg)/usr/share/man
+install-tools: hosttoolssystemd = $(CURDIR)/debian/$(hosttoolspkg)/lib/systemd/system
+install-tools: cloudpkg = $(cloud_common_pkg_name)
+install-tools: cloudbin = $(CURDIR)/debian/$(cloudpkg)/usr/bin
+install-tools: cloudsbin = $(CURDIR)/debian/$(cloudpkg)/usr/sbin
+install-tools: cloudman = $(CURDIR)/debian/$(cloudpkg)/usr/share/man
+install-tools: $(stampdir)/stamp-prepare-indep $(stampdir)/stamp-build-perarch
+	@echo Debug: $@
+
+ifeq ($(do_tools_common),true)
+	rm -rf $(builddir)/tools
+	install -d $(builddir)/tools
+	for i in *; do $(LN) $(CURDIR)/$$i $(builddir)/tools/; done
+	rm $(builddir)/tools/tools
+	rsync -a tools/ $(builddir)/tools/tools/
+
+	install -d $(toolsbin)
+	install -d $(toolssbin)
+	install -d $(toolsman)/man1
+	install -d $(toolsman)/man8
+	install -d $(toolsbashcomp)
+	install -d $(toolspython)
+
+	install -m755 debian/tools/generic $(toolsbin)/usbip
+	install -m755 debian/tools/generic $(toolsbin)/usbipd
+	install -m644 $(CURDIR)/tools/usb/usbip/doc/*.8 $(toolsman)/man8/
+
+	install -m755 debian/tools/generic $(toolsbin)/cpupower
+	install -m644 $(CURDIR)/tools/power/cpupower/man/*.1 $(toolsman)/man1/
+
+	install -m755 debian/tools/generic $(toolsbin)/rtla
+
+	install -m755 debian/tools/generic $(toolsbin)/perf
+
+	install -m755 debian/tools/generic $(toolssbin)/bpftool
+	make -C $(builddir)/tools/tools/bpf/bpftool doc
+	install -m644 $(builddir)/tools/tools/bpf/bpftool/Documentation/*.8 \
+		$(toolsman)/man8
+	install -m644 $(builddir)/tools/tools/bpf/bpftool/bash-completion/bpftool \
+		$(toolsbashcomp)
+
+	install -m755 debian/tools/generic $(toolsbin)/x86_energy_perf_policy
+	install -m755 debian/tools/generic $(toolsbin)/turbostat
+
+	cd $(builddir)/tools/tools/perf && make man
+	install -m644 $(builddir)/tools/tools/perf/Documentation/*.1 \
+		$(toolsman)/man1
+
+	install -m644 $(CURDIR)/tools/power/x86/x86_energy_perf_policy/*.8 $(toolsman)/man8
+	install -m644 $(CURDIR)/tools/power/x86/turbostat/*.8 $(toolsman)/man8
+
+ifeq ($(do_tools_perf_python),true)
+	# Python wrapper module for python-perf
+	install -d $(toolspython)/perf
+	install -m644 debian/tools/python-perf.py $(toolspython)/perf/__init__.py
+endif
+ifeq ($(do_cloud_tools),true)
+ifeq ($(do_tools_hyperv),true)
+	install -d $(cloudsbin)
+	install -m755 debian/tools/generic $(cloudsbin)/hv_kvp_daemon
+	install -m755 debian/tools/generic $(cloudsbin)/hv_vss_daemon
+	install -m755 debian/tools/generic $(cloudsbin)/hv_fcopy_daemon
+	install -m755 debian/tools/generic $(cloudsbin)/lsvmbus
+	install -m755 debian/cloud-tools/hv_get_dhcp_info $(cloudsbin)
+	install -m755 debian/cloud-tools/hv_get_dns_info $(cloudsbin)
+	install -m755 debian/cloud-tools/hv_set_ifconfig $(cloudsbin)
+
+	install -d $(cloudman)/man8
+	install -m644 $(CURDIR)/tools/hv/*.8 $(cloudman)/man8
+endif
+endif
+
+ifeq ($(do_tools_acpidbg),true)
+	install -m755 debian/tools/generic $(toolsbin)/acpidbg
+endif
+
+endif
+
+ifeq ($(do_tools_host),true)
+	install -d $(hosttoolsbin)
+	install -d $(hosttoolsman)/man1
+	install -d $(hosttoolssystemd)
+
+	install -m 755 $(CURDIR)/tools/kvm/kvm_stat/kvm_stat $(hosttoolsbin)/
+	install -m 644 $(CURDIR)/tools/kvm/kvm_stat/kvm_stat.service \
+		$(hosttoolssystemd)/
+
+	cd $(builddir)/tools/tools/kvm/kvm_stat && make man
+	install -m644 $(builddir)/tools/tools/kvm/kvm_stat/*.1 \
+		$(hosttoolsman)/man1
+endif
+
+$(stampdir)/stamp-prepare-indep:
+	@echo Debug: $@
+	dh_prep -i
+	$(stamp)
+
+.PHONY: install-indep
+install-indep: $(stampdir)/stamp-install-headers install-source install-tools
+	@echo Debug: $@
+
+# This is just to make it easy to call manually. Normally done in
+# binary-indep target during builds.
+.PHONY: binary-headers
+binary-headers: $(stampdir)/stamp-prepare-indep $(stampdir)/stamp-install-headers
+	@echo Debug: $@
+	dh_installchangelogs -p$(indep_hdrpkg)
+	dh_installdocs -p$(indep_hdrpkg)
+	dh_compress -p$(indep_hdrpkg)
+	dh_fixperms -p$(indep_hdrpkg)
+	dh_installdeb -p$(indep_hdrpkg)
+	$(lockme) dh_gencontrol -p$(indep_hdrpkg)
+	dh_md5sums -p$(indep_hdrpkg)
+	dh_builddeb -p$(indep_hdrpkg)
+
+binary-indep: cloudpkg = $(cloud_common_pkg_name)
+binary-indep: hosttoolspkg = $(hosttools_pkg_name)
+binary-indep: install-indep
+	@echo Debug: $@
+	dh_installchangelogs -i
+	dh_installdocs -i
+	dh_compress -i
+	dh_fixperms -i
+ifeq ($(do_tools_common),true)
+ifeq ($(do_cloud_tools),true)
+ifeq ($(do_tools_hyperv),true)
+	dh_installinit -p$(cloudpkg) -n --name hv-kvp-daemon
+	dh_installinit -p$(cloudpkg) -n --name hv-vss-daemon
+	dh_installinit -p$(cloudpkg) -n --name hv-fcopy-daemon
+	dh_installudev -p$(cloudpkg) -n --name hv-kvp-daemon
+	dh_installudev -p$(cloudpkg) -n --name hv-vss-daemon
+	dh_installudev -p$(cloudpkg) -n --name hv-fcopy-daemon
+	dh_systemd_enable -p$(cloudpkg)
+	dh_installinit -p$(cloudpkg) -o --name hv-kvp-daemon
+	dh_installinit -p$(cloudpkg) -o --name hv-vss-daemon
+	dh_installinit -p$(cloudpkg) -o --name hv-fcopy-daemon
+	dh_systemd_start -p$(cloudpkg)
+endif
+	# Keep intel_sgx service disabled by default, so add it after dh_systemd_enable
+	# and dh_systemd_start are called:
+	dh_installinit -p$(cloudpkg) --no-start --no-enable --name intel-sgx-load-module
+endif
+endif
+ifeq ($(do_tools_host),true)
+	# Keep kvm_stat.service disabled by default (after dh_systemd_enable
+	# and dh_systemd_start:
+	dh_installinit -p$(hosttoolspkg) --no-enable --no-start --name kvm_stat
+endif
+	dh_installdeb -i
+	$(lockme) dh_gencontrol -i
+	dh_md5sums -i
+	dh_builddeb -i
--- linux-qcom-6.8.0.orig/debian/rules.d/4-checks.mk
+++ linux-qcom-6.8.0/debian/rules.d/4-checks.mk
@@ -0,0 +1,18 @@
+# Check the signature of staging modules
+module-signature-check-%: $(stampdir)/stamp-install-%
+	@echo Debug: $@
+	$(DROOT)/scripts/checks/module-signature-check "$*" \
+		"$(DROOT)/$(mods_pkg_name)-$*" \
+		"$(DROOT)/$(mods_extra_pkg_name)-$*" \
+		$(do_skip_checks)
+
+checks-%: module-signature-check-%
+	@echo Debug: $@
+
+# Check the config against the known options list.
+config-prepare-check-%: $(stampdir)/stamp-prepare-tree-%
+	@echo Debug: $@
+ifneq ($(do_skip_checks),true)
+	python3 $(DROOT)/scripts/misc/annotations -f $(commonconfdir)/annotations \
+		--arch $(arch) --flavour $* --check $(builddir)/build-$*/.config
+endif
--- linux-qcom-6.8.0.orig/debian/scripts/checks/final-checks
+++ linux-qcom-6.8.0/debian/scripts/checks/final-checks
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+debian="$1"
+abi="$2"
+
+archs=$(awk '/^Architecture:/ { $1=""; for (i=1; i<=NF; i++) { if ($i != "all") { print $i }}}' debian/control | sort -u)
+
+fail=0
+
+failure()
+{
+	echo "EE: $*" 1>&2
+	fail=1
+}
+
+for arch in $archs
+do
+	if [ ! -f "$debian/rules.d/$arch.mk" ]; then
+		continue
+	fi
+
+	image_pkg=$(awk -F '\\s*=\\s*' '$1 == "do_flavour_image_package" { print $2 }' "$debian/rules.d/$arch.mk")
+	if [ "$image_pkg" = "false" ]; then
+		continue
+	fi
+
+	flavours=$(
+		awk '/^\s*flavours\s*=/{
+			sub(/^\s*flavours\s*=\s*/, "");
+			print
+		}' "$debian/rules.d/$arch.mk")
+	for flavour in $flavours
+	do
+		if [ -d debian/certs ]; then
+			if ! python3 debian/scripts/misc/annotations --export -c CONFIG_SYSTEM_TRUSTED_KEYS --arch "$arch" --flavour "$flavour" | grep -q '^CONFIG_SYSTEM_TRUSTED_KEYS="debian/canonical-certs.pem"$' ; then
+				failure "'CONFIG_SYSTEM_TRUSTED_KEYS=\"debian/canonical-certs.pem\"' is required"
+			fi
+		fi
+		if [ -d debian/revoked-certs ]; then
+			if ! python3 debian/scripts/misc/annotations --export -c CONFIG_SYSTEM_REVOCATION_KEYS --arch "$arch" --flavour "$flavour" | grep -q '^CONFIG_SYSTEM_REVOCATION_KEYS="debian/canonical-revoked-certs.pem"$' ; then
+				failure "'CONFIG_SYSTEM_REVOCATION_KEYS=\"debian/canonical-revoked-certs.pem\"' is required"
+			fi
+		fi
+	done
+done
+
+exit "$fail"
--- linux-qcom-6.8.0.orig/debian/scripts/checks/module-signature-check
+++ linux-qcom-6.8.0/debian/scripts/checks/module-signature-check
@@ -0,0 +1,91 @@
+#!/bin/bash -eu
+
+flavor="${1}"
+mods_dir="${2}"
+mods_extra_dir="${3}"
+
+skip_checks=${4:-}
+case "${skip_checks,,}" in
+        1|true|yes) skip_checks=1 ;;
+        *) skip_checks=0 ;;
+esac
+
+echo "II: Checking signature of staging modules for ${flavor}..."
+
+root=$(dirname "$(realpath -e "${0}")")/../../..
+. "${root}"/debian/debian.env
+
+# Collect the signature-inclusion files
+sig_incs=()
+for d in debian "${DEBIAN}" ; do
+	if [ -f "${root}"/"${d}"/signature-inclusion ] ; then
+		sig_incs+=("${root}"/"${d}"/signature-inclusion)
+	fi
+done
+
+if [ "${#sig_incs[@]}" -gt 0 ] ; then
+	echo "II: Use signature inclusion file(s):"
+	printf "    %s\n" "${sig_incs[@]}"
+	sig_all=0
+else
+	echo "WW: Signature inclusion file(s) missing"
+	echo "II: All modules must be signed"
+	sig_all=1
+fi
+
+if ! [ -d "${mods_dir}" ] ; then
+	echo "EE: Modules directory missing:"
+	echo "    ${mods_dir}"
+	if [ ${skip_checks} -eq 1 ] ; then
+		echo "WW: Explicitly asked to ignore failures"
+		echo "II: Done"
+		exit 0
+	fi
+	exit 1
+fi
+
+echo "II: Checking modules directory:"
+echo "    ${mods_dir}"
+mods_dirs=("${mods_dir}")
+
+if [ -d "${mods_extra_dir}" ] ; then
+	echo "    ${mods_extra_dir}"
+	mods_dirs+=("${mods_extra_dir}")
+fi
+
+pass=0
+fail=0
+while IFS= read -r mod ; do
+	is=0
+	if /sbin/modinfo "${mod}" | grep -q "^signature:" ; then
+		# Module is signed
+		is=1
+	fi
+
+	must=0
+	if [ ${sig_all} -eq 1 ] || grep -qFx "${mod##*/}" "${sig_incs[@]}" ; then
+		# Module must be signed
+		must=1
+	fi
+
+	case "${is}${must}" in
+		00) echo "    PASS (unsigned) : ${mod##*/}" ; pass=$((pass + 1)) ;;
+		01) echo "    FAIL (unsigned) : ${mod##*/}" ; fail=$((fail + 1)) ;;
+		10) echo "    FAIL (signed)   : ${mod##*/}" ; fail=$((fail + 1)) ;;
+		11) echo "    PASS (signed)   : ${mod##*/}" ; pass=$((pass + 1)) ;;
+	esac
+done < <(find "${mods_dirs[@]}" -path '*/drivers/staging/*.ko' | sort)
+
+echo "II: Checked $((pass + fail)) modules : ${pass} PASS, ${fail} FAIL"
+
+if [ ${fail} -ne 0 ] ; then
+	if [ ${skip_checks} -eq 1 ] ; then
+		echo "WW: Explicitly asked to ignore failures"
+	else
+		echo "EE: Modules signature failures"
+		exit 1
+	fi
+fi
+
+echo "II: Done"
+exit 0
--- linux-qcom-6.8.0.orig/debian/scripts/control-create
+++ linux-qcom-6.8.0/debian/scripts/control-create
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+. debian/debian.env
+
+vars=$1
+any_signed=$2
+
+. $vars
+
+[ "$provides" != '' ] && provides="$provides, "
+
+flavour=$(basename $vars | sed 's/.*\.//')
+stub="${DEBIAN}/control.d/flavour-control.stub debian/control.d/flavour-buildinfo.stub"
+if [ "$any_signed" = 'true' ]; then
+	sign_me_pkg="-unsigned"
+	sign_me_txt=" unsigned"
+	sign_peer_pkg=""
+else
+	sign_me_pkg=""
+	sign_me_txt=""
+	sign_peer_pkg="-unsigned"
+fi
+
+cat $stub | grep -v '^#' | sed \
+	-e "s#FLAVOUR#$flavour#g"		\
+	-e "s#DESC#$desc#g"			\
+	-e "s#ARCH#$arch#g"			\
+	-e "s#SUPPORTED#$supported#g"		\
+	-e "s#TARGET#$target#g"			\
+	-e "s#BOOTLOADER#$bootloader#g" 	\
+	-e "s#=PROVIDES=#$provides#g"		\
+	-e "s#=CONFLICTS=#$conflicts#g"		\
+	-e "s#=SIGN-ME-PKG=#$sign_me_pkg#g"	\
+	-e "s#=SIGN-ME-TXT=#$sign_me_txt#g"	\
+	-e "s#=SIGN-PEER-PKG=#$sign_peer_pkg#g"
+
+while read package version extras
+do
+	module="$package"
+	module_type=
+
+	# Module arch parameters are skipped here, so a package section will
+	# be generated for each flavour, and its Architecture will be set to
+	# all architectures with that flavour. Even that is being generated,
+	# it doesn't follow all of them will be built. That's to work-around
+	# dkms_exclude/dkms_include that manipulates supported architectures
+	# in $(DEBIAN)/rules.d/$(arch).mk.
+	for param in $extras; do
+		case "$param" in
+		modulename=*) module="${param#modulename=}" ;;
+		type=*) module_type="${param#type=}" ;;
+		*) continue ;;
+		esac
+	done
+
+	[ "$module_type" = "standalone" ] || continue
+
+	cat debian/control.d/flavour-module.stub | grep -v '^#' | sed	\
+		-e "s#ARCH#$arch#g"		\
+		-e "s#MODULE#$module#g"		\
+		-e "s#FLAVOUR#$flavour#g"
+done <"${DEBIAN}/dkms-versions"
--- linux-qcom-6.8.0.orig/debian/scripts/dkms-build
+++ linux-qcom-6.8.0/debian/scripts/dkms-build
@@ -0,0 +1,271 @@
+#!/bin/sh
+set -e
+
+dkms_dir="$1"
+abi_flavour="$2"
+sign="$3"
+pkgname="$4"
+pkgdir="$5"
+dbgpkgdir="$6"
+package="$7"
+shift 7
+
+here=$(dirname "$(readlink -f "${0}")")
+
+srcdir=$(pwd)
+cd "$dkms_dir" || exit 1
+
+built_using_record()
+{
+	local subst="$1"
+	local built_using="$2"
+	if [ ! -f "$subst" ]; then
+		touch "$subst"
+	fi
+	if ! grep -q -s "^linux:BuiltUsing=" "$subst"; then
+		echo "linux:BuiltUsing=" >>"$subst"
+	fi
+	sed -i -e "s/^\(linux:BuiltUsing=.*\)/\1$built_using, /" "$subst"
+}
+
+# ABI: returns present in $? and located path in lpackage_path when found.
+package_present()
+{
+	for lpackage_path in "$1"_*.deb
+	do
+		break
+	done
+	[ -f "$lpackage_path" ]
+}
+
+# Download and extract the DKMS package -- note there may be more
+# than one package to install.
+for package_path in "$@"
+do
+	package_file=$(basename "$package_path")
+	echo "II: dkms-build downloading $package ($package_file)"
+	rpackage=$( echo "$package_path" | sed -e 's@.*/@@' -e 's@_.*@@' )
+	lpackage=$( echo "$rpackage" | sed -e 's@=.*@@' )
+
+	while true
+	do
+		if package_present "$lpackage"; then
+			break
+		fi
+		case "$package_path" in
+		pool/*)
+			# Attempt download from the launchpad librarian first.
+			"$here/file-downloader" "https://launchpad.net/ubuntu/+archive/primary/+files/$package_file" || true
+			if package_present "$lpackage"; then
+				break
+			fi
+
+			# Download from the available pools.
+			for pool in $( grep -h '^deb ' /etc/apt/sources.list /etc/apt/sources.list.d/*.list | awk '{print $2}' | sort -u )
+			do
+				if package_present "$lpackage"; then
+					break
+				fi
+				url="$pool/$package_path"
+				"$here/file-downloader" "$url" && break || true
+				# No components in PPAs.
+				url=$(echo "$url" | sed -e 's@/pool/[^/]*/@/pool/main/@')
+				"$here/file-downloader" "$url" && break || true
+			done
+			;;
+		http*:*)
+			"$here/file-downloader" "$package_path"
+			;;
+		*/*)
+			cp -p "$package_path" .
+			;;
+		*)
+			apt-get download "$rpackage"
+			;;
+		esac
+		break
+	done
+	if ! package_present "$lpackage"; then
+		echo "EE: $lpackage not found"
+		exit 1
+	fi
+
+	dpkg -x "$lpackage"_*.deb "$package"
+
+	lversion=$( echo "$lpackage_path" | sed -e 's@.*/@@' -e 's@_[^_]*$@@' -e 's@.*_@@')
+	#built_using_record "$srcdir/debian/$pkgname.substvars" "$built_using$lpackage (= $lversion)"
+done
+
+# Pick out the package/version from the dkms.conf.
+for dkms_conf in "$package/usr/src"/*/"dkms.conf"
+do
+	break
+done
+
+# It seems some packages have a # in the name which works fine if the
+# package is installed directly, but not so much if we build it out
+# of the normal location.
+sed -i -e '/^PACKAGE_NAME=/ s/#//g' "$dkms_conf"
+
+# Run any dkms-package specfic configuration steps
+dkms_config_specific="$srcdir/$0-configure--$package"
+dkms_config_generic=$(echo "$dkms_config_specific" | sed -e 's/-[0-9][0-9]*$/-N/')
+for dkms_config in "$dkms_config_specific" "$dkms_config_generic"
+do
+	if [ -z "$dkms_config" -o ! -e "$dkms_config" ]; then
+		continue
+	fi
+	echo "II: dkms-build-configure $(basename "$dkms_config") found, executing"
+	"$dkms_config" \
+		"$srcdir" \
+		"$dkms_conf" \
+		"$dkms_dir" \
+		"$abi_flavour" \
+		"$sign" \
+		"$pkgname" \
+		"$pkgdir" \
+		"$dbgpkgdir" \
+		"$package" \
+		"$@" || exit 1
+	break
+done
+
+cat - <<'EOF' >>"$dkms_conf"
+POST_BUILD="ubuntu-save-objects ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build ${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/objects $POST_BUILD"
+EOF
+ubuntu_script="$(dirname "$dkms_conf")/ubuntu-save-objects"
+cat - <<'EOF' >"$ubuntu_script"
+#!/bin/sh
+from="$1"
+to="$2"
+script="$3"
+shift 2
+
+# Copy the objects.
+echo "II: copying objects to '$to'"
+mkdir -p "$to"
+(cd "$from" && find -name \*.o -o -name \*.mod | cpio -Lpd "$to")
+
+# Call the original post_install script if there is one.
+[ "$script" = '' ] && exit 0
+
+shift
+exec "$(dirname "$0")/$script" "$@"
+EOF
+chmod +x "$ubuntu_script"
+dkms_package=$( sed -ne 's/PACKAGE_NAME="\(.*\)"/\1/p' "$dkms_conf" )
+dkms_version=$( sed -ne 's/PACKAGE_VERSION="\(.*\)"/\1/p' "$dkms_conf" )
+
+# Build the DKMS binaries.
+echo "II: dkms-build building $package"
+fakeroot=""
+[ $(id -u) -ne 0 ] && fakeroot="/usr/bin/fakeroot"
+rc=0
+$fakeroot /usr/sbin/dkms build --no-prepare-kernel --no-clean-kernel \
+	-k "$abi_flavour" ${ARCH:+-a $ARCH} \
+	--sourcetree "$dkms_dir/source" \
+	--dkmstree "$dkms_dir/build" \
+	--kernelsourcedir "$dkms_dir/headers/linux-headers-$abi_flavour" \
+	"$dkms_conf" || rc=$?
+
+# Find the log and add it to our own.
+for log in "$dkms_dir/build/$dkms_package/$dkms_version/$abi_flavour"/*/"log/make.log" "$dkms_dir/build/$dkms_package/$dkms_version/build/make.log"
+do
+	if [ -f "$log" ]; then
+		sed -e "s@$dkms_dir@<<DKMSDIR>>@g" <"$log"
+		break
+	fi
+done
+
+# If this build failed then exit here.
+[ "$rc" != 0 ] && exit "$rc"
+
+# Install the modules with debug symbols we possibly built,
+# and strip the original modules for the next install step.
+if [ -n "$dbgpkgdir" ]; then
+	dbgpkgdir="$dbgpkgdir/$package"
+	echo "II: dkms-build installing $package into $dbgpkgdir (debug symbols)"
+	install -d "$dbgpkgdir"
+	find "$dkms_dir/build/$dkms_package/$dkms_version/$abi_version" -name \*.ko |
+	while read module; do
+		vmodule=$( basename "$module" )
+
+		# Check for '.debug_info' section in order to copy module.
+		# Useful if debug symbols are requested but not built for
+		# any reason (including not yet supported by DKMS package).
+		# Strip module just in case even if section isn't present.
+		if ${CROSS_COMPILE}objdump -h -j '.debug_info' "$module" >/dev/null 2>&1
+		then
+			echo "copying $vmodule"
+			cp "$module" "$dbgpkgdir"
+		else
+			echo "ignoring $vmodule (missing debug symbols)"
+		fi
+
+		# Just 'strip -g' as '/usr/sbin/dkms' does.
+		echo "stripping $vmodule"
+		strip -g "$module"
+	done
+fi
+
+# Install and optionally sign the modules we have built.
+pkgdir="$pkgdir/$package"
+echo "II: dkms-build installing $package into $pkgdir"
+install -d "$pkgdir"
+find "$dkms_dir/build/$dkms_package/$dkms_version/$abi_version" -name \*.ko |
+while read module; do
+	vmodule=$( basename "$module" )
+	case "$sign" in
+	--*)
+		echo "copying $vmodule"
+		cp "$module" "$pkgdir"
+		;;
+	*)
+		echo "signing $vmodule"
+		$sign "$module" "$pkgdir/$vmodule"
+		;;
+	esac
+done
+
+find "$dkms_dir/build/$dkms_package/$dkms_version/objects" -name \*.o -print | \
+while read object
+do
+	"$srcdir/debian/scripts/fix-filenames" "$object" "$dkms_dir"
+done
+
+# This assumes that .mod files are in the top level build tree
+# If there are ever .mod files in sub-directories, the dirname of objectlist needs to be stripped as well
+find "$dkms_dir/build/$dkms_package/$dkms_version/objects" -name \*.mod -print | \
+while read objectlist
+do
+	sed "s|^$dkms_dir/build/$dkms_package/$dkms_version/build/||" -i $objectlist
+done
+
+# Finally see if there is a dkms-package specific post processor present.  Hand
+# it the original source directory, destination package directory, the objects
+# as squirreled away, and the log in case it is useful.  Finally pass a formed
+# signing command line in case we need to do that.
+dkms_build_specific="$srcdir/$0--$package"
+dkms_build_generic=$(echo "$dkms_build_specific" | sed -n -e 's/-[0-9][0-9]*[a-z]*$/-N/p')
+for dkms_build in "$dkms_build_specific" "$dkms_build_generic"
+do
+	if [ -z "$dkms_build" -o ! -e "$dkms_build" ]; then
+		continue
+	fi
+	echo "II: dkms-build override $(basename "$dkms_build") found, executing"
+	"$dkms_build" \
+		"$srcdir" \
+		"$dkms_dir/build/$dkms_package/$dkms_version/objects" \
+		"$log" \
+		"$dkms_dir" \
+		"$abi_flavour" \
+		"$sign" \
+		"$pkgname" \
+		"$pkgdir" \
+		"$dbgpkgdir" \
+		"$package" \
+		"$@" || exit 1
+	break
+done
+
+echo "II: dkms-build build $package complete"
--- linux-qcom-6.8.0.orig/debian/scripts/dkms-build--nvidia-N
+++ linux-qcom-6.8.0/debian/scripts/dkms-build--nvidia-N
@@ -0,0 +1,112 @@
+#!/bin/sh
+set -e
+
+srcdir="$1"
+objects="$2"
+log="$3"
+shift 3
+
+dkms_dir="$1"
+abi_flavour="$2"
+sign="$3"
+pkgname="$4"
+pkgdir="$5"
+dbgpkgdir="$6"
+package="$7"
+shift 7
+
+build="$( dirname "$objects" )/build"
+
+# Copy over the objects ready for reconstruction.  The objects copy
+# contains the *.o files. For our purposes we only want the *.o files,
+# elide the rest. And .mod files for ld linking in recentish kernels.
+mkdir -p "$pkgdir/bits/scripts"
+(
+	gcc_variant1=$(gcc --version | head -1 | sed -e 's/^gcc/GCC:/')
+	gcc_variant2=$(gcc --version | head -1 | sed -e 's/^\(gcc\) \((.*)\) \(.*\)$/\1 version \3 \2/')
+	cd "$objects" || exit 1
+	find -name \*.o -o -name \*.mod | \
+	while read file
+	do
+		cp --parents "$file" "$pkgdir/bits"
+		"$srcdir/debian/scripts/fix-filenames" "$pkgdir/bits/$file" "$gcc_variant1"
+		"$srcdir/debian/scripts/fix-filenames" "$pkgdir/bits/$file" "$gcc_variant2"
+	done
+)
+
+# Install the support files we need.
+echo "II: copying support files ..."
+for lds_src in \
+	"$dkms_dir/headers/linux-headers-$abi_flavour/scripts/module.lds" \
+	"/usr/src/linux-headers-$abi_flavour/scripts/module.lds" \
+	"$dkms_dir/headers/linux-headers-$abi_flavour/scripts/module-common.lds" \
+	"/usr/src/linux-headers-$abi_flavour/scripts/module-common.lds"
+do
+	[ ! -f "$lds_src" ] && continue
+	echo "II: copying support files ... found $lds_src"
+	cp "$lds_src" "$pkgdir/bits/scripts"
+	break
+done
+
+# Build helper scripts.
+cat - <<'EOL' >"$pkgdir/bits/BUILD"
+[ "$1" = "unsigned" ] && { signed_only=:; shift; }
+[ "$1" = "nocheck" ] && { check_only=:; shift; }
+EOL
+grep /usr/bin/ld.bfd "$log" | grep -v scripts/genksyms/genksyms | grep -v "warning:\|NOTE:" | sed -e "s@$build/@@g" >>"$pkgdir/bits/BUILD"
+sed -e 's/.*-o  *\([^ ]*\) .*/rm -f \1/g' <"$pkgdir/bits/BUILD" >"$pkgdir/bits/CLEAN"
+
+# As the builds contain the absolute filenames as used.  Use RECONSTRUCT to
+# rebuild the .ko's, sign them, pull off the signatures and then finally clean
+# up again.
+(
+	cd "$pkgdir/bits"
+
+	# Add checksum check.
+	echo "\$check_only sha256sum -c SHA256SUMS || exit 1" >>"$pkgdir/bits/BUILD"
+
+	# Add .ko handling to the CLEAN/BUILD dance.
+	for ko in "$pkgdir"/*.ko
+	do
+		ko=$(basename "$ko")
+		echo "\$signed_only cat '$ko' '$ko.sig' >'../$ko'" >>"$pkgdir/bits/BUILD"
+		echo "\$signed_only rm -f '$ko'" >>"$pkgdir/bits/BUILD"
+		echo "rm -f '../$ko'" >>"$pkgdir/bits/CLEAN"
+	done
+
+	# Clear out anything we are not going to distribute and build unsigned .kos.
+	sh ./CLEAN
+	sh ./BUILD unsigned nocheck
+
+	if [ "$sign" = "--custom" ]; then
+		# We are building for and archive custom signing upload.  Keep everything.
+		:
+	elif [ "$sign" = "--lrm" ]; then
+		# We are in the LRM build; grab sha256 checksums and clean up.
+		sha256sum -b *.ko >"SHA256SUMS"
+		sh ./CLEAN
+
+	else
+		# We are in the main kernel, put the .kos together as we will
+		# on the users machine, sign them, and keep just the signature.
+		: >"SHA256SUMS"
+		for ko in *.ko
+		do
+			echo "detached-signature $ko"
+			$sign "$ko" "$ko.signed"
+			length=$( stat --format %s "$ko" )
+			dd if="$ko.signed" of="$ko.sig" bs=1 skip="$length" 2>/dev/null
+
+			rm -f "$ko.signed"
+			# Keep a checksum of the pre-signed object so we can check it is
+			# built correctly in LRM.
+			sha256sum -b "$ko" >>"SHA256SUMS"
+		done
+
+		# Clean out anything which not a signature.
+		mv "$pkgdir/bits/"*.sig "$pkgdir"
+		mv "$pkgdir/bits/SHA256SUMS" "$pkgdir"
+		find "$pkgdir" -name \*.sig -prune -o -name SHA256SUMS -prune -o -type f -print | xargs rm -f
+		find "$pkgdir" -depth -type d -print | xargs rmdir --ignore-fail-on-non-empty
+	fi
+)
--- linux-qcom-6.8.0.orig/debian/scripts/dkms-build-configure--zfs
+++ linux-qcom-6.8.0/debian/scripts/dkms-build-configure--zfs
@@ -0,0 +1,24 @@
+#!/bin/sh
+set -e
+
+srcdir="$1"
+dkms_conf="$2"
+shift 2
+
+dkms_dir="$1"
+abi_flavour="$2"
+sign="$3"
+pkgname="$4"
+pkgdir="$5"
+dbgpkgdir="$6"
+package="$7"
+shift 7
+
+# ZFS debug symbols are enabled in dkms.conf via PACKAGE_CONFIG file.
+if [ -n "$dbgpkgdir" ]; then
+	echo "enable zfs debug symbols"
+	pkg_cfg="$(dirname "$dkms_conf")/pkg_cfg"
+	echo 'ZFS_DKMS_ENABLE_DEBUGINFO=yes' >"$pkg_cfg"
+	echo 'ZFS_DKMS_DISABLE_STRIP=yes'   >>"$pkg_cfg"
+	sed -i "s,^\(PACKAGE_CONFIG=\).*,\1$pkg_cfg," $dkms_conf
+fi
--- linux-qcom-6.8.0.orig/debian/scripts/file-downloader
+++ linux-qcom-6.8.0/debian/scripts/file-downloader
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+if [ "$#" -ne 1 ]; then
+	echo "Usage: $0 <url>" 1>&2
+	exit 1
+fi
+url="$1"
+
+to=$(basename "$url")
+
+count=0
+what='fetching'
+while :
+do
+	if [ "$count" -eq 20 ]; then
+		echo "EE: excessive redirects" 1>&2
+		exit 1
+	fi
+	count=$(($count+1))
+
+	echo "II: $what $url"
+
+	curl --silent --fail --show-error "$url" -o "$to" -D "$to.hdr" || exit 1
+	redirect=$(awk '/^Location: / {gsub(/^[[:space:]]+|[[:space:]]+$/,"",$2); print $2;}' "$to.hdr")
+	[ -z "$redirect" ] && break
+	what='  following'
+
+	url=$(echo "$redirect" | sed -e 's@https://launchpadlibrarian.net/@http://launchpadlibrarian.net/@')
+	if [ "$redirect" != "$url" ]; then
+		echo "II:   fixing $redirect"
+	fi
+done
+
+exit 0
--- linux-qcom-6.8.0.orig/debian/scripts/fix-filenames.c
+++ linux-qcom-6.8.0/debian/scripts/fix-filenames.c
@@ -0,0 +1,80 @@
+/*
+ * fix-filenames: find a specified pathname prefix and remove it from
+ *                C strings.
+ *
+ * Copyright (C) 2018 Canonical Ltd.
+ * Author: Andy Whitcroft <apw@canonical.com>
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+int
+main(int argc, char *argv[])
+{
+	int rc;
+	char *in_name;
+	char *prefix;
+	int prefix_len;
+	int in_fd;
+	struct stat in_info;
+	char *in;
+	off_t size;
+	int length;
+
+	if (argc != 3) {
+		fprintf(stderr, "Usage: %s <file> <prefix>\n", argv[0]);
+		exit(1);
+	}
+	in_name    = argv[1];
+	prefix     = argv[2];
+	prefix_len = strlen(prefix);
+
+	in_fd = open(in_name, O_RDWR);
+	if (in_fd < 0) {
+		perror("open input failed");
+		exit(1);
+	}
+
+	rc = fstat(in_fd, &in_info);
+	if (rc < 0) {
+		perror("fstat input failed");
+		exit(1);
+	}
+	size = in_info.st_size;
+
+	in = mmap((void *)0, size, PROT_READ|PROT_WRITE, MAP_SHARED, in_fd, (off_t)0);
+	if (!in) {
+		perror("mmap failed");
+		exit(1);
+	}
+
+	for (; size > 0; size--, in++) {
+		if (*in != *prefix)
+			continue;
+		if (strncmp(in, prefix, prefix_len) != 0)
+			continue;
+		/* In the case of an exact match there there is nothing to move. */
+		if (in[prefix_len] == '\0')
+			length = 0;
+		/* If this is a filename, strip the leading slash. */
+		else if (in[prefix_len] == '/')
+			length = strlen(in + prefix_len + 1) + 1;
+		/* Otherwise just keep the suffix. */
+		else
+			length = strlen(in + prefix_len) + 1;
+
+		/*
+		 * Copy the suffix portion down to the start and clear
+		 * the remainder of the space to 0.
+		 */
+		memmove(in, in + prefix_len + 1, length);
+		memset(in + length, '\0', prefix_len);
+	}
+}
--- linux-qcom-6.8.0.orig/debian/scripts/link-headers
+++ linux-qcom-6.8.0/debian/scripts/link-headers
@@ -0,0 +1,42 @@
+#!/bin/bash -e
+
+. debian/debian.env
+
+hdrdir="$1"
+symdir="$2"
+flavour="$3"
+
+echo "Symlinking and copying headers for $flavour..."
+
+excludes="( -path ./debian -prune -o -path ./${DEBIAN} -prune -o -path ./.git ) -prune -o"
+
+(
+find . $excludes  -type f \
+	\( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \
+	-name '*.sh' -o -name '*.pl' -o -name '*.lds' \) -print
+find ./include ./scripts -name .gitignore -prune -o -type f -print
+find ./include -mindepth 1 -maxdepth 1 $excludes -type d -print
+) | (
+while read file; do
+	dir=$file
+	lastdir=$file
+
+	if [ -e "$hdrdir/$file" -o -L "$hdrdir/$file" ]; then
+		continue
+	fi
+
+	while [ ! -e "$hdrdir/$dir" -a ! -L "$hdrdir/$dir" ]; do
+		lastdir=$dir
+		dir=`dirname $dir`
+	done
+	# If the last item to exist is a symlink we assume all is good
+	if [ ! -L "$hdrdir/$dir" ]; then
+		# Turns things like "./foo" into "../"
+		deref="`echo -n $lastdir | sed -e 's/^\.//' -e's,/[^/]*,../,g'`"
+		item="`echo -n $lastdir | sed -e 's/^\.\///'`"
+		ln -s $deref$symdir/$item $hdrdir/$item
+	fi
+done
+)
+
+exit
--- linux-qcom-6.8.0.orig/debian/scripts/link-lib-rust
+++ linux-qcom-6.8.0/debian/scripts/link-lib-rust
@@ -0,0 +1,17 @@
+#!/bin/bash -e
+
+. debian/debian.env
+
+hdrdir="$1"
+symdir="$2"
+flavour="$3"
+
+echo "Symlinking and copying Rust files for $flavour..."
+
+# Symlink Rust folder
+item=rust
+relpath=$(echo $symdir | sed s/headers/lib-rust/)-$flavour/$item
+echo ln -s ../$relpath $hdrdir/$item
+ln -s ../$relpath $hdrdir/$item
+
+exit
--- linux-qcom-6.8.0.orig/debian/scripts/misc/annotations
+++ linux-qcom-6.8.0/debian/scripts/misc/annotations
@@ -0,0 +1,35 @@
+#!/usr/bin/env python3
+# -*- mode: python -*-
+
+# This file is not installed; it's just to run annotations from inside a source
+# distribution without installing it in the system.
+
+import sys
+
+# Prevent generating .pyc files on import
+#
+# We may end up adding these files to our git repos by mistake, so simply
+# prevent generating them in advance.
+#
+# There's a tiny performance penalty with this, because python needs to
+# re-generate the bytecode on-the-fly every time the script is executed, but
+# this overhead is absolutely negligible compared the rest of the kernel build
+# time.
+sys.dont_write_bytecode = True
+
+import os  # noqa: E402 Import not at top of file
+
+from kconfig import run  # noqa: E402 Import not at top of file
+
+
+# Update PATH to make sure that annotations can be executed directly from the
+# source directory.
+def update_path():
+    script_dir = os.path.dirname(os.path.abspath(__file__))
+    current_path = os.environ.get("PATH", "")
+    new_path = f"{script_dir}:{current_path}"
+    os.environ["PATH"] = new_path
+
+
+update_path()
+exit(run.main())
--- linux-qcom-6.8.0.orig/debian/scripts/misc/find-missing-sauce.sh
+++ linux-qcom-6.8.0/debian/scripts/misc/find-missing-sauce.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+#
+# Find the 'UBUNTU: SAUCE:' patches that have been dropped from
+# the previous release.
+#
+PREV_REL=focal
+PREV_REPO=git://kernel.ubuntu.com/ubuntu/ubuntu-${PREV_REL}.git
+
+git fetch ${PREV_REPO} master-next
+git log --pretty=oneline FETCH_HEAD|grep SAUCE|while read c m;do echo $m;done |sort > $$.prev-rel
+git log --pretty=oneline |grep SAUCE|while read c m;do echo $m;done |sort > $$.curr-rel
+
+diff -u $$.prev-rel $$.curr-rel |grep "^-"
+rm -f $$.prev-rel $$.curr-rel
+
--- linux-qcom-6.8.0.orig/debian/scripts/misc/gen-auto-reconstruct
+++ linux-qcom-6.8.0/debian/scripts/misc/gen-auto-reconstruct
@@ -0,0 +1,89 @@
+#!/bin/bash
+
+if [ "$#" -ne 3 ]; then
+	echo "Usage: $0 <orig tag>|<base release> <reconstruct> <options>" 1>&2
+	exit 1
+fi
+tag="$1"
+reconstruct="$2"
+options="$3"
+
+case "$tag" in
+v*)	;;
+*)	tag="v${tag%.*}" ;;
+esac
+
+# Validate the tag.
+count=$( git tag -l "$tag" | wc -l )
+if [ "$count" != 1 ]; then
+	echo "$0: $tag: tag invalid" 1>&2
+	exit 1
+fi
+
+#git ls-tree -r --full-tree HEAD | grep ^120 | \
+#while read mode type blobid name
+
+(
+	# Identify all new symlinks since the proffered tag.
+	echo "# Recreate any symlinks created since the orig."
+	git diff "$tag.." --raw --no-renames | awk '(/^:000000 120000/ && $5 == "A") { print $NF }' | \
+	while read name
+	do
+		link=$( readlink "$name" )
+
+		echo "[ ! -L '$name' ] && ln -sf '$link' '$name'"
+	done
+
+	# Identify files with execute permissions added since the proffered tag.
+	git diff "$tag.." --raw --no-renames | awk -F '[: \t]' '{print $2, $3, $NF }' | \
+	while IFS=" " read old new name
+	do
+		old=$( printf "0%s" $old )
+		new=$( printf "0%s" $new )
+		changed=$(( (old ^ new) & 0111 ))
+		if [ "$changed" -ne 0 ]; then
+			added=$(( new & 0111 ))
+			if [ "$added" -ne 0 ]; then
+				echo "chmod +x '$name'"
+                       elif [ "$new" -ne 0 ]; then
+				echo "chmod -x '$name'"
+			fi
+		fi
+	done
+
+       # Identify all removed files since the proffered tag.
+	echo "# Remove any files deleted from the orig."
+	git diff "$tag.." --raw --no-renames | awk '(/^:/ && $5 == "D") { print $NF }' | \
+	while read name
+	do
+		echo "rm -f '$name'"
+	done
+
+	# All done, make sure this does not complete in error.
+	echo "exit 0"
+) >"$reconstruct"
+
+(
+	# Identify all new symlinks since the proffered tag.
+	echo "# Ignore any symlinks created since the orig which are rebuilt by reconstruct."
+	git diff "$tag.." --raw --no-renames | awk '(/^:000000 120000/ && $5 == "A") { print $NF }' | \
+	while read name
+	do
+		echo "extend-diff-ignore=^$name\$"
+	done
+) >"$options.update"
+
+
+head='^## autoreconstruct -- begin$'
+foot='^## autoreconstruct -- end$'
+sed -i -e "
+	/$head/,/$foot/{
+		/$head/{
+			p;
+			r $options.update
+		};
+		/$foot/p;
+		d
+	}
+" "$options"
+rm -f "$options.update"
--- linux-qcom-6.8.0.orig/debian/scripts/misc/git-ubuntu-log
+++ linux-qcom-6.8.0/debian/scripts/misc/git-ubuntu-log
@@ -0,0 +1,163 @@
+#!/usr/bin/env python3
+
+import codecs
+import json
+import sys
+import textwrap
+import urllib.request
+
+sys.stdin = codecs.getreader("utf-8")(sys.stdin.detach())
+sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach())
+
+entries = []
+
+
+def add_entry(entry):
+    global tracking_bug
+
+    if entry and "ignore" not in entry:
+        combo = []
+        for bug in set(entry.get("bugs", [])):
+            combo.append(bug)
+        for cve in set(entry.get("cves", [])):
+            combo.append(cve)
+        combo = sorted(combo)
+
+        if len(combo) == 0:
+            if entry.get("subject", "").startswith("UBUNTU"):
+                combo = "__packaging__"
+            else:
+                combo = "__mainline__"
+        else:
+            if entry.get("subject", "") == "UBUNTU: link-to-tracker: update tracking bug":
+                tracking_bug = combo
+            if combo not in keys:
+                keys.append(combo)
+
+        entry["key"] = combo
+        entries.append(entry)
+
+
+# Suck up the git log output and extract the information we need.
+keys = []
+tracking_bug = None
+entry = None
+subject_wait = False
+for line in sys.stdin:
+    if line.startswith("commit "):
+        add_entry(entry)
+        entry = {}
+        subject_wait = True
+
+    elif line.startswith("Author: "):
+        bits = line.strip().split(maxsplit=1)
+        entry["author"] = bits[1]
+
+    elif subject_wait and line.startswith("    "):
+        subject_wait = False
+        entry["subject"] = line.strip()
+
+    elif line.startswith("    BugLink: "):
+        bits = line.strip().split(maxsplit=2)
+        if len(bits) > 2:
+            # There is text after the URL, so use that (after stripping the
+            # enclosing characters)
+            entry.setdefault("bugs", []).append(bits[2][1:-1])
+        elif "launchpad.net" in bits[1]:
+            # Extract the bug number from the launchpad URL
+            bits = bits[1].split("/")
+            entry.setdefault("bugs", []).append(bits[-1])
+
+    elif line.startswith("    CVE-"):
+        entry.setdefault("cves", []).append(line.strip())
+
+    elif line.startswith("    Ignore:"):
+        entry["ignore"] = True
+
+    elif line.startswith("    Properties:"):
+        for prop in line.strip().split()[1:]:
+            if prop in ("ignore", "no-changelog"):
+                entry["ignore"] = True
+
+add_entry(entry)
+
+entries.reverse()
+
+# Go through the entries and clear out authors for upstream commits.
+for entry in entries:
+    if entry["subject"].startswith("UBUNTU:"):
+        entry["subject"] = entry["subject"][7:].strip()
+    else:
+        del entry["author"]
+
+# Lump everything without a bug at the bottom.
+keys.append("__packaging__")
+keys.append("__mainline__")
+
+# Ensure we list the tracking bug updates first.
+if tracking_bug is not None:
+    keys.remove(tracking_bug)
+    keys.insert(0, tracking_bug)
+
+emit_nl = False
+for key in keys:
+    if key == "__packaging__":
+        title_set = ["Miscellaneous Ubuntu changes"]
+    elif key == "__mainline__":
+        title_set = ["Miscellaneous upstream changes"]
+    else:
+        title_set = []
+        for bug in key:
+            if bug.startswith("CVE-"):
+                title_set.append(bug)
+            elif bug.isdigit():
+                # Assume that it is an LP bug number if 'bug' contains only digits
+                bug_info = None
+
+                try:
+                    # urllib.request.urlcleanup()
+                    request = urllib.request.Request("https://api.launchpad.net/devel/bugs/" + bug)
+                    request.add_header("Cache-Control", "no-cache")
+                    with urllib.request.urlopen(request) as response:
+                        data = response.read()
+                        bug_info = json.loads(data.decode("utf-8"))
+
+                    title = bug_info["title"]
+                    if "description" in bug_info:
+                        for line in bug_info["description"].split("\n"):
+                            if line.startswith("Kernel-Description:"):
+                                title = line.split(" ", 1)[1]
+
+                except urllib.error.HTTPError:
+                    title = "INVALID or PRIVATE BUG"
+
+                title += " (LP###" + bug + ")"
+                title_set.append(title)
+            else:
+                # Finally treat 'bug' itself as the title
+                title_set.append(bug)
+
+    emit_title = True
+    for entry in entries:
+        if entry["key"] != key:
+            continue
+
+        if emit_title:
+            if emit_nl:
+                print("")
+            emit_nl = True
+
+            title_lines = textwrap.wrap("#// ".join(title_set), 76)
+            print("  * " + title_lines[0].replace("LP###", "LP: #").replace("#//", " //"))
+            for line in title_lines[1:]:
+                line = line.replace("LP###", "LP: #").replace("#//", " //")
+                print("    " + line)
+
+            emit_title = False
+
+        if key != tracking_bug or (key == tracking_bug and entry["subject"] != "link-to-tracker: update tracking bug"):
+            title_lines = textwrap.wrap(entry["subject"], 76)
+            print("    - " + title_lines[0])
+            for line in title_lines[1:]:
+                line = line.replace("LP###", "LP: #")
+                print("      " + line)
--- linux-qcom-6.8.0.orig/debian/scripts/misc/insert-changes
+++ linux-qcom-6.8.0/debian/scripts/misc/insert-changes
@@ -0,0 +1,42 @@
+#!/usr/bin/python3
+
+import os
+import sys
+
+from subprocess import check_output
+
+droot = 'debian'
+if len(sys.argv) > 1:
+    droot = sys.argv[1]
+
+debian = 'debian.master'
+if len(sys.argv) > 2:
+    debian = sys.argv[2]
+
+rules = os.path.join(droot, 'rules')
+changelog = os.path.join(debian, 'changelog')
+changelog_new = os.path.join(debian, 'changelog.new')
+
+# Generate the list of new changes
+changes = check_output(['make', '-s', '-f', rules, 'printchanges']).decode('UTF-8')
+
+# Insert the new changes into the changelog
+with open(changelog) as orig, open(changelog_new, 'w') as new:
+    printed = False
+    skip_newline = False
+    for line in orig:
+        if line.startswith('  CHANGELOG: '):
+            if not printed:
+                printed = True
+                if changes == '':
+                    skip_newline = True
+                    continue
+                new.write(changes)
+        else:
+            if skip_newline and line.strip() == '':
+                skip_newline = False
+                continue
+            new.write(line)
+
+# Replace the original changelog with the new one
+os.rename(changelog_new, changelog)
--- linux-qcom-6.8.0.orig/debian/scripts/misc/insert-ubuntu-changes
+++ linux-qcom-6.8.0/debian/scripts/misc/insert-ubuntu-changes
@@ -0,0 +1,64 @@
+#!/usr/bin/env python3
+
+import re
+import os
+import sys
+
+def version_cmp(a, b):
+    a = re.split(r"[\.-]+", a)
+    b = re.split(r"[\.-]+", b)
+    i = 0
+    while True:
+        if len(a) <= i:
+            if len(b) <= i:
+                return 0
+            return -1
+        if len(b) <= i:
+            return 1
+        if int(a[i]) < int(b[i]):
+            return -1
+        if int(a[i]) > int(b[i]):
+            return 1
+        i += 1
+
+if len(sys.argv) == 4:
+    sys.argv.append("debian.master/changelog")
+
+if len(sys.argv) == 5:
+    changelog, end, start, source_changelog = sys.argv[1:]
+else:
+    print("Usage: insert-ubuntu-changes <changelog> <stop at> <start at> [<source changelog>]")
+    sys.exit(1)
+
+changes = []
+output = False
+with open(source_changelog) as fh:
+    for line in fh:
+        m = re.match(r"^\S+\s+\((.*)\)", line)
+        if m:
+            if version_cmp(m.group(1), end) <= 0:
+                break
+            if m.group(1) == start:
+                output = True
+            if output:
+                changes.append("\n")
+                changes.append("  [ Ubuntu: {} ]\n".format(m.group(1)))
+                changes.append("\n")
+                continue
+
+        if output and re.match(r"^(  * |    |      )\S", line):
+            changes.append(line)
+
+printed = 3
+with open(changelog + ".new", "w") as fh_new:
+    with open(changelog) as fh:
+        for line in fh:
+            if line.startswith("  CHANGELOG: "):
+                printed -= 1
+                fh_new.write(line)
+                if printed == 0:
+                    fh_new.write("".join(changes))
+                continue
+            fh_new.write(line)
+
+os.rename(changelog + ".new", changelog)
--- linux-qcom-6.8.0.orig/debian/scripts/misc/kconfig/annotations.py
+++ linux-qcom-6.8.0/debian/scripts/misc/kconfig/annotations.py
@@ -0,0 +1,521 @@
+# -*- mode: python -*-
+# python module to manage Ubuntu kernel .config and annotations
+# Copyright © 2022 Canonical Ltd.
+
+import json
+import re
+import shutil
+import tempfile
+from abc import abstractmethod
+from ast import literal_eval
+from os.path import abspath, dirname
+
+from kconfig.version import ANNOTATIONS_FORMAT_VERSION
+
+
+class Config:
+    def __init__(self, fname, do_include=True):
+        """
+        Basic configuration file object
+        """
+        self.fname = fname
+        self.config = {}
+        self.do_include = do_include
+
+        raw_data = self._load(fname)
+        self._parse(raw_data)
+
+    @staticmethod
+    def _load(fname: str) -> str:
+        with open(fname, "rt", encoding="utf-8") as fd:
+            data = fd.read()
+        return data.rstrip()
+
+    def __str__(self):
+        """Return a JSON representation of the config"""
+        return json.dumps(self.config, indent=4)
+
+    @abstractmethod
+    def _parse(self, data: str):
+        pass
+
+
+class KConfig(Config):
+    """
+    Parse a .config file, individual config options can be accessed via
+    .config[<CONFIG_OPTION>]
+    """
+
+    def _parse(self, data: str):
+        self.config = {}
+        for line in data.splitlines():
+            m = re.match(r"^# (CONFIG_.*) is not set$", line)
+            if m:
+                self.config[m.group(1)] = literal_eval("'n'")
+                continue
+            m = re.match(r"^(CONFIG_[A-Za-z0-9_]+)=(.*)$", line)
+            if m:
+                self.config[m.group(1)] = literal_eval("'" + m.group(2) + "'")
+                continue
+
+
+class Annotation(Config):
+    """
+    Parse body of annotations file
+    """
+
+    def __init__(self, fname, do_include=True, do_json=False):
+        self.do_json = do_json
+        super().__init__(fname, do_include=True)
+
+    def _parse_body(self, data: str, parent=True):
+        for line in data.splitlines():
+            # Replace tabs with spaces, squeeze multiple into singles and
+            # remove leading and trailing spaces
+            line = line.replace("\t", " ")
+            line = re.sub(r" +", " ", line)
+            line = line.strip()
+
+            # Ignore empty lines
+            if not line:
+                continue
+
+            # Catpure flavors of included files
+            if line.startswith("# FLAVOUR: "):
+                self.include_flavour += line.split(" ")[2:]
+                continue
+
+            # Ignore comments
+            if line.startswith("#"):
+                continue
+
+            # Handle includes (recursively)
+            m = re.match(r'^include\s+"?([^"]*)"?', line)
+            if m:
+                if parent:
+                    self.include.append(m.group(1))
+                if self.do_include:
+                    include_fname = dirname(abspath(self.fname)) + "/" + m.group(1)
+                    include_data = self._load(include_fname)
+                    self._parse_body(include_data, parent=False)
+                continue
+
+            # Handle policy and note lines
+            if re.match(r".* (policy|note)<", line):
+                try:
+                    conf = line.split(" ")[0]
+                    if conf in self.config:
+                        entry = self.config[conf]
+                    else:
+                        entry = {"policy": {}}
+
+                    match = False
+                    m = re.match(r".* policy<(.*?)>", line)
+                    if m:
+                        match = True
+                        # Update the previous entry considering potential overrides:
+                        #  - if the new entry is adding a rule for a new
+                        #    arch/flavour, simply add that
+                        #  - if the new entry is overriding a previous
+                        #    arch-flavour item, then overwrite that item
+                        #  - if the new entry is overriding a whole arch, then
+                        #    remove all the previous flavour rules of that arch
+                        new_entry = literal_eval(m.group(1))
+                        for key in new_entry:
+                            if key in self.arch:
+                                for flavour_key in list(entry["policy"].keys()):
+                                    if flavour_key.startswith(key):
+                                        del entry["policy"][flavour_key]
+                                entry["policy"][key] = new_entry[key]
+                            else:
+                                entry["policy"][key] = new_entry[key]
+
+                    m = re.match(r".* note<(.*?)>", line)
+                    if m:
+                        entry["oneline"] = match
+                        match = True
+                        entry["note"] = "'" + m.group(1).replace("'", "") + "'"
+
+                    if not match:
+                        raise SyntaxError("syntax error")
+                    self.config[conf] = entry
+                except Exception as e:
+                    raise SyntaxError(str(e) + f", line = {line}") from e
+                continue
+
+            # Invalid line
+            raise SyntaxError(f"invalid line: {line}")
+
+    def _legacy_parse(self, data: str):
+        """
+        Parse main annotations file, individual config options can be accessed
+        via self.config[<CONFIG_OPTION>]
+        """
+        self.config = {}
+        self.arch = []
+        self.flavour = []
+        self.flavour_dep = {}
+        self.include = []
+        self.header = ""
+        self.include_flavour = []
+
+        # Parse header (only main header will considered, headers in includes
+        # will be treated as comments)
+        for line in data.splitlines():
+            if re.match(r"^#.*", line):
+                m = re.match(r"^# ARCH: (.*)", line)
+                if m:
+                    self.arch = list(m.group(1).split(" "))
+                m = re.match(r"^# FLAVOUR: (.*)", line)
+                if m:
+                    self.flavour = list(m.group(1).split(" "))
+                m = re.match(r"^# FLAVOUR_DEP: (.*)", line)
+                if m:
+                    self.flavour_dep = literal_eval(m.group(1))
+                self.header += line + "\n"
+            else:
+                break
+
+        # Return an error if architectures are not defined
+        if not self.arch:
+            raise SyntaxError("ARCH not defined in annotations")
+        # Return an error if flavours are not defined
+        if not self.flavour:
+            raise SyntaxError("FLAVOUR not defined in annotations")
+
+        # Parse body
+        self._parse_body(data)
+
+        # Sanity check: Verify that all FLAVOUR_DEP flavors are valid
+        if self.do_include:
+            for src, tgt in self.flavour_dep.items():
+                if src not in self.flavour:
+                    raise SyntaxError(f"Invalid source flavour in FLAVOUR_DEP: {src}")
+                if tgt not in self.include_flavour:
+                    raise SyntaxError(f"Invalid target flavour in FLAVOUR_DEP: {tgt}")
+
+    def _json_parse(self, data, is_included=False):
+        data = json.loads(data)
+
+        # Check if version is supported
+        version = data["attributes"]["_version"]
+        if version > ANNOTATIONS_FORMAT_VERSION:
+            raise SyntaxError(f"annotations format version {version} not supported")
+
+        # Check for top-level annotations vs imported annotations
+        if not is_included:
+            self.config = data["config"]
+            self.arch = data["attributes"]["arch"]
+            self.flavour = data["attributes"]["flavour"]
+            self.flavour_dep = data["attributes"]["flavour_dep"]
+            self.include = data["attributes"]["include"]
+            self.include_flavour = []
+        else:
+            # We are procesing an imported annotations, so merge all the
+            # configs and attributes.
+            try:
+                self.config = data["config"] | self.config
+            except TypeError:
+                self.config = {**self.config, **data["config"]}
+            self.arch = list(set(self.arch) | set(data["attributes"]["arch"]))
+            self.flavour = list(set(self.flavour) | set(data["attributes"]["flavour"]))
+            self.include_flavour = list(set(self.include_flavour) | set(data["attributes"]["flavour"]))
+            self.flavour_dep = self.flavour_dep | data["attributes"]["flavour_dep"]
+
+        # Handle recursive inclusions
+        if self.do_include:
+            for f in data["attributes"]["include"]:
+                include_fname = dirname(abspath(self.fname)) + "/" + f
+                data = self._load(include_fname)
+                self._json_parse(data, is_included=True)
+
+    def _parse(self, data: str):
+        if self.do_json:
+            self._json_parse(data, is_included=False)
+        else:
+            self._legacy_parse(data)
+
+    def _remove_entry(self, config: str):
+        if self.config[config]:
+            del self.config[config]
+
+    def remove(self, config: str, arch: str = None, flavour: str = None):
+        if config not in self.config:
+            return
+        if arch is not None:
+            if flavour is not None:
+                flavour = f"{arch}-{flavour}"
+            else:
+                flavour = arch
+            del self.config[config]["policy"][flavour]
+            if not self.config[config]["policy"]:
+                self._remove_entry(config)
+        else:
+            self._remove_entry(config)
+
+    def set(
+        self,
+        config: str,
+        arch: str = None,
+        flavour: str = None,
+        value: str = None,
+        note: str = None,
+    ):
+        if value is not None:
+            if config not in self.config:
+                self.config[config] = {"policy": {}}
+            if arch is not None:
+                if flavour is not None:
+                    flavour = f"{arch}-{flavour}"
+                else:
+                    flavour = arch
+                self.config[config]["policy"][flavour] = value
+            else:
+                for a in self.arch:
+                    self.config[config]["policy"][a] = value
+        if note is not None:
+            self.config[config]["note"] = "'" + note.replace("'", "") + "'"
+
+    def update(self, c: KConfig, arch: str, flavour: str = None, configs: list = None):
+        """Merge configs from a Kconfig object into Annotation object"""
+
+        # Determine if we need to import all configs or a single config
+        if not configs:
+            configs = c.config.keys()
+            try:
+                configs |= self.search_config(arch=arch, flavour=flavour).keys()
+            except TypeError:
+                configs = {
+                    **configs,
+                    **self.search_config(arch=arch, flavour=flavour).keys(),
+                }
+
+        # Import configs from the Kconfig object into Annotations
+        flavour_arg = flavour
+        if flavour is not None:
+            flavour = arch + f"-{flavour}"
+        else:
+            flavour = arch
+        for conf in configs:
+            if conf in c.config:
+                val = c.config[conf]
+            else:
+                val = "-"
+            if conf in self.config:
+                if "policy" in self.config[conf]:
+                    # Add a TODO if a config with a note is changing and print
+                    # a warning
+                    old_val = self.search_config(config=conf, arch=arch, flavour=flavour_arg)
+                    if old_val:
+                        old_val = old_val[conf]
+                    if val != old_val and "note" in self.config[conf]:
+                        self.config[conf]["note"] = "TODO: update note"
+                        print(f"WARNING: {conf} changed from {old_val} to {val}, updating note")
+                    self.config[conf]["policy"][flavour] = val
+                else:
+                    self.config[conf]["policy"] = {flavour: val}
+            else:
+                self.config[conf] = {"policy": {flavour: val}}
+
+    def _compact(self):
+        # Try to remove redundant settings: if the config value of a flavour is
+        # the same as the one of the main arch simply drop it.
+        for conf in self.config.copy():
+            if "policy" not in self.config[conf]:
+                continue
+            for flavour in self.flavour:
+                if flavour not in self.config[conf]["policy"]:
+                    continue
+                m = re.match(r"^(.*?)-(.*)$", flavour)
+                if not m:
+                    continue
+                arch = m.group(1)
+                if arch in self.config[conf]["policy"]:
+                    if self.config[conf]["policy"][flavour] == self.config[conf]["policy"][arch]:
+                        del self.config[conf]["policy"][flavour]
+                        continue
+                if flavour not in self.flavour_dep:
+                    continue
+                generic = self.flavour_dep[flavour]
+                if generic in self.config[conf]["policy"]:
+                    if self.config[conf]["policy"][flavour] == self.config[conf]["policy"][generic]:
+                        del self.config[conf]["policy"][flavour]
+                        continue
+            # Remove rules for flavours / arches that are not supported (not
+            # listed in the annotations header).
+            for flavour in self.config[conf]["policy"].copy():
+                if flavour not in list(set(self.arch + self.flavour)):
+                    del self.config[conf]["policy"][flavour]
+            # Remove configs that are all undefined across all arches/flavours
+            # (unless we have includes)
+            if not self.include:
+                if "policy" in self.config[conf]:
+                    if list(set(self.config[conf]["policy"].values())) == ["-"]:
+                        self.config[conf]["policy"] = {}
+            # Drop empty rules
+            if not self.config[conf]["policy"]:
+                del self.config[conf]
+            else:
+                # Compact same value across all flavour within the same arch
+                for arch in self.arch:
+                    arch_flavours = [i for i in self.flavour if i.startswith(arch)]
+                    value = None
+                    for flavour in arch_flavours:
+                        if flavour not in self.config[conf]["policy"]:
+                            break
+                        if value is None:
+                            value = self.config[conf]["policy"][flavour]
+                        elif value != self.config[conf]["policy"][flavour]:
+                            break
+                    else:
+                        for flavour in arch_flavours:
+                            del self.config[conf]["policy"][flavour]
+                        self.config[conf]["policy"][arch] = value
+        # After the first round of compaction we may end up having configs that
+        # are undefined across all arches, so do another round of compaction to
+        # drop these settings that are not needed anymore
+        # (unless we have includes).
+        if not self.include:
+            for conf in self.config.copy():
+                # Remove configs that are all undefined across all arches/flavours
+                if "policy" in self.config[conf]:
+                    if list(set(self.config[conf]["policy"].values())) == ["-"]:
+                        self.config[conf]["policy"] = {}
+                # Drop empty rules
+                if not self.config[conf]["policy"]:
+                    del self.config[conf]
+
+    @staticmethod
+    def _sorted(config):
+        """Sort configs alphabetically but return configs with a note first"""
+        w_note = []
+        wo_note = []
+        for c in sorted(config):
+            if "note" in config[c]:
+                w_note.append(c)
+            else:
+                wo_note.append(c)
+        return w_note + wo_note
+
+    def save(self, fname: str):
+        """Save annotations data to the annotation file"""
+        # Compact annotations structure
+        self._compact()
+
+        # Save annotations to disk
+        with tempfile.NamedTemporaryFile(mode="w+t", delete=False) as tmp:
+            # Write header
+            tmp.write(self.header + "\n")
+
+            # Write includes
+            for i in self.include:
+                tmp.write(f'include "{i}"\n')
+            if self.include:
+                tmp.write("\n")
+
+            # Write config annotations and notes
+            tmp.flush()
+            shutil.copy(tmp.name, fname)
+            tmp_a = Annotation(fname)
+
+            # Only save local differences (preserve includes)
+            marker = False
+            for conf in self._sorted(self.config):
+                new_val = self.config[conf]
+                if "policy" not in new_val:
+                    continue
+
+                # If new_val is a subset of old_val, skip it unless there are
+                # new notes that are different than the old ones.
+                old_val = tmp_a.config.get(conf)
+                if old_val and "policy" in old_val:
+                    try:
+                        can_skip = old_val["policy"] == old_val["policy"] | new_val["policy"]
+                    except TypeError:
+                        can_skip = old_val["policy"] == {
+                            **old_val["policy"],
+                            **new_val["policy"],
+                        }
+                    if can_skip:
+                        if "note" not in new_val:
+                            continue
+                        if "note" in old_val and "note" in new_val:
+                            if old_val["note"] == new_val["note"]:
+                                continue
+
+                # Write out the policy (and note) line(s)
+                val = dict(sorted(new_val["policy"].items()))
+                line = f"{conf: <47} policy<{val}>"
+                if "note" in new_val:
+                    val = new_val["note"]
+                    if new_val.get("oneline", False):
+                        # Single line
+                        line += f" note<{val}>"
+                    else:
+                        # Separate policy and note lines,
+                        # followed by an empty line
+                        line += f"\n{conf: <47} note<{val}>\n"
+                elif not marker:
+                    # Write out a marker indicating the start of annotations
+                    # without notes
+                    tmp.write("\n# ---- Annotations without notes ----\n\n")
+                    marker = True
+                tmp.write(line + "\n")
+
+            # Replace annotations with the updated version
+            tmp.flush()
+            shutil.move(tmp.name, fname)
+
+    def search_config(self, config: str = None, arch: str = None, flavour: str = None) -> dict:
+        """Return config value of a specific config option or architecture"""
+        if flavour is None:
+            flavour = "generic"
+        flavour = f"{arch}-{flavour}"
+        if flavour in self.flavour_dep:
+            generic = self.flavour_dep[flavour]
+        else:
+            generic = flavour
+        if config is None and arch is None:
+            # Get all config options for all architectures
+            return self.config
+        if config is None and arch is not None:
+            # Get config options of a specific architecture
+            ret = {}
+            for c, val in self.config.items():
+                if "policy" not in val:
+                    continue
+                if flavour in val["policy"]:
+                    ret[c] = val["policy"][flavour]
+                elif generic != flavour and generic in val["policy"]:
+                    ret[c] = val["policy"][generic]
+                elif arch in val["policy"]:
+                    ret[c] = val["policy"][arch]
+            return ret
+        if config is not None and arch is None:
+            # Get a specific config option for all architectures
+            return self.config[config] if config in self.config else None
+        if config is not None and arch is not None:
+            # Get a specific config option for a specific architecture
+            if config in self.config:
+                if "policy" in self.config[config]:
+                    if flavour in self.config[config]["policy"]:
+                        return {config: self.config[config]["policy"][flavour]}
+                    if generic != flavour and generic in self.config[config]["policy"]:
+                        return {config: self.config[config]["policy"][generic]}
+                    if arch in self.config[config]["policy"]:
+                        return {config: self.config[config]["policy"][arch]}
+        return None
+
+    @staticmethod
+    def to_config(data: dict) -> str:
+        """Convert annotations data to .config format"""
+        s = ""
+        for c in data:
+            v = data[c]
+            if v == "n":
+                s += f"# {c} is not set\n"
+            elif v == "-":
+                pass
+            else:
+                s += f"{c}={v}\n"
+        return s.rstrip()
--- linux-qcom-6.8.0.orig/debian/scripts/misc/kconfig/run.py
+++ linux-qcom-6.8.0/debian/scripts/misc/kconfig/run.py
@@ -0,0 +1,369 @@
+# -*- mode: python -*-
+# Manage Ubuntu kernel .config and annotations
+# Copyright © 2022 Canonical Ltd.
+
+import argparse
+import json
+import os
+import sys
+from signal import SIG_DFL, SIGPIPE, signal
+
+try:
+    from argcomplete import autocomplete
+except ModuleNotFoundError:
+    # Allow to run this program also when argcomplete is not available
+    def autocomplete(_unused):
+        pass
+
+
+from kconfig.annotations import Annotation, KConfig  # noqa: E402 Import not at top of file
+from kconfig.utils import arg_fail, autodetect_annotations  # noqa: E402 Import not at top of file
+from kconfig.version import ANNOTATIONS_FORMAT_VERSION, VERSION  # noqa: E402 Import not at top of file
+
+SKIP_CONFIGS = (
+    # CONFIG_VERSION_SIGNATURE is dynamically set during the build
+    "CONFIG_VERSION_SIGNATURE",
+    # Allow to use a different versions of toolchain tools
+    "CONFIG_GCC_VERSION",
+    "CONFIG_CC_VERSION_TEXT",
+    "CONFIG_AS_VERSION",
+    "CONFIG_LD_VERSION",
+    "CONFIG_LLD_VERSION",
+    "CONFIG_CLANG_VERSION",
+    "CONFIG_PAHOLE_VERSION",
+    "CONFIG_RUSTC_VERSION_TEXT",
+    "CONFIG_BINDGEN_VERSION_TEXT",
+)
+
+
+def make_parser():
+    parser = argparse.ArgumentParser(
+        description="Manage Ubuntu kernel .config and annotations",
+    )
+    parser.add_argument("--version", "-v", action="version", version=f"%(prog)s {VERSION}")
+
+    parser.add_argument(
+        "--file",
+        "-f",
+        action="store",
+        help="Pass annotations or .config file to be parsed",
+    )
+    parser.add_argument("--arch", "-a", action="store", help="Select architecture")
+    parser.add_argument("--flavour", "-l", action="store", help='Select flavour (default is "generic")')
+    parser.add_argument("--config", "-c", action="store", help="Select a specific config option")
+    parser.add_argument("--query", "-q", action="store_true", help="Query annotations")
+    parser.add_argument(
+        "--note",
+        "-n",
+        action="store",
+        help="Write a specific note to a config option in annotations",
+    )
+    parser.add_argument(
+        "--autocomplete",
+        action="store_true",
+        help="Enable config bash autocomplete: `source <(annotations --autocomplete)`",
+    )
+    parser.add_argument(
+        "--source",
+        "-t",
+        action="store_true",
+        help="Jump to a config definition in the kernel source code",
+    )
+    parser.add_argument(
+        "--no-include",
+        action="store_true",
+        help="Do not process included annotations (stop at the main file)",
+    )
+    parser.add_argument(
+        "--json",
+        action="store_true",
+        help="Try to parse annotations file in pure JSON format",
+    )
+
+    ga = parser.add_argument_group(title="Action").add_mutually_exclusive_group(required=False)
+    ga.add_argument(
+        "--write",
+        "-w",
+        action="store",
+        metavar="VALUE",
+        dest="value",
+        help="Set a specific config value in annotations (use 'null' to remove)",
+    )
+    ga.add_argument(
+        "--export",
+        "-e",
+        action="store_true",
+        help="Convert annotations to .config format",
+    )
+    ga.add_argument(
+        "--import",
+        "-i",
+        action="store",
+        metavar="FILE",
+        dest="import_file",
+        help="Import a full .config for a specific arch and flavour into annotations",
+    )
+    ga.add_argument(
+        "--update",
+        "-u",
+        action="store",
+        metavar="FILE",
+        dest="update_file",
+        help="Import a partial .config into annotations (only resync configs specified in FILE)",
+    )
+    ga.add_argument(
+        "--check",
+        "-k",
+        action="store",
+        metavar="FILE",
+        dest="check_file",
+        help="Validate kernel .config with annotations",
+    )
+    return parser
+
+
+_ARGPARSER = make_parser()
+
+
+def export_result(data):
+    # Dump metadata / attributes first
+    out = '{\n  "attributes": {\n'
+    for key, value in sorted(data["attributes"].items()):
+        out += f'     "{key}": {json.dumps(value)},\n'
+    out = out.rstrip(",\n")
+    out += "\n  },"
+    print(out)
+
+    configs_with_note = {key: value for key, value in data["config"].items() if "note" in value}
+    configs_without_note = {key: value for key, value in data["config"].items() if "note" not in value}
+
+    # Dump configs, sorted alphabetically, showing items with a note first
+    out = '  "config": {\n'
+    for key in sorted(configs_with_note) + sorted(configs_without_note):
+        policy = data["config"][key]["policy"]
+        if "note" in data["config"][key]:
+            note = data["config"][key]["note"]
+            out += f'    "{key}": {{"policy": {json.dumps(policy)}, "note": {json.dumps(note)}}},\n'
+        else:
+            out += f'    "{key}": {{"policy": {json.dumps(policy)}}},\n'
+    out = out.rstrip(",\n")
+    out += "\n  }\n}"
+    print(out)
+
+
+def print_result(config, data):
+    if data is not None and config is not None and config not in data:
+        data = {config: data}
+    print(json.dumps(data, sort_keys=True, indent=2))
+
+
+def do_query(args):
+    if args.arch is None and args.flavour is not None:
+        arg_fail(_ARGPARSER, "error: --flavour requires --arch")
+    a = Annotation(args.file, do_include=(not args.no_include), do_json=args.json)
+    res = a.search_config(config=args.config, arch=args.arch, flavour=args.flavour)
+    # If no arguments are specified dump the whole annotations structure
+    if args.config is None and args.arch is None and args.flavour is None:
+        res = {
+            "attributes": {
+                "arch": a.arch,
+                "flavour": a.flavour,
+                "flavour_dep": a.flavour_dep,
+                "include": a.include,
+                "_version": ANNOTATIONS_FORMAT_VERSION,
+            },
+            "config": res,
+        }
+        export_result(res)
+    else:
+        print_result(args.config, res)
+
+
+def do_autocomplete(args):
+    a = Annotation(args.file)
+    res = (c.removeprefix("CONFIG_") for c in a.search_config())
+    res_str = " ".join(res)
+    print(f'complete -W "{res_str}" annotations')
+
+
+def do_source(args):
+    if args.config is None:
+        arg_fail(_ARGPARSER, "error: --source requires --config")
+    if not os.path.exists("tags"):
+        print("tags not found in the current directory, try: `make tags`")
+        sys.exit(1)
+    os.system(f"vim -t {args.config}")
+
+
+def do_note(args):
+    if args.config is None:
+        arg_fail(_ARGPARSER, "error: --note requires --config")
+
+    # Set the note in annotations
+    a = Annotation(args.file)
+    a.set(args.config, note=args.note)
+
+    # Save back to annotations
+    a.save(args.file)
+
+    # Query and print back the value
+    a = Annotation(args.file)
+    res = a.search_config(config=args.config)
+    print_result(args.config, res)
+
+
+def do_write(args):
+    if args.config is None:
+        arg_fail(_ARGPARSER, "error: --write requires --config")
+
+    # Set the value in annotations ('null' means remove)
+    a = Annotation(args.file)
+    if args.value == "null":
+        a.remove(args.config, arch=args.arch, flavour=args.flavour)
+    else:
+        a.set(
+            args.config,
+            arch=args.arch,
+            flavour=args.flavour,
+            value=args.value,
+            note=args.note,
+        )
+
+    # Save back to annotations
+    a.save(args.file)
+
+    # Query and print back the value
+    a = Annotation(args.file)
+    res = a.search_config(config=args.config)
+    print_result(args.config, res)
+
+
+def do_export(args):
+    if args.arch is None:
+        arg_fail(_ARGPARSER, "error: --export requires --arch")
+    a = Annotation(args.file)
+    conf = a.search_config(config=args.config, arch=args.arch, flavour=args.flavour)
+    if conf:
+        print(a.to_config(conf))
+
+
+def do_import(args):
+    if args.arch is None:
+        arg_fail(_ARGPARSER, "error: --arch is required with --import")
+    if args.flavour is None:
+        arg_fail(_ARGPARSER, "error: --flavour is required with --import")
+    if args.config is not None:
+        arg_fail(_ARGPARSER, "error: --config cannot be used with --import (try --update)")
+
+    # Merge with the current annotations
+    a = Annotation(args.file)
+    c = KConfig(args.import_file)
+    a.update(c, arch=args.arch, flavour=args.flavour)
+
+    # Save back to annotations
+    a.save(args.file)
+
+
+def do_update(args):
+    if args.arch is None:
+        arg_fail(_ARGPARSER, "error: --arch is required with --update")
+
+    # Merge with the current annotations
+    a = Annotation(args.file)
+    c = KConfig(args.update_file)
+    if args.config is None:
+        configs = list(set(c.config.keys()) - set(SKIP_CONFIGS))
+    if configs:
+        a.update(c, arch=args.arch, flavour=args.flavour, configs=configs)
+
+    # Save back to annotations
+    a.save(args.file)
+
+
+def do_check(args):
+    # Determine arch and flavour
+    if args.arch is None:
+        arg_fail(_ARGPARSER, "error: --arch is required with --check")
+
+    print(f"check-config: loading annotations from {args.file}")
+    total = good = ret = 0
+
+    # Load annotations settings
+    a = Annotation(args.file)
+    a_configs = a.search_config(arch=args.arch, flavour=args.flavour).keys()
+
+    # Parse target .config
+    c = KConfig(args.check_file)
+    c_configs = c.config.keys()
+
+    # Validate .config against annotations
+    for conf in sorted(a_configs | c_configs):
+        if conf in SKIP_CONFIGS:
+            continue
+        entry = a.search_config(config=conf, arch=args.arch, flavour=args.flavour)
+        expected = entry[conf] if entry else "-"
+        value = c.config[conf] if conf in c.config else "-"
+        if value != expected:
+            policy = a.config[conf] if conf in a.config else "undefined"
+            if "policy" in policy:
+                policy = f"policy<{policy['policy']}>"
+            print(f"check-config: {conf} changed from {expected} to {value}: {policy})")
+            ret = 1
+        else:
+            good += 1
+        total += 1
+
+    num = total - good
+    if ret:
+        if os.path.exists(".git"):
+            print(f"check-config: {num} config options have been changed, review them with `git diff`")
+        else:
+            print(f"check-config: {num} config options have changed")
+    else:
+        print("check-config: all good")
+    sys.exit(ret)
+
+
+def main():
+    # Prevent broken pipe errors when showing output in pipe to other tools
+    # (less for example)
+    signal(SIGPIPE, SIG_DFL)
+
+    # Main annotations program
+    autocomplete(_ARGPARSER)
+    args = _ARGPARSER.parse_args()
+
+    if args.file is None:
+        args.file = autodetect_annotations()
+        if args.file is None:
+            arg_fail(
+                _ARGPARSER,
+                "error: could not determine DEBDIR, try using: --file/-f",
+                show_usage=False,
+            )
+
+    if args.config and not args.config.startswith("CONFIG_"):
+        args.config = "CONFIG_" + args.config
+
+    if args.value:
+        do_write(args)
+    elif args.note:
+        do_note(args)
+    elif args.export:
+        do_export(args)
+    elif args.import_file:
+        do_import(args)
+    elif args.update_file:
+        do_update(args)
+    elif args.check_file:
+        do_check(args)
+    elif args.autocomplete:
+        do_autocomplete(args)
+    elif args.source:
+        do_source(args)
+    else:
+        do_query(args)
+
+
+if __name__ == "__main__":
+    main()
--- linux-qcom-6.8.0.orig/debian/scripts/misc/kconfig/utils.py
+++ linux-qcom-6.8.0/debian/scripts/misc/kconfig/utils.py
@@ -0,0 +1,20 @@
+# -*- mode: python -*-
+# Misc helpers for Kconfig and annotations
+# Copyright © 2023 Canonical Ltd.
+
+import sys
+
+
+def autodetect_annotations():
+    try:
+        with open("debian/debian.env", "rt", encoding="utf-8") as fd:
+            return fd.read().rstrip().split("=")[1] + "/config/annotations"
+    except (FileNotFoundError, IndexError):
+        return None
+
+
+def arg_fail(parser, message, show_usage=True):
+    print(message)
+    if show_usage:
+        parser.print_usage()
+    sys.exit(1)
--- linux-qcom-6.8.0.orig/debian/scripts/misc/kconfig/version.py
+++ linux-qcom-6.8.0/debian/scripts/misc/kconfig/version.py
@@ -0,0 +1,10 @@
+# -*- mode: python -*-
+# version of annotations module
+# Copyright © 2022 Canonical Ltd.
+
+VERSION = "0.1"
+
+ANNOTATIONS_FORMAT_VERSION = 5
+
+if __name__ == "__main__":
+    print(VERSION)
--- linux-qcom-6.8.0.orig/debian/scripts/misc/kernelconfig
+++ linux-qcom-6.8.0/debian/scripts/misc/kernelconfig
@@ -0,0 +1,178 @@
+#!/bin/bash -u
+#
+# Manage kernel config annotations
+#
+# Supported environment variales:
+#   conc_level  : Concurrency level for upstream make (-jX)
+#   skip_checks : Skip config checks if set to 'true'
+#   gcc         : Default gcc to use (mandatory)
+#
+
+function cleanup()
+{
+	rm -rf build "${TMP_DIR}"
+}
+
+# We have to be in the top level Ubuntu kernel source directory
+if ! [ -e debian/debian.env ] ; then
+	echo "ERROR: This is not an Ubuntu kernel source directory" >&2
+	exit 1
+fi
+
+if [ -z "${gcc:-}" ] ; then
+	echo "ERROR: 'gcc' environment variable must be set" >&2
+	exit 1
+fi
+
+if [ ${#} -ne 1 ] ; then
+	echo "Usage: $0 updateconfigs|defaultconfigs|genconfigs|editconfigs"
+	exit 2
+fi
+
+mode=${1}
+
+case "${mode}" in
+	updateconfigs)  target="syncconfig" ;;
+	defaultconfigs) target="olddefconfig" ;;
+	genconfigs)     target="oldconfig" ;;
+	editconfigs)    ;;  # Target is set later based on user input
+	*) echo "ERROR: Invalid mode: ${1}" >&2
+	   exit 1 ;;
+esac
+
+. debian/debian.env
+
+annotations_file=${DEBIAN}/config/annotations
+warning_partial=()
+
+TMP_DIR=$(mktemp -d)
+trap cleanup EXIT
+
+# Use annotations to generate configs
+FLAVOURS=$(sed -ne 's/^# FLAVOUR: //p' "${annotations_file}")
+
+for arch_flavour in ${FLAVOURS} ; do
+	arch=${arch_flavour%%-*}
+	flavour=${arch_flavour#*-}
+	tmp_conf_file=${TMP_DIR}/${arch}-config.flavour.${flavour}
+
+	# Map debian archs to kernel archs
+	case "${arch}" in
+		amd64)   kern_arch="x86_64" ;;
+		arm64)   kern_arch="arm64" ;;
+		armhf)   kern_arch="arm" ;;
+		ppc64el) kern_arch="powerpc" ;;
+		riscv64) kern_arch="riscv" ;;
+		s390x)   kern_arch="s390" ;;
+		*)       echo "WARNING: Unsupported architecture: ${arch}"
+		         warning_partial+=("${arch}")
+		         continue ;;
+	esac
+
+	# Determine cross toolchain to use for Kconfig compiler tests
+	cross_compile="$(dpkg-architecture -qDEB_HOST_GNU_TYPE -a"${arch}" 2>/dev/null)-"
+
+	# Arch-specific compiler, if any
+	arch_gcc=$(cat <<EOF | make -s -f - all
+include ${DEBIAN}/rules.d/${arch}.mk
+all:
+	@echo \$(if \$(gcc),\$(gcc),${gcc})
+EOF
+			)
+	gcc_path=$(which "${cross_compile}${arch_gcc}" || true)
+	if [ -z "${gcc_path}" ] ; then
+		echo "WARNING: ${cross_compile}${arch_gcc} not installed"
+		warning_partial+=("${arch}")
+		continue
+	fi
+
+	if [ "${mode}" = "editconfigs" ] ; then
+		while true ; do
+			echo -n "Do you want to edit configs for ${arch}-${flavour}? [Y/n] "
+			read -r choice
+			case "${choice,,}" in
+				y|"") target="menuconfig" ; break ;;
+				n)    target="syncconfig" ; break ;;
+			esac
+		done
+	fi
+
+	rm -rf build
+	mkdir build
+
+	# Generate .config from annotations
+	python3 debian/scripts/misc/annotations -f "${annotations_file}" \
+			--arch "${arch}" --flavour "${flavour}" --export > build/.config
+
+	# Environment variables for 'make *config'
+	env=(ARCH="${kern_arch}"
+		 DEB_ARCH="${arch}"
+		 CROSS_COMPILE="${cross_compile}"
+		 CC="${gcc_path}")
+
+	# Concurrency level
+	if [ -n "${conc_level:-}" ] ; then
+		env+=("${conc_level}")
+	fi
+
+	# Call config target
+	echo
+	echo "* Run ${target} on ${arch}/${flavour} ..."
+	${kmake} O=build "${env[@]}" "${target}"
+
+	# Move config for further processing
+	mv build/.config "${tmp_conf_file}"
+done
+
+rc=0
+
+if [ "${skip_checks:-}" = "true" ] ; then
+	echo
+	echo "Skipping config-check (skip_checks=${skip_checks}) ..."
+else
+	echo
+	echo "Running config-check for all configurations ..."
+	fail=0
+	for arch_flavour in ${FLAVOURS} ; do
+		arch=${arch_flavour%%-*}
+		flavour=${arch_flavour#*-}
+		tmp_conf_file=${TMP_DIR}/${arch}-config.flavour.${flavour}
+
+		echo
+		echo "* Run config-check for ${arch}-${flavour} ..."
+		python3 debian/scripts/misc/annotations -f "${annotations_file}" \
+				--arch "${arch}" --flavour "${flavour}" --check "${tmp_conf_file}" || \
+			fail=$((fail + 1))
+	done
+
+	if [ ${fail} -gt 0 ] ; then
+		rc=1
+		echo "ERROR: ${fail} config-check failures detected" >&2
+	fi
+fi
+
+if [ ${#warning_partial[@]} -gt 0 ] ; then
+	rc=1
+	echo "ERROR: Config operation not applied to all architectures (skipped ${warning_partial[*]})" >&2
+fi
+
+# Recreate the annotations file
+if [ "${mode}" = "genconfigs" ] ; then
+	rm -rf CONFIGS
+	mv "${TMP_DIR}" CONFIGS
+else
+	echo
+	echo "Importing all configurations ..."
+	echo
+	for arch_flavour in ${FLAVOURS} ; do
+		arch=${arch_flavour%%-*}
+		flavour=${arch_flavour#*-}
+		tmp_conf_file=${TMP_DIR}/${arch}-config.flavour.${flavour}
+
+		echo "* Import configs for ${arch}-${flavour} ..."
+		python3 debian/scripts/misc/annotations -f "${annotations_file}" \
+				--arch "${arch}" --flavour "${flavour}" --import "${tmp_conf_file}"
+	done
+fi
+
+exit "${rc}"
--- linux-qcom-6.8.0.orig/debian/scripts/module-inclusion
+++ linux-qcom-6.8.0/debian/scripts/module-inclusion
@@ -0,0 +1,104 @@
+#!/bin/bash
+
+#
+# Build a new directory of modules based on an inclusion list.
+# The includsion list format must be a bash regular expression.
+#
+# usage: $0 ROOT INCLUSION_LIST
+# example: $0 \
+#       debian/build/build-virtual-ALL debian/build/build-virtual \
+#	debian.master/control.d/virtual.inclusion-list \
+#	virtual.depmap
+master=0
+if [ "$1" = "--master" ]; then
+	master=1
+	shift
+fi
+
+ROOT=$1
+NROOT=$2
+ILIST=$3
+DEPMAP=$4
+
+tmp="/tmp/module-inclusion.$$"
+
+#
+# Prep a destination directory.
+#
+mkdir -p ${NROOT}
+
+{
+	# Copy over the framework into the master package.
+	if  [ "$master" -eq 1 ]; then
+		(cd ${ROOT}; find . ! -name "*.ko" -type f)
+	fi
+
+	# Copy over modules by name or pattern.
+	while read -r i
+	do
+		#
+		# 'find' blurts a warning if it cannot find any ko files.
+		#
+		case "$i" in
+		\!*)
+			(cd ${ROOT}; ${i#!} || true)
+			;;
+		*\**)
+			(cd ${ROOT}; eval find "${i}" -name "*.ko" || true)
+			;;
+		*)
+			echo "$i"
+			;;
+		esac
+	done <"${ILIST}"
+} >"$tmp"
+
+# Copy over the listed modules.
+while read i
+do
+	# If this is already moved over, all is good.
+	if [ -f "${NROOT}/$i" ]; then
+		:
+
+	# If present in the source, moved it over.
+	elif [ -f "${ROOT}/$i" ]; then
+		mkdir -p "${NROOT}/`dirname $i`"
+		mv "${ROOT}/$i" "${NROOT}/$i"
+
+	# Otherwise, it is missing.
+	else
+		echo "Warning: Could not find ${ROOT}/$i" 1>&2
+	fi
+done <"$tmp"
+
+# Copy over any dependancies, note if those are missing
+# we know they are in a pre-requisite package as they must
+# have existed at depmap generation time, and can only have
+# moved into a package.
+let n=0 || true
+while [ -s "$tmp" ]
+do
+	let n="$n+1" || true
+	[ "$n" = "20" ] && break || true
+
+	echo "NOTE: pass $n: dependency scan" 1>&2
+
+	while read i
+	do
+		grep "^$i " "$DEPMAP" | \
+		while read m d
+		do
+			if [ -f "${ROOT}/$d" ]; then
+				echo "NOTE: pass $n: ${i} pulls in ${d}" 1>&2
+				echo "$d"
+				mkdir -p "${NROOT}/`dirname $d`"
+				mv "${ROOT}/$d" "${NROOT}/$d"
+			fi
+		done
+	done <"$tmp" >"$tmp.new"
+	mv -f "$tmp.new" "$tmp"
+done
+
+rm -f "$tmp"
+
+exit 0
--- linux-qcom-6.8.0.orig/debian/scripts/sign-module
+++ linux-qcom-6.8.0/debian/scripts/sign-module
@@ -0,0 +1,40 @@
+#!/bin/bash -eu
+#
+# Staging drivers must not be signed if they are not listed in a
+# signature-inclusion file to prevent loading of 'unsafe' drivers in a
+# Secure Boot environment.
+#
+# Exit with status 0 if the provided module needs to be signed, 1 otherwise
+#
+
+mod=${1}
+
+# Sign the module if not a staging driver
+if [ "${mod/\/drivers\/staging\//}" = "${mod}" ] ; then
+	exit 0
+fi
+
+root=$(dirname "$(realpath -e "${0}")")/../..
+. "${root}"/debian/debian.env
+
+# Collect the signature-inclusion files
+sig_incls=()
+for d in debian "${DEBIAN}" ; do
+	if [ -f "${root}"/"${d}"/signature-inclusion ] ; then
+		sig_incls+=("${root}"/"${d}"/signature-inclusion)
+	fi
+done
+
+# Sign the module if no signature-inclusion files
+if [ ${#sig_incls[@]} -eq 0 ] ; then
+	exit 0
+fi
+
+# Sign the module if listed in signature-inclusion files
+if grep -qFx "${mod##*/}" "${sig_incls[@]}" ; then
+	exit 0
+fi
+
+# Don't sign the module
+echo "UBUNTU: Not signing ${1}"
+exit 1
--- linux-qcom-6.8.0.orig/debian/signature-inclusion
+++ linux-qcom-6.8.0/debian/signature-inclusion
@@ -0,0 +1,12 @@
+#
+# This file lists the staging drivers that are safe for signing
+# and loading in a secure boot environment with signed module enforcement.
+#
+r8188eu.ko
+r8192e_pci.ko
+r8192u_usb.ko
+r8712u.ko
+rtllib_crypt_ccmp.ko
+rtllib_crypt_tkip.ko
+rtllib_crypt_wep.ko
+rtllib.ko
--- linux-qcom-6.8.0.orig/debian/snapcraft.mk
+++ linux-qcom-6.8.0/debian/snapcraft.mk
@@ -0,0 +1,11 @@
+ifeq ($(ARCH),)
+  arch := $(shell uname -m | sed -e s/i.86/i386/ -e s/x86_64/amd64/ \
+            -e s/arm.*/armhf/ -e s/s390/s390x/ -e s/ppc.*/powerpc/ \
+            -e s/aarch64.*/arm64/ )
+else ifeq ($(ARCH),arm)
+  arch := armhf
+else
+  arch := $(ARCH)
+endif
+config:
+	python3 debian/scripts/misc/annotations --export --arch $(arch) --flavour $(flavour) >.config
--- linux-qcom-6.8.0.orig/debian/source/format
+++ linux-qcom-6.8.0/debian/source/format
@@ -0,0 +1 @@
+1.0
--- linux-qcom-6.8.0.orig/debian/source/options
+++ linux-qcom-6.8.0/debian/source/options
@@ -0,0 +1,9 @@
+# Ignore vbox symlinks, we will regenerate these at clean (LP:1426113)
+## autoreconstruct -- begin
+# Ignore any symlinks created since the orig which are rebuilt by reconstruct.
+extend-diff-ignore=^include/dt-bindings/arm/qcom_dma_heap_dt_constants.h$
+## autoreconstruct -- end
+
+# force "dpkg-source -I -i" behavior
+diff-ignore
+tar-ignore
--- linux-qcom-6.8.0.orig/debian/templates/extra.postinst.in
+++ linux-qcom-6.8.0/debian/templates/extra.postinst.in
@@ -0,0 +1,20 @@
+#!/bin/sh
+set -e
+
+version=@abiname@@localversion@
+image_path=/boot/@image-stem@-$version
+
+if [ "$1" != configure ]; then
+    exit 0
+fi
+
+depmod -a -F /boot/System.map-$version $version || true
+if [ -d /etc/kernel/postinst.d ]; then
+    cat - >/usr/lib/linux/triggers/$version <<EOF
+DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \
+	    --arg="$image_path" /etc/kernel/postinst.d
+EOF
+    dpkg-trigger --no-await linux-update-$version
+fi
+
+exit 0
--- linux-qcom-6.8.0.orig/debian/templates/extra.postrm.in
+++ linux-qcom-6.8.0/debian/templates/extra.postrm.in
@@ -0,0 +1,31 @@
+#!/bin/sh
+set -e
+
+version=@abiname@@localversion@
+image_path=/boot/@image-stem@-$version
+
+if [ "$1" != remove ]; then
+    exit 0
+fi
+
+depmod -a -F /boot/System.map-$version $version 2>/dev/null || true
+#
+# We should be rebuilding the initramfs here on removal to pare down the
+# initramfs if it contains any of the objects we just removed.  But people
+# commonly remove kernels in order to free space in /boot, and rebuilding the
+# initramfs now risks ENOSPC when we are trying to make space.  The files we
+# leave lying about could be confusing, but we trade that against safety on
+# removal.
+#
+#if [ -d /etc/kernel/postinst.d ]; then
+#    # We want to behave as if linux-image (without us) was installed, therefore
+#    # we do not want the postinst support to know we are being removed, claim
+#    # this is an installation event.
+#    cat - >/usr/lib/linux/triggers/$version <<EOF
+#DEB_MAINT_PARAMS="configure" run-parts --report --exit-on-error --arg=$version \
+#	--arg="$image_path" /etc/kernel/postinst.d
+#EOF
+#    dpkg-trigger --no-await linux-update-$version
+#fi
+
+exit 0
--- linux-qcom-6.8.0.orig/debian/templates/headers.postinst.in
+++ linux-qcom-6.8.0/debian/templates/headers.postinst.in
@@ -0,0 +1,15 @@
+#!/bin/sh
+set -e
+
+version=@abiname@@localversion@
+
+if [ "$1" != configure ]; then
+    exit 0
+fi
+
+if [ -d /etc/kernel/header_postinst.d ]; then
+    DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \
+		/etc/kernel/header_postinst.d
+fi
+
+exit 0
--- linux-qcom-6.8.0.orig/debian/templates/image.postinst.in
+++ linux-qcom-6.8.0/debian/templates/image.postinst.in
@@ -0,0 +1,62 @@
+#!/bin/sh
+set -e
+
+version=@abiname@@localversion@
+image_path=/boot/@image-stem@-$version
+
+#
+# When we install linux-image we have to run kernel postinst.d support to
+# generate the initramfs, create links etc.  Should it have an associated
+# linux-image-extra package and we install that we also need to run kernel
+# postinst.d, to regenerate the initramfs.  If we are installing both at the
+# same time, we necessarily trigger kernel postinst.d twice. As this includes
+# rebuilding the initramfs and reconfiguring the boot loader this is very time
+# consuming.
+#
+# Similarly for removal when we remove the linux-image-extra package we need to
+# run kernel postinst.d handling in order to pare down the initramfs to
+# linux-image contents only.  When we remove the linux-image need to remove the
+# now redundant initramfs.  If we are removing both at the same time, then
+# we will rebuilt the initramfs and then immediatly remove it.
+#
+# Switches to using a trigger against the linux-image package for all
+# postinst.d and postrm.d handling.  On installation postinst.d gets triggered
+# twice once by linux-image and once by linux-image-extra.  As triggers are
+# non-cumulative we will only run this processing once.  When removing both
+# packages we will trigger postinst.d from linux-image-extra and then in
+# linux-image postrm.d we effectivly ignore the pending trigger and simply run
+# the postrm.d.  This prevents us from rebuilding the initramfs.
+#
+if [ "$1" = triggered ]; then
+    trigger=/usr/lib/linux/triggers/$version
+    if [ -f "$trigger" ]; then
+	sh "$trigger"
+	rm -f "$trigger"
+    fi
+    exit 0
+fi
+
+if [ "$1" != configure ]; then
+    exit 0
+fi
+
+depmod $version
+
+if [ -f /lib/modules/$version/.fresh-install ]; then
+    change=install
+else
+    change=upgrade
+fi
+linux-update-symlinks $change $version $image_path
+rm -f /lib/modules/$version/.fresh-install
+
+if [ -d /etc/kernel/postinst.d ]; then
+    mkdir -p /usr/lib/linux/triggers
+    cat - >/usr/lib/linux/triggers/$version <<EOF
+DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \
+      --arg=$image_path /etc/kernel/postinst.d
+EOF
+    dpkg-trigger --no-await linux-update-$version
+fi
+
+exit 0
--- linux-qcom-6.8.0.orig/debian/templates/image.postrm.in
+++ linux-qcom-6.8.0/debian/templates/image.postrm.in
@@ -0,0 +1,40 @@
+#!/bin/sh
+set -e
+
+version=@abiname@@localversion@
+image_path=/boot/@image-stem@-$version
+
+rm -f /lib/modules/$version/.fresh-install
+
+if [ "$1" != upgrade ] && command -v linux-update-symlinks >/dev/null; then
+    linux-update-symlinks remove $version $image_path
+fi
+
+if [ -d /etc/kernel/postrm.d ]; then
+    # We cannot trigger ourselves as at the end of this we will no longer
+    # exist and can no longer respond to the trigger.  The trigger would
+    # then become lost.  Therefore we clear any pending trigger and apply
+    # postrm directly.
+    if [ -f /usr/lib/linux/triggers/$version ]; then
+	echo "$0 ... removing pending trigger"
+	rm -f /usr/lib/linux/triggers/$version
+    fi
+    DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \
+	      --arg=$image_path /etc/kernel/postrm.d
+fi
+
+if [ "$1" = purge ]; then
+    for extra_file in modules.dep modules.isapnpmap modules.pcimap \
+                      modules.usbmap modules.parportmap \
+                      modules.generic_string modules.ieee1394map \
+                      modules.ieee1394map modules.pnpbiosmap \
+                      modules.alias modules.ccwmap modules.inputmap \
+                      modules.symbols modules.ofmap \
+                      modules.seriomap modules.\*.bin \
+		      modules.softdep modules.devname; do
+	eval rm -f /lib/modules/$version/$extra_file
+    done
+    rmdir /lib/modules/$version || true
+fi
+
+exit 0
--- linux-qcom-6.8.0.orig/debian/templates/image.preinst.in
+++ linux-qcom-6.8.0/debian/templates/image.preinst.in
@@ -0,0 +1,22 @@
+#!/bin/sh
+set -e
+
+version=@abiname@@localversion@
+image_path=/boot/@image-stem@-$version
+
+if [ "$1" = abort-upgrade ]; then
+    exit 0
+fi
+
+if [ "$1" = install ]; then
+    # Create a flag file for postinst
+    mkdir -p /lib/modules/$version
+    touch /lib/modules/$version/.fresh-install
+fi
+
+if [ -d /etc/kernel/preinst.d ]; then
+    DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \
+	      --arg=$image_path /etc/kernel/preinst.d
+fi
+
+exit 0
--- linux-qcom-6.8.0.orig/debian/templates/image.prerm.in
+++ linux-qcom-6.8.0/debian/templates/image.prerm.in
@@ -0,0 +1,18 @@
+#!/bin/sh
+set -e
+
+version=@abiname@@localversion@
+image_path=/boot/@image-stem@-$version
+
+if [ "$1" != remove ]; then
+    exit 0
+fi
+
+linux-check-removal $version
+
+if [ -d /etc/kernel/prerm.d ]; then
+    DEB_MAINT_PARAMS="$*" run-parts --report --exit-on-error --arg=$version \
+	      --arg=$image_path /etc/kernel/prerm.d
+fi
+
+exit 0
--- linux-qcom-6.8.0.orig/debian/tests-build/README
+++ linux-qcom-6.8.0/debian/tests-build/README
@@ -0,0 +1,21 @@
+Scripts placed in this directory get called one at a time by run-parts(8).
+The scripts are expected to perform some sort of sanity checks on the
+finished build. Scripts will be called once for each flavour.
+
+Some environment variables are exported to make life a little easier:
+
+DPKG_ARCH     : The dpkg architecture (e.g. "amd64")
+KERN_ARCH     : The kernel architecture (e.g. "x86_64")
+FLAVOUR       : The specific flavour for this run (e.g. "generic")
+VERSION       : The full version of this build (e.g. 2.6.22-1)
+REVISION      : The exact revision of this build (e.g. 1.3)
+PREV_REVISION : The revision prior to this one
+ABI_NUM       : The specific ABI number for this build (e.g. 2)
+PREV_ABI_NUM  : The previous ABI number. Can be the same as ABI_NUM.
+BUILD_DIR     : The directory where this build took place
+INSTALL_DIR   : The directory where the package is prepared
+SOURCE_DIR    : Where the main kernel source is
+
+Scripts are expected to have a zero exit status when no problems occur,
+and non-zero when an error occurs that should stop the build. Scripts
+should print whatever info they deem needed to deduce the problem.
--- linux-qcom-6.8.0.orig/debian/tests-build/check-aliases
+++ linux-qcom-6.8.0/debian/tests-build/check-aliases
@@ -0,0 +1,26 @@
+#!/usr/bin/perl -w
+
+my %map;
+
+print "Checking for dupe aliases in $ENV{'FLAVOUR'}...\n";
+
+$aliases =
+  "$ENV{'INSTALL_DIR'}/lib/modules/$ENV{'VERSION'}-$ENV{'FLAVOUR'}/modules.alias";
+
+exit 0 unless (-e $aliases);
+
+open(ALIASES, "< $aliases") or die "Could not open $aliases";
+
+while (<ALIASES>) {
+	chomp;
+	my ($junk, $alias, $module) = split;
+
+	if (defined($map{$alias})) {
+		printf("%s %20s / %-20s : %s \n", ("$map{$alias}" eq "$module")
+			? "INT" : "   ", $map{$alias}, $module, $alias);
+	} else {
+		$map{$alias} = $module;
+	}
+}
+
+exit(0);
--- linux-qcom-6.8.0.orig/debian/tests/control
+++ linux-qcom-6.8.0/debian/tests/control
@@ -0,0 +1,7 @@
+Tests: rebuild
+Depends: @builddeps@, fakeroot
+Restrictions: allow-stderr, skippable
+
+Tests: ubuntu-regression-suite
+Depends: build-essential, fakeroot, gcc-multilib [amd64 armhf i386], gdb, git, python3
+Restrictions: allow-stderr, isolation-machine, breaks-testbed, skippable
--- linux-qcom-6.8.0.orig/debian/tests/rebuild
+++ linux-qcom-6.8.0/debian/tests/rebuild
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# If we are triggering for just linux or linux-meta we know we have
+# just built the kernel and there is no point in repeating that
+# build, it just wastes time.  (LP: #1498862)
+build_needed=0
+for trigger in ${ADT_TEST_TRIGGERS:-force}
+do
+	case "$trigger" in
+	linux/*|linux-lts-*/*|linux-meta*/*|linux-oem*/*|fakeroot/*|gdb/*|git/*|bzr/*|gcc-multilib/*)	;;
+	*)						build_needed=1 ;;
+	esac
+done
+if [ "$build_needed" -eq 0 ]; then
+	echo "rebuild: short circuiting build for '${ADT_TEST_TRIGGERS}'"
+	exit 77
+fi
+
+set -e
+dpkg-buildpackage -rfakeroot -us -uc -b -Pautopkgtest
--- linux-qcom-6.8.0.orig/debian/tests/ubuntu-regression-suite
+++ linux-qcom-6.8.0/debian/tests/ubuntu-regression-suite
@@ -0,0 +1,46 @@
+#!/bin/sh
+set -e
+
+# Only run regression-suite on kernels we can boot in canonistack
+source=`dpkg-parsechangelog -SSource`
+case $source in
+    linux|linux-unstable|linux-hwe*|linux-lowlatency*|linux-kvm|linux-oem)
+	;;
+    *)
+	echo "ubuntu-regression-suite is pointless, if one cannot boot the kernel"
+	exit 77
+	;;
+esac
+
+# Only run regression-suite if we were requested to
+have_meta=0
+for trigger in ${ADT_TEST_TRIGGERS}
+do
+    case "$trigger" in
+	linux-meta/*|linux-meta-*/*)
+	    have_meta=1
+	    ;;
+    esac
+done
+if [ -n "$ADT_TEST_TRIGGERS" ] && [ "$have_meta" -eq 0 ]; then
+    echo "ubuntu-regression-suite is not requested, as there is no linux-meta trigger"
+    exit 77
+fi
+
+sver=`dpkg-parsechangelog -SVersion`
+read x rver x </proc/version_signature
+
+flavour=${rver#*-*-}
+rver=${rver%-$flavour}
+
+echo "Source Package Version: $sver"
+echo "Running Kernel Version: $rver"
+
+if [ "$sver" != "$rver" ]; then
+    echo "ERROR: running version does not match source package" 1>&2
+    exit 1
+fi
+
+git clone --depth=1 -b autotest3 git://git.launchpad.net/~canonical-kernel-team/+git/kernel-testing
+git -C kernel-testing/ show HEAD -q
+kernel-testing/run-dep8-tests
--- linux-qcom-6.8.0.orig/debian/tools/generic
+++ linux-qcom-6.8.0/debian/tools/generic
@@ -0,0 +1,60 @@
+#!/bin/bash
+full_version=`uname -r`
+
+# First check for a fully qualified version.
+this="/usr/lib/linux-tools/$full_version/`basename $0`"
+if [ -f "$this" ]; then
+	exec "$this" "$@"
+fi
+
+# Removing flavour from version i.e. generic or server.
+flavour_abi=${full_version#*-}
+flavour=${flavour_abi#*-}
+version=${full_version%-$flavour}
+this="$0_$version"
+if [ -f "$this" ]; then
+	exec "$this" "$@"
+fi
+
+# Before saucy kernels we had no flavour linkage.
+if dpkg --compare-versions "$version" lt "3.11.0"; then
+	flavour=''
+else
+	flavour="-$flavour"
+fi
+# Hint at the cloud tools if they exist (trusty and later)
+if dpkg --compare-versions "$version" ge "3.13.0"; then
+	cld=""
+else
+	cld=":"
+fi
+# Work out if this is an LTS backport or not.
+codename=`lsb_release -cs`
+case "$codename" in
+precise)	base='3.2.0-9999' ;;
+trusty)		base='3.13.0-9999' ;;
+*)		base='' ;;
+esac
+std=""
+lts=":"
+if [ "$base" != "" ]; then
+	if dpkg --compare-versions "$version" gt "$base"; then
+		std=":"
+		lts=""
+	fi
+fi
+
+# Give them a hint as to what to install.
+		echo "WARNING: `basename $0` not found for kernel $version" >&2
+		echo "" >&2
+		echo "  You may need to install the following packages for this specific kernel:" >&2
+		echo "    linux-tools-$version$flavour" >&2
+$cld		echo "    linux-cloud-tools-$version$flavour" >&2
+		echo "" >&2
+		echo "  You may also want to install one of the following packages to keep up to date:" >&2
+$std		echo "    linux-tools$flavour" >&2
+$std $cld	echo "    linux-cloud-tools$flavour" >&2
+$lts		echo "    linux-tools$flavour-lts-<series>" >&2
+$lts $cld	echo "    linux-cloud-tools$flavour-lts-<series>" >&2
+
+exit 2
--- linux-qcom-6.8.0.orig/debian/tools/python-perf.py
+++ linux-qcom-6.8.0/debian/tools/python-perf.py
@@ -0,0 +1,34 @@
+import os
+import importlib.util
+from glob import glob
+
+
+class KernelNotFoundError(Exception):
+    def __init__(self):
+        kernel_version = os.uname().release
+        flavor = kernel_version.split("-", 2)[2]
+        super().__init__(
+            f"\nWARNING: python perf module not found for kernel {kernel_version}\n\n"
+            f"  You may need to install the following package for this specific kernel:\n"
+            f"    linux-tools-{kernel_version}\n\n"
+            f"  You may also want to install the following package to keep up to date:\n"
+            f"    linux-tools-{flavor}"
+        )
+
+
+# Load the actual python-perf module for the running kernel
+_kernel_version = os.uname().release
+_perf_dir = f"/usr/lib/linux-tools/{_kernel_version}/lib"
+if not os.path.exists(_perf_dir):
+    _abi_version = "-".join(_kernel_version.split("-")[0:2])
+    _perf_dir = f"/usr/lib/python3/dist-packages/linux-tools-{_abi_version}"
+    if not os.path.exists(_perf_dir):
+        raise KernelNotFoundError()
+_perf_lib = glob(os.path.join(_perf_dir, "perf.*.so"))[-1]
+
+_spec = importlib.util.spec_from_file_location("perf", _perf_lib)
+_perf = importlib.util.module_from_spec(_spec)
+_spec.loader.exec_module(_perf)
+
+# Expose the 'perf' module.
+__all__ = ["perf"]
--- linux-qcom-6.8.0.orig/debian/v4l2loopback-modules.ignore
+++ linux-qcom-6.8.0/debian/v4l2loopback-modules.ignore
@@ -0,0 +1 @@
+v4l2loopback
--- linux-qcom-6.8.0.orig/debian/zfs-modules.ignore
+++ linux-qcom-6.8.0/debian/zfs-modules.ignore
@@ -0,0 +1,11 @@
+icp
+spl
+splat
+zavl
+zcommon
+zfs
+zlua
+znvpair
+zpios
+zunicode
+zzstd
--- linux-qcom-6.8.0.orig/drivers/Makefile
+++ linux-qcom-6.8.0/drivers/Makefile
@@ -66,14 +66,9 @@
 # iommu/ comes before gpu as gpu are using iommu controllers
 obj-y				+= iommu/
 
-# gpu/ comes after char for AGP vs DRM startup and after iommu
-obj-y				+= gpu/
 
 obj-$(CONFIG_CONNECTOR)		+= connector/
 
-# i810fb depends on char/agp/
-obj-$(CONFIG_FB_I810)           += video/fbdev/i810/
-
 obj-$(CONFIG_PARPORT)		+= parport/
 obj-y				+= base/ block/ misc/ mfd/ nfc/
 obj-$(CONFIG_LIBNVDIMM)		+= nvdimm/
@@ -85,6 +80,11 @@
 obj-y				+= scsi/
 obj-y				+= nvme/
 obj-$(CONFIG_ATA)		+= ata/
+
+# gpu/ comes after char for AGP vs DRM startup and after iommu
+obj-y				+= gpu/
+# i810fb depends on char/agp/
+obj-$(CONFIG_FB_I810)           += video/fbdev/i810/
 obj-$(CONFIG_TARGET_CORE)	+= target/
 obj-$(CONFIG_MTD)		+= mtd/
 obj-$(CONFIG_SPI)		+= spi/
--- linux-qcom-6.8.0.orig/drivers/accel/drm_accel.c
+++ linux-qcom-6.8.0/drivers/accel/drm_accel.c
@@ -8,7 +8,7 @@
 
 #include <linux/debugfs.h>
 #include <linux/device.h>
-#include <linux/idr.h>
+#include <linux/xarray.h>
 
 #include <drm/drm_accel.h>
 #include <drm/drm_auth.h>
@@ -18,8 +18,7 @@
 #include <drm/drm_ioctl.h>
 #include <drm/drm_print.h>
 
-static DEFINE_SPINLOCK(accel_minor_lock);
-static struct idr accel_minors_idr;
+DEFINE_XARRAY_ALLOC(accel_minors_xa);
 
 static struct dentry *accel_debugfs_root;
 
@@ -118,99 +117,6 @@
 }
 
 /**
- * accel_minor_alloc() - Allocates a new accel minor
- *
- * This function access the accel minors idr and allocates from it
- * a new id to represent a new accel minor
- *
- * Return: A new id on success or error code in case idr_alloc failed
- */
-int accel_minor_alloc(void)
-{
-	unsigned long flags;
-	int r;
-
-	spin_lock_irqsave(&accel_minor_lock, flags);
-	r = idr_alloc(&accel_minors_idr, NULL, 0, ACCEL_MAX_MINORS, GFP_NOWAIT);
-	spin_unlock_irqrestore(&accel_minor_lock, flags);
-
-	return r;
-}
-
-/**
- * accel_minor_remove() - Remove an accel minor
- * @index: The minor id to remove.
- *
- * This function access the accel minors idr and removes from
- * it the member with the id that is passed to this function.
- */
-void accel_minor_remove(int index)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&accel_minor_lock, flags);
-	idr_remove(&accel_minors_idr, index);
-	spin_unlock_irqrestore(&accel_minor_lock, flags);
-}
-
-/**
- * accel_minor_replace() - Replace minor pointer in accel minors idr.
- * @minor: Pointer to the new minor.
- * @index: The minor id to replace.
- *
- * This function access the accel minors idr structure and replaces the pointer
- * that is associated with an existing id. Because the minor pointer can be
- * NULL, we need to explicitly pass the index.
- *
- * Return: 0 for success, negative value for error
- */
-void accel_minor_replace(struct drm_minor *minor, int index)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&accel_minor_lock, flags);
-	idr_replace(&accel_minors_idr, minor, index);
-	spin_unlock_irqrestore(&accel_minor_lock, flags);
-}
-
-/*
- * Looks up the given minor-ID and returns the respective DRM-minor object. The
- * refence-count of the underlying device is increased so you must release this
- * object with accel_minor_release().
- *
- * The object can be only a drm_minor that represents an accel device.
- *
- * As long as you hold this minor, it is guaranteed that the object and the
- * minor->dev pointer will stay valid! However, the device may get unplugged and
- * unregistered while you hold the minor.
- */
-static struct drm_minor *accel_minor_acquire(unsigned int minor_id)
-{
-	struct drm_minor *minor;
-	unsigned long flags;
-
-	spin_lock_irqsave(&accel_minor_lock, flags);
-	minor = idr_find(&accel_minors_idr, minor_id);
-	if (minor)
-		drm_dev_get(minor->dev);
-	spin_unlock_irqrestore(&accel_minor_lock, flags);
-
-	if (!minor) {
-		return ERR_PTR(-ENODEV);
-	} else if (drm_dev_is_unplugged(minor->dev)) {
-		drm_dev_put(minor->dev);
-		return ERR_PTR(-ENODEV);
-	}
-
-	return minor;
-}
-
-static void accel_minor_release(struct drm_minor *minor)
-{
-	drm_dev_put(minor->dev);
-}
-
-/**
  * accel_open - open method for ACCEL file
  * @inode: device inode
  * @filp: file pointer.
@@ -227,7 +133,7 @@
 	struct drm_minor *minor;
 	int retcode;
 
-	minor = accel_minor_acquire(iminor(inode));
+	minor = drm_minor_acquire(&accel_minors_xa, iminor(inode));
 	if (IS_ERR(minor))
 		return PTR_ERR(minor);
 
@@ -246,7 +152,7 @@
 
 err_undo:
 	atomic_dec(&dev->open_count);
-	accel_minor_release(minor);
+	drm_minor_release(minor);
 	return retcode;
 }
 EXPORT_SYMBOL_GPL(accel_open);
@@ -257,7 +163,7 @@
 	struct drm_minor *minor;
 	int err;
 
-	minor = accel_minor_acquire(iminor(inode));
+	minor = drm_minor_acquire(&accel_minors_xa, iminor(inode));
 	if (IS_ERR(minor))
 		return PTR_ERR(minor);
 
@@ -274,7 +180,7 @@
 		err = 0;
 
 out:
-	accel_minor_release(minor);
+	drm_minor_release(minor);
 
 	return err;
 }
@@ -290,15 +196,13 @@
 	unregister_chrdev(ACCEL_MAJOR, "accel");
 	debugfs_remove(accel_debugfs_root);
 	accel_sysfs_destroy();
-	idr_destroy(&accel_minors_idr);
+	WARN_ON(!xa_empty(&accel_minors_xa));
 }
 
 int __init accel_core_init(void)
 {
 	int ret;
 
-	idr_init(&accel_minors_idr);
-
 	ret = accel_sysfs_init();
 	if (ret < 0) {
 		DRM_ERROR("Cannot create ACCEL class: %d\n", ret);
--- linux-qcom-6.8.0.orig/drivers/accel/habanalabs/common/debugfs.c
+++ linux-qcom-6.8.0/drivers/accel/habanalabs/common/debugfs.c
@@ -1643,19 +1643,19 @@
 				&hl_data64b_fops);
 
 	debugfs_create_file("set_power_state",
-				0200,
+				0644,
 				root,
 				dev_entry,
 				&hl_power_fops);
 
 	debugfs_create_file("device",
-				0200,
+				0644,
 				root,
 				dev_entry,
 				&hl_device_fops);
 
 	debugfs_create_file("clk_gate",
-				0200,
+				0644,
 				root,
 				dev_entry,
 				&hl_clk_gate_fops);
@@ -1667,13 +1667,13 @@
 				&hl_stop_on_err_fops);
 
 	debugfs_create_file("dump_security_violations",
-				0644,
+				0400,
 				root,
 				dev_entry,
 				&hl_security_violations_fops);
 
 	debugfs_create_file("dump_razwi_events",
-				0644,
+				0400,
 				root,
 				dev_entry,
 				&hl_razwi_check_fops);
@@ -1706,7 +1706,7 @@
 				&hdev->reset_info.skip_reset_on_timeout);
 
 	debugfs_create_file("state_dump",
-				0600,
+				0644,
 				root,
 				dev_entry,
 				&hl_state_dump_fops);
@@ -1724,7 +1724,7 @@
 
 	for (i = 0, entry = dev_entry->entry_arr ; i < count ; i++, entry++) {
 		debugfs_create_file(hl_debugfs_list[i].name,
-					0444,
+					0644,
 					root,
 					entry,
 					&hl_debugfs_fops);
--- linux-qcom-6.8.0.orig/drivers/accel/habanalabs/common/habanalabs.h
+++ linux-qcom-6.8.0/drivers/accel/habanalabs/common/habanalabs.h
@@ -2547,7 +2547,7 @@
  * DEVICES
  */
 
-#define HL_STR_MAX	32
+#define HL_STR_MAX	64
 
 #define HL_DEV_STS_MAX (HL_DEVICE_STATUS_LAST + 1)
 
--- linux-qcom-6.8.0.orig/drivers/accel/habanalabs/gaudi2/gaudi2_security.c
+++ linux-qcom-6.8.0/drivers/accel/habanalabs/gaudi2/gaudi2_security.c
@@ -479,6 +479,7 @@
 	mmDCORE0_EDMA0_CORE_CTX_TE_NUMROWS,
 	mmDCORE0_EDMA0_CORE_CTX_IDX,
 	mmDCORE0_EDMA0_CORE_CTX_IDX_INC,
+	mmDCORE0_EDMA0_CORE_WR_COMP_MAX_OUTSTAND,
 	mmDCORE0_EDMA0_CORE_RD_LBW_RATE_LIM_CFG,
 	mmDCORE0_EDMA0_QM_CQ_CFG0_0,
 	mmDCORE0_EDMA0_QM_CQ_CFG0_1,
--- linux-qcom-6.8.0.orig/drivers/accel/ivpu/ivpu_drv.c
+++ linux-qcom-6.8.0/drivers/accel/ivpu/ivpu_drv.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
  */
 
 #include <linux/firmware.h>
@@ -131,22 +131,6 @@
 	return 0;
 }
 
-static int ivpu_get_core_clock_rate(struct ivpu_device *vdev, u64 *clk_rate)
-{
-	int ret;
-
-	ret = ivpu_rpm_get_if_active(vdev);
-	if (ret < 0)
-		return ret;
-
-	*clk_rate = ret ? ivpu_hw_reg_pll_freq_get(vdev) : 0;
-
-	if (ret)
-		ivpu_rpm_put(vdev);
-
-	return 0;
-}
-
 static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
 {
 	struct ivpu_file_priv *file_priv = file->driver_priv;
@@ -170,7 +154,7 @@
 		args->value = vdev->platform;
 		break;
 	case DRM_IVPU_PARAM_CORE_CLOCK_RATE:
-		ret = ivpu_get_core_clock_rate(vdev, &args->value);
+		args->value = ivpu_hw_ratio_to_freq(vdev, vdev->hw->pll.max_ratio);
 		break;
 	case DRM_IVPU_PARAM_NUM_CONTEXTS:
 		args->value = ivpu_get_context_count(vdev);
@@ -387,12 +371,15 @@
 {
 	int ret;
 
-	ivpu_prepare_for_reset(vdev);
+	/* Save PCI state before powering down as it sometimes gets corrupted if NPU hangs */
+	pci_save_state(to_pci_dev(vdev->drm.dev));
 
 	ret = ivpu_hw_power_down(vdev);
 	if (ret)
 		ivpu_warn(vdev, "Failed to power down HW: %d\n", ret);
 
+	pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
+
 	return ret;
 }
 
@@ -530,7 +517,7 @@
 	vdev->context_xa_limit.min = IVPU_USER_CONTEXT_MIN_SSID;
 	vdev->context_xa_limit.max = IVPU_USER_CONTEXT_MAX_SSID;
 	atomic64_set(&vdev->unique_id_counter, 0);
-	xa_init_flags(&vdev->context_xa, XA_FLAGS_ALLOC);
+	xa_init_flags(&vdev->context_xa, XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ);
 	xa_init_flags(&vdev->submitted_jobs_xa, XA_FLAGS_ALLOC1);
 	lockdep_set_class(&vdev->submitted_jobs_xa.xa_lock, &submitted_jobs_xa_lock_class_key);
 	INIT_LIST_HEAD(&vdev->bo_list);
@@ -559,11 +546,11 @@
 	/* Power up early so the rest of init code can access VPU registers */
 	ret = ivpu_hw_power_up(vdev);
 	if (ret)
-		goto err_power_down;
+		goto err_shutdown;
 
 	ret = ivpu_mmu_global_context_init(vdev);
 	if (ret)
-		goto err_power_down;
+		goto err_shutdown;
 
 	ret = ivpu_mmu_init(vdev);
 	if (ret)
@@ -600,10 +587,8 @@
 	ivpu_mmu_reserved_context_fini(vdev);
 err_mmu_gctx_fini:
 	ivpu_mmu_global_context_fini(vdev);
-err_power_down:
-	ivpu_hw_power_down(vdev);
-	if (IVPU_WA(d3hot_after_power_off))
-		pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
+err_shutdown:
+	ivpu_shutdown(vdev);
 err_xa_destroy:
 	xa_destroy(&vdev->submitted_jobs_xa);
 	xa_destroy(&vdev->context_xa);
@@ -626,9 +611,8 @@
 static void ivpu_dev_fini(struct ivpu_device *vdev)
 {
 	ivpu_pm_disable(vdev);
+	ivpu_prepare_for_reset(vdev);
 	ivpu_shutdown(vdev);
-	if (IVPU_WA(d3hot_after_power_off))
-		pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
 
 	ivpu_jobs_abort_all(vdev);
 	ivpu_job_done_consumer_fini(vdev);
--- linux-qcom-6.8.0.orig/drivers/accel/ivpu/ivpu_drv.h
+++ linux-qcom-6.8.0/drivers/accel/ivpu/ivpu_drv.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
  */
 
 #ifndef __IVPU_DRV_H__
@@ -87,7 +87,6 @@
 struct ivpu_wa_table {
 	bool punit_disabled;
 	bool clear_runtime_mem;
-	bool d3hot_after_power_off;
 	bool interrupt_clear_with_0;
 	bool disable_clock_relinquish;
 	bool disable_d0i3_msg;
--- linux-qcom-6.8.0.orig/drivers/accel/ivpu/ivpu_fw.c
+++ linux-qcom-6.8.0/drivers/accel/ivpu/ivpu_fw.c
@@ -60,6 +60,10 @@
 	{ IVPU_HW_40XX, "intel/vpu/vpu_40xx_v0.0.bin" },
 };
 
+/* Production fw_names from the table above */
+MODULE_FIRMWARE("intel/vpu/vpu_37xx_v0.0.bin");
+MODULE_FIRMWARE("intel/vpu/vpu_40xx_v0.0.bin");
+
 static int ivpu_fw_request(struct ivpu_device *vdev)
 {
 	int ret = -ENOENT;
@@ -519,8 +523,10 @@
 	boot_params->ipc_payload_area_start = ipc_mem_rx->vpu_addr + ivpu_bo_size(ipc_mem_rx) / 2;
 	boot_params->ipc_payload_area_size = ivpu_bo_size(ipc_mem_rx) / 2;
 
-	boot_params->global_aliased_pio_base = vdev->hw->ranges.user.start;
-	boot_params->global_aliased_pio_size = ivpu_hw_range_size(&vdev->hw->ranges.user);
+	if (ivpu_hw_gen(vdev) == IVPU_HW_37XX) {
+		boot_params->global_aliased_pio_base = vdev->hw->ranges.user.start;
+		boot_params->global_aliased_pio_size = ivpu_hw_range_size(&vdev->hw->ranges.user);
+	}
 
 	/* Allow configuration for L2C_PAGE_TABLE with boot param value */
 	boot_params->autoconfig = 1;
--- linux-qcom-6.8.0.orig/drivers/accel/ivpu/ivpu_gem.c
+++ linux-qcom-6.8.0/drivers/accel/ivpu/ivpu_gem.c
@@ -402,7 +402,7 @@
 	mutex_lock(&bo->lock);
 
 	drm_printf(p, "%-9p %-3u 0x%-12llx %-10lu 0x%-8x %-4u",
-		   bo, bo->ctx->id, bo->vpu_addr, bo->base.base.size,
+		   bo, bo->ctx ? bo->ctx->id : 0, bo->vpu_addr, bo->base.base.size,
 		   bo->flags, kref_read(&bo->base.base.refcount));
 
 	if (bo->base.pages)
--- linux-qcom-6.8.0.orig/drivers/accel/ivpu/ivpu_hw.h
+++ linux-qcom-6.8.0/drivers/accel/ivpu/ivpu_hw.h
@@ -21,6 +21,7 @@
 	u32 (*profiling_freq_get)(struct ivpu_device *vdev);
 	void (*profiling_freq_drive)(struct ivpu_device *vdev, bool enable);
 	u32 (*reg_pll_freq_get)(struct ivpu_device *vdev);
+	u32 (*ratio_to_freq)(struct ivpu_device *vdev, u32 ratio);
 	u32 (*reg_telemetry_offset_get)(struct ivpu_device *vdev);
 	u32 (*reg_telemetry_size_get)(struct ivpu_device *vdev);
 	u32 (*reg_telemetry_enable_get)(struct ivpu_device *vdev);
@@ -130,6 +131,11 @@
 	return vdev->hw->ops->reg_pll_freq_get(vdev);
 };
 
+static inline u32 ivpu_hw_ratio_to_freq(struct ivpu_device *vdev, u32 ratio)
+{
+	return vdev->hw->ops->ratio_to_freq(vdev, ratio);
+}
+
 static inline u32 ivpu_hw_reg_telemetry_offset_get(struct ivpu_device *vdev)
 {
 	return vdev->hw->ops->reg_telemetry_offset_get(vdev);
--- linux-qcom-6.8.0.orig/drivers/accel/ivpu/ivpu_hw_37xx.c
+++ linux-qcom-6.8.0/drivers/accel/ivpu/ivpu_hw_37xx.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
  */
 
 #include "ivpu_drv.h"
@@ -75,7 +75,6 @@
 {
 	vdev->wa.punit_disabled = false;
 	vdev->wa.clear_runtime_mem = false;
-	vdev->wa.d3hot_after_power_off = true;
 
 	REGB_WR32(VPU_37XX_BUTTRESS_INTERRUPT_STAT, BUTTRESS_ALL_IRQ_MASK);
 	if (REGB_RD32(VPU_37XX_BUTTRESS_INTERRUPT_STAT) == BUTTRESS_ALL_IRQ_MASK) {
@@ -86,7 +85,6 @@
 
 	IVPU_PRINT_WA(punit_disabled);
 	IVPU_PRINT_WA(clear_runtime_mem);
-	IVPU_PRINT_WA(d3hot_after_power_off);
 	IVPU_PRINT_WA(interrupt_clear_with_0);
 }
 
@@ -595,9 +593,9 @@
 	ivpu_pll_init_frequency_ratios(vdev);
 
 	ivpu_hw_init_range(&hw->ranges.global, 0x80000000, SZ_512M);
-	ivpu_hw_init_range(&hw->ranges.user,   0xc0000000, 255 * SZ_1M);
+	ivpu_hw_init_range(&hw->ranges.user,   0x88000000, 511 * SZ_1M);
 	ivpu_hw_init_range(&hw->ranges.shave, 0x180000000, SZ_2G);
-	ivpu_hw_init_range(&hw->ranges.dma,   0x200000000, SZ_8G);
+	ivpu_hw_init_range(&hw->ranges.dma,   0x200000000, SZ_128G);
 
 	vdev->platform = IVPU_PLATFORM_SILICON;
 	ivpu_hw_wa_init(vdev);
@@ -805,12 +803,12 @@
 	/* Profiling freq - is a debug feature. Unavailable on VPU 37XX. */
 }
 
-static u32 ivpu_hw_37xx_pll_to_freq(u32 ratio, u32 config)
+static u32 ivpu_hw_37xx_ratio_to_freq(struct ivpu_device *vdev, u32 ratio)
 {
 	u32 pll_clock = PLL_REF_CLK_FREQ * ratio;
 	u32 cpu_clock;
 
-	if ((config & 0xff) == PLL_RATIO_4_3)
+	if ((vdev->hw->config & 0xff) == PLL_RATIO_4_3)
 		cpu_clock = pll_clock * 2 / 4;
 	else
 		cpu_clock = pll_clock * 2 / 5;
@@ -829,7 +827,7 @@
 	if (!ivpu_is_silicon(vdev))
 		return PLL_SIMULATION_FREQ;
 
-	return ivpu_hw_37xx_pll_to_freq(pll_curr_ratio, vdev->hw->config);
+	return ivpu_hw_37xx_ratio_to_freq(vdev, pll_curr_ratio);
 }
 
 static u32 ivpu_hw_37xx_reg_telemetry_offset_get(struct ivpu_device *vdev)
@@ -1052,6 +1050,7 @@
 	.profiling_freq_get = ivpu_hw_37xx_profiling_freq_get,
 	.profiling_freq_drive = ivpu_hw_37xx_profiling_freq_drive,
 	.reg_pll_freq_get = ivpu_hw_37xx_reg_pll_freq_get,
+	.ratio_to_freq = ivpu_hw_37xx_ratio_to_freq,
 	.reg_telemetry_offset_get = ivpu_hw_37xx_reg_telemetry_offset_get,
 	.reg_telemetry_size_get = ivpu_hw_37xx_reg_telemetry_size_get,
 	.reg_telemetry_enable_get = ivpu_hw_37xx_reg_telemetry_enable_get,
--- linux-qcom-6.8.0.orig/drivers/accel/ivpu/ivpu_hw_40xx.c
+++ linux-qcom-6.8.0/drivers/accel/ivpu/ivpu_hw_40xx.c
@@ -730,9 +730,9 @@
 	ivpu_pll_init_frequency_ratios(vdev);
 
 	ivpu_hw_init_range(&vdev->hw->ranges.global, 0x80000000, SZ_512M);
-	ivpu_hw_init_range(&vdev->hw->ranges.user,   0x80000000, SZ_256M);
-	ivpu_hw_init_range(&vdev->hw->ranges.shave,  0x80000000 + SZ_256M, SZ_2G - SZ_256M);
-	ivpu_hw_init_range(&vdev->hw->ranges.dma,   0x200000000, SZ_8G);
+	ivpu_hw_init_range(&vdev->hw->ranges.shave,  0x80000000, SZ_2G);
+	ivpu_hw_init_range(&vdev->hw->ranges.user,  0x100000000, SZ_256G);
+	vdev->hw->ranges.dma = vdev->hw->ranges.user;
 
 	ivpu_hw_read_platform(vdev);
 	ivpu_hw_wa_init(vdev);
@@ -980,6 +980,11 @@
 	return PLL_RATIO_TO_FREQ(pll_curr_ratio);
 }
 
+static u32 ivpu_hw_40xx_ratio_to_freq(struct ivpu_device *vdev, u32 ratio)
+{
+	return PLL_RATIO_TO_FREQ(ratio);
+}
+
 static u32 ivpu_hw_40xx_reg_telemetry_offset_get(struct ivpu_device *vdev)
 {
 	return REGB_RD32(VPU_40XX_BUTTRESS_VPU_TELEMETRY_OFFSET);
@@ -1230,6 +1235,7 @@
 	.profiling_freq_get = ivpu_hw_40xx_profiling_freq_get,
 	.profiling_freq_drive = ivpu_hw_40xx_profiling_freq_drive,
 	.reg_pll_freq_get = ivpu_hw_40xx_reg_pll_freq_get,
+	.ratio_to_freq = ivpu_hw_40xx_ratio_to_freq,
 	.reg_telemetry_offset_get = ivpu_hw_40xx_reg_telemetry_offset_get,
 	.reg_telemetry_size_get = ivpu_hw_40xx_reg_telemetry_size_get,
 	.reg_telemetry_enable_get = ivpu_hw_40xx_reg_telemetry_enable_get,
--- linux-qcom-6.8.0.orig/drivers/accel/ivpu/ivpu_ipc.c
+++ linux-qcom-6.8.0/drivers/accel/ivpu/ivpu_ipc.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
  */
 
 #include <linux/genalloc.h>
@@ -292,15 +292,16 @@
 	return ret;
 }
 
-static int
+int
 ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req,
 			       enum vpu_ipc_msg_type expected_resp_type,
-			       struct vpu_jsm_msg *resp, u32 channel,
-			       unsigned long timeout_ms)
+			       struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms)
 {
 	struct ivpu_ipc_consumer cons;
 	int ret;
 
+	drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev));
+
 	ivpu_ipc_consumer_add(vdev, &cons, channel, NULL);
 
 	ret = ivpu_ipc_send(vdev, &cons, req);
@@ -326,19 +327,21 @@
 	return ret;
 }
 
-int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *req,
-				 enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp,
-				 u32 channel, unsigned long timeout_ms)
+int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req,
+			  enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp,
+			  u32 channel, unsigned long timeout_ms)
 {
 	struct vpu_jsm_msg hb_req = { .type = VPU_JSM_MSG_QUERY_ENGINE_HB };
 	struct vpu_jsm_msg hb_resp;
 	int ret, hb_ret;
 
-	drm_WARN_ON(&vdev->drm, pm_runtime_status_suspended(vdev->drm.dev));
+	ret = ivpu_rpm_get(vdev);
+	if (ret < 0)
+		return ret;
 
 	ret = ivpu_ipc_send_receive_internal(vdev, req, expected_resp, resp, channel, timeout_ms);
 	if (ret != -ETIMEDOUT)
-		return ret;
+		goto rpm_put;
 
 	hb_ret = ivpu_ipc_send_receive_internal(vdev, &hb_req, VPU_JSM_MSG_QUERY_ENGINE_HB_DONE,
 						&hb_resp, VPU_IPC_CHAN_ASYNC_CMD,
@@ -346,21 +349,7 @@
 	if (hb_ret == -ETIMEDOUT)
 		ivpu_pm_trigger_recovery(vdev, "IPC timeout");
 
-	return ret;
-}
-
-int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req,
-			  enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp,
-			  u32 channel, unsigned long timeout_ms)
-{
-	int ret;
-
-	ret = ivpu_rpm_get(vdev);
-	if (ret < 0)
-		return ret;
-
-	ret = ivpu_ipc_send_receive_active(vdev, req, expected_resp, resp, channel, timeout_ms);
-
+rpm_put:
 	ivpu_rpm_put(vdev);
 	return ret;
 }
@@ -501,7 +490,11 @@
 	spin_lock_init(&ipc->cons_lock);
 	INIT_LIST_HEAD(&ipc->cons_list);
 	INIT_LIST_HEAD(&ipc->cb_msg_list);
-	drmm_mutex_init(&vdev->drm, &ipc->lock);
+	ret = drmm_mutex_init(&vdev->drm, &ipc->lock);
+	if (ret) {
+		ivpu_err(vdev, "Failed to initialize ipc->lock, ret %d\n", ret);
+		goto err_free_rx;
+	}
 	ivpu_ipc_reset(vdev);
 	return 0;
 
--- linux-qcom-6.8.0.orig/drivers/accel/ivpu/ivpu_ipc.h
+++ linux-qcom-6.8.0/drivers/accel/ivpu/ivpu_ipc.h
@@ -99,10 +99,9 @@
 int ivpu_ipc_receive(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
 		     struct ivpu_ipc_hdr *ipc_buf, struct vpu_jsm_msg *jsm_msg,
 		     unsigned long timeout_ms);
-
-int ivpu_ipc_send_receive_active(struct ivpu_device *vdev, struct vpu_jsm_msg *req,
-				 enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp,
-				 u32 channel, unsigned long timeout_ms);
+int ivpu_ipc_send_receive_internal(struct ivpu_device *vdev, struct vpu_jsm_msg *req,
+				   enum vpu_ipc_msg_type expected_resp_type,
+				   struct vpu_jsm_msg *resp, u32 channel, unsigned long timeout_ms);
 int ivpu_ipc_send_receive(struct ivpu_device *vdev, struct vpu_jsm_msg *req,
 			  enum vpu_ipc_msg_type expected_resp, struct vpu_jsm_msg *resp,
 			  u32 channel, unsigned long timeout_ms);
--- linux-qcom-6.8.0.orig/drivers/accel/ivpu/ivpu_jsm_msg.c
+++ linux-qcom-6.8.0/drivers/accel/ivpu/ivpu_jsm_msg.c
@@ -273,9 +273,8 @@
 
 	req.payload.pwr_d0i3_enter.send_response = 1;
 
-	ret = ivpu_ipc_send_receive_active(vdev, &req, VPU_JSM_MSG_PWR_D0I3_ENTER_DONE,
-					   &resp, VPU_IPC_CHAN_GEN_CMD,
-					   vdev->timeout.d0i3_entry_msg);
+	ret = ivpu_ipc_send_receive_internal(vdev, &req, VPU_JSM_MSG_PWR_D0I3_ENTER_DONE, &resp,
+					     VPU_IPC_CHAN_GEN_CMD, vdev->timeout.d0i3_entry_msg);
 	if (ret)
 		return ret;
 
--- linux-qcom-6.8.0.orig/drivers/accel/ivpu/ivpu_mmu.c
+++ linux-qcom-6.8.0/drivers/accel/ivpu/ivpu_mmu.c
@@ -278,7 +278,7 @@
 	case IVPU_MMU_EVT_F_VMS_FETCH:
 		return "Fetch of VMS caused external abort";
 	default:
-		return "Unknown CMDQ command";
+		return "Unknown event";
 	}
 }
 
@@ -286,15 +286,15 @@
 {
 	switch (err) {
 	case IVPU_MMU_CERROR_NONE:
-		return "No CMDQ Error";
+		return "No error";
 	case IVPU_MMU_CERROR_ILL:
 		return "Illegal command";
 	case IVPU_MMU_CERROR_ABT:
-		return "External abort on CMDQ read";
+		return "External abort on command queue read";
 	case IVPU_MMU_CERROR_ATC_INV_SYNC:
 		return "Sync failed to complete ATS invalidation";
 	default:
-		return "Unknown CMDQ Error";
+		return "Unknown error";
 	}
 }
 
--- linux-qcom-6.8.0.orig/drivers/accel/ivpu/ivpu_mmu_context.c
+++ linux-qcom-6.8.0/drivers/accel/ivpu/ivpu_mmu_context.c
@@ -461,8 +461,8 @@
 		start = vdev->hw->ranges.global.start;
 		end = vdev->hw->ranges.shave.end;
 	} else {
-		start = vdev->hw->ranges.user.start;
-		end = vdev->hw->ranges.dma.end;
+		start = min_t(u64, vdev->hw->ranges.user.start, vdev->hw->ranges.shave.start);
+		end = max_t(u64, vdev->hw->ranges.user.end, vdev->hw->ranges.dma.end);
 	}
 
 	drm_mm_init(&ctx->mm, start, end - start);
--- linux-qcom-6.8.0.orig/drivers/accel/ivpu/ivpu_pm.c
+++ linux-qcom-6.8.0/drivers/accel/ivpu/ivpu_pm.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (C) 2020-2023 Intel Corporation
+ * Copyright (C) 2020-2024 Intel Corporation
  */
 
 #include <linux/highmem.h>
@@ -58,14 +58,11 @@
 {
 	int ret;
 
-	/* Save PCI state before powering down as it sometimes gets corrupted if NPU hangs */
-	pci_save_state(to_pci_dev(vdev->drm.dev));
+	ivpu_prepare_for_reset(vdev);
 
 	ret = ivpu_shutdown(vdev);
 	if (ret)
-		ivpu_err(vdev, "Failed to shutdown VPU: %d\n", ret);
-
-	pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
+		ivpu_err(vdev, "Failed to shutdown NPU: %d\n", ret);
 
 	return ret;
 }
@@ -74,10 +71,10 @@
 {
 	int ret;
 
+retry:
 	pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D0);
 	pci_restore_state(to_pci_dev(vdev->drm.dev));
 
-retry:
 	ret = ivpu_hw_power_up(vdev);
 	if (ret) {
 		ivpu_err(vdev, "Failed to power up HW: %d\n", ret);
@@ -100,6 +97,7 @@
 	ivpu_mmu_disable(vdev);
 err_power_down:
 	ivpu_hw_power_down(vdev);
+	pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
 
 	if (!ivpu_fw_is_cold_boot(vdev)) {
 		ivpu_pm_prepare_cold_boot(vdev);
@@ -309,7 +307,7 @@
 {
 	int ret;
 
-	ret = pm_runtime_get_if_active(vdev->drm.dev, false);
+	ret = pm_runtime_get_if_in_use(vdev->drm.dev);
 	drm_WARN_ON(&vdev->drm, ret < 0);
 
 	return ret;
@@ -378,6 +376,7 @@
 
 	pm_runtime_use_autosuspend(dev);
 	pm_runtime_set_autosuspend_delay(dev, delay);
+	pm_runtime_set_active(dev);
 
 	ivpu_dbg(vdev, PM, "Autosuspend delay = %d\n", delay);
 }
@@ -392,7 +391,6 @@
 {
 	struct device *dev = vdev->drm.dev;
 
-	pm_runtime_set_active(dev);
 	pm_runtime_allow(dev);
 	pm_runtime_mark_last_busy(dev);
 	pm_runtime_put_autosuspend(dev);
--- linux-qcom-6.8.0.orig/drivers/accel/qaic/qaic_control.c
+++ linux-qcom-6.8.0/drivers/accel/qaic/qaic_control.c
@@ -496,7 +496,7 @@
 	nents = sgt->nents;
 	nents_dma = nents;
 	*size = QAIC_MANAGE_EXT_MSG_LENGTH - msg_hdr_len - sizeof(**out_trans);
-	for_each_sgtable_sg(sgt, sg, i) {
+	for_each_sgtable_dma_sg(sgt, sg, i) {
 		*size -= sizeof(*asp);
 		/* Save 1K for possible follow-up transactions. */
 		if (*size < SZ_1K) {
--- linux-qcom-6.8.0.orig/drivers/accel/qaic/qaic_data.c
+++ linux-qcom-6.8.0/drivers/accel/qaic/qaic_data.c
@@ -179,7 +179,7 @@
 	nents = 0;
 
 	size = size ? size : PAGE_SIZE;
-	for (sg = sgt_in->sgl; sg; sg = sg_next(sg)) {
+	for_each_sgtable_dma_sg(sgt_in, sg, j) {
 		len = sg_dma_len(sg);
 
 		if (!len)
@@ -216,7 +216,7 @@
 
 	/* copy relevant sg node and fix page and length */
 	sgn = sgf;
-	for_each_sgtable_sg(sgt, sg, j) {
+	for_each_sgtable_dma_sg(sgt, sg, j) {
 		memcpy(sg, sgn, sizeof(*sg));
 		if (sgn == sgf) {
 			sg_dma_address(sg) += offf;
@@ -296,7 +296,7 @@
 	 * fence.
 	 */
 	dev_addr = req->dev_addr;
-	for_each_sgtable_sg(slice->sgt, sg, i) {
+	for_each_sgtable_dma_sg(slice->sgt, sg, i) {
 		slice->reqs[i].cmd = cmd;
 		slice->reqs[i].src_addr = cpu_to_le64(slice->dir == DMA_TO_DEVICE ?
 						      sg_dma_address(sg) : dev_addr);
--- linux-qcom-6.8.0.orig/drivers/accel/qaic/qaic_drv.c
+++ linux-qcom-6.8.0/drivers/accel/qaic/qaic_drv.c
@@ -32,6 +32,7 @@
 
 MODULE_IMPORT_NS(DMA_BUF);
 
+#define PCI_DEV_AIC080			0xa080
 #define PCI_DEV_AIC100			0xa100
 #define QAIC_NAME			"qaic"
 #define QAIC_DESC			"Qualcomm Cloud AI Accelerators"
@@ -322,7 +323,7 @@
 		return NULL;
 
 	qdev->dev_state = QAIC_OFFLINE;
-	if (id->device == PCI_DEV_AIC100) {
+	if (id->device == PCI_DEV_AIC080 || id->device == PCI_DEV_AIC100) {
 		qdev->num_dbc = 16;
 		qdev->dbc = devm_kcalloc(&pdev->dev, qdev->num_dbc, sizeof(*qdev->dbc), GFP_KERNEL);
 		if (!qdev->dbc)
@@ -561,6 +562,7 @@
 };
 
 static const struct pci_device_id qaic_ids[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, PCI_DEV_AIC080), },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, PCI_DEV_AIC100), },
 	{ }
 };
--- linux-qcom-6.8.0.orig/drivers/accessibility/speakup/main.c
+++ linux-qcom-6.8.0/drivers/accessibility/speakup/main.c
@@ -574,7 +574,7 @@
 	}
 	attr_ch = get_char(vc, (u_short *)tmp_pos, &spk_attr);
 	buf[cnt++] = attr_ch;
-	while (tmpx < vc->vc_cols - 1) {
+	while (tmpx < vc->vc_cols - 1 && cnt < ARRAY_SIZE(buf) - 1) {
 		tmp_pos += 2;
 		tmpx++;
 		ch = get_char(vc, (u_short *)tmp_pos, &temp);
--- linux-qcom-6.8.0.orig/drivers/accessibility/speakup/synth.c
+++ linux-qcom-6.8.0/drivers/accessibility/speakup/synth.c
@@ -208,8 +208,10 @@
 	wake_up_process(speakup_task);
 }
 
-void synth_write(const char *buf, size_t count)
+void synth_write(const char *_buf, size_t count)
 {
+	const unsigned char *buf = (const unsigned char *) _buf;
+
 	while (count--)
 		synth_buffer_add(*buf++);
 	synth_start();
--- linux-qcom-6.8.0.orig/drivers/acpi/ac.c
+++ linux-qcom-6.8.0/drivers/acpi/ac.c
@@ -145,7 +145,7 @@
 						  dev_name(&adev->dev), event,
 						  (u32) ac->state);
 		acpi_notifier_call_chain(adev, event, (u32) ac->state);
-		kobject_uevent(&ac->charger->dev.kobj, KOBJ_CHANGE);
+		power_supply_changed(ac->charger);
 	}
 }
 
@@ -268,7 +268,7 @@
 	if (acpi_ac_get_state(ac))
 		return 0;
 	if (old_state != ac->state)
-		kobject_uevent(&ac->charger->dev.kobj, KOBJ_CHANGE);
+		power_supply_changed(ac->charger);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/acpi/acpi_ipmi.c
+++ linux-qcom-6.8.0/drivers/acpi/acpi_ipmi.c
@@ -22,6 +22,8 @@
 /* the IPMI timeout is 5s */
 #define IPMI_TIMEOUT			(5000)
 #define ACPI_IPMI_MAX_MSG_LENGTH	64
+/* 2s should be suffient for SMI being selected */
+#define ACPI_IPMI_SMI_SELECTION_TIMEOUT	(2 * HZ)
 
 struct acpi_ipmi_device {
 	/* the device list attached to driver_data.ipmi_devices */
@@ -54,6 +56,7 @@
 	 * to this selected global IPMI system interface.
 	 */
 	struct acpi_ipmi_device *selected_smi;
+	struct completion smi_selection_done;
 };
 
 struct acpi_ipmi_msg {
@@ -463,8 +466,10 @@
 		if (temp->handle == handle)
 			goto err_lock;
 	}
-	if (!driver_data.selected_smi)
+	if (!driver_data.selected_smi) {
 		driver_data.selected_smi = ipmi_device;
+		complete(&driver_data.smi_selection_done);
+	}
 	list_add_tail(&ipmi_device->head, &driver_data.ipmi_devices);
 	mutex_unlock(&driver_data.ipmi_lock);
 
@@ -578,6 +583,20 @@
 	return status;
 }
 
+int acpi_wait_for_acpi_ipmi(void)
+{
+	long ret;
+
+	ret = wait_for_completion_interruptible_timeout(&driver_data.smi_selection_done,
+							ACPI_IPMI_SMI_SELECTION_TIMEOUT);
+
+	if (ret <= 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(acpi_wait_for_acpi_ipmi);
+
 static int __init acpi_ipmi_init(void)
 {
 	int result;
@@ -586,6 +605,8 @@
 	if (acpi_disabled)
 		return 0;
 
+	init_completion(&driver_data.smi_selection_done);
+
 	status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
 						    ACPI_ADR_SPACE_IPMI,
 						    &acpi_ipmi_space_handler,
--- linux-qcom-6.8.0.orig/drivers/acpi/acpi_lpss.c
+++ linux-qcom-6.8.0/drivers/acpi/acpi_lpss.c
@@ -325,6 +325,7 @@
 
 static const struct property_entry bsw_spi_properties[] = {
 	PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_BSW_SSP),
+	PROPERTY_ENTRY_U32("num-cs", 2),
 	{ }
 };
 
--- linux-qcom-6.8.0.orig/drivers/acpi/acpi_pad.c
+++ linux-qcom-6.8.0/drivers/acpi/acpi_pad.c
@@ -132,8 +132,10 @@
 {
 	struct cpumask *pad_busy_cpus = to_cpumask(pad_busy_cpus_bits);
 
-	cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
-	tsk_in_cpu[tsk_index] = -1;
+	if (tsk_in_cpu[tsk_index] != -1) {
+		cpumask_clear_cpu(tsk_in_cpu[tsk_index], pad_busy_cpus);
+		tsk_in_cpu[tsk_index] = -1;
+	}
 }
 
 static unsigned int idle_pct = 5; /* percentage */
--- linux-qcom-6.8.0.orig/drivers/acpi/acpi_processor.c
+++ linux-qcom-6.8.0/drivers/acpi/acpi_processor.c
@@ -397,7 +397,7 @@
 
 	result = acpi_processor_get_info(device);
 	if (result) /* Processor is not physically present or unavailable */
-		return 0;
+		goto err_clear_driver_data;
 
 	BUG_ON(pr->id >= nr_cpu_ids);
 
@@ -412,7 +412,7 @@
 			"BIOS reported wrong ACPI id %d for the processor\n",
 			pr->id);
 		/* Give up, but do not abort the namespace scan. */
-		goto err;
+		goto err_clear_driver_data;
 	}
 	/*
 	 * processor_device_array is not cleared on errors to allow buggy BIOS
@@ -424,12 +424,12 @@
 	dev = get_cpu_device(pr->id);
 	if (!dev) {
 		result = -ENODEV;
-		goto err;
+		goto err_clear_per_cpu;
 	}
 
 	result = acpi_bind_one(dev, device);
 	if (result)
-		goto err;
+		goto err_clear_per_cpu;
 
 	pr->dev = dev;
 
@@ -440,10 +440,11 @@
 	dev_err(dev, "Processor driver could not be attached\n");
 	acpi_unbind_one(dev);
 
- err:
-	free_cpumask_var(pr->throttling.shared_cpu_map);
-	device->driver_data = NULL;
+ err_clear_per_cpu:
 	per_cpu(processors, pr->id) = NULL;
+ err_clear_driver_data:
+	device->driver_data = NULL;
+	free_cpumask_var(pr->throttling.shared_cpu_map);
  err_free_pr:
 	kfree(pr);
 	return result;
--- linux-qcom-6.8.0.orig/drivers/acpi/acpica/Makefile
+++ linux-qcom-6.8.0/drivers/acpi/acpica/Makefile
@@ -5,6 +5,7 @@
 
 ccflags-y			:= -D_LINUX -DBUILDING_ACPICA
 ccflags-$(CONFIG_ACPI_DEBUG)	+= -DACPI_DEBUG_OUTPUT
+CFLAGS_tbfind.o 		+= $(call cc-disable-warning, stringop-truncation)
 
 # use acpi.o to put all files here into acpi.o modparam namespace
 obj-y	+= acpi.o
--- linux-qcom-6.8.0.orig/drivers/acpi/acpica/acevents.h
+++ linux-qcom-6.8.0/drivers/acpi/acpica/acevents.h
@@ -188,7 +188,7 @@
 		      u8 acpi_ns_is_locked);
 
 void
-acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
+acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, u32 max_depth,
 			    acpi_adr_space_type space_id, u32 function);
 
 acpi_status
--- linux-qcom-6.8.0.orig/drivers/acpi/acpica/achware.h
+++ linux-qcom-6.8.0/drivers/acpi/acpica/achware.h
@@ -103,8 +103,6 @@
 
 acpi_status acpi_hw_enable_all_runtime_gpes(void);
 
-acpi_status acpi_hw_enable_all_wakeup_gpes(void);
-
 u8 acpi_hw_check_all_gpes(acpi_handle gpe_skip_device, u32 gpe_skip_number);
 
 acpi_status
--- linux-qcom-6.8.0.orig/drivers/acpi/acpica/dbconvert.c
+++ linux-qcom-6.8.0/drivers/acpi/acpica/dbconvert.c
@@ -174,6 +174,8 @@
 	elements =
 	    ACPI_ALLOCATE_ZEROED(DB_DEFAULT_PKG_ELEMENTS *
 				 sizeof(union acpi_object));
+	if (!elements)
+		return (AE_NO_MEMORY);
 
 	this = string;
 	for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++) {
--- linux-qcom-6.8.0.orig/drivers/acpi/acpica/dbnames.c
+++ linux-qcom-6.8.0/drivers/acpi/acpica/dbnames.c
@@ -550,8 +550,12 @@
 	ACPI_FREE(buffer.pointer);
 
 	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
-	acpi_evaluate_object(obj_handle, NULL, NULL, &buffer);
-
+	status = acpi_evaluate_object(obj_handle, NULL, NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		acpi_os_printf("Could Not evaluate object %p\n",
+			       obj_handle);
+		return (AE_OK);
+	}
 	/*
 	 * Since this is a field unit, surround the output in braces
 	 */
--- linux-qcom-6.8.0.orig/drivers/acpi/acpica/dswexec.c
+++ linux-qcom-6.8.0/drivers/acpi/acpica/dswexec.c
@@ -397,11 +397,11 @@
 
 			/* Resolve all operands */
 
+			union acpi_operand_object **stack_ptr = NULL;
+			if (walk_state->num_operands > 0)
+				stack_ptr = ACPI_WALK_OPERANDS;
 			status = acpi_ex_resolve_operands(walk_state->opcode,
-							  &(walk_state->
-							    operands
-							    [walk_state->
-							     num_operands - 1]),
+							  stack_ptr,
 							  walk_state);
 		}
 
--- linux-qcom-6.8.0.orig/drivers/acpi/acpica/evregion.c
+++ linux-qcom-6.8.0/drivers/acpi/acpica/evregion.c
@@ -65,6 +65,7 @@
 						acpi_gbl_default_address_spaces
 						[i])) {
 			acpi_ev_execute_reg_methods(acpi_gbl_root_node,
+						    ACPI_UINT32_MAX,
 						    acpi_gbl_default_address_spaces
 						    [i], ACPI_REG_CONNECT);
 		}
@@ -672,6 +673,7 @@
  * FUNCTION:    acpi_ev_execute_reg_methods
  *
  * PARAMETERS:  node            - Namespace node for the device
+ *              max_depth       - Depth to which search for _REG
  *              space_id        - The address space ID
  *              function        - Passed to _REG: On (1) or Off (0)
  *
@@ -683,7 +685,7 @@
  ******************************************************************************/
 
 void
-acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
+acpi_ev_execute_reg_methods(struct acpi_namespace_node *node, u32 max_depth,
 			    acpi_adr_space_type space_id, u32 function)
 {
 	struct acpi_reg_walk_info info;
@@ -717,7 +719,7 @@
 	 * regions and _REG methods. (i.e. handlers must be installed for all
 	 * regions of this Space ID before we can run any _REG methods)
 	 */
-	(void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
+	(void)acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, max_depth,
 				     ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, NULL,
 				     &info, NULL);
 
--- linux-qcom-6.8.0.orig/drivers/acpi/acpica/evxfregn.c
+++ linux-qcom-6.8.0/drivers/acpi/acpica/evxfregn.c
@@ -85,7 +85,8 @@
 	/* Run all _REG methods for this address space */
 
 	if (run_reg) {
-		acpi_ev_execute_reg_methods(node, space_id, ACPI_REG_CONNECT);
+		acpi_ev_execute_reg_methods(node, ACPI_UINT32_MAX, space_id,
+					    ACPI_REG_CONNECT);
 	}
 
 unlock_and_exit:
@@ -231,8 +232,6 @@
 
 			/* Now we can delete the handler object */
 
-			acpi_os_release_mutex(handler_obj->address_space.
-					      context_mutex);
 			acpi_ut_remove_reference(handler_obj);
 			goto unlock_and_exit;
 		}
@@ -263,6 +262,7 @@
  * FUNCTION:    acpi_execute_reg_methods
  *
  * PARAMETERS:  device          - Handle for the device
+ *              max_depth       - Depth to which search for _REG
  *              space_id        - The address space ID
  *
  * RETURN:      Status
@@ -271,7 +271,8 @@
  *
  ******************************************************************************/
 acpi_status
-acpi_execute_reg_methods(acpi_handle device, acpi_adr_space_type space_id)
+acpi_execute_reg_methods(acpi_handle device, u32 max_depth,
+			 acpi_adr_space_type space_id)
 {
 	struct acpi_namespace_node *node;
 	acpi_status status;
@@ -296,7 +297,8 @@
 
 		/* Run all _REG methods for this address space */
 
-		acpi_ev_execute_reg_methods(node, space_id, ACPI_REG_CONNECT);
+		acpi_ev_execute_reg_methods(node, max_depth, space_id,
+					    ACPI_REG_CONNECT);
 	} else {
 		status = AE_BAD_PARAMETER;
 	}
--- linux-qcom-6.8.0.orig/drivers/acpi/acpica/exprep.c
+++ linux-qcom-6.8.0/drivers/acpi/acpica/exprep.c
@@ -437,6 +437,9 @@
 
 		if (info->connection_node) {
 			second_desc = info->connection_node->object;
+			if (second_desc == NULL) {
+				break;
+			}
 			if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) {
 				status =
 				    acpi_ds_get_buffer_arguments(second_desc);
--- linux-qcom-6.8.0.orig/drivers/acpi/acpica/exregion.c
+++ linux-qcom-6.8.0/drivers/acpi/acpica/exregion.c
@@ -44,7 +44,6 @@
 	struct acpi_mem_mapping *mm = mem_info->cur_mm;
 	u32 length;
 	acpi_size map_length;
-	acpi_size page_boundary_map_length;
 #ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
 	u32 remainder;
 #endif
@@ -138,26 +137,8 @@
 		map_length = (acpi_size)
 		    ((mem_info->address + mem_info->length) - address);
 
-		/*
-		 * If mapping the entire remaining portion of the region will cross
-		 * a page boundary, just map up to the page boundary, do not cross.
-		 * On some systems, crossing a page boundary while mapping regions
-		 * can cause warnings if the pages have different attributes
-		 * due to resource management.
-		 *
-		 * This has the added benefit of constraining a single mapping to
-		 * one page, which is similar to the original code that used a 4k
-		 * maximum window.
-		 */
-		page_boundary_map_length = (acpi_size)
-		    (ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address);
-		if (page_boundary_map_length == 0) {
-			page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE;
-		}
-
-		if (map_length > page_boundary_map_length) {
-			map_length = page_boundary_map_length;
-		}
+		if (map_length > ACPI_DEFAULT_PAGE_SIZE)
+			map_length = ACPI_DEFAULT_PAGE_SIZE;
 
 		/* Create a new mapping starting at the address given */
 
--- linux-qcom-6.8.0.orig/drivers/acpi/acpica/exsystem.c
+++ linux-qcom-6.8.0/drivers/acpi/acpica/exsystem.c
@@ -133,14 +133,15 @@
 		 * (ACPI specifies 100 usec as max, but this gives some slack in
 		 * order to support existing BIOSs)
 		 */
-		ACPI_ERROR((AE_INFO,
-			    "Time parameter is too large (%u)", how_long_us));
+		ACPI_ERROR_ONCE((AE_INFO,
+				 "Time parameter is too large (%u)",
+				 how_long_us));
 		status = AE_AML_OPERAND_VALUE;
 	} else {
 		if (how_long_us > 100) {
-			ACPI_WARNING((AE_INFO,
-				      "Time parameter %u us > 100 us violating ACPI spec, please fix the firmware.",
-				      how_long_us));
+			ACPI_WARNING_ONCE((AE_INFO,
+					   "Time parameter %u us > 100 us violating ACPI spec, please fix the firmware.",
+					   how_long_us));
 		}
 		acpi_os_stall(how_long_us);
 	}
--- linux-qcom-6.8.0.orig/drivers/acpi/acpica/psargs.c
+++ linux-qcom-6.8.0/drivers/acpi/acpica/psargs.c
@@ -25,6 +25,8 @@
 static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
 						       *parser_state);
 
+static void acpi_ps_free_field_list(union acpi_parse_object *start);
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ps_get_next_package_length
@@ -685,6 +687,39 @@
 
 /*******************************************************************************
  *
+ * FUNCTION:    acpi_ps_free_field_list
+ *
+ * PARAMETERS:  start               - First Op in field list
+ *
+ * RETURN:      None.
+ *
+ * DESCRIPTION: Free all Op objects inside a field list.
+ *
+ ******************************************************************************/
+
+static void acpi_ps_free_field_list(union acpi_parse_object *start)
+{
+	union acpi_parse_object *cur = start;
+	union acpi_parse_object *next;
+	union acpi_parse_object *arg;
+
+	while (cur) {
+		next = cur->common.next;
+
+		/* AML_INT_CONNECTION_OP can have a single argument */
+
+		arg = acpi_ps_get_arg(cur, 0);
+		if (arg) {
+			acpi_ps_free_op(arg);
+		}
+
+		acpi_ps_free_op(cur);
+		cur = next;
+	}
+}
+
+/*******************************************************************************
+ *
  * FUNCTION:    acpi_ps_get_next_arg
  *
  * PARAMETERS:  walk_state          - Current state
@@ -751,6 +786,10 @@
 			while (parser_state->aml < parser_state->pkg_end) {
 				field = acpi_ps_get_next_field(parser_state);
 				if (!field) {
+					if (arg) {
+						acpi_ps_free_field_list(arg);
+					}
+
 					return_ACPI_STATUS(AE_NO_MEMORY);
 				}
 
@@ -820,6 +859,10 @@
 			    acpi_ps_get_next_namepath(walk_state, parser_state,
 						      arg,
 						      ACPI_NOT_METHOD_CALL);
+			if (ACPI_FAILURE(status)) {
+				acpi_ps_free_op(arg);
+				return_ACPI_STATUS(status);
+			}
 		} else {
 			/* Single complex argument, nothing returned */
 
@@ -854,6 +897,10 @@
 			    acpi_ps_get_next_namepath(walk_state, parser_state,
 						      arg,
 						      ACPI_POSSIBLE_METHOD_CALL);
+			if (ACPI_FAILURE(status)) {
+				acpi_ps_free_op(arg);
+				return_ACPI_STATUS(status);
+			}
 
 			if (arg->common.aml_opcode == AML_INT_METHODCALL_OP) {
 
--- linux-qcom-6.8.0.orig/drivers/acpi/apei/ghes.c
+++ linux-qcom-6.8.0/drivers/acpi/apei/ghes.c
@@ -170,8 +170,6 @@
 static struct ghes_estatus_cache __rcu *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE];
 static atomic_t ghes_estatus_cache_alloced;
 
-static int ghes_panic_timeout __read_mostly = 30;
-
 static void __iomem *ghes_map(u64 pfn, enum fixed_addresses fixmap_idx)
 {
 	phys_addr_t paddr;
@@ -899,14 +897,16 @@
 			 struct acpi_hest_generic_status *estatus,
 			 u64 buf_paddr, enum fixed_addresses fixmap_idx)
 {
+	const char *msg = GHES_PFX "Fatal hardware error";
+
 	__ghes_print_estatus(KERN_EMERG, ghes->generic, estatus);
 
 	ghes_clear_estatus(ghes, estatus, buf_paddr, fixmap_idx);
 
-	/* reboot to log the error! */
 	if (!panic_timeout)
-		panic_timeout = ghes_panic_timeout;
-	panic("Fatal hardware error!");
+		pr_emerg("%s but panic disabled\n", msg);
+
+	panic(msg);
 }
 
 static int ghes_proc(struct ghes *ghes)
--- linux-qcom-6.8.0.orig/drivers/acpi/arm64/gtdt.c
+++ linux-qcom-6.8.0/drivers/acpi/arm64/gtdt.c
@@ -283,7 +283,7 @@
 		if (frame->virt_irq > 0)
 			acpi_unregister_gsi(gtdt_frame->virtual_timer_interrupt);
 		frame->virt_irq = 0;
-	} while (i-- >= 0 && gtdt_frame--);
+	} while (i-- > 0 && gtdt_frame--);
 
 	return -EINVAL;
 }
--- linux-qcom-6.8.0.orig/drivers/acpi/arm64/iort.c
+++ linux-qcom-6.8.0/drivers/acpi/arm64/iort.c
@@ -1712,6 +1712,15 @@
 	/* HiSilicon Hip09 Platform */
 	{"HISI  ", "HIP09   ", 0, ACPI_SIG_IORT, greater_than_or_equal,
 	 "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
+	{"HISI  ", "HIP09A  ", 0, ACPI_SIG_IORT, greater_than_or_equal,
+	 "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
+	/* HiSilicon Hip10/11 Platform uses the same SMMU IP with Hip09 */
+	{"HISI  ", "HIP10   ", 0, ACPI_SIG_IORT, greater_than_or_equal,
+	 "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
+	{"HISI  ", "HIP10C  ", 0, ACPI_SIG_IORT, greater_than_or_equal,
+	 "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
+	{"HISI  ", "HIP11   ", 0, ACPI_SIG_IORT, greater_than_or_equal,
+	 "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
 	{ }
 };
 
--- linux-qcom-6.8.0.orig/drivers/acpi/battery.c
+++ linux-qcom-6.8.0/drivers/acpi/battery.c
@@ -678,12 +678,18 @@
 	return count;
 }
 
-static const struct device_attribute alarm_attr = {
+static struct device_attribute alarm_attr = {
 	.attr = {.name = "alarm", .mode = 0644},
 	.show = acpi_battery_alarm_show,
 	.store = acpi_battery_alarm_store,
 };
 
+static struct attribute *acpi_battery_attrs[] = {
+	&alarm_attr.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(acpi_battery);
+
 /*
  * The Battery Hooking API
  *
@@ -697,28 +703,35 @@
 static LIST_HEAD(battery_hook_list);
 static DEFINE_MUTEX(hook_mutex);
 
-static void __battery_hook_unregister(struct acpi_battery_hook *hook, int lock)
+static void battery_hook_unregister_unlocked(struct acpi_battery_hook *hook)
 {
 	struct acpi_battery *battery;
+
 	/*
 	 * In order to remove a hook, we first need to
 	 * de-register all the batteries that are registered.
 	 */
-	if (lock)
-		mutex_lock(&hook_mutex);
 	list_for_each_entry(battery, &acpi_battery_list, list) {
 		if (!hook->remove_battery(battery->bat, hook))
 			power_supply_changed(battery->bat);
 	}
-	list_del(&hook->list);
-	if (lock)
-		mutex_unlock(&hook_mutex);
+	list_del_init(&hook->list);
+
 	pr_info("extension unregistered: %s\n", hook->name);
 }
 
 void battery_hook_unregister(struct acpi_battery_hook *hook)
 {
-	__battery_hook_unregister(hook, 1);
+	mutex_lock(&hook_mutex);
+	/*
+	 * Ignore already unregistered battery hooks. This might happen
+	 * if a battery hook was previously unloaded due to an error when
+	 * adding a new battery.
+	 */
+	if (!list_empty(&hook->list))
+		battery_hook_unregister_unlocked(hook);
+
+	mutex_unlock(&hook_mutex);
 }
 EXPORT_SYMBOL_GPL(battery_hook_unregister);
 
@@ -727,7 +740,6 @@
 	struct acpi_battery *battery;
 
 	mutex_lock(&hook_mutex);
-	INIT_LIST_HEAD(&hook->list);
 	list_add(&hook->list, &battery_hook_list);
 	/*
 	 * Now that the driver is registered, we need
@@ -744,7 +756,7 @@
 			 * hooks.
 			 */
 			pr_err("extension failed to load: %s", hook->name);
-			__battery_hook_unregister(hook, 0);
+			battery_hook_unregister_unlocked(hook);
 			goto end;
 		}
 
@@ -783,7 +795,7 @@
 			 */
 			pr_err("error in extension, unloading: %s",
 					hook_node->name);
-			__battery_hook_unregister(hook_node, 0);
+			battery_hook_unregister_unlocked(hook_node);
 		}
 	}
 	mutex_unlock(&hook_mutex);
@@ -816,14 +828,17 @@
 	 * need to remove the hooks.
 	 */
 	list_for_each_entry_safe(hook, ptr, &battery_hook_list, list) {
-		__battery_hook_unregister(hook, 1);
+		battery_hook_unregister(hook);
 	}
 	mutex_destroy(&hook_mutex);
 }
 
 static int sysfs_add_battery(struct acpi_battery *battery)
 {
-	struct power_supply_config psy_cfg = { .drv_data = battery, };
+	struct power_supply_config psy_cfg = {
+		.drv_data = battery,
+		.attr_grp = acpi_battery_groups,
+	};
 	bool full_cap_broken = false;
 
 	if (!ACPI_BATTERY_CAPACITY_VALID(battery->full_charge_capacity) &&
@@ -868,7 +883,7 @@
 		return result;
 	}
 	battery_hook_add_battery(battery);
-	return device_create_file(&battery->bat->dev, &alarm_attr);
+	return 0;
 }
 
 static void sysfs_remove_battery(struct acpi_battery *battery)
@@ -879,7 +894,6 @@
 		return;
 	}
 	battery_hook_remove_battery(battery);
-	device_remove_file(&battery->bat->dev, &alarm_attr);
 	power_supply_unregister(battery->bat);
 	battery->bat = NULL;
 	mutex_unlock(&battery->sysfs_lock);
--- linux-qcom-6.8.0.orig/drivers/acpi/bus.c
+++ linux-qcom-6.8.0/drivers/acpi/bus.c
@@ -316,9 +316,14 @@
 		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PAD_SUPPORT;
 	if (IS_ENABLED(CONFIG_ACPI_PROCESSOR))
 		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PPC_OST_SUPPORT;
+	if (IS_ENABLED(CONFIG_ACPI_THERMAL))
+		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_FAST_THERMAL_SAMPLING_SUPPORT;
 
 	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_OST_SUPPORT;
 	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PCLPI_SUPPORT;
+	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_OVER_16_PSTATES_SUPPORT;
+	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_GED_SUPPORT;
+	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_IRQ_RESOURCE_SOURCE_SUPPORT;
 	if (IS_ENABLED(CONFIG_ACPI_PRMT))
 		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PRM_SUPPORT;
 	if (IS_ENABLED(CONFIG_ACPI_FFH))
--- linux-qcom-6.8.0.orig/drivers/acpi/button.c
+++ linux-qcom-6.8.0/drivers/acpi/button.c
@@ -130,6 +130,17 @@
 		},
 		.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
 	},
+	{
+		/*
+		 * Samsung galaxybook2 ,initial _LID device notification returns
+		 * lid closed.
+		 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "750XED"),
+		},
+		.driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN,
+	},
 	{}
 };
 
--- linux-qcom-6.8.0.orig/drivers/acpi/cppc_acpi.c
+++ linux-qcom-6.8.0/drivers/acpi/cppc_acpi.c
@@ -103,6 +103,11 @@
 				(cpc)->cpc_entry.reg.space_id ==	\
 				ACPI_ADR_SPACE_PLATFORM_COMM)
 
+/* Check if a CPC register is in FFH */
+#define CPC_IN_FFH(cpc) ((cpc)->type == ACPI_TYPE_BUFFER &&		\
+				(cpc)->cpc_entry.reg.space_id ==	\
+				ACPI_ADR_SPACE_FIXED_HARDWARE)
+
 /* Check if a CPC register is in SystemMemory */
 #define CPC_IN_SYSTEM_MEMORY(cpc) ((cpc)->type == ACPI_TYPE_BUFFER &&	\
 				(cpc)->cpc_entry.reg.space_id ==	\
@@ -166,6 +171,16 @@
 show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, reference_perf);
 show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time);
 
+/* Check for valid access_width, otherwise, fallback to using bit_width */
+#define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_width)
+
+/* Shift and apply the mask for CPC reads/writes */
+#define MASK_VAL_READ(reg, val) (((val) >> (reg)->bit_offset) &				\
+					GENMASK(((reg)->bit_width) - 1, 0))
+#define MASK_VAL_WRITE(reg, prev_val, val)						\
+	((((val) & GENMASK(((reg)->bit_width) - 1, 0)) << (reg)->bit_offset) |		\
+	((prev_val) & ~(GENMASK(((reg)->bit_width) - 1, 0) << (reg)->bit_offset)))	\
+
 static ssize_t show_feedback_ctrs(struct kobject *kobj,
 		struct kobj_attribute *attr, char *buf)
 {
@@ -780,6 +795,7 @@
 			} else if (gas_t->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
 				if (gas_t->address) {
 					void __iomem *addr;
+					size_t access_width;
 
 					if (!osc_cpc_flexible_adr_space_confirmed) {
 						pr_debug("Flexible address space capability not supported\n");
@@ -787,7 +803,8 @@
 							goto out_free;
 					}
 
-					addr = ioremap(gas_t->address, gas_t->bit_width/8);
+					access_width = GET_BIT_WIDTH(gas_t) / 8;
+					addr = ioremap(gas_t->address, access_width);
 					if (!addr)
 						goto out_free;
 					cpc_ptr->cpc_regs[i-2].sys_mem_vaddr = addr;
@@ -846,6 +863,7 @@
 
 	/* Store CPU Logical ID */
 	cpc_ptr->cpu_id = pr->id;
+	raw_spin_lock_init(&cpc_ptr->rmw_lock);
 
 	/* Parse PSD data for this CPU */
 	ret = acpi_get_psd(cpc_ptr, handle);
@@ -983,6 +1001,7 @@
 static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val)
 {
 	void __iomem *vaddr = NULL;
+	int size;
 	int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
 	struct cpc_reg *reg = &reg_res->cpc_entry.reg;
 
@@ -992,14 +1011,14 @@
 	}
 
 	*val = 0;
+	size = GET_BIT_WIDTH(reg);
 
 	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
-		u32 width = 8 << (reg->access_width - 1);
 		u32 val_u32;
 		acpi_status status;
 
 		status = acpi_os_read_port((acpi_io_address)reg->address,
-					   &val_u32, width);
+					   &val_u32, size);
 		if (ACPI_FAILURE(status)) {
 			pr_debug("Error: Failed to read SystemIO port %llx\n",
 				 reg->address);
@@ -1008,17 +1027,24 @@
 
 		*val = val_u32;
 		return 0;
-	} else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0)
+	} else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) {
+		/*
+		 * For registers in PCC space, the register size is determined
+		 * by the bit width field; the access size is used to indicate
+		 * the PCC subspace id.
+		 */
+		size = reg->bit_width;
 		vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id);
+	}
 	else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
 		vaddr = reg_res->sys_mem_vaddr;
 	else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE)
 		return cpc_read_ffh(cpu, reg, val);
 	else
 		return acpi_os_read_memory((acpi_physical_address)reg->address,
-				val, reg->bit_width);
+				val, size);
 
-	switch (reg->bit_width) {
+	switch (size) {
 	case 8:
 		*val = readb_relaxed(vaddr);
 		break;
@@ -1032,27 +1058,40 @@
 		*val = readq_relaxed(vaddr);
 		break;
 	default:
-		pr_debug("Error: Cannot read %u bit width from PCC for ss: %d\n",
-			 reg->bit_width, pcc_ss_id);
+		if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+			pr_debug("Error: Cannot read %u bit width from system memory: 0x%llx\n",
+				size, reg->address);
+		} else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) {
+			pr_debug("Error: Cannot read %u bit width from PCC for ss: %d\n",
+				size, pcc_ss_id);
+		}
 		return -EFAULT;
 	}
 
+	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
+		*val = MASK_VAL_READ(reg, *val);
+
 	return 0;
 }
 
 static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
 {
 	int ret_val = 0;
+	int size;
+	u64 prev_val;
 	void __iomem *vaddr = NULL;
 	int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
 	struct cpc_reg *reg = &reg_res->cpc_entry.reg;
+	struct cpc_desc *cpc_desc;
+	unsigned long flags;
+
+	size = GET_BIT_WIDTH(reg);
 
 	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
-		u32 width = 8 << (reg->access_width - 1);
 		acpi_status status;
 
 		status = acpi_os_write_port((acpi_io_address)reg->address,
-					    (u32)val, width);
+					    (u32)val, size);
 		if (ACPI_FAILURE(status)) {
 			pr_debug("Error: Failed to write SystemIO port %llx\n",
 				 reg->address);
@@ -1060,17 +1099,52 @@
 		}
 
 		return 0;
-	} else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0)
+	} else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) {
+		/*
+		 * For registers in PCC space, the register size is determined
+		 * by the bit width field; the access size is used to indicate
+		 * the PCC subspace id.
+		 */
+		size = reg->bit_width;
 		vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id);
+	}
 	else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
 		vaddr = reg_res->sys_mem_vaddr;
 	else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE)
 		return cpc_write_ffh(cpu, reg, val);
 	else
 		return acpi_os_write_memory((acpi_physical_address)reg->address,
-				val, reg->bit_width);
+				val, size);
 
-	switch (reg->bit_width) {
+	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+		cpc_desc = per_cpu(cpc_desc_ptr, cpu);
+		if (!cpc_desc) {
+			pr_debug("No CPC descriptor for CPU:%d\n", cpu);
+			return -ENODEV;
+		}
+
+		raw_spin_lock_irqsave(&cpc_desc->rmw_lock, flags);
+		switch (size) {
+		case 8:
+			prev_val = readb_relaxed(vaddr);
+			break;
+		case 16:
+			prev_val = readw_relaxed(vaddr);
+			break;
+		case 32:
+			prev_val = readl_relaxed(vaddr);
+			break;
+		case 64:
+			prev_val = readq_relaxed(vaddr);
+			break;
+		default:
+			raw_spin_unlock_irqrestore(&cpc_desc->rmw_lock, flags);
+			return -EFAULT;
+		}
+		val = MASK_VAL_WRITE(reg, prev_val, val);
+	}
+
+	switch (size) {
 	case 8:
 		writeb_relaxed(val, vaddr);
 		break;
@@ -1084,12 +1158,20 @@
 		writeq_relaxed(val, vaddr);
 		break;
 	default:
-		pr_debug("Error: Cannot write %u bit width to PCC for ss: %d\n",
-			 reg->bit_width, pcc_ss_id);
+		if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+			pr_debug("Error: Cannot write %u bit width to system memory: 0x%llx\n",
+				size, reg->address);
+		} else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) {
+			pr_debug("Error: Cannot write %u bit width to PCC for ss: %d\n",
+				size, pcc_ss_id);
+		}
 		ret_val = -EFAULT;
 		break;
 	}
 
+	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
+		raw_spin_unlock_irqrestore(&cpc_desc->rmw_lock, flags);
+
 	return ret_val;
 }
 
@@ -1158,6 +1240,19 @@
 }
 
 /**
+ * cppc_get_highest_perf - Get the highest performance register value.
+ * @cpunum: CPU from which to get highest performance.
+ * @highest_perf: Return address.
+ *
+ * Return: 0 for success, -EIO otherwise.
+ */
+int cppc_get_highest_perf(int cpunum, u64 *highest_perf)
+{
+	return cppc_get_perf(cpunum, HIGHEST_PERF, highest_perf);
+}
+EXPORT_SYMBOL_GPL(cppc_get_highest_perf);
+
+/**
  * cppc_get_epp_perf - Get the epp register value.
  * @cpunum: CPU from which to get epp preference value.
  * @epp_perf: Return address.
@@ -1427,9 +1522,12 @@
 		/* after writing CPC, transfer the ownership of PCC to platform */
 		ret = send_pcc_cmd(pcc_ss_id, CMD_WRITE);
 		up_write(&pcc_ss_data->pcc_lock);
+	} else if (osc_cpc_flexible_adr_space_confirmed &&
+		   CPC_SUPPORTED(epp_set_reg) && CPC_IN_FFH(epp_set_reg)) {
+		ret = cpc_write(cpu, epp_set_reg, perf_ctrls->energy_perf);
 	} else {
 		ret = -ENOTSUPP;
-		pr_debug("_CPC in PCC is not supported\n");
+		pr_debug("_CPC in PCC and _CPC in FFH are not supported\n");
 	}
 
 	return ret;
@@ -1814,9 +1912,15 @@
 	u64 mul, div;
 
 	if (caps->lowest_freq && caps->nominal_freq) {
-		mul = caps->nominal_freq - caps->lowest_freq;
+		/* Avoid special case when nominal_freq is equal to lowest_freq */
+		if (caps->lowest_freq == caps->nominal_freq) {
+			mul = caps->nominal_freq;
+			div = caps->nominal_perf;
+		} else {
+			mul = caps->nominal_freq - caps->lowest_freq;
+			div = caps->nominal_perf - caps->lowest_perf;
+		}
 		mul *= KHZ_PER_MHZ;
-		div = caps->nominal_perf - caps->lowest_perf;
 		offset = caps->nominal_freq * KHZ_PER_MHZ -
 			 div64_u64(caps->nominal_perf * mul, div);
 	} else {
@@ -1837,11 +1941,17 @@
 {
 	s64 retval, offset = 0;
 	static u64 max_khz;
-	u64  mul, div;
+	u64 mul, div;
 
 	if (caps->lowest_freq && caps->nominal_freq) {
-		mul = caps->nominal_perf - caps->lowest_perf;
-		div = caps->nominal_freq - caps->lowest_freq;
+		/* Avoid special case when nominal_freq is equal to lowest_freq */
+		if (caps->lowest_freq == caps->nominal_freq) {
+			mul = caps->nominal_perf;
+			div = caps->nominal_freq;
+		} else {
+			mul = caps->nominal_perf - caps->lowest_perf;
+			div = caps->nominal_freq - caps->lowest_freq;
+		}
 		/*
 		 * We don't need to convert to kHz for computing offset and can
 		 * directly use nominal_freq and lowest_freq as the div64_u64
--- linux-qcom-6.8.0.orig/drivers/acpi/device_sysfs.c
+++ linux-qcom-6.8.0/drivers/acpi/device_sysfs.c
@@ -540,8 +540,9 @@
 	 * If device has _STR, 'description' file is created
 	 */
 	if (acpi_has_method(dev->handle, "_STR")) {
-		status = acpi_evaluate_object(dev->handle, "_STR",
-					NULL, &buffer);
+		status = acpi_evaluate_object_typed(dev->handle, "_STR",
+						    NULL, &buffer,
+						    ACPI_TYPE_BUFFER);
 		if (ACPI_FAILURE(status))
 			buffer.pointer = NULL;
 		dev->pnp.str_obj = buffer.pointer;
--- linux-qcom-6.8.0.orig/drivers/acpi/ec.c
+++ linux-qcom-6.8.0/drivers/acpi/ec.c
@@ -783,6 +783,9 @@
 	unsigned long tmp;
 	int ret = 0;
 
+	if (t->rdata)
+		memset(t->rdata, 0, t->rlen);
+
 	/* start transaction */
 	spin_lock_irqsave(&ec->lock, tmp);
 	/* Enable GPE for command processing (IBF=0/OBF=1) */
@@ -819,8 +822,6 @@
 
 	if (!ec || (!t) || (t->wlen && !t->wdata) || (t->rlen && !t->rdata))
 		return -EINVAL;
-	if (t->rdata)
-		memset(t->rdata, 0, t->rlen);
 
 	mutex_lock(&ec->mutex);
 	if (ec->global_lock) {
@@ -847,7 +848,7 @@
 				.wdata = NULL, .rdata = &d,
 				.wlen = 0, .rlen = 1};
 
-	return acpi_ec_transaction(ec, &t);
+	return acpi_ec_transaction_unlocked(ec, &t);
 }
 
 static int acpi_ec_burst_disable(struct acpi_ec *ec)
@@ -857,7 +858,7 @@
 				.wlen = 0, .rlen = 0};
 
 	return (acpi_ec_read_status(ec) & ACPI_EC_FLAG_BURST) ?
-				acpi_ec_transaction(ec, &t) : 0;
+				acpi_ec_transaction_unlocked(ec, &t) : 0;
 }
 
 static int acpi_ec_read(struct acpi_ec *ec, u8 address, u8 *data)
@@ -873,6 +874,19 @@
 	return result;
 }
 
+static int acpi_ec_read_unlocked(struct acpi_ec *ec, u8 address, u8 *data)
+{
+	int result;
+	u8 d;
+	struct transaction t = {.command = ACPI_EC_COMMAND_READ,
+				.wdata = &address, .rdata = &d,
+				.wlen = 1, .rlen = 1};
+
+	result = acpi_ec_transaction_unlocked(ec, &t);
+	*data = d;
+	return result;
+}
+
 static int acpi_ec_write(struct acpi_ec *ec, u8 address, u8 data)
 {
 	u8 wdata[2] = { address, data };
@@ -883,6 +897,16 @@
 	return acpi_ec_transaction(ec, &t);
 }
 
+static int acpi_ec_write_unlocked(struct acpi_ec *ec, u8 address, u8 data)
+{
+	u8 wdata[2] = { address, data };
+	struct transaction t = {.command = ACPI_EC_COMMAND_WRITE,
+				.wdata = wdata, .rdata = NULL,
+				.wlen = 2, .rlen = 0};
+
+	return acpi_ec_transaction_unlocked(ec, &t);
+}
+
 int ec_read(u8 addr, u8 *val)
 {
 	int err;
@@ -1323,6 +1347,7 @@
 	struct acpi_ec *ec = handler_context;
 	int result = 0, i, bytes = bits / 8;
 	u8 *value = (u8 *)value64;
+	u32 glk;
 
 	if ((address > 0xFF) || !value || !handler_context)
 		return AE_BAD_PARAMETER;
@@ -1330,17 +1355,38 @@
 	if (function != ACPI_READ && function != ACPI_WRITE)
 		return AE_BAD_PARAMETER;
 
+	mutex_lock(&ec->mutex);
+
+	if (ec->global_lock) {
+		acpi_status status;
+
+		status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
+		if (ACPI_FAILURE(status)) {
+			result = -ENODEV;
+			goto unlock;
+		}
+	}
+
 	if (ec->busy_polling || bits > 8)
 		acpi_ec_burst_enable(ec);
 
-	for (i = 0; i < bytes; ++i, ++address, ++value)
+	for (i = 0; i < bytes; ++i, ++address, ++value) {
 		result = (function == ACPI_READ) ?
-			acpi_ec_read(ec, address, value) :
-			acpi_ec_write(ec, address, *value);
+			acpi_ec_read_unlocked(ec, address, value) :
+			acpi_ec_write_unlocked(ec, address, *value);
+		if (result < 0)
+			break;
+	}
 
 	if (ec->busy_polling || bits > 8)
 		acpi_ec_burst_disable(ec);
 
+	if (ec->global_lock)
+		acpi_release_global_lock(glk);
+
+unlock:
+	mutex_unlock(&ec->mutex);
+
 	switch (result) {
 	case -EINVAL:
 		return AE_BAD_PARAMETER;
@@ -1348,8 +1394,10 @@
 		return AE_NOT_FOUND;
 	case -ETIME:
 		return AE_TIME;
-	default:
+	case 0:
 		return AE_OK;
+	default:
+		return AE_ERROR;
 	}
 }
 
@@ -1487,8 +1535,10 @@
 	acpi_ec_start(ec, false);
 
 	if (!test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
+		acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle;
+
 		acpi_ec_enter_noirq(ec);
-		status = acpi_install_address_space_handler_no_reg(ec->handle,
+		status = acpi_install_address_space_handler_no_reg(scope_handle,
 								   ACPI_ADR_SPACE_EC,
 								   &acpi_ec_space_handler,
 								   NULL, ec);
@@ -1497,11 +1547,10 @@
 			return -ENODEV;
 		}
 		set_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
-		ec->address_space_handler_holder = ec->handle;
 	}
 
 	if (call_reg && !test_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags)) {
-		acpi_execute_reg_methods(ec->handle, ACPI_ADR_SPACE_EC);
+		acpi_execute_reg_methods(ec->handle, ACPI_UINT32_MAX, ACPI_ADR_SPACE_EC);
 		set_bit(EC_FLAGS_EC_REG_CALLED, &ec->flags);
 	}
 
@@ -1553,10 +1602,13 @@
 
 static void ec_remove_handlers(struct acpi_ec *ec)
 {
+	acpi_handle scope_handle = ec == first_ec ? ACPI_ROOT_OBJECT : ec->handle;
+
 	if (test_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags)) {
 		if (ACPI_FAILURE(acpi_remove_address_space_handler(
-					ec->address_space_handler_holder,
-					ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
+						scope_handle,
+						ACPI_ADR_SPACE_EC,
+						&acpi_ec_space_handler)))
 			pr_err("failed to remove space handler\n");
 		clear_bit(EC_FLAGS_EC_HANDLER_INSTALLED, &ec->flags);
 	}
@@ -1595,14 +1647,18 @@
 {
 	int ret;
 
-	ret = ec_install_handlers(ec, device, call_reg);
-	if (ret)
-		return ret;
-
 	/* First EC capable of handling transactions */
 	if (!first_ec)
 		first_ec = ec;
 
+	ret = ec_install_handlers(ec, device, call_reg);
+	if (ret) {
+		if (ec == first_ec)
+			first_ec = NULL;
+
+		return ret;
+	}
+
 	pr_info("EC_CMD/EC_SC=0x%lx, EC_DATA=0x%lx\n", ec->command_addr,
 		ec->data_addr);
 
@@ -1709,6 +1765,12 @@
 	}
 }
 
+void acpi_ec_register_opregions(struct acpi_device *adev)
+{
+	if (first_ec && first_ec->handle != adev->handle)
+		acpi_execute_reg_methods(adev->handle, 1, ACPI_ADR_SPACE_EC);
+}
+
 static acpi_status
 ec_parse_io_ports(struct acpi_resource *resource, void *context)
 {
--- linux-qcom-6.8.0.orig/drivers/acpi/fan_core.c
+++ linux-qcom-6.8.0/drivers/acpi/fan_core.c
@@ -367,19 +367,25 @@
 	result = sysfs_create_link(&pdev->dev.kobj,
 				   &cdev->device.kobj,
 				   "thermal_cooling");
-	if (result)
+	if (result) {
 		dev_err(&pdev->dev, "Failed to create sysfs link 'thermal_cooling'\n");
+		goto err_unregister;
+	}
 
 	result = sysfs_create_link(&cdev->device.kobj,
 				   &pdev->dev.kobj,
 				   "device");
 	if (result) {
 		dev_err(&pdev->dev, "Failed to create sysfs link 'device'\n");
-		goto err_end;
+		goto err_remove_link;
 	}
 
 	return 0;
 
+err_remove_link:
+	sysfs_remove_link(&pdev->dev.kobj, "thermal_cooling");
+err_unregister:
+	thermal_cooling_device_unregister(cdev);
 err_end:
 	if (fan->acpi4)
 		acpi_fan_delete_attributes(device);
--- linux-qcom-6.8.0.orig/drivers/acpi/internal.h
+++ linux-qcom-6.8.0/drivers/acpi/internal.h
@@ -184,7 +184,6 @@
 
 struct acpi_ec {
 	acpi_handle handle;
-	acpi_handle address_space_handler_holder;
 	int gpe;
 	int irq;
 	unsigned long command_addr;
@@ -222,6 +221,7 @@
 			      acpi_handle handle, acpi_ec_query_func func,
 			      void *data);
 void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit);
+void acpi_ec_register_opregions(struct acpi_device *adev);
 
 #ifdef CONFIG_PM_SLEEP
 void acpi_ec_flush_work(void);
@@ -301,5 +301,10 @@
 void acpi_mipi_scan_crs_csi2(void);
 void acpi_mipi_init_crs_csi2_swnodes(void);
 void acpi_mipi_crs_csi2_cleanup(void);
+#ifdef CONFIG_X86
+bool acpi_graph_ignore_port(acpi_handle handle);
+#else
+static inline bool acpi_graph_ignore_port(acpi_handle handle) { return false; }
+#endif
 
 #endif /* _ACPI_INTERNAL_H_ */
--- linux-qcom-6.8.0.orig/drivers/acpi/mipi-disco-img.c
+++ linux-qcom-6.8.0/drivers/acpi/mipi-disco-img.c
@@ -19,6 +19,7 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/dmi.h>
 #include <linux/limits.h>
 #include <linux/list.h>
 #include <linux/module.h>
@@ -723,3 +724,83 @@
 	list_for_each_entry_safe(csi2, csi2_tmp, &acpi_mipi_crs_csi2_list, entry)
 		acpi_mipi_del_crs_csi2(csi2);
 }
+
+#ifdef CONFIG_X86
+#include <asm/cpu_device_id.h>
+#include <asm/intel-family.h>
+
+/* CPU matches for Dell generations with broken ACPI MIPI DISCO info */
+static const struct x86_cpu_id dell_broken_mipi_disco_cpu_gens[] = {
+	X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE, NULL),
+	X86_MATCH_INTEL_FAM6_MODEL(TIGERLAKE_L, NULL),
+	X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, NULL),
+	X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, NULL),
+	X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, NULL),
+	X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_P, NULL),
+	X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE_S, NULL),
+	{}
+};
+
+static const char *strnext(const char *s1, const char *s2)
+{
+	s1 = strstr(s1, s2);
+
+	if (!s1)
+		return NULL;
+
+	return s1 + strlen(s2);
+}
+
+/**
+ * acpi_graph_ignore_port - Tell whether a port node should be ignored
+ * @handle: The ACPI handle of the node (which may be a port node)
+ *
+ * Return: true if a port node should be ignored and the data to that should
+ * come from other sources instead (Windows ACPI definitions and
+ * ipu-bridge). This is currently used to ignore bad port nodes related to IPU6
+ * ("IPU?") and camera sensor devices ("LNK?") in certain Dell systems with
+ * Intel VSC.
+ */
+bool acpi_graph_ignore_port(acpi_handle handle)
+{
+	const char *path = NULL, *orig_path;
+	static bool dmi_tested, ignore_port;
+
+	if (!dmi_tested) {
+		if (dmi_name_in_vendors("Dell Inc.") &&
+		    x86_match_cpu(dell_broken_mipi_disco_cpu_gens))
+			ignore_port = true;
+
+		dmi_tested = true;
+	}
+
+	if (!ignore_port)
+		return false;
+
+	/* Check if the device is either "IPU" or "LNK" (sensor). */
+	orig_path = acpi_handle_path(handle);
+	if (!orig_path)
+		return false;
+	path = strnext(orig_path, "IPU");
+	if (!path)
+		path = strnext(orig_path, "LNK");
+	if (!path)
+		goto out_free;
+
+	if (!(isdigit(path[0]) && path[1] == '.'))
+		goto out_free;
+
+	/* Check if the node has a "PRT" prefix. */
+	path = strnext(path, "PRT");
+	if (path && isdigit(path[0]) && !path[1]) {
+		acpi_handle_debug(handle, "ignoring data node\n");
+
+		kfree(orig_path);
+		return true;
+	}
+
+out_free:
+	kfree(orig_path);
+	return false;
+}
+#endif
--- linux-qcom-6.8.0.orig/drivers/acpi/nfit/core.c
+++ linux-qcom-6.8.0/drivers/acpi/nfit/core.c
@@ -454,8 +454,13 @@
 	if (cmd_rc)
 		*cmd_rc = -EINVAL;
 
-	if (cmd == ND_CMD_CALL)
+	if (cmd == ND_CMD_CALL) {
+		if (!buf || buf_len < sizeof(*call_pkg))
+			return -EINVAL;
+
 		call_pkg = buf;
+	}
+
 	func = cmd_to_func(nfit_mem, cmd, call_pkg, &family);
 	if (func < 0)
 		return func;
--- linux-qcom-6.8.0.orig/drivers/acpi/numa/hmat.c
+++ linux-qcom-6.8.0/drivers/acpi/numa/hmat.c
@@ -59,9 +59,8 @@
 };
 
 enum {
-	NODE_ACCESS_CLASS_0 = 0,
-	NODE_ACCESS_CLASS_1,
-	NODE_ACCESS_CLASS_GENPORT_SINK,
+	NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL = ACCESS_COORDINATE_MAX,
+	NODE_ACCESS_CLASS_GENPORT_SINK_CPU,
 	NODE_ACCESS_CLASS_MAX,
 };
 
@@ -127,7 +126,8 @@
 /**
  * acpi_get_genport_coordinates - Retrieve the access coordinates for a generic port
  * @uid: ACPI unique id
- * @coord: The access coordinates written back out for the generic port
+ * @coord: The access coordinates written back out for the generic port.
+ *	   Expect 2 levels array.
  *
  * Return: 0 on success. Errno on failure.
  *
@@ -143,7 +143,10 @@
 	if (!target)
 		return -ENOENT;
 
-	*coord = target->coord[NODE_ACCESS_CLASS_GENPORT_SINK];
+	coord[ACCESS_COORDINATE_LOCAL] =
+		target->coord[NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL];
+	coord[ACCESS_COORDINATE_CPU] =
+		target->coord[NODE_ACCESS_CLASS_GENPORT_SINK_CPU];
 
 	return 0;
 }
@@ -374,11 +377,11 @@
 
 	if (target && target->processor_pxm == init_pxm) {
 		hmat_update_target_access(target, type, value,
-					  NODE_ACCESS_CLASS_0);
+					  ACCESS_COORDINATE_LOCAL);
 		/* If the node has a CPU, update access 1 */
 		if (node_state(pxm_to_node(init_pxm), N_CPU))
 			hmat_update_target_access(target, type, value,
-						  NODE_ACCESS_CLASS_1);
+						  ACCESS_COORDINATE_CPU);
 	}
 }
 
@@ -697,7 +700,8 @@
 	int i;
 
 	/* Don't update for generic port if there's no device handle */
-	if (access == NODE_ACCESS_CLASS_GENPORT_SINK &&
+	if ((access == NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL ||
+	     access == NODE_ACCESS_CLASS_GENPORT_SINK_CPU) &&
 	    !(*(u16 *)target->gen_port_device_handle))
 		return;
 
@@ -709,7 +713,8 @@
 	 */
 	if (target->processor_pxm != PXM_INVAL) {
 		cpu_nid = pxm_to_node(target->processor_pxm);
-		if (access == 0 || node_state(cpu_nid, N_CPU)) {
+		if (access == ACCESS_COORDINATE_LOCAL ||
+		    node_state(cpu_nid, N_CPU)) {
 			set_bit(target->processor_pxm, p_nodes);
 			return;
 		}
@@ -737,7 +742,9 @@
 		list_for_each_entry(initiator, &initiators, node) {
 			u32 value;
 
-			if (access == 1 && !initiator->has_cpu) {
+			if ((access == ACCESS_COORDINATE_CPU ||
+			     access == NODE_ACCESS_CLASS_GENPORT_SINK_CPU) &&
+			    !initiator->has_cpu) {
 				clear_bit(initiator->processor_pxm, p_nodes);
 				continue;
 			}
@@ -770,20 +777,24 @@
 	}
 }
 
-static void hmat_register_generic_target_initiators(struct memory_target *target)
+static void hmat_update_generic_target(struct memory_target *target)
 {
 	static DECLARE_BITMAP(p_nodes, MAX_NUMNODES);
 
-	__hmat_register_target_initiators(target, p_nodes,
-					  NODE_ACCESS_CLASS_GENPORT_SINK);
+	hmat_update_target_attrs(target, p_nodes,
+				 NODE_ACCESS_CLASS_GENPORT_SINK_LOCAL);
+	hmat_update_target_attrs(target, p_nodes,
+				 NODE_ACCESS_CLASS_GENPORT_SINK_CPU);
 }
 
 static void hmat_register_target_initiators(struct memory_target *target)
 {
 	static DECLARE_BITMAP(p_nodes, MAX_NUMNODES);
 
-	__hmat_register_target_initiators(target, p_nodes, 0);
-	__hmat_register_target_initiators(target, p_nodes, 1);
+	__hmat_register_target_initiators(target, p_nodes,
+					  ACCESS_COORDINATE_LOCAL);
+	__hmat_register_target_initiators(target, p_nodes,
+					  ACCESS_COORDINATE_CPU);
 }
 
 static void hmat_register_target_cache(struct memory_target *target)
@@ -835,7 +846,7 @@
 	 */
 	mutex_lock(&target_lock);
 	if (*(u16 *)target->gen_port_device_handle) {
-		hmat_register_generic_target_initiators(target);
+		hmat_update_generic_target(target);
 		target->registered = true;
 	}
 	mutex_unlock(&target_lock);
@@ -854,8 +865,8 @@
 	if (!target->registered) {
 		hmat_register_target_initiators(target);
 		hmat_register_target_cache(target);
-		hmat_register_target_perf(target, NODE_ACCESS_CLASS_0);
-		hmat_register_target_perf(target, NODE_ACCESS_CLASS_1);
+		hmat_register_target_perf(target, ACCESS_COORDINATE_LOCAL);
+		hmat_register_target_perf(target, ACCESS_COORDINATE_CPU);
 		target->registered = true;
 	}
 	mutex_unlock(&target_lock);
@@ -927,7 +938,7 @@
 		return NOTIFY_OK;
 
 	mutex_lock(&target_lock);
-	hmat_update_target_attrs(target, p_nodes, 1);
+	hmat_update_target_attrs(target, p_nodes, ACCESS_COORDINATE_CPU);
 	mutex_unlock(&target_lock);
 
 	perf = &target->coord[1];
--- linux-qcom-6.8.0.orig/drivers/acpi/numa/srat.c
+++ linux-qcom-6.8.0/drivers/acpi/numa/srat.c
@@ -206,6 +206,11 @@
 	return acpi_numa < 0;
 }
 
+__weak int __init numa_fill_memblks(u64 start, u64 end)
+{
+	return NUMA_NO_MEMBLK;
+}
+
 #if defined(CONFIG_X86) || defined(CONFIG_ARM64) || defined(CONFIG_LOONGARCH)
 /*
  * Callback for SLIT parsing.  pxm_to_node() returns NUMA_NO_NODE for
--- linux-qcom-6.8.0.orig/drivers/acpi/osi.c
+++ linux-qcom-6.8.0/drivers/acpi/osi.c
@@ -444,6 +444,77 @@
 	},
 
 	/*
+	 * The following Lenovo models have a broken workaround in the
+	 * acpi_video backlight implementation to meet the Windows 8
+	 * requirement of 101 backlight levels. Reverting to pre-Win8
+	 * behavior fixes the problem.
+	 */
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad L430",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L430"),
+		},
+	},
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad T430",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430"),
+		},
+	},
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad T430s",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430s"),
+		},
+	},
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad T530",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T530"),
+		},
+	},
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad W530",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W530"),
+		},
+	},
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad X1 Carbon",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X1 Carbon"),
+		},
+	},
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad X230",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"),
+		},
+	},
+	{
+	.callback = dmi_disable_osi_win8,
+	.ident = "Lenovo ThinkPad Edge E330",
+	.matches = {
+		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Edge E330"),
+		},
+	},
+
+	/*
 	 * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
 	 * Linux ignores it, except for the machines enumerated below.
 	 */
--- linux-qcom-6.8.0.orig/drivers/acpi/pmic/tps68470_pmic.c
+++ linux-qcom-6.8.0/drivers/acpi/pmic/tps68470_pmic.c
@@ -376,10 +376,8 @@
 	struct tps68470_pmic_opregion *opregion;
 	acpi_status status;
 
-	if (!dev || !tps68470_regmap) {
-		dev_warn(dev, "dev or regmap is NULL\n");
-		return -EINVAL;
-	}
+	if (!tps68470_regmap)
+		return dev_err_probe(dev, -EINVAL, "regmap is missing\n");
 
 	if (!handle) {
 		dev_warn(dev, "acpi handle is NULL\n");
--- linux-qcom-6.8.0.orig/drivers/acpi/prmt.c
+++ linux-qcom-6.8.0/drivers/acpi/prmt.c
@@ -52,7 +52,7 @@
 static LIST_HEAD(prm_module_list);
 
 struct prm_handler_info {
-	guid_t guid;
+	efi_guid_t guid;
 	efi_status_t (__efiapi *handler_addr)(u64, void *);
 	u64 static_data_buffer_addr;
 	u64 acpi_param_buffer_addr;
@@ -72,17 +72,21 @@
 	struct prm_handler_info handlers[] __counted_by(handler_count);
 };
 
-static u64 efi_pa_va_lookup(u64 pa)
+static u64 efi_pa_va_lookup(efi_guid_t *guid, u64 pa)
 {
 	efi_memory_desc_t *md;
 	u64 pa_offset = pa & ~PAGE_MASK;
 	u64 page = pa & PAGE_MASK;
 
 	for_each_efi_memory_desc(md) {
-		if (md->phys_addr < pa && pa < md->phys_addr + PAGE_SIZE * md->num_pages)
+		if ((md->attribute & EFI_MEMORY_RUNTIME) &&
+		    (md->phys_addr < pa && pa < md->phys_addr + PAGE_SIZE * md->num_pages)) {
 			return pa_offset + md->virt_addr + page - md->phys_addr;
+		}
 	}
 
+	pr_warn("Failed to find VA for GUID: %pUL, PA: 0x%llx", guid, pa);
+
 	return 0;
 }
 
@@ -148,9 +152,15 @@
 		th = &tm->handlers[cur_handler];
 
 		guid_copy(&th->guid, (guid_t *)handler_info->handler_guid);
-		th->handler_addr = (void *)efi_pa_va_lookup(handler_info->handler_address);
-		th->static_data_buffer_addr = efi_pa_va_lookup(handler_info->static_data_buffer_address);
-		th->acpi_param_buffer_addr = efi_pa_va_lookup(handler_info->acpi_param_buffer_address);
+		th->handler_addr =
+			(void *)efi_pa_va_lookup(&th->guid, handler_info->handler_address);
+
+		th->static_data_buffer_addr =
+			efi_pa_va_lookup(&th->guid, handler_info->static_data_buffer_address);
+
+		th->acpi_param_buffer_addr =
+			efi_pa_va_lookup(&th->guid, handler_info->acpi_param_buffer_address);
+
 	} while (++cur_handler < tm->handler_count && (handler_info = get_next_handler(handler_info)));
 
 	return 0;
@@ -253,6 +263,11 @@
 		if (!handler || !module)
 			goto invalid_guid;
 
+		if (!handler->handler_addr) {
+			buffer->prm_status = PRM_HANDLER_ERROR;
+			return AE_OK;
+		}
+
 		ACPI_COPY_NAMESEG(context.signature, "PRMC");
 		context.revision = 0x0;
 		context.reserved = 0x0;
--- linux-qcom-6.8.0.orig/drivers/acpi/processor_idle.c
+++ linux-qcom-6.8.0/drivers/acpi/processor_idle.c
@@ -16,7 +16,6 @@
 #include <linux/acpi.h>
 #include <linux/dmi.h>
 #include <linux/sched.h>       /* need_resched() */
-#include <linux/sort.h>
 #include <linux/tick.h>
 #include <linux/cpuidle.h>
 #include <linux/cpu.h>
@@ -386,25 +385,24 @@
 	acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
 }
 
-static int acpi_cst_latency_cmp(const void *a, const void *b)
+static void acpi_cst_latency_sort(struct acpi_processor_cx *states, size_t length)
 {
-	const struct acpi_processor_cx *x = a, *y = b;
+	int i, j, k;
 
-	if (!(x->valid && y->valid))
-		return 0;
-	if (x->latency > y->latency)
-		return 1;
-	if (x->latency < y->latency)
-		return -1;
-	return 0;
-}
-static void acpi_cst_latency_swap(void *a, void *b, int n)
-{
-	struct acpi_processor_cx *x = a, *y = b;
+	for (i = 1; i < length; i++) {
+		if (!states[i].valid)
+			continue;
 
-	if (!(x->valid && y->valid))
-		return;
-	swap(x->latency, y->latency);
+		for (j = i - 1, k = i; j >= 0; j--) {
+			if (!states[j].valid)
+				continue;
+
+			if (states[j].latency > states[k].latency)
+				swap(states[j].latency, states[k].latency);
+
+			k = j;
+		}
+	}
 }
 
 static int acpi_processor_power_verify(struct acpi_processor *pr)
@@ -449,10 +447,7 @@
 
 	if (buggy_latency) {
 		pr_notice("FW issue: working around C-state latencies out of order\n");
-		sort(&pr->power.states[1], max_cstate,
-		     sizeof(struct acpi_processor_cx),
-		     acpi_cst_latency_cmp,
-		     acpi_cst_latency_swap);
+		acpi_cst_latency_sort(&pr->power.states[1], max_cstate);
 	}
 
 	lapic_timer_propagate_broadcast(pr);
@@ -1430,6 +1425,8 @@
 		acpi_processor_registered--;
 		if (acpi_processor_registered == 0)
 			cpuidle_unregister_driver(&acpi_idle_driver);
+
+		kfree(dev);
 	}
 
 	pr->flags.power_setup_done = 0;
--- linux-qcom-6.8.0.orig/drivers/acpi/property.c
+++ linux-qcom-6.8.0/drivers/acpi/property.c
@@ -80,6 +80,9 @@
 	struct acpi_data_node *dn;
 	bool result;
 
+	if (acpi_graph_ignore_port(handle))
+		return false;
+
 	dn = kzalloc(sizeof(*dn), GFP_KERNEL);
 	if (!dn)
 		return false;
@@ -1179,8 +1182,6 @@
 		}
 		break;
 	}
-	if (nval == 0)
-		return -EINVAL;
 
 	if (obj->type == ACPI_TYPE_BUFFER) {
 		if (proptype != DEV_PROP_U8)
@@ -1204,9 +1205,11 @@
 		ret = acpi_copy_property_array_uint(items, (u64 *)val, nval);
 		break;
 	case DEV_PROP_STRING:
-		ret = acpi_copy_property_array_string(
-			items, (char **)val,
-			min_t(u32, nval, obj->package.count));
+		nval = min_t(u32, nval, obj->package.count);
+		if (nval == 0)
+			return -ENODATA;
+
+		ret = acpi_copy_property_array_string(items, (char **)val, nval);
 		break;
 	default:
 		ret = -EINVAL;
--- linux-qcom-6.8.0.orig/drivers/acpi/resource.c
+++ linux-qcom-6.8.0/drivers/acpi/resource.c
@@ -250,6 +250,9 @@
 	switch (addr->resource_type) {
 	case ACPI_MEMORY_RANGE:
 		acpi_dev_memresource_flags(res, len, wp);
+
+		if (addr->info.mem.caching == ACPI_PREFETCHABLE_MEMORY)
+			res->flags |= IORESOURCE_PREFETCH;
 		break;
 	case ACPI_IO_RANGE:
 		acpi_dev_ioresource_flags(res, len, iodec,
@@ -265,9 +268,6 @@
 	if (addr->producer_consumer == ACPI_PRODUCER)
 		res->flags |= IORESOURCE_WINDOW;
 
-	if (addr->info.mem.caching == ACPI_PREFETCHABLE_MEMORY)
-		res->flags |= IORESOURCE_PREFETCH;
-
 	return !(res->flags & IORESOURCE_DISABLED);
 }
 
@@ -441,6 +441,20 @@
 		},
 	},
 	{
+		/* Asus Vivobook X1504VAP */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "X1504VAP"),
+		},
+	},
+	{
+		/* Asus Vivobook X1704VAP */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_BOARD_NAME, "X1704VAP"),
+		},
+	},
+	{
 		/* Asus ExpertBook B1402CBA */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
@@ -469,38 +483,38 @@
 		},
 	},
 	{
-		/* Asus ExpertBook B2402CBA */
+		/* Asus ExpertBook B2402 (B2402CBA / B2402FBA / B2402CVA / B2402FVA) */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-			DMI_MATCH(DMI_BOARD_NAME, "B2402CBA"),
+			DMI_MATCH(DMI_BOARD_NAME, "B2402"),
 		},
 	},
 	{
-		/* Asus ExpertBook B2402FBA */
+		/* Asus ExpertBook B2502 (B2502CBA / B2502FBA / B2502CVA / B2502FVA) */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-			DMI_MATCH(DMI_BOARD_NAME, "B2402FBA"),
+			DMI_MATCH(DMI_BOARD_NAME, "B2502"),
 		},
 	},
 	{
-		/* Asus ExpertBook B2502 */
+		/* Asus Vivobook Go E1404GA* */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-			DMI_MATCH(DMI_BOARD_NAME, "B2502CBA"),
+			DMI_MATCH(DMI_BOARD_NAME, "E1404GA"),
 		},
 	},
 	{
-		/* Asus Vivobook E1504GA */
+		/* Asus Vivobook E1504GA* */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 			DMI_MATCH(DMI_BOARD_NAME, "E1504GA"),
 		},
 	},
 	{
-		/* Asus Vivobook E1504GAB */
+		/* Asus Vivobook Pro N6506M* */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-			DMI_MATCH(DMI_BOARD_NAME, "E1504GAB"),
+			DMI_MATCH(DMI_BOARD_NAME, "N6506M"),
 		},
 	},
 	{
@@ -510,6 +524,25 @@
 			DMI_MATCH(DMI_BOARD_NAME, "17U70P"),
 		},
 	},
+	{
+		/* TongFang GXxHRXx/TUXEDO InfinityBook Pro Gen9 AMD */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "GXxHRXx"),
+		},
+	},
+	{
+		/* TongFang GMxHGxx/TUXEDO Stellaris Slim Gen1 AMD */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "GMxHGxx"),
+		},
+	},
+	{
+		/* LG Electronics 16T90SP */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"),
+			DMI_MATCH(DMI_BOARD_NAME, "16T90SP"),
+		},
+	},
 	{ }
 };
 
@@ -520,6 +553,18 @@
  */
 static const struct dmi_system_id irq1_edge_low_force_override[] = {
 	{
+		/* MECHREV Jiaolong17KS Series GM7XG0M */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "GM7XG0M"),
+		},
+	},
+	{
+		/* XMG APEX 17 (M23) */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "GMxBGxx"),
+		},
+	},
+	{
 		/* TongFang GMxRGxx/XMG CORE 15 (M22)/TUXEDO Stellaris 15 Gen4 AMD */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_NAME, "GMxRGxx"),
@@ -532,6 +577,12 @@
 		},
 	},
 	{
+		/* TongFang GMxXGxX/TUXEDO Polaris 15 Gen5 AMD */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "GMxXGxX"),
+		},
+	},
+	{
 		/* TongFang GMxXGxx sold as Eluktronics Inc. RP-15 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Eluktronics Inc."),
@@ -588,6 +639,57 @@
 			DMI_MATCH(DMI_BOARD_NAME, "GM5RGEE0016COM"),
 		},
 	},
+	{
+		/* Lunnen Ground 15 / AMD Ryzen 5 5500U */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Lunnen"),
+			DMI_MATCH(DMI_BOARD_NAME, "LLL5DAW"),
+		},
+	},
+	{
+		/* Lunnen Ground 16 / AMD Ryzen 7 5800U */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Lunnen"),
+			DMI_MATCH(DMI_BOARD_NAME, "LL6FA"),
+		},
+	},
+	{
+		/* MAIBENBEN X577 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "MAIBENBEN"),
+			DMI_MATCH(DMI_BOARD_NAME, "X577"),
+		},
+	},
+	{
+		/* Maibenben X565 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "MAIBENBEN"),
+			DMI_MATCH(DMI_BOARD_NAME, "X565"),
+		},
+	},
+	{
+		/* TongFang GXxHRXx/TUXEDO InfinityBook Pro Gen9 AMD */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "GXxHRXx"),
+		},
+	},
+	{
+		/* TongFang GMxHGxx/TUXEDO Stellaris Slim Gen1 AMD */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "GMxHGxx"),
+		},
+	},
+	{
+		/*
+		 * TongFang GM5HG0A in case of the SKIKK Vanaheim relabel the
+		 * board-name is changed, so check OEM strings instead. Note
+		 * OEM string matches are always exact matches.
+		 * https://bugzilla.kernel.org/show_bug.cgi?id=219614
+		 */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_OEM_STRING, "GM5HG0A"),
+		},
+	},
 	{ }
 };
 
@@ -613,11 +715,11 @@
 	for (i = 0; i < ARRAY_SIZE(override_table); i++) {
 		const struct irq_override_cmp *entry = &override_table[i];
 
-		if (dmi_check_system(entry->system) &&
-		    entry->irq == gsi &&
+		if (entry->irq == gsi &&
 		    entry->triggering == triggering &&
 		    entry->polarity == polarity &&
-		    entry->shareable == shareable)
+		    entry->shareable == shareable &&
+		    dmi_check_system(entry->system))
 			return entry->override;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/acpi/sbs.c
+++ linux-qcom-6.8.0/drivers/acpi/sbs.c
@@ -77,7 +77,6 @@
 	u16 spec;
 	u8 id;
 	u8 present:1;
-	u8 have_sysfs_alarm:1;
 };
 
 #define to_acpi_battery(x) power_supply_get_drvdata(x)
@@ -462,12 +461,18 @@
 	return count;
 }
 
-static const struct device_attribute alarm_attr = {
+static struct device_attribute alarm_attr = {
 	.attr = {.name = "alarm", .mode = 0644},
 	.show = acpi_battery_alarm_show,
 	.store = acpi_battery_alarm_store,
 };
 
+static struct attribute *acpi_battery_attrs[] = {
+	&alarm_attr.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(acpi_battery);
+
 /* --------------------------------------------------------------------------
                                  Driver Interface
    -------------------------------------------------------------------------- */
@@ -518,7 +523,10 @@
 static int acpi_battery_add(struct acpi_sbs *sbs, int id)
 {
 	struct acpi_battery *battery = &sbs->battery[id];
-	struct power_supply_config psy_cfg = { .drv_data = battery, };
+	struct power_supply_config psy_cfg = {
+		.drv_data = battery,
+		.attr_grp = acpi_battery_groups,
+	};
 	int result;
 
 	battery->id = id;
@@ -548,10 +556,6 @@
 		goto end;
 	}
 
-	result = device_create_file(&battery->bat->dev, &alarm_attr);
-	if (result)
-		goto end;
-	battery->have_sysfs_alarm = 1;
       end:
 	pr_info("%s [%s]: Battery Slot [%s] (battery %s)\n",
 	       ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
@@ -563,11 +567,8 @@
 {
 	struct acpi_battery *battery = &sbs->battery[id];
 
-	if (battery->bat) {
-		if (battery->have_sysfs_alarm)
-			device_remove_file(&battery->bat->dev, &alarm_attr);
+	if (battery->bat)
 		power_supply_unregister(battery->bat);
-	}
 }
 
 static int acpi_charger_add(struct acpi_sbs *sbs)
@@ -610,7 +611,7 @@
 	if (sbs->charger_exists) {
 		acpi_ac_get_present(sbs);
 		if (sbs->charger_present != saved_charger_state)
-			kobject_uevent(&sbs->charger->dev.kobj, KOBJ_CHANGE);
+			power_supply_changed(sbs->charger);
 	}
 
 	if (sbs->manager_present) {
@@ -622,7 +623,7 @@
 			acpi_battery_read(bat);
 			if (saved_battery_state == bat->present)
 				continue;
-			kobject_uevent(&bat->bat->dev.kobj, KOBJ_CHANGE);
+			power_supply_changed(bat->bat);
 		}
 	}
 }
--- linux-qcom-6.8.0.orig/drivers/acpi/scan.c
+++ linux-qcom-6.8.0/drivers/acpi/scan.c
@@ -314,18 +314,14 @@
 		 * again).
 		 */
 		if (adev->handler) {
-			dev_warn(&adev->dev, "Already enumerated\n");
-			return -EALREADY;
+			dev_dbg(&adev->dev, "Already enumerated\n");
+			return 0;
 		}
 		error = acpi_bus_scan(adev->handle);
 		if (error) {
 			dev_warn(&adev->dev, "Namespace scan failure\n");
 			return error;
 		}
-		if (!adev->handler) {
-			dev_warn(&adev->dev, "Enumeration failure\n");
-			error = -ENODEV;
-		}
 	} else {
 		error = acpi_scan_device_not_enumerated(adev);
 	}
@@ -798,6 +794,7 @@
 	"INTC1059", /* IVSC (TGL) driver must be loaded to allow i2c access to camera sensors */
 	"INTC1095", /* IVSC (ADL) driver must be loaded to allow i2c access to camera sensors */
 	"INTC100A", /* IVSC (RPL) driver must be loaded to allow i2c access to camera sensors */
+	"INTC10CF", /* IVSC (MTL) driver must be loaded to allow i2c access to camera sensors */
 	NULL
 };
 
@@ -1806,7 +1803,8 @@
 			if (dep->honor_dep)
 				adev->flags.honor_deps = 1;
 
-			adev->dep_unmet++;
+			if (!dep->met)
+				adev->dep_unmet++;
 		}
 	}
 }
@@ -2226,6 +2224,8 @@
 	if (device->handler)
 		goto ok;
 
+	acpi_ec_register_opregions(device);
+
 	if (!device->flags.initialized) {
 		device->flags.power_manageable =
 			device->power.states[ACPI_STATE_D0].flags.valid;
--- linux-qcom-6.8.0.orig/drivers/acpi/sleep.c
+++ linux-qcom-6.8.0/drivers/acpi/sleep.c
@@ -385,18 +385,6 @@
 		DMI_MATCH(DMI_PRODUCT_NAME, "20GGA00L00"),
 		},
 	},
-	/*
-	 * ASUS B1400CEAE hangs on resume from suspend (see
-	 * https://bugzilla.kernel.org/show_bug.cgi?id=215742).
-	 */
-	{
-	.callback = init_default_s3,
-	.ident = "ASUS B1400CEAE",
-	.matches = {
-		DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-		DMI_MATCH(DMI_PRODUCT_NAME, "ASUS EXPERTBOOK B1400CEAE"),
-		},
-	},
 	{},
 };
 
--- linux-qcom-6.8.0.orig/drivers/acpi/thermal.c
+++ linux-qcom-6.8.0/drivers/acpi/thermal.c
@@ -167,11 +167,17 @@
 
 static int acpi_thermal_temp(struct acpi_thermal *tz, int temp_deci_k)
 {
+	int temp;
+
 	if (temp_deci_k == THERMAL_TEMP_INVALID)
 		return THERMAL_TEMP_INVALID;
 
-	return deci_kelvin_to_millicelsius_with_offset(temp_deci_k,
+	temp = deci_kelvin_to_millicelsius_with_offset(temp_deci_k,
 						       tz->kelvin_offset);
+	if (temp <= 0)
+		return THERMAL_TEMP_INVALID;
+
+	return temp;
 }
 
 static bool acpi_thermal_trip_valid(struct acpi_thermal_trip *acpi_trip)
--- linux-qcom-6.8.0.orig/drivers/acpi/utils.c
+++ linux-qcom-6.8.0/drivers/acpi/utils.c
@@ -559,7 +559,7 @@
  *
  * Caller must free the returned buffer
  */
-static char *acpi_handle_path(acpi_handle handle)
+char *acpi_handle_path(acpi_handle handle)
 {
 	struct acpi_buffer buffer = {
 		.length = ACPI_ALLOCATE_BUFFER,
--- linux-qcom-6.8.0.orig/drivers/acpi/video_detect.c
+++ linux-qcom-6.8.0/drivers/acpi/video_detect.c
@@ -252,6 +252,14 @@
 		DMI_MATCH(DMI_PRODUCT_NAME, "PCG-FRV35"),
 		},
 	},
+	{
+	 .callback = video_detect_force_vendor,
+	 /* Panasonic Toughbook CF-18 */
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Matsushita Electric Industrial"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"),
+		},
+	},
 
 	/*
 	 * Toshiba models with Transflective display, these need to use
@@ -499,6 +507,14 @@
 	},
 	{
 	 .callback = video_detect_force_native,
+	 /* Lenovo Slim 7 16ARH7 */
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "82UX"),
+		},
+	},
+	{
+	 .callback = video_detect_force_native,
 	 /* Lenovo ThinkPad X131e (3371 AMD version) */
 	 .matches = {
 		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
@@ -532,6 +548,38 @@
 		},
 	},
 	{
+	 .callback = video_detect_force_native,
+	 /* Apple MacBook Air 7,2 */
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+		DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir7,2"),
+		},
+	},
+	{
+	 .callback = video_detect_force_native,
+	 /* Apple MacBook Air 9,1 */
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+		DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir9,1"),
+		},
+	},
+	{
+	 .callback = video_detect_force_native,
+	 /* Apple MacBook Pro 9,2 */
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+		DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro9,2"),
+		},
+	},
+	{
+	 .callback = video_detect_force_native,
+	 /* Apple MacBook Pro 11,2 */
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+		DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro11,2"),
+		},
+	},
+	{
 	 /* https://bugzilla.redhat.com/show_bug.cgi?id=1217249 */
 	 .callback = video_detect_force_native,
 	 /* Apple MacBook Pro 12,1 */
@@ -542,6 +590,14 @@
 	},
 	{
 	 .callback = video_detect_force_native,
+	 /* Apple MacBook Pro 16,2 */
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+		DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro16,2"),
+		},
+	},
+	{
+	 .callback = video_detect_force_native,
 	 /* Dell Inspiron N4010 */
 	 .matches = {
 		DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
@@ -894,6 +950,7 @@
 	static DEFINE_MUTEX(init_mutex);
 	static bool nvidia_wmi_ec_present;
 	static bool apple_gmux_present;
+	static bool dell_uart_backlight_present;
 	static bool native_available;
 	static bool init_done;
 	static long video_caps;
@@ -908,6 +965,7 @@
 				    &video_caps, NULL);
 		nvidia_wmi_ec_present = nvidia_wmi_ec_supported();
 		apple_gmux_present = apple_gmux_detect(NULL, NULL);
+		dell_uart_backlight_present = acpi_dev_found("DELL0501");
 		init_done = true;
 	}
 	if (native)
@@ -938,6 +996,9 @@
 	if (apple_gmux_present)
 		return acpi_backlight_apple_gmux;
 
+	if (dell_uart_backlight_present)
+		return acpi_backlight_vendor;
+
 	/* Use ACPI video if available, except when native should be preferred. */
 	if ((video_caps & ACPI_VIDEO_BACKLIGHT) &&
 	     !(native_available && prefer_native_over_acpi_video()))
--- linux-qcom-6.8.0.orig/drivers/acpi/x86/s2idle.c
+++ linux-qcom-6.8.0/drivers/acpi/x86/s2idle.c
@@ -488,7 +488,19 @@
 		rev_id = 1;
 		lps0_dsm_func_mask = validate_dsm(adev->handle,
 					ACPI_LPS0_DSM_UUID, rev_id, &lps0_dsm_guid);
-		lps0_dsm_func_mask_microsoft = -EINVAL;
+		if (lps0_dsm_func_mask > 0 && lps0_dsm_func_mask_microsoft > 0) {
+			unsigned int func_mask;
+
+			/*
+			 * Log a message if the _DSM function sets for two
+			 * different UUIDs overlap.
+			 */
+			func_mask = lps0_dsm_func_mask & lps0_dsm_func_mask_microsoft;
+			if (func_mask)
+				acpi_handle_info(adev->handle,
+						 "Duplicate LPS0 _DSM functions (mask: 0x%x)\n",
+						 func_mask);
+		}
 	}
 
 	if (lps0_dsm_func_mask < 0 && lps0_dsm_func_mask_microsoft < 0)
@@ -549,19 +561,22 @@
 				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
 
 	/* LPS0 entry */
-	if (lps0_dsm_func_mask > 0)
-		acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
-					ACPI_LPS0_ENTRY_AMD :
-					ACPI_LPS0_ENTRY,
+	if (lps0_dsm_func_mask > 0 && acpi_s2idle_vendor_amd())
+		acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD,
 					lps0_dsm_func_mask, lps0_dsm_guid);
+
 	if (lps0_dsm_func_mask_microsoft > 0) {
-		/* modern standby entry */
+		/* Modern Standby entry */
 		acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_ENTRY,
 				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
 		acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY,
 				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
 	}
 
+	if (lps0_dsm_func_mask > 0 && !acpi_s2idle_vendor_amd())
+		acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY,
+					lps0_dsm_func_mask, lps0_dsm_guid);
+
 	list_for_each_entry(handler, &lps0_s2idle_devops_head, list_node) {
 		if (handler->prepare)
 			handler->prepare();
@@ -600,14 +615,14 @@
 					ACPI_LPS0_EXIT_AMD :
 					ACPI_LPS0_EXIT,
 					lps0_dsm_func_mask, lps0_dsm_guid);
-	if (lps0_dsm_func_mask_microsoft > 0)
+
+	if (lps0_dsm_func_mask_microsoft > 0) {
 		acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT,
 				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
-
-	/* Modern standby exit */
-	if (lps0_dsm_func_mask_microsoft > 0)
+		/* Modern Standby exit */
 		acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_EXIT,
 				lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
+	}
 
 	/* Screen on */
 	if (lps0_dsm_func_mask_microsoft > 0)
--- linux-qcom-6.8.0.orig/drivers/acpi/x86/utils.c
+++ linux-qcom-6.8.0/drivers/acpi/x86/utils.c
@@ -12,6 +12,7 @@
 
 #include <linux/acpi.h>
 #include <linux/dmi.h>
+#include <linux/pci.h>
 #include <linux/platform_device.h>
 #include <asm/cpu_device_id.h>
 #include <asm/intel-family.h>
@@ -197,16 +198,16 @@
 }
 
 /*
- * AMD systems from Renoir and Lucienne *require* that the NVME controller
+ * AMD systems from Renoir onwards *require* that the NVME controller
  * is put into D3 over a Modern Standby / suspend-to-idle cycle.
  *
  * This is "typically" accomplished using the `StorageD3Enable`
  * property in the _DSD that is checked via the `acpi_storage_d3` function
- * but this property was introduced after many of these systems launched
- * and most OEM systems don't have it in their BIOS.
+ * but some OEM systems still don't have it in their BIOS.
  *
  * The Microsoft documentation for StorageD3Enable mentioned that Windows has
- * a hardcoded allowlist for D3 support, which was used for these platforms.
+ * a hardcoded allowlist for D3 support as well as a registry key to override
+ * the BIOS, which has been used for these cases.
  *
  * This allows quirking on Linux in a similar fashion.
  *
@@ -219,19 +220,15 @@
  *    https://bugzilla.kernel.org/show_bug.cgi?id=216773
  *    https://bugzilla.kernel.org/show_bug.cgi?id=217003
  * 2) On at least one HP system StorageD3Enable is missing on the second NVME
-      disk in the system.
+ *    disk in the system.
+ * 3) On at least one HP Rembrandt system StorageD3Enable is missing on the only
+ *    NVME device.
  */
-static const struct x86_cpu_id storage_d3_cpu_ids[] = {
-	X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 24, NULL),  /* Picasso */
-	X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 96, NULL),	/* Renoir */
-	X86_MATCH_VENDOR_FAM_MODEL(AMD, 23, 104, NULL),	/* Lucienne */
-	X86_MATCH_VENDOR_FAM_MODEL(AMD, 25, 80, NULL),	/* Cezanne */
-	{}
-};
-
 bool force_storage_d3(void)
 {
-	return x86_match_cpu(storage_d3_cpu_ids);
+	if (!cpu_feature_enabled(X86_FEATURE_ZEN))
+		return false;
+	return acpi_gbl_FADT.flags & ACPI_FADT_LOW_POWER_S0;
 }
 
 /*
@@ -260,9 +257,10 @@
 #define ACPI_QUIRK_SKIP_I2C_CLIENTS				BIT(0)
 #define ACPI_QUIRK_UART1_SKIP					BIT(1)
 #define ACPI_QUIRK_UART1_TTY_UART2_SKIP				BIT(2)
-#define ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY			BIT(3)
-#define ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY			BIT(4)
-#define ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS			BIT(5)
+#define ACPI_QUIRK_PNP_UART1_SKIP				BIT(3)
+#define ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY			BIT(4)
+#define ACPI_QUIRK_USE_ACPI_AC_AND_BATTERY			BIT(5)
+#define ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS			BIT(6)
 
 static const struct dmi_system_id acpi_quirk_skip_dmi_ids[] = {
 	/*
@@ -289,6 +287,7 @@
 	/*
 	 * 2. Devices which also have the skip i2c/serdev quirks and which
 	 *    need the x86-android-tablets module to properly work.
+	 *    Sorted alphabetically.
 	 */
 #if IS_ENABLED(CONFIG_X86_ANDROID_TABLETS)
 	{
@@ -302,6 +301,19 @@
 					ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
 	},
 	{
+		/* Acer Iconia One 8 A1-840 (non FHD version) */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"),
+			/* Above strings are too generic also match BIOS date */
+			DMI_MATCH(DMI_BIOS_DATE, "04/01/2014"),
+		},
+		.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
+					ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
+					ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
+	},
+	{
+		/* Asus ME176C tablet */
 		.matches = {
 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"),
@@ -312,23 +324,24 @@
 					ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
 	},
 	{
-		/* Lenovo Yoga Book X90F/L */
+		/* Asus TF103C transformer 2-in-1 */
 		.matches = {
-			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
-			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
-			DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"),
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
 		},
 		.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
-					ACPI_QUIRK_UART1_SKIP |
 					ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
 					ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
 	},
 	{
+		/* Lenovo Yoga Book X90F/L */
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-			DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"),
 		},
 		.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
+					ACPI_QUIRK_UART1_SKIP |
 					ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
 					ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
 	},
@@ -342,6 +355,7 @@
 			DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"),
 		},
 		.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
+					ACPI_QUIRK_PNP_UART1_SKIP |
 					ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
 	},
 	{
@@ -386,6 +400,19 @@
 					ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY),
 	},
 	{
+		/* Vexia Edu Atla 10 tablet 9V version */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+			DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
+			/* Above strings are too generic, also match on BIOS date */
+			DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"),
+		},
+		.driver_data = (void *)(ACPI_QUIRK_SKIP_I2C_CLIENTS |
+					ACPI_QUIRK_UART1_SKIP |
+					ACPI_QUIRK_SKIP_ACPI_AC_AND_BATTERY |
+					ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS),
+	},
+	{
 		/* Whitelabel (sold as various brands) TM800A550L */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
@@ -405,6 +432,7 @@
 	{ "10EC5640", 0 }, /* RealTek ALC5640 audio codec */
 	{ "10EC5651", 0 }, /* RealTek ALC5651 audio codec */
 	{ "INT33F4", 0 },  /* X-Powers AXP288 PMIC */
+	{ "INT33F5", 0 },  /* TI Dollar Cove PMIC */
 	{ "INT33FD", 0 },  /* Intel Crystal Cove PMIC */
 	{ "INT34D3", 0 },  /* Intel Whiskey Cove PMIC */
 	{ "NPCE69A", 0 },  /* Asus Transformer keyboard dock */
@@ -428,27 +456,46 @@
 }
 EXPORT_SYMBOL_GPL(acpi_quirk_skip_i2c_client_enumeration);
 
-int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip)
+static int acpi_dmi_skip_serdev_enumeration(struct device *controller_parent, bool *skip)
 {
 	struct acpi_device *adev = ACPI_COMPANION(controller_parent);
 	const struct dmi_system_id *dmi_id;
 	long quirks = 0;
-	u64 uid;
-	int ret;
+	u64 uid = 0;
 
-	*skip = false;
-
-	ret = acpi_dev_uid_to_integer(adev, &uid);
-	if (ret)
+	dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids);
+	if (!dmi_id)
 		return 0;
 
-	/* to not match on PNP enumerated debug UARTs */
-	if (!dev_is_platform(controller_parent))
+	quirks = (unsigned long)dmi_id->driver_data;
+
+	/* uid is left at 0 on errors and 0 is not a valid UART UID */
+	acpi_dev_uid_to_integer(adev, &uid);
+
+	/* For PCI UARTs without an UID */
+	if (!uid && dev_is_pci(controller_parent)) {
+		struct pci_dev *pdev = to_pci_dev(controller_parent);
+
+		/*
+		 * Devfn values for PCI UARTs on Bay Trail SoCs, which are
+		 * the only devices where this fallback is necessary.
+		 */
+		if (pdev->devfn == PCI_DEVFN(0x1e, 3))
+			uid = 1;
+		else if (pdev->devfn == PCI_DEVFN(0x1e, 4))
+			uid = 2;
+	}
+
+	if (!uid)
 		return 0;
 
-	dmi_id = dmi_first_match(acpi_quirk_skip_dmi_ids);
-	if (dmi_id)
-		quirks = (unsigned long)dmi_id->driver_data;
+	if (!dev_is_platform(controller_parent) && !dev_is_pci(controller_parent)) {
+		/* PNP enumerated UARTs */
+		if ((quirks & ACPI_QUIRK_PNP_UART1_SKIP) && uid == 1)
+			*skip = true;
+
+		return 0;
+	}
 
 	if ((quirks & ACPI_QUIRK_UART1_SKIP) && uid == 1)
 		*skip = true;
@@ -463,7 +510,6 @@
 
 	return 0;
 }
-EXPORT_SYMBOL_GPL(acpi_quirk_skip_serdev_enumeration);
 
 bool acpi_quirk_skip_gpio_event_handlers(void)
 {
@@ -478,8 +524,41 @@
 	return (quirks & ACPI_QUIRK_SKIP_GPIO_EVENT_HANDLERS);
 }
 EXPORT_SYMBOL_GPL(acpi_quirk_skip_gpio_event_handlers);
+#else
+static int acpi_dmi_skip_serdev_enumeration(struct device *controller_parent, bool *skip)
+{
+	return 0;
+}
 #endif
 
+int acpi_quirk_skip_serdev_enumeration(struct device *controller_parent, bool *skip)
+{
+	struct acpi_device *adev = ACPI_COMPANION(controller_parent);
+
+	*skip = false;
+
+	/*
+	 * The DELL0501 ACPI HID represents an UART (CID is set to PNP0501) with
+	 * a backlight-controller attached. There is no separate ACPI device with
+	 * an UartSerialBusV2() resource to model the backlight-controller.
+	 * Set skip to true so that the tty core creates a serdev ctrl device.
+	 * The backlight driver will manually create the serdev client device.
+	 */
+	if (adev && acpi_dev_hid_match(adev, "DELL0501")) {
+		*skip = true;
+		/*
+		 * Create a platform dev for dell-uart-backlight to bind to.
+		 * This is a static device, so no need to store the result.
+		 */
+		platform_device_register_simple("dell-uart-backlight", PLATFORM_DEVID_NONE,
+						NULL, 0);
+		return 0;
+	}
+
+	return acpi_dmi_skip_serdev_enumeration(controller_parent, skip);
+}
+EXPORT_SYMBOL_GPL(acpi_quirk_skip_serdev_enumeration);
+
 /* Lists of PMIC ACPI HIDs with an (often better) native charger driver */
 static const struct {
 	const char *hid;
--- linux-qcom-6.8.0.orig/drivers/android/Kconfig
+++ linux-qcom-6.8.0/drivers/android/Kconfig
@@ -2,7 +2,7 @@
 menu "Android"
 
 config ANDROID_BINDER_IPC
-	bool "Android Binder IPC Driver"
+	tristate "Android Binder IPC Driver"
 	depends on MMU
 	default n
 	help
@@ -14,8 +14,8 @@
 	  between said processes.
 
 config ANDROID_BINDERFS
-	bool "Android Binderfs filesystem"
-	depends on ANDROID_BINDER_IPC
+	tristate "Android Binderfs filesystem"
+	depends on (ANDROID_BINDER_IPC=y) || (ANDROID_BINDER_IPC=m && m)
 	default n
 	help
 	  Binderfs is a pseudo-filesystem for the Android Binder IPC driver
--- linux-qcom-6.8.0.orig/drivers/android/Makefile
+++ linux-qcom-6.8.0/drivers/android/Makefile
@@ -1,6 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
 ccflags-y += -I$(src)			# needed for trace events
 
-obj-$(CONFIG_ANDROID_BINDERFS)		+= binderfs.o
-obj-$(CONFIG_ANDROID_BINDER_IPC)	+= binder.o binder_alloc.o
-obj-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o
+binder_linux-y := binder.o binder_alloc.o
+obj-$(CONFIG_ANDROID_BINDER_IPC) += binder_linux.o
+binder_linux-$(CONFIG_ANDROID_BINDERFS) += binderfs.o
+binder_linux-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o
+
+# binder-$(CONFIG_ANDROID_BINDER_IPC) := binder.o binder_alloc.o
+# binder-$(CONFIG_ANDROID_BINDERFS) += binderfs.o
--- linux-qcom-6.8.0.orig/drivers/android/binder.c
+++ linux-qcom-6.8.0/drivers/android/binder.c
@@ -570,9 +570,7 @@
 static bool binder_available_for_proc_work_ilocked(struct binder_thread *thread)
 {
 	return !thread->transaction_stack &&
-		binder_worklist_empty_ilocked(&thread->todo) &&
-		(thread->looper & (BINDER_LOOPER_STATE_ENTERED |
-				   BINDER_LOOPER_STATE_REGISTERED));
+		binder_worklist_empty_ilocked(&thread->todo);
 }
 
 static void binder_wakeup_poll_threads_ilocked(struct binder_proc *proc,
@@ -1708,8 +1706,10 @@
 	size_t object_size = 0;
 
 	read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset);
-	if (offset > buffer->data_size || read_size < sizeof(*hdr))
+	if (offset > buffer->data_size || read_size < sizeof(*hdr) ||
+	    !IS_ALIGNED(offset, sizeof(u32)))
 		return 0;
+
 	if (u) {
 		if (copy_from_user(object, u + offset, read_size))
 			return 0;
@@ -2930,8 +2930,7 @@
 	struct binder_context *context = proc->context;
 	int t_debug_id = atomic_inc_return(&binder_last_id);
 	ktime_t t_start_time = ktime_get();
-	char *secctx = NULL;
-	u32 secctx_sz = 0;
+	struct lsmcontext lsmctx;
 	struct list_head sgc_head;
 	struct list_head pf_head;
 	const void __user *user_buffer = (const void __user *)
@@ -3210,8 +3209,8 @@
 		size_t added_size;
 
 		security_cred_getsecid(proc->cred, &secid);
-		ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
-		if (ret) {
+		ret = security_secid_to_secctx(secid, &lsmctx);
+		if (ret < 0) {
 			binder_txn_error("%d:%d failed to get security context\n",
 				thread->pid, proc->pid);
 			return_error = BR_FAILED_REPLY;
@@ -3219,7 +3218,7 @@
 			return_error_line = __LINE__;
 			goto err_get_secctx_failed;
 		}
-		added_size = ALIGN(secctx_sz, sizeof(u64));
+		added_size = ALIGN(lsmctx.len, sizeof(u64));
 		extra_buffers_size += added_size;
 		if (extra_buffers_size < added_size) {
 			binder_txn_error("%d:%d integer overflow of extra_buffers_size\n",
@@ -3253,23 +3252,23 @@
 		t->buffer = NULL;
 		goto err_binder_alloc_buf_failed;
 	}
-	if (secctx) {
+	if (lsmctx.context) {
 		int err;
 		size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) +
 				    ALIGN(tr->offsets_size, sizeof(void *)) +
 				    ALIGN(extra_buffers_size, sizeof(void *)) -
-				    ALIGN(secctx_sz, sizeof(u64));
+				    ALIGN(lsmctx.len, sizeof(u64));
 
 		t->security_ctx = t->buffer->user_data + buf_offset;
 		err = binder_alloc_copy_to_buffer(&target_proc->alloc,
 						  t->buffer, buf_offset,
-						  secctx, secctx_sz);
+						  lsmctx.context, lsmctx.len);
 		if (err) {
 			t->security_ctx = 0;
 			WARN_ON(1);
 		}
-		security_release_secctx(secctx, secctx_sz);
-		secctx = NULL;
+		security_release_secctx(&lsmctx);
+		lsmctx.context = NULL;
 	}
 	t->buffer->debug_id = t->debug_id;
 	t->buffer->transaction = t;
@@ -3313,7 +3312,7 @@
 	off_end_offset = off_start_offset + tr->offsets_size;
 	sg_buf_offset = ALIGN(off_end_offset, sizeof(void *));
 	sg_buf_end_offset = sg_buf_offset + extra_buffers_size -
-		ALIGN(secctx_sz, sizeof(u64));
+		ALIGN(lsmctx.len, sizeof(u64));
 	off_min = 0;
 	for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
 	     buffer_offset += sizeof(binder_size_t)) {
@@ -3342,6 +3341,7 @@
 		 */
 		copy_size = object_offset - user_offset;
 		if (copy_size && (user_offset > object_offset ||
+				object_offset > tr->data_size ||
 				binder_alloc_copy_user_to_buffer(
 					&target_proc->alloc,
 					t->buffer, user_offset,
@@ -3691,8 +3691,8 @@
 	binder_alloc_free_buf(&target_proc->alloc, t->buffer);
 err_binder_alloc_buf_failed:
 err_bad_extra_size:
-	if (secctx)
-		security_release_secctx(secctx, secctx_sz);
+	if (lsmctx.context)
+		security_release_secctx(&lsmctx);
 err_get_secctx_failed:
 	kfree(tcomplete);
 	binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
@@ -5365,7 +5365,7 @@
 			goto err;
 		break;
 	case BINDER_SET_MAX_THREADS: {
-		int max_threads;
+		u32 max_threads;
 
 		if (copy_from_user(&max_threads, ubuf,
 				   sizeof(max_threads))) {
@@ -6631,9 +6631,20 @@
 	return ret;
 }
 
-device_initcall(binder_init);
+module_init(binder_init);
+/*
+ * binder will have no exit function since binderfs instances can be mounted
+ * multiple times and also in user namespaces finding and destroying them all
+ * is not feasible without introducing insane locking. Just ignoring existing
+ * instances on module unload also wouldn't work since we would loose track of
+ * what major numer was dynamically allocated and also what minor numbers are
+ * already given out. So this would get us into all kinds of issues with device
+ * number reuse. So simply don't allow unloading unless we are forced to do so.
+ */
+
+MODULE_AUTHOR("Google, Inc.");
+MODULE_DESCRIPTION("Driver for Android binder device");
+MODULE_LICENSE("GPL v2");
 
 #define CREATE_TRACE_POINTS
 #include "binder_trace.h"
-
-MODULE_LICENSE("GPL v2");
--- linux-qcom-6.8.0.orig/drivers/android/binder_alloc.c
+++ linux-qcom-6.8.0/drivers/android/binder_alloc.c
@@ -38,8 +38,7 @@
 };
 static uint32_t binder_alloc_debug_mask = BINDER_DEBUG_USER_ERROR;
 
-module_param_named(debug_mask, binder_alloc_debug_mask,
-		   uint, 0644);
+module_param_named(alloc_debug_mask, binder_alloc_debug_mask, uint, 0644);
 
 #define binder_alloc_debug(mask, x...) \
 	do { \
--- linux-qcom-6.8.0.orig/drivers/android/binder_alloc.h
+++ linux-qcom-6.8.0/drivers/android/binder_alloc.h
@@ -6,6 +6,7 @@
 #ifndef _LINUX_BINDER_ALLOC_H
 #define _LINUX_BINDER_ALLOC_H
 
+#include <linux/kconfig.h>
 #include <linux/rbtree.h>
 #include <linux/list.h>
 #include <linux/mm.h>
@@ -111,7 +112,7 @@
 	bool oneway_spam_detected;
 };
 
-#ifdef CONFIG_ANDROID_BINDER_IPC_SELFTEST
+#if IS_ENABLED(CONFIG_ANDROID_BINDER_IPC_SELFTEST)
 void binder_selftest_alloc(struct binder_alloc *alloc);
 #else
 static inline void binder_selftest_alloc(struct binder_alloc *alloc) {}
--- linux-qcom-6.8.0.orig/drivers/android/binder_internal.h
+++ linux-qcom-6.8.0/drivers/android/binder_internal.h
@@ -5,6 +5,7 @@
 
 #include <linux/export.h>
 #include <linux/fs.h>
+#include <linux/kconfig.h>
 #include <linux/list.h>
 #include <linux/miscdevice.h>
 #include <linux/mutex.h>
@@ -77,7 +78,7 @@
 
 extern char *binder_devices_param;
 
-#ifdef CONFIG_ANDROID_BINDERFS
+#if IS_ENABLED(CONFIG_ANDROID_BINDERFS)
 extern bool is_binderfs_device(const struct inode *inode);
 extern struct dentry *binderfs_create_file(struct dentry *dir, const char *name,
 					   const struct file_operations *fops,
@@ -98,7 +99,7 @@
 static inline void binderfs_remove_file(struct dentry *dentry) {}
 #endif
 
-#ifdef CONFIG_ANDROID_BINDERFS
+#if IS_ENABLED(CONFIG_ANDROID_BINDERFS)
 extern int __init init_binderfs(void);
 #else
 static inline int __init init_binderfs(void)
@@ -421,7 +422,7 @@
 	struct list_head todo;
 	struct binder_stats stats;
 	struct list_head delivered_death;
-	int max_threads;
+	u32 max_threads;
 	int requested_threads;
 	int requested_threads_started;
 	int tmp_ref;
--- linux-qcom-6.8.0.orig/drivers/android/binderfs.c
+++ linux-qcom-6.8.0/drivers/android/binderfs.c
@@ -120,7 +120,7 @@
 	struct super_block *sb = ref_inode->i_sb;
 	struct binderfs_info *info = sb->s_fs_info;
 #if defined(CONFIG_IPC_NS)
-	bool use_reserve = (info->ipc_ns == &init_ipc_ns);
+	bool use_reserve = (info->ipc_ns == show_init_ipc_ns());
 #else
 	bool use_reserve = true;
 #endif
@@ -397,7 +397,7 @@
 	struct dentry *root = sb->s_root;
 	struct binderfs_info *info = sb->s_fs_info;
 #if defined(CONFIG_IPC_NS)
-	bool use_reserve = (info->ipc_ns == &init_ipc_ns);
+	bool use_reserve = (info->ipc_ns == show_init_ipc_ns());
 #else
 	bool use_reserve = true;
 #endif
@@ -683,7 +683,7 @@
 		return -ENOMEM;
 	info = sb->s_fs_info;
 
-	info->ipc_ns = get_ipc_ns(current->nsproxy->ipc_ns);
+	info->ipc_ns = get_ipc_ns_exported(current->nsproxy->ipc_ns);
 
 	info->root_gid = make_kgid(sb->s_user_ns, 0);
 	if (!gid_valid(info->root_gid))
--- linux-qcom-6.8.0.orig/drivers/ata/ahci.c
+++ linux-qcom-6.8.0/drivers/ata/ahci.c
@@ -431,7 +431,6 @@
 	{ PCI_VDEVICE(INTEL, 0x02d7), board_ahci_low_power }, /* Comet Lake PCH RAID */
 	/* Elkhart Lake IDs 0x4b60 & 0x4b62 https://sata-io.org/product/8803 not tested yet */
 	{ PCI_VDEVICE(INTEL, 0x4b63), board_ahci_low_power }, /* Elkhart Lake AHCI */
-	{ PCI_VDEVICE(INTEL, 0x7ae2), board_ahci_low_power }, /* Alder Lake-P AHCI */
 
 	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
 	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -668,22 +667,90 @@
 module_param(mobile_lpm_policy, int, 0644);
 MODULE_PARM_DESC(mobile_lpm_policy, "Default LPM policy for mobile chipsets");
 
-static void ahci_pci_save_initial_config(struct pci_dev *pdev,
-					 struct ahci_host_priv *hpriv)
+static char *ahci_mask_port_map;
+module_param_named(mask_port_map, ahci_mask_port_map, charp, 0444);
+MODULE_PARM_DESC(mask_port_map,
+		 "32-bits port map masks to ignore controllers ports. "
+		 "Valid values are: "
+		 "\"<mask>\" to apply the same mask to all AHCI controller "
+		 "devices, and \"<pci_dev>=<mask>,<pci_dev>=<mask>,...\" to "
+		 "specify different masks for the controllers specified, "
+		 "where <pci_dev> is the PCI ID of an AHCI controller in the "
+		 "form \"domain:bus:dev.func\"");
+
+static void ahci_apply_port_map_mask(struct device *dev,
+				     struct ahci_host_priv *hpriv, char *mask_s)
 {
-	if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA) {
-		switch (pdev->device) {
-		case 0x1166:
-			dev_info(&pdev->dev, "ASM1166 has only six ports\n");
-			hpriv->saved_port_map = 0x3f;
+	unsigned int mask;
+
+	if (kstrtouint(mask_s, 0, &mask)) {
+		dev_err(dev, "Invalid port map mask\n");
+		return;
+	}
+
+	hpriv->mask_port_map = mask;
+}
+
+static void ahci_get_port_map_mask(struct device *dev,
+				   struct ahci_host_priv *hpriv)
+{
+	char *param, *end, *str, *mask_s;
+	char *name;
+
+	if (!strlen(ahci_mask_port_map))
+		return;
+
+	str = kstrdup(ahci_mask_port_map, GFP_KERNEL);
+	if (!str)
+		return;
+
+	/* Handle single mask case */
+	if (!strchr(str, '=')) {
+		ahci_apply_port_map_mask(dev, hpriv, str);
+		goto free;
+	}
+
+	/*
+	 * Mask list case: parse the parameter to apply the mask only if
+	 * the device name matches.
+	 */
+	param = str;
+	end = param + strlen(param);
+	while (param && param < end && *param) {
+		name = param;
+		param = strchr(name, '=');
+		if (!param)
 			break;
-		case 0x1064:
-			dev_info(&pdev->dev, "ASM1064 has only four ports\n");
-			hpriv->saved_port_map = 0xf;
+
+		*param = '\0';
+		param++;
+		if (param >= end)
 			break;
+
+		if (strcmp(dev_name(dev), name) != 0) {
+			param = strchr(param, ',');
+			if (param)
+				param++;
+			continue;
+		}
+
+		mask_s = param;
+		param = strchr(mask_s, ',');
+		if (param) {
+			*param = '\0';
+			param++;
 		}
+
+		ahci_apply_port_map_mask(dev, hpriv, mask_s);
 	}
 
+free:
+	kfree(str);
+}
+
+static void ahci_pci_save_initial_config(struct pci_dev *pdev,
+					 struct ahci_host_priv *hpriv)
+{
 	if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) {
 		dev_info(&pdev->dev, "JMB361 has only one port\n");
 		hpriv->saved_port_map = 1;
@@ -703,6 +770,10 @@
 			  "Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.\n");
 	}
 
+	/* Handle port map masks passed as module parameter. */
+	if (ahci_mask_port_map)
+		ahci_get_port_map_mask(&pdev->dev, hpriv);
+
 	ahci_save_initial_config(&pdev->dev, hpriv);
 }
 
@@ -1660,6 +1731,14 @@
 	if (!(hpriv->flags & AHCI_HFLAG_USE_LPM_POLICY))
 		return;
 
+	/* If no LPM states are supported by the HBA, do not bother with LPM */
+	if ((ap->host->flags & ATA_HOST_NO_PART) &&
+	    (ap->host->flags & ATA_HOST_NO_SSC) &&
+	    (ap->host->flags & ATA_HOST_NO_DEVSLP)) {
+		ata_port_dbg(ap, "no LPM states supported, not enabling LPM\n");
+		return;
+	}
+
 	/* user modified policy via module param */
 	if (mobile_lpm_policy != -1) {
 		policy = mobile_lpm_policy;
@@ -1904,8 +1983,10 @@
 	n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
 
 	host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
-	if (!host)
-		return -ENOMEM;
+	if (!host) {
+		rc = -ENOMEM;
+		goto err_rm_sysfs_file;
+	}
 	host->private_data = hpriv;
 
 	if (ahci_init_msi(pdev, n_ports, hpriv) < 0) {
@@ -1958,11 +2039,11 @@
 	/* initialize adapter */
 	rc = ahci_configure_dma_masks(pdev, hpriv);
 	if (rc)
-		return rc;
+		goto err_rm_sysfs_file;
 
 	rc = ahci_pci_reset_controller(host);
 	if (rc)
-		return rc;
+		goto err_rm_sysfs_file;
 
 	ahci_pci_init_controller(host);
 	ahci_pci_print_info(host);
@@ -1971,10 +2052,15 @@
 
 	rc = ahci_host_activate(host, &ahci_sht);
 	if (rc)
-		return rc;
+		goto err_rm_sysfs_file;
 
 	pm_runtime_put_noidle(&pdev->dev);
 	return 0;
+
+err_rm_sysfs_file:
+	sysfs_remove_file_from_group(&pdev->dev.kobj,
+				     &dev_attr_remapped_nvme.attr, NULL);
+	return rc;
 }
 
 static void ahci_shutdown_one(struct pci_dev *pdev)
--- linux-qcom-6.8.0.orig/drivers/ata/libahci.c
+++ linux-qcom-6.8.0/drivers/ata/libahci.c
@@ -2082,13 +2082,6 @@
 	struct ahci_port_priv *pp = qc->ap->private_data;
 	u8 *rx_fis = pp->rx_fis;
 
-	/*
-	 * rtf may already be filled (e.g. for successful NCQ commands).
-	 * If that is the case, we have nothing to do.
-	 */
-	if (qc->flags & ATA_QCFLAG_RTF_FILLED)
-		return;
-
 	if (pp->fbs_enabled)
 		rx_fis += qc->dev->link->pmp * AHCI_RX_FIS_SZ;
 
@@ -2102,7 +2095,6 @@
 	    !(qc->flags & ATA_QCFLAG_EH)) {
 		ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf);
 		qc->result_tf.status = (rx_fis + RX_FIS_PIO_SETUP)[15];
-		qc->flags |= ATA_QCFLAG_RTF_FILLED;
 		return;
 	}
 
@@ -2125,12 +2117,10 @@
 		 */
 		qc->result_tf.status = fis[2];
 		qc->result_tf.error = fis[3];
-		qc->flags |= ATA_QCFLAG_RTF_FILLED;
 		return;
 	}
 
 	ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf);
-	qc->flags |= ATA_QCFLAG_RTF_FILLED;
 }
 
 static void ahci_qc_ncq_fill_rtf(struct ata_port *ap, u64 done_mask)
@@ -2165,6 +2155,7 @@
 			if (qc && ata_is_ncq(qc->tf.protocol)) {
 				qc->result_tf.status = status;
 				qc->result_tf.error = error;
+				qc->result_tf.flags = qc->tf.flags;
 				qc->flags |= ATA_QCFLAG_RTF_FILLED;
 			}
 			done_mask &= ~(1ULL << tag);
@@ -2189,6 +2180,7 @@
 			fis += RX_FIS_SDB;
 			qc->result_tf.status = fis[2];
 			qc->result_tf.error = fis[3];
+			qc->result_tf.flags = qc->tf.flags;
 			qc->flags |= ATA_QCFLAG_RTF_FILLED;
 		}
 		done_mask &= ~(1ULL << tag);
--- linux-qcom-6.8.0.orig/drivers/ata/libata-core.c
+++ linux-qcom-6.8.0/drivers/ata/libata-core.c
@@ -2539,7 +2539,7 @@
 	bool cdl_enabled;
 	u64 val;
 
-	if (ata_id_major_version(dev->id) < 12)
+	if (ata_id_major_version(dev->id) < 11)
 		goto not_supported;
 
 	if (!ata_log_supported(dev, ATA_LOG_IDENTIFY_DEVICE) ||
@@ -4180,8 +4180,8 @@
 	{ "PIONEER BD-RW   BDR-207M",	NULL,	ATA_HORKAGE_NOLPM },
 	{ "PIONEER BD-RW   BDR-205",	NULL,	ATA_HORKAGE_NOLPM },
 
-	/* Crucial BX100 SSD 500GB has broken LPM support */
-	{ "CT500BX100SSD1",		NULL,	ATA_HORKAGE_NOLPM },
+	/* Crucial devices with broken LPM support */
+	{ "CT*0BX*00SSD1",		NULL,	ATA_HORKAGE_NOLPM },
 
 	/* 512GB MX100 with MU01 firmware has both queued TRIM and LPM issues */
 	{ "Crucial_CT512MX100*",	"MU01",	ATA_HORKAGE_NO_NCQ_TRIM |
@@ -4199,6 +4199,12 @@
 						ATA_HORKAGE_ZERO_AFTER_TRIM |
 						ATA_HORKAGE_NOLPM },
 
+	/* Apacer models with LPM issues */
+	{ "Apacer AS340*",		NULL,	ATA_HORKAGE_NOLPM },
+
+	/* AMD Radeon devices with broken LPM support */
+	{ "R3SL240G",			NULL,	ATA_HORKAGE_NOLPM },
+
 	/* These specific Samsung models/firmware-revs do not handle LPM well */
 	{ "SAMSUNG MZMPC128HBFU-000MV", "CXM14M1Q", ATA_HORKAGE_NOLPM },
 	{ "SAMSUNG SSD PM830 mSATA *",  "CXM13D1Q", ATA_HORKAGE_NOLPM },
@@ -4838,8 +4844,16 @@
 {
 	struct ata_port *ap = qc->ap;
 
+	/*
+	 * rtf may already be filled (e.g. for successful NCQ commands).
+	 * If that is the case, we have nothing to do.
+	 */
+	if (qc->flags & ATA_QCFLAG_RTF_FILLED)
+		return;
+
 	qc->result_tf.flags = qc->tf.flags;
 	ap->ops->qc_fill_rtf(qc);
+	qc->flags |= ATA_QCFLAG_RTF_FILLED;
 }
 
 static void ata_verify_xfer(struct ata_queued_cmd *qc)
@@ -5527,6 +5541,18 @@
 	return ap;
 }
 
+void ata_port_free(struct ata_port *ap)
+{
+	if (!ap)
+		return;
+
+	kfree(ap->pmp_link);
+	kfree(ap->slave_link);
+	kfree(ap->ncq_sense_buf);
+	kfree(ap);
+}
+EXPORT_SYMBOL_GPL(ata_port_free);
+
 static void ata_devres_release(struct device *gendev, void *res)
 {
 	struct ata_host *host = dev_get_drvdata(gendev);
@@ -5553,12 +5579,7 @@
 	int i;
 
 	for (i = 0; i < host->n_ports; i++) {
-		struct ata_port *ap = host->ports[i];
-
-		kfree(ap->pmp_link);
-		kfree(ap->slave_link);
-		kfree(ap->ncq_sense_buf);
-		kfree(ap);
+		ata_port_free(host->ports[i]);
 		host->ports[i] = NULL;
 	}
 	kfree(host);
@@ -5608,12 +5629,16 @@
 	if (!host)
 		return NULL;
 
-	if (!devres_open_group(dev, NULL, GFP_KERNEL))
-		goto err_free;
+	if (!devres_open_group(dev, NULL, GFP_KERNEL)) {
+		kfree(host);
+		return NULL;
+	}
 
 	dr = devres_alloc(ata_devres_release, 0, GFP_KERNEL);
-	if (!dr)
+	if (!dr) {
+		kfree(host);
 		goto err_out;
+	}
 
 	devres_add(dev, dr);
 	dev_set_drvdata(dev, host);
@@ -5641,8 +5666,6 @@
 
  err_out:
 	devres_release_group(dev, NULL);
- err_free:
-	kfree(host);
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(ata_host_alloc);
@@ -5941,7 +5964,7 @@
 	 * allocation time.
 	 */
 	for (i = host->n_ports; host->ports[i]; i++)
-		kfree(host->ports[i]);
+		ata_port_free(host->ports[i]);
 
 	/* give ports names and add SCSI hosts */
 	for (i = 0; i < host->n_ports; i++) {
--- linux-qcom-6.8.0.orig/drivers/ata/libata-eh.c
+++ linux-qcom-6.8.0/drivers/ata/libata-eh.c
@@ -630,6 +630,14 @@
 	list_for_each_entry_safe(scmd, tmp, eh_work_q, eh_entry) {
 		struct ata_queued_cmd *qc;
 
+		/*
+		 * If the scmd was added to EH, via ata_qc_schedule_eh() ->
+		 * scsi_timeout() -> scsi_eh_scmd_add(), scsi_timeout() will
+		 * have set DID_TIME_OUT (since libata does not have an abort
+		 * handler). Thus, to clear DID_TIME_OUT, clear the host byte.
+		 */
+		set_host_byte(scmd, DID_OK);
+
 		ata_qc_for_each_raw(ap, qc, i) {
 			if (qc->flags & ATA_QCFLAG_ACTIVE &&
 			    qc->scsicmd == scmd)
@@ -640,6 +648,7 @@
 			/* the scmd has an associated qc */
 			if (!(qc->flags & ATA_QCFLAG_EH)) {
 				/* which hasn't failed yet, timeout */
+				set_host_byte(scmd, DID_TIME_OUT);
 				qc->err_mask |= AC_ERR_TIMEOUT;
 				qc->flags |= ATA_QCFLAG_EH;
 				nr_timedout++;
@@ -712,8 +721,10 @@
 				ehc->saved_ncq_enabled |= 1 << devno;
 
 			/* If we are resuming, wake up the device */
-			if (ap->pflags & ATA_PFLAG_RESUMING)
+			if (ap->pflags & ATA_PFLAG_RESUMING) {
+				dev->flags |= ATA_DFLAG_RESUMING;
 				ehc->i.dev_action[devno] |= ATA_EH_SET_ACTIVE;
+			}
 		}
 	}
 
@@ -3169,6 +3180,7 @@
 	return 0;
 
  err:
+	dev->flags &= ~ATA_DFLAG_RESUMING;
 	*r_failed_dev = dev;
 	return rc;
 }
@@ -4048,10 +4060,20 @@
 
 	WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED);
 
-	/* Set all devices attached to the port in standby mode */
-	ata_for_each_link(link, ap, HOST_FIRST) {
-		ata_for_each_dev(dev, link, ENABLED)
-			ata_dev_power_set_standby(dev);
+	/*
+	 * We will reach this point for all of the PM events:
+	 * PM_EVENT_SUSPEND (if runtime pm, PM_EVENT_AUTO will also be set)
+	 * PM_EVENT_FREEZE, and PM_EVENT_HIBERNATE.
+	 *
+	 * We do not want to perform disk spin down for PM_EVENT_FREEZE.
+	 * (Spin down will be performed by the subsequent PM_EVENT_HIBERNATE.)
+	 */
+	if (!(ap->pm_mesg.event & PM_EVENT_FREEZE)) {
+		/* Set all devices attached to the port in standby mode */
+		ata_for_each_link(link, ap, HOST_FIRST) {
+			ata_for_each_dev(dev, link, ENABLED)
+				ata_dev_power_set_standby(dev);
+		}
 	}
 
 	/*
--- linux-qcom-6.8.0.orig/drivers/ata/libata-scsi.c
+++ linux-qcom-6.8.0/drivers/ata/libata-scsi.c
@@ -230,6 +230,87 @@
 				   SCSI_SENSE_BUFFERSIZE, information);
 }
 
+/**
+ *	ata_scsi_set_passthru_sense_fields - Set ATA fields in sense buffer
+ *	@qc: ATA PASS-THROUGH command.
+ *
+ *	Populates "ATA Status Return sense data descriptor" / "Fixed format
+ *	sense data" with ATA taskfile fields.
+ *
+ *	LOCKING:
+ *	None.
+ */
+static void ata_scsi_set_passthru_sense_fields(struct ata_queued_cmd *qc)
+{
+	struct ata_device *dev = qc->dev;
+	struct scsi_cmnd *cmd = qc->scsicmd;
+	struct ata_taskfile *tf = &qc->result_tf;
+	unsigned char *sb = cmd->sense_buffer;
+
+	if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) {
+		ata_dev_dbg(dev,
+			    "missing result TF: can't set ATA PT sense fields\n");
+		return;
+	}
+
+	if ((sb[0] & 0x7f) >= 0x72) {
+		unsigned char *desc;
+		u8 len;
+
+		/* descriptor format */
+		len = sb[7];
+		desc = (char *)scsi_sense_desc_find(sb, len + 8, 9);
+		if (!desc) {
+			if (SCSI_SENSE_BUFFERSIZE < len + 14)
+				return;
+			sb[7] = len + 14;
+			desc = sb + 8 + len;
+		}
+		desc[0] = 9;
+		desc[1] = 12;
+		/*
+		 * Copy registers into sense buffer.
+		 */
+		desc[2] = 0x00;
+		desc[3] = tf->error;
+		desc[5] = tf->nsect;
+		desc[7] = tf->lbal;
+		desc[9] = tf->lbam;
+		desc[11] = tf->lbah;
+		desc[12] = tf->device;
+		desc[13] = tf->status;
+
+		/*
+		 * Fill in Extend bit, and the high order bytes
+		 * if applicable.
+		 */
+		if (tf->flags & ATA_TFLAG_LBA48) {
+			desc[2] |= 0x01;
+			desc[4] = tf->hob_nsect;
+			desc[6] = tf->hob_lbal;
+			desc[8] = tf->hob_lbam;
+			desc[10] = tf->hob_lbah;
+		}
+	} else {
+		/* Fixed sense format */
+		sb[0] |= 0x80;
+		sb[3] = tf->error;
+		sb[4] = tf->status;
+		sb[5] = tf->device;
+		sb[6] = tf->nsect;
+		if (tf->flags & ATA_TFLAG_LBA48)  {
+			sb[8] |= 0x80;
+			if (tf->hob_nsect)
+				sb[8] |= 0x40;
+			if (tf->hob_lbal || tf->hob_lbam || tf->hob_lbah)
+				sb[8] |= 0x20;
+		}
+		sb[9] = tf->lbal;
+		sb[10] = tf->lbam;
+		sb[11] = tf->lbah;
+	}
+}
+
 static void ata_scsi_set_invalid_field(struct ata_device *dev,
 				       struct scsi_cmnd *cmd, u16 field, u8 bit)
 {
@@ -837,10 +918,8 @@
  *	ata_gen_passthru_sense - Generate check condition sense block.
  *	@qc: Command that completed.
  *
- *	This function is specific to the ATA descriptor format sense
- *	block specified for the ATA pass through commands.  Regardless
- *	of whether the command errored or not, return a sense
- *	block. Copy all controller registers into the sense
+ *	This function is specific to the ATA pass through commands.
+ *	Regardless of whether the command errored or not, return a sense
  *	block. If there was no error, we get the request from an ATA
  *	passthrough command, so we use the following sense data:
  *	sk = RECOVERED ERROR
@@ -852,13 +931,16 @@
  */
 static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
 {
+	struct ata_device *dev = qc->dev;
 	struct scsi_cmnd *cmd = qc->scsicmd;
 	struct ata_taskfile *tf = &qc->result_tf;
-	unsigned char *sb = cmd->sense_buffer;
-	unsigned char *desc = sb + 8;
 	u8 sense_key, asc, ascq;
 
-	memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
+	if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) {
+		ata_dev_dbg(dev,
+			    "missing result TF: can't generate ATA PT sense data\n");
+		return;
+	}
 
 	/*
 	 * Use ata_to_sense_error() to map status register bits
@@ -876,62 +958,6 @@
 		 */
 		scsi_build_sense(cmd, 1, RECOVERED_ERROR, 0, 0x1D);
 	}
-
-	if ((cmd->sense_buffer[0] & 0x7f) >= 0x72) {
-		u8 len;
-
-		/* descriptor format */
-		len = sb[7];
-		desc = (char *)scsi_sense_desc_find(sb, len + 8, 9);
-		if (!desc) {
-			if (SCSI_SENSE_BUFFERSIZE < len + 14)
-				return;
-			sb[7] = len + 14;
-			desc = sb + 8 + len;
-		}
-		desc[0] = 9;
-		desc[1] = 12;
-		/*
-		 * Copy registers into sense buffer.
-		 */
-		desc[2] = 0x00;
-		desc[3] = tf->error;
-		desc[5] = tf->nsect;
-		desc[7] = tf->lbal;
-		desc[9] = tf->lbam;
-		desc[11] = tf->lbah;
-		desc[12] = tf->device;
-		desc[13] = tf->status;
-
-		/*
-		 * Fill in Extend bit, and the high order bytes
-		 * if applicable.
-		 */
-		if (tf->flags & ATA_TFLAG_LBA48) {
-			desc[2] |= 0x01;
-			desc[4] = tf->hob_nsect;
-			desc[6] = tf->hob_lbal;
-			desc[8] = tf->hob_lbam;
-			desc[10] = tf->hob_lbah;
-		}
-	} else {
-		/* Fixed sense format */
-		desc[0] = tf->error;
-		desc[1] = tf->status;
-		desc[2] = tf->device;
-		desc[3] = tf->nsect;
-		desc[7] = 0;
-		if (tf->flags & ATA_TFLAG_LBA48)  {
-			desc[8] |= 0x80;
-			if (tf->hob_nsect)
-				desc[8] |= 0x40;
-			if (tf->hob_lbal || tf->hob_lbam || tf->hob_lbah)
-				desc[8] |= 0x20;
-		}
-		desc[9] = tf->lbal;
-		desc[10] = tf->lbam;
-		desc[11] = tf->lbah;
-	}
 }
 
 /**
@@ -953,14 +979,19 @@
 	u64 block;
 	u8 sense_key, asc, ascq;
 
-	memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
-
 	if (ata_dev_disabled(dev)) {
 		/* Device disabled after error recovery */
 		/* LOGICAL UNIT NOT READY, HARD RESET REQUIRED */
 		ata_scsi_set_sense(dev, cmd, NOT_READY, 0x04, 0x21);
 		return;
 	}
+
+	if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) {
+		ata_dev_dbg(dev,
+			    "missing result TF: can't generate sense data\n");
+		return;
+	}
+
 	/* Use ata_to_sense_error() to map status register bits
 	 * onto sense key, asc & ascq.
 	 */
@@ -1629,26 +1660,29 @@
 {
 	struct scsi_cmnd *cmd = qc->scsicmd;
 	u8 *cdb = cmd->cmnd;
-	int need_sense = (qc->err_mask != 0) &&
-		!(qc->flags & ATA_QCFLAG_SENSE_VALID);
+	bool have_sense = qc->flags & ATA_QCFLAG_SENSE_VALID;
+	bool is_ata_passthru = cdb[0] == ATA_16 || cdb[0] == ATA_12;
+	bool is_ck_cond_request = cdb[2] & 0x20;
+	bool is_error = qc->err_mask != 0;
 
 	/* For ATA pass thru (SAT) commands, generate a sense block if
 	 * user mandated it or if there's an error.  Note that if we
-	 * generate because the user forced us to [CK_COND =1], a check
+	 * generate because the user forced us to [CK_COND=1], a check
 	 * condition is generated and the ATA register values are returned
 	 * whether the command completed successfully or not. If there
-	 * was no error, we use the following sense data:
+	 * was no error, and CK_COND=1, we use the following sense data:
 	 * sk = RECOVERED ERROR
 	 * asc,ascq = ATA PASS-THROUGH INFORMATION AVAILABLE
 	 */
-	if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
-	    ((cdb[2] & 0x20) || need_sense))
-		ata_gen_passthru_sense(qc);
-	else if (need_sense)
+	if (is_ata_passthru && (is_ck_cond_request || is_error || have_sense)) {
+		if (!have_sense)
+			ata_gen_passthru_sense(qc);
+		ata_scsi_set_passthru_sense_fields(qc);
+		if (is_ck_cond_request)
+			set_status_byte(qc->scsicmd, SAM_STAT_CHECK_CONDITION);
+	} else if (is_error && !have_sense) {
 		ata_gen_ata_sense(qc);
-	else
-		/* Keep the SCSI ML and status byte, clear host byte. */
-		cmd->result &= 0x0000ffff;
+	}
 
 	ata_qc_done(qc);
 }
@@ -1828,11 +1862,11 @@
 		2
 	};
 
-	/* set scsi removable (RMB) bit per ata bit, or if the
-	 * AHCI port says it's external (Hotplug-capable, eSATA).
+	/*
+	 * Set the SCSI Removable Media Bit (RMB) if the ATA removable media
+	 * device bit (obsolete since ATA-8 ACS) is set.
 	 */
-	if (ata_id_removable(args->id) ||
-	    (args->dev->link->ap->pflags & ATA_PFLAG_EXTERNAL))
+	if (ata_id_removable(args->id))
 		hdr[1] |= (1 << 7);
 
 	if (args->dev->class == ATA_DEV_ZAC) {
@@ -2313,7 +2347,7 @@
 	case ALL_SUB_MPAGES:
 		n = ata_msense_control_spg0(dev, buf, changeable);
 		n += ata_msense_control_spgt2(dev, buf + n, CDL_T2A_SUB_MPAGE);
-		n += ata_msense_control_spgt2(dev, buf + n, CDL_T2A_SUB_MPAGE);
+		n += ata_msense_control_spgt2(dev, buf + n, CDL_T2B_SUB_MPAGE);
 		n += ata_msense_control_ata_feature(dev, buf + n);
 		return n;
 	default:
@@ -2587,14 +2621,8 @@
 	/* handle completion from EH */
 	if (unlikely(err_mask || qc->flags & ATA_QCFLAG_SENSE_VALID)) {
 
-		if (!(qc->flags & ATA_QCFLAG_SENSE_VALID)) {
-			/* FIXME: not quite right; we don't want the
-			 * translation of taskfile registers into a
-			 * sense descriptors, since that's only
-			 * correct for ATA, not ATAPI
-			 */
+		if (!(qc->flags & ATA_QCFLAG_SENSE_VALID))
 			ata_gen_passthru_sense(qc);
-		}
 
 		/* SCSI EH automatically locks door if sdev->locked is
 		 * set.  Sometimes door lock request continues to
@@ -4730,6 +4758,7 @@
 	struct ata_link *link;
 	struct ata_device *dev;
 	unsigned long flags;
+	bool do_resume;
 	int ret = 0;
 
 	mutex_lock(&ap->scsi_scan_mutex);
@@ -4744,25 +4773,34 @@
 			 * bail out.
 			 */
 			if (ap->pflags & ATA_PFLAG_SUSPENDED)
-				goto unlock;
+				goto unlock_ap;
 
 			if (!sdev)
 				continue;
 			if (scsi_device_get(sdev))
 				continue;
 
+			do_resume = dev->flags & ATA_DFLAG_RESUMING;
+
 			spin_unlock_irqrestore(ap->lock, flags);
+			if (do_resume) {
+				ret = scsi_resume_device(sdev);
+				if (ret == -EWOULDBLOCK)
+					goto unlock_scan;
+				dev->flags &= ~ATA_DFLAG_RESUMING;
+			}
 			ret = scsi_rescan_device(sdev);
 			scsi_device_put(sdev);
 			spin_lock_irqsave(ap->lock, flags);
 
 			if (ret)
-				goto unlock;
+				goto unlock_ap;
 		}
 	}
 
-unlock:
+unlock_ap:
 	spin_unlock_irqrestore(ap->lock, flags);
+unlock_scan:
 	mutex_unlock(&ap->scsi_scan_mutex);
 
 	/* Reschedule with a delay if scsi_rescan_device() returned an error */
--- linux-qcom-6.8.0.orig/drivers/ata/libata-sff.c
+++ linux-qcom-6.8.0/drivers/ata/libata-sff.c
@@ -602,7 +602,7 @@
 {
 	struct ata_port *ap = qc->ap;
 	struct page *page;
-	unsigned int offset;
+	unsigned int offset, count;
 
 	if (!qc->cursg) {
 		qc->curbytes = qc->nbytes;
@@ -618,25 +618,27 @@
 	page = nth_page(page, (offset >> PAGE_SHIFT));
 	offset %= PAGE_SIZE;
 
-	trace_ata_sff_pio_transfer_data(qc, offset, qc->sect_size);
+	/* don't overrun current sg */
+	count = min(qc->cursg->length - qc->cursg_ofs, qc->sect_size);
+
+	trace_ata_sff_pio_transfer_data(qc, offset, count);
 
 	/*
 	 * Split the transfer when it splits a page boundary.  Note that the
 	 * split still has to be dword aligned like all ATA data transfers.
 	 */
 	WARN_ON_ONCE(offset % 4);
-	if (offset + qc->sect_size > PAGE_SIZE) {
+	if (offset + count > PAGE_SIZE) {
 		unsigned int split_len = PAGE_SIZE - offset;
 
 		ata_pio_xfer(qc, page, offset, split_len);
-		ata_pio_xfer(qc, nth_page(page, 1), 0,
-			     qc->sect_size - split_len);
+		ata_pio_xfer(qc, nth_page(page, 1), 0, count - split_len);
 	} else {
-		ata_pio_xfer(qc, page, offset, qc->sect_size);
+		ata_pio_xfer(qc, page, offset, count);
 	}
 
-	qc->curbytes += qc->sect_size;
-	qc->cursg_ofs += qc->sect_size;
+	qc->curbytes += count;
+	qc->cursg_ofs += count;
 
 	if (qc->cursg_ofs == qc->cursg->length) {
 		qc->cursg = sg_next(qc->cursg);
--- linux-qcom-6.8.0.orig/drivers/ata/pata_legacy.c
+++ linux-qcom-6.8.0/drivers/ata/pata_legacy.c
@@ -173,8 +173,6 @@
 static struct legacy_probe probe_list[NR_HOST];
 static struct legacy_data legacy_data[NR_HOST];
 static struct ata_host *legacy_host[NR_HOST];
-static int nr_legacy_host;
-
 
 /**
  *	legacy_probe_add	-	Add interface to probe list
@@ -1276,9 +1274,11 @@
 {
 	int i;
 
-	for (i = 0; i < nr_legacy_host; i++) {
+	for (i = 0; i < NR_HOST; i++) {
 		struct legacy_data *ld = &legacy_data[i];
-		ata_host_detach(legacy_host[i]);
+
+		if (legacy_host[i])
+			ata_host_detach(legacy_host[i]);
 		platform_device_unregister(ld->platform_dev);
 	}
 }
--- linux-qcom-6.8.0.orig/drivers/ata/pata_macio.c
+++ linux-qcom-6.8.0/drivers/ata/pata_macio.c
@@ -541,7 +541,8 @@
 
 		while (sg_len) {
 			/* table overflow should never happen */
-			BUG_ON (pi++ >= MAX_DCMDS);
+			if (WARN_ON_ONCE(pi >= MAX_DCMDS))
+				return AC_ERR_SYSTEM;
 
 			len = (sg_len < MAX_DBDMA_SEG) ? sg_len : MAX_DBDMA_SEG;
 			table->command = cpu_to_le16(write ? OUTPUT_MORE: INPUT_MORE);
@@ -553,11 +554,13 @@
 			addr += len;
 			sg_len -= len;
 			++table;
+			++pi;
 		}
 	}
 
 	/* Should never happen according to Tejun */
-	BUG_ON(!pi);
+	if (WARN_ON_ONCE(!pi))
+		return AC_ERR_SYSTEM;
 
 	/* Convert the last command to an input/output */
 	table--;
--- linux-qcom-6.8.0.orig/drivers/ata/pata_serverworks.c
+++ linux-qcom-6.8.0/drivers/ata/pata_serverworks.c
@@ -46,10 +46,11 @@
 #define SVWKS_CSB5_REVISION_NEW	0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
 #define SVWKS_CSB6_REVISION	0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
 
-/* Seagate Barracuda ATA IV Family drives in UDMA mode 5
- * can overrun their FIFOs when used with the CSB5 */
-
-static const char *csb_bad_ata100[] = {
+/*
+ * Seagate Barracuda ATA IV Family drives in UDMA mode 5
+ * can overrun their FIFOs when used with the CSB5.
+ */
+static const char * const csb_bad_ata100[] = {
 	"ST320011A",
 	"ST340016A",
 	"ST360021A",
@@ -163,10 +164,11 @@
  *	@adev: ATA device
  *	@mask: Mask of proposed modes
  *
- *	Check the blacklist and disable UDMA5 if matched
+ *	Check the list of devices with broken UDMA5 and
+ *	disable UDMA5 if matched.
  */
-
-static unsigned int serverworks_csb_filter(struct ata_device *adev, unsigned int mask)
+static unsigned int serverworks_csb_filter(struct ata_device *adev,
+					   unsigned int mask)
 {
 	const char *p;
 	char model_num[ATA_ID_PROD_LEN + 1];
--- linux-qcom-6.8.0.orig/drivers/ata/sata_gemini.c
+++ linux-qcom-6.8.0/drivers/ata/sata_gemini.c
@@ -200,7 +200,10 @@
 		pclk = sg->sata0_pclk;
 	else
 		pclk = sg->sata1_pclk;
-	clk_enable(pclk);
+	ret = clk_enable(pclk);
+	if (ret)
+		return ret;
+
 	msleep(10);
 
 	/* Do not keep clocking a bridge that is not online */
--- linux-qcom-6.8.0.orig/drivers/ata/sata_highbank.c
+++ linux-qcom-6.8.0/drivers/ata/sata_highbank.c
@@ -348,6 +348,7 @@
 			phy_nodes[phy] = phy_data.np;
 			cphy_base[phy] = of_iomap(phy_nodes[phy], 0);
 			if (cphy_base[phy] == NULL) {
+				of_node_put(phy_data.np);
 				return 0;
 			}
 			phy_count += 1;
--- linux-qcom-6.8.0.orig/drivers/ata/sata_mv.c
+++ linux-qcom-6.8.0/drivers/ata/sata_mv.c
@@ -787,37 +787,6 @@
 	},
 };
 
-static const struct pci_device_id mv_pci_tbl[] = {
-	{ PCI_VDEVICE(MARVELL, 0x5040), chip_504x },
-	{ PCI_VDEVICE(MARVELL, 0x5041), chip_504x },
-	{ PCI_VDEVICE(MARVELL, 0x5080), chip_5080 },
-	{ PCI_VDEVICE(MARVELL, 0x5081), chip_508x },
-	/* RocketRAID 1720/174x have different identifiers */
-	{ PCI_VDEVICE(TTI, 0x1720), chip_6042 },
-	{ PCI_VDEVICE(TTI, 0x1740), chip_6042 },
-	{ PCI_VDEVICE(TTI, 0x1742), chip_6042 },
-
-	{ PCI_VDEVICE(MARVELL, 0x6040), chip_604x },
-	{ PCI_VDEVICE(MARVELL, 0x6041), chip_604x },
-	{ PCI_VDEVICE(MARVELL, 0x6042), chip_6042 },
-	{ PCI_VDEVICE(MARVELL, 0x6080), chip_608x },
-	{ PCI_VDEVICE(MARVELL, 0x6081), chip_608x },
-
-	{ PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x },
-
-	/* Adaptec 1430SA */
-	{ PCI_VDEVICE(ADAPTEC2, 0x0243), chip_7042 },
-
-	/* Marvell 7042 support */
-	{ PCI_VDEVICE(MARVELL, 0x7042), chip_7042 },
-
-	/* Highpoint RocketRAID PCIe series */
-	{ PCI_VDEVICE(TTI, 0x2300), chip_7042 },
-	{ PCI_VDEVICE(TTI, 0x2310), chip_7042 },
-
-	{ }			/* terminate list */
-};
-
 static const struct mv_hw_ops mv5xxx_ops = {
 	.phy_errata		= mv5_phy_errata,
 	.enable_leds		= mv5_enable_leds,
@@ -4303,6 +4272,36 @@
 static int mv_pci_device_resume(struct pci_dev *pdev);
 #endif
 
+static const struct pci_device_id mv_pci_tbl[] = {
+	{ PCI_VDEVICE(MARVELL, 0x5040), chip_504x },
+	{ PCI_VDEVICE(MARVELL, 0x5041), chip_504x },
+	{ PCI_VDEVICE(MARVELL, 0x5080), chip_5080 },
+	{ PCI_VDEVICE(MARVELL, 0x5081), chip_508x },
+	/* RocketRAID 1720/174x have different identifiers */
+	{ PCI_VDEVICE(TTI, 0x1720), chip_6042 },
+	{ PCI_VDEVICE(TTI, 0x1740), chip_6042 },
+	{ PCI_VDEVICE(TTI, 0x1742), chip_6042 },
+
+	{ PCI_VDEVICE(MARVELL, 0x6040), chip_604x },
+	{ PCI_VDEVICE(MARVELL, 0x6041), chip_604x },
+	{ PCI_VDEVICE(MARVELL, 0x6042), chip_6042 },
+	{ PCI_VDEVICE(MARVELL, 0x6080), chip_608x },
+	{ PCI_VDEVICE(MARVELL, 0x6081), chip_608x },
+
+	{ PCI_VDEVICE(ADAPTEC2, 0x0241), chip_604x },
+
+	/* Adaptec 1430SA */
+	{ PCI_VDEVICE(ADAPTEC2, 0x0243), chip_7042 },
+
+	/* Marvell 7042 support */
+	{ PCI_VDEVICE(MARVELL, 0x7042), chip_7042 },
+
+	/* Highpoint RocketRAID PCIe series */
+	{ PCI_VDEVICE(TTI, 0x2300), chip_7042 },
+	{ PCI_VDEVICE(TTI, 0x2310), chip_7042 },
+
+	{ }			/* terminate list */
+};
 
 static struct pci_driver mv_pci_driver = {
 	.name			= DRV_NAME,
@@ -4315,6 +4314,7 @@
 #endif
 
 };
+MODULE_DEVICE_TABLE(pci, mv_pci_tbl);
 
 /**
  *      mv_print_info - Dump key info to kernel log for perusal.
@@ -4487,7 +4487,6 @@
 MODULE_AUTHOR("Brett Russ");
 MODULE_DESCRIPTION("SCSI low-level driver for Marvell SATA controllers");
 MODULE_LICENSE("GPL v2");
-MODULE_DEVICE_TABLE(pci, mv_pci_tbl);
 MODULE_VERSION(DRV_VERSION);
 MODULE_ALIAS("platform:" DRV_NAME);
 
--- linux-qcom-6.8.0.orig/drivers/ata/sata_sil.c
+++ linux-qcom-6.8.0/drivers/ata/sata_sil.c
@@ -128,7 +128,7 @@
 static const struct sil_drivelist {
 	const char *product;
 	unsigned int quirk;
-} sil_blacklist [] = {
+} sil_quirks[] = {
 	{ "ST320012AS",		SIL_QUIRK_MOD15WRITE },
 	{ "ST330013AS",		SIL_QUIRK_MOD15WRITE },
 	{ "ST340017AS",		SIL_QUIRK_MOD15WRITE },
@@ -600,8 +600,8 @@
  *	list, and apply the fixups to only the specific
  *	devices/hosts/firmwares that need it.
  *
- *	20040111 - Seagate drives affected by the Mod15Write bug are blacklisted
- *	The Maxtor quirk is in the blacklist, but I'm keeping the original
+ *	20040111 - Seagate drives affected by the Mod15Write bug are quirked
+ *	The Maxtor quirk is in sil_quirks, but I'm keeping the original
  *	pessimistic fix for the following reasons...
  *	- There seems to be less info on it, only one device gleaned off the
  *	Windows	driver, maybe only one is affected.  More info would be greatly
@@ -620,9 +620,9 @@
 
 	ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
 
-	for (n = 0; sil_blacklist[n].product; n++)
-		if (!strcmp(sil_blacklist[n].product, model_num)) {
-			quirks = sil_blacklist[n].quirk;
+	for (n = 0; sil_quirks[n].product; n++)
+		if (!strcmp(sil_quirks[n].product, model_num)) {
+			quirks = sil_quirks[n].quirk;
 			break;
 		}
 
--- linux-qcom-6.8.0.orig/drivers/ata/sata_sx4.c
+++ linux-qcom-6.8.0/drivers/ata/sata_sx4.c
@@ -957,8 +957,7 @@
 
 	offset -= (idx * window_size);
 	idx++;
-	dist = ((long) (window_size - (offset + size))) >= 0 ? size :
-		(long) (window_size - offset);
+	dist = min(size, window_size - offset);
 	memcpy_fromio(psource, dimm_mmio + offset / 4, dist);
 
 	psource += dist;
@@ -1005,8 +1004,7 @@
 	readl(mmio + PDC_DIMM_WINDOW_CTLR);
 	offset -= (idx * window_size);
 	idx++;
-	dist = ((long)(s32)(window_size - (offset + size))) >= 0 ? size :
-		(long) (window_size - offset);
+	dist = min(size, window_size - offset);
 	memcpy_toio(dimm_mmio + offset / 4, psource, dist);
 	writel(0x01, mmio + PDC_GENERAL_CTLR);
 	readl(mmio + PDC_GENERAL_CTLR);
--- linux-qcom-6.8.0.orig/drivers/atm/idt77252.c
+++ linux-qcom-6.8.0/drivers/atm/idt77252.c
@@ -1118,8 +1118,8 @@
 	rpp->len += skb->len;
 
 	if (stat & SAR_RSQE_EPDU) {
+		unsigned int len, truesize;
 		unsigned char *l1l2;
-		unsigned int len;
 
 		l1l2 = (unsigned char *) ((unsigned long) skb->data + skb->len - 6);
 
@@ -1189,14 +1189,15 @@
 		ATM_SKB(skb)->vcc = vcc;
 		__net_timestamp(skb);
 
+		truesize = skb->truesize;
 		vcc->push(vcc, skb);
 		atomic_inc(&vcc->stats->rx);
 
-		if (skb->truesize > SAR_FB_SIZE_3)
+		if (truesize > SAR_FB_SIZE_3)
 			add_rx_skb(card, 3, SAR_FB_SIZE_3, 1);
-		else if (skb->truesize > SAR_FB_SIZE_2)
+		else if (truesize > SAR_FB_SIZE_2)
 			add_rx_skb(card, 2, SAR_FB_SIZE_2, 1);
-		else if (skb->truesize > SAR_FB_SIZE_1)
+		else if (truesize > SAR_FB_SIZE_1)
 			add_rx_skb(card, 1, SAR_FB_SIZE_1, 1);
 		else
 			add_rx_skb(card, 0, SAR_FB_SIZE_0, 1);
--- linux-qcom-6.8.0.orig/drivers/auxdisplay/ht16k33.c
+++ linux-qcom-6.8.0/drivers/auxdisplay/ht16k33.c
@@ -506,6 +506,7 @@
 	led->max_brightness = MAX_BRIGHTNESS;
 
 	err = devm_led_classdev_register_ext(dev, led, &init_data);
+	fwnode_handle_put(init_data.fwnode);
 	if (err)
 		dev_err(dev, "Failed to register LED\n");
 
--- linux-qcom-6.8.0.orig/drivers/base/base.h
+++ linux-qcom-6.8.0/drivers/base/base.h
@@ -192,11 +192,14 @@
 void devices_kset_move_last(struct device *dev);
 
 #if defined(CONFIG_MODULES) && defined(CONFIG_SYSFS)
-void module_add_driver(struct module *mod, struct device_driver *drv);
+int module_add_driver(struct module *mod, struct device_driver *drv);
 void module_remove_driver(struct device_driver *drv);
 #else
-static inline void module_add_driver(struct module *mod,
-				     struct device_driver *drv) { }
+static inline int module_add_driver(struct module *mod,
+				    struct device_driver *drv)
+{
+	return 0;
+}
 static inline void module_remove_driver(struct device_driver *drv) { }
 #endif
 
--- linux-qcom-6.8.0.orig/drivers/base/bus.c
+++ linux-qcom-6.8.0/drivers/base/bus.c
@@ -152,7 +152,8 @@
 {
 	struct bus_attribute *bus_attr = to_bus_attr(attr);
 	struct subsys_private *subsys_priv = to_subsys_private(kobj);
-	ssize_t ret = 0;
+	/* return -EIO for reading a bus attribute without show() */
+	ssize_t ret = -EIO;
 
 	if (bus_attr->show)
 		ret = bus_attr->show(subsys_priv->bus, buf);
@@ -164,7 +165,8 @@
 {
 	struct bus_attribute *bus_attr = to_bus_attr(attr);
 	struct subsys_private *subsys_priv = to_subsys_private(kobj);
-	ssize_t ret = 0;
+	/* return -EIO for writing a bus attribute without store() */
+	ssize_t ret = -EIO;
 
 	if (bus_attr->store)
 		ret = bus_attr->store(subsys_priv->bus, buf, count);
@@ -674,7 +676,12 @@
 		if (error)
 			goto out_del_list;
 	}
-	module_add_driver(drv->owner, drv);
+	error = module_add_driver(drv->owner, drv);
+	if (error) {
+		printk(KERN_ERR "%s: failed to create module links for %s\n",
+			__func__, drv->name);
+		goto out_detach;
+	}
 
 	error = driver_create_file(drv, &driver_attr_uevent);
 	if (error) {
@@ -699,6 +706,8 @@
 
 	return 0;
 
+out_detach:
+	driver_detach(drv);
 out_del_list:
 	klist_del(&priv->knode_bus);
 out_unregister:
@@ -913,6 +922,8 @@
 	bus_remove_file(bus, &bus_attr_uevent);
 bus_uevent_fail:
 	kset_unregister(&priv->subsys);
+	/* Above kset_unregister() will kfree @priv */
+	priv = NULL;
 out:
 	kfree(priv);
 	return retval;
--- linux-qcom-6.8.0.orig/drivers/base/cacheinfo.c
+++ linux-qcom-6.8.0/drivers/base/cacheinfo.c
@@ -61,6 +61,9 @@
 	if (!cache_leaves(cpu))
 		return false;
 
+	if (!per_cpu_cacheinfo(cpu))
+		return false;
+
 	llc = per_cpu_cacheinfo_idx(cpu, cache_leaves(cpu) - 1);
 
 	return (llc->attributes & CACHE_ID) || !!llc->fw_token;
@@ -554,7 +557,11 @@
 	 */
 	ci_cacheinfo(cpu)->early_ci_levels = false;
 
-	if (cache_leaves(cpu) <= early_leaves)
+	/*
+	 * Some architectures (e.g., x86) do not use early initialization.
+	 * Allocate memory now in such case.
+	 */
+	if (cache_leaves(cpu) <= early_leaves && per_cpu_cacheinfo(cpu))
 		return 0;
 
 	kfree(per_cpu_cacheinfo(cpu));
--- linux-qcom-6.8.0.orig/drivers/base/class.c
+++ linux-qcom-6.8.0/drivers/base/class.c
@@ -312,8 +312,12 @@
 	struct subsys_private *sp = class_to_subsys(class);
 	struct klist_node *start_knode = NULL;
 
-	if (!sp)
+	memset(iter, 0, sizeof(*iter));
+	if (!sp) {
+		pr_crit("%s: class %p was not registered yet\n",
+			__func__, class);
 		return;
+	}
 
 	if (start)
 		start_knode = &start->p->knode_class;
@@ -340,6 +344,9 @@
 	struct klist_node *knode;
 	struct device *dev;
 
+	if (!iter->sp)
+		return NULL;
+
 	while (1) {
 		knode = klist_next(&iter->ki);
 		if (!knode)
--- linux-qcom-6.8.0.orig/drivers/base/core.c
+++ linux-qcom-6.8.0/drivers/base/core.c
@@ -44,6 +44,7 @@
 static void __fw_devlink_link_to_consumers(struct device *dev);
 static bool fw_devlink_drv_reg_done;
 static bool fw_devlink_best_effort;
+static struct workqueue_struct *device_link_wq;
 
 /**
  * __fwnode_link_add - Create a link between two fwnode_handles.
@@ -532,12 +533,26 @@
 	/*
 	 * It may take a while to complete this work because of the SRCU
 	 * synchronization in device_link_release_fn() and if the consumer or
-	 * supplier devices get deleted when it runs, so put it into the "long"
-	 * workqueue.
+	 * supplier devices get deleted when it runs, so put it into the
+	 * dedicated workqueue.
 	 */
-	queue_work(system_long_wq, &link->rm_work);
+	queue_work(device_link_wq, &link->rm_work);
 }
 
+/**
+ * device_link_wait_removal - Wait for ongoing devlink removal jobs to terminate
+ */
+void device_link_wait_removal(void)
+{
+	/*
+	 * devlink removal jobs are queued in the dedicated work queue.
+	 * To be sure that all removal jobs are terminated, ensure that any
+	 * scheduled work has run to completion.
+	 */
+	flush_workqueue(device_link_wq);
+}
+EXPORT_SYMBOL_GPL(device_link_wait_removal);
+
 static struct class devlink_class = {
 	.name = "devlink",
 	.dev_groups = devlink_groups,
@@ -1011,7 +1026,8 @@
 		return NULL;
 
 	list_for_each_entry(link, &fwnode->suppliers, c_hook)
-		if (!(link->flags & FWLINK_FLAG_CYCLE))
+		if (!(link->flags &
+		      (FWLINK_FLAG_CYCLE | FWLINK_FLAG_IGNORE)))
 			return link->supplier;
 
 	return NULL;
@@ -1921,10 +1937,10 @@
  *
  * Return true if one or more cycles were found. Otherwise, return false.
  */
-static bool __fw_devlink_relax_cycles(struct device *con,
+static bool __fw_devlink_relax_cycles(struct fwnode_handle *con_handle,
 				 struct fwnode_handle *sup_handle)
 {
-	struct device *sup_dev = NULL, *par_dev = NULL;
+	struct device *sup_dev = NULL, *par_dev = NULL, *con_dev = NULL;
 	struct fwnode_link *link;
 	struct device_link *dev_link;
 	bool ret = false;
@@ -1941,28 +1957,31 @@
 
 	sup_handle->flags |= FWNODE_FLAG_VISITED;
 
-	sup_dev = get_dev_from_fwnode(sup_handle);
-
 	/* Termination condition. */
-	if (sup_dev == con) {
+	if (sup_handle == con_handle) {
 		pr_debug("----- cycle: start -----\n");
 		ret = true;
 		goto out;
 	}
 
+	sup_dev = get_dev_from_fwnode(sup_handle);
+	con_dev = get_dev_from_fwnode(con_handle);
 	/*
 	 * If sup_dev is bound to a driver and @con hasn't started binding to a
 	 * driver, sup_dev can't be a consumer of @con. So, no need to check
 	 * further.
 	 */
 	if (sup_dev && sup_dev->links.status ==  DL_DEV_DRIVER_BOUND &&
-	    con->links.status == DL_DEV_NO_DRIVER) {
+	    con_dev && con_dev->links.status == DL_DEV_NO_DRIVER) {
 		ret = false;
 		goto out;
 	}
 
 	list_for_each_entry(link, &sup_handle->suppliers, c_hook) {
-		if (__fw_devlink_relax_cycles(con, link->supplier)) {
+		if (link->flags & FWLINK_FLAG_IGNORE)
+			continue;
+
+		if (__fw_devlink_relax_cycles(con_handle, link->supplier)) {
 			__fwnode_link_cycle(link);
 			ret = true;
 		}
@@ -1977,7 +1996,7 @@
 	else
 		par_dev = fwnode_get_next_parent_dev(sup_handle);
 
-	if (par_dev && __fw_devlink_relax_cycles(con, par_dev->fwnode)) {
+	if (par_dev && __fw_devlink_relax_cycles(con_handle, par_dev->fwnode)) {
 		pr_debug("%pfwf: cycle: child of %pfwf\n", sup_handle,
 			 par_dev->fwnode);
 		ret = true;
@@ -1995,7 +2014,7 @@
 		    !(dev_link->flags & DL_FLAG_CYCLE))
 			continue;
 
-		if (__fw_devlink_relax_cycles(con,
+		if (__fw_devlink_relax_cycles(con_handle,
 					      dev_link->supplier->fwnode)) {
 			pr_debug("%pfwf: cycle: depends on %pfwf\n", sup_handle,
 				 dev_link->supplier->fwnode);
@@ -2008,6 +2027,7 @@
 out:
 	sup_handle->flags &= ~FWNODE_FLAG_VISITED;
 	put_device(sup_dev);
+	put_device(con_dev);
 	put_device(par_dev);
 	return ret;
 }
@@ -2040,10 +2060,8 @@
 	int ret = 0;
 	u32 flags;
 
-	if (con->fwnode == link->consumer)
-		flags = fw_devlink_get_flags(link->flags);
-	else
-		flags = FW_DEVLINK_FLAGS_PERMISSIVE;
+	if (link->flags & FWLINK_FLAG_IGNORE)
+		return 0;
 
 	/*
 	 * In some cases, a device P might also be a supplier to its child node
@@ -2065,25 +2083,23 @@
 		return -EINVAL;
 
 	/*
-	 * SYNC_STATE_ONLY device links don't block probing and supports cycles.
-	 * So, one might expect that cycle detection isn't necessary for them.
-	 * However, if the device link was marked as SYNC_STATE_ONLY because
-	 * it's part of a cycle, then we still need to do cycle detection. This
-	 * is because the consumer and supplier might be part of multiple cycles
-	 * and we need to detect all those cycles.
+	 * Don't try to optimize by not calling the cycle detection logic under
+	 * certain conditions. There's always some corner case that won't get
+	 * detected.
 	 */
-	if (!device_link_flag_is_sync_state_only(flags) ||
-	    flags & DL_FLAG_CYCLE) {
-		device_links_write_lock();
-		if (__fw_devlink_relax_cycles(con, sup_handle)) {
-			__fwnode_link_cycle(link);
-			flags = fw_devlink_get_flags(link->flags);
-			pr_debug("----- cycle: end -----\n");
-			dev_info(con, "Fixed dependency cycle(s) with %pfwf\n",
-				 sup_handle);
-		}
-		device_links_write_unlock();
+	device_links_write_lock();
+	if (__fw_devlink_relax_cycles(link->consumer, sup_handle)) {
+		__fwnode_link_cycle(link);
+		pr_debug("----- cycle: end -----\n");
+		pr_info("%pfwf: Fixed dependency cycle(s) with %pfwf\n",
+			link->consumer, sup_handle);
 	}
+	device_links_write_unlock();
+
+	if (con->fwnode == link->consumer)
+		flags = fw_devlink_get_flags(link->flags);
+	else
+		flags = FW_DEVLINK_FLAGS_PERMISSIVE;
 
 	if (sup_handle->flags & FWNODE_FLAG_NOT_DEVICE)
 		sup_dev = fwnode_get_next_parent_dev(sup_handle);
@@ -2657,8 +2673,11 @@
 	if (!env)
 		return -ENOMEM;
 
+	/* Synchronize with really_probe() */
+	device_lock(dev);
 	/* let the kset specific function add its keys */
 	retval = kset->uevent_ops->uevent(&dev->kobj, env);
+	device_unlock(dev);
 	if (retval)
 		goto out;
 
@@ -4002,6 +4021,41 @@
 EXPORT_SYMBOL_GPL(device_for_each_child_reverse);
 
 /**
+ * device_for_each_child_reverse_from - device child iterator in reversed order.
+ * @parent: parent struct device.
+ * @from: optional starting point in child list
+ * @fn: function to be called for each device.
+ * @data: data for the callback.
+ *
+ * Iterate over @parent's child devices, starting at @from, and call @fn
+ * for each, passing it @data. This helper is identical to
+ * device_for_each_child_reverse() when @from is NULL.
+ *
+ * @fn is checked each iteration. If it returns anything other than 0,
+ * iteration stop and that value is returned to the caller of
+ * device_for_each_child_reverse_from();
+ */
+int device_for_each_child_reverse_from(struct device *parent,
+				       struct device *from, const void *data,
+				       int (*fn)(struct device *, const void *))
+{
+	struct klist_iter i;
+	struct device *child;
+	int error = 0;
+
+	if (!parent->p)
+		return 0;
+
+	klist_iter_init_node(&parent->p->klist_children, &i,
+			     (from ? &from->p->knode_parent : NULL));
+	while ((child = prev_device(&i)) && !error)
+		error = fn(child, data);
+	klist_iter_exit(&i);
+	return error;
+}
+EXPORT_SYMBOL_GPL(device_for_each_child_reverse_from);
+
+/**
  * device_find_child - device iterator for locating a particular device.
  * @parent: parent struct device
  * @match: Callback function to check device
@@ -4098,9 +4152,14 @@
 	sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);
 	if (!sysfs_dev_char_kobj)
 		goto char_kobj_err;
+	device_link_wq = alloc_workqueue("device_link_wq", 0, 0);
+	if (!device_link_wq)
+		goto wq_err;
 
 	return 0;
 
+ wq_err:
+	kobject_put(sysfs_dev_char_kobj);
  char_kobj_err:
 	kobject_put(sysfs_dev_block_kobj);
  block_kobj_err:
@@ -4467,9 +4526,11 @@
  */
 int device_rename(struct device *dev, const char *new_name)
 {
+	struct subsys_private *sp = NULL;
 	struct kobject *kobj = &dev->kobj;
 	char *old_device_name = NULL;
 	int error;
+	bool is_link_renamed = false;
 
 	dev = get_device(dev);
 	if (!dev)
@@ -4484,7 +4545,7 @@
 	}
 
 	if (dev->class) {
-		struct subsys_private *sp = class_to_subsys(dev->class);
+		sp = class_to_subsys(dev->class);
 
 		if (!sp) {
 			error = -EINVAL;
@@ -4493,16 +4554,19 @@
 
 		error = sysfs_rename_link_ns(&sp->subsys.kobj, kobj, old_device_name,
 					     new_name, kobject_namespace(kobj));
-		subsys_put(sp);
 		if (error)
 			goto out;
+
+		is_link_renamed = true;
 	}
 
 	error = kobject_rename(kobj, new_name);
-	if (error)
-		goto out;
-
 out:
+	if (error && is_link_renamed)
+		sysfs_rename_link_ns(&sp->subsys.kobj, kobj, new_name,
+				     old_device_name, kobject_namespace(kobj));
+	subsys_put(sp);
+
 	put_device(dev);
 
 	kfree(old_device_name);
--- linux-qcom-6.8.0.orig/drivers/base/cpu.c
+++ linux-qcom-6.8.0/drivers/base/cpu.c
@@ -588,6 +588,7 @@
 CPU_SHOW_VULN_FALLBACK(retbleed);
 CPU_SHOW_VULN_FALLBACK(spec_rstack_overflow);
 CPU_SHOW_VULN_FALLBACK(gds);
+CPU_SHOW_VULN_FALLBACK(reg_file_data_sampling);
 
 static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL);
 static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL);
@@ -602,6 +603,7 @@
 static DEVICE_ATTR(retbleed, 0444, cpu_show_retbleed, NULL);
 static DEVICE_ATTR(spec_rstack_overflow, 0444, cpu_show_spec_rstack_overflow, NULL);
 static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL);
+static DEVICE_ATTR(reg_file_data_sampling, 0444, cpu_show_reg_file_data_sampling, NULL);
 
 static struct attribute *cpu_root_vulnerabilities_attrs[] = {
 	&dev_attr_meltdown.attr,
@@ -617,6 +619,7 @@
 	&dev_attr_retbleed.attr,
 	&dev_attr_spec_rstack_overflow.attr,
 	&dev_attr_gather_data_sampling.attr,
+	&dev_attr_reg_file_data_sampling.attr,
 	NULL
 };
 
--- linux-qcom-6.8.0.orig/drivers/base/devres.c
+++ linux-qcom-6.8.0/drivers/base/devres.c
@@ -567,6 +567,7 @@
 	grp->id = grp;
 	if (id)
 		grp->id = id;
+	grp->color = 0;
 
 	spin_lock_irqsave(&dev->devres_lock, flags);
 	add_dr(dev, &grp->node[0]);
@@ -896,9 +897,12 @@
 	/*
 	 * Otherwise: allocate new, larger chunk. We need to allocate before
 	 * taking the lock as most probably the caller uses GFP_KERNEL.
+	 * alloc_dr() will call check_dr_size() to reserve extra memory
+	 * for struct devres automatically, so size @new_size user request
+	 * is delivered to it directly as devm_kmalloc() does.
 	 */
 	new_dr = alloc_dr(devm_kmalloc_release,
-			  total_new_size, gfp, dev_to_node(dev));
+			  new_size, gfp, dev_to_node(dev));
 	if (!new_dr)
 		return NULL;
 
@@ -1222,7 +1226,11 @@
  */
 void devm_free_percpu(struct device *dev, void __percpu *pdata)
 {
-	WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match,
+	/*
+	 * Use devres_release() to prevent memory leakage as
+	 * devm_free_pages() does.
+	 */
+	WARN_ON(devres_release(dev, devm_percpu_release, devm_percpu_match,
 			       (__force void *)pdata));
 }
 EXPORT_SYMBOL_GPL(devm_free_percpu);
--- linux-qcom-6.8.0.orig/drivers/base/firmware_loader/main.c
+++ linux-qcom-6.8.0/drivers/base/firmware_loader/main.c
@@ -825,19 +825,18 @@
 	shash->tfm = alg;
 
 	if (crypto_shash_digest(shash, fw->data, fw->size, sha256buf) < 0)
-		goto out_shash;
+		goto out_free;
 
 	for (int i = 0; i < SHA256_DIGEST_SIZE; i++)
 		sprintf(&outbuf[i * 2], "%02x", sha256buf[i]);
 	outbuf[SHA256_BLOCK_SIZE] = 0;
 	dev_dbg(device, "Loaded FW: %s, sha256: %s\n", name, outbuf);
 
-out_shash:
-	crypto_free_shash(alg);
 out_free:
 	kfree(shash);
 	kfree(outbuf);
 	kfree(sha256buf);
+	crypto_free_shash(alg);
 }
 #else
 static void fw_log_firmware_info(const struct firmware *fw, const char *name,
@@ -845,6 +844,26 @@
 {}
 #endif
 
+/*
+ * Reject firmware file names with ".." path components.
+ * There are drivers that construct firmware file names from device-supplied
+ * strings, and we don't want some device to be able to tell us "I would like to
+ * be sent my firmware from ../../../etc/shadow, please".
+ *
+ * Search for ".." surrounded by either '/' or start/end of string.
+ *
+ * This intentionally only looks at the firmware name, not at the firmware base
+ * directory or at symlink contents.
+ */
+static bool name_contains_dotdot(const char *name)
+{
+	size_t name_len = strlen(name);
+
+	return strcmp(name, "..") == 0 || strncmp(name, "../", 3) == 0 ||
+	       strstr(name, "/../") != NULL ||
+	       (name_len >= 3 && strcmp(name+name_len-3, "/..") == 0);
+}
+
 /* called from request_firmware() and request_firmware_work_func() */
 static int
 _request_firmware(const struct firmware **firmware_p, const char *name,
@@ -865,6 +884,14 @@
 		goto out;
 	}
 
+	if (name_contains_dotdot(name)) {
+		dev_warn(device,
+			 "Firmware load for '%s' refused, path contains '..' component\n",
+			 name);
+		ret = -EINVAL;
+		goto out;
+	}
+
 	ret = _request_firmware_prepare(&fw, name, device, buf, size,
 					offset, opt_flags);
 	if (ret <= 0) /* error or already assigned */
@@ -942,6 +969,8 @@
  *      @name will be used as $FIRMWARE in the uevent environment and
  *      should be distinctive enough not to be confused with any other
  *      firmware image for this or any other device.
+ *	It must not contain any ".." path components - "foo/bar..bin" is
+ *	allowed, but "foo/../bar.bin" is not.
  *
  *	Caller must hold the reference count of @device.
  *
--- linux-qcom-6.8.0.orig/drivers/base/memory.c
+++ linux-qcom-6.8.0/drivers/base/memory.c
@@ -188,6 +188,7 @@
 	unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr);
 	unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
 	unsigned long nr_vmemmap_pages = 0;
+	struct memory_notify arg;
 	struct zone *zone;
 	int ret;
 
@@ -207,9 +208,19 @@
 	if (mem->altmap)
 		nr_vmemmap_pages = mem->altmap->free;
 
+	arg.altmap_start_pfn = start_pfn;
+	arg.altmap_nr_pages = nr_vmemmap_pages;
+	arg.start_pfn = start_pfn + nr_vmemmap_pages;
+	arg.nr_pages = nr_pages - nr_vmemmap_pages;
 	mem_hotplug_begin();
+	ret = memory_notify(MEM_PREPARE_ONLINE, &arg);
+	ret = notifier_to_errno(ret);
+	if (ret)
+		goto out_notifier;
+
 	if (nr_vmemmap_pages) {
-		ret = mhp_init_memmap_on_memory(start_pfn, nr_vmemmap_pages, zone);
+		ret = mhp_init_memmap_on_memory(start_pfn, nr_vmemmap_pages,
+						zone, mem->altmap->inaccessible);
 		if (ret)
 			goto out;
 	}
@@ -231,7 +242,11 @@
 					  nr_vmemmap_pages);
 
 	mem->zone = zone;
+	mem_hotplug_done();
+	return ret;
 out:
+	memory_notify(MEM_FINISH_OFFLINE, &arg);
+out_notifier:
 	mem_hotplug_done();
 	return ret;
 }
@@ -244,6 +259,7 @@
 	unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr);
 	unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
 	unsigned long nr_vmemmap_pages = 0;
+	struct memory_notify arg;
 	int ret;
 
 	if (!mem->zone)
@@ -275,6 +291,11 @@
 		mhp_deinit_memmap_on_memory(start_pfn, nr_vmemmap_pages);
 
 	mem->zone = NULL;
+	arg.altmap_start_pfn = start_pfn;
+	arg.altmap_nr_pages = nr_vmemmap_pages;
+	arg.start_pfn = start_pfn + nr_vmemmap_pages;
+	arg.nr_pages = nr_pages - nr_vmemmap_pages;
+	memory_notify(MEM_FINISH_OFFLINE, &arg);
 out:
 	mem_hotplug_done();
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/base/module.c
+++ linux-qcom-6.8.0/drivers/base/module.c
@@ -30,14 +30,14 @@
 	mutex_unlock(&drivers_dir_mutex);
 }
 
-void module_add_driver(struct module *mod, struct device_driver *drv)
+int module_add_driver(struct module *mod, struct device_driver *drv)
 {
 	char *driver_name;
-	int no_warn;
 	struct module_kobject *mk = NULL;
+	int ret;
 
 	if (!drv)
-		return;
+		return 0;
 
 	if (mod)
 		mk = &mod->mkobj;
@@ -56,17 +56,41 @@
 	}
 
 	if (!mk)
-		return;
+		return 0;
+
+	ret = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
+	if (ret)
+		return ret;
 
-	/* Don't check return codes; these calls are idempotent */
-	no_warn = sysfs_create_link(&drv->p->kobj, &mk->kobj, "module");
 	driver_name = make_driver_name(drv);
-	if (driver_name) {
-		module_create_drivers_dir(mk);
-		no_warn = sysfs_create_link(mk->drivers_dir, &drv->p->kobj,
-					    driver_name);
-		kfree(driver_name);
+	if (!driver_name) {
+		ret = -ENOMEM;
+		goto out_remove_kobj;
+	}
+
+	module_create_drivers_dir(mk);
+	if (!mk->drivers_dir) {
+		ret = -EINVAL;
+		goto out_free_driver_name;
 	}
+
+	ret = sysfs_create_link(mk->drivers_dir, &drv->p->kobj, driver_name);
+	if (ret)
+		goto out_remove_drivers_dir;
+
+	kfree(driver_name);
+
+	return 0;
+
+out_remove_drivers_dir:
+	sysfs_remove_link(mk->drivers_dir, driver_name);
+
+out_free_driver_name:
+	kfree(driver_name);
+
+out_remove_kobj:
+	sysfs_remove_link(&drv->p->kobj, "module");
+	return ret;
 }
 
 void module_remove_driver(struct device_driver *drv)
--- linux-qcom-6.8.0.orig/drivers/base/node.c
+++ linux-qcom-6.8.0/drivers/base/node.c
@@ -126,7 +126,7 @@
 }
 
 static struct node_access_nodes *node_init_node_access(struct node *node,
-						       unsigned int access)
+						       enum access_coordinate_class access)
 {
 	struct node_access_nodes *access_node;
 	struct device *dev;
@@ -191,7 +191,7 @@
  * @access: The access class the for the given attributes
  */
 void node_set_perf_attrs(unsigned int nid, struct access_coordinate *coord,
-			 unsigned int access)
+			 enum access_coordinate_class access)
 {
 	struct node_access_nodes *c;
 	struct node *node;
@@ -689,7 +689,7 @@
  */
 int register_memory_node_under_compute_node(unsigned int mem_nid,
 					    unsigned int cpu_nid,
-					    unsigned int access)
+					    enum access_coordinate_class access)
 {
 	struct node *init_node, *targ_node;
 	struct node_access_nodes *initiator, *target;
--- linux-qcom-6.8.0.orig/drivers/base/power/common.c
+++ linux-qcom-6.8.0/drivers/base/power/common.c
@@ -168,6 +168,115 @@
 EXPORT_SYMBOL_GPL(dev_pm_domain_attach_by_name);
 
 /**
+ * dev_pm_domain_attach_list - Associate a device with its PM domains.
+ * @dev: The device used to lookup the PM domains for.
+ * @data: The data used for attaching to the PM domains.
+ * @list: An out-parameter with an allocated list of attached PM domains.
+ *
+ * This function helps to attach a device to its multiple PM domains. The
+ * caller, which is typically a driver's probe function, may provide a list of
+ * names for the PM domains that we should try to attach the device to, but it
+ * may also provide an empty list, in case the attach should be done for all of
+ * the available PM domains.
+ *
+ * Callers must ensure proper synchronization of this function with power
+ * management callbacks.
+ *
+ * Returns the number of attached PM domains or a negative error code in case of
+ * a failure. Note that, to detach the list of PM domains, the driver shall call
+ * dev_pm_domain_detach_list(), typically during the remove phase.
+ */
+int dev_pm_domain_attach_list(struct device *dev,
+			      const struct dev_pm_domain_attach_data *data,
+			      struct dev_pm_domain_list **list)
+{
+	struct device_node *np = dev->of_node;
+	struct dev_pm_domain_list *pds;
+	struct device *pd_dev = NULL;
+	int ret, i, num_pds = 0;
+	bool by_id = true;
+	u32 pd_flags = data ? data->pd_flags : 0;
+	u32 link_flags = pd_flags & PD_FLAG_NO_DEV_LINK ? 0 :
+			DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME;
+
+	if (dev->pm_domain)
+		return -EEXIST;
+
+	/* For now this is limited to OF based platforms. */
+	if (!np)
+		return 0;
+
+	if (data && data->pd_names) {
+		num_pds = data->num_pd_names;
+		by_id = false;
+	} else {
+		num_pds = of_count_phandle_with_args(np, "power-domains",
+						     "#power-domain-cells");
+	}
+
+	if (num_pds <= 0)
+		return 0;
+
+	pds = devm_kzalloc(dev, sizeof(*pds), GFP_KERNEL);
+	if (!pds)
+		return -ENOMEM;
+
+	pds->pd_devs = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_devs),
+				    GFP_KERNEL);
+	if (!pds->pd_devs)
+		return -ENOMEM;
+
+	pds->pd_links = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_links),
+				     GFP_KERNEL);
+	if (!pds->pd_links)
+		return -ENOMEM;
+
+	if (link_flags && pd_flags & PD_FLAG_DEV_LINK_ON)
+		link_flags |= DL_FLAG_RPM_ACTIVE;
+
+	for (i = 0; i < num_pds; i++) {
+		if (by_id)
+			pd_dev = dev_pm_domain_attach_by_id(dev, i);
+		else
+			pd_dev = dev_pm_domain_attach_by_name(dev,
+							data->pd_names[i]);
+		if (IS_ERR_OR_NULL(pd_dev)) {
+			ret = pd_dev ? PTR_ERR(pd_dev) : -ENODEV;
+			goto err_attach;
+		}
+
+		if (link_flags) {
+			struct device_link *link;
+
+			link = device_link_add(dev, pd_dev, link_flags);
+			if (!link) {
+				ret = -ENODEV;
+				goto err_link;
+			}
+
+			pds->pd_links[i] = link;
+		}
+
+		pds->pd_devs[i] = pd_dev;
+	}
+
+	pds->num_pds = num_pds;
+	*list = pds;
+	return num_pds;
+
+err_link:
+	dev_pm_domain_detach(pd_dev, true);
+err_attach:
+	while (--i >= 0) {
+		if (pds->pd_links[i])
+			device_link_del(pds->pd_links[i]);
+		dev_pm_domain_detach(pds->pd_devs[i], true);
+	}
+	return ret;
+}
+EXPORT_SYMBOL_GPL(dev_pm_domain_attach_list);
+
+/**
  * dev_pm_domain_detach - Detach a device from its PM domain.
  * @dev: Device to detach.
  * @power_off: Used to indicate whether we should power off the device.
@@ -188,6 +297,31 @@
 EXPORT_SYMBOL_GPL(dev_pm_domain_detach);
 
 /**
+ * dev_pm_domain_detach_list - Detach a list of PM domains.
+ * @list: The list of PM domains to detach.
+ *
+ * This function reverse the actions from dev_pm_domain_attach_list().
+ * Typically it should be invoked during the remove phase from drivers.
+ *
+ * Callers must ensure proper synchronization of this function with power
+ * management callbacks.
+ */
+void dev_pm_domain_detach_list(struct dev_pm_domain_list *list)
+{
+	int i;
+
+	if (!list)
+		return;
+
+	for (i = 0; i < list->num_pds; i++) {
+		if (list->pd_links[i])
+			device_link_del(list->pd_links[i]);
+		dev_pm_domain_detach(list->pd_devs[i], true);
+	}
+}
+EXPORT_SYMBOL_GPL(dev_pm_domain_detach_list);
+
+/**
  * dev_pm_domain_start - Start the device through its PM domain.
  * @dev: Device to start.
  *
--- linux-qcom-6.8.0.orig/drivers/base/power/runtime.c
+++ linux-qcom-6.8.0/drivers/base/power/runtime.c
@@ -1176,7 +1176,7 @@
 EXPORT_SYMBOL_GPL(__pm_runtime_resume);
 
 /**
- * pm_runtime_get_if_active - Conditionally bump up device usage counter.
+ * pm_runtime_get_conditional - Conditionally bump up device usage counter.
  * @dev: Device to handle.
  * @ign_usage_count: Whether or not to look at the current usage counter value.
  *
@@ -1197,7 +1197,7 @@
  * The caller is responsible for decrementing the runtime PM usage counter of
  * @dev after this function has returned a positive value for it.
  */
-int pm_runtime_get_if_active(struct device *dev, bool ign_usage_count)
+static int pm_runtime_get_conditional(struct device *dev, bool ign_usage_count)
 {
 	unsigned long flags;
 	int retval;
@@ -1218,9 +1218,40 @@
 
 	return retval;
 }
+
+/**
+ * pm_runtime_get_if_active - Bump up runtime PM usage counter if the device is
+ *			      in active state
+ * @dev: Target device.
+ *
+ * Increment the runtime PM usage counter of @dev if its runtime PM status is
+ * %RPM_ACTIVE, in which case it returns 1. If the device is in a different
+ * state, 0 is returned. -EINVAL is returned if runtime PM is disabled for the
+ * device, in which case also the usage_count will remain unmodified.
+ */
+int pm_runtime_get_if_active(struct device *dev)
+{
+	return pm_runtime_get_conditional(dev, true);
+}
 EXPORT_SYMBOL_GPL(pm_runtime_get_if_active);
 
 /**
+ * pm_runtime_get_if_in_use - Conditionally bump up runtime PM usage counter.
+ * @dev: Target device.
+ *
+ * Increment the runtime PM usage counter of @dev if its runtime PM status is
+ * %RPM_ACTIVE and its runtime PM usage counter is greater than 0, in which case
+ * it returns 1. If the device is in a different state or its usage_count is 0,
+ * 0 is returned. -EINVAL is returned if runtime PM is disabled for the device,
+ * in which case also the usage_count will remain unmodified.
+ */
+int pm_runtime_get_if_in_use(struct device *dev)
+{
+	return pm_runtime_get_conditional(dev, false);
+}
+EXPORT_SYMBOL_GPL(pm_runtime_get_if_in_use);
+
+/**
  * __pm_runtime_set_status - Set runtime PM status of a device.
  * @dev: Device to handle.
  * @status: New runtime PM status of the device.
--- linux-qcom-6.8.0.orig/drivers/base/power/wakeirq.c
+++ linux-qcom-6.8.0/drivers/base/power/wakeirq.c
@@ -313,8 +313,10 @@
 		return;
 
 	if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED &&
-	    wirq->status & WAKE_IRQ_DEDICATED_REVERSE)
+	    wirq->status & WAKE_IRQ_DEDICATED_REVERSE) {
 		enable_irq(wirq->irq);
+		wirq->status |= WAKE_IRQ_DEDICATED_ENABLED;
+	}
 }
 
 /**
--- linux-qcom-6.8.0.orig/drivers/base/regmap/internal.h
+++ linux-qcom-6.8.0/drivers/base/regmap/internal.h
@@ -59,6 +59,7 @@
 			unsigned long raw_spinlock_flags;
 		};
 	};
+	struct lock_class_key *lock_key;
 	regmap_lock lock;
 	regmap_unlock unlock;
 	void *lock_arg; /* This is passed to lock/unlock functions */
--- linux-qcom-6.8.0.orig/drivers/base/regmap/regcache-maple.c
+++ linux-qcom-6.8.0/drivers/base/regmap/regcache-maple.c
@@ -110,9 +110,10 @@
 	struct maple_tree *mt = map->cache;
 	MA_STATE(mas, mt, min, max);
 	unsigned long *entry, *lower, *upper;
-	unsigned long lower_index, lower_last;
+	/* initialized to work around false-positive -Wuninitialized warning */
+	unsigned long lower_index = 0, lower_last = 0;
 	unsigned long upper_index, upper_last;
-	int ret;
+	int ret = 0;
 
 	lower = NULL;
 	upper = NULL;
@@ -145,7 +146,7 @@
 			upper_index = max + 1;
 			upper_last = mas.last;
 
-			upper = kmemdup(&entry[max + 1],
+			upper = kmemdup(&entry[max - mas.index + 1],
 					((mas.last - max) *
 					 sizeof(unsigned long)),
 					map->alloc_flags);
@@ -244,7 +245,7 @@
 	unsigned long lmin = min;
 	unsigned long lmax = max;
 	unsigned int r, v, sync_start;
-	int ret;
+	int ret = 0;
 	bool sync_needed = false;
 
 	map->cache_bypass = true;
@@ -355,6 +356,9 @@
 
 	mt_init(mt);
 
+	if (!mt_external_lock(mt) && map->lock_key)
+		lockdep_set_class_and_subclass(&mt->ma_lock, map->lock_key, 1);
+
 	if (!map->num_reg_defaults)
 		return 0;
 
--- linux-qcom-6.8.0.orig/drivers/base/regmap/regmap-i2c.c
+++ linux-qcom-6.8.0/drivers/base/regmap/regmap-i2c.c
@@ -350,7 +350,8 @@
 
 		if (quirks->max_write_len &&
 		    (bus->max_raw_write == 0 || bus->max_raw_write > quirks->max_write_len))
-			max_write = quirks->max_write_len;
+			max_write = quirks->max_write_len -
+				(config->reg_bits + config->pad_bits) / BITS_PER_BYTE;
 
 		if (max_read || max_write) {
 			ret_bus = kmemdup(bus, sizeof(*bus), GFP_KERNEL);
--- linux-qcom-6.8.0.orig/drivers/base/regmap/regmap-irq.c
+++ linux-qcom-6.8.0/drivers/base/regmap/regmap-irq.c
@@ -514,12 +514,16 @@
 		return IRQ_NONE;
 }
 
+static struct lock_class_key regmap_irq_lock_class;
+static struct lock_class_key regmap_irq_request_class;
+
 static int regmap_irq_map(struct irq_domain *h, unsigned int virq,
 			  irq_hw_number_t hw)
 {
 	struct regmap_irq_chip_data *data = h->host_data;
 
 	irq_set_chip_data(virq, data);
+	irq_set_lockdep_class(virq, &regmap_irq_lock_class, &regmap_irq_request_class);
 	irq_set_chip(virq, &data->irq_chip);
 	irq_set_nested_thread(virq, 1);
 	irq_set_parent(virq, data->irq);
--- linux-qcom-6.8.0.orig/drivers/base/regmap/regmap-kunit.c
+++ linux-qcom-6.8.0/drivers/base/regmap/regmap-kunit.c
@@ -4,11 +4,14 @@
 //
 // Copyright 2023 Arm Ltd
 
+#include <kunit/resource.h>
 #include <kunit/test.h>
 #include "internal.h"
 
 #define BLOCK_TEST_SIZE 12
 
+KUNIT_DEFINE_ACTION_WRAPPER(regmap_exit_action, regmap_exit, struct regmap *);
+
 static void get_changed_bytes(void *orig, void *new, size_t size)
 {
 	char *o = orig;
@@ -70,9 +73,9 @@
 				 struct regmap_ram_data **data)
 {
 	unsigned int *buf;
-	struct regmap *ret;
+	struct regmap *ret = ERR_PTR(-ENOMEM);
 	size_t size = (config->max_register + 1) * sizeof(unsigned int);
-	int i;
+	int i, error;
 	struct reg_default *defaults;
 
 	config->disable_locking = config->cache_type == REGCACHE_RBTREE ||
@@ -86,15 +89,17 @@
 
 	*data = kzalloc(sizeof(**data), GFP_KERNEL);
 	if (!(*data))
-		return ERR_PTR(-ENOMEM);
+		goto out_free;
 	(*data)->vals = buf;
 
 	if (config->num_reg_defaults) {
-		defaults = kcalloc(config->num_reg_defaults,
-				   sizeof(struct reg_default),
-				   GFP_KERNEL);
+		defaults = kunit_kcalloc(test,
+					 config->num_reg_defaults,
+					 sizeof(struct reg_default),
+					 GFP_KERNEL);
 		if (!defaults)
-			return ERR_PTR(-ENOMEM);
+			goto out_free;
+
 		config->reg_defaults = defaults;
 
 		for (i = 0; i < config->num_reg_defaults; i++) {
@@ -104,10 +109,19 @@
 	}
 
 	ret = regmap_init_ram(config, *data);
-	if (IS_ERR(ret)) {
-		kfree(buf);
-		kfree(*data);
-	}
+	if (IS_ERR(ret))
+		goto out_free;
+
+	/* This calls regmap_exit() on failure, which frees buf and *data */
+	error = kunit_add_action_or_reset(test, regmap_exit_action, ret);
+	if (error)
+		ret = ERR_PTR(error);
+
+	return ret;
+
+out_free:
+	kfree(buf);
+	kfree(*data);
 
 	return ret;
 }
@@ -142,8 +156,6 @@
 
 	/* If using a cache the cache satisfied the read */
 	KUNIT_EXPECT_EQ(test, t->type == REGCACHE_NONE, data->read[0]);
-
-	regmap_exit(map);
 }
 
 static void bulk_write(struct kunit *test)
@@ -179,8 +191,6 @@
 	/* If using a cache the cache satisfied the read */
 	for (i = 0; i < BLOCK_TEST_SIZE; i++)
 		KUNIT_EXPECT_EQ(test, t->type == REGCACHE_NONE, data->read[i]);
-
-	regmap_exit(map);
 }
 
 static void bulk_read(struct kunit *test)
@@ -212,8 +222,6 @@
 	/* If using a cache the cache satisfied the read */
 	for (i = 0; i < BLOCK_TEST_SIZE; i++)
 		KUNIT_EXPECT_EQ(test, t->type == REGCACHE_NONE, data->read[i]);
-
-	regmap_exit(map);
 }
 
 static void write_readonly(struct kunit *test)
@@ -247,8 +255,6 @@
 	/* Did that match what we see on the device? */
 	for (i = 0; i < BLOCK_TEST_SIZE; i++)
 		KUNIT_EXPECT_EQ(test, i != 5, data->written[i]);
-
-	regmap_exit(map);
 }
 
 static void read_writeonly(struct kunit *test)
@@ -287,8 +293,6 @@
 
 	/* Did we trigger a hardware access? */
 	KUNIT_EXPECT_FALSE(test, data->read[5]);
-
-	regmap_exit(map);
 }
 
 static void reg_defaults(struct kunit *test)
@@ -401,8 +405,6 @@
 			break;
 		}
 	}
-
-	regmap_exit(map);
 }
 
 static void stride(struct kunit *test)
@@ -444,8 +446,6 @@
 			KUNIT_EXPECT_TRUE(test, data->written[i]);
 		}
 	}
-
-	regmap_exit(map);
 }
 
 static struct regmap_range_cfg test_range = {
@@ -546,8 +546,6 @@
 		KUNIT_EXPECT_FALSE(test, data->read[i]);
 		KUNIT_EXPECT_FALSE(test, data->written[i]);
 	}
-
-	regmap_exit(map);
 }
 
 /* Try to stress dynamic creation of cache data structures */
@@ -601,8 +599,6 @@
 		KUNIT_EXPECT_EQ(test, rval, vals[i]);
 		KUNIT_EXPECT_EQ(test, t->type == REGCACHE_NONE, data->read[i]);
 	}
-
-	regmap_exit(map);
 }
 
 static void cache_bypass(struct kunit *test)
@@ -639,8 +635,6 @@
 	regcache_cache_bypass(map, false);
 	KUNIT_EXPECT_EQ(test, 0, regmap_read(map, 0, &rval));
 	KUNIT_EXPECT_EQ(test, val, rval);
-
-	regmap_exit(map);
 }
 
 static void cache_sync(struct kunit *test)
@@ -677,8 +671,6 @@
 	KUNIT_EXPECT_MEMEQ(test, data->vals, val, sizeof(val));
 	for (i = 0; i < BLOCK_TEST_SIZE; i++)
 		KUNIT_EXPECT_EQ(test, true, data->written[i]);
-
-	regmap_exit(map);
 }
 
 static void cache_sync_defaults(struct kunit *test)
@@ -713,8 +705,6 @@
 	/* Did we just sync the one register we touched? */
 	for (i = 0; i < BLOCK_TEST_SIZE; i++)
 		KUNIT_EXPECT_EQ(test, i == 2, data->written[i]);
-
-	regmap_exit(map);
 }
 
 static void cache_sync_readonly(struct kunit *test)
@@ -754,8 +744,6 @@
 	/* Did that match what we see on the device? */
 	for (i = 0; i < BLOCK_TEST_SIZE; i++)
 		KUNIT_EXPECT_EQ(test, i != 5, data->written[i]);
-
-	regmap_exit(map);
 }
 
 static void cache_sync_patch(struct kunit *test)
@@ -815,8 +803,6 @@
 			break;
 		}
 	}
-
-	regmap_exit(map);
 }
 
 static void cache_drop(struct kunit *test)
@@ -857,8 +843,6 @@
 	for (i = 0; i < BLOCK_TEST_SIZE; i++)
 		KUNIT_EXPECT_EQ(test, data->read[i], i >= 3 && i <= 5);
 	KUNIT_EXPECT_MEMEQ(test, data->vals, rval, sizeof(rval));
-
-	regmap_exit(map);
 }
 
 static void cache_present(struct kunit *test)
@@ -896,8 +880,6 @@
 	/* Now everything should be cached */
 	for (i = 0; i < BLOCK_TEST_SIZE; i++)
 		KUNIT_ASSERT_TRUE(test, regcache_reg_cached(map, i));
-
-	regmap_exit(map);
 }
 
 /* Check that caching the window register works with sync */
@@ -1002,9 +984,9 @@
 				     struct regmap_ram_data **data)
 {
 	u16 *buf;
-	struct regmap *ret;
+	struct regmap *ret = ERR_PTR(-ENOMEM);
 	size_t size = (config->max_register + 1) * config->reg_bits / 8;
-	int i;
+	int i, error;
 	struct reg_default *defaults;
 
 	config->cache_type = test_type->cache_type;
@@ -1020,15 +1002,16 @@
 
 	*data = kzalloc(sizeof(**data), GFP_KERNEL);
 	if (!(*data))
-		return ERR_PTR(-ENOMEM);
+		goto out_free;
 	(*data)->vals = (void *)buf;
 
 	config->num_reg_defaults = config->max_register + 1;
-	defaults = kcalloc(config->num_reg_defaults,
-			   sizeof(struct reg_default),
-			   GFP_KERNEL);
+	defaults = kunit_kcalloc(test,
+				 config->num_reg_defaults,
+				 sizeof(struct reg_default),
+				 GFP_KERNEL);
 	if (!defaults)
-		return ERR_PTR(-ENOMEM);
+		goto out_free;
 	config->reg_defaults = defaults;
 
 	for (i = 0; i < config->num_reg_defaults; i++) {
@@ -1041,7 +1024,8 @@
 			defaults[i].def = be16_to_cpu(buf[i]);
 			break;
 		default:
-			return ERR_PTR(-EINVAL);
+			ret = ERR_PTR(-EINVAL);
+			goto out_free;
 		}
 	}
 
@@ -1053,10 +1037,19 @@
 		config->num_reg_defaults = 0;
 
 	ret = regmap_init_raw_ram(config, *data);
-	if (IS_ERR(ret)) {
-		kfree(buf);
-		kfree(*data);
-	}
+	if (IS_ERR(ret))
+		goto out_free;
+
+	/* This calls regmap_exit() on failure, which frees buf and *data */
+	error = kunit_add_action_or_reset(test, regmap_exit_action, ret);
+	if (error)
+		ret = ERR_PTR(error);
+
+	return ret;
+
+out_free:
+	kfree(buf);
+	kfree(*data);
 
 	return ret;
 }
@@ -1082,8 +1075,6 @@
 		KUNIT_EXPECT_EQ(test, 0, regmap_read(map, i, &rval));
 		KUNIT_EXPECT_EQ(test, config.reg_defaults[i].def, rval);
 	}
-
-	regmap_exit(map);
 }
 
 static void raw_read_defaults(struct kunit *test)
@@ -1105,7 +1096,7 @@
 		return;
 
 	val_len = sizeof(*rval) * (config.max_register + 1);
-	rval = kmalloc(val_len, GFP_KERNEL);
+	rval = kunit_kmalloc(test, val_len, GFP_KERNEL);
 	KUNIT_ASSERT_TRUE(test, rval != NULL);
 	if (!rval)
 		return;
@@ -1120,9 +1111,6 @@
 			KUNIT_EXPECT_EQ(test, def, le16_to_cpu(rval[i]));
 		}
 	}
-	
-	kfree(rval);
-	regmap_exit(map);
 }
 
 static void raw_write_read_single(struct kunit *test)
@@ -1147,8 +1135,6 @@
 	KUNIT_EXPECT_EQ(test, 0, regmap_write(map, 0, val));
 	KUNIT_EXPECT_EQ(test, 0, regmap_read(map, 0, &rval));
 	KUNIT_EXPECT_EQ(test, val, rval);
-
-	regmap_exit(map);
 }
 
 static void raw_write(struct kunit *test)
@@ -1199,8 +1185,6 @@
 
 	/* The values should appear in the "hardware" */
 	KUNIT_EXPECT_MEMEQ(test, &hw_buf[2], val, sizeof(val));
-
-	regmap_exit(map);
 }
 
 static bool reg_zero(struct device *dev, unsigned int reg)
@@ -1259,8 +1243,6 @@
 	/* Make sure we didn't touch the register after the noinc register */
 	KUNIT_EXPECT_EQ(test, 0, regmap_read(map, 1, &val));
 	KUNIT_ASSERT_EQ(test, val_test, val);
-
-	regmap_exit(map);
 }
 
 static void raw_sync(struct kunit *test)
@@ -1337,8 +1319,6 @@
 
 	/* The values should now appear in the "hardware" */
 	KUNIT_EXPECT_MEMEQ(test, &hw_buf[2], &val[0], sizeof(val));
-
-	regmap_exit(map);
 }
 
 static struct kunit_case regmap_test_cases[] = {
--- linux-qcom-6.8.0.orig/drivers/base/regmap/regmap-spi.c
+++ linux-qcom-6.8.0/drivers/base/regmap/regmap-spi.c
@@ -122,8 +122,7 @@
 			return ERR_PTR(-ENOMEM);
 
 		max_msg_size = spi_max_message_size(spi);
-		reg_reserve_size = config->reg_bits / BITS_PER_BYTE
-				 + config->pad_bits / BITS_PER_BYTE;
+		reg_reserve_size = (config->reg_bits + config->pad_bits) / BITS_PER_BYTE;
 		if (max_size + reg_reserve_size > max_msg_size)
 			max_size -= reg_reserve_size;
 
--- linux-qcom-6.8.0.orig/drivers/base/regmap/regmap.c
+++ linux-qcom-6.8.0/drivers/base/regmap/regmap.c
@@ -598,6 +598,17 @@
 }
 EXPORT_SYMBOL_GPL(regmap_attach_dev);
 
+static int dev_get_regmap_match(struct device *dev, void *res, void *data);
+
+static int regmap_detach_dev(struct device *dev, struct regmap *map)
+{
+	if (!dev)
+		return 0;
+
+	return devres_release(dev, dev_get_regmap_release,
+			      dev_get_regmap_match, (void *)map->name);
+}
+
 static enum regmap_endian regmap_get_reg_endian(const struct regmap_bus *bus,
 					const struct regmap_config *config)
 {
@@ -745,6 +756,7 @@
 						   lock_key, lock_name);
 		}
 		map->lock_arg = map;
+		map->lock_key = lock_key;
 	}
 
 	/*
@@ -1050,13 +1062,13 @@
 
 		/* Sanity check */
 		if (range_cfg->range_max < range_cfg->range_min) {
-			dev_err(map->dev, "Invalid range %d: %d < %d\n", i,
+			dev_err(map->dev, "Invalid range %d: %u < %u\n", i,
 				range_cfg->range_max, range_cfg->range_min);
 			goto err_range;
 		}
 
 		if (range_cfg->range_max > map->max_register) {
-			dev_err(map->dev, "Invalid range %d: %d > %d\n", i,
+			dev_err(map->dev, "Invalid range %d: %u > %u\n", i,
 				range_cfg->range_max, map->max_register);
 			goto err_range;
 		}
@@ -1442,6 +1454,7 @@
 {
 	struct regmap_async *async;
 
+	regmap_detach_dev(map->dev, map);
 	regcache_exit(map);
 	regmap_debugfs_exit(map);
 	regmap_range_exit(map);
@@ -2837,6 +2850,43 @@
 EXPORT_SYMBOL_GPL(regmap_read);
 
 /**
+ * regmap_read_bypassed() - Read a value from a single register direct
+ *			    from the device, bypassing the cache
+ *
+ * @map: Register map to read from
+ * @reg: Register to be read from
+ * @val: Pointer to store read value
+ *
+ * A value of zero will be returned on success, a negative errno will
+ * be returned in error cases.
+ */
+int regmap_read_bypassed(struct regmap *map, unsigned int reg, unsigned int *val)
+{
+	int ret;
+	bool bypass, cache_only;
+
+	if (!IS_ALIGNED(reg, map->reg_stride))
+		return -EINVAL;
+
+	map->lock(map->lock_arg);
+
+	bypass = map->cache_bypass;
+	cache_only = map->cache_only;
+	map->cache_bypass = true;
+	map->cache_only = false;
+
+	ret = _regmap_read(map, reg, val);
+
+	map->cache_bypass = bypass;
+	map->cache_only = cache_only;
+
+	map->unlock(map->lock_arg);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(regmap_read_bypassed);
+
+/**
  * regmap_raw_read() - Read raw data from the device
  *
  * @map: Register map to read from
--- linux-qcom-6.8.0.orig/drivers/base/topology.c
+++ linux-qcom-6.8.0/drivers/base/topology.c
@@ -27,9 +27,17 @@
 			   loff_t off, size_t count)				\
 {										\
 	struct device *dev = kobj_to_dev(kobj);                                 \
+	cpumask_var_t mask;							\
+	ssize_t n;								\
 										\
-	return cpumap_print_bitmask_to_buf(buf, topology_##mask(dev->id),	\
-					   off, count);                         \
+	if (!alloc_cpumask_var(&mask, GFP_KERNEL))				\
+		return -ENOMEM;							\
+										\
+	cpumask_copy(mask, topology_##mask(dev->id));				\
+	n = cpumap_print_bitmask_to_buf(buf, mask, off, count);			\
+	free_cpumask_var(mask);							\
+										\
+	return n;								\
 }										\
 										\
 static ssize_t name##_list_read(struct file *file, struct kobject *kobj,	\
@@ -37,9 +45,17 @@
 				loff_t off, size_t count)			\
 {										\
 	struct device *dev = kobj_to_dev(kobj);					\
+	cpumask_var_t mask;							\
+	ssize_t n;								\
+										\
+	if (!alloc_cpumask_var(&mask, GFP_KERNEL))				\
+		return -ENOMEM;							\
+										\
+	cpumask_copy(mask, topology_##mask(dev->id));				\
+	n = cpumap_print_list_to_buf(buf, mask, off, count);			\
+	free_cpumask_var(mask);							\
 										\
-	return cpumap_print_list_to_buf(buf, topology_##mask(dev->id),		\
-					off, count);				\
+	return n;								\
 }
 
 define_id_show_func(physical_package_id, "%d");
--- linux-qcom-6.8.0.orig/drivers/base/trace.h
+++ linux-qcom-6.8.0/drivers/base/trace.h
@@ -24,18 +24,18 @@
 		__field(struct device *, dev)
 		__field(const char *, op)
 		__field(void *, node)
-		__field(const char *, name)
+		__string(name, name)
 		__field(size_t, size)
 	),
 	TP_fast_assign(
 		__assign_str(devname, dev_name(dev));
 		__entry->op = op;
 		__entry->node = node;
-		__entry->name = name;
+		__assign_str(name, name);
 		__entry->size = size;
 	),
 	TP_printk("%s %3s %p %s (%zu bytes)", __get_str(devname),
-		  __entry->op, __entry->node, __entry->name, __entry->size)
+		  __entry->op, __entry->node, __get_str(name), __entry->size)
 );
 
 DEFINE_EVENT(devres, devres_log,
--- linux-qcom-6.8.0.orig/drivers/block/aoe/aoecmd.c
+++ linux-qcom-6.8.0/drivers/block/aoe/aoecmd.c
@@ -361,6 +361,7 @@
 	}
 
 	ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit;
+	dev_hold(t->ifp->nd);
 	skb->dev = t->ifp->nd;
 }
 
@@ -401,6 +402,8 @@
 		__skb_queue_head_init(&queue);
 		__skb_queue_tail(&queue, skb);
 		aoenet_xmit(&queue);
+	} else {
+		dev_put(f->t->ifp->nd);
 	}
 	return 1;
 }
@@ -419,13 +422,16 @@
 	rcu_read_lock();
 	for_each_netdev_rcu(&init_net, ifp) {
 		dev_hold(ifp);
-		if (!is_aoe_netif(ifp))
-			goto cont;
+		if (!is_aoe_netif(ifp)) {
+			dev_put(ifp);
+			continue;
+		}
 
 		skb = new_skb(sizeof *h + sizeof *ch);
 		if (skb == NULL) {
 			printk(KERN_INFO "aoe: skb alloc failure\n");
-			goto cont;
+			dev_put(ifp);
+			continue;
 		}
 		skb_put(skb, sizeof *h + sizeof *ch);
 		skb->dev = ifp;
@@ -440,9 +446,6 @@
 		h->major = cpu_to_be16(aoemajor);
 		h->minor = aoeminor;
 		h->cmd = AOECMD_CFG;
-
-cont:
-		dev_put(ifp);
 	}
 	rcu_read_unlock();
 }
@@ -483,10 +486,13 @@
 	memcpy(h->dst, t->addr, sizeof h->dst);
 	memcpy(h->src, t->ifp->nd->dev_addr, sizeof h->src);
 
+	dev_hold(t->ifp->nd);
 	skb->dev = t->ifp->nd;
 	skb = skb_clone(skb, GFP_ATOMIC);
-	if (skb == NULL)
+	if (skb == NULL) {
+		dev_put(t->ifp->nd);
 		return;
+	}
 	f->sent = ktime_get();
 	__skb_queue_head_init(&queue);
 	__skb_queue_tail(&queue, skb);
@@ -617,6 +623,8 @@
 		__skb_queue_head_init(&queue);
 		__skb_queue_tail(&queue, skb);
 		aoenet_xmit(&queue);
+	} else {
+		dev_put(f->t->ifp->nd);
 	}
 }
 
@@ -1395,6 +1403,7 @@
 	ah->cmdstat = ATA_CMD_ID_ATA;
 	ah->lba3 = 0xa0;
 
+	dev_hold(t->ifp->nd);
 	skb->dev = t->ifp->nd;
 
 	d->rttavg = RTTAVG_INIT;
@@ -1404,6 +1413,8 @@
 	skb = skb_clone(skb, GFP_ATOMIC);
 	if (skb)
 		f->sent = ktime_get();
+	else
+		dev_put(t->ifp->nd);
 
 	return skb;
 }
--- linux-qcom-6.8.0.orig/drivers/block/aoe/aoenet.c
+++ linux-qcom-6.8.0/drivers/block/aoe/aoenet.c
@@ -63,6 +63,7 @@
 			pr_warn("aoe: packet could not be sent on %s.  %s\n",
 				ifp ? ifp->name : "netif",
 				"consider increasing tx_queue_len");
+		dev_put(ifp);
 		spin_lock_irq(&txlock);
 	}
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/block/brd.c
+++ linux-qcom-6.8.0/drivers/block/brd.c
@@ -310,8 +310,40 @@
  * (should share code eventually).
  */
 static LIST_HEAD(brd_devices);
+static DEFINE_MUTEX(brd_devices_mutex);
 static struct dentry *brd_debugfs_dir;
 
+static struct brd_device *brd_find_or_alloc_device(int i)
+{
+	struct brd_device *brd;
+
+	mutex_lock(&brd_devices_mutex);
+	list_for_each_entry(brd, &brd_devices, brd_list) {
+		if (brd->brd_number == i) {
+			mutex_unlock(&brd_devices_mutex);
+			return ERR_PTR(-EEXIST);
+		}
+	}
+
+	brd = kzalloc(sizeof(*brd), GFP_KERNEL);
+	if (!brd) {
+		mutex_unlock(&brd_devices_mutex);
+		return ERR_PTR(-ENOMEM);
+	}
+	brd->brd_number	= i;
+	list_add_tail(&brd->brd_list, &brd_devices);
+	mutex_unlock(&brd_devices_mutex);
+	return brd;
+}
+
+static void brd_free_device(struct brd_device *brd)
+{
+	mutex_lock(&brd_devices_mutex);
+	list_del(&brd->brd_list);
+	mutex_unlock(&brd_devices_mutex);
+	kfree(brd);
+}
+
 static int brd_alloc(int i)
 {
 	struct brd_device *brd;
@@ -319,14 +351,9 @@
 	char buf[DISK_NAME_LEN];
 	int err = -ENOMEM;
 
-	list_for_each_entry(brd, &brd_devices, brd_list)
-		if (brd->brd_number == i)
-			return -EEXIST;
-	brd = kzalloc(sizeof(*brd), GFP_KERNEL);
-	if (!brd)
-		return -ENOMEM;
-	brd->brd_number		= i;
-	list_add_tail(&brd->brd_list, &brd_devices);
+	brd = brd_find_or_alloc_device(i);
+	if (IS_ERR(brd))
+		return PTR_ERR(brd);
 
 	xa_init(&brd->brd_pages);
 
@@ -369,8 +396,7 @@
 out_cleanup_disk:
 	put_disk(disk);
 out_free_dev:
-	list_del(&brd->brd_list);
-	kfree(brd);
+	brd_free_device(brd);
 	return err;
 }
 
@@ -389,8 +415,7 @@
 		del_gendisk(brd->brd_disk);
 		put_disk(brd->brd_disk);
 		brd_free_pages(brd);
-		list_del(&brd->brd_list);
-		kfree(brd);
+		brd_free_device(brd);
 	}
 }
 
@@ -417,16 +442,6 @@
 {
 	int err, i;
 
-	brd_check_and_reset_par();
-
-	brd_debugfs_dir = debugfs_create_dir("ramdisk_pages", NULL);
-
-	for (i = 0; i < rd_nr; i++) {
-		err = brd_alloc(i);
-		if (err)
-			goto out_free;
-	}
-
 	/*
 	 * brd module now has a feature to instantiate underlying device
 	 * structure on-demand, provided that there is an access dev node.
@@ -442,11 +457,18 @@
 	 *	dynamically.
 	 */
 
+	brd_check_and_reset_par();
+
+	brd_debugfs_dir = debugfs_create_dir("ramdisk_pages", NULL);
+
 	if (__register_blkdev(RAMDISK_MAJOR, "ramdisk", brd_probe)) {
 		err = -EIO;
 		goto out_free;
 	}
 
+	for (i = 0; i < rd_nr; i++)
+		brd_alloc(i);
+
 	pr_info("brd: module loaded\n");
 	return 0;
 
--- linux-qcom-6.8.0.orig/drivers/block/drbd/drbd_main.c
+++ linux-qcom-6.8.0/drivers/block/drbd/drbd_main.c
@@ -1550,7 +1550,7 @@
 	 * put_page(); and would cause either a VM_BUG directly, or
 	 * __page_cache_release a page that would actually still be referenced
 	 * by someone, leading to some obscure delayed Oops somewhere else. */
-	if (!drbd_disable_sendpage && sendpage_ok(page))
+	if (!drbd_disable_sendpage && sendpages_ok(page, len, offset))
 		msg.msg_flags |= MSG_NOSIGNAL | MSG_SPLICE_PAGES;
 
 	drbd_update_congested(peer_device->connection);
@@ -3392,10 +3392,12 @@
 void drbd_uuid_set_bm(struct drbd_device *device, u64 val) __must_hold(local)
 {
 	unsigned long flags;
-	if (device->ldev->md.uuid[UI_BITMAP] == 0 && val == 0)
+	spin_lock_irqsave(&device->ldev->md.uuid_lock, flags);
+	if (device->ldev->md.uuid[UI_BITMAP] == 0 && val == 0) {
+		spin_unlock_irqrestore(&device->ldev->md.uuid_lock, flags);
 		return;
+	}
 
-	spin_lock_irqsave(&device->ldev->md.uuid_lock, flags);
 	if (val == 0) {
 		drbd_uuid_move_history(device);
 		device->ldev->md.uuid[UI_HISTORY_START] = device->ldev->md.uuid[UI_BITMAP];
--- linux-qcom-6.8.0.orig/drivers/block/drbd/drbd_state.c
+++ linux-qcom-6.8.0/drivers/block/drbd/drbd_state.c
@@ -876,7 +876,7 @@
 		  ns.disk == D_OUTDATED)
 		rv = SS_CONNECTED_OUTDATES;
 
-	else if ((ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
+	else if (nc && (ns.conn == C_VERIFY_S || ns.conn == C_VERIFY_T) &&
 		 (nc->verify_alg[0] == 0))
 		rv = SS_NO_VERIFY_ALG;
 
--- linux-qcom-6.8.0.orig/drivers/block/loop.c
+++ linux-qcom-6.8.0/drivers/block/loop.c
@@ -211,13 +211,10 @@
 	if (lo->lo_state == Lo_bound)
 		blk_mq_freeze_queue(lo->lo_queue);
 	lo->use_dio = use_dio;
-	if (use_dio) {
-		blk_queue_flag_clear(QUEUE_FLAG_NOMERGES, lo->lo_queue);
+	if (use_dio)
 		lo->lo_flags |= LO_FLAGS_DIRECT_IO;
-	} else {
-		blk_queue_flag_set(QUEUE_FLAG_NOMERGES, lo->lo_queue);
+	else
 		lo->lo_flags &= ~LO_FLAGS_DIRECT_IO;
-	}
 	if (lo->lo_state == Lo_bound)
 		blk_mq_unfreeze_queue(lo->lo_queue);
 }
@@ -2036,14 +2033,6 @@
 	blk_queue_max_hw_sectors(lo->lo_queue, 2560u);
 
 	/*
-	 * By default, we do buffer IO, so it doesn't make sense to enable
-	 * merge because the I/O submitted to backing file is handled page by
-	 * page. For directio mode, merge does help to dispatch bigger request
-	 * to underlayer disk. We will enable merge once directio is enabled.
-	 */
-	blk_queue_flag_set(QUEUE_FLAG_NOMERGES, lo->lo_queue);
-
-	/*
 	 * Disable partition scanning by default. The in-kernel partition
 	 * scanning can be requested individually per-device during its
 	 * setup. Userspace can always add and remove partitions from all
--- linux-qcom-6.8.0.orig/drivers/block/nbd.c
+++ linux-qcom-6.8.0/drivers/block/nbd.c
@@ -181,6 +181,17 @@
 {
 	struct request *req = blk_mq_rq_from_pdu(cmd);
 
+	lockdep_assert_held(&cmd->lock);
+
+	/*
+	 * Clear INFLIGHT flag so that this cmd won't be completed in
+	 * normal completion path
+	 *
+	 * INFLIGHT flag will be set when the cmd is queued to nbd next
+	 * time.
+	 */
+	__clear_bit(NBD_CMD_INFLIGHT, &cmd->flags);
+
 	if (!test_and_set_bit(NBD_CMD_REQUEUED, &cmd->flags))
 		blk_mq_requeue_request(req, true);
 }
@@ -459,8 +470,8 @@
 					nbd_mark_nsock_dead(nbd, nsock, 1);
 				mutex_unlock(&nsock->tx_lock);
 			}
-			mutex_unlock(&cmd->lock);
 			nbd_requeue_cmd(cmd);
+			mutex_unlock(&cmd->lock);
 			nbd_config_put(nbd);
 			return BLK_EH_DONE;
 		}
@@ -567,7 +578,10 @@
 	return result == -ERESTARTSYS || result == -EINTR;
 }
 
-/* always call with the tx_lock held */
+/*
+ * Returns BLK_STS_RESOURCE if the caller should retry after a delay. Returns
+ * -EAGAIN if the caller should requeue @cmd. Returns -EIO if sending failed.
+ */
 static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index)
 {
 	struct request *req = blk_mq_rq_from_pdu(cmd);
@@ -584,6 +598,9 @@
 	u32 nbd_cmd_flags = 0;
 	int sent = nsock->sent, skip = 0;
 
+	lockdep_assert_held(&cmd->lock);
+	lockdep_assert_held(&nsock->tx_lock);
+
 	iov_iter_kvec(&from, ITER_SOURCE, &iov, 1, sizeof(request));
 
 	type = req_to_nbd_cmd_type(req);
@@ -648,7 +665,7 @@
 				nsock->sent = sent;
 			}
 			set_bit(NBD_CMD_REQUEUED, &cmd->flags);
-			return BLK_STS_RESOURCE;
+			return (__force int)BLK_STS_RESOURCE;
 		}
 		dev_err_ratelimited(disk_to_dev(nbd->disk),
 			"Send control failed (result %d)\n", result);
@@ -689,7 +706,7 @@
 					nsock->pending = req;
 					nsock->sent = sent;
 					set_bit(NBD_CMD_REQUEUED, &cmd->flags);
-					return BLK_STS_RESOURCE;
+					return (__force int)BLK_STS_RESOURCE;
 				}
 				dev_err(disk_to_dev(nbd->disk),
 					"Send data failed (result %d)\n",
@@ -986,7 +1003,7 @@
 	return !test_bit(NBD_RT_DISCONNECTED, &config->runtime_flags);
 }
 
-static int nbd_handle_cmd(struct nbd_cmd *cmd, int index)
+static blk_status_t nbd_handle_cmd(struct nbd_cmd *cmd, int index)
 {
 	struct request *req = blk_mq_rq_from_pdu(cmd);
 	struct nbd_device *nbd = cmd->nbd;
@@ -994,18 +1011,20 @@
 	struct nbd_sock *nsock;
 	int ret;
 
+	lockdep_assert_held(&cmd->lock);
+
 	config = nbd_get_config_unlocked(nbd);
 	if (!config) {
 		dev_err_ratelimited(disk_to_dev(nbd->disk),
 				    "Socks array is empty\n");
-		return -EINVAL;
+		return BLK_STS_IOERR;
 	}
 
 	if (index >= config->num_connections) {
 		dev_err_ratelimited(disk_to_dev(nbd->disk),
 				    "Attempted send on invalid socket\n");
 		nbd_config_put(nbd);
-		return -EINVAL;
+		return BLK_STS_IOERR;
 	}
 	cmd->status = BLK_STS_OK;
 again:
@@ -1028,7 +1047,7 @@
 			 */
 			sock_shutdown(nbd);
 			nbd_config_put(nbd);
-			return -EIO;
+			return BLK_STS_IOERR;
 		}
 		goto again;
 	}
@@ -1041,7 +1060,7 @@
 	blk_mq_start_request(req);
 	if (unlikely(nsock->pending && nsock->pending != req)) {
 		nbd_requeue_cmd(cmd);
-		ret = 0;
+		ret = BLK_STS_OK;
 		goto out;
 	}
 	/*
@@ -1060,19 +1079,19 @@
 				    "Request send failed, requeueing\n");
 		nbd_mark_nsock_dead(nbd, nsock, 1);
 		nbd_requeue_cmd(cmd);
-		ret = 0;
+		ret = BLK_STS_OK;
 	}
 out:
 	mutex_unlock(&nsock->tx_lock);
 	nbd_config_put(nbd);
-	return ret;
+	return ret < 0 ? BLK_STS_IOERR : (__force blk_status_t)ret;
 }
 
 static blk_status_t nbd_queue_rq(struct blk_mq_hw_ctx *hctx,
 			const struct blk_mq_queue_data *bd)
 {
 	struct nbd_cmd *cmd = blk_mq_rq_to_pdu(bd->rq);
-	int ret;
+	blk_status_t ret;
 
 	/*
 	 * Since we look at the bio's to send the request over the network we
@@ -1092,10 +1111,6 @@
 	 * appropriate.
 	 */
 	ret = nbd_handle_cmd(cmd, hctx->queue_num);
-	if (ret < 0)
-		ret = BLK_STS_IOERR;
-	else if (!ret)
-		ret = BLK_STS_OK;
 	mutex_unlock(&cmd->lock);
 
 	return ret;
@@ -2145,6 +2160,7 @@
 	flush_workqueue(nbd->recv_workq);
 	nbd_clear_que(nbd);
 	nbd->task_setup = NULL;
+	clear_bit(NBD_RT_BOUND, &nbd->config->runtime_flags);
 	mutex_unlock(&nbd->config_lock);
 
 	if (test_and_clear_bit(NBD_RT_HAS_CONFIG_REF,
@@ -2433,6 +2449,12 @@
 	}
 
 	dev_list = nla_nest_start_noflag(reply, NBD_ATTR_DEVICE_LIST);
+	if (!dev_list) {
+		nlmsg_free(reply);
+		ret = -EMSGSIZE;
+		goto out;
+	}
+
 	if (index == -1) {
 		ret = idr_for_each(&nbd_index_idr, &status_cb, reply);
 		if (ret) {
--- linux-qcom-6.8.0.orig/drivers/block/null_blk/main.c
+++ linux-qcom-6.8.0/drivers/block/null_blk/main.c
@@ -392,13 +392,25 @@
 static int nullb_apply_submit_queues(struct nullb_device *dev,
 				     unsigned int submit_queues)
 {
-	return nullb_update_nr_hw_queues(dev, submit_queues, dev->poll_queues);
+	int ret;
+
+	mutex_lock(&lock);
+	ret = nullb_update_nr_hw_queues(dev, submit_queues, dev->poll_queues);
+	mutex_unlock(&lock);
+
+	return ret;
 }
 
 static int nullb_apply_poll_queues(struct nullb_device *dev,
 				   unsigned int poll_queues)
 {
-	return nullb_update_nr_hw_queues(dev, dev->submit_queues, poll_queues);
+	int ret;
+
+	mutex_lock(&lock);
+	ret = nullb_update_nr_hw_queues(dev, dev->submit_queues, poll_queues);
+	mutex_unlock(&lock);
+
+	return ret;
 }
 
 NULLB_DEVICE_ATTR(size, ulong, NULL);
@@ -444,28 +456,32 @@
 	if (ret < 0)
 		return ret;
 
+	ret = count;
+	mutex_lock(&lock);
 	if (!dev->power && newp) {
 		if (test_and_set_bit(NULLB_DEV_FL_UP, &dev->flags))
-			return count;
+			goto out;
+
 		ret = null_add_dev(dev);
 		if (ret) {
 			clear_bit(NULLB_DEV_FL_UP, &dev->flags);
-			return ret;
+			goto out;
 		}
 
 		set_bit(NULLB_DEV_FL_CONFIGURED, &dev->flags);
 		dev->power = newp;
+		ret = count;
 	} else if (dev->power && !newp) {
 		if (test_and_clear_bit(NULLB_DEV_FL_UP, &dev->flags)) {
-			mutex_lock(&lock);
 			dev->power = newp;
 			null_del_dev(dev->nullb);
-			mutex_unlock(&lock);
 		}
 		clear_bit(NULLB_DEV_FL_CONFIGURED, &dev->flags);
 	}
 
-	return count;
+out:
+	mutex_unlock(&lock);
+	return ret;
 }
 
 CONFIGFS_ATTR(nullb_device_, power);
@@ -2033,8 +2049,8 @@
 		return -EINVAL;
 	}
 
-	dev->blocksize = round_down(dev->blocksize, 512);
-	dev->blocksize = clamp_t(unsigned int, dev->blocksize, 512, 4096);
+	if (blk_validate_block_size(dev->blocksize))
+		return -EINVAL;
 
 	if (dev->queue_mode == NULL_Q_MQ && dev->use_per_node_hctx) {
 		if (dev->submit_queues != nr_online_nodes)
@@ -2173,15 +2189,12 @@
 	nullb->q->queuedata = nullb;
 	blk_queue_flag_set(QUEUE_FLAG_NONROT, nullb->q);
 
-	mutex_lock(&lock);
 	rv = ida_alloc(&nullb_indexes, GFP_KERNEL);
-	if (rv < 0) {
-		mutex_unlock(&lock);
+	if (rv < 0)
 		goto out_cleanup_zone;
-	}
+
 	nullb->index = rv;
 	dev->index = rv;
-	mutex_unlock(&lock);
 
 	blk_queue_logical_block_size(nullb->q, dev->blocksize);
 	blk_queue_physical_block_size(nullb->q, dev->blocksize);
@@ -2205,9 +2218,7 @@
 	if (rv)
 		goto out_ida_free;
 
-	mutex_lock(&lock);
 	list_add_tail(&nullb->list, &nullb_list);
-	mutex_unlock(&lock);
 
 	pr_info("disk %s created\n", nullb->disk_name);
 
@@ -2256,7 +2267,9 @@
 	if (!dev)
 		return -ENOMEM;
 
+	mutex_lock(&lock);
 	ret = null_add_dev(dev);
+	mutex_unlock(&lock);
 	if (ret) {
 		null_free_dev(dev);
 		return ret;
@@ -2372,10 +2385,13 @@
 
 	if (g_queue_mode == NULL_Q_MQ && shared_tags)
 		blk_mq_free_tag_set(&tag_set);
+
+	mutex_destroy(&lock);
 }
 
 module_init(null_init);
 module_exit(null_exit);
 
 MODULE_AUTHOR("Jens Axboe <axboe@kernel.dk>");
+MODULE_DESCRIPTION("multi queue aware block test driver");
 MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/block/null_blk/zoned.c
+++ linux-qcom-6.8.0/drivers/block/null_blk/zoned.c
@@ -83,6 +83,17 @@
 		return -EINVAL;
 	}
 
+	/*
+	 * If a smaller zone capacity was requested, do not allow a smaller last
+	 * zone at the same time as such zone configuration does not correspond
+	 * to any real zoned device.
+	 */
+	if (dev->zone_capacity != dev->zone_size &&
+	    dev->size & (dev->zone_size - 1)) {
+		pr_err("A smaller last zone is not allowed with zone capacity smaller than zone size.\n");
+		return -EINVAL;
+	}
+
 	zone_capacity_sects = mb_to_sects(dev->zone_capacity);
 	dev_capacity_sects = mb_to_sects(dev->size);
 	dev->zone_size_sects = mb_to_sects(dev->zone_size);
@@ -112,7 +123,7 @@
 	if (dev->zone_max_active && dev->zone_max_open > dev->zone_max_active) {
 		dev->zone_max_open = dev->zone_max_active;
 		pr_info("changed the maximum number of open zones to %u\n",
-			dev->nr_zones);
+			dev->zone_max_open);
 	} else if (dev->zone_max_open >= dev->nr_zones - dev->zone_nr_conv) {
 		dev->zone_max_open = 0;
 		pr_info("zone_max_open limit disabled, limit >= zone count\n");
--- linux-qcom-6.8.0.orig/drivers/block/rbd.c
+++ linux-qcom-6.8.0/drivers/block/rbd.c
@@ -89,7 +89,7 @@
 #define RBD_MINORS_PER_MAJOR		256
 #define RBD_SINGLE_MAJOR_PART_SHIFT	4
 
-#define RBD_MAX_PARENT_CHAIN_LEN	16
+#define RBD_MAX_PARENT_CHAIN_LEN	128
 
 #define RBD_SNAP_DEV_NAME_PREFIX	"snap_"
 #define RBD_MAX_SNAP_NAME_LEN	\
@@ -362,7 +362,7 @@
 enum rbd_lock_state {
 	RBD_LOCK_STATE_UNLOCKED,
 	RBD_LOCK_STATE_LOCKED,
-	RBD_LOCK_STATE_RELEASING,
+	RBD_LOCK_STATE_QUIESCING,
 };
 
 /* WatchNotify::ClientId */
@@ -422,7 +422,7 @@
 	struct list_head	running_list;
 	struct completion	acquire_wait;
 	int			acquire_err;
-	struct completion	releasing_wait;
+	struct completion	quiescing_wait;
 
 	spinlock_t		object_map_lock;
 	u8			*object_map;
@@ -525,7 +525,7 @@
 	lockdep_assert_held(&rbd_dev->lock_rwsem);
 
 	return rbd_dev->lock_state == RBD_LOCK_STATE_LOCKED ||
-	       rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING;
+	       rbd_dev->lock_state == RBD_LOCK_STATE_QUIESCING;
 }
 
 static bool rbd_is_lock_owner(struct rbd_device *rbd_dev)
@@ -3457,13 +3457,14 @@
 	lockdep_assert_held(&rbd_dev->lock_rwsem);
 	spin_lock(&rbd_dev->lock_lists_lock);
 	if (!list_empty(&img_req->lock_item)) {
+		rbd_assert(!list_empty(&rbd_dev->running_list));
 		list_del_init(&img_req->lock_item);
-		need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING &&
+		need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_QUIESCING &&
 			       list_empty(&rbd_dev->running_list));
 	}
 	spin_unlock(&rbd_dev->lock_lists_lock);
 	if (need_wakeup)
-		complete(&rbd_dev->releasing_wait);
+		complete(&rbd_dev->quiescing_wait);
 }
 
 static int rbd_img_exclusive_lock(struct rbd_img_request *img_req)
@@ -3476,11 +3477,6 @@
 	if (rbd_lock_add_request(img_req))
 		return 1;
 
-	if (rbd_dev->opts->exclusive) {
-		WARN_ON(1); /* lock got released? */
-		return -EROFS;
-	}
-
 	/*
 	 * Note the use of mod_delayed_work() in rbd_acquire_lock()
 	 * and cancel_delayed_work() in wake_lock_waiters().
@@ -4181,16 +4177,16 @@
 	/*
 	 * Ensure that all in-flight IO is flushed.
 	 */
-	rbd_dev->lock_state = RBD_LOCK_STATE_RELEASING;
-	rbd_assert(!completion_done(&rbd_dev->releasing_wait));
+	rbd_dev->lock_state = RBD_LOCK_STATE_QUIESCING;
+	rbd_assert(!completion_done(&rbd_dev->quiescing_wait));
 	if (list_empty(&rbd_dev->running_list))
 		return true;
 
 	up_write(&rbd_dev->lock_rwsem);
-	wait_for_completion(&rbd_dev->releasing_wait);
+	wait_for_completion(&rbd_dev->quiescing_wait);
 
 	down_write(&rbd_dev->lock_rwsem);
-	if (rbd_dev->lock_state != RBD_LOCK_STATE_RELEASING)
+	if (rbd_dev->lock_state != RBD_LOCK_STATE_QUIESCING)
 		return false;
 
 	rbd_assert(list_empty(&rbd_dev->running_list));
@@ -4601,6 +4597,10 @@
 			rbd_warn(rbd_dev, "failed to update lock cookie: %d",
 				 ret);
 
+		if (rbd_dev->opts->exclusive)
+			rbd_warn(rbd_dev,
+			     "temporarily releasing lock on exclusive mapping");
+
 		/*
 		 * Lock cookie cannot be updated on older OSDs, so do
 		 * a manual release and queue an acquire.
@@ -5382,7 +5382,7 @@
 	INIT_LIST_HEAD(&rbd_dev->acquiring_list);
 	INIT_LIST_HEAD(&rbd_dev->running_list);
 	init_completion(&rbd_dev->acquire_wait);
-	init_completion(&rbd_dev->releasing_wait);
+	init_completion(&rbd_dev->quiescing_wait);
 
 	spin_lock_init(&rbd_dev->object_map_lock);
 
@@ -6588,11 +6588,6 @@
 	if (ret)
 		return ret;
 
-	/*
-	 * The lock may have been released by now, unless automatic lock
-	 * transitions are disabled.
-	 */
-	rbd_assert(!rbd_dev->opts->exclusive || rbd_is_lock_owner(rbd_dev));
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/block/ublk_drv.c
+++ linux-qcom-6.8.0/drivers/block/ublk_drv.c
@@ -68,9 +68,6 @@
 	struct llist_node node;
 
 	struct kref ref;
-	__u64 sector;
-	__u32 operation;
-	__u32 nr_zones;
 };
 
 struct ublk_uring_cmd_pdu {
@@ -211,6 +208,33 @@
 
 #ifdef CONFIG_BLK_DEV_ZONED
 
+struct ublk_zoned_report_desc {
+	__u64 sector;
+	__u32 operation;
+	__u32 nr_zones;
+};
+
+static DEFINE_XARRAY(ublk_zoned_report_descs);
+
+static int ublk_zoned_insert_report_desc(const struct request *req,
+		struct ublk_zoned_report_desc *desc)
+{
+	return xa_insert(&ublk_zoned_report_descs, (unsigned long)req,
+			    desc, GFP_KERNEL);
+}
+
+static struct ublk_zoned_report_desc *ublk_zoned_erase_report_desc(
+		const struct request *req)
+{
+	return xa_erase(&ublk_zoned_report_descs, (unsigned long)req);
+}
+
+static struct ublk_zoned_report_desc *ublk_zoned_get_report_desc(
+		const struct request *req)
+{
+	return xa_load(&ublk_zoned_report_descs, (unsigned long)req);
+}
+
 static int ublk_get_nr_zones(const struct ublk_device *ub)
 {
 	const struct ublk_param_basic *p = &ub->params.basic;
@@ -317,7 +341,7 @@
 		unsigned int zones_in_request =
 			min_t(unsigned int, remaining_zones, max_zones_per_request);
 		struct request *req;
-		struct ublk_rq_data *pdu;
+		struct ublk_zoned_report_desc desc;
 		blk_status_t status;
 
 		memset(buffer, 0, buffer_length);
@@ -328,20 +352,23 @@
 			goto out;
 		}
 
-		pdu = blk_mq_rq_to_pdu(req);
-		pdu->operation = UBLK_IO_OP_REPORT_ZONES;
-		pdu->sector = sector;
-		pdu->nr_zones = zones_in_request;
+		desc.operation = UBLK_IO_OP_REPORT_ZONES;
+		desc.sector = sector;
+		desc.nr_zones = zones_in_request;
+		ret = ublk_zoned_insert_report_desc(req, &desc);
+		if (ret)
+			goto free_req;
 
 		ret = blk_rq_map_kern(disk->queue, req, buffer, buffer_length,
 					GFP_KERNEL);
-		if (ret) {
-			blk_mq_free_request(req);
-			goto out;
-		}
+		if (ret)
+			goto erase_desc;
 
 		status = blk_execute_rq(req, 0);
 		ret = blk_status_to_errno(status);
+erase_desc:
+		ublk_zoned_erase_report_desc(req);
+free_req:
 		blk_mq_free_request(req);
 		if (ret)
 			goto out;
@@ -375,7 +402,7 @@
 {
 	struct ublksrv_io_desc *iod = ublk_get_iod(ubq, req->tag);
 	struct ublk_io *io = &ubq->ios[req->tag];
-	struct ublk_rq_data *pdu = blk_mq_rq_to_pdu(req);
+	struct ublk_zoned_report_desc *desc;
 	u32 ublk_op;
 
 	switch (req_op(req)) {
@@ -398,12 +425,15 @@
 		ublk_op = UBLK_IO_OP_ZONE_RESET_ALL;
 		break;
 	case REQ_OP_DRV_IN:
-		ublk_op = pdu->operation;
+		desc = ublk_zoned_get_report_desc(req);
+		if (!desc)
+			return BLK_STS_IOERR;
+		ublk_op = desc->operation;
 		switch (ublk_op) {
 		case UBLK_IO_OP_REPORT_ZONES:
 			iod->op_flags = ublk_op | ublk_req_build_flags(req);
-			iod->nr_zones = pdu->nr_zones;
-			iod->start_sector = pdu->sector;
+			iod->nr_zones = desc->nr_zones;
+			iod->start_sector = desc->sector;
 			return BLK_STS_OK;
 		default:
 			return BLK_STS_IOERR;
@@ -680,12 +710,21 @@
 	return ublk_get_queue(ub, q_id)->io_cmd_buf;
 }
 
+static inline int __ublk_queue_cmd_buf_size(int depth)
+{
+	return round_up(depth * sizeof(struct ublksrv_io_desc), PAGE_SIZE);
+}
+
 static inline int ublk_queue_cmd_buf_size(struct ublk_device *ub, int q_id)
 {
 	struct ublk_queue *ubq = ublk_get_queue(ub, q_id);
 
-	return round_up(ubq->q_depth * sizeof(struct ublksrv_io_desc),
-			PAGE_SIZE);
+	return __ublk_queue_cmd_buf_size(ubq->q_depth);
+}
+
+static int ublk_max_cmd_buf_size(void)
+{
+	return __ublk_queue_cmd_buf_size(UBLK_MAX_QUEUE_DEPTH);
 }
 
 static inline bool ublk_queue_can_use_recovery_reissue(
@@ -1338,7 +1377,7 @@
 {
 	struct ublk_device *ub = filp->private_data;
 	size_t sz = vma->vm_end - vma->vm_start;
-	unsigned max_sz = UBLK_MAX_QUEUE_DEPTH * sizeof(struct ublksrv_io_desc);
+	unsigned max_sz = ublk_max_cmd_buf_size();
 	unsigned long pfn, end, phys_off = vma->vm_pgoff << PAGE_SHIFT;
 	int q_id, ret = 0;
 
@@ -1606,6 +1645,21 @@
 	blk_mq_kick_requeue_list(ub->ub_disk->queue);
 }
 
+static struct gendisk *ublk_detach_disk(struct ublk_device *ub)
+{
+	struct gendisk *disk;
+
+	/* Sync with ublk_abort_queue() by holding the lock */
+	spin_lock(&ub->lock);
+	disk = ub->ub_disk;
+	ub->dev_info.state = UBLK_S_DEV_DEAD;
+	ub->dev_info.ublksrv_pid = -1;
+	ub->ub_disk = NULL;
+	spin_unlock(&ub->lock);
+
+	return disk;
+}
+
 static void ublk_stop_dev(struct ublk_device *ub)
 {
 	struct gendisk *disk;
@@ -1619,14 +1673,7 @@
 		ublk_unquiesce_dev(ub);
 	}
 	del_gendisk(ub->ub_disk);
-
-	/* Sync with ublk_abort_queue() by holding the lock */
-	spin_lock(&ub->lock);
-	disk = ub->ub_disk;
-	ub->dev_info.state = UBLK_S_DEV_DEAD;
-	ub->dev_info.ublksrv_pid = -1;
-	ub->ub_disk = NULL;
-	spin_unlock(&ub->lock);
+	disk = ublk_detach_disk(ub);
 	put_disk(disk);
  unlock:
 	mutex_unlock(&ub->mutex);
@@ -2259,7 +2306,7 @@
 
 out_put_cdev:
 	if (ret) {
-		ub->dev_info.state = UBLK_S_DEV_DEAD;
+		ublk_detach_disk(ub);
 		ublk_put_device(ub);
 	}
 out_put_disk:
@@ -2354,10 +2401,19 @@
 	 * TODO: provide forward progress for RECOVERY handler, so that
 	 * unprivileged device can benefit from it
 	 */
-	if (info.flags & UBLK_F_UNPRIVILEGED_DEV)
+	if (info.flags & UBLK_F_UNPRIVILEGED_DEV) {
 		info.flags &= ~(UBLK_F_USER_RECOVERY_REISSUE |
 				UBLK_F_USER_RECOVERY);
 
+		/*
+		 * For USER_COPY, we depends on userspace to fill request
+		 * buffer by pwrite() to ublk char device, which can't be
+		 * used for unprivileged device
+		 */
+		if (info.flags & UBLK_F_USER_COPY)
+			return -EINVAL;
+	}
+
 	/* the created device is always owned by current user */
 	ublk_store_owner_uid_gid(&info.owner_uid, &info.owner_gid);
 
@@ -2666,6 +2722,8 @@
 	mutex_lock(&ub->mutex);
 	if (!ublk_can_use_recovery(ub))
 		goto out_unlock;
+	if (!ub->nr_queues_ready)
+		goto out_unlock;
 	/*
 	 * START_RECOVERY is only allowd after:
 	 *
@@ -2925,7 +2983,7 @@
 		ret = ublk_ctrl_end_recovery(ub, cmd);
 		break;
 	default:
-		ret = -ENOTSUPP;
+		ret = -EOPNOTSUPP;
 		break;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/block/virtio_blk.c
+++ linux-qcom-6.8.0/drivers/block/virtio_blk.c
@@ -471,18 +471,18 @@
 	return virtblk_prep_rq(req->mq_hctx, vblk, req, vbr) == BLK_STS_OK;
 }
 
-static bool virtblk_add_req_batch(struct virtio_blk_vq *vq,
+static void virtblk_add_req_batch(struct virtio_blk_vq *vq,
 					struct request **rqlist)
 {
+	struct request *req;
 	unsigned long flags;
-	int err;
 	bool kick;
 
 	spin_lock_irqsave(&vq->lock, flags);
 
-	while (!rq_list_empty(*rqlist)) {
-		struct request *req = rq_list_pop(rqlist);
+	while ((req = rq_list_pop(rqlist))) {
 		struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
+		int err;
 
 		err = virtblk_add_req(vq->vq, vbr);
 		if (err) {
@@ -495,37 +495,33 @@
 	kick = virtqueue_kick_prepare(vq->vq);
 	spin_unlock_irqrestore(&vq->lock, flags);
 
-	return kick;
+	if (kick)
+		virtqueue_notify(vq->vq);
 }
 
 static void virtio_queue_rqs(struct request **rqlist)
 {
-	struct request *req, *next, *prev = NULL;
+	struct request *submit_list = NULL;
 	struct request *requeue_list = NULL;
+	struct request **requeue_lastp = &requeue_list;
+	struct virtio_blk_vq *vq = NULL;
+	struct request *req;
 
-	rq_list_for_each_safe(rqlist, req, next) {
-		struct virtio_blk_vq *vq = get_virtio_blk_vq(req->mq_hctx);
-		bool kick;
-
-		if (!virtblk_prep_rq_batch(req)) {
-			rq_list_move(rqlist, &requeue_list, req, prev);
-			req = prev;
-			if (!req)
-				continue;
-		}
+	while ((req = rq_list_pop(rqlist))) {
+		struct virtio_blk_vq *this_vq = get_virtio_blk_vq(req->mq_hctx);
 
-		if (!next || req->mq_hctx != next->mq_hctx) {
-			req->rq_next = NULL;
-			kick = virtblk_add_req_batch(vq, rqlist);
-			if (kick)
-				virtqueue_notify(vq->vq);
-
-			*rqlist = next;
-			prev = NULL;
-		} else
-			prev = req;
+		if (vq && vq != this_vq)
+			virtblk_add_req_batch(vq, &submit_list);
+		vq = this_vq;
+
+		if (virtblk_prep_rq_batch(req))
+			rq_list_add(&submit_list, req); /* reverse order */
+		else
+			rq_list_add_tail(&requeue_lastp, req);
 	}
 
+	if (vq)
+		virtblk_add_req_batch(vq, &submit_list);
 	*rqlist = requeue_list;
 }
 
@@ -1592,9 +1588,12 @@
 static int virtblk_freeze(struct virtio_device *vdev)
 {
 	struct virtio_blk *vblk = vdev->priv;
+	struct request_queue *q = vblk->disk->queue;
 
 	/* Ensure no requests in virtqueues before deleting vqs. */
-	blk_mq_freeze_queue(vblk->disk->queue);
+	blk_mq_freeze_queue(q);
+	blk_mq_quiesce_queue_nowait(q);
+	blk_mq_unfreeze_queue(q);
 
 	/* Ensure we don't receive any more interrupts */
 	virtio_reset_device(vdev);
@@ -1618,8 +1617,8 @@
 		return ret;
 
 	virtio_device_ready(vdev);
+	blk_mq_unquiesce_queue(vblk->disk->queue);
 
-	blk_mq_unfreeze_queue(vblk->disk->queue);
 	return 0;
 }
 #endif
--- linux-qcom-6.8.0.orig/drivers/block/zram/zram_drv.c
+++ linux-qcom-6.8.0/drivers/block/zram/zram_drv.c
@@ -297,17 +297,30 @@
 		/*
 		 * Do not mark ZRAM_UNDER_WB slot as ZRAM_IDLE to close race.
 		 * See the comment in writeback_store.
+		 *
+		 * Also do not mark ZRAM_SAME slots as ZRAM_IDLE, because no
+		 * post-processing (recompress, writeback) happens to the
+		 * ZRAM_SAME slot.
+		 *
+		 * And ZRAM_WB slots simply cannot be ZRAM_IDLE.
 		 */
 		zram_slot_lock(zram, index);
-		if (zram_allocated(zram, index) &&
-				!zram_test_flag(zram, index, ZRAM_UNDER_WB)) {
+		if (!zram_allocated(zram, index) ||
+		    zram_test_flag(zram, index, ZRAM_WB) ||
+		    zram_test_flag(zram, index, ZRAM_UNDER_WB) ||
+		    zram_test_flag(zram, index, ZRAM_SAME)) {
+			zram_slot_unlock(zram, index);
+			continue;
+		}
+
 #ifdef CONFIG_ZRAM_TRACK_ENTRY_ACTIME
-			is_idle = !cutoff || ktime_after(cutoff,
-							 zram->table[index].ac_time);
+		is_idle = !cutoff ||
+			ktime_after(cutoff, zram->table[index].ac_time);
 #endif
-			if (is_idle)
-				zram_set_flag(zram, index, ZRAM_IDLE);
-		}
+		if (is_idle)
+			zram_set_flag(zram, index, ZRAM_IDLE);
+		else
+			zram_clear_flag(zram, index, ZRAM_IDLE);
 		zram_slot_unlock(zram, index);
 	}
 }
@@ -522,6 +535,12 @@
 	}
 
 	nr_pages = i_size_read(inode) >> PAGE_SHIFT;
+	/* Refuse to use zero sized device (also prevents self reference) */
+	if (!nr_pages) {
+		err = -EINVAL;
+		goto out;
+	}
+
 	bitmap_sz = BITS_TO_LONGS(nr_pages) * sizeof(long);
 	bitmap = kvzalloc(bitmap_sz, GFP_KERNEL);
 	if (!bitmap) {
@@ -640,6 +659,12 @@
 		goto release_init_lock;
 	}
 
+	/* Do not permit concurrent post-processing actions. */
+	if (atomic_xchg(&zram->pp_in_progress, 1)) {
+		up_read(&zram->init_lock);
+		return -EAGAIN;
+	}
+
 	if (!zram->backing_dev) {
 		ret = -ENODEV;
 		goto release_init_lock;
@@ -766,6 +791,7 @@
 		free_block_bdev(zram, blk_idx);
 	__free_page(page);
 release_init_lock:
+	atomic_set(&zram->pp_in_progress, 0);
 	up_read(&zram->init_lock);
 
 	return ret;
@@ -1216,12 +1242,16 @@
 	size_t num_pages = disksize >> PAGE_SHIFT;
 	size_t index;
 
+	if (!zram->table)
+		return;
+
 	/* Free all pages that are still in this zram device */
 	for (index = 0; index < num_pages; index++)
 		zram_free_page(zram, index);
 
 	zs_destroy_pool(zram->mem_pool);
 	vfree(zram->table);
+	zram->table = NULL;
 }
 
 static bool zram_meta_alloc(struct zram *zram, u64 disksize)
@@ -1236,6 +1266,7 @@
 	zram->mem_pool = zs_create_pool(zram->disk->disk_name);
 	if (!zram->mem_pool) {
 		vfree(zram->table);
+		zram->table = NULL;
 		return false;
 	}
 
@@ -1596,6 +1627,13 @@
 	if (ret)
 		return ret;
 
+	/*
+	 * We touched this entry so mark it as non-IDLE. This makes sure that
+	 * we don't preserve IDLE flag and don't incorrectly pick this entry
+	 * for different post-processing type (e.g. writeback).
+	 */
+	zram_clear_flag(zram, index, ZRAM_IDLE);
+
 	class_index_old = zs_lookup_class_index(zram->mem_pool, comp_len_old);
 	/*
 	 * Iterate the secondary comp algorithms list (in order of priority)
@@ -1758,6 +1796,12 @@
 		goto release_init_lock;
 	}
 
+	/* Do not permit concurrent post-processing actions. */
+	if (atomic_xchg(&zram->pp_in_progress, 1)) {
+		up_read(&zram->init_lock);
+		return -EAGAIN;
+	}
+
 	if (algo) {
 		bool found = false;
 
@@ -1822,6 +1866,7 @@
 	__free_page(page);
 
 release_init_lock:
+	atomic_set(&zram->pp_in_progress, 0);
 	up_read(&zram->init_lock);
 	return ret;
 }
@@ -1979,6 +2024,13 @@
 		zcomp_destroy(comp);
 		zram->num_active_comps--;
 	}
+
+	for (prio = ZRAM_PRIMARY_COMP; prio < ZRAM_MAX_COMPS; prio++) {
+		/* Do not free statically defined compression algorithms */
+		if (zram->comp_algs[prio] != default_compressor)
+			kfree(zram->comp_algs[prio]);
+		zram->comp_algs[prio] = NULL;
+	}
 }
 
 static void zram_reset_device(struct zram *zram)
@@ -1987,11 +2039,6 @@
 
 	zram->limit_pages = 0;
 
-	if (!init_done(zram)) {
-		up_write(&zram->init_lock);
-		return;
-	}
-
 	set_capacity_and_notify(zram->disk, 0);
 	part_stat_set_all(zram->disk->part0, 0);
 
@@ -2000,6 +2047,7 @@
 	zram->disksize = 0;
 	zram_destroy_comps(zram);
 	memset(&zram->stats, 0, sizeof(zram->stats));
+	atomic_set(&zram->pp_in_progress, 0);
 	reset_bdev(zram);
 
 	comp_algorithm_set(zram, ZRAM_PRIMARY_COMP, default_compressor);
@@ -2210,6 +2258,8 @@
 	zram->disk->fops = &zram_devops;
 	zram->disk->private_data = zram;
 	snprintf(zram->disk->disk_name, 16, "zram%d", device_id);
+	atomic_set(&zram->pp_in_progress, 0);
+	comp_algorithm_set(zram, ZRAM_PRIMARY_COMP, default_compressor);
 
 	/* Actual capacity set using sysfs (/sys/block/zram<id>/disksize */
 	set_capacity(zram->disk, 0);
@@ -2244,8 +2294,6 @@
 	if (ret)
 		goto out_cleanup_disk;
 
-	comp_algorithm_set(zram, ZRAM_PRIMARY_COMP, default_compressor);
-
 	zram_debugfs_register(zram);
 	pr_info("Added device: %s\n", zram->disk->disk_name);
 	return device_id;
--- linux-qcom-6.8.0.orig/drivers/block/zram/zram_drv.h
+++ linux-qcom-6.8.0/drivers/block/zram/zram_drv.h
@@ -139,5 +139,6 @@
 #ifdef CONFIG_ZRAM_MEMORY_TRACKING
 	struct dentry *debugfs_dir;
 #endif
+	atomic_t pp_in_progress;
 };
 #endif
--- linux-qcom-6.8.0.orig/drivers/bluetooth/ath3k.c
+++ linux-qcom-6.8.0/drivers/bluetooth/ath3k.c
@@ -3,7 +3,6 @@
  * Copyright (c) 2008-2009 Atheros Communications Inc.
  */
 
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -128,7 +127,6 @@
  * for AR3012
  */
 static const struct usb_device_id ath3k_blist_tbl[] = {
-
 	/* Atheros AR3012 with sflash firmware*/
 	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
 	{ USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
@@ -202,7 +200,7 @@
 #define TIMEGAP_USEC_MAX	100
 
 static int ath3k_load_firmware(struct usb_device *udev,
-				const struct firmware *firmware)
+			       const struct firmware *firmware)
 {
 	u8 *send_buf;
 	int len = 0;
@@ -237,9 +235,9 @@
 		memcpy(send_buf, firmware->data + sent, size);
 
 		err = usb_bulk_msg(udev, pipe, send_buf, size,
-					&len, 3000);
+				   &len, 3000);
 
-		if (err || (len != size)) {
+		if (err || len != size) {
 			ath3k_log_failed_loading(err, len, size, count);
 			goto error;
 		}
@@ -262,7 +260,7 @@
 }
 
 static int ath3k_get_version(struct usb_device *udev,
-			struct ath3k_version *version)
+			     struct ath3k_version *version)
 {
 	return usb_control_msg_recv(udev, 0, ATH3K_GETVERSION,
 				    USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
@@ -271,7 +269,7 @@
 }
 
 static int ath3k_load_fwfile(struct usb_device *udev,
-		const struct firmware *firmware)
+			     const struct firmware *firmware)
 {
 	u8 *send_buf;
 	int len = 0;
@@ -310,8 +308,8 @@
 		memcpy(send_buf, firmware->data + sent, size);
 
 		err = usb_bulk_msg(udev, pipe, send_buf, size,
-					&len, 3000);
-		if (err || (len != size)) {
+				   &len, 3000);
+		if (err || len != size) {
 			ath3k_log_failed_loading(err, len, size, count);
 			kfree(send_buf);
 			return err;
@@ -425,7 +423,6 @@
 	}
 
 	switch (fw_version.ref_clock) {
-
 	case ATH3K_XTAL_FREQ_26M:
 		clk_value = 26;
 		break;
@@ -441,7 +438,7 @@
 	}
 
 	snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s",
-		le32_to_cpu(fw_version.rom_version), clk_value, ".dfu");
+		 le32_to_cpu(fw_version.rom_version), clk_value, ".dfu");
 
 	ret = request_firmware(&firmware, filename, &udev->dev);
 	if (ret < 0) {
@@ -456,7 +453,7 @@
 }
 
 static int ath3k_probe(struct usb_interface *intf,
-			const struct usb_device_id *id)
+		       const struct usb_device_id *id)
 {
 	const struct firmware *firmware;
 	struct usb_device *udev = interface_to_usbdev(intf);
@@ -505,10 +502,10 @@
 	if (ret < 0) {
 		if (ret == -ENOENT)
 			BT_ERR("Firmware file \"%s\" not found",
-							ATH3K_FIRMWARE);
+			       ATH3K_FIRMWARE);
 		else
 			BT_ERR("Firmware file \"%s\" request failed (err=%d)",
-							ATH3K_FIRMWARE, ret);
+			       ATH3K_FIRMWARE, ret);
 		return ret;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/bluetooth/btbcm.c
+++ linux-qcom-6.8.0/drivers/bluetooth/btbcm.c
@@ -540,13 +540,12 @@
 static const char *btbcm_get_board_name(struct device *dev)
 {
 #ifdef CONFIG_OF
-	struct device_node *root;
+	struct device_node *root __free(device_node) = of_find_node_by_path("/");
 	char *board_type;
 	const char *tmp;
 	int len;
 	int i;
 
-	root = of_find_node_by_path("/");
 	if (!root)
 		return NULL;
 
@@ -556,12 +555,14 @@
 	/* get rid of any '/' in the compatible string */
 	len = strlen(tmp) + 1;
 	board_type = devm_kzalloc(dev, len, GFP_KERNEL);
+	if (!board_type)
+		return NULL;
+
 	strscpy(board_type, tmp, len);
 	for (i = 0; i < len; i++) {
 		if (board_type[i] == '/')
 			board_type[i] = '-';
 	}
-	of_node_put(root);
 
 	return board_type;
 #else
--- linux-qcom-6.8.0.orig/drivers/bluetooth/btintel.c
+++ linux-qcom-6.8.0/drivers/bluetooth/btintel.c
@@ -26,21 +26,11 @@
 #define ECDSA_OFFSET		644
 #define ECDSA_HEADER_LEN	320
 
-#define BTINTEL_PPAG_NAME   "PPAG"
-
 enum {
 	DSM_SET_WDISABLE2_DELAY = 1,
 	DSM_SET_RESET_METHOD = 3,
 };
 
-/* structure to store the PPAG data read from ACPI table */
-struct btintel_ppag {
-	u32	domain;
-	u32     mode;
-	acpi_status status;
-	struct hci_dev *hdev;
-};
-
 #define CMD_WRITE_BOOT_PARAMS	0xfc0e
 struct cmd_write_boot_params {
 	__le32 boot_addr;
@@ -441,7 +431,7 @@
 		return PTR_ERR(skb);
 	}
 
-	if (skb->len != sizeof(*ver)) {
+	if (!skb || skb->len != sizeof(*ver)) {
 		bt_dev_err(hdev, "Intel version event size mismatch");
 		kfree_skb(skb);
 		return -EILSEQ;
@@ -1317,65 +1307,6 @@
 	return 0;
 }
 
-static acpi_status btintel_ppag_callback(acpi_handle handle, u32 lvl, void *data,
-					 void **ret)
-{
-	acpi_status status;
-	size_t len;
-	struct btintel_ppag *ppag = data;
-	union acpi_object *p, *elements;
-	struct acpi_buffer string = {ACPI_ALLOCATE_BUFFER, NULL};
-	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
-	struct hci_dev *hdev = ppag->hdev;
-
-	status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
-	if (ACPI_FAILURE(status)) {
-		bt_dev_warn(hdev, "PPAG-BT: ACPI Failure: %s", acpi_format_exception(status));
-		return status;
-	}
-
-	len = strlen(string.pointer);
-	if (len < strlen(BTINTEL_PPAG_NAME)) {
-		kfree(string.pointer);
-		return AE_OK;
-	}
-
-	if (strncmp((char *)string.pointer + len - 4, BTINTEL_PPAG_NAME, 4)) {
-		kfree(string.pointer);
-		return AE_OK;
-	}
-	kfree(string.pointer);
-
-	status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
-	if (ACPI_FAILURE(status)) {
-		ppag->status = status;
-		bt_dev_warn(hdev, "PPAG-BT: ACPI Failure: %s", acpi_format_exception(status));
-		return status;
-	}
-
-	p = buffer.pointer;
-	ppag = (struct btintel_ppag *)data;
-
-	if (p->type != ACPI_TYPE_PACKAGE || p->package.count != 2) {
-		kfree(buffer.pointer);
-		bt_dev_warn(hdev, "PPAG-BT: Invalid object type: %d or package count: %d",
-			    p->type, p->package.count);
-		ppag->status = AE_ERROR;
-		return AE_ERROR;
-	}
-
-	elements = p->package.elements;
-
-	/* PPAG table is located at element[1] */
-	p = &elements[1];
-
-	ppag->domain = (u32)p->package.elements[0].integer.value;
-	ppag->mode = (u32)p->package.elements[1].integer.value;
-	ppag->status = AE_OK;
-	kfree(buffer.pointer);
-	return AE_CTRL_TERMINATE;
-}
-
 static int btintel_set_debug_features(struct hci_dev *hdev,
 			       const struct intel_debug_features *features)
 {
@@ -2404,10 +2335,13 @@
 
 static void btintel_set_ppag(struct hci_dev *hdev, struct intel_version_tlv *ver)
 {
-	struct btintel_ppag ppag;
 	struct sk_buff *skb;
 	struct hci_ppag_enable_cmd ppag_cmd;
 	acpi_handle handle;
+	struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
+	union acpi_object *p, *elements;
+	u32 domain, mode;
+	acpi_status status;
 
 	/* PPAG is not supported if CRF is HrP2, Jfp2, JfP1 */
 	switch (ver->cnvr_top & 0xFFF) {
@@ -2425,22 +2359,34 @@
 		return;
 	}
 
-	memset(&ppag, 0, sizeof(ppag));
-
-	ppag.hdev = hdev;
-	ppag.status = AE_NOT_FOUND;
-	acpi_walk_namespace(ACPI_TYPE_PACKAGE, handle, 1, NULL,
-			    btintel_ppag_callback, &ppag, NULL);
-
-	if (ACPI_FAILURE(ppag.status)) {
-		if (ppag.status == AE_NOT_FOUND) {
+	status = acpi_evaluate_object(handle, "PPAG", NULL, &buffer);
+	if (ACPI_FAILURE(status)) {
+		if (status == AE_NOT_FOUND) {
 			bt_dev_dbg(hdev, "PPAG-BT: ACPI entry not found");
 			return;
 		}
+		bt_dev_warn(hdev, "PPAG-BT: ACPI Failure: %s", acpi_format_exception(status));
 		return;
 	}
 
-	if (ppag.domain != 0x12) {
+	p = buffer.pointer;
+	if (p->type != ACPI_TYPE_PACKAGE || p->package.count != 2) {
+		bt_dev_warn(hdev, "PPAG-BT: Invalid object type: %d or package count: %d",
+			    p->type, p->package.count);
+		kfree(buffer.pointer);
+		return;
+	}
+
+	elements = p->package.elements;
+
+	/* PPAG table is located at element[1] */
+	p = &elements[1];
+
+	domain = (u32)p->package.elements[0].integer.value;
+	mode = (u32)p->package.elements[1].integer.value;
+	kfree(buffer.pointer);
+
+	if (domain != 0x12) {
 		bt_dev_dbg(hdev, "PPAG-BT: Bluetooth domain is disabled in ACPI firmware");
 		return;
 	}
@@ -2451,19 +2397,22 @@
 	 * BIT 1 : 0 Disabled in China
 	 *         1 Enabled in China
 	 */
-	if ((ppag.mode & 0x01) != BIT(0) && (ppag.mode & 0x02) != BIT(1)) {
-		bt_dev_dbg(hdev, "PPAG-BT: EU, China mode are disabled in CB/BIOS");
+	mode &= 0x03;
+
+	if (!mode) {
+		bt_dev_dbg(hdev, "PPAG-BT: EU, China mode are disabled in BIOS");
 		return;
 	}
 
-	ppag_cmd.ppag_enable_flags = cpu_to_le32(ppag.mode);
+	ppag_cmd.ppag_enable_flags = cpu_to_le32(mode);
 
-	skb = __hci_cmd_sync(hdev, INTEL_OP_PPAG_CMD, sizeof(ppag_cmd), &ppag_cmd, HCI_CMD_TIMEOUT);
+	skb = __hci_cmd_sync(hdev, INTEL_OP_PPAG_CMD, sizeof(ppag_cmd),
+			     &ppag_cmd, HCI_CMD_TIMEOUT);
 	if (IS_ERR(skb)) {
 		bt_dev_warn(hdev, "Failed to send PPAG Enable (%ld)", PTR_ERR(skb));
 		return;
 	}
-	bt_dev_info(hdev, "PPAG-BT: Enabled (Mode %d)", ppag.mode);
+	bt_dev_info(hdev, "PPAG-BT: Enabled (Mode %d)", mode);
 	kfree_skb(skb);
 }
 
@@ -2771,9 +2720,6 @@
 					       INTEL_ROM_LEGACY_NO_WBS_SUPPORT))
 				set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
 					&hdev->quirks);
-			if (ver.hw_variant == 0x08 && ver.fw_variant == 0x22)
-				set_bit(HCI_QUIRK_VALID_LE_STATES,
-					&hdev->quirks);
 
 			err = btintel_legacy_rom_setup(hdev, &ver);
 			break;
@@ -2782,7 +2728,6 @@
 		case 0x12:      /* ThP */
 		case 0x13:      /* HrP */
 		case 0x14:      /* CcP */
-			set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
 			fallthrough;
 		case 0x0c:	/* WsP */
 			/* Apply the device specific HCI quirks
@@ -2869,9 +2814,6 @@
 		/* These variants don't seem to support LE Coded PHY */
 		set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks);
 
-		/* Set Valid LE States quirk */
-		set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
-
 		/* Setup MSFT Extension support */
 		btintel_set_msft_opcode(hdev, ver.hw_variant);
 
@@ -2892,15 +2834,15 @@
 		 */
 		set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
 
-		/* Apply LE States quirk from solar onwards */
-		set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
-
 		/* Setup MSFT Extension support */
 		btintel_set_msft_opcode(hdev,
 					INTEL_HW_VARIANT(ver_tlv.cnvi_bt));
 		btintel_set_dsm_reset_method(hdev, &ver_tlv);
 
 		err = btintel_bootloader_setup_tlv(hdev, &ver_tlv);
+		if (err)
+			goto exit_error;
+
 		btintel_register_devcoredump_support(hdev);
 		break;
 	default:
@@ -2981,13 +2923,12 @@
 	case INTEL_TLV_TEST_EXCEPTION:
 		/* Generate devcoredump from exception */
 		if (!hci_devcd_init(hdev, skb->len)) {
-			hci_devcd_append(hdev, skb);
+			hci_devcd_append(hdev, skb_clone(skb, GFP_ATOMIC));
 			hci_devcd_complete(hdev);
 		} else {
 			bt_dev_err(hdev, "Failed to generate devcoredump");
-			kfree_skb(skb);
 		}
-		return 0;
+	break;
 	default:
 		bt_dev_err(hdev, "Invalid exception type %02X", tlv->val[0]);
 	}
@@ -3014,7 +2955,8 @@
 				 * indicating that the bootup completed.
 				 */
 				btintel_bootup(hdev, ptr, len);
-				break;
+				kfree_skb(skb);
+				return 0;
 			case 0x06:
 				/* When the firmware loading completes the
 				 * device sends out a vendor specific event
@@ -3022,7 +2964,8 @@
 				 * loading.
 				 */
 				btintel_secure_send_result(hdev, ptr, len);
-				break;
+				kfree_skb(skb);
+				return 0;
 			}
 		}
 
--- linux-qcom-6.8.0.orig/drivers/bluetooth/btmrvl_main.c
+++ linux-qcom-6.8.0/drivers/bluetooth/btmrvl_main.c
@@ -121,13 +121,6 @@
 				((event->data[2] == MODULE_BROUGHT_UP) ||
 				(event->data[2] == MODULE_ALREADY_UP)) ?
 				"Bring-up succeed" : "Bring-up failed");
-
-			if (event->length > 3 && event->data[3])
-				priv->btmrvl_dev.dev_type = HCI_AMP;
-			else
-				priv->btmrvl_dev.dev_type = HCI_PRIMARY;
-
-			BT_DBG("dev_type: %d", priv->btmrvl_dev.dev_type);
 		} else if (priv->btmrvl_dev.sendcmdflag &&
 				event->data[1] == MODULE_SHUTDOWN_REQ) {
 			BT_DBG("EVENT:%s", (event->data[2]) ?
@@ -686,8 +679,6 @@
 	hdev->wakeup = btmrvl_wakeup;
 	SET_HCIDEV_DEV(hdev, &card->func->dev);
 
-	hdev->dev_type = priv->btmrvl_dev.dev_type;
-
 	ret = hci_register_dev(hdev);
 	if (ret < 0) {
 		BT_ERR("Can not register HCI device");
--- linux-qcom-6.8.0.orig/drivers/bluetooth/btmrvl_sdio.c
+++ linux-qcom-6.8.0/drivers/bluetooth/btmrvl_sdio.c
@@ -92,7 +92,7 @@
 		} else {
 			ret = devm_request_irq(dev, cfg->irq_bt,
 					       btmrvl_wake_irq_bt,
-					       0, "bt_wake", card);
+					       IRQF_NO_AUTOEN, "bt_wake", card);
 			if (ret) {
 				dev_err(dev,
 					"Failed to request irq_bt %d (%d)\n",
@@ -101,7 +101,6 @@
 
 			/* Configure wakeup (enabled by default) */
 			device_init_wakeup(dev, true);
-			disable_irq(cfg->irq_bt);
 		}
 	}
 
--- linux-qcom-6.8.0.orig/drivers/bluetooth/btmtk.c
+++ linux-qcom-6.8.0/drivers/bluetooth/btmtk.c
@@ -371,15 +371,20 @@
 {
 	struct btmediatek_data *data = hci_get_priv(hdev);
 	int err;
+	bool complete = false;
 
-	if (!IS_ENABLED(CONFIG_DEV_COREDUMP))
+	if (!IS_ENABLED(CONFIG_DEV_COREDUMP)) {
+		kfree_skb(skb);
 		return 0;
+	}
 
 	switch (data->cd_info.state) {
 	case HCI_DEVCOREDUMP_IDLE:
 		err = hci_devcd_init(hdev, MTK_COREDUMP_SIZE);
-		if (err < 0)
+		if (err < 0) {
+			kfree_skb(skb);
 			break;
+		}
 		data->cd_info.cnt = 0;
 
 		/* It is supposed coredump can be done within 5 seconds */
@@ -388,26 +393,26 @@
 		fallthrough;
 	case HCI_DEVCOREDUMP_ACTIVE:
 	default:
+		/* Mediatek coredump data would be more than MTK_COREDUMP_NUM */
+		if (data->cd_info.cnt >= MTK_COREDUMP_NUM &&
+		    skb->len > MTK_COREDUMP_END_LEN)
+			if (!memcmp((char *)&skb->data[skb->len - MTK_COREDUMP_END_LEN],
+				    MTK_COREDUMP_END, MTK_COREDUMP_END_LEN - 1))
+				complete = true;
+
 		err = hci_devcd_append(hdev, skb);
 		if (err < 0)
 			break;
 		data->cd_info.cnt++;
 
-		/* Mediatek coredump data would be more than MTK_COREDUMP_NUM */
-		if (data->cd_info.cnt > MTK_COREDUMP_NUM &&
-		    skb->len > MTK_COREDUMP_END_LEN)
-			if (!memcmp((char *)&skb->data[skb->len - MTK_COREDUMP_END_LEN],
-				    MTK_COREDUMP_END, MTK_COREDUMP_END_LEN - 1)) {
-				bt_dev_info(hdev, "Mediatek coredump end");
-				hci_devcd_complete(hdev);
-			}
+		if (complete) {
+			bt_dev_info(hdev, "Mediatek coredump end");
+			hci_devcd_complete(hdev);
+		}
 
 		break;
 	}
 
-	if (err < 0)
-		kfree_skb(skb);
-
 	return err;
 }
 EXPORT_SYMBOL_GPL(btmtk_process_coredump);
@@ -420,5 +425,6 @@
 MODULE_FIRMWARE(FIRMWARE_MT7622);
 MODULE_FIRMWARE(FIRMWARE_MT7663);
 MODULE_FIRMWARE(FIRMWARE_MT7668);
+MODULE_FIRMWARE(FIRMWARE_MT7922);
 MODULE_FIRMWARE(FIRMWARE_MT7961);
 MODULE_FIRMWARE(FIRMWARE_MT7925);
--- linux-qcom-6.8.0.orig/drivers/bluetooth/btmtk.h
+++ linux-qcom-6.8.0/drivers/bluetooth/btmtk.h
@@ -4,6 +4,7 @@
 #define FIRMWARE_MT7622		"mediatek/mt7622pr2h.bin"
 #define FIRMWARE_MT7663		"mediatek/mt7663pr2h.bin"
 #define FIRMWARE_MT7668		"mediatek/mt7668pr2h.bin"
+#define FIRMWARE_MT7922		"mediatek/BT_RAM_CODE_MT7922_1_1_hdr.bin"
 #define FIRMWARE_MT7961		"mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin"
 #define FIRMWARE_MT7925		"mediatek/mt7925/BT_RAM_CODE_MT7925_1_1_hdr.bin"
 
--- linux-qcom-6.8.0.orig/drivers/bluetooth/btmtksdio.c
+++ linux-qcom-6.8.0/drivers/bluetooth/btmtksdio.c
@@ -1144,9 +1144,6 @@
 			}
 		}
 
-		/* Valid LE States quirk for MediaTek 7921 */
-		set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
-
 		break;
 	case 0x7663:
 	case 0x7668:
--- linux-qcom-6.8.0.orig/drivers/bluetooth/btnxpuart.c
+++ linux-qcom-6.8.0/drivers/bluetooth/btnxpuart.c
@@ -29,6 +29,7 @@
 #define BTNXPUART_CHECK_BOOT_SIGNATURE	3
 #define BTNXPUART_SERDEV_OPEN		4
 #define BTNXPUART_IR_IN_PROGRESS	5
+#define BTNXPUART_FW_DOWNLOAD_ABORT	6
 
 /* NXP HW err codes */
 #define BTNXPUART_IR_HW_ERR		0xb0
@@ -126,6 +127,7 @@
 	struct hci_dev *hdev;
 	struct work_struct work;
 	struct timer_list ps_timer;
+	struct mutex ps_lock;
 };
 
 struct wakeup_cmd_payload {
@@ -158,6 +160,7 @@
 	u8 fw_name[MAX_FW_FILE_NAME_LEN];
 	u32 fw_dnld_v1_offset;
 	u32 fw_v1_sent_bytes;
+	u32 fw_dnld_v3_offset;
 	u32 fw_v3_offset_correction;
 	u32 fw_v1_expected_len;
 	u32 boot_reg_offset;
@@ -186,6 +189,11 @@
 #define NXP_NAK_V3		0x7b
 #define NXP_CRC_ERROR_V3	0x7c
 
+/* Bootloader signature error codes */
+#define NXP_ACK_RX_TIMEOUT	0x0002	/* ACK not received from host */
+#define NXP_HDR_RX_TIMEOUT	0x0003	/* FW Header chunk not received */
+#define NXP_DATA_RX_TIMEOUT	0x0004	/* FW Data chunk not received */
+
 #define HDR_LEN			16
 
 #define NXP_RECV_CHIP_VER_V1 \
@@ -276,11 +284,22 @@
 	__be32 crc;
 } __packed;
 
+struct nxp_v3_rx_timeout_nak {
+	u8 nak;
+	__le32 offset;
+	u8 crc;
+} __packed;
+
+union nxp_v3_rx_timeout_nak_u {
+	struct nxp_v3_rx_timeout_nak pkt;
+	u8 buf[6];
+};
+
 static u8 crc8_table[CRC8_TABLE_SIZE];
 
 /* Default configurations */
 #define DEFAULT_H2C_WAKEUP_MODE	WAKEUP_METHOD_BREAK
-#define DEFAULT_PS_MODE		PS_MODE_DISABLE
+#define DEFAULT_PS_MODE		PS_MODE_ENABLE
 #define FW_INIT_BAUDRATE	HCI_NXP_PRI_BAUDRATE
 
 static struct sk_buff *nxp_drv_send_cmd(struct hci_dev *hdev, u16 opcode,
@@ -317,6 +336,9 @@
 
 	if (psdata->cur_psmode == PS_MODE_ENABLE)
 		mod_timer(&psdata->ps_timer, jiffies + msecs_to_jiffies(psdata->h2c_ps_interval));
+
+	if (psdata->ps_state == PS_STATE_AWAKE && psdata->ps_cmd == PS_CMD_ENTER_PS)
+		cancel_work_sync(&psdata->work);
 }
 
 static void ps_cancel_timer(struct btnxpuart_dev *nxpdev)
@@ -324,7 +346,7 @@
 	struct ps_data *psdata = &nxpdev->psdata;
 
 	flush_work(&psdata->work);
-	del_timer_sync(&psdata->ps_timer);
+	timer_shutdown_sync(&psdata->ps_timer);
 }
 
 static void ps_control(struct hci_dev *hdev, u8 ps_state)
@@ -337,6 +359,7 @@
 	    !test_bit(BTNXPUART_SERDEV_OPEN, &nxpdev->tx_state))
 		return;
 
+	mutex_lock(&psdata->ps_lock);
 	switch (psdata->cur_h2c_wakeupmode) {
 	case WAKEUP_METHOD_DTR:
 		if (ps_state == PS_STATE_AWAKE)
@@ -350,12 +373,15 @@
 			status = serdev_device_break_ctl(nxpdev->serdev, 0);
 		else
 			status = serdev_device_break_ctl(nxpdev->serdev, -1);
+		msleep(20); /* Allow chip to detect UART-break and enter sleep */
 		bt_dev_dbg(hdev, "Set UART break: %s, status=%d",
 			   str_on_off(ps_state == PS_STATE_SLEEP), status);
 		break;
 	}
 	if (!status)
 		psdata->ps_state = ps_state;
+	mutex_unlock(&psdata->ps_lock);
+
 	if (ps_state == PS_STATE_AWAKE)
 		btnxpuart_tx_wakeup(nxpdev);
 }
@@ -391,17 +417,42 @@
 
 	psdata->hdev = hdev;
 	INIT_WORK(&psdata->work, ps_work_func);
+	mutex_init(&psdata->ps_lock);
 	timer_setup(&psdata->ps_timer, ps_timeout_func, 0);
 }
 
-static void ps_wakeup(struct btnxpuart_dev *nxpdev)
+static bool ps_wakeup(struct btnxpuart_dev *nxpdev)
 {
 	struct ps_data *psdata = &nxpdev->psdata;
+	u8 ps_state;
 
-	if (psdata->ps_state != PS_STATE_AWAKE) {
+	mutex_lock(&psdata->ps_lock);
+	ps_state = psdata->ps_state;
+	mutex_unlock(&psdata->ps_lock);
+
+	if (ps_state != PS_STATE_AWAKE) {
 		psdata->ps_cmd = PS_CMD_EXIT_PS;
 		schedule_work(&psdata->work);
+		return true;
 	}
+	return false;
+}
+
+static void ps_cleanup(struct btnxpuart_dev *nxpdev)
+{
+	struct ps_data *psdata = &nxpdev->psdata;
+	u8 ps_state;
+
+	mutex_lock(&psdata->ps_lock);
+	ps_state = psdata->ps_state;
+	mutex_unlock(&psdata->ps_lock);
+
+	if (ps_state != PS_STATE_AWAKE)
+		ps_control(psdata->hdev, PS_STATE_AWAKE);
+
+	ps_cancel_timer(nxpdev);
+	cancel_work_sync(&psdata->work);
+	mutex_destroy(&psdata->ps_lock);
 }
 
 static int send_ps_cmd(struct hci_dev *hdev, void *data)
@@ -534,6 +585,7 @@
 	nxpdev->fw_v1_sent_bytes = 0;
 	nxpdev->fw_v1_expected_len = HDR_LEN;
 	nxpdev->boot_reg_offset = 0;
+	nxpdev->fw_dnld_v3_offset = 0;
 	nxpdev->fw_v3_offset_correction = 0;
 	nxpdev->baudrate_changed = false;
 	nxpdev->timeout_changed = false;
@@ -548,14 +600,23 @@
 					       !test_bit(BTNXPUART_FW_DOWNLOADING,
 							 &nxpdev->tx_state),
 					       msecs_to_jiffies(60000));
+
+	release_firmware(nxpdev->fw);
+	memset(nxpdev->fw_name, 0, sizeof(nxpdev->fw_name));
+
 	if (err == 0) {
-		bt_dev_err(hdev, "FW Download Timeout.");
+		bt_dev_err(hdev, "FW Download Timeout. offset: %d",
+				nxpdev->fw_dnld_v1_offset ?
+				nxpdev->fw_dnld_v1_offset :
+				nxpdev->fw_dnld_v3_offset);
 		return -ETIMEDOUT;
 	}
+	if (test_bit(BTNXPUART_FW_DOWNLOAD_ABORT, &nxpdev->tx_state)) {
+		bt_dev_err(hdev, "FW Download Aborted");
+		return -EINTR;
+	}
 
 	serdev_device_set_flow_control(nxpdev->serdev, true);
-	release_firmware(nxpdev->fw);
-	memset(nxpdev->fw_name, 0, sizeof(nxpdev->fw_name));
 
 	/* Allow the downloaded FW to initialize */
 	msleep(1200);
@@ -883,6 +944,32 @@
 	return 0;
 }
 
+static void nxp_handle_fw_download_error(struct hci_dev *hdev, struct v3_data_req *req)
+{
+	struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
+	__u32 offset = __le32_to_cpu(req->offset);
+	__u16 err = __le16_to_cpu(req->error);
+	union nxp_v3_rx_timeout_nak_u nak_tx_buf;
+
+	switch (err) {
+	case NXP_ACK_RX_TIMEOUT:
+	case NXP_HDR_RX_TIMEOUT:
+	case NXP_DATA_RX_TIMEOUT:
+		nak_tx_buf.pkt.nak = NXP_NAK_V3;
+		nak_tx_buf.pkt.offset = __cpu_to_le32(offset);
+		nak_tx_buf.pkt.crc = crc8(crc8_table, nak_tx_buf.buf,
+				      sizeof(nak_tx_buf) - 1, 0xff);
+		serdev_device_write_buf(nxpdev->serdev, nak_tx_buf.buf,
+					sizeof(nak_tx_buf));
+		break;
+	default:
+		bt_dev_dbg(hdev, "Unknown bootloader error code: %d", err);
+		break;
+
+	}
+
+}
+
 static int nxp_recv_fw_req_v3(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
@@ -897,7 +984,12 @@
 	if (!req || !nxpdev->fw)
 		goto free_skb;
 
-	nxp_send_ack(NXP_ACK_V3, hdev);
+	if (!req->error) {
+		nxp_send_ack(NXP_ACK_V3, hdev);
+	} else {
+		nxp_handle_fw_download_error(hdev, req);
+		goto free_skb;
+	}
 
 	len = __le16_to_cpu(req->len);
 
@@ -924,9 +1016,6 @@
 		wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q);
 		goto free_skb;
 	}
-	if (req->error)
-		bt_dev_dbg(hdev, "FW Download received err 0x%02x from chip",
-			   req->error);
 
 	offset = __le32_to_cpu(req->offset);
 	if (offset < nxpdev->fw_v3_offset_correction) {
@@ -938,8 +1027,9 @@
 		goto free_skb;
 	}
 
-	serdev_device_write_buf(nxpdev->serdev, nxpdev->fw->data + offset -
-				nxpdev->fw_v3_offset_correction, len);
+	nxpdev->fw_dnld_v3_offset = offset - nxpdev->fw_v3_offset_correction;
+	serdev_device_write_buf(nxpdev->serdev, nxpdev->fw->data +
+				nxpdev->fw_dnld_v3_offset, len);
 
 free_skb:
 	kfree_skb(skb);
@@ -1171,7 +1261,6 @@
 {
 	struct btnxpuart_dev *nxpdev = (struct btnxpuart_dev *)data;
 
-	ps_wakeup(nxpdev);
 	ps_start_timer(nxpdev);
 	return skb_dequeue(&nxpdev->txq);
 }
@@ -1186,6 +1275,9 @@
 	struct sk_buff *skb;
 	int len;
 
+	if (ps_wakeup(nxpdev))
+		return;
+
 	while ((skb = nxp_dequeue(nxpdev))) {
 		len = serdev_device_write_buf(serdev, skb->data, skb->len);
 		hdev->stat.byte_tx += len;
@@ -1193,7 +1285,7 @@
 		skb_pull(skb, len);
 		if (skb->len > 0) {
 			skb_queue_head(&nxpdev->txq, skb);
-			break;
+			continue;
 		}
 
 		switch (hci_skb_pkt_type(skb)) {
@@ -1232,8 +1324,12 @@
 {
 	struct btnxpuart_dev *nxpdev = hci_get_drvdata(hdev);
 
-	ps_wakeup(nxpdev);
 	serdev_device_close(nxpdev->serdev);
+	skb_queue_purge(&nxpdev->txq);
+	if (!IS_ERR_OR_NULL(nxpdev->rx_skb)) {
+		kfree_skb(nxpdev->rx_skb);
+		nxpdev->rx_skb = NULL;
+	}
 	clear_bit(BTNXPUART_SERDEV_OPEN, &nxpdev->tx_state);
 	return 0;
 }
@@ -1248,8 +1344,10 @@
 
 	cancel_work_sync(&nxpdev->tx_work);
 
-	kfree_skb(nxpdev->rx_skb);
-	nxpdev->rx_skb = NULL;
+	if (!IS_ERR_OR_NULL(nxpdev->rx_skb)) {
+		kfree_skb(nxpdev->rx_skb);
+		nxpdev->rx_skb = NULL;
+	}
 
 	return 0;
 }
@@ -1364,16 +1462,22 @@
 	struct btnxpuart_dev *nxpdev = serdev_device_get_drvdata(serdev);
 	struct hci_dev *hdev = nxpdev->hdev;
 
-	/* Restore FW baudrate to fw_init_baudrate if changed.
-	 * This will ensure FW baudrate is in sync with
-	 * driver baudrate in case this driver is re-inserted.
-	 */
-	if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) {
-		nxpdev->new_baudrate = nxpdev->fw_init_baudrate;
-		nxp_set_baudrate_cmd(hdev, NULL);
+	if (is_fw_downloading(nxpdev)) {
+		set_bit(BTNXPUART_FW_DOWNLOAD_ABORT, &nxpdev->tx_state);
+		clear_bit(BTNXPUART_FW_DOWNLOADING, &nxpdev->tx_state);
+		wake_up_interruptible(&nxpdev->check_boot_sign_wait_q);
+		wake_up_interruptible(&nxpdev->fw_dnld_done_wait_q);
+	} else {
+		/* Restore FW baudrate to fw_init_baudrate if changed.
+		 * This will ensure FW baudrate is in sync with
+		 * driver baudrate in case this driver is re-inserted.
+		 */
+		if (nxpdev->current_baudrate != nxpdev->fw_init_baudrate) {
+			nxpdev->new_baudrate = nxpdev->fw_init_baudrate;
+			nxp_set_baudrate_cmd(hdev, NULL);
+		}
 	}
-
-	ps_cancel_timer(nxpdev);
+	ps_cleanup(nxpdev);
 	hci_unregister_dev(hdev);
 	hci_free_dev(hdev);
 }
--- linux-qcom-6.8.0.orig/drivers/bluetooth/btqca.c
+++ linux-qcom-6.8.0/drivers/bluetooth/btqca.c
@@ -13,8 +13,6 @@
 
 #include "btqca.h"
 
-#define VERSION "0.1"
-
 int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver,
 			 enum qca_btsoc_type soc_type)
 {
@@ -55,11 +53,6 @@
 	}
 
 	edl = (struct edl_event_hdr *)(skb->data);
-	if (!edl) {
-		bt_dev_err(hdev, "QCA TLV with no header");
-		err = -EILSEQ;
-		goto out;
-	}
 
 	if (edl->cresp != EDL_CMD_REQ_RES_EVT ||
 	    edl->rtype != rtype) {
@@ -99,7 +92,8 @@
 {
 	struct sk_buff *skb;
 	struct edl_event_hdr *edl;
-	char cmd, build_label[QCA_FW_BUILD_VER_LEN];
+	char *build_label;
+	char cmd;
 	int build_lbl_len, err = 0;
 
 	bt_dev_dbg(hdev, "QCA read fw build info");
@@ -114,13 +108,13 @@
 		return err;
 	}
 
-	edl = (struct edl_event_hdr *)(skb->data);
-	if (!edl) {
-		bt_dev_err(hdev, "QCA read fw build info with no header");
+	if (skb->len < sizeof(*edl)) {
 		err = -EILSEQ;
 		goto out;
 	}
 
+	edl = (struct edl_event_hdr *)(skb->data);
+
 	if (edl->cresp != EDL_CMD_REQ_RES_EVT ||
 	    edl->rtype != EDL_GET_BUILD_INFO_CMD) {
 		bt_dev_err(hdev, "QCA Wrong packet received %d %d", edl->cresp,
@@ -129,14 +123,27 @@
 		goto out;
 	}
 
+	if (skb->len < sizeof(*edl) + 1) {
+		err = -EILSEQ;
+		goto out;
+	}
+
 	build_lbl_len = edl->data[0];
-	if (build_lbl_len <= QCA_FW_BUILD_VER_LEN - 1) {
-		memcpy(build_label, edl->data + 1, build_lbl_len);
-		*(build_label + build_lbl_len) = '\0';
+
+	if (skb->len < sizeof(*edl) + 1 + build_lbl_len) {
+		err = -EILSEQ;
+		goto out;
+	}
+
+	build_label = kstrndup(&edl->data[1], build_lbl_len, GFP_KERNEL);
+	if (!build_label) {
+		err = -ENOMEM;
+		goto out;
 	}
 
 	hci_set_fw_info(hdev, "%s", build_label);
 
+	kfree(build_label);
 out:
 	kfree_skb(skb);
 	return err;
@@ -166,11 +173,6 @@
 	}
 
 	edl = (struct edl_event_hdr *)(skb->data);
-	if (!edl) {
-		bt_dev_err(hdev, "QCA Patch config with no header");
-		err = -EILSEQ;
-		goto out;
-	}
 
 	if (edl->cresp != EDL_PATCH_CONFIG_RES_EVT || edl->rtype != EDL_PATCH_CONFIG_CMD) {
 		bt_dev_err(hdev, "QCA Wrong packet received %d %d", edl->cresp,
@@ -235,6 +237,11 @@
 		goto out;
 	}
 
+	if (skb->len < 3) {
+		err = -EILSEQ;
+		goto out;
+	}
+
 	*bid = (edl->data[1] << 8) + edl->data[2];
 	bt_dev_dbg(hdev, "%s: bid = %x", __func__, *bid);
 
@@ -265,9 +272,43 @@
 }
 EXPORT_SYMBOL_GPL(qca_send_pre_shutdown_cmd);
 
-static void qca_tlv_check_data(struct hci_dev *hdev,
+static bool qca_filename_has_extension(const char *filename)
+{
+	const char *suffix = strrchr(filename, '.');
+
+	/* File extensions require a dot, but not as the first or last character */
+	if (!suffix || suffix == filename || *(suffix + 1) == '\0')
+		return 0;
+
+	/* Avoid matching directories with names that look like files with extensions */
+	return !strchr(suffix, '/');
+}
+
+static bool qca_get_alt_nvm_file(char *filename, size_t max_size)
+{
+	char fwname[64];
+	const char *suffix;
+
+	/* nvm file name has an extension, replace with .bin */
+	if (qca_filename_has_extension(filename)) {
+		suffix = strrchr(filename, '.');
+		strscpy(fwname, filename, suffix - filename + 1);
+		snprintf(fwname + (suffix - filename),
+		       sizeof(fwname) - (suffix - filename), ".bin");
+		/* If nvm file is already the default one, return false to skip the retry. */
+		if (strcmp(fwname, filename) == 0)
+			return false;
+
+		snprintf(filename, max_size, "%s", fwname);
+		return true;
+	}
+	return false;
+}
+
+static int qca_tlv_check_data(struct hci_dev *hdev,
 			       struct qca_fw_config *config,
-		u8 *fw_data, enum qca_btsoc_type soc_type)
+			       u8 *fw_data, size_t fw_size,
+			       enum qca_btsoc_type soc_type)
 {
 	const u8 *data;
 	u32 type_len;
@@ -277,12 +318,16 @@
 	struct tlv_type_patch *tlv_patch;
 	struct tlv_type_nvm *tlv_nvm;
 	uint8_t nvm_baud_rate = config->user_baud_rate;
+	u8 type;
 
 	config->dnld_mode = QCA_SKIP_EVT_NONE;
 	config->dnld_type = QCA_SKIP_EVT_NONE;
 
 	switch (config->type) {
 	case ELF_TYPE_PATCH:
+		if (fw_size < 7)
+			return -EINVAL;
+
 		config->dnld_mode = QCA_SKIP_EVT_VSE_CC;
 		config->dnld_type = QCA_SKIP_EVT_VSE_CC;
 
@@ -291,6 +336,9 @@
 		bt_dev_dbg(hdev, "File version      : 0x%x", fw_data[6]);
 		break;
 	case TLV_TYPE_PATCH:
+		if (fw_size < sizeof(struct tlv_type_hdr) + sizeof(struct tlv_type_patch))
+			return -EINVAL;
+
 		tlv = (struct tlv_type_hdr *)fw_data;
 		type_len = le32_to_cpu(tlv->type_len);
 		tlv_patch = (struct tlv_type_patch *)tlv->data;
@@ -330,25 +378,64 @@
 		break;
 
 	case TLV_TYPE_NVM:
+		if (fw_size < sizeof(struct tlv_type_hdr))
+			return -EINVAL;
+
 		tlv = (struct tlv_type_hdr *)fw_data;
 
 		type_len = le32_to_cpu(tlv->type_len);
-		length = (type_len >> 8) & 0x00ffffff;
+		length = type_len >> 8;
+		type = type_len & 0xff;
 
-		BT_DBG("TLV Type\t\t : 0x%x", type_len & 0x000000ff);
+		/* Some NVM files have more than one set of tags, only parse
+		 * the first set when it has type 2 for now. When there is
+		 * more than one set there is an enclosing header of type 4.
+		 */
+		if (type == 4) {
+			if (fw_size < 2 * sizeof(struct tlv_type_hdr))
+				return -EINVAL;
+
+			tlv++;
+
+			type_len = le32_to_cpu(tlv->type_len);
+			length = type_len >> 8;
+			type = type_len & 0xff;
+		}
+
+		BT_DBG("TLV Type\t\t : 0x%x", type);
 		BT_DBG("Length\t\t : %d bytes", length);
 
+		if (type != 2)
+			break;
+
+		if (fw_size < length + (tlv->data - fw_data))
+			return -EINVAL;
+
 		idx = 0;
 		data = tlv->data;
-		while (idx < length) {
+		while (idx < length - sizeof(struct tlv_type_nvm)) {
 			tlv_nvm = (struct tlv_type_nvm *)(data + idx);
 
 			tag_id = le16_to_cpu(tlv_nvm->tag_id);
 			tag_len = le16_to_cpu(tlv_nvm->tag_len);
 
+			if (length < idx + sizeof(struct tlv_type_nvm) + tag_len)
+				return -EINVAL;
+
 			/* Update NVM tags as needed */
 			switch (tag_id) {
+			case EDL_TAG_ID_BD_ADDR:
+				if (tag_len != sizeof(bdaddr_t))
+					return -EINVAL;
+
+				memcpy(&config->bdaddr, tlv_nvm->data, sizeof(bdaddr_t));
+
+				break;
+
 			case EDL_TAG_ID_HCI:
+				if (tag_len < 3)
+					return -EINVAL;
+
 				/* HCI transport layer parameters
 				 * enabling software inband sleep
 				 * onto controller side.
@@ -364,6 +451,9 @@
 				break;
 
 			case EDL_TAG_ID_DEEP_SLEEP:
+				if (tag_len < 1)
+					return -EINVAL;
+
 				/* Sleep enable mask
 				 * enabling deep sleep feature on controller.
 				 */
@@ -372,14 +462,16 @@
 				break;
 			}
 
-			idx += (sizeof(u16) + sizeof(u16) + 8 + tag_len);
+			idx += sizeof(struct tlv_type_nvm) + tag_len;
 		}
 		break;
 
 	default:
 		BT_ERR("Unknown TLV type %d", config->type);
-		break;
+		return -EINVAL;
 	}
+
+	return 0;
 }
 
 static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size,
@@ -428,11 +520,6 @@
 	}
 
 	edl = (struct edl_event_hdr *)(skb->data);
-	if (!edl) {
-		bt_dev_err(hdev, "TLV with no header");
-		err = -EILSEQ;
-		goto out;
-	}
 
 	if (edl->cresp != EDL_CMD_REQ_RES_EVT || edl->rtype != rtype) {
 		bt_dev_err(hdev, "QCA TLV with error stat 0x%x rtype 0x%x",
@@ -510,6 +597,19 @@
 					   config->fwname, ret);
 				return ret;
 			}
+		}
+		/* If the board-specific file is missing, try loading the default
+		 * one, unless that was attempted already.
+		 */
+		else if (config->type == TLV_TYPE_NVM &&
+			 qca_get_alt_nvm_file(config->fwname, sizeof(config->fwname))) {
+			bt_dev_info(hdev, "QCA Downloading %s", config->fwname);
+			ret = request_firmware(&fw, config->fwname, &hdev->dev);
+			if (ret) {
+				bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
+					   config->fwname, ret);
+				return ret;
+			}
 		} else {
 			bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
 				   config->fwname, ret);
@@ -529,7 +629,9 @@
 	memcpy(data, fw->data, size);
 	release_firmware(fw);
 
-	qca_tlv_check_data(hdev, config, data, soc_type);
+	ret = qca_tlv_check_data(hdev, config, data, size, soc_type);
+	if (ret)
+		goto out;
 
 	segment = data;
 	remain = size;
@@ -612,28 +714,77 @@
 }
 EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome);
 
-static void qca_generate_hsp_nvm_name(char *fwname, size_t max_size,
+static int qca_check_bdaddr(struct hci_dev *hdev, const struct qca_fw_config *config)
+{
+	struct hci_rp_read_bd_addr *bda;
+	struct sk_buff *skb;
+	int err;
+
+	if (bacmp(&hdev->public_addr, BDADDR_ANY))
+		return 0;
+
+	skb = __hci_cmd_sync(hdev, HCI_OP_READ_BD_ADDR, 0, NULL,
+			     HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb)) {
+		err = PTR_ERR(skb);
+		bt_dev_err(hdev, "Failed to read device address (%d)", err);
+		return err;
+	}
+
+	if (skb->len != sizeof(*bda)) {
+		bt_dev_err(hdev, "Device address length mismatch");
+		kfree_skb(skb);
+		return -EIO;
+	}
+
+	bda = (struct hci_rp_read_bd_addr *)skb->data;
+	if (!bacmp(&bda->bdaddr, &config->bdaddr))
+		set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
+
+	kfree_skb(skb);
+
+	return 0;
+}
+
+static void qca_get_nvm_name_by_board(char *fwname, size_t max_size,
+		const char *stem, enum qca_btsoc_type soc_type,
 		struct qca_btsoc_version ver, u8 rom_ver, u16 bid)
 {
 	const char *variant;
+	const char *prefix;
 
-	/* hsp gf chip */
-	if ((le32_to_cpu(ver.soc_id) & QCA_HSP_GF_SOC_MASK) == QCA_HSP_GF_SOC_ID)
-		variant = "g";
-	else
-		variant = "";
+	/* Set the default value to variant and prefix */
+	variant = "";
+	prefix = "b";
 
-	if (bid == 0x0)
-		snprintf(fwname, max_size, "qca/hpnv%02x%s.bin", rom_ver, variant);
-	else
-		snprintf(fwname, max_size, "qca/hpnv%02x%s.%x", rom_ver, variant, bid);
+	if (soc_type == QCA_QCA2066)
+		prefix = "";
+
+	if (soc_type == QCA_WCN6855 || soc_type == QCA_QCA2066) {
+		/* If the chip is manufactured by GlobalFoundries */
+		if ((le32_to_cpu(ver.soc_id) & QCA_HSP_GF_SOC_MASK) == QCA_HSP_GF_SOC_ID)
+			variant = "g";
+	}
+
+	if (rom_ver != 0) {
+		if (bid == 0x0 || bid == 0xffff)
+			snprintf(fwname, max_size, "qca/%s%02x%s.bin", stem, rom_ver, variant);
+		else
+			snprintf(fwname, max_size, "qca/%s%02x%s.%s%02x", stem, rom_ver,
+						variant, prefix, bid);
+	} else {
+		if (bid == 0x0 || bid == 0xffff)
+			snprintf(fwname, max_size, "qca/%s%s.bin", stem, variant);
+		else
+			snprintf(fwname, max_size, "qca/%s%s.%s%02x", stem, variant, prefix, bid);
+	}
 }
 
 int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
 		   enum qca_btsoc_type soc_type, struct qca_btsoc_version ver,
-		   const char *firmware_name)
+		   const char *firmware_name, const char *rampatch_name)
 {
-	struct qca_fw_config config;
+	struct qca_fw_config config = {};
 	int err;
 	u8 rom_ver = 0;
 	u32 soc_ver;
@@ -655,49 +806,54 @@
 	else
 		rom_ver = ((soc_ver & 0x00000f00) >> 0x04) | (soc_ver & 0x0000000f);
 
-	if (soc_type == QCA_WCN6750)
+	if (soc_type == QCA_WCN6750) {
 		qca_send_patch_config_cmd(hdev);
+	}
 
 	/* Download rampatch file */
 	config.type = TLV_TYPE_PATCH;
-	switch (soc_type) {
-	case QCA_WCN3990:
-	case QCA_WCN3991:
-	case QCA_WCN3998:
-		snprintf(config.fwname, sizeof(config.fwname),
-			 "qca/crbtfw%02x.tlv", rom_ver);
-		break;
-	case QCA_WCN3988:
-		snprintf(config.fwname, sizeof(config.fwname),
-			 "qca/apbtfw%02x.tlv", rom_ver);
-		break;
-	case QCA_QCA2066:
-		snprintf(config.fwname, sizeof(config.fwname),
-			 "qca/hpbtfw%02x.tlv", rom_ver);
-		break;
-	case QCA_QCA6390:
-		snprintf(config.fwname, sizeof(config.fwname),
-			 "qca/htbtfw%02x.tlv", rom_ver);
-		break;
-	case QCA_WCN6750:
-		/* Choose mbn file by default.If mbn file is not found
-		 * then choose tlv file
-		 */
-		config.type = ELF_TYPE_PATCH;
-		snprintf(config.fwname, sizeof(config.fwname),
-			 "qca/msbtfw%02x.mbn", rom_ver);
-		break;
-	case QCA_WCN6855:
-		snprintf(config.fwname, sizeof(config.fwname),
-			 "qca/hpbtfw%02x.tlv", rom_ver);
-		break;
-	case QCA_WCN7850:
-		snprintf(config.fwname, sizeof(config.fwname),
-			 "qca/hmtbtfw%02x.tlv", rom_ver);
-		break;
-	default:
-		snprintf(config.fwname, sizeof(config.fwname),
-			 "qca/rampatch_%08x.bin", soc_ver);
+	if (rampatch_name) {
+		snprintf(config.fwname, sizeof(config.fwname), "qca/%s", rampatch_name);
+	} else {
+		switch (soc_type) {
+		case QCA_WCN3990:
+		case QCA_WCN3991:
+		case QCA_WCN3998:
+			snprintf(config.fwname, sizeof(config.fwname),
+				 "qca/crbtfw%02x.tlv", rom_ver);
+			break;
+		case QCA_WCN3988:
+			snprintf(config.fwname, sizeof(config.fwname),
+				 "qca/apbtfw%02x.tlv", rom_ver);
+			break;
+		case QCA_QCA2066:
+			snprintf(config.fwname, sizeof(config.fwname),
+				 "qca/hpbtfw%02x.tlv", rom_ver);
+			break;
+		case QCA_QCA6390:
+			snprintf(config.fwname, sizeof(config.fwname),
+				 "qca/htbtfw%02x.tlv", rom_ver);
+			break;
+		case QCA_WCN6750:
+			/* Choose mbn file by default.If mbn file is not found
+			 * then choose tlv file
+			 */
+			config.type = ELF_TYPE_PATCH;
+			snprintf(config.fwname, sizeof(config.fwname),
+				 "qca/msbtfw%02x.mbn", rom_ver);
+			break;
+		case QCA_WCN6855:
+			snprintf(config.fwname, sizeof(config.fwname),
+				 "qca/hpbtfw%02x.tlv", rom_ver);
+			break;
+		case QCA_WCN7850:
+			snprintf(config.fwname, sizeof(config.fwname),
+				 "qca/hmtbtfw%02x.tlv", rom_ver);
+			break;
+		default:
+			snprintf(config.fwname, sizeof(config.fwname),
+				 "qca/rampatch_%08x.bin", soc_ver);
+		}
 	}
 
 	err = qca_download_firmware(hdev, &config, soc_type, rom_ver);
@@ -709,14 +865,20 @@
 	/* Give the controller some time to get ready to receive the NVM */
 	msleep(10);
 
-	if (soc_type == QCA_QCA2066)
+	if (soc_type == QCA_QCA2066 || soc_type == QCA_WCN7850)
 		qca_read_fw_board_id(hdev, &boardid);
 
 	/* Download NVM configuration */
 	config.type = TLV_TYPE_NVM;
 	if (firmware_name) {
-		snprintf(config.fwname, sizeof(config.fwname),
-			 "qca/%s", firmware_name);
+		/* The firmware name has an extension, use it directly */
+		if (qca_filename_has_extension(firmware_name)) {
+			snprintf(config.fwname, sizeof(config.fwname), "qca/%s", firmware_name);
+		} else {
+			qca_read_fw_board_id(hdev, &boardid);
+			qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname),
+				 firmware_name, soc_type, ver, 0, boardid);
+		}
 	} else {
 		switch (soc_type) {
 		case QCA_WCN3990:
@@ -735,8 +897,9 @@
 				 "qca/apnv%02x.bin", rom_ver);
 			break;
 		case QCA_QCA2066:
-			qca_generate_hsp_nvm_name(config.fwname,
-				sizeof(config.fwname), ver, rom_ver, boardid);
+			qca_get_nvm_name_by_board(config.fwname,
+				sizeof(config.fwname), "hpnv", soc_type, ver,
+				rom_ver, boardid);
 			break;
 		case QCA_QCA6390:
 			snprintf(config.fwname, sizeof(config.fwname),
@@ -747,14 +910,14 @@
 				 "qca/msnv%02x.bin", rom_ver);
 			break;
 		case QCA_WCN6855:
-			snprintf(config.fwname, sizeof(config.fwname),
-				 "qca/hpnv%02x.bin", rom_ver);
+			qca_read_fw_board_id(hdev, &boardid);
+			qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname),
+						  "hpnv", soc_type, ver, rom_ver, boardid);
 			break;
 		case QCA_WCN7850:
-			snprintf(config.fwname, sizeof(config.fwname),
-				 "qca/hmtnv%02x.bin", rom_ver);
+			qca_get_nvm_name_by_board(config.fwname, sizeof(config.fwname),
+				 "hmtnv", soc_type, ver, rom_ver, boardid);
 			break;
-
 		default:
 			snprintf(config.fwname, sizeof(config.fwname),
 				 "qca/nvm_%08x.bin", soc_ver);
@@ -818,6 +981,10 @@
 		break;
 	}
 
+	err = qca_check_bdaddr(hdev, &config);
+	if (err)
+		return err;
+
 	bt_dev_info(hdev, "QCA setup on UART is completed");
 
 	return 0;
@@ -826,11 +993,15 @@
 
 int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
 {
+	bdaddr_t bdaddr_swapped;
 	struct sk_buff *skb;
 	int err;
 
-	skb = __hci_cmd_sync_ev(hdev, EDL_WRITE_BD_ADDR_OPCODE, 6, bdaddr,
-				HCI_EV_VENDOR, HCI_INIT_TIMEOUT);
+	baswap(&bdaddr_swapped, bdaddr);
+
+	skb = __hci_cmd_sync_ev(hdev, EDL_WRITE_BD_ADDR_OPCODE, 6,
+				&bdaddr_swapped, HCI_EV_VENDOR,
+				HCI_INIT_TIMEOUT);
 	if (IS_ERR(skb)) {
 		err = PTR_ERR(skb);
 		bt_dev_err(hdev, "QCA Change address cmd failed (%d)", err);
@@ -845,6 +1016,5 @@
 
 
 MODULE_AUTHOR("Ben Young Tae Kim <ytkim@qca.qualcomm.com>");
-MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family ver " VERSION);
-MODULE_VERSION(VERSION);
+MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family");
 MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/bluetooth/btqca.h
+++ linux-qcom-6.8.0/drivers/bluetooth/btqca.h
@@ -29,6 +29,7 @@
 #define EDL_PATCH_CONFIG_RES_EVT	(0x00)
 #define QCA_DISABLE_LOGGING_SUB_OP	(0x14)
 
+#define EDL_TAG_ID_BD_ADDR		2
 #define EDL_TAG_ID_HCI			(17)
 #define EDL_TAG_ID_DEEP_SLEEP		(27)
 
@@ -47,7 +48,6 @@
 #define get_soc_ver(soc_id, rom_ver)	\
 	((le32_to_cpu(soc_id) << 16) | (le16_to_cpu(rom_ver)))
 
-#define QCA_FW_BUILD_VER_LEN		255
 #define QCA_HSP_GF_SOC_ID			0x1200
 #define QCA_HSP_GF_SOC_MASK			0x0000ff00
 
@@ -94,6 +94,7 @@
 	uint8_t user_baud_rate;
 	enum qca_tlv_dnld_mode dnld_mode;
 	enum qca_tlv_dnld_mode dnld_type;
+	bdaddr_t bdaddr;
 };
 
 struct edl_event_hdr {
@@ -160,7 +161,7 @@
 int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr);
 int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
 		   enum qca_btsoc_type soc_type, struct qca_btsoc_version ver,
-		   const char *firmware_name);
+		   const char *firmware_name, const char *rampatch_name);
 int qca_read_soc_version(struct hci_dev *hdev, struct qca_btsoc_version *ver,
 			 enum qca_btsoc_type);
 int qca_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
@@ -175,7 +176,8 @@
 static inline int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
 				 enum qca_btsoc_type soc_type,
 				 struct qca_btsoc_version ver,
-				 const char *firmware_name)
+				 const char *firmware_name,
+				 const char *rampatch_name)
 {
 	return -EOPNOTSUPP;
 }
--- linux-qcom-6.8.0.orig/drivers/bluetooth/btrsi.c
+++ linux-qcom-6.8.0/drivers/bluetooth/btrsi.c
@@ -134,7 +134,6 @@
 		hdev->bus = HCI_USB;
 
 	hci_set_drvdata(hdev, h_adapter);
-	hdev->dev_type = HCI_PRIMARY;
 	hdev->open = rsi_hci_open;
 	hdev->close = rsi_hci_close;
 	hdev->flush = rsi_hci_flush;
--- linux-qcom-6.8.0.orig/drivers/bluetooth/btrtl.c
+++ linux-qcom-6.8.0/drivers/bluetooth/btrtl.c
@@ -1275,7 +1275,6 @@
 	case CHIP_ID_8852B:
 	case CHIP_ID_8852C:
 	case CHIP_ID_8851B:
-		set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
 		set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
 
 		/* RTL8852C needs to transmit mSBC data continuously without
@@ -1285,6 +1284,7 @@
 			btrealtek_set_flag(hdev, REALTEK_ALT6_CONTINUOUS_TX_CHIP);
 
 		if (btrtl_dev->project_id == CHIP_ID_8852A ||
+		    btrtl_dev->project_id == CHIP_ID_8852B ||
 		    btrtl_dev->project_id == CHIP_ID_8852C)
 			set_bit(HCI_QUIRK_USE_MSFT_EXT_ADDRESS_FILTER, &hdev->quirks);
 
--- linux-qcom-6.8.0.orig/drivers/bluetooth/btsdio.c
+++ linux-qcom-6.8.0/drivers/bluetooth/btsdio.c
@@ -32,9 +32,6 @@
 	/* Generic Bluetooth Type-B SDIO device */
 	{ SDIO_DEVICE_CLASS(SDIO_CLASS_BT_B) },
 
-	/* Generic Bluetooth AMP controller */
-	{ SDIO_DEVICE_CLASS(SDIO_CLASS_BT_AMP) },
-
 	{ }	/* Terminating entry */
 };
 
@@ -319,11 +316,6 @@
 	hdev->bus = HCI_SDIO;
 	hci_set_drvdata(hdev, data);
 
-	if (id->class == SDIO_CLASS_BT_AMP)
-		hdev->dev_type = HCI_AMP;
-	else
-		hdev->dev_type = HCI_PRIMARY;
-
 	data->hdev = hdev;
 
 	SET_HCIDEV_DEV(hdev, &func->dev);
--- linux-qcom-6.8.0.orig/drivers/bluetooth/btusb.c
+++ linux-qcom-6.8.0/drivers/bluetooth/btusb.c
@@ -14,6 +14,7 @@
 #include <linux/iopoll.h>
 #include <linux/of_device.h>
 #include <linux/of_irq.h>
+#include <linux/pci.h>
 #include <linux/suspend.h>
 #include <linux/gpio/consumer.h>
 #include <linux/debugfs.h>
@@ -407,6 +408,9 @@
 	{ USB_DEVICE(0x0cf3, 0xe700), .driver_info = BTUSB_QCA_WCN6855 |
 						     BTUSB_WIDEBAND_SPEECH |
 						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x0489, 0xe0fc), .driver_info = BTUSB_QCA_WCN6855 |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
 
 	/* Broadcom BCM2035 */
 	{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
@@ -538,10 +542,14 @@
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x13d3, 0x3592), .driver_info = BTUSB_REALTEK |
 						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x0489, 0xe122), .driver_info = BTUSB_REALTEK |
+						     BTUSB_WIDEBAND_SPEECH },
 
 	/* Realtek 8852BE Bluetooth devices */
 	{ USB_DEVICE(0x0cb8, 0xc559), .driver_info = BTUSB_REALTEK |
 						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x0bda, 0x4853), .driver_info = BTUSB_REALTEK |
+						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0bda, 0x887b), .driver_info = BTUSB_REALTEK |
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x0bda, 0xb85b), .driver_info = BTUSB_REALTEK |
@@ -552,6 +560,14 @@
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x13d3, 0x3572), .driver_info = BTUSB_REALTEK |
 						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x13d3, 0x3591), .driver_info = BTUSB_REALTEK |
+						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x0489, 0xe123), .driver_info = BTUSB_REALTEK |
+						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x0489, 0xe125), .driver_info = BTUSB_REALTEK |
+						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x13d3, 0x3610), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH },
 
 	/* Realtek Bluetooth devices */
 	{ USB_VENDOR_AND_INTERFACE_INFO(0x0bda, 0xe0, 0x01, 0x01),
@@ -583,6 +599,9 @@
 	{ USB_DEVICE(0x0489, 0xe0c8), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH |
 						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x0489, 0xe0cd), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
 	{ USB_DEVICE(0x0489, 0xe0e0), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH |
 						     BTUSB_VALID_LE_STATES },
@@ -613,6 +632,9 @@
 	{ USB_DEVICE(0x0e8d, 0x0608), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH |
 						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x13d3, 0x3606), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
 
 	/* MediaTek MT7922A Bluetooth devices */
 	{ USB_DEVICE(0x0489, 0xe0d8), .driver_info = BTUSB_MEDIATEK |
@@ -654,6 +676,52 @@
 	{ USB_DEVICE(0x35f5, 0x7922), .driver_info = BTUSB_MEDIATEK |
 						     BTUSB_WIDEBAND_SPEECH |
 						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x13d3, 0x3614), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x13d3, 0x3615), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x04ca, 0x38e4), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x13d3, 0x3605), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x13d3, 0x3607), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
+
+	/* Additional MediaTek MT7925 Bluetooth devices */
+	{ USB_DEVICE(0x0489, 0xe111), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x0489, 0xe113), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x0489, 0xe124), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x0489, 0xe14f), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x0489, 0xe150), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x0489, 0xe151), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x13d3, 0x3602), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
+	{ USB_DEVICE(0x13d3, 0x3603), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
+
+	/* Additional MediaTek MT7925 Bluetooth devices */
+	{ USB_DEVICE(0x13d3, 0x3602), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH |
+						     BTUSB_VALID_LE_STATES },
 
 	/* Additional Realtek 8723AE Bluetooth devices */
 	{ USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },
@@ -690,6 +758,8 @@
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x2b89, 0x8761), .driver_info = BTUSB_REALTEK |
 						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x13d3, 0x3628), .driver_info = BTUSB_MEDIATEK |
+						     BTUSB_WIDEBAND_SPEECH },
 
 	/* Additional Realtek 8821AE Bluetooth devices */
 	{ USB_DEVICE(0x0b05, 0x17dc), .driver_info = BTUSB_REALTEK },
@@ -854,6 +924,10 @@
 
 	int (*setup_on_usb)(struct hci_dev *hdev);
 
+	int (*suspend)(struct hci_dev *hdev);
+	int (*resume)(struct hci_dev *hdev);
+	int (*disconnect)(struct hci_dev *hdev);
+
 	int oob_wake_irq;   /* irq for out-of-band wake-on-bt */
 	unsigned cmd_timeout_cnt;
 
@@ -1352,7 +1426,15 @@
 	if (!urb)
 		return -ENOMEM;
 
-	size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
+	if (le16_to_cpu(data->udev->descriptor.idVendor)  == 0x0a12 &&
+	    le16_to_cpu(data->udev->descriptor.idProduct) == 0x0001)
+		/* Fake CSR devices don't seem to support sort-transter */
+		size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
+	else
+		/* Use maximum HCI Event size so the USB stack handles
+		 * ZPL/short-transfer automatically.
+		 */
+		size = HCI_MAX_EVENT_SIZE;
 
 	buf = kmalloc(size, mem_flags);
 	if (!buf) {
@@ -3273,7 +3355,6 @@
 {
 	struct btusb_data *data = hci_get_drvdata(hdev);
 	u16 handle = le16_to_cpu(hci_acl_hdr(skb)->handle);
-	struct sk_buff *skb_cd;
 
 	switch (handle) {
 	case 0xfc6f:		/* Firmware dump from device */
@@ -3286,9 +3367,12 @@
 		 * for backward compatibility, so we have to clone the packet
 		 * extraly for the in-kernel coredump support.
 		 */
-		skb_cd = skb_clone(skb, GFP_ATOMIC);
-		if (skb_cd)
-			btmtk_process_coredump(hdev, skb_cd);
+		if (IS_ENABLED(CONFIG_DEV_COREDUMP)) {
+			struct sk_buff *skb_cd = skb_clone(skb, GFP_ATOMIC);
+
+			if (skb_cd)
+				btmtk_process_coredump(hdev, skb_cd);
+		}
 
 		fallthrough;
 	case 0x05ff:		/* Firmware debug logging 1 */
@@ -3366,6 +3450,35 @@
 	return 0;
 }
 
+#define BTUSB_EDGE_LED_COMMAND		0xfc77
+
+static void btusb_edge_set_led(struct hci_dev *hdev, bool state)
+{
+	struct sk_buff *skb;
+	u8 config_led[] = { 0x09, 0x00, 0x01, 0x01 };
+
+	if (state)
+		config_led[1] = 0x01;
+
+	skb = __hci_cmd_sync(hdev, BTUSB_EDGE_LED_COMMAND, sizeof(config_led), config_led, HCI_INIT_TIMEOUT);
+	if (IS_ERR(skb))
+		BT_ERR("%s fail to set LED (%ld)", hdev->name, PTR_ERR(skb));
+	else
+		kfree_skb(skb);
+}
+
+static int btusb_edge_post_init(struct hci_dev *hdev)
+{
+	btusb_edge_set_led(hdev, true);
+	return 0;
+}
+
+static int btusb_edge_shutdown(struct hci_dev *hdev)
+{
+	btusb_edge_set_led(hdev, false);
+	return 0;
+}
+
 static int btusb_set_bdaddr_ath3012(struct hci_dev *hdev,
 				    const bdaddr_t *bdaddr)
 {
@@ -3461,13 +3574,12 @@
 
 static void btusb_coredump_qca(struct hci_dev *hdev)
 {
+	int err;
 	static const u8 param[] = { 0x26 };
-	struct sk_buff *skb;
 
-	skb = __hci_cmd_sync(hdev, 0xfc0c, 1, param, HCI_CMD_TIMEOUT);
-	if (IS_ERR(skb))
-		bt_dev_err(hdev, "%s: triggle crash failed (%ld)", __func__, PTR_ERR(skb));
-	kfree_skb(skb);
+	err = __hci_cmd_send(hdev, 0xfc0c, 1, param);
+	if (err < 0)
+		bt_dev_err(hdev, "%s: triggle crash failed (%d)", __func__, err);
 }
 
 /*
@@ -4311,11 +4423,6 @@
 	hdev->bus = HCI_USB;
 	hci_set_drvdata(hdev, data);
 
-	if (id->driver_info & BTUSB_AMP)
-		hdev->dev_type = HCI_AMP;
-	else
-		hdev->dev_type = HCI_PRIMARY;
-
 	data->hdev = hdev;
 
 	SET_HCIDEV_DEV(hdev, &intf->dev);
@@ -4398,8 +4505,18 @@
 			btintel_set_flag(hdev, INTEL_BROKEN_SHUTDOWN_LED);
 	}
 
-	if (id->driver_info & BTUSB_MARVELL)
+	if (id->driver_info & BTUSB_MARVELL) {
+		struct pci_dev *pdev;
 		hdev->set_bdaddr = btusb_set_bdaddr_marvell;
+		pdev = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0720, NULL);
+		if (!pdev)
+			pdev = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0733, NULL);
+		if (pdev) {
+			pci_dev_put(pdev);
+			hdev->post_init = btusb_edge_post_init;
+			hdev->shutdown = btusb_edge_shutdown;
+		}
+	}
 
 	if (IS_ENABLED(CONFIG_BT_HCIBTUSB_MTK) &&
 	    (id->driver_info & BTUSB_MEDIATEK)) {
@@ -4481,6 +4598,9 @@
 		set_bit(HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER, &hdev->quirks);
 		set_bit(HCI_QUIRK_BROKEN_SET_RPA_TIMEOUT, &hdev->quirks);
 		set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks);
+		set_bit(HCI_QUIRK_BROKEN_READ_ENC_KEY_SIZE, &hdev->quirks);
+		set_bit(HCI_QUIRK_BROKEN_EXT_CREATE_CONN, &hdev->quirks);
+		set_bit(HCI_QUIRK_BROKEN_WRITE_AUTH_PAYLOAD_TIMEOUT, &hdev->quirks);
 	}
 
 	if (!reset)
@@ -4497,8 +4617,8 @@
 	if (id->driver_info & BTUSB_WIDEBAND_SPEECH)
 		set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
 
-	if (id->driver_info & BTUSB_VALID_LE_STATES)
-		set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
+	if (!(id->driver_info & BTUSB_VALID_LE_STATES))
+		set_bit(HCI_QUIRK_BROKEN_LE_STATES, &hdev->quirks);
 
 	if (id->driver_info & BTUSB_DIGIANSWER) {
 		data->cmdreq_type = USB_TYPE_VENDOR;
@@ -4598,6 +4718,9 @@
 	if (data->diag)
 		usb_set_intfdata(data->diag, NULL);
 
+	if (data->disconnect)
+		data->disconnect(hdev);
+
 	hci_unregister_dev(hdev);
 
 	if (intf == data->intf) {
@@ -4631,8 +4754,10 @@
 
 	BT_DBG("intf %p", intf);
 
-	/* Don't suspend if there are connections */
-	if (hci_conn_count(data->hdev))
+	/* Don't auto-suspend if there are connections; external suspend calls
+	 * shall never fail.
+	 */
+	if (PMSG_IS_AUTO(message) && hci_conn_count(data->hdev))
 		return -EBUSY;
 
 	if (data->suspend_count++)
@@ -4650,6 +4775,9 @@
 
 	cancel_work_sync(&data->work);
 
+	if (data->suspend)
+		data->suspend(data->hdev);
+
 	btusb_stop_traffic(data);
 	usb_kill_anchored_urbs(&data->tx_anchor);
 
@@ -4753,6 +4881,9 @@
 			btusb_submit_isoc_urb(hdev, GFP_NOIO);
 	}
 
+	if (data->resume)
+		data->resume(hdev);
+
 	spin_lock_irq(&data->txlock);
 	play_deferred(data);
 	clear_bit(BTUSB_SUSPENDING, &data->flags);
--- linux-qcom-6.8.0.orig/drivers/bluetooth/hci_bcm4377.c
+++ linux-qcom-6.8.0/drivers/bluetooth/hci_bcm4377.c
@@ -32,7 +32,7 @@
 #define BCM4378_DEVICE_ID 0x5f69
 #define BCM4387_DEVICE_ID 0x5f71
 
-#define BCM4377_TIMEOUT 1000
+#define BCM4377_TIMEOUT msecs_to_jiffies(1000)
 
 /*
  * These devices only support DMA transactions inside a 32bit window
@@ -495,6 +495,10 @@
  *                  extended scanning
  * broken_mws_transport_config: Set to true if the chip erroneously claims to
  *                              support MWS Transport Configuration
+ * broken_le_ext_adv_report_phy: Set to true if this chip stuffs flags inside
+ *                               reserved bits of Primary/Secondary_PHY inside
+ *                               LE Extended Advertising Report events which
+ *                               have to be ignored
  * send_calibration: Optional callback to send calibration data
  * send_ptb: Callback to send "PTB" regulatory/calibration data
  */
@@ -513,6 +517,7 @@
 	unsigned long broken_ext_scan : 1;
 	unsigned long broken_mws_transport_config : 1;
 	unsigned long broken_le_coded : 1;
+	unsigned long broken_le_ext_adv_report_phy : 1;
 
 	int (*send_calibration)(struct bcm4377_data *bcm4377);
 	int (*send_ptb)(struct bcm4377_data *bcm4377,
@@ -716,7 +721,7 @@
 		ring->events[msgid] = NULL;
 	}
 
-	bitmap_release_region(ring->msgids, msgid, ring->n_entries);
+	bitmap_release_region(ring->msgids, msgid, 0);
 
 unlock:
 	spin_unlock_irqrestore(&ring->lock, flags);
@@ -2361,7 +2366,6 @@
 	bcm4377->hdev = hdev;
 
 	hdev->bus = HCI_PCI;
-	hdev->dev_type = HCI_PRIMARY;
 	hdev->open = bcm4377_hci_open;
 	hdev->close = bcm4377_hci_close;
 	hdev->send = bcm4377_hci_send_frame;
@@ -2374,6 +2378,8 @@
 		set_bit(HCI_QUIRK_BROKEN_EXT_SCAN, &hdev->quirks);
 	if (bcm4377->hw->broken_le_coded)
 		set_bit(HCI_QUIRK_BROKEN_LE_CODED, &hdev->quirks);
+	if (bcm4377->hw->broken_le_ext_adv_report_phy)
+		set_bit(HCI_QUIRK_FIXUP_LE_EXT_ADV_REPORT_PHY, &hdev->quirks);
 
 	pci_set_drvdata(pdev, bcm4377);
 	hci_set_drvdata(hdev, bcm4377);
@@ -2478,6 +2484,7 @@
 		.clear_pciecfg_subsystem_ctrl_bit19 = true,
 		.broken_mws_transport_config = true,
 		.broken_le_coded = true,
+		.broken_le_ext_adv_report_phy = true,
 		.send_calibration = bcm4387_send_calibration,
 		.send_ptb = bcm4378_send_ptb,
 	},
--- linux-qcom-6.8.0.orig/drivers/bluetooth/hci_h5.c
+++ linux-qcom-6.8.0/drivers/bluetooth/hci_h5.c
@@ -113,6 +113,7 @@
 	int (*suspend)(struct h5 *h5);
 	int (*resume)(struct h5 *h5);
 	const struct acpi_gpio_mapping *acpi_gpio_map;
+	int sizeof_priv;
 };
 
 struct h5_device_data {
@@ -863,7 +864,8 @@
 	if (IS_ERR(h5->device_wake_gpio))
 		return PTR_ERR(h5->device_wake_gpio);
 
-	return hci_uart_register_device(&h5->serdev_hu, &h5p);
+	return hci_uart_register_device_priv(&h5->serdev_hu, &h5p,
+					     h5->vnd->sizeof_priv);
 }
 
 static void h5_serdev_remove(struct serdev_device *serdev)
@@ -1070,6 +1072,7 @@
 	.suspend	= h5_btrtl_suspend,
 	.resume		= h5_btrtl_resume,
 	.acpi_gpio_map	= acpi_btrtl_gpios,
+	.sizeof_priv    = sizeof(struct btrealtek_data),
 };
 
 static const struct h5_device_data h5_data_rtl8822cs = {
--- linux-qcom-6.8.0.orig/drivers/bluetooth/hci_ldisc.c
+++ linux-qcom-6.8.0/drivers/bluetooth/hci_ldisc.c
@@ -667,11 +667,6 @@
 	if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags))
 		set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
 
-	if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags))
-		hdev->dev_type = HCI_AMP;
-	else
-		hdev->dev_type = HCI_PRIMARY;
-
 	/* Only call open() for the protocol after hdev is fully initialized as
 	 * open() (or a timer/workqueue it starts) may attempt to reference it.
 	 */
@@ -722,7 +717,6 @@
 {
 	unsigned long valid_flags = BIT(HCI_UART_RAW_DEVICE) |
 				    BIT(HCI_UART_RESET_ON_INIT) |
-				    BIT(HCI_UART_CREATE_AMP) |
 				    BIT(HCI_UART_INIT_PENDING) |
 				    BIT(HCI_UART_EXT_CONFIG) |
 				    BIT(HCI_UART_VND_DETECT);
--- linux-qcom-6.8.0.orig/drivers/bluetooth/hci_qca.c
+++ linux-qcom-6.8.0/drivers/bluetooth/hci_qca.c
@@ -7,7 +7,7 @@
  *
  *  Copyright (C) 2007 Texas Instruments, Inc.
  *  Copyright (c) 2010, 2012, 2018 The Linux Foundation. All rights reserved.
- *  Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *  Copyright (c) 2023, 2024  Qualcomm Innovation Center, Inc. All rights reserved.
  *
  *  Acknowledgements:
  *  This file is based on hci_ll.c, which was...
@@ -226,7 +226,8 @@
 	struct qca_power *bt_power;
 	u32 init_speed;
 	u32 oper_speed;
-	const char *firmware_name;
+	bool bdaddr_property_broken;
+	const char *firmware_name[2];
 };
 
 static int qca_regulator_enable(struct qca_serdev *qcadev);
@@ -256,7 +257,18 @@
 	if (hu->serdev) {
 		struct qca_serdev *qsd = serdev_device_get_drvdata(hu->serdev);
 
-		return qsd->firmware_name;
+		return qsd->firmware_name[0];
+	} else {
+		return NULL;
+	}
+}
+
+static const char *qca_get_rampatch_name(struct hci_uart *hu)
+{
+	if (hu->serdev) {
+		struct qca_serdev *qsd = serdev_device_get_drvdata(hu->serdev);
+
+		return qsd->firmware_name[1];
 	} else {
 		return NULL;
 	}
@@ -1090,6 +1102,8 @@
 				qca->memdump_state = QCA_MEMDUMP_COLLECTED;
 				cancel_delayed_work(&qca->ctrl_memdump_timeout);
 				clear_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
+				clear_bit(QCA_IBS_DISABLED, &qca->flags);
+				wake_up_bit(&qca->flags, QCA_MEMDUMP_COLLECTION);
 				mutex_unlock(&qca->hci_memdump_lock);
 				return;
 			}
@@ -1167,6 +1181,7 @@
 			qca->qca_memdump = NULL;
 			qca->memdump_state = QCA_MEMDUMP_COLLECTED;
 			clear_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
+			wake_up_bit(&qca->flags, QCA_MEMDUMP_COLLECTION);
 		}
 
 		mutex_unlock(&qca->hci_memdump_lock);
@@ -1205,7 +1220,15 @@
 		 * vendor command).
 		 */
 
-		if (hdr->evt == HCI_EV_VENDOR)
+		/* For the WCN6750/WCN6855/WCN7850, like the WCN3990, the
+		 * vendor command for a baudrate change command isn't sent as
+		 * synchronous HCI command, the controller sends the corresponding
+		 * command complete event with the new baudrate. The event is
+		 * received and properly decoded after changing the baudrate of
+		 * the host port. It needs to be dropped.
+		 */
+
+		if (hdr->evt == HCI_EV_VENDOR || hdr->evt == HCI_EV_CMD_COMPLETE)
 			complete(&qca->drop_ev_comp);
 
 		kfree_skb(skb);
@@ -1356,10 +1379,12 @@
 	case QCA_WCN3990:
 	case QCA_WCN3991:
 	case QCA_WCN3998:
+		usleep_range(1000, 10000);
+		break;
 	case QCA_WCN6750:
 	case QCA_WCN6855:
 	case QCA_WCN7850:
-		usleep_range(1000, 10000);
+		msleep(30);
 		break;
 
 	default:
@@ -1496,6 +1521,9 @@
 
 		switch (soc_type) {
 		case QCA_WCN3990:
+		case QCA_WCN6750:
+		case QCA_WCN6855:
+		case QCA_WCN7850:
 			reinit_completion(&qca->drop_ev_comp);
 			set_bit(QCA_DROP_VENDOR_EVENT, &qca->flags);
 			break;
@@ -1530,6 +1558,9 @@
 
 		switch (soc_type) {
 		case QCA_WCN3990:
+		case QCA_WCN6750:
+		case QCA_WCN6855:
+		case QCA_WCN7850:
 			/* Wait for the controller to send the vendor event
 			 * for the baudrate change command.
 			 */
@@ -1582,7 +1613,7 @@
 	struct qca_data *qca = hu->priv;
 
 	wait_on_bit_timeout(&qca->flags, QCA_MEMDUMP_COLLECTION,
-			    TASK_UNINTERRUPTIBLE, MEMDUMP_TIMEOUT_MS);
+			    TASK_UNINTERRUPTIBLE, msecs_to_jiffies(MEMDUMP_TIMEOUT_MS));
 
 	clear_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
 }
@@ -1634,6 +1665,23 @@
 	}
 
 	clear_bit(QCA_HW_ERROR_EVENT, &qca->flags);
+
+	/*
+	 * If the SoC always enables the bt_en pin via hardware and the driver
+	 * cannot control the bt_en pin of the SoC chip, then during SSR,
+	 * the QCA_SSR_TRIGGERED and QCA_IBS_DISABLED bits cannot be cleared.
+	 * This leads to a reset command timeout failure.
+	 *
+	 * To address this, clear QCA_SSR_TRIGGERED and QCA_IBS_DISABLED bits
+	 * after the coredump collection is complete.
+	 * Also, add msleep delay to wait for controller to complete SSR.
+	 */
+	if (!test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) {
+		clear_bit(QCA_SSR_TRIGGERED, &qca->flags);
+		clear_bit(QCA_IBS_DISABLED, &qca->flags);
+		qca->tx_ibs_state = HCI_IBS_TX_AWAKE;
+		msleep(50);
+	}
 }
 
 static void qca_cmd_timeout(struct hci_dev *hdev)
@@ -1672,6 +1720,9 @@
 	struct hci_uart *hu = hci_get_drvdata(hdev);
 	bool wakeup;
 
+	if (!hu->serdev)
+		return true;
+
 	/* BT SoC attached through the serial bus is handled by the serdev driver.
 	 * So we need to use the device handle of the serdev driver to get the
 	 * status of device may wakeup.
@@ -1841,8 +1892,10 @@
 	unsigned int retries = 0;
 	enum qca_btsoc_type soc_type = qca_soc_type(hu);
 	const char *firmware_name = qca_get_firmware_name(hu);
+	const char *rampatch_name = qca_get_rampatch_name(hu);
 	int ret;
 	struct qca_btsoc_version ver;
+	struct qca_serdev *qcadev;
 	const char *soc_name;
 
 	ret = qca_check_speeds(hu);
@@ -1904,16 +1957,9 @@
 	case QCA_WCN6750:
 	case QCA_WCN6855:
 	case QCA_WCN7850:
-
-		/* Set BDA quirk bit for reading BDA value from fwnode property
-		 * only if that property exist in DT.
-		 */
-		if (fwnode_property_present(dev_fwnode(hdev->dev.parent), "local-bd-address")) {
-			set_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
-			bt_dev_info(hdev, "setting quirk bit to read BDA from fwnode later");
-		} else {
-			bt_dev_dbg(hdev, "local-bd-address` is not present in the devicetree so not setting quirk bit for BDA");
-		}
+		qcadev = serdev_device_get_drvdata(hu->serdev);
+		if (qcadev->bdaddr_property_broken)
+			set_bit(HCI_QUIRK_BDADDR_PROPERTY_BROKEN, &hdev->quirks);
 
 		hci_set_aosp_capable(hdev);
 
@@ -1935,7 +1981,6 @@
 
 		qca_baudrate = qca_get_baudrate_value(speed);
 	}
-
 	switch (soc_type) {
 	case QCA_WCN3988:
 	case QCA_WCN3990:
@@ -1955,14 +2000,16 @@
 
 	/* Setup patch / NVM configurations */
 	ret = qca_uart_setup(hdev, qca_baudrate, soc_type, ver,
-			firmware_name);
+			firmware_name, rampatch_name);
 	if (!ret) {
 		clear_bit(QCA_IBS_DISABLED, &qca->flags);
 		qca_debugfs_init(hdev);
 		hu->hdev->hw_error = qca_hw_error;
 		hu->hdev->cmd_timeout = qca_cmd_timeout;
-		if (device_can_wakeup(hu->serdev->ctrl->dev.parent))
-			hu->hdev->wakeup = qca_wakeup;
+		if (hu->serdev) {
+			if (device_can_wakeup(hu->serdev->ctrl->dev.parent))
+				hu->hdev->wakeup = qca_wakeup;
+		}
 	} else if (ret == -ENOENT) {
 		/* No patch/nvm-config found, run with original fw/config */
 		set_bit(QCA_ROM_FW, &qca->flags);
@@ -2161,6 +2208,7 @@
 
 	case QCA_WCN6750:
 	case QCA_WCN6855:
+	case QCA_WCN7850:
 		gpiod_set_value_cansleep(qcadev->bt_en, 0);
 		msleep(100);
 		qca_regulator_disable(qcadev);
@@ -2288,13 +2336,16 @@
 	qcadev->serdev_hu.serdev = serdev;
 	data = device_get_match_data(&serdev->dev);
 	serdev_device_set_drvdata(serdev, qcadev);
-	device_property_read_string(&serdev->dev, "firmware-name",
-					 &qcadev->firmware_name);
+	device_property_read_string_array(&serdev->dev, "firmware-name",
+					 qcadev->firmware_name, ARRAY_SIZE(qcadev->firmware_name));
 	device_property_read_u32(&serdev->dev, "max-speed",
 				 &qcadev->oper_speed);
 	if (!qcadev->oper_speed)
 		BT_DBG("UART will pick default operating speed");
 
+	qcadev->bdaddr_property_broken = device_property_read_bool(&serdev->dev,
+			"qcom,local-bd-address-broken");
+
 	if (data)
 		qcadev->btsoc_type = data->soc_type;
 	else
@@ -2326,20 +2377,25 @@
 
 		qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
 					       GPIOD_OUT_LOW);
-		if (IS_ERR_OR_NULL(qcadev->bt_en) &&
+		if (IS_ERR(qcadev->bt_en) &&
 		    (data->soc_type == QCA_WCN6750 ||
 		     data->soc_type == QCA_WCN6855)) {
 			dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n");
-			power_ctrl_enabled = false;
+			return PTR_ERR(qcadev->bt_en);
 		}
 
+		if (!qcadev->bt_en)
+			power_ctrl_enabled = false;
+
 		qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl",
 					       GPIOD_IN);
-		if (IS_ERR_OR_NULL(qcadev->sw_ctrl) &&
+		if (IS_ERR(qcadev->sw_ctrl) &&
 		    (data->soc_type == QCA_WCN6750 ||
 		     data->soc_type == QCA_WCN6855 ||
-		     data->soc_type == QCA_WCN7850))
-			dev_warn(&serdev->dev, "failed to acquire SW_CTRL gpio\n");
+		     data->soc_type == QCA_WCN7850)) {
+			dev_err(&serdev->dev, "failed to acquire SW_CTRL gpio\n");
+			return PTR_ERR(qcadev->sw_ctrl);
+		}
 
 		qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL);
 		if (IS_ERR(qcadev->susclk)) {
@@ -2357,11 +2413,14 @@
 	default:
 		qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable",
 					       GPIOD_OUT_LOW);
-		if (IS_ERR_OR_NULL(qcadev->bt_en)) {
-			dev_warn(&serdev->dev, "failed to acquire enable gpio\n");
-			power_ctrl_enabled = false;
+		if (IS_ERR(qcadev->bt_en)) {
+			dev_err(&serdev->dev, "failed to acquire enable gpio\n");
+			return PTR_ERR(qcadev->bt_en);
 		}
 
+		if (!qcadev->bt_en)
+			power_ctrl_enabled = false;
+
 		qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL);
 		if (IS_ERR(qcadev->susclk)) {
 			dev_warn(&serdev->dev, "failed to acquire clk\n");
@@ -2388,6 +2447,13 @@
 	if (power_ctrl_enabled) {
 		set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
 		hdev->shutdown = qca_power_off;
+	} else {
+	/* host not respond to controller's IBS command
+	 * when BT close hci and no close uart,
+	 * causing controller to enter an abnormal state.
+	 * Therefore, disable HCI_AUTO_OFF
+	 */
+		hci_dev_clear_flag(hdev, HCI_AUTO_OFF);
 	}
 
 	if (data) {
@@ -2398,8 +2464,8 @@
 			set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED,
 				&hdev->quirks);
 
-		if (data->capabilities & QCA_CAP_VALID_LE_STATES)
-			set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
+		if (!(data->capabilities & QCA_CAP_VALID_LE_STATES))
+			set_bit(HCI_QUIRK_BROKEN_LE_STATES, &hdev->quirks);
 	}
 
 	return 0;
@@ -2440,15 +2506,27 @@
 	struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
 	struct hci_uart *hu = &qcadev->serdev_hu;
 	struct hci_dev *hdev = hu->hdev;
-	struct qca_data *qca = hu->priv;
 	const u8 ibs_wake_cmd[] = { 0xFD };
 	const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 };
 
 	if (qcadev->btsoc_type == QCA_QCA6390) {
-		if (test_bit(QCA_BT_OFF, &qca->flags) ||
-		    !test_bit(HCI_RUNNING, &hdev->flags))
+		/* The purpose of sending the VSC is to reset SOC into a initial
+		 * state and the state will ensure next hdev->setup() success.
+		 * if HCI_QUIRK_NON_PERSISTENT_SETUP is set, it means that
+		 * hdev->setup() can do its job regardless of SoC state, so
+		 * don't need to send the VSC.
+		 * if HCI_SETUP is set, it means that hdev->setup() was never
+		 * invoked and the SOC is already in the initial state, so
+		 * don't also need to send the VSC.
+		 */
+		if (test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks) ||
+		    hci_dev_test_flag(hdev, HCI_SETUP))
 			return;
 
+		/* The serdev must be in open state when conrol logic arrives
+		 * here, so also fix the use-after-free issue caused by that
+		 * the serdev is flushed or wrote after it is closed.
+		 */
 		serdev_device_write_flush(serdev);
 		ret = serdev_device_write_buf(serdev, ibs_wake_cmd,
 					      sizeof(ibs_wake_cmd));
--- linux-qcom-6.8.0.orig/drivers/bluetooth/hci_serdev.c
+++ linux-qcom-6.8.0/drivers/bluetooth/hci_serdev.c
@@ -300,8 +300,9 @@
 	.write_wakeup = hci_uart_write_wakeup,
 };
 
-int hci_uart_register_device(struct hci_uart *hu,
-			     const struct hci_uart_proto *p)
+int hci_uart_register_device_priv(struct hci_uart *hu,
+			     const struct hci_uart_proto *p,
+			     int sizeof_priv)
 {
 	int err;
 	struct hci_dev *hdev;
@@ -325,7 +326,7 @@
 	set_bit(HCI_UART_PROTO_READY, &hu->flags);
 
 	/* Initialize and register HCI device */
-	hdev = hci_alloc_dev();
+	hdev = hci_alloc_dev_priv(sizeof_priv);
 	if (!hdev) {
 		BT_ERR("Can't allocate HCI device");
 		err = -ENOMEM;
@@ -365,11 +366,6 @@
 	if (test_bit(HCI_UART_EXT_CONFIG, &hu->hdev_flags))
 		set_bit(HCI_QUIRK_EXTERNAL_CONFIG, &hdev->quirks);
 
-	if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags))
-		hdev->dev_type = HCI_AMP;
-	else
-		hdev->dev_type = HCI_PRIMARY;
-
 	if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags))
 		return 0;
 
@@ -394,7 +390,7 @@
 	percpu_free_rwsem(&hu->proto_lock);
 	return err;
 }
-EXPORT_SYMBOL_GPL(hci_uart_register_device);
+EXPORT_SYMBOL_GPL(hci_uart_register_device_priv);
 
 void hci_uart_unregister_device(struct hci_uart *hu)
 {
--- linux-qcom-6.8.0.orig/drivers/bluetooth/hci_uart.h
+++ linux-qcom-6.8.0/drivers/bluetooth/hci_uart.h
@@ -37,7 +37,6 @@
 
 #define HCI_UART_RAW_DEVICE	0
 #define HCI_UART_RESET_ON_INIT	1
-#define HCI_UART_CREATE_AMP	2
 #define HCI_UART_INIT_PENDING	3
 #define HCI_UART_EXT_CONFIG	4
 #define HCI_UART_VND_DETECT	5
@@ -97,7 +96,17 @@
 
 int hci_uart_register_proto(const struct hci_uart_proto *p);
 int hci_uart_unregister_proto(const struct hci_uart_proto *p);
-int hci_uart_register_device(struct hci_uart *hu, const struct hci_uart_proto *p);
+
+int hci_uart_register_device_priv(struct hci_uart *hu,
+				  const struct hci_uart_proto *p,
+				  int sizeof_priv);
+
+static inline int hci_uart_register_device(struct hci_uart *hu,
+					   const struct hci_uart_proto *p)
+{
+	return hci_uart_register_device_priv(hu, p, 0);
+}
+
 void hci_uart_unregister_device(struct hci_uart *hu);
 
 int hci_uart_tx_wakeup(struct hci_uart *hu);
--- linux-qcom-6.8.0.orig/drivers/bluetooth/hci_vhci.c
+++ linux-qcom-6.8.0/drivers/bluetooth/hci_vhci.c
@@ -384,17 +384,10 @@
 {
 	struct hci_dev *hdev;
 	struct sk_buff *skb;
-	__u8 dev_type;
 
 	if (data->hdev)
 		return -EBADFD;
 
-	/* bits 0-1 are dev_type (Primary or AMP) */
-	dev_type = opcode & 0x03;
-
-	if (dev_type != HCI_PRIMARY && dev_type != HCI_AMP)
-		return -EINVAL;
-
 	/* bits 2-5 are reserved (must be zero) */
 	if (opcode & 0x3c)
 		return -EINVAL;
@@ -412,7 +405,6 @@
 	data->hdev = hdev;
 
 	hdev->bus = HCI_VIRTUAL;
-	hdev->dev_type = dev_type;
 	hci_set_drvdata(hdev, data);
 
 	hdev->open  = vhci_open_dev;
@@ -433,8 +425,6 @@
 	if (opcode & 0x80)
 		set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
 
-	set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks);
-
 	if (hci_register_dev(hdev) < 0) {
 		BT_ERR("Can't register HCI device");
 		hci_free_dev(hdev);
@@ -634,7 +624,7 @@
 	struct vhci_data *data = container_of(work, struct vhci_data,
 					      open_timeout.work);
 
-	vhci_create_device(data, amp ? HCI_AMP : HCI_PRIMARY);
+	vhci_create_device(data, 0x00);
 }
 
 static int vhci_open(struct inode *inode, struct file *file)
--- linux-qcom-6.8.0.orig/drivers/bluetooth/virtio_bt.c
+++ linux-qcom-6.8.0/drivers/bluetooth/virtio_bt.c
@@ -274,7 +274,6 @@
 
 	switch (type) {
 	case VIRTIO_BT_CONFIG_TYPE_PRIMARY:
-	case VIRTIO_BT_CONFIG_TYPE_AMP:
 		break;
 	default:
 		return -EINVAL;
@@ -303,7 +302,6 @@
 	vbt->hdev = hdev;
 
 	hdev->bus = HCI_VIRTIO;
-	hdev->dev_type = type;
 	hci_set_drvdata(hdev, vbt);
 
 	hdev->open  = virtbt_open;
--- linux-qcom-6.8.0.orig/drivers/bus/Kconfig
+++ linux-qcom-6.8.0/drivers/bus/Kconfig
@@ -186,11 +186,12 @@
 
 config TEGRA_ACONNECT
 	tristate "Tegra ACONNECT Bus Driver"
-	depends on ARCH_TEGRA_210_SOC
+	depends on ARCH_TEGRA
 	depends on OF && PM
 	help
 	  Driver for the Tegra ACONNECT bus which is used to interface with
-	  the devices inside the Audio Processing Engine (APE) for Tegra210.
+	  the devices inside the Audio Processing Engine (APE) for
+	  Tegra210 and later.
 
 config TEGRA_GMI
 	tristate "Tegra Generic Memory Interface bus driver"
--- linux-qcom-6.8.0.orig/drivers/bus/arm-integrator-lm.c
+++ linux-qcom-6.8.0/drivers/bus/arm-integrator-lm.c
@@ -85,6 +85,7 @@
 		return -ENODEV;
 	}
 	map = syscon_node_to_regmap(syscon);
+	of_node_put(syscon);
 	if (IS_ERR(map)) {
 		dev_err(dev,
 			"could not find Integrator/AP system controller\n");
--- linux-qcom-6.8.0.orig/drivers/bus/mhi/ep/main.c
+++ linux-qcom-6.8.0/drivers/bus/mhi/ep/main.c
@@ -90,7 +90,7 @@
 	struct mhi_ring_element *event;
 	int ret;
 
-	event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA);
+	event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL);
 	if (!event)
 		return -ENOMEM;
 
@@ -109,7 +109,7 @@
 	struct mhi_ring_element *event;
 	int ret;
 
-	event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA);
+	event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL);
 	if (!event)
 		return -ENOMEM;
 
@@ -127,7 +127,7 @@
 	struct mhi_ring_element *event;
 	int ret;
 
-	event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA);
+	event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL);
 	if (!event)
 		return -ENOMEM;
 
@@ -146,7 +146,7 @@
 	struct mhi_ring_element *event;
 	int ret;
 
-	event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA);
+	event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL);
 	if (!event)
 		return -ENOMEM;
 
@@ -438,7 +438,7 @@
 		read_offset = mhi_chan->tre_size - mhi_chan->tre_bytes_left;
 		write_offset = len - buf_left;
 
-		buf_addr = kmem_cache_zalloc(mhi_cntrl->tre_buf_cache, GFP_KERNEL | GFP_DMA);
+		buf_addr = kmem_cache_zalloc(mhi_cntrl->tre_buf_cache, GFP_KERNEL);
 		if (!buf_addr)
 			return -ENOMEM;
 
@@ -1149,8 +1149,9 @@
 	mhi_ep_mmio_mask_interrupts(mhi_cntrl);
 	mhi_ep_mmio_init(mhi_cntrl);
 
-	mhi_cntrl->mhi_event = kzalloc(mhi_cntrl->event_rings * (sizeof(*mhi_cntrl->mhi_event)),
-					GFP_KERNEL);
+	mhi_cntrl->mhi_event = kcalloc(mhi_cntrl->event_rings,
+				       sizeof(*mhi_cntrl->mhi_event),
+				       GFP_KERNEL);
 	if (!mhi_cntrl->mhi_event)
 		return -ENOMEM;
 
@@ -1480,14 +1481,14 @@
 
 	mhi_cntrl->ev_ring_el_cache = kmem_cache_create("mhi_ep_event_ring_el",
 							sizeof(struct mhi_ring_element), 0,
-							SLAB_CACHE_DMA, NULL);
+							0, NULL);
 	if (!mhi_cntrl->ev_ring_el_cache) {
 		ret = -ENOMEM;
 		goto err_free_cmd;
 	}
 
 	mhi_cntrl->tre_buf_cache = kmem_cache_create("mhi_ep_tre_buf", MHI_EP_DEFAULT_MTU, 0,
-						      SLAB_CACHE_DMA, NULL);
+						      0, NULL);
 	if (!mhi_cntrl->tre_buf_cache) {
 		ret = -ENOMEM;
 		goto err_destroy_ev_ring_el_cache;
@@ -1496,7 +1497,7 @@
 	mhi_cntrl->ring_item_cache = kmem_cache_create("mhi_ep_ring_item",
 							sizeof(struct mhi_ep_ring_item), 0,
 							0, NULL);
-	if (!mhi_cntrl->ev_ring_el_cache) {
+	if (!mhi_cntrl->ring_item_cache) {
 		ret = -ENOMEM;
 		goto err_destroy_tre_buf_cache;
 	}
--- linux-qcom-6.8.0.orig/drivers/bus/mhi/host/init.c
+++ linux-qcom-6.8.0/drivers/bus/mhi/host/init.c
@@ -62,6 +62,7 @@
 	[MHI_PM_STATE_FW_DL_ERR] = "Firmware Download Error",
 	[MHI_PM_STATE_SYS_ERR_DETECT] = "SYS ERROR Detect",
 	[MHI_PM_STATE_SYS_ERR_PROCESS] = "SYS ERROR Process",
+	[MHI_PM_STATE_SYS_ERR_FAIL] = "SYS ERROR Failure",
 	[MHI_PM_STATE_SHUTDOWN_PROCESS] = "SHUTDOWN Process",
 	[MHI_PM_STATE_LD_ERR_FATAL_DETECT] = "Linkdown or Error Fatal Detect",
 };
--- linux-qcom-6.8.0.orig/drivers/bus/mhi/host/internal.h
+++ linux-qcom-6.8.0/drivers/bus/mhi/host/internal.h
@@ -88,6 +88,7 @@
 	MHI_PM_STATE_FW_DL_ERR,
 	MHI_PM_STATE_SYS_ERR_DETECT,
 	MHI_PM_STATE_SYS_ERR_PROCESS,
+	MHI_PM_STATE_SYS_ERR_FAIL,
 	MHI_PM_STATE_SHUTDOWN_PROCESS,
 	MHI_PM_STATE_LD_ERR_FATAL_DETECT,
 	MHI_PM_STATE_MAX
@@ -104,14 +105,16 @@
 #define MHI_PM_FW_DL_ERR				BIT(7)
 #define MHI_PM_SYS_ERR_DETECT				BIT(8)
 #define MHI_PM_SYS_ERR_PROCESS				BIT(9)
-#define MHI_PM_SHUTDOWN_PROCESS				BIT(10)
+#define MHI_PM_SYS_ERR_FAIL				BIT(10)
+#define MHI_PM_SHUTDOWN_PROCESS				BIT(11)
 /* link not accessible */
-#define MHI_PM_LD_ERR_FATAL_DETECT			BIT(11)
+#define MHI_PM_LD_ERR_FATAL_DETECT			BIT(12)
 
 #define MHI_REG_ACCESS_VALID(pm_state)			((pm_state & (MHI_PM_POR | MHI_PM_M0 | \
 						MHI_PM_M2 | MHI_PM_M3_ENTER | MHI_PM_M3_EXIT | \
 						MHI_PM_SYS_ERR_DETECT | MHI_PM_SYS_ERR_PROCESS | \
-						MHI_PM_SHUTDOWN_PROCESS | MHI_PM_FW_DL_ERR)))
+						MHI_PM_SYS_ERR_FAIL | MHI_PM_SHUTDOWN_PROCESS |  \
+						MHI_PM_FW_DL_ERR)))
 #define MHI_PM_IN_ERROR_STATE(pm_state)			(pm_state >= MHI_PM_FW_DL_ERR)
 #define MHI_PM_IN_FATAL_STATE(pm_state)			(pm_state == MHI_PM_LD_ERR_FATAL_DETECT)
 #define MHI_DB_ACCESS_VALID(mhi_cntrl)			(mhi_cntrl->pm_state & mhi_cntrl->db_access)
--- linux-qcom-6.8.0.orig/drivers/bus/mhi/host/pci_generic.c
+++ linux-qcom-6.8.0/drivers/bus/mhi/host/pci_generic.c
@@ -239,6 +239,19 @@
 		.channel = ch_num,		\
 	}
 
+static const struct mhi_channel_config modem_qcom_v2_mhi_channels[] = {
+	MHI_CHANNEL_CONFIG_UL(46, "IP_SW0", 2048, 1),
+	MHI_CHANNEL_CONFIG_DL(47, "IP_SW0", 2048, 2),
+};
+
+static struct mhi_event_config modem_qcom_v2_mhi_events[] = {
+	/* first ring is control+data ring */
+	MHI_EVENT_CONFIG_CTRL(0, 64),
+	/* Software channels dedicated event ring */
+	MHI_EVENT_CONFIG_SW_DATA(1, 64),
+	MHI_EVENT_CONFIG_SW_DATA(2, 64),
+};
+
 static const struct mhi_channel_config modem_qcom_v1_mhi_channels[] = {
 	MHI_CHANNEL_CONFIG_UL(4, "DIAG", 16, 1),
 	MHI_CHANNEL_CONFIG_DL(5, "DIAG", 16, 1),
@@ -279,6 +292,15 @@
 	.event_cfg = modem_qcom_v1_mhi_events,
 };
 
+static const struct mhi_controller_config modem_qcom_v3_mhiv_config = {
+	.max_channels = 128,
+	.timeout_ms = 8000,
+	.num_channels = ARRAY_SIZE(modem_qcom_v2_mhi_channels),
+	.ch_cfg = modem_qcom_v2_mhi_channels,
+	.num_events = ARRAY_SIZE(modem_qcom_v2_mhi_events),
+	.event_cfg = modem_qcom_v2_mhi_events,
+};
+
 static const struct mhi_controller_config modem_qcom_v1_mhiv_config = {
 	.max_channels = 128,
 	.timeout_ms = 8000,
@@ -295,6 +317,14 @@
 	.config = &modem_qcom_v2_mhiv_config,
 	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
 	.dma_data_width = 32,
+};
+
+static const struct mhi_pci_dev_info mhi_qcom_sa8775p_info = {
+	.name = "qcom-sa8775p",
+	.config = &modem_qcom_v3_mhiv_config,
+	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
+	.dma_data_width = 32,
+	.mru_default = 32768,
 	.sideband_wake = false,
 };
 
@@ -598,8 +628,19 @@
 	.mru_default = 32768,
 };
 
+static const struct mhi_pci_dev_info mhi_telit_fe990a_info = {
+	.name = "telit-fe990a",
+	.config = &modem_telit_fn990_config,
+	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
+	.dma_data_width = 32,
+	.sideband_wake = false,
+	.mru_default = 32768,
+};
+
 /* Keep the list sorted based on the PID. New VID should be added as the last entry */
 static const struct pci_device_id mhi_pci_id_table[] = {
+	{PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0116),
+		.driver_data = (kernel_ulong_t) &mhi_qcom_sa8775p_info },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0304),
 		.driver_data = (kernel_ulong_t) &mhi_qcom_sdx24_info },
 	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, PCI_VENDOR_ID_QCOM, 0x010c),
@@ -615,9 +656,9 @@
 	/* Telit FN990 */
 	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2010),
 		.driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
-	/* Telit FE990 */
+	/* Telit FE990A */
 	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0308, 0x1c5d, 0x2015),
-		.driver_data = (kernel_ulong_t) &mhi_telit_fn990_info },
+		.driver_data = (kernel_ulong_t) &mhi_telit_fe990a_info },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0308),
 		.driver_data = (kernel_ulong_t) &mhi_qcom_sdx65_info },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0309),
--- linux-qcom-6.8.0.orig/drivers/bus/mhi/host/pm.c
+++ linux-qcom-6.8.0/drivers/bus/mhi/host/pm.c
@@ -36,7 +36,10 @@
  *     M0 <--> M0
  *     M0 -> FW_DL_ERR
  *     M0 -> M3_ENTER -> M3 -> M3_EXIT --> M0
- * L1: SYS_ERR_DETECT -> SYS_ERR_PROCESS --> POR
+ * L1: SYS_ERR_DETECT -> SYS_ERR_PROCESS
+ *     SYS_ERR_PROCESS -> SYS_ERR_FAIL
+ *     SYS_ERR_FAIL -> SYS_ERR_DETECT
+ *     SYS_ERR_PROCESS --> POR
  * L2: SHUTDOWN_PROCESS -> LD_ERR_FATAL_DETECT
  *     SHUTDOWN_PROCESS -> DISABLE
  * L3: LD_ERR_FATAL_DETECT <--> LD_ERR_FATAL_DETECT
@@ -93,7 +96,12 @@
 	},
 	{
 		MHI_PM_SYS_ERR_PROCESS,
-		MHI_PM_POR | MHI_PM_SHUTDOWN_PROCESS |
+		MHI_PM_POR | MHI_PM_SYS_ERR_FAIL | MHI_PM_SHUTDOWN_PROCESS |
+		MHI_PM_LD_ERR_FATAL_DETECT
+	},
+	{
+		MHI_PM_SYS_ERR_FAIL,
+		MHI_PM_SYS_ERR_DETECT | MHI_PM_SHUTDOWN_PROCESS |
 		MHI_PM_LD_ERR_FATAL_DETECT
 	},
 	/* L2 States */
@@ -629,7 +637,13 @@
 					!in_reset, timeout);
 		if (!ret || in_reset) {
 			dev_err(dev, "Device failed to exit MHI Reset state\n");
-			goto exit_sys_error_transition;
+			write_lock_irq(&mhi_cntrl->pm_lock);
+			cur_state = mhi_tryset_pm_state(mhi_cntrl,
+							MHI_PM_SYS_ERR_FAIL);
+			write_unlock_irq(&mhi_cntrl->pm_lock);
+			/* Shutdown may have occurred, otherwise cleanup now */
+			if (cur_state != MHI_PM_SYS_ERR_FAIL)
+				goto exit_sys_error_transition;
 		}
 
 		/*
--- linux-qcom-6.8.0.orig/drivers/bus/ti-sysc.c
+++ linux-qcom-6.8.0/drivers/bus/ti-sysc.c
@@ -2283,11 +2283,9 @@
 			      const char *name)
 {
 	struct device_node *np = ddata->dev->of_node;
-	struct property *prop;
-	const __be32 *p;
 	u32 val;
 
-	of_property_for_each_u32(np, name, prop, p, val) {
+	of_property_for_each_u32(np, name, val) {
 		if (val >= SYSC_NR_IDLEMODES) {
 			dev_err(ddata->dev, "invalid idlemode: %i\n", val);
 			return -EINVAL;
--- linux-qcom-6.8.0.orig/drivers/cdrom/cdrom.c
+++ linux-qcom-6.8.0/drivers/cdrom/cdrom.c
@@ -282,7 +282,7 @@
 /* default compatibility mode */
 static bool autoclose=1;
 static bool autoeject;
-static bool lockdoor = 1;
+static bool lockdoor = 0;
 /* will we ever get to use this... sigh. */
 static bool check_media_type;
 /* automatically restart mrw format */
@@ -2313,7 +2313,7 @@
 		return -EINVAL;
 
 	/* Prevent arg from speculatively bypassing the length check */
-	barrier_nospec();
+	arg = array_index_nospec(arg, cdi->capacity);
 
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
@@ -2358,7 +2358,7 @@
 		return -EFAULT;
 
 	tmp_info.media_flags = 0;
-	if (tmp_info.last_media_change - cdi->last_media_change_ms < 0)
+	if (cdi->last_media_change_ms > tmp_info.last_media_change)
 		tmp_info.media_flags |= MEDIA_CHANGED_FLAG;
 
 	tmp_info.last_media_change = cdi->last_media_change_ms;
--- linux-qcom-6.8.0.orig/drivers/char/Kconfig
+++ linux-qcom-6.8.0/drivers/char/Kconfig
@@ -410,6 +410,14 @@
 
 source "drivers/char/xillybus/Kconfig"
 
+config MSM_RDBG
+	tristate "QTI Remote debug driver"
+	help
+	Implements a shared memory based transport mechanism that allows
+	for a debugger running on a host PC to communicate with a remote
+	stub running on peripheral subsystems such as the ADSP, MODEM etc.
+		Say M if you want to enable this module.
+
 config ADI
 	tristate "SPARC Privileged ADI driver"
 	depends on SPARC64
--- linux-qcom-6.8.0.orig/drivers/char/Makefile
+++ linux-qcom-6.8.0/drivers/char/Makefile
@@ -43,3 +43,4 @@
 obj-$(CONFIG_XILLYBUS_CLASS)	+= xillybus/
 obj-$(CONFIG_POWERNV_OP_PANEL)	+= powernv-op-panel.o
 obj-$(CONFIG_ADI)		+= adi.o
+obj-$(CONFIG_MSM_RDBG)		+= rdbg.o
--- linux-qcom-6.8.0.orig/drivers/char/hpet.c
+++ linux-qcom-6.8.0/drivers/char/hpet.c
@@ -270,8 +270,13 @@
 	if (!devp->hd_ireqfreq)
 		return -EIO;
 
-	if (count < sizeof(unsigned long))
-		return -EINVAL;
+	if (in_compat_syscall()) {
+		if (count < sizeof(compat_ulong_t))
+			return -EINVAL;
+	} else {
+		if (count < sizeof(unsigned long))
+			return -EINVAL;
+	}
 
 	add_wait_queue(&devp->hd_waitqueue, &wait);
 
@@ -295,9 +300,16 @@
 		schedule();
 	}
 
-	retval = put_user(data, (unsigned long __user *)buf);
-	if (!retval)
-		retval = sizeof(unsigned long);
+	if (in_compat_syscall()) {
+		retval = put_user(data, (compat_ulong_t __user *)buf);
+		if (!retval)
+			retval = sizeof(compat_ulong_t);
+	} else {
+		retval = put_user(data, (unsigned long __user *)buf);
+		if (!retval)
+			retval = sizeof(unsigned long);
+	}
+
 out:
 	__set_current_state(TASK_RUNNING);
 	remove_wait_queue(&devp->hd_waitqueue, &wait);
@@ -652,12 +664,24 @@
 	unsigned short hi_timer;
 };
 
+/* 32-bit types would lead to different command codes which should be
+ * translated into 64-bit ones before passed to hpet_ioctl_common
+ */
+#define COMPAT_HPET_INFO       _IOR('h', 0x03, struct compat_hpet_info)
+#define COMPAT_HPET_IRQFREQ    _IOW('h', 0x6, compat_ulong_t)
+
 static long
 hpet_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct hpet_info info;
 	int err;
 
+	if (cmd == COMPAT_HPET_INFO)
+		cmd = HPET_INFO;
+
+	if (cmd == COMPAT_HPET_IRQFREQ)
+		cmd = HPET_IRQFREQ;
+
 	mutex_lock(&hpet_mutex);
 	err = hpet_ioctl_common(file->private_data, cmd, arg, &info);
 	mutex_unlock(&hpet_mutex);
--- linux-qcom-6.8.0.orig/drivers/char/hw_random/amd-rng.c
+++ linux-qcom-6.8.0/drivers/char/hw_random/amd-rng.c
@@ -143,8 +143,10 @@
 
 found:
 	err = pci_read_config_dword(pdev, 0x58, &pmbase);
-	if (err)
+	if (err) {
+		err = pcibios_err_to_errno(err);
 		goto put_dev;
+	}
 
 	pmbase &= 0x0000FF00;
 	if (pmbase == 0) {
--- linux-qcom-6.8.0.orig/drivers/char/hw_random/bcm2835-rng.c
+++ linux-qcom-6.8.0/drivers/char/hw_random/bcm2835-rng.c
@@ -94,8 +94,10 @@
 		return ret;
 
 	ret = reset_control_reset(priv->reset);
-	if (ret)
+	if (ret) {
+		clk_disable_unprepare(priv->clk);
 		return ret;
+	}
 
 	if (priv->mask_interrupts) {
 		/* mask the interrupt */
--- linux-qcom-6.8.0.orig/drivers/char/hw_random/cctrng.c
+++ linux-qcom-6.8.0/drivers/char/hw_random/cctrng.c
@@ -622,6 +622,7 @@
 	/* wait for Cryptocell reset completion */
 	if (!cctrng_wait_for_reset_completion(drvdata)) {
 		dev_err(dev, "Cryptocell reset not completed");
+		clk_disable_unprepare(drvdata->clk);
 		return -EBUSY;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/char/hw_random/core.c
+++ linux-qcom-6.8.0/drivers/char/hw_random/core.c
@@ -174,7 +174,6 @@
 	reinit_completion(&rng->cleanup_done);
 
 skip_init:
-	rng->quality = min_t(u16, min_t(u16, default_quality, 1024), rng->quality ?: 1024);
 	current_quality = rng->quality; /* obsolete */
 
 	return 0;
@@ -563,6 +562,9 @@
 	complete(&rng->cleanup_done);
 	init_completion(&rng->dying);
 
+	/* Adjust quality field to always have a proper value */
+	rng->quality = min_t(u16, min_t(u16, default_quality, 1024), rng->quality ?: 1024);
+
 	if (!current_rng ||
 	    (!cur_rng_set_by_user && rng->quality > current_rng->quality)) {
 		/*
--- linux-qcom-6.8.0.orig/drivers/char/hw_random/mtk-rng.c
+++ linux-qcom-6.8.0/drivers/char/hw_random/mtk-rng.c
@@ -142,7 +142,7 @@
 	dev_set_drvdata(&pdev->dev, priv);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, RNG_AUTOSUSPEND_TIMEOUT);
 	pm_runtime_use_autosuspend(&pdev->dev);
-	pm_runtime_enable(&pdev->dev);
+	devm_pm_runtime_enable(&pdev->dev);
 
 	dev_info(&pdev->dev, "registered RNG driver\n");
 
--- linux-qcom-6.8.0.orig/drivers/char/hw_random/stm32-rng.c
+++ linux-qcom-6.8.0/drivers/char/hw_random/stm32-rng.c
@@ -220,7 +220,8 @@
 				if (err && i > RNG_NB_RECOVER_TRIES) {
 					dev_err((struct device *)priv->rng.priv,
 						"Couldn't recover from seed error\n");
-					return -ENOTRECOVERABLE;
+					retval = -ENOTRECOVERABLE;
+					goto exit_rpm;
 				}
 
 				continue;
@@ -238,7 +239,8 @@
 			if (err && i > RNG_NB_RECOVER_TRIES) {
 				dev_err((struct device *)priv->rng.priv,
 					"Couldn't recover from seed error");
-				return -ENOTRECOVERABLE;
+				retval = -ENOTRECOVERABLE;
+				goto exit_rpm;
 			}
 
 			continue;
@@ -250,6 +252,7 @@
 		max -= sizeof(u32);
 	}
 
+exit_rpm:
 	pm_runtime_mark_last_busy((struct device *) priv->rng.priv);
 	pm_runtime_put_sync_autosuspend((struct device *) priv->rng.priv);
 
@@ -353,13 +356,15 @@
 	err = readl_relaxed_poll_timeout_atomic(priv->base + RNG_SR, reg,
 						reg & RNG_SR_DRDY,
 						10, 100000);
-	if (err | (reg & ~RNG_SR_DRDY)) {
+	if (err || (reg & ~RNG_SR_DRDY)) {
 		clk_disable_unprepare(priv->clk);
 		dev_err((struct device *)priv->rng.priv,
 			"%s: timeout:%x SR: %x!\n", __func__, err, reg);
 		return -EINVAL;
 	}
 
+	clk_disable_unprepare(priv->clk);
+
 	return 0;
 }
 
@@ -384,6 +389,11 @@
 static int __maybe_unused stm32_rng_suspend(struct device *dev)
 {
 	struct stm32_rng_private *priv = dev_get_drvdata(dev);
+	int err;
+
+	err = clk_prepare_enable(priv->clk);
+	if (err)
+		return err;
 
 	if (priv->data->has_cond_reset) {
 		priv->pm_conf.nscr = readl_relaxed(priv->base + RNG_NSCR);
@@ -465,6 +475,8 @@
 		writel_relaxed(reg, priv->base + RNG_CR);
 	}
 
+	clk_disable_unprepare(priv->clk);
+
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/char/ipmi/ipmb_dev_int.c
+++ linux-qcom-6.8.0/drivers/char/ipmi/ipmb_dev_int.c
@@ -321,6 +321,9 @@
 	ipmb_dev->miscdev.name = devm_kasprintf(&client->dev, GFP_KERNEL,
 						"%s%d", "ipmb-",
 						client->adapter->nr);
+	if (!ipmb_dev->miscdev.name)
+		return -ENOMEM;
+
 	ipmb_dev->miscdev.fops = &ipmb_fops;
 	ipmb_dev->miscdev.parent = &client->dev;
 	ret = misc_register(&ipmb_dev->miscdev);
--- linux-qcom-6.8.0.orig/drivers/char/ipmi/ssif_bmc.c
+++ linux-qcom-6.8.0/drivers/char/ipmi/ssif_bmc.c
@@ -177,13 +177,15 @@
 	unsigned long flags;
 	ssize_t ret;
 
-	if (count > sizeof(struct ipmi_ssif_msg))
+	if (count < sizeof(msg.len) ||
+	    count > sizeof(struct ipmi_ssif_msg))
 		return -EINVAL;
 
 	if (copy_from_user(&msg, buf, count))
 		return -EFAULT;
 
-	if (!msg.len || count < sizeof_field(struct ipmi_ssif_msg, len) + msg.len)
+	if (!msg.len || msg.len > IPMI_SSIF_PAYLOAD_MAX ||
+	    count < sizeof_field(struct ipmi_ssif_msg, len) + msg.len)
 		return -EINVAL;
 
 	spin_lock_irqsave(&ssif_bmc->lock, flags);
@@ -290,7 +292,6 @@
 	ssif_bmc->nbytes_processed = 0;
 	ssif_bmc->remain_len = 0;
 	ssif_bmc->busy = false;
-	memset(&ssif_bmc->part_buf, 0, sizeof(struct ssif_part_buffer));
 	wake_up_all(&ssif_bmc->wait_queue);
 }
 
@@ -742,9 +743,11 @@
 			ssif_bmc->aborting = true;
 		}
 	} else if (ssif_bmc->state == SSIF_RES_SENDING) {
-		if (ssif_bmc->is_singlepart_read || ssif_bmc->block_num == 0xFF)
+		if (ssif_bmc->is_singlepart_read || ssif_bmc->block_num == 0xFF) {
+			memset(&ssif_bmc->part_buf, 0, sizeof(struct ssif_part_buffer));
 			/* Invalidate response buffer to denote it is sent */
 			complete_response(ssif_bmc);
+		}
 		ssif_bmc->state = SSIF_READY;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/char/misc.c
+++ linux-qcom-6.8.0/drivers/char/misc.c
@@ -63,16 +63,30 @@
 #define DYNAMIC_MINORS 128 /* like dynamic majors */
 static DEFINE_IDA(misc_minors_ida);
 
-static int misc_minor_alloc(void)
+static int misc_minor_alloc(int minor)
 {
-	int ret;
+	int ret = 0;
 
-	ret = ida_alloc_max(&misc_minors_ida, DYNAMIC_MINORS - 1, GFP_KERNEL);
-	if (ret >= 0) {
-		ret = DYNAMIC_MINORS - ret - 1;
+	if (minor == MISC_DYNAMIC_MINOR) {
+		/* allocate free id */
+		ret = ida_alloc_max(&misc_minors_ida, DYNAMIC_MINORS - 1, GFP_KERNEL);
+		if (ret >= 0) {
+			ret = DYNAMIC_MINORS - ret - 1;
+		} else {
+			ret = ida_alloc_range(&misc_minors_ida, MISC_DYNAMIC_MINOR + 1,
+					      MINORMASK, GFP_KERNEL);
+		}
 	} else {
-		ret = ida_alloc_range(&misc_minors_ida, MISC_DYNAMIC_MINOR + 1,
-				      MINORMASK, GFP_KERNEL);
+		/* specific minor, check if it is in dynamic or misc dynamic range  */
+		if (minor < DYNAMIC_MINORS) {
+			minor = DYNAMIC_MINORS - minor - 1;
+			ret = ida_alloc_range(&misc_minors_ida, minor, minor, GFP_KERNEL);
+		} else if (minor > MISC_DYNAMIC_MINOR) {
+			ret = ida_alloc_range(&misc_minors_ida, minor, minor, GFP_KERNEL);
+		} else {
+			/* case of non-dynamic minors, no need to allocate id */
+			ret = 0;
+		}
 	}
 	return ret;
 }
@@ -219,7 +233,7 @@
 	mutex_lock(&misc_mtx);
 
 	if (is_dynamic) {
-		int i = misc_minor_alloc();
+		int i = misc_minor_alloc(misc->minor);
 
 		if (i < 0) {
 			err = -EBUSY;
@@ -228,6 +242,7 @@
 		misc->minor = i;
 	} else {
 		struct miscdevice *c;
+		int i;
 
 		list_for_each_entry(c, &misc_list, list) {
 			if (c->minor == misc->minor) {
@@ -235,6 +250,12 @@
 				goto out;
 			}
 		}
+
+		i = misc_minor_alloc(misc->minor);
+		if (i < 0) {
+			err = -EBUSY;
+			goto out;
+		}
 	}
 
 	dev = MKDEV(MISC_MAJOR, misc->minor);
@@ -243,8 +264,8 @@
 		device_create_with_groups(&misc_class, misc->parent, dev,
 					  misc, misc->groups, "%s", misc->name);
 	if (IS_ERR(misc->this_device)) {
+		misc_minor_free(misc->minor);
 		if (is_dynamic) {
-			misc_minor_free(misc->minor);
 			misc->minor = MISC_DYNAMIC_MINOR;
 		}
 		err = PTR_ERR(misc->this_device);
--- linux-qcom-6.8.0.orig/drivers/char/ppdev.c
+++ linux-qcom-6.8.0/drivers/char/ppdev.c
@@ -296,28 +296,35 @@
 	if (!port) {
 		pr_warn("%s: no associated port!\n", name);
 		rc = -ENXIO;
-		goto err;
+		goto err_free_name;
 	}
 
 	index = ida_alloc(&ida_index, GFP_KERNEL);
+	if (index < 0) {
+		pr_warn("%s: failed to get index!\n", name);
+		rc = index;
+		goto err_put_port;
+	}
+
 	memset(&ppdev_cb, 0, sizeof(ppdev_cb));
 	ppdev_cb.irq_func = pp_irq;
 	ppdev_cb.flags = (pp->flags & PP_EXCL) ? PARPORT_FLAG_EXCL : 0;
 	ppdev_cb.private = pp;
 	pdev = parport_register_dev_model(port, name, &ppdev_cb, index);
-	parport_put_port(port);
 
 	if (!pdev) {
 		pr_warn("%s: failed to register device!\n", name);
 		rc = -ENXIO;
 		ida_free(&ida_index, index);
-		goto err;
+		goto err_put_port;
 	}
 
 	pp->pdev = pdev;
 	pp->index = index;
 	dev_dbg(&pdev->dev, "registered pardevice\n");
-err:
+err_put_port:
+	parport_put_port(port);
+err_free_name:
 	kfree(name);
 	return rc;
 }
--- linux-qcom-6.8.0.orig/drivers/char/random.c
+++ linux-qcom-6.8.0/drivers/char/random.c
@@ -702,7 +702,7 @@
 
 static void __cold _credit_init_bits(size_t bits)
 {
-	static struct execute_work set_ready;
+	static DECLARE_WORK(set_ready, crng_set_ready);
 	unsigned int new, orig, add;
 	unsigned long flags;
 
@@ -718,8 +718,8 @@
 
 	if (orig < POOL_READY_BITS && new >= POOL_READY_BITS) {
 		crng_reseed(NULL); /* Sets crng_init to CRNG_READY under base_crng.lock. */
-		if (static_key_initialized)
-			execute_in_process_context(crng_set_ready, &set_ready);
+		if (static_key_initialized && system_unbound_wq)
+			queue_work(system_unbound_wq, &set_ready);
 		atomic_notifier_call_chain(&random_ready_notifier, 0, NULL);
 		wake_up_interruptible(&crng_init_wait);
 		kill_fasync(&fasync, SIGIO, POLL_IN);
@@ -890,8 +890,8 @@
 
 	/*
 	 * If we were initialized by the cpu or bootloader before jump labels
-	 * are initialized, then we should enable the static branch here, where
-	 * it's guaranteed that jump labels have been initialized.
+	 * or workqueues are initialized, then we should enable the static
+	 * branch here, where it's guaranteed that these have been initialized.
 	 */
 	if (!static_branch_likely(&crng_is_ready) && crng_init >= CRNG_READY)
 		crng_set_ready(NULL);
--- linux-qcom-6.8.0.orig/drivers/char/rdbg.c
+++ linux-qcom-6.8.0/drivers/char/rdbg.c
@@ -0,0 +1,1241 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
+ * ​​​​Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/soc/qcom/smem.h>
+#include <linux/uaccess.h>
+#include <linux/interrupt.h>
+#include <linux/soc/qcom/smem_state.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#define SMP2P_NUM_PROCS				32
+#define MAX_RETRIES				20
+
+#define SM_VERSION				1
+#define SM_BLOCKSIZE				128
+
+#define SMQ_MAGIC_INIT				0xFF00FF00
+#define SMQ_MAGIC_PRODUCER			(SMQ_MAGIC_INIT | 0x1)
+#define SMQ_MAGIC_CONSUMER			(SMQ_MAGIC_INIT | 0x2)
+
+#define SMEM_LC_DEBUGGER 470
+
+static DECLARE_COMPLETION(rdbg_driver_probe_done);
+
+enum SMQ_STATUS {
+	SMQ_SUCCESS    =  0,
+	SMQ_ENOMEMORY  = -1,
+	SMQ_EBADPARM   = -2,
+	SMQ_UNDERFLOW  = -3,
+	SMQ_OVERFLOW   = -4
+};
+
+enum smq_type {
+	PRODUCER = 1,
+	CONSUMER = 2,
+	INVALID  = 3
+};
+
+struct smq_block_map {
+	uint32_t index_read;
+	uint32_t num_blocks;
+	uint8_t *map;
+};
+
+struct smq_node {
+	uint16_t index_block;
+	uint16_t num_blocks;
+} __packed;
+
+struct smq_hdr {
+	uint8_t producer_version;
+	uint8_t consumer_version;
+} __packed;
+
+struct smq_out_state {
+	uint32_t init;
+	uint32_t index_check_queue_for_reset;
+	uint32_t index_sent_write;
+	uint32_t index_free_read;
+} __packed;
+
+struct smq_out {
+	struct smq_out_state s;
+	struct smq_node sent[];
+};
+
+struct smq_in_state {
+	uint32_t init;
+	uint32_t index_check_queue_for_reset_ack;
+	uint32_t index_sent_read;
+	uint32_t index_free_write;
+} __packed;
+
+struct smq_in {
+	struct smq_in_state s;
+	struct smq_node free[];
+};
+
+struct smq {
+	struct smq_hdr *hdr;
+	struct smq_out *out;
+	struct smq_in *in;
+	uint8_t *blocks;
+	uint32_t num_blocks;
+	struct mutex *lock;
+	uint32_t initialized;
+	struct smq_block_map block_map;
+	enum smq_type type;
+};
+
+struct gpio_info {
+	int gpio_base_id;
+	int irq_base_id;
+	unsigned int smem_bit;
+	struct qcom_smem_state *smem_state;
+};
+
+struct rdbg_data {
+	struct device *device;
+	struct completion work;
+	struct gpio_info in;
+	struct gpio_info out;
+	bool   device_initialized;
+	int    gpio_out_offset;
+	bool   device_opened;
+	void   *smem_addr;
+	size_t smem_size;
+	struct smq    producer_smrb;
+	struct smq    consumer_smrb;
+	struct mutex  write_mutex;
+	int smp2p_data[32];
+};
+
+struct rdbg_device {
+	struct cdev cdev;
+	struct class *class;
+	dev_t dev_no;
+	int num_devices;
+	struct rdbg_data *rdbg_data;
+};
+
+static struct rdbg_device g_rdbg_instance = {
+	.class = NULL,
+	.dev_no = 0,
+	.num_devices = SMP2P_NUM_PROCS,
+	.rdbg_data = NULL,
+};
+
+struct processor_specific_info {
+	char *name;
+	unsigned int smem_buffer_addr;
+	size_t smem_buffer_size;
+};
+
+static struct processor_specific_info proc_info[SMP2P_NUM_PROCS] = {
+		{0},	/*APPS*/
+		{"rdbg_modem", 0, 0},	/*MODEM*/
+		{"rdbg_adsp", SMEM_LC_DEBUGGER, 16*1024},	/*ADSP*/
+		{0},	/*SMP2P_RESERVED_PROC_1*/
+		{"rdbg_wcnss", 0, 0},		/*WCNSS*/
+		{"rdbg_cdsp", SMEM_LC_DEBUGGER, 16*1024},		/*CDSP*/
+		{NULL},	/*SMP2P_POWER_PROC*/
+		{NULL},	/*SMP2P_TZ_PROC*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{"rdbg_cdsp1", SMEM_LC_DEBUGGER, 16*1024},		/*CDSP1*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*SMP2P_REMOTE_MOCK_PROC*/
+		{NULL},	/*EMPTY*/
+		{"rdbg_gdsp0", SMEM_LC_DEBUGGER, 16*1024},		/*GDSP0*/
+		{"rdbg_gdsp1", SMEM_LC_DEBUGGER, 16*1024},		/*GDSP1*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{NULL},	/*EMPTY*/
+		{NULL}	/*EMPTY*/
+};
+
+static int smq_blockmap_get(struct smq_block_map *block_map,
+	uint32_t *block_index, uint32_t n)
+{
+	uint32_t start;
+	uint32_t mark = 0;
+	uint32_t found = 0;
+	uint32_t i = 0;
+
+	start = block_map->index_read;
+
+	if (n == 1) {
+		do {
+			if (!block_map->map[block_map->index_read]) {
+				*block_index = block_map->index_read;
+				block_map->map[block_map->index_read] = 1;
+				block_map->index_read++;
+				block_map->index_read %= block_map->num_blocks;
+				return SMQ_SUCCESS;
+			}
+			block_map->index_read++;
+		} while (start != (block_map->index_read %=
+			block_map->num_blocks));
+	} else {
+		mark = block_map->num_blocks;
+
+		do {
+			if (!block_map->map[block_map->index_read]) {
+				if (mark > block_map->index_read) {
+					mark = block_map->index_read;
+					start = block_map->index_read;
+					found = 0;
+				}
+
+				found++;
+				if (found == n) {
+					*block_index = mark;
+					for (i = 0; i < n; i++)
+						block_map->map[mark + i] =
+							(uint8_t)(n - i);
+					block_map->index_read += block_map->map
+						[block_map->index_read] - 1;
+					return SMQ_SUCCESS;
+				}
+			} else {
+				found = 0;
+				block_map->index_read += block_map->map
+					[block_map->index_read] - 1;
+				mark = block_map->num_blocks;
+			}
+			block_map->index_read++;
+		} while (start != (block_map->index_read %=
+			block_map->num_blocks));
+	}
+
+	return SMQ_ENOMEMORY;
+}
+
+static void smq_blockmap_put(struct smq_block_map *block_map, uint32_t i)
+{
+	uint32_t num_blocks = block_map->map[i];
+
+	while (num_blocks--) {
+		block_map->map[i] = 0;
+		i++;
+	}
+}
+
+static int smq_blockmap_reset(struct smq_block_map *block_map)
+{
+	if (!block_map->map)
+		return SMQ_ENOMEMORY;
+	memset(block_map->map, 0, block_map->num_blocks + 1);
+	block_map->index_read = 0;
+
+	return SMQ_SUCCESS;
+}
+
+static int smq_blockmap_ctor(struct smq_block_map *block_map,
+	uint32_t num_blocks)
+{
+	if (num_blocks <= 1)
+		return SMQ_ENOMEMORY;
+
+	block_map->map = kcalloc(num_blocks, sizeof(uint8_t), GFP_KERNEL);
+	if (!block_map->map)
+		return SMQ_ENOMEMORY;
+
+	block_map->num_blocks = num_blocks - 1;
+	smq_blockmap_reset(block_map);
+
+	return SMQ_SUCCESS;
+}
+
+static void smq_blockmap_dtor(struct smq_block_map *block_map)
+{
+	kfree(block_map->map);
+	block_map->map = NULL;
+}
+
+static int smq_free(struct smq *smq, void *data)
+{
+	struct smq_node node;
+	uint32_t index_block;
+	int err = SMQ_SUCCESS;
+
+	if (smq->lock)
+		mutex_lock(smq->lock);
+
+	if ((smq->hdr->producer_version != SM_VERSION) &&
+		(smq->out->s.init != SMQ_MAGIC_PRODUCER)) {
+		err = SMQ_UNDERFLOW;
+		goto bail;
+	}
+
+	index_block = ((uint8_t *)data - smq->blocks) / SM_BLOCKSIZE;
+	if (index_block >= smq->num_blocks) {
+		err = SMQ_EBADPARM;
+		goto bail;
+	}
+
+	node.index_block = (uint16_t)index_block;
+	node.num_blocks = 0;
+	*((struct smq_node *)(smq->in->free +
+		smq->in->s.index_free_write)) = node;
+
+	smq->in->s.index_free_write = (smq->in->s.index_free_write + 1)
+		% smq->num_blocks;
+
+bail:
+	if (smq->lock)
+		mutex_unlock(smq->lock);
+	return err;
+}
+
+static int smq_receive(struct smq *smq, void **pp, int *pnsize, int *pbmore)
+{
+	struct smq_node *node;
+	int err = SMQ_SUCCESS;
+	int more = 0;
+
+	if ((smq->hdr->producer_version != SM_VERSION) &&
+		(smq->out->s.init != SMQ_MAGIC_PRODUCER))
+		return SMQ_UNDERFLOW;
+
+	if (smq->in->s.index_sent_read == smq->out->s.index_sent_write) {
+		err = SMQ_UNDERFLOW;
+		goto bail;
+	}
+
+	node = (struct smq_node *)(smq->out->sent + smq->in->s.index_sent_read);
+	if (node->index_block >= smq->num_blocks) {
+		err = SMQ_EBADPARM;
+		goto bail;
+	}
+
+	smq->in->s.index_sent_read = (smq->in->s.index_sent_read + 1)
+		% smq->num_blocks;
+
+	*pp = smq->blocks + (node->index_block * SM_BLOCKSIZE);
+	*pnsize = SM_BLOCKSIZE * node->num_blocks;
+
+	/*
+	 * Ensure that the reads and writes are updated in the memory
+	 * when they are done and not cached. Also, ensure that the reads
+	 * and writes are not reordered as they are shared between two cores.
+	 */
+	rmb();
+	if (smq->in->s.index_sent_read != smq->out->s.index_sent_write)
+		more = 1;
+
+bail:
+	*pbmore = more;
+	return err;
+}
+
+static int smq_alloc_send(struct smq *smq, const uint8_t *pcb, int nsize)
+{
+	void *pv = 0;
+	int num_blocks;
+	uint32_t index_block = 0;
+	int err = SMQ_SUCCESS;
+	struct smq_node *node = NULL;
+
+	mutex_lock(smq->lock);
+
+	if ((smq->in->s.init == SMQ_MAGIC_CONSUMER) &&
+	 (smq->hdr->consumer_version == SM_VERSION)) {
+		if (smq->out->s.index_check_queue_for_reset ==
+			smq->in->s.index_check_queue_for_reset_ack) {
+			while (smq->out->s.index_free_read !=
+				smq->in->s.index_free_write) {
+				node = (struct smq_node *)(
+					smq->in->free +
+					smq->out->s.index_free_read);
+				if (node->index_block >= smq->num_blocks) {
+					err = SMQ_EBADPARM;
+					goto bail;
+				}
+
+				smq->out->s.index_free_read =
+					(smq->out->s.index_free_read + 1)
+						% smq->num_blocks;
+
+				smq_blockmap_put(&smq->block_map,
+					node->index_block);
+				/*
+				 * Ensure that the reads and writes are
+				 * updated in the memory when they are done
+				 * and not cached. Also, ensure that the reads
+				 * and writes are not reordered as they are
+				 * shared between two cores.
+				 */
+				rmb();
+			}
+		}
+	}
+
+	num_blocks = ALIGN(nsize, SM_BLOCKSIZE)/SM_BLOCKSIZE;
+	err = smq_blockmap_get(&smq->block_map, &index_block, num_blocks);
+	if (err != SMQ_SUCCESS)
+		goto bail;
+
+	pv = smq->blocks + (SM_BLOCKSIZE * index_block);
+
+	err = copy_from_user((void *)pv, (void *)pcb, nsize);
+	if (err != 0)
+		goto bail;
+
+	((struct smq_node *)(smq->out->sent +
+		smq->out->s.index_sent_write))->index_block
+			= (uint16_t)index_block;
+	((struct smq_node *)(smq->out->sent +
+		smq->out->s.index_sent_write))->num_blocks
+			= (uint16_t)num_blocks;
+
+	smq->out->s.index_sent_write = (smq->out->s.index_sent_write + 1)
+		% smq->num_blocks;
+
+bail:
+	if (err != SMQ_SUCCESS) {
+		if (pv)
+			smq_blockmap_put(&smq->block_map, index_block);
+	}
+	mutex_unlock(smq->lock);
+	return err;
+}
+
+static int smq_reset_producer_queue_internal(struct smq *smq,
+	uint32_t reset_num)
+{
+	int retval = 0;
+	uint32_t i;
+
+	if (smq->type != PRODUCER)
+		goto bail;
+
+	mutex_lock(smq->lock);
+	if (smq->out->s.index_check_queue_for_reset != reset_num) {
+		smq->out->s.index_check_queue_for_reset = reset_num;
+		for (i = 0; i < smq->num_blocks; i++)
+			(smq->out->sent + i)->index_block = 0xFFFF;
+
+		smq_blockmap_reset(&smq->block_map);
+		smq->out->s.index_sent_write = 0;
+		smq->out->s.index_free_read = 0;
+		retval = 1;
+	}
+	mutex_unlock(smq->lock);
+
+bail:
+	return retval;
+}
+
+static int smq_check_queue_reset(struct smq *p_cons, struct smq *p_prod)
+{
+	int retval = 0;
+	uint32_t reset_num, i;
+
+	if ((p_cons->type != CONSUMER) ||
+		(p_cons->out->s.init != SMQ_MAGIC_PRODUCER) ||
+		(p_cons->hdr->producer_version != SM_VERSION))
+		goto bail;
+
+	reset_num = p_cons->out->s.index_check_queue_for_reset;
+	if (p_cons->in->s.index_check_queue_for_reset_ack != reset_num) {
+		p_cons->in->s.index_check_queue_for_reset_ack = reset_num;
+		for (i = 0; i < p_cons->num_blocks; i++)
+			(p_cons->in->free + i)->index_block = 0xFFFF;
+
+		p_cons->in->s.index_sent_read = 0;
+		p_cons->in->s.index_free_write = 0;
+
+		retval = smq_reset_producer_queue_internal(p_prod, reset_num);
+	}
+
+bail:
+	return retval;
+}
+
+static int check_subsystem_debug_enabled(void *base_addr, int size)
+{
+	int num_blocks;
+	uint8_t *pb_orig;
+	uint8_t *pb;
+	struct smq smq;
+	int err = 0;
+
+	pb = pb_orig = (uint8_t *)base_addr;
+	pb += sizeof(struct smq_hdr);
+	pb = PTR_ALIGN(pb, 8);
+	size -= pb - (uint8_t *)pb_orig;
+	num_blocks = (int)((size - sizeof(struct smq_out_state) -
+		sizeof(struct smq_in_state))/(SM_BLOCKSIZE +
+		sizeof(struct smq_node) * 2));
+	if (num_blocks <= 0) {
+		err = SMQ_EBADPARM;
+		goto bail;
+	}
+
+	pb += num_blocks * SM_BLOCKSIZE;
+	smq.out = (struct smq_out *)pb;
+	pb += sizeof(struct smq_out_state) + (num_blocks *
+		sizeof(struct smq_node));
+	smq.in = (struct smq_in *)pb;
+
+	if (smq.in->s.init != SMQ_MAGIC_CONSUMER) {
+		pr_err("%s, smq in consumer not initialized\n", __func__);
+		err = -ECOMM;
+	}
+
+bail:
+	return err;
+}
+
+static void smq_dtor(struct smq *smq)
+{
+	if (smq->initialized == SMQ_MAGIC_INIT) {
+		switch (smq->type) {
+		case PRODUCER:
+			smq->out->s.init = 0;
+			smq_blockmap_dtor(&smq->block_map);
+			break;
+		case CONSUMER:
+			smq->in->s.init = 0;
+			break;
+		default:
+		case INVALID:
+			break;
+		}
+
+		smq->initialized = 0;
+	}
+}
+
+/*
+ * The shared memory is used as a circular ring buffer in each direction.
+ * Thus we have a bi-directional shared memory channel between the AP
+ * and a subsystem. We call this SMQ. Each memory channel contains a header,
+ * data and a control mechanism that is used to synchronize read and write
+ * of data between the AP and the remote subsystem.
+ *
+ * Overall SMQ memory view:
+ *
+ *    +------------------------------------------------+
+ *    | SMEM buffer                                    |
+ *    |-----------------------+------------------------|
+ *    |Producer: LA           | Producer: Remote       |
+ *    |Consumer: Remote       |           subsystem    |
+ *    |          subsystem    | Consumer: LA           |
+ *    |                       |                        |
+ *    |               Producer|                Consumer|
+ *    +-----------------------+------------------------+
+ *    |                       |
+ *    |                       |
+ *    |                       +--------------------------------------+
+ *    |                                                              |
+ *    |                                                              |
+ *    v                                                              v
+ *    +--------------------------------------------------------------+
+ *    |   Header  |       Data      |            Control             |
+ *    +-----------+---+---+---+-----+----+--+--+-----+---+--+--+-----+
+ *    |           | b | b | b |     | S  |n |n |     | S |n |n |     |
+ *    |  Producer | l | l | l |     | M  |o |o |     | M |o |o |     |
+ *    |    Ver    | o | o | o |     | Q  |d |d |     | Q |d |d |     |
+ *    |-----------| c | c | c | ... |    |e |e | ... |   |e |e | ... |
+ *    |           | k | k | k |     | O  |  |  |     | I |  |  |     |
+ *    |  Consumer |   |   |   |     | u  |0 |1 |     | n |0 |1 |     |
+ *    |    Ver    | 0 | 1 | 2 |     | t  |  |  |     |   |  |  |     |
+ *    +-----------+---+---+---+-----+----+--+--+-----+---+--+--+-----+
+ *                                       |           |
+ *                                       +           |
+ *                                                   |
+ *                          +------------------------+
+ *                          |
+ *                          v
+ *                        +----+----+----+----+
+ *                        | SMQ Nodes         |
+ *                        |----|----|----|----|
+ *                 Node # |  0 |  1 |  2 | ...|
+ *                        |----|----|----|----|
+ * Starting Block Index # |  0 |  3 |  8 | ...|
+ *                        |----|----|----|----|
+ *            # of blocks |  3 |  5 |  1 | ...|
+ *                        +----+----+----+----+
+ *
+ * Header: Contains version numbers for software compatibility to ensure
+ * that both producers and consumers on the AP and subsystems know how to
+ * read from and write to the queue.
+ * Both the producer and consumer versions are 1.
+ *     +---------+-------------------+
+ *     | Size    | Field             |
+ *     +---------+-------------------+
+ *     | 1 byte  | Producer Version  |
+ *     +---------+-------------------+
+ *     | 1 byte  | Consumer Version  |
+ *     +---------+-------------------+
+ *
+ * Data: The data portion contains multiple blocks [0..N] of a fixed size.
+ * The block size SM_BLOCKSIZE is fixed to 128 bytes for header version #1.
+ * Payload sent from the debug agent app is split (if necessary) and placed
+ * in these blocks. The first data block is placed at the next 8 byte aligned
+ * address after the header.
+ *
+ * The number of blocks for a given SMEM allocation is derived as follows:
+ *   Number of Blocks = ((Total Size - Alignment - Size of Header
+ *		- Size of SMQIn - Size of SMQOut)/(SM_BLOCKSIZE))
+ *
+ * The producer maintains a private block map of each of these blocks to
+ * determine which of these blocks in the queue is available and which are free.
+ *
+ * Control:
+ * The control portion contains a list of nodes [0..N] where N is number
+ * of available data blocks. Each node identifies the data
+ * block indexes that contain a particular debug message to be transferred,
+ * and the number of blocks it took to hold the contents of the message.
+ *
+ * Each node has the following structure:
+ *     +---------+-------------------+
+ *     | Size    | Field             |
+ *     +---------+-------------------+
+ *     | 2 bytes |Staring Block Index|
+ *     +---------+-------------------+
+ *     | 2 bytes |Number of Blocks   |
+ *     +---------+-------------------+
+ *
+ * The producer and the consumer update different parts of the control channel
+ * (SMQOut / SMQIn) respectively. Each of these control data structures contains
+ * information about the last node that was written / read, and the actual nodes
+ * that were written/read.
+ *
+ * SMQOut Structure (R/W by producer, R by consumer):
+ *     +---------+-------------------+
+ *     | Size    | Field             |
+ *     +---------+-------------------+
+ *     | 4 bytes | Magic Init Number |
+ *     +---------+-------------------+
+ *     | 4 bytes | Reset             |
+ *     +---------+-------------------+
+ *     | 4 bytes | Last Sent Index   |
+ *     +---------+-------------------+
+ *     | 4 bytes | Index Free Read   |
+ *     +---------+-------------------+
+ *
+ * SMQIn Structure (R/W by consumer, R by producer):
+ *     +---------+-------------------+
+ *     | Size    | Field             |
+ *     +---------+-------------------+
+ *     | 4 bytes | Magic Init Number |
+ *     +---------+-------------------+
+ *     | 4 bytes | Reset ACK         |
+ *     +---------+-------------------+
+ *     | 4 bytes | Last Read Index   |
+ *     +---------+-------------------+
+ *     | 4 bytes | Index Free Write  |
+ *     +---------+-------------------+
+ *
+ * Magic Init Number:
+ * Both SMQ Out and SMQ In initialize this field with a predefined magic
+ * number so as to make sure that both the consumer and producer blocks
+ * have fully initialized and have valid data in the shared memory control area.
+ *	Producer Magic #: 0xFF00FF01
+ *	Consumer Magic #: 0xFF00FF02
+ */
+static int smq_ctor(struct smq *smq, void *base_addr, int size,
+	enum smq_type type, struct mutex *lock_ptr)
+{
+	int num_blocks;
+	uint8_t *pb_orig;
+	uint8_t *pb;
+	uint32_t i;
+	int err;
+
+	if (smq->initialized == SMQ_MAGIC_INIT) {
+		err = SMQ_EBADPARM;
+		goto bail;
+	}
+
+	if (!base_addr || !size) {
+		err = SMQ_EBADPARM;
+		goto bail;
+	}
+
+	if (type == PRODUCER)
+		smq->lock = lock_ptr;
+
+	pb_orig = (uint8_t *)base_addr;
+	smq->hdr = (struct smq_hdr *)pb_orig;
+	pb = pb_orig;
+	pb += sizeof(struct smq_hdr);
+	pb = PTR_ALIGN(pb, 8);
+	size -= pb - (uint8_t *)pb_orig;
+	num_blocks = (int)((size - sizeof(struct smq_out_state) -
+		sizeof(struct smq_in_state))/(SM_BLOCKSIZE +
+		sizeof(struct smq_node) * 2));
+	if (num_blocks <= 0) {
+		err = SMQ_ENOMEMORY;
+		goto bail;
+	}
+
+	smq->blocks = pb;
+	smq->num_blocks = num_blocks;
+	pb += num_blocks * SM_BLOCKSIZE;
+	smq->out = (struct smq_out *)pb;
+	pb += sizeof(struct smq_out_state) + (num_blocks *
+		sizeof(struct smq_node));
+	smq->in = (struct smq_in *)pb;
+	smq->type = type;
+	if (type == PRODUCER) {
+		smq->hdr->producer_version = SM_VERSION;
+		for (i = 0; i < smq->num_blocks; i++)
+			(smq->out->sent + i)->index_block = 0xFFFF;
+
+		err = smq_blockmap_ctor(&smq->block_map, smq->num_blocks);
+		if (err != SMQ_SUCCESS)
+			goto bail;
+
+		smq->out->s.index_sent_write = 0;
+		smq->out->s.index_free_read = 0;
+		if (smq->out->s.init == SMQ_MAGIC_PRODUCER) {
+			smq->out->s.index_check_queue_for_reset += 1;
+		} else {
+			smq->out->s.index_check_queue_for_reset = 1;
+			smq->out->s.init = SMQ_MAGIC_PRODUCER;
+		}
+	} else {
+		smq->hdr->consumer_version = SM_VERSION;
+		for (i = 0; i < smq->num_blocks; i++)
+			(smq->in->free + i)->index_block = 0xFFFF;
+
+		smq->in->s.index_sent_read = 0;
+		smq->in->s.index_free_write = 0;
+		if (smq->out->s.init == SMQ_MAGIC_PRODUCER) {
+			smq->in->s.index_check_queue_for_reset_ack =
+				smq->out->s.index_check_queue_for_reset;
+		} else {
+			smq->in->s.index_check_queue_for_reset_ack = 0;
+		}
+
+		smq->in->s.init = SMQ_MAGIC_CONSUMER;
+	}
+	smq->initialized = SMQ_MAGIC_INIT;
+	err = SMQ_SUCCESS;
+
+bail:
+	return err;
+}
+
+static void send_interrupt_to_subsystem(struct rdbg_data *rdbgdata)
+{
+	unsigned int offset = rdbgdata->gpio_out_offset;
+	unsigned int val;
+
+	val = (rdbgdata->smp2p_data[offset]) ^ (BIT(rdbgdata->out.smem_bit+offset));
+	qcom_smem_state_update_bits(rdbgdata->out.smem_state,
+			BIT(rdbgdata->out.smem_bit+offset), val);
+	rdbgdata->smp2p_data[offset] = val;
+	rdbgdata->gpio_out_offset = (offset + 1) % 32;
+}
+
+static irqreturn_t on_interrupt_from(int irq, void *ptr)
+{
+	struct rdbg_data *rdbgdata = (struct rdbg_data *) ptr;
+
+	dev_dbg(rdbgdata->device, "%s: Received interrupt %d from subsystem\n",
+		__func__, irq);
+	complete(&(rdbgdata->work));
+	return IRQ_HANDLED;
+}
+
+static int initialize_smq(struct rdbg_data *rdbgdata)
+{
+	int err = 0;
+	unsigned char *smem_consumer_buffer = rdbgdata->smem_addr;
+
+	smem_consumer_buffer += (rdbgdata->smem_size/2);
+
+	if (smq_ctor(&(rdbgdata->producer_smrb), (void *)(rdbgdata->smem_addr),
+		((rdbgdata->smem_size)/2), PRODUCER, &rdbgdata->write_mutex)) {
+		dev_err(rdbgdata->device, "%s: smq producer allocation failed\n",
+			__func__);
+		err = -ENOMEM;
+		goto bail;
+	}
+
+	if (smq_ctor(&(rdbgdata->consumer_smrb), (void *)smem_consumer_buffer,
+		((rdbgdata->smem_size)/2), CONSUMER, NULL)) {
+		dev_err(rdbgdata->device, "%s: smq consumer allocation failed\n",
+			__func__);
+		err = -ENOMEM;
+	}
+
+bail:
+	return err;
+
+}
+
+static int rdbg_open(struct inode *inode, struct file *filp)
+{
+	int device_id = -1;
+	struct rdbg_device *device = &g_rdbg_instance;
+	struct rdbg_data *rdbgdata = NULL;
+	int err = 0;
+
+	if (!inode || !device->rdbg_data) {
+		pr_err("Memory not allocated yet\n");
+		err = -ENODEV;
+		goto bail;
+	}
+
+	device_id = MINOR(inode->i_rdev);
+	rdbgdata = &device->rdbg_data[device_id];
+
+	if (rdbgdata->device_opened) {
+		dev_err(rdbgdata->device, "%s: Device already opened\n",
+			__func__);
+		err = -EEXIST;
+		goto bail;
+	}
+
+	rdbgdata->smem_size = proc_info[device_id].smem_buffer_size;
+	if (!rdbgdata->smem_size) {
+		dev_err(rdbgdata->device, "%s: smem not initialized\n",
+			 __func__);
+		err = -ENOMEM;
+		goto bail;
+	}
+
+	rdbgdata->smem_addr = qcom_smem_get(QCOM_SMEM_HOST_ANY,
+			      proc_info[device_id].smem_buffer_addr,
+			      &(rdbgdata->smem_size));
+
+	if (IS_ERR(rdbgdata->smem_addr)) {
+		pr_err("rdbg: Can't retrieve data from common SMEM region.\n"
+				"Retrieving data from device specific partition.\n");
+		if (PTR_ERR(rdbgdata->smem_addr) == -ENOENT) {
+			rdbgdata->smem_addr = qcom_smem_get(device_id,
+					proc_info[device_id].smem_buffer_addr,
+					&(rdbgdata->smem_size));
+		}
+	}
+	if (!rdbgdata->smem_addr) {
+		dev_err(rdbgdata->device, "%s: Could not allocate smem memory\n",
+			__func__);
+		err = -ENOMEM;
+		pr_err("rdbg:Could not allocate smem memory\n");
+		goto bail;
+	}
+	dev_dbg(rdbgdata->device, "%s: SMEM address=0x%lx smem_size=%d\n",
+		__func__, (unsigned long)rdbgdata->smem_addr,
+		(unsigned int)rdbgdata->smem_size);
+
+	if (check_subsystem_debug_enabled(rdbgdata->smem_addr,
+		rdbgdata->smem_size/2)) {
+		dev_err(rdbgdata->device, "%s: Subsystem %s is not debug enabled\n",
+			__func__, proc_info[device_id].name);
+		pr_err("rdbg:Sub system debug is not enabled\n");
+		err = -ECOMM;
+		goto bail;
+	}
+
+	init_completion(&rdbgdata->work);
+
+	err = request_threaded_irq(rdbgdata->in.irq_base_id, NULL,
+	      on_interrupt_from,
+	      IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+	      proc_info[device_id].name, (void *)&device->rdbg_data[device_id]);
+	if (err) {
+		dev_err(rdbgdata->device,
+			"%s: Failed to register interrupt.Err=%d,irqid=%d.\n",
+			__func__, err, rdbgdata->in.irq_base_id);
+		pr_err("rdbg : Failed to register interrupt %d\n", err);
+		goto bail;
+	}
+
+	mutex_init(&rdbgdata->write_mutex);
+
+	err = initialize_smq(rdbgdata);
+	if (err) {
+		dev_err(rdbgdata->device, "Error initializing smq. Err=%d\n",
+			err);
+		pr_err("rdbg: initialize_smq() failed with err %d\n", err);
+		goto smq_bail;
+	}
+
+	rdbgdata->device_opened = true;
+
+	filp->private_data = (void *)rdbgdata;
+	return 0;
+
+smq_bail:
+	smq_dtor(&(rdbgdata->producer_smrb));
+	smq_dtor(&(rdbgdata->consumer_smrb));
+	mutex_destroy(&rdbgdata->write_mutex);
+bail:
+	return err;
+}
+
+static int rdbg_release(struct inode *inode, struct file *filp)
+{
+	int device_id = -1;
+	struct rdbg_device *rdbgdevice = &g_rdbg_instance;
+	struct rdbg_data *rdbgdata = NULL;
+	int err = 0;
+
+	if (!inode || !rdbgdevice->rdbg_data) {
+		pr_err("Memory not allocated yet\n");
+		err = -ENODEV;
+		goto bail;
+	}
+
+	device_id = MINOR(inode->i_rdev);
+	rdbgdata = &rdbgdevice->rdbg_data[device_id];
+
+	if (rdbgdata->device_opened) {
+		dev_dbg(rdbgdata->device, "%s: Destroying %s.\n", __func__,
+			proc_info[device_id].name);
+		rdbgdata->device_opened = false;
+		complete(&(rdbgdata->work));
+		if (rdbgdevice->rdbg_data[device_id].producer_smrb.initialized)
+			smq_dtor(&(
+			rdbgdevice->rdbg_data[device_id].producer_smrb));
+		if (rdbgdevice->rdbg_data[device_id].consumer_smrb.initialized)
+			smq_dtor(&(
+			rdbgdevice->rdbg_data[device_id].consumer_smrb));
+		mutex_destroy(&rdbgdata->write_mutex);
+	}
+
+	filp->private_data = NULL;
+
+bail:
+	return err;
+}
+
+static ssize_t rdbg_read(struct file *filp, char __user *buf, size_t size,
+	loff_t *offset)
+{
+	int err = 0;
+	struct rdbg_data *rdbgdata = filp->private_data;
+	void *p_sent_buffer = NULL;
+	int nsize = 0;
+	int more = 0;
+
+	if (!rdbgdata) {
+		pr_err("Invalid argument\n");
+		err = -EINVAL;
+		goto bail;
+	}
+
+	dev_dbg(rdbgdata->device, "%s: In receive\n", __func__);
+	err = wait_for_completion_interruptible(&(rdbgdata->work));
+	if (err) {
+		dev_err(rdbgdata->device, "%s: Error in wait\n", __func__);
+		goto bail;
+	}
+
+	smq_check_queue_reset(&(rdbgdata->consumer_smrb),
+		&(rdbgdata->producer_smrb));
+	if (smq_receive(&(rdbgdata->consumer_smrb), &p_sent_buffer,
+			&nsize, &more) != SMQ_SUCCESS) {
+		dev_err(rdbgdata->device, "%s: Error in smq_recv(). Err code = %d\n",
+			__func__, err);
+		err = -ENODATA;
+		goto bail;
+	}
+	size = ((size < nsize) ? size : nsize);
+	err = copy_to_user(buf, p_sent_buffer, size);
+	if (err != 0) {
+		dev_err(rdbgdata->device, "%s: Error in copy_to_user(). Err code = %d\n",
+			__func__, err);
+		err = -ENODATA;
+		goto bail;
+	}
+	smq_free(&(rdbgdata->consumer_smrb), p_sent_buffer);
+	err = size;
+	dev_dbg(rdbgdata->device, "%s: Read data to buffer with address 0x%lx\n",
+		__func__, (unsigned long) buf);
+
+bail:
+	return err;
+}
+
+static ssize_t rdbg_write(struct file *filp, const char __user *buf,
+	size_t size, loff_t *offset)
+{
+	int err = 0;
+	int num_retries = 0;
+	struct rdbg_data *rdbgdata = filp->private_data;
+
+	if (!rdbgdata) {
+		pr_err("Invalid argument\n");
+		err = -EINVAL;
+		goto bail;
+	}
+
+	do {
+		err = smq_alloc_send(&(rdbgdata->producer_smrb), buf, size);
+		dev_dbg(rdbgdata->device, "%s, smq_alloc_send returned %d.\n",
+			__func__, err);
+	} while (err != 0 && num_retries++ < MAX_RETRIES);
+
+	if (err != 0) {
+		pr_err("rdbg: send_interrupt_to_subsystem failed\n");
+		err = -ECOMM;
+		goto bail;
+	}
+
+	send_interrupt_to_subsystem(rdbgdata);
+
+	err = size;
+
+bail:
+	return err;
+}
+
+static const struct file_operations rdbg_fops = {
+	.open = rdbg_open,
+	.read =  rdbg_read,
+	.write =  rdbg_write,
+	.release = rdbg_release,
+};
+
+static int register_smp2p_out(struct device *dev, char *node_name,
+			struct gpio_info *gpio_info_ptr)
+{
+	struct device_node *node = dev->of_node;
+
+	if (gpio_info_ptr) {
+		if (of_find_property(node, "qcom,smem-states", NULL)) {
+			gpio_info_ptr->smem_state =
+				    qcom_smem_state_get(dev, "rdbg-smp2p-out",
+						&gpio_info_ptr->smem_bit);
+			if (IS_ERR_OR_NULL(gpio_info_ptr->smem_state)) {
+				pr_err("rdbg: failed get smem state\n");
+				return PTR_ERR(gpio_info_ptr->smem_state);
+			}
+		}
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static int register_smp2p_in(struct device *dev, char *node_name,
+			struct gpio_info *gpio_info_ptr)
+{
+	int id = 0;
+	struct device_node *node = dev->of_node;
+
+	if (gpio_info_ptr) {
+		id = of_irq_get_byname(node, "rdbg-smp2p-in");
+		gpio_info_ptr->gpio_base_id = id;
+		gpio_info_ptr->irq_base_id = id;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static int rdbg_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct rdbg_device *rdbgdevice = &g_rdbg_instance;
+	int minor = 0;
+	int err = 0;
+	char *rdbg_compatible_string = "qcom,smp2p-interrupt-rdbg-";
+	int max_len = strlen(rdbg_compatible_string) + strlen("xxx-out");
+	char *node_name = kcalloc(max_len, sizeof(char), GFP_KERNEL);
+
+	if (!node_name) {
+		err = -ENOMEM;
+		goto bail;
+	}
+	for (minor = 0; minor < rdbgdevice->num_devices; minor++) {
+		if (!proc_info[minor].name)
+			continue;
+		if (snprintf(node_name, max_len, "%s%d-out",
+			rdbg_compatible_string, minor) <= 0) {
+			pr_err("Error in snprintf\n");
+			err = -ENOMEM;
+			goto bail;
+		}
+
+		if (of_device_is_compatible(dev->of_node, node_name)) {
+			err = register_smp2p_out(dev, node_name,
+			&rdbgdevice->rdbg_data[minor].out);
+			if (err) {
+				pr_err("%s: register_smp2p_out failed for %s\n",
+				__func__, proc_info[minor].name);
+				goto bail;
+			}
+			rdbgdevice->rdbg_data[minor].device_initialized = true;
+		}
+		if (snprintf(node_name, max_len, "%s%d-in",
+			rdbg_compatible_string, minor) <= 0) {
+			pr_err("Error in snprintf\n");
+			err = -ENOMEM;
+			goto bail;
+		}
+
+		if (of_device_is_compatible(dev->of_node, node_name)) {
+			if (register_smp2p_in(dev, node_name,
+			    &rdbgdevice->rdbg_data[minor].in)) {
+				pr_err("register_smp2p_in failed for %s\n",
+				proc_info[minor].name);
+			}
+		}
+	}
+bail:
+	kfree(node_name);
+	complete(&rdbg_driver_probe_done);
+	return err;
+}
+
+static const struct of_device_id rdbg_match_table[] = {
+	{ .compatible = "qcom,smp2p-interrupt-rdbg-2-out", },
+	{ .compatible = "qcom,smp2p-interrupt-rdbg-2-in", },
+	{ .compatible = "qcom,smp2p-interrupt-rdbg-5-out", },
+	{ .compatible = "qcom,smp2p-interrupt-rdbg-5-in", },
+	{ .compatible = "qcom,smp2p-interrupt-rdbg-12-out", },
+	{ .compatible = "qcom,smp2p-interrupt-rdbg-12-in", },
+	{ .compatible = "qcom,smp2p-interrupt-rdbg-17-out", },
+	{ .compatible = "qcom,smp2p-interrupt-rdbg-17-in", },
+	{ .compatible = "qcom,smp2p-interrupt-rdbg-18-out", },
+	{ .compatible = "qcom,smp2p-interrupt-rdbg-18-in", },
+	{}
+};
+
+static struct platform_driver rdbg_driver = {
+	.probe = rdbg_probe,
+	.driver = {
+		.name = "rdbg",
+		.of_match_table = rdbg_match_table,
+	},
+};
+
+static int __init rdbg_init(void)
+{
+	struct rdbg_device *rdbgdevice = &g_rdbg_instance;
+	int minor = 0;
+	int major = 0;
+	int minor_nodes_created = 0;
+	int err = 0;
+
+	if (rdbgdevice->num_devices < 1 ||
+		rdbgdevice->num_devices > SMP2P_NUM_PROCS) {
+		pr_err("rgdb: invalid num_devices\n");
+		err = -EDOM;
+		goto bail;
+	}
+	rdbgdevice->rdbg_data = kcalloc(rdbgdevice->num_devices,
+		sizeof(struct rdbg_data), GFP_KERNEL);
+	if (!rdbgdevice->rdbg_data) {
+		err = -ENOMEM;
+		goto bail;
+	}
+	err = alloc_chrdev_region(&rdbgdevice->dev_no, 0,
+		rdbgdevice->num_devices, "rdbgctl");
+	if (err) {
+		pr_err("Error in alloc_chrdev_region.\n");
+		goto data_bail;
+	}
+	major = MAJOR(rdbgdevice->dev_no);
+
+	cdev_init(&rdbgdevice->cdev, &rdbg_fops);
+	rdbgdevice->cdev.owner = THIS_MODULE;
+	err = cdev_add(&rdbgdevice->cdev, MKDEV(major, 0),
+		rdbgdevice->num_devices);
+	if (err) {
+		pr_err("Error in cdev_add\n");
+		goto chrdev_bail;
+	}
+	rdbgdevice->class = class_create("rdbg");
+	if (IS_ERR(rdbgdevice->class)) {
+		err = PTR_ERR(rdbgdevice->class);
+		pr_err("Error in class_create\n");
+		goto cdev_bail;
+	}
+	err = platform_driver_register(&rdbg_driver);
+	if (err)
+		goto bail;
+	wait_for_completion(&rdbg_driver_probe_done);
+	for (minor = 0; minor < rdbgdevice->num_devices; minor++) {
+		if (!proc_info[minor].name || !rdbgdevice->rdbg_data[minor].device_initialized)
+			continue;
+		rdbgdevice->rdbg_data[minor].device = device_create(
+			rdbgdevice->class, NULL, MKDEV(major, minor),
+			NULL, "%s", proc_info[minor].name);
+		if (IS_ERR(rdbgdevice->rdbg_data[minor].device)) {
+			err = PTR_ERR(rdbgdevice->rdbg_data[minor].device);
+			pr_err("Error in device_create\n");
+			goto device_bail;
+		}
+		minor_nodes_created++;
+		dev_dbg(rdbgdevice->rdbg_data[minor].device,
+			"%s: created /dev/%s c %d %d'\n", __func__,
+			proc_info[minor].name, major, minor);
+	}
+	if (!minor_nodes_created) {
+		pr_err("No device tree entries found\n");
+		err = -EINVAL;
+		goto class_bail;
+	}
+
+	goto bail;
+
+device_bail:
+	for (--minor; minor >= 0; minor--) {
+		if (rdbgdevice->rdbg_data[minor].device_initialized)
+			device_destroy(rdbgdevice->class,
+				MKDEV(MAJOR(rdbgdevice->dev_no), minor));
+	}
+class_bail:
+	class_destroy(rdbgdevice->class);
+cdev_bail:
+	cdev_del(&rdbgdevice->cdev);
+chrdev_bail:
+	unregister_chrdev_region(rdbgdevice->dev_no, rdbgdevice->num_devices);
+data_bail:
+	kfree(rdbgdevice->rdbg_data);
+bail:
+	return err;
+}
+module_init(rdbg_init);
+
+static void __exit rdbg_exit(void)
+{
+	struct rdbg_device *rdbgdevice = &g_rdbg_instance;
+	int minor;
+
+	for (minor = 0; minor < rdbgdevice->num_devices; minor++) {
+		if (rdbgdevice->rdbg_data[minor].device_initialized) {
+			device_destroy(rdbgdevice->class,
+				MKDEV(MAJOR(rdbgdevice->dev_no), minor));
+		}
+	}
+	class_destroy(rdbgdevice->class);
+	cdev_del(&rdbgdevice->cdev);
+	unregister_chrdev_region(rdbgdevice->dev_no, 1);
+	kfree(rdbgdevice->rdbg_data);
+}
+module_exit(rdbg_exit);
+
+MODULE_DESCRIPTION("rdbg module");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/char/tpm/eventlog/acpi.c
+++ linux-qcom-6.8.0/drivers/char/tpm/eventlog/acpi.c
@@ -63,6 +63,11 @@
 	return n == 0;
 }
 
+static void tpm_bios_log_free(void *data)
+{
+	kvfree(data);
+}
+
 /* read binary bios log */
 int tpm_read_log_acpi(struct tpm_chip *chip)
 {
@@ -136,7 +141,7 @@
 	}
 
 	/* malloc EventLog space */
-	log->bios_event_log = devm_kmalloc(&chip->dev, len, GFP_KERNEL);
+	log->bios_event_log = kvmalloc(len, GFP_KERNEL);
 	if (!log->bios_event_log)
 		return -ENOMEM;
 
@@ -162,10 +167,16 @@
 		goto err;
 	}
 
+	ret = devm_add_action(&chip->dev, tpm_bios_log_free, log->bios_event_log);
+	if (ret) {
+		log->bios_event_log = NULL;
+		goto err;
+	}
+
 	return format;
 
 err:
-	devm_kfree(&chip->dev, log->bios_event_log);
+	tpm_bios_log_free(log->bios_event_log);
 	log->bios_event_log = NULL;
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/char/tpm/eventlog/common.c
+++ linux-qcom-6.8.0/drivers/char/tpm/eventlog/common.c
@@ -47,6 +47,8 @@
 	if (!err) {
 		seq = file->private_data;
 		seq->private = chip;
+	} else {
+		put_device(&chip->dev);
 	}
 
 	return err;
--- linux-qcom-6.8.0.orig/drivers/char/tpm/tpm-chip.c
+++ linux-qcom-6.8.0/drivers/char/tpm/tpm-chip.c
@@ -519,10 +519,6 @@
 {
 	struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng);
 
-	/* Give back zero bytes, as TPM chip has not yet fully resumed: */
-	if (chip->flags & TPM_CHIP_FLAG_SUSPENDED)
-		return 0;
-
 	return tpm_get_random(chip, data, max);
 }
 
--- linux-qcom-6.8.0.orig/drivers/char/tpm/tpm-dev-common.c
+++ linux-qcom-6.8.0/drivers/char/tpm/tpm-dev-common.c
@@ -47,6 +47,8 @@
 
 	if (!ret)
 		ret = tpm2_commit_space(chip, space, buf, &len);
+	else
+		tpm2_flush_space(chip);
 
 out_rc:
 	return ret ? ret : len;
--- linux-qcom-6.8.0.orig/drivers/char/tpm/tpm-interface.c
+++ linux-qcom-6.8.0/drivers/char/tpm/tpm-interface.c
@@ -394,6 +394,13 @@
 	if (!chip)
 		return -ENODEV;
 
+	rc = tpm_try_get_ops(chip);
+	if (rc) {
+		/* Can be safely set out of locks, as no action cannot race: */
+		chip->flags |= TPM_CHIP_FLAG_SUSPENDED;
+		goto out;
+	}
+
 	if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED)
 		goto suspended;
 
@@ -401,19 +408,18 @@
 	    !pm_suspend_via_firmware())
 		goto suspended;
 
-	rc = tpm_try_get_ops(chip);
-	if (!rc) {
-		if (chip->flags & TPM_CHIP_FLAG_TPM2)
-			tpm2_shutdown(chip, TPM2_SU_STATE);
-		else
-			rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
-
-		tpm_put_ops(chip);
+	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
+		tpm2_shutdown(chip, TPM2_SU_STATE);
+		goto suspended;
 	}
 
+	rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
+
 suspended:
 	chip->flags |= TPM_CHIP_FLAG_SUSPENDED;
+	tpm_put_ops(chip);
 
+out:
 	if (rc)
 		dev_err(dev, "Ignoring error %d while suspending\n", rc);
 	return 0;
@@ -462,11 +468,18 @@
 	if (!chip)
 		return -ENODEV;
 
+	/* Give back zero bytes, as TPM chip has not yet fully resumed: */
+	if (chip->flags & TPM_CHIP_FLAG_SUSPENDED) {
+		rc = 0;
+		goto out;
+	}
+
 	if (chip->flags & TPM_CHIP_FLAG_TPM2)
 		rc = tpm2_get_random(chip, out, max);
 	else
 		rc = tpm1_get_random(chip, out, max);
 
+out:
 	tpm_put_ops(chip);
 	return rc;
 }
--- linux-qcom-6.8.0.orig/drivers/char/tpm/tpm2-space.c
+++ linux-qcom-6.8.0/drivers/char/tpm/tpm2-space.c
@@ -166,6 +166,9 @@
 	struct tpm_space *space = &chip->work_space;
 	int i;
 
+	if (!space)
+		return;
+
 	for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++)
 		if (space->context_tbl[i] && ~space->context_tbl[i])
 			tpm2_flush_context(chip, space->context_tbl[i]);
--- linux-qcom-6.8.0.orig/drivers/char/tpm/tpm_tis_core.c
+++ linux-qcom-6.8.0/drivers/char/tpm/tpm_tis_core.c
@@ -919,8 +919,6 @@
 	int rc;
 	u32 int_status;
 
-	INIT_WORK(&priv->free_irq_work, tpm_tis_free_irq_func);
-
 	rc = devm_request_threaded_irq(chip->dev.parent, irq, NULL,
 				       tis_int_handler, IRQF_ONESHOT | flags,
 				       dev_name(&chip->dev), chip);
@@ -1022,7 +1020,8 @@
 		interrupt = 0;
 
 	tpm_tis_write32(priv, reg, ~TPM_GLOBAL_INT_ENABLE & interrupt);
-	flush_work(&priv->free_irq_work);
+	if (priv->free_irq_work.func)
+		flush_work(&priv->free_irq_work);
 
 	tpm_tis_clkrun_enable(chip, false);
 
@@ -1132,6 +1131,7 @@
 	priv->phy_ops = phy_ops;
 	priv->locality_count = 0;
 	mutex_init(&priv->locality_count_mutex);
+	INIT_WORK(&priv->free_irq_work, tpm_tis_free_irq_func);
 
 	dev_set_drvdata(&chip->dev, priv);
 
--- linux-qcom-6.8.0.orig/drivers/char/tpm/tpm_tis_spi_main.c
+++ linux-qcom-6.8.0/drivers/char/tpm/tpm_tis_spi_main.c
@@ -37,6 +37,7 @@
 #include "tpm_tis_spi.h"
 
 #define MAX_SPI_FRAMESIZE 64
+#define SPI_HDRSIZE 4
 
 /*
  * TCG SPI flow control is documented in section 6.4 of the spec[1]. In short,
@@ -247,7 +248,7 @@
 int tpm_tis_spi_init(struct spi_device *spi, struct tpm_tis_spi_phy *phy,
 		     int irq, const struct tpm_tis_phy_ops *phy_ops)
 {
-	phy->iobuf = devm_kmalloc(&spi->dev, MAX_SPI_FRAMESIZE, GFP_KERNEL);
+	phy->iobuf = devm_kmalloc(&spi->dev, SPI_HDRSIZE + MAX_SPI_FRAMESIZE, GFP_KERNEL);
 	if (!phy->iobuf)
 		return -ENOMEM;
 
@@ -317,6 +318,7 @@
 }
 
 static const struct spi_device_id tpm_tis_spi_id[] = {
+	{ "attpm20p", (unsigned long)tpm_tis_spi_probe },
 	{ "st33htpm-spi", (unsigned long)tpm_tis_spi_probe },
 	{ "slb9670", (unsigned long)tpm_tis_spi_probe },
 	{ "tpm_tis_spi", (unsigned long)tpm_tis_spi_probe },
--- linux-qcom-6.8.0.orig/drivers/char/virtio_console.c
+++ linux-qcom-6.8.0/drivers/char/virtio_console.c
@@ -2016,25 +2016,27 @@
 		multiport = true;
 	}
 
-	err = init_vqs(portdev);
-	if (err < 0) {
-		dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
-		goto free_chrdev;
-	}
-
 	spin_lock_init(&portdev->ports_lock);
 	INIT_LIST_HEAD(&portdev->ports);
 	INIT_LIST_HEAD(&portdev->list);
 
-	virtio_device_ready(portdev->vdev);
-
 	INIT_WORK(&portdev->config_work, &config_work_handler);
 	INIT_WORK(&portdev->control_work, &control_work_handler);
 
 	if (multiport) {
 		spin_lock_init(&portdev->c_ivq_lock);
 		spin_lock_init(&portdev->c_ovq_lock);
+	}
 
+	err = init_vqs(portdev);
+	if (err < 0) {
+		dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
+		goto free_chrdev;
+	}
+
+	virtio_device_ready(portdev->vdev);
+
+	if (multiport) {
 		err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock);
 		if (err < 0) {
 			dev_err(&vdev->dev,
--- linux-qcom-6.8.0.orig/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ linux-qcom-6.8.0/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -639,8 +639,8 @@
 	dev_set_drvdata(dev, (void *)drvdata);
 
 	drvdata->base_address = devm_platform_ioremap_resource(pdev, 0);
-	if (!drvdata->base_address) {
-		retval = -ENODEV;
+	if (IS_ERR(drvdata->base_address)) {
+		retval = PTR_ERR(drvdata->base_address);
 		goto failed;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/char/xillybus/xillyusb.c
+++ linux-qcom-6.8.0/drivers/char/xillybus/xillyusb.c
@@ -50,6 +50,7 @@
 static const char xillyname[] = "xillyusb";
 
 static unsigned int fifo_buf_order;
+static struct workqueue_struct *wakeup_wq;
 
 #define USB_VENDOR_ID_XILINX		0x03fd
 #define USB_VENDOR_ID_ALTERA		0x09fb
@@ -569,10 +570,6 @@
  * errors if executed. The mechanism relies on that xdev->error is assigned
  * a non-zero value by report_io_error() prior to queueing wakeup_all(),
  * which prevents bulk_in_work() from calling process_bulk_in().
- *
- * The fact that wakeup_all() and bulk_in_work() are queued on the same
- * workqueue makes their concurrent execution very unlikely, however the
- * kernel's API doesn't seem to ensure this strictly.
  */
 
 static void wakeup_all(struct work_struct *work)
@@ -627,7 +624,7 @@
 
 	if (do_once) {
 		kref_get(&xdev->kref); /* xdev is used by work item */
-		queue_work(xdev->workq, &xdev->wakeup_workitem);
+		queue_work(wakeup_wq, &xdev->wakeup_workitem);
 	}
 }
 
@@ -1906,6 +1903,13 @@
 
 static int xillyusb_setup_base_eps(struct xillyusb_dev *xdev)
 {
+	struct usb_device *udev = xdev->udev;
+
+	/* Verify that device has the two fundamental bulk in/out endpoints */
+	if (usb_pipe_type_check(udev, usb_sndbulkpipe(udev, MSG_EP_NUM)) ||
+	    usb_pipe_type_check(udev, usb_rcvbulkpipe(udev, IN_EP_NUM)))
+		return -ENODEV;
+
 	xdev->msg_ep = endpoint_alloc(xdev, MSG_EP_NUM | USB_DIR_OUT,
 				      bulk_out_work, 1, 2);
 	if (!xdev->msg_ep)
@@ -1935,14 +1939,15 @@
 			  __le16 *chandesc,
 			  int num_channels)
 {
-	struct xillyusb_channel *chan;
+	struct usb_device *udev = xdev->udev;
+	struct xillyusb_channel *chan, *new_channels;
 	int i;
 
 	chan = kcalloc(num_channels, sizeof(*chan), GFP_KERNEL);
 	if (!chan)
 		return -ENOMEM;
 
-	xdev->channels = chan;
+	new_channels = chan;
 
 	for (i = 0; i < num_channels; i++, chan++) {
 		unsigned int in_desc = le16_to_cpu(*chandesc++);
@@ -1971,6 +1976,15 @@
 		 */
 
 		if ((out_desc & 0x80) && i < 14) { /* Entry is valid */
+			if (usb_pipe_type_check(udev,
+						usb_sndbulkpipe(udev, i + 2))) {
+				dev_err(xdev->dev,
+					"Missing BULK OUT endpoint %d\n",
+					i + 2);
+				kfree(new_channels);
+				return -ENODEV;
+			}
+
 			chan->writable = 1;
 			chan->out_synchronous = !!(out_desc & 0x40);
 			chan->out_seekable = !!(out_desc & 0x20);
@@ -1980,6 +1994,7 @@
 		}
 	}
 
+	xdev->channels = new_channels;
 	return 0;
 }
 
@@ -2096,9 +2111,11 @@
 	 * just after responding with the IDT, there is no reason for any
 	 * work item to be running now. To be sure that xdev->channels
 	 * is updated on anything that might run in parallel, flush the
-	 * workqueue, which rarely does anything.
+	 * device's workqueue and the wakeup work item. This rarely
+	 * does anything.
 	 */
 	flush_workqueue(xdev->workq);
+	flush_work(&xdev->wakeup_workitem);
 
 	xdev->num_channels = num_channels;
 
@@ -2258,6 +2275,10 @@
 {
 	int rc = 0;
 
+	wakeup_wq = alloc_workqueue(xillyname, 0, 0);
+	if (!wakeup_wq)
+		return -ENOMEM;
+
 	if (LOG2_INITIAL_FIFO_BUF_SIZE > PAGE_SHIFT)
 		fifo_buf_order = LOG2_INITIAL_FIFO_BUF_SIZE - PAGE_SHIFT;
 	else
@@ -2265,12 +2286,17 @@
 
 	rc = usb_register(&xillyusb_driver);
 
+	if (rc)
+		destroy_workqueue(wakeup_wq);
+
 	return rc;
 }
 
 static void __exit xillyusb_exit(void)
 {
 	usb_deregister(&xillyusb_driver);
+
+	destroy_workqueue(wakeup_wq);
 }
 
 module_init(xillyusb_init);
--- linux-qcom-6.8.0.orig/drivers/clk/analogbits/wrpll-cln28hpc.c
+++ linux-qcom-6.8.0/drivers/clk/analogbits/wrpll-cln28hpc.c
@@ -292,7 +292,7 @@
 			vco = vco_pre * f;
 		}
 
-		delta = abs(target_rate - vco);
+		delta = abs(target_vco_rate - vco);
 		if (delta < best_delta) {
 			best_delta = delta;
 			best_r = r;
--- linux-qcom-6.8.0.orig/drivers/clk/at91/sama7g5.c
+++ linux-qcom-6.8.0/drivers/clk/at91/sama7g5.c
@@ -66,6 +66,7 @@
 	PLL_COMPID_FRAC,
 	PLL_COMPID_DIV0,
 	PLL_COMPID_DIV1,
+	PLL_COMPID_MAX,
 };
 
 /*
@@ -165,7 +166,7 @@
 	u8 t;
 	u8 eid;
 	u8 safe_div;
-} sama7g5_plls[][PLL_ID_MAX] = {
+} sama7g5_plls[][PLL_COMPID_MAX] = {
 	[PLL_ID_CPU] = {
 		[PLL_COMPID_FRAC] = {
 			.n = "cpupll_fracck",
@@ -1038,7 +1039,7 @@
 	sama7g5_pmc->chws[PMC_MAIN] = hw;
 
 	for (i = 0; i < PLL_ID_MAX; i++) {
-		for (j = 0; j < 3; j++) {
+		for (j = 0; j < PLL_COMPID_MAX; j++) {
 			struct clk_hw *parent_hw;
 
 			if (!sama7g5_plls[i][j].n)
--- linux-qcom-6.8.0.orig/drivers/clk/bcm/clk-bcm2711-dvp.c
+++ linux-qcom-6.8.0/drivers/clk/bcm/clk-bcm2711-dvp.c
@@ -56,6 +56,8 @@
 	if (ret)
 		return ret;
 
+	data->num = NR_CLOCKS;
+
 	data->hws[0] = clk_hw_register_gate_parent_data(&pdev->dev,
 							"hdmi0-108MHz",
 							&clk_dvp_parent, 0,
@@ -76,7 +78,6 @@
 		goto unregister_clk0;
 	}
 
-	data->num = NR_CLOCKS;
 	ret = of_clk_add_hw_provider(pdev->dev.of_node, of_clk_hw_onecell_get,
 				     data);
 	if (ret)
--- linux-qcom-6.8.0.orig/drivers/clk/bcm/clk-bcm53573-ilp.c
+++ linux-qcom-6.8.0/drivers/clk/bcm/clk-bcm53573-ilp.c
@@ -112,7 +112,7 @@
 		goto err_free_ilp;
 	}
 
-	ilp->regmap = syscon_node_to_regmap(of_get_parent(np));
+	ilp->regmap = syscon_node_to_regmap(np->parent);
 	if (IS_ERR(ilp->regmap)) {
 		err = PTR_ERR(ilp->regmap);
 		goto err_free_ilp;
--- linux-qcom-6.8.0.orig/drivers/clk/bcm/clk-raspberrypi.c
+++ linux-qcom-6.8.0/drivers/clk/bcm/clk-raspberrypi.c
@@ -371,8 +371,8 @@
 			if (IS_ERR(hw))
 				return PTR_ERR(hw);
 
-			data->hws[clks->id] = hw;
 			data->num = clks->id + 1;
+			data->hws[clks->id] = hw;
 		}
 
 		clks++;
--- linux-qcom-6.8.0.orig/drivers/clk/clk-apple-nco.c
+++ linux-qcom-6.8.0/drivers/clk/clk-apple-nco.c
@@ -297,6 +297,9 @@
 		memset(&init, 0, sizeof(init));
 		init.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
 						"%s-%d", np->name, i);
+		if (!init.name)
+			return -ENOMEM;
+
 		init.ops = &applnco_ops;
 		init.parent_data = &pdata;
 		init.num_parents = 1;
--- linux-qcom-6.8.0.orig/drivers/clk/clk-axi-clkgen.c
+++ linux-qcom-6.8.0/drivers/clk/clk-axi-clkgen.c
@@ -7,6 +7,7 @@
  */
 
 #include <linux/platform_device.h>
+#include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/slab.h>
 #include <linux/io.h>
@@ -512,6 +513,7 @@
 	struct clk_init_data init;
 	const char *parent_names[2];
 	const char *clk_name;
+	struct clk *axi_clk;
 	unsigned int i;
 	int ret;
 
@@ -528,8 +530,24 @@
 		return PTR_ERR(axi_clkgen->base);
 
 	init.num_parents = of_clk_get_parent_count(pdev->dev.of_node);
-	if (init.num_parents < 1 || init.num_parents > 2)
-		return -EINVAL;
+
+	axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk");
+	if (!IS_ERR(axi_clk)) {
+		if (init.num_parents < 2 || init.num_parents > 3)
+			return -EINVAL;
+
+		init.num_parents -= 1;
+	} else {
+		/*
+		 * Legacy... So that old DTs which do not have clock-names still
+		 * work. In this case we don't explicitly enable the AXI bus
+		 * clock.
+		 */
+		if (PTR_ERR(axi_clk) != -ENOENT)
+			return PTR_ERR(axi_clk);
+		if (init.num_parents < 1 || init.num_parents > 2)
+			return -EINVAL;
+	}
 
 	for (i = 0; i < init.num_parents; i++) {
 		parent_names[i] = of_clk_get_parent_name(pdev->dev.of_node, i);
--- linux-qcom-6.8.0.orig/drivers/clk/clk-conf.c
+++ linux-qcom-6.8.0/drivers/clk/clk-conf.c
@@ -81,13 +81,11 @@
 static int __set_clk_rates(struct device_node *node, bool clk_supplier)
 {
 	struct of_phandle_args clkspec;
-	struct property	*prop;
-	const __be32 *cur;
 	int rc, index = 0;
 	struct clk *clk;
 	u32 rate;
 
-	of_property_for_each_u32(node, "assigned-clock-rates", prop, cur, rate) {
+	of_property_for_each_u32(node, "assigned-clock-rates", rate) {
 		if (rate) {
 			rc = of_parse_phandle_with_args(node, "assigned-clocks",
 					"#clock-cells",	index, &clkspec);
--- linux-qcom-6.8.0.orig/drivers/clk/clk-en7523.c
+++ linux-qcom-6.8.0/drivers/clk/clk-en7523.c
@@ -40,6 +40,7 @@
 	u8 div_shift;
 	u16 div_val0;
 	u8 div_step;
+	u8 div_offset;
 };
 
 struct en_clk_gate {
@@ -67,6 +68,7 @@
 		.div_bits = 3,
 		.div_shift = 0,
 		.div_step = 1,
+		.div_offset = 1,
 	}, {
 		.id = EN7523_CLK_EMI,
 		.name = "emi",
@@ -80,6 +82,7 @@
 		.div_bits = 3,
 		.div_shift = 0,
 		.div_step = 1,
+		.div_offset = 1,
 	}, {
 		.id = EN7523_CLK_BUS,
 		.name = "bus",
@@ -93,6 +96,7 @@
 		.div_bits = 3,
 		.div_shift = 0,
 		.div_step = 1,
+		.div_offset = 1,
 	}, {
 		.id = EN7523_CLK_SLIC,
 		.name = "slic",
@@ -133,13 +137,14 @@
 		.div_bits = 3,
 		.div_shift = 0,
 		.div_step = 1,
+		.div_offset = 1,
 	}, {
 		.id = EN7523_CLK_CRYPTO,
 		.name = "crypto",
 
 		.base_reg = REG_CRYPTO_CLKSRC,
 		.base_bits = 1,
-		.base_shift = 8,
+		.base_shift = 0,
 		.base_values = emi_base,
 		.n_base_values = ARRAY_SIZE(emi_base),
 	}
@@ -184,7 +189,7 @@
 	if (!val && desc->div_val0)
 		return desc->div_val0;
 
-	return (val + 1) * desc->div_step;
+	return (val + desc->div_offset) * desc->div_step;
 }
 
 static int en7523_pci_is_enabled(struct clk_hw *hw)
@@ -279,6 +284,8 @@
 	u32 rate;
 	int i;
 
+	clk_data->num = EN7523_NUM_CLOCKS;
+
 	for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) {
 		const struct en_clk_desc *desc = &en7523_base_clks[i];
 
@@ -297,8 +304,6 @@
 
 	hw = en7523_register_pcie_clk(dev, np_base);
 	clk_data->hws[EN7523_CLK_PCIE] = hw;
-
-	clk_data->num = EN7523_NUM_CLOCKS;
 }
 
 static int en7523_clk_probe(struct platform_device *pdev)
--- linux-qcom-6.8.0.orig/drivers/clk/clk-renesas-pcie.c
+++ linux-qcom-6.8.0/drivers/clk/clk-renesas-pcie.c
@@ -25,10 +25,12 @@
 #define RS9_REG_SS_AMP_0V7			0x1
 #define RS9_REG_SS_AMP_0V8			0x2
 #define RS9_REG_SS_AMP_0V9			0x3
+#define RS9_REG_SS_AMP_DEFAULT			RS9_REG_SS_AMP_0V8
 #define RS9_REG_SS_AMP_MASK			0x3
 #define RS9_REG_SS_SSC_100			0
 #define RS9_REG_SS_SSC_M025			(1 << 3)
 #define RS9_REG_SS_SSC_M050			(3 << 3)
+#define RS9_REG_SS_SSC_DEFAULT			RS9_REG_SS_SSC_100
 #define RS9_REG_SS_SSC_MASK			(3 << 3)
 #define RS9_REG_SS_SSC_LOCK			BIT(5)
 #define RS9_REG_SR				0x2
@@ -205,8 +207,8 @@
 	int ret;
 
 	/* Set defaults */
-	rs9->pll_amplitude = RS9_REG_SS_AMP_0V7;
-	rs9->pll_ssc = RS9_REG_SS_SSC_100;
+	rs9->pll_amplitude = RS9_REG_SS_AMP_DEFAULT;
+	rs9->pll_ssc = RS9_REG_SS_SSC_DEFAULT;
 
 	/* Output clock amplitude */
 	ret = of_property_read_u32(np, "renesas,out-amplitude-microvolt",
@@ -247,13 +249,13 @@
 	int i;
 
 	/* If amplitude is non-default, update it. */
-	if (rs9->pll_amplitude != RS9_REG_SS_AMP_0V7) {
+	if (rs9->pll_amplitude != RS9_REG_SS_AMP_DEFAULT) {
 		regmap_update_bits(rs9->regmap, RS9_REG_SS, RS9_REG_SS_AMP_MASK,
 				   rs9->pll_amplitude);
 	}
 
 	/* If SSC is non-default, update it. */
-	if (rs9->pll_ssc != RS9_REG_SS_SSC_100) {
+	if (rs9->pll_ssc != RS9_REG_SS_SSC_DEFAULT) {
 		regmap_update_bits(rs9->regmap, RS9_REG_SS, RS9_REG_SS_SSC_MASK,
 				   rs9->pll_ssc);
 	}
--- linux-qcom-6.8.0.orig/drivers/clk/clk-si5351.c
+++ linux-qcom-6.8.0/drivers/clk/clk-si5351.c
@@ -1175,8 +1175,8 @@
 {
 	struct device_node *child, *np = client->dev.of_node;
 	struct si5351_platform_data *pdata;
-	struct property *prop;
-	const __be32 *p;
+	u32 array[4];
+	int sz, i;
 	int num = 0;
 	u32 val;
 
@@ -1191,20 +1191,24 @@
 	 * property silabs,pll-source : <num src>, [<..>]
 	 * allow to selectively set pll source
 	 */
-	of_property_for_each_u32(np, "silabs,pll-source", prop, p, num) {
+	sz = of_property_read_variable_u32_array(np, "silabs,pll-source", array, 2, 4);
+	sz = (sz == -EINVAL) ? 0 : sz; /* Missing property is OK */
+	if (sz < 0)
+		return dev_err_probe(&client->dev, sz, "invalid pll-source\n");
+	if (sz % 2)
+		return dev_err_probe(&client->dev, -EINVAL,
+				     "missing pll-source for pll %d\n", array[sz - 1]);
+
+	for (i = 0; i < sz; i += 2) {
+		num = array[i];
+		val = array[i + 1];
+
 		if (num >= 2) {
 			dev_err(&client->dev,
 				"invalid pll %d on pll-source prop\n", num);
 			return -EINVAL;
 		}
 
-		p = of_prop_next_u32(prop, p, &val);
-		if (!p) {
-			dev_err(&client->dev,
-				"missing pll-source for pll %d\n", num);
-			return -EINVAL;
-		}
-
 		switch (val) {
 		case 0:
 			pdata->pll_src[num] = SI5351_PLL_SRC_XTAL;
@@ -1232,19 +1236,24 @@
 	pdata->pll_reset[0] = true;
 	pdata->pll_reset[1] = true;
 
-	of_property_for_each_u32(np, "silabs,pll-reset-mode", prop, p, num) {
+	sz = of_property_read_variable_u32_array(np, "silabs,pll-reset-mode", array, 2, 4);
+	sz = (sz == -EINVAL) ? 0 : sz; /* Missing property is OK */
+	if (sz < 0)
+		return dev_err_probe(&client->dev, sz, "invalid pll-reset-mode\n");
+	if (sz % 2)
+		return dev_err_probe(&client->dev, -EINVAL,
+				     "missing pll-reset-mode for pll %d\n", array[sz - 1]);
+
+	for (i = 0; i < sz; i += 2) {
+		num = array[i];
+		val = array[i + 1];
+
 		if (num >= 2) {
 			dev_err(&client->dev,
 				"invalid pll %d on pll-reset-mode prop\n", num);
 			return -EINVAL;
 		}
 
-		p = of_prop_next_u32(prop, p, &val);
-		if (!p) {
-			dev_err(&client->dev,
-				"missing pll-reset-mode for pll %d\n", num);
-			return -EINVAL;
-		}
 
 		switch (val) {
 		case 0:
--- linux-qcom-6.8.0.orig/drivers/clk/clk.c
+++ linux-qcom-6.8.0/drivers/clk/clk.c
@@ -37,6 +37,10 @@
 static HLIST_HEAD(clk_orphan_list);
 static LIST_HEAD(clk_notifier_list);
 
+/* List of registered clks that use runtime PM */
+static HLIST_HEAD(clk_rpm_list);
+static DEFINE_MUTEX(clk_rpm_list_lock);
+
 static const struct hlist_head *all_lists[] = {
 	&clk_root_list,
 	&clk_orphan_list,
@@ -59,6 +63,7 @@
 	struct clk_hw		*hw;
 	struct module		*owner;
 	struct device		*dev;
+	struct hlist_node	rpm_node;
 	struct device_node	*of_node;
 	struct clk_core		*parent;
 	struct clk_parent_map	*parents;
@@ -122,6 +127,89 @@
 	pm_runtime_put_sync(core->dev);
 }
 
+/**
+ * clk_pm_runtime_get_all() - Runtime "get" all clk provider devices
+ *
+ * Call clk_pm_runtime_get() on all runtime PM enabled clks in the clk tree so
+ * that disabling unused clks avoids a deadlock where a device is runtime PM
+ * resuming/suspending and the runtime PM callback is trying to grab the
+ * prepare_lock for something like clk_prepare_enable() while
+ * clk_disable_unused_subtree() holds the prepare_lock and is trying to runtime
+ * PM resume/suspend the device as well.
+ *
+ * Context: Acquires the 'clk_rpm_list_lock' and returns with the lock held on
+ * success. Otherwise the lock is released on failure.
+ *
+ * Return: 0 on success, negative errno otherwise.
+ */
+static int clk_pm_runtime_get_all(void)
+{
+	int ret;
+	struct clk_core *core, *failed;
+
+	/*
+	 * Grab the list lock to prevent any new clks from being registered
+	 * or unregistered until clk_pm_runtime_put_all().
+	 */
+	mutex_lock(&clk_rpm_list_lock);
+
+	/*
+	 * Runtime PM "get" all the devices that are needed for the clks
+	 * currently registered. Do this without holding the prepare_lock, to
+	 * avoid the deadlock.
+	 */
+	hlist_for_each_entry(core, &clk_rpm_list, rpm_node) {
+		ret = clk_pm_runtime_get(core);
+		if (ret) {
+			failed = core;
+			pr_err("clk: Failed to runtime PM get '%s' for clk '%s'\n",
+			       dev_name(failed->dev), failed->name);
+			goto err;
+		}
+	}
+
+	return 0;
+
+err:
+	hlist_for_each_entry(core, &clk_rpm_list, rpm_node) {
+		if (core == failed)
+			break;
+
+		clk_pm_runtime_put(core);
+	}
+	mutex_unlock(&clk_rpm_list_lock);
+
+	return ret;
+}
+
+/**
+ * clk_pm_runtime_put_all() - Runtime "put" all clk provider devices
+ *
+ * Put the runtime PM references taken in clk_pm_runtime_get_all() and release
+ * the 'clk_rpm_list_lock'.
+ */
+static void clk_pm_runtime_put_all(void)
+{
+	struct clk_core *core;
+
+	hlist_for_each_entry(core, &clk_rpm_list, rpm_node)
+		clk_pm_runtime_put(core);
+	mutex_unlock(&clk_rpm_list_lock);
+}
+
+static void clk_pm_runtime_init(struct clk_core *core)
+{
+	struct device *dev = core->dev;
+
+	if (dev && pm_runtime_enabled(dev)) {
+		core->rpm_enabled = true;
+
+		mutex_lock(&clk_rpm_list_lock);
+		hlist_add_head(&core->rpm_node, &clk_rpm_list);
+		mutex_unlock(&clk_rpm_list_lock);
+	}
+}
+
 /***           locking             ***/
 static void clk_prepare_lock(void)
 {
@@ -418,6 +506,9 @@
 	if (IS_ERR(hw))
 		return ERR_CAST(hw);
 
+	if (!hw)
+		return NULL;
+
 	return hw->core;
 }
 
@@ -939,6 +1030,25 @@
 }
 EXPORT_SYMBOL_GPL(clk_rate_exclusive_get);
 
+static void devm_clk_rate_exclusive_put(void *data)
+{
+	struct clk *clk = data;
+
+	clk_rate_exclusive_put(clk);
+}
+
+int devm_clk_rate_exclusive_get(struct device *dev, struct clk *clk)
+{
+	int ret;
+
+	ret = clk_rate_exclusive_get(clk);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev, devm_clk_rate_exclusive_put, clk);
+}
+EXPORT_SYMBOL_GPL(devm_clk_rate_exclusive_get);
+
 static void clk_core_unprepare(struct clk_core *core)
 {
 	lockdep_assert_held(&prepare_lock);
@@ -1359,9 +1469,6 @@
 	if (core->flags & CLK_IGNORE_UNUSED)
 		return;
 
-	if (clk_pm_runtime_get(core))
-		return;
-
 	if (clk_core_is_prepared(core)) {
 		trace_clk_unprepare(core);
 		if (core->ops->unprepare_unused)
@@ -1370,8 +1477,6 @@
 			core->ops->unprepare(core->hw);
 		trace_clk_unprepare_complete(core);
 	}
-
-	clk_pm_runtime_put(core);
 }
 
 static void __init clk_disable_unused_subtree(struct clk_core *core)
@@ -1387,9 +1492,6 @@
 	if (core->flags & CLK_OPS_PARENT_ENABLE)
 		clk_core_prepare_enable(core->parent);
 
-	if (clk_pm_runtime_get(core))
-		goto unprepare_out;
-
 	flags = clk_enable_lock();
 
 	if (core->enable_count)
@@ -1414,8 +1516,6 @@
 
 unlock_out:
 	clk_enable_unlock(flags);
-	clk_pm_runtime_put(core);
-unprepare_out:
 	if (core->flags & CLK_OPS_PARENT_ENABLE)
 		clk_core_disable_unprepare(core->parent);
 }
@@ -1431,6 +1531,7 @@
 static int __init clk_disable_unused(void)
 {
 	struct clk_core *core;
+	int ret;
 
 	if (clk_ignore_unused) {
 		pr_warn("clk: Not disabling unused clocks\n");
@@ -1439,6 +1540,13 @@
 
 	pr_info("clk: Disabling unused clocks\n");
 
+	ret = clk_pm_runtime_get_all();
+	if (ret)
+		return ret;
+	/*
+	 * Grab the prepare lock to keep the clk topology stable while iterating
+	 * over clks.
+	 */
 	clk_prepare_lock();
 
 	hlist_for_each_entry(core, &clk_root_list, child_node)
@@ -1455,6 +1563,8 @@
 
 	clk_prepare_unlock();
 
+	clk_pm_runtime_put_all();
+
 	return 0;
 }
 late_initcall_sync(clk_disable_unused);
@@ -3230,9 +3340,7 @@
 {
 	struct clk_core *child;
 
-	clk_pm_runtime_get(c);
 	clk_summary_show_one(s, c, level);
-	clk_pm_runtime_put(c);
 
 	hlist_for_each_entry(child, &c->children, child_node)
 		clk_summary_show_subtree(s, child, level + 1);
@@ -3242,11 +3350,15 @@
 {
 	struct clk_core *c;
 	struct hlist_head **lists = s->private;
+	int ret;
 
 	seq_puts(s, "                                 enable  prepare  protect                                duty  hardware                            connection\n");
 	seq_puts(s, "   clock                          count    count    count        rate   accuracy phase  cycle    enable   consumer                         id\n");
 	seq_puts(s, "---------------------------------------------------------------------------------------------------------------------------------------------\n");
 
+	ret = clk_pm_runtime_get_all();
+	if (ret)
+		return ret;
 
 	clk_prepare_lock();
 
@@ -3255,6 +3367,7 @@
 			clk_summary_show_subtree(s, c, 0);
 
 	clk_prepare_unlock();
+	clk_pm_runtime_put_all();
 
 	return 0;
 }
@@ -3302,8 +3415,14 @@
 	struct clk_core *c;
 	bool first_node = true;
 	struct hlist_head **lists = s->private;
+	int ret;
+
+	ret = clk_pm_runtime_get_all();
+	if (ret)
+		return ret;
 
 	seq_putc(s, '{');
+
 	clk_prepare_lock();
 
 	for (; *lists; lists++) {
@@ -3316,6 +3435,7 @@
 	}
 
 	clk_prepare_unlock();
+	clk_pm_runtime_put_all();
 
 	seq_puts(s, "}\n");
 	return 0;
@@ -3959,8 +4079,6 @@
 	}
 
 	clk_core_reparent_orphans_nolock();
-
-	kref_init(&core->ref);
 out:
 	clk_pm_runtime_put(core);
 unlock:
@@ -4189,6 +4307,22 @@
 	kfree(core->parents);
 }
 
+/* Free memory allocated for a struct clk_core */
+static void __clk_release(struct kref *ref)
+{
+	struct clk_core *core = container_of(ref, struct clk_core, ref);
+
+	if (core->rpm_enabled) {
+		mutex_lock(&clk_rpm_list_lock);
+		hlist_del(&core->rpm_node);
+		mutex_unlock(&clk_rpm_list_lock);
+	}
+
+	clk_core_free_parent_map(core);
+	kfree_const(core->name);
+	kfree(core);
+}
+
 static struct clk *
 __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw)
 {
@@ -4209,6 +4343,8 @@
 		goto fail_out;
 	}
 
+	kref_init(&core->ref);
+
 	core->name = kstrdup_const(init->name, GFP_KERNEL);
 	if (!core->name) {
 		ret = -ENOMEM;
@@ -4221,9 +4357,8 @@
 	}
 	core->ops = init->ops;
 
-	if (dev && pm_runtime_enabled(dev))
-		core->rpm_enabled = true;
 	core->dev = dev;
+	clk_pm_runtime_init(core);
 	core->of_node = np;
 	if (dev && dev->driver)
 		core->owner = dev->driver->owner;
@@ -4263,12 +4398,10 @@
 	hw->clk = NULL;
 
 fail_create_clk:
-	clk_core_free_parent_map(core);
 fail_parents:
 fail_ops:
-	kfree_const(core->name);
 fail_name:
-	kfree(core);
+	kref_put(&core->ref, __clk_release);
 fail_out:
 	return ERR_PTR(ret);
 }
@@ -4348,18 +4481,6 @@
 }
 EXPORT_SYMBOL_GPL(of_clk_hw_register);
 
-/* Free memory allocated for a clock. */
-static void __clk_release(struct kref *ref)
-{
-	struct clk_core *core = container_of(ref, struct clk_core, ref);
-
-	lockdep_assert_held(&prepare_lock);
-
-	clk_core_free_parent_map(core);
-	kfree_const(core->name);
-	kfree(core);
-}
-
 /*
  * Empty clk_ops for unregistered clocks. These are used temporarily
  * after clk_unregister() was called on a clock and until last clock
@@ -4450,7 +4571,8 @@
 	if (ops == &clk_nodrv_ops) {
 		pr_err("%s: unregistered clock: %s\n", __func__,
 		       clk->core->name);
-		goto unlock;
+		clk_prepare_unlock();
+		return;
 	}
 	/*
 	 * Assign empty clock ops for consumers that might still hold
@@ -4484,11 +4606,10 @@
 	if (clk->core->protect_count)
 		pr_warn("%s: unregistering protected clock: %s\n",
 					__func__, clk->core->name);
+	clk_prepare_unlock();
 
 	kref_put(&clk->core->ref, __clk_release);
 	free_clk(clk);
-unlock:
-	clk_prepare_unlock();
 }
 EXPORT_SYMBOL_GPL(clk_unregister);
 
@@ -4647,13 +4768,11 @@
 	if (clk->min_rate > 0 || clk->max_rate < ULONG_MAX)
 		clk_set_rate_range_nolock(clk, 0, ULONG_MAX);
 
-	owner = clk->core->owner;
-	kref_put(&clk->core->ref, __clk_release);
-
 	clk_prepare_unlock();
 
+	owner = clk->core->owner;
+	kref_put(&clk->core->ref, __clk_release);
 	module_put(owner);
-
 	free_clk(clk);
 }
 
@@ -5245,9 +5364,8 @@
 const char *of_clk_get_parent_name(const struct device_node *np, int index)
 {
 	struct of_phandle_args clkspec;
-	struct property *prop;
 	const char *clk_name;
-	const __be32 *vp;
+	bool found = false;
 	u32 pv;
 	int rc;
 	int count;
@@ -5264,16 +5382,19 @@
 	/* if there is an indices property, use it to transfer the index
 	 * specified into an array offset for the clock-output-names property.
 	 */
-	of_property_for_each_u32(clkspec.np, "clock-indices", prop, vp, pv) {
+	of_property_for_each_u32(clkspec.np, "clock-indices", pv) {
 		if (index == pv) {
 			index = count;
+			found = true;
 			break;
 		}
 		count++;
 	}
 	/* We went off the end of 'clock-indices' without finding it */
-	if (prop && !vp)
+	if (of_property_present(clkspec.np, "clock-indices") && !found) {
+		of_node_put(clkspec.np);
 		return NULL;
+	}
 
 	if (of_property_read_string_index(clkspec.np, "clock-output-names",
 					  index,
@@ -5385,14 +5506,12 @@
 int of_clk_detect_critical(struct device_node *np, int index,
 			   unsigned long *flags)
 {
-	struct property *prop;
-	const __be32 *cur;
 	uint32_t idx;
 
 	if (!np || !flags)
 		return -EINVAL;
 
-	of_property_for_each_u32(np, "clock-critical", prop, cur, idx)
+	of_property_for_each_u32(np, "clock-critical", idx)
 		if (index == idx)
 			*flags |= CLK_IS_CRITICAL;
 
--- linux-qcom-6.8.0.orig/drivers/clk/clkdev.c
+++ linux-qcom-6.8.0/drivers/clk/clkdev.c
@@ -144,7 +144,7 @@
 	mutex_unlock(&clocks_mutex);
 }
 
-#define MAX_DEV_ID	20
+#define MAX_DEV_ID	24
 #define MAX_CON_ID	16
 
 struct clk_lookup_alloc {
--- linux-qcom-6.8.0.orig/drivers/clk/davinci/da8xx-cfgchip.c
+++ linux-qcom-6.8.0/drivers/clk/davinci/da8xx-cfgchip.c
@@ -508,7 +508,7 @@
 	const char * const parent_names[] = { "usb_refclkin", "pll0_auxclk" };
 	struct clk *fck_clk;
 	struct da8xx_usb0_clk48 *usb0;
-	struct clk_init_data init;
+	struct clk_init_data init = {};
 	int ret;
 
 	fck_clk = devm_clk_get(dev, "fck");
@@ -583,7 +583,7 @@
 {
 	const char * const parent_names[] = { "usb0_clk48", "usb_refclkin" };
 	struct da8xx_usb1_clk48 *usb1;
-	struct clk_init_data init;
+	struct clk_init_data init = {};
 	int ret;
 
 	usb1 = devm_kzalloc(dev, sizeof(*usb1), GFP_KERNEL);
--- linux-qcom-6.8.0.orig/drivers/clk/hisilicon/clk-hi3519.c
+++ linux-qcom-6.8.0/drivers/clk/hisilicon/clk-hi3519.c
@@ -130,7 +130,7 @@
 	of_clk_del_provider(pdev->dev.of_node);
 
 	hisi_clk_unregister_gate(hi3519_gate_clks,
-				ARRAY_SIZE(hi3519_mux_clks),
+				ARRAY_SIZE(hi3519_gate_clks),
 				crg->clk_data);
 	hisi_clk_unregister_mux(hi3519_mux_clks,
 				ARRAY_SIZE(hi3519_mux_clks),
--- linux-qcom-6.8.0.orig/drivers/clk/hisilicon/clk-hi3559a.c
+++ linux-qcom-6.8.0/drivers/clk/hisilicon/clk-hi3559a.c
@@ -491,7 +491,6 @@
 
 		clk = clk_register(NULL, &p_clk->hw);
 		if (IS_ERR(clk)) {
-			devm_kfree(dev, p_clk);
 			dev_err(dev, "%s: failed to register clock %s\n",
 			       __func__, clks[i].name);
 			continue;
--- linux-qcom-6.8.0.orig/drivers/clk/imx/clk-composite-7ulp.c
+++ linux-qcom-6.8.0/drivers/clk/imx/clk-composite-7ulp.c
@@ -14,6 +14,7 @@
 #include "../clk-fractional-divider.h"
 #include "clk.h"
 
+#define PCG_PR_MASK		BIT(31)
 #define PCG_PCS_SHIFT	24
 #define PCG_PCS_MASK	0x7
 #define PCG_CGC_SHIFT	30
@@ -78,6 +79,12 @@
 	struct clk_hw *hw;
 	u32 val;
 
+	val = readl(reg);
+	if (!(val & PCG_PR_MASK)) {
+		pr_info("PCC PR is 0 for clk:%s, bypass\n", name);
+		return 0;
+	}
+
 	if (mux_present) {
 		mux = kzalloc(sizeof(*mux), GFP_KERNEL);
 		if (!mux)
--- linux-qcom-6.8.0.orig/drivers/clk/imx/clk-composite-8m.c
+++ linux-qcom-6.8.0/drivers/clk/imx/clk-composite-8m.c
@@ -204,6 +204,34 @@
 	.determine_rate = imx8m_clk_composite_mux_determine_rate,
 };
 
+static int imx8m_clk_composite_gate_enable(struct clk_hw *hw)
+{
+	struct clk_gate *gate = to_clk_gate(hw);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(gate->lock, flags);
+
+	val = readl(gate->reg);
+	val |= BIT(gate->bit_idx);
+	writel(val, gate->reg);
+
+	spin_unlock_irqrestore(gate->lock, flags);
+
+	return 0;
+}
+
+static void imx8m_clk_composite_gate_disable(struct clk_hw *hw)
+{
+	/* composite clk requires the disable hook */
+}
+
+static const struct clk_ops imx8m_clk_composite_gate_ops = {
+	.enable = imx8m_clk_composite_gate_enable,
+	.disable = imx8m_clk_composite_gate_disable,
+	.is_enabled = clk_gate_is_enabled,
+};
+
 struct clk_hw *__imx8m_clk_hw_composite(const char *name,
 					const char * const *parent_names,
 					int num_parents, void __iomem *reg,
@@ -217,10 +245,11 @@
 	struct clk_mux *mux = NULL;
 	const struct clk_ops *divider_ops;
 	const struct clk_ops *mux_ops;
+	const struct clk_ops *gate_ops;
 
 	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
 	if (!mux)
-		goto fail;
+		return ERR_CAST(hw);
 
 	mux_hw = &mux->hw;
 	mux->reg = reg;
@@ -230,7 +259,7 @@
 
 	div = kzalloc(sizeof(*div), GFP_KERNEL);
 	if (!div)
-		goto fail;
+		goto free_mux;
 
 	div_hw = &div->hw;
 	div->reg = reg;
@@ -257,28 +286,32 @@
 	div->flags = CLK_DIVIDER_ROUND_CLOSEST;
 
 	/* skip registering the gate ops if M4 is enabled */
-	if (!mcore_booted) {
-		gate = kzalloc(sizeof(*gate), GFP_KERNEL);
-		if (!gate)
-			goto fail;
-
-		gate_hw = &gate->hw;
-		gate->reg = reg;
-		gate->bit_idx = PCG_CGC_SHIFT;
-		gate->lock = &imx_ccm_lock;
-	}
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		goto free_div;
+
+	gate_hw = &gate->hw;
+	gate->reg = reg;
+	gate->bit_idx = PCG_CGC_SHIFT;
+	gate->lock = &imx_ccm_lock;
+	if (!mcore_booted)
+		gate_ops = &clk_gate_ops;
+	else
+		gate_ops = &imx8m_clk_composite_gate_ops;
 
 	hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
 			mux_hw, mux_ops, div_hw,
-			divider_ops, gate_hw, &clk_gate_ops, flags);
+			divider_ops, gate_hw, gate_ops, flags);
 	if (IS_ERR(hw))
-		goto fail;
+		goto free_gate;
 
 	return hw;
 
-fail:
+free_gate:
 	kfree(gate);
+free_div:
 	kfree(div);
+free_mux:
 	kfree(mux);
 	return ERR_CAST(hw);
 }
--- linux-qcom-6.8.0.orig/drivers/clk/imx/clk-composite-93.c
+++ linux-qcom-6.8.0/drivers/clk/imx/clk-composite-93.c
@@ -76,6 +76,13 @@
 
 static void imx93_clk_composite_gate_disable(struct clk_hw *hw)
 {
+	/*
+	 * Skip disable the root clock gate if mcore enabled.
+	 * The root clock may be used by the mcore.
+	 */
+	if (mcore_booted)
+		return;
+
 	imx93_clk_composite_gate_endisable(hw, 0);
 }
 
@@ -222,7 +229,7 @@
 		hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
 					       mux_hw, &clk_mux_ro_ops, div_hw,
 					       &clk_divider_ro_ops, NULL, NULL, flags);
-	} else if (!mcore_booted) {
+	} else {
 		gate = kzalloc(sizeof(*gate), GFP_KERNEL);
 		if (!gate)
 			goto fail;
@@ -238,12 +245,6 @@
 					       &imx93_clk_composite_divider_ops, gate_hw,
 					       &imx93_clk_composite_gate_ops,
 					       flags | CLK_SET_RATE_NO_REPARENT);
-	} else {
-		hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
-					       mux_hw, &imx93_clk_composite_mux_ops, div_hw,
-					       &imx93_clk_composite_divider_ops, NULL,
-					       &imx93_clk_composite_gate_ops,
-					       flags | CLK_SET_RATE_NO_REPARENT);
 	}
 
 	if (IS_ERR(hw))
--- linux-qcom-6.8.0.orig/drivers/clk/imx/clk-fracn-gppll.c
+++ linux-qcom-6.8.0/drivers/clk/imx/clk-fracn-gppll.c
@@ -252,9 +252,11 @@
 	pll_div = FIELD_PREP(PLL_RDIV_MASK, rate->rdiv) | rate->odiv |
 		FIELD_PREP(PLL_MFI_MASK, rate->mfi);
 	writel_relaxed(pll_div, pll->base + PLL_DIV);
+	readl(pll->base + PLL_DIV);
 	if (pll->flags & CLK_FRACN_GPPLL_FRACN) {
 		writel_relaxed(rate->mfd, pll->base + PLL_DENOMINATOR);
 		writel_relaxed(FIELD_PREP(PLL_MFN_MASK, rate->mfn), pll->base + PLL_NUMERATOR);
+		readl(pll->base + PLL_NUMERATOR);
 	}
 
 	/* Wait for 5us according to fracn mode pll doc */
@@ -263,6 +265,7 @@
 	/* Enable Powerup */
 	tmp |= POWERUP_MASK;
 	writel_relaxed(tmp, pll->base + PLL_CTRL);
+	readl(pll->base + PLL_CTRL);
 
 	/* Wait Lock */
 	ret = clk_fracn_gppll_wait_lock(pll);
@@ -291,19 +294,24 @@
 	if (val & POWERUP_MASK)
 		return 0;
 
+	if (pll->flags & CLK_FRACN_GPPLL_FRACN)
+		writel_relaxed(readl_relaxed(pll->base + PLL_NUMERATOR),
+			       pll->base + PLL_NUMERATOR);
+
 	val |= CLKMUX_BYPASS;
 	writel_relaxed(val, pll->base + PLL_CTRL);
 
 	val |= POWERUP_MASK;
 	writel_relaxed(val, pll->base + PLL_CTRL);
-
-	val |= CLKMUX_EN;
-	writel_relaxed(val, pll->base + PLL_CTRL);
+	readl(pll->base + PLL_CTRL);
 
 	ret = clk_fracn_gppll_wait_lock(pll);
 	if (ret)
 		return ret;
 
+	val |= CLKMUX_EN;
+	writel_relaxed(val, pll->base + PLL_CTRL);
+
 	val &= ~CLKMUX_BYPASS;
 	writel_relaxed(val, pll->base + PLL_CTRL);
 
--- linux-qcom-6.8.0.orig/drivers/clk/imx/clk-imx6ul.c
+++ linux-qcom-6.8.0/drivers/clk/imx/clk-imx6ul.c
@@ -542,8 +542,8 @@
 
 	clk_set_parent(hws[IMX6UL_CLK_ENFC_SEL]->clk, hws[IMX6UL_CLK_PLL2_PFD2]->clk);
 
-	clk_set_parent(hws[IMX6UL_CLK_ENET1_REF_SEL]->clk, hws[IMX6UL_CLK_ENET_REF]->clk);
-	clk_set_parent(hws[IMX6UL_CLK_ENET2_REF_SEL]->clk, hws[IMX6UL_CLK_ENET2_REF]->clk);
+	clk_set_parent(hws[IMX6UL_CLK_ENET1_REF_SEL]->clk, hws[IMX6UL_CLK_ENET1_REF_125M]->clk);
+	clk_set_parent(hws[IMX6UL_CLK_ENET2_REF_SEL]->clk, hws[IMX6UL_CLK_ENET2_REF_125M]->clk);
 
 	imx_register_uart_clocks();
 }
--- linux-qcom-6.8.0.orig/drivers/clk/imx/clk-imx7d.c
+++ linux-qcom-6.8.0/drivers/clk/imx/clk-imx7d.c
@@ -498,9 +498,9 @@
 	hws[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_hw_mux2_flags("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel), CLK_SET_PARENT_GATE);
 	hws[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_hw_mux2_flags("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel), CLK_SET_PARENT_GATE);
 	hws[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_hw_mux2_flags("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel), CLK_SET_PARENT_GATE);
-	hws[IMX7D_DRAM_ROOT_SRC] = imx_clk_hw_mux2_flags("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel), CLK_SET_PARENT_GATE);
+	hws[IMX7D_DRAM_ROOT_SRC] = imx_clk_hw_mux2("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel));
 	hws[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_hw_mux2_flags("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel), CLK_SET_PARENT_GATE);
-	hws[IMX7D_DRAM_ALT_ROOT_SRC]  = imx_clk_hw_mux2_flags("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel), CLK_SET_PARENT_GATE);
+	hws[IMX7D_DRAM_ALT_ROOT_SRC]  = imx_clk_hw_mux2("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel));
 	hws[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_hw_mux2_flags("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel), CLK_SET_PARENT_GATE);
 	hws[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_hw_mux2_flags("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel), CLK_SET_PARENT_GATE);
 	hws[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_hw_mux2_flags("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel), CLK_SET_PARENT_GATE);
--- linux-qcom-6.8.0.orig/drivers/clk/imx/clk-imx8-acm.c
+++ linux-qcom-6.8.0/drivers/clk/imx/clk-imx8-acm.c
@@ -289,9 +289,9 @@
 							 DL_FLAG_STATELESS |
 							 DL_FLAG_PM_RUNTIME |
 							 DL_FLAG_RPM_ACTIVE);
-		if (IS_ERR(dev_pm->pd_dev_link[i])) {
+		if (!dev_pm->pd_dev_link[i]) {
 			dev_pm_domain_detach(dev_pm->pd_dev[i], false);
-			ret = PTR_ERR(dev_pm->pd_dev_link[i]);
+			ret = -EINVAL;
 			goto detach_pm;
 		}
 	}
--- linux-qcom-6.8.0.orig/drivers/clk/imx/clk-imx8mp-audiomix.c
+++ linux-qcom-6.8.0/drivers/clk/imx/clk-imx8mp-audiomix.c
@@ -18,7 +18,12 @@
 
 #define CLKEN0			0x000
 #define CLKEN1			0x004
-#define SAI_MCLK_SEL(n)		(0x300 + 4 * (n))	/* n in 0..5 */
+#define SAI1_MCLK_SEL		0x300
+#define SAI2_MCLK_SEL		0x304
+#define SAI3_MCLK_SEL		0x308
+#define SAI5_MCLK_SEL		0x30C
+#define SAI6_MCLK_SEL		0x310
+#define SAI7_MCLK_SEL		0x314
 #define PDM_SEL			0x318
 #define SAI_PLL_GNRL_CTL	0x400
 
@@ -95,13 +100,13 @@
 		IMX8MP_CLK_AUDIOMIX_SAI##n##_MCLK1_SEL, {},		\
 		clk_imx8mp_audiomix_sai##n##_mclk1_parents,		\
 		ARRAY_SIZE(clk_imx8mp_audiomix_sai##n##_mclk1_parents), \
-		SAI_MCLK_SEL(n), 1, 0					\
+		SAI##n##_MCLK_SEL, 1, 0					\
 	}, {								\
 		"sai"__stringify(n)"_mclk2_sel",			\
 		IMX8MP_CLK_AUDIOMIX_SAI##n##_MCLK2_SEL, {},		\
 		clk_imx8mp_audiomix_sai_mclk2_parents,			\
 		ARRAY_SIZE(clk_imx8mp_audiomix_sai_mclk2_parents),	\
-		SAI_MCLK_SEL(n), 4, 1					\
+		SAI##n##_MCLK_SEL, 4, 1					\
 	}, {								\
 		"sai"__stringify(n)"_ipg_cg",				\
 		IMX8MP_CLK_AUDIOMIX_SAI##n##_IPG,			\
@@ -141,6 +146,15 @@
 		PDM_SEL, 2, 0						\
 	}
 
+#define CLK_GATE_PARENT(gname, cname, pname)						\
+	{								\
+		gname"_cg",						\
+		IMX8MP_CLK_AUDIOMIX_##cname,				\
+		{ .fw_name = pname, .name = pname }, NULL, 1,		\
+		CLKEN0 + 4 * !!(IMX8MP_CLK_AUDIOMIX_##cname / 32),	\
+		1, IMX8MP_CLK_AUDIOMIX_##cname % 32			\
+	}
+
 struct clk_imx8mp_audiomix_sel {
 	const char			*name;
 	int				clkid;
@@ -158,14 +172,14 @@
 	CLK_GATE("earc", EARC_IPG),
 	CLK_GATE("ocrama", OCRAMA_IPG),
 	CLK_GATE("aud2htx", AUD2HTX_IPG),
-	CLK_GATE("earc_phy", EARC_PHY),
+	CLK_GATE_PARENT("earc_phy", EARC_PHY, "sai_pll_out_div2"),
 	CLK_GATE("sdma2", SDMA2_ROOT),
 	CLK_GATE("sdma3", SDMA3_ROOT),
 	CLK_GATE("spba2", SPBA2_ROOT),
 	CLK_GATE("dsp", DSP_ROOT),
 	CLK_GATE("dspdbg", DSPDBG_ROOT),
 	CLK_GATE("edma", EDMA_ROOT),
-	CLK_GATE("audpll", AUDPLL_ROOT),
+	CLK_GATE_PARENT("audpll", AUDPLL_ROOT, "osc_24m"),
 	CLK_GATE("mu2", MU2_ROOT),
 	CLK_GATE("mu3", MU3_ROOT),
 	CLK_PDM,
--- linux-qcom-6.8.0.orig/drivers/clk/imx/clk-imx8mp.c
+++ linux-qcom-6.8.0/drivers/clk/imx/clk-imx8mp.c
@@ -399,8 +399,9 @@
 
 static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
 						  "dummy", "dummy", "gpu_pll_out", "vpu_pll_out",
-						  "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
-						  "dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
+						  "arm_pll_out", "sys_pll1_out", "sys_pll2_out",
+						  "sys_pll3_out", "dummy", "dummy", "osc_24m",
+						  "dummy", "osc_32k"};
 
 static struct clk_hw **hws;
 static struct clk_hw_onecell_data *clk_hw_data;
@@ -551,8 +552,8 @@
 
 	hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1);
 
-	hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_composite("dram_alt", imx8mp_dram_alt_sels, ccm_base + 0xa000);
-	hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_composite_critical("dram_apb", imx8mp_dram_apb_sels, ccm_base + 0xa080);
+	hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_fw_managed_composite("dram_alt", imx8mp_dram_alt_sels, ccm_base + 0xa000);
+	hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_fw_managed_composite_critical("dram_apb", imx8mp_dram_apb_sels, ccm_base + 0xa080);
 	hws[IMX8MP_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mp_vpu_g1_sels, ccm_base + 0xa100);
 	hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mp_vpu_g2_sels, ccm_base + 0xa180);
 	hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, ccm_base + 0xa200);
--- linux-qcom-6.8.0.orig/drivers/clk/imx/clk-imx8qxp.c
+++ linux-qcom-6.8.0/drivers/clk/imx/clk-imx8qxp.c
@@ -170,8 +170,8 @@
 	imx_clk_scu("pwm_clk",   IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER);
 	imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL);
 	imx_clk_scu2("lcd_clk", lcd_sels, ARRAY_SIZE(lcd_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER);
-	imx_clk_scu2("lcd_pxl_clk", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_MISC0);
 	imx_clk_scu("lcd_pxl_bypass_div_clk", IMX_SC_R_LCD_0, IMX_SC_PM_CLK_BYPASS);
+	imx_clk_scu2("lcd_pxl_clk", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_MISC0);
 
 	/* Audio SS */
 	imx_clk_scu("audio_pll0_clk", IMX_SC_R_AUDIO_PLL_0, IMX_SC_PM_CLK_PLL);
@@ -206,18 +206,18 @@
 	imx_clk_scu("usb3_lpm_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_MISC);
 
 	/* Display controller SS */
-	imx_clk_scu2("dc0_disp0_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0);
-	imx_clk_scu2("dc0_disp1_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1);
 	imx_clk_scu("dc0_pll0_clk", IMX_SC_R_DC_0_PLL_0, IMX_SC_PM_CLK_PLL);
 	imx_clk_scu("dc0_pll1_clk", IMX_SC_R_DC_0_PLL_1, IMX_SC_PM_CLK_PLL);
 	imx_clk_scu("dc0_bypass0_clk", IMX_SC_R_DC_0_VIDEO0, IMX_SC_PM_CLK_BYPASS);
+	imx_clk_scu2("dc0_disp0_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC0);
+	imx_clk_scu2("dc0_disp1_clk", dc0_sels, ARRAY_SIZE(dc0_sels), IMX_SC_R_DC_0, IMX_SC_PM_CLK_MISC1);
 	imx_clk_scu("dc0_bypass1_clk", IMX_SC_R_DC_0_VIDEO1, IMX_SC_PM_CLK_BYPASS);
 
-	imx_clk_scu2("dc1_disp0_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC0);
-	imx_clk_scu2("dc1_disp1_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC1);
 	imx_clk_scu("dc1_pll0_clk", IMX_SC_R_DC_1_PLL_0, IMX_SC_PM_CLK_PLL);
 	imx_clk_scu("dc1_pll1_clk", IMX_SC_R_DC_1_PLL_1, IMX_SC_PM_CLK_PLL);
 	imx_clk_scu("dc1_bypass0_clk", IMX_SC_R_DC_1_VIDEO0, IMX_SC_PM_CLK_BYPASS);
+	imx_clk_scu2("dc1_disp0_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC0);
+	imx_clk_scu2("dc1_disp1_clk", dc1_sels, ARRAY_SIZE(dc1_sels), IMX_SC_R_DC_1, IMX_SC_PM_CLK_MISC1);
 	imx_clk_scu("dc1_bypass1_clk", IMX_SC_R_DC_1_VIDEO1, IMX_SC_PM_CLK_BYPASS);
 
 	/* MIPI-LVDS SS */
--- linux-qcom-6.8.0.orig/drivers/clk/imx/clk-imx93.c
+++ linux-qcom-6.8.0/drivers/clk/imx/clk-imx93.c
@@ -15,6 +15,11 @@
 
 #include "clk.h"
 
+#define IMX93_CLK_END 208
+
+#define PLAT_IMX93 BIT(0)
+#define PLAT_IMX91 BIT(1)
+
 enum clk_sel {
 	LOW_SPEED_IO_SEL,
 	NON_IO_SEL,
@@ -33,6 +38,7 @@
 static u32 share_count_sai3;
 static u32 share_count_mub;
 static u32 share_count_pdm;
+static u32 share_count_spdif;
 
 static const char * const a55_core_sels[] = {"a55_alt", "arm_pll"};
 static const char *parent_names[MAX_SEL][4] = {
@@ -53,6 +59,7 @@
 	u32 off;
 	enum clk_sel sel;
 	unsigned long flags;
+	unsigned long plat;
 } root_array[] = {
 	/* a55/m33/bus critical clk for system run */
 	{ IMX93_CLK_A55_PERIPH,		"a55_periph_root",	0x0000,	FAST_SEL, CLK_IS_CRITICAL },
@@ -63,9 +70,9 @@
 	{ IMX93_CLK_BUS_AON,		"bus_aon_root",		0x0300,	LOW_SPEED_IO_SEL, CLK_IS_CRITICAL },
 	{ IMX93_CLK_WAKEUP_AXI,		"wakeup_axi_root",	0x0380,	FAST_SEL, CLK_IS_CRITICAL },
 	{ IMX93_CLK_SWO_TRACE,		"swo_trace_root",	0x0400,	LOW_SPEED_IO_SEL, },
-	{ IMX93_CLK_M33_SYSTICK,	"m33_systick_root",	0x0480,	LOW_SPEED_IO_SEL, },
-	{ IMX93_CLK_FLEXIO1,		"flexio1_root",		0x0500,	LOW_SPEED_IO_SEL, },
-	{ IMX93_CLK_FLEXIO2,		"flexio2_root",		0x0580,	LOW_SPEED_IO_SEL, },
+	{ IMX93_CLK_M33_SYSTICK,	"m33_systick_root",	0x0480,	LOW_SPEED_IO_SEL, 0, PLAT_IMX93, },
+	{ IMX93_CLK_FLEXIO1,		"flexio1_root",		0x0500,	LOW_SPEED_IO_SEL, 0, PLAT_IMX93, },
+	{ IMX93_CLK_FLEXIO2,		"flexio2_root",		0x0580,	LOW_SPEED_IO_SEL, 0, PLAT_IMX93, },
 	{ IMX93_CLK_LPTMR1,		"lptmr1_root",		0x0700,	LOW_SPEED_IO_SEL, },
 	{ IMX93_CLK_LPTMR2,		"lptmr2_root",		0x0780,	LOW_SPEED_IO_SEL, },
 	{ IMX93_CLK_TPM2,		"tpm2_root",		0x0880,	TPM_SEL, },
@@ -120,15 +127,15 @@
 	{ IMX93_CLK_HSIO_ACSCAN_80M,	"hsio_acscan_80m_root",	0x1f80,	LOW_SPEED_IO_SEL, },
 	{ IMX93_CLK_HSIO_ACSCAN_480M,	"hsio_acscan_480m_root", 0x2000, MISC_SEL, },
 	{ IMX93_CLK_NIC_AXI,		"nic_axi_root",		0x2080, FAST_SEL, CLK_IS_CRITICAL, },
-	{ IMX93_CLK_ML_APB,		"ml_apb_root",		0x2180,	LOW_SPEED_IO_SEL, },
-	{ IMX93_CLK_ML,			"ml_root",		0x2200,	FAST_SEL, },
+	{ IMX93_CLK_ML_APB,		"ml_apb_root",		0x2180,	LOW_SPEED_IO_SEL, 0, PLAT_IMX93, },
+	{ IMX93_CLK_ML,			"ml_root",		0x2200,	FAST_SEL, 0, PLAT_IMX93, },
 	{ IMX93_CLK_MEDIA_AXI,		"media_axi_root",	0x2280,	FAST_SEL, },
 	{ IMX93_CLK_MEDIA_APB,		"media_apb_root",	0x2300,	LOW_SPEED_IO_SEL, },
-	{ IMX93_CLK_MEDIA_LDB,		"media_ldb_root",	0x2380,	VIDEO_SEL, },
+	{ IMX93_CLK_MEDIA_LDB,		"media_ldb_root",	0x2380,	VIDEO_SEL, 0, PLAT_IMX93, },
 	{ IMX93_CLK_MEDIA_DISP_PIX,	"media_disp_pix_root",	0x2400,	VIDEO_SEL, },
 	{ IMX93_CLK_CAM_PIX,		"cam_pix_root",		0x2480,	VIDEO_SEL, },
-	{ IMX93_CLK_MIPI_TEST_BYTE,	"mipi_test_byte_root",	0x2500,	VIDEO_SEL, },
-	{ IMX93_CLK_MIPI_PHY_CFG,	"mipi_phy_cfg_root",	0x2580,	VIDEO_SEL, },
+	{ IMX93_CLK_MIPI_TEST_BYTE,	"mipi_test_byte_root",	0x2500,	VIDEO_SEL, 0, PLAT_IMX93, },
+	{ IMX93_CLK_MIPI_PHY_CFG,	"mipi_phy_cfg_root",	0x2580,	VIDEO_SEL, 0, PLAT_IMX93, },
 	{ IMX93_CLK_ADC,		"adc_root",		0x2700,	LOW_SPEED_IO_SEL, },
 	{ IMX93_CLK_PDM,		"pdm_root",		0x2780,	AUDIO_SEL, },
 	{ IMX93_CLK_TSTMR1,		"tstmr1_root",		0x2800,	LOW_SPEED_IO_SEL, },
@@ -137,13 +144,16 @@
 	{ IMX93_CLK_MQS2,		"mqs2_root",		0x2980,	AUDIO_SEL, },
 	{ IMX93_CLK_AUDIO_XCVR,		"audio_xcvr_root",	0x2a00,	NON_IO_SEL, },
 	{ IMX93_CLK_SPDIF,		"spdif_root",		0x2a80,	AUDIO_SEL, },
-	{ IMX93_CLK_ENET,		"enet_root",		0x2b00,	NON_IO_SEL, },
-	{ IMX93_CLK_ENET_TIMER1,	"enet_timer1_root",	0x2b80,	LOW_SPEED_IO_SEL, },
-	{ IMX93_CLK_ENET_TIMER2,	"enet_timer2_root",	0x2c00,	LOW_SPEED_IO_SEL, },
-	{ IMX93_CLK_ENET_REF,		"enet_ref_root",	0x2c80,	NON_IO_SEL, },
-	{ IMX93_CLK_ENET_REF_PHY,	"enet_ref_phy_root",	0x2d00,	LOW_SPEED_IO_SEL, },
-	{ IMX93_CLK_I3C1_SLOW,		"i3c1_slow_root",	0x2d80,	LOW_SPEED_IO_SEL, },
-	{ IMX93_CLK_I3C2_SLOW,		"i3c2_slow_root",	0x2e00,	LOW_SPEED_IO_SEL, },
+	{ IMX93_CLK_ENET,		"enet_root",		0x2b00,	NON_IO_SEL, 0, PLAT_IMX93, },
+	{ IMX93_CLK_ENET_TIMER1,	"enet_timer1_root",	0x2b80,	LOW_SPEED_IO_SEL, 0, PLAT_IMX93, },
+	{ IMX93_CLK_ENET_TIMER2,	"enet_timer2_root",	0x2c00,	LOW_SPEED_IO_SEL, 0, PLAT_IMX93, },
+	{ IMX93_CLK_ENET_REF,		"enet_ref_root",	0x2c80,	NON_IO_SEL, 0, PLAT_IMX93, },
+	{ IMX93_CLK_ENET_REF_PHY,	"enet_ref_phy_root",	0x2d00,	LOW_SPEED_IO_SEL, 0, PLAT_IMX93, },
+	{ IMX91_CLK_ENET1_QOS_TSN,	"enet1_qos_tsn_root",   0x2b00, NON_IO_SEL, 0, PLAT_IMX91, },
+	{ IMX91_CLK_ENET_TIMER,		"enet_timer_root",      0x2b80, LOW_SPEED_IO_SEL, 0, PLAT_IMX91, },
+	{ IMX91_CLK_ENET2_REGULAR,	"enet2_regular_root",   0x2c80, NON_IO_SEL, 0, PLAT_IMX91, },
+	{ IMX93_CLK_I3C1_SLOW,		"i3c1_slow_root",	0x2d80,	LOW_SPEED_IO_SEL, 0, PLAT_IMX93, },
+	{ IMX93_CLK_I3C2_SLOW,		"i3c2_slow_root",	0x2e00,	LOW_SPEED_IO_SEL, 0, PLAT_IMX93, },
 	{ IMX93_CLK_USB_PHY_BURUNIN,	"usb_phy_root",		0x2e80,	LOW_SPEED_IO_SEL, },
 	{ IMX93_CLK_PAL_CAME_SCAN,	"pal_came_scan_root",	0x2f00,	MISC_SEL, }
 };
@@ -155,6 +165,7 @@
 	u32 off;
 	unsigned long flags;
 	u32 *shared_count;
+	unsigned long plat;
 } ccgr_array[] = {
 	{ IMX93_CLK_A55_GATE,		"a55_alt",	"a55_alt_root",		0x8000, },
 	/* M33 critical clk for system run */
@@ -167,10 +178,10 @@
 	{ IMX93_CLK_WDOG5_GATE,		"wdog5",	"osc_24m",		0x8400, },
 	{ IMX93_CLK_SEMA1_GATE,		"sema1",	"bus_aon_root",		0x8440, },
 	{ IMX93_CLK_SEMA2_GATE,		"sema2",	"bus_wakeup_root",	0x8480, },
-	{ IMX93_CLK_MU1_A_GATE,		"mu1_a",	"bus_aon_root",		0x84c0, CLK_IGNORE_UNUSED },
-	{ IMX93_CLK_MU2_A_GATE,		"mu2_a",	"bus_wakeup_root",	0x84c0, CLK_IGNORE_UNUSED },
-	{ IMX93_CLK_MU1_B_GATE,		"mu1_b",	"bus_aon_root",		0x8500, 0, &share_count_mub },
-	{ IMX93_CLK_MU2_B_GATE,		"mu2_b",	"bus_wakeup_root",	0x8500, 0, &share_count_mub },
+	{ IMX93_CLK_MU1_A_GATE,		"mu1_a",	"bus_aon_root",		0x84c0, CLK_IGNORE_UNUSED, NULL, PLAT_IMX93 },
+	{ IMX93_CLK_MU2_A_GATE,		"mu2_a",	"bus_wakeup_root",	0x84c0, CLK_IGNORE_UNUSED, NULL, PLAT_IMX93 },
+	{ IMX93_CLK_MU1_B_GATE,		"mu1_b",	"bus_aon_root",		0x8500, 0, &share_count_mub, PLAT_IMX93 },
+	{ IMX93_CLK_MU2_B_GATE,		"mu2_b",	"bus_wakeup_root",	0x8500, 0, &share_count_mub, PLAT_IMX93 },
 	{ IMX93_CLK_EDMA1_GATE,		"edma1",	"m33_root",		0x8540, },
 	{ IMX93_CLK_EDMA2_GATE,		"edma2",	"wakeup_axi_root",	0x8580, },
 	{ IMX93_CLK_FLEXSPI1_GATE,	"flexspi1",	"flexspi1_root",	0x8640, },
@@ -178,8 +189,8 @@
 	{ IMX93_CLK_GPIO2_GATE,		"gpio2",	"bus_wakeup_root",	0x88c0, },
 	{ IMX93_CLK_GPIO3_GATE,		"gpio3",	"bus_wakeup_root",	0x8900, },
 	{ IMX93_CLK_GPIO4_GATE,		"gpio4",	"bus_wakeup_root",	0x8940, },
-	{ IMX93_CLK_FLEXIO1_GATE,	"flexio1",	"flexio1_root",		0x8980, },
-	{ IMX93_CLK_FLEXIO2_GATE,	"flexio2",	"flexio2_root",		0x89c0, },
+	{ IMX93_CLK_FLEXIO1_GATE,	"flexio1",	"flexio1_root",		0x8980, 0, NULL, PLAT_IMX93},
+	{ IMX93_CLK_FLEXIO2_GATE,	"flexio2",	"flexio2_root",		0x89c0, 0, NULL, PLAT_IMX93},
 	{ IMX93_CLK_LPIT1_GATE,		"lpit1",	"bus_aon_root",		0x8a00, },
 	{ IMX93_CLK_LPIT2_GATE,		"lpit2",	"bus_wakeup_root",	0x8a40, },
 	{ IMX93_CLK_LPTMR1_GATE,	"lptmr1",	"lptmr1_root",		0x8a80, },
@@ -228,10 +239,10 @@
 	{ IMX93_CLK_SAI3_GATE,          "sai3",         "sai3_root",            0x94c0, 0, &share_count_sai3},
 	{ IMX93_CLK_SAI3_IPG,		"sai3_ipg_clk", "bus_wakeup_root",	0x94c0, 0, &share_count_sai3},
 	{ IMX93_CLK_MIPI_CSI_GATE,	"mipi_csi",	"media_apb_root",	0x9580, },
-	{ IMX93_CLK_MIPI_DSI_GATE,	"mipi_dsi",	"media_apb_root",	0x95c0, },
-	{ IMX93_CLK_LVDS_GATE,		"lvds",		"media_ldb_root",	0x9600, },
+	{ IMX93_CLK_MIPI_DSI_GATE,	"mipi_dsi",	"media_apb_root",	0x95c0, 0, NULL, PLAT_IMX93 },
+	{ IMX93_CLK_LVDS_GATE,		"lvds",		"media_ldb_root",	0x9600, 0, NULL, PLAT_IMX93 },
 	{ IMX93_CLK_LCDIF_GATE,		"lcdif",	"media_apb_root",	0x9640, },
-	{ IMX93_CLK_PXP_GATE,		"pxp",		"media_apb_root",	0x9680, },
+	{ IMX93_CLK_PXP_GATE,		"pxp",		"media_apb_root",	0x9680, 0, NULL, PLAT_IMX93 },
 	{ IMX93_CLK_ISI_GATE,		"isi",		"media_apb_root",	0x96c0, },
 	{ IMX93_CLK_NIC_MEDIA_GATE,	"nic_media",	"media_axi_root",	0x9700, },
 	{ IMX93_CLK_USB_CONTROLLER_GATE, "usb_controller", "hsio_root",		0x9a00, },
@@ -242,10 +253,13 @@
 	{ IMX93_CLK_MQS1_GATE,		"mqs1",		"sai1_root",		0x9b00, },
 	{ IMX93_CLK_MQS2_GATE,		"mqs2",		"sai3_root",		0x9b40, },
 	{ IMX93_CLK_AUD_XCVR_GATE,	"aud_xcvr",	"audio_xcvr_root",	0x9b80, },
-	{ IMX93_CLK_SPDIF_GATE,		"spdif",	"spdif_root",		0x9c00, },
+	{ IMX93_CLK_SPDIF_IPG,		"spdif_ipg_clk", "bus_wakeup_root",	0x9c00, 0, &share_count_spdif},
+	{ IMX93_CLK_SPDIF_GATE,		"spdif",	"spdif_root",		0x9c00, 0, &share_count_spdif},
 	{ IMX93_CLK_HSIO_32K_GATE,	"hsio_32k",	"osc_32k",		0x9dc0, },
-	{ IMX93_CLK_ENET1_GATE,		"enet1",	"wakeup_axi_root",	0x9e00, },
-	{ IMX93_CLK_ENET_QOS_GATE,	"enet_qos",	"wakeup_axi_root",	0x9e40, },
+	{ IMX93_CLK_ENET1_GATE,		"enet1",	"wakeup_axi_root",	0x9e00, 0, NULL, PLAT_IMX93, },
+	{ IMX93_CLK_ENET_QOS_GATE,	"enet_qos",	"wakeup_axi_root",	0x9e40, 0, NULL, PLAT_IMX93, },
+	{ IMX91_CLK_ENET2_REGULAR_GATE, "enet2_regular", "wakeup_axi_root",	0x9e00, 0, NULL, PLAT_IMX91, },
+	{ IMX91_CLK_ENET1_QOS_TSN_GATE, "enet1_qos_tsn", "wakeup_axi_root",	0x9e40, 0, NULL, PLAT_IMX91, },
 	/* Critical because clk accessed during CPU idle */
 	{ IMX93_CLK_SYS_CNT_GATE,	"sys_cnt",	"osc_24m",		0x9e80, CLK_IS_CRITICAL},
 	{ IMX93_CLK_TSTMR1_GATE,	"tstmr1",	"bus_aon_root",		0x9ec0, },
@@ -265,6 +279,7 @@
 	const struct imx93_clk_ccgr *ccgr;
 	void __iomem *base, *anatop_base;
 	int i, ret;
+	const unsigned long plat = (unsigned long)device_get_match_data(&pdev->dev);
 
 	clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws,
 					  IMX93_CLK_END), GFP_KERNEL);
@@ -314,17 +329,20 @@
 
 	for (i = 0; i < ARRAY_SIZE(root_array); i++) {
 		root = &root_array[i];
-		clks[root->clk] = imx93_clk_composite_flags(root->name,
-							    parent_names[root->sel],
-							    4, base + root->off, 3,
-							    root->flags);
+		if (!root->plat || root->plat & plat)
+			clks[root->clk] = imx93_clk_composite_flags(root->name,
+								    parent_names[root->sel],
+								    4, base + root->off, 3,
+								    root->flags);
 	}
 
 	for (i = 0; i < ARRAY_SIZE(ccgr_array); i++) {
 		ccgr = &ccgr_array[i];
-		clks[ccgr->clk] = imx93_clk_gate(NULL, ccgr->name, ccgr->parent_name,
-						 ccgr->flags, base + ccgr->off, 0, 1, 1, 3,
-						 ccgr->shared_count);
+		if (!ccgr->plat || ccgr->plat & plat)
+			clks[ccgr->clk] = imx93_clk_gate(NULL,
+							 ccgr->name, ccgr->parent_name,
+							 ccgr->flags, base + ccgr->off, 0, 1, 1, 3,
+							 ccgr->shared_count);
 	}
 
 	clks[IMX93_CLK_A55_SEL] = imx_clk_hw_mux2("a55_sel", base + 0x4820, 0, 1, a55_core_sels,
@@ -354,7 +372,8 @@
 }
 
 static const struct of_device_id imx93_clk_of_match[] = {
-	{ .compatible = "fsl,imx93-ccm" },
+	{ .compatible = "fsl,imx93-ccm", .data = (void *)PLAT_IMX93 },
+	{ .compatible = "fsl,imx91-ccm", .data = (void *)PLAT_IMX91 },
 	{ /* Sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, imx93_clk_of_match);
--- linux-qcom-6.8.0.orig/drivers/clk/imx/clk-lpcg-scu.c
+++ linux-qcom-6.8.0/drivers/clk/imx/clk-lpcg-scu.c
@@ -6,10 +6,12 @@
 
 #include <linux/bits.h>
 #include <linux/clk-provider.h>
+#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/units.h>
 
 #include "clk-scu.h"
 
@@ -41,6 +43,29 @@
 
 #define to_clk_lpcg_scu(_hw) container_of(_hw, struct clk_lpcg_scu, hw)
 
+/* e10858 -LPCG clock gating register synchronization errata */
+static void lpcg_e10858_writel(unsigned long rate, void __iomem *reg, u32 val)
+{
+	writel(val, reg);
+
+	if (rate >= 24 * HZ_PER_MHZ || rate == 0) {
+		/*
+		 * The time taken to access the LPCG registers from the AP core
+		 * through the interconnect is longer than the minimum delay
+		 * of 4 clock cycles required by the errata.
+		 * Adding a readl will provide sufficient delay to prevent
+		 * back-to-back writes.
+		 */
+		readl(reg);
+	} else {
+		/*
+		 * For clocks running below 24MHz, wait a minimum of
+		 * 4 clock cycles.
+		 */
+		ndelay(4 * (DIV_ROUND_UP(1000 * HZ_PER_MHZ, rate)));
+	}
+}
+
 static int clk_lpcg_scu_enable(struct clk_hw *hw)
 {
 	struct clk_lpcg_scu *clk = to_clk_lpcg_scu(hw);
@@ -57,7 +82,8 @@
 		val |= CLK_GATE_SCU_LPCG_HW_SEL;
 
 	reg |= val << clk->bit_idx;
-	writel(reg, clk->reg);
+
+	lpcg_e10858_writel(clk_hw_get_rate(hw), clk->reg, reg);
 
 	spin_unlock_irqrestore(&imx_lpcg_scu_lock, flags);
 
@@ -74,7 +100,7 @@
 
 	reg = readl_relaxed(clk->reg);
 	reg &= ~(CLK_GATE_SCU_LPCG_MASK << clk->bit_idx);
-	writel(reg, clk->reg);
+	lpcg_e10858_writel(clk_hw_get_rate(hw), clk->reg, reg);
 
 	spin_unlock_irqrestore(&imx_lpcg_scu_lock, flags);
 }
@@ -145,13 +171,8 @@
 {
 	struct clk_lpcg_scu *clk = dev_get_drvdata(dev);
 
-	/*
-	 * FIXME: Sometimes writes don't work unless the CPU issues
-	 * them twice
-	 */
-
-	writel(clk->state, clk->reg);
 	writel(clk->state, clk->reg);
+	lpcg_e10858_writel(0, clk->reg, clk->state);
 	dev_dbg(dev, "restore lpcg state 0x%x\n", clk->state);
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/clk/imx/clk-scu.c
+++ linux-qcom-6.8.0/drivers/clk/imx/clk-scu.c
@@ -596,7 +596,7 @@
 		clk->rate = clk_scu_recalc_rate(&clk->hw, 0);
 	else
 		clk->rate = clk_hw_get_rate(&clk->hw);
-	clk->is_enabled = clk_hw_is_enabled(&clk->hw);
+	clk->is_enabled = clk_hw_is_prepared(&clk->hw);
 
 	if (clk->parent)
 		dev_dbg(dev, "save parent %s idx %u\n", clk_hw_get_name(clk->parent),
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/Kconfig
+++ linux-qcom-6.8.0/drivers/clk/mediatek/Kconfig
@@ -887,13 +887,6 @@
 	help
 	  This driver supports MediaTek MT8195 AI Processor Unit System clocks.
 
-config COMMON_CLK_MT8195_AUDSYS
-	tristate "Clock driver for MediaTek MT8195 audsys"
-	depends on COMMON_CLK_MT8195
-	default COMMON_CLK_MT8195
-	help
-	  This driver supports MediaTek MT8195 audsys clocks.
-
 config COMMON_CLK_MT8195_IMP_IIC_WRAP
 	tristate "Clock driver for MediaTek MT8195 imp_iic_wrap"
 	depends on COMMON_CLK_MT8195
@@ -908,14 +901,6 @@
 	help
 	  This driver supports MediaTek MT8195 mfgcfg clocks.
 
-config COMMON_CLK_MT8195_MSDC
-	tristate "Clock driver for MediaTek MT8195 msdc"
-	depends on COMMON_CLK_MT8195
-	default COMMON_CLK_MT8195
-	help
-	  This driver supports MediaTek MT8195 MMC and SD Controller's
-	  msdc and msdc_top clocks.
-
 config COMMON_CLK_MT8195_SCP_ADSP
 	tristate "Clock driver for MediaTek MT8195 scp_adsp"
 	depends on COMMON_CLK_MT8195
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-mt2701-aud.c
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-mt2701-aud.c
@@ -55,10 +55,16 @@
 	GATE_DUMMY(CLK_DUMMY, "aud_dummy"),
 	/* AUDIO0 */
 	GATE_AUDIO0(CLK_AUD_AFE, "audio_afe", "aud_intbus_sel", 2),
+	GATE_DUMMY(CLK_AUD_LRCK_DETECT, "audio_lrck_detect_dummy"),
+	GATE_DUMMY(CLK_AUD_I2S, "audio_i2c_dummy"),
+	GATE_DUMMY(CLK_AUD_APLL_TUNER, "audio_apll_tuner_dummy"),
 	GATE_AUDIO0(CLK_AUD_HDMI, "audio_hdmi", "audpll_sel", 20),
 	GATE_AUDIO0(CLK_AUD_SPDF, "audio_spdf", "audpll_sel", 21),
 	GATE_AUDIO0(CLK_AUD_SPDF2, "audio_spdf2", "audpll_sel", 22),
 	GATE_AUDIO0(CLK_AUD_APLL, "audio_apll", "audpll_sel", 23),
+	GATE_DUMMY(CLK_AUD_TML, "audio_tml_dummy"),
+	GATE_DUMMY(CLK_AUD_AHB_IDLE_EXT, "audio_ahb_idle_ext_dummy"),
+	GATE_DUMMY(CLK_AUD_AHB_IDLE_INT, "audio_ahb_idle_int_dummy"),
 	/* AUDIO1 */
 	GATE_AUDIO1(CLK_AUD_I2SIN1, "audio_i2sin1", "aud_mux1_sel", 0),
 	GATE_AUDIO1(CLK_AUD_I2SIN2, "audio_i2sin2", "aud_mux1_sel", 1),
@@ -76,10 +82,12 @@
 	GATE_AUDIO1(CLK_AUD_ASRCI2, "audio_asrci2", "asm_h_sel", 13),
 	GATE_AUDIO1(CLK_AUD_ASRCO1, "audio_asrco1", "asm_h_sel", 14),
 	GATE_AUDIO1(CLK_AUD_ASRCO2, "audio_asrco2", "asm_h_sel", 15),
+	GATE_DUMMY(CLK_AUD_HDMIRX, "audio_hdmirx_dummy"),
 	GATE_AUDIO1(CLK_AUD_INTDIR, "audio_intdir", "intdir_sel", 20),
 	GATE_AUDIO1(CLK_AUD_A1SYS, "audio_a1sys", "aud_mux1_sel", 21),
 	GATE_AUDIO1(CLK_AUD_A2SYS, "audio_a2sys", "aud_mux2_sel", 22),
 	GATE_AUDIO1(CLK_AUD_AFE_CONN, "audio_afe_conn", "aud_mux1_sel", 23),
+	GATE_DUMMY(CLK_AUD_AFE_PCMIF, "audio_afe_pcmif_dummy"),
 	GATE_AUDIO1(CLK_AUD_AFE_MRGIF, "audio_afe_mrgif", "aud_mux1_sel", 25),
 	/* AUDIO2 */
 	GATE_AUDIO2(CLK_AUD_MMIF_UL1, "audio_ul1", "aud_mux1_sel", 0),
@@ -100,6 +108,8 @@
 	GATE_AUDIO2(CLK_AUD_MMIF_AWB2, "audio_awb2", "aud_mux1_sel", 15),
 	GATE_AUDIO2(CLK_AUD_MMIF_DAI, "audio_dai", "aud_mux1_sel", 16),
 	/* AUDIO3 */
+	GATE_DUMMY(CLK_AUD_DMIC1, "audio_dmic1_dummy"),
+	GATE_DUMMY(CLK_AUD_DMIC2, "audio_dmic2_dummy"),
 	GATE_AUDIO3(CLK_AUD_ASRCI3, "audio_asrci3", "asm_h_sel", 2),
 	GATE_AUDIO3(CLK_AUD_ASRCI4, "audio_asrci4", "asm_h_sel", 3),
 	GATE_AUDIO3(CLK_AUD_ASRCI5, "audio_asrci5", "asm_h_sel", 4),
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-mt2701-bdp.c
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-mt2701-bdp.c
@@ -31,6 +31,7 @@
 	GATE_MTK(_id, _name, _parent, &bdp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
 
 static const struct mtk_gate bdp_clks[] = {
+	GATE_DUMMY(CLK_DUMMY, "bdp_dummy"),
 	GATE_BDP0(CLK_BDP_BRG_BA, "brg_baclk", "mm_sel", 0),
 	GATE_BDP0(CLK_BDP_BRG_DRAM, "brg_dram", "mm_sel", 1),
 	GATE_BDP0(CLK_BDP_LARB_DRAM, "larb_dram", "mm_sel", 2),
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-mt2701-img.c
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-mt2701-img.c
@@ -22,6 +22,7 @@
 	GATE_MTK(_id, _name, _parent, &img_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
 
 static const struct mtk_gate img_clks[] = {
+	GATE_DUMMY(CLK_DUMMY, "img_dummy"),
 	GATE_IMG(CLK_IMG_SMI_COMM, "img_smi_comm", "mm_sel", 0),
 	GATE_IMG(CLK_IMG_RESZ, "img_resz", "mm_sel", 1),
 	GATE_IMG(CLK_IMG_JPGDEC_SMI, "img_jpgdec_smi", "mm_sel", 5),
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-mt2701-mm.c
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-mt2701-mm.c
@@ -31,6 +31,7 @@
 	GATE_MTK(_id, _name, _parent, &disp1_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
 
 static const struct mtk_gate mm_clks[] = {
+	GATE_DUMMY(CLK_DUMMY, "mm_dummy"),
 	GATE_DISP0(CLK_MM_SMI_COMMON, "mm_smi_comm", "mm_sel", 0),
 	GATE_DISP0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 1),
 	GATE_DISP0(CLK_MM_CMDQ, "mm_cmdq", "mm_sel", 2),
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-mt2701-vdec.c
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-mt2701-vdec.c
@@ -31,6 +31,7 @@
 	GATE_MTK(_id, _name, _parent, &vdec1_cg_regs, _shift, &mtk_clk_gate_ops_setclr_inv)
 
 static const struct mtk_gate vdec_clks[] = {
+	GATE_DUMMY(CLK_DUMMY, "vdec_dummy"),
 	GATE_VDEC0(CLK_VDEC_CKGEN, "vdec_cken", "vdec_sel", 0),
 	GATE_VDEC1(CLK_VDEC_LARB, "vdec_larb_cken", "mm_sel", 0),
 };
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-mt7622-apmixedsys.c
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-mt7622-apmixedsys.c
@@ -127,7 +127,6 @@
 	of_clk_del_provider(node);
 	mtk_clk_unregister_gates(apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data);
 	mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
-	mtk_free_clk_data(clk_data);
 }
 
 static const struct of_device_id of_match_clk_mt7622_apmixed[] = {
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-mt7981-topckgen.c
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-mt7981-topckgen.c
@@ -357,8 +357,9 @@
 	MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_325M_SEL, "sgm_325m_sel",
 			     sgm_325m_parents, 0x050, 0x054, 0x058, 8, 1, 15,
 			     0x1C0, 21),
-	MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents,
-			     0x050, 0x054, 0x058, 16, 1, 23, 0x1C0, 22),
+	MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents,
+				   0x050, 0x054, 0x058, 16, 1, 23, 0x1C0, 22,
+				   CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
 	MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents,
 			     0x050, 0x054, 0x058, 24, 3, 31, 0x1C0, 23),
 	/* CLK_CFG_6 */
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-mt7988-infracfg.c
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-mt7988-infracfg.c
@@ -152,7 +152,7 @@
 	GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P1, "infra_pcie_peri_ck_26m_ck_p1",
 		    "csw_infra_f26m_sel", 8),
 	GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P2, "infra_pcie_peri_ck_26m_ck_p2",
-		    "csw_infra_f26m_sel", 9),
+		    "infra_pcie_peri_ck_26m_ck_p3", 9),
 	GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P3, "infra_pcie_peri_ck_26m_ck_p3",
 		    "csw_infra_f26m_sel", 10),
 	/* INFRA1 */
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-mt8135-apmixedsys.c
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-mt8135-apmixedsys.c
@@ -59,7 +59,7 @@
 
 	ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
 	if (ret)
-		return ret;
+		goto free_clk_data;
 
 	ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
 	if (ret)
@@ -69,6 +69,8 @@
 
 unregister_plls:
 	mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
+free_clk_data:
+	mtk_free_clk_data(clk_data);
 
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-mt8183-mfgcfg.c
@@ -29,6 +29,7 @@
 static const struct mtk_clk_desc mfg_desc = {
 	.clks = mfg_clks,
 	.num_clks = ARRAY_SIZE(mfg_clks),
+	.need_runtime_pm = true,
 };
 
 static const struct of_device_id of_match_clk_mt8183_mfg[] = {
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-mt8183.c
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-mt8183.c
@@ -790,7 +790,7 @@
 	/* infra_sspm_26m_self is main clock in co-processor, should not be closed in Linux. */
 	GATE_INFRA3_FLAGS(CLK_INFRA_SSPM_26M_SELF, "infra_sspm_26m_self", "f_f26m_ck", 3, CLK_IS_CRITICAL),
 	/* infra_sspm_32k_self is main clock in co-processor, should not be closed in Linux. */
-	GATE_INFRA3_FLAGS(CLK_INFRA_SSPM_32K_SELF, "infra_sspm_32k_self", "f_f26m_ck", 4, CLK_IS_CRITICAL),
+	GATE_INFRA3_FLAGS(CLK_INFRA_SSPM_32K_SELF, "infra_sspm_32k_self", "clk32k", 4, CLK_IS_CRITICAL),
 	GATE_INFRA3(CLK_INFRA_UFS_AXI, "infra_ufs_axi", "axi_sel", 5),
 	GATE_INFRA3(CLK_INFRA_I2C6, "infra_i2c6", "i2c_sel", 6),
 	GATE_INFRA3(CLK_INFRA_AP_MSDC0, "infra_ap_msdc0", "msdc50_hclk_sel", 7),
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-mt8365-mm.c
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-mt8365-mm.c
@@ -53,7 +53,7 @@
 	GATE_MM0(CLK_MM_MM_DSI0, "mm_dsi0", "mm_sel", 17),
 	GATE_MM0(CLK_MM_MM_DISP_RDMA1, "mm_disp_rdma1", "mm_sel", 18),
 	GATE_MM0(CLK_MM_MM_MDP_RDMA1, "mm_mdp_rdma1", "mm_sel", 19),
-	GATE_MM0(CLK_MM_DPI0_DPI0, "mm_dpi0_dpi0", "vpll_dpix", 20),
+	GATE_MM0(CLK_MM_DPI0_DPI0, "mm_dpi0_dpi0", "dpi0_sel", 20),
 	GATE_MM0(CLK_MM_MM_FAKE, "mm_fake", "mm_sel", 21),
 	GATE_MM0(CLK_MM_MM_SMI_COMMON, "mm_smi_common", "mm_sel", 22),
 	GATE_MM0(CLK_MM_MM_SMI_LARB0, "mm_smi_larb0", "mm_sel", 23),
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-mtk.c
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-mtk.c
@@ -13,6 +13,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
 #include "clk-mtk.h"
@@ -494,6 +495,18 @@
 			return IS_ERR(base) ? PTR_ERR(base) : -ENOMEM;
 	}
 
+
+	if (mcd->need_runtime_pm) {
+		devm_pm_runtime_enable(&pdev->dev);
+		/*
+		 * Do a pm_runtime_resume_and_get() to workaround a possible
+		 * deadlock between clk_register() and the genpd framework.
+		 */
+		r = pm_runtime_resume_and_get(&pdev->dev);
+		if (r)
+			return r;
+	}
+
 	/* Calculate how many clk_hw_onecell_data entries to allocate */
 	num_clks = mcd->num_clks + mcd->num_composite_clks;
 	num_clks += mcd->num_fixed_clks + mcd->num_factor_clks;
@@ -574,6 +587,9 @@
 			goto unregister_clks;
 	}
 
+	if (mcd->need_runtime_pm)
+		pm_runtime_put(&pdev->dev);
+
 	return r;
 
 unregister_clks:
@@ -604,6 +620,9 @@
 free_base:
 	if (mcd->shared_io && base)
 		iounmap(base);
+
+	if (mcd->need_runtime_pm)
+		pm_runtime_put(&pdev->dev);
 	return r;
 }
 
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-mtk.h
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-mtk.h
@@ -237,6 +237,8 @@
 
 	int (*clk_notifier_func)(struct device *dev, struct clk *clk);
 	unsigned int mfg_clk_idx;
+
+	bool need_runtime_pm;
 };
 
 int mtk_clk_pdev_probe(struct platform_device *pdev);
--- linux-qcom-6.8.0.orig/drivers/clk/mediatek/clk-pllfh.c
+++ linux-qcom-6.8.0/drivers/clk/mediatek/clk-pllfh.c
@@ -68,7 +68,7 @@
 
 	node = of_find_compatible_node(NULL, NULL, compatible_node);
 	if (!node) {
-		pr_err("cannot find \"%s\"\n", compatible_node);
+		pr_warn("cannot find \"%s\"\n", compatible_node);
 		return;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/clk/meson/axg.c
+++ linux-qcom-6.8.0/drivers/clk/meson/axg.c
@@ -2142,7 +2142,9 @@
 	&axg_vclk_input,
 	&axg_vclk2_input,
 	&axg_vclk_div,
+	&axg_vclk_div1,
 	&axg_vclk2_div,
+	&axg_vclk2_div1,
 	&axg_vclk_div2_en,
 	&axg_vclk_div4_en,
 	&axg_vclk_div6_en,
--- linux-qcom-6.8.0.orig/drivers/clk/meson/s4-peripherals.c
+++ linux-qcom-6.8.0/drivers/clk/meson/s4-peripherals.c
@@ -2978,7 +2978,7 @@
 		.name = "pwm_j_div",
 		.ops = &clk_regmap_divider_ops,
 		.parent_hws = (const struct clk_hw *[]) {
-			&s4_pwm_h_mux.hw
+			&s4_pwm_j_mux.hw
 		},
 		.num_parents = 1,
 		.flags = CLK_SET_RATE_PARENT,
--- linux-qcom-6.8.0.orig/drivers/clk/meson/s4-pll.c
+++ linux-qcom-6.8.0/drivers/clk/meson/s4-pll.c
@@ -38,6 +38,11 @@
 			.shift   = 0,
 			.width   = 8,
 		},
+		.frac = {
+			.reg_off = ANACTRL_FIXPLL_CTRL1,
+			.shift   = 0,
+			.width   = 17,
+		},
 		.n = {
 			.reg_off = ANACTRL_FIXPLL_CTRL0,
 			.shift   = 10,
--- linux-qcom-6.8.0.orig/drivers/clk/mmp/pwr-island.c
+++ linux-qcom-6.8.0/drivers/clk/mmp/pwr-island.c
@@ -106,10 +106,10 @@
 	pm_domain->flags = flags;
 	pm_domain->lock = lock;
 
-	pm_genpd_init(&pm_domain->genpd, NULL, true);
 	pm_domain->genpd.name = name;
 	pm_domain->genpd.power_on = mmp_pm_domain_power_on;
 	pm_domain->genpd.power_off = mmp_pm_domain_power_off;
+	pm_genpd_init(&pm_domain->genpd, NULL, true);
 
 	return &pm_domain->genpd;
 }
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/Kconfig
+++ linux-qcom-6.8.0/drivers/clk/qcom/Kconfig
@@ -20,6 +20,24 @@
 
 if COMMON_CLK_QCOM
 
+config CLK_X1E80100_CAMCC
+	tristate "X1E80100 Camera Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select CLK_X1E80100_GCC
+	help
+	  Support for the camera clock controller on X1E80100 devices.
+	  Say Y if you want to support camera devices and camera functionality.
+
+config CLK_X1E80100_DISPCC
+	tristate "X1E80100 Display Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select CLK_X1E80100_GCC
+	help
+	  Support for the two display clock controllers on Qualcomm
+	  Technologies, Inc. X1E80100 devices.
+	  Say Y if you want to support display devices and functionality such as
+	  splash screen.
+
 config CLK_X1E80100_GCC
 	tristate "X1E80100 Global Clock Controller"
 	depends on ARM64 || COMPILE_TEST
@@ -30,6 +48,15 @@
 	  Say Y if you want to use peripheral devices such as UART, SPI, I2C,
 	  USB, UFS, SD/eMMC, PCIe, etc.
 
+config CLK_X1E80100_GPUCC
+	tristate "X1E80100 Graphics Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select CLK_X1E80100_GCC
+	help
+	  Support for the graphics clock controller on X1E80100 devices.
+	  Say Y if you want to support graphics controller devices and
+	  functionality such as 3D graphics.
+
 config QCOM_A53PLL
 	tristate "MSM8916 A53 PLL"
 	help
@@ -410,6 +437,25 @@
 	  Say Y if you want to support display devices and functionality such as
 	  splash screen.
 
+config QCS_DISPCC_615
+	tristate "QCS615 Display Clock Controller"
+	select QCM_GCC_615
+	help
+	  Support for the display clock controller on Qualcomm Technologies, Inc
+	  QCS615 devices.
+	  Say Y if you want to support display devices and functionality such as
+	  splash screen.
+
+config QCS_CAMCC_615
+	tristate "QCS615 Camera Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select QCS_GCC_615
+	help
+	  Support for the camera clock controller on Qualcomm Technologies, Inc
+	  QCS615 devices.
+	  Say Y if you want to support camera devices and functionality such as
+	  capturing pictures.
+
 config QCS_GCC_404
 	tristate "QCS404 Global Clock Controller"
 	help
@@ -417,6 +463,53 @@
 	  Say Y if you want to use multimedia devices or peripheral
 	  devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc.
 
+config SA_CAMCC_8775P
+	tristate "SA8775P Camera Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select SA_GCC_8775P
+	help
+	  Support for the camera clock controller on Qualcomm Technologies, Inc
+	  SA8775P devices.
+	  Say Y if you want to support camera devices and functionality such as
+	  capturing pictures.
+
+config QCS_GPUCC_615
+	tristate "QCS615 Graphics clock controller"
+	depends on ARM64 || COMPILE_TEST
+	select QCS_GCC_615
+	help
+	  Support for the graphics clock controller on QCS615 devices.
+	  Say Y if you want to support graphics controller devices and
+	  functionality such as 3D graphics.
+
+config QCS_VIDEOCC_615
+	tristate "QCS615 Video Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select QCS_GCC_615
+	help
+	  Support for the video clock controller on QCS615 devices.
+	  Say Y if you want to support video devices and functionality such as
+	  video encode and decode.
+
+config QCS_GCC_8300
+	tristate "QCS8300 Global Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select QCOM_GDSC
+	help
+	  Support for the global clock controller on Qualcomm Technologies, Inc
+	  QCS8300 devices.
+	  Say Y if you want to use peripheral devices such as UART,
+	  SPI, I2C, USB, SD/UFS, PCIe etc.
+
+config QCS_GCC_615
+	tristate "QCS615 Global Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select QCOM_GDSC
+	help
+	  Support for the global clock controller on QCS615 devices.
+	  Say Y if you want to use multimedia devices or peripheral
+	  devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc.
+
 config SC_CAMCC_7180
 	tristate "SC7180 Camera Clock Controller"
 	depends on ARM64 || COMPILE_TEST
@@ -439,6 +532,7 @@
 
 config SC_CAMCC_8280XP
 	tristate "SC8280XP Camera Clock Controller"
+	depends on ARM64 || COMPILE_TEST
 	select SC_GCC_8280XP
 	help
 	  Support for the camera clock controller on Qualcomm Technologies, Inc
@@ -446,6 +540,16 @@
 	  Say Y if you want to support camera devices and functionality such as
 	  capturing pictures.
 
+config SA_DISPCC_8775P
+	tristate "SA8775P Display Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select SA_GCC_8775P
+	help
+	  Support for the two display clock controllers on Qualcomm Technologies, Inc.
+	  SA8775P devices.
+	  Say Y if you want to support display devices and functionality such as
+	  splash screen.
+
 config SC_DISPCC_7180
 	tristate "SC7180 Display Clock Controller"
 	depends on ARM64 || COMPILE_TEST
@@ -777,6 +881,14 @@
 	  Support for the camera clock controller on SM6350 devices.
 	  Say Y if you want to support camera devices and camera functionality.
 
+config SM_CAMCC_7150
+	tristate "SM7150 Camera Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select SM_GCC_7150
+	help
+	  Support for the camera clock controller on SM7150 devices.
+	  Say Y if you want to support camera devices and camera functionality.
+
 config SM_CAMCC_8250
 	tristate "SM8250 Camera Clock Controller"
 	depends on ARM64 || COMPILE_TEST
@@ -821,6 +933,16 @@
 	  Say Y if you want to support display devices and functionality such as
 	  splash screen
 
+config SM_DISPCC_7150
+	tristate "SM7150 Display Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	depends on SM_GCC_7150
+	help
+	  Support for the display clock controller on Qualcomm Technologies, Inc
+	  SM7150 devices.
+	  Say Y if you want to support display devices and functionality such as
+	  splash screen.
+
 config SM_DISPCC_8250
 	tristate "SM8150/SM8250/SM8350 Display Clock Controller"
 	depends on ARM64 || COMPILE_TEST
@@ -936,6 +1058,7 @@
 config SM_GCC_8150
 	tristate "SM8150 Global Clock Controller"
 	depends on ARM64 || COMPILE_TEST
+	select QCOM_GDSC
 	help
 	  Support for the global clock controller on SM8150 devices.
 	  Say Y if you want to use peripheral devices such as UART,
@@ -1069,6 +1192,7 @@
 
 config SM_GPUCC_8650
 	tristate "SM8650 Graphics Clock Controller"
+	depends on ARM64 || COMPILE_TEST
 	select SM_GCC_8650
 	help
 	  Support for the graphics clock controller on SM8650 devices.
@@ -1091,6 +1215,27 @@
 	  Support for the TCSR clock controller on SM8650 devices.
 	  Say Y if you want to use peripheral devices such as SD/UFS.
 
+config SA_VIDEOCC_8775P
+	tristate "SA8775P Video Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select SA_GCC_8775P
+	select QCOM_GDSC
+	help
+	  Support for the video clock controller on Qualcomm Technologies, Inc.
+	  SA8775P devices.
+	  Say Y if you want to support video devices and functionality such as
+	  video encode/decode.
+
+config SM_VIDEOCC_7150
+	tristate "SM7150 Video Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select SM_GCC_7150
+	select QCOM_GDSC
+	help
+	  Support for the video clock controller on SM7150 devices.
+	  Say Y if you want to support video devices and functionality such as
+	  video encode and decode.
+
 config SM_VIDEOCC_8150
 	tristate "SM8150 Video Clock Controller"
 	depends on ARM64 || COMPILE_TEST
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/Makefile
+++ linux-qcom-6.8.0/drivers/clk/qcom/Makefile
@@ -21,7 +21,10 @@
 obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
 obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
 obj-$(CONFIG_CLK_GFM_LPASS_SM8250) += lpass-gfm-sm8250.o
+obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o
+obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o
 obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o
+obj-$(CONFIG_CLK_X1E80100_GPUCC) += gpucc-x1e80100.o
 obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o
 obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o
 obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
@@ -63,7 +66,13 @@
 obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
 obj-$(CONFIG_QCM_GCC_2290) += gcc-qcm2290.o
 obj-$(CONFIG_QCM_DISPCC_2290) += dispcc-qcm2290.o
+obj-$(CONFIG_QCS_DISPCC_615) += dispcc-qcs615.o
+obj-$(CONFIG_QCS_CAMCC_615) += camcc-qcs615.o
 obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o
+obj-$(CONFIG_QCS_GCC_615) += gcc-qcs615.o
+obj-$(CONFIG_QCS_GPUCC_615) += gpucc-qcs615.o
+obj-$(CONFIG_QCS_VIDEOCC_615) += videocc-qcs615.o
+obj-$(CONFIG_QCS_GCC_8300) += gcc-qcs8300.o
 obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o
 obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o
 obj-$(CONFIG_QDU_ECPRICC_1000) += ecpricc-qdu1000.o
@@ -71,11 +80,14 @@
 obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o
 obj-$(CONFIG_SC_CAMCC_7280) += camcc-sc7280.o
 obj-$(CONFIG_SC_CAMCC_8280XP) += camcc-sc8280xp.o
+obj-$(CONFIG_SA_DISPCC_8775P) += dispcc0-sa8775p.o dispcc1-sa8775p.o
 obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o
 obj-$(CONFIG_SC_DISPCC_7280) += dispcc-sc7280.o
 obj-$(CONFIG_SC_DISPCC_8280XP) += dispcc-sc8280xp.o
+obj-$(CONFIG_SA_CAMCC_8775P) += camcc-sa8775p.o
 obj-$(CONFIG_SA_GCC_8775P) += gcc-sa8775p.o
 obj-$(CONFIG_SA_GPUCC_8775P) += gpucc-sa8775p.o
+obj-$(CONFIG_SA_VIDEOCC_8775P) += videocc-sa8775p.o
 obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o
 obj-$(CONFIG_SC_GCC_7280) += gcc-sc7280.o
 obj-$(CONFIG_SC_GCC_8180X) += gcc-sc8180x.o
@@ -103,6 +115,7 @@
 obj-$(CONFIG_SDX_GCC_65) += gcc-sdx65.o
 obj-$(CONFIG_SDX_GCC_75) += gcc-sdx75.o
 obj-$(CONFIG_SM_CAMCC_6350) += camcc-sm6350.o
+obj-$(CONFIG_SM_CAMCC_7150) += camcc-sm7150.o
 obj-$(CONFIG_SM_CAMCC_8250) += camcc-sm8250.o
 obj-$(CONFIG_SM_CAMCC_8450) += camcc-sm8450.o
 obj-$(CONFIG_SM_CAMCC_8550) += camcc-sm8550.o
@@ -110,6 +123,7 @@
 obj-$(CONFIG_SM_DISPCC_6125) += dispcc-sm6125.o
 obj-$(CONFIG_SM_DISPCC_6350) += dispcc-sm6350.o
 obj-$(CONFIG_SM_DISPCC_6375) += dispcc-sm6375.o
+obj-$(CONFIG_SM_DISPCC_7150) += dispcc-sm7150.o
 obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o
 obj-$(CONFIG_SM_DISPCC_8450) += dispcc-sm8450.o
 obj-$(CONFIG_SM_DISPCC_8550) += dispcc-sm8550.o
@@ -138,6 +152,7 @@
 obj-$(CONFIG_SM_GPUCC_8650) += gpucc-sm8650.o
 obj-$(CONFIG_SM_TCSRCC_8550) += tcsrcc-sm8550.o
 obj-$(CONFIG_SM_TCSRCC_8650) += tcsrcc-sm8650.o
+obj-$(CONFIG_SM_VIDEOCC_7150) += videocc-sm7150.o
 obj-$(CONFIG_SM_VIDEOCC_8150) += videocc-sm8150.o
 obj-$(CONFIG_SM_VIDEOCC_8250) += videocc-sm8250.o
 obj-$(CONFIG_SM_VIDEOCC_8350) += videocc-sm8350.o
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/apss-ipq-pll.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/apss-ipq-pll.c
@@ -55,6 +55,29 @@
 	},
 };
 
+static struct clk_alpha_pll ipq_pll_stromer = {
+	.offset = 0x0,
+	/*
+	 * Reuse CLK_ALPHA_PLL_TYPE_STROMER_PLUS register offsets.
+	 * Although this is a bit confusing, but the offset values
+	 * are correct nevertheless.
+	 */
+	.regs = ipq_pll_offsets[CLK_ALPHA_PLL_TYPE_STROMER_PLUS],
+	.flags = SUPPORTS_DYNAMIC_UPDATE,
+	.clkr = {
+		.enable_reg = 0x0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "a53pll",
+			.parent_data = &(const struct clk_parent_data) {
+				.fw_name = "xo",
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_stromer_ops,
+		},
+	},
+};
+
 static struct clk_alpha_pll ipq_pll_stromer_plus = {
 	.offset = 0x0,
 	.regs = ipq_pll_offsets[CLK_ALPHA_PLL_TYPE_STROMER_PLUS],
@@ -73,10 +96,10 @@
 	},
 };
 
+/* 1.008 GHz configuration */
 static const struct alpha_pll_config ipq5018_pll_config = {
-	.l = 0x32,
+	.l = 0x2a,
 	.config_ctl_val = 0x4001075b,
-	.config_ctl_hi_val = 0x304,
 	.main_output_mask = BIT(0),
 	.aux_output_mask = BIT(1),
 	.early_output_mask = BIT(3),
@@ -90,7 +113,6 @@
 static const struct alpha_pll_config ipq5332_pll_config = {
 	.l = 0x2d,
 	.config_ctl_val = 0x4001075b,
-	.config_ctl_hi_val = 0x304,
 	.main_output_mask = BIT(0),
 	.aux_output_mask = BIT(1),
 	.early_output_mask = BIT(3),
@@ -144,8 +166,8 @@
 };
 
 static const struct apss_pll_data ipq5018_pll_data = {
-	.pll_type = CLK_ALPHA_PLL_TYPE_STROMER_PLUS,
-	.pll = &ipq_pll_stromer_plus,
+	.pll_type = CLK_ALPHA_PLL_TYPE_STROMER,
+	.pll = &ipq_pll_stromer,
 	.pll_config = &ipq5018_pll_config,
 };
 
@@ -203,7 +225,8 @@
 
 	if (data->pll_type == CLK_ALPHA_PLL_TYPE_HUAYRA)
 		clk_alpha_pll_configure(data->pll, regmap, data->pll_config);
-	else if (data->pll_type == CLK_ALPHA_PLL_TYPE_STROMER_PLUS)
+	else if (data->pll_type == CLK_ALPHA_PLL_TYPE_STROMER ||
+		 data->pll_type == CLK_ALPHA_PLL_TYPE_STROMER_PLUS)
 		clk_stromer_pll_configure(data->pll, regmap, data->pll_config);
 
 	ret = devm_clk_register_regmap(dev, &data->pll->clkr);
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/apss-ipq6018.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/apss-ipq6018.c
@@ -123,7 +123,7 @@
 	if (!regmap)
 		return -ENODEV;
 
-	ret = qcom_cc_really_probe(pdev, &apss_ipq6018_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &apss_ipq6018_desc, regmap);
 	if (ret)
 		return ret;
 
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/camcc-qcs615.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/camcc-qcs615.c
@@ -0,0 +1,1591 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,qcs615-camcc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_BI_TCXO,
+};
+
+enum {
+	P_BI_TCXO,
+	P_CAM_CC_PLL0_OUT_AUX,
+	P_CAM_CC_PLL1_OUT_AUX,
+	P_CAM_CC_PLL2_OUT_AUX2,
+	P_CAM_CC_PLL2_OUT_EARLY,
+	P_CAM_CC_PLL3_OUT_MAIN,
+};
+
+static const struct pll_vco brammo_vco[] = {
+	{ 500000000, 1250000000, 0 },
+};
+
+static const struct pll_vco spark_vco[] = {
+	{ 1000000000, 2100000000, 0 },
+	{ 750000000, 1500000000, 1 },
+	{ 500000000, 1000000000, 2 },
+	{ 300000000, 500000000, 3 },
+	{ 550000000, 1100000000, 4 },
+};
+
+/* 600MHz configuration VCO - 2 */
+static const struct alpha_pll_config cam_cc_pll0_config = {
+	.l = 0x1f,
+	.alpha_hi = 0x40,
+	.alpha_en_mask = BIT(24),
+	.vco_val = BIT(21),
+	.vco_mask = GENMASK(21, 20),
+	.aux_output_mask = BIT(1),
+	.config_ctl_val = 0x4001055b,
+	.test_ctl_hi_val = 0x1,
+	.test_ctl_hi_mask = 0x1,
+};
+
+static struct clk_alpha_pll cam_cc_pll0 = {
+	.offset = 0x0,
+	.vco_table = spark_vco,
+	.num_vco = ARRAY_SIZE(spark_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_ops,
+		},
+	},
+};
+
+/* 808MHz configuration VCO - 2 */
+static struct alpha_pll_config cam_cc_pll1_config = {
+	.l = 0x2a,
+	.alpha_hi = 0x15,
+	.alpha = 0x55555555,
+	.alpha_en_mask = BIT(24),
+	.vco_val = BIT(21),
+	.vco_mask = GENMASK(21, 20),
+	.aux_output_mask = BIT(1),
+	.config_ctl_val = 0x4001055b,
+	.test_ctl_hi_val = 0x1,
+	.test_ctl_hi_mask = 0x1,
+};
+
+static struct clk_alpha_pll cam_cc_pll1 = {
+	.offset = 0x1000,
+	.vco_table = spark_vco,
+	.num_vco = ARRAY_SIZE(spark_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll1",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_ops,
+		},
+	},
+};
+
+/* 960MHz configuration VCO - 0 */
+static struct alpha_pll_config cam_cc_pll2_config = {
+	.l = 0x32,
+	.vco_val = 0x0,
+	.vco_mask = GENMASK(21, 20),
+	.early_output_mask = BIT(3),
+	.aux2_output_mask = BIT(2),
+	.post_div_val = 0x1 << 8,
+	.post_div_mask = 0x3 << 8,
+	.config_ctl_val = 0x04289,
+	.test_ctl_val = 0x08000000,
+	.test_ctl_mask = 0x08000000,
+};
+
+static struct clk_alpha_pll cam_cc_pll2 = {
+	.offset = 0x2000,
+	.vco_table = brammo_vco,
+	.num_vco = ARRAY_SIZE(brammo_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll2",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_cam_cc_pll2_out_aux2[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll2_out_aux2 = {
+	.offset = 0x2000,
+	.post_div_shift = 8,
+	.post_div_table = post_div_table_cam_cc_pll2_out_aux2,
+	.num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll2_out_aux2),
+	.width = 2,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_pll2_out_aux2",
+		.parent_hws = (const struct clk_hw*[]) {
+			&cam_cc_pll2.clkr.hw,
+		},
+		.num_parents = 1,
+		.ops = &clk_alpha_pll_postdiv_ops,
+	},
+};
+
+/* 1080MHz configuration - VCO - 0 */
+static struct alpha_pll_config cam_cc_pll3_config = {
+	.l = 0x38,
+	.alpha_hi = 0x40,
+	.alpha_en_mask = BIT(24),
+	.vco_val = 0x0,
+	.vco_mask = GENMASK(21, 20),
+	.main_output_mask = BIT(0),
+	.config_ctl_val = 0x4001055b,
+	.test_ctl_hi_val = 0x1,
+	.test_ctl_hi_mask = 0x1,
+};
+
+static struct clk_alpha_pll cam_cc_pll3 = {
+	.offset = 0x3000,
+	.vco_table = spark_vco,
+	.num_vco = ARRAY_SIZE(spark_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll3",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_ops,
+		},
+	},
+};
+
+static const struct parent_map cam_cc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL1_OUT_AUX, 2 },
+	{ P_CAM_CC_PLL0_OUT_AUX, 6 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll1.clkr.hw },
+	{ .hw = &cam_cc_pll0.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL2_OUT_EARLY, 4 },
+	{ P_CAM_CC_PLL3_OUT_MAIN, 5 },
+	{ P_CAM_CC_PLL0_OUT_AUX, 6 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll2.clkr.hw },
+	{ .hw = &cam_cc_pll3.clkr.hw },
+	{ .hw = &cam_cc_pll0.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL1_OUT_AUX, 2 },
+	{ P_CAM_CC_PLL2_OUT_EARLY, 4 },
+	{ P_CAM_CC_PLL3_OUT_MAIN, 5 },
+	{ P_CAM_CC_PLL0_OUT_AUX, 6 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll1.clkr.hw },
+	{ .hw = &cam_cc_pll2.clkr.hw },
+	{ .hw = &cam_cc_pll3.clkr.hw },
+	{ .hw = &cam_cc_pll0.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL2_OUT_AUX2, 1 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll2_out_aux2.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_4[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL3_OUT_MAIN, 5 },
+	{ P_CAM_CC_PLL0_OUT_AUX, 6 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_4[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll3.clkr.hw },
+	{ .hw = &cam_cc_pll0.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_5[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL0_OUT_AUX, 6 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_5[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll0.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_6[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL1_OUT_AUX, 2 },
+	{ P_CAM_CC_PLL3_OUT_MAIN, 5 },
+	{ P_CAM_CC_PLL0_OUT_AUX, 6 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_6[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll1.clkr.hw },
+	{ .hw = &cam_cc_pll3.clkr.hw },
+	{ .hw = &cam_cc_pll0.clkr.hw },
+};
+
+static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = {
+	F(200000000, P_CAM_CC_PLL0_OUT_AUX, 3, 0, 0),
+	F(360000000, P_CAM_CC_PLL3_OUT_MAIN, 3, 0, 0),
+	F(432000000, P_CAM_CC_PLL3_OUT_MAIN, 2.5, 0, 0),
+	F(480000000, P_CAM_CC_PLL2_OUT_EARLY, 2, 0, 0),
+	F(540000000, P_CAM_CC_PLL3_OUT_MAIN, 2, 0, 0),
+	F(600000000, P_CAM_CC_PLL0_OUT_AUX, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_bps_clk_src = {
+	.cmd_rcgr = 0x6010,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_bps_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_bps_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_cci_clk_src[] = {
+	F(37500000, P_CAM_CC_PLL0_OUT_AUX, 16, 0, 0),
+	F(50000000, P_CAM_CC_PLL0_OUT_AUX, 12, 0, 0),
+	F(100000000, P_CAM_CC_PLL0_OUT_AUX, 6, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_cci_clk_src = {
+	.cmd_rcgr = 0xb0d8,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_5,
+	.freq_tbl = ftbl_cam_cc_cci_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_cci_clk_src",
+		.parent_data = cam_cc_parent_data_5,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_5),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = {
+	F(100000000, P_CAM_CC_PLL0_OUT_AUX, 6, 0, 0),
+	F(200000000, P_CAM_CC_PLL0_OUT_AUX, 3, 0, 0),
+	F(269333333, P_CAM_CC_PLL1_OUT_AUX, 3, 0, 0),
+	F(320000000, P_CAM_CC_PLL2_OUT_EARLY, 3, 0, 0),
+	F(384000000, P_CAM_CC_PLL2_OUT_EARLY, 2.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_cphy_rx_clk_src = {
+	.cmd_rcgr = 0x9064,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_2,
+	.freq_tbl = ftbl_cam_cc_cphy_rx_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_cphy_rx_clk_src",
+		.parent_data = cam_cc_parent_data_2,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_2),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_csi0phytimer_clk_src[] = {
+	F(100000000, P_CAM_CC_PLL0_OUT_AUX, 6, 0, 0),
+	F(200000000, P_CAM_CC_PLL0_OUT_AUX, 3, 0, 0),
+	F(269333333, P_CAM_CC_PLL1_OUT_AUX, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = {
+	.cmd_rcgr = 0x5004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csi0phytimer_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = {
+	.cmd_rcgr = 0x5028,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csi1phytimer_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = {
+	.cmd_rcgr = 0x504c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csi2phytimer_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_fast_ahb_clk_src[] = {
+	F(100000000, P_CAM_CC_PLL0_OUT_AUX, 6, 0, 0),
+	F(200000000, P_CAM_CC_PLL0_OUT_AUX, 3, 0, 0),
+	F(300000000, P_CAM_CC_PLL0_OUT_AUX, 2, 0, 0),
+	F(404000000, P_CAM_CC_PLL1_OUT_AUX, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_fast_ahb_clk_src = {
+	.cmd_rcgr = 0x603c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_fast_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_fast_ahb_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_icp_clk_src[] = {
+	F(240000000, P_CAM_CC_PLL0_OUT_AUX, 2.5, 0, 0),
+	F(360000000, P_CAM_CC_PLL3_OUT_MAIN, 3, 0, 0),
+	F(432000000, P_CAM_CC_PLL3_OUT_MAIN, 2.5, 0, 0),
+	F(480000000, P_CAM_CC_PLL2_OUT_EARLY, 2, 0, 0),
+	F(540000000, P_CAM_CC_PLL3_OUT_MAIN, 2, 0, 0),
+	F(600000000, P_CAM_CC_PLL0_OUT_AUX, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_icp_clk_src = {
+	.cmd_rcgr = 0xb088,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_icp_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_icp_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_ife_0_clk_src[] = {
+	F(240000000, P_CAM_CC_PLL0_OUT_AUX, 2.5, 0, 0),
+	F(360000000, P_CAM_CC_PLL3_OUT_MAIN, 3, 0, 0),
+	F(432000000, P_CAM_CC_PLL3_OUT_MAIN, 2.5, 0, 0),
+	F(540000000, P_CAM_CC_PLL3_OUT_MAIN, 2, 0, 0),
+	F(600000000, P_CAM_CC_PLL0_OUT_AUX, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_ife_0_clk_src = {
+	.cmd_rcgr = 0x9010,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_4,
+	.freq_tbl = ftbl_cam_cc_ife_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ife_0_clk_src",
+		.parent_data = cam_cc_parent_data_4,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_4),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_ife_0_csid_clk_src[] = {
+	F(100000000, P_CAM_CC_PLL0_OUT_AUX, 6, 0, 0),
+	F(200000000, P_CAM_CC_PLL0_OUT_AUX, 3, 0, 0),
+	F(320000000, P_CAM_CC_PLL2_OUT_EARLY, 3, 0, 0),
+	F(404000000, P_CAM_CC_PLL1_OUT_AUX, 2, 0, 0),
+	F(480000000, P_CAM_CC_PLL2_OUT_EARLY, 2, 0, 0),
+	F(540000000, P_CAM_CC_PLL3_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_ife_0_csid_clk_src = {
+	.cmd_rcgr = 0x903c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_2,
+	.freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ife_0_csid_clk_src",
+		.parent_data = cam_cc_parent_data_2,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_2),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_ife_1_clk_src = {
+	.cmd_rcgr = 0xa010,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_4,
+	.freq_tbl = ftbl_cam_cc_ife_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ife_1_clk_src",
+		.parent_data = cam_cc_parent_data_4,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_4),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_ife_1_csid_clk_src = {
+	.cmd_rcgr = 0xa034,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_2,
+	.freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ife_1_csid_clk_src",
+		.parent_data = cam_cc_parent_data_2,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_2),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_ife_lite_clk_src = {
+	.cmd_rcgr = 0xb004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_4,
+	.freq_tbl = ftbl_cam_cc_ife_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ife_lite_clk_src",
+		.parent_data = cam_cc_parent_data_4,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_4),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = {
+	.cmd_rcgr = 0xb024,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_2,
+	.freq_tbl = ftbl_cam_cc_ife_0_csid_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ife_lite_csid_clk_src",
+		.parent_data = cam_cc_parent_data_2,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_2),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_ipe_0_clk_src = {
+	.cmd_rcgr = 0x7010,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_icp_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ipe_0_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_jpeg_clk_src[] = {
+	F(66666667, P_CAM_CC_PLL0_OUT_AUX, 9, 0, 0),
+	F(133333333, P_CAM_CC_PLL0_OUT_AUX, 4.5, 0, 0),
+	F(216000000, P_CAM_CC_PLL3_OUT_MAIN, 5, 0, 0),
+	F(320000000, P_CAM_CC_PLL2_OUT_EARLY, 3, 0, 0),
+	F(480000000, P_CAM_CC_PLL2_OUT_EARLY, 2, 0, 0),
+	F(600000000, P_CAM_CC_PLL0_OUT_AUX, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_jpeg_clk_src = {
+	.cmd_rcgr = 0xb04c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_jpeg_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_jpeg_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_lrme_clk_src[] = {
+	F(200000000, P_CAM_CC_PLL0_OUT_AUX, 3, 0, 0),
+	F(216000000, P_CAM_CC_PLL3_OUT_MAIN, 5, 0, 0),
+	F(300000000, P_CAM_CC_PLL0_OUT_AUX, 2, 0, 0),
+	F(404000000, P_CAM_CC_PLL1_OUT_AUX, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_lrme_clk_src = {
+	.cmd_rcgr = 0xb0f8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_6,
+	.freq_tbl = ftbl_cam_cc_lrme_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_lrme_clk_src",
+		.parent_data = cam_cc_parent_data_6,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_6),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_mclk0_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(24000000, P_CAM_CC_PLL2_OUT_AUX2, 10, 1, 2),
+	F(34285714, P_CAM_CC_PLL2_OUT_AUX2, 14, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_mclk0_clk_src = {
+	.cmd_rcgr = 0x4004,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_3,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk0_clk_src",
+		.parent_data = cam_cc_parent_data_3,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_3),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_mclk1_clk_src = {
+	.cmd_rcgr = 0x4024,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_3,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk1_clk_src",
+		.parent_data = cam_cc_parent_data_3,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_3),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_mclk2_clk_src = {
+	.cmd_rcgr = 0x4044,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_3,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk2_clk_src",
+		.parent_data = cam_cc_parent_data_3,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_3),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_mclk3_clk_src = {
+	.cmd_rcgr = 0x4064,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_3,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk3_clk_src",
+		.parent_data = cam_cc_parent_data_3,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_3),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = {
+	F(80000000, P_CAM_CC_PLL0_OUT_AUX, 7.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_slow_ahb_clk_src = {
+	.cmd_rcgr = 0x6058,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_slow_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_slow_ahb_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_branch cam_cc_bps_ahb_clk = {
+	.halt_reg = 0x6070,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6070,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_bps_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_bps_areg_clk = {
+	.halt_reg = 0x6054,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_bps_areg_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_bps_axi_clk = {
+	.halt_reg = 0x6038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_bps_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_bps_clk = {
+	.halt_reg = 0x6028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_bps_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_bps_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_camnoc_axi_clk = {
+	.halt_reg = 0xb124,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb124,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_camnoc_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cci_clk = {
+	.halt_reg = 0xb0f0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb0f0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cci_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cci_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_core_ahb_clk = {
+	.halt_reg = 0xb144,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xb144,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_core_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_ahb_clk = {
+	.halt_reg = 0xb11c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb11c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csi0phytimer_clk = {
+	.halt_reg = 0x501c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x501c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csi0phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csi0phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csi1phytimer_clk = {
+	.halt_reg = 0x5040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x5040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csi1phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csi1phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csi2phytimer_clk = {
+	.halt_reg = 0x5064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x5064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csi2phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csi2phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csiphy0_clk = {
+	.halt_reg = 0x5020,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x5020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csiphy0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csiphy1_clk = {
+	.halt_reg = 0x5044,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x5044,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csiphy1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csiphy2_clk = {
+	.halt_reg = 0x5068,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x5068,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csiphy2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_icp_clk = {
+	.halt_reg = 0xb0a0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb0a0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_icp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_icp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_0_axi_clk = {
+	.halt_reg = 0x9080,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9080,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_0_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_0_clk = {
+	.halt_reg = 0x9028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_0_cphy_rx_clk = {
+	.halt_reg = 0x907c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x907c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_0_cphy_rx_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_0_csid_clk = {
+	.halt_reg = 0x9054,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_0_csid_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_0_csid_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_0_dsp_clk = {
+	.halt_reg = 0x9038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_0_dsp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_1_axi_clk = {
+	.halt_reg = 0xa058,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa058,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_1_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_1_clk = {
+	.halt_reg = 0xa028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_1_cphy_rx_clk = {
+	.halt_reg = 0xa054,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_1_cphy_rx_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_1_csid_clk = {
+	.halt_reg = 0xa04c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa04c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_1_csid_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_1_csid_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_1_dsp_clk = {
+	.halt_reg = 0xa030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_1_dsp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_lite_clk = {
+	.halt_reg = 0xb01c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb01c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_lite_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_lite_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_lite_cphy_rx_clk = {
+	.halt_reg = 0xb044,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb044,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_lite_cphy_rx_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_lite_csid_clk = {
+	.halt_reg = 0xb03c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb03c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_lite_csid_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_lite_csid_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ipe_0_ahb_clk = {
+	.halt_reg = 0x7040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x7040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ipe_0_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ipe_0_areg_clk = {
+	.halt_reg = 0x703c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x703c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ipe_0_areg_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ipe_0_axi_clk = {
+	.halt_reg = 0x7038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x7038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ipe_0_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ipe_0_clk = {
+	.halt_reg = 0x7028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x7028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ipe_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ipe_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_jpeg_clk = {
+	.halt_reg = 0xb064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_jpeg_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_jpeg_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_lrme_clk = {
+	.halt_reg = 0xb110,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb110,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_lrme_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_lrme_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk0_clk = {
+	.halt_reg = 0x401c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x401c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk1_clk = {
+	.halt_reg = 0x403c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x403c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk2_clk = {
+	.halt_reg = 0x405c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x405c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk3_clk = {
+	.halt_reg = 0x407c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x407c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_soc_ahb_clk = {
+	.halt_reg = 0xb140,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb140,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_soc_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_sys_tmr_clk = {
+	.halt_reg = 0xb0a8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb0a8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_sys_tmr_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc titan_top_gdsc = {
+	.gdscr = 0xb134,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "titan_top_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR,
+};
+
+static struct gdsc bps_gdsc = {
+	.gdscr = 0x6004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "bps_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.parent = &titan_top_gdsc.pd,
+	.flags = POLL_CFG_GDSCR,
+};
+
+static struct gdsc ife_0_gdsc = {
+	.gdscr = 0x9004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "ife_0_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.parent = &titan_top_gdsc.pd,
+	.flags = POLL_CFG_GDSCR,
+};
+
+static struct gdsc ife_1_gdsc = {
+	.gdscr = 0xa004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "ife_1_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.parent = &titan_top_gdsc.pd,
+	.flags = POLL_CFG_GDSCR,
+};
+
+static struct gdsc ipe_0_gdsc = {
+	.gdscr = 0x7004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "ipe_0_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.parent = &titan_top_gdsc.pd,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct clk_regmap *cam_cc_qcs615_clocks[] = {
+	[CAM_CC_BPS_AHB_CLK] = &cam_cc_bps_ahb_clk.clkr,
+	[CAM_CC_BPS_AREG_CLK] = &cam_cc_bps_areg_clk.clkr,
+	[CAM_CC_BPS_AXI_CLK] = &cam_cc_bps_axi_clk.clkr,
+	[CAM_CC_BPS_CLK] = &cam_cc_bps_clk.clkr,
+	[CAM_CC_BPS_CLK_SRC] = &cam_cc_bps_clk_src.clkr,
+	[CAM_CC_CAMNOC_AXI_CLK] = &cam_cc_camnoc_axi_clk.clkr,
+	[CAM_CC_CCI_CLK] = &cam_cc_cci_clk.clkr,
+	[CAM_CC_CCI_CLK_SRC] = &cam_cc_cci_clk_src.clkr,
+	[CAM_CC_CORE_AHB_CLK] = &cam_cc_core_ahb_clk.clkr,
+	[CAM_CC_CPAS_AHB_CLK] = &cam_cc_cpas_ahb_clk.clkr,
+	[CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr,
+	[CAM_CC_CSI0PHYTIMER_CLK] = &cam_cc_csi0phytimer_clk.clkr,
+	[CAM_CC_CSI0PHYTIMER_CLK_SRC] = &cam_cc_csi0phytimer_clk_src.clkr,
+	[CAM_CC_CSI1PHYTIMER_CLK] = &cam_cc_csi1phytimer_clk.clkr,
+	[CAM_CC_CSI1PHYTIMER_CLK_SRC] = &cam_cc_csi1phytimer_clk_src.clkr,
+	[CAM_CC_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr,
+	[CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr,
+	[CAM_CC_CSIPHY0_CLK] = &cam_cc_csiphy0_clk.clkr,
+	[CAM_CC_CSIPHY1_CLK] = &cam_cc_csiphy1_clk.clkr,
+	[CAM_CC_CSIPHY2_CLK] = &cam_cc_csiphy2_clk.clkr,
+	[CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr,
+	[CAM_CC_ICP_CLK] = &cam_cc_icp_clk.clkr,
+	[CAM_CC_ICP_CLK_SRC] = &cam_cc_icp_clk_src.clkr,
+	[CAM_CC_IFE_0_AXI_CLK] = &cam_cc_ife_0_axi_clk.clkr,
+	[CAM_CC_IFE_0_CLK] = &cam_cc_ife_0_clk.clkr,
+	[CAM_CC_IFE_0_CLK_SRC] = &cam_cc_ife_0_clk_src.clkr,
+	[CAM_CC_IFE_0_CPHY_RX_CLK] = &cam_cc_ife_0_cphy_rx_clk.clkr,
+	[CAM_CC_IFE_0_CSID_CLK] = &cam_cc_ife_0_csid_clk.clkr,
+	[CAM_CC_IFE_0_CSID_CLK_SRC] = &cam_cc_ife_0_csid_clk_src.clkr,
+	[CAM_CC_IFE_0_DSP_CLK] = &cam_cc_ife_0_dsp_clk.clkr,
+	[CAM_CC_IFE_1_AXI_CLK] = &cam_cc_ife_1_axi_clk.clkr,
+	[CAM_CC_IFE_1_CLK] = &cam_cc_ife_1_clk.clkr,
+	[CAM_CC_IFE_1_CLK_SRC] = &cam_cc_ife_1_clk_src.clkr,
+	[CAM_CC_IFE_1_CPHY_RX_CLK] = &cam_cc_ife_1_cphy_rx_clk.clkr,
+	[CAM_CC_IFE_1_CSID_CLK] = &cam_cc_ife_1_csid_clk.clkr,
+	[CAM_CC_IFE_1_CSID_CLK_SRC] = &cam_cc_ife_1_csid_clk_src.clkr,
+	[CAM_CC_IFE_1_DSP_CLK] = &cam_cc_ife_1_dsp_clk.clkr,
+	[CAM_CC_IFE_LITE_CLK] = &cam_cc_ife_lite_clk.clkr,
+	[CAM_CC_IFE_LITE_CLK_SRC] = &cam_cc_ife_lite_clk_src.clkr,
+	[CAM_CC_IFE_LITE_CPHY_RX_CLK] = &cam_cc_ife_lite_cphy_rx_clk.clkr,
+	[CAM_CC_IFE_LITE_CSID_CLK] = &cam_cc_ife_lite_csid_clk.clkr,
+	[CAM_CC_IFE_LITE_CSID_CLK_SRC] = &cam_cc_ife_lite_csid_clk_src.clkr,
+	[CAM_CC_IPE_0_AHB_CLK] = &cam_cc_ipe_0_ahb_clk.clkr,
+	[CAM_CC_IPE_0_AREG_CLK] = &cam_cc_ipe_0_areg_clk.clkr,
+	[CAM_CC_IPE_0_AXI_CLK] = &cam_cc_ipe_0_axi_clk.clkr,
+	[CAM_CC_IPE_0_CLK] = &cam_cc_ipe_0_clk.clkr,
+	[CAM_CC_IPE_0_CLK_SRC] = &cam_cc_ipe_0_clk_src.clkr,
+	[CAM_CC_JPEG_CLK] = &cam_cc_jpeg_clk.clkr,
+	[CAM_CC_JPEG_CLK_SRC] = &cam_cc_jpeg_clk_src.clkr,
+	[CAM_CC_LRME_CLK] = &cam_cc_lrme_clk.clkr,
+	[CAM_CC_LRME_CLK_SRC] = &cam_cc_lrme_clk_src.clkr,
+	[CAM_CC_MCLK0_CLK] = &cam_cc_mclk0_clk.clkr,
+	[CAM_CC_MCLK0_CLK_SRC] = &cam_cc_mclk0_clk_src.clkr,
+	[CAM_CC_MCLK1_CLK] = &cam_cc_mclk1_clk.clkr,
+	[CAM_CC_MCLK1_CLK_SRC] = &cam_cc_mclk1_clk_src.clkr,
+	[CAM_CC_MCLK2_CLK] = &cam_cc_mclk2_clk.clkr,
+	[CAM_CC_MCLK2_CLK_SRC] = &cam_cc_mclk2_clk_src.clkr,
+	[CAM_CC_MCLK3_CLK] = &cam_cc_mclk3_clk.clkr,
+	[CAM_CC_MCLK3_CLK_SRC] = &cam_cc_mclk3_clk_src.clkr,
+	[CAM_CC_PLL0] = &cam_cc_pll0.clkr,
+	[CAM_CC_PLL1] = &cam_cc_pll1.clkr,
+	[CAM_CC_PLL2] = &cam_cc_pll2.clkr,
+	[CAM_CC_PLL2_OUT_AUX2] = &cam_cc_pll2_out_aux2.clkr,
+	[CAM_CC_PLL3] = &cam_cc_pll3.clkr,
+	[CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr,
+	[CAM_CC_SOC_AHB_CLK] = &cam_cc_soc_ahb_clk.clkr,
+	[CAM_CC_SYS_TMR_CLK] = &cam_cc_sys_tmr_clk.clkr,
+};
+
+static struct gdsc *cam_cc_qcs615_gdscs[] = {
+	[BPS_GDSC] = &bps_gdsc,
+	[IFE_0_GDSC] = &ife_0_gdsc,
+	[IFE_1_GDSC] = &ife_1_gdsc,
+	[IPE_0_GDSC] = &ipe_0_gdsc,
+	[TITAN_TOP_GDSC] = &titan_top_gdsc,
+};
+
+static const struct qcom_reset_map cam_cc_qcs615_resets[] = {
+	[CAM_CC_BPS_BCR] = { 0x6000 },
+	[CAM_CC_CAMNOC_BCR] = { 0xb120 },
+	[CAM_CC_CCI_BCR] = { 0xb0d4 },
+	[CAM_CC_CPAS_BCR] = { 0xb118 },
+	[CAM_CC_CSI0PHY_BCR] = { 0x5000 },
+	[CAM_CC_CSI1PHY_BCR] = { 0x5024 },
+	[CAM_CC_CSI2PHY_BCR] = { 0x5048 },
+	[CAM_CC_ICP_BCR] = { 0xb074 },
+	[CAM_CC_IFE_0_BCR] = { 0x9000 },
+	[CAM_CC_IFE_1_BCR] = { 0xa000 },
+	[CAM_CC_IFE_LITE_BCR] = { 0xb000 },
+	[CAM_CC_IPE_0_BCR] = { 0x7000 },
+	[CAM_CC_JPEG_BCR] = { 0xb048 },
+	[CAM_CC_LRME_BCR] = { 0xb0f4 },
+	[CAM_CC_MCLK0_BCR] = { 0x4000 },
+	[CAM_CC_MCLK1_BCR] = { 0x4020 },
+	[CAM_CC_MCLK2_BCR] = { 0x4040 },
+	[CAM_CC_MCLK3_BCR] = { 0x4060 },
+	[CAM_CC_TITAN_TOP_BCR] = { 0xb130 },
+};
+
+static const struct regmap_config cam_cc_qcs615_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0xd004,
+	.fast_io = true,
+};
+
+static const struct qcom_cc_desc cam_cc_qcs615_desc = {
+	.config = &cam_cc_qcs615_regmap_config,
+	.clks = cam_cc_qcs615_clocks,
+	.num_clks = ARRAY_SIZE(cam_cc_qcs615_clocks),
+	.resets = cam_cc_qcs615_resets,
+	.num_resets = ARRAY_SIZE(cam_cc_qcs615_resets),
+	.gdscs = cam_cc_qcs615_gdscs,
+	.num_gdscs = ARRAY_SIZE(cam_cc_qcs615_gdscs),
+};
+
+static const struct of_device_id cam_cc_qcs615_match_table[] = {
+	{ .compatible = "qcom,qcs615-camcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, cam_cc_qcs615_match_table);
+
+static int cam_cc_qcs615_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+
+	regmap = qcom_cc_map(pdev, &cam_cc_qcs615_desc);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	clk_alpha_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll0_config);
+	clk_alpha_pll_configure(&cam_cc_pll1, regmap, &cam_cc_pll1_config);
+	clk_alpha_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll2_config);
+	clk_alpha_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll3_config);
+
+	return qcom_cc_really_probe(&pdev->dev, &cam_cc_qcs615_desc, regmap);
+}
+
+static struct platform_driver cam_cc_qcs615_driver = {
+	.probe = cam_cc_qcs615_probe,
+	.driver = {
+		.name = "camcc-qcs615",
+		.of_match_table = cam_cc_qcs615_match_table,
+	},
+};
+
+module_platform_driver(cam_cc_qcs615_driver);
+
+MODULE_DESCRIPTION("QTI CAMCC QCS615 Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/camcc-sa8775p.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/camcc-sa8775p.c
@@ -0,0 +1,1967 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,sa8775p-camcc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_IFACE,
+	DT_BI_TCXO,
+	DT_BI_TCXO_AO,
+	DT_SLEEP_CLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_BI_TCXO_AO,
+	P_CAM_CC_PLL0_OUT_EVEN,
+	P_CAM_CC_PLL0_OUT_MAIN,
+	P_CAM_CC_PLL0_OUT_ODD,
+	P_CAM_CC_PLL2_OUT_EVEN,
+	P_CAM_CC_PLL2_OUT_MAIN,
+	P_CAM_CC_PLL3_OUT_EVEN,
+	P_CAM_CC_PLL4_OUT_EVEN,
+	P_CAM_CC_PLL5_OUT_EVEN,
+	P_SLEEP_CLK,
+};
+
+static const struct pll_vco lucid_evo_vco[] = {
+	{ 249600000, 2020000000, 0 },
+};
+
+static const struct pll_vco rivian_evo_vco[] = {
+	{ 864000000, 1056000000, 0 },
+};
+
+static const struct alpha_pll_config cam_cc_pll0_config = {
+	.l = 0x3e,
+	.alpha = 0x8000,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x32aa299c,
+	.user_ctl_val = 0x00008400,
+	.user_ctl_hi_val = 0x00400805,
+};
+
+static struct clk_alpha_pll cam_cc_pll0 = {
+	.offset = 0x0,
+	.vco_table = lucid_evo_vco,
+	.num_vco = ARRAY_SIZE(lucid_evo_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_cam_cc_pll0_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = {
+	.offset = 0x0,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_cam_cc_pll0_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_pll0_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&cam_cc_pll0.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_lucid_evo_ops,
+	},
+};
+
+static const struct clk_div_table post_div_table_cam_cc_pll0_out_odd[] = {
+	{ 0x2, 3 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll0_out_odd = {
+	.offset = 0x0,
+	.post_div_shift = 14,
+	.post_div_table = post_div_table_cam_cc_pll0_out_odd,
+	.num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_odd),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_pll0_out_odd",
+		.parent_hws = (const struct clk_hw*[]) {
+			&cam_cc_pll0.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_lucid_evo_ops,
+	},
+};
+
+static const struct alpha_pll_config cam_cc_pll2_config = {
+	.l = 0x32,
+	.alpha = 0x0,
+	.config_ctl_val = 0x90008820,
+	.config_ctl_hi_val = 0x00890263,
+	.config_ctl_hi1_val = 0x00000247,
+	.user_ctl_val = 0x00000000,
+	.user_ctl_hi_val = 0x00400000,
+};
+
+static struct clk_alpha_pll cam_cc_pll2 = {
+	.offset = 0x1000,
+	.vco_table = rivian_evo_vco,
+	.num_vco = ARRAY_SIZE(rivian_evo_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_EVO],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll2",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_rivian_evo_ops,
+		},
+	},
+};
+
+static const struct alpha_pll_config cam_cc_pll3_config = {
+	.l = 0x32,
+	.alpha = 0x0,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x32aa299c,
+	.user_ctl_val = 0x00000400,
+	.user_ctl_hi_val = 0x00400805,
+};
+
+static struct clk_alpha_pll cam_cc_pll3 = {
+	.offset = 0x2000,
+	.vco_table = lucid_evo_vco,
+	.num_vco = ARRAY_SIZE(lucid_evo_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll3",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_cam_cc_pll3_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll3_out_even = {
+	.offset = 0x2000,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_cam_cc_pll3_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll3_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_pll3_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&cam_cc_pll3.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_lucid_evo_ops,
+	},
+};
+
+static const struct alpha_pll_config cam_cc_pll4_config = {
+	.l = 0x32,
+	.alpha = 0x0,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x32aa299c,
+	.user_ctl_val = 0x00000400,
+	.user_ctl_hi_val = 0x00400805,
+};
+
+static struct clk_alpha_pll cam_cc_pll4 = {
+	.offset = 0x3000,
+	.vco_table = lucid_evo_vco,
+	.num_vco = ARRAY_SIZE(lucid_evo_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll4",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_cam_cc_pll4_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll4_out_even = {
+	.offset = 0x3000,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_cam_cc_pll4_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll4_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_pll4_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&cam_cc_pll4.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_lucid_evo_ops,
+	},
+};
+
+static const struct alpha_pll_config cam_cc_pll5_config = {
+	.l = 0x32,
+	.alpha = 0x0,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x32aa299c,
+	.user_ctl_val = 0x00000400,
+	.user_ctl_hi_val = 0x00400805,
+};
+
+static struct clk_alpha_pll cam_cc_pll5 = {
+	.offset = 0x4000,
+	.vco_table = lucid_evo_vco,
+	.num_vco = ARRAY_SIZE(lucid_evo_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll5",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_cam_cc_pll5_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll5_out_even = {
+	.offset = 0x4000,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_cam_cc_pll5_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll5_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_pll5_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&cam_cc_pll5.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_lucid_evo_ops,
+	},
+};
+
+static const struct parent_map cam_cc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL0_OUT_MAIN, 1 },
+	{ P_CAM_CC_PLL0_OUT_EVEN, 2 },
+	{ P_CAM_CC_PLL0_OUT_ODD, 3 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll0.clkr.hw },
+	{ .hw = &cam_cc_pll0_out_even.clkr.hw },
+	{ .hw = &cam_cc_pll0_out_odd.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL2_OUT_EVEN, 3 },
+	{ P_CAM_CC_PLL2_OUT_MAIN, 5 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll2.clkr.hw },
+	{ .hw = &cam_cc_pll2.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL4_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll4_out_even.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL5_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll5_out_even.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_4[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL3_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_4[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll3_out_even.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_5[] = {
+	{ P_SLEEP_CLK, 0 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_5[] = {
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map cam_cc_parent_map_6_ao[] = {
+	{ P_BI_TCXO_AO, 0 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_6_ao[] = {
+	{ .index = DT_BI_TCXO_AO },
+};
+
+static const struct freq_tbl ftbl_cam_cc_camnoc_axi_clk_src[] = {
+	F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_camnoc_axi_clk_src = {
+	.cmd_rcgr = 0x13170,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_camnoc_axi_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_camnoc_axi_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_cci_0_clk_src[] = {
+	F(37500000, P_CAM_CC_PLL0_OUT_MAIN, 16, 1, 2),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_cci_0_clk_src = {
+	.cmd_rcgr = 0x130a0,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_cci_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_cci_0_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_cci_1_clk_src = {
+	.cmd_rcgr = 0x130bc,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_cci_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_cci_1_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_cci_2_clk_src = {
+	.cmd_rcgr = 0x130d8,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_cci_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_cci_2_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_cci_3_clk_src = {
+	.cmd_rcgr = 0x130f4,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_cci_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_cci_3_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = {
+	F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_cphy_rx_clk_src = {
+	.cmd_rcgr = 0x11034,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_cphy_rx_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_cphy_rx_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = {
+	.cmd_rcgr = 0x15074,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_cphy_rx_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csi0phytimer_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = {
+	.cmd_rcgr = 0x15098,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_cphy_rx_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csi1phytimer_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = {
+	.cmd_rcgr = 0x150b8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_cphy_rx_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csi2phytimer_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = {
+	.cmd_rcgr = 0x150d8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_cphy_rx_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csi3phytimer_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_csid_clk_src = {
+	.cmd_rcgr = 0x13150,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_cphy_rx_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csid_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_fast_ahb_clk_src[] = {
+	F(300000000, P_CAM_CC_PLL0_OUT_MAIN, 4, 0, 0),
+	F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_fast_ahb_clk_src = {
+	.cmd_rcgr = 0x13120,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_fast_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_fast_ahb_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_icp_clk_src[] = {
+	F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
+	F(600000000, P_CAM_CC_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_icp_clk_src = {
+	.cmd_rcgr = 0x1307c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_icp_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_icp_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_ife_0_clk_src[] = {
+	F(480000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0),
+	F(600000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_ife_0_clk_src = {
+	.cmd_rcgr = 0x11004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_2,
+	.freq_tbl = ftbl_cam_cc_ife_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ife_0_clk_src",
+		.parent_data = cam_cc_parent_data_2,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_ife_1_clk_src[] = {
+	F(480000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0),
+	F(600000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_ife_1_clk_src = {
+	.cmd_rcgr = 0x12004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_3,
+	.freq_tbl = ftbl_cam_cc_ife_1_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ife_1_clk_src",
+		.parent_data = cam_cc_parent_data_3,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_ife_lite_clk_src[] = {
+	F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_ife_lite_clk_src = {
+	.cmd_rcgr = 0x13000,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_ife_lite_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ife_lite_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = {
+	.cmd_rcgr = 0x13020,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_cphy_rx_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ife_lite_csid_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_ipe_clk_src[] = {
+	F(480000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0),
+	F(600000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_ipe_clk_src = {
+	.cmd_rcgr = 0x10004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_4,
+	.freq_tbl = ftbl_cam_cc_ipe_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ipe_clk_src",
+		.parent_data = cam_cc_parent_data_4,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_mclk0_clk_src[] = {
+	F(19200000, P_CAM_CC_PLL2_OUT_MAIN, 1, 1, 50),
+	F(24000000, P_CAM_CC_PLL2_OUT_MAIN, 10, 1, 4),
+	F(64000000, P_CAM_CC_PLL2_OUT_MAIN, 15, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_mclk0_clk_src = {
+	.cmd_rcgr = 0x15004,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk0_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_mclk1_clk_src = {
+	.cmd_rcgr = 0x15020,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk1_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_mclk2_clk_src = {
+	.cmd_rcgr = 0x1503c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk2_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_mclk3_clk_src = {
+	.cmd_rcgr = 0x15058,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk3_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_sleep_clk_src[] = {
+	F(32000, P_SLEEP_CLK, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_sleep_clk_src = {
+	.cmd_rcgr = 0x131f0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_5,
+	.freq_tbl = ftbl_cam_cc_sleep_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_sleep_clk_src",
+		.parent_data = cam_cc_parent_data_5,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_5),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = {
+	F(80000000, P_CAM_CC_PLL0_OUT_EVEN, 7.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_slow_ahb_clk_src = {
+	.cmd_rcgr = 0x13138,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_slow_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_slow_ahb_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_xo_clk_src[] = {
+	F(19200000, P_BI_TCXO_AO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_xo_clk_src = {
+	.cmd_rcgr = 0x131d4,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_6_ao,
+	.freq_tbl = ftbl_cam_cc_xo_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_xo_clk_src",
+		.parent_data = cam_cc_parent_data_6_ao,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_6_ao),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_branch cam_cc_camnoc_axi_clk = {
+	.halt_reg = 0x13188,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13188,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_camnoc_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_camnoc_axi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_camnoc_dcd_xo_clk = {
+	.halt_reg = 0x13190,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13190,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_camnoc_dcd_xo_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_qdss_debug_xo_clk = {
+	.halt_reg = 0x131b8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x131b8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_qdss_debug_xo_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cci_0_clk = {
+	.halt_reg = 0x130b8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x130b8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cci_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cci_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cci_1_clk = {
+	.halt_reg = 0x130d4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x130d4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cci_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cci_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cci_2_clk = {
+	.halt_reg = 0x130f0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x130f0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cci_2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cci_2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cci_3_clk = {
+	.halt_reg = 0x1310c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1310c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cci_3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cci_3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_core_ahb_clk = {
+	.halt_reg = 0x131d0,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x131d0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_core_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_ahb_clk = {
+	.halt_reg = 0x13110,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13110,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_fast_ahb_clk = {
+	.halt_reg = 0x13118,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13118,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_fast_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_ife_0_clk = {
+	.halt_reg = 0x11024,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x11024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_ife_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_ife_1_clk = {
+	.halt_reg = 0x12024,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x12024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_ife_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_ife_lite_clk = {
+	.halt_reg = 0x1301c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1301c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_ife_lite_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_lite_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_ipe_clk = {
+	.halt_reg = 0x10024,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x10024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_ipe_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ipe_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_sfe_lite_0_clk = {
+	.halt_reg = 0x13050,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13050,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_sfe_lite_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_sfe_lite_1_clk = {
+	.halt_reg = 0x13068,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13068,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_sfe_lite_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csi0phytimer_clk = {
+	.halt_reg = 0x1508c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1508c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csi0phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csi0phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csi1phytimer_clk = {
+	.halt_reg = 0x150b0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x150b0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csi1phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csi1phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csi2phytimer_clk = {
+	.halt_reg = 0x150d0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x150d0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csi2phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csi2phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csi3phytimer_clk = {
+	.halt_reg = 0x150f0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x150f0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csi3phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csi3phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csid_clk = {
+	.halt_reg = 0x13168,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13168,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csid_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csid_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csid_csiphy_rx_clk = {
+	.halt_reg = 0x15094,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15094,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csid_csiphy_rx_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csiphy0_clk = {
+	.halt_reg = 0x15090,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15090,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csiphy0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csiphy1_clk = {
+	.halt_reg = 0x150b4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x150b4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csiphy1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csiphy2_clk = {
+	.halt_reg = 0x150d4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x150d4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csiphy2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csiphy3_clk = {
+	.halt_reg = 0x150f4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x150f4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csiphy3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_icp_ahb_clk = {
+	.halt_reg = 0x1309c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1309c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_icp_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_icp_clk = {
+	.halt_reg = 0x13094,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13094,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_icp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_icp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_0_clk = {
+	.halt_reg = 0x1101c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1101c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_0_fast_ahb_clk = {
+	.halt_reg = 0x11030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x11030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_0_fast_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_1_clk = {
+	.halt_reg = 0x1201c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1201c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_1_fast_ahb_clk = {
+	.halt_reg = 0x12030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x12030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_1_fast_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_lite_ahb_clk = {
+	.halt_reg = 0x13044,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13044,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_lite_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_lite_clk = {
+	.halt_reg = 0x13018,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_lite_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_lite_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_lite_cphy_rx_clk = {
+	.halt_reg = 0x13040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_lite_cphy_rx_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_lite_csid_clk = {
+	.halt_reg = 0x13038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_lite_csid_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_lite_csid_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ipe_ahb_clk = {
+	.halt_reg = 0x10030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x10030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ipe_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ipe_clk = {
+	.halt_reg = 0x1001c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1001c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ipe_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ipe_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ipe_fast_ahb_clk = {
+	.halt_reg = 0x10034,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x10034,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ipe_fast_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk0_clk = {
+	.halt_reg = 0x1501c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1501c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk1_clk = {
+	.halt_reg = 0x15038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk2_clk = {
+	.halt_reg = 0x15054,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk3_clk = {
+	.halt_reg = 0x15070,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15070,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_sfe_lite_0_clk = {
+	.halt_reg = 0x1304c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1304c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_sfe_lite_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_sfe_lite_0_fast_ahb_clk = {
+	.halt_reg = 0x1305c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1305c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_sfe_lite_0_fast_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_sfe_lite_1_clk = {
+	.halt_reg = 0x13064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_sfe_lite_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_sfe_lite_1_fast_ahb_clk = {
+	.halt_reg = 0x13074,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13074,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_sfe_lite_1_fast_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_sm_obs_clk = {
+	.halt_reg = 0x1510c,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x1510c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_sm_obs_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_titan_top_accu_shift_clk = {
+	.halt_reg = 0x131f0,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x131f0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_titan_top_accu_shift_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc cam_cc_titan_top_gdsc = {
+	.gdscr = 0x131bc,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "cam_cc_titan_top_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct clk_regmap *cam_cc_sa8775p_clocks[] = {
+	[CAM_CC_CAMNOC_AXI_CLK] = &cam_cc_camnoc_axi_clk.clkr,
+	[CAM_CC_CAMNOC_AXI_CLK_SRC] = &cam_cc_camnoc_axi_clk_src.clkr,
+	[CAM_CC_CAMNOC_DCD_XO_CLK] = &cam_cc_camnoc_dcd_xo_clk.clkr,
+	[CAM_CC_CCI_0_CLK] = &cam_cc_cci_0_clk.clkr,
+	[CAM_CC_CCI_0_CLK_SRC] = &cam_cc_cci_0_clk_src.clkr,
+	[CAM_CC_CCI_1_CLK] = &cam_cc_cci_1_clk.clkr,
+	[CAM_CC_CCI_1_CLK_SRC] = &cam_cc_cci_1_clk_src.clkr,
+	[CAM_CC_CCI_2_CLK] = &cam_cc_cci_2_clk.clkr,
+	[CAM_CC_CCI_2_CLK_SRC] = &cam_cc_cci_2_clk_src.clkr,
+	[CAM_CC_CCI_3_CLK] = &cam_cc_cci_3_clk.clkr,
+	[CAM_CC_CCI_3_CLK_SRC] = &cam_cc_cci_3_clk_src.clkr,
+	[CAM_CC_CORE_AHB_CLK] = &cam_cc_core_ahb_clk.clkr,
+	[CAM_CC_CPAS_AHB_CLK] = &cam_cc_cpas_ahb_clk.clkr,
+	[CAM_CC_CPAS_FAST_AHB_CLK] = &cam_cc_cpas_fast_ahb_clk.clkr,
+	[CAM_CC_CPAS_IFE_0_CLK] = &cam_cc_cpas_ife_0_clk.clkr,
+	[CAM_CC_CPAS_IFE_1_CLK] = &cam_cc_cpas_ife_1_clk.clkr,
+	[CAM_CC_CPAS_IFE_LITE_CLK] = &cam_cc_cpas_ife_lite_clk.clkr,
+	[CAM_CC_CPAS_IPE_CLK] = &cam_cc_cpas_ipe_clk.clkr,
+	[CAM_CC_CPAS_SFE_LITE_0_CLK] = &cam_cc_cpas_sfe_lite_0_clk.clkr,
+	[CAM_CC_CPAS_SFE_LITE_1_CLK] = &cam_cc_cpas_sfe_lite_1_clk.clkr,
+	[CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr,
+	[CAM_CC_CSI0PHYTIMER_CLK] = &cam_cc_csi0phytimer_clk.clkr,
+	[CAM_CC_CSI0PHYTIMER_CLK_SRC] = &cam_cc_csi0phytimer_clk_src.clkr,
+	[CAM_CC_CSI1PHYTIMER_CLK] = &cam_cc_csi1phytimer_clk.clkr,
+	[CAM_CC_CSI1PHYTIMER_CLK_SRC] = &cam_cc_csi1phytimer_clk_src.clkr,
+	[CAM_CC_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr,
+	[CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr,
+	[CAM_CC_CSI3PHYTIMER_CLK] = &cam_cc_csi3phytimer_clk.clkr,
+	[CAM_CC_CSI3PHYTIMER_CLK_SRC] = &cam_cc_csi3phytimer_clk_src.clkr,
+	[CAM_CC_CSID_CLK] = &cam_cc_csid_clk.clkr,
+	[CAM_CC_CSID_CLK_SRC] = &cam_cc_csid_clk_src.clkr,
+	[CAM_CC_CSID_CSIPHY_RX_CLK] = &cam_cc_csid_csiphy_rx_clk.clkr,
+	[CAM_CC_CSIPHY0_CLK] = &cam_cc_csiphy0_clk.clkr,
+	[CAM_CC_CSIPHY1_CLK] = &cam_cc_csiphy1_clk.clkr,
+	[CAM_CC_CSIPHY2_CLK] = &cam_cc_csiphy2_clk.clkr,
+	[CAM_CC_CSIPHY3_CLK] = &cam_cc_csiphy3_clk.clkr,
+	[CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr,
+	[CAM_CC_ICP_AHB_CLK] = &cam_cc_icp_ahb_clk.clkr,
+	[CAM_CC_ICP_CLK] = &cam_cc_icp_clk.clkr,
+	[CAM_CC_ICP_CLK_SRC] = &cam_cc_icp_clk_src.clkr,
+	[CAM_CC_IFE_0_CLK] = &cam_cc_ife_0_clk.clkr,
+	[CAM_CC_IFE_0_CLK_SRC] = &cam_cc_ife_0_clk_src.clkr,
+	[CAM_CC_IFE_0_FAST_AHB_CLK] = &cam_cc_ife_0_fast_ahb_clk.clkr,
+	[CAM_CC_IFE_1_CLK] = &cam_cc_ife_1_clk.clkr,
+	[CAM_CC_IFE_1_CLK_SRC] = &cam_cc_ife_1_clk_src.clkr,
+	[CAM_CC_IFE_1_FAST_AHB_CLK] = &cam_cc_ife_1_fast_ahb_clk.clkr,
+	[CAM_CC_IFE_LITE_AHB_CLK] = &cam_cc_ife_lite_ahb_clk.clkr,
+	[CAM_CC_IFE_LITE_CLK] = &cam_cc_ife_lite_clk.clkr,
+	[CAM_CC_IFE_LITE_CLK_SRC] = &cam_cc_ife_lite_clk_src.clkr,
+	[CAM_CC_IFE_LITE_CPHY_RX_CLK] = &cam_cc_ife_lite_cphy_rx_clk.clkr,
+	[CAM_CC_IFE_LITE_CSID_CLK] = &cam_cc_ife_lite_csid_clk.clkr,
+	[CAM_CC_IFE_LITE_CSID_CLK_SRC] = &cam_cc_ife_lite_csid_clk_src.clkr,
+	[CAM_CC_IPE_AHB_CLK] = &cam_cc_ipe_ahb_clk.clkr,
+	[CAM_CC_IPE_CLK] = &cam_cc_ipe_clk.clkr,
+	[CAM_CC_IPE_CLK_SRC] = &cam_cc_ipe_clk_src.clkr,
+	[CAM_CC_IPE_FAST_AHB_CLK] = &cam_cc_ipe_fast_ahb_clk.clkr,
+	[CAM_CC_MCLK0_CLK] = &cam_cc_mclk0_clk.clkr,
+	[CAM_CC_MCLK0_CLK_SRC] = &cam_cc_mclk0_clk_src.clkr,
+	[CAM_CC_MCLK1_CLK] = &cam_cc_mclk1_clk.clkr,
+	[CAM_CC_MCLK1_CLK_SRC] = &cam_cc_mclk1_clk_src.clkr,
+	[CAM_CC_MCLK2_CLK] = &cam_cc_mclk2_clk.clkr,
+	[CAM_CC_MCLK2_CLK_SRC] = &cam_cc_mclk2_clk_src.clkr,
+	[CAM_CC_MCLK3_CLK] = &cam_cc_mclk3_clk.clkr,
+	[CAM_CC_MCLK3_CLK_SRC] = &cam_cc_mclk3_clk_src.clkr,
+	[CAM_CC_PLL0] = &cam_cc_pll0.clkr,
+	[CAM_CC_PLL0_OUT_EVEN] = &cam_cc_pll0_out_even.clkr,
+	[CAM_CC_PLL0_OUT_ODD] = &cam_cc_pll0_out_odd.clkr,
+	[CAM_CC_PLL2] = &cam_cc_pll2.clkr,
+	[CAM_CC_PLL3] = &cam_cc_pll3.clkr,
+	[CAM_CC_PLL3_OUT_EVEN] = &cam_cc_pll3_out_even.clkr,
+	[CAM_CC_PLL4] = &cam_cc_pll4.clkr,
+	[CAM_CC_PLL4_OUT_EVEN] = &cam_cc_pll4_out_even.clkr,
+	[CAM_CC_PLL5] = &cam_cc_pll5.clkr,
+	[CAM_CC_PLL5_OUT_EVEN] = &cam_cc_pll5_out_even.clkr,
+	[CAM_CC_SFE_LITE_0_CLK] = &cam_cc_sfe_lite_0_clk.clkr,
+	[CAM_CC_SFE_LITE_0_FAST_AHB_CLK] = &cam_cc_sfe_lite_0_fast_ahb_clk.clkr,
+	[CAM_CC_SFE_LITE_1_CLK] = &cam_cc_sfe_lite_1_clk.clkr,
+	[CAM_CC_SFE_LITE_1_FAST_AHB_CLK] = &cam_cc_sfe_lite_1_fast_ahb_clk.clkr,
+	[CAM_CC_SLEEP_CLK_SRC] = &cam_cc_sleep_clk_src.clkr,
+	[CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr,
+	[CAM_CC_SM_OBS_CLK] = &cam_cc_sm_obs_clk.clkr,
+	[CAM_CC_TITAN_TOP_ACCU_SHIFT_CLK] = NULL,
+	[CAM_CC_XO_CLK_SRC] = &cam_cc_xo_clk_src.clkr,
+	[CAM_CC_QDSS_DEBUG_XO_CLK] = &cam_cc_qdss_debug_xo_clk.clkr,
+};
+
+static struct gdsc *cam_cc_sa8775p_gdscs[] = {
+	[CAM_CC_TITAN_TOP_GDSC] = &cam_cc_titan_top_gdsc,
+};
+
+static const struct qcom_reset_map cam_cc_sa8775p_resets[] = {
+	[CAM_CC_ICP_BCR] = { 0x13078 },
+	[CAM_CC_IFE_0_BCR] = { 0x11000 },
+	[CAM_CC_IFE_1_BCR] = { 0x12000 },
+	[CAM_CC_IPE_0_BCR] = { 0x10000 },
+	[CAM_CC_SFE_LITE_0_BCR] = { 0x13048 },
+	[CAM_CC_SFE_LITE_1_BCR] = { 0x13060 },
+};
+
+static const struct regmap_config cam_cc_sa8775p_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x16218,
+	.fast_io = true,
+};
+
+static struct qcom_cc_desc cam_cc_sa8775p_desc = {
+	.config = &cam_cc_sa8775p_regmap_config,
+	.clks = cam_cc_sa8775p_clocks,
+	.num_clks = ARRAY_SIZE(cam_cc_sa8775p_clocks),
+	.resets = cam_cc_sa8775p_resets,
+	.num_resets = ARRAY_SIZE(cam_cc_sa8775p_resets),
+	.gdscs = cam_cc_sa8775p_gdscs,
+	.num_gdscs = ARRAY_SIZE(cam_cc_sa8775p_gdscs),
+};
+
+static const struct of_device_id cam_cc_sa8775p_match_table[] = {
+	{ .compatible = "qcom,qcs8300-camcc" },
+	{ .compatible = "qcom,sa8775p-camcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, cam_cc_sa8775p_match_table);
+
+static int cam_cc_sa8775p_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+	int ret;
+
+	ret = qcom_cc_attach_pds(&pdev->dev, &cam_cc_sa8775p_desc);
+	if (ret)
+		return ret;
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret)
+		return ret;
+
+	regmap = qcom_cc_map(pdev, &cam_cc_sa8775p_desc);
+	if (IS_ERR(regmap)) {
+		pm_runtime_put(&pdev->dev);
+		return PTR_ERR(regmap);
+	}
+
+	clk_lucid_evo_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll0_config);
+	clk_rivian_evo_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll2_config);
+	clk_lucid_evo_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll3_config);
+	clk_lucid_evo_pll_configure(&cam_cc_pll4, regmap, &cam_cc_pll4_config);
+	clk_lucid_evo_pll_configure(&cam_cc_pll5, regmap, &cam_cc_pll5_config);
+
+	if (of_device_is_compatible(pdev->dev.of_node, "qcom,qcs8300-camcc")) {
+		cam_cc_camnoc_axi_clk_src.cmd_rcgr = 0x13154;
+		cam_cc_camnoc_axi_clk.halt_reg = 0x1316c;
+		cam_cc_camnoc_axi_clk.clkr.enable_reg = 0x1316c;
+		cam_cc_camnoc_dcd_xo_clk.halt_reg = 0x13174;
+		cam_cc_camnoc_dcd_xo_clk.clkr.enable_reg = 0x13174;
+
+		cam_cc_csi0phytimer_clk_src.cmd_rcgr = 0x15054;
+		cam_cc_csi1phytimer_clk_src.cmd_rcgr = 0x15078;
+		cam_cc_csi2phytimer_clk_src.cmd_rcgr = 0x15098;
+		cam_cc_csid_clk_src.cmd_rcgr = 0x13134;
+
+		cam_cc_mclk0_clk_src.cmd_rcgr = 0x15000;
+		cam_cc_mclk1_clk_src.cmd_rcgr = 0x1501c;
+		cam_cc_mclk2_clk_src.cmd_rcgr = 0x15038;
+
+		cam_cc_fast_ahb_clk_src.cmd_rcgr = 0x13104;
+		cam_cc_slow_ahb_clk_src.cmd_rcgr = 0x1311c;
+		cam_cc_xo_clk_src.cmd_rcgr = 0x131b8;
+		cam_cc_sleep_clk_src.cmd_rcgr = 0x131d4;
+
+		cam_cc_core_ahb_clk.halt_reg = 0x131b4;
+		cam_cc_core_ahb_clk.clkr.enable_reg = 0x131b4;
+
+		cam_cc_cpas_ahb_clk.halt_reg = 0x130f4;
+		cam_cc_cpas_ahb_clk.clkr.enable_reg = 0x130f4;
+		cam_cc_cpas_fast_ahb_clk.halt_reg = 0x130fc;
+		cam_cc_cpas_fast_ahb_clk.clkr.enable_reg = 0x130fc;
+
+		cam_cc_csi0phytimer_clk.halt_reg = 0x1506c;
+		cam_cc_csi0phytimer_clk.clkr.enable_reg = 0x1506c;
+		cam_cc_csi1phytimer_clk.halt_reg = 0x15090;
+		cam_cc_csi1phytimer_clk.clkr.enable_reg = 0x15090;
+		cam_cc_csi2phytimer_clk.halt_reg = 0x150b0;
+		cam_cc_csi2phytimer_clk.clkr.enable_reg = 0x150b0;
+		cam_cc_csid_clk.halt_reg = 0x1314c;
+		cam_cc_csid_clk.clkr.enable_reg = 0x1314c;
+		cam_cc_csid_csiphy_rx_clk.halt_reg = 0x15074;
+		cam_cc_csid_csiphy_rx_clk.clkr.enable_reg = 0x15074;
+		cam_cc_csiphy0_clk.halt_reg = 0x15070;
+		cam_cc_csiphy0_clk.clkr.enable_reg = 0x15070;
+		cam_cc_csiphy1_clk.halt_reg = 0x15094;
+		cam_cc_csiphy1_clk.clkr.enable_reg = 0x15094;
+		cam_cc_csiphy2_clk.halt_reg = 0x150b4;
+		cam_cc_csiphy2_clk.clkr.enable_reg = 0x150b4;
+
+		cam_cc_mclk0_clk.halt_reg = 0x15018;
+		cam_cc_mclk0_clk.clkr.enable_reg = 0x15018;
+		cam_cc_mclk1_clk.halt_reg = 0x15034;
+		cam_cc_mclk1_clk.clkr.enable_reg = 0x15034;
+		cam_cc_mclk2_clk.halt_reg = 0x15050;
+		cam_cc_mclk2_clk.clkr.enable_reg = 0x15050;
+		cam_cc_qdss_debug_xo_clk.halt_reg = 0x1319c;
+		cam_cc_qdss_debug_xo_clk.clkr.enable_reg = 0x1319c;
+
+		cam_cc_titan_top_gdsc.gdscr = 0x131a0;
+
+		cam_cc_sa8775p_clocks[CAM_CC_CCI_3_CLK] = NULL;
+		cam_cc_sa8775p_clocks[CAM_CC_CCI_3_CLK_SRC] = NULL;
+		cam_cc_sa8775p_clocks[CAM_CC_CSI3PHYTIMER_CLK] = NULL;
+		cam_cc_sa8775p_clocks[CAM_CC_CSI3PHYTIMER_CLK_SRC] = NULL;
+		cam_cc_sa8775p_clocks[CAM_CC_CSIPHY3_CLK] = NULL;
+		cam_cc_sa8775p_clocks[CAM_CC_MCLK3_CLK] = NULL;
+		cam_cc_sa8775p_clocks[CAM_CC_MCLK3_CLK_SRC] = NULL;
+		cam_cc_sa8775p_clocks[CAM_CC_SM_OBS_CLK] =
+					&cam_cc_sm_obs_clk.clkr;
+		cam_cc_sa8775p_clocks[CAM_CC_TITAN_TOP_ACCU_SHIFT_CLK] =
+				&cam_cc_titan_top_accu_shift_clk.clkr;
+
+		/* Keep some clocks always enabled */
+		regmap_update_bits(regmap, 0x13178, BIT(0), BIT(0)); /* CAM_CC_CAMNOC_XO_CLK */
+		regmap_update_bits(regmap, 0x131d0, BIT(0), BIT(0)); /* CAM_CC_GDSC_CLK */
+		regmap_update_bits(regmap, 0x131ec, BIT(0), BIT(0)); /* CAM_CC_SLEEP_CLK */
+	} else {
+		/* Keep some clocks always enabled */
+		qcom_branch_set_clk_en(regmap, 0x13194); /* CAM_CC_CAMNOC_XO_CLK */
+		qcom_branch_set_clk_en(regmap, 0x131ec); /* CAM_CC_GDSC_CLK */
+		qcom_branch_set_clk_en(regmap, 0x13208); /* CAM_CC_SLEEP_CLK */
+	}
+
+	ret = qcom_cc_really_probe(&pdev->dev, &cam_cc_sa8775p_desc, regmap);
+
+	pm_runtime_put(&pdev->dev);
+
+	return ret;
+}
+
+static struct platform_driver cam_cc_sa8775p_driver = {
+	.probe = cam_cc_sa8775p_probe,
+	.driver = {
+		.name = "camcc-sa8775p",
+		.of_match_table = cam_cc_sa8775p_match_table,
+	},
+};
+
+module_platform_driver(cam_cc_sa8775p_driver);
+
+MODULE_DESCRIPTION("QTI CAMCC SA8775P Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/camcc-sc7180.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/camcc-sc7180.c
@@ -1680,7 +1680,7 @@
 	clk_agera_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll2_config);
 	clk_fabia_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll3_config);
 
-	ret = qcom_cc_really_probe(pdev, &cam_cc_sc7180_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &cam_cc_sc7180_desc, regmap);
 	pm_runtime_put(&pdev->dev);
 	if (ret < 0) {
 		dev_err(&pdev->dev, "Failed to register CAM CC clocks\n");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/camcc-sc7280.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/camcc-sc7280.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/clk-provider.h>
@@ -2247,6 +2248,9 @@
 
 static struct gdsc cam_cc_titan_top_gdsc = {
 	.gdscr = 0xc194,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "cam_cc_titan_top_gdsc",
 	},
@@ -2256,46 +2260,66 @@
 
 static struct gdsc cam_cc_bps_gdsc = {
 	.gdscr = 0x7004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "cam_cc_bps_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.parent = &cam_cc_titan_top_gdsc.pd,
 	.flags = HW_CTRL | RETAIN_FF_ENABLE,
 };
 
 static struct gdsc cam_cc_ife_0_gdsc = {
 	.gdscr = 0xa004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "cam_cc_ife_0_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.parent = &cam_cc_titan_top_gdsc.pd,
 	.flags = RETAIN_FF_ENABLE,
 };
 
 static struct gdsc cam_cc_ife_1_gdsc = {
 	.gdscr = 0xb004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "cam_cc_ife_1_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.parent = &cam_cc_titan_top_gdsc.pd,
 	.flags = RETAIN_FF_ENABLE,
 };
 
 static struct gdsc cam_cc_ife_2_gdsc = {
 	.gdscr = 0xb070,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "cam_cc_ife_2_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.parent = &cam_cc_titan_top_gdsc.pd,
 	.flags = RETAIN_FF_ENABLE,
 };
 
 static struct gdsc cam_cc_ipe_0_gdsc = {
 	.gdscr = 0x8004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "cam_cc_ipe_0_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.parent = &cam_cc_titan_top_gdsc.pd,
 	.flags = HW_CTRL | RETAIN_FF_ENABLE,
 };
 
@@ -2457,7 +2481,7 @@
 	clk_lucid_pll_configure(&cam_cc_pll5, regmap, &cam_cc_pll5_config);
 	clk_lucid_pll_configure(&cam_cc_pll6, regmap, &cam_cc_pll6_config);
 
-	return qcom_cc_really_probe(pdev, &cam_cc_sc7280_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &cam_cc_sc7280_desc, regmap);
 }
 
 static struct platform_driver cam_cc_sc7280_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/camcc-sc8280xp.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/camcc-sc8280xp.c
@@ -630,6 +630,7 @@
 	F(480000000, P_CAMCC_PLL7_OUT_EVEN, 1, 0, 0),
 	F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0),
 	F(760000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_bps_clk_src = {
@@ -654,6 +655,7 @@
 	F(320000000, P_CAMCC_PLL7_OUT_ODD, 1, 0, 0),
 	F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0),
 	F(480000000, P_CAMCC_PLL7_OUT_EVEN, 1, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_camnoc_axi_clk_src = {
@@ -673,6 +675,7 @@
 static const struct freq_tbl ftbl_camcc_cci_0_clk_src[] = {
 	F(19200000, P_BI_TCXO, 1, 0, 0),
 	F(37500000, P_CAMCC_PLL0_OUT_EVEN, 16, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_cci_0_clk_src = {
@@ -735,6 +738,7 @@
 	F(19200000, P_BI_TCXO, 1, 0, 0),
 	F(240000000, P_CAMCC_PLL0_OUT_EVEN, 2.5, 0, 0),
 	F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_cphy_rx_clk_src = {
@@ -754,6 +758,7 @@
 static const struct freq_tbl ftbl_camcc_csi0phytimer_clk_src[] = {
 	F(19200000, P_BI_TCXO, 1, 0, 0),
 	F(300000000, P_CAMCC_PLL0_OUT_EVEN, 2, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_csi0phytimer_clk_src = {
@@ -818,6 +823,7 @@
 	F(200000000, P_CAMCC_PLL0_OUT_EVEN, 3, 0, 0),
 	F(300000000, P_CAMCC_PLL0_OUT_MAIN, 4, 0, 0),
 	F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_fast_ahb_clk_src = {
@@ -838,6 +844,7 @@
 	F(19200000, P_BI_TCXO, 1, 0, 0),
 	F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0),
 	F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_icp_clk_src = {
@@ -860,6 +867,7 @@
 	F(558000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0),
 	F(637000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0),
 	F(760000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_ife_0_clk_src = {
@@ -883,6 +891,7 @@
 	F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0),
 	F(480000000, P_CAMCC_PLL7_OUT_EVEN, 1, 0, 0),
 	F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_ife_0_csid_clk_src = {
@@ -905,6 +914,7 @@
 	F(558000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0),
 	F(637000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0),
 	F(760000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_ife_1_clk_src = {
@@ -941,6 +951,7 @@
 	F(558000000, P_CAMCC_PLL5_OUT_EVEN, 1, 0, 0),
 	F(637000000, P_CAMCC_PLL5_OUT_EVEN, 1, 0, 0),
 	F(760000000, P_CAMCC_PLL5_OUT_EVEN, 1, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_ife_2_clk_src = {
@@ -962,6 +973,7 @@
 	F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0),
 	F(480000000, P_CAMCC_PLL7_OUT_EVEN, 1, 0, 0),
 	F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_ife_2_csid_clk_src = {
@@ -984,6 +996,7 @@
 	F(558000000, P_CAMCC_PLL6_OUT_EVEN, 1, 0, 0),
 	F(637000000, P_CAMCC_PLL6_OUT_EVEN, 1, 0, 0),
 	F(760000000, P_CAMCC_PLL6_OUT_EVEN, 1, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_ife_3_clk_src = {
@@ -1020,6 +1033,7 @@
 	F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0),
 	F(480000000, P_CAMCC_PLL7_OUT_EVEN, 1, 0, 0),
 	F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_ife_lite_0_clk_src = {
@@ -1140,6 +1154,7 @@
 	F(475000000, P_CAMCC_PLL1_OUT_EVEN, 1, 0, 0),
 	F(520000000, P_CAMCC_PLL1_OUT_EVEN, 1, 0, 0),
 	F(600000000, P_CAMCC_PLL1_OUT_EVEN, 1, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_ipe_0_clk_src = {
@@ -1163,6 +1178,7 @@
 	F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0),
 	F(480000000, P_CAMCC_PLL7_OUT_EVEN, 1, 0, 0),
 	F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_jpeg_clk_src = {
@@ -1184,6 +1200,7 @@
 	F(300000000, P_CAMCC_PLL0_OUT_EVEN, 2, 0, 0),
 	F(320000000, P_CAMCC_PLL7_OUT_ODD, 1, 0, 0),
 	F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_lrme_clk_src = {
@@ -1204,6 +1221,7 @@
 	F(19200000, P_BI_TCXO, 1, 0, 0),
 	F(24000000, P_CAMCC_PLL2_OUT_EARLY, 10, 1, 4),
 	F(64000000, P_CAMCC_PLL2_OUT_EARLY, 15, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_mclk0_clk_src = {
@@ -1320,6 +1338,7 @@
 
 static const struct freq_tbl ftbl_camcc_sleep_clk_src[] = {
 	F(32000, P_SLEEP_CLK, 1, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_sleep_clk_src = {
@@ -1339,6 +1358,7 @@
 static const struct freq_tbl ftbl_camcc_slow_ahb_clk_src[] = {
 	F(19200000, P_BI_TCXO, 1, 0, 0),
 	F(80000000, P_CAMCC_PLL7_OUT_EVEN, 6, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_slow_ahb_clk_src = {
@@ -1357,6 +1377,7 @@
 
 static const struct freq_tbl ftbl_camcc_xo_clk_src[] = {
 	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 camcc_xo_clk_src = {
@@ -3015,7 +3036,7 @@
 	 */
 	regmap_update_bits(regmap, 0xc1e4, BIT(0), 1);
 
-	ret = qcom_cc_really_probe(pdev, &camcc_sc8280xp_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &camcc_sc8280xp_desc, regmap);
 	if (ret)
 		goto err_disable;
 
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/camcc-sdm845.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/camcc-sdm845.c
@@ -1735,7 +1735,7 @@
 	cam_cc_pll_config.l = 0x14;
 	clk_fabia_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll_config);
 
-	return qcom_cc_really_probe(pdev, &cam_cc_sdm845_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &cam_cc_sdm845_desc, regmap);
 }
 
 static struct platform_driver cam_cc_sdm845_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/camcc-sm6350.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/camcc-sm6350.c
@@ -1879,7 +1879,7 @@
 	clk_agera_pll_configure(&camcc_pll2, regmap, &camcc_pll2_config);
 	clk_fabia_pll_configure(&camcc_pll3, regmap, &camcc_pll3_config);
 
-	return qcom_cc_really_probe(pdev, &camcc_sm6350_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &camcc_sm6350_desc, regmap);
 }
 
 static struct platform_driver camcc_sm6350_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/camcc-sm7150.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/camcc-sm7150.c
@@ -0,0 +1,2061 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2018, 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,sm7150-camcc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "common.h"
+#include "gdsc.h"
+
+enum {
+	DT_BI_TCXO,
+	DT_BI_TCXO_AO,
+	DT_CHIP_SLEEP_CLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_BI_TCXO_MX,
+	P_CAMCC_PLL0_OUT_EVEN,
+	P_CAMCC_PLL0_OUT_MAIN,
+	P_CAMCC_PLL0_OUT_ODD,
+	P_CAMCC_PLL1_OUT_EVEN,
+	P_CAMCC_PLL2_OUT_AUX,
+	P_CAMCC_PLL2_OUT_EARLY,
+	P_CAMCC_PLL2_OUT_MAIN,
+	P_CAMCC_PLL3_OUT_EVEN,
+	P_CAMCC_PLL4_OUT_EVEN,
+	P_CHIP_SLEEP_CLK,
+};
+
+static const struct pll_vco fabia_vco[] = {
+	{ 249600000, 2000000000, 0 },
+};
+
+/* 1200MHz configuration */
+static const struct alpha_pll_config camcc_pll0_config = {
+	.l = 0x3e,
+	.alpha = 0x8000,
+	.post_div_mask = 0xff << 8,
+	.post_div_val = 0x31 << 8,
+	.test_ctl_val = 0x40000000,
+};
+
+static struct clk_alpha_pll camcc_pll0 = {
+	.offset = 0x0,
+	.vco_table = fabia_vco,
+	.num_vco = ARRAY_SIZE(fabia_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fabia_ops,
+		},
+	},
+};
+
+static struct clk_fixed_factor camcc_pll0_out_even = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_pll0_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&camcc_pll0.clkr.hw,
+		},
+		.num_parents = 1,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+static struct clk_fixed_factor camcc_pll0_out_odd = {
+	.mult = 1,
+	.div = 3,
+	.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_pll0_out_odd",
+		.parent_hws = (const struct clk_hw*[]) {
+			&camcc_pll0.clkr.hw,
+		},
+		.num_parents = 1,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+/* 680MHz configuration */
+static const struct alpha_pll_config camcc_pll1_config = {
+	.l = 0x23,
+	.alpha = 0x6aaa,
+	.post_div_mask = 0xf << 8,
+	.post_div_val = 0x1 << 8,
+	.test_ctl_val = 0x40000000,
+};
+
+static struct clk_alpha_pll camcc_pll1 = {
+	.offset = 0x1000,
+	.vco_table = fabia_vco,
+	.num_vco = ARRAY_SIZE(fabia_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_pll1",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fabia_ops,
+		},
+	},
+};
+
+static struct clk_fixed_factor camcc_pll1_out_even = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_pll1_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&camcc_pll1.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+/* 1920MHz configuration */
+static const struct alpha_pll_config camcc_pll2_config = {
+	.l = 0x64,
+	.post_div_val = 0x3 << 8,
+	.post_div_mask = 0x3 << 8,
+	.early_output_mask = BIT(3),
+	.aux_output_mask = BIT(1),
+	.main_output_mask = BIT(0),
+	.config_ctl_hi_val = 0x400003d6,
+	.config_ctl_val = 0x20000954,
+};
+
+static struct clk_alpha_pll camcc_pll2 = {
+	.offset = 0x2000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_pll2",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_agera_ops,
+		},
+	},
+};
+
+static struct clk_fixed_factor camcc_pll2_out_early = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_pll2_out_early",
+		.parent_hws = (const struct clk_hw*[]) {
+			&camcc_pll2.clkr.hw,
+		},
+		.num_parents = 1,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+static struct clk_alpha_pll_postdiv camcc_pll2_out_aux = {
+	.offset = 0x2000,
+	.post_div_shift = 8,
+	.width = 2,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_pll2_out_aux",
+		.parent_hws = (const struct clk_hw*[]) {
+			&camcc_pll2.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_ops,
+	},
+};
+
+static struct clk_alpha_pll_postdiv camcc_pll2_out_main = {
+	.offset = 0x2000,
+	.post_div_shift = 8,
+	.width = 2,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_pll2_out_main",
+		.parent_hws = (const struct clk_hw*[]) {
+			&camcc_pll2.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_ops,
+	},
+};
+
+/* 760MHz configuration */
+static const struct alpha_pll_config camcc_pll3_config = {
+	.l = 0x27,
+	.alpha = 0x9555,
+	.post_div_mask = 0xf << 8,
+	.post_div_val = 0x1 << 8,
+	.test_ctl_val = 0x40000000,
+};
+
+static struct clk_alpha_pll camcc_pll3 = {
+	.offset = 0x3000,
+	.vco_table = fabia_vco,
+	.num_vco = ARRAY_SIZE(fabia_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_pll3",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fabia_ops,
+		},
+	},
+};
+
+static struct clk_fixed_factor camcc_pll3_out_even = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_pll3_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&camcc_pll3.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+static struct clk_alpha_pll camcc_pll4 = {
+	.offset = 0x4000,
+	.vco_table = fabia_vco,
+	.num_vco = ARRAY_SIZE(fabia_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_pll4",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fabia_ops,
+		},
+	},
+};
+
+static struct clk_fixed_factor camcc_pll4_out_even = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_pll4_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&camcc_pll4.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+static const struct parent_map camcc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAMCC_PLL0_OUT_MAIN, 1 },
+	{ P_CAMCC_PLL0_OUT_EVEN, 2 },
+	{ P_CAMCC_PLL0_OUT_ODD, 3 },
+	{ P_CAMCC_PLL2_OUT_MAIN, 5 },
+};
+
+static const struct clk_parent_data camcc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &camcc_pll0.clkr.hw },
+	{ .hw = &camcc_pll0_out_even.hw },
+	{ .hw = &camcc_pll0_out_odd.hw },
+	{ .hw = &camcc_pll2_out_main.clkr.hw },
+};
+
+static const struct parent_map camcc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAMCC_PLL0_OUT_MAIN, 1 },
+	{ P_CAMCC_PLL0_OUT_EVEN, 2 },
+	{ P_CAMCC_PLL0_OUT_ODD, 3 },
+	{ P_CAMCC_PLL1_OUT_EVEN, 4 },
+	{ P_CAMCC_PLL2_OUT_EARLY, 5 },
+};
+
+static const struct clk_parent_data camcc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &camcc_pll0.clkr.hw },
+	{ .hw = &camcc_pll0_out_even.hw },
+	{ .hw = &camcc_pll0_out_odd.hw },
+	{ .hw = &camcc_pll1_out_even.hw },
+	{ .hw = &camcc_pll2_out_early.hw },
+};
+
+static const struct parent_map camcc_parent_map_2[] = {
+	{ P_BI_TCXO_MX, 0 },
+	{ P_CAMCC_PLL2_OUT_AUX, 5 },
+};
+
+static const struct clk_parent_data camcc_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &camcc_pll2_out_aux.clkr.hw },
+};
+
+static const struct parent_map camcc_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAMCC_PLL0_OUT_MAIN, 1 },
+	{ P_CAMCC_PLL0_OUT_EVEN, 2 },
+	{ P_CAMCC_PLL0_OUT_ODD, 3 },
+	{ P_CAMCC_PLL2_OUT_EARLY, 5 },
+	{ P_CAMCC_PLL4_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data camcc_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &camcc_pll0.clkr.hw },
+	{ .hw = &camcc_pll0_out_even.hw },
+	{ .hw = &camcc_pll0_out_odd.hw },
+	{ .hw = &camcc_pll2_out_early.hw },
+	{ .hw = &camcc_pll4_out_even.hw },
+};
+
+static const struct parent_map camcc_parent_map_4[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAMCC_PLL3_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data camcc_parent_data_4[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &camcc_pll3_out_even.hw },
+};
+
+static const struct parent_map camcc_parent_map_5[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAMCC_PLL4_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data camcc_parent_data_5[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &camcc_pll4_out_even.hw },
+};
+
+static const struct parent_map camcc_parent_map_6[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAMCC_PLL1_OUT_EVEN, 4 },
+};
+
+static const struct clk_parent_data camcc_parent_data_6[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &camcc_pll1_out_even.hw },
+};
+
+static const struct parent_map camcc_parent_map_7[] = {
+	{ P_CHIP_SLEEP_CLK, 0 },
+};
+
+static const struct clk_parent_data camcc_parent_data_7[] = {
+	{ .index = DT_CHIP_SLEEP_CLK },
+};
+
+static const struct parent_map camcc_parent_map_8[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAMCC_PLL0_OUT_ODD, 3 },
+};
+
+static const struct clk_parent_data camcc_parent_data_8[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &camcc_pll0_out_odd.hw },
+};
+
+static const struct parent_map camcc_parent_map_9[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data camcc_parent_data_9[] = {
+	{ .index = DT_BI_TCXO_AO },
+};
+
+static const struct freq_tbl ftbl_camcc_bps_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(100000000, P_CAMCC_PLL0_OUT_EVEN, 6, 0, 0),
+	F(200000000, P_CAMCC_PLL0_OUT_ODD, 2, 0, 0),
+	F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0),
+	F(480000000, P_CAMCC_PLL2_OUT_MAIN, 1, 0, 0),
+	F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_bps_clk_src = {
+	.cmd_rcgr = 0x7010,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_0,
+	.freq_tbl = ftbl_camcc_bps_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_bps_clk_src",
+		.parent_data = camcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_0),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_camnoc_axi_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(150000000, P_CAMCC_PLL0_OUT_EVEN, 4, 0, 0),
+	F(240000000, P_CAMCC_PLL2_OUT_MAIN, 2, 0, 0),
+	F(320000000, P_CAMCC_PLL2_OUT_MAIN, 1.5, 0, 0),
+	F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(480000000, P_CAMCC_PLL2_OUT_MAIN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_camnoc_axi_clk_src = {
+	.cmd_rcgr = 0xc12c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_0,
+	.freq_tbl = ftbl_camcc_camnoc_axi_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_camnoc_axi_clk_src",
+		.parent_data = camcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_0),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_cci_0_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(37500000, P_CAMCC_PLL0_OUT_EVEN, 16, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_cci_0_clk_src = {
+	.cmd_rcgr = 0xc0c4,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_0,
+	.freq_tbl = ftbl_camcc_cci_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_cci_0_clk_src",
+		.parent_data = camcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 camcc_cci_1_clk_src = {
+	.cmd_rcgr = 0xc0e0,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_0,
+	.freq_tbl = ftbl_camcc_cci_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_cci_1_clk_src",
+		.parent_data = camcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_cphy_rx_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(300000000, P_CAMCC_PLL0_OUT_EVEN, 2, 0, 0),
+	F(384000000, P_CAMCC_PLL2_OUT_EARLY, 2.5, 0, 0),
+	F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_cphy_rx_clk_src = {
+	.cmd_rcgr = 0xa064,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_1,
+	.freq_tbl = ftbl_camcc_cphy_rx_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_cphy_rx_clk_src",
+		.parent_data = camcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_1),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_csi0phytimer_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(300000000, P_CAMCC_PLL0_OUT_EVEN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_csi0phytimer_clk_src = {
+	.cmd_rcgr = 0x6004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_0,
+	.freq_tbl = ftbl_camcc_csi0phytimer_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_csi0phytimer_clk_src",
+		.parent_data = camcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 camcc_csi1phytimer_clk_src = {
+	.cmd_rcgr = 0x6028,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_0,
+	.freq_tbl = ftbl_camcc_csi0phytimer_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_csi1phytimer_clk_src",
+		.parent_data = camcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 camcc_csi2phytimer_clk_src = {
+	.cmd_rcgr = 0x604c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_0,
+	.freq_tbl = ftbl_camcc_csi0phytimer_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_csi2phytimer_clk_src",
+		.parent_data = camcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 camcc_csi3phytimer_clk_src = {
+	.cmd_rcgr = 0x6070,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_0,
+	.freq_tbl = ftbl_camcc_csi0phytimer_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_csi3phytimer_clk_src",
+		.parent_data = camcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_fast_ahb_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(50000000, P_CAMCC_PLL0_OUT_EVEN, 12, 0, 0),
+	F(100000000, P_CAMCC_PLL0_OUT_EVEN, 6, 0, 0),
+	F(200000000, P_CAMCC_PLL0_OUT_EVEN, 3, 0, 0),
+	F(300000000, P_CAMCC_PLL0_OUT_MAIN, 4, 0, 0),
+	F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_fast_ahb_clk_src = {
+	.cmd_rcgr = 0x703c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_0,
+	.freq_tbl = ftbl_camcc_fast_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_fast_ahb_clk_src",
+		.parent_data = camcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_fd_core_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(380000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0),
+	F(384000000, P_CAMCC_PLL2_OUT_EARLY, 2.5, 0, 0),
+	F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(480000000, P_CAMCC_PLL2_OUT_EARLY, 2, 0, 0),
+	F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_fd_core_clk_src = {
+	.cmd_rcgr = 0xc09c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_3,
+	.freq_tbl = ftbl_camcc_fd_core_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_fd_core_clk_src",
+		.parent_data = camcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_icp_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0),
+	F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_icp_clk_src = {
+	.cmd_rcgr = 0xc074,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_0,
+	.freq_tbl = ftbl_camcc_icp_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_icp_clk_src",
+		.parent_data = camcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_0),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_ife_0_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(380000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0),
+	F(510000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0),
+	F(637000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0),
+	F(760000000, P_CAMCC_PLL3_OUT_EVEN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_ife_0_clk_src = {
+	.cmd_rcgr = 0xa010,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_4,
+	.freq_tbl = ftbl_camcc_ife_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_ife_0_clk_src",
+		.parent_data = camcc_parent_data_4,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_ife_0_csid_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(75000000, P_CAMCC_PLL0_OUT_EVEN, 8, 0, 0),
+	F(300000000, P_CAMCC_PLL0_OUT_EVEN, 2, 0, 0),
+	F(384000000, P_CAMCC_PLL2_OUT_EARLY, 2.5, 0, 0),
+	F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_ife_0_csid_clk_src = {
+	.cmd_rcgr = 0xa03c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_1,
+	.freq_tbl = ftbl_camcc_ife_0_csid_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_ife_0_csid_clk_src",
+		.parent_data = camcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_1),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_ife_1_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(380000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0),
+	F(510000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0),
+	F(637000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0),
+	F(760000000, P_CAMCC_PLL4_OUT_EVEN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_ife_1_clk_src = {
+	.cmd_rcgr = 0xb010,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_5,
+	.freq_tbl = ftbl_camcc_ife_1_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_ife_1_clk_src",
+		.parent_data = camcc_parent_data_5,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_5),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 camcc_ife_1_csid_clk_src = {
+	.cmd_rcgr = 0xb034,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_1,
+	.freq_tbl = ftbl_camcc_ife_0_csid_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_ife_1_csid_clk_src",
+		.parent_data = camcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_1),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_ife_lite_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(320000000, P_CAMCC_PLL2_OUT_MAIN, 1.5, 0, 0),
+	F(400000000, P_CAMCC_PLL0_OUT_ODD, 1, 0, 0),
+	F(480000000, P_CAMCC_PLL2_OUT_MAIN, 1, 0, 0),
+	F(600000000, P_CAMCC_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_ife_lite_clk_src = {
+	.cmd_rcgr = 0xc004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_0,
+	.freq_tbl = ftbl_camcc_ife_lite_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_ife_lite_clk_src",
+		.parent_data = camcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 camcc_ife_lite_csid_clk_src = {
+	.cmd_rcgr = 0xc020,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_1,
+	.freq_tbl = ftbl_camcc_cphy_rx_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_ife_lite_csid_clk_src",
+		.parent_data = camcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_1),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_ipe_0_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(340000000, P_CAMCC_PLL1_OUT_EVEN, 1, 0, 0),
+	F(430000000, P_CAMCC_PLL1_OUT_EVEN, 1, 0, 0),
+	F(520000000, P_CAMCC_PLL1_OUT_EVEN, 1, 0, 0),
+	F(600000000, P_CAMCC_PLL1_OUT_EVEN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_ipe_0_clk_src = {
+	.cmd_rcgr = 0x8010,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_6,
+	.freq_tbl = ftbl_camcc_ipe_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_ipe_0_clk_src",
+		.parent_data = camcc_parent_data_6,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_6),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 camcc_jpeg_clk_src = {
+	.cmd_rcgr = 0xc048,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_0,
+	.freq_tbl = ftbl_camcc_bps_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_jpeg_clk_src",
+		.parent_data = camcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_0),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_lrme_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(100000000, P_CAMCC_PLL0_OUT_EVEN, 6, 0, 0),
+	F(240000000, P_CAMCC_PLL2_OUT_MAIN, 2, 0, 0),
+	F(300000000, P_CAMCC_PLL0_OUT_EVEN, 2, 0, 0),
+	F(320000000, P_CAMCC_PLL2_OUT_MAIN, 1.5, 0, 0),
+	F(400000000, P_CAMCC_PLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_lrme_clk_src = {
+	.cmd_rcgr = 0xc100,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_0,
+	.freq_tbl = ftbl_camcc_lrme_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_lrme_clk_src",
+		.parent_data = camcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_0),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_mclk0_clk_src[] = {
+	F(19200000, P_BI_TCXO_MX, 1, 0, 0),
+	F(24000000, P_CAMCC_PLL2_OUT_AUX, 1, 1, 20),
+	F(34285714, P_CAMCC_PLL2_OUT_AUX, 14, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_mclk0_clk_src = {
+	.cmd_rcgr = 0x5004,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_2,
+	.freq_tbl = ftbl_camcc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_mclk0_clk_src",
+		.parent_data = camcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_2),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 camcc_mclk1_clk_src = {
+	.cmd_rcgr = 0x5024,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_2,
+	.freq_tbl = ftbl_camcc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_mclk1_clk_src",
+		.parent_data = camcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_2),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 camcc_mclk2_clk_src = {
+	.cmd_rcgr = 0x5044,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_2,
+	.freq_tbl = ftbl_camcc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_mclk2_clk_src",
+		.parent_data = camcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_2),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 camcc_mclk3_clk_src = {
+	.cmd_rcgr = 0x5064,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_2,
+	.freq_tbl = ftbl_camcc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_mclk3_clk_src",
+		.parent_data = camcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_2),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_sleep_clk_src[] = {
+	F(32000, P_CHIP_SLEEP_CLK, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_sleep_clk_src = {
+	.cmd_rcgr = 0xc1a4,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_7,
+	.freq_tbl = ftbl_camcc_sleep_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_sleep_clk_src",
+		.parent_data = camcc_parent_data_7,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_7),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_slow_ahb_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(80000000, P_CAMCC_PLL0_OUT_ODD, 5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_slow_ahb_clk_src = {
+	.cmd_rcgr = 0x7058,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_8,
+	.freq_tbl = ftbl_camcc_slow_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_slow_ahb_clk_src",
+		.parent_data = camcc_parent_data_8,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_8),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_camcc_xo_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 camcc_xo_clk_src = {
+	.cmd_rcgr = 0xc188,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = camcc_parent_map_9,
+	.freq_tbl = ftbl_camcc_xo_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "camcc_xo_clk_src",
+		.parent_data = camcc_parent_data_9,
+		.num_parents = ARRAY_SIZE(camcc_parent_data_9),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_branch camcc_bps_ahb_clk = {
+	.halt_reg = 0x7070,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x7070,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_bps_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_bps_areg_clk = {
+	.halt_reg = 0x7054,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x7054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_bps_areg_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_bps_axi_clk = {
+	.halt_reg = 0x7038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x7038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_bps_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_camnoc_axi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_bps_clk = {
+	.halt_reg = 0x7028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x7028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_bps_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_bps_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_camnoc_axi_clk = {
+	.halt_reg = 0xc148,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc148,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_camnoc_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_camnoc_axi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_camnoc_dcd_xo_clk = {
+	.halt_reg = 0xc150,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc150,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_camnoc_dcd_xo_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_cci_0_clk = {
+	.halt_reg = 0xc0dc,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc0dc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_cci_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_cci_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_cci_1_clk = {
+	.halt_reg = 0xc0f8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc0f8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_cci_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_cci_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_core_ahb_clk = {
+	.halt_reg = 0xc184,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0xc184,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_core_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_cpas_ahb_clk = {
+	.halt_reg = 0xc124,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc124,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_cpas_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_csi0phytimer_clk = {
+	.halt_reg = 0x601c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x601c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_csi0phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_csi0phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_csi1phytimer_clk = {
+	.halt_reg = 0x6040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_csi1phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_csi1phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_csi2phytimer_clk = {
+	.halt_reg = 0x6064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_csi2phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_csi2phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_csi3phytimer_clk = {
+	.halt_reg = 0x6088,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6088,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_csi3phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_csi3phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_csiphy0_clk = {
+	.halt_reg = 0x6020,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_csiphy0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_csiphy1_clk = {
+	.halt_reg = 0x6044,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6044,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_csiphy1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_csiphy2_clk = {
+	.halt_reg = 0x6068,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6068,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_csiphy2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_csiphy3_clk = {
+	.halt_reg = 0x608c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x608c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_csiphy3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_fd_core_clk = {
+	.halt_reg = 0xc0b4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc0b4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_fd_core_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_fd_core_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_fd_core_uar_clk = {
+	.halt_reg = 0xc0bc,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc0bc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_fd_core_uar_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_fd_core_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_icp_ahb_clk = {
+	.halt_reg = 0xc094,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc094,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_icp_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_icp_clk = {
+	.halt_reg = 0xc08c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc08c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_icp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_icp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ife_0_axi_clk = {
+	.halt_reg = 0xa080,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa080,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ife_0_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_camnoc_axi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ife_0_clk = {
+	.halt_reg = 0xa028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ife_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_ife_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ife_0_cphy_rx_clk = {
+	.halt_reg = 0xa07c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa07c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ife_0_cphy_rx_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ife_0_csid_clk = {
+	.halt_reg = 0xa054,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ife_0_csid_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_ife_0_csid_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ife_0_dsp_clk = {
+	.halt_reg = 0xa038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ife_0_dsp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_ife_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ife_1_axi_clk = {
+	.halt_reg = 0xb058,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb058,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ife_1_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_camnoc_axi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ife_1_clk = {
+	.halt_reg = 0xb028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ife_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_ife_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ife_1_cphy_rx_clk = {
+	.halt_reg = 0xb054,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ife_1_cphy_rx_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ife_1_csid_clk = {
+	.halt_reg = 0xb04c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb04c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ife_1_csid_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_ife_1_csid_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ife_1_dsp_clk = {
+	.halt_reg = 0xb030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ife_1_dsp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_ife_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ife_lite_clk = {
+	.halt_reg = 0xc01c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc01c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ife_lite_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_ife_lite_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ife_lite_cphy_rx_clk = {
+	.halt_reg = 0xc040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ife_lite_cphy_rx_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ife_lite_csid_clk = {
+	.halt_reg = 0xc038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ife_lite_csid_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_ife_lite_csid_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ipe_0_ahb_clk = {
+	.halt_reg = 0x8040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ipe_0_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ipe_0_areg_clk = {
+	.halt_reg = 0x803c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x803c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ipe_0_areg_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ipe_0_axi_clk = {
+	.halt_reg = 0x8038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ipe_0_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_camnoc_axi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ipe_0_clk = {
+	.halt_reg = 0x8028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ipe_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_ipe_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ipe_1_ahb_clk = {
+	.halt_reg = 0x9028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ipe_1_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ipe_1_areg_clk = {
+	.halt_reg = 0x9024,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ipe_1_areg_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ipe_1_axi_clk = {
+	.halt_reg = 0x9020,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ipe_1_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_camnoc_axi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_ipe_1_clk = {
+	.halt_reg = 0x9010,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_ipe_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_ipe_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_jpeg_clk = {
+	.halt_reg = 0xc060,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc060,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_jpeg_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_jpeg_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_lrme_clk = {
+	.halt_reg = 0xc118,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc118,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_lrme_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_lrme_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_mclk0_clk = {
+	.halt_reg = 0x501c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x501c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_mclk0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_mclk0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_mclk1_clk = {
+	.halt_reg = 0x503c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x503c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_mclk1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_mclk1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_mclk2_clk = {
+	.halt_reg = 0x505c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x505c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_mclk2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_mclk2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_mclk3_clk = {
+	.halt_reg = 0x507c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x507c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_mclk3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_mclk3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch camcc_sleep_clk = {
+	.halt_reg = 0xc1bc,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc1bc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "camcc_sleep_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&camcc_sleep_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc camcc_titan_top_gdsc;
+
+static struct gdsc camcc_bps_gdsc = {
+	.gdscr = 0x7004,
+	.pd = {
+		.name = "camcc_bps_gdsc",
+	},
+	.flags = HW_CTRL | POLL_CFG_GDSCR,
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camcc_ife_0_gdsc = {
+	.gdscr = 0xa004,
+	.pd = {
+		.name = "camcc_ife_0_gdsc",
+	},
+	.flags = POLL_CFG_GDSCR,
+	.parent = &camcc_titan_top_gdsc.pd,
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camcc_ife_1_gdsc = {
+	.gdscr = 0xb004,
+	.pd = {
+		.name = "camcc_ife_1_gdsc",
+	},
+	.flags = POLL_CFG_GDSCR,
+	.parent = &camcc_titan_top_gdsc.pd,
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camcc_ipe_0_gdsc = {
+	.gdscr = 0x8004,
+	.pd = {
+		.name = "camcc_ipe_0_gdsc",
+	},
+	.flags = HW_CTRL | POLL_CFG_GDSCR,
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camcc_ipe_1_gdsc = {
+	.gdscr = 0x9004,
+	.pd = {
+		.name = "camcc_ipe_1_gdsc",
+	},
+	.flags = HW_CTRL | POLL_CFG_GDSCR,
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camcc_titan_top_gdsc = {
+	.gdscr = 0xc1c4,
+	.pd = {
+		.name = "camcc_titan_top_gdsc",
+	},
+	.flags = POLL_CFG_GDSCR,
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+struct clk_hw *camcc_sm7150_hws[] = {
+	[CAMCC_PLL0_OUT_EVEN] = &camcc_pll0_out_even.hw,
+	[CAMCC_PLL0_OUT_ODD] = &camcc_pll0_out_odd.hw,
+	[CAMCC_PLL1_OUT_EVEN] = &camcc_pll1_out_even.hw,
+	[CAMCC_PLL2_OUT_EARLY] = &camcc_pll2_out_early.hw,
+	[CAMCC_PLL3_OUT_EVEN] = &camcc_pll3_out_even.hw,
+	[CAMCC_PLL4_OUT_EVEN] = &camcc_pll4_out_even.hw,
+};
+
+static struct clk_regmap *camcc_sm7150_clocks[] = {
+	[CAMCC_BPS_AHB_CLK] = &camcc_bps_ahb_clk.clkr,
+	[CAMCC_BPS_AREG_CLK] = &camcc_bps_areg_clk.clkr,
+	[CAMCC_BPS_AXI_CLK] = &camcc_bps_axi_clk.clkr,
+	[CAMCC_BPS_CLK] = &camcc_bps_clk.clkr,
+	[CAMCC_BPS_CLK_SRC] = &camcc_bps_clk_src.clkr,
+	[CAMCC_CAMNOC_AXI_CLK] = &camcc_camnoc_axi_clk.clkr,
+	[CAMCC_CAMNOC_AXI_CLK_SRC] = &camcc_camnoc_axi_clk_src.clkr,
+	[CAMCC_CAMNOC_DCD_XO_CLK] = &camcc_camnoc_dcd_xo_clk.clkr,
+	[CAMCC_CCI_0_CLK] = &camcc_cci_0_clk.clkr,
+	[CAMCC_CCI_0_CLK_SRC] = &camcc_cci_0_clk_src.clkr,
+	[CAMCC_CCI_1_CLK] = &camcc_cci_1_clk.clkr,
+	[CAMCC_CCI_1_CLK_SRC] = &camcc_cci_1_clk_src.clkr,
+	[CAMCC_CORE_AHB_CLK] = &camcc_core_ahb_clk.clkr,
+	[CAMCC_CPAS_AHB_CLK] = &camcc_cpas_ahb_clk.clkr,
+	[CAMCC_CPHY_RX_CLK_SRC] = &camcc_cphy_rx_clk_src.clkr,
+	[CAMCC_CSI0PHYTIMER_CLK] = &camcc_csi0phytimer_clk.clkr,
+	[CAMCC_CSI0PHYTIMER_CLK_SRC] = &camcc_csi0phytimer_clk_src.clkr,
+	[CAMCC_CSI1PHYTIMER_CLK] = &camcc_csi1phytimer_clk.clkr,
+	[CAMCC_CSI1PHYTIMER_CLK_SRC] = &camcc_csi1phytimer_clk_src.clkr,
+	[CAMCC_CSI2PHYTIMER_CLK] = &camcc_csi2phytimer_clk.clkr,
+	[CAMCC_CSI2PHYTIMER_CLK_SRC] = &camcc_csi2phytimer_clk_src.clkr,
+	[CAMCC_CSI3PHYTIMER_CLK] = &camcc_csi3phytimer_clk.clkr,
+	[CAMCC_CSI3PHYTIMER_CLK_SRC] = &camcc_csi3phytimer_clk_src.clkr,
+	[CAMCC_CSIPHY0_CLK] = &camcc_csiphy0_clk.clkr,
+	[CAMCC_CSIPHY1_CLK] = &camcc_csiphy1_clk.clkr,
+	[CAMCC_CSIPHY2_CLK] = &camcc_csiphy2_clk.clkr,
+	[CAMCC_CSIPHY3_CLK] = &camcc_csiphy3_clk.clkr,
+	[CAMCC_FAST_AHB_CLK_SRC] = &camcc_fast_ahb_clk_src.clkr,
+	[CAMCC_FD_CORE_CLK] = &camcc_fd_core_clk.clkr,
+	[CAMCC_FD_CORE_CLK_SRC] = &camcc_fd_core_clk_src.clkr,
+	[CAMCC_FD_CORE_UAR_CLK] = &camcc_fd_core_uar_clk.clkr,
+	[CAMCC_ICP_AHB_CLK] = &camcc_icp_ahb_clk.clkr,
+	[CAMCC_ICP_CLK] = &camcc_icp_clk.clkr,
+	[CAMCC_ICP_CLK_SRC] = &camcc_icp_clk_src.clkr,
+	[CAMCC_IFE_0_AXI_CLK] = &camcc_ife_0_axi_clk.clkr,
+	[CAMCC_IFE_0_CLK] = &camcc_ife_0_clk.clkr,
+	[CAMCC_IFE_0_CLK_SRC] = &camcc_ife_0_clk_src.clkr,
+	[CAMCC_IFE_0_CPHY_RX_CLK] = &camcc_ife_0_cphy_rx_clk.clkr,
+	[CAMCC_IFE_0_CSID_CLK] = &camcc_ife_0_csid_clk.clkr,
+	[CAMCC_IFE_0_CSID_CLK_SRC] = &camcc_ife_0_csid_clk_src.clkr,
+	[CAMCC_IFE_0_DSP_CLK] = &camcc_ife_0_dsp_clk.clkr,
+	[CAMCC_IFE_1_AXI_CLK] = &camcc_ife_1_axi_clk.clkr,
+	[CAMCC_IFE_1_CLK] = &camcc_ife_1_clk.clkr,
+	[CAMCC_IFE_1_CLK_SRC] = &camcc_ife_1_clk_src.clkr,
+	[CAMCC_IFE_1_CPHY_RX_CLK] = &camcc_ife_1_cphy_rx_clk.clkr,
+	[CAMCC_IFE_1_CSID_CLK] = &camcc_ife_1_csid_clk.clkr,
+	[CAMCC_IFE_1_CSID_CLK_SRC] = &camcc_ife_1_csid_clk_src.clkr,
+	[CAMCC_IFE_1_DSP_CLK] = &camcc_ife_1_dsp_clk.clkr,
+	[CAMCC_IFE_LITE_CLK] = &camcc_ife_lite_clk.clkr,
+	[CAMCC_IFE_LITE_CLK_SRC] = &camcc_ife_lite_clk_src.clkr,
+	[CAMCC_IFE_LITE_CPHY_RX_CLK] = &camcc_ife_lite_cphy_rx_clk.clkr,
+	[CAMCC_IFE_LITE_CSID_CLK] = &camcc_ife_lite_csid_clk.clkr,
+	[CAMCC_IFE_LITE_CSID_CLK_SRC] = &camcc_ife_lite_csid_clk_src.clkr,
+	[CAMCC_IPE_0_AHB_CLK] = &camcc_ipe_0_ahb_clk.clkr,
+	[CAMCC_IPE_0_AREG_CLK] = &camcc_ipe_0_areg_clk.clkr,
+	[CAMCC_IPE_0_AXI_CLK] = &camcc_ipe_0_axi_clk.clkr,
+	[CAMCC_IPE_0_CLK] = &camcc_ipe_0_clk.clkr,
+	[CAMCC_IPE_0_CLK_SRC] = &camcc_ipe_0_clk_src.clkr,
+	[CAMCC_IPE_1_AHB_CLK] = &camcc_ipe_1_ahb_clk.clkr,
+	[CAMCC_IPE_1_AREG_CLK] = &camcc_ipe_1_areg_clk.clkr,
+	[CAMCC_IPE_1_AXI_CLK] = &camcc_ipe_1_axi_clk.clkr,
+	[CAMCC_IPE_1_CLK] = &camcc_ipe_1_clk.clkr,
+	[CAMCC_JPEG_CLK] = &camcc_jpeg_clk.clkr,
+	[CAMCC_JPEG_CLK_SRC] = &camcc_jpeg_clk_src.clkr,
+	[CAMCC_LRME_CLK] = &camcc_lrme_clk.clkr,
+	[CAMCC_LRME_CLK_SRC] = &camcc_lrme_clk_src.clkr,
+	[CAMCC_MCLK0_CLK] = &camcc_mclk0_clk.clkr,
+	[CAMCC_MCLK0_CLK_SRC] = &camcc_mclk0_clk_src.clkr,
+	[CAMCC_MCLK1_CLK] = &camcc_mclk1_clk.clkr,
+	[CAMCC_MCLK1_CLK_SRC] = &camcc_mclk1_clk_src.clkr,
+	[CAMCC_MCLK2_CLK] = &camcc_mclk2_clk.clkr,
+	[CAMCC_MCLK2_CLK_SRC] = &camcc_mclk2_clk_src.clkr,
+	[CAMCC_MCLK3_CLK] = &camcc_mclk3_clk.clkr,
+	[CAMCC_MCLK3_CLK_SRC] = &camcc_mclk3_clk_src.clkr,
+	[CAMCC_PLL0] = &camcc_pll0.clkr,
+	[CAMCC_PLL1] = &camcc_pll1.clkr,
+	[CAMCC_PLL2] = &camcc_pll2.clkr,
+	[CAMCC_PLL2_OUT_AUX] = &camcc_pll2_out_aux.clkr,
+	[CAMCC_PLL2_OUT_MAIN] = &camcc_pll2_out_main.clkr,
+	[CAMCC_PLL3] = &camcc_pll3.clkr,
+	[CAMCC_PLL4] = &camcc_pll4.clkr,
+	[CAMCC_SLEEP_CLK] = &camcc_sleep_clk.clkr,
+	[CAMCC_SLEEP_CLK_SRC] = &camcc_sleep_clk_src.clkr,
+	[CAMCC_SLOW_AHB_CLK_SRC] = &camcc_slow_ahb_clk_src.clkr,
+	[CAMCC_XO_CLK_SRC] = &camcc_xo_clk_src.clkr,
+};
+
+static struct gdsc *camcc_sm7150_gdscs[] = {
+	[BPS_GDSC] = &camcc_bps_gdsc,
+	[IFE_0_GDSC] = &camcc_ife_0_gdsc,
+	[IFE_1_GDSC] = &camcc_ife_1_gdsc,
+	[IPE_0_GDSC] = &camcc_ipe_0_gdsc,
+	[IPE_1_GDSC] = &camcc_ipe_1_gdsc,
+	[TITAN_TOP_GDSC] = &camcc_titan_top_gdsc,
+};
+
+static const struct regmap_config camcc_sm7150_regmap_config = {
+	.reg_bits	= 32,
+	.reg_stride	= 4,
+	.val_bits	= 32,
+	.max_register	= 0xd024,
+	.fast_io	= true,
+};
+
+static const struct qcom_cc_desc camcc_sm7150_desc = {
+	.config = &camcc_sm7150_regmap_config,
+	.clk_hws = camcc_sm7150_hws,
+	.num_clk_hws = ARRAY_SIZE(camcc_sm7150_hws),
+	.clks = camcc_sm7150_clocks,
+	.num_clks = ARRAY_SIZE(camcc_sm7150_clocks),
+	.gdscs = camcc_sm7150_gdscs,
+	.num_gdscs = ARRAY_SIZE(camcc_sm7150_gdscs),
+};
+
+static const struct of_device_id camcc_sm7150_match_table[] = {
+	{ .compatible = "qcom,sm7150-camcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, camcc_sm7150_match_table);
+
+static int camcc_sm7150_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+
+	regmap = qcom_cc_map(pdev, &camcc_sm7150_desc);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	clk_fabia_pll_configure(&camcc_pll0, regmap, &camcc_pll0_config);
+	clk_fabia_pll_configure(&camcc_pll1, regmap, &camcc_pll1_config);
+	clk_agera_pll_configure(&camcc_pll2, regmap, &camcc_pll2_config);
+	clk_fabia_pll_configure(&camcc_pll3, regmap, &camcc_pll3_config);
+	clk_fabia_pll_configure(&camcc_pll4, regmap, &camcc_pll3_config);
+
+	/* Keep some clocks always-on */
+	qcom_branch_set_clk_en(regmap, 0xc1a0); /* CAMCC_GDSC_CLK */
+
+	return qcom_cc_really_probe(&pdev->dev, &camcc_sm7150_desc, regmap);
+}
+
+static struct platform_driver camcc_sm7150_driver = {
+	.probe = camcc_sm7150_probe,
+	.driver = {
+		.name = "camcc-sm7150",
+		.of_match_table = camcc_sm7150_match_table,
+	},
+};
+
+module_platform_driver(camcc_sm7150_driver);
+
+MODULE_DESCRIPTION("Qualcomm SM7150 Camera Clock Controller");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/camcc-sm8250.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/camcc-sm8250.c
@@ -2433,7 +2433,7 @@
 	clk_lucid_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll3_config);
 	clk_lucid_pll_configure(&cam_cc_pll4, regmap, &cam_cc_pll4_config);
 
-	return qcom_cc_really_probe(pdev, &cam_cc_sm8250_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &cam_cc_sm8250_desc, regmap);
 }
 
 static struct platform_driver cam_cc_sm8250_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/camcc-sm8450.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/camcc-sm8450.c
@@ -2839,7 +2839,7 @@
 	clk_lucid_evo_pll_configure(&cam_cc_pll7, regmap, &cam_cc_pll7_config);
 	clk_lucid_evo_pll_configure(&cam_cc_pll8, regmap, &cam_cc_pll8_config);
 
-	return qcom_cc_really_probe(pdev, &cam_cc_sm8450_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &cam_cc_sm8450_desc, regmap);
 }
 
 static struct platform_driver cam_cc_sm8450_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/camcc-sm8550.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/camcc-sm8550.c
@@ -3544,7 +3544,7 @@
 	regmap_update_bits(regmap, 0x1419c, BIT(0), BIT(0));
 	regmap_update_bits(regmap, 0x142cc, BIT(0), BIT(0));
 
-	ret = qcom_cc_really_probe(pdev, &cam_cc_sm8550_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &cam_cc_sm8550_desc, regmap);
 
 	pm_runtime_put(&pdev->dev);
 
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/camcc-x1e80100.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/camcc-x1e80100.c
@@ -0,0 +1,2486 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,x1e80100-camcc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_BI_TCXO,
+	DT_BI_TCXO_AO,
+	DT_SLEEP_CLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_BI_TCXO_AO,
+	P_CAM_CC_PLL0_OUT_EVEN,
+	P_CAM_CC_PLL0_OUT_MAIN,
+	P_CAM_CC_PLL0_OUT_ODD,
+	P_CAM_CC_PLL1_OUT_EVEN,
+	P_CAM_CC_PLL2_OUT_EVEN,
+	P_CAM_CC_PLL2_OUT_MAIN,
+	P_CAM_CC_PLL3_OUT_EVEN,
+	P_CAM_CC_PLL4_OUT_EVEN,
+	P_CAM_CC_PLL6_OUT_EVEN,
+	P_CAM_CC_PLL8_OUT_EVEN,
+	P_SLEEP_CLK,
+};
+
+static const struct pll_vco lucid_ole_vco[] = {
+	{ 249600000, 2300000000, 0 },
+};
+
+static const struct pll_vco rivian_ole_vco[] = {
+	{ 777000000, 1285000000, 0 },
+};
+
+static const struct alpha_pll_config cam_cc_pll0_config = {
+	.l = 0x3e,
+	.alpha = 0x8000,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x82aa299c,
+	.test_ctl_val = 0x00000000,
+	.test_ctl_hi_val = 0x00000003,
+	.test_ctl_hi1_val = 0x00009000,
+	.test_ctl_hi2_val = 0x00000034,
+	.user_ctl_val = 0x00008400,
+	.user_ctl_hi_val = 0x00000005,
+};
+
+static struct clk_alpha_pll cam_cc_pll0 = {
+	.offset = 0x0,
+	.vco_table = lucid_ole_vco,
+	.num_vco = ARRAY_SIZE(lucid_ole_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_cam_cc_pll0_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = {
+	.offset = 0x0,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_cam_cc_pll0_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_pll0_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&cam_cc_pll0.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_lucid_ole_ops,
+	},
+};
+
+static const struct clk_div_table post_div_table_cam_cc_pll0_out_odd[] = {
+	{ 0x2, 3 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll0_out_odd = {
+	.offset = 0x0,
+	.post_div_shift = 14,
+	.post_div_table = post_div_table_cam_cc_pll0_out_odd,
+	.num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_odd),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_pll0_out_odd",
+		.parent_hws = (const struct clk_hw*[]) {
+			&cam_cc_pll0.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_lucid_ole_ops,
+	},
+};
+
+static const struct alpha_pll_config cam_cc_pll1_config = {
+	.l = 0x1f,
+	.alpha = 0xaaaa,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x82aa299c,
+	.test_ctl_val = 0x00000000,
+	.test_ctl_hi_val = 0x00000003,
+	.test_ctl_hi1_val = 0x00009000,
+	.test_ctl_hi2_val = 0x00000034,
+	.user_ctl_val = 0x00000400,
+	.user_ctl_hi_val = 0x00000005,
+};
+
+static struct clk_alpha_pll cam_cc_pll1 = {
+	.offset = 0x1000,
+	.vco_table = lucid_ole_vco,
+	.num_vco = ARRAY_SIZE(lucid_ole_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll1",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_cam_cc_pll1_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = {
+	.offset = 0x1000,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_cam_cc_pll1_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll1_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_pll1_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&cam_cc_pll1.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_lucid_ole_ops,
+	},
+};
+
+static const struct alpha_pll_config cam_cc_pll2_config = {
+	.l = 0x32,
+	.alpha = 0x0,
+	.config_ctl_val = 0x10000030,
+	.config_ctl_hi_val = 0x80890263,
+	.config_ctl_hi1_val = 0x00000217,
+	.user_ctl_val = 0x00000001,
+	.user_ctl_hi_val = 0x00000000,
+};
+
+static struct clk_alpha_pll cam_cc_pll2 = {
+	.offset = 0x2000,
+	.vco_table = rivian_ole_vco,
+	.num_vco = ARRAY_SIZE(rivian_ole_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_EVO],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll2",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_rivian_evo_ops,
+		},
+	},
+};
+
+static const struct alpha_pll_config cam_cc_pll3_config = {
+	.l = 0x24,
+	.alpha = 0x0,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x82aa299c,
+	.test_ctl_val = 0x00000000,
+	.test_ctl_hi_val = 0x00000003,
+	.test_ctl_hi1_val = 0x00009000,
+	.test_ctl_hi2_val = 0x00000034,
+	.user_ctl_val = 0x00000400,
+	.user_ctl_hi_val = 0x00000005,
+};
+
+static struct clk_alpha_pll cam_cc_pll3 = {
+	.offset = 0x3000,
+	.vco_table = lucid_ole_vco,
+	.num_vco = ARRAY_SIZE(lucid_ole_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll3",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_cam_cc_pll3_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll3_out_even = {
+	.offset = 0x3000,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_cam_cc_pll3_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll3_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_pll3_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&cam_cc_pll3.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_lucid_ole_ops,
+	},
+};
+
+static const struct alpha_pll_config cam_cc_pll4_config = {
+	.l = 0x24,
+	.alpha = 0x0,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x82aa299c,
+	.test_ctl_val = 0x00000000,
+	.test_ctl_hi_val = 0x00000003,
+	.test_ctl_hi1_val = 0x00009000,
+	.test_ctl_hi2_val = 0x00000034,
+	.user_ctl_val = 0x00000400,
+	.user_ctl_hi_val = 0x00000005,
+};
+
+static struct clk_alpha_pll cam_cc_pll4 = {
+	.offset = 0x4000,
+	.vco_table = lucid_ole_vco,
+	.num_vco = ARRAY_SIZE(lucid_ole_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll4",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_cam_cc_pll4_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll4_out_even = {
+	.offset = 0x4000,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_cam_cc_pll4_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll4_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_pll4_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&cam_cc_pll4.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_lucid_ole_ops,
+	},
+};
+
+static const struct alpha_pll_config cam_cc_pll6_config = {
+	.l = 0x24,
+	.alpha = 0x0,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x82aa299c,
+	.test_ctl_val = 0x00000000,
+	.test_ctl_hi_val = 0x00000003,
+	.test_ctl_hi1_val = 0x00009000,
+	.test_ctl_hi2_val = 0x00000034,
+	.user_ctl_val = 0x00000400,
+	.user_ctl_hi_val = 0x00000005,
+};
+
+static struct clk_alpha_pll cam_cc_pll6 = {
+	.offset = 0x6000,
+	.vco_table = lucid_ole_vco,
+	.num_vco = ARRAY_SIZE(lucid_ole_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll6",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_cam_cc_pll6_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll6_out_even = {
+	.offset = 0x6000,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_cam_cc_pll6_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll6_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_pll6_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&cam_cc_pll6.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_lucid_ole_ops,
+	},
+};
+
+static const struct alpha_pll_config cam_cc_pll8_config = {
+	.l = 0x32,
+	.alpha = 0x0,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x82aa299c,
+	.test_ctl_val = 0x00000000,
+	.test_ctl_hi_val = 0x00000003,
+	.test_ctl_hi1_val = 0x00009000,
+	.test_ctl_hi2_val = 0x00000034,
+	.user_ctl_val = 0x00000400,
+	.user_ctl_hi_val = 0x00000005,
+};
+
+static struct clk_alpha_pll cam_cc_pll8 = {
+	.offset = 0x8000,
+	.vco_table = lucid_ole_vco,
+	.num_vco = ARRAY_SIZE(lucid_ole_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_pll8",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_cam_cc_pll8_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv cam_cc_pll8_out_even = {
+	.offset = 0x8000,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_cam_cc_pll8_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll8_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_pll8_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&cam_cc_pll8.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_lucid_ole_ops,
+	},
+};
+
+static const struct parent_map cam_cc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL0_OUT_MAIN, 1 },
+	{ P_CAM_CC_PLL0_OUT_EVEN, 2 },
+	{ P_CAM_CC_PLL0_OUT_ODD, 3 },
+	{ P_CAM_CC_PLL8_OUT_EVEN, 5 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll0.clkr.hw },
+	{ .hw = &cam_cc_pll0_out_even.clkr.hw },
+	{ .hw = &cam_cc_pll0_out_odd.clkr.hw },
+	{ .hw = &cam_cc_pll8_out_even.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL2_OUT_EVEN, 3 },
+	{ P_CAM_CC_PLL2_OUT_MAIN, 5 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll2.clkr.hw },
+	{ .hw = &cam_cc_pll2.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL3_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll3_out_even.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL4_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll4_out_even.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_4[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL1_OUT_EVEN, 4 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_4[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll1_out_even.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_5[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_CAM_CC_PLL6_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_5[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &cam_cc_pll6_out_even.clkr.hw },
+};
+
+static const struct parent_map cam_cc_parent_map_6[] = {
+	{ P_SLEEP_CLK, 0 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_6_ao[] = {
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map cam_cc_parent_map_7[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data cam_cc_parent_data_7_ao[] = {
+	{ .index = DT_BI_TCXO_AO },
+};
+
+static const struct freq_tbl ftbl_cam_cc_bps_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(160000000, P_CAM_CC_PLL0_OUT_ODD, 2.5, 0, 0),
+	F(200000000, P_CAM_CC_PLL0_OUT_ODD, 2, 0, 0),
+	F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0),
+	F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_bps_clk_src = {
+	.cmd_rcgr = 0x10278,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_bps_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_bps_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_camnoc_axi_rt_clk_src[] = {
+	F(240000000, P_CAM_CC_PLL0_OUT_EVEN, 2.5, 0, 0),
+	F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0),
+	F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_camnoc_axi_rt_clk_src = {
+	.cmd_rcgr = 0x138f8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_camnoc_axi_rt_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_camnoc_axi_rt_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_cci_0_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(30000000, P_CAM_CC_PLL8_OUT_EVEN, 16, 0, 0),
+	F(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_cci_0_clk_src = {
+	.cmd_rcgr = 0x1365c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_cci_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_cci_0_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_cci_1_clk_src = {
+	.cmd_rcgr = 0x1378c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_cci_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_cci_1_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(300000000, P_CAM_CC_PLL0_OUT_MAIN, 4, 0, 0),
+	F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_cphy_rx_clk_src = {
+	.cmd_rcgr = 0x11164,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_cphy_rx_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_cphy_rx_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_csi0phytimer_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(266666667, P_CAM_CC_PLL0_OUT_ODD, 1.5, 0, 0),
+	F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = {
+	.cmd_rcgr = 0x150e0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csi0phytimer_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = {
+	.cmd_rcgr = 0x15104,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csi1phytimer_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = {
+	.cmd_rcgr = 0x15124,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csi2phytimer_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = {
+	.cmd_rcgr = 0x15258,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csi3phytimer_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_csi4phytimer_clk_src = {
+	.cmd_rcgr = 0x1538c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csi4phytimer_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_csi5phytimer_clk_src = {
+	.cmd_rcgr = 0x154c0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csi5phytimer_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_csid_clk_src[] = {
+	F(300000000, P_CAM_CC_PLL0_OUT_MAIN, 4, 0, 0),
+	F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_csid_clk_src = {
+	.cmd_rcgr = 0x138d4,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_csid_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_csid_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_fast_ahb_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(80000000, P_CAM_CC_PLL0_OUT_EVEN, 7.5, 0, 0),
+	F(100000000, P_CAM_CC_PLL0_OUT_EVEN, 6, 0, 0),
+	F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0),
+	F(300000000, P_CAM_CC_PLL0_OUT_MAIN, 4, 0, 0),
+	F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_fast_ahb_clk_src = {
+	.cmd_rcgr = 0x10018,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_fast_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_fast_ahb_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_icp_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0),
+	F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0),
+	F(480000000, P_CAM_CC_PLL8_OUT_EVEN, 1, 0, 0),
+	F(600000000, P_CAM_CC_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_icp_clk_src = {
+	.cmd_rcgr = 0x13520,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_icp_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_icp_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_ife_0_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(345600000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0),
+	F(432000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0),
+	F(594000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0),
+	F(675000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0),
+	F(727000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_ife_0_clk_src = {
+	.cmd_rcgr = 0x11018,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_2,
+	.freq_tbl = ftbl_cam_cc_ife_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ife_0_clk_src",
+		.parent_data = cam_cc_parent_data_2,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_ife_1_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(345600000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0),
+	F(432000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0),
+	F(594000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0),
+	F(675000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0),
+	F(727000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_ife_1_clk_src = {
+	.cmd_rcgr = 0x12018,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_3,
+	.freq_tbl = ftbl_cam_cc_ife_1_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ife_1_clk_src",
+		.parent_data = cam_cc_parent_data_3,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_ife_lite_clk_src[] = {
+	F(266666667, P_CAM_CC_PLL0_OUT_ODD, 1.5, 0, 0),
+	F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0),
+	F(480000000, P_CAM_CC_PLL8_OUT_EVEN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_ife_lite_clk_src = {
+	.cmd_rcgr = 0x13000,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_ife_lite_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ife_lite_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = {
+	.cmd_rcgr = 0x1313c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_ife_lite_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ife_lite_csid_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_ipe_nps_clk_src[] = {
+	F(304000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0),
+	F(364000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0),
+	F(500000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0),
+	F(600000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0),
+	F(700000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_ipe_nps_clk_src = {
+	.cmd_rcgr = 0x103cc,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_4,
+	.freq_tbl = ftbl_cam_cc_ipe_nps_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_ipe_nps_clk_src",
+		.parent_data = cam_cc_parent_data_4,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_jpeg_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(160000000, P_CAM_CC_PLL0_OUT_ODD, 2.5, 0, 0),
+	F(200000000, P_CAM_CC_PLL0_OUT_ODD, 2, 0, 0),
+	F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0),
+	F(480000000, P_CAM_CC_PLL8_OUT_EVEN, 1, 0, 0),
+	F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_jpeg_clk_src = {
+	.cmd_rcgr = 0x133dc,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_jpeg_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_jpeg_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_mclk0_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(24000000, P_CAM_CC_PLL2_OUT_MAIN, 10, 1, 4),
+	F(68571429, P_CAM_CC_PLL2_OUT_MAIN, 14, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_mclk0_clk_src = {
+	.cmd_rcgr = 0x15000,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk0_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_mclk1_clk_src = {
+	.cmd_rcgr = 0x1501c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk1_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_mclk2_clk_src = {
+	.cmd_rcgr = 0x15038,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk2_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_mclk3_clk_src = {
+	.cmd_rcgr = 0x15054,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk3_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_mclk4_clk_src = {
+	.cmd_rcgr = 0x15070,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk4_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_mclk5_clk_src = {
+	.cmd_rcgr = 0x1508c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk5_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_mclk6_clk_src = {
+	.cmd_rcgr = 0x150a8,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk6_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 cam_cc_mclk7_clk_src = {
+	.cmd_rcgr = 0x150c4,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_1,
+	.freq_tbl = ftbl_cam_cc_mclk0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_mclk7_clk_src",
+		.parent_data = cam_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_sfe_0_clk_src[] = {
+	F(345600000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0),
+	F(432000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0),
+	F(594000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0),
+	F(675000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0),
+	F(727000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_sfe_0_clk_src = {
+	.cmd_rcgr = 0x13294,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_5,
+	.freq_tbl = ftbl_cam_cc_sfe_0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_sfe_0_clk_src",
+		.parent_data = cam_cc_parent_data_5,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_5),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_sleep_clk_src[] = {
+	F(32000, P_SLEEP_CLK, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_sleep_clk_src = {
+	.cmd_rcgr = 0x13aa0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_6,
+	.freq_tbl = ftbl_cam_cc_sleep_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_sleep_clk_src",
+		.parent_data = cam_cc_parent_data_6_ao,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_6_ao),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(64000000, P_CAM_CC_PLL8_OUT_EVEN, 7.5, 0, 0),
+	F(80000000, P_CAM_CC_PLL0_OUT_EVEN, 7.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_slow_ahb_clk_src = {
+	.cmd_rcgr = 0x10148,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_0,
+	.freq_tbl = ftbl_cam_cc_slow_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_slow_ahb_clk_src",
+		.parent_data = cam_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_cam_cc_xo_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 cam_cc_xo_clk_src = {
+	.cmd_rcgr = 0x13a84,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = cam_cc_parent_map_7,
+	.freq_tbl = ftbl_cam_cc_xo_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "cam_cc_xo_clk_src",
+		.parent_data = cam_cc_parent_data_7_ao,
+		.num_parents = ARRAY_SIZE(cam_cc_parent_data_7_ao),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_branch cam_cc_bps_ahb_clk = {
+	.halt_reg = 0x10274,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x10274,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_bps_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_bps_clk = {
+	.halt_reg = 0x103a4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x103a4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_bps_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_bps_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_bps_fast_ahb_clk = {
+	.halt_reg = 0x10144,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x10144,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_bps_fast_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_camnoc_axi_nrt_clk = {
+	.halt_reg = 0x13920,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13920,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_camnoc_axi_nrt_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_camnoc_axi_rt_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_camnoc_axi_rt_clk = {
+	.halt_reg = 0x13910,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13910,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_camnoc_axi_rt_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_camnoc_axi_rt_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_camnoc_dcd_xo_clk = {
+	.halt_reg = 0x1392c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1392c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_camnoc_dcd_xo_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_camnoc_xo_clk = {
+	.halt_reg = 0x13930,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13930,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_camnoc_xo_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cci_0_clk = {
+	.halt_reg = 0x13788,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13788,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cci_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cci_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cci_1_clk = {
+	.halt_reg = 0x138b8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x138b8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cci_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cci_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_core_ahb_clk = {
+	.halt_reg = 0x13a80,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x13a80,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_core_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_ahb_clk = {
+	.halt_reg = 0x138bc,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x138bc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_bps_clk = {
+	.halt_reg = 0x103b0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x103b0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_bps_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_bps_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_fast_ahb_clk = {
+	.halt_reg = 0x138c8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x138c8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_fast_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_ife_0_clk = {
+	.halt_reg = 0x11150,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x11150,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_ife_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_ife_1_clk = {
+	.halt_reg = 0x1203c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1203c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_ife_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_ife_lite_clk = {
+	.halt_reg = 0x13138,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13138,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_ife_lite_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_lite_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_ipe_nps_clk = {
+	.halt_reg = 0x10504,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x10504,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_ipe_nps_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ipe_nps_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_cpas_sfe_0_clk = {
+	.halt_reg = 0x133cc,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x133cc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_cpas_sfe_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_sfe_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csi0phytimer_clk = {
+	.halt_reg = 0x150f8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x150f8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csi0phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csi0phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csi1phytimer_clk = {
+	.halt_reg = 0x1511c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1511c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csi1phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csi1phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csi2phytimer_clk = {
+	.halt_reg = 0x15250,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15250,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csi2phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csi2phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csi3phytimer_clk = {
+	.halt_reg = 0x15384,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15384,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csi3phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csi3phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csi4phytimer_clk = {
+	.halt_reg = 0x154b8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x154b8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csi4phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csi4phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csi5phytimer_clk = {
+	.halt_reg = 0x155ec,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x155ec,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csi5phytimer_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csi5phytimer_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csid_clk = {
+	.halt_reg = 0x138ec,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x138ec,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csid_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_csid_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csid_csiphy_rx_clk = {
+	.halt_reg = 0x15100,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15100,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csid_csiphy_rx_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csiphy0_clk = {
+	.halt_reg = 0x150fc,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x150fc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csiphy0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csiphy1_clk = {
+	.halt_reg = 0x15120,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15120,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csiphy1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csiphy2_clk = {
+	.halt_reg = 0x15254,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15254,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csiphy2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csiphy3_clk = {
+	.halt_reg = 0x15388,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15388,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csiphy3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csiphy4_clk = {
+	.halt_reg = 0x154bc,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x154bc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csiphy4_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_csiphy5_clk = {
+	.halt_reg = 0x155f0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x155f0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_csiphy5_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_icp_ahb_clk = {
+	.halt_reg = 0x13658,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13658,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_icp_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_icp_clk = {
+	.halt_reg = 0x1364c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1364c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_icp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_icp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_0_clk = {
+	.halt_reg = 0x11144,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x11144,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_0_dsp_clk = {
+	.halt_reg = 0x11154,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x11154,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_0_dsp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_0_fast_ahb_clk = {
+	.halt_reg = 0x11160,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x11160,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_0_fast_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_1_clk = {
+	.halt_reg = 0x12030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x12030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_1_dsp_clk = {
+	.halt_reg = 0x12040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x12040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_1_dsp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_1_fast_ahb_clk = {
+	.halt_reg = 0x1204c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1204c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_1_fast_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_lite_ahb_clk = {
+	.halt_reg = 0x13278,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13278,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_lite_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_lite_clk = {
+	.halt_reg = 0x1312c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1312c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_lite_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_lite_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_lite_cphy_rx_clk = {
+	.halt_reg = 0x13274,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13274,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_lite_cphy_rx_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_cphy_rx_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ife_lite_csid_clk = {
+	.halt_reg = 0x13268,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13268,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ife_lite_csid_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ife_lite_csid_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ipe_nps_ahb_clk = {
+	.halt_reg = 0x1051c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1051c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ipe_nps_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_slow_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ipe_nps_clk = {
+	.halt_reg = 0x104f8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x104f8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ipe_nps_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ipe_nps_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ipe_nps_fast_ahb_clk = {
+	.halt_reg = 0x10520,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x10520,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ipe_nps_fast_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ipe_pps_clk = {
+	.halt_reg = 0x10508,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x10508,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ipe_pps_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_ipe_nps_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_ipe_pps_fast_ahb_clk = {
+	.halt_reg = 0x10524,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x10524,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_ipe_pps_fast_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_jpeg_clk = {
+	.halt_reg = 0x13508,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x13508,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_jpeg_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_jpeg_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk0_clk = {
+	.halt_reg = 0x15018,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk1_clk = {
+	.halt_reg = 0x15034,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15034,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk2_clk = {
+	.halt_reg = 0x15050,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15050,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk3_clk = {
+	.halt_reg = 0x1506c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1506c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk4_clk = {
+	.halt_reg = 0x15088,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x15088,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk4_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk4_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk5_clk = {
+	.halt_reg = 0x150a4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x150a4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk5_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk5_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk6_clk = {
+	.halt_reg = 0x150c0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x150c0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk6_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk6_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_mclk7_clk = {
+	.halt_reg = 0x150dc,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x150dc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_mclk7_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_mclk7_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_sfe_0_clk = {
+	.halt_reg = 0x133c0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x133c0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_sfe_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_sfe_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch cam_cc_sfe_0_fast_ahb_clk = {
+	.halt_reg = 0x133d8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x133d8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "cam_cc_sfe_0_fast_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&cam_cc_fast_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc cam_cc_bps_gdsc = {
+	.gdscr = 0x10004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "cam_cc_bps_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc cam_cc_ife_0_gdsc = {
+	.gdscr = 0x11004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "cam_cc_ife_0_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc cam_cc_ife_1_gdsc = {
+	.gdscr = 0x12004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "cam_cc_ife_1_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc cam_cc_ipe_0_gdsc = {
+	.gdscr = 0x103b8,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "cam_cc_ipe_0_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc cam_cc_sfe_0_gdsc = {
+	.gdscr = 0x13280,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "cam_cc_sfe_0_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc cam_cc_titan_top_gdsc = {
+	.gdscr = 0x13a6c,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "cam_cc_titan_top_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct clk_regmap *cam_cc_x1e80100_clocks[] = {
+	[CAM_CC_BPS_AHB_CLK] = &cam_cc_bps_ahb_clk.clkr,
+	[CAM_CC_BPS_CLK] = &cam_cc_bps_clk.clkr,
+	[CAM_CC_BPS_CLK_SRC] = &cam_cc_bps_clk_src.clkr,
+	[CAM_CC_BPS_FAST_AHB_CLK] = &cam_cc_bps_fast_ahb_clk.clkr,
+	[CAM_CC_CAMNOC_AXI_NRT_CLK] = &cam_cc_camnoc_axi_nrt_clk.clkr,
+	[CAM_CC_CAMNOC_AXI_RT_CLK] = &cam_cc_camnoc_axi_rt_clk.clkr,
+	[CAM_CC_CAMNOC_AXI_RT_CLK_SRC] = &cam_cc_camnoc_axi_rt_clk_src.clkr,
+	[CAM_CC_CAMNOC_DCD_XO_CLK] = &cam_cc_camnoc_dcd_xo_clk.clkr,
+	[CAM_CC_CAMNOC_XO_CLK] = &cam_cc_camnoc_xo_clk.clkr,
+	[CAM_CC_CCI_0_CLK] = &cam_cc_cci_0_clk.clkr,
+	[CAM_CC_CCI_0_CLK_SRC] = &cam_cc_cci_0_clk_src.clkr,
+	[CAM_CC_CCI_1_CLK] = &cam_cc_cci_1_clk.clkr,
+	[CAM_CC_CCI_1_CLK_SRC] = &cam_cc_cci_1_clk_src.clkr,
+	[CAM_CC_CORE_AHB_CLK] = &cam_cc_core_ahb_clk.clkr,
+	[CAM_CC_CPAS_AHB_CLK] = &cam_cc_cpas_ahb_clk.clkr,
+	[CAM_CC_CPAS_BPS_CLK] = &cam_cc_cpas_bps_clk.clkr,
+	[CAM_CC_CPAS_FAST_AHB_CLK] = &cam_cc_cpas_fast_ahb_clk.clkr,
+	[CAM_CC_CPAS_IFE_0_CLK] = &cam_cc_cpas_ife_0_clk.clkr,
+	[CAM_CC_CPAS_IFE_1_CLK] = &cam_cc_cpas_ife_1_clk.clkr,
+	[CAM_CC_CPAS_IFE_LITE_CLK] = &cam_cc_cpas_ife_lite_clk.clkr,
+	[CAM_CC_CPAS_IPE_NPS_CLK] = &cam_cc_cpas_ipe_nps_clk.clkr,
+	[CAM_CC_CPAS_SFE_0_CLK] = &cam_cc_cpas_sfe_0_clk.clkr,
+	[CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr,
+	[CAM_CC_CSI0PHYTIMER_CLK] = &cam_cc_csi0phytimer_clk.clkr,
+	[CAM_CC_CSI0PHYTIMER_CLK_SRC] = &cam_cc_csi0phytimer_clk_src.clkr,
+	[CAM_CC_CSI1PHYTIMER_CLK] = &cam_cc_csi1phytimer_clk.clkr,
+	[CAM_CC_CSI1PHYTIMER_CLK_SRC] = &cam_cc_csi1phytimer_clk_src.clkr,
+	[CAM_CC_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr,
+	[CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr,
+	[CAM_CC_CSI3PHYTIMER_CLK] = &cam_cc_csi3phytimer_clk.clkr,
+	[CAM_CC_CSI3PHYTIMER_CLK_SRC] = &cam_cc_csi3phytimer_clk_src.clkr,
+	[CAM_CC_CSI4PHYTIMER_CLK] = &cam_cc_csi4phytimer_clk.clkr,
+	[CAM_CC_CSI4PHYTIMER_CLK_SRC] = &cam_cc_csi4phytimer_clk_src.clkr,
+	[CAM_CC_CSI5PHYTIMER_CLK] = &cam_cc_csi5phytimer_clk.clkr,
+	[CAM_CC_CSI5PHYTIMER_CLK_SRC] = &cam_cc_csi5phytimer_clk_src.clkr,
+	[CAM_CC_CSID_CLK] = &cam_cc_csid_clk.clkr,
+	[CAM_CC_CSID_CLK_SRC] = &cam_cc_csid_clk_src.clkr,
+	[CAM_CC_CSID_CSIPHY_RX_CLK] = &cam_cc_csid_csiphy_rx_clk.clkr,
+	[CAM_CC_CSIPHY0_CLK] = &cam_cc_csiphy0_clk.clkr,
+	[CAM_CC_CSIPHY1_CLK] = &cam_cc_csiphy1_clk.clkr,
+	[CAM_CC_CSIPHY2_CLK] = &cam_cc_csiphy2_clk.clkr,
+	[CAM_CC_CSIPHY3_CLK] = &cam_cc_csiphy3_clk.clkr,
+	[CAM_CC_CSIPHY4_CLK] = &cam_cc_csiphy4_clk.clkr,
+	[CAM_CC_CSIPHY5_CLK] = &cam_cc_csiphy5_clk.clkr,
+	[CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr,
+	[CAM_CC_ICP_AHB_CLK] = &cam_cc_icp_ahb_clk.clkr,
+	[CAM_CC_ICP_CLK] = &cam_cc_icp_clk.clkr,
+	[CAM_CC_ICP_CLK_SRC] = &cam_cc_icp_clk_src.clkr,
+	[CAM_CC_IFE_0_CLK] = &cam_cc_ife_0_clk.clkr,
+	[CAM_CC_IFE_0_CLK_SRC] = &cam_cc_ife_0_clk_src.clkr,
+	[CAM_CC_IFE_0_DSP_CLK] = &cam_cc_ife_0_dsp_clk.clkr,
+	[CAM_CC_IFE_0_FAST_AHB_CLK] = &cam_cc_ife_0_fast_ahb_clk.clkr,
+	[CAM_CC_IFE_1_CLK] = &cam_cc_ife_1_clk.clkr,
+	[CAM_CC_IFE_1_CLK_SRC] = &cam_cc_ife_1_clk_src.clkr,
+	[CAM_CC_IFE_1_DSP_CLK] = &cam_cc_ife_1_dsp_clk.clkr,
+	[CAM_CC_IFE_1_FAST_AHB_CLK] = &cam_cc_ife_1_fast_ahb_clk.clkr,
+	[CAM_CC_IFE_LITE_AHB_CLK] = &cam_cc_ife_lite_ahb_clk.clkr,
+	[CAM_CC_IFE_LITE_CLK] = &cam_cc_ife_lite_clk.clkr,
+	[CAM_CC_IFE_LITE_CLK_SRC] = &cam_cc_ife_lite_clk_src.clkr,
+	[CAM_CC_IFE_LITE_CPHY_RX_CLK] = &cam_cc_ife_lite_cphy_rx_clk.clkr,
+	[CAM_CC_IFE_LITE_CSID_CLK] = &cam_cc_ife_lite_csid_clk.clkr,
+	[CAM_CC_IFE_LITE_CSID_CLK_SRC] = &cam_cc_ife_lite_csid_clk_src.clkr,
+	[CAM_CC_IPE_NPS_AHB_CLK] = &cam_cc_ipe_nps_ahb_clk.clkr,
+	[CAM_CC_IPE_NPS_CLK] = &cam_cc_ipe_nps_clk.clkr,
+	[CAM_CC_IPE_NPS_CLK_SRC] = &cam_cc_ipe_nps_clk_src.clkr,
+	[CAM_CC_IPE_NPS_FAST_AHB_CLK] = &cam_cc_ipe_nps_fast_ahb_clk.clkr,
+	[CAM_CC_IPE_PPS_CLK] = &cam_cc_ipe_pps_clk.clkr,
+	[CAM_CC_IPE_PPS_FAST_AHB_CLK] = &cam_cc_ipe_pps_fast_ahb_clk.clkr,
+	[CAM_CC_JPEG_CLK] = &cam_cc_jpeg_clk.clkr,
+	[CAM_CC_JPEG_CLK_SRC] = &cam_cc_jpeg_clk_src.clkr,
+	[CAM_CC_MCLK0_CLK] = &cam_cc_mclk0_clk.clkr,
+	[CAM_CC_MCLK0_CLK_SRC] = &cam_cc_mclk0_clk_src.clkr,
+	[CAM_CC_MCLK1_CLK] = &cam_cc_mclk1_clk.clkr,
+	[CAM_CC_MCLK1_CLK_SRC] = &cam_cc_mclk1_clk_src.clkr,
+	[CAM_CC_MCLK2_CLK] = &cam_cc_mclk2_clk.clkr,
+	[CAM_CC_MCLK2_CLK_SRC] = &cam_cc_mclk2_clk_src.clkr,
+	[CAM_CC_MCLK3_CLK] = &cam_cc_mclk3_clk.clkr,
+	[CAM_CC_MCLK3_CLK_SRC] = &cam_cc_mclk3_clk_src.clkr,
+	[CAM_CC_MCLK4_CLK] = &cam_cc_mclk4_clk.clkr,
+	[CAM_CC_MCLK4_CLK_SRC] = &cam_cc_mclk4_clk_src.clkr,
+	[CAM_CC_MCLK5_CLK] = &cam_cc_mclk5_clk.clkr,
+	[CAM_CC_MCLK5_CLK_SRC] = &cam_cc_mclk5_clk_src.clkr,
+	[CAM_CC_MCLK6_CLK] = &cam_cc_mclk6_clk.clkr,
+	[CAM_CC_MCLK6_CLK_SRC] = &cam_cc_mclk6_clk_src.clkr,
+	[CAM_CC_MCLK7_CLK] = &cam_cc_mclk7_clk.clkr,
+	[CAM_CC_MCLK7_CLK_SRC] = &cam_cc_mclk7_clk_src.clkr,
+	[CAM_CC_PLL0] = &cam_cc_pll0.clkr,
+	[CAM_CC_PLL0_OUT_EVEN] = &cam_cc_pll0_out_even.clkr,
+	[CAM_CC_PLL0_OUT_ODD] = &cam_cc_pll0_out_odd.clkr,
+	[CAM_CC_PLL1] = &cam_cc_pll1.clkr,
+	[CAM_CC_PLL1_OUT_EVEN] = &cam_cc_pll1_out_even.clkr,
+	[CAM_CC_PLL2] = &cam_cc_pll2.clkr,
+	[CAM_CC_PLL3] = &cam_cc_pll3.clkr,
+	[CAM_CC_PLL3_OUT_EVEN] = &cam_cc_pll3_out_even.clkr,
+	[CAM_CC_PLL4] = &cam_cc_pll4.clkr,
+	[CAM_CC_PLL4_OUT_EVEN] = &cam_cc_pll4_out_even.clkr,
+	[CAM_CC_PLL6] = &cam_cc_pll6.clkr,
+	[CAM_CC_PLL6_OUT_EVEN] = &cam_cc_pll6_out_even.clkr,
+	[CAM_CC_PLL8] = &cam_cc_pll8.clkr,
+	[CAM_CC_PLL8_OUT_EVEN] = &cam_cc_pll8_out_even.clkr,
+	[CAM_CC_SFE_0_CLK] = &cam_cc_sfe_0_clk.clkr,
+	[CAM_CC_SFE_0_CLK_SRC] = &cam_cc_sfe_0_clk_src.clkr,
+	[CAM_CC_SFE_0_FAST_AHB_CLK] = &cam_cc_sfe_0_fast_ahb_clk.clkr,
+	[CAM_CC_SLEEP_CLK_SRC] = &cam_cc_sleep_clk_src.clkr,
+	[CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr,
+	[CAM_CC_XO_CLK_SRC] = &cam_cc_xo_clk_src.clkr,
+};
+
+static struct gdsc *cam_cc_x1e80100_gdscs[] = {
+	[CAM_CC_BPS_GDSC] = &cam_cc_bps_gdsc,
+	[CAM_CC_IFE_0_GDSC] = &cam_cc_ife_0_gdsc,
+	[CAM_CC_IFE_1_GDSC] = &cam_cc_ife_1_gdsc,
+	[CAM_CC_IPE_0_GDSC] = &cam_cc_ipe_0_gdsc,
+	[CAM_CC_SFE_0_GDSC] = &cam_cc_sfe_0_gdsc,
+	[CAM_CC_TITAN_TOP_GDSC] = &cam_cc_titan_top_gdsc,
+};
+
+static const struct qcom_reset_map cam_cc_x1e80100_resets[] = {
+	[CAM_CC_BPS_BCR] = { 0x10000 },
+	[CAM_CC_ICP_BCR] = { 0x1351c },
+	[CAM_CC_IFE_0_BCR] = { 0x11000 },
+	[CAM_CC_IFE_1_BCR] = { 0x12000 },
+	[CAM_CC_IPE_0_BCR] = { 0x103b4 },
+	[CAM_CC_SFE_0_BCR] = { 0x1327c },
+};
+
+static const struct regmap_config cam_cc_x1e80100_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x1603c,
+	.fast_io = true,
+};
+
+static const struct qcom_cc_desc cam_cc_x1e80100_desc = {
+	.config = &cam_cc_x1e80100_regmap_config,
+	.clks = cam_cc_x1e80100_clocks,
+	.num_clks = ARRAY_SIZE(cam_cc_x1e80100_clocks),
+	.resets = cam_cc_x1e80100_resets,
+	.num_resets = ARRAY_SIZE(cam_cc_x1e80100_resets),
+	.gdscs = cam_cc_x1e80100_gdscs,
+	.num_gdscs = ARRAY_SIZE(cam_cc_x1e80100_gdscs),
+};
+
+static const struct of_device_id cam_cc_x1e80100_match_table[] = {
+	{ .compatible = "qcom,x1e80100-camcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, cam_cc_x1e80100_match_table);
+
+static int cam_cc_x1e80100_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+	int ret;
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret)
+		return ret;
+
+	regmap = qcom_cc_map(pdev, &cam_cc_x1e80100_desc);
+	if (IS_ERR(regmap)) {
+		pm_runtime_put(&pdev->dev);
+		return PTR_ERR(regmap);
+	}
+
+	clk_lucid_ole_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll0_config);
+	clk_lucid_ole_pll_configure(&cam_cc_pll1, regmap, &cam_cc_pll1_config);
+	clk_rivian_evo_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll2_config);
+	clk_lucid_ole_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll3_config);
+	clk_lucid_ole_pll_configure(&cam_cc_pll4, regmap, &cam_cc_pll4_config);
+	clk_lucid_ole_pll_configure(&cam_cc_pll6, regmap, &cam_cc_pll6_config);
+	clk_lucid_ole_pll_configure(&cam_cc_pll8, regmap, &cam_cc_pll8_config);
+
+	/* Keep clocks always enabled */
+	regmap_update_bits(regmap, 0x13a9c, BIT(0), BIT(0)); /* cam_cc_gdsc_clk */
+	regmap_update_bits(regmap, 0x13ab8, BIT(0), BIT(0)); /* cam_cc_sleep_clk */
+
+	ret = qcom_cc_really_probe(&pdev->dev, &cam_cc_x1e80100_desc, regmap);
+
+	pm_runtime_put(&pdev->dev);
+
+	return ret;
+}
+
+static struct platform_driver cam_cc_x1e80100_driver = {
+	.probe = cam_cc_x1e80100_probe,
+	.driver = {
+		.name = "camcc-x1e80100",
+		.of_match_table = cam_cc_x1e80100_match_table,
+	},
+};
+
+module_platform_driver(cam_cc_x1e80100_driver);
+
+MODULE_DESCRIPTION("QTI Camera Clock Controller X1E80100 Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/clk-alpha-pll.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/clk-alpha-pll.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2015, 2018, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021, 2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021, 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/kernel.h>
@@ -40,7 +40,7 @@
 
 #define PLL_USER_CTL(p)		((p)->offset + (p)->regs[PLL_OFF_USER_CTL])
 # define PLL_POST_DIV_SHIFT	8
-# define PLL_POST_DIV_MASK(p)	GENMASK((p)->width, 0)
+# define PLL_POST_DIV_MASK(p)	GENMASK((p)->width ? (p)->width - 1 : 3, 0)
 # define PLL_ALPHA_EN		BIT(24)
 # define PLL_ALPHA_MODE		BIT(25)
 # define PLL_VCO_SHIFT		20
@@ -52,6 +52,7 @@
 #define PLL_CONFIG_CTL(p)	((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL])
 #define PLL_CONFIG_CTL_U(p)	((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U])
 #define PLL_CONFIG_CTL_U1(p)	((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U1])
+#define PLL_CONFIG_CTL_U2(p)	((p)->offset + (p)->regs[PLL_OFF_CONFIG_CTL_U2])
 #define PLL_TEST_CTL(p)		((p)->offset + (p)->regs[PLL_OFF_TEST_CTL])
 #define PLL_TEST_CTL_U(p)	((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U])
 #define PLL_TEST_CTL_U1(p)     ((p)->offset + (p)->regs[PLL_OFF_TEST_CTL_U1])
@@ -212,7 +213,6 @@
 		[PLL_OFF_USER_CTL] = 0x18,
 		[PLL_OFF_USER_CTL_U] = 0x1c,
 		[PLL_OFF_CONFIG_CTL] = 0x20,
-		[PLL_OFF_CONFIG_CTL_U] = 0xff,
 		[PLL_OFF_TEST_CTL] = 0x30,
 		[PLL_OFF_TEST_CTL_U] = 0x34,
 		[PLL_OFF_STATUS] = 0x28,
@@ -228,6 +228,32 @@
 		[PLL_OFF_ALPHA_VAL] = 0x24,
 		[PLL_OFF_ALPHA_VAL_U] = 0x28,
 	},
+	[CLK_ALPHA_PLL_TYPE_ZONDA_OLE] =  {
+		[PLL_OFF_L_VAL] = 0x04,
+		[PLL_OFF_ALPHA_VAL] = 0x08,
+		[PLL_OFF_USER_CTL] = 0x0c,
+		[PLL_OFF_USER_CTL_U] = 0x10,
+		[PLL_OFF_CONFIG_CTL] = 0x14,
+		[PLL_OFF_CONFIG_CTL_U] = 0x18,
+		[PLL_OFF_CONFIG_CTL_U1] = 0x1c,
+		[PLL_OFF_CONFIG_CTL_U2] = 0x20,
+		[PLL_OFF_TEST_CTL] = 0x24,
+		[PLL_OFF_TEST_CTL_U] = 0x28,
+		[PLL_OFF_TEST_CTL_U1] = 0x2c,
+		[PLL_OFF_OPMODE] = 0x30,
+		[PLL_OFF_STATUS] = 0x3c,
+	},
+	[CLK_ALPHA_PLL_TYPE_NSS_HUAYRA] =  {
+		[PLL_OFF_L_VAL] = 0x04,
+		[PLL_OFF_ALPHA_VAL] = 0x08,
+		[PLL_OFF_TEST_CTL] = 0x0c,
+		[PLL_OFF_TEST_CTL_U] = 0x10,
+		[PLL_OFF_USER_CTL] = 0x14,
+		[PLL_OFF_CONFIG_CTL] = 0x18,
+		[PLL_OFF_CONFIG_CTL_U] = 0x1c,
+		[PLL_OFF_STATUS] = 0x20,
+	},
+
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
 
@@ -382,6 +408,8 @@
 	mask |= config->pre_div_mask;
 	mask |= config->post_div_mask;
 	mask |= config->vco_mask;
+	mask |= config->alpha_en_mask;
+	mask |= config->alpha_mode_mask;
 
 	regmap_update_bits(regmap, PLL_USER_CTL(pll), mask, val);
 
@@ -1480,8 +1508,8 @@
 	}
 
 	return regmap_update_bits(regmap, PLL_USER_CTL(pll),
-				  PLL_POST_DIV_MASK(pll) << PLL_POST_DIV_SHIFT,
-				  val << PLL_POST_DIV_SHIFT);
+				  PLL_POST_DIV_MASK(pll) << pll->post_div_shift,
+				  val << pll->post_div_shift);
 }
 
 const struct clk_ops clk_alpha_pll_postdiv_trion_ops = {
@@ -1640,7 +1668,7 @@
 	if (ret < 0)
 		return ret;
 
-	regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
+	regmap_update_bits(pll->clkr.regmap, PLL_L_VAL(pll), LUCID_EVO_PLL_L_VAL_MASK,  l);
 	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
 
 	/* Latch the PLL input */
@@ -1759,6 +1787,58 @@
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_agera_ops);
 
+/**
+ * clk_lucid_5lpe_pll_configure - configure the lucid 5lpe pll
+ *
+ * @pll: clk alpha pll
+ * @regmap: register map
+ * @config: configuration to apply for pll
+ */
+void clk_lucid_5lpe_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
+				  const struct alpha_pll_config *config)
+{
+	/*
+	 * If the bootloader left the PLL enabled it's likely that there are
+	 * RCGs that will lock up if we disable the PLL below.
+	 */
+	if (trion_pll_is_enabled(pll, regmap)) {
+		pr_debug("Lucid 5LPE PLL is already enabled, skipping configuration\n");
+		return;
+	}
+
+	clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
+	regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL);
+	clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
+	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll),
+				     config->config_ctl_val);
+	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll),
+				     config->config_ctl_hi_val);
+	clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll),
+				     config->config_ctl_hi1_val);
+	clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),
+					config->user_ctl_val);
+	clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll),
+					config->user_ctl_hi_val);
+	clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U1(pll),
+					config->user_ctl_hi1_val);
+	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),
+					config->test_ctl_val);
+	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll),
+					config->test_ctl_hi_val);
+	clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll),
+					config->test_ctl_hi1_val);
+
+	/* Disable PLL output */
+	regmap_update_bits(regmap, PLL_MODE(pll),  PLL_OUTCTRL, 0);
+
+	/* Set operation mode to OFF */
+	regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
+
+	/* Place the PLL in STANDBY mode */
+	regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
+}
+EXPORT_SYMBOL_GPL(clk_lucid_5lpe_pll_configure);
+
 static int alpha_pll_lucid_5lpe_enable(struct clk_hw *hw)
 {
 	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
@@ -2474,6 +2554,8 @@
 	rate = alpha_pll_round_rate(rate, prate, &l, &a, ALPHA_REG_BITWIDTH);
 
 	regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
+
+	a <<= ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH;
 	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
 	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll),
 		     a >> ALPHA_BITWIDTH);
@@ -2538,6 +2620,9 @@
 	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll),
 					a >> ALPHA_BITWIDTH);
 
+	regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll),
+			   PLL_ALPHA_EN, PLL_ALPHA_EN);
+
 	regmap_write(pll->clkr.regmap, PLL_MODE(pll), PLL_BYPASSNL);
 
 	/* Wait five micro seconds or more */
@@ -2571,3 +2656,173 @@
 	.set_rate = clk_alpha_pll_stromer_plus_set_rate,
 };
 EXPORT_SYMBOL_GPL(clk_alpha_pll_stromer_plus_ops);
+
+static int clk_alpha_pll_slew_update(struct clk_alpha_pll *pll)
+{
+	int ret;
+	u32 val;
+
+	regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_UPDATE, PLL_UPDATE);
+	regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
+
+	ret = wait_for_pll_update(pll);
+	if (ret)
+		return ret;
+	/*
+	 * Hardware programming mandates a wait of at least 570ns before polling the LOCK
+	 * detect bit. Have a delay of 1us just to be safe.
+	 */
+	mb();
+	udelay(1);
+
+	return wait_for_pll_enable_lock(pll);
+}
+
+static int clk_alpha_pll_slew_set_rate(struct clk_hw *hw, unsigned long rate,
+					unsigned long parent_rate)
+{
+	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+	unsigned long freq_hz;
+	const struct pll_vco *curr_vco, *vco;
+	u32 l, alpha_width = pll_alpha_width(pll);
+	u64 a;
+
+	freq_hz =  alpha_pll_round_rate(rate, parent_rate, &l, &a, alpha_width);
+	if (freq_hz != rate) {
+		pr_err("alpha_pll: Call clk_set_rate with rounded rates!\n");
+		return -EINVAL;
+	}
+
+	curr_vco = alpha_pll_find_vco(pll, clk_hw_get_rate(hw));
+	if (!curr_vco) {
+		pr_err("alpha pll: not in a valid vco range\n");
+		return -EINVAL;
+	}
+
+	vco = alpha_pll_find_vco(pll, freq_hz);
+	if (!vco) {
+		pr_err("alpha pll: not in a valid vco range\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * Dynamic pll update will not support switching frequencies across
+	 * vco ranges. In those cases fall back to normal alpha set rate.
+	 */
+	if (curr_vco->val != vco->val)
+		return clk_alpha_pll_set_rate(hw, rate, parent_rate);
+
+	a = a << (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);
+
+	regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
+	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
+	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), a >> 32);
+
+	/* Ensure that the write above goes through before proceeding. */
+	mb();
+
+	if (clk_hw_is_enabled(hw))
+		return clk_alpha_pll_slew_update(pll);
+
+	return 0;
+}
+
+/*
+ * Slewing plls should be bought up at frequency which is in the middle of the
+ * desired VCO range. So after bringing up the pll at calibration freq, set it
+ * back to desired frequency(that was set by previous clk_set_rate).
+ */
+static int clk_alpha_pll_calibrate(struct clk_hw *hw)
+{
+	unsigned long calibration_freq, freq_hz;
+	struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+	struct clk_hw *parent;
+	const struct pll_vco *vco;
+	u32 l, alpha_width = pll_alpha_width(pll);
+	int rc;
+	u64 a;
+
+	parent = clk_hw_get_parent(hw);
+	if (!parent) {
+		pr_err("alpha pll: no valid parent found\n");
+		return -EINVAL;
+	}
+
+	vco = alpha_pll_find_vco(pll, clk_hw_get_rate(hw));
+	if (!vco) {
+		pr_err("alpha pll: not in a valid vco range\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * As during slewing plls vco_sel won't be allowed to change, vco table
+	 * should have only one entry table, i.e. index = 0, find the
+	 * calibration frequency.
+	 */
+	calibration_freq = (pll->vco_table[0].min_freq + pll->vco_table[0].max_freq) / 2;
+
+	freq_hz = alpha_pll_round_rate(calibration_freq, clk_hw_get_rate(parent),
+					&l, &a, alpha_width);
+	if (freq_hz != calibration_freq) {
+		pr_err("alpha_pll: call clk_set_rate with rounded rates!\n");
+		return -EINVAL;
+	}
+
+	/* Setup PLL for calibration frequency */
+	a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);
+
+	regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
+	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
+	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), a >> 32);
+
+	regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll), PLL_VCO_MASK << PLL_VCO_SHIFT,
+				vco->val << PLL_VCO_SHIFT);
+
+	/* Bringup the pll at calibration frequency */
+	rc = clk_alpha_pll_enable(hw);
+	if (rc) {
+		pr_err("alpha pll calibration failed\n");
+		return rc;
+	}
+
+	/*
+	 * PLL is already running at calibration frequency.
+	 * So slew pll to the previously set frequency.
+	 */
+	freq_hz = alpha_pll_round_rate(clk_hw_get_rate(hw),
+			clk_hw_get_rate(parent), &l, &a, alpha_width);
+
+	pr_debug("pll %s: setting back to required rate %lu, freq_hz %ld\n",
+		clk_hw_get_name(hw), clk_hw_get_rate(hw), freq_hz);
+
+	/* Setup the PLL for the new frequency */
+	a <<= (ALPHA_REG_BITWIDTH - ALPHA_BITWIDTH);
+
+	regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
+	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
+	regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll), a >> 32);
+
+	regmap_update_bits(pll->clkr.regmap, PLL_USER_CTL(pll), PLL_ALPHA_EN, PLL_ALPHA_EN);
+
+	return clk_alpha_pll_slew_update(pll);
+}
+
+static int clk_alpha_pll_slew_enable(struct clk_hw *hw)
+{
+	int rc;
+
+	rc = clk_alpha_pll_calibrate(hw);
+	if (rc)
+		return rc;
+
+	return clk_alpha_pll_enable(hw);
+}
+
+const struct clk_ops clk_alpha_pll_slew_ops = {
+	.enable = clk_alpha_pll_slew_enable,
+	.disable = clk_alpha_pll_disable,
+	.recalc_rate = clk_alpha_pll_recalc_rate,
+	.round_rate = clk_alpha_pll_round_rate,
+	.set_rate = clk_alpha_pll_slew_set_rate,
+};
+EXPORT_SYMBOL_GPL(clk_alpha_pll_slew_ops);
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/clk-alpha-pll.h
+++ linux-qcom-6.8.0/drivers/clk/qcom/clk-alpha-pll.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (c) 2015, 2018, 2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 
@@ -21,6 +21,7 @@
 	CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION,
 	CLK_ALPHA_PLL_TYPE_AGERA,
 	CLK_ALPHA_PLL_TYPE_ZONDA,
+	CLK_ALPHA_PLL_TYPE_ZONDA_OLE,
 	CLK_ALPHA_PLL_TYPE_LUCID_EVO,
 	CLK_ALPHA_PLL_TYPE_LUCID_OLE,
 	CLK_ALPHA_PLL_TYPE_RIVIAN_EVO,
@@ -28,6 +29,7 @@
 	CLK_ALPHA_PLL_TYPE_BRAMMO_EVO,
 	CLK_ALPHA_PLL_TYPE_STROMER,
 	CLK_ALPHA_PLL_TYPE_STROMER_PLUS,
+	CLK_ALPHA_PLL_TYPE_NSS_HUAYRA,
 	CLK_ALPHA_PLL_TYPE_MAX,
 };
 
@@ -42,6 +44,7 @@
 	PLL_OFF_CONFIG_CTL,
 	PLL_OFF_CONFIG_CTL_U,
 	PLL_OFF_CONFIG_CTL_U1,
+	PLL_OFF_CONFIG_CTL_U2,
 	PLL_OFF_TEST_CTL,
 	PLL_OFF_TEST_CTL_U,
 	PLL_OFF_TEST_CTL_U1,
@@ -119,6 +122,7 @@
 	u32 config_ctl_val;
 	u32 config_ctl_hi_val;
 	u32 config_ctl_hi1_val;
+	u32 config_ctl_hi2_val;
 	u32 user_ctl_val;
 	u32 user_ctl_hi_val;
 	u32 user_ctl_hi1_val;
@@ -173,6 +177,7 @@
 
 extern const struct clk_ops clk_alpha_pll_zonda_ops;
 #define clk_alpha_pll_postdiv_zonda_ops clk_alpha_pll_postdiv_fabia_ops
+#define clk_alpha_pll_zonda_ole_ops clk_alpha_pll_zonda_ops
 
 extern const struct clk_ops clk_alpha_pll_lucid_evo_ops;
 extern const struct clk_ops clk_alpha_pll_reset_lucid_evo_ops;
@@ -185,6 +190,8 @@
 extern const struct clk_ops clk_alpha_pll_rivian_evo_ops;
 #define clk_alpha_pll_postdiv_rivian_evo_ops clk_alpha_pll_postdiv_fabia_ops
 
+extern const struct clk_ops clk_alpha_pll_slew_ops;
+
 void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 			     const struct alpha_pll_config *config);
 void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
@@ -198,6 +205,8 @@
 
 void clk_zonda_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 			     const struct alpha_pll_config *config);
+void clk_lucid_5lpe_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
+				  const struct alpha_pll_config *config);
 void clk_lucid_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
 				 const struct alpha_pll_config *config);
 void clk_lucid_ole_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/clk-branch.h
+++ linux-qcom-6.8.0/drivers/clk/qcom/clk-branch.h
@@ -64,6 +64,7 @@
 #define CBCR_FORCE_MEM_PERIPH_OFF	BIT(12)
 #define CBCR_WAKEUP			GENMASK(11, 8)
 #define CBCR_SLEEP			GENMASK(7, 4)
+#define CBCR_CLOCK_ENABLE		BIT(0)
 
 static inline void qcom_branch_set_force_mem_core(struct regmap *regmap,
 						  struct clk_branch clk, bool on)
@@ -98,6 +99,11 @@
 			   FIELD_PREP(CBCR_SLEEP, val));
 }
 
+static inline void qcom_branch_set_clk_en(struct regmap *regmap, u32 cbcr)
+{
+	regmap_update_bits(regmap, cbcr, CBCR_CLOCK_ENABLE, CBCR_CLOCK_ENABLE);
+}
+
 extern const struct clk_ops clk_branch_ops;
 extern const struct clk_ops clk_branch2_ops;
 extern const struct clk_ops clk_branch_simple_ops;
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/clk-rcg.h
+++ linux-qcom-6.8.0/drivers/clk/qcom/clk-rcg.h
@@ -176,6 +176,8 @@
 extern const struct clk_ops clk_pixel_ops;
 extern const struct clk_ops clk_gfx3d_ops;
 extern const struct clk_ops clk_rcg2_shared_ops;
+extern const struct clk_ops clk_rcg2_shared_floor_ops;
+extern const struct clk_ops clk_rcg2_shared_no_init_park_ops;
 extern const struct clk_ops clk_dp_ops;
 
 struct clk_rcg_dfs_data {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/clk-rcg2.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/clk-rcg2.c
@@ -1020,15 +1020,23 @@
 	return clk_rcg2_clear_force_enable(hw);
 }
 
-static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
-				    unsigned long parent_rate)
+static int __clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long parent_rate,
+				      enum freq_policy policy)
 {
 	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
 	const struct freq_tbl *f;
 
-	f = qcom_find_freq(rcg->freq_tbl, rate);
-	if (!f)
+	switch (policy) {
+	case FLOOR:
+		f = qcom_find_freq_floor(rcg->freq_tbl, rate);
+		break;
+	case CEIL:
+		f = qcom_find_freq(rcg->freq_tbl, rate);
+		break;
+	default:
 		return -EINVAL;
+	}
 
 	/*
 	 * In case clock is disabled, update the M, N and D registers, cache
@@ -1041,10 +1049,28 @@
 	return clk_rcg2_shared_force_enable_clear(hw, f);
 }
 
+static int clk_rcg2_shared_set_rate(struct clk_hw *hw, unsigned long rate,
+				    unsigned long parent_rate)
+{
+	return __clk_rcg2_shared_set_rate(hw, rate, parent_rate, CEIL);
+}
+
 static int clk_rcg2_shared_set_rate_and_parent(struct clk_hw *hw,
 		unsigned long rate, unsigned long parent_rate, u8 index)
 {
-	return clk_rcg2_shared_set_rate(hw, rate, parent_rate);
+	return __clk_rcg2_shared_set_rate(hw, rate, parent_rate, CEIL);
+}
+
+static int clk_rcg2_shared_set_floor_rate(struct clk_hw *hw, unsigned long rate,
+					  unsigned long parent_rate)
+{
+	return __clk_rcg2_shared_set_rate(hw, rate, parent_rate, FLOOR);
+}
+
+static int clk_rcg2_shared_set_floor_rate_and_parent(struct clk_hw *hw,
+		unsigned long rate, unsigned long parent_rate, u8 index)
+{
+	return __clk_rcg2_shared_set_rate(hw, rate, parent_rate, FLOOR);
 }
 
 static int clk_rcg2_shared_enable(struct clk_hw *hw)
@@ -1138,7 +1164,39 @@
 	return clk_rcg2_recalc_rate(hw, parent_rate);
 }
 
+static int clk_rcg2_shared_init(struct clk_hw *hw)
+{
+	/*
+	 * This does a few things:
+	 *
+	 *  1. Sets rcg->parked_cfg to reflect the value at probe so that the
+	 *     proper parent is reported from clk_rcg2_shared_get_parent().
+	 *
+	 *  2. Clears the force enable bit of the RCG because we rely on child
+	 *     clks (branches) to turn the RCG on/off with a hardware feedback
+	 *     mechanism and only set the force enable bit in the RCG when we
+	 *     want to make sure the clk stays on for parent switches or
+	 *     parking.
+	 *
+	 *  3. Parks shared RCGs on the safe source at registration because we
+	 *     can't be certain that the parent clk will stay on during boot,
+	 *     especially if the parent is shared. If this RCG is enabled at
+	 *     boot, and the parent is turned off, the RCG will get stuck on. A
+	 *     GDSC can wedge if is turned on and the RCG is stuck on because
+	 *     the GDSC's controller will hang waiting for the clk status to
+	 *     toggle on when it never does.
+	 *
+	 * The safest option here is to "park" the RCG at init so that the clk
+	 * can never get stuck on or off. This ensures the GDSC can't get
+	 * wedged.
+	 */
+	clk_rcg2_shared_disable(hw);
+
+	return 0;
+}
+
 const struct clk_ops clk_rcg2_shared_ops = {
+	.init = clk_rcg2_shared_init,
 	.enable = clk_rcg2_shared_enable,
 	.disable = clk_rcg2_shared_disable,
 	.get_parent = clk_rcg2_shared_get_parent,
@@ -1150,6 +1208,48 @@
 };
 EXPORT_SYMBOL_GPL(clk_rcg2_shared_ops);
 
+const struct clk_ops clk_rcg2_shared_floor_ops = {
+	.enable = clk_rcg2_shared_enable,
+	.disable = clk_rcg2_shared_disable,
+	.get_parent = clk_rcg2_shared_get_parent,
+	.set_parent = clk_rcg2_shared_set_parent,
+	.recalc_rate = clk_rcg2_shared_recalc_rate,
+	.determine_rate = clk_rcg2_determine_floor_rate,
+	.set_rate = clk_rcg2_shared_set_floor_rate,
+	.set_rate_and_parent = clk_rcg2_shared_set_floor_rate_and_parent,
+};
+EXPORT_SYMBOL_GPL(clk_rcg2_shared_floor_ops);
+
+static int clk_rcg2_shared_no_init_park(struct clk_hw *hw)
+{
+	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+
+	/*
+	 * Read the config register so that the parent is properly mapped at
+	 * registration time.
+	 */
+	regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &rcg->parked_cfg);
+
+	return 0;
+}
+
+/*
+ * Like clk_rcg2_shared_ops but skip the init so that the clk frequency is left
+ * unchanged at registration time.
+ */
+const struct clk_ops clk_rcg2_shared_no_init_park_ops = {
+	.init = clk_rcg2_shared_no_init_park,
+	.enable = clk_rcg2_shared_enable,
+	.disable = clk_rcg2_shared_disable,
+	.get_parent = clk_rcg2_shared_get_parent,
+	.set_parent = clk_rcg2_shared_set_parent,
+	.recalc_rate = clk_rcg2_shared_recalc_rate,
+	.determine_rate = clk_rcg2_determine_rate,
+	.set_rate = clk_rcg2_shared_set_rate,
+	.set_rate_and_parent = clk_rcg2_shared_set_rate_and_parent,
+};
+EXPORT_SYMBOL_GPL(clk_rcg2_shared_no_init_park_ops);
+
 /* Common APIs to be used for DFS based RCGR */
 static void clk_rcg2_dfs_populate_freq(struct clk_hw *hw, unsigned int l,
 				       struct freq_tbl *f)
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/clk-rpmh.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/clk-rpmh.c
@@ -263,6 +263,8 @@
 		cmd_state = 0;
 	}
 
+	cmd_state = min(cmd_state, BCM_TCS_CMD_VOTE_MASK);
+
 	if (c->last_sent_aggr_state != cmd_state) {
 		cmd.addr = c->res_addr;
 		cmd.data = BCM_TCS_CMD(1, enable, 0, cmd_state);
@@ -327,7 +329,7 @@
 {
 	struct clk_rpmh *c = to_clk_rpmh(hw);
 
-	return c->aggr_state * c->unit;
+	return (unsigned long)c->aggr_state * c->unit;
 }
 
 static const struct clk_ops clk_rpmh_bcm_ops = {
@@ -387,6 +389,18 @@
 DEFINE_CLK_RPMH_BCM(pka, "PKA0");
 DEFINE_CLK_RPMH_BCM(qpic_clk, "QP0");
 
+static struct clk_hw *sar2130p_rpmh_clocks[] = {
+	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div1.hw,
+	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div1_ao.hw,
+	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_a.hw,
+	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_a_ao.hw,
+};
+
+static const struct clk_rpmh_desc clk_rpmh_sar2130p = {
+	.clks = sar2130p_rpmh_clocks,
+	.num_clks = ARRAY_SIZE(sar2130p_rpmh_clocks),
+};
+
 static struct clk_hw *sdm845_rpmh_clocks[] = {
 	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
 	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
@@ -793,6 +807,24 @@
 	.num_clks = ARRAY_SIZE(x1e80100_rpmh_clocks),
 };
 
+static struct clk_hw *qcs615_rpmh_clocks[] = {
+	[RPMH_CXO_CLK]		= &clk_rpmh_bi_tcxo_div2.hw,
+	[RPMH_CXO_CLK_A]	= &clk_rpmh_bi_tcxo_div2_ao.hw,
+	[RPMH_LN_BB_CLK2]	= &clk_rpmh_ln_bb_clk2_a2.hw,
+	[RPMH_LN_BB_CLK2_A]	= &clk_rpmh_ln_bb_clk2_a2_ao.hw,
+	[RPMH_LN_BB_CLK3]	= &clk_rpmh_ln_bb_clk3_a2.hw,
+	[RPMH_LN_BB_CLK3_A]	= &clk_rpmh_ln_bb_clk3_a2_ao.hw,
+	[RPMH_RF_CLK1]		= &clk_rpmh_rf_clk1_a.hw,
+	[RPMH_RF_CLK1_A]	= &clk_rpmh_rf_clk1_a_ao.hw,
+	[RPMH_RF_CLK2]		= &clk_rpmh_rf_clk2_a.hw,
+	[RPMH_RF_CLK2_A]	= &clk_rpmh_rf_clk2_a_ao.hw,
+};
+
+static const struct clk_rpmh_desc clk_rpmh_qcs615 = {
+	.clks = qcs615_rpmh_clocks,
+	.num_clks = ARRAY_SIZE(qcs615_rpmh_clocks),
+};
+
 static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
 					 void *data)
 {
@@ -876,8 +908,10 @@
 }
 
 static const struct of_device_id clk_rpmh_match_table[] = {
+	{ .compatible = "qcom,qcs615-rpmh-clk", .data = &clk_rpmh_qcs615},
 	{ .compatible = "qcom,qdu1000-rpmh-clk", .data = &clk_rpmh_qdu1000},
 	{ .compatible = "qcom,sa8775p-rpmh-clk", .data = &clk_rpmh_sa8775p},
+	{ .compatible = "qcom,sar2130p-rpmh-clk", .data = &clk_rpmh_sar2130p},
 	{ .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180},
 	{ .compatible = "qcom,sc8180x-rpmh-clk", .data = &clk_rpmh_sc8180x},
 	{ .compatible = "qcom,sc8280xp-rpmh-clk", .data = &clk_rpmh_sc8280xp},
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/clk-smd-rpm.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/clk-smd-rpm.c
@@ -768,6 +768,7 @@
 
 static const struct rpm_smd_clk_desc rpm_clk_msm8976 = {
 	.clks = msm8976_clks,
+	.num_clks = ARRAY_SIZE(msm8976_clks),
 	.icc_clks = bimc_pcnoc_snoc_smmnoc_icc_clks,
 	.num_icc_clks = ARRAY_SIZE(bimc_pcnoc_snoc_smmnoc_icc_clks),
 };
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/common.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/common.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/export.h>
@@ -208,11 +209,9 @@
 static void qcom_cc_drop_protected(struct device *dev, struct qcom_cc *cc)
 {
 	struct device_node *np = dev->of_node;
-	struct property *prop;
-	const __be32 *p;
 	u32 i;
 
-	of_property_for_each_u32(np, "protected-clocks", prop, p, i) {
+	of_property_for_each_u32(np, "protected-clocks", i) {
 		if (i >= cc->num_rclks)
 			continue;
 
@@ -234,11 +233,10 @@
 	return cc->rclks[idx] ? &cc->rclks[idx]->hw : NULL;
 }
 
-int qcom_cc_really_probe(struct platform_device *pdev,
+int qcom_cc_really_probe(struct device *dev,
 			 const struct qcom_cc_desc *desc, struct regmap *regmap)
 {
 	int i, ret;
-	struct device *dev = &pdev->dev;
 	struct qcom_reset_controller *reset;
 	struct qcom_cc *cc;
 	struct gdsc_desc *scd;
@@ -270,6 +268,7 @@
 		scd->dev = dev;
 		scd->scs = desc->gdscs;
 		scd->num = desc->num_gdscs;
+		scd->pmdomains = desc->pmdomains;
 		ret = gdsc_register(scd, &reset->rcdev, regmap);
 		if (ret)
 			return ret;
@@ -315,7 +314,7 @@
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	return qcom_cc_really_probe(pdev, desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, desc, regmap);
 }
 EXPORT_SYMBOL_GPL(qcom_cc_probe);
 
@@ -333,8 +332,27 @@
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	return qcom_cc_really_probe(pdev, desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, desc, regmap);
 }
 EXPORT_SYMBOL_GPL(qcom_cc_probe_by_index);
 
+static void qcom_cc_detach_pds(void *data)
+{
+	struct qcom_cc_desc *desc = (struct qcom_cc_desc *)data;
+
+	dev_pm_domain_detach_list(desc->pmdomains);
+}
+
+int qcom_cc_attach_pds(struct device *dev, struct qcom_cc_desc *desc)
+{
+	int ret;
+
+	ret = dev_pm_domain_attach_list(dev, NULL, &desc->pmdomains);
+	if (ret < 0 && ret != -EEXIST)
+		return ret;
+
+	return devm_add_action_or_reset(dev, qcom_cc_detach_pds, desc);
+}
+EXPORT_SYMBOL_GPL(qcom_cc_attach_pds);
+
 MODULE_LICENSE("GPL v2");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/common.h
+++ linux-qcom-6.8.0/drivers/clk/qcom/common.h
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /* Copyright (c) 2014, The Linux Foundation. All rights reserved. */
+/* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. */
 
 #ifndef __QCOM_CLK_COMMON_H__
 #define __QCOM_CLK_COMMON_H__
@@ -29,6 +30,7 @@
 	size_t num_gdscs;
 	struct clk_hw **clk_hws;
 	size_t num_clk_hws;
+	struct dev_pm_domain_list *pmdomains;
 };
 
 /**
@@ -58,12 +60,13 @@
 
 extern struct regmap *qcom_cc_map(struct platform_device *pdev,
 				  const struct qcom_cc_desc *desc);
-extern int qcom_cc_really_probe(struct platform_device *pdev,
+extern int qcom_cc_really_probe(struct device *dev,
 				const struct qcom_cc_desc *desc,
 				struct regmap *regmap);
 extern int qcom_cc_probe(struct platform_device *pdev,
 			 const struct qcom_cc_desc *desc);
 extern int qcom_cc_probe_by_index(struct platform_device *pdev, int index,
 				  const struct qcom_cc_desc *desc);
+extern int qcom_cc_attach_pds(struct device *dev, struct qcom_cc_desc *desc);
 
 #endif
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-qcm2290.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-qcm2290.c
@@ -522,7 +522,7 @@
 	/* Keep DISP_CC_XO_CLK always-ON */
 	regmap_update_bits(regmap, 0x604c, BIT(0), BIT(0));
 
-	ret = qcom_cc_really_probe(pdev, &disp_cc_qcm2290_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_qcm2290_desc, regmap);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register DISP CC clocks\n");
 		return ret;
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-qcs615.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-qcs615.c
@@ -0,0 +1,786 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,qcs615-dispcc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_BI_TCXO,
+	DT_GPLL0,
+	DT_DSI0_PHY_PLL_OUT_BYTECLK,
+	DT_DSI0_PHY_PLL_OUT_DSICLK,
+	DT_DSI1_PHY_PLL_OUT_DSICLK,
+	DT_DP_PHY_PLL_LINK_CLK,
+	DT_DP_PHY_PLL_VCO_DIV_CLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_DISP_CC_PLL0_OUT_MAIN,
+	P_DP_PHY_PLL_LINK_CLK,
+	P_DP_PHY_PLL_VCO_DIV_CLK,
+	P_DSI0_PHY_PLL_OUT_BYTECLK,
+	P_DSI0_PHY_PLL_OUT_DSICLK,
+	P_DSI1_PHY_PLL_OUT_DSICLK,
+	P_GPLL0_OUT_MAIN,
+};
+
+static const struct pll_vco disp_cc_pll_vco[] = {
+	{ 500000000, 1000000000, 2 },
+};
+
+/* 576MHz configuration VCO - 2 */
+static struct alpha_pll_config disp_cc_pll0_config = {
+	.l = 0x1e,
+	.vco_val = BIT(21),
+	.vco_mask = GENMASK(21, 20),
+	.main_output_mask = BIT(0),
+	.config_ctl_val = 0x4001055b,
+	.test_ctl_hi_val = 0x1,
+	.test_ctl_hi_mask = 0x1,
+};
+
+static struct clk_alpha_pll disp_cc_pll0 = {
+	.offset = 0x0,
+	.vco_table = disp_cc_pll_vco,
+	.num_vco = ARRAY_SIZE(disp_cc_pll_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_slew_ops,
+		},
+	},
+};
+
+static const struct parent_map disp_cc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DP_PHY_PLL_LINK_CLK, 1 },
+	{ P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DP_PHY_PLL_LINK_CLK },
+	{ .index = DT_DP_PHY_PLL_VCO_DIV_CLK },
+};
+
+static const struct parent_map disp_cc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct parent_map disp_cc_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
+};
+
+static const struct parent_map disp_cc_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DISP_CC_PLL0_OUT_MAIN, 1 },
+	{ P_GPLL0_OUT_MAIN, 4 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &disp_cc_pll0.clkr.hw },
+	{ .index = DT_GPLL0 },
+};
+
+static const struct parent_map disp_cc_parent_map_4[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPLL0_OUT_MAIN, 4 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_4[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_GPLL0 },
+};
+
+static const struct parent_map disp_cc_parent_map_5[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+	{ P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_5[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
+	{ .index = DT_DSI1_PHY_PLL_OUT_DSICLK },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(37500000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+	F(75000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
+	.cmd_rcgr = 0x2170,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_4,
+	.freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_ahb_clk_src",
+		.parent_data = disp_cc_parent_data_4,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
+	.cmd_rcgr = 0x20c0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_2,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_byte0_clk_src",
+		.parent_data = disp_cc_parent_data_2,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux1_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
+	.cmd_rcgr = 0x2158,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_1,
+	.freq_tbl = ftbl_disp_cc_mdss_dp_aux1_clk_src,
+	.clkr.hw.init = &(struct clk_init_data){
+		.name = "disp_cc_mdss_dp_aux_clk_src",
+		.parent_data = disp_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
+	.cmd_rcgr = 0x2110,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dp_crypto_clk_src",
+		.parent_data = disp_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
+	.cmd_rcgr = 0x20f4,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dp_link_clk_src",
+		.parent_data = disp_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_pixel1_clk_src = {
+	.cmd_rcgr = 0x2140,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dp_pixel1_clk_src",
+		.parent_data = disp_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
+	.cmd_rcgr = 0x2128,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dp_pixel_clk_src",
+		.parent_data = disp_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
+	.cmd_rcgr = 0x20dc,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_2,
+	.freq_tbl = ftbl_disp_cc_mdss_dp_aux1_clk_src,
+	.clkr.hw.init = &(struct clk_init_data){
+		.name = "disp_cc_mdss_esc0_clk_src",
+		.parent_data = disp_cc_parent_data_2,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(307000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
+	.cmd_rcgr = 0x2078,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_3,
+	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_mdp_clk_src",
+		.parent_data = disp_cc_parent_data_3,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
+	.cmd_rcgr = 0x2060,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_5,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_pclk0_clk_src",
+		.parent_data = disp_cc_parent_data_5,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_pixel_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
+	.cmd_rcgr = 0x2090,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_3,
+	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_rot_clk_src",
+		.parent_data = disp_cc_parent_data_3,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
+	.cmd_rcgr = 0x20a8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_1,
+	.freq_tbl = ftbl_disp_cc_mdss_dp_aux1_clk_src,
+	.clkr.hw.init = &(struct clk_init_data){
+		.name = "disp_cc_mdss_vsync_clk_src",
+		.parent_data = disp_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
+	.reg = 0x20d8,
+	.shift = 0,
+	.width = 2,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_byte0_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&disp_cc_mdss_byte0_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div disp_cc_mdss_dp_link_div_clk_src = {
+	.reg = 0x210c,
+	.shift = 0,
+	.width = 2,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dp_link_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&disp_cc_mdss_dp_link_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_branch disp_cc_mdss_ahb_clk = {
+	.halt_reg = 0x2048,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2048,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_byte0_clk = {
+	.halt_reg = 0x2024,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_byte0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_byte0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
+	.halt_reg = 0x2028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_byte0_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_byte0_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dp_aux_clk = {
+	.halt_reg = 0x2044,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2044,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dp_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dp_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dp_crypto_clk = {
+	.halt_reg = 0x2038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dp_crypto_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dp_crypto_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dp_link_clk = {
+	.halt_reg = 0x2030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dp_link_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dp_link_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
+	.halt_reg = 0x2034,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2034,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dp_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dp_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dp_pixel1_clk = {
+	.halt_reg = 0x2040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dp_pixel1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dp_pixel1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
+	.halt_reg = 0x203c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x203c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dp_pixel_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dp_pixel_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_esc0_clk = {
+	.halt_reg = 0x202c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x202c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_esc0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_esc0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_mdp_clk = {
+	.halt_reg = 0x2008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_mdp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
+	.halt_reg = 0x2018,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_mdp_lut_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
+	.halt_reg = 0x4004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_non_gdsc_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_pclk0_clk = {
+	.halt_reg = 0x2004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_pclk0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_pclk0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_rot_clk = {
+	.halt_reg = 0x2010,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_rot_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_rot_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
+	.halt_reg = 0x400c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x400c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_rscc_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
+	.halt_reg = 0x4008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x4008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_rscc_vsync_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_vsync_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_vsync_clk = {
+	.halt_reg = 0x2020,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_vsync_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_vsync_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc mdss_core_gdsc = {
+	.gdscr = 0x3000,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "mdss_core_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = HW_CTRL | POLL_CFG_GDSCR,
+};
+
+static struct clk_regmap *disp_cc_qcs615_clocks[] = {
+	[DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
+	[DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
+	[DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
+	[DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
+	[DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
+	[DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
+	[DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr,
+	[DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr,
+	[DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr,
+	[DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr,
+	[DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr,
+	[DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr,
+	[DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dp_link_div_clk_src.clkr,
+	[DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr,
+	[DISP_CC_MDSS_DP_PIXEL1_CLK] = &disp_cc_mdss_dp_pixel1_clk.clkr,
+	[DISP_CC_MDSS_DP_PIXEL1_CLK_SRC] = &disp_cc_mdss_dp_pixel1_clk_src.clkr,
+	[DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr,
+	[DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr,
+	[DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
+	[DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
+	[DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
+	[DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
+	[DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
+	[DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
+	[DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
+	[DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
+	[DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
+	[DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
+	[DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
+	[DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
+	[DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
+	[DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
+	[DISP_CC_PLL0] = &disp_cc_pll0.clkr,
+};
+
+static struct gdsc *disp_cc_qcs615_gdscs[] = {
+	[MDSS_CORE_GDSC] = &mdss_core_gdsc,
+};
+
+static const struct regmap_config disp_cc_qcs615_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x10000,
+	.fast_io = true,
+};
+
+static const struct qcom_cc_desc disp_cc_qcs615_desc = {
+	.config = &disp_cc_qcs615_regmap_config,
+	.clks = disp_cc_qcs615_clocks,
+	.num_clks = ARRAY_SIZE(disp_cc_qcs615_clocks),
+	.gdscs = disp_cc_qcs615_gdscs,
+	.num_gdscs = ARRAY_SIZE(disp_cc_qcs615_gdscs),
+};
+
+static const struct of_device_id disp_cc_qcs615_match_table[] = {
+	{ .compatible = "qcom,qcs615-dispcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, disp_cc_qcs615_match_table);
+
+static int disp_cc_qcs615_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+
+	regmap = qcom_cc_map(pdev, &disp_cc_qcs615_desc);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	clk_alpha_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
+
+	/* Keep some clocks always enabled */
+	regmap_update_bits(regmap, 0x6054, BIT(0), BIT(0)); /* DISP_CC_XO_CLK */
+
+	return qcom_cc_really_probe(&pdev->dev, &disp_cc_qcs615_desc, regmap);
+}
+
+static struct platform_driver disp_cc_qcs615_driver = {
+	.probe = disp_cc_qcs615_probe,
+	.driver = {
+		.name = "dispcc-qcs615",
+		.of_match_table = disp_cc_qcs615_match_table,
+	},
+};
+
+module_platform_driver(disp_cc_qcs615_driver);
+
+MODULE_DESCRIPTION("QTI DISPCC QCS615 Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-sc7180.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-sc7180.c
@@ -713,7 +713,7 @@
 
 	clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll_config);
 
-	return qcom_cc_really_probe(pdev, &disp_cc_sc7180_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &disp_cc_sc7180_desc, regmap);
 }
 
 static struct platform_driver disp_cc_sc7180_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-sc7280.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-sc7280.c
@@ -884,7 +884,7 @@
 	 */
 	regmap_update_bits(regmap, 0x5008, BIT(0), BIT(0));
 
-	return qcom_cc_really_probe(pdev, &disp_cc_sc7280_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &disp_cc_sc7280_desc, regmap);
 }
 
 static struct platform_driver disp_cc_sc7280_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-sc8280xp.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-sc8280xp.c
@@ -3172,7 +3172,7 @@
 	clk_lucid_pll_configure(clkr_to_alpha_clk_pll(desc->clks[DISP_CC_PLL1]), regmap, &disp_cc_pll1_config);
 	clk_lucid_pll_configure(clkr_to_alpha_clk_pll(desc->clks[DISP_CC_PLL2]), regmap, &disp_cc_pll2_config);
 
-	ret = qcom_cc_really_probe(pdev, desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, desc, regmap);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register display clock controller\n");
 		goto out_pm_runtime_put;
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-sdm845.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-sdm845.c
@@ -759,6 +759,8 @@
 
 static struct gdsc mdss_gdsc = {
 	.gdscr = 0x3000,
+	.en_few_wait_val = 0x6,
+	.en_rest_wait_val = 0x5,
 	.pd = {
 		.name = "mdss_gdsc",
 	},
@@ -861,7 +863,7 @@
 	/* Enable hardware clock gating for DSI and MDP clocks */
 	regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0);
 
-	return qcom_cc_really_probe(pdev, &disp_cc_sdm845_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &disp_cc_sdm845_desc, regmap);
 }
 
 static struct platform_driver disp_cc_sdm845_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-sm6115.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-sm6115.c
@@ -586,7 +586,7 @@
 	/* Keep DISP_CC_XO_CLK always-ON */
 	regmap_update_bits(regmap, 0x604c, BIT(0), BIT(0));
 
-	ret = qcom_cc_really_probe(pdev, &disp_cc_sm6115_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm6115_desc, regmap);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register DISP CC clocks\n");
 		return ret;
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-sm6125.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-sm6125.c
@@ -682,7 +682,7 @@
 
 	clk_alpha_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
 
-	return qcom_cc_really_probe(pdev, &disp_cc_sm6125_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &disp_cc_sm6125_desc, regmap);
 }
 
 static struct platform_driver disp_cc_sm6125_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-sm6350.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-sm6350.c
@@ -187,13 +187,12 @@
 	.cmd_rcgr = 0x1144,
 	.mnd_width = 0,
 	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_6,
 	.freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "disp_cc_mdss_dp_aux_clk_src",
-		.parent_data = &(const struct clk_parent_data){
-			.fw_name = "bi_tcxo",
-		},
-		.num_parents = 1,
+		.parent_data = disp_cc_parent_data_6,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_6),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -221,26 +220,17 @@
 	},
 };
 
-static const struct freq_tbl ftbl_disp_cc_mdss_dp_link_clk_src[] = {
-	F(162000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
-	F(270000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
-	F(540000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
-	F(810000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0),
-	{ }
-};
-
 static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
 	.cmd_rcgr = 0x10f8,
 	.mnd_width = 0,
 	.hid_width = 5,
 	.parent_map = disp_cc_parent_map_0,
-	.freq_tbl = ftbl_disp_cc_mdss_dp_link_clk_src,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "disp_cc_mdss_dp_link_clk_src",
 		.parent_data = disp_cc_parent_data_0,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_byte2_ops,
 	},
 };
 
@@ -770,7 +760,7 @@
 
 	clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
 
-	return qcom_cc_really_probe(pdev, &disp_cc_sm6350_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &disp_cc_sm6350_desc, regmap);
 }
 
 static struct platform_driver disp_cc_sm6350_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-sm6375.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-sm6375.c
@@ -583,7 +583,7 @@
 
 	clk_lucid_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
 
-	return qcom_cc_really_probe(pdev, &disp_cc_sm6375_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &disp_cc_sm6375_desc, regmap);
 }
 
 static struct platform_driver disp_cc_sm6375_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-sm7150.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-sm7150.c
@@ -0,0 +1,1006 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com>
+ * Copyright (c) 2024, David Wronek <david@mainlining.org>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,sm7150-dispcc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "common.h"
+#include "gdsc.h"
+
+enum {
+	DT_BI_TCXO,
+	DT_BI_TCXO_AO,
+	DT_GCC_DISP_GPLL0_CLK,
+	DT_CHIP_SLEEP_CLK,
+	DT_DSI0_PHY_PLL_OUT_BYTECLK,
+	DT_DSI0_PHY_PLL_OUT_DSICLK,
+	DT_DSI1_PHY_PLL_OUT_BYTECLK,
+	DT_DSI1_PHY_PLL_OUT_DSICLK,
+	DT_DP_PHY_PLL_LINK_CLK,
+	DT_DP_PHY_PLL_VCO_DIV_CLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_CHIP_SLEEP_CLK,
+	P_DISPCC_PLL0_OUT_EVEN,
+	P_DISPCC_PLL0_OUT_MAIN,
+	P_DP_PHY_PLL_LINK_CLK,
+	P_DP_PHY_PLL_VCO_DIV_CLK,
+	P_DSI0_PHY_PLL_OUT_BYTECLK,
+	P_DSI0_PHY_PLL_OUT_DSICLK,
+	P_DSI1_PHY_PLL_OUT_BYTECLK,
+	P_DSI1_PHY_PLL_OUT_DSICLK,
+	P_GCC_DISP_GPLL0_CLK,
+};
+
+static const struct pll_vco fabia_vco[] = {
+	{ 249600000, 2000000000, 0 },
+	{ 125000000, 1000000000, 1 },
+};
+
+/* 860MHz configuration */
+static const struct alpha_pll_config dispcc_pll0_config = {
+	.l = 0x2c,
+	.alpha = 0xcaaa,
+	.test_ctl_val = 0x40000000,
+};
+
+static struct clk_alpha_pll dispcc_pll0 = {
+	.offset = 0x0,
+	.vco_table = fabia_vco,
+	.num_vco = ARRAY_SIZE(fabia_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fabia_ops,
+		},
+	},
+};
+
+static const struct parent_map dispcc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
+	{ P_DSI1_PHY_PLL_OUT_BYTECLK, 2 },
+};
+
+static const struct clk_parent_data dispcc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
+	{ .index = DT_DSI1_PHY_PLL_OUT_BYTECLK },
+};
+
+static const struct parent_map dispcc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DP_PHY_PLL_LINK_CLK, 1 },
+	{ P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
+};
+
+static const struct clk_parent_data dispcc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DP_PHY_PLL_LINK_CLK },
+	{ .index = DT_DP_PHY_PLL_VCO_DIV_CLK },
+};
+
+static const struct parent_map dispcc_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data dispcc_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct clk_parent_data dispcc_parent_data_2_ao[] = {
+	{ .index = DT_BI_TCXO_AO },
+};
+
+static const struct parent_map dispcc_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DISPCC_PLL0_OUT_MAIN, 1 },
+	{ P_GCC_DISP_GPLL0_CLK, 4 },
+	{ P_DISPCC_PLL0_OUT_EVEN, 5 },
+};
+
+static const struct clk_parent_data dispcc_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &dispcc_pll0.clkr.hw },
+	{ .index = DT_GCC_DISP_GPLL0_CLK },
+	{ .hw = &dispcc_pll0.clkr.hw },
+};
+
+static const struct parent_map dispcc_parent_map_4[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+	{ P_DSI1_PHY_PLL_OUT_DSICLK, 2 },
+};
+
+static const struct clk_parent_data dispcc_parent_data_4[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
+	{ .index = DT_DSI1_PHY_PLL_OUT_DSICLK },
+};
+
+static const struct parent_map dispcc_parent_map_5[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GCC_DISP_GPLL0_CLK, 4 },
+};
+
+static const struct clk_parent_data dispcc_parent_data_5[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_GCC_DISP_GPLL0_CLK },
+};
+
+static const struct parent_map dispcc_parent_map_6[] = {
+	{ P_CHIP_SLEEP_CLK, 0 },
+};
+
+static const struct clk_parent_data dispcc_parent_data_6[] = {
+	{ .index = DT_CHIP_SLEEP_CLK },
+};
+
+static const struct freq_tbl ftbl_dispcc_mdss_ahb_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(37500000, P_GCC_DISP_GPLL0_CLK, 16, 0, 0),
+	F(75000000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 dispcc_mdss_ahb_clk_src = {
+	.cmd_rcgr = 0x22bc,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_5,
+	.freq_tbl = ftbl_dispcc_mdss_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_ahb_clk_src",
+		.parent_data = dispcc_parent_data_5,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_5),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_dispcc_mdss_byte0_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 dispcc_mdss_byte0_clk_src = {
+	.cmd_rcgr = 0x2110,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_0,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_byte0_clk_src",
+		.parent_data = dispcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 dispcc_mdss_byte1_clk_src = {
+	.cmd_rcgr = 0x212c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_0,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_byte1_clk_src",
+		.parent_data = dispcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 dispcc_mdss_dp_aux_clk_src = {
+	.cmd_rcgr = 0x21dc,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_2,
+	.freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_dp_aux_clk_src",
+		.parent_data = dispcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_2),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_dispcc_mdss_dp_crypto_clk_src[] = {
+	F(108000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),
+	F(180000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0),
+	F(360000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
+	F(540000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 dispcc_mdss_dp_crypto_clk_src = {
+	.cmd_rcgr = 0x2194,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_1,
+	.freq_tbl = ftbl_dispcc_mdss_dp_crypto_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_dp_crypto_clk_src",
+		.parent_data = dispcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_1),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 dispcc_mdss_dp_link_clk_src = {
+	.cmd_rcgr = 0x2178,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_1,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_dp_link_clk_src",
+		.parent_data = dispcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 dispcc_mdss_dp_pixel1_clk_src = {
+	.cmd_rcgr = 0x21c4,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_1,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_dp_pixel1_clk_src",
+		.parent_data = dispcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 dispcc_mdss_dp_pixel_clk_src = {
+	.cmd_rcgr = 0x21ac,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_1,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_dp_pixel_clk_src",
+		.parent_data = dispcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 dispcc_mdss_esc0_clk_src = {
+	.cmd_rcgr = 0x2148,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_0,
+	.freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_esc0_clk_src",
+		.parent_data = dispcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 dispcc_mdss_esc1_clk_src = {
+	.cmd_rcgr = 0x2160,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_0,
+	.freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_esc1_clk_src",
+		.parent_data = dispcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_dispcc_mdss_mdp_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(85714286, P_GCC_DISP_GPLL0_CLK, 7, 0, 0),
+	F(100000000, P_GCC_DISP_GPLL0_CLK, 6, 0, 0),
+	F(150000000, P_GCC_DISP_GPLL0_CLK, 4, 0, 0),
+	F(172000000, P_DISPCC_PLL0_OUT_MAIN, 5, 0, 0),
+	F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0),
+	F(286666667, P_DISPCC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0),
+	F(344000000, P_DISPCC_PLL0_OUT_MAIN, 2.5, 0, 0),
+	F(430000000, P_DISPCC_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 dispcc_mdss_mdp_clk_src = {
+	.cmd_rcgr = 0x20c8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_3,
+	.freq_tbl = ftbl_dispcc_mdss_mdp_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_mdp_clk_src",
+		.parent_data = dispcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 dispcc_mdss_pclk0_clk_src = {
+	.cmd_rcgr = 0x2098,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_pclk0_clk_src",
+		.parent_data = dispcc_parent_data_4,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_pixel_ops,
+	},
+};
+
+static struct clk_rcg2 dispcc_mdss_pclk1_clk_src = {
+	.cmd_rcgr = 0x20b0,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_pclk1_clk_src",
+		.parent_data = dispcc_parent_data_4,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_pixel_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_dispcc_mdss_rot_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(171428571, P_GCC_DISP_GPLL0_CLK, 3.5, 0, 0),
+	F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0),
+	F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0),
+	F(344000000, P_DISPCC_PLL0_OUT_MAIN, 2.5, 0, 0),
+	F(430000000, P_DISPCC_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 dispcc_mdss_rot_clk_src = {
+	.cmd_rcgr = 0x20e0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_3,
+	.freq_tbl = ftbl_dispcc_mdss_rot_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_rot_clk_src",
+		.parent_data = dispcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_3),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 dispcc_mdss_vsync_clk_src = {
+	.cmd_rcgr = 0x20f8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_2,
+	.freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_mdss_vsync_clk_src",
+		.parent_data = dispcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_2),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_dispcc_sleep_clk_src[] = {
+	F(32000, P_CHIP_SLEEP_CLK, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 dispcc_sleep_clk_src = {
+	.cmd_rcgr = 0x6060,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_6,
+	.freq_tbl = ftbl_dispcc_sleep_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_sleep_clk_src",
+		.parent_data = dispcc_parent_data_6,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_6),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 dispcc_xo_clk_src = {
+	.cmd_rcgr = 0x6044,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = dispcc_parent_map_2,
+	.freq_tbl = ftbl_dispcc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "dispcc_xo_clk_src",
+		.parent_data = dispcc_parent_data_2_ao,
+		.num_parents = ARRAY_SIZE(dispcc_parent_data_2_ao),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_branch dispcc_mdss_ahb_clk = {
+	.halt_reg = 0x2080,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2080,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_byte0_clk = {
+	.halt_reg = 0x2028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_byte0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_byte0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_regmap_div dispcc_mdss_byte0_div_clk_src = {
+	.reg = 0x2128,
+	.shift = 0,
+	.width = 2,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_byte0_div_clk_src",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_byte0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_div_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_byte0_intf_clk = {
+	.halt_reg = 0x202c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x202c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_byte0_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_byte0_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_byte1_clk = {
+	.halt_reg = 0x2030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_byte1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_byte1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_regmap_div dispcc_mdss_byte1_div_clk_src = {
+	.reg = 0x2144,
+	.shift = 0,
+	.width = 2,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_byte1_div_clk_src",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_byte1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_div_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_byte1_intf_clk = {
+	.halt_reg = 0x2034,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2034,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_byte1_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_byte1_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_dp_aux_clk = {
+	.halt_reg = 0x2054,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_dp_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_dp_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_dp_crypto_clk = {
+	.halt_reg = 0x2048,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2048,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_dp_crypto_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_dp_crypto_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_dp_link_clk = {
+	.halt_reg = 0x2040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_dp_link_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_dp_link_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_dp_link_intf_clk = {
+	.halt_reg = 0x2044,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2044,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_dp_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_dp_link_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_dp_pixel1_clk = {
+	.halt_reg = 0x2050,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2050,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_dp_pixel1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_dp_pixel1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_dp_pixel_clk = {
+	.halt_reg = 0x204c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x204c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_dp_pixel_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_dp_pixel_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_esc0_clk = {
+	.halt_reg = 0x2038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_esc0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_esc0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_esc1_clk = {
+	.halt_reg = 0x203c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x203c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_esc1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_esc1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_mdp_clk = {
+	.halt_reg = 0x200c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x200c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_mdp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_mdp_lut_clk = {
+	.halt_reg = 0x201c,
+	.halt_check = BRANCH_VOTED,
+	.clkr = {
+		.enable_reg = 0x201c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_mdp_lut_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_non_gdsc_ahb_clk = {
+	.halt_reg = 0x4004,
+	.halt_check = BRANCH_VOTED,
+	.clkr = {
+		.enable_reg = 0x4004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_non_gdsc_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_pclk0_clk = {
+	.halt_reg = 0x2004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_pclk0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_pclk0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_pclk1_clk = {
+	.halt_reg = 0x2008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_pclk1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_pclk1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_rot_clk = {
+	.halt_reg = 0x2014,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_rot_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_rot_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_rscc_ahb_clk = {
+	.halt_reg = 0x400c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x400c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_rscc_ahb_clk",
+			.parent_names = (const char *[]) {
+				"dispcc_mdss_ahb_clk_src",
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_rscc_vsync_clk = {
+	.halt_reg = 0x4008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x4008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_rscc_vsync_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_vsync_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_mdss_vsync_clk = {
+	.halt_reg = 0x2024,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_mdss_vsync_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&dispcc_mdss_vsync_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch dispcc_sleep_clk = {
+	.halt_reg = 0x6078,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6078,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "dispcc_sleep_clk",
+			.parent_names = (const char *[]) {
+				"dispcc_sleep_clk_src",
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc mdss_gdsc = {
+	.gdscr = 0x3000,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "mdss_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = HW_CTRL,
+};
+
+static struct clk_regmap *dispcc_sm7150_clocks[] = {
+	[DISPCC_MDSS_AHB_CLK] = &dispcc_mdss_ahb_clk.clkr,
+	[DISPCC_MDSS_AHB_CLK_SRC] = &dispcc_mdss_ahb_clk_src.clkr,
+	[DISPCC_MDSS_BYTE0_CLK] = &dispcc_mdss_byte0_clk.clkr,
+	[DISPCC_MDSS_BYTE0_CLK_SRC] = &dispcc_mdss_byte0_clk_src.clkr,
+	[DISPCC_MDSS_BYTE0_DIV_CLK_SRC] = &dispcc_mdss_byte0_div_clk_src.clkr,
+	[DISPCC_MDSS_BYTE0_INTF_CLK] = &dispcc_mdss_byte0_intf_clk.clkr,
+	[DISPCC_MDSS_BYTE1_CLK] = &dispcc_mdss_byte1_clk.clkr,
+	[DISPCC_MDSS_BYTE1_CLK_SRC] = &dispcc_mdss_byte1_clk_src.clkr,
+	[DISPCC_MDSS_BYTE1_DIV_CLK_SRC] = &dispcc_mdss_byte1_div_clk_src.clkr,
+	[DISPCC_MDSS_BYTE1_INTF_CLK] = &dispcc_mdss_byte1_intf_clk.clkr,
+	[DISPCC_MDSS_DP_AUX_CLK] = &dispcc_mdss_dp_aux_clk.clkr,
+	[DISPCC_MDSS_DP_AUX_CLK_SRC] = &dispcc_mdss_dp_aux_clk_src.clkr,
+	[DISPCC_MDSS_DP_CRYPTO_CLK] = &dispcc_mdss_dp_crypto_clk.clkr,
+	[DISPCC_MDSS_DP_CRYPTO_CLK_SRC] = &dispcc_mdss_dp_crypto_clk_src.clkr,
+	[DISPCC_MDSS_DP_LINK_CLK] = &dispcc_mdss_dp_link_clk.clkr,
+	[DISPCC_MDSS_DP_LINK_CLK_SRC] = &dispcc_mdss_dp_link_clk_src.clkr,
+	[DISPCC_MDSS_DP_LINK_INTF_CLK] = &dispcc_mdss_dp_link_intf_clk.clkr,
+	[DISPCC_MDSS_DP_PIXEL1_CLK] = &dispcc_mdss_dp_pixel1_clk.clkr,
+	[DISPCC_MDSS_DP_PIXEL1_CLK_SRC] = &dispcc_mdss_dp_pixel1_clk_src.clkr,
+	[DISPCC_MDSS_DP_PIXEL_CLK] = &dispcc_mdss_dp_pixel_clk.clkr,
+	[DISPCC_MDSS_DP_PIXEL_CLK_SRC] = &dispcc_mdss_dp_pixel_clk_src.clkr,
+	[DISPCC_MDSS_ESC0_CLK] = &dispcc_mdss_esc0_clk.clkr,
+	[DISPCC_MDSS_ESC0_CLK_SRC] = &dispcc_mdss_esc0_clk_src.clkr,
+	[DISPCC_MDSS_ESC1_CLK] = &dispcc_mdss_esc1_clk.clkr,
+	[DISPCC_MDSS_ESC1_CLK_SRC] = &dispcc_mdss_esc1_clk_src.clkr,
+	[DISPCC_MDSS_MDP_CLK] = &dispcc_mdss_mdp_clk.clkr,
+	[DISPCC_MDSS_MDP_CLK_SRC] = &dispcc_mdss_mdp_clk_src.clkr,
+	[DISPCC_MDSS_MDP_LUT_CLK] = &dispcc_mdss_mdp_lut_clk.clkr,
+	[DISPCC_MDSS_NON_GDSC_AHB_CLK] = &dispcc_mdss_non_gdsc_ahb_clk.clkr,
+	[DISPCC_MDSS_PCLK0_CLK] = &dispcc_mdss_pclk0_clk.clkr,
+	[DISPCC_MDSS_PCLK0_CLK_SRC] = &dispcc_mdss_pclk0_clk_src.clkr,
+	[DISPCC_MDSS_PCLK1_CLK] = &dispcc_mdss_pclk1_clk.clkr,
+	[DISPCC_MDSS_PCLK1_CLK_SRC] = &dispcc_mdss_pclk1_clk_src.clkr,
+	[DISPCC_MDSS_ROT_CLK] = &dispcc_mdss_rot_clk.clkr,
+	[DISPCC_MDSS_ROT_CLK_SRC] = &dispcc_mdss_rot_clk_src.clkr,
+	[DISPCC_MDSS_RSCC_AHB_CLK] = &dispcc_mdss_rscc_ahb_clk.clkr,
+	[DISPCC_MDSS_RSCC_VSYNC_CLK] = &dispcc_mdss_rscc_vsync_clk.clkr,
+	[DISPCC_MDSS_VSYNC_CLK] = &dispcc_mdss_vsync_clk.clkr,
+	[DISPCC_MDSS_VSYNC_CLK_SRC] = &dispcc_mdss_vsync_clk_src.clkr,
+	[DISPCC_PLL0] = &dispcc_pll0.clkr,
+	[DISPCC_SLEEP_CLK] = &dispcc_sleep_clk.clkr,
+	[DISPCC_SLEEP_CLK_SRC] = &dispcc_sleep_clk_src.clkr,
+	[DISPCC_XO_CLK_SRC] = &dispcc_xo_clk_src.clkr,
+};
+
+static struct gdsc *dispcc_sm7150_gdscs[] = {
+	[MDSS_GDSC] = &mdss_gdsc,
+};
+
+static const struct regmap_config dispcc_sm7150_regmap_config = {
+	.reg_bits	= 32,
+	.reg_stride	= 4,
+	.val_bits	= 32,
+	.max_register	= 0x10000,
+	.fast_io	= true,
+};
+
+static const struct qcom_cc_desc dispcc_sm7150_desc = {
+	.config = &dispcc_sm7150_regmap_config,
+	.clks = dispcc_sm7150_clocks,
+	.num_clks = ARRAY_SIZE(dispcc_sm7150_clocks),
+	.gdscs = dispcc_sm7150_gdscs,
+	.num_gdscs = ARRAY_SIZE(dispcc_sm7150_gdscs),
+};
+
+static const struct of_device_id dispcc_sm7150_match_table[] = {
+	{ .compatible = "qcom,sm7150-dispcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, dispcc_sm7150_match_table);
+
+static int dispcc_sm7150_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+
+	regmap = qcom_cc_map(pdev, &dispcc_sm7150_desc);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	clk_fabia_pll_configure(&dispcc_pll0, regmap, &dispcc_pll0_config);
+	/* Enable clock gating for DSI and MDP clocks */
+	regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0);
+
+	/* Keep some clocks always-on */
+	qcom_branch_set_clk_en(regmap, 0x605c); /* DISPCC_XO_CLK */
+
+	return qcom_cc_really_probe(&pdev->dev, &dispcc_sm7150_desc, regmap);
+}
+
+static struct platform_driver dispcc_sm7150_driver = {
+	.probe = dispcc_sm7150_probe,
+	.driver = {
+		.name = "dispcc-sm7150",
+		.of_match_table = dispcc_sm7150_match_table,
+	},
+};
+
+module_platform_driver(dispcc_sm7150_driver);
+
+MODULE_DESCRIPTION("Qualcomm SM7150 Display Clock Controller");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-sm8250.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-sm8250.c
@@ -851,6 +851,7 @@
 				&disp_cc_mdss_dp_link1_div_clk_src.clkr.hw,
 			},
 			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -886,6 +887,7 @@
 				&disp_cc_mdss_dp_link_div_clk_src.clkr.hw,
 			},
 			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -1011,6 +1013,7 @@
 				&disp_cc_mdss_mdp_clk_src.clkr.hw,
 			},
 			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -1359,8 +1362,13 @@
 		disp_cc_sm8250_clocks[DISP_CC_MDSS_EDP_GTC_CLK_SRC] = NULL;
 	}
 
-	clk_lucid_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
-	clk_lucid_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll1_config);
+	if (of_device_is_compatible(pdev->dev.of_node, "qcom,sm8350-dispcc")) {
+		clk_lucid_5lpe_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
+		clk_lucid_5lpe_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll1_config);
+	} else {
+		clk_lucid_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
+		clk_lucid_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll1_config);
+	}
 
 	/* Enable clock gating for MDP clocks */
 	regmap_update_bits(regmap, 0x8000, 0x10, 0x10);
@@ -1368,7 +1376,7 @@
 	/* DISP_CC_XO_CLK always-on */
 	regmap_update_bits(regmap, 0x605c, BIT(0), BIT(0));
 
-	ret = qcom_cc_really_probe(pdev, &disp_cc_sm8250_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm8250_desc, regmap);
 
 	pm_runtime_put(&pdev->dev);
 
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-sm8450.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-sm8450.c
@@ -309,26 +309,17 @@
 	},
 };
 
-static const struct freq_tbl ftbl_disp_cc_mdss_dptx0_link_clk_src[] = {
-	F(162000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
-	F(270000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
-	F(540000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
-	F(810000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
-	{ }
-};
-
 static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = {
 	.cmd_rcgr = 0x819c,
 	.mnd_width = 0,
 	.hid_width = 5,
 	.parent_map = disp_cc_parent_map_3,
-	.freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
 	.clkr.hw.init = &(struct clk_init_data) {
 		.name = "disp_cc_mdss_dptx0_link_clk_src",
 		.parent_data = disp_cc_parent_data_3,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_byte2_ops,
 	},
 };
 
@@ -382,13 +373,12 @@
 	.mnd_width = 0,
 	.hid_width = 5,
 	.parent_map = disp_cc_parent_map_3,
-	.freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
 	.clkr.hw.init = &(struct clk_init_data) {
 		.name = "disp_cc_mdss_dptx1_link_clk_src",
 		.parent_data = disp_cc_parent_data_3,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_byte2_ops,
 	},
 };
 
@@ -442,13 +432,12 @@
 	.mnd_width = 0,
 	.hid_width = 5,
 	.parent_map = disp_cc_parent_map_3,
-	.freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
 	.clkr.hw.init = &(struct clk_init_data) {
 		.name = "disp_cc_mdss_dptx2_link_clk_src",
 		.parent_data = disp_cc_parent_data_3,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_byte2_ops,
 	},
 };
 
@@ -502,13 +491,12 @@
 	.mnd_width = 0,
 	.hid_width = 5,
 	.parent_map = disp_cc_parent_map_3,
-	.freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
 	.clkr.hw.init = &(struct clk_init_data) {
 		.name = "disp_cc_mdss_dptx3_link_clk_src",
 		.parent_data = disp_cc_parent_data_3,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_byte2_ops,
 	},
 };
 
@@ -1793,7 +1781,7 @@
 	 */
 	regmap_update_bits(regmap, 0xe05c, BIT(0), BIT(0));
 
-	ret = qcom_cc_really_probe(pdev, &disp_cc_sm8450_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm8450_desc, regmap);
 	if (ret)
 		goto err_put_rpm;
 
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-sm8550.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-sm8550.c
@@ -196,7 +196,7 @@
 static const struct parent_map disp_cc_parent_map_4[] = {
 	{ P_BI_TCXO, 0 },
 	{ P_DP0_PHY_PLL_LINK_CLK, 1 },
-	{ P_DP1_PHY_PLL_VCO_DIV_CLK, 2 },
+	{ P_DP0_PHY_PLL_VCO_DIV_CLK, 2 },
 	{ P_DP3_PHY_PLL_VCO_DIV_CLK, 3 },
 	{ P_DP1_PHY_PLL_VCO_DIV_CLK, 4 },
 	{ P_DP2_PHY_PLL_VCO_DIV_CLK, 6 },
@@ -213,7 +213,7 @@
 
 static const struct parent_map disp_cc_parent_map_5[] = {
 	{ P_BI_TCXO, 0 },
-	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 4 },
+	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
 	{ P_DSI1_PHY_PLL_OUT_BYTECLK, 4 },
 };
 
@@ -345,26 +345,17 @@
 	},
 };
 
-static const struct freq_tbl ftbl_disp_cc_mdss_dptx0_link_clk_src[] = {
-	F(162000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
-	F(270000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
-	F(540000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
-	F(810000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
-	{ }
-};
-
 static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = {
 	.cmd_rcgr = 0x8170,
 	.mnd_width = 0,
 	.hid_width = 5,
 	.parent_map = disp_cc_parent_map_7,
-	.freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
 	.clkr.hw.init = &(struct clk_init_data) {
 		.name = "disp_cc_mdss_dptx0_link_clk_src",
 		.parent_data = disp_cc_parent_data_7,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_7),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_byte2_ops,
 	},
 };
 
@@ -409,7 +400,7 @@
 		.parent_data = disp_cc_parent_data_0,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_dp_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -418,13 +409,12 @@
 	.mnd_width = 0,
 	.hid_width = 5,
 	.parent_map = disp_cc_parent_map_3,
-	.freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
 	.clkr.hw.init = &(struct clk_init_data) {
 		.name = "disp_cc_mdss_dptx1_link_clk_src",
 		.parent_data = disp_cc_parent_data_3,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_byte2_ops,
 	},
 };
 
@@ -478,13 +468,12 @@
 	.mnd_width = 0,
 	.hid_width = 5,
 	.parent_map = disp_cc_parent_map_3,
-	.freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
 	.clkr.hw.init = &(struct clk_init_data) {
 		.name = "disp_cc_mdss_dptx2_link_clk_src",
 		.parent_data = disp_cc_parent_data_3,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_byte2_ops,
 	},
 };
 
@@ -538,13 +527,12 @@
 	.mnd_width = 0,
 	.hid_width = 5,
 	.parent_map = disp_cc_parent_map_3,
-	.freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
 	.clkr.hw.init = &(struct clk_init_data) {
 		.name = "disp_cc_mdss_dptx3_link_clk_src",
 		.parent_data = disp_cc_parent_data_3,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_byte2_ops,
 	},
 };
 
@@ -574,7 +562,7 @@
 		.parent_data = disp_cc_parent_data_5,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_rcg2_shared_ops,
 	},
 };
 
@@ -589,7 +577,7 @@
 		.parent_data = disp_cc_parent_data_5,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_rcg2_shared_ops,
 	},
 };
 
@@ -1623,7 +1611,7 @@
 		.name = "mdss_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
-	.flags = HW_CTRL | RETAIN_FF_ENABLE,
+	.flags = POLL_CFG_GDSCR | HW_CTRL | RETAIN_FF_ENABLE,
 };
 
 static struct gdsc mdss_int2_gdsc = {
@@ -1632,7 +1620,7 @@
 		.name = "mdss_int2_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
-	.flags = HW_CTRL | RETAIN_FF_ENABLE,
+	.flags = POLL_CFG_GDSCR | HW_CTRL | RETAIN_FF_ENABLE,
 };
 
 static struct clk_regmap *disp_cc_sm8550_clocks[] = {
@@ -1786,7 +1774,7 @@
 	 */
 	regmap_update_bits(regmap, 0xe054, BIT(0), BIT(0));
 
-	ret = qcom_cc_really_probe(pdev, &disp_cc_sm8550_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm8550_desc, regmap);
 	if (ret)
 		goto err_put_rpm;
 
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-sm8650.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-sm8650.c
@@ -343,26 +343,17 @@
 	},
 };
 
-static const struct freq_tbl ftbl_disp_cc_mdss_dptx0_link_clk_src[] = {
-	F(162000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
-	F(270000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
-	F(540000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
-	F(810000, P_DP0_PHY_PLL_LINK_CLK, 1, 0, 0),
-	{ }
-};
-
 static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = {
 	.cmd_rcgr = 0x8170,
 	.mnd_width = 0,
 	.hid_width = 5,
 	.parent_map = disp_cc_parent_map_7,
-	.freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
 	.clkr.hw.init = &(const struct clk_init_data) {
 		.name = "disp_cc_mdss_dptx0_link_clk_src",
 		.parent_data = disp_cc_parent_data_7,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_7),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_byte2_ops,
 	},
 };
 
@@ -416,13 +407,12 @@
 	.mnd_width = 0,
 	.hid_width = 5,
 	.parent_map = disp_cc_parent_map_3,
-	.freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
 	.clkr.hw.init = &(const struct clk_init_data) {
 		.name = "disp_cc_mdss_dptx1_link_clk_src",
 		.parent_data = disp_cc_parent_data_3,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_byte2_ops,
 	},
 };
 
@@ -476,13 +466,12 @@
 	.mnd_width = 0,
 	.hid_width = 5,
 	.parent_map = disp_cc_parent_map_3,
-	.freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
 	.clkr.hw.init = &(const struct clk_init_data) {
 		.name = "disp_cc_mdss_dptx2_link_clk_src",
 		.parent_data = disp_cc_parent_data_3,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_byte2_ops,
 	},
 };
 
@@ -536,13 +525,12 @@
 	.mnd_width = 0,
 	.hid_width = 5,
 	.parent_map = disp_cc_parent_map_3,
-	.freq_tbl = ftbl_disp_cc_mdss_dptx0_link_clk_src,
 	.clkr.hw.init = &(const struct clk_init_data) {
 		.name = "disp_cc_mdss_dptx3_link_clk_src",
 		.parent_data = disp_cc_parent_data_3,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_byte2_ops,
 	},
 };
 
@@ -1780,7 +1768,7 @@
 	/* Keep clocks always enabled */
 	regmap_update_bits(regmap, 0xe054, BIT(0), BIT(0)); /* disp_cc_xo_clk */
 
-	ret = qcom_cc_really_probe(pdev, &disp_cc_sm8650_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_sm8650_desc, regmap);
 	if (ret)
 		goto err_put_rpm;
 
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc-x1e80100.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc-x1e80100.c
@@ -0,0 +1,1718 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,x1e80100-dispcc.h>
+
+#include "common.h"
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "reset.h"
+#include "gdsc.h"
+
+/* Need to match the order of clocks in DT binding */
+enum {
+	DT_BI_TCXO,
+	DT_BI_TCXO_AO,
+	DT_AHB_CLK,
+	DT_SLEEP_CLK,
+
+	DT_DSI0_PHY_PLL_OUT_BYTECLK,
+	DT_DSI0_PHY_PLL_OUT_DSICLK,
+	DT_DSI1_PHY_PLL_OUT_BYTECLK,
+	DT_DSI1_PHY_PLL_OUT_DSICLK,
+
+	DT_DP0_PHY_PLL_LINK_CLK,
+	DT_DP0_PHY_PLL_VCO_DIV_CLK,
+	DT_DP1_PHY_PLL_LINK_CLK,
+	DT_DP1_PHY_PLL_VCO_DIV_CLK,
+	DT_DP2_PHY_PLL_LINK_CLK,
+	DT_DP2_PHY_PLL_VCO_DIV_CLK,
+	DT_DP3_PHY_PLL_LINK_CLK,
+	DT_DP3_PHY_PLL_VCO_DIV_CLK,
+};
+
+#define DISP_CC_MISC_CMD	0xF000
+
+enum {
+	P_BI_TCXO,
+	P_BI_TCXO_AO,
+	P_DISP_CC_PLL0_OUT_MAIN,
+	P_DISP_CC_PLL1_OUT_EVEN,
+	P_DISP_CC_PLL1_OUT_MAIN,
+	P_DP0_PHY_PLL_LINK_CLK,
+	P_DP0_PHY_PLL_VCO_DIV_CLK,
+	P_DP1_PHY_PLL_LINK_CLK,
+	P_DP1_PHY_PLL_VCO_DIV_CLK,
+	P_DP2_PHY_PLL_LINK_CLK,
+	P_DP2_PHY_PLL_VCO_DIV_CLK,
+	P_DP3_PHY_PLL_LINK_CLK,
+	P_DP3_PHY_PLL_VCO_DIV_CLK,
+	P_DSI0_PHY_PLL_OUT_BYTECLK,
+	P_DSI0_PHY_PLL_OUT_DSICLK,
+	P_DSI1_PHY_PLL_OUT_BYTECLK,
+	P_DSI1_PHY_PLL_OUT_DSICLK,
+	P_SLEEP_CLK,
+};
+
+static const struct pll_vco lucid_ole_vco[] = {
+	{ 249600000, 2300000000, 0 },
+};
+
+static const struct alpha_pll_config disp_cc_pll0_config = {
+	.l = 0xd,
+	.alpha = 0x6492,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x82aa299c,
+	.test_ctl_val = 0x00000000,
+	.test_ctl_hi_val = 0x00000003,
+	.test_ctl_hi1_val = 0x00009000,
+	.test_ctl_hi2_val = 0x00000034,
+	.user_ctl_val = 0x00000000,
+	.user_ctl_hi_val = 0x00000005,
+};
+
+static struct clk_alpha_pll disp_cc_pll0 = {
+	.offset = 0x0,
+	.vco_table = lucid_ole_vco,
+	.num_vco = ARRAY_SIZE(lucid_ole_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_reset_lucid_ole_ops,
+		},
+	},
+};
+
+static const struct alpha_pll_config disp_cc_pll1_config = {
+	.l = 0x1f,
+	.alpha = 0x4000,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x82aa299c,
+	.test_ctl_val = 0x00000000,
+	.test_ctl_hi_val = 0x00000003,
+	.test_ctl_hi1_val = 0x00009000,
+	.test_ctl_hi2_val = 0x00000034,
+	.user_ctl_val = 0x00000000,
+	.user_ctl_hi_val = 0x00000005,
+};
+
+static struct clk_alpha_pll disp_cc_pll1 = {
+	.offset = 0x1000,
+	.vco_table = lucid_ole_vco,
+	.num_vco = ARRAY_SIZE(lucid_ole_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_pll1",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_reset_lucid_ole_ops,
+		},
+	},
+};
+
+static const struct parent_map disp_cc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DP0_PHY_PLL_LINK_CLK, 1 },
+	{ P_DP0_PHY_PLL_VCO_DIV_CLK, 2 },
+	{ P_DP3_PHY_PLL_VCO_DIV_CLK, 3 },
+	{ P_DP1_PHY_PLL_VCO_DIV_CLK, 4 },
+	{ P_DP2_PHY_PLL_VCO_DIV_CLK, 6 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DP0_PHY_PLL_LINK_CLK },
+	{ .index = DT_DP0_PHY_PLL_VCO_DIV_CLK },
+	{ .index = DT_DP3_PHY_PLL_VCO_DIV_CLK },
+	{ .index = DT_DP1_PHY_PLL_VCO_DIV_CLK },
+	{ .index = DT_DP2_PHY_PLL_VCO_DIV_CLK },
+};
+
+static const struct parent_map disp_cc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_1_ao[] = {
+	{ .index = DT_BI_TCXO_AO },
+};
+
+static const struct parent_map disp_cc_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
+	{ P_DSI1_PHY_PLL_OUT_DSICLK, 3 },
+	{ P_DSI1_PHY_PLL_OUT_BYTECLK, 4 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
+	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
+	{ .index = DT_DSI1_PHY_PLL_OUT_DSICLK },
+	{ .index = DT_DSI1_PHY_PLL_OUT_BYTECLK },
+};
+
+static const struct parent_map disp_cc_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DP0_PHY_PLL_LINK_CLK, 1 },
+	{ P_DP1_PHY_PLL_LINK_CLK, 2 },
+	{ P_DP2_PHY_PLL_LINK_CLK, 3 },
+	{ P_DP3_PHY_PLL_LINK_CLK, 4 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DP0_PHY_PLL_LINK_CLK },
+	{ .index = DT_DP1_PHY_PLL_LINK_CLK },
+	{ .index = DT_DP2_PHY_PLL_LINK_CLK },
+	{ .index = DT_DP3_PHY_PLL_LINK_CLK },
+};
+
+static const struct parent_map disp_cc_parent_map_4[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
+	{ P_DSI1_PHY_PLL_OUT_BYTECLK, 4 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_4[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
+	{ .index = DT_DSI1_PHY_PLL_OUT_BYTECLK },
+};
+
+static const struct parent_map disp_cc_parent_map_5[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DISP_CC_PLL1_OUT_MAIN, 4 },
+	{ P_DISP_CC_PLL1_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_5[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &disp_cc_pll1.clkr.hw },
+	{ .hw = &disp_cc_pll1.clkr.hw },
+};
+
+static const struct parent_map disp_cc_parent_map_6[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DISP_CC_PLL0_OUT_MAIN, 1 },
+	{ P_DISP_CC_PLL1_OUT_MAIN, 4 },
+	{ P_DISP_CC_PLL1_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_6[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &disp_cc_pll0.clkr.hw },
+	{ .hw = &disp_cc_pll1.clkr.hw },
+	{ .hw = &disp_cc_pll1.clkr.hw },
+};
+
+static const struct parent_map disp_cc_parent_map_7[] = {
+	{ P_SLEEP_CLK, 0 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_7[] = {
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(37500000, P_DISP_CC_PLL1_OUT_MAIN, 16, 0, 0),
+	F(75000000, P_DISP_CC_PLL1_OUT_MAIN, 8, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
+	.cmd_rcgr = 0x82ec,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_5,
+	.freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_ahb_clk_src",
+		.parent_data = disp_cc_parent_data_5,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_byte0_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
+	.cmd_rcgr = 0x810c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_2,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_byte0_clk_src",
+		.parent_data = disp_cc_parent_data_2,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = {
+	.cmd_rcgr = 0x8128,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_2,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_byte1_clk_src",
+		.parent_data = disp_cc_parent_data_2,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx0_aux_clk_src = {
+	.cmd_rcgr = 0x81c0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_1,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx0_aux_clk_src",
+		.parent_data = disp_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = {
+	.cmd_rcgr = 0x8174,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_3,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx0_link_clk_src",
+		.parent_data = disp_cc_parent_data_3,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx0_pixel0_clk_src = {
+	.cmd_rcgr = 0x8190,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx0_pixel0_clk_src",
+		.parent_data = disp_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx0_pixel1_clk_src = {
+	.cmd_rcgr = 0x81a8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx0_pixel1_clk_src",
+		.parent_data = disp_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx1_aux_clk_src = {
+	.cmd_rcgr = 0x8224,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_1,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx1_aux_clk_src",
+		.parent_data = disp_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx1_link_clk_src = {
+	.cmd_rcgr = 0x8208,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_3,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx1_link_clk_src",
+		.parent_data = disp_cc_parent_data_3,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx1_pixel0_clk_src = {
+	.cmd_rcgr = 0x81d8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx1_pixel0_clk_src",
+		.parent_data = disp_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx1_pixel1_clk_src = {
+	.cmd_rcgr = 0x81f0,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx1_pixel1_clk_src",
+		.parent_data = disp_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx2_aux_clk_src = {
+	.cmd_rcgr = 0x8288,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_1,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx2_aux_clk_src",
+		.parent_data = disp_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx2_link_clk_src = {
+	.cmd_rcgr = 0x823c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_3,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx2_link_clk_src",
+		.parent_data = disp_cc_parent_data_3,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx2_pixel0_clk_src = {
+	.cmd_rcgr = 0x8258,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx2_pixel0_clk_src",
+		.parent_data = disp_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx2_pixel1_clk_src = {
+	.cmd_rcgr = 0x8270,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx2_pixel1_clk_src",
+		.parent_data = disp_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx3_aux_clk_src = {
+	.cmd_rcgr = 0x82d4,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_1,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx3_aux_clk_src",
+		.parent_data = disp_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx3_link_clk_src = {
+	.cmd_rcgr = 0x82b8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_3,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx3_link_clk_src",
+		.parent_data = disp_cc_parent_data_3,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx3_pixel0_clk_src = {
+	.cmd_rcgr = 0x82a0,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx3_pixel0_clk_src",
+		.parent_data = disp_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
+	.cmd_rcgr = 0x8144,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_4,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_esc0_clk_src",
+		.parent_data = disp_cc_parent_data_4,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = {
+	.cmd_rcgr = 0x815c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_4,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_esc1_clk_src",
+		.parent_data = disp_cc_parent_data_4,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(85714286, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(100000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(150000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(172000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(200000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(325000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(375000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(514000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(575000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
+	.cmd_rcgr = 0x80dc,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_6,
+	.freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_mdp_clk_src",
+		.parent_data = disp_cc_parent_data_6,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_6),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
+	.cmd_rcgr = 0x80ac,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_2,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_pclk0_clk_src",
+		.parent_data = disp_cc_parent_data_2,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_pixel_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = {
+	.cmd_rcgr = 0x80c4,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_2,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_pclk1_clk_src",
+		.parent_data = disp_cc_parent_data_2,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_pixel_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
+	.cmd_rcgr = 0x80f4,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_1,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_vsync_clk_src",
+		.parent_data = disp_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = {
+	F(32000, P_SLEEP_CLK, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 disp_cc_sleep_clk_src = {
+	.cmd_rcgr = 0xe05c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_7,
+	.freq_tbl = ftbl_disp_cc_sleep_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_sleep_clk_src",
+		.parent_data = disp_cc_parent_data_7,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_7),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_xo_clk_src = {
+	.cmd_rcgr = 0xe03c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_1,
+	.freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_xo_clk_src",
+		.parent_data = disp_cc_parent_data_1_ao,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1_ao),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
+	.reg = 0x8124,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_byte0_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&disp_cc_mdss_byte0_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = {
+	.reg = 0x8140,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_byte1_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&disp_cc_mdss_byte1_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div disp_cc_mdss_dptx0_link_div_clk_src = {
+	.reg = 0x818c,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx0_link_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div disp_cc_mdss_dptx1_link_div_clk_src = {
+	.reg = 0x8220,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx1_link_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&disp_cc_mdss_dptx1_link_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div disp_cc_mdss_dptx2_link_div_clk_src = {
+	.reg = 0x8254,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx2_link_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&disp_cc_mdss_dptx2_link_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div disp_cc_mdss_dptx3_link_div_clk_src = {
+	.reg = 0x82d0,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx3_link_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&disp_cc_mdss_dptx3_link_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_branch disp_cc_mdss_accu_clk = {
+	.halt_reg = 0xe058,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xe058,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_accu_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_ahb1_clk = {
+	.halt_reg = 0xa020,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_ahb1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_ahb_clk = {
+	.halt_reg = 0x80a8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x80a8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_byte0_clk = {
+	.halt_reg = 0x8028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_byte0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_byte0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
+	.halt_reg = 0x802c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x802c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_byte0_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_byte0_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_byte1_clk = {
+	.halt_reg = 0x8030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_byte1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_byte1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_byte1_intf_clk = {
+	.halt_reg = 0x8034,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8034,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_byte1_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_byte1_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx0_aux_clk = {
+	.halt_reg = 0x8058,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8058,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx0_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx0_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx0_link_clk = {
+	.halt_reg = 0x8040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx0_link_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx0_link_intf_clk = {
+	.halt_reg = 0x8048,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8048,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx0_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx0_pixel0_clk = {
+	.halt_reg = 0x8050,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8050,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx0_pixel0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx0_pixel0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx0_pixel1_clk = {
+	.halt_reg = 0x8054,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx0_pixel1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx0_pixel1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx0_usb_router_link_intf_clk = {
+	.halt_reg = 0x8044,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8044,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx0_usb_router_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx1_aux_clk = {
+	.halt_reg = 0x8074,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8074,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx1_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx1_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx1_link_clk = {
+	.halt_reg = 0x8064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx1_link_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx1_link_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx1_link_intf_clk = {
+	.halt_reg = 0x806c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x806c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx1_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx1_pixel0_clk = {
+	.halt_reg = 0x805c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x805c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx1_pixel0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx1_pixel0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx1_pixel1_clk = {
+	.halt_reg = 0x8060,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8060,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx1_pixel1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx1_pixel1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx1_usb_router_link_intf_clk = {
+	.halt_reg = 0x8068,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8068,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx1_usb_router_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx2_aux_clk = {
+	.halt_reg = 0x8090,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8090,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx2_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx2_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx2_link_clk = {
+	.halt_reg = 0x8080,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8080,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx2_link_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx2_link_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx2_link_intf_clk = {
+	.halt_reg = 0x8084,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8084,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx2_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx2_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx2_pixel0_clk = {
+	.halt_reg = 0x8078,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8078,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx2_pixel0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx2_pixel0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx2_pixel1_clk = {
+	.halt_reg = 0x807c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x807c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx2_pixel1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx2_pixel1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx2_usb_router_link_intf_clk = {
+	.halt_reg = 0x8088,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8088,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx2_usb_router_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx2_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx3_aux_clk = {
+	.halt_reg = 0x80a0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x80a0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx3_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx3_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx3_link_clk = {
+	.halt_reg = 0x8098,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8098,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx3_link_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx3_link_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx3_link_intf_clk = {
+	.halt_reg = 0x809c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x809c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx3_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx3_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_dptx3_pixel0_clk = {
+	.halt_reg = 0x8094,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8094,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx3_pixel0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_dptx3_pixel0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_esc0_clk = {
+	.halt_reg = 0x8038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_esc0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_esc0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_esc1_clk = {
+	.halt_reg = 0x803c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x803c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_esc1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_esc1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_mdp1_clk = {
+	.halt_reg = 0xa004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_mdp1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_mdp_clk = {
+	.halt_reg = 0x800c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x800c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_mdp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_mdp_lut1_clk = {
+	.halt_reg = 0xa010,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_mdp_lut1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
+	.halt_reg = 0x8018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x8018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_mdp_lut_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
+	.halt_reg = 0xc004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xc004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_non_gdsc_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_pclk0_clk = {
+	.halt_reg = 0x8004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_pclk0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_pclk0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_pclk1_clk = {
+	.halt_reg = 0x8008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_pclk1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_pclk1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
+	.halt_reg = 0xc00c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc00c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_rscc_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
+	.halt_reg = 0xc008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xc008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_rscc_vsync_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_vsync_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_vsync1_clk = {
+	.halt_reg = 0xa01c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa01c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_vsync1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_vsync_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_vsync_clk = {
+	.halt_reg = 0x8024,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_vsync_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_vsync_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc mdss_gdsc = {
+	.gdscr = 0x9000,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "mdss_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = HW_CTRL | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc mdss_int2_gdsc = {
+	.gdscr = 0xb000,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "mdss_int2_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = HW_CTRL | RETAIN_FF_ENABLE,
+};
+
+static struct clk_regmap *disp_cc_x1e80100_clocks[] = {
+	[DISP_CC_MDSS_ACCU_CLK] = &disp_cc_mdss_accu_clk.clkr,
+	[DISP_CC_MDSS_AHB1_CLK] = &disp_cc_mdss_ahb1_clk.clkr,
+	[DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
+	[DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
+	[DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
+	[DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
+	[DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
+	[DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
+	[DISP_CC_MDSS_BYTE1_CLK] = &disp_cc_mdss_byte1_clk.clkr,
+	[DISP_CC_MDSS_BYTE1_CLK_SRC] = &disp_cc_mdss_byte1_clk_src.clkr,
+	[DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = &disp_cc_mdss_byte1_div_clk_src.clkr,
+	[DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr,
+	[DISP_CC_MDSS_DPTX0_AUX_CLK] = &disp_cc_mdss_dptx0_aux_clk.clkr,
+	[DISP_CC_MDSS_DPTX0_AUX_CLK_SRC] = &disp_cc_mdss_dptx0_aux_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX0_LINK_CLK] = &disp_cc_mdss_dptx0_link_clk.clkr,
+	[DISP_CC_MDSS_DPTX0_LINK_CLK_SRC] = &disp_cc_mdss_dptx0_link_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx0_link_div_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX0_LINK_INTF_CLK] = &disp_cc_mdss_dptx0_link_intf_clk.clkr,
+	[DISP_CC_MDSS_DPTX0_PIXEL0_CLK] = &disp_cc_mdss_dptx0_pixel0_clk.clkr,
+	[DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx0_pixel0_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX0_PIXEL1_CLK] = &disp_cc_mdss_dptx0_pixel1_clk.clkr,
+	[DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx0_pixel1_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK] =
+		&disp_cc_mdss_dptx0_usb_router_link_intf_clk.clkr,
+	[DISP_CC_MDSS_DPTX1_AUX_CLK] = &disp_cc_mdss_dptx1_aux_clk.clkr,
+	[DISP_CC_MDSS_DPTX1_AUX_CLK_SRC] = &disp_cc_mdss_dptx1_aux_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX1_LINK_CLK] = &disp_cc_mdss_dptx1_link_clk.clkr,
+	[DISP_CC_MDSS_DPTX1_LINK_CLK_SRC] = &disp_cc_mdss_dptx1_link_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx1_link_div_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX1_LINK_INTF_CLK] = &disp_cc_mdss_dptx1_link_intf_clk.clkr,
+	[DISP_CC_MDSS_DPTX1_PIXEL0_CLK] = &disp_cc_mdss_dptx1_pixel0_clk.clkr,
+	[DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx1_pixel0_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX1_PIXEL1_CLK] = &disp_cc_mdss_dptx1_pixel1_clk.clkr,
+	[DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx1_pixel1_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK] =
+		&disp_cc_mdss_dptx1_usb_router_link_intf_clk.clkr,
+	[DISP_CC_MDSS_DPTX2_AUX_CLK] = &disp_cc_mdss_dptx2_aux_clk.clkr,
+	[DISP_CC_MDSS_DPTX2_AUX_CLK_SRC] = &disp_cc_mdss_dptx2_aux_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX2_LINK_CLK] = &disp_cc_mdss_dptx2_link_clk.clkr,
+	[DISP_CC_MDSS_DPTX2_LINK_CLK_SRC] = &disp_cc_mdss_dptx2_link_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX2_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx2_link_div_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX2_LINK_INTF_CLK] = &disp_cc_mdss_dptx2_link_intf_clk.clkr,
+	[DISP_CC_MDSS_DPTX2_PIXEL0_CLK] = &disp_cc_mdss_dptx2_pixel0_clk.clkr,
+	[DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx2_pixel0_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX2_PIXEL1_CLK] = &disp_cc_mdss_dptx2_pixel1_clk.clkr,
+	[DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx2_pixel1_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX2_USB_ROUTER_LINK_INTF_CLK] =
+		&disp_cc_mdss_dptx2_usb_router_link_intf_clk.clkr,
+	[DISP_CC_MDSS_DPTX3_AUX_CLK] = &disp_cc_mdss_dptx3_aux_clk.clkr,
+	[DISP_CC_MDSS_DPTX3_AUX_CLK_SRC] = &disp_cc_mdss_dptx3_aux_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX3_LINK_CLK] = &disp_cc_mdss_dptx3_link_clk.clkr,
+	[DISP_CC_MDSS_DPTX3_LINK_CLK_SRC] = &disp_cc_mdss_dptx3_link_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX3_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx3_link_div_clk_src.clkr,
+	[DISP_CC_MDSS_DPTX3_LINK_INTF_CLK] = &disp_cc_mdss_dptx3_link_intf_clk.clkr,
+	[DISP_CC_MDSS_DPTX3_PIXEL0_CLK] = &disp_cc_mdss_dptx3_pixel0_clk.clkr,
+	[DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx3_pixel0_clk_src.clkr,
+	[DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
+	[DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
+	[DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr,
+	[DISP_CC_MDSS_ESC1_CLK_SRC] = &disp_cc_mdss_esc1_clk_src.clkr,
+	[DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr,
+	[DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
+	[DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
+	[DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr,
+	[DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
+	[DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
+	[DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
+	[DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
+	[DISP_CC_MDSS_PCLK1_CLK] = &disp_cc_mdss_pclk1_clk.clkr,
+	[DISP_CC_MDSS_PCLK1_CLK_SRC] = &disp_cc_mdss_pclk1_clk_src.clkr,
+	[DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
+	[DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
+	[DISP_CC_MDSS_VSYNC1_CLK] = &disp_cc_mdss_vsync1_clk.clkr,
+	[DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
+	[DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
+	[DISP_CC_PLL0] = &disp_cc_pll0.clkr,
+	[DISP_CC_PLL1] = &disp_cc_pll1.clkr,
+	[DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr,
+	[DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr,
+};
+
+static const struct qcom_reset_map disp_cc_x1e80100_resets[] = {
+	[DISP_CC_MDSS_CORE_BCR] = { 0x8000 },
+	[DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 },
+	[DISP_CC_MDSS_RSCC_BCR] = { 0xc000 },
+};
+
+static struct gdsc *disp_cc_x1e80100_gdscs[] = {
+	[MDSS_GDSC] = &mdss_gdsc,
+	[MDSS_INT2_GDSC] = &mdss_int2_gdsc,
+};
+
+static const struct regmap_config disp_cc_x1e80100_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x11008,
+	.fast_io = true,
+};
+
+static const struct qcom_cc_desc disp_cc_x1e80100_desc = {
+	.config = &disp_cc_x1e80100_regmap_config,
+	.clks = disp_cc_x1e80100_clocks,
+	.num_clks = ARRAY_SIZE(disp_cc_x1e80100_clocks),
+	.resets = disp_cc_x1e80100_resets,
+	.num_resets = ARRAY_SIZE(disp_cc_x1e80100_resets),
+	.gdscs = disp_cc_x1e80100_gdscs,
+	.num_gdscs = ARRAY_SIZE(disp_cc_x1e80100_gdscs),
+};
+
+static const struct of_device_id disp_cc_x1e80100_match_table[] = {
+	{ .compatible = "qcom,x1e80100-dispcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, disp_cc_x1e80100_match_table);
+
+static int disp_cc_x1e80100_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+	int ret;
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret)
+		return ret;
+
+	regmap = qcom_cc_map(pdev, &disp_cc_x1e80100_desc);
+	if (IS_ERR(regmap)) {
+		ret = PTR_ERR(regmap);
+		goto err_put_rpm;
+	}
+
+	clk_lucid_evo_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
+	clk_lucid_evo_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll1_config);
+
+	/* Enable clock gating for MDP clocks */
+	regmap_update_bits(regmap, DISP_CC_MISC_CMD, 0x10, 0x10);
+
+	/* Keep clocks always enabled */
+	regmap_update_bits(regmap, 0xe074, BIT(0), BIT(0)); /* disp_cc_sleep_clk */
+	regmap_update_bits(regmap, 0xe054, BIT(0), BIT(0)); /* disp_cc_xo_clk */
+
+	ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_x1e80100_desc, regmap);
+	if (ret)
+		goto err_put_rpm;
+
+	pm_runtime_put(&pdev->dev);
+
+	return 0;
+
+err_put_rpm:
+	pm_runtime_put_sync(&pdev->dev);
+
+	return ret;
+}
+
+static struct platform_driver disp_cc_x1e80100_driver = {
+	.probe = disp_cc_x1e80100_probe,
+	.driver = {
+		.name = "dispcc-x1e80100",
+		.of_match_table = disp_cc_x1e80100_match_table,
+	},
+};
+
+static int __init disp_cc_x1e80100_init(void)
+{
+	return platform_driver_register(&disp_cc_x1e80100_driver);
+}
+subsys_initcall(disp_cc_x1e80100_init);
+
+static void __exit disp_cc_x1e80100_exit(void)
+{
+	platform_driver_unregister(&disp_cc_x1e80100_driver);
+}
+module_exit(disp_cc_x1e80100_exit);
+
+MODULE_DESCRIPTION("QTI Display Clock Controller X1E80100 Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc0-sa8775p.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc0-sa8775p.c
@@ -0,0 +1,1486 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,sa8775p-dispcc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_IFACE,
+	DT_BI_TCXO,
+	DT_BI_TCXO_AO,
+	DT_SLEEP_CLK,
+	DT_DP0_PHY_PLL_LINK_CLK,
+	DT_DP0_PHY_PLL_VCO_DIV_CLK,
+	DT_DP1_PHY_PLL_LINK_CLK,
+	DT_DP1_PHY_PLL_VCO_DIV_CLK,
+	DT_DSI0_PHY_PLL_OUT_BYTECLK,
+	DT_DSI0_PHY_PLL_OUT_DSICLK,
+	DT_DSI1_PHY_PLL_OUT_BYTECLK,
+	DT_DSI1_PHY_PLL_OUT_DSICLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_DP0_PHY_PLL_LINK_CLK,
+	P_DP0_PHY_PLL_VCO_DIV_CLK,
+	P_DP1_PHY_PLL_LINK_CLK,
+	P_DP1_PHY_PLL_VCO_DIV_CLK,
+	P_DSI0_PHY_PLL_OUT_BYTECLK,
+	P_DSI0_PHY_PLL_OUT_DSICLK,
+	P_DSI1_PHY_PLL_OUT_BYTECLK,
+	P_DSI1_PHY_PLL_OUT_DSICLK,
+	P_MDSS_0_DISP_CC_PLL0_OUT_MAIN,
+	P_MDSS_0_DISP_CC_PLL1_OUT_EVEN,
+	P_MDSS_0_DISP_CC_PLL1_OUT_MAIN,
+	P_SLEEP_CLK,
+};
+
+static const struct pll_vco lucid_evo_vco[] = {
+	{ 249600000, 2020000000, 0 },
+};
+
+static const struct alpha_pll_config mdss_0_disp_cc_pll0_config = {
+	.l = 0x3a,
+	.alpha = 0x9800,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x32aa299c,
+	.user_ctl_val = 0x00000000,
+	.user_ctl_hi_val = 0x00400805,
+};
+
+static struct clk_alpha_pll mdss_0_disp_cc_pll0 = {
+	.offset = 0x0,
+	.vco_table = lucid_evo_vco,
+	.num_vco = ARRAY_SIZE(lucid_evo_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct alpha_pll_config mdss_0_disp_cc_pll1_config = {
+	.l = 0x1f,
+	.alpha = 0x4000,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x32aa299c,
+	.user_ctl_val = 0x00000000,
+	.user_ctl_hi_val = 0x00400805,
+};
+
+static struct clk_alpha_pll mdss_0_disp_cc_pll1 = {
+	.offset = 0x1000,
+	.vco_table = lucid_evo_vco,
+	.num_vco = ARRAY_SIZE(lucid_evo_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_pll1",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct parent_map disp_cc_0_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DP0_PHY_PLL_LINK_CLK, 1 },
+	{ P_DP0_PHY_PLL_VCO_DIV_CLK, 2 },
+	{ P_DP1_PHY_PLL_VCO_DIV_CLK, 4 },
+};
+
+static const struct clk_parent_data disp_cc_0_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DP0_PHY_PLL_LINK_CLK },
+	{ .index = DT_DP0_PHY_PLL_VCO_DIV_CLK },
+	{ .index = DT_DP1_PHY_PLL_VCO_DIV_CLK },
+};
+
+static const struct parent_map disp_cc_0_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
+	{ P_DSI1_PHY_PLL_OUT_DSICLK, 3 },
+	{ P_DSI1_PHY_PLL_OUT_BYTECLK, 4 },
+};
+
+static const struct clk_parent_data disp_cc_0_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
+	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
+	{ .index = DT_DSI1_PHY_PLL_OUT_DSICLK },
+	{ .index = DT_DSI1_PHY_PLL_OUT_BYTECLK },
+};
+
+static const struct parent_map disp_cc_0_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data disp_cc_0_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct clk_parent_data disp_cc_0_parent_data_2_ao[] = {
+	{ .index = DT_BI_TCXO_AO },
+};
+
+static const struct parent_map disp_cc_0_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DP0_PHY_PLL_LINK_CLK, 1 },
+	{ P_DP1_PHY_PLL_LINK_CLK, 2 },
+};
+
+static const struct clk_parent_data disp_cc_0_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DP0_PHY_PLL_LINK_CLK },
+	{ .index = DT_DP1_PHY_PLL_LINK_CLK },
+};
+
+static const struct parent_map disp_cc_0_parent_map_4[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
+	{ P_DSI1_PHY_PLL_OUT_BYTECLK, 4 },
+};
+
+static const struct clk_parent_data disp_cc_0_parent_data_4[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
+	{ .index = DT_DSI1_PHY_PLL_OUT_BYTECLK },
+};
+
+static const struct parent_map disp_cc_0_parent_map_5[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_MDSS_0_DISP_CC_PLL1_OUT_MAIN, 4 },
+	{ P_MDSS_0_DISP_CC_PLL1_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data disp_cc_0_parent_data_5[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &mdss_0_disp_cc_pll1.clkr.hw },
+	{ .hw = &mdss_0_disp_cc_pll1.clkr.hw },
+};
+
+static const struct parent_map disp_cc_0_parent_map_6[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_MDSS_0_DISP_CC_PLL0_OUT_MAIN, 1 },
+	{ P_MDSS_0_DISP_CC_PLL1_OUT_MAIN, 4 },
+	{ P_MDSS_0_DISP_CC_PLL1_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data disp_cc_0_parent_data_6[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &mdss_0_disp_cc_pll0.clkr.hw },
+	{ .hw = &mdss_0_disp_cc_pll1.clkr.hw },
+	{ .hw = &mdss_0_disp_cc_pll1.clkr.hw },
+};
+
+static const struct parent_map disp_cc_0_parent_map_7[] = {
+	{ P_SLEEP_CLK, 0 },
+};
+
+static const struct clk_parent_data disp_cc_0_parent_data_7[] = {
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct freq_tbl ftbl_mdss_0_disp_cc_mdss_ahb_clk_src[] = {
+	F(37500000, P_MDSS_0_DISP_CC_PLL1_OUT_MAIN, 16, 0, 0),
+	F(75000000, P_MDSS_0_DISP_CC_PLL1_OUT_MAIN, 8, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_ahb_clk_src = {
+	.cmd_rcgr = 0x824c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_5,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_ahb_clk_src",
+		.parent_data = disp_cc_0_parent_data_5,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_5),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_mdss_0_disp_cc_mdss_byte0_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_byte0_clk_src = {
+	.cmd_rcgr = 0x80ec,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_1,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_byte0_clk_src",
+		.parent_data = disp_cc_0_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_byte1_clk_src = {
+	.cmd_rcgr = 0x8108,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_1,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_byte1_clk_src",
+		.parent_data = disp_cc_0_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx0_aux_clk_src = {
+	.cmd_rcgr = 0x81b8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_2,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_dptx0_aux_clk_src",
+		.parent_data = disp_cc_0_parent_data_2,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx0_crypto_clk_src = {
+	.cmd_rcgr = 0x8170,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_3,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_dptx0_crypto_clk_src",
+		.parent_data = disp_cc_0_parent_data_3,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx0_link_clk_src = {
+	.cmd_rcgr = 0x8154,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_3,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_dptx0_link_clk_src",
+		.parent_data = disp_cc_0_parent_data_3,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx0_pixel0_clk_src = {
+	.cmd_rcgr = 0x8188,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_0,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_dptx0_pixel0_clk_src",
+		.parent_data = disp_cc_0_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx0_pixel1_clk_src = {
+	.cmd_rcgr = 0x81a0,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_0,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_dptx0_pixel1_clk_src",
+		.parent_data = disp_cc_0_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx0_pixel2_clk_src = {
+	.cmd_rcgr = 0x826c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_0,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_dptx0_pixel2_clk_src",
+		.parent_data = disp_cc_0_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx0_pixel3_clk_src = {
+	.cmd_rcgr = 0x8284,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_0,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_dptx0_pixel3_clk_src",
+		.parent_data = disp_cc_0_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx1_aux_clk_src = {
+	.cmd_rcgr = 0x8234,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_2,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_dptx1_aux_clk_src",
+		.parent_data = disp_cc_0_parent_data_2,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx1_crypto_clk_src = {
+	.cmd_rcgr = 0x821c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_3,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_dptx1_crypto_clk_src",
+		.parent_data = disp_cc_0_parent_data_3,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx1_link_clk_src = {
+	.cmd_rcgr = 0x8200,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_3,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_dptx1_link_clk_src",
+		.parent_data = disp_cc_0_parent_data_3,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx1_pixel0_clk_src = {
+	.cmd_rcgr = 0x81d0,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_0,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_dptx1_pixel0_clk_src",
+		.parent_data = disp_cc_0_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_dptx1_pixel1_clk_src = {
+	.cmd_rcgr = 0x81e8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_0,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_dptx1_pixel1_clk_src",
+		.parent_data = disp_cc_0_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_esc0_clk_src = {
+	.cmd_rcgr = 0x8124,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_4,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_esc0_clk_src",
+		.parent_data = disp_cc_0_parent_data_4,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_esc1_clk_src = {
+	.cmd_rcgr = 0x813c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_4,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_esc1_clk_src",
+		.parent_data = disp_cc_0_parent_data_4,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_mdss_0_disp_cc_mdss_mdp_clk_src[] = {
+	F(375000000, P_MDSS_0_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(500000000, P_MDSS_0_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(575000000, P_MDSS_0_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(650000000, P_MDSS_0_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_mdp_clk_src = {
+	.cmd_rcgr = 0x80bc,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_6,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_mdp_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_mdp_clk_src",
+		.parent_data = disp_cc_0_parent_data_6,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_6),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_pclk0_clk_src = {
+	.cmd_rcgr = 0x808c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_1,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_pclk0_clk_src",
+		.parent_data = disp_cc_0_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_pixel_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_pclk1_clk_src = {
+	.cmd_rcgr = 0x80a4,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_1,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_pclk1_clk_src",
+		.parent_data = disp_cc_0_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_pixel_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_mdss_vsync_clk_src = {
+	.cmd_rcgr = 0x80d4,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_2,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_vsync_clk_src",
+		.parent_data = disp_cc_0_parent_data_2,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_mdss_0_disp_cc_sleep_clk_src[] = {
+	F(32000, P_SLEEP_CLK, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_sleep_clk_src = {
+	.cmd_rcgr = 0xc058,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_7,
+	.freq_tbl = ftbl_mdss_0_disp_cc_sleep_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_sleep_clk_src",
+		.parent_data = disp_cc_0_parent_data_7,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_7),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_0_disp_cc_xo_clk_src = {
+	.cmd_rcgr = 0xc03c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_0_parent_map_2,
+	.freq_tbl = ftbl_mdss_0_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_xo_clk_src",
+		.parent_data = disp_cc_0_parent_data_2_ao,
+		.num_parents = ARRAY_SIZE(disp_cc_0_parent_data_2_ao),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_regmap_div mdss_0_disp_cc_mdss_byte0_div_clk_src = {
+	.reg = 0x8104,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_byte0_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&mdss_0_disp_cc_mdss_byte0_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ops,
+	},
+};
+
+static struct clk_regmap_div mdss_0_disp_cc_mdss_byte1_div_clk_src = {
+	.reg = 0x8120,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_byte1_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&mdss_0_disp_cc_mdss_byte1_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ops,
+	},
+};
+
+static struct clk_regmap_div mdss_0_disp_cc_mdss_dptx0_link_div_clk_src = {
+	.reg = 0x816c,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_dptx0_link_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&mdss_0_disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div mdss_0_disp_cc_mdss_dptx1_link_div_clk_src = {
+	.reg = 0x8218,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_0_disp_cc_mdss_dptx1_link_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&mdss_0_disp_cc_mdss_dptx1_link_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_ahb1_clk = {
+	.halt_reg = 0x8088,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8088,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_ahb1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_ahb_clk = {
+	.halt_reg = 0x8084,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8084,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_byte0_clk = {
+	.halt_reg = 0x8034,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8034,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_byte0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_byte0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_byte0_intf_clk = {
+	.halt_reg = 0x8038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_byte0_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_byte0_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_byte1_clk = {
+	.halt_reg = 0x803c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x803c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_byte1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_byte1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_byte1_intf_clk = {
+	.halt_reg = 0x8040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_byte1_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_byte1_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx0_aux_clk = {
+	.halt_reg = 0x805c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x805c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx0_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx0_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx0_crypto_clk = {
+	.halt_reg = 0x8058,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8058,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx0_crypto_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx0_crypto_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx0_link_clk = {
+	.halt_reg = 0x804c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x804c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx0_link_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx0_link_intf_clk = {
+	.halt_reg = 0x8050,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8050,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx0_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx0_pixel0_clk = {
+	.halt_reg = 0x8060,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8060,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx0_pixel0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx0_pixel0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx0_pixel1_clk = {
+	.halt_reg = 0x8064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx0_pixel1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx0_pixel1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx0_pixel2_clk = {
+	.halt_reg = 0x8264,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8264,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx0_pixel2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx0_pixel2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx0_pixel3_clk = {
+	.halt_reg = 0x8268,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8268,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx0_pixel3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx0_pixel3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx0_usb_router_link_intf_clk = {
+	.halt_reg = 0x8054,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx0_usb_router_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx1_aux_clk = {
+	.halt_reg = 0x8080,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8080,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx1_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx1_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx1_crypto_clk = {
+	.halt_reg = 0x807c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x807c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx1_crypto_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx1_crypto_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx1_link_clk = {
+	.halt_reg = 0x8070,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8070,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx1_link_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx1_link_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx1_link_intf_clk = {
+	.halt_reg = 0x8074,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8074,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx1_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx1_pixel0_clk = {
+	.halt_reg = 0x8068,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8068,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx1_pixel0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx1_pixel0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx1_pixel1_clk = {
+	.halt_reg = 0x806c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x806c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx1_pixel1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx1_pixel1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_dptx1_usb_router_link_intf_clk = {
+	.halt_reg = 0x8078,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8078,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_dptx1_usb_router_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_esc0_clk = {
+	.halt_reg = 0x8044,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8044,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_esc0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_esc0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_esc1_clk = {
+	.halt_reg = 0x8048,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8048,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_esc1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_esc1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_mdp1_clk = {
+	.halt_reg = 0x8014,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_mdp1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_mdp_clk = {
+	.halt_reg = 0x800c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x800c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_mdp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_mdp_lut1_clk = {
+	.halt_reg = 0x8024,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x8024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_mdp_lut1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_mdp_lut_clk = {
+	.halt_reg = 0x801c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x801c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_mdp_lut_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_non_gdsc_ahb_clk = {
+	.halt_reg = 0xa004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xa004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_non_gdsc_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_pclk0_clk = {
+	.halt_reg = 0x8004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_pclk0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_pclk0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_pclk1_clk = {
+	.halt_reg = 0x8008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_pclk1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_pclk1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_pll_lock_monitor_clk = {
+	.halt_reg = 0xe000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xe000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_pll_lock_monitor_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_rscc_ahb_clk = {
+	.halt_reg = 0xa00c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa00c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_rscc_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_rscc_vsync_clk = {
+	.halt_reg = 0xa008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_rscc_vsync_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_vsync_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_vsync1_clk = {
+	.halt_reg = 0x8030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_vsync1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_vsync_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_mdss_vsync_clk = {
+	.halt_reg = 0x802c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x802c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_mdss_vsync_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_0_disp_cc_mdss_vsync_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_0_disp_cc_sm_obs_clk = {
+	.halt_reg = 0x11014,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x11014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_0_disp_cc_sm_obs_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc mdss_0_disp_cc_mdss_core_gdsc = {
+	.gdscr = 0x9000,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "mdss_0_disp_cc_mdss_core_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL,
+};
+
+static struct gdsc mdss_0_disp_cc_mdss_core_int2_gdsc = {
+	.gdscr = 0xd000,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "mdss_0_disp_cc_mdss_core_int2_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL,
+};
+
+static struct clk_regmap *disp_cc_0_sa8775p_clocks[] = {
+	[MDSS_DISP_CC_MDSS_AHB1_CLK] = &mdss_0_disp_cc_mdss_ahb1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_AHB_CLK] = &mdss_0_disp_cc_mdss_ahb_clk.clkr,
+	[MDSS_DISP_CC_MDSS_AHB_CLK_SRC] = &mdss_0_disp_cc_mdss_ahb_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE0_CLK] = &mdss_0_disp_cc_mdss_byte0_clk.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE0_CLK_SRC] = &mdss_0_disp_cc_mdss_byte0_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &mdss_0_disp_cc_mdss_byte0_div_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE0_INTF_CLK] = &mdss_0_disp_cc_mdss_byte0_intf_clk.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE1_CLK] = &mdss_0_disp_cc_mdss_byte1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE1_CLK_SRC] = &mdss_0_disp_cc_mdss_byte1_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = &mdss_0_disp_cc_mdss_byte1_div_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE1_INTF_CLK] = &mdss_0_disp_cc_mdss_byte1_intf_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK] = &mdss_0_disp_cc_mdss_dptx0_aux_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx0_aux_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_CRYPTO_CLK] = &mdss_0_disp_cc_mdss_dptx0_crypto_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_CRYPTO_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx0_crypto_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK] = &mdss_0_disp_cc_mdss_dptx0_link_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx0_link_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC] =
+	      &mdss_0_disp_cc_mdss_dptx0_link_div_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_LINK_INTF_CLK] = &mdss_0_disp_cc_mdss_dptx0_link_intf_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK] = &mdss_0_disp_cc_mdss_dptx0_pixel0_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx0_pixel0_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK] = &mdss_0_disp_cc_mdss_dptx0_pixel1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx0_pixel1_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK] = &mdss_0_disp_cc_mdss_dptx0_pixel2_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx0_pixel2_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK] = &mdss_0_disp_cc_mdss_dptx0_pixel3_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx0_pixel3_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK] =
+	      &mdss_0_disp_cc_mdss_dptx0_usb_router_link_intf_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK] = &mdss_0_disp_cc_mdss_dptx1_aux_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx1_aux_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_CRYPTO_CLK] = &mdss_0_disp_cc_mdss_dptx1_crypto_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_CRYPTO_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx1_crypto_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_LINK_CLK] = &mdss_0_disp_cc_mdss_dptx1_link_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_LINK_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx1_link_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC] =
+	      &mdss_0_disp_cc_mdss_dptx1_link_div_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_LINK_INTF_CLK] = &mdss_0_disp_cc_mdss_dptx1_link_intf_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_PIXEL0_CLK] = &mdss_0_disp_cc_mdss_dptx1_pixel0_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx1_pixel0_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_PIXEL1_CLK] = &mdss_0_disp_cc_mdss_dptx1_pixel1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC] = &mdss_0_disp_cc_mdss_dptx1_pixel1_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK] =
+	      &mdss_0_disp_cc_mdss_dptx1_usb_router_link_intf_clk.clkr,
+	[MDSS_DISP_CC_MDSS_ESC0_CLK] = &mdss_0_disp_cc_mdss_esc0_clk.clkr,
+	[MDSS_DISP_CC_MDSS_ESC0_CLK_SRC] = &mdss_0_disp_cc_mdss_esc0_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_ESC1_CLK] = &mdss_0_disp_cc_mdss_esc1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_ESC1_CLK_SRC] = &mdss_0_disp_cc_mdss_esc1_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_MDP1_CLK] = &mdss_0_disp_cc_mdss_mdp1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_MDP_CLK] = &mdss_0_disp_cc_mdss_mdp_clk.clkr,
+	[MDSS_DISP_CC_MDSS_MDP_CLK_SRC] = &mdss_0_disp_cc_mdss_mdp_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_MDP_LUT1_CLK] = &mdss_0_disp_cc_mdss_mdp_lut1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_MDP_LUT_CLK] = &mdss_0_disp_cc_mdss_mdp_lut_clk.clkr,
+	[MDSS_DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &mdss_0_disp_cc_mdss_non_gdsc_ahb_clk.clkr,
+	[MDSS_DISP_CC_MDSS_PCLK0_CLK] = &mdss_0_disp_cc_mdss_pclk0_clk.clkr,
+	[MDSS_DISP_CC_MDSS_PCLK0_CLK_SRC] = &mdss_0_disp_cc_mdss_pclk0_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_PCLK1_CLK] = &mdss_0_disp_cc_mdss_pclk1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_PCLK1_CLK_SRC] = &mdss_0_disp_cc_mdss_pclk1_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_PLL_LOCK_MONITOR_CLK] = &mdss_0_disp_cc_mdss_pll_lock_monitor_clk.clkr,
+	[MDSS_DISP_CC_MDSS_RSCC_AHB_CLK] = &mdss_0_disp_cc_mdss_rscc_ahb_clk.clkr,
+	[MDSS_DISP_CC_MDSS_RSCC_VSYNC_CLK] = &mdss_0_disp_cc_mdss_rscc_vsync_clk.clkr,
+	[MDSS_DISP_CC_MDSS_VSYNC1_CLK] = &mdss_0_disp_cc_mdss_vsync1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_VSYNC_CLK] = &mdss_0_disp_cc_mdss_vsync_clk.clkr,
+	[MDSS_DISP_CC_MDSS_VSYNC_CLK_SRC] = &mdss_0_disp_cc_mdss_vsync_clk_src.clkr,
+	[MDSS_DISP_CC_PLL0] = &mdss_0_disp_cc_pll0.clkr,
+	[MDSS_DISP_CC_PLL1] = &mdss_0_disp_cc_pll1.clkr,
+	[MDSS_DISP_CC_SLEEP_CLK_SRC] = &mdss_0_disp_cc_sleep_clk_src.clkr,
+	[MDSS_DISP_CC_SM_OBS_CLK] = &mdss_0_disp_cc_sm_obs_clk.clkr,
+	[MDSS_DISP_CC_XO_CLK_SRC] = &mdss_0_disp_cc_xo_clk_src.clkr,
+};
+
+static struct gdsc *disp_cc_0_sa8775p_gdscs[] = {
+	[MDSS_DISP_CC_MDSS_CORE_GDSC] = &mdss_0_disp_cc_mdss_core_gdsc,
+	[MDSS_DISP_CC_MDSS_CORE_INT2_GDSC] = &mdss_0_disp_cc_mdss_core_int2_gdsc,
+};
+
+static const struct qcom_reset_map disp_cc_0_sa8775p_resets[] = {
+	[MDSS_DISP_CC_MDSS_CORE_BCR] = { 0x8000 },
+	[MDSS_DISP_CC_MDSS_RSCC_BCR] = { 0xa000 },
+};
+
+static const struct regmap_config disp_cc_0_sa8775p_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x12414,
+	.fast_io = true,
+};
+
+static struct qcom_cc_desc disp_cc_0_sa8775p_desc = {
+	.config = &disp_cc_0_sa8775p_regmap_config,
+	.clks = disp_cc_0_sa8775p_clocks,
+	.num_clks = ARRAY_SIZE(disp_cc_0_sa8775p_clocks),
+	.resets = disp_cc_0_sa8775p_resets,
+	.num_resets = ARRAY_SIZE(disp_cc_0_sa8775p_resets),
+	.gdscs = disp_cc_0_sa8775p_gdscs,
+	.num_gdscs = ARRAY_SIZE(disp_cc_0_sa8775p_gdscs),
+};
+
+static const struct of_device_id disp_cc_0_sa8775p_match_table[] = {
+	{ .compatible = "qcom,sa8775p-dispcc0" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, disp_cc_0_sa8775p_match_table);
+
+static int disp_cc_0_sa8775p_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+	int ret;
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret)
+		return ret;
+
+	regmap = qcom_cc_map(pdev, &disp_cc_0_sa8775p_desc);
+	if (IS_ERR(regmap)) {
+		pm_runtime_put(&pdev->dev);
+		return PTR_ERR(regmap);
+	}
+
+	clk_lucid_evo_pll_configure(&mdss_0_disp_cc_pll0, regmap, &mdss_0_disp_cc_pll0_config);
+	clk_lucid_evo_pll_configure(&mdss_0_disp_cc_pll1, regmap, &mdss_0_disp_cc_pll1_config);
+
+	/*
+	 * Keep clocks always enabled:
+	 *	mdss_0_disp_cc_sleep_clk
+	 *	mdss_0_disp_cc_xo_clk
+	 * Use qcom_clk_set_en()
+	 */
+	regmap_update_bits(regmap, 0xc070, BIT(0), BIT(0));
+	regmap_update_bits(regmap, 0xc054, BIT(0), BIT(0));
+
+	ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_0_sa8775p_desc, regmap);
+
+	pm_runtime_put(&pdev->dev);
+
+	return ret;
+}
+
+static struct platform_driver disp_cc_0_sa8775p_driver = {
+	.probe = disp_cc_0_sa8775p_probe,
+	.driver = {
+		.name = "dispcc0-sa8775p",
+		.of_match_table = disp_cc_0_sa8775p_match_table,
+	},
+};
+
+module_platform_driver(disp_cc_0_sa8775p_driver);
+
+MODULE_DESCRIPTION("QTI DISPCC0 SA8775P Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/dispcc1-sa8775p.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/dispcc1-sa8775p.c
@@ -0,0 +1,1495 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,sa8775p-dispcc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_IFACE,
+	DT_BI_TCXO,
+	DT_BI_TCXO_AO,
+	DT_SLEEP_CLK,
+	DT_DP0_PHY_PLL_LINK_CLK,
+	DT_DP0_PHY_PLL_VCO_DIV_CLK,
+	DT_DP1_PHY_PLL_LINK_CLK,
+	DT_DP1_PHY_PLL_VCO_DIV_CLK,
+	DT_DSI0_PHY_PLL_OUT_BYTECLK,
+	DT_DSI0_PHY_PLL_OUT_DSICLK,
+	DT_DSI1_PHY_PLL_OUT_BYTECLK,
+	DT_DSI1_PHY_PLL_OUT_DSICLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_DP0_PHY_PLL_LINK_CLK,
+	P_DP0_PHY_PLL_VCO_DIV_CLK,
+	P_DP1_PHY_PLL_LINK_CLK,
+	P_DP1_PHY_PLL_VCO_DIV_CLK,
+	P_DSI0_PHY_PLL_OUT_BYTECLK,
+	P_DSI0_PHY_PLL_OUT_DSICLK,
+	P_DSI1_PHY_PLL_OUT_BYTECLK,
+	P_DSI1_PHY_PLL_OUT_DSICLK,
+	P_MDSS_1_DISP_CC_PLL0_OUT_MAIN,
+	P_MDSS_1_DISP_CC_PLL1_OUT_EVEN,
+	P_MDSS_1_DISP_CC_PLL1_OUT_MAIN,
+	P_SLEEP_CLK,
+};
+
+static const struct pll_vco lucid_evo_vco[] = {
+	{ 249600000, 2020000000, 0 },
+};
+
+static const struct alpha_pll_config mdss_1_disp_cc_pll0_config = {
+	.l = 0x3a,
+	.alpha = 0x9800,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x32aa299c,
+	.user_ctl_val = 0x00000000,
+	.user_ctl_hi_val = 0x00400805,
+};
+
+static struct clk_alpha_pll mdss_1_disp_cc_pll0 = {
+	.offset = 0x0,
+	.vco_table = lucid_evo_vco,
+	.num_vco = ARRAY_SIZE(lucid_evo_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct alpha_pll_config mdss_1_disp_cc_pll1_config = {
+	.l = 0x1f,
+	.alpha = 0x4000,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x32aa299c,
+	.user_ctl_val = 0x00000000,
+	.user_ctl_hi_val = 0x00400805,
+};
+
+static struct clk_alpha_pll mdss_1_disp_cc_pll1 = {
+	.offset = 0x1000,
+	.vco_table = lucid_evo_vco,
+	.num_vco = ARRAY_SIZE(lucid_evo_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_pll1",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct parent_map disp_cc_1_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DP0_PHY_PLL_LINK_CLK, 1 },
+	{ P_DP0_PHY_PLL_VCO_DIV_CLK, 2 },
+	{ P_DP1_PHY_PLL_VCO_DIV_CLK, 4 },
+};
+
+static const struct clk_parent_data disp_cc_1_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DP0_PHY_PLL_LINK_CLK },
+	{ .index = DT_DP0_PHY_PLL_VCO_DIV_CLK },
+	{ .index = DT_DP1_PHY_PLL_VCO_DIV_CLK },
+};
+
+static const struct parent_map disp_cc_1_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
+	{ P_DSI1_PHY_PLL_OUT_DSICLK, 3 },
+	{ P_DSI1_PHY_PLL_OUT_BYTECLK, 4 },
+};
+
+static const struct clk_parent_data disp_cc_1_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
+	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
+	{ .index = DT_DSI1_PHY_PLL_OUT_DSICLK },
+	{ .index = DT_DSI1_PHY_PLL_OUT_BYTECLK },
+};
+
+static const struct parent_map disp_cc_1_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data disp_cc_1_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct clk_parent_data disp_cc_1_parent_data_2_ao[] = {
+	{ .index = DT_BI_TCXO_AO },
+};
+
+static const struct parent_map disp_cc_1_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DP0_PHY_PLL_LINK_CLK, 1 },
+	{ P_DP1_PHY_PLL_LINK_CLK, 2 },
+};
+
+static const struct clk_parent_data disp_cc_1_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DP0_PHY_PLL_LINK_CLK },
+	{ .index = DT_DP1_PHY_PLL_LINK_CLK },
+};
+
+static const struct parent_map disp_cc_1_parent_map_4[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DSI0_PHY_PLL_OUT_BYTECLK, 2 },
+	{ P_DSI1_PHY_PLL_OUT_BYTECLK, 4 },
+};
+
+static const struct clk_parent_data disp_cc_1_parent_data_4[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DSI0_PHY_PLL_OUT_BYTECLK },
+	{ .index = DT_DSI1_PHY_PLL_OUT_BYTECLK },
+};
+
+static const struct parent_map disp_cc_1_parent_map_5[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_MDSS_1_DISP_CC_PLL1_OUT_MAIN, 4 },
+	{ P_MDSS_1_DISP_CC_PLL1_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data disp_cc_1_parent_data_5[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &mdss_1_disp_cc_pll1.clkr.hw },
+	{ .hw = &mdss_1_disp_cc_pll1.clkr.hw },
+};
+
+static const struct parent_map disp_cc_1_parent_map_6[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_MDSS_1_DISP_CC_PLL0_OUT_MAIN, 1 },
+	{ P_MDSS_1_DISP_CC_PLL1_OUT_MAIN, 4 },
+	{ P_MDSS_1_DISP_CC_PLL1_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data disp_cc_1_parent_data_6[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &mdss_1_disp_cc_pll0.clkr.hw },
+	{ .hw = &mdss_1_disp_cc_pll1.clkr.hw },
+	{ .hw = &mdss_1_disp_cc_pll1.clkr.hw },
+};
+
+static const struct parent_map disp_cc_1_parent_map_7[] = {
+	{ P_SLEEP_CLK, 0 },
+};
+
+static const struct clk_parent_data disp_cc_1_parent_data_7_ao[] = {
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct freq_tbl ftbl_mdss_1_disp_cc_mdss_ahb_clk_src[] = {
+	F(37500000, P_MDSS_1_DISP_CC_PLL1_OUT_MAIN, 16, 0, 0),
+	F(75000000, P_MDSS_1_DISP_CC_PLL1_OUT_MAIN, 8, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_ahb_clk_src = {
+	.cmd_rcgr = 0x824c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_5,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_ahb_clk_src",
+		.parent_data = disp_cc_1_parent_data_5,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_5),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_mdss_1_disp_cc_mdss_byte0_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_byte0_clk_src = {
+	.cmd_rcgr = 0x80ec,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_1,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_byte0_clk_src",
+		.parent_data = disp_cc_1_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_byte1_clk_src = {
+	.cmd_rcgr = 0x8108,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_1,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_byte1_clk_src",
+		.parent_data = disp_cc_1_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx0_aux_clk_src = {
+	.cmd_rcgr = 0x81b8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_2,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_dptx0_aux_clk_src",
+		.parent_data = disp_cc_1_parent_data_2,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx0_crypto_clk_src = {
+	.cmd_rcgr = 0x8170,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_3,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_dptx0_crypto_clk_src",
+		.parent_data = disp_cc_1_parent_data_3,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx0_link_clk_src = {
+	.cmd_rcgr = 0x8154,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_3,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_dptx0_link_clk_src",
+		.parent_data = disp_cc_1_parent_data_3,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx0_pixel0_clk_src = {
+	.cmd_rcgr = 0x8188,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_0,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_dptx0_pixel0_clk_src",
+		.parent_data = disp_cc_1_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx0_pixel1_clk_src = {
+	.cmd_rcgr = 0x81a0,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_0,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_dptx0_pixel1_clk_src",
+		.parent_data = disp_cc_1_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx0_pixel2_clk_src = {
+	.cmd_rcgr = 0x826c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_0,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_dptx0_pixel2_clk_src",
+		.parent_data = disp_cc_1_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx0_pixel3_clk_src = {
+	.cmd_rcgr = 0x8284,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_0,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_dptx0_pixel3_clk_src",
+		.parent_data = disp_cc_1_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx1_aux_clk_src = {
+	.cmd_rcgr = 0x8234,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_2,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_dptx1_aux_clk_src",
+		.parent_data = disp_cc_1_parent_data_2,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx1_crypto_clk_src = {
+	.cmd_rcgr = 0x821c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_3,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_dptx1_crypto_clk_src",
+		.parent_data = disp_cc_1_parent_data_3,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx1_link_clk_src = {
+	.cmd_rcgr = 0x8200,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_3,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_dptx1_link_clk_src",
+		.parent_data = disp_cc_1_parent_data_3,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx1_pixel0_clk_src = {
+	.cmd_rcgr = 0x81d0,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_0,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_dptx1_pixel0_clk_src",
+		.parent_data = disp_cc_1_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_dptx1_pixel1_clk_src = {
+	.cmd_rcgr = 0x81e8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_0,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_dptx1_pixel1_clk_src",
+		.parent_data = disp_cc_1_parent_data_0,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_dp_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_esc0_clk_src = {
+	.cmd_rcgr = 0x8124,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_4,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_esc0_clk_src",
+		.parent_data = disp_cc_1_parent_data_4,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_esc1_clk_src = {
+	.cmd_rcgr = 0x813c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_4,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_esc1_clk_src",
+		.parent_data = disp_cc_1_parent_data_4,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_mdss_1_disp_cc_mdss_mdp_clk_src[] = {
+	F(375000000, P_MDSS_1_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(500000000, P_MDSS_1_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(575000000, P_MDSS_1_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(650000000, P_MDSS_1_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_mdp_clk_src = {
+	.cmd_rcgr = 0x80bc,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_6,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_mdp_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_mdp_clk_src",
+		.parent_data = disp_cc_1_parent_data_6,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_6),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_pclk0_clk_src = {
+	.cmd_rcgr = 0x808c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_1,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_pclk0_clk_src",
+		.parent_data = disp_cc_1_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_pixel_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_pclk1_clk_src = {
+	.cmd_rcgr = 0x80a4,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_1,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_pclk1_clk_src",
+		.parent_data = disp_cc_1_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_pixel_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_mdss_vsync_clk_src = {
+	.cmd_rcgr = 0x80d4,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_2,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_vsync_clk_src",
+		.parent_data = disp_cc_1_parent_data_2,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_mdss_1_disp_cc_sleep_clk_src[] = {
+	F(32000, P_SLEEP_CLK, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_sleep_clk_src = {
+	.cmd_rcgr = 0xc058,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_7,
+	.freq_tbl = ftbl_mdss_1_disp_cc_sleep_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_sleep_clk_src",
+		.parent_data = disp_cc_1_parent_data_7_ao,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_7_ao),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 mdss_1_disp_cc_xo_clk_src = {
+	.cmd_rcgr = 0xc03c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_1_parent_map_2,
+	.freq_tbl = ftbl_mdss_1_disp_cc_mdss_byte0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_xo_clk_src",
+		.parent_data = disp_cc_1_parent_data_2_ao,
+		.num_parents = ARRAY_SIZE(disp_cc_1_parent_data_2_ao),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_regmap_div mdss_1_disp_cc_mdss_byte0_div_clk_src = {
+	.reg = 0x8104,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_byte0_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&mdss_1_disp_cc_mdss_byte0_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ops,
+	},
+};
+
+static struct clk_regmap_div mdss_1_disp_cc_mdss_byte1_div_clk_src = {
+	.reg = 0x8120,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_byte1_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&mdss_1_disp_cc_mdss_byte1_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ops,
+	},
+};
+
+static struct clk_regmap_div mdss_1_disp_cc_mdss_dptx0_link_div_clk_src = {
+	.reg = 0x816c,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_dptx0_link_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&mdss_1_disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div mdss_1_disp_cc_mdss_dptx1_link_div_clk_src = {
+	.reg = 0x8218,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "mdss_1_disp_cc_mdss_dptx1_link_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&mdss_1_disp_cc_mdss_dptx1_link_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_ahb1_clk = {
+	.halt_reg = 0x8088,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8088,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_ahb1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_ahb_clk = {
+	.halt_reg = 0x8084,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8084,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_byte0_clk = {
+	.halt_reg = 0x8034,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8034,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_byte0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_byte0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_byte0_intf_clk = {
+	.halt_reg = 0x8038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_byte0_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_byte0_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_byte1_clk = {
+	.halt_reg = 0x803c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x803c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_byte1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_byte1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_byte1_intf_clk = {
+	.halt_reg = 0x8040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_byte1_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_byte1_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx0_aux_clk = {
+	.halt_reg = 0x805c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x805c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx0_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx0_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx0_crypto_clk = {
+	.halt_reg = 0x8058,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8058,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx0_crypto_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx0_crypto_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx0_link_clk = {
+	.halt_reg = 0x804c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x804c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx0_link_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx0_link_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx0_link_intf_clk = {
+	.halt_reg = 0x8050,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8050,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx0_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx0_pixel0_clk = {
+	.halt_reg = 0x8060,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8060,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx0_pixel0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx0_pixel0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx0_pixel1_clk = {
+	.halt_reg = 0x8064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx0_pixel1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx0_pixel1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx0_pixel2_clk = {
+	.halt_reg = 0x8264,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8264,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx0_pixel2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx0_pixel2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx0_pixel3_clk = {
+	.halt_reg = 0x8268,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8268,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx0_pixel3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx0_pixel3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx0_usb_router_link_intf_clk = {
+	.halt_reg = 0x8054,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx0_usb_router_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx1_aux_clk = {
+	.halt_reg = 0x8080,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8080,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx1_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx1_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx1_crypto_clk = {
+	.halt_reg = 0x807c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x807c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx1_crypto_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx1_crypto_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx1_link_clk = {
+	.halt_reg = 0x8070,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8070,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx1_link_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx1_link_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx1_link_intf_clk = {
+	.halt_reg = 0x8074,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8074,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx1_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx1_pixel0_clk = {
+	.halt_reg = 0x8068,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8068,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx1_pixel0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx1_pixel0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx1_pixel1_clk = {
+	.halt_reg = 0x806c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x806c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx1_pixel1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx1_pixel1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_dptx1_usb_router_link_intf_clk = {
+	.halt_reg = 0x8078,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8078,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_dptx1_usb_router_link_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_esc0_clk = {
+	.halt_reg = 0x8044,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8044,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_esc0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_esc0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_esc1_clk = {
+	.halt_reg = 0x8048,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8048,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_esc1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_esc1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_mdp1_clk = {
+	.halt_reg = 0x8014,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_mdp1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_mdp_clk = {
+	.halt_reg = 0x800c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x800c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_mdp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_mdp_lut1_clk = {
+	.halt_reg = 0x8024,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x8024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_mdp_lut1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_mdp_lut_clk = {
+	.halt_reg = 0x801c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x801c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_mdp_lut_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_mdp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_non_gdsc_ahb_clk = {
+	.halt_reg = 0xa004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xa004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_non_gdsc_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_pclk0_clk = {
+	.halt_reg = 0x8004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_pclk0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_pclk0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_pclk1_clk = {
+	.halt_reg = 0x8008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_pclk1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_pclk1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_pll_lock_monitor_clk = {
+	.halt_reg = 0xe000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xe000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_pll_lock_monitor_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_rscc_ahb_clk = {
+	.halt_reg = 0xa00c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa00c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_rscc_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_rscc_vsync_clk = {
+	.halt_reg = 0xa008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_rscc_vsync_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_vsync_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_vsync1_clk = {
+	.halt_reg = 0x8030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_vsync1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_vsync_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_mdss_vsync_clk = {
+	.halt_reg = 0x802c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x802c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_mdss_vsync_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&mdss_1_disp_cc_mdss_vsync_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch mdss_1_disp_cc_sm_obs_clk = {
+	.halt_reg = 0x11014,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x11014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "mdss_1_disp_cc_sm_obs_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc mdss_1_disp_cc_mdss_core_gdsc = {
+	.gdscr = 0x9000,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "mdss_1_disp_cc_mdss_core_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL,
+};
+
+static struct gdsc mdss_1_disp_cc_mdss_core_int2_gdsc = {
+	.gdscr = 0xd000,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "mdss_1_disp_cc_mdss_core_int2_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL,
+};
+
+static struct clk_regmap *disp_cc_1_sa8775p_clocks[] = {
+	[MDSS_DISP_CC_MDSS_AHB1_CLK] = &mdss_1_disp_cc_mdss_ahb1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_AHB_CLK] = &mdss_1_disp_cc_mdss_ahb_clk.clkr,
+	[MDSS_DISP_CC_MDSS_AHB_CLK_SRC] = &mdss_1_disp_cc_mdss_ahb_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE0_CLK] = &mdss_1_disp_cc_mdss_byte0_clk.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE0_CLK_SRC] = &mdss_1_disp_cc_mdss_byte0_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &mdss_1_disp_cc_mdss_byte0_div_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE0_INTF_CLK] = &mdss_1_disp_cc_mdss_byte0_intf_clk.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE1_CLK] = &mdss_1_disp_cc_mdss_byte1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE1_CLK_SRC] = &mdss_1_disp_cc_mdss_byte1_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = &mdss_1_disp_cc_mdss_byte1_div_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_BYTE1_INTF_CLK] = &mdss_1_disp_cc_mdss_byte1_intf_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK] = &mdss_1_disp_cc_mdss_dptx0_aux_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_AUX_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx0_aux_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_CRYPTO_CLK] = &mdss_1_disp_cc_mdss_dptx0_crypto_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_CRYPTO_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx0_crypto_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK] = &mdss_1_disp_cc_mdss_dptx0_link_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_LINK_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx0_link_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC] =
+	      &mdss_1_disp_cc_mdss_dptx0_link_div_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_LINK_INTF_CLK] = &mdss_1_disp_cc_mdss_dptx0_link_intf_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK] = &mdss_1_disp_cc_mdss_dptx0_pixel0_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx0_pixel0_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK] = &mdss_1_disp_cc_mdss_dptx0_pixel1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx0_pixel1_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK] = &mdss_1_disp_cc_mdss_dptx0_pixel2_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL2_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx0_pixel2_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK] = &mdss_1_disp_cc_mdss_dptx0_pixel3_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_PIXEL3_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx0_pixel3_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK] =
+	      &mdss_1_disp_cc_mdss_dptx0_usb_router_link_intf_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK] = &mdss_1_disp_cc_mdss_dptx1_aux_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_AUX_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx1_aux_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_CRYPTO_CLK] = &mdss_1_disp_cc_mdss_dptx1_crypto_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_CRYPTO_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx1_crypto_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_LINK_CLK] = &mdss_1_disp_cc_mdss_dptx1_link_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_LINK_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx1_link_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC] =
+	      &mdss_1_disp_cc_mdss_dptx1_link_div_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_LINK_INTF_CLK] = &mdss_1_disp_cc_mdss_dptx1_link_intf_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_PIXEL0_CLK] = &mdss_1_disp_cc_mdss_dptx1_pixel0_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx1_pixel0_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_PIXEL1_CLK] = &mdss_1_disp_cc_mdss_dptx1_pixel1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC] = &mdss_1_disp_cc_mdss_dptx1_pixel1_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK] =
+	      &mdss_1_disp_cc_mdss_dptx1_usb_router_link_intf_clk.clkr,
+	[MDSS_DISP_CC_MDSS_ESC0_CLK] = &mdss_1_disp_cc_mdss_esc0_clk.clkr,
+	[MDSS_DISP_CC_MDSS_ESC0_CLK_SRC] = &mdss_1_disp_cc_mdss_esc0_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_ESC1_CLK] = &mdss_1_disp_cc_mdss_esc1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_ESC1_CLK_SRC] = &mdss_1_disp_cc_mdss_esc1_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_MDP1_CLK] = &mdss_1_disp_cc_mdss_mdp1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_MDP_CLK] = &mdss_1_disp_cc_mdss_mdp_clk.clkr,
+	[MDSS_DISP_CC_MDSS_MDP_CLK_SRC] = &mdss_1_disp_cc_mdss_mdp_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_MDP_LUT1_CLK] = &mdss_1_disp_cc_mdss_mdp_lut1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_MDP_LUT_CLK] = &mdss_1_disp_cc_mdss_mdp_lut_clk.clkr,
+	[MDSS_DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &mdss_1_disp_cc_mdss_non_gdsc_ahb_clk.clkr,
+	[MDSS_DISP_CC_MDSS_PCLK0_CLK] = &mdss_1_disp_cc_mdss_pclk0_clk.clkr,
+	[MDSS_DISP_CC_MDSS_PCLK0_CLK_SRC] = &mdss_1_disp_cc_mdss_pclk0_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_PCLK1_CLK] = &mdss_1_disp_cc_mdss_pclk1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_PCLK1_CLK_SRC] = &mdss_1_disp_cc_mdss_pclk1_clk_src.clkr,
+	[MDSS_DISP_CC_MDSS_PLL_LOCK_MONITOR_CLK] = &mdss_1_disp_cc_mdss_pll_lock_monitor_clk.clkr,
+	[MDSS_DISP_CC_MDSS_RSCC_AHB_CLK] = &mdss_1_disp_cc_mdss_rscc_ahb_clk.clkr,
+	[MDSS_DISP_CC_MDSS_RSCC_VSYNC_CLK] = &mdss_1_disp_cc_mdss_rscc_vsync_clk.clkr,
+	[MDSS_DISP_CC_MDSS_VSYNC1_CLK] = &mdss_1_disp_cc_mdss_vsync1_clk.clkr,
+	[MDSS_DISP_CC_MDSS_VSYNC_CLK] = &mdss_1_disp_cc_mdss_vsync_clk.clkr,
+	[MDSS_DISP_CC_MDSS_VSYNC_CLK_SRC] = &mdss_1_disp_cc_mdss_vsync_clk_src.clkr,
+	[MDSS_DISP_CC_PLL0] = &mdss_1_disp_cc_pll0.clkr,
+	[MDSS_DISP_CC_PLL1] = &mdss_1_disp_cc_pll1.clkr,
+	[MDSS_DISP_CC_SLEEP_CLK_SRC] = &mdss_1_disp_cc_sleep_clk_src.clkr,
+	[MDSS_DISP_CC_SM_OBS_CLK] = &mdss_1_disp_cc_sm_obs_clk.clkr,
+	[MDSS_DISP_CC_XO_CLK_SRC] = &mdss_1_disp_cc_xo_clk_src.clkr,
+};
+
+static struct gdsc *disp_cc_1_sa8775p_gdscs[] = {
+	[MDSS_DISP_CC_MDSS_CORE_GDSC] = &mdss_1_disp_cc_mdss_core_gdsc,
+	[MDSS_DISP_CC_MDSS_CORE_INT2_GDSC] = &mdss_1_disp_cc_mdss_core_int2_gdsc,
+};
+
+static const struct qcom_reset_map disp_cc_1_sa8775p_resets[] = {
+	[MDSS_DISP_CC_MDSS_CORE_BCR] = { 0x8000 },
+	[MDSS_DISP_CC_MDSS_RSCC_BCR] = { 0xa000 },
+};
+
+static const struct regmap_config disp_cc_1_sa8775p_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x12414,
+	.fast_io = true,
+};
+
+static struct qcom_cc_desc disp_cc_1_sa8775p_desc = {
+	.config = &disp_cc_1_sa8775p_regmap_config,
+	.clks = disp_cc_1_sa8775p_clocks,
+	.num_clks = ARRAY_SIZE(disp_cc_1_sa8775p_clocks),
+	.resets = disp_cc_1_sa8775p_resets,
+	.num_resets = ARRAY_SIZE(disp_cc_1_sa8775p_resets),
+	.gdscs = disp_cc_1_sa8775p_gdscs,
+	.num_gdscs = ARRAY_SIZE(disp_cc_1_sa8775p_gdscs),
+};
+
+static const struct of_device_id disp_cc_1_sa8775p_match_table[] = {
+	{ .compatible = "qcom,sa8775p-dispcc1" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, disp_cc_1_sa8775p_match_table);
+
+static int disp_cc_1_sa8775p_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+	int ret;
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret)
+		return ret;
+
+	regmap = qcom_cc_map(pdev, &disp_cc_1_sa8775p_desc);
+	if (IS_ERR(regmap)) {
+		pm_runtime_put(&pdev->dev);
+		return PTR_ERR(regmap);
+	}
+
+	clk_lucid_evo_pll_configure(&mdss_1_disp_cc_pll0, regmap, &mdss_1_disp_cc_pll0_config);
+	clk_lucid_evo_pll_configure(&mdss_1_disp_cc_pll1, regmap, &mdss_1_disp_cc_pll1_config);
+
+	/*
+	 * Keep clocks always enabled:
+	 *	mdss_1_disp_cc_sleep_clk
+	 *	mdss_1_disp_cc_xo_clk
+	 */
+	regmap_update_bits(regmap, 0xc070, BIT(0), BIT(0));
+	regmap_update_bits(regmap, 0xc054, BIT(0), BIT(0));
+
+	/*
+	 * Reparent below clocks to XO
+	 *	mdss_1_disp_cc_mdss_dptx0_crypto_clk_src
+	 *	mdss_1_disp_cc_mdss_dptx1_crypto_clk_src
+	 */
+	regmap_write(regmap, 0x8174, 0x0);
+	regmap_update_bits(regmap, 0x8170, BIT(0), BIT(0));
+	regmap_write(regmap, 0x8220, 0x0);
+	regmap_update_bits(regmap, 0x821c, BIT(0), BIT(0));
+
+	ret = qcom_cc_really_probe(&pdev->dev, &disp_cc_1_sa8775p_desc, regmap);
+
+	pm_runtime_put(&pdev->dev);
+
+	return ret;
+}
+
+static struct platform_driver disp_cc_1_sa8775p_driver = {
+	.probe = disp_cc_1_sa8775p_probe,
+	.driver = {
+		.name = "dispcc1-sa8775p",
+		.of_match_table = disp_cc_1_sa8775p_match_table,
+	},
+};
+
+module_platform_driver(disp_cc_1_sa8775p_driver);
+
+MODULE_DESCRIPTION("QTI DISPCC1 SA8775P Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/ecpricc-qdu1000.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/ecpricc-qdu1000.c
@@ -2439,7 +2439,7 @@
 	clk_lucid_evo_pll_configure(&ecpri_cc_pll0, regmap, &ecpri_cc_pll0_config);
 	clk_lucid_evo_pll_configure(&ecpri_cc_pll1, regmap, &ecpri_cc_pll1_config);
 
-	return qcom_cc_really_probe(pdev, &ecpri_cc_qdu1000_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &ecpri_cc_qdu1000_desc, regmap);
 }
 
 static struct platform_driver ecpri_cc_qdu1000_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-ipq5018.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-ipq5018.c
@@ -857,6 +857,7 @@
 
 static const struct freq_tbl ftbl_pcie0_aux_clk_src[] = {
 	F(2000000, P_XO, 12, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 pcie0_aux_clk_src = {
@@ -1099,6 +1100,7 @@
 	F(100000000, P_GPLL0, 8, 0, 0),
 	F(200000000, P_GPLL0, 4, 0, 0),
 	F(320000000, P_GPLL0, 2.5, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 qpic_io_macro_clk_src = {
@@ -1194,6 +1196,7 @@
 static const struct freq_tbl ftbl_ubi0_core_clk_src[] = {
 	F(850000000, P_UBI32_PLL, 1, 0, 0),
 	F(1000000000, P_UBI32_PLL, 1, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 ubi0_core_clk_src = {
@@ -1754,7 +1757,7 @@
 	.halt_check = BRANCH_HALT_DELAY,
 	.halt_bit = 31,
 	.clkr = {
-		.enable_reg = 0x683190,
+		.enable_reg = 0x68190,
 		.enable_mask = BIT(0),
 		.hw.init = &(struct clk_init_data) {
 			.name = "gcc_gmac0_sys_clk",
@@ -2180,7 +2183,7 @@
 };
 
 static struct clk_branch gcc_pcie1_pipe_clk = {
-	.halt_reg = 8,
+	.halt_reg = 0x76018,
 	.halt_check = BRANCH_HALT_DELAY,
 	.halt_bit = 31,
 	.clkr = {
@@ -3632,7 +3635,7 @@
 	[GCC_SYSTEM_NOC_BCR] = { 0x26000, 0 },
 	[GCC_TCSR_BCR] = { 0x28000, 0 },
 	[GCC_TLMM_BCR] = { 0x34000, 0 },
-	[GCC_UBI0_AXI_ARES] = { 0x680},
+	[GCC_UBI0_AXI_ARES] = { 0x68010, 0 },
 	[GCC_UBI0_AHB_ARES] = { 0x68010, 1 },
 	[GCC_UBI0_NC_AXI_ARES] = { 0x68010, 2 },
 	[GCC_UBI0_DBG_ARES] = { 0x68010, 3 },
@@ -3695,7 +3698,7 @@
 
 	clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
 
-	return qcom_cc_really_probe(pdev, &ipq5018_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &ipq5018_desc, regmap);
 }
 
 static struct platform_driver gcc_ipq5018_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-ipq5332.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-ipq5332.c
@@ -3388,6 +3388,7 @@
 	[GCC_QDSS_DAP_DIV_CLK_SRC] = &gcc_qdss_dap_div_clk_src.clkr,
 	[GCC_QDSS_ETR_USB_CLK] = &gcc_qdss_etr_usb_clk.clkr,
 	[GCC_QDSS_EUD_AT_CLK] = &gcc_qdss_eud_at_clk.clkr,
+	[GCC_QDSS_TSCTR_CLK_SRC] = &gcc_qdss_tsctr_clk_src.clkr,
 	[GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr,
 	[GCC_QPIC_CLK] = &gcc_qpic_clk.clkr,
 	[GCC_QPIC_IO_MACRO_CLK] = &gcc_qpic_io_macro_clk.clkr,
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-ipq6018.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-ipq6018.c
@@ -1554,6 +1554,7 @@
 
 static const struct freq_tbl ftbl_pcie_aux_clk_src[] = {
 	F(24000000, P_XO, 1, 0, 0),
+	{ }
 };
 
 static const struct clk_parent_data gcc_xo_gpll0_core_pi_sleep_clk[] = {
@@ -1734,6 +1735,7 @@
 	F(160000000, P_GPLL0, 5, 0, 0),
 	F(216000000, P_GPLL6, 5, 0, 0),
 	F(308570000, P_GPLL6, 3.5, 0, 0),
+	{ }
 };
 
 static const struct clk_parent_data gcc_xo_gpll0_gpll6_gpll0_div2[] = {
@@ -4623,7 +4625,7 @@
 	clk_alpha_pll_configure(&nss_crypto_pll_main, regmap,
 				&nss_crypto_pll_config);
 
-	return qcom_cc_really_probe(pdev, &gcc_ipq6018_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_ipq6018_desc, regmap);
 }
 
 static struct platform_driver gcc_ipq6018_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-ipq8074.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-ipq8074.c
@@ -644,6 +644,7 @@
 
 static const struct freq_tbl ftbl_pcie_aux_clk_src[] = {
 	F(19200000, P_XO, 1, 0, 0),
+	{ }
 };
 
 static const struct clk_parent_data gcc_xo_gpll0_sleep_clk[] = {
@@ -795,6 +796,7 @@
 	F(19200000, P_XO, 1, 0, 0),
 	F(160000000, P_GPLL0, 5, 0, 0),
 	F(308570000, P_GPLL6, 3.5, 0, 0),
+	{ }
 };
 
 static const struct clk_parent_data gcc_xo_gpll0_gpll6_gpll0_div2[] = {
@@ -4726,7 +4728,7 @@
 	clk_alpha_pll_configure(&nss_crypto_pll_main, regmap,
 				&nss_crypto_pll_config);
 
-	return qcom_cc_really_probe(pdev, &gcc_ipq8074_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_ipq8074_desc, regmap);
 }
 
 static struct platform_driver gcc_ipq8074_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-ipq9574.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-ipq9574.c
@@ -65,7 +65,7 @@
 
 static struct clk_alpha_pll gpll0_main = {
 	.offset = 0x20000,
-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
 	.clkr = {
 		.enable_reg = 0x0b000,
 		.enable_mask = BIT(0),
@@ -93,7 +93,7 @@
 
 static struct clk_alpha_pll_postdiv gpll0 = {
 	.offset = 0x20000,
-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
 	.width = 4,
 	.clkr.hw.init = &(const struct clk_init_data) {
 		.name = "gpll0",
@@ -107,7 +107,7 @@
 
 static struct clk_alpha_pll gpll4_main = {
 	.offset = 0x22000,
-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
 	.clkr = {
 		.enable_reg = 0x0b000,
 		.enable_mask = BIT(2),
@@ -122,7 +122,7 @@
 
 static struct clk_alpha_pll_postdiv gpll4 = {
 	.offset = 0x22000,
-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
 	.width = 4,
 	.clkr.hw.init = &(const struct clk_init_data) {
 		.name = "gpll4",
@@ -136,7 +136,7 @@
 
 static struct clk_alpha_pll gpll2_main = {
 	.offset = 0x21000,
-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
 	.clkr = {
 		.enable_reg = 0x0b000,
 		.enable_mask = BIT(1),
@@ -151,7 +151,7 @@
 
 static struct clk_alpha_pll_postdiv gpll2 = {
 	.offset = 0x21000,
-	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
 	.width = 4,
 	.clkr.hw.init = &(const struct clk_init_data) {
 		.name = "gpll2",
@@ -2082,6 +2082,7 @@
 static const struct freq_tbl ftbl_sdcc_ice_core_clk_src[] = {
 	F(150000000, P_GPLL4, 8, 0, 0),
 	F(300000000, P_GPLL4, 4, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 sdcc1_ice_core_clk_src = {
@@ -2139,9 +2140,10 @@
 
 static struct clk_branch gcc_crypto_axi_clk = {
 	.halt_reg = 0x16010,
+	.halt_check = BRANCH_HALT_VOTED,
 	.clkr = {
-		.enable_reg = 0x16010,
-		.enable_mask = BIT(0),
+		.enable_reg = 0xb004,
+		.enable_mask = BIT(15),
 		.hw.init = &(const struct clk_init_data) {
 			.name = "gcc_crypto_axi_clk",
 			.parent_hws = (const struct clk_hw *[]) {
@@ -2155,9 +2157,10 @@
 
 static struct clk_branch gcc_crypto_ahb_clk = {
 	.halt_reg = 0x16014,
+	.halt_check = BRANCH_HALT_VOTED,
 	.clkr = {
-		.enable_reg = 0x16014,
-		.enable_mask = BIT(0),
+		.enable_reg = 0xb004,
+		.enable_mask = BIT(16),
 		.hw.init = &(const struct clk_init_data) {
 			.name = "gcc_crypto_ahb_clk",
 			.parent_hws = (const struct clk_hw *[]) {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-mdm9607.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-mdm9607.c
@@ -535,7 +535,7 @@
 };
 
 static struct clk_rcg2 blsp1_uart6_apps_clk_src = {
-	.cmd_rcgr = 0x6044,
+	.cmd_rcgr = 0x7044,
 	.mnd_width = 16,
 	.hid_width = 5,
 	.parent_map = gcc_xo_gpll0_map,
@@ -1604,7 +1604,7 @@
 	/* Vote for GPLL0 to turn on. Needed by acpuclock. */
 	regmap_update_bits(regmap, 0x45000, BIT(0), BIT(0));
 
-	return qcom_cc_really_probe(pdev, &gcc_mdm9607_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_mdm9607_desc, regmap);
 }
 
 static struct platform_driver gcc_mdm9607_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-mdm9615.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-mdm9615.c
@@ -1736,7 +1736,7 @@
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	return qcom_cc_really_probe(pdev, &gcc_mdm9615_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_mdm9615_desc, regmap);
 }
 
 static struct platform_driver gcc_mdm9615_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-msm8917.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-msm8917.c
@@ -3270,7 +3270,7 @@
 
 	clk_alpha_pll_configure(&gpll3_early, regmap, &gpll3_early_config);
 
-	return qcom_cc_really_probe(pdev, gcc_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, gcc_desc, regmap);
 }
 
 static const struct of_device_id gcc_msm8917_match_table[] = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-msm8939.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-msm8939.c
@@ -4108,7 +4108,7 @@
 	clk_pll_configure_sr_hpm_lp(&gpll3, regmap, &gpll3_config, true);
 	clk_pll_configure_sr_hpm_lp(&gpll4, regmap, &gpll4_config, true);
 
-	return qcom_cc_really_probe(pdev, &gcc_msm8939_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_msm8939_desc, regmap);
 }
 
 static struct platform_driver gcc_msm8939_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-msm8953.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-msm8953.c
@@ -4216,7 +4216,7 @@
 
 	clk_alpha_pll_configure(&gpll3_early, regmap, &gpll3_early_config);
 
-	return qcom_cc_really_probe(pdev, &gcc_msm8953_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_msm8953_desc, regmap);
 }
 
 static const struct of_device_id gcc_msm8953_match_table[] = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-msm8976.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-msm8976.c
@@ -4129,7 +4129,7 @@
 	if (ret)
 		return ret;
 
-	return qcom_cc_really_probe(pdev, &gcc_msm8976_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_msm8976_desc, regmap);
 }
 
 static struct platform_driver gcc_msm8976_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-msm8996.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-msm8996.c
@@ -3620,7 +3620,7 @@
 	 */
 	regmap_update_bits(regmap, 0x52008, BIT(21), BIT(21));
 
-	return qcom_cc_really_probe(pdev, &gcc_msm8996_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_msm8996_desc, regmap);
 }
 
 static struct platform_driver gcc_msm8996_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-msm8998.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-msm8998.c
@@ -3292,7 +3292,7 @@
 	regmap_write(regmap, GCC_MMSS_MISC, 0x10003);
 	regmap_write(regmap, GCC_GPU_MISC, 0x10003);
 
-	return qcom_cc_really_probe(pdev, &gcc_msm8998_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_msm8998_desc, regmap);
 }
 
 static const struct of_device_id gcc_msm8998_match_table[] = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-qcm2290.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-qcm2290.c
@@ -2994,7 +2994,7 @@
 	clk_alpha_pll_configure(&gpll8, regmap, &gpll8_config);
 	clk_alpha_pll_configure(&gpll9, regmap, &gpll9_config);
 
-	return qcom_cc_really_probe(pdev, &gcc_qcm2290_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_qcm2290_desc, regmap);
 }
 
 static struct platform_driver gcc_qcm2290_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-qcs404.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-qcs404.c
@@ -131,6 +131,7 @@
 /* 930MHz configuration */
 static const struct alpha_pll_config gpll3_config = {
 	.l = 48,
+	.alpha_hi = 0x70,
 	.alpha = 0x0,
 	.alpha_en_mask = BIT(24),
 	.post_div_mask = 0xf << 8,
@@ -2824,7 +2825,7 @@
 
 	clk_alpha_pll_configure(&gpll3_out_main, regmap, &gpll3_config);
 
-	return qcom_cc_really_probe(pdev, &gcc_qcs404_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_qcs404_desc, regmap);
 }
 
 static struct platform_driver gcc_qcs404_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-qcs615.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-qcs615.c
@@ -0,0 +1,3034 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,qcs615-gcc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_BI_TCXO,
+	DT_BI_TCXO_AO,
+	DT_SLEEP_CLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_GPLL0_OUT_AUX2_DIV,
+	P_GPLL0_OUT_MAIN,
+	P_GPLL3_OUT_MAIN,
+	P_GPLL3_OUT_MAIN_DIV,
+	P_GPLL4_OUT_MAIN,
+	P_GPLL6_OUT_MAIN,
+	P_GPLL7_OUT_MAIN,
+	P_GPLL8_OUT_MAIN,
+	P_SLEEP_CLK,
+};
+
+static struct clk_alpha_pll gpll0 = {
+	.offset = 0x0,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_ops,
+		},
+	},
+};
+
+/* Fixed divider clock of GPLL0 instead of PLL normal postdiv */
+static struct clk_fixed_factor gpll0_out_aux2_div = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data) {
+		.name = "gpll0_out_aux2_div",
+		.parent_data = &(const struct clk_parent_data) {
+			.hw = &gpll0.clkr.hw,
+		},
+		.num_parents = 1,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+static struct clk_alpha_pll gpll3 = {
+	.offset = 0x3000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(3),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpll3",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_ops,
+		},
+	},
+};
+
+/* Fixed divider clock of GPLL3 instead of PLL normal postdiv */
+static struct clk_fixed_factor gpll3_out_aux2_div = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data) {
+		.name = "gpll3_out_aux2_div",
+		.parent_data = &(const struct clk_parent_data) {
+			.hw = &gpll3.clkr.hw,
+		},
+		.num_parents = 1,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+static struct clk_alpha_pll gpll4 = {
+	.offset = 0x76000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(4),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpll4",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_ops,
+		},
+	},
+};
+
+static struct clk_alpha_pll gpll6 = {
+	.offset = 0x13000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(6),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpll6",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_gpll6_out_main[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv gpll6_out_main = {
+	.offset = 0x13000,
+	.post_div_shift = 8,
+	.post_div_table = post_div_table_gpll6_out_main,
+	.num_post_div = ARRAY_SIZE(post_div_table_gpll6_out_main),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpll6_out_main",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gpll6.clkr.hw,
+		},
+		.num_parents = 1,
+		.ops = &clk_alpha_pll_postdiv_ops,
+	},
+};
+
+static struct clk_alpha_pll gpll7 = {
+	.offset = 0x1a000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(7),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpll7",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_ops,
+		},
+	},
+};
+
+static struct clk_alpha_pll gpll8 = {
+	.offset = 0x1b000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(8),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpll8",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_gpll8_out_main[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv gpll8_out_main = {
+	.offset = 0x1b000,
+	.post_div_shift = 8,
+	.post_div_table = post_div_table_gpll8_out_main,
+	.num_post_div = ARRAY_SIZE(post_div_table_gpll8_out_main),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpll8_out_main",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gpll8.clkr.hw,
+		},
+		.num_parents = 1,
+		.ops = &clk_alpha_pll_postdiv_ops,
+	},
+};
+
+static const struct parent_map gcc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+	{ P_GPLL0_OUT_AUX2_DIV, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll0_out_aux2_div.hw },
+};
+
+static const struct clk_parent_data gcc_parent_data_0_ao[] = {
+	{ .index = DT_BI_TCXO_AO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll0.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+	{ P_GPLL6_OUT_MAIN, 2 },
+	{ P_GPLL0_OUT_AUX2_DIV, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll6_out_main.clkr.hw },
+	{ .hw = &gpll0_out_aux2_div.hw },
+};
+
+static const struct parent_map gcc_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+	{ P_SLEEP_CLK, 5 },
+	{ P_GPLL0_OUT_AUX2_DIV, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .index = DT_SLEEP_CLK },
+	{ .hw = &gpll0_out_aux2_div.hw },
+};
+
+static const struct parent_map gcc_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data gcc_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map gcc_parent_map_4[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data gcc_parent_data_4[] = {
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct parent_map gcc_parent_map_5[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+	{ P_GPLL7_OUT_MAIN, 3 },
+	{ P_GPLL4_OUT_MAIN, 5 },
+	{ P_GPLL0_OUT_AUX2_DIV, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_5[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll7.clkr.hw },
+	{ .hw = &gpll4.clkr.hw },
+	{ .hw = &gpll0_out_aux2_div.hw },
+};
+
+static const struct parent_map gcc_parent_map_6[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+	{ P_GPLL7_OUT_MAIN, 3 },
+	{ P_GPLL0_OUT_AUX2_DIV, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_6[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll7.clkr.hw },
+	{ .hw = &gpll0_out_aux2_div.hw },
+};
+
+static const struct parent_map gcc_parent_map_7[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+	{ P_GPLL3_OUT_MAIN_DIV, 4 },
+	{ P_GPLL0_OUT_AUX2_DIV, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_7[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll3_out_aux2_div.hw },
+	{ .hw = &gpll0_out_aux2_div.hw },
+};
+
+static const struct parent_map gcc_parent_map_8[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+	{ P_GPLL8_OUT_MAIN, 2 },
+	{ P_GPLL4_OUT_MAIN, 5 },
+	{ P_GPLL0_OUT_AUX2_DIV, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_8[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll8_out_main.clkr.hw },
+	{ .hw = &gpll4.clkr.hw },
+	{ .hw = &gpll0_out_aux2_div.hw },
+};
+
+static const struct parent_map gcc_parent_map_9[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+	{ P_GPLL3_OUT_MAIN, 4 },
+};
+
+static const struct clk_parent_data gcc_parent_data_9[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll3.clkr.hw },
+};
+
+static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_cpuss_ahb_clk_src = {
+	.cmd_rcgr = 0x48014,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_cpuss_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_cpuss_ahb_clk_src",
+		.parent_data = gcc_parent_data_0_ao,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0_ao),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_emac_ptp_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(50000000, P_GPLL0_OUT_AUX2_DIV, 6, 0, 0),
+	F(75000000, P_GPLL0_OUT_AUX2_DIV, 4, 0, 0),
+	F(125000000, P_GPLL7_OUT_MAIN, 4, 0, 0),
+	F(250000000, P_GPLL7_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_emac_ptp_clk_src = {
+	.cmd_rcgr = 0x6038,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_5,
+	.freq_tbl = ftbl_gcc_emac_ptp_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_emac_ptp_clk_src",
+		.parent_data = gcc_parent_data_5,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_5),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_emac_rgmii_clk_src[] = {
+	F(2500000, P_BI_TCXO, 1, 25, 192),
+	F(5000000, P_BI_TCXO, 1, 25, 96),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(25000000, P_GPLL0_OUT_AUX2_DIV, 12, 0, 0),
+	F(50000000, P_GPLL0_OUT_AUX2_DIV, 6, 0, 0),
+	F(75000000, P_GPLL0_OUT_AUX2_DIV, 4, 0, 0),
+	F(125000000, P_GPLL7_OUT_MAIN, 4, 0, 0),
+	F(250000000, P_GPLL7_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_emac_rgmii_clk_src = {
+	.cmd_rcgr = 0x601c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_6,
+	.freq_tbl = ftbl_gcc_emac_rgmii_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_emac_rgmii_clk_src",
+		.parent_data = gcc_parent_data_6,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_6),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = {
+	F(25000000, P_GPLL0_OUT_AUX2_DIV, 12, 0, 0),
+	F(50000000, P_GPLL0_OUT_AUX2_DIV, 6, 0, 0),
+	F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_gp1_clk_src = {
+	.cmd_rcgr = 0x64004,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_gp1_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_gp1_clk_src",
+		.parent_data = gcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_2),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_gp2_clk_src = {
+	.cmd_rcgr = 0x65004,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_gp1_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_gp2_clk_src",
+		.parent_data = gcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_2),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_gp3_clk_src = {
+	.cmd_rcgr = 0x66004,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_gp1_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_gp3_clk_src",
+		.parent_data = gcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_2),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_pcie_0_aux_clk_src[] = {
+	F(9600000, P_BI_TCXO, 2, 0, 0),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pcie_0_aux_clk_src = {
+	.cmd_rcgr = 0x6b02c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_3,
+	.freq_tbl = ftbl_gcc_pcie_0_aux_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_0_aux_clk_src",
+		.parent_data = gcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_3),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_pcie_phy_refgen_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pcie_phy_refgen_clk_src = {
+	.cmd_rcgr = 0x6f014,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pcie_phy_refgen_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_phy_refgen_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pdm2_clk_src = {
+	.cmd_rcgr = 0x33010,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pdm2_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pdm2_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_qspi_core_clk_src[] = {
+	F(60000000, P_GPLL0_OUT_AUX2_DIV, 5, 0, 0),
+	F(133250000, P_GPLL3_OUT_MAIN_DIV, 4, 0, 0),
+	F(266500000, P_GPLL3_OUT_MAIN_DIV, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_qspi_core_clk_src = {
+	.cmd_rcgr = 0x4b008,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_7,
+	.freq_tbl = ftbl_gcc_qspi_core_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_qspi_core_clk_src",
+		.parent_data = gcc_parent_data_7,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_7),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+	F(7372800, P_GPLL0_OUT_AUX2_DIV, 1, 384, 15625),
+	F(14745600, P_GPLL0_OUT_AUX2_DIV, 1, 768, 15625),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(29491200, P_GPLL0_OUT_AUX2_DIV, 1, 1536, 15625),
+	F(32000000, P_GPLL0_OUT_AUX2_DIV, 1, 8, 75),
+	F(48000000, P_GPLL0_OUT_AUX2_DIV, 1, 4, 25),
+	F(64000000, P_GPLL0_OUT_AUX2_DIV, 1, 16, 75),
+	F(75000000, P_GPLL0_OUT_AUX2_DIV, 4, 0, 0),
+	F(80000000, P_GPLL0_OUT_AUX2_DIV, 1, 4, 15),
+	F(96000000, P_GPLL0_OUT_AUX2_DIV, 1, 8, 25),
+	F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+	F(102400000, P_GPLL0_OUT_AUX2_DIV, 1, 128, 375),
+	F(112000000, P_GPLL0_OUT_AUX2_DIV, 1, 28, 75),
+	F(117964800, P_GPLL0_OUT_AUX2_DIV, 1, 6144, 15625),
+	F(120000000, P_GPLL0_OUT_AUX2_DIV, 2.5, 0, 0),
+	F(128000000, P_GPLL6_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s0_clk_src",
+	.parent_data = gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+	.ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
+	.cmd_rcgr = 0x17148,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s1_clk_src",
+	.parent_data = gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+	.ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
+	.cmd_rcgr = 0x17278,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s2_clk_src",
+	.parent_data = gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+	.ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
+	.cmd_rcgr = 0x173a8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s3_clk_src",
+	.parent_data = gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+	.ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
+	.cmd_rcgr = 0x174d8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s4_clk_src",
+	.parent_data = gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+	.ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
+	.cmd_rcgr = 0x17608,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s5_clk_src",
+	.parent_data = gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+	.ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
+	.cmd_rcgr = 0x17738,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s0_clk_src",
+	.parent_data = gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+	.ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
+	.cmd_rcgr = 0x18148,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s1_clk_src",
+	.parent_data = gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+	.ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
+	.cmd_rcgr = 0x18278,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s2_clk_src",
+	.parent_data = gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+	.ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
+	.cmd_rcgr = 0x183a8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s3_clk_src",
+	.parent_data = gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+	.ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
+	.cmd_rcgr = 0x184d8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s4_clk_src",
+	.parent_data = gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+	.ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
+	.cmd_rcgr = 0x18608,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s5_clk_src",
+	.parent_data = gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+	.ops = &clk_rcg2_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
+	.cmd_rcgr = 0x18738,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = {
+	F(144000, P_BI_TCXO, 16, 3, 25),
+	F(400000, P_BI_TCXO, 12, 1, 4),
+	F(20000000, P_GPLL0_OUT_AUX2_DIV, 5, 1, 3),
+	F(25000000, P_GPLL0_OUT_AUX2_DIV, 6, 1, 2),
+	F(50000000, P_GPLL0_OUT_AUX2_DIV, 6, 0, 0),
+	F(100000000, P_GPLL0_OUT_AUX2_DIV, 3, 0, 0),
+	F(192000000, P_GPLL6_OUT_MAIN, 2, 0, 0),
+	F(384000000, P_GPLL6_OUT_MAIN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_sdcc1_apps_clk_src = {
+	.cmd_rcgr = 0x12028,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_sdcc1_apps_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_sdcc1_apps_clk_src",
+		.parent_data = gcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+		.ops = &clk_rcg2_floor_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = {
+	F(75000000, P_GPLL0_OUT_AUX2_DIV, 4, 0, 0),
+	F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+	F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = {
+	.cmd_rcgr = 0x12010,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_sdcc1_ice_core_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.ops = &clk_rcg2_floor_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
+	F(400000, P_BI_TCXO, 12, 1, 4),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(25000000, P_GPLL0_OUT_AUX2_DIV, 12, 0, 0),
+	F(50000000, P_GPLL0_OUT_AUX2_DIV, 6, 0, 0),
+	F(100000000, P_GPLL0_OUT_AUX2_DIV, 3, 0, 0),
+	F(202000000, P_GPLL8_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
+	.cmd_rcgr = 0x1400c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_8,
+	.freq_tbl = ftbl_gcc_sdcc2_apps_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_sdcc2_apps_clk_src",
+		.parent_data = gcc_parent_data_8,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_8),
+		.ops = &clk_rcg2_floor_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+	F(25000000, P_GPLL0_OUT_AUX2_DIV, 12, 0, 0),
+	F(50000000, P_GPLL0_OUT_AUX2_DIV, 6, 0, 0),
+	F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
+	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+	F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = {
+	.cmd_rcgr = 0x77020,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_ufs_phy_axi_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+	F(37500000, P_GPLL0_OUT_AUX2_DIV, 8, 0, 0),
+	F(75000000, P_GPLL0_OUT_AUX2_DIV, 4, 0, 0),
+	F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+	F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = {
+	.cmd_rcgr = 0x77048,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_ufs_phy_ice_core_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = {
+	.cmd_rcgr = 0x7707c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_4,
+	.freq_tbl = ftbl_gcc_pcie_0_aux_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_ufs_phy_phy_aux_clk_src",
+		.parent_data = gcc_parent_data_4,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_4),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
+	F(37500000, P_GPLL0_OUT_AUX2_DIV, 8, 0, 0),
+	F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+	F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = {
+	.cmd_rcgr = 0x77060,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_ufs_phy_unipro_core_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_ufs_phy_unipro_core_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_usb20_sec_master_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+	F(120000000, P_GPLL0_OUT_MAIN, 5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_usb20_sec_master_clk_src = {
+	.cmd_rcgr = 0xa601c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_usb20_sec_master_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb20_sec_master_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_usb20_sec_mock_utmi_clk_src = {
+	.cmd_rcgr = 0xa6034,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pdm2_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb20_sec_mock_utmi_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_usb2_sec_phy_aux_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_usb2_sec_phy_aux_clk_src = {
+	.cmd_rcgr = 0xa6060,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_3,
+	.freq_tbl = ftbl_gcc_usb2_sec_phy_aux_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb2_sec_phy_aux_clk_src",
+		.parent_data = gcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_3),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
+	F(66666667, P_GPLL0_OUT_AUX2_DIV, 4.5, 0, 0),
+	F(133333333, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+	F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_usb30_prim_master_clk_src = {
+	.cmd_rcgr = 0xf01c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_usb30_prim_master_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb30_prim_master_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_mock_utmi_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(20000000, P_GPLL0_OUT_AUX2_DIV, 15, 0, 0),
+	F(40000000, P_GPLL0_OUT_AUX2_DIV, 7.5, 0, 0),
+	F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = {
+	.cmd_rcgr = 0xf034,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb30_prim_mock_utmi_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = {
+	.cmd_rcgr = 0xf060,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_3,
+	.freq_tbl = ftbl_gcc_usb2_sec_phy_aux_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb3_prim_phy_aux_clk_src",
+		.parent_data = gcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_3),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_vsensor_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_vsensor_clk_src = {
+	.cmd_rcgr = 0x7a018,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_9,
+	.freq_tbl = ftbl_gcc_vsensor_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_vsensor_clk_src",
+		.parent_data = gcc_parent_data_9,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_9),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_branch gcc_aggre_ufs_phy_axi_clk = {
+	.halt_reg = 0x770c0,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x770c0,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x770c0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_aggre_ufs_phy_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_ufs_phy_axi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_aggre_usb2_sec_axi_clk = {
+	.halt_reg = 0xa6084,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xa6084,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_aggre_usb2_sec_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb20_sec_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_aggre_usb3_prim_axi_clk = {
+	.halt_reg = 0xf07c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xf07c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_aggre_usb3_prim_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb30_prim_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ahb2phy_east_clk = {
+	.halt_reg = 0x6a008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x6a008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x6a008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ahb2phy_east_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ahb2phy_west_clk = {
+	.halt_reg = 0x6a004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x6a004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x6a004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ahb2phy_west_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+	.halt_reg = 0x38004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x38004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52004,
+		.enable_mask = BIT(10),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_boot_rom_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_camera_hf_axi_clk = {
+	.halt_reg = 0xb030,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xb030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_camera_hf_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ce1_ahb_clk = {
+	.halt_reg = 0x4100c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x4100c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52004,
+		.enable_mask = BIT(3),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ce1_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ce1_axi_clk = {
+	.halt_reg = 0x41008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52004,
+		.enable_mask = BIT(4),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ce1_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ce1_clk = {
+	.halt_reg = 0x41004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52004,
+		.enable_mask = BIT(5),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ce1_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_cfg_noc_usb2_sec_axi_clk = {
+	.halt_reg = 0xa609c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xa609c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_cfg_noc_usb2_sec_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb20_sec_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = {
+	.halt_reg = 0xf078,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xf078,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_cfg_noc_usb3_prim_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb30_prim_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_cpuss_ahb_clk = {
+	.halt_reg = 0x48000,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52004,
+		.enable_mask = BIT(21),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_cpuss_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_cpuss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ddrss_gpu_axi_clk = {
+	.halt_reg = 0x71154,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x71154,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ddrss_gpu_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_disp_gpll0_div_clk_src = {
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x52004,
+		.enable_mask = BIT(20),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_disp_gpll0_div_clk_src",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpll0_out_aux2_div.hw,
+			},
+			.num_parents = 1,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_disp_hf_axi_clk = {
+	.halt_reg = 0xb038,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xb038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_disp_hf_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_emac_axi_clk = {
+	.halt_reg = 0x6010,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_emac_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_emac_ptp_clk = {
+	.halt_reg = 0x6034,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6034,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_emac_ptp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_emac_ptp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_emac_rgmii_clk = {
+	.halt_reg = 0x6018,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_emac_rgmii_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_emac_rgmii_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_emac_slv_ahb_clk = {
+	.halt_reg = 0x6014,
+	.halt_check = BRANCH_HALT,
+	.hwcg_reg = 0x6014,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x6014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_emac_slv_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gp1_clk = {
+	.halt_reg = 0x64000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x64000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gp1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_gp1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gp2_clk = {
+	.halt_reg = 0x65000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x65000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gp2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_gp2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gp3_clk = {
+	.halt_reg = 0x66000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x66000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gp3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_gp3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gpu_gpll0_clk_src = {
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x52004,
+		.enable_mask = BIT(15),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_gpll0_clk_src",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpll0.clkr.hw,
+			},
+			.num_parents = 1,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gpu_gpll0_div_clk_src = {
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x52004,
+		.enable_mask = BIT(16),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_gpll0_div_clk_src",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpll0_out_aux2_div.hw,
+			},
+			.num_parents = 1,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gpu_iref_clk = {
+	.halt_reg = 0x8c010,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8c010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_iref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gpu_memnoc_gfx_clk = {
+	.halt_reg = 0x7100c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x7100c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_memnoc_gfx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = {
+	.halt_reg = 0x71018,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x71018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_snoc_dvm_gfx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie0_phy_refgen_clk = {
+	.halt_reg = 0x6f02c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6f02c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie0_phy_refgen_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_phy_refgen_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_aux_clk = {
+	.halt_reg = 0x6b020,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(3),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_0_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_cfg_ahb_clk = {
+	.halt_reg = 0x6b01c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x6b01c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(2),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_cfg_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_clkref_clk = {
+	.halt_reg = 0x8c00c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8c00c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_clkref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
+	.halt_reg = 0x6b018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(1),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_mstr_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_pipe_clk = {
+	.halt_reg = 0x6b024,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(4),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_pipe_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_slv_axi_clk = {
+	.halt_reg = 0x6b014,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x6b014,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_slv_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_slv_q2a_axi_clk = {
+	.halt_reg = 0x6b010,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(5),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_slv_q2a_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_phy_aux_clk = {
+	.halt_reg = 0x6f004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x6f004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_0_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+	.halt_reg = 0x3300c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3300c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pdm2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pdm2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pdm_ahb_clk = {
+	.halt_reg = 0x33004,
+	.halt_check = BRANCH_HALT,
+	.hwcg_reg = 0x33004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x33004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pdm_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pdm_xo4_clk = {
+	.halt_reg = 0x33008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x33008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pdm_xo4_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+	.halt_reg = 0x34004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x34004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52004,
+		.enable_mask = BIT(13),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_prng_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = {
+	.halt_reg = 0xb018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0xb018,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0xb018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_camera_nrt_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_disp_ahb_clk = {
+	.halt_reg = 0xb020,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0xb020,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0xb020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_disp_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_pcie_ahb_clk = {
+	.halt_reg = 0x6b044,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x6b044,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(28),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_pcie_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = {
+	.halt_reg = 0xb014,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0xb014,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0xb014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_video_vcodec_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qspi_cnoc_periph_ahb_clk = {
+	.halt_reg = 0x4b000,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qspi_cnoc_periph_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qspi_core_clk = {
+	.halt_reg = 0x4b004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x4b004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qspi_core_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qspi_core_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_core_2x_clk = {
+	.halt_reg = 0x17014,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(9),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_core_2x_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_core_clk = {
+	.halt_reg = 0x1700c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(8),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_core_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s0_clk = {
+	.halt_reg = 0x17144,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(10),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_s0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap0_s0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s1_clk = {
+	.halt_reg = 0x17274,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(11),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_s1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap0_s1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s2_clk = {
+	.halt_reg = 0x173a4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(12),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_s2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap0_s2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s3_clk = {
+	.halt_reg = 0x174d4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(13),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_s3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap0_s3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s4_clk = {
+	.halt_reg = 0x17604,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(14),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_s4_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap0_s4_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s5_clk = {
+	.halt_reg = 0x17734,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(15),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_s5_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap0_s5_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = {
+	.halt_reg = 0x18014,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(18),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_core_2x_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_core_clk = {
+	.halt_reg = 0x1800c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(19),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_core_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s0_clk = {
+	.halt_reg = 0x18144,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(22),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_s0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_s0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s1_clk = {
+	.halt_reg = 0x18274,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(23),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_s1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_s1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s2_clk = {
+	.halt_reg = 0x183a4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(24),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_s2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_s2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s3_clk = {
+	.halt_reg = 0x184d4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(25),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_s3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_s3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s4_clk = {
+	.halt_reg = 0x18604,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(26),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_s4_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_s4_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s5_clk = {
+	.halt_reg = 0x18734,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(27),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_s5_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_s5_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = {
+	.halt_reg = 0x17004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(6),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_0_m_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = {
+	.halt_reg = 0x17008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x17008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(7),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_0_s_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_1_m_ahb_clk = {
+	.halt_reg = 0x18004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(20),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_1_m_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = {
+	.halt_reg = 0x18008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x18008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x5200c,
+		.enable_mask = BIT(21),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_1_s_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_rx1_usb2_clkref_clk = {
+	.halt_reg = 0x8c030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8c030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_rx1_usb2_clkref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_rx3_usb2_clkref_clk = {
+	.halt_reg = 0x8c038,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x8c038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_rx3_usb2_clkref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+	.halt_reg = 0x12008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x12008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_sdcc1_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+	.halt_reg = 0x12004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x12004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_sdcc1_apps_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_sdcc1_apps_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_sdcc1_ice_core_clk = {
+	.halt_reg = 0x1200c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1200c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_sdcc1_ice_core_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_sdcc1_ice_core_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_sdcc2_ahb_clk = {
+	.halt_reg = 0x14008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x14008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_sdcc2_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_sdcc2_apps_clk = {
+	.halt_reg = 0x14004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x14004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_sdcc2_apps_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_sdcc2_apps_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = {
+	.halt_reg = 0x4819c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52004,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data) {
+			.name = "gcc_sys_noc_cpuss_ahb_clk",
+			.parent_data = &(const struct clk_parent_data) {
+				.hw = &gcc_cpuss_ahb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_card_clkref_clk = {
+	.halt_reg = 0x8c004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x8c004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_card_clkref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_mem_clkref_clk = {
+	.halt_reg = 0x8c000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8c000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_mem_clkref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_ahb_clk = {
+	.halt_reg = 0x77014,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x77014,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x77014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_axi_clk = {
+	.halt_reg = 0x77010,
+	.halt_check = BRANCH_HALT,
+	.hwcg_reg = 0x77010,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x77010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_ufs_phy_axi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_ice_core_clk = {
+	.halt_reg = 0x77044,
+	.halt_check = BRANCH_HALT,
+	.hwcg_reg = 0x77044,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x77044,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_ice_core_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_ufs_phy_ice_core_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_phy_aux_clk = {
+	.halt_reg = 0x77078,
+	.halt_check = BRANCH_HALT,
+	.hwcg_reg = 0x77078,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x77078,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_ufs_phy_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = {
+	.halt_reg = 0x7701c,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x7701c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_rx_symbol_0_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = {
+	.halt_reg = 0x77018,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x77018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_tx_symbol_0_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_unipro_core_clk = {
+	.halt_reg = 0x77040,
+	.halt_check = BRANCH_HALT,
+	.hwcg_reg = 0x77040,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x77040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_unipro_core_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_ufs_phy_unipro_core_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb20_sec_master_clk = {
+	.halt_reg = 0xa6010,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xa6010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb20_sec_master_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb20_sec_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb20_sec_mock_utmi_clk = {
+	.halt_reg = 0xa6018,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa6018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb20_sec_mock_utmi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb20_sec_mock_utmi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb20_sec_sleep_clk = {
+	.halt_reg = 0xa6014,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa6014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb20_sec_sleep_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb2_prim_clkref_clk = {
+	.halt_reg = 0x8c028,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x8c028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb2_prim_clkref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb2_sec_clkref_clk = {
+	.halt_reg = 0x8c018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x8c018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb2_sec_clkref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb2_sec_phy_aux_clk = {
+	.halt_reg = 0xa6050,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa6050,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb2_sec_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb2_sec_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb2_sec_phy_com_aux_clk = {
+	.halt_reg = 0xa6054,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa6054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb2_sec_phy_com_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb2_sec_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb2_sec_phy_pipe_clk = {
+	.halt_reg = 0xa6058,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0xa6058,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb2_sec_phy_pipe_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb30_prim_master_clk = {
+	.halt_reg = 0xf010,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xf010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb30_prim_master_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb30_prim_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb30_prim_mock_utmi_clk = {
+	.halt_reg = 0xf018,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xf018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb30_prim_mock_utmi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb30_prim_mock_utmi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb30_prim_sleep_clk = {
+	.halt_reg = 0xf014,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xf014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb30_prim_sleep_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb3_prim_clkref_clk = {
+	.halt_reg = 0x8c014,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x8c014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb3_prim_clkref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb3_prim_phy_aux_clk = {
+	.halt_reg = 0xf050,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xf050,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb3_prim_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb3_prim_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = {
+	.halt_reg = 0xf054,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xf054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb3_prim_phy_com_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb3_prim_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb3_prim_phy_pipe_clk = {
+	.halt_reg = 0xf058,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0xf058,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb3_prim_phy_pipe_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb3_sec_clkref_clk = {
+	.halt_reg = 0x8c008,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x8c008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb3_sec_clkref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_video_axi0_clk = {
+	.halt_reg = 0xb024,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xb024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_video_axi0_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_hw *gcc_qcs615_hws[] = {
+	[GPLL0_OUT_AUX2_DIV] = &gpll0_out_aux2_div.hw,
+	[GPLL3_OUT_AUX2_DIV] = &gpll3_out_aux2_div.hw,
+};
+
+static struct gdsc emac_gdsc = {
+	.gdscr = 0x6004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.pd = {
+		.name = "emac_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc pcie_0_gdsc = {
+	.gdscr = 0x6b004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.pd = {
+		.name = "pcie_0_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc ufs_phy_gdsc = {
+	.gdscr = 0x77004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.pd = {
+		.name = "ufs_phy_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc usb20_sec_gdsc = {
+	.gdscr = 0xa6004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.pd = {
+		.name = "usb20_sec_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc usb30_prim_gdsc = {
+	.gdscr = 0xf004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.pd = {
+		.name = "usb30_prim_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc hlos1_vote_aggre_noc_mmu_audio_tbu_gdsc = {
+	.gdscr = 0x7d040,
+	.pd = {
+		.name = "hlos1_vote_aggre_noc_mmu_audio_tbu",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE,
+};
+
+static struct gdsc hlos1_vote_aggre_noc_mmu_tbu1_gdsc = {
+	.gdscr = 0x7d044,
+	.pd = {
+		.name = "hlos1_vote_aggre_noc_mmu_tbu1",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE,
+};
+
+static struct gdsc hlos1_vote_aggre_noc_mmu_tbu2_gdsc = {
+	.gdscr = 0x7d048,
+	.pd = {
+		.name = "hlos1_vote_aggre_noc_mmu_tbu2",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE,
+};
+
+static struct gdsc hlos1_vote_aggre_noc_mmu_pcie_tbu_gdsc = {
+	.gdscr = 0x7d04c,
+	.pd = {
+		.name = "hlos1_vote_aggre_noc_mmu_pcie_tbu",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE,
+};
+
+static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = {
+	.gdscr = 0x7d050,
+	.pd = {
+		.name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE,
+};
+
+static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf_gdsc = {
+	.gdscr = 0x7d054,
+	.pd = {
+		.name = "hlos1_vote_mmnoc_mmu_tbu_sf_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE,
+};
+
+static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc = {
+	.gdscr = 0x7d058,
+	.pd = {
+		.name = "hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE,
+};
+
+static struct clk_regmap *gcc_qcs615_clocks[] = {
+	[GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr,
+	[GCC_AGGRE_USB2_SEC_AXI_CLK] = &gcc_aggre_usb2_sec_axi_clk.clkr,
+	[GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr,
+	[GCC_AHB2PHY_EAST_CLK] = &gcc_ahb2phy_east_clk.clkr,
+	[GCC_AHB2PHY_WEST_CLK] = &gcc_ahb2phy_west_clk.clkr,
+	[GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+	[GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr,
+	[GCC_CE1_AHB_CLK] = &gcc_ce1_ahb_clk.clkr,
+	[GCC_CE1_AXI_CLK] = &gcc_ce1_axi_clk.clkr,
+	[GCC_CE1_CLK] = &gcc_ce1_clk.clkr,
+	[GCC_CFG_NOC_USB2_SEC_AXI_CLK] = &gcc_cfg_noc_usb2_sec_axi_clk.clkr,
+	[GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr,
+	[GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr,
+	[GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr,
+	[GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr,
+	[GCC_DISP_GPLL0_DIV_CLK_SRC] = &gcc_disp_gpll0_div_clk_src.clkr,
+	[GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr,
+	[GCC_EMAC_AXI_CLK] = &gcc_emac_axi_clk.clkr,
+	[GCC_EMAC_PTP_CLK] = &gcc_emac_ptp_clk.clkr,
+	[GCC_EMAC_PTP_CLK_SRC] = &gcc_emac_ptp_clk_src.clkr,
+	[GCC_EMAC_RGMII_CLK] = &gcc_emac_rgmii_clk.clkr,
+	[GCC_EMAC_RGMII_CLK_SRC] = &gcc_emac_rgmii_clk_src.clkr,
+	[GCC_EMAC_SLV_AHB_CLK] = &gcc_emac_slv_ahb_clk.clkr,
+	[GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+	[GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr,
+	[GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+	[GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr,
+	[GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+	[GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr,
+	[GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr,
+	[GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr,
+	[GCC_GPU_IREF_CLK] = &gcc_gpu_iref_clk.clkr,
+	[GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr,
+	[GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr,
+	[GCC_PCIE0_PHY_REFGEN_CLK] = &gcc_pcie0_phy_refgen_clk.clkr,
+	[GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr,
+	[GCC_PCIE_0_AUX_CLK_SRC] = &gcc_pcie_0_aux_clk_src.clkr,
+	[GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr,
+	[GCC_PCIE_0_CLKREF_CLK] = &gcc_pcie_0_clkref_clk.clkr,
+	[GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr,
+	[GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr,
+	[GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr,
+	[GCC_PCIE_0_SLV_Q2A_AXI_CLK] = &gcc_pcie_0_slv_q2a_axi_clk.clkr,
+	[GCC_PCIE_PHY_AUX_CLK] = &gcc_pcie_phy_aux_clk.clkr,
+	[GCC_PCIE_PHY_REFGEN_CLK_SRC] = &gcc_pcie_phy_refgen_clk_src.clkr,
+	[GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+	[GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr,
+	[GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+	[GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr,
+	[GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+	[GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr,
+	[GCC_QMIP_DISP_AHB_CLK] = &gcc_qmip_disp_ahb_clk.clkr,
+	[GCC_QMIP_PCIE_AHB_CLK] = &gcc_qmip_pcie_ahb_clk.clkr,
+	[GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr,
+	[GCC_QSPI_CNOC_PERIPH_AHB_CLK] = &gcc_qspi_cnoc_periph_ahb_clk.clkr,
+	[GCC_QSPI_CORE_CLK] = &gcc_qspi_core_clk.clkr,
+	[GCC_QSPI_CORE_CLK_SRC] = &gcc_qspi_core_clk_src.clkr,
+	[GCC_QUPV3_WRAP0_CORE_2X_CLK] = &gcc_qupv3_wrap0_core_2x_clk.clkr,
+	[GCC_QUPV3_WRAP0_CORE_CLK] = &gcc_qupv3_wrap0_core_clk.clkr,
+	[GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr,
+	[GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr,
+	[GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr,
+	[GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr,
+	[GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr,
+	[GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr,
+	[GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr,
+	[GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr,
+	[GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr,
+	[GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr,
+	[GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr,
+	[GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr,
+	[GCC_QUPV3_WRAP1_CORE_2X_CLK] = &gcc_qupv3_wrap1_core_2x_clk.clkr,
+	[GCC_QUPV3_WRAP1_CORE_CLK] = &gcc_qupv3_wrap1_core_clk.clkr,
+	[GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr,
+	[GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr,
+	[GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr,
+	[GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr,
+	[GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr,
+	[GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr,
+	[GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr,
+	[GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr,
+	[GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr,
+	[GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr,
+	[GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr,
+	[GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr,
+	[GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr,
+	[GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr,
+	[GCC_QUPV3_WRAP_1_M_AHB_CLK] = &gcc_qupv3_wrap_1_m_ahb_clk.clkr,
+	[GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr,
+	[GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr,
+	[GCC_RX3_USB2_CLKREF_CLK] = &gcc_rx3_usb2_clkref_clk.clkr,
+	[GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+	[GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+	[GCC_SDCC1_APPS_CLK_SRC] = &gcc_sdcc1_apps_clk_src.clkr,
+	[GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr,
+	[GCC_SDCC1_ICE_CORE_CLK_SRC] = &gcc_sdcc1_ice_core_clk_src.clkr,
+	[GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
+	[GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
+	[GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr,
+	[GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr,
+	[GCC_UFS_CARD_CLKREF_CLK] = &gcc_ufs_card_clkref_clk.clkr,
+	[GCC_UFS_MEM_CLKREF_CLK] = &gcc_ufs_mem_clkref_clk.clkr,
+	[GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr,
+	[GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr,
+	[GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr,
+	[GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr,
+	[GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr,
+	[GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr,
+	[GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr,
+	[GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr,
+	[GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr,
+	[GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr,
+	[GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = &gcc_ufs_phy_unipro_core_clk_src.clkr,
+	[GCC_USB20_SEC_MASTER_CLK] = &gcc_usb20_sec_master_clk.clkr,
+	[GCC_USB20_SEC_MASTER_CLK_SRC] = &gcc_usb20_sec_master_clk_src.clkr,
+	[GCC_USB20_SEC_MOCK_UTMI_CLK] = &gcc_usb20_sec_mock_utmi_clk.clkr,
+	[GCC_USB20_SEC_MOCK_UTMI_CLK_SRC] = &gcc_usb20_sec_mock_utmi_clk_src.clkr,
+	[GCC_USB20_SEC_SLEEP_CLK] = &gcc_usb20_sec_sleep_clk.clkr,
+	[GCC_USB2_PRIM_CLKREF_CLK] = &gcc_usb2_prim_clkref_clk.clkr,
+	[GCC_USB2_SEC_CLKREF_CLK] = &gcc_usb2_sec_clkref_clk.clkr,
+	[GCC_USB2_SEC_PHY_AUX_CLK] = &gcc_usb2_sec_phy_aux_clk.clkr,
+	[GCC_USB2_SEC_PHY_AUX_CLK_SRC] = &gcc_usb2_sec_phy_aux_clk_src.clkr,
+	[GCC_USB2_SEC_PHY_COM_AUX_CLK] = &gcc_usb2_sec_phy_com_aux_clk.clkr,
+	[GCC_USB2_SEC_PHY_PIPE_CLK] = &gcc_usb2_sec_phy_pipe_clk.clkr,
+	[GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr,
+	[GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr,
+	[GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr,
+	[GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = &gcc_usb30_prim_mock_utmi_clk_src.clkr,
+	[GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr,
+	[GCC_USB3_PRIM_CLKREF_CLK] = &gcc_usb3_prim_clkref_clk.clkr,
+	[GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr,
+	[GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr,
+	[GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr,
+	[GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr,
+	[GCC_USB3_SEC_CLKREF_CLK] = &gcc_usb3_sec_clkref_clk.clkr,
+	[GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr,
+	[GCC_VSENSOR_CLK_SRC] = &gcc_vsensor_clk_src.clkr,
+	[GPLL0] = &gpll0.clkr,
+	[GPLL3] = &gpll3.clkr,
+	[GPLL4] = &gpll4.clkr,
+	[GPLL6] = &gpll6.clkr,
+	[GPLL6_OUT_MAIN] = &gpll6_out_main.clkr,
+	[GPLL7] = &gpll7.clkr,
+	[GPLL8] = &gpll8.clkr,
+	[GPLL8_OUT_MAIN] = &gpll8_out_main.clkr,
+};
+
+static struct gdsc *gcc_qcs615_gdscs[] = {
+	[EMAC_GDSC] = &emac_gdsc,
+	[PCIE_0_GDSC] = &pcie_0_gdsc,
+	[UFS_PHY_GDSC] = &ufs_phy_gdsc,
+	[USB20_SEC_GDSC] = &usb20_sec_gdsc,
+	[USB30_PRIM_GDSC] = &usb30_prim_gdsc,
+	[HLOS1_VOTE_AGGRE_NOC_MMU_AUDIO_TBU_GDSC] = &hlos1_vote_aggre_noc_mmu_audio_tbu_gdsc,
+	[HLOS1_VOTE_AGGRE_NOC_MMU_TBU1_GDSC] = &hlos1_vote_aggre_noc_mmu_tbu1_gdsc,
+	[HLOS1_VOTE_AGGRE_NOC_MMU_TBU2_GDSC] = &hlos1_vote_aggre_noc_mmu_tbu2_gdsc,
+	[HLOS1_VOTE_AGGRE_NOC_MMU_PCIE_TBU_GDSC] = &hlos1_vote_aggre_noc_mmu_pcie_tbu_gdsc,
+	[HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc,
+	[HLOS1_VOTE_MMNOC_MMU_TBU_SF_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_sf_gdsc,
+	[HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc,
+};
+
+static const struct qcom_reset_map gcc_qcs615_resets[] = {
+	[GCC_EMAC_BCR] = { 0x6000 },
+	[GCC_QUSB2PHY_PRIM_BCR] = { 0xd000 },
+	[GCC_QUSB2PHY_SEC_BCR] = { 0xd004 },
+	[GCC_USB30_PRIM_BCR] = { 0xf000 },
+	[GCC_USB2_PHY_SEC_BCR] = { 0x50018 },
+	[GCC_USB3_DP_PHY_SEC_BCR] = { 0x50020 },
+	[GCC_USB3PHY_PHY_SEC_BCR] = { 0x5001c },
+	[GCC_PCIE_0_BCR] = { 0x6b000 },
+	[GCC_PCIE_0_PHY_BCR] = { 0x6c01c },
+	[GCC_PCIE_PHY_BCR] = { 0x6f000 },
+	[GCC_PCIE_PHY_COM_BCR] = { 0x6f010 },
+	[GCC_UFS_PHY_BCR] = { 0x77000 },
+	[GCC_USB20_SEC_BCR] = { 0xa6000 },
+	[GCC_USB3PHY_PHY_PRIM_SP0_BCR] = { 0x50008 },
+	[GCC_USB3_PHY_PRIM_SP0_BCR] = { 0x50000 },
+	[GCC_SDCC1_BCR] = { 0x12000 },
+	[GCC_SDCC2_BCR] = { 0x14000 },
+};
+
+static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src),
+};
+
+static const struct regmap_config gcc_qcs615_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0xa609c,
+	.fast_io = true,
+};
+
+static const struct qcom_cc_desc gcc_qcs615_desc = {
+	.config = &gcc_qcs615_regmap_config,
+	.clk_hws = gcc_qcs615_hws,
+	.num_clk_hws = ARRAY_SIZE(gcc_qcs615_hws),
+	.clks = gcc_qcs615_clocks,
+	.num_clks = ARRAY_SIZE(gcc_qcs615_clocks),
+	.resets = gcc_qcs615_resets,
+	.num_resets = ARRAY_SIZE(gcc_qcs615_resets),
+	.gdscs = gcc_qcs615_gdscs,
+	.num_gdscs = ARRAY_SIZE(gcc_qcs615_gdscs),
+};
+
+static const struct of_device_id gcc_qcs615_match_table[] = {
+	{ .compatible = "qcom,qcs615-gcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, gcc_qcs615_match_table);
+
+static int gcc_qcs615_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+	int ret;
+
+	regmap = qcom_cc_map(pdev, &gcc_qcs615_desc);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+	/*
+	 * Disable the GPLL0 active input to MM blocks and GPU
+	 * via MISC registers.
+	 */
+	regmap_update_bits(regmap, 0x0b084, BIT(0), BIT(0));
+	regmap_update_bits(regmap, 0x9b000, BIT(0), BIT(0));
+
+	/* Keep some clocks always enabled */
+	qcom_branch_set_clk_en(regmap, 0xb008); /* GCC_CAMERA_AHB_CLK */
+	qcom_branch_set_clk_en(regmap, 0xb044); /* GCC_CAMERA_XO_CLK */
+	qcom_branch_set_clk_en(regmap, 0xb00c); /* GCC_DISP_AHB_CLK */
+	qcom_branch_set_clk_en(regmap, 0xb048); /* GCC_DISP_XO_CLK */
+	qcom_branch_set_clk_en(regmap, 0x71004); /* GCC_GPU_CFG_AHB_CLK */
+	qcom_branch_set_clk_en(regmap, 0xb004); /* GCC_VIDEO_AHB_CLK */
+	qcom_branch_set_clk_en(regmap, 0xb040); /* GCC_VIDEO_XO_CLK */
+	qcom_branch_set_clk_en(regmap, 0x480040); /* GCC_CPUSS_GNOC_CLK */
+
+	ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks,
+				       ARRAY_SIZE(gcc_dfs_clocks));
+	if (ret)
+		return ret;
+
+	return qcom_cc_really_probe(&pdev->dev, &gcc_qcs615_desc, regmap);
+}
+
+static struct platform_driver gcc_qcs615_driver = {
+	.probe = gcc_qcs615_probe,
+	.driver = {
+		.name = "gcc-qcs615",
+		.of_match_table = gcc_qcs615_match_table,
+	},
+};
+
+static int __init gcc_qcs615_init(void)
+{
+	return platform_driver_register(&gcc_qcs615_driver);
+}
+subsys_initcall(gcc_qcs615_init);
+
+static void __exit gcc_qcs615_exit(void)
+{
+	platform_driver_unregister(&gcc_qcs615_driver);
+}
+module_exit(gcc_qcs615_exit);
+
+MODULE_DESCRIPTION("QTI GCC QCS615 Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-qcs8300.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-qcs8300.c
@@ -0,0 +1,3640 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,qcs8300-gcc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "clk-regmap-phy-mux.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_BI_TCXO,
+	DT_SLEEP_CLK,
+	DT_PCIE_0_PIPE_CLK,
+	DT_PCIE_1_PIPE_CLK,
+	DT_PCIE_PHY_AUX_CLK,
+	DT_RXC0_REF_CLK,
+	DT_UFS_PHY_RX_SYMBOL_0_CLK,
+	DT_UFS_PHY_RX_SYMBOL_1_CLK,
+	DT_UFS_PHY_TX_SYMBOL_0_CLK,
+	DT_USB3_PHY_WRAPPER_GCC_USB30_PRIM_PIPE_CLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_GCC_GPLL0_OUT_EVEN,
+	P_GCC_GPLL0_OUT_MAIN,
+	P_GCC_GPLL1_OUT_MAIN,
+	P_GCC_GPLL4_OUT_MAIN,
+	P_GCC_GPLL7_OUT_MAIN,
+	P_GCC_GPLL9_OUT_MAIN,
+	P_PCIE_0_PIPE_CLK,
+	P_PCIE_1_PIPE_CLK,
+	P_PCIE_PHY_AUX_CLK,
+	P_RXC0_REF_CLK,
+	P_SLEEP_CLK,
+	P_UFS_PHY_RX_SYMBOL_0_CLK,
+	P_UFS_PHY_RX_SYMBOL_1_CLK,
+	P_UFS_PHY_TX_SYMBOL_0_CLK,
+	P_USB3_PHY_WRAPPER_GCC_USB30_PRIM_PIPE_CLK,
+};
+
+static struct clk_alpha_pll gcc_gpll0 = {
+	.offset = 0x0,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.enable_reg = 0x4b028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_gcc_gpll0_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv gcc_gpll0_out_even = {
+	.offset = 0x0,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_gcc_gpll0_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_gcc_gpll0_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_gpll0_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gcc_gpll0.clkr.hw,
+		},
+		.num_parents = 1,
+		.ops = &clk_alpha_pll_postdiv_lucid_evo_ops,
+	},
+};
+
+static struct clk_alpha_pll gcc_gpll1 = {
+	.offset = 0x1000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.enable_reg = 0x4b028,
+		.enable_mask = BIT(1),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpll1",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_lucid_evo_ops,
+		},
+	},
+};
+
+static struct clk_alpha_pll gcc_gpll4 = {
+	.offset = 0x4000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.enable_reg = 0x4b028,
+		.enable_mask = BIT(4),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpll4",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_lucid_evo_ops,
+		},
+	},
+};
+
+static struct clk_alpha_pll gcc_gpll7 = {
+	.offset = 0x7000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.enable_reg = 0x4b028,
+		.enable_mask = BIT(7),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpll7",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_lucid_evo_ops,
+		},
+	},
+};
+
+static struct clk_alpha_pll gcc_gpll9 = {
+	.offset = 0x9000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.enable_reg = 0x4b028,
+		.enable_mask = BIT(9),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpll9",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct parent_map gcc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_GCC_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gcc_gpll0.clkr.hw },
+	{ .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_SLEEP_CLK, 5 },
+	{ P_GCC_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gcc_gpll0.clkr.hw },
+	{ .index = DT_SLEEP_CLK },
+	{ .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data gcc_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map gcc_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_GCC_GPLL1_OUT_MAIN, 4 },
+	{ P_GCC_GPLL4_OUT_MAIN, 5 },
+	{ P_GCC_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gcc_gpll0.clkr.hw },
+	{ .hw = &gcc_gpll1.clkr.hw },
+	{ .hw = &gcc_gpll4.clkr.hw },
+	{ .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_4[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_GCC_GPLL4_OUT_MAIN, 5 },
+	{ P_GCC_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_4[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gcc_gpll0.clkr.hw },
+	{ .hw = &gcc_gpll4.clkr.hw },
+	{ .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_5[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data gcc_parent_data_5[] = {
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct parent_map gcc_parent_map_6[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GCC_GPLL7_OUT_MAIN, 2 },
+	{ P_GCC_GPLL4_OUT_MAIN, 5 },
+	{ P_GCC_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_6[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gcc_gpll7.clkr.hw },
+	{ .hw = &gcc_gpll4.clkr.hw },
+	{ .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_7[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GCC_GPLL7_OUT_MAIN, 2 },
+	{ P_RXC0_REF_CLK, 3 },
+	{ P_GCC_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_7[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gcc_gpll7.clkr.hw },
+	{ .index = DT_RXC0_REF_CLK },
+	{ .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_8[] = {
+	{ P_PCIE_PHY_AUX_CLK, 1 },
+	{ P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_8[] = {
+	{ .index = DT_PCIE_PHY_AUX_CLK },
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct parent_map gcc_parent_map_10[] = {
+	{ P_PCIE_PHY_AUX_CLK, 1 },
+	{ P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_10[] = {
+	{ .index = DT_PCIE_PHY_AUX_CLK },
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct parent_map gcc_parent_map_12[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_GCC_GPLL9_OUT_MAIN, 2 },
+	{ P_GCC_GPLL4_OUT_MAIN, 5 },
+	{ P_GCC_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_12[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gcc_gpll0.clkr.hw },
+	{ .hw = &gcc_gpll9.clkr.hw },
+	{ .hw = &gcc_gpll4.clkr.hw },
+	{ .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_13[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GCC_GPLL0_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data gcc_parent_data_13[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gcc_gpll0.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_14[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_GCC_GPLL4_OUT_MAIN, 3 },
+	{ P_GCC_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_14[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gcc_gpll0.clkr.hw },
+	{ .hw = &gcc_gpll4.clkr.hw },
+	{ .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_15[] = {
+	{ P_UFS_PHY_RX_SYMBOL_0_CLK, 0 },
+	{ P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_15[] = {
+	{ .index = DT_UFS_PHY_RX_SYMBOL_0_CLK },
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct parent_map gcc_parent_map_16[] = {
+	{ P_UFS_PHY_RX_SYMBOL_1_CLK, 0 },
+	{ P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_16[] = {
+	{ .index = DT_UFS_PHY_RX_SYMBOL_1_CLK },
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct parent_map gcc_parent_map_17[] = {
+	{ P_UFS_PHY_TX_SYMBOL_0_CLK, 0 },
+	{ P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_17[] = {
+	{ .index = DT_UFS_PHY_TX_SYMBOL_0_CLK },
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct parent_map gcc_parent_map_18[] = {
+	{ P_USB3_PHY_WRAPPER_GCC_USB30_PRIM_PIPE_CLK, 0 },
+	{ P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_18[] = {
+	{ .index = DT_USB3_PHY_WRAPPER_GCC_USB30_PRIM_PIPE_CLK },
+	{ .index = DT_BI_TCXO },
+};
+
+static struct clk_regmap_mux gcc_pcie_0_phy_aux_clk_src = {
+	.reg = 0xa9074,
+	.shift = 0,
+	.width = 2,
+	.parent_map = gcc_parent_map_8,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_phy_aux_clk_src",
+			.parent_data = gcc_parent_data_8,
+			.num_parents = ARRAY_SIZE(gcc_parent_data_8),
+			.ops = &clk_regmap_mux_closest_ops,
+		},
+	},
+};
+
+static struct clk_regmap_phy_mux gcc_pcie_0_pipe_clk_src = {
+	.reg = 0xa906c,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_pipe_clk_src",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_PCIE_0_PIPE_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static struct clk_regmap_mux gcc_pcie_1_phy_aux_clk_src = {
+	.reg = 0x77074,
+	.shift = 0,
+	.width = 2,
+	.parent_map = gcc_parent_map_10,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_1_phy_aux_clk_src",
+			.parent_data = gcc_parent_data_10,
+			.num_parents = ARRAY_SIZE(gcc_parent_data_10),
+			.ops = &clk_regmap_mux_closest_ops,
+		},
+	},
+};
+
+static struct clk_regmap_phy_mux gcc_pcie_1_pipe_clk_src = {
+	.reg = 0x7706c,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_1_pipe_clk_src",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_PCIE_1_PIPE_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static struct clk_regmap_mux gcc_ufs_phy_rx_symbol_0_clk_src = {
+	.reg = 0x83060,
+	.shift = 0,
+	.width = 2,
+	.parent_map = gcc_parent_map_15,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_rx_symbol_0_clk_src",
+			.parent_data = gcc_parent_data_15,
+			.num_parents = ARRAY_SIZE(gcc_parent_data_15),
+			.ops = &clk_regmap_mux_closest_ops,
+		},
+	},
+};
+
+static struct clk_regmap_mux gcc_ufs_phy_rx_symbol_1_clk_src = {
+	.reg = 0x830d0,
+	.shift = 0,
+	.width = 2,
+	.parent_map = gcc_parent_map_16,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_rx_symbol_1_clk_src",
+			.parent_data = gcc_parent_data_16,
+			.num_parents = ARRAY_SIZE(gcc_parent_data_16),
+			.ops = &clk_regmap_mux_closest_ops,
+		},
+	},
+};
+
+static struct clk_regmap_mux gcc_ufs_phy_tx_symbol_0_clk_src = {
+	.reg = 0x83050,
+	.shift = 0,
+	.width = 2,
+	.parent_map = gcc_parent_map_17,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_tx_symbol_0_clk_src",
+			.parent_data = gcc_parent_data_17,
+			.num_parents = ARRAY_SIZE(gcc_parent_data_17),
+			.ops = &clk_regmap_mux_closest_ops,
+		},
+	},
+};
+
+static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src = {
+	.reg = 0x1b068,
+	.shift = 0,
+	.width = 2,
+	.parent_map = gcc_parent_map_18,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb3_prim_phy_pipe_clk_src",
+			.parent_data = gcc_parent_data_18,
+			.num_parents = ARRAY_SIZE(gcc_parent_data_18),
+			.ops = &clk_regmap_mux_closest_ops,
+		},
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_emac0_phy_aux_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_emac0_phy_aux_clk_src = {
+	.cmd_rcgr = 0xb6028,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_emac0_phy_aux_clk_src",
+		.parent_data = gcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_emac0_ptp_clk_src[] = {
+	F(125000000, P_GCC_GPLL7_OUT_MAIN, 8, 0, 0),
+	F(230400000, P_GCC_GPLL4_OUT_MAIN, 3.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_emac0_ptp_clk_src = {
+	.cmd_rcgr = 0xb6060,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_6,
+	.freq_tbl = ftbl_gcc_emac0_ptp_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_emac0_ptp_clk_src",
+		.parent_data = gcc_parent_data_6,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_6),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_emac0_rgmii_clk_src[] = {
+	F(5000000, P_GCC_GPLL0_OUT_EVEN, 10, 1, 6),
+	F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0),
+	F(125000000, P_GCC_GPLL7_OUT_MAIN, 8, 0, 0),
+	F(250000000, P_GCC_GPLL7_OUT_MAIN, 4, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_emac0_rgmii_clk_src = {
+	.cmd_rcgr = 0xb6048,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_7,
+	.freq_tbl = ftbl_gcc_emac0_rgmii_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_emac0_rgmii_clk_src",
+		.parent_data = gcc_parent_data_7,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_7),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = {
+	F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+	F(200000000, P_GCC_GPLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_gp1_clk_src = {
+	.cmd_rcgr = 0x70004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_gp1_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_gp1_clk_src",
+		.parent_data = gcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_gp2_clk_src = {
+	.cmd_rcgr = 0x71004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_gp1_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_gp2_clk_src",
+		.parent_data = gcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_gp3_clk_src = {
+	.cmd_rcgr = 0x62004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_gp1_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_gp3_clk_src",
+		.parent_data = gcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_gp4_clk_src = {
+	.cmd_rcgr = 0x1e004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_gp1_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_gp4_clk_src",
+		.parent_data = gcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_gp5_clk_src = {
+	.cmd_rcgr = 0x1f004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_gp1_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_gp5_clk_src",
+		.parent_data = gcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_pcie_0_aux_clk_src = {
+	.cmd_rcgr = 0xa9078,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_0_aux_clk_src",
+		.parent_data = gcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_pcie_0_phy_rchng_clk_src[] = {
+	F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pcie_0_phy_rchng_clk_src = {
+	.cmd_rcgr = 0xa9054,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_0_phy_rchng_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_pcie_1_aux_clk_src = {
+	.cmd_rcgr = 0x77078,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_1_aux_clk_src",
+		.parent_data = gcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_pcie_1_phy_rchng_clk_src = {
+	.cmd_rcgr = 0x77054,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_1_phy_rchng_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = {
+	F(60000000, P_GCC_GPLL0_OUT_MAIN, 10, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pdm2_clk_src = {
+	.cmd_rcgr = 0x3f010,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pdm2_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pdm2_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
+	F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625),
+	F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625),
+	F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75),
+	F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25),
+	F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75),
+	F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15),
+	F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25),
+	F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0),
+	{ }
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s0_clk_src",
+	.parent_data = gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
+	.cmd_rcgr = 0x23154,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s1_clk_src",
+	.parent_data = gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
+	.cmd_rcgr = 0x23288,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s2_clk_src[] = {
+	F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625),
+	F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625),
+	F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75),
+	F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25),
+	F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75),
+	F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15),
+	F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25),
+	F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+	{ }
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s2_clk_src",
+	.parent_data = gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
+	.cmd_rcgr = 0x233bc,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s3_clk_src",
+	.parent_data = gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
+	.cmd_rcgr = 0x234f0,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s4_clk_src",
+	.parent_data = gcc_parent_data_4,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_4),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
+	.cmd_rcgr = 0x23624,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_4,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s5_clk_src",
+	.parent_data = gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
+	.cmd_rcgr = 0x23758,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s6_clk_src",
+	.parent_data = gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
+	.cmd_rcgr = 0x2388c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s7_clk_src",
+	.parent_data = gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
+	.cmd_rcgr = 0x239c0,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s0_clk_src",
+	.parent_data = gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
+	.cmd_rcgr = 0x24154,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s1_clk_src",
+	.parent_data = gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
+	.cmd_rcgr = 0x24288,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s2_clk_src",
+	.parent_data = gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
+	.cmd_rcgr = 0x243bc,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s3_clk_src",
+	.parent_data = gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
+	.cmd_rcgr = 0x244f0,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s4_clk_src",
+	.parent_data = gcc_parent_data_4,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_4),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
+	.cmd_rcgr = 0x24624,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_4,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s5_clk_src",
+	.parent_data = gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
+	.cmd_rcgr = 0x24758,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s6_clk_src",
+	.parent_data = gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
+	.cmd_rcgr = 0x2488c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s7_clk_src",
+	.parent_data = gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {
+	.cmd_rcgr = 0x249c0,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap0_s2_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap3_s0_clk_src[] = {
+	F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625),
+	F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625),
+	F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75),
+	F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25),
+	F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75),
+	F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0),
+	F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15),
+	F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25),
+	F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+	F(403200000, P_GCC_GPLL4_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_init_data gcc_qupv3_wrap3_s0_clk_src_init = {
+	.name = "gcc_qupv3_wrap3_s0_clk_src",
+	.parent_data = gcc_parent_data_3,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_3),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap3_s0_clk_src = {
+	.cmd_rcgr = 0xc4158,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_3,
+	.freq_tbl = ftbl_gcc_qupv3_wrap3_s0_clk_src,
+	.clkr.hw.init = &gcc_qupv3_wrap3_s0_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk_src[] = {
+	F(144000, P_BI_TCXO, 16, 3, 25),
+	F(400000, P_BI_TCXO, 12, 1, 4),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(20000000, P_GCC_GPLL0_OUT_EVEN, 5, 1, 3),
+	F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0),
+	F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0),
+	F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0),
+	F(192000000, P_GCC_GPLL9_OUT_MAIN, 4, 0, 0),
+	F(384000000, P_GCC_GPLL9_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_sdcc1_apps_clk_src = {
+	.cmd_rcgr = 0x20014,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_12,
+	.freq_tbl = ftbl_gcc_sdcc1_apps_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_sdcc1_apps_clk_src",
+		.parent_data = gcc_parent_data_12,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_12),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_floor_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = {
+	F(150000000, P_GCC_GPLL0_OUT_MAIN, 4, 0, 0),
+	F(300000000, P_GCC_GPLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = {
+	.cmd_rcgr = 0x2002c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_13,
+	.freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_sdcc1_ice_core_clk_src",
+		.parent_data = gcc_parent_data_13,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_13),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_floor_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = {
+	F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0),
+	F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0),
+	F(150000000, P_GCC_GPLL0_OUT_MAIN, 4, 0, 0),
+	F(300000000, P_GCC_GPLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = {
+	.cmd_rcgr = 0x8302c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_ufs_phy_axi_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+	F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0),
+	F(201600000, P_GCC_GPLL4_OUT_MAIN, 4, 0, 0),
+	F(403200000, P_GCC_GPLL4_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = {
+	.cmd_rcgr = 0x83074,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_14,
+	.freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_ufs_phy_ice_core_clk_src",
+		.parent_data = gcc_parent_data_14,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_14),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = {
+	.cmd_rcgr = 0x830a8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_5,
+	.freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_ufs_phy_phy_aux_clk_src",
+		.parent_data = gcc_parent_data_5,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_5),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_unipro_core_clk_src[] = {
+	F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0),
+	F(150000000, P_GCC_GPLL0_OUT_MAIN, 4, 0, 0),
+	F(300000000, P_GCC_GPLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = {
+	.cmd_rcgr = 0x8308c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_ufs_phy_unipro_core_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_ufs_phy_unipro_core_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_usb20_master_clk_src[] = {
+	F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_usb20_master_clk_src = {
+	.cmd_rcgr = 0x1c028,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_usb20_master_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb20_master_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_usb20_mock_utmi_clk_src = {
+	.cmd_rcgr = 0x1c040,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb20_mock_utmi_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
+	F(133333333, P_GCC_GPLL0_OUT_MAIN, 4.5, 0, 0),
+	F(200000000, P_GCC_GPLL0_OUT_MAIN, 3, 0, 0),
+	F(240000000, P_GCC_GPLL0_OUT_MAIN, 2.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_usb30_prim_master_clk_src = {
+	.cmd_rcgr = 0x1b028,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_usb30_prim_master_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb30_prim_master_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = {
+	.cmd_rcgr = 0x1b040,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb30_prim_mock_utmi_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = {
+	.cmd_rcgr = 0x1b06c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_emac0_phy_aux_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb3_prim_phy_aux_clk_src",
+		.parent_data = gcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_regmap_div gcc_pcie_0_pipe_div_clk_src = {
+	.reg = 0xa9070,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_0_pipe_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gcc_pcie_0_pipe_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div gcc_pcie_1_pipe_div_clk_src = {
+	.reg = 0x77070,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_1_pipe_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gcc_pcie_1_pipe_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div gcc_qupv3_wrap3_s0_div_clk_src = {
+	.reg = 0xc4288,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_qupv3_wrap3_s0_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gcc_qupv3_wrap3_s0_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div gcc_usb20_mock_utmi_postdiv_clk_src = {
+	.reg = 0x1c058,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb20_mock_utmi_postdiv_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gcc_usb20_mock_utmi_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div gcc_usb30_prim_mock_utmi_postdiv_clk_src = {
+	.reg = 0x1b058,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb30_prim_mock_utmi_postdiv_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gcc_usb30_prim_mock_utmi_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_branch gcc_aggre_noc_qupv3_axi_clk = {
+	.halt_reg = 0x8e200,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x8e200,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x4b000,
+		.enable_mask = BIT(28),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_aggre_noc_qupv3_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_aggre_ufs_phy_axi_clk = {
+	.halt_reg = 0x830d4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x830d4,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x830d4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_aggre_ufs_phy_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_ufs_phy_axi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_aggre_usb2_prim_axi_clk = {
+	.halt_reg = 0x1c05c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x1c05c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1c05c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_aggre_usb2_prim_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb20_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_aggre_usb3_prim_axi_clk = {
+	.halt_reg = 0x1b084,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x1b084,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1b084,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_aggre_usb3_prim_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb30_prim_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ahb2phy0_clk = {
+	.halt_reg = 0x76004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x76004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x76004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ahb2phy0_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ahb2phy2_clk = {
+	.halt_reg = 0x76008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x76008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x76008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ahb2phy2_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ahb2phy3_clk = {
+	.halt_reg = 0x7600c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x7600c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x7600c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ahb2phy3_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+	.halt_reg = 0x44004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x44004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x4b000,
+		.enable_mask = BIT(10),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_boot_rom_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_camera_hf_axi_clk = {
+	.halt_reg = 0x32010,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x32010,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x32010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_camera_hf_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_camera_sf_axi_clk = {
+	.halt_reg = 0x32018,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x32018,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x32018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_camera_sf_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_camera_throttle_xo_clk = {
+	.halt_reg = 0x32024,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x32024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_camera_throttle_xo_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_cfg_noc_usb2_prim_axi_clk = {
+	.halt_reg = 0x1c060,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x1c060,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1c060,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_cfg_noc_usb2_prim_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb20_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = {
+	.halt_reg = 0x1b088,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x1b088,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1b088,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_cfg_noc_usb3_prim_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb30_prim_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ddrss_gpu_axi_clk = {
+	.halt_reg = 0x7d164,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x7d164,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x7d164,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ddrss_gpu_axi_clk",
+			.ops = &clk_branch2_aon_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_disp_hf_axi_clk = {
+	.halt_reg = 0x33010,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x33010,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x33010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_disp_hf_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_edp_ref_clkref_en = {
+	.halt_reg = 0x97448,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x97448,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_edp_ref_clkref_en",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_emac0_axi_clk = {
+	.halt_reg = 0xb6018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0xb6018,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0xb6018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_emac0_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_emac0_phy_aux_clk = {
+	.halt_reg = 0xb6024,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb6024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_emac0_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_emac0_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_emac0_ptp_clk = {
+	.halt_reg = 0xb6040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb6040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_emac0_ptp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_emac0_ptp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_emac0_rgmii_clk = {
+	.halt_reg = 0xb6044,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb6044,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_emac0_rgmii_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_emac0_rgmii_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_emac0_slv_ahb_clk = {
+	.halt_reg = 0xb6020,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0xb6020,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0xb6020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_emac0_slv_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gp1_clk = {
+	.halt_reg = 0x70000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x70000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gp1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_gp1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gp2_clk = {
+	.halt_reg = 0x71000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x71000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gp2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_gp2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gp3_clk = {
+	.halt_reg = 0x62000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x62000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gp3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_gp3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gp4_clk = {
+	.halt_reg = 0x1e000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1e000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gp4_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_gp4_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gp5_clk = {
+	.halt_reg = 0x1f000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1f000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gp5_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_gp5_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gpu_gpll0_clk_src = {
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x4b000,
+		.enable_mask = BIT(15),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_gpll0_clk_src",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_gpll0.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gpu_gpll0_div_clk_src = {
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x4b000,
+		.enable_mask = BIT(16),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_gpll0_div_clk_src",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_gpll0_out_even.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gpu_memnoc_gfx_center_pipeline_clk = {
+	.halt_reg = 0x7d160,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x7d160,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x7d160,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_memnoc_gfx_center_pipeline_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gpu_memnoc_gfx_clk = {
+	.halt_reg = 0x7d010,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x7d010,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x7d010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_memnoc_gfx_clk",
+			.ops = &clk_branch2_aon_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gpu_snoc_dvm_gfx_clk = {
+	.halt_reg = 0x7d01c,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x7d01c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_snoc_dvm_gfx_clk",
+			.ops = &clk_branch2_aon_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gpu_tcu_throttle_ahb_clk = {
+	.halt_reg = 0x7d008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x7d008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x7d008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_tcu_throttle_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gpu_tcu_throttle_clk = {
+	.halt_reg = 0x7d014,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x7d014,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x7d014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_tcu_throttle_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_aux_clk = {
+	.halt_reg = 0xa9038,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b010,
+		.enable_mask = BIT(16),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_0_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_cfg_ahb_clk = {
+	.halt_reg = 0xa902c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0xa902c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x4b010,
+		.enable_mask = BIT(12),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_cfg_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
+	.halt_reg = 0xa9024,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b010,
+		.enable_mask = BIT(11),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_mstr_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_phy_aux_clk = {
+	.halt_reg = 0xa9030,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b010,
+		.enable_mask = BIT(13),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_0_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_phy_rchng_clk = {
+	.halt_reg = 0xa9050,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b010,
+		.enable_mask = BIT(15),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_phy_rchng_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_0_phy_rchng_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_pipe_clk = {
+	.halt_reg = 0xa9040,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x4b010,
+		.enable_mask = BIT(14),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_pipe_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_0_pipe_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_pipediv2_clk = {
+	.halt_reg = 0xa9048,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x4b018,
+		.enable_mask = BIT(22),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_pipediv2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_0_pipe_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_slv_axi_clk = {
+	.halt_reg = 0xa901c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b010,
+		.enable_mask = BIT(10),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_slv_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_slv_q2a_axi_clk = {
+	.halt_reg = 0xa9018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b018,
+		.enable_mask = BIT(12),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_slv_q2a_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_1_aux_clk = {
+	.halt_reg = 0x77038,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b000,
+		.enable_mask = BIT(31),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_1_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_1_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_1_cfg_ahb_clk = {
+	.halt_reg = 0x7702c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x7702c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(2),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_1_cfg_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_1_mstr_axi_clk = {
+	.halt_reg = 0x77024,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(1),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_1_mstr_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_1_phy_aux_clk = {
+	.halt_reg = 0x77030,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(3),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_1_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_1_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_1_phy_rchng_clk = {
+	.halt_reg = 0x77050,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b000,
+		.enable_mask = BIT(22),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_1_phy_rchng_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_1_phy_rchng_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_1_pipe_clk = {
+	.halt_reg = 0x77040,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(4),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_1_pipe_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_1_pipe_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_1_pipediv2_clk = {
+	.halt_reg = 0x77048,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x4b018,
+		.enable_mask = BIT(16),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_1_pipediv2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_1_pipe_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_1_slv_axi_clk = {
+	.halt_reg = 0x7701c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_1_slv_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_1_slv_q2a_axi_clk = {
+	.halt_reg = 0x77018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(5),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_1_slv_q2a_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_clkref_en = {
+	.halt_reg = 0x9746c,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x9746c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_clkref_en",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_throttle_cfg_clk = {
+	.halt_reg = 0xb2034,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b020,
+		.enable_mask = BIT(15),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_throttle_cfg_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+	.halt_reg = 0x3f00c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3f00c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pdm2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pdm2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pdm_ahb_clk = {
+	.halt_reg = 0x3f004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x3f004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x3f004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pdm_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pdm_xo4_clk = {
+	.halt_reg = 0x3f008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3f008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pdm_xo4_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = {
+	.halt_reg = 0x32008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x32008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x32008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_camera_nrt_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_camera_rt_ahb_clk = {
+	.halt_reg = 0x3200c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x3200c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x3200c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_camera_rt_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_disp_ahb_clk = {
+	.halt_reg = 0x33008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x33008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x33008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_disp_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_disp_rot_ahb_clk = {
+	.halt_reg = 0x3300c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x3300c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_disp_rot_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_video_cvp_ahb_clk = {
+	.halt_reg = 0x34008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x34008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x34008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_video_cvp_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = {
+	.halt_reg = 0x3400c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x3400c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x3400c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_video_vcodec_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_video_vcpu_ahb_clk = {
+	.halt_reg = 0x34010,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x34010,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x34010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_video_vcpu_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_core_2x_clk = {
+	.halt_reg = 0x23018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(9),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_core_2x_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_core_clk = {
+	.halt_reg = 0x2300c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(8),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_core_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s0_clk = {
+	.halt_reg = 0x2314c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(10),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_s0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap0_s0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s1_clk = {
+	.halt_reg = 0x23280,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(11),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_s1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap0_s1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s2_clk = {
+	.halt_reg = 0x233b4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(12),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_s2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap0_s2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s3_clk = {
+	.halt_reg = 0x234e8,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(13),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_s3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap0_s3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s4_clk = {
+	.halt_reg = 0x2361c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(14),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_s4_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap0_s4_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s5_clk = {
+	.halt_reg = 0x23750,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(15),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_s5_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap0_s5_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s6_clk = {
+	.halt_reg = 0x23884,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(16),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_s6_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap0_s6_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap0_s7_clk = {
+	.halt_reg = 0x239b8,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(17),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap0_s7_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap0_s7_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = {
+	.halt_reg = 0x24018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(18),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_core_2x_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_core_clk = {
+	.halt_reg = 0x2400c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(19),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_core_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s0_clk = {
+	.halt_reg = 0x2414c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(22),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_s0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_s0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s1_clk = {
+	.halt_reg = 0x24280,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(23),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_s1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_s1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s2_clk = {
+	.halt_reg = 0x243b4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(24),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_s2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_s2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s3_clk = {
+	.halt_reg = 0x244e8,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(25),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_s3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_s3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s4_clk = {
+	.halt_reg = 0x2461c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(26),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_s4_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_s4_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s5_clk = {
+	.halt_reg = 0x24750,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(27),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_s5_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_s5_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s6_clk = {
+	.halt_reg = 0x24884,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b018,
+		.enable_mask = BIT(27),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_s6_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_s6_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s7_clk = {
+	.halt_reg = 0x249b8,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b018,
+		.enable_mask = BIT(28),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_s7_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_s7_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap3_core_2x_clk = {
+	.halt_reg = 0xc4018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b000,
+		.enable_mask = BIT(24),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap3_core_2x_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap3_core_clk = {
+	.halt_reg = 0xc400c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b000,
+		.enable_mask = BIT(23),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap3_core_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap3_qspi_clk = {
+	.halt_reg = 0xc4284,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b000,
+		.enable_mask = BIT(26),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap3_qspi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap3_s0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap3_s0_clk = {
+	.halt_reg = 0xc4150,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x4b000,
+		.enable_mask = BIT(25),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap3_s0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap3_s0_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_0_m_ahb_clk = {
+	.halt_reg = 0x23004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x23004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(6),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_0_m_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_0_s_ahb_clk = {
+	.halt_reg = 0x23008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x23008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(7),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_0_s_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_1_m_ahb_clk = {
+	.halt_reg = 0x24004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x24004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(20),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_1_m_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = {
+	.halt_reg = 0x24008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x24008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x4b008,
+		.enable_mask = BIT(21),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_1_s_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_3_m_ahb_clk = {
+	.halt_reg = 0xc4004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0xc4004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x4b000,
+		.enable_mask = BIT(27),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_3_m_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_3_s_ahb_clk = {
+	.halt_reg = 0xc4008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0xc4008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x4b000,
+		.enable_mask = BIT(20),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_3_s_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+	.halt_reg = 0x2000c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2000c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_sdcc1_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+	.halt_reg = 0x20004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x20004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_sdcc1_apps_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_sdcc1_apps_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_sdcc1_ice_core_clk = {
+	.halt_reg = 0x20044,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x20044,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x20044,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_sdcc1_ice_core_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_sdcc1_ice_core_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_sgmi_clkref_en = {
+	.halt_reg = 0x97034,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x97034,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_sgmi_clkref_en",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_ahb_clk = {
+	.halt_reg = 0x83020,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x83020,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x83020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_axi_clk = {
+	.halt_reg = 0x83018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x83018,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x83018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_ufs_phy_axi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_ice_core_clk = {
+	.halt_reg = 0x8306c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x8306c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x8306c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_ice_core_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_ufs_phy_ice_core_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_phy_aux_clk = {
+	.halt_reg = 0x830a4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x830a4,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x830a4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_ufs_phy_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = {
+	.halt_reg = 0x83028,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x83028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_rx_symbol_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_ufs_phy_rx_symbol_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = {
+	.halt_reg = 0x830c0,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x830c0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_rx_symbol_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_ufs_phy_rx_symbol_1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = {
+	.halt_reg = 0x83024,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x83024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_tx_symbol_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_ufs_phy_tx_symbol_0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ufs_phy_unipro_core_clk = {
+	.halt_reg = 0x83064,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x83064,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x83064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_unipro_core_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_ufs_phy_unipro_core_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb20_master_clk = {
+	.halt_reg = 0x1c018,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1c018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb20_master_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb20_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb20_mock_utmi_clk = {
+	.halt_reg = 0x1c024,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1c024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb20_mock_utmi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb20_mock_utmi_postdiv_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb20_sleep_clk = {
+	.halt_reg = 0x1c020,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1c020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb20_sleep_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb30_prim_master_clk = {
+	.halt_reg = 0x1b018,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1b018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb30_prim_master_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb30_prim_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb30_prim_mock_utmi_clk = {
+	.halt_reg = 0x1b024,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1b024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb30_prim_mock_utmi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb30_prim_sleep_clk = {
+	.halt_reg = 0x1b020,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1b020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb30_prim_sleep_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb3_prim_phy_aux_clk = {
+	.halt_reg = 0x1b05c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1b05c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb3_prim_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb3_prim_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = {
+	.halt_reg = 0x1b060,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1b060,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb3_prim_phy_com_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb3_prim_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb3_prim_phy_pipe_clk = {
+	.halt_reg = 0x1b064,
+	.halt_check = BRANCH_HALT_DELAY,
+	.hwcg_reg = 0x1b064,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1b064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb3_prim_phy_pipe_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb3_prim_phy_pipe_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb_clkref_en = {
+	.halt_reg = 0x97468,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x97468,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb_clkref_en",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_video_axi0_clk = {
+	.halt_reg = 0x34014,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x34014,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x34014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_video_axi0_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_video_axi1_clk = {
+	.halt_reg = 0x3401c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x3401c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x3401c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_video_axi1_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc gcc_emac0_gdsc = {
+	.gdscr = 0xb6004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "gcc_emac0_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc gcc_pcie_0_gdsc = {
+	.gdscr = 0xa9004,
+	.collapse_ctrl = 0x4b104,
+	.collapse_mask = BIT(0),
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "gcc_pcie_0_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE | RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
+};
+
+static struct gdsc gcc_pcie_1_gdsc = {
+	.gdscr = 0x77004,
+	.collapse_ctrl = 0x4b104,
+	.collapse_mask = BIT(1),
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "gcc_pcie_1_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE | RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
+};
+
+static struct gdsc gcc_ufs_phy_gdsc = {
+	.gdscr = 0x83004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "gcc_ufs_phy_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
+};
+
+static struct gdsc gcc_usb20_prim_gdsc = {
+	.gdscr = 0x1c004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "gcc_usb20_prim_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
+};
+
+static struct gdsc gcc_usb30_prim_gdsc = {
+	.gdscr = 0x1b004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "gcc_usb30_prim_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
+};
+
+static struct clk_regmap *gcc_qcs8300_clocks[] = {
+	[GCC_AGGRE_NOC_QUPV3_AXI_CLK] = &gcc_aggre_noc_qupv3_axi_clk.clkr,
+	[GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr,
+	[GCC_AGGRE_USB2_PRIM_AXI_CLK] = &gcc_aggre_usb2_prim_axi_clk.clkr,
+	[GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr,
+	[GCC_AHB2PHY0_CLK] = &gcc_ahb2phy0_clk.clkr,
+	[GCC_AHB2PHY2_CLK] = &gcc_ahb2phy2_clk.clkr,
+	[GCC_AHB2PHY3_CLK] = &gcc_ahb2phy3_clk.clkr,
+	[GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
+	[GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr,
+	[GCC_CAMERA_SF_AXI_CLK] = &gcc_camera_sf_axi_clk.clkr,
+	[GCC_CAMERA_THROTTLE_XO_CLK] = &gcc_camera_throttle_xo_clk.clkr,
+	[GCC_CFG_NOC_USB2_PRIM_AXI_CLK] = &gcc_cfg_noc_usb2_prim_axi_clk.clkr,
+	[GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr,
+	[GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr,
+	[GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr,
+	[GCC_EDP_REF_CLKREF_EN] = &gcc_edp_ref_clkref_en.clkr,
+	[GCC_EMAC0_AXI_CLK] = &gcc_emac0_axi_clk.clkr,
+	[GCC_EMAC0_PHY_AUX_CLK] = &gcc_emac0_phy_aux_clk.clkr,
+	[GCC_EMAC0_PHY_AUX_CLK_SRC] = &gcc_emac0_phy_aux_clk_src.clkr,
+	[GCC_EMAC0_PTP_CLK] = &gcc_emac0_ptp_clk.clkr,
+	[GCC_EMAC0_PTP_CLK_SRC] = &gcc_emac0_ptp_clk_src.clkr,
+	[GCC_EMAC0_RGMII_CLK] = &gcc_emac0_rgmii_clk.clkr,
+	[GCC_EMAC0_RGMII_CLK_SRC] = &gcc_emac0_rgmii_clk_src.clkr,
+	[GCC_EMAC0_SLV_AHB_CLK] = &gcc_emac0_slv_ahb_clk.clkr,
+	[GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+	[GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr,
+	[GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+	[GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr,
+	[GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+	[GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr,
+	[GCC_GP4_CLK] = &gcc_gp4_clk.clkr,
+	[GCC_GP4_CLK_SRC] = &gcc_gp4_clk_src.clkr,
+	[GCC_GP5_CLK] = &gcc_gp5_clk.clkr,
+	[GCC_GP5_CLK_SRC] = &gcc_gp5_clk_src.clkr,
+	[GCC_GPLL0] = &gcc_gpll0.clkr,
+	[GCC_GPLL0_OUT_EVEN] = &gcc_gpll0_out_even.clkr,
+	[GCC_GPLL1] = &gcc_gpll1.clkr,
+	[GCC_GPLL4] = &gcc_gpll4.clkr,
+	[GCC_GPLL7] = &gcc_gpll7.clkr,
+	[GCC_GPLL9] = &gcc_gpll9.clkr,
+	[GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr,
+	[GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr,
+	[GCC_GPU_MEMNOC_GFX_CENTER_PIPELINE_CLK] = &gcc_gpu_memnoc_gfx_center_pipeline_clk.clkr,
+	[GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr,
+	[GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr,
+	[GCC_GPU_TCU_THROTTLE_AHB_CLK] = &gcc_gpu_tcu_throttle_ahb_clk.clkr,
+	[GCC_GPU_TCU_THROTTLE_CLK] = &gcc_gpu_tcu_throttle_clk.clkr,
+	[GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr,
+	[GCC_PCIE_0_AUX_CLK_SRC] = &gcc_pcie_0_aux_clk_src.clkr,
+	[GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr,
+	[GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr,
+	[GCC_PCIE_0_PHY_AUX_CLK] = &gcc_pcie_0_phy_aux_clk.clkr,
+	[GCC_PCIE_0_PHY_AUX_CLK_SRC] = &gcc_pcie_0_phy_aux_clk_src.clkr,
+	[GCC_PCIE_0_PHY_RCHNG_CLK] = &gcc_pcie_0_phy_rchng_clk.clkr,
+	[GCC_PCIE_0_PHY_RCHNG_CLK_SRC] = &gcc_pcie_0_phy_rchng_clk_src.clkr,
+	[GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr,
+	[GCC_PCIE_0_PIPE_CLK_SRC] = &gcc_pcie_0_pipe_clk_src.clkr,
+	[GCC_PCIE_0_PIPE_DIV_CLK_SRC] = &gcc_pcie_0_pipe_div_clk_src.clkr,
+	[GCC_PCIE_0_PIPEDIV2_CLK] = &gcc_pcie_0_pipediv2_clk.clkr,
+	[GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr,
+	[GCC_PCIE_0_SLV_Q2A_AXI_CLK] = &gcc_pcie_0_slv_q2a_axi_clk.clkr,
+	[GCC_PCIE_1_AUX_CLK] = &gcc_pcie_1_aux_clk.clkr,
+	[GCC_PCIE_1_AUX_CLK_SRC] = &gcc_pcie_1_aux_clk_src.clkr,
+	[GCC_PCIE_1_CFG_AHB_CLK] = &gcc_pcie_1_cfg_ahb_clk.clkr,
+	[GCC_PCIE_1_MSTR_AXI_CLK] = &gcc_pcie_1_mstr_axi_clk.clkr,
+	[GCC_PCIE_1_PHY_AUX_CLK] = &gcc_pcie_1_phy_aux_clk.clkr,
+	[GCC_PCIE_1_PHY_AUX_CLK_SRC] = &gcc_pcie_1_phy_aux_clk_src.clkr,
+	[GCC_PCIE_1_PHY_RCHNG_CLK] = &gcc_pcie_1_phy_rchng_clk.clkr,
+	[GCC_PCIE_1_PHY_RCHNG_CLK_SRC] = &gcc_pcie_1_phy_rchng_clk_src.clkr,
+	[GCC_PCIE_1_PIPE_CLK] = &gcc_pcie_1_pipe_clk.clkr,
+	[GCC_PCIE_1_PIPE_CLK_SRC] = &gcc_pcie_1_pipe_clk_src.clkr,
+	[GCC_PCIE_1_PIPE_DIV_CLK_SRC] = &gcc_pcie_1_pipe_div_clk_src.clkr,
+	[GCC_PCIE_1_PIPEDIV2_CLK] = &gcc_pcie_1_pipediv2_clk.clkr,
+	[GCC_PCIE_1_SLV_AXI_CLK] = &gcc_pcie_1_slv_axi_clk.clkr,
+	[GCC_PCIE_1_SLV_Q2A_AXI_CLK] = &gcc_pcie_1_slv_q2a_axi_clk.clkr,
+	[GCC_PCIE_CLKREF_EN] = &gcc_pcie_clkref_en.clkr,
+	[GCC_PCIE_THROTTLE_CFG_CLK] = &gcc_pcie_throttle_cfg_clk.clkr,
+	[GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
+	[GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr,
+	[GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
+	[GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr,
+	[GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr,
+	[GCC_QMIP_CAMERA_RT_AHB_CLK] = &gcc_qmip_camera_rt_ahb_clk.clkr,
+	[GCC_QMIP_DISP_AHB_CLK] = &gcc_qmip_disp_ahb_clk.clkr,
+	[GCC_QMIP_DISP_ROT_AHB_CLK] = &gcc_qmip_disp_rot_ahb_clk.clkr,
+	[GCC_QMIP_VIDEO_CVP_AHB_CLK] = &gcc_qmip_video_cvp_ahb_clk.clkr,
+	[GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr,
+	[GCC_QMIP_VIDEO_VCPU_AHB_CLK] = &gcc_qmip_video_vcpu_ahb_clk.clkr,
+	[GCC_QUPV3_WRAP0_CORE_2X_CLK] = &gcc_qupv3_wrap0_core_2x_clk.clkr,
+	[GCC_QUPV3_WRAP0_CORE_CLK] = &gcc_qupv3_wrap0_core_clk.clkr,
+	[GCC_QUPV3_WRAP0_S0_CLK] = &gcc_qupv3_wrap0_s0_clk.clkr,
+	[GCC_QUPV3_WRAP0_S0_CLK_SRC] = &gcc_qupv3_wrap0_s0_clk_src.clkr,
+	[GCC_QUPV3_WRAP0_S1_CLK] = &gcc_qupv3_wrap0_s1_clk.clkr,
+	[GCC_QUPV3_WRAP0_S1_CLK_SRC] = &gcc_qupv3_wrap0_s1_clk_src.clkr,
+	[GCC_QUPV3_WRAP0_S2_CLK] = &gcc_qupv3_wrap0_s2_clk.clkr,
+	[GCC_QUPV3_WRAP0_S2_CLK_SRC] = &gcc_qupv3_wrap0_s2_clk_src.clkr,
+	[GCC_QUPV3_WRAP0_S3_CLK] = &gcc_qupv3_wrap0_s3_clk.clkr,
+	[GCC_QUPV3_WRAP0_S3_CLK_SRC] = &gcc_qupv3_wrap0_s3_clk_src.clkr,
+	[GCC_QUPV3_WRAP0_S4_CLK] = &gcc_qupv3_wrap0_s4_clk.clkr,
+	[GCC_QUPV3_WRAP0_S4_CLK_SRC] = &gcc_qupv3_wrap0_s4_clk_src.clkr,
+	[GCC_QUPV3_WRAP0_S5_CLK] = &gcc_qupv3_wrap0_s5_clk.clkr,
+	[GCC_QUPV3_WRAP0_S5_CLK_SRC] = &gcc_qupv3_wrap0_s5_clk_src.clkr,
+	[GCC_QUPV3_WRAP0_S6_CLK] = &gcc_qupv3_wrap0_s6_clk.clkr,
+	[GCC_QUPV3_WRAP0_S6_CLK_SRC] = &gcc_qupv3_wrap0_s6_clk_src.clkr,
+	[GCC_QUPV3_WRAP0_S7_CLK] = &gcc_qupv3_wrap0_s7_clk.clkr,
+	[GCC_QUPV3_WRAP0_S7_CLK_SRC] = &gcc_qupv3_wrap0_s7_clk_src.clkr,
+	[GCC_QUPV3_WRAP1_CORE_2X_CLK] = &gcc_qupv3_wrap1_core_2x_clk.clkr,
+	[GCC_QUPV3_WRAP1_CORE_CLK] = &gcc_qupv3_wrap1_core_clk.clkr,
+	[GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr,
+	[GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr,
+	[GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr,
+	[GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr,
+	[GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr,
+	[GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr,
+	[GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr,
+	[GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr,
+	[GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr,
+	[GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr,
+	[GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr,
+	[GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr,
+	[GCC_QUPV3_WRAP1_S6_CLK] = &gcc_qupv3_wrap1_s6_clk.clkr,
+	[GCC_QUPV3_WRAP1_S6_CLK_SRC] = &gcc_qupv3_wrap1_s6_clk_src.clkr,
+	[GCC_QUPV3_WRAP1_S7_CLK] = &gcc_qupv3_wrap1_s7_clk.clkr,
+	[GCC_QUPV3_WRAP1_S7_CLK_SRC] = &gcc_qupv3_wrap1_s7_clk_src.clkr,
+	[GCC_QUPV3_WRAP3_CORE_2X_CLK] = &gcc_qupv3_wrap3_core_2x_clk.clkr,
+	[GCC_QUPV3_WRAP3_CORE_CLK] = &gcc_qupv3_wrap3_core_clk.clkr,
+	[GCC_QUPV3_WRAP3_QSPI_CLK] = &gcc_qupv3_wrap3_qspi_clk.clkr,
+	[GCC_QUPV3_WRAP3_S0_CLK] = &gcc_qupv3_wrap3_s0_clk.clkr,
+	[GCC_QUPV3_WRAP3_S0_CLK_SRC] = &gcc_qupv3_wrap3_s0_clk_src.clkr,
+	[GCC_QUPV3_WRAP3_S0_DIV_CLK_SRC] = &gcc_qupv3_wrap3_s0_div_clk_src.clkr,
+	[GCC_QUPV3_WRAP_0_M_AHB_CLK] = &gcc_qupv3_wrap_0_m_ahb_clk.clkr,
+	[GCC_QUPV3_WRAP_0_S_AHB_CLK] = &gcc_qupv3_wrap_0_s_ahb_clk.clkr,
+	[GCC_QUPV3_WRAP_1_M_AHB_CLK] = &gcc_qupv3_wrap_1_m_ahb_clk.clkr,
+	[GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr,
+	[GCC_QUPV3_WRAP_3_M_AHB_CLK] = &gcc_qupv3_wrap_3_m_ahb_clk.clkr,
+	[GCC_QUPV3_WRAP_3_S_AHB_CLK] = &gcc_qupv3_wrap_3_s_ahb_clk.clkr,
+	[GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+	[GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+	[GCC_SDCC1_APPS_CLK_SRC] = &gcc_sdcc1_apps_clk_src.clkr,
+	[GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr,
+	[GCC_SDCC1_ICE_CORE_CLK_SRC] = &gcc_sdcc1_ice_core_clk_src.clkr,
+	[GCC_SGMI_CLKREF_EN] = &gcc_sgmi_clkref_en.clkr,
+	[GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr,
+	[GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr,
+	[GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr,
+	[GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr,
+	[GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr,
+	[GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr,
+	[GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr,
+	[GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr,
+	[GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_rx_symbol_0_clk_src.clkr,
+	[GCC_UFS_PHY_RX_SYMBOL_1_CLK] = &gcc_ufs_phy_rx_symbol_1_clk.clkr,
+	[GCC_UFS_PHY_RX_SYMBOL_1_CLK_SRC] = &gcc_ufs_phy_rx_symbol_1_clk_src.clkr,
+	[GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr,
+	[GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_tx_symbol_0_clk_src.clkr,
+	[GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr,
+	[GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = &gcc_ufs_phy_unipro_core_clk_src.clkr,
+	[GCC_USB20_MASTER_CLK] = &gcc_usb20_master_clk.clkr,
+	[GCC_USB20_MASTER_CLK_SRC] = &gcc_usb20_master_clk_src.clkr,
+	[GCC_USB20_MOCK_UTMI_CLK] = &gcc_usb20_mock_utmi_clk.clkr,
+	[GCC_USB20_MOCK_UTMI_CLK_SRC] = &gcc_usb20_mock_utmi_clk_src.clkr,
+	[GCC_USB20_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb20_mock_utmi_postdiv_clk_src.clkr,
+	[GCC_USB20_SLEEP_CLK] = &gcc_usb20_sleep_clk.clkr,
+	[GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr,
+	[GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr,
+	[GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr,
+	[GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = &gcc_usb30_prim_mock_utmi_clk_src.clkr,
+	[GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr,
+	[GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr,
+	[GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr,
+	[GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr,
+	[GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr,
+	[GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr,
+	[GCC_USB3_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb3_prim_phy_pipe_clk_src.clkr,
+	[GCC_USB_CLKREF_EN] = &gcc_usb_clkref_en.clkr,
+	[GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr,
+	[GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr,
+};
+
+static struct gdsc *gcc_qcs8300_gdscs[] = {
+	[GCC_EMAC0_GDSC] = &gcc_emac0_gdsc,
+	[GCC_PCIE_0_GDSC] = &gcc_pcie_0_gdsc,
+	[GCC_PCIE_1_GDSC] = &gcc_pcie_1_gdsc,
+	[GCC_UFS_PHY_GDSC] = &gcc_ufs_phy_gdsc,
+	[GCC_USB20_PRIM_GDSC] = &gcc_usb20_prim_gdsc,
+	[GCC_USB30_PRIM_GDSC] = &gcc_usb30_prim_gdsc,
+};
+
+static const struct qcom_reset_map gcc_qcs8300_resets[] = {
+	[GCC_EMAC0_BCR] = { 0xb6000 },
+	[GCC_PCIE_0_BCR] = { 0xa9000 },
+	[GCC_PCIE_0_LINK_DOWN_BCR] = { 0xbf000 },
+	[GCC_PCIE_0_NOCSR_COM_PHY_BCR] = { 0xbf008 },
+	[GCC_PCIE_0_PHY_BCR] = { 0xa9144 },
+	[GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR] = { 0xbf00c },
+	[GCC_PCIE_1_BCR] = { 0x77000 },
+	[GCC_PCIE_1_LINK_DOWN_BCR] = { 0xae084 },
+	[GCC_PCIE_1_NOCSR_COM_PHY_BCR] = { 0xae090 },
+	[GCC_PCIE_1_PHY_BCR] = { 0xae08c },
+	[GCC_PCIE_1_PHY_NOCSR_COM_PHY_BCR] = { 0xae094 },
+	[GCC_SDCC1_BCR] = { 0x20000 },
+	[GCC_UFS_PHY_BCR] = { 0x83000 },
+	[GCC_USB20_PRIM_BCR] = { 0x1c000 },
+	[GCC_USB2_PHY_PRIM_BCR] = { 0x5c01c },
+	[GCC_USB2_PHY_SEC_BCR] = { 0x5c020 },
+	[GCC_USB30_PRIM_BCR] = { 0x1b000 },
+	[GCC_USB3_DP_PHY_PRIM_BCR] = { 0x5c008 },
+	[GCC_USB3_PHY_PRIM_BCR] = { 0x5c000 },
+	[GCC_USB3_PHY_TERT_BCR] = { 0x5c024 },
+	[GCC_USB3_UNIPHY_MP0_BCR] = { 0x5c00c },
+	[GCC_USB3_UNIPHY_MP1_BCR] = { 0x5c010 },
+	[GCC_USB3PHY_PHY_PRIM_BCR] = { 0x5c004 },
+	[GCC_USB3UNIPHY_PHY_MP0_BCR] = { 0x5c014 },
+	[GCC_USB3UNIPHY_PHY_MP1_BCR] = { 0x5c018 },
+	[GCC_USB_PHY_CFG_AHB2PHY_BCR] = { 0x76000 },
+	[GCC_VIDEO_AXI0_CLK_ARES] = { 0x34014, 2 },
+	[GCC_VIDEO_AXI1_CLK_ARES] = { 0x3401c, 2 },
+	[GCC_VIDEO_BCR] = { 0x34000 },
+};
+
+static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap3_s0_clk_src),
+};
+
+static const struct regmap_config gcc_qcs8300_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x472cffc,
+	.fast_io = true,
+};
+
+static const struct qcom_cc_desc gcc_qcs8300_desc = {
+	.config = &gcc_qcs8300_regmap_config,
+	.clks = gcc_qcs8300_clocks,
+	.num_clks = ARRAY_SIZE(gcc_qcs8300_clocks),
+	.resets = gcc_qcs8300_resets,
+	.num_resets = ARRAY_SIZE(gcc_qcs8300_resets),
+	.gdscs = gcc_qcs8300_gdscs,
+	.num_gdscs = ARRAY_SIZE(gcc_qcs8300_gdscs),
+};
+
+static const struct of_device_id gcc_qcs8300_match_table[] = {
+	{ .compatible = "qcom,qcs8300-gcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, gcc_qcs8300_match_table);
+
+static int gcc_qcs8300_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+	int ret;
+
+	regmap = qcom_cc_map(pdev, &gcc_qcs8300_desc);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks,
+				       ARRAY_SIZE(gcc_dfs_clocks));
+	if (ret)
+		return ret;
+
+	/* Keep some clocks always enabled */
+	qcom_branch_set_clk_en(regmap, 0x32004); /* GCC_CAMERA_AHB_CLK */
+	qcom_branch_set_clk_en(regmap, 0x32020); /* GCC_CAMERA_XO_CLK */
+	qcom_branch_set_clk_en(regmap, 0x33004); /* GCC_DISP_AHB_CLK */
+	qcom_branch_set_clk_en(regmap, 0x33018); /* GCC_DISP_XO_CLK */
+	qcom_branch_set_clk_en(regmap, 0x7d004); /* GCC_GPU_CFG_AHB_CLK */
+	qcom_branch_set_clk_en(regmap, 0x34004); /* GCC_VIDEO_AHB_CLK */
+	qcom_branch_set_clk_en(regmap, 0x34024); /* GCC_VIDEO_XO_CLK */
+
+	/* FORCE_MEM_CORE_ON for ufs phy ice core clocks */
+	qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true);
+
+	return qcom_cc_really_probe(&pdev->dev, &gcc_qcs8300_desc, regmap);
+}
+
+static struct platform_driver gcc_qcs8300_driver = {
+	.probe = gcc_qcs8300_probe,
+	.driver = {
+		.name = "gcc-qcs8300",
+		.of_match_table = gcc_qcs8300_match_table,
+	},
+};
+
+static int __init gcc_qcs8300_init(void)
+{
+	return platform_driver_register(&gcc_qcs8300_driver);
+}
+subsys_initcall(gcc_qcs8300_init);
+
+static void __exit gcc_qcs8300_exit(void)
+{
+	platform_driver_unregister(&gcc_qcs8300_driver);
+}
+module_exit(gcc_qcs8300_exit);
+
+MODULE_DESCRIPTION("QTI GCC QCS8300 Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-qdu1000.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-qdu1000.c
@@ -2674,7 +2674,7 @@
 	if (ret)
 		return ret;
 
-	ret = qcom_cc_really_probe(pdev, &gcc_qdu1000_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &gcc_qdu1000_desc, regmap);
 	if (ret)
 		return dev_err_probe(&pdev->dev, ret, "Failed to register GCC clocks\n");
 
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sa8775p.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sa8775p.c
@@ -1,14 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022, 2024, Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2023, Linaro Limited
  */
 
-#include <linux/clk.h>
 #include <linux/clk-provider.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/mod_devicetable.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
@@ -1737,26 +1735,6 @@
 	},
 };
 
-static struct clk_branch gcc_aggre_ufs_phy_axi_hw_ctl_clk = {
-	.halt_reg = 0x830d4,
-	.halt_check = BRANCH_HALT_VOTED,
-	.hwcg_reg = 0x830d4,
-	.hwcg_bit = 1,
-	.clkr = {
-		.enable_reg = 0x830d4,
-		.enable_mask = BIT(1),
-		.hw.init = &(const struct clk_init_data){
-			.name = "gcc_aggre_ufs_phy_axi_hw_ctl_clk",
-			.parent_hws = (const struct clk_hw*[]){
-				&gcc_ufs_phy_axi_clk_src.clkr.hw,
-			},
-			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
-			.ops = &clk_branch2_ops,
-		},
-	},
-};
-
 static struct clk_branch gcc_aggre_usb2_prim_axi_clk = {
 	.halt_reg = 0x1c05c,
 	.halt_check = BRANCH_HALT_VOTED,
@@ -3809,26 +3787,6 @@
 	},
 };
 
-static struct clk_branch gcc_ufs_phy_axi_hw_ctl_clk = {
-	.halt_reg = 0x83018,
-	.halt_check = BRANCH_HALT_VOTED,
-	.hwcg_reg = 0x83018,
-	.hwcg_bit = 1,
-	.clkr = {
-		.enable_reg = 0x83018,
-		.enable_mask = BIT(1),
-		.hw.init = &(const struct clk_init_data){
-			.name = "gcc_ufs_phy_axi_hw_ctl_clk",
-			.parent_hws = (const struct clk_hw*[]){
-				&gcc_ufs_phy_axi_clk_src.clkr.hw,
-			},
-			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
-			.ops = &clk_branch2_ops,
-		},
-	},
-};
-
 static struct clk_branch gcc_ufs_phy_ice_core_clk = {
 	.halt_reg = 0x8306c,
 	.halt_check = BRANCH_HALT_VOTED,
@@ -3849,26 +3807,6 @@
 	},
 };
 
-static struct clk_branch gcc_ufs_phy_ice_core_hw_ctl_clk = {
-	.halt_reg = 0x8306c,
-	.halt_check = BRANCH_HALT_VOTED,
-	.hwcg_reg = 0x8306c,
-	.hwcg_bit = 1,
-	.clkr = {
-		.enable_reg = 0x8306c,
-		.enable_mask = BIT(1),
-		.hw.init = &(const struct clk_init_data){
-			.name = "gcc_ufs_phy_ice_core_hw_ctl_clk",
-			.parent_hws = (const struct clk_hw*[]){
-				&gcc_ufs_phy_ice_core_clk_src.clkr.hw,
-			},
-			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
-			.ops = &clk_branch2_ops,
-		},
-	},
-};
-
 static struct clk_branch gcc_ufs_phy_phy_aux_clk = {
 	.halt_reg = 0x830a4,
 	.halt_check = BRANCH_HALT_VOTED,
@@ -3889,26 +3827,6 @@
 	},
 };
 
-static struct clk_branch gcc_ufs_phy_phy_aux_hw_ctl_clk = {
-	.halt_reg = 0x830a4,
-	.halt_check = BRANCH_HALT_VOTED,
-	.hwcg_reg = 0x830a4,
-	.hwcg_bit = 1,
-	.clkr = {
-		.enable_reg = 0x830a4,
-		.enable_mask = BIT(1),
-		.hw.init = &(const struct clk_init_data){
-			.name = "gcc_ufs_phy_phy_aux_hw_ctl_clk",
-			.parent_hws = (const struct clk_hw*[]){
-				&gcc_ufs_phy_phy_aux_clk_src.clkr.hw,
-			},
-			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
-			.ops = &clk_branch2_ops,
-		},
-	},
-};
-
 static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = {
 	.halt_reg = 0x83028,
 	.halt_check = BRANCH_HALT_DELAY,
@@ -3983,26 +3901,6 @@
 	},
 };
 
-static struct clk_branch gcc_ufs_phy_unipro_core_hw_ctl_clk = {
-	.halt_reg = 0x83064,
-	.halt_check = BRANCH_HALT_VOTED,
-	.hwcg_reg = 0x83064,
-	.hwcg_bit = 1,
-	.clkr = {
-		.enable_reg = 0x83064,
-		.enable_mask = BIT(1),
-		.hw.init = &(const struct clk_init_data){
-			.name = "gcc_ufs_phy_unipro_core_hw_ctl_clk",
-			.parent_hws = (const struct clk_hw*[]){
-				&gcc_ufs_phy_unipro_core_clk_src.clkr.hw,
-			},
-			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
-			.ops = &clk_branch2_ops,
-		},
-	},
-};
-
 static struct clk_branch gcc_usb20_master_clk = {
 	.halt_reg = 0x1c018,
 	.halt_check = BRANCH_HALT,
@@ -4305,81 +4203,120 @@
 
 static struct gdsc pcie_0_gdsc = {
 	.gdscr = 0xa9004,
+	.collapse_ctrl = 0x4b104,
+	.collapse_mask = BIT(0),
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "pcie_0_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE | RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
 };
 
 static struct gdsc pcie_1_gdsc = {
 	.gdscr = 0x77004,
+	.collapse_ctrl = 0x4b104,
+	.collapse_mask = BIT(1),
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "pcie_1_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE | RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
 };
 
 static struct gdsc ufs_card_gdsc = {
 	.gdscr = 0x81004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "ufs_card_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
 };
 
 static struct gdsc ufs_phy_gdsc = {
 	.gdscr = 0x83004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "ufs_phy_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
 };
 
 static struct gdsc usb20_prim_gdsc = {
 	.gdscr = 0x1c004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "usb20_prim_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
 };
 
 static struct gdsc usb30_prim_gdsc = {
 	.gdscr = 0x1b004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "usb30_prim_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
 };
 
 static struct gdsc usb30_sec_gdsc = {
 	.gdscr = 0x2f004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "usb30_sec_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
 };
 
 static struct gdsc emac0_gdsc = {
 	.gdscr = 0xb6004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "emac0_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
 };
 
 static struct gdsc emac1_gdsc = {
 	.gdscr = 0xb4004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "emac1_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
+	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
 };
 
 static struct clk_regmap *gcc_sa8775p_clocks[] = {
 	[GCC_AGGRE_NOC_QUPV3_AXI_CLK] = &gcc_aggre_noc_qupv3_axi_clk.clkr,
 	[GCC_AGGRE_UFS_CARD_AXI_CLK] = &gcc_aggre_ufs_card_axi_clk.clkr,
 	[GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr,
-	[GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK] = &gcc_aggre_ufs_phy_axi_hw_ctl_clk.clkr,
 	[GCC_AGGRE_USB2_PRIM_AXI_CLK] = &gcc_aggre_usb2_prim_axi_clk.clkr,
 	[GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr,
 	[GCC_AGGRE_USB3_SEC_AXI_CLK] = &gcc_aggre_usb3_sec_axi_clk.clkr,
@@ -4569,13 +4506,10 @@
 	[GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr,
 	[GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr,
 	[GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr,
-	[GCC_UFS_PHY_AXI_HW_CTL_CLK] = &gcc_ufs_phy_axi_hw_ctl_clk.clkr,
 	[GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr,
 	[GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr,
-	[GCC_UFS_PHY_ICE_CORE_HW_CTL_CLK] = &gcc_ufs_phy_ice_core_hw_ctl_clk.clkr,
 	[GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr,
 	[GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr,
-	[GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK] = &gcc_ufs_phy_phy_aux_hw_ctl_clk.clkr,
 	[GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr,
 	[GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_rx_symbol_0_clk_src.clkr,
 	[GCC_UFS_PHY_RX_SYMBOL_1_CLK] = &gcc_ufs_phy_rx_symbol_1_clk.clkr,
@@ -4584,7 +4518,6 @@
 	[GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_tx_symbol_0_clk_src.clkr,
 	[GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr,
 	[GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = &gcc_ufs_phy_unipro_core_clk_src.clkr,
-	[GCC_UFS_PHY_UNIPRO_CORE_HW_CTL_CLK] = &gcc_ufs_phy_unipro_core_hw_ctl_clk.clkr,
 	[GCC_USB20_MASTER_CLK] = &gcc_usb20_master_clk.clkr,
 	[GCC_USB20_MASTER_CLK_SRC] = &gcc_usb20_master_clk_src.clkr,
 	[GCC_USB20_MOCK_UTMI_CLK] = &gcc_usb20_mock_utmi_clk.clkr,
@@ -4747,6 +4680,7 @@
 	 * GCC_CAMERA_AHB_CLK, GCC_CAMERA_XO_CLK, GCC_DISP1_AHB_CLK,
 	 * GCC_DISP1_XO_CLK, GCC_DISP_AHB_CLK, GCC_DISP_XO_CLK,
 	 * GCC_GPU_CFG_AHB_CLK, GCC_VIDEO_AHB_CLK, GCC_VIDEO_XO_CLK.
+	 * Use qcom_clk_set_en()
 	 */
 	regmap_update_bits(regmap, 0x32004, BIT(0), BIT(0));
 	regmap_update_bits(regmap, 0x32020, BIT(0), BIT(0));
@@ -4758,7 +4692,10 @@
 	regmap_update_bits(regmap, 0x34004, BIT(0), BIT(0));
 	regmap_update_bits(regmap, 0x34024, BIT(0), BIT(0));
 
-	return qcom_cc_really_probe(pdev, &gcc_sa8775p_desc, regmap);
+	/* FORCE_MEM_CORE_ON for ufs phy ice core clocks */
+	qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true);
+
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sa8775p_desc, regmap);
 }
 
 static struct platform_driver gcc_sa8775p_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sc7180.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sc7180.c
@@ -2462,7 +2462,7 @@
 	if (ret)
 		return ret;
 
-	return qcom_cc_really_probe(pdev, &gcc_sc7180_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sc7180_desc, regmap);
 }
 
 static struct platform_driver gcc_sc7180_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sc7280.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sc7280.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/clk-provider.h>
@@ -3094,6 +3095,9 @@
 
 static struct gdsc gcc_pcie_0_gdsc = {
 	.gdscr = 0x6b004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "gcc_pcie_0_gdsc",
 	},
@@ -3112,6 +3116,9 @@
 
 static struct gdsc gcc_ufs_phy_gdsc = {
 	.gdscr = 0x77004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "gcc_ufs_phy_gdsc",
 	},
@@ -3121,6 +3128,9 @@
 
 static struct gdsc gcc_usb30_prim_gdsc = {
 	.gdscr = 0xf004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "gcc_usb30_prim_gdsc",
 	},
@@ -3467,12 +3477,15 @@
 	regmap_update_bits(regmap, 0x71004, BIT(0), BIT(0));
 	regmap_update_bits(regmap, 0x7100C, BIT(13), BIT(13));
 
+	/* FORCE_MEM_CORE_ON for ufs phy ice core clocks */
+	qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true);
+
 	ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks,
 			ARRAY_SIZE(gcc_dfs_clocks));
 	if (ret)
 		return ret;
 
-	return qcom_cc_really_probe(pdev, &gcc_sc7280_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sc7280_desc, regmap);
 }
 
 static struct platform_driver gcc_sc7280_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sc8180x.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sc8180x.c
@@ -142,6 +142,23 @@
 	},
 };
 
+static struct clk_alpha_pll gpll9 = {
+	.offset = 0x1c000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(9),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpll9",
+			.parent_data = &(const struct clk_parent_data) {
+				.fw_name = "bi_tcxo",
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_trion_ops,
+		},
+	},
+};
+
 static const struct parent_map gcc_parent_map_0[] = {
 	{ P_BI_TCXO, 0 },
 	{ P_GPLL0_OUT_MAIN, 1 },
@@ -241,7 +258,7 @@
 static const struct clk_parent_data gcc_parents_7[] = {
 	{ .fw_name = "bi_tcxo", },
 	{ .hw = &gpll0.clkr.hw },
-	{ .name = "gppl9" },
+	{ .hw = &gpll9.clkr.hw },
 	{ .hw = &gpll4.clkr.hw },
 	{ .hw = &gpll0_out_even.clkr.hw },
 };
@@ -260,28 +277,6 @@
 	{ .hw = &gpll0_out_even.clkr.hw },
 };
 
-static const struct freq_tbl ftbl_gcc_cpuss_ahb_clk_src[] = {
-	F(19200000, P_BI_TCXO, 1, 0, 0),
-	F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0),
-	F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
-	{ }
-};
-
-static struct clk_rcg2 gcc_cpuss_ahb_clk_src = {
-	.cmd_rcgr = 0x48014,
-	.mnd_width = 0,
-	.hid_width = 5,
-	.parent_map = gcc_parent_map_0,
-	.freq_tbl = ftbl_gcc_cpuss_ahb_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_cpuss_ahb_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
-};
-
 static const struct freq_tbl ftbl_gcc_emac_ptp_clk_src[] = {
 	F(19200000, P_BI_TCXO, 1, 0, 0),
 	F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
@@ -609,19 +604,29 @@
 	{ }
 };
 
+static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s0_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
+};
+
 static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
 	.cmd_rcgr = 0x17148,
 	.mnd_width = 16,
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s0_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s1_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
@@ -630,13 +635,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s1_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s2_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
@@ -645,13 +652,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s2_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s3_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
@@ -660,13 +669,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s3_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s4_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
@@ -675,13 +686,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s4_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s5_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
@@ -690,13 +703,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s5_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s6_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
@@ -705,13 +720,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s6_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s7_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
@@ -720,13 +737,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s7_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s0_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
@@ -735,13 +754,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap1_s0_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s1_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
@@ -750,13 +771,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap1_s1_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s2_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
@@ -765,13 +788,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap1_s2_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s3_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
@@ -780,13 +805,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap1_s3_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s4_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
@@ -795,13 +822,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap1_s4_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s5_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
@@ -810,13 +839,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap1_s5_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s0_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_s0_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = {
@@ -825,13 +856,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap2_s0_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap2_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s1_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_s1_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = {
@@ -840,28 +873,33 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap2_s1_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap2_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s2_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_s2_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
+
 static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = {
 	.cmd_rcgr = 0x1e3a8,
 	.mnd_width = 16,
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap2_s2_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap2_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s3_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_s3_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = {
@@ -870,13 +908,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap2_s3_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap2_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s4_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_s4_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = {
@@ -885,13 +925,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap2_s4_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap2_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s5_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_s5_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = {
@@ -900,13 +942,7 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap2_s5_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap2_s5_clk_src_init,
 };
 
 static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
@@ -916,7 +952,7 @@
 	F(25000000, P_GPLL0_OUT_MAIN, 12, 1, 2),
 	F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0),
 	F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
-	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+	F(202000000, P_GPLL9_OUT_MAIN, 4, 0, 0),
 	{ }
 };
 
@@ -939,9 +975,8 @@
 	F(400000, P_BI_TCXO, 12, 1, 4),
 	F(9600000, P_BI_TCXO, 2, 0, 0),
 	F(19200000, P_BI_TCXO, 1, 0, 0),
-	F(37500000, P_GPLL0_OUT_MAIN, 16, 0, 0),
 	F(50000000, P_GPLL0_OUT_MAIN, 12, 0, 0),
-	F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+	F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0),
 	{ }
 };
 
@@ -1599,25 +1634,6 @@
 	},
 };
 
-/* For CPUSS functionality the AHB clock needs to be left enabled */
-static struct clk_branch gcc_cpuss_ahb_clk = {
-	.halt_reg = 0x48000,
-	.halt_check = BRANCH_HALT_VOTED,
-	.clkr = {
-		.enable_reg = 0x52004,
-		.enable_mask = BIT(21),
-		.hw.init = &(struct clk_init_data){
-			.name = "gcc_cpuss_ahb_clk",
-			.parent_hws = (const struct clk_hw *[]){
-				      &gcc_cpuss_ahb_clk_src.clkr.hw
-			},
-			.num_parents = 1,
-			.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
-			.ops = &clk_branch2_ops,
-		},
-	},
-};
-
 static struct clk_branch gcc_cpuss_rbcpr_clk = {
 	.halt_reg = 0x48008,
 	.halt_check = BRANCH_HALT,
@@ -3150,25 +3166,6 @@
 	},
 };
 
-/* For CPUSS functionality the SYS NOC clock needs to be left enabled */
-static struct clk_branch gcc_sys_noc_cpuss_ahb_clk = {
-	.halt_reg = 0x4819c,
-	.halt_check = BRANCH_HALT_VOTED,
-	.clkr = {
-		.enable_reg = 0x52004,
-		.enable_mask = BIT(0),
-		.hw.init = &(struct clk_init_data){
-			.name = "gcc_sys_noc_cpuss_ahb_clk",
-			.parent_hws = (const struct clk_hw *[]){
-				      &gcc_cpuss_ahb_clk_src.clkr.hw
-			},
-			.num_parents = 1,
-			.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
-			.ops = &clk_branch2_ops,
-		},
-	},
-};
-
 static struct clk_branch gcc_tsif_ahb_clk = {
 	.halt_reg = 0x36004,
 	.halt_check = BRANCH_HALT,
@@ -4258,8 +4255,6 @@
 	[GCC_CFG_NOC_USB3_MP_AXI_CLK] = &gcc_cfg_noc_usb3_mp_axi_clk.clkr,
 	[GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr,
 	[GCC_CFG_NOC_USB3_SEC_AXI_CLK] = &gcc_cfg_noc_usb3_sec_axi_clk.clkr,
-	[GCC_CPUSS_AHB_CLK] = &gcc_cpuss_ahb_clk.clkr,
-	[GCC_CPUSS_AHB_CLK_SRC] = &gcc_cpuss_ahb_clk_src.clkr,
 	[GCC_CPUSS_RBCPR_CLK] = &gcc_cpuss_rbcpr_clk.clkr,
 	[GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr,
 	[GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr,
@@ -4396,7 +4391,6 @@
 	[GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr,
 	[GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr,
 	[GCC_SDCC4_APPS_CLK_SRC] = &gcc_sdcc4_apps_clk_src.clkr,
-	[GCC_SYS_NOC_CPUSS_AHB_CLK] = &gcc_sys_noc_cpuss_ahb_clk.clkr,
 	[GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr,
 	[GCC_TSIF_INACTIVITY_TIMERS_CLK] = &gcc_tsif_inactivity_timers_clk.clkr,
 	[GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr,
@@ -4483,6 +4477,7 @@
 	[GPLL1] = &gpll1.clkr,
 	[GPLL4] = &gpll4.clkr,
 	[GPLL7] = &gpll7.clkr,
+	[GPLL9] = &gpll9.clkr,
 };
 
 static const struct qcom_reset_map gcc_sc8180x_resets[] = {
@@ -4533,6 +4528,29 @@
 	[GCC_VIDEO_AXI1_CLK_BCR] = { 0xb028, 2 },
 };
 
+static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s0_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s1_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s2_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s3_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s4_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s5_clk_src),
+};
+
 static struct gdsc *gcc_sc8180x_gdscs[] = {
 	[EMAC_GDSC] = &emac_gdsc,
 	[PCIE_0_GDSC] = &pcie_0_gdsc,
@@ -4574,6 +4592,7 @@
 static int gcc_sc8180x_probe(struct platform_device *pdev)
 {
 	struct regmap *regmap;
+	int ret;
 
 	regmap = qcom_cc_map(pdev, &gcc_sc8180x_desc);
 	if (IS_ERR(regmap))
@@ -4601,7 +4620,12 @@
 	regmap_update_bits(regmap, 0x4d110, 0x3, 0x3);
 	regmap_update_bits(regmap, 0x71028, 0x3, 0x3);
 
-	return qcom_cc_really_probe(pdev, &gcc_sc8180x_desc, regmap);
+	ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks,
+					ARRAY_SIZE(gcc_dfs_clocks));
+	if (ret)
+		return ret;
+
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sc8180x_desc, regmap);
 }
 
 static struct platform_driver gcc_sc8180x_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sc8280xp.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sc8280xp.c
@@ -7563,7 +7563,7 @@
 	if (ret)
 		goto err_put_rpm;
 
-	ret = qcom_cc_really_probe(pdev, &gcc_sc8280xp_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &gcc_sc8280xp_desc, regmap);
 	if (ret)
 		goto err_put_rpm;
 
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sdm660.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sdm660.c
@@ -2474,7 +2474,7 @@
 	if (ret)
 		return ret;
 
-	return qcom_cc_really_probe(pdev, &gcc_sdm660_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sdm660_desc, regmap);
 }
 
 static struct platform_driver gcc_sdm660_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sdm845.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sdm845.c
@@ -454,7 +454,7 @@
 	.name = "gcc_qupv3_wrap0_s0_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
@@ -470,7 +470,7 @@
 	.name = "gcc_qupv3_wrap0_s1_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
@@ -486,7 +486,7 @@
 	.name = "gcc_qupv3_wrap0_s2_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
@@ -502,7 +502,7 @@
 	.name = "gcc_qupv3_wrap0_s3_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
@@ -518,7 +518,7 @@
 	.name = "gcc_qupv3_wrap0_s4_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
@@ -534,7 +534,7 @@
 	.name = "gcc_qupv3_wrap0_s5_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
@@ -550,7 +550,7 @@
 	.name = "gcc_qupv3_wrap0_s6_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
@@ -566,7 +566,7 @@
 	.name = "gcc_qupv3_wrap0_s7_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
@@ -582,7 +582,7 @@
 	.name = "gcc_qupv3_wrap1_s0_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
@@ -598,7 +598,7 @@
 	.name = "gcc_qupv3_wrap1_s1_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
@@ -614,7 +614,7 @@
 	.name = "gcc_qupv3_wrap1_s2_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
@@ -630,7 +630,7 @@
 	.name = "gcc_qupv3_wrap1_s3_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
@@ -646,7 +646,7 @@
 	.name = "gcc_qupv3_wrap1_s4_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
@@ -662,7 +662,7 @@
 	.name = "gcc_qupv3_wrap1_s5_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
@@ -678,7 +678,7 @@
 	.name = "gcc_qupv3_wrap1_s6_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
@@ -694,7 +694,7 @@
 	.name = "gcc_qupv3_wrap1_s7_clk_src",
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {
@@ -4011,7 +4011,7 @@
 		return ret;
 
 	gcc_desc = of_device_get_match_data(&pdev->dev);
-	return qcom_cc_really_probe(pdev, gcc_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, gcc_desc, regmap);
 }
 
 static struct platform_driver gcc_sdm845_driver = {
@@ -4037,3 +4037,4 @@
 MODULE_DESCRIPTION("QTI GCC SDM845 Driver");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:gcc-sdm845");
+MODULE_SOFTDEP("pre: rpmhpd");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sdx55.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sdx55.c
@@ -1620,7 +1620,7 @@
 	regmap_update_bits(regmap, 0x6d008, BIT(21), BIT(21));
 	regmap_update_bits(regmap, 0x6d008, BIT(22), BIT(22));
 
-	return qcom_cc_really_probe(pdev, &gcc_sdx55_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sdx55_desc, regmap);
 }
 
 static struct platform_driver gcc_sdx55_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sdx65.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sdx65.c
@@ -1583,7 +1583,7 @@
 	regmap_update_bits(regmap, 0x6d008, BIT(21), BIT(21));
 	regmap_update_bits(regmap, 0x6d008, BIT(22), BIT(22));
 
-	return qcom_cc_really_probe(pdev, &gcc_sdx65_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sdx65_desc, regmap);
 }
 
 static struct platform_driver gcc_sdx65_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sdx75.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sdx75.c
@@ -2944,7 +2944,7 @@
 	regmap_update_bits(regmap, 0x3e004, BIT(0), BIT(0));
 	regmap_update_bits(regmap, 0x3e008, BIT(0), BIT(0));
 
-	return qcom_cc_really_probe(pdev, &gcc_sdx75_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sdx75_desc, regmap);
 }
 
 static struct platform_driver gcc_sdx75_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sm4450.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sm4450.c
@@ -2871,7 +2871,7 @@
 
 	regmap_update_bits(regmap, 0x4201c, BIT(21), BIT(21));
 
-	return qcom_cc_really_probe(pdev, &gcc_sm4450_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sm4450_desc, regmap);
 }
 
 static struct platform_driver gcc_sm4450_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sm6115.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sm6115.c
@@ -3513,7 +3513,7 @@
 	clk_alpha_pll_configure(&gpll10, regmap, &gpll10_config);
 	clk_alpha_pll_configure(&gpll11, regmap, &gpll11_config);
 
-	return qcom_cc_really_probe(pdev, &gcc_sm6115_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sm6115_desc, regmap);
 }
 
 static struct platform_driver gcc_sm6115_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sm6125.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sm6125.c
@@ -4161,7 +4161,7 @@
 	if (ret)
 		return ret;
 
-	return qcom_cc_really_probe(pdev, &gcc_sm6125_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sm6125_desc, regmap);
 }
 
 static struct platform_driver gcc_sm6125_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sm6350.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sm6350.c
@@ -100,8 +100,8 @@
 		.enable_mask = BIT(6),
 		.hw.init = &(struct clk_init_data){
 			.name = "gpll6",
-			.parent_hws = (const struct clk_hw*[]){
-				&gpll0.clkr.hw,
+			.parent_data = &(const struct clk_parent_data){
+				.fw_name = "bi_tcxo",
 			},
 			.num_parents = 1,
 			.ops = &clk_alpha_pll_fixed_fabia_ops,
@@ -124,7 +124,7 @@
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gpll6_out_even",
 		.parent_hws = (const struct clk_hw*[]){
-			&gpll0.clkr.hw,
+			&gpll6.clkr.hw,
 		},
 		.num_parents = 1,
 		.ops = &clk_alpha_pll_postdiv_fabia_ops,
@@ -139,8 +139,8 @@
 		.enable_mask = BIT(7),
 		.hw.init = &(struct clk_init_data){
 			.name = "gpll7",
-			.parent_hws = (const struct clk_hw*[]){
-				&gpll0.clkr.hw,
+			.parent_data = &(const struct clk_parent_data){
+				.fw_name = "bi_tcxo",
 			},
 			.num_parents = 1,
 			.ops = &clk_alpha_pll_fixed_fabia_ops,
@@ -182,6 +182,14 @@
 	{ .hw = &gpll0_out_odd.clkr.hw },
 };
 
+static const struct parent_map gcc_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data gcc_parent_data_3[] = {
+	{ .fw_name = "bi_tcxo" },
+};
+
 static const struct parent_map gcc_parent_map_4[] = {
 	{ P_BI_TCXO, 0 },
 	{ P_GPLL0_OUT_MAIN, 1 },
@@ -701,13 +709,12 @@
 	.cmd_rcgr = 0x3a0b0,
 	.mnd_width = 0,
 	.hid_width = 5,
+	.parent_map = gcc_parent_map_3,
 	.freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_ufs_phy_phy_aux_clk_src",
-		.parent_data = &(const struct clk_parent_data){
-			.fw_name = "bi_tcxo",
-		},
-		.num_parents = 1,
+		.parent_data = gcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_3),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -764,13 +771,12 @@
 	.cmd_rcgr = 0x1a034,
 	.mnd_width = 0,
 	.hid_width = 5,
+	.parent_map = gcc_parent_map_3,
 	.freq_tbl = ftbl_gcc_usb30_prim_mock_utmi_clk_src,
 	.clkr.hw.init = &(struct clk_init_data){
 		.name = "gcc_usb30_prim_mock_utmi_clk_src",
-		.parent_data = &(const struct clk_parent_data){
-			.fw_name = "bi_tcxo",
-		},
-		.num_parents = 1,
+		.parent_data = gcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_3),
 		.ops = &clk_rcg2_ops,
 	},
 };
@@ -2559,7 +2565,7 @@
 	if (ret)
 		return ret;
 
-	return qcom_cc_really_probe(pdev, &gcc_sm6350_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sm6350_desc, regmap);
 }
 
 static struct platform_driver gcc_sm6350_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sm6375.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sm6375.c
@@ -3895,7 +3895,7 @@
 	clk_lucid_pll_configure(&gpll8, regmap, &gpll8_config);
 	clk_zonda_pll_configure(&gpll9, regmap, &gpll9_config);
 
-	return qcom_cc_really_probe(pdev, &gcc_sm6375_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sm6375_desc, regmap);
 }
 
 static struct platform_driver gcc_sm6375_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sm7150.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sm7150.c
@@ -3022,7 +3022,7 @@
 	if (ret)
 		return ret;
 
-	return qcom_cc_really_probe(pdev, &gcc_sm7150_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sm7150_desc, regmap);
 }
 
 static struct platform_driver gcc_sm7150_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sm8150.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sm8150.c
@@ -453,19 +453,29 @@
 	{ }
 };
 
+static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s0_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
+};
+
 static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
 	.cmd_rcgr = 0x17148,
 	.mnd_width = 16,
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s0_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s1_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
@@ -474,13 +484,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s1_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s2_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
@@ -489,13 +501,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s2_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s3_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
@@ -504,13 +518,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s3_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s4_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
@@ -519,13 +535,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s4_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s5_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
@@ -534,13 +552,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s5_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s6_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
@@ -549,13 +569,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s6_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = {
+	.name = "gcc_qupv3_wrap0_s7_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
@@ -564,13 +586,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap0_s7_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s0_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
@@ -579,13 +603,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap1_s0_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s1_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
@@ -594,13 +620,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap1_s1_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s2_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
@@ -609,13 +637,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap1_s2_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s3_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
@@ -624,13 +654,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap1_s3_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s4_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
@@ -639,13 +671,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap1_s4_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_s5_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
@@ -654,13 +688,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap1_s5_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s0_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_s0_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = {
@@ -669,13 +705,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap2_s0_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap2_s0_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s1_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_s1_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = {
@@ -684,13 +722,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap2_s1_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap2_s1_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s2_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_s2_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = {
@@ -699,13 +739,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap2_s2_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap2_s2_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s3_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_s3_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = {
@@ -714,13 +756,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap2_s3_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap2_s3_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s4_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_s4_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = {
@@ -729,13 +773,15 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap2_s4_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap2_s4_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s5_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_s5_clk_src",
+	.parent_data = gcc_parents_0,
+	.num_parents = ARRAY_SIZE(gcc_parents_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = {
@@ -744,13 +790,7 @@
 	.hid_width = 5,
 	.parent_map = gcc_parent_map_0,
 	.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
-	.clkr.hw.init = &(struct clk_init_data){
-		.name = "gcc_qupv3_wrap2_s5_clk_src",
-		.parent_data = gcc_parents_0,
-		.num_parents = ARRAY_SIZE(gcc_parents_0),
-		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
-	},
+	.clkr.hw.init = &gcc_qupv3_wrap2_s5_clk_src_init,
 };
 
 static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
@@ -3750,6 +3790,29 @@
 	[USB30_SEC_GDSC] = &usb30_sec_gdsc,
 };
 
+static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s0_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s1_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s2_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s3_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s4_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s5_clk_src),
+};
+
 static const struct regmap_config gcc_sm8150_regmap_config = {
 	.reg_bits	= 32,
 	.reg_stride	= 4,
@@ -3777,6 +3840,7 @@
 static int gcc_sm8150_probe(struct platform_device *pdev)
 {
 	struct regmap *regmap;
+	int ret;
 
 	regmap = qcom_cc_map(pdev, &gcc_sm8150_desc);
 	if (IS_ERR(regmap))
@@ -3786,7 +3850,12 @@
 	regmap_update_bits(regmap, 0x4d110, 0x3, 0x3);
 	regmap_update_bits(regmap, 0x71028, 0x3, 0x3);
 
-	return qcom_cc_really_probe(pdev, &gcc_sm8150_desc, regmap);
+	ret = qcom_cc_register_rcg_dfs(regmap, gcc_dfs_clocks,
+				       ARRAY_SIZE(gcc_dfs_clocks));
+	if (ret)
+		dev_err_probe(&pdev->dev, ret, "Failed to register with DFS!\n");
+
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sm8150_desc, regmap);
 }
 
 static struct platform_driver gcc_sm8150_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sm8250.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sm8250.c
@@ -3226,7 +3226,7 @@
 	.pd = {
 		.name = "pcie_0_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 };
 
 static struct gdsc pcie_1_gdsc = {
@@ -3234,7 +3234,7 @@
 	.pd = {
 		.name = "pcie_1_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 };
 
 static struct gdsc pcie_2_gdsc = {
@@ -3242,7 +3242,7 @@
 	.pd = {
 		.name = "pcie_2_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 };
 
 static struct gdsc ufs_card_gdsc = {
@@ -3661,7 +3661,7 @@
 	if (ret)
 		return ret;
 
-	return qcom_cc_really_probe(pdev, &gcc_sm8250_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sm8250_desc, regmap);
 }
 
 static struct platform_driver gcc_sm8250_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sm8350.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sm8350.c
@@ -3826,7 +3826,7 @@
 	/* FORCE_MEM_CORE_ON for ufs phy ice core clocks */
 	regmap_update_bits(regmap, gcc_ufs_phy_ice_core_clk.halt_reg, BIT(14), BIT(14));
 
-	return qcom_cc_really_probe(pdev, &gcc_sm8350_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sm8350_desc, regmap);
 }
 
 static struct platform_driver gcc_sm8350_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sm8450.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sm8450.c
@@ -2974,7 +2974,7 @@
 	.pd = {
 		.name = "pcie_0_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 };
 
 static struct gdsc pcie_1_gdsc = {
@@ -2982,7 +2982,7 @@
 	.pd = {
 		.name = "pcie_1_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 };
 
 static struct gdsc ufs_phy_gdsc = {
@@ -3294,7 +3294,7 @@
 	regmap_update_bits(regmap, 0x42004, BIT(0), BIT(0));
 	regmap_update_bits(regmap, 0x42028, BIT(0), BIT(0));
 
-	return qcom_cc_really_probe(pdev, &gcc_sm8450_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sm8450_desc, regmap);
 }
 
 static struct platform_driver gcc_sm8450_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sm8550.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sm8550.c
@@ -536,7 +536,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -551,7 +551,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -566,7 +566,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -581,7 +581,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -596,7 +596,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -611,7 +611,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -626,7 +626,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -641,7 +641,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -656,7 +656,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -671,7 +671,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -700,7 +700,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
@@ -717,7 +717,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
@@ -750,7 +750,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
@@ -767,7 +767,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
@@ -784,7 +784,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
@@ -801,7 +801,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
@@ -818,7 +818,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
@@ -835,7 +835,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {
@@ -852,7 +852,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = {
@@ -869,7 +869,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = {
@@ -886,7 +886,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = {
@@ -903,7 +903,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = {
@@ -920,7 +920,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = {
@@ -937,7 +937,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = {
@@ -975,7 +975,7 @@
 	.parent_data = gcc_parent_data_8,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_8),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s6_clk_src = {
@@ -992,7 +992,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = {
@@ -1159,7 +1159,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_shared_no_init_park_ops,
 	},
 };
 
@@ -3003,7 +3003,7 @@
 	.pd = {
 		.name = "pcie_0_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
 };
 
@@ -3014,7 +3014,7 @@
 	.pd = {
 		.name = "pcie_0_phy_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
 };
 
@@ -3025,7 +3025,7 @@
 	.pd = {
 		.name = "pcie_1_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
 };
 
@@ -3036,7 +3036,7 @@
 	.pd = {
 		.name = "pcie_1_phy_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
 };
 
@@ -3369,7 +3369,7 @@
 	/* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */
 	regmap_write(regmap, 0x52024, 0x0);
 
-	return qcom_cc_really_probe(pdev, &gcc_sm8550_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sm8550_desc, regmap);
 }
 
 static struct platform_driver gcc_sm8550_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-sm8650.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-sm8650.c
@@ -713,7 +713,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -728,7 +728,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -743,7 +743,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -758,7 +758,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -773,7 +773,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -788,7 +788,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -803,7 +803,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -818,7 +818,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -833,7 +833,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -848,7 +848,7 @@
 		.parent_data = gcc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -863,7 +863,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_qspi_ref_clk_src = {
@@ -899,7 +899,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
@@ -916,7 +916,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
@@ -948,7 +948,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
@@ -980,7 +980,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
@@ -997,7 +997,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
@@ -1014,7 +1014,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
@@ -1031,7 +1031,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {
@@ -1059,7 +1059,7 @@
 		.parent_data = gcc_parent_data_2,
 		.num_parents = ARRAY_SIZE(gcc_parent_data_2),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_shared_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
@@ -1068,7 +1068,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = {
@@ -1085,7 +1085,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = {
@@ -1102,7 +1102,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = {
@@ -1119,7 +1119,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = {
@@ -1136,7 +1136,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = {
@@ -1153,7 +1153,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = {
@@ -1186,7 +1186,7 @@
 	.parent_data = gcc_parent_data_10,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_10),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s6_clk_src = {
@@ -1203,7 +1203,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = {
@@ -1226,7 +1226,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap3_qspi_ref_clk_src = {
@@ -3437,7 +3437,7 @@
 	.pd = {
 		.name = "pcie_0_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
 };
 
@@ -3448,7 +3448,7 @@
 	.pd = {
 		.name = "pcie_0_phy_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
 };
 
@@ -3459,7 +3459,7 @@
 	.pd = {
 		.name = "pcie_1_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
 };
 
@@ -3470,7 +3470,7 @@
 	.pd = {
 		.name = "pcie_1_phy_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
 };
 
@@ -3822,7 +3822,7 @@
 	/* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */
 	regmap_write(regmap, 0x52150, 0x0);
 
-	return qcom_cc_really_probe(pdev, &gcc_sm8650_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_sm8650_desc, regmap);
 }
 
 static struct platform_driver gcc_sm8650_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gcc-x1e80100.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gcc-x1e80100.c
@@ -670,7 +670,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
@@ -687,7 +687,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
@@ -719,7 +719,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
@@ -736,7 +736,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
@@ -768,7 +768,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
@@ -785,7 +785,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
@@ -802,7 +802,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
@@ -819,7 +819,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
@@ -836,7 +836,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
@@ -853,7 +853,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
@@ -870,7 +870,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
@@ -887,7 +887,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
@@ -904,7 +904,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
@@ -921,7 +921,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
@@ -938,7 +938,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
@@ -955,7 +955,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {
@@ -972,7 +972,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = {
@@ -989,7 +989,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = {
@@ -1006,7 +1006,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = {
@@ -1023,7 +1023,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = {
@@ -1040,7 +1040,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = {
@@ -1057,7 +1057,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = {
@@ -1074,7 +1074,7 @@
 	.parent_data = gcc_parent_data_8,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_8),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s6_clk_src = {
@@ -1091,7 +1091,7 @@
 	.parent_data = gcc_parent_data_0,
 	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
 	.flags = CLK_SET_RATE_PARENT,
-	.ops = &clk_rcg2_shared_ops,
+	.ops = &clk_rcg2_ops,
 };
 
 static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = {
@@ -2812,7 +2812,7 @@
 
 static struct clk_branch gcc_pcie_0_pipe_clk = {
 	.halt_reg = 0xa0044,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52010,
 		.enable_mask = BIT(25),
@@ -2901,7 +2901,7 @@
 
 static struct clk_branch gcc_pcie_1_pipe_clk = {
 	.halt_reg = 0x2c044,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52020,
 		.enable_mask = BIT(30),
@@ -2990,7 +2990,7 @@
 
 static struct clk_branch gcc_pcie_2_pipe_clk = {
 	.halt_reg = 0x13044,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52020,
 		.enable_mask = BIT(23),
@@ -3110,7 +3110,7 @@
 
 static struct clk_branch gcc_pcie_3_pipe_clk = {
 	.halt_reg = 0x58050,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52020,
 		.enable_mask = BIT(3),
@@ -3123,7 +3123,7 @@
 
 static struct clk_branch gcc_pcie_3_pipediv2_clk = {
 	.halt_reg = 0x58060,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52020,
 		.enable_mask = BIT(5),
@@ -3235,7 +3235,7 @@
 
 static struct clk_branch gcc_pcie_4_pipe_clk = {
 	.halt_reg = 0x6b044,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52008,
 		.enable_mask = BIT(4),
@@ -3248,7 +3248,7 @@
 
 static struct clk_branch gcc_pcie_4_pipediv2_clk = {
 	.halt_reg = 0x6b054,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52010,
 		.enable_mask = BIT(27),
@@ -3360,7 +3360,7 @@
 
 static struct clk_branch gcc_pcie_5_pipe_clk = {
 	.halt_reg = 0x2f044,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52018,
 		.enable_mask = BIT(17),
@@ -3373,7 +3373,7 @@
 
 static struct clk_branch gcc_pcie_5_pipediv2_clk = {
 	.halt_reg = 0x2f054,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52018,
 		.enable_mask = BIT(19),
@@ -3498,7 +3498,7 @@
 
 static struct clk_branch gcc_pcie_6a_pipe_clk = {
 	.halt_reg = 0x31050,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52018,
 		.enable_mask = BIT(26),
@@ -3511,7 +3511,7 @@
 
 static struct clk_branch gcc_pcie_6a_pipediv2_clk = {
 	.halt_reg = 0x31060,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52018,
 		.enable_mask = BIT(28),
@@ -3636,7 +3636,7 @@
 
 static struct clk_branch gcc_pcie_6b_pipe_clk = {
 	.halt_reg = 0x8d050,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52000,
 		.enable_mask = BIT(30),
@@ -3649,7 +3649,7 @@
 
 static struct clk_branch gcc_pcie_6b_pipediv2_clk = {
 	.halt_reg = 0x8d060,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52010,
 		.enable_mask = BIT(28),
@@ -5109,7 +5109,7 @@
 
 static struct clk_branch gcc_usb3_mp_phy_pipe_0_clk = {
 	.halt_reg = 0x17290,
-	.halt_check = BRANCH_HALT,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x17290,
 		.enable_mask = BIT(0),
@@ -5122,7 +5122,7 @@
 
 static struct clk_branch gcc_usb3_mp_phy_pipe_1_clk = {
 	.halt_reg = 0x17298,
-	.halt_check = BRANCH_HALT,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x17298,
 		.enable_mask = BIT(0),
@@ -5186,7 +5186,7 @@
 
 static struct clk_branch gcc_usb3_prim_phy_pipe_clk = {
 	.halt_reg = 0x39068,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.hwcg_reg = 0x39068,
 	.hwcg_bit = 1,
 	.clkr = {
@@ -5257,7 +5257,7 @@
 
 static struct clk_branch gcc_usb3_sec_phy_pipe_clk = {
 	.halt_reg = 0xa1068,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.hwcg_reg = 0xa1068,
 	.hwcg_bit = 1,
 	.clkr = {
@@ -5269,6 +5269,7 @@
 				&gcc_usb3_sec_phy_pipe_clk_src.clkr.hw,
 			},
 			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -5327,7 +5328,7 @@
 
 static struct clk_branch gcc_usb3_tert_phy_pipe_clk = {
 	.halt_reg = 0xa2068,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.hwcg_reg = 0xa2068,
 	.hwcg_bit = 1,
 	.clkr = {
@@ -5339,6 +5340,7 @@
 				&gcc_usb3_tert_phy_pipe_clk_src.clkr.hw,
 			},
 			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -5405,7 +5407,7 @@
 
 static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = {
 	.halt_reg = 0x9f0d8,
-	.halt_check = BRANCH_HALT,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x9f0d8,
 		.enable_mask = BIT(0),
@@ -5418,7 +5420,7 @@
 
 static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = {
 	.halt_reg = 0x9f048,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52010,
 		.enable_mask = BIT(19),
@@ -5457,7 +5459,7 @@
 
 static struct clk_branch gcc_usb4_0_phy_usb_pipe_clk = {
 	.halt_reg = 0x9f0a4,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.hwcg_reg = 0x9f0a4,
 	.hwcg_bit = 1,
 	.clkr = {
@@ -5582,7 +5584,7 @@
 
 static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = {
 	.halt_reg = 0x2b0d8,
-	.halt_check = BRANCH_HALT,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x2b0d8,
 		.enable_mask = BIT(0),
@@ -5595,7 +5597,7 @@
 
 static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = {
 	.halt_reg = 0x2b048,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52028,
 		.enable_mask = BIT(0),
@@ -5634,7 +5636,7 @@
 
 static struct clk_branch gcc_usb4_1_phy_usb_pipe_clk = {
 	.halt_reg = 0x2b0a4,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.hwcg_reg = 0x2b0a4,
 	.hwcg_bit = 1,
 	.clkr = {
@@ -5759,7 +5761,7 @@
 
 static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = {
 	.halt_reg = 0x110d8,
-	.halt_check = BRANCH_HALT,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x110d8,
 		.enable_mask = BIT(0),
@@ -5772,7 +5774,7 @@
 
 static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = {
 	.halt_reg = 0x11048,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.clkr = {
 		.enable_reg = 0x52028,
 		.enable_mask = BIT(1),
@@ -5811,7 +5813,7 @@
 
 static struct clk_branch gcc_usb4_2_phy_usb_pipe_clk = {
 	.halt_reg = 0x110a4,
-	.halt_check = BRANCH_HALT_VOTED,
+	.halt_check = BRANCH_HALT_SKIP,
 	.hwcg_reg = 0x110a4,
 	.hwcg_bit = 1,
 	.clkr = {
@@ -6081,7 +6083,7 @@
 	.pd = {
 		.name = "gcc_usb20_prim_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
 };
 
@@ -6153,7 +6155,7 @@
 	.pd = {
 		.name = "gcc_usb3_mp_ss1_phy_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
 };
 
@@ -6201,7 +6203,7 @@
 	.pd = {
 		.name = "gcc_usb_0_phy_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
 };
 
@@ -6213,7 +6215,7 @@
 	.pd = {
 		.name = "gcc_usb_1_phy_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
 };
 
@@ -6781,7 +6783,7 @@
 	/* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */
 	regmap_write(regmap, 0x52224, 0x0);
 
-	return qcom_cc_really_probe(pdev, &gcc_x1e80100_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gcc_x1e80100_desc, regmap);
 }
 
 static struct platform_driver gcc_x1e80100_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gdsc.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gdsc.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2015, 2017-2018, 2022, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/bitops.h>
@@ -46,7 +47,7 @@
 #define RETAIN_MEM		BIT(14)
 #define RETAIN_PERIPH		BIT(13)
 
-#define STATUS_POLL_TIMEOUT_US	1500
+#define STATUS_POLL_TIMEOUT_US	2000
 #define TIMEOUT_US		500
 
 #define domain_to_gdsc(domain) container_of(domain, struct gdsc, pd)
@@ -470,7 +471,7 @@
 {
 	int i, ret;
 	struct genpd_onecell_data *data;
-	struct device *dev = desc->dev;
+	struct device *dev = desc->dev, *pd_dev;
 	struct gdsc **scs = desc->scs;
 	size_t num = desc->num;
 
@@ -512,6 +513,16 @@
 			pm_genpd_add_subdomain(scs[i]->parent, &scs[i]->pd);
 		else if (!IS_ERR_OR_NULL(dev->pm_domain))
 			pm_genpd_add_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd);
+		else if (desc->pmdomains) {
+			for (int j = 0; j < desc->pmdomains->num_pds; j++) {
+				pd_dev = desc->pmdomains->pd_devs[j];
+				if (!IS_ERR_OR_NULL(pd_dev)) {
+					struct generic_pm_domain *genpd =
+						pd_to_genpd(pd_dev->pm_domain);
+					pm_genpd_add_subdomain(genpd, &scs[i]->pd);
+				}
+			}
+		}
 	}
 
 	return of_genpd_add_provider_onecell(dev->of_node, data);
@@ -520,7 +531,7 @@
 void gdsc_unregister(struct gdsc_desc *desc)
 {
 	int i;
-	struct device *dev = desc->dev;
+	struct device *dev = desc->dev, *pd_dev;
 	struct gdsc **scs = desc->scs;
 	size_t num = desc->num;
 
@@ -532,6 +543,16 @@
 			pm_genpd_remove_subdomain(scs[i]->parent, &scs[i]->pd);
 		else if (!IS_ERR_OR_NULL(dev->pm_domain))
 			pm_genpd_remove_subdomain(pd_to_genpd(dev->pm_domain), &scs[i]->pd);
+		else if (desc->pmdomains) {
+			for (int j = 0; j < desc->pmdomains->num_pds; j++) {
+				pd_dev = desc->pmdomains->pd_devs[j];
+				if (!IS_ERR_OR_NULL(pd_dev)) {
+					struct generic_pm_domain *genpd =
+						pd_to_genpd(pd_dev->pm_domain);
+					pm_genpd_remove_subdomain(genpd, &scs[i]->pd);
+				}
+			}
+		}
 	}
 	of_genpd_del_provider(dev->of_node);
 }
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gdsc.h
+++ linux-qcom-6.8.0/drivers/clk/qcom/gdsc.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2015, 2017-2018, 2022, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef __QCOM_GDSC_H__
@@ -78,6 +79,7 @@
 struct gdsc_desc {
 	struct device *dev;
 	struct gdsc **scs;
+	struct dev_pm_domain_list *pmdomains;
 	size_t num;
 };
 
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-msm8998.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-msm8998.c
@@ -334,7 +334,7 @@
 	/* tweak droop detector (GPUCC_GPU_DD_WRAP_CTRL) to reduce leakage */
 	regmap_write_bits(regmap, gfx3d_clk.clkr.enable_reg, BIT(0), BIT(0));
 
-	return qcom_cc_really_probe(pdev, &gpucc_msm8998_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpucc_msm8998_desc, regmap);
 }
 
 static struct platform_driver gpucc_msm8998_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-qcs615.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-qcs615.c
@@ -0,0 +1,525 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,qcs615-gpucc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_BI_TCXO,
+	DT_GPLL0_OUT_MAIN,
+	DT_GPLL0_OUT_MAIN_DIV,
+};
+
+enum {
+	P_BI_TCXO,
+	P_GPLL0_OUT_MAIN,
+	P_GPLL0_OUT_MAIN_DIV,
+	P_GPU_CC_PLL0_2X_CLK,
+	P_CRC_DIV_PLL0_OUT_AUX2,
+	P_GPU_CC_PLL0_OUT_MAIN,
+	P_GPU_CC_PLL1_OUT_AUX,
+	P_CRC_DIV_PLL1_OUT_AUX2,
+	P_GPU_CC_PLL1_OUT_MAIN,
+};
+
+static const struct pll_vco gpu_cc_pll0_vco[] = {
+	{ 1000000000, 2100000000, 0 },
+};
+
+static struct pll_vco gpu_cc_pll1_vco[] = {
+	{ 500000000,  1000000000, 2 },
+};
+
+/* 1020MHz configuration VCO - 0 */
+static struct alpha_pll_config gpu_cc_pll0_config = {
+	.l = 0x35,
+	.config_ctl_val = 0x4001055b,
+	.test_ctl_hi_val = 0x1,
+	.test_ctl_hi_mask = 0x1,
+	.alpha_hi = 0x20,
+	.alpha = 0x00,
+	.alpha_en_mask = BIT(24),
+	.vco_val = 0x0,
+	.vco_mask = GENMASK(21, 20),
+	.aux2_output_mask = BIT(2),
+};
+
+static struct clk_alpha_pll gpu_cc_pll0 = {
+	.offset = 0x0,
+	.vco_table = gpu_cc_pll0_vco,
+	.num_vco = ARRAY_SIZE(gpu_cc_pll0_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_slew_ops,
+		},
+	},
+};
+
+/* 930MHz configuration VCO - 2 */
+static struct alpha_pll_config gpu_cc_pll1_config = {
+	.l = 0x30,
+	.config_ctl_val = 0x4001055b,
+	.test_ctl_hi_val = 0x1,
+	.test_ctl_hi_mask = 0x1,
+	.alpha_hi = 0x70,
+	.alpha = 0x00,
+	.alpha_en_mask = BIT(24),
+	.vco_val = BIT(21),
+	.vco_mask = GENMASK(21, 20),
+	.aux2_output_mask = BIT(2),
+};
+
+static struct clk_alpha_pll gpu_cc_pll1 = {
+	.offset = 0x100,
+	.vco_table = gpu_cc_pll1_vco,
+	.num_vco = ARRAY_SIZE(gpu_cc_pll1_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_pll1",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_slew_ops,
+		},
+	}
+};
+
+/* Clock Ramp Controller */
+static struct clk_fixed_factor crc_div_pll0 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "crc_div_pll0",
+			.parent_data = &(const struct clk_parent_data){
+				.hw = &gpu_cc_pll0.clkr.hw,
+			},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+/* Clock Ramp Controller */
+static struct clk_fixed_factor crc_div_pll1 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data){
+		.name = "crc_div_pll1",
+			.parent_data = &(const struct clk_parent_data){
+				.hw = &gpu_cc_pll1.clkr.hw,
+			},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+static const struct parent_map gpu_cc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPU_CC_PLL0_OUT_MAIN, 1 },
+	{ P_GPU_CC_PLL1_OUT_MAIN, 3 },
+	{ P_GPLL0_OUT_MAIN, 5 },
+	{ P_GPLL0_OUT_MAIN_DIV, 6 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gpu_cc_pll0.clkr.hw },
+	{ .hw = &gpu_cc_pll1.clkr.hw },
+	{ .index = DT_GPLL0_OUT_MAIN },
+	{ .index = DT_GPLL0_OUT_MAIN_DIV },
+};
+
+static const struct parent_map gpu_cc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPU_CC_PLL0_2X_CLK, 1 },
+	{ P_CRC_DIV_PLL0_OUT_AUX2, 2 },
+	{ P_GPU_CC_PLL1_OUT_AUX, 3 },
+	{ P_CRC_DIV_PLL1_OUT_AUX2, 4 },
+	{ P_GPLL0_OUT_MAIN, 5 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gpu_cc_pll0.clkr.hw },
+	{ .hw = &crc_div_pll0.hw },
+	{ .hw = &gpu_cc_pll1.clkr.hw },
+	{ .hw = &crc_div_pll1.hw },
+	{ .index = DT_GPLL0_OUT_MAIN },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
+	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gpu_cc_gmu_clk_src = {
+	.cmd_rcgr = 0x1120,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gpu_cc_parent_map_0,
+	.freq_tbl = ftbl_gpu_cc_gmu_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpu_cc_gmu_clk_src",
+		.parent_data = gpu_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = {
+	F(290000000, P_CRC_DIV_PLL1_OUT_AUX2, 1, 0, 0),
+	F(350000000, P_CRC_DIV_PLL1_OUT_AUX2, 1, 0, 0),
+	F(435000000, P_CRC_DIV_PLL1_OUT_AUX2, 1, 0, 0),
+	F(500000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0),
+	F(550000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0),
+	F(650000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0),
+	F(700000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0),
+	F(745000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0),
+	F(845000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0),
+	F(895000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = {
+	.cmd_rcgr = 0x101c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gpu_cc_parent_map_1,
+	.freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpu_cc_gx_gfx3d_clk_src",
+		.parent_data = gpu_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_branch gpu_cc_crc_ahb_clk = {
+	.halt_reg = 0x107c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x107c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_crc_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_gfx3d_clk = {
+	.halt_reg = 0x10a4,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x10a4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_cx_gfx3d_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_gx_gfx3d_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_gfx3d_slv_clk = {
+	.halt_reg = 0x10a8,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x10a8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_cx_gfx3d_slv_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_gx_gfx3d_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_gmu_clk = {
+	.halt_reg = 0x1098,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1098,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_cx_gmu_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_gmu_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
+	.halt_reg = 0x108c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x108c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_cx_snoc_dvm_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cxo_aon_clk = {
+	.halt_reg = 0x1004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x1004,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "gpu_cc_cxo_aon_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cxo_clk = {
+	.halt_reg = 0x109c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x109c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_cxo_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_gx_gfx3d_clk = {
+	.halt_reg = 0x1054,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x1054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_gx_gfx3d_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_gx_gfx3d_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_gx_gmu_clk = {
+	.halt_reg = 0x1064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_gx_gmu_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_gmu_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = {
+	.halt_reg = 0x5000,
+	.halt_check = BRANCH_VOTED,
+	.clkr = {
+		.enable_reg = 0x5000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_hlos1_vote_gpu_smmu_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_sleep_clk = {
+	.halt_reg = 0x1090,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x1090,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_sleep_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_hw *gpu_cc_qcs615_hws[] = {
+	[CRC_DIV_PLL0] = &crc_div_pll0.hw,
+	[CRC_DIV_PLL1] = &crc_div_pll1.hw,
+};
+
+static struct gdsc cx_gdsc = {
+	.gdscr = 0x106c,
+	.gds_hw_ctrl = 0x1540,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x8,
+	.pd = {
+		.name = "cx_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR,
+};
+
+static struct gdsc gx_gdsc = {
+	.gdscr = 0x100c,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.pd = {
+		.name = "gx_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR,
+};
+
+static struct clk_regmap *gpu_cc_qcs615_clocks[] = {
+	[GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
+	[GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr,
+	[GPU_CC_CX_GFX3D_SLV_CLK] = &gpu_cc_cx_gfx3d_slv_clk.clkr,
+	[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
+	[GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
+	[GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
+	[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
+	[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
+	[GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr,
+	[GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr,
+	[GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
+	[GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr,
+	[GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
+	[GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
+	[GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr,
+};
+
+static struct gdsc *gpu_cc_qcs615_gdscs[] = {
+	[CX_GDSC] = &cx_gdsc,
+	[GX_GDSC] = &gx_gdsc,
+};
+
+static const struct qcom_reset_map gpu_cc_qcs615_resets[] = {
+	[GPU_CC_CX_BCR] = { 0x1068 },
+	[GPU_CC_GFX3D_AON_BCR] = { 0x10a0 },
+	[GPU_CC_GMU_BCR] = { 0x111c },
+	[GPU_CC_GX_BCR] = { 0x1008 },
+	[GPU_CC_XO_BCR] = { 0x1000 },
+};
+
+static const struct regmap_config gpu_cc_qcs615_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x7008,
+	.fast_io = true,
+};
+
+static const struct qcom_cc_desc gpu_cc_qcs615_desc = {
+	.config = &gpu_cc_qcs615_regmap_config,
+	.clks = gpu_cc_qcs615_clocks,
+	.num_clks = ARRAY_SIZE(gpu_cc_qcs615_clocks),
+	.clk_hws = gpu_cc_qcs615_hws,
+	.num_clk_hws = ARRAY_SIZE(gpu_cc_qcs615_hws),
+	.resets = gpu_cc_qcs615_resets,
+	.num_resets = ARRAY_SIZE(gpu_cc_qcs615_resets),
+	.gdscs = gpu_cc_qcs615_gdscs,
+	.num_gdscs = ARRAY_SIZE(gpu_cc_qcs615_gdscs),
+};
+
+static const struct of_device_id gpu_cc_qcs615_match_table[] = {
+	{ .compatible = "qcom,qcs615-gpucc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, gpu_cc_qcs615_match_table);
+
+static void configure_crc(struct regmap *regmap)
+{
+	/* Recommended WAKEUP/SLEEP settings for the gpu_cc_cx_gmu_clk */
+	regmap_update_bits(regmap, gpu_cc_cx_gmu_clk.clkr.enable_reg, 0xff0, 0xff0);
+
+	/*
+	 * After POR, Clock Ramp Controller(CRC) will be in bypass mode.
+	 * Software needs to do the following operation to enable the CRC
+	 * for GFX3D clock and divide the input clock by div by 2.
+	 */
+	regmap_update_bits(regmap, 0x1028, 0x00015011, 0x00015011);
+	regmap_update_bits(regmap, 0x1024, 0x00800000, 0x00800000);
+}
+
+static int gpu_cc_qcs615_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+
+	regmap = qcom_cc_map(pdev, &gpu_cc_qcs615_desc);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	clk_alpha_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
+	clk_alpha_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
+
+	/* Keep some clocks always enabled */
+	regmap_update_bits(regmap, 0x1078, BIT(0), BIT(0)); /* GPU_CC_AHB_CLK */
+
+	configure_crc(regmap);
+
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_qcs615_desc, regmap);
+}
+
+static struct platform_driver gpu_cc_qcs615_driver = {
+	.probe = gpu_cc_qcs615_probe,
+	.driver = {
+		.name = "gpucc-qcs615",
+		.of_match_table = gpu_cc_qcs615_match_table,
+	},
+};
+
+module_platform_driver(gpu_cc_qcs615_driver);
+
+MODULE_DESCRIPTION("QTI GPUCC QCS615 Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sa8775p.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sa8775p.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022, 2024, Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2023, Linaro Limited
  */
 
@@ -161,7 +161,7 @@
 		.name = "gpu_cc_ff_clk_src",
 		.parent_data = gpu_cc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_rcg2_shared_ops,
 	},
 };
 
@@ -181,7 +181,7 @@
 		.parent_data = gpu_cc_parent_data_1,
 		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_rcg2_shared_ops,
 	},
 };
 
@@ -200,7 +200,7 @@
 		.name = "gpu_cc_hub_clk_src",
 		.parent_data = gpu_cc_parent_data_2,
 		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_2),
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_rcg2_shared_ops,
 	},
 };
 
@@ -280,7 +280,7 @@
 				&gpu_cc_hub_ahb_div_clk_src.clkr.hw,
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+			.flags = CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -294,8 +294,7 @@
 		.enable_mask = BIT(0),
 		.hw.init = &(const struct clk_init_data){
 			.name = "gpu_cc_cb_clk",
-			.flags = CLK_IS_CRITICAL,
-			.ops = &clk_branch2_ops,
+			.ops = &clk_branch2_aon_ops,
 		},
 	},
 };
@@ -312,7 +311,25 @@
 				&gpu_cc_hub_ahb_div_clk_src.clkr.hw,
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_accu_shift_clk = {
+	.halt_reg = 0x95e8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x95e8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data){
+			.name = "gpu_cc_cx_accu_shift_clk",
+			.parent_hws = (const struct clk_hw*[]){
+				&gpu_cc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -330,7 +347,7 @@
 				&gpu_cc_ff_clk_src.clkr.hw,
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+			.flags = CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -348,7 +365,7 @@
 				&gpu_cc_gmu_clk_src.clkr.hw,
 			},
 			.num_parents = 1,
-			.flags =  CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+			.flags =  CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_aon_ops,
 		},
 	},
@@ -362,7 +379,6 @@
 		.enable_mask = BIT(0),
 		.hw.init = &(const struct clk_init_data){
 			.name = "gpu_cc_cx_snoc_dvm_clk",
-			.flags = CLK_IS_CRITICAL,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -380,7 +396,7 @@
 				&gpu_cc_xo_clk_src.clkr.hw,
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+			.flags = CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -398,7 +414,7 @@
 				&gpu_cc_xo_clk_src.clkr.hw,
 			},
 			.num_parents = 1,
-			.flags =  CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+			.flags =  CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -416,12 +432,30 @@
 				&gpu_cc_demet_div_clk_src.clkr.hw,
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+			.flags = CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_aon_ops,
 		},
 	},
 };
 
+static struct clk_branch gpu_cc_gx_accu_shift_clk = {
+	.halt_reg = 0x95e4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x95e4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data){
+			.name = "gpu_cc_gx_accu_shift_clk",
+			.parent_hws = (const struct clk_hw*[]){
+				&gpu_cc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
 static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = {
 	.halt_reg = 0x7000,
 	.halt_check = BRANCH_HALT_VOTED,
@@ -430,7 +464,6 @@
 		.enable_mask = BIT(0),
 		.hw.init = &(const struct clk_init_data){
 			.name = "gpu_cc_hlos1_vote_gpu_smmu_clk",
-			.flags = CLK_IS_CRITICAL,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -448,7 +481,7 @@
 				&gpu_cc_hub_clk_src.clkr.hw,
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+			.flags = CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_aon_ops,
 		},
 	},
@@ -466,7 +499,7 @@
 				&gpu_cc_hub_cx_int_div_clk_src.clkr.hw,
 			},
 			.num_parents = 1,
-			.flags =  CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+			.flags =  CLK_SET_RATE_PARENT,
 			.ops = &clk_branch2_aon_ops,
 		},
 	},
@@ -480,7 +513,6 @@
 		.enable_mask = BIT(0),
 		.hw.init = &(const struct clk_init_data){
 			.name = "gpu_cc_memnoc_gfx_clk",
-			.flags = CLK_IS_CRITICAL,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -494,7 +526,6 @@
 		.enable_mask = BIT(0),
 		.hw.init = &(const struct clk_init_data){
 			.name = "gpu_cc_sleep_clk",
-			.flags = CLK_IS_CRITICAL,
 			.ops = &clk_branch2_ops,
 		},
 	},
@@ -504,6 +535,7 @@
 	[GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
 	[GPU_CC_CB_CLK] = &gpu_cc_cb_clk.clkr,
 	[GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
+	[GPU_CC_CX_ACCU_SHIFT_CLK] = NULL,
 	[GPU_CC_CX_FF_CLK] = &gpu_cc_cx_ff_clk.clkr,
 	[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
 	[GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
@@ -513,6 +545,7 @@
 	[GPU_CC_DEMET_DIV_CLK_SRC] = &gpu_cc_demet_div_clk_src.clkr,
 	[GPU_CC_FF_CLK_SRC] = &gpu_cc_ff_clk_src.clkr,
 	[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
+	[GPU_CC_GX_ACCU_SHIFT_CLK] = NULL,
 	[GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr,
 	[GPU_CC_HUB_AHB_DIV_CLK_SRC] = &gpu_cc_hub_ahb_div_clk_src.clkr,
 	[GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr,
@@ -528,16 +561,22 @@
 
 static struct gdsc cx_gdsc = {
 	.gdscr = 0x9108,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.gds_hw_ctrl = 0x953c,
 	.pd = {
 		.name = "cx_gdsc",
 	},
 	.pwrsts = PWRSTS_OFF_ON,
-	.flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON,
+	.flags = VOTABLE | RETAIN_FF_ENABLE,
 };
 
 static struct gdsc gx_gdsc = {
 	.gdscr = 0x905c,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
 	.pd = {
 		.name = "gx_gdsc",
 		.power_on = gdsc_gx_do_nothing_enable,
@@ -582,6 +621,7 @@
 };
 
 static const struct of_device_id gpu_cc_sa8775p_match_table[] = {
+	{ .compatible = "qcom,qcs8300-gpucc" },
 	{ .compatible = "qcom,sa8775p-gpucc" },
 	{ }
 };
@@ -595,10 +635,18 @@
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
+	if (of_device_is_compatible(pdev->dev.of_node, "qcom,qcs8300-gpucc")) {
+		gpu_cc_pll0_config.l = 0x31;
+		gpu_cc_pll0_config.alpha = 0xe555;
+
+		gpu_cc_sa8775p_clocks[GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_clk.clkr;
+		gpu_cc_sa8775p_clocks[GPU_CC_GX_ACCU_SHIFT_CLK] = &gpu_cc_gx_accu_shift_clk.clkr;
+	}
+
 	clk_lucid_evo_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
 	clk_lucid_evo_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
 
-	return qcom_cc_really_probe(pdev, &gpu_cc_sa8775p_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sa8775p_desc, regmap);
 }
 
 static struct platform_driver gpu_cc_sa8775p_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sc7180.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sc7180.c
@@ -241,7 +241,7 @@
 	value = 0xF << CX_GMU_CBCR_WAKE_SHIFT | 0xF << CX_GMU_CBCR_SLEEP_SHIFT;
 	regmap_update_bits(regmap, 0x1098, mask, value);
 
-	return qcom_cc_really_probe(pdev, &gpu_cc_sc7180_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sc7180_desc, regmap);
 }
 
 static struct platform_driver gpu_cc_sc7180_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sc7280.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sc7280.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/clk-provider.h>
@@ -379,6 +380,9 @@
 
 static struct gdsc cx_gdsc = {
 	.gdscr = 0x106c,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
 	.gds_hw_ctrl = 0x1540,
 	.pd = {
 		.name = "cx_gdsc",
@@ -389,6 +393,9 @@
 
 static struct gdsc gx_gdsc = {
 	.gdscr = 0x100c,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
 	.clamp_io_ctrl = 0x1508,
 	.pd = {
 		.name = "gx_gdsc",
@@ -465,7 +472,7 @@
 	regmap_update_bits(regmap, 0x1098, BIT(0), BIT(0));
 	regmap_update_bits(regmap, 0x1098, BIT(13), BIT(13));
 
-	return qcom_cc_really_probe(pdev, &gpu_cc_sc7280_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sc7280_desc, regmap);
 }
 
 static struct platform_driver gpu_cc_sc7280_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sc8280xp.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sc8280xp.c
@@ -451,7 +451,7 @@
 	regmap_update_bits(regmap, 0x1170, BIT(0), BIT(0));
 	regmap_update_bits(regmap, 0x109c, BIT(0), BIT(0));
 
-	ret = qcom_cc_really_probe(pdev, &gpu_cc_sc8280xp_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &gpu_cc_sc8280xp_desc, regmap);
 	pm_runtime_put(&pdev->dev);
 
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sdm660.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sdm660.c
@@ -330,7 +330,7 @@
 	gpu_pll_config.alpha_hi = 0x8a;
 	clk_alpha_pll_configure(&gpu_pll1_pll_out_main, regmap, &gpu_pll_config);
 
-	return qcom_cc_really_probe(pdev, &gpucc_sdm660_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpucc_sdm660_desc, regmap);
 }
 
 static struct platform_driver gpucc_sdm660_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sdm845.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sdm845.c
@@ -192,7 +192,7 @@
 	value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT;
 	regmap_update_bits(regmap, 0x1098, mask, value);
 
-	return qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sdm845_desc, regmap);
 }
 
 static struct platform_driver gpu_cc_sdm845_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sm6115.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sm6115.c
@@ -488,7 +488,7 @@
 	qcom_branch_set_force_mem_core(regmap, gpu_cc_gx_gfx3d_clk, true);
 	qcom_branch_set_force_periph_on(regmap, gpu_cc_gx_gfx3d_clk, true);
 
-	return qcom_cc_really_probe(pdev, &gpu_cc_sm6115_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm6115_desc, regmap);
 }
 
 static struct platform_driver gpu_cc_sm6115_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sm6125.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sm6125.c
@@ -409,7 +409,7 @@
 	qcom_branch_set_force_mem_core(regmap, gpu_cc_gx_gfx3d_clk, true);
 	qcom_branch_set_force_periph_on(regmap, gpu_cc_gx_gfx3d_clk, true);
 
-	return qcom_cc_really_probe(pdev, &gpu_cc_sm6125_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm6125_desc, regmap);
 }
 
 static struct platform_driver gpu_cc_sm6125_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sm6350.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sm6350.c
@@ -502,7 +502,7 @@
 	value = 0xF << CX_GMU_CBCR_WAKE_SHIFT | 0xF << CX_GMU_CBCR_SLEEP_SHIFT;
 	regmap_update_bits(regmap, 0x1098, mask, value);
 
-	return qcom_cc_really_probe(pdev, &gpu_cc_sm6350_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm6350_desc, regmap);
 }
 
 static struct platform_driver gpu_cc_sm6350_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sm6375.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sm6375.c
@@ -455,7 +455,7 @@
 	clk_lucid_pll_configure(&gpucc_pll0, regmap, &gpucc_pll0_config);
 	clk_lucid_pll_configure(&gpucc_pll1, regmap, &gpucc_pll1_config);
 
-	ret = qcom_cc_really_probe(pdev, &gpucc_sm6375_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &gpucc_sm6375_desc, regmap);
 	pm_runtime_put(&pdev->dev);
 
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sm8150.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sm8150.c
@@ -304,7 +304,7 @@
 
 	clk_trion_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
 
-	return qcom_cc_really_probe(pdev, &gpu_cc_sm8150_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8150_desc, regmap);
 }
 
 static struct platform_driver gpu_cc_sm8150_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sm8250.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sm8250.c
@@ -320,7 +320,7 @@
 	value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT;
 	regmap_update_bits(regmap, 0x1098, mask, value);
 
-	return qcom_cc_really_probe(pdev, &gpu_cc_sm8250_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8250_desc, regmap);
 }
 
 static struct platform_driver gpu_cc_sm8250_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sm8350.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sm8350.c
@@ -2,6 +2,7 @@
 /*
  * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
  * Copyright (c) 2022, Linaro Limited
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/clk.h>
@@ -147,7 +148,7 @@
 		.parent_data = gpu_cc_parent_data_0,
 		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_rcg2_shared_ops,
 	},
 };
 
@@ -169,7 +170,7 @@
 		.parent_data = gpu_cc_parent_data_1,
 		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
 		.flags = CLK_SET_RATE_PARENT,
-		.ops = &clk_rcg2_ops,
+		.ops = &clk_rcg2_shared_ops,
 	},
 };
 
@@ -604,7 +605,7 @@
 	clk_lucid_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
 	clk_lucid_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
 
-	return qcom_cc_really_probe(pdev, &gpu_cc_sm8350_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8350_desc, regmap);
 }
 
 static const struct of_device_id gpu_cc_sm8350_match_table[] = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sm8450.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sm8450.c
@@ -751,7 +751,7 @@
 	clk_lucid_evo_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
 	clk_lucid_evo_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
 
-	return qcom_cc_really_probe(pdev, &gpu_cc_sm8450_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8450_desc, regmap);
 }
 
 static struct platform_driver gpu_cc_sm8450_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sm8550.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sm8550.c
@@ -583,7 +583,7 @@
 	regmap_update_bits(regmap, 0x9004, BIT(0), BIT(0));
 	regmap_update_bits(regmap, 0x900c, BIT(0), BIT(0));
 
-	return qcom_cc_really_probe(pdev, &gpu_cc_sm8550_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8550_desc, regmap);
 }
 
 static struct platform_driver gpu_cc_sm8550_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-sm8650.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-sm8650.c
@@ -647,7 +647,7 @@
 	clk_lucid_ole_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
 	clk_lucid_ole_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
 
-	return qcom_cc_really_probe(pdev, &gpu_cc_sm8650_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8650_desc, regmap);
 }
 
 static struct platform_driver gpu_cc_sm8650_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/gpucc-x1e80100.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/gpucc-x1e80100.c
@@ -0,0 +1,656 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,x1e80100-gpucc.h>
+#include <dt-bindings/reset/qcom,x1e80100-gpucc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_BI_TCXO,
+	DT_GPLL0_OUT_MAIN,
+	DT_GPLL0_OUT_MAIN_DIV,
+};
+
+enum {
+	P_BI_TCXO,
+	P_GPLL0_OUT_MAIN,
+	P_GPLL0_OUT_MAIN_DIV,
+	P_GPU_CC_PLL0_OUT_MAIN,
+	P_GPU_CC_PLL1_OUT_MAIN,
+};
+
+static const struct pll_vco lucid_ole_vco[] = {
+	{ 249600000, 2300000000, 0 },
+};
+
+static const struct pll_vco zonda_ole_vco[] = {
+	{ 700000000, 3600000000, 0 },
+};
+
+static const struct alpha_pll_config gpu_cc_pll0_config = {
+	.l = 0x29,
+	.alpha = 0xa000,
+	.config_ctl_val = 0x08240800,
+	.config_ctl_hi_val = 0x05008001,
+	.config_ctl_hi1_val = 0x00000000,
+	.config_ctl_hi2_val = 0x00000000,
+	.user_ctl_val = 0x00000000,
+	.user_ctl_hi_val = 0x02000000,
+};
+
+static struct clk_alpha_pll gpu_cc_pll0 = {
+	.offset = 0x0,
+	.vco_table = zonda_ole_vco,
+	.num_vco = ARRAY_SIZE(zonda_ole_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_ZONDA_OLE],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_zonda_ole_ops,
+		},
+	},
+};
+
+static const struct alpha_pll_config gpu_cc_pll1_config = {
+	.l = 0x16,
+	.alpha = 0xeaaa,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x82aa299c,
+	.test_ctl_val = 0x00000000,
+	.test_ctl_hi_val = 0x00000003,
+	.test_ctl_hi1_val = 0x00009000,
+	.test_ctl_hi2_val = 0x00000034,
+	.user_ctl_val = 0x00000000,
+	.user_ctl_hi_val = 0x00000005,
+};
+
+static struct clk_alpha_pll gpu_cc_pll1 = {
+	.offset = 0x1000,
+	.vco_table = lucid_ole_vco,
+	.num_vco = ARRAY_SIZE(lucid_ole_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_pll1",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct parent_map gpu_cc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPLL0_OUT_MAIN, 5 },
+	{ P_GPLL0_OUT_MAIN_DIV, 6 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_GPLL0_OUT_MAIN },
+	{ .index = DT_GPLL0_OUT_MAIN_DIV },
+};
+
+static const struct parent_map gpu_cc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPU_CC_PLL0_OUT_MAIN, 1 },
+	{ P_GPU_CC_PLL1_OUT_MAIN, 3 },
+	{ P_GPLL0_OUT_MAIN, 5 },
+	{ P_GPLL0_OUT_MAIN_DIV, 6 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gpu_cc_pll0.clkr.hw },
+	{ .hw = &gpu_cc_pll1.clkr.hw },
+	{ .index = DT_GPLL0_OUT_MAIN },
+	{ .index = DT_GPLL0_OUT_MAIN_DIV },
+};
+
+static const struct parent_map gpu_cc_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPU_CC_PLL1_OUT_MAIN, 3 },
+	{ P_GPLL0_OUT_MAIN, 5 },
+	{ P_GPLL0_OUT_MAIN_DIV, 6 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gpu_cc_pll1.clkr.hw },
+	{ .index = DT_GPLL0_OUT_MAIN },
+	{ .index = DT_GPLL0_OUT_MAIN_DIV },
+};
+
+static const struct parent_map gpu_cc_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_ff_clk_src[] = {
+	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gpu_cc_ff_clk_src = {
+	.cmd_rcgr = 0x9474,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gpu_cc_parent_map_0,
+	.freq_tbl = ftbl_gpu_cc_ff_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpu_cc_ff_clk_src",
+		.parent_data = gpu_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(220000000, P_GPU_CC_PLL1_OUT_MAIN, 2, 0, 0),
+	F(550000000, P_GPU_CC_PLL1_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gpu_cc_gmu_clk_src = {
+	.cmd_rcgr = 0x9318,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gpu_cc_parent_map_1,
+	.freq_tbl = ftbl_gpu_cc_gmu_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpu_cc_gmu_clk_src",
+		.parent_data = gpu_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 gpu_cc_hub_clk_src = {
+	.cmd_rcgr = 0x93ec,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gpu_cc_parent_map_2,
+	.freq_tbl = ftbl_gpu_cc_ff_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpu_cc_hub_clk_src",
+		.parent_data = gpu_cc_parent_data_2,
+		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 gpu_cc_xo_clk_src = {
+	.cmd_rcgr = 0x9010,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gpu_cc_parent_map_3,
+	.freq_tbl = NULL,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpu_cc_xo_clk_src",
+		.parent_data = gpu_cc_parent_data_3,
+		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_regmap_div gpu_cc_demet_div_clk_src = {
+	.reg = 0x9054,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpu_cc_demet_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gpu_cc_xo_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div gpu_cc_xo_div_clk_src = {
+	.reg = 0x9050,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpu_cc_xo_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gpu_cc_xo_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_branch gpu_cc_ahb_clk = {
+	.halt_reg = 0x911c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x911c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_hub_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_crc_ahb_clk = {
+	.halt_reg = 0x9120,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9120,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_crc_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_hub_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_ff_clk = {
+	.halt_reg = 0x914c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x914c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_cx_ff_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_ff_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_gmu_clk = {
+	.halt_reg = 0x913c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x913c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_cx_gmu_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_gmu_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_aon_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cxo_aon_clk = {
+	.halt_reg = 0x9004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_cxo_aon_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cxo_clk = {
+	.halt_reg = 0x9144,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9144,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_cxo_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_demet_clk = {
+	.halt_reg = 0x900c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x900c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_demet_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_demet_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_aon_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_freq_measure_clk = {
+	.halt_reg = 0x9008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_freq_measure_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_xo_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = {
+	.halt_reg = 0x7000,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x7000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_hlos1_vote_gpu_smmu_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_gx_gmu_clk = {
+	.halt_reg = 0x90bc,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x90bc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_gx_gmu_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_gmu_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_gx_vsense_clk = {
+	.halt_reg = 0x90b0,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x90b0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_gx_vsense_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_hub_aon_clk = {
+	.halt_reg = 0x93e8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x93e8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_hub_aon_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_hub_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_aon_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_hub_cx_int_clk = {
+	.halt_reg = 0x9148,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9148,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_hub_cx_int_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gpu_cc_hub_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_aon_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_memnoc_gfx_clk = {
+	.halt_reg = 0x9150,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9150,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_memnoc_gfx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_mnd1x_0_gfx3d_clk = {
+	.halt_reg = 0x9288,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9288,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_mnd1x_0_gfx3d_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_mnd1x_1_gfx3d_clk = {
+	.halt_reg = 0x928c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x928c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_mnd1x_1_gfx3d_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_sleep_clk = {
+	.halt_reg = 0x9134,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9134,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_sleep_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc gpu_cx_gdsc = {
+	.gdscr = 0x9108,
+	.gds_hw_ctrl = 0x953c,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "gpu_cx_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc gpu_gx_gdsc = {
+	.gdscr = 0x905c,
+	.clamp_io_ctrl = 0x9504,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "gpu_gx_gdsc",
+		.power_on = gdsc_gx_do_nothing_enable,
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = CLAMP_IO | AON_RESET | SW_RESET | POLL_CFG_GDSCR,
+};
+
+static struct clk_regmap *gpu_cc_x1e80100_clocks[] = {
+	[GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
+	[GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
+	[GPU_CC_CX_FF_CLK] = &gpu_cc_cx_ff_clk.clkr,
+	[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
+	[GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
+	[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
+	[GPU_CC_DEMET_CLK] = &gpu_cc_demet_clk.clkr,
+	[GPU_CC_DEMET_DIV_CLK_SRC] = &gpu_cc_demet_div_clk_src.clkr,
+	[GPU_CC_FF_CLK_SRC] = &gpu_cc_ff_clk_src.clkr,
+	[GPU_CC_FREQ_MEASURE_CLK] = &gpu_cc_freq_measure_clk.clkr,
+	[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
+	[GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
+	[GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr,
+	[GPU_CC_GX_VSENSE_CLK] = &gpu_cc_gx_vsense_clk.clkr,
+	[GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr,
+	[GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr,
+	[GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr,
+	[GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr,
+	[GPU_CC_MND1X_0_GFX3D_CLK] = &gpu_cc_mnd1x_0_gfx3d_clk.clkr,
+	[GPU_CC_MND1X_1_GFX3D_CLK] = &gpu_cc_mnd1x_1_gfx3d_clk.clkr,
+	[GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
+	[GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
+	[GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr,
+	[GPU_CC_XO_CLK_SRC] = &gpu_cc_xo_clk_src.clkr,
+	[GPU_CC_XO_DIV_CLK_SRC] = &gpu_cc_xo_div_clk_src.clkr,
+};
+
+static const struct qcom_reset_map gpu_cc_x1e80100_resets[] = {
+	[GPUCC_GPU_CC_XO_BCR] = { 0x9000 },
+	[GPUCC_GPU_CC_GX_BCR] = { 0x9058 },
+	[GPUCC_GPU_CC_CX_BCR] = { 0x9104 },
+	[GPUCC_GPU_CC_GFX3D_AON_BCR] = { 0x9198 },
+	[GPUCC_GPU_CC_ACD_BCR] = { 0x9358 },
+	[GPUCC_GPU_CC_FAST_HUB_BCR] = { 0x93e4 },
+	[GPUCC_GPU_CC_FF_BCR] = { 0x9470 },
+	[GPUCC_GPU_CC_GMU_BCR] = { 0x9314 },
+	[GPUCC_GPU_CC_CB_BCR] = { 0x93a0 },
+};
+
+static struct gdsc *gpu_cc_x1e80100_gdscs[] = {
+	[GPU_CX_GDSC] = &gpu_cx_gdsc,
+	[GPU_GX_GDSC] = &gpu_gx_gdsc,
+};
+
+static const struct regmap_config gpu_cc_x1e80100_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x9988,
+	.fast_io = true,
+};
+
+static const struct qcom_cc_desc gpu_cc_x1e80100_desc = {
+	.config = &gpu_cc_x1e80100_regmap_config,
+	.clks = gpu_cc_x1e80100_clocks,
+	.num_clks = ARRAY_SIZE(gpu_cc_x1e80100_clocks),
+	.resets = gpu_cc_x1e80100_resets,
+	.num_resets = ARRAY_SIZE(gpu_cc_x1e80100_resets),
+	.gdscs = gpu_cc_x1e80100_gdscs,
+	.num_gdscs = ARRAY_SIZE(gpu_cc_x1e80100_gdscs),
+};
+
+static const struct of_device_id gpu_cc_x1e80100_match_table[] = {
+	{ .compatible = "qcom,x1e80100-gpucc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, gpu_cc_x1e80100_match_table);
+
+static int gpu_cc_x1e80100_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+
+	regmap = qcom_cc_map(pdev, &gpu_cc_x1e80100_desc);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	clk_zonda_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
+	clk_lucid_evo_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
+
+	/* Keep clocks always enabled */
+	regmap_update_bits(regmap, 0x93a4, BIT(0), BIT(0)); /* gpu_cc_cb_clk */
+
+	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_x1e80100_desc, regmap);
+}
+
+static struct platform_driver gpu_cc_x1e80100_driver = {
+	.probe = gpu_cc_x1e80100_probe,
+	.driver = {
+		.name = "gpucc-x1e80100",
+		.of_match_table = gpu_cc_x1e80100_match_table,
+	},
+};
+module_platform_driver(gpu_cc_x1e80100_driver);
+
+MODULE_DESCRIPTION("QTI GPU Clock Controller X1E80100 Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/kpss-xcc.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/kpss-xcc.c
@@ -58,9 +58,7 @@
 	if (IS_ERR(hw))
 		return PTR_ERR(hw);
 
-	of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, hw);
-
-	return 0;
+	return of_clk_add_hw_provider(dev->of_node, of_clk_hw_simple_get, hw);
 }
 
 static struct platform_driver kpss_xcc_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/lcc-ipq806x.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/lcc-ipq806x.c
@@ -454,7 +454,7 @@
 	/* Enable PLL4 source on the LPASS Primary PLL Mux */
 	regmap_write(regmap, 0xc4, 0x1);
 
-	return qcom_cc_really_probe(pdev, &lcc_ipq806x_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &lcc_ipq806x_desc, regmap);
 }
 
 static struct platform_driver lcc_ipq806x_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/lcc-msm8960.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/lcc-msm8960.c
@@ -481,7 +481,7 @@
 	/* Enable PLL4 source on the LPASS Primary PLL Mux */
 	regmap_write(regmap, 0xc4, 0x1);
 
-	return qcom_cc_really_probe(pdev, &lcc_msm8960_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &lcc_msm8960_desc, regmap);
 }
 
 static struct platform_driver lcc_msm8960_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/lpassaudiocc-sc7280.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/lpassaudiocc-sc7280.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/clk-provider.h>
@@ -766,18 +767,23 @@
 		goto exit;
 	}
 
-	clk_zonda_pll_configure(&lpass_audio_cc_pll, regmap, &lpass_audio_cc_pll_config);
+	if (!of_property_read_bool(pdev->dev.of_node, "qcom,adsp-skip-pll")) {
+		clk_zonda_pll_configure(&lpass_audio_cc_pll, regmap, &lpass_audio_cc_pll_config);
 
-	/* PLL settings */
-	regmap_write(regmap, 0x4, 0x3b);
-	regmap_write(regmap, 0x8, 0xff05);
+		/* PLL settings */
+		regmap_write(regmap, 0x4, 0x3b);
+		regmap_write(regmap, 0x8, 0xff05);
+	}
 
-	ret = qcom_cc_really_probe(pdev, &lpass_audio_cc_sc7280_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &lpass_audio_cc_sc7280_desc, regmap);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC clocks\n");
 		goto exit;
 	}
 
+	lpass_audio_cc_sc7280_regmap_config.name = "lpassaudio_cc_reset";
+	lpass_audio_cc_sc7280_regmap_config.max_register = 0xc8;
+
 	ret = qcom_cc_probe_by_index(pdev, 1, &lpass_audio_cc_reset_sc7280_desc);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register LPASS AUDIO CC Resets\n");
@@ -847,7 +853,7 @@
 
 	clk_lucid_pll_configure(&lpass_aon_cc_pll, regmap, &lpass_aon_cc_pll_config);
 
-	ret = qcom_cc_really_probe(pdev, &lpass_aon_cc_sc7280_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &lpass_aon_cc_sc7280_desc, regmap);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to register LPASS AON CC clocks\n");
 		goto exit;
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/lpasscorecc-sc7180.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/lpasscorecc-sc7180.c
@@ -414,7 +414,7 @@
 	clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap,
 				&lpass_lpaaudio_dig_pll_config);
 
-	ret = qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &lpass_core_cc_sc7180_desc, regmap);
 
 	pm_runtime_mark_last_busy(&pdev->dev);
 exit:
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/lpasscorecc-sc7280.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/lpasscorecc-sc7280.c
@@ -406,7 +406,7 @@
 
 	clk_lucid_pll_configure(&lpass_core_cc_dig_pll, regmap, &lpass_core_cc_dig_pll_config);
 
-	return qcom_cc_really_probe(pdev, &lpass_core_cc_sc7280_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &lpass_core_cc_sc7280_desc, regmap);
 }
 
 static struct platform_driver lpass_core_cc_sc7280_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/mmcc-apq8084.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/mmcc-apq8084.c
@@ -348,6 +348,7 @@
 	F(333430000, P_MMPLL1, 3.5, 0, 0),
 	F(400000000, P_MMPLL0, 2, 0, 0),
 	F(466800000, P_MMPLL1, 2.5, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 mmss_axi_clk_src = {
@@ -372,6 +373,7 @@
 	F(150000000, P_GPLL0, 4, 0, 0),
 	F(228570000, P_MMPLL0, 3.5, 0, 0),
 	F(320000000, P_MMPLL0, 2.5, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 ocmemnoc_clk_src = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/mmcc-msm8960.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/mmcc-msm8960.c
@@ -3122,7 +3122,7 @@
 
 	clk_pll_configure_sr(&pll15, regmap, &pll15_config, false);
 
-	return qcom_cc_really_probe(pdev, desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, desc, regmap);
 }
 
 static struct platform_driver mmcc_msm8960_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/mmcc-msm8974.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/mmcc-msm8974.c
@@ -290,6 +290,7 @@
 	F(291750000, P_MMPLL1, 4, 0, 0),
 	F(400000000, P_MMPLL0, 2, 0, 0),
 	F(466800000, P_MMPLL1, 2.5, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 mmss_axi_clk_src = {
@@ -314,6 +315,7 @@
 	F(150000000, P_GPLL0, 4, 0, 0),
 	F(291750000, P_MMPLL1, 4, 0, 0),
 	F(400000000, P_MMPLL0, 2, 0, 0),
+	{ }
 };
 
 static struct clk_rcg2 ocmemnoc_clk_src = {
@@ -2766,7 +2768,7 @@
 		msm8226_clock_override();
 	}
 
-	return qcom_cc_really_probe(pdev, desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, desc, regmap);
 }
 
 static struct platform_driver mmcc_msm8974_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/mmcc-msm8994.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/mmcc-msm8994.c
@@ -2602,7 +2602,7 @@
 	clk_alpha_pll_configure(&mmpll3_early, regmap, &mmpll_p_config);
 	clk_alpha_pll_configure(&mmpll5_early, regmap, &mmpll_p_config);
 
-	return qcom_cc_really_probe(pdev, &mmcc_msm8994_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &mmcc_msm8994_desc, regmap);
 }
 
 static struct platform_driver mmcc_msm8994_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/mmcc-msm8996.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/mmcc-msm8996.c
@@ -3626,7 +3626,7 @@
 	/* Disable the NoC FSM for mmss_mmagic_cfg_ahb_clk */
 	regmap_update_bits(regmap, 0x5054, BIT(15), 0);
 
-	return qcom_cc_really_probe(pdev, &mmcc_msm8996_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &mmcc_msm8996_desc, regmap);
 }
 
 static struct platform_driver mmcc_msm8996_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/mmcc-msm8998.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/mmcc-msm8998.c
@@ -2535,6 +2535,8 @@
 
 static struct gdsc video_top_gdsc = {
 	.gdscr = 0x1024,
+	.cxcs = (unsigned int []){ 0x1028, 0x1034, 0x1038 },
+	.cxc_count = 3,
 	.pd = {
 		.name = "video_top",
 	},
@@ -2543,20 +2545,26 @@
 
 static struct gdsc video_subcore0_gdsc = {
 	.gdscr = 0x1040,
+	.cxcs = (unsigned int []){ 0x1048 },
+	.cxc_count = 1,
 	.pd = {
 		.name = "video_subcore0",
 	},
 	.parent = &video_top_gdsc.pd,
 	.pwrsts = PWRSTS_OFF_ON,
+	.flags = HW_CTRL,
 };
 
 static struct gdsc video_subcore1_gdsc = {
 	.gdscr = 0x1044,
+	.cxcs = (unsigned int []){ 0x104c },
+	.cxc_count = 1,
 	.pd = {
 		.name = "video_subcore1",
 	},
 	.parent = &video_top_gdsc.pd,
 	.pwrsts = PWRSTS_OFF_ON,
+	.flags = HW_CTRL,
 };
 
 static struct gdsc mdss_gdsc = {
@@ -2858,7 +2866,7 @@
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	return qcom_cc_really_probe(pdev, &mmcc_msm8998_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &mmcc_msm8998_desc, regmap);
 }
 
 static struct platform_driver mmcc_msm8998_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/mmcc-sdm660.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/mmcc-sdm660.c
@@ -2847,7 +2847,7 @@
 	clk_alpha_pll_configure(&mmpll8, regmap, &mmpll8_config);
 	clk_alpha_pll_configure(&mmpll10, regmap, &mmpll10_config);
 
-	return qcom_cc_really_probe(pdev, &mmcc_660_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &mmcc_660_desc, regmap);
 }
 
 static struct platform_driver mmcc_660_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/reset.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/reset.c
@@ -22,8 +22,8 @@
 	return 0;
 }
 
-static int
-qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+static int qcom_reset_set_assert(struct reset_controller_dev *rcdev,
+				 unsigned long id, bool assert)
 {
 	struct qcom_reset_controller *rst;
 	const struct qcom_reset_map *map;
@@ -33,21 +33,22 @@
 	map = &rst->reset_map[id];
 	mask = map->bitmask ? map->bitmask : BIT(map->bit);
 
-	return regmap_update_bits(rst->regmap, map->reg, mask, mask);
+	regmap_update_bits(rst->regmap, map->reg, mask, assert ? mask : 0);
+
+	/* Read back the register to ensure write completion, ignore the value */
+	regmap_read(rst->regmap, map->reg, &mask);
+
+	return 0;
 }
 
-static int
-qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+static int qcom_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
 {
-	struct qcom_reset_controller *rst;
-	const struct qcom_reset_map *map;
-	u32 mask;
-
-	rst = to_qcom_reset_controller(rcdev);
-	map = &rst->reset_map[id];
-	mask = map->bitmask ? map->bitmask : BIT(map->bit);
+	return qcom_reset_set_assert(rcdev, id, true);
+}
 
-	return regmap_update_bits(rst->regmap, map->reg, mask, 0);
+static int qcom_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+	return qcom_reset_set_assert(rcdev, id, false);
 }
 
 const struct reset_control_ops qcom_reset_ops = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/tcsrcc-sm8550.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/tcsrcc-sm8550.c
@@ -129,6 +129,13 @@
 	},
 };
 
+static struct clk_regmap *tcsr_cc_sar2130p_clocks[] = {
+	[TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr,
+	[TCSR_PCIE_1_CLKREF_EN] = &tcsr_pcie_1_clkref_en.clkr,
+	[TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr,
+	[TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr,
+};
+
 static struct clk_regmap *tcsr_cc_sm8550_clocks[] = {
 	[TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr,
 	[TCSR_PCIE_1_CLKREF_EN] = &tcsr_pcie_1_clkref_en.clkr,
@@ -146,6 +153,12 @@
 	.fast_io = true,
 };
 
+static const struct qcom_cc_desc tcsr_cc_sar2130p_desc = {
+	.config = &tcsr_cc_sm8550_regmap_config,
+	.clks = tcsr_cc_sar2130p_clocks,
+	.num_clks = ARRAY_SIZE(tcsr_cc_sar2130p_clocks),
+};
+
 static const struct qcom_cc_desc tcsr_cc_sm8550_desc = {
 	.config = &tcsr_cc_sm8550_regmap_config,
 	.clks = tcsr_cc_sm8550_clocks,
@@ -153,7 +166,8 @@
 };
 
 static const struct of_device_id tcsr_cc_sm8550_match_table[] = {
-	{ .compatible = "qcom,sm8550-tcsr" },
+	{ .compatible = "qcom,sar2130p-tcsr", .data = &tcsr_cc_sar2130p_desc },
+	{ .compatible = "qcom,sm8550-tcsr", .data = &tcsr_cc_sm8550_desc },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, tcsr_cc_sm8550_match_table);
@@ -162,11 +176,11 @@
 {
 	struct regmap *regmap;
 
-	regmap = qcom_cc_map(pdev, &tcsr_cc_sm8550_desc);
+	regmap = qcom_cc_map(pdev, of_device_get_match_data(&pdev->dev));
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
-	return qcom_cc_really_probe(pdev, &tcsr_cc_sm8550_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &tcsr_cc_sm8550_desc, regmap);
 }
 
 static struct platform_driver tcsr_cc_sm8550_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/videocc-qcs615.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/videocc-qcs615.c
@@ -0,0 +1,332 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,qcs615-videocc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_BI_TCXO,
+	DT_SLEEP_CLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_SLEEP_CLK,
+	P_VIDEO_PLL0_OUT_AUX,
+	P_VIDEO_PLL0_OUT_AUX2,
+	P_VIDEO_PLL0_OUT_MAIN,
+};
+
+static const struct pll_vco video_cc_pll0_vco[] = {
+	{ 500000000, 1000000000, 2 },
+};
+
+/* 600MHz configuration VCO - 2 */
+static struct alpha_pll_config video_pll0_config = {
+	.l = 0x1f,
+	.alpha_hi = 0x40,
+	.alpha = 0x00,
+	.alpha_en_mask = BIT(24),
+	.vco_val = BIT(21),
+	.vco_mask = GENMASK(21, 20),
+	.main_output_mask = BIT(0),
+	.config_ctl_val = 0x4001055b,
+	.test_ctl_hi_val = 0x1,
+	.test_ctl_hi_mask = 0x1,
+};
+
+static struct clk_alpha_pll video_pll0 = {
+	.offset = 0x42c,
+	.vco_table = video_cc_pll0_vco,
+	.num_vco = ARRAY_SIZE(video_cc_pll0_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "video_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_slew_ops,
+		},
+	},
+};
+
+static const struct parent_map video_cc_parent_map_0[] = {
+	{ P_SLEEP_CLK, 0 },
+};
+
+static const struct clk_parent_data video_cc_parent_data_0_ao[] = {
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map video_cc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_VIDEO_PLL0_OUT_MAIN, 1 },
+	{ P_VIDEO_PLL0_OUT_AUX, 2 },
+	{ P_VIDEO_PLL0_OUT_AUX2, 3 },
+};
+
+static const struct clk_parent_data video_cc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &video_pll0.clkr.hw },
+	{ .hw = &video_pll0.clkr.hw },
+	{ .hw = &video_pll0.clkr.hw },
+};
+
+static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = {
+	F(32000, P_SLEEP_CLK, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 video_cc_sleep_clk_src = {
+	.cmd_rcgr = 0xaf8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = video_cc_parent_map_0,
+	.freq_tbl = ftbl_video_cc_sleep_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "video_cc_sleep_clk_src",
+		.parent_data = video_cc_parent_data_0_ao,
+		.num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_video_cc_venus_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(133333333, P_VIDEO_PLL0_OUT_MAIN, 4.5, 0, 0),
+	F(240000000, P_VIDEO_PLL0_OUT_MAIN, 2.5, 0, 0),
+	F(300000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
+	F(380000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
+	F(410000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
+	F(460000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 video_cc_venus_clk_src = {
+	.cmd_rcgr = 0x7f0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = video_cc_parent_map_1,
+	.freq_tbl = ftbl_video_cc_venus_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "video_cc_venus_clk_src",
+		.parent_data = video_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(video_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_branch video_cc_sleep_clk = {
+	.halt_reg = 0xb18,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xb18,
+		.enable_mask = BIT(0),
+		.hw.init = &(struct clk_init_data){
+			.name = "video_cc_sleep_clk",
+			.parent_data = &(const struct clk_parent_data){
+				.hw = &video_cc_sleep_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch video_cc_vcodec0_axi_clk = {
+	.halt_reg = 0x8f0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8f0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "video_cc_vcodec0_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch video_cc_vcodec0_core_clk = {
+	.halt_reg = 0x890,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x890,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "video_cc_vcodec0_core_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&video_cc_venus_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch video_cc_venus_ahb_clk = {
+	.halt_reg = 0x9b0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9b0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "video_cc_venus_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch video_cc_venus_ctl_axi_clk = {
+	.halt_reg = 0x8d0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8d0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "video_cc_venus_ctl_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch video_cc_venus_ctl_core_clk = {
+	.halt_reg = 0x850,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x850,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "video_cc_venus_ctl_core_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&video_cc_venus_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc vcodec0_gdsc = {
+	.gdscr = 0x874,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x6,
+	.pd = {
+		.name = "vcodec0_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = HW_CTRL | POLL_CFG_GDSCR,
+};
+
+static struct gdsc venus_gdsc = {
+	.gdscr = 0x814,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x6,
+	.pd = {
+		.name = "venus_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR,
+};
+
+static struct clk_regmap *video_cc_qcs615_clocks[] = {
+	[VIDEO_CC_SLEEP_CLK] = &video_cc_sleep_clk.clkr,
+	[VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr,
+	[VIDEO_CC_VCODEC0_AXI_CLK] = &video_cc_vcodec0_axi_clk.clkr,
+	[VIDEO_CC_VCODEC0_CORE_CLK] = &video_cc_vcodec0_core_clk.clkr,
+	[VIDEO_CC_VENUS_AHB_CLK] = &video_cc_venus_ahb_clk.clkr,
+	[VIDEO_CC_VENUS_CLK_SRC] = &video_cc_venus_clk_src.clkr,
+	[VIDEO_CC_VENUS_CTL_AXI_CLK] = &video_cc_venus_ctl_axi_clk.clkr,
+	[VIDEO_CC_VENUS_CTL_CORE_CLK] = &video_cc_venus_ctl_core_clk.clkr,
+	[VIDEO_PLL0] = &video_pll0.clkr,
+};
+
+static struct gdsc *video_cc_qcs615_gdscs[] = {
+	[VCODEC0_GDSC] = &vcodec0_gdsc,
+	[VENUS_GDSC] = &venus_gdsc,
+};
+
+static const struct qcom_reset_map video_cc_qcs615_resets[] = {
+	[VIDEO_CC_INTERFACE_BCR] = { 0x8b0 },
+	[VIDEO_CC_VCODEC0_BCR] = { 0x870 },
+	[VIDEO_CC_VENUS_BCR] = { 0x810 },
+};
+
+static const struct regmap_config video_cc_qcs615_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0xb94,
+	.fast_io = true,
+};
+
+static const struct qcom_cc_desc video_cc_qcs615_desc = {
+	.config = &video_cc_qcs615_regmap_config,
+	.clks = video_cc_qcs615_clocks,
+	.num_clks = ARRAY_SIZE(video_cc_qcs615_clocks),
+	.resets = video_cc_qcs615_resets,
+	.num_resets = ARRAY_SIZE(video_cc_qcs615_resets),
+	.gdscs = video_cc_qcs615_gdscs,
+	.num_gdscs = ARRAY_SIZE(video_cc_qcs615_gdscs),
+};
+
+static const struct of_device_id video_cc_qcs615_match_table[] = {
+	{ .compatible = "qcom,qcs615-videocc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, video_cc_qcs615_match_table);
+
+static int video_cc_qcs615_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+
+	regmap = qcom_cc_map(pdev, &video_cc_qcs615_desc);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	clk_alpha_pll_configure(&video_pll0, regmap, &video_pll0_config);
+
+	/* Keep some clocks always enabled */
+	regmap_update_bits(regmap, 0x0ab8, BIT(0), BIT(0)); /* VIDEO_CC_XO_CLK */
+
+	return qcom_cc_really_probe(&pdev->dev, &video_cc_qcs615_desc, regmap);
+}
+
+static struct platform_driver video_cc_qcs615_driver = {
+	.probe = video_cc_qcs615_probe,
+	.driver = {
+		.name = "videocc-qcs615",
+		.of_match_table = video_cc_qcs615_match_table,
+	},
+};
+
+module_platform_driver(video_cc_qcs615_driver);
+
+MODULE_DESCRIPTION("QTI VIDEOCC QCS615 Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/videocc-sa8775p.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/videocc-sa8775p.c
@@ -0,0 +1,581 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,sa8775p-videocc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_IFACE,
+	DT_BI_TCXO,
+	DT_BI_TCXO_AO,
+	DT_SLEEP_CLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_BI_TCXO_AO,
+	P_SLEEP_CLK,
+	P_VIDEO_PLL0_OUT_MAIN,
+	P_VIDEO_PLL1_OUT_MAIN,
+};
+
+static const struct pll_vco lucid_evo_vco[] = {
+	{ 249600000, 2020000000, 0 },
+};
+
+static const struct alpha_pll_config video_pll0_config = {
+	.l = 0x39,
+	.alpha = 0x3000,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x32aa299c,
+	.user_ctl_val = 0x00000000,
+	.user_ctl_hi_val = 0x00400805,
+};
+
+static struct clk_alpha_pll video_pll0 = {
+	.offset = 0x0,
+	.vco_table = lucid_evo_vco,
+	.num_vco = ARRAY_SIZE(lucid_evo_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "video_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct alpha_pll_config video_pll1_config = {
+	.l = 0x39,
+	.alpha = 0x3000,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00182261,
+	.config_ctl_hi1_val = 0x32aa299c,
+	.user_ctl_val = 0x00000000,
+	.user_ctl_hi_val = 0x00400805,
+};
+
+static struct clk_alpha_pll video_pll1 = {
+	.offset = 0x1000,
+	.vco_table = lucid_evo_vco,
+	.num_vco = ARRAY_SIZE(lucid_evo_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "video_pll1",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct parent_map video_cc_parent_map_0_ao[] = {
+	{ P_BI_TCXO_AO, 0 },
+};
+
+static const struct clk_parent_data video_cc_parent_data_0_ao[] = {
+	{ .index = DT_BI_TCXO_AO },
+};
+
+static const struct parent_map video_cc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_VIDEO_PLL0_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data video_cc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &video_pll0.clkr.hw },
+};
+
+static const struct parent_map video_cc_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_VIDEO_PLL1_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data video_cc_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &video_pll1.clkr.hw },
+};
+
+static const struct parent_map video_cc_parent_map_3[] = {
+	{ P_SLEEP_CLK, 0 },
+};
+
+static const struct clk_parent_data video_cc_parent_data_3[] = {
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = {
+	F(19200000, P_BI_TCXO_AO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 video_cc_ahb_clk_src = {
+	.cmd_rcgr = 0x8030,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = video_cc_parent_map_0_ao,
+	.freq_tbl = ftbl_video_cc_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "video_cc_ahb_clk_src",
+		.parent_data = video_cc_parent_data_0_ao,
+		.num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = {
+	F(1098000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
+	F(1332000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
+	F(1599000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
+	F(1680000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 video_cc_mvs0_clk_src = {
+	.cmd_rcgr = 0x8000,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = video_cc_parent_map_1,
+	.freq_tbl = ftbl_video_cc_mvs0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "video_cc_mvs0_clk_src",
+		.parent_data = video_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(video_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_video_cc_mvs1_clk_src[] = {
+	F(1098000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0),
+	F(1332000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0),
+	F(1600000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0),
+	F(1800000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 video_cc_mvs1_clk_src = {
+	.cmd_rcgr = 0x8018,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = video_cc_parent_map_2,
+	.freq_tbl = ftbl_video_cc_mvs1_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "video_cc_mvs1_clk_src",
+		.parent_data = video_cc_parent_data_2,
+		.num_parents = ARRAY_SIZE(video_cc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = {
+	F(32000, P_SLEEP_CLK, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 video_cc_sleep_clk_src = {
+	.cmd_rcgr = 0x812c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = video_cc_parent_map_3,
+	.freq_tbl = ftbl_video_cc_sleep_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "video_cc_sleep_clk_src",
+		.parent_data = video_cc_parent_data_3,
+		.num_parents = ARRAY_SIZE(video_cc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 video_cc_xo_clk_src = {
+	.cmd_rcgr = 0x8110,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = video_cc_parent_map_0_ao,
+	.freq_tbl = ftbl_video_cc_ahb_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "video_cc_xo_clk_src",
+		.parent_data = video_cc_parent_data_0_ao,
+		.num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_regmap_div video_cc_mvs0_div_clk_src = {
+	.reg = 0x80b8,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "video_cc_mvs0_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&video_cc_mvs0_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = {
+	.reg = 0x806c,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "video_cc_mvs0c_div2_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&video_cc_mvs0_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div video_cc_mvs1_div_clk_src = {
+	.reg = 0x80dc,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "video_cc_mvs1_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&video_cc_mvs1_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div video_cc_mvs1c_div2_div_clk_src = {
+	.reg = 0x8094,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "video_cc_mvs1c_div2_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&video_cc_mvs1_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div video_cc_sm_div_clk_src = {
+	.reg = 0x8108,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "video_cc_sm_div_clk_src",
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_branch video_cc_mvs0_clk = {
+	.halt_reg = 0x80b0,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x80b0,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x80b0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "video_cc_mvs0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&video_cc_mvs0_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch video_cc_mvs0c_clk = {
+	.halt_reg = 0x8064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "video_cc_mvs0c_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&video_cc_mvs0c_div2_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch video_cc_mvs1_clk = {
+	.halt_reg = 0x80d4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x80d4,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x80d4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "video_cc_mvs1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&video_cc_mvs1_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch video_cc_mvs1c_clk = {
+	.halt_reg = 0x808c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x808c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "video_cc_mvs1c_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&video_cc_mvs1c_div2_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch video_cc_pll_lock_monitor_clk = {
+	.halt_reg = 0x9000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "video_cc_pll_lock_monitor_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&video_cc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch video_cc_sm_obs_clk = {
+	.halt_reg = 0x810c,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x810c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "video_cc_sm_obs_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&video_cc_sm_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc video_cc_mvs0c_gdsc = {
+	.gdscr = 0x804c,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x6,
+	.pd = {
+		.name = "video_cc_mvs0c_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
+};
+
+static struct gdsc video_cc_mvs0_gdsc = {
+	.gdscr = 0x809c,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x6,
+	.pd = {
+		.name = "video_cc_mvs0_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.parent = &video_cc_mvs0c_gdsc.pd,
+	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
+};
+
+static struct gdsc video_cc_mvs1c_gdsc = {
+	.gdscr = 0x8074,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x6,
+	.pd = {
+		.name = "video_cc_mvs1c_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR,
+};
+
+static struct gdsc video_cc_mvs1_gdsc = {
+	.gdscr = 0x80c0,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x6,
+	.pd = {
+		.name = "video_cc_mvs1_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.parent = &video_cc_mvs1c_gdsc.pd,
+	.flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR | HW_CTRL,
+};
+
+static struct clk_regmap *video_cc_sa8775p_clocks[] = {
+	[VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr,
+	[VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr,
+	[VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr,
+	[VIDEO_CC_MVS0_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr,
+	[VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr,
+	[VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr,
+	[VIDEO_CC_MVS1_CLK] = &video_cc_mvs1_clk.clkr,
+	[VIDEO_CC_MVS1_CLK_SRC] = &video_cc_mvs1_clk_src.clkr,
+	[VIDEO_CC_MVS1_DIV_CLK_SRC] = &video_cc_mvs1_div_clk_src.clkr,
+	[VIDEO_CC_MVS1C_CLK] = &video_cc_mvs1c_clk.clkr,
+	[VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC] = &video_cc_mvs1c_div2_div_clk_src.clkr,
+	[VIDEO_CC_PLL_LOCK_MONITOR_CLK] = &video_cc_pll_lock_monitor_clk.clkr,
+	[VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr,
+	[VIDEO_CC_SM_DIV_CLK_SRC] = &video_cc_sm_div_clk_src.clkr,
+	[VIDEO_CC_SM_OBS_CLK] = &video_cc_sm_obs_clk.clkr,
+	[VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr,
+	[VIDEO_PLL0] = &video_pll0.clkr,
+	[VIDEO_PLL1] = &video_pll1.clkr,
+};
+
+static struct gdsc *video_cc_sa8775p_gdscs[] = {
+	[VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc,
+	[VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc,
+	[VIDEO_CC_MVS1_GDSC] = &video_cc_mvs1_gdsc,
+	[VIDEO_CC_MVS1C_GDSC] = &video_cc_mvs1c_gdsc,
+};
+
+static const struct qcom_reset_map video_cc_sa8775p_resets[] = {
+	[VIDEO_CC_INTERFACE_BCR] = { 0x80e8 },
+	[VIDEO_CC_MVS0_BCR] = { 0x8098 },
+	[VIDEO_CC_MVS0C_CLK_ARES] = { 0x8064, 2 },
+	[VIDEO_CC_MVS0C_BCR] = { 0x8048 },
+	[VIDEO_CC_MVS1_BCR] = { 0x80bc },
+	[VIDEO_CC_MVS1C_CLK_ARES] = { 0x808c, 2 },
+	[VIDEO_CC_MVS1C_BCR] = { 0x8070 },
+};
+
+static const struct regmap_config video_cc_sa8775p_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0xb000,
+	.fast_io = true,
+};
+
+static struct qcom_cc_desc video_cc_sa8775p_desc = {
+	.config = &video_cc_sa8775p_regmap_config,
+	.clks = video_cc_sa8775p_clocks,
+	.num_clks = ARRAY_SIZE(video_cc_sa8775p_clocks),
+	.resets = video_cc_sa8775p_resets,
+	.num_resets = ARRAY_SIZE(video_cc_sa8775p_resets),
+	.gdscs = video_cc_sa8775p_gdscs,
+	.num_gdscs = ARRAY_SIZE(video_cc_sa8775p_gdscs),
+};
+
+static const struct of_device_id video_cc_sa8775p_match_table[] = {
+	{ .compatible = "qcom,sa8775p-videocc" },
+	{ .compatible = "qcom,qcs8300-videocc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, video_cc_sa8775p_match_table);
+
+static int video_cc_sa8775p_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+	int ret;
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return ret;
+
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret)
+		return ret;
+
+	regmap = qcom_cc_map(pdev, &video_cc_sa8775p_desc);
+	if (IS_ERR(regmap)) {
+		pm_runtime_put(&pdev->dev);
+		return PTR_ERR(regmap);
+	}
+
+	clk_lucid_evo_pll_configure(&video_pll0, regmap, &video_pll0_config);
+	clk_lucid_evo_pll_configure(&video_pll1, regmap, &video_pll1_config);
+
+	/* Set mvs0c clock divider to div-3 on qcs8300 to fix infrequent video hangs */
+	if (of_device_is_compatible(pdev->dev.of_node, "qcom,qcs8300-videocc"))
+		regmap_write(regmap, video_cc_mvs0c_div2_div_clk_src.reg, 2);
+
+	/* Keep some clocks always enabled */
+	qcom_branch_set_clk_en(regmap, 0x80ec); /* VIDEO_CC_AHB_CLK */
+	qcom_branch_set_clk_en(regmap, 0x8144); /* VIDEO_CC_SLEEP_CLK */
+	qcom_branch_set_clk_en(regmap, 0x8128); /* VIDEO_CC_XO_CLK */
+
+	ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sa8775p_desc, regmap);
+
+	pm_runtime_put(&pdev->dev);
+
+	return ret;
+}
+
+static struct platform_driver video_cc_sa8775p_driver = {
+	.probe = video_cc_sa8775p_probe,
+	.driver = {
+		.name = "videocc-sa8775p",
+		.of_match_table = video_cc_sa8775p_match_table,
+	},
+};
+
+module_platform_driver(video_cc_sa8775p_driver);
+
+MODULE_DESCRIPTION("QTI VIDEOCC SA8775P Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/videocc-sc7180.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/videocc-sc7180.c
@@ -226,7 +226,7 @@
 	/* Keep VIDEO_CC_XO_CLK ALWAYS-ON */
 	regmap_update_bits(regmap, 0x984, 0x1, 0x1);
 
-	return qcom_cc_really_probe(pdev, &video_cc_sc7180_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &video_cc_sc7180_desc, regmap);
 }
 
 static struct platform_driver video_cc_sc7180_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/videocc-sc7280.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/videocc-sc7280.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/clk-provider.h>
@@ -232,6 +233,9 @@
 
 static struct gdsc mvs0_gdsc = {
 	.gdscr = 0x3004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x6,
 	.pd = {
 		.name = "mvs0_gdsc",
 	},
@@ -241,6 +245,9 @@
 
 static struct gdsc mvsc_gdsc = {
 	.gdscr = 0x2004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x6,
 	.pd = {
 		.name = "mvsc_gdsc",
 	},
@@ -298,7 +305,7 @@
 
 	clk_lucid_pll_configure(&video_pll0, regmap, &video_pll0_config);
 
-	return qcom_cc_really_probe(pdev, &video_cc_sc7280_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &video_cc_sc7280_desc, regmap);
 }
 
 static struct platform_driver video_cc_sc7280_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/videocc-sdm845.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/videocc-sdm845.c
@@ -329,7 +329,7 @@
 
 	clk_fabia_pll_configure(&video_pll0, regmap, &video_pll0_config);
 
-	return qcom_cc_really_probe(pdev, &video_cc_sdm845_desc, regmap);
+	return qcom_cc_really_probe(&pdev->dev, &video_cc_sdm845_desc, regmap);
 }
 
 static struct platform_driver video_cc_sdm845_driver = {
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/videocc-sm7150.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/videocc-sm7150.c
@@ -0,0 +1,357 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,sm7150-videocc.h>
+
+#include "common.h"
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "gdsc.h"
+
+enum {
+	DT_BI_TCXO,
+	DT_BI_TCXO_AO,
+};
+
+enum {
+	P_BI_TCXO,
+	P_VIDEOCC_PLL0_OUT_EVEN,
+	P_VIDEOCC_PLL0_OUT_MAIN,
+	P_VIDEOCC_PLL0_OUT_ODD,
+};
+
+static const struct pll_vco fabia_vco[] = {
+	{ 249600000, 2000000000, 0 },
+	{ 125000000, 1000000000, 1 },
+};
+
+static struct alpha_pll_config videocc_pll0_config = {
+	.l = 0x19,
+	.alpha = 0x0,
+	.config_ctl_val = 0x20485699,
+	.config_ctl_hi_val = 0x00002067,
+	.user_ctl_val = 0x00000001,
+	.user_ctl_hi_val = 0x00004805,
+	.test_ctl_hi_val = 0x40000000,
+};
+
+static struct clk_alpha_pll videocc_pll0 = {
+	.offset = 0x42c,
+	.vco_table = fabia_vco,
+	.num_vco = ARRAY_SIZE(fabia_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "videocc_pll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fabia_ops,
+		},
+	},
+};
+
+static const struct parent_map videocc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_VIDEOCC_PLL0_OUT_MAIN, 1 },
+	{ P_VIDEOCC_PLL0_OUT_EVEN, 2 },
+	{ P_VIDEOCC_PLL0_OUT_ODD, 3 },
+};
+
+static const struct clk_parent_data videocc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &videocc_pll0.clkr.hw },
+	{ .hw = &videocc_pll0.clkr.hw },
+	{ .hw = &videocc_pll0.clkr.hw },
+};
+
+static const struct parent_map videocc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data videocc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO_AO },
+};
+
+static const struct freq_tbl ftbl_videocc_iris_clk_src[] = {
+	F(240000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0),
+	F(338000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0),
+	F(365000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0),
+	F(444000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0),
+	F(533000000, P_VIDEOCC_PLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 videocc_iris_clk_src = {
+	.cmd_rcgr = 0x7f0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = videocc_parent_map_0,
+	.freq_tbl = ftbl_videocc_iris_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "videocc_iris_clk_src",
+		.parent_data = videocc_parent_data_0,
+		.num_parents = ARRAY_SIZE(videocc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_videocc_xo_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 videocc_xo_clk_src = {
+	.cmd_rcgr = 0xa98,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = videocc_parent_map_1,
+	.freq_tbl = ftbl_videocc_xo_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "videocc_xo_clk_src",
+		.parent_data = videocc_parent_data_1,
+		.num_parents = ARRAY_SIZE(videocc_parent_data_1),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_branch videocc_iris_ahb_clk = {
+	.halt_reg = 0x8f4,
+	.halt_check = BRANCH_VOTED,
+	.clkr = {
+		.enable_reg = 0x8f4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "videocc_iris_ahb_clk",
+			.parent_data = &(const struct clk_parent_data) {
+				.hw = &videocc_iris_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch videocc_mvs0_axi_clk = {
+	.halt_reg = 0x9ec,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9ec,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "videocc_mvs0_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch videocc_mvs0_core_clk = {
+	.halt_reg = 0x890,
+	.halt_check = BRANCH_VOTED,
+	.clkr = {
+		.enable_reg = 0x890,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "videocc_mvs0_core_clk",
+			.parent_data = &(const struct clk_parent_data) {
+				.hw = &videocc_iris_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch videocc_mvs1_axi_clk = {
+	.halt_reg = 0xa0c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa0c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "videocc_mvs1_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch videocc_mvs1_core_clk = {
+	.halt_reg = 0x8d0,
+	.halt_check = BRANCH_VOTED,
+	.clkr = {
+		.enable_reg = 0x8d0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "videocc_mvs1_core_clk",
+			.parent_data = &(const struct clk_parent_data) {
+				.hw = &videocc_iris_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch videocc_mvsc_core_clk = {
+	.halt_reg = 0x850,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x850,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "videocc_mvsc_core_clk",
+			.parent_data = &(const struct clk_parent_data) {
+				.hw = &videocc_iris_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch videocc_mvsc_ctl_axi_clk = {
+	.halt_reg = 0x9cc,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9cc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "videocc_mvsc_ctl_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch videocc_venus_ahb_clk = {
+	.halt_reg = 0xa6c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa6c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "videocc_venus_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc venus_gdsc = {
+	.gdscr = 0x814,
+	.pd = {
+		.name = "venus_gdsc",
+	},
+	.cxcs = (unsigned int []){ 0x850, 0x9cc },
+	.cxc_count = 2,
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR,
+};
+
+static struct gdsc vcodec0_gdsc = {
+	.gdscr = 0x874,
+	.pd = {
+		.name = "vcodec0_gdsc",
+	},
+	.cxcs = (unsigned int []){ 0x890, 0x9ec },
+	.cxc_count = 2,
+	.flags = HW_CTRL | POLL_CFG_GDSCR,
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc vcodec1_gdsc = {
+	.gdscr = 0x8b4,
+	.pd = {
+		.name = "vcodec1_gdsc",
+	},
+	.cxcs = (unsigned int []){ 0x8d0, 0xa0c },
+	.cxc_count = 2,
+	.flags = HW_CTRL | POLL_CFG_GDSCR,
+	.pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct clk_regmap *videocc_sm7150_clocks[] = {
+	[VIDEOCC_PLL0] = &videocc_pll0.clkr,
+	[VIDEOCC_IRIS_AHB_CLK] = &videocc_iris_ahb_clk.clkr,
+	[VIDEOCC_IRIS_CLK_SRC] = &videocc_iris_clk_src.clkr,
+	[VIDEOCC_MVS0_AXI_CLK] = &videocc_mvs0_axi_clk.clkr,
+	[VIDEOCC_MVS0_CORE_CLK] = &videocc_mvs0_core_clk.clkr,
+	[VIDEOCC_MVS1_AXI_CLK] = &videocc_mvs1_axi_clk.clkr,
+	[VIDEOCC_MVS1_CORE_CLK] = &videocc_mvs1_core_clk.clkr,
+	[VIDEOCC_MVSC_CORE_CLK] = &videocc_mvsc_core_clk.clkr,
+	[VIDEOCC_MVSC_CTL_AXI_CLK] = &videocc_mvsc_ctl_axi_clk.clkr,
+	[VIDEOCC_VENUS_AHB_CLK] = &videocc_venus_ahb_clk.clkr,
+	[VIDEOCC_XO_CLK_SRC] = &videocc_xo_clk_src.clkr,
+};
+
+static struct gdsc *videocc_sm7150_gdscs[] = {
+	[VENUS_GDSC] = &venus_gdsc,
+	[VCODEC0_GDSC] = &vcodec0_gdsc,
+	[VCODEC1_GDSC] = &vcodec1_gdsc,
+};
+
+static const struct regmap_config videocc_sm7150_regmap_config = {
+	.reg_bits	= 32,
+	.reg_stride	= 4,
+	.val_bits	= 32,
+	.max_register	= 0xb94,
+	.fast_io	= true,
+};
+
+static const struct qcom_cc_desc videocc_sm7150_desc = {
+	.config = &videocc_sm7150_regmap_config,
+	.clks = videocc_sm7150_clocks,
+	.num_clks = ARRAY_SIZE(videocc_sm7150_clocks),
+	.gdscs = videocc_sm7150_gdscs,
+	.num_gdscs = ARRAY_SIZE(videocc_sm7150_gdscs),
+};
+
+static const struct of_device_id videocc_sm7150_match_table[] = {
+	{ .compatible = "qcom,sm7150-videocc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, videocc_sm7150_match_table);
+
+static int videocc_sm7150_probe(struct platform_device *pdev)
+{
+	struct regmap *regmap;
+
+	regmap = qcom_cc_map(pdev, &videocc_sm7150_desc);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	clk_fabia_pll_configure(&videocc_pll0, regmap, &videocc_pll0_config);
+
+	/* Keep some clocks always-on */
+	qcom_branch_set_clk_en(regmap, 0x984); /* VIDEOCC_XO_CLK */
+
+	return qcom_cc_really_probe(&pdev->dev, &videocc_sm7150_desc, regmap);
+}
+
+static struct platform_driver videocc_sm7150_driver = {
+	.probe = videocc_sm7150_probe,
+	.driver = {
+		.name = "videocc-sm7150",
+		.of_match_table = videocc_sm7150_match_table,
+	},
+};
+module_platform_driver(videocc_sm7150_driver);
+
+MODULE_DESCRIPTION("Qualcomm SM7150 Video Clock Controller");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/videocc-sm8150.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/videocc-sm8150.c
@@ -262,7 +262,7 @@
 	/* Keep VIDEO_CC_XO_CLK ALWAYS-ON */
 	regmap_update_bits(regmap, 0x984, 0x1, 0x1);
 
-	ret = qcom_cc_really_probe(pdev, &video_cc_sm8150_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sm8150_desc, regmap);
 
 	pm_runtime_put_sync(&pdev->dev);
 
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/videocc-sm8250.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/videocc-sm8250.c
@@ -387,7 +387,7 @@
 	regmap_update_bits(regmap, 0xe58, BIT(0), BIT(0));
 	regmap_update_bits(regmap, 0xeec, BIT(0), BIT(0));
 
-	ret = qcom_cc_really_probe(pdev, &video_cc_sm8250_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sm8250_desc, regmap);
 
 	pm_runtime_put(&pdev->dev);
 
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/videocc-sm8350.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/videocc-sm8350.c
@@ -566,7 +566,7 @@
 	regmap_update_bits(regmap, 0xe58, BIT(0), BIT(0));
 	regmap_update_bits(regmap, video_cc_xo_clk_cbcr, BIT(0), BIT(0));
 
-	ret = qcom_cc_really_probe(pdev, &video_cc_sm8350_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sm8350_desc, regmap);
 	pm_runtime_put(&pdev->dev);
 
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/videocc-sm8450.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/videocc-sm8450.c
@@ -433,7 +433,7 @@
 	regmap_update_bits(regmap, 0x8130, BIT(0), BIT(0));
 	regmap_update_bits(regmap, 0x8114, BIT(0), BIT(0));
 
-	ret = qcom_cc_really_probe(pdev, &video_cc_sm8450_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sm8450_desc, regmap);
 
 	pm_runtime_put(&pdev->dev);
 
--- linux-qcom-6.8.0.orig/drivers/clk/qcom/videocc-sm8550.c
+++ linux-qcom-6.8.0/drivers/clk/qcom/videocc-sm8550.c
@@ -438,7 +438,7 @@
 	regmap_update_bits(regmap, 0x8140, BIT(0), BIT(0));
 	regmap_update_bits(regmap, 0x8124, BIT(0), BIT(0));
 
-	ret = qcom_cc_really_probe(pdev, &video_cc_sm8550_desc, regmap);
+	ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sm8550_desc, regmap);
 
 	pm_runtime_put(&pdev->dev);
 
--- linux-qcom-6.8.0.orig/drivers/clk/ralink/clk-mtmips.c
+++ linux-qcom-6.8.0/drivers/clk/ralink/clk-mtmips.c
@@ -263,8 +263,8 @@
 		.rate = _rate		 \
 	}
 
-static struct mtmips_clk_fixed rt305x_fixed_clocks[] = {
-	CLK_FIXED("xtal", NULL, 40000000)
+static struct mtmips_clk_fixed rt3883_fixed_clocks[] = {
+	CLK_FIXED("periph", "xtal", 40000000)
 };
 
 static struct mtmips_clk_fixed rt3352_fixed_clocks[] = {
@@ -366,6 +366,12 @@
 	return container_of(hw, struct mtmips_clk, hw);
 }
 
+static unsigned long rt2880_xtal_recalc_rate(struct clk_hw *hw,
+					     unsigned long parent_rate)
+{
+	return 40000000;
+}
+
 static unsigned long rt5350_xtal_recalc_rate(struct clk_hw *hw,
 					     unsigned long parent_rate)
 {
@@ -677,10 +683,12 @@
 }
 
 static struct mtmips_clk rt2880_clks_base[] = {
+	{ CLK_BASE("xtal", NULL, rt2880_xtal_recalc_rate) },
 	{ CLK_BASE("cpu", "xtal", rt2880_cpu_recalc_rate) }
 };
 
 static struct mtmips_clk rt305x_clks_base[] = {
+	{ CLK_BASE("xtal", NULL, rt2880_xtal_recalc_rate) },
 	{ CLK_BASE("cpu", "xtal", rt305x_cpu_recalc_rate) }
 };
 
@@ -690,6 +698,7 @@
 };
 
 static struct mtmips_clk rt3883_clks_base[] = {
+	{ CLK_BASE("xtal", NULL, rt2880_xtal_recalc_rate) },
 	{ CLK_BASE("cpu", "xtal", rt3883_cpu_recalc_rate) },
 	{ CLK_BASE("bus", "cpu", rt3883_bus_recalc_rate) }
 };
@@ -746,8 +755,8 @@
 static const struct mtmips_clk_data rt2880_clk_data = {
 	.clk_base = rt2880_clks_base,
 	.num_clk_base = ARRAY_SIZE(rt2880_clks_base),
-	.clk_fixed = rt305x_fixed_clocks,
-	.num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),
+	.clk_fixed = NULL,
+	.num_clk_fixed = 0,
 	.clk_factor = rt2880_factor_clocks,
 	.num_clk_factor = ARRAY_SIZE(rt2880_factor_clocks),
 	.clk_periph = rt2880_pherip_clks,
@@ -757,8 +766,8 @@
 static const struct mtmips_clk_data rt305x_clk_data = {
 	.clk_base = rt305x_clks_base,
 	.num_clk_base = ARRAY_SIZE(rt305x_clks_base),
-	.clk_fixed = rt305x_fixed_clocks,
-	.num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),
+	.clk_fixed = NULL,
+	.num_clk_fixed = 0,
 	.clk_factor = rt305x_factor_clocks,
 	.num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks),
 	.clk_periph = rt305x_pherip_clks,
@@ -779,8 +788,8 @@
 static const struct mtmips_clk_data rt3883_clk_data = {
 	.clk_base = rt3883_clks_base,
 	.num_clk_base = ARRAY_SIZE(rt3883_clks_base),
-	.clk_fixed = rt305x_fixed_clocks,
-	.num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),
+	.clk_fixed = rt3883_fixed_clocks,
+	.num_clk_fixed = ARRAY_SIZE(rt3883_fixed_clocks),
 	.clk_factor = NULL,
 	.num_clk_factor = 0,
 	.clk_periph = rt5350_pherip_clks,
--- linux-qcom-6.8.0.orig/drivers/clk/renesas/r8a779a0-cpg-mssr.c
+++ linux-qcom-6.8.0/drivers/clk/renesas/r8a779a0-cpg-mssr.c
@@ -139,7 +139,7 @@
 	DEF_MOD("avb3",		214,	R8A779A0_CLK_S3D2),
 	DEF_MOD("avb4",		215,	R8A779A0_CLK_S3D2),
 	DEF_MOD("avb5",		216,	R8A779A0_CLK_S3D2),
-	DEF_MOD("canfd0",	328,	R8A779A0_CLK_CANFD),
+	DEF_MOD("canfd0",	328,	R8A779A0_CLK_S3D2),
 	DEF_MOD("csi40",	331,	R8A779A0_CLK_CSI0),
 	DEF_MOD("csi41",	400,	R8A779A0_CLK_CSI0),
 	DEF_MOD("csi42",	401,	R8A779A0_CLK_CSI0),
--- linux-qcom-6.8.0.orig/drivers/clk/renesas/r8a779f0-cpg-mssr.c
+++ linux-qcom-6.8.0/drivers/clk/renesas/r8a779f0-cpg-mssr.c
@@ -161,7 +161,7 @@
 	DEF_MOD("cmt1",		911,	R8A779F0_CLK_R),
 	DEF_MOD("cmt2",		912,	R8A779F0_CLK_R),
 	DEF_MOD("cmt3",		913,	R8A779F0_CLK_R),
-	DEF_MOD("pfc0",		915,	R8A779F0_CLK_CL16M),
+	DEF_MOD("pfc0",		915,	R8A779F0_CLK_CPEX),
 	DEF_MOD("tsc",		919,	R8A779F0_CLK_CL16M),
 	DEF_MOD("rswitch2",	1505,	R8A779F0_CLK_RSW2),
 	DEF_MOD("ether-serdes",	1506,	R8A779F0_CLK_S0D2_HSC),
--- linux-qcom-6.8.0.orig/drivers/clk/renesas/r8a779g0-cpg-mssr.c
+++ linux-qcom-6.8.0/drivers/clk/renesas/r8a779g0-cpg-mssr.c
@@ -22,7 +22,7 @@
 
 enum clk_ids {
 	/* Core Clock Outputs exported to DT */
-	LAST_DT_CORE_CLK = R8A779G0_CLK_R,
+	LAST_DT_CORE_CLK = R8A779G0_CLK_CP,
 
 	/* External Input Clocks */
 	CLK_EXTAL,
@@ -141,6 +141,7 @@
 	DEF_FIXED("svd2_vip",	R8A779G0_CLK_SVD2_VIP,	CLK_SV_VIP,	2, 1),
 	DEF_FIXED("cbfusa",	R8A779G0_CLK_CBFUSA,	CLK_EXTAL,	2, 1),
 	DEF_FIXED("cpex",	R8A779G0_CLK_CPEX,	CLK_EXTAL,	2, 1),
+	DEF_FIXED("cp",		R8A779G0_CLK_CP,	CLK_EXTAL,	2, 1),
 	DEF_FIXED("viobus",	R8A779G0_CLK_VIOBUS,	CLK_VIO,	1, 1),
 	DEF_FIXED("viobusd2",	R8A779G0_CLK_VIOBUSD2,	CLK_VIO,	2, 1),
 	DEF_FIXED("vcbus",	R8A779G0_CLK_VCBUS,	CLK_VC,		1, 1),
@@ -193,7 +194,7 @@
 	DEF_MOD("msi4",		622,	R8A779G0_CLK_MSO),
 	DEF_MOD("msi5",		623,	R8A779G0_CLK_MSO),
 	DEF_MOD("pciec0",	624,	R8A779G0_CLK_S0D2_HSC),
-	DEF_MOD("pscie1",	625,	R8A779G0_CLK_S0D2_HSC),
+	DEF_MOD("pciec1",	625,	R8A779G0_CLK_S0D2_HSC),
 	DEF_MOD("pwm",		628,	R8A779G0_CLK_SASYNCPERD4),
 	DEF_MOD("rpc-if",	629,	R8A779G0_CLK_RPCD2),
 	DEF_MOD("scif0",	702,	R8A779G0_CLK_SASYNCPERD4),
@@ -232,10 +233,10 @@
 	DEF_MOD("cmt1",		911,	R8A779G0_CLK_R),
 	DEF_MOD("cmt2",		912,	R8A779G0_CLK_R),
 	DEF_MOD("cmt3",		913,	R8A779G0_CLK_R),
-	DEF_MOD("pfc0",		915,	R8A779G0_CLK_CL16M),
-	DEF_MOD("pfc1",		916,	R8A779G0_CLK_CL16M),
-	DEF_MOD("pfc2",		917,	R8A779G0_CLK_CL16M),
-	DEF_MOD("pfc3",		918,	R8A779G0_CLK_CL16M),
+	DEF_MOD("pfc0",		915,	R8A779G0_CLK_CP),
+	DEF_MOD("pfc1",		916,	R8A779G0_CLK_CP),
+	DEF_MOD("pfc2",		917,	R8A779G0_CLK_CP),
+	DEF_MOD("pfc3",		918,	R8A779G0_CLK_CP),
 	DEF_MOD("tsc",		919,	R8A779G0_CLK_CL16M),
 	DEF_MOD("tsn",		2723,	R8A779G0_CLK_S0D4_HSC),
 	DEF_MOD("ssiu",		2926,	R8A779G0_CLK_S0D6_PER),
--- linux-qcom-6.8.0.orig/drivers/clk/renesas/r9a07g043-cpg.c
+++ linux-qcom-6.8.0/drivers/clk/renesas/r9a07g043-cpg.c
@@ -138,7 +138,7 @@
 	DEF_FIXED("SPI1", R9A07G043_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4),
 	DEF_SD_MUX("SD0", R9A07G043_CLK_SD0, SEL_SDHI0, SEL_SDHI0_STS, sel_shdi,
 		   mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
-	DEF_SD_MUX("SD1", R9A07G043_CLK_SD1, SEL_SDHI1, SEL_SDHI0_STS, sel_shdi,
+	DEF_SD_MUX("SD1", R9A07G043_CLK_SD1, SEL_SDHI1, SEL_SDHI1_STS, sel_shdi,
 		   mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
 	DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G043_CLK_SD0, 1, 4),
 	DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G043_CLK_SD1, 1, 4),
@@ -265,6 +265,10 @@
 				0x5a8, 1),
 	DEF_MOD("tsu_pclk",	R9A07G043_TSU_PCLK, R9A07G043_CLK_TSU,
 				0x5ac, 0),
+#ifdef CONFIG_RISCV
+	DEF_MOD("nceplic_aclk",	R9A07G043_NCEPLIC_ACLK, R9A07G043_CLK_P1,
+				0x608, 0),
+#endif
 };
 
 static struct rzg2l_reset r9a07g043_resets[] = {
@@ -318,6 +322,10 @@
 	DEF_RST(R9A07G043_ADC_PRESETN, 0x8a8, 0),
 	DEF_RST(R9A07G043_ADC_ADRST_N, 0x8a8, 1),
 	DEF_RST(R9A07G043_TSU_PRESETN, 0x8ac, 0),
+#ifdef CONFIG_RISCV
+	DEF_RST(R9A07G043_NCEPLIC_ARESETN, 0x908, 0),
+#endif
+
 };
 
 static const unsigned int r9a07g043_crit_mod_clks[] __initconst = {
@@ -327,6 +335,7 @@
 #endif
 #ifdef CONFIG_RISCV
 	MOD_CLK_BASE + R9A07G043_IAX45_CLK,
+	MOD_CLK_BASE + R9A07G043_NCEPLIC_ACLK,
 #endif
 	MOD_CLK_BASE + R9A07G043_DMAC_ACLK,
 };
--- linux-qcom-6.8.0.orig/drivers/clk/renesas/r9a07g044-cpg.c
+++ linux-qcom-6.8.0/drivers/clk/renesas/r9a07g044-cpg.c
@@ -178,7 +178,7 @@
 		DEF_FIXED("SPI1", R9A07G044_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4),
 		DEF_SD_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0, SEL_SDHI0_STS, sel_shdi,
 			   mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
-		DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, SEL_SDHI0_STS, sel_shdi,
+		DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, SEL_SDHI1_STS, sel_shdi,
 			   mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
 		DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G044_CLK_SD0, 1, 4),
 		DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G044_CLK_SD1, 1, 4),
--- linux-qcom-6.8.0.orig/drivers/clk/renesas/rzg2l-cpg.c
+++ linux-qcom-6.8.0/drivers/clk/renesas/rzg2l-cpg.c
@@ -555,7 +555,7 @@
 rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params,
 			       unsigned long rate)
 {
-	unsigned long foutpostdiv_rate;
+	unsigned long foutpostdiv_rate, foutvco_rate;
 
 	params->pl5_intin = rate / MEGA;
 	params->pl5_fracin = div_u64(((u64)rate % MEGA) << 24, MEGA);
@@ -564,10 +564,11 @@
 	params->pl5_postdiv2 = 1;
 	params->pl5_spread = 0x16;
 
-	foutpostdiv_rate =
-		EXTAL_FREQ_IN_MEGA_HZ * MEGA / params->pl5_refdiv *
-		((((params->pl5_intin << 24) + params->pl5_fracin)) >> 24) /
-		(params->pl5_postdiv1 * params->pl5_postdiv2);
+	foutvco_rate = div_u64(mul_u32_u32(EXTAL_FREQ_IN_MEGA_HZ * MEGA,
+					   (params->pl5_intin << 24) + params->pl5_fracin),
+			       params->pl5_refdiv) >> 24;
+	foutpostdiv_rate = DIV_ROUND_CLOSEST_ULL(foutvco_rate,
+						 params->pl5_postdiv1 * params->pl5_postdiv2);
 
 	return foutpostdiv_rate;
 }
--- linux-qcom-6.8.0.orig/drivers/clk/rockchip/clk-rk3228.c
+++ linux-qcom-6.8.0/drivers/clk/rockchip/clk-rk3228.c
@@ -409,7 +409,7 @@
 			RK2928_CLKSEL_CON(29), 0, 3, DFLAGS),
 	DIV(0, "sclk_vop_pre", "sclk_vop_src", 0,
 			RK2928_CLKSEL_CON(27), 8, 8, DFLAGS),
-	MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, 0,
+	MUX(DCLK_VOP, "dclk_vop", mux_dclk_vop_p, CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
 			RK2928_CLKSEL_CON(27), 1, 1, MFLAGS),
 
 	FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
--- linux-qcom-6.8.0.orig/drivers/clk/rockchip/clk-rk3588.c
+++ linux-qcom-6.8.0/drivers/clk/rockchip/clk-rk3588.c
@@ -526,7 +526,7 @@
 PNAME(pmu_300m_24m_p)			= { "clk_300m_src", "xin24m" };
 PNAME(pmu_400m_24m_p)			= { "clk_400m_src", "xin24m" };
 PNAME(pmu_100m_50m_24m_src_p)		= { "clk_pmu1_100m_src", "clk_pmu1_50m_src", "xin24m" };
-PNAME(pmu_24m_32k_100m_src_p)		= { "xin24m", "32k", "clk_pmu1_100m_src" };
+PNAME(pmu_24m_32k_100m_src_p)		= { "xin24m", "xin32k", "clk_pmu1_100m_src" };
 PNAME(hclk_pmu1_root_p)			= { "clk_pmu1_200m_src", "clk_pmu1_100m_src", "clk_pmu1_50m_src", "xin24m" };
 PNAME(hclk_pmu_cm0_root_p)		= { "clk_pmu1_400m_src", "clk_pmu1_200m_src", "clk_pmu1_100m_src", "xin24m" };
 PNAME(mclk_pdm0_p)			= { "clk_pmu1_300m_src", "clk_pmu1_200m_src" };
--- linux-qcom-6.8.0.orig/drivers/clk/rockchip/clk.c
+++ linux-qcom-6.8.0/drivers/clk/rockchip/clk.c
@@ -433,12 +433,13 @@
 				    struct rockchip_clk_branch *list,
 				    unsigned int nr_clk)
 {
-	struct clk *clk = NULL;
+	struct clk *clk;
 	unsigned int idx;
 	unsigned long flags;
 
 	for (idx = 0; idx < nr_clk; idx++, list++) {
 		flags = list->flags;
+		clk = NULL;
 
 		/* catch simple muxes */
 		switch (list->branch_type) {
--- linux-qcom-6.8.0.orig/drivers/clk/samsung/clk-exynos-clkout.c
+++ linux-qcom-6.8.0/drivers/clk/samsung/clk-exynos-clkout.c
@@ -13,9 +13,9 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm.h>
-#include <linux/property.h>
 
 #define EXYNOS_CLKOUT_NR_CLKS		1
 #define EXYNOS_CLKOUT_PARENTS		32
@@ -84,17 +84,24 @@
 static int exynos_clkout_match_parent_dev(struct device *dev, u32 *mux_mask)
 {
 	const struct exynos_clkout_variant *variant;
+	const struct of_device_id *match;
 
 	if (!dev->parent) {
 		dev_err(dev, "not instantiated from MFD\n");
 		return -EINVAL;
 	}
 
-	variant = device_get_match_data(dev->parent);
-	if (!variant) {
+	/*
+	 * 'exynos_clkout_ids' arrays is not the ids array matched by
+	 * the dev->parent driver, so of_device_get_match_data() or
+	 * device_get_match_data() cannot be used here.
+	 */
+	match = of_match_device(exynos_clkout_ids, dev->parent);
+	if (!match) {
 		dev_err(dev, "cannot match parent device\n");
 		return -EINVAL;
 	}
+	variant = match->data;
 
 	*mux_mask = variant->mux_mask;
 
--- linux-qcom-6.8.0.orig/drivers/clk/samsung/clk-exynos4.c
+++ linux-qcom-6.8.0/drivers/clk/samsung/clk-exynos4.c
@@ -1040,19 +1040,20 @@
 static void __init exynos4_clk_register_finpll(struct samsung_clk_provider *ctx)
 {
 	struct samsung_fixed_rate_clock fclk;
-	struct clk *clk;
-	unsigned long finpll_f = 24000000;
+	unsigned long finpll_f;
+	unsigned int parent;
 	char *parent_name;
 	unsigned int xom = exynos4_get_xom();
 
 	parent_name = xom & 1 ? "xusbxti" : "xxti";
-	clk = clk_get(NULL, parent_name);
-	if (IS_ERR(clk)) {
+	parent = xom & 1 ? CLK_XUSBXTI : CLK_XXTI;
+
+	finpll_f = clk_hw_get_rate(ctx->clk_data.hws[parent]);
+	if (!finpll_f) {
 		pr_err("%s: failed to lookup parent clock %s, assuming "
 			"fin_pll clock frequency is 24MHz\n", __func__,
 			parent_name);
-	} else {
-		finpll_f = clk_get_rate(clk);
+		finpll_f = 24000000;
 	}
 
 	fclk.id = CLK_FIN_PLL;
--- linux-qcom-6.8.0.orig/drivers/clk/samsung/clk-exynos7885.c
+++ linux-qcom-6.8.0/drivers/clk/samsung/clk-exynos7885.c
@@ -20,7 +20,7 @@
 #define CLKS_NR_TOP			(CLK_GOUT_FSYS_USB30DRD + 1)
 #define CLKS_NR_CORE			(CLK_GOUT_TREX_P_CORE_PCLK_P_CORE + 1)
 #define CLKS_NR_PERI			(CLK_GOUT_WDT1_PCLK + 1)
-#define CLKS_NR_FSYS			(CLK_GOUT_MMC_SDIO_SDCLKIN + 1)
+#define CLKS_NR_FSYS			(CLK_MOUT_FSYS_USB30DRD_USER + 1)
 
 /* ---- CMU_TOP ------------------------------------------------------------- */
 
--- linux-qcom-6.8.0.orig/drivers/clk/samsung/clk-exynos850.c
+++ linux-qcom-6.8.0/drivers/clk/samsung/clk-exynos850.c
@@ -605,7 +605,7 @@
 
 static const struct samsung_gate_clock apm_gate_clks[] __initconst = {
 	GATE(CLK_GOUT_CLKCMU_CMGP_BUS, "gout_clkcmu_cmgp_bus", "dout_apm_bus",
-	     CLK_CON_GAT_CLKCMU_CMGP_BUS, 21, 0, 0),
+	     CLK_CON_GAT_CLKCMU_CMGP_BUS, 21, CLK_SET_RATE_PARENT, 0),
 	GATE(CLK_GOUT_CLKCMU_CHUB_BUS, "gout_clkcmu_chub_bus",
 	     "mout_clkcmu_chub_bus",
 	     CLK_CON_GAT_GATE_CLKCMU_CHUB_BUS, 21, 0, 0),
@@ -974,19 +974,19 @@
 static const struct samsung_mux_clock cmgp_mux_clks[] __initconst = {
 	MUX(CLK_MOUT_CMGP_ADC, "mout_cmgp_adc", mout_cmgp_adc_p,
 	    CLK_CON_MUX_CLK_CMGP_ADC, 0, 1),
-	MUX(CLK_MOUT_CMGP_USI0, "mout_cmgp_usi0", mout_cmgp_usi0_p,
-	    CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP0, 0, 1),
-	MUX(CLK_MOUT_CMGP_USI1, "mout_cmgp_usi1", mout_cmgp_usi1_p,
-	    CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP1, 0, 1),
+	MUX_F(CLK_MOUT_CMGP_USI0, "mout_cmgp_usi0", mout_cmgp_usi0_p,
+	      CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP0, 0, 1, CLK_SET_RATE_PARENT, 0),
+	MUX_F(CLK_MOUT_CMGP_USI1, "mout_cmgp_usi1", mout_cmgp_usi1_p,
+	      CLK_CON_MUX_MUX_CLK_CMGP_USI_CMGP1, 0, 1, CLK_SET_RATE_PARENT, 0),
 };
 
 static const struct samsung_div_clock cmgp_div_clks[] __initconst = {
 	DIV(CLK_DOUT_CMGP_ADC, "dout_cmgp_adc", "gout_clkcmu_cmgp_bus",
 	    CLK_CON_DIV_DIV_CLK_CMGP_ADC, 0, 4),
-	DIV(CLK_DOUT_CMGP_USI0, "dout_cmgp_usi0", "mout_cmgp_usi0",
-	    CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP0, 0, 5),
-	DIV(CLK_DOUT_CMGP_USI1, "dout_cmgp_usi1", "mout_cmgp_usi1",
-	    CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP1, 0, 5),
+	DIV_F(CLK_DOUT_CMGP_USI0, "dout_cmgp_usi0", "mout_cmgp_usi0",
+	      CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP0, 0, 5, CLK_SET_RATE_PARENT, 0),
+	DIV_F(CLK_DOUT_CMGP_USI1, "dout_cmgp_usi1", "mout_cmgp_usi1",
+	      CLK_CON_DIV_DIV_CLK_CMGP_USI_CMGP1, 0, 5, CLK_SET_RATE_PARENT, 0),
 };
 
 static const struct samsung_gate_clock cmgp_gate_clks[] __initconst = {
@@ -1001,12 +1001,12 @@
 	     "gout_clkcmu_cmgp_bus",
 	     CLK_CON_GAT_GOUT_CMGP_GPIO_PCLK, 21, CLK_IGNORE_UNUSED, 0),
 	GATE(CLK_GOUT_CMGP_USI0_IPCLK, "gout_cmgp_usi0_ipclk", "dout_cmgp_usi0",
-	     CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_IPCLK, 21, 0, 0),
+	     CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_IPCLK, 21, CLK_SET_RATE_PARENT, 0),
 	GATE(CLK_GOUT_CMGP_USI0_PCLK, "gout_cmgp_usi0_pclk",
 	     "gout_clkcmu_cmgp_bus",
 	     CLK_CON_GAT_GOUT_CMGP_USI_CMGP0_PCLK, 21, 0, 0),
 	GATE(CLK_GOUT_CMGP_USI1_IPCLK, "gout_cmgp_usi1_ipclk", "dout_cmgp_usi1",
-	     CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_IPCLK, 21, 0, 0),
+	     CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_IPCLK, 21, CLK_SET_RATE_PARENT, 0),
 	GATE(CLK_GOUT_CMGP_USI1_PCLK, "gout_cmgp_usi1_pclk",
 	     "gout_clkcmu_cmgp_bus",
 	     CLK_CON_GAT_GOUT_CMGP_USI_CMGP1_PCLK, 21, 0, 0),
@@ -1557,8 +1557,9 @@
 	    mout_peri_uart_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART_USER, 4, 1),
 	MUX(CLK_MOUT_PERI_HSI2C_USER, "mout_peri_hsi2c_user",
 	    mout_peri_hsi2c_user_p, PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER, 4, 1),
-	MUX(CLK_MOUT_PERI_SPI_USER, "mout_peri_spi_user", mout_peri_spi_user_p,
-	    PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 4, 1),
+	MUX_F(CLK_MOUT_PERI_SPI_USER, "mout_peri_spi_user",
+	      mout_peri_spi_user_p, PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 4, 1,
+	      CLK_SET_RATE_PARENT, 0),
 };
 
 static const struct samsung_div_clock peri_div_clks[] __initconst = {
@@ -1568,8 +1569,8 @@
 	    CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1, 0, 5),
 	DIV(CLK_DOUT_PERI_HSI2C2, "dout_peri_hsi2c2", "gout_peri_hsi2c2",
 	    CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2, 0, 5),
-	DIV(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "mout_peri_spi_user",
-	    CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 0, 5),
+	DIV_F(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "mout_peri_spi_user",
+	      CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 0, 5, CLK_SET_RATE_PARENT, 0),
 };
 
 static const struct samsung_gate_clock peri_gate_clks[] __initconst = {
@@ -1611,7 +1612,7 @@
 	     "mout_peri_bus_user",
 	     CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 21, 0, 0),
 	GATE(CLK_GOUT_SPI0_IPCLK, "gout_spi0_ipclk", "dout_peri_spi0",
-	     CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 21, 0, 0),
+	     CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 21, CLK_SET_RATE_PARENT, 0),
 	GATE(CLK_GOUT_SPI0_PCLK, "gout_spi0_pclk", "mout_peri_bus_user",
 	     CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 21, 0, 0),
 	GATE(CLK_GOUT_SYSREG_PERI_PCLK, "gout_sysreg_peri_pclk",
--- linux-qcom-6.8.0.orig/drivers/clk/samsung/clk-exynosautov9.c
+++ linux-qcom-6.8.0/drivers/clk/samsung/clk-exynosautov9.c
@@ -352,13 +352,13 @@
 	/* CMU_TOP_PURECLKCOMP */
 	PLL(pll_0822x, FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk",
 	    PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0, NULL),
-	PLL(pll_0822x, FOUT_SHARED0_PLL, "fout_shared1_pll", "oscclk",
+	PLL(pll_0822x, FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk",
 	    PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1, NULL),
-	PLL(pll_0822x, FOUT_SHARED0_PLL, "fout_shared2_pll", "oscclk",
+	PLL(pll_0822x, FOUT_SHARED2_PLL, "fout_shared2_pll", "oscclk",
 	    PLL_LOCKTIME_PLL_SHARED2, PLL_CON3_PLL_SHARED2, NULL),
-	PLL(pll_0822x, FOUT_SHARED0_PLL, "fout_shared3_pll", "oscclk",
+	PLL(pll_0822x, FOUT_SHARED3_PLL, "fout_shared3_pll", "oscclk",
 	    PLL_LOCKTIME_PLL_SHARED3, PLL_CON3_PLL_SHARED3, NULL),
-	PLL(pll_0822x, FOUT_SHARED0_PLL, "fout_shared4_pll", "oscclk",
+	PLL(pll_0822x, FOUT_SHARED4_PLL, "fout_shared4_pll", "oscclk",
 	    PLL_LOCKTIME_PLL_SHARED4, PLL_CON3_PLL_SHARED4, NULL),
 };
 
--- linux-qcom-6.8.0.orig/drivers/clk/sifive/sifive-prci.c
+++ linux-qcom-6.8.0/drivers/clk/sifive/sifive-prci.c
@@ -4,7 +4,6 @@
  * Copyright (C) 2020 Zong Li
  */
 
-#include <linux/clkdev.h>
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -536,13 +535,6 @@
 				 init.name, r);
 			return r;
 		}
-
-		r = clk_hw_register_clkdev(&pic->hw, pic->name, dev_name(dev));
-		if (r) {
-			dev_warn(dev, "Failed to register clkdev for %s: %d\n",
-				 init.name, r);
-			return r;
-		}
 
 		pd->hw_clks.hws[i] = &pic->hw;
 	}
--- linux-qcom-6.8.0.orig/drivers/clk/starfive/clk-starfive-jh7110-sys.c
+++ linux-qcom-6.8.0/drivers/clk/starfive/clk-starfive-jh7110-sys.c
@@ -385,6 +385,32 @@
 }
 EXPORT_SYMBOL_GPL(jh7110_reset_controller_register);
 
+/*
+ * This clock notifier is called when the rate of PLL0 clock is to be changed.
+ * The cpu_root clock should save the curent parent clock and switch its parent
+ * clock to osc before PLL0 rate will be changed. Then switch its parent clock
+ * back after the PLL0 rate is completed.
+ */
+static int jh7110_pll0_clk_notifier_cb(struct notifier_block *nb,
+				       unsigned long action, void *data)
+{
+	struct jh71x0_clk_priv *priv = container_of(nb, struct jh71x0_clk_priv, pll_clk_nb);
+	struct clk *cpu_root = priv->reg[JH7110_SYSCLK_CPU_ROOT].hw.clk;
+	int ret = 0;
+
+	if (action == PRE_RATE_CHANGE) {
+		struct clk *osc = clk_get(priv->dev, "osc");
+
+		priv->original_clk = clk_get_parent(cpu_root);
+		ret = clk_set_parent(cpu_root, osc);
+		clk_put(osc);
+	} else if (action == POST_RATE_CHANGE) {
+		ret = clk_set_parent(cpu_root, priv->original_clk);
+	}
+
+	return notifier_from_errno(ret);
+}
+
 static int __init jh7110_syscrg_probe(struct platform_device *pdev)
 {
 	struct jh71x0_clk_priv *priv;
@@ -413,7 +439,10 @@
 		if (IS_ERR(priv->pll[0]))
 			return PTR_ERR(priv->pll[0]);
 	} else {
-		clk_put(pllclk);
+		priv->pll_clk_nb.notifier_call = jh7110_pll0_clk_notifier_cb;
+		ret = clk_notifier_register(pllclk, &priv->pll_clk_nb);
+		if (ret)
+			return ret;
 		priv->pll[0] = NULL;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/clk/starfive/clk-starfive-jh7110-vout.c
+++ linux-qcom-6.8.0/drivers/clk/starfive/clk-starfive-jh7110-vout.c
@@ -145,7 +145,7 @@
 
 	/* enable power domain and clocks */
 	pm_runtime_enable(priv->dev);
-	ret = pm_runtime_get_sync(priv->dev);
+	ret = pm_runtime_resume_and_get(priv->dev);
 	if (ret < 0)
 		return dev_err_probe(priv->dev, ret, "failed to turn on power\n");
 
--- linux-qcom-6.8.0.orig/drivers/clk/starfive/clk-starfive-jh71x0.h
+++ linux-qcom-6.8.0/drivers/clk/starfive/clk-starfive-jh71x0.h
@@ -114,6 +114,8 @@
 	spinlock_t rmw_lock;
 	struct device *dev;
 	void __iomem *base;
+	struct clk *original_clk;
+	struct notifier_block pll_clk_nb;
 	struct clk_hw *pll[3];
 	struct jh71x0_clk reg[];
 };
--- linux-qcom-6.8.0.orig/drivers/clk/sunxi-ng/ccu-sun20i-d1.c
+++ linux-qcom-6.8.0/drivers/clk/sunxi-ng/ccu-sun20i-d1.c
@@ -1371,7 +1371,7 @@
 
 	/* Enforce m1 = 0, m0 = 0 for PLL_AUDIO0 */
 	val = readl(reg + SUN20I_D1_PLL_AUDIO0_REG);
-	val &= ~BIT(1) | BIT(0);
+	val &= ~(BIT(1) | BIT(0));
 	writel(val, reg + SUN20I_D1_PLL_AUDIO0_REG);
 
 	/* Force fanout-27M factor N to 0. */
--- linux-qcom-6.8.0.orig/drivers/clk/sunxi-ng/ccu-sun50i-a100.c
+++ linux-qcom-6.8.0/drivers/clk/sunxi-ng/ccu-sun50i-a100.c
@@ -436,7 +436,7 @@
 					  24, 2,	/* mux */
 					  BIT(31),	/* gate */
 					  2,		/* post-div */
-					  CLK_SET_RATE_NO_REPARENT);
+					  0);
 
 static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1", mmc_parents, 0x834,
 					  0, 4,		/* M */
@@ -444,7 +444,7 @@
 					  24, 2,	/* mux */
 					  BIT(31),	/* gate */
 					  2,		/* post-div */
-					  CLK_SET_RATE_NO_REPARENT);
+					  0);
 
 static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2", mmc_parents, 0x838,
 					  0, 4,		/* M */
@@ -452,7 +452,7 @@
 					  24, 2,	/* mux */
 					  BIT(31),	/* gate */
 					  2,		/* post-div */
-					  CLK_SET_RATE_NO_REPARENT);
+					  0);
 
 static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb3", 0x84c, BIT(0), 0);
 static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb3", 0x84c, BIT(1), 0);
--- linux-qcom-6.8.0.orig/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ linux-qcom-6.8.0/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -182,6 +182,8 @@
 					      &ccu_nkm_ops,
 					      CLK_SET_RATE_UNGATE | CLK_SET_RATE_PARENT),
 		.features	= CCU_FEATURE_CLOSEST_RATE,
+		.min_rate	= 500000000,
+		.max_rate	= 1400000000,
 	},
 };
 
@@ -531,11 +533,11 @@
 				 CLK_SET_RATE_PARENT);
 
 /*
- * DSI output seems to work only when PLL_MIPI selected. Set it and prevent
- * the mux from reparenting.
+ * Experiments showed that RGB output requires pll-video0-2x, while DSI
+ * requires pll-mipi. It will not work with incorrect clock, the screen will
+ * be blank.
+ * sun50i-a64.dtsi assigns pll-mipi as TCON0 parent by default
  */
-#define SUN50I_A64_TCON0_CLK_REG	0x118
-
 static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" };
 static const u8 tcon0_table[] = { 0, 2, };
 static SUNXI_CCU_MUX_TABLE_WITH_GATE_CLOSEST(tcon0_clk, "tcon0", tcon0_parents,
@@ -955,11 +957,6 @@
 
 	writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
 
-	/* Set PLL MIPI as parent for TCON0 */
-	val = readl(reg + SUN50I_A64_TCON0_CLK_REG);
-	val &= ~GENMASK(26, 24);
-	writel(val | (0 << 24), reg + SUN50I_A64_TCON0_CLK_REG);
-
 	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a64_ccu_desc);
 	if (ret)
 		return ret;
--- linux-qcom-6.8.0.orig/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
+++ linux-qcom-6.8.0/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
@@ -21,7 +21,6 @@
 
 /* PLL_VIDEO0 exported for HDMI PHY */
 
-#define CLK_PLL_VIDEO0_2X		8
 #define CLK_PLL_VE			9
 #define CLK_PLL_DDR0			10
 
@@ -32,7 +31,6 @@
 #define CLK_PLL_PERIPH1_2X		14
 #define CLK_PLL_VIDEO1			15
 #define CLK_PLL_GPU			16
-#define CLK_PLL_MIPI			17
 #define CLK_PLL_HSIC			18
 #define CLK_PLL_DE			19
 #define CLK_PLL_DDR1			20
--- linux-qcom-6.8.0.orig/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
+++ linux-qcom-6.8.0/drivers/clk/sunxi-ng/ccu-sun50i-h6.c
@@ -1181,11 +1181,18 @@
 	SUN50I_H6_USB3_CLK_REG,
 };
 
+static struct ccu_mux_nb sun50i_h6_cpu_nb = {
+	.common		= &cpux_clk.common,
+	.cm		= &cpux_clk.mux,
+	.delay_us       = 1,
+	.bypass_index   = 0, /* index of 24 MHz oscillator */
+};
+
 static int sun50i_h6_ccu_probe(struct platform_device *pdev)
 {
 	void __iomem *reg;
+	int i, ret;
 	u32 val;
-	int i;
 
 	reg = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(reg))
@@ -1252,7 +1259,15 @@
 	val |= BIT(24);
 	writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);
 
-	return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
+	ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
+	if (ret)
+		return ret;
+
+	/* Reparent CPU during PLL CPUX rate changes */
+	ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
+				  &sun50i_h6_cpu_nb);
+
+	return 0;
 }
 
 static const struct of_device_id sun50i_h6_ccu_ids[] = {
--- linux-qcom-6.8.0.orig/drivers/clk/sunxi-ng/ccu_common.c
+++ linux-qcom-6.8.0/drivers/clk/sunxi-ng/ccu_common.c
@@ -44,6 +44,16 @@
 			unsigned long current_rate,
 			unsigned long best_rate)
 {
+	unsigned long min_rate, max_rate;
+
+	clk_hw_get_rate_range(&common->hw, &min_rate, &max_rate);
+
+	if (current_rate > max_rate)
+		return false;
+
+	if (current_rate < min_rate)
+		return false;
+
 	if (common->features & CCU_FEATURE_CLOSEST_RATE)
 		return abs(current_rate - target_rate) < abs(best_rate - target_rate);
 
@@ -138,6 +148,21 @@
 		}
 	}
 
+	for (i = 0; i < desc->num_ccu_clks; i++) {
+		struct ccu_common *cclk = desc->ccu_clks[i];
+
+		if (!cclk)
+			continue;
+
+		if (cclk->max_rate)
+			clk_hw_set_rate_range(&cclk->hw, cclk->min_rate,
+					      cclk->max_rate);
+		else
+			WARN(cclk->min_rate,
+			     "No max_rate, ignoring min_rate of clock %d - %s\n",
+			     i, clk_hw_get_name(&cclk->hw));
+	}
+
 	ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
 				     desc->hw_clks);
 	if (ret)
--- linux-qcom-6.8.0.orig/drivers/clk/sunxi-ng/ccu_common.h
+++ linux-qcom-6.8.0/drivers/clk/sunxi-ng/ccu_common.h
@@ -31,6 +31,9 @@
 	u16		lock_reg;
 	u32		prediv;
 
+	unsigned long	min_rate;
+	unsigned long	max_rate;
+
 	unsigned long	features;
 	spinlock_t	*lock;
 	struct clk_hw	hw;
--- linux-qcom-6.8.0.orig/drivers/clk/sunxi/clk-simple-gates.c
+++ linux-qcom-6.8.0/drivers/clk/sunxi/clk-simple-gates.c
@@ -21,11 +21,9 @@
 {
 	struct clk_onecell_data *clk_data;
 	const char *clk_parent, *clk_name;
-	struct property *prop;
 	struct resource res;
 	void __iomem *clk_reg;
 	void __iomem *reg;
-	const __be32 *p;
 	int number, i = 0, j;
 	u8 clk_bit;
 	u32 index;
@@ -47,7 +45,7 @@
 	if (!clk_data->clks)
 		goto err_free_data;
 
-	of_property_for_each_u32(node, "clock-indices", prop, p, index) {
+	of_property_for_each_u32(node, "clock-indices", index) {
 		of_property_read_string_index(node, "clock-output-names",
 					      i, &clk_name);
 
--- linux-qcom-6.8.0.orig/drivers/clk/sunxi/clk-sun8i-bus-gates.c
+++ linux-qcom-6.8.0/drivers/clk/sunxi/clk-sun8i-bus-gates.c
@@ -24,11 +24,9 @@
 	const char *parents[PARENT_MAX];
 	struct clk_onecell_data *clk_data;
 	const char *clk_name;
-	struct property *prop;
 	struct resource res;
 	void __iomem *clk_reg;
 	void __iomem *reg;
-	const __be32 *p;
 	int number, i;
 	u8 clk_bit;
 	int index;
@@ -58,7 +56,7 @@
 		goto err_free_data;
 
 	i = 0;
-	of_property_for_each_u32(node, "clock-indices", prop, p, index) {
+	of_property_for_each_u32(node, "clock-indices", index) {
 		of_property_read_string_index(node, "clock-output-names",
 					      i, &clk_name);
 
--- linux-qcom-6.8.0.orig/drivers/clk/ti/clk-dra7-atl.c
+++ linux-qcom-6.8.0/drivers/clk/ti/clk-dra7-atl.c
@@ -240,6 +240,7 @@
 		}
 
 		clk = of_clk_get_from_provider(&clkspec);
+		of_node_put(clkspec.np);
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to get atl clock %d from provider\n",
 			       __func__, i);
--- linux-qcom-6.8.0.orig/drivers/clk/zynq/clkc.c
+++ linux-qcom-6.8.0/drivers/clk/zynq/clkc.c
@@ -42,6 +42,7 @@
 #define SLCR_SWDT_CLK_SEL		(zynq_clkc_base + 0x204)
 
 #define NUM_MIO_PINS	54
+#define CLK_NAME_LEN	16
 
 #define DBG_CLK_CTRL_CLKACT_TRC		BIT(0)
 #define DBG_CLK_CTRL_CPU_1XCLKACT	BIT(1)
@@ -215,7 +216,7 @@
 	int i;
 	u32 tmp;
 	int ret;
-	char *clk_name;
+	char clk_name[CLK_NAME_LEN];
 	unsigned int fclk_enable = 0;
 	const char *clk_output_name[clk_max];
 	const char *cpu_parents[4];
@@ -426,12 +427,10 @@
 			"gem1_emio_mux", CLK_SET_RATE_PARENT,
 			SLCR_GEM1_CLK_CTRL, 0, 0, &gem1clk_lock);
 
-	tmp = strlen("mio_clk_00x");
-	clk_name = kmalloc(tmp, GFP_KERNEL);
 	for (i = 0; i < NUM_MIO_PINS; i++) {
 		int idx;
 
-		snprintf(clk_name, tmp, "mio_clk_%2.2d", i);
+		snprintf(clk_name, CLK_NAME_LEN, "mio_clk_%2.2d", i);
 		idx = of_property_match_string(np, "clock-names", clk_name);
 		if (idx >= 0)
 			can_mio_mux_parents[i] = of_clk_get_parent_name(np,
@@ -439,7 +438,6 @@
 		else
 			can_mio_mux_parents[i] = dummy_nm;
 	}
-	kfree(clk_name);
 	clk_register_mux(NULL, "can_mux", periph_parents, 4,
 			CLK_SET_RATE_NO_REPARENT, SLCR_CAN_CLK_CTRL, 4, 2, 0,
 			&canclk_lock);
--- linux-qcom-6.8.0.orig/drivers/clocksource/Kconfig
+++ linux-qcom-6.8.0/drivers/clocksource/Kconfig
@@ -390,7 +390,8 @@
 	  This affects CPU_FREQ max delta from the initial frequency.
 
 config ARM_TIMER_SP804
-	bool "Support for Dual Timer SP804 module" if COMPILE_TEST
+	bool "Support for Dual Timer SP804 module"
+	depends on ARM || ARM64 || COMPILE_TEST
 	depends on GENERIC_SCHED_CLOCK && HAVE_CLK
 	select CLKSRC_MMIO
 	select TIMER_OF if OF
--- linux-qcom-6.8.0.orig/drivers/clocksource/arm_global_timer.c
+++ linux-qcom-6.8.0/drivers/clocksource/arm_global_timer.c
@@ -32,7 +32,7 @@
 #define GT_CONTROL_IRQ_ENABLE		BIT(2)	/* banked */
 #define GT_CONTROL_AUTO_INC		BIT(3)	/* banked */
 #define GT_CONTROL_PRESCALER_SHIFT      8
-#define GT_CONTROL_PRESCALER_MAX        0xF
+#define GT_CONTROL_PRESCALER_MAX        0xFF
 #define GT_CONTROL_PRESCALER_MASK       (GT_CONTROL_PRESCALER_MAX << \
 					 GT_CONTROL_PRESCALER_SHIFT)
 
@@ -290,18 +290,17 @@
 	switch (event) {
 	case PRE_RATE_CHANGE:
 	{
-		int psv;
+		unsigned long psv;
 
-		psv = DIV_ROUND_CLOSEST(ndata->new_rate,
-					gt_target_rate);
-
-		if (abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR)
+		psv = DIV_ROUND_CLOSEST(ndata->new_rate, gt_target_rate);
+		if (!psv ||
+		    abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR)
 			return NOTIFY_BAD;
 
 		psv--;
 
 		/* prescaler within legal range? */
-		if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX)
+		if (psv > GT_CONTROL_PRESCALER_MAX)
 			return NOTIFY_BAD;
 
 		/*
--- linux-qcom-6.8.0.orig/drivers/clocksource/hyperv_timer.c
+++ linux-qcom-6.8.0/drivers/clocksource/hyperv_timer.c
@@ -27,7 +27,8 @@
 #include <asm/mshyperv.h>
 
 static struct clock_event_device __percpu *hv_clock_event;
-static u64 hv_sched_clock_offset __ro_after_init;
+/* Note: offset can hold negative values after hibernation. */
+static u64 hv_sched_clock_offset __read_mostly;
 
 /*
  * If false, we're using the old mechanism for stimer0 interrupts
@@ -137,7 +138,21 @@
 	ce->name = "Hyper-V clockevent";
 	ce->features = CLOCK_EVT_FEAT_ONESHOT;
 	ce->cpumask = cpumask_of(cpu);
-	ce->rating = 1000;
+
+	/*
+	 * Lower the rating of the Hyper-V timer in a TDX VM without paravisor,
+	 * so the local APIC timer (lapic_clockevent) is the default timer in
+	 * such a VM. The Hyper-V timer is not preferred in such a VM because
+	 * it depends on the slow VM Reference Counter MSR (the Hyper-V TSC
+	 * page is not enbled in such a VM because the VM uses Invariant TSC
+	 * as a better clocksource and it's challenging to mark the Hyper-V
+	 * TSC page shared in very early boot).
+	 */
+	if (!ms_hyperv.paravisor_present && hv_isolation_type_tdx())
+		ce->rating = 90;
+	else
+		ce->rating = 1000;
+
 	ce->set_state_shutdown = hv_ce_shutdown;
 	ce->set_state_oneshot = hv_ce_set_oneshot;
 	ce->set_next_event = hv_ce_set_next_event;
@@ -456,6 +471,17 @@
 	hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
 }
 
+/*
+ * Called during resume from hibernation, from overridden
+ * x86_platform.restore_sched_clock_state routine. This is to adjust offsets
+ * used to calculate time for hv tsc page based sched_clock, to account for
+ * time spent before hibernation.
+ */
+void hv_adj_sched_clock_offset(u64 offset)
+{
+	hv_sched_clock_offset -= offset;
+}
+
 #ifdef HAVE_VDSO_CLOCKMODE_HVCLOCK
 static int hv_cs_enable(struct clocksource *cs)
 {
--- linux-qcom-6.8.0.orig/drivers/clocksource/samsung_pwm_timer.c
+++ linux-qcom-6.8.0/drivers/clocksource/samsung_pwm_timer.c
@@ -418,8 +418,6 @@
 static int __init samsung_pwm_alloc(struct device_node *np,
 				    const struct samsung_pwm_variant *variant)
 {
-	struct property *prop;
-	const __be32 *cur;
 	u32 val;
 	int i, ret;
 
@@ -427,7 +425,7 @@
 	for (i = 0; i < SAMSUNG_PWM_NUM; ++i)
 		pwm.irq[i] = irq_of_parse_and_map(np, i);
 
-	of_property_for_each_u32(np, "samsung,pwm-outputs", prop, cur, val) {
+	of_property_for_each_u32(np, "samsung,pwm-outputs", val) {
 		if (val >= SAMSUNG_PWM_NUM) {
 			pr_warn("%s: invalid channel index in samsung,pwm-outputs property\n", __func__);
 			continue;
--- linux-qcom-6.8.0.orig/drivers/clocksource/sh_cmt.c
+++ linux-qcom-6.8.0/drivers/clocksource/sh_cmt.c
@@ -528,6 +528,7 @@
 static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id)
 {
 	struct sh_cmt_channel *ch = dev_id;
+	unsigned long flags;
 
 	/* clear flags */
 	sh_cmt_write_cmcsr(ch, sh_cmt_read_cmcsr(ch) &
@@ -558,6 +559,8 @@
 
 	ch->flags &= ~FLAG_SKIPEVENT;
 
+	raw_spin_lock_irqsave(&ch->lock, flags);
+
 	if (ch->flags & FLAG_REPROGRAM) {
 		ch->flags &= ~FLAG_REPROGRAM;
 		sh_cmt_clock_event_program_verify(ch, 1);
@@ -570,6 +573,8 @@
 
 	ch->flags &= ~FLAG_IRQCONTEXT;
 
+	raw_spin_unlock_irqrestore(&ch->lock, flags);
+
 	return IRQ_HANDLED;
 }
 
@@ -780,12 +785,18 @@
 				   struct clock_event_device *ced)
 {
 	struct sh_cmt_channel *ch = ced_to_sh_cmt(ced);
+	unsigned long flags;
 
 	BUG_ON(!clockevent_state_oneshot(ced));
+
+	raw_spin_lock_irqsave(&ch->lock, flags);
+
 	if (likely(ch->flags & FLAG_IRQCONTEXT))
 		ch->next_match_value = delta - 1;
 	else
-		sh_cmt_set_next(ch, delta - 1);
+		__sh_cmt_set_next(ch, delta - 1);
+
+	raw_spin_unlock_irqrestore(&ch->lock, flags);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/clocksource/timer-imx-tpm.c
+++ linux-qcom-6.8.0/drivers/clocksource/timer-imx-tpm.c
@@ -83,20 +83,28 @@
 static int tpm_set_next_event(unsigned long delta,
 				struct clock_event_device *evt)
 {
-	unsigned long next, now;
+	unsigned long next, prev, now;
 
-	next = tpm_read_counter();
-	next += delta;
+	prev = tpm_read_counter();
+	next = prev + delta;
 	writel(next, timer_base + TPM_C0V);
 	now = tpm_read_counter();
 
 	/*
+	 * Need to wait CNT increase at least 1 cycle to make sure
+	 * the C0V has been updated into HW.
+	 */
+	if ((next & 0xffffffff) != readl(timer_base + TPM_C0V))
+		while (now == tpm_read_counter())
+			;
+
+	/*
 	 * NOTE: We observed in a very small probability, the bus fabric
 	 * contention between GPU and A7 may results a few cycles delay
 	 * of writing CNT registers which may cause the min_delta event got
 	 * missed, so we need add a ETIME check here in case it happened.
 	 */
-	return (int)(next - now) <= 0 ? -ETIME : 0;
+	return (now - prev) >= delta ? -ETIME : 0;
 }
 
 static int tpm_set_state_oneshot(struct clock_event_device *evt)
--- linux-qcom-6.8.0.orig/drivers/clocksource/timer-of.c
+++ linux-qcom-6.8.0/drivers/clocksource/timer-of.c
@@ -25,10 +25,7 @@
 
 	struct clock_event_device *clkevt = &to->clkevt;
 
-	if (of_irq->percpu)
-		free_percpu_irq(of_irq->irq, clkevt);
-	else
-		free_irq(of_irq->irq, clkevt);
+	free_irq(of_irq->irq, clkevt);
 }
 
 /**
@@ -42,9 +39,6 @@
  * - Get interrupt number by name
  * - Get interrupt number by index
  *
- * When the interrupt is per CPU, 'request_percpu_irq()' is called,
- * otherwise 'request_irq()' is used.
- *
  * Returns 0 on success, < 0 otherwise
  */
 static __init int timer_of_irq_init(struct device_node *np,
@@ -69,12 +63,9 @@
 		return -EINVAL;
 	}
 
-	ret = of_irq->percpu ?
-		request_percpu_irq(of_irq->irq, of_irq->handler,
-				   np->full_name, clkevt) :
-		request_irq(of_irq->irq, of_irq->handler,
-			    of_irq->flags ? of_irq->flags : IRQF_TIMER,
-			    np->full_name, clkevt);
+	ret = request_irq(of_irq->irq, of_irq->handler,
+			  of_irq->flags ? of_irq->flags : IRQF_TIMER,
+			  np->full_name, clkevt);
 	if (ret) {
 		pr_err("Failed to request irq %d for %pOF\n", of_irq->irq, np);
 		return ret;
--- linux-qcom-6.8.0.orig/drivers/clocksource/timer-of.h
+++ linux-qcom-6.8.0/drivers/clocksource/timer-of.h
@@ -11,7 +11,6 @@
 struct of_timer_irq {
 	int irq;
 	int index;
-	int percpu;
 	const char *name;
 	unsigned long flags;
 	irq_handler_t handler;
--- linux-qcom-6.8.0.orig/drivers/clocksource/timer-qcom.c
+++ linux-qcom-6.8.0/drivers/clocksource/timer-qcom.c
@@ -233,6 +233,7 @@
 	}
 
 	if (of_property_read_u32(np, "clock-frequency", &freq)) {
+		iounmap(cpu0_base);
 		pr_err("Unknown frequency\n");
 		return -EINVAL;
 	}
@@ -243,7 +244,11 @@
 	freq /= 4;
 	writel_relaxed(DGT_CLK_CTL_DIV_4, source_base + DGT_CLK_CTL);
 
-	return msm_timer_init(freq, 32, irq, !!percpu_offset);
+	ret = msm_timer_init(freq, 32, irq, !!percpu_offset);
+	if (ret)
+		iounmap(cpu0_base);
+
+	return ret;
 }
 TIMER_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
 TIMER_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
--- linux-qcom-6.8.0.orig/drivers/clocksource/timer-riscv.c
+++ linux-qcom-6.8.0/drivers/clocksource/timer-riscv.c
@@ -108,6 +108,9 @@
 {
 	struct clock_event_device *ce = per_cpu_ptr(&riscv_clock_event, cpu);
 
+	/* Clear timer interrupt */
+	riscv_clock_event_stop();
+
 	ce->cpumask = cpumask_of(cpu);
 	ce->irq = riscv_clock_event_irq;
 	if (riscv_timer_cannot_wake_cpu)
--- linux-qcom-6.8.0.orig/drivers/clocksource/timer-ti-dm-systimer.c
+++ linux-qcom-6.8.0/drivers/clocksource/timer-ti-dm-systimer.c
@@ -686,9 +686,9 @@
 
 static int __init dmtimer_percpu_quirk_init(struct device_node *np, u32 pa)
 {
-	struct device_node *arm_timer;
+	struct device_node *arm_timer __free(device_node) =
+		of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
 
-	arm_timer = of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
 	if (of_device_is_available(arm_timer)) {
 		pr_warn_once("ARM architected timer wrap issue i940 detected\n");
 		return 0;
--- linux-qcom-6.8.0.orig/drivers/comedi/comedi_fops.c
+++ linux-qcom-6.8.0/drivers/comedi/comedi_fops.c
@@ -2407,6 +2407,18 @@
 
 			start += PAGE_SIZE;
 		}
+
+#ifdef CONFIG_MMU
+		/*
+		 * Leaving behind a partial mapping of a buffer we're about to
+		 * drop is unsafe, see remap_pfn_range_notrack().
+		 * We need to zap the range here ourselves instead of relying
+		 * on the automatic zapping in remap_pfn_range() because we call
+		 * remap_pfn_range() in a loop.
+		 */
+		if (retval)
+			zap_vma_ptes(vma, vma->vm_start, size);
+#endif
 	}
 
 	if (retval == 0) {
--- linux-qcom-6.8.0.orig/drivers/comedi/drivers/ni_routing/tools/convert_c_to_py.c
+++ linux-qcom-6.8.0/drivers/comedi/drivers/ni_routing/tools/convert_c_to_py.c
@@ -140,6 +140,11 @@
 {
 	FILE *fp = fopen("ni_values.py", "w");
 
+	if (fp == NULL) {
+		fprintf(stderr, "Could not open file!");
+		return -1;
+	}
+
 	/* write route register values */
 	fprintf(fp, "ni_route_values = {\n");
 	for (int i = 0; ni_all_route_values[i]; ++i)
--- linux-qcom-6.8.0.orig/drivers/comedi/drivers/vmk80xx.c
+++ linux-qcom-6.8.0/drivers/comedi/drivers/vmk80xx.c
@@ -641,33 +641,22 @@
 	struct vmk80xx_private *devpriv = dev->private;
 	struct usb_interface *intf = comedi_to_usb_interface(dev);
 	struct usb_host_interface *iface_desc = intf->cur_altsetting;
-	struct usb_endpoint_descriptor *ep_desc;
-	int i;
+	struct usb_endpoint_descriptor *ep_rx_desc, *ep_tx_desc;
+	int ret;
 
-	if (iface_desc->desc.bNumEndpoints != 2)
-		return -ENODEV;
-
-	for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
-		ep_desc = &iface_desc->endpoint[i].desc;
-
-		if (usb_endpoint_is_int_in(ep_desc) ||
-		    usb_endpoint_is_bulk_in(ep_desc)) {
-			if (!devpriv->ep_rx)
-				devpriv->ep_rx = ep_desc;
-			continue;
-		}
+	if (devpriv->model == VMK8061_MODEL)
+		ret = usb_find_common_endpoints(iface_desc, &ep_rx_desc,
+						&ep_tx_desc, NULL, NULL);
+	else
+		ret = usb_find_common_endpoints(iface_desc, NULL, NULL,
+						&ep_rx_desc, &ep_tx_desc);
 
-		if (usb_endpoint_is_int_out(ep_desc) ||
-		    usb_endpoint_is_bulk_out(ep_desc)) {
-			if (!devpriv->ep_tx)
-				devpriv->ep_tx = ep_desc;
-			continue;
-		}
-	}
-
-	if (!devpriv->ep_rx || !devpriv->ep_tx)
+	if (ret)
 		return -ENODEV;
 
+	devpriv->ep_rx = ep_rx_desc;
+	devpriv->ep_tx = ep_tx_desc;
+
 	if (!usb_endpoint_maxp(devpriv->ep_rx) || !usb_endpoint_maxp(devpriv->ep_tx))
 		return -EINVAL;
 
--- linux-qcom-6.8.0.orig/drivers/counter/stm32-timer-cnt.c
+++ linux-qcom-6.8.0/drivers/counter/stm32-timer-cnt.c
@@ -195,11 +195,17 @@
 {
 	struct stm32_timer_cnt *const priv = counter_priv(counter);
 	u32 cr1;
+	int ret;
 
 	if (enable) {
 		regmap_read(priv->regmap, TIM_CR1, &cr1);
-		if (!(cr1 & TIM_CR1_CEN))
-			clk_enable(priv->clk);
+		if (!(cr1 & TIM_CR1_CEN)) {
+			ret = clk_enable(priv->clk);
+			if (ret) {
+				dev_err(counter->parent, "Cannot enable clock %d\n", ret);
+				return ret;
+			}
+		}
 
 		regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN,
 				   TIM_CR1_CEN);
@@ -383,7 +389,11 @@
 		return ret;
 
 	if (priv->enabled) {
-		clk_enable(priv->clk);
+		ret = clk_enable(priv->clk);
+		if (ret) {
+			dev_err(dev, "Cannot enable clock %d\n", ret);
+			return ret;
+		}
 
 		/* Restore registers that may have been lost */
 		regmap_write(priv->regmap, TIM_SMCR, priv->bak.smcr);
--- linux-qcom-6.8.0.orig/drivers/counter/ti-ecap-capture.c
+++ linux-qcom-6.8.0/drivers/counter/ti-ecap-capture.c
@@ -576,8 +576,13 @@
 {
 	struct counter_device *counter_dev = dev_get_drvdata(dev);
 	struct ecap_cnt_dev *ecap_dev = counter_priv(counter_dev);
+	int ret;
 
-	clk_enable(ecap_dev->clk);
+	ret = clk_enable(ecap_dev->clk);
+	if (ret) {
+		dev_err(dev, "Cannot enable clock %d\n", ret);
+		return ret;
+	}
 
 	ecap_cnt_capture_set_evmode(counter_dev, ecap_dev->pm_ctx.ev_mode);
 
--- linux-qcom-6.8.0.orig/drivers/counter/ti-eqep.c
+++ linux-qcom-6.8.0/drivers/counter/ti-eqep.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/bitops.h>
+#include <linux/clk.h>
 #include <linux/counter.h>
 #include <linux/kernel.h>
 #include <linux/mod_devicetable.h>
@@ -376,6 +377,7 @@
 	struct counter_device *counter;
 	struct ti_eqep_cnt *priv;
 	void __iomem *base;
+	struct clk *clk;
 	int err;
 
 	counter = devm_counter_alloc(dev, sizeof(*priv));
@@ -415,6 +417,10 @@
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
+	clk = devm_clk_get_enabled(dev, NULL);
+	if (IS_ERR(clk))
+		return dev_err_probe(dev, PTR_ERR(clk), "failed to enable clock\n");
+
 	err = counter_add(counter);
 	if (err < 0) {
 		pm_runtime_put_sync(dev);
--- linux-qcom-6.8.0.orig/drivers/cpufreq/Kconfig.arm
+++ linux-qcom-6.8.0/drivers/cpufreq/Kconfig.arm
@@ -173,6 +173,7 @@
 config ARM_QCOM_CPUFREQ_HW
 	tristate "QCOM CPUFreq HW driver"
 	depends on ARCH_QCOM || COMPILE_TEST
+	depends on COMMON_CLK
 	help
 	  Support for the CPUFreq HW driver.
 	  Some QCOM chipsets have a HW engine to offload the steps
--- linux-qcom-6.8.0.orig/drivers/cpufreq/acpi-cpufreq.c
+++ linux-qcom-6.8.0/drivers/cpufreq/acpi-cpufreq.c
@@ -628,7 +628,14 @@
 #endif
 
 #ifdef CONFIG_ACPI_CPPC_LIB
-static u64 get_max_boost_ratio(unsigned int cpu)
+/*
+ * get_max_boost_ratio: Computes the max_boost_ratio as the ratio
+ * between the highest_perf and the nominal_perf.
+ *
+ * Returns the max_boost_ratio for @cpu. Returns the CPPC nominal
+ * frequency via @nominal_freq if it is non-NULL pointer.
+ */
+static u64 get_max_boost_ratio(unsigned int cpu, u64 *nominal_freq)
 {
 	struct cppc_perf_caps perf_caps;
 	u64 highest_perf, nominal_perf;
@@ -651,6 +658,9 @@
 
 	nominal_perf = perf_caps.nominal_perf;
 
+	if (nominal_freq)
+		*nominal_freq = perf_caps.nominal_freq;
+
 	if (!highest_perf || !nominal_perf) {
 		pr_debug("CPU%d: highest or nominal performance missing\n", cpu);
 		return 0;
@@ -663,8 +673,12 @@
 
 	return div_u64(highest_perf << SCHED_CAPACITY_SHIFT, nominal_perf);
 }
+
 #else
-static inline u64 get_max_boost_ratio(unsigned int cpu) { return 0; }
+static inline u64 get_max_boost_ratio(unsigned int cpu, u64 *nominal_freq)
+{
+	return 0;
+}
 #endif
 
 static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
@@ -674,9 +688,9 @@
 	struct acpi_cpufreq_data *data;
 	unsigned int cpu = policy->cpu;
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
+	u64 max_boost_ratio, nominal_freq = 0;
 	unsigned int valid_states = 0;
 	unsigned int result = 0;
-	u64 max_boost_ratio;
 	unsigned int i;
 #ifdef CONFIG_SMP
 	static int blacklisted;
@@ -826,16 +840,20 @@
 	}
 	freq_table[valid_states].frequency = CPUFREQ_TABLE_END;
 
-	max_boost_ratio = get_max_boost_ratio(cpu);
+	max_boost_ratio = get_max_boost_ratio(cpu, &nominal_freq);
 	if (max_boost_ratio) {
-		unsigned int freq = freq_table[0].frequency;
+		unsigned int freq = nominal_freq;
 
 		/*
-		 * Because the loop above sorts the freq_table entries in the
-		 * descending order, freq is the maximum frequency in the table.
-		 * Assume that it corresponds to the CPPC nominal frequency and
-		 * use it to set cpuinfo.max_freq.
+		 * The loop above sorts the freq_table entries in the
+		 * descending order. If ACPI CPPC has not advertised
+		 * the nominal frequency (this is possible in CPPC
+		 * revisions prior to 3), then use the first entry in
+		 * the pstate table as a proxy for nominal frequency.
 		 */
+		if (!freq)
+			freq = freq_table[0].frequency;
+
 		policy->cpuinfo.max_freq = freq * max_boost_ratio >> SCHED_CAPACITY_SHIFT;
 	} else {
 		/*
@@ -890,8 +908,10 @@
 	if (perf->states[0].core_frequency * 1000 != freq_table[0].frequency)
 		pr_warn(FW_WARN "P-state 0 is not max freq\n");
 
-	if (acpi_cpufreq_driver.set_boost)
+	if (acpi_cpufreq_driver.set_boost) {
 		set_boost(policy, acpi_cpufreq_driver.boost_enabled);
+		policy->boost_enabled = acpi_cpufreq_driver.boost_enabled;
+	}
 
 	return result;
 
--- linux-qcom-6.8.0.orig/drivers/cpufreq/amd-pstate-ut.c
+++ linux-qcom-6.8.0/drivers/cpufreq/amd-pstate-ut.c
@@ -26,10 +26,11 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/fs.h>
-#include <linux/amd-pstate.h>
 
 #include <acpi/cppc_acpi.h>
 
+#include "amd-pstate.h"
+
 /*
  * Abbreviations:
  * amd_pstate_ut: used as a shortform for AMD P-State unit test.
@@ -201,6 +202,7 @@
 	int cpu = 0;
 	struct cpufreq_policy *policy = NULL;
 	struct amd_cpudata *cpudata = NULL;
+	u32 nominal_freq_khz;
 
 	for_each_possible_cpu(cpu) {
 		policy = cpufreq_cpu_get(cpu);
@@ -208,13 +210,14 @@
 			break;
 		cpudata = policy->driver_data;
 
-		if (!((cpudata->max_freq >= cpudata->nominal_freq) &&
-			(cpudata->nominal_freq > cpudata->lowest_nonlinear_freq) &&
+		nominal_freq_khz = cpudata->nominal_freq*1000;
+		if (!((cpudata->max_freq >= nominal_freq_khz) &&
+			(nominal_freq_khz > cpudata->lowest_nonlinear_freq) &&
 			(cpudata->lowest_nonlinear_freq > cpudata->min_freq) &&
 			(cpudata->min_freq > 0))) {
 			amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL;
 			pr_err("%s cpu%d max=%d >= nominal=%d > lowest_nonlinear=%d > min=%d > 0, the formula is incorrect!\n",
-				__func__, cpu, cpudata->max_freq, cpudata->nominal_freq,
+				__func__, cpu, cpudata->max_freq, nominal_freq_khz,
 				cpudata->lowest_nonlinear_freq, cpudata->min_freq);
 			goto skip_test;
 		}
@@ -228,13 +231,13 @@
 
 		if (cpudata->boost_supported) {
 			if ((policy->max == cpudata->max_freq) ||
-					(policy->max == cpudata->nominal_freq))
+					(policy->max == nominal_freq_khz))
 				amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS;
 			else {
 				amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL;
 				pr_err("%s cpu%d policy_max=%d should be equal cpu_max=%d or cpu_nominal=%d !\n",
 					__func__, cpu, policy->max, cpudata->max_freq,
-					cpudata->nominal_freq);
+					nominal_freq_khz);
 				goto skip_test;
 			}
 		} else {
--- linux-qcom-6.8.0.orig/drivers/cpufreq/amd-pstate.c
+++ linux-qcom-6.8.0/drivers/cpufreq/amd-pstate.c
@@ -36,7 +36,7 @@
 #include <linux/delay.h>
 #include <linux/uaccess.h>
 #include <linux/static_call.h>
-#include <linux/amd-pstate.h>
+#include <linux/topology.h>
 
 #include <acpi/processor.h>
 #include <acpi/cppc_acpi.h>
@@ -45,10 +45,45 @@
 #include <asm/processor.h>
 #include <asm/cpufeature.h>
 #include <asm/cpu_device_id.h>
+
+#include "amd-pstate.h"
 #include "amd-pstate-trace.h"
 
 #define AMD_PSTATE_TRANSITION_LATENCY	20000
 #define AMD_PSTATE_TRANSITION_DELAY	1000
+#define CPPC_HIGHEST_PERF_PERFORMANCE	196
+#define CPPC_HIGHEST_PERF_DEFAULT	166
+
+#define AMD_CPPC_EPP_PERFORMANCE		0x00
+#define AMD_CPPC_EPP_BALANCE_PERFORMANCE	0x80
+#define AMD_CPPC_EPP_BALANCE_POWERSAVE		0xBF
+#define AMD_CPPC_EPP_POWERSAVE			0xFF
+
+/*
+ * enum amd_pstate_mode - driver working mode of amd pstate
+ */
+enum amd_pstate_mode {
+	AMD_PSTATE_UNDEFINED = 0,
+	AMD_PSTATE_DISABLE,
+	AMD_PSTATE_PASSIVE,
+	AMD_PSTATE_ACTIVE,
+	AMD_PSTATE_GUIDED,
+	AMD_PSTATE_MAX,
+};
+
+static const char * const amd_pstate_mode_string[] = {
+	[AMD_PSTATE_UNDEFINED]   = "undefined",
+	[AMD_PSTATE_DISABLE]     = "disable",
+	[AMD_PSTATE_PASSIVE]     = "passive",
+	[AMD_PSTATE_ACTIVE]      = "active",
+	[AMD_PSTATE_GUIDED]      = "guided",
+	NULL,
+};
+
+struct quirk_entry {
+	u32 nominal_freq;
+	u32 lowest_freq;
+};
 
 /*
  * TODO: We need more time to fine tune processors with shared memory solution
@@ -64,6 +99,8 @@
 static struct cpufreq_driver amd_pstate_epp_driver;
 static int cppc_state = AMD_PSTATE_UNDEFINED;
 static bool cppc_enabled;
+static struct quirk_entry *quirks;
+static bool amd_pstate_prefcore = true;
 
 /*
  * AMD Energy Preference Performance (EPP)
@@ -108,6 +145,41 @@
 
 typedef int (*cppc_mode_transition_fn)(int);
 
+static struct quirk_entry quirk_amd_7k62 = {
+	.nominal_freq = 2600,
+	.lowest_freq = 550,
+};
+
+static int __init dmi_matched_7k62_bios_bug(const struct dmi_system_id *dmi)
+{
+	/**
+	 * match the broken bios for family 17h processor support CPPC V2
+	 * broken BIOS lack of nominal_freq and lowest_freq capabilities
+	 * definition in ACPI tables
+	 */
+	if (boot_cpu_has(X86_FEATURE_ZEN2)) {
+		quirks = dmi->driver_data;
+		pr_info("Overriding nominal and lowest frequencies for %s\n", dmi->ident);
+		return 1;
+	}
+
+	return 0;
+}
+
+static const struct dmi_system_id amd_pstate_quirks_table[] __initconst = {
+	{
+		.callback = dmi_matched_7k62_bios_bug,
+		.ident = "AMD EPYC 7K62",
+		.matches = {
+			DMI_MATCH(DMI_BIOS_VERSION, "5.14"),
+			DMI_MATCH(DMI_BIOS_RELEASE, "12/12/2019"),
+		},
+		.driver_data = &quirk_amd_7k62,
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(dmi, amd_pstate_quirks_table);
+
 static inline int get_mode_idx_from_str(const char *str, size_t size)
 {
 	int i;
@@ -175,6 +247,26 @@
 	return index;
 }
 
+static void pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
+			       u32 des_perf, u32 max_perf, bool fast_switch)
+{
+	if (fast_switch)
+		wrmsrl(MSR_AMD_CPPC_REQ, READ_ONCE(cpudata->cppc_req_cached));
+	else
+		wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ,
+			      READ_ONCE(cpudata->cppc_req_cached));
+}
+
+DEFINE_STATIC_CALL(amd_pstate_update_perf, pstate_update_perf);
+
+static inline void amd_pstate_update_perf(struct amd_cpudata *cpudata,
+					  u32 min_perf, u32 des_perf,
+					  u32 max_perf, bool fast_switch)
+{
+	static_call(amd_pstate_update_perf)(cpudata, min_perf, des_perf,
+					    max_perf, fast_switch);
+}
+
 static int amd_pstate_set_epp(struct amd_cpudata *cpudata, u32 epp)
 {
 	int ret;
@@ -191,6 +283,9 @@
 		if (!ret)
 			cpudata->epp_cached = epp;
 	} else {
+		amd_pstate_update_perf(cpudata, cpudata->min_limit_perf, 0U,
+					     cpudata->max_limit_perf, false);
+
 		perf_ctrls.energy_perf = epp;
 		ret = cppc_set_epp_perf(cpudata->cpu, &perf_ctrls, 1);
 		if (ret) {
@@ -209,10 +304,8 @@
 	int epp = -EINVAL;
 	int ret;
 
-	if (!pref_index) {
-		pr_debug("EPP pref_index is invalid\n");
-		return -EINVAL;
-	}
+	if (!pref_index)
+		epp = cpudata->epp_default;
 
 	if (epp == -EINVAL)
 		epp = epp_values[pref_index];
@@ -287,6 +380,21 @@
 	return static_call(amd_pstate_enable)(enable);
 }
 
+static u32 amd_pstate_highest_perf_set(struct amd_cpudata *cpudata)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+
+	/*
+	 * For AMD CPUs with Family ID 19H and Model ID range 0x70 to 0x7f,
+	 * the highest performance level is set to 196.
+	 * https://bugzilla.kernel.org/show_bug.cgi?id=218759
+	 */
+	if (c->x86 == 0x19 && (c->x86_model >= 0x70 && c->x86_model <= 0x7f))
+		return CPPC_HIGHEST_PERF_PERFORMANCE;
+
+	return CPPC_HIGHEST_PERF_DEFAULT;
+}
+
 static int pstate_init_perf(struct amd_cpudata *cpudata)
 {
 	u64 cap1;
@@ -297,13 +405,14 @@
 	if (ret)
 		return ret;
 
-	/*
-	 * TODO: Introduce AMD specific power feature.
-	 *
-	 * CPPC entry doesn't indicate the highest performance in some ASICs.
+	/* For platforms that do not support the preferred core feature, the
+	 * highest_pef may be configured with 166 or 255, to avoid max frequency
+	 * calculated wrongly. we take the AMD_CPPC_HIGHEST_PERF(cap1) value as
+	 * the default max perf.
 	 */
-	highest_perf = amd_get_highest_perf();
-	if (highest_perf > AMD_CPPC_HIGHEST_PERF(cap1))
+	if (cpudata->hw_prefcore)
+		highest_perf = amd_pstate_highest_perf_set(cpudata);
+	else
 		highest_perf = AMD_CPPC_HIGHEST_PERF(cap1);
 
 	WRITE_ONCE(cpudata->highest_perf, highest_perf);
@@ -324,8 +433,9 @@
 	if (ret)
 		return ret;
 
-	highest_perf = amd_get_highest_perf();
-	if (highest_perf > cppc_perf.highest_perf)
+	if (cpudata->hw_prefcore)
+		highest_perf = amd_pstate_highest_perf_set(cpudata);
+	else
 		highest_perf = cppc_perf.highest_perf;
 
 	WRITE_ONCE(cpudata->highest_perf, highest_perf);
@@ -361,16 +471,6 @@
 	return static_call(amd_pstate_init_perf)(cpudata);
 }
 
-static void pstate_update_perf(struct amd_cpudata *cpudata, u32 min_perf,
-			       u32 des_perf, u32 max_perf, bool fast_switch)
-{
-	if (fast_switch)
-		wrmsrl(MSR_AMD_CPPC_REQ, READ_ONCE(cpudata->cppc_req_cached));
-	else
-		wrmsrl_on_cpu(cpudata->cpu, MSR_AMD_CPPC_REQ,
-			      READ_ONCE(cpudata->cppc_req_cached));
-}
-
 static void cppc_update_perf(struct amd_cpudata *cpudata,
 			     u32 min_perf, u32 des_perf,
 			     u32 max_perf, bool fast_switch)
@@ -384,16 +484,6 @@
 	cppc_set_perf(cpudata->cpu, &perf_ctrls);
 }
 
-DEFINE_STATIC_CALL(amd_pstate_update_perf, pstate_update_perf);
-
-static inline void amd_pstate_update_perf(struct amd_cpudata *cpudata,
-					  u32 min_perf, u32 des_perf,
-					  u32 max_perf, bool fast_switch)
-{
-	static_call(amd_pstate_update_perf)(cpudata, min_perf, des_perf,
-					    max_perf, fast_switch);
-}
-
 static inline bool amd_pstate_sample(struct amd_cpudata *cpudata)
 {
 	u64 aperf, mperf, tsc;
@@ -555,9 +645,14 @@
 	unsigned long max_perf, min_perf, des_perf,
 		      cap_perf, lowest_nonlinear_perf, max_freq;
 	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-	struct amd_cpudata *cpudata = policy->driver_data;
+	struct amd_cpudata *cpudata;
 	unsigned int target_freq;
 
+	if (!policy)
+		return;
+
+	cpudata = policy->driver_data;
+
 	if (policy->min != cpudata->min_limit_freq || policy->max != cpudata->max_limit_freq)
 		amd_pstate_update_min_max_limit(policy);
 
@@ -570,7 +665,7 @@
 	if (target_perf < capacity)
 		des_perf = DIV_ROUND_UP(cap_perf * target_perf, capacity);
 
-	min_perf = READ_ONCE(cpudata->highest_perf);
+	min_perf = READ_ONCE(cpudata->lowest_perf);
 	if (_min_perf < capacity)
 		min_perf = DIV_ROUND_UP(cap_perf * _min_perf, capacity);
 
@@ -592,74 +687,22 @@
 
 static int amd_get_min_freq(struct amd_cpudata *cpudata)
 {
-	struct cppc_perf_caps cppc_perf;
-
-	int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
-	if (ret)
-		return ret;
-
-	/* Switch to khz */
-	return cppc_perf.lowest_freq * 1000;
+	return READ_ONCE(cpudata->min_freq);
 }
 
 static int amd_get_max_freq(struct amd_cpudata *cpudata)
 {
-	struct cppc_perf_caps cppc_perf;
-	u32 max_perf, max_freq, nominal_freq, nominal_perf;
-	u64 boost_ratio;
-
-	int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
-	if (ret)
-		return ret;
-
-	nominal_freq = cppc_perf.nominal_freq;
-	nominal_perf = READ_ONCE(cpudata->nominal_perf);
-	max_perf = READ_ONCE(cpudata->highest_perf);
-
-	boost_ratio = div_u64(max_perf << SCHED_CAPACITY_SHIFT,
-			      nominal_perf);
-
-	max_freq = nominal_freq * boost_ratio >> SCHED_CAPACITY_SHIFT;
-
-	/* Switch to khz */
-	return max_freq * 1000;
+	return READ_ONCE(cpudata->max_freq);
 }
 
 static int amd_get_nominal_freq(struct amd_cpudata *cpudata)
 {
-	struct cppc_perf_caps cppc_perf;
-
-	int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
-	if (ret)
-		return ret;
-
-	/* Switch to khz */
-	return cppc_perf.nominal_freq * 1000;
+	return READ_ONCE(cpudata->nominal_freq);
 }
 
 static int amd_get_lowest_nonlinear_freq(struct amd_cpudata *cpudata)
 {
-	struct cppc_perf_caps cppc_perf;
-	u32 lowest_nonlinear_freq, lowest_nonlinear_perf,
-	    nominal_freq, nominal_perf;
-	u64 lowest_nonlinear_ratio;
-
-	int ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
-	if (ret)
-		return ret;
-
-	nominal_freq = cppc_perf.nominal_freq;
-	nominal_perf = READ_ONCE(cpudata->nominal_perf);
-
-	lowest_nonlinear_perf = cppc_perf.lowest_nonlinear_perf;
-
-	lowest_nonlinear_ratio = div_u64(lowest_nonlinear_perf << SCHED_CAPACITY_SHIFT,
-					 nominal_perf);
-
-	lowest_nonlinear_freq = nominal_freq * lowest_nonlinear_ratio >> SCHED_CAPACITY_SHIFT;
-
-	/* Switch to khz */
-	return lowest_nonlinear_freq * 1000;
+	return READ_ONCE(cpudata->lowest_nonlinear_freq);
 }
 
 static int amd_pstate_set_boost(struct cpufreq_policy *policy, int state)
@@ -675,7 +718,7 @@
 	if (state)
 		policy->cpuinfo.max_freq = cpudata->max_freq;
 	else
-		policy->cpuinfo.max_freq = cpudata->nominal_freq;
+		policy->cpuinfo.max_freq = cpudata->nominal_freq * 1000;
 
 	policy->max = policy->cpuinfo.max_freq;
 
@@ -706,6 +749,135 @@
 	wrmsrl_on_cpu(cpu, MSR_AMD_PERF_CTL, 0);
 }
 
+/**
+ * amd_pstate_init_freq: Initialize the max_freq, min_freq,
+ *                       nominal_freq and lowest_nonlinear_freq for
+ *                       the @cpudata object.
+ *
+ *  Requires: highest_perf, lowest_perf, nominal_perf and
+ *            lowest_nonlinear_perf members of @cpudata to be
+ *            initialized.
+ *
+ *  Returns 0 on success, non-zero value on failure.
+ */
+static int amd_pstate_init_freq(struct amd_cpudata *cpudata)
+{
+	int ret;
+	u32 min_freq;
+	u32 highest_perf, max_freq;
+	u32 nominal_perf, nominal_freq;
+	u32 lowest_nonlinear_perf, lowest_nonlinear_freq;
+	u32 boost_ratio, lowest_nonlinear_ratio;
+	struct cppc_perf_caps cppc_perf;
+
+
+	ret = cppc_get_perf_caps(cpudata->cpu, &cppc_perf);
+	if (ret)
+		return ret;
+
+	if (quirks && quirks->lowest_freq)
+		min_freq = quirks->lowest_freq * 1000;
+	else
+		min_freq = cppc_perf.lowest_freq * 1000;
+
+	if (quirks && quirks->nominal_freq)
+		nominal_freq = quirks->nominal_freq ;
+	else
+		nominal_freq = cppc_perf.nominal_freq;
+
+	nominal_perf = READ_ONCE(cpudata->nominal_perf);
+
+	highest_perf = READ_ONCE(cpudata->highest_perf);
+	boost_ratio = div_u64(highest_perf << SCHED_CAPACITY_SHIFT, nominal_perf);
+	max_freq = (nominal_freq * boost_ratio >> SCHED_CAPACITY_SHIFT) * 1000;
+
+	lowest_nonlinear_perf = READ_ONCE(cpudata->lowest_nonlinear_perf);
+	lowest_nonlinear_ratio = div_u64(lowest_nonlinear_perf << SCHED_CAPACITY_SHIFT,
+					 nominal_perf);
+	lowest_nonlinear_freq = (nominal_freq * lowest_nonlinear_ratio >> SCHED_CAPACITY_SHIFT) * 1000;
+
+	WRITE_ONCE(cpudata->min_freq, min_freq);
+	WRITE_ONCE(cpudata->lowest_nonlinear_freq, lowest_nonlinear_freq);
+	WRITE_ONCE(cpudata->nominal_freq, nominal_freq);
+	WRITE_ONCE(cpudata->max_freq, max_freq);
+
+	return 0;
+}
+
+/*
+ * Set amd-pstate preferred core enable can't be done directly from cpufreq callbacks
+ * due to locking, so queue the work for later.
+ */
+static void amd_pstste_sched_prefcore_workfn(struct work_struct *work)
+{
+	sched_set_itmt_support();
+}
+static DECLARE_WORK(sched_prefcore_work, amd_pstste_sched_prefcore_workfn);
+
+/*
+ * Get the highest performance register value.
+ * @cpu: CPU from which to get highest performance.
+ * @highest_perf: Return address.
+ *
+ * Return: 0 for success, -EIO otherwise.
+ */
+static int amd_pstate_get_highest_perf(int cpu, u32 *highest_perf)
+{
+	int ret;
+
+	if (boot_cpu_has(X86_FEATURE_CPPC)) {
+		u64 cap1;
+
+		ret = rdmsrl_safe_on_cpu(cpu, MSR_AMD_CPPC_CAP1, &cap1);
+		if (ret)
+			return ret;
+		WRITE_ONCE(*highest_perf, AMD_CPPC_HIGHEST_PERF(cap1));
+	} else {
+		u64 cppc_highest_perf;
+
+		ret = cppc_get_highest_perf(cpu, &cppc_highest_perf);
+		if (ret)
+			return ret;
+		WRITE_ONCE(*highest_perf, cppc_highest_perf);
+	}
+
+	return (ret);
+}
+
+#define CPPC_MAX_PERF	U8_MAX
+
+static void amd_pstate_init_prefcore(struct amd_cpudata *cpudata)
+{
+	int ret, prio;
+	u32 highest_perf;
+
+	ret = amd_pstate_get_highest_perf(cpudata->cpu, &highest_perf);
+	if (ret)
+		return;
+
+	cpudata->hw_prefcore = true;
+	/* check if CPPC preferred core feature is enabled*/
+	if (highest_perf < CPPC_MAX_PERF)
+		prio = (int)highest_perf;
+	else {
+		pr_debug("AMD CPPC preferred core is unsupported!\n");
+		cpudata->hw_prefcore = false;
+		return;
+	}
+
+	if (!amd_pstate_prefcore)
+		return;
+
+	/*
+	 * The priorities can be set regardless of whether or not
+	 * sched_set_itmt_support(true) has been called and it is valid to
+	 * update them at any time after it has been called.
+	 */
+	sched_set_itmt_core_prio(prio, cpudata->cpu);
+
+	schedule_work(&sched_prefcore_work);
+}
+
 static int amd_pstate_cpu_init(struct cpufreq_policy *policy)
 {
 	int min_freq, max_freq, nominal_freq, lowest_nonlinear_freq, ret;
@@ -727,10 +899,16 @@
 
 	cpudata->cpu = policy->cpu;
 
+	amd_pstate_init_prefcore(cpudata);
+
 	ret = amd_pstate_init_perf(cpudata);
 	if (ret)
 		goto free_cpudata1;
 
+	ret = amd_pstate_init_freq(cpudata);
+	if (ret)
+		goto free_cpudata1;
+
 	min_freq = amd_get_min_freq(cpudata);
 	max_freq = amd_get_max_freq(cpudata);
 	nominal_freq = amd_get_nominal_freq(cpudata);
@@ -772,13 +950,8 @@
 		goto free_cpudata2;
 	}
 
-	/* Initial processor data capability frequencies */
-	cpudata->max_freq = max_freq;
-	cpudata->min_freq = min_freq;
 	cpudata->max_limit_freq = max_freq;
 	cpudata->min_limit_freq = min_freq;
-	cpudata->nominal_freq = nominal_freq;
-	cpudata->lowest_nonlinear_freq = lowest_nonlinear_freq;
 
 	policy->driver_data = cpudata;
 
@@ -877,6 +1050,17 @@
 	return sysfs_emit(buf, "%u\n", perf);
 }
 
+static ssize_t show_amd_pstate_hw_prefcore(struct cpufreq_policy *policy,
+					   char *buf)
+{
+	bool hw_prefcore;
+	struct amd_cpudata *cpudata = policy->driver_data;
+
+	hw_prefcore = READ_ONCE(cpudata->hw_prefcore);
+
+	return sysfs_emit(buf, "%s\n", str_enabled_disabled(hw_prefcore));
+}
+
 static ssize_t show_energy_performance_available_preferences(
 				struct cpufreq_policy *policy, char *buf)
 {
@@ -950,11 +1134,21 @@
 		return -EINVAL;
 
 	cppc_state = mode;
+
+	ret = amd_pstate_enable(true);
+	if (ret) {
+		pr_err("failed to enable cppc during amd-pstate driver registration, return %d\n",
+		       ret);
+		amd_pstate_driver_cleanup();
+		return ret;
+	}
+
 	ret = cpufreq_register_driver(current_pstate_driver);
 	if (ret) {
 		amd_pstate_driver_cleanup();
 		return ret;
 	}
+
 	return 0;
 }
 
@@ -1074,18 +1268,27 @@
 	return ret < 0 ? ret : count;
 }
 
+static ssize_t prefcore_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	return sysfs_emit(buf, "%s\n", str_enabled_disabled(amd_pstate_prefcore));
+}
+
 cpufreq_freq_attr_ro(amd_pstate_max_freq);
 cpufreq_freq_attr_ro(amd_pstate_lowest_nonlinear_freq);
 
 cpufreq_freq_attr_ro(amd_pstate_highest_perf);
+cpufreq_freq_attr_ro(amd_pstate_hw_prefcore);
 cpufreq_freq_attr_rw(energy_performance_preference);
 cpufreq_freq_attr_ro(energy_performance_available_preferences);
 static DEVICE_ATTR_RW(status);
+static DEVICE_ATTR_RO(prefcore);
 
 static struct freq_attr *amd_pstate_attr[] = {
 	&amd_pstate_max_freq,
 	&amd_pstate_lowest_nonlinear_freq,
 	&amd_pstate_highest_perf,
+	&amd_pstate_hw_prefcore,
 	NULL,
 };
 
@@ -1093,6 +1296,7 @@
 	&amd_pstate_max_freq,
 	&amd_pstate_lowest_nonlinear_freq,
 	&amd_pstate_highest_perf,
+	&amd_pstate_hw_prefcore,
 	&energy_performance_preference,
 	&energy_performance_available_preferences,
 	NULL,
@@ -1100,6 +1304,7 @@
 
 static struct attribute *pstate_global_attributes[] = {
 	&dev_attr_status.attr,
+	&dev_attr_prefcore.attr,
 	NULL
 };
 
@@ -1151,10 +1356,16 @@
 	cpudata->cpu = policy->cpu;
 	cpudata->epp_policy = 0;
 
+	amd_pstate_init_prefcore(cpudata);
+
 	ret = amd_pstate_init_perf(cpudata);
 	if (ret)
 		goto free_cpudata1;
 
+	ret = amd_pstate_init_freq(cpudata);
+	if (ret)
+		goto free_cpudata1;
+
 	min_freq = amd_get_min_freq(cpudata);
 	max_freq = amd_get_max_freq(cpudata);
 	nominal_freq = amd_get_nominal_freq(cpudata);
@@ -1171,15 +1382,9 @@
 	/* It will be updated by governor */
 	policy->cur = policy->cpuinfo.min_freq;
 
-	/* Initial processor data capability frequencies */
-	cpudata->max_freq = max_freq;
-	cpudata->min_freq = min_freq;
-	cpudata->nominal_freq = nominal_freq;
-	cpudata->lowest_nonlinear_freq = lowest_nonlinear_freq;
-
 	policy->driver_data = cpudata;
 
-	cpudata->epp_cached = amd_pstate_get_epp(cpudata, 0);
+	cpudata->epp_cached = cpudata->epp_default = amd_pstate_get_epp(cpudata, 0);
 
 	policy->min = policy->cpuinfo.min_freq;
 	policy->max = policy->cpuinfo.max_freq;
@@ -1216,6 +1421,13 @@
 
 static int amd_pstate_epp_cpu_exit(struct cpufreq_policy *policy)
 {
+	struct amd_cpudata *cpudata = policy->driver_data;
+
+	if (cpudata) {
+		kfree(cpudata);
+		policy->driver_data = NULL;
+	}
+
 	pr_debug("CPU %d exiting\n", policy->cpu);
 	return 0;
 }
@@ -1242,7 +1454,7 @@
 	value = READ_ONCE(cpudata->cppc_req_cached);
 
 	if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE)
-		min_perf = max_perf;
+		min_perf = min(cpudata->nominal_perf, max_perf);
 
 	/* Initial min/max values for CPPC Performance Controls Register */
 	value &= ~AMD_CPPC_MIN_PERF(~0L);
@@ -1486,8 +1698,18 @@
 	if (cpufreq_get_current_driver())
 		return -EEXIST;
 
-	switch (cppc_state) {
-	case AMD_PSTATE_UNDEFINED:
+	quirks = NULL;
+
+	/* check if this machine need CPPC quirks */
+	dmi_check_system(amd_pstate_quirks_table);
+
+	/*
+	* determine the driver mode from the command line or kernel config.
+	* If no command line input is provided, cppc_state will be AMD_PSTATE_UNDEFINED.
+	* command line options will override the kernel config settings.
+	*/
+
+	if (cppc_state == AMD_PSTATE_UNDEFINED) {
 		/* Disable on the following configs by default:
 		 * 1. Undefined platforms
 		 * 2. Server platforms
@@ -1499,15 +1721,20 @@
 			pr_info("driver load is disabled, boot with specific mode to enable this\n");
 			return -ENODEV;
 		}
-		ret = amd_pstate_set_driver(CONFIG_X86_AMD_PSTATE_DEFAULT_MODE);
-		if (ret)
-			return ret;
-		break;
+		/* get driver mode from kernel config option [1:4] */
+		cppc_state = CONFIG_X86_AMD_PSTATE_DEFAULT_MODE;
+	}
+
+	switch (cppc_state) {
 	case AMD_PSTATE_DISABLE:
+		pr_info("driver load is disabled, boot with specific mode to enable this\n");
 		return -ENODEV;
 	case AMD_PSTATE_PASSIVE:
 	case AMD_PSTATE_ACTIVE:
 	case AMD_PSTATE_GUIDED:
+		ret = amd_pstate_set_driver(cppc_state);
+		if (ret)
+			return ret;
 		break;
 	default:
 		return -EINVAL;
@@ -1528,7 +1755,7 @@
 	/* enable amd pstate feature */
 	ret = amd_pstate_enable(true);
 	if (ret) {
-		pr_err("failed to enable with return %d\n", ret);
+		pr_err("failed to enable driver mode(%d)\n", cppc_state);
 		return ret;
 	}
 
@@ -1567,7 +1794,17 @@
 
 	return amd_pstate_set_driver(mode_idx);
 }
+
+static int __init amd_prefcore_param(char *str)
+{
+	if (!strcmp(str, "disable"))
+		amd_pstate_prefcore = false;
+
+	return 0;
+}
+
 early_param("amd_pstate", amd_pstate_param);
+early_param("amd_prefcore", amd_prefcore_param);
 
 MODULE_AUTHOR("Huang Rui <ray.huang@amd.com>");
 MODULE_DESCRIPTION("AMD Processor P-state Frequency Driver");
--- linux-qcom-6.8.0.orig/drivers/cpufreq/amd-pstate.h
+++ linux-qcom-6.8.0/drivers/cpufreq/amd-pstate.h
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2022 Advanced Micro Devices, Inc.
+ *
+ * Author: Meng Li <li.meng@amd.com>
+ */
+
+#ifndef _LINUX_AMD_PSTATE_H
+#define _LINUX_AMD_PSTATE_H
+
+#include <linux/pm_qos.h>
+
+/*********************************************************************
+ *                        AMD P-state INTERFACE                       *
+ *********************************************************************/
+/**
+ * struct  amd_aperf_mperf
+ * @aperf: actual performance frequency clock count
+ * @mperf: maximum performance frequency clock count
+ * @tsc:   time stamp counter
+ */
+struct amd_aperf_mperf {
+	u64 aperf;
+	u64 mperf;
+	u64 tsc;
+};
+
+/**
+ * struct amd_cpudata - private CPU data for AMD P-State
+ * @cpu: CPU number
+ * @req: constraint request to apply
+ * @cppc_req_cached: cached performance request hints
+ * @highest_perf: the maximum performance an individual processor may reach,
+ *		  assuming ideal conditions
+ * @nominal_perf: the maximum sustained performance level of the processor,
+ *		  assuming ideal operating conditions
+ * @lowest_nonlinear_perf: the lowest performance level at which nonlinear power
+ *			   savings are achieved
+ * @lowest_perf: the absolute lowest performance level of the processor
+ * @max_freq: the frequency that mapped to highest_perf
+ * @min_freq: the frequency that mapped to lowest_perf
+ * @nominal_freq: the frequency that mapped to nominal_perf
+ * @lowest_nonlinear_freq: the frequency that mapped to lowest_nonlinear_perf
+ * @cur: Difference of Aperf/Mperf/tsc count between last and current sample
+ * @prev: Last Aperf/Mperf/tsc count value read from register
+ * @freq: current cpu frequency value
+ * @boost_supported: check whether the Processor or SBIOS supports boost mode
+ * @hw_prefcore: check whether HW supports preferred core featue.
+ * 		  Only when hw_prefcore and early prefcore param are true,
+ * 		  AMD P-State driver supports preferred core featue.
+ * @epp_policy: Last saved policy used to set energy-performance preference
+ * @epp_cached: Cached CPPC energy-performance preference value
+ * @policy: Cpufreq policy value
+ * @cppc_cap1_cached Cached MSR_AMD_CPPC_CAP1 register value
+ *
+ * The amd_cpudata is key private data for each CPU thread in AMD P-State, and
+ * represents all the attributes and goals that AMD P-State requests at runtime.
+ */
+struct amd_cpudata {
+	int	cpu;
+
+	struct	freq_qos_request req[2];
+	u64	cppc_req_cached;
+
+	u32	highest_perf;
+	u32	nominal_perf;
+	u32	lowest_nonlinear_perf;
+	u32	lowest_perf;
+	u32     min_limit_perf;
+	u32     max_limit_perf;
+	u32     min_limit_freq;
+	u32     max_limit_freq;
+
+	u32	max_freq;
+	u32	min_freq;
+	u32	nominal_freq;
+	u32	lowest_nonlinear_freq;
+
+	struct amd_aperf_mperf cur;
+	struct amd_aperf_mperf prev;
+
+	u64	freq;
+	bool	boost_supported;
+	bool	hw_prefcore;
+
+	/* EPP feature related attributes*/
+	s16	epp_policy;
+	s16	epp_cached;
+	u32	policy;
+	u64	cppc_cap1_cached;
+	bool	suspended;
+	s16	epp_default;
+};
+
+#endif /* _LINUX_AMD_PSTATE_H */
--- linux-qcom-6.8.0.orig/drivers/cpufreq/brcmstb-avs-cpufreq.c
+++ linux-qcom-6.8.0/drivers/cpufreq/brcmstb-avs-cpufreq.c
@@ -481,7 +481,12 @@
 static unsigned int brcm_avs_cpufreq_get(unsigned int cpu)
 {
 	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-	struct private_data *priv = policy->driver_data;
+	struct private_data *priv;
+
+	if (!policy)
+		return 0;
+
+	priv = policy->driver_data;
 
 	cpufreq_cpu_put(policy);
 
--- linux-qcom-6.8.0.orig/drivers/cpufreq/cppc_cpufreq.c
+++ linux-qcom-6.8.0/drivers/cpufreq/cppc_cpufreq.c
@@ -118,6 +118,9 @@
 
 	perf = cppc_perf_from_fbctrs(cpu_data, &cppc_fi->prev_perf_fb_ctrs,
 				     &fb_ctrs);
+	if (!perf)
+		return;
+
 	cppc_fi->prev_perf_fb_ctrs = fb_ctrs;
 
 	perf <<= SCHED_CAPACITY_SHIFT;
@@ -425,6 +428,9 @@
 	struct cppc_cpudata *cpu_data;
 
 	policy = cpufreq_cpu_get_raw(cpu_dev->id);
+	if (!policy)
+		return -EINVAL;
+
 	cpu_data = policy->driver_data;
 	perf_caps = &cpu_data->perf_caps;
 	max_cap = arch_scale_cpu_capacity(cpu_dev->id);
@@ -492,6 +498,9 @@
 	int step;
 
 	policy = cpufreq_cpu_get_raw(cpu_dev->id);
+	if (!policy)
+		return -EINVAL;
+
 	cpu_data = policy->driver_data;
 	perf_caps = &cpu_data->perf_caps;
 	max_cap = arch_scale_cpu_capacity(cpu_dev->id);
@@ -730,35 +739,72 @@
 	delta_delivered = get_delta(fb_ctrs_t1->delivered,
 				    fb_ctrs_t0->delivered);
 
-	/* Check to avoid divide-by zero and invalid delivered_perf */
+	/*
+	 * Avoid divide-by zero and unchanged feedback counters.
+	 * Leave it for callers to handle.
+	 */
 	if (!delta_reference || !delta_delivered)
-		return cpu_data->perf_ctrls.desired_perf;
+		return 0;
 
 	return (reference_perf * delta_delivered) / delta_reference;
 }
 
+static int cppc_get_perf_ctrs_sample(int cpu,
+				     struct cppc_perf_fb_ctrs *fb_ctrs_t0,
+				     struct cppc_perf_fb_ctrs *fb_ctrs_t1)
+{
+	int ret;
+
+	ret = cppc_get_perf_ctrs(cpu, fb_ctrs_t0);
+	if (ret)
+		return ret;
+
+	udelay(2); /* 2usec delay between sampling */
+
+	return cppc_get_perf_ctrs(cpu, fb_ctrs_t1);
+}
+
 static unsigned int cppc_cpufreq_get_rate(unsigned int cpu)
 {
 	struct cppc_perf_fb_ctrs fb_ctrs_t0 = {0}, fb_ctrs_t1 = {0};
 	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-	struct cppc_cpudata *cpu_data = policy->driver_data;
+	struct cppc_cpudata *cpu_data;
 	u64 delivered_perf;
 	int ret;
 
-	cpufreq_cpu_put(policy);
+	if (!policy)
+		return -ENODEV;
 
-	ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t0);
-	if (ret)
-		return 0;
+	cpu_data = policy->driver_data;
 
-	udelay(2); /* 2usec delay between sampling */
+	cpufreq_cpu_put(policy);
 
-	ret = cppc_get_perf_ctrs(cpu, &fb_ctrs_t1);
-	if (ret)
-		return 0;
+	ret = cppc_get_perf_ctrs_sample(cpu, &fb_ctrs_t0, &fb_ctrs_t1);
+	if (ret) {
+		if (ret == -EFAULT)
+			/* Any of the associated CPPC regs is 0. */
+			goto out_invalid_counters;
+		else
+			return 0;
+	}
 
 	delivered_perf = cppc_perf_from_fbctrs(cpu_data, &fb_ctrs_t0,
 					       &fb_ctrs_t1);
+	if (!delivered_perf)
+		goto out_invalid_counters;
+
+	return cppc_perf_to_khz(&cpu_data->perf_caps, delivered_perf);
+
+out_invalid_counters:
+	/*
+	 * Feedback counters could be unchanged or 0 when a cpu enters a
+	 * low-power idle state, e.g. clock-gated or power-gated.
+	 * Use desired perf for reflecting frequency.  Get the latest register
+	 * value first as some platforms may update the actual delivered perf
+	 * there; if failed, resort to the cached desired perf.
+	 */
+	if (cppc_get_desired_perf(cpu, &delivered_perf))
+		delivered_perf = cpu_data->perf_ctrls.desired_perf;
 
 	return cppc_perf_to_khz(&cpu_data->perf_caps, delivered_perf);
 }
@@ -822,10 +868,15 @@
 static unsigned int hisi_cppc_cpufreq_get_rate(unsigned int cpu)
 {
 	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-	struct cppc_cpudata *cpu_data = policy->driver_data;
+	struct cppc_cpudata *cpu_data;
 	u64 desired_perf;
 	int ret;
 
+	if (!policy)
+		return -ENODEV;
+
+	cpu_data = policy->driver_data;
+
 	cpufreq_cpu_put(policy);
 
 	ret = cppc_get_desired_perf(cpu, &desired_perf);
--- linux-qcom-6.8.0.orig/drivers/cpufreq/cpufreq-dt.c
+++ linux-qcom-6.8.0/drivers/cpufreq/cpufreq-dt.c
@@ -208,7 +208,7 @@
 	if (!priv)
 		return -ENOMEM;
 
-	if (!alloc_cpumask_var(&priv->cpus, GFP_KERNEL))
+	if (!zalloc_cpumask_var(&priv->cpus, GFP_KERNEL))
 		return -ENOMEM;
 
 	cpumask_set_cpu(cpu, priv->cpus);
--- linux-qcom-6.8.0.orig/drivers/cpufreq/cpufreq.c
+++ linux-qcom-6.8.0/drivers/cpufreq/cpufreq.c
@@ -644,14 +644,16 @@
 	if (policy->boost_enabled == enable)
 		return count;
 
+	policy->boost_enabled = enable;
+
 	cpus_read_lock();
 	ret = cpufreq_driver->set_boost(policy, enable);
 	cpus_read_unlock();
 
-	if (ret)
+	if (ret) {
+		policy->boost_enabled = !policy->boost_enabled;
 		return ret;
-
-	policy->boost_enabled = enable;
+	}
 
 	return count;
 }
@@ -1419,6 +1421,10 @@
 			goto out_free_policy;
 		}
 
+		/* Let the per-policy boost flag mirror the cpufreq_driver boost during init */
+		if (cpufreq_boost_enabled() && policy_has_boost_freq(policy))
+			policy->boost_enabled = true;
+
 		/*
 		 * The initialization has succeeded and the policy is online.
 		 * If there is a problem with its frequency table, take it
@@ -1571,7 +1577,8 @@
 	if (cpufreq_driver->ready)
 		cpufreq_driver->ready(policy);
 
-	if (cpufreq_thermal_control_enabled(cpufreq_driver))
+	/* Register cpufreq cooling only for a new policy */
+	if (new_policy && cpufreq_thermal_control_enabled(cpufreq_driver))
 		policy->cdev = of_cpufreq_cooling_register(policy);
 
 	pr_debug("initialization complete\n");
@@ -1655,11 +1662,6 @@
 	else
 		policy->last_policy = policy->policy;
 
-	if (cpufreq_thermal_control_enabled(cpufreq_driver)) {
-		cpufreq_cooling_unregister(policy->cdev);
-		policy->cdev = NULL;
-	}
-
 	if (has_target())
 		cpufreq_exit_governor(policy);
 
@@ -1669,10 +1671,13 @@
 	 */
 	if (cpufreq_driver->offline) {
 		cpufreq_driver->offline(policy);
-	} else if (cpufreq_driver->exit) {
-		cpufreq_driver->exit(policy);
-		policy->freq_table = NULL;
+		return;
 	}
+
+	if (cpufreq_driver->exit)
+		cpufreq_driver->exit(policy);
+
+	policy->freq_table = NULL;
 }
 
 static int cpufreq_offline(unsigned int cpu)
@@ -1720,8 +1725,17 @@
 		return;
 	}
 
+	/*
+	 * Unregister cpufreq cooling once all the CPUs of the policy are
+	 * removed.
+	 */
+	if (cpufreq_thermal_control_enabled(cpufreq_driver)) {
+		cpufreq_cooling_unregister(policy->cdev);
+		policy->cdev = NULL;
+	}
+
 	/* We did light-weight exit earlier, do full tear down now */
-	if (cpufreq_driver->offline)
+	if (cpufreq_driver->offline && cpufreq_driver->exit)
 		cpufreq_driver->exit(policy);
 
 	up_write(&policy->rwsem);
@@ -2755,11 +2769,12 @@
 
 	cpus_read_lock();
 	for_each_active_policy(policy) {
+		policy->boost_enabled = state;
 		ret = cpufreq_driver->set_boost(policy, state);
-		if (ret)
+		if (ret) {
+			policy->boost_enabled = !policy->boost_enabled;
 			goto err_reset_state;
-
-		policy->boost_enabled = state;
+		}
 	}
 	cpus_read_unlock();
 
@@ -2841,6 +2856,20 @@
 	return 0;
 }
 
+static char cpufreq_driver_name[CPUFREQ_NAME_LEN];
+
+static int __init cpufreq_driver_setup(char *str)
+{
+	strscpy(cpufreq_driver_name, str, CPUFREQ_NAME_LEN);
+	return 1;
+}
+
+/*
+ * Set this name to only allow one specific cpu freq driver, e.g.,
+ * cpufreq_driver=powernow-k8
+ */
+__setup("cpufreq_driver=", cpufreq_driver_setup);
+
 /**
  * cpufreq_register_driver - register a CPU Frequency driver
  * @driver_data: A struct cpufreq_driver containing the values#
@@ -2876,7 +2905,13 @@
 		 (driver_data->adjust_perf && !driver_data->fast_switch))
 		return -EINVAL;
 
-	pr_debug("trying to register driver %s\n", driver_data->name);
+	pr_debug("trying to register driver %s, cpufreq_driver=%s\n",
+		driver_data->name, cpufreq_driver_name);
+
+	if (cpufreq_driver_name[0])
+		if (!driver_data->name ||
+			strcmp(cpufreq_driver_name, driver_data->name))
+				return -EINVAL;
 
 	/* Protect against concurrent CPU online/offline. */
 	cpus_read_lock();
--- linux-qcom-6.8.0.orig/drivers/cpufreq/freq_table.c
+++ linux-qcom-6.8.0/drivers/cpufreq/freq_table.c
@@ -40,7 +40,7 @@
 	cpufreq_for_each_valid_entry(pos, table) {
 		freq = pos->frequency;
 
-		if (!cpufreq_boost_enabled()
+		if ((!cpufreq_boost_enabled() || !policy->boost_enabled)
 		    && (pos->flags & CPUFREQ_BOOST_FREQ))
 			continue;
 
--- linux-qcom-6.8.0.orig/drivers/cpufreq/intel_pstate.c
+++ linux-qcom-6.8.0/drivers/cpufreq/intel_pstate.c
@@ -25,6 +25,7 @@
 #include <linux/acpi.h>
 #include <linux/vmalloc.h>
 #include <linux/pm_qos.h>
+#include <linux/bitfield.h>
 #include <trace/events/power.h>
 
 #include <asm/cpu.h>
@@ -359,15 +360,14 @@
 	int ret;
 
 	ret = cppc_get_perf_caps(cpu, &cppc_perf);
-	if (ret)
-		return;
-
 	/*
-	 * On some systems with overclocking enabled, CPPC.highest_perf is hardcoded to 0xff.
-	 * In this case we can't use CPPC.highest_perf to enable ITMT.
-	 * In this case we can look at MSR_HWP_CAPABILITIES bits [8:0] to decide.
+	 * If CPPC is not available, fall back to MSR_HWP_CAPABILITIES bits [8:0].
+	 *
+	 * Also, on some systems with overclocking enabled, CPPC.highest_perf is
+	 * hardcoded to 0xff, so CPPC.highest_perf cannot be used to enable ITMT.
+	 * Fall back to MSR_HWP_CAPABILITIES then too.
 	 */
-	if (cppc_perf.highest_perf == CPPC_MAX_PERF)
+	if (ret || cppc_perf.highest_perf == CPPC_MAX_PERF)
 		cppc_perf.highest_perf = HWP_HIGHEST_PERF(READ_ONCE(all_cpu_data[cpu]->hwp_cap_cached));
 
 	/*
@@ -1632,24 +1632,31 @@
 	wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_STATUS, 0);
 }
 
-static DEFINE_SPINLOCK(hwp_notify_lock);
+static DEFINE_RAW_SPINLOCK(hwp_notify_lock);
 static cpumask_t hwp_intr_enable_mask;
 
+#define HWP_GUARANTEED_PERF_CHANGE_STATUS      BIT(0)
+#define HWP_HIGHEST_PERF_CHANGE_STATUS         BIT(3)
+
 void notify_hwp_interrupt(void)
 {
 	unsigned int this_cpu = smp_processor_id();
 	struct cpudata *cpudata;
+	u64 value, status_mask;
 	unsigned long flags;
-	u64 value;
 
 	if (!READ_ONCE(hwp_active) || !boot_cpu_has(X86_FEATURE_HWP_NOTIFY))
 		return;
 
+	status_mask = HWP_GUARANTEED_PERF_CHANGE_STATUS;
+	if (cpu_feature_enabled(X86_FEATURE_HWP_HIGHEST_PERF_CHANGE))
+		status_mask |= HWP_HIGHEST_PERF_CHANGE_STATUS;
+
 	rdmsrl_safe(MSR_HWP_STATUS, &value);
-	if (!(value & 0x01))
+	if (!(value & status_mask))
 		return;
 
-	spin_lock_irqsave(&hwp_notify_lock, flags);
+	raw_spin_lock_irqsave(&hwp_notify_lock, flags);
 
 	if (!cpumask_test_cpu(this_cpu, &hwp_intr_enable_mask))
 		goto ack_intr;
@@ -1673,13 +1680,13 @@
 
 	schedule_delayed_work(&cpudata->hwp_notify_work, msecs_to_jiffies(10));
 
-	spin_unlock_irqrestore(&hwp_notify_lock, flags);
+	raw_spin_unlock_irqrestore(&hwp_notify_lock, flags);
 
 	return;
 
 ack_intr:
 	wrmsrl_safe(MSR_HWP_STATUS, 0);
-	spin_unlock_irqrestore(&hwp_notify_lock, flags);
+	raw_spin_unlock_irqrestore(&hwp_notify_lock, flags);
 }
 
 static void intel_pstate_disable_hwp_interrupt(struct cpudata *cpudata)
@@ -1692,25 +1699,33 @@
 	/* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */
 	wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x00);
 
-	spin_lock_irqsave(&hwp_notify_lock, flags);
+	raw_spin_lock_irqsave(&hwp_notify_lock, flags);
 	if (cpumask_test_and_clear_cpu(cpudata->cpu, &hwp_intr_enable_mask))
 		cancel_delayed_work(&cpudata->hwp_notify_work);
-	spin_unlock_irqrestore(&hwp_notify_lock, flags);
+	raw_spin_unlock_irqrestore(&hwp_notify_lock, flags);
 }
 
+#define HWP_GUARANTEED_PERF_CHANGE_REQ BIT(0)
+#define HWP_HIGHEST_PERF_CHANGE_REQ    BIT(2)
+
 static void intel_pstate_enable_hwp_interrupt(struct cpudata *cpudata)
 {
-	/* Enable HWP notification interrupt for guaranteed performance change */
+	/* Enable HWP notification interrupt for performance change */
 	if (boot_cpu_has(X86_FEATURE_HWP_NOTIFY)) {
+		u64 interrupt_mask = HWP_GUARANTEED_PERF_CHANGE_REQ;
+
 		unsigned long flags;
 
-		spin_lock_irqsave(&hwp_notify_lock, flags);
+		raw_spin_lock_irqsave(&hwp_notify_lock, flags);
 		INIT_DELAYED_WORK(&cpudata->hwp_notify_work, intel_pstate_notify_work);
 		cpumask_set_cpu(cpudata->cpu, &hwp_intr_enable_mask);
-		spin_unlock_irqrestore(&hwp_notify_lock, flags);
+		raw_spin_unlock_irqrestore(&hwp_notify_lock, flags);
+
+		if (cpu_feature_enabled(X86_FEATURE_HWP_HIGHEST_PERF_CHANGE))
+			interrupt_mask |= HWP_HIGHEST_PERF_CHANGE_REQ;
 
 		/* wrmsrl_on_cpu has to be outside spinlock as this can result in IPC */
-		wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x01);
+		wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, interrupt_mask);
 		wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_STATUS, 0);
 	}
 }
@@ -2404,52 +2419,56 @@
 	.get_val = core_get_val,
 };
 
-#define X86_MATCH(model, policy)					 \
-	X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, INTEL_FAM6_##model, \
-					   X86_FEATURE_APERFMPERF, &policy)
+#define X86_MATCH(vfm, policy)					 \
+	X86_MATCH_VFM_FEATURE(vfm, X86_FEATURE_APERFMPERF, &policy)
 
 static const struct x86_cpu_id intel_pstate_cpu_ids[] = {
-	X86_MATCH(SANDYBRIDGE,		core_funcs),
-	X86_MATCH(SANDYBRIDGE_X,	core_funcs),
-	X86_MATCH(ATOM_SILVERMONT,	silvermont_funcs),
-	X86_MATCH(IVYBRIDGE,		core_funcs),
-	X86_MATCH(HASWELL,		core_funcs),
-	X86_MATCH(BROADWELL,		core_funcs),
-	X86_MATCH(IVYBRIDGE_X,		core_funcs),
-	X86_MATCH(HASWELL_X,		core_funcs),
-	X86_MATCH(HASWELL_L,		core_funcs),
-	X86_MATCH(HASWELL_G,		core_funcs),
-	X86_MATCH(BROADWELL_G,		core_funcs),
-	X86_MATCH(ATOM_AIRMONT,		airmont_funcs),
-	X86_MATCH(SKYLAKE_L,		core_funcs),
-	X86_MATCH(BROADWELL_X,		core_funcs),
-	X86_MATCH(SKYLAKE,		core_funcs),
-	X86_MATCH(BROADWELL_D,		core_funcs),
-	X86_MATCH(XEON_PHI_KNL,		knl_funcs),
-	X86_MATCH(XEON_PHI_KNM,		knl_funcs),
-	X86_MATCH(ATOM_GOLDMONT,	core_funcs),
-	X86_MATCH(ATOM_GOLDMONT_PLUS,	core_funcs),
-	X86_MATCH(SKYLAKE_X,		core_funcs),
-	X86_MATCH(COMETLAKE,		core_funcs),
-	X86_MATCH(ICELAKE_X,		core_funcs),
-	X86_MATCH(TIGERLAKE,		core_funcs),
-	X86_MATCH(SAPPHIRERAPIDS_X,	core_funcs),
-	X86_MATCH(EMERALDRAPIDS_X,      core_funcs),
+	X86_MATCH(INTEL_SANDYBRIDGE,		core_funcs),
+	X86_MATCH(INTEL_SANDYBRIDGE_X,		core_funcs),
+	X86_MATCH(INTEL_ATOM_SILVERMONT,	silvermont_funcs),
+	X86_MATCH(INTEL_IVYBRIDGE,		core_funcs),
+	X86_MATCH(INTEL_HASWELL,		core_funcs),
+	X86_MATCH(INTEL_BROADWELL,		core_funcs),
+	X86_MATCH(INTEL_IVYBRIDGE_X,		core_funcs),
+	X86_MATCH(INTEL_HASWELL_X,		core_funcs),
+	X86_MATCH(INTEL_HASWELL_L,		core_funcs),
+	X86_MATCH(INTEL_HASWELL_G,		core_funcs),
+	X86_MATCH(INTEL_BROADWELL_G,		core_funcs),
+	X86_MATCH(INTEL_ATOM_AIRMONT,		airmont_funcs),
+	X86_MATCH(INTEL_SKYLAKE_L,		core_funcs),
+	X86_MATCH(INTEL_BROADWELL_X,		core_funcs),
+	X86_MATCH(INTEL_SKYLAKE,		core_funcs),
+	X86_MATCH(INTEL_BROADWELL_D,		core_funcs),
+	X86_MATCH(INTEL_XEON_PHI_KNL,		knl_funcs),
+	X86_MATCH(INTEL_XEON_PHI_KNM,		knl_funcs),
+	X86_MATCH(INTEL_ATOM_GOLDMONT,		core_funcs),
+	X86_MATCH(INTEL_ATOM_GOLDMONT_PLUS,	core_funcs),
+	X86_MATCH(INTEL_SKYLAKE_X,		core_funcs),
+	X86_MATCH(INTEL_COMETLAKE,		core_funcs),
+	X86_MATCH(INTEL_ICELAKE_X,		core_funcs),
+	X86_MATCH(INTEL_TIGERLAKE,		core_funcs),
+	X86_MATCH(INTEL_SAPPHIRERAPIDS_X,	core_funcs),
+	X86_MATCH(INTEL_EMERALDRAPIDS_X,	core_funcs),
 	{}
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_pstate_cpu_ids);
 
 static const struct x86_cpu_id intel_pstate_cpu_oob_ids[] __initconst = {
-	X86_MATCH(BROADWELL_D,		core_funcs),
-	X86_MATCH(BROADWELL_X,		core_funcs),
-	X86_MATCH(SKYLAKE_X,		core_funcs),
-	X86_MATCH(ICELAKE_X,		core_funcs),
-	X86_MATCH(SAPPHIRERAPIDS_X,	core_funcs),
+	X86_MATCH(INTEL_BROADWELL_D,		core_funcs),
+	X86_MATCH(INTEL_BROADWELL_X,		core_funcs),
+	X86_MATCH(INTEL_SKYLAKE_X,		core_funcs),
+	X86_MATCH(INTEL_ICELAKE_X,		core_funcs),
+	X86_MATCH(INTEL_SAPPHIRERAPIDS_X,	core_funcs),
+	X86_MATCH(INTEL_EMERALDRAPIDS_X,	core_funcs),
+	X86_MATCH(INTEL_GRANITERAPIDS_D,	core_funcs),
+	X86_MATCH(INTEL_GRANITERAPIDS_X,	core_funcs),
+	X86_MATCH(INTEL_ATOM_CRESTMONT,		core_funcs),
+	X86_MATCH(INTEL_ATOM_CRESTMONT_X,	core_funcs),
 	{}
 };
 
 static const struct x86_cpu_id intel_pstate_cpu_ee_disable_ids[] = {
-	X86_MATCH(KABYLAKE,		core_funcs),
+	X86_MATCH(INTEL_KABYLAKE,		core_funcs),
 	{}
 };
 
@@ -3137,10 +3156,10 @@
 			if (intel_pstate_driver == &intel_pstate)
 				intel_pstate_clear_update_util_hook(cpu);
 
-			spin_lock(&hwp_notify_lock);
+			raw_spin_lock(&hwp_notify_lock);
 			kfree(all_cpu_data[cpu]);
 			WRITE_ONCE(all_cpu_data[cpu], NULL);
-			spin_unlock(&hwp_notify_lock);
+			raw_spin_unlock(&hwp_notify_lock);
 		}
 	}
 	cpus_read_unlock();
@@ -3388,14 +3407,13 @@
 
 #define INTEL_PSTATE_HWP_BROADWELL	0x01
 
-#define X86_MATCH_HWP(model, hwp_mode)					\
-	X86_MATCH_VENDOR_FAM_MODEL_FEATURE(INTEL, 6, INTEL_FAM6_##model, \
-					   X86_FEATURE_HWP, hwp_mode)
+#define X86_MATCH_HWP(vfm, hwp_mode)				\
+	X86_MATCH_VFM_FEATURE(vfm, X86_FEATURE_HWP, hwp_mode)
 
 static const struct x86_cpu_id hwp_support_ids[] __initconst = {
-	X86_MATCH_HWP(BROADWELL_X,	INTEL_PSTATE_HWP_BROADWELL),
-	X86_MATCH_HWP(BROADWELL_D,	INTEL_PSTATE_HWP_BROADWELL),
-	X86_MATCH_HWP(ANY,		0),
+	X86_MATCH_HWP(INTEL_BROADWELL_X,	INTEL_PSTATE_HWP_BROADWELL),
+	X86_MATCH_HWP(INTEL_BROADWELL_D,	INTEL_PSTATE_HWP_BROADWELL),
+	X86_MATCH_HWP(INTEL_ANY,		0),
 	{}
 };
 
@@ -3407,19 +3425,41 @@
 	return !!(value & 0x1);
 }
 
-static const struct x86_cpu_id intel_epp_balance_perf[] = {
+#define POWERSAVE_MASK			GENMASK(7, 0)
+#define BALANCE_POWER_MASK		GENMASK(15, 8)
+#define BALANCE_PERFORMANCE_MASK	GENMASK(23, 16)
+#define PERFORMANCE_MASK		GENMASK(31, 24)
+
+#define HWP_SET_EPP_VALUES(powersave, balance_power, balance_perf, performance) \
+	(FIELD_PREP_CONST(POWERSAVE_MASK, powersave) |\
+	 FIELD_PREP_CONST(BALANCE_POWER_MASK, balance_power) |\
+	 FIELD_PREP_CONST(BALANCE_PERFORMANCE_MASK, balance_perf) |\
+	 FIELD_PREP_CONST(PERFORMANCE_MASK, performance))
+
+#define HWP_SET_DEF_BALANCE_PERF_EPP(balance_perf) \
+	(HWP_SET_EPP_VALUES(HWP_EPP_POWERSAVE, HWP_EPP_BALANCE_POWERSAVE,\
+	 balance_perf, HWP_EPP_PERFORMANCE))
+
+static const struct x86_cpu_id intel_epp_default[] = {
 	/*
 	 * Set EPP value as 102, this is the max suggested EPP
 	 * which can result in one core turbo frequency for
 	 * AlderLake Mobile CPUs.
 	 */
-	X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, 102),
-	X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, 32),
+	X86_MATCH_VFM(INTEL_ALDERLAKE_L, HWP_SET_DEF_BALANCE_PERF_EPP(102)),
+	X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, HWP_SET_DEF_BALANCE_PERF_EPP(32)),
+	X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, HWP_SET_DEF_BALANCE_PERF_EPP(32)),
+	X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, HWP_SET_DEF_BALANCE_PERF_EPP(32)),
+	X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, HWP_SET_DEF_BALANCE_PERF_EPP(32)),
+	X86_MATCH_VFM(INTEL_METEORLAKE_L, HWP_SET_EPP_VALUES(HWP_EPP_POWERSAVE,
+		      179, 64, 16)),
+	X86_MATCH_VFM(INTEL_ARROWLAKE, HWP_SET_EPP_VALUES(HWP_EPP_POWERSAVE,
+		      179, 64, 16)),
 	{}
 };
 
 static const struct x86_cpu_id intel_hybrid_scaling_factor[] = {
-	X86_MATCH_INTEL_FAM6_MODEL(METEORLAKE_L, HYBRID_SCALING_FACTOR_MTL),
+	X86_MATCH_VFM(INTEL_METEORLAKE_L, HYBRID_SCALING_FACTOR_MTL),
 	{}
 };
 
@@ -3512,11 +3552,24 @@
 	intel_pstate_sysfs_expose_params();
 
 	if (hwp_active) {
-		const struct x86_cpu_id *id = x86_match_cpu(intel_epp_balance_perf);
+		const struct x86_cpu_id *id = x86_match_cpu(intel_epp_default);
 		const struct x86_cpu_id *hybrid_id = x86_match_cpu(intel_hybrid_scaling_factor);
 
-		if (id)
-			epp_values[EPP_INDEX_BALANCE_PERFORMANCE] = id->driver_data;
+		if (id) {
+			epp_values[EPP_INDEX_POWERSAVE] =
+					FIELD_GET(POWERSAVE_MASK, id->driver_data);
+			epp_values[EPP_INDEX_BALANCE_POWERSAVE] =
+					FIELD_GET(BALANCE_POWER_MASK, id->driver_data);
+			epp_values[EPP_INDEX_BALANCE_PERFORMANCE] =
+					FIELD_GET(BALANCE_PERFORMANCE_MASK, id->driver_data);
+			epp_values[EPP_INDEX_PERFORMANCE] =
+					FIELD_GET(PERFORMANCE_MASK, id->driver_data);
+			pr_debug("Updated EPPs powersave:%x balanced power:%x balanced perf:%x performance:%x\n",
+				 epp_values[EPP_INDEX_POWERSAVE],
+				 epp_values[EPP_INDEX_BALANCE_POWERSAVE],
+				 epp_values[EPP_INDEX_BALANCE_PERFORMANCE],
+				 epp_values[EPP_INDEX_PERFORMANCE]);
+		}
 
 		if (hybrid_id) {
 			hybrid_scaling_factor = hybrid_id->driver_data;
--- linux-qcom-6.8.0.orig/drivers/cpufreq/loongson2_cpufreq.c
+++ linux-qcom-6.8.0/drivers/cpufreq/loongson2_cpufreq.c
@@ -154,7 +154,9 @@
 
 	ret = cpufreq_register_driver(&loongson2_cpufreq_driver);
 
-	if (!ret && !nowait) {
+	if (ret) {
+		platform_driver_unregister(&platform_driver);
+	} else if (!nowait) {
 		saved_cpu_wait = cpu_wait;
 		cpu_wait = loongson2_cpu_wait;
 	}
--- linux-qcom-6.8.0.orig/drivers/cpufreq/mediatek-cpufreq-hw.c
+++ linux-qcom-6.8.0/drivers/cpufreq/mediatek-cpufreq-hw.c
@@ -13,6 +13,7 @@
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 
 #define LUT_MAX_ENTRIES			32U
@@ -61,7 +62,7 @@
 
 	policy = cpufreq_cpu_get_raw(cpu_dev->id);
 	if (!policy)
-		return 0;
+		return -EINVAL;
 
 	data = policy->driver_data;
 
@@ -300,7 +301,23 @@
 static int mtk_cpufreq_hw_driver_probe(struct platform_device *pdev)
 {
 	const void *data;
-	int ret;
+	int ret, cpu;
+	struct device *cpu_dev;
+	struct regulator *cpu_reg;
+
+	/* Make sure that all CPU supplies are available before proceeding. */
+	for_each_possible_cpu(cpu) {
+		cpu_dev = get_cpu_device(cpu);
+		if (!cpu_dev)
+			return dev_err_probe(&pdev->dev, -EPROBE_DEFER,
+					     "Failed to get cpu%d device\n", cpu);
+
+		cpu_reg = devm_regulator_get(cpu_dev, "cpu");
+		if (IS_ERR(cpu_reg))
+			return dev_err_probe(&pdev->dev, PTR_ERR(cpu_reg),
+					     "CPU%d regulator get failed\n", cpu);
+	}
+
 
 	data = of_device_get_match_data(&pdev->dev);
 	if (!data)
--- linux-qcom-6.8.0.orig/drivers/cpufreq/qcom-cpufreq-hw.c
+++ linux-qcom-6.8.0/drivers/cpufreq/qcom-cpufreq-hw.c
@@ -142,14 +142,12 @@
 }
 
 /* Get the frequency requested by the cpufreq core for the CPU */
-static unsigned int qcom_cpufreq_get_freq(unsigned int cpu)
+static unsigned int qcom_cpufreq_get_freq(struct cpufreq_policy *policy)
 {
 	struct qcom_cpufreq_data *data;
 	const struct qcom_cpufreq_soc_data *soc_data;
-	struct cpufreq_policy *policy;
 	unsigned int index;
 
-	policy = cpufreq_cpu_get_raw(cpu);
 	if (!policy)
 		return 0;
 
@@ -162,12 +160,10 @@
 	return policy->freq_table[index].frequency;
 }
 
-static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
+static unsigned int __qcom_cpufreq_hw_get(struct cpufreq_policy *policy)
 {
 	struct qcom_cpufreq_data *data;
-	struct cpufreq_policy *policy;
 
-	policy = cpufreq_cpu_get_raw(cpu);
 	if (!policy)
 		return 0;
 
@@ -176,7 +172,12 @@
 	if (data->throttle_irq >= 0)
 		return qcom_lmh_get_throttle_freq(data) / HZ_PER_KHZ;
 
-	return qcom_cpufreq_get_freq(cpu);
+	return qcom_cpufreq_get_freq(policy);
+}
+
+static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
+{
+	return __qcom_cpufreq_hw_get(cpufreq_cpu_get_raw(cpu));
 }
 
 static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,
@@ -362,7 +363,7 @@
 	 * If h/w throttled frequency is higher than what cpufreq has requested
 	 * for, then stop polling and switch back to interrupt mechanism.
 	 */
-	if (throttled_freq >= qcom_cpufreq_get_freq(cpu))
+	if (throttled_freq >= qcom_cpufreq_get_freq(cpufreq_cpu_get_raw(cpu)))
 		enable_irq(data->throttle_irq);
 	else
 		mod_delayed_work(system_highpri_wq, &data->throttle_work,
@@ -440,7 +441,6 @@
 		return data->throttle_irq;
 
 	data->cancel_throttle = false;
-	data->policy = policy;
 
 	mutex_init(&data->throttle_lock);
 	INIT_DEFERRABLE_WORK(&data->throttle_work, qcom_lmh_dcvs_poll);
@@ -551,6 +551,7 @@
 
 	policy->driver_data = data;
 	policy->dvfs_possible_from_any_cpu = true;
+	data->policy = policy;
 
 	ret = qcom_cpufreq_hw_read_lut(cpu_dev, policy);
 	if (ret) {
@@ -623,11 +624,24 @@
 {
 	struct qcom_cpufreq_data *data = container_of(hw, struct qcom_cpufreq_data, cpu_clk);
 
-	return qcom_lmh_get_throttle_freq(data);
+	return __qcom_cpufreq_hw_get(data->policy) * HZ_PER_KHZ;
+}
+
+/*
+ * Since we cannot determine the closest rate of the target rate, let's just
+ * return the actual rate at which the clock is running at. This is needed to
+ * make clk_set_rate() API work properly.
+ */
+static int qcom_cpufreq_hw_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
+{
+	req->rate = qcom_cpufreq_hw_recalc_rate(hw, 0);
+
+	return 0;
 }
 
 static const struct clk_ops qcom_cpufreq_hw_clk_ops = {
 	.recalc_rate = qcom_cpufreq_hw_recalc_rate,
+	.determine_rate = qcom_cpufreq_hw_determine_rate,
 };
 
 static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev)
--- linux-qcom-6.8.0.orig/drivers/cpufreq/qcom-cpufreq-nvmem.c
+++ linux-qcom-6.8.0/drivers/cpufreq/qcom-cpufreq-nvmem.c
@@ -480,23 +480,30 @@
 
 	drv = devm_kzalloc(&pdev->dev, struct_size(drv, cpus, num_possible_cpus()),
 		           GFP_KERNEL);
-	if (!drv)
+	if (!drv) {
+		of_node_put(np);
 		return -ENOMEM;
+	}
 
 	match = pdev->dev.platform_data;
 	drv->data = match->data;
-	if (!drv->data)
+	if (!drv->data) {
+		of_node_put(np);
 		return -ENODEV;
+	}
 
 	if (drv->data->get_version) {
 		speedbin_nvmem = of_nvmem_cell_get(np, NULL);
-		if (IS_ERR(speedbin_nvmem))
+		if (IS_ERR(speedbin_nvmem)) {
+			of_node_put(np);
 			return dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem),
 					     "Could not get nvmem cell\n");
+		}
 
 		ret = drv->data->get_version(cpu_dev,
 							speedbin_nvmem, &pvs_name, drv);
 		if (ret) {
+			of_node_put(np);
 			nvmem_cell_put(speedbin_nvmem);
 			return ret;
 		}
--- linux-qcom-6.8.0.orig/drivers/cpufreq/s3c64xx-cpufreq.c
+++ linux-qcom-6.8.0/drivers/cpufreq/s3c64xx-cpufreq.c
@@ -24,6 +24,7 @@
 	unsigned int vddarm_max;
 };
 
+#ifdef CONFIG_REGULATOR
 static struct s3c64xx_dvfs s3c64xx_dvfs_table[] = {
 	[0] = { 1000000, 1150000 },
 	[1] = { 1050000, 1150000 },
@@ -31,6 +32,7 @@
 	[3] = { 1200000, 1350000 },
 	[4] = { 1300000, 1350000 },
 };
+#endif
 
 static struct cpufreq_frequency_table s3c64xx_freq_table[] = {
 	{ 0, 0,  66000 },
@@ -51,15 +53,16 @@
 static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
 				      unsigned int index)
 {
-	struct s3c64xx_dvfs *dvfs;
-	unsigned int old_freq, new_freq;
+	unsigned int new_freq = s3c64xx_freq_table[index].frequency;
 	int ret;
 
+#ifdef CONFIG_REGULATOR
+	struct s3c64xx_dvfs *dvfs;
+	unsigned int old_freq;
+
 	old_freq = clk_get_rate(policy->clk) / 1000;
-	new_freq = s3c64xx_freq_table[index].frequency;
 	dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data];
 
-#ifdef CONFIG_REGULATOR
 	if (vddarm && new_freq > old_freq) {
 		ret = regulator_set_voltage(vddarm,
 					    dvfs->vddarm_min,
--- linux-qcom-6.8.0.orig/drivers/cpufreq/scmi-cpufreq.c
+++ linux-qcom-6.8.0/drivers/cpufreq/scmi-cpufreq.c
@@ -62,9 +62,9 @@
 					     unsigned int target_freq)
 {
 	struct scmi_data *priv = policy->driver_data;
+	unsigned long freq = target_freq;
 
-	if (!perf_ops->freq_set(ph, priv->domain_id,
-				target_freq * 1000, true))
+	if (!perf_ops->freq_set(ph, priv->domain_id, freq * 1000, true))
 		return target_freq;
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/cpufreq/ti-cpufreq.c
+++ linux-qcom-6.8.0/drivers/cpufreq/ti-cpufreq.c
@@ -61,6 +61,9 @@
 	unsigned long efuse_shift;
 	unsigned long rev_offset;
 	bool multi_regulator;
+/* Backward compatibility hack: Might have missing syscon */
+#define TI_QUIRK_SYSCON_MAY_BE_MISSING	0x1
+	u8 quirks;
 };
 
 struct ti_cpufreq_data {
@@ -182,6 +185,7 @@
 	.efuse_mask = BIT(3),
 	.rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE,
 	.multi_regulator = false,
+	.quirks = TI_QUIRK_SYSCON_MAY_BE_MISSING,
 };
 
 /*
@@ -209,6 +213,7 @@
 	.efuse_mask = BIT(9),
 	.rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE,
 	.multi_regulator = true,
+	.quirks = TI_QUIRK_SYSCON_MAY_BE_MISSING,
 };
 
 /*
@@ -223,6 +228,7 @@
 	.efuse_mask = 0,
 	.rev_offset = OMAP3_CONTROL_IDCODE - OMAP3_SYSCON_BASE,
 	.multi_regulator = false,
+	.quirks = TI_QUIRK_SYSCON_MAY_BE_MISSING,
 };
 
 static struct ti_cpufreq_soc_data am625_soc_data = {
@@ -250,7 +256,7 @@
 
 	ret = regmap_read(opp_data->syscon, opp_data->soc_data->efuse_offset,
 			  &efuse);
-	if (ret == -EIO) {
+	if (opp_data->soc_data->quirks & TI_QUIRK_SYSCON_MAY_BE_MISSING && ret == -EIO) {
 		/* not a syscon register! */
 		void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
 				opp_data->soc_data->efuse_offset, 4);
@@ -291,7 +297,7 @@
 
 	ret = regmap_read(opp_data->syscon, opp_data->soc_data->rev_offset,
 			  &revision);
-	if (ret == -EIO) {
+	if (opp_data->soc_data->quirks & TI_QUIRK_SYSCON_MAY_BE_MISSING && ret == -EIO) {
 		/* not a syscon register! */
 		void __iomem *regs = ioremap(OMAP3_SYSCON_BASE +
 				opp_data->soc_data->rev_offset, 4);
@@ -419,7 +425,7 @@
 
 	ret = dev_pm_opp_set_config(opp_data->cpu_dev, &config);
 	if (ret < 0) {
-		dev_err(opp_data->cpu_dev, "Failed to set OPP config\n");
+		dev_err_probe(opp_data->cpu_dev, ret, "Failed to set OPP config\n");
 		goto fail_put_node;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/cpuidle/cpuidle-psci-domain.c
+++ linux-qcom-6.8.0/drivers/cpuidle/cpuidle-psci-domain.c
@@ -20,6 +20,7 @@
 #include <linux/string.h>
 
 #include "cpuidle-psci.h"
+#include "dt_idle_genpd.h"
 
 struct psci_pd_provider {
 	struct list_head link;
@@ -66,12 +67,16 @@
 
 	/*
 	 * Allow power off when OSI has been successfully enabled.
-	 * PREEMPT_RT is not yet ready to enter domain idle states.
+	 * On a PREEMPT_RT based configuration the domain idle states are
+	 * supported, but only during system-wide suspend.
 	 */
-	if (use_osi && !IS_ENABLED(CONFIG_PREEMPT_RT))
+	if (use_osi) {
 		pd->power_off = psci_pd_power_off;
-	else
+		if (IS_ENABLED(CONFIG_PREEMPT_RT))
+			pd->flags |= GENPD_FLAG_RPM_ALWAYS_ON;
+	} else {
 		pd->flags |= GENPD_FLAG_ALWAYS_ON;
+	}
 
 	/* Use governor for CPU PM domains if it has some states to manage. */
 	pd_gov = pd->states ? &pm_domain_cpu_gov : NULL;
--- linux-qcom-6.8.0.orig/drivers/cpuidle/cpuidle-psci.c
+++ linux-qcom-6.8.0/drivers/cpuidle/cpuidle-psci.c
@@ -28,6 +28,7 @@
 
 #include "cpuidle-psci.h"
 #include "dt_idle_states.h"
+#include "dt_idle_genpd.h"
 
 struct psci_cpuidle_data {
 	u32 *psci_states;
@@ -36,6 +37,7 @@
 
 static DEFINE_PER_CPU_READ_MOSTLY(struct psci_cpuidle_data, psci_cpuidle_data);
 static DEFINE_PER_CPU(u32, domain_state);
+static bool psci_cpuidle_use_syscore;
 static bool psci_cpuidle_use_cpuhp;
 
 void psci_set_domain_state(u32 state)
@@ -165,6 +167,12 @@
 	.resume = psci_idle_syscore_resume,
 };
 
+static void psci_idle_init_syscore(void)
+{
+	if (psci_cpuidle_use_syscore)
+		register_syscore_ops(&psci_idle_syscore_ops);
+}
+
 static void psci_idle_init_cpuhp(void)
 {
 	int err;
@@ -172,8 +180,6 @@
 	if (!psci_cpuidle_use_cpuhp)
 		return;
 
-	register_syscore_ops(&psci_idle_syscore_ops);
-
 	err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING,
 					"cpuidle/psci:online",
 					psci_idle_cpuhp_up,
@@ -221,22 +227,23 @@
 	if (!psci_has_osi_support())
 		return 0;
 
-	if (IS_ENABLED(CONFIG_PREEMPT_RT))
-		return 0;
-
-	data->dev = psci_dt_attach_cpu(cpu);
+	data->dev = dt_idle_attach_cpu(cpu, "psci");
 	if (IS_ERR_OR_NULL(data->dev))
 		return PTR_ERR_OR_ZERO(data->dev);
 
+	psci_cpuidle_use_syscore = true;
+
 	/*
 	 * Using the deepest state for the CPU to trigger a potential selection
 	 * of a shared state for the domain, assumes the domain states are all
-	 * deeper states.
+	 * deeper states. On PREEMPT_RT the hierarchical topology is limited to
+	 * s2ram and s2idle.
 	 */
-	drv->states[state_count - 1].flags |= CPUIDLE_FLAG_RCU_IDLE;
-	drv->states[state_count - 1].enter = psci_enter_domain_idle_state;
 	drv->states[state_count - 1].enter_s2idle = psci_enter_s2idle_domain_idle_state;
-	psci_cpuidle_use_cpuhp = true;
+	if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
+		drv->states[state_count - 1].enter = psci_enter_domain_idle_state;
+		psci_cpuidle_use_cpuhp = true;
+	}
 
 	return 0;
 }
@@ -311,7 +318,8 @@
 {
 	struct psci_cpuidle_data *data = per_cpu_ptr(&psci_cpuidle_data, cpu);
 
-	psci_dt_detach_cpu(data->dev);
+	dt_idle_detach_cpu(data->dev);
+	psci_cpuidle_use_syscore = false;
 	psci_cpuidle_use_cpuhp = false;
 }
 
@@ -408,6 +416,7 @@
 			goto out_fail;
 	}
 
+	psci_idle_init_syscore();
 	psci_idle_init_cpuhp();
 	return 0;
 
--- linux-qcom-6.8.0.orig/drivers/cpuidle/cpuidle-psci.h
+++ linux-qcom-6.8.0/drivers/cpuidle/cpuidle-psci.h
@@ -3,29 +3,9 @@
 #ifndef __CPUIDLE_PSCI_H
 #define __CPUIDLE_PSCI_H
 
-struct device;
 struct device_node;
 
 void psci_set_domain_state(u32 state);
 int psci_dt_parse_state_node(struct device_node *np, u32 *state);
 
-#ifdef CONFIG_ARM_PSCI_CPUIDLE_DOMAIN
-
-#include "dt_idle_genpd.h"
-
-static inline struct device *psci_dt_attach_cpu(int cpu)
-{
-	return dt_idle_attach_cpu(cpu, "psci");
-}
-
-static inline void psci_dt_detach_cpu(struct device *dev)
-{
-	dt_idle_detach_cpu(dev);
-}
-
-#else
-static inline struct device *psci_dt_attach_cpu(int cpu) { return NULL; }
-static inline void psci_dt_detach_cpu(struct device *dev) { }
-#endif
-
 #endif /* __CPUIDLE_PSCI_H */
--- linux-qcom-6.8.0.orig/drivers/cpuidle/cpuidle-riscv-sbi.c
+++ linux-qcom-6.8.0/drivers/cpuidle/cpuidle-riscv-sbi.c
@@ -8,6 +8,7 @@
 
 #define pr_fmt(fmt) "cpuidle-riscv-sbi: " fmt
 
+#include <linux/cleanup.h>
 #include <linux/cpuhotplug.h>
 #include <linux/cpuidle.h>
 #include <linux/cpumask.h>
@@ -267,19 +268,16 @@
 {
 	struct sbi_cpuidle_data *data = per_cpu_ptr(&sbi_cpuidle_data, cpu);
 	struct device_node *state_node;
-	struct device_node *cpu_node;
 	u32 *states;
 	int i, ret;
 
-	cpu_node = of_cpu_device_node_get(cpu);
+	struct device_node *cpu_node __free(device_node) = of_cpu_device_node_get(cpu);
 	if (!cpu_node)
 		return -ENODEV;
 
 	states = devm_kcalloc(dev, state_count, sizeof(*states), GFP_KERNEL);
-	if (!states) {
-		ret = -ENOMEM;
-		goto fail;
-	}
+	if (!states)
+		return -ENOMEM;
 
 	/* Parse SBI specific details from state DT nodes */
 	for (i = 1; i < state_count; i++) {
@@ -295,10 +293,8 @@
 
 		pr_debug("sbi-state %#x index %d\n", states[i], i);
 	}
-	if (i != state_count) {
-		ret = -ENODEV;
-		goto fail;
-	}
+	if (i != state_count)
+		return -ENODEV;
 
 	/* Initialize optional data, used for the hierarchical topology. */
 	ret = sbi_dt_cpu_init_topology(drv, data, state_count, cpu);
@@ -308,10 +304,7 @@
 	/* Store states in the per-cpu struct. */
 	data->states = states;
 
-fail:
-	of_node_put(cpu_node);
-
-	return ret;
+	return 0;
 }
 
 static void sbi_cpuidle_deinit_cpu(int cpu)
@@ -541,12 +534,12 @@
 	int cpu, ret;
 	struct cpuidle_driver *drv;
 	struct cpuidle_device *dev;
-	struct device_node *np, *pds_node;
+	struct device_node *pds_node;
 
 	/* Detect OSI support based on CPU DT nodes */
 	sbi_cpuidle_use_osi = true;
 	for_each_possible_cpu(cpu) {
-		np = of_cpu_device_node_get(cpu);
+		struct device_node *np __free(device_node) = of_cpu_device_node_get(cpu);
 		if (np &&
 		    of_property_present(np, "power-domains") &&
 		    of_property_present(np, "power-domain-names")) {
--- linux-qcom-6.8.0.orig/drivers/cpuidle/driver.c
+++ linux-qcom-6.8.0/drivers/cpuidle/driver.c
@@ -16,6 +16,7 @@
 #include <linux/cpumask.h>
 #include <linux/tick.h>
 #include <linux/cpu.h>
+#include <linux/math64.h>
 
 #include "cpuidle.h"
 
@@ -187,7 +188,7 @@
 			s->target_residency = div_u64(s->target_residency_ns, NSEC_PER_USEC);
 
 		if (s->exit_latency > 0)
-			s->exit_latency_ns = s->exit_latency * NSEC_PER_USEC;
+			s->exit_latency_ns = mul_u32_u32(s->exit_latency, NSEC_PER_USEC);
 		else if (s->exit_latency_ns < 0)
 			s->exit_latency_ns =  0;
 		else
--- linux-qcom-6.8.0.orig/drivers/crypto/bcm/cipher.c
+++ linux-qcom-6.8.0/drivers/crypto/bcm/cipher.c
@@ -2415,6 +2415,7 @@
 
 static int ahash_hmac_init(struct ahash_request *req)
 {
+	int ret;
 	struct iproc_reqctx_s *rctx = ahash_request_ctx(req);
 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
 	struct iproc_ctx_s *ctx = crypto_ahash_ctx(tfm);
@@ -2424,7 +2425,9 @@
 	flow_log("ahash_hmac_init()\n");
 
 	/* init the context as a hash */
-	ahash_init(req);
+	ret = ahash_init(req);
+	if (ret)
+		return ret;
 
 	if (!spu_no_incr_hash(ctx)) {
 		/* SPU-M can do incr hashing but needs sw for outer HMAC */
--- linux-qcom-6.8.0.orig/drivers/crypto/bcm/spu2.c
+++ linux-qcom-6.8.0/drivers/crypto/bcm/spu2.c
@@ -495,7 +495,7 @@
 	if (hash_iv_len) {
 		packet_log("  Hash IV Length %u bytes\n", hash_iv_len);
 		packet_dump("  hash IV: ", ptr, hash_iv_len);
-		ptr += ciph_key_len;
+		ptr += hash_iv_len;
 	}
 
 	if (ciph_iv_len) {
--- linux-qcom-6.8.0.orig/drivers/crypto/caam/blob_gen.c
+++ linux-qcom-6.8.0/drivers/crypto/caam/blob_gen.c
@@ -2,6 +2,7 @@
 /*
  * Copyright (C) 2015 Pengutronix, Steffen Trumtrar <kernel@pengutronix.de>
  * Copyright (C) 2021 Pengutronix, Ahmad Fatoum <kernel@pengutronix.de>
+ * Copyright 2024 NXP
  */
 
 #define pr_fmt(fmt) "caam blob_gen: " fmt
@@ -104,7 +105,7 @@
 	}
 
 	ctrlpriv = dev_get_drvdata(jrdev->parent);
-	moo = FIELD_GET(CSTA_MOO, rd_reg32(&ctrlpriv->ctrl->perfmon.status));
+	moo = FIELD_GET(CSTA_MOO, rd_reg32(&ctrlpriv->jr[0]->perfmon.status));
 	if (moo != CSTA_MOO_SECURE && moo != CSTA_MOO_TRUSTED)
 		dev_warn(jrdev,
 			 "using insecure test key, enable HAB to use unique device key!\n");
--- linux-qcom-6.8.0.orig/drivers/crypto/caam/caamhash.c
+++ linux-qcom-6.8.0/drivers/crypto/caam/caamhash.c
@@ -708,6 +708,7 @@
 		       GFP_KERNEL : GFP_ATOMIC;
 	struct ahash_edesc *edesc;
 
+	sg_num = pad_sg_nents(sg_num);
 	edesc = kzalloc(struct_size(edesc, sec4_sg, sg_num), flags);
 	if (!edesc)
 		return NULL;
--- linux-qcom-6.8.0.orig/drivers/crypto/caam/caampkc.c
+++ linux-qcom-6.8.0/drivers/crypto/caam/caampkc.c
@@ -984,7 +984,7 @@
 	return -ENOMEM;
 }
 
-static void caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx,
+static int caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx,
 				       struct rsa_key *raw_key)
 {
 	struct caam_rsa_key *rsa_key = &ctx->key;
@@ -994,7 +994,7 @@
 
 	rsa_key->p = caam_read_raw_data(raw_key->p, &p_sz);
 	if (!rsa_key->p)
-		return;
+		return -ENOMEM;
 	rsa_key->p_sz = p_sz;
 
 	rsa_key->q = caam_read_raw_data(raw_key->q, &q_sz);
@@ -1029,7 +1029,7 @@
 
 	rsa_key->priv_form = FORM3;
 
-	return;
+	return 0;
 
 free_dq:
 	kfree_sensitive(rsa_key->dq);
@@ -1043,6 +1043,7 @@
 	kfree_sensitive(rsa_key->q);
 free_p:
 	kfree_sensitive(rsa_key->p);
+	return -ENOMEM;
 }
 
 static int caam_rsa_set_priv_key(struct crypto_akcipher *tfm, const void *key,
@@ -1088,7 +1089,9 @@
 	rsa_key->e_sz = raw_key.e_sz;
 	rsa_key->n_sz = raw_key.n_sz;
 
-	caam_rsa_set_priv_key_form(ctx, &raw_key);
+	ret = caam_rsa_set_priv_key_form(ctx, &raw_key);
+	if (ret)
+		goto err;
 
 	return 0;
 
--- linux-qcom-6.8.0.orig/drivers/crypto/caam/qi.c
+++ linux-qcom-6.8.0/drivers/crypto/caam/qi.c
@@ -772,7 +772,7 @@
 
 	caam_debugfs_qi_init(ctrlpriv);
 
-	err = devm_add_action_or_reset(qidev, caam_qi_shutdown, ctrlpriv);
+	err = devm_add_action_or_reset(qidev, caam_qi_shutdown, qidev);
 	if (err)
 		return err;
 
--- linux-qcom-6.8.0.orig/drivers/crypto/cavium/cpt/cptpf_main.c
+++ linux-qcom-6.8.0/drivers/crypto/cavium/cpt/cptpf_main.c
@@ -44,7 +44,7 @@
 		dev_err(dev, "Cores still busy %llx", coremask);
 		grp = cpt_read_csr64(cpt->reg_base,
 				     CPTX_PF_EXEC_BUSY(0));
-		if (timeout--)
+		if (!timeout--)
 			break;
 
 		udelay(CSR_DELAY);
@@ -302,6 +302,8 @@
 
 	ret = do_cpt_init(cpt, mcode);
 	if (ret) {
+		dma_free_coherent(&cpt->pdev->dev, mcode->code_size,
+				  mcode->code, mcode->phys_base);
 		dev_err(dev, "do_cpt_init failed with ret: %d\n", ret);
 		goto fw_release;
 	}
@@ -394,7 +396,7 @@
 		dev_err(dev, "Cores still busy");
 		grp = cpt_read_csr64(cpt->reg_base,
 				     CPTX_PF_EXEC_BUSY(0));
-		if (timeout--)
+		if (!timeout--)
 			break;
 
 		udelay(CSR_DELAY);
--- linux-qcom-6.8.0.orig/drivers/crypto/ccp/platform-access.c
+++ linux-qcom-6.8.0/drivers/crypto/ccp/platform-access.c
@@ -118,9 +118,16 @@
 		goto unlock;
 	}
 
-	/* Store the status in request header for caller to investigate */
+	/*
+	 * Read status from PSP. If status is non-zero, it indicates an error
+	 * occurred during "processing" of the command.
+	 * If status is zero, it indicates the command was "processed"
+	 * successfully, but the result of the command is in the payload.
+	 * Return both cases to the caller as -EIO to investigate.
+	 */
 	cmd_reg = ioread32(cmd);
-	req->header.status = FIELD_GET(PSP_CMDRESP_STS, cmd_reg);
+	if (FIELD_GET(PSP_CMDRESP_STS, cmd_reg))
+		req->header.status = FIELD_GET(PSP_CMDRESP_STS, cmd_reg);
 	if (req->header.status) {
 		ret = -EIO;
 		goto unlock;
--- linux-qcom-6.8.0.orig/drivers/crypto/ccp/sev-dev.c
+++ linux-qcom-6.8.0/drivers/crypto/ccp/sev-dev.c
@@ -349,7 +349,18 @@
 
 	sev->int_rcvd = 0;
 
-	reg = FIELD_PREP(SEV_CMDRESP_CMD, cmd) | SEV_CMDRESP_IOC;
+	reg = FIELD_PREP(SEV_CMDRESP_CMD, cmd);
+
+	/*
+	 * If invoked during panic handling, local interrupts are disabled so
+	 * the PSP command completion interrupt can't be used.
+	 * sev_wait_cmd_ioc() already checks for interrupts disabled and
+	 * polls for PSP command completion.  Ensure we do not request an
+	 * interrupt from the PSP if irqs disabled.
+	 */
+	if (!irqs_disabled())
+		reg |= SEV_CMDRESP_IOC;
+
 	iowrite32(reg, sev->io_regs + sev->vdata->cmdresp_reg);
 
 	/* wait for command completion */
@@ -1381,6 +1392,8 @@
 	return;
 
 err:
+	sev_dev_destroy(psp_master);
+
 	psp_master->sev_data = NULL;
 }
 
--- linux-qcom-6.8.0.orig/drivers/crypto/ccp/sp-platform.c
+++ linux-qcom-6.8.0/drivers/crypto/ccp/sp-platform.c
@@ -39,44 +39,38 @@
 	},
 };
 
-#ifdef CONFIG_ACPI
 static const struct acpi_device_id sp_acpi_match[] = {
 	{ "AMDI0C00", (kernel_ulong_t)&dev_vdata[0] },
 	{ },
 };
 MODULE_DEVICE_TABLE(acpi, sp_acpi_match);
-#endif
 
-#ifdef CONFIG_OF
 static const struct of_device_id sp_of_match[] = {
 	{ .compatible = "amd,ccp-seattle-v1a",
 	  .data = (const void *)&dev_vdata[0] },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, sp_of_match);
-#endif
 
 static struct sp_dev_vdata *sp_get_of_version(struct platform_device *pdev)
 {
-#ifdef CONFIG_OF
 	const struct of_device_id *match;
 
 	match = of_match_node(sp_of_match, pdev->dev.of_node);
 	if (match && match->data)
 		return (struct sp_dev_vdata *)match->data;
-#endif
+
 	return NULL;
 }
 
 static struct sp_dev_vdata *sp_get_acpi_version(struct platform_device *pdev)
 {
-#ifdef CONFIG_ACPI
 	const struct acpi_device_id *match;
 
 	match = acpi_match_device(sp_acpi_match, &pdev->dev);
 	if (match && match->driver_data)
 		return (struct sp_dev_vdata *)match->driver_data;
-#endif
+
 	return NULL;
 }
 
@@ -212,12 +206,8 @@
 static struct platform_driver sp_platform_driver = {
 	.driver = {
 		.name = "ccp",
-#ifdef CONFIG_ACPI
 		.acpi_match_table = sp_acpi_match,
-#endif
-#ifdef CONFIG_OF
 		.of_match_table = sp_of_match,
-#endif
 	},
 	.probe = sp_platform_probe,
 	.remove_new = sp_platform_remove,
--- linux-qcom-6.8.0.orig/drivers/crypto/hisilicon/debugfs.c
+++ linux-qcom-6.8.0/drivers/crypto/hisilicon/debugfs.c
@@ -783,8 +783,14 @@
 {
 	int i;
 
+	if (!dregs)
+		return;
+
 	/* Setting the pointer is NULL to prevent double free */
 	for (i = 0; i < reg_len; i++) {
+		if (!dregs[i].regs)
+			continue;
+
 		kfree(dregs[i].regs);
 		dregs[i].regs = NULL;
 	}
@@ -834,14 +840,21 @@
 static int qm_diff_regs_init(struct hisi_qm *qm,
 		struct dfx_diff_registers *dregs, u32 reg_len)
 {
+	int ret;
+
 	qm->debug.qm_diff_regs = dfx_regs_init(qm, qm_diff_regs, ARRAY_SIZE(qm_diff_regs));
-	if (IS_ERR(qm->debug.qm_diff_regs))
-		return PTR_ERR(qm->debug.qm_diff_regs);
+	if (IS_ERR(qm->debug.qm_diff_regs)) {
+		ret = PTR_ERR(qm->debug.qm_diff_regs);
+		qm->debug.qm_diff_regs = NULL;
+		return ret;
+	}
 
 	qm->debug.acc_diff_regs = dfx_regs_init(qm, dregs, reg_len);
 	if (IS_ERR(qm->debug.acc_diff_regs)) {
 		dfx_regs_uninit(qm, qm->debug.qm_diff_regs, ARRAY_SIZE(qm_diff_regs));
-		return PTR_ERR(qm->debug.acc_diff_regs);
+		ret = PTR_ERR(qm->debug.acc_diff_regs);
+		qm->debug.acc_diff_regs = NULL;
+		return ret;
 	}
 
 	return 0;
@@ -882,7 +895,9 @@
 static void qm_diff_regs_uninit(struct hisi_qm *qm, u32 reg_len)
 {
 	dfx_regs_uninit(qm, qm->debug.acc_diff_regs, reg_len);
+	qm->debug.acc_diff_regs = NULL;
 	dfx_regs_uninit(qm, qm->debug.qm_diff_regs, ARRAY_SIZE(qm_diff_regs));
+	qm->debug.qm_diff_regs = NULL;
 }
 
 /**
--- linux-qcom-6.8.0.orig/drivers/crypto/hisilicon/hpre/hpre_main.c
+++ linux-qcom-6.8.0/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -13,9 +13,7 @@
 #include <linux/uacce.h>
 #include "hpre.h"
 
-#define HPRE_QM_ABNML_INT_MASK		0x100004
 #define HPRE_CTRL_CNT_CLR_CE_BIT	BIT(0)
-#define HPRE_COMM_CNT_CLR_CE		0x0
 #define HPRE_CTRL_CNT_CLR_CE		0x301000
 #define HPRE_FSM_MAX_CNT		0x301008
 #define HPRE_VFG_AXQOS			0x30100c
@@ -42,7 +40,6 @@
 #define HPRE_HAC_INT_SET		0x301500
 #define HPRE_RNG_TIMEOUT_NUM		0x301A34
 #define HPRE_CORE_INT_ENABLE		0
-#define HPRE_CORE_INT_DISABLE		GENMASK(21, 0)
 #define HPRE_RDCHN_INI_ST		0x301a00
 #define HPRE_CLSTR_BASE			0x302000
 #define HPRE_CORE_EN_OFFSET		0x04
@@ -66,7 +63,6 @@
 #define HPRE_CLSTR_ADDR_INTRVL		0x1000
 #define HPRE_CLUSTER_INQURY		0x100
 #define HPRE_CLSTR_ADDR_INQRY_RSLT	0x104
-#define HPRE_TIMEOUT_ABNML_BIT		6
 #define HPRE_PASID_EN_BIT		9
 #define HPRE_REG_RD_INTVRL_US		10
 #define HPRE_REG_RD_TMOUT_US		1000
@@ -203,9 +199,9 @@
 	{HPRE_QM_RESET_MASK_CAP, 0x3128, 0, GENMASK(31, 0), 0x0, 0xC37, 0x6C37},
 	{HPRE_QM_OOO_SHUTDOWN_MASK_CAP, 0x3128, 0, GENMASK(31, 0), 0x0, 0x4, 0x6C37},
 	{HPRE_QM_CE_MASK_CAP, 0x312C, 0, GENMASK(31, 0), 0x0, 0x8, 0x8},
-	{HPRE_NFE_MASK_CAP, 0x3130, 0, GENMASK(31, 0), 0x0, 0x3FFFFE, 0x1FFFFFE},
-	{HPRE_RESET_MASK_CAP, 0x3134, 0, GENMASK(31, 0), 0x0, 0x3FFFFE, 0xBFFFFE},
-	{HPRE_OOO_SHUTDOWN_MASK_CAP, 0x3134, 0, GENMASK(31, 0), 0x0, 0x22, 0xBFFFFE},
+	{HPRE_NFE_MASK_CAP, 0x3130, 0, GENMASK(31, 0), 0x0, 0x3FFFFE, 0x1FFFC3E},
+	{HPRE_RESET_MASK_CAP, 0x3134, 0, GENMASK(31, 0), 0x0, 0x3FFFFE, 0xBFFC3E},
+	{HPRE_OOO_SHUTDOWN_MASK_CAP, 0x3134, 0, GENMASK(31, 0), 0x0, 0x22, 0xBFFC3E},
 	{HPRE_CE_MASK_CAP, 0x3138, 0, GENMASK(31, 0), 0x0, 0x1, 0x1},
 	{HPRE_CLUSTER_NUM_CAP, 0x313c, 20, GENMASK(3, 0), 0x0,  0x4, 0x1},
 	{HPRE_CORE_TYPE_NUM_CAP, 0x313c, 16, GENMASK(3, 0), 0x0, 0x2, 0x2},
@@ -358,6 +354,8 @@
 	},
 };
 
+static const struct hisi_qm_err_ini hpre_err_ini;
+
 bool hpre_check_alg_support(struct hisi_qm *qm, u32 alg)
 {
 	u32 cap_val;
@@ -654,11 +652,6 @@
 	writel(HPRE_QM_USR_CFG_MASK, qm->io_base + QM_AWUSER_M_CFG_ENABLE);
 	writel_relaxed(HPRE_QM_AXI_CFG_MASK, qm->io_base + QM_AXI_M_CFG);
 
-	/* HPRE need more time, we close this interrupt */
-	val = readl_relaxed(qm->io_base + HPRE_QM_ABNML_INT_MASK);
-	val |= BIT(HPRE_TIMEOUT_ABNML_BIT);
-	writel_relaxed(val, qm->io_base + HPRE_QM_ABNML_INT_MASK);
-
 	if (qm->ver >= QM_HW_V3)
 		writel(HPRE_RSA_ENB | HPRE_ECC_ENB,
 			qm->io_base + HPRE_TYPES_ENB);
@@ -667,9 +660,7 @@
 
 	writel(HPRE_QM_VFG_AX_MASK, qm->io_base + HPRE_VFG_AXCACHE);
 	writel(0x0, qm->io_base + HPRE_BD_ENDIAN);
-	writel(0x0, qm->io_base + HPRE_INT_MASK);
 	writel(0x0, qm->io_base + HPRE_POISON_BYPASS);
-	writel(0x0, qm->io_base + HPRE_COMM_CNT_CLR_CE);
 	writel(0x0, qm->io_base + HPRE_ECC_BYPASS);
 
 	writel(HPRE_BD_USR_MASK, qm->io_base + HPRE_BD_ARUSR_CFG);
@@ -759,7 +750,7 @@
 
 static void hpre_hw_error_enable(struct hisi_qm *qm)
 {
-	u32 ce, nfe;
+	u32 ce, nfe, err_en;
 
 	ce = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_CE_MASK_CAP, qm->cap_ver);
 	nfe = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_NFE_MASK_CAP, qm->cap_ver);
@@ -776,7 +767,8 @@
 	hpre_master_ooo_ctrl(qm, true);
 
 	/* enable hpre hw error interrupts */
-	writel(HPRE_CORE_INT_ENABLE, qm->io_base + HPRE_INT_MASK);
+	err_en = ce | nfe | HPRE_HAC_RAS_FE_ENABLE;
+	writel(~err_en, qm->io_base + HPRE_INT_MASK);
 }
 
 static inline struct hisi_qm *hpre_file_to_qm(struct hpre_debugfs_file *file)
@@ -1162,6 +1154,7 @@
 		qm->qp_num = pf_q_num;
 		qm->debug.curr_qm_qp_num = pf_q_num;
 		qm->qm_list = &hpre_devices;
+		qm->err_ini = &hpre_err_ini;
 		if (pf_q_num_flag)
 			set_bit(QM_MODULE_PARAM, &qm->misc_ctl);
 	}
@@ -1288,11 +1281,15 @@
 
 static void hpre_clear_hw_err_status(struct hisi_qm *qm, u32 err_sts)
 {
-	u32 nfe;
-
 	writel(err_sts, qm->io_base + HPRE_HAC_SOURCE_INT);
-	nfe = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_NFE_MASK_CAP, qm->cap_ver);
-	writel(nfe, qm->io_base + HPRE_RAS_NFE_ENB);
+}
+
+static void hpre_disable_error_report(struct hisi_qm *qm, u32 err_type)
+{
+	u32 nfe_mask;
+
+	nfe_mask = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_NFE_MASK_CAP, qm->cap_ver);
+	writel(nfe_mask & (~err_type), qm->io_base + HPRE_RAS_NFE_ENB);
 }
 
 static void hpre_open_axi_master_ooo(struct hisi_qm *qm)
@@ -1306,6 +1303,27 @@
 	       qm->io_base + HPRE_AM_OOO_SHUTDOWN_ENB);
 }
 
+static enum acc_err_result hpre_get_err_result(struct hisi_qm *qm)
+{
+	u32 err_status;
+
+	err_status = hpre_get_hw_err_status(qm);
+	if (err_status) {
+		if (err_status & qm->err_info.ecc_2bits_mask)
+			qm->err_status.is_dev_ecc_mbit = true;
+		hpre_log_hw_error(qm, err_status);
+
+		if (err_status & qm->err_info.dev_reset_mask) {
+			/* Disable the same error reporting until device is recovered. */
+			hpre_disable_error_report(qm, err_status);
+			return ACC_ERR_NEED_RESET;
+		}
+		hpre_clear_hw_err_status(qm, err_status);
+	}
+
+	return ACC_ERR_RECOVERED;
+}
+
 static void hpre_err_info_init(struct hisi_qm *qm)
 {
 	struct hisi_qm_err_info *err_info = &qm->err_info;
@@ -1332,12 +1350,12 @@
 	.hw_err_disable		= hpre_hw_error_disable,
 	.get_dev_hw_err_status	= hpre_get_hw_err_status,
 	.clear_dev_hw_err_status = hpre_clear_hw_err_status,
-	.log_dev_hw_err		= hpre_log_hw_error,
 	.open_axi_master_ooo	= hpre_open_axi_master_ooo,
 	.open_sva_prefetch	= hpre_open_sva_prefetch,
 	.close_sva_prefetch	= hpre_close_sva_prefetch,
 	.show_last_dfx_regs	= hpre_show_last_dfx_regs,
 	.err_info_init		= hpre_err_info_init,
+	.get_err_result		= hpre_get_err_result,
 };
 
 static int hpre_pf_probe_init(struct hpre *hpre)
@@ -1351,8 +1369,6 @@
 
 	hpre_open_sva_prefetch(qm);
 
-	qm->err_ini = &hpre_err_ini;
-	qm->err_ini->err_info_init(qm);
 	hisi_qm_dev_err_init(qm);
 	ret = hpre_show_last_regs_init(qm);
 	if (ret)
@@ -1381,6 +1397,18 @@
 	return 0;
 }
 
+static void hpre_probe_uninit(struct hisi_qm *qm)
+{
+	if (qm->fun_type == QM_HW_VF)
+		return;
+
+	hpre_cnt_regs_clear(qm);
+	qm->debug.curr_qm_qp_num = 0;
+	hpre_show_last_regs_uninit(qm);
+	hpre_close_sva_prefetch(qm);
+	hisi_qm_dev_err_uninit(qm);
+}
+
 static int hpre_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	struct hisi_qm *qm;
@@ -1406,7 +1434,7 @@
 
 	ret = hisi_qm_start(qm);
 	if (ret)
-		goto err_with_err_init;
+		goto err_with_probe_init;
 
 	ret = hpre_debugfs_init(qm);
 	if (ret)
@@ -1445,9 +1473,8 @@
 	hpre_debugfs_exit(qm);
 	hisi_qm_stop(qm, QM_NORMAL);
 
-err_with_err_init:
-	hpre_show_last_regs_uninit(qm);
-	hisi_qm_dev_err_uninit(qm);
+err_with_probe_init:
+	hpre_probe_uninit(qm);
 
 err_with_qm_init:
 	hisi_qm_uninit(qm);
@@ -1469,13 +1496,7 @@
 	hpre_debugfs_exit(qm);
 	hisi_qm_stop(qm, QM_NORMAL);
 
-	if (qm->fun_type == QM_HW_PF) {
-		hpre_cnt_regs_clear(qm);
-		qm->debug.curr_qm_qp_num = 0;
-		hpre_show_last_regs_uninit(qm);
-		hisi_qm_dev_err_uninit(qm);
-	}
-
+	hpre_probe_uninit(qm);
 	hisi_qm_uninit(qm);
 }
 
--- linux-qcom-6.8.0.orig/drivers/crypto/hisilicon/qm.c
+++ linux-qcom-6.8.0/drivers/crypto/hisilicon/qm.c
@@ -265,12 +265,6 @@
 	SHAPER_VFT,
 };
 
-enum acc_err_result {
-	ACC_ERR_NONE,
-	ACC_ERR_NEED_RESET,
-	ACC_ERR_RECOVERED,
-};
-
 enum qm_alg_type {
 	ALG_TYPE_0,
 	ALG_TYPE_1,
@@ -443,6 +437,7 @@
 };
 
 static void qm_irqs_unregister(struct hisi_qm *qm);
+static int qm_reset_device(struct hisi_qm *qm);
 
 static u32 qm_get_hw_error_status(struct hisi_qm *qm)
 {
@@ -1414,22 +1409,25 @@
 
 static enum acc_err_result qm_hw_error_handle_v2(struct hisi_qm *qm)
 {
-	u32 error_status, tmp;
+	u32 error_status;
 
-	/* read err sts */
-	tmp = readl(qm->io_base + QM_ABNORMAL_INT_STATUS);
-	error_status = qm->error_mask & tmp;
-
-	if (error_status) {
+	error_status = qm_get_hw_error_status(qm);
+	if (error_status & qm->error_mask) {
 		if (error_status & QM_ECC_MBIT)
 			qm->err_status.is_qm_ecc_mbit = true;
 
 		qm_log_hw_error(qm, error_status);
-		if (error_status & qm->err_info.qm_reset_mask)
+		if (error_status & qm->err_info.qm_reset_mask) {
+			/* Disable the same error reporting until device is recovered. */
+			writel(qm->err_info.nfe & (~error_status),
+			       qm->io_base + QM_RAS_NFE_ENABLE);
 			return ACC_ERR_NEED_RESET;
+		}
 
+		/* Clear error source if not need reset. */
 		writel(error_status, qm->io_base + QM_ABNORMAL_INT_SOURCE);
 		writel(qm->err_info.nfe, qm->io_base + QM_RAS_NFE_ENABLE);
+		writel(qm->err_info.ce, qm->io_base + QM_RAS_CE_ENABLE);
 	}
 
 	return ACC_ERR_RECOVERED;
@@ -2833,12 +2831,9 @@
 	hisi_qm_set_state(qm, QM_NOT_READY);
 	up_write(&qm->qps_lock);
 
+	qm_remove_uacce(qm);
 	qm_irqs_unregister(qm);
 	hisi_qm_pci_uninit(qm);
-	if (qm->use_sva) {
-		uacce_remove(qm->uacce);
-		qm->uacce = NULL;
-	}
 }
 EXPORT_SYMBOL_GPL(hisi_qm_uninit);
 
@@ -3801,30 +3796,12 @@
 
 static enum acc_err_result qm_dev_err_handle(struct hisi_qm *qm)
 {
-	u32 err_sts;
-
-	if (!qm->err_ini->get_dev_hw_err_status) {
-		dev_err(&qm->pdev->dev, "Device doesn't support get hw error status!\n");
+	if (!qm->err_ini->get_err_result) {
+		dev_err(&qm->pdev->dev, "Device doesn't support reset!\n");
 		return ACC_ERR_NONE;
 	}
 
-	/* get device hardware error status */
-	err_sts = qm->err_ini->get_dev_hw_err_status(qm);
-	if (err_sts) {
-		if (err_sts & qm->err_info.ecc_2bits_mask)
-			qm->err_status.is_dev_ecc_mbit = true;
-
-		if (qm->err_ini->log_dev_hw_err)
-			qm->err_ini->log_dev_hw_err(qm, err_sts);
-
-		if (err_sts & qm->err_info.dev_reset_mask)
-			return ACC_ERR_NEED_RESET;
-
-		if (qm->err_ini->clear_dev_hw_err_status)
-			qm->err_ini->clear_dev_hw_err_status(qm, err_sts);
-	}
-
-	return ACC_ERR_RECOVERED;
+	return qm->err_ini->get_err_result(qm);
 }
 
 static enum acc_err_result qm_process_dev_error(struct hisi_qm *qm)
@@ -3955,6 +3932,28 @@
 	return -ETIMEDOUT;
 }
 
+static void qm_dev_ecc_mbit_handle(struct hisi_qm *qm)
+{
+	u32 nfe_enb = 0;
+
+	/* Kunpeng930 hardware automatically close master ooo when NFE occurs */
+	if (qm->ver >= QM_HW_V3)
+		return;
+
+	if (!qm->err_status.is_dev_ecc_mbit &&
+	    qm->err_status.is_qm_ecc_mbit &&
+	    qm->err_ini->close_axi_master_ooo) {
+		qm->err_ini->close_axi_master_ooo(qm);
+	} else if (qm->err_status.is_dev_ecc_mbit &&
+		   !qm->err_status.is_qm_ecc_mbit &&
+		   !qm->err_ini->close_axi_master_ooo) {
+		nfe_enb = readl(qm->io_base + QM_RAS_NFE_ENABLE);
+		writel(nfe_enb & QM_RAS_NFE_MBIT_DISABLE,
+		       qm->io_base + QM_RAS_NFE_ENABLE);
+		writel(QM_ECC_MBIT, qm->io_base + QM_ABNORMAL_INT_SET);
+	}
+}
+
 static int qm_vf_reset_prepare(struct hisi_qm *qm,
 			       enum qm_stop_reason stop_reason)
 {
@@ -4019,6 +4018,8 @@
 		return ret;
 	}
 
+	qm_dev_ecc_mbit_handle(qm);
+
 	/* PF obtains the information of VF by querying the register. */
 	qm_cmd_uninit(qm);
 
@@ -4049,33 +4050,26 @@
 	return 0;
 }
 
-static void qm_dev_ecc_mbit_handle(struct hisi_qm *qm)
+static int qm_master_ooo_check(struct hisi_qm *qm)
 {
-	u32 nfe_enb = 0;
+	u32 val;
+	int ret;
 
-	/* Kunpeng930 hardware automatically close master ooo when NFE occurs */
-	if (qm->ver >= QM_HW_V3)
-		return;
+	/* Check the ooo register of the device before resetting the device. */
+	writel(ACC_MASTER_GLOBAL_CTRL_SHUTDOWN, qm->io_base + ACC_MASTER_GLOBAL_CTRL);
+	ret = readl_relaxed_poll_timeout(qm->io_base + ACC_MASTER_TRANS_RETURN,
+					 val, (val == ACC_MASTER_TRANS_RETURN_RW),
+					 POLL_PERIOD, POLL_TIMEOUT);
+	if (ret)
+		pci_warn(qm->pdev, "Bus lock! Please reset system.\n");
 
-	if (!qm->err_status.is_dev_ecc_mbit &&
-	    qm->err_status.is_qm_ecc_mbit &&
-	    qm->err_ini->close_axi_master_ooo) {
-		qm->err_ini->close_axi_master_ooo(qm);
-	} else if (qm->err_status.is_dev_ecc_mbit &&
-		   !qm->err_status.is_qm_ecc_mbit &&
-		   !qm->err_ini->close_axi_master_ooo) {
-		nfe_enb = readl(qm->io_base + QM_RAS_NFE_ENABLE);
-		writel(nfe_enb & QM_RAS_NFE_MBIT_DISABLE,
-		       qm->io_base + QM_RAS_NFE_ENABLE);
-		writel(QM_ECC_MBIT, qm->io_base + QM_ABNORMAL_INT_SET);
-	}
+	return ret;
 }
 
-static int qm_soft_reset(struct hisi_qm *qm)
+static int qm_soft_reset_prepare(struct hisi_qm *qm)
 {
 	struct pci_dev *pdev = qm->pdev;
 	int ret;
-	u32 val;
 
 	/* Ensure all doorbells and mailboxes received by QM */
 	ret = qm_check_req_recv(qm);
@@ -4096,30 +4090,23 @@
 		return ret;
 	}
 
-	qm_dev_ecc_mbit_handle(qm);
-
-	/* OOO register set and check */
-	writel(ACC_MASTER_GLOBAL_CTRL_SHUTDOWN,
-	       qm->io_base + ACC_MASTER_GLOBAL_CTRL);
-
-	/* If bus lock, reset chip */
-	ret = readl_relaxed_poll_timeout(qm->io_base + ACC_MASTER_TRANS_RETURN,
-					 val,
-					 (val == ACC_MASTER_TRANS_RETURN_RW),
-					 POLL_PERIOD, POLL_TIMEOUT);
-	if (ret) {
-		pci_emerg(pdev, "Bus lock! Please reset system.\n");
+	ret = qm_master_ooo_check(qm);
+	if (ret)
 		return ret;
-	}
 
 	if (qm->err_ini->close_sva_prefetch)
 		qm->err_ini->close_sva_prefetch(qm);
 
 	ret = qm_set_pf_mse(qm, false);
-	if (ret) {
+	if (ret)
 		pci_err(pdev, "Fails to disable pf MSE bit.\n");
-		return ret;
-	}
+
+	return ret;
+}
+
+static int qm_reset_device(struct hisi_qm *qm)
+{
+	struct pci_dev *pdev = qm->pdev;
 
 	/* The reset related sub-control registers are not in PCI BAR */
 	if (ACPI_HANDLE(&pdev->dev)) {
@@ -4138,12 +4125,23 @@
 			pci_err(pdev, "Reset step %llu failed!\n", value);
 			return -EIO;
 		}
-	} else {
-		pci_err(pdev, "No reset method!\n");
-		return -EINVAL;
+
+		return 0;
 	}
 
-	return 0;
+	pci_err(pdev, "No reset method!\n");
+	return -EINVAL;
+}
+
+static int qm_soft_reset(struct hisi_qm *qm)
+{
+	int ret;
+
+	ret = qm_soft_reset_prepare(qm);
+	if (ret)
+		return ret;
+
+	return qm_reset_device(qm);
 }
 
 static int qm_vf_reset_done(struct hisi_qm *qm)
@@ -5096,6 +5094,35 @@
 	return ret;
 }
 
+static int qm_clear_device(struct hisi_qm *qm)
+{
+	acpi_handle handle = ACPI_HANDLE(&qm->pdev->dev);
+	int ret;
+
+	if (qm->fun_type == QM_HW_VF)
+		return 0;
+
+	/* Device does not support reset, return */
+	if (!qm->err_ini->err_info_init)
+		return 0;
+	qm->err_ini->err_info_init(qm);
+
+	if (!handle)
+		return 0;
+
+	/* No reset method, return */
+	if (!acpi_has_method(handle, qm->err_info.acpi_rst))
+		return 0;
+
+	ret = qm_master_ooo_check(qm);
+	if (ret) {
+		writel(0x0, qm->io_base + ACC_MASTER_GLOBAL_CTRL);
+		return ret;
+	}
+
+	return qm_reset_device(qm);
+}
+
 static int hisi_qm_pci_init(struct hisi_qm *qm)
 {
 	struct pci_dev *pdev = qm->pdev;
@@ -5125,8 +5152,14 @@
 		goto err_get_pci_res;
 	}
 
+	ret = qm_clear_device(qm);
+	if (ret)
+		goto err_free_vectors;
+
 	return 0;
 
+err_free_vectors:
+	pci_free_irq_vectors(pdev);
 err_get_pci_res:
 	qm_put_pci_res(qm);
 err_disable_pcidev:
@@ -5427,7 +5460,6 @@
 {
 	struct pci_dev *pdev = qm->pdev;
 	int ret;
-	u32 val;
 
 	ret = qm->ops->set_msi(qm, false);
 	if (ret) {
@@ -5435,18 +5467,9 @@
 		return ret;
 	}
 
-	/* shutdown OOO register */
-	writel(ACC_MASTER_GLOBAL_CTRL_SHUTDOWN,
-	       qm->io_base + ACC_MASTER_GLOBAL_CTRL);
-
-	ret = readl_relaxed_poll_timeout(qm->io_base + ACC_MASTER_TRANS_RETURN,
-					 val,
-					 (val == ACC_MASTER_TRANS_RETURN_RW),
-					 POLL_PERIOD, POLL_TIMEOUT);
-	if (ret) {
-		pci_emerg(pdev, "Bus lock! Please reset system.\n");
+	ret = qm_master_ooo_check(qm);
+	if (ret)
 		return ret;
-	}
 
 	ret = qm_set_pf_mse(qm, false);
 	if (ret)
--- linux-qcom-6.8.0.orig/drivers/crypto/hisilicon/sec2/sec.h
+++ linux-qcom-6.8.0/drivers/crypto/hisilicon/sec2/sec.h
@@ -37,6 +37,7 @@
 	u8 *a_ivin;
 	dma_addr_t a_ivin_dma;
 	struct aead_request *aead_req;
+	bool fallback;
 };
 
 /* SEC request of Crypto */
@@ -90,9 +91,7 @@
 	dma_addr_t a_key_dma;
 	u8 *a_key;
 	u8 a_key_len;
-	u8 mac_len;
 	u8 a_alg;
-	bool fallback;
 	struct crypto_shash *hash_tfm;
 	struct crypto_aead *fallback_aead_tfm;
 };
--- linux-qcom-6.8.0.orig/drivers/crypto/hisilicon/sec2/sec_crypto.c
+++ linux-qcom-6.8.0/drivers/crypto/hisilicon/sec2/sec_crypto.c
@@ -481,8 +481,10 @@
 
 	if (ctx->pbuf_supported)
 		sec_free_pbuf_resource(dev, qp_ctx->res);
-	if (ctx->alg_type == SEC_AEAD)
+	if (ctx->alg_type == SEC_AEAD) {
 		sec_free_mac_resource(dev, qp_ctx->res);
+		sec_free_aiv_resource(dev, qp_ctx->res);
+	}
 }
 
 static int sec_alloc_qp_ctx_resource(struct hisi_qm *qm, struct sec_ctx *ctx,
@@ -950,15 +952,14 @@
 	struct aead_request *aead_req = req->aead_req;
 	struct crypto_aead *tfm = crypto_aead_reqtfm(aead_req);
 	size_t authsize = crypto_aead_authsize(tfm);
-	u8 *mac_out = req->out_mac;
 	struct scatterlist *sgl = aead_req->src;
+	u8 *mac_out = req->out_mac;
 	size_t copy_size;
 	off_t skip_size;
 
 	/* Copy input mac */
 	skip_size = aead_req->assoclen + aead_req->cryptlen - authsize;
-	copy_size = sg_pcopy_to_buffer(sgl, sg_nents(sgl), mac_out,
-				       authsize, skip_size);
+	copy_size = sg_pcopy_to_buffer(sgl, sg_nents(sgl), mac_out, authsize, skip_size);
 	if (unlikely(copy_size != authsize))
 		return -EINVAL;
 
@@ -1122,10 +1123,7 @@
 	struct sec_ctx *ctx = crypto_tfm_ctx(tfm);
 	struct sec_auth_ctx *a_ctx = &ctx->a_ctx;
 
-	if (unlikely(a_ctx->fallback_aead_tfm))
-		return crypto_aead_setauthsize(a_ctx->fallback_aead_tfm, authsize);
-
-	return 0;
+	return crypto_aead_setauthsize(a_ctx->fallback_aead_tfm, authsize);
 }
 
 static int sec_aead_fallback_setkey(struct sec_auth_ctx *a_ctx,
@@ -1141,7 +1139,6 @@
 static int sec_aead_setkey(struct crypto_aead *tfm, const u8 *key,
 			   const u32 keylen, const enum sec_hash_alg a_alg,
 			   const enum sec_calg c_alg,
-			   const enum sec_mac_len mac_len,
 			   const enum sec_cmode c_mode)
 {
 	struct sec_ctx *ctx = crypto_aead_ctx(tfm);
@@ -1153,7 +1150,6 @@
 
 	ctx->a_ctx.a_alg = a_alg;
 	ctx->c_ctx.c_alg = c_alg;
-	ctx->a_ctx.mac_len = mac_len;
 	c_ctx->c_mode = c_mode;
 
 	if (c_mode == SEC_CMODE_CCM || c_mode == SEC_CMODE_GCM) {
@@ -1164,13 +1160,7 @@
 		}
 		memcpy(c_ctx->c_key, key, keylen);
 
-		if (unlikely(a_ctx->fallback_aead_tfm)) {
-			ret = sec_aead_fallback_setkey(a_ctx, tfm, key, keylen);
-			if (ret)
-				return ret;
-		}
-
-		return 0;
+		return sec_aead_fallback_setkey(a_ctx, tfm, key, keylen);
 	}
 
 	ret = crypto_authenc_extractkeys(&keys, key, keylen);
@@ -1189,10 +1179,15 @@
 		goto bad_key;
 	}
 
-	if ((ctx->a_ctx.mac_len & SEC_SQE_LEN_RATE_MASK)  ||
-	    (ctx->a_ctx.a_key_len & SEC_SQE_LEN_RATE_MASK)) {
+	if (ctx->a_ctx.a_key_len & SEC_SQE_LEN_RATE_MASK) {
 		ret = -EINVAL;
-		dev_err(dev, "MAC or AUTH key length error!\n");
+		dev_err(dev, "AUTH key length error!\n");
+		goto bad_key;
+	}
+
+	ret = sec_aead_fallback_setkey(a_ctx, tfm, key, keylen);
+	if (ret) {
+		dev_err(dev, "set sec fallback key err!\n");
 		goto bad_key;
 	}
 
@@ -1204,27 +1199,19 @@
 }
 
 
-#define GEN_SEC_AEAD_SETKEY_FUNC(name, aalg, calg, maclen, cmode)	\
-static int sec_setkey_##name(struct crypto_aead *tfm, const u8 *key,	\
-	u32 keylen)							\
-{									\
-	return sec_aead_setkey(tfm, key, keylen, aalg, calg, maclen, cmode);\
+#define GEN_SEC_AEAD_SETKEY_FUNC(name, aalg, calg, cmode)				\
+static int sec_setkey_##name(struct crypto_aead *tfm, const u8 *key, u32 keylen)	\
+{											\
+	return sec_aead_setkey(tfm, key, keylen, aalg, calg, cmode);			\
 }
 
-GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha1, SEC_A_HMAC_SHA1,
-			 SEC_CALG_AES, SEC_HMAC_SHA1_MAC, SEC_CMODE_CBC)
-GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha256, SEC_A_HMAC_SHA256,
-			 SEC_CALG_AES, SEC_HMAC_SHA256_MAC, SEC_CMODE_CBC)
-GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha512, SEC_A_HMAC_SHA512,
-			 SEC_CALG_AES, SEC_HMAC_SHA512_MAC, SEC_CMODE_CBC)
-GEN_SEC_AEAD_SETKEY_FUNC(aes_ccm, 0, SEC_CALG_AES,
-			 SEC_HMAC_CCM_MAC, SEC_CMODE_CCM)
-GEN_SEC_AEAD_SETKEY_FUNC(aes_gcm, 0, SEC_CALG_AES,
-			 SEC_HMAC_GCM_MAC, SEC_CMODE_GCM)
-GEN_SEC_AEAD_SETKEY_FUNC(sm4_ccm, 0, SEC_CALG_SM4,
-			 SEC_HMAC_CCM_MAC, SEC_CMODE_CCM)
-GEN_SEC_AEAD_SETKEY_FUNC(sm4_gcm, 0, SEC_CALG_SM4,
-			 SEC_HMAC_GCM_MAC, SEC_CMODE_GCM)
+GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha1, SEC_A_HMAC_SHA1, SEC_CALG_AES, SEC_CMODE_CBC)
+GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha256, SEC_A_HMAC_SHA256, SEC_CALG_AES, SEC_CMODE_CBC)
+GEN_SEC_AEAD_SETKEY_FUNC(aes_cbc_sha512, SEC_A_HMAC_SHA512, SEC_CALG_AES, SEC_CMODE_CBC)
+GEN_SEC_AEAD_SETKEY_FUNC(aes_ccm, 0, SEC_CALG_AES, SEC_CMODE_CCM)
+GEN_SEC_AEAD_SETKEY_FUNC(aes_gcm, 0, SEC_CALG_AES, SEC_CMODE_GCM)
+GEN_SEC_AEAD_SETKEY_FUNC(sm4_ccm, 0, SEC_CALG_SM4, SEC_CMODE_CCM)
+GEN_SEC_AEAD_SETKEY_FUNC(sm4_gcm, 0, SEC_CALG_SM4, SEC_CMODE_GCM)
 
 static int sec_aead_sgl_map(struct sec_ctx *ctx, struct sec_req *req)
 {
@@ -1472,9 +1459,10 @@
 static void set_aead_auth_iv(struct sec_ctx *ctx, struct sec_req *req)
 {
 	struct aead_request *aead_req = req->aead_req.aead_req;
-	struct sec_cipher_req *c_req = &req->c_req;
+	struct crypto_aead *tfm = crypto_aead_reqtfm(aead_req);
+	size_t authsize = crypto_aead_authsize(tfm);
 	struct sec_aead_req *a_req = &req->aead_req;
-	size_t authsize = ctx->a_ctx.mac_len;
+	struct sec_cipher_req *c_req = &req->c_req;
 	u32 data_size = aead_req->cryptlen;
 	u8 flage = 0;
 	u8 cm, cl;
@@ -1515,10 +1503,8 @@
 static void sec_aead_set_iv(struct sec_ctx *ctx, struct sec_req *req)
 {
 	struct aead_request *aead_req = req->aead_req.aead_req;
-	struct crypto_aead *tfm = crypto_aead_reqtfm(aead_req);
-	size_t authsize = crypto_aead_authsize(tfm);
-	struct sec_cipher_req *c_req = &req->c_req;
 	struct sec_aead_req *a_req = &req->aead_req;
+	struct sec_cipher_req *c_req = &req->c_req;
 
 	memcpy(c_req->c_ivin, aead_req->iv, ctx->c_ctx.ivsize);
 
@@ -1526,15 +1512,11 @@
 		/*
 		 * CCM 16Byte Cipher_IV: {1B_Flage,13B_IV,2B_counter},
 		 * the  counter must set to 0x01
+		 * CCM 16Byte Auth_IV: {1B_AFlage,13B_IV,2B_Ptext_length}
 		 */
-		ctx->a_ctx.mac_len = authsize;
-		/* CCM 16Byte Auth_IV: {1B_AFlage,13B_IV,2B_Ptext_length} */
 		set_aead_auth_iv(ctx, req);
-	}
-
-	/* GCM 12Byte Cipher_IV == Auth_IV */
-	if (ctx->c_ctx.c_mode == SEC_CMODE_GCM) {
-		ctx->a_ctx.mac_len = authsize;
+	} else if (ctx->c_ctx.c_mode == SEC_CMODE_GCM) {
+		/* GCM 12Byte Cipher_IV == Auth_IV */
 		memcpy(a_req->a_ivin, c_req->c_ivin, SEC_AIV_SIZE);
 	}
 }
@@ -1544,9 +1526,11 @@
 {
 	struct sec_aead_req *a_req = &req->aead_req;
 	struct aead_request *aq = a_req->aead_req;
+	struct crypto_aead *tfm = crypto_aead_reqtfm(aq);
+	size_t authsize = crypto_aead_authsize(tfm);
 
 	/* C_ICV_Len is MAC size, 0x4 ~ 0x10 */
-	sec_sqe->type2.icvw_kmode |= cpu_to_le16((u16)ctx->mac_len);
+	sec_sqe->type2.icvw_kmode |= cpu_to_le16((u16)authsize);
 
 	/* mode set to CCM/GCM, don't set {A_Alg, AKey_Len, MAC_Len} */
 	sec_sqe->type2.a_key_addr = sec_sqe->type2.c_key_addr;
@@ -1570,9 +1554,11 @@
 {
 	struct sec_aead_req *a_req = &req->aead_req;
 	struct aead_request *aq = a_req->aead_req;
+	struct crypto_aead *tfm = crypto_aead_reqtfm(aq);
+	size_t authsize = crypto_aead_authsize(tfm);
 
 	/* C_ICV_Len is MAC size, 0x4 ~ 0x10 */
-	sqe3->c_icv_key |= cpu_to_le16((u16)ctx->mac_len << SEC_MAC_OFFSET_V3);
+	sqe3->c_icv_key |= cpu_to_le16((u16)authsize << SEC_MAC_OFFSET_V3);
 
 	/* mode set to CCM/GCM, don't set {A_Alg, AKey_Len, MAC_Len} */
 	sqe3->a_key_addr = sqe3->c_key_addr;
@@ -1596,11 +1582,12 @@
 	struct sec_aead_req *a_req = &req->aead_req;
 	struct sec_cipher_req *c_req = &req->c_req;
 	struct aead_request *aq = a_req->aead_req;
+	struct crypto_aead *tfm = crypto_aead_reqtfm(aq);
+	size_t authsize = crypto_aead_authsize(tfm);
 
 	sec_sqe->type2.a_key_addr = cpu_to_le64(ctx->a_key_dma);
 
-	sec_sqe->type2.mac_key_alg =
-			cpu_to_le32(ctx->mac_len / SEC_SQE_LEN_RATE);
+	sec_sqe->type2.mac_key_alg = cpu_to_le32(authsize / SEC_SQE_LEN_RATE);
 
 	sec_sqe->type2.mac_key_alg |=
 			cpu_to_le32((u32)((ctx->a_key_len) /
@@ -1650,11 +1637,13 @@
 	struct sec_aead_req *a_req = &req->aead_req;
 	struct sec_cipher_req *c_req = &req->c_req;
 	struct aead_request *aq = a_req->aead_req;
+	struct crypto_aead *tfm = crypto_aead_reqtfm(aq);
+	size_t authsize = crypto_aead_authsize(tfm);
 
 	sqe3->a_key_addr = cpu_to_le64(ctx->a_key_dma);
 
 	sqe3->auth_mac_key |=
-			cpu_to_le32((u32)(ctx->mac_len /
+			cpu_to_le32((u32)(authsize /
 			SEC_SQE_LEN_RATE) << SEC_MAC_OFFSET_V3);
 
 	sqe3->auth_mac_key |=
@@ -1705,9 +1694,9 @@
 {
 	struct aead_request *a_req = req->aead_req.aead_req;
 	struct crypto_aead *tfm = crypto_aead_reqtfm(a_req);
+	size_t authsize = crypto_aead_authsize(tfm);
 	struct sec_aead_req *aead_req = &req->aead_req;
 	struct sec_cipher_req *c_req = &req->c_req;
-	size_t authsize = crypto_aead_authsize(tfm);
 	struct sec_qp_ctx *qp_ctx = req->qp_ctx;
 	struct aead_request *backlog_aead_req;
 	struct sec_req *backlog_req;
@@ -1720,10 +1709,8 @@
 	if (!err && c_req->encrypt) {
 		struct scatterlist *sgl = a_req->dst;
 
-		sz = sg_pcopy_from_buffer(sgl, sg_nents(sgl),
-					  aead_req->out_mac,
-					  authsize, a_req->cryptlen +
-					  a_req->assoclen);
+		sz = sg_pcopy_from_buffer(sgl, sg_nents(sgl), aead_req->out_mac,
+					  authsize, a_req->cryptlen + a_req->assoclen);
 		if (unlikely(sz != authsize)) {
 			dev_err(c->dev, "copy out mac err!\n");
 			err = -EINVAL;
@@ -1931,8 +1918,10 @@
 
 static int sec_aead_ctx_init(struct crypto_aead *tfm, const char *hash_name)
 {
+	struct aead_alg *alg = crypto_aead_alg(tfm);
 	struct sec_ctx *ctx = crypto_aead_ctx(tfm);
-	struct sec_auth_ctx *auth_ctx = &ctx->a_ctx;
+	struct sec_auth_ctx *a_ctx = &ctx->a_ctx;
+	const char *aead_name = alg->base.cra_name;
 	int ret;
 
 	ret = sec_aead_init(tfm);
@@ -1941,11 +1930,20 @@
 		return ret;
 	}
 
-	auth_ctx->hash_tfm = crypto_alloc_shash(hash_name, 0, 0);
-	if (IS_ERR(auth_ctx->hash_tfm)) {
+	a_ctx->hash_tfm = crypto_alloc_shash(hash_name, 0, 0);
+	if (IS_ERR(a_ctx->hash_tfm)) {
 		dev_err(ctx->dev, "aead alloc shash error!\n");
 		sec_aead_exit(tfm);
-		return PTR_ERR(auth_ctx->hash_tfm);
+		return PTR_ERR(a_ctx->hash_tfm);
+	}
+
+	a_ctx->fallback_aead_tfm = crypto_alloc_aead(aead_name, 0,
+						     CRYPTO_ALG_NEED_FALLBACK | CRYPTO_ALG_ASYNC);
+	if (IS_ERR(a_ctx->fallback_aead_tfm)) {
+		dev_err(ctx->dev, "aead driver alloc fallback tfm error!\n");
+		crypto_free_shash(ctx->a_ctx.hash_tfm);
+		sec_aead_exit(tfm);
+		return PTR_ERR(a_ctx->fallback_aead_tfm);
 	}
 
 	return 0;
@@ -1955,6 +1953,7 @@
 {
 	struct sec_ctx *ctx = crypto_aead_ctx(tfm);
 
+	crypto_free_aead(ctx->a_ctx.fallback_aead_tfm);
 	crypto_free_shash(ctx->a_ctx.hash_tfm);
 	sec_aead_exit(tfm);
 }
@@ -1981,7 +1980,6 @@
 		sec_aead_exit(tfm);
 		return PTR_ERR(a_ctx->fallback_aead_tfm);
 	}
-	a_ctx->fallback = false;
 
 	return 0;
 }
@@ -2240,21 +2238,20 @@
 {
 	struct aead_request *req = sreq->aead_req.aead_req;
 	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
-	size_t authsize = crypto_aead_authsize(tfm);
+	size_t sz = crypto_aead_authsize(tfm);
 	u8 c_mode = ctx->c_ctx.c_mode;
 	struct device *dev = ctx->dev;
 	int ret;
 
-	if (unlikely(req->cryptlen + req->assoclen > MAX_INPUT_DATA_LEN ||
-	    req->assoclen > SEC_MAX_AAD_LEN)) {
-		dev_err(dev, "aead input spec error!\n");
+	/* Hardware does not handle cases where authsize is less than 4 bytes */
+	if (unlikely(sz < MIN_MAC_LEN)) {
+		sreq->aead_req.fallback = true;
 		return -EINVAL;
 	}
 
-	if (unlikely((c_mode == SEC_CMODE_GCM && authsize < DES_BLOCK_SIZE) ||
-	   (c_mode == SEC_CMODE_CCM && (authsize < MIN_MAC_LEN ||
-		authsize & MAC_LEN_MASK)))) {
-		dev_err(dev, "aead input mac length error!\n");
+	if (unlikely(req->cryptlen + req->assoclen > MAX_INPUT_DATA_LEN ||
+	    req->assoclen > SEC_MAX_AAD_LEN)) {
+		dev_err(dev, "aead input spec error!\n");
 		return -EINVAL;
 	}
 
@@ -2273,7 +2270,7 @@
 	if (sreq->c_req.encrypt)
 		sreq->c_req.c_len = req->cryptlen;
 	else
-		sreq->c_req.c_len = req->cryptlen - authsize;
+		sreq->c_req.c_len = req->cryptlen - sz;
 	if (c_mode == SEC_CMODE_CBC) {
 		if (unlikely(sreq->c_req.c_len & (AES_BLOCK_SIZE - 1))) {
 			dev_err(dev, "aead crypto length error!\n");
@@ -2299,8 +2296,8 @@
 
 	if (ctx->sec->qm.ver == QM_HW_V2) {
 		if (unlikely(!req->cryptlen || (!sreq->c_req.encrypt &&
-		    req->cryptlen <= authsize))) {
-			ctx->a_ctx.fallback = true;
+			     req->cryptlen <= authsize))) {
+			sreq->aead_req.fallback = true;
 			return -EINVAL;
 		}
 	}
@@ -2328,16 +2325,9 @@
 				bool encrypt)
 {
 	struct sec_auth_ctx *a_ctx = &ctx->a_ctx;
-	struct device *dev = ctx->dev;
 	struct aead_request *subreq;
 	int ret;
 
-	/* Kunpeng920 aead mode not support input 0 size */
-	if (!a_ctx->fallback_aead_tfm) {
-		dev_err(dev, "aead fallback tfm is NULL!\n");
-		return -EINVAL;
-	}
-
 	subreq = aead_request_alloc(a_ctx->fallback_aead_tfm, GFP_KERNEL);
 	if (!subreq)
 		return -ENOMEM;
@@ -2369,10 +2359,11 @@
 	req->aead_req.aead_req = a_req;
 	req->c_req.encrypt = encrypt;
 	req->ctx = ctx;
+	req->aead_req.fallback = false;
 
 	ret = sec_aead_param_check(ctx, req);
 	if (unlikely(ret)) {
-		if (ctx->a_ctx.fallback)
+		if (req->aead_req.fallback)
 			return sec_aead_soft_crypto(ctx, a_req, encrypt);
 		return -EINVAL;
 	}
--- linux-qcom-6.8.0.orig/drivers/crypto/hisilicon/sec2/sec_crypto.h
+++ linux-qcom-6.8.0/drivers/crypto/hisilicon/sec2/sec_crypto.h
@@ -23,17 +23,6 @@
 	SEC_A_HMAC_SHA512 = 0x15,
 };
 
-enum sec_mac_len {
-	SEC_HMAC_CCM_MAC   = 16,
-	SEC_HMAC_GCM_MAC   = 16,
-	SEC_SM3_MAC        = 32,
-	SEC_HMAC_SM3_MAC   = 32,
-	SEC_HMAC_MD5_MAC   = 16,
-	SEC_HMAC_SHA1_MAC   = 20,
-	SEC_HMAC_SHA256_MAC = 32,
-	SEC_HMAC_SHA512_MAC = 64,
-};
-
 enum sec_cmode {
 	SEC_CMODE_ECB    = 0x0,
 	SEC_CMODE_CBC    = 0x1,
--- linux-qcom-6.8.0.orig/drivers/crypto/hisilicon/sec2/sec_main.c
+++ linux-qcom-6.8.0/drivers/crypto/hisilicon/sec2/sec_main.c
@@ -152,7 +152,7 @@
 	{SEC_CORE_TYPE_NUM_CAP, 0x313c, 16, GENMASK(3, 0), 0x1, 0x1, 0x1},
 	{SEC_CORE_NUM_CAP, 0x313c, 8, GENMASK(7, 0), 0x4, 0x4, 0x4},
 	{SEC_CORES_PER_CLUSTER_NUM_CAP, 0x313c, 0, GENMASK(7, 0), 0x4, 0x4, 0x4},
-	{SEC_CORE_ENABLE_BITMAP, 0x3140, 32, GENMASK(31, 0), 0x17F, 0x17F, 0xF},
+	{SEC_CORE_ENABLE_BITMAP, 0x3140, 0, GENMASK(31, 0), 0x17F, 0x17F, 0xF},
 	{SEC_DRV_ALG_BITMAP_LOW, 0x3144, 0, GENMASK(31, 0), 0x18050CB, 0x18050CB, 0x18670CF},
 	{SEC_DRV_ALG_BITMAP_HIGH, 0x3148, 0, GENMASK(31, 0), 0x395C, 0x395C, 0x395C},
 	{SEC_DEV_ALG_BITMAP_LOW, 0x314c, 0, GENMASK(31, 0), 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
@@ -1006,11 +1006,15 @@
 
 static void sec_clear_hw_err_status(struct hisi_qm *qm, u32 err_sts)
 {
-	u32 nfe;
-
 	writel(err_sts, qm->io_base + SEC_CORE_INT_SOURCE);
-	nfe = hisi_qm_get_hw_info(qm, sec_basic_info, SEC_NFE_MASK_CAP, qm->cap_ver);
-	writel(nfe, qm->io_base + SEC_RAS_NFE_REG);
+}
+
+static void sec_disable_error_report(struct hisi_qm *qm, u32 err_type)
+{
+	u32 nfe_mask;
+
+	nfe_mask = hisi_qm_get_hw_info(qm, sec_basic_info, SEC_NFE_MASK_CAP, qm->cap_ver);
+	writel(nfe_mask & (~err_type), qm->io_base + SEC_RAS_NFE_REG);
 }
 
 static void sec_open_axi_master_ooo(struct hisi_qm *qm)
@@ -1022,6 +1026,27 @@
 	writel(val | SEC_AXI_SHUTDOWN_ENABLE, qm->io_base + SEC_CONTROL_REG);
 }
 
+static enum acc_err_result sec_get_err_result(struct hisi_qm *qm)
+{
+	u32 err_status;
+
+	err_status = sec_get_hw_err_status(qm);
+	if (err_status) {
+		if (err_status & qm->err_info.ecc_2bits_mask)
+			qm->err_status.is_dev_ecc_mbit = true;
+		sec_log_hw_error(qm, err_status);
+
+		if (err_status & qm->err_info.dev_reset_mask) {
+			/* Disable the same error reporting until device is recovered. */
+			sec_disable_error_report(qm, err_status);
+			return ACC_ERR_NEED_RESET;
+		}
+		sec_clear_hw_err_status(qm, err_status);
+	}
+
+	return ACC_ERR_RECOVERED;
+}
+
 static void sec_err_info_init(struct hisi_qm *qm)
 {
 	struct hisi_qm_err_info *err_info = &qm->err_info;
@@ -1048,12 +1073,12 @@
 	.hw_err_disable		= sec_hw_error_disable,
 	.get_dev_hw_err_status	= sec_get_hw_err_status,
 	.clear_dev_hw_err_status = sec_clear_hw_err_status,
-	.log_dev_hw_err		= sec_log_hw_error,
 	.open_axi_master_ooo	= sec_open_axi_master_ooo,
 	.open_sva_prefetch	= sec_open_sva_prefetch,
 	.close_sva_prefetch	= sec_close_sva_prefetch,
 	.show_last_dfx_regs	= sec_show_last_dfx_regs,
 	.err_info_init		= sec_err_info_init,
+	.get_err_result		= sec_get_err_result,
 };
 
 static int sec_pf_probe_init(struct sec_dev *sec)
@@ -1061,9 +1086,6 @@
 	struct hisi_qm *qm = &sec->qm;
 	int ret;
 
-	qm->err_ini = &sec_err_ini;
-	qm->err_ini->err_info_init(qm);
-
 	ret = sec_set_user_domain_and_cache(qm);
 	if (ret)
 		return ret;
@@ -1118,6 +1140,7 @@
 		qm->qp_num = pf_q_num;
 		qm->debug.curr_qm_qp_num = pf_q_num;
 		qm->qm_list = &sec_devices;
+		qm->err_ini = &sec_err_ini;
 		if (pf_q_num_flag)
 			set_bit(QM_MODULE_PARAM, &qm->misc_ctl);
 	} else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) {
@@ -1182,6 +1205,12 @@
 
 static void sec_probe_uninit(struct hisi_qm *qm)
 {
+	if (qm->fun_type == QM_HW_VF)
+		return;
+
+	sec_debug_regs_clear(qm);
+	sec_show_last_regs_uninit(qm);
+	sec_close_sva_prefetch(qm);
 	hisi_qm_dev_err_uninit(qm);
 }
 
@@ -1270,7 +1299,6 @@
 	sec_debugfs_exit(qm);
 	hisi_qm_stop(qm, QM_NORMAL);
 err_probe_uninit:
-	sec_show_last_regs_uninit(qm);
 	sec_probe_uninit(qm);
 err_qm_uninit:
 	sec_qm_uninit(qm);
@@ -1292,11 +1320,6 @@
 	sec_debugfs_exit(qm);
 
 	(void)hisi_qm_stop(qm, QM_NORMAL);
-
-	if (qm->fun_type == QM_HW_PF)
-		sec_debug_regs_clear(qm);
-	sec_show_last_regs_uninit(qm);
-
 	sec_probe_uninit(qm);
 
 	sec_qm_uninit(qm);
--- linux-qcom-6.8.0.orig/drivers/crypto/hisilicon/sgl.c
+++ linux-qcom-6.8.0/drivers/crypto/hisilicon/sgl.c
@@ -228,7 +228,7 @@
 	dma_addr_t curr_sgl_dma = 0;
 	struct acc_hw_sge *curr_hw_sge;
 	struct scatterlist *sg;
-	int sg_n;
+	int sg_n, ret;
 
 	if (!dev || !sgl || !pool || !hw_sgl_dma)
 		return ERR_PTR(-EINVAL);
@@ -243,14 +243,15 @@
 
 	if (sg_n_mapped > pool->sge_nr) {
 		dev_err(dev, "the number of entries in input scatterlist is bigger than SGL pool setting.\n");
-		return ERR_PTR(-EINVAL);
+		ret = -EINVAL;
+		goto err_unmap;
 	}
 
 	curr_hw_sgl = acc_get_sgl(pool, index, &curr_sgl_dma);
 	if (IS_ERR(curr_hw_sgl)) {
 		dev_err(dev, "Get SGL error!\n");
-		dma_unmap_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL);
-		return ERR_PTR(-ENOMEM);
+		ret = -ENOMEM;
+		goto err_unmap;
 	}
 	curr_hw_sgl->entry_length_in_sgl = cpu_to_le16(pool->sge_nr);
 	curr_hw_sge = curr_hw_sgl->sge_entries;
@@ -265,6 +266,11 @@
 	*hw_sgl_dma = curr_sgl_dma;
 
 	return curr_hw_sgl;
+
+err_unmap:
+	dma_unmap_sg(dev, sgl, sg_n, DMA_BIDIRECTIONAL);
+
+	return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(hisi_acc_sg_buf_map_to_hw_sgl);
 
--- linux-qcom-6.8.0.orig/drivers/crypto/hisilicon/zip/zip_main.c
+++ linux-qcom-6.8.0/drivers/crypto/hisilicon/zip/zip_main.c
@@ -1069,11 +1069,15 @@
 
 static void hisi_zip_clear_hw_err_status(struct hisi_qm *qm, u32 err_sts)
 {
-	u32 nfe;
-
 	writel(err_sts, qm->io_base + HZIP_CORE_INT_SOURCE);
-	nfe = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_NFE_MASK_CAP, qm->cap_ver);
-	writel(nfe, qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);
+}
+
+static void hisi_zip_disable_error_report(struct hisi_qm *qm, u32 err_type)
+{
+	u32 nfe_mask;
+
+	nfe_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_NFE_MASK_CAP, qm->cap_ver);
+	writel(nfe_mask & (~err_type), qm->io_base + HZIP_CORE_INT_RAS_NFE_ENB);
 }
 
 static void hisi_zip_open_axi_master_ooo(struct hisi_qm *qm)
@@ -1103,6 +1107,27 @@
 	       qm->io_base + HZIP_CORE_INT_SET);
 }
 
+static enum acc_err_result hisi_zip_get_err_result(struct hisi_qm *qm)
+{
+	u32 err_status;
+
+	err_status = hisi_zip_get_hw_err_status(qm);
+	if (err_status) {
+		if (err_status & qm->err_info.ecc_2bits_mask)
+			qm->err_status.is_dev_ecc_mbit = true;
+		hisi_zip_log_hw_error(qm, err_status);
+
+		if (err_status & qm->err_info.dev_reset_mask) {
+			/* Disable the same error reporting until device is recovered. */
+			hisi_zip_disable_error_report(qm, err_status);
+			return ACC_ERR_NEED_RESET;
+		}
+		hisi_zip_clear_hw_err_status(qm, err_status);
+	}
+
+	return ACC_ERR_RECOVERED;
+}
+
 static void hisi_zip_err_info_init(struct hisi_qm *qm)
 {
 	struct hisi_qm_err_info *err_info = &qm->err_info;
@@ -1130,13 +1155,13 @@
 	.hw_err_disable		= hisi_zip_hw_error_disable,
 	.get_dev_hw_err_status	= hisi_zip_get_hw_err_status,
 	.clear_dev_hw_err_status = hisi_zip_clear_hw_err_status,
-	.log_dev_hw_err		= hisi_zip_log_hw_error,
 	.open_axi_master_ooo	= hisi_zip_open_axi_master_ooo,
 	.close_axi_master_ooo	= hisi_zip_close_axi_master_ooo,
 	.open_sva_prefetch	= hisi_zip_open_sva_prefetch,
 	.close_sva_prefetch	= hisi_zip_close_sva_prefetch,
 	.show_last_dfx_regs	= hisi_zip_show_last_dfx_regs,
 	.err_info_init		= hisi_zip_err_info_init,
+	.get_err_result		= hisi_zip_get_err_result,
 };
 
 static int hisi_zip_pf_probe_init(struct hisi_zip *hisi_zip)
@@ -1151,8 +1176,6 @@
 
 	hisi_zip->ctrl = ctrl;
 	ctrl->hisi_zip = hisi_zip;
-	qm->err_ini = &hisi_zip_err_ini;
-	qm->err_ini->err_info_init(qm);
 
 	ret = hisi_zip_set_user_domain_and_cache(qm);
 	if (ret)
@@ -1213,6 +1236,7 @@
 		qm->qp_num = pf_q_num;
 		qm->debug.curr_qm_qp_num = pf_q_num;
 		qm->qm_list = &zip_devices;
+		qm->err_ini = &hisi_zip_err_ini;
 		if (pf_q_num_flag)
 			set_bit(QM_MODULE_PARAM, &qm->misc_ctl);
 	} else if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V1) {
@@ -1279,6 +1303,16 @@
 	return 0;
 }
 
+static void hisi_zip_probe_uninit(struct hisi_qm *qm)
+{
+	if (qm->fun_type == QM_HW_VF)
+		return;
+
+	hisi_zip_show_last_regs_uninit(qm);
+	hisi_zip_close_sva_prefetch(qm);
+	hisi_qm_dev_err_uninit(qm);
+}
+
 static int hisi_zip_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	struct hisi_zip *hisi_zip;
@@ -1305,7 +1339,7 @@
 
 	ret = hisi_qm_start(qm);
 	if (ret)
-		goto err_dev_err_uninit;
+		goto err_probe_uninit;
 
 	ret = hisi_zip_debugfs_init(qm);
 	if (ret)
@@ -1344,9 +1378,8 @@
 	hisi_zip_debugfs_exit(qm);
 	hisi_qm_stop(qm, QM_NORMAL);
 
-err_dev_err_uninit:
-	hisi_zip_show_last_regs_uninit(qm);
-	hisi_qm_dev_err_uninit(qm);
+err_probe_uninit:
+	hisi_zip_probe_uninit(qm);
 
 err_qm_uninit:
 	hisi_zip_qm_uninit(qm);
@@ -1368,8 +1401,7 @@
 
 	hisi_zip_debugfs_exit(qm);
 	hisi_qm_stop(qm, QM_NORMAL);
-	hisi_zip_show_last_regs_uninit(qm);
-	hisi_qm_dev_err_uninit(qm);
+	hisi_zip_probe_uninit(qm);
 	hisi_zip_qm_uninit(qm);
 }
 
--- linux-qcom-6.8.0.orig/drivers/crypto/inside-secure/safexcel_hash.c
+++ linux-qcom-6.8.0/drivers/crypto/inside-secure/safexcel_hash.c
@@ -2093,7 +2093,7 @@
 
 	safexcel_ahash_cra_init(tfm);
 	ctx->aes = kmalloc(sizeof(*ctx->aes), GFP_KERNEL);
-	return PTR_ERR_OR_ZERO(ctx->aes);
+	return ctx->aes == NULL ? -ENOMEM : 0;
 }
 
 static void safexcel_xcbcmac_cra_exit(struct crypto_tfm *tfm)
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/iaa/iaa_crypto_main.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/iaa/iaa_crypto_main.c
@@ -173,7 +173,7 @@
 		async_mode = false;
 		use_irq = false;
 	} else if (sysfs_streq(name, "async")) {
-		async_mode = true;
+		async_mode = false;
 		use_irq = false;
 	} else if (sysfs_streq(name, "async_irq")) {
 		async_mode = true;
@@ -599,10 +599,10 @@
 		if (!device_mode)
 			continue;
 
-		free_device_compression_mode(iaa_device, device_mode);
-		iaa_device->compression_modes[i] = NULL;
 		if (iaa_compression_modes[i]->free)
 			iaa_compression_modes[i]->free(device_mode);
+		free_device_compression_mode(iaa_device, device_mode);
+		iaa_device->compression_modes[i] = NULL;
 	}
 }
 
@@ -908,6 +908,8 @@
 		return -EINVAL;
 
 	cpus_per_iaa = (nr_nodes * nr_cpus_per_node) / nr_iaa;
+	if (!cpus_per_iaa)
+		cpus_per_iaa = 1;
 out:
 	return 0;
 }
@@ -923,10 +925,12 @@
 		}
 	}
 
-	if (nr_iaa)
+	if (nr_iaa) {
 		cpus_per_iaa = (nr_nodes * nr_cpus_per_node) / nr_iaa;
-	else
-		cpus_per_iaa = 0;
+		if (!cpus_per_iaa)
+			cpus_per_iaa = 1;
+	} else
+		cpus_per_iaa = 1;
 }
 
 static int wq_table_add_wqs(int iaa, int cpu)
@@ -1324,7 +1328,7 @@
 
 	*compression_crc = idxd_desc->iax_completion->crc;
 
-	if (!ctx->async_mode)
+	if (!ctx->async_mode || disable_async)
 		idxd_free_desc(wq, idxd_desc);
 out:
 	return ret;
@@ -1570,7 +1574,7 @@
 
 	*dlen = req->dlen;
 
-	if (!ctx->async_mode)
+	if (!ctx->async_mode || disable_async)
 		idxd_free_desc(wq, idxd_desc);
 
 	/* Update stats */
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c
@@ -471,6 +471,7 @@
 			return -ENODEV;
 		}
 		npe_id = npe_spec.args[0];
+		of_node_put(npe_spec.np);
 
 		ret = of_parse_phandle_with_fixed_args(np, "queue-rx", 1, 0,
 						       &queue_spec);
@@ -479,6 +480,7 @@
 			return -ENODEV;
 		}
 		recv_qid = queue_spec.args[0];
+		of_node_put(queue_spec.np);
 
 		ret = of_parse_phandle_with_fixed_args(np, "queue-txready", 1, 0,
 						       &queue_spec);
@@ -487,6 +489,7 @@
 			return -ENODEV;
 		}
 		send_qid = queue_spec.args[0];
+		of_node_put(queue_spec.np);
 	} else {
 		/*
 		 * Hardcoded engine when using platform data, this goes away
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/Kconfig
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/Kconfig
@@ -106,3 +106,17 @@
 
 	  To compile this as a module, choose M here: the module
 	  will be called qat_c62xvf.
+
+config CRYPTO_DEV_QAT_ERROR_INJECTION
+	bool "Support for Intel(R) QAT Devices Heartbeat Error Injection"
+	depends on CRYPTO_DEV_QAT
+	depends on DEBUG_FS
+	help
+	  Enables a mechanism that allows to inject a heartbeat error on
+	  Intel(R) QuickAssist devices for testing purposes.
+
+	  This is intended for developer use only.
+	  If unsure, say N.
+
+	  This functionality is available via debugfs entry of the Intel(R)
+	  QuickAssist device
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c
@@ -296,7 +296,7 @@
 {
 	if (adf_gen4_init_thd2arb_map(accel_dev))
 		dev_warn(&GET_DEV(accel_dev),
-			 "Generate of the thread to arbiter map failed");
+			 "Failed to generate thread to arbiter mapping");
 
 	return GET_HW_DATA(accel_dev)->thd_to_arb_map;
 }
@@ -372,6 +372,13 @@
 	if (!fw_config)
 		return 0;
 
+	/* If dcc, all rings handle compression requests */
+	if (adf_get_service_enabled(accel_dev) == SVC_DCC) {
+		for (i = 0; i < RP_GROUP_COUNT; i++)
+			rps[i] = COMP;
+		goto set_mask;
+	}
+
 	for (i = 0; i < RP_GROUP_COUNT; i++) {
 		switch (fw_config[i].ae_mask) {
 		case ADF_AE_GROUP_0:
@@ -400,6 +407,7 @@
 		}
 	}
 
+set_mask:
 	ring_to_svc_map = rps[RP_GROUP_0] << ADF_CFG_SERV_RING_PAIR_0_SHIFT |
 			  rps[RP_GROUP_1] << ADF_CFG_SERV_RING_PAIR_1_SHIFT |
 			  rps[RP_GROUP_0] << ADF_CFG_SERV_RING_PAIR_2_SHIFT |
@@ -420,7 +428,7 @@
 	else
 		id = -EINVAL;
 
-	if (id < 0 || id > num_objs)
+	if (id < 0 || id >= num_objs)
 		return NULL;
 
 	return fw_objs[id];
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c
@@ -208,7 +208,7 @@
 {
 	if (adf_gen4_init_thd2arb_map(accel_dev))
 		dev_warn(&GET_DEV(accel_dev),
-			 "Generate of the thread to arbiter map failed");
+			 "Failed to generate thread to arbiter mapping");
 
 	return GET_HW_DATA(accel_dev)->thd_to_arb_map;
 }
@@ -331,6 +331,13 @@
 	if (!fw_config)
 		return 0;
 
+	/* If dcc, all rings handle compression requests */
+	if (adf_get_service_enabled(accel_dev) == SVC_DCC) {
+		for (i = 0; i < RP_GROUP_COUNT; i++)
+			rps[i] = COMP;
+		goto set_mask;
+	}
+
 	for (i = 0; i < RP_GROUP_COUNT; i++) {
 		switch (fw_config[i].ae_mask) {
 		case ADF_AE_GROUP_0:
@@ -359,6 +366,7 @@
 		}
 	}
 
+set_mask:
 	ring_to_svc_map = rps[RP_GROUP_0] << ADF_CFG_SERV_RING_PAIR_0_SHIFT |
 			  rps[RP_GROUP_1] << ADF_CFG_SERV_RING_PAIR_1_SHIFT |
 			  rps[RP_GROUP_0] << ADF_CFG_SERV_RING_PAIR_2_SHIFT |
@@ -379,7 +387,7 @@
 	else
 		id = -EINVAL;
 
-	if (id < 0 || id > num_objs)
+	if (id < 0 || id >= num_objs)
 		return NULL;
 
 	return fw_objs[id];
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_4xxx/adf_drv.c
@@ -197,7 +197,9 @@
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Intel");
 MODULE_FIRMWARE(ADF_4XXX_FW);
+MODULE_FIRMWARE(ADF_402XX_FW);
 MODULE_FIRMWARE(ADF_4XXX_MMP);
+MODULE_FIRMWARE(ADF_402XX_MMP);
 MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");
 MODULE_VERSION(ADF_DRV_VERSION);
 MODULE_SOFTDEP("pre: crypto-intel_qat");
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/Makefile
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/Makefile
@@ -53,3 +53,5 @@
 			       adf_pfvf_pf_msg.o adf_pfvf_pf_proto.o \
 			       adf_pfvf_vf_msg.o adf_pfvf_vf_proto.o \
 			       adf_gen2_pfvf.o adf_gen4_pfvf.o
+
+intel_qat-$(CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION) += adf_heartbeat_inject.o
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h
@@ -332,6 +332,7 @@
 	struct ratelimit_state vf2pf_ratelimit;
 	u32 vf_nr;
 	bool init;
+	bool restarting;
 	u8 vf_compat_ver;
 };
 
@@ -401,6 +402,7 @@
 	struct adf_error_counters ras_errors;
 	struct mutex state_lock; /* protect state of the device */
 	bool is_vf;
+	bool autoreset_on_error;
 	u32 accel_id;
 };
 #endif
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_aer.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_aer.c
@@ -7,8 +7,15 @@
 #include <linux/delay.h>
 #include "adf_accel_devices.h"
 #include "adf_common_drv.h"
+#include "adf_pfvf_pf_msg.h"
+
+struct adf_fatal_error_data {
+	struct adf_accel_dev *accel_dev;
+	struct work_struct work;
+};
 
 static struct workqueue_struct *device_reset_wq;
+static struct workqueue_struct *device_sriov_wq;
 
 static pci_ers_result_t adf_error_detected(struct pci_dev *pdev,
 					   pci_channel_state_t state)
@@ -26,6 +33,19 @@
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 
+	set_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
+	if (accel_dev->hw_device->exit_arb) {
+		dev_dbg(&pdev->dev, "Disabling arbitration\n");
+		accel_dev->hw_device->exit_arb(accel_dev);
+	}
+	adf_error_notifier(accel_dev);
+	adf_pf2vf_notify_fatal_error(accel_dev);
+	adf_dev_restarting_notify(accel_dev);
+	adf_pf2vf_notify_restarting(accel_dev);
+	adf_pf2vf_wait_for_restarting_complete(accel_dev);
+	pci_clear_master(pdev);
+	adf_dev_down(accel_dev, false);
+
 	return PCI_ERS_RESULT_NEED_RESET;
 }
 
@@ -37,6 +57,13 @@
 	struct work_struct reset_work;
 };
 
+/* sriov dev data */
+struct adf_sriov_dev_data {
+	struct adf_accel_dev *accel_dev;
+	struct completion compl;
+	struct work_struct sriov_work;
+};
+
 void adf_reset_sbr(struct adf_accel_dev *accel_dev)
 {
 	struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
@@ -82,11 +109,22 @@
 	}
 }
 
+static void adf_device_sriov_worker(struct work_struct *work)
+{
+	struct adf_sriov_dev_data *sriov_data =
+		container_of(work, struct adf_sriov_dev_data, sriov_work);
+
+	adf_reenable_sriov(sriov_data->accel_dev);
+	complete(&sriov_data->compl);
+}
+
 static void adf_device_reset_worker(struct work_struct *work)
 {
 	struct adf_reset_dev_data *reset_data =
 		  container_of(work, struct adf_reset_dev_data, reset_work);
 	struct adf_accel_dev *accel_dev = reset_data->accel_dev;
+	unsigned long wait_jiffies = msecs_to_jiffies(10000);
+	struct adf_sriov_dev_data sriov_data;
 
 	adf_dev_restarting_notify(accel_dev);
 	if (adf_dev_restart(accel_dev)) {
@@ -97,14 +135,22 @@
 		WARN(1, "QAT: device restart failed. Device is unusable\n");
 		return;
 	}
+
+	sriov_data.accel_dev = accel_dev;
+	init_completion(&sriov_data.compl);
+	INIT_WORK(&sriov_data.sriov_work, adf_device_sriov_worker);
+	queue_work(device_sriov_wq, &sriov_data.sriov_work);
+	if (wait_for_completion_timeout(&sriov_data.compl, wait_jiffies))
+		adf_pf2vf_notify_restarted(accel_dev);
+
 	adf_dev_restarted_notify(accel_dev);
 	clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
 
 	/* The dev is back alive. Notify the caller if in sync mode */
-	if (reset_data->mode == ADF_DEV_RESET_SYNC)
-		complete(&reset_data->compl);
-	else
+	if (reset_data->mode == ADF_DEV_RESET_ASYNC)
 		kfree(reset_data);
+	else
+		complete(&reset_data->compl);
 }
 
 static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev,
@@ -136,6 +182,7 @@
 		if (!timeout) {
 			dev_err(&GET_DEV(accel_dev),
 				"Reset device timeout expired\n");
+			cancel_work_sync(&reset_data->reset_work);
 			ret = -EFAULT;
 		}
 		kfree(reset_data);
@@ -147,14 +194,25 @@
 static pci_ers_result_t adf_slot_reset(struct pci_dev *pdev)
 {
 	struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
+	int res = 0;
 
 	if (!accel_dev) {
 		pr_err("QAT: Can't find acceleration device\n");
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
-	if (adf_dev_aer_schedule_reset(accel_dev, ADF_DEV_RESET_SYNC))
+
+	if (!pdev->is_busmaster)
+		pci_set_master(pdev);
+	pci_restore_state(pdev);
+	pci_save_state(pdev);
+	res = adf_dev_up(accel_dev, false);
+	if (res && res != -EALREADY)
 		return PCI_ERS_RESULT_DISCONNECT;
 
+	adf_reenable_sriov(accel_dev);
+	adf_pf2vf_notify_restarted(accel_dev);
+	adf_dev_restarted_notify(accel_dev);
+	clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
 	return PCI_ERS_RESULT_RECOVERED;
 }
 
@@ -171,11 +229,65 @@
 };
 EXPORT_SYMBOL_GPL(adf_err_handler);
 
+int adf_dev_autoreset(struct adf_accel_dev *accel_dev)
+{
+	if (accel_dev->autoreset_on_error)
+		return adf_dev_aer_schedule_reset(accel_dev, ADF_DEV_RESET_ASYNC);
+
+	return 0;
+}
+
+static void adf_notify_fatal_error_worker(struct work_struct *work)
+{
+	struct adf_fatal_error_data *wq_data =
+			container_of(work, struct adf_fatal_error_data, work);
+	struct adf_accel_dev *accel_dev = wq_data->accel_dev;
+	struct adf_hw_device_data *hw_device = accel_dev->hw_device;
+
+	adf_error_notifier(accel_dev);
+
+	if (!accel_dev->is_vf) {
+		/* Disable arbitration to stop processing of new requests */
+		if (accel_dev->autoreset_on_error && hw_device->exit_arb)
+			hw_device->exit_arb(accel_dev);
+		if (accel_dev->pf.vf_info)
+			adf_pf2vf_notify_fatal_error(accel_dev);
+		adf_dev_autoreset(accel_dev);
+	}
+
+	kfree(wq_data);
+}
+
+int adf_notify_fatal_error(struct adf_accel_dev *accel_dev)
+{
+	struct adf_fatal_error_data *wq_data;
+
+	wq_data = kzalloc(sizeof(*wq_data), GFP_ATOMIC);
+	if (!wq_data)
+		return -ENOMEM;
+
+	wq_data->accel_dev = accel_dev;
+	INIT_WORK(&wq_data->work, adf_notify_fatal_error_worker);
+	adf_misc_wq_queue_work(&wq_data->work);
+
+	return 0;
+}
+
 int adf_init_aer(void)
 {
 	device_reset_wq = alloc_workqueue("qat_device_reset_wq",
 					  WQ_MEM_RECLAIM, 0);
-	return !device_reset_wq ? -EFAULT : 0;
+	if (!device_reset_wq)
+		return -EFAULT;
+
+	device_sriov_wq = alloc_workqueue("qat_device_sriov_wq", 0, 0);
+	if (!device_sriov_wq) {
+		destroy_workqueue(device_reset_wq);
+		device_reset_wq = NULL;
+		return -EFAULT;
+	}
+
+	return 0;
 }
 
 void adf_exit_aer(void)
@@ -183,4 +295,8 @@
 	if (device_reset_wq)
 		destroy_workqueue(device_reset_wq);
 	device_reset_wq = NULL;
+
+	if (device_sriov_wq)
+		destroy_workqueue(device_sriov_wq);
+	device_sriov_wq = NULL;
 }
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_cfg.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_cfg.c
@@ -290,17 +290,19 @@
 	 * 3. if the key exists with the same value, then return without doing
 	 *    anything (the newly created key_val is freed).
 	 */
+	down_write(&cfg->lock);
 	if (!adf_cfg_key_val_get(accel_dev, section_name, key, temp_val)) {
 		if (strncmp(temp_val, key_val->val, sizeof(temp_val))) {
 			adf_cfg_keyval_remove(key, section);
 		} else {
 			kfree(key_val);
-			return 0;
+			goto out;
 		}
 	}
 
-	down_write(&cfg->lock);
 	adf_cfg_keyval_add(key_val, section);
+
+out:
 	up_write(&cfg->lock);
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_cfg_strings.h
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_cfg_strings.h
@@ -49,5 +49,6 @@
 	ADF_ETRMGR_BANK "%d" ADF_ETRMGR_CORE_AFFINITY
 #define ADF_ACCEL_STR "Accelerator%d"
 #define ADF_HEARTBEAT_TIMER  "HeartbeatTimer"
+#define ADF_SRIOV_ENABLED "SriovEnabled"
 
 #endif
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_clock.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_clock.c
@@ -83,6 +83,9 @@
 	}
 
 	delta_us = timespec_to_us(&ts3) - timespec_to_us(&ts1);
+	if (!delta_us)
+		return -EINVAL;
+
 	temp = (timestamp2 - timestamp1) * ME_CLK_DIVIDER * 10;
 	temp = DIV_ROUND_CLOSEST_ULL(temp, delta_us);
 	/*
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_cnv_dbgfs.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_cnv_dbgfs.c
@@ -16,7 +16,6 @@
 
 #define CNV_ERR_INFO_MASK		GENMASK(11, 0)
 #define CNV_ERR_TYPE_MASK		GENMASK(15, 12)
-#define CNV_SLICE_ERR_MASK		GENMASK(7, 0)
 #define CNV_SLICE_ERR_SIGN_BIT_INDEX	7
 #define CNV_DELTA_ERR_SIGN_BIT_INDEX	11
 
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_common_drv.h
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_common_drv.h
@@ -40,6 +40,7 @@
 	ADF_EVENT_SHUTDOWN,
 	ADF_EVENT_RESTARTING,
 	ADF_EVENT_RESTARTED,
+	ADF_EVENT_FATAL_ERROR,
 };
 
 struct service_hndl {
@@ -60,6 +61,8 @@
 
 void adf_devmgr_update_class_index(struct adf_hw_device_data *hw_data);
 void adf_clean_vf_map(bool);
+int adf_notify_fatal_error(struct adf_accel_dev *accel_dev);
+void adf_error_notifier(struct adf_accel_dev *accel_dev);
 int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev,
 		       struct adf_accel_dev *pf);
 void adf_devmgr_rm_dev(struct adf_accel_dev *accel_dev,
@@ -84,12 +87,14 @@
 extern const struct pci_error_handlers adf_err_handler;
 void adf_reset_sbr(struct adf_accel_dev *accel_dev);
 void adf_reset_flr(struct adf_accel_dev *accel_dev);
+int adf_dev_autoreset(struct adf_accel_dev *accel_dev);
 void adf_dev_restore(struct adf_accel_dev *accel_dev);
 int adf_init_aer(void);
 void adf_exit_aer(void);
 int adf_init_arb(struct adf_accel_dev *accel_dev);
 void adf_exit_arb(struct adf_accel_dev *accel_dev);
 void adf_update_ring_arb(struct adf_etr_ring_data *ring);
+int adf_disable_arb_thd(struct adf_accel_dev *accel_dev, u32 ae, u32 thr);
 
 int adf_dev_get(struct adf_accel_dev *accel_dev);
 void adf_dev_put(struct adf_accel_dev *accel_dev);
@@ -188,6 +193,7 @@
 #if defined(CONFIG_PCI_IOV)
 int adf_sriov_configure(struct pci_dev *pdev, int numvfs);
 void adf_disable_sriov(struct adf_accel_dev *accel_dev);
+void adf_reenable_sriov(struct adf_accel_dev *accel_dev);
 void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask);
 void adf_disable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev);
 bool adf_recv_and_handle_pf2vf_msg(struct adf_accel_dev *accel_dev);
@@ -208,6 +214,10 @@
 {
 }
 
+static inline void adf_reenable_sriov(struct adf_accel_dev *accel_dev)
+{
+}
+
 static inline int adf_init_pf_wq(void)
 {
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_dbgfs.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_dbgfs.c
@@ -22,18 +22,13 @@
 void adf_dbgfs_init(struct adf_accel_dev *accel_dev)
 {
 	char name[ADF_DEVICE_NAME_LENGTH];
-	void *ret;
 
 	/* Create dev top level debugfs entry */
 	snprintf(name, sizeof(name), "%s%s_%s", ADF_DEVICE_NAME_PREFIX,
 		 accel_dev->hw_device->dev_class->name,
 		 pci_name(accel_dev->accel_pci_dev.pci_dev));
 
-	ret = debugfs_create_dir(name, NULL);
-	if (IS_ERR_OR_NULL(ret))
-		return;
-
-	accel_dev->debugfs_dir = ret;
+	accel_dev->debugfs_dir = debugfs_create_dir(name, NULL);
 
 	adf_cfg_dev_dbgfs_add(accel_dev);
 }
@@ -59,9 +54,6 @@
  */
 void adf_dbgfs_add(struct adf_accel_dev *accel_dev)
 {
-	if (!accel_dev->debugfs_dir)
-		return;
-
 	if (!accel_dev->is_vf) {
 		adf_fw_counters_dbgfs_add(accel_dev);
 		adf_heartbeat_dbgfs_add(accel_dev);
@@ -77,9 +69,6 @@
  */
 void adf_dbgfs_rm(struct adf_accel_dev *accel_dev)
 {
-	if (!accel_dev->debugfs_dir)
-		return;
-
 	if (!accel_dev->is_vf) {
 		adf_tl_dbgfs_rm(accel_dev);
 		adf_cnv_dbgfs_rm(accel_dev);
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_gen2_pfvf.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_gen2_pfvf.c
@@ -100,7 +100,9 @@
 	errmsk3 |= ADF_GEN2_ERR_MSK_VF2PF(ADF_GEN2_VF_MSK);
 	ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3);
 
-	errmsk3 &= ADF_GEN2_ERR_MSK_VF2PF(sources | disabled);
+	/* Update only section of errmsk3 related to VF2PF */
+	errmsk3 &= ~ADF_GEN2_ERR_MSK_VF2PF(ADF_GEN2_VF_MSK);
+	errmsk3 |= ADF_GEN2_ERR_MSK_VF2PF(sources | disabled);
 	ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3);
 
 	/* Return the sources of the (new) interrupt(s) */
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c
@@ -398,6 +398,9 @@
 			 ADF_GEN4_ADMIN_ACCELENGINES;
 
 	if (srv_id == SVC_DCC) {
+		if (ae_cnt > ICP_QAT_HW_AE_DELIMITER)
+			return -EINVAL;
+
 		memcpy(thd2arb_map, thrd_to_arb_map_dcc,
 		       array_size(sizeof(*thd2arb_map), ae_cnt));
 		return 0;
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_gen4_ras.c
@@ -1007,8 +1007,7 @@
 static bool adf_handle_ssmcpppar_err(struct adf_accel_dev *accel_dev,
 				     void __iomem *csr, u32 iastatssm)
 {
-	u32 reg = ADF_CSR_RD(csr, ADF_GEN4_SSMCPPERR);
-	u32 bits_num = BITS_PER_REG(reg);
+	u32 reg, bits_num = BITS_PER_REG(reg);
 	bool reset_required = false;
 	unsigned long errs_bits;
 	u32 bit_iterator;
@@ -1106,8 +1105,7 @@
 static bool adf_handle_ser_err_ssmsh(struct adf_accel_dev *accel_dev,
 				     void __iomem *csr, u32 iastatssm)
 {
-	u32 reg = ADF_CSR_RD(csr, ADF_GEN4_SER_ERR_SSMSH);
-	u32 bits_num = BITS_PER_REG(reg);
+	u32 reg, bits_num = BITS_PER_REG(reg);
 	bool reset_required = false;
 	unsigned long errs_bits;
 	u32 bit_iterator;
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_gen4_tl.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_gen4_tl.c
@@ -149,5 +149,6 @@
 	tl_data->sl_exec_counters = sl_exec_counters;
 	tl_data->rp_counters = rp_counters;
 	tl_data->num_rp_counters = ARRAY_SIZE(rp_counters);
+	tl_data->max_sl_cnt = ADF_GEN4_TL_MAX_SLICES_PER_TYPE;
 }
 EXPORT_SYMBOL_GPL(adf_gen4_init_tl_data);
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_heartbeat.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_heartbeat.c
@@ -23,12 +23,6 @@
 
 #define ADF_HB_EMPTY_SIG 0xA5A5A5A5
 
-/* Heartbeat counter pair */
-struct hb_cnt_pair {
-	__u16 resp_heartbeat_cnt;
-	__u16 req_heartbeat_cnt;
-};
-
 static int adf_hb_check_polling_freq(struct adf_accel_dev *accel_dev)
 {
 	u64 curr_time = adf_clock_get_current_time();
@@ -211,6 +205,19 @@
 	return ret;
 }
 
+static void adf_heartbeat_reset(struct adf_accel_dev *accel_dev)
+{
+	u64 curr_time = adf_clock_get_current_time();
+	u64 time_since_reset = curr_time - accel_dev->heartbeat->last_hb_reset_time;
+
+	if (time_since_reset < ADF_CFG_HB_RESET_MS)
+		return;
+
+	accel_dev->heartbeat->last_hb_reset_time = curr_time;
+	if (adf_notify_fatal_error(accel_dev))
+		dev_err(&GET_DEV(accel_dev), "Failed to notify fatal error\n");
+}
+
 void adf_heartbeat_status(struct adf_accel_dev *accel_dev,
 			  enum adf_device_heartbeat_status *hb_status)
 {
@@ -235,6 +242,7 @@
 			"Heartbeat ERROR: QAT is not responding.\n");
 		*hb_status = HB_DEV_UNRESPONSIVE;
 		hb->hb_failed_counter++;
+		adf_heartbeat_reset(accel_dev);
 		return;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_heartbeat.h
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_heartbeat.h
@@ -13,17 +13,26 @@
 #define ADF_CFG_HB_TIMER_DEFAULT_MS 500
 #define ADF_CFG_HB_COUNT_THRESHOLD 3
 
+#define ADF_CFG_HB_RESET_MS 5000
+
 enum adf_device_heartbeat_status {
 	HB_DEV_UNRESPONSIVE = 0,
 	HB_DEV_ALIVE,
 	HB_DEV_UNSUPPORTED,
 };
 
+/* Heartbeat counter pair */
+struct hb_cnt_pair {
+	__u16 resp_heartbeat_cnt;
+	__u16 req_heartbeat_cnt;
+};
+
 struct adf_heartbeat {
 	unsigned int hb_sent_counter;
 	unsigned int hb_failed_counter;
 	unsigned int hb_timer;
 	u64 last_hb_check_time;
+	u64 last_hb_reset_time;
 	bool ctrs_cnt_checked;
 	struct hb_dma_addr {
 		dma_addr_t phy_addr;
@@ -35,6 +44,9 @@
 		struct dentry *cfg;
 		struct dentry *sent;
 		struct dentry *failed;
+#ifdef CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION
+		struct dentry *inject_error;
+#endif
 	} dbgfs;
 };
 
@@ -51,6 +63,15 @@
 			  enum adf_device_heartbeat_status *hb_status);
 void adf_heartbeat_check_ctrs(struct adf_accel_dev *accel_dev);
 
+#ifdef CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION
+int adf_heartbeat_inject_error(struct adf_accel_dev *accel_dev);
+#else
+static inline int adf_heartbeat_inject_error(struct adf_accel_dev *accel_dev)
+{
+	return -EPERM;
+}
+#endif
+
 #else
 static inline int adf_heartbeat_init(struct adf_accel_dev *accel_dev)
 {
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_heartbeat_dbgfs.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_heartbeat_dbgfs.c
@@ -155,6 +155,43 @@
 	.write = adf_hb_cfg_write,
 };
 
+static ssize_t adf_hb_error_inject_write(struct file *file,
+					 const char __user *user_buf,
+					 size_t count, loff_t *ppos)
+{
+	struct adf_accel_dev *accel_dev = file->private_data;
+	size_t written_chars;
+	char buf[3];
+	int ret;
+
+	/* last byte left as string termination */
+	if (count != 2)
+		return -EINVAL;
+
+	written_chars = simple_write_to_buffer(buf, sizeof(buf) - 1,
+					       ppos, user_buf, count);
+	if (buf[0] != '1')
+		return -EINVAL;
+
+	ret = adf_heartbeat_inject_error(accel_dev);
+	if (ret) {
+		dev_err(&GET_DEV(accel_dev),
+			"Heartbeat error injection failed with status %d\n",
+			ret);
+		return ret;
+	}
+
+	dev_info(&GET_DEV(accel_dev), "Heartbeat error injection enabled\n");
+
+	return written_chars;
+}
+
+static const struct file_operations adf_hb_error_inject_fops = {
+	.owner = THIS_MODULE,
+	.open = simple_open,
+	.write = adf_hb_error_inject_write,
+};
+
 void adf_heartbeat_dbgfs_add(struct adf_accel_dev *accel_dev)
 {
 	struct adf_heartbeat *hb = accel_dev->heartbeat;
@@ -171,6 +208,17 @@
 					       &hb->hb_failed_counter, &adf_hb_stats_fops);
 	hb->dbgfs.cfg = debugfs_create_file("config", 0600, hb->dbgfs.base_dir,
 					    accel_dev, &adf_hb_cfg_fops);
+
+	if (IS_ENABLED(CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION)) {
+		struct dentry *inject_error __maybe_unused;
+
+		inject_error = debugfs_create_file("inject_error", 0200,
+						   hb->dbgfs.base_dir, accel_dev,
+						   &adf_hb_error_inject_fops);
+#ifdef CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION
+		hb->dbgfs.inject_error = inject_error;
+#endif
+	}
 }
 EXPORT_SYMBOL_GPL(adf_heartbeat_dbgfs_add);
 
@@ -189,6 +237,10 @@
 	hb->dbgfs.failed = NULL;
 	debugfs_remove(hb->dbgfs.cfg);
 	hb->dbgfs.cfg = NULL;
+#ifdef CONFIG_CRYPTO_DEV_QAT_ERROR_INJECTION
+	debugfs_remove(hb->dbgfs.inject_error);
+	hb->dbgfs.inject_error = NULL;
+#endif
 	debugfs_remove(hb->dbgfs.base_dir);
 	hb->dbgfs.base_dir = NULL;
 }
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_heartbeat_inject.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_heartbeat_inject.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright(c) 2023 Intel Corporation */
+#include <linux/random.h>
+
+#include "adf_admin.h"
+#include "adf_common_drv.h"
+#include "adf_heartbeat.h"
+
+#define MAX_HB_TICKS 0xFFFFFFFF
+
+static int adf_hb_set_timer_to_max(struct adf_accel_dev *accel_dev)
+{
+	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+
+	accel_dev->heartbeat->hb_timer = 0;
+
+	if (hw_data->stop_timer)
+		hw_data->stop_timer(accel_dev);
+
+	return adf_send_admin_hb_timer(accel_dev, MAX_HB_TICKS);
+}
+
+static void adf_set_hb_counters_fail(struct adf_accel_dev *accel_dev, u32 ae,
+				     u32 thr)
+{
+	struct hb_cnt_pair *stats = accel_dev->heartbeat->dma.virt_addr;
+	struct adf_hw_device_data *hw_device = accel_dev->hw_device;
+	const size_t max_aes = hw_device->get_num_aes(hw_device);
+	const size_t hb_ctrs = hw_device->num_hb_ctrs;
+	size_t thr_id = ae * hb_ctrs + thr;
+	u16 num_rsp = stats[thr_id].resp_heartbeat_cnt;
+
+	/*
+	 * Inject live.req != live.rsp and live.rsp == last.rsp
+	 * to trigger the heartbeat error detection
+	 */
+	stats[thr_id].req_heartbeat_cnt++;
+	stats += (max_aes * hb_ctrs);
+	stats[thr_id].resp_heartbeat_cnt = num_rsp;
+}
+
+int adf_heartbeat_inject_error(struct adf_accel_dev *accel_dev)
+{
+	struct adf_hw_device_data *hw_device = accel_dev->hw_device;
+	const size_t max_aes = hw_device->get_num_aes(hw_device);
+	const size_t hb_ctrs = hw_device->num_hb_ctrs;
+	u32 rand, rand_ae, rand_thr;
+	unsigned long ae_mask;
+	int ret;
+
+	ae_mask = hw_device->ae_mask;
+
+	do {
+		/* Ensure we have a valid ae */
+		get_random_bytes(&rand, sizeof(rand));
+		rand_ae = rand % max_aes;
+	} while (!test_bit(rand_ae, &ae_mask));
+
+	get_random_bytes(&rand, sizeof(rand));
+	rand_thr = rand % hb_ctrs;
+
+	/* Increase the heartbeat timer to prevent FW updating HB counters */
+	ret = adf_hb_set_timer_to_max(accel_dev);
+	if (ret)
+		return ret;
+
+	/* Configure worker threads to stop processing any packet */
+	ret = adf_disable_arb_thd(accel_dev, rand_ae, rand_thr);
+	if (ret)
+		return ret;
+
+	/* Change HB counters memory to simulate a hang */
+	adf_set_hb_counters_fail(accel_dev, rand_ae, rand_thr);
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_hw_arbiter.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_hw_arbiter.c
@@ -90,10 +90,6 @@
 
 	hw_data->get_arb_info(&info);
 
-	/* Reset arbiter configuration */
-	for (i = 0; i < ADF_ARB_NUM; i++)
-		WRITE_CSR_ARB_SARCONFIG(csr, arb_off, i, 0);
-
 	/* Unmap worker threads to service arbiters */
 	for (i = 0; i < hw_data->num_engines; i++)
 		WRITE_CSR_ARB_WT2SAM(csr, arb_off, wt_off, i, 0);
@@ -103,3 +99,28 @@
 		csr_ops->write_csr_ring_srv_arb_en(csr, i, 0);
 }
 EXPORT_SYMBOL_GPL(adf_exit_arb);
+
+int adf_disable_arb_thd(struct adf_accel_dev *accel_dev, u32 ae, u32 thr)
+{
+	void __iomem *csr = accel_dev->transport->banks[0].csr_addr;
+	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
+	const u32 *thd_2_arb_cfg;
+	struct arb_info info;
+	u32 ae_thr_map;
+
+	if (ADF_AE_STRAND0_THREAD == thr || ADF_AE_STRAND1_THREAD == thr)
+		thr = ADF_AE_ADMIN_THREAD;
+
+	hw_data->get_arb_info(&info);
+	thd_2_arb_cfg = hw_data->get_arb_mapping(accel_dev);
+	if (!thd_2_arb_cfg)
+		return -EFAULT;
+
+	/* Disable scheduling for this particular AE and thread */
+	ae_thr_map = *(thd_2_arb_cfg + ae);
+	ae_thr_map &= ~(GENMASK(3, 0) << (thr * BIT(2)));
+
+	WRITE_CSR_ARB_WT2SAM(csr, info.arb_offset, info.wt2sam_offset, ae,
+			     ae_thr_map);
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_init.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_init.c
@@ -323,6 +323,8 @@
 	if (hw_data->stop_timer)
 		hw_data->stop_timer(accel_dev);
 
+	hw_data->disable_iov(accel_dev);
+
 	if (wait)
 		msleep(100);
 
@@ -386,8 +388,6 @@
 
 	adf_tl_shutdown(accel_dev);
 
-	hw_data->disable_iov(accel_dev);
-
 	if (test_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status)) {
 		hw_data->free_irq(accel_dev);
 		clear_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
@@ -433,6 +433,18 @@
 	return 0;
 }
 
+void adf_error_notifier(struct adf_accel_dev *accel_dev)
+{
+	struct service_hndl *service;
+
+	list_for_each_entry(service, &service_table, list) {
+		if (service->event_hld(accel_dev, ADF_EVENT_FATAL_ERROR))
+			dev_err(&GET_DEV(accel_dev),
+				"Failed to send error event to %s.\n",
+				service->name);
+	}
+}
+
 static int adf_dev_shutdown_cache_cfg(struct adf_accel_dev *accel_dev)
 {
 	char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0};
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_isr.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_isr.c
@@ -139,8 +139,13 @@
 
 	if (ras_ops->handle_interrupt &&
 	    ras_ops->handle_interrupt(accel_dev, &reset_required)) {
-		if (reset_required)
+		if (reset_required) {
 			dev_err(&GET_DEV(accel_dev), "Fatal error, reset required\n");
+			if (adf_notify_fatal_error(accel_dev))
+				dev_err(&GET_DEV(accel_dev),
+					"Failed to notify fatal error\n");
+		}
+
 		return true;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_pfvf_msg.h
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_pfvf_msg.h
@@ -99,6 +99,8 @@
 	ADF_PF2VF_MSGTYPE_RESTARTING		= 0x01,
 	ADF_PF2VF_MSGTYPE_VERSION_RESP		= 0x02,
 	ADF_PF2VF_MSGTYPE_BLKMSG_RESP		= 0x03,
+	ADF_PF2VF_MSGTYPE_FATAL_ERROR		= 0x04,
+	ADF_PF2VF_MSGTYPE_RESTARTED		= 0x05,
 /* Values from 0x10 are Gen4 specific, message type is only 4 bits in Gen2 devices. */
 	ADF_PF2VF_MSGTYPE_RP_RESET_RESP		= 0x10,
 };
@@ -112,6 +114,7 @@
 	ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ	= 0x07,
 	ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ	= 0x08,
 	ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ	= 0x09,
+	ADF_VF2PF_MSGTYPE_RESTARTING_COMPLETE	= 0x0a,
 /* Values from 0x10 are Gen4 specific, message type is only 4 bits in Gen2 devices. */
 	ADF_VF2PF_MSGTYPE_RP_RESET		= 0x10,
 };
@@ -124,8 +127,10 @@
 	ADF_PFVF_COMPAT_FAST_ACK		= 0x03,
 	/* Ring to service mapping support for non-standard mappings */
 	ADF_PFVF_COMPAT_RING_TO_SVC_MAP		= 0x04,
+	/* Fallback compat */
+	ADF_PFVF_COMPAT_FALLBACK		= 0x05,
 	/* Reference to the latest version */
-	ADF_PFVF_COMPAT_THIS_VERSION		= 0x04,
+	ADF_PFVF_COMPAT_THIS_VERSION		= 0x05,
 };
 
 /* PF->VF Version Response */
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_pfvf_pf_msg.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_pfvf_pf_msg.c
@@ -1,24 +1,89 @@
 // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
 /* Copyright(c) 2015 - 2021 Intel Corporation */
+#include <linux/delay.h>
 #include <linux/pci.h>
 #include "adf_accel_devices.h"
 #include "adf_pfvf_msg.h"
 #include "adf_pfvf_pf_msg.h"
 #include "adf_pfvf_pf_proto.h"
 
+#define ADF_PF_WAIT_RESTARTING_COMPLETE_DELAY	100
+#define ADF_VF_SHUTDOWN_RETRY			100
+
 void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev)
 {
 	struct adf_accel_vf_info *vf;
 	struct pfvf_message msg = { .type = ADF_PF2VF_MSGTYPE_RESTARTING };
 	int i, num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev));
 
+	dev_dbg(&GET_DEV(accel_dev), "pf2vf notify restarting\n");
 	for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++) {
-		if (vf->init && adf_send_pf2vf_msg(accel_dev, i, msg))
+		if (vf->init && vf->vf_compat_ver >= ADF_PFVF_COMPAT_FALLBACK)
+			vf->restarting = true;
+		else
+			vf->restarting = false;
+
+		if (!vf->init)
+			continue;
+
+		if (adf_send_pf2vf_msg(accel_dev, i, msg))
 			dev_err(&GET_DEV(accel_dev),
 				"Failed to send restarting msg to VF%d\n", i);
 	}
 }
 
+void adf_pf2vf_wait_for_restarting_complete(struct adf_accel_dev *accel_dev)
+{
+	int num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev));
+	int i, retries = ADF_VF_SHUTDOWN_RETRY;
+	struct adf_accel_vf_info *vf;
+	bool vf_running;
+
+	dev_dbg(&GET_DEV(accel_dev), "pf2vf wait for restarting complete\n");
+	do {
+		vf_running = false;
+		for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++)
+			if (vf->restarting)
+				vf_running = true;
+		if (!vf_running)
+			break;
+		msleep(ADF_PF_WAIT_RESTARTING_COMPLETE_DELAY);
+	} while (--retries);
+
+	if (vf_running)
+		dev_warn(&GET_DEV(accel_dev), "Some VFs are still running\n");
+}
+
+void adf_pf2vf_notify_restarted(struct adf_accel_dev *accel_dev)
+{
+	struct pfvf_message msg = { .type = ADF_PF2VF_MSGTYPE_RESTARTED };
+	int i, num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev));
+	struct adf_accel_vf_info *vf;
+
+	dev_dbg(&GET_DEV(accel_dev), "pf2vf notify restarted\n");
+	for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++) {
+		if (vf->init && vf->vf_compat_ver >= ADF_PFVF_COMPAT_FALLBACK &&
+		    adf_send_pf2vf_msg(accel_dev, i, msg))
+			dev_err(&GET_DEV(accel_dev),
+				"Failed to send restarted msg to VF%d\n", i);
+	}
+}
+
+void adf_pf2vf_notify_fatal_error(struct adf_accel_dev *accel_dev)
+{
+	struct pfvf_message msg = { .type = ADF_PF2VF_MSGTYPE_FATAL_ERROR };
+	int i, num_vfs = pci_num_vf(accel_to_pci_dev(accel_dev));
+	struct adf_accel_vf_info *vf;
+
+	dev_dbg(&GET_DEV(accel_dev), "pf2vf notify fatal error\n");
+	for (i = 0, vf = accel_dev->pf.vf_info; i < num_vfs; i++, vf++) {
+		if (vf->init && vf->vf_compat_ver >= ADF_PFVF_COMPAT_FALLBACK &&
+		    adf_send_pf2vf_msg(accel_dev, i, msg))
+			dev_err(&GET_DEV(accel_dev),
+				"Failed to send fatal error msg to VF%d\n", i);
+	}
+}
+
 int adf_pf_capabilities_msg_provider(struct adf_accel_dev *accel_dev,
 				     u8 *buffer, u8 compat)
 {
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_pfvf_pf_msg.h
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_pfvf_pf_msg.h
@@ -5,7 +5,28 @@
 
 #include "adf_accel_devices.h"
 
+#if defined(CONFIG_PCI_IOV)
 void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev);
+void adf_pf2vf_wait_for_restarting_complete(struct adf_accel_dev *accel_dev);
+void adf_pf2vf_notify_restarted(struct adf_accel_dev *accel_dev);
+void adf_pf2vf_notify_fatal_error(struct adf_accel_dev *accel_dev);
+#else
+static inline void adf_pf2vf_notify_restarting(struct adf_accel_dev *accel_dev)
+{
+}
+
+static inline void adf_pf2vf_wait_for_restarting_complete(struct adf_accel_dev *accel_dev)
+{
+}
+
+static inline void adf_pf2vf_notify_restarted(struct adf_accel_dev *accel_dev)
+{
+}
+
+static inline void adf_pf2vf_notify_fatal_error(struct adf_accel_dev *accel_dev)
+{
+}
+#endif
 
 typedef int (*adf_pf2vf_blkmsg_provider)(struct adf_accel_dev *accel_dev,
 					 u8 *buffer, u8 compat);
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_pfvf_pf_proto.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_pfvf_pf_proto.c
@@ -291,6 +291,14 @@
 		vf_info->init = false;
 		}
 		break;
+	case ADF_VF2PF_MSGTYPE_RESTARTING_COMPLETE:
+		{
+		dev_dbg(&GET_DEV(accel_dev),
+			"Restarting Complete received from VF%d\n", vf_nr);
+		vf_info->restarting = false;
+		vf_info->init = false;
+		}
+		break;
 	case ADF_VF2PF_MSGTYPE_LARGE_BLOCK_REQ:
 	case ADF_VF2PF_MSGTYPE_MEDIUM_BLOCK_REQ:
 	case ADF_VF2PF_MSGTYPE_SMALL_BLOCK_REQ:
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_pfvf_vf_msg.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_pfvf_vf_msg.c
@@ -48,6 +48,20 @@
 }
 EXPORT_SYMBOL_GPL(adf_vf2pf_notify_shutdown);
 
+void adf_vf2pf_notify_restart_complete(struct adf_accel_dev *accel_dev)
+{
+	struct pfvf_message msg = { .type = ADF_VF2PF_MSGTYPE_RESTARTING_COMPLETE };
+
+	/* Check compatibility version */
+	if (accel_dev->vf.pf_compat_ver < ADF_PFVF_COMPAT_FALLBACK)
+		return;
+
+	if (adf_send_vf2pf_msg(accel_dev, msg))
+		dev_err(&GET_DEV(accel_dev),
+			"Failed to send Restarting complete event to PF\n");
+}
+EXPORT_SYMBOL_GPL(adf_vf2pf_notify_restart_complete);
+
 int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev)
 {
 	u8 pf_version;
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_pfvf_vf_msg.h
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_pfvf_vf_msg.h
@@ -6,6 +6,7 @@
 #if defined(CONFIG_PCI_IOV)
 int adf_vf2pf_notify_init(struct adf_accel_dev *accel_dev);
 void adf_vf2pf_notify_shutdown(struct adf_accel_dev *accel_dev);
+void adf_vf2pf_notify_restart_complete(struct adf_accel_dev *accel_dev);
 int adf_vf2pf_request_version(struct adf_accel_dev *accel_dev);
 int adf_vf2pf_get_capabilities(struct adf_accel_dev *accel_dev);
 int adf_vf2pf_get_ring_to_svc(struct adf_accel_dev *accel_dev);
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_pfvf_vf_proto.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_pfvf_vf_proto.c
@@ -308,6 +308,12 @@
 
 		adf_pf2vf_handle_pf_restarting(accel_dev);
 		return false;
+	case ADF_PF2VF_MSGTYPE_RESTARTED:
+		dev_dbg(&GET_DEV(accel_dev), "Restarted message received from PF\n");
+		return true;
+	case ADF_PF2VF_MSGTYPE_FATAL_ERROR:
+		dev_err(&GET_DEV(accel_dev), "Fatal error received from PF\n");
+		return true;
 	case ADF_PF2VF_MSGTYPE_VERSION_RESP:
 	case ADF_PF2VF_MSGTYPE_BLKMSG_RESP:
 	case ADF_PF2VF_MSGTYPE_RP_RESET_RESP:
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_rl.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_rl.c
@@ -788,6 +788,24 @@
 	sla_type_arr[node_id] = NULL;
 }
 
+static void free_all_sla(struct adf_accel_dev *accel_dev)
+{
+	struct adf_rl *rl_data = accel_dev->rate_limiting;
+	int sla_id;
+
+	mutex_lock(&rl_data->rl_lock);
+
+	for (sla_id = 0; sla_id < RL_NODES_CNT_MAX; sla_id++) {
+		if (!rl_data->sla[sla_id])
+			continue;
+
+		kfree(rl_data->sla[sla_id]);
+		rl_data->sla[sla_id] = NULL;
+	}
+
+	mutex_unlock(&rl_data->rl_lock);
+}
+
 /**
  * add_update_sla() - handles the creation and the update of an SLA
  * @accel_dev: pointer to acceleration device structure
@@ -1088,6 +1106,7 @@
 	mutex_init(&rl->rl_lock);
 	rl->device_data = &accel_dev->hw_device->rl_data;
 	rl->accel_dev = accel_dev;
+	init_rwsem(&rl->user_input.lock);
 	accel_dev->rate_limiting = rl;
 
 err_ret:
@@ -1107,7 +1126,7 @@
 	}
 
 	if ((fw_caps & RL_CAPABILITY_MASK) != RL_CAPABILITY_VALUE) {
-		dev_info(&GET_DEV(accel_dev), "not supported\n");
+		dev_info(&GET_DEV(accel_dev), "feature not supported by FW\n");
 		ret = -EOPNOTSUPP;
 		goto ret_free;
 	}
@@ -1155,7 +1174,7 @@
 		return;
 
 	adf_sysfs_rl_rm(accel_dev);
-	adf_rl_remove_sla_all(accel_dev, true);
+	free_all_sla(accel_dev);
 }
 
 void adf_rl_exit(struct adf_accel_dev *accel_dev)
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_sriov.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_sriov.c
@@ -60,7 +60,6 @@
 		/* This ptr will be populated when VFs will be created */
 		vf_info->accel_dev = accel_dev;
 		vf_info->vf_nr = i;
-		vf_info->vf_compat_ver = 0;
 
 		mutex_init(&vf_info->pf2vf_lock);
 		ratelimit_state_init(&vf_info->vf2pf_ratelimit,
@@ -84,6 +83,32 @@
 	return pci_enable_sriov(pdev, totalvfs);
 }
 
+void adf_reenable_sriov(struct adf_accel_dev *accel_dev)
+{
+	struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
+	char cfg[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0};
+	unsigned long val = 0;
+
+	if (adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC,
+				    ADF_SRIOV_ENABLED, cfg))
+		return;
+
+	if (!accel_dev->pf.vf_info)
+		return;
+
+	if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, ADF_NUM_CY,
+					&val, ADF_DEC))
+		return;
+
+	if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, ADF_NUM_DC,
+					&val, ADF_DEC))
+		return;
+
+	set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
+	dev_dbg(&pdev->dev, "Re-enabling SRIOV\n");
+	adf_enable_sriov(accel_dev);
+}
+
 /**
  * adf_disable_sriov() - Disable SRIOV for the device
  * @accel_dev:  Pointer to accel device.
@@ -103,6 +128,7 @@
 		return;
 
 	adf_pf2vf_notify_restarting(accel_dev);
+	adf_pf2vf_wait_for_restarting_complete(accel_dev);
 	pci_disable_sriov(accel_to_pci_dev(accel_dev));
 
 	/* Disable VF to PF interrupts */
@@ -115,8 +141,10 @@
 	for (i = 0, vf = accel_dev->pf.vf_info; i < totalvfs; i++, vf++)
 		mutex_destroy(&vf->pf2vf_lock);
 
-	kfree(accel_dev->pf.vf_info);
-	accel_dev->pf.vf_info = NULL;
+	if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status)) {
+		kfree(accel_dev->pf.vf_info);
+		accel_dev->pf.vf_info = NULL;
+	}
 }
 EXPORT_SYMBOL_GPL(adf_disable_sriov);
 
@@ -194,6 +222,10 @@
 	if (ret)
 		return ret;
 
+	val = 1;
+	adf_cfg_add_key_value_param(accel_dev, ADF_GENERAL_SEC, ADF_SRIOV_ENABLED,
+				    &val, ADF_DEC);
+
 	return numvfs;
 }
 EXPORT_SYMBOL_GPL(adf_sriov_configure);
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_sysfs.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_sysfs.c
@@ -204,6 +204,42 @@
 }
 static DEVICE_ATTR_RW(pm_idle_enabled);
 
+static ssize_t auto_reset_show(struct device *dev, struct device_attribute *attr,
+			       char *buf)
+{
+	char *auto_reset;
+	struct adf_accel_dev *accel_dev;
+
+	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
+	if (!accel_dev)
+		return -EINVAL;
+
+	auto_reset = accel_dev->autoreset_on_error ? "on" : "off";
+
+	return sysfs_emit(buf, "%s\n", auto_reset);
+}
+
+static ssize_t auto_reset_store(struct device *dev, struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct adf_accel_dev *accel_dev;
+	bool enabled = false;
+	int ret;
+
+	ret = kstrtobool(buf, &enabled);
+	if (ret)
+		return ret;
+
+	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
+	if (!accel_dev)
+		return -EINVAL;
+
+	accel_dev->autoreset_on_error = enabled;
+
+	return count;
+}
+static DEVICE_ATTR_RW(auto_reset);
+
 static DEVICE_ATTR_RW(state);
 static DEVICE_ATTR_RW(cfg_services);
 
@@ -291,6 +327,7 @@
 	&dev_attr_pm_idle_enabled.attr,
 	&dev_attr_rp2srv.attr,
 	&dev_attr_num_rps.attr,
+	&dev_attr_auto_reset.attr,
 	NULL,
 };
 
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_telemetry.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_telemetry.c
@@ -41,6 +41,20 @@
 	return 0;
 }
 
+static int validate_tl_slice_counters(struct icp_qat_fw_init_admin_slice_cnt *slice_count,
+				      u8 max_slices_per_type)
+{
+	u8 *sl_counter = (u8 *)slice_count;
+	int i;
+
+	for (i = 0; i < ADF_TL_SL_CNT_COUNT; i++) {
+		if (sl_counter[i] > max_slices_per_type)
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int adf_tl_alloc_mem(struct adf_accel_dev *accel_dev)
 {
 	struct adf_tl_hw_data *tl_data = &GET_TL_DATA(accel_dev);
@@ -214,6 +228,13 @@
 		return ret;
 	}
 
+	ret = validate_tl_slice_counters(&telemetry->slice_cnt, tl_data->max_sl_cnt);
+	if (ret) {
+		dev_err(dev, "invalid value returned by FW\n");
+		adf_send_admin_tl_stop(accel_dev);
+		return ret;
+	}
+
 	telemetry->hbuffs = state;
 	atomic_set(&telemetry->state, state);
 
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_telemetry.h
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_telemetry.h
@@ -40,6 +40,7 @@
 	u8 num_dev_counters;
 	u8 num_rp_counters;
 	u8 max_rp;
+	u8 max_sl_cnt;
 };
 
 struct adf_telemetry {
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/adf_vf_isr.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/adf_vf_isr.c
@@ -13,6 +13,7 @@
 #include "adf_cfg.h"
 #include "adf_cfg_strings.h"
 #include "adf_cfg_common.h"
+#include "adf_pfvf_vf_msg.h"
 #include "adf_transport_access_macros.h"
 #include "adf_transport_internal.h"
 
@@ -75,6 +76,7 @@
 
 	/* Re-enable PF2VF interrupts */
 	adf_enable_pf2vf_interrupts(accel_dev);
+	adf_vf2pf_notify_restart_complete(accel_dev);
 	kfree(stop_data);
 }
 
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_common/qat_comp_algs.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_common/qat_comp_algs.c
@@ -13,15 +13,6 @@
 #include "qat_compression.h"
 #include "qat_algs_send.h"
 
-#define QAT_RFC_1950_HDR_SIZE 2
-#define QAT_RFC_1950_FOOTER_SIZE 4
-#define QAT_RFC_1950_CM_DEFLATE 8
-#define QAT_RFC_1950_CM_DEFLATE_CINFO_32K 7
-#define QAT_RFC_1950_CM_MASK 0x0f
-#define QAT_RFC_1950_CM_OFFSET 4
-#define QAT_RFC_1950_DICT_MASK 0x20
-#define QAT_RFC_1950_COMP_HDR 0x785e
-
 static DEFINE_MUTEX(algs_lock);
 static unsigned int active_devs;
 
--- linux-qcom-6.8.0.orig/drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
+++ linux-qcom-6.8.0/drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
@@ -192,8 +192,12 @@
 	ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3);
 	ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK5, errmsk5);
 
-	errmsk3 &= ADF_DH895XCC_ERR_MSK_VF2PF_L(sources | disabled);
-	errmsk5 &= ADF_DH895XCC_ERR_MSK_VF2PF_U(sources | disabled);
+	/* Update only section of errmsk3 and errmsk5 related to VF2PF */
+	errmsk3 &= ~ADF_DH895XCC_ERR_MSK_VF2PF_L(ADF_DH895XCC_VF_MSK);
+	errmsk5 &= ~ADF_DH895XCC_ERR_MSK_VF2PF_U(ADF_DH895XCC_VF_MSK);
+
+	errmsk3 |= ADF_DH895XCC_ERR_MSK_VF2PF_L(sources | disabled);
+	errmsk5 |= ADF_DH895XCC_ERR_MSK_VF2PF_U(sources | disabled);
 	ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK3, errmsk3);
 	ADF_CSR_WR(pmisc_addr, ADF_GEN2_ERRMSK5, errmsk5);
 
--- linux-qcom-6.8.0.orig/drivers/crypto/marvell/Kconfig
+++ linux-qcom-6.8.0/drivers/crypto/marvell/Kconfig
@@ -28,6 +28,7 @@
 	select CRYPTO_SKCIPHER
 	select CRYPTO_HASH
 	select CRYPTO_AEAD
+	select CRYPTO_AUTHENC
 	select CRYPTO_DEV_MARVELL
 	help
 		This driver allows you to utilize the Marvell Cryptographic
@@ -47,6 +48,7 @@
 	select CRYPTO_SKCIPHER
 	select CRYPTO_HASH
 	select CRYPTO_AEAD
+	select CRYPTO_AUTHENC
 	select NET_DEVLINK
 	help
 		This driver allows you to utilize the Marvell Cryptographic
--- linux-qcom-6.8.0.orig/drivers/crypto/marvell/cesa/hash.c
+++ linux-qcom-6.8.0/drivers/crypto/marvell/cesa/hash.c
@@ -947,7 +947,7 @@
 		.base = {
 			.cra_name = "md5",
 			.cra_driver_name = "mv-md5",
-			.cra_priority = 300,
+			.cra_priority = 0,
 			.cra_flags = CRYPTO_ALG_ASYNC |
 				     CRYPTO_ALG_ALLOCATES_MEMORY |
 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
@@ -1018,7 +1018,7 @@
 		.base = {
 			.cra_name = "sha1",
 			.cra_driver_name = "mv-sha1",
-			.cra_priority = 300,
+			.cra_priority = 0,
 			.cra_flags = CRYPTO_ALG_ASYNC |
 				     CRYPTO_ALG_ALLOCATES_MEMORY |
 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
@@ -1092,7 +1092,7 @@
 		.base = {
 			.cra_name = "sha256",
 			.cra_driver_name = "mv-sha256",
-			.cra_priority = 300,
+			.cra_priority = 0,
 			.cra_flags = CRYPTO_ALG_ASYNC |
 				     CRYPTO_ALG_ALLOCATES_MEMORY |
 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
@@ -1302,7 +1302,7 @@
 		.base = {
 			.cra_name = "hmac(md5)",
 			.cra_driver_name = "mv-hmac-md5",
-			.cra_priority = 300,
+			.cra_priority = 0,
 			.cra_flags = CRYPTO_ALG_ASYNC |
 				     CRYPTO_ALG_ALLOCATES_MEMORY |
 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
@@ -1373,7 +1373,7 @@
 		.base = {
 			.cra_name = "hmac(sha1)",
 			.cra_driver_name = "mv-hmac-sha1",
-			.cra_priority = 300,
+			.cra_priority = 0,
 			.cra_flags = CRYPTO_ALG_ASYNC |
 				     CRYPTO_ALG_ALLOCATES_MEMORY |
 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
@@ -1444,7 +1444,7 @@
 		.base = {
 			.cra_name = "hmac(sha256)",
 			.cra_driver_name = "mv-hmac-sha256",
-			.cra_priority = 300,
+			.cra_priority = 0,
 			.cra_flags = CRYPTO_ALG_ASYNC |
 				     CRYPTO_ALG_ALLOCATES_MEMORY |
 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
--- linux-qcom-6.8.0.orig/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c
+++ linux-qcom-6.8.0/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c
@@ -17,7 +17,6 @@
 #include <crypto/sha2.h>
 #include <crypto/xts.h>
 #include <crypto/scatterwalk.h>
-#include <linux/rtnetlink.h>
 #include <linux/sort.h>
 #include <linux/module.h>
 #include "otx_cptvf.h"
@@ -66,6 +65,8 @@
 	.count = ATOMIC_INIT(0)
 };
 
+static struct otx_cpt_sdesc *alloc_sdesc(struct crypto_shash *alg);
+
 static inline int get_se_device(struct pci_dev **pdev, int *cpu_num)
 {
 	int count, ret = 0;
@@ -509,44 +510,61 @@
 	ctx->cipher_type = cipher_type;
 	ctx->mac_type = mac_type;
 
+	switch (ctx->mac_type) {
+	case OTX_CPT_SHA1:
+		ctx->hashalg = crypto_alloc_shash("sha1", 0, 0);
+		break;
+
+	case OTX_CPT_SHA256:
+		ctx->hashalg = crypto_alloc_shash("sha256", 0, 0);
+		break;
+
+	case OTX_CPT_SHA384:
+		ctx->hashalg = crypto_alloc_shash("sha384", 0, 0);
+		break;
+
+	case OTX_CPT_SHA512:
+		ctx->hashalg = crypto_alloc_shash("sha512", 0, 0);
+		break;
+	}
+
+	if (IS_ERR(ctx->hashalg))
+		return PTR_ERR(ctx->hashalg);
+
+	crypto_aead_set_reqsize_dma(tfm, sizeof(struct otx_cpt_req_ctx));
+
+	if (!ctx->hashalg)
+		return 0;
+
 	/*
 	 * When selected cipher is NULL we use HMAC opcode instead of
 	 * FLEXICRYPTO opcode therefore we don't need to use HASH algorithms
 	 * for calculating ipad and opad
 	 */
 	if (ctx->cipher_type != OTX_CPT_CIPHER_NULL) {
-		switch (ctx->mac_type) {
-		case OTX_CPT_SHA1:
-			ctx->hashalg = crypto_alloc_shash("sha1", 0,
-							  CRYPTO_ALG_ASYNC);
-			if (IS_ERR(ctx->hashalg))
-				return PTR_ERR(ctx->hashalg);
-			break;
-
-		case OTX_CPT_SHA256:
-			ctx->hashalg = crypto_alloc_shash("sha256", 0,
-							  CRYPTO_ALG_ASYNC);
-			if (IS_ERR(ctx->hashalg))
-				return PTR_ERR(ctx->hashalg);
-			break;
-
-		case OTX_CPT_SHA384:
-			ctx->hashalg = crypto_alloc_shash("sha384", 0,
-							  CRYPTO_ALG_ASYNC);
-			if (IS_ERR(ctx->hashalg))
-				return PTR_ERR(ctx->hashalg);
-			break;
-
-		case OTX_CPT_SHA512:
-			ctx->hashalg = crypto_alloc_shash("sha512", 0,
-							  CRYPTO_ALG_ASYNC);
-			if (IS_ERR(ctx->hashalg))
-				return PTR_ERR(ctx->hashalg);
-			break;
+		int ss = crypto_shash_statesize(ctx->hashalg);
+
+		ctx->ipad = kzalloc(ss, GFP_KERNEL);
+		if (!ctx->ipad) {
+			crypto_free_shash(ctx->hashalg);
+			return -ENOMEM;
+		}
+
+		ctx->opad = kzalloc(ss, GFP_KERNEL);
+		if (!ctx->opad) {
+			kfree(ctx->ipad);
+			crypto_free_shash(ctx->hashalg);
+			return -ENOMEM;
 		}
 	}
 
-	crypto_aead_set_reqsize_dma(tfm, sizeof(struct otx_cpt_req_ctx));
+	ctx->sdesc = alloc_sdesc(ctx->hashalg);
+	if (!ctx->sdesc) {
+		kfree(ctx->opad);
+		kfree(ctx->ipad);
+		crypto_free_shash(ctx->hashalg);
+		return -ENOMEM;
+	}
 
 	return 0;
 }
@@ -602,8 +620,7 @@
 
 	kfree(ctx->ipad);
 	kfree(ctx->opad);
-	if (ctx->hashalg)
-		crypto_free_shash(ctx->hashalg);
+	crypto_free_shash(ctx->hashalg);
 	kfree(ctx->sdesc);
 }
 
@@ -699,7 +716,7 @@
 		*dst = cpu_to_be64p(src);
 }
 
-static int copy_pad(u8 mac_type, u8 *out_pad, u8 *in_pad)
+static int swap_pad(u8 mac_type, u8 *pad)
 {
 	struct sha512_state *sha512;
 	struct sha256_state *sha256;
@@ -707,22 +724,19 @@
 
 	switch (mac_type) {
 	case OTX_CPT_SHA1:
-		sha1 = (struct sha1_state *) in_pad;
+		sha1 = (struct sha1_state *)pad;
 		swap_data32(sha1->state, SHA1_DIGEST_SIZE);
-		memcpy(out_pad, &sha1->state, SHA1_DIGEST_SIZE);
 		break;
 
 	case OTX_CPT_SHA256:
-		sha256 = (struct sha256_state *) in_pad;
+		sha256 = (struct sha256_state *)pad;
 		swap_data32(sha256->state, SHA256_DIGEST_SIZE);
-		memcpy(out_pad, &sha256->state, SHA256_DIGEST_SIZE);
 		break;
 
 	case OTX_CPT_SHA384:
 	case OTX_CPT_SHA512:
-		sha512 = (struct sha512_state *) in_pad;
+		sha512 = (struct sha512_state *)pad;
 		swap_data64(sha512->state, SHA512_DIGEST_SIZE);
-		memcpy(out_pad, &sha512->state, SHA512_DIGEST_SIZE);
 		break;
 
 	default:
@@ -732,55 +746,53 @@
 	return 0;
 }
 
-static int aead_hmac_init(struct crypto_aead *cipher)
+static int aead_hmac_init(struct crypto_aead *cipher,
+			  struct crypto_authenc_keys *keys)
 {
 	struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(cipher);
-	int state_size = crypto_shash_statesize(ctx->hashalg);
 	int ds = crypto_shash_digestsize(ctx->hashalg);
 	int bs = crypto_shash_blocksize(ctx->hashalg);
-	int authkeylen = ctx->auth_key_len;
+	int authkeylen = keys->authkeylen;
 	u8 *ipad = NULL, *opad = NULL;
-	int ret = 0, icount = 0;
+	int icount = 0;
+	int ret;
 
-	ctx->sdesc = alloc_sdesc(ctx->hashalg);
-	if (!ctx->sdesc)
-		return -ENOMEM;
+	if (authkeylen > bs) {
+		ret = crypto_shash_digest(&ctx->sdesc->shash, keys->authkey,
+					  authkeylen, ctx->key);
+		if (ret)
+			return ret;
+		authkeylen = ds;
+	} else
+		memcpy(ctx->key, keys->authkey, authkeylen);
 
-	ctx->ipad = kzalloc(bs, GFP_KERNEL);
-	if (!ctx->ipad) {
-		ret = -ENOMEM;
-		goto calc_fail;
-	}
+	ctx->enc_key_len = keys->enckeylen;
+	ctx->auth_key_len = authkeylen;
 
-	ctx->opad = kzalloc(bs, GFP_KERNEL);
-	if (!ctx->opad) {
-		ret = -ENOMEM;
-		goto calc_fail;
-	}
+	if (ctx->cipher_type == OTX_CPT_CIPHER_NULL)
+		return keys->enckeylen ? -EINVAL : 0;
 
-	ipad = kzalloc(state_size, GFP_KERNEL);
-	if (!ipad) {
-		ret = -ENOMEM;
-		goto calc_fail;
+	switch (keys->enckeylen) {
+	case AES_KEYSIZE_128:
+		ctx->key_type = OTX_CPT_AES_128_BIT;
+		break;
+	case AES_KEYSIZE_192:
+		ctx->key_type = OTX_CPT_AES_192_BIT;
+		break;
+	case AES_KEYSIZE_256:
+		ctx->key_type = OTX_CPT_AES_256_BIT;
+		break;
+	default:
+		/* Invalid key length */
+		return -EINVAL;
 	}
 
-	opad = kzalloc(state_size, GFP_KERNEL);
-	if (!opad) {
-		ret = -ENOMEM;
-		goto calc_fail;
-	}
+	memcpy(ctx->key + authkeylen, keys->enckey, keys->enckeylen);
 
-	if (authkeylen > bs) {
-		ret = crypto_shash_digest(&ctx->sdesc->shash, ctx->key,
-					  authkeylen, ipad);
-		if (ret)
-			goto calc_fail;
-
-		authkeylen = ds;
-	} else {
-		memcpy(ipad, ctx->key, authkeylen);
-	}
+	ipad = ctx->ipad;
+	opad = ctx->opad;
 
+	memcpy(ipad, ctx->key, authkeylen);
 	memset(ipad + authkeylen, 0, bs - authkeylen);
 	memcpy(opad, ipad, bs);
 
@@ -798,7 +810,7 @@
 	crypto_shash_init(&ctx->sdesc->shash);
 	crypto_shash_update(&ctx->sdesc->shash, ipad, bs);
 	crypto_shash_export(&ctx->sdesc->shash, ipad);
-	ret = copy_pad(ctx->mac_type, ctx->ipad, ipad);
+	ret = swap_pad(ctx->mac_type, ipad);
 	if (ret)
 		goto calc_fail;
 
@@ -806,25 +818,9 @@
 	crypto_shash_init(&ctx->sdesc->shash);
 	crypto_shash_update(&ctx->sdesc->shash, opad, bs);
 	crypto_shash_export(&ctx->sdesc->shash, opad);
-	ret = copy_pad(ctx->mac_type, ctx->opad, opad);
-	if (ret)
-		goto calc_fail;
-
-	kfree(ipad);
-	kfree(opad);
-
-	return 0;
+	ret = swap_pad(ctx->mac_type, opad);
 
 calc_fail:
-	kfree(ctx->ipad);
-	ctx->ipad = NULL;
-	kfree(ctx->opad);
-	ctx->opad = NULL;
-	kfree(ipad);
-	kfree(opad);
-	kfree(ctx->sdesc);
-	ctx->sdesc = NULL;
-
 	return ret;
 }
 
@@ -832,57 +828,15 @@
 					   const unsigned char *key,
 					   unsigned int keylen)
 {
-	struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(cipher);
-	struct crypto_authenc_key_param *param;
-	int enckeylen = 0, authkeylen = 0;
-	struct rtattr *rta = (void *)key;
-	int status = -EINVAL;
-
-	if (!RTA_OK(rta, keylen))
-		goto badkey;
-
-	if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
-		goto badkey;
-
-	if (RTA_PAYLOAD(rta) < sizeof(*param))
-		goto badkey;
-
-	param = RTA_DATA(rta);
-	enckeylen = be32_to_cpu(param->enckeylen);
-	key += RTA_ALIGN(rta->rta_len);
-	keylen -= RTA_ALIGN(rta->rta_len);
-	if (keylen < enckeylen)
-		goto badkey;
-
-	if (keylen > OTX_CPT_MAX_KEY_SIZE)
-		goto badkey;
-
-	authkeylen = keylen - enckeylen;
-	memcpy(ctx->key, key, keylen);
-
-	switch (enckeylen) {
-	case AES_KEYSIZE_128:
-		ctx->key_type = OTX_CPT_AES_128_BIT;
-		break;
-	case AES_KEYSIZE_192:
-		ctx->key_type = OTX_CPT_AES_192_BIT;
-		break;
-	case AES_KEYSIZE_256:
-		ctx->key_type = OTX_CPT_AES_256_BIT;
-		break;
-	default:
-		/* Invalid key length */
-		goto badkey;
-	}
+	struct crypto_authenc_keys authenc_keys;
+	int status;
 
-	ctx->enc_key_len = enckeylen;
-	ctx->auth_key_len = authkeylen;
-
-	status = aead_hmac_init(cipher);
+	status = crypto_authenc_extractkeys(&authenc_keys, key, keylen);
 	if (status)
 		goto badkey;
 
-	return 0;
+	status = aead_hmac_init(cipher, &authenc_keys);
+
 badkey:
 	return status;
 }
@@ -891,36 +845,7 @@
 					    const unsigned char *key,
 					    unsigned int keylen)
 {
-	struct otx_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(cipher);
-	struct crypto_authenc_key_param *param;
-	struct rtattr *rta = (void *)key;
-	int enckeylen = 0;
-
-	if (!RTA_OK(rta, keylen))
-		goto badkey;
-
-	if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
-		goto badkey;
-
-	if (RTA_PAYLOAD(rta) < sizeof(*param))
-		goto badkey;
-
-	param = RTA_DATA(rta);
-	enckeylen = be32_to_cpu(param->enckeylen);
-	key += RTA_ALIGN(rta->rta_len);
-	keylen -= RTA_ALIGN(rta->rta_len);
-	if (enckeylen != 0)
-		goto badkey;
-
-	if (keylen > OTX_CPT_MAX_KEY_SIZE)
-		goto badkey;
-
-	memcpy(ctx->key, key, keylen);
-	ctx->enc_key_len = enckeylen;
-	ctx->auth_key_len = keylen;
-	return 0;
-badkey:
-	return -EINVAL;
+	return otx_cpt_aead_cbc_aes_sha_setkey(cipher, key, keylen);
 }
 
 static int otx_cpt_aead_gcm_aes_setkey(struct crypto_aead *cipher,
--- linux-qcom-6.8.0.orig/drivers/crypto/marvell/octeontx2/cn10k_cpt.c
+++ linux-qcom-6.8.0/drivers/crypto/marvell/octeontx2/cn10k_cpt.c
@@ -138,6 +138,10 @@
 		return -ENOMEM;
 	cptr_dma = dma_map_single(&pdev->dev, hctx, CN10K_CPT_HW_CTX_SIZE,
 				  DMA_BIDIRECTIONAL);
+	if (dma_mapping_error(&pdev->dev, cptr_dma)) {
+		kfree(hctx);
+		return -ENOMEM;
+	}
 
 	cn10k_cpt_hw_ctx_set(hctx, 1);
 	er_ctx->hw_ctx = hctx;
--- linux-qcom-6.8.0.orig/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c
+++ linux-qcom-6.8.0/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c
@@ -11,7 +11,6 @@
 #include <crypto/xts.h>
 #include <crypto/gcm.h>
 #include <crypto/scatterwalk.h>
-#include <linux/rtnetlink.h>
 #include <linux/sort.h>
 #include <linux/module.h>
 #include "otx2_cptvf.h"
@@ -55,6 +54,8 @@
 	.count = ATOMIC_INIT(0)
 };
 
+static struct otx2_cpt_sdesc *alloc_sdesc(struct crypto_shash *alg);
+
 static inline int get_se_device(struct pci_dev **pdev, int *cpu_num)
 {
 	int count;
@@ -598,40 +599,56 @@
 	ctx->cipher_type = cipher_type;
 	ctx->mac_type = mac_type;
 
+	switch (ctx->mac_type) {
+	case OTX2_CPT_SHA1:
+		ctx->hashalg = crypto_alloc_shash("sha1", 0, 0);
+		break;
+
+	case OTX2_CPT_SHA256:
+		ctx->hashalg = crypto_alloc_shash("sha256", 0, 0);
+		break;
+
+	case OTX2_CPT_SHA384:
+		ctx->hashalg = crypto_alloc_shash("sha384", 0, 0);
+		break;
+
+	case OTX2_CPT_SHA512:
+		ctx->hashalg = crypto_alloc_shash("sha512", 0, 0);
+		break;
+	}
+
+	if (IS_ERR(ctx->hashalg))
+		return PTR_ERR(ctx->hashalg);
+
+	if (ctx->hashalg) {
+		ctx->sdesc = alloc_sdesc(ctx->hashalg);
+		if (!ctx->sdesc) {
+			crypto_free_shash(ctx->hashalg);
+			return -ENOMEM;
+		}
+	}
+
 	/*
 	 * When selected cipher is NULL we use HMAC opcode instead of
 	 * FLEXICRYPTO opcode therefore we don't need to use HASH algorithms
 	 * for calculating ipad and opad
 	 */
-	if (ctx->cipher_type != OTX2_CPT_CIPHER_NULL) {
-		switch (ctx->mac_type) {
-		case OTX2_CPT_SHA1:
-			ctx->hashalg = crypto_alloc_shash("sha1", 0,
-							  CRYPTO_ALG_ASYNC);
-			if (IS_ERR(ctx->hashalg))
-				return PTR_ERR(ctx->hashalg);
-			break;
-
-		case OTX2_CPT_SHA256:
-			ctx->hashalg = crypto_alloc_shash("sha256", 0,
-							  CRYPTO_ALG_ASYNC);
-			if (IS_ERR(ctx->hashalg))
-				return PTR_ERR(ctx->hashalg);
-			break;
-
-		case OTX2_CPT_SHA384:
-			ctx->hashalg = crypto_alloc_shash("sha384", 0,
-							  CRYPTO_ALG_ASYNC);
-			if (IS_ERR(ctx->hashalg))
-				return PTR_ERR(ctx->hashalg);
-			break;
-
-		case OTX2_CPT_SHA512:
-			ctx->hashalg = crypto_alloc_shash("sha512", 0,
-							  CRYPTO_ALG_ASYNC);
-			if (IS_ERR(ctx->hashalg))
-				return PTR_ERR(ctx->hashalg);
-			break;
+	if (ctx->cipher_type != OTX2_CPT_CIPHER_NULL && ctx->hashalg) {
+		int ss = crypto_shash_statesize(ctx->hashalg);
+
+		ctx->ipad = kzalloc(ss, GFP_KERNEL);
+		if (!ctx->ipad) {
+			kfree(ctx->sdesc);
+			crypto_free_shash(ctx->hashalg);
+			return -ENOMEM;
+		}
+
+		ctx->opad = kzalloc(ss, GFP_KERNEL);
+		if (!ctx->opad) {
+			kfree(ctx->ipad);
+			kfree(ctx->sdesc);
+			crypto_free_shash(ctx->hashalg);
+			return -ENOMEM;
 		}
 	}
 	switch (ctx->cipher_type) {
@@ -713,8 +730,7 @@
 
 	kfree(ctx->ipad);
 	kfree(ctx->opad);
-	if (ctx->hashalg)
-		crypto_free_shash(ctx->hashalg);
+	crypto_free_shash(ctx->hashalg);
 	kfree(ctx->sdesc);
 
 	if (ctx->fbk_cipher) {
@@ -788,7 +804,7 @@
 		cpu_to_be64s(src);
 }
 
-static int copy_pad(u8 mac_type, u8 *out_pad, u8 *in_pad)
+static int swap_pad(u8 mac_type, u8 *pad)
 {
 	struct sha512_state *sha512;
 	struct sha256_state *sha256;
@@ -796,22 +812,19 @@
 
 	switch (mac_type) {
 	case OTX2_CPT_SHA1:
-		sha1 = (struct sha1_state *) in_pad;
+		sha1 = (struct sha1_state *)pad;
 		swap_data32(sha1->state, SHA1_DIGEST_SIZE);
-		memcpy(out_pad, &sha1->state, SHA1_DIGEST_SIZE);
 		break;
 
 	case OTX2_CPT_SHA256:
-		sha256 = (struct sha256_state *) in_pad;
+		sha256 = (struct sha256_state *)pad;
 		swap_data32(sha256->state, SHA256_DIGEST_SIZE);
-		memcpy(out_pad, &sha256->state, SHA256_DIGEST_SIZE);
 		break;
 
 	case OTX2_CPT_SHA384:
 	case OTX2_CPT_SHA512:
-		sha512 = (struct sha512_state *) in_pad;
+		sha512 = (struct sha512_state *)pad;
 		swap_data64(sha512->state, SHA512_DIGEST_SIZE);
-		memcpy(out_pad, &sha512->state, SHA512_DIGEST_SIZE);
 		break;
 
 	default:
@@ -821,55 +834,54 @@
 	return 0;
 }
 
-static int aead_hmac_init(struct crypto_aead *cipher)
+static int aead_hmac_init(struct crypto_aead *cipher,
+			  struct crypto_authenc_keys *keys)
 {
 	struct otx2_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(cipher);
-	int state_size = crypto_shash_statesize(ctx->hashalg);
 	int ds = crypto_shash_digestsize(ctx->hashalg);
 	int bs = crypto_shash_blocksize(ctx->hashalg);
-	int authkeylen = ctx->auth_key_len;
+	int authkeylen = keys->authkeylen;
 	u8 *ipad = NULL, *opad = NULL;
-	int ret = 0, icount = 0;
-
-	ctx->sdesc = alloc_sdesc(ctx->hashalg);
-	if (!ctx->sdesc)
-		return -ENOMEM;
-
-	ctx->ipad = kzalloc(bs, GFP_KERNEL);
-	if (!ctx->ipad) {
-		ret = -ENOMEM;
-		goto calc_fail;
-	}
-
-	ctx->opad = kzalloc(bs, GFP_KERNEL);
-	if (!ctx->opad) {
-		ret = -ENOMEM;
-		goto calc_fail;
-	}
-
-	ipad = kzalloc(state_size, GFP_KERNEL);
-	if (!ipad) {
-		ret = -ENOMEM;
-		goto calc_fail;
-	}
-
-	opad = kzalloc(state_size, GFP_KERNEL);
-	if (!opad) {
-		ret = -ENOMEM;
-		goto calc_fail;
-	}
+	int icount = 0;
+	int ret;
 
 	if (authkeylen > bs) {
-		ret = crypto_shash_digest(&ctx->sdesc->shash, ctx->key,
-					  authkeylen, ipad);
+		ret = crypto_shash_digest(&ctx->sdesc->shash, keys->authkey,
+					  authkeylen, ctx->key);
 		if (ret)
 			goto calc_fail;
 
 		authkeylen = ds;
-	} else {
-		memcpy(ipad, ctx->key, authkeylen);
+	} else
+		memcpy(ctx->key, keys->authkey, authkeylen);
+
+	ctx->enc_key_len = keys->enckeylen;
+	ctx->auth_key_len = authkeylen;
+
+	if (ctx->cipher_type == OTX2_CPT_CIPHER_NULL)
+		return keys->enckeylen ? -EINVAL : 0;
+
+	switch (keys->enckeylen) {
+	case AES_KEYSIZE_128:
+		ctx->key_type = OTX2_CPT_AES_128_BIT;
+		break;
+	case AES_KEYSIZE_192:
+		ctx->key_type = OTX2_CPT_AES_192_BIT;
+		break;
+	case AES_KEYSIZE_256:
+		ctx->key_type = OTX2_CPT_AES_256_BIT;
+		break;
+	default:
+		/* Invalid key length */
+		return -EINVAL;
 	}
 
+	memcpy(ctx->key + authkeylen, keys->enckey, keys->enckeylen);
+
+	ipad = ctx->ipad;
+	opad = ctx->opad;
+
+	memcpy(ipad, ctx->key, authkeylen);
 	memset(ipad + authkeylen, 0, bs - authkeylen);
 	memcpy(opad, ipad, bs);
 
@@ -887,7 +899,7 @@
 	crypto_shash_init(&ctx->sdesc->shash);
 	crypto_shash_update(&ctx->sdesc->shash, ipad, bs);
 	crypto_shash_export(&ctx->sdesc->shash, ipad);
-	ret = copy_pad(ctx->mac_type, ctx->ipad, ipad);
+	ret = swap_pad(ctx->mac_type, ipad);
 	if (ret)
 		goto calc_fail;
 
@@ -895,25 +907,9 @@
 	crypto_shash_init(&ctx->sdesc->shash);
 	crypto_shash_update(&ctx->sdesc->shash, opad, bs);
 	crypto_shash_export(&ctx->sdesc->shash, opad);
-	ret = copy_pad(ctx->mac_type, ctx->opad, opad);
-	if (ret)
-		goto calc_fail;
-
-	kfree(ipad);
-	kfree(opad);
-
-	return 0;
+	ret = swap_pad(ctx->mac_type, opad);
 
 calc_fail:
-	kfree(ctx->ipad);
-	ctx->ipad = NULL;
-	kfree(ctx->opad);
-	ctx->opad = NULL;
-	kfree(ipad);
-	kfree(opad);
-	kfree(ctx->sdesc);
-	ctx->sdesc = NULL;
-
 	return ret;
 }
 
@@ -921,87 +917,17 @@
 					    const unsigned char *key,
 					    unsigned int keylen)
 {
-	struct otx2_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(cipher);
-	struct crypto_authenc_key_param *param;
-	int enckeylen = 0, authkeylen = 0;
-	struct rtattr *rta = (void *)key;
-
-	if (!RTA_OK(rta, keylen))
-		return -EINVAL;
-
-	if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
-		return -EINVAL;
-
-	if (RTA_PAYLOAD(rta) < sizeof(*param))
-		return -EINVAL;
-
-	param = RTA_DATA(rta);
-	enckeylen = be32_to_cpu(param->enckeylen);
-	key += RTA_ALIGN(rta->rta_len);
-	keylen -= RTA_ALIGN(rta->rta_len);
-	if (keylen < enckeylen)
-		return -EINVAL;
-
-	if (keylen > OTX2_CPT_MAX_KEY_SIZE)
-		return -EINVAL;
-
-	authkeylen = keylen - enckeylen;
-	memcpy(ctx->key, key, keylen);
-
-	switch (enckeylen) {
-	case AES_KEYSIZE_128:
-		ctx->key_type = OTX2_CPT_AES_128_BIT;
-		break;
-	case AES_KEYSIZE_192:
-		ctx->key_type = OTX2_CPT_AES_192_BIT;
-		break;
-	case AES_KEYSIZE_256:
-		ctx->key_type = OTX2_CPT_AES_256_BIT;
-		break;
-	default:
-		/* Invalid key length */
-		return -EINVAL;
-	}
+	struct crypto_authenc_keys authenc_keys;
 
-	ctx->enc_key_len = enckeylen;
-	ctx->auth_key_len = authkeylen;
-
-	return aead_hmac_init(cipher);
+	return crypto_authenc_extractkeys(&authenc_keys, key, keylen) ?:
+	       aead_hmac_init(cipher, &authenc_keys);
 }
 
 static int otx2_cpt_aead_ecb_null_sha_setkey(struct crypto_aead *cipher,
 					     const unsigned char *key,
 					     unsigned int keylen)
 {
-	struct otx2_cpt_aead_ctx *ctx = crypto_aead_ctx_dma(cipher);
-	struct crypto_authenc_key_param *param;
-	struct rtattr *rta = (void *)key;
-	int enckeylen = 0;
-
-	if (!RTA_OK(rta, keylen))
-		return -EINVAL;
-
-	if (rta->rta_type != CRYPTO_AUTHENC_KEYA_PARAM)
-		return -EINVAL;
-
-	if (RTA_PAYLOAD(rta) < sizeof(*param))
-		return -EINVAL;
-
-	param = RTA_DATA(rta);
-	enckeylen = be32_to_cpu(param->enckeylen);
-	key += RTA_ALIGN(rta->rta_len);
-	keylen -= RTA_ALIGN(rta->rta_len);
-	if (enckeylen != 0)
-		return -EINVAL;
-
-	if (keylen > OTX2_CPT_MAX_KEY_SIZE)
-		return -EINVAL;
-
-	memcpy(ctx->key, key, keylen);
-	ctx->enc_key_len = enckeylen;
-	ctx->auth_key_len = keylen;
-
-	return 0;
+	return otx2_cpt_aead_cbc_aes_sha_setkey(cipher, key, keylen);
 }
 
 static int otx2_cpt_aead_gcm_aes_setkey(struct crypto_aead *cipher,
--- linux-qcom-6.8.0.orig/drivers/crypto/mxs-dcp.c
+++ linux-qcom-6.8.0/drivers/crypto/mxs-dcp.c
@@ -220,7 +220,8 @@
 static int mxs_dcp_run_aes(struct dcp_async_ctx *actx,
 			   struct skcipher_request *req, int init)
 {
-	dma_addr_t key_phys, src_phys, dst_phys;
+	dma_addr_t key_phys = 0;
+	dma_addr_t src_phys, dst_phys;
 	struct dcp *sdcp = global_sdcp;
 	struct dcp_dma_desc *desc = &sdcp->coh->desc[actx->chan];
 	struct dcp_aes_req_ctx *rctx = skcipher_request_ctx(req);
--- linux-qcom-6.8.0.orig/drivers/crypto/n2_core.c
+++ linux-qcom-6.8.0/drivers/crypto/n2_core.c
@@ -1357,6 +1357,7 @@
 	ahash->setkey = n2_hmac_async_setkey;
 
 	base = &ahash->halg.base;
+	err = -EINVAL;
 	if (snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)",
 		     p->child_alg) >= CRYPTO_MAX_ALG_NAME)
 		goto out_free_p;
--- linux-qcom-6.8.0.orig/drivers/crypto/qce/aead.c
+++ linux-qcom-6.8.0/drivers/crypto/qce/aead.c
@@ -86,6 +86,9 @@
 		}
 	}
 
+	if (qce->qce_cmd_desc_enable)
+		qce_bam_release_lock(qce);
+
 	qce->async_req_done(qce, error);
 }
 
@@ -433,6 +436,9 @@
 	else
 		rctx->assoclen = req->assoclen;
 
+	if (qce->qce_cmd_desc_enable)
+		qce_bam_acquire_lock(qce);
+
 	diff_dst = (req->src != req->dst) ? true : false;
 	dir_src = diff_dst ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
 	dir_dst = diff_dst ? DMA_FROM_DEVICE : DMA_BIDIRECTIONAL;
@@ -786,7 +792,7 @@
 	alg->init			= qce_aead_init;
 	alg->exit			= qce_aead_exit;
 
-	alg->base.cra_priority		= 300;
+	alg->base.cra_priority		= 275;
 	alg->base.cra_flags		= CRYPTO_ALG_ASYNC |
 					  CRYPTO_ALG_ALLOCATES_MEMORY |
 					  CRYPTO_ALG_KERN_DRIVER_ONLY |
--- linux-qcom-6.8.0.orig/drivers/crypto/qce/common.c
+++ linux-qcom-6.8.0/drivers/crypto/qce/common.c
@@ -25,7 +25,10 @@
 
 static inline void qce_write(struct qce_device *qce, u32 offset, u32 val)
 {
-	writel(val, qce->base + offset);
+	if (qce->qce_cmd_desc_enable)
+		qce_write_reg_dma(qce, offset, val, 1);
+	else
+		writel(val, qce->base + offset);
 }
 
 static inline void qce_write_array(struct qce_device *qce, u32 offset,
@@ -33,8 +36,12 @@
 {
 	int i;
 
-	for (i = 0; i < len; i++)
-		qce_write(qce, offset + i * sizeof(u32), val[i]);
+	for (i = 0; i < len; i++) {
+		if (qce->qce_cmd_desc_enable)
+			qce_write_reg_dma(qce, offset + i * sizeof(u32), val[i], 1);
+		else
+			qce_write(qce, offset + i * sizeof(u32), val[i]);
+	}
 }
 
 static inline void
@@ -42,8 +49,12 @@
 {
 	int i;
 
-	for (i = 0; i < len; i++)
-		qce_write(qce, offset + i * sizeof(u32), 0);
+	for (i = 0; i < len; i++) {
+		if (qce->qce_cmd_desc_enable)
+			qce_write_reg_dma(qce, offset + i * sizeof(u32), 0, 1);
+		else
+			qce_write(qce, offset + i * sizeof(u32), 0);
+	}
 }
 
 static u32 qce_config_reg(struct qce_device *qce, int little)
@@ -157,11 +168,15 @@
 	__be32 mackey[QCE_SHA_HMAC_KEY_SIZE / sizeof(__be32)] = {0};
 	u32 auth_cfg = 0, config;
 	unsigned int iv_words;
+	int ret = 0;
 
 	/* if not the last, the size has to be on the block boundary */
 	if (!rctx->last_blk && req->nbytes % blocksize)
 		return -EINVAL;
 
+	if (qce->qce_cmd_desc_enable)
+		qce_clear_bam_transaction(qce);
+
 	qce_setup_config(qce);
 
 	if (IS_CMAC(rctx->flags)) {
@@ -225,6 +240,13 @@
 
 	qce_crypto_go(qce, true);
 
+	if (qce->qce_cmd_desc_enable) {
+		ret = qce_submit_cmd_desc(qce, 0);
+		if (ret) {
+			dev_err(qce->dev, "Error in sha cmd descriptor ret = %d\n", ret);
+			return ret;
+		}
+	}
 	return 0;
 }
 #endif
@@ -325,6 +347,10 @@
 	u32 encr_cfg = 0, auth_cfg = 0, config;
 	unsigned int ivsize = rctx->ivsize;
 	unsigned long flags = rctx->flags;
+	int ret = 0;
+
+	if (qce->qce_cmd_desc_enable)
+		qce_clear_bam_transaction(qce);
 
 	qce_setup_config(qce);
 
@@ -388,6 +414,14 @@
 
 	qce_crypto_go(qce, true);
 
+	if (qce->qce_cmd_desc_enable) {
+		ret = qce_submit_cmd_desc(qce, 0);
+		if (ret) {
+			dev_err(qce->dev, "Error in skcipher cmd descriptor ret = %d\n", ret);
+			return ret;
+		}
+	}
+
 	return 0;
 }
 #endif
@@ -438,6 +472,10 @@
 	unsigned long flags = rctx->flags;
 	u32 encr_cfg, auth_cfg, config, totallen;
 	u32 iv_last_word;
+	int ret = 0;
+
+	if (qce->qce_cmd_desc_enable)
+		qce_clear_bam_transaction(qce);
 
 	qce_setup_config(qce);
 
@@ -537,6 +575,14 @@
 	/* Start the process */
 	qce_crypto_go(qce, !IS_CCM(flags));
 
+	if (qce->qce_cmd_desc_enable) {
+		ret = qce_submit_cmd_desc(qce, 0);
+		if (ret) {
+			dev_err(qce->dev, "Error in aead cmd descriptor ret = %d\n", ret);
+			return ret;
+		}
+	}
+
 	return 0;
 }
 #endif
@@ -593,3 +639,39 @@
 	*minor = (val & CORE_MINOR_REV_MASK) >> CORE_MINOR_REV_SHIFT;
 	*step = (val & CORE_STEP_REV_MASK) >> CORE_STEP_REV_SHIFT;
 }
+
+int qce_bam_acquire_lock(struct qce_device *qce)
+{
+	int ret = 0;
+
+	qce_clear_bam_transaction(qce);
+
+	/* This is just a dummy write to acquire lock bam pipe */
+	qce_write_reg_dma(qce, REG_AUTH_SEG_CFG, 0, 1);
+
+	ret = qce_submit_cmd_desc(qce, QCE_DMA_DESC_FLAG_LOCK);
+	if (ret) {
+		dev_err(qce->dev, "Error in LOCK cmd descriptor ret = %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+int qce_bam_release_lock(struct qce_device *qce)
+{
+	int ret = 0;
+
+	qce_clear_bam_transaction(qce);
+
+	/* This is just q dummy write to release lock on bam pipe*/
+	qce_write_reg_dma(qce, REG_AUTH_SEG_CFG, 0, 1);
+
+	ret = qce_submit_cmd_desc(qce, QCE_DMA_DESC_FLAG_UNLOCK);
+	if (ret) {
+		dev_err(qce->dev, "Error in LOCK cmd descriptor ret = %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/crypto/qce/core.c
+++ linux-qcom-6.8.0/drivers/crypto/qce/core.c
@@ -9,6 +9,7 @@
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
 #include <linux/types.h>
@@ -51,16 +52,19 @@
 static int qce_register_algs(struct qce_device *qce)
 {
 	const struct qce_algo_ops *ops;
-	int i, ret = -ENODEV;
+	int i, j, ret = -ENODEV;
 
 	for (i = 0; i < ARRAY_SIZE(qce_ops); i++) {
 		ops = qce_ops[i];
 		ret = ops->register_algs(qce);
-		if (ret)
-			break;
+		if (ret) {
+			for (j = i - 1; j >= 0; j--)
+				ops->unregister_algs(qce);
+			return ret;
+		}
 	}
 
-	return ret;
+	return 0;
 }
 
 static int qce_handle_request(struct crypto_async_request *async_req)
@@ -192,7 +196,8 @@
 {
 	struct device *dev = &pdev->dev;
 	struct qce_device *qce;
-	int ret;
+	struct resource *res = NULL;
+	int ret = 0;
 
 	qce = devm_kzalloc(dev, sizeof(*qce), GFP_KERNEL);
 	if (!qce)
@@ -205,6 +210,18 @@
 	if (IS_ERR(qce->base))
 		return PTR_ERR(qce->base);
 
+	if (device_property_read_bool(dev, "qce,cmd_desc_support")) {
+		qce->qce_cmd_desc_enable = true;
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+		if (!res)
+			return -EINVAL;
+		qce->base_dma = dma_map_resource(dev, res->start, resource_size(res),
+						 DMA_BIDIRECTIONAL, 0);
+		ret = dma_mapping_error(dev, qce->base_dma);
+		if (ret)
+			return ret;
+	}
+
 	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 	if (ret < 0)
 		return ret;
@@ -225,7 +242,12 @@
 	if (IS_ERR(qce->mem_path))
 		return PTR_ERR(qce->mem_path);
 
-	ret = icc_set_bw(qce->mem_path, QCE_DEFAULT_MEM_BANDWIDTH, QCE_DEFAULT_MEM_BANDWIDTH);
+	if (of_property_read_u32((&pdev->dev)->of_node, "qcom,icc_bw", &qce->icc_bw)) {
+		pr_warn("%s: No icc BW set, using default\n", __func__);
+		qce->icc_bw = QCE_DEFAULT_MEM_BANDWIDTH;
+	}
+
+	ret = icc_set_bw(qce->mem_path, qce->icc_bw, qce->icc_bw);
 	if (ret)
 		return ret;
 
@@ -247,7 +269,7 @@
 
 	ret = qce_check_version(qce);
 	if (ret)
-		goto err_clks;
+		goto err_dma;
 
 	spin_lock_init(&qce->lock);
 	tasklet_init(&qce->done_tasklet, qce_tasklet_req_done,
@@ -283,10 +305,62 @@
 
 	tasklet_kill(&qce->done_tasklet);
 	qce_unregister_algs(qce);
+	icc_set_bw(qce->mem_path, qce->icc_bw, qce->icc_bw);
 	qce_dma_release(&qce->dma);
+	icc_set_bw(qce->mem_path, 0, 0);
+	clk_disable_unprepare(qce->bus);
+	clk_disable_unprepare(qce->iface);
+	clk_disable_unprepare(qce->core);
+}
+
+static int  qce_crypto_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct qce_device *qce = platform_get_drvdata(pdev);
+
 	clk_disable_unprepare(qce->bus);
 	clk_disable_unprepare(qce->iface);
 	clk_disable_unprepare(qce->core);
+	icc_set_bw(qce->mem_path, 0, 0);
+
+	return 0;
+}
+
+static int  qce_crypto_resume(struct platform_device *pdev)
+{
+	struct qce_device *qce = platform_get_drvdata(pdev);
+	int ret = 0;
+
+	ret = icc_set_bw(qce->mem_path, qce->icc_bw, qce->icc_bw);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(qce->core);
+	if (ret)
+		goto err_mem_path_disable;
+
+	ret = clk_prepare_enable(qce->iface);
+	if (ret)
+		goto err_clks_core;
+
+	ret = clk_prepare_enable(qce->bus);
+	if (ret)
+		goto err_clks_iface;
+
+	return 0;
+
+err_clks_iface:
+	clk_disable_unprepare(qce->iface);
+err_clks_core:
+	clk_disable_unprepare(qce->core);
+err_mem_path_disable:
+	icc_set_bw(qce->mem_path, 0, 0);
+
+	return ret;
+}
+
+static void qce_crypto_shutdown(struct platform_device *pdev)
+{
+	qce_crypto_remove(pdev);
 }
 
 static const struct of_device_id qce_crypto_of_match[] = {
@@ -300,6 +374,9 @@
 static struct platform_driver qce_crypto_driver = {
 	.probe = qce_crypto_probe,
 	.remove_new = qce_crypto_remove,
+	.suspend = qce_crypto_suspend,
+	.resume = qce_crypto_resume,
+	.shutdown = qce_crypto_shutdown,
 	.driver = {
 		.name = KBUILD_MODNAME,
 		.of_match_table = qce_crypto_of_match,
--- linux-qcom-6.8.0.orig/drivers/crypto/qce/core.h
+++ linux-qcom-6.8.0/drivers/crypto/qce/core.h
@@ -42,6 +42,11 @@
 	int (*async_req_enqueue)(struct qce_device *qce,
 				 struct crypto_async_request *req);
 	void (*async_req_done)(struct qce_device *qce, int ret);
+	u32 icc_bw;
+	dma_addr_t base_dma;
+	__le32 *reg_read_buf;
+	dma_addr_t reg_buf_phys;
+	bool qce_cmd_desc_enable;
 };
 
 /**
@@ -58,4 +63,12 @@
 	int (*async_req_handle)(struct crypto_async_request *async_req);
 };
 
+int qce_write_reg_dma(struct qce_device *qce, unsigned int offset, u32 val,
+		      int cnt);
+int qce_read_reg_dma(struct qce_device *qce, unsigned int offset, void *buff,
+		     int cnt);
+void qce_clear_bam_transaction(struct qce_device *qce);
+int qce_submit_cmd_desc(struct qce_device *qce, unsigned long flags);
+int qce_bam_acquire_lock(struct qce_device *qce);
+int qce_bam_release_lock(struct qce_device *qce);
 #endif /* _CORE_H_ */
--- linux-qcom-6.8.0.orig/drivers/crypto/qce/dma.c
+++ linux-qcom-6.8.0/drivers/crypto/qce/dma.c
@@ -1,15 +1,242 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
 #include <crypto/scatterwalk.h>
 
 #include "dma.h"
+#include "core.h"
+
+#define QCE_REG_BUF_DMA_ADDR(qce, vaddr) \
+	((qce)->reg_buf_phys + \
+	 ((uint8_t *)(vaddr) - (uint8_t *)(qce)->reg_read_buf))
+
+void qce_clear_bam_transaction(struct qce_device *qce)
+{
+	struct qce_bam_transaction *qce_bam_txn = NULL;
+
+	if (qce != NULL)
+		qce_bam_txn = qce->dma.qce_bam_txn;
+	qce_bam_txn->qce_bam_ce_index = 0;
+	qce_bam_txn->qce_write_sgl_cnt = 0;
+	qce_bam_txn->qce_read_sgl_cnt = 0;
+	qce_bam_txn->qce_bam_ce_index = 0;
+	qce_bam_txn->qce_pre_bam_ce_index = 0;
+}
+
+static int qce_dma_prep_cmd_sg(struct qce_device *qce, struct dma_chan *chan,
+			       struct scatterlist *qce_bam_sgl,
+			       int qce_sgl_cnt, unsigned long flags,
+			       enum dma_transfer_direction dir,
+			       dma_async_tx_callback cb, void *cb_param)
+{
+	struct dma_async_tx_descriptor *dma_desc = NULL;
+	struct qce_desc_info *desc = NULL;
+	dma_cookie_t cookie = 0;
+
+	desc = qce->dma.qce_bam_txn->qce_desc;
+
+	if (!qce_bam_sgl || !qce_sgl_cnt)
+		return -EINVAL;
+
+	if (!dma_map_sg(qce->dev, qce_bam_sgl,
+			qce_sgl_cnt, dir)) {
+		dev_err(qce->dev, "failure in mapping sgl for cmd desc\n");
+		return -ENOMEM;
+	}
+
+	dma_desc = dmaengine_prep_slave_sg(chan, qce_bam_sgl, qce_sgl_cnt,
+					   dir, flags);
+	if (!dma_desc) {
+		pr_err("%s:failure in prep cmd desc\n", __func__);
+		dma_unmap_sg(qce->dev, qce_bam_sgl, qce_sgl_cnt, dir);
+		kfree(desc);
+		return -EINVAL;
+	}
+
+	desc->dma_desc = dma_desc;
+	desc->dma_desc->callback = cb;
+	desc->dma_desc->callback_param = cb_param;
+
+	cookie = dmaengine_submit(desc->dma_desc);
+
+	return dma_submit_error(cookie);
+}
+
+int qce_submit_cmd_desc(struct qce_device *qce, unsigned long flags)
+{
+	struct qce_bam_transaction *qce_bam_txn = NULL;
+	struct dma_chan *chan = NULL;
+	unsigned long desc_flags = 0;
+	int ret = 0;
+
+	if (qce == NULL)
+		return -EINVAL;
+
+	qce_bam_txn = qce->dma.qce_bam_txn;
+	chan = qce->dma.rxchan;
+
+	if (flags & QCE_DMA_DESC_FLAG_LOCK)
+		desc_flags = DMA_PREP_CMD | DMA_PREP_LOCK;
+	else if (flags & QCE_DMA_DESC_FLAG_UNLOCK)
+		desc_flags = DMA_PREP_CMD | DMA_PREP_UNLOCK;
+	else
+		desc_flags = DMA_PREP_CMD;
+
+	/* For command descriptor always use consumer pipe
+	 * it recomended as per HPG
+	 */
+
+	if (qce_bam_txn->qce_read_sgl_cnt) {
+		ret = qce_dma_prep_cmd_sg(qce, chan,
+					qce_bam_txn->qce_reg_read_sgl,
+					qce_bam_txn->qce_read_sgl_cnt,
+					desc_flags, DMA_DEV_TO_MEM,
+					NULL, NULL);
+		if (ret) {
+			pr_err("error while submiting cmd desc for rx ret = %d\n", ret);
+			return ret;
+		}
+	}
+
+	if (qce_bam_txn->qce_write_sgl_cnt) {
+		ret = qce_dma_prep_cmd_sg(qce, chan,
+					qce_bam_txn->qce_reg_write_sgl,
+					qce_bam_txn->qce_write_sgl_cnt,
+					desc_flags, DMA_MEM_TO_DEV,
+					NULL, NULL);
+	}
+
+	if (ret) {
+		pr_err("error while submiting cmd desc for tx ret = %d\n", ret);
+		return ret;
+	}
+
+	qce_dma_issue_pending(&qce->dma);
+	if (qce_bam_txn->qce_read_sgl_cnt)
+		dma_unmap_sg(qce->dev, qce_bam_txn->qce_reg_read_sgl,
+			     qce_bam_txn->qce_read_sgl_cnt, DMA_DEV_TO_MEM);
+	if (qce_bam_txn->qce_write_sgl_cnt)
+		dma_unmap_sg(qce->dev, qce_bam_txn->qce_reg_write_sgl,
+			     qce_bam_txn->qce_write_sgl_cnt, DMA_MEM_TO_DEV);
+	return ret;
+}
+
+static void qce_prep_dma_command_desc(struct qce_device *qce,
+				      struct qce_dma_data *dma, bool read, unsigned int addr,
+				      void *buff, int size)
+{
+	struct qce_bam_transaction *qce_bam_txn = dma->qce_bam_txn;
+	struct bam_cmd_element *qce_bam_ce_buffer = NULL;
+	int qce_bam_ce_size = 0, cnt = 0, index = 0;
+
+
+	index = qce_bam_txn->qce_bam_ce_index;
+	qce_bam_ce_buffer = &qce_bam_txn->qce_bam_ce[index];
+	if (read)
+		bam_prep_ce(qce_bam_ce_buffer, addr, BAM_READ_COMMAND,
+			    QCE_REG_BUF_DMA_ADDR(qce,
+						 (unsigned int *)buff));
+	else
+		bam_prep_ce_le32(qce_bam_ce_buffer, addr, BAM_WRITE_COMMAND,
+				 *((__le32 *)buff));
+
+	qce_bam_ce_buffer = &qce_bam_txn->qce_bam_ce
+		[qce_bam_txn->qce_pre_bam_ce_index];
+	qce_bam_txn->qce_bam_ce_index += size;
+	qce_bam_ce_size = (qce_bam_txn->qce_bam_ce_index -
+		qce_bam_txn->qce_pre_bam_ce_index) *
+		sizeof(struct bam_cmd_element);
+
+	if (read) {
+		cnt = qce_bam_txn->qce_read_sgl_cnt;
+		sg_set_buf(&qce_bam_txn->qce_reg_read_sgl[cnt],
+			  qce_bam_ce_buffer,
+			  qce_bam_ce_size);
+
+		++qce_bam_txn->qce_read_sgl_cnt;
+		qce_bam_txn->qce_pre_bam_ce_index =
+					qce_bam_txn->qce_bam_ce_index;
+	} else {
+		cnt = qce_bam_txn->qce_write_sgl_cnt;
+		sg_set_buf(&qce_bam_txn->qce_reg_write_sgl[cnt],
+			   qce_bam_ce_buffer,
+			   qce_bam_ce_size);
+
+		++qce_bam_txn->qce_write_sgl_cnt;
+		qce_bam_txn->qce_pre_bam_ce_index =
+					qce_bam_txn->qce_bam_ce_index;
+	}
+}
+
+int qce_write_reg_dma(struct qce_device *qce,
+		      unsigned int offset, u32 val, int cnt)
+{
+	void *buff =  NULL;
+	unsigned int reg_addr = 0;
+
+	buff = &val;
+
+	if (qce == NULL)
+		return -EINVAL;
+
+	reg_addr = ((unsigned int)(qce->base_dma) + offset);
+	qce_prep_dma_command_desc(qce, &qce->dma, false, reg_addr, buff, cnt);
+
+	return 0;
+}
+
+int qce_read_reg_dma(struct qce_device *qce,
+		     unsigned int offset, void *buff, int cnt)
+{
+	void *vaddr = NULL;
+	unsigned int reg_addr = 0;
+
+	if (qce == NULL)
+		return -EINVAL;
+
+	reg_addr = ((unsigned int)(qce->base_dma) + offset);
+	vaddr = qce->reg_read_buf;
+
+	qce_prep_dma_command_desc(qce, &qce->dma, true, reg_addr, vaddr, cnt);
+	memcpy(buff, vaddr, 4);
+
+	return 0;
+}
+
+static struct qce_bam_transaction *qce_alloc_bam_txn(struct qce_dma_data *dma)
+{
+	struct qce_bam_transaction *qce_bam_txn = NULL;
+
+	dma->qce_bam_txn = kmalloc(sizeof(*qce_bam_txn), GFP_KERNEL);
+	if (!dma->qce_bam_txn)
+		return NULL;
+
+	dma->qce_bam_txn->qce_desc = kzalloc(sizeof(struct qce_desc_info),
+					     GFP_KERNEL);
+	if (!dma->qce_bam_txn->qce_desc) {
+		kfree(dma->qce_bam_txn);
+		return NULL;
+	}
+
+	sg_init_table(dma->qce_bam_txn->qce_reg_write_sgl,
+		      QCE_BAM_CMD_SGL_SIZE);
+
+	sg_init_table(dma->qce_bam_txn->qce_reg_read_sgl,
+		      QCE_BAM_CMD_SGL_SIZE);
+
+	qce_bam_txn = dma->qce_bam_txn;
+
+	return qce_bam_txn;
+}
 
 int qce_dma_request(struct device *dev, struct qce_dma_data *dma)
 {
+	struct qce_device *qce = container_of(dma, struct qce_device, dma);
 	int ret;
 
 	dma->txchan = dma_request_chan(dev, "tx");
@@ -31,6 +258,24 @@
 
 	dma->ignore_buf = dma->result_buf + QCE_RESULT_BUF_SZ;
 
+	if (qce->qce_cmd_desc_enable) {
+		dma->qce_bam_txn = qce_alloc_bam_txn(dma);
+		if (!dma->qce_bam_txn) {
+			pr_err("Failed to allocate bam transaction\n");
+			ret = -ENOMEM;
+			goto error_nomem;
+		}
+
+		qce->reg_read_buf = dmam_alloc_coherent(qce->dev,
+				    QCE_MAX_REG_READ *
+				    sizeof(*qce->reg_read_buf),
+				    &qce->reg_buf_phys, GFP_KERNEL);
+		if (!qce->reg_read_buf) {
+			pr_err("Failed to allocate reg_read_buf\n");
+			ret = -ENOMEM;
+			goto error_nomem;
+		}
+	}
 	return 0;
 error_nomem:
 	dma_release_channel(dma->rxchan);
@@ -41,9 +286,21 @@
 
 void qce_dma_release(struct qce_dma_data *dma)
 {
+	struct qce_device *qce = container_of(dma,
+			struct qce_device, dma);
+
 	dma_release_channel(dma->txchan);
 	dma_release_channel(dma->rxchan);
 	kfree(dma->result_buf);
+	if (qce->qce_cmd_desc_enable) {
+		if (qce->reg_read_buf)
+			dmam_free_coherent(qce->dev, QCE_MAX_REG_READ *
+					   sizeof(*qce->reg_read_buf),
+					   qce->reg_read_buf,
+					   qce->reg_buf_phys);
+		kfree(dma->qce_bam_txn->qce_desc);
+		kfree(dma->qce_bam_txn);
+	}
 }
 
 struct scatterlist *
--- linux-qcom-6.8.0.orig/drivers/crypto/qce/dma.h
+++ linux-qcom-6.8.0/drivers/crypto/qce/dma.h
@@ -7,6 +7,7 @@
 #define _DMA_H_
 
 #include <linux/dmaengine.h>
+#include <linux/dma/qcom_bam_dma.h>
 
 /* maximum data transfer block size between BAM and CE */
 #define QCE_BAM_BURST_SIZE		64
@@ -14,6 +15,12 @@
 #define QCE_AUTHIV_REGS_CNT		16
 #define QCE_AUTH_BYTECOUNT_REGS_CNT	4
 #define QCE_CNTRIV_REGS_CNT		4
+#define QCE_BAM_CMD_SGL_SIZE           128
+#define QCE_BAM_CMD_ELEMENT_SIZE       128
+#define QCE_DMA_DESC_FLAG_BAM_NWD      (0x0004)
+#define QCE_MAX_REG_READ               8
+#define QCE_DMA_DESC_FLAG_LOCK          (0x0002)
+#define QCE_DMA_DESC_FLAG_UNLOCK        (0x0001)
 
 struct qce_result_dump {
 	u32 auth_iv[QCE_AUTHIV_REGS_CNT];
@@ -27,11 +34,28 @@
 #define QCE_RESULT_BUF_SZ	\
 		ALIGN(sizeof(struct qce_result_dump), QCE_BAM_BURST_SIZE)
 
+struct qce_bam_transaction {
+	struct bam_cmd_element qce_bam_ce[QCE_BAM_CMD_ELEMENT_SIZE];
+	struct scatterlist qce_reg_write_sgl[QCE_BAM_CMD_SGL_SIZE];
+	struct scatterlist qce_reg_read_sgl[QCE_BAM_CMD_SGL_SIZE];
+	struct qce_desc_info *qce_desc;
+	u32 qce_bam_ce_index;
+	u32 qce_pre_bam_ce_index;
+	u32 qce_write_sgl_cnt;
+	u32 qce_read_sgl_cnt;
+};
+
 struct qce_dma_data {
 	struct dma_chan *txchan;
 	struct dma_chan *rxchan;
 	struct qce_result_dump *result_buf;
 	void *ignore_buf;
+	struct qce_bam_transaction *qce_bam_txn;
+};
+
+struct qce_desc_info {
+	struct dma_async_tx_descriptor *dma_desc;
+	enum dma_data_direction dir;
 };
 
 int qce_dma_request(struct device *dev, struct qce_dma_data *dma);
@@ -44,5 +68,5 @@
 struct scatterlist *
 qce_sgtable_add(struct sg_table *sgt, struct scatterlist *sg_add,
 		unsigned int max_len);
-
+void qce_dma_issue_cmd_desc_pending(struct qce_dma_data *dma, bool read);
 #endif /* _DMA_H_ */
--- linux-qcom-6.8.0.orig/drivers/crypto/qce/sha.c
+++ linux-qcom-6.8.0/drivers/crypto/qce/sha.c
@@ -69,6 +69,9 @@
 	rctx->last_blk = false;
 	rctx->first_blk = false;
 
+	if (qce->qce_cmd_desc_enable)
+		qce_bam_release_lock(qce);
+
 	qce->async_req_done(tmpl->qce, error);
 }
 
@@ -90,6 +93,9 @@
 		rctx->authklen = AES_KEYSIZE_128;
 	}
 
+	if (qce->qce_cmd_desc_enable)
+		qce_bam_acquire_lock(qce);
+
 	rctx->src_nents = sg_nents_for_len(req->src, req->nbytes);
 	if (rctx->src_nents < 0) {
 		dev_err(qce->dev, "Invalid numbers of src SG.\n");
@@ -482,7 +488,7 @@
 
 	base = &alg->halg.base;
 	base->cra_blocksize = def->blocksize;
-	base->cra_priority = 300;
+	base->cra_priority = 175;
 	base->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
 	base->cra_ctxsize = sizeof(struct qce_sha_ctx);
 	base->cra_alignmask = 0;
--- linux-qcom-6.8.0.orig/drivers/crypto/qce/skcipher.c
+++ linux-qcom-6.8.0/drivers/crypto/qce/skcipher.c
@@ -56,6 +56,9 @@
 	if (error < 0)
 		dev_dbg(qce->dev, "skcipher operation error (%x)\n", status);
 
+	if (qce->qce_cmd_desc_enable)
+		qce_bam_release_lock(qce);
+
 	memcpy(rctx->iv, result_buf->encr_cntr_iv, rctx->ivsize);
 	qce->async_req_done(tmpl->qce, error);
 }
@@ -82,6 +85,9 @@
 	dir_src = diff_dst ? DMA_TO_DEVICE : DMA_BIDIRECTIONAL;
 	dir_dst = diff_dst ? DMA_FROM_DEVICE : DMA_BIDIRECTIONAL;
 
+	if (qce->qce_cmd_desc_enable)
+		qce_bam_acquire_lock(qce);
+
 	rctx->src_nents = sg_nents_for_len(req->src, req->cryptlen);
 	if (diff_dst)
 		rctx->dst_nents = sg_nents_for_len(req->dst, req->cryptlen);
@@ -461,7 +467,7 @@
 	alg->encrypt			= qce_skcipher_encrypt;
 	alg->decrypt			= qce_skcipher_decrypt;
 
-	alg->base.cra_priority		= 300;
+	alg->base.cra_priority		= 275;
 	alg->base.cra_flags		= CRYPTO_ALG_ASYNC |
 					  CRYPTO_ALG_ALLOCATES_MEMORY |
 					  CRYPTO_ALG_KERN_DRIVER_ONLY;
--- linux-qcom-6.8.0.orig/drivers/crypto/qcom-rng.c
+++ linux-qcom-6.8.0/drivers/crypto/qcom-rng.c
@@ -196,7 +196,7 @@
 	if (IS_ERR(rng->clk))
 		return PTR_ERR(rng->clk);
 
-	rng->of_data = (struct qcom_rng_of_data *)of_device_get_match_data(&pdev->dev);
+	rng->of_data = (struct qcom_rng_of_data *)device_get_match_data(&pdev->dev);
 
 	qcom_rng_dev = rng;
 	ret = crypto_register_rng(&qcom_rng_alg);
@@ -247,7 +247,7 @@
 };
 
 static const struct acpi_device_id __maybe_unused qcom_rng_acpi_match[] = {
-	{ .id = "QCOM8160", .driver_data = 1 },
+	{ .id = "QCOM8160", .driver_data = (kernel_ulong_t)&qcom_prng_ee_of_data },
 	{}
 };
 MODULE_DEVICE_TABLE(acpi, qcom_rng_acpi_match);
--- linux-qcom-6.8.0.orig/drivers/crypto/starfive/jh7110-cryp.h
+++ linux-qcom-6.8.0/drivers/crypto/starfive/jh7110-cryp.h
@@ -30,6 +30,7 @@
 #define MAX_KEY_SIZE				SHA512_BLOCK_SIZE
 #define STARFIVE_AES_IV_LEN			AES_BLOCK_SIZE
 #define STARFIVE_AES_CTR_LEN			AES_BLOCK_SIZE
+#define STARFIVE_RSA_MAX_KEYSZ			256
 
 union starfive_aes_csr {
 	u32 v;
@@ -218,12 +219,11 @@
 	struct scatterlist			*out_sg;
 	struct ahash_request			ahash_fbk_req;
 	size_t					total;
-	size_t					nents;
 	unsigned int				blksize;
 	unsigned int				digsize;
 	unsigned long				in_sg_len;
 	unsigned char				*adata;
-	u8 rsa_data[] __aligned(sizeof(u32));
+	u8 rsa_data[STARFIVE_RSA_MAX_KEYSZ] __aligned(sizeof(u32));
 };
 
 struct starfive_cryp_dev *starfive_cryp_find_dev(struct starfive_cryp_ctx *ctx);
--- linux-qcom-6.8.0.orig/drivers/crypto/starfive/jh7110-rsa.c
+++ linux-qcom-6.8.0/drivers/crypto/starfive/jh7110-rsa.c
@@ -31,7 +31,6 @@
 /* A * A * R mod N ==> A */
 #define CRYPTO_CMD_AARN			0x7
 
-#define STARFIVE_RSA_MAX_KEYSZ		256
 #define STARFIVE_RSA_RESET		0x2
 
 static inline int starfive_pka_wait_done(struct starfive_cryp_ctx *ctx)
@@ -71,7 +70,7 @@
 {
 	struct starfive_cryp_dev *cryp = ctx->cryp;
 	struct starfive_cryp_request_ctx *rctx = ctx->rctx;
-	int count = rctx->total / sizeof(u32) - 1;
+	int count = (ALIGN(rctx->total, 4) / 4) - 1;
 	int loop;
 	u32 temp;
 	u8 opsize;
@@ -248,12 +247,17 @@
 	struct starfive_cryp_dev *cryp = ctx->cryp;
 	struct starfive_cryp_request_ctx *rctx = ctx->rctx;
 	struct starfive_rsa_key *key = &ctx->rsa_key;
-	int ret = 0;
+	int ret = 0, shift = 0;
 
 	writel(STARFIVE_RSA_RESET, cryp->base + STARFIVE_PKA_CACR_OFFSET);
 
-	rctx->total = sg_copy_to_buffer(rctx->in_sg, rctx->nents,
-					rctx->rsa_data, rctx->total);
+	if (!IS_ALIGNED(rctx->total, sizeof(u32))) {
+		shift = sizeof(u32) - (rctx->total & 0x3);
+		memset(rctx->rsa_data, 0, shift);
+	}
+
+	rctx->total = sg_copy_to_buffer(rctx->in_sg, sg_nents(rctx->in_sg),
+					rctx->rsa_data + shift, rctx->total);
 
 	if (enc) {
 		key->bitlen = key->e_bitlen;
@@ -273,7 +277,6 @@
 
 err_rsa_crypt:
 	writel(STARFIVE_RSA_RESET, cryp->base + STARFIVE_PKA_CACR_OFFSET);
-	kfree(rctx->rsa_data);
 	return ret;
 }
 
@@ -303,7 +306,6 @@
 	rctx->in_sg = req->src;
 	rctx->out_sg = req->dst;
 	rctx->total = req->src_len;
-	rctx->nents = sg_nents(rctx->in_sg);
 	ctx->rctx = rctx;
 
 	return starfive_rsa_enc_core(ctx, 1);
--- linux-qcom-6.8.0.orig/drivers/crypto/stm32/stm32-cryp.c
+++ linux-qcom-6.8.0/drivers/crypto/stm32/stm32-cryp.c
@@ -11,6 +11,7 @@
 #include <crypto/internal/des.h>
 #include <crypto/internal/skcipher.h>
 #include <crypto/scatterwalk.h>
+#include <linux/bottom_half.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/err.h>
@@ -1665,8 +1666,11 @@
 		it_mask &= ~IMSCR_OUT;
 	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);
+		local_bh_enable();
+	}
 
 	return IRQ_HANDLED;
 }
--- linux-qcom-6.8.0.orig/drivers/crypto/xilinx/zynqmp-aes-gcm.c
+++ linux-qcom-6.8.0/drivers/crypto/xilinx/zynqmp-aes-gcm.c
@@ -231,7 +231,10 @@
 		err = zynqmp_aes_aead_cipher(areq);
 	}
 
+	local_bh_disable();
 	crypto_finalize_aead_request(engine, areq, err);
+	local_bh_enable();
+
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/cxl/Kconfig
+++ linux-qcom-6.8.0/drivers/cxl/Kconfig
@@ -59,6 +59,7 @@
 	default CXL_BUS
 	select ACPI_TABLE_LIB
 	select ACPI_HMAT
+	select CXL_PORT
 	help
 	  Enable support for host managed device memory (HDM) resources
 	  published by a platform's ACPI CXL memory layout description.  See
--- linux-qcom-6.8.0.orig/drivers/cxl/Makefile
+++ linux-qcom-6.8.0/drivers/cxl/Makefile
@@ -1,13 +1,21 @@
 # SPDX-License-Identifier: GPL-2.0
+
+# Order is important here for the built-in case:
+# - 'core' first for fundamental init
+# - 'port' before platform root drivers like 'acpi' so that CXL-root ports
+#   are immediately enabled
+# - 'mem' and 'pmem' before endpoint drivers so that memdevs are
+#   immediately enabled
+# - 'pci' last, also mirrors the hardware enumeration hierarchy
 obj-y += core/
-obj-$(CONFIG_CXL_PCI) += cxl_pci.o
-obj-$(CONFIG_CXL_MEM) += cxl_mem.o
+obj-$(CONFIG_CXL_PORT) += cxl_port.o
 obj-$(CONFIG_CXL_ACPI) += cxl_acpi.o
 obj-$(CONFIG_CXL_PMEM) += cxl_pmem.o
-obj-$(CONFIG_CXL_PORT) += cxl_port.o
+obj-$(CONFIG_CXL_MEM) += cxl_mem.o
+obj-$(CONFIG_CXL_PCI) += cxl_pci.o
 
-cxl_mem-y := mem.o
-cxl_pci-y := pci.o
+cxl_port-y := port.o
 cxl_acpi-y := acpi.o
 cxl_pmem-y := pmem.o security.o
-cxl_port-y := port.o
+cxl_mem-y := mem.o
+cxl_pci-y := pci.o
--- linux-qcom-6.8.0.orig/drivers/cxl/acpi.c
+++ linux-qcom-6.8.0/drivers/cxl/acpi.c
@@ -74,6 +74,43 @@
 	return cxlrd->cxlsd.target[n];
 }
 
+static u64 cxl_xor_hpa_to_spa(struct cxl_root_decoder *cxlrd, u64 hpa)
+{
+	struct cxl_cxims_data *cximsd = cxlrd->platform_data;
+	int hbiw = cxlrd->cxlsd.nr_targets;
+	u64 val;
+	int pos;
+
+	/* No xormaps for host bridge interleave ways of 1 or 3 */
+	if (hbiw == 1 || hbiw == 3)
+		return hpa;
+
+	/*
+	 * For root decoders using xormaps (hbiw: 2,4,6,8,12,16) restore
+	 * the position bit to its value before the xormap was applied at
+	 * HPA->DPA translation.
+	 *
+	 * pos is the lowest set bit in an XORMAP
+	 * val is the XORALLBITS(HPA & XORMAP)
+	 *
+	 * XORALLBITS: The CXL spec (3.1 Table 9-22) defines XORALLBITS
+	 * as an operation that outputs a single bit by XORing all the
+	 * bits in the input (hpa & xormap). Implement XORALLBITS using
+	 * hweight64(). If the hamming weight is even the XOR of those
+	 * bits results in val==0, if odd the XOR result is val==1.
+	 */
+
+	for (int i = 0; i < cximsd->nr_maps; i++) {
+		if (!cximsd->xormaps[i])
+			continue;
+		pos = __ffs(cximsd->xormaps[i]);
+		val = (hweight64(hpa & cximsd->xormaps[i]) & 1);
+		hpa = (hpa & ~(1ULL << pos)) | (val << pos);
+	}
+
+	return hpa;
+}
+
 struct cxl_cxims_context {
 	struct device *dev;
 	struct cxl_root_decoder *cxlrd;
@@ -410,6 +447,9 @@
 
 	cxlrd->qos_class = cfmws->qtg_id;
 
+	if (cfmws->interleave_arithmetic == ACPI_CEDT_CFMWS_ARITHMETIC_XOR)
+		cxlrd->hpa_to_spa = cxl_xor_hpa_to_spa;
+
 	rc = cxl_decoder_add(cxld, target_map);
 err_xormap:
 	if (rc)
@@ -530,13 +570,15 @@
 	if (kstrtou32(acpi_device_uid(hb), 0, &uid))
 		return -EINVAL;
 
-	rc = acpi_get_genport_coordinates(uid, &dport->hb_coord);
+	rc = acpi_get_genport_coordinates(uid, dport->hb_coord);
 	if (rc < 0)
 		return rc;
 
 	/* Adjust back to picoseconds from nanoseconds */
-	dport->hb_coord.read_latency *= 1000;
-	dport->hb_coord.write_latency *= 1000;
+	for (int i = 0; i < ACCESS_COORDINATE_MAX; i++) {
+		dport->hb_coord[i].read_latency *= 1000;
+		dport->hb_coord[i].write_latency *= 1000;
+	}
 
 	return 0;
 }
@@ -920,6 +962,13 @@
 
 /* load before dax_hmem sees 'Soft Reserved' CXL ranges */
 subsys_initcall(cxl_acpi_init);
+
+/*
+ * Arrange for host-bridge ports to be active synchronous with
+ * cxl_acpi_probe() exit.
+ */
+MODULE_SOFTDEP("pre: cxl_port");
+
 module_exit(cxl_acpi_exit);
 MODULE_LICENSE("GPL v2");
 MODULE_IMPORT_NS(CXL);
--- linux-qcom-6.8.0.orig/drivers/cxl/core/cdat.c
+++ linux-qcom-6.8.0/drivers/cxl/core/cdat.c
@@ -162,15 +162,22 @@
 static int cxl_port_perf_data_calculate(struct cxl_port *port,
 					struct xarray *dsmas_xa)
 {
-	struct access_coordinate c;
+	struct access_coordinate ep_c;
+	struct access_coordinate coord[ACCESS_COORDINATE_MAX];
 	struct dsmas_entry *dent;
 	int valid_entries = 0;
 	unsigned long index;
 	int rc;
 
-	rc = cxl_endpoint_get_perf_coordinates(port, &c);
+	rc = cxl_endpoint_get_perf_coordinates(port, &ep_c);
 	if (rc) {
-		dev_dbg(&port->dev, "Failed to retrieve perf coordinates.\n");
+		dev_dbg(&port->dev, "Failed to retrieve ep perf coordinates.\n");
+		return rc;
+	}
+
+	rc = cxl_hb_get_perf_coordinates(port, coord);
+	if (rc)  {
+		dev_dbg(&port->dev, "Failed to retrieve hb perf coordinates.\n");
 		return rc;
 	}
 
@@ -185,18 +192,19 @@
 	xa_for_each(dsmas_xa, index, dent) {
 		int qos_class;
 
-		dent->coord.read_latency = dent->coord.read_latency +
-					   c.read_latency;
-		dent->coord.write_latency = dent->coord.write_latency +
-					    c.write_latency;
-		dent->coord.read_bandwidth = min_t(int, c.read_bandwidth,
-						   dent->coord.read_bandwidth);
-		dent->coord.write_bandwidth = min_t(int, c.write_bandwidth,
-						    dent->coord.write_bandwidth);
-
+		cxl_coordinates_combine(&dent->coord, &dent->coord, &ep_c);
+		/*
+		 * Keeping the host bridge coordinates separate from the dsmas
+		 * coordinates in order to allow calculation of access class
+		 * 0 and 1 for region later.
+		 */
+		cxl_coordinates_combine(&coord[ACCESS_COORDINATE_LOCAL],
+					&coord[ACCESS_COORDINATE_LOCAL],
+					&dent->coord);
 		dent->entries = 1;
-		rc = cxl_root->ops->qos_class(cxl_root, &dent->coord, 1,
-					      &qos_class);
+		rc = cxl_root->ops->qos_class(cxl_root,
+					      &coord[ACCESS_COORDINATE_LOCAL],
+					      1, &qos_class);
 		if (rc != 1)
 			continue;
 
@@ -389,36 +397,38 @@
 static int cdat_sslbis_handler(union acpi_subtable_headers *header, void *arg,
 			       const unsigned long end)
 {
+	struct acpi_cdat_sslbis_table {
+		struct acpi_cdat_header header;
+		struct acpi_cdat_sslbis sslbis_header;
+		struct acpi_cdat_sslbe entries[];
+	} *tbl = (struct acpi_cdat_sslbis_table *)header;
+	int size = sizeof(header->cdat) + sizeof(tbl->sslbis_header);
 	struct acpi_cdat_sslbis *sslbis;
-	int size = sizeof(header->cdat) + sizeof(*sslbis);
 	struct cxl_port *port = arg;
 	struct device *dev = &port->dev;
-	struct acpi_cdat_sslbe *entry;
 	int remain, entries, i;
 	u16 len;
 
 	len = le16_to_cpu((__force __le16)header->cdat.length);
 	remain = len - size;
-	if (!remain || remain % sizeof(*entry) ||
+	if (!remain || remain % sizeof(tbl->entries[0]) ||
 	    (unsigned long)header + len > end) {
 		dev_warn(dev, "Malformed SSLBIS table length: (%u)\n", len);
 		return -EINVAL;
 	}
 
-	/* Skip common header */
-	sslbis = (struct acpi_cdat_sslbis *)((unsigned long)header +
-					     sizeof(header->cdat));
-
+	sslbis = &tbl->sslbis_header;
 	/* Unrecognized data type, we can skip */
 	if (sslbis->data_type > ACPI_HMAT_WRITE_BANDWIDTH)
 		return 0;
 
-	entries = remain / sizeof(*entry);
-	entry = (struct acpi_cdat_sslbe *)((unsigned long)header + sizeof(*sslbis));
+	entries = remain / sizeof(tbl->entries[0]);
+	if (struct_size(tbl, entries, entries) != len)
+		return -EINVAL;
 
 	for (i = 0; i < entries; i++) {
-		u16 x = le16_to_cpu((__force __le16)entry->portx_id);
-		u16 y = le16_to_cpu((__force __le16)entry->porty_id);
+		u16 x = le16_to_cpu((__force __le16)tbl->entries[i].portx_id);
+		u16 y = le16_to_cpu((__force __le16)tbl->entries[i].porty_id);
 		__le64 le_base;
 		__le16 le_val;
 		struct cxl_dport *dport;
@@ -448,8 +458,8 @@
 			break;
 		}
 
-		le_base = (__force __le64)sslbis->entry_base_unit;
-		le_val = (__force __le16)entry->latency_or_bandwidth;
+		le_base = (__force __le64)tbl->sslbis_header.entry_base_unit;
+		le_val = (__force __le16)tbl->entries[i].latency_or_bandwidth;
 
 		if (check_mul_overflow(le64_to_cpu(le_base),
 				       le16_to_cpu(le_val), &val))
@@ -462,8 +472,6 @@
 							  sslbis->data_type,
 							  val);
 		}
-
-		entry++;
 	}
 
 	return 0;
@@ -484,4 +492,26 @@
 }
 EXPORT_SYMBOL_NS_GPL(cxl_switch_parse_cdat, CXL);
 
+/**
+ * cxl_coordinates_combine - Combine the two input coordinates
+ *
+ * @out: Output coordinate of c1 and c2 combined
+ * @c1: input coordinates
+ * @c2: input coordinates
+ */
+void cxl_coordinates_combine(struct access_coordinate *out,
+			     struct access_coordinate *c1,
+			     struct access_coordinate *c2)
+{
+		if (c1->write_bandwidth && c2->write_bandwidth)
+			out->write_bandwidth = min(c1->write_bandwidth,
+						   c2->write_bandwidth);
+		out->write_latency = c1->write_latency + c2->write_latency;
+
+		if (c1->read_bandwidth && c2->read_bandwidth)
+			out->read_bandwidth = min(c1->read_bandwidth,
+						  c2->read_bandwidth);
+		out->read_latency = c1->read_latency + c2->read_latency;
+}
+
 MODULE_IMPORT_NS(CXL);
--- linux-qcom-6.8.0.orig/drivers/cxl/core/core.h
+++ linux-qcom-6.8.0/drivers/cxl/core/core.h
@@ -27,7 +27,14 @@
 int cxl_region_init(void);
 void cxl_region_exit(void);
 int cxl_get_poison_by_endpoint(struct cxl_port *port);
+struct cxl_region *cxl_dpa_to_region(const struct cxl_memdev *cxlmd, u64 dpa);
+
 #else
+static inline
+struct cxl_region *cxl_dpa_to_region(const struct cxl_memdev *cxlmd, u64 dpa)
+{
+	return NULL;
+}
 static inline int cxl_get_poison_by_endpoint(struct cxl_port *port)
 {
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/cxl/core/hdm.c
+++ linux-qcom-6.8.0/drivers/cxl/core/hdm.c
@@ -52,6 +52,14 @@
 	struct cxl_dport *dport = NULL;
 	int single_port_map[1];
 	unsigned long index;
+	struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev);
+
+	/*
+	 * Capability checks are moot for passthrough decoders, support
+	 * any and all possibilities.
+	 */
+	cxlhdm->interleave_mask = ~0U;
+	cxlhdm->iw_cap_mask = ~0UL;
 
 	cxlsd = cxl_switch_decoder_alloc(port, 1);
 	if (IS_ERR(cxlsd))
@@ -79,6 +87,11 @@
 		cxlhdm->interleave_mask |= GENMASK(11, 8);
 	if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_14_12, hdm_cap))
 		cxlhdm->interleave_mask |= GENMASK(14, 12);
+	cxlhdm->iw_cap_mask = BIT(1) | BIT(2) | BIT(4) | BIT(8);
+	if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_3_6_12_WAY, hdm_cap))
+		cxlhdm->iw_cap_mask |= BIT(3) | BIT(6) | BIT(12);
+	if (FIELD_GET(CXL_HDM_DECODER_INTERLEAVE_16_WAY, hdm_cap))
+		cxlhdm->iw_cap_mask |= BIT(16);
 }
 
 static bool should_emulate_decoders(struct cxl_endpoint_dvsec_info *info)
@@ -700,7 +713,44 @@
 	return 0;
 }
 
-static int cxl_decoder_reset(struct cxl_decoder *cxld)
+static int commit_reap(struct device *dev, const void *data)
+{
+	struct cxl_port *port = to_cxl_port(dev->parent);
+	struct cxl_decoder *cxld;
+
+	if (!is_switch_decoder(dev) && !is_endpoint_decoder(dev))
+		return 0;
+
+	cxld = to_cxl_decoder(dev);
+	if (port->commit_end == cxld->id &&
+	    ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)) {
+		port->commit_end--;
+		dev_dbg(&port->dev, "reap: %s commit_end: %d\n",
+			dev_name(&cxld->dev), port->commit_end);
+	}
+
+	return 0;
+}
+
+void cxl_port_commit_reap(struct cxl_decoder *cxld)
+{
+	struct cxl_port *port = to_cxl_port(cxld->dev.parent);
+
+	lockdep_assert_held_write(&cxl_region_rwsem);
+
+	/*
+	 * Once the highest committed decoder is disabled, free any other
+	 * decoders that were pinned allocated by out-of-order release.
+	 */
+	port->commit_end--;
+	dev_dbg(&port->dev, "reap: %s commit_end: %d\n", dev_name(&cxld->dev),
+		port->commit_end);
+	device_for_each_child_reverse_from(&port->dev, &cxld->dev, NULL,
+					   commit_reap);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_port_commit_reap, CXL);
+
+static void cxl_decoder_reset(struct cxl_decoder *cxld)
 {
 	struct cxl_port *port = to_cxl_port(cxld->dev.parent);
 	struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev);
@@ -709,14 +759,14 @@
 	u32 ctrl;
 
 	if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)
-		return 0;
+		return;
 
-	if (port->commit_end != id) {
+	if (port->commit_end == id)
+		cxl_port_commit_reap(cxld);
+	else
 		dev_dbg(&port->dev,
 			"%s: out of order reset, expected decoder%d.%d\n",
 			dev_name(&cxld->dev), port->id, port->commit_end);
-		return -EBUSY;
-	}
 
 	down_read(&cxl_dpa_rwsem);
 	ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id));
@@ -729,7 +779,6 @@
 	writel(0, hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(id));
 	up_read(&cxl_dpa_rwsem);
 
-	port->commit_end--;
 	cxld->flags &= ~CXL_DECODER_F_ENABLE;
 
 	/* Userspace is now responsible for reconfiguring this decoder */
@@ -739,8 +788,6 @@
 		cxled = to_cxl_endpoint_decoder(&cxld->dev);
 		cxled->state = CXL_DECODER_STATE_MANUAL;
 	}
-
-	return 0;
 }
 
 static int cxl_setup_hdm_decoder_from_dvsec(
--- linux-qcom-6.8.0.orig/drivers/cxl/core/mbox.c
+++ linux-qcom-6.8.0/drivers/cxl/core/mbox.c
@@ -915,7 +915,7 @@
 
 		payload->handles[i++] = gen->hdr.handle;
 		dev_dbg(mds->cxlds.dev, "Event log '%d': Clearing %u\n", log,
-			le16_to_cpu(payload->handles[i]));
+			le16_to_cpu(payload->handles[i - 1]));
 
 		if (i == max_handles) {
 			payload->nr_recs = i;
@@ -946,24 +946,22 @@
 	struct cxl_memdev *cxlmd = mds->cxlds.cxlmd;
 	struct device *dev = mds->cxlds.dev;
 	struct cxl_get_event_payload *payload;
-	struct cxl_mbox_cmd mbox_cmd;
 	u8 log_type = type;
 	u16 nr_rec;
 
 	mutex_lock(&mds->event.log_lock);
 	payload = mds->event.buf;
 
-	mbox_cmd = (struct cxl_mbox_cmd) {
-		.opcode = CXL_MBOX_OP_GET_EVENT_RECORD,
-		.payload_in = &log_type,
-		.size_in = sizeof(log_type),
-		.payload_out = payload,
-		.size_out = mds->payload_size,
-		.min_out = struct_size(payload, records, 0),
-	};
-
 	do {
 		int rc, i;
+		struct cxl_mbox_cmd mbox_cmd = (struct cxl_mbox_cmd) {
+			.opcode = CXL_MBOX_OP_GET_EVENT_RECORD,
+			.payload_in = &log_type,
+			.size_in = sizeof(log_type),
+			.payload_out = payload,
+			.size_out = mds->payload_size,
+			.min_out = struct_size(payload, records, 0),
+		};
 
 		rc = cxl_internal_send_cmd(mds, &mbox_cmd);
 		if (rc) {
@@ -1296,7 +1294,6 @@
 	struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
 	struct cxl_mbox_poison_out *po;
 	struct cxl_mbox_poison_in pi;
-	struct cxl_mbox_cmd mbox_cmd;
 	int nr_records = 0;
 	int rc;
 
@@ -1308,16 +1305,16 @@
 	pi.offset = cpu_to_le64(offset);
 	pi.length = cpu_to_le64(len / CXL_POISON_LEN_MULT);
 
-	mbox_cmd = (struct cxl_mbox_cmd) {
-		.opcode = CXL_MBOX_OP_GET_POISON,
-		.size_in = sizeof(pi),
-		.payload_in = &pi,
-		.size_out = mds->payload_size,
-		.payload_out = po,
-		.min_out = struct_size(po, record, 0),
-	};
-
 	do {
+		struct cxl_mbox_cmd mbox_cmd = (struct cxl_mbox_cmd){
+			.opcode = CXL_MBOX_OP_GET_POISON,
+			.size_in = sizeof(pi),
+			.payload_in = &pi,
+			.size_out = mds->payload_size,
+			.payload_out = po,
+			.min_out = struct_size(po, record, 0),
+		};
+
 		rc = cxl_internal_send_cmd(mds, &mbox_cmd);
 		if (rc)
 			break;
--- linux-qcom-6.8.0.orig/drivers/cxl/core/memdev.c
+++ linux-qcom-6.8.0/drivers/cxl/core/memdev.c
@@ -251,50 +251,6 @@
 }
 EXPORT_SYMBOL_NS_GPL(cxl_trigger_poison_list, CXL);
 
-struct cxl_dpa_to_region_context {
-	struct cxl_region *cxlr;
-	u64 dpa;
-};
-
-static int __cxl_dpa_to_region(struct device *dev, void *arg)
-{
-	struct cxl_dpa_to_region_context *ctx = arg;
-	struct cxl_endpoint_decoder *cxled;
-	u64 dpa = ctx->dpa;
-
-	if (!is_endpoint_decoder(dev))
-		return 0;
-
-	cxled = to_cxl_endpoint_decoder(dev);
-	if (!cxled->dpa_res || !resource_size(cxled->dpa_res))
-		return 0;
-
-	if (dpa > cxled->dpa_res->end || dpa < cxled->dpa_res->start)
-		return 0;
-
-	dev_dbg(dev, "dpa:0x%llx mapped in region:%s\n", dpa,
-		dev_name(&cxled->cxld.region->dev));
-
-	ctx->cxlr = cxled->cxld.region;
-
-	return 1;
-}
-
-static struct cxl_region *cxl_dpa_to_region(struct cxl_memdev *cxlmd, u64 dpa)
-{
-	struct cxl_dpa_to_region_context ctx;
-	struct cxl_port *port;
-
-	ctx = (struct cxl_dpa_to_region_context) {
-		.dpa = dpa,
-	};
-	port = cxlmd->endpoint;
-	if (port && is_cxl_endpoint(port) && cxl_num_decoders_committed(port))
-		device_for_each_child(&port->dev, &ctx, __cxl_dpa_to_region);
-
-	return ctx.cxlr;
-}
-
 static int cxl_validate_poison_dpa(struct cxl_memdev *cxlmd, u64 dpa)
 {
 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
--- linux-qcom-6.8.0.orig/drivers/cxl/core/pci.c
+++ linux-qcom-6.8.0/drivers/cxl/core/pci.c
@@ -390,10 +390,6 @@
 
 		size |= temp & CXL_DVSEC_MEM_SIZE_LOW_MASK;
 		if (!size) {
-			info->dvsec_range[i] = (struct range) {
-				.start = 0,
-				.end = CXL_RESOURCE_NONE,
-			};
 			continue;
 		}
 
@@ -411,12 +407,10 @@
 
 		base |= temp & CXL_DVSEC_MEM_BASE_LOW_MASK;
 
-		info->dvsec_range[i] = (struct range) {
+		info->dvsec_range[ranges++] = (struct range) {
 			.start = base,
 			.end = base + size - 1
 		};
-
-		ranges++;
 	}
 
 	info->ranges = ranges;
@@ -1034,3 +1028,32 @@
 
 	return cxl_flit_size(pdev) * MEGA / bw;
 }
+
+static int __cxl_endpoint_decoder_reset_detected(struct device *dev, void *data)
+{
+	struct cxl_port *port = data;
+	struct cxl_decoder *cxld;
+	struct cxl_hdm *cxlhdm;
+	void __iomem *hdm;
+	u32 ctrl;
+
+	if (!is_endpoint_decoder(dev))
+		return 0;
+
+	cxld = to_cxl_decoder(dev);
+	if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)
+		return 0;
+
+	cxlhdm = dev_get_drvdata(&port->dev);
+	hdm = cxlhdm->regs.hdm_decoder;
+	ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(cxld->id));
+
+	return !FIELD_GET(CXL_HDM_DECODER0_CTRL_COMMITTED, ctrl);
+}
+
+bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port)
+{
+	return device_for_each_child(&port->dev, port,
+				     __cxl_endpoint_decoder_reset_detected);
+}
+EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_reset_detected, CXL);
--- linux-qcom-6.8.0.orig/drivers/cxl/core/pmem.c
+++ linux-qcom-6.8.0/drivers/cxl/core/pmem.c
@@ -62,10 +62,14 @@
 	return is_cxl_nvdimm_bridge(dev);
 }
 
-struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_memdev *cxlmd)
+/**
+ * cxl_find_nvdimm_bridge() - find a bridge device relative to a port
+ * @port: any descendant port of an nvdimm-bridge associated
+ *        root-cxl-port
+ */
+struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_port *port)
 {
-	struct cxl_root *cxl_root __free(put_cxl_root) =
-		find_cxl_root(cxlmd->endpoint);
+	struct cxl_root *cxl_root __free(put_cxl_root) = find_cxl_root(port);
 	struct device *dev;
 
 	if (!cxl_root)
@@ -242,18 +246,20 @@
 
 /**
  * devm_cxl_add_nvdimm() - add a bridge between a cxl_memdev and an nvdimm
+ * @parent_port: parent port for the (to be added) @cxlmd endpoint port
  * @cxlmd: cxl_memdev instance that will perform LIBNVDIMM operations
  *
  * Return: 0 on success negative error code on failure.
  */
-int devm_cxl_add_nvdimm(struct cxl_memdev *cxlmd)
+int devm_cxl_add_nvdimm(struct cxl_port *parent_port,
+			struct cxl_memdev *cxlmd)
 {
 	struct cxl_nvdimm_bridge *cxl_nvb;
 	struct cxl_nvdimm *cxl_nvd;
 	struct device *dev;
 	int rc;
 
-	cxl_nvb = cxl_find_nvdimm_bridge(cxlmd);
+	cxl_nvb = cxl_find_nvdimm_bridge(parent_port);
 	if (!cxl_nvb)
 		return -ENODEV;
 
--- linux-qcom-6.8.0.orig/drivers/cxl/core/port.c
+++ linux-qcom-6.8.0/drivers/cxl/core/port.c
@@ -2069,11 +2069,18 @@
 
 static struct workqueue_struct *cxl_bus_wq;
 
-static void cxl_bus_rescan_queue(struct work_struct *w)
+static int cxl_rescan_attach(struct device *dev, void *data)
 {
-	int rc = bus_rescan_devices(&cxl_bus_type);
+	int rc = device_attach(dev);
+
+	dev_vdbg(dev, "rescan: %s\n", rc ? "attach" : "detached");
 
-	pr_debug("CXL bus rescan result: %d\n", rc);
+	return 0;
+}
+
+static void cxl_bus_rescan_queue(struct work_struct *w)
+{
+	bus_for_each_dev(&cxl_bus_type, NULL, NULL, cxl_rescan_attach);
 }
 
 void cxl_bus_rescan(void)
@@ -2096,18 +2103,41 @@
 }
 EXPORT_SYMBOL_NS_GPL(schedule_cxl_memdev_detach, CXL);
 
-static void combine_coordinates(struct access_coordinate *c1,
-				struct access_coordinate *c2)
+/**
+ * cxl_hb_get_perf_coordinates - Retrieve performance numbers between initiator
+ *				 and host bridge
+ *
+ * @port: endpoint cxl_port
+ * @coord: output access coordinates
+ *
+ * Return: errno on failure, 0 on success.
+ */
+int cxl_hb_get_perf_coordinates(struct cxl_port *port,
+				struct access_coordinate *coord)
 {
-		if (c2->write_bandwidth)
-			c1->write_bandwidth = min(c1->write_bandwidth,
-						  c2->write_bandwidth);
-		c1->write_latency += c2->write_latency;
-
-		if (c2->read_bandwidth)
-			c1->read_bandwidth = min(c1->read_bandwidth,
-						 c2->read_bandwidth);
-		c1->read_latency += c2->read_latency;
+	struct cxl_port *iter = port;
+	struct cxl_dport *dport;
+
+	if (!is_cxl_endpoint(port))
+		return -EINVAL;
+
+	dport = iter->parent_dport;
+	while (iter && !is_cxl_root(to_cxl_port(iter->dev.parent))) {
+		iter = to_cxl_port(iter->dev.parent);
+		dport = iter->parent_dport;
+	}
+
+	coord[ACCESS_COORDINATE_LOCAL] =
+		dport->hb_coord[ACCESS_COORDINATE_LOCAL];
+	coord[ACCESS_COORDINATE_CPU] =
+		dport->hb_coord[ACCESS_COORDINATE_CPU];
+
+	return 0;
+}
+
+static bool parent_port_is_cxl_root(struct cxl_port *port)
+{
+	return is_cxl_root(to_cxl_port(port->dev.parent));
 }
 
 /**
@@ -2129,30 +2159,31 @@
 	struct cxl_dport *dport;
 	struct pci_dev *pdev;
 	unsigned int bw;
+	bool is_cxl_root;
 
 	if (!is_cxl_endpoint(port))
 		return -EINVAL;
 
-	dport = iter->parent_dport;
-
 	/*
-	 * Exit the loop when the parent port of the current port is cxl root.
-	 * The iterative loop starts at the endpoint and gathers the
-	 * latency of the CXL link from the current iter to the next downstream
-	 * port each iteration. If the parent is cxl root then there is
-	 * nothing to gather.
+	 * Exit the loop when the parent port of the current iter port is cxl
+	 * root. The iterative loop starts at the endpoint and gathers the
+	 * latency of the CXL link from the current device/port to the connected
+	 * downstream port each iteration.
 	 */
-	while (iter && !is_cxl_root(to_cxl_port(iter->dev.parent))) {
-		combine_coordinates(&c, &dport->sw_coord);
-		c.write_latency += dport->link_latency;
-		c.read_latency += dport->link_latency;
-
-		iter = to_cxl_port(iter->dev.parent);
+	do {
 		dport = iter->parent_dport;
-	}
+		iter = to_cxl_port(iter->dev.parent);
+		is_cxl_root = parent_port_is_cxl_root(iter);
 
-	/* Augment with the generic port (host bridge) perf data */
-	combine_coordinates(&c, &dport->hb_coord);
+		/*
+		 * There's no valid access_coordinate for a root port since RPs do not
+		 * have CDAT and therefore needs to be skipped.
+		 */
+		if (!is_cxl_root)
+			cxl_coordinates_combine(&c, &c, &dport->sw_coord);
+		c.write_latency += dport->link_latency;
+		c.read_latency += dport->link_latency;
+	} while (!is_cxl_root);
 
 	/* Get the calculated PCI paths bandwidth */
 	pdev = to_pci_dev(port->uport_dev->parent);
--- linux-qcom-6.8.0.orig/drivers/cxl/core/region.c
+++ linux-qcom-6.8.0/drivers/cxl/core/region.c
@@ -128,8 +128,8 @@
 				"Bypassing cpu_cache_invalidate_memregion() for testing!\n");
 			return 0;
 		} else {
-			dev_err(&cxlr->dev,
-				"Failed to synchronize CPU cache state\n");
+			dev_WARN(&cxlr->dev,
+				 "Failed to synchronize CPU cache state\n");
 			return -ENXIO;
 		}
 	}
@@ -138,19 +138,17 @@
 	return 0;
 }
 
-static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
+static void cxl_region_decode_reset(struct cxl_region *cxlr, int count)
 {
 	struct cxl_region_params *p = &cxlr->params;
-	int i, rc = 0;
+	int i;
 
 	/*
-	 * Before region teardown attempt to flush, and if the flush
-	 * fails cancel the region teardown for data consistency
-	 * concerns
+	 * Before region teardown attempt to flush, evict any data cached for
+	 * this region, or scream loudly about missing arch / platform support
+	 * for CXL teardown.
 	 */
-	rc = cxl_region_invalidate_memregion(cxlr);
-	if (rc)
-		return rc;
+	cxl_region_invalidate_memregion(cxlr);
 
 	for (i = count - 1; i >= 0; i--) {
 		struct cxl_endpoint_decoder *cxled = p->targets[i];
@@ -173,23 +171,17 @@
 			cxl_rr = cxl_rr_load(iter, cxlr);
 			cxld = cxl_rr->decoder;
 			if (cxld->reset)
-				rc = cxld->reset(cxld);
-			if (rc)
-				return rc;
+				cxld->reset(cxld);
 			set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
 		}
 
 endpoint_reset:
-		rc = cxled->cxld.reset(&cxled->cxld);
-		if (rc)
-			return rc;
+		cxled->cxld.reset(&cxled->cxld);
 		set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
 	}
 
 	/* all decoders associated with this region have been torn down */
 	clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
-
-	return 0;
 }
 
 static int commit_decoder(struct cxl_decoder *cxld)
@@ -305,16 +297,8 @@
 		 * still pending.
 		 */
 		if (p->state == CXL_CONFIG_RESET_PENDING) {
-			rc = cxl_region_decode_reset(cxlr, p->interleave_ways);
-			/*
-			 * Revert to committed since there may still be active
-			 * decoders associated with this region, or move forward
-			 * to active to mark the reset successful
-			 */
-			if (rc)
-				p->state = CXL_CONFIG_COMMIT;
-			else
-				p->state = CXL_CONFIG_ACTIVE;
+			cxl_region_decode_reset(cxlr, p->interleave_ways);
+			p->state = CXL_CONFIG_ACTIVE;
 		}
 	}
 
@@ -998,6 +982,26 @@
 	}
 	cxld = cxl_rr->decoder;
 
+	/*
+	 * the number of targets should not exceed the target_count
+	 * of the decoder
+	 */
+	if (is_switch_decoder(&cxld->dev)) {
+		struct cxl_switch_decoder *cxlsd;
+
+		cxlsd = to_cxl_switch_decoder(&cxld->dev);
+		if (cxl_rr->nr_targets > cxlsd->nr_targets) {
+			dev_dbg(&cxlr->dev,
+				"%s:%s %s add: %s:%s @ %d overflows targets: %d\n",
+				dev_name(port->uport_dev), dev_name(&port->dev),
+				dev_name(&cxld->dev), dev_name(&cxlmd->dev),
+				dev_name(&cxled->cxld.dev), pos,
+				cxlsd->nr_targets);
+			rc = -ENXIO;
+			goto out_erase;
+		}
+	}
+
 	rc = cxl_rr_ep_add(cxl_rr, cxled);
 	if (rc) {
 		dev_dbg(&cxlr->dev,
@@ -1107,6 +1111,50 @@
 	return 0;
 }
 
+static int check_interleave_cap(struct cxl_decoder *cxld, int iw, int ig)
+{
+	struct cxl_port *port = to_cxl_port(cxld->dev.parent);
+	struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev);
+	unsigned int interleave_mask;
+	u8 eiw;
+	u16 eig;
+	int high_pos, low_pos;
+
+	if (!test_bit(iw, &cxlhdm->iw_cap_mask))
+		return -ENXIO;
+	/*
+	 * Per CXL specification r3.1(8.2.4.20.13 Decoder Protection),
+	 * if eiw < 8:
+	 *   DPAOFFSET[51: eig + 8] = HPAOFFSET[51: eig + 8 + eiw]
+	 *   DPAOFFSET[eig + 7: 0]  = HPAOFFSET[eig + 7: 0]
+	 *
+	 *   when the eiw is 0, all the bits of HPAOFFSET[51: 0] are used, the
+	 *   interleave bits are none.
+	 *
+	 * if eiw >= 8:
+	 *   DPAOFFSET[51: eig + 8] = HPAOFFSET[51: eig + eiw] / 3
+	 *   DPAOFFSET[eig + 7: 0]  = HPAOFFSET[eig + 7: 0]
+	 *
+	 *   when the eiw is 8, all the bits of HPAOFFSET[51: 0] are used, the
+	 *   interleave bits are none.
+	 */
+	ways_to_eiw(iw, &eiw);
+	if (eiw == 0 || eiw == 8)
+		return 0;
+
+	granularity_to_eig(ig, &eig);
+	if (eiw > 8)
+		high_pos = eiw + eig - 1;
+	else
+		high_pos = eiw + eig + 7;
+	low_pos = eig + 8;
+	interleave_mask = GENMASK(high_pos, low_pos);
+	if (interleave_mask & ~cxlhdm->interleave_mask)
+		return -ENXIO;
+
+	return 0;
+}
+
 static int cxl_port_setup_targets(struct cxl_port *port,
 				  struct cxl_region *cxlr,
 				  struct cxl_endpoint_decoder *cxled)
@@ -1120,6 +1168,7 @@
 	struct cxl_region_params *p = &cxlr->params;
 	struct cxl_decoder *cxld = cxl_rr->decoder;
 	struct cxl_switch_decoder *cxlsd;
+	struct cxl_port *iter = port;
 	u16 eig, peig;
 	u8 eiw, peiw;
 
@@ -1136,16 +1185,26 @@
 
 	cxlsd = to_cxl_switch_decoder(&cxld->dev);
 	if (cxl_rr->nr_targets_set) {
-		int i, distance;
+		int i, distance = 1;
+		struct cxl_region_ref *cxl_rr_iter;
 
 		/*
-		 * Passthrough decoders impose no distance requirements between
-		 * peers
+		 * The "distance" between peer downstream ports represents which
+		 * endpoint positions in the region interleave a given port can
+		 * host.
+		 *
+		 * For example, at the root of a hierarchy the distance is
+		 * always 1 as every index targets a different host-bridge. At
+		 * each subsequent switch level those ports map every Nth region
+		 * position where N is the width of the switch == distance.
 		 */
-		if (cxl_rr->nr_targets == 1)
-			distance = 0;
-		else
-			distance = p->nr_targets / cxl_rr->nr_targets;
+		do {
+			cxl_rr_iter = cxl_rr_load(iter, cxlr);
+			distance *= cxl_rr_iter->nr_targets;
+			iter = to_cxl_port(iter->dev.parent);
+		} while (!is_cxl_root(iter));
+		distance *= cxlrd->cxlsd.cxld.interleave_ways;
+
 		for (i = 0; i < cxl_rr->nr_targets_set; i++)
 			if (ep->dport == cxlsd->target[i]) {
 				rc = check_last_peer(cxled, ep, cxl_rr,
@@ -1257,6 +1316,15 @@
 			return -ENXIO;
 		}
 	} else {
+		rc = check_interleave_cap(cxld, iw, ig);
+		if (rc) {
+			dev_dbg(&cxlr->dev,
+				"%s:%s iw: %d ig: %d is not supported\n",
+				dev_name(port->uport_dev),
+				dev_name(&port->dev), iw, ig);
+			return rc;
+		}
+
 		cxld->interleave_ways = iw;
 		cxld->interleave_granularity = ig;
 		cxld->hpa_range = (struct range) {
@@ -1456,10 +1524,13 @@
 				      const struct cxl_dport *dport, int pos)
 {
 	struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
+	struct cxl_switch_decoder *cxlsd = &cxlrd->cxlsd;
+	struct cxl_decoder *cxld = &cxlsd->cxld;
+	int iw = cxld->interleave_ways;
 	struct cxl_port *iter;
 	int rc;
 
-	if (cxlrd->calc_hb(cxlrd, pos) != dport) {
+	if (dport != cxlrd->cxlsd.target[pos % iw]) {
 		dev_dbg(&cxlr->dev, "%s:%s invalid target position for %s\n",
 			dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
 			dev_name(&cxlrd->cxlsd.cxld.dev));
@@ -1693,6 +1764,15 @@
 	struct cxl_dport *dport;
 	int rc = -ENXIO;
 
+	rc = check_interleave_cap(&cxled->cxld, p->interleave_ways,
+				  p->interleave_granularity);
+	if (rc) {
+		dev_dbg(&cxlr->dev, "%s iw: %d ig: %d is not supported\n",
+			dev_name(&cxled->cxld.dev), p->interleave_ways,
+			p->interleave_granularity);
+		return rc;
+	}
+
 	if (cxled->mode != cxlr->mode) {
 		dev_dbg(&cxlr->dev, "%s region mode: %d mismatch: %d\n",
 			dev_name(&cxled->cxld.dev), cxlr->mode, cxled->mode);
@@ -1861,13 +1941,7 @@
 	get_device(&cxlr->dev);
 
 	if (p->state > CXL_CONFIG_ACTIVE) {
-		/*
-		 * TODO: tear down all impacted regions if a device is
-		 * removed out of order
-		 */
-		rc = cxl_region_decode_reset(cxlr, p->interleave_ways);
-		if (rc)
-			goto out;
+		cxl_region_decode_reset(cxlr, p->interleave_ways);
 		p->state = CXL_CONFIG_ACTIVE;
 	}
 
@@ -2187,15 +2261,6 @@
 	struct device *dev;
 	int rc;
 
-	switch (mode) {
-	case CXL_DECODER_RAM:
-	case CXL_DECODER_PMEM:
-		break;
-	default:
-		dev_err(&cxlrd->cxlsd.cxld.dev, "unsupported mode %d\n", mode);
-		return ERR_PTR(-EINVAL);
-	}
-
 	cxlr = cxl_region_alloc(cxlrd, id);
 	if (IS_ERR(cxlr))
 		return cxlr;
@@ -2246,6 +2311,15 @@
 {
 	int rc;
 
+	switch (mode) {
+	case CXL_DECODER_RAM:
+	case CXL_DECODER_PMEM:
+		break;
+	default:
+		dev_err(&cxlrd->cxlsd.cxld.dev, "unsupported mode %d\n", mode);
+		return ERR_PTR(-EINVAL);
+	}
+
 	rc = memregion_alloc(GFP_KERNEL);
 	if (rc < 0)
 		return ERR_PTR(rc);
@@ -2510,28 +2584,78 @@
 	return rc;
 }
 
+struct cxl_dpa_to_region_context {
+	struct cxl_region *cxlr;
+	u64 dpa;
+};
+
+static int __cxl_dpa_to_region(struct device *dev, void *arg)
+{
+	struct cxl_dpa_to_region_context *ctx = arg;
+	struct cxl_endpoint_decoder *cxled;
+	struct cxl_region *cxlr;
+	u64 dpa = ctx->dpa;
+
+	if (!is_endpoint_decoder(dev))
+		return 0;
+
+	cxled = to_cxl_endpoint_decoder(dev);
+	if (!cxled || !cxled->dpa_res || !resource_size(cxled->dpa_res))
+		return 0;
+
+	if (dpa > cxled->dpa_res->end || dpa < cxled->dpa_res->start)
+		return 0;
+
+	/*
+	 * Stop the region search (return 1) when an endpoint mapping is
+	 * found. The region may not be fully constructed so offering
+	 * the cxlr in the context structure is not guaranteed.
+	 */
+	cxlr = cxled->cxld.region;
+	if (cxlr)
+		dev_dbg(dev, "dpa:0x%llx mapped in region:%s\n", dpa,
+			dev_name(&cxlr->dev));
+	else
+		dev_dbg(dev, "dpa:0x%llx mapped in endpoint:%s\n", dpa,
+			dev_name(dev));
+
+	ctx->cxlr = cxlr;
+
+	return 1;
+}
+
+struct cxl_region *cxl_dpa_to_region(const struct cxl_memdev *cxlmd, u64 dpa)
+{
+	struct cxl_dpa_to_region_context ctx;
+	struct cxl_port *port;
+
+	ctx = (struct cxl_dpa_to_region_context) {
+		.dpa = dpa,
+	};
+	port = cxlmd->endpoint;
+	if (port && is_cxl_endpoint(port) && cxl_num_decoders_committed(port))
+		device_for_each_child(&port->dev, &ctx, __cxl_dpa_to_region);
+
+	return ctx.cxlr;
+}
+
 static struct lock_class_key cxl_pmem_region_key;
 
-static struct cxl_pmem_region *cxl_pmem_region_alloc(struct cxl_region *cxlr)
+static int cxl_pmem_region_alloc(struct cxl_region *cxlr)
 {
 	struct cxl_region_params *p = &cxlr->params;
 	struct cxl_nvdimm_bridge *cxl_nvb;
-	struct cxl_pmem_region *cxlr_pmem;
 	struct device *dev;
 	int i;
 
-	down_read(&cxl_region_rwsem);
-	if (p->state != CXL_CONFIG_COMMIT) {
-		cxlr_pmem = ERR_PTR(-ENXIO);
-		goto out;
-	}
+	guard(rwsem_read)(&cxl_region_rwsem);
+	if (p->state != CXL_CONFIG_COMMIT)
+		return -ENXIO;
 
-	cxlr_pmem = kzalloc(struct_size(cxlr_pmem, mapping, p->nr_targets),
-			    GFP_KERNEL);
-	if (!cxlr_pmem) {
-		cxlr_pmem = ERR_PTR(-ENOMEM);
-		goto out;
-	}
+	struct cxl_pmem_region *cxlr_pmem __free(kfree) =
+		kzalloc(struct_size(cxlr_pmem, mapping, p->nr_targets), GFP_KERNEL);
+	if (!cxlr_pmem)
+		return -ENOMEM;
 
 	cxlr_pmem->hpa_range.start = p->res->start;
 	cxlr_pmem->hpa_range.end = p->res->end;
@@ -2548,11 +2672,9 @@
 		 * bridge for one device is the same for all.
 		 */
 		if (i == 0) {
-			cxl_nvb = cxl_find_nvdimm_bridge(cxlmd);
-			if (!cxl_nvb) {
-				cxlr_pmem = ERR_PTR(-ENODEV);
-				goto out;
-			}
+			cxl_nvb = cxl_find_nvdimm_bridge(cxlmd->endpoint);
+			if (!cxl_nvb)
+				return -ENODEV;
 			cxlr->cxl_nvb = cxl_nvb;
 		}
 		m->cxlmd = cxlmd;
@@ -2563,18 +2685,16 @@
 	}
 
 	dev = &cxlr_pmem->dev;
-	cxlr_pmem->cxlr = cxlr;
-	cxlr->cxlr_pmem = cxlr_pmem;
 	device_initialize(dev);
 	lockdep_set_class(&dev->mutex, &cxl_pmem_region_key);
 	device_set_pm_not_required(dev);
 	dev->parent = &cxlr->dev;
 	dev->bus = &cxl_bus_type;
 	dev->type = &cxl_pmem_region_type;
-out:
-	up_read(&cxl_region_rwsem);
+	cxlr_pmem->cxlr = cxlr;
+	cxlr->cxlr_pmem = no_free_ptr(cxlr_pmem);
 
-	return cxlr_pmem;
+	return 0;
 }
 
 static void cxl_dax_region_release(struct device *dev)
@@ -2691,9 +2811,10 @@
 	struct device *dev;
 	int rc;
 
-	cxlr_pmem = cxl_pmem_region_alloc(cxlr);
-	if (IS_ERR(cxlr_pmem))
-		return PTR_ERR(cxlr_pmem);
+	rc = cxl_pmem_region_alloc(cxlr);
+	if (rc)
+		return rc;
+	cxlr_pmem = cxlr->cxlr_pmem;
 	cxl_nvb = cxlr->cxl_nvb;
 
 	dev = &cxlr_pmem->dev;
--- linux-qcom-6.8.0.orig/drivers/cxl/core/regs.c
+++ linux-qcom-6.8.0/drivers/cxl/core/regs.c
@@ -271,6 +271,7 @@
 static bool cxl_decode_regblock(struct pci_dev *pdev, u32 reg_lo, u32 reg_hi,
 				struct cxl_register_map *map)
 {
+	u8 reg_type = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK, reg_lo);
 	int bar = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BIR_MASK, reg_lo);
 	u64 offset = ((u64)reg_hi << 32) |
 		     (reg_lo & CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK);
@@ -278,11 +279,11 @@
 	if (offset > pci_resource_len(pdev, bar)) {
 		dev_warn(&pdev->dev,
 			 "BAR%d: %pr: too small (offset: %pa, type: %d)\n", bar,
-			 &pdev->resource[bar], &offset, map->reg_type);
+			 &pdev->resource[bar], &offset, reg_type);
 		return false;
 	}
 
-	map->reg_type = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK, reg_lo);
+	map->reg_type = reg_type;
 	map->resource = pci_resource_start(pdev, bar) + offset;
 	map->max_size = pci_resource_len(pdev, bar) - offset;
 	return true;
--- linux-qcom-6.8.0.orig/drivers/cxl/core/trace.c
+++ linux-qcom-6.8.0/drivers/cxl/core/trace.c
@@ -7,20 +7,13 @@
 #define CREATE_TRACE_POINTS
 #include "trace.h"
 
-static bool cxl_is_hpa_in_range(u64 hpa, struct cxl_region *cxlr, int pos)
+static bool cxl_is_hpa_in_chunk(u64 hpa, struct cxl_region *cxlr, int pos)
 {
 	struct cxl_region_params *p = &cxlr->params;
 	int gran = p->interleave_granularity;
 	int ways = p->interleave_ways;
 	u64 offset;
 
-	/* Is the hpa within this region at all */
-	if (hpa < p->res->start || hpa > p->res->end) {
-		dev_dbg(&cxlr->dev,
-			"Addr trans fail: hpa 0x%llx not in region\n", hpa);
-		return false;
-	}
-
 	/* Is the hpa in an expected chunk for its pos(-ition) */
 	offset = hpa - p->res->start;
 	offset = do_div(offset, gran * ways);
@@ -36,6 +29,7 @@
 static u64 cxl_dpa_to_hpa(u64 dpa,  struct cxl_region *cxlr,
 			  struct cxl_endpoint_decoder *cxled)
 {
+	struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent);
 	u64 dpa_offset, hpa_offset, bits_upper, mask_upper, hpa;
 	struct cxl_region_params *p = &cxlr->params;
 	int pos = cxled->pos;
@@ -75,7 +69,18 @@
 	/* Apply the hpa_offset to the region base address */
 	hpa = hpa_offset + p->res->start;
 
-	if (!cxl_is_hpa_in_range(hpa, cxlr, cxled->pos))
+	/* Root decoder translation overrides typical modulo decode */
+	if (cxlrd->hpa_to_spa)
+		hpa = cxlrd->hpa_to_spa(cxlrd, hpa);
+
+	if (hpa < p->res->start || hpa > p->res->end) {
+		dev_dbg(&cxlr->dev,
+			"Addr trans fail: hpa 0x%llx not in region\n", hpa);
+		return ULLONG_MAX;
+	}
+
+	/* Simple chunk check, by pos & gran, only applies to modulo decodes */
+	if (!cxlrd->hpa_to_spa && (!cxl_is_hpa_in_chunk(hpa, cxlr, pos)))
 		return ULLONG_MAX;
 
 	return hpa;
--- linux-qcom-6.8.0.orig/drivers/cxl/core/trace.h
+++ linux-qcom-6.8.0/drivers/cxl/core/trace.h
@@ -253,8 +253,8 @@
  * DRAM Event Record
  * CXL rev 3.0 section 8.2.9.2.1.2; Table 8-44
  */
-#define CXL_DPA_FLAGS_MASK			0x3F
-#define CXL_DPA_MASK				(~CXL_DPA_FLAGS_MASK)
+#define CXL_DPA_FLAGS_MASK			GENMASK(1, 0)
+#define CXL_DPA_MASK				GENMASK_ULL(63, 6)
 
 #define CXL_DPA_VOLATILE			BIT(0)
 #define CXL_DPA_NOT_REPAIRABLE			BIT(1)
@@ -279,7 +279,7 @@
 #define CXL_GMER_MEM_EVT_TYPE_ECC_ERROR			0x00
 #define CXL_GMER_MEM_EVT_TYPE_INV_ADDR			0x01
 #define CXL_GMER_MEM_EVT_TYPE_DATA_PATH_ERROR		0x02
-#define show_mem_event_type(type)	__print_symbolic(type,			\
+#define show_gmer_mem_event_type(type)	__print_symbolic(type,			\
 	{ CXL_GMER_MEM_EVT_TYPE_ECC_ERROR,		"ECC Error" },		\
 	{ CXL_GMER_MEM_EVT_TYPE_INV_ADDR,		"Invalid Address" },	\
 	{ CXL_GMER_MEM_EVT_TYPE_DATA_PATH_ERROR,	"Data Path Error" }	\
@@ -361,7 +361,7 @@
 		"device=%x comp_id=%s validity_flags='%s'",
 		__entry->dpa, show_dpa_flags(__entry->dpa_flags),
 		show_event_desc_flags(__entry->descriptor),
-		show_mem_event_type(__entry->type),
+		show_gmer_mem_event_type(__entry->type),
 		show_trans_type(__entry->transaction_type),
 		__entry->channel, __entry->rank, __entry->device,
 		__print_hex(__entry->comp_id, CXL_EVENT_GEN_MED_COMP_ID_SIZE),
@@ -378,6 +378,17 @@
  * DRAM Event Record defines many fields the same as the General Media Event
  * Record.  Reuse those definitions as appropriate.
  */
+#define CXL_DER_MEM_EVT_TYPE_ECC_ERROR			0x00
+#define CXL_DER_MEM_EVT_TYPE_SCRUB_MEDIA_ECC_ERROR	0x01
+#define CXL_DER_MEM_EVT_TYPE_INV_ADDR			0x02
+#define CXL_DER_MEM_EVT_TYPE_DATA_PATH_ERROR		0x03
+#define show_dram_mem_event_type(type)  __print_symbolic(type,				\
+	{ CXL_DER_MEM_EVT_TYPE_ECC_ERROR,		"ECC Error" },			\
+	{ CXL_DER_MEM_EVT_TYPE_SCRUB_MEDIA_ECC_ERROR,	"Scrub Media ECC Error" },	\
+	{ CXL_DER_MEM_EVT_TYPE_INV_ADDR,		"Invalid Address" },		\
+	{ CXL_DER_MEM_EVT_TYPE_DATA_PATH_ERROR,		"Data Path Error" }		\
+)
+
 #define CXL_DER_VALID_CHANNEL				BIT(0)
 #define CXL_DER_VALID_RANK				BIT(1)
 #define CXL_DER_VALID_NIBBLE				BIT(2)
@@ -452,7 +463,7 @@
 		"validity_flags='%s'",
 		__entry->dpa, show_dpa_flags(__entry->dpa_flags),
 		show_event_desc_flags(__entry->descriptor),
-		show_mem_event_type(__entry->type),
+		show_dram_mem_event_type(__entry->type),
 		show_trans_type(__entry->transaction_type),
 		__entry->channel, __entry->rank, __entry->nibble_mask,
 		__entry->bank_group, __entry->bank,
@@ -646,18 +657,18 @@
 
 TRACE_EVENT(cxl_poison,
 
-	TP_PROTO(struct cxl_memdev *cxlmd, struct cxl_region *region,
+	TP_PROTO(struct cxl_memdev *cxlmd, struct cxl_region *cxlr,
 		 const struct cxl_poison_record *record, u8 flags,
 		 __le64 overflow_ts, enum cxl_poison_trace_type trace_type),
 
-	TP_ARGS(cxlmd, region, record, flags, overflow_ts, trace_type),
+	TP_ARGS(cxlmd, cxlr, record, flags, overflow_ts, trace_type),
 
 	TP_STRUCT__entry(
 		__string(memdev, dev_name(&cxlmd->dev))
 		__string(host, dev_name(cxlmd->dev.parent))
 		__field(u64, serial)
 		__field(u8, trace_type)
-		__string(region, region)
+		__string(region, cxlr ? dev_name(&cxlr->dev) : "")
 		__field(u64, overflow_ts)
 		__field(u64, hpa)
 		__field(u64, dpa)
@@ -677,10 +688,10 @@
 		__entry->source = cxl_poison_record_source(record);
 		__entry->trace_type = trace_type;
 		__entry->flags = flags;
-		if (region) {
-			__assign_str(region, dev_name(&region->dev));
-			memcpy(__entry->uuid, &region->params.uuid, 16);
-			__entry->hpa = cxl_trace_hpa(region, cxlmd,
+		if (cxlr) {
+			__assign_str(region, dev_name(&cxlr->dev));
+			memcpy(__entry->uuid, &cxlr->params.uuid, 16);
+			__entry->hpa = cxl_trace_hpa(cxlr, cxlmd,
 						     __entry->dpa);
 		} else {
 			__assign_str(region, "");
--- linux-qcom-6.8.0.orig/drivers/cxl/cxl.h
+++ linux-qcom-6.8.0/drivers/cxl/cxl.h
@@ -44,6 +44,8 @@
 #define   CXL_HDM_DECODER_TARGET_COUNT_MASK GENMASK(7, 4)
 #define   CXL_HDM_DECODER_INTERLEAVE_11_8 BIT(8)
 #define   CXL_HDM_DECODER_INTERLEAVE_14_12 BIT(9)
+#define   CXL_HDM_DECODER_INTERLEAVE_3_6_12_WAY BIT(11)
+#define   CXL_HDM_DECODER_INTERLEAVE_16_WAY BIT(12)
 #define CXL_HDM_DECODER_CTRL_OFFSET 0x4
 #define   CXL_HDM_DECODER_ENABLE BIT(1)
 #define CXL_HDM_DECODER0_BASE_LOW_OFFSET(i) (0x20 * (i) + 0x10)
@@ -354,7 +356,7 @@
 	struct cxl_region *region;
 	unsigned long flags;
 	int (*commit)(struct cxl_decoder *cxld);
-	int (*reset)(struct cxl_decoder *cxld);
+	void (*reset)(struct cxl_decoder *cxld);
 };
 
 /*
@@ -431,12 +433,14 @@
 struct cxl_root_decoder;
 typedef struct cxl_dport *(*cxl_calc_hb_fn)(struct cxl_root_decoder *cxlrd,
 					    int pos);
+typedef u64 (*cxl_hpa_to_spa_fn)(struct cxl_root_decoder *cxlrd, u64 hpa);
 
 /**
  * struct cxl_root_decoder - Static platform CXL address decoder
  * @res: host / parent resource for region allocations
  * @region_id: region id for next region provisioning event
  * @calc_hb: which host bridge covers the n'th position by granularity
+ * @hpa_to_spa: translate CXL host-physical-address to Platform system-physical-address
  * @platform_data: platform specific configuration data
  * @range_lock: sync region autodiscovery by address range
  * @qos_class: QoS performance class cookie
@@ -446,6 +450,7 @@
 	struct resource *res;
 	atomic_t region_id;
 	cxl_calc_hb_fn calc_hb;
+	cxl_hpa_to_spa_fn hpa_to_spa;
 	void *platform_data;
 	struct mutex range_lock;
 	int qos_class;
@@ -671,7 +676,7 @@
 	struct cxl_port *port;
 	struct cxl_regs regs;
 	struct access_coordinate sw_coord;
-	struct access_coordinate hb_coord;
+	struct access_coordinate hb_coord[ACCESS_COORDINATE_MAX];
 	long link_latency;
 };
 
@@ -722,6 +727,7 @@
 int cxl_num_decoders_committed(struct cxl_port *port);
 bool is_cxl_port(const struct device *dev);
 struct cxl_port *to_cxl_port(const struct device *dev);
+void cxl_port_commit_reap(struct cxl_decoder *cxld);
 struct pci_bus;
 int devm_cxl_register_pci_bus(struct device *host, struct device *uport_dev,
 			      struct pci_bus *bus);
@@ -845,8 +851,8 @@
 struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev);
 bool is_cxl_nvdimm(struct device *dev);
 bool is_cxl_nvdimm_bridge(struct device *dev);
-int devm_cxl_add_nvdimm(struct cxl_memdev *cxlmd);
-struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_memdev *cxlmd);
+int devm_cxl_add_nvdimm(struct cxl_port *parent_port, struct cxl_memdev *cxlmd);
+struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_port *port);
 
 #ifdef CONFIG_CXL_REGION
 bool is_cxl_pmem_region(struct device *dev);
@@ -879,9 +885,17 @@
 
 int cxl_endpoint_get_perf_coordinates(struct cxl_port *port,
 				      struct access_coordinate *coord);
+int cxl_hb_get_perf_coordinates(struct cxl_port *port,
+				struct access_coordinate *coord);
 
 void cxl_memdev_update_perf(struct cxl_memdev *cxlmd);
 
+void cxl_coordinates_combine(struct access_coordinate *out,
+			     struct access_coordinate *c1,
+			     struct access_coordinate *c2);
+
+bool cxl_endpoint_decoder_reset_detected(struct cxl_port *port);
+
 /*
  * Unit test builds overrides this to __weak, find the 'strong' version
  * of these symbols in tools/testing/cxl/.
--- linux-qcom-6.8.0.orig/drivers/cxl/cxlmem.h
+++ linux-qcom-6.8.0/drivers/cxl/cxlmem.h
@@ -559,7 +559,7 @@
 		  0x3b, 0x3f, 0x17)
 
 #define DEFINE_CXL_VENDOR_DEBUG_UUID                                           \
-	UUID_INIT(0xe1819d9, 0x11a9, 0x400c, 0x81, 0x1f, 0xd6, 0x07, 0x19,     \
+	UUID_INIT(0x5e1819d9, 0x11a9, 0x400c, 0x81, 0x1f, 0xd6, 0x07, 0x19,     \
 		  0x40, 0x3d, 0x86)
 
 struct cxl_mbox_get_supported_logs {
@@ -848,11 +848,21 @@
 
 int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd);
 
+/**
+ * struct cxl_hdm - HDM Decoder registers and cached / decoded capabilities
+ * @regs: mapped registers, see devm_cxl_setup_hdm()
+ * @decoder_count: number of decoders for this port
+ * @target_count: for switch decoders, max downstream port targets
+ * @interleave_mask: interleave granularity capability, see check_interleave_cap()
+ * @iw_cap_mask: bitmask of supported interleave ways, see check_interleave_cap()
+ * @port: mapped cxl_port, see devm_cxl_setup_hdm()
+ */
 struct cxl_hdm {
 	struct cxl_component_regs regs;
 	unsigned int decoder_count;
 	unsigned int target_count;
 	unsigned int interleave_mask;
+	unsigned long iw_cap_mask;
 	struct cxl_port *port;
 };
 
--- linux-qcom-6.8.0.orig/drivers/cxl/mem.c
+++ linux-qcom-6.8.0/drivers/cxl/mem.c
@@ -152,6 +152,15 @@
 		return -ENXIO;
 	}
 
+	if (resource_size(&cxlds->pmem_res) && IS_ENABLED(CONFIG_CXL_PMEM)) {
+		rc = devm_cxl_add_nvdimm(parent_port, cxlmd);
+		if (rc) {
+			if (rc == -ENODEV)
+				dev_info(dev, "PMEM disabled by platform\n");
+			return rc;
+		}
+	}
+
 	if (dport->rch)
 		endpoint_parent = parent_port->uport_dev;
 	else
@@ -174,14 +183,6 @@
 	if (rc)
 		return rc;
 
-	if (resource_size(&cxlds->pmem_res) && IS_ENABLED(CONFIG_CXL_PMEM)) {
-		rc = devm_cxl_add_nvdimm(cxlmd);
-		if (rc == -ENODEV)
-			dev_info(dev, "PMEM disabled by platform\n");
-		else
-			return rc;
-	}
-
 	/*
 	 * The kernel may be operating out of CXL memory on this device,
 	 * there is no spec defined way to determine whether this device
--- linux-qcom-6.8.0.orig/drivers/cxl/pci.c
+++ linux-qcom-6.8.0/drivers/cxl/pci.c
@@ -917,8 +917,7 @@
 	if (rc)
 		return rc;
 
-	rc = cxl_pci_ras_unmask(pdev);
-	if (rc)
+	if (cxl_pci_ras_unmask(pdev))
 		dev_dbg(&pdev->dev, "No RAS reporting unmasked\n");
 
 	pci_save_state(pdev);
@@ -957,11 +956,33 @@
 		 dev->driver ? "successful" : "failed");
 }
 
+static void cxl_reset_done(struct pci_dev *pdev)
+{
+	struct cxl_dev_state *cxlds = pci_get_drvdata(pdev);
+	struct cxl_memdev *cxlmd = cxlds->cxlmd;
+	struct device *dev = &pdev->dev;
+
+	/*
+	 * FLR does not expect to touch the HDM decoders and related
+	 * registers.  SBR, however, will wipe all device configurations.
+	 * Issue a warning if there was an active decoder before the reset
+	 * that no longer exists.
+	 */
+	guard(device)(&cxlmd->dev);
+	if (cxlmd->endpoint &&
+	    cxl_endpoint_decoder_reset_detected(cxlmd->endpoint)) {
+		dev_crit(dev, "SBR happened without memory regions removal.\n");
+		dev_crit(dev, "System may be unstable if regions hosted system memory.\n");
+		add_taint(TAINT_USER, LOCKDEP_STILL_OK);
+	}
+}
+
 static const struct pci_error_handlers cxl_error_handlers = {
 	.error_detected	= cxl_error_detected,
 	.slot_reset	= cxl_slot_reset,
 	.resume		= cxl_error_resume,
 	.cor_error_detected	= cxl_cor_error_detected,
+	.reset_done	= cxl_reset_done,
 };
 
 static struct pci_driver cxl_pci_driver = {
--- linux-qcom-6.8.0.orig/drivers/cxl/port.c
+++ linux-qcom-6.8.0/drivers/cxl/port.c
@@ -208,7 +208,22 @@
 	},
 };
 
-module_cxl_driver(cxl_port_driver);
+static int __init cxl_port_init(void)
+{
+	return cxl_driver_register(&cxl_port_driver);
+}
+/*
+ * Be ready to immediately enable ports emitted by the platform CXL root
+ * (e.g. cxl_acpi) when CONFIG_CXL_PORT=y.
+ */
+subsys_initcall(cxl_port_init);
+
+static void __exit cxl_port_exit(void)
+{
+	cxl_driver_unregister(&cxl_port_driver);
+}
+module_exit(cxl_port_exit);
+
 MODULE_LICENSE("GPL v2");
 MODULE_IMPORT_NS(CXL);
 MODULE_ALIAS_CXL(CXL_DEVICE_PORT);
--- linux-qcom-6.8.0.orig/drivers/dax/device.c
+++ linux-qcom-6.8.0/drivers/dax/device.c
@@ -86,7 +86,7 @@
 		nr_pages = 1;
 
 	pgoff = linear_page_index(vmf->vma,
-			ALIGN(vmf->address, fault_size));
+			ALIGN_DOWN(vmf->address, fault_size));
 
 	for (i = 0; i < nr_pages; i++) {
 		struct page *page = pfn_to_page(pfn_t_to_pfn(pfn) + i);
--- linux-qcom-6.8.0.orig/drivers/dma-buf/dma-buf.c
+++ linux-qcom-6.8.0/drivers/dma-buf/dma-buf.c
@@ -9,6 +9,8 @@
  * Arnd Bergmann <arnd@arndb.de>, Rob Clark <rob@ti.com> and
  * Daniel Vetter <daniel@ffwll.ch> for their support in creation and
  * refining of this idea.
+ *
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/fs.h>
@@ -1412,6 +1414,27 @@
 }
 EXPORT_SYMBOL_NS_GPL(dma_buf_begin_cpu_access, DMA_BUF);
 
+int dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf,
+		enum dma_data_direction direction,
+		unsigned int offset, unsigned int len)
+{
+	int ret = 0;
+
+	if (WARN_ON(!dmabuf))
+		return -EINVAL;
+	if (dmabuf->ops->begin_cpu_access_partial)
+		ret = dmabuf->ops->begin_cpu_access_partial(dmabuf, direction,
+				offset, len);
+	/* Ensure that all fences are waited upon - but we first allow
+	 * the native handler the chance to do so more efficiently if it
+	 * chooses. A double invocation here will be reasonably cheap no-op.
+	 */
+	if (ret == 0)
+		ret = __dma_buf_begin_cpu_access(dmabuf, direction);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access_partial);
+
 /**
  * dma_buf_end_cpu_access - Must be called after accessing a dma_buf from the
  * cpu in the kernel context. Calls end_cpu_access to allow exporter-specific
@@ -1440,6 +1463,19 @@
 }
 EXPORT_SYMBOL_NS_GPL(dma_buf_end_cpu_access, DMA_BUF);
 
+int dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf,
+		enum dma_data_direction direction,
+		unsigned int offset, unsigned int len)
+{
+	int ret = 0;
+
+	WARN_ON(!dmabuf);
+	if (dmabuf->ops->end_cpu_access_partial)
+		ret = dmabuf->ops->end_cpu_access_partial(dmabuf, direction,
+				offset, len);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access_partial);
 
 /**
  * dma_buf_mmap - Setup up a userspace mmap with the given vma
--- linux-qcom-6.8.0.orig/drivers/dma-buf/dma-fence-array.c
+++ linux-qcom-6.8.0/drivers/dma-buf/dma-fence-array.c
@@ -103,10 +103,36 @@
 static bool dma_fence_array_signaled(struct dma_fence *fence)
 {
 	struct dma_fence_array *array = to_dma_fence_array(fence);
+	int num_pending;
+	unsigned int i;
 
-	if (atomic_read(&array->num_pending) > 0)
+	/*
+	 * We need to read num_pending before checking the enable_signal bit
+	 * to avoid racing with the enable_signaling() implementation, which
+	 * might decrement the counter, and cause a partial check.
+	 * atomic_read_acquire() pairs with atomic_dec_and_test() in
+	 * dma_fence_array_enable_signaling()
+	 *
+	 * The !--num_pending check is here to account for the any_signaled case
+	 * if we race with enable_signaling(), that means the !num_pending check
+	 * in the is_signalling_enabled branch might be outdated (num_pending
+	 * might have been decremented), but that's fine. The user will get the
+	 * right value when testing again later.
+	 */
+	num_pending = atomic_read_acquire(&array->num_pending);
+	if (test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT, &array->base.flags)) {
+		if (num_pending <= 0)
+			goto signal;
 		return false;
+	}
 
+	for (i = 0; i < array->num_fences; ++i) {
+		if (dma_fence_is_signaled(array->fences[i]) && !--num_pending)
+			goto signal;
+	}
+	return false;
+
+signal:
 	dma_fence_array_clear_pending_error(array);
 	return true;
 }
--- linux-qcom-6.8.0.orig/drivers/dma-buf/dma-fence-unwrap.c
+++ linux-qcom-6.8.0/drivers/dma-buf/dma-fence-unwrap.c
@@ -12,6 +12,7 @@
 #include <linux/dma-fence-chain.h>
 #include <linux/dma-fence-unwrap.h>
 #include <linux/slab.h>
+#include <linux/sort.h>
 
 /* Internal helper to start new array iteration, don't use directly */
 static struct dma_fence *
@@ -59,6 +60,25 @@
 }
 EXPORT_SYMBOL_GPL(dma_fence_unwrap_next);
 
+
+static int fence_cmp(const void *_a, const void *_b)
+{
+	struct dma_fence *a = *(struct dma_fence **)_a;
+	struct dma_fence *b = *(struct dma_fence **)_b;
+
+	if (a->context < b->context)
+		return -1;
+	else if (a->context > b->context)
+		return 1;
+
+	if (dma_fence_is_later(b, a))
+		return 1;
+	else if (dma_fence_is_later(a, b))
+		return -1;
+
+	return 0;
+}
+
 /* Implementation for the dma_fence_merge() marco, don't use directly */
 struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences,
 					   struct dma_fence **fences,
@@ -67,8 +87,7 @@
 	struct dma_fence_array *result;
 	struct dma_fence *tmp, **array;
 	ktime_t timestamp;
-	unsigned int i;
-	size_t count;
+	int i, j, count;
 
 	count = 0;
 	timestamp = ns_to_ktime(0);
@@ -96,78 +115,55 @@
 	if (!array)
 		return NULL;
 
-	/*
-	 * This trashes the input fence array and uses it as position for the
-	 * following merge loop. This works because the dma_fence_merge()
-	 * wrapper macro is creating this temporary array on the stack together
-	 * with the iterators.
-	 */
-	for (i = 0; i < num_fences; ++i)
-		fences[i] = dma_fence_unwrap_first(fences[i], &iter[i]);
-
 	count = 0;
-	do {
-		unsigned int sel;
-
-restart:
-		tmp = NULL;
-		for (i = 0; i < num_fences; ++i) {
-			struct dma_fence *next;
-
-			while (fences[i] && dma_fence_is_signaled(fences[i]))
-				fences[i] = dma_fence_unwrap_next(&iter[i]);
-
-			next = fences[i];
-			if (!next)
-				continue;
-
-			/*
-			 * We can't guarantee that inpute fences are ordered by
-			 * context, but it is still quite likely when this
-			 * function is used multiple times. So attempt to order
-			 * the fences by context as we pass over them and merge
-			 * fences with the same context.
-			 */
-			if (!tmp || tmp->context > next->context) {
-				tmp = next;
-				sel = i;
-
-			} else if (tmp->context < next->context) {
-				continue;
-
-			} else if (dma_fence_is_later(tmp, next)) {
-				fences[i] = dma_fence_unwrap_next(&iter[i]);
-				goto restart;
+	for (i = 0; i < num_fences; ++i) {
+		dma_fence_unwrap_for_each(tmp, &iter[i], fences[i]) {
+			if (!dma_fence_is_signaled(tmp)) {
+				array[count++] = dma_fence_get(tmp);
 			} else {
-				fences[sel] = dma_fence_unwrap_next(&iter[sel]);
-				goto restart;
+				ktime_t t = dma_fence_timestamp(tmp);
+
+				if (ktime_after(t, timestamp))
+					timestamp = t;
 			}
 		}
+	}
 
-		if (tmp) {
-			array[count++] = dma_fence_get(tmp);
-			fences[sel] = dma_fence_unwrap_next(&iter[sel]);
-		}
-	} while (tmp);
+	if (count == 0 || count == 1)
+		goto return_fastpath;
 
-	if (count == 0) {
-		tmp = dma_fence_allocate_private_stub(ktime_get());
-		goto return_tmp;
-	}
+	sort(array, count, sizeof(*array), fence_cmp, NULL);
 
-	if (count == 1) {
-		tmp = array[0];
-		goto return_tmp;
+	/*
+	 * Only keep the most recent fence for each context.
+	 */
+	j = 0;
+	for (i = 1; i < count; i++) {
+		if (array[i]->context == array[j]->context)
+			dma_fence_put(array[i]);
+		else
+			array[++j] = array[i];
 	}
+	count = ++j;
 
-	result = dma_fence_array_create(count, array,
-					dma_fence_context_alloc(1),
-					1, false);
-	if (!result) {
-		tmp = NULL;
-		goto return_tmp;
+	if (count > 1) {
+		result = dma_fence_array_create(count, array,
+						dma_fence_context_alloc(1),
+						1, false);
+		if (!result) {
+			for (i = 0; i < count; i++)
+				dma_fence_put(array[i]);
+			tmp = NULL;
+			goto return_tmp;
+		}
+		return &result->base;
 	}
-	return &result->base;
+
+return_fastpath:
+	if (count == 0)
+		tmp = dma_fence_allocate_private_stub(timestamp);
+	else
+		tmp = array[0];
 
 return_tmp:
 	kfree(array);
--- linux-qcom-6.8.0.orig/drivers/dma-buf/dma-heap.c
+++ linux-qcom-6.8.0/drivers/dma-buf/dma-heap.c
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2011 Google, Inc.
  * Copyright (C) 2019 Linaro Ltd.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/cdev.h>
@@ -12,6 +13,7 @@
 #include <linux/dma-buf.h>
 #include <linux/err.h>
 #include <linux/xarray.h>
+#include <linux/kref.h>
 #include <linux/list.h>
 #include <linux/slab.h>
 #include <linux/nospec.h>
@@ -31,6 +33,9 @@
  * @heap_devt		heap device node
  * @list		list head connecting to list of heaps
  * @heap_cdev		heap char device
+ * @heap_dev		heap device struct
+ * @minor:		heap device node minor number
+ * @refcount:		reference counter for this heap device
  *
  * Represents a heap of memory from which buffers can be made.
  */
@@ -41,6 +46,9 @@
 	dev_t heap_devt;
 	struct list_head list;
 	struct cdev heap_cdev;
+	int minor;
+	struct kref refcount;
+	struct device *heap_dev;
 };
 
 static LIST_HEAD(heap_list);
@@ -49,12 +57,15 @@
 static struct class *dma_heap_class;
 static DEFINE_XARRAY_ALLOC(dma_heap_minors);
 
-static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
-				 unsigned int fd_flags,
-				 unsigned int heap_flags)
+struct dma_buf *dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
+				      unsigned int fd_flags,
+				      unsigned int heap_flags)
 {
-	struct dma_buf *dmabuf;
-	int fd;
+	if (fd_flags & ~DMA_HEAP_VALID_FD_FLAGS)
+		return ERR_PTR(-EINVAL);
+
+	if (heap_flags & ~DMA_HEAP_VALID_HEAP_FLAGS)
+		return ERR_PTR(-EINVAL);
 
 	/*
 	 * Allocations from all heaps have to begin
@@ -62,9 +73,20 @@
 	 */
 	len = PAGE_ALIGN(len);
 	if (!len)
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
+
+	return heap->ops->allocate(heap, len, fd_flags, heap_flags);
+}
+EXPORT_SYMBOL_GPL(dma_heap_buffer_alloc);
+
+static int dma_heap_bufferfd_alloc(struct dma_heap *heap, size_t len,
+				   unsigned int fd_flags,
+				   unsigned int heap_flags)
+{
+	struct dma_buf *dmabuf;
+	int fd;
 
-	dmabuf = heap->ops->allocate(heap, len, fd_flags, heap_flags);
+	dmabuf = dma_heap_buffer_alloc(heap, len, fd_flags, heap_flags);
 	if (IS_ERR(dmabuf))
 		return PTR_ERR(dmabuf);
 
@@ -102,15 +124,9 @@
 	if (heap_allocation->fd)
 		return -EINVAL;
 
-	if (heap_allocation->fd_flags & ~DMA_HEAP_VALID_FD_FLAGS)
-		return -EINVAL;
-
-	if (heap_allocation->heap_flags & ~DMA_HEAP_VALID_HEAP_FLAGS)
-		return -EINVAL;
-
-	fd = dma_heap_buffer_alloc(heap, heap_allocation->len,
-				   heap_allocation->fd_flags,
-				   heap_allocation->heap_flags);
+	fd = dma_heap_bufferfd_alloc(heap, heap_allocation->len,
+				     heap_allocation->fd_flags,
+				     heap_allocation->heap_flags);
 	if (fd < 0)
 		return fd;
 
@@ -205,6 +221,18 @@
 }
 
 /**
+ * dma_heap_get_dev() - get device struct for the heap
+ * @heap: DMA-Heap to retrieve device struct from
+ *
+ * Returns:
+ * The device struct for the heap.
+ */
+struct device *dma_heap_get_dev(struct dma_heap *heap)
+{
+		return heap->heap_dev;
+}
+
+/**
  * dma_heap_get_name() - get heap name
  * @heap: DMA-Heap to retrieve private data for
  *
@@ -215,12 +243,11 @@
 {
 	return heap->name;
 }
+EXPORT_SYMBOL_GPL(dma_heap_get_name);
 
 struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
 {
 	struct dma_heap *heap, *h, *err_ret;
-	struct device *dev_ret;
-	unsigned int minor;
 	int ret;
 
 	if (!exp_info->name || !strcmp(exp_info->name, "")) {
@@ -237,12 +264,13 @@
 	if (!heap)
 		return ERR_PTR(-ENOMEM);
 
+	kref_init(&heap->refcount);
 	heap->name = exp_info->name;
 	heap->ops = exp_info->ops;
 	heap->priv = exp_info->priv;
 
 	/* Find unused minor number */
-	ret = xa_alloc(&dma_heap_minors, &minor, heap,
+	ret = xa_alloc(&dma_heap_minors, &heap->minor, heap,
 		       XA_LIMIT(0, NUM_HEAP_MINORS - 1), GFP_KERNEL);
 	if (ret < 0) {
 		pr_err("dma_heap: Unable to get minor number for heap\n");
@@ -251,7 +279,7 @@
 	}
 
 	/* Create device */
-	heap->heap_devt = MKDEV(MAJOR(dma_heap_devt), minor);
+	heap->heap_devt = MKDEV(MAJOR(dma_heap_devt), heap->minor);
 
 	cdev_init(&heap->heap_cdev, &dma_heap_fops);
 	ret = cdev_add(&heap->heap_cdev, heap->heap_devt, 1);
@@ -261,17 +289,20 @@
 		goto err1;
 	}
 
-	dev_ret = device_create(dma_heap_class,
-				NULL,
-				heap->heap_devt,
-				NULL,
-				heap->name);
-	if (IS_ERR(dev_ret)) {
+	heap->heap_dev = device_create(dma_heap_class,
+			NULL,
+			heap->heap_devt,
+			NULL,
+			heap->name);
+	if (IS_ERR(heap->heap_dev)) {
 		pr_err("dma_heap: Unable to create device\n");
-		err_ret = ERR_CAST(dev_ret);
+		err_ret = ERR_CAST(heap->heap_dev);
 		goto err2;
 	}
 
+	/* Make sure it doesn't disappear on us */
+	heap->heap_dev = get_device(heap->heap_dev);
+
 	mutex_lock(&heap_list_lock);
 	/* check the name is unique */
 	list_for_each_entry(h, &heap_list, list) {
@@ -295,11 +326,55 @@
 err2:
 	cdev_del(&heap->heap_cdev);
 err1:
-	xa_erase(&dma_heap_minors, minor);
+	xa_erase(&dma_heap_minors, heap->minor);
 err0:
 	kfree(heap);
 	return err_ret;
 }
+EXPORT_SYMBOL_GPL(dma_heap_add);
+
+struct dma_heap *dma_heap_find(const char *name)
+{
+	struct dma_heap *h;
+
+	mutex_lock(&heap_list_lock);
+	list_for_each_entry(h, &heap_list, list) {
+		if (!strcmp(h->name, name)) {
+			kref_get(&h->refcount);
+			mutex_unlock(&heap_list_lock);
+			return h;
+		}
+	}
+	mutex_unlock(&heap_list_lock);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(dma_heap_find);
+
+static void dma_heap_release(struct kref *ref)
+{
+	struct dma_heap *heap = container_of(ref, struct dma_heap, refcount);
+
+	/* Note, we already holding the heap_list_lock here */
+	list_del(&heap->list);
+
+	device_destroy(dma_heap_class, heap->heap_devt);
+	cdev_del(&heap->heap_cdev);
+	xa_erase(&dma_heap_minors, heap->minor);
+
+	kfree(heap);
+}
+
+void dma_heap_put(struct dma_heap *h)
+{
+	/*
+	 * Take the heap_list_lock now to avoid racing with code
+	 * scanning the list and then taking a kref.
+	 */
+	mutex_lock(&heap_list_lock);
+	kref_put(&h->refcount, dma_heap_release);
+	mutex_unlock(&heap_list_lock);
+}
+EXPORT_SYMBOL_GPL(dma_heap_put);
 
 static char *dma_heap_devnode(const struct device *dev, umode_t *mode)
 {
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/Kconfig
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/Kconfig
@@ -12,3 +12,67 @@
 	  Choose this option to enable dma-buf CMA heap. This heap is backed
 	  by the Contiguous Memory Allocator (CMA). If your system has these
 	  regions, you should say Y here.
+
+config QCOM_DMABUF_HEAPS
+	tristate "QCOM DMA-BUF Heaps"
+	depends on DMABUF_HEAPS
+	help
+	  Choose this option to build the dma-buf heap module. Other
+	  heaps can subsequently be compiled into this module by enabling
+	  the appropriate defconfig option.
+	  If in doubt, say M here.
+
+config QCOM_DMABUF_HEAPS_SYSTEM
+	bool "QCOM DMA-BUF System Heap"
+	depends on QCOM_DMABUF_HEAPS
+	help
+	  Choose this option to build the QCOM DMA-BUF system
+	  heap. This heap combines the built-in system heap
+	  along with other optimizatons. If in doubt, say Y
+	  here.
+
+config QCOM_DMABUF_HEAPS_PAGE_POOL_REFILL
+	bool "QCOM DMA-BUF Page Pool Refill"
+	depends on QCOM_DMABUF_HEAPS_SYSTEM
+	help
+	  Choose this option to enable the page pool auto refill
+	  feature for the system heap's page pools. When enabled,
+	  a thread is created which wakes up to refill the page pools
+	  when they fall below a particular threshold, which in turn
+	  results in smaller allocation latencies. If in doubt, say Y
+	  here.
+
+config QCOM_DMABUF_HEAPS_SYSTEM_SECURE
+	bool "QCOM DMA-BUF System Secure Heap"
+	depends on QCOM_DMABUF_HEAPS
+	depends on QCOM_DMABUF_HEAPS_SYSTEM
+	help
+	  Choose this option to build the QCOM DMA-BUF system
+	  secure heap. This heap, which combines the built-in
+	  system heap along with other optimizations, assigns
+	  memory that is secure by default. If in doubt, say Y
+	  here.
+
+config QCOM_DMABUF_HEAPS_SYSTEM_UNCACHED
+	bool "QCOM DMA-BUF Uncached System Heap"
+	depends on QCOM_DMABUF_HEAPS && QCOM_DMABUF_HEAPS_SYSTEM
+	help
+	  Choose this option to create an uncached QCOM DMA-BUF
+	  system heap. This heap is equivalent to our system heap,
+	  such that the memory is mapped as uncached. If in doubt,
+	  say Y here.
+
+config QCOM_DMABUF_HEAPS_CMA
+	bool "QCOM DMA-BUF CMA Heap"
+	depends on QCOM_DMABUF_HEAPS && DMA_CMA
+	help
+	  Choose this option to build the QCOM DMA-BUF CMA heap.
+	  If in doubt, say Y here.
+
+config QCOM_DMABUF_HEAPS_CARVEOUT
+	bool "QCOM dma-buf Carveout Heap"
+	depends on QCOM_DMABUF_HEAPS
+	depends on ARCH_SPARSEMEM_ENABLE
+	help
+	  Choose this option to build the QCOM DMA-BUF Carveout heap.
+	  If in doubt, say Y here.
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/Makefile
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/Makefile
@@ -1,3 +1,13 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_DMABUF_HEAPS_SYSTEM)	+= system_heap.o
 obj-$(CONFIG_DMABUF_HEAPS_CMA)		+= cma_heap.o
+obj-$(CONFIG_QCOM_DMABUF_HEAPS)		+= qcom_dma_heaps.o
+qcom_dma_heaps-y			:= qcom_dma_heap.o qcom_dt_parser.o qcom_sg_ops.o
+qcom_dma_heaps-$(CONFIG_QCOM_DMABUF_HEAPS_SYSTEM) += qcom_system_heap.o \
+						     qcom_dynamic_page_pool.o
+qcom_dma_heaps-$(CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_SECURE) += qcom_secure_system_heap.o \
+							    qcom_dynamic_page_pool.o \
+							    qcom_dma_heap_secure_utils.o
+qcom_dma_heaps-$(CONFIG_QCOM_DMABUF_HEAPS_CMA)	+= qcom_cma_heap.o
+qcom_dma_heaps-$(CONFIG_QCOM_DMABUF_HEAPS_CARVEOUT) += qcom_carveout_heap.o \
+						       qcom_dma_heap_secure_utils.o
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/cma_heap.c
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/cma_heap.c
@@ -165,7 +165,7 @@
 	struct vm_area_struct *vma = vmf->vma;
 	struct cma_heap_buffer *buffer = vma->vm_private_data;
 
-	if (vmf->pgoff > buffer->pagecount)
+	if (vmf->pgoff >= buffer->pagecount)
 		return VM_FAULT_SIGBUS;
 
 	return vmf_insert_pfn(vma, vmf->address, page_to_pfn(buffer->pages[vmf->pgoff]));
@@ -274,8 +274,8 @@
 
 static struct dma_buf *cma_heap_allocate(struct dma_heap *heap,
 					 unsigned long len,
-					 unsigned long fd_flags,
-					 unsigned long heap_flags)
+					 u32 fd_flags,
+					 u64 heap_flags)
 {
 	struct cma_heap *cma_heap = dma_heap_get_drvdata(heap);
 	struct cma_heap_buffer *buffer;
@@ -366,7 +366,14 @@
 	.allocate = cma_heap_allocate,
 };
 
-static int __add_cma_heap(struct cma *cma, void *data)
+/**
+ * cma_heap_add - adds a CMA heap to dmabuf heaps
+ * @cma:       pointer to the CMA pool to register the heap for
+ * @data:      unused
+ *
+ * Returns 0 on success. Else, returns errno.
+ */
+int cma_heap_add(struct cma *cma, void *data)
 {
 	struct cma_heap *cma_heap;
 	struct dma_heap_export_info exp_info;
@@ -390,6 +397,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(cma_heap_add);
 
 static int add_default_cma_heap(void)
 {
@@ -397,7 +405,7 @@
 	int ret = 0;
 
 	if (default_cma)
-		ret = __add_cma_heap(default_cma, NULL);
+		ret = cma_heap_add(default_cma, NULL);
 
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_carveout_heap.c
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_carveout_heap.c
@@ -0,0 +1,423 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DMA-BUF heap carveout heap allocator. Copied from
+ * drivers/staging/android/ion/heaps/ion_carveout_heap.c as of commit
+ * aeb022cc01ecc ("dma-heap: qcom: Change symbol names to let module be built
+ * in")
+ *
+ * Copyright (C) 2011 Google, Inc.
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/genalloc.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <soc/qcom/secure_buffer.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/list.h>
+#include <linux/dma-buf.h>
+#include <linux/dma-heap.h>
+#include <linux/qcom_dma_heap.h>
+
+#include "qcom_dma_heap_secure_utils.h"
+#include "qcom_sg_ops.h"
+#include "qcom_carveout_heap.h"
+
+#define CARVEOUT_ALLOCATE_FAIL -1
+
+
+/*
+ * @pool_refcount_priv -
+ *	Cookie set by carveout_heap_add_memory for use with its callbacks.
+ *	Cookie provider will call carveout_heap_remove_memory if refcount
+ *	reaches zero.
+ * @pool_refcount_get -
+ *	Function callback to Increase refcount. Returns 0
+ *	on success and fails if refcount is already zero.
+ * @pool_refcount_put - Function callback to decrease refcount.
+ */
+struct carveout_heap {
+	struct dma_heap *heap;
+	struct rw_semaphore mem_sem;
+	struct gen_pool *pool;
+	struct device *dev;
+	bool is_secure;
+	phys_addr_t base;
+};
+
+struct secure_carveout_heap {
+	u32 token;
+	struct carveout_heap carveout_heap;
+};
+
+static void sc_heap_free(struct qcom_sg_buffer *buffer);
+
+void __maybe_unused pages_sync_for_device(struct device *dev, struct page *page,
+			       size_t size, enum dma_data_direction dir)
+{
+	struct scatterlist sg;
+
+	sg_init_table(&sg, 1);
+	sg_set_page(&sg, page, size, 0);
+	/*
+	 * This is not correct - sg_dma_address needs a dma_addr_t that is valid
+	 * for the targeted device, but this works on the currently targeted
+	 * hardware.
+	 */
+	sg_dma_address(&sg) = page_to_phys(page);
+	dma_sync_sg_for_device(dev, &sg, 1, dir);
+}
+
+static phys_addr_t carveout_allocate(struct carveout_heap *carveout_heap,
+				     unsigned long size)
+{
+	unsigned long offset = CARVEOUT_ALLOCATE_FAIL;
+
+	down_read(&carveout_heap->mem_sem);
+	if (carveout_heap->pool) {
+		offset = gen_pool_alloc(carveout_heap->pool, size);
+		if (!offset) {
+			offset = CARVEOUT_ALLOCATE_FAIL;
+			goto unlock;
+		}
+	}
+
+unlock:
+	up_read(&carveout_heap->mem_sem);
+	return offset;
+}
+
+static void carveout_free(struct carveout_heap *carveout_heap,
+			  phys_addr_t addr, unsigned long size)
+{
+	if (addr == CARVEOUT_ALLOCATE_FAIL)
+		return;
+
+	down_read(&carveout_heap->mem_sem);
+	if (carveout_heap->pool)
+		gen_pool_free(carveout_heap->pool, addr, size);
+	up_read(&carveout_heap->mem_sem);
+}
+
+struct mem_buf_vmperm *
+carveout_setup_vmperm(struct carveout_heap *carveout_heap,
+			struct sg_table *sgt)
+{
+	struct secure_carveout_heap *sc_heap;
+	struct mem_buf_vmperm *vmperm;
+	int *vmids, *perms;
+	u32 nr;
+	int ret;
+
+	if (!carveout_heap->is_secure) {
+		vmperm = mem_buf_vmperm_alloc(sgt);
+		return vmperm;
+	}
+
+	sc_heap = container_of(carveout_heap,
+			struct secure_carveout_heap, carveout_heap);
+
+	ret = get_vmperm_from_ion_flags(sc_heap->token,
+			&vmids, &perms, &nr);
+	if (ret)
+		return ERR_PTR(ret);
+
+	vmperm = mem_buf_vmperm_alloc_staticvm(sgt, vmids, perms, nr);
+	kfree(vmids);
+	kfree(perms);
+
+	return vmperm;
+}
+
+static struct dma_buf *__carveout_heap_allocate(struct carveout_heap *carveout_heap,
+						unsigned long len,
+						u32 fd_flags,
+						u64 heap_flags,
+						void (*buffer_free)(struct qcom_sg_buffer *))
+{
+	struct sg_table *table;
+	struct qcom_sg_buffer *buffer;
+	phys_addr_t paddr;
+	int ret;
+	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+	struct dma_buf *dmabuf;
+
+	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
+	if (!buffer)
+		return ERR_PTR(-ENOMEM);
+
+	/* Initialize the buffer */
+	INIT_LIST_HEAD(&buffer->attachments);
+	mutex_init(&buffer->lock);
+	buffer->heap = carveout_heap->heap;
+	buffer->len = len;
+	buffer->free = buffer_free;
+	buffer->uncached = true;
+
+	table = &buffer->sg_table;
+	ret = sg_alloc_table(table, 1, GFP_KERNEL);
+	if (ret)
+		goto err_free;
+
+	paddr = carveout_allocate(carveout_heap, len);
+	if (paddr == CARVEOUT_ALLOCATE_FAIL) {
+		ret = -ENOMEM;
+		goto err_free_table;
+	}
+
+	sg_set_page(table->sgl, pfn_to_page(PFN_DOWN(paddr)), len, 0);
+
+	buffer->vmperm = carveout_setup_vmperm(carveout_heap, &buffer->sg_table);
+	if (IS_ERR(buffer->vmperm))
+		goto err_free_carveout;
+
+
+	/* Instantiate our dma_buf */
+	exp_info.exp_name = dma_heap_get_name(carveout_heap->heap);
+	exp_info.size = buffer->len;
+	exp_info.flags = fd_flags;
+	exp_info.priv = buffer;
+	dmabuf = qcom_dma_buf_export(&exp_info, &qcom_sg_buf_ops);
+	if (IS_ERR(dmabuf)) {
+		ret = PTR_ERR(dmabuf);
+		goto err_free_vmperm;
+	}
+
+	return dmabuf;
+
+err_free_vmperm:
+	mem_buf_vmperm_release(buffer->vmperm);
+err_free_carveout:
+	carveout_free(carveout_heap, paddr, len);
+err_free_table:
+	sg_free_table(table);
+err_free:
+	kfree(buffer);
+	return ERR_PTR(ret);
+}
+
+static int carveout_pages_zero(struct page *page, size_t size);
+
+static void carveout_heap_free(struct qcom_sg_buffer *buffer)
+{
+	struct carveout_heap *carveout_heap;
+	struct sg_table *table = &buffer->sg_table;
+	struct page *page = sg_page(table->sgl);
+	phys_addr_t paddr = page_to_phys(page);
+	struct device *dev;
+
+	carveout_heap = dma_heap_get_drvdata(buffer->heap);
+
+	dev = carveout_heap->dev;
+
+	carveout_pages_zero(page, buffer->len);
+	carveout_free(carveout_heap, paddr, buffer->len);
+	sg_free_table(table);
+	kfree(buffer);
+}
+
+
+static struct dma_buf *carveout_heap_allocate(struct dma_heap *heap,
+					      unsigned long len,
+					      u32 fd_flags,
+					      u64 heap_flags)
+{
+	struct carveout_heap *carveout_heap = dma_heap_get_drvdata(heap);
+
+	return __carveout_heap_allocate(carveout_heap, len, fd_flags,
+					heap_flags, carveout_heap_free);
+}
+
+static int carveout_pages_zero(struct page *page, size_t size)
+{
+	void __iomem *addr;
+
+	addr = ioremap_wc(page_to_phys(page), size);
+	if (!addr)
+		return -ENOMEM;
+	memset(addr, 0, size);
+	iounmap(addr);
+
+	return 0;
+}
+
+static int carveout_init_heap_memory(struct carveout_heap *co_heap,
+				     phys_addr_t base, ssize_t size)
+{
+	struct page *page = pfn_to_page(PFN_DOWN(base));
+	int ret = 0;
+
+	ret = carveout_pages_zero(page, size);
+	if (ret)
+		return ret;
+
+	co_heap->pool = gen_pool_create(PAGE_SHIFT, -1);
+	if (!co_heap->pool)
+		return -ENOMEM;
+
+	co_heap->base = base;
+	gen_pool_add(co_heap->pool, co_heap->base, size, -1);
+
+	return 0;
+}
+
+static int __carveout_heap_init(struct platform_heap *heap_data,
+				struct carveout_heap *carveout_heap)
+{
+	struct device *dev = heap_data->dev;
+	int ret = 0;
+
+	carveout_heap->dev = dev;
+	ret = carveout_init_heap_memory(carveout_heap,
+					heap_data->base,
+					heap_data->size);
+
+	init_rwsem(&carveout_heap->mem_sem);
+
+	return ret;
+}
+
+static const struct dma_heap_ops carveout_heap_ops = {
+	.allocate = carveout_heap_allocate,
+};
+
+static void carveout_heap_destroy(struct carveout_heap *heap);
+
+int qcom_carveout_heap_create(struct platform_heap *heap_data)
+{
+	struct dma_heap_export_info exp_info;
+	struct carveout_heap *carveout_heap;
+	int ret;
+
+	if (!heap_data->is_nomap) {
+		pr_err("carveout heap memory regions need to be created with no-map\n");
+		return -EINVAL;
+	}
+
+	carveout_heap = kzalloc(sizeof(*carveout_heap), GFP_KERNEL);
+	if (!carveout_heap)
+		return -ENOMEM;
+
+	ret = __carveout_heap_init(heap_data, carveout_heap);
+	if (ret)
+		goto err;
+
+	carveout_heap->is_secure = false;
+
+	exp_info.name = heap_data->name;
+	exp_info.ops = &carveout_heap_ops;
+	exp_info.priv = carveout_heap;
+
+	carveout_heap->heap = dma_heap_add(&exp_info);
+	if (IS_ERR(carveout_heap->heap)) {
+		ret = PTR_ERR(carveout_heap->heap);
+		goto destroy_heap;
+	}
+
+	return 0;
+
+destroy_heap:
+	carveout_heap_destroy(carveout_heap);
+err:
+	kfree(carveout_heap);
+
+	return ret;
+}
+
+static void carveout_heap_destroy(struct carveout_heap *carveout_heap)
+{
+	down_write(&carveout_heap->mem_sem);
+	if (carveout_heap->pool)
+		gen_pool_destroy(carveout_heap->pool);
+	up_write(&carveout_heap->mem_sem);
+	carveout_heap = NULL;
+}
+
+static struct dma_buf *sc_heap_allocate(struct dma_heap *heap,
+					unsigned long len,
+					u32 fd_flags,
+					u64 heap_flags)
+{
+	struct secure_carveout_heap *sc_heap;
+
+	sc_heap = dma_heap_get_drvdata(heap);
+	return  __carveout_heap_allocate(&sc_heap->carveout_heap, len,
+					 fd_flags, heap_flags, sc_heap_free);
+}
+
+static void sc_heap_free(struct qcom_sg_buffer *buffer)
+{
+	struct secure_carveout_heap *sc_heap;
+	struct sg_table *table = &buffer->sg_table;
+	struct page *page = sg_page(table->sgl);
+	phys_addr_t paddr = PFN_PHYS(page_to_pfn(page));
+
+	sc_heap = dma_heap_get_drvdata(buffer->heap);
+
+	if (qcom_is_buffer_hlos_accessible(sc_heap->token))
+		carveout_pages_zero(page, buffer->len);
+	carveout_free(&sc_heap->carveout_heap, paddr, buffer->len);
+	sg_free_table(table);
+	kfree(buffer);
+}
+
+static struct dma_heap_ops sc_heap_ops = {
+	.allocate = sc_heap_allocate,
+};
+
+int qcom_secure_carveout_heap_create(struct platform_heap *heap_data)
+{
+	struct dma_heap_export_info exp_info;
+	struct secure_carveout_heap *sc_heap;
+	int ret;
+
+	if (!heap_data->is_nomap) {
+		pr_err("secure carveout heap memory regions need to be created with no-map\n");
+		return -EINVAL;
+	}
+
+	sc_heap = kzalloc(sizeof(*sc_heap), GFP_KERNEL);
+	if (!sc_heap)
+		return -ENOMEM;
+
+	ret = __carveout_heap_init(heap_data, &sc_heap->carveout_heap);
+	if (ret)
+		goto err;
+
+	ret = hyp_assign_from_flags(heap_data->base, heap_data->size,
+				    heap_data->token);
+	if (ret) {
+		pr_err("secure_carveout_heap: Assign token 0x%x failed\n",
+		       heap_data->token);
+		goto destroy_heap;
+	}
+
+	sc_heap->token = heap_data->token;
+	sc_heap->carveout_heap.is_secure = true;
+
+	exp_info.name = heap_data->name;
+	exp_info.ops = &sc_heap_ops;
+	exp_info.priv = sc_heap;
+
+	sc_heap->carveout_heap.heap = dma_heap_add(&exp_info);
+	if (IS_ERR(sc_heap->carveout_heap.heap)) {
+		ret = PTR_ERR(sc_heap->carveout_heap.heap);
+		goto destroy_heap;
+	}
+
+	return 0;
+
+destroy_heap:
+	carveout_heap_destroy(&sc_heap->carveout_heap);
+err:
+	kfree(sc_heap);
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_carveout_heap.h
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_carveout_heap.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _QCOM_CARVEOUT_HEAP_H
+#define _QCOM_CARVEOUT_HEAP_H
+
+#include "qcom_dt_parser.h"
+
+#ifdef CONFIG_QCOM_DMABUF_HEAPS_CARVEOUT
+int qcom_secure_carveout_heap_create(struct platform_heap *heap_data);
+int qcom_carveout_heap_create(struct platform_heap *heap_data);
+#else
+static inline int qcom_secure_carveout_heap_create(struct platform_heap *heap_data)
+{
+	return -EINVAL;
+}
+static inline int qcom_carveout_heap_create(struct platform_heap *heap_data)
+{
+	return -EINVAL;
+}
+#endif
+
+#endif /* _QCOM_CARVEOUT_HEAP_H */
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_cma_heap.c
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_cma_heap.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DMABUF CMA heap exporter
+ * Copied from drivers/dma-buf/heaps/cma_heap.c as of commit b61614ec318a
+ * ("dma-buf: heaps: Add CMA heap to dmabuf heaps")
+ *
+ * Copyright (C) 2012, 2019 Linaro Ltd.
+ * Author: <benjamin.gaignard@linaro.org> for ST-Ericsson.
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/cma.h>
+#include <linux/device.h>
+#include <linux/dma-buf.h>
+#include <linux/dma-heap.h>
+#include <linux/dma-map-ops.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/scatterlist.h>
+#include <linux/sched/signal.h>
+#include <linux/list.h>
+
+#include "qcom_cma_heap.h"
+#include "qcom_sg_ops.h"
+
+struct cma_heap {
+	struct cma *cma;
+	/* max_align is in units of page_order, similar to CONFIG_CMA_ALIGNMENT */
+	u32 max_align;
+	bool uncached;
+};
+
+static void cma_heap_free(struct qcom_sg_buffer *buffer)
+{
+	struct cma_heap *cma_heap;
+	unsigned long nr_pages = buffer->len >> PAGE_SHIFT;
+	struct page *cma_pages = sg_page(buffer->sg_table.sgl);
+
+	cma_heap = dma_heap_get_drvdata(buffer->heap);
+
+	/* free page list */
+	sg_free_table(&buffer->sg_table);
+	/* release memory */
+	cma_release(cma_heap->cma, cma_pages, nr_pages);
+	kfree(buffer);
+}
+
+/* dmabuf heap CMA operations functions */
+struct dma_buf *cma_heap_allocate(struct dma_heap *heap,
+				  unsigned long len,
+				  u32 fd_flags,
+				  u64 heap_flags)
+{
+	struct cma_heap *cma_heap;
+	struct qcom_sg_buffer *helper_buffer;
+	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+	struct page *cma_pages;
+	size_t size = PAGE_ALIGN(len);
+	unsigned long nr_pages = size >> PAGE_SHIFT;
+	unsigned long align = get_order(size);
+	struct dma_buf *dmabuf;
+	int ret = -ENOMEM;
+
+	cma_heap = dma_heap_get_drvdata(heap);
+
+	if (align > cma_heap->max_align)
+		align = cma_heap->max_align;
+
+	helper_buffer = kzalloc(sizeof(*helper_buffer), GFP_KERNEL);
+	if (!helper_buffer)
+		return ERR_PTR(-ENOMEM);
+
+	helper_buffer->heap = heap;
+	INIT_LIST_HEAD(&helper_buffer->attachments);
+	mutex_init(&helper_buffer->lock);
+	helper_buffer->len = size;
+	helper_buffer->uncached = cma_heap->uncached;
+	helper_buffer->free = cma_heap_free;
+
+	cma_pages = cma_alloc(cma_heap->cma, nr_pages, align, false);
+	if (!cma_pages)
+		goto free_buf;
+
+	if (PageHighMem(cma_pages)) {
+		unsigned long nr_clear_pages = nr_pages;
+		struct page *page = cma_pages;
+
+		while (nr_clear_pages > 0) {
+			void *vaddr = kmap_local_page(page);
+
+			memset(vaddr, 0, PAGE_SIZE);
+			kunmap_local(vaddr);
+			/*
+			 * Avoid wasting time zeroing memory if the process
+			 * has been killed by SIGKILL
+			 */
+			if (fatal_signal_pending(current))
+				goto free_cma;
+
+			page++;
+			nr_clear_pages--;
+		}
+	} else {
+		memset(page_address(cma_pages), 0, size);
+	}
+
+	ret = sg_alloc_table(&helper_buffer->sg_table, 1, GFP_KERNEL);
+	if (ret)
+		goto free_cma;
+
+	sg_set_page(helper_buffer->sg_table.sgl, cma_pages, size, 0);
+
+	helper_buffer->vmperm = mem_buf_vmperm_alloc(&helper_buffer->sg_table);
+	if (IS_ERR(helper_buffer->vmperm))
+		goto free_sgtable;
+
+	if (helper_buffer->uncached) {
+		dma_map_sgtable(dma_heap_get_dev(heap), &helper_buffer->sg_table,
+				DMA_BIDIRECTIONAL, 0);
+		dma_unmap_sgtable(dma_heap_get_dev(heap), &helper_buffer->sg_table,
+				  DMA_BIDIRECTIONAL, 0);
+	}
+
+	/* create the dmabuf */
+	exp_info.exp_name = dma_heap_get_name(heap);
+	exp_info.size = helper_buffer->len;
+	exp_info.flags = fd_flags;
+	exp_info.priv = helper_buffer;
+	dmabuf = qcom_dma_buf_export(&exp_info, &qcom_sg_buf_ops);
+	if (IS_ERR(dmabuf)) {
+		ret = PTR_ERR(dmabuf);
+		goto vmperm_release;
+	}
+
+	return dmabuf;
+
+vmperm_release:
+	mem_buf_vmperm_release(helper_buffer->vmperm);
+free_sgtable:
+	sg_free_table(&helper_buffer->sg_table);
+free_cma:
+	cma_release(cma_heap->cma, cma_pages, nr_pages);
+free_buf:
+	kfree(helper_buffer);
+	return ERR_PTR(ret);
+}
+
+static const struct dma_heap_ops cma_heap_ops = {
+	.allocate = cma_heap_allocate,
+};
+
+static int __add_cma_heap(struct platform_heap *heap_data, void *data)
+{
+	struct cma_heap *cma_heap;
+	struct dma_heap_export_info exp_info;
+	struct dma_heap *heap;
+
+	if (!heap_data->dev->cma_area) {
+		pr_err("%s: CMA area for device uninitialized!\n", __func__);
+		return -EINVAL;
+	}
+
+	cma_heap = kzalloc(sizeof(*cma_heap), GFP_KERNEL);
+	if (!cma_heap)
+		return -ENOMEM;
+
+	cma_heap->cma = heap_data->dev->cma_area;
+	cma_heap->max_align = CONFIG_CMA_ALIGNMENT;
+	if (heap_data->max_align)
+		cma_heap->max_align = heap_data->max_align;
+	cma_heap->uncached = heap_data->is_uncached;
+
+	exp_info.name = heap_data->name;
+	exp_info.ops = &cma_heap_ops;
+	exp_info.priv = cma_heap;
+
+	heap = dma_heap_add(&exp_info);
+	if (IS_ERR(heap)) {
+		int ret = PTR_ERR(heap);
+
+		kfree(cma_heap);
+		return ret;
+	}
+
+	if (cma_heap->uncached)
+		dma_coerce_mask_and_coherent(dma_heap_get_dev(heap),
+					     DMA_BIT_MASK(64));
+
+	return 0;
+}
+
+int qcom_add_cma_heap(struct platform_heap *heap_data)
+{
+	return __add_cma_heap(heap_data, NULL);
+}
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_cma_heap.h
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_cma_heap.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _QCOM_CMA_HEAP_H
+#define _QCOM_CMA_HEAP_H
+
+#include "qcom_dt_parser.h"
+
+#ifdef CONFIG_QCOM_DMABUF_HEAPS_CMA
+int qcom_add_cma_heap(struct platform_heap *heap_data);
+#else
+static int qcom_add_cma_heap(struct platform_heap *heap_data)
+{
+	return 1;
+}
+#endif
+
+#endif /* _QCOM_CMA_HEAP_H */
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_dma_heap.c
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_dma_heap.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+
+#include <linux/qcom_dma_heap.h>
+#include "qcom_cma_heap.h"
+#include "qcom_dt_parser.h"
+#include "qcom_system_heap.h"
+#include "qcom_carveout_heap.h"
+#include "qcom_secure_system_heap.h"
+#include "qcom_dma_heap_priv.h"
+
+/*
+ * We cache the file ops used by DMA-BUFs so that a user with a struct file
+ * pointer can determine if that file is for a DMA-BUF. We can't initialize
+ * the pointer here at compile time as ERR_PTR() evaluates to a function.
+ */
+#define FOPS_INIT_VAL ERR_PTR(-EINVAL)
+static const struct file_operations *dma_buf_cached_fops;
+
+static int qcom_dma_heap_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	int i;
+	struct platform_data *heaps;
+
+	qcom_system_heap_create("qcom,system", NULL, false);
+#ifdef CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_UNCACHED
+	qcom_system_heap_create("qcom,system-uncached", NULL, true);
+#endif
+	qcom_secure_system_heap_create("qcom,secure-pixel", NULL,
+				       QCOM_DMA_HEAP_FLAG_CP_PIXEL);
+	qcom_secure_system_heap_create("qcom,secure-non-pixel", NULL,
+				       QCOM_DMA_HEAP_FLAG_CP_NON_PIXEL);
+	heaps = parse_heap_dt(pdev);
+	if (IS_ERR_OR_NULL(heaps))
+		return PTR_ERR(heaps);
+
+	for (i = 0; i < heaps->nr; i++) {
+		struct platform_heap *heap_data = &heaps->heaps[i];
+
+		switch (heap_data->type) {
+#ifdef CONFIG_QCOM_DMABUF_HEAPS_CARVEOUT
+		case HEAP_TYPE_CARVEOUT:
+			ret = qcom_carveout_heap_create(heap_data);
+			break;
+#endif
+		case HEAP_TYPE_CMA:
+			ret = qcom_add_cma_heap(heap_data);
+			break;
+		default:
+			pr_err("%s: Unknown heap type %u\n", __func__, heap_data->type);
+			break;
+		}
+
+		if (ret)
+			pr_err("%s: DMA-BUF Heap: Failed to create %s, error is %d\n",
+			       __func__, heap_data->name, ret);
+		else
+			pr_info("%s: DMA-BUF Heap: Created %s\n", __func__,
+				heap_data->name);
+	}
+
+	free_pdata(heaps);
+
+	dma_buf_cached_fops = FOPS_INIT_VAL;
+
+	return ret;
+}
+
+void qcom_store_dma_buf_fops(struct file *file)
+{
+	if (dma_buf_cached_fops == FOPS_INIT_VAL)
+		dma_buf_cached_fops = file->f_op;
+}
+EXPORT_SYMBOL_GPL(qcom_store_dma_buf_fops);
+
+bool qcom_is_dma_buf_file(struct file *file)
+{
+	return file->f_op == dma_buf_cached_fops;
+}
+EXPORT_SYMBOL_GPL(qcom_is_dma_buf_file);
+
+static const struct of_device_id qcom_dma_heap_match_table[] = {
+	{.compatible = "qcom,dma-heaps"},
+	{},
+};
+
+static struct platform_driver qcom_dma_heap_driver = {
+	.probe = qcom_dma_heap_probe,
+	.driver = {
+		.name = "qcom-dma-heap",
+		.of_match_table = qcom_dma_heap_match_table,
+	},
+};
+
+static int __init init_heap_driver(void)
+{
+	return platform_driver_register(&qcom_dma_heap_driver);
+}
+module_init(init_heap_driver);
+
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_dma_heap_priv.h
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_dma_heap_priv.h
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2011 Google, Inc.
+ * Copyright (C) 2019 Linaro Ltd.
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _QCOM_DMA_HEAP_PRIV_H
+#define _QCOM_DMA_HEAP_PRIV_H
+
+#include <linux/dma-heap.h>
+#include <linux/list.h>
+#include <linux/fs.h>
+
+#include <linux/mem-buf-exporter.h>
+
+void qcom_store_dma_buf_fops(struct file *file);
+
+static inline struct dma_buf *qcom_dma_buf_export(struct dma_buf_export_info *exp_info,
+						  struct mem_buf_dma_buf_ops *ops)
+{
+	struct dma_buf *dmabuf;
+
+	dmabuf = mem_buf_dma_buf_export(exp_info, ops);
+	if (!IS_ERR(dmabuf))
+		qcom_store_dma_buf_fops(dmabuf->file);
+
+	return dmabuf;
+}
+
+/**
+ * struct heap_helper_buffer - helper buffer metadata
+ * @heap:		back pointer to the heap the buffer came from
+ * @dmabuf:		backing dma-buf for this buffer
+ * @size:		size of the buffer
+ * @priv_virt		pointer to heap specific private value
+ * @lock		mutext to protect the data in this structure
+ * @vmap_cnt		count of vmap references on the buffer
+ * @vaddr		vmap'ed virtual address
+ * @pagecount		number of pages in the buffer
+ * @pages		list of page pointers
+ * @attachments		list of device attachments
+ *
+ * @free		heap callback to free the buffer
+ */
+struct heap_helper_buffer {
+	struct dma_heap *heap;
+	struct dma_buf *dmabuf;
+	size_t size;
+
+	void *priv_virt;
+	struct mutex lock;
+	int vmap_cnt;
+	void *vaddr;
+	pgoff_t pagecount;
+	struct page **pages;
+	struct list_head attachments;
+
+	void (*free)(struct heap_helper_buffer *buffer);
+};
+
+#endif /* _QCOM_DMA_HEAP_PRIV_H */
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_dma_heap_secure_utils.c
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_dma_heap_secure_utils.c
@@ -0,0 +1,287 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/slab.h>
+#include <soc/qcom/secure_buffer.h>
+#include <linux/qcom_dma_heap.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+
+int get_secure_vmid(unsigned long flags)
+{
+	if (flags & QCOM_DMA_HEAP_FLAG_CP_TZ)
+		return VMID_TZ;
+	if (flags & QCOM_DMA_HEAP_FLAG_CP_TOUCH)
+		return VMID_CP_TOUCH;
+	if (flags & QCOM_DMA_HEAP_FLAG_CP_BITSTREAM)
+		return VMID_CP_BITSTREAM;
+	if (flags & QCOM_DMA_HEAP_FLAG_CP_PIXEL)
+		return VMID_CP_PIXEL;
+	if (flags & QCOM_DMA_HEAP_FLAG_CP_NON_PIXEL)
+		return VMID_CP_NON_PIXEL;
+	if (flags & QCOM_DMA_HEAP_FLAG_CP_CAMERA)
+		return VMID_CP_CAMERA;
+	if (flags & QCOM_DMA_HEAP_FLAG_CP_SEC_DISPLAY)
+		return VMID_CP_SEC_DISPLAY;
+	if (flags & QCOM_DMA_HEAP_FLAG_CP_APP)
+		return VMID_CP_APP;
+	if (flags & QCOM_DMA_HEAP_FLAG_CP_CAMERA_PREVIEW)
+		return VMID_CP_CAMERA_PREVIEW;
+	if (flags & QCOM_DMA_HEAP_FLAG_CP_SPSS_SP)
+		return VMID_CP_SPSS_SP;
+	if (flags & QCOM_DMA_HEAP_FLAG_CP_SPSS_SP_SHARED)
+		return VMID_CP_SPSS_SP_SHARED;
+	if (flags & QCOM_DMA_HEAP_FLAG_CP_SPSS_HLOS_SHARED)
+		return VMID_CP_SPSS_HLOS_SHARED;
+	if (flags & QCOM_DMA_HEAP_FLAG_CP_CDSP)
+		return VMID_CP_CDSP;
+	if (flags & QCOM_DMA_HEAP_FLAG_CP_MSS_MSA)
+		return VMID_MSS_MSA;
+
+	return -EINVAL;
+}
+
+static unsigned int count_set_bits(unsigned long val)
+{
+	return ((unsigned int)bitmap_weight(&val, BITS_PER_LONG));
+}
+
+bool qcom_is_buffer_hlos_accessible(unsigned long flags)
+{
+	if (!(flags & QCOM_DMA_HEAP_FLAG_CP_HLOS) &&
+	    !(flags & QCOM_DMA_HEAP_FLAG_CP_SPSS_HLOS_SHARED))
+		return false;
+
+	return true;
+}
+
+static int get_vmid(unsigned long flags)
+{
+	int vmid;
+
+	vmid = get_secure_vmid(flags);
+	if (vmid < 0) {
+		if (flags & QCOM_DMA_HEAP_FLAG_CP_HLOS)
+			vmid = VMID_HLOS;
+	}
+	return vmid;
+}
+
+static int populate_vm_list(unsigned long flags, unsigned int *vm_list,
+			 int nelems)
+{
+	unsigned int itr = 0;
+	int vmid;
+
+	flags = flags & QCOM_DMA_HEAP_FLAGS_CP_MASK;
+	if (!flags)
+		return -EINVAL;
+
+	for_each_set_bit(itr, &flags, BITS_PER_LONG) {
+		vmid = get_vmid(0x1UL << itr);
+		if (vmid < 0 || !nelems)
+			return -EINVAL;
+
+		vm_list[nelems - 1] = vmid;
+		nelems--;
+	}
+	return 0;
+}
+
+static int hyp_unassign_sg(struct sg_table *sgt, int *source_vm_list,
+		int source_nelems, bool clear_page_private)
+{
+	u32 dest_vmid = VMID_HLOS;
+	u32 dest_perms = PERM_READ | PERM_WRITE | PERM_EXEC;
+	struct scatterlist *sg;
+	int ret, i;
+
+	if (source_nelems <= 0) {
+		pr_err("%s: source_nelems invalid\n",
+				__func__);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = hyp_assign_table(sgt, source_vm_list, source_nelems, &dest_vmid,
+			&dest_perms, 1);
+	if (ret)
+		goto out;
+
+	if (clear_page_private)
+		for_each_sg(sgt->sgl, sg, sgt->nents, i)
+			ClearPagePrivate(sg_page(sg));
+out:
+	return ret;
+}
+
+static int hyp_assign_sg(struct sg_table *sgt, int *dest_vm_list,
+		int dest_nelems, bool set_page_private)
+{
+	u32 source_vmid = VMID_HLOS;
+	struct scatterlist *sg;
+	int *dest_perms;
+	int ret, i;
+
+	if (dest_nelems <= 0) {
+		pr_err("%s: dest_nelems invalid\n",
+				__func__);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	dest_perms = kcalloc(dest_nelems, sizeof(*dest_perms), GFP_KERNEL);
+	if (!dest_perms) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < dest_nelems; i++)
+		dest_perms[i] = msm_secure_get_vmid_perms(dest_vm_list[i]);
+
+	ret = hyp_assign_table(sgt, &source_vmid, 1,
+			dest_vm_list, dest_perms, dest_nelems);
+
+	if (ret) {
+		pr_err("%s: Assign call failed\n",
+				__func__);
+		goto out_free_dest;
+	}
+	if (set_page_private)
+		for_each_sg(sgt->sgl, sg, sgt->nents, i)
+			SetPagePrivate(sg_page(sg));
+
+out_free_dest:
+	kfree(dest_perms);
+out:
+	return ret;
+}
+
+int hyp_unassign_sg_from_flags(struct sg_table *sgt, unsigned long flags,
+			       bool set_page_private)
+{
+	int ret;
+	int *source_vm_list;
+	int source_nelems;
+
+	source_nelems = count_set_bits(flags & QCOM_DMA_HEAP_FLAGS_CP_MASK);
+	source_vm_list = kcalloc(source_nelems, sizeof(*source_vm_list),
+				 GFP_KERNEL);
+	if (!source_vm_list)
+		return -ENOMEM;
+	ret = populate_vm_list(flags, source_vm_list, source_nelems);
+	if (ret) {
+		pr_err("%s: Failed to get secure vmids\n", __func__);
+		goto out_free_source;
+	}
+
+	ret = hyp_unassign_sg(sgt, source_vm_list, source_nelems,
+				  set_page_private);
+
+out_free_source:
+	kfree(source_vm_list);
+	return ret;
+}
+
+int hyp_assign_sg_from_flags(struct sg_table *sgt, unsigned long flags,
+			     bool set_page_private)
+{
+	int ret;
+	int *dest_vm_list = NULL;
+	int dest_nelems;
+
+	dest_nelems = count_set_bits(flags & QCOM_DMA_HEAP_FLAGS_CP_MASK);
+	dest_vm_list = kcalloc(dest_nelems, sizeof(*dest_vm_list), GFP_KERNEL);
+	if (!dest_vm_list) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = populate_vm_list(flags, dest_vm_list, dest_nelems);
+	if (ret) {
+		pr_err("%s: Failed to get secure vmid(s)\n", __func__);
+		goto out_free_dest_vm;
+	}
+
+	ret = hyp_assign_sg(sgt, dest_vm_list, dest_nelems,
+				set_page_private);
+
+out_free_dest_vm:
+	kfree(dest_vm_list);
+out:
+	return ret;
+}
+
+int get_vmperm_from_ion_flags(unsigned long flags, int **_vmids,
+			int **_perms, u32 *_nr)
+{
+	int *vmids, *modes;
+	u32 nr, i;
+
+	if (!_vmids || !_perms || !_nr)
+		return -EINVAL;
+
+	nr = count_set_bits(flags);
+	vmids = kcalloc(nr, sizeof(*vmids), GFP_KERNEL);
+	if (!vmids)
+		return -ENOMEM;
+
+	modes = kcalloc(nr, sizeof(*modes), GFP_KERNEL);
+	if (!modes) {
+		kfree(vmids);
+		return -ENOMEM;
+	}
+
+	if ((flags & ~QCOM_DMA_HEAP_FLAGS_CP_MASK) ||
+	    populate_vm_list(flags, vmids, nr)) {
+		pr_err("%s: Failed to parse secure flags 0x%lx\n", __func__,
+		       flags);
+		kfree(modes);
+		kfree(vmids);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < nr; i++)
+		modes[i] = msm_secure_get_vmid_perms(vmids[i]);
+
+	*_vmids = vmids;
+	*_perms = modes;
+	*_nr = nr;
+	return 0;
+}
+
+int hyp_assign_from_flags(u64 base, u64 size, unsigned long flags)
+{
+	int *vmids, *modes;
+	u32 nr;
+	u64 src_vm = BIT(QCOM_SCM_VMID_HLOS);
+	struct qcom_scm_vmperm *newvm;
+	int ret;
+	int i;
+
+	ret = get_vmperm_from_ion_flags(flags, &vmids, &modes, &nr);
+	if (ret)
+		return ret;
+
+	newvm = kcalloc(nr, sizeof(struct qcom_scm_vmperm), GFP_KERNEL);
+	if (!newvm) {
+		ret = -ENOMEM;
+		goto kcalloc_fail;
+	}
+	for (i = 0; i < nr; i++) {
+		newvm[i].vmid = vmids[i];
+		newvm[i].perm = modes[i];
+	}
+	ret = qcom_scm_assign_mem(base, size, &src_vm, newvm, nr);
+	if (ret)
+		pr_err("%s: Assign call failed, flags 0x%lx\n", __func__,
+		       flags);
+
+	kfree(newvm);
+kcalloc_fail:
+	kfree(modes);
+	kfree(vmids);
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_dma_heap_secure_utils.h
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_dma_heap_secure_utils.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _QCOM_DMA_HEAP_SECURE_UTILS_H
+#define _QCOM_DMA_HEAP_SECURE_UTILS_H
+
+int hyp_assign_sg_from_flags(struct sg_table *sgt, unsigned long flags,
+			     bool set_page_private);
+
+int hyp_unassign_sg_from_flags(struct sg_table *sgt, unsigned long flags,
+			       bool set_page_private);
+
+/*
+ * This function handles conversion from the legacy ion flag based interface
+ * to a precise list of vmids and permissions.
+ */
+int get_vmperm_from_ion_flags(unsigned long flags, int **vmids, int **perms, u32 *nr);
+int hyp_assign_from_flags(u64 base, u64 size, unsigned long flags);
+bool qcom_is_buffer_hlos_accessible(unsigned long flags);
+int get_secure_vmid(unsigned long flags);
+
+#endif /* _QCOM_DMA_HEAP_SECURE_UTILS_H */
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_dt_parser.c
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_dt_parser.c
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_reserved_mem.h>
+
+#include <linux/qcom_dma_heap.h>
+#include "qcom_dt_parser.h"
+
+#ifdef CONFIG_PANIC_ON_QCOM_DMA_HEAPS_FAILURE
+#define QCOM_DMA_HEAP_WARN(fmt...) panic(fmt)
+#else /* CONFIG_PANIC_ON_QCOM_DMA_HEAPS_FAILURE */
+#define QCOM_DMA_HEAP_WARN(fmt...) WARN(1, fmt)
+#endif /* CONFIG_PANIC_ON_QCOM_DMA_HEAPS_FAILURE */
+
+static int populate_heap(struct device_node *node,
+			 struct platform_heap *heap)
+{
+	int ret;
+
+	/* Mandatory properties */
+	ret = of_property_read_string(node, "qcom,dma-heap-name", &heap->name);
+	if (ret)
+		goto err;
+
+	ret = of_property_read_u32(node, "qcom,dma-heap-type", &heap->type);
+	if (ret) {
+		pr_err("Reading %s property in node %s failed with err %d.\n",
+		       "qcom,dma-heap-type", of_node_full_name(node), ret);
+		goto err;
+	}
+
+	/* Optional properties */
+	heap->is_uncached = of_property_read_bool(node, "qcom,uncached-heap");
+
+	ret = of_property_read_u32(node, "qcom,token", &heap->token);
+	if (ret && ret != -EINVAL)
+		goto err;
+
+	ret = of_property_read_u32(node, "qcom,max-align", &heap->max_align);
+	if (ret && ret != -EINVAL)
+		goto err;
+
+	return 0;
+
+err:
+	if (ret)
+		QCOM_DMA_HEAP_WARN("%s: Unable to populate heap %s, err: %d\n",
+				   __func__, of_node_full_name(node), ret);
+	return ret;
+}
+
+void free_pdata(const struct platform_data *pdata)
+{
+	kfree(pdata->heaps);
+	kfree(pdata);
+}
+
+static int heap_dt_init(struct device_node *mem_node,
+			struct platform_heap *heap)
+{
+	const __be32 *basep;
+	u64 base, size;
+	struct device *dev = heap->dev;
+	struct reserved_mem *rmem;
+	int ret = 0;
+
+
+	rmem = of_reserved_mem_lookup(mem_node);
+
+	if (!rmem) {
+		dev_err(dev, "Failed to find reserved memory region\n");
+		return -EINVAL;
+	}
+
+	/*
+	 * We only need to call this when the memory-region is managed by
+	 * a reserved memory region driver (e.g. CMA, coherent, etc). In that
+	 * case, they will have ops for device specific initialization for
+	 * the memory region. Otherwise, we have a pure carveout, which needs
+	 * not be initialized.
+	 */
+	if (rmem->ops) {
+		ret = of_reserved_mem_device_init_by_idx(dev, dev->of_node, 0);
+		if (ret) {
+			dev_err(dev,
+				"Failed to initialize memory region rc: %d\n",
+				ret);
+			return ret;
+		}
+	}
+
+	basep = of_get_address(mem_node, 0, &size, NULL);
+	if (basep) {
+		base = of_translate_address(mem_node, basep);
+		if (base != OF_BAD_ADDR) {
+			heap->base = base;
+			heap->size = size;
+		} else {
+			ret = -EINVAL;
+			dev_err(heap->dev,
+				"Failed to get heap base/size\n");
+			of_reserved_mem_device_release(dev);
+		}
+	}
+	heap->is_nomap =  of_property_read_bool(mem_node, "no-map");
+
+	return ret;
+}
+
+static void release_reserved_memory_regions(struct platform_heap *heaps,
+					    int idx)
+{
+	struct device *dev;
+	struct device_node *node, *mem_node;
+
+	for (idx = idx - 1; idx >= 0; idx--) {
+		dev = heaps[idx].dev;
+		node = dev->of_node;
+		mem_node = of_parse_phandle(node, "memory-region", 0);
+
+		if (mem_node)
+			of_reserved_mem_device_release(dev);
+
+		of_node_put(mem_node);
+	}
+}
+
+struct platform_data *parse_heap_dt(struct platform_device *pdev)
+{
+	struct platform_data *pdata = NULL;
+	struct device_node *node;
+	struct device_node *mem_node;
+	struct platform_device *new_dev = NULL;
+	const struct device_node *dt_node = pdev->dev.of_node;
+	int ret;
+	int idx = 0;
+
+	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return ERR_PTR(-ENOMEM);
+
+	for_each_available_child_of_node(dt_node, node)
+		pdata->nr++;
+
+	/*
+	 * No heaps defined in the devicetree. However, there may be other
+	 * heaps (e.g. system heaps) that do not need to be defined in the
+	 * devicetree.
+	 */
+	if (!pdata->nr)
+		goto out;
+
+	pdata->heaps = kcalloc(pdata->nr, sizeof(*pdata->heaps), GFP_KERNEL);
+	if (!pdata->heaps) {
+		kfree(pdata);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	for_each_available_child_of_node(dt_node, node) {
+		new_dev = of_platform_device_create(node, NULL, &pdev->dev);
+		if (!new_dev) {
+			pr_err("Failed to create device %s\n", node->name);
+			ret = -EINVAL;
+			goto free_heaps;
+		}
+		of_dma_configure(&new_dev->dev, node, true);
+
+		pdata->heaps[idx].dev = &new_dev->dev;
+
+		ret = populate_heap(node, &pdata->heaps[idx]);
+		if (ret)
+			goto free_heaps;
+
+		mem_node = of_parse_phandle(node, "memory-region", 0);
+		if (mem_node) {
+			ret = heap_dt_init(mem_node, &pdata->heaps[idx]);
+			if (ret)
+				goto free_heaps;
+
+			of_node_put(mem_node);
+		}
+
+		++idx;
+	}
+
+out:
+	return pdata;
+
+free_heaps:
+	of_node_put(node);
+	release_reserved_memory_regions(pdata->heaps, idx);
+	free_pdata(pdata);
+	return ERR_PTR(ret);
+}
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_dt_parser.h
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_dt_parser.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _QCOM_DT_PARSER_H
+#define _QCOM_DT_PARSER_H
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+
+/**
+ * struct platform_heap - defines a heap in the given platform
+ * @type:	type of the heap
+ * @name:	used for debug purposes
+ * @base:	base address of heap in physical memory if applicable
+ * @size:	size of the heap in bytes if applicable
+ * @dev:	the device associated with the heap's DT node
+ * @is_dynamic:	indicates if memory can be added or removed from carveout heaps
+ * is_nomap:	indicates if this heap is assosicated with a memory region which is
+ *		which has no-map property.
+ * is_uncached:	indicates if this heap provides uncached memory or not
+ * @token:	the end points to which memory for secure carveout memory is
+ *		assigned to
+ * @max_align:  page order of the maximum alignment. Used by cma heap.
+ *
+ * Provided by the board file.
+ */
+struct platform_heap {
+	u32 type;
+	const char *name;
+	phys_addr_t base;
+	size_t size;
+	struct device *dev;
+	bool is_uncached;
+	bool is_nomap;
+	u32 token;
+	u32 max_align;
+};
+
+/**
+ * struct platform_data - array of platform heaps passed from board file
+ * @nr:    number of structures in the array
+ * @heaps: array of platform_heap structions
+ *
+ * Provided by the board file in the form of platform data to a platform device.
+ */
+struct platform_data {
+	int nr;
+	struct platform_heap *heaps;
+};
+
+struct platform_data *parse_heap_dt(struct platform_device *pdev);
+void free_pdata(const struct platform_data *pdata);
+
+#endif /* _QCOM_DT_PARSER_H */
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_dynamic_page_pool.c
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_dynamic_page_pool.c
@@ -0,0 +1,336 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Dynamic page pool system
+ *
+ * Taken from:
+ * mm/dynamic_page_pool.c
+ * Git-repo: https://git.linaro.org/people/john.stultz/android-dev.git
+ * Branch: dma-buf-heap-perf
+ * Git-commit: 458ea8030852755867bdc0384aa40f97aba7a572
+ *
+ * Based on the ION page pool code
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/swap.h>
+#include <linux/spinlock.h>
+#include <linux/sched/signal.h>
+#include <uapi/linux/sched/types.h>
+
+#include "qcom_dynamic_page_pool.h"
+
+static LIST_HEAD(pool_list);
+static DEFINE_MUTEX(pool_list_lock);
+
+void dynamic_page_pool_add(struct dynamic_page_pool *pool, struct page *page)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pool->lock, flags);
+	if (PageHighMem(page)) {
+		list_add_tail(&page->lru, &pool->high_items);
+		pool->high_count++;
+	} else {
+		list_add_tail(&page->lru, &pool->low_items);
+		pool->low_count++;
+	}
+
+	atomic_inc(&pool->count);
+	mod_node_page_state(page_pgdat(page), NR_KERNEL_MISC_RECLAIMABLE,
+			    1 << pool->order);
+	spin_unlock_irqrestore(&pool->lock, flags);
+}
+
+struct page *dynamic_page_pool_remove(struct dynamic_page_pool *pool, bool high)
+{
+	struct page *page;
+
+	if (high) {
+		BUG_ON(!pool->high_count);
+		page = list_first_entry(&pool->high_items, struct page, lru);
+		pool->high_count--;
+	} else {
+		BUG_ON(!pool->low_count);
+		page = list_first_entry(&pool->low_items, struct page, lru);
+		pool->low_count--;
+	}
+
+	atomic_dec(&pool->count);
+	list_del(&page->lru);
+	mod_node_page_state(page_pgdat(page), NR_KERNEL_MISC_RECLAIMABLE,
+			    -(1 << pool->order));
+	return page;
+}
+
+void dynamic_page_pool_free(struct dynamic_page_pool *pool, struct page *page)
+{
+	BUG_ON(pool->order != compound_order(page));
+
+	dynamic_page_pool_add(pool, page);
+}
+
+int dynamic_page_pool_total(struct dynamic_page_pool *pool, bool high)
+{
+	int count = pool->low_count;
+
+	if (high)
+		count += pool->high_count;
+
+	return count << pool->order;
+}
+
+struct dynamic_page_pool *dynamic_page_pool_create(gfp_t gfp_mask, unsigned int order)
+{
+	struct dynamic_page_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL);
+
+	if (!pool)
+		return NULL;
+	pool->high_count = 0;
+	pool->low_count = 0;
+	INIT_LIST_HEAD(&pool->low_items);
+	INIT_LIST_HEAD(&pool->high_items);
+	pool->gfp_mask = gfp_mask | __GFP_COMP;
+	pool->order = order;
+	spin_lock_init(&pool->lock);
+
+	mutex_lock(&pool_list_lock);
+	list_add(&pool->list, &pool_list);
+	mutex_unlock(&pool_list_lock);
+
+	return pool;
+}
+
+void dynamic_page_pool_destroy(struct dynamic_page_pool *pool)
+{
+	struct page *page, *tmp;
+	LIST_HEAD(pages);
+	int num_pages = 0;
+	int ret = DYNAMIC_POOL_SUCCESS;
+	unsigned long flags;
+
+	/* Remove us from the pool list */
+	mutex_lock(&pool_list_lock);
+	list_del(&pool->list);
+	mutex_unlock(&pool_list_lock);
+
+	/* Free any remaining pages in the pool */
+	spin_lock_irqsave(&pool->lock, flags);
+	while (true) {
+		if (pool->low_count)
+			page = dynamic_page_pool_remove(pool, false);
+		else if (pool->high_count)
+			page = dynamic_page_pool_remove(pool, true);
+		else
+			break;
+
+		list_add(&page->lru, &pages);
+		num_pages++;
+	}
+	spin_unlock_irqrestore(&pool->lock, flags);
+
+	if (num_pages && pool->prerelease_callback)
+		ret = pool->prerelease_callback(pool, &pages, num_pages);
+
+	if (ret != DYNAMIC_POOL_SUCCESS) {
+		pr_err("Failed to reclaim pages when destroying the pool!\n");
+		return;
+	}
+
+	list_for_each_entry_safe(page, tmp, &pages, lru) {
+		list_del(&page->lru);
+		__free_pages(page, pool->order);
+	}
+
+	kfree(pool);
+}
+
+static int dynamic_page_pool_do_shrink(struct dynamic_page_pool *pool, gfp_t gfp_mask,
+				       int nr_to_scan)
+{
+	int freed = 0;
+	bool high;
+	struct page *page, *tmp;
+	LIST_HEAD(pages);
+	int ret = DYNAMIC_POOL_SUCCESS;
+
+	if (current_is_kswapd())
+		high = true;
+	else
+		high = !!(gfp_mask & __GFP_HIGHMEM);
+
+	if (nr_to_scan == 0)
+		return dynamic_page_pool_total(pool, high);
+
+	while (freed < nr_to_scan) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&pool->lock, flags);
+		if (pool->low_count) {
+			page = dynamic_page_pool_remove(pool, false);
+		} else if (high && pool->high_count) {
+			page = dynamic_page_pool_remove(pool, true);
+		} else {
+			spin_unlock_irqrestore(&pool->lock, flags);
+			break;
+		}
+		spin_unlock_irqrestore(&pool->lock, flags);
+		list_add(&page->lru, &pages);
+		freed += (1 << pool->order);
+	}
+
+	if (freed && pool->prerelease_callback)
+		ret = pool->prerelease_callback(pool, &pages, freed >> pool->order);
+
+	if (ret != DYNAMIC_POOL_SUCCESS) {
+		pr_err("Failed to reclaim secure page pool pages!\n");
+		return 0;
+	}
+
+	list_for_each_entry_safe(page, tmp, &pages, lru) {
+		list_del(&page->lru);
+		__free_pages(page, pool->order);
+	}
+
+	return freed;
+}
+
+void dynamic_page_pool_shrink_high_and_low(struct dynamic_page_pool **pools_list,
+					   int num_pools, int nr_to_scan)
+{
+	int i, remaining = nr_to_scan;
+
+	mutex_lock(&pool_list_lock);
+	for (i = 0; i < num_pools; i++) {
+		remaining -= dynamic_page_pool_do_shrink(pools_list[i], __GFP_HIGHMEM,
+							 remaining);
+
+		if (remaining <= 0) {
+			mutex_unlock(&pool_list_lock);
+			return;
+		}
+	}
+	mutex_unlock(&pool_list_lock);
+}
+
+static int dynamic_page_pool_shrink(gfp_t gfp_mask, int nr_to_scan)
+{
+	struct dynamic_page_pool *pool;
+	int nr_total = 0;
+	int nr_freed;
+	int only_scan = 0;
+
+	if (!nr_to_scan)
+		only_scan = 1;
+
+	mutex_lock(&pool_list_lock);
+	list_for_each_entry(pool, &pool_list, list) {
+		if (only_scan) {
+			nr_total += dynamic_page_pool_do_shrink(pool,
+								gfp_mask,
+								nr_to_scan);
+		} else {
+			nr_freed = dynamic_page_pool_do_shrink(pool,
+							       gfp_mask,
+							       nr_to_scan);
+			nr_to_scan -= nr_freed;
+			nr_total += nr_freed;
+			if (nr_to_scan <= 0)
+				break;
+		}
+	}
+	mutex_unlock(&pool_list_lock);
+
+	return nr_total;
+}
+
+static unsigned long dynamic_page_pool_shrink_count(struct shrinker *shrinker,
+						    struct shrink_control *sc)
+{
+	return dynamic_page_pool_shrink(sc->gfp_mask, 0);
+}
+
+static unsigned long dynamic_page_pool_shrink_scan(struct shrinker *shrinker,
+						   struct shrink_control *sc)
+{
+	int to_scan = sc->nr_to_scan;
+
+	if (to_scan == 0)
+		return 0;
+
+	return dynamic_page_pool_shrink(sc->gfp_mask, to_scan);
+}
+
+struct dynamic_page_pool **dynamic_page_pool_create_pools(int vmid,
+							  prerelease_callback callback)
+{
+	struct dynamic_page_pool **pool_list;
+	int i;
+	int ret;
+
+	pool_list = kmalloc_array(NUM_ORDERS, sizeof(*pool_list), GFP_KERNEL);
+	if (!pool_list)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; i < NUM_ORDERS; i++) {
+		pool_list[i] = dynamic_page_pool_create(order_flags[i],
+							orders[i]);
+		pool_list[i]->vmid = vmid;
+		pool_list[i]->prerelease_callback = callback;
+		atomic_set(&pool_list[i]->count, 0);
+		pool_list[i]->last_low_watermark_ktime = 0;
+
+		if (IS_ERR_OR_NULL(pool_list[i])) {
+			int j;
+
+			pr_err("%s: page pool creation failed for the order %u pool!\n",
+			       __func__, orders[i]);
+			for (j = 0; j < i; j++)
+				dynamic_page_pool_destroy(pool_list[j]);
+
+			ret = -ENOMEM;
+			goto free_pool_arr;
+		}
+	}
+
+	return pool_list;
+
+free_pool_arr:
+	kfree(pool_list);
+
+	return ERR_PTR(ret);
+}
+
+void dynamic_page_pool_release_pools(struct dynamic_page_pool **pool_list)
+{
+	int i;
+
+	for (i = 0; i < NUM_ORDERS; i++)
+		dynamic_page_pool_destroy(pool_list[i]);
+
+	kfree(pool_list);
+}
+
+int dynamic_page_pool_init_shrinker(void)
+{
+	static bool registered;
+	static struct shrinker *shrinker;
+
+	if (registered)
+		return 0;
+
+	shrinker = shrinker_alloc(0, "dynamic_page_pool");
+	if (!shrinker)
+		return -ENOMEM;
+
+	shrinker->count_objects = dynamic_page_pool_shrink_count;
+	shrinker->scan_objects = dynamic_page_pool_shrink_scan;
+	shrinker_register(shrinker);
+
+	registered = true;
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_dynamic_page_pool.h
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_dynamic_page_pool.h
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * ION Memory Allocator kernel interface header
+ *
+ * Taken from:
+ * include/linux/dynamic_page_pool.h
+ * Git-repo: https://git.linaro.org/people/john.stultz/android-dev.git
+ * Branch: dma-buf-heap-perf
+ * Git-commit: 458ea8030852755867bdc0384aa40f97aba7a572
+ *
+ * Copyright (C) 2011 Google, Inc.
+ *
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _DYN_PAGE_POOL_H
+#define _DYN_PAGE_POOL_H
+
+#include <linux/device.h>
+#include <linux/kref.h>
+#include <linux/mm_types.h>
+#include <linux/mutex.h>
+#include <linux/shrinker.h>
+#include <linux/types.h>
+
+#define HIGH_ORDER_GFP  (((GFP_HIGHUSER | __GFP_ZERO | __GFP_NOWARN \
+				| __GFP_NORETRY) & ~__GFP_RECLAIM) \
+				| __GFP_COMP)
+#define LOW_ORDER_GFP (GFP_HIGHUSER | __GFP_ZERO | __GFP_COMP)
+
+/*
+ * We add __GFP_NOWARN for order 4 allocations since the core mm/ framework
+ * makes no guarantee of these allocations succeeding.
+ */
+static gfp_t order_flags[] = {HIGH_ORDER_GFP, HIGH_ORDER_GFP,
+			      LOW_ORDER_GFP};
+#if defined(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) && !defined(CONFIG_64BIT) && !defined(CONFIG_ARM_LPAE)
+static const unsigned int orders[] = {8, 4, 0};
+#else
+static const unsigned int orders[] = {9, 4, 0};
+#endif
+#define NUM_ORDERS ARRAY_SIZE(orders)
+
+enum dynamic_pool_callback_ret {
+	DYNAMIC_POOL_SUCCESS,
+	DYNAMIC_POOL_FAILURE,
+};
+
+struct dynamic_page_pool;
+
+typedef enum dynamic_pool_callback_ret (*prerelease_callback)(struct dynamic_page_pool *pool,
+							      struct list_head *pages,
+							      int num_pages);
+
+/**
+ * struct dynamic_page_pool - pagepool struct
+ * @high_count:			number of highmem items in the pool
+ * @low_count:			number of lowmem items in the pool
+ * @count:			total number of pages/items in the pool
+ * @high_items:			list of highmem items
+ * @low_items:			list of lowmem items
+ * @last_low_watermark_ktime:	most recent time at which the zone watermarks were
+ *				low
+ * @refill_worker:		kthread used to refill a pool, if applicable
+ * @lock:			lock protecting this struct and especially the count
+ *				item list
+ * @gfp_mask:			gfp_mask to use from alloc
+ * @order:			order of pages in the pool
+ * @list:			list node for list of pools
+ * @vmid:			the vmid used for this pool
+ * @prerelease_callback:	preprocessing function called before pages are
+ *				released to buddy
+ *
+ * Allows you to keep a pool of pre allocated pages to use
+ * Keeping a pool of pages that is ready for dma, ie any cached mapping have
+ * been invalidated from the cache, provides a significant performance benefit
+ * on many systems
+ */
+struct dynamic_page_pool {
+	int high_count;
+	int low_count;
+	atomic_t count;
+	struct list_head high_items;
+	struct list_head low_items;
+	ktime_t last_low_watermark_ktime;
+	struct task_struct *refill_worker;
+	spinlock_t lock;
+	gfp_t gfp_mask;
+	unsigned int order;
+	struct list_head list;
+	int vmid;
+	prerelease_callback prerelease_callback;
+};
+
+struct dynamic_page_pool **dynamic_page_pool_create_pools(int vmid,
+							  prerelease_callback callback);
+void dynamic_page_pool_release_pools(struct dynamic_page_pool **pool_list);
+
+struct page *dynamic_page_pool_alloc(struct dynamic_page_pool *pool);
+void dynamic_page_pool_free(struct dynamic_page_pool *pool, struct page *page);
+
+int dynamic_page_pool_init_shrinker(void);
+void dynamic_page_pool_shrink_high_and_low(struct dynamic_page_pool **pools_list,
+					   int num_pools, int nr_to_scan);
+int dynamic_page_pool_total(struct dynamic_page_pool *pool, bool high);
+
+struct page *dynamic_page_pool_remove(struct dynamic_page_pool *pool, bool high);
+void dynamic_page_pool_add(struct dynamic_page_pool *pool, struct page *page);
+
+#endif /* _DYN_PAGE_POOL_H */
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_secure_system_heap.c
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_secure_system_heap.c
@@ -0,0 +1,726 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DMABUF System heap exporter
+ * Originally copied from: drivers/dma-buf/heaps/system_heap.c as of commit
+ * 263e38f82cbb ("dma-buf: heaps: Remove redundant heap identifier from system
+ * heap name")
+ *
+ * Additions taken from modifications to drivers/dma-buf/heaps/system-heap.c,
+ * from patches submitted, are listed below:
+ *
+ * Addition that modifies dma_buf ops to use SG tables taken from
+ * drivers/dma-buf/heaps/system-heap.c in:
+ * https://lore.kernel.org/lkml/20201017013255.43568-2-john.stultz@linaro.org/
+ *
+ * Addition that skips unneeded syncs in the dma_buf ops taken from
+ * https://lore.kernel.org/lkml/20201017013255.43568-5-john.stultz@linaro.org/
+ *
+ * Addition that tries to allocate higher order pages taken from
+ * https://lore.kernel.org/lkml/20201017013255.43568-6-john.stultz@linaro.org/
+ *
+ * Addition that implements an uncached heap taken from
+ * https://lore.kernel.org/lkml/20201017013255.43568-8-john.stultz@linaro.org/,
+ * with our own modificaitons made to account for core kernel changes that are
+ * a part of the patch series.
+ *
+ * Pooling functionality taken from:
+ * Git-repo: https://git.linaro.org/people/john.stultz/android-dev.git
+ * Branch: dma-buf-heap-perf
+ * Git-commit: 6f080eb67dce63c6efa57ef564ca4cd762ccebb0
+ * Git-commit: 6fb9593b928c4cb485bef4e88c59c6b9fdf11352
+ *
+ * Branched off from qcom_system_heap.c as of commit a4e135a8e482
+ * ("dt-bindings: ipcc: Add WPSS client to IPCC header") to accommodate secure
+ * pooling.
+ *
+ * Copyright (C) 2011 Google, Inc.
+ * Copyright (C) 2019, 2020 Linaro Ltd.
+ *
+ * Portions based off of Andrew Davis' SRAM heap:
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ *	Andrew F. Davis <afd@ti.com>
+ *
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/dma-buf.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-heap.h>
+#include <linux/err.h>
+#include <linux/highmem.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/qcom_dma_heap.h>
+
+#include "qcom_dma_heap_secure_utils.h"
+#include "qcom_dynamic_page_pool.h"
+#include "qcom_sg_ops.h"
+#include "qcom_secure_system_heap.h"
+#include "qcom_system_heap.h"
+
+#define MAX_NR_PREFETCH_REGIONS 32
+
+/*
+ * The video client may not hold the last reference count on the
+ * ion_buffer(s). Delay for a short time after the video client sends
+ * the IOC_DRAIN event to increase the chance that the reference
+ * count drops to zero. Time in milliseconds.
+ */
+#define SHRINK_DELAY 1000
+
+struct prefetch_info {
+	struct list_head list;
+	struct dma_heap *heap;
+	u64 size;
+	bool shrink;
+};
+
+static LIST_HEAD(prefetch_list);
+static DEFINE_SPINLOCK(work_lock);
+static struct delayed_work prefetch_work;
+static struct workqueue_struct *prefetch_wq;
+
+static LIST_HEAD(secure_heaps);
+
+static inline struct dynamic_page_pool **get_sys_heap_page_pool(void)
+{
+	static struct dynamic_page_pool **qcom_sys_heap_pools;
+	struct dma_heap *dma_heap;
+	struct qcom_system_heap *sys_heap;
+
+	if (qcom_sys_heap_pools)
+		return qcom_sys_heap_pools;
+
+	dma_heap = dma_heap_find("qcom,system");
+	if (!dma_heap) {
+		pr_err("Unable to find the system heap\n");
+		goto out;
+	}
+
+	sys_heap = (struct qcom_system_heap *) dma_heap_get_drvdata(dma_heap);
+	qcom_sys_heap_pools = sys_heap->pool_list;
+
+out:
+	return qcom_sys_heap_pools;
+}
+
+static struct sg_table *get_pages(u64 size, struct dma_heap *heap)
+{
+	LIST_HEAD(pages);
+	struct dynamic_page_pool **qcom_sys_heap_pools;
+	unsigned long size_remaining = size;
+	struct page *page, *tmp_page;
+	int max_order = orders[0];
+	int num_pages = 0;
+	struct sg_table *sgt;
+	struct scatterlist *sg;
+	int ret;
+
+	qcom_sys_heap_pools = get_sys_heap_page_pool();
+	if (!qcom_sys_heap_pools) {
+		pr_err("%s: Couldn't obtain the pools for the system heap!\n", __func__);
+		return ERR_PTR(-EINVAL);
+	}
+
+	while (size_remaining > 0) {
+		page = qcom_sys_heap_alloc_largest_available(qcom_sys_heap_pools,
+							     size_remaining,
+							     max_order,
+							     false);
+
+		if (!page) {
+			pr_err("%s: Failed to get pages from the system heap: %lu, %llu!\n",
+			       __func__, size_remaining, size);
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		list_add_tail(&page->lru, &pages);
+		size_remaining -= page_size(page);
+		max_order = compound_order(page);
+		num_pages++;
+	}
+
+	sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
+	if (!sgt) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ret = sg_alloc_table(sgt, num_pages, GFP_KERNEL);
+	if (ret) {
+		pr_err("%s: sg table allocation failed with %d\n", __func__, ret);
+		goto free_table;
+	}
+
+	sg = sgt->sgl;
+	list_for_each_entry(page, &pages, lru) {
+		sg_set_page(sg, page, page_size(page), 0);
+		sg = sg_next(sg);
+	}
+
+	dma_map_sgtable(dma_heap_get_dev(heap), sgt, DMA_BIDIRECTIONAL, 0);
+	dma_unmap_sgtable(dma_heap_get_dev(heap), sgt, DMA_BIDIRECTIONAL, 0);
+
+	return sgt;
+
+free_table:
+	kfree(sgt);
+err:
+	list_for_each_entry_safe(page, tmp_page, &pages, lru)
+		__free_pages(page, compound_order(page));
+
+	return ERR_PTR(ret);
+}
+
+static void process_one_prefetch(struct prefetch_info *info)
+{
+	struct qcom_secure_system_heap *secure_heap = dma_heap_get_drvdata(info->heap);
+
+	struct sg_table *sgt;
+	struct scatterlist *sg;
+	struct page *page;
+	int ret;
+	int i, j;
+
+	sgt = get_pages(info->size, info->heap);
+	if (IS_ERR(sgt))
+		return;
+
+	ret = hyp_assign_sg_from_flags(sgt, secure_heap->vmid, true);
+	if (ret)
+		goto err;
+
+	for_each_sgtable_sg(sgt, sg, i) {
+		page = sg_page(sg);
+
+		for (j = 0; j < NUM_ORDERS; j++) {
+			if (compound_order(page) == orders[j])
+				break;
+		}
+		dynamic_page_pool_free(secure_heap->pool_list[j], page);
+	}
+
+	sg_free_table(sgt);
+
+	return;
+
+err:
+	for_each_sgtable_sg(sgt, sg, i) {
+		page = sg_page(sg);
+		__free_pages(page, compound_order(page));
+	}
+	sg_free_table(sgt);
+}
+
+static void process_one_shrink(struct prefetch_info *info)
+{
+	struct qcom_secure_system_heap *secure_heap = dma_heap_get_drvdata(info->heap);
+
+	dynamic_page_pool_shrink_high_and_low(secure_heap->pool_list,
+					      NUM_ORDERS, info->size / PAGE_SIZE);
+}
+
+static void secure_system_heap_prefetch_work(struct work_struct *work)
+{
+	struct prefetch_info *info, *tmp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&work_lock, flags);
+	list_for_each_entry_safe(info, tmp, &prefetch_list, list) {
+		list_del(&info->list);
+		spin_unlock_irqrestore(&work_lock, flags);
+
+		if (info->shrink)
+			process_one_shrink(info);
+		else
+			process_one_prefetch(info);
+
+		kfree(info);
+		spin_lock_irqsave(&work_lock, flags);
+	}
+	spin_unlock_irqrestore(&work_lock, flags);
+}
+
+static int alloc_prefetch_info(struct dma_buf_heap_prefetch_region *region,
+			       bool shrink, struct list_head *items)
+{
+	struct prefetch_info *info;
+
+	info = kmalloc(sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->size = PAGE_ALIGN(region->size);
+	info->heap = region->heap;
+	info->shrink = shrink;
+	INIT_LIST_HEAD(&info->list);
+	list_add_tail(&info->list, items);
+	return 0;
+}
+
+static int __qcom_secure_system_heap_resize(struct dma_buf_heap_prefetch_region *regions,
+					    size_t nr_regions,
+					    bool shrink)
+{
+	struct qcom_secure_system_heap *list_ptr, *secure_heap = NULL;
+	int i, ret = 0;
+	struct prefetch_info *info, *tmp;
+	unsigned long flags;
+	LIST_HEAD(items);
+
+	if (!regions || nr_regions > MAX_NR_PREFETCH_REGIONS) {
+		pr_err("%s: Invalid input for %s\n", __func__,
+		       (shrink) ? "drain" : "prefetch");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < nr_regions; i++) {
+		list_for_each_entry(list_ptr, &secure_heaps, list) {
+			if (list_ptr == dma_heap_get_drvdata(regions->heap)) {
+				secure_heap = list_ptr;
+				break;
+			}
+		}
+
+		if (!secure_heap) {
+			pr_err("%s: %s is not a secure system heap!\n", __func__,
+			       dma_heap_get_name(regions->heap));
+			ret = -EINVAL;
+			goto out_free;
+		}
+
+		ret = alloc_prefetch_info(&regions[i], shrink, &items);
+		if (ret)
+			goto out_free;
+	}
+
+	spin_lock_irqsave(&work_lock, flags);
+	list_splice_tail_init(&items, &prefetch_list);
+	queue_delayed_work(prefetch_wq, &prefetch_work,
+			   shrink ?  msecs_to_jiffies(SHRINK_DELAY) : 0);
+	spin_unlock_irqrestore(&work_lock, flags);
+
+	return 0;
+
+out_free:
+	list_for_each_entry_safe(info, tmp, &items, list) {
+		list_del(&info->list);
+		kfree(info);
+	}
+	return ret;
+}
+
+int qcom_secure_system_heap_prefetch(struct dma_buf_heap_prefetch_region *regions,
+				     size_t nr_regions)
+{
+	return __qcom_secure_system_heap_resize(regions, nr_regions, false);
+}
+EXPORT_SYMBOL_GPL(qcom_secure_system_heap_prefetch);
+
+int qcom_secure_system_heap_drain(struct dma_buf_heap_prefetch_region *regions,
+				  size_t nr_regions)
+{
+	return __qcom_secure_system_heap_resize(regions, nr_regions, true);
+}
+EXPORT_SYMBOL_GPL(qcom_secure_system_heap_drain);
+
+static enum dynamic_pool_callback_ret free_secure_pages(struct dynamic_page_pool *pool,
+							struct list_head *pages,
+							int num_pages)
+{
+	struct page *page;
+	struct sg_table sgt;
+	struct scatterlist *sg;
+	int ret;
+
+	if (!num_pages)
+		return DYNAMIC_POOL_SUCCESS;
+
+	ret = sg_alloc_table(&sgt, num_pages, GFP_KERNEL);
+	if (ret)
+		return DYNAMIC_POOL_FAILURE;
+
+	sg = sgt.sgl;
+	list_for_each_entry(page, pages, lru) {
+		sg_set_page(sg, page, page_size(page), 0);
+		sg = sg_next(sg);
+	}
+
+	ret = hyp_unassign_sg_from_flags(&sgt, pool->vmid, true);
+	sg_free_table(&sgt);
+
+	if (ret)
+		return DYNAMIC_POOL_FAILURE;
+
+	return DYNAMIC_POOL_SUCCESS;
+}
+
+static void page_list_merge(struct list_head *secure_pages,
+			    struct list_head *non_secure_pages,
+			    struct scatterlist *sg,
+			    struct scatterlist *non_secure_sg)
+{
+	bool is_secure_head, is_non_secure_head;
+	struct page *secure_page = list_first_entry(secure_pages, struct page, lru);
+	struct page *non_secure_page = list_first_entry(non_secure_pages, struct page, lru);
+
+	do {
+		is_secure_head = list_entry_is_head(secure_page, secure_pages, lru);
+		is_non_secure_head = list_entry_is_head(non_secure_page, non_secure_pages, lru);
+
+		if (!is_secure_head && !is_non_secure_head) {
+			if (page_size(non_secure_page) >= page_size(secure_page)) {
+				sg_set_page(sg, non_secure_page,
+					    page_size(non_secure_page), 0);
+				sg_set_page(non_secure_sg, non_secure_page,
+					    page_size(non_secure_page), 0);
+
+				non_secure_page = list_next_entry(non_secure_page, lru);
+				non_secure_sg = sg_next(non_secure_sg);
+			} else {
+				sg_set_page(sg, secure_page,
+					    page_size(secure_page), 0);
+				secure_page = list_next_entry(secure_page, lru);
+			}
+		} else if (!is_non_secure_head) {
+			sg_set_page(sg, non_secure_page,
+					page_size(non_secure_page), 0);
+			sg_set_page(non_secure_sg, non_secure_page,
+					page_size(non_secure_page), 0);
+
+			non_secure_page = list_next_entry(non_secure_page, lru);
+			non_secure_sg = sg_next(non_secure_sg);
+		} else if (!is_secure_head) {
+			sg_set_page(sg, secure_page,
+					page_size(secure_page), 0);
+			secure_page = list_next_entry(secure_page, lru);
+		}
+
+		sg = sg_next(sg);
+	} while (sg);
+}
+
+static int page_to_pool_ind(struct page *page)
+{
+	int i;
+
+	for (i = 0; i < NUM_ORDERS; i++)
+		if (compound_order(page) == orders[i])
+			break;
+	return i;
+}
+
+static void system_heap_free(struct qcom_sg_buffer *buffer)
+{
+	struct qcom_secure_system_heap *sys_heap;
+	struct sg_table *table;
+	struct scatterlist *sg;
+	int i, j;
+
+	sys_heap = dma_heap_get_drvdata(buffer->heap);
+	table = &buffer->sg_table;
+
+	for_each_sg(table->sgl, sg, table->nents, i) {
+		struct page *page = sg_page(sg);
+
+		for (j = 0; j < NUM_ORDERS; j++) {
+			if (compound_order(page) == orders[j])
+				break;
+		}
+		dynamic_page_pool_free(sys_heap->pool_list[j], page);
+	}
+	sg_free_table(table);
+	kfree(buffer);
+}
+
+static struct page *alloc_largest_available(struct dynamic_page_pool **pools,
+					    unsigned long size,
+					    unsigned int max_order,
+					    bool *page_from_secure_pool)
+{
+	struct page *page = NULL;
+	int i;
+	struct dynamic_page_pool **qcom_sys_heap_pools = get_sys_heap_page_pool();
+
+	if (!qcom_sys_heap_pools) {
+		pr_err("%s: Couldn't obtain the pools for the system heap!\n", __func__);
+		return NULL;
+	}
+
+	*page_from_secure_pool = true;
+
+	for (i = 0; i < NUM_ORDERS; i++) {
+		unsigned long flags;
+
+		if (size <  (PAGE_SIZE << orders[i]))
+			continue;
+		if (max_order < orders[i])
+			continue;
+
+		spin_lock_irqsave(&pools[i]->lock, flags);
+		if (pools[i]->high_count)
+			page = dynamic_page_pool_remove(pools[i], true);
+		else if (pools[i]->low_count)
+			page = dynamic_page_pool_remove(pools[i], false);
+		spin_unlock_irqrestore(&pools[i]->lock, flags);
+
+		if (!page)
+			continue;
+		return page;
+	}
+
+	*page_from_secure_pool = false;
+
+	return qcom_sys_heap_alloc_largest_available(qcom_sys_heap_pools,
+						     size,
+						     max_order,
+						     false);
+}
+
+static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
+					       unsigned long len,
+					       u32 fd_flags,
+					       u64 heap_flags)
+{
+	struct qcom_secure_system_heap *sys_heap;
+	struct qcom_sg_buffer *buffer;
+	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+	unsigned long size_remaining = len;
+	unsigned int max_order = orders[0];
+	bool page_from_secure_pool;
+	struct dma_buf *dmabuf;
+	struct sg_table *table, non_secure_table;
+	struct scatterlist *sg, *non_secure_sg = NULL;
+	LIST_HEAD(secure_pages);
+	LIST_HEAD(non_secure_pages);
+	struct page *page, *tmp_page;
+	int total_pages = 0, num_non_secure_pages = 0;
+	int ret = -ENOMEM, hyp_ret = 0;
+	int perms;
+	int vmid;
+
+	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
+	if (!buffer)
+		return ERR_PTR(-ENOMEM);
+
+	sys_heap = dma_heap_get_drvdata(heap);
+
+	INIT_LIST_HEAD(&buffer->attachments);
+	mutex_init(&buffer->lock);
+	buffer->heap = heap;
+	buffer->len = len;
+	buffer->uncached = true;
+	buffer->free = system_heap_free;
+
+	while (size_remaining > 0) {
+		/*
+		 * Avoid trying to allocate memory if the process
+		 * has been killed by SIGKILL
+		 */
+		if (fatal_signal_pending(current))
+			goto free_buffer;
+
+		page = alloc_largest_available(sys_heap->pool_list,
+					       size_remaining,
+					       max_order,
+					       &page_from_secure_pool);
+		if (!page)
+			goto free_buffer;
+
+		if (page_from_secure_pool) {
+			list_add_tail(&page->lru, &secure_pages);
+		} else {
+			num_non_secure_pages++;
+			list_add_tail(&page->lru, &non_secure_pages);
+		}
+
+		size_remaining -= page_size(page);
+		max_order = compound_order(page);
+		total_pages++;
+	}
+
+	table = &buffer->sg_table;
+	if (sg_alloc_table(table, total_pages, GFP_KERNEL))
+		goto free_buffer;
+	sg = table->sgl;
+
+	if (num_non_secure_pages) {
+		if (sg_alloc_table(&non_secure_table, num_non_secure_pages, GFP_KERNEL))
+			goto free_sg;
+		non_secure_sg = non_secure_table.sgl;
+	}
+
+	page_list_merge(&secure_pages, &non_secure_pages, sg, non_secure_sg);
+
+	if (num_non_secure_pages) {
+		dma_map_sgtable(dma_heap_get_dev(heap), &non_secure_table, DMA_BIDIRECTIONAL, 0);
+		dma_unmap_sgtable(dma_heap_get_dev(heap), &non_secure_table, DMA_BIDIRECTIONAL, 0);
+
+		hyp_ret = hyp_assign_sg_from_flags(&non_secure_table, sys_heap->vmid, true);
+		if (hyp_ret) {
+			if (hyp_ret != -EADDRNOTAVAIL)
+				/* Set hyp_ret = 0 so that we free the non-secure pages */
+				hyp_ret = 0;
+
+			goto free_non_secure_sg;
+		}
+	}
+
+	perms = msm_secure_get_vmid_perms(sys_heap->vmid);
+	vmid = get_secure_vmid(sys_heap->vmid);
+	buffer->vmperm = mem_buf_vmperm_alloc_staticvm(table,
+				&vmid, &perms, 1);
+
+	if (IS_ERR(buffer->vmperm)) {
+		ret = PTR_ERR(buffer->vmperm);
+		goto hyp_unassign;
+	}
+
+	/* create the dmabuf */
+	exp_info.exp_name = dma_heap_get_name(heap);
+	exp_info.ops = &qcom_sg_buf_ops.dma_ops;
+	exp_info.size = buffer->len;
+	exp_info.flags = fd_flags;
+	exp_info.priv = buffer;
+	dmabuf = qcom_dma_buf_export(&exp_info, &qcom_sg_buf_ops);
+	if (IS_ERR(dmabuf)) {
+		ret = PTR_ERR(dmabuf);
+		goto vmperm_release;
+	}
+
+	if (num_non_secure_pages)
+		sg_free_table(&non_secure_table);
+
+	return dmabuf;
+
+vmperm_release:
+	mem_buf_vmperm_release(buffer->vmperm);
+
+hyp_unassign:
+	/* We check PagePrivate() below to see if we've reclaimed a particular page */
+	hyp_ret = hyp_unassign_sg_from_flags(&non_secure_table, sys_heap->vmid, true);
+
+free_non_secure_sg:
+	if (num_non_secure_pages)
+		sg_free_table(&non_secure_table);
+free_sg:
+	sg_free_table(table);
+free_buffer:
+	list_for_each_entry_safe(page, tmp_page, &secure_pages, lru)
+		dynamic_page_pool_free(sys_heap->pool_list[page_to_pool_ind(page)], page);
+	if (!hyp_ret)
+		list_for_each_entry_safe(page, tmp_page, &non_secure_pages, lru)
+			__free_pages(page, compound_order(page));
+
+	kfree(buffer);
+
+	return ERR_PTR(ret);
+}
+
+
+static const struct dma_heap_ops system_heap_ops = {
+	.allocate = system_heap_allocate,
+};
+
+static int create_prefetch_workqueue(void)
+{
+	static bool registered;
+
+	if (registered)
+		return 0;
+
+	INIT_DELAYED_WORK(&prefetch_work,
+			  secure_system_heap_prefetch_work);
+
+	prefetch_wq = alloc_workqueue("system_secure_prefetch_wq",
+				      WQ_UNBOUND | WQ_FREEZABLE, 0);
+	if (!prefetch_wq) {
+		pr_err("Failed to create system secure prefetch workqueue\n");
+		return -ENOMEM;
+	}
+
+	registered = true;
+	return 0;
+}
+
+void qcom_secure_system_heap_create(const char *name, const char *secure_system_alias, int vmid)
+{
+	struct dma_heap_export_info exp_info;
+	struct dma_heap *heap;
+	struct qcom_secure_system_heap *sys_heap;
+	int ret;
+
+	if (get_secure_vmid(vmid) == -EINVAL || hweight_long(vmid) != 1) {
+		pr_err("Invalid VMID or supplied more than one VMID\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = dynamic_page_pool_init_shrinker();
+	if (ret)
+		goto out;
+
+	ret = create_prefetch_workqueue();
+	if (ret)
+		goto out;
+
+	sys_heap = kzalloc(sizeof(*sys_heap), GFP_KERNEL);
+	if (!sys_heap) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	sys_heap->vmid = vmid;
+	sys_heap->pool_list = dynamic_page_pool_create_pools(vmid, free_secure_pages);
+	if (IS_ERR(sys_heap->pool_list)) {
+		ret = PTR_ERR(sys_heap->pool_list);
+		goto free_heap;
+	}
+
+	exp_info.name = name;
+	exp_info.ops = &system_heap_ops;
+	exp_info.priv = sys_heap;
+
+	heap = dma_heap_add(&exp_info);
+	if (IS_ERR(heap)) {
+		ret = PTR_ERR(heap);
+		goto free_pools;
+	}
+
+	dma_coerce_mask_and_coherent(dma_heap_get_dev(heap), DMA_BIT_MASK(64));
+
+	list_add(&sys_heap->list, &secure_heaps);
+
+	pr_info("%s: DMA-BUF Heap: Created '%s'\n", __func__, name);
+
+	if (secure_system_alias != NULL) {
+		exp_info.name = secure_system_alias;
+
+		heap = dma_heap_add(&exp_info);
+		if (IS_ERR(heap)) {
+			pr_err("%s: Failed to create '%s', error is %ld\n", __func__,
+			       secure_system_alias, PTR_ERR(heap));
+			return;
+		}
+
+		dma_coerce_mask_and_coherent(dma_heap_get_dev(heap), DMA_BIT_MASK(64));
+
+		pr_info("%s: DMA-BUF Heap: Created '%s'\n", __func__, secure_system_alias);
+	}
+
+	return;
+
+free_pools:
+	dynamic_page_pool_release_pools(sys_heap->pool_list);
+
+free_heap:
+	kfree(sys_heap);
+
+out:
+	pr_err("%s: Failed to create '%s', error is %d\n", __func__, name, ret);
+}
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_secure_system_heap.h
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_secure_system_heap.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _QCOM_SECURE_SYSTEM_HEAP_H
+#define _QCOM_SECURE_SYSTEM_HEAP_H
+
+#include <linux/dma-heap.h>
+#include <linux/err.h>
+#include "qcom_dynamic_page_pool.h"
+
+struct qcom_secure_system_heap {
+	struct dynamic_page_pool **pool_list;
+	int vmid;
+	struct list_head list;
+};
+
+#ifdef CONFIG_QCOM_DMABUF_HEAPS_SYSTEM_SECURE
+void qcom_secure_system_heap_create(const char *name, const char *secure_system_alias,
+				    int vmid);
+#else
+static void qcom_secure_system_heap_create(const char *name, const char *secure_system_alias,
+					   int vmid)
+{
+
+}
+#endif
+
+#endif /* _QCOM_SECURE_SYSTEM_HEAP_H */
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_sg_ops.c
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_sg_ops.c
@@ -0,0 +1,599 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * mmap() algorithm taken from drivers/staging/android/ion/ion_heap.c as
+ * of commit a3ec289e74b4 ("arm-smmu: Fix missing qsmmuv500 callback")
+ *
+ * Copyright (C) 2011 Google, Inc.
+ * Copyright (C) 2019, 2020 Linaro Ltd.
+ *
+ * Portions based off of Andrew Davis' SRAM heap:
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ *	Andrew F. Davis <afd@ti.com>
+ *
+ * These ops were base of the ops in drivers/dma-buf/heaps/system-heap.c from
+ * https://lore.kernel.org/lkml/20201017013255.43568-2-john.stultz@linaro.org/
+ *
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/dma-buf.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-heap.h>
+#include <linux/err.h>
+#include <linux/highmem.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/of.h>
+#include <linux/dma-map-ops.h>
+#include <linux/qcom_dma_heap.h>
+#include <linux/msm_dma_iommu_mapping.h>
+#include <linux/qti-smmu-proxy-callbacks.h>
+
+#include "qcom_sg_ops.h"
+
+int proxy_invalid_map(struct device *dev, struct sg_table *table,
+		      struct dma_buf *dmabuf)
+{
+	WARN(1, "Trying to map with SMMU proxy driver when it has not fully probed!\n");
+	return -EINVAL;
+}
+
+void proxy_invalid_unmap(struct device *dev, struct sg_table *table,
+			 struct dma_buf *dmabuf)
+{
+	WARN(1, "Trying to unmap with SMMU proxy driver when it has not fully probed!\n");
+}
+
+static struct smmu_proxy_callbacks smmu_proxy_callback_ops = {
+	.map_sgtable = proxy_invalid_map,
+	.unmap_sgtable = proxy_invalid_unmap,
+};
+
+static struct sg_table *dup_sg_table(struct sg_table *table)
+{
+	struct sg_table *new_table;
+	int ret, i;
+	struct scatterlist *sg, *new_sg;
+
+	new_table = kzalloc(sizeof(*new_table), GFP_KERNEL);
+	if (!new_table)
+		return ERR_PTR(-ENOMEM);
+
+	ret = sg_alloc_table(new_table, table->orig_nents, GFP_KERNEL);
+	if (ret) {
+		kfree(new_table);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	new_sg = new_table->sgl;
+	for_each_sgtable_sg(table, sg, i) {
+		sg_set_page(new_sg, sg_page(sg), sg->length, sg->offset);
+		new_sg = sg_next(new_sg);
+	}
+
+	return new_table;
+}
+
+int qcom_sg_attach(struct dma_buf *dmabuf,
+		   struct dma_buf_attachment *attachment)
+{
+	struct qcom_sg_buffer *buffer = dmabuf->priv;
+	struct dma_heap_attachment *a;
+	struct sg_table *table;
+
+	a = kzalloc(sizeof(*a), GFP_KERNEL);
+	if (!a)
+		return -ENOMEM;
+
+	table = dup_sg_table(&buffer->sg_table);
+	if (IS_ERR(table)) {
+		kfree(a);
+		return -ENOMEM;
+	}
+
+	a->table = table;
+	a->dev = attachment->dev;
+	INIT_LIST_HEAD(&a->list);
+	a->mapped = false;
+
+	attachment->priv = a;
+
+	mutex_lock(&buffer->lock);
+	list_add(&a->list, &buffer->attachments);
+	mutex_unlock(&buffer->lock);
+
+	return 0;
+}
+
+void qcom_sg_detach(struct dma_buf *dmabuf,
+		    struct dma_buf_attachment *attachment)
+{
+	struct qcom_sg_buffer *buffer = dmabuf->priv;
+	struct dma_heap_attachment *a = attachment->priv;
+
+	mutex_lock(&buffer->lock);
+	list_del(&a->list);
+	mutex_unlock(&buffer->lock);
+
+	sg_free_table(a->table);
+	kfree(a->table);
+	kfree(a);
+}
+
+struct sg_table *qcom_sg_map_dma_buf(struct dma_buf_attachment *attachment,
+				     enum dma_data_direction direction)
+{
+	struct dma_heap_attachment *a = attachment->priv;
+	struct sg_table *table = a->table;
+	struct qcom_sg_buffer *buffer;
+	struct mem_buf_vmperm *vmperm;
+	unsigned long attrs = attachment->dma_map_attrs;
+	int ret;
+
+	buffer = attachment->dmabuf->priv;
+	vmperm = buffer->vmperm;
+
+	if (smmu_proxy_callback_ops.map_sgtable &&
+	    (attrs & DMA_ATTR_QTI_SMMU_PROXY_MAP)) {
+		ret = smmu_proxy_callback_ops.map_sgtable(attachment->dev, table,
+							  attachment->dmabuf);
+		return ret ? ERR_PTR(ret) : table;
+	}
+
+	/* Prevent map/unmap during begin/end_cpu_access */
+	mutex_lock(&buffer->lock);
+
+	/* Ensure VM permissions are constant while the buffer is mapped */
+	mem_buf_vmperm_pin(vmperm);
+	if (buffer->uncached || !mem_buf_vmperm_can_cmo(vmperm))
+		attrs |= DMA_ATTR_SKIP_CPU_SYNC;
+
+	if (attrs & DMA_ATTR_DELAYED_UNMAP) {
+		ret = msm_dma_map_sgtable(attachment->dev, table, direction,
+					  attachment->dmabuf, attrs);
+	} else if (!a->mapped) {
+		ret = dma_map_sgtable(attachment->dev, table, direction, attrs);
+	} else {
+		dev_err(attachment->dev, "Error: Dma-buf is already mapped!\n");
+		ret = -EBUSY;
+	}
+
+	if (ret) {
+		table = ERR_PTR(ret);
+		goto err_map_sgtable;
+	}
+
+	a->mapped = true;
+	mutex_unlock(&buffer->lock);
+	return table;
+
+err_map_sgtable:
+	mem_buf_vmperm_unpin(vmperm);
+	mutex_unlock(&buffer->lock);
+	return table;
+}
+
+void qcom_sg_unmap_dma_buf(struct dma_buf_attachment *attachment,
+			   struct sg_table *table,
+			   enum dma_data_direction direction)
+{
+	struct dma_heap_attachment *a = attachment->priv;
+	struct qcom_sg_buffer *buffer;
+	struct mem_buf_vmperm *vmperm;
+	unsigned long attrs = attachment->dma_map_attrs;
+
+	buffer = attachment->dmabuf->priv;
+	vmperm = buffer->vmperm;
+
+	if (smmu_proxy_callback_ops.unmap_sgtable &&
+	    (attrs & DMA_ATTR_QTI_SMMU_PROXY_MAP)) {
+		smmu_proxy_callback_ops.unmap_sgtable(attachment->dev, table,
+						      attachment->dmabuf);
+		return;
+	}
+
+	/* Prevent map/unmap during begin/end_cpu_access */
+	mutex_lock(&buffer->lock);
+
+	if (buffer->uncached || !mem_buf_vmperm_can_cmo(vmperm))
+		attrs |= DMA_ATTR_SKIP_CPU_SYNC;
+
+	a->mapped = false;
+
+	if (attrs & DMA_ATTR_DELAYED_UNMAP) {
+		msm_dma_unmap_sgtable(attachment->dev, table, direction,
+				      attachment->dmabuf, attrs);
+	} else {
+		dma_unmap_sgtable(attachment->dev, table, direction, attrs);
+	}
+	mem_buf_vmperm_unpin(vmperm);
+	mutex_unlock(&buffer->lock);
+}
+
+int qcom_sg_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
+				     enum dma_data_direction direction)
+{
+	struct qcom_sg_buffer *buffer = dmabuf->priv;
+	struct dma_heap_attachment *a;
+
+	if (buffer->uncached)
+		return 0;
+
+	mutex_lock(&buffer->lock);
+
+	/* Keep the same behavior as ion by returning 0 instead of -EPERM */
+	if (!mem_buf_vmperm_can_cmo(buffer->vmperm)) {
+		mutex_unlock(&buffer->lock);
+		return 0;
+	}
+
+	if (buffer->vmap_cnt)
+		invalidate_kernel_vmap_range(buffer->vaddr, buffer->len);
+
+	list_for_each_entry(a, &buffer->attachments, list) {
+		if (!a->mapped)
+			continue;
+		dma_sync_sgtable_for_cpu(a->dev, a->table, direction);
+	}
+
+	mutex_unlock(&buffer->lock);
+
+	return 0;
+}
+
+int qcom_sg_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
+				   enum dma_data_direction direction)
+{
+	struct qcom_sg_buffer *buffer = dmabuf->priv;
+	struct dma_heap_attachment *a;
+
+	if (buffer->uncached)
+		return 0;
+
+	mutex_lock(&buffer->lock);
+
+	/* Keep the same behavior as ion by returning 0 instead of -EPERM */
+	if (!mem_buf_vmperm_can_cmo(buffer->vmperm)) {
+		mutex_unlock(&buffer->lock);
+		return 0;
+	}
+
+	if (buffer->vmap_cnt)
+		flush_kernel_vmap_range(buffer->vaddr, buffer->len);
+
+	list_for_each_entry(a, &buffer->attachments, list) {
+		if (!a->mapped)
+			continue;
+		dma_sync_sgtable_for_device(a->dev, a->table, direction);
+	}
+	mutex_unlock(&buffer->lock);
+
+	return 0;
+}
+
+static int sgl_sync_range(struct device *dev, struct scatterlist *sgl,
+			  unsigned int nents, unsigned long offset,
+			  unsigned long length,
+			  enum dma_data_direction dir, bool for_cpu)
+{
+	int i;
+	struct scatterlist *sg;
+	unsigned int len = 0;
+	dma_addr_t sg_dma_addr;
+
+	for_each_sg(sgl, sg, nents, i) {
+		if (sg_dma_len(sg) == 0)
+			break;
+
+		if (i > 0) {
+			if (!get_dma_ops(dev))
+				return 0;
+
+			pr_warn_ratelimited("Partial cmo only supported with 1 segment\n"
+				"is dma_set_max_seg_size being set on dev:%s\n",
+				dev_name(dev));
+			return -EINVAL;
+		}
+	}
+
+	for_each_sg(sgl, sg, nents, i) {
+		unsigned int sg_offset, sg_left, size = 0;
+
+		if (i == 0)
+			sg_dma_addr = sg_dma_address(sg);
+
+		len += sg->length;
+		if (len <= offset) {
+			sg_dma_addr += sg->length;
+			continue;
+		}
+
+		sg_left = len - offset;
+		sg_offset = sg->length - sg_left;
+
+		size = (length < sg_left) ? length : sg_left;
+		if (for_cpu)
+			dma_sync_single_range_for_cpu(dev, sg_dma_addr,
+						      sg_offset, size, dir);
+		else
+			dma_sync_single_range_for_device(dev, sg_dma_addr,
+							 sg_offset, size, dir);
+
+		offset += size;
+		length -= size;
+		sg_dma_addr += sg->length;
+
+		if (length == 0)
+			break;
+	}
+
+	return 0;
+}
+
+int qcom_sg_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf,
+					     enum dma_data_direction dir,
+					     unsigned int offset,
+					     unsigned int len)
+{
+	struct qcom_sg_buffer *buffer = dmabuf->priv;
+	struct dma_heap_attachment *a;
+	int ret = 0;
+
+	if (buffer->uncached)
+		return 0;
+
+	mutex_lock(&buffer->lock);
+
+	/* Keep the same behavior as ion by returning 0 instead of -EPERM */
+	if (!mem_buf_vmperm_can_cmo(buffer->vmperm)) {
+		mutex_unlock(&buffer->lock);
+		return 0;
+	}
+
+	if (buffer->vmap_cnt)
+		invalidate_kernel_vmap_range(buffer->vaddr + offset, len);
+
+	list_for_each_entry(a, &buffer->attachments, list) {
+		if (!a->mapped)
+			continue;
+
+		ret = sgl_sync_range(a->dev, a->table->sgl, a->table->orig_nents,
+				     offset, len, dir, true);
+	}
+	mutex_unlock(&buffer->lock);
+
+	return ret;
+}
+
+int qcom_sg_dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf,
+					   enum dma_data_direction direction,
+					   unsigned int offset,
+					   unsigned int len)
+{
+	struct qcom_sg_buffer *buffer = dmabuf->priv;
+	struct dma_heap_attachment *a;
+	int ret = 0;
+
+	if (buffer->uncached)
+		return 0;
+
+	mutex_lock(&buffer->lock);
+
+	/* Keep the same behavior as ion by returning 0 instead of -EPERM */
+	if (!mem_buf_vmperm_can_cmo(buffer->vmperm)) {
+		mutex_unlock(&buffer->lock);
+		return 0;
+	}
+
+	if (buffer->vmap_cnt)
+		flush_kernel_vmap_range(buffer->vaddr + offset, len);
+
+	list_for_each_entry(a, &buffer->attachments, list) {
+		if (!a->mapped)
+			continue;
+
+		ret = sgl_sync_range(a->dev, a->table->sgl, a->table->orig_nents,
+				     offset, len, direction, false);
+	}
+	mutex_unlock(&buffer->lock);
+
+	return ret;
+}
+
+static void qcom_sg_vm_ops_open(struct vm_area_struct *vma)
+{
+	struct mem_buf_vmperm *vmperm = vma->vm_private_data;
+
+	mem_buf_vmperm_pin(vmperm);
+}
+
+static void qcom_sg_vm_ops_close(struct vm_area_struct *vma)
+{
+	struct mem_buf_vmperm *vmperm = vma->vm_private_data;
+
+	mem_buf_vmperm_unpin(vmperm);
+}
+
+static const struct vm_operations_struct qcom_sg_vm_ops = {
+	.open = qcom_sg_vm_ops_open,
+	.close = qcom_sg_vm_ops_close,
+};
+
+int qcom_sg_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
+{
+	struct qcom_sg_buffer *buffer = dmabuf->priv;
+	struct sg_table *table = &buffer->sg_table;
+	struct scatterlist *sg;
+	unsigned long addr = vma->vm_start;
+	unsigned long offset = vma->vm_pgoff * PAGE_SIZE;
+	int ret;
+	int i;
+
+	mem_buf_vmperm_pin(buffer->vmperm);
+	if (!mem_buf_vmperm_can_mmap(buffer->vmperm, vma)) {
+		mem_buf_vmperm_unpin(buffer->vmperm);
+		return -EPERM;
+	}
+
+	vma->vm_ops = &qcom_sg_vm_ops;
+	vma->vm_private_data = buffer->vmperm;
+	if (buffer->uncached)
+		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+	for_each_sg(table->sgl, sg, table->nents, i) {
+		struct page *page = sg_page(sg);
+		unsigned long remainder = vma->vm_end - addr;
+		unsigned long len = sg->length;
+
+		if (offset >= sg->length) {
+			offset -= sg->length;
+			continue;
+		} else if (offset) {
+			page += offset / PAGE_SIZE;
+			len = sg->length - offset;
+			offset = 0;
+		}
+		len = min(len, remainder);
+		ret = remap_pfn_range(vma, addr, page_to_pfn(page), len,
+				      vma->vm_page_prot);
+		if (ret) {
+			mem_buf_vmperm_unpin(buffer->vmperm);
+			return ret;
+		}
+		addr += len;
+		if (addr >= vma->vm_end)
+			return 0;
+	}
+	return 0;
+}
+
+void *qcom_sg_do_vmap(struct qcom_sg_buffer *buffer)
+{
+	struct sg_table *table = &buffer->sg_table;
+	int npages = PAGE_ALIGN(buffer->len) / PAGE_SIZE;
+	struct page **pages = vmalloc(sizeof(struct page *) * npages);
+	struct page **tmp = pages;
+	struct sg_page_iter piter;
+	pgprot_t pgprot = PAGE_KERNEL;
+	void *vaddr;
+
+	if (!pages)
+		return ERR_PTR(-ENOMEM);
+
+	if (buffer->uncached)
+		pgprot = pgprot_writecombine(PAGE_KERNEL);
+
+	for_each_sgtable_page(table, &piter, 0) {
+		WARN_ON(tmp - pages >= npages);
+		*tmp++ = sg_page_iter_page(&piter);
+	}
+
+	vaddr = vmap(pages, npages, VM_MAP, pgprot);
+	vfree(pages);
+
+	if (!vaddr)
+		return ERR_PTR(-ENOMEM);
+
+	return vaddr;
+}
+
+int qcom_sg_vmap(struct dma_buf *dmabuf, struct iosys_map *map)
+{
+	struct qcom_sg_buffer *buffer = dmabuf->priv;
+	void *vaddr;
+	int ret = 0;
+
+	mem_buf_vmperm_pin(buffer->vmperm);
+	if (!mem_buf_vmperm_can_vmap(buffer->vmperm)) {
+		mem_buf_vmperm_unpin(buffer->vmperm);
+		return -EPERM;
+	}
+
+	mutex_lock(&buffer->lock);
+	if (buffer->vmap_cnt) {
+		buffer->vmap_cnt++;
+		iosys_map_set_vaddr(map, buffer->vaddr);
+		goto out;
+	}
+
+	vaddr = qcom_sg_do_vmap(buffer);
+	if (IS_ERR(vaddr)) {
+		ret = PTR_ERR(vaddr);
+		mem_buf_vmperm_unpin(buffer->vmperm);
+		goto out;
+	}
+
+	buffer->vaddr = vaddr;
+	buffer->vmap_cnt++;
+	iosys_map_set_vaddr(map, buffer->vaddr);
+out:
+	mutex_unlock(&buffer->lock);
+
+	return ret;
+}
+
+void qcom_sg_vunmap(struct dma_buf *dmabuf, struct iosys_map *map)
+{
+	struct qcom_sg_buffer *buffer = dmabuf->priv;
+
+	mutex_lock(&buffer->lock);
+	if (!--buffer->vmap_cnt) {
+		vunmap(buffer->vaddr);
+		buffer->vaddr = NULL;
+	}
+	mem_buf_vmperm_unpin(buffer->vmperm);
+	mutex_unlock(&buffer->lock);
+	iosys_map_clear(map);
+}
+
+void qcom_sg_release(struct dma_buf *dmabuf)
+{
+	struct qcom_sg_buffer *buffer = dmabuf->priv;
+
+	if (mem_buf_vmperm_release(buffer->vmperm))
+		return;
+
+	msm_dma_buf_freed(buffer);
+	buffer->free(buffer);
+}
+
+struct mem_buf_vmperm *qcom_sg_lookup_vmperm(struct dma_buf *dmabuf)
+{
+	struct qcom_sg_buffer *buffer = dmabuf->priv;
+
+	return buffer->vmperm;
+}
+
+struct mem_buf_dma_buf_ops qcom_sg_buf_ops = {
+	.attach = qcom_sg_attach,
+	.lookup = qcom_sg_lookup_vmperm,
+	.dma_ops = {
+		.attach = NULL, /* Will be set by mem_buf_dma_buf_export */
+		.detach = qcom_sg_detach,
+		.map_dma_buf = qcom_sg_map_dma_buf,
+		.unmap_dma_buf = qcom_sg_unmap_dma_buf,
+		.begin_cpu_access = qcom_sg_dma_buf_begin_cpu_access,
+		.end_cpu_access = qcom_sg_dma_buf_end_cpu_access,
+		.begin_cpu_access_partial = qcom_sg_dma_buf_begin_cpu_access_partial,
+		.end_cpu_access_partial = qcom_sg_dma_buf_end_cpu_access_partial,
+		.mmap = qcom_sg_mmap,
+		.vmap = qcom_sg_vmap,
+		.vunmap = qcom_sg_vunmap,
+		.release = qcom_sg_release,
+	}
+};
+EXPORT_SYMBOL_GPL(qcom_sg_buf_ops);
+
+int qti_smmu_proxy_register_callbacks(smmu_proxy_map_sgtable map_sgtable_fn_ptr,
+				      smmu_proxy_unmap_sgtable unmap_sgtable_fn_ptr)
+{
+	smmu_proxy_callback_ops.map_sgtable = map_sgtable_fn_ptr;
+	smmu_proxy_callback_ops.unmap_sgtable = unmap_sgtable_fn_ptr;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(qti_smmu_proxy_register_callbacks);
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_sg_ops.h
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_sg_ops.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2011 Google, Inc.
+ * Copyright (C) 2019, 2020 Linaro Ltd.
+ *
+ * Portions based off of Andrew Davis' SRAM heap:
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ *	Andrew F. Davis <afd@ti.com>
+ *
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _QCOM_SG_OPS_H
+#define _QCOM_SG_OPS_H
+
+#include <linux/scatterlist.h>
+#include <linux/dma-heap.h>
+#include <linux/device.h>
+#include "qcom_dma_heap_priv.h"
+
+struct qcom_sg_buffer {
+	struct dma_heap *heap;
+	struct list_head attachments;
+	struct mutex lock;
+	unsigned long len;
+	struct sg_table sg_table;
+	int vmap_cnt;
+	void *vaddr;
+	bool uncached;
+	struct mem_buf_vmperm *vmperm;
+	void (*free)(struct qcom_sg_buffer *buffer);
+};
+
+struct dma_heap_attachment {
+	struct device *dev;
+	struct sg_table *table;
+	struct list_head list;
+	bool mapped;
+};
+
+int qcom_sg_attach(struct dma_buf *dmabuf,
+		   struct dma_buf_attachment *attachment);
+
+void qcom_sg_detach(struct dma_buf *dmabuf,
+		    struct dma_buf_attachment *attachment);
+
+struct sg_table *qcom_sg_map_dma_buf(struct dma_buf_attachment *attachment,
+				     enum dma_data_direction direction);
+
+void qcom_sg_unmap_dma_buf(struct dma_buf_attachment *attachment,
+			   struct sg_table *table,
+			   enum dma_data_direction direction);
+
+int qcom_sg_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
+				     enum dma_data_direction direction);
+
+int qcom_sg_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
+				   enum dma_data_direction direction);
+
+int qcom_sg_dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf,
+					     enum dma_data_direction dir,
+					     unsigned int offset,
+					     unsigned int len);
+
+int qcom_sg_dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf,
+					   enum dma_data_direction direction,
+					   unsigned int offset,
+					   unsigned int len);
+
+int qcom_sg_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma);
+
+void *qcom_sg_do_vmap(struct qcom_sg_buffer *buffer);
+
+int qcom_sg_vmap(struct dma_buf *dmabuf, struct iosys_map *map);
+
+void qcom_sg_vunmap(struct dma_buf *dmabuf, struct iosys_map *map);
+
+void qcom_sg_release(struct dma_buf *dmabuf);
+
+struct mem_buf_vmperm *qcom_sg_lookup_vmperm(struct dma_buf *dmabuf);
+
+extern struct mem_buf_dma_buf_ops qcom_sg_buf_ops;
+
+#endif /* _QCOM_SG_OPS_H */
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_system_heap.c
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_system_heap.c
@@ -0,0 +1,620 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * DMABUF System heap exporter
+ * Originally copied from: drivers/dma-buf/heaps/system_heap.c as of commit
+ * 263e38f82cbb ("dma-buf: heaps: Remove redundant heap identifier from system
+ * heap name")
+ *
+ * Additions taken from modifications to drivers/dma-buf/heaps/system-heap.c,
+ * from patches submitted, are listed below:
+ *
+ * Addition that modifies dma_buf ops to use SG tables taken from
+ * drivers/dma-buf/heaps/system-heap.c in:
+ * https://lore.kernel.org/lkml/20201017013255.43568-2-john.stultz@linaro.org/
+ *
+ * Addition that skips unneeded syncs in the dma_buf ops taken from
+ * https://lore.kernel.org/lkml/20201017013255.43568-5-john.stultz@linaro.org/
+ *
+ * Addition that tries to allocate higher order pages taken from
+ * https://lore.kernel.org/lkml/20201017013255.43568-6-john.stultz@linaro.org/
+ *
+ * Addition that implements an uncached heap taken from
+ * https://lore.kernel.org/lkml/20201017013255.43568-8-john.stultz@linaro.org/,
+ * with our own modificaitons made to account for core kernel changes that are
+ * a part of the patch series.
+ *
+ * Pooling functionality taken from:
+ * Git-repo: https://git.linaro.org/people/john.stultz/android-dev.git
+ * Branch: dma-buf-heap-perf
+ * Git-commit: 6f080eb67dce63c6efa57ef564ca4cd762ccebb0
+ * Git-commit: 6fb9593b928c4cb485bef4e88c59c6b9fdf11352
+ *
+ * Copyright (C) 2011 Google, Inc.
+ * Copyright (C) 2019, 2020 Linaro Ltd.
+ *
+ * Portions based off of Andrew Davis' SRAM heap:
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ *	Andrew F. Davis <afd@ti.com>
+ *
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/dma-buf.h>
+#include <linux/dma-mapping.h>
+#include <linux/dma-heap.h>
+#include <linux/err.h>
+#include <linux/highmem.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/kthread.h>
+#include <linux/qcom_dma_heap.h>
+#include <uapi/linux/sched/types.h>
+
+#include "qcom_dma_heap_secure_utils.h"
+#include "qcom_dynamic_page_pool.h"
+#include "qcom_sg_ops.h"
+#include "qcom_system_heap.h"
+#include "../../../mm/internal.h"
+
+#if IS_ENABLED(CONFIG_QCOM_DMABUF_HEAPS_PAGE_POOL_REFILL)
+#define DYNAMIC_POOL_FILL_MARK (100 * SZ_1M)
+#define DYNAMIC_POOL_LOW_MARK_PERCENT 40UL
+#define DYNAMIC_POOL_LOW_MARK ((DYNAMIC_POOL_FILL_MARK * DYNAMIC_POOL_LOW_MARK_PERCENT) / 100)
+
+#define DYNAMIC_POOL_REFILL_DEFER_WINDOW_MS 10
+#define DYNAMIC_POOL_KTHREAD_NICE_VAL 10
+
+static int get_dynamic_pool_fillmark(struct dynamic_page_pool *pool)
+{
+	return DYNAMIC_POOL_FILL_MARK / (PAGE_SIZE << pool->order);
+}
+
+static bool dynamic_pool_fillmark_reached(struct dynamic_page_pool *pool)
+{
+	return atomic_read(&pool->count) >= get_dynamic_pool_fillmark(pool);
+}
+
+static int get_dynamic_pool_lowmark(struct dynamic_page_pool *pool)
+{
+	return DYNAMIC_POOL_LOW_MARK / (PAGE_SIZE << pool->order);
+}
+
+static bool dynamic_pool_count_below_lowmark(struct dynamic_page_pool *pool)
+{
+	return atomic_read(&pool->count) < get_dynamic_pool_lowmark(pool);
+}
+
+/* Based on gfp_zone() in mm/mmzone.c since it is not exported. */
+enum zone_type dynamic_pool_gfp_zone(gfp_t flags)
+{
+	enum zone_type z;
+	gfp_t local_flags = flags;
+	int bit;
+
+	bit = (__force int) ((local_flags) & GFP_ZONEMASK);
+
+	z = (GFP_ZONE_TABLE >> (bit * GFP_ZONES_SHIFT)) &
+					 ((1 << GFP_ZONES_SHIFT) - 1);
+	VM_BUG_ON((GFP_ZONE_BAD >> bit) & 1);
+	return z;
+}
+
+/*
+ * Based on __zone_watermark_ok() in mm/page_alloc.c since it is not exported.
+ *
+ * Return true if free base pages are above 'mark'. For high-order checks it
+ * will return true of the order-0 watermark is reached and there is at least
+ * one free page of a suitable size. Checking now avoids taking the zone lock
+ * to check in the allocation paths if no pages are free.
+ */
+static bool __dynamic_pool_zone_watermark_ok(struct zone *z, unsigned int order, unsigned long mark,
+					     int highest_zoneidx, long free_pages)
+{
+	long min = mark;
+	long unusable_free;
+	int o;
+
+	/*
+	 * Access to high atomic reserves is not required, and CMA should not be
+	 * used, since these allocations are non-movable.
+	 */
+	unusable_free = ((1 << order) - 1) + z->nr_reserved_highatomic;
+#ifdef CONFIG_CMA
+	unusable_free += zone_page_state(z, NR_FREE_CMA_PAGES);
+#endif
+
+	/* free_pages may go negative - that's OK */
+	free_pages -= unusable_free;
+
+	/*
+	 * Check watermarks for an order-0 allocation request. If these
+	 * are not met, then a high-order request also cannot go ahead
+	 * even if a suitable page happened to be free.
+	 *
+	 * 'min' can be taken as 'mark' since we do not expect these allocations
+	 * to require disruptive actions (such as running the OOM killer) or
+	 * a lot of effort.
+	 */
+	if (free_pages <= min + z->lowmem_reserve[highest_zoneidx])
+		return false;
+
+	/* If this is an order-0 request then the watermark is fine */
+	if (!order)
+		return true;
+
+	/* For a high-order request, check at least one suitable page is free */
+	for (o = order; o < MAX_ORDER; o++) {
+		struct free_area *area = &z->free_area[o];
+		int mt;
+
+		if (!area->nr_free)
+			continue;
+
+		for (mt = 0; mt < MIGRATE_PCPTYPES; mt++) {
+			if (!free_area_empty(area, mt))
+				return true;
+		}
+	}
+
+	return false;
+}
+
+/* Based on zone_watermark_ok_safe from mm/page_alloc.c since it is not exported. */
+bool dynamic_pool_zone_watermark_ok_safe(struct zone *z, unsigned int order,
+						unsigned long mark, int highest_zoneidx)
+{
+	long free_pages = zone_page_state(z, NR_FREE_PAGES);
+
+	if (z->percpu_drift_mark && free_pages < z->percpu_drift_mark)
+		free_pages = zone_page_state_snapshot(z, NR_FREE_PAGES);
+
+	return __dynamic_pool_zone_watermark_ok(z, order, mark, highest_zoneidx, free_pages);
+}
+
+/* do a simple check to see if we are in any low memory situation */
+static bool dynamic_pool_refill_ok(struct dynamic_page_pool *pool)
+{
+	struct zone *zone;
+	int i, mark;
+	enum zone_type classzone_idx = dynamic_pool_gfp_zone(pool->gfp_mask);
+	s64 delta;
+
+	/* check if we are within the refill defer window */
+	delta = ktime_ms_delta(ktime_get(), pool->last_low_watermark_ktime);
+	if (delta < DYNAMIC_POOL_REFILL_DEFER_WINDOW_MS)
+		return false;
+
+	/*
+	 * make sure that if we allocate a pool->order page from buddy,
+	 * we don't put the zone watermarks below the high threshold.
+	 * This makes sure there's no unwanted repetitive refilling and
+	 * reclaiming of buddy pages on the pool.
+	 */
+	for (i = classzone_idx; i >= 0; i--) {
+		zone = &NODE_DATA(numa_node_id())->node_zones[i];
+
+		if (!strcmp(zone->name, "DMA32"))
+			continue;
+
+		mark = high_wmark_pages(zone);
+		mark += 1 << pool->order;
+		if (!dynamic_pool_zone_watermark_ok_safe(zone, pool->order, mark, classzone_idx)) {
+			pool->last_low_watermark_ktime = ktime_get();
+			return false;
+		}
+	}
+
+	return true;
+}
+
+static void dynamic_page_pool_refill(struct dynamic_page_pool *pool)
+{
+	struct page *page;
+	gfp_t gfp_refill = (pool->gfp_mask | __GFP_RECLAIM) & ~__GFP_NORETRY;
+
+	/* skip refilling order 0 pools */
+	if (!pool->order)
+		return;
+
+	while (!dynamic_pool_fillmark_reached(pool) && dynamic_pool_refill_ok(pool)) {
+		page = alloc_pages(gfp_refill, pool->order);
+		if (!page)
+			break;
+
+		dynamic_page_pool_add(pool, page);
+	}
+}
+
+static bool dynamic_pool_needs_refill(struct dynamic_page_pool *pool)
+{
+	return pool->order && dynamic_pool_count_below_lowmark(pool);
+}
+
+static int system_heap_refill_worker(void *data)
+{
+	struct dynamic_page_pool **pool_list = data;
+	int i;
+
+	for (;;) {
+		for (i = 0; i < NUM_ORDERS; i++) {
+			if (dynamic_pool_count_below_lowmark(pool_list[i]))
+				dynamic_page_pool_refill(pool_list[i]);
+		}
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (unlikely(kthread_should_stop())) {
+			set_current_state(TASK_RUNNING);
+			break;
+		}
+		schedule();
+
+		set_current_state(TASK_RUNNING);
+	}
+
+	return 0;
+}
+
+static int system_heap_create_refill_worker(struct qcom_system_heap *sys_heap, const char *name)
+{
+	struct task_struct *refill_worker;
+	struct sched_attr attr = { .sched_nice = DYNAMIC_POOL_KTHREAD_NICE_VAL };
+	int ret;
+	int i;
+
+	refill_worker = kthread_run(system_heap_refill_worker, sys_heap->pool_list,
+				    "%s-pool-refill-thread", name);
+	if (IS_ERR(refill_worker)) {
+		pr_err("%s: failed to create %s-pool-refill-thread: %ld\n",
+			__func__, name, PTR_ERR(refill_worker));
+		return PTR_ERR(refill_worker);
+	}
+
+	ret = sched_setattr(refill_worker, &attr);
+	if (ret) {
+		pr_warn("%s: failed to set task priority for %s-pool-refill-thread: ret = %d\n",
+			__func__, name, ret);
+		kthread_stop(refill_worker);
+		return ret;
+	}
+
+	for (i = 0; i < NUM_ORDERS; i++)
+		sys_heap->pool_list[i]->refill_worker = refill_worker;
+
+	return ret;
+}
+
+static void system_heap_destroy_refill_worker(struct qcom_system_heap *sys_heap)
+{
+	kthread_stop(sys_heap->pool_list[0]->refill_worker);
+}
+#else
+static bool dynamic_pool_needs_refill(struct dynamic_page_pool *pool)
+{
+	return false;
+}
+
+static int system_heap_create_refill_worker(struct qcom_system_heap *sys_heap, const char *name)
+{
+	return 0;
+}
+
+static void system_heap_destroy_refill_worker(struct qcom_system_heap *sys_heap)
+{
+}
+#endif
+
+static int system_heap_clear_pages(struct page **pages, int num, pgprot_t pgprot)
+{
+	void *addr = vmap(pages, num, VM_MAP, pgprot);
+
+	if (!addr)
+		return -ENOMEM;
+	memset(addr, 0, PAGE_SIZE * num);
+	vunmap(addr);
+	return 0;
+}
+
+static int system_heap_zero_buffer(struct qcom_sg_buffer *buffer)
+{
+	struct sg_table *sgt = &buffer->sg_table;
+	struct sg_page_iter piter;
+	struct page *pages[32];
+	int p = 0;
+	int ret = 0;
+
+	for_each_sgtable_page(sgt, &piter, 0) {
+		pages[p++] = sg_page_iter_page(&piter);
+		if (p == ARRAY_SIZE(pages)) {
+			ret = system_heap_clear_pages(pages, p, PAGE_KERNEL);
+			if (ret)
+				return ret;
+			p = 0;
+		}
+	}
+	if (p)
+		ret = system_heap_clear_pages(pages, p, PAGE_KERNEL);
+
+	return ret;
+}
+
+void qcom_system_heap_free(struct qcom_sg_buffer *buffer)
+{
+	struct qcom_system_heap *sys_heap;
+	struct sg_table *table;
+	struct scatterlist *sg;
+	int i, j;
+
+	sys_heap = dma_heap_get_drvdata(buffer->heap);
+	table = &buffer->sg_table;
+
+	/* Zero the buffer pages before adding back to the pool */
+	system_heap_zero_buffer(buffer);
+
+	for_each_sg(table->sgl, sg, table->nents, i) {
+		struct page *page = sg_page(sg);
+
+		for (j = 0; j < NUM_ORDERS; j++) {
+			if (compound_order(page) == orders[j])
+				break;
+		}
+
+		/* Do not keep page in the pool if it is a zone movable page */
+		if (is_zone_movable_page(page)) {
+			/* Unpin the page before freeing page back to buddy */
+			put_page(page);
+			__free_pages(page, compound_order(page));
+		} else {
+			dynamic_page_pool_free(sys_heap->pool_list[j], page);
+		}
+	}
+	sg_free_table(table);
+	kfree(buffer);
+}
+
+struct page *qcom_sys_heap_alloc_largest_available(struct dynamic_page_pool **pools,
+						   unsigned long size,
+						   unsigned int max_order,
+						   bool movable)
+{
+	struct page *page = NULL;
+	int i;
+
+	for (i = 0; i < NUM_ORDERS; i++) {
+		unsigned long flags;
+
+		if (size <  (PAGE_SIZE << orders[i]))
+			continue;
+		if (max_order < orders[i])
+			continue;
+
+		spin_lock_irqsave(&pools[i]->lock, flags);
+		if (pools[i]->high_count)
+			page = dynamic_page_pool_remove(pools[i], true);
+		else if (pools[i]->low_count)
+			page = dynamic_page_pool_remove(pools[i], false);
+		spin_unlock_irqrestore(&pools[i]->lock, flags);
+
+		if (!page)
+			page = alloc_pages(pools[i]->gfp_mask, pools[i]->order);
+		if (!page)
+			continue;
+
+		if (dynamic_pool_needs_refill(pools[i]))
+			wake_up_process(pools[i]->refill_worker);
+
+		return page;
+	}
+	return NULL;
+}
+
+int system_qcom_sg_buffer_alloc(struct dma_heap *heap,
+				struct qcom_sg_buffer *buffer,
+				unsigned long len,
+				bool movable)
+{
+	struct qcom_system_heap *sys_heap;
+	unsigned long size_remaining = len;
+	unsigned int max_order = orders[0];
+	struct sg_table *table;
+	struct scatterlist *sg;
+	struct list_head pages;
+	struct page *page, *tmp_page;
+	int i, ret = -ENOMEM;
+
+	sys_heap = dma_heap_get_drvdata(heap);
+
+	INIT_LIST_HEAD(&buffer->attachments);
+	mutex_init(&buffer->lock);
+	buffer->heap = heap;
+	buffer->len = len;
+	buffer->uncached = sys_heap->uncached;
+	buffer->free = qcom_system_heap_free;
+
+	INIT_LIST_HEAD(&pages);
+	i = 0;
+	while (size_remaining > 0) {
+		/*
+		 * Avoid trying to allocate memory if the process
+		 * has been killed by SIGKILL
+		 */
+		if (fatal_signal_pending(current))
+			goto free_mem;
+
+		page = qcom_sys_heap_alloc_largest_available(sys_heap->pool_list,
+							     size_remaining,
+							     max_order,
+							     movable);
+		if (!page)
+			goto free_mem;
+
+		list_add_tail(&page->lru, &pages);
+		size_remaining -= page_size(page);
+		max_order = compound_order(page);
+		i++;
+	}
+
+	table = &buffer->sg_table;
+	if (sg_alloc_table(table, i, GFP_KERNEL))
+		goto free_mem;
+
+	sg = table->sgl;
+	list_for_each_entry_safe(page, tmp_page, &pages, lru) {
+		sg_set_page(sg, page, page_size(page), 0);
+		sg = sg_next(sg);
+		list_del(&page->lru);
+	}
+
+	/*
+	 * For uncached buffers, we need to initially flush cpu cache, since
+	 * the __GFP_ZERO on the allocation means the zeroing was done by the
+	 * cpu and thus it is likely cached. Map (and implicitly flush) and
+	 * unmap it now so we don't get corruption later on.
+	 */
+	if (buffer->uncached) {
+		dma_map_sgtable(dma_heap_get_dev(heap), table, DMA_BIDIRECTIONAL, 0);
+		dma_unmap_sgtable(dma_heap_get_dev(heap), table, DMA_BIDIRECTIONAL, 0);
+	}
+
+	return 0;
+
+free_mem:
+	list_for_each_entry_safe(page, tmp_page, &pages, lru) {
+		/* Unpin the memory first if it was borrowed from movable zone */
+		if (is_zone_movable_page(page))
+			put_page(page);
+		__free_pages(page, compound_order(page));
+	}
+
+	return ret;
+}
+
+static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
+					    unsigned long len,
+					    u32 fd_flags,
+					    u64 heap_flags)
+{
+	struct qcom_sg_buffer *buffer;
+	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+	struct dma_buf *dmabuf;
+	int ret;
+
+	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
+	if (!buffer)
+		return ERR_PTR(-ENOMEM);
+
+	ret = system_qcom_sg_buffer_alloc(heap, buffer, len, false);
+	if (ret)
+		goto free_buf_struct;
+
+	buffer->vmperm = mem_buf_vmperm_alloc(&buffer->sg_table);
+	if (IS_ERR(buffer->vmperm)) {
+		ret = PTR_ERR(buffer->vmperm);
+		goto free_sys_heap_mem;
+	}
+
+	/* create the dmabuf */
+	exp_info.exp_name = dma_heap_get_name(heap);
+	exp_info.size = buffer->len;
+	exp_info.flags = fd_flags;
+	exp_info.priv = buffer;
+	dmabuf = qcom_dma_buf_export(&exp_info, &qcom_sg_buf_ops);
+	if (IS_ERR(dmabuf)) {
+		ret = PTR_ERR(dmabuf);
+		goto free_vmperm;
+	}
+
+	return dmabuf;
+
+free_vmperm:
+	mem_buf_vmperm_release(buffer->vmperm);
+free_sys_heap_mem:
+	qcom_system_heap_free(buffer);
+	return ERR_PTR(ret);
+free_buf_struct:
+	kfree(buffer);
+
+	return ERR_PTR(ret);
+}
+
+static const struct dma_heap_ops system_heap_ops = {
+	.allocate = system_heap_allocate,
+};
+
+void qcom_system_heap_create(const char *name, const char *system_alias, bool uncached)
+{
+	struct dma_heap_export_info exp_info;
+	struct dma_heap *heap;
+	struct qcom_system_heap *sys_heap;
+	int ret;
+
+	ret = dynamic_page_pool_init_shrinker();
+	if (ret)
+		goto out;
+
+	sys_heap = kzalloc(sizeof(*sys_heap), GFP_KERNEL);
+	if (!sys_heap) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	exp_info.name = name;
+	exp_info.ops = &system_heap_ops;
+	exp_info.priv = sys_heap;
+
+	sys_heap->uncached = uncached;
+
+	sys_heap->pool_list = dynamic_page_pool_create_pools(0, NULL);
+	if (IS_ERR(sys_heap->pool_list)) {
+		ret = PTR_ERR(sys_heap->pool_list);
+		goto free_heap;
+	}
+
+	ret = system_heap_create_refill_worker(sys_heap, name);
+	if (ret)
+		goto free_pools;
+
+	heap = dma_heap_add(&exp_info);
+	if (IS_ERR(heap)) {
+		ret = PTR_ERR(heap);
+		goto stop_worker;
+	}
+
+	if (uncached)
+		dma_coerce_mask_and_coherent(dma_heap_get_dev(heap),
+					     DMA_BIT_MASK(64));
+
+	pr_info("%s: DMA-BUF Heap: Created '%s'\n", __func__, name);
+
+	if (system_alias != NULL) {
+		exp_info.name = system_alias;
+
+		heap = dma_heap_add(&exp_info);
+		if (IS_ERR(heap)) {
+			pr_err("%s: Failed to create '%s', error is %ld\n", __func__,
+			       system_alias, PTR_ERR(heap));
+			return;
+		}
+
+		dma_coerce_mask_and_coherent(dma_heap_get_dev(heap), DMA_BIT_MASK(64));
+
+		pr_info("%s: DMA-BUF Heap: Created '%s'\n", __func__, system_alias);
+	}
+
+	return;
+
+stop_worker:
+	system_heap_destroy_refill_worker(sys_heap);
+
+free_pools:
+	dynamic_page_pool_release_pools(sys_heap->pool_list);
+
+free_heap:
+	kfree(sys_heap);
+
+out:
+	pr_err("%s: Failed to create '%s', error is %d\n", __func__, name, ret);
+}
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/qcom_system_heap.h
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/qcom_system_heap.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _QCOM_SYSTEM_HEAP_H
+#define _QCOM_SYSTEM_HEAP_H
+
+#include <linux/dma-heap.h>
+#include <linux/err.h>
+#include "qcom_sg_ops.h"
+#include "qcom_dynamic_page_pool.h"
+#include "qcom_sg_ops.h"
+
+struct qcom_system_heap {
+	int uncached;
+	struct dynamic_page_pool **pool_list;
+};
+
+#ifdef CONFIG_QCOM_DMABUF_HEAPS_SYSTEM
+void qcom_system_heap_create(const char *name, const char *system_alias, bool uncached);
+void qcom_system_heap_free(struct qcom_sg_buffer *buffer);
+struct page *qcom_sys_heap_alloc_largest_available(struct dynamic_page_pool **pools,
+						   unsigned long size,
+						   unsigned int max_order,
+						   bool movable);
+int system_qcom_sg_buffer_alloc(struct dma_heap *heap,
+				struct qcom_sg_buffer *buffer,
+				unsigned long len,
+				bool movable);
+enum zone_type dynamic_pool_gfp_zone(gfp_t flags);
+
+bool dynamic_pool_zone_watermark_ok_safe(struct zone *z, unsigned int order,
+					unsigned long mark, int highest_zoneidx);
+#else
+static inline void qcom_system_heap_create(const char *name, const char *system_alias,
+					   bool uncached)
+{
+
+}
+static inline void qcom_system_heap_free(struct qcom_sg_buffer *buffer)
+{
+
+}
+static inline struct page *qcom_sys_heap_alloc_largest_available(struct dynamic_page_pool **pools,
+								 unsigned long size,
+								 unsigned int max_order,
+								 bool movable)
+{
+	return ERR_PTR(-EOPNOTSUPP);
+}
+static inline int system_qcom_sg_buffer_alloc(struct dma_heap *heap,
+					      struct qcom_sg_buffer *buffer,
+					      unsigned long len,
+					      bool movable)
+{
+	return -EOPNOTSUPP;
+}
+enum zone_type dynamic_pool_gfp_zone(gfp_t flags)
+{
+	return -EOPNOTSUPP;
+}
+
+bool dynamic_pool_zone_watermark_ok_safe(struct zone *z, unsigned int order,
+					unsigned long mark, int highest_zoneidx)
+{
+	return -EOPNOTSUPP;
+}
+#endif
+
+#endif /* _QCOM_SYSTEM_HEAP_H */
--- linux-qcom-6.8.0.orig/drivers/dma-buf/heaps/system_heap.c
+++ linux-qcom-6.8.0/drivers/dma-buf/heaps/system_heap.c
@@ -333,8 +333,8 @@
 
 static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
 					    unsigned long len,
-					    unsigned long fd_flags,
-					    unsigned long heap_flags)
+					    u32 fd_flags,
+					    u64 heap_flags)
 {
 	struct system_heap_buffer *buffer;
 	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
--- linux-qcom-6.8.0.orig/drivers/dma-buf/st-dma-fence-chain.c
+++ linux-qcom-6.8.0/drivers/dma-buf/st-dma-fence-chain.c
@@ -84,11 +84,11 @@
 		return -ENOMEM;
 
 	chain = mock_chain(NULL, f, 1);
-	if (!chain)
+	if (chain)
+		dma_fence_enable_sw_signaling(chain);
+	else
 		err = -ENOMEM;
 
-	dma_fence_enable_sw_signaling(chain);
-
 	dma_fence_signal(f);
 	dma_fence_put(f);
 
--- linux-qcom-6.8.0.orig/drivers/dma-buf/st-dma-fence.c
+++ linux-qcom-6.8.0/drivers/dma-buf/st-dma-fence.c
@@ -540,6 +540,12 @@
 			t[i].before = pass;
 			t[i].task = kthread_run(thread_signal_callback, &t[i],
 						"dma-fence:%d", i);
+			if (IS_ERR(t[i].task)) {
+				ret = PTR_ERR(t[i].task);
+				while (--i >= 0)
+					kthread_stop_put(t[i].task);
+				return ret;
+			}
 			get_task_struct(t[i].task);
 		}
 
--- linux-qcom-6.8.0.orig/drivers/dma-buf/sync_debug.c
+++ linux-qcom-6.8.0/drivers/dma-buf/sync_debug.c
@@ -110,12 +110,12 @@
 
 	seq_printf(s, "%s: %d\n", obj->name, obj->value);
 
-	spin_lock_irq(&obj->lock);
+	spin_lock(&obj->lock); /* Caller already disabled IRQ. */
 	list_for_each(pos, &obj->pt_list) {
 		struct sync_pt *pt = container_of(pos, struct sync_pt, link);
 		sync_print_fence(s, &pt->base, false);
 	}
-	spin_unlock_irq(&obj->lock);
+	spin_unlock(&obj->lock);
 }
 
 static void sync_print_sync_file(struct seq_file *s,
--- linux-qcom-6.8.0.orig/drivers/dma-buf/udmabuf.c
+++ linux-qcom-6.8.0/drivers/dma-buf/udmabuf.c
@@ -35,12 +35,13 @@
 	struct vm_area_struct *vma = vmf->vma;
 	struct udmabuf *ubuf = vma->vm_private_data;
 	pgoff_t pgoff = vmf->pgoff;
+	unsigned long pfn;
 
 	if (pgoff >= ubuf->pagecount)
 		return VM_FAULT_SIGBUS;
-	vmf->page = ubuf->pages[pgoff];
-	get_page(vmf->page);
-	return 0;
+
+	pfn = page_to_pfn(ubuf->pages[pgoff]);
+	return vmf_insert_pfn(vma, vmf->address, pfn);
 }
 
 static const struct vm_operations_struct udmabuf_vm_ops = {
@@ -56,6 +57,7 @@
 
 	vma->vm_ops = &udmabuf_vm_ops;
 	vma->vm_private_data = ubuf;
+	vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
 	return 0;
 }
 
@@ -192,7 +194,7 @@
 };
 
 #define SEALS_WANTED (F_SEAL_SHRINK)
-#define SEALS_DENIED (F_SEAL_WRITE)
+#define SEALS_DENIED (F_SEAL_WRITE|F_SEAL_FUTURE_WRITE)
 
 static long udmabuf_create(struct miscdevice *device,
 			   struct udmabuf_create_list *head,
--- linux-qcom-6.8.0.orig/drivers/dma/Kconfig
+++ linux-qcom-6.8.0/drivers/dma/Kconfig
@@ -394,7 +394,7 @@
 
 config MCF_EDMA
 	tristate "Freescale eDMA engine support, ColdFire mcf5441x SoCs"
-	depends on M5441x || COMPILE_TEST
+	depends on M5441x || (COMPILE_TEST && FSL_EDMA=n)
 	select DMA_ENGINE
 	select DMA_VIRTUAL_CHANNELS
 	help
@@ -643,16 +643,16 @@
 
 config TEGRA210_ADMA
 	tristate "NVIDIA Tegra210 ADMA support"
-	depends on (ARCH_TEGRA_210_SOC || COMPILE_TEST)
+	depends on (ARCH_TEGRA || COMPILE_TEST)
 	select DMA_ENGINE
 	select DMA_VIRTUAL_CHANNELS
 	help
-	  Support for the NVIDIA Tegra210 ADMA controller driver. The
-	  DMA controller has multiple DMA channels and is used to service
-	  various audio clients in the Tegra210 audio processing engine
-	  (APE). This DMA controller transfers data from memory to
-	  peripheral and vice versa. It does not support memory to
-	  memory data transfer.
+	  Support for the NVIDIA Tegra210/Tegra186/Tegra194/Tegra234 ADMA
+	  controller driver. The DMA controller has multiple DMA channels
+	  and is used to service various audio clients in the Tegra210
+	  audio processing engine (APE). This DMA controller transfers
+	  data from memory to peripheral and vice versa. It does not
+	  support memory to memory data transfer.
 
 config TIMB_DMA
 	tristate "Timberdale FPGA DMA support"
--- linux-qcom-6.8.0.orig/drivers/dma/altera-msgdma.c
+++ linux-qcom-6.8.0/drivers/dma/altera-msgdma.c
@@ -233,7 +233,7 @@
 	struct msgdma_sw_desc *child, *next;
 
 	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) {
 		mdev->desc_free_cnt++;
 		list_move_tail(&child->node, &mdev->free_list);
@@ -583,17 +583,16 @@
 static void msgdma_chan_desc_cleanup(struct msgdma_device *mdev)
 {
 	struct msgdma_sw_desc *desc, *next;
+	unsigned long irqflags;
 
 	list_for_each_entry_safe(desc, next, &mdev->done_list, node) {
 		struct dmaengine_desc_callback cb;
 
-		list_del(&desc->node);
-
 		dmaengine_desc_get_callback(&desc->async_tx, &cb);
 		if (dmaengine_desc_callback_valid(&cb)) {
-			spin_unlock(&mdev->lock);
+			spin_unlock_irqrestore(&mdev->lock, irqflags);
 			dmaengine_desc_callback_invoke(&cb, NULL);
-			spin_lock(&mdev->lock);
+			spin_lock_irqsave(&mdev->lock, irqflags);
 		}
 
 		/* Run any dependencies, then free the descriptor */
--- linux-qcom-6.8.0.orig/drivers/dma/apple-admac.c
+++ linux-qcom-6.8.0/drivers/dma/apple-admac.c
@@ -153,6 +153,8 @@
 {
 	struct admac_sram *sram;
 	int i, ret = 0, nblocks;
+	ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE);
+	ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE);
 
 	if (dir == DMA_MEM_TO_DEV)
 		sram = &ad->txcache;
@@ -912,12 +914,7 @@
 		goto free_irq;
 	}
 
-	ad->txcache.size = readl_relaxed(ad->base + REG_TX_SRAM_SIZE);
-	ad->rxcache.size = readl_relaxed(ad->base + REG_RX_SRAM_SIZE);
-
 	dev_info(&pdev->dev, "Audio DMA Controller\n");
-	dev_info(&pdev->dev, "imprint %x TX cache %u RX cache %u\n",
-		 readl_relaxed(ad->base + REG_IMPRINT), ad->txcache.size, ad->rxcache.size);
 
 	return 0;
 
--- linux-qcom-6.8.0.orig/drivers/dma/at_xdmac.c
+++ linux-qcom-6.8.0/drivers/dma/at_xdmac.c
@@ -1363,6 +1363,8 @@
 		return NULL;
 
 	desc = at_xdmac_memset_create_desc(chan, atchan, dest, len, value);
+	if (!desc)
+		return NULL;
 	list_add_tail(&desc->desc_node, &desc->descs_list);
 
 	desc->tx_dma_desc.cookie = -EBUSY;
--- linux-qcom-6.8.0.orig/drivers/dma/dma-axi-dmac.c
+++ linux-qcom-6.8.0/drivers/dma/dma-axi-dmac.c
@@ -1134,8 +1134,8 @@
 {
 	struct axi_dmac *dmac = platform_get_drvdata(pdev);
 
-	of_dma_controller_free(pdev->dev.of_node);
 	free_irq(dmac->irq, dmac);
+	of_dma_controller_free(pdev->dev.of_node);
 	tasklet_kill(&dmac->chan.vchan.task);
 	dma_async_device_unregister(&dmac->dma_dev);
 	clk_disable_unprepare(dmac->clk);
--- linux-qcom-6.8.0.orig/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
+++ linux-qcom-6.8.0/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c
@@ -302,6 +302,7 @@
 		kfree(desc);
 		return NULL;
 	}
+	desc->nr_hw_descs = num;
 
 	return desc;
 }
@@ -328,7 +329,7 @@
 static void axi_desc_put(struct axi_dma_desc *desc)
 {
 	struct axi_dma_chan *chan = desc->chan;
-	int count = atomic_read(&chan->descs_allocated);
+	int count = desc->nr_hw_descs;
 	struct axi_dma_hw_desc *hw_desc;
 	int descs_put;
 
@@ -1139,9 +1140,6 @@
 		/* Remove the completed descriptor from issued list before completing */
 		list_del(&vd->node);
 		vchan_cookie_complete(vd);
-
-		/* Submit queued descriptors after processing the completed ones */
-		axi_chan_start_first_queued(chan);
 	}
 
 out:
--- linux-qcom-6.8.0.orig/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
+++ linux-qcom-6.8.0/drivers/dma/dw-axi-dmac/dw-axi-dmac.h
@@ -104,6 +104,7 @@
 	u32				completed_blocks;
 	u32				length;
 	u32				period_len;
+	u32				nr_hw_descs;
 };
 
 struct axi_dma_chan_config {
--- linux-qcom-6.8.0.orig/drivers/dma/dw-edma/dw-hdma-v0-core.c
+++ linux-qcom-6.8.0/drivers/dma/dw-edma/dw-hdma-v0-core.c
@@ -17,8 +17,8 @@
 	DW_HDMA_V0_CB					= BIT(0),
 	DW_HDMA_V0_TCB					= BIT(1),
 	DW_HDMA_V0_LLP					= BIT(2),
-	DW_HDMA_V0_LIE					= BIT(3),
-	DW_HDMA_V0_RIE					= BIT(4),
+	DW_HDMA_V0_LWIE					= BIT(3),
+	DW_HDMA_V0_RWIE					= BIT(4),
 	DW_HDMA_V0_CCS					= BIT(8),
 	DW_HDMA_V0_LLE					= BIT(9),
 };
@@ -195,25 +195,14 @@
 static void dw_hdma_v0_core_write_chunk(struct dw_edma_chunk *chunk)
 {
 	struct dw_edma_burst *child;
-	struct dw_edma_chan *chan = chunk->chan;
 	u32 control = 0, i = 0;
-	int j;
 
 	if (chunk->cb)
 		control = DW_HDMA_V0_CB;
 
-	j = chunk->bursts_alloc;
-	list_for_each_entry(child, &chunk->burst->list, list) {
-		j--;
-		if (!j) {
-			control |= DW_HDMA_V0_LIE;
-			if (!(chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL))
-				control |= DW_HDMA_V0_RIE;
-		}
-
+	list_for_each_entry(child, &chunk->burst->list, list)
 		dw_hdma_v0_write_ll_data(chunk, i++, control, child->sz,
 					 child->sar, child->dar);
-	}
 
 	control = DW_HDMA_V0_LLP | DW_HDMA_V0_TCB;
 	if (!chunk->cb)
@@ -247,10 +236,11 @@
 	if (first) {
 		/* Enable engine */
 		SET_CH_32(dw, chan->dir, chan->id, ch_en, BIT(0));
-		/* Interrupt enable&unmask - done, abort */
-		tmp = GET_CH_32(dw, chan->dir, chan->id, int_setup) |
-		      HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK |
-		      HDMA_V0_LOCAL_STOP_INT_EN | HDMA_V0_LOCAL_ABORT_INT_EN;
+		/* Interrupt unmask - stop, abort */
+		tmp = GET_CH_32(dw, chan->dir, chan->id, int_setup);
+		tmp &= ~(HDMA_V0_STOP_INT_MASK | HDMA_V0_ABORT_INT_MASK);
+		/* Interrupt enable - stop, abort */
+		tmp |= HDMA_V0_LOCAL_STOP_INT_EN | HDMA_V0_LOCAL_ABORT_INT_EN;
 		if (!(dw->chip->flags & DW_EDMA_CHIP_LOCAL))
 			tmp |= HDMA_V0_REMOTE_STOP_INT_EN | HDMA_V0_REMOTE_ABORT_INT_EN;
 		SET_CH_32(dw, chan->dir, chan->id, int_setup, tmp);
--- linux-qcom-6.8.0.orig/drivers/dma/dw/acpi.c
+++ linux-qcom-6.8.0/drivers/dma/dw/acpi.c
@@ -8,13 +8,15 @@
 
 static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
 {
+	struct dw_dma *dw = to_dw_dma(chan->device);
+	struct dw_dma_chip_pdata *data = dev_get_drvdata(dw->dma.dev);
 	struct acpi_dma_spec *dma_spec = param;
 	struct dw_dma_slave slave = {
 		.dma_dev = dma_spec->dev,
 		.src_id = dma_spec->slave_id,
 		.dst_id = dma_spec->slave_id,
-		.m_master = 0,
-		.p_master = 1,
+		.m_master = data->m_master,
+		.p_master = data->p_master,
 	};
 
 	return dw_dma_filter(chan, &slave);
--- linux-qcom-6.8.0.orig/drivers/dma/dw/core.c
+++ linux-qcom-6.8.0/drivers/dma/dw/core.c
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/log2.h>
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -621,12 +622,10 @@
 	struct dw_desc		*prev;
 	struct dw_desc		*first;
 	u32			ctllo, ctlhi;
-	u8			m_master = dwc->dws.m_master;
-	u8			lms = DWC_LLP_LMS(m_master);
+	u8			lms = DWC_LLP_LMS(dwc->dws.m_master);
 	dma_addr_t		reg;
 	unsigned int		reg_width;
 	unsigned int		mem_width;
-	unsigned int		data_width = dw->pdata->data_width[m_master];
 	unsigned int		i;
 	struct scatterlist	*sg;
 	size_t			total_len = 0;
@@ -660,7 +659,7 @@
 			mem = sg_dma_address(sg);
 			len = sg_dma_len(sg);
 
-			mem_width = __ffs(data_width | mem | len);
+			mem_width = __ffs(sconfig->src_addr_width | mem | len);
 
 slave_sg_todev_fill_desc:
 			desc = dwc_desc_get(dwc);
@@ -720,7 +719,7 @@
 			lli_write(desc, sar, reg);
 			lli_write(desc, dar, mem);
 			lli_write(desc, ctlhi, ctlhi);
-			mem_width = __ffs(data_width | mem);
+			mem_width = __ffs(sconfig->dst_addr_width | mem);
 			lli_write(desc, ctllo, ctllo | DWC_CTLL_DST_WIDTH(mem_width));
 			desc->len = dlen;
 
@@ -780,17 +779,93 @@
 }
 EXPORT_SYMBOL_GPL(dw_dma_filter);
 
+static int dwc_verify_p_buswidth(struct dma_chan *chan)
+{
+	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+	struct dw_dma *dw = to_dw_dma(chan->device);
+	u32 reg_width, max_width;
+
+	if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
+		reg_width = dwc->dma_sconfig.dst_addr_width;
+	else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM)
+		reg_width = dwc->dma_sconfig.src_addr_width;
+	else /* DMA_MEM_TO_MEM */
+		return 0;
+
+	max_width = dw->pdata->data_width[dwc->dws.p_master];
+
+	/* Fall-back to 1-byte transfer width if undefined */
+	if (reg_width == DMA_SLAVE_BUSWIDTH_UNDEFINED)
+		reg_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+	else if (!is_power_of_2(reg_width) || reg_width > max_width)
+		return -EINVAL;
+	else /* bus width is valid */
+		return 0;
+
+	/* Update undefined addr width value */
+	if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
+		dwc->dma_sconfig.dst_addr_width = reg_width;
+	else /* DMA_DEV_TO_MEM */
+		dwc->dma_sconfig.src_addr_width = reg_width;
+
+	return 0;
+}
+
+static int dwc_verify_m_buswidth(struct dma_chan *chan)
+{
+	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+	struct dw_dma *dw = to_dw_dma(chan->device);
+	u32 reg_width, reg_burst, mem_width;
+
+	mem_width = dw->pdata->data_width[dwc->dws.m_master];
+
+	/*
+	 * It's possible to have a data portion locked in the DMA FIFO in case
+	 * of the channel suspension. Subsequent channel disabling will cause
+	 * that data silent loss. In order to prevent that maintain the src and
+	 * dst transfer widths coherency by means of the relation:
+	 * (CTLx.SRC_TR_WIDTH * CTLx.SRC_MSIZE >= CTLx.DST_TR_WIDTH)
+	 * Look for the details in the commit message that brings this change.
+	 *
+	 * Note the DMA configs utilized in the calculations below must have
+	 * been verified to have correct values by this method call.
+	 */
+	if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV) {
+		reg_width = dwc->dma_sconfig.dst_addr_width;
+		if (mem_width < reg_width)
+			return -EINVAL;
+
+		dwc->dma_sconfig.src_addr_width = mem_width;
+	} else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM) {
+		reg_width = dwc->dma_sconfig.src_addr_width;
+		reg_burst = rounddown_pow_of_two(dwc->dma_sconfig.src_maxburst);
+
+		dwc->dma_sconfig.dst_addr_width = min(mem_width, reg_width * reg_burst);
+	}
+
+	return 0;
+}
+
 static int dwc_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
 {
 	struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
 	struct dw_dma *dw = to_dw_dma(chan->device);
+	int ret;
 
 	memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig));
 
 	dwc->dma_sconfig.src_maxburst =
-		clamp(dwc->dma_sconfig.src_maxburst, 0U, dwc->max_burst);
+		clamp(dwc->dma_sconfig.src_maxburst, 1U, dwc->max_burst);
 	dwc->dma_sconfig.dst_maxburst =
-		clamp(dwc->dma_sconfig.dst_maxburst, 0U, dwc->max_burst);
+		clamp(dwc->dma_sconfig.dst_maxburst, 1U, dwc->max_burst);
+
+	ret = dwc_verify_p_buswidth(chan);
+	if (ret)
+		return ret;
+
+	ret = dwc_verify_m_buswidth(chan);
+	if (ret)
+		return ret;
 
 	dw->encode_maxburst(dwc, &dwc->dma_sconfig.src_maxburst);
 	dw->encode_maxburst(dwc, &dwc->dma_sconfig.dst_maxburst);
--- linux-qcom-6.8.0.orig/drivers/dma/dw/internal.h
+++ linux-qcom-6.8.0/drivers/dma/dw/internal.h
@@ -51,11 +51,15 @@
 	int (*probe)(struct dw_dma_chip *chip);
 	int (*remove)(struct dw_dma_chip *chip);
 	struct dw_dma_chip *chip;
+	u8 m_master;
+	u8 p_master;
 };
 
 static __maybe_unused const struct dw_dma_chip_pdata dw_dma_chip_pdata = {
 	.probe = dw_dma_probe,
 	.remove = dw_dma_remove,
+	.m_master = 0,
+	.p_master = 1,
 };
 
 static const struct dw_dma_platform_data idma32_pdata = {
@@ -72,6 +76,8 @@
 	.pdata = &idma32_pdata,
 	.probe = idma32_dma_probe,
 	.remove = idma32_dma_remove,
+	.m_master = 0,
+	.p_master = 0,
 };
 
 static const struct dw_dma_platform_data xbar_pdata = {
@@ -88,6 +94,8 @@
 	.pdata = &xbar_pdata,
 	.probe = idma32_dma_probe,
 	.remove = idma32_dma_remove,
+	.m_master = 0,
+	.p_master = 0,
 };
 
 #endif /* _DMA_DW_INTERNAL_H */
--- linux-qcom-6.8.0.orig/drivers/dma/dw/pci.c
+++ linux-qcom-6.8.0/drivers/dma/dw/pci.c
@@ -56,10 +56,10 @@
 	if (ret)
 		return ret;
 
-	dw_dma_acpi_controller_register(chip->dw);
-
 	pci_set_drvdata(pdev, data);
 
+	dw_dma_acpi_controller_register(chip->dw);
+
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/dma/fsl-edma-common.c
+++ linux-qcom-6.8.0/drivers/dma/fsl-edma-common.c
@@ -3,6 +3,7 @@
 // Copyright (c) 2013-2014 Freescale Semiconductor, Inc
 // Copyright (c) 2017 Sysam, Angelo Dureghello  <angelo@sysam.it>
 
+#include <linux/clk.h>
 #include <linux/dmapool.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -74,18 +75,10 @@
 
 	flags = fsl_edma_drvflags(fsl_chan);
 	val = edma_readl_chreg(fsl_chan, ch_sbr);
-	/* Remote/local swapped wrongly on iMX8 QM Audio edma */
-	if (flags & FSL_EDMA_DRV_QUIRK_SWAPPED) {
-		if (!fsl_chan->is_rxchan)
-			val |= EDMA_V3_CH_SBR_RD;
-		else
-			val |= EDMA_V3_CH_SBR_WR;
-	} else {
-		if (fsl_chan->is_rxchan)
-			val |= EDMA_V3_CH_SBR_RD;
-		else
-			val |= EDMA_V3_CH_SBR_WR;
-	}
+	if (fsl_chan->is_rxchan)
+		val |= EDMA_V3_CH_SBR_RD;
+	else
+		val |= EDMA_V3_CH_SBR_WR;
 
 	if (fsl_chan->is_remote)
 		val &= ~(EDMA_V3_CH_SBR_RD | EDMA_V3_CH_SBR_WR);
@@ -97,8 +90,8 @@
 		 * ch_mux: With the exception of 0, attempts to write a value
 		 * already in use will be forced to 0.
 		 */
-		if (!edma_readl_chreg(fsl_chan, ch_mux))
-			edma_writel_chreg(fsl_chan, fsl_chan->srcid, ch_mux);
+		if (!edma_readl(fsl_chan->edma, fsl_chan->mux_addr))
+			edma_writel(fsl_chan->edma, fsl_chan->srcid, fsl_chan->mux_addr);
 	}
 
 	val = edma_readl_chreg(fsl_chan, ch_csr);
@@ -134,7 +127,7 @@
 	flags = fsl_edma_drvflags(fsl_chan);
 
 	if (flags & FSL_EDMA_DRV_HAS_CHMUX)
-		edma_writel_chreg(fsl_chan, 0, ch_mux);
+		edma_writel(fsl_chan->edma, 0, fsl_chan->mux_addr);
 
 	val &= ~EDMA_V3_CH_CSR_ERQ;
 	edma_writel_chreg(fsl_chan, val, ch_csr);
@@ -754,6 +747,8 @@
 	fsl_desc->iscyclic = false;
 
 	fsl_chan->is_sw = true;
+	if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_MEM_REMOTE)
+		fsl_chan->is_remote = true;
 
 	/* To match with copy_align and max_seg_size so 1 tcd is enough */
 	fsl_edma_fill_tcd(fsl_chan, fsl_desc->tcd[0].vtcd, dma_src, dma_dst,
@@ -802,6 +797,9 @@
 {
 	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
 
+	if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_HAS_CHCLK)
+		clk_prepare_enable(fsl_chan->clk);
+
 	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
 				sizeof(struct fsl_edma_hw_tcd),
 				32, 0);
@@ -829,6 +827,9 @@
 	fsl_chan->tcd_pool = NULL;
 	fsl_chan->is_sw = false;
 	fsl_chan->srcid = 0;
+	fsl_chan->is_remote = false;
+	if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_HAS_CHCLK)
+		clk_disable_unprepare(fsl_chan->clk);
 }
 
 void fsl_edma_cleanup_vchan(struct dma_device *dmadev)
--- linux-qcom-6.8.0.orig/drivers/dma/fsl-edma-common.h
+++ linux-qcom-6.8.0/drivers/dma/fsl-edma-common.h
@@ -146,10 +146,12 @@
 	enum dma_data_direction		dma_dir;
 	char				chan_name[32];
 	struct fsl_edma_hw_tcd __iomem *tcd;
+	void __iomem			*mux_addr;
 	u32				real_count;
 	struct work_struct		issue_worker;
 	struct platform_device		*pdev;
 	struct device			*pd_dev;
+	struct device_link		*pd_dev_link;
 	u32				srcid;
 	struct clk			*clk;
 	int                             priority;
@@ -177,8 +179,7 @@
 #define FSL_EDMA_DRV_HAS_PD		BIT(5)
 #define FSL_EDMA_DRV_HAS_CHCLK		BIT(6)
 #define FSL_EDMA_DRV_HAS_CHMUX		BIT(7)
-/* imx8 QM audio edma remote local swapped */
-#define FSL_EDMA_DRV_QUIRK_SWAPPED	BIT(8)
+#define FSL_EDMA_DRV_MEM_REMOTE		BIT(8)
 /* control and status register is in tcd address space, edma3 reg layout */
 #define FSL_EDMA_DRV_SPLIT_REG		BIT(9)
 #define FSL_EDMA_DRV_BUS_8BYTE		BIT(10)
@@ -207,6 +208,8 @@
 	u32			chreg_off;
 	u32			chreg_space_sz;
 	u32			flags;
+	u32			mux_off;	/* channel mux register offset */
+	u32			mux_skip;	/* how much skip for each channel */
 	int			(*setup_irq)(struct platform_device *pdev,
 					     struct fsl_edma_engine *fsl_edma);
 };
--- linux-qcom-6.8.0.orig/drivers/dma/fsl-edma-main.c
+++ linux-qcom-6.8.0/drivers/dma/fsl-edma-main.c
@@ -336,16 +336,19 @@
 };
 
 static struct fsl_edma_drvdata imx8qm_data = {
-	.flags = FSL_EDMA_DRV_HAS_PD | FSL_EDMA_DRV_EDMA3,
+	.flags = FSL_EDMA_DRV_HAS_PD | FSL_EDMA_DRV_EDMA3 | FSL_EDMA_DRV_MEM_REMOTE,
 	.chreg_space_sz = 0x10000,
 	.chreg_off = 0x10000,
 	.setup_irq = fsl_edma3_irq_init,
 };
 
-static struct fsl_edma_drvdata imx8qm_audio_data = {
-	.flags = FSL_EDMA_DRV_QUIRK_SWAPPED | FSL_EDMA_DRV_HAS_PD | FSL_EDMA_DRV_EDMA3,
+static struct fsl_edma_drvdata imx8ulp_data = {
+	.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_CHCLK | FSL_EDMA_DRV_HAS_DMACLK |
+		 FSL_EDMA_DRV_EDMA3,
 	.chreg_space_sz = 0x10000,
 	.chreg_off = 0x10000,
+	.mux_off = 0x10000 + offsetof(struct fsl_edma3_ch_reg, ch_mux),
+	.mux_skip = 0x10000,
 	.setup_irq = fsl_edma3_irq_init,
 };
 
@@ -360,6 +363,8 @@
 	.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA4,
 	.chreg_space_sz = 0x8000,
 	.chreg_off = 0x10000,
+	.mux_off = 0x10000 + offsetof(struct fsl_edma3_ch_reg, ch_mux),
+	.mux_skip = 0x8000,
 	.setup_irq = fsl_edma3_irq_init,
 };
 
@@ -368,17 +373,40 @@
 	{ .compatible = "fsl,ls1028a-edma", .data = &ls1028a_data},
 	{ .compatible = "fsl,imx7ulp-edma", .data = &imx7ulp_data},
 	{ .compatible = "fsl,imx8qm-edma", .data = &imx8qm_data},
-	{ .compatible = "fsl,imx8qm-adma", .data = &imx8qm_audio_data},
+	{ .compatible = "fsl,imx8ulp-edma", .data = &imx8ulp_data},
 	{ .compatible = "fsl,imx93-edma3", .data = &imx93_data3},
 	{ .compatible = "fsl,imx93-edma4", .data = &imx93_data4},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);
 
+static void fsl_edma3_detach_pd(struct fsl_edma_engine *fsl_edma)
+{
+	struct fsl_edma_chan *fsl_chan;
+	int i;
+
+	for (i = 0; i < fsl_edma->n_chans; i++) {
+		if (fsl_edma->chan_masked & BIT(i))
+			continue;
+		fsl_chan = &fsl_edma->chans[i];
+		if (fsl_chan->pd_dev_link)
+			device_link_del(fsl_chan->pd_dev_link);
+		if (fsl_chan->pd_dev) {
+			dev_pm_domain_detach(fsl_chan->pd_dev, false);
+			pm_runtime_dont_use_autosuspend(fsl_chan->pd_dev);
+			pm_runtime_set_suspended(fsl_chan->pd_dev);
+		}
+	}
+}
+
+static void devm_fsl_edma3_detach_pd(void *data)
+{
+	fsl_edma3_detach_pd(data);
+}
+
 static int fsl_edma3_attach_pd(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma)
 {
 	struct fsl_edma_chan *fsl_chan;
-	struct device_link *link;
 	struct device *pd_chan;
 	struct device *dev;
 	int i;
@@ -394,15 +422,16 @@
 		pd_chan = dev_pm_domain_attach_by_id(dev, i);
 		if (IS_ERR_OR_NULL(pd_chan)) {
 			dev_err(dev, "Failed attach pd %d\n", i);
-			return -EINVAL;
+			goto detach;
 		}
 
-		link = device_link_add(dev, pd_chan, DL_FLAG_STATELESS |
+		fsl_chan->pd_dev_link = device_link_add(dev, pd_chan, DL_FLAG_STATELESS |
 					     DL_FLAG_PM_RUNTIME |
 					     DL_FLAG_RPM_ACTIVE);
-		if (!link) {
+		if (!fsl_chan->pd_dev_link) {
 			dev_err(dev, "Failed to add device_link to %d\n", i);
-			return -EINVAL;
+			dev_pm_domain_detach(pd_chan, false);
+			goto detach;
 		}
 
 		fsl_chan->pd_dev = pd_chan;
@@ -413,6 +442,10 @@
 	}
 
 	return 0;
+
+detach:
+	fsl_edma3_detach_pd(fsl_edma);
+	return -EINVAL;
 }
 
 static int fsl_edma_probe(struct platform_device *pdev)
@@ -421,6 +454,7 @@
 	struct fsl_edma_engine *fsl_edma;
 	const struct fsl_edma_drvdata *drvdata = NULL;
 	u32 chan_mask[2] = {0, 0};
+	char clk_name[36];
 	struct edma_regs *regs;
 	int chans;
 	int ret, i;
@@ -509,6 +543,9 @@
 		ret = fsl_edma3_attach_pd(pdev, fsl_edma);
 		if (ret)
 			return ret;
+		ret = devm_add_action_or_reset(&pdev->dev, devm_fsl_edma3_detach_pd, fsl_edma);
+		if (ret)
+			return ret;
 	}
 
 	INIT_LIST_HEAD(&fsl_edma->dma_dev.channels);
@@ -533,12 +570,23 @@
 				offsetof(struct fsl_edma3_ch_reg, tcd) : 0;
 		fsl_chan->tcd = fsl_edma->membase
 				+ i * drvdata->chreg_space_sz + drvdata->chreg_off + len;
+		fsl_chan->mux_addr = fsl_edma->membase + drvdata->mux_off + i * drvdata->mux_skip;
 
+		if (drvdata->flags & FSL_EDMA_DRV_HAS_CHCLK) {
+			snprintf(clk_name, sizeof(clk_name), "ch%02d", i);
+			fsl_chan->clk = devm_clk_get_enabled(&pdev->dev,
+							     (const char *)clk_name);
+
+			if (IS_ERR(fsl_chan->clk))
+				return PTR_ERR(fsl_chan->clk);
+		}
 		fsl_chan->pdev = pdev;
 		vchan_init(&fsl_chan->vchan, &fsl_edma->dma_dev);
 
 		edma_write_tcdreg(fsl_chan, 0, csr);
 		fsl_edma_chan_mux(fsl_chan, 0, false);
+		if (fsl_chan->edma->drvdata->flags & FSL_EDMA_DRV_HAS_CHCLK)
+			clk_disable_unprepare(fsl_chan->clk);
 	}
 
 	ret = fsl_edma->drvdata->setup_irq(pdev, fsl_edma);
--- linux-qcom-6.8.0.orig/drivers/dma/idma64.c
+++ linux-qcom-6.8.0/drivers/dma/idma64.c
@@ -171,6 +171,10 @@
 	u32 status_err;
 	unsigned short i;
 
+	/* Since IRQ may be shared, check if DMA controller is powered on */
+	if (status == GENMASK(31, 0))
+		return IRQ_NONE;
+
 	dev_vdbg(idma64->dma.dev, "%s: status=%#x\n", __func__, status);
 
 	/* Check if we have any interrupt from the DMA controller */
@@ -594,7 +598,9 @@
 
 	idma64->dma.dev = chip->sysdev;
 
-	dma_set_max_seg_size(idma64->dma.dev, IDMA64C_CTLH_BLOCK_TS_MASK);
+	ret = dma_set_max_seg_size(idma64->dma.dev, IDMA64C_CTLH_BLOCK_TS_MASK);
+	if (ret)
+		return ret;
 
 	ret = dma_async_device_register(&idma64->dma);
 	if (ret)
--- linux-qcom-6.8.0.orig/drivers/dma/idxd/cdev.c
+++ linux-qcom-6.8.0/drivers/dma/idxd/cdev.c
@@ -342,7 +342,7 @@
 	if (!evl)
 		return;
 
-	spin_lock(&evl->lock);
+	mutex_lock(&evl->lock);
 	status.bits = ioread64(idxd->reg_base + IDXD_EVLSTATUS_OFFSET);
 	t = status.tail;
 	h = status.head;
@@ -354,9 +354,8 @@
 			set_bit(h, evl->bmap);
 		h = (h + 1) % size;
 	}
-	spin_unlock(&evl->lock);
-
 	drain_workqueue(wq->wq);
+	mutex_unlock(&evl->lock);
 }
 
 static int idxd_cdev_release(struct inode *node, struct file *filep)
@@ -401,6 +400,18 @@
 	int rc;
 
 	dev_dbg(&pdev->dev, "%s called\n", __func__);
+
+	/*
+	 * Due to an erratum in some of the devices supported by the driver,
+	 * direct user submission to the device can be unsafe.
+	 * (See document INTEL-SA-01084)
+	 *
+	 * For the devices that exhibit this behavior, require that the user
+	 * has CAP_SYS_RAWIO capabilities.
+	 */
+	if (!idxd->user_submission_safe && !capable(CAP_SYS_RAWIO))
+		return -EPERM;
+
 	rc = check_vma(wq, vma, __func__);
 	if (rc < 0)
 		return rc;
@@ -415,6 +426,70 @@
 			vma->vm_page_prot);
 }
 
+static int idxd_submit_user_descriptor(struct idxd_user_context *ctx,
+				       struct dsa_hw_desc __user *udesc)
+{
+	struct idxd_wq *wq = ctx->wq;
+	struct idxd_dev *idxd_dev = &wq->idxd->idxd_dev;
+	const uint64_t comp_addr_align = is_dsa_dev(idxd_dev) ? 0x20 : 0x40;
+	void __iomem *portal = idxd_wq_portal_addr(wq);
+	struct dsa_hw_desc descriptor __aligned(64);
+	int rc;
+
+	rc = copy_from_user(&descriptor, udesc, sizeof(descriptor));
+	if (rc)
+		return -EFAULT;
+
+	/*
+	 * DSA devices are capable of indirect ("batch") command submission.
+	 * On devices where direct user submissions are not safe, we cannot
+	 * allow this since there is no good way for us to verify these
+	 * indirect commands.
+	 */
+	if (is_dsa_dev(idxd_dev) && descriptor.opcode == DSA_OPCODE_BATCH &&
+		!wq->idxd->user_submission_safe)
+		return -EINVAL;
+	/*
+	 * As per the programming specification, the completion address must be
+	 * aligned to 32 or 64 bytes. If this is violated the hardware
+	 * engine can get very confused (security issue).
+	 */
+	if (!IS_ALIGNED(descriptor.completion_addr, comp_addr_align))
+		return -EINVAL;
+
+	if (wq_dedicated(wq))
+		iosubmit_cmds512(portal, &descriptor, 1);
+	else {
+		descriptor.priv = 0;
+		descriptor.pasid = ctx->pasid;
+		rc = idxd_enqcmds(wq, portal, &descriptor);
+		if (rc < 0)
+			return rc;
+	}
+
+	return 0;
+}
+
+static ssize_t idxd_cdev_write(struct file *filp, const char __user *buf, size_t len,
+			       loff_t *unused)
+{
+	struct dsa_hw_desc __user *udesc = (struct dsa_hw_desc __user *)buf;
+	struct idxd_user_context *ctx = filp->private_data;
+	ssize_t written = 0;
+	int i;
+
+	for (i = 0; i < len/sizeof(struct dsa_hw_desc); i++) {
+		int rc = idxd_submit_user_descriptor(ctx, udesc + i);
+
+		if (rc)
+			return written ? written : rc;
+
+		written += sizeof(struct dsa_hw_desc);
+	}
+
+	return written;
+}
+
 static __poll_t idxd_cdev_poll(struct file *filp,
 			       struct poll_table_struct *wait)
 {
@@ -437,6 +512,7 @@
 	.open = idxd_cdev_open,
 	.release = idxd_cdev_release,
 	.mmap = idxd_cdev_mmap,
+	.write = idxd_cdev_write,
 	.poll = idxd_cdev_poll,
 };
 
@@ -501,7 +577,6 @@
 	struct idxd_cdev *idxd_cdev;
 
 	idxd_cdev = wq->idxd_cdev;
-	ida_destroy(&file_ida);
 	wq->idxd_cdev = NULL;
 	cdev_device_del(&idxd_cdev->cdev, cdev_dev(idxd_cdev));
 	put_device(cdev_dev(idxd_cdev));
--- linux-qcom-6.8.0.orig/drivers/dma/idxd/debugfs.c
+++ linux-qcom-6.8.0/drivers/dma/idxd/debugfs.c
@@ -66,7 +66,7 @@
 	if (!evl || !evl->log)
 		return 0;
 
-	spin_lock(&evl->lock);
+	mutex_lock(&evl->lock);
 
 	evl_status.bits = ioread64(idxd->reg_base + IDXD_EVLSTATUS_OFFSET);
 	t = evl_status.tail;
@@ -87,7 +87,7 @@
 		dump_event_entry(idxd, s, i, &count, processed);
 	}
 
-	spin_unlock(&evl->lock);
+	mutex_unlock(&evl->lock);
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/dma/idxd/device.c
+++ linux-qcom-6.8.0/drivers/dma/idxd/device.c
@@ -775,7 +775,7 @@
 		goto err_alloc;
 	}
 
-	spin_lock(&evl->lock);
+	mutex_lock(&evl->lock);
 	evl->log = addr;
 	evl->dma = dma_addr;
 	evl->log_size = size;
@@ -796,7 +796,7 @@
 	gencfg.evl_en = 1;
 	iowrite32(gencfg.bits, idxd->reg_base + IDXD_GENCFG_OFFSET);
 
-	spin_unlock(&evl->lock);
+	mutex_unlock(&evl->lock);
 	return 0;
 
 err_alloc:
@@ -819,7 +819,7 @@
 	if (!gencfg.evl_en)
 		return;
 
-	spin_lock(&evl->lock);
+	mutex_lock(&evl->lock);
 	gencfg.evl_en = 0;
 	iowrite32(gencfg.bits, idxd->reg_base + IDXD_GENCFG_OFFSET);
 
@@ -836,7 +836,7 @@
 	evl_dma = evl->dma;
 	evl->log = NULL;
 	evl->size = IDXD_EVL_SIZE_MIN;
-	spin_unlock(&evl->lock);
+	mutex_unlock(&evl->lock);
 
 	dma_free_coherent(dev, evl_log_size, evl_log, evl_dma);
 }
--- linux-qcom-6.8.0.orig/drivers/dma/idxd/idxd.h
+++ linux-qcom-6.8.0/drivers/dma/idxd/idxd.h
@@ -288,12 +288,13 @@
 	int evl_cr_off;
 	int cr_status_off;
 	int cr_result_off;
+	bool user_submission_safe;
 	load_device_defaults_fn_t load_device_defaults;
 };
 
 struct idxd_evl {
 	/* Lock to protect event log access. */
-	spinlock_t lock;
+	struct mutex lock;
 	void *log;
 	dma_addr_t dma;
 	/* Total size of event log = number of entries * entry size. */
@@ -374,6 +375,8 @@
 
 	struct dentry *dbgfs_dir;
 	struct dentry *dbgfs_evl_file;
+
+	bool user_submission_safe;
 };
 
 static inline unsigned int evl_ent_size(struct idxd_device *idxd)
--- linux-qcom-6.8.0.orig/drivers/dma/idxd/init.c
+++ linux-qcom-6.8.0/drivers/dma/idxd/init.c
@@ -47,6 +47,7 @@
 		.align = 32,
 		.dev_type = &dsa_device_type,
 		.evl_cr_off = offsetof(struct dsa_evl_entry, cr),
+		.user_submission_safe = false, /* See INTEL-SA-01084 erratum */
 		.cr_status_off = offsetof(struct dsa_completion_record, status),
 		.cr_result_off = offsetof(struct dsa_completion_record, result),
 	},
@@ -57,6 +58,7 @@
 		.align = 64,
 		.dev_type = &iax_device_type,
 		.evl_cr_off = offsetof(struct iax_evl_entry, cr),
+		.user_submission_safe = false, /* See INTEL-SA-01084 erratum */
 		.cr_status_off = offsetof(struct iax_completion_record, status),
 		.cr_result_off = offsetof(struct iax_completion_record, error_code),
 		.load_device_defaults = idxd_load_iaa_device_defaults,
@@ -354,7 +356,7 @@
 	if (!evl)
 		return -ENOMEM;
 
-	spin_lock_init(&evl->lock);
+	mutex_init(&evl->lock);
 	evl->size = IDXD_EVL_SIZE_MIN;
 
 	idxd_name = dev_name(idxd_confdev(idxd));
@@ -774,6 +776,8 @@
 	dev_info(&pdev->dev, "Intel(R) Accelerator Device (v%x)\n",
 		 idxd->hw.version);
 
+	idxd->user_submission_safe = data->user_submission_safe;
+
 	return 0;
 
  err_dev_register:
--- linux-qcom-6.8.0.orig/drivers/dma/idxd/irq.c
+++ linux-qcom-6.8.0/drivers/dma/idxd/irq.c
@@ -363,7 +363,7 @@
 	evl_status.bits = 0;
 	evl_status.int_pending = 1;
 
-	spin_lock(&evl->lock);
+	mutex_lock(&evl->lock);
 	/* Clear interrupt pending bit */
 	iowrite32(evl_status.bits_upper32,
 		  idxd->reg_base + IDXD_EVLSTATUS_OFFSET + sizeof(u32));
@@ -380,7 +380,7 @@
 
 	evl_status.head = h;
 	iowrite32(evl_status.bits_lower32, idxd->reg_base + IDXD_EVLSTATUS_OFFSET);
-	spin_unlock(&evl->lock);
+	mutex_unlock(&evl->lock);
 }
 
 irqreturn_t idxd_misc_thread(int vec, void *data)
@@ -611,11 +611,13 @@
 
 	spin_unlock(&irq_entry->list_lock);
 
-	list_for_each_entry(desc, &flist, list) {
+	list_for_each_entry_safe(desc, n, &flist, list) {
 		/*
 		 * Check against the original status as ABORT is software defined
 		 * and 0xff, which DSA_COMP_STATUS_MASK can mask out.
 		 */
+		list_del(&desc->list);
+
 		if (unlikely(desc->completion->status == IDXD_COMP_DESC_ABORT)) {
 			idxd_desc_complete(desc, IDXD_COMPLETE_ABORT, true);
 			continue;
--- linux-qcom-6.8.0.orig/drivers/dma/idxd/perfmon.c
+++ linux-qcom-6.8.0/drivers/dma/idxd/perfmon.c
@@ -528,14 +528,11 @@
 		return 0;
 
 	target = cpumask_any_but(cpu_online_mask, cpu);
-
 	/* migrate events if there is a valid target */
-	if (target < nr_cpu_ids)
+	if (target < nr_cpu_ids) {
 		cpumask_set_cpu(target, &perfmon_dsa_cpu_mask);
-	else
-		target = -1;
-
-	perf_pmu_migrate_context(&idxd_pmu->pmu, cpu, target);
+		perf_pmu_migrate_context(&idxd_pmu->pmu, cpu, target);
+	}
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/dma/idxd/registers.h
+++ linux-qcom-6.8.0/drivers/dma/idxd/registers.h
@@ -6,9 +6,6 @@
 #include <uapi/linux/idxd.h>
 
 /* PCI Config */
-#define PCI_DEVICE_ID_INTEL_DSA_SPR0	0x0b25
-#define PCI_DEVICE_ID_INTEL_IAX_SPR0	0x0cfe
-
 #define DEVICE_VERSION_1		0x100
 #define DEVICE_VERSION_2		0x200
 
--- linux-qcom-6.8.0.orig/drivers/dma/idxd/sysfs.c
+++ linux-qcom-6.8.0/drivers/dma/idxd/sysfs.c
@@ -1197,12 +1197,35 @@
 static struct device_attribute dev_attr_wq_enqcmds_retries =
 		__ATTR(enqcmds_retries, 0644, wq_enqcmds_retries_show, wq_enqcmds_retries_store);
 
+static ssize_t op_cap_show_common(struct device *dev, char *buf, unsigned long *opcap_bmap)
+{
+	ssize_t pos;
+	int i;
+
+	pos = 0;
+	for (i = IDXD_MAX_OPCAP_BITS/64 - 1; i >= 0; i--) {
+		unsigned long val = opcap_bmap[i];
+
+		/* On systems where direct user submissions are not safe, we need to clear out
+		 * the BATCH capability from the capability mask in sysfs since we cannot support
+		 * that command on such systems.
+		 */
+		if (i == DSA_OPCODE_BATCH/64 && !confdev_to_idxd(dev)->user_submission_safe)
+			clear_bit(DSA_OPCODE_BATCH % 64, &val);
+
+		pos += sysfs_emit_at(buf, pos, "%*pb", 64, &val);
+		pos += sysfs_emit_at(buf, pos, "%c", i == 0 ? '\n' : ',');
+	}
+
+	return pos;
+}
+
 static ssize_t wq_op_config_show(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
 	struct idxd_wq *wq = confdev_to_wq(dev);
 
-	return sysfs_emit(buf, "%*pb\n", IDXD_MAX_OPCAP_BITS, wq->opcap_bmap);
+	return op_cap_show_common(dev, buf, wq->opcap_bmap);
 }
 
 static int idxd_verify_supported_opcap(struct idxd_device *idxd, unsigned long *opmask)
@@ -1455,7 +1478,7 @@
 {
 	struct idxd_device *idxd = confdev_to_idxd(dev);
 
-	return sysfs_emit(buf, "%*pb\n", IDXD_MAX_OPCAP_BITS, idxd->opcap_bmap);
+	return op_cap_show_common(dev, buf, idxd->opcap_bmap);
 }
 static DEVICE_ATTR_RO(op_cap);
 
--- linux-qcom-6.8.0.orig/drivers/dma/ioat/init.c
+++ linux-qcom-6.8.0/drivers/dma/ioat/init.c
@@ -534,18 +534,6 @@
 	return err;
 }
 
-static int ioat_register(struct ioatdma_device *ioat_dma)
-{
-	int err = dma_async_device_register(&ioat_dma->dma_dev);
-
-	if (err) {
-		ioat_disable_interrupts(ioat_dma);
-		dma_pool_destroy(ioat_dma->completion_pool);
-	}
-
-	return err;
-}
-
 static void ioat_dma_remove(struct ioatdma_device *ioat_dma)
 {
 	struct dma_device *dma = &ioat_dma->dma_dev;
@@ -1181,9 +1169,9 @@
 		       ioat_chan->reg_base + IOAT_DCACTRL_OFFSET);
 	}
 
-	err = ioat_register(ioat_dma);
+	err = dma_async_device_register(&ioat_dma->dma_dev);
 	if (err)
-		return err;
+		goto err_disable_interrupts;
 
 	ioat_kobject_add(ioat_dma, &ioat_ktype);
 
@@ -1192,20 +1180,29 @@
 
 	/* disable relaxed ordering */
 	err = pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &val16);
-	if (err)
-		return pcibios_err_to_errno(err);
+	if (err) {
+		err = pcibios_err_to_errno(err);
+		goto err_disable_interrupts;
+	}
 
 	/* clear relaxed ordering enable */
 	val16 &= ~PCI_EXP_DEVCTL_RELAX_EN;
 	err = pcie_capability_write_word(pdev, PCI_EXP_DEVCTL, val16);
-	if (err)
-		return pcibios_err_to_errno(err);
+	if (err) {
+		err = pcibios_err_to_errno(err);
+		goto err_disable_interrupts;
+	}
 
 	if (ioat_dma->cap & IOAT_CAP_DPS)
 		writeb(ioat_pending_level + 1,
 		       ioat_dma->reg_base + IOAT_PREFETCH_LIMIT_OFFSET);
 
 	return 0;
+
+err_disable_interrupts:
+	ioat_disable_interrupts(ioat_dma);
+	dma_pool_destroy(ioat_dma->completion_pool);
+	return err;
 }
 
 static void ioat_shutdown(struct pci_dev *pdev)
@@ -1350,6 +1347,8 @@
 	void __iomem * const *iomap;
 	struct device *dev = &pdev->dev;
 	struct ioatdma_device *device;
+	unsigned int i;
+	u8 version;
 	int err;
 
 	err = pcim_enable_device(pdev);
@@ -1363,6 +1362,10 @@
 	if (!iomap)
 		return -ENOMEM;
 
+	version = readb(iomap[IOAT_MMIO_BAR] + IOAT_VER_OFFSET);
+	if (version < IOAT_VER_3_0)
+		return -ENODEV;
+
 	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
 	if (err)
 		return err;
@@ -1373,17 +1376,18 @@
 	pci_set_master(pdev);
 	pci_set_drvdata(pdev, device);
 
-	device->version = readb(device->reg_base + IOAT_VER_OFFSET);
+	device->version = version;
 	if (device->version >= IOAT_VER_3_4)
 		ioat_dca_enabled = 0;
-	if (device->version >= IOAT_VER_3_0) {
-		if (is_skx_ioat(pdev))
-			device->version = IOAT_VER_3_2;
-		err = ioat3_dma_probe(device, ioat_dca_enabled);
-	} else
-		return -ENODEV;
 
+	if (is_skx_ioat(pdev))
+		device->version = IOAT_VER_3_2;
+
+	err = ioat3_dma_probe(device, ioat_dca_enabled);
 	if (err) {
+		for (i = 0; i < IOAT_MAX_CHANS; i++)
+			kfree(device->idx[i]);
+		kfree(device);
 		dev_err(dev, "Intel(R) I/OAT DMA Engine init failed\n");
 		return -ENODEV;
 	}
@@ -1445,6 +1449,7 @@
 static void __exit ioat_exit_module(void)
 {
 	pci_unregister_driver(&ioat_pci_driver);
+	kmem_cache_destroy(ioat_sed_cache);
 	kmem_cache_destroy(ioat_cache);
 }
 module_exit(ioat_exit_module);
--- linux-qcom-6.8.0.orig/drivers/dma/ls2x-apb-dma.c
+++ linux-qcom-6.8.0/drivers/dma/ls2x-apb-dma.c
@@ -31,7 +31,7 @@
 #define LDMA_ASK_VALID		BIT(2)
 #define LDMA_START		BIT(3) /* DMA start operation */
 #define LDMA_STOP		BIT(4) /* DMA stop operation */
-#define LDMA_CONFIG_MASK	GENMASK(4, 0) /* DMA controller config bits mask */
+#define LDMA_CONFIG_MASK	GENMASK_ULL(4, 0) /* DMA controller config bits mask */
 
 /* Bitfields in ndesc_addr field of HW decriptor */
 #define LDMA_DESC_EN		BIT(0) /*1: The next descriptor is valid */
--- linux-qcom-6.8.0.orig/drivers/dma/mv_xor.c
+++ linux-qcom-6.8.0/drivers/dma/mv_xor.c
@@ -1388,6 +1388,7 @@
 			irq = irq_of_parse_and_map(np, 0);
 			if (!irq) {
 				ret = -ENODEV;
+				of_node_put(np);
 				goto err_channel_add;
 			}
 
@@ -1396,6 +1397,7 @@
 			if (IS_ERR(chan)) {
 				ret = PTR_ERR(chan);
 				irq_dispose_mapping(irq);
+				of_node_put(np);
 				goto err_channel_add;
 			}
 
--- linux-qcom-6.8.0.orig/drivers/dma/owl-dma.c
+++ linux-qcom-6.8.0/drivers/dma/owl-dma.c
@@ -250,7 +250,7 @@
 	else
 		regval &= ~val;
 
-	writel(val, pchan->base + reg);
+	writel(regval, pchan->base + reg);
 }
 
 static void pchan_writel(struct owl_dma_pchan *pchan, u32 reg, u32 data)
@@ -274,7 +274,7 @@
 	else
 		regval &= ~val;
 
-	writel(val, od->base + reg);
+	writel(regval, od->base + reg);
 }
 
 static void dma_writel(struct owl_dma *od, u32 reg, u32 data)
--- linux-qcom-6.8.0.orig/drivers/dma/pl330.c
+++ linux-qcom-6.8.0/drivers/dma/pl330.c
@@ -1053,9 +1053,6 @@
 
 	thrd->req_running = idx;
 
-	if (desc->rqtype == DMA_MEM_TO_DEV || desc->rqtype == DMA_DEV_TO_MEM)
-		UNTIL(thrd, PL330_STATE_WFP);
-
 	return true;
 }
 
--- linux-qcom-6.8.0.orig/drivers/dma/qcom/bam_dma.c
+++ linux-qcom-6.8.0/drivers/dma/qcom/bam_dma.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 2021 The Linux Foundation. All rights reserved.
  */
 /*
  * QCOM BAM DMA engine driver
@@ -39,6 +39,7 @@
 #include <linux/of_dma.h>
 #include <linux/circ_buf.h>
 #include <linux/clk.h>
+#include <linux/dma/qcom_bam_dma.h>
 #include <linux/dmaengine.h>
 #include <linux/pm_runtime.h>
 
@@ -58,6 +59,8 @@
 #define DESC_FLAG_EOB BIT(13)
 #define DESC_FLAG_NWD BIT(12)
 #define DESC_FLAG_CMD BIT(11)
+#define DESC_FLAG_LOCK BIT(10)
+#define DESC_FLAG_UNLOCK BIT(9)
 
 struct bam_async_desc {
 	struct virt_dma_desc vd;
@@ -338,7 +341,10 @@
 /* BAM_P_SW_OFSTS */
 #define P_SW_OFSTS_MASK		0xffff
 
-#define BAM_DESC_FIFO_SIZE	SZ_32K
+#define MSM_SLIM_DESC_NUM	32
+#define MSM_SLIM_DESC_FIFO_SIZE	(MSM_SLIM_DESC_NUM * 8)
+#define BAM_DESC_FIFO_SIZE	(bdev->r_mem.is_r_mem ? (MSM_SLIM_DESC_FIFO_SIZE) : SZ_32K)
+
 #define MAX_DESCRIPTORS (BAM_DESC_FIFO_SIZE / sizeof(struct bam_desc_hw) - 1)
 #define BAM_FIFO_SIZE	(SZ_32K - 8)
 #define IS_BUSY(chan)	(CIRC_SPACE(bchan->tail, bchan->head,\
@@ -377,6 +383,26 @@
 	return container_of(common, struct bam_chan, vc.chan);
 }
 
+/**
+ * struct remote_mem - Stores remote memory information
+ * @r_res:	Memory resource structure parsed from devicetree
+ * @r_vbase:	Virtual base address of remote memory region
+ * @r_vsbase:	Saved virtual base address of remote memory region
+ * @r_pbase:	Physical base address of remote memory region
+ * @is_r_mem:	Indicates if remote memory is used or not
+ *
+ * Some BAM clients require the use of a specific memory region for the
+ * pipe descriptor fifo. This structure is used to hold the remote
+ * memory region information.
+ */
+struct remote_mem {
+	struct resource *r_res;
+	void __iomem *r_vbase;
+	void __iomem *r_vsbase;
+	u32 r_pbase;
+	bool is_r_mem;
+};
+
 struct bam_device {
 	void __iomem *regs;
 	struct device *dev;
@@ -398,6 +424,7 @@
 
 	/* dma start transaction tasklet */
 	struct tasklet_struct task;
+	struct remote_mem r_mem;
 };
 
 /**
@@ -501,7 +528,7 @@
 	writel_relaxed(ALIGN(bchan->fifo_phys, sizeof(struct bam_desc_hw)),
 			bam_addr(bdev, bchan->id, BAM_P_DESC_FIFO_ADDR));
 	writel_relaxed(BAM_FIFO_SIZE,
-			bam_addr(bdev, bchan->id, BAM_P_FIFO_SIZES));
+		       bam_addr(bdev, bchan->id, BAM_P_FIFO_SIZES));
 
 	/* enable the per pipe interrupts, enable EOT, ERR, and INT irqs */
 	writel_relaxed(P_DEFAULT_IRQS_EN,
@@ -543,9 +570,20 @@
 	if (bchan->fifo_virt)
 		return 0;
 
-	/* allocate FIFO descriptor space, but only if necessary */
-	bchan->fifo_virt = dma_alloc_wc(bdev->dev, BAM_DESC_FIFO_SIZE,
-					&bchan->fifo_phys, GFP_KERNEL);
+	if (bdev->r_mem.is_r_mem) {
+		bchan->fifo_virt = bdev->r_mem.r_vbase;
+		bchan->fifo_phys = bdev->r_mem.r_res->start;
+	} else {
+		/* allocate FIFO descriptor space, but only if necessary */
+		bchan->fifo_virt = dma_alloc_wc(bdev->dev, BAM_DESC_FIFO_SIZE,
+						&bchan->fifo_phys, GFP_KERNEL);
+	}
+
+	if (bdev->r_mem.is_r_mem) {
+		memset_io(bchan->fifo_virt, 0x0, MSM_SLIM_DESC_NUM * 8);
+		bdev->r_mem.r_vbase = bdev->r_mem.r_vbase + (MSM_SLIM_DESC_NUM * 8);
+		bdev->r_mem.r_res->start = bdev->r_mem.r_res->start + (MSM_SLIM_DESC_NUM * 8);
+	}
 
 	if (!bchan->fifo_virt) {
 		dev_err(bdev->dev, "Failed to allocate desc fifo\n");
@@ -588,9 +626,16 @@
 	bam_reset_channel(bchan);
 	spin_unlock_irqrestore(&bchan->vc.lock, flags);
 
-	dma_free_wc(bdev->dev, BAM_DESC_FIFO_SIZE, bchan->fifo_virt,
-		    bchan->fifo_phys);
+	if (!bdev->r_mem.is_r_mem) {
+		dma_free_wc(bdev->dev, BAM_DESC_FIFO_SIZE, bchan->fifo_virt,
+			    bchan->fifo_phys);
+	} else {
+		bdev->r_mem.r_vbase = bdev->r_mem.r_vsbase;
+		bdev->r_mem.r_res->start = bdev->r_mem.r_pbase;
+	}
+
 	bchan->fifo_virt = NULL;
+	bchan->fifo_phys = 0;
 
 	/* mask irq for pipe/channel */
 	val = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE));
@@ -657,7 +702,6 @@
 	struct bam_desc_hw *desc;
 	unsigned int num_alloc = 0;
 
-
 	if (!is_slave_direction(direction)) {
 		dev_err(bdev->dev, "invalid dma direction\n");
 		return NULL;
@@ -686,6 +730,13 @@
 
 	/* fill in temporary descriptors */
 	desc = async_desc->desc;
+	if (flags & DMA_PREP_CMD) {
+		if (flags & DMA_PREP_LOCK)
+			desc->flags |= cpu_to_le16(DESC_FLAG_LOCK);
+		if (flags & DMA_PREP_UNLOCK)
+			desc->flags |= cpu_to_le16(DESC_FLAG_UNLOCK);
+	}
+
 	for_each_sg(sgl, sg, sg_len, i) {
 		unsigned int remainder = sg_dma_len(sg);
 		unsigned int curr_offset = 0;
@@ -1140,6 +1191,7 @@
 static void bam_issue_pending(struct dma_chan *chan)
 {
 	struct bam_chan *bchan = to_bam_chan(chan);
+	struct bam_device *bdev = bchan->bdev;
 	unsigned long flags;
 
 	spin_lock_irqsave(&bchan->vc.lock, flags);
@@ -1237,6 +1289,7 @@
 {
 	struct bam_device *bdev;
 	const struct of_device_id *match;
+	struct resource *remote_res;
 	int ret, i;
 
 	bdev = devm_kzalloc(&pdev->dev, sizeof(*bdev), GFP_KERNEL);
@@ -1257,6 +1310,31 @@
 	if (IS_ERR(bdev->regs))
 		return PTR_ERR(bdev->regs);
 
+	bdev->r_mem.is_r_mem = false;
+	remote_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+						  "bam_remote_mem");
+	if (remote_res) {
+		bdev->r_mem.is_r_mem = true;
+		bdev->r_mem.r_pbase = (unsigned long long)remote_res->start;
+		bdev->r_mem.r_vbase = devm_ioremap(&pdev->dev,
+						   remote_res->start,
+						   resource_size(remote_res));
+
+		if (!bdev->r_mem.r_vbase) {
+			dev_err(&pdev->dev, "Remote mem ioremap failed\n");
+			return -ENOMEM;
+		}
+
+		bdev->r_mem.r_vsbase = bdev->r_mem.r_vbase;
+		bdev->r_mem.r_res = remote_res;
+	}
+
+	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
+	if (ret) {
+		dev_err(&pdev->dev, "Could not set 32 bit mask\n");
+		return -ENODEV;
+	}
+
 	bdev->irq = platform_get_irq(pdev, 0);
 	if (bdev->irq < 0)
 		return bdev->irq;
@@ -1336,6 +1414,7 @@
 	/* set capabilities */
 	dma_cap_zero(bdev->common.cap_mask);
 	dma_cap_set(DMA_SLAVE, bdev->common.cap_mask);
+	dma_cap_set(DMA_PRIVATE, bdev->common.cap_mask);
 
 	/* initialize dmaengine apis */
 	bdev->common.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
--- linux-qcom-6.8.0.orig/drivers/dma/qcom/gpi.c
+++ linux-qcom-6.8.0/drivers/dma/qcom/gpi.c
@@ -2,6 +2,7 @@
 /*
  * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  * Copyright (c) 2020, Linaro Limited
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <dt-bindings/dma/qcom-gpi.h>
@@ -27,6 +28,7 @@
 #define TRE_FLAGS_IEOT		BIT(9)
 #define TRE_FLAGS_BEI		BIT(10)
 #define TRE_FLAGS_LINK		BIT(11)
+#define TRE_FLAGS_IMMEDIATE_DMA	BIT(16)
 #define TRE_FLAGS_TYPE		GENMASK(23, 16)
 
 /* SPI CONFIG0 WD0 */
@@ -64,6 +66,15 @@
 
 /* DMA TRE */
 #define TRE_DMA_LEN		GENMASK(23, 0)
+#define TRE_DMA_IMMEDIATE_LEN	GENMASK(3, 0)
+
+/* Lock TRE */
+#define TRE_I2C_LOCK		BIT(0)
+#define TRE_MINOR_TYPE		GENMASK(19, 16)
+#define TRE_MAJOR_TYPE		GENMASK(23, 20)
+
+/* Lock Unlock TRE */
+#define TRE_I2C_UNLOCK		BIT(8)
 
 /* Register offsets from gpi-top */
 #define GPII_n_CH_k_CNTXT_0_OFFS(n, k)	(0x20000 + (0x4000 * (n)) + (0x80 * (k)))
@@ -522,7 +533,7 @@
 	bool ieob_set;
 };
 
-#define MAX_TRE 3
+#define MAX_TRE 5
 
 struct gpi_desc {
 	struct virt_dma_desc vd;
@@ -1076,8 +1087,17 @@
 	dev_dbg(gpii->gpi_dev->dev, "Residue %d\n", result.residue);
 
 	dma_cookie_complete(&vd->tx);
-	dmaengine_desc_get_callback_invoke(&vd->tx, &result);
-
+	if (gchan->protocol == QCOM_GPI_I2C) {
+		struct dmaengine_desc_callback cb;
+		struct gpi_i2c_config *i2c;
+
+		dmaengine_desc_get_callback(&vd->tx, &cb);
+		i2c = cb.callback_param;
+		i2c->status = compl_event->status;
+		dmaengine_desc_callback_invoke(&cb, &result);
+	} else {
+		dmaengine_desc_get_callback_invoke(&vd->tx, &result);
+	}
 gpi_free_desc:
 	spin_lock_irqsave(&gchan->vc.lock, flags);
 	list_del(&vd->node);
@@ -1644,6 +1664,20 @@
 	struct gpi_tre *tre;
 	unsigned int i;
 
+	/* create lock tre for first tranfser */
+	if (i2c->shared_se && i2c->first_msg) {
+		tre = &desc->tre[tre_idx];
+		tre_idx++;
+
+		/* lock: chain bit set */
+		tre->dword[0] = 0;
+		tre->dword[1] = 0;
+		tre->dword[2] = 0;
+		tre->dword[3] = u32_encode_bits(1, TRE_I2C_LOCK);
+		tre->dword[3] |= u32_encode_bits(0, TRE_MINOR_TYPE);
+		tre->dword[3] |= u32_encode_bits(3, TRE_MAJOR_TYPE);
+	}
+
 	/* first create config tre if applicable */
 	if (i2c->set_config) {
 		tre = &desc->tre[tre_idx];
@@ -1702,6 +1736,20 @@
 		tre->dword[3] |= u32_encode_bits(1, TRE_FLAGS_IEOT);
 	}
 
+	/* Unlock tre for last transfer */
+	if (i2c->shared_se && i2c->last_msg && i2c->op != I2C_READ) {
+		tre = &desc->tre[tre_idx];
+		tre_idx++;
+
+		/* unlock tre: ieob set */
+		tre->dword[0] = 0;
+		tre->dword[1] = 0;
+		tre->dword[2] = 0;
+		tre->dword[3] = u32_encode_bits(1, TRE_I2C_UNLOCK);
+		tre->dword[3] |= u32_encode_bits(1, TRE_MINOR_TYPE);
+		tre->dword[3] |= u32_encode_bits(3, TRE_MAJOR_TYPE);
+	}
+
 	for (i = 0; i < tre_idx; i++)
 		dev_dbg(dev, "TRE:%d %x:%x:%x:%x\n", i, desc->tre[i].dword[0],
 			desc->tre[i].dword[1], desc->tre[i].dword[2], desc->tre[i].dword[3]);
@@ -1718,6 +1766,8 @@
 	dma_addr_t address;
 	struct gpi_tre *tre;
 	unsigned int i;
+	u8 *buf;
+	int len = 0;
 
 	/* first create config tre if applicable */
 	if (direction == DMA_MEM_TO_DEV && spi->set_config) {
@@ -1770,14 +1820,32 @@
 	tre_idx++;
 
 	address = sg_dma_address(sgl);
-	tre->dword[0] = lower_32_bits(address);
-	tre->dword[1] = upper_32_bits(address);
+	len = sg_dma_len(sgl);
 
-	tre->dword[2] = u32_encode_bits(sg_dma_len(sgl), TRE_DMA_LEN);
+	/* Support Immediate dma for write transfers for data length up to 8 bytes */
+	if ((spi->flags & QCOM_GPI_IMMEDIATE_DMA) && direction == DMA_MEM_TO_DEV) {
+		buf = (u8 *)sg_virt(sgl);
 
-	tre->dword[3] = u32_encode_bits(TRE_TYPE_DMA, TRE_FLAGS_TYPE);
-	if (direction == DMA_MEM_TO_DEV)
+		/* memcpy may not always be length of 8, hence pre-fill both dword's with 0 */
+		tre->dword[0] = 0;
+		tre->dword[1] = 0;
+		memcpy((u8 *)&tre->dword[0], buf, len);
+
+		tre->dword[2] = u32_encode_bits(len, TRE_DMA_IMMEDIATE_LEN);
+
+		tre->dword[3] = u32_encode_bits(TRE_TYPE_DMA, TRE_FLAGS_TYPE);
 		tre->dword[3] |= u32_encode_bits(1, TRE_FLAGS_IEOT);
+		tre->dword[3] |= u32_encode_bits(1, TRE_FLAGS_IMMEDIATE_DMA);
+	} else {
+		tre->dword[0] = lower_32_bits(address);
+		tre->dword[1] = upper_32_bits(address);
+
+		tre->dword[2] = u32_encode_bits(len, TRE_DMA_LEN);
+
+		tre->dword[3] = u32_encode_bits(TRE_TYPE_DMA, TRE_FLAGS_TYPE);
+		if (direction == DMA_MEM_TO_DEV)
+			tre->dword[3] |= u32_encode_bits(1, TRE_FLAGS_IEOT);
+	}
 
 	for (i = 0; i < tre_idx; i++)
 		dev_dbg(dev, "TRE:%d %x:%x:%x:%x\n", i, desc->tre[i].dword[0],
@@ -2254,6 +2322,7 @@
 	/* configure dmaengine apis */
 	gpi_dev->dma_device.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
 	gpi_dev->dma_device.residue_granularity = DMA_RESIDUE_GRANULARITY_DESCRIPTOR;
+	dma_cap_set(DMA_PRIVATE, gpi_dev->dma_device.cap_mask);
 	gpi_dev->dma_device.src_addr_widths = DMA_SLAVE_BUSWIDTH_8_BYTES;
 	gpi_dev->dma_device.dst_addr_widths = DMA_SLAVE_BUSWIDTH_8_BYTES;
 	gpi_dev->dma_device.device_alloc_chan_resources = gpi_alloc_chan_resources;
--- linux-qcom-6.8.0.orig/drivers/dma/tegra186-gpc-dma.c
+++ linux-qcom-6.8.0/drivers/dma/tegra186-gpc-dma.c
@@ -231,6 +231,7 @@
 	bool config_init;
 	char name[30];
 	enum dma_transfer_direction sid_dir;
+	enum dma_status status;
 	int id;
 	int irq;
 	int slave_id;
@@ -393,6 +394,8 @@
 		tegra_dma_dump_chan_regs(tdc);
 	}
 
+	tdc->status = DMA_PAUSED;
+
 	return ret;
 }
 
@@ -419,6 +422,8 @@
 	val = tdc_read(tdc, TEGRA_GPCDMA_CHAN_CSRE);
 	val &= ~TEGRA_GPCDMA_CHAN_CSRE_PAUSE;
 	tdc_write(tdc, TEGRA_GPCDMA_CHAN_CSRE, val);
+
+	tdc->status = DMA_IN_PROGRESS;
 }
 
 static int tegra_dma_device_resume(struct dma_chan *dc)
@@ -544,6 +549,7 @@
 
 	tegra_dma_sid_free(tdc);
 	tdc->dma_desc = NULL;
+	tdc->status = DMA_COMPLETE;
 }
 
 static void tegra_dma_chan_decode_error(struct tegra_dma_channel *tdc,
@@ -716,6 +722,7 @@
 		tdc->dma_desc = NULL;
 	}
 
+	tdc->status = DMA_COMPLETE;
 	tegra_dma_sid_free(tdc);
 	vchan_get_all_descriptors(&tdc->vc, &head);
 	spin_unlock_irqrestore(&tdc->vc.lock, flags);
@@ -746,6 +753,9 @@
 	bytes_xfer = dma_desc->bytes_xfer +
 		     sg_req[dma_desc->sg_idx].len - (wcount * 4);
 
+	if (dma_desc->bytes_req == bytes_xfer)
+		return 0;
+
 	residual = dma_desc->bytes_req - (bytes_xfer % dma_desc->bytes_req);
 
 	return residual;
@@ -766,6 +776,9 @@
 	if (ret == DMA_COMPLETE)
 		return ret;
 
+	if (tdc->status == DMA_PAUSED)
+		ret = DMA_PAUSED;
+
 	spin_lock_irqsave(&tdc->vc.lock, flags);
 	vd = vchan_find_desc(&tdc->vc, cookie);
 	if (vd) {
--- linux-qcom-6.8.0.orig/drivers/dma/ti/edma.c
+++ linux-qcom-6.8.0/drivers/dma/ti/edma.c
@@ -208,7 +208,6 @@
 struct edma_cc;
 
 struct edma_tc {
-	struct device_node		*node;
 	u16				id;
 };
 
@@ -2466,13 +2465,13 @@
 			if (ret || i == ecc->num_tc)
 				break;
 
-			ecc->tc_list[i].node = tc_args.np;
 			ecc->tc_list[i].id = i;
 			queue_priority_mapping[i][1] = tc_args.args[0];
 			if (queue_priority_mapping[i][1] > lowest_priority) {
 				lowest_priority = queue_priority_mapping[i][1];
 				info->default_queue = i;
 			}
+			of_node_put(tc_args.np);
 		}
 
 		/* See if we have optional dma-channel-mask array */
--- linux-qcom-6.8.0.orig/drivers/dma/ti/k3-udma.c
+++ linux-qcom-6.8.0/drivers/dma/ti/k3-udma.c
@@ -4472,7 +4472,9 @@
 		ud->rchan_cnt = UDMA_CAP2_RCHAN_CNT(cap2);
 		break;
 	case DMA_TYPE_BCDMA:
-		ud->bchan_cnt = BCDMA_CAP2_BCHAN_CNT(cap2);
+		ud->bchan_cnt = BCDMA_CAP2_BCHAN_CNT(cap2) +
+				BCDMA_CAP3_HBCHAN_CNT(cap3) +
+				BCDMA_CAP3_UBCHAN_CNT(cap3);
 		ud->tchan_cnt = BCDMA_CAP2_TCHAN_CNT(cap2);
 		ud->rchan_cnt = BCDMA_CAP2_RCHAN_CNT(cap2);
 		ud->rflow_cnt = ud->rchan_cnt;
--- linux-qcom-6.8.0.orig/drivers/dma/ti/omap-dma.c
+++ linux-qcom-6.8.0/drivers/dma/ti/omap-dma.c
@@ -1186,10 +1186,10 @@
 	d->dev_addr = dev_addr;
 	d->fi = burst;
 	d->es = es;
+	d->sglen = 1;
 	d->sg[0].addr = buf_addr;
 	d->sg[0].en = period_len / es_bytes[es];
 	d->sg[0].fn = buf_len / period_len;
-	d->sglen = 1;
 
 	d->ccr = c->ccr;
 	if (dir == DMA_DEV_TO_MEM)
@@ -1258,10 +1258,10 @@
 	d->dev_addr = src;
 	d->fi = 0;
 	d->es = data_type;
+	d->sglen = 1;
 	d->sg[0].en = len / BIT(data_type);
 	d->sg[0].fn = 1;
 	d->sg[0].addr = dest;
-	d->sglen = 1;
 	d->ccr = c->ccr;
 	d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_POSTINC;
 
@@ -1309,6 +1309,7 @@
 	if (data_type > CSDP_DATA_TYPE_32)
 		data_type = CSDP_DATA_TYPE_32;
 
+	d->sglen = 1;
 	sg = &d->sg[0];
 	d->dir = DMA_MEM_TO_MEM;
 	d->dev_addr = xt->src_start;
@@ -1316,7 +1317,6 @@
 	sg->en = xt->sgl[0].size / BIT(data_type);
 	sg->fn = xt->numf;
 	sg->addr = xt->dst_start;
-	d->sglen = 1;
 	d->ccr = c->ccr;
 
 	src_icg = dmaengine_get_src_icg(xt, &xt->sgl[0]);
--- linux-qcom-6.8.0.orig/drivers/dma/xilinx/xdma-regs.h
+++ linux-qcom-6.8.0/drivers/dma/xilinx/xdma-regs.h
@@ -117,6 +117,9 @@
 			 CHAN_CTRL_IE_WRITE_ERROR |			\
 			 CHAN_CTRL_IE_DESC_ERROR)
 
+/* bits of the channel status register */
+#define XDMA_CHAN_STATUS_BUSY			BIT(0)
+
 #define XDMA_CHAN_STATUS_MASK CHAN_CTRL_START
 
 #define XDMA_CHAN_ERROR_MASK (CHAN_CTRL_IE_DESC_ALIGN_MISMATCH |	\
--- linux-qcom-6.8.0.orig/drivers/dma/xilinx/xdma.c
+++ linux-qcom-6.8.0/drivers/dma/xilinx/xdma.c
@@ -71,6 +71,8 @@
 	enum dma_transfer_direction	dir;
 	struct dma_slave_config		cfg;
 	u32				irq;
+	struct completion		last_interrupt;
+	bool				stop_requested;
 };
 
 /**
@@ -376,6 +378,8 @@
 		return ret;
 
 	xchan->busy = true;
+	xchan->stop_requested = false;
+	reinit_completion(&xchan->last_interrupt);
 
 	return 0;
 }
@@ -387,7 +391,6 @@
 static int xdma_xfer_stop(struct xdma_chan *xchan)
 {
 	int ret;
-	u32 val;
 	struct xdma_device *xdev = xchan->xdev_hdl;
 
 	/* clear run stop bit to prevent any further auto-triggering */
@@ -395,13 +398,7 @@
 			   CHAN_CTRL_RUN_STOP);
 	if (ret)
 		return ret;
-
-	/* Clear the channel status register */
-	ret = regmap_read(xdev->rmap, xchan->base + XDMA_CHAN_STATUS_RC, &val);
-	if (ret)
-		return ret;
-
-	return 0;
+	return ret;
 }
 
 /**
@@ -474,6 +471,8 @@
 		xchan->xdev_hdl = xdev;
 		xchan->base = base + i * XDMA_CHAN_STRIDE;
 		xchan->dir = dir;
+		xchan->stop_requested = false;
+		init_completion(&xchan->last_interrupt);
 
 		ret = xdma_channel_init(xchan);
 		if (ret)
@@ -521,6 +520,7 @@
 	spin_lock_irqsave(&xdma_chan->vchan.lock, flags);
 
 	xdma_chan->busy = false;
+	xdma_chan->stop_requested = true;
 	vd = vchan_next_desc(&xdma_chan->vchan);
 	if (vd) {
 		list_del(&vd->node);
@@ -542,17 +542,26 @@
 static void xdma_synchronize(struct dma_chan *chan)
 {
 	struct xdma_chan *xdma_chan = to_xdma_chan(chan);
+	struct xdma_device *xdev = xdma_chan->xdev_hdl;
+	int st = 0;
+
+	/* If the engine continues running, wait for the last interrupt */
+	regmap_read(xdev->rmap, xdma_chan->base + XDMA_CHAN_STATUS, &st);
+	if (st & XDMA_CHAN_STATUS_BUSY)
+		wait_for_completion_timeout(&xdma_chan->last_interrupt, msecs_to_jiffies(1000));
 
 	vchan_synchronize(&xdma_chan->vchan);
 }
 
 /**
- * xdma_fill_descs - Fill hardware descriptors with contiguous memory block addresses
- * @sw_desc: tx descriptor state container
- * @src_addr: Value for a ->src_addr field of a first descriptor
- * @dst_addr: Value for a ->dst_addr field of a first descriptor
- * @size: Total size of a contiguous memory block
- * @filled_descs_num: Number of filled hardware descriptors for corresponding sw_desc
+ * xdma_fill_descs() - Fill hardware descriptors for one contiguous memory chunk.
+ *		       More than one descriptor will be used if the size is bigger
+ *		       than XDMA_DESC_BLEN_MAX.
+ * @sw_desc: Descriptor container
+ * @src_addr: First value for the ->src_addr field
+ * @dst_addr: First value for the ->dst_addr field
+ * @size: Size of the contiguous memory block
+ * @filled_descs_num: Index of the first descriptor to take care of in @sw_desc
  */
 static inline u32 xdma_fill_descs(struct xdma_desc *sw_desc, u64 src_addr,
 				  u64 dst_addr, u32 size, u32 filled_descs_num)
@@ -704,7 +713,7 @@
 	desc_num = 0;
 	for (i = 0; i < periods; i++) {
 		desc_num += xdma_fill_descs(sw_desc, *src, *dst, period_size, desc_num);
-		addr += i * period_size;
+		addr += period_size;
 	}
 
 	tx_desc = vchan_tx_prep(&xdma_chan->vchan, &sw_desc->vdesc, flags);
@@ -878,6 +887,9 @@
 
 	spin_lock(&xchan->vchan.lock);
 
+	if (xchan->stop_requested)
+		complete(&xchan->last_interrupt);
+
 	/* get submitted request */
 	vd = vchan_next_desc(&xchan->vchan);
 	if (!vd)
--- linux-qcom-6.8.0.orig/drivers/dma/xilinx/xilinx_dpdma.c
+++ linux-qcom-6.8.0/drivers/dma/xilinx/xilinx_dpdma.c
@@ -214,7 +214,8 @@
  * @running: true if the channel is running
  * @first_frame: flag for the first frame of stream
  * @video_group: flag if multi-channel operation is needed for video channels
- * @lock: lock to access struct xilinx_dpdma_chan
+ * @lock: lock to access struct xilinx_dpdma_chan. Must be taken before
+ *        @vchan.lock, if both are to be held.
  * @desc_pool: descriptor allocation pool
  * @err_task: error IRQ bottom half handler
  * @desc: References to descriptors being processed
@@ -1097,12 +1098,14 @@
 	 * Complete the active descriptor, if any, promote the pending
 	 * descriptor to active, and queue the next transfer, if any.
 	 */
+	spin_lock(&chan->vchan.lock);
 	if (chan->desc.active)
 		vchan_cookie_complete(&chan->desc.active->vdesc);
 	chan->desc.active = pending;
 	chan->desc.pending = NULL;
 
 	xilinx_dpdma_chan_queue_transfer(chan);
+	spin_unlock(&chan->vchan.lock);
 
 out:
 	spin_unlock_irqrestore(&chan->lock, flags);
@@ -1264,10 +1267,12 @@
 	struct xilinx_dpdma_chan *chan = to_xilinx_chan(dchan);
 	unsigned long flags;
 
-	spin_lock_irqsave(&chan->vchan.lock, flags);
+	spin_lock_irqsave(&chan->lock, flags);
+	spin_lock(&chan->vchan.lock);
 	if (vchan_issue_pending(&chan->vchan))
 		xilinx_dpdma_chan_queue_transfer(chan);
-	spin_unlock_irqrestore(&chan->vchan.lock, flags);
+	spin_unlock(&chan->vchan.lock);
+	spin_unlock_irqrestore(&chan->lock, flags);
 }
 
 static int xilinx_dpdma_config(struct dma_chan *dchan,
@@ -1495,7 +1500,9 @@
 		    XILINX_DPDMA_EINTR_CHAN_ERR_MASK << chan->id);
 
 	spin_lock_irqsave(&chan->lock, flags);
+	spin_lock(&chan->vchan.lock);
 	xilinx_dpdma_chan_queue_transfer(chan);
+	spin_unlock(&chan->vchan.lock);
 	spin_unlock_irqrestore(&chan->lock, flags);
 }
 
--- linux-qcom-6.8.0.orig/drivers/dpll/Kconfig
+++ linux-qcom-6.8.0/drivers/dpll/Kconfig
@@ -4,4 +4,4 @@
 #
 
 config DPLL
-  bool
+	bool
--- linux-qcom-6.8.0.orig/drivers/dpll/dpll_core.c
+++ linux-qcom-6.8.0/drivers/dpll/dpll_core.c
@@ -29,6 +29,8 @@
 	WARN_ON_ONCE(!xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED))
 #define ASSERT_DPLL_NOT_REGISTERED(d)	\
 	WARN_ON_ONCE(xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED))
+#define ASSERT_DPLL_PIN_REGISTERED(p) \
+	WARN_ON_ONCE(!xa_get_mark(&dpll_pin_xa, (p)->id, DPLL_REGISTERED))
 
 struct dpll_device_registration {
 	struct list_head list;
@@ -40,6 +42,7 @@
 	struct list_head list;
 	const struct dpll_pin_ops *ops;
 	void *priv;
+	void *cookie;
 };
 
 struct dpll_device *dpll_device_get_by_id(int id)
@@ -52,12 +55,14 @@
 
 static struct dpll_pin_registration *
 dpll_pin_registration_find(struct dpll_pin_ref *ref,
-			   const struct dpll_pin_ops *ops, void *priv)
+			   const struct dpll_pin_ops *ops, void *priv,
+			   void *cookie)
 {
 	struct dpll_pin_registration *reg;
 
 	list_for_each_entry(reg, &ref->registration_list, list) {
-		if (reg->ops == ops && reg->priv == priv)
+		if (reg->ops == ops && reg->priv == priv &&
+		    reg->cookie == cookie)
 			return reg;
 	}
 	return NULL;
@@ -65,7 +70,8 @@
 
 static int
 dpll_xa_ref_pin_add(struct xarray *xa_pins, struct dpll_pin *pin,
-		    const struct dpll_pin_ops *ops, void *priv)
+		    const struct dpll_pin_ops *ops, void *priv,
+		    void *cookie)
 {
 	struct dpll_pin_registration *reg;
 	struct dpll_pin_ref *ref;
@@ -76,7 +82,7 @@
 	xa_for_each(xa_pins, i, ref) {
 		if (ref->pin != pin)
 			continue;
-		reg = dpll_pin_registration_find(ref, ops, priv);
+		reg = dpll_pin_registration_find(ref, ops, priv, cookie);
 		if (reg) {
 			refcount_inc(&ref->refcount);
 			return 0;
@@ -109,6 +115,7 @@
 	}
 	reg->ops = ops;
 	reg->priv = priv;
+	reg->cookie = cookie;
 	if (ref_exists)
 		refcount_inc(&ref->refcount);
 	list_add_tail(&reg->list, &ref->registration_list);
@@ -117,7 +124,8 @@
 }
 
 static int dpll_xa_ref_pin_del(struct xarray *xa_pins, struct dpll_pin *pin,
-			       const struct dpll_pin_ops *ops, void *priv)
+			       const struct dpll_pin_ops *ops, void *priv,
+			       void *cookie)
 {
 	struct dpll_pin_registration *reg;
 	struct dpll_pin_ref *ref;
@@ -126,12 +134,12 @@
 	xa_for_each(xa_pins, i, ref) {
 		if (ref->pin != pin)
 			continue;
-		reg = dpll_pin_registration_find(ref, ops, priv);
+		reg = dpll_pin_registration_find(ref, ops, priv, cookie);
 		if (WARN_ON(!reg))
 			return -EINVAL;
+		list_del(&reg->list);
+		kfree(reg);
 		if (refcount_dec_and_test(&ref->refcount)) {
-			list_del(&reg->list);
-			kfree(reg);
 			xa_erase(xa_pins, i);
 			WARN_ON(!list_empty(&ref->registration_list));
 			kfree(ref);
@@ -144,7 +152,7 @@
 
 static int
 dpll_xa_ref_dpll_add(struct xarray *xa_dplls, struct dpll_device *dpll,
-		     const struct dpll_pin_ops *ops, void *priv)
+		     const struct dpll_pin_ops *ops, void *priv, void *cookie)
 {
 	struct dpll_pin_registration *reg;
 	struct dpll_pin_ref *ref;
@@ -155,7 +163,7 @@
 	xa_for_each(xa_dplls, i, ref) {
 		if (ref->dpll != dpll)
 			continue;
-		reg = dpll_pin_registration_find(ref, ops, priv);
+		reg = dpll_pin_registration_find(ref, ops, priv, cookie);
 		if (reg) {
 			refcount_inc(&ref->refcount);
 			return 0;
@@ -188,6 +196,7 @@
 	}
 	reg->ops = ops;
 	reg->priv = priv;
+	reg->cookie = cookie;
 	if (ref_exists)
 		refcount_inc(&ref->refcount);
 	list_add_tail(&reg->list, &ref->registration_list);
@@ -197,7 +206,7 @@
 
 static void
 dpll_xa_ref_dpll_del(struct xarray *xa_dplls, struct dpll_device *dpll,
-		     const struct dpll_pin_ops *ops, void *priv)
+		     const struct dpll_pin_ops *ops, void *priv, void *cookie)
 {
 	struct dpll_pin_registration *reg;
 	struct dpll_pin_ref *ref;
@@ -206,12 +215,12 @@
 	xa_for_each(xa_dplls, i, ref) {
 		if (ref->dpll != dpll)
 			continue;
-		reg = dpll_pin_registration_find(ref, ops, priv);
+		reg = dpll_pin_registration_find(ref, ops, priv, cookie);
 		if (WARN_ON(!reg))
 			return;
+		list_del(&reg->list);
+		kfree(reg);
 		if (refcount_dec_and_test(&ref->refcount)) {
-			list_del(&reg->list);
-			kfree(reg);
 			xa_erase(xa_dplls, i);
 			WARN_ON(!list_empty(&ref->registration_list));
 			kfree(ref);
@@ -440,7 +449,7 @@
 				   sizeof(*src->freq_supported);
 		dst->freq_supported = kmemdup(src->freq_supported,
 					      freq_size, GFP_KERNEL);
-		if (!src->freq_supported)
+		if (!dst->freq_supported)
 			return -ENOMEM;
 	}
 	if (src->board_label) {
@@ -592,14 +601,14 @@
 
 static int
 __dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin,
-		    const struct dpll_pin_ops *ops, void *priv)
+		    const struct dpll_pin_ops *ops, void *priv, void *cookie)
 {
 	int ret;
 
-	ret = dpll_xa_ref_pin_add(&dpll->pin_refs, pin, ops, priv);
+	ret = dpll_xa_ref_pin_add(&dpll->pin_refs, pin, ops, priv, cookie);
 	if (ret)
 		return ret;
-	ret = dpll_xa_ref_dpll_add(&pin->dpll_refs, dpll, ops, priv);
+	ret = dpll_xa_ref_dpll_add(&pin->dpll_refs, dpll, ops, priv, cookie);
 	if (ret)
 		goto ref_pin_del;
 	xa_set_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED);
@@ -608,7 +617,7 @@
 	return ret;
 
 ref_pin_del:
-	dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv);
+	dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv, cookie);
 	return ret;
 }
 
@@ -640,7 +649,7 @@
 		      dpll->clock_id == pin->clock_id)))
 		ret = -EINVAL;
 	else
-		ret = __dpll_pin_register(dpll, pin, ops, priv);
+		ret = __dpll_pin_register(dpll, pin, ops, priv, NULL);
 	mutex_unlock(&dpll_lock);
 
 	return ret;
@@ -649,10 +658,11 @@
 
 static void
 __dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin,
-		      const struct dpll_pin_ops *ops, void *priv)
+		      const struct dpll_pin_ops *ops, void *priv, void *cookie)
 {
-	dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv);
-	dpll_xa_ref_dpll_del(&pin->dpll_refs, dpll, ops, priv);
+	ASSERT_DPLL_PIN_REGISTERED(pin);
+	dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv, cookie);
+	dpll_xa_ref_dpll_del(&pin->dpll_refs, dpll, ops, priv, cookie);
 	if (xa_empty(&pin->dpll_refs))
 		xa_clear_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED);
 }
@@ -677,7 +687,7 @@
 
 	mutex_lock(&dpll_lock);
 	dpll_pin_delete_ntf(pin);
-	__dpll_pin_unregister(dpll, pin, ops, priv);
+	__dpll_pin_unregister(dpll, pin, ops, priv, NULL);
 	mutex_unlock(&dpll_lock);
 }
 EXPORT_SYMBOL_GPL(dpll_pin_unregister);
@@ -713,12 +723,12 @@
 		return -EINVAL;
 
 	mutex_lock(&dpll_lock);
-	ret = dpll_xa_ref_pin_add(&pin->parent_refs, parent, ops, priv);
+	ret = dpll_xa_ref_pin_add(&pin->parent_refs, parent, ops, priv, pin);
 	if (ret)
 		goto unlock;
 	refcount_inc(&pin->refcount);
 	xa_for_each(&parent->dpll_refs, i, ref) {
-		ret = __dpll_pin_register(ref->dpll, pin, ops, priv);
+		ret = __dpll_pin_register(ref->dpll, pin, ops, priv, parent);
 		if (ret) {
 			stop = i;
 			goto dpll_unregister;
@@ -732,11 +742,12 @@
 dpll_unregister:
 	xa_for_each(&parent->dpll_refs, i, ref)
 		if (i < stop) {
-			__dpll_pin_unregister(ref->dpll, pin, ops, priv);
+			__dpll_pin_unregister(ref->dpll, pin, ops, priv,
+					      parent);
 			dpll_pin_delete_ntf(pin);
 		}
 	refcount_dec(&pin->refcount);
-	dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv);
+	dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv, pin);
 unlock:
 	mutex_unlock(&dpll_lock);
 	return ret;
@@ -761,10 +772,10 @@
 
 	mutex_lock(&dpll_lock);
 	dpll_pin_delete_ntf(pin);
-	dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv);
+	dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv, pin);
 	refcount_dec(&pin->refcount);
 	xa_for_each(&pin->dpll_refs, i, ref)
-		__dpll_pin_unregister(ref->dpll, pin, ops, priv);
+		__dpll_pin_unregister(ref->dpll, pin, ops, priv, parent);
 	mutex_unlock(&dpll_lock);
 }
 EXPORT_SYMBOL_GPL(dpll_pin_on_pin_unregister);
--- linux-qcom-6.8.0.orig/drivers/dpll/dpll_netlink.c
+++ linux-qcom-6.8.0/drivers/dpll/dpll_netlink.c
@@ -335,6 +335,51 @@
 	return 0;
 }
 
+static int
+dpll_msg_add_pin_esync(struct sk_buff *msg, struct dpll_pin *pin,
+		       struct dpll_pin_ref *ref, struct netlink_ext_ack *extack)
+{
+	const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
+	struct dpll_device *dpll = ref->dpll;
+	struct dpll_pin_esync esync;
+	struct nlattr *nest;
+	int ret, i;
+
+	if (!ops->esync_get)
+		return 0;
+	ret = ops->esync_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
+			     dpll_priv(dpll), &esync, extack);
+	if (ret == -EOPNOTSUPP)
+		return 0;
+	else if (ret)
+		return ret;
+	if (nla_put_64bit(msg, DPLL_A_PIN_ESYNC_FREQUENCY, sizeof(esync.freq),
+			  &esync.freq, DPLL_A_PIN_PAD))
+		return -EMSGSIZE;
+	if (nla_put_u32(msg, DPLL_A_PIN_ESYNC_PULSE, esync.pulse))
+		return -EMSGSIZE;
+	for (i = 0; i < esync.range_num; i++) {
+		nest = nla_nest_start(msg,
+				      DPLL_A_PIN_ESYNC_FREQUENCY_SUPPORTED);
+		if (!nest)
+			return -EMSGSIZE;
+		if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MIN,
+				  sizeof(esync.range[i].min),
+				  &esync.range[i].min, DPLL_A_PIN_PAD))
+			goto nest_cancel;
+		if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MAX,
+				  sizeof(esync.range[i].max),
+				  &esync.range[i].max, DPLL_A_PIN_PAD))
+			goto nest_cancel;
+		nla_nest_end(msg, nest);
+	}
+	return 0;
+
+nest_cancel:
+	nla_nest_cancel(msg, nest);
+	return -EMSGSIZE;
+}
+
 static bool dpll_pin_is_freq_supported(struct dpll_pin *pin, u32 freq)
 {
 	int fs;
@@ -476,6 +521,9 @@
 	ret = dpll_msg_add_ffo(msg, pin, ref, extack);
 	if (ret)
 		return ret;
+	ret = dpll_msg_add_pin_esync(msg, pin, ref, extack);
+	if (ret)
+		return ret;
 	if (xa_empty(&pin->parent_refs))
 		ret = dpll_msg_add_pin_dplls(msg, pin, extack);
 	else
@@ -732,6 +780,83 @@
 }
 
 static int
+dpll_pin_esync_set(struct dpll_pin *pin, struct nlattr *a,
+		   struct netlink_ext_ack *extack)
+{
+	struct dpll_pin_ref *ref, *failed;
+	const struct dpll_pin_ops *ops;
+	struct dpll_pin_esync esync;
+	u64 freq = nla_get_u64(a);
+	struct dpll_device *dpll;
+	bool supported = false;
+	unsigned long i;
+	int ret;
+
+	xa_for_each(&pin->dpll_refs, i, ref) {
+		ops = dpll_pin_ops(ref);
+		if (!ops->esync_set || !ops->esync_get) {
+			NL_SET_ERR_MSG(extack,
+				       "embedded sync feature is not supported by this device");
+			return -EOPNOTSUPP;
+		}
+	}
+	ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
+	ops = dpll_pin_ops(ref);
+	dpll = ref->dpll;
+	ret = ops->esync_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
+			     dpll_priv(dpll), &esync, extack);
+	if (ret) {
+		NL_SET_ERR_MSG(extack, "unable to get current embedded sync frequency value");
+		return ret;
+	}
+	if (freq == esync.freq)
+		return 0;
+	for (i = 0; i < esync.range_num; i++)
+		if (freq <= esync.range[i].max && freq >= esync.range[i].min)
+			supported = true;
+	if (!supported) {
+		NL_SET_ERR_MSG_ATTR(extack, a,
+				    "requested embedded sync frequency value is not supported by this device");
+		return -EINVAL;
+	}
+
+	xa_for_each(&pin->dpll_refs, i, ref) {
+		void *pin_dpll_priv;
+
+		ops = dpll_pin_ops(ref);
+		dpll = ref->dpll;
+		pin_dpll_priv = dpll_pin_on_dpll_priv(dpll, pin);
+		ret = ops->esync_set(pin, pin_dpll_priv, dpll, dpll_priv(dpll),
+				      freq, extack);
+		if (ret) {
+			failed = ref;
+			NL_SET_ERR_MSG_FMT(extack,
+					   "embedded sync frequency set failed for dpll_id: %u",
+					   dpll->id);
+			goto rollback;
+		}
+	}
+	__dpll_pin_change_ntf(pin);
+
+	return 0;
+
+rollback:
+	xa_for_each(&pin->dpll_refs, i, ref) {
+		void *pin_dpll_priv;
+
+		if (ref == failed)
+			break;
+		ops = dpll_pin_ops(ref);
+		dpll = ref->dpll;
+		pin_dpll_priv = dpll_pin_on_dpll_priv(dpll, pin);
+		if (ops->esync_set(pin, pin_dpll_priv, dpll, dpll_priv(dpll),
+				   esync.freq, extack))
+			NL_SET_ERR_MSG(extack, "set embedded sync frequency rollback failed");
+	}
+	return ret;
+}
+
+static int
 dpll_pin_on_pin_state_set(struct dpll_pin *pin, u32 parent_idx,
 			  enum dpll_pin_state state,
 			  struct netlink_ext_ack *extack)
@@ -1032,6 +1157,11 @@
 			if (ret)
 				return ret;
 			break;
+		case DPLL_A_PIN_ESYNC_FREQUENCY:
+			ret = dpll_pin_esync_set(pin, a, info->extack);
+			if (ret)
+				return ret;
+			break;
 		}
 	}
 
--- linux-qcom-6.8.0.orig/drivers/dpll/dpll_nl.c
+++ linux-qcom-6.8.0/drivers/dpll/dpll_nl.c
@@ -62,7 +62,7 @@
 };
 
 /* DPLL_CMD_PIN_SET - do */
-static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_PHASE_ADJUST + 1] = {
+static const struct nla_policy dpll_pin_set_nl_policy[DPLL_A_PIN_ESYNC_FREQUENCY + 1] = {
 	[DPLL_A_PIN_ID] = { .type = NLA_U32, },
 	[DPLL_A_PIN_FREQUENCY] = { .type = NLA_U64, },
 	[DPLL_A_PIN_DIRECTION] = NLA_POLICY_RANGE(NLA_U32, 1, 2),
@@ -71,6 +71,7 @@
 	[DPLL_A_PIN_PARENT_DEVICE] = NLA_POLICY_NESTED(dpll_pin_parent_device_nl_policy),
 	[DPLL_A_PIN_PARENT_PIN] = NLA_POLICY_NESTED(dpll_pin_parent_pin_nl_policy),
 	[DPLL_A_PIN_PHASE_ADJUST] = { .type = NLA_S32, },
+	[DPLL_A_PIN_ESYNC_FREQUENCY] = { .type = NLA_U64, },
 };
 
 /* Ops table for dpll */
@@ -138,7 +139,7 @@
 		.doit		= dpll_nl_pin_set_doit,
 		.post_doit	= dpll_pin_post_doit,
 		.policy		= dpll_pin_set_nl_policy,
-		.maxattr	= DPLL_A_PIN_PHASE_ADJUST,
+		.maxattr	= DPLL_A_PIN_ESYNC_FREQUENCY,
 		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
 	},
 };
--- linux-qcom-6.8.0.orig/drivers/edac/Makefile
+++ linux-qcom-6.8.0/drivers/edac/Makefile
@@ -54,11 +54,13 @@
 layerscape_edac_mod-y			:= fsl_ddr_edac.o layerscape_edac.o
 obj-$(CONFIG_EDAC_LAYERSCAPE)		+= layerscape_edac_mod.o
 
-skx_edac-y				:= skx_common.o skx_base.o
-obj-$(CONFIG_EDAC_SKX)			+= skx_edac.o
+skx_edac_common-y			:= skx_common.o
 
-i10nm_edac-y				:= skx_common.o i10nm_base.o
-obj-$(CONFIG_EDAC_I10NM)		+= i10nm_edac.o
+skx_edac-y				:= skx_base.o
+obj-$(CONFIG_EDAC_SKX)			+= skx_edac.o skx_edac_common.o
+
+i10nm_edac-y				:= i10nm_base.o
+obj-$(CONFIG_EDAC_I10NM)		+= i10nm_edac.o skx_edac_common.o
 
 obj-$(CONFIG_EDAC_CELL)			+= cell_edac.o
 obj-$(CONFIG_EDAC_PPC4XX)		+= ppc4xx_edac.o
--- linux-qcom-6.8.0.orig/drivers/edac/amd64_edac.c
+++ linux-qcom-6.8.0/drivers/edac/amd64_edac.c
@@ -80,7 +80,7 @@
 		amd64_warn("%s: error reading F%dx%03x.\n",
 			   func, PCI_FUNC(pdev->devfn), offset);
 
-	return err;
+	return pcibios_err_to_errno(err);
 }
 
 int __amd64_write_pci_cfg_dword(struct pci_dev *pdev, int offset,
@@ -93,7 +93,7 @@
 		amd64_warn("%s: error writing to F%dx%03x.\n",
 			   func, PCI_FUNC(pdev->devfn), offset);
 
-	return err;
+	return pcibios_err_to_errno(err);
 }
 
 /*
@@ -1024,8 +1024,10 @@
 	}
 
 	ret = pci_read_config_dword(pdev, REG_LOCAL_NODE_TYPE_MAP, &tmp);
-	if (ret)
+	if (ret) {
+		ret = pcibios_err_to_errno(ret);
 		goto out;
+	}
 
 	gpu_node_map.node_count = FIELD_GET(LNTM_NODE_COUNT, tmp);
 	gpu_node_map.base_node_id = FIELD_GET(LNTM_BASE_NODE_ID, tmp);
@@ -3626,36 +3628,24 @@
 
 static bool umc_ecc_enabled(struct amd64_pvt *pvt)
 {
-	u8 umc_en_mask = 0, ecc_en_mask = 0;
-	u16 nid = pvt->mc_node_id;
 	struct amd64_umc *umc;
-	u8 ecc_en = 0, i;
+	bool ecc_en = false;
+	int i;
 
+	/* Check whether at least one UMC is enabled: */
 	for_each_umc(i) {
 		umc = &pvt->umc[i];
 
-		/* Only check enabled UMCs. */
-		if (!(umc->sdp_ctrl & UMC_SDP_INIT))
-			continue;
-
-		umc_en_mask |= BIT(i);
-
-		if (umc->umc_cap_hi & UMC_ECC_ENABLED)
-			ecc_en_mask |= BIT(i);
+		if (umc->sdp_ctrl & UMC_SDP_INIT &&
+		    umc->umc_cap_hi & UMC_ECC_ENABLED) {
+			ecc_en = true;
+			break;
+		}
 	}
 
-	/* Check whether at least one UMC is enabled: */
-	if (umc_en_mask)
-		ecc_en = umc_en_mask == ecc_en_mask;
-	else
-		edac_dbg(0, "Node %d: No enabled UMCs.\n", nid);
+	edac_dbg(3, "Node %d: DRAM ECC %s.\n", pvt->mc_node_id, (ecc_en ? "enabled" : "disabled"));
 
-	edac_dbg(3, "Node %d: DRAM ECC %s.\n", nid, (ecc_en ? "enabled" : "disabled"));
-
-	if (!ecc_en)
-		return false;
-	else
-		return true;
+	return ecc_en;
 }
 
 static inline void
--- linux-qcom-6.8.0.orig/drivers/edac/bluefield_edac.c
+++ linux-qcom-6.8.0/drivers/edac/bluefield_edac.c
@@ -180,7 +180,7 @@
 static void bluefield_edac_init_dimms(struct mem_ctl_info *mci)
 {
 	struct bluefield_edac_priv *priv = mci->pvt_info;
-	int mem_ctrl_idx = mci->mc_idx;
+	u64 mem_ctrl_idx = mci->mc_idx;
 	struct dimm_info *dimm;
 	u64 smc_info, smc_arg;
 	int is_empty = 1, i;
--- linux-qcom-6.8.0.orig/drivers/edac/fsl_ddr_edac.c
+++ linux-qcom-6.8.0/drivers/edac/fsl_ddr_edac.c
@@ -328,21 +328,25 @@
 	 * TODO: Add support for 32-bit wide buses
 	 */
 	if ((err_detect & DDR_EDE_SBE) && (bus_width == 64)) {
+		u64 cap = (u64)cap_high << 32 | cap_low;
+		u32 s = syndrome;
+
 		sbe_ecc_decode(cap_high, cap_low, syndrome,
 				&bad_data_bit, &bad_ecc_bit);
 
-		if (bad_data_bit != -1)
-			fsl_mc_printk(mci, KERN_ERR,
-				"Faulty Data bit: %d\n", bad_data_bit);
-		if (bad_ecc_bit != -1)
-			fsl_mc_printk(mci, KERN_ERR,
-				"Faulty ECC bit: %d\n", bad_ecc_bit);
+		if (bad_data_bit >= 0) {
+			fsl_mc_printk(mci, KERN_ERR, "Faulty Data bit: %d\n", bad_data_bit);
+			cap ^= 1ULL << bad_data_bit;
+		}
+
+		if (bad_ecc_bit >= 0) {
+			fsl_mc_printk(mci, KERN_ERR, "Faulty ECC bit: %d\n", bad_ecc_bit);
+			s ^= 1 << bad_ecc_bit;
+		}
 
 		fsl_mc_printk(mci, KERN_ERR,
 			"Expected Data / ECC:\t%#8.8x_%08x / %#2.2x\n",
-			cap_high ^ (1 << (bad_data_bit - 32)),
-			cap_low ^ (1 << bad_data_bit),
-			syndrome ^ (1 << bad_ecc_bit));
+			upper_32_bits(cap), lower_32_bits(cap), s);
 	}
 
 	fsl_mc_printk(mci, KERN_ERR,
--- linux-qcom-6.8.0.orig/drivers/edac/i10nm_base.c
+++ linux-qcom-6.8.0/drivers/edac/i10nm_base.c
@@ -1088,6 +1088,7 @@
 		return -ENODEV;
 
 	cfg = (struct res_config *)id->driver_data;
+	skx_set_res_cfg(cfg);
 	res_cfg = cfg;
 
 	rc = skx_get_hi_lo(0x09a2, off, &tolm, &tohm);
--- linux-qcom-6.8.0.orig/drivers/edac/igen6_edac.c
+++ linux-qcom-6.8.0/drivers/edac/igen6_edac.c
@@ -257,6 +257,11 @@
 #define DID_MTL_P_SKU2	0x7d02
 #define DID_MTL_P_SKU3	0x7d14
 
+/* Compute die IDs for Arrow Lake-UH with IBECC */
+#define DID_ARL_UH_SKU1	0x7d06
+#define DID_ARL_UH_SKU2	0x7d20
+#define DID_ARL_UH_SKU3	0x7d30
+
 static int get_mchbar(struct pci_dev *pdev, u64 *mchbar)
 {
 	union  {
@@ -310,7 +315,7 @@
 	if (igen6_tom <= _4GB)
 		return eaddr + igen6_tolud - _4GB;
 
-	if (eaddr < _4GB)
+	if (eaddr >= igen6_tom)
 		return eaddr + igen6_tolud - igen6_tom;
 
 	return eaddr;
@@ -595,6 +600,9 @@
 	{ PCI_VDEVICE(INTEL, DID_MTL_P_SKU1), (kernel_ulong_t)&mtl_p_cfg },
 	{ PCI_VDEVICE(INTEL, DID_MTL_P_SKU2), (kernel_ulong_t)&mtl_p_cfg },
 	{ PCI_VDEVICE(INTEL, DID_MTL_P_SKU3), (kernel_ulong_t)&mtl_p_cfg },
+	{ PCI_VDEVICE(INTEL, DID_ARL_UH_SKU1), (kernel_ulong_t)&mtl_p_cfg },
+	{ PCI_VDEVICE(INTEL, DID_ARL_UH_SKU2), (kernel_ulong_t)&mtl_p_cfg },
+	{ PCI_VDEVICE(INTEL, DID_ARL_UH_SKU3), (kernel_ulong_t)&mtl_p_cfg },
 	{ },
 };
 MODULE_DEVICE_TABLE(pci, igen6_pci_tbl);
@@ -798,7 +806,7 @@
 
 	rc = pci_read_config_word(imc->pdev, ERRCMD_OFFSET, &errcmd);
 	if (rc)
-		return rc;
+		return pcibios_err_to_errno(rc);
 
 	if (enable)
 		errcmd |= ERRCMD_CE | ERRSTS_UE;
@@ -807,7 +815,7 @@
 
 	rc = pci_write_config_word(imc->pdev, ERRCMD_OFFSET, errcmd);
 	if (rc)
-		return rc;
+		return pcibios_err_to_errno(rc);
 
 	return 0;
 }
@@ -1235,6 +1243,7 @@
 	imc->mci = mci;
 	return 0;
 fail3:
+	mci->pvt_info = NULL;
 	kfree(mci->ctl_name);
 fail2:
 	edac_mc_free(mci);
@@ -1259,6 +1268,7 @@
 
 		edac_mc_del_mc(mci->pdev);
 		kfree(mci->ctl_name);
+		mci->pvt_info = NULL;
 		edac_mc_free(mci);
 		iounmap(imc->window);
 	}
--- linux-qcom-6.8.0.orig/drivers/edac/qcom_edac.c
+++ linux-qcom-6.8.0/drivers/edac/qcom_edac.c
@@ -95,7 +95,7 @@
 	 * Configure interrupt enable registers such that Tag, Data RAM related
 	 * interrupts are propagated to interrupt controller for servicing
 	 */
-	ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_2_enable,
+	ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_0_enable,
 				 TRP0_INTERRUPT_ENABLE,
 				 TRP0_INTERRUPT_ENABLE);
 	if (ret)
@@ -113,7 +113,7 @@
 	if (ret)
 		return ret;
 
-	ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_2_enable,
+	ret = regmap_update_bits(llcc_bcast_regmap, drv->edac_reg_offset->cmn_interrupt_0_enable,
 				 DRP0_INTERRUPT_ENABLE,
 				 DRP0_INTERRUPT_ENABLE);
 	if (ret)
@@ -342,9 +342,11 @@
 	int ecc_irq;
 	int rc;
 
-	rc = qcom_llcc_core_setup(llcc_driv_data, llcc_driv_data->bcast_regmap);
-	if (rc)
-		return rc;
+	if (!llcc_driv_data->ecc_irq_configured) {
+		rc = qcom_llcc_core_setup(llcc_driv_data, llcc_driv_data->bcast_regmap);
+		if (rc)
+			return rc;
+	}
 
 	/* Allocate edac control info */
 	edev_ctl = edac_device_alloc_ctl_info(0, "qcom-llcc", 1, "bank",
--- linux-qcom-6.8.0.orig/drivers/edac/skx_common.c
+++ linux-qcom-6.8.0/drivers/edac/skx_common.c
@@ -47,8 +47,9 @@
 static u64 skx_tolm, skx_tohm;
 static LIST_HEAD(dev_edac_list);
 static bool skx_mem_cfg_2lm;
+static struct res_config *skx_res_cfg;
 
-int __init skx_adxl_get(void)
+int skx_adxl_get(void)
 {
 	const char * const *names;
 	int i, j;
@@ -110,14 +111,16 @@
 
 	return -ENODEV;
 }
+EXPORT_SYMBOL_GPL(skx_adxl_get);
 
-void __exit skx_adxl_put(void)
+void skx_adxl_put(void)
 {
 	kfree(adxl_values);
 	kfree(adxl_msg);
 }
+EXPORT_SYMBOL_GPL(skx_adxl_put);
 
-static bool skx_adxl_decode(struct decoded_addr *res, bool error_in_1st_level_mem)
+static bool skx_adxl_decode(struct decoded_addr *res, enum error_source err_src)
 {
 	struct skx_dev *d;
 	int i, len = 0;
@@ -133,8 +136,24 @@
 		return false;
 	}
 
+	/*
+	 * GNR with a Flat2LM memory configuration may mistakenly classify
+	 * a near-memory error(DDR5) as a far-memory error(CXL), resulting
+	 * in the incorrect selection of decoded ADXL components.
+	 * To address this, prefetch the decoded far-memory controller ID
+	 * and adjust the error source to near-memory if the far-memory
+	 * controller ID is invalid.
+	 */
+	if (skx_res_cfg && skx_res_cfg->type == GNR && err_src == ERR_SRC_2LM_FM) {
+		res->imc = (int)adxl_values[component_indices[INDEX_MEMCTRL]];
+		if (res->imc == -1) {
+			err_src = ERR_SRC_2LM_NM;
+			edac_dbg(0, "Adjust the error source to near-memory.\n");
+		}
+	}
+
 	res->socket  = (int)adxl_values[component_indices[INDEX_SOCKET]];
-	if (error_in_1st_level_mem) {
+	if (err_src == ERR_SRC_2LM_NM) {
 		res->imc     = (adxl_nm_bitmap & BIT_NM_MEMCTRL) ?
 			       (int)adxl_values[component_indices[INDEX_NM_MEMCTRL]] : -1;
 		res->channel = (adxl_nm_bitmap & BIT_NM_CHANNEL) ?
@@ -187,12 +206,20 @@
 {
 	skx_mem_cfg_2lm = mem_cfg_2lm;
 }
+EXPORT_SYMBOL_GPL(skx_set_mem_cfg);
+
+void skx_set_res_cfg(struct res_config *cfg)
+{
+	skx_res_cfg = cfg;
+}
+EXPORT_SYMBOL_GPL(skx_set_res_cfg);
 
 void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log)
 {
 	driver_decode = decode;
 	skx_show_retry_rd_err_log = show_retry_log;
 }
+EXPORT_SYMBOL_GPL(skx_set_decode);
 
 int skx_get_src_id(struct skx_dev *d, int off, u8 *id)
 {
@@ -206,6 +233,7 @@
 	*id = GET_BITFIELD(reg, 12, 14);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(skx_get_src_id);
 
 int skx_get_node_id(struct skx_dev *d, u8 *id)
 {
@@ -219,6 +247,7 @@
 	*id = GET_BITFIELD(reg, 0, 2);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(skx_get_node_id);
 
 static int get_width(u32 mtr)
 {
@@ -284,6 +313,7 @@
 		*list = &dev_edac_list;
 	return ndev;
 }
+EXPORT_SYMBOL_GPL(skx_get_all_bus_mappings);
 
 int skx_get_hi_lo(unsigned int did, int off[], u64 *tolm, u64 *tohm)
 {
@@ -323,6 +353,7 @@
 	pci_dev_put(pdev);
 	return -ENODEV;
 }
+EXPORT_SYMBOL_GPL(skx_get_hi_lo);
 
 static int skx_get_dimm_attr(u32 reg, int lobit, int hibit, int add,
 			     int minval, int maxval, const char *name)
@@ -394,6 +425,7 @@
 
 	return 1;
 }
+EXPORT_SYMBOL_GPL(skx_get_dimm_info);
 
 int skx_get_nvdimm_info(struct dimm_info *dimm, struct skx_imc *imc,
 			int chan, int dimmno, const char *mod_str)
@@ -442,6 +474,7 @@
 
 	return (size == 0 || size == ~0ull) ? 0 : 1;
 }
+EXPORT_SYMBOL_GPL(skx_get_nvdimm_info);
 
 int skx_register_mci(struct skx_imc *imc, struct pci_dev *pdev,
 		     const char *ctl_name, const char *mod_str,
@@ -512,6 +545,7 @@
 	imc->mci = NULL;
 	return rc;
 }
+EXPORT_SYMBOL_GPL(skx_register_mci);
 
 static void skx_unregister_mci(struct skx_imc *imc)
 {
@@ -609,31 +643,27 @@
 			     optype, skx_msg);
 }
 
-static bool skx_error_in_1st_level_mem(const struct mce *m)
+static enum error_source skx_error_source(const struct mce *m)
 {
-	u32 errcode;
+	u32 errcode = GET_BITFIELD(m->status, 0, 15) & MCACOD_MEM_ERR_MASK;
 
-	if (!skx_mem_cfg_2lm)
-		return false;
-
-	errcode = GET_BITFIELD(m->status, 0, 15) & MCACOD_MEM_ERR_MASK;
-
-	return errcode == MCACOD_EXT_MEM_ERR;
-}
+	if (errcode != MCACOD_MEM_CTL_ERR && errcode != MCACOD_EXT_MEM_ERR)
+		return ERR_SRC_NOT_MEMORY;
 
-static bool skx_error_in_mem(const struct mce *m)
-{
-	u32 errcode;
+	if (!skx_mem_cfg_2lm)
+		return ERR_SRC_1LM;
 
-	errcode = GET_BITFIELD(m->status, 0, 15) & MCACOD_MEM_ERR_MASK;
+	if (errcode == MCACOD_EXT_MEM_ERR)
+		return ERR_SRC_2LM_NM;
 
-	return (errcode == MCACOD_MEM_CTL_ERR || errcode == MCACOD_EXT_MEM_ERR);
+	return ERR_SRC_2LM_FM;
 }
 
 int skx_mce_check_error(struct notifier_block *nb, unsigned long val,
 			void *data)
 {
 	struct mce *mce = (struct mce *)data;
+	enum error_source err_src;
 	struct decoded_addr res;
 	struct mem_ctl_info *mci;
 	char *type;
@@ -641,14 +671,16 @@
 	if (mce->kflags & MCE_HANDLED_CEC)
 		return NOTIFY_DONE;
 
+	err_src = skx_error_source(mce);
+
 	/* Ignore unless this is memory related with an address */
-	if (!skx_error_in_mem(mce) || !(mce->status & MCI_STATUS_ADDRV))
+	if (err_src == ERR_SRC_NOT_MEMORY || !(mce->status & MCI_STATUS_ADDRV))
 		return NOTIFY_DONE;
 
 	memset(&res, 0, sizeof(res));
 	res.mce  = mce;
 	res.addr = mce->addr & MCI_ADDR_PHYSADDR;
-	if (!pfn_to_online_page(res.addr >> PAGE_SHIFT)) {
+	if (!pfn_to_online_page(res.addr >> PAGE_SHIFT) && !arch_is_platform_page(res.addr)) {
 		pr_err("Invalid address 0x%llx in IA32_MC%d_ADDR\n", mce->addr, mce->bank);
 		return NOTIFY_DONE;
 	}
@@ -656,7 +688,7 @@
 	/* Try driver decoder first */
 	if (!(driver_decode && driver_decode(&res))) {
 		/* Then try firmware decoder (ACPI DSM methods) */
-		if (!(adxl_component_count && skx_adxl_decode(&res, skx_error_in_1st_level_mem(mce))))
+		if (!(adxl_component_count && skx_adxl_decode(&res, err_src)))
 			return NOTIFY_DONE;
 	}
 
@@ -688,6 +720,7 @@
 	mce->kflags |= MCE_HANDLED_EDAC;
 	return NOTIFY_DONE;
 }
+EXPORT_SYMBOL_GPL(skx_mce_check_error);
 
 void skx_remove(void)
 {
@@ -725,3 +758,8 @@
 		kfree(d);
 	}
 }
+EXPORT_SYMBOL_GPL(skx_remove);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Tony Luck");
+MODULE_DESCRIPTION("MC Driver for Intel server processors");
--- linux-qcom-6.8.0.orig/drivers/edac/skx_common.h
+++ linux-qcom-6.8.0/drivers/edac/skx_common.h
@@ -147,6 +147,13 @@
 	INDEX_MAX
 };
 
+enum error_source {
+	ERR_SRC_1LM,
+	ERR_SRC_2LM_NM,
+	ERR_SRC_2LM_FM,
+	ERR_SRC_NOT_MEMORY,
+};
+
 #define BIT_NM_MEMCTRL	BIT_ULL(INDEX_NM_MEMCTRL)
 #define BIT_NM_CHANNEL	BIT_ULL(INDEX_NM_CHANNEL)
 #define BIT_NM_DIMM	BIT_ULL(INDEX_NM_DIMM)
@@ -231,10 +238,11 @@
 typedef bool (*skx_decode_f)(struct decoded_addr *res);
 typedef void (*skx_show_retry_log_f)(struct decoded_addr *res, char *msg, int len, bool scrub_err);
 
-int __init skx_adxl_get(void);
-void __exit skx_adxl_put(void);
+int skx_adxl_get(void);
+void skx_adxl_put(void);
 void skx_set_decode(skx_decode_f decode, skx_show_retry_log_f show_retry_log);
 void skx_set_mem_cfg(bool mem_cfg_2lm);
+void skx_set_res_cfg(struct res_config *cfg);
 
 int skx_get_src_id(struct skx_dev *d, int off, u8 *id);
 int skx_get_node_id(struct skx_dev *d, u8 *id);
--- linux-qcom-6.8.0.orig/drivers/edac/synopsys_edac.c
+++ linux-qcom-6.8.0/drivers/edac/synopsys_edac.c
@@ -9,6 +9,8 @@
 #include <linux/edac.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/sizes.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
 
@@ -299,6 +301,7 @@
 /**
  * struct synps_edac_priv - DDR memory controller private instance data.
  * @baseaddr:		Base address of the DDR controller.
+ * @reglock:		Concurrent CSRs access lock.
  * @message:		Buffer for framing the event specific info.
  * @stat:		ECC status information.
  * @p_data:		Platform data.
@@ -313,6 +316,7 @@
  */
 struct synps_edac_priv {
 	void __iomem *baseaddr;
+	spinlock_t reglock;
 	char message[SYNPS_EDAC_MSG_SIZE];
 	struct synps_ecc_status stat;
 	const struct synps_platform_data *p_data;
@@ -334,6 +338,7 @@
  * @get_mtype:		Get mtype.
  * @get_dtype:		Get dtype.
  * @get_ecc_state:	Get ECC state.
+ * @get_mem_info:	Get EDAC memory info
  * @quirks:		To differentiate IPs.
  */
 struct synps_platform_data {
@@ -341,6 +346,9 @@
 	enum mem_type (*get_mtype)(const void __iomem *base);
 	enum dev_type (*get_dtype)(const void __iomem *base);
 	bool (*get_ecc_state)(void __iomem *base);
+#ifdef CONFIG_EDAC_DEBUG
+	u64 (*get_mem_info)(struct synps_edac_priv *priv);
+#endif
 	int quirks;
 };
 
@@ -399,6 +407,25 @@
 	return 0;
 }
 
+#ifdef CONFIG_EDAC_DEBUG
+/**
+ * zynqmp_get_mem_info - Get the current memory info.
+ * @priv:	DDR memory controller private instance data.
+ *
+ * Return: host interface address.
+ */
+static u64 zynqmp_get_mem_info(struct synps_edac_priv *priv)
+{
+	u64 hif_addr = 0, linear_addr;
+
+	linear_addr = priv->poison_addr;
+	if (linear_addr >= SZ_32G)
+		linear_addr = linear_addr - SZ_32G + SZ_2G;
+	hif_addr = linear_addr >> 3;
+	return hif_addr;
+}
+#endif
+
 /**
  * zynqmp_get_error_info - Get the current ECC error info.
  * @priv:	DDR memory controller private instance data.
@@ -408,7 +435,8 @@
 static int zynqmp_get_error_info(struct synps_edac_priv *priv)
 {
 	struct synps_ecc_status *p;
-	u32 regval, clearval = 0;
+	u32 regval, clearval;
+	unsigned long flags;
 	void __iomem *base;
 
 	base = priv->baseaddr;
@@ -452,10 +480,14 @@
 	p->ueinfo.blknr = (regval & ECC_CEADDR1_BLKNR_MASK);
 	p->ueinfo.data = readl(base + ECC_UESYND0_OFST);
 out:
-	clearval = ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT;
-	clearval |= ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
+	spin_lock_irqsave(&priv->reglock, flags);
+
+	clearval = readl(base + ECC_CLR_OFST) |
+		   ECC_CTRL_CLR_CE_ERR | ECC_CTRL_CLR_CE_ERRCNT |
+		   ECC_CTRL_CLR_UE_ERR | ECC_CTRL_CLR_UE_ERRCNT;
 	writel(clearval, base + ECC_CLR_OFST);
-	writel(0x0, base + ECC_CLR_OFST);
+
+	spin_unlock_irqrestore(&priv->reglock, flags);
 
 	return 0;
 }
@@ -515,24 +547,41 @@
 
 static void enable_intr(struct synps_edac_priv *priv)
 {
+	unsigned long flags;
+
 	/* Enable UE/CE Interrupts */
-	if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
-		writel(DDR_UE_MASK | DDR_CE_MASK,
-		       priv->baseaddr + ECC_CLR_OFST);
-	else
+	if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
 		writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
 		       priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
 
+		return;
+	}
+
+	spin_lock_irqsave(&priv->reglock, flags);
+
+	writel(DDR_UE_MASK | DDR_CE_MASK,
+	       priv->baseaddr + ECC_CLR_OFST);
+
+	spin_unlock_irqrestore(&priv->reglock, flags);
 }
 
 static void disable_intr(struct synps_edac_priv *priv)
 {
+	unsigned long flags;
+
 	/* Disable UE/CE Interrupts */
-	if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
-		writel(0x0, priv->baseaddr + ECC_CLR_OFST);
-	else
+	if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
 		writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
 		       priv->baseaddr + DDR_QOS_IRQ_DB_OFST);
+
+		return;
+	}
+
+	spin_lock_irqsave(&priv->reglock, flags);
+
+	writel(0, priv->baseaddr + ECC_CLR_OFST);
+
+	spin_unlock_irqrestore(&priv->reglock, flags);
 }
 
 /**
@@ -576,8 +625,6 @@
 	/* v3.0 of the controller does not have this register */
 	if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR))
 		writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
-	else
-		enable_intr(priv);
 
 	return IRQ_HANDLED;
 }
@@ -899,6 +946,9 @@
 	.get_mtype	= zynqmp_get_mtype,
 	.get_dtype	= zynqmp_get_dtype,
 	.get_ecc_state	= zynqmp_get_ecc_state,
+#ifdef CONFIG_EDAC_DEBUG
+	.get_mem_info	= zynqmp_get_mem_info,
+#endif
 	.quirks         = (DDR_ECC_INTR_SUPPORT
 #ifdef CONFIG_EDAC_DEBUG
 			  | DDR_ECC_DATA_POISON_SUPPORT
@@ -952,10 +1002,16 @@
 static void ddr_poison_setup(struct synps_edac_priv *priv)
 {
 	int col = 0, row = 0, bank = 0, bankgrp = 0, rank = 0, regval;
+	const struct synps_platform_data *p_data;
 	int index;
 	ulong hif_addr = 0;
 
-	hif_addr = priv->poison_addr >> 3;
+	p_data = priv->p_data;
+
+	if (p_data->get_mem_info)
+		hif_addr = p_data->get_mem_info(priv);
+	else
+		hif_addr = priv->poison_addr >> 3;
 
 	for (index = 0; index < DDR_MAX_ROW_SHIFT; index++) {
 		if (priv->row_shift[index])
@@ -1359,6 +1415,7 @@
 	priv = mci->pvt_info;
 	priv->baseaddr = baseaddr;
 	priv->p_data = p_data;
+	spin_lock_init(&priv->reglock);
 
 	mc_init(mci, pdev);
 
--- linux-qcom-6.8.0.orig/drivers/edac/versal_edac.c
+++ linux-qcom-6.8.0/drivers/edac/versal_edac.c
@@ -423,7 +423,7 @@
 			 convert_to_physical(priv, pinf), pinf.burstpos);
 
 		edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci,
-				     priv->ce_cnt, 0, 0, 0, 0, 0, -1,
+				     1, 0, 0, 0, 0, 0, -1,
 				     priv->message, "");
 	}
 
@@ -436,7 +436,7 @@
 			 convert_to_physical(priv, pinf), pinf.burstpos);
 
 		edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci,
-				     priv->ue_cnt, 0, 0, 0, 0, 0, -1,
+				     1, 0, 0, 0, 0, 0, -1,
 				     priv->message, "");
 	}
 
@@ -1006,8 +1006,7 @@
 	}
 
 	rc = xlnx_register_event(PM_NOTIFY_CB, VERSAL_EVENT_ERROR_PMC_ERR1,
-				 XPM_EVENT_ERROR_MASK_DDRMC_CR | XPM_EVENT_ERROR_MASK_DDRMC_NCR |
-				 XPM_EVENT_ERROR_MASK_NOC_CR | XPM_EVENT_ERROR_MASK_NOC_NCR,
+				 XPM_EVENT_ERROR_MASK_DDRMC_CR | XPM_EVENT_ERROR_MASK_DDRMC_NCR,
 				 false, err_callback, mci);
 	if (rc) {
 		if (rc == -EACCES)
@@ -1044,8 +1043,6 @@
 
 	xlnx_unregister_event(PM_NOTIFY_CB, VERSAL_EVENT_ERROR_PMC_ERR1,
 			      XPM_EVENT_ERROR_MASK_DDRMC_CR |
-			      XPM_EVENT_ERROR_MASK_NOC_CR |
-			      XPM_EVENT_ERROR_MASK_NOC_NCR |
 			      XPM_EVENT_ERROR_MASK_DDRMC_NCR, err_callback, mci);
 	edac_mc_del_mc(&pdev->dev);
 	edac_mc_free(mci);
--- linux-qcom-6.8.0.orig/drivers/extcon/Kconfig
+++ linux-qcom-6.8.0/drivers/extcon/Kconfig
@@ -116,7 +116,8 @@
 
 config EXTCON_MAX8997
 	tristate "Maxim MAX8997 EXTCON Support"
-	depends on MFD_MAX8997 && IRQ_DOMAIN
+	depends on MFD_MAX8997
+	select IRQ_DOMAIN
 	help
 	  If you say yes here you get support for the MUIC device of
 	  Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory
--- linux-qcom-6.8.0.orig/drivers/firewire/core-cdev.c
+++ linux-qcom-6.8.0/drivers/firewire/core-cdev.c
@@ -598,11 +598,11 @@
 		queue_event(client, &e->event, rsp, sizeof(*rsp) + rsp->length, NULL, 0);
 
 		break;
+	}
 	default:
 		WARN_ON(1);
 		break;
 	}
-	}
 
 	/* Drop the idr's reference */
 	client_put(client);
--- linux-qcom-6.8.0.orig/drivers/firewire/device-attribute-test.c
+++ linux-qcom-6.8.0/drivers/firewire/device-attribute-test.c
@@ -99,6 +99,7 @@
 	struct device *unit0_dev = (struct device *)&unit0.device;
 	static const int unit0_expected_ids[] = {0x00ffffff, 0x00ffffff, 0x0000a02d, 0x00010001};
 	char *buf = kunit_kzalloc(test, PAGE_SIZE, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 	int ids[4] = {0, 0, 0, 0};
 
 	// Ensure associations for node and unit devices.
@@ -180,6 +181,7 @@
 	struct device *unit0_dev = (struct device *)&unit0.device;
 	static const int unit0_expected_ids[] = {0x00012345, 0x00fedcba, 0x00abcdef, 0x00543210};
 	char *buf = kunit_kzalloc(test, PAGE_SIZE, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
 	int ids[4] = {0, 0, 0, 0};
 
 	// Ensure associations for node and unit devices.
--- linux-qcom-6.8.0.orig/drivers/firewire/nosy.c
+++ linux-qcom-6.8.0/drivers/firewire/nosy.c
@@ -148,10 +148,12 @@
 	if (atomic_read(&buffer->size) == 0)
 		return -ENODEV;
 
-	/* FIXME: Check length <= user_length. */
+	length = buffer->head->length;
+
+	if (length > user_length)
+		return 0;
 
 	end = buffer->data + buffer->capacity;
-	length = buffer->head->length;
 
 	if (&buffer->head->data[length] < end) {
 		if (copy_to_user(data, buffer->head->data, length))
--- linux-qcom-6.8.0.orig/drivers/firewire/ohci.c
+++ linux-qcom-6.8.0/drivers/firewire/ohci.c
@@ -1556,6 +1556,8 @@
 #define HEADER_GET_DATA_LENGTH(q)	(((q) >> 16) & 0xffff)
 #define HEADER_GET_EXTENDED_TCODE(q)	(((q) >> 0) & 0xffff)
 
+static u32 get_cycle_time(struct fw_ohci *ohci);
+
 static void handle_local_rom(struct fw_ohci *ohci,
 			     struct fw_packet *packet, u32 csr)
 {
@@ -1580,6 +1582,8 @@
 				 (void *) ohci->config_rom + i, length);
 	}
 
+	// Timestamping on behalf of the hardware.
+	response.timestamp = cycle_time_to_ohci_tstamp(get_cycle_time(ohci));
 	fw_core_handle_response(&ohci->card, &response);
 }
 
@@ -1628,6 +1632,8 @@
 	fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0);
 
  out:
+	// Timestamping on behalf of the hardware.
+	response.timestamp = cycle_time_to_ohci_tstamp(get_cycle_time(ohci));
 	fw_core_handle_response(&ohci->card, &response);
 }
 
@@ -1670,8 +1676,6 @@
 	}
 }
 
-static u32 get_cycle_time(struct fw_ohci *ohci);
-
 static void at_context_transmit(struct context *ctx, struct fw_packet *packet)
 {
 	unsigned long flags;
@@ -2060,6 +2064,8 @@
 
 	ohci->generation = generation;
 	reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
+	if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS)
+		reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset);
 
 	if (ohci->quirks & QUIRK_RESET_PACKET)
 		ohci->request_generation = generation;
@@ -2125,12 +2131,14 @@
 		return IRQ_NONE;
 
 	/*
-	 * busReset and postedWriteErr must not be cleared yet
+	 * busReset and postedWriteErr events must not be cleared yet
 	 * (OHCI 1.1 clauses 7.2.3.2 and 13.2.8.1)
 	 */
 	reg_write(ohci, OHCI1394_IntEventClear,
 		  event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr));
 	log_irqs(ohci, event);
+	if (event & OHCI1394_busReset)
+		reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset);
 
 	if (event & OHCI1394_selfIDComplete)
 		queue_work(selfid_workqueue, &ohci->bus_reset_work);
--- linux-qcom-6.8.0.orig/drivers/firmware/Kconfig
+++ linux-qcom-6.8.0/drivers/firmware/Kconfig
@@ -106,7 +106,7 @@
 	select ISCSI_BOOT_SYSFS
 	select ISCSI_IBFT_FIND if X86
 	depends on ACPI && SCSI && SCSI_LOWLEVEL
-	default	n
+	default n
 	help
 	  This option enables support for detection and exposing of iSCSI
 	  Boot Firmware Table (iBFT) via sysfs to userspace. If you wish to
@@ -182,6 +182,7 @@
 config SYSFB
 	bool
 	select BOOT_VESA_SUPPORT
+	select SCREEN_INFO
 
 config SYSFB_SIMPLEFB
 	bool "Mark VGA/VBE/EFI FB as generic system framebuffer"
--- linux-qcom-6.8.0.orig/drivers/firmware/arm_ffa/driver.c
+++ linux-qcom-6.8.0/drivers/firmware/arm_ffa/driver.c
@@ -790,7 +790,7 @@
 
 			part_id = packed_id_list[ids_processed++];
 
-			if (!ids_count[list]) { /* Global Notification */
+			if (ids_count[list] == 1) { /* Global Notification */
 				__do_sched_recv_cb(part_id, 0, false);
 				continue;
 			}
--- linux-qcom-6.8.0.orig/drivers/firmware/arm_scmi/bus.c
+++ linux-qcom-6.8.0/drivers/firmware/arm_scmi/bus.c
@@ -305,7 +305,10 @@
 
 static void scmi_device_release(struct device *dev)
 {
-	kfree(to_scmi_dev(dev));
+	struct scmi_device *scmi_dev = to_scmi_dev(dev);
+
+	kfree_const(scmi_dev->name);
+	kfree(scmi_dev);
 }
 
 static void __scmi_device_destroy(struct scmi_device *scmi_dev)
@@ -318,7 +321,6 @@
 	if (scmi_dev->protocol_id == SCMI_PROTOCOL_SYSTEM)
 		atomic_set(&scmi_syspower_registered, 0);
 
-	kfree_const(scmi_dev->name);
 	ida_free(&scmi_bus_id, scmi_dev->id);
 	device_unregister(&scmi_dev->dev);
 }
@@ -390,7 +392,6 @@
 
 	return scmi_dev;
 put_dev:
-	kfree_const(scmi_dev->name);
 	put_device(&scmi_dev->dev);
 	ida_free(&scmi_bus_id, id);
 	return NULL;
--- linux-qcom-6.8.0.orig/drivers/firmware/arm_scmi/common.h
+++ linux-qcom-6.8.0/drivers/firmware/arm_scmi/common.h
@@ -163,6 +163,7 @@
  *      used to initialize this channel
  * @dev: Reference to device in the SCMI hierarchy corresponding to this
  *	 channel
+ * @is_p2a: A flag to identify a channel as P2A (RX)
  * @rx_timeout_ms: The configured RX timeout in milliseconds.
  * @handle: Pointer to SCMI entity handle
  * @no_completion_irq: Flag to indicate that this channel has no completion
@@ -174,6 +175,7 @@
 struct scmi_chan_info {
 	int id;
 	struct device *dev;
+	bool is_p2a;
 	unsigned int rx_timeout_ms;
 	struct scmi_handle *handle;
 	bool no_completion_irq;
@@ -291,6 +293,7 @@
 #endif
 #ifdef CONFIG_ARM_SCMI_TRANSPORT_SMC
 extern const struct scmi_desc scmi_smc_desc;
+extern const struct scmi_desc scmi_qcom_smc_desc;
 #endif
 #ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO
 extern const struct scmi_desc scmi_virtio_desc;
--- linux-qcom-6.8.0.orig/drivers/firmware/arm_scmi/driver.c
+++ linux-qcom-6.8.0/drivers/firmware/arm_scmi/driver.c
@@ -857,6 +857,11 @@
 static inline void scmi_clear_channel(struct scmi_info *info,
 				      struct scmi_chan_info *cinfo)
 {
+	if (!cinfo->is_p2a) {
+		dev_warn(cinfo->dev, "Invalid clear on A2P channel !\n");
+		return;
+	}
+
 	if (info->desc->ops->clear_channel)
 		info->desc->ops->clear_channel(cinfo);
 }
@@ -2333,6 +2338,7 @@
 	if (!cinfo)
 		return -ENOMEM;
 
+	cinfo->is_p2a = !tx;
 	cinfo->rx_timeout_ms = info->desc->max_rx_timeout_ms;
 
 	/* Create a unique name for this transport device */
@@ -2617,10 +2623,8 @@
 	dbg->top_dentry = top_dentry;
 
 	if (devm_add_action_or_reset(info->dev,
-				     scmi_debugfs_common_cleanup, dbg)) {
-		scmi_debugfs_common_cleanup(dbg);
+				     scmi_debugfs_common_cleanup, dbg))
 		return NULL;
-	}
 
 	return dbg;
 }
@@ -2927,7 +2931,7 @@
 #ifdef CONFIG_ARM_SCMI_TRANSPORT_SMC
 	{ .compatible = "arm,scmi-smc", .data = &scmi_smc_desc},
 	{ .compatible = "arm,scmi-smc-param", .data = &scmi_smc_desc},
-	{ .compatible = "qcom,scmi-smc", .data = &scmi_smc_desc},
+	{ .compatible = "qcom,scmi-smc", .data = &scmi_qcom_smc_desc},
 #endif
 #ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO
 	{ .compatible = "arm,scmi-virtio", .data = &scmi_virtio_desc},
--- linux-qcom-6.8.0.orig/drivers/firmware/arm_scmi/mailbox.c
+++ linux-qcom-6.8.0/drivers/firmware/arm_scmi/mailbox.c
@@ -23,6 +23,7 @@
  * @chan_receiver: Optional Receiver mailbox unidirectional channel
  * @cinfo: SCMI channel info
  * @shmem: Transmit/Receive shared memory area
+ * @chan_lock: Lock that prevents multiple xfers from being queued
  */
 struct scmi_mailbox {
 	struct mbox_client cl;
@@ -30,6 +31,7 @@
 	struct mbox_chan *chan_receiver;
 	struct scmi_chan_info *cinfo;
 	struct scmi_shared_mem __iomem *shmem;
+	struct mutex chan_lock;
 };
 
 #define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl)
@@ -228,6 +230,7 @@
 
 	cinfo->transport_info = smbox;
 	smbox->cinfo = cinfo;
+	mutex_init(&smbox->chan_lock);
 
 	return 0;
 }
@@ -255,13 +258,23 @@
 	struct scmi_mailbox *smbox = cinfo->transport_info;
 	int ret;
 
-	ret = mbox_send_message(smbox->chan, xfer);
+	/*
+	 * The mailbox layer has its own queue. However the mailbox queue
+	 * confuses the per message SCMI timeouts since the clock starts when
+	 * the message is submitted into the mailbox queue. So when multiple
+	 * messages are queued up the clock starts on all messages instead of
+	 * only the one inflight.
+	 */
+	mutex_lock(&smbox->chan_lock);
 
-	/* mbox_send_message returns non-negative value on success, so reset */
-	if (ret > 0)
-		ret = 0;
+	ret = mbox_send_message(smbox->chan, xfer);
+	/* mbox_send_message returns non-negative value on success */
+	if (ret < 0) {
+		mutex_unlock(&smbox->chan_lock);
+		return ret;
+	}
 
-	return ret;
+	return 0;
 }
 
 static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret,
@@ -269,13 +282,10 @@
 {
 	struct scmi_mailbox *smbox = cinfo->transport_info;
 
-	/*
-	 * NOTE: we might prefer not to need the mailbox ticker to manage the
-	 * transfer queueing since the protocol layer queues things by itself.
-	 * Unfortunately, we have to kick the mailbox framework after we have
-	 * received our message.
-	 */
 	mbox_client_txdone(smbox->chan, ret);
+
+	/* Release channel */
+	mutex_unlock(&smbox->chan_lock);
 }
 
 static void mailbox_fetch_response(struct scmi_chan_info *cinfo,
--- linux-qcom-6.8.0.orig/drivers/firmware/arm_scmi/optee.c
+++ linux-qcom-6.8.0/drivers/firmware/arm_scmi/optee.c
@@ -471,6 +471,13 @@
 	struct scmi_chan_info *cinfo = p;
 	struct scmi_optee_channel *channel = cinfo->transport_info;
 
+	/*
+	 * Different protocols might share the same chan info, so a previous
+	 * call might have already freed the structure.
+	 */
+	if (!channel)
+		return 0;
+
 	mutex_lock(&scmi_optee_private->mu);
 	list_del(&channel->link);
 	mutex_unlock(&scmi_optee_private->mu);
--- linux-qcom-6.8.0.orig/drivers/firmware/arm_scmi/raw_mode.c
+++ linux-qcom-6.8.0/drivers/firmware/arm_scmi/raw_mode.c
@@ -921,7 +921,7 @@
 	rd->raw = raw;
 	filp->private_data = rd;
 
-	return 0;
+	return nonseekable_open(inode, filp);
 }
 
 static int scmi_dbg_raw_mode_release(struct inode *inode, struct file *filp)
@@ -950,6 +950,7 @@
 	.open = scmi_dbg_raw_mode_open,
 	.release = scmi_dbg_raw_mode_release,
 	.write = scmi_dbg_raw_mode_reset_write,
+	.llseek = no_llseek,
 	.owner = THIS_MODULE,
 };
 
@@ -959,6 +960,7 @@
 	.read = scmi_dbg_raw_mode_message_read,
 	.write = scmi_dbg_raw_mode_message_write,
 	.poll = scmi_dbg_raw_mode_message_poll,
+	.llseek = no_llseek,
 	.owner = THIS_MODULE,
 };
 
@@ -975,6 +977,7 @@
 	.read = scmi_dbg_raw_mode_message_read,
 	.write = scmi_dbg_raw_mode_message_async_write,
 	.poll = scmi_dbg_raw_mode_message_poll,
+	.llseek = no_llseek,
 	.owner = THIS_MODULE,
 };
 
@@ -998,6 +1001,7 @@
 	.release = scmi_dbg_raw_mode_release,
 	.read = scmi_test_dbg_raw_mode_notif_read,
 	.poll = scmi_test_dbg_raw_mode_notif_poll,
+	.llseek = no_llseek,
 	.owner = THIS_MODULE,
 };
 
@@ -1021,6 +1025,7 @@
 	.release = scmi_dbg_raw_mode_release,
 	.read = scmi_test_dbg_raw_mode_errors_read,
 	.poll = scmi_test_dbg_raw_mode_errors_poll,
+	.llseek = no_llseek,
 	.owner = THIS_MODULE,
 };
 
--- linux-qcom-6.8.0.orig/drivers/firmware/arm_scmi/smc.c
+++ linux-qcom-6.8.0/drivers/firmware/arm_scmi/smc.c
@@ -214,6 +214,13 @@
 	struct scmi_chan_info *cinfo = p;
 	struct scmi_smc *scmi_info = cinfo->transport_info;
 
+	/*
+	 * Different protocols might share the same chan info, so a previous
+	 * smc_chan_free call might have already freed the structure.
+	 */
+	if (!scmi_info)
+		return 0;
+
 	/* Ignore any possible further reception on the IRQ path */
 	if (scmi_info->irq > 0)
 		free_irq(scmi_info->irq, scmi_info);
@@ -296,3 +303,12 @@
 	.sync_cmds_completed_on_ret = true,
 	.atomic_enabled = IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE),
 };
+
+const struct scmi_desc scmi_qcom_smc_desc = {
+	.ops = &scmi_smc_ops,
+	.max_rx_timeout_ms = 3000,
+	.max_msg = 10,
+	.max_msg_size = 256,
+	.sync_cmds_completed_on_ret = true,
+	.atomic_enabled = IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE),
+};
--- linux-qcom-6.8.0.orig/drivers/firmware/arm_scpi.c
+++ linux-qcom-6.8.0/drivers/firmware/arm_scpi.c
@@ -630,6 +630,9 @@
 	if (ret)
 		return ERR_PTR(ret);
 
+	if (!buf.opp_count)
+		return ERR_PTR(-ENOENT);
+
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
 		return ERR_PTR(-ENOMEM);
--- linux-qcom-6.8.0.orig/drivers/firmware/arm_sdei.c
+++ linux-qcom-6.8.0/drivers/firmware/arm_sdei.c
@@ -763,7 +763,7 @@
 	int err;
 
 	/* unregister private events */
-	cpuhp_remove_state(sdei_entry_point);
+	cpuhp_remove_state(sdei_hp_state);
 
 	err = sdei_unregister_shared();
 	if (err)
--- linux-qcom-6.8.0.orig/drivers/firmware/cirrus/cs_dsp.c
+++ linux-qcom-6.8.0/drivers/firmware/cirrus/cs_dsp.c
@@ -522,7 +522,7 @@
 {
 	cs_dsp_debugfs_clear(dsp);
 	debugfs_remove_recursive(dsp->debugfs_root);
-	dsp->debugfs_root = NULL;
+	dsp->debugfs_root = ERR_PTR(-ENODEV);
 }
 EXPORT_SYMBOL_NS_GPL(cs_dsp_cleanup_debugfs, FW_CS_DSP);
 #else
@@ -796,6 +796,9 @@
 
 	lockdep_assert_held(&ctl->dsp->pwr_lock);
 
+	if (ctl->flags && !(ctl->flags & WMFW_CTL_FLAG_WRITEABLE))
+		return -EPERM;
+
 	if (len + off * sizeof(u32) > ctl->len)
 		return -EINVAL;
 
@@ -1053,9 +1056,16 @@
 	int len;
 };
 
-static int cs_dsp_coeff_parse_string(int bytes, const u8 **pos, const u8 **str)
+static int cs_dsp_coeff_parse_string(int bytes, const u8 **pos, unsigned int avail,
+				     const u8 **str)
 {
-	int length;
+	int length, total_field_len;
+
+	/* String fields are at least one __le32 */
+	if (sizeof(__le32) > avail) {
+		*pos = NULL;
+		return 0;
+	}
 
 	switch (bytes) {
 	case 1:
@@ -1068,10 +1078,16 @@
 		return 0;
 	}
 
+	total_field_len = ((length + bytes) + 3) & ~0x03;
+	if ((unsigned int)total_field_len > avail) {
+		*pos = NULL;
+		return 0;
+	}
+
 	if (str)
 		*str = *pos + bytes;
 
-	*pos += ((length + bytes) + 3) & ~0x03;
+	*pos += total_field_len;
 
 	return length;
 }
@@ -1096,71 +1112,134 @@
 	return val;
 }
 
-static inline void cs_dsp_coeff_parse_alg(struct cs_dsp *dsp, const u8 **data,
-					  struct cs_dsp_coeff_parsed_alg *blk)
+static int cs_dsp_coeff_parse_alg(struct cs_dsp *dsp,
+				  const struct wmfw_region *region,
+				  struct cs_dsp_coeff_parsed_alg *blk)
 {
 	const struct wmfw_adsp_alg_data *raw;
+	unsigned int data_len = le32_to_cpu(region->len);
+	unsigned int pos;
+	const u8 *tmp;
+
+	raw = (const struct wmfw_adsp_alg_data *)region->data;
 
 	switch (dsp->fw_ver) {
 	case 0:
 	case 1:
-		raw = (const struct wmfw_adsp_alg_data *)*data;
-		*data = raw->data;
+		if (sizeof(*raw) > data_len)
+			return -EOVERFLOW;
 
 		blk->id = le32_to_cpu(raw->id);
 		blk->name = raw->name;
-		blk->name_len = strlen(raw->name);
+		blk->name_len = strnlen(raw->name, ARRAY_SIZE(raw->name));
 		blk->ncoeff = le32_to_cpu(raw->ncoeff);
+
+		pos = sizeof(*raw);
 		break;
 	default:
-		blk->id = cs_dsp_coeff_parse_int(sizeof(raw->id), data);
-		blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), data,
+		if (sizeof(raw->id) > data_len)
+			return -EOVERFLOW;
+
+		tmp = region->data;
+		blk->id = cs_dsp_coeff_parse_int(sizeof(raw->id), &tmp);
+		pos = tmp - region->data;
+
+		tmp = &region->data[pos];
+		blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), &tmp, data_len - pos,
 							  &blk->name);
-		cs_dsp_coeff_parse_string(sizeof(u16), data, NULL);
-		blk->ncoeff = cs_dsp_coeff_parse_int(sizeof(raw->ncoeff), data);
+		if (!tmp)
+			return -EOVERFLOW;
+
+		pos = tmp - region->data;
+		cs_dsp_coeff_parse_string(sizeof(u16), &tmp, data_len - pos, NULL);
+		if (!tmp)
+			return -EOVERFLOW;
+
+		pos = tmp - region->data;
+		if (sizeof(raw->ncoeff) > (data_len - pos))
+			return -EOVERFLOW;
+
+		blk->ncoeff = cs_dsp_coeff_parse_int(sizeof(raw->ncoeff), &tmp);
+		pos += sizeof(raw->ncoeff);
 		break;
 	}
 
+	if ((int)blk->ncoeff < 0)
+		return -EOVERFLOW;
+
 	cs_dsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id);
 	cs_dsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name);
 	cs_dsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff);
+
+	return pos;
 }
 
-static inline void cs_dsp_coeff_parse_coeff(struct cs_dsp *dsp, const u8 **data,
-					    struct cs_dsp_coeff_parsed_coeff *blk)
+static int cs_dsp_coeff_parse_coeff(struct cs_dsp *dsp,
+				    const struct wmfw_region *region,
+				    unsigned int pos,
+				    struct cs_dsp_coeff_parsed_coeff *blk)
 {
 	const struct wmfw_adsp_coeff_data *raw;
+	unsigned int data_len = le32_to_cpu(region->len);
+	unsigned int blk_len, blk_end_pos;
 	const u8 *tmp;
-	int length;
+
+	raw = (const struct wmfw_adsp_coeff_data *)&region->data[pos];
+	if (sizeof(raw->hdr) > (data_len - pos))
+		return -EOVERFLOW;
+
+	blk_len = le32_to_cpu(raw->hdr.size);
+	if (blk_len > S32_MAX)
+		return -EOVERFLOW;
+
+	if (blk_len > (data_len - pos - sizeof(raw->hdr)))
+		return -EOVERFLOW;
+
+	blk_end_pos = pos + sizeof(raw->hdr) + blk_len;
+
+	blk->offset = le16_to_cpu(raw->hdr.offset);
+	blk->mem_type = le16_to_cpu(raw->hdr.type);
 
 	switch (dsp->fw_ver) {
 	case 0:
 	case 1:
-		raw = (const struct wmfw_adsp_coeff_data *)*data;
-		*data = *data + sizeof(raw->hdr) + le32_to_cpu(raw->hdr.size);
+		if (sizeof(*raw) > (data_len - pos))
+			return -EOVERFLOW;
 
-		blk->offset = le16_to_cpu(raw->hdr.offset);
-		blk->mem_type = le16_to_cpu(raw->hdr.type);
 		blk->name = raw->name;
-		blk->name_len = strlen(raw->name);
+		blk->name_len = strnlen(raw->name, ARRAY_SIZE(raw->name));
 		blk->ctl_type = le16_to_cpu(raw->ctl_type);
 		blk->flags = le16_to_cpu(raw->flags);
 		blk->len = le32_to_cpu(raw->len);
 		break;
 	default:
-		tmp = *data;
-		blk->offset = cs_dsp_coeff_parse_int(sizeof(raw->hdr.offset), &tmp);
-		blk->mem_type = cs_dsp_coeff_parse_int(sizeof(raw->hdr.type), &tmp);
-		length = cs_dsp_coeff_parse_int(sizeof(raw->hdr.size), &tmp);
-		blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), &tmp,
+		pos += sizeof(raw->hdr);
+		tmp = &region->data[pos];
+		blk->name_len = cs_dsp_coeff_parse_string(sizeof(u8), &tmp, data_len - pos,
 							  &blk->name);
-		cs_dsp_coeff_parse_string(sizeof(u8), &tmp, NULL);
-		cs_dsp_coeff_parse_string(sizeof(u16), &tmp, NULL);
+		if (!tmp)
+			return -EOVERFLOW;
+
+		pos = tmp - region->data;
+		cs_dsp_coeff_parse_string(sizeof(u8), &tmp, data_len - pos, NULL);
+		if (!tmp)
+			return -EOVERFLOW;
+
+		pos = tmp - region->data;
+		cs_dsp_coeff_parse_string(sizeof(u16), &tmp, data_len - pos, NULL);
+		if (!tmp)
+			return -EOVERFLOW;
+
+		pos = tmp - region->data;
+		if (sizeof(raw->ctl_type) + sizeof(raw->flags) + sizeof(raw->len) >
+		    (data_len - pos))
+			return -EOVERFLOW;
+
 		blk->ctl_type = cs_dsp_coeff_parse_int(sizeof(raw->ctl_type), &tmp);
+		pos += sizeof(raw->ctl_type);
 		blk->flags = cs_dsp_coeff_parse_int(sizeof(raw->flags), &tmp);
+		pos += sizeof(raw->flags);
 		blk->len = cs_dsp_coeff_parse_int(sizeof(raw->len), &tmp);
-
-		*data = *data + sizeof(raw->hdr) + length;
 		break;
 	}
 
@@ -1170,6 +1249,8 @@
 	cs_dsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags);
 	cs_dsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type);
 	cs_dsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len);
+
+	return blk_end_pos;
 }
 
 static int cs_dsp_check_coeff_flags(struct cs_dsp *dsp,
@@ -1193,12 +1274,16 @@
 	struct cs_dsp_alg_region alg_region = {};
 	struct cs_dsp_coeff_parsed_alg alg_blk;
 	struct cs_dsp_coeff_parsed_coeff coeff_blk;
-	const u8 *data = region->data;
-	int i, ret;
+	int i, pos, ret;
+
+	pos = cs_dsp_coeff_parse_alg(dsp, region, &alg_blk);
+	if (pos < 0)
+		return pos;
 
-	cs_dsp_coeff_parse_alg(dsp, &data, &alg_blk);
 	for (i = 0; i < alg_blk.ncoeff; i++) {
-		cs_dsp_coeff_parse_coeff(dsp, &data, &coeff_blk);
+		pos = cs_dsp_coeff_parse_coeff(dsp, region, pos, &coeff_blk);
+		if (pos < 0)
+			return pos;
 
 		switch (coeff_blk.ctl_type) {
 		case WMFW_CTL_TYPE_BYTES:
@@ -1267,6 +1352,10 @@
 	const struct wmfw_adsp1_sizes *adsp1_sizes;
 
 	adsp1_sizes = (void *)&firmware->data[pos];
+	if (sizeof(*adsp1_sizes) > firmware->size - pos) {
+		cs_dsp_err(dsp, "%s: file truncated\n", file);
+		return 0;
+	}
 
 	cs_dsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file,
 		   le32_to_cpu(adsp1_sizes->dm), le32_to_cpu(adsp1_sizes->pm),
@@ -1283,6 +1372,10 @@
 	const struct wmfw_adsp2_sizes *adsp2_sizes;
 
 	adsp2_sizes = (void *)&firmware->data[pos];
+	if (sizeof(*adsp2_sizes) > firmware->size - pos) {
+		cs_dsp_err(dsp, "%s: file truncated\n", file);
+		return 0;
+	}
 
 	cs_dsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file,
 		   le32_to_cpu(adsp2_sizes->xm), le32_to_cpu(adsp2_sizes->ym),
@@ -1322,7 +1415,6 @@
 	struct regmap *regmap = dsp->regmap;
 	unsigned int pos = 0;
 	const struct wmfw_header *header;
-	const struct wmfw_adsp1_sizes *adsp1_sizes;
 	const struct wmfw_footer *footer;
 	const struct wmfw_region *region;
 	const struct cs_dsp_region *mem;
@@ -1338,10 +1430,8 @@
 
 	ret = -EINVAL;
 
-	pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer);
-	if (pos >= firmware->size) {
-		cs_dsp_err(dsp, "%s: file too short, %zu bytes\n",
-			   file, firmware->size);
+	if (sizeof(*header) >= firmware->size) {
+		ret = -EOVERFLOW;
 		goto out_fw;
 	}
 
@@ -1369,22 +1459,36 @@
 
 	pos = sizeof(*header);
 	pos = dsp->ops->parse_sizes(dsp, file, pos, firmware);
+	if ((pos == 0) || (sizeof(*footer) > firmware->size - pos)) {
+		ret = -EOVERFLOW;
+		goto out_fw;
+	}
 
 	footer = (void *)&firmware->data[pos];
 	pos += sizeof(*footer);
 
 	if (le32_to_cpu(header->len) != pos) {
-		cs_dsp_err(dsp, "%s: unexpected header length %d\n",
-			   file, le32_to_cpu(header->len));
+		ret = -EOVERFLOW;
 		goto out_fw;
 	}
 
 	cs_dsp_dbg(dsp, "%s: timestamp %llu\n", file,
 		   le64_to_cpu(footer->timestamp));
 
-	while (pos < firmware->size &&
-	       sizeof(*region) < firmware->size - pos) {
+	while (pos < firmware->size) {
+		/* Is there enough data for a complete block header? */
+		if (sizeof(*region) > firmware->size - pos) {
+			ret = -EOVERFLOW;
+			goto out_fw;
+		}
+
 		region = (void *)&(firmware->data[pos]);
+
+		if (le32_to_cpu(region->len) > firmware->size - pos - sizeof(*region)) {
+			ret = -EOVERFLOW;
+			goto out_fw;
+		}
+
 		region_name = "Unknown";
 		reg = 0;
 		text = NULL;
@@ -1441,16 +1545,6 @@
 			   regions, le32_to_cpu(region->len), offset,
 			   region_name);
 
-		if (le32_to_cpu(region->len) >
-		    firmware->size - pos - sizeof(*region)) {
-			cs_dsp_err(dsp,
-				   "%s.%d: %s region len %d bytes exceeds file length %zu\n",
-				   file, regions, region_name,
-				   le32_to_cpu(region->len), firmware->size);
-			ret = -EINVAL;
-			goto out_fw;
-		}
-
 		if (text) {
 			memcpy(text, region->data, le32_to_cpu(region->len));
 			cs_dsp_info(dsp, "%s: %s\n", file, text);
@@ -1501,6 +1595,9 @@
 	cs_dsp_buf_free(&buf_list);
 	kfree(text);
 
+	if (ret == -EOVERFLOW)
+		cs_dsp_err(dsp, "%s: file content overflows file data\n", file);
+
 	return ret;
 }
 
@@ -2068,10 +2165,20 @@
 	pos = le32_to_cpu(hdr->len);
 
 	blocks = 0;
-	while (pos < firmware->size &&
-	       sizeof(*blk) < firmware->size - pos) {
+	while (pos < firmware->size) {
+		/* Is there enough data for a complete block header? */
+		if (sizeof(*blk) > firmware->size - pos) {
+			ret = -EOVERFLOW;
+			goto out_fw;
+		}
+
 		blk = (void *)(&firmware->data[pos]);
 
+		if (le32_to_cpu(blk->len) > firmware->size - pos - sizeof(*blk)) {
+			ret = -EOVERFLOW;
+			goto out_fw;
+		}
+
 		type = le16_to_cpu(blk->type);
 		offset = le16_to_cpu(blk->offset);
 		version = le32_to_cpu(blk->ver) >> 8;
@@ -2168,17 +2275,6 @@
 		}
 
 		if (reg) {
-			if (le32_to_cpu(blk->len) >
-			    firmware->size - pos - sizeof(*blk)) {
-				cs_dsp_err(dsp,
-					   "%s.%d: %s region len %d bytes exceeds file length %zu\n",
-					   file, blocks, region_name,
-					   le32_to_cpu(blk->len),
-					   firmware->size);
-				ret = -EINVAL;
-				goto out_fw;
-			}
-
 			buf = cs_dsp_buf_alloc(blk->data,
 					       le32_to_cpu(blk->len),
 					       &buf_list);
@@ -2218,6 +2314,10 @@
 	regmap_async_complete(regmap);
 	cs_dsp_buf_free(&buf_list);
 	kfree(text);
+
+	if (ret == -EOVERFLOW)
+		cs_dsp_err(dsp, "%s: file content overflows file data\n", file);
+
 	return ret;
 }
 
@@ -2246,6 +2346,11 @@
 
 	mutex_init(&dsp->pwr_lock);
 
+#ifdef CONFIG_DEBUG_FS
+	/* Ensure this is invalid if client never provides a debugfs root */
+	dsp->debugfs_root = ERR_PTR(-ENODEV);
+#endif
+
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/firmware/dmi-id.c
+++ linux-qcom-6.8.0/drivers/firmware/dmi-id.c
@@ -169,9 +169,14 @@
 	return 0;
 }
 
+static void dmi_dev_release(struct device *dev)
+{
+	kfree(dev);
+}
+
 static struct class dmi_class = {
 	.name = "dmi",
-	.dev_release = (void(*)(struct device *)) kfree,
+	.dev_release = dmi_dev_release,
 	.dev_uevent = dmi_dev_uevent,
 };
 
--- linux-qcom-6.8.0.orig/drivers/firmware/dmi_scan.c
+++ linux-qcom-6.8.0/drivers/firmware/dmi_scan.c
@@ -102,6 +102,17 @@
 		const struct dmi_header *dm = (const struct dmi_header *)data;
 
 		/*
+		 * If a short entry is found (less than 4 bytes), not only it
+		 * is invalid, but we cannot reliably locate the next entry.
+		 */
+		if (dm->length < sizeof(struct dmi_header)) {
+			pr_warn(FW_BUG
+				"Corrupted DMI table, offset %zd (only %d entries processed)\n",
+				data - buf, i);
+			break;
+		}
+
+		/*
 		 *  We want to know the total length (formatted area and
 		 *  strings) before decoding to make sure we won't run off the
 		 *  table in dmi_decode or dmi_string
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/Kconfig
+++ linux-qcom-6.8.0/drivers/firmware/efi/Kconfig
@@ -76,10 +76,6 @@
 	bool "Enable the generic EFI decompressor"
 	depends on EFI_GENERIC_STUB && !ARM
 	select HAVE_KERNEL_GZIP
-	select HAVE_KERNEL_LZ4
-	select HAVE_KERNEL_LZMA
-	select HAVE_KERNEL_LZO
-	select HAVE_KERNEL_XZ
 	select HAVE_KERNEL_ZSTD
 	help
 	  Create the bootable image as an EFI application that carries the
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/Makefile
+++ linux-qcom-6.8.0/drivers/firmware/efi/Makefile
@@ -25,6 +25,7 @@
 obj-$(CONFIG_EFI_BOOTLOADER_CONTROL)	+= efibc.o
 obj-$(CONFIG_EFI_TEST)			+= test/
 obj-$(CONFIG_EFI_DEV_PATH_PARSER)	+= dev-path-parser.o
+obj-$(CONFIG_EFI)			+= secureboot.o
 obj-$(CONFIG_APPLE_PROPERTIES)		+= apple-properties.o
 obj-$(CONFIG_EFI_RCI2_TABLE)		+= rci2-table.o
 obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE)	+= embedded-firmware.o
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/efi-init.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/efi-init.c
@@ -19,6 +19,7 @@
 #include <linux/of_fdt.h>
 #include <linux/platform_device.h>
 #include <linux/screen_info.h>
+#include <linux/security.h>
 
 #include <asm/efi.h>
 
@@ -237,6 +238,13 @@
 		return;
 	}
 
+	efi_set_secure_boot(efi_get__secure_boot());
+
+#ifdef CONFIG_LOCK_DOWN_IN_SECURE_BOOT
+	if (efi_enabled(EFI_SECURE_BOOT))
+		security_lock_kernel_down("EFI Secure Boot mode", LOCKDOWN_INTEGRITY_MAX);
+#endif
+
 	reserve_regions();
 	/*
 	 * For memblock manipulation, the cap should come after the memblock_add().
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/efi.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/efi.c
@@ -33,6 +33,7 @@
 #include <linux/memblock.h>
 #include <linux/security.h>
 #include <linux/notifier.h>
+#include <linux/bsearch.h>
 
 #include <asm/early_ioremap.h>
 
@@ -203,6 +204,8 @@
 
 	name_size = sizeof(name);
 
+	if (!efi.get_next_variable)
+		return false;
 	status = efi.get_next_variable(&name_size, &name, &guid);
 	if (status == EFI_UNSUPPORTED)
 		return false;
@@ -597,7 +600,8 @@
 	{EFI_MEMORY_ATTRIBUTES_TABLE_GUID,	&efi_mem_attr_table,	"MEMATTR"	},
 	{LINUX_EFI_RANDOM_SEED_TABLE_GUID,	&efi_rng_seed,		"RNG"		},
 	{LINUX_EFI_TPM_EVENT_LOG_GUID,		&efi.tpm_log,		"TPMEventLog"	},
-	{LINUX_EFI_TPM_FINAL_LOG_GUID,		&efi.tpm_final_log,	"TPMFinalLog"	},
+	{EFI_TCG2_FINAL_EVENTS_TABLE_GUID,	&efi.tpm_final_log,	"TPMFinalLog"	},
+	{EFI_CC_FINAL_EVENTS_TABLE_GUID,	&efi.tpm_final_log,	"CCFinalLog"	},
 	{LINUX_EFI_MEMRESERVE_TABLE_GUID,	&mem_reserve,		"MEMRESERVE"	},
 	{LINUX_EFI_INITRD_MEDIA_GUID,		&initrd,		"INITRD"	},
 	{EFI_RT_PROPERTIES_TABLE_GUID,		&rt_prop,		"RTPROP"	},
@@ -990,40 +994,101 @@
 	return -EINVAL;
 }
 
+struct efi_error_code {
+	efi_status_t status;
+	int errno;
+	const char *description;
+};
+
+static const struct efi_error_code efi_error_codes[] = {
+	{ EFI_SUCCESS, 0, "Success"},
+#if 0
+	{ EFI_LOAD_ERROR, -EPICK_AN_ERRNO, "Load Error"},
+#endif
+	{ EFI_INVALID_PARAMETER, -EINVAL, "Invalid Parameter"},
+	{ EFI_UNSUPPORTED, -ENOSYS, "Unsupported"},
+	{ EFI_BAD_BUFFER_SIZE, -ENOSPC, "Bad Buffer Size"},
+	{ EFI_BUFFER_TOO_SMALL, -ENOSPC, "Buffer Too Small"},
+	{ EFI_NOT_READY, -EAGAIN, "Not Ready"},
+	{ EFI_DEVICE_ERROR, -EIO, "Device Error"},
+	{ EFI_WRITE_PROTECTED, -EROFS, "Write Protected"},
+	{ EFI_OUT_OF_RESOURCES, -ENOMEM, "Out of Resources"},
+#if 0
+	{ EFI_VOLUME_CORRUPTED, -EPICK_AN_ERRNO, "Volume Corrupt"},
+	{ EFI_VOLUME_FULL, -EPICK_AN_ERRNO, "Volume Full"},
+	{ EFI_NO_MEDIA, -EPICK_AN_ERRNO, "No Media"},
+	{ EFI_MEDIA_CHANGED, -EPICK_AN_ERRNO, "Media changed"},
+#endif
+	{ EFI_NOT_FOUND, -ENOENT, "Not Found"},
+#if 0
+	{ EFI_ACCESS_DENIED, -EPICK_AN_ERRNO, "Access Denied"},
+	{ EFI_NO_RESPONSE, -EPICK_AN_ERRNO, "No Response"},
+	{ EFI_NO_MAPPING, -EPICK_AN_ERRNO, "No mapping"},
+	{ EFI_TIMEOUT, -EPICK_AN_ERRNO, "Time out"},
+	{ EFI_NOT_STARTED, -EPICK_AN_ERRNO, "Not started"},
+	{ EFI_ALREADY_STARTED, -EPICK_AN_ERRNO, "Already started"},
+#endif
+	{ EFI_ABORTED, -EINTR, "Aborted"},
+#if 0
+	{ EFI_ICMP_ERROR, -EPICK_AN_ERRNO, "ICMP Error"},
+	{ EFI_TFTP_ERROR, -EPICK_AN_ERRNO, "TFTP Error"},
+	{ EFI_PROTOCOL_ERROR, -EPICK_AN_ERRNO, "Protocol Error"},
+	{ EFI_INCOMPATIBLE_VERSION, -EPICK_AN_ERRNO, "Incompatible Version"},
+#endif
+	{ EFI_SECURITY_VIOLATION, -EACCES, "Security Policy Violation"},
+#if 0
+	{ EFI_CRC_ERROR, -EPICK_AN_ERRNO, "CRC Error"},
+	{ EFI_END_OF_MEDIA, -EPICK_AN_ERRNO, "End of Media"},
+	{ EFI_END_OF_FILE, -EPICK_AN_ERRNO, "End of File"},
+	{ EFI_INVALID_LANGUAGE, -EPICK_AN_ERRNO, "Invalid Languages"},
+	{ EFI_COMPROMISED_DATA, -EPICK_AN_ERRNO, "Compromised Data"},
+
+	// warnings
+	{ EFI_WARN_UNKOWN_GLYPH, -EPICK_AN_ERRNO, "Warning Unknown Glyph"},
+	{ EFI_WARN_DELETE_FAILURE, -EPICK_AN_ERRNO, "Warning Delete Failure"},
+	{ EFI_WARN_WRITE_FAILURE, -EPICK_AN_ERRNO, "Warning Write Failure"},
+	{ EFI_WARN_BUFFER_TOO_SMALL, -EPICK_AN_ERRNO, "Warning Buffer Too Small"},
+#endif
+};
+
+static int
+efi_status_cmp_bsearch(const void *key, const void *item)
+{
+	u64 status = (u64)(uintptr_t)key;
+	struct efi_error_code *code = (struct efi_error_code *)item;
+
+	if (status < code->status)
+		return -1;
+	if (status > code->status)
+		return 1;
+	return 0;
+}
+
 int efi_status_to_err(efi_status_t status)
 {
-	int err;
+	struct efi_error_code *found;
+	size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code);
 
-	switch (status) {
-	case EFI_SUCCESS:
-		err = 0;
-		break;
-	case EFI_INVALID_PARAMETER:
-		err = -EINVAL;
-		break;
-	case EFI_OUT_OF_RESOURCES:
-		err = -ENOSPC;
-		break;
-	case EFI_DEVICE_ERROR:
-		err = -EIO;
-		break;
-	case EFI_WRITE_PROTECTED:
-		err = -EROFS;
-		break;
-	case EFI_SECURITY_VIOLATION:
-		err = -EACCES;
-		break;
-	case EFI_NOT_FOUND:
-		err = -ENOENT;
-		break;
-	case EFI_ABORTED:
-		err = -EINTR;
-		break;
-	default:
-		err = -EINVAL;
-	}
+	found = bsearch((void *)(uintptr_t)status, efi_error_codes,
+			sizeof(struct efi_error_code), num,
+			efi_status_cmp_bsearch);
+	if (!found)
+		return -EINVAL;
+	return found->errno;
+}
+
+const char *
+efi_status_to_str(efi_status_t status)
+{
+	struct efi_error_code *found;
+	size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code);
 
-	return err;
+	found = bsearch((void *)(uintptr_t)status, efi_error_codes,
+			sizeof(struct efi_error_code), num,
+			efi_status_cmp_bsearch);
+	if (!found)
+		return "Unknown error code";
+	return found->description;
 }
 EXPORT_SYMBOL_GPL(efi_status_to_err);
 
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/fdtparams.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/fdtparams.c
@@ -16,16 +16,24 @@
 	MMSIZE,
 	DCSIZE,
 	DCVERS,
+	SCBOOT,
 
 	PARAMCOUNT
 };
 
+static u32 __secure_boot __initdata = efi_secureboot_mode_unset;
+u32 __init efi_get__secure_boot(void)
+{
+	return __secure_boot;
+}
+
 static __initconst const char name[][22] = {
 	[SYSTAB] = "System Table         ",
 	[MMBASE] = "MemMap Address       ",
 	[MMSIZE] = "MemMap Size          ",
 	[DCSIZE] = "MemMap Desc. Size    ",
 	[DCVERS] = "MemMap Desc. Version ",
+	[SCBOOT] = "Secure Boot Enabled  ",
 };
 
 static __initconst const struct {
@@ -53,6 +61,7 @@
 			[MMSIZE] = "linux,uefi-mmap-size",
 			[DCSIZE] = "linux,uefi-mmap-desc-size",
 			[DCVERS] = "linux,uefi-mmap-desc-ver",
+			[SCBOOT] = "linux,uefi-secure-boot",
 		}
 	}
 };
@@ -95,6 +104,7 @@
 		[MMSIZE] = { &mm->size,		sizeof(mm->size) },
 		[DCSIZE] = { &mm->desc_size,	sizeof(mm->desc_size) },
 		[DCVERS] = { &mm->desc_version,	sizeof(mm->desc_version) },
+		[SCBOOT] = { &__secure_boot,	sizeof(__secure_boot) },
 	};
 
 	BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name));
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/libstub/Makefile
+++ linux-qcom-6.8.0/drivers/firmware/efi/libstub/Makefile
@@ -11,7 +11,7 @@
 
 cflags-$(CONFIG_X86_32)		:= -march=i386
 cflags-$(CONFIG_X86_64)		:= -mcmodel=small
-cflags-$(CONFIG_X86)		+= -m$(BITS) -D__KERNEL__ \
+cflags-$(CONFIG_X86)		+= -m$(BITS) -D__KERNEL__ -std=gnu11 \
 				   -fPIC -fno-strict-aliasing -mno-red-zone \
 				   -mno-mmx -mno-sse -fshort-wchar \
 				   -Wno-pointer-sign \
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/libstub/Makefile.zboot
+++ linux-qcom-6.8.0/drivers/firmware/efi/libstub/Makefile.zboot
@@ -12,22 +12,16 @@
 $(obj)/vmlinux.bin: $(obj)/$(EFI_ZBOOT_PAYLOAD) FORCE
 	$(call if_changed,copy_and_pad)
 
-comp-type-$(CONFIG_KERNEL_GZIP)		:= gzip
-comp-type-$(CONFIG_KERNEL_LZ4)		:= lz4
-comp-type-$(CONFIG_KERNEL_LZMA)		:= lzma
-comp-type-$(CONFIG_KERNEL_LZO)		:= lzo
-comp-type-$(CONFIG_KERNEL_XZ)		:= xzkern
-comp-type-$(CONFIG_KERNEL_ZSTD)		:= zstd22
-
 # in GZIP, the appended le32 carrying the uncompressed size is part of the
 # format, but in other cases, we just append it at the end for convenience,
 # causing the original tools to complain when checking image integrity.
-# So disregard it when calculating the payload size in the zimage header.
-zboot-method-y                         := $(comp-type-y)_with_size
-zboot-size-len-y                       := 4
+comp-type-y				:= gzip
+zboot-method-y				:= gzip
+zboot-size-len-y			:= 0
 
-zboot-method-$(CONFIG_KERNEL_GZIP)     := gzip
-zboot-size-len-$(CONFIG_KERNEL_GZIP)   := 0
+comp-type-$(CONFIG_KERNEL_ZSTD)		:= zstd
+zboot-method-$(CONFIG_KERNEL_ZSTD)	:= zstd22_with_size
+zboot-size-len-$(CONFIG_KERNEL_ZSTD)	:= 4
 
 $(obj)/vmlinuz: $(obj)/vmlinux.bin FORCE
 	$(call if_changed,$(zboot-method-y))
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -11,6 +11,7 @@
 
 #include <linux/efi.h>
 #include <linux/kernel.h>
+#include <linux/overflow.h>
 #include <asm/efi.h>
 #include <asm/setup.h>
 
@@ -24,6 +25,8 @@
 static bool efi_nosoftreserve;
 static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA);
 
+int efi_mem_encrypt;
+
 bool __pure __efi_soft_reserve_enabled(void)
 {
 	return !efi_nosoftreserve;
@@ -75,6 +78,12 @@
 			efi_noinitrd = true;
 		} else if (IS_ENABLED(CONFIG_X86_64) && !strcmp(param, "no5lvl")) {
 			efi_no5lvl = true;
+		} else if (IS_ENABLED(CONFIG_ARCH_HAS_MEM_ENCRYPT) &&
+			   !strcmp(param, "mem_encrypt") && val) {
+			if (parse_option_str(val, "on"))
+				efi_mem_encrypt = 1;
+			else if (parse_option_str(val, "off"))
+				efi_mem_encrypt = -1;
 		} else if (!strcmp(param, "efi") && val) {
 			efi_nochunk = parse_option_str(val, "nochunk");
 			efi_novamap |= parse_option_str(val, "novamap");
@@ -193,7 +202,7 @@
 	*load_options_size = load_option_unpacked.optional_data_size;
 }
 
-enum efistub_event {
+enum efistub_event_type {
 	EFISTUB_EVT_INITRD,
 	EFISTUB_EVT_LOAD_OPTIONS,
 	EFISTUB_EVT_COUNT,
@@ -219,54 +228,95 @@
 	},
 };
 
+static_assert(sizeof(efi_tcg2_event_t) == sizeof(efi_cc_event_t));
+
+union efistub_event {
+	efi_tcg2_event_t	tcg2_data;
+	efi_cc_event_t		cc_data;
+};
+
+struct efistub_measured_event {
+	union efistub_event	event_data;
+	TCG_PCClientTaggedEvent tagged_event __packed;
+};
+
 static efi_status_t efi_measure_tagged_event(unsigned long load_addr,
 					     unsigned long load_size,
-					     enum efistub_event event)
+					     enum efistub_event_type event)
 {
+	union {
+		efi_status_t
+		(__efiapi *hash_log_extend_event)(void *, u64, efi_physical_addr_t,
+						  u64, const union efistub_event *);
+		struct { u32 hash_log_extend_event; } mixed_mode;
+	} method;
+	struct efistub_measured_event *evt;
+	int size = struct_size(evt, tagged_event.tagged_event_data,
+			       events[event].event_data_len);
 	efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
 	efi_tcg2_protocol_t *tcg2 = NULL;
+	union efistub_event ev;
 	efi_status_t status;
+	void *protocol;
 
 	efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2);
 	if (tcg2) {
-		struct efi_measured_event {
-			efi_tcg2_event_t	event_data;
-			efi_tcg2_tagged_event_t tagged_event;
-			u8			tagged_event_data[];
-		} *evt;
-		int size = sizeof(*evt) + events[event].event_data_len;
-
-		status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size,
-				     (void **)&evt);
-		if (status != EFI_SUCCESS)
-			goto fail;
-
-		evt->event_data = (struct efi_tcg2_event){
+		ev.tcg2_data = (struct efi_tcg2_event){
 			.event_size			= size,
-			.event_header.header_size	= sizeof(evt->event_data.event_header),
+			.event_header.header_size	= sizeof(ev.tcg2_data.event_header),
 			.event_header.header_version	= EFI_TCG2_EVENT_HEADER_VERSION,
 			.event_header.pcr_index		= events[event].pcr_index,
 			.event_header.event_type	= EV_EVENT_TAG,
 		};
+		protocol = tcg2;
+		method.hash_log_extend_event =
+			(void *)efi_table_attr(tcg2, hash_log_extend_event);
+	} else {
+		efi_guid_t cc_guid = EFI_CC_MEASUREMENT_PROTOCOL_GUID;
+		efi_cc_protocol_t *cc = NULL;
+
+		efi_bs_call(locate_protocol, &cc_guid, NULL, (void **)&cc);
+		if (!cc)
+			return EFI_UNSUPPORTED;
 
-		evt->tagged_event = (struct efi_tcg2_tagged_event){
-			.tagged_event_id		= events[event].event_id,
-			.tagged_event_data_size		= events[event].event_data_len,
+		ev.cc_data = (struct efi_cc_event){
+			.event_size			= size,
+			.event_header.header_size	= sizeof(ev.cc_data.event_header),
+			.event_header.header_version	= EFI_CC_EVENT_HEADER_VERSION,
+			.event_header.event_type	= EV_EVENT_TAG,
 		};
 
-		memcpy(evt->tagged_event_data, events[event].event_data,
-		       events[event].event_data_len);
-
-		status = efi_call_proto(tcg2, hash_log_extend_event, 0,
-					load_addr, load_size, &evt->event_data);
-		efi_bs_call(free_pool, evt);
-
+		status = efi_call_proto(cc, map_pcr_to_mr_index,
+					events[event].pcr_index,
+					&ev.cc_data.event_header.mr_index);
 		if (status != EFI_SUCCESS)
 			goto fail;
-		return EFI_SUCCESS;
+
+		protocol = cc;
+		method.hash_log_extend_event =
+			(void *)efi_table_attr(cc, hash_log_extend_event);
 	}
 
-	return EFI_UNSUPPORTED;
+	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, size, (void **)&evt);
+	if (status != EFI_SUCCESS)
+		goto fail;
+
+	*evt = (struct efistub_measured_event) {
+		.event_data			     = ev,
+		.tagged_event.tagged_event_id	     = events[event].event_id,
+		.tagged_event.tagged_event_data_size = events[event].event_data_len,
+	};
+
+	memcpy(evt->tagged_event.tagged_event_data, events[event].event_data,
+	       events[event].event_data_len);
+
+	status = efi_fn_call(&method, hash_log_extend_event, protocol, 0,
+			     load_addr, load_size, &evt->event_data);
+	efi_bs_call(free_pool, evt);
+
+	if (status == EFI_SUCCESS)
+		return EFI_SUCCESS;
+
 fail:
 	efi_warn("Failed to measure data for event %d: 0x%lx\n", event, status);
 	return status;
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/libstub/efi-stub.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/libstub/efi-stub.c
@@ -129,7 +129,7 @@
 
 	if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) ||
 	    IS_ENABLED(CONFIG_CMDLINE_FORCE) ||
-	    cmdline_size == 0) {
+	    cmdline[0] == 0) {
 		status = efi_parse_options(CONFIG_CMDLINE);
 		if (status != EFI_SUCCESS) {
 			efi_err("Failed to parse options\n");
@@ -149,7 +149,7 @@
 	return EFI_SUCCESS;
 
 fail_free_cmdline:
-	efi_bs_call(free_pool, cmdline_ptr);
+	efi_bs_call(free_pool, cmdline);
 	return status;
 }
 
@@ -167,7 +167,7 @@
 
 	si = setup_graphics();
 
-	efi_retrieve_tpm2_eventlog();
+	efi_retrieve_eventlog();
 
 	/* Ask the firmware to clear memory on unclean shutdown */
 	efi_enable_reset_attack_mitigation();
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/libstub/efistub.h
+++ linux-qcom-6.8.0/drivers/firmware/efi/libstub/efistub.h
@@ -37,8 +37,8 @@
 extern bool efi_nochunk;
 extern bool efi_nokaslr;
 extern int efi_loglevel;
+extern int efi_mem_encrypt;
 extern bool efi_novamap;
-
 extern const efi_system_table_t *efi_system_table;
 
 typedef union efi_dxe_services_table efi_dxe_services_table_t;
@@ -171,7 +171,7 @@
  * the EFI memory map. Other related structures, e.g. x86 e820ext, need
  * to factor in this headroom requirement as well.
  */
-#define EFI_MMAP_NR_SLACK_SLOTS	8
+#define EFI_MMAP_NR_SLACK_SLOTS	16
 
 typedef struct efi_generic_dev_path efi_device_path_protocol_t;
 
@@ -843,14 +843,14 @@
 	/* u8[] event follows here */
 } __packed;
 
-struct efi_tcg2_tagged_event {
-	u32 tagged_event_id;
-	u32 tagged_event_data_size;
-	/* u8  tagged event data follows here */
-} __packed;
+/* from TCG PC Client Platform Firmware Profile Specification */
+typedef struct tdTCG_PCClientTaggedEvent {
+	u32	tagged_event_id;
+	u32	tagged_event_data_size;
+	u8	tagged_event_data[];
+} TCG_PCClientTaggedEvent;
 
 typedef struct efi_tcg2_event efi_tcg2_event_t;
-typedef struct efi_tcg2_tagged_event efi_tcg2_tagged_event_t;
 typedef union efi_tcg2_protocol efi_tcg2_protocol_t;
 
 union efi_tcg2_protocol {
@@ -882,6 +882,87 @@
 	} mixed_mode;
 };
 
+typedef struct {
+	u8 major;
+	u8 minor;
+} efi_cc_version_t;
+
+typedef struct {
+	u8 type;
+	u8 sub_type;
+} efi_cc_type_t;
+
+/* EFI CC type/subtype defines */
+#define EFI_CC_TYPE_NONE		0
+#define EFI_CC_TYPE_AMD_SEV		1
+#define EFI_CC_TYPE_INTEL_TDX		2
+
+typedef u32 efi_cc_mr_index_t;
+
+struct efi_cc_event {
+	u32 event_size;
+	struct {
+		u32 header_size;
+		u16 header_version;
+		u32 mr_index;
+		u32 event_type;
+	} __packed event_header;
+	/* u8[] event follows here */
+} __packed;
+
+typedef struct efi_cc_event efi_cc_event_t;
+
+typedef u32 efi_cc_event_log_bitmap_t;
+typedef u32 efi_cc_event_log_format_t;
+typedef u32 efi_cc_event_algorithm_bitmap_t;
+
+typedef struct {
+	u8				size;
+	efi_cc_version_t		structure_version;
+	efi_cc_version_t		protocol_version;
+	efi_cc_event_algorithm_bitmap_t	hash_algorithm_bitmap;
+	efi_cc_event_log_bitmap_t	supported_event_logs;
+	efi_cc_type_t			cc_type;
+} efi_cc_boot_service_cap_t;
+
+#define EFI_CC_EVENT_HEADER_VERSION	1
+
+#define EFI_CC_BOOT_HASH_ALG_SHA384	0x00000004
+
+#define EFI_CC_EVENT_LOG_FORMAT_TCG_2	0x00000002
+
+typedef union efi_cc_protocol efi_cc_protocol_t;
+
+union efi_cc_protocol {
+	struct {
+		efi_status_t
+		(__efiapi *get_capability)(efi_cc_protocol_t *,
+					   efi_cc_boot_service_cap_t *);
+
+		efi_status_t
+		(__efiapi *get_event_log)(efi_cc_protocol_t *,
+					  efi_cc_event_log_format_t,
+					  efi_physical_addr_t *,
+					  efi_physical_addr_t *,
+					  efi_bool_t *);
+
+		efi_status_t
+		(__efiapi *hash_log_extend_event)(efi_cc_protocol_t *, u64,
+						  efi_physical_addr_t, u64,
+						  const efi_cc_event_t *);
+
+		efi_status_t
+		(__efiapi *map_pcr_to_mr_index)(efi_cc_protocol_t *, u32,
+						efi_cc_mr_index_t *);
+	};
+	struct {
+		u32 get_capability;
+		u32 get_event_log;
+		u32 hash_log_extend_event;
+		u32 map_pcr_to_mr_index;
+	} mixed_mode;
+};
+
 struct riscv_efi_boot_protocol {
 	u64 revision;
 
@@ -1061,7 +1142,7 @@
 efi_enable_reset_attack_mitigation(void) { }
 #endif
 
-void efi_retrieve_tpm2_eventlog(void);
+void efi_retrieve_eventlog(void);
 
 struct screen_info *alloc_screen_info(void);
 struct screen_info *__alloc_screen_info(void);
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/libstub/fdt.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/libstub/fdt.c
@@ -132,6 +132,12 @@
 		}
 	}
 
+	fdt_val32 = cpu_to_fdt32(efi_get_secureboot());
+	status = fdt_setprop(fdt, node, "linux,uefi-secure-boot",
+			     &fdt_val32, sizeof(fdt_val32));
+	if (status)
+		goto fdt_set_fail;
+
 	/* Shrink the FDT back to its minimum size: */
 	fdt_pack(fdt);
 
@@ -335,8 +341,8 @@
 
 fail:
 	efi_free(fdt_size, fdt_addr);
-
-	efi_bs_call(free_pool, priv.runtime_map);
+	if (!efi_novamap)
+		efi_bs_call(free_pool, priv.runtime_map);
 
 	return EFI_LOAD_ERROR;
 }
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/libstub/loongarch.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/libstub/loongarch.c
@@ -41,7 +41,7 @@
 unsigned long __weak kernel_entry_address(unsigned long kernel_addr,
 		efi_loaded_image_t *image)
 {
-	return *(unsigned long *)(kernel_addr + 8) - VMLINUX_LOAD_ADDRESS + kernel_addr;
+	return *(unsigned long *)(kernel_addr + 8) - PHYSADDR(VMLINUX_LOAD_ADDRESS) + kernel_addr;
 }
 
 efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/libstub/randomalloc.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/libstub/randomalloc.c
@@ -120,7 +120,7 @@
 			continue;
 		}
 
-		target = round_up(md->phys_addr, align) + target_slot * align;
+		target = round_up(max_t(u64, md->phys_addr, alloc_min), align) + target_slot * align;
 		pages = size / EFI_PAGE_SIZE;
 
 		status = efi_bs_call(allocate_pages, EFI_ALLOCATE_ADDRESS,
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/libstub/screen_info.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/libstub/screen_info.c
@@ -32,6 +32,8 @@
 	if (status != EFI_SUCCESS)
 		return NULL;
 
+	memset(si, 0, sizeof(*si));
+
 	status = efi_bs_call(install_configuration_table,
 			     &screen_info_guid, si);
 	if (status == EFI_SUCCESS)
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/libstub/tpm.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/libstub/tpm.c
@@ -47,39 +47,18 @@
 
 #endif
 
-void efi_retrieve_tpm2_eventlog(void)
+static void efi_retrieve_tcg2_eventlog(int version, efi_physical_addr_t log_location,
+				       efi_physical_addr_t log_last_entry,
+				       efi_bool_t truncated,
+				       struct efi_tcg2_final_events_table *final_events_table)
 {
-	efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
 	efi_guid_t linux_eventlog_guid = LINUX_EFI_TPM_EVENT_LOG_GUID;
 	efi_status_t status;
-	efi_physical_addr_t log_location = 0, log_last_entry = 0;
 	struct linux_efi_tpm_eventlog *log_tbl = NULL;
-	struct efi_tcg2_final_events_table *final_events_table = NULL;
 	unsigned long first_entry_addr, last_entry_addr;
 	size_t log_size, last_entry_size;
-	efi_bool_t truncated;
-	int version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
-	efi_tcg2_protocol_t *tcg2_protocol = NULL;
 	int final_events_size = 0;
 
-	status = efi_bs_call(locate_protocol, &tcg2_guid, NULL,
-			     (void **)&tcg2_protocol);
-	if (status != EFI_SUCCESS)
-		return;
-
-	status = efi_call_proto(tcg2_protocol, get_event_log, version,
-				&log_location, &log_last_entry, &truncated);
-
-	if (status != EFI_SUCCESS || !log_location) {
-		version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
-		status = efi_call_proto(tcg2_protocol, get_event_log, version,
-					&log_location, &log_last_entry,
-					&truncated);
-		if (status != EFI_SUCCESS || !log_location)
-			return;
-
-	}
-
 	first_entry_addr = (unsigned long) log_location;
 
 	/*
@@ -93,8 +72,10 @@
 		 * get_event_log only returns the address of the last entry.
 		 * We need to calculate its size to deduce the full size of
 		 * the logs.
+		 *
+		 * CC Event log also uses TCG2 format, handle it same as TPM2.
 		 */
-		if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {
+		if (version > EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) {
 			/*
 			 * The TCG2 log format has variable length entries,
 			 * and the information to decode the hash algorithms
@@ -115,7 +96,7 @@
 	}
 
 	/* Allocate space for the logs and copy them. */
-	status = efi_bs_call(allocate_pool, EFI_LOADER_DATA,
+	status = efi_bs_call(allocate_pool, EFI_ACPI_RECLAIM_MEMORY,
 			     sizeof(*log_tbl) + log_size, (void **)&log_tbl);
 
 	if (status != EFI_SUCCESS) {
@@ -127,8 +108,6 @@
 	 * Figure out whether any events have already been logged to the
 	 * final events structure, and if so how much space they take up
 	 */
-	if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
-		final_events_table = get_efi_config_table(LINUX_EFI_TPM_FINAL_LOG_GUID);
 	if (final_events_table && final_events_table->nr_events) {
 		struct tcg_pcr_event2_head *header;
 		int offset;
@@ -165,3 +144,50 @@
 err_free:
 	efi_bs_call(free_pool, log_tbl);
 }
+
+void efi_retrieve_eventlog(void)
+{
+	struct efi_tcg2_final_events_table *final_events_table = NULL;
+	efi_physical_addr_t log_location = 0, log_last_entry = 0;
+	efi_guid_t tpm2_guid = EFI_TCG2_PROTOCOL_GUID;
+	int version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
+	efi_tcg2_protocol_t *tpm2 = NULL;
+	efi_bool_t truncated;
+	efi_status_t status;
+
+	status = efi_bs_call(locate_protocol, &tpm2_guid, NULL, (void **)&tpm2);
+	if (status == EFI_SUCCESS) {
+		status = efi_call_proto(tpm2, get_event_log, version, &log_location,
+					&log_last_entry, &truncated);
+
+		if (status != EFI_SUCCESS || !log_location) {
+			version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
+			status = efi_call_proto(tpm2, get_event_log, version,
+						&log_location, &log_last_entry,
+						&truncated);
+		} else {
+			final_events_table =
+				get_efi_config_table(EFI_TCG2_FINAL_EVENTS_TABLE_GUID);
+		}
+	} else {
+		efi_guid_t cc_guid = EFI_CC_MEASUREMENT_PROTOCOL_GUID;
+		efi_cc_protocol_t *cc = NULL;
+
+		status = efi_bs_call(locate_protocol, &cc_guid, NULL, (void **)&cc);
+		if (status != EFI_SUCCESS)
+			return;
+
+		version = EFI_CC_EVENT_LOG_FORMAT_TCG_2;
+		status = efi_call_proto(cc, get_event_log, version, &log_location,
+					&log_last_entry, &truncated);
+
+		final_events_table =
+			get_efi_config_table(EFI_CC_FINAL_EVENTS_TABLE_GUID);
+	}
+
+	if (status != EFI_SUCCESS || !log_location)
+		return;
+
+	efi_retrieve_tcg2_eventlog(version, log_location, log_last_entry,
+				   truncated, final_events_table);
+}
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/libstub/x86-stub.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/libstub/x86-stub.c
@@ -21,6 +21,8 @@
 #include "efistub.h"
 #include "x86-stub.h"
 
+extern char _bss[], _ebss[];
+
 const efi_system_table_t *efi_system_table;
 const efi_dxe_services_table_t *efi_dxe_table;
 static efi_loaded_image_t *image = NULL;
@@ -236,6 +238,15 @@
 	rounded_end = roundup(start + size, EFI_PAGE_SIZE);
 
 	if (memattr != NULL) {
+		status = efi_call_proto(memattr, set_memory_attributes,
+					rounded_start,
+					rounded_end - rounded_start,
+					EFI_MEMORY_RO);
+		if (status != EFI_SUCCESS) {
+			efi_warn("Failed to set EFI_MEMORY_RO attribute\n");
+			return status;
+		}
+
 		status = efi_call_proto(memattr, clear_memory_attributes,
 					rounded_start,
 					rounded_end - rounded_start,
@@ -458,13 +469,17 @@
 efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
 				   efi_system_table_t *sys_table_arg)
 {
-	static struct boot_params boot_params __page_aligned_bss;
-	struct setup_header *hdr = &boot_params.hdr;
 	efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
+	struct boot_params *boot_params;
+	struct setup_header *hdr;
 	int options_size = 0;
 	efi_status_t status;
+	unsigned long alloc;
 	char *cmdline_ptr;
 
+	if (efi_is_native())
+		memset(_bss, 0, _ebss - _bss);
+
 	efi_system_table = sys_table_arg;
 
 	/* Check if we were booted by the EFI firmware */
@@ -477,25 +492,32 @@
 		efi_exit(handle, status);
 	}
 
+	status = efi_allocate_pages(PARAM_SIZE, &alloc, ULONG_MAX);
+	if (status != EFI_SUCCESS)
+		efi_exit(handle, status);
+
+	boot_params = memset((void *)alloc, 0x0, PARAM_SIZE);
+	hdr	    = &boot_params->hdr;
+
 	/* Assign the setup_header fields that the kernel actually cares about */
 	hdr->root_flags	= 1;
 	hdr->vid_mode	= 0xffff;
 
 	hdr->type_of_loader = 0x21;
+	hdr->initrd_addr_max = INT_MAX;
 
 	/* Convert unicode cmdline to ascii */
 	cmdline_ptr = efi_convert_cmdline(image, &options_size);
-	if (!cmdline_ptr)
-		goto fail;
+	if (!cmdline_ptr) {
+		efi_free(PARAM_SIZE, alloc);
+		efi_exit(handle, EFI_OUT_OF_RESOURCES);
+	}
 
 	efi_set_u64_split((unsigned long)cmdline_ptr, &hdr->cmd_line_ptr,
-			  &boot_params.ext_cmd_line_ptr);
+			  &boot_params->ext_cmd_line_ptr);
 
-	efi_stub_entry(handle, sys_table_arg, &boot_params);
+	efi_stub_entry(handle, sys_table_arg, boot_params);
 	/* not reached */
-
-fail:
-	efi_exit(handle, status);
 }
 
 static void add_e820ext(struct boot_params *params,
@@ -761,6 +783,26 @@
 	efi_warn("Decompression failed: %s\n", str);
 }
 
+static const char *cmdline_memmap_override;
+
+static efi_status_t parse_options(const char *cmdline)
+{
+	static const char opts[][14] = {
+		"mem=", "memmap=", "efi_fake_mem=", "hugepages="
+	};
+
+	for (int i = 0; i < ARRAY_SIZE(opts); i++) {
+		const char *p = strstr(cmdline, opts[i]);
+
+		if (p == cmdline || (p > cmdline && isspace(p[-1]))) {
+			cmdline_memmap_override = opts[i];
+			break;
+		}
+	}
+
+	return efi_parse_options(cmdline);
+}
+
 static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry)
 {
 	unsigned long virt_addr = LOAD_PHYSICAL_ADDR;
@@ -792,6 +834,10 @@
 		    !memcmp(efistub_fw_vendor(), ami, sizeof(ami))) {
 			efi_debug("AMI firmware v2.0 or older detected - disabling physical KASLR\n");
 			seed[0] = 0;
+		} else if (cmdline_memmap_override) {
+			efi_info("%s detected on the kernel command line - disabling physical KASLR\n",
+				 cmdline_memmap_override);
+			seed[0] = 0;
 		}
 
 		boot_params_ptr->hdr.loadflags |= KASLR_FLAG;
@@ -812,7 +858,7 @@
 
 	*kernel_entry = addr + entry;
 
-	return efi_adjust_memory_range_protection(addr, kernel_total_size);
+	return efi_adjust_memory_range_protection(addr, kernel_text_size);
 }
 
 static void __noreturn enter_kernel(unsigned long kernel_addr,
@@ -868,7 +914,7 @@
 	}
 
 #ifdef CONFIG_CMDLINE_BOOL
-	status = efi_parse_options(CONFIG_CMDLINE);
+	status = parse_options(CONFIG_CMDLINE);
 	if (status != EFI_SUCCESS) {
 		efi_err("Failed to parse options\n");
 		goto fail;
@@ -877,13 +923,16 @@
 	if (!IS_ENABLED(CONFIG_CMDLINE_OVERRIDE)) {
 		unsigned long cmdline_paddr = ((u64)hdr->cmd_line_ptr |
 					       ((u64)boot_params->ext_cmd_line_ptr << 32));
-		status = efi_parse_options((char *)cmdline_paddr);
+		status = parse_options((char *)cmdline_paddr);
 		if (status != EFI_SUCCESS) {
 			efi_err("Failed to parse options\n");
 			goto fail;
 		}
 	}
 
+	if (efi_mem_encrypt > 0)
+		hdr->xloadflags |= XLF_MEM_ENCRYPTION;
+
 	status = efi_decompress_kernel(&kernel_entry);
 	if (status != EFI_SUCCESS) {
 		efi_err("Failed to decompress kernel\n");
@@ -923,7 +972,7 @@
 
 	efi_random_get_seed();
 
-	efi_retrieve_tpm2_eventlog();
+	efi_retrieve_eventlog();
 
 	setup_graphics(boot_params);
 
@@ -958,8 +1007,6 @@
 void efi_handover_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg,
 			struct boot_params *boot_params)
 {
-	extern char _bss[], _ebss[];
-
 	memset(_bss, 0, _ebss - _bss);
 	efi_stub_entry(handle, sys_table_arg, boot_params);
 }
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/libstub/zboot.lds
+++ linux-qcom-6.8.0/drivers/firmware/efi/libstub/zboot.lds
@@ -41,6 +41,7 @@
 	}
 
 	/DISCARD/ : {
+		*(.discard .discard.*)
 		*(.modinfo .init.modinfo)
 	}
 }
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/memmap.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/memmap.c
@@ -15,10 +15,6 @@
 #include <asm/early_ioremap.h>
 #include <asm/efi.h>
 
-#ifndef __efi_memmap_free
-#define __efi_memmap_free(phys, size, flags) do { } while (0)
-#endif
-
 /**
  * __efi_memmap_init - Common code for mapping the EFI memory map
  * @data: EFI memory map data
@@ -51,11 +47,6 @@
 		return -ENOMEM;
 	}
 
-	if (efi.memmap.flags & (EFI_MEMMAP_MEMBLOCK | EFI_MEMMAP_SLAB))
-		__efi_memmap_free(efi.memmap.phys_map,
-				  efi.memmap.desc_size * efi.memmap.nr_map,
-				  efi.memmap.flags);
-
 	map.phys_map = data->phys_map;
 	map.nr_map = data->size / data->desc_size;
 	map.map_end = map.map + data->size;
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/secureboot.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/secureboot.c
@@ -0,0 +1,38 @@
+/* Core kernel secure boot support.
+ *
+ * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/efi.h>
+#include <linux/kernel.h>
+#include <linux/printk.h>
+
+/*
+ * Decide what to do when UEFI secure boot mode is enabled.
+ */
+void __init efi_set_secure_boot(enum efi_secureboot_mode mode)
+{
+	if (efi_enabled(EFI_BOOT)) {
+		switch (mode) {
+		case efi_secureboot_mode_disabled:
+			pr_info("Secure boot disabled\n");
+			break;
+		case efi_secureboot_mode_enabled:
+			set_bit(EFI_SECURE_BOOT, &efi.flags);
+			pr_info("Secure boot enabled\n");
+			break;
+		default:
+			pr_warn("Secure boot could not be determined (mode %u)\n",
+				   mode);
+			break;
+		}
+	}
+}
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/sysfb_efi.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/sysfb_efi.c
@@ -91,6 +91,7 @@
 		_ret_;						\
 	})
 
+#ifdef CONFIG_EFI
 static int __init efifb_set_system(const struct dmi_system_id *id)
 {
 	struct efifb_dmi_info *info = id->driver_data;
@@ -346,7 +347,6 @@
 	.add_links = efifb_add_links,
 };
 
-#ifdef CONFIG_EFI
 static struct fwnode_handle efifb_fwnode;
 
 __init void sysfb_apply_efi_quirks(void)
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/tpm.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/tpm.c
@@ -40,7 +40,8 @@
 {
 	struct linux_efi_tpm_eventlog *log_tbl;
 	struct efi_tcg2_final_events_table *final_tbl;
-	int tbl_size;
+	unsigned int tbl_size;
+	int final_tbl_size;
 	int ret = 0;
 
 	if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) {
@@ -80,26 +81,26 @@
 		goto out;
 	}
 
-	tbl_size = 0;
+	final_tbl_size = 0;
 	if (final_tbl->nr_events != 0) {
 		void *events = (void *)efi.tpm_final_log
 				+ sizeof(final_tbl->version)
 				+ sizeof(final_tbl->nr_events);
 
-		tbl_size = tpm2_calc_event_log_size(events,
-						    final_tbl->nr_events,
-						    log_tbl->log);
+		final_tbl_size = tpm2_calc_event_log_size(events,
+							  final_tbl->nr_events,
+							  log_tbl->log);
 	}
 
-	if (tbl_size < 0) {
+	if (final_tbl_size < 0) {
 		pr_err(FW_BUG "Failed to parse event in TPM Final Events Log\n");
 		ret = -EINVAL;
 		goto out_calc;
 	}
 
 	memblock_reserve(efi.tpm_final_log,
-			 tbl_size + sizeof(*final_tbl));
-	efi_tpm_final_log_size = tbl_size;
+			 final_tbl_size + sizeof(*final_tbl));
+	efi_tpm_final_log_size = final_tbl_size;
 
 out_calc:
 	early_memunmap(final_tbl, sizeof(*final_tbl));
--- linux-qcom-6.8.0.orig/drivers/firmware/efi/unaccepted_memory.c
+++ linux-qcom-6.8.0/drivers/firmware/efi/unaccepted_memory.c
@@ -4,6 +4,7 @@
 #include <linux/memblock.h>
 #include <linux/spinlock.h>
 #include <linux/crash_dump.h>
+#include <linux/nmi.h>
 #include <asm/unaccepted_memory.h>
 
 /* Protects unaccepted memory bitmap and accepting_list */
@@ -149,6 +150,9 @@
 	}
 
 	list_del(&range.list);
+
+	touch_softlockup_watchdog();
+
 	spin_unlock_irqrestore(&unaccepted_memory_lock, flags);
 }
 
--- linux-qcom-6.8.0.orig/drivers/firmware/google/gsmi.c
+++ linux-qcom-6.8.0/drivers/firmware/google/gsmi.c
@@ -918,7 +918,8 @@
 	gsmi_dev.pdev = platform_device_register_full(&gsmi_dev_info);
 	if (IS_ERR(gsmi_dev.pdev)) {
 		printk(KERN_ERR "gsmi: unable to register platform device\n");
-		return PTR_ERR(gsmi_dev.pdev);
+		ret = PTR_ERR(gsmi_dev.pdev);
+		goto out_unregister;
 	}
 
 	/* SMI access needs to be serialized */
@@ -1056,10 +1057,11 @@
 	gsmi_buf_free(gsmi_dev.name_buf);
 	kmem_cache_destroy(gsmi_dev.mem_pool);
 	platform_device_unregister(gsmi_dev.pdev);
-	pr_info("gsmi: failed to load: %d\n", ret);
+out_unregister:
 #ifdef CONFIG_PM
 	platform_driver_unregister(&gsmi_driver_info);
 #endif
+	pr_info("gsmi: failed to load: %d\n", ret);
 	return ret;
 }
 
--- linux-qcom-6.8.0.orig/drivers/firmware/iscsi_ibft.c
+++ linux-qcom-6.8.0/drivers/firmware/iscsi_ibft.c
@@ -310,7 +310,10 @@
 		str += sprintf_ipaddr(str, nic->ip_addr);
 		break;
 	case ISCSI_BOOT_ETH_SUBNET_MASK:
-		val = cpu_to_be32(~((1 << (32-nic->subnet_mask_prefix))-1));
+		if (nic->subnet_mask_prefix > 32)
+			val = cpu_to_be32(~0);
+		else
+			val = cpu_to_be32(~((1 << (32-nic->subnet_mask_prefix))-1));
 		str += sprintf(str, "%pI4", &val);
 		break;
 	case ISCSI_BOOT_ETH_PREFIX_LEN:
--- linux-qcom-6.8.0.orig/drivers/firmware/microchip/mpfs-auto-update.c
+++ linux-qcom-6.8.0/drivers/firmware/microchip/mpfs-auto-update.c
@@ -74,14 +74,11 @@
 #define AUTO_UPDATE_RESERVED_SIZE	SZ_1M
 #define AUTO_UPDATE_BITSTREAM_BASE	(AUTO_UPDATE_DIRECTORY_SIZE + AUTO_UPDATE_RESERVED_SIZE)
 
-#define AUTO_UPDATE_TIMEOUT_MS		60000
-
 struct mpfs_auto_update_priv {
 	struct mpfs_sys_controller *sys_controller;
 	struct device *dev;
 	struct mtd_info *flash;
 	struct fw_upload *fw_uploader;
-	struct completion programming_complete;
 	size_t size_per_bitstream;
 	bool cancel_request;
 };
@@ -143,19 +140,6 @@
 
 static enum fw_upload_err mpfs_auto_update_poll_complete(struct fw_upload *fw_uploader)
 {
-	struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;
-	int ret;
-
-	/*
-	 * There is no meaningful way to get the status of the programming while
-	 * it is in progress, so attempting anything other than waiting for it
-	 * to complete would be misplaced.
-	 */
-	ret = wait_for_completion_timeout(&priv->programming_complete,
-					  msecs_to_jiffies(AUTO_UPDATE_TIMEOUT_MS));
-	if (ret)
-		return FW_UPLOAD_ERR_TIMEOUT;
-
 	return FW_UPLOAD_ERR_NONE;
 }
 
@@ -206,10 +190,12 @@
 	if (ret | response->resp_status) {
 		dev_warn(priv->dev, "Verification of Upgrade Image failed!\n");
 		ret = ret ? ret : -EBADMSG;
+		goto free_message;
 	}
 
 	dev_info(priv->dev, "Verification of Upgrade Image passed!\n");
 
+free_message:
 	devm_kfree(priv->dev, message);
 free_response:
 	devm_kfree(priv->dev, response);
@@ -344,30 +330,20 @@
 						 u32 offset, u32 size, u32 *written)
 {
 	struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle;
-	enum fw_upload_err err = FW_UPLOAD_ERR_NONE;
 	int ret;
 
-	reinit_completion(&priv->programming_complete);
-
 	ret = mpfs_auto_update_write_bitstream(fw_uploader, data, offset, size, written);
-	if (ret) {
-		err = FW_UPLOAD_ERR_RW_ERROR;
-		goto out;
-	}
+	if (ret)
+		return FW_UPLOAD_ERR_RW_ERROR;
 
-	if (priv->cancel_request) {
-		err = FW_UPLOAD_ERR_CANCELED;
-		goto out;
-	}
+	if (priv->cancel_request)
+		return FW_UPLOAD_ERR_CANCELED;
 
 	ret = mpfs_auto_update_verify_image(fw_uploader);
 	if (ret)
-		err = FW_UPLOAD_ERR_FW_INVALID;
+		return FW_UPLOAD_ERR_FW_INVALID;
 
-out:
-	complete(&priv->programming_complete);
-
-	return err;
+	return FW_UPLOAD_ERR_NONE;
 }
 
 static const struct fw_upload_ops mpfs_auto_update_ops = {
@@ -461,8 +437,6 @@
 		return dev_err_probe(dev, ret,
 				     "The current bitstream does not support auto-update\n");
 
-	init_completion(&priv->programming_complete);
-
 	fw_uploader = firmware_upload_register(THIS_MODULE, dev, "mpfs-auto-update",
 					       &mpfs_auto_update_ops, priv);
 	if (IS_ERR(fw_uploader))
--- linux-qcom-6.8.0.orig/drivers/firmware/psci/psci.c
+++ linux-qcom-6.8.0/drivers/firmware/psci/psci.c
@@ -29,6 +29,8 @@
 #include <asm/smp_plat.h>
 #include <asm/suspend.h>
 
+#define REBOOT_PREFIX "mode-"
+
 /*
  * While a 64-bit OS can make calls with SMC32 calling conventions, for some
  * calls it is necessary to use SMC64 to pass or return 64-bit values.
@@ -79,6 +81,14 @@
 static u32 psci_cpu_suspend_feature;
 static bool psci_system_reset2_supported;
 
+struct psci_reset_param {
+	const char *mode;
+	u32 reset_type;
+	u32 cookie;
+};
+static struct psci_reset_param *psci_reset_params;
+static size_t num_psci_reset_params;
+
 static inline bool psci_has_ext_power_state(void)
 {
 	return psci_cpu_suspend_feature &
@@ -305,11 +315,29 @@
 	return 0;
 }
 
+static void psci_vendor_sys_reset2(unsigned long action, void *data)
+{
+	const char *cmd = data;
+	size_t i;
+
+	for (i = 0; i < num_psci_reset_params; i++) {
+		if (!strcmp(psci_reset_params[i].mode, cmd)) {
+			invoke_psci_fn(PSCI_FN_NATIVE(1_1, SYSTEM_RESET2),
+				       psci_reset_params[i].reset_type,
+				       psci_reset_params[i].cookie, 0);
+			break;
+		}
+	}
+}
+
 static int psci_sys_reset(struct notifier_block *nb, unsigned long action,
 			  void *data)
 {
+	if (data && psci_system_reset2_supported && num_psci_reset_params)
+		psci_vendor_sys_reset2(action, data);
+
 	if ((reboot_mode == REBOOT_WARM || reboot_mode == REBOOT_SOFT) &&
-	    psci_system_reset2_supported) {
+		 psci_system_reset2_supported) {
 		/*
 		 * reset_type[31] = 0 (architectural)
 		 * reset_type[30:0] = 0 (SYSTEM_WARM_RESET)
@@ -497,10 +525,12 @@
 
 static int psci_system_suspend(unsigned long unused)
 {
+	int err;
 	phys_addr_t pa_cpu_resume = __pa_symbol(cpu_resume);
 
-	return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND),
+	err = invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND),
 			      pa_cpu_resume, 0, 0);
+	return psci_to_linux_errno(err);
 }
 
 static int psci_system_suspend_enter(suspend_state_t state)
@@ -523,18 +553,26 @@
 		psci_system_reset2_supported = true;
 }
 
-static void __init psci_init_system_suspend(void)
+static int __init psci_init_system_suspend(void)
 {
 	int ret;
+	u32 ver;
 
 	if (!IS_ENABLED(CONFIG_SUSPEND))
-		return;
+		return 0;
+
+	ver = psci_0_2_get_version();
+	if (PSCI_VERSION_MAJOR(ver) < 1)
+		return 0;
 
 	ret = psci_features(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND));
 
 	if (ret != PSCI_RET_NOT_SUPPORTED)
 		suspend_set_ops(&psci_suspend_ops);
+
+	return ret;
 }
+late_initcall(psci_init_system_suspend)
 
 static void __init psci_init_cpu_suspend(void)
 {
@@ -651,7 +689,6 @@
 	if (PSCI_VERSION_MAJOR(ver) >= 1) {
 		psci_init_smccc();
 		psci_init_cpu_suspend();
-		psci_init_system_suspend();
 		psci_init_system_reset2();
 		kvm_init_hyp_services();
 	}
@@ -748,6 +785,63 @@
 	{},
 };
 
+static int __init psci_init_system_reset2_modes(void)
+{
+	const size_t len = strlen(REBOOT_PREFIX);
+	struct psci_reset_param *param;
+	struct device_node *np;
+	struct property *prop;
+	size_t count = 0;
+	u32 magic[2];
+	int ret;
+
+	if (!psci_system_reset2_supported)
+		return 0;
+
+	np = of_find_matching_node(NULL, psci_of_match);
+	if (!np)
+		return 0;
+
+	for_each_property_of_node(np, prop) {
+		if (strncmp(prop->name, REBOOT_PREFIX, len))
+			continue;
+		ret = of_property_count_elems_of_size(np, prop->name, sizeof(magic[0]));
+		if (ret != 1 && ret != 2)
+			continue;
+
+		count++;
+	}
+
+	param = psci_reset_params = kcalloc(count, sizeof(*psci_reset_params), GFP_KERNEL);
+	if (!psci_reset_params)
+		return -ENOMEM;
+
+	for_each_property_of_node(np, prop) {
+		if (strncmp(prop->name, REBOOT_PREFIX, len))
+			continue;
+
+		param->mode = kstrdup_const(prop->name + len, GFP_KERNEL);
+		if (!param->mode)
+			continue;
+
+		ret = of_property_read_variable_u32_array(np, prop->name, magic, 1, 2);
+		if (ret < 0) {
+			pr_warn("Failed to parse vendor reboot mode %s\n", param->mode);
+			kfree(param->mode);
+			continue;
+		}
+
+		/* Force reset type to be in vendor space */
+		param->reset_type = PSCI_1_1_RESET_TYPE_VENDOR_START | magic[0];
+		param->cookie = ret == 2 ? magic[1] : 0;
+		param++;
+		num_psci_reset_params++;
+	}
+
+	return 0;
+}
+arch_initcall(psci_init_system_reset2_modes);
+
 int __init psci_dt_init(void)
 {
 	struct device_node *np;
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/Kconfig
+++ linux-qcom-6.8.0/drivers/firmware/qcom/Kconfig
@@ -7,18 +7,46 @@
 menu "Qualcomm firmware drivers"
 
 config QCOM_SCM
+	select QCOM_TZMEM
 	tristate
 
-config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
-	bool "Qualcomm download mode enabled by default"
-	depends on QCOM_SCM
+config QCOM_TZMEM
+	tristate
+	select GENERIC_ALLOCATOR
+
+choice
+	prompt "TrustZone interface memory allocator mode"
+	depends on QCOM_TZMEM
+	default QCOM_TZMEM_MODE_GENERIC
+	help
+	  Selects the mode of the memory allocator providing memory buffers of
+	  suitable format for sharing with the TrustZone. If in doubt, select
+	  'Generic'.
+
+config QCOM_TZMEM_MODE_GENERIC
+	bool "Generic"
+	help
+	  Use the generic allocator mode. The memory is page-aligned, non-cachable
+	  and physically contiguous.
+
+config QCOM_TZMEM_MODE_SHMBRIDGE
+	bool "SHM Bridge"
 	help
-	  A device with "download mode" enabled will upon an unexpected
-	  warm-restart enter a special debug mode that allows the user to
-	  "download" memory content over USB for offline postmortem analysis.
-	  The feature can be enabled/disabled on the kernel command line.
+	  Use Qualcomm Shared Memory Bridge. The memory has the same alignment as
+	  in the 'Generic' allocator but is also explicitly marked as an SHM Bridge
+	  buffer.
 
-	  Say Y here to enable "download mode" by default.
+	  With this selected, all buffers passed to the TrustZone must be allocated
+	  using the TZMem allocator or else the TrustZone will refuse to use them.
+
+endchoice
+
+config QCOM_SCM_ADDON
+	bool "Qualcomm SCM Addon Support"
+	depends on QCOM_SCM
+	help
+	  QCOM SCM addon provision APIs for client like kgsl, SHMBridge, etc,
+	  once enable it provides extra API via QCOM_SCM.
 
 config QCOM_QSEECOM
 	bool "Qualcomm QSEECOM interface driver"
@@ -53,4 +81,14 @@
 	  Select Y here to provide access to EFI variables on the aforementioned
 	  platforms.
 
+config QTI_TZ_LOG
+	tristate "QTI Trust Zone (TZ) Log Driver"
+	depends on QCOM_TZMEM && PROC_FS && QCOM_SCM
+	help
+	  Provide debugging capability with a procfs interface for messages produced
+	  by the Secure code (Trust zone). These messages provide diagnostic information
+	  about TZ operations.
+
+source "drivers/firmware/qcom/si_core/Kconfig"
+
 endmenu
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/Makefile
+++ linux-qcom-6.8.0/drivers/firmware/qcom/Makefile
@@ -5,5 +5,8 @@
 
 obj-$(CONFIG_QCOM_SCM)		+= qcom-scm.o
 qcom-scm-objs += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
+obj-$(CONFIG_QCOM_TZMEM)	+= qcom_tzmem.o
 obj-$(CONFIG_QCOM_QSEECOM)	+= qcom_qseecom.o
 obj-$(CONFIG_QCOM_QSEECOM_UEFISECAPP) += qcom_qseecom_uefisecapp.o
+obj-$(CONFIG_QTI_TZ_LOG)	+= tz_log.o
+obj-$(CONFIG_QCOM_SI_CORE)	+= si_core/
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c
@@ -221,6 +221,19 @@
  * alignment of 8 bytes (64 bits) for GUIDs. Our definition of efi_guid_t,
  * however, has an alignment of 4 byte (32 bits). So far, this seems to work
  * fine here. See also the comment on the typedef of efi_guid_t.
+ *
+ * Note: It looks like uefisecapp is quite picky about how the memory passed to
+ * it is structured and aligned. In particular the request/response setup used
+ * for QSEE_CMD_UEFI_GET_VARIABLE. While qcom_qseecom_app_send(), in theory,
+ * accepts separate buffers/addresses for the request and response parts, in
+ * practice, however, it seems to expect them to be both part of a larger
+ * contiguous block. We initially allocated separate buffers for the request
+ * and response but this caused the QSEE_CMD_UEFI_GET_VARIABLE command to
+ * either not write any response to the response buffer or outright crash the
+ * device. Therefore, we now allocate a single contiguous block of DMA memory
+ * for both and properly align the data using the macros below. In particular,
+ * request and response structs are aligned at 8 byte (via __reqdata_offs()),
+ * following the driver that this has been reverse-engineered from.
  */
 #define qcuefi_buf_align_fields(fields...)					\
 	({									\
@@ -244,6 +257,12 @@
 #define __array_offs(type, count, offset)					\
 	__field_impl(sizeof(type) * (count), __alignof__(type), offset)
 
+#define __array_offs_aligned(type, count, align, offset)			\
+	__field_impl(sizeof(type) * (count), align, offset)
+
+#define __reqdata_offs(size, offset)						\
+	__array_offs_aligned(u8, size, 8, offset)
+
 #define __array(type, count)		__array_offs(type, count, NULL)
 #define __field_offs(type, offset)	__array_offs(type, 1, offset)
 #define __field(type)			__array_offs(type, 1, NULL)
@@ -277,10 +296,15 @@
 	unsigned long buffer_size = *data_size;
 	efi_status_t efi_status = EFI_SUCCESS;
 	unsigned long name_length;
+	dma_addr_t cmd_buf_dma;
+	size_t cmd_buf_size;
+	void *cmd_buf;
 	size_t guid_offs;
 	size_t name_offs;
 	size_t req_size;
 	size_t rsp_size;
+	size_t req_offs;
+	size_t rsp_offs;
 	ssize_t status;
 
 	if (!name || !guid)
@@ -304,17 +328,19 @@
 		__array(u8, buffer_size)
 	);
 
-	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
+	cmd_buf_size = qcuefi_buf_align_fields(
+		__reqdata_offs(req_size, &req_offs)
+		__reqdata_offs(rsp_size, &rsp_offs)
+	);
+
+	cmd_buf = qseecom_dma_alloc(qcuefi->client, cmd_buf_size, &cmd_buf_dma, GFP_KERNEL);
+	if (!cmd_buf) {
 		efi_status = EFI_OUT_OF_RESOURCES;
 		goto out;
 	}
 
-	rsp_data = kzalloc(rsp_size, GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	req_data = cmd_buf + req_offs;
+	rsp_data = cmd_buf + rsp_offs;
 
 	req_data->command_id = QSEE_CMD_UEFI_GET_VARIABLE;
 	req_data->data_size = buffer_size;
@@ -332,7 +358,9 @@
 
 	memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
 
-	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
+	status = qcom_qseecom_app_send(qcuefi->client,
+				       cmd_buf_dma + req_offs, req_size,
+				       cmd_buf_dma + rsp_offs, rsp_size);
 	if (status) {
 		efi_status = EFI_DEVICE_ERROR;
 		goto out_free;
@@ -407,9 +435,7 @@
 	memcpy(data, ((void *)rsp_data) + rsp_data->data_offset, rsp_data->data_size);
 
 out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
+	qseecom_dma_free(qcuefi->client, cmd_buf_size, cmd_buf, cmd_buf_dma);
 out:
 	return efi_status;
 }
@@ -422,10 +448,15 @@
 	struct qsee_rsp_uefi_set_variable *rsp_data;
 	efi_status_t efi_status = EFI_SUCCESS;
 	unsigned long name_length;
+	dma_addr_t cmd_buf_dma;
+	size_t cmd_buf_size;
+	void *cmd_buf;
 	size_t name_offs;
 	size_t guid_offs;
 	size_t data_offs;
 	size_t req_size;
+	size_t req_offs;
+	size_t rsp_offs;
 	ssize_t status;
 
 	if (!name || !guid)
@@ -450,17 +481,19 @@
 		__array_offs(u8, data_size, &data_offs)
 	);
 
-	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
+	cmd_buf_size = qcuefi_buf_align_fields(
+		__reqdata_offs(req_size, &req_offs)
+		__reqdata_offs(sizeof(*rsp_data), &rsp_offs)
+	);
+
+	cmd_buf = qseecom_dma_alloc(qcuefi->client, cmd_buf_size, &cmd_buf_dma, GFP_KERNEL);
+	if (!cmd_buf) {
 		efi_status = EFI_OUT_OF_RESOURCES;
 		goto out;
 	}
 
-	rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	req_data = cmd_buf + req_offs;
+	rsp_data = cmd_buf + rsp_offs;
 
 	req_data->command_id = QSEE_CMD_UEFI_SET_VARIABLE;
 	req_data->attributes = attributes;
@@ -483,8 +516,9 @@
 	if (data_size)
 		memcpy(((void *)req_data) + req_data->data_offset, data, req_data->data_size);
 
-	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data,
-				       sizeof(*rsp_data));
+	status = qcom_qseecom_app_send(qcuefi->client,
+				       cmd_buf_dma + req_offs, req_size,
+				       cmd_buf_dma + rsp_offs, sizeof(*rsp_data));
 	if (status) {
 		efi_status = EFI_DEVICE_ERROR;
 		goto out_free;
@@ -507,9 +541,7 @@
 	}
 
 out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
+	qseecom_dma_free(qcuefi->client, cmd_buf_size, cmd_buf, cmd_buf_dma);
 out:
 	return efi_status;
 }
@@ -521,10 +553,15 @@
 	struct qsee_req_uefi_get_next_variable *req_data;
 	struct qsee_rsp_uefi_get_next_variable *rsp_data;
 	efi_status_t efi_status = EFI_SUCCESS;
+	dma_addr_t cmd_buf_dma;
+	size_t cmd_buf_size;
+	void *cmd_buf;
 	size_t guid_offs;
 	size_t name_offs;
 	size_t req_size;
 	size_t rsp_size;
+	size_t req_offs;
+	size_t rsp_offs;
 	ssize_t status;
 
 	if (!name_size || !name || !guid)
@@ -545,17 +582,19 @@
 		__array(*name, *name_size / sizeof(*name))
 	);
 
-	req_data = kzalloc(req_size, GFP_KERNEL);
-	if (!req_data) {
+	cmd_buf_size = qcuefi_buf_align_fields(
+		__reqdata_offs(req_size, &req_offs)
+		__reqdata_offs(rsp_size, &rsp_offs)
+	);
+
+	cmd_buf = qseecom_dma_alloc(qcuefi->client, cmd_buf_size, &cmd_buf_dma, GFP_KERNEL);
+	if (!cmd_buf) {
 		efi_status = EFI_OUT_OF_RESOURCES;
 		goto out;
 	}
 
-	rsp_data = kzalloc(rsp_size, GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	req_data = cmd_buf + req_offs;
+	rsp_data = cmd_buf + rsp_offs;
 
 	req_data->command_id = QSEE_CMD_UEFI_GET_NEXT_VARIABLE;
 	req_data->guid_offset = guid_offs;
@@ -572,7 +611,9 @@
 		goto out_free;
 	}
 
-	status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size);
+	status = qcom_qseecom_app_send(qcuefi->client,
+				       cmd_buf_dma + req_offs, req_size,
+				       cmd_buf_dma + rsp_offs, rsp_size);
 	if (status) {
 		efi_status = EFI_DEVICE_ERROR;
 		goto out_free;
@@ -645,9 +686,7 @@
 	}
 
 out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
+	qseecom_dma_free(qcuefi->client, cmd_buf_size, cmd_buf, cmd_buf_dma);
 out:
 	return efi_status;
 }
@@ -659,26 +698,34 @@
 	struct qsee_req_uefi_query_variable_info *req_data;
 	struct qsee_rsp_uefi_query_variable_info *rsp_data;
 	efi_status_t efi_status = EFI_SUCCESS;
+	dma_addr_t cmd_buf_dma;
+	size_t cmd_buf_size;
+	void *cmd_buf;
+	size_t req_offs;
+	size_t rsp_offs;
 	int status;
 
-	req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
-	if (!req_data) {
+	cmd_buf_size = qcuefi_buf_align_fields(
+		__reqdata_offs(sizeof(*req_data), &req_offs)
+		__reqdata_offs(sizeof(*rsp_data), &rsp_offs)
+	);
+
+	cmd_buf = qseecom_dma_alloc(qcuefi->client, cmd_buf_size, &cmd_buf_dma, GFP_KERNEL);
+	if (!cmd_buf) {
 		efi_status = EFI_OUT_OF_RESOURCES;
 		goto out;
 	}
 
-	rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL);
-	if (!rsp_data) {
-		efi_status = EFI_OUT_OF_RESOURCES;
-		goto out_free_req;
-	}
+	req_data = cmd_buf + req_offs;
+	rsp_data = cmd_buf + rsp_offs;
 
 	req_data->command_id = QSEE_CMD_UEFI_QUERY_VARIABLE_INFO;
 	req_data->attributes = attr;
 	req_data->length = sizeof(*req_data);
 
-	status = qcom_qseecom_app_send(qcuefi->client, req_data, sizeof(*req_data), rsp_data,
-				       sizeof(*rsp_data));
+	status = qcom_qseecom_app_send(qcuefi->client,
+				       cmd_buf_dma + req_offs, sizeof(*req_data),
+				       cmd_buf_dma + rsp_offs, sizeof(*rsp_data));
 	if (status) {
 		efi_status = EFI_DEVICE_ERROR;
 		goto out_free;
@@ -711,9 +758,7 @@
 		*max_variable_size = rsp_data->max_variable_size;
 
 out_free:
-	kfree(rsp_data);
-out_free_req:
-	kfree(req_data);
+	qseecom_dma_free(qcuefi->client, cmd_buf_size, cmd_buf, cmd_buf_dma);
 out:
 	return efi_status;
 }
@@ -741,6 +786,10 @@
 static struct qcuefi_client *qcuefi_acquire(void)
 {
 	mutex_lock(&__qcuefi_lock);
+	if (!__qcuefi) {
+		mutex_unlock(&__qcuefi_lock);
+		return NULL;
+	}
 	return __qcuefi;
 }
 
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/qcom_scm-smc.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/qcom_scm-smc.c
@@ -2,6 +2,7 @@
 /* Copyright (c) 2015,2019 The Linux Foundation. All rights reserved.
  */
 
+#include <linux/cleanup.h>
 #include <linux/io.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
@@ -9,6 +10,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 #include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
 #include <linux/arm-smccc.h>
 #include <linux/dma-mapping.h>
 
@@ -71,7 +73,7 @@
 	struct arm_smccc_res get_wq_res;
 	struct arm_smccc_args get_wq_ctx = {0};
 
-	get_wq_ctx.args[0] = ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL,
+	get_wq_ctx.args[0] = ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL,
 				ARM_SMCCC_SMC_64, ARM_SMCCC_OWNER_SIP,
 				SCM_SMC_FNID(QCOM_SCM_SVC_WAITQ, QCOM_SCM_WAITQ_GET_WQ_CTX));
 
@@ -150,11 +152,10 @@
 		   enum qcom_scm_convention qcom_convention,
 		   struct qcom_scm_res *res, bool atomic)
 {
+	struct qcom_tzmem_pool *mempool = qcom_scm_get_tzmem_pool();
 	int arglen = desc->arginfo & 0xf;
 	int i, ret;
-	dma_addr_t args_phys = 0;
-	void *args_virt = NULL;
-	size_t alloc_len;
+	void *args_virt __free(qcom_tzmem) = NULL;
 	gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL;
 	u32 smccc_call_type = atomic ? ARM_SMCCC_FAST_CALL : ARM_SMCCC_STD_CALL;
 	u32 qcom_smccc_convention = (qcom_convention == SMC_CONVENTION_ARM_32) ?
@@ -172,9 +173,9 @@
 		smc.args[i + SCM_SMC_FIRST_REG_IDX] = desc->args[i];
 
 	if (unlikely(arglen > SCM_SMC_N_REG_ARGS)) {
-		alloc_len = SCM_SMC_N_EXT_ARGS * sizeof(u64);
-		args_virt = kzalloc(PAGE_ALIGN(alloc_len), flag);
-
+		args_virt = qcom_tzmem_alloc(mempool,
+					     SCM_SMC_N_EXT_ARGS * sizeof(u64),
+					     flag);
 		if (!args_virt)
 			return -ENOMEM;
 
@@ -192,25 +193,10 @@
 						      SCM_SMC_FIRST_EXT_IDX]);
 		}
 
-		args_phys = dma_map_single(dev, args_virt, alloc_len,
-					   DMA_TO_DEVICE);
-
-		if (dma_mapping_error(dev, args_phys)) {
-			kfree(args_virt);
-			return -ENOMEM;
-		}
-
-		smc.args[SCM_SMC_LAST_REG_IDX] = args_phys;
+		smc.args[SCM_SMC_LAST_REG_IDX] = qcom_tzmem_to_phys(args_virt);
 	}
 
-	/* ret error check follows after args_virt cleanup*/
 	ret = __scm_smc_do(dev, &smc, &smc_res, atomic);
-
-	if (args_virt) {
-		dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE);
-		kfree(args_virt);
-	}
-
 	if (ret)
 		return ret;
 
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/qcom_scm.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/qcom_scm.c
@@ -1,31 +1,40 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright (c) 2010,2015,2019 The Linux Foundation. All rights reserved.
  * Copyright (C) 2015 Linaro Ltd.
+ * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/arm-smccc.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/cleanup.h>
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/cpumask.h>
 #include <linux/dma-mapping.h>
+#include <linux/err.h>
 #include <linux/export.h>
 #include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
 #include <linux/init.h>
 #include <linux/interconnect.h>
 #include <linux/interrupt.h>
+#include <linux/kstrtox.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
+#include <linux/of_reserved_mem.h>
 #include <linux/platform_device.h>
 #include <linux/reset-controller.h>
+#include <linux/sizes.h>
 #include <linux/types.h>
 
 #include "qcom_scm.h"
+#include "qcom_tzmem.h"
 
-static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT);
-module_param(download_mode, bool, 0);
+static u32 download_mode;
 
 struct qcom_scm {
 	struct device *dev;
@@ -41,8 +50,11 @@
 	int scm_vote_count;
 
 	u64 dload_mode_addr;
-};
 
+	struct qcom_tzmem_pool *mempool;
+};
+#if 0
+/* moved to include/linux/firmware/qcom/qcom_scm.h */
 struct qcom_scm_current_perm_info {
 	__le32 vmid;
 	__le32 perm;
@@ -55,7 +67,7 @@
 	__le64 mem_addr;
 	__le64 mem_size;
 };
-
+#endif
 /**
  * struct qcom_scm_qseecom_resp - QSEECOM SCM call response.
  * @result:    Result or status of the SCM call. See &enum qcom_scm_qseecom_result.
@@ -102,6 +114,7 @@
 };
 
 #define QSEECOM_MAX_APP_NAME_SIZE		64
+#define SHMBRIDGE_RESULT_NOTSUPP		4
 
 /* Each bit configures cold/warm boot address for one of the 4 CPUs */
 static const u8 qcom_scm_cpu_cold_bits[QCOM_SCM_BOOT_MAX_CPUS] = {
@@ -114,6 +127,12 @@
 #define QCOM_SMC_WAITQ_FLAG_WAKE_ONE	BIT(0)
 #define QCOM_SMC_WAITQ_FLAG_WAKE_ALL	BIT(1)
 
+#define QCOM_DLOAD_MASK		GENMASK(5, 4)
+#define QCOM_DLOAD_NODUMP	0
+#define QCOM_DLOAD_FULLDUMP	1
+#define QCOM_DLOAD_MINIDUMP	2
+#define QCOM_DLOAD_BOTHDUMP	3
+
 static const char * const qcom_scm_convention_names[] = {
 	[SMC_CONVENTION_UNKNOWN] = "unknown",
 	[SMC_CONVENTION_ARM_32] = "smc arm 32",
@@ -121,6 +140,13 @@
 	[SMC_CONVENTION_LEGACY] = "smc legacy",
 };
 
+static const char * const download_mode_name[] = {
+	[QCOM_DLOAD_NODUMP]	= "off",
+	[QCOM_DLOAD_FULLDUMP]	= "full",
+	[QCOM_DLOAD_MINIDUMP]	= "mini",
+	[QCOM_DLOAD_BOTHDUMP]	= "full,mini",
+};
+
 static struct qcom_scm *__scm;
 
 static int qcom_scm_clk_enable(void)
@@ -195,6 +221,11 @@
 enum qcom_scm_convention qcom_scm_convention = SMC_CONVENTION_UNKNOWN;
 static DEFINE_SPINLOCK(scm_query_lock);
 
+struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void)
+{
+	return __scm->mempool;
+}
+
 static enum qcom_scm_convention __get_convention(void)
 {
 	unsigned long flags;
@@ -458,7 +489,7 @@
 }
 EXPORT_SYMBOL_GPL(qcom_scm_set_remote_state);
 
-static int qcom_scm_disable_sdi(void)
+int qcom_scm_disable_sdi(void)
 {
 	int ret;
 	struct qcom_scm_desc desc = {
@@ -480,6 +511,7 @@
 
 	return ret ? : res.result[0];
 }
+EXPORT_SYMBOL_GPL(qcom_scm_disable_sdi);
 
 static int __qcom_scm_set_dload_mode(struct device *dev, bool enable)
 {
@@ -496,19 +528,31 @@
 	return qcom_scm_call_atomic(__scm->dev, &desc, NULL);
 }
 
-static void qcom_scm_set_download_mode(bool enable)
+static int qcom_scm_io_rmw(phys_addr_t addr, unsigned int mask, unsigned int val)
+{
+	unsigned int old;
+	unsigned int new;
+	int ret;
+
+	ret = qcom_scm_io_readl(addr, &old);
+	if (ret)
+		return ret;
+
+	new = (old & ~mask) | (val & mask);
+
+	return qcom_scm_io_writel(addr, new);
+}
+
+static void qcom_scm_set_download_mode(u32 dload_mode)
 {
-	bool avail;
 	int ret = 0;
 
-	avail = __qcom_scm_is_call_available(__scm->dev,
-					     QCOM_SCM_SVC_BOOT,
-					     QCOM_SCM_BOOT_SET_DLOAD_MODE);
-	if (avail) {
-		ret = __qcom_scm_set_dload_mode(__scm->dev, enable);
-	} else if (__scm->dload_mode_addr) {
-		ret = qcom_scm_io_writel(__scm->dload_mode_addr,
-				enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0);
+	if (__scm->dload_mode_addr) {
+		ret = qcom_scm_io_rmw(__scm->dload_mode_addr, QCOM_DLOAD_MASK,
+				      FIELD_PREP(QCOM_DLOAD_MASK, dload_mode));
+	} else if (__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_BOOT,
+						QCOM_SCM_BOOT_SET_DLOAD_MODE)) {
+		ret = __qcom_scm_set_dload_mode(__scm->dev, !!dload_mode);
 	} else {
 		dev_err(__scm->dev,
 			"No available mechanism for setting download mode\n");
@@ -554,13 +598,23 @@
 	 * During the scm call memory protection will be enabled for the meta
 	 * data blob, so make sure it's physically contiguous, 4K aligned and
 	 * non-cachable to avoid XPU violations.
+	 *
+	 * For PIL calls the hypervisor like Gunyah or older QHEE creates SHM
+	 * Bridges for the blob buffers on behalf of Linux so we must not do it
+	 * ourselves hence use TZMem allocator only when these hypervisors are
+	 * not present.
+	 *
+	 * If we pass a buffer that is already part of an SHM Bridge to this
+	 * call, it will fail.
 	 */
-	mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys,
-				       GFP_KERNEL);
-	if (!mdata_buf) {
-		dev_err(__scm->dev, "Allocation of metadata buffer failed.\n");
+	if (ctx && ctx->shm_bridge_needed)
+		mdata_buf = qcom_tzmem_alloc(__scm->mempool, size, GFP_KERNEL);
+	else
+		mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys, GFP_KERNEL);
+
+	if (!mdata_buf)
 		return -ENOMEM;
-	}
+
 	memcpy(mdata_buf, metadata, size);
 
 	ret = qcom_scm_clk_enable();
@@ -569,22 +623,36 @@
 
 	ret = qcom_scm_bw_enable();
 	if (ret)
-		return ret;
+		goto disable_clk;
 
-	desc.args[1] = mdata_phys;
+	if (ctx && ctx->shm_bridge_needed)
+		desc.args[1] = qcom_tzmem_to_phys(mdata_buf);
+	else
+		desc.args[1] = mdata_phys;
 
 	ret = qcom_scm_call(__scm->dev, &desc, &res);
-
 	qcom_scm_bw_disable();
+
+disable_clk:
 	qcom_scm_clk_disable();
 
 out:
-	if (ret < 0 || !ctx) {
-		dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
-	} else if (ctx) {
-		ctx->ptr = mdata_buf;
-		ctx->phys = mdata_phys;
-		ctx->size = size;
+	if (ret < 0) {
+		if (ctx && ctx->shm_bridge_needed)
+			qcom_tzmem_free(mdata_buf);
+		else
+			dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
+	} else {
+		if (ctx) {
+			if (ctx->shm_bridge_needed)
+				ctx->phys = qcom_tzmem_to_phys(mdata_buf);
+			else
+				ctx->phys = mdata_phys;
+			ctx->ptr = mdata_buf;
+			ctx->size = size;
+		} else {
+			dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
+		}
 	}
 
 	return ret ? : res.result[0];
@@ -600,7 +668,10 @@
 	if (!ctx->ptr)
 		return;
 
-	dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys);
+	if (ctx->shm_bridge_needed)
+		qcom_tzmem_free(ctx->ptr);
+	else
+		dma_free_coherent(__scm->dev, ctx->size, ctx->ptr, ctx->phys);
 
 	ctx->ptr = NULL;
 	ctx->phys = 0;
@@ -637,10 +708,12 @@
 
 	ret = qcom_scm_bw_enable();
 	if (ret)
-		return ret;
+		goto disable_clk;
 
 	ret = qcom_scm_call(__scm->dev, &desc, &res);
 	qcom_scm_bw_disable();
+
+disable_clk:
 	qcom_scm_clk_disable();
 
 	return ret ? : res.result[0];
@@ -672,10 +745,12 @@
 
 	ret = qcom_scm_bw_enable();
 	if (ret)
-		return ret;
+		goto disable_clk;
 
 	ret = qcom_scm_call(__scm->dev, &desc, &res);
 	qcom_scm_bw_disable();
+
+disable_clk:
 	qcom_scm_clk_disable();
 
 	return ret ? : res.result[0];
@@ -706,11 +781,12 @@
 
 	ret = qcom_scm_bw_enable();
 	if (ret)
-		return ret;
+		goto disable_clk;
 
 	ret = qcom_scm_call(__scm->dev, &desc, &res);
-
 	qcom_scm_bw_disable();
+
+disable_clk:
 	qcom_scm_clk_disable();
 
 	return ret ? : res.result[0];
@@ -855,6 +931,32 @@
 }
 EXPORT_SYMBOL_GPL(qcom_scm_restore_sec_cfg);
 
+#define QCOM_SCM_CP_APERTURE_CONTEXT_MASK	GENMASK(7, 0)
+
+bool qcom_scm_set_gpu_smmu_aperture_is_available(void)
+{
+	return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP,
+					    QCOM_SCM_MP_CP_SMMU_APERTURE_ID);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_set_gpu_smmu_aperture_is_available);
+
+int qcom_scm_set_gpu_smmu_aperture(unsigned int context_bank)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_MP,
+		.cmd = QCOM_SCM_MP_CP_SMMU_APERTURE_ID,
+		.arginfo = QCOM_SCM_ARGS(4),
+		.args[0] = 0xffff0000 | FIELD_PREP(QCOM_SCM_CP_APERTURE_CONTEXT_MASK, context_bank),
+		.args[1] = 0xffffffff,
+		.args[2] = 0xffffffff,
+		.args[3] = 0xffffffff,
+		.owner = ARM_SMCCC_OWNER_SIP
+	};
+
+	return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_set_gpu_smmu_aperture);
+
 int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size)
 {
 	struct qcom_scm_desc desc = {
@@ -987,14 +1089,13 @@
 	struct qcom_scm_mem_map_info *mem_to_map;
 	phys_addr_t mem_to_map_phys;
 	phys_addr_t dest_phys;
-	dma_addr_t ptr_phys;
+	phys_addr_t ptr_phys;
 	size_t mem_to_map_sz;
 	size_t dest_sz;
 	size_t src_sz;
 	size_t ptr_sz;
 	int next_vm;
 	__le32 *src;
-	void *ptr;
 	int ret, i, b;
 	u64 srcvm_bits = *srcvm;
 
@@ -1004,10 +1105,13 @@
 	ptr_sz = ALIGN(src_sz, SZ_64) + ALIGN(mem_to_map_sz, SZ_64) +
 			ALIGN(dest_sz, SZ_64);
 
-	ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_phys, GFP_KERNEL);
+	void *ptr __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							ptr_sz, GFP_KERNEL);
 	if (!ptr)
 		return -ENOMEM;
 
+	ptr_phys = qcom_tzmem_to_phys(ptr);
+
 	/* Fill source vmid detail */
 	src = ptr;
 	i = 0;
@@ -1036,7 +1140,6 @@
 
 	ret = __qcom_scm_assign_mem(__scm->dev, mem_to_map_phys, mem_to_map_sz,
 				    ptr_phys, src_sz, dest_phys, dest_sz);
-	dma_free_coherent(__scm->dev, ptr_sz, ptr, ptr_phys);
 	if (ret) {
 		dev_err(__scm->dev,
 			"Assign memory protection call failed %d\n", ret);
@@ -1049,6 +1152,39 @@
 EXPORT_SYMBOL_GPL(qcom_scm_assign_mem);
 
 /**
+ *  qcom_scm_assign_mem_regions() - Make a secure call to reassign memory
+ *                                   ownership of several memory regions
+ *  @mem_regions:    A buffer describing the set of memory regions that need to
+ *                   be reassigned
+ *  @mem_regions_sz: The size of the buffer describing the set of memory
+ *                   regions that need to be reassigned (in bytes)
+ *  @srcvms:         A buffer populated with he vmid(s) for the current set of
+ *                   owners
+ *  @src_sz:         The size of the src_vms buffer (in bytes)
+ *  @newvms:         A buffer populated with the new owners and corresponding
+ *                  permission flags.
+ *  @newvms_sz:      The size of the new_vms buffer (in bytes)
+ *
+ *  NOTE: It is up to the caller to ensure that the buffers that will be accessed
+ *  by the secure world are cache aligned, and have been flushed prior to
+ *  invoking this call.
+ *
+ *  Return negative errno on failure, 0 on success.
+ */
+int qcom_scm_assign_mem_regions(struct qcom_scm_mem_map_info *mem_regions,
+		size_t mem_regions_sz, u32 *srcvms,
+		size_t src_sz,
+		struct qcom_scm_current_perm_info *newvms,
+		size_t newvms_sz)
+{
+	return __qcom_scm_assign_mem(__scm ? __scm->dev : NULL,
+			virt_to_phys(mem_regions), mem_regions_sz,
+			virt_to_phys(srcvms), src_sz,
+			virt_to_phys(newvms), newvms_sz);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_assign_mem_regions);
+
+/**
  * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available
  */
 bool qcom_scm_ocmem_lock_available(void)
@@ -1184,37 +1320,253 @@
 		.args[4] = data_unit_size,
 		.owner = ARM_SMCCC_OWNER_SIP,
 	};
-	void *keybuf;
-	dma_addr_t key_phys;
-	int ret;
 
-	/*
-	 * 'key' may point to vmalloc()'ed memory, but we need to pass a
-	 * physical address that's been properly flushed.  The sanctioned way to
-	 * do this is by using the DMA API.  But as is best practice for crypto
-	 * keys, we also must wipe the key after use.  This makes kmemdup() +
-	 * dma_map_single() not clearly correct, since the DMA API can use
-	 * bounce buffers.  Instead, just use dma_alloc_coherent().  Programming
-	 * keys is normally rare and thus not performance-critical.
-	 */
+	int ret;
 
-	keybuf = dma_alloc_coherent(__scm->dev, key_size, &key_phys,
-				    GFP_KERNEL);
+	void *keybuf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							   key_size,
+							   GFP_KERNEL);
 	if (!keybuf)
 		return -ENOMEM;
 	memcpy(keybuf, key, key_size);
-	desc.args[1] = key_phys;
+	desc.args[1] = qcom_tzmem_to_phys(keybuf);
 
 	ret = qcom_scm_call(__scm->dev, &desc, NULL);
 
 	memzero_explicit(keybuf, key_size);
 
-	dma_free_coherent(__scm->dev, key_size, keybuf, key_phys);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(qcom_scm_ice_set_key);
 
 /**
+ * qcom_scm_derive_sw_secret() - Derive software secret from wrapped key
+ * @wkey: the hardware wrapped key inaccessible to software
+ * @wkey_size: size of the wrapped key
+ * @sw_secret: the secret to be derived which is exactly the secret size
+ * @sw_secret_size: size of the sw_secret
+ *
+ * Derive a software secret from a hardware wrapped key for software crypto
+ * operations.
+ * For wrapped keys, the key needs to be unwrapped, in order to derive a
+ * software secret, which can be done in the hardware from a secure execution
+ * environment.
+ *
+ * For more information on sw secret, please refer to "Hardware-wrapped keys"
+ * section of Documentation/block/inline-encryption.rst.
+ *
+ * Return: 0 on success; -errno on failure.
+ */
+int qcom_scm_derive_sw_secret(const u8 *wkey, size_t wkey_size,
+			     u8 *sw_secret, size_t sw_secret_size)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_ES,
+		.cmd =  QCOM_SCM_ES_DERIVE_SW_SECRET,
+		.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW,
+					 QCOM_SCM_VAL, QCOM_SCM_RW,
+					 QCOM_SCM_VAL),
+		.args[1] = wkey_size,
+		.args[3] = sw_secret_size,
+		.owner = ARM_SMCCC_OWNER_SIP,
+	};
+
+	int ret;
+
+	void *wkey_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							     wkey_size,
+							     GFP_KERNEL);
+	if (!wkey_buf)
+		return -ENOMEM;
+
+	void *secret_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							       sw_secret_size,
+							       GFP_KERNEL);
+	if (!secret_buf) {
+		ret = -ENOMEM;
+		goto out_free_wrapped;
+	}
+
+	memcpy(wkey_buf, wkey, wkey_size);
+	desc.args[0] = qcom_tzmem_to_phys(wkey_buf);
+	desc.args[2] = qcom_tzmem_to_phys(secret_buf);
+
+	ret = qcom_scm_call(__scm->dev, &desc, NULL);
+	if (!ret)
+		memcpy(sw_secret, secret_buf, sw_secret_size);
+
+	memzero_explicit(secret_buf, sw_secret_size);
+
+out_free_wrapped:
+	memzero_explicit(wkey_buf, wkey_size);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_derive_sw_secret);
+
+/**
+ * qcom_scm_generate_ice_key() - Generate a wrapped key for encryption.
+ * @lt_key: the wrapped key returned after key generation
+ * @lt_key_size: size of the wrapped key to be returned.
+ *
+ * Generate a key using the built-in HW module in the SoC. Wrap the key using
+ * the platform-specific Key Encryption Key and return to the caller.
+ *
+ * Return: 0 on success; -errno on failure.
+ */
+int qcom_scm_generate_ice_key(u8 *lt_key, size_t lt_key_size)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_ES,
+		.cmd =  QCOM_SCM_ES_GENERATE_ICE_KEY,
+		.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW, QCOM_SCM_VAL),
+		.args[1] = lt_key_size,
+		.owner = ARM_SMCCC_OWNER_SIP,
+	};
+
+	int ret;
+
+	void *lt_key_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							       lt_key_size,
+							       GFP_KERNEL);
+	if (!lt_key_buf)
+		return -ENOMEM;
+
+	desc.args[0] = qcom_tzmem_to_phys(lt_key_buf);
+
+	ret = qcom_scm_call(__scm->dev, &desc, NULL);
+	if (!ret)
+		memcpy(lt_key, lt_key_buf, lt_key_size);
+
+	memzero_explicit(lt_key_buf, lt_key_size);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_generate_ice_key);
+
+/**
+ * qcom_scm_prepare_ice_key() - Get the per-boot ephemeral wrapped key
+ * @lt_key: the longterm wrapped key
+ * @lt_key_size: size of the wrapped key
+ * @eph_key: ephemeral wrapped key to be returned
+ * @eph_key_size: size of the ephemeral wrapped key
+ *
+ * Qualcomm wrapped keys (longterm keys) are rewrapped with a per-boot
+ * ephemeral key for added protection. These are ephemeral in nature as
+ * they are valid only for that boot.
+ *
+ * Retrieve the key wrapped with the per-boot ephemeral key and return it to
+ * the caller.
+ *
+ * Return: 0 on success; -errno on failure.
+ */
+int qcom_scm_prepare_ice_key(const u8 *lt_key, size_t lt_key_size,
+			    u8 *eph_key, size_t eph_key_size)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_ES,
+		.cmd =  QCOM_SCM_ES_PREPARE_ICE_KEY,
+		.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RO,
+					 QCOM_SCM_VAL, QCOM_SCM_RW,
+					 QCOM_SCM_VAL),
+		.args[1] = lt_key_size,
+		.args[3] = eph_key_size,
+		.owner = ARM_SMCCC_OWNER_SIP,
+	};
+
+	int ret;
+
+	void *lt_key_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							       lt_key_size,
+							       GFP_KERNEL);
+	if (!lt_key_buf)
+		return -ENOMEM;
+
+	void *eph_key_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+								eph_key_size,
+								GFP_KERNEL);
+	if (!eph_key_buf) {
+		ret = -ENOMEM;
+		goto out_free_longterm;
+	}
+
+	memcpy(lt_key_buf, lt_key, lt_key_size);
+	desc.args[0] = qcom_tzmem_to_phys(lt_key_buf);
+	desc.args[2] = qcom_tzmem_to_phys(eph_key_buf);
+
+	ret = qcom_scm_call(__scm->dev, &desc, NULL);
+	if (!ret)
+		memcpy(eph_key, eph_key_buf, eph_key_size);
+
+	memzero_explicit(eph_key_buf, eph_key_size);
+
+out_free_longterm:
+	memzero_explicit(lt_key_buf, lt_key_size);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_prepare_ice_key);
+
+/**
+ * qcom_scm_import_ice_key() - Import a wrapped key for encryption
+ * @imp_key: the raw key that is imported
+ * @imp_key_size: size of the key to be imported
+ * @lt_key: the wrapped key to be returned
+ * @lt_key_size: size of the wrapped key
+ *
+ * Import a raw key and return a long-term wrapped key to the caller.
+ *
+ * Return: 0 on success; -errno on failure.
+ */
+int qcom_scm_import_ice_key(const u8 *imp_key, size_t imp_key_size,
+			   u8 *lt_key, size_t lt_key_size)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_ES,
+		.cmd =  QCOM_SCM_ES_IMPORT_ICE_KEY,
+		.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RO,
+					 QCOM_SCM_VAL, QCOM_SCM_RW,
+					 QCOM_SCM_VAL),
+		.args[1] = imp_key_size,
+		.args[3] = lt_key_size,
+		.owner = ARM_SMCCC_OWNER_SIP,
+	};
+
+	int ret;
+
+	void *imp_key_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+								imp_key_size,
+								GFP_KERNEL);
+	if (!imp_key_buf)
+		return -ENOMEM;
+
+	void *lt_key_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							       lt_key_size,
+							       GFP_KERNEL);
+	if (!lt_key_buf) {
+		ret = -ENOMEM;
+		goto out_free_longterm;
+	}
+
+	memcpy(imp_key_buf, imp_key, imp_key_size);
+	desc.args[0] = qcom_tzmem_to_phys(imp_key_buf);
+	desc.args[2] = qcom_tzmem_to_phys(lt_key_buf);
+
+	ret = qcom_scm_call(__scm->dev, &desc, NULL);
+	if (!ret)
+		memcpy(lt_key, lt_key_buf, lt_key_size);
+
+	memzero_explicit(lt_key_buf, lt_key_size);
+
+out_free_longterm:
+	memzero_explicit(imp_key_buf, imp_key_size);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_import_ice_key);
+
+
+/**
  * qcom_scm_hdcp_available() - Check if secure environment supports HDCP.
  *
  * Return true if HDCP is supported, false if not.
@@ -1321,6 +1673,76 @@
 }
 EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh_available);
 
+int qcom_scm_shm_bridge_enable(void)
+{
+	int ret;
+
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_MP,
+		.cmd = QCOM_SCM_MP_SHM_BRIDGE_ENABLE,
+		.owner = ARM_SMCCC_OWNER_SIP
+	};
+
+	struct qcom_scm_res res;
+
+	if (!__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP,
+					  QCOM_SCM_MP_SHM_BRIDGE_ENABLE))
+		return -EOPNOTSUPP;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	if (ret)
+		return ret;
+
+	if (res.result[0] == SHMBRIDGE_RESULT_NOTSUPP)
+		return -EOPNOTSUPP;
+
+	return res.result[0];
+}
+EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_enable);
+
+int qcom_scm_shm_bridge_create(struct device *dev, u64 pfn_and_ns_perm_flags,
+			       u64 ipfn_and_s_perm_flags, u64 size_and_flags,
+			       u64 ns_vmids, u64 *handle)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_MP,
+		.cmd = QCOM_SCM_MP_SHM_BRIDGE_CREATE,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = pfn_and_ns_perm_flags,
+		.args[1] = ipfn_and_s_perm_flags,
+		.args[2] = size_and_flags,
+		.args[3] = ns_vmids,
+		.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_VAL, QCOM_SCM_VAL,
+					 QCOM_SCM_VAL, QCOM_SCM_VAL),
+	};
+
+	struct qcom_scm_res res;
+	int ret;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	if (handle && !ret)
+		*handle = res.result[1];
+
+	return ret ?: res.result[0];
+}
+EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_create);
+
+int qcom_scm_shm_bridge_delete(struct device *dev, u64 handle)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_MP,
+		.cmd = QCOM_SCM_MP_SHM_BRIDGE_DELETE,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = handle,
+		.arginfo = QCOM_SCM_ARGS(1, QCOM_SCM_VAL),
+	};
+
+	return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_delete);
+
 int qcom_scm_lmh_profile_change(u32 profile_id)
 {
 	struct qcom_scm_desc desc = {
@@ -1338,8 +1760,6 @@
 int qcom_scm_lmh_dcvsh(u32 payload_fn, u32 payload_reg, u32 payload_val,
 		       u64 limit_node, u32 node_id, u64 version)
 {
-	dma_addr_t payload_phys;
-	u32 *payload_buf;
 	int ret, payload_size = 5 * sizeof(u32);
 
 	struct qcom_scm_desc desc = {
@@ -1354,7 +1774,9 @@
 		.owner = ARM_SMCCC_OWNER_SIP,
 	};
 
-	payload_buf = dma_alloc_coherent(__scm->dev, payload_size, &payload_phys, GFP_KERNEL);
+	u32 *payload_buf __free(qcom_tzmem) = qcom_tzmem_alloc(__scm->mempool,
+							       payload_size,
+							       GFP_KERNEL);
 	if (!payload_buf)
 		return -ENOMEM;
 
@@ -1364,15 +1786,28 @@
 	payload_buf[3] = 1;
 	payload_buf[4] = payload_val;
 
-	desc.args[0] = payload_phys;
+	desc.args[0] = qcom_tzmem_to_phys(payload_buf);
 
 	ret = qcom_scm_call(__scm->dev, &desc, NULL);
 
-	dma_free_coherent(__scm->dev, payload_size, payload_buf, payload_phys);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh);
 
+int qcom_scm_gpu_init_regs(u32 gpu_req)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_GPU,
+		.cmd = QCOM_SCM_SVC_GPU_INIT_REGS,
+		.arginfo = QCOM_SCM_ARGS(1),
+		.args[0] = gpu_req,
+		.owner = ARM_SMCCC_OWNER_SIP,
+	};
+
+	return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_gpu_init_regs);
+
 static int qcom_scm_find_dload_address(struct device *dev, u64 *addr)
 {
 	struct device_node *tcsr;
@@ -1576,9 +2011,9 @@
 /**
  * qcom_scm_qseecom_app_send() - Send to and receive data from a given QSEE app.
  * @app_id:   The ID of the target app.
- * @req:      Request buffer sent to the app (must be DMA-mappable).
+ * @req:      DMA address of the request buffer sent to the app.
  * @req_size: Size of the request buffer.
- * @rsp:      Response buffer, written to by the app (must be DMA-mappable).
+ * @rsp:      DMA address of the response buffer, written to by the app.
  * @rsp_size: Size of the response buffer.
  *
  * Sends a request to the QSEE app associated with the given ID and read back
@@ -1589,33 +2024,13 @@
  *
  * Return: Zero on success, nonzero on failure.
  */
-int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
-			      size_t rsp_size)
+int qcom_scm_qseecom_app_send(u32 app_id, dma_addr_t req, size_t req_size,
+			      dma_addr_t rsp, size_t rsp_size)
 {
 	struct qcom_scm_qseecom_resp res = {};
 	struct qcom_scm_desc desc = {};
-	dma_addr_t req_phys;
-	dma_addr_t rsp_phys;
 	int status;
 
-	/* Map request buffer */
-	req_phys = dma_map_single(__scm->dev, req, req_size, DMA_TO_DEVICE);
-	status = dma_mapping_error(__scm->dev, req_phys);
-	if (status) {
-		dev_err(__scm->dev, "qseecom: failed to map request buffer\n");
-		return status;
-	}
-
-	/* Map response buffer */
-	rsp_phys = dma_map_single(__scm->dev, rsp, rsp_size, DMA_FROM_DEVICE);
-	status = dma_mapping_error(__scm->dev, rsp_phys);
-	if (status) {
-		dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
-		dev_err(__scm->dev, "qseecom: failed to map response buffer\n");
-		return status;
-	}
-
-	/* Set up SCM call data */
 	desc.owner = QSEECOM_TZ_OWNER_TZ_APPS;
 	desc.svc = QSEECOM_TZ_SVC_APP_ID_PLACEHOLDER;
 	desc.cmd = QSEECOM_TZ_CMD_APP_SEND;
@@ -1623,18 +2038,13 @@
 				     QCOM_SCM_RW, QCOM_SCM_VAL,
 				     QCOM_SCM_RW, QCOM_SCM_VAL);
 	desc.args[0] = app_id;
-	desc.args[1] = req_phys;
+	desc.args[1] = req;
 	desc.args[2] = req_size;
-	desc.args[3] = rsp_phys;
+	desc.args[3] = rsp;
 	desc.args[4] = rsp_size;
 
-	/* Perform call */
 	status = qcom_scm_qseecom_call(&desc, &res);
 
-	/* Unmap buffers */
-	dma_unmap_single(__scm->dev, rsp_phys, rsp_size, DMA_FROM_DEVICE);
-	dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE);
-
 	if (status)
 		return status;
 
@@ -1649,7 +2059,7 @@
  * We do not yet support re-entrant calls via the qseecom interface. To prevent
  + any potential issues with this, only allow validated machines for now.
  */
-static const struct of_device_id qcom_scm_qseecom_allowlist[] = {
+static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
 	{ .compatible = "lenovo,thinkpad-x13s", },
 	{ }
 };
@@ -1738,7 +2148,8 @@
  */
 bool qcom_scm_is_available(void)
 {
-	return !!__scm;
+	/* Paired with smp_store_release() in qcom_scm_probe */
+	return !!smp_load_acquire(&__scm);
 }
 EXPORT_SYMBOL_GPL(qcom_scm_is_available);
 
@@ -1764,12 +2175,12 @@
 	if (ret)
 		return ret;
 
-	wait_for_completion(&__scm->waitq_comp);
+	wait_for_completion_state(&__scm->waitq_comp, TASK_IDLE);
 
 	return 0;
 }
 
-static int qcom_scm_waitq_wakeup(struct qcom_scm *scm, unsigned int wq_ctx)
+static int qcom_scm_waitq_wakeup(unsigned int wq_ctx)
 {
 	int ret;
 
@@ -1801,7 +2212,7 @@
 			goto out;
 		}
 
-		ret = qcom_scm_waitq_wakeup(scm, wq_ctx);
+		ret = qcom_scm_waitq_wakeup(wq_ctx);
 		if (ret)
 			goto out;
 	} while (more_pending);
@@ -1810,8 +2221,52 @@
 	return IRQ_HANDLED;
 }
 
+static int get_download_mode(char *buffer, const struct kernel_param *kp)
+{
+	if (download_mode >= ARRAY_SIZE(download_mode_name))
+		return sysfs_emit(buffer, "unknown mode\n");
+
+	return sysfs_emit(buffer, "%s\n", download_mode_name[download_mode]);
+}
+
+static int set_download_mode(const char *val, const struct kernel_param *kp)
+{
+	bool tmp;
+	int ret;
+
+	ret = sysfs_match_string(download_mode_name, val);
+	if (ret < 0) {
+		ret = kstrtobool(val, &tmp);
+		if (ret < 0) {
+			pr_err("qcom_scm: err: %d\n", ret);
+			return ret;
+		}
+
+		ret = tmp ? 1 : 0;
+	}
+
+	download_mode = ret;
+	if (__scm)
+		qcom_scm_set_download_mode(download_mode);
+
+	return 0;
+}
+
+static const struct kernel_param_ops download_mode_param_ops = {
+	.get = get_download_mode,
+	.set = set_download_mode,
+};
+
+module_param_cb(download_mode, &download_mode_param_ops, NULL, 0644);
+MODULE_PARM_DESC(download_mode, "download mode: off/0/N for no dump mode, full/on/1/Y for full dump mode, mini for minidump mode and full,mini for both full and minidump mode together are acceptable values");
+
+#ifdef CONFIG_QCOM_SCM_ADDON
+#include "qcom_scm_addon.c"
+#endif
+
 static int qcom_scm_probe(struct platform_device *pdev)
 {
+	struct qcom_tzmem_pool_config pool_config;
 	struct qcom_scm *scm;
 	int irq, ret;
 
@@ -1819,10 +2274,12 @@
 	if (!scm)
 		return -ENOMEM;
 
+	scm->dev = &pdev->dev;
 	ret = qcom_scm_find_dload_address(&pdev->dev, &scm->dload_mode_addr);
 	if (ret < 0)
 		return ret;
 
+	init_completion(&scm->waitq_comp);
 	mutex_init(&scm->scm_bw_lock);
 
 	scm->path = devm_of_icc_get(&pdev->dev, NULL);
@@ -1854,10 +2311,8 @@
 	if (ret)
 		return ret;
 
-	__scm = scm;
-	__scm->dev = &pdev->dev;
-
-	init_completion(&__scm->waitq_comp);
+	/* Paired with smp_load_acquire() in qcom_scm_is_available(). */
+	smp_store_release(&__scm, scm);
 
 	irq = platform_get_irq_optional(pdev, 0);
 	if (irq < 0) {
@@ -1873,20 +2328,38 @@
 	__get_convention();
 
 	/*
-	 * If requested enable "download mode", from this point on warmboot
+	 * If "download mode" is requested, from this point on warmboot
 	 * will cause the boot stages to enter download mode, unless
 	 * disabled below by a clean shutdown/reboot.
 	 */
-	if (download_mode)
-		qcom_scm_set_download_mode(true);
-
+	qcom_scm_set_download_mode(download_mode);
 
 	/*
 	 * Disable SDI if indicated by DT that it is enabled by default.
 	 */
-	if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled"))
+	if (of_property_read_bool(pdev->dev.of_node, "qcom,sdi-enabled") || !download_mode)
 		qcom_scm_disable_sdi();
 
+	ret = of_reserved_mem_device_init(__scm->dev);
+	if (ret && ret != -ENODEV)
+		return dev_err_probe(__scm->dev, ret,
+				     "Failed to setup the reserved memory region for TZ mem\n");
+
+	ret = qcom_tzmem_enable(__scm->dev);
+	if (ret)
+		return dev_err_probe(__scm->dev, ret,
+				     "Failed to enable the TrustZone memory allocator\n");
+
+	memset(&pool_config, 0, sizeof(pool_config));
+	pool_config.initial_size = 0;
+	pool_config.policy = QCOM_TZMEM_POLICY_ON_DEMAND;
+	pool_config.max_size = SZ_256K;
+
+	__scm->mempool = devm_qcom_tzmem_pool_new(__scm->dev, &pool_config);
+	if (IS_ERR(__scm->mempool))
+		return dev_err_probe(__scm->dev, PTR_ERR(__scm->mempool),
+				     "Failed to create the SCM memory pool\n");
+
 	/*
 	 * Initialize the QSEECOM interface.
 	 *
@@ -1906,7 +2379,7 @@
 static void qcom_scm_shutdown(struct platform_device *pdev)
 {
 	/* Clean shutdown, disable download mode to allow normal restart */
-	qcom_scm_set_download_mode(false);
+	qcom_scm_set_download_mode(QCOM_DLOAD_NODUMP);
 }
 
 static const struct of_device_id qcom_scm_dt_match[] = {
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/qcom_scm.h
+++ linux-qcom-6.8.0/drivers/firmware/qcom/qcom_scm.h
@@ -1,10 +1,12 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /* Copyright (c) 2010-2015,2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 #ifndef __QCOM_SCM_INT_H
 #define __QCOM_SCM_INT_H
 
 struct device;
+struct qcom_tzmem_pool;
 
 enum qcom_scm_convention {
 	SMC_CONVENTION_UNKNOWN,
@@ -78,6 +80,8 @@
 int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
 		    struct qcom_scm_res *res);
 
+struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void);
+
 #define QCOM_SCM_SVC_BOOT		0x01
 #define QCOM_SCM_BOOT_SET_ADDR		0x01
 #define QCOM_SCM_BOOT_TERMINATE_PC	0x02
@@ -113,6 +117,10 @@
 #define QCOM_SCM_MP_IOMMU_SET_CP_POOL_SIZE	0x05
 #define QCOM_SCM_MP_VIDEO_VAR			0x08
 #define QCOM_SCM_MP_ASSIGN			0x16
+#define QCOM_SCM_MP_CP_SMMU_APERTURE_ID		0x1b
+#define QCOM_SCM_MP_SHM_BRIDGE_ENABLE		0x1c
+#define QCOM_SCM_MP_SHM_BRIDGE_DELETE		0x1d
+#define QCOM_SCM_MP_SHM_BRIDGE_CREATE		0x1e
 
 #define QCOM_SCM_SVC_OCMEM		0x0f
 #define QCOM_SCM_OCMEM_LOCK_CMD		0x01
@@ -121,6 +129,10 @@
 #define QCOM_SCM_SVC_ES			0x10	/* Enterprise Security */
 #define QCOM_SCM_ES_INVALIDATE_ICE_KEY	0x03
 #define QCOM_SCM_ES_CONFIG_SET_ICE_KEY	0x04
+#define QCOM_SCM_ES_DERIVE_SW_SECRET	0x07
+#define QCOM_SCM_ES_GENERATE_ICE_KEY   0x08
+#define QCOM_SCM_ES_PREPARE_ICE_KEY    0x09
+#define QCOM_SCM_ES_IMPORT_ICE_KEY     0xA
 
 #define QCOM_SCM_SVC_HDCP		0x11
 #define QCOM_SCM_HDCP_INVOKE		0x01
@@ -138,6 +150,9 @@
 #define QCOM_SCM_WAITQ_RESUME			0x02
 #define QCOM_SCM_WAITQ_GET_WQ_CTX		0x03
 
+#define QCOM_SCM_SVC_GPU			0x28
+#define QCOM_SCM_SVC_GPU_INIT_REGS		0x01
+
 /* common error codes */
 #define QCOM_SCM_V2_EBUSY	-12
 #define QCOM_SCM_ENOMEM		-5
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/qcom_scm_addon.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/qcom_scm_addon.c
@@ -0,0 +1,663 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define QCOM_SCM_MP_CP_SMMU_APERTURE_ID         0x1b
+#define QCOM_SCM_CP_APERTURE_REG    0x0
+#define QCOM_SCM_SVC_GPU            0x28
+#define QCOM_SCM_SVC_GPU_INIT_REGS          0x1
+
+#define QCOM_SCM_SVC_SMCINVOKE          0x06
+#define QCOM_SCM_SMCINVOKE_INVOKE_LEGACY    0x00
+#define QCOM_SCM_SMCINVOKE_INVOKE       0x02
+#define QCOM_SCM_SMCINVOKE_CB_RSP       0x01
+
+#define QCOM_SCM_SVC_INFO       0x06
+#define QCOM_SCM_INFO_IS_CALL_AVAIL 0x01
+#define QCOM_SCM_INFO_GET_FEAT_VERSION_CMD  0x03
+
+/* TOS Services and Function IDs */
+#define QCOM_SCM_SVC_QSEELOG            0x01
+#define QCOM_SCM_QSEELOG_REGISTER       0x06
+#define QCOM_SCM_QUERY_ENCR_LOG_FEAT_ID     0x0b
+#define QCOM_SCM_REQUEST_ENCR_LOG_ID        0x0c
+
+/* Feature IDs for QCOM_SCM_INFO_GET_FEAT_VERSION */
+#define QCOM_SCM_TZ_DBG_ETM_FEAT_ID     0x08
+#define QCOM_SCM_FEAT_LOG_ID            0x0a
+#define QCOM_SCM_MP_CP_FEAT_ID          0x0c
+
+#define QCOM_SCM_SVC_DCVS           0x0D
+#define QCOM_SCM_DCVS_RESET         0x07
+#define QCOM_SCM_DCVS_UPDATE            0x08
+#define QCOM_SCM_DCVS_INIT          0x09
+#define QCOM_SCM_DCVS_UPDATE_V2         0x0a
+#define QCOM_SCM_DCVS_INIT_V2           0x0b
+#define QCOM_SCM_DCVS_INIT_CA_V2        0x0c
+#define QCOM_SCM_DCVS_UPDATE_CA_V2      0x0d
+
+#define QCOM_SCM_IO_RESET           0x03
+
+/* IDs for sdi and sec wdog control */
+#define QCOM_SCM_BOOT_SEC_WDOG_DIS	0x07
+#define QCOM_SCM_BOOT_SEC_WDOG_TRIGGER	0x08
+#define QCOM_SCM_BOOT_WDOG_DEBUG_PART	0x09
+#define QCOM_SCM_BOOT_SPIN_CPU		0x0d
+
+/* IDs for SHE */
+#define QCOM_SCM_SVC_SHE                        0x21
+#define QCOM_SCM_SHE_ID                         0x1
+
+/* IDs for QCOM_SCM_INFO_BW_PROF_ID */
+#define QCOM_SCM_INFO_BW_PROF_ID	0x07
+
+/* IDs for CAMERA */
+#define QCOM_SCM_SVC_CAMERA			0x18
+#define QCOM_SCM_CAMERA_UPDATE_CAMNOC_QOS	0xA
+
+/* IDs for Dump Table*/
+#define QCOM_SCM_SVC_UTIL			0x03
+#define QCOM_SCM_UTIL_DUMP_TABLE_ASSIGN		0x13
+
+static int __qcom_scm_get_feat_version(struct device *dev, u64 feat_id, u64 *version)
+{
+	int ret;
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_INFO,
+		.cmd = QCOM_SCM_INFO_GET_FEAT_VERSION_CMD,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = feat_id,
+		.arginfo = QCOM_SCM_ARGS(1),
+	};
+	struct qcom_scm_res res;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	if (version)
+		*version = res.result[0];
+
+	return ret;
+}
+
+/**
+ * qcom_scm_dcvs_ca_available() - check if context aware DCVS operations are
+ * available
+ */
+bool qcom_scm_dcvs_ca_available(void)
+{
+	struct device *dev = __scm ? __scm->dev : NULL;
+
+	return __qcom_scm_is_call_available(dev, QCOM_SCM_SVC_DCVS,
+					QCOM_SCM_DCVS_INIT_CA_V2) &&
+			__qcom_scm_is_call_available(dev, QCOM_SCM_SVC_DCVS,
+					QCOM_SCM_DCVS_UPDATE_CA_V2);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_dcvs_ca_available);
+
+/**
+ * qcom_scm_dcvs_core_available() - check if core DCVS operations are available
+ */
+bool qcom_scm_dcvs_core_available(void)
+{
+	struct device *dev = __scm ? __scm->dev : NULL;
+
+	return __qcom_scm_is_call_available(dev, QCOM_SCM_SVC_DCVS,
+					QCOM_SCM_DCVS_INIT) &&
+			 __qcom_scm_is_call_available(dev, QCOM_SCM_SVC_DCVS,
+					QCOM_SCM_DCVS_UPDATE) &&
+			 __qcom_scm_is_call_available(dev, QCOM_SCM_SVC_DCVS,
+					QCOM_SCM_DCVS_RESET);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_dcvs_core_available);
+
+int qcom_scm_dcvs_reset(void)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_DCVS,
+		.cmd = QCOM_SCM_DCVS_RESET,
+		.owner = ARM_SMCCC_OWNER_SIP
+	};
+
+	return qcom_scm_call(__scm ? __scm->dev : NULL, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_dcvs_reset);
+
+int qcom_scm_dcvs_init_v2(phys_addr_t addr, size_t size, int *version)
+{
+	int ret;
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_DCVS,
+		.cmd = QCOM_SCM_DCVS_INIT_V2,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = addr,
+		.args[1] = size,
+		.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW, QCOM_SCM_VAL),
+	};
+	struct qcom_scm_res res;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	if (ret >= 0)
+		*version = res.result[0];
+	return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_dcvs_init_v2);
+
+int qcom_scm_dcvs_update(int level, s64 total_time, s64 busy_time)
+{
+	int ret;
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_DCVS,
+		.cmd = QCOM_SCM_DCVS_UPDATE,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = level,
+		.args[1] = total_time,
+		.args[2] = busy_time,
+		.arginfo = QCOM_SCM_ARGS(3),
+	};
+	struct qcom_scm_res res;
+
+	ret = qcom_scm_call_atomic(__scm->dev, &desc, &res);
+
+	return ret ? : res.result[0];
+}
+EXPORT_SYMBOL_GPL(qcom_scm_dcvs_update);
+
+int qcom_scm_dcvs_update_v2(int level, s64 total_time, s64 busy_time)
+{
+	int ret;
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_DCVS,
+		.cmd = QCOM_SCM_DCVS_UPDATE_V2,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = level,
+		.args[1] = total_time,
+		.args[2] = busy_time,
+		.arginfo = QCOM_SCM_ARGS(3),
+	};
+	struct qcom_scm_res res;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	return ret ? : res.result[0];
+}
+EXPORT_SYMBOL_GPL(qcom_scm_dcvs_update_v2);
+
+int qcom_scm_dcvs_update_ca_v2(int level, s64 total_time, s64 busy_time,
+		int context_count)
+{
+	int ret;
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_DCVS,
+		.cmd = QCOM_SCM_DCVS_UPDATE_CA_V2,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = level,
+		.args[1] = total_time,
+		.args[2] = busy_time,
+		.args[3] = context_count,
+		.arginfo = QCOM_SCM_ARGS(4),
+	};
+	struct qcom_scm_res res;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	return ret ? : res.result[0];
+
+}
+EXPORT_SYMBOL_GPL(qcom_scm_dcvs_update_ca_v2);
+
+int qcom_scm_dcvs_init_ca_v2(phys_addr_t addr, size_t size)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_DCVS,
+		.cmd = QCOM_SCM_DCVS_INIT_CA_V2,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = addr,
+		.args[1] = size,
+		.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW, QCOM_SCM_VAL),
+	};
+
+	return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_dcvs_init_ca_v2);
+
+int qcom_scm_io_reset(void)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_IO,
+		.cmd = QCOM_SCM_IO_RESET,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.arginfo = QCOM_SCM_ARGS(2),
+	};
+
+	return qcom_scm_call_atomic(__scm ? __scm->dev : NULL, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_io_reset);
+
+int qcom_scm_get_tz_log_feat_id(u64 *version)
+{
+	return __qcom_scm_get_feat_version(__scm->dev, QCOM_SCM_FEAT_LOG_ID, version);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_get_tz_log_feat_id);
+
+int qcom_scm_get_tz_feat_id_version(u64 feat_id, u64 *version)
+{
+	return __qcom_scm_get_feat_version(__scm->dev, feat_id, version);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_get_tz_feat_id_version);
+
+int qcom_scm_register_qsee_log_buf(phys_addr_t buf, size_t len)
+{
+	int ret;
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_QSEELOG,
+		.cmd = QCOM_SCM_QSEELOG_REGISTER,
+		.owner = ARM_SMCCC_OWNER_TRUSTED_OS,
+		.args[0] = buf,
+		.args[1] = len,
+		.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW),
+	};
+	struct qcom_scm_res res;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	return ret ? : res.result[0];
+}
+EXPORT_SYMBOL_GPL(qcom_scm_register_qsee_log_buf);
+
+int qcom_scm_query_encrypted_log_feature(u64 *enabled)
+{
+	int ret;
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_QSEELOG,
+		.cmd = QCOM_SCM_QUERY_ENCR_LOG_FEAT_ID,
+		.owner = ARM_SMCCC_OWNER_TRUSTED_OS
+	};
+	struct qcom_scm_res res;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+	if (enabled)
+		*enabled = res.result[0];
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_query_encrypted_log_feature);
+
+int qcom_scm_request_encrypted_log(phys_addr_t buf,
+					size_t len,
+					uint32_t log_id,
+					bool is_full_tz_logs_supported,
+					bool is_full_tz_logs_enabled)
+{
+	int ret;
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_QSEELOG,
+		.cmd = QCOM_SCM_REQUEST_ENCR_LOG_ID,
+		.owner = ARM_SMCCC_OWNER_TRUSTED_OS,
+		.args[0] = buf,
+		.args[1] = len,
+		.args[2] = log_id
+	};
+	struct qcom_scm_res res;
+
+	if (is_full_tz_logs_supported) {
+		if (is_full_tz_logs_enabled) {
+			/* requesting full logs */
+			desc.args[3] = 1;
+		} else {
+			/* requesting incremental logs */
+			desc.args[3] = 0;
+		}
+		desc.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW);
+	} else {
+		desc.arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_RW);
+	}
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	return ret ? : res.result[0];
+}
+EXPORT_SYMBOL_GPL(qcom_scm_request_encrypted_log);
+
+bool qcom_scm_kgsl_set_smmu_aperture_available(void)
+{
+	int ret;
+
+	ret = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_MP,
+				QCOM_SCM_MP_CP_SMMU_APERTURE_ID);
+
+	return ret > 0;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_kgsl_set_smmu_aperture_available);
+
+int qcom_scm_kgsl_set_smmu_aperture(unsigned int num_context_bank)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_MP,
+		.cmd = QCOM_SCM_MP_CP_SMMU_APERTURE_ID,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = 0xffff0000
+				| ((QCOM_SCM_CP_APERTURE_REG & 0xff) << 8)
+				| (num_context_bank & 0xff),
+		.args[1] = 0xffffffff,
+		.args[2] = 0xffffffff,
+		.args[3] = 0xffffffff,
+		.arginfo = QCOM_SCM_ARGS(4),
+	};
+
+	return qcom_scm_call(__scm->dev, &desc, NULL);
+
+}
+EXPORT_SYMBOL_GPL(qcom_scm_kgsl_set_smmu_aperture);
+
+int qcom_scm_kgsl_init_regs(u32 gpu_req)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_GPU,
+		.cmd = QCOM_SCM_SVC_GPU_INIT_REGS,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = gpu_req,
+		.arginfo = QCOM_SCM_ARGS(1),
+	};
+
+	return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_kgsl_init_regs);
+
+int qcom_scm_multi_kgsl_init_regs(u32 gpu_req, u32 cmd)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_GPU,
+		.cmd = cmd,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = gpu_req,
+		.arginfo = QCOM_SCM_ARGS(1),
+	};
+
+	return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_multi_kgsl_init_regs);
+
+int qcom_scm_invoke_smc(phys_addr_t in_buf, size_t in_buf_size,
+		phys_addr_t out_buf, size_t out_buf_size, int32_t *result,
+		u64 *response_type, unsigned int *data)
+{
+	int ret;
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_SMCINVOKE,
+		.cmd = QCOM_SCM_SMCINVOKE_INVOKE,
+		.owner = ARM_SMCCC_OWNER_TRUSTED_OS,
+		.args[0] = in_buf,
+		.args[1] = in_buf_size,
+		.args[2] = out_buf,
+		.args[3] = out_buf_size,
+		.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW, QCOM_SCM_VAL,
+					QCOM_SCM_RW, QCOM_SCM_VAL),
+	};
+	struct qcom_scm_res res;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	if (result)
+		*result = res.result[1];
+
+	if (response_type)
+		*response_type = res.result[0];
+
+	if (data)
+		*data = res.result[2];
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_invoke_smc);
+
+int qcom_scm_invoke_smc_legacy(phys_addr_t in_buf, size_t in_buf_size,
+		phys_addr_t out_buf, size_t out_buf_size, int32_t *result,
+		u64 *response_type, unsigned int *data)
+{
+	int ret;
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_SMCINVOKE,
+		.cmd = QCOM_SCM_SMCINVOKE_INVOKE_LEGACY,
+		.owner = ARM_SMCCC_OWNER_TRUSTED_OS,
+		.args[0] = in_buf,
+		.args[1] = in_buf_size,
+		.args[2] = out_buf,
+		.args[3] = out_buf_size,
+		.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW, QCOM_SCM_VAL,
+					QCOM_SCM_RW, QCOM_SCM_VAL),
+	};
+
+	struct qcom_scm_res res;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	if (result)
+		*result = res.result[1];
+
+	if (response_type)
+		*response_type = res.result[0];
+
+	if (data)
+		*data = res.result[2];
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_invoke_smc_legacy);
+
+int qcom_scm_invoke_callback_response(phys_addr_t out_buf,
+	size_t out_buf_size, int32_t *result, u64 *response_type,
+	unsigned int *data)
+{
+	int ret;
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_SMCINVOKE,
+		.cmd = QCOM_SCM_SMCINVOKE_CB_RSP,
+		.owner = ARM_SMCCC_OWNER_TRUSTED_OS,
+		.args[0] = out_buf,
+		.args[1] = out_buf_size,
+		.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_RW, QCOM_SCM_VAL),
+	};
+	struct qcom_scm_res res;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	if (result)
+		*result = res.result[1];
+
+	if (response_type)
+		*response_type = res.result[0];
+
+	if (data)
+		*data = res.result[2];
+
+	return ret;
+
+}
+EXPORT_SYMBOL_GPL(qcom_scm_invoke_callback_response);
+
+/**
+ * qcm_scm_sec_wdog_deactivate() - Deactivate secure watchdog
+ */
+int qcom_scm_sec_wdog_deactivate(void)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_BOOT,
+		.cmd = QCOM_SCM_BOOT_SEC_WDOG_DIS,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = 1,
+		.arginfo = QCOM_SCM_ARGS(1),
+	};
+
+	return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_sec_wdog_deactivate);
+
+/**
+ * qcom_scm_sec_wdog_trigger() - Trigger secure watchdog
+ */
+int qcom_scm_sec_wdog_trigger(void)
+{
+	int ret;
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_BOOT,
+		.cmd = QCOM_SCM_BOOT_SEC_WDOG_TRIGGER,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = 0,
+		.arginfo = QCOM_SCM_ARGS(1),
+	};
+	struct qcom_scm_res res;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	return ret ? : res.result[0];
+}
+EXPORT_SYMBOL_GPL(qcom_scm_sec_wdog_trigger);
+
+/**
+ * qcom_scm_spin_cpu(void) - spin on cpu
+ */
+int qcom_scm_spin_cpu(void)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_BOOT,
+		.cmd = QCOM_SCM_BOOT_SPIN_CPU,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = 0,
+		.arginfo = QCOM_SCM_ARGS(1),
+	};
+
+	return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_spin_cpu);
+
+int qcom_scm_ddrbw_profiler(phys_addr_t in_buf, size_t in_buf_size,
+			    phys_addr_t out_buf, size_t out_buf_size)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_INFO,
+		.cmd = QCOM_SCM_INFO_BW_PROF_ID,
+		.owner = ARM_SMCCC_OWNER_SIP,
+	};
+
+	desc.args[0] = in_buf;
+	desc.args[1] = in_buf_size;
+	desc.args[2] = out_buf;
+	desc.args[3] = out_buf_size;
+	desc.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW, QCOM_SCM_VAL,
+				     QCOM_SCM_RW, QCOM_SCM_VAL);
+
+	return qcom_scm_call(__scm ? __scm->dev : NULL, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_ddrbw_profiler);
+
+/**
+ * qcom_scm_she_op() - request TZ SHE (Secure Hardware Extension) service
+ *		       to perform crypto operations based on SHE tables.
+ */
+int qcom_scm_she_op(u64 _arg1, u64 _arg2, u64 _arg3, u64 _arg4, u64 *res1)
+{
+	int ret;
+
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_SHE,
+		.cmd = QCOM_SCM_SHE_ID,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_VAL, QCOM_SCM_VAL,
+				     QCOM_SCM_RW, QCOM_SCM_VAL),
+	};
+	struct qcom_scm_res res;
+
+	desc.args[0] = _arg1;
+	desc.args[1] = _arg2;
+	desc.args[2] = _arg3;
+	desc.args[3] = _arg4;
+
+	ret = qcom_scm_call_atomic(__scm ? __scm->dev : NULL, &desc, &res);
+
+	/* The result from SHE service must be handled by the SHE client */
+	if (res1)
+		*res1 = res.result[0];
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_she_op);
+
+int qcom_scm_camera_update_camnoc_qos(uint32_t use_case_id,
+	uint32_t cam_qos_cnt, struct qcom_scm_camera_qos *cam_qos)
+{
+	int ret;
+	dma_addr_t payload_phys;
+	u32 *payload_buf = NULL;
+	u32 payload_size = 0;
+
+	if ((cam_qos_cnt > QCOM_SCM_CAMERA_MAX_QOS_CNT) || (cam_qos_cnt && !cam_qos)) {
+		pr_err("Invalid input SmartQoS count: %d\n", cam_qos_cnt);
+		return -EINVAL;
+	}
+
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_CAMERA,
+		.cmd = QCOM_SCM_CAMERA_UPDATE_CAMNOC_QOS,
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = use_case_id,
+		.args[2] = payload_size,
+		.arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_VAL, QCOM_SCM_RW, QCOM_SCM_VAL),
+	};
+
+	payload_size = cam_qos_cnt * sizeof(struct qcom_scm_camera_qos);
+
+	/* fill all required qos settings */
+	if (use_case_id && payload_size && cam_qos) {
+		payload_buf = dma_alloc_coherent(__scm->dev,
+						 payload_size, &payload_phys, GFP_KERNEL);
+		if (!payload_buf)
+			return -ENOMEM;
+
+		memcpy(payload_buf, cam_qos, payload_size);
+		desc.args[1] = payload_phys;
+		desc.args[2] = payload_size;
+
+	}
+	ret = qcom_scm_call(__scm->dev, &desc, NULL);
+
+	if (payload_buf)
+		dma_free_coherent(__scm->dev, payload_size, payload_buf, payload_phys);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_scm_camera_update_camnoc_qos);
+
+int qcom_scm_assign_dump_table_region(bool is_assign, phys_addr_t addr, size_t size)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_SVC_UTIL,
+		.cmd = QCOM_SCM_UTIL_DUMP_TABLE_ASSIGN,
+		.arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_VAL, QCOM_SCM_VAL, QCOM_SCM_VAL),
+		.owner = ARM_SMCCC_OWNER_SIP,
+		.args[0] = is_assign,
+		.args[1] = addr,
+		.args[2] = size,
+	};
+
+	return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL_GPL(qcom_scm_assign_dump_table_region);
+
+int qcom_scm_load_ccu_qup_fw(u32 qup_type)
+{
+	struct qcom_scm_desc desc = {
+		.svc = QCOM_SCM_TZ_CCU_QUP,
+		.cmd = QCOM_SCM_LOAD_CCU_QUP_FW,
+		.arginfo = QCOM_SCM_ARGS(1),
+		.args[0] = qup_type,
+		.owner = ARM_SMCCC_OWNER_SIP,
+	};
+	struct qcom_scm_res res;
+	int ret;
+
+	ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+	return ret ? : res.result[0];
+}
+EXPORT_SYMBOL_GPL(qcom_scm_load_ccu_qup_fw);
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/qcom_tzmem.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/qcom_tzmem.c
@@ -0,0 +1,758 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Memory allocator for buffers shared with the TrustZone.
+ *
+ * Copyright (C) 2023-2024 Linaro Ltd.
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt) "qcom_tzmem: [%d][%s]: " fmt, __LINE__,  __func__
+
+#include <linux/bug.h>
+#include <linux/cleanup.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <dt-bindings/firmware/qcom,scm.h>
+#include <linux/genalloc.h>
+#include <linux/gfp.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/radix-tree.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/of_platform.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/platform_device.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/device.h>
+
+#include "qcom_tzmem.h"
+
+struct qcom_tzmem_pool {
+	struct gen_pool *genpool;
+	struct list_head areas;
+	enum qcom_tzmem_policy policy;
+	size_t increment;
+	size_t max_size;
+	spinlock_t lock;
+};
+
+struct qcom_tzmem_chunk {
+	phys_addr_t paddr;
+	size_t size;
+	struct qcom_tzmem_pool *owner;
+};
+#define MAXSHMVMS 4
+#define PERM_BITS 3
+#define VM_BITS 16
+#define VMID_NUM_HYP 0
+#define VMID_NUM_HLOS 1
+#define SELF_OWNER_BIT 1
+#define SHM_NUM_VM_SHIFT 9
+#define SHM_VM_MASK 0xFFFF
+#define SHM_PERM_MASK 0x7
+
+#define SHMBRIDGE_E_NOT_SUPPORTED 4	/* SHMbridge is not implemented */
+
+#define AC_ERR_SHARED_MEMORY_SINGLE_SOURCE 15
+
+/* ns_vmids */
+#define UPDATE_NS_VMIDS(ns_vmids, id)	\
+				(((uint64_t)(ns_vmids) << VM_BITS) \
+				| ((uint64_t)(id) & SHM_VM_MASK))
+
+/* ns_perms */
+#define UPDATE_NS_PERMS(ns_perms, perm)	\
+				(((uint64_t)(ns_perms) << PERM_BITS) \
+				| ((uint64_t)(perm) & SHM_PERM_MASK))
+
+/* pfn_and_ns_perm_flags = paddr | ns_perms */
+#define UPDATE_PFN_AND_NS_PERM_FLAGS(paddr, ns_perms)	\
+				((uint64_t)(paddr) | (ns_perms))
+
+
+/* ipfn_and_s_perm_flags = ipaddr | tz_perm */
+#define UPDATE_IPFN_AND_S_PERM_FLAGS(ipaddr, tz_perm)	\
+				((uint64_t)(ipaddr) | (uint64_t)(tz_perm))
+
+/* size_and_flags when dest_vm is not HYP */
+#define UPDATE_SIZE_AND_FLAGS(size, destnum)	\
+				((size) | (destnum) << SHM_NUM_VM_SHIFT)
+
+struct bridge_list {
+	struct list_head head;
+	struct mutex lock;
+};
+
+struct bridge_list_entry {
+	struct list_head list;
+	phys_addr_t paddr;
+	uint64_t handle;
+	int32_t ref_count;
+};
+
+static struct device *qcom_tzmem_dev;
+static RADIX_TREE(qcom_tzmem_chunks, GFP_ATOMIC);
+static DEFINE_SPINLOCK(qcom_tzmem_chunks_lock);
+
+#if IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_GENERIC)
+
+static int qcom_tzmem_init(void)
+{
+	return 0;
+}
+
+static int32_t __qcom_tzmem_register(phys_addr_t paddr, size_t size, uint32_t *ns_vmid_list,
+		uint32_t *ns_vm_perm_list, uint32_t ns_vmid_num, uint32_t tz_perm, uint64_t *handle)
+{
+	return 0;
+}
+
+static int32_t __qcom_tzmem_deregister(uint64_t handle)
+{
+	return 0;
+}
+
+#elif IS_ENABLED(CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE)
+
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/of.h>
+
+#define QCOM_SHM_BRIDGE_NUM_VM_SHIFT 9
+
+static bool qcom_tzmem_using_shm_bridge;
+static struct bridge_list bridge_list_head;
+
+/* List of machines that are known to not support SHM bridge correctly. */
+static const char *const qcom_tzmem_blacklist[] = {
+	"qcom,sc8180x",
+	NULL
+};
+
+static int qcom_tzmem_init(void)
+{
+	const char *const *platform;
+	int ret;
+
+	for (platform = qcom_tzmem_blacklist; *platform; platform++) {
+		if (of_machine_is_compatible(*platform))
+			goto notsupp;
+	}
+
+	ret = qcom_scm_shm_bridge_enable();
+	if (ret == -EOPNOTSUPP)
+		goto notsupp;
+
+	if (!ret)
+		qcom_tzmem_using_shm_bridge = true;
+
+	mutex_init(&bridge_list_head.lock);
+	INIT_LIST_HEAD(&bridge_list_head.head);
+
+	return ret;
+
+notsupp:
+	dev_info(qcom_tzmem_dev, "SHM Bridge not supported\n");
+	return 0;
+}
+
+int qcom_tzmem_init_area(struct qcom_tzmem_area *area)
+{
+	u64 pfn_and_ns_perm, ipfn_and_s_perm, size_and_flags;
+	int ret;
+
+	if (!qcom_tzmem_using_shm_bridge)
+		return 0;
+
+	pfn_and_ns_perm = (u64)area->paddr | QCOM_SCM_PERM_RW;
+	ipfn_and_s_perm = (u64)area->paddr | QCOM_SCM_PERM_RW;
+	size_and_flags = area->size | (1 << QCOM_SHM_BRIDGE_NUM_VM_SHIFT);
+
+	u64 *handle __free(kfree) = kzalloc(sizeof(*handle), GFP_KERNEL);
+	if (!handle)
+		return -ENOMEM;
+
+	ret = qcom_scm_shm_bridge_create(qcom_tzmem_dev, pfn_and_ns_perm,
+					 ipfn_and_s_perm, size_and_flags,
+					 QCOM_SCM_VMID_HLOS, handle);
+	if (ret)
+		return ret;
+
+	area->priv = no_free_ptr(handle);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_init_area);
+
+void qcom_tzmem_cleanup_area(struct qcom_tzmem_area *area)
+{
+	u64 *handle = area->priv;
+
+	if (!qcom_tzmem_using_shm_bridge)
+		return;
+
+	qcom_scm_shm_bridge_delete(qcom_tzmem_dev, *handle);
+	kfree(handle);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_cleanup_area);
+
+static int32_t qcom_tzmem_list_add_locked(phys_addr_t paddr,
+						uint64_t handle)
+{
+	struct bridge_list_entry *entry;
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+	entry->handle = handle;
+	entry->paddr = paddr;
+	entry->ref_count = 0;
+
+	list_add_tail(&entry->list, &bridge_list_head.head);
+	return 0;
+}
+
+static void qcom_tzmem_list_del_locked(uint64_t handle)
+{
+	struct bridge_list_entry *entry;
+
+	list_for_each_entry(entry, &bridge_list_head.head, list) {
+		if (entry->handle == handle) {
+			list_del(&entry->list);
+			kfree(entry);
+			break;
+		}
+	}
+}
+
+/**
+ * qcom_tzmem_list_dec_refcount_locked: Decrement the reference count of
+ *					registered shmbridge and if refcount reached to zero delete
+ *					the shmbridge (i.e send a scm call to tz and remove that
+ *					from out local list too.
+ *					API suppose to be called in a locked enviorment.
+ *
+ * Return 0 in case of success else error code in case of failure
+ */
+static int32_t qcom_tzmem_list_dec_refcount_locked(uint64_t handle)
+{
+	struct bridge_list_entry *entry;
+	int32_t ret = -EINVAL;
+
+	list_for_each_entry(entry, &bridge_list_head.head, list)
+		if (entry->handle == handle) {
+
+			if (entry->ref_count > 0) {
+				/* decrement reference count */
+				entry->ref_count--;
+				pr_debug("bridge on %lld exists decrease refcount :%d\n",
+						handle, entry->ref_count);
+
+				if (entry->ref_count == 0) {
+				/* All valid reference are freed, it's time to delete the bridge */
+					//ret = qcom_scm_delete_shm_bridge(handle);
+					ret = qcom_scm_shm_bridge_delete(qcom_tzmem_dev, handle);
+					if (ret) {
+						pr_err("Failed to del bridge %lld, ret = %d\n",
+								handle, ret);
+						/* restore reference count in case of failure */
+						entry->ref_count++;
+						goto exit;
+					}
+					qcom_tzmem_list_del_locked(handle);
+				}
+				ret = 0;
+			} else
+				pr_err("ref_count should not be negative handle %lld , refcount: %d\n",
+					 handle, entry->ref_count);
+			break;
+		}
+exit:
+	if (ret == -EINVAL)
+		pr_err("Not able to find bridge handle %lld in map\n", handle);
+
+	return ret;
+}
+
+/**
+ * qcom_tzmem_list_inc_refcount_locked: Increment the ref count in case if
+ *					we try to register a pre-registered phyaddr with shmbridge
+ *					and provide a valid handle to the caller API which was
+ *					passed by caller as a pointer.
+ *					API suppose to be called in a locked enviorment.
+ *
+ * Return 0 in case of success else error code in case of failure.
+ */
+static int32_t qcom_tzmem_list_inc_refcount_locked(phys_addr_t paddr, uint64_t *handle)
+{
+	struct bridge_list_entry *entry;
+	int32_t ret = -EINVAL;
+
+	list_for_each_entry(entry, &bridge_list_head.head, list)
+		if (entry->paddr == paddr) {
+
+			entry->ref_count++;
+			pr_debug("%s: bridge on %llx exists increase refcount :%d\n",
+				__func__, (uint64_t)paddr, entry->ref_count);
+
+			/* update handle in case we found paddr already exist */
+			*handle = entry->handle;
+			ret = 0;
+			break;
+		}
+	if (ret)
+		pr_err("Not able to find bridge paddr %llx in map\n", (uint64_t)paddr);
+	return ret;
+}
+
+static int32_t qcom_tzmem_query_locked(phys_addr_t paddr)
+{
+	struct bridge_list_entry *entry;
+
+	list_for_each_entry(entry, &bridge_list_head.head, list)
+		if (entry->paddr == paddr) {
+			pr_debug("A bridge on %llx exists\n", (uint64_t)paddr);
+			return -EEXIST;
+		}
+	return 0;
+}
+
+/* Register paddr & size as a bridge, return bridge handle */
+static int32_t __qcom_tzmem_register(
+		phys_addr_t paddr,
+		size_t size,
+		uint32_t *ns_vmid_list,
+		uint32_t *ns_vm_perm_list,
+		uint32_t ns_vmid_num,
+		uint32_t tz_perm,
+		uint64_t *handle)
+
+{
+	int32_t ret = 0;
+	uint64_t pfn_and_ns_perm_flags = 0;
+	uint64_t ipfn_and_s_perm_flags = 0;
+	uint64_t size_and_flags = 0;
+	uint64_t ns_perms = 0;
+	uint64_t ns_vmids = 0;
+	int i = 0;
+
+	if (!qcom_tzmem_using_shm_bridge)
+		return 0;
+
+	if (!handle || !ns_vmid_list || !ns_vm_perm_list ||
+				ns_vmid_num > MAXSHMVMS) {
+		pr_err("invalid input parameters\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&bridge_list_head.lock);
+	ret = qcom_tzmem_query_locked(paddr);
+	if (ret) {
+		pr_debug("found 0%llu already exist with shmbridge\n", paddr);
+		goto bridge_exist;
+	}
+
+	for (i = 0; i < ns_vmid_num; i++) {
+		ns_perms = UPDATE_NS_PERMS(ns_perms, ns_vm_perm_list[i]);
+		ns_vmids = UPDATE_NS_VMIDS(ns_vmids, ns_vmid_list[i]);
+	}
+
+	pfn_and_ns_perm_flags = UPDATE_PFN_AND_NS_PERM_FLAGS(paddr, ns_perms);
+	ipfn_and_s_perm_flags = UPDATE_IPFN_AND_S_PERM_FLAGS(paddr, tz_perm);
+	size_and_flags = UPDATE_SIZE_AND_FLAGS(size, ns_vmid_num);
+
+	if (ns_vmid_num == 0) {
+		size_and_flags |= SELF_OWNER_BIT << 1;
+		size_and_flags |= QCOM_SCM_PERM_RW << 2;
+	}
+
+	pr_debug("%s: desc.args[0] %llx, args[1] %llx, args[2] %llx, args[3] %llx\n",
+		__func__, pfn_and_ns_perm_flags, ipfn_and_s_perm_flags,
+		size_and_flags, ns_vmids);
+
+	ret = qcom_scm_shm_bridge_create(qcom_tzmem_dev, pfn_and_ns_perm_flags,
+			ipfn_and_s_perm_flags, size_and_flags, ns_vmids,
+			handle);
+
+	if (ret) {
+		pr_err("Shm creation failed, ret: %d, NS PA|Perm: 0x%llx, size|flags: 0x%llx, ns_vmids: 0x%llx\n",
+			ret, pfn_and_ns_perm_flags, size_and_flags, ns_vmids);
+
+		/*
+		 * If bridge is already existing and we are not real owner also paddr
+		 * not exist in our map we will add an entry in our map and go for
+		 * deregister for this since QTEE also maintain ref_count. So for this
+		 * we should deregister to decrease ref_count in QTEE.
+		 */
+		if (ret == AC_ERR_SHARED_MEMORY_SINGLE_SOURCE)
+			pr_err("bridge %llu exist but not registered in our map\n", paddr);
+		else {
+			ret = -EINVAL;
+			goto exit;
+		}
+	}
+
+	ret = qcom_tzmem_list_add_locked(paddr, *handle);
+bridge_exist:
+	ret = qcom_tzmem_list_inc_refcount_locked(paddr, handle);
+exit:
+	mutex_unlock(&bridge_list_head.lock);
+	return ret;
+}
+
+/* Deregister bridge */
+static int32_t __qcom_tzmem_deregister(uint64_t handle)
+{
+	int32_t ret = 0;
+
+	if (!qcom_tzmem_using_shm_bridge)
+		return 0;
+
+	mutex_lock(&bridge_list_head.lock);
+	ret = qcom_tzmem_list_dec_refcount_locked(handle);
+	mutex_unlock(&bridge_list_head.lock);
+
+	return ret;
+}
+
+#endif /* CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE */
+
+int32_t qcom_tzmem_register(phys_addr_t paddr, size_t size, uint32_t *ns_vmid_list,
+		uint32_t *ns_vm_perm_list, uint32_t ns_vmid_num, uint32_t tz_perm, uint64_t *handle)
+{
+	return __qcom_tzmem_register(paddr, size, ns_vmid_list, ns_vm_perm_list,
+			ns_vmid_num, tz_perm, handle);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_register);
+
+int32_t qcom_tzmem_deregister(uint64_t handle)
+{
+	return __qcom_tzmem_deregister(handle);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_deregister);
+
+static int qcom_tzmem_pool_add_memory(struct qcom_tzmem_pool *pool,
+				      size_t size, gfp_t gfp)
+{
+	int ret;
+
+	struct qcom_tzmem_area *area __free(kfree) = kzalloc(sizeof(*area),
+							     gfp);
+	if (!area)
+		return -ENOMEM;
+
+	area->size = PAGE_ALIGN(size);
+
+	area->vaddr = dma_alloc_coherent(qcom_tzmem_dev, area->size,
+					 &area->paddr, gfp);
+	if (!area->vaddr)
+		return -ENOMEM;
+
+	ret = qcom_tzmem_init_area(area);
+	if (ret) {
+		dma_free_coherent(qcom_tzmem_dev, area->size,
+				  area->vaddr, area->paddr);
+		return ret;
+	}
+
+	ret = gen_pool_add_virt(pool->genpool, (unsigned long)area->vaddr,
+				(phys_addr_t)area->paddr, size, -1);
+	if (ret) {
+		dma_free_coherent(qcom_tzmem_dev, area->size,
+				  area->vaddr, area->paddr);
+		return ret;
+	}
+
+	scoped_guard(spinlock_irqsave, &pool->lock)
+		list_add_tail(&area->list, &pool->areas);
+
+	area = NULL;
+	return 0;
+}
+
+/**
+ * qcom_tzmem_pool_new() - Create a new TZ memory pool.
+ * @config: Pool configuration.
+ *
+ * Create a new pool of memory suitable for sharing with the TrustZone.
+ *
+ * Must not be used in atomic context.
+ *
+ * Return: New memory pool address or ERR_PTR() on error.
+ */
+struct qcom_tzmem_pool *
+qcom_tzmem_pool_new(const struct qcom_tzmem_pool_config *config)
+{
+	int ret = -ENOMEM;
+
+	might_sleep();
+
+	switch (config->policy) {
+	case QCOM_TZMEM_POLICY_STATIC:
+		if (!config->initial_size)
+			return ERR_PTR(-EINVAL);
+		break;
+	case QCOM_TZMEM_POLICY_MULTIPLIER:
+		if (!config->increment)
+			return ERR_PTR(-EINVAL);
+		break;
+	case QCOM_TZMEM_POLICY_ON_DEMAND:
+		break;
+	default:
+		return ERR_PTR(-EINVAL);
+	}
+
+	struct qcom_tzmem_pool *pool __free(kfree) = kzalloc(sizeof(*pool),
+							     GFP_KERNEL);
+	if (!pool)
+		return ERR_PTR(-ENOMEM);
+
+	pool->genpool = gen_pool_create(PAGE_SHIFT, -1);
+	if (!pool->genpool)
+		return ERR_PTR(-ENOMEM);
+
+	gen_pool_set_algo(pool->genpool, gen_pool_best_fit, NULL);
+
+	pool->policy = config->policy;
+	pool->increment = config->increment;
+	pool->max_size = config->max_size;
+	INIT_LIST_HEAD(&pool->areas);
+	spin_lock_init(&pool->lock);
+
+	if (config->initial_size) {
+		ret = qcom_tzmem_pool_add_memory(pool, config->initial_size,
+						 GFP_KERNEL);
+		if (ret) {
+			gen_pool_destroy(pool->genpool);
+			return ERR_PTR(ret);
+		}
+	}
+
+	return_ptr(pool);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_pool_new);
+
+/**
+ * qcom_tzmem_pool_free() - Destroy a TZ memory pool and free all resources.
+ * @pool: Memory pool to free.
+ *
+ * Must not be called if any of the allocated chunks has not been freed.
+ * Must not be used in atomic context.
+ */
+void qcom_tzmem_pool_free(struct qcom_tzmem_pool *pool)
+{
+	struct qcom_tzmem_area *area, *next;
+	struct qcom_tzmem_chunk *chunk;
+	struct radix_tree_iter iter;
+	bool non_empty = false;
+	void __rcu **slot;
+
+	might_sleep();
+
+	if (!pool)
+		return;
+
+	scoped_guard(spinlock_irqsave, &qcom_tzmem_chunks_lock) {
+		radix_tree_for_each_slot(slot, &qcom_tzmem_chunks, &iter, 0) {
+			chunk = radix_tree_deref_slot_protected(slot,
+						&qcom_tzmem_chunks_lock);
+
+			if (chunk->owner == pool)
+				non_empty = true;
+		}
+	}
+
+	WARN(non_empty, "Freeing TZ memory pool with memory still allocated");
+
+	list_for_each_entry_safe(area, next, &pool->areas, list) {
+		list_del(&area->list);
+		qcom_tzmem_cleanup_area(area);
+		dma_free_coherent(qcom_tzmem_dev, area->size,
+				  area->vaddr, area->paddr);
+		kfree(area);
+	}
+
+	gen_pool_destroy(pool->genpool);
+	kfree(pool);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_pool_free);
+
+static void devm_qcom_tzmem_pool_free(void *data)
+{
+	struct qcom_tzmem_pool *pool = data;
+
+	qcom_tzmem_pool_free(pool);
+}
+
+/**
+ * devm_qcom_tzmem_pool_new() - Managed variant of qcom_tzmem_pool_new().
+ * @dev: Device managing this resource.
+ * @config: Pool configuration.
+ *
+ * Must not be used in atomic context.
+ *
+ * Return: Address of the managed pool or ERR_PTR() on failure.
+ */
+struct qcom_tzmem_pool *
+devm_qcom_tzmem_pool_new(struct device *dev,
+			 const struct qcom_tzmem_pool_config *config)
+{
+	struct qcom_tzmem_pool *pool;
+	int ret;
+
+	pool = qcom_tzmem_pool_new(config);
+	if (IS_ERR(pool))
+		return pool;
+
+	ret = devm_add_action_or_reset(dev, devm_qcom_tzmem_pool_free, pool);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return pool;
+}
+EXPORT_SYMBOL_GPL(devm_qcom_tzmem_pool_new);
+
+static bool qcom_tzmem_try_grow_pool(struct qcom_tzmem_pool *pool,
+				     size_t requested, gfp_t gfp)
+{
+	size_t current_size = gen_pool_size(pool->genpool);
+
+	if (pool->max_size && (current_size + requested) > pool->max_size)
+		return false;
+
+	switch (pool->policy) {
+	case QCOM_TZMEM_POLICY_STATIC:
+		return false;
+	case QCOM_TZMEM_POLICY_MULTIPLIER:
+		requested = current_size * pool->increment;
+		break;
+	case QCOM_TZMEM_POLICY_ON_DEMAND:
+		break;
+	}
+
+	return !qcom_tzmem_pool_add_memory(pool, requested, gfp);
+}
+
+/**
+ * qcom_tzmem_alloc() - Allocate a memory chunk suitable for sharing with TZ.
+ * @pool: TZ memory pool from which to allocate memory.
+ * @size: Number of bytes to allocate.
+ * @gfp: GFP flags.
+ *
+ * Can be used in any context.
+ *
+ * Return:
+ * Address of the allocated buffer or NULL if no more memory can be allocated.
+ * The buffer must be released using qcom_tzmem_free().
+ */
+void *qcom_tzmem_alloc(struct qcom_tzmem_pool *pool, size_t size, gfp_t gfp)
+{
+	unsigned long vaddr;
+	int ret;
+
+	if (!size)
+		return NULL;
+
+	size = PAGE_ALIGN(size);
+
+	struct qcom_tzmem_chunk *chunk __free(kfree) = kzalloc(sizeof(*chunk),
+							       gfp);
+	if (!chunk)
+		return NULL;
+
+again:
+	vaddr = gen_pool_alloc(pool->genpool, size);
+	if (!vaddr) {
+		if (qcom_tzmem_try_grow_pool(pool, size, gfp))
+			goto again;
+
+		return NULL;
+	}
+
+	chunk->paddr = gen_pool_virt_to_phys(pool->genpool, vaddr);
+	chunk->size = size;
+	chunk->owner = pool;
+
+	scoped_guard(spinlock_irqsave, &qcom_tzmem_chunks_lock) {
+		ret = radix_tree_insert(&qcom_tzmem_chunks, vaddr, chunk);
+		if (ret) {
+			gen_pool_free(pool->genpool, vaddr, size);
+			return NULL;
+		}
+
+		chunk = NULL;
+	}
+
+	return (void *)vaddr;
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_alloc);
+
+/**
+ * qcom_tzmem_free() - Release a buffer allocated from a TZ memory pool.
+ * @vaddr: Virtual address of the buffer.
+ *
+ * Can be used in any context.
+ */
+void qcom_tzmem_free(void *vaddr)
+{
+	struct qcom_tzmem_chunk *chunk;
+
+	scoped_guard(spinlock_irqsave, &qcom_tzmem_chunks_lock)
+		chunk = radix_tree_delete_item(&qcom_tzmem_chunks,
+					       (unsigned long)vaddr, NULL);
+
+	if (!chunk) {
+		WARN(1, "Virtual address %p not owned by TZ memory allocator",
+		     vaddr);
+		return;
+	}
+
+	scoped_guard(spinlock_irqsave, &chunk->owner->lock)
+		gen_pool_free(chunk->owner->genpool, (unsigned long)vaddr,
+			      chunk->size);
+	kfree(chunk);
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_free);
+
+/**
+ * qcom_tzmem_to_phys() - Map the virtual address of a TZ buffer to physical.
+ * @vaddr: Virtual address of the buffer allocated from a TZ memory pool.
+ *
+ * Can be used in any context. The address must have been returned by a call
+ * to qcom_tzmem_alloc().
+ *
+ * Returns: Physical address of the buffer.
+ */
+phys_addr_t qcom_tzmem_to_phys(void *vaddr)
+{
+	struct qcom_tzmem_chunk *chunk;
+
+	guard(spinlock_irqsave)(&qcom_tzmem_chunks_lock);
+
+	chunk = radix_tree_lookup(&qcom_tzmem_chunks, (unsigned long)vaddr);
+	if (!chunk)
+		return 0;
+
+	return chunk->paddr;
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_to_phys);
+
+int qcom_tzmem_enable(struct device *dev)
+{
+	if (qcom_tzmem_dev)
+		return -EBUSY;
+
+	qcom_tzmem_dev = dev;
+
+	return qcom_tzmem_init();
+}
+EXPORT_SYMBOL_GPL(qcom_tzmem_enable);
+
+MODULE_DESCRIPTION("TrustZone memory allocator for Qualcomm firmware drivers");
+MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski@linaro.org>");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/qcom_tzmem.h
+++ linux-qcom-6.8.0/drivers/firmware/qcom/qcom_tzmem.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2023-2024 Linaro Ltd.
+ */
+
+#ifndef __QCOM_TZMEM_PRIV_H
+#define __QCOM_TZMEM_PRIV_H
+
+struct device;
+
+int qcom_tzmem_enable(struct device *dev);
+
+#endif /* __QCOM_TZMEM_PRIV_H */
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/Kconfig
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/Kconfig
@@ -0,0 +1,44 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config QCOM_SI_CORE
+	tristate "Secure QTEE Communication Support"
+	depends on QCOM_SCM_ADDON && QCOM_TZMEM
+	help
+	  Enable SI-CORE driver which supports capability based secure
+	  communication between QTEE and VM. Using SI-CORE, kernel can
+	  issue calls to QTEE or TAs to request a service or exposes services
+	  to QTEE and TAs. The SI-CORE implements the necessary marshaling of
+	  messages with QTEE.
+
+config QCOM_SI_CORE_ADCI
+	bool "Use ADCI thread to cater service requests from other VMs"
+	depends on QCOM_SI_CORE
+	help
+	  Use a kernel thread to register callback service to QTEE that
+	  will cater requests initiated by other VMs requiring services
+	  hosted by primary VM.
+
+	  Enable if there are multiple VMs and services are hosted only
+	  by primary VM.
+
+config QCOM_SI_CORE_WQ
+	bool "Use direct invocation for RELEASE requests"
+	depends on QCOM_SI_CORE
+	help
+	  Use a kernel thread to issue RELEASE request to QTEE and TAs
+	  instead of using asynchronous messages. It may slow down the system
+	  and prone to failure as it uses direct invocation which requires
+	  extra resources from QTEE.
+
+	  Enable if only QTEE does not support asynchronous message.
+
+config QCOM_SI_CORE_MEM_OBJECT
+	tristate "Add support for memory object"
+	depends on QCOM_SI_CORE
+	help
+	  Enable support for memory object. This provide an interface
+	  to export or sharing memory with QTEE. It allows kernel clients
+	  to create memory object and do the necessary mapping and unmapping
+	  using QTEE shared memory driver.
+
+source "drivers/firmware/qcom/si_core/si_core_xts/Kconfig"
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/Makefile
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/Makefile
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+si-core-adci-$(CONFIG_QCOM_SI_CORE_ADCI) += si_core_adci.o
+si-core-wq-$(CONFIG_QCOM_SI_CORE_WQ) += si_core_wq.o
+si_core_module-objs := qcom_scm_invoke.o si_core_async.o si_core.o $(si-core-adci-y) $(si-core-wq-y)
+obj-$(CONFIG_QCOM_SI_CORE) += si_core_module.o
+
+# Add si_core extenstions here!
+
+obj-$(CONFIG_QCOM_SI_CORE_MEM_OBJECT) += mem_object.o
+mem_object-objs := xts/mem-object.o
+
+obj-$(CONFIG_QCOM_SI_CORE_XTS) += si_core_xts/
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/qcom_scm_invoke.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/qcom_scm_invoke.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/delay.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+
+#include "si_core.h"
+
+/* 6 Sec. retry seems reasonable!? */
+#define SCM_EBUSY_WAIT_MS 30
+#define SCM_EBUSY_MAX_RETRY 200
+
+int si_object_invoke_ctx_invoke(struct si_object_invoke_ctx *oic,
+	int *result, u64 *response_type, unsigned int *data)
+{
+	int ret, i = 0;
+
+	/* TODO. buffers always coherent!? */
+
+	do {
+		/* Direct invocation of callback!? */
+		if (!(oic->flags & OIC_FLAG_BUSY)) {
+			ret = qcom_scm_invoke_smc(oic->in.paddr,
+				oic->in.msg.size,
+				oic->out.paddr,
+				oic->out.msg.size,
+				result,
+				response_type,
+				data);
+
+		} else {
+			ret = qcom_scm_invoke_callback_response(oic->out.paddr,
+				oic->out.msg.size,
+				result,
+				response_type,
+				data);
+		}
+
+		if (ret != -EBUSY)
+			break;
+
+		msleep(SCM_EBUSY_WAIT_MS);
+
+	} while (++i < SCM_EBUSY_MAX_RETRY);
+
+	if (ret)
+		pr_err("QTEE returned with %d!\n", ret);
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/si_core.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/si_core.c
@@ -0,0 +1,1272 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt) "si-core: %s: " fmt, __func__
+
+#include <dt-bindings/firmware/qcom,scm.h>
+#include <linux/delay.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/init.h>
+#include <linux/kobject.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/xarray.h>
+
+#include "si_core.h"
+
+#if IS_ENABLED(CONFIG_QCOM_SI_CORE_ADCI)
+#include "si_core_adci.h"
+#endif
+
+/* Static 'Primordial Object' operations. */
+
+#define OBJECT_OP_YIELD	1
+#define OBJECT_OP_SLEEP	2
+
+/* 'static_si_object_primordial' always exists! */
+/* 'primordial_object_register' and 'primordial_object_release' extend it. */
+
+static struct si_object static_si_object_primordial;
+
+static int primordial_object_register(struct si_object *object);
+static void primordial_object_release(struct si_object *object);
+
+/* Marshaling API. */
+/*
+ * 'prepare_msg' Prepare input buffer for sending to QTEE.
+ * 'update_args' Parse QTEE response in input buffer.
+ * 'prepare_args' Parse QTEE request from output buffer.
+ * 'update_msg' Update output buffer with response for QTEE request.
+ *
+ * 'prepare_msg' and 'update_args' are used in direct invocation path.
+ * 'prepare_args' and 'update_msg' are used for QTEE request (callback or async).
+ */
+
+static int prepare_msg(struct si_object_invoke_ctx *oic,
+	struct si_object *object, unsigned long op, struct si_arg u[]);
+static int update_args(struct si_arg u[], struct si_object_invoke_ctx *oic);
+static int prepare_args(struct si_object_invoke_ctx *oic);
+static int update_msg(struct si_object_invoke_ctx *oic);
+
+static int next_arg_type(struct si_arg u[], int i, enum arg_type type)
+{
+	while (u[i].type != SI_AT_END && u[i].type != type)
+		i++;
+
+	return i;
+}
+
+/**
+ * args_for_each_type - Iterate over argument of given type.
+ * @i: index in @args.
+ * @args: array of arguments.
+ * @at: type of argument.
+ */
+#define args_for_each_type(i, args, at) \
+	for (i = 0, i = next_arg_type(args, i, at); \
+		args[i].type != SI_AT_END; i = next_arg_type(args, ++i, at))
+
+#define arg_for_each_input_buffer(i, args)  args_for_each_type(i, args, SI_AT_IB)
+#define arg_for_each_output_buffer(i, args) args_for_each_type(i, args, SI_AT_OB)
+#define arg_for_each_input_object(i, args)  args_for_each_type(i, args, SI_AT_IO)
+#define arg_for_each_output_object(i, args) args_for_each_type(i, args, SI_AT_OO)
+
+/* Outside this file we use 'struct si_object' to identify an object. */
+
+/* We only allocate IDs with 'QTEE_OBJ_NS_BIT' set in range
+ * ['SI_OBJECT_ID_START' .. SI_OBJECT_ID_END]. 'si_object' represents NS object.
+ * The first ID with 'QTEE_OBJ_NS_BIT' set is reserved for primordial object.
+ */
+
+#define SI_OBJECT_PRIMORDIAL	(QTEE_OBJ_NS_BIT)
+#define SI_OBJECT_ID_START		(SI_OBJECT_PRIMORDIAL + 1)
+#define SI_OBJECT_ID_END		(UINT_MAX)
+
+#define SET_SI_OBJECT(p, type, ...) __SET_SI_OBJECT(p, type, ##__VA_ARGS__, 0UL)
+#define __SET_SI_OBJECT(p, type, optr, ...) do { \
+		(p)->object_type = (type); \
+		(p)->info.object_ptr = (unsigned long)(optr); \
+		(p)->release = NULL; \
+	} while (0)
+
+struct si_object *allocate_si_object(void)
+{
+	struct si_object *object;
+
+	/* TODO. Use slab?! **/
+
+	object = kzalloc(sizeof(struct si_object), GFP_KERNEL);
+	if (object)
+		SET_SI_OBJECT(object, SI_OT_NULL);
+
+	return object;
+}
+EXPORT_SYMBOL_GPL(allocate_si_object);
+
+void free_si_object(struct si_object *object)
+{
+	kfree(object);
+}
+EXPORT_SYMBOL_GPL(free_si_object);
+
+static DEFINE_XARRAY_ALLOC(xa_si_objects);
+
+/* 'get_si_object' and 'put_si_object'. */
+
+static int __free_si_object(struct si_object *object);
+static void ____destroy_si_object(struct kref *refcount)
+{
+	struct si_object *object = container_of(refcount, struct si_object, refcount);
+
+	__free_si_object(object);
+}
+
+int get_si_object(struct si_object *object)
+{
+	if (object != NULL_SI_OBJECT &&
+		object != ROOT_SI_OBJECT)
+		return kref_get_unless_zero(&object->refcount);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(get_si_object);
+
+static struct si_object *qtee__get_si_object(unsigned int object_id)
+{
+	/* For input object QTEE guarantees their validity by not issuing any RELEASE
+	 * through out the invocation (i.e. RCU is not necessary).
+	 * The RCU is mostly here (1) if QTEE violate this rule, and (2) for output
+	 * object where QTEE did not issue an appropriate RETAIN.
+	 */
+
+	XA_STATE(xas, &xa_si_objects, object_id);
+	struct si_object *object;
+
+	rcu_read_lock();
+	do {
+		object = xas_load(&xas);
+		if (xa_is_zero(object)) {
+
+			/* So that do not retry for 'XA_ZERO_ENTRY'. */
+			object = NULL;
+		}
+
+	} while (xas_retry(&xas, object));
+
+	if (!get_si_object(object))
+		object = NULL;
+
+	rcu_read_unlock();
+
+	return object;
+}
+
+struct si_object *qtee_get_si_object(unsigned int object_id)
+{
+	switch (object_id) {
+	case SI_OBJECT_PRIMORDIAL:
+		return &static_si_object_primordial;
+
+	default:
+		return qtee__get_si_object(object_id);
+	}
+}
+
+void put_si_object(struct si_object *object)
+{
+	if (object != &static_si_object_primordial &&
+		object != NULL_SI_OBJECT &&
+		object != ROOT_SI_OBJECT)
+		kref_put(&object->refcount, ____destroy_si_object);
+}
+EXPORT_SYMBOL_GPL(put_si_object);
+
+/* 'alloc_si_object_id' and 'erase_si_object'. */
+
+static int alloc_si_object_id(struct si_object *object, u32 *idx)
+{
+	static u32 xa_si_last_id = SI_OBJECT_ID_START;
+
+	/* Every ID allocated here, will have 'QTEE_OBJ_NS_BIT' set. */
+	return xa_alloc_cyclic(&xa_si_objects, idx, object,
+		XA_LIMIT(SI_OBJECT_ID_START, SI_OBJECT_ID_END),
+			&xa_si_last_id, GFP_KERNEL);
+}
+
+struct si_object *erase_si_object(u32 idx)
+{
+	return xa_erase(&xa_si_objects, idx);
+}
+
+static int __free_si_object(struct si_object *object)
+{
+	/* This is used by si-core itself if it requires to do cleanup on the
+	 * object before calling it's release operation.
+	 */
+
+	if (object->release)
+		object->release(object);
+
+	synchronize_rcu();
+
+	switch (typeof_si_object(object)) {
+	case SI_OT_USER:
+		release_user_object(object);
+
+		break;
+	case SI_OT_CB_OBJECT: {
+		/* Keep the name in case 'release' needs it! */
+		const char *name = object->name;
+
+		if (object->ops->release)
+			object->ops->release(object);
+
+		kfree_const(name);
+		break;
+	}
+	case SI_OT_ROOT:
+	case SI_OT_NULL:
+	default:
+
+		break;
+	}
+
+	return 0;
+}
+
+enum si_object_type si_object_type(unsigned int object_id)
+{
+	if (object_id == QTEE_OBJ_NULL)
+		return SI_OT_NULL;
+
+	if (object_id & QTEE_OBJ_NS_BIT)
+		return SI_OT_CB_OBJECT;
+
+	return SI_OT_USER;
+}
+
+/**
+ * init_si_object_user - Initialize an instance of si_object.
+ * @object: object to initialize.
+ * @ot: type of object.
+ * @ops: instance of callbacks.
+ * @fmt: name assigned to the object.
+ *
+ * Return: On error, -EINVAL if the arguments are invalid.
+ * On success, return zero.
+ */
+int init_si_object_user(struct si_object *object, enum si_object_type ot,
+	struct si_object_operations *ops, const char *fmt, ...)
+{
+	int ret;
+	va_list ap;
+
+	kref_init(&object->refcount);
+	SET_SI_OBJECT(object, SI_OT_NULL);
+
+	/* **/
+	/* 'init_si_object_user' only initializes 'si_object'. The 'object_id'
+	 * allocation is postponed to 'get_object_id'. We want to use different
+	 * IDs so user can decide to share a 'si_object'.
+	 *
+	 **/
+
+	va_start(ap, fmt);
+	switch (ot) {
+	case SI_OT_NULL:
+
+		ret = 0;
+		break;
+	case SI_OT_CB_OBJECT:
+	case SI_OT_ROOT:
+		object->ops = ops;
+		if (!object->ops->dispatch)
+			return -EINVAL;
+
+		object->name = kvasprintf_const(GFP_KERNEL, fmt, ap);
+		if (!object->name)
+			return -ENOMEM;
+
+		SET_SI_OBJECT(object, SI_OT_CB_OBJECT);
+
+		if (ot == SI_OT_ROOT) {
+			object->release = primordial_object_release;
+
+			/* Finally, REGISTER it. */
+			primordial_object_register(object);
+		}
+
+		ret = 0;
+		break;
+	case SI_OT_USER:
+	default:
+		ret = -EINVAL;
+	}
+	va_end(ap);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(init_si_object_user);
+
+/* 'init_si_object' is to be consumed internally on return path.
+ * It is used for processing input objects.
+ */
+
+static int init_si_object(struct si_object **object, unsigned int object_id)
+{
+	int ret;
+
+	switch (si_object_type(object_id)) {
+	case SI_OT_NULL:
+
+		/* Should we receive ''SI_OT_NULL'' from QTEE!? Why not. **/
+		*object = NULL_SI_OBJECT;
+
+		ret = 0;
+		break;
+	case SI_OT_CB_OBJECT: {
+		struct si_object *t_object = qtee_get_si_object(object_id);
+
+		if (t_object != NULL) {
+			*object = t_object;
+
+			ret = 0;
+		} else
+			ret = -EINVAL;
+
+		break;
+	}
+	case SI_OT_USER: {
+		struct si_object *t_object = allocate_si_object();
+
+		if (t_object != NULL) {
+			kref_init(&t_object->refcount);
+
+			/* "no-name"; it is not really a reason to fail here!. */
+			t_object->name = kasprintf(GFP_KERNEL, "qtee-%u", object_id);
+
+			SET_SI_OBJECT(t_object, SI_OT_USER, object_id);
+
+			*object = t_object;
+
+			ret = 0;
+		} else
+			ret = -ENOMEM;
+
+		break;
+	}
+	default:
+		/* Err. SHOULD NEVER GET HERE! **/
+
+		ret = 0;
+
+		break;
+	}
+
+	if (ret) {
+
+		/* If unable to obtain an 'si_object' instance, set to NULL. */
+
+		*object = NULL_SI_OBJECT;
+	}
+
+	return ret;
+}
+
+/* 'get_object_id' is to be consumed internally on direct path to QTEE.
+ * Unlike 'init_si_object' 'get_object_id' does not increase the object's
+ * reference counter, i.e. the client should do that.
+ */
+
+int get_object_id(struct si_object *object, unsigned int *object_id)
+{
+	int ret;
+
+	switch (typeof_si_object(object)) {
+	case SI_OT_CB_OBJECT: {
+		u32 idx;
+
+		ret = alloc_si_object_id(object, &idx);
+		if (ret < 0)
+			goto out;
+
+		*object_id = idx;
+
+		ret = 0;
+	}
+
+		break;
+	case SI_OT_USER:
+		*object_id = object->info.object_ptr;
+
+		ret = 0;
+		break;
+	case SI_OT_NULL:
+		*object_id = QTEE_OBJ_NULL;
+
+		ret = 0;
+		break;
+	case SI_OT_ROOT:
+		*object_id = QTEE_OBJ_ROOT;
+
+		ret = 0;
+		break;
+	default:
+		return -EBADF;
+	}
+
+out:
+
+	return ret;
+}
+
+void __put_object_id(unsigned int object_id)
+{
+	/* Release 'idx' allocated in 'get_object_id'. **/
+
+	erase_si_object(object_id);
+}
+
+/* Context management API */
+
+/* 'shmem_alloc',
+ * 'si_object_invoke_ctx_init', and
+ * 'si_object_invoke_ctx_uninit'.
+ */
+
+#define OUT_BUFFER_SIZE SZ_32K
+
+static DEFINE_IDA(si_object_invoke_ctxs_ida);
+
+static int shmem_alloc(struct si_object_invoke_ctx *oic, struct si_arg u[])
+{
+	int ret = 0;
+	int i;
+
+	/* See 'prepare_msg'. Calculate size of inbound message. */
+
+	size_t size = OFFSET_TO_BUFFER_ARGS((struct qtee_object_invoke *)(0), size_of_arg(u));
+
+	arg_for_each_input_buffer(i, u)
+		size = align_offset(u[i].b.size + size);
+
+	arg_for_each_output_buffer(i, u)
+		size = align_offset(u[i].b.size + size);
+
+	/* QTEE requires both input and output buffer
+	 *   (1) to be PAGE_SIZE aligned and
+	 *   (2) to be multiple of PAGE_SIZE.
+	 */
+
+	size = PAGE_ALIGN(size);
+
+	oic->in.msg.size = size;
+	/* Get inbound buffer. */
+	oic->in.msg.addr = (void *)__get_free_pages(GFP_KERNEL | __GFP_COMP | GFP_DMA32,
+						get_order(oic->in.msg.size));
+
+	if (!oic->in.msg.addr)
+		return -ENOMEM;
+
+	oic->out.msg.size = OUT_BUFFER_SIZE;
+	/* Get outbound buffer. */
+	oic->out.msg.addr = (void *)__get_free_pages(GFP_KERNEL | __GFP_COMP | GFP_DMA32,
+						get_order(oic->out.msg.size));
+
+	if (!oic->out.msg.addr) {
+		free_pages((long)oic->in.msg.addr, get_order(oic->in.msg.size));
+		return -ENOMEM;
+	}
+
+	oic->in.paddr = __pa(oic->in.msg.addr);
+	oic->out.paddr = __pa(oic->out.msg.addr);
+	pr_debug("IN : paddr: %llx, size: %zu\n", oic->in.paddr, oic->in.msg.size);
+	pr_debug("OUT: paddr: %llx, size: %zu\n", oic->out.paddr, oic->out.msg.size);
+
+	ret = qcom_tzmem_register(oic->in.paddr, oic->in.msg.size,
+				(uint32_t[]){ QCOM_SCM_VMID_HLOS },
+				(uint32_t[]){ QCOM_SCM_PERM_RW }, 1, QCOM_SCM_PERM_RW,
+				&oic->in.handle);
+	if (ret) {
+		pr_err("Bridge creation failed for in buffer, paddr: %llx, size: %zu, ret: %d\n",
+			oic->in.paddr, oic->in.msg.size, ret);
+		free_pages((long)oic->in.msg.addr, get_order(oic->in.msg.size));
+		free_pages((long)oic->out.msg.addr, get_order(oic->out.msg.size));
+		return -EINVAL;
+	}
+
+	ret = qcom_tzmem_register(oic->out.paddr, oic->out.msg.size,
+				(uint32_t[]){ QCOM_SCM_VMID_HLOS },
+				(uint32_t[]){ QCOM_SCM_PERM_RW }, 1, QCOM_SCM_PERM_RW,
+				&oic->out.handle);
+	if (ret) {
+		pr_err("Bridge creation failed for out buffer, paddr: %llx, size: %zu, ret: %d\n",
+			oic->out.paddr, oic->out.msg.size, ret);
+		qcom_tzmem_deregister(oic->in.handle);
+		free_pages((long)oic->in.msg.addr, get_order(oic->in.msg.size));
+		free_pages((long)oic->out.msg.addr, get_order(oic->out.msg.size));
+		return -EINVAL;
+	}
+
+	/* QTEE assume unused buffers are zeroed; Do it now! */
+	memset(oic->in.msg.addr, 0, oic->in.msg.size);
+	memset(oic->out.msg.addr, 0, oic->out.msg.size);
+
+	return 0;
+}
+
+static int si_object_invoke_ctx_init(struct si_object_invoke_ctx *oic, struct si_arg u[])
+{
+	memset(oic, 0, sizeof(*oic));
+
+	/* First check if we can allocate an ID, then initialize it. */
+	/* Context IDa [0 .. 10) are never used. */
+
+	oic->context_id = ida_alloc_min(&si_object_invoke_ctxs_ida, 10, GFP_KERNEL);
+	if (oic->context_id < 0) {
+		pr_err("unable to allocate context ID (%d)\n", oic->context_id);
+
+		return oic->context_id;
+	}
+
+	if (shmem_alloc(oic, u)) {
+		ida_free(&si_object_invoke_ctxs_ida, oic->context_id);
+
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD(&oic->objects_head);
+
+	return 0;
+}
+
+static void si_object_invoke_ctx_uninit(struct si_object_invoke_ctx *oic)
+{
+	ida_free(&si_object_invoke_ctxs_ida, oic->context_id);
+
+	qcom_tzmem_deregister(oic->in.handle);
+	qcom_tzmem_deregister(oic->out.handle);
+	free_pages((long)oic->in.msg.addr, get_order(oic->in.msg.size));
+	free_pages((long)oic->out.msg.addr, get_order(oic->out.msg.size));
+}
+
+/* For X_msg functions, on failure we do the cleanup. Because, we could not
+ * construct a message to send so the caller remains the owner of the objects.
+ * For X_args functions, on failure wo do ''not'' do a cleanup. Because,
+ * we received the message and receiver should be the new owner to cleanup.
+ */
+
+static int prepare_msg(struct si_object_invoke_ctx *oic,
+	struct si_object *object, unsigned long op, struct si_arg u[])
+{
+	int i, ib = 0, ob = 0, io = 0, oo = 0;
+
+	unsigned int object_id;
+
+	/* Use input message buffer in 'oic'. */
+
+	struct qtee_object_invoke *msg = (struct qtee_object_invoke *)oic->in.msg.addr;
+	size_t msg_size = oic->in.msg.size;
+
+	/* Start offset in a message for buffer argument. */
+
+	unsigned int offset = OFFSET_TO_BUFFER_ARGS(msg, size_of_arg(u));
+
+	if (get_object_id(object, &object_id))
+		return -ENOSPC;
+
+	arg_for_each_input_buffer(i, u) {
+		void *msg_ptr;
+
+		msg->args[ib].b.offset = offset;
+		msg->args[ib].b.size = u[i].b.size;
+		if (!arg_in_bounds(&msg->args[ib], msg_size))
+			return -ENOMEM;
+
+		msg_ptr = OFFSET_TO_PTR(msg, offset);
+
+		if (!u[i].flags)
+			memcpy(msg_ptr, u[i].b.addr, u[i].b.size);
+		else if (copy_from_user(msg_ptr, u[i].b.uaddr, u[i].b.size))
+			return -EFAULT;
+
+		offset = align_offset(u[i].b.size + offset);
+		ib++;
+	}
+
+	ob = ib;
+	arg_for_each_output_buffer(i, u) {
+		msg->args[ob].b.offset = offset;
+		msg->args[ob].b.size = u[i].b.size;
+		if (!arg_in_bounds(&msg->args[ob], msg_size))
+			return -ENOMEM;
+
+		offset = align_offset(u[i].b.size + offset);
+		ob++;
+	}
+
+	io = ob;
+	arg_for_each_input_object(i, u) {
+		if (get_object_id(u[i].o, &msg->args[io].o)) {
+
+			/* Unable to 'get_object_id'; 'put' whatever we got. **/
+
+			__put_object_id(object_id);
+			for (--io; io >= ob; io--)
+				__put_object_id(msg->args[io].o);
+
+			return -ENOSPC;
+		}
+
+		io++;
+	}
+
+	oo = io;
+	arg_for_each_output_object(i, u)
+		oo++;
+
+	/* Set object, operation, and argument counts. */
+
+	init_oi_msg(msg, object_id, op, ib, ob, io, oo);
+
+	return 0;
+}
+
+static int update_args(struct si_arg u[], struct si_object_invoke_ctx *oic)
+{
+	int ret = 0;
+
+	int i, ib = 0, ob = 0, io = 0, oo = 0;
+
+	/* Use input message buffer in 'oic'. */
+
+	struct qtee_object_invoke *msg = (struct qtee_object_invoke *)oic->in.msg.addr;
+
+	arg_for_each_input_buffer(i, u)
+		ib++;
+
+	ob = ib;
+	arg_for_each_output_buffer(i, u) {
+		void *msg_ptr = OFFSET_TO_PTR(msg, msg->args[ob].b.offset);
+
+		if (!u[i].flags) {
+			memcpy(u[i].b.addr, msg_ptr, msg->args[ob].b.size);
+		} else if (copy_to_user(u[i].b.uaddr, msg_ptr, msg->args[ob].b.size)) {
+			/* On failour, continue so that we process output objects for RELEASE.*/
+			ret = -EFAULT;
+		}
+
+		u[i].b.size = msg->args[ob].b.size;
+		ob++;
+	}
+
+	io = ob;
+	arg_for_each_input_object(i, u)
+		io++;
+
+	oo = io;
+	arg_for_each_output_object(i, u) {
+		int err;
+
+		/* **/
+		/* If 'init_si_object' returns error (e.g. requested handle is invalid or
+		 * 'init_si_object' is unable to allocate 'si_object'), we continue to
+		 * process arguments. It is necessary so that latter we can issue the 'RELEASE'.
+		 *
+		 * If 'init_si_object' failed to allocated the 'si_object', we could not
+		 * release that object.
+		 *
+		 **/
+
+		err = init_si_object(&u[i].o, msg->args[oo].o);
+		if (err)
+			ret = err;
+
+		oo++;
+	}
+
+	return ret;
+}
+
+static int prepare_args(struct si_object_invoke_ctx *oic)
+{
+	/* We initialise user arguments based on the callback message.
+	 * It is important to preserve the order of arguments, i.e. 'SI_AT_IB', 'SI_AT_OB',
+	 * following by 'SI_AT_IO', and 'SI_AT_OO'.
+	 */
+
+	int ret = 0;
+
+	int i;
+
+	/* Use output message buffer in 'oic'. */
+
+	struct qtee_callback *msg = (struct qtee_callback *)oic->out.msg.addr;
+
+	/* We assume QTEE already checked the buffer boundaries! */
+
+	for_each_input_buffer(i, msg->counts) {
+		oic->u[i].b.addr = OFFSET_TO_PTR(msg, msg->args[i].b.offset);
+		oic->u[i].b.size = msg->args[i].b.size;
+		oic->u[i].type = SI_AT_IB;
+	}
+
+	for_each_output_buffer(i, msg->counts) {
+		oic->u[i].b.addr = OFFSET_TO_PTR(msg, msg->args[i].b.offset);
+		oic->u[i].b.size = msg->args[i].b.size;
+		oic->u[i].type = SI_AT_OB;
+	}
+
+	for_each_input_object(i, msg->counts) {
+		int err;
+
+		/* See comments for 'for_each_output_object' in 'update_args'. **/
+
+		err = init_si_object(&oic->u[i].o, msg->args[i].o);
+		if (err)
+			ret = err;
+
+		oic->u[i].type = SI_AT_IO;
+	}
+
+	for_each_output_object(i, msg->counts)
+		oic->u[i].type = SI_AT_OO;
+
+	/* End of Arguments. */
+
+	oic->u[i].type = SI_AT_END;
+
+	return ret;
+}
+
+static int update_msg(struct si_object_invoke_ctx *oic)
+{
+	int i, ib = 0, ob = 0, io = 0, oo = 0;
+
+	/* Use output message buffer in 'oic'. */
+
+	struct qtee_callback *msg = (struct qtee_callback *)oic->out.msg.addr;
+
+	arg_for_each_input_buffer(i, oic->u)
+		ib++;
+
+	ob = ib;
+	arg_for_each_output_buffer(i, oic->u) {
+
+		/* Only reduce size of client requested that; never increase it. */
+
+		if (msg->args[ob].b.size < oic->u[i].b.size)
+			return -EINVAL;
+
+		msg->args[ob].b.size = oic->u[i].b.size;
+
+		ob++;
+	}
+
+	io = ob;
+	arg_for_each_input_object(i, oic->u)
+		io++;
+
+	oo = io;
+	arg_for_each_output_object(i, oic->u) {
+		if (get_object_id(oic->u[i].o, &msg->args[oo].o)) {
+
+			/* Unable to 'get_object_id'; 'put' whatever we got. **/
+			for (--oo; oo >= io; --oo)
+				__put_object_id(msg->args[oo].o);
+
+			return -ENOSPC;
+		}
+
+		oo++;
+	}
+
+	return 0;
+}
+
+/* Invoke an 'si_object' instance. */
+
+static void si_object_invoke(struct si_object_invoke_ctx *oic, struct qtee_callback *msg)
+{
+	int i, errno;
+
+	/* Get object being invoked!!! */
+	unsigned int object_id = msg->cxt;
+	struct si_object *object;
+
+	/* QTEE can not invoke NULL object or objects it hosts. */
+	if (si_object_type(object_id) == SI_OT_NULL ||
+		si_object_type(object_id) == SI_OT_USER) {
+		errno = -EINVAL;
+
+		goto out;
+	}
+
+	object = qtee_get_si_object(object_id);
+	if (!object) {
+		errno = -EINVAL;
+
+		goto out;
+	}
+
+	oic->object = object;
+
+	switch (SI_OBJECT_OP_METHOD_ID(msg->op)) {
+	case SI_OBJECT_OP_RELEASE:
+
+		/* Remove the 'object' from 'xa_si_objects' so that the 'object_id'
+		 * becomes invalid for further use. However, call 'put_si_object'
+		 * to schedule the actual release if there is no user.
+		 */
+
+		erase_si_object(object_id);
+		put_si_object(object);
+		errno = 0;
+
+		break;
+	case SI_OBJECT_OP_RETAIN:
+		get_si_object(object);
+		errno = 0;
+
+		break;
+	default:
+
+		/* Check if the operation is supported before going forward. */
+		if (object->ops->op_supported) {
+			if (object->ops->op_supported(msg->op)) {
+				errno = -EINVAL;
+
+				break;
+			}
+		}
+
+		errno = prepare_args(oic);
+		if (errno) {
+
+			/* Unable to parse the message. Release any object arrived as input. */
+			arg_for_each_input_buffer(i, oic->u)
+				put_si_object(oic->u[i].o);
+
+			break;
+		}
+
+		errno = object->ops->dispatch(oic->context_id,
+			/* .dispatch(Object, Operation, Arguments). */
+			object, msg->op, oic->u);
+
+		if (!errno) {
+
+			/* On SUCCESS, notify 'object' at appropriate time. */
+			oic->flags |= OIC_FLAG_NOTIFY;
+		}
+
+	}
+
+	switch (errno) {
+	case 0:
+
+		break;
+
+	case -ERESTARTSYS:
+	case -ERESTARTNOINTR:
+	case -ERESTARTNOHAND:
+	case -ERESTART_RESTARTBLOCK:
+
+		/* There's no easy way to restart the syscall that end up in callback
+		 * object invocation. Just fail the call with EINTR.
+		 */
+
+		/* We do not do any cleanup for input objects. */
+
+		errno = -EINTR;
+
+		fallthrough;
+	default:
+
+		/* On error, dispatcher should do the cleanup. */
+
+		break;
+	}
+
+out:
+
+	oic->errno = errno;
+}
+
+/**
+ * si_object_do_invoke - Submit an invocation for si_object_invoke_ctx.
+ * @oic: context to use for current invocation.
+ * @object: object being invoked.
+ * @op: requested operation on @object.
+ * @u: array of argument for the current invocation.
+ * @result: result return from QTEE.
+ *
+ * The caller is responsible to keep track of the refcount for each object,
+ * including @object. On return (success or failure), the caller loses the
+ * ownership of all input object of type SI_OT_CB_OBJECT.
+ *
+ * Return: On success return 0. On failure returns -EINVAL if unable to parse the
+ * request or response. It returns -ENODEV if it can not communicate with QTEE, or
+ * -EAGAIN if it can not communicate with QTEE but it is safe for the caller to
+ * retry the call (after getting IO again as they are put on return). It returns
+ * -ENOMEM if memory could not be allocated, or -ENOSPC if there is not free
+ * context ID or QTEE handler.
+ */
+int si_object_do_invoke(struct si_object_invoke_ctx *oic,
+	struct si_object *object, unsigned long op, struct si_arg u[], int *result)
+{
+	int i, ret, errno;
+	unsigned int data;
+	u64 response_type;
+
+	struct qtee_callback *cb_msg;
+
+	if (typeof_si_object(object) != SI_OT_USER &&
+		typeof_si_object(object) != SI_OT_ROOT)
+		return -EINVAL;
+
+	ret = si_object_invoke_ctx_init(oic, u);
+	if (ret)
+		return ret;
+
+	pr_debug("start an invocation for %s.\n", si_object_name(object));
+
+	ret = prepare_msg(oic, object, op, u);
+	if (ret)
+		goto out;
+
+	/* INVOKE remote object!! */
+
+	cb_msg = (struct qtee_callback *)oic->out.msg.addr;
+
+	while (1) {
+		if (oic->flags & OIC_FLAG_BUSY) {
+			errno = oic->errno;
+
+			/* Update output buffer only if result is SUCCESS. */
+			if (!errno)
+				errno = update_msg(oic);
+
+			err_to_qtee_err(cb_msg, errno);
+		}
+
+		/* APPEND async requests before handing the output buffer over to QTEE. */
+		__append__async_reqs(oic);
+
+		ret = si_object_invoke_ctx_invoke(oic, result, &response_type, &data);
+
+		if (oic->flags & OIC_FLAG_BUSY) {
+			struct si_object *t_object = oic->object;
+
+			/* A busy 'oic' can have a 'NULL_SI_OBJECT' object if
+			 * 'si_object_invoke' fails, internally.
+			 */
+
+			if (t_object) {
+
+				/* Only notify if we should!? */
+				if (oic->flags & OIC_FLAG_NOTIFY) {
+					if (t_object->ops->notify)
+						t_object->ops->notify(oic->context_id,
+							t_object, (errno | ret));
+				}
+
+				put_si_object(t_object);
+			}
+
+			/* 'oic' is done. Cleanup. */
+			oic->object = NULL_SI_OBJECT;
+			oic->flags &= ~(OIC_FLAG_BUSY | OIC_FLAG_NOTIFY);
+		}
+
+		if (ret) {
+
+			/* 'si_object_invoke_ctx_invoke' failed; We can not recover from this. */
+
+			/* We never get a chance to communicate with QTEE.
+			 * RETRIEVE all pending async requests queued for this context.
+			 */
+
+			__revive__async_queued_reqs(oic);
+
+			/* SI_OT_CB_OBJECT input objects are orphan; let's put them. */
+			if (!(oic->flags & OIC_FLAG_QTEE)) {
+				arg_for_each_input_object(i, u)
+					if (typeof_si_object(u[i].o) == SI_OT_CB_OBJECT)
+						put_si_object(u[i].o);
+
+				/* So QTEE is unaawre of this.
+				 * Let the caller know in case they want to do something about it,
+				 * e.g. retry the call.
+				 */
+
+				ret = -EAGAIN;
+
+			} else {
+
+				/* So QTEE is aware of this.
+				 * On error, there is no clean way to clean up.
+				 */
+
+				ret = -ENODEV;
+			}
+
+			goto out;
+
+		} else {
+
+			/* QTEE obtained the ownership of SI_OT_CB_OBJECT input objects in 'u'.
+			 * On further failure, QTEE is responsible to release them.
+			 */
+
+			oic->flags |= OIC_FLAG_QTEE;
+		}
+
+		/* SUCCESS. Release async request queued for this context.*/
+		__release__async_queued_reqs(oic);
+
+		/* Is it not a callback request?! */
+		if (response_type == QTEE_RESULT_INBOUND_REQ_NEEDED) {
+			oic->flags |= OIC_FLAG_BUSY;
+
+			/* Before dispatching the request, handle any pending async requests. */
+			__fetch__async_reqs(oic);
+
+			si_object_invoke(oic, cb_msg);
+
+		} else {
+			if (!*result) {
+				ret = update_args(u, oic);
+				if (ret) {
+					arg_for_each_output_object(i, u)
+						put_si_object(u[i].o);
+				}
+			}
+
+			break;
+
+		}
+	}
+
+	__fetch__async_reqs(oic);
+
+out:
+	si_object_invoke_ctx_uninit(oic);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(si_object_do_invoke);
+
+/* Primordial Object. */
+/* It is invoked by QTEE for kernel services. */
+
+static struct si_object *primordial_object = NULL_SI_OBJECT;
+static DEFINE_MUTEX(primordial_object_lock);
+
+static int primordial_object_register(struct si_object *object)
+{
+	/* A primordial_object is a valid callback object. */
+	if (typeof_si_object(object) != SI_OT_CB_OBJECT)
+		return -EINVAL;
+
+	/* Finally, REGISTER it. */
+
+	/* We do not check if there is any other object registered. */
+	/* This allows safe transition from one object to another without effecting QTEE. */
+
+	mutex_lock(&primordial_object_lock);
+	rcu_assign_pointer(primordial_object, object);
+	mutex_unlock(&primordial_object_lock);
+
+	return 0;
+}
+
+static void primordial_object_release(struct si_object *object)
+{
+	mutex_lock(&primordial_object_lock);
+
+	/* Only reset 'primordial_object' if it points to this object. */
+	if (primordial_object == object)
+		rcu_assign_pointer(primordial_object, NULL_SI_OBJECT);
+
+	mutex_unlock(&primordial_object_lock);
+}
+
+static struct si_object *get_primordial_object(void)
+{
+	struct si_object *object;
+
+	rcu_read_lock();
+	object = rcu_dereference(primordial_object);
+
+	if (!get_si_object(object))
+		object = NULL_SI_OBJECT;
+
+	rcu_read_unlock();
+
+	return object;
+}
+
+static int op_sleep(struct si_arg args[])
+{
+	if (size_of_arg(args) != 1 || args[0].type != SI_AT_IB)
+		return -EINVAL;
+
+	msleep(*(u32 *)(args[0].b.addr));
+
+	return 0;
+}
+
+static int do_primordial_object_dispatch(unsigned int context_id,
+	struct si_object *primordial_object, unsigned long op, struct si_arg args[])
+{
+	int i, ret = -EINVAL;
+
+	struct si_object *object;
+
+	/* Static 'primordial_object': Unused here! */
+
+	switch (op) {
+	case OBJECT_OP_YIELD:
+		ret = 0;
+
+		break;
+	case OBJECT_OP_SLEEP:
+		ret = op_sleep(args);
+
+		break;
+	default:
+		object = get_primordial_object();
+
+		if (object) {
+			pr_info("QTEE invocation for %s, op %lu.\n", si_object_name(object), op);
+
+			ret = object->ops->dispatch(context_id,
+				/* .dispatch(Object, Operation, Arguments). */
+				object, op, args);
+
+			put_si_object(object);
+		} else {
+			pr_err("No primordial object registered.\n");
+
+			/* Release any object arrived as input. */
+			arg_for_each_input_object(i, args)
+				put_si_object(args[i].o);
+		}
+	}
+
+	return ret;
+}
+
+static struct si_object_operations primordial_ops = {
+	.dispatch = do_primordial_object_dispatch
+};
+
+static struct si_object static_si_object_primordial = {
+	.object_type = SI_OT_CB_OBJECT,
+	.ops = &primordial_ops
+};
+
+/* Dump QTEE object table. */
+static ssize_t ot_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	struct si_object *object;
+	unsigned long idx;
+	size_t len = 0;
+
+	rcu_read_lock();
+	xa_for_each_start(&xa_si_objects, idx, object, SI_OBJECT_ID_START) {
+		len += scnprintf(buf + len, PAGE_SIZE - len, "%lx %4d %s\n",
+			idx, kref_read(&object->refcount), si_object_name(object));
+	}
+	rcu_read_unlock();
+
+	return len;
+}
+
+/* Info for registered primordial object. */
+static ssize_t po_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	struct si_object *object = get_primordial_object();
+	size_t len = 0;
+
+	if (object) {
+		len = scnprintf(buf, PAGE_SIZE, "%s %d\n",
+			/* minus one for the above 'get_primordial_object'. */
+			si_object_name(object), kref_read(&object->refcount) - 1);
+		put_si_object(object);
+	}
+
+	return len;
+}
+
+/* Defined in si_core_async.c. */
+ssize_t release_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf);
+
+static struct kobj_attribute ot = __ATTR_RO(ot);
+static struct kobj_attribute po = __ATTR_RO(po);
+static struct kobj_attribute release = __ATTR_RO(release);
+static struct attribute *attrs[] = {
+	&ot.attr,
+	&po.attr,
+	&release.attr,
+	NULL
+};
+
+static struct attribute_group attr_group = {
+	.attrs = attrs,
+};
+
+static struct kobject *si_core_kobj;
+static int __init si_core_init(void)
+{
+	int ret;
+
+	ret = init_si_core_wq();
+	if (ret)
+		return ret;
+
+	/* Create '/sys/kernel/si_core'. */
+	si_core_kobj = kobject_create_and_add("si_core", kernel_kobj);
+	if (!si_core_kobj) {
+		destroy_si_core_wq();
+
+		return -ENOMEM;
+	}
+
+	ret = sysfs_create_group(si_core_kobj, &attr_group);
+	if (ret) {
+		kobject_put(si_core_kobj);
+		destroy_si_core_wq();
+	}
+
+#if IS_ENABLED(CONFIG_QCOM_SI_CORE_ADCI)
+	adci_start();
+#endif
+
+	return ret;
+}
+
+static void __exit si_core_exit(void)
+{
+	/* TODO. Prevent unloading if 'xa_si_objects' is not empty. */
+
+#if IS_ENABLED(CONFIG_QCOM_SI_CORE_ADCI)
+	adci_shutdown();
+#endif
+
+	sysfs_remove_group(si_core_kobj, &attr_group);
+
+	kobject_put(si_core_kobj);
+}
+
+module_init(si_core_init);
+module_exit(si_core_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("SI CORE driver");
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/si_core.h
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/si_core.h
@@ -0,0 +1,190 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __SI_CORE_H__
+#define __SI_CORE_H__
+
+#include <linux/firmware/qcom/si_object.h>
+
+/* QTEE object ID API. */
+
+enum si_object_type si_object_type(unsigned int object_id);
+
+/* 'get_object_id' allocates a QTEE handler for a si_object. */
+/* '__put_object_id' erases the QTEE handler. */
+/* 'qtee_get_si_object' returns si_object for a QTEE handler and increase the refcount. */
+
+int get_object_id(struct si_object *object, unsigned int *object_id);
+void __put_object_id(unsigned int object_id);
+struct si_object *qtee_get_si_object(unsigned int object_id);
+
+int si_object_invoke_ctx_invoke(struct si_object_invoke_ctx *oic, int *result,
+	u64 *response_type, unsigned int *data);
+
+#ifdef CONFIG_QCOM_SI_CORE_WQ
+int init_si_core_wq(void);
+void destroy_si_core_wq(void);
+#else
+static inline int init_si_core_wq(void) { return 0; }
+static inline void destroy_si_core_wq(void) { }
+#endif /* CONFIG_QCOM_SI_CORE_WQ */
+
+void release_user_object(struct si_object *object);
+
+/* ASYNC message management API. */
+
+void __append__async_reqs(struct si_object_invoke_ctx *oic);
+void __revive__async_queued_reqs(struct si_object_invoke_ctx *oic);
+void __release__async_queued_reqs(struct si_object_invoke_ctx *oic);
+void __fetch__async_reqs(struct si_object_invoke_ctx *oic);
+
+/* ''QTEE'' related definitions. */
+
+#define QTEE_RESULT_INBOUND_REQ_NEEDED 3
+
+#define INVOKE_MESSAGE_ALIGN_BYTES 8U
+
+#define QTEE_OBJ_NULL (0U)
+#define QTEE_OBJ_ROOT (1U)
+
+#define QTEE_OBJ_NS_BIT (1U << 31)
+
+#define align_offset(o) PTR_ALIGN((o), INVOKE_MESSAGE_ALIGN_BYTES)
+
+/* Definitions from QTEE as part of the transport protocol. */
+/* 'qtee_smcinvoke_msg_arg', 'struct qtee_object_invoke', and 'struct qtee_callback'. */
+
+union qtee_smcinvoke_msg_arg {
+	struct {
+		u32 offset;
+		u32 size;
+	} b;
+	u32 o;
+};
+
+/* Check if a buffer argument 'arg' can fit in a message of size 'sz'. */
+#define arg_in_bounds(arg, sz) \
+	(((arg)->b.offset < (sz)) && ((arg)->b.size < ((sz) - (arg)->b.offset)))
+
+struct qtee_object_invoke {
+	u32 cxt;
+	u32 op;
+	u32 counts;
+	union qtee_smcinvoke_msg_arg args[];
+};
+
+struct qtee_callback {
+	u32 result;
+	u32 cxt;
+	u32 op;
+	u32 counts;
+	union qtee_smcinvoke_msg_arg args[];
+};
+
+#define OFFSET_TO_PTR(m, off) ((void *)&((char *)(m))[(off)])
+
+/* Offset in the message for the beginning of buffer argument's contents. */
+#define OFFSET_TO_BUFFER_ARGS(m, n) \
+	align_offset(offsetof(typeof(*m), args) + (n * sizeof((m)->args[0])))
+
+#define counts_num__bi_(x) (((x) >> 0) & 0xFU)
+#define counts_num__bo_(x) (((x) >> 4) & 0xFU)
+#define counts_num__oi_(x) (((x) >> 8) & 0xFU)
+#define counts_num__oo_(x) (((x) >> 12) & 0xFU)
+
+#define counts_idx__bi_(x) 0U
+#define counts_idx__bo_(x) (counts_idx__bi_(x) + counts_num__bi_(x))
+#define counts_idx__oi_(x) (counts_idx__bo_(x) + counts_num__bo_(x))
+#define counts_idx__oo_(x) (counts_idx__oi_(x) + counts_num__oi_(x))
+#define counts_total(x) (counts_idx__oo_(x) + counts_num__oo_(x))
+
+#define FOR_ARGS(i, c, type) \
+	for (i = counts_idx##type(c); i < (counts_idx##type(c) + counts_num##type(c)); i++)
+
+#define for_each_input_buffer(i, c)  FOR_ARGS(i, c, __bi_)
+#define for_each_output_buffer(i, c) FOR_ARGS(i, c, __bo_)
+#define for_each_input_object(i, c)  FOR_ARGS(i, c, __oi_)
+#define for_each_output_object(i, c) FOR_ARGS(i, c, __oo_)
+
+#define bi_shift 0
+#define ob_shift 4
+#define io_shift 8
+#define oo_shift 12
+
+static inline void init_oi_msg(struct qtee_object_invoke *msg,
+	u32 cxt, u32 op, int ib, int ob, int io, int oo)
+{
+	u32 counts = 0;
+
+	counts |= ((oo - io) & 0xFU) << oo_shift;	/* No. Output Objects. */
+	counts |= ((io - ob) & 0xFU) << io_shift;	/* No. Input Objects. */
+	counts |= ((ob - ib) & 0xFU) << ob_shift;	/* No. Output Buffer. */
+	counts |= (ib & 0xFU) << bi_shift;			/* No. Input Buffer. */
+
+	msg->cxt = cxt;
+	msg->op = op;
+	msg->counts = counts;
+}
+
+static inline void err_to_qtee_err(struct qtee_callback *cb_msg, int err)
+{
+
+/* Generic error codes */
+
+#define OBJECT_OK				0	/* non-specific success code */
+#define OBJECT_ERROR			1	/* non-specific error */
+#define OBJECT_ERROR_INVALID	2	/* unsupported/unrecognized request */
+#define OBJECT_ERROR_SIZE_IN	3	/* supplied buffer/string too large */
+#define OBJECT_ERROR_SIZE_OUT	4	/* supplied output buffer too small */
+
+#define OBJECT_ERROR_USERBASE	10	/* start of user-defined error range */
+
+/* Transport layer error codes */
+
+#define OBJECT_ERROR_DEFUNCT	-90	/* object no longer exists */
+#define OBJECT_ERROR_ABORT		-91	/* calling thread must exit */
+#define OBJECT_ERROR_BADOBJ		-92	/* invalid object context */
+#define OBJECT_ERROR_NOSLOTS	-93	/* caller's object table full */
+#define OBJECT_ERROR_MAXARGS	-94	/* too many args */
+#define OBJECT_ERROR_MAXDATA	-95	/* buffers too large */
+#define OBJECT_ERROR_UNAVAIL	-96	/* the request could not be processed */
+#define OBJECT_ERROR_KMEM		-97	/* kernel out of memory */
+#define OBJECT_ERROR_REMOTE		-98	/* local method sent to remote object */
+#define OBJECT_ERROR_BUSY		-99	/* Object is busy */
+#define OBJECT_ERROR_TIMEOUT	-103	/* Call Back Object invocation timed out. */
+
+	switch (err) {
+	case 0:
+		cb_msg->result = OBJECT_OK;
+
+		break;
+	case -ENOMEM:
+		cb_msg->result = OBJECT_ERROR_KMEM;
+
+		break;
+	case -ENODEV:
+		cb_msg->result = OBJECT_ERROR_DEFUNCT;
+
+		break;
+	case -ENOSPC:
+	case -EBUSY:
+		cb_msg->result = OBJECT_ERROR_BUSY;
+
+		break;
+	case -EBADF:
+		cb_msg->result = OBJECT_ERROR_UNAVAIL;
+
+		break;
+	case -EINVAL:
+		cb_msg->result = OBJECT_ERROR_INVALID;
+
+		break;
+	default:
+		/* Positive err. are sent back as-is, negatives are transport related. */
+		cb_msg->result = (err >= OBJECT_OK) ? err : OBJECT_ERROR;
+	}
+}
+
+#endif /* __SI_CORE_H__ */
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/si_core_adci.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/si_core_adci.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/kthread.h>
+
+#include "si_core.h"
+
+static struct task_struct *adci_task;
+static struct si_object_invoke_ctx oic;
+
+static void wait_to_die(void)
+{
+	for (;;) {
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		if (kthread_should_stop())
+			break;
+
+		schedule();
+	}
+
+	__set_current_state(TASK_RUNNING);
+}
+
+static int adci_fn(void *unused)
+{
+	int ret, result = 0;
+	struct si_arg args[1] = { 0 };
+
+	/* IClientEnv_OP_adciAccept is 8. */
+	ret = si_object_do_invoke(&oic, ROOT_SI_OBJECT, 8, args, &result);
+
+	if (ret)
+		pr_err("unable to register ADCI thread (%d).\n", ret);
+	else if (result == OBJECT_ERROR_INVALID)
+		pr_err("ADCI feature is not supported on this chipsets.\n");
+
+	pr_debug("exited.\n");
+
+	/* Let's wait for someone to collect our result. */
+	if (!kthread_should_stop())
+		wait_to_die();
+
+	return result;
+}
+
+void adci_start(void)
+{
+	adci_task = kthread_run(adci_fn, NULL, "adci_thread");
+
+	/* Who cares if it fails?! */
+	if (IS_ERR(adci_task))
+		pr_err("failed (%ld).\n", PTR_ERR(adci_task));
+}
+
+int adci_shutdown(void)
+{
+	int ret, result = 0;
+	struct si_arg args[1] = { 0 };
+
+	/* IClientEnv_OP_adciShutdown is 9. */
+	ret = si_object_do_invoke(&oic, ROOT_SI_OBJECT, 9, args, &result);
+
+	if (ret || result)
+		pr_err("failed (ret = %d, %d).\n", ret, result);
+
+	/* If IClientEnv_OP_adciShutdown fails, we may stuck here. */
+	kthread_stop(adci_task);
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/si_core_adci.h
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/si_core_adci.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __SI_CORE_ADCI_H__
+#define __SI_CORE_ADCI_H__
+
+void adci_start(void);
+int adci_shutdown(void);
+
+#endif /* __SI_CORE_ADCI_H__ */
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/si_core_async.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/si_core_async.c
@@ -0,0 +1,480 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/kobject.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+
+#include "si_core.h"
+
+/* Processing of the async messges happens without any ordering. */
+
+struct si_object *erase_si_object(u32 idx);
+u32 global_version;
+
+struct async_msg_info {
+	u32 owner;
+	u32 out;
+	u64 user_data[];
+};
+
+/* Async handlers and providers. */
+struct async_msg {
+	struct {
+		u32 version;	/* Protocol version: top 16b major, lower 16b minor. */
+		u32 op;			/* Async operation. */
+	} header;
+
+	/* Format of the Async data field is defined by the specified operation. */
+
+	union {
+		struct {
+			u32 count;	/* Number of objects that should be released. */
+			u32 obj[];
+		} op_release;
+
+		/* This is a generic structure. */
+		struct {
+			u32 count;	/* SET to one; We create per-object 'owner' messages. */
+			struct async_msg_info async_info;
+		} info;
+	};
+};
+
+/* Async Operations and header information. */
+
+#define ASYNC_HEADER_SIZE sizeof(((struct async_msg *)(0))->header)
+
+/* ASYNC_OP_x: operation.
+ * ASYNC_OP_x_HDR_SIZE: header size for the operation.
+ * ASYNC_OP_x_SIZE: size of each entry in a message for the operation.
+ * ASYNC_OP_x_MSG_SIZE: size of a message with n entries.
+ */
+
+#define ASYNC_OP_USER_HDR_SIZE offsetof(struct async_msg, info.async_info.user_data)
+
+#define ASYNC_OP_RELEASE SI_OBJECT_OP_RELEASE	/* Added in minor version 0x0000. **/
+#define ASYNC_OP_RELEASE_HDR_SIZE offsetof(struct async_msg, op_release.obj)
+#define ASYNC_OP_RELEASE_SIZE sizeof(((struct async_msg *)(0))->op_release.obj[0])
+#define ASYNC_OP_RELEASE_MSG_SIZE(n) \
+	(ASYNC_OP_RELEASE_HDR_SIZE + ((n) * ASYNC_OP_RELEASE_SIZE))
+
+int get_async_proto_version(void)
+{
+	return global_version;
+}
+EXPORT_SYMBOL_GPL(get_async_proto_version);
+
+/* 'async_si_buffer' return the available async buffer in the output buffer. */
+
+static struct si_buffer async_si_buffer(struct si_object_invoke_ctx *oic)
+{
+	int i;
+	size_t offset;
+
+	struct qtee_callback *msg = (struct qtee_callback *)oic->out.msg.addr;
+
+	if (!(oic->flags & OIC_FLAG_BUSY))
+		return oic->out.msg;
+
+	/* Async requests are appended to the output buffer after the CB message. */
+
+	offset = OFFSET_TO_BUFFER_ARGS(msg, counts_total(msg->counts));
+
+	for_each_input_buffer(i, msg->counts)
+		offset += align_offset(msg->args[i].b.size);
+
+	for_each_output_buffer(i, msg->counts)
+		offset += align_offset(msg->args[i].b.size);
+
+	if (oic->out.msg.size > offset) {
+		return (struct si_buffer)
+			{
+				{ oic->out.msg.addr + offset },
+				oic->out.msg.size - offset
+			};
+	}
+
+	pr_err("no space left for async messages! or malformed message.\n");
+
+	return (struct si_buffer) { { 0 }, 0 };
+}
+
+#ifndef CONFIG_QCOM_SI_CORE_WQ
+
+/* 'async_ops_mutex' serialize the construction of async message. */
+static DEFINE_MUTEX(async_ops_mutex);
+
+/* List of objects that should be released. */
+/* All objects in 'release_ops_list' should have refcount set to ''zero''. */
+static LIST_HEAD(release_ops_list);
+
+/* 'release_user_object' put object in release pending list.
+ * 'async_release_provider' remove objects from release pending list and construct
+ *  the async message.
+ * 'revive_async_queued_reqs' move object back to release pending list.
+ * 'destroy_user_object' called to finish the job after QTEE acknowledged the release.
+ */
+
+void release_user_object(struct si_object *object)
+{
+	/* Use async message for RELEASE request.
+	 * We free the object in '__release__async_queued_reqs' when appropriate.
+	 */
+
+	pr_debug("%s queued for async release.\n", si_object_name(object));
+
+	mutex_lock(&async_ops_mutex);
+	list_add_tail(&object->node, &release_ops_list);
+	mutex_unlock(&async_ops_mutex);
+}
+
+static size_t async_release_provider(struct si_object_invoke_ctx *oic,
+	struct async_msg *async_msg, size_t size)
+{
+	int i = 0;
+	struct si_object *object, *t;
+
+	/* We need space for at least a single entry. */
+	if (size < ASYNC_OP_RELEASE_MSG_SIZE(1))
+		return 0;
+
+	mutex_lock(&async_ops_mutex);
+	list_for_each_entry_safe(object, t, &release_ops_list, node) {
+		async_msg->op_release.obj[i] = object->info.object_ptr;
+
+		/* Move object to the oic's object_head.
+		 * We only free objects in '__release__async_queued_reqs' if QTEE
+		 * acknowledge the release; otherwise, move back objects to 'release_ops_list'
+		 * in '__revive__async_queued_reqs'.
+		 */
+
+		list_move(&object->node, &oic->objects_head);
+
+		if (size - ASYNC_OP_RELEASE_SIZE < ASYNC_OP_RELEASE_MSG_SIZE(++i))
+			break;
+	}
+
+	mutex_unlock(&async_ops_mutex);
+
+	/* INITIALIZE the header and message. */
+
+	if (i) {
+		async_msg->header.version = 0x00010002U;
+		async_msg->header.op = ASYNC_OP_RELEASE;
+		async_msg->op_release.count = i;
+	}
+
+	return (i) ? ASYNC_OP_RELEASE_MSG_SIZE(i) : 0;
+}
+
+static void revive_async_queued_reqs(struct si_object *object)
+{
+	if (!kref_read(&object->refcount)) {
+
+		/* Move it back to 'release_ops_list' and retry again. */
+
+		mutex_lock(&async_ops_mutex);
+		list_add(&object->node, &release_ops_list);
+		mutex_unlock(&async_ops_mutex);
+
+	} else {
+		/* Two Puts, one for a get in 'call_prepare' and */
+		put_si_object(object);
+
+		/* ... try to RELEASE the object. */
+		put_si_object(object);
+	}
+}
+
+static void destroy_user_object(struct si_object *object)
+{
+	if (!kref_read(&object->refcount)) {
+		kfree(object->name);
+
+		/* QTEE release should be done! free the object. */
+		free_si_object(object);
+	} else {
+
+		/* Put object we got in 'call_prepare'. */
+		put_si_object(object);
+	}
+}
+
+ssize_t release_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	struct si_object *object;
+	size_t len = 0;
+
+	mutex_lock(&async_ops_mutex);
+	list_for_each_entry(object, &release_ops_list, node)
+		len += scnprintf(buf + len, PAGE_SIZE - len, "%s\n", si_object_name(object));
+	mutex_unlock(&async_ops_mutex);
+
+	return len;
+}
+
+#else /* CONFIG_QCOM_SI_CORE_WQ */
+static size_t async_release_provider(struct si_object_invoke_ctx *oic,
+	struct async_msg *async_msg, size_t size)
+{
+	return 0;
+}
+
+static void revive_async_queued_reqs(struct si_object *object)
+{
+	/* Two Puts, one for a get in 'call_prepare' and */
+	put_si_object(object);
+
+	/* ... try to RELEASE the object. */
+	put_si_object(object);
+}
+
+static void destroy_user_object(struct si_object *object)
+{
+	/* Put object we got in 'call_prepare'. */
+	put_si_object(object);
+}
+
+#endif /* CONFIG_QCOM_SI_CORE_WQ */
+
+/* Object prepare. */
+
+static void call_prepare(struct si_object_invoke_ctx *oic,
+	unsigned int object_id, struct si_buffer *async_buffer)
+{
+	struct async_msg *async_msg = async_buffer->addr;
+
+	switch (si_object_type(object_id)) {
+	case SI_OT_CB_OBJECT: {
+		struct si_object *object, *t_object;
+		struct si_arg args[3] = { 0 };
+
+		/* We are sure 'async_buffer' has enough space for a header. */
+
+		args[0].b.addr = async_buffer->addr + ASYNC_OP_USER_HDR_SIZE;
+		args[0].b.size = async_buffer->size - ASYNC_OP_USER_HDR_SIZE;
+		args[0].type = SI_AT_OB;
+		args[1].type = SI_AT_OO;
+
+		object = qtee_get_si_object(object_id);
+
+		/* We do not expect 'object' to be NULL_SI_OBJECT. */
+
+		if (object->ops->prepare) {
+			unsigned long op = object->ops->prepare(object, args);
+
+			if (op != SI_OBJECT_OP_NO_OP) {
+				t_object = args[1].o;
+
+				/* Object's provider has done some preparation on the object. */
+
+				async_msg->info.async_info.owner = object_id;
+
+				if (typeof_si_object(t_object) != SI_OT_NULL) {
+					if (get_object_id(t_object,
+						&async_msg->info.async_info.out)) {
+						put_si_object(t_object);
+
+						break;
+					}
+
+					/* We temporarily keep si_object for ourselves; get one. */
+					get_si_object(t_object);
+
+					list_add_tail(&t_object->node, &oic->objects_head);
+				}
+
+				async_msg->info.count = 1;
+				async_msg->header.version = 0x00010002U;
+				async_msg->header.op = op;
+
+				/* Move forward. */
+
+				async_buffer->addr += align_offset(args[0].b.size +
+					ASYNC_OP_USER_HDR_SIZE);
+				async_buffer->size -= align_offset(args[0].b.size +
+					ASYNC_OP_USER_HDR_SIZE);
+			}
+		}
+
+		put_si_object(object);
+	}
+
+		break;
+	case SI_OT_USER:
+	case SI_OT_NULL:
+	default:
+
+		break;
+	}
+}
+
+void prepare_objects(struct si_object_invoke_ctx *oic, struct si_buffer async_buffer)
+{
+	int i;
+
+	if (!(oic->flags & OIC_FLAG_BUSY)) {
+		/* Use input message buffer in 'oic'; Process input objects. */
+
+		struct qtee_object_invoke *msg = (struct qtee_object_invoke *)oic->in.msg.addr;
+
+		for_each_input_object(i, msg->counts) {
+			if (async_buffer.size < ASYNC_OP_USER_HDR_SIZE)
+				break;
+
+			call_prepare(oic, msg->args[i].o, &async_buffer);
+		}
+
+	} else {
+		/* Use output message buffer in 'oic'; Process output objects. */
+
+		struct qtee_callback *msg = (struct qtee_callback *)oic->out.msg.addr;
+
+		for_each_output_object(i, msg->counts) {
+			if (async_buffer.size < ASYNC_OP_USER_HDR_SIZE)
+				break;
+
+			call_prepare(oic, msg->args[i].o, &async_buffer);
+		}
+	}
+}
+
+/* '__append__async_reqs',
+ * '__revive__async_queued_reqs', and
+ * '__release__async_queued_reqs'.
+ */
+
+/* '__append__async_reqs' is a provider dispatcher (from si_core to QTEE). */
+
+void __append__async_reqs(struct si_object_invoke_ctx *oic)
+{
+	size_t size;
+
+	struct si_buffer async_buffer = async_si_buffer(oic);
+
+	pr_debug("%u.\n", oic->context_id);
+
+	/* Processe RELEASE requests first. */
+	size = async_release_provider(oic, async_buffer.addr, async_buffer.size);
+
+	/* Let's use whatever buffer left for remaining of async messages. */
+
+	async_buffer.addr += align_offset(size);
+	async_buffer.size -= align_offset(size);
+
+	prepare_objects(oic, async_buffer);
+}
+
+void __revive__async_queued_reqs(struct si_object_invoke_ctx *oic)
+{
+	struct si_object *object, *t;
+
+	pr_debug("%u.\n", oic->context_id);
+
+	/* Something went wrong; QTEE did not recived the async messages. */
+
+	list_for_each_entry_safe(object, t, &oic->objects_head, node) {
+		list_del(&object->node);
+
+		revive_async_queued_reqs(object);
+	}
+
+	INIT_LIST_HEAD(&oic->objects_head);
+}
+
+void __release__async_queued_reqs(struct si_object_invoke_ctx *oic)
+{
+	struct si_object *object, *t;
+
+	pr_debug("%u.\n", oic->context_id);
+
+	list_for_each_entry_safe(object, t, &oic->objects_head, node) {
+		list_del_init(&object->node);
+
+		destroy_user_object(object);
+	}
+}
+
+static size_t async_release_handler(struct si_object_invoke_ctx *oic,
+	struct async_msg *async_msg, size_t size)
+{
+	int i;
+
+	/* We need space for at least a single entry. */
+	if (size < ASYNC_OP_RELEASE_MSG_SIZE(1))
+		return 0;
+
+	for (i = 0; i < async_msg->op_release.count; i++) {
+		struct si_object *object;
+
+		/* Remove the 'object' from 'xa_si_objects' so that the 'object_id'
+		 * becomes invalid for further use. However, call 'put_si_object'
+		 * to schedule the actual release if there is no user.
+		 */
+
+		object = erase_si_object(async_msg->op_release.obj[i]);
+
+		pr_debug("%s (refs: %u).\n", si_object_name(object), kref_read(&object->refcount));
+
+		put_si_object(object);
+	}
+
+	return ASYNC_OP_RELEASE_MSG_SIZE(i);
+}
+
+/* '__fetch__async_reqs' is a handler dispatcher (from QTEE to si_core). */
+
+void __fetch__async_reqs(struct si_object_invoke_ctx *oic)
+{
+	size_t consumed, used = 0;
+
+	struct si_buffer async_buffer = async_si_buffer(oic);
+
+	pr_debug("%u.\n", oic->context_id);
+
+	while (async_buffer.size - used > ASYNC_HEADER_SIZE) {
+		struct async_msg *async_msg = (struct async_msg *)(async_buffer.addr + used);
+
+		/* QTEE assumes unused buffer is set to zero. */
+		if (!async_msg->header.version)
+			goto out;
+
+		switch (async_msg->header.op) {
+		case ASYNC_OP_RELEASE:
+			global_version = async_msg->header.version;
+			consumed = async_release_handler(oic,
+				async_msg, async_buffer.size - used);
+
+			break;
+		default: /* Unsupported operations. */
+			consumed = 0;
+		}
+
+		used += align_offset(consumed);
+
+		if (!consumed) {
+			pr_err("Drop async buffer (context_id %d): buffer %p, (%p, %zx), processed %zx\n",
+				oic->context_id,
+				oic->out.msg.addr,	/* Address of Output buffer. */
+				async_buffer.addr,	/* Address of beginning of async buffer. */
+				async_buffer.size,	/* Available size of async buffer. */
+				used);				/* Processed async buffer. */
+
+			/* Dump a couple of lines from the buffer. */
+			print_hex_dump(KERN_INFO, "si-core: ", DUMP_PREFIX_OFFSET, 16, 4,
+				async_buffer.addr,
+				min(ASYNC_HEADER_SIZE + 88, async_buffer.size),
+				true);
+
+			goto out;
+		}
+	}
+
+ out:
+
+	/* Reset the async buffer for next use in '__append__async_reqs'. */
+	memset(async_buffer.addr, 0, async_buffer.size);
+}
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/si_core_wq.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/si_core_wq.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/workqueue.h>
+#include <linux/slab.h>
+
+#include "si_core.h"
+
+static struct workqueue_struct *si_core_wq;
+
+/* Number of all release requests submitted. */
+static atomic_t pending_releases = ATOMIC_INIT(0);
+
+/* Number of release reqests dropped. */
+static int release_failed;
+
+/* 'release_user_object' put object in release work queue.
+ * 'si_object_do_release' make direct invocation to release an object.
+ * 'destroy_user_object' called to finish the job after QTEE acknowledged the release.
+ */
+
+static void destroy_user_object(struct work_struct *work);
+void release_user_object(struct si_object *object)
+{
+	INIT_WORK(&object->work, destroy_user_object);
+
+	pr_debug("%s queued for release.\n", si_object_name(object));
+
+	atomic_inc(&pending_releases);
+
+	/* QUEUE a release work. */
+	queue_work(si_core_wq, &object->work);
+}
+
+static void si_object_do_release(struct si_object *object)
+{
+	int ret, result;
+
+	/* We are on ordered workqueue; it's safe to do this! */
+	static struct si_object_invoke_ctx oic;
+	static struct si_arg args[1] = { 0 };
+
+	ret = si_object_do_invoke(&oic, object, SI_OBJECT_OP_RELEASE, args, &result);
+
+	if (ret == -EAGAIN) {
+
+		/* On faioure, failure no callback response is in progress. */
+
+		pr_debug("%s rescheduled for release.\n", si_object_name(object));
+
+		queue_work(si_core_wq, &object->work);
+	} else {
+
+		/* On failure, there are two scenarios:
+		 *  - ret != 0 while retuning a callback response.
+		 *  - ret == 0 and result != 0.
+		 * In any of these case, there is nothing we can do to cleanup.
+		 */
+
+		if (ret || result) {
+			release_failed++;
+
+			pr_err("release failed for %s (%d result = %x); %d objects remain zombie.\n",
+				si_object_name(object), ret, result, release_failed);
+		}
+
+		atomic_dec(&pending_releases);
+
+		kfree(object->name);
+
+		free_si_object(object);
+	}
+}
+
+static void destroy_user_object(struct work_struct *work)
+{
+	struct si_object *object = container_of(work, struct si_object, work);
+
+	pr_debug("%s releasing.\n", si_object_name(object));
+
+	si_object_do_release(object);
+}
+
+ssize_t release_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	return scnprintf(buf, PAGE_SIZE, "%d %d\n",
+		atomic_read(&pending_releases), release_failed);
+}
+
+/* 'init_si_core_wq' and 'destroy_si_core_wq'. */
+
+int init_si_core_wq(void)
+{
+
+	/* We use ordered workqueue. If decide to change to workqueue with more
+	 * concurrency make sure to update 'si_object_do_release'.
+	 */
+
+	si_core_wq = alloc_ordered_workqueue("si_core_wq", 0);
+	if (!si_core_wq) {
+		pr_err("failed to create si_core_wq.\n");
+
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+void destroy_si_core_wq(void)
+{
+	destroy_workqueue(si_core_wq);
+}
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/si_core_xts/Kconfig
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/si_core_xts/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# QCOM SI-CORE XTS driver
+#
+config QCOM_SI_CORE_XTS
+	tristate "Secure QSEE Support"
+	depends on QCOM_SI_CORE
+	help
+	  Enable SMCInvoke driver which supports capability based secure
+	  communication between QTI Secure Execution Environment (QSEE)
+	  and high level operating system. It exposes APIs for both
+	  userspace and kernel clients.
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/si_core_xts/Makefile
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/si_core_xts/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+obj-$(CONFIG_QCOM_SI_CORE_XTS) += qcom_smcinvoke.o
+qcom_smcinvoke-objs	+= qseecom.o smci_kernel.o smci.o
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/si_core_xts/qseecom.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/si_core_xts/qseecom.c
@@ -0,0 +1,389 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt) "qseecom: %s: " fmt, __func__
+
+#include <dt-bindings/firmware/qcom,scm.h>
+#include <linux/anon_inodes.h>
+#include <linux/delay.h>
+#include <linux/elf.h>
+#include <linux/fdtable.h>
+#include <linux/file.h>
+#include <linux/firmware.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/fs.h>
+#include <linux/kref.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include "smci_internal.h"
+
+#if IS_ENABLED(CONFIG_QSEECOM_COMPAT)
+#include "../IQSEEComCompat.h"
+#include "../IQSEEComCompatAppLoader.h"
+#include "linux/qseecom_api.h"
+#include "misc/qseecom_kernel.h"
+#endif /* CONFIG_QSEECOM_COMPAT */
+
+/* Device for firmware API :0.*/
+extern struct device *smci_dev;
+
+#define MAX_FW_APP_SIZE	256		/* Application name size. */
+#define FILE_EXT_SIZE 5			/* File extension like .mbn etc. */
+
+#if IS_ENABLED(CONFIG_QSEECOM_COMPAT)
+
+const uint32_t CQSEEComCompatAppLoader_UID = 122;
+
+struct qseecom_compat_context {
+	void *dev; /* in/out */
+	unsigned char *sbuf; /* in/out */
+	u32 sbuf_len; /* in/out */
+	uint64_t handle;
+	u8 app_arch;
+	struct Object client_env;
+	struct Object app_loader;
+	struct Object app_controller;
+};
+
+char *firmware_request_from_smcinvoke(const char *appname, size_t *fw_size, uint64_t *handle);
+
+static int load_app(struct qseecom_compat_context *cxt, const char *app_name)
+{
+	size_t fw_size = 0;
+	u8 *imgbuf_va = NULL;
+	int ret = 0;
+	char dist_name[MAX_FW_APP_SIZE] = {0};
+	size_t dist_name_len = 0;
+	uint64_t handle;
+
+	if (strnlen(app_name, MAX_FW_APP_SIZE) == MAX_FW_APP_SIZE) {
+		pr_err("The app_name (%s) with length %zu is not valid\n",
+			app_name, strnlen(app_name, MAX_FW_APP_SIZE));
+		return -EINVAL;
+	}
+
+	ret = IQSEEComCompatAppLoader_lookupTA(cxt->app_loader,
+		app_name, strlen(app_name), &cxt->app_controller);
+	if (!ret) {
+		pr_info("app %s exists\n", app_name);
+		return ret;
+	}
+
+	imgbuf_va = firmware_request_from_smcinvoke(app_name, &fw_size, &handle);
+	if (imgbuf_va == NULL) {
+		pr_err("Failed on firmware_request_from_smcinvoke\n");
+		return -EINVAL;
+	}
+
+	ret = IQSEEComCompatAppLoader_loadFromBuffer(
+			cxt->app_loader, imgbuf_va, fw_size,
+			app_name, strlen(app_name),
+			dist_name, MAX_FW_APP_SIZE, &dist_name_len,
+			&cxt->app_controller);
+	if (ret) {
+		pr_err("loadFromBuffer failed for app %s, ret = %d\n",
+				app_name, ret);
+		goto exit_release_shm;
+	}
+	cxt->app_arch = *(uint8_t *)(imgbuf_va + EI_CLASS);
+
+	pr_info("%s %d, loaded app %s, dist_name %s, dist_name_len %zu\n",
+		__func__, __LINE__, app_name, dist_name, dist_name_len);
+
+exit_release_shm:
+	qcom_tzmem_deregister(handle);
+	free_pages((long)imgbuf_va, get_order(*fw_size));
+	return ret;
+}
+
+static int __qseecom_start_app(struct qseecom_handle **handle,
+	char *app_name, uint32_t size)
+{
+	int ret = 0;
+	struct qseecom_compat_context *cxt = NULL;
+
+	pr_warn("%s, start app %s, size %u\n",
+		__func__, app_name, size);
+	if (app_name == NULL || handle == NULL) {
+		pr_err("app_name is null or invalid handle\n");
+		return -EINVAL;
+	}
+	/* allocate qseecom_compat_context */
+	cxt = kzalloc(sizeof(struct qseecom_compat_context), GFP_KERNEL);
+	if (!cxt)
+		return -ENOMEM;
+
+	/* get client env */
+	ret = get_client_env_object(&cxt->client_env);
+	if (ret) {
+		pr_err("failed to get clientEnv when loading app %s, ret %d\n",
+			app_name, ret);
+		ret = -EINVAL;
+		goto exit_free_cxt;
+	}
+	/* get apploader with CQSEEComCompatAppLoader_UID */
+	ret = IClientEnv_open(cxt->client_env, CQSEEComCompatAppLoader_UID,
+				&cxt->app_loader);
+	if (ret) {
+		pr_err("failed to get apploader when loading app %s, ret %d\n",
+			app_name, ret);
+		ret = -EINVAL;
+		goto exit_release_clientenv;
+	}
+
+	/* load app*/
+	ret = load_app(cxt, app_name);
+	if (ret) {
+		pr_err("failed to load app %s, ret = %d\n",
+			app_name, ret);
+		ret = -EINVAL;
+		goto exit_release_apploader;
+	}
+
+	/* Align size with page_size as __get_free_pages expect page aligned size. */
+	size = PAGE_ALIGN(size);
+
+	/* Get the physical address of the req/resp buffer */
+	cxt->sbuf = (unsigned char *)__get_free_pages(GFP_KERNEL | __GFP_COMP | GFP_DMA32,
+							get_order(size));
+	if (!cxt->sbuf) {
+		ret = -EINVAL;
+		goto exit_release_appcontroller;
+	}
+
+	ret = qcom_tzmem_register(__pa(cxt->sbuf), size,
+				(uint32_t[]){ QCOM_SCM_VMID_HLOS },
+				(uint32_t[]){ QCOM_SCM_PERM_RW }, 1, QCOM_SCM_PERM_RW,
+				&cxt->handle);
+	if (ret) {
+		pr_err("failed to create bridge for req/rsp buffer, ret: %d\n", ret);
+		free_pages((long)cxt->sbuf, get_order(size));
+		ret = -EINVAL;
+		goto exit_release_appcontroller;
+	}
+
+	cxt->sbuf_len = size;
+	*handle = (struct qseecom_handle *)cxt;
+
+	return ret;
+
+exit_release_appcontroller:
+	Object_release(cxt->app_controller);
+exit_release_apploader:
+	Object_release(cxt->app_loader);
+exit_release_clientenv:
+	Object_release(cxt->client_env);
+exit_free_cxt:
+	kfree(cxt);
+
+	return ret;
+}
+
+static int __qseecom_shutdown_app(struct qseecom_handle **handle)
+{
+	struct qseecom_compat_context *cxt = NULL;
+
+	if ((handle == NULL) || (*handle == NULL)) {
+		pr_err("Handle is NULL\n");
+		return -EINVAL;
+	}
+
+	cxt = (struct qseecom_compat_context *)(*handle);
+
+	qcom_tzmem_deregister(cxt->handle);
+	free_pages((long)cxt->sbuf, get_order(cxt->sbuf_len));
+	Object_release(cxt->app_controller);
+	Object_release(cxt->app_loader);
+	Object_release(cxt->client_env);
+	kfree(cxt);
+	*handle = NULL;
+	return 0;
+}
+
+static int __qseecom_send_command(struct qseecom_handle *handle,
+	void *send_buf, uint32_t sbuf_len, void *resp_buf, uint32_t rbuf_len)
+{
+struct qseecom_compat_context *cxt =
+		(struct qseecom_compat_context *)handle;
+	size_t out_len = 0;
+
+	pr_debug("%s, sbuf_len %u, rbuf_len %u\n",
+		__func__, sbuf_len, rbuf_len);
+
+	if (!handle || !send_buf || !resp_buf || !sbuf_len || !rbuf_len) {
+		pr_err("One of params is invalid. %s, handle %p, send_buf %p,resp_buf %p,sbuf_len %u, rbuf_len %u\n",
+			 __func__, handle, send_buf, resp_buf, sbuf_len, rbuf_len);
+		return -EINVAL;
+	}
+	return IQSEEComCompat_sendRequest(cxt->app_controller,
+				  send_buf, sbuf_len,
+				  resp_buf, rbuf_len,
+				  send_buf, sbuf_len, &out_len,
+				  resp_buf, rbuf_len, &out_len,
+				  NULL, 0, /* embedded offset array */
+				  (cxt->app_arch == ELFCLASS64),
+				  Object_NULL, Object_NULL,
+				  Object_NULL, Object_NULL);
+}
+
+static int __qseecom_process_listener_from_smcinvoke(uint32_t *result,
+		u64 *response_type, unsigned int *data)
+{
+	/* this API is not supported by compat */
+	pr_debug("%s is not supported by compat\n", __func__);
+	return -EOPNOTSUPP;
+}
+
+int qseecom_start_app(struct qseecom_handle **handle, char *app_name, uint32_t size)
+{
+	return __qseecom_start_app(handle, app_name, size);
+}
+EXPORT_SYMBOL_GPL(qseecom_start_app);
+
+int qseecom_shutdown_app(struct qseecom_handle **handle)
+{
+	return __qseecom_shutdown_app(handle);
+}
+EXPORT_SYMBOL_GPL(qseecom_shutdown_app);
+
+int qseecom_send_command(struct qseecom_handle *handle, void *send_buf,
+	uint32_t sbuf_len, void *resp_buf, uint32_t rbuf_len)
+{
+	return __qseecom_send_command(handle, send_buf, sbuf_len, resp_buf, rbuf_len);
+}
+EXPORT_SYMBOL_GPL(qseecom_send_command);
+
+int qseecom_process_listener_from_smcinvoke(uint32_t *result,
+		u64 *response_type, unsigned int *data)
+{
+	return __qseecom_process_listener_from_smcinvoke(result,
+		response_type, data);
+}
+EXPORT_SYMBOL_GPL(qseecom_process_listener_from_smcinvoke);
+
+#endif /* CONFIG_QSEECOM_COMPAT */
+
+char *firmware_request_from_smcinvoke(const char *appname, size_t *fw_size, uint64_t *handle)
+{
+	int rc = 0;
+	const struct firmware *fw_entry = NULL, *fw_entry00 = NULL, *fw_entrylast = NULL;
+	char fw_name[MAX_FW_APP_SIZE + FILE_EXT_SIZE] = "\0";
+	int num_images = 0, phi = 0;
+	unsigned char app_arch = 0;
+	u8 *img_data_ptr = NULL;
+	size_t bufferOffset = 0, phdr_table_offset = 0;
+	size_t *offset = NULL;
+	Elf32_Phdr phdr32;
+	Elf64_Phdr phdr64;
+	struct elf32_hdr *ehdr = NULL;
+	struct elf64_hdr *ehdr64 = NULL;
+
+
+	/* load b00*/
+	snprintf(fw_name, sizeof(fw_name), "%s.b00", appname);
+	rc = firmware_request_nowarn(&fw_entry00, fw_name, smci_dev);
+	if (rc) {
+		pr_err("Load %s failed, ret:%d\n", fw_name, rc);
+		return NULL;
+	}
+
+	app_arch = *(unsigned char *)(fw_entry00->data + EI_CLASS);
+
+	/*Get the offsets for split images header*/
+	if (app_arch == ELFCLASS32) {
+
+		ehdr = (struct elf32_hdr *)fw_entry00->data;
+		num_images = ehdr->e_phnum;
+		offset = kcalloc(num_images, sizeof(size_t), GFP_KERNEL);
+		if (offset == NULL)
+			goto release_fw_entry00;
+		phdr_table_offset = (size_t) ehdr->e_phoff;
+		for (phi = 1; phi < num_images; ++phi) {
+			bufferOffset = phdr_table_offset + phi * sizeof(Elf32_Phdr);
+			phdr32 = *(Elf32_Phdr *)(fw_entry00->data + bufferOffset);
+			offset[phi] = (size_t)phdr32.p_offset;
+		}
+
+	} else if (app_arch == ELFCLASS64) {
+
+		ehdr64 = (struct elf64_hdr *)fw_entry00->data;
+		num_images = ehdr64->e_phnum;
+		offset = kcalloc(num_images, sizeof(size_t), GFP_KERNEL);
+		if (offset == NULL)
+			goto release_fw_entry00;
+		phdr_table_offset = (size_t) ehdr64->e_phoff;
+		for (phi = 1; phi < num_images; ++phi) {
+			bufferOffset = phdr_table_offset + phi * sizeof(Elf64_Phdr);
+			phdr64 = *(Elf64_Phdr *)(fw_entry00->data + bufferOffset);
+			offset[phi] = (size_t)phdr64.p_offset;
+		}
+
+	} else {
+
+		pr_err("QSEE %s app, arch %u is not supported\n", appname, app_arch);
+		goto release_fw_entry00;
+	}
+
+	/*Find the size of last split bin image*/
+	snprintf(fw_name, ARRAY_SIZE(fw_name), "%s.b%02d", appname, num_images-1);
+	rc = firmware_request_nowarn(&fw_entrylast, fw_name, smci_dev);
+	if (rc) {
+		pr_err("Failed to locate blob %s\n", fw_name);
+		goto release_fw_entry00;
+	}
+
+	/*Total size of image will be the offset of last image + the size of last split image*/
+	*fw_size = fw_entrylast->size + offset[num_images-1];
+	*fw_size = PAGE_ALIGN(*fw_size);
+
+	/*Allocate memory for the buffer that will hold the split image*/
+	img_data_ptr = (u8 *)__get_free_pages(GFP_KERNEL|__GFP_COMP|GFP_DMA32,
+						get_order(*fw_size));
+	if (!img_data_ptr) {
+		pr_err("failed to allocate memory for size: %zu\n", *fw_size);
+		goto release_fw_entrylast;
+	}
+
+	rc = qcom_tzmem_register(__pa((unsigned long) img_data_ptr), *fw_size,
+				(uint32_t[]){ QCOM_SCM_VMID_HLOS },
+				(uint32_t[]){ QCOM_SCM_PERM_RW }, 1, QCOM_SCM_PERM_RW,
+				handle);
+	if (rc) {
+		pr_err("failed to create bridge for buffer, rc: %d, size: %zu\n", rc, *fw_size);
+		free_pages((long)img_data_ptr, get_order(*fw_size));
+		goto release_fw_entrylast;
+	}
+
+	/*
+	 * Copy contents of split bins to the buffer
+	 */
+	memcpy(img_data_ptr, fw_entry00->data, fw_entry00->size);
+	for (phi = 1; phi < num_images-1; phi++) {
+		snprintf(fw_name, ARRAY_SIZE(fw_name), "%s.b%02d", appname, phi);
+		rc = firmware_request_nowarn(&fw_entry, fw_name, smci_dev);
+		if (rc) {
+			pr_err("Failed to locate blob %s\n", fw_name);
+			qcom_tzmem_deregister(*handle);
+			free_pages((long)img_data_ptr, get_order(*fw_size));
+			img_data_ptr = NULL;
+			goto release_fw_entrylast;
+		}
+		memcpy(img_data_ptr + offset[phi], fw_entry->data, fw_entry->size);
+		release_firmware(fw_entry);
+		fw_entry = NULL;
+	}
+	memcpy(img_data_ptr + offset[phi], fw_entrylast->data, fw_entrylast->size);
+
+release_fw_entrylast:
+	release_firmware(fw_entrylast);
+release_fw_entry00:
+	release_firmware(fw_entry00);
+	kfree(offset);
+	return img_data_ptr;
+}
+EXPORT_SYMBOL_GPL(firmware_request_from_smcinvoke);
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/si_core_xts/smci.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/si_core_xts/smci.c
@@ -0,0 +1,1781 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt) "smcinvoke: %s: " fmt, __func__
+
+#include <linux/module.h>
+#include <linux/file.h>
+#include <linux/dma-buf.h>
+#include <linux/mem-buf.h>
+#include <linux/freezer.h>
+#include <linux/cdev.h>
+#include <linux/version.h>
+#include <linux/anon_inodes.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+
+#if IS_ENABLED(CONFIG_QSEECOM_COMPAT)
+#include "misc/qseecom_kernel.h"
+#endif
+
+# undef OBJECT_OP_METHOD_MASK
+
+#include "smci_impl.h"
+
+#include <linux/firmware/qcom/si_core_xts.h>
+
+#define SMCI_DEVICE_NAME "smcinvoke"
+#define SMCI_CLASS "smcinvoke-class"
+
+static DEFINE_MUTEX(si_mutex);
+
+static const struct file_operations qtee_fops;
+static const struct file_operations server_fops;
+
+static struct si_object_operations cbo_sio_ops;
+
+/* 'struct cb_object' is a userspace callback object. */
+
+struct cb_object {
+	struct si_object object;
+
+	/* If set, we will notify the userspace server about the release of object. */
+	int notify_on_release;
+
+	/* 'u_handle' + 'server_info' combo that represents this object.*/
+
+	/* 'si' keeps a refcounted copy of server_info. If userspace server dies,
+	 * we keep 'si' around until QTEE releases all instances of cb_objects.
+	 */
+
+	struct {
+		s64 u_handle;
+
+		struct server_info *si;
+	};
+};
+
+#define to_cb_object(o) container_of((o), struct cb_object, object)
+
+static int is_cb_object(struct si_object *object)
+{
+	/* Check 'typeof_si_object' to make sure 'object''s 'ops' has been
+	 * initialized before checking it.
+	 */
+
+	return (typeof_si_object(object) == SI_OT_CB_OBJECT) &&
+		(object->ops == &cbo_sio_ops);
+}
+
+/* U_HANDLE allocation and mapping to instance of 'file'. */
+
+static int u_handle_alloc(const char *name, const struct file_operations *fops,
+	void *private, s64 *u_handle)
+{
+	int fd;
+
+	struct file *file;
+
+	fd = get_unused_fd_flags(O_RDWR);
+	if (fd < 0)
+		return fd;
+
+	file = anon_inode_getfile(name, fops, private, O_RDWR);
+	if (IS_ERR(file)) {
+		put_unused_fd(fd);
+
+		return PTR_ERR(file);
+	}
+
+	fd_install(fd, file);
+	*u_handle = fd;
+
+	pr_debug("fd %d assigned for %s.\n", fd, name);
+
+	return 0;
+}
+
+static struct file *get_file_of_type(int fd, const struct file_operations *fop)
+{
+	struct file *filp = fget(fd);
+
+	if (!filp)
+		return NULL;
+
+	if (filp->f_op != fop) {
+		fput(filp);
+
+		return NULL;
+	}
+
+	return filp;
+}
+
+#define get_qtee_file(uh)		get_file_of_type((uh), &qtee_fops)
+#define get_cb_server_file(uh)	get_file_of_type((uh), &server_fops)
+
+/* That's how userspace distinguish object domain. But why!? */
+/* 'U_HANDLE_IS_OBJECT' represents HLOS and QTEE domains. */
+#define U_HANDLE_IS_OBJECT(uh)		((uh) >= 0)
+#define U_HANDLE_IS_NULL(uh)		((uh) == SMCINVOKE_USERSPACE_OBJ_NULL)
+#define U_HANDLE_IS_CB_OBJECT(uh)	((uh) < SMCINVOKE_USERSPACE_OBJ_NULL)
+
+/* SI_OBJECT to/from U_HANDLE. */
+
+/* 'get_si_object_from_u_handle': converts a u_handle to instance of si_object.
+ * It calls 'get_si_object' before returning (i.e. ref == 2) for all objects
+ * except 'SI_OT_USER'; One reference for QTEE and one for driver itself.
+ */
+
+static struct cb_object *cb_object_alloc(s64 server_id)
+{
+	struct file *filp;
+	struct cb_object *cb_object;
+
+	filp = get_cb_server_file(server_id);
+	if (!filp)
+		return ERR_PTR(-EBADF);
+
+	cb_object = kzalloc(sizeof(*cb_object), GFP_KERNEL);
+	if (cb_object) {
+
+		/* Default is to always notify the callback server. */
+		cb_object->notify_on_release = 1;
+		cb_object->si = filp->private_data;
+
+		/* We put 'filp' (below) while keeping the instance of 'server_info'.
+		 * We want to receive the file's release callback for server if server dies.
+		 * This will keep the 'server_info' instance alive as long as the cb_object exists.
+		 */
+
+		kref_get(&cb_object->si->refcount);
+
+	} else
+		cb_object = ERR_PTR(-ENOMEM);
+
+	fput(filp);
+
+	return cb_object;
+}
+
+static void mem_object_release(void *private);
+static int get_si_object_from_u_handle(struct smcinvoke_obj *o, struct si_arg *arg)
+{
+	int ret = 0;
+
+	struct si_object *object;
+
+	/* The 'U_HANDLE' instance mapped to 'si_object'. */
+	s64 u_handle = o->fd;
+
+	if (U_HANDLE_IS_NULL(u_handle)) {
+		object = NULL_SI_OBJECT;
+
+	} else if (U_HANDLE_IS_CB_OBJECT(u_handle)) {
+		struct cb_object *cb_object;
+
+		/* We always allocate a 'cb_object' instance. 'u_handle' has meaning only
+		 * in the context of callback server. Having a same 'u_handle' does not
+		 * necessarily means objects are the same!
+		 */
+
+		cb_object = cb_object_alloc(o->cb_server_fd);
+		if (!IS_ERR(cb_object)) {
+
+			/* 'cb_object' represent an object in 'si'. */
+
+			cb_object->u_handle = u_handle;
+			init_si_object_user(&cb_object->object, SI_OT_CB_OBJECT, &cbo_sio_ops,
+				"cbo-%s%d", cb_object->si->comm, u_handle);
+
+			object = &cb_object->object;
+
+			get_si_object(object);
+		} else
+			ret = PTR_ERR(cb_object);
+
+	} else { /* 'U_HANDLE_IS_OBJECT'. */
+		struct dma_buf *dma_buf;
+
+		dma_buf = dma_buf_get(u_handle);
+		if (!IS_ERR(dma_buf)) {
+
+			struct cb_object *x_cb;
+
+			/* This is an effort to simulate the invalid fix propagted deep
+			 * in userspace. See: 'mem_object_release'. If IS_ERR(x_cb), we will
+			 * proceed without the mem-object RELEASE but will print a warning
+			 * for leak in 'mem_object_release'.
+			 */
+
+			/* BUG!!! This assumes only callback server is sending a memory object;
+			 * It assumes memory object ALWAYS should belong to a server, i.e.
+			 * 'cb_server_fd' MUST be valid. I can not fix it.
+			 */
+
+			x_cb = cb_object_alloc(o->cb_server_fd);
+			if (!IS_ERR(x_cb))
+				x_cb->u_handle = u_handle;
+
+			object = init_si_mem_object_user(dma_buf, mem_object_release,
+				IS_ERR(x_cb) ? NULL : x_cb);
+
+			if (!object)
+				ret = -EINVAL;
+
+			get_si_object(object);
+
+			/* 'init_si_mem_object_user' calls 'dma_buf_get' internally. */
+			dma_buf_put(dma_buf);
+		} else {
+			struct file *filp;
+
+			filp = get_qtee_file(u_handle);
+			if (filp) {
+				object = filp->private_data;
+
+				/* We put 'filp' while keeping the instance of object. */
+				get_si_object(object);
+
+				fput(filp);
+			} else
+				ret = -EINVAL;
+		}
+	}
+
+	if (ret) {
+
+		/* Return 'NULL' as default. */
+
+		object = NULL_SI_OBJECT;
+	}
+
+	arg->o = object;
+
+	return ret;
+}
+
+/* 'get_u_handle_from_si_object': converts 'object' to 'u_handle'.
+ * On SUCCESS, it calls 'put_si_object' before returning for all objects except
+ * 'SI_OT_USER'.
+ */
+
+static int get_u_handle_from_si_object(struct si_object *object,
+	s64 *u_handle, struct server_info **si)
+{
+	int ret = 0;
+
+	if (si)
+		*si = NULL;
+
+	switch (typeof_si_object(object)) {
+	case SI_OT_NULL:
+		*u_handle = SMCINVOKE_USERSPACE_OBJ_NULL;
+
+		break;
+	case SI_OT_CB_OBJECT: {
+
+		/* Check for memory object or an object in a callback server!? */
+
+		if (is_mem_object(object)) {
+			struct dma_buf *dma_buf = mem_object_to_dma_buf(object);
+
+			get_dma_buf(dma_buf);
+			*u_handle = dma_buf_fd(dma_buf, O_CLOEXEC);
+			if (*u_handle < 0) {
+				dma_buf_put(dma_buf);
+
+				ret = -EBADF;
+			} else
+				put_si_object(object);
+
+		} else {
+			struct cb_object *cb_object = to_cb_object(object);
+
+			*u_handle = cb_object->u_handle;
+
+			if (si)
+				*si = cb_object->si;
+
+			/* We put 'object'. 'u_handle' has meaning only in the context
+			 * of callback server. QTEE will not release it as long as a request
+			 * is in progress in a callback server.
+			 */
+
+			put_si_object(object);
+		}
+	}
+
+		break;
+	case SI_OT_USER:
+
+		/* On SUCCESS, we do not put 'object' unlike object of 'SI_OT_CB_OBJECT'
+		 * type. Because, it is used by file's 'private_data'.
+		 */
+
+		if (u_handle_alloc(si_object_name(object), &qtee_fops, object, u_handle))
+			ret = -EBADF;
+
+		break;
+	case SI_OT_ROOT:
+	default:
+		ret = -EBADF;
+
+		break;
+	}
+
+	if (ret)
+		*u_handle = SMCINVOKE_USERSPACE_OBJ_NULL;
+
+	return ret;
+}
+
+/* Marshaling API. */
+/* 'marshal_in_req' Prepare input buffer for sending to QTEE.
+ * 'marshal_out_req' Parse QTEE response in input buffer.
+ * 'marshal_in_cb_req' Parse QTEE request from output buffer.
+ * 'marshal_out_cb_req' Update output buffer with response for QTEE request.
+ *
+ * 'marshal_in_req' and 'marshal_out_req' are used in direct invocation path.
+ * 'marshal_in_cb_req' and 'marshal_out_cb_req' are used for QTEE request.
+ */
+
+static void marshal_in_req_cleanup(struct si_arg u[], int notify)
+{
+	int i;
+	struct si_object *object;
+
+	for (i = 0; u[i].type; i++) {
+		switch (u[i].type) {
+		case SI_AT_IO:
+
+			object = u[i].o;
+
+			/* For cb_objects, we will notify userspace of its release.
+			 * On failure, we should not do that.
+			 */
+
+			if (is_cb_object(object))
+				to_cb_object(object)->notify_on_release = notify;
+
+			/* For object of type SI_OT_USER, 'get_si_object_from_u_handle' does
+			 * not call 'get_si_object' before returning (i.e. ref == 1). Replace
+			 * it with NULL_SI_OBJECT as after 'put_si_object', u[i].o is invalid.
+			 */
+
+			else if (typeof_si_object(object) == SI_OT_USER)
+				u[i].o = NULL_SI_OBJECT;
+
+			put_si_object(object);
+
+			break;
+		case SI_AT_IB:
+		case SI_AT_OB:
+		case SI_AT_OO:
+		default:
+
+			break;
+		}
+	}
+}
+
+static int marshal_in_req(struct si_arg u[], union smcinvoke_arg args[], u32 counts)
+{
+	int i, err = 0;
+
+	FOR_ARGS(i, counts, BI) {
+		u[i].type = SI_AT_IB;
+		u[i].flags = SI_ARG_FLAGS_UADDR;
+		u[i].b.uaddr = u64_to_user_ptr(args[i].b.addr);
+		u[i].b.size = args[i].b.size;
+	}
+
+	FOR_ARGS(i, counts, BO) {
+		u[i].type = SI_AT_OB;
+		u[i].flags = SI_ARG_FLAGS_UADDR;
+		u[i].b.uaddr = u64_to_user_ptr(args[i].b.addr);
+		u[i].b.size = args[i].b.size;
+	}
+
+	FOR_ARGS(i, counts, OI) {
+		u[i].type = SI_AT_IO;
+
+		if (!err)
+			err = get_si_object_from_u_handle(&args[i].o, &u[i]);
+		else
+			u[i].o = NULL_SI_OBJECT;
+	}
+
+	FOR_ARGS(i, counts, OO)
+		u[i].type = SI_AT_OO;
+
+	u[i].type = SI_AT_END;
+
+	if (!err)
+		return 0;
+
+	/* Release whatever resources we got in 'u'. */
+	/* Return with clean slate. */
+
+	marshal_in_req_cleanup(u, 0);
+
+	/* Here, drop QTEE istances; on Success QTEE does that. */
+
+	for (i = 0; u[i].type; i++) {
+		if (u[i].type == SI_AT_IO &&
+			typeof_si_object(u[i].o) != SI_OT_USER)
+			put_si_object(u[i].o);
+	}
+
+	return -1;
+}
+
+/* 'marshal_out_req' consumes 'u' as initialized by 'marshal_in_req' to fill 'args'. */
+
+static int marshal_out_req(union smcinvoke_arg args[], struct si_arg u[])
+{
+	int i = 0, err = 0;
+
+	while (u[i].type == SI_AT_IB)
+		i++;
+
+	while (u[i].type == SI_AT_OB) {
+		args[i].b.size = u[i].b.size;
+
+		i++;
+	}
+
+	while (u[i].type == SI_AT_IO) {
+
+		/* 'get_si_object_from_u_handle' increases the refcount of all si_object
+		 * instances. We drop the temporary reference.
+		 */
+
+		put_si_object(u[i].o);
+
+		i++;
+	}
+
+	while (u[i].type == SI_AT_OO) {
+
+		/* 'get_u_handle_from_si_object' convert the si_object instances to a
+		 * u_handle and put the reference counter. On failure, we do not need to
+		 * continue with heavy work anymore.
+		 */
+
+		if (err) {
+
+			/* Last iteration FAILED. Use an easy way out. */
+
+			args[i].o.fd = SMCINVOKE_USERSPACE_OBJ_NULL;
+
+			put_si_object(u[i].o);
+		} else if (get_u_handle_from_si_object(u[i].o, &args[i].o.fd, NULL)) {
+			put_si_object(u[i].o);
+
+			err = -1;
+		}
+
+		i++;
+	}
+
+	if (!err)
+		return 0;
+
+	/* Release whatever resources we got in 'args'! */
+	/* Return with clean slate. */
+
+	for (i = 0; u[i].type; i++) {
+		if (u[i].type == SI_AT_OO) {
+			if (U_HANDLE_IS_OBJECT(args[i].o.fd)) {
+
+				/* This is a file descriptor. Need cleanup. */
+				/* TODO. Cleanup exported object. */
+
+			}
+		}
+	}
+
+	return -1;
+}
+
+/* We assume 'u' is sorted so 'SI_AT_IB', 'SI_AT_OB', following by 'SI_AT_IO', and 'SI_AT_OO'. */
+
+static int marshal_in_cb_req(union smcinvoke_arg args[], void __user *u_args,
+	u32 *counts, struct si_arg u[], struct server_info *target_si)
+{
+	int i = 0, err = 0;
+	int ib = 0, ob = 0, io = 0, oo = 0;
+
+	size_t offset = 0;
+
+	for (; u[i].type == SI_AT_IB; i++) {
+		void __user *u_addr;
+
+		if (!err) {
+			args[i].b.addr = (u64) (u_args + offset);
+			args[i].b.size = u[i].b.size;
+
+			u_addr = u64_to_user_ptr(args[i].b.addr);
+
+			if (copy_to_user(u_addr, u[i].b.addr, u[i].b.size))
+				err = -1;
+
+			offset = ALIGN(offset + u[i].b.size, 8);
+		}
+	}
+
+	ib = i;
+
+	for (; u[i].type == SI_AT_OB; i++) {
+		if (!err) {
+			args[i].b.addr = (u64) (u_args + offset);
+			args[i].b.size = u[i].b.size;
+
+			offset = ALIGN(offset + u[i].b.size, 8);
+		}
+	}
+
+	ob = i;
+
+	for (; u[i].type == SI_AT_IO; i++) {
+		struct server_info *si;
+
+		if (!err) {
+			if (get_u_handle_from_si_object(u[i].o, &args[i].o.fd, &si)) {
+				put_si_object(u[i].o);
+
+				err = -1;
+			}
+
+			if (target_si && si && si != target_si)
+				err = -1;
+		} else {
+
+			/* Last iteration FAILED. Use an easy way out. */
+
+			args[i].o.fd = SMCINVOKE_USERSPACE_OBJ_NULL;
+
+			put_si_object(u[i].o);
+		}
+	}
+
+	io = i;
+
+	for (; u[i].type == SI_AT_OO; i++)
+		;
+
+	oo = i;
+
+	if (!err) {
+		*counts = 0;
+		*counts |= ((oo - io) & 0xFU) << 12;	/* No. Output Objects. */
+		*counts |= ((io - ob) & 0xFU) << 8;		/* No. Input Objects. */
+		*counts |= ((ob - ib) & 0xFU) << 4;		/* No. Output Buffer. */
+		*counts |= (ib & 0xFU);					/* No. Input Buffer. */
+
+		return 0;
+	}
+
+	/* Release whatever resources we got in 'args'! */
+	/* Return with clean slate. */
+
+	for (i = 0; u[i].type; i++) {
+		if (u[i].type == SI_AT_IO) {
+			if (U_HANDLE_IS_OBJECT(args[i].o.fd)) {
+
+				/* This is a file descriptor. Need cleanup. */
+				/* TODO. Cleanup exported object. */
+
+			}
+		}
+	}
+
+	return -1;
+}
+
+static int marshal_out_cb_req(struct si_arg u[], union smcinvoke_arg args[])
+{
+	int i = 0, err = 0;
+
+	while (u[i].type == SI_AT_IB)
+		i++;
+
+	while (u[i].type ==  SI_AT_OB) {
+		void __user *u_addr;
+
+		if (args[i].b.size <= u[i].b.size) {
+			u[i].b.size = args[i].b.size;
+			u_addr = u64_to_user_ptr(args[i].b.addr);
+
+			if (copy_from_user(u[i].b.addr, u_addr, args[i].b.size))
+				return -1;
+		} else
+			return -1;
+
+		i++;
+	}
+
+	while (u[i].type == SI_AT_IO)
+		i++;
+
+	while (u[i].type == SI_AT_OO) {
+
+		/* Client is not aware if a callback has been terminated.
+		 * We temporarily hold a reference for objects as the callback is
+		 * in progress. We drop these references in the objects' notification.
+		 */
+
+		if (err) {
+
+			/* On failure, we do not need to continue with heavy work anymore. */
+
+			u[i].o = NULL_SI_OBJECT;
+		} else
+			err = get_si_object_from_u_handle(&args[i].o, &u[i]);
+
+		i++;
+	}
+
+	if (!err)
+		return 0;
+
+	/* Release whatever resources we got in 'u'. */
+	/* Return with clean slate. */
+
+	for (i = 0; u[i].type; i++) {
+		switch (u[i].type) {
+		case SI_AT_OO:
+
+			/* For cb_objects, we will notify userspace of its release.
+			 * On failure, we should not do that.
+			 */
+
+			if (is_cb_object(u[i].o))
+				to_cb_object(u[i].o)->notify_on_release = 0;
+
+			/* 'get_si_object_from_u_handle' calls 'get_si_object' before
+			 * returning (i.e. ref == 2) for all objects except SI_OT_USER.
+			 * One reference for QTEE and one for driver itself.
+			 */
+
+			if (typeof_si_object(u[i].o) != SI_OT_USER)
+				put_si_object(u[i].o);
+
+			put_si_object(u[i].o);
+
+			break;
+		case SI_AT_IB:
+		case SI_AT_OB:
+		case SI_AT_IO:
+		default:
+
+			break;
+		}
+	}
+
+	return -1;
+}
+
+/* Transaction management. */
+
+static struct cb_txn *txn_alloc(int u_args_n)
+{
+	struct cb_txn *t;
+
+	t = kzalloc(sizeof(*t), GFP_KERNEL);
+	if (!t)
+		return ERR_PTR(-ENOMEM);
+
+	/* 'u_args' is a memory used by 'process_accept_req'. Allocate it here. */
+
+	t->u_args_sz = u_args_n * sizeof(t->u_args[0]);
+	if (t->u_args_sz) {
+		t->u_args = kzalloc(t->u_args_sz, GFP_KERNEL);
+		if (!t->u_args) {
+			kfree(t);
+
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
+	t->processing = XST_NEW;
+	kref_init(&t->refcount);
+	init_completion(&t->completion);
+	INIT_LIST_HEAD(&t->node);
+
+	return t;
+}
+
+static void txn_free(struct cb_txn *cb_txn)
+{
+	int i;
+	struct si_arg *args = cb_txn->args;
+
+	if (args) {
+		for (i = 0; i < size_of_arg(args); i++) {
+			if (args[i].type == SI_AT_IB ||
+				args[i].type == SI_AT_OB)
+				kfree(args[i].b.addr);
+		}
+
+		kfree(args);
+	}
+
+	kfree(cb_txn->u_args);
+	kfree(cb_txn);
+}
+
+static int queue_txn(struct server_info *si, struct cb_txn *cb_txn)
+{
+	int dead;
+
+	mutex_lock(&si_mutex);
+	dead = si->dead;
+	if (!dead) {
+		list_add(&cb_txn->node, &si->cb_tx_list);
+		cb_txn->processing = XST_PENDING;
+	}
+	mutex_unlock(&si_mutex);
+
+	return dead;
+}
+
+static void dequeue_txn_locked(struct cb_txn *cb_txn)
+{
+	list_del_init(&cb_txn->node);
+}
+
+static struct cb_txn *dequeue_txn_by_id(struct server_info *si, unsigned int id)
+{
+	struct cb_txn *t;
+
+	mutex_lock(&si_mutex);
+	list_for_each_entry(t, &si->cb_tx_list, node)
+		if (t->context_id == id) {
+			dequeue_txn_locked(t);
+
+			goto found;
+		}
+
+	t = NULL;
+
+found:
+	mutex_unlock(&si_mutex);
+
+	return t;
+}
+
+static int set_txn_state_locked(struct cb_txn *cb_txn, enum state state)
+{
+	/* Supported state transitions:
+	 * PENDING    -> PROCESSING, XST_TIMEDOUT.
+	 * PROCESSING -> PROCESSED, XST_TIMEDOUT.
+	 */
+
+	/* Moving to PROCESSING state; we should be in PENDING state. */
+	if (state == XST_PROCESSING) {
+		if (cb_txn->processing != XST_PENDING)
+			return -1;
+
+	/* Moving to PROCESSED state; we should be in PROCESSING state. */
+	} else if (state == XST_PROCESSED) {
+		if (cb_txn->processing != XST_PROCESSING)
+			return -1;
+
+	/* Moving to TIMEDOUT state; we should not be in PROCESSED state. */
+	} else if (state == XST_TIMEDOUT) {
+		if (cb_txn->processing != XST_PENDING &&
+			cb_txn->processing != XST_PROCESSING)
+			return -1;
+
+	} else
+		return -1;
+
+	cb_txn->processing = state;
+
+	return 0;
+}
+
+static struct cb_txn *get_txn_for_state_transition_locked(struct server_info *si,
+	unsigned int id, enum state state)
+{
+	struct cb_txn *t, *cb_txn = NULL;
+
+	/* Supported state transitions:
+	 * PENDING    -> PROCESSING.
+	 * PROCESSING -> PROCESSED.
+	 *
+	 * We only search for these possible transtitions; other state, i.e.
+	 * TIMEDOUT is insignificant.
+	 */
+
+	list_for_each_entry(t, &si->cb_tx_list, node) {
+
+		/* Search for a specific transaction with a particular state?! */
+		if ((id != CONTEXT_ID_ANY) && (t->context_id != id))
+			continue;
+
+		/* Moving to PROCESSING state; we should be in PENDING state. */
+		if (state == XST_PROCESSING) {
+			if (t->processing == XST_PENDING) {
+				cb_txn = t;
+				break;
+			}
+
+		/* Moving to PROCESSED state; we should be in PROCESSING state. */
+		} else if (state == XST_PROCESSED) {
+			if (t->processing == XST_PROCESSING) {
+				cb_txn = t;
+				break;
+			}
+
+		} else {
+			pr_err("invalid state transition %d\n", state);
+
+			break;
+		}
+	}
+
+	if (cb_txn && !kref_get_unless_zero(&cb_txn->refcount))
+		cb_txn = NULL;
+
+	return cb_txn;
+}
+
+static struct cb_txn *get_txn_for_state_transition(struct server_info *si,
+	unsigned int context_id, enum state state)
+{
+	struct cb_txn *cb_txn;
+
+	mutex_lock(&si_mutex);
+	cb_txn = get_txn_for_state_transition_locked(si, context_id, state);
+	mutex_unlock(&si_mutex);
+
+	return cb_txn;
+}
+
+static int set_txn_state(struct cb_txn *cb_txn, enum state state)
+{
+	int ret;
+
+	mutex_lock(&si_mutex);
+	ret = set_txn_state_locked(cb_txn, state);
+	mutex_unlock(&si_mutex);
+
+	return ret;
+}
+
+static void __release_txn(struct kref *refcount)
+{
+	struct cb_txn *cb_txn = container_of(refcount, struct cb_txn, refcount);
+
+	txn_free(cb_txn);
+}
+
+static void put_txn(struct cb_txn *cb_txn)
+{
+	kref_put(&cb_txn->refcount, __release_txn);
+}
+
+static void dequeue_and_put_txn(struct cb_txn *cb_txn)
+{
+	mutex_lock(&si_mutex);
+	/* Only if it is queued. */
+	if (cb_txn->processing != XST_NEW)
+		dequeue_txn_locked(cb_txn);
+	mutex_unlock(&si_mutex);
+
+	put_txn(cb_txn);
+}
+
+/* 'wait_for_pending_txn' picks the next available pending transaction or sleep. */
+
+static int wait_for_pending_txn(struct server_info *si, struct cb_txn **cb_txn)
+{
+	int ret = 0;
+	struct cb_txn *t;
+
+	DEFINE_WAIT_FUNC(wait, woken_wake_function);
+
+	add_wait_queue(&si->Q, &wait);
+	while (1) {
+		if (signal_pending(current)) {
+			ret = -ERESTARTSYS;
+
+			break;
+		}
+
+		mutex_lock(&si_mutex);
+		t = get_txn_for_state_transition_locked(si, CONTEXT_ID_ANY, XST_PROCESSING);
+		if (t) {
+			/* ''PENDING -> PROCESSING'' is atomic so it is not picked up again. */
+			set_txn_state_locked(t, XST_PROCESSING);
+			mutex_unlock(&si_mutex);
+
+			break;
+		}
+		mutex_unlock(&si_mutex);
+
+		wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT);
+	}
+
+	remove_wait_queue(&si->Q, &wait);
+	*cb_txn = t;
+
+	return ret;
+}
+
+/* Callback object's operations. */
+
+static void ____destroy_server_info(struct kref *kref);
+
+/* 'dispatcher_marshal_in' and 'dispatcher_marshal_out'. */
+
+/* The only reason they are here are due to UAPI design. */
+/* The marshaling with 'marshal_in_cb_req' and 'marshal_out_cb_req' should happen
+ * in dispatcher (1) as it's overhead should be attributed to the invoke thread,
+ * (2) marshaling form args to transaction is relevant here. However, the UAPI,
+ * requires addrss (not the offset) which is anly available in 'process_accept_req'.
+ */
+
+static struct si_arg *dispatcher_marshal_in(struct si_arg args[])
+{
+	struct si_arg *cb_txn_args;
+	int i, nargs = size_of_arg(args);
+
+	/* Plus one for 'SI_AT_END'. */
+	cb_txn_args = kcalloc(nargs + 1, sizeof(struct si_arg), GFP_KERNEL);
+	if (!cb_txn_args)
+		return NULL;
+
+	for (i = 0; i < nargs; i++) {
+		cb_txn_args[i].type = args[i].type;
+
+		if (args[i].type == SI_AT_IB) {
+			cb_txn_args[i].b.addr = kzalloc(args[i].b.size, GFP_KERNEL);
+			if (!cb_txn_args[i].b.addr)
+				goto failed;
+
+			cb_txn_args[i].b.size = args[i].b.size;
+
+			memcpy(cb_txn_args[i].b.addr, args[i].b.addr, args[i].b.size);
+		} else if (args[i].type == SI_AT_OB) {
+			cb_txn_args[i].b.addr = kzalloc(args[i].b.size, GFP_KERNEL);
+			if (!cb_txn_args[i].b.addr)
+				goto failed;
+
+			cb_txn_args[i].b.size = args[i].b.size;
+		} else /* 'SI_AT_IO' || 'SI_AT_OO'. */
+			cb_txn_args[i].o = args[i].o;
+
+	}
+
+	return cb_txn_args;
+
+failed:
+
+	for (i = 0; i < nargs; i++) {
+		if (cb_txn_args[i].type == SI_AT_IB ||
+			cb_txn_args[i].type == SI_AT_OB)
+			kfree(cb_txn_args[i].b.addr);
+	}
+
+	kfree(cb_txn_args);
+
+	return NULL;
+}
+
+static void dispatcher_marshal_out(struct si_arg cb_txn_args[], struct si_arg args[])
+{
+	int i, nargs = size_of_arg(args);
+
+	/* See 'marshal_out_cb_req'. */
+	for (i = 0; i < nargs; i++) {
+		if (args[i].type == SI_AT_OB) {
+			args[i].b.size = cb_txn_args[i].b.size;
+
+			memcpy(args[i].b.addr, cb_txn_args[i].b.addr, cb_txn_args[i].b.size);
+		} else if (args[i].type == SI_AT_OO)
+			args[i].o = cb_txn_args[i].o;
+	}
+}
+
+static int cbo_dispatch(unsigned int context_id,
+	struct si_object *object, unsigned long op, struct si_arg args[])
+{
+	struct cb_txn *cb_txn;
+	struct cb_object *cb_object = to_cb_object(object);
+
+	int errno, nargs = size_of_arg(args);
+
+	cb_txn = txn_alloc(nargs);
+	if (IS_ERR(cb_txn))
+		return PTR_ERR(cb_txn);
+
+	/* 'context_id' is unique. Let's use it fot transaction ID. */
+
+	cb_txn->context_id = context_id;
+	cb_txn->op = op;
+	cb_txn->u_handle = cb_object->u_handle;
+
+	/* TODO. Move this to 'txn_alloc'. */
+	cb_txn->args = dispatcher_marshal_in(args);
+	if (!cb_txn->args) {
+		put_txn(cb_txn);
+
+		return -EINVAL;
+	}
+
+	/* START a Transaction. */
+
+	pr_debug("%s invocation with %d arguments and op %lu (context_id %u).\n",
+		si_object_name(object), nargs, cb_txn->op, context_id);
+
+	if (queue_txn(cb_object->si, cb_txn)) {
+		put_txn(cb_txn);
+
+		return -EINVAL;
+	}
+
+	wake_up_interruptible_all(&cb_object->si->Q);
+
+	if (context_id == CONTEXT_ID_ANY) {
+
+		/* We submitted a transaction with 'CONTEXT_ID_ANY' context ID.
+		 * This means no one is waiting for this callback request; just return.
+		 * 'process_accept_req' does the cleanup after processing this request.
+		 */
+
+		return 0;
+	}
+
+	/* Wait in FREEZABLE state in case we should suspend, here. */
+	wait_for_completion_state(&cb_txn->completion, TASK_KILLABLE | TASK_FREEZABLE);
+
+	/* We do not care why 'wait_for_completion_state' returend. The fastest way
+	 * to exit the dispatcher is to TIMEOUT the transaction. However, if 'set_txn_state'
+	 * failed, then transaction has already been PROCESSED.
+	 */
+
+	errno = set_txn_state(cb_txn, XST_TIMEDOUT) ? cb_txn->errno : -EINVAL;
+	pr_debug("%s invocation returned with %d (context_id %u).\n",
+		si_object_name(object), errno, context_id);
+	if (!errno)
+		dispatcher_marshal_out(cb_txn->args, args);
+	else
+		dequeue_and_put_txn(cb_txn);
+
+	return errno;
+}
+
+static void cbo_notify(unsigned int context_id, struct si_object *object, int status)
+{
+	struct cb_txn *cb_txn;
+
+	cb_txn = dequeue_txn_by_id(to_cb_object(object)->si, context_id);
+	if (cb_txn) {
+		int i;
+		struct si_arg *u = cb_txn->args;
+
+		for (i = 0; u[i].type; i++) {
+			switch (u[i].type) {
+			case SI_AT_OO:
+
+				/* See 'marshal_out_cb_req'. */
+
+				/* 'get_si_object_from_u_handle' calls 'get_si_object'
+				 * before returning (i.e. ref == 2) for all objects
+				 * except SI_OT_USER. One reference for QTEE and one
+				 * for driver itself. If !status, then QTEE owns an
+				 * instance of the object so we call 'put_si_object'
+				 * once.
+				 */
+
+				if (status && (typeof_si_object(u[i].o) != SI_OT_USER))
+					put_si_object(u[i].o);
+
+				put_si_object(u[i].o);
+
+				break;
+			case SI_AT_IB:
+			case SI_AT_OB:
+			case SI_AT_IO:
+			default:
+
+				break;
+			}
+		}
+
+		put_txn(cb_txn);
+	}
+}
+
+static void cbo_release(struct si_object *object)
+{
+	struct cb_object *cb_object = to_cb_object(object);
+
+	if (cb_object->notify_on_release) {
+		static struct si_arg args[] = { { .type = 0 } };
+
+		/* Use 'CONTEXT_ID_ANY' as context ID; as we do not care about the results. */
+		cbo_dispatch(CONTEXT_ID_ANY, object, SI_OBJECT_OP_RELEASE, args);
+	}
+
+	/* The matching 'kref_get' is in 'cb_object_alloc'. */
+	kref_put(&cb_object->si->refcount, ____destroy_server_info);
+	kfree(cb_object);
+}
+
+
+static void mem_object_release(void *private)
+{
+	/* THIS IS A STUPIDEST IMPLEMENTATION EVER! */
+
+	/* Old smcinvoke driver had a memory leak but rather than fixing it by
+	 * figuring out the root cause they decided it is COOL to send irrelevant
+	 * memory release to userspace to compensate for the leaked memory. Interestingly,
+	 * it has a made up story behind to justify the wrong change, see comments in
+	 * 'process_tzcb_req' this patch:
+	 * https://review-android.quicinc.com/c/platform/vendor/qcom/opensource/securemsm-kernel/+/4382238.
+	 * I WISH I COULD HAVE REVERTED THIS.
+	 */
+
+	struct cb_object *cb_x = private;
+
+	if (cb_x) {
+
+		/* Note 'cb_x->object' has not been isinialized. Do not use it! */
+		pr_debug("dma_buf released i.e. cbo-%s%lld\n", cb_x->si->comm, cb_x->u_handle);
+
+		cbo_release(&cb_x->object);
+	} else
+		pr_err("memory leak detected!\n");
+}
+
+static struct si_object_operations cbo_sio_ops = {
+	.release = cbo_release,
+	.notify = cbo_notify,
+	.dispatch = cbo_dispatch,
+};
+
+/* */
+/* We support three types of files:
+ *   - 'qtee_fops'
+ *   - 'server_fops'
+ *   - 'root_fops'.
+ */
+
+/* User Callback server */
+
+static long process_accept_req(struct server_info *si, struct smcinvoke_accept *accept)
+{
+	struct cb_txn *cb_txn;
+
+	if (accept->argsize != sizeof(union smcinvoke_arg))
+		return -EINVAL;
+
+	/* Processing response ... */
+	if (accept->has_resp) {
+		int i, errno = 0;
+
+		pr_debug("%s submit response (context_id %llu)\n", si->comm, accept->txn_id);
+
+		/* 'CONTEXT_ID_ANY' context ID?! Ignore. */
+		if (!accept->txn_id)
+			goto wait_on_request;
+
+		cb_txn = get_txn_for_state_transition(si, accept->txn_id, XST_PROCESSED);
+		if (!cb_txn) {
+
+			/* We get here, if the invoke thread goes away, e.g. timed out or killed. */
+			/* In correct implementation we should return to userspace for the callback
+			 * server to cleanup.
+			 */
+
+			goto wait_on_request;
+		}
+
+		errno = accept->result;
+		if (!errno) {
+			/* Only parse arguments on SUCCESS. */
+
+			/* Only copy arguments that we expect, i.e. 'u_args_sz'. */
+			if (copy_from_user(cb_txn->u_args,
+				(void __user *)accept->buf_addr, cb_txn->u_args_sz)) {
+
+				errno = -EFAULT;
+			} else {
+				if (marshal_out_cb_req(cb_txn->args, cb_txn->u_args))
+					errno = -EINVAL;
+			}
+		}
+
+		cb_txn->errno = errno;
+
+		/* Try to notify the invoke thread. */
+		if (set_txn_state(cb_txn, XST_PROCESSED)) {
+
+			/* If 'set_txn_state' fails, e.g. invoke thread TIMEDOUT
+			 * undo 'marshal_out_cb_req' only on SUCCESS.
+			 */
+			if (!errno) {
+				struct si_arg *u = cb_txn->args;
+
+				/* See comments in 'marshal_out_cb_req'. */
+
+				for (i = 0; u[i].type; i++) {
+					if (u[i].type != SI_AT_OO)
+						continue;
+
+					/* u[i].type == SI_AT_OO. */
+
+					if (is_cb_object(u[i].o))
+						to_cb_object(u[i].o)->notify_on_release = 0;
+
+					if (typeof_si_object(u[i].o) != SI_OT_USER)
+						put_si_object(u[i].o);
+
+					put_si_object(u[i].o);
+				}
+			}
+
+		} else
+			complete(&cb_txn->completion);
+
+		put_txn(cb_txn);
+
+		if (errno && !accept->result)
+			goto wait_on_request;
+
+
+		/* SUCCESS submitting the response. */
+	}
+
+	/* Processing request ... */
+wait_on_request:
+
+	do {
+		if (wait_for_pending_txn(si, &cb_txn)) {
+			pr_debug("%s received a signal.\n", si->comm);
+
+			return -ERESTARTSYS;
+		}
+
+		/* CONSTRUCT a request. */
+
+		accept->cbobj_id = cb_txn->u_handle;
+		accept->op = cb_txn->op;
+		accept->txn_id = cb_txn->context_id;
+
+		if (marshal_in_cb_req(cb_txn->u_args,
+			(void __user *)ALIGN(accept->buf_addr + cb_txn->u_args_sz, 8),
+				&accept->counts, cb_txn->args, si)) {
+
+			goto out_failed;
+		}
+
+		pr_debug("%s pick request with arguments (%04x) and op %d (context_id %llu)\n",
+			si->comm, accept->counts, accept->op, accept->txn_id);
+
+		if (copy_to_user((void __user *)accept->buf_addr,
+			cb_txn->u_args, cb_txn->u_args_sz)) {
+
+			/* TODO. We need to do some cleanup for 'marshal_in_cb_req'. */
+
+			goto out_failed;
+		}
+
+		/* SUCCESS picking a request; return. */
+		break;
+
+out_failed:
+
+		/* FAILED parsing a request; notify QTEE (if necessary) and try another one. */
+		if (!accept->txn_id)
+			dequeue_and_put_txn(cb_txn);
+		else
+			complete(&cb_txn->completion);
+
+		put_txn(cb_txn);
+
+	} while (1);
+
+	if (!accept->txn_id)
+		dequeue_and_put_txn(cb_txn);
+
+	put_txn(cb_txn);
+
+	return 0;
+}
+
+static long server_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	long ret;
+	struct server_info *si = filp->private_data;
+
+	switch (cmd) {
+	case SMCINVOKE_IOCTL_ACCEPT_REQ: {
+		struct smcinvoke_accept accept;
+
+		if (_IOC_SIZE(cmd) != sizeof(accept))
+			return -EINVAL;
+
+		if (copy_from_user(&accept, (void __user *)arg, sizeof(accept)))
+			return -EFAULT;
+
+		ret = process_accept_req(si, &accept);
+		if (ret == -ERESTARTSYS) {
+			struct smcinvoke_accept __user *a = (struct smcinvoke_accept __user *)arg;
+
+			/* BAD IOCTL UAPI DESIGN! */
+
+			/* We do this because same IOCTL command has been used for two different
+			 * purposes (submit response + pick request). 'ERESTARTSYS' means we were
+			 * handling second part of the IOCTL when signal arrived.
+			 */
+
+			/* We need to reset 'has_resp' so if the IOCTL call restarted we
+			 * resume from second half of the IOCTL. I did not use an state for 'si'
+			 * as restart is not guaranteed.
+			 */
+
+			if (put_user(0, &a->has_resp))
+				return -EFAULT;
+
+		} else if (!ret) {
+
+			/* We picked a request; and submitted any pending response.*/
+			accept.has_resp = 0;
+
+			if (copy_to_user((void __user *)arg, &accept, sizeof(accept))) {
+
+				/* TODO. We need to do some cleanup for 'process_accept_req'. */
+
+				return -EFAULT;
+			}
+		}
+
+		break;
+	}
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+static int server_release(struct inode *nodp, struct file *filp)
+{
+	struct cb_txn *cb_txn, *t;
+
+	struct server_info *si = filp->private_data;
+
+	/* We get here when there is no more server thread running in kernel. */
+
+	mutex_lock(&si_mutex);
+	si->dead = 1;
+
+	/* Terminate any PENDING or PROCESSING transaction. */
+	list_for_each_entry_safe(cb_txn, t, &si->cb_tx_list, node) {
+		if (cb_txn->processing == XST_PENDING ||
+			cb_txn->processing == XST_PROCESSING) {
+			if (!cb_txn->context_id) {
+
+				/* For PROCESSING transaction,
+				 * 'process_accept_req' already dequeued.
+				 */
+
+				if (cb_txn->processing == XST_PENDING) {
+					dequeue_txn_locked(cb_txn);
+
+					txn_free(cb_txn);
+				}
+			} else
+				complete(&cb_txn->completion);
+		}
+	}
+
+	mutex_unlock(&si_mutex);
+
+	/* We can not notify QTEE of the server demise; we keep objects around to
+	 * notify QTEE the next time it invokes an object with a dead server.
+	 */
+
+	pr_info("%s server terminated (refs: %u).\n", si->comm, kref_read(&si->refcount));
+
+	kref_put(&si->refcount, ____destroy_server_info);
+
+	return 0;
+}
+
+static const struct file_operations server_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = server_ioctl,
+	.compat_ioctl = server_ioctl,
+	.release = server_release,
+};
+
+/* QTEE object invocation. */
+
+static long process_invoke_req(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	int i, ret;
+
+	struct si_object *object = filp->private_data;
+
+	struct smcinvoke_cmd_req u_req;	/* User request. */
+	union smcinvoke_arg *u_args;	/* Array of arguments as passed from userspace. */
+	int u_args_nr;					/* Total number of arguments in 'u_args'. */
+
+	struct si_arg *u = NULL;		/* Array of arguments passed to the QTEE. */
+
+	struct si_object_invoke_ctx *oic;
+
+	/* Do some sanity check! */
+
+	if (_IOC_SIZE(cmd) != sizeof(u_req))
+		return -EINVAL;
+
+	if (copy_from_user(&u_req, (void __user *)arg, sizeof(u_req)))
+		return -EFAULT;
+
+	if (typeof_si_object(object) == SI_OT_ROOT) {
+		if ((u_req.op == IClientEnv_OP_notifyDomainChange) ||
+			(u_req.op == IClientEnv_OP_adciAccept) ||
+			(u_req.op == IClientEnv_OP_adciShutdown)) {
+			pr_err("invalid rootenv op\n");
+
+			return -EINVAL;
+		}
+
+		if (u_req.op == IClientEnv_OP_registerWithCredentials) {
+			if (u_req.counts != OBJECT_COUNTS_PACK(0, 0, 1, 1)) {
+				pr_err("IClientEnv_OP_registerWithCredentials: incorrect number of arguments.\n");
+
+				return -EINVAL;
+			}
+		}
+	}
+
+	if (u_req.argsize != sizeof(union smcinvoke_arg))
+		return -EINVAL;
+
+	/* Allocate and initialize resources. */
+
+	oic = kzalloc(sizeof(*oic), GFP_KERNEL);
+	if (!oic)
+		return -ENOMEM;
+
+	u_args_nr = OBJECT_COUNTS_TOTAL(u_req.counts);
+	u_args = kcalloc(u_args_nr, u_req.argsize, GFP_KERNEL);
+	if (!u_args) {
+		ret = -ENOMEM;
+
+		goto out_failed;
+	}
+
+	/* Plus one for 'SI_AT_END'. */
+	u = kcalloc(u_args_nr + 1, sizeof(struct si_arg), GFP_KERNEL);
+	if (!u) {
+		ret = -ENOMEM;
+
+		goto out_failed;
+	}
+
+	/* Copy argument array from userspace. */
+	if (copy_from_user(u_args, (void __user *)u_req.args, u_args_nr * u_req.argsize)) {
+		ret = -EFAULT;
+
+		goto out_failed;
+	}
+
+	if (typeof_si_object(object) == SI_OT_ROOT) {
+		if (u_req.op == IClientEnv_OP_registerWithCredentials) {
+			if (U_HANDLE_IS_NULL(u_args[0].o.fd)) {
+				pr_err("IClientEnv_OP_registerWithCredentials: privileged credential.\n");
+
+				ret = -EINVAL;
+				goto out_failed;
+			}
+		}
+	}
+
+	pr_debug("%s object invocation with %d arguments (%04x) and op %d.\n",
+		si_object_name(object), u_args_nr, u_req.counts, u_req.op);
+
+	/* + INITIATE an invocation. */
+
+	if (marshal_in_req(u, u_args, u_req.counts)) {
+		pr_err("marshal_in_req failed.\n");
+		ret = -EINVAL;
+
+		goto out_failed;
+	}
+
+	/* TODO. Move this initialization to SI-CORE. */
+	u_req.result = OBJECT_ERROR_INVALID;
+
+	ret = si_object_do_invoke(oic, object, u_req.op, u, &u_req.result);
+	if (ret) {
+		pr_err("si_object_do_invoke failed %d, %d.\n", ret, u_req.result);
+
+		if (u_req.result) {
+			if (ret == -EINVAL || ret == -ENOMEM ||	ret == -ENOSPC) {
+
+				/* SI-CORE did not even starts the invocation. */
+
+				marshal_in_req_cleanup(u, 0);
+
+				for (i = 0; u[i].type; i++) {
+					if (u[i].type == SI_AT_IO &&
+						typeof_si_object(u[i].o) != SI_OT_USER)
+						put_si_object(u[i].o);
+				}
+
+				goto out_failed;
+			}
+		}
+
+		/* SI-CORE made an unsuccessful invocation. */
+		/* ret == -EINVAL || ret == -ENOMEM && !u_req.result: Marshal out failed.
+		 * ret == -EAGAIN || ret == -ENODEV: QTEE communication failed.
+		 */
+
+		marshal_in_req_cleanup(u, 0);
+
+		goto out_failed;
+	}
+
+	if (!u_req.result) {
+		if (marshal_out_req(u_args, u)) {
+			pr_err("marshal_out_req failed.\n");
+			ret = -EINVAL;
+
+			goto out_failed;
+		}
+
+		if (copy_to_user((void __user *)u_req.args, u_args, u_args_nr * u_req.argsize)) {
+			ret = -EFAULT;
+
+			goto out_failed;
+		}
+	} else {
+
+		/* SI-CORE made a successful invocation but QTEE failed.
+		 * We still need to put temporary references we hold from 'marshal_in_req';
+		 * QTEE will release it's own. 'notify == 1' as we return success to user.
+		 */
+
+		marshal_in_req_cleanup(u, 1);
+	}
+
+	/* Copy u_req.result back! */
+	if (copy_to_user((void __user *)arg, &u_req, sizeof(u_req))) {
+		ret = -EFAULT;
+
+		goto out_failed;
+	}
+
+	pr_debug("%s object invocation returned with %d.\n",
+		si_object_name(object), u_req.result);
+
+	ret = 0;
+
+out_failed:
+
+	kfree(u);
+	kfree(u_args);
+	kfree(oic);
+
+	if (ret)
+		pr_err("failed with %d\n", ret);
+
+	return ret;
+}
+
+static long qtee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	long ret;
+
+	switch (cmd) {
+	case SMCINVOKE_IOCTL_INVOKE_REQ:
+		ret = process_invoke_req(filp, cmd, arg);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+static int qtee_release(struct inode *nodp, struct file *filp)
+{
+	struct si_object *object = filp->private_data;
+
+	/* The matching 'get_si_object' is in 'get_u_handle_from_si_object'. */
+
+	pr_debug("%s released.\n", si_object_name(object));
+
+	put_si_object(object);
+
+	return 0;
+}
+
+static const struct file_operations qtee_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = qtee_ioctl,
+	.compat_ioctl = qtee_ioctl,
+	.release = qtee_release,
+};
+
+/* ''ROOT Object'' */
+
+static void ____destroy_server_info(struct kref *kref)
+{
+	struct server_info *si = container_of(kref, struct server_info, refcount);
+
+	pr_info("%s server destroyed.\n", si->comm);
+
+	kfree(si);
+}
+
+static long process_server_req(struct file *filp, unsigned int cmd,	unsigned long arg)
+{
+	s64 u_handle;
+	struct server_info *si;
+
+	/* Use may pass an instance of 'smcinvoke_server' to change the output buffer
+	 * size. We do not care for that value as si_core always use a constant.
+	 */
+
+	si = kzalloc(sizeof(*si), GFP_KERNEL);
+	if (!si)
+		return -ENOMEM;
+
+	kref_init(&si->refcount);
+	INIT_LIST_HEAD(&si->cb_tx_list);
+	init_waitqueue_head(&si->Q);
+	get_task_comm(si->comm, current);
+
+	/* Assign a u_handle for the server. */
+	if (!u_handle_alloc(si->comm, &server_fops, si, &u_handle))
+		return u_handle;
+
+	kfree(si);
+
+	return -EBADF;
+}
+
+static long root_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	long ret;
+
+	switch (cmd) {
+	case SMCINVOKE_IOCTL_INVOKE_REQ:
+		ret = process_invoke_req(filp, cmd, arg);
+		break;
+	case SMCINVOKE_IOCTL_SERVER_REQ:
+		ret = process_server_req(filp, cmd, arg);
+		break;
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	return ret;
+}
+
+static int root_open(struct inode *nodp, struct file *filp)
+{
+	/* Always return the same instance of root si_object. */
+
+	filp->private_data = ROOT_SI_OBJECT;
+
+	return 0;
+}
+
+static const struct file_operations root_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = root_ioctl,
+	.compat_ioctl = root_ioctl,
+	.open = root_open,
+};
+
+static dev_t smcinvoke_device_no;
+static struct class *driver_class;
+struct device *smci_dev;
+static struct cdev smcinvoke_cdev;
+
+static int smcinvoke_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = alloc_chrdev_region(&smcinvoke_device_no, 0, 1, SMCI_DEVICE_NAME);
+	if (ret < 0) {
+		pr_err("alloc_chrdev_region failed %d.\n", ret);
+
+		return ret;
+	}
+
+	driver_class = class_create(SMCI_DEVICE_NAME);
+	if (IS_ERR(driver_class)) {
+		ret = PTR_ERR(driver_class);
+		pr_err("class_create failed %d.\n", ret);
+
+		goto exit_unreg_chrdev_region;
+	}
+
+	cdev_init(&smcinvoke_cdev, &root_fops);
+	smcinvoke_cdev.owner = THIS_MODULE;
+
+	ret = cdev_add(&smcinvoke_cdev, MKDEV(MAJOR(smcinvoke_device_no), 0), 1);
+	if (ret < 0) {
+		pr_err("cdev_add failed %d.\n", ret);
+
+		goto exit_destroy_class;
+	}
+
+	/* Create '/dev/smcinvoke'. */
+	smci_dev = device_create(driver_class, NULL, smcinvoke_device_no, NULL, SMCI_DEVICE_NAME);
+	if (IS_ERR(smci_dev)) {
+		ret = PTR_ERR(smci_dev);
+		pr_err("device_create failed %d.\n", ret);
+
+		goto exit_destroy_cdev;
+	}
+
+	return 0;
+
+exit_destroy_cdev:
+	cdev_del(&smcinvoke_cdev);
+exit_destroy_class:
+	class_destroy(driver_class);
+exit_unreg_chrdev_region:
+	unregister_chrdev_region(smcinvoke_device_no, 1);
+
+	return ret;
+}
+
+static const struct of_device_id smcinvoke_match[] = {
+	{ .compatible = "qcom,smcinvoke", }, {},
+};
+
+static struct platform_driver smcinvoke_plat_driver = {
+	.probe = smcinvoke_probe,
+	.driver = {
+		.name = "smcinvoke",
+		.of_match_table = smcinvoke_match,
+	},
+};
+
+module_platform_driver(smcinvoke_plat_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("smcinvoke driver");
+MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
+MODULE_IMPORT_NS(DMA_BUF);
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/si_core_xts/smci_impl.h
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/si_core_xts/smci_impl.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __SMCI_IMPL_H__
+#define __SMCI_IMPL_H__
+
+#include <linux/sched.h>
+#include <linux/firmware/qcom/si_object.h>
+
+#include "smci_internal.h"
+
+struct server_info {
+	char comm[TASK_COMM_LEN];
+	struct kref refcount;
+
+	int dead;
+
+	struct list_head cb_tx_list;
+
+	/* Queue of server threads waiting for a new transaction. */
+	wait_queue_head_t Q;
+};
+
+#define CONTEXT_ID_ANY 0
+
+struct cb_txn {
+	struct kref refcount;
+
+	unsigned int context_id;
+
+	/* ''Object Invocation'' */
+
+	s64 u_handle;			/* Object's u_handle to invoke. */
+	unsigned long op;		/* Operation to perform on object. */
+	struct si_arg *args;	/* Arguments for the requested operation. */
+	int errno;				/* Result of the operation. */
+
+	enum state {
+		XST_NEW = 0,		/* New transaction. */
+		XST_PENDING = 1,	/* Waiting for server. */
+		XST_PROCESSING = 2,	/* Being processed by server. */
+		XST_PROCESSED = 3,	/* Done. */
+		XST_TIMEDOUT = 4,
+	} processing;
+
+	/* ''Object Invocation'' as seen by userspace. */
+
+	size_t u_args_sz;
+	union smcinvoke_arg *u_args;
+
+	struct list_head node;
+	struct completion completion;
+};
+
+#define U_ARGS_SIZE(t) (size_of_arg((t)->args) * sizeof((t)->u_args[0]))
+
+#endif /* __SMCI_IMPL_H__ */
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/si_core_xts/smci_internal.h
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/si_core_xts/smci_internal.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _SMCI_INTERNAL_H_
+#define _SMCI_INTERNAL_H_
+
+#include <soc/qcom/smci_object.h>
+#include <soc/qcom/smci_clientenv.h>
+#include <uapi/linux/smcinvoke.h>
+
+extern struct device *class_dev;
+
+#endif /* _SMCI_INTERNAL_H_ */
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/si_core_xts/smci_kernel.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/si_core_xts/smci_kernel.c
@@ -0,0 +1,175 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt) "smcinvoke_kernel: %s: " fmt, __func__
+
+#include <linux/slab.h>
+#include "smci_impl.h"
+
+#if IS_ENABLED(CONFIG_QSEECOM_COMPAT)
+#include "../IQSEEComCompat.h"
+#include "../IQSEEComCompatAppLoader.h"
+#include "linux/qseecom_api.h"
+#include "misc/qseecom_kernel.h"
+#endif
+
+#undef OBJECT_OP_METHOD_MASK
+#undef OBJECT_OP_METHOD_ID
+#undef OBJECT_OP_RELEASE
+#undef OBJECT_OP_RETAIN
+#include "smci_impl.h"
+
+static int32_t do_invoke(void *context, uint32_t op,
+	union ObjectArg *args, uint32_t counts);
+
+/* Marshaling APIs. */
+
+static void marshal_in(struct si_arg u[], union ObjectArg args[], uint32_t counts)
+{
+	int i;
+
+	FOR_ARGS(i, counts, BI) {
+		u[i].b.addr = args[i].b.ptr;
+		u[i].b.size = args[i].b.size;
+
+		u[i].type = SI_AT_IB;
+	}
+
+	FOR_ARGS(i, counts, BO) {
+		u[i].b.addr = args[i].b.ptr;
+		u[i].b.size = args[i].b.size;
+
+		u[i].type = SI_AT_OB;
+	}
+
+	FOR_ARGS(i, counts, OI) {
+		u[i].o = args[i].o.context;
+
+		/* No need to temporarily get objects; we trust the kernel clients. */
+
+		u[i].type = SI_AT_IO;
+	}
+
+	FOR_ARGS(i, counts, OO)
+		u[i].type = SI_AT_OO;
+}
+
+static void marshal_out(union ObjectArg args[], struct si_arg u[], uint32_t counts)
+{
+	int i;
+
+	FOR_ARGS(i, counts, BI) {
+		/* NOTHING TO DO FOR INPUT BUFFERS. */
+	}
+
+	FOR_ARGS(i, counts, BO) {
+		args[i].b.size = u[i].b.size;
+	}
+
+	FOR_ARGS(i, counts, OI) {
+		/* NOTHING TO DO FOR INPUT OBJECTS. */
+	}
+
+	FOR_ARGS(i, counts, OO) {
+		args[i].o.context = u[i].o;
+		args[i].o.invoke = do_invoke;
+	}
+}
+
+/* Invocation function. */
+
+static int32_t do_invoke(void *context, uint32_t op,
+	union ObjectArg *args, uint32_t counts)
+{
+	int ret, result;
+
+	struct si_object *object = context;
+
+	struct si_arg *u;
+	struct si_object_invoke_ctx *oic;
+
+	if (ObjectOp_isLocal(op)) {
+		switch (ObjectOp_methodID(op)) {
+		case Object_OP_retain:
+			get_si_object(object);
+
+			return OBJECT_OK;
+		case Object_OP_release:
+			put_si_object(object);
+
+			return OBJECT_OK;
+		default:
+
+			break;
+		}
+
+		return OBJECT_ERROR_REMOTE;
+	}
+
+	/* Allocate resources. */
+
+	oic = kzalloc(sizeof(*oic), GFP_KERNEL);
+	if (!oic)
+		return -OBJECT_ERROR_KMEM;
+
+	u = kcalloc(OBJECT_COUNTS_TOTAL(counts) + 1, sizeof(struct si_arg), GFP_KERNEL);
+	if (!u) {
+		ret = -OBJECT_ERROR_KMEM;
+
+		goto out_failed;
+	}
+
+	pr_info("%s object invocation with %lu arguments (%04x) and op %d.\n",
+		si_object_name(object), OBJECT_COUNTS_TOTAL(counts), counts, op);
+
+	/* + INITIATE an invocation. */
+
+	marshal_in(u, args, counts);
+
+	ret = si_object_do_invoke(oic, object, op, u, &result);
+	if (ret) {
+		pr_err("si_object_do_invoke failed with %d.\n", ret);
+		ret = OBJECT_ERROR_UNAVAIL;
+
+		goto out_failed;
+	}
+
+	if (!result)
+		marshal_out(args, u, counts);
+
+	ret = result;
+
+out_failed:
+
+	pr_info("%s object invocation returned with %d.\n",	si_object_name(object), ret);
+
+	kfree(u);
+	kfree(oic);
+
+	return ret;
+}
+
+int get_root_obj(struct Object *rootObj)
+{
+	rootObj->context = ROOT_SI_OBJECT;
+	rootObj->invoke = do_invoke;
+
+	return 0;
+}
+
+int32_t get_client_env_object(struct Object *clientEnvObj)
+{
+	int ret;
+	struct Object rootObj;
+
+	get_root_obj(&rootObj);
+
+	ret = IClientEnv_registerWithCredentials(rootObj, Object_NULL, clientEnvObj);
+	if (ret)
+		pr_err("Failed to get ClientEnvObject (ret = %d).\n", ret);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(get_client_env_object);
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/si_core/xts/mem-object.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/si_core/xts/mem-object.c
@@ -0,0 +1,555 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt) "si-mo: %s: " fmt, __func__
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/dma-buf.h>
+#include <linux/mem-buf.h>
+#include <linux/of_platform.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
+#include <linux/firmware/qcom/si_core_xts.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+
+/* Memory object operations. */
+/* ... */
+
+/* 'Primordial Object' operations related to memory object. */
+#define OBJECT_OP_MAP_REGION	0
+
+/* Auto mapping operation. */
+#define OBJECT_OP_AUTO_MAP 0x00000003UL
+
+#define SMCINVOKE_ASYNC_VERSION 0x00010002U
+
+/* TZ defined values for cacheability */
+#define CACHE_NS_CACHED 0x10000000U
+#define CACHE_UNCACHED 0x20000000U
+
+static struct platform_device *mem_object_pdev;
+
+static struct si_object primordial_object;
+
+/* **/
+/* Memory object reference counting details:
+ * There is one reference counter in memory object, i.e. 'object'.
+ * 'object' counts number of times this object has been exported to TZ plus
+ * total number of mappings plus one (for ownership reference).
+ *
+ * HOW IT WORKS
+ *
+ * Client obtains an instance of 'si_object' by calling 'init_si_mem_object_user'
+ * with an instance of 'struct dma_buf' to initialize a memory object. It can
+ * immediately use this instance of 'si_object' to share memory with TZ.
+ * However, by transferring this object to TZ, client will lose it's ownership.
+ * To retain the ownership it should call 'get_si_object' and send a second
+ * instance of this object to TZ while keeping the initial 'si_object' instance
+ * (hence plus one for ownership).
+ *
+ * Every time TZ request mapping of the memory object, the driver issues
+ * 'get_si_object' on 'object'.
+ *
+ **/
+
+struct mem_object {
+	struct si_object object;
+
+	struct dma_buf *dma_buf;
+
+	union {
+		struct {
+
+			/* SHMBridge information. */
+			/* Select with 'qcom,shmbridge'. */
+
+			struct map {
+				struct dma_buf_attachment *buf_attach;
+				struct sg_table *sgt;
+
+				/* 'lock' to protect concurrent request from QTEE. */
+				struct mutex lock;
+				int early_mapped;
+			} map;
+
+			/* Use SHMBridge, hence the handle. */
+			u64 shm_bridge_handle;
+
+			struct mapping_info {
+				phys_addr_t p_addr;
+				size_t p_addr_len;
+				uint32_t perms;
+			} mapping_info;
+		};
+
+		/* XXX information. */
+		/* struct { ... } */
+	};
+
+	struct list_head node;
+
+	/* Private pointer passed for callbacks. */
+
+	void *private;
+
+	void (*release)(void *private);
+};
+
+#define to_mem_object(o) container_of((o), struct mem_object, object)
+
+/* List of memory objects. Only used for sysfs. */
+
+static LIST_HEAD(mo_list);
+static DEFINE_MUTEX(mo_list_mutex);
+
+/* 'mo_notify' and 'mo_dispatch' are shared by all types of memory objects. */
+
+static void mo_notify(unsigned int context_id, struct si_object *object, int status)
+{
+
+}
+
+static int mo_dispatch(unsigned int context_id,
+	struct si_object *object, unsigned long op, struct si_arg args[])
+{
+	return 0;
+}
+
+static struct si_object_operations mem_ops = {
+	.notify = mo_notify,
+	.dispatch = mo_dispatch
+};
+
+int op_supported(unsigned long op)
+{
+	switch (op) {
+	case OBJECT_OP_MAP_REGION:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+/** Support for 'SHMBridge'. **/
+
+/* 'make_shm_bridge_single' only support single continuous memory. */
+
+static int make_shm_bridge_single(struct mem_object *mo)
+{
+	int ret;
+
+	u32 *vmid_list, *perms_list, nelems;
+
+	/* 'sgt' should have one mapped entry. **/
+
+	if (mo->map.sgt->nents != 1)
+		return -EINVAL;
+
+	ret = mem_buf_dma_buf_copy_vmperm(mo->dma_buf,
+		(int **)(&vmid_list),
+		(int **)(&perms_list),
+		(int *)(&nelems));
+
+	if (ret)
+		return ret;
+
+	if (mem_buf_dma_buf_exclusive_owner(mo->dma_buf))
+		perms_list[0] = QCOM_SCM_PERM_RW;
+
+	mo->mapping_info.p_addr = sg_dma_address(mo->map.sgt->sgl);
+	mo->mapping_info.p_addr_len = sg_dma_len(mo->map.sgt->sgl);
+	mo->mapping_info.perms = QCOM_SCM_PERM_RW;
+
+	ret = qcom_tzmem_register(mo->mapping_info.p_addr, mo->mapping_info.p_addr_len,
+		vmid_list, perms_list, nelems, mo->mapping_info.perms,
+		&mo->shm_bridge_handle);
+
+	kfree(perms_list);
+	kfree(vmid_list);
+
+	if (ret) {
+
+		/* If 'p_addr' is not zero, then the memory object is already mapped. */
+
+		mo->mapping_info.p_addr = 0;
+		mo->mapping_info.p_addr_len = 0;
+		// SCM driver touch this value even an failure so set to 0
+		mo->shm_bridge_handle = 0;
+	}
+
+	return ret;
+}
+
+static void rm_shm_bridge(struct mem_object *mo)
+{
+	if (mo->shm_bridge_handle)
+		qcom_tzmem_deregister(mo->shm_bridge_handle);
+	mo->shm_bridge_handle = 0;
+}
+
+static void detach_dma_buf(struct mem_object *mo)
+{
+	if (mo->map.sgt) {
+		dma_buf_unmap_attachment_unlocked(mo->map.buf_attach,
+			mo->map.sgt, DMA_BIDIRECTIONAL);
+	}
+
+	if (mo->map.buf_attach)
+		dma_buf_detach(mo->dma_buf, mo->map.buf_attach);
+
+	mo->map.buf_attach = NULL;
+	mo->map.sgt = NULL;
+}
+
+/* 'init_tz_shared_memory' is called while holding the 'map.lock' mutex. */
+
+static int init_tz_shared_memory(struct mem_object *mo)
+{
+	int ret;
+	struct dma_buf_attachment *buf_attach;
+	struct sg_table *sgt;
+
+	mo->map.buf_attach = NULL;
+	mo->map.sgt = NULL;
+	mo->shm_bridge_handle = 0;
+
+	buf_attach = dma_buf_attach(mo->dma_buf, &mem_object_pdev->dev);
+	if (IS_ERR(buf_attach))
+		return PTR_ERR(buf_attach);
+
+	mo->map.buf_attach = buf_attach;
+
+	sgt = dma_buf_map_attachment_unlocked(buf_attach, DMA_BIDIRECTIONAL);
+
+	if (IS_ERR(sgt)) {
+		ret = PTR_ERR(sgt);
+
+		goto out_failed;
+	}
+
+	mo->map.sgt = sgt;
+
+	ret = make_shm_bridge_single(mo);
+	if (ret)
+		goto out_failed;
+
+	return 0;
+
+out_failed:
+	detach_dma_buf(mo);
+
+	return ret;
+}
+
+static int map_memory_obj(struct mem_object *mo, int advisory)
+{
+	int ret;
+
+	if (mo->map.early_mapped)
+		pr_debug("%s auto-mapped. Memory optimization unavailable.\n",
+			si_object_name(&mo->object));
+
+	mutex_lock(&mo->map.lock);
+	if (mo->mapping_info.p_addr == 0) {
+
+		/* 'mo' has not been mapped before. Do it now. */
+
+		ret = init_tz_shared_memory(mo);
+
+	} else {
+
+		/* 'mo' is already mapped. Just return. */
+
+		ret = advisory;
+	}
+
+	mutex_unlock(&mo->map.lock);
+
+	return ret;
+}
+
+static void release_memory_obj(struct mem_object *mo)
+{
+	rm_shm_bridge(mo);
+
+	detach_dma_buf(mo);
+}
+
+static unsigned long mo_shm_bridge_prepare(struct si_object *object, struct si_arg args[])
+{
+	struct mem_object *mo = to_mem_object(object);
+
+	struct {
+		u64 p_addr;
+		u64 len;
+		u32 perms;
+	} *mi;
+
+	if (get_async_proto_version() != SMCINVOKE_ASYNC_VERSION)
+		return SI_OBJECT_OP_NO_OP;
+
+	if (args[0].b.size < sizeof(*mi))
+		return SI_OBJECT_OP_NO_OP;
+
+	if (!map_memory_obj(mo, 1)) {
+		mo->map.early_mapped = 1;
+
+		/* 'object' has been mapped. Share it. */
+
+		get_si_object(object);
+
+		mi = (typeof(mi)) (args[0].b.addr);
+		mi->p_addr = mo->mapping_info.p_addr;
+		mi->len = mo->mapping_info.p_addr_len;
+		/* append cacheability info to upper nibble */
+		mi->perms = CACHE_NS_CACHED | mo->mapping_info.perms;
+		args[0].b.size = sizeof(*mi);
+
+		args[1].o = object;
+
+		return OBJECT_OP_AUTO_MAP;
+	}
+
+	return SI_OBJECT_OP_NO_OP;
+}
+
+static void mo_shm_bridge_release(struct si_object *object)
+{
+	struct mem_object *mo = to_mem_object(object);
+
+	release_memory_obj(mo);
+
+	if (mo->release)
+		mo->release(mo->private);
+
+	/* Put a dam-buf copy obtained in 'init_si_mem_object_user'.*/
+
+	dma_buf_put(mo->dma_buf);
+
+	mutex_lock(&mo_list_mutex);
+	list_del(&mo->node);
+	mutex_unlock(&mo_list_mutex);
+
+	pr_info("%s unmapped.\n", si_object_name(object));
+
+	kfree(mo);
+}
+
+/* Primordial object for 'SHMBridge'. */
+
+static int shm_bridge__po_dispatch(unsigned int context_id,
+	struct si_object *unused, unsigned long op, struct si_arg args[])
+{
+	int ret;
+
+	struct si_object *object;
+	struct mem_object *mo;
+
+	switch (op) {
+	case OBJECT_OP_MAP_REGION: {
+
+		/* Format of response as expected by TZ. */
+
+		struct {
+			u64 p_addr;
+			u64 len;
+			u32 perms;
+		} *mi;
+
+		if (size_of_arg(args) != 3 ||
+			args[0].type != SI_AT_OB  ||
+			args[1].type != SI_AT_IO  ||
+			args[2].type != SI_AT_OO) {
+
+			pr_err("mapping of a memory object with invalid message format.\n");
+
+			return -EINVAL;
+		}
+
+		object = args[1].o;
+
+		if (!is_mem_object(object)) {
+			pr_err("mapping of a non-memory object.\n");
+
+			put_si_object(object);
+			return -EINVAL;
+		}
+
+		mo = to_mem_object(object);
+
+		ret = map_memory_obj(mo, 0);
+		if (!ret) {
+
+			/* 'object' has been mapped. Share it. */
+
+			args[2].o = object;
+
+			mi = (typeof(mi)) (args[0].b.addr);
+			mi->p_addr = mo->mapping_info.p_addr;
+			mi->len = mo->mapping_info.p_addr_len;
+			/* append cacheability info to upper nibble */
+			mi->perms = CACHE_NS_CACHED | mo->mapping_info.perms;
+
+			pr_info("%s mapped %llx %llx\n",
+				si_object_name(object), mi->p_addr, mi->len);
+
+		} else {
+			pr_err("mapping memory object %s failed.\n",
+				si_object_name(object));
+
+			put_si_object(object);
+		}
+	}
+
+		break;
+	default:
+
+		/* The operation is not supported! */
+
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static struct si_object_operations shm_bridge__po_ops = {
+	.op_supported = op_supported,
+	.dispatch = shm_bridge__po_dispatch
+};
+
+/* Memory Object Extension. */
+
+struct si_object *init_si_mem_object_user(struct dma_buf *dma_buf,
+	void (*release)(void *), void *private)
+{
+	struct mem_object *mo;
+
+	if (!mem_ops.release) {
+		pr_err("memory object type is unknown.\n");
+
+		return NULL_SI_OBJECT;
+	}
+
+	mo = kzalloc(sizeof(*mo), GFP_KERNEL);
+	if (!mo)
+		return NULL_SI_OBJECT;
+
+	mutex_init(&mo->map.lock);
+
+	/* Get a copy of dma-buf. */
+	get_dma_buf(dma_buf);
+
+	mo->dma_buf = dma_buf;
+	mo->private = private;
+	mo->release = release;
+
+	init_si_object_user(&mo->object, SI_OT_CB_OBJECT, &mem_ops, "mem-object-%p", dma_buf);
+
+	mutex_lock(&mo_list_mutex);
+	list_add_tail(&mo->node, &mo_list);
+	mutex_unlock(&mo_list_mutex);
+
+	return &mo->object;
+}
+EXPORT_SYMBOL_GPL(init_si_mem_object_user);
+
+struct dma_buf *mem_object_to_dma_buf(struct si_object *object)
+{
+	if (is_mem_object(object))
+		return to_mem_object(object)->dma_buf;
+
+	return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(mem_object_to_dma_buf);
+
+int is_mem_object(struct si_object *object)
+{
+	/* Check 'typeof_si_object' to make sure 'object''s 'ops' has been
+	 * initialized before checking it.
+	 */
+
+	return (typeof_si_object(object) == SI_OT_CB_OBJECT) &&
+		(object->ops == &mem_ops);
+}
+EXPORT_SYMBOL_GPL(is_mem_object);
+
+static ssize_t mem_objects_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	size_t len = 0;
+	struct mem_object *mo;
+
+	mutex_lock(&mo_list_mutex);
+	list_for_each_entry(mo, &mo_list, node) {
+		len += scnprintf(buf + len, PAGE_SIZE - len, "%s %u (%llx %zx) %d\n",
+			si_object_name(&mo->object), kref_read(&mo->object.refcount),
+			mo->mapping_info.p_addr, mo->mapping_info.p_addr_len, mo->map.early_mapped);
+	}
+
+	mutex_unlock(&mo_list_mutex);
+
+	return len;
+}
+
+/* 'struct device_attribute dev_attr_mem_objects'. */
+/* Use device attribute rather than driver attribute in case we want to support
+ * multiple types of memory objects as different devices.
+ */
+
+static DEVICE_ATTR_RO(mem_objects);
+
+static struct attribute *attrs[] = {
+	&dev_attr_mem_objects.attr,
+	NULL
+};
+
+static struct attribute_group attr_group = {
+	.attrs = attrs,
+};
+
+static const struct attribute_group *attr_groups[] = {
+	&attr_group,
+	NULL
+};
+
+static int mem_object_probe(struct platform_device *pdev)
+{
+	int ret;
+
+	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+	if (ret)
+		return ret;
+
+	/* Select memory object type: default to SHMBridge. */
+	mem_ops.release = mo_shm_bridge_release;
+	mem_ops.prepare = mo_shm_bridge_prepare;
+
+	init_si_object_user(&primordial_object,
+		SI_OT_ROOT, &shm_bridge__po_ops, "po_in_mem_object");
+
+	mem_object_pdev = pdev;
+
+	return 0;
+}
+
+static const struct of_device_id mem_object_match[] = {
+	{ .compatible = "qcom,mem-object", }, {}
+};
+
+static struct platform_driver mem_object_plat_driver = {
+	.probe = mem_object_probe,
+	.driver = {
+		.name = "mem-object",
+		.dev_groups = attr_groups,
+		.of_match_table = mem_object_match,
+	},
+};
+
+module_platform_driver(mem_object_plat_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Memory object driver");
+MODULE_IMPORT_NS(DMA_BUF);
--- linux-qcom-6.8.0.orig/drivers/firmware/qcom/tz_log.c
+++ linux-qcom-6.8.0/drivers/firmware/qcom/tz_log.c
@@ -0,0 +1,1960 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt) "tz_log:[%s][%d]: " fmt, __func__, __LINE__
+
+#include <linux/debugfs.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/of.h>
+#include <linux/dma-buf.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_tzmem.h>
+#include <linux/proc_fs.h>
+#include <linux/version.h>
+#if IS_ENABLED(CONFIG_MSM_TMECOM_QMP)
+#include <linux/tmelog.h>
+#endif
+
+
+/* QSEE_LOG_BUF_SIZE = 32K */
+#define QSEE_LOG_BUF_SIZE 0x8000
+
+/* enlarged qsee log buf size is 128K by default */
+#define QSEE_LOG_BUF_SIZE_V2 0x20000
+
+/* Tme log buffer size 20K */
+#define TME_LOG_BUF_SIZE 0x5000
+
+/* TZ Diagnostic Area legacy version number */
+#define TZBSP_DIAG_MAJOR_VERSION_LEGACY	2
+
+/* TZ Diagnostic Area version number */
+#define TZBSP_FVER_MAJOR_MINOR_MASK     0x3FF  /* 10 bits */
+#define TZBSP_FVER_MAJOR_SHIFT          22
+#define TZBSP_FVER_MINOR_SHIFT          12
+#define TZBSP_DIAG_MAJOR_VERSION_V9     9
+#define TZBSP_DIAG_MINOR_VERSION_V2     2
+#define TZBSP_DIAG_MINOR_VERSION_V21    3
+#define TZBSP_DIAG_MINOR_VERSION_V22    4
+
+/* TZ Diag Feature Version Id */
+#define QCOM_SCM_FEAT_DIAG_ID           0x06
+
+/*
+ * Preprocessor Definitions and Constants
+ */
+#define TZBSP_MAX_CPU_COUNT 0x08
+/*
+ * Number of VMID Tables
+ */
+#define TZBSP_DIAG_NUM_OF_VMID 16
+/*
+ * VMID Description length
+ */
+#define TZBSP_DIAG_VMID_DESC_LEN 7
+/*
+ * Number of Interrupts
+ */
+#define TZBSP_DIAG_INT_NUM  32
+/*
+ * Length of descriptive name associated with Interrupt
+ */
+#define TZBSP_MAX_INT_DESC 16
+/*
+ * TZ 3.X version info
+ */
+#define QSEE_VERSION_TZ_3_X 0x800000
+/*
+ * TZ 4.X version info
+ */
+#define QSEE_VERSION_TZ_4_X 0x1000000
+
+#define TZBSP_AES_256_ENCRYPTED_KEY_SIZE 256
+#define TZBSP_NONCE_LEN 12
+#define TZBSP_TAG_LEN 16
+
+#define ENCRYPTED_TZ_LOG_ID 0
+#define ENCRYPTED_QSEE_LOG_ID 1
+
+/*
+ * Directory for TZ DBG logs
+ */
+#define TZDBG_DIR_NAME "tzdbg"
+
+/*
+ * VMID Table
+ */
+struct tzdbg_vmid_t {
+	uint8_t vmid; /* Virtual Machine Identifier */
+	uint8_t desc[TZBSP_DIAG_VMID_DESC_LEN];	/* ASCII Text */
+};
+/*
+ * Boot Info Table
+ */
+struct tzdbg_boot_info_t {
+	uint32_t wb_entry_cnt;	/* Warmboot entry CPU Counter */
+	uint32_t wb_exit_cnt;	/* Warmboot exit CPU Counter */
+	uint32_t pc_entry_cnt;	/* Power Collapse entry CPU Counter */
+	uint32_t pc_exit_cnt;	/* Power Collapse exit CPU counter */
+	uint32_t warm_jmp_addr;	/* Last Warmboot Jump Address */
+	uint32_t spare;	/* Reserved for future use. */
+};
+/*
+ * Boot Info Table for 64-bit
+ */
+struct tzdbg_boot_info64_t {
+	uint32_t wb_entry_cnt;  /* Warmboot entry CPU Counter */
+	uint32_t wb_exit_cnt;   /* Warmboot exit CPU Counter */
+	uint32_t pc_entry_cnt;  /* Power Collapse entry CPU Counter */
+	uint32_t pc_exit_cnt;   /* Power Collapse exit CPU counter */
+	uint32_t psci_entry_cnt;/* PSCI syscall entry CPU Counter */
+	uint32_t psci_exit_cnt;   /* PSCI syscall exit CPU Counter */
+	uint64_t warm_jmp_addr; /* Last Warmboot Jump Address */
+	uint32_t warm_jmp_instr; /* Last Warmboot Jump Address Instruction */
+};
+/*
+ * Reset Info Table
+ */
+struct tzdbg_reset_info_t {
+	uint32_t reset_type;	/* Reset Reason */
+	uint32_t reset_cnt;	/* Number of resets occurred/CPU */
+};
+/*
+ * Interrupt Info Table
+ */
+struct tzdbg_int_t {
+	/*
+	 * Type of Interrupt/exception
+	 */
+	uint16_t int_info;
+	/*
+	 * Availability of the slot
+	 */
+	uint8_t avail;
+	/*
+	 * Reserved for future use
+	 */
+	uint8_t spare;
+	/*
+	 * Interrupt # for IRQ and FIQ
+	 */
+	uint32_t int_num;
+	/*
+	 * ASCII text describing type of interrupt e.g:
+	 * Secure Timer, EBI XPU. This string is always null terminated,
+	 * supporting at most TZBSP_MAX_INT_DESC characters.
+	 * Any additional characters are truncated.
+	 */
+	uint8_t int_desc[TZBSP_MAX_INT_DESC];
+	uint64_t int_count[TZBSP_MAX_CPU_COUNT]; /* # of times seen per CPU */
+};
+
+/*
+ * Interrupt Info Table used in tz version >=4.X
+ */
+struct tzdbg_int_t_tz40 {
+	uint16_t int_info;
+	uint8_t avail;
+	uint8_t spare;
+	uint32_t int_num;
+	uint8_t int_desc[TZBSP_MAX_INT_DESC];
+	uint32_t int_count[TZBSP_MAX_CPU_COUNT]; /* uint32_t in TZ ver >= 4.x*/
+};
+
+/* warm boot reason for cores */
+struct tzbsp_diag_wakeup_info_t {
+	/* Wake source info : APCS_GICC_HPPIR */
+	uint32_t HPPIR;
+	/* Wake source info : APCS_GICC_AHPPIR */
+	uint32_t AHPPIR;
+};
+
+/*
+ * Log ring buffer position
+ */
+struct tzdbg_log_pos_t {
+	uint16_t wrap;
+	uint16_t offset;
+};
+
+struct tzdbg_log_pos_v2_t {
+	uint32_t wrap;
+	uint32_t offset;
+};
+
+ /*
+  * Log ring buffer
+  */
+struct tzdbg_log_t {
+	struct tzdbg_log_pos_t	log_pos;
+	/* open ended array to the end of the 4K IMEM buffer */
+	uint8_t					log_buf[];
+};
+
+struct tzdbg_log_v2_t {
+	struct tzdbg_log_pos_v2_t	log_pos;
+	/* open ended array to the end of the 4K IMEM buffer */
+	uint8_t					log_buf[];
+};
+
+struct tzbsp_encr_info_for_log_chunk_t {
+	uint32_t size_to_encr;
+	uint8_t nonce[TZBSP_NONCE_LEN];
+	uint8_t tag[TZBSP_TAG_LEN];
+};
+
+/*
+ * Only `ENTIRE_LOG` will be used unless the
+ * "OEM_tz_num_of_diag_log_chunks_to_encr" devcfg field >= 2.
+ * If this is true, the diag log will be encrypted in two
+ * separate chunks: a smaller chunk containing only error
+ * fatal logs and a bigger "rest of the log" chunk. In this
+ * case, `ERR_FATAL_LOG_CHUNK` and `BIG_LOG_CHUNK` will be
+ * used instead of `ENTIRE_LOG`.
+ */
+enum tzbsp_encr_info_for_log_chunks_idx_t {
+	BIG_LOG_CHUNK = 0,
+	ENTIRE_LOG = 1,
+	ERR_FATAL_LOG_CHUNK = 1,
+	MAX_NUM_OF_CHUNKS,
+};
+
+struct tzbsp_encr_info_t {
+	uint32_t num_of_chunks;
+	struct tzbsp_encr_info_for_log_chunk_t chunks[MAX_NUM_OF_CHUNKS];
+	uint8_t key[TZBSP_AES_256_ENCRYPTED_KEY_SIZE];
+};
+
+/*
+ * Diagnostic Table
+ * Note: This is the reference data structure for tz diagnostic table
+ * supporting TZBSP_MAX_CPU_COUNT, the real diagnostic data is directly
+ * copied into buffer from i/o memory.
+ */
+struct tzdbg_t {
+	uint32_t magic_num;
+	uint32_t version;
+	/*
+	 * Number of CPU's
+	 */
+	uint32_t cpu_count;
+	/*
+	 * Offset of VMID Table
+	 */
+	uint32_t vmid_info_off;
+	/*
+	 * Offset of Boot Table
+	 */
+	uint32_t boot_info_off;
+	/*
+	 * Offset of Reset info Table
+	 */
+	uint32_t reset_info_off;
+	/*
+	 * Offset of Interrupt info Table
+	 */
+	uint32_t int_info_off;
+	/*
+	 * Ring Buffer Offset
+	 */
+	uint32_t ring_off;
+	/*
+	 * Ring Buffer Length
+	 */
+	uint32_t ring_len;
+
+	/* Offset for Wakeup info */
+	uint32_t wakeup_info_off;
+
+	union {
+		/* The elements in below structure have to be used for TZ where
+		 * diag version = TZBSP_DIAG_MINOR_VERSION_V2
+		 */
+		struct {
+
+			/*
+			 * VMID to EE Mapping
+			 */
+			struct tzdbg_vmid_t vmid_info[TZBSP_DIAG_NUM_OF_VMID];
+			/*
+			 * Boot Info
+			 */
+			struct tzdbg_boot_info_t  boot_info[TZBSP_MAX_CPU_COUNT];
+			/*
+			 * Reset Info
+			 */
+			struct tzdbg_reset_info_t reset_info[TZBSP_MAX_CPU_COUNT];
+			uint32_t num_interrupts;
+			struct tzdbg_int_t  int_info[TZBSP_DIAG_INT_NUM];
+			/* Wake up info */
+			struct tzbsp_diag_wakeup_info_t  wakeup_info[TZBSP_MAX_CPU_COUNT];
+
+			uint8_t key[TZBSP_AES_256_ENCRYPTED_KEY_SIZE];
+
+			uint8_t nonce[TZBSP_NONCE_LEN];
+
+			uint8_t tag[TZBSP_TAG_LEN];
+		};
+		/* The elements in below structure have to be used for TZ where
+		 * diag version = TZBSP_DIAG_MINOR_VERSION_V21
+		 */
+		struct {
+
+			uint32_t encr_info_for_log_off;
+
+			/*
+			 * VMID to EE Mapping
+			 */
+			struct tzdbg_vmid_t vmid_info_v2[TZBSP_DIAG_NUM_OF_VMID];
+			/*
+			 * Boot Info
+			 */
+			struct tzdbg_boot_info_t  boot_info_v2[TZBSP_MAX_CPU_COUNT];
+			/*
+			 * Reset Info
+			 */
+			struct tzdbg_reset_info_t reset_info_v2[TZBSP_MAX_CPU_COUNT];
+			uint32_t num_interrupts_v2;
+			struct tzdbg_int_t  int_info_v2[TZBSP_DIAG_INT_NUM];
+
+			/* Wake up info */
+			struct tzbsp_diag_wakeup_info_t  wakeup_info_v2[TZBSP_MAX_CPU_COUNT];
+
+			struct tzbsp_encr_info_t encr_info_for_log;
+		};
+	};
+
+	/*
+	 * We need at least 2K for the ring buffer
+	 */
+	struct tzdbg_log_t ring_buffer;	/* TZ Ring Buffer */
+};
+
+struct hypdbg_log_pos_t {
+	uint16_t wrap;
+	uint16_t offset;
+};
+
+struct rmdbg_log_hdr_t {
+	uint32_t write_idx;
+	uint32_t size;
+};
+struct rmdbg_log_pos_t {
+	uint32_t read_idx;
+	uint32_t size;
+};
+struct hypdbg_boot_info_t {
+	uint32_t warm_entry_cnt;
+	uint32_t warm_exit_cnt;
+};
+
+struct hypdbg_t {
+	/* Magic Number */
+	uint32_t magic_num;
+
+	/* Number of CPU's */
+	uint32_t cpu_count;
+
+	/* Ring Buffer Offset */
+	uint32_t ring_off;
+
+	/* Ring buffer position mgmt */
+	struct hypdbg_log_pos_t log_pos;
+	uint32_t log_len;
+
+	/* S2 fault numbers */
+	uint32_t s2_fault_counter;
+
+	/* Boot Info */
+	struct hypdbg_boot_info_t boot_info[TZBSP_MAX_CPU_COUNT];
+
+	/* Ring buffer pointer */
+	uint8_t log_buf_p[];
+};
+
+struct tme_log_pos {
+	uint32_t offset;
+	size_t size;
+};
+
+/*
+ * Enumeration order for VMID's
+ */
+enum tzdbg_stats_type {
+	TZDBG_BOOT = 0,
+	TZDBG_RESET,
+	TZDBG_INTERRUPT,
+	TZDBG_VMID,
+	TZDBG_GENERAL,
+	TZDBG_LOG,
+	TZDBG_QSEE_LOG,
+	TZDBG_HYP_GENERAL,
+	TZDBG_HYP_LOG,
+	TZDBG_RM_LOG,
+	TZDBG_TME_LOG,
+	TZDBG_STATS_MAX
+};
+
+struct tzdbg_stat {
+	size_t display_len;
+	size_t display_offset;
+	char *name;
+	char *data;
+	bool avail;
+};
+
+struct tzdbg {
+	void __iomem *virt_iobase;
+	void __iomem *hyp_virt_iobase;
+	void __iomem *rmlog_virt_iobase;
+	void __iomem *tmelog_virt_iobase;
+	struct tzdbg_t *diag_buf;
+	struct hypdbg_t *hyp_diag_buf;
+	uint8_t *rm_diag_buf;
+	uint8_t *tme_buf;
+	char *disp_buf;
+	int debug_tz[TZDBG_STATS_MAX];
+	struct tzdbg_stat stat[TZDBG_STATS_MAX];
+	uint32_t hyp_debug_rw_buf_size;
+	uint32_t rmlog_rw_buf_size;
+	bool is_hyplog_enabled;
+	uint32_t tz_version;
+	bool is_encrypted_log_enabled;
+	bool is_enlarged_buf;
+	bool is_full_encrypted_tz_logs_supported;
+	bool is_full_encrypted_tz_logs_enabled;
+	int tz_diag_minor_version;
+	int tz_diag_major_version;
+};
+
+struct tzbsp_encr_log_t {
+	/* Magic Number */
+	uint32_t magic_num;
+	/* version NUMBER */
+	uint32_t version;
+	/* encrypted log size */
+	uint32_t encr_log_buff_size;
+	/* Wrap value*/
+	uint16_t wrap_count;
+	/* AES encryption key wrapped up with oem public key*/
+	uint8_t key[TZBSP_AES_256_ENCRYPTED_KEY_SIZE];
+	/* Nonce used for encryption*/
+	uint8_t nonce[TZBSP_NONCE_LEN];
+	/* Tag to be used for Validation */
+	uint8_t tag[TZBSP_TAG_LEN];
+	/* Encrypted log buffer */
+	uint8_t log_buf[];
+};
+
+struct encrypted_log_info {
+	phys_addr_t paddr;
+	void *vaddr;
+	size_t size;
+	uint64_t shmb_handle;
+};
+
+static struct tzdbg tzdbg = {
+	.stat[TZDBG_BOOT].name = "boot",
+	.stat[TZDBG_RESET].name = "reset",
+	.stat[TZDBG_INTERRUPT].name = "interrupt",
+	.stat[TZDBG_VMID].name = "vmid",
+	.stat[TZDBG_GENERAL].name = "general",
+	.stat[TZDBG_LOG].name = "log",
+	.stat[TZDBG_QSEE_LOG].name = "qsee_log",
+	.stat[TZDBG_HYP_GENERAL].name = "hyp_general",
+	.stat[TZDBG_HYP_LOG].name = "hyp_log",
+	.stat[TZDBG_RM_LOG].name = "rm_log",
+	.stat[TZDBG_TME_LOG].name = "tme_log",
+};
+
+static struct tzdbg_log_t *g_qsee_log;
+static struct tzdbg_log_v2_t *g_qsee_log_v2;
+static dma_addr_t coh_pmem;
+static uint32_t debug_rw_buf_size;
+static uint32_t display_buf_size;
+static uint32_t qseelog_buf_size;
+static phys_addr_t disp_buf_paddr;
+static uint32_t tmecrashdump_address_offset;
+
+static uint64_t qseelog_shmbridge_handle;
+static struct encrypted_log_info enc_qseelog_info;
+static struct encrypted_log_info enc_tzlog_info;
+
+/*
+ * Debugfs data structure and functions
+ */
+
+static int _disp_tz_general_stats(void)
+{
+	int len = 0;
+
+	len += scnprintf(tzdbg.disp_buf + len, debug_rw_buf_size - 1,
+			"   Version        : 0x%x\n"
+			"   Magic Number   : 0x%x\n"
+			"   Number of CPU  : %d\n",
+			tzdbg.diag_buf->version,
+			tzdbg.diag_buf->magic_num,
+			tzdbg.diag_buf->cpu_count);
+	tzdbg.stat[TZDBG_GENERAL].data = tzdbg.disp_buf;
+	return len;
+}
+
+static int _disp_tz_vmid_stats(void)
+{
+	int i, num_vmid;
+	int len = 0;
+	struct tzdbg_vmid_t *ptr;
+
+	ptr = (struct tzdbg_vmid_t *)((unsigned char *)tzdbg.diag_buf +
+					tzdbg.diag_buf->vmid_info_off);
+	num_vmid = ((tzdbg.diag_buf->boot_info_off -
+				tzdbg.diag_buf->vmid_info_off)/
+					(sizeof(struct tzdbg_vmid_t)));
+
+	for (i = 0; i < num_vmid; i++) {
+		if (ptr->vmid < 0xFF) {
+			len += scnprintf(tzdbg.disp_buf + len,
+				(debug_rw_buf_size - 1) - len,
+				"   0x%x        %s\n",
+				(uint32_t)ptr->vmid, (uint8_t *)ptr->desc);
+		}
+		if (len > (debug_rw_buf_size - 1)) {
+			pr_warn("%s: Cannot fit all info into the buffer\n",
+								__func__);
+			break;
+		}
+		ptr++;
+	}
+
+	tzdbg.stat[TZDBG_VMID].data = tzdbg.disp_buf;
+	return len;
+}
+
+static int _disp_tz_boot_stats(void)
+{
+	int i;
+	int len = 0;
+	struct tzdbg_boot_info_t *ptr = NULL;
+	struct tzdbg_boot_info64_t *ptr_64 = NULL;
+
+	pr_info("qsee_version = 0x%x\n", tzdbg.tz_version);
+	if (tzdbg.tz_version >= QSEE_VERSION_TZ_3_X) {
+		ptr_64 = (struct tzdbg_boot_info64_t *)((unsigned char *)
+			tzdbg.diag_buf + tzdbg.diag_buf->boot_info_off);
+	} else {
+		ptr = (struct tzdbg_boot_info_t *)((unsigned char *)
+			tzdbg.diag_buf + tzdbg.diag_buf->boot_info_off);
+	}
+
+	for (i = 0; i < tzdbg.diag_buf->cpu_count; i++) {
+		if (tzdbg.tz_version >= QSEE_VERSION_TZ_3_X) {
+			len += scnprintf(tzdbg.disp_buf + len,
+					(debug_rw_buf_size - 1) - len,
+					"  CPU #: %d\n"
+					"     Warmboot jump address : 0x%llx\n"
+					"     Warmboot entry CPU counter : 0x%x\n"
+					"     Warmboot exit CPU counter : 0x%x\n"
+					"     Power Collapse entry CPU counter : 0x%x\n"
+					"     Power Collapse exit CPU counter : 0x%x\n"
+					"     Psci entry CPU counter : 0x%x\n"
+					"     Psci exit CPU counter : 0x%x\n"
+					"     Warmboot Jump Address Instruction : 0x%x\n",
+					i, (uint64_t)ptr_64->warm_jmp_addr,
+					ptr_64->wb_entry_cnt,
+					ptr_64->wb_exit_cnt,
+					ptr_64->pc_entry_cnt,
+					ptr_64->pc_exit_cnt,
+					ptr_64->psci_entry_cnt,
+					ptr_64->psci_exit_cnt,
+					ptr_64->warm_jmp_instr);
+
+			if (len > (debug_rw_buf_size - 1)) {
+				pr_warn("%s: Cannot fit all info into the buffer\n",
+						__func__);
+				break;
+			}
+			ptr_64++;
+		} else {
+			len += scnprintf(tzdbg.disp_buf + len,
+					(debug_rw_buf_size - 1) - len,
+					"  CPU #: %d\n"
+					"     Warmboot jump address     : 0x%x\n"
+					"     Warmboot entry CPU counter: 0x%x\n"
+					"     Warmboot exit CPU counter : 0x%x\n"
+					"     Power Collapse entry CPU counter: 0x%x\n"
+					"     Power Collapse exit CPU counter : 0x%x\n",
+					i, ptr->warm_jmp_addr,
+					ptr->wb_entry_cnt,
+					ptr->wb_exit_cnt,
+					ptr->pc_entry_cnt,
+					ptr->pc_exit_cnt);
+
+			if (len > (debug_rw_buf_size - 1)) {
+				pr_warn("%s: Cannot fit all info into the buffer\n",
+						__func__);
+				break;
+			}
+			ptr++;
+		}
+	}
+	tzdbg.stat[TZDBG_BOOT].data = tzdbg.disp_buf;
+	return len;
+}
+
+static int _disp_tz_reset_stats(void)
+{
+	int i;
+	int len = 0;
+	struct tzdbg_reset_info_t *ptr;
+
+	ptr = (struct tzdbg_reset_info_t *)((unsigned char *)tzdbg.diag_buf +
+					tzdbg.diag_buf->reset_info_off);
+
+	for (i = 0; i < tzdbg.diag_buf->cpu_count; i++) {
+		len += scnprintf(tzdbg.disp_buf + len,
+				(debug_rw_buf_size - 1) - len,
+				"  CPU #: %d\n"
+				"     Reset Type (reason)       : 0x%x\n"
+				"     Reset counter             : 0x%x\n",
+				i, ptr->reset_type, ptr->reset_cnt);
+
+		if (len > (debug_rw_buf_size - 1)) {
+			pr_warn("%s: Cannot fit all info into the buffer\n",
+								__func__);
+			break;
+		}
+
+		ptr++;
+	}
+	tzdbg.stat[TZDBG_RESET].data = tzdbg.disp_buf;
+	return len;
+}
+
+static int _disp_tz_interrupt_stats(void)
+{
+	int i, j;
+	int len = 0;
+	int *num_int;
+	void *ptr;
+	struct tzdbg_int_t *tzdbg_ptr;
+	struct tzdbg_int_t_tz40 *tzdbg_ptr_tz40;
+
+	num_int = (uint32_t *)((unsigned char *)tzdbg.diag_buf +
+			(tzdbg.diag_buf->int_info_off - sizeof(uint32_t)));
+	ptr = ((unsigned char *)tzdbg.diag_buf +
+					tzdbg.diag_buf->int_info_off);
+
+	pr_info("qsee_version = 0x%x\n", tzdbg.tz_version);
+
+	if (tzdbg.tz_version < QSEE_VERSION_TZ_4_X) {
+		tzdbg_ptr = ptr;
+		for (i = 0; i < (*num_int); i++) {
+			len += scnprintf(tzdbg.disp_buf + len,
+				(debug_rw_buf_size - 1) - len,
+				"     Interrupt Number          : 0x%x\n"
+				"     Type of Interrupt         : 0x%x\n"
+				"     Description of interrupt  : %s\n",
+				tzdbg_ptr->int_num,
+				(uint32_t)tzdbg_ptr->int_info,
+				(uint8_t *)tzdbg_ptr->int_desc);
+			for (j = 0; j < tzdbg.diag_buf->cpu_count; j++) {
+				len += scnprintf(tzdbg.disp_buf + len,
+				(debug_rw_buf_size - 1) - len,
+				"     int_count on CPU # %d      : %u\n",
+				(uint32_t)j,
+				(uint32_t)tzdbg_ptr->int_count[j]);
+			}
+			len += scnprintf(tzdbg.disp_buf + len,
+					debug_rw_buf_size - 1, "\n");
+
+			if (len > (debug_rw_buf_size - 1)) {
+				pr_warn("%s: Cannot fit all info into buf\n",
+								__func__);
+				break;
+			}
+			tzdbg_ptr++;
+		}
+	} else {
+		tzdbg_ptr_tz40 = ptr;
+		for (i = 0; i < (*num_int); i++) {
+			len += scnprintf(tzdbg.disp_buf + len,
+				(debug_rw_buf_size - 1) - len,
+				"     Interrupt Number          : 0x%x\n"
+				"     Type of Interrupt         : 0x%x\n"
+				"     Description of interrupt  : %s\n",
+				tzdbg_ptr_tz40->int_num,
+				(uint32_t)tzdbg_ptr_tz40->int_info,
+				(uint8_t *)tzdbg_ptr_tz40->int_desc);
+			for (j = 0; j < tzdbg.diag_buf->cpu_count; j++) {
+				len += scnprintf(tzdbg.disp_buf + len,
+				(debug_rw_buf_size - 1) - len,
+				"     int_count on CPU # %d      : %u\n",
+				(uint32_t)j,
+				(uint32_t)tzdbg_ptr_tz40->int_count[j]);
+			}
+			len += scnprintf(tzdbg.disp_buf + len,
+					debug_rw_buf_size - 1, "\n");
+
+			if (len > (debug_rw_buf_size - 1)) {
+				pr_warn("%s: Cannot fit all info into buf\n",
+								__func__);
+				break;
+			}
+			tzdbg_ptr_tz40++;
+		}
+	}
+
+	tzdbg.stat[TZDBG_INTERRUPT].data = tzdbg.disp_buf;
+	return len;
+}
+
+static int _disp_tz_log_stats_legacy(void)
+{
+	int len = 0;
+	unsigned char *ptr;
+
+	ptr = (unsigned char *)tzdbg.diag_buf +
+					tzdbg.diag_buf->ring_off;
+	len += scnprintf(tzdbg.disp_buf, (debug_rw_buf_size - 1) - len,
+							"%s\n", ptr);
+
+	tzdbg.stat[TZDBG_LOG].data = tzdbg.disp_buf;
+	return len;
+}
+
+static int _disp_log_stats(struct tzdbg_log_t *log,
+			struct tzdbg_log_pos_t *log_start, uint32_t log_len,
+			size_t count, uint32_t buf_idx)
+{
+	uint32_t wrap_start;
+	uint32_t wrap_end;
+	uint32_t wrap_cnt;
+	int max_len;
+	int len = 0;
+	int i = 0;
+
+	wrap_start = log_start->wrap;
+	wrap_end = log->log_pos.wrap;
+
+	/* Calculate difference in # of buffer wrap-arounds */
+	if (wrap_end >= wrap_start)
+		wrap_cnt = wrap_end - wrap_start;
+	else {
+		/* wrap counter has wrapped around, invalidate start position */
+		wrap_cnt = 2;
+	}
+
+	if (wrap_cnt > 1) {
+		/* end position has wrapped around more than once, */
+		/* current start no longer valid                   */
+		log_start->wrap = log->log_pos.wrap - 1;
+		log_start->offset = (log->log_pos.offset + 1) % log_len;
+	} else if ((wrap_cnt == 1) &&
+		(log->log_pos.offset > log_start->offset)) {
+		/* end position has overwritten start */
+		log_start->offset = (log->log_pos.offset + 1) % log_len;
+	}
+
+	pr_debug("diag_buf wrap = %u, offset = %u\n",
+		log->log_pos.wrap, log->log_pos.offset);
+	while (log_start->offset == log->log_pos.offset) {
+		/*
+		 * No data in ring buffer,
+		 * so we'll hang around until something happens
+		 */
+		unsigned long t = msleep_interruptible(50);
+
+		if (t != 0) {
+			/* Some event woke us up, so let's quit */
+			return 0;
+}
+
+		if (buf_idx == TZDBG_LOG)
+			memcpy_fromio((void *)tzdbg.diag_buf, tzdbg.virt_iobase,
+						debug_rw_buf_size);
+
+	}
+
+	max_len = (count > debug_rw_buf_size) ? debug_rw_buf_size : count;
+
+	pr_debug("diag_buf wrap = %u, offset = %u\n",
+		log->log_pos.wrap, log->log_pos.offset);
+	/*
+	 *  Read from ring buff while there is data and space in return buff
+	 */
+	while ((log_start->offset != log->log_pos.offset) && (len < max_len)) {
+		tzdbg.disp_buf[i++] = log->log_buf[log_start->offset];
+		log_start->offset = (log_start->offset + 1) % log_len;
+		if (log_start->offset == 0)
+			++log_start->wrap;
+		++len;
+	}
+
+	/*
+	 * return buffer to caller
+	 */
+	tzdbg.stat[buf_idx].data = tzdbg.disp_buf;
+	return len;
+}
+
+static int _disp_log_stats_v2(struct tzdbg_log_v2_t *log,
+			struct tzdbg_log_pos_v2_t *log_start, uint32_t log_len,
+			size_t count, uint32_t buf_idx)
+{
+	uint32_t wrap_start;
+	uint32_t wrap_end;
+	uint32_t wrap_cnt;
+	int max_len;
+	int len = 0;
+	int i = 0;
+
+	wrap_start = log_start->wrap;
+	wrap_end = log->log_pos.wrap;
+
+	/* Calculate difference in # of buffer wrap-arounds */
+	if (wrap_end >= wrap_start)
+		wrap_cnt = wrap_end - wrap_start;
+	else {
+		/* wrap counter has wrapped around, invalidate start position */
+		wrap_cnt = 2;
+}
+
+	if (wrap_cnt > 1) {
+		/* end position has wrapped around more than once, */
+		/* current start no longer valid                   */
+		log_start->wrap = log->log_pos.wrap - 1;
+		log_start->offset = (log->log_pos.offset + 1) % log_len;
+	} else if ((wrap_cnt == 1) &&
+		(log->log_pos.offset > log_start->offset)) {
+		/* end position has overwritten start */
+		log_start->offset = (log->log_pos.offset + 1) % log_len;
+	}
+	pr_debug("diag_buf wrap = %u, offset = %u\n",
+		log->log_pos.wrap, log->log_pos.offset);
+
+	while (log_start->offset == log->log_pos.offset) {
+		/*
+		 * No data in ring buffer,
+		 * so we'll hang around until something happens
+		 */
+		unsigned long t = msleep_interruptible(50);
+
+		if (t != 0) {
+			/* Some event woke us up, so let's quit */
+			return 0;
+		}
+
+		if (buf_idx == TZDBG_LOG)
+			memcpy_fromio((void *)tzdbg.diag_buf, tzdbg.virt_iobase,
+						debug_rw_buf_size);
+
+	}
+
+	max_len = (count > debug_rw_buf_size) ? debug_rw_buf_size : count;
+
+	pr_debug("diag_buf wrap = %u, offset = %u\n",
+		log->log_pos.wrap, log->log_pos.offset);
+
+	/*
+	 *  Read from ring buff while there is data and space in return buff
+	 */
+	while ((log_start->offset != log->log_pos.offset) && (len < max_len)) {
+		tzdbg.disp_buf[i++] = log->log_buf[log_start->offset];
+		log_start->offset = (log_start->offset + 1) % log_len;
+		if (log_start->offset == 0)
+			++log_start->wrap;
+		++len;
+	}
+
+	/*
+	 * return buffer to caller
+	 */
+	tzdbg.stat[buf_idx].data = tzdbg.disp_buf;
+	return len;
+}
+
+static int __disp_hyp_log_stats(uint8_t *log,
+			struct hypdbg_log_pos_t *log_start, uint32_t log_len,
+			size_t count, uint32_t buf_idx)
+{
+	struct hypdbg_t *hyp = tzdbg.hyp_diag_buf;
+	unsigned long t = 0;
+	uint32_t wrap_start;
+	uint32_t wrap_end;
+	uint32_t wrap_cnt;
+	int max_len;
+	int len = 0;
+	int i = 0;
+
+	wrap_start = log_start->wrap;
+	wrap_end = hyp->log_pos.wrap;
+
+	/* Calculate difference in # of buffer wrap-arounds */
+	if (wrap_end >= wrap_start)
+		wrap_cnt = wrap_end - wrap_start;
+	else {
+		/* wrap counter has wrapped around, invalidate start position */
+		wrap_cnt = 2;
+	}
+
+	if (wrap_cnt > 1) {
+		/* end position has wrapped around more than once, */
+		/* current start no longer valid                   */
+		log_start->wrap = hyp->log_pos.wrap - 1;
+		log_start->offset = (hyp->log_pos.offset + 1) % log_len;
+	} else if ((wrap_cnt == 1) &&
+		(hyp->log_pos.offset > log_start->offset)) {
+		/* end position has overwritten start */
+		log_start->offset = (hyp->log_pos.offset + 1) % log_len;
+	}
+
+	while (log_start->offset == hyp->log_pos.offset) {
+		/*
+		 * No data in ring buffer,
+		 * so we'll hang around until something happens
+		 */
+		t = msleep_interruptible(50);
+		if (t != 0) {
+			/* Some event woke us up, so let's quit */
+			return 0;
+		}
+
+		/* TZDBG_HYP_LOG */
+		memcpy_fromio((void *)tzdbg.hyp_diag_buf, tzdbg.hyp_virt_iobase,
+						tzdbg.hyp_debug_rw_buf_size);
+	}
+
+	max_len = (count > tzdbg.hyp_debug_rw_buf_size) ?
+				tzdbg.hyp_debug_rw_buf_size : count;
+
+	/*
+	 *  Read from ring buff while there is data and space in return buff
+	 */
+	while ((log_start->offset != hyp->log_pos.offset) && (len < max_len)) {
+		tzdbg.disp_buf[i++] = log[log_start->offset];
+		log_start->offset = (log_start->offset + 1) % log_len;
+		if (log_start->offset == 0)
+			++log_start->wrap;
+		++len;
+	}
+
+	/*
+	 * return buffer to caller
+	 */
+	tzdbg.stat[buf_idx].data = tzdbg.disp_buf;
+	return len;
+}
+static int __disp_rm_log_stats(uint8_t *log_ptr, uint32_t max_len)
+{
+	uint32_t i = 0;
+	/*
+	 *  Transfer data from rm dialog buff to display buffer in user space
+	 */
+	while ((i < max_len) && (i < display_buf_size)) {
+		tzdbg.disp_buf[i] = log_ptr[i];
+		i++;
+	}
+	if (i != max_len)
+		pr_err("Dropping RM log message, max_len:%d display_buf_size:%d\n",
+			i, display_buf_size);
+	tzdbg.stat[TZDBG_RM_LOG].data = tzdbg.disp_buf;
+	return i;
+}
+
+static int print_text(char *intro_message,
+			unsigned char *text_addr,
+			unsigned int size,
+			char *buf, uint32_t buf_len)
+{
+	unsigned int   i;
+	int len = 0;
+
+	pr_debug("begin address %p, size %d\n", text_addr, size);
+	len += scnprintf(buf + len, buf_len - len, "%s\n", intro_message);
+	for (i = 0;  i < size;  i++) {
+		if (buf_len <= len + 6) {
+			pr_err("buffer not enough, buf_len %d, len %d\n",
+				buf_len, len);
+			return buf_len;
+		}
+		len += scnprintf(buf + len, buf_len - len, "%02hhx ",
+					text_addr[i]);
+		if ((i & 0x1f) == 0x1f)
+			len += scnprintf(buf + len, buf_len - len, "%c", '\n');
+	}
+	len += scnprintf(buf + len, buf_len - len, "%c", '\n');
+	return len;
+}
+
+static int _disp_encrpted_log_stats(struct encrypted_log_info *enc_log_info,
+				enum tzdbg_stats_type type, uint32_t log_id)
+{
+	int ret = 0, len = 0;
+	struct tzbsp_encr_log_t *encr_log_head;
+	uint32_t size = 0;
+
+	if ((!tzdbg.is_full_encrypted_tz_logs_supported) &&
+		(tzdbg.is_full_encrypted_tz_logs_enabled))
+		pr_info("TZ not supporting full encrypted log functionality\n");
+	ret = qcom_scm_request_encrypted_log(enc_log_info->paddr,
+		enc_log_info->size, log_id, tzdbg.is_full_encrypted_tz_logs_supported,
+		tzdbg.is_full_encrypted_tz_logs_enabled);
+	if (ret)
+		return 0;
+	encr_log_head = (struct tzbsp_encr_log_t *)(enc_log_info->vaddr);
+	pr_debug("display_buf_size = %d, encr_log_buff_size = %d\n",
+		display_buf_size, encr_log_head->encr_log_buff_size);
+	size = encr_log_head->encr_log_buff_size;
+
+	len += scnprintf(tzdbg.disp_buf + len,
+			(display_buf_size - 1) - len,
+			"\n-------- New Encrypted %s --------\n",
+			((log_id == ENCRYPTED_QSEE_LOG_ID) ?
+				"QSEE Log" : "TZ Dialog"));
+
+	len += scnprintf(tzdbg.disp_buf + len,
+			(display_buf_size - 1) - len,
+			"\nMagic_Num :\n0x%x\n"
+			"\nVerion :\n%d\n"
+			"\nEncr_Log_Buff_Size :\n%d\n"
+			"\nWrap_Count :\n%d\n",
+			encr_log_head->magic_num,
+			encr_log_head->version,
+			encr_log_head->encr_log_buff_size,
+			encr_log_head->wrap_count);
+
+	len += print_text("\nKey : ", encr_log_head->key,
+			TZBSP_AES_256_ENCRYPTED_KEY_SIZE,
+			tzdbg.disp_buf + len, display_buf_size);
+	len += print_text("\nNonce : ", encr_log_head->nonce,
+			TZBSP_NONCE_LEN,
+			tzdbg.disp_buf + len, display_buf_size - len);
+	len += print_text("\nTag : ", encr_log_head->tag,
+			TZBSP_TAG_LEN,
+			tzdbg.disp_buf + len, display_buf_size - len);
+
+	if (len > display_buf_size - size)
+		pr_warn("Cannot fit all info into the buffer\n");
+
+	pr_debug("encrypted log size %d, disply buffer size %d, used len %d\n",
+			size, display_buf_size, len);
+
+	len += print_text("\nLog : ", encr_log_head->log_buf, size,
+				tzdbg.disp_buf + len, display_buf_size - len);
+	memset(enc_log_info->vaddr, 0, enc_log_info->size);
+	tzdbg.stat[type].data = tzdbg.disp_buf;
+	return len;
+}
+
+static int _disp_tz_log_stats(size_t count)
+{
+	static struct tzdbg_log_pos_v2_t log_start_v2 = {0};
+	static struct tzdbg_log_pos_t log_start = {0};
+	struct tzdbg_log_v2_t *log_v2_ptr;
+	struct tzdbg_log_t *log_ptr;
+
+	log_ptr = (struct tzdbg_log_t *)((unsigned char *)tzdbg.diag_buf +
+			tzdbg.diag_buf->ring_off -
+			offsetof(struct tzdbg_log_t, log_buf));
+
+	log_v2_ptr = (struct tzdbg_log_v2_t *)((unsigned char *)tzdbg.diag_buf +
+			tzdbg.diag_buf->ring_off -
+			offsetof(struct tzdbg_log_v2_t, log_buf));
+
+	if (!tzdbg.is_enlarged_buf)
+		return _disp_log_stats(log_ptr, &log_start,
+				tzdbg.diag_buf->ring_len, count, TZDBG_LOG);
+
+	return _disp_log_stats_v2(log_v2_ptr, &log_start_v2,
+			tzdbg.diag_buf->ring_len, count, TZDBG_LOG);
+}
+
+static int _disp_hyp_log_stats(size_t count)
+{
+	static struct hypdbg_log_pos_t log_start = {0};
+	uint8_t *log_ptr;
+	uint32_t log_len;
+
+	log_ptr = (uint8_t *)((unsigned char *)tzdbg.hyp_diag_buf +
+				tzdbg.hyp_diag_buf->ring_off);
+	log_len = tzdbg.hyp_debug_rw_buf_size - tzdbg.hyp_diag_buf->ring_off;
+
+	return __disp_hyp_log_stats(log_ptr, &log_start,
+			log_len, count, TZDBG_HYP_LOG);
+}
+
+static int _disp_rm_log_stats(size_t count)
+{
+	static struct rmdbg_log_pos_t log_start = { 0 };
+	struct rmdbg_log_hdr_t *p_log_hdr = NULL;
+	uint8_t *log_ptr = NULL;
+	uint32_t log_len = 0;
+	static bool wrap_around = { false };
+
+	/* Return 0 to close the display file,if there is nothing else to do */
+	if ((log_start.size == 0x0) && wrap_around) {
+		wrap_around = false;
+		return 0;
+	}
+	/* Copy RM log data to tzdbg diag buffer for the first time */
+	/* Initialize the tracking data structure */
+	if (tzdbg.rmlog_rw_buf_size != 0) {
+		if (!wrap_around) {
+			memcpy_fromio((void *)tzdbg.rm_diag_buf,
+					tzdbg.rmlog_virt_iobase,
+					tzdbg.rmlog_rw_buf_size);
+			/* get RM header info first */
+			p_log_hdr = (struct rmdbg_log_hdr_t *)tzdbg.rm_diag_buf;
+			/* Update RM log buffer index tracker and its size */
+			log_start.read_idx = 0x0;
+			log_start.size = p_log_hdr->size;
+		}
+		/* Update RM log buffer starting ptr */
+		log_ptr =
+			(uint8_t *) ((unsigned char *)tzdbg.rm_diag_buf +
+				 sizeof(struct rmdbg_log_hdr_t));
+	} else {
+	/* Return 0 to close the display file,if there is nothing else to do */
+		pr_err("There is no RM log to read, size is %d!\n",
+			tzdbg.rmlog_rw_buf_size);
+		return 0;
+	}
+	log_len = log_start.size;
+	log_ptr += log_start.read_idx;
+	/* Check if we exceed the max length provided by user space */
+	log_len = (count > log_len) ? log_len : count;
+	/* Update tracking data structure */
+	log_start.size -= log_len;
+	log_start.read_idx += log_len;
+
+	if (log_start.size)
+		wrap_around =  true;
+	return __disp_rm_log_stats(log_ptr, log_len);
+}
+
+static int _disp_qsee_log_stats(size_t count)
+{
+	static struct tzdbg_log_pos_t log_start = {0};
+	static struct tzdbg_log_pos_v2_t log_start_v2 = {0};
+
+	if (!tzdbg.is_enlarged_buf)
+		return _disp_log_stats(g_qsee_log, &log_start,
+			QSEE_LOG_BUF_SIZE - sizeof(struct tzdbg_log_pos_t),
+			count, TZDBG_QSEE_LOG);
+
+	return _disp_log_stats_v2(g_qsee_log_v2, &log_start_v2,
+		QSEE_LOG_BUF_SIZE_V2 - sizeof(struct tzdbg_log_pos_v2_t),
+		count, TZDBG_QSEE_LOG);
+}
+
+static int _disp_hyp_general_stats(size_t count)
+{
+	int len = 0;
+	int i;
+	struct hypdbg_boot_info_t *ptr = NULL;
+
+	len += scnprintf((unsigned char *)tzdbg.disp_buf + len,
+			tzdbg.hyp_debug_rw_buf_size - 1,
+			"   Magic Number    : 0x%x\n"
+			"   CPU Count       : 0x%x\n"
+			"   S2 Fault Counter: 0x%x\n",
+			tzdbg.hyp_diag_buf->magic_num,
+			tzdbg.hyp_diag_buf->cpu_count,
+			tzdbg.hyp_diag_buf->s2_fault_counter);
+
+	ptr = tzdbg.hyp_diag_buf->boot_info;
+	for (i = 0; i < tzdbg.hyp_diag_buf->cpu_count; i++) {
+		len += scnprintf((unsigned char *)tzdbg.disp_buf + len,
+				(tzdbg.hyp_debug_rw_buf_size - 1) - len,
+				"  CPU #: %d\n"
+				"     Warmboot entry CPU counter: 0x%x\n"
+				"     Warmboot exit CPU counter : 0x%x\n",
+				i, ptr->warm_entry_cnt, ptr->warm_exit_cnt);
+
+		if (len > (tzdbg.hyp_debug_rw_buf_size - 1)) {
+			pr_warn("%s: Cannot fit all info into the buffer\n",
+								__func__);
+			break;
+		}
+		ptr++;
+	}
+
+	tzdbg.stat[TZDBG_HYP_GENERAL].data = (char *)tzdbg.disp_buf;
+	return len;
+}
+
+#if IS_ENABLED(CONFIG_MSM_TMECOM_QMP)
+static int _disp_tme_log_stats(size_t count)
+{
+	static struct tme_log_pos log_start = { 0 };
+	static bool wrap_around = { false };
+	uint32_t buf_size;
+	uint8_t *log_ptr = NULL;
+	uint32_t log_len = 0;
+	int ret = 0;
+
+	/* Return 0 to close the display file */
+	if ((log_start.size == 0x0) && wrap_around) {
+		wrap_around = false;
+		return 0;
+	}
+
+	/* Copy TME log data to tzdbg diag buffer for the first time */
+	if (!wrap_around) {
+		if (tmelog_process_request(tmecrashdump_address_offset,
+								   TME_LOG_BUF_SIZE, &buf_size)) {
+			pr_err("Read tme log failed, ret=%d, buf_size: %#x\n", ret, buf_size);
+			return 0;
+		}
+		log_start.offset = 0x0;
+		log_start.size = buf_size;
+	}
+
+	log_ptr = tzdbg.tmelog_virt_iobase;
+	log_len = log_start.size;
+	log_ptr += log_start.offset;
+
+	/* Check if we exceed the max length provided by user space */
+	log_len = min(min((uint32_t)count, log_len), display_buf_size);
+
+	log_start.size -= log_len;
+	log_start.offset += log_len;
+	pr_debug("log_len: %d, log_start.offset: %#x, log_start.size: %#x\n",
+			log_len, log_start.offset, log_start.size);
+
+	if (log_start.size)
+		wrap_around =  true;
+
+	/* Copy TME log data to display buffer */
+	memcpy_fromio(tzdbg.disp_buf, log_ptr, log_len);
+
+	tzdbg.stat[TZDBG_TME_LOG].data = tzdbg.disp_buf;
+	return log_len;
+}
+#else
+static int _disp_tme_log_stats(size_t count)
+{
+	return 0;
+}
+#endif
+
+static ssize_t tzdbg_fs_read_unencrypted(int tz_id, char __user *buf,
+	size_t count, loff_t *offp)
+{
+	int len = 0;
+
+	if (tz_id == TZDBG_BOOT || tz_id == TZDBG_RESET ||
+		tz_id == TZDBG_INTERRUPT || tz_id == TZDBG_GENERAL ||
+		tz_id == TZDBG_VMID || tz_id == TZDBG_LOG)
+		memcpy_fromio((void *)tzdbg.diag_buf, tzdbg.virt_iobase,
+						debug_rw_buf_size);
+
+	if (tz_id == TZDBG_HYP_GENERAL || tz_id == TZDBG_HYP_LOG)
+		memcpy_fromio((void *)tzdbg.hyp_diag_buf,
+				tzdbg.hyp_virt_iobase,
+				tzdbg.hyp_debug_rw_buf_size);
+
+	switch (tz_id) {
+	case TZDBG_BOOT:
+		len = _disp_tz_boot_stats();
+		break;
+	case TZDBG_RESET:
+		len = _disp_tz_reset_stats();
+		break;
+	case TZDBG_INTERRUPT:
+		len = _disp_tz_interrupt_stats();
+		break;
+	case TZDBG_GENERAL:
+		len = _disp_tz_general_stats();
+		break;
+	case TZDBG_VMID:
+		len = _disp_tz_vmid_stats();
+		break;
+	case TZDBG_LOG:
+		if (TZBSP_DIAG_MAJOR_VERSION_LEGACY <
+				(tzdbg.diag_buf->version >> 16)) {
+			len = _disp_tz_log_stats(count);
+			*offp = 0;
+		} else {
+			len = _disp_tz_log_stats_legacy();
+		}
+		break;
+	case TZDBG_QSEE_LOG:
+		len = _disp_qsee_log_stats(count);
+		*offp = 0;
+		break;
+	case TZDBG_HYP_GENERAL:
+		len = _disp_hyp_general_stats(count);
+		break;
+	case TZDBG_HYP_LOG:
+		len = _disp_hyp_log_stats(count);
+		*offp = 0;
+		break;
+	case TZDBG_RM_LOG:
+		len = _disp_rm_log_stats(count);
+		*offp = 0;
+		break;
+	case TZDBG_TME_LOG:
+		len = _disp_tme_log_stats(count);
+		*offp = 0;
+		break;
+	default:
+		break;
+	}
+
+	if (len > count)
+		len = count;
+
+	return simple_read_from_buffer(buf, len, offp,
+				tzdbg.stat[tz_id].data, len);
+}
+
+static ssize_t tzdbg_fs_read_encrypted(int tz_id, char __user *buf,
+	size_t count, loff_t *offp)
+{
+	int len = 0, ret = 0;
+	struct tzdbg_stat *stat = &(tzdbg.stat[tz_id]);
+
+	pr_debug("%s: tz_id = %d\n", __func__, tz_id);
+
+	if (tz_id >= TZDBG_STATS_MAX) {
+		pr_err("invalid encrypted log id %d\n", tz_id);
+		return ret;
+	}
+
+	if (!stat->display_len) {
+		if (tz_id == TZDBG_QSEE_LOG)
+			stat->display_len = _disp_encrpted_log_stats(
+					&enc_qseelog_info,
+					tz_id, ENCRYPTED_QSEE_LOG_ID);
+		else
+			stat->display_len = _disp_encrpted_log_stats(
+					&enc_tzlog_info,
+					tz_id, ENCRYPTED_TZ_LOG_ID);
+		stat->display_offset = 0;
+	}
+	len = stat->display_len;
+	if (len > count)
+		len = count;
+
+	*offp = 0;
+	ret = simple_read_from_buffer(buf, len, offp,
+				tzdbg.stat[tz_id].data + stat->display_offset,
+				count);
+	stat->display_offset += ret;
+	stat->display_len -= ret;
+	pr_debug("ret = %d, offset = %d\n", ret, (int)(*offp));
+	pr_debug("display_len = %lu, offset = %lu\n",
+			stat->display_len, stat->display_offset);
+	return ret;
+}
+
+static ssize_t tzdbg_fs_read(struct file *file, char __user *buf,
+	size_t count, loff_t *offp)
+{
+	struct seq_file *seq = file->private_data;
+	int tz_id = TZDBG_STATS_MAX;
+
+	if (seq)
+		tz_id = *(int *)(seq->private);
+	else {
+		pr_err("%s: Seq data null unable to proceed\n", __func__);
+		return 0;
+	}
+
+	if (!tzdbg.is_encrypted_log_enabled ||
+	    (tz_id == TZDBG_HYP_GENERAL || tz_id == TZDBG_HYP_LOG)
+	    || tz_id == TZDBG_RM_LOG || tz_id == TZDBG_TME_LOG)
+		return tzdbg_fs_read_unencrypted(tz_id, buf, count, offp);
+	else
+		return tzdbg_fs_read_encrypted(tz_id, buf, count, offp);
+}
+
+static int tzdbg_procfs_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, NULL, pde_data(inode));
+}
+
+static int tzdbg_procfs_release(struct inode *inode, struct file *file)
+{
+	return single_release(inode, file);
+}
+
+const struct proc_ops tzdbg_fops = {
+	.proc_flags   = PROC_ENTRY_PERMANENT,
+	.proc_read    = tzdbg_fs_read,
+	.proc_open    = tzdbg_procfs_open,
+	.proc_release = tzdbg_procfs_release,
+};
+
+static int tzdbg_init_tme_log(struct platform_device *pdev, void __iomem *virt_iobase)
+{
+	/*
+	 * Tme logs are dumped in tme log ddr region but that region is not
+	 * accessible to hlos. Instead, collect logs at tme crashdump ddr
+	 * region with tmecom interface and then display logs reading from
+	 * crashdump region.
+	 */
+	if (of_property_read_u32((&pdev->dev)->of_node, "tmecrashdump-address-offset",
+				&tmecrashdump_address_offset)) {
+		pr_err("Tme Crashdump address offset need to be defined!\n");
+		return -EINVAL;
+	}
+
+	tzdbg.tmelog_virt_iobase =
+		devm_ioremap(&pdev->dev, tmecrashdump_address_offset, TME_LOG_BUF_SIZE);
+	if (!tzdbg.tmelog_virt_iobase) {
+		pr_err("ERROR: Could not ioremap: start=%#x, len=%u\n",
+				tmecrashdump_address_offset, TME_LOG_BUF_SIZE);
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+/*
+ * Allocates log buffer from ION, registers the buffer at TZ
+ */
+static int tzdbg_register_qsee_log_buf(struct platform_device *pdev)
+{
+	int ret = 0;
+	void *buf = NULL;
+	uint32_t ns_vmids[] = {QCOM_SCM_VMID_HLOS};
+	uint32_t ns_vm_perms[] = {QCOM_SCM_PERM_RW};
+	uint32_t ns_vm_nums = 1;
+
+	if (tzdbg.is_enlarged_buf) {
+		if (of_property_read_u32((&pdev->dev)->of_node,
+			"qseelog-buf-size-v2", &qseelog_buf_size)) {
+			pr_debug("Enlarged qseelog buf size isn't defined\n");
+			qseelog_buf_size = QSEE_LOG_BUF_SIZE_V2;
+		}
+	}  else {
+		qseelog_buf_size = QSEE_LOG_BUF_SIZE;
+	}
+	pr_debug("qseelog buf size is 0x%x\n", qseelog_buf_size);
+
+	buf = dma_alloc_coherent(&pdev->dev,
+			qseelog_buf_size, &coh_pmem, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	if (!tzdbg.is_encrypted_log_enabled) {
+		ret = qcom_tzmem_register(coh_pmem,
+			qseelog_buf_size, ns_vmids, ns_vm_perms, ns_vm_nums,
+			QCOM_SCM_PERM_RW,
+			&qseelog_shmbridge_handle);
+		if (ret) {
+			pr_err("failed to create bridge for qsee_log buf\n");
+			goto exit_free_mem;
+		}
+	}
+
+	g_qsee_log = (struct tzdbg_log_t *)buf;
+	g_qsee_log->log_pos.wrap = g_qsee_log->log_pos.offset = 0;
+
+	g_qsee_log_v2 = (struct tzdbg_log_v2_t *)buf;
+	g_qsee_log_v2->log_pos.wrap = g_qsee_log_v2->log_pos.offset = 0;
+
+	ret = qcom_scm_register_qsee_log_buf(coh_pmem, qseelog_buf_size);
+	if (ret) {
+		pr_err(
+		"%s: scm_call to register log buf failed, resp result =%d\n",
+		__func__, ret);
+		goto exit_dereg_bridge;
+	}
+
+	return ret;
+
+exit_dereg_bridge:
+	if (!tzdbg.is_encrypted_log_enabled)
+		qcom_tzmem_deregister(qseelog_shmbridge_handle);
+exit_free_mem:
+	dma_free_coherent(&pdev->dev, qseelog_buf_size,
+			(void *)g_qsee_log, coh_pmem);
+	return ret;
+}
+
+static void tzdbg_free_qsee_log_buf(struct platform_device *pdev)
+{
+	if (!tzdbg.is_encrypted_log_enabled)
+		qcom_tzmem_deregister(qseelog_shmbridge_handle);
+	dma_free_coherent(&pdev->dev, qseelog_buf_size,
+				(void *)g_qsee_log, coh_pmem);
+}
+
+static int tzdbg_allocate_encrypted_log_buf(struct platform_device *pdev)
+{
+	int ret = 0;
+	uint32_t ns_vmids[] = {QCOM_SCM_VMID_HLOS};
+	uint32_t ns_vm_perms[] = {QCOM_SCM_PERM_RW};
+	uint32_t ns_vm_nums = 1;
+
+	if (!tzdbg.is_encrypted_log_enabled)
+		return 0;
+
+	/* max encrypted qsee log buf zize (include header, and page align) */
+	enc_qseelog_info.size = qseelog_buf_size + PAGE_SIZE;
+
+	enc_qseelog_info.vaddr = dma_alloc_coherent(&pdev->dev,
+					enc_qseelog_info.size,
+					&enc_qseelog_info.paddr, GFP_KERNEL);
+	if (enc_qseelog_info.vaddr == NULL)
+		return -ENOMEM;
+
+	ret = qcom_tzmem_register(enc_qseelog_info.paddr,
+			enc_qseelog_info.size, ns_vmids,
+			ns_vm_perms, ns_vm_nums,
+			QCOM_SCM_PERM_RW, &enc_qseelog_info.shmb_handle);
+	if (ret) {
+		pr_err("failed to create encr_qsee_log bridge, ret %d\n", ret);
+		goto exit_free_qseelog;
+	}
+	pr_debug("Alloc memory for encr_qsee_log, size = %zu\n",
+			enc_qseelog_info.size);
+
+	enc_tzlog_info.size = debug_rw_buf_size;
+	enc_tzlog_info.vaddr = dma_alloc_coherent(&pdev->dev,
+					enc_tzlog_info.size,
+					&enc_tzlog_info.paddr, GFP_KERNEL);
+	if (enc_tzlog_info.vaddr == NULL)
+		goto exit_unreg_qseelog;
+
+	ret = qcom_tzmem_register(enc_tzlog_info.paddr,
+			enc_tzlog_info.size, ns_vmids, ns_vm_perms, ns_vm_nums,
+			QCOM_SCM_PERM_RW, &enc_tzlog_info.shmb_handle);
+	if (ret) {
+		pr_err("failed to create encr_tz_log bridge, ret = %d\n", ret);
+		goto exit_free_tzlog;
+	}
+	pr_debug("Alloc memory for encr_tz_log, size %zu\n",
+		enc_qseelog_info.size);
+
+	return 0;
+
+exit_free_tzlog:
+	dma_free_coherent(&pdev->dev, enc_tzlog_info.size,
+			enc_tzlog_info.vaddr, enc_tzlog_info.paddr);
+exit_unreg_qseelog:
+	qcom_tzmem_deregister(enc_qseelog_info.shmb_handle);
+exit_free_qseelog:
+	dma_free_coherent(&pdev->dev, enc_qseelog_info.size,
+			enc_qseelog_info.vaddr, enc_qseelog_info.paddr);
+	return -ENOMEM;
+}
+
+static void tzdbg_free_encrypted_log_buf(struct platform_device *pdev)
+{
+	qcom_tzmem_deregister(enc_tzlog_info.shmb_handle);
+	dma_free_coherent(&pdev->dev, enc_tzlog_info.size,
+			enc_tzlog_info.vaddr, enc_tzlog_info.paddr);
+	qcom_tzmem_deregister(enc_qseelog_info.shmb_handle);
+	dma_free_coherent(&pdev->dev, enc_qseelog_info.size,
+			enc_qseelog_info.vaddr, enc_qseelog_info.paddr);
+}
+
+static int  tzdbg_fs_init(struct platform_device *pdev)
+{
+	int rc = 0;
+	int i;
+	struct proc_dir_entry *dent_dir;
+	struct proc_dir_entry *dent;
+
+	dent_dir = proc_mkdir(TZDBG_DIR_NAME, NULL);
+	if (dent_dir == NULL) {
+		dev_err(&pdev->dev, "tzdbg proc_mkdir failed\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < TZDBG_STATS_MAX; i++) {
+		tzdbg.debug_tz[i] = i;
+		if (!tzdbg.stat[i].avail)
+			continue;
+
+		dent = proc_create_data(tzdbg.stat[i].name,
+				0444, dent_dir,
+				&tzdbg_fops, &tzdbg.debug_tz[i]);
+		if (dent == NULL) {
+			dev_err(&pdev->dev, "TZ proc_create_data failed\n");
+			rc = -ENOMEM;
+			goto err;
+		}
+	}
+	platform_set_drvdata(pdev, dent_dir);
+	return 0;
+err:
+	remove_proc_subtree(TZDBG_DIR_NAME, NULL);
+
+	return rc;
+}
+
+static void tzdbg_fs_exit(struct platform_device *pdev)
+{
+	struct proc_dir_entry *dent_dir;
+
+	dent_dir = platform_get_drvdata(pdev);
+	if (dent_dir)
+		remove_proc_subtree(TZDBG_DIR_NAME, NULL);
+}
+
+static int __update_hypdbg_base(struct platform_device *pdev,
+			void __iomem *virt_iobase)
+{
+	phys_addr_t hypdiag_phy_iobase;
+	uint32_t hyp_address_offset;
+	uint32_t hyp_size_offset;
+	struct hypdbg_t *hyp;
+	uint32_t *ptr = NULL;
+
+	if (of_property_read_u32((&pdev->dev)->of_node, "hyplog-address-offset",
+							&hyp_address_offset)) {
+		dev_err(&pdev->dev, "hyplog address offset is not defined\n");
+		return -EINVAL;
+	}
+	if (of_property_read_u32((&pdev->dev)->of_node, "hyplog-size-offset",
+							&hyp_size_offset)) {
+		dev_err(&pdev->dev, "hyplog size offset is not defined\n");
+		return -EINVAL;
+	}
+
+	hypdiag_phy_iobase = readl_relaxed(virt_iobase + hyp_address_offset);
+	tzdbg.hyp_debug_rw_buf_size = readl_relaxed(virt_iobase +
+					hyp_size_offset);
+
+	tzdbg.hyp_virt_iobase = devm_ioremap(&pdev->dev,
+					hypdiag_phy_iobase,
+					tzdbg.hyp_debug_rw_buf_size);
+	if (!tzdbg.hyp_virt_iobase) {
+		dev_err(&pdev->dev, "ERROR could not ioremap: start=%pr, len=%u\n",
+			&hypdiag_phy_iobase, tzdbg.hyp_debug_rw_buf_size);
+		return -ENXIO;
+	}
+
+	ptr = kzalloc(tzdbg.hyp_debug_rw_buf_size, GFP_KERNEL);
+	if (!ptr)
+		return -ENOMEM;
+
+	tzdbg.hyp_diag_buf = (struct hypdbg_t *)ptr;
+	hyp = tzdbg.hyp_diag_buf;
+	hyp->log_pos.wrap = hyp->log_pos.offset = 0;
+	return 0;
+}
+
+static int __update_rmlog_base(struct platform_device *pdev,
+			       void __iomem *virt_iobase)
+{
+	uint32_t rmlog_address;
+	uint32_t rmlog_size;
+	uint32_t *ptr = NULL;
+
+	/* if we don't get the node just ignore it */
+	if (of_property_read_u32((&pdev->dev)->of_node, "rmlog-address",
+							&rmlog_address)) {
+		dev_err(&pdev->dev, "RM log address is not defined\n");
+		tzdbg.rmlog_rw_buf_size = 0;
+		return 0;
+	}
+	/* if we don't get the node just ignore it */
+	if (of_property_read_u32((&pdev->dev)->of_node, "rmlog-size",
+							&rmlog_size)) {
+		dev_err(&pdev->dev, "RM log size is not defined\n");
+		tzdbg.rmlog_rw_buf_size = 0;
+		return 0;
+	}
+
+	tzdbg.rmlog_rw_buf_size = rmlog_size;
+
+	/* Check if there is RM log to read */
+	if (!tzdbg.rmlog_rw_buf_size) {
+		tzdbg.rmlog_virt_iobase = NULL;
+		tzdbg.rm_diag_buf = NULL;
+		dev_err(&pdev->dev, "RM log size is %d\n",
+			tzdbg.rmlog_rw_buf_size);
+		return 0;
+	}
+
+	tzdbg.rmlog_virt_iobase = devm_ioremap(&pdev->dev,
+					rmlog_address,
+					rmlog_size);
+	if (!tzdbg.rmlog_virt_iobase) {
+		dev_err(&pdev->dev, "ERROR could not ioremap: start=%u, len=%u\n",
+			rmlog_address, tzdbg.rmlog_rw_buf_size);
+		return -ENXIO;
+	}
+
+	ptr = kzalloc(tzdbg.rmlog_rw_buf_size, GFP_KERNEL);
+	if (!ptr)
+		return -ENOMEM;
+
+	tzdbg.rm_diag_buf = (uint8_t *)ptr;
+	return 0;
+}
+static int tzdbg_get_tz_version(void)
+{
+	u64 version;
+	int ret = 0;
+
+	ret = qcom_scm_get_tz_log_feat_id(&version);
+
+	if (ret) {
+		pr_err("%s: scm_call to get tz version failed\n",
+				__func__);
+		return ret;
+	}
+	tzdbg.tz_version = version;
+
+	ret = qcom_scm_get_tz_feat_id_version(QCOM_SCM_FEAT_DIAG_ID, &version);
+	if (ret) {
+		pr_err("%s: scm_call to get tz diag version failed, ret = %d\n",
+				__func__, ret);
+		return ret;
+	}
+	pr_warn("tz diag version is %llu\n", version);
+	tzdbg.tz_diag_major_version =
+		((version >> TZBSP_FVER_MAJOR_SHIFT) & TZBSP_FVER_MAJOR_MINOR_MASK);
+	tzdbg.tz_diag_minor_version =
+		((version >> TZBSP_FVER_MINOR_SHIFT) & TZBSP_FVER_MAJOR_MINOR_MASK);
+	if (tzdbg.tz_diag_major_version == TZBSP_DIAG_MAJOR_VERSION_V9) {
+		switch (tzdbg.tz_diag_minor_version) {
+		case TZBSP_DIAG_MINOR_VERSION_V2:
+		case TZBSP_DIAG_MINOR_VERSION_V21:
+		case TZBSP_DIAG_MINOR_VERSION_V22:
+			tzdbg.is_enlarged_buf = true;
+			break;
+		default:
+			tzdbg.is_enlarged_buf = false;
+		}
+	} else {
+		tzdbg.is_enlarged_buf = false;
+	}
+	return ret;
+}
+
+static void tzdbg_query_encrypted_log(void)
+{
+	int ret = 0;
+	uint64_t enabled;
+
+	ret = qcom_scm_query_encrypted_log_feature(&enabled);
+	if (ret) {
+		if (ret == -EIO)
+			pr_info("SCM_CALL : SYS CALL NOT SUPPORTED IN TZ\n");
+		else
+			pr_err("scm_call QUERY_ENCR_LOG_FEATURE failed ret %d\n", ret);
+		tzdbg.is_encrypted_log_enabled = false;
+	} else {
+		pr_warn("encrypted qseelog enabled is %llu\n", enabled);
+		tzdbg.is_encrypted_log_enabled = enabled;
+	}
+}
+
+/*
+ * Driver functions
+ */
+static int tz_log_probe(struct platform_device *pdev)
+{
+	struct resource *resource;
+	void __iomem *virt_iobase;
+	phys_addr_t tzdiag_phy_iobase;
+	uint32_t *ptr = NULL;
+	int ret = 0, i;
+
+	/* Defer if qcom_scm is not available */
+	if (!qcom_scm_is_available())
+		return dev_err_probe(&pdev->dev, -EPROBE_DEFER, "qcom_scm is not up!\n");
+
+	/*
+	 * By default all nodes will be created.
+	 * Mark avail as false later selectively if there's need to skip proc node creation.
+	 */
+	for (i = 0; i < TZDBG_STATS_MAX; i++)
+		tzdbg.stat[i].avail = true;
+
+	ret = tzdbg_get_tz_version();
+	if (ret)
+		return ret;
+
+	/*
+	 * Get address that stores the physical location diagnostic data
+	 */
+	resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!resource) {
+		dev_err(&pdev->dev,
+				"%s: ERROR Missing MEM resource\n", __func__);
+		return -ENXIO;
+	}
+
+	/*
+	 * Get the debug buffer size
+	 */
+	debug_rw_buf_size = resource_size(resource);
+
+	/*
+	 * Map address that stores the physical location diagnostic data
+	 */
+	virt_iobase = devm_ioremap(&pdev->dev, resource->start,
+				debug_rw_buf_size);
+	if (!virt_iobase) {
+		dev_err(&pdev->dev,
+			"%s: ERROR could not ioremap: start=%pr, len=%u\n",
+			__func__, &resource->start,
+			(unsigned int)(debug_rw_buf_size));
+		return -ENXIO;
+	}
+
+	if (pdev->dev.of_node) {
+		tzdbg.is_hyplog_enabled = of_property_read_bool(
+			(&pdev->dev)->of_node, "qcom,hyplog-enabled");
+		if (tzdbg.is_hyplog_enabled) {
+			ret = __update_hypdbg_base(pdev, virt_iobase);
+			if (ret) {
+				dev_err(&pdev->dev,
+					"%s: fail to get hypdbg_base ret %d\n",
+					__func__, ret);
+				return -EINVAL;
+			}
+			ret = __update_rmlog_base(pdev, virt_iobase);
+			if (ret) {
+				dev_err(&pdev->dev,
+					"%s: fail to get rmlog_base ret %d\n",
+					__func__, ret);
+				return -EINVAL;
+			}
+		} else {
+			tzdbg.stat[TZDBG_HYP_LOG].avail = false;
+			tzdbg.stat[TZDBG_HYP_GENERAL].avail = false;
+			tzdbg.stat[TZDBG_RM_LOG].avail = false;
+			dev_info(&pdev->dev, "Hyp log service not support\n");
+		}
+	} else {
+		dev_dbg(&pdev->dev, "Device tree data is not found\n");
+	}
+
+	/*
+	 * Retrieve the address of diagnostic data
+	 */
+	tzdiag_phy_iobase = readl_relaxed(virt_iobase);
+
+	tzdbg_query_encrypted_log();
+	/*
+	 * Map the diagnostic information area if encryption is disabled
+	 */
+	if (!tzdbg.is_encrypted_log_enabled) {
+		tzdbg.virt_iobase = devm_ioremap(&pdev->dev,
+				tzdiag_phy_iobase, debug_rw_buf_size);
+
+		if (!tzdbg.virt_iobase) {
+			dev_err(&pdev->dev,
+				"%s: could not ioremap: start=%pr, len=%u\n",
+				__func__, &tzdiag_phy_iobase,
+				debug_rw_buf_size);
+			return -ENXIO;
+		}
+		/* allocate diag_buf */
+		ptr = kzalloc(debug_rw_buf_size, GFP_KERNEL);
+		if (ptr == NULL)
+			return -ENOMEM;
+		tzdbg.diag_buf = (struct tzdbg_t *)ptr;
+	} else {
+		if ((tzdbg.tz_diag_major_version == TZBSP_DIAG_MAJOR_VERSION_V9) &&
+			(tzdbg.tz_diag_minor_version >= TZBSP_DIAG_MINOR_VERSION_V22))
+			tzdbg.is_full_encrypted_tz_logs_supported = true;
+		if (pdev->dev.of_node) {
+			tzdbg.is_full_encrypted_tz_logs_enabled = of_property_read_bool(
+				(&pdev->dev)->of_node, "qcom,full-encrypted-tz-logs-enabled");
+		}
+	}
+
+	/* Init for tme log */
+	ret = tzdbg_init_tme_log(pdev, virt_iobase);
+	if (ret < 0) {
+		tzdbg.stat[TZDBG_TME_LOG].avail = false;
+		pr_warn("Tme log initialization failed!\n");
+	}
+
+	/* register unencrypted qsee log buffer */
+	ret = tzdbg_register_qsee_log_buf(pdev);
+	if (ret)
+		goto exit_free_diag_buf;
+
+	/* allocate encrypted qsee and tz log buffer */
+	ret = tzdbg_allocate_encrypted_log_buf(pdev);
+	if (ret) {
+		dev_err(&pdev->dev,
+			" %s: Failed to allocate encrypted log buffer\n",
+			__func__);
+		goto exit_free_qsee_log_buf;
+	}
+
+	/* allocate display_buf */
+	if (UINT_MAX/4 < qseelog_buf_size) {
+		pr_err("display_buf_size integer overflow\n");
+		goto exit_free_qsee_log_buf;
+	}
+	display_buf_size = qseelog_buf_size * 4;
+	tzdbg.disp_buf = dma_alloc_coherent(&pdev->dev, display_buf_size,
+		&disp_buf_paddr, GFP_KERNEL);
+	if (tzdbg.disp_buf == NULL) {
+		ret = -ENOMEM;
+		goto exit_free_encr_log_buf;
+	}
+
+	if (tzdbg_fs_init(pdev))
+		goto exit_free_disp_buf;
+	return 0;
+
+exit_free_disp_buf:
+	dma_free_coherent(&pdev->dev, display_buf_size,
+			(void *)tzdbg.disp_buf, disp_buf_paddr);
+exit_free_encr_log_buf:
+	tzdbg_free_encrypted_log_buf(pdev);
+exit_free_qsee_log_buf:
+	tzdbg_free_qsee_log_buf(pdev);
+exit_free_diag_buf:
+	if (!tzdbg.is_encrypted_log_enabled)
+		kfree(tzdbg.diag_buf);
+	return -ENXIO;
+}
+
+static int tz_log_remove(struct platform_device *pdev)
+{
+	tzdbg_fs_exit(pdev);
+	dma_free_coherent(&pdev->dev, display_buf_size,
+			(void *)tzdbg.disp_buf, disp_buf_paddr);
+	tzdbg_free_encrypted_log_buf(pdev);
+	tzdbg_free_qsee_log_buf(pdev);
+	if (!tzdbg.is_encrypted_log_enabled)
+		kfree(tzdbg.diag_buf);
+	return 0;
+}
+
+static const struct of_device_id tzlog_match[] = {
+	{.compatible = "qcom,tz-log"},
+	{}
+};
+
+static struct platform_driver tz_log_driver = {
+	.probe		= tz_log_probe,
+	.remove		= tz_log_remove,
+	.driver		= {
+		.name = "tz_log",
+		.of_match_table = tzlog_match,
+		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
+	},
+};
+
+module_platform_driver(tz_log_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TZ Log driver");
--- linux-qcom-6.8.0.orig/drivers/firmware/raspberrypi.c
+++ linux-qcom-6.8.0/drivers/firmware/raspberrypi.c
@@ -9,6 +9,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/kref.h>
 #include <linux/mailbox_client.h>
+#include <linux/mailbox_controller.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_platform.h>
@@ -97,8 +98,8 @@
 	if (size & 3)
 		return -EINVAL;
 
-	buf = dma_alloc_coherent(fw->cl.dev, PAGE_ALIGN(size), &bus_addr,
-				 GFP_ATOMIC);
+	buf = dma_alloc_coherent(fw->chan->mbox->dev, PAGE_ALIGN(size),
+				 &bus_addr, GFP_ATOMIC);
 	if (!buf)
 		return -ENOMEM;
 
@@ -126,7 +127,7 @@
 		ret = -EINVAL;
 	}
 
-	dma_free_coherent(fw->cl.dev, PAGE_ALIGN(size), buf, bus_addr);
+	dma_free_coherent(fw->chan->mbox->dev, PAGE_ALIGN(size), buf, bus_addr);
 
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/firmware/smccc/smccc.c
+++ linux-qcom-6.8.0/drivers/firmware/smccc/smccc.c
@@ -16,7 +16,6 @@
 static enum arm_smccc_conduit smccc_conduit = SMCCC_CONDUIT_NONE;
 
 bool __ro_after_init smccc_trng_available = false;
-u64 __ro_after_init smccc_has_sve_hint = false;
 s32 __ro_after_init smccc_soc_id_version = SMCCC_RET_NOT_SUPPORTED;
 s32 __ro_after_init smccc_soc_id_revision = SMCCC_RET_NOT_SUPPORTED;
 
@@ -28,9 +27,6 @@
 	smccc_conduit = conduit;
 
 	smccc_trng_available = smccc_probe_trng();
-	if (IS_ENABLED(CONFIG_ARM64_SVE) &&
-	    smccc_version >= ARM_SMCCC_VERSION_1_3)
-		smccc_has_sve_hint = true;
 
 	if ((smccc_version >= ARM_SMCCC_VERSION_1_2) &&
 	    (smccc_conduit != SMCCC_CONDUIT_NONE)) {
--- linux-qcom-6.8.0.orig/drivers/firmware/sysfb.c
+++ linux-qcom-6.8.0/drivers/firmware/sysfb.c
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
+#include <linux/pci.h>
 #include <linux/platform_data/simplefb.h>
 #include <linux/platform_device.h>
 #include <linux/screen_info.h>
@@ -38,6 +39,8 @@
 static DEFINE_MUTEX(disable_lock);
 static bool disabled;
 
+static struct device *sysfb_parent_dev(const struct screen_info *si);
+
 static bool sysfb_unregister(void)
 {
 	if (IS_ERR_OR_NULL(pd))
@@ -51,6 +54,7 @@
 
 /**
  * sysfb_disable() - disable the Generic System Framebuffers support
+ * @dev:	the device to check if non-NULL
  *
  * This disables the registration of system framebuffer devices that match the
  * generic drivers that make use of the system framebuffer set up by firmware.
@@ -60,33 +64,85 @@
  * Context: The function can sleep. A @disable_lock mutex is acquired to serialize
  *          against sysfb_init(), that registers a system framebuffer device.
  */
-void sysfb_disable(void)
+void sysfb_disable(struct device *dev)
 {
+	struct screen_info *si = &screen_info;
+	struct device *parent;
+
 	mutex_lock(&disable_lock);
-	sysfb_unregister();
-	disabled = true;
+	parent = sysfb_parent_dev(si);
+	if (!dev || !parent || dev == parent) {
+		sysfb_unregister();
+		disabled = true;
+	}
 	mutex_unlock(&disable_lock);
 }
 EXPORT_SYMBOL_GPL(sysfb_disable);
 
+#if defined(CONFIG_PCI)
+static bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
+{
+	/*
+	 * TODO: Try to integrate this code into the PCI subsystem
+	 */
+	int ret;
+	u16 command;
+
+	ret = pci_read_config_word(pdev, PCI_COMMAND, &command);
+	if (ret != PCIBIOS_SUCCESSFUL)
+		return false;
+	if (!(command & PCI_COMMAND_MEMORY))
+		return false;
+	return true;
+}
+#else
+static bool sysfb_pci_dev_is_enabled(struct pci_dev *pdev)
+{
+	return false;
+}
+#endif
+
+static struct device *sysfb_parent_dev(const struct screen_info *si)
+{
+	struct pci_dev *pdev;
+
+	pdev = screen_info_pci_dev(si);
+	if (IS_ERR(pdev)) {
+		return ERR_CAST(pdev);
+	} else if (pdev) {
+		if (!sysfb_pci_dev_is_enabled(pdev))
+			return ERR_PTR(-ENODEV);
+		return &pdev->dev;
+	}
+
+	return NULL;
+}
+
 static __init int sysfb_init(void)
 {
 	struct screen_info *si = &screen_info;
+	struct device *parent;
 	struct simplefb_platform_data mode;
 	const char *name;
 	bool compatible;
 	int ret = 0;
 
+	screen_info_apply_fixups();
+
 	mutex_lock(&disable_lock);
 	if (disabled)
 		goto unlock_mutex;
 
 	sysfb_apply_efi_quirks();
 
+	parent = sysfb_parent_dev(si);
+	if (IS_ERR(parent))
+		goto unlock_mutex;
+
 	/* try to create a simple-framebuffer device */
 	compatible = sysfb_parse_mode(si, &mode);
 	if (compatible) {
-		pd = sysfb_create_simplefb(si, &mode);
+		pd = sysfb_create_simplefb(si, &mode, parent);
 		if (!IS_ERR(pd))
 			goto unlock_mutex;
 	}
@@ -109,6 +165,8 @@
 		goto unlock_mutex;
 	}
 
+	pd->dev.parent = parent;
+
 	sysfb_set_efifb_fwnode(pd);
 
 	ret = platform_device_add_data(pd, si, sizeof(*si));
--- linux-qcom-6.8.0.orig/drivers/firmware/sysfb_simplefb.c
+++ linux-qcom-6.8.0/drivers/firmware/sysfb_simplefb.c
@@ -91,7 +91,8 @@
 }
 
 __init struct platform_device *sysfb_create_simplefb(const struct screen_info *si,
-						     const struct simplefb_platform_data *mode)
+						     const struct simplefb_platform_data *mode,
+						     struct device *parent)
 {
 	struct platform_device *pd;
 	struct resource res;
@@ -143,6 +144,8 @@
 	if (!pd)
 		return ERR_PTR(-ENOMEM);
 
+	pd->dev.parent = parent;
+
 	sysfb_set_efifb_fwnode(pd);
 
 	ret = platform_device_add_resources(pd, &res, 1);
--- linux-qcom-6.8.0.orig/drivers/firmware/tegra/bpmp-debugfs.c
+++ linux-qcom-6.8.0/drivers/firmware/tegra/bpmp-debugfs.c
@@ -77,7 +77,7 @@
 
 	root_path_buf = kzalloc(root_path_buf_len, GFP_KERNEL);
 	if (!root_path_buf)
-		goto out;
+		return NULL;
 
 	root_path = dentry_path(bpmp->debugfs_mirror, root_path_buf,
 				root_path_buf_len);
--- linux-qcom-6.8.0.orig/drivers/firmware/tegra/bpmp.c
+++ linux-qcom-6.8.0/drivers/firmware/tegra/bpmp.c
@@ -24,12 +24,6 @@
 #define MSG_RING	BIT(1)
 #define TAG_SZ		32
 
-static inline struct tegra_bpmp *
-mbox_client_to_bpmp(struct mbox_client *client)
-{
-	return container_of(client, struct tegra_bpmp, mbox.client);
-}
-
 static inline const struct tegra_bpmp_ops *
 channel_to_ops(struct tegra_bpmp_channel *channel)
 {
--- linux-qcom-6.8.0.orig/drivers/firmware/turris-mox-rwtm.c
+++ linux-qcom-6.8.0/drivers/firmware/turris-mox-rwtm.c
@@ -2,7 +2,7 @@
 /*
  * Turris Mox rWTM firmware driver
  *
- * Copyright (C) 2019 Marek Behún <kabel@kernel.org>
+ * Copyright (C) 2019, 2024 Marek Behún <kabel@kernel.org>
  */
 
 #include <linux/armada-37xx-rwtm-mailbox.h>
@@ -174,6 +174,9 @@
 	struct mox_rwtm *rwtm = dev_get_drvdata(cl->dev);
 	struct armada_37xx_rwtm_rx_msg *msg = data;
 
+	if (completion_done(&rwtm->cmd_done))
+		return;
+
 	rwtm->reply = *msg;
 	complete(&rwtm->cmd_done);
 }
@@ -199,9 +202,8 @@
 	if (ret < 0)
 		return ret;
 
-	ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2);
-	if (ret < 0)
-		return ret;
+	if (!wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2))
+		return -ETIMEDOUT;
 
 	ret = mox_get_status(MBOX_CMD_BOARD_INFO, reply->retval);
 	if (ret == -ENODATA) {
@@ -235,9 +237,8 @@
 	if (ret < 0)
 		return ret;
 
-	ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2);
-	if (ret < 0)
-		return ret;
+	if (!wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2))
+		return -ETIMEDOUT;
 
 	ret = mox_get_status(MBOX_CMD_ECDSA_PUB_KEY, reply->retval);
 	if (ret == -ENODATA) {
@@ -274,9 +275,8 @@
 	if (ret < 0)
 		return ret;
 
-	ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2);
-	if (ret < 0)
-		return ret;
+	if (!wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2))
+		return -ETIMEDOUT;
 
 	return mox_get_status(MBOX_CMD_GET_RANDOM, rwtm->reply.retval);
 }
@@ -499,6 +499,7 @@
 	platform_set_drvdata(pdev, rwtm);
 
 	mutex_init(&rwtm->busy);
+	init_completion(&rwtm->cmd_done);
 
 	rwtm->mbox_client.dev = dev;
 	rwtm->mbox_client.rx_callback = mox_rwtm_rx_callback;
@@ -512,8 +513,6 @@
 		goto remove_files;
 	}
 
-	init_completion(&rwtm->cmd_done);
-
 	ret = mox_get_board_info(rwtm);
 	if (ret < 0)
 		dev_warn(dev, "Cannot read board information: %i\n", ret);
--- linux-qcom-6.8.0.orig/drivers/fpga/dfl-pci.c
+++ linux-qcom-6.8.0/drivers/fpga/dfl-pci.c
@@ -78,6 +78,7 @@
 #define PCIE_DEVICE_ID_SILICOM_PAC_N5011	0x1001
 #define PCIE_DEVICE_ID_INTEL_DFL		0xbcce
 /* PCI Subdevice ID for PCIE_DEVICE_ID_INTEL_DFL */
+#define PCIE_SUBDEVICE_ID_INTEL_D5005		0x138d
 #define PCIE_SUBDEVICE_ID_INTEL_N6000		0x1770
 #define PCIE_SUBDEVICE_ID_INTEL_N6001		0x1771
 #define PCIE_SUBDEVICE_ID_INTEL_C6100		0x17d4
@@ -102,6 +103,8 @@
 	{PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5010),},
 	{PCI_DEVICE(PCI_VENDOR_ID_SILICOM_DENMARK, PCIE_DEVICE_ID_SILICOM_PAC_N5011),},
 	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL,
+			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_D5005),},
+	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL,
 			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6000),},
 	{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, PCIE_DEVICE_ID_INTEL_DFL_VF,
 			PCI_VENDOR_ID_INTEL, PCIE_SUBDEVICE_ID_INTEL_N6000),},
--- linux-qcom-6.8.0.orig/drivers/fpga/fpga-bridge.c
+++ linux-qcom-6.8.0/drivers/fpga/fpga-bridge.c
@@ -55,33 +55,26 @@
 }
 EXPORT_SYMBOL_GPL(fpga_bridge_disable);
 
-static struct fpga_bridge *__fpga_bridge_get(struct device *dev,
+static struct fpga_bridge *__fpga_bridge_get(struct device *bridge_dev,
 					     struct fpga_image_info *info)
 {
 	struct fpga_bridge *bridge;
-	int ret = -ENODEV;
 
-	bridge = to_fpga_bridge(dev);
+	bridge = to_fpga_bridge(bridge_dev);
 
 	bridge->info = info;
 
-	if (!mutex_trylock(&bridge->mutex)) {
-		ret = -EBUSY;
-		goto err_dev;
-	}
+	if (!mutex_trylock(&bridge->mutex))
+		return ERR_PTR(-EBUSY);
 
-	if (!try_module_get(dev->parent->driver->owner))
-		goto err_ll_mod;
+	if (!try_module_get(bridge->br_ops_owner)) {
+		mutex_unlock(&bridge->mutex);
+		return ERR_PTR(-ENODEV);
+	}
 
 	dev_dbg(&bridge->dev, "get\n");
 
 	return bridge;
-
-err_ll_mod:
-	mutex_unlock(&bridge->mutex);
-err_dev:
-	put_device(dev);
-	return ERR_PTR(ret);
 }
 
 /**
@@ -98,13 +91,18 @@
 struct fpga_bridge *of_fpga_bridge_get(struct device_node *np,
 				       struct fpga_image_info *info)
 {
-	struct device *dev;
+	struct fpga_bridge *bridge;
+	struct device *bridge_dev;
 
-	dev = class_find_device_by_of_node(&fpga_bridge_class, np);
-	if (!dev)
+	bridge_dev = class_find_device_by_of_node(&fpga_bridge_class, np);
+	if (!bridge_dev)
 		return ERR_PTR(-ENODEV);
 
-	return __fpga_bridge_get(dev, info);
+	bridge = __fpga_bridge_get(bridge_dev, info);
+	if (IS_ERR(bridge))
+		put_device(bridge_dev);
+
+	return bridge;
 }
 EXPORT_SYMBOL_GPL(of_fpga_bridge_get);
 
@@ -125,6 +123,7 @@
 struct fpga_bridge *fpga_bridge_get(struct device *dev,
 				    struct fpga_image_info *info)
 {
+	struct fpga_bridge *bridge;
 	struct device *bridge_dev;
 
 	bridge_dev = class_find_device(&fpga_bridge_class, NULL, dev,
@@ -132,7 +131,11 @@
 	if (!bridge_dev)
 		return ERR_PTR(-ENODEV);
 
-	return __fpga_bridge_get(bridge_dev, info);
+	bridge = __fpga_bridge_get(bridge_dev, info);
+	if (IS_ERR(bridge))
+		put_device(bridge_dev);
+
+	return bridge;
 }
 EXPORT_SYMBOL_GPL(fpga_bridge_get);
 
@@ -146,7 +149,7 @@
 	dev_dbg(&bridge->dev, "put\n");
 
 	bridge->info = NULL;
-	module_put(bridge->dev.parent->driver->owner);
+	module_put(bridge->br_ops_owner);
 	mutex_unlock(&bridge->mutex);
 	put_device(&bridge->dev);
 }
@@ -316,18 +319,19 @@
 ATTRIBUTE_GROUPS(fpga_bridge);
 
 /**
- * fpga_bridge_register - create and register an FPGA Bridge device
+ * __fpga_bridge_register - create and register an FPGA Bridge device
  * @parent:	FPGA bridge device from pdev
  * @name:	FPGA bridge name
  * @br_ops:	pointer to structure of fpga bridge ops
  * @priv:	FPGA bridge private data
+ * @owner:	owner module containing the br_ops
  *
  * Return: struct fpga_bridge pointer or ERR_PTR()
  */
 struct fpga_bridge *
-fpga_bridge_register(struct device *parent, const char *name,
-		     const struct fpga_bridge_ops *br_ops,
-		     void *priv)
+__fpga_bridge_register(struct device *parent, const char *name,
+		       const struct fpga_bridge_ops *br_ops,
+		       void *priv, struct module *owner)
 {
 	struct fpga_bridge *bridge;
 	int id, ret;
@@ -357,6 +361,7 @@
 
 	bridge->name = name;
 	bridge->br_ops = br_ops;
+	bridge->br_ops_owner = owner;
 	bridge->priv = priv;
 
 	bridge->dev.groups = br_ops->groups;
@@ -386,7 +391,7 @@
 
 	return ERR_PTR(ret);
 }
-EXPORT_SYMBOL_GPL(fpga_bridge_register);
+EXPORT_SYMBOL_GPL(__fpga_bridge_register);
 
 /**
  * fpga_bridge_unregister - unregister an FPGA bridge
--- linux-qcom-6.8.0.orig/drivers/fpga/fpga-mgr.c
+++ linux-qcom-6.8.0/drivers/fpga/fpga-mgr.c
@@ -664,20 +664,16 @@
 };
 ATTRIBUTE_GROUPS(fpga_mgr);
 
-static struct fpga_manager *__fpga_mgr_get(struct device *dev)
+static struct fpga_manager *__fpga_mgr_get(struct device *mgr_dev)
 {
 	struct fpga_manager *mgr;
 
-	mgr = to_fpga_manager(dev);
+	mgr = to_fpga_manager(mgr_dev);
 
-	if (!try_module_get(dev->parent->driver->owner))
-		goto err_dev;
+	if (!try_module_get(mgr->mops_owner))
+		mgr = ERR_PTR(-ENODEV);
 
 	return mgr;
-
-err_dev:
-	put_device(dev);
-	return ERR_PTR(-ENODEV);
 }
 
 static int fpga_mgr_dev_match(struct device *dev, const void *data)
@@ -693,12 +689,18 @@
  */
 struct fpga_manager *fpga_mgr_get(struct device *dev)
 {
-	struct device *mgr_dev = class_find_device(&fpga_mgr_class, NULL, dev,
-						   fpga_mgr_dev_match);
+	struct fpga_manager *mgr;
+	struct device *mgr_dev;
+
+	mgr_dev = class_find_device(&fpga_mgr_class, NULL, dev, fpga_mgr_dev_match);
 	if (!mgr_dev)
 		return ERR_PTR(-ENODEV);
 
-	return __fpga_mgr_get(mgr_dev);
+	mgr = __fpga_mgr_get(mgr_dev);
+	if (IS_ERR(mgr))
+		put_device(mgr_dev);
+
+	return mgr;
 }
 EXPORT_SYMBOL_GPL(fpga_mgr_get);
 
@@ -711,13 +713,18 @@
  */
 struct fpga_manager *of_fpga_mgr_get(struct device_node *node)
 {
-	struct device *dev;
+	struct fpga_manager *mgr;
+	struct device *mgr_dev;
 
-	dev = class_find_device_by_of_node(&fpga_mgr_class, node);
-	if (!dev)
+	mgr_dev = class_find_device_by_of_node(&fpga_mgr_class, node);
+	if (!mgr_dev)
 		return ERR_PTR(-ENODEV);
 
-	return __fpga_mgr_get(dev);
+	mgr = __fpga_mgr_get(mgr_dev);
+	if (IS_ERR(mgr))
+		put_device(mgr_dev);
+
+	return mgr;
 }
 EXPORT_SYMBOL_GPL(of_fpga_mgr_get);
 
@@ -727,7 +734,7 @@
  */
 void fpga_mgr_put(struct fpga_manager *mgr)
 {
-	module_put(mgr->dev.parent->driver->owner);
+	module_put(mgr->mops_owner);
 	put_device(&mgr->dev);
 }
 EXPORT_SYMBOL_GPL(fpga_mgr_put);
@@ -766,9 +773,10 @@
 EXPORT_SYMBOL_GPL(fpga_mgr_unlock);
 
 /**
- * fpga_mgr_register_full - create and register an FPGA Manager device
+ * __fpga_mgr_register_full - create and register an FPGA Manager device
  * @parent:	fpga manager device from pdev
  * @info:	parameters for fpga manager
+ * @owner:	owner module containing the ops
  *
  * The caller of this function is responsible for calling fpga_mgr_unregister().
  * Using devm_fpga_mgr_register_full() instead is recommended.
@@ -776,7 +784,8 @@
  * Return: pointer to struct fpga_manager pointer or ERR_PTR()
  */
 struct fpga_manager *
-fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info)
+__fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info,
+			 struct module *owner)
 {
 	const struct fpga_manager_ops *mops = info->mops;
 	struct fpga_manager *mgr;
@@ -804,6 +813,8 @@
 
 	mutex_init(&mgr->ref_mutex);
 
+	mgr->mops_owner = owner;
+
 	mgr->name = info->name;
 	mgr->mops = info->mops;
 	mgr->priv = info->priv;
@@ -841,14 +852,15 @@
 
 	return ERR_PTR(ret);
 }
-EXPORT_SYMBOL_GPL(fpga_mgr_register_full);
+EXPORT_SYMBOL_GPL(__fpga_mgr_register_full);
 
 /**
- * fpga_mgr_register - create and register an FPGA Manager device
+ * __fpga_mgr_register - create and register an FPGA Manager device
  * @parent:	fpga manager device from pdev
  * @name:	fpga manager name
  * @mops:	pointer to structure of fpga manager ops
  * @priv:	fpga manager private data
+ * @owner:	owner module containing the ops
  *
  * The caller of this function is responsible for calling fpga_mgr_unregister().
  * Using devm_fpga_mgr_register() instead is recommended. This simple
@@ -859,8 +871,8 @@
  * Return: pointer to struct fpga_manager pointer or ERR_PTR()
  */
 struct fpga_manager *
-fpga_mgr_register(struct device *parent, const char *name,
-		  const struct fpga_manager_ops *mops, void *priv)
+__fpga_mgr_register(struct device *parent, const char *name,
+		    const struct fpga_manager_ops *mops, void *priv, struct module *owner)
 {
 	struct fpga_manager_info info = { 0 };
 
@@ -868,9 +880,9 @@
 	info.mops = mops;
 	info.priv = priv;
 
-	return fpga_mgr_register_full(parent, &info);
+	return __fpga_mgr_register_full(parent, &info, owner);
 }
-EXPORT_SYMBOL_GPL(fpga_mgr_register);
+EXPORT_SYMBOL_GPL(__fpga_mgr_register);
 
 /**
  * fpga_mgr_unregister - unregister an FPGA manager
@@ -900,9 +912,10 @@
 }
 
 /**
- * devm_fpga_mgr_register_full - resource managed variant of fpga_mgr_register()
+ * __devm_fpga_mgr_register_full - resource managed variant of fpga_mgr_register()
  * @parent:	fpga manager device from pdev
  * @info:	parameters for fpga manager
+ * @owner:	owner module containing the ops
  *
  * Return:  fpga manager pointer on success, negative error code otherwise.
  *
@@ -910,7 +923,8 @@
  * function will be called automatically when the managing device is detached.
  */
 struct fpga_manager *
-devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info)
+__devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info,
+			      struct module *owner)
 {
 	struct fpga_mgr_devres *dr;
 	struct fpga_manager *mgr;
@@ -919,7 +933,7 @@
 	if (!dr)
 		return ERR_PTR(-ENOMEM);
 
-	mgr = fpga_mgr_register_full(parent, info);
+	mgr = __fpga_mgr_register_full(parent, info, owner);
 	if (IS_ERR(mgr)) {
 		devres_free(dr);
 		return mgr;
@@ -930,14 +944,15 @@
 
 	return mgr;
 }
-EXPORT_SYMBOL_GPL(devm_fpga_mgr_register_full);
+EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register_full);
 
 /**
- * devm_fpga_mgr_register - resource managed variant of fpga_mgr_register()
+ * __devm_fpga_mgr_register - resource managed variant of fpga_mgr_register()
  * @parent:	fpga manager device from pdev
  * @name:	fpga manager name
  * @mops:	pointer to structure of fpga manager ops
  * @priv:	fpga manager private data
+ * @owner:	owner module containing the ops
  *
  * Return:  fpga manager pointer on success, negative error code otherwise.
  *
@@ -946,8 +961,9 @@
  * device is detached.
  */
 struct fpga_manager *
-devm_fpga_mgr_register(struct device *parent, const char *name,
-		       const struct fpga_manager_ops *mops, void *priv)
+__devm_fpga_mgr_register(struct device *parent, const char *name,
+			 const struct fpga_manager_ops *mops, void *priv,
+			 struct module *owner)
 {
 	struct fpga_manager_info info = { 0 };
 
@@ -955,9 +971,9 @@
 	info.mops = mops;
 	info.priv = priv;
 
-	return devm_fpga_mgr_register_full(parent, &info);
+	return __devm_fpga_mgr_register_full(parent, &info, owner);
 }
-EXPORT_SYMBOL_GPL(devm_fpga_mgr_register);
+EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register);
 
 static void fpga_mgr_dev_release(struct device *dev)
 {
--- linux-qcom-6.8.0.orig/drivers/fpga/fpga-region.c
+++ linux-qcom-6.8.0/drivers/fpga/fpga-region.c
@@ -53,7 +53,7 @@
 	}
 
 	get_device(dev);
-	if (!try_module_get(dev->parent->driver->owner)) {
+	if (!try_module_get(region->ops_owner)) {
 		put_device(dev);
 		mutex_unlock(&region->mutex);
 		return ERR_PTR(-ENODEV);
@@ -75,7 +75,7 @@
 
 	dev_dbg(dev, "put\n");
 
-	module_put(dev->parent->driver->owner);
+	module_put(region->ops_owner);
 	put_device(dev);
 	mutex_unlock(&region->mutex);
 }
@@ -181,14 +181,16 @@
 ATTRIBUTE_GROUPS(fpga_region);
 
 /**
- * fpga_region_register_full - create and register an FPGA Region device
+ * __fpga_region_register_full - create and register an FPGA Region device
  * @parent: device parent
  * @info: parameters for FPGA Region
+ * @owner: module containing the get_bridges function
  *
  * Return: struct fpga_region or ERR_PTR()
  */
 struct fpga_region *
-fpga_region_register_full(struct device *parent, const struct fpga_region_info *info)
+__fpga_region_register_full(struct device *parent, const struct fpga_region_info *info,
+			    struct module *owner)
 {
 	struct fpga_region *region;
 	int id, ret = 0;
@@ -213,6 +215,7 @@
 	region->compat_id = info->compat_id;
 	region->priv = info->priv;
 	region->get_bridges = info->get_bridges;
+	region->ops_owner = owner;
 
 	mutex_init(&region->mutex);
 	INIT_LIST_HEAD(&region->bridge_list);
@@ -241,13 +244,14 @@
 
 	return ERR_PTR(ret);
 }
-EXPORT_SYMBOL_GPL(fpga_region_register_full);
+EXPORT_SYMBOL_GPL(__fpga_region_register_full);
 
 /**
- * fpga_region_register - create and register an FPGA Region device
+ * __fpga_region_register - create and register an FPGA Region device
  * @parent: device parent
  * @mgr: manager that programs this region
  * @get_bridges: optional function to get bridges to a list
+ * @owner: module containing the get_bridges function
  *
  * This simple version of the register function should be sufficient for most users.
  * The fpga_region_register_full() function is available for users that need to
@@ -256,17 +260,17 @@
  * Return: struct fpga_region or ERR_PTR()
  */
 struct fpga_region *
-fpga_region_register(struct device *parent, struct fpga_manager *mgr,
-		     int (*get_bridges)(struct fpga_region *))
+__fpga_region_register(struct device *parent, struct fpga_manager *mgr,
+		       int (*get_bridges)(struct fpga_region *), struct module *owner)
 {
 	struct fpga_region_info info = { 0 };
 
 	info.mgr = mgr;
 	info.get_bridges = get_bridges;
 
-	return fpga_region_register_full(parent, &info);
+	return __fpga_region_register_full(parent, &info, owner);
 }
-EXPORT_SYMBOL_GPL(fpga_region_register);
+EXPORT_SYMBOL_GPL(__fpga_region_register);
 
 /**
  * fpga_region_unregister - unregister an FPGA region
--- linux-qcom-6.8.0.orig/drivers/gpio/Kconfig
+++ linux-qcom-6.8.0/drivers/gpio/Kconfig
@@ -711,7 +711,8 @@
 	  Say yes here to support UniPhier GPIOs.
 
 config GPIO_VF610
-	def_bool y
+	bool "VF610 GPIO support"
+	default y if SOC_VF610
 	depends on ARCH_MXC
 	select GPIOLIB_IRQCHIP
 	help
@@ -1526,7 +1527,7 @@
 	  are "output only" GPIOs.
 
 config GPIO_TQMX86
-	tristate "TQ-Systems QTMX86 GPIO"
+	tristate "TQ-Systems TQMx86 GPIO"
 	depends on MFD_TQMX86 || COMPILE_TEST
 	depends on HAS_IOPORT_MAP
 	select GPIOLIB_IRQCHIP
@@ -1586,6 +1587,18 @@
 menu "PCI GPIO expanders"
 	depends on PCI
 
+config GPIO_AAEON
+	tristate "AAEON GPIO support"
+	depends on ASUS_WMI
+	depends on UBUNTU_ODM_DRIVERS
+	select MFD_AAEON
+	help
+	  Say yes here to support GPIO pins on Single Board Computers produced
+	  by AAEON.
+
+	  This driver leverages the ASUS WMI interface to access device
+	  resources.
+
 config GPIO_AMD8111
 	tristate "AMD 8111 GPIO driver"
 	depends on X86 || COMPILE_TEST
@@ -1793,6 +1806,8 @@
 
 config GPIO_AGGREGATOR
 	tristate "GPIO Aggregator"
+	select CONFIGFS_FS
+	select DEV_SYNC_PROBE
 	help
 	  Say yes here to enable the GPIO Aggregator, which provides a way to
 	  aggregate existing GPIO lines into a new virtual GPIO chip.
@@ -1842,3 +1857,6 @@
 endmenu
 
 endif
+
+config DEV_SYNC_PROBE
+	tristate
--- linux-qcom-6.8.0.orig/drivers/gpio/Makefile
+++ linux-qcom-6.8.0/drivers/gpio/Makefile
@@ -19,11 +19,15 @@
 # directly supported by gpio-generic
 gpio-generic-$(CONFIG_GPIO_GENERIC)	+= gpio-mmio.o
 
+# Utilities for drivers that need synchronous fake device creation
+obj-$(CONFIG_DEV_SYNC_PROBE)		+= dev-sync-probe.o
+
 obj-$(CONFIG_GPIO_104_DIO_48E)		+= gpio-104-dio-48e.o
 obj-$(CONFIG_GPIO_104_IDI_48)		+= gpio-104-idi-48.o
 obj-$(CONFIG_GPIO_104_IDIO_16)		+= gpio-104-idio-16.o
 obj-$(CONFIG_GPIO_74X164)		+= gpio-74x164.o
 obj-$(CONFIG_GPIO_74XX_MMIO)		+= gpio-74xx-mmio.o
+obj-$(CONFIG_GPIO_AAEON)                += gpio-aaeon.o
 obj-$(CONFIG_GPIO_ADNP)			+= gpio-adnp.o
 obj-$(CONFIG_GPIO_ADP5520)		+= gpio-adp5520.o
 obj-$(CONFIG_GPIO_AGGREGATOR)		+= gpio-aggregator.o
--- linux-qcom-6.8.0.orig/drivers/gpio/dev-sync-probe.c
+++ linux-qcom-6.8.0/drivers/gpio/dev-sync-probe.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Common code for drivers creating fake platform devices.
+ *
+ * Provides synchronous device creation: waits for probe completion and
+ * returns the probe success or error status to the device creator.
+ *
+ * Copyright (C) 2021 Bartosz Golaszewski<brgl@bgdev.pl>
+ * Copyright (C) 2025 Koichiro Den<koichiro.den@canonical.com>
+ */
+
+#include <linux/device.h>
+#include <linux/slab.h>
+
+#include "dev-sync-probe.h"
+
+static int dev_sync_probe_notifier_call(struct notifier_block *nb,
+					unsigned long action, void *data)
+{
+	struct dev_sync_probe_data *pdata;
+	struct device *dev = data;
+
+	pdata = container_of(nb, struct dev_sync_probe_data, bus_notifier);
+	if (!device_match_name(dev, pdata->name))
+		return NOTIFY_DONE;
+
+	switch (action) {
+	case BUS_NOTIFY_BOUND_DRIVER:
+		pdata->driver_bound = true;
+		break;
+	case BUS_NOTIFY_DRIVER_NOT_BOUND:
+		pdata->driver_bound = false;
+		break;
+	default:
+		return NOTIFY_DONE;
+	}
+
+	complete(&pdata->probe_completion);
+	return NOTIFY_OK;
+}
+
+void dev_sync_probe_init(struct dev_sync_probe_data *data)
+{
+	memset(data, 0, sizeof(*data));
+	init_completion(&data->probe_completion);
+	data->bus_notifier.notifier_call = dev_sync_probe_notifier_call;
+}
+EXPORT_SYMBOL_GPL(dev_sync_probe_init);
+
+int dev_sync_probe_register(struct dev_sync_probe_data *data,
+			    struct platform_device_info *pdevinfo)
+{
+	struct platform_device *pdev;
+	char *name;
+
+	name = kasprintf(GFP_KERNEL, "%s.%d", pdevinfo->name, pdevinfo->id);
+	if (!name)
+		return -ENOMEM;
+
+	data->driver_bound = false;
+	data->name = name;
+	reinit_completion(&data->probe_completion);
+	bus_register_notifier(&platform_bus_type, &data->bus_notifier);
+
+	pdev = platform_device_register_full(pdevinfo);
+	if (IS_ERR(pdev)) {
+		bus_unregister_notifier(&platform_bus_type, &data->bus_notifier);
+		kfree(data->name);
+		return PTR_ERR(pdev);
+	}
+
+	wait_for_completion(&data->probe_completion);
+	bus_unregister_notifier(&platform_bus_type, &data->bus_notifier);
+
+	if (!data->driver_bound) {
+		platform_device_unregister(pdev);
+		kfree(data->name);
+		return -ENXIO;
+	}
+
+	data->pdev = pdev;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(dev_sync_probe_register);
+
+void dev_sync_probe_unregister(struct dev_sync_probe_data *data)
+{
+	platform_device_unregister(data->pdev);
+	kfree(data->name);
+	data->pdev = NULL;
+}
+EXPORT_SYMBOL_GPL(dev_sync_probe_unregister);
+
+MODULE_AUTHOR("Bartosz Golaszewski<brgl@bgdev.pl>");
+MODULE_AUTHOR("Koichiro Den<koichiro.den@canonical.com>");
+MODULE_DESCRIPTION("Utilities for synchronous fake device creation");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/gpio/dev-sync-probe.h
+++ linux-qcom-6.8.0/drivers/gpio/dev-sync-probe.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef DEV_SYNC_PROBE_H
+#define DEV_SYNC_PROBE_H
+
+#include <linux/completion.h>
+#include <linux/notifier.h>
+#include <linux/platform_device.h>
+
+struct dev_sync_probe_data {
+	struct platform_device *pdev;
+	const char *name;
+
+	/* Synchronize with probe */
+	struct notifier_block bus_notifier;
+	struct completion probe_completion;
+	bool driver_bound;
+};
+
+void dev_sync_probe_init(struct dev_sync_probe_data *data);
+int dev_sync_probe_register(struct dev_sync_probe_data *data,
+			    struct platform_device_info *pdevinfo);
+void dev_sync_probe_unregister(struct dev_sync_probe_data *data);
+
+#endif /* DEV_SYNC_PROBE_H */
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-aaeon.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-aaeon.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * AAEON GPIO driver
+ * Copyright (c) 2021, AAEON Ltd.
+ *
+ * Author: Edward Lin <edward1_lin@aaeon.com.tw>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/acpi.h>
+#include <linux/bitops.h>
+#include <linux/gpio/driver.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_data/x86/asus-wmi.h>
+#include <linux/platform_device.h>
+
+#define DRVNAME "gpio_aaeon"
+#define ASUS_NB_WMI_EVENT_GUID   "0B3CBB35-E3C2-45ED-91C2-4C5A6D195D1C"
+#define AAEON_WMI_MGMT_GUID      "97845ED0-4E6D-11DE-8A39-0800200C9A66"
+
+#define GET_GPIO_NUMBER_ID       0x00010000
+#define GET_LEVEL_METHOD_ID      0x00010001
+#define SET_LEVEL_METHOD_ID      0x00010002
+#define GET_DIRECTION_METHOD_ID  0x00010003
+#define SET_DIRECTION_METHOD_ID  0x00010004
+#define GET_SIO_NUMBER_METHOD_ID 0xF0010
+
+struct aaeon_gpio_bank {
+	struct gpio_chip chip;
+	unsigned int regbase;
+	struct aaeon_gpio_data *data;
+};
+
+struct aaeon_gpio_data {
+	int nr_bank;
+	struct aaeon_gpio_bank *bank;
+};
+
+static int aaeon_gpio_get_number(void);
+static int aaeon_gpio_get_direction(struct gpio_chip *chip,
+				 unsigned int offset);
+static int aaeon_gpio_output_set_direction(struct gpio_chip *chip,
+				 unsigned int offset, int value);
+static int aaeon_gpio_input_set_direction(struct gpio_chip *chip,
+				 unsigned int offset);
+static int aaeon_gpio_get(struct gpio_chip *chip,
+				 unsigned int offset);
+static void aaeon_gpio_set(struct gpio_chip *chip, unsigned int offset,
+				 int value);
+
+#define AAEON_GPIO_BANK(_base, _ngpio, _regbase)			\
+{									\
+	.chip = {							\
+		.label            = DRVNAME,				\
+		.owner            = THIS_MODULE,			\
+		.get_direction    = aaeon_gpio_get_direction,		\
+		.direction_input  = aaeon_gpio_input_set_direction,     \
+		.direction_output = aaeon_gpio_output_set_direction,    \
+		.get              = aaeon_gpio_get,			\
+		.set              = aaeon_gpio_set,			\
+		.base             = _base,				\
+		.ngpio            = _ngpio,				\
+		.can_sleep        = true,				\
+	},								\
+	.regbase = _regbase,						\
+}
+
+static struct aaeon_gpio_bank aaeon_gpio_bank[] = {
+	AAEON_GPIO_BANK(0, 0, 0xF0),
+};
+
+static int aaeon_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+	int err, retval;
+	u32 dev_id = 0x0;
+
+	dev_id |= offset;
+	err = asus_wmi_evaluate_method(GET_DIRECTION_METHOD_ID, dev_id,
+				       0, &retval);
+	if (err)
+		return err;
+
+	return retval;
+}
+
+static int aaeon_gpio_input_set_direction(struct gpio_chip *chip,
+					  unsigned int offset)
+{
+	int err, retval;
+	u32 dev_id;
+
+	dev_id = BIT(16) | offset;
+	err = asus_wmi_evaluate_method(SET_DIRECTION_METHOD_ID, dev_id,
+				       0, &retval);
+	if (err)
+		return err;
+
+	return retval;
+}
+
+static int aaeon_gpio_output_set_direction(struct gpio_chip *chip,
+					   unsigned int offset, int value)
+{
+	int err, retval;
+	u32 dev_id = 0x0;
+
+	dev_id |= offset;
+	err = asus_wmi_evaluate_method(SET_DIRECTION_METHOD_ID, dev_id,
+				       0, &retval);
+	if (err)
+		return err;
+
+	return retval;
+}
+
+static int aaeon_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	int err, retval;
+	u32 dev_id = 0x0;
+
+	dev_id |= offset;
+	err = asus_wmi_evaluate_method(GET_LEVEL_METHOD_ID, dev_id, 0, &retval);
+	if (err)
+		return err;
+
+	return retval;
+}
+
+static void aaeon_gpio_set(struct gpio_chip *chip, unsigned int offset,
+			   int value)
+{
+	int retval;
+	u32 dev_id = offset;
+
+	if (value)
+		dev_id = BIT(16) | dev_id;
+
+	asus_wmi_evaluate_method(SET_LEVEL_METHOD_ID, dev_id, 0, &retval);
+}
+
+static int aaeon_gpio_get_number(void)
+{
+	int err, retval;
+
+	err = asus_wmi_evaluate_method(GET_GPIO_NUMBER_ID,
+				       GET_SIO_NUMBER_METHOD_ID,
+				       0, &retval);
+	if (err)
+		return err;
+
+	return retval;
+}
+
+static int __init aaeon_gpio_probe(struct platform_device *pdev)
+{
+	int err, i;
+	int dio_number = 0;
+	struct aaeon_gpio_data *data;
+	struct aaeon_gpio_bank *bank;
+
+	/* Prevent other drivers adding this platfom device */
+	if (!wmi_has_guid(AAEON_WMI_MGMT_GUID)) {
+		pr_debug("AAEON Management GUID not found\n");
+		return -ENODEV;
+	}
+
+	dio_number = aaeon_gpio_get_number();
+	if (dio_number < 0)
+		return -ENODEV;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->nr_bank = ARRAY_SIZE(aaeon_gpio_bank);
+	data->bank = aaeon_gpio_bank;
+	platform_set_drvdata(pdev, data);
+	bank = &data->bank[0];
+	bank->chip.parent = &pdev->dev;
+	bank->chip.ngpio = dio_number;
+	bank->data = data;
+	err = devm_gpiochip_add_data(&pdev->dev, &bank->chip, bank);
+	if (err)
+		pr_debug("Failed to register gpiochip %d: %d\n", i, err);
+
+	return err;
+}
+
+static struct platform_driver aaeon_gpio_driver = {
+	.driver = {
+		.name = "gpio-aaeon",
+	},
+};
+
+module_platform_driver_probe(aaeon_gpio_driver, aaeon_gpio_probe);
+
+MODULE_ALIAS("platform:gpio-aaeon");
+MODULE_DESCRIPTION("AAEON GPIO Driver");
+MODULE_AUTHOR("Edward Lin <edward1_lin@aaeon.com.tw>");
+MODULE_LICENSE("GPL v2");
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-aggregator.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-aggregator.c
@@ -9,10 +9,13 @@
 
 #include <linux/bitmap.h>
 #include <linux/bitops.h>
+#include <linux/configfs.h>
 #include <linux/ctype.h>
 #include <linux/delay.h>
 #include <linux/idr.h>
 #include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/lockdep.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
@@ -27,23 +30,88 @@
 #include <linux/gpio/driver.h>
 #include <linux/gpio/machine.h>
 
+#include "dev-sync-probe.h"
+
 #define AGGREGATOR_MAX_GPIOS 512
+#define AGGREGATOR_LEGACY_PREFIX "_sysfs"
 
 /*
  * GPIO Aggregator sysfs interface
  */
 
 struct gpio_aggregator {
+	struct dev_sync_probe_data probe_data;
+	struct config_group group;
 	struct gpiod_lookup_table *lookups;
-	struct platform_device *pdev;
+	struct mutex lock;
+	int id;
+
+	/* List of gpio_aggregator_line. Always added in order */
+	struct list_head list_head;
+
+	/* used by legacy sysfs interface only */
+	bool init_via_sysfs;
 	char args[];
 };
 
+struct gpio_aggregator_line {
+	struct config_group group;
+	struct gpio_aggregator *parent;
+	struct list_head entry;
+
+	/* Line index within the aggregator device */
+	unsigned int idx;
+
+	/* Custom name for the virtual line */
+	const char *name;
+	/* GPIO chip label or line name */
+	const char *key;
+	/* Can be negative to indicate lookup by line name */
+	int offset;
+
+	enum gpio_lookup_flags flags;
+};
+
+struct gpio_aggregator_pdev_meta {
+	bool init_via_sysfs;
+};
+
 static DEFINE_MUTEX(gpio_aggregator_lock);	/* protects idr */
 static DEFINE_IDR(gpio_aggregator_idr);
 
-static int aggr_add_gpio(struct gpio_aggregator *aggr, const char *key,
-			 int hwnum, unsigned int *n)
+static int gpio_aggregator_alloc(struct gpio_aggregator **aggr, size_t arg_size)
+{
+	int ret;
+
+	struct gpio_aggregator *new __free(kfree) = kzalloc(
+					sizeof(*new) + arg_size, GFP_KERNEL);
+	if (!new)
+		return -ENOMEM;
+
+	scoped_guard(mutex, &gpio_aggregator_lock)
+		ret = idr_alloc(&gpio_aggregator_idr, new, 0, 0, GFP_KERNEL);
+
+	if (ret < 0)
+		return ret;
+
+	new->id = ret;
+	INIT_LIST_HEAD(&new->list_head);
+	mutex_init(&new->lock);
+	*aggr = no_free_ptr(new);
+	return 0;
+}
+
+static void gpio_aggregator_free(struct gpio_aggregator *aggr)
+{
+	scoped_guard(mutex, &gpio_aggregator_lock)
+		idr_remove(&gpio_aggregator_idr, aggr->id);
+
+	mutex_destroy(&aggr->lock);
+	kfree(aggr);
+}
+
+static int gpio_aggregator_add_gpio(struct gpio_aggregator *aggr,
+				    const char *key, int hwnum, unsigned int *n)
 {
 	struct gpiod_lookup_table *lookups;
 
@@ -61,180 +129,101 @@
 	return 0;
 }
 
-static int aggr_parse(struct gpio_aggregator *aggr)
+static bool gpio_aggregator_is_active(struct gpio_aggregator *aggr)
 {
-	char *args = skip_spaces(aggr->args);
-	char *name, *offsets, *p;
-	unsigned long *bitmap;
-	unsigned int i, n = 0;
-	int error = 0;
-
-	bitmap = bitmap_alloc(AGGREGATOR_MAX_GPIOS, GFP_KERNEL);
-	if (!bitmap)
-		return -ENOMEM;
+	lockdep_assert_held(&aggr->lock);
 
-	args = next_arg(args, &name, &p);
-	while (*args) {
-		args = next_arg(args, &offsets, &p);
-
-		p = get_options(offsets, 0, &error);
-		if (error == 0 || *p) {
-			/* Named GPIO line */
-			error = aggr_add_gpio(aggr, name, U16_MAX, &n);
-			if (error)
-				goto free_bitmap;
-
-			name = offsets;
-			continue;
-		}
-
-		/* GPIO chip + offset(s) */
-		error = bitmap_parselist(offsets, bitmap, AGGREGATOR_MAX_GPIOS);
-		if (error) {
-			pr_err("Cannot parse %s: %d\n", offsets, error);
-			goto free_bitmap;
-		}
-
-		for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) {
-			error = aggr_add_gpio(aggr, name, i, &n);
-			if (error)
-				goto free_bitmap;
-		}
-
-		args = next_arg(args, &name, &p);
-	}
-
-	if (!n) {
-		pr_err("No GPIOs specified\n");
-		error = -EINVAL;
-	}
-
-free_bitmap:
-	bitmap_free(bitmap);
-	return error;
+	return aggr->probe_data.pdev && platform_get_drvdata(aggr->probe_data.pdev);
 }
 
-static ssize_t new_device_store(struct device_driver *driver, const char *buf,
-				size_t count)
+/* Only aggregators created via legacy sysfs can be "activating". */
+static bool gpio_aggregator_is_activating(struct gpio_aggregator *aggr)
 {
-	struct gpio_aggregator *aggr;
-	struct platform_device *pdev;
-	int res, id;
-
-	/* kernfs guarantees string termination, so count + 1 is safe */
-	aggr = kzalloc(sizeof(*aggr) + count + 1, GFP_KERNEL);
-	if (!aggr)
-		return -ENOMEM;
-
-	memcpy(aggr->args, buf, count + 1);
-
-	aggr->lookups = kzalloc(struct_size(aggr->lookups, table, 1),
-				GFP_KERNEL);
-	if (!aggr->lookups) {
-		res = -ENOMEM;
-		goto free_ga;
-	}
+	lockdep_assert_held(&aggr->lock);
 
-	mutex_lock(&gpio_aggregator_lock);
-	id = idr_alloc(&gpio_aggregator_idr, aggr, 0, 0, GFP_KERNEL);
-	mutex_unlock(&gpio_aggregator_lock);
+	return aggr->probe_data.pdev && !platform_get_drvdata(aggr->probe_data.pdev);
+}
 
-	if (id < 0) {
-		res = id;
-		goto free_table;
-	}
+static size_t gpio_aggregator_count_lines(struct gpio_aggregator *aggr)
+{
+	lockdep_assert_held(&aggr->lock);
 
-	aggr->lookups->dev_id = kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, id);
-	if (!aggr->lookups->dev_id) {
-		res = -ENOMEM;
-		goto remove_idr;
-	}
+	return list_count_nodes(&aggr->list_head);
+}
 
-	res = aggr_parse(aggr);
-	if (res)
-		goto free_dev_id;
+static struct gpio_aggregator_line *
+gpio_aggregator_line_alloc(struct gpio_aggregator *parent, unsigned int idx,
+			   char *key, int offset)
+{
+	struct gpio_aggregator_line *line;
 
-	gpiod_add_lookup_table(aggr->lookups);
+	line = kzalloc(sizeof(*line), GFP_KERNEL);
+	if (!line)
+		return ERR_PTR(-ENOMEM);
 
-	pdev = platform_device_register_simple(DRV_NAME, id, NULL, 0);
-	if (IS_ERR(pdev)) {
-		res = PTR_ERR(pdev);
-		goto remove_table;
+	if (key) {
+		line->key = kstrdup(key, GFP_KERNEL);
+		if (!line->key) {
+			kfree(line);
+			return ERR_PTR(-ENOMEM);
+		}
 	}
 
-	aggr->pdev = pdev;
-	return count;
+	line->flags = GPIO_LOOKUP_FLAGS_DEFAULT;
+	line->parent = parent;
+	line->idx = idx;
+	line->offset = offset;
+	INIT_LIST_HEAD(&line->entry);
 
-remove_table:
-	gpiod_remove_lookup_table(aggr->lookups);
-free_dev_id:
-	kfree(aggr->lookups->dev_id);
-remove_idr:
-	mutex_lock(&gpio_aggregator_lock);
-	idr_remove(&gpio_aggregator_idr, id);
-	mutex_unlock(&gpio_aggregator_lock);
-free_table:
-	kfree(aggr->lookups);
-free_ga:
-	kfree(aggr);
-	return res;
-}
-
-static DRIVER_ATTR_WO(new_device);
-
-static void gpio_aggregator_free(struct gpio_aggregator *aggr)
-{
-	platform_device_unregister(aggr->pdev);
-	gpiod_remove_lookup_table(aggr->lookups);
-	kfree(aggr->lookups->dev_id);
-	kfree(aggr->lookups);
-	kfree(aggr);
+	return line;
 }
 
-static ssize_t delete_device_store(struct device_driver *driver,
-				   const char *buf, size_t count)
+static void gpio_aggregator_line_add(struct gpio_aggregator *aggr,
+				     struct gpio_aggregator_line *line)
 {
-	struct gpio_aggregator *aggr;
-	unsigned int id;
-	int error;
+	struct gpio_aggregator_line *tmp;
 
-	if (!str_has_prefix(buf, DRV_NAME "."))
-		return -EINVAL;
+	lockdep_assert_held(&aggr->lock);
 
-	error = kstrtouint(buf + strlen(DRV_NAME "."), 10, &id);
-	if (error)
-		return error;
-
-	mutex_lock(&gpio_aggregator_lock);
-	aggr = idr_remove(&gpio_aggregator_idr, id);
-	mutex_unlock(&gpio_aggregator_lock);
-	if (!aggr)
-		return -ENOENT;
-
-	gpio_aggregator_free(aggr);
-	return count;
+	list_for_each_entry(tmp, &aggr->list_head, entry) {
+		if (tmp->idx > line->idx) {
+			list_add_tail(&line->entry, &tmp->entry);
+			return;
+		}
+	}
+	list_add_tail(&line->entry, &aggr->list_head);
 }
-static DRIVER_ATTR_WO(delete_device);
-
-static struct attribute *gpio_aggregator_attrs[] = {
-	&driver_attr_new_device.attr,
-	&driver_attr_delete_device.attr,
-	NULL
-};
-ATTRIBUTE_GROUPS(gpio_aggregator);
 
-static int __exit gpio_aggregator_idr_remove(int id, void *p, void *data)
+static void gpio_aggregator_line_del(struct gpio_aggregator *aggr,
+				     struct gpio_aggregator_line *line)
 {
-	gpio_aggregator_free(p);
-	return 0;
-}
+	lockdep_assert_held(&aggr->lock);
 
-static void __exit gpio_aggregator_remove_all(void)
-{
-	mutex_lock(&gpio_aggregator_lock);
-	idr_for_each(&gpio_aggregator_idr, gpio_aggregator_idr_remove, NULL);
-	idr_destroy(&gpio_aggregator_idr);
-	mutex_unlock(&gpio_aggregator_lock);
+	list_del(&line->entry);
+}
+
+static void gpio_aggregator_free_lines(struct gpio_aggregator *aggr)
+{
+	struct gpio_aggregator_line *line, *tmp;
+
+	list_for_each_entry_safe(line, tmp, &aggr->list_head, entry) {
+		configfs_unregister_group(&line->group);
+		/*
+		 * Normally, we acquire aggr->lock within the configfs
+		 * callback. However, in the legacy sysfs interface case,
+		 * calling configfs_(un)register_group while holding
+		 * aggr->lock could cause a deadlock. Fortunately, this is
+		 * unnecessary because the new_device/delete_device path
+		 * and the module unload path are mutually exclusive,
+		 * thanks to an explicit try_module_get. That's why this
+		 * minimal scoped_guard suffices.
+		 */
+		scoped_guard(mutex, &aggr->lock)
+			gpio_aggregator_line_del(aggr, line);
+		kfree(line->key);
+		kfree(line->name);
+		kfree(line);
+	}
 }
 
 
@@ -560,6 +549,728 @@
 	return fwd;
 }
 
+/*
+ * Configfs interface
+ */
+
+static struct gpio_aggregator *
+to_gpio_aggregator(struct config_item *item)
+{
+	struct config_group *group = to_config_group(item);
+
+	return container_of(group, struct gpio_aggregator, group);
+}
+
+static struct gpio_aggregator_line *
+to_gpio_aggregator_line(struct config_item *item)
+{
+	struct config_group *group = to_config_group(item);
+
+	return container_of(group, struct gpio_aggregator_line, group);
+}
+
+static struct fwnode_handle *
+gpio_aggregator_make_device_sw_node(struct gpio_aggregator *aggr)
+{
+	struct property_entry properties[2];
+	struct gpio_aggregator_line *line;
+	size_t num_lines;
+	int n = 0;
+
+	memset(properties, 0, sizeof(properties));
+
+	num_lines = gpio_aggregator_count_lines(aggr);
+	if (num_lines == 0)
+		return NULL;
+
+	const char **line_names __free(kfree) = kcalloc(
+				num_lines, sizeof(*line_names), GFP_KERNEL);
+	if (!line_names)
+		return ERR_PTR(-ENOMEM);
+
+	/* The list is always sorted as new elements are inserted in order. */
+	list_for_each_entry(line, &aggr->list_head, entry)
+		line_names[n++] = line->name ?: "";
+
+	properties[0] = PROPERTY_ENTRY_STRING_ARRAY_LEN(
+					"gpio-line-names",
+					line_names, num_lines);
+
+	return fwnode_create_software_node(properties, NULL);
+}
+
+static int gpio_aggregator_activate(struct gpio_aggregator *aggr)
+{
+	struct platform_device_info pdevinfo;
+	struct gpio_aggregator_line *line;
+	struct fwnode_handle *swnode;
+	unsigned int n = 0;
+	int ret = 0;
+
+	if (gpio_aggregator_count_lines(aggr) == 0)
+		return -EINVAL;
+
+	aggr->lookups = kzalloc(struct_size(aggr->lookups, table, 1),
+				GFP_KERNEL);
+	if (!aggr->lookups)
+		return -ENOMEM;
+
+	swnode = gpio_aggregator_make_device_sw_node(aggr);
+	if (IS_ERR(swnode)) {
+		ret = PTR_ERR(swnode);
+		goto err_remove_lookups;
+	}
+
+	memset(&pdevinfo, 0, sizeof(pdevinfo));
+	pdevinfo.name = DRV_NAME;
+	pdevinfo.id = aggr->id;
+	pdevinfo.fwnode = swnode;
+
+	/* The list is always sorted as new elements are inserted in order. */
+	list_for_each_entry(line, &aggr->list_head, entry) {
+		/*
+		 * - Either GPIO chip label or line name must be configured
+		 *   (i.e. line->key must be non-NULL)
+		 * - Line directories must be named with sequential numeric
+		 *   suffixes starting from 0. (i.e. ./line0, ./line1, ...)
+		 */
+		if (!line->key || line->idx != n) {
+			ret = -EINVAL;
+			goto err_remove_swnode;
+		}
+
+		if (line->offset < 0)
+			ret = gpio_aggregator_add_gpio(aggr, line->key,
+						       U16_MAX, &n);
+		else
+			ret = gpio_aggregator_add_gpio(aggr, line->key,
+						       line->offset, &n);
+		if (ret)
+			goto err_remove_swnode;
+	}
+
+	aggr->lookups->dev_id = kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, aggr->id);
+	if (!aggr->lookups->dev_id) {
+		ret = -ENOMEM;
+		goto err_remove_swnode;
+	}
+
+	gpiod_add_lookup_table(aggr->lookups);
+
+	ret = dev_sync_probe_register(&aggr->probe_data, &pdevinfo);
+	if (ret)
+		goto err_remove_lookup_table;
+
+	return 0;
+
+err_remove_lookup_table:
+	kfree(aggr->lookups->dev_id);
+	gpiod_remove_lookup_table(aggr->lookups);
+err_remove_swnode:
+	fwnode_remove_software_node(swnode);
+err_remove_lookups:
+	kfree(aggr->lookups);
+
+	return ret;
+}
+
+static void gpio_aggregator_deactivate(struct gpio_aggregator *aggr)
+{
+	dev_sync_probe_unregister(&aggr->probe_data);
+	gpiod_remove_lookup_table(aggr->lookups);
+	kfree(aggr->lookups->dev_id);
+	kfree(aggr->lookups);
+}
+
+static void gpio_aggregator_lockup_configfs(struct gpio_aggregator *aggr,
+					    bool lock)
+{
+	struct configfs_subsystem *subsys = aggr->group.cg_subsys;
+	struct gpio_aggregator_line *line;
+
+	/*
+	 * The device only needs to depend on leaf lines. This is
+	 * sufficient to lock up all the configfs entries that the
+	 * instantiated, alive device depends on.
+	 */
+	list_for_each_entry(line, &aggr->list_head, entry) {
+		if (lock)
+			configfs_depend_item_unlocked(
+					subsys, &line->group.cg_item);
+		else
+			configfs_undepend_item_unlocked(
+					&line->group.cg_item);
+	}
+}
+
+static ssize_t
+gpio_aggregator_line_key_show(struct config_item *item, char *page)
+{
+	struct gpio_aggregator_line *line = to_gpio_aggregator_line(item);
+	struct gpio_aggregator *aggr = line->parent;
+
+	guard(mutex)(&aggr->lock);
+
+	return sysfs_emit(page, "%s\n", line->key ?: "");
+}
+
+static ssize_t
+gpio_aggregator_line_key_store(struct config_item *item, const char *page,
+			       size_t count)
+{
+	struct gpio_aggregator_line *line = to_gpio_aggregator_line(item);
+	struct gpio_aggregator *aggr = line->parent;
+
+	char *key __free(kfree) = kstrndup(skip_spaces(page), count,
+					   GFP_KERNEL);
+	if (!key)
+		return -ENOMEM;
+
+	strim(key);
+
+	guard(mutex)(&aggr->lock);
+
+	if (gpio_aggregator_is_activating(aggr) ||
+	    gpio_aggregator_is_active(aggr))
+		return -EBUSY;
+
+	kfree(line->key);
+	line->key = no_free_ptr(key);
+
+	return count;
+}
+CONFIGFS_ATTR(gpio_aggregator_line_, key);
+
+static ssize_t
+gpio_aggregator_line_name_show(struct config_item *item, char *page)
+{
+	struct gpio_aggregator_line *line = to_gpio_aggregator_line(item);
+	struct gpio_aggregator *aggr = line->parent;
+
+	guard(mutex)(&aggr->lock);
+
+	return sysfs_emit(page, "%s\n", line->name ?: "");
+}
+
+static ssize_t
+gpio_aggregator_line_name_store(struct config_item *item, const char *page,
+				size_t count)
+{
+	struct gpio_aggregator_line *line = to_gpio_aggregator_line(item);
+	struct gpio_aggregator *aggr = line->parent;
+
+	char *name __free(kfree) = kstrndup(skip_spaces(page), count,
+					    GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+
+	strim(name);
+
+	guard(mutex)(&aggr->lock);
+
+	if (gpio_aggregator_is_activating(aggr) ||
+	    gpio_aggregator_is_active(aggr))
+		return -EBUSY;
+
+	kfree(line->name);
+	line->name = no_free_ptr(name);
+
+	return count;
+}
+CONFIGFS_ATTR(gpio_aggregator_line_, name);
+
+static ssize_t
+gpio_aggregator_line_offset_show(struct config_item *item, char *page)
+{
+	struct gpio_aggregator_line *line = to_gpio_aggregator_line(item);
+	struct gpio_aggregator *aggr = line->parent;
+
+	guard(mutex)(&aggr->lock);
+
+	return sysfs_emit(page, "%d\n", line->offset);
+}
+
+static ssize_t
+gpio_aggregator_line_offset_store(struct config_item *item, const char *page,
+				  size_t count)
+{
+	struct gpio_aggregator_line *line = to_gpio_aggregator_line(item);
+	struct gpio_aggregator *aggr = line->parent;
+	int offset, ret;
+
+	ret = kstrtoint(page, 0, &offset);
+	if (ret)
+		return ret;
+
+	/*
+	 * When offset == -1, 'key' represents a line name to lookup.
+	 * When 0 <= offset < 65535, 'key' represents the label of the chip with
+	 * the 'offset' value representing the line within that chip.
+	 *
+	 * GPIOLIB uses the U16_MAX value to indicate lookup by line name so
+	 * the greatest offset we can accept is (U16_MAX - 1).
+	 */
+	if (offset > (U16_MAX - 1) || offset < -1)
+		return -EINVAL;
+
+	guard(mutex)(&aggr->lock);
+
+	if (gpio_aggregator_is_activating(aggr) ||
+	    gpio_aggregator_is_active(aggr))
+		return -EBUSY;
+
+	line->offset = offset;
+
+	return count;
+}
+CONFIGFS_ATTR(gpio_aggregator_line_, offset);
+
+static struct configfs_attribute *gpio_aggregator_line_attrs[] = {
+	&gpio_aggregator_line_attr_key,
+	&gpio_aggregator_line_attr_name,
+	&gpio_aggregator_line_attr_offset,
+	NULL
+};
+
+static ssize_t
+gpio_aggregator_device_dev_name_show(struct config_item *item, char *page)
+{
+	struct gpio_aggregator *aggr = to_gpio_aggregator(item);
+	struct platform_device *pdev;
+
+	guard(mutex)(&aggr->lock);
+
+	pdev = aggr->probe_data.pdev;
+	if (pdev)
+		return sysfs_emit(page, "%s\n", dev_name(&pdev->dev));
+
+	return sysfs_emit(page, "%s.%d\n", DRV_NAME, aggr->id);
+}
+CONFIGFS_ATTR_RO(gpio_aggregator_device_, dev_name);
+
+static ssize_t
+gpio_aggregator_device_live_show(struct config_item *item, char *page)
+{
+	struct gpio_aggregator *aggr = to_gpio_aggregator(item);
+
+	guard(mutex)(&aggr->lock);
+
+	return sysfs_emit(page, "%c\n",
+			  gpio_aggregator_is_active(aggr) ? '1' : '0');
+}
+
+static ssize_t
+gpio_aggregator_device_live_store(struct config_item *item, const char *page,
+				  size_t count)
+{
+	struct gpio_aggregator *aggr = to_gpio_aggregator(item);
+	int ret = 0;
+	bool live;
+
+	ret = kstrtobool(page, &live);
+	if (ret)
+		return ret;
+
+	if (!try_module_get(THIS_MODULE))
+		return -ENOENT;
+
+	if (live && !aggr->init_via_sysfs)
+		gpio_aggregator_lockup_configfs(aggr, true);
+
+	scoped_guard(mutex, &aggr->lock) {
+		if (gpio_aggregator_is_activating(aggr) ||
+		    (live == gpio_aggregator_is_active(aggr)))
+			ret = -EPERM;
+		else if (live)
+			ret = gpio_aggregator_activate(aggr);
+		else
+			gpio_aggregator_deactivate(aggr);
+	}
+
+	/*
+	 * Undepend is required only if device disablement (live == 0)
+	 * succeeds or if device enablement (live == 1) fails.
+	 */
+	if (live == !!ret && !aggr->init_via_sysfs)
+		gpio_aggregator_lockup_configfs(aggr, false);
+
+	module_put(THIS_MODULE);
+
+	return ret ?: count;
+}
+CONFIGFS_ATTR(gpio_aggregator_device_, live);
+
+static struct configfs_attribute *gpio_aggregator_device_attrs[] = {
+	&gpio_aggregator_device_attr_dev_name,
+	&gpio_aggregator_device_attr_live,
+	NULL
+};
+
+static void
+gpio_aggregator_line_release(struct config_item *item)
+{
+	struct gpio_aggregator_line *line = to_gpio_aggregator_line(item);
+	struct gpio_aggregator *aggr = line->parent;
+
+	guard(mutex)(&aggr->lock);
+
+	gpio_aggregator_line_del(aggr, line);
+	kfree(line->key);
+	kfree(line->name);
+	kfree(line);
+}
+
+static struct configfs_item_operations gpio_aggregator_line_item_ops = {
+	.release	= gpio_aggregator_line_release,
+};
+
+static const struct config_item_type gpio_aggregator_line_type = {
+	.ct_item_ops	= &gpio_aggregator_line_item_ops,
+	.ct_attrs	= gpio_aggregator_line_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
+static void gpio_aggregator_device_release(struct config_item *item)
+{
+	struct gpio_aggregator *aggr = to_gpio_aggregator(item);
+
+	/*
+	 * At this point, aggr is neither active nor activating,
+	 * so calling gpio_aggregator_deactivate() is always unnecessary.
+	 */
+	gpio_aggregator_free(aggr);
+}
+
+static struct configfs_item_operations gpio_aggregator_device_item_ops = {
+	.release	= gpio_aggregator_device_release,
+};
+
+static struct config_group *
+gpio_aggregator_device_make_group(struct config_group *group, const char *name)
+{
+	struct gpio_aggregator *aggr = to_gpio_aggregator(&group->cg_item);
+	struct gpio_aggregator_line *line;
+	unsigned int idx;
+	int ret, nchar;
+
+	ret = sscanf(name, "line%u%n", &idx, &nchar);
+	if (ret != 1 || nchar != strlen(name))
+		return ERR_PTR(-EINVAL);
+
+	if (aggr->init_via_sysfs)
+		/*
+		 * Aggregators created via legacy sysfs interface are exposed as
+		 * default groups, which means rmdir(2) is prohibited for them.
+		 * For simplicity, and to avoid confusion, we also prohibit
+		 * mkdir(2).
+		 */
+		return ERR_PTR(-EPERM);
+
+	guard(mutex)(&aggr->lock);
+
+	if (gpio_aggregator_is_active(aggr))
+		return ERR_PTR(-EBUSY);
+
+	list_for_each_entry(line, &aggr->list_head, entry)
+		if (line->idx == idx)
+			return ERR_PTR(-EINVAL);
+
+	line = gpio_aggregator_line_alloc(aggr, idx, NULL, -1);
+	if (IS_ERR(line))
+		return ERR_CAST(line);
+
+	config_group_init_type_name(&line->group, name, &gpio_aggregator_line_type);
+
+	gpio_aggregator_line_add(aggr, line);
+
+	return &line->group;
+}
+
+static struct configfs_group_operations gpio_aggregator_device_group_ops = {
+	.make_group	= gpio_aggregator_device_make_group,
+};
+
+static const struct config_item_type gpio_aggregator_device_type = {
+	.ct_group_ops	= &gpio_aggregator_device_group_ops,
+	.ct_item_ops	= &gpio_aggregator_device_item_ops,
+	.ct_attrs	= gpio_aggregator_device_attrs,
+	.ct_owner	= THIS_MODULE,
+};
+
+static struct config_group *
+gpio_aggregator_make_group(struct config_group *group, const char *name)
+{
+	struct gpio_aggregator *aggr;
+	int ret;
+
+	/*
+	 * "_sysfs" prefix is reserved for auto-generated config group
+	 * for devices create via legacy sysfs interface.
+	 */
+	if (strncmp(name, AGGREGATOR_LEGACY_PREFIX,
+		    sizeof(AGGREGATOR_LEGACY_PREFIX) - 1) == 0)
+		return ERR_PTR(-EINVAL);
+
+	/* arg space is unneeded */
+	ret = gpio_aggregator_alloc(&aggr, 0);
+	if (ret)
+		return ERR_PTR(ret);
+
+	config_group_init_type_name(&aggr->group, name, &gpio_aggregator_device_type);
+	dev_sync_probe_init(&aggr->probe_data);
+
+	return &aggr->group;
+}
+
+static struct configfs_group_operations gpio_aggregator_group_ops = {
+	.make_group	= gpio_aggregator_make_group,
+};
+
+static const struct config_item_type gpio_aggregator_type = {
+	.ct_group_ops	= &gpio_aggregator_group_ops,
+	.ct_owner	= THIS_MODULE,
+};
+
+static struct configfs_subsystem gpio_aggregator_subsys = {
+	.su_group = {
+		.cg_item = {
+			.ci_namebuf	= DRV_NAME,
+			.ci_type	= &gpio_aggregator_type,
+		},
+	},
+};
+
+/*
+ * Sysfs interface
+ */
+static int gpio_aggregator_parse(struct gpio_aggregator *aggr)
+{
+	char *args = skip_spaces(aggr->args);
+	struct gpio_aggregator_line *line;
+	char name[CONFIGFS_ITEM_NAME_LEN];
+	char *key, *offsets, *p;
+	unsigned int i, n = 0;
+	int error = 0;
+
+	unsigned long *bitmap __free(bitmap) =
+			bitmap_alloc(AGGREGATOR_MAX_GPIOS, GFP_KERNEL);
+	if (!bitmap)
+		return -ENOMEM;
+
+	args = next_arg(args, &key, &p);
+	while (*args) {
+		args = next_arg(args, &offsets, &p);
+
+		p = get_options(offsets, 0, &error);
+		if (error == 0 || *p) {
+			/* Named GPIO line */
+			scnprintf(name, sizeof(name), "line%u", n);
+			line = gpio_aggregator_line_alloc(aggr, n, key, -1);
+			if (IS_ERR(line)) {
+				error = PTR_ERR(line);
+				goto err;
+			}
+			config_group_init_type_name(&line->group, name,
+						    &gpio_aggregator_line_type);
+			error = configfs_register_group(&aggr->group,
+							&line->group);
+			if (error)
+				goto err;
+			scoped_guard(mutex, &aggr->lock)
+				gpio_aggregator_line_add(aggr, line);
+
+			error = gpio_aggregator_add_gpio(aggr, key, U16_MAX, &n);
+			if (error)
+				goto err;
+
+			key = offsets;
+			continue;
+		}
+
+		/* GPIO chip + offset(s) */
+		error = bitmap_parselist(offsets, bitmap, AGGREGATOR_MAX_GPIOS);
+		if (error) {
+			pr_err("Cannot parse %s: %d\n", offsets, error);
+			goto err;
+		}
+
+		for_each_set_bit(i, bitmap, AGGREGATOR_MAX_GPIOS) {
+			scnprintf(name, sizeof(name), "line%u", n);
+			line = gpio_aggregator_line_alloc(aggr, n, key, i);
+			if (IS_ERR(line)) {
+				error = PTR_ERR(line);
+				goto err;
+			}
+			config_group_init_type_name(&line->group, name,
+						    &gpio_aggregator_line_type);
+			error = configfs_register_group(&aggr->group,
+							&line->group);
+			if (error)
+				goto err;
+			scoped_guard(mutex, &aggr->lock)
+				gpio_aggregator_line_add(aggr, line);
+
+			error = gpio_aggregator_add_gpio(aggr, key, i, &n);
+			if (error)
+				goto err;
+		}
+
+		args = next_arg(args, &key, &p);
+	}
+
+	if (!n) {
+		pr_err("No GPIOs specified\n");
+		error = -EINVAL;
+		goto err;
+	}
+
+	return 0;
+
+err:
+	gpio_aggregator_free_lines(aggr);
+	return error;
+}
+
+static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver,
+						const char *buf, size_t count)
+{
+	struct gpio_aggregator_pdev_meta meta = { .init_via_sysfs = true };
+	char name[CONFIGFS_ITEM_NAME_LEN];
+	struct gpio_aggregator *aggr;
+	struct platform_device *pdev;
+	int res;
+
+	if (!try_module_get(THIS_MODULE))
+		return -ENOENT;
+
+	/* kernfs guarantees string termination, so count + 1 is safe */
+	res = gpio_aggregator_alloc(&aggr, count + 1);
+	if (res)
+		goto put_module;
+
+	memcpy(aggr->args, buf, count + 1);
+
+	aggr->init_via_sysfs = true;
+	aggr->lookups = kzalloc(struct_size(aggr->lookups, table, 1),
+				GFP_KERNEL);
+	if (!aggr->lookups) {
+		res = -ENOMEM;
+		goto free_ga;
+	}
+
+	aggr->lookups->dev_id = kasprintf(GFP_KERNEL, "%s.%d", DRV_NAME, aggr->id);
+	if (!aggr->lookups->dev_id) {
+		res = -ENOMEM;
+		goto free_table;
+	}
+
+	scnprintf(name, sizeof(name), "%s.%d", AGGREGATOR_LEGACY_PREFIX, aggr->id);
+	config_group_init_type_name(&aggr->group, name, &gpio_aggregator_device_type);
+
+	/*
+	 * Since the device created by sysfs might be toggled via configfs
+	 * 'live' attribute later, this initialization is needed.
+	 */
+	dev_sync_probe_init(&aggr->probe_data);
+
+	/* Expose to configfs */
+	res = configfs_register_group(&gpio_aggregator_subsys.su_group,
+				      &aggr->group);
+	if (res)
+		goto free_dev_id;
+
+	res = gpio_aggregator_parse(aggr);
+	if (res)
+		goto unregister_group;
+
+	gpiod_add_lookup_table(aggr->lookups);
+
+	pdev = platform_device_register_data(NULL, DRV_NAME, aggr->id, &meta, sizeof(meta));
+	if (IS_ERR(pdev)) {
+		res = PTR_ERR(pdev);
+		goto remove_table;
+	}
+
+	aggr->probe_data.pdev = pdev;
+	module_put(THIS_MODULE);
+	return count;
+
+remove_table:
+	gpiod_remove_lookup_table(aggr->lookups);
+unregister_group:
+	configfs_unregister_group(&aggr->group);
+free_dev_id:
+	kfree(aggr->lookups->dev_id);
+free_table:
+	kfree(aggr->lookups);
+free_ga:
+	gpio_aggregator_free(aggr);
+put_module:
+	module_put(THIS_MODULE);
+	return res;
+}
+
+static struct driver_attribute driver_attr_gpio_aggregator_new_device =
+	__ATTR(new_device, 0200, NULL, gpio_aggregator_new_device_store);
+
+static void gpio_aggregator_destroy(struct gpio_aggregator *aggr)
+{
+	scoped_guard(mutex, &aggr->lock) {
+		if (gpio_aggregator_is_activating(aggr) ||
+		    gpio_aggregator_is_active(aggr))
+			gpio_aggregator_deactivate(aggr);
+	}
+	gpio_aggregator_free_lines(aggr);
+	configfs_unregister_group(&aggr->group);
+	kfree(aggr);
+}
+
+static ssize_t gpio_aggregator_delete_device_store(struct device_driver *driver,
+						   const char *buf, size_t count)
+{
+	struct gpio_aggregator *aggr;
+	unsigned int id;
+	int error;
+
+	if (!str_has_prefix(buf, DRV_NAME "."))
+		return -EINVAL;
+
+	error = kstrtouint(buf + strlen(DRV_NAME "."), 10, &id);
+	if (error)
+		return error;
+
+	if (!try_module_get(THIS_MODULE))
+		return -ENOENT;
+
+	mutex_lock(&gpio_aggregator_lock);
+	aggr = idr_find(&gpio_aggregator_idr, id);
+	/*
+	 * For simplicity, devices created via configfs cannot be deleted
+	 * via sysfs.
+	 */
+	if (aggr && aggr->init_via_sysfs)
+		idr_remove(&gpio_aggregator_idr, id);
+	else {
+		mutex_unlock(&gpio_aggregator_lock);
+		module_put(THIS_MODULE);
+		return -ENOENT;
+	}
+	mutex_unlock(&gpio_aggregator_lock);
+
+	gpio_aggregator_destroy(aggr);
+	module_put(THIS_MODULE);
+	return count;
+}
+
+static struct driver_attribute driver_attr_gpio_aggregator_delete_device =
+	__ATTR(delete_device, 0200, NULL, gpio_aggregator_delete_device_store);
+
+static struct attribute *gpio_aggregator_attrs[] = {
+	&driver_attr_gpio_aggregator_new_device.attr,
+	&driver_attr_gpio_aggregator_delete_device.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(gpio_aggregator);
 
 /*
  *  GPIO Aggregator platform device
@@ -567,7 +1278,9 @@
 
 static int gpio_aggregator_probe(struct platform_device *pdev)
 {
+	struct gpio_aggregator_pdev_meta *meta;
 	struct device *dev = &pdev->dev;
+	bool init_via_sysfs = false;
 	struct gpio_desc **descs;
 	struct gpiochip_fwd *fwd;
 	unsigned long features;
@@ -581,10 +1294,28 @@
 	if (!descs)
 		return -ENOMEM;
 
+	meta = dev_get_platdata(&pdev->dev);
+	if (meta && meta->init_via_sysfs)
+		init_via_sysfs = true;
+
 	for (i = 0; i < n; i++) {
 		descs[i] = devm_gpiod_get_index(dev, NULL, i, GPIOD_ASIS);
-		if (IS_ERR(descs[i]))
+		if (IS_ERR(descs[i])) {
+			/*
+			 * Deferred probing is not suitable when the aggregator
+			 * is created via configfs. They should just retry later
+			 * whenever they like. For device creation via sysfs,
+			 * error is propagated without overriding for backward
+			 * compatibility. .prevent_deferred_probe is kept unset
+			 * for other cases.
+			 */
+			if (!init_via_sysfs && !dev_of_node(dev) &&
+			    descs[i] == ERR_PTR(-EPROBE_DEFER)) {
+				pr_warn("Deferred probe canceled for creation via configfs.\n");
+				return -ENODEV;
+			}
 			return PTR_ERR(descs[i]);
+		}
 	}
 
 	features = (uintptr_t)device_get_match_data(dev);
@@ -618,9 +1349,63 @@
 	},
 };
 
+static int __exit gpio_aggregator_idr_remove(int id, void *p, void *data)
+{
+	/*
+	 * There should be no aggregator created via configfs, as their
+	 * presence would prevent module unloading.
+	 */
+	gpio_aggregator_destroy(p);
+	return 0;
+}
+
+static void __exit gpio_aggregator_remove_all(void)
+{
+	/*
+	 * Configfs callbacks acquire gpio_aggregator_lock when accessing
+	 * gpio_aggregator_idr, so to prevent lock inversion deadlock, we
+	 * cannot protect idr_for_each invocation here with
+	 * gpio_aggregator_lock, as gpio_aggregator_idr_remove() accesses
+	 * configfs groups. Fortunately, the new_device/delete_device path
+	 * and the module unload path are mutually exclusive, thanks to an
+	 * explicit try_module_get inside of those driver attr handlers.
+	 * Also, when we reach here, no configfs entries present or being
+	 * created. Therefore, no need to protect with gpio_aggregator_lock
+	 * below.
+	 */
+	idr_for_each(&gpio_aggregator_idr, gpio_aggregator_idr_remove, NULL);
+	idr_destroy(&gpio_aggregator_idr);
+}
+
 static int __init gpio_aggregator_init(void)
 {
-	return platform_driver_register(&gpio_aggregator_driver);
+	int ret = 0;
+
+	config_group_init(&gpio_aggregator_subsys.su_group);
+	mutex_init(&gpio_aggregator_subsys.su_mutex);
+	ret = configfs_register_subsystem(&gpio_aggregator_subsys);
+	if (ret) {
+		pr_err("Failed to register the '%s' configfs subsystem: %d\n",
+		       gpio_aggregator_subsys.su_group.cg_item.ci_namebuf, ret);
+		mutex_destroy(&gpio_aggregator_subsys.su_mutex);
+		return ret;
+	}
+
+	/*
+	 * CAVEAT: This must occur after configfs registration. Otherwise,
+	 * a race condition could arise: driver attribute groups might be
+	 * exposed and accessed by users before configfs registration
+	 * completes. new_device_store() does not expect a partially
+	 * initialized configfs state.
+	 */
+	ret = platform_driver_register(&gpio_aggregator_driver);
+	if (ret) {
+		pr_err("Failed to register the platform driver: %d\n", ret);
+		mutex_destroy(&gpio_aggregator_subsys.su_mutex);
+		configfs_unregister_subsystem(&gpio_aggregator_subsys);
+	}
+
+	return ret;
 }
 module_init(gpio_aggregator_init);
 
@@ -628,6 +1413,7 @@
 {
 	gpio_aggregator_remove_all();
 	platform_driver_unregister(&gpio_aggregator_driver);
+	configfs_unregister_subsystem(&gpio_aggregator_subsys);
 }
 module_exit(gpio_aggregator_exit);
 
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-aspeed.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-aspeed.c
@@ -406,6 +406,8 @@
 	gpio->dcache[GPIO_BANK(offset)] = reg;
 
 	iowrite32(reg, addr);
+	/* Flush write */
+	ioread32(addr);
 }
 
 static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset,
@@ -1191,7 +1193,7 @@
 	if (!gpio_id)
 		return -EINVAL;
 
-	gpio->clk = of_clk_get(pdev->dev.of_node, 0);
+	gpio->clk = devm_clk_get_enabled(&pdev->dev, NULL);
 	if (IS_ERR(gpio->clk)) {
 		dev_warn(&pdev->dev,
 				"Failed to get clock from devicetree, debouncing disabled\n");
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-brcmstb.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-brcmstb.c
@@ -592,8 +592,6 @@
 	void __iomem *reg_base;
 	struct brcmstb_gpio_priv *priv;
 	struct resource *res;
-	struct property *prop;
-	const __be32 *p;
 	u32 bank_width;
 	int num_banks = 0;
 	int err;
@@ -638,8 +636,7 @@
 	flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER;
 #endif
 
-	of_property_for_each_u32(np, "brcm,gpio-bank-widths", prop, p,
-			bank_width) {
+	of_property_for_each_u32(np, "brcm,gpio-bank-widths", bank_width) {
 		struct brcmstb_gpio_bank *bank;
 		struct gpio_chip *gc;
 
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-crystalcove.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-crystalcove.c
@@ -92,7 +92,7 @@
 		case 0x5e:
 			return GPIOPANELCTL;
 		default:
-			return -EOPNOTSUPP;
+			return -ENOTSUPP;
 		}
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-davinci.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-davinci.c
@@ -225,6 +225,11 @@
 	else
 		nirq = DIV_ROUND_UP(ngpio, 16);
 
+	if (nirq > MAX_INT_PER_BANK) {
+		dev_err(dev, "Too many IRQs!\n");
+		return -EINVAL;
+	}
+
 	chips = devm_kzalloc(dev, sizeof(*chips), GFP_KERNEL);
 	if (!chips)
 		return -ENOMEM;
@@ -284,7 +289,7 @@
  * serve as EDMA event triggers.
  */
 
-static void gpio_irq_disable(struct irq_data *d)
+static void gpio_irq_mask(struct irq_data *d)
 {
 	struct davinci_gpio_regs __iomem *g = irq2regs(d);
 	uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d);
@@ -293,7 +298,7 @@
 	writel_relaxed(mask, &g->clr_rising);
 }
 
-static void gpio_irq_enable(struct irq_data *d)
+static void gpio_irq_unmask(struct irq_data *d)
 {
 	struct davinci_gpio_regs __iomem *g = irq2regs(d);
 	uintptr_t mask = (uintptr_t)irq_data_get_irq_handler_data(d);
@@ -319,8 +324,8 @@
 
 static struct irq_chip gpio_irqchip = {
 	.name		= "GPIO",
-	.irq_enable	= gpio_irq_enable,
-	.irq_disable	= gpio_irq_disable,
+	.irq_unmask	= gpio_irq_unmask,
+	.irq_mask	= gpio_irq_mask,
 	.irq_set_type	= gpio_irq_type,
 	.flags		= IRQCHIP_SET_TYPE_MASKED | IRQCHIP_SKIP_SET_WAKE,
 };
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-exar.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-exar.c
@@ -99,11 +99,13 @@
 	struct exar_gpio_chip *exar_gpio = gpiochip_get_data(chip);
 	unsigned int addr = exar_offset_to_lvl_addr(exar_gpio, offset);
 	unsigned int bit = exar_offset_to_bit(exar_gpio, offset);
+	unsigned int bit_value = value ? BIT(bit) : 0;
 
-	if (value)
-		regmap_set_bits(exar_gpio->regmap, addr, BIT(bit));
-	else
-		regmap_clear_bits(exar_gpio->regmap, addr, BIT(bit));
+	/*
+	 * regmap_write_bits() forces value to be written when an external
+	 * pull up/down might otherwise indicate value was already set.
+	 */
+	regmap_write_bits(exar_gpio->regmap, addr, BIT(bit), bit_value);
 }
 
 static int exar_direction_output(struct gpio_chip *chip, unsigned int offset,
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-grgpio.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-grgpio.c
@@ -328,6 +328,7 @@
 static int grgpio_probe(struct platform_device *ofdev)
 {
 	struct device_node *np = ofdev->dev.of_node;
+	struct device *dev = &ofdev->dev;
 	void  __iomem *regs;
 	struct gpio_chip *gc;
 	struct grgpio_priv *priv;
@@ -337,7 +338,7 @@
 	int size;
 	int i;
 
-	priv = devm_kzalloc(&ofdev->dev, sizeof(*priv), GFP_KERNEL);
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
@@ -346,28 +347,31 @@
 		return PTR_ERR(regs);
 
 	gc = &priv->gc;
-	err = bgpio_init(gc, &ofdev->dev, 4, regs + GRGPIO_DATA,
+	err = bgpio_init(gc, dev, 4, regs + GRGPIO_DATA,
 			 regs + GRGPIO_OUTPUT, NULL, regs + GRGPIO_DIR, NULL,
 			 BGPIOF_BIG_ENDIAN_BYTE_ORDER);
 	if (err) {
-		dev_err(&ofdev->dev, "bgpio_init() failed\n");
+		dev_err(dev, "bgpio_init() failed\n");
 		return err;
 	}
 
 	priv->regs = regs;
 	priv->imask = gc->read_reg(regs + GRGPIO_IMASK);
-	priv->dev = &ofdev->dev;
+	priv->dev = dev;
 
 	gc->owner = THIS_MODULE;
 	gc->to_irq = grgpio_to_irq;
-	gc->label = devm_kasprintf(&ofdev->dev, GFP_KERNEL, "%pOF", np);
+	gc->label = devm_kasprintf(dev, GFP_KERNEL, "%pOF", np);
+	if (!gc->label)
+		return -ENOMEM;
+
 	gc->base = -1;
 
 	err = of_property_read_u32(np, "nbits", &prop);
 	if (err || prop <= 0 || prop > GRGPIO_MAX_NGPIO) {
 		gc->ngpio = GRGPIO_MAX_NGPIO;
-		dev_dbg(&ofdev->dev,
-			"No or invalid nbits property: assume %d\n", gc->ngpio);
+		dev_dbg(dev, "No or invalid nbits property: assume %d\n",
+			gc->ngpio);
 	} else {
 		gc->ngpio = prop;
 	}
@@ -379,7 +383,7 @@
 	irqmap = (s32 *)of_get_property(np, "irqmap", &size);
 	if (irqmap) {
 		if (size < gc->ngpio) {
-			dev_err(&ofdev->dev,
+			dev_err(dev,
 				"irqmap shorter than ngpio (%d < %d)\n",
 				size, gc->ngpio);
 			return -EINVAL;
@@ -389,7 +393,7 @@
 						     &grgpio_irq_domain_ops,
 						     priv);
 		if (!priv->domain) {
-			dev_err(&ofdev->dev, "Could not add irq domain\n");
+			dev_err(dev, "Could not add irq domain\n");
 			return -EINVAL;
 		}
 
@@ -419,13 +423,13 @@
 
 	err = gpiochip_add_data(gc, priv);
 	if (err) {
-		dev_err(&ofdev->dev, "Could not add gpiochip\n");
+		dev_err(dev, "Could not add gpiochip\n");
 		if (priv->domain)
 			irq_domain_remove(priv->domain);
 		return err;
 	}
 
-	dev_info(&ofdev->dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n",
+	dev_info(dev, "regs=0x%p, base=%d, ngpio=%d, irqs=%s\n",
 		 priv->regs, gc->base, gc->ngpio, priv->domain ? "on" : "off");
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-ljca.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-ljca.c
@@ -82,9 +82,9 @@
 	int ret;
 
 	mutex_lock(&ljca_gpio->trans_lock);
+	packet->num = 1;
 	packet->item[0].index = gpio_id;
 	packet->item[0].value = config | ljca_gpio->connect_mode[gpio_id];
-	packet->num = 1;
 
 	ret = ljca_transfer(ljca_gpio->ljca, LJCA_GPIO_CONFIG, (u8 *)packet,
 			    struct_size(packet, item, packet->num), NULL, 0);
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-loongson-64bit.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-loongson-64bit.c
@@ -237,9 +237,9 @@
 static const struct loongson_gpio_chip_data loongson_gpio_ls2k2000_data2 = {
 	.label = "ls2k2000_gpio",
 	.mode = BIT_CTRL_MODE,
-	.conf_offset = 0x84,
-	.in_offset = 0x88,
-	.out_offset = 0x80,
+	.conf_offset = 0x4,
+	.in_offset = 0x8,
+	.out_offset = 0x0,
 };
 
 static const struct loongson_gpio_chip_data loongson_gpio_ls3a5000_data = {
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-lpc32xx.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-lpc32xx.c
@@ -529,6 +529,7 @@
 	{ .compatible = "nxp,lpc3220-gpio", },
 	{ },
 };
+MODULE_DEVICE_TABLE(of, lpc32xx_gpio_of_match);
 
 static struct platform_driver lpc32xx_gpio_driver = {
 	.driver		= {
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-mlxbf3.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-mlxbf3.c
@@ -39,6 +39,8 @@
 #define MLXBF_GPIO_CAUSE_OR_EVTEN0        0x14
 #define MLXBF_GPIO_CAUSE_OR_CLRCAUSE      0x18
 
+#define MLXBF_GPIO_CLR_ALL_INTS           GENMASK(31, 0)
+
 struct mlxbf3_gpio_context {
 	struct gpio_chip gc;
 
@@ -82,6 +84,8 @@
 	val = readl(gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
 	val &= ~BIT(offset);
 	writel(val, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
+
+	writel(BIT(offset), gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
 	raw_spin_unlock_irqrestore(&gs->gc.bgpio_lock, flags);
 
 	gpiochip_disable_irq(gc, offset);
@@ -253,6 +257,15 @@
 	return 0;
 }
 
+static void mlxbf3_gpio_shutdown(struct platform_device *pdev)
+{
+	struct mlxbf3_gpio_context *gs = platform_get_drvdata(pdev);
+
+	/* Disable and clear all interrupts */
+	writel(0, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_EVTEN0);
+	writel(MLXBF_GPIO_CLR_ALL_INTS, gs->gpio_cause_io + MLXBF_GPIO_CAUSE_OR_CLRCAUSE);
+}
+
 static const struct acpi_device_id mlxbf3_gpio_acpi_match[] = {
 	{ "MLNXBF33", 0 },
 	{}
@@ -265,6 +278,7 @@
 		.acpi_match_table = mlxbf3_gpio_acpi_match,
 	},
 	.probe    = mlxbf3_gpio_probe,
+	.shutdown = mlxbf3_gpio_shutdown,
 };
 module_platform_driver(mlxbf3_gpio_driver);
 
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-mmio.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-mmio.c
@@ -619,8 +619,6 @@
 	ret = gpiochip_get_ngpios(gc, dev);
 	if (ret)
 		gc->ngpio = gc->bgpio_bits;
-	else
-		gc->bgpio_bits = roundup_pow_of_two(round_up(gc->ngpio, 8));
 
 	ret = bgpio_setup_io(gc, dat, set, clr, flags);
 	if (ret)
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-mxc.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-mxc.c
@@ -490,8 +490,7 @@
 	port->gc.request = mxc_gpio_request;
 	port->gc.free = mxc_gpio_free;
 	port->gc.to_irq = mxc_gpio_to_irq;
-	port->gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 :
-					     pdev->id * 32;
+	port->gc.base = of_alias_get_id(np, "gpio") * 32;
 
 	err = devm_gpiochip_add_data(&pdev->dev, &port->gc, port);
 	if (err)
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-npcm-sgpio.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-npcm-sgpio.c
@@ -434,7 +434,7 @@
 	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
 	struct irq_chip *ic = irq_desc_get_chip(desc);
 	struct npcm_sgpio *gpio = gpiochip_get_data(gc);
-	unsigned int i, j, girq;
+	unsigned int i, j;
 	unsigned long reg;
 
 	chained_irq_enter(ic, desc);
@@ -443,11 +443,9 @@
 		const struct npcm_sgpio_bank *bank = &npcm_sgpio_banks[i];
 
 		reg = ioread8(bank_reg(gpio, bank, EVENT_STS));
-		for_each_set_bit(j, &reg, 8) {
-			girq = irq_find_mapping(gc->irq.domain,
-						i * 8 + gpio->nout_sgpio + j);
-			generic_handle_domain_irq(gc->irq.domain, girq);
-		}
+		for_each_set_bit(j, &reg, 8)
+			generic_handle_domain_irq(gc->irq.domain,
+						  i * 8 + gpio->nout_sgpio + j);
 	}
 
 	chained_irq_exit(ic, desc);
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-pca953x.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-pca953x.c
@@ -758,6 +758,8 @@
 	int level;
 
 	if (chip->driver_data & PCA_PCAL) {
+		guard(mutex)(&chip->i2c_lock);
+
 		/* Enable latch on interrupt-enabled inputs */
 		pca953x_write_regs(chip, PCAL953X_IN_LATCH, chip->irq_mask);
 
@@ -839,25 +841,6 @@
 	DECLARE_BITMAP(trigger, MAX_LINE);
 	int ret;
 
-	if (chip->driver_data & PCA_PCAL) {
-		/* Read the current interrupt status from the device */
-		ret = pca953x_read_regs(chip, PCAL953X_INT_STAT, trigger);
-		if (ret)
-			return false;
-
-		/* Check latched inputs and clear interrupt status */
-		ret = pca953x_read_regs(chip, chip->regs->input, cur_stat);
-		if (ret)
-			return false;
-
-		/* Apply filter for rising/falling edge selection */
-		bitmap_replace(new_stat, chip->irq_trig_fall, chip->irq_trig_raise, cur_stat, gc->ngpio);
-
-		bitmap_and(pending, new_stat, trigger, gc->ngpio);
-
-		return !bitmap_empty(pending, gc->ngpio);
-	}
-
 	ret = pca953x_read_regs(chip, chip->regs->input, cur_stat);
 	if (ret)
 		return false;
@@ -1086,7 +1069,8 @@
 		 */
 		reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
 		if (IS_ERR(reset_gpio))
-			return PTR_ERR(reset_gpio);
+			return dev_err_probe(dev, PTR_ERR(reset_gpio),
+					     "Failed to get reset gpio\n");
 	}
 
 	chip->client = client;
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-rockchip.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-rockchip.c
@@ -713,6 +713,7 @@
 		return -ENODEV;
 
 	pctldev = of_pinctrl_get(pctlnp);
+	of_node_put(pctlnp);
 	if (!pctldev)
 		return -EPROBE_DEFER;
 
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-sim.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-sim.c
@@ -1009,6 +1009,33 @@
 	dev->pdev = NULL;
 }
 
+static void
+gpio_sim_device_lockup_configfs(struct gpio_sim_device *dev, bool lock)
+{
+	struct configfs_subsystem *subsys = dev->group.cg_subsys;
+	struct gpio_sim_bank *bank;
+	struct gpio_sim_line *line;
+	struct config_item *item;
+
+	/*
+	 * The device only needs to depend on leaf entries. This is
+	 * sufficient to lock up all the configfs entries that the
+	 * instantiated, alive device depends on.
+	 */
+	list_for_each_entry(bank, &dev->bank_list, siblings) {
+		list_for_each_entry(line, &bank->line_list, siblings) {
+			item = line->hog ? &line->hog->item
+					 : &line->group.cg_item;
+
+			if (lock)
+				WARN_ON(configfs_depend_item_unlocked(subsys,
+								      item));
+			else
+				configfs_undepend_item_unlocked(item);
+		}
+	}
+}
+
 static ssize_t
 gpio_sim_device_config_live_store(struct config_item *item,
 				  const char *page, size_t count)
@@ -1021,14 +1048,24 @@
 	if (ret)
 		return ret;
 
-	guard(mutex)(&dev->lock);
+	if (live)
+		gpio_sim_device_lockup_configfs(dev, true);
+
+	scoped_guard(mutex, &dev->lock) {
+		if (live == gpio_sim_device_is_live_unlocked(dev))
+			ret = -EPERM;
+		else if (live)
+			ret = gpio_sim_device_activate_unlocked(dev);
+		else
+			gpio_sim_device_deactivate_unlocked(dev);
+	}
 
-	if (live == gpio_sim_device_is_live_unlocked(dev))
-		ret = -EPERM;
-	else if (live)
-		ret = gpio_sim_device_activate_unlocked(dev);
-	else
-		gpio_sim_device_deactivate_unlocked(dev);
+	/*
+	 * Undepend is required only if device disablement (live == 0)
+	 * succeeds or if device enablement (live == 1) fails.
+	 */
+	if (live == !!ret)
+		gpio_sim_device_lockup_configfs(dev, false);
 
 	return ret ?: count;
 }
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-tangier.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-tangier.c
@@ -195,7 +195,8 @@
 
 static void tng_irq_ack(struct irq_data *d)
 {
-	struct tng_gpio *priv = irq_data_get_irq_chip_data(d);
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct tng_gpio *priv = gpiochip_get_data(gc);
 	irq_hw_number_t gpio = irqd_to_hwirq(d);
 	void __iomem *gisr;
 	u8 shift;
@@ -227,7 +228,8 @@
 
 static void tng_irq_mask(struct irq_data *d)
 {
-	struct tng_gpio *priv = irq_data_get_irq_chip_data(d);
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct tng_gpio *priv = gpiochip_get_data(gc);
 	irq_hw_number_t gpio = irqd_to_hwirq(d);
 
 	tng_irq_unmask_mask(priv, gpio, false);
@@ -236,7 +238,8 @@
 
 static void tng_irq_unmask(struct irq_data *d)
 {
-	struct tng_gpio *priv = irq_data_get_irq_chip_data(d);
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct tng_gpio *priv = gpiochip_get_data(gc);
 	irq_hw_number_t gpio = irqd_to_hwirq(d);
 
 	gpiochip_enable_irq(&priv->chip, gpio);
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-tegra186.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-tegra186.c
@@ -36,12 +36,6 @@
 #define  TEGRA186_GPIO_SCR_SEC_REN		BIT(27)
 #define  TEGRA186_GPIO_SCR_SEC_G1W		BIT(9)
 #define  TEGRA186_GPIO_SCR_SEC_G1R		BIT(1)
-#define  TEGRA186_GPIO_FULL_ACCESS		(TEGRA186_GPIO_SCR_SEC_WEN | \
-						 TEGRA186_GPIO_SCR_SEC_REN | \
-						 TEGRA186_GPIO_SCR_SEC_G1R | \
-						 TEGRA186_GPIO_SCR_SEC_G1W)
-#define  TEGRA186_GPIO_SCR_SEC_ENABLE		(TEGRA186_GPIO_SCR_SEC_WEN | \
-						 TEGRA186_GPIO_SCR_SEC_REN)
 
 /* control registers */
 #define TEGRA186_GPIO_ENABLE_CONFIG 0x00
@@ -177,10 +171,18 @@
 
 	value = __raw_readl(secure + TEGRA186_GPIO_SCR);
 
-	if ((value & TEGRA186_GPIO_SCR_SEC_ENABLE) == 0)
-		return true;
-
-	if ((value & TEGRA186_GPIO_FULL_ACCESS) == TEGRA186_GPIO_FULL_ACCESS)
+	/*
+	 * When SCR_SEC_[R|W]EN is unset, then we have full read/write access to all the
+	 * registers for given GPIO pin.
+	 * When SCR_SEC[R|W]EN is set, then there is need to further check the accompanying
+	 * SCR_SEC_G1[R|W] bit to determine read/write access to all the registers for given
+	 * GPIO pin.
+	 */
+
+	if (((value & TEGRA186_GPIO_SCR_SEC_REN) == 0 ||
+	     ((value & TEGRA186_GPIO_SCR_SEC_REN) && (value & TEGRA186_GPIO_SCR_SEC_G1R))) &&
+	     ((value & TEGRA186_GPIO_SCR_SEC_WEN) == 0 ||
+	     ((value & TEGRA186_GPIO_SCR_SEC_WEN) && (value & TEGRA186_GPIO_SCR_SEC_G1W))))
 		return true;
 
 	return false;
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-tqmx86.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-tqmx86.c
@@ -6,6 +6,7 @@
  *   Vadim V.Vlasov <vvlasov@dev.rtsoft.ru>
  */
 
+#include <linux/bitmap.h>
 #include <linux/bitops.h>
 #include <linux/errno.h>
 #include <linux/gpio/driver.h>
@@ -28,16 +29,25 @@
 #define TQMX86_GPIIC	3	/* GPI Interrupt Configuration Register */
 #define TQMX86_GPIIS	4	/* GPI Interrupt Status Register */
 
+#define TQMX86_GPII_NONE	0
 #define TQMX86_GPII_FALLING	BIT(0)
 #define TQMX86_GPII_RISING	BIT(1)
+/* Stored in irq_type as a trigger type, but not actually valid as a register
+ * value, so the name doesn't use "GPII"
+ */
+#define TQMX86_INT_BOTH		(BIT(0) | BIT(1))
 #define TQMX86_GPII_MASK	(BIT(0) | BIT(1))
 #define TQMX86_GPII_BITS	2
+/* Stored in irq_type with GPII bits */
+#define TQMX86_INT_UNMASKED	BIT(2)
 
 struct tqmx86_gpio_data {
 	struct gpio_chip	chip;
 	void __iomem		*io_base;
 	int			irq;
+	/* Lock must be held for accessing output and irq_type fields */
 	raw_spinlock_t		spinlock;
+	DECLARE_BITMAP(output, TQMX86_NGPIO);
 	u8			irq_type[TQMX86_NGPI];
 };
 
@@ -64,15 +74,10 @@
 {
 	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
 	unsigned long flags;
-	u8 val;
 
 	raw_spin_lock_irqsave(&gpio->spinlock, flags);
-	val = tqmx86_gpio_read(gpio, TQMX86_GPIOD);
-	if (value)
-		val |= BIT(offset);
-	else
-		val &= ~BIT(offset);
-	tqmx86_gpio_write(gpio, val, TQMX86_GPIOD);
+	__assign_bit(offset, gpio->output, value);
+	tqmx86_gpio_write(gpio, bitmap_get_value8(gpio->output, 0), TQMX86_GPIOD);
 	raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
 }
 
@@ -107,21 +112,38 @@
 	return GPIO_LINE_DIRECTION_OUT;
 }
 
+static void tqmx86_gpio_irq_config(struct tqmx86_gpio_data *gpio, int offset)
+	__must_hold(&gpio->spinlock)
+{
+	u8 type = TQMX86_GPII_NONE, gpiic;
+
+	if (gpio->irq_type[offset] & TQMX86_INT_UNMASKED) {
+		type = gpio->irq_type[offset] & TQMX86_GPII_MASK;
+
+		if (type == TQMX86_INT_BOTH)
+			type = tqmx86_gpio_get(&gpio->chip, offset + TQMX86_NGPO)
+				? TQMX86_GPII_FALLING
+				: TQMX86_GPII_RISING;
+	}
+
+	gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
+	gpiic &= ~(TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS));
+	gpiic |= type << (offset * TQMX86_GPII_BITS);
+	tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
+}
+
 static void tqmx86_gpio_irq_mask(struct irq_data *data)
 {
 	unsigned int offset = (data->hwirq - TQMX86_NGPO);
 	struct tqmx86_gpio_data *gpio = gpiochip_get_data(
 		irq_data_get_irq_chip_data(data));
 	unsigned long flags;
-	u8 gpiic, mask;
-
-	mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
 
 	raw_spin_lock_irqsave(&gpio->spinlock, flags);
-	gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
-	gpiic &= ~mask;
-	tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
+	gpio->irq_type[offset] &= ~TQMX86_INT_UNMASKED;
+	tqmx86_gpio_irq_config(gpio, offset);
 	raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
+
 	gpiochip_disable_irq(&gpio->chip, irqd_to_hwirq(data));
 }
 
@@ -131,16 +153,12 @@
 	struct tqmx86_gpio_data *gpio = gpiochip_get_data(
 		irq_data_get_irq_chip_data(data));
 	unsigned long flags;
-	u8 gpiic, mask;
-
-	mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
 
 	gpiochip_enable_irq(&gpio->chip, irqd_to_hwirq(data));
+
 	raw_spin_lock_irqsave(&gpio->spinlock, flags);
-	gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
-	gpiic &= ~mask;
-	gpiic |= gpio->irq_type[offset] << (offset * TQMX86_GPII_BITS);
-	tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
+	gpio->irq_type[offset] |= TQMX86_INT_UNMASKED;
+	tqmx86_gpio_irq_config(gpio, offset);
 	raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
 }
 
@@ -151,7 +169,7 @@
 	unsigned int offset = (data->hwirq - TQMX86_NGPO);
 	unsigned int edge_type = type & IRQF_TRIGGER_MASK;
 	unsigned long flags;
-	u8 new_type, gpiic;
+	u8 new_type;
 
 	switch (edge_type) {
 	case IRQ_TYPE_EDGE_RISING:
@@ -161,19 +179,16 @@
 		new_type = TQMX86_GPII_FALLING;
 		break;
 	case IRQ_TYPE_EDGE_BOTH:
-		new_type = TQMX86_GPII_FALLING | TQMX86_GPII_RISING;
+		new_type = TQMX86_INT_BOTH;
 		break;
 	default:
 		return -EINVAL; /* not supported */
 	}
 
-	gpio->irq_type[offset] = new_type;
-
 	raw_spin_lock_irqsave(&gpio->spinlock, flags);
-	gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
-	gpiic &= ~((TQMX86_GPII_MASK) << (offset * TQMX86_GPII_BITS));
-	gpiic |= new_type << (offset * TQMX86_GPII_BITS);
-	tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
+	gpio->irq_type[offset] &= ~TQMX86_GPII_MASK;
+	gpio->irq_type[offset] |= new_type;
+	tqmx86_gpio_irq_config(gpio, offset);
 	raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
 
 	return 0;
@@ -184,8 +199,8 @@
 	struct gpio_chip *chip = irq_desc_get_handler_data(desc);
 	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
 	struct irq_chip *irq_chip = irq_desc_get_chip(desc);
-	unsigned long irq_bits;
-	int i = 0;
+	unsigned long irq_bits, flags;
+	int i;
 	u8 irq_status;
 
 	chained_irq_enter(irq_chip, desc);
@@ -194,6 +209,34 @@
 	tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
 
 	irq_bits = irq_status;
+
+	raw_spin_lock_irqsave(&gpio->spinlock, flags);
+	for_each_set_bit(i, &irq_bits, TQMX86_NGPI) {
+		/*
+		 * Edge-both triggers are implemented by flipping the edge
+		 * trigger after each interrupt, as the controller only supports
+		 * either rising or falling edge triggers, but not both.
+		 *
+		 * Internally, the TQMx86 GPIO controller has separate status
+		 * registers for rising and falling edge interrupts. GPIIC
+		 * configures which bits from which register are visible in the
+		 * interrupt status register GPIIS and defines what triggers the
+		 * parent IRQ line. Writing to GPIIS always clears both rising
+		 * and falling interrupt flags internally, regardless of the
+		 * currently configured trigger.
+		 *
+		 * In consequence, we can cleanly implement the edge-both
+		 * trigger in software by first clearing the interrupt and then
+		 * setting the new trigger based on the current GPIO input in
+		 * tqmx86_gpio_irq_config() - even if an edge arrives between
+		 * reading the input and setting the trigger, we will have a new
+		 * interrupt pending.
+		 */
+		if ((gpio->irq_type[i] & TQMX86_GPII_MASK) == TQMX86_INT_BOTH)
+			tqmx86_gpio_irq_config(gpio, i);
+	}
+	raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
+
 	for_each_set_bit(i, &irq_bits, TQMX86_NGPI)
 		generic_handle_domain_irq(gpio->chip.irq.domain,
 					  i + TQMX86_NGPO);
@@ -277,6 +320,13 @@
 
 	tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD);
 
+	/*
+	 * Reading the previous output state is not possible with TQMx86 hardware.
+	 * Initialize all outputs to 0 to have a defined state that matches the
+	 * shadow register.
+	 */
+	tqmx86_gpio_write(gpio, 0, TQMX86_GPIOD);
+
 	chip = &gpio->chip;
 	chip->label = "gpio-tqmx86";
 	chip->owner = THIS_MODULE;
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-wcove.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-wcove.c
@@ -104,7 +104,7 @@
 	unsigned int reg = type == CTRL_IN ? GPIO_IN_CTRL_BASE : GPIO_OUT_CTRL_BASE;
 
 	if (gpio >= WCOVE_GPIO_NUM)
-		return -EOPNOTSUPP;
+		return -ENOTSUPP;
 
 	return reg + gpio;
 }
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-xilinx.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-xilinx.c
@@ -65,7 +65,7 @@
 	DECLARE_BITMAP(state, 64);
 	DECLARE_BITMAP(last_irq_read, 64);
 	DECLARE_BITMAP(dir, 64);
-	spinlock_t gpio_lock;	/* For serializing operations */
+	raw_spinlock_t gpio_lock;	/* For serializing operations */
 	int irq;
 	DECLARE_BITMAP(enable, 64);
 	DECLARE_BITMAP(rising_edge, 64);
@@ -179,14 +179,14 @@
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
 	int bit = xgpio_to_bit(chip, gpio);
 
-	spin_lock_irqsave(&chip->gpio_lock, flags);
+	raw_spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	/* Write to GPIO signal and set its direction to output */
 	__assign_bit(bit, chip->state, val);
 
 	xgpio_write_ch(chip, XGPIO_DATA_OFFSET, bit, chip->state);
 
-	spin_unlock_irqrestore(&chip->gpio_lock, flags);
+	raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
 
 /**
@@ -210,7 +210,7 @@
 	bitmap_remap(hw_mask, mask, chip->sw_map, chip->hw_map, 64);
 	bitmap_remap(hw_bits, bits, chip->sw_map, chip->hw_map, 64);
 
-	spin_lock_irqsave(&chip->gpio_lock, flags);
+	raw_spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	bitmap_replace(state, chip->state, hw_bits, hw_mask, 64);
 
@@ -218,7 +218,7 @@
 
 	bitmap_copy(chip->state, state, 64);
 
-	spin_unlock_irqrestore(&chip->gpio_lock, flags);
+	raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
 
 /**
@@ -236,13 +236,13 @@
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
 	int bit = xgpio_to_bit(chip, gpio);
 
-	spin_lock_irqsave(&chip->gpio_lock, flags);
+	raw_spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	/* Set the GPIO bit in shadow register and set direction as input */
 	__set_bit(bit, chip->dir);
 	xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir);
 
-	spin_unlock_irqrestore(&chip->gpio_lock, flags);
+	raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
 	return 0;
 }
@@ -265,7 +265,7 @@
 	struct xgpio_instance *chip = gpiochip_get_data(gc);
 	int bit = xgpio_to_bit(chip, gpio);
 
-	spin_lock_irqsave(&chip->gpio_lock, flags);
+	raw_spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	/* Write state of GPIO signal */
 	__assign_bit(bit, chip->state, val);
@@ -275,7 +275,7 @@
 	__clear_bit(bit, chip->dir);
 	xgpio_write_ch(chip, XGPIO_TRI_OFFSET, bit, chip->dir);
 
-	spin_unlock_irqrestore(&chip->gpio_lock, flags);
+	raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
 	return 0;
 }
@@ -401,7 +401,7 @@
 	int bit = xgpio_to_bit(chip, irq_offset);
 	u32 mask = BIT(bit / 32), temp;
 
-	spin_lock_irqsave(&chip->gpio_lock, flags);
+	raw_spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	__clear_bit(bit, chip->enable);
 
@@ -411,7 +411,7 @@
 		temp &= ~mask;
 		xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, temp);
 	}
-	spin_unlock_irqrestore(&chip->gpio_lock, flags);
+	raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
 
 	gpiochip_disable_irq(&chip->gc, irq_offset);
 }
@@ -431,7 +431,7 @@
 
 	gpiochip_enable_irq(&chip->gc, irq_offset);
 
-	spin_lock_irqsave(&chip->gpio_lock, flags);
+	raw_spin_lock_irqsave(&chip->gpio_lock, flags);
 
 	__set_bit(bit, chip->enable);
 
@@ -450,7 +450,7 @@
 		xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, val);
 	}
 
-	spin_unlock_irqrestore(&chip->gpio_lock, flags);
+	raw_spin_unlock_irqrestore(&chip->gpio_lock, flags);
 }
 
 /**
@@ -515,7 +515,7 @@
 
 	chained_irq_enter(irqchip, desc);
 
-	spin_lock(&chip->gpio_lock);
+	raw_spin_lock(&chip->gpio_lock);
 
 	xgpio_read_ch_all(chip, XGPIO_DATA_OFFSET, all);
 
@@ -532,7 +532,7 @@
 	bitmap_copy(chip->last_irq_read, all, 64);
 	bitmap_or(all, rising, falling, 64);
 
-	spin_unlock(&chip->gpio_lock);
+	raw_spin_unlock(&chip->gpio_lock);
 
 	dev_dbg(gc->parent, "IRQ rising %*pb falling %*pb\n", 64, rising, 64, falling);
 
@@ -623,7 +623,7 @@
 	bitmap_set(chip->hw_map,  0, width[0]);
 	bitmap_set(chip->hw_map, 32, width[1]);
 
-	spin_lock_init(&chip->gpio_lock);
+	raw_spin_lock_init(&chip->gpio_lock);
 
 	chip->gc.base = -1;
 	chip->gc.ngpio = bitmap_weight(chip->hw_map, 64);
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-zevio.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-zevio.c
@@ -11,6 +11,7 @@
 #include <linux/io.h>
 #include <linux/mod_devicetable.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 
@@ -169,6 +170,7 @@
 /* Initialization */
 static int zevio_gpio_probe(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
 	struct zevio_gpio *controller;
 	int status, i;
 
@@ -180,6 +182,10 @@
 	controller->chip = zevio_gpio_chip;
 	controller->chip.parent = &pdev->dev;
 
+	controller->chip.label = devm_kasprintf(dev, GFP_KERNEL, "%pfw", dev_fwnode(dev));
+	if (!controller->chip.label)
+		return -ENOMEM;
+
 	controller->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(controller->regs))
 		return dev_err_probe(&pdev->dev, PTR_ERR(controller->regs),
--- linux-qcom-6.8.0.orig/drivers/gpio/gpio-zynqmp-modepin.c
+++ linux-qcom-6.8.0/drivers/gpio/gpio-zynqmp-modepin.c
@@ -146,6 +146,7 @@
 	{ .compatible = "xlnx,zynqmp-gpio-modepin", },
 	{ }
 };
+MODULE_DEVICE_TABLE(of, modepin_platform_id);
 
 static struct platform_driver modepin_platform_driver = {
 	.driver = {
--- linux-qcom-6.8.0.orig/drivers/gpio/gpiolib-acpi.c
+++ linux-qcom-6.8.0/drivers/gpio/gpiolib-acpi.c
@@ -128,7 +128,24 @@
 
 static int acpi_gpiochip_find(struct gpio_chip *gc, void *data)
 {
-	return device_match_acpi_handle(&gc->gpiodev->dev, data);
+	/* First check the actual GPIO device */
+	if (device_match_acpi_handle(&gc->gpiodev->dev, data))
+		return true;
+
+	/*
+	 * When the ACPI device is artificially split to the banks of GPIOs,
+	 * where each of them is represented by a separate GPIO device,
+	 * the firmware node of the physical device may not be shared among
+	 * the banks as they may require different values for the same property,
+	 * e.g., number of GPIOs in a certain bank. In such case the ACPI handle
+	 * of a GPIO device is NULL and can not be used. Hence we have to check
+	 * the parent device to be sure that there is no match before bailing
+	 * out.
+	 */
+	if (gc->parent)
+		return device_match_acpi_handle(gc->parent, data);
+
+	return false;
 }
 
 /**
--- linux-qcom-6.8.0.orig/drivers/gpio/gpiolib-cdev.c
+++ linux-qcom-6.8.0/drivers/gpio/gpiolib-cdev.c
@@ -95,6 +95,10 @@
 	GPIOHANDLE_REQUEST_OPEN_DRAIN | \
 	GPIOHANDLE_REQUEST_OPEN_SOURCE)
 
+#define GPIOHANDLE_REQUEST_DIRECTION_FLAGS \
+	(GPIOHANDLE_REQUEST_INPUT | \
+	 GPIOHANDLE_REQUEST_OUTPUT)
+
 static int linehandle_validate_flags(u32 flags)
 {
 	/* Return an error if an unknown flag is set */
@@ -175,21 +179,21 @@
 	if (ret)
 		return ret;
 
+	/* Lines must be reconfigured explicitly as input or output. */
+	if (!(lflags & GPIOHANDLE_REQUEST_DIRECTION_FLAGS))
+		return -EINVAL;
+
 	for (i = 0; i < lh->num_descs; i++) {
 		desc = lh->descs[i];
-		linehandle_flags_to_desc_flags(gcnf.flags, &desc->flags);
+		linehandle_flags_to_desc_flags(lflags, &desc->flags);
 
-		/*
-		 * Lines have to be requested explicitly for input
-		 * or output, else the line will be treated "as is".
-		 */
 		if (lflags & GPIOHANDLE_REQUEST_OUTPUT) {
 			int val = !!gcnf.default_values[i];
 
 			ret = gpiod_direction_output(desc, val);
 			if (ret)
 				return ret;
-		} else if (lflags & GPIOHANDLE_REQUEST_INPUT) {
+		} else {
 			ret = gpiod_direction_input(desc);
 			if (ret)
 				return ret;
@@ -734,6 +738,25 @@
 		       GPIO_V2_LINE_EVENT_FALLING_EDGE;
 }
 
+static inline char *make_irq_label(const char *orig)
+{
+	char *new;
+
+	if (!orig)
+		return NULL;
+
+	new = kstrdup_and_replace(orig, '/', ':', GFP_KERNEL);
+	if (!new)
+		return ERR_PTR(-ENOMEM);
+
+	return new;
+}
+
+static inline void free_irq_label(const char *label)
+{
+	kfree(label);
+}
+
 #ifdef CONFIG_HTE
 
 static enum hte_return process_hw_ts_thread(void *p)
@@ -1021,6 +1044,7 @@
 {
 	unsigned long irqflags;
 	int ret, level, irq;
+	char *label;
 
 	/* try hardware */
 	ret = gpiod_set_debounce(line->desc, debounce_period_us);
@@ -1043,11 +1067,17 @@
 			if (irq < 0)
 				return -ENXIO;
 
+			label = make_irq_label(line->req->label);
+			if (IS_ERR(label))
+				return -ENOMEM;
+
 			irqflags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING;
 			ret = request_irq(irq, debounce_irq_handler, irqflags,
-					  line->req->label, line);
-			if (ret)
+					  label, line);
+			if (ret) {
+				free_irq_label(label);
 				return ret;
+			}
 			line->irq = irq;
 		} else {
 			ret = hte_edge_setup(line, GPIO_V2_LINE_FLAG_EDGE_BOTH);
@@ -1092,7 +1122,7 @@
 static void edge_detector_stop(struct line *line)
 {
 	if (line->irq) {
-		free_irq(line->irq, line);
+		free_irq_label(free_irq(line->irq, line));
 		line->irq = 0;
 	}
 
@@ -1116,6 +1146,7 @@
 	unsigned long irqflags = 0;
 	u64 eflags;
 	int irq, ret;
+	char *label;
 
 	eflags = edflags & GPIO_V2_LINE_EDGE_FLAGS;
 	if (eflags && !kfifo_initialized(&line->req->events)) {
@@ -1152,11 +1183,17 @@
 			IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
 	irqflags |= IRQF_ONESHOT;
 
+	label = make_irq_label(line->req->label);
+	if (IS_ERR(label))
+		return PTR_ERR(label);
+
 	/* Request a thread to read the events */
 	ret = request_threaded_irq(irq, edge_irq_handler, edge_irq_thread,
-				   irqflags, line->req->label, line);
-	if (ret)
+				   irqflags, label, line);
+	if (ret) {
+		free_irq_label(label);
 		return ret;
+	}
 
 	line->irq = irq;
 	return 0;
@@ -1166,6 +1203,8 @@
 				struct gpio_v2_line_config *lc,
 				unsigned int line_idx, u64 edflags)
 {
+	u64 eflags;
+	int ret;
 	u64 active_edflags = READ_ONCE(line->edflags);
 	unsigned int debounce_period_us =
 			gpio_v2_line_config_debounce_period(lc, line_idx);
@@ -1177,6 +1216,18 @@
 	/* sw debounced and still will be...*/
 	if (debounce_period_us && READ_ONCE(line->sw_debounced)) {
 		line_set_debounce_period(line, debounce_period_us);
+		/*
+		 * ensure event fifo is initialised if edge detection
+		 * is now enabled.
+		 */
+		eflags = edflags & GPIO_V2_LINE_EDGE_FLAGS;
+		if (eflags && !kfifo_initialized(&line->req->events)) {
+			ret = kfifo_alloc(&line->req->events,
+					  line->req->event_buffer_size,
+					  GFP_KERNEL);
+			if (ret)
+				return ret;
+		}
 		return 0;
 	}
 
@@ -1489,12 +1540,14 @@
 		line = &lr->lines[i];
 		desc = lr->lines[i].desc;
 		flags = gpio_v2_line_config_flags(&lc, i);
-		gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags);
-		edflags = flags & GPIO_V2_LINE_EDGE_DETECTOR_FLAGS;
 		/*
-		 * Lines have to be requested explicitly for input
-		 * or output, else the line will be treated "as is".
+		 * Lines not explicitly reconfigured as input or output
+		 * are left unchanged.
 		 */
+		if (!(flags & GPIO_V2_LINE_DIRECTION_FLAGS))
+			continue;
+		gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags);
+		edflags = flags & GPIO_V2_LINE_EDGE_DETECTOR_FLAGS;
 		if (flags & GPIO_V2_LINE_FLAG_OUTPUT) {
 			int val = gpio_v2_line_config_output_value(&lc, i);
 
@@ -1502,7 +1555,7 @@
 			ret = gpiod_direction_output(desc, val);
 			if (ret)
 				return ret;
-		} else if (flags & GPIO_V2_LINE_FLAG_INPUT) {
+		} else {
 			ret = gpiod_direction_input(desc);
 			if (ret)
 				return ret;
@@ -1979,7 +2032,7 @@
 		blocking_notifier_chain_unregister(&le->gdev->device_notifier,
 						   &le->device_unregistered_nb);
 	if (le->irq)
-		free_irq(le->irq, le);
+		free_irq_label(free_irq(le->irq, le));
 	if (le->desc)
 		gpiod_free(le->desc);
 	kfree(le->label);
@@ -2120,6 +2173,7 @@
 	int fd;
 	int ret;
 	int irq, irqflags = 0;
+	char *label;
 
 	if (copy_from_user(&eventreq, ip, sizeof(eventreq)))
 		return -EFAULT;
@@ -2204,15 +2258,23 @@
 	if (ret)
 		goto out_free_le;
 
+	label = make_irq_label(le->label);
+	if (IS_ERR(label)) {
+		ret = PTR_ERR(label);
+		goto out_free_le;
+	}
+
 	/* Request a thread to read the events */
 	ret = request_threaded_irq(irq,
 				   lineevent_irq_handler,
 				   lineevent_irq_thread,
 				   irqflags,
-				   le->label,
+				   label,
 				   le);
-	if (ret)
+	if (ret) {
+		free_irq_label(label);
 		goto out_free_le;
+	}
 
 	le->irq = irq;
 
@@ -2758,11 +2820,11 @@
 	struct gpio_chardev_data *cdev = file->private_data;
 	struct gpio_device *gdev = cdev->gdev;
 
-	bitmap_free(cdev->watched_lines);
 	blocking_notifier_chain_unregister(&gdev->device_notifier,
 					   &cdev->device_unregistered_nb);
 	blocking_notifier_chain_unregister(&gdev->line_state_notifier,
 					   &cdev->lineinfo_changed_nb);
+	bitmap_free(cdev->watched_lines);
 	gpio_device_put(gdev);
 	kfree(cdev);
 
--- linux-qcom-6.8.0.orig/drivers/gpio/gpiolib-devres.c
+++ linux-qcom-6.8.0/drivers/gpio/gpiolib-devres.c
@@ -158,7 +158,7 @@
 	if (!dr)
 		return ERR_PTR(-ENOMEM);
 
-	desc = fwnode_gpiod_get_index(fwnode, con_id, index, flags, label);
+	desc = gpiod_find_and_request(dev, fwnode, con_id, index, flags, label, false);
 	if (IS_ERR(desc)) {
 		devres_free(dr);
 		return desc;
--- linux-qcom-6.8.0.orig/drivers/gpio/gpiolib-of.c
+++ linux-qcom-6.8.0/drivers/gpio/gpiolib-of.c
@@ -202,6 +202,24 @@
 		 */
 		{ "qi,lb60",		"rb-gpios",	true },
 #endif
+#if IS_ENABLED(CONFIG_PCI_LANTIQ)
+		/*
+		 * According to the PCI specification, the RST# pin is an
+		 * active-low signal. However, most of the device trees that
+		 * have been widely used for a long time incorrectly describe
+		 * reset GPIO as active-high, and were also using wrong name
+		 * for the property.
+		 */
+		{ "lantiq,pci-xway",	"gpio-reset",	false },
+#endif
+#if IS_ENABLED(CONFIG_TOUCHSCREEN_TSC2005)
+		/*
+		 * DTS for Nokia N900 incorrectly specified "active high"
+		 * polarity for the reset line, while the chip actually
+		 * treats it as "active low".
+		 */
+		{ "ti,tsc2005",		"reset-gpios",	false },
+#endif
 	};
 	unsigned int i;
 
@@ -501,9 +519,9 @@
 		{ "reset",	"reset-n-io",	"marvell,nfc-uart" },
 		{ "reset",	"reset-n-io",	"mrvl,nfc-uart" },
 #endif
-#if !IS_ENABLED(CONFIG_PCI_LANTIQ)
+#if IS_ENABLED(CONFIG_PCI_LANTIQ)
 		/* MIPS Lantiq PCI */
-		{ "reset",	"gpios-reset",	"lantiq,pci-xway" },
+		{ "reset",	"gpio-reset",	"lantiq,pci-xway" },
 #endif
 
 		/*
--- linux-qcom-6.8.0.orig/drivers/gpio/gpiolib-sysfs.c
+++ linux-qcom-6.8.0/drivers/gpio/gpiolib-sysfs.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include <linux/bitops.h>
+#include <linux/cleanup.h>
 #include <linux/device.h>
 #include <linux/idr.h>
 #include <linux/init.h>
@@ -773,15 +774,15 @@
 	struct gpio_desc *desc;
 	struct gpio_chip *chip = gdev->chip;
 
-	if (!gdev->mockdev)
-		return;
+	scoped_guard(mutex, &sysfs_lock) {
+		if (!gdev->mockdev)
+			return;
 
-	device_unregister(gdev->mockdev);
+		device_unregister(gdev->mockdev);
 
-	/* prevent further gpiod exports */
-	mutex_lock(&sysfs_lock);
-	gdev->mockdev = NULL;
-	mutex_unlock(&sysfs_lock);
+		/* prevent further gpiod exports */
+		gdev->mockdev = NULL;
+	}
 
 	/* unregister gpiod class devices owned by sysfs */
 	for_each_gpio_desc_with_flag(chip, desc, FLAG_SYSFS) {
--- linux-qcom-6.8.0.orig/drivers/gpio/gpiolib.c
+++ linux-qcom-6.8.0/drivers/gpio/gpiolib.c
@@ -12,9 +12,11 @@
 #include <linux/idr.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqdesc.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/nospec.h>
 #include <linux/of.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/seq_file.h>
@@ -174,7 +176,7 @@
 	if (hwnum >= gdev->ngpio)
 		return ERR_PTR(-EINVAL);
 
-	return &gdev->descs[hwnum];
+	return &gdev->descs[array_index_nospec(hwnum, gdev->ngpio)];
 }
 EXPORT_SYMBOL_GPL(gpio_device_get_desc);
 
@@ -653,6 +655,45 @@
 }
 EXPORT_SYMBOL_GPL(gpiochip_line_is_valid);
 
+static void gpiod_free_irqs(struct gpio_desc *desc)
+{
+	int irq = gpiod_to_irq(desc);
+	struct irq_desc *irqd = irq_to_desc(irq);
+	void *cookie;
+
+	for (;;) {
+		/*
+		 * Make sure the action doesn't go away while we're
+		 * dereferencing it. Retrieve and store the cookie value.
+		 * If the irq is freed after we release the lock, that's
+		 * alright - the underlying maple tree lookup will return NULL
+		 * and nothing will happen in free_irq().
+		 */
+		scoped_guard(mutex, &irqd->request_mutex) {
+			if (!irq_desc_has_action(irqd))
+				return;
+
+			cookie = irqd->action->dev_id;
+		}
+
+		free_irq(irq, cookie);
+	}
+}
+
+/*
+ * The chip is going away but there may be users who had requested interrupts
+ * on its GPIO lines who have no idea about its removal and have no way of
+ * being notified about it. We need to free any interrupts still in use here or
+ * we'll leak memory and resources (like procfs files).
+ */
+static void gpiochip_free_remaining_irqs(struct gpio_chip *gc)
+{
+	struct gpio_desc *desc;
+
+	for_each_gpio_desc_with_flag(gc, desc, FLAG_USED_AS_IRQ)
+		gpiod_free_irqs(desc);
+}
+
 static void gpiodev_release(struct device *dev)
 {
 	struct gpio_device *gdev = to_gpio_device(dev);
@@ -1052,6 +1093,8 @@
 	/* FIXME: should the legacy sysfs handling be moved to gpio_device? */
 	gpiochip_sysfs_unregister(gdev);
 	gpiochip_free_hogs(gc);
+	gpiochip_free_remaining_irqs(gc);
+
 	/* Numb the device, cancelling all outstanding operations */
 	gdev->chip = NULL;
 	gpiochip_irqchip_remove(gc);
@@ -2402,6 +2445,11 @@
 }
 EXPORT_SYMBOL_GPL(gpiochip_dup_line_label);
 
+static inline const char *function_name_or_default(const char *con_id)
+{
+	return con_id ?: "(default)";
+}
+
 /**
  * gpiochip_request_own_desc - Allow GPIO chip to request its own descriptor
  * @gc: GPIO chip
@@ -2430,10 +2478,11 @@
 					    enum gpiod_flags dflags)
 {
 	struct gpio_desc *desc = gpiochip_get_desc(gc, hwnum);
+	const char *name = function_name_or_default(label);
 	int ret;
 
 	if (IS_ERR(desc)) {
-		chip_err(gc, "failed to get GPIO descriptor\n");
+		chip_err(gc, "failed to get GPIO %s descriptor\n", name);
 		return desc;
 	}
 
@@ -2443,8 +2492,8 @@
 
 	ret = gpiod_configure_flags(desc, label, lflags, dflags);
 	if (ret) {
-		chip_err(gc, "setup of own GPIO %s failed\n", label);
 		gpiod_free_commit(desc);
+		chip_err(gc, "setup of own GPIO %s failed\n", name);
 		return ERR_PTR(ret);
 	}
 
@@ -4119,34 +4168,33 @@
 					      enum gpiod_flags *flags,
 					      unsigned long *lookupflags)
 {
+	const char *name = function_name_or_default(con_id);
 	struct gpio_desc *desc = ERR_PTR(-ENOENT);
 
 	if (is_of_node(fwnode)) {
-		dev_dbg(consumer, "using DT '%pfw' for '%s' GPIO lookup\n",
-			fwnode, con_id);
+		dev_dbg(consumer, "using DT '%pfw' for '%s' GPIO lookup\n", fwnode, name);
 		desc = of_find_gpio(to_of_node(fwnode), con_id, idx, lookupflags);
 	} else if (is_acpi_node(fwnode)) {
-		dev_dbg(consumer, "using ACPI '%pfw' for '%s' GPIO lookup\n",
-			fwnode, con_id);
+		dev_dbg(consumer, "using ACPI '%pfw' for '%s' GPIO lookup\n", fwnode, name);
 		desc = acpi_find_gpio(fwnode, con_id, idx, flags, lookupflags);
 	} else if (is_software_node(fwnode)) {
-		dev_dbg(consumer, "using swnode '%pfw' for '%s' GPIO lookup\n",
-			fwnode, con_id);
+		dev_dbg(consumer, "using swnode '%pfw' for '%s' GPIO lookup\n", fwnode, name);
 		desc = swnode_find_gpio(fwnode, con_id, idx, lookupflags);
 	}
 
 	return desc;
 }
 
-static struct gpio_desc *gpiod_find_and_request(struct device *consumer,
-						struct fwnode_handle *fwnode,
-						const char *con_id,
-						unsigned int idx,
-						enum gpiod_flags flags,
-						const char *label,
-						bool platform_lookup_allowed)
+struct gpio_desc *gpiod_find_and_request(struct device *consumer,
+					 struct fwnode_handle *fwnode,
+					 const char *con_id,
+					 unsigned int idx,
+					 enum gpiod_flags flags,
+					 const char *label,
+					 bool platform_lookup_allowed)
 {
 	unsigned long lookupflags = GPIO_LOOKUP_FLAGS_DEFAULT;
+	const char *name = function_name_or_default(con_id);
 	struct gpio_desc *desc;
 	int ret;
 
@@ -4162,7 +4210,7 @@
 	}
 
 	if (IS_ERR(desc)) {
-		dev_dbg(consumer, "No GPIO consumer %s found\n", con_id);
+		dev_dbg(consumer, "No GPIO consumer %s found\n", name);
 		return desc;
 	}
 
@@ -4183,15 +4231,14 @@
 		 *
 		 * FIXME: Make this more sane and safe.
 		 */
-		dev_info(consumer,
-			 "nonexclusive access to GPIO for %s\n", con_id);
+		dev_info(consumer, "nonexclusive access to GPIO for %s\n", name);
 		return desc;
 	}
 
 	ret = gpiod_configure_flags(desc, con_id, lookupflags, flags);
 	if (ret < 0) {
-		dev_dbg(consumer, "setup of GPIO %s failed\n", con_id);
 		gpiod_put(desc);
+		dev_dbg(consumer, "setup of GPIO %s failed\n", name);
 		return ERR_PTR(ret);
 	}
 
@@ -4307,6 +4354,7 @@
 int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
 		unsigned long lflags, enum gpiod_flags dflags)
 {
+	const char *name = function_name_or_default(con_id);
 	int ret;
 
 	if (lflags & GPIO_ACTIVE_LOW)
@@ -4350,7 +4398,7 @@
 
 	/* No particular flag request, return here... */
 	if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) {
-		gpiod_dbg(desc, "no flags found for %s\n", con_id);
+		gpiod_dbg(desc, "no flags found for GPIO %s\n", name);
 		return 0;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpio/gpiolib.h
+++ linux-qcom-6.8.0/drivers/gpio/gpiolib.h
@@ -202,6 +202,14 @@
 	return ret;
 }
 
+struct gpio_desc *gpiod_find_and_request(struct device *consumer,
+					 struct fwnode_handle *fwnode,
+					 const char *con_id,
+					 unsigned int idx,
+					 enum gpiod_flags flags,
+					 const char *label,
+					 bool platform_lookup_allowed);
+
 int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
 		unsigned long lflags, enum gpiod_flags dflags);
 int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/Kconfig
+++ linux-qcom-6.8.0/drivers/gpu/drm/Kconfig
@@ -221,6 +221,7 @@
 config DRM_GPUVM
 	tristate
 	depends on DRM
+	select DRM_EXEC
 	help
 	  GPU-VM representation providing helpers to manage a GPUs virtual
 	  address space
@@ -420,6 +421,10 @@
 config DRM_PANEL_ORIENTATION_QUIRKS
 	tristate
 
+# Separate option as not all DRM drivers use it
+config DRM_PANEL_BACKLIGHT_QUIRKS
+	tristate
+
 config DRM_LIB_RANDOM
 	bool
 	default n
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/Makefile
+++ linux-qcom-6.8.0/drivers/gpu/drm/Makefile
@@ -63,6 +63,7 @@
 obj-$(CONFIG_DRM)	+= drm.o
 
 obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o
+obj-$(CONFIG_DRM_PANEL_BACKLIGHT_QUIRKS) += drm_panel_backlight_quirks.o
 
 #
 # Memory-management helpers
@@ -157,6 +158,7 @@
 obj-$(CONFIG_DRM_QXL) += qxl/
 obj-$(CONFIG_DRM_VIRTIO_GPU) += virtio/
 obj-$(CONFIG_DRM_MSM) += msm/
+obj-$(CONFIG_DRM_MSM) += msm_default/
 obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-$(CONFIG_DRM_STM) += stm/
 obj-$(CONFIG_DRM_STI) += sti/
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/aldebaran.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/aldebaran.c
@@ -97,7 +97,7 @@
 		adev->ip_blocks[i].status.hw = false;
 	}
 
-	return r;
+	return 0;
 }
 
 static int
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -198,7 +198,7 @@
 extern uint amdgpu_dc_feature_mask;
 extern uint amdgpu_dc_debug_mask;
 extern uint amdgpu_dc_visual_confirm;
-extern uint amdgpu_dm_abm_level;
+extern int amdgpu_dm_abm_level;
 extern int amdgpu_backlight;
 extern int amdgpu_damage_clips;
 extern struct amdgpu_mgpu_info mgpu_info;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
@@ -147,6 +147,7 @@
 					   struct acpi_buffer *params)
 {
 	acpi_status status;
+	union acpi_object *obj;
 	union acpi_object atif_arg_elements[2];
 	struct acpi_object_list atif_arg;
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -169,16 +170,24 @@
 
 	status = acpi_evaluate_object(atif->handle, NULL, &atif_arg,
 				      &buffer);
+	obj = (union acpi_object *)buffer.pointer;
 
-	/* Fail only if calling the method fails and ATIF is supported */
-	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+	/* Fail if calling the method fails */
+	if (ACPI_FAILURE(status)) {
 		DRM_DEBUG_DRIVER("failed to evaluate ATIF got %s\n",
 				 acpi_format_exception(status));
-		kfree(buffer.pointer);
+		kfree(obj);
 		return NULL;
 	}
 
-	return buffer.pointer;
+	if (obj->type != ACPI_TYPE_BUFFER) {
+		DRM_DEBUG_DRIVER("bad object returned from ATIF: %d\n",
+				 obj->type);
+		kfree(obj);
+		return NULL;
+	}
+
+	return obj;
 }
 
 /**
@@ -789,6 +798,7 @@
 		return -EIO;
 	}
 
+	kfree(info);
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_afmt.c
@@ -100,6 +100,7 @@
 	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_48khz, &res.n_48khz, 48000);
+	res.clock = clock;
 
 	return res;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
@@ -146,7 +146,7 @@
 {
 	int ret;
 
-	if (!adev->kfd.init_complete)
+	if (!adev->kfd.init_complete || adev->kfd.client.dev)
 		return 0;
 
 	ret = drm_client_init(&adev->ddev, &adev->kfd.client, "kfd",
@@ -360,15 +360,15 @@
 	return r;
 }
 
-void amdgpu_amdkfd_free_gtt_mem(struct amdgpu_device *adev, void *mem_obj)
+void amdgpu_amdkfd_free_gtt_mem(struct amdgpu_device *adev, void **mem_obj)
 {
-	struct amdgpu_bo *bo = (struct amdgpu_bo *) mem_obj;
+	struct amdgpu_bo **bo = (struct amdgpu_bo **) mem_obj;
 
-	amdgpu_bo_reserve(bo, true);
-	amdgpu_bo_kunmap(bo);
-	amdgpu_bo_unpin(bo);
-	amdgpu_bo_unreserve(bo);
-	amdgpu_bo_unref(&(bo));
+	amdgpu_bo_reserve(*bo, true);
+	amdgpu_bo_kunmap(*bo);
+	amdgpu_bo_unpin(*bo);
+	amdgpu_bo_unreserve(*bo);
+	amdgpu_bo_unref(bo);
 }
 
 int amdgpu_amdkfd_alloc_gws(struct amdgpu_device *adev, size_t size,
@@ -455,6 +455,9 @@
 		else
 			mem_info->local_mem_size_private =
 					KFD_XCP_MEMORY_SIZE(adev, xcp->id);
+	} else if (adev->flags & AMD_IS_APU) {
+		mem_info->local_mem_size_public = (ttm_tt_pages_limit() << PAGE_SHIFT);
+		mem_info->local_mem_size_private = 0;
 	} else {
 		mem_info->local_mem_size_public = adev->gmc.visible_vram_size;
 		mem_info->local_mem_size_private = adev->gmc.real_vram_size -
@@ -708,8 +711,9 @@
 void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle)
 {
 	enum amd_powergating_state state = idle ? AMD_PG_STATE_GATE : AMD_PG_STATE_UNGATE;
-	if (IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 11 &&
-	    ((adev->mes.kiq_version & AMDGPU_MES_VERSION_MASK) <= 64)) {
+	if ((IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 11 &&
+	    ((adev->mes.kiq_version & AMDGPU_MES_VERSION_MASK) <= 64)) ||
+		(IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 12)) {
 		pr_debug("GFXOFF is %s\n", idle ? "enabled" : "disabled");
 		amdgpu_gfx_off_ctrl(adev, idle);
 	} else if ((IP_VERSION_MAJ(amdgpu_ip_version(adev, GC_HWIP, 0)) == 9) &&
@@ -803,6 +807,8 @@
 		}
 		do_div(tmp, adev->xcp_mgr->num_xcp_per_mem_partition);
 		return ALIGN_DOWN(tmp, PAGE_SIZE);
+	} else if (adev->flags & AMD_IS_APU) {
+		return (ttm_tt_pages_limit() << PAGE_SHIFT);
 	} else {
 		return adev->gmc.real_vram_size;
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -223,7 +223,7 @@
 int amdgpu_amdkfd_alloc_gtt_mem(struct amdgpu_device *adev, size_t size,
 				void **mem_obj, uint64_t *gpu_addr,
 				void **cpu_ptr, bool mqd_gfx9);
-void amdgpu_amdkfd_free_gtt_mem(struct amdgpu_device *adev, void *mem_obj);
+void amdgpu_amdkfd_free_gtt_mem(struct amdgpu_device *adev, void **mem_obj);
 int amdgpu_amdkfd_alloc_gws(struct amdgpu_device *adev, size_t size,
 				void **mem_obj);
 void amdgpu_amdkfd_free_gws(struct amdgpu_device *adev, void *mem_obj);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -196,7 +196,7 @@
 			return -EINVAL;
 
 		vram_size = KFD_XCP_MEMORY_SIZE(adev, xcp_id);
-		if (adev->gmc.is_app_apu) {
+		if (adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) {
 			system_mem_needed = size;
 			ttm_mem_needed = size;
 		}
@@ -220,7 +220,7 @@
 	    (kfd_mem_limit.ttm_mem_used + ttm_mem_needed >
 	     kfd_mem_limit.max_ttm_mem_limit) ||
 	    (adev && xcp_id >= 0 && adev->kfd.vram_used[xcp_id] + vram_needed >
-	     vram_size - reserved_for_pt)) {
+	     vram_size - reserved_for_pt - atomic64_read(&adev->vram_pin_size))) {
 		ret = -ENOMEM;
 		goto release;
 	}
@@ -232,7 +232,8 @@
 		  "adev reference can't be null when vram is used");
 	if (adev && xcp_id >= 0) {
 		adev->kfd.vram_used[xcp_id] += vram_needed;
-		adev->kfd.vram_used_aligned[xcp_id] += adev->gmc.is_app_apu ?
+		adev->kfd.vram_used_aligned[xcp_id] +=
+				(adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) ?
 				vram_needed :
 				ALIGN(vram_needed, VRAM_AVAILABLITY_ALIGN);
 	}
@@ -260,7 +261,7 @@
 
 		if (adev) {
 			adev->kfd.vram_used[xcp_id] -= size;
-			if (adev->gmc.is_app_apu) {
+			if (adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) {
 				adev->kfd.vram_used_aligned[xcp_id] -= size;
 				kfd_mem_limit.system_mem_used -= size;
 				kfd_mem_limit.ttm_mem_used -= size;
@@ -414,6 +415,10 @@
 		 "Called with userptr BO"))
 		return -EINVAL;
 
+	/* bo has been pinned, not need validate it */
+	if (bo->tbo.pin_count)
+		return 0;
+
 	amdgpu_bo_placement_from_domain(bo, domain);
 
 	ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
@@ -887,7 +892,7 @@
 	 * if peer device has large BAR. In contrast, access over xGMI is
 	 * allowed for both small and large BAR configurations of peer device
 	 */
-	if ((adev != bo_adev && !adev->gmc.is_app_apu) &&
+	if ((adev != bo_adev && !(adev->gmc.is_app_apu || adev->flags & AMD_IS_APU)) &&
 	    ((mem->domain == AMDGPU_GEM_DOMAIN_VRAM) ||
 	     (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL) ||
 	     (mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP))) {
@@ -1186,7 +1191,8 @@
 	int ret;
 
 	ctx->sync = &mem->sync;
-	drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0);
+	drm_exec_init(&ctx->exec, DRM_EXEC_INTERRUPTIBLE_WAIT |
+		      DRM_EXEC_IGNORE_DUPLICATES, 0);
 	drm_exec_until_all_locked(&ctx->exec) {
 		ctx->n_vms = 0;
 		list_for_each_entry(entry, &mem->attachments, list) {
@@ -1424,8 +1430,8 @@
 	list_add_tail(&vm->vm_list_node,
 			&(vm->process_info->vm_list_head));
 	vm->process_info->n_vms++;
-
-	*ef = dma_fence_get(&vm->process_info->eviction_fence->base);
+	if (ef)
+		*ef = dma_fence_get(&vm->process_info->eviction_fence->base);
 	mutex_unlock(&vm->process_info->lock);
 
 	return 0;
@@ -1653,7 +1659,7 @@
 		- atomic64_read(&adev->vram_pin_size)
 		- reserved_for_pt;
 
-	if (adev->gmc.is_app_apu) {
+	if (adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) {
 		system_mem_available = no_system_mem_limit ?
 					kfd_mem_limit.max_system_mem_limit :
 					kfd_mem_limit.max_system_mem_limit -
@@ -1701,7 +1707,7 @@
 	if (flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
 		domain = alloc_domain = AMDGPU_GEM_DOMAIN_VRAM;
 
-		if (adev->gmc.is_app_apu) {
+		if (adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) {
 			domain = AMDGPU_GEM_DOMAIN_GTT;
 			alloc_domain = AMDGPU_GEM_DOMAIN_GTT;
 			alloc_flags = 0;
@@ -1851,6 +1857,7 @@
 err_bo_create:
 	amdgpu_amdkfd_unreserve_mem_limit(adev, aligned_size, flags, xcp_id);
 err_reserve_limit:
+	amdgpu_sync_free(&(*mem)->sync);
 	mutex_destroy(&(*mem)->lock);
 	if (gobj)
 		drm_gem_object_put(gobj);
@@ -1947,7 +1954,7 @@
 	if (size) {
 		if (!is_imported &&
 		   (mem->bo->preferred_domains == AMDGPU_GEM_DOMAIN_VRAM ||
-		   (adev->gmc.is_app_apu &&
+		   ((adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) &&
 		    mem->bo->preferred_domains == AMDGPU_GEM_DOMAIN_GTT)))
 			*size = bo_size;
 		else
@@ -2370,8 +2377,9 @@
 	(*mem)->dmabuf = dma_buf;
 	(*mem)->bo = bo;
 	(*mem)->va = va;
-	(*mem)->domain = (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) && !adev->gmc.is_app_apu ?
-		AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT;
+	(*mem)->domain = (bo->preferred_domains & AMDGPU_GEM_DOMAIN_VRAM) &&
+			 !(adev->gmc.is_app_apu || adev->flags & AMD_IS_APU) ?
+			 AMDGPU_GEM_DOMAIN_VRAM : AMDGPU_GEM_DOMAIN_GTT;
 
 	(*mem)->mapped_to_gpu_memory = 0;
 	(*mem)->process_info = avm->process_info;
@@ -2706,7 +2714,7 @@
 
 		/* keep mem without hmm range at userptr_inval_list */
 		if (!mem->range)
-			 continue;
+			continue;
 
 		/* Only check mem with hmm range associated */
 		valid = amdgpu_ttm_tt_get_user_pages_done(
@@ -2934,9 +2942,6 @@
 			if (!attachment->is_mapped)
 				continue;
 
-			if (attachment->bo_va->base.bo->tbo.pin_count)
-				continue;
-
 			kfd_mem_dmaunmap_attachment(mem, attachment);
 			ret = update_gpuvm_pte(mem, attachment, &sync_obj);
 			if (ret) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c
@@ -1018,7 +1018,9 @@
 		if (clock_type == COMPUTE_ENGINE_PLL_PARAM) {
 			args.v3.ulClockParams = cpu_to_le32((clock_type << 24) | clock);
 
-			amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+			if (amdgpu_atom_execute_table(adev->mode_info.atom_context,
+			    index, (uint32_t *)&args, sizeof(args)))
+				return -EINVAL;
 
 			dividers->post_div = args.v3.ucPostDiv;
 			dividers->enable_post_div = (args.v3.ucCntlFlag &
@@ -1038,7 +1040,9 @@
 			if (strobe_mode)
 				args.v5.ucInputFlag = ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN;
 
-			amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+			if (amdgpu_atom_execute_table(adev->mode_info.atom_context,
+			    index, (uint32_t *)&args, sizeof(args)))
+				return -EINVAL;
 
 			dividers->post_div = args.v5.ucPostDiv;
 			dividers->enable_post_div = (args.v5.ucCntlFlag &
@@ -1056,7 +1060,9 @@
 		/* fusion */
 		args.v4.ulClock = cpu_to_le32(clock);	/* 10 khz */
 
-		amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+		if (amdgpu_atom_execute_table(adev->mode_info.atom_context,
+		    index, (uint32_t *)&args, sizeof(args)))
+			return -EINVAL;
 
 		dividers->post_divider = dividers->post_div = args.v4.ucPostDiv;
 		dividers->real_clock = le32_to_cpu(args.v4.ulClock);
@@ -1067,7 +1073,9 @@
 		args.v6_in.ulClock.ulComputeClockFlag = clock_type;
 		args.v6_in.ulClock.ulClockFreq = cpu_to_le32(clock);	/* 10 khz */
 
-		amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+		if (amdgpu_atom_execute_table(adev->mode_info.atom_context,
+		    index, (uint32_t *)&args, sizeof(args)))
+			return -EINVAL;
 
 		dividers->whole_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDiv);
 		dividers->frac_fb_div = le16_to_cpu(args.v6_out.ulFbDiv.usFbDivFrac);
@@ -1109,7 +1117,9 @@
 			if (strobe_mode)
 				args.ucInputFlag |= MPLL_INPUT_FLAG_STROBE_MODE_EN;
 
-			amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+			if (amdgpu_atom_execute_table(adev->mode_info.atom_context,
+			    index, (uint32_t *)&args, sizeof(args)))
+				return -EINVAL;
 
 			mpll_param->clkfrac = le16_to_cpu(args.ulFbDiv.usFbDivFrac);
 			mpll_param->clkf = le16_to_cpu(args.ulFbDiv.usFbDiv);
@@ -1151,7 +1161,8 @@
 	if (mem_clock)
 		args.sReserved.ulClock = cpu_to_le32(mem_clock & SET_CLOCK_FREQ_MASK);
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args,
+		sizeof(args));
 }
 
 void amdgpu_atombios_get_default_voltages(struct amdgpu_device *adev,
@@ -1205,7 +1216,9 @@
 		args.v2.ucVoltageMode = 0;
 		args.v2.usVoltageLevel = 0;
 
-		amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+		if (amdgpu_atom_execute_table(adev->mode_info.atom_context,
+		    index, (uint32_t *)&args, sizeof(args)))
+			return -EINVAL;
 
 		*voltage = le16_to_cpu(args.v2.usVoltageLevel);
 		break;
@@ -1214,7 +1227,9 @@
 		args.v3.ucVoltageMode = ATOM_GET_VOLTAGE_LEVEL;
 		args.v3.usVoltageLevel = cpu_to_le16(voltage_id);
 
-		amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+		if (amdgpu_atom_execute_table(adev->mode_info.atom_context,
+		    index, (uint32_t *)&args, sizeof(args)))
+			return -EINVAL;
 
 		*voltage = le16_to_cpu(args.v3.usVoltageLevel);
 		break;
@@ -1476,6 +1491,8 @@
 										(u32)le32_to_cpu(*((u32 *)reg_data + j));
 									j++;
 								} 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 - 1];
 								}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_atomfirmware.c
@@ -211,6 +211,7 @@
 	struct atom_integrated_system_info_v1_11 v11;
 	struct atom_integrated_system_info_v1_12 v12;
 	struct atom_integrated_system_info_v2_1 v21;
+	struct atom_integrated_system_info_v2_3 v23;
 };
 
 union umc_info {
@@ -359,6 +360,20 @@
 					if (vram_type)
 						*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
 					break;
+				case 3:
+					mem_channel_number = igp_info->v23.umachannelnumber;
+					if (!mem_channel_number)
+						mem_channel_number = 1;
+					mem_type = igp_info->v23.memorytype;
+					if (mem_type == LpDdr5MemType)
+						mem_channel_width = 32;
+					else
+						mem_channel_width = 64;
+					if (vram_width)
+						*vram_width = mem_channel_number * mem_channel_width;
+					if (vram_type)
+						*vram_type = convert_atom_mem_type_to_vram_type(adev, mem_type);
+					break;
 				default:
 					return -EINVAL;
 				}
@@ -384,7 +399,7 @@
 					mem_channel_number = vram_info->v30.channel_num;
 					mem_channel_width = vram_info->v30.channel_width;
 					if (vram_width)
-						*vram_width = mem_channel_number * (1 << mem_channel_width);
+						*vram_width = mem_channel_number * 16;
 					break;
 				default:
 					return -EINVAL;
@@ -941,5 +956,6 @@
 		return -EINVAL;
 	}
 
-	return amdgpu_atom_execute_table(ctx, ATOM_CMD_INIT, (uint32_t *)&asic_init_ps_v2_1);
+	return amdgpu_atom_execute_table(ctx, ATOM_CMD_INIT, (uint32_t *)&asic_init_ps_v2_1,
+		sizeof(asic_init_ps_v2_1));
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
@@ -213,6 +213,9 @@
 		struct amdgpu_firmware_info *ucode;
 
 		id = fw_type_convert(cgs_device, type);
+		if (id >= AMDGPU_UCODE_ID_MAXIMUM)
+			return -EINVAL;
+
 		ucode = &adev->firmware.ucode[id];
 		if (ucode->fw == NULL)
 			return -EINVAL;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -263,6 +263,10 @@
 			if (size < sizeof(struct drm_amdgpu_bo_list_in))
 				goto free_partial_kdata;
 
+			/* Only a single BO list is allowed to simplify handling. */
+			if (p->bo_list)
+				goto free_partial_kdata;
+
 			ret = amdgpu_cs_p1_bo_handles(p, p->chunks[i].kdata);
 			if (ret)
 				goto free_partial_kdata;
@@ -819,7 +823,7 @@
 
 	p->bytes_moved += ctx.bytes_moved;
 	if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
-	    amdgpu_bo_in_cpu_visible_vram(bo))
+	    amdgpu_res_cpu_visible(adev, bo->tbo.resource))
 		p->bytes_moved_vis += ctx.bytes_moved;
 
 	if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) {
@@ -1057,6 +1061,9 @@
 			r = amdgpu_ring_parse_cs(ring, p, job, ib);
 			if (r)
 				return r;
+
+			if (ib->sa_bo)
+				ib->gpu_addr =  amdgpu_sa_bo_gpu_addr(ib->sa_bo);
 		} else {
 			ib->ptr = (uint32_t *)kptr;
 			r = amdgpu_ring_patch_cs_in_place(ring, p, job, ib);
@@ -1093,6 +1100,21 @@
 	unsigned int i;
 	int r;
 
+	/*
+	 * We can't use gang submit on with reserved VMIDs when the VM changes
+	 * can't be invalidated by more than one engine at the same time.
+	 */
+	if (p->gang_size > 1 && !p->adev->vm_manager.concurrent_flush) {
+		for (i = 0; i < p->gang_size; ++i) {
+			struct drm_sched_entity *entity = p->entities[i];
+			struct drm_gpu_scheduler *sched = entity->rq->sched;
+			struct amdgpu_ring *ring = to_amdgpu_ring(sched);
+
+			if (amdgpu_vmid_uses_reserved(vm, ring->vm_hub))
+				return -EINVAL;
+		}
+	}
+
 	r = amdgpu_vm_clear_freed(adev, vm, NULL);
 	if (r)
 		return r;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
@@ -685,16 +685,24 @@
 
 	switch (args->in.op) {
 	case AMDGPU_CTX_OP_ALLOC_CTX:
+		if (args->in.flags)
+			return -EINVAL;
 		r = amdgpu_ctx_alloc(adev, fpriv, filp, priority, &id);
 		args->out.alloc.ctx_id = id;
 		break;
 	case AMDGPU_CTX_OP_FREE_CTX:
+		if (args->in.flags)
+			return -EINVAL;
 		r = amdgpu_ctx_free(fpriv, id);
 		break;
 	case AMDGPU_CTX_OP_QUERY_STATE:
+		if (args->in.flags)
+			return -EINVAL;
 		r = amdgpu_ctx_query(adev, fpriv, id, &args->out);
 		break;
 	case AMDGPU_CTX_OP_QUERY_STATE2:
+		if (args->in.flags)
+			return -EINVAL;
 		r = amdgpu_ctx_query2(adev, fpriv, id, &args->out);
 		break;
 	case AMDGPU_CTX_OP_GET_STABLE_PSTATE:
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -402,7 +402,7 @@
 	int r;
 	uint32_t *data, x;
 
-	if (size & 0x3 || *pos & 0x3)
+	if (size > 4096 || size & 0x3 || *pos & 0x3)
 		return -EINVAL;
 
 	r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
@@ -1648,7 +1648,7 @@
 
 	for (i = 0; i < ARRAY_SIZE(debugfs_regs); i++) {
 		ent = debugfs_create_file(debugfs_regs_names[i],
-					  S_IFREG | 0444, root,
+					  S_IFREG | 0400, root,
 					  adev, debugfs_regs[i]);
 		if (!i && !IS_ERR_OR_NULL(ent))
 			i_size_write(ent->d_inode, adev->rmmio_size);
@@ -2060,12 +2060,13 @@
 	struct amdgpu_device *adev = (struct amdgpu_device *)file_inode(f)->i_private;
 	char reg_offset[11];
 	uint32_t *new = NULL, *tmp = NULL;
-	int ret, i = 0, len = 0;
+	unsigned int len = 0;
+	int ret, i = 0;
 
 	do {
 		memset(reg_offset, 0, 11);
 		if (copy_from_user(reg_offset, buf + len,
-					min(10, ((int)size-len)))) {
+					min(10, (size-len)))) {
 			ret = -EFAULT;
 			goto error_free;
 		}
@@ -2185,11 +2186,11 @@
 	amdgpu_securedisplay_debugfs_init(adev);
 	amdgpu_fw_attestation_debugfs_init(adev);
 
-	debugfs_create_file("amdgpu_evict_vram", 0444, root, adev,
+	debugfs_create_file("amdgpu_evict_vram", 0400, root, adev,
 			    &amdgpu_evict_vram_fops);
-	debugfs_create_file("amdgpu_evict_gtt", 0444, root, adev,
+	debugfs_create_file("amdgpu_evict_gtt", 0400, root, adev,
 			    &amdgpu_evict_gtt_fops);
-	debugfs_create_file("amdgpu_test_ib", 0444, root, adev,
+	debugfs_create_file("amdgpu_test_ib", 0400, root, adev,
 			    &amdgpu_debugfs_test_ib_fops);
 	debugfs_create_file("amdgpu_vm_info", 0444, root, adev,
 			    &amdgpu_debugfs_vm_info_fops);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -3945,6 +3945,7 @@
 	mutex_init(&adev->grbm_idx_mutex);
 	mutex_init(&adev->mn_lock);
 	mutex_init(&adev->virt.vf_errors.lock);
+	mutex_init(&adev->virt.rlcg_reg_lock);
 	hash_init(adev->mn_hash);
 	mutex_init(&adev->psp.mutex);
 	mutex_init(&adev->notifier_lock);
@@ -4120,18 +4121,22 @@
 					adev->ip_blocks[i].status.hw = true;
 				}
 			}
+		} else if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) &&
+				   !amdgpu_device_has_display_hardware(adev)) {
+					r = psp_gpu_reset(adev);
 		} else {
-			tmp = amdgpu_reset_method;
-			/* It should do a default reset when loading or reloading the driver,
-			 * regardless of the module parameter reset_method.
-			 */
-			amdgpu_reset_method = AMD_RESET_METHOD_NONE;
-			r = amdgpu_asic_reset(adev);
-			amdgpu_reset_method = tmp;
-			if (r) {
-				dev_err(adev->dev, "asic reset on init failed\n");
-				goto failed;
-			}
+				tmp = amdgpu_reset_method;
+				/* It should do a default reset when loading or reloading the driver,
+				 * regardless of the module parameter reset_method.
+				 */
+				amdgpu_reset_method = AMD_RESET_METHOD_NONE;
+				r = amdgpu_asic_reset(adev);
+				amdgpu_reset_method = tmp;
+		}
+
+		if (r) {
+		  dev_err(adev->dev, "asic reset on init failed\n");
+		  goto failed;
 		}
 	}
 
@@ -4421,8 +4426,8 @@
 	int idx;
 	bool px;
 
-	amdgpu_fence_driver_sw_fini(adev);
 	amdgpu_device_ip_fini(adev);
+	amdgpu_fence_driver_sw_fini(adev);
 	amdgpu_ucode_release(&adev->firmware.gpu_info_fw);
 	adev->accel_working = false;
 	dma_fence_put(rcu_dereference_protected(adev->gang_submit, true));
@@ -4524,6 +4529,8 @@
 	if (r)
 		goto unprepare;
 
+	flush_delayed_work(&adev->gfx.gfx_off_delay_work);
+
 	for (i = 0; i < adev->num_ip_blocks; i++) {
 		if (!adev->ip_blocks[i].status.valid)
 			continue;
@@ -4894,7 +4901,8 @@
 		shadow = vmbo->shadow;
 
 		/* 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->parent->tbo.resource->mem_type != TTM_PL_VRAM)
 			continue;
@@ -4938,27 +4946,26 @@
  * amdgpu_device_reset_sriov - reset ASIC for SR-IOV vf
  *
  * @adev: amdgpu_device pointer
- * @from_hypervisor: request from hypervisor
+ * @reset_context: amdgpu reset context pointer
  *
  * do VF FLR and reinitialize Asic
  * return 0 means succeeded otherwise failed
  */
 static int amdgpu_device_reset_sriov(struct amdgpu_device *adev,
-				     bool from_hypervisor)
+				     struct amdgpu_reset_context *reset_context)
 {
 	int r;
 	struct amdgpu_hive_info *hive = NULL;
-	int retry_limit = 0;
 
-retry:
-	amdgpu_amdkfd_pre_reset(adev);
-
-	if (from_hypervisor)
+	if (test_bit(AMDGPU_HOST_FLR, &reset_context->flags)) {
+		clear_bit(AMDGPU_HOST_FLR, &reset_context->flags);
 		r = amdgpu_virt_request_full_gpu(adev, true);
-	else
+	} else {
 		r = amdgpu_virt_reset_gpu(adev);
+	}
 	if (r)
 		return r;
+
 	amdgpu_irq_gpu_reset_resume_helper(adev);
 
 	/* some sw clean up VF needs to do before recover */
@@ -4967,7 +4974,7 @@
 	/* Resume IP prior to SMC */
 	r = amdgpu_device_ip_reinit_early_sriov(adev);
 	if (r)
-		goto error;
+		return r;
 
 	amdgpu_virt_init_data_exchange(adev);
 
@@ -4978,38 +4985,35 @@
 	/* now we are okay to resume SMC/CP/SDMA */
 	r = amdgpu_device_ip_reinit_late_sriov(adev);
 	if (r)
-		goto error;
+		return r;
 
 	hive = amdgpu_get_xgmi_hive(adev);
 	/* Update PSP FW topology after reset */
 	if (hive && adev->gmc.xgmi.num_physical_nodes > 1)
 		r = amdgpu_xgmi_update_topology(hive, adev);
-
 	if (hive)
 		amdgpu_put_xgmi_hive(hive);
+	if (r)
+		return r;
 
-	if (!r) {
-		r = amdgpu_ib_ring_tests(adev);
-
-		amdgpu_amdkfd_post_reset(adev);
-	}
+	r = amdgpu_ib_ring_tests(adev);
+	if (r)
+		return r;
 
-error:
-	if (!r && adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) {
+	if (adev->virt.gim_feature & AMDGIM_FEATURE_GIM_FLR_VRAMLOST) {
 		amdgpu_inc_vram_lost(adev);
 		r = amdgpu_device_recover_vram(adev);
 	}
-	amdgpu_virt_release_full_gpu(adev, true);
+	if (r)
+		return r;
 
-	if (AMDGPU_RETRY_SRIOV_RESET(r)) {
-		if (retry_limit < AMDGPU_MAX_RETRY_LIMIT) {
-			retry_limit++;
-			goto retry;
-		} else
-			DRM_ERROR("GPU reset retry is beyond the retry limit\n");
-	}
+	/* need to be called during full access so we can't do it later like
+	 * bare-metal does.
+	 */
+	amdgpu_amdkfd_post_reset(adev);
+	amdgpu_virt_release_full_gpu(adev, true);
 
-	return r;
+	return 0;
 }
 
 /**
@@ -5100,11 +5104,14 @@
 
 	dev_info(adev->dev, "GPU mode1 reset\n");
 
+	/* Cache the state before bus master disable. The saved config space
+	 * values are used in other cases like restore after mode-2 reset.
+	 */
+	amdgpu_device_cache_pci_state(adev->pdev);
+
 	/* disable BM */
 	pci_clear_master(adev->pdev);
 
-	amdgpu_device_cache_pci_state(adev->pdev);
-
 	if (amdgpu_dpm_is_mode1_reset_supported(adev)) {
 		dev_info(adev->dev, "GPU smu mode1 reset\n");
 		ret = amdgpu_dpm_mode1_reset(adev);
@@ -5539,6 +5546,7 @@
 	int i, r = 0;
 	bool need_emergency_restart = false;
 	bool audio_suspended = false;
+	int retry_limit = AMDGPU_MAX_RETRY_LIMIT;
 
 	/*
 	 * Special case: RAS triggered and full reset isn't supported
@@ -5573,7 +5581,7 @@
 	 * to put adev in the 1st position.
 	 */
 	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_add_tail(&tmp_adev->reset_list, &device_list);
 			if (adev->shutdown)
@@ -5614,8 +5622,7 @@
 
 		cancel_delayed_work_sync(&tmp_adev->delayed_init_work);
 
-		if (!amdgpu_sriov_vf(tmp_adev))
-			amdgpu_amdkfd_pre_reset(tmp_adev);
+		amdgpu_amdkfd_pre_reset(tmp_adev);
 
 		/*
 		 * Mark these ASICs to be reseted as untracked first
@@ -5668,18 +5675,16 @@
 				  r, adev_to_drm(tmp_adev)->unique);
 			tmp_adev->asic_reset_res = r;
 		}
-
-		/*
-		 * Drop all pending non scheduler resets. Scheduler resets
-		 * were already dropped during drm_sched_stop
-		 */
-		amdgpu_device_stop_pending_resets(tmp_adev);
 	}
 
 	/* Actual ASIC resets if needed.*/
 	/* Host driver will handle XGMI hive reset for SRIOV */
 	if (amdgpu_sriov_vf(adev)) {
-		r = amdgpu_device_reset_sriov(adev, job ? false : true);
+		r = amdgpu_device_reset_sriov(adev, reset_context);
+		if (AMDGPU_RETRY_SRIOV_RESET(r) && (retry_limit--) > 0) {
+			amdgpu_virt_release_full_gpu(adev, true);
+			goto retry;
+		}
 		if (r)
 			adev->asic_reset_res = r;
 
@@ -5694,6 +5699,16 @@
 			goto retry;
 	}
 
+	list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
+		/*
+		 * Drop any pending non scheduler resets queued before reset is done.
+		 * Any reset scheduled after this point would be valid. Scheduler resets
+		 * were already dropped during drm_sched_stop and no new ones can come
+		 * in before drm_sched_start.
+		 */
+		amdgpu_device_stop_pending_resets(tmp_adev);
+	}
+
 skip_hw_reset:
 
 	/* Post ASIC reset for all devs .*/
@@ -5786,13 +5801,18 @@
 	*speed = PCI_SPEED_UNKNOWN;
 	*width = PCIE_LNK_WIDTH_UNKNOWN;
 
-	while ((parent = pci_upstream_bridge(parent))) {
-		/* skip upstream/downstream switches internal to dGPU*/
-		if (parent->vendor == PCI_VENDOR_ID_ATI)
-			continue;
-		*speed = pcie_get_speed_cap(parent);
-		*width = pcie_get_width_cap(parent);
-		break;
+	if (amdgpu_device_pcie_dynamic_switching_supported(adev)) {
+		while ((parent = pci_upstream_bridge(parent))) {
+			/* skip upstream/downstream switches internal to dGPU*/
+			if (parent->vendor == PCI_VENDOR_ID_ATI)
+				continue;
+			*speed = pcie_get_speed_cap(parent);
+			*width = pcie_get_width_cap(parent);
+			break;
+		}
+	} else {
+		/* use the current speeds rather than max if switching is not supported */
+		pcie_bandwidth_available(adev->pdev, NULL, speed, width);
 	}
 }
 
@@ -6007,7 +6027,7 @@
 	    adev->nbio.funcs->enable_doorbell_interrupt)
 		adev->nbio.funcs->enable_doorbell_interrupt(adev, true);
 
-	if (amdgpu_passthrough(adev) &&
+	if (amdgpu_passthrough(adev) && adev->nbio.funcs &&
 	    adev->nbio.funcs->clear_doorbell_interrupt)
 		adev->nbio.funcs->clear_doorbell_interrupt(adev);
 
@@ -6107,6 +6127,20 @@
 	struct amdgpu_reset_context reset_context;
 	u32 memsize;
 	struct list_head device_list;
+	struct amdgpu_hive_info *hive;
+	int hive_ras_recovery = 0;
+	struct amdgpu_ras *ras;
+
+	/* PCI error slot reset should be skipped During RAS recovery */
+	hive = amdgpu_get_xgmi_hive(adev);
+	if (hive) {
+		hive_ras_recovery = atomic_read(&hive->ras_recovery);
+		amdgpu_put_xgmi_hive(hive);
+	}
+	ras = amdgpu_ras_get_context(adev);
+	if ((amdgpu_ip_version(adev, GC_HWIP, 0) == IP_VERSION(9, 4, 3)) &&
+		 ras && (atomic_read(&ras->in_recovery) || hive_ras_recovery))
+		return PCI_ERS_RESULT_RECOVERED;
 
 	DRM_INFO("PCI error: slot reset callback!!\n");
 
@@ -6201,6 +6235,9 @@
 	struct amdgpu_device *adev = drm_to_adev(dev);
 	int r;
 
+	if (amdgpu_sriov_vf(adev))
+		return false;
+
 	r = pci_save_state(pdev);
 	if (!r) {
 		kfree(adev->pci_state);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -1278,11 +1278,10 @@
 				 *     0b10 : encode is disabled
 				 *     0b01 : decode is disabled
 				 */
-				adev->vcn.vcn_config[adev->vcn.num_vcn_inst] =
-					ip->revision & 0xc0;
-				ip->revision &= ~0xc0;
 				if (adev->vcn.num_vcn_inst <
 				    AMDGPU_MAX_VCN_INSTANCES) {
+					adev->vcn.vcn_config[adev->vcn.num_vcn_inst] =
+						ip->revision & 0xc0;
 					adev->vcn.num_vcn_inst++;
 					adev->vcn.inst_mask |=
 						(1U << ip->instance_number);
@@ -1293,6 +1292,7 @@
 						adev->vcn.num_vcn_inst + 1,
 						AMDGPU_MAX_VCN_INSTANCES);
 				}
+				ip->revision &= ~0xc0;
 			}
 			if (le16_to_cpu(ip->hw_id) == SDMA0_HWID ||
 			    le16_to_cpu(ip->hw_id) == SDMA1_HWID ||
@@ -1572,7 +1572,7 @@
 		break;
 	case 2:
 		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;
 	default:
 		dev_err(adev->dev,
@@ -1867,6 +1867,7 @@
 		amdgpu_device_ip_block_add(adev, &smu_v13_0_ip_block);
 		break;
 	case IP_VERSION(14, 0, 0):
+	case IP_VERSION(14, 0, 1):
 		amdgpu_device_ip_block_add(adev, &smu_v14_0_ip_block);
 		break;
 	default:
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -917,8 +917,7 @@
 {
 	u64 micro_tile_mode;
 
-	/* Zero swizzle mode means linear */
-	if (AMDGPU_TILING_GET(afb->tiling_flags, SWIZZLE_MODE) == 0)
+	if (AMDGPU_TILING_GET(afb->tiling_flags, ARRAY_MODE) == 1) /* LINEAR_ALIGNED */
 		return 0;
 
 	micro_tile_mode = AMDGPU_TILING_GET(afb->tiling_flags, MICRO_TILE_MODE);
@@ -1042,6 +1041,30 @@
 			block_width = 256 / format_info->cpp[i];
 			block_height = 1;
 			block_size_log2 = 8;
+		} else if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) >= AMD_FMT_MOD_TILE_VER_GFX12) {
+			int swizzle = AMD_FMT_MOD_GET(TILE, modifier);
+
+			switch (swizzle) {
+			case AMD_FMT_MOD_TILE_GFX12_256B_2D:
+				block_size_log2 = 8;
+				break;
+			case AMD_FMT_MOD_TILE_GFX12_4K_2D:
+				block_size_log2 = 12;
+				break;
+			case AMD_FMT_MOD_TILE_GFX12_64K_2D:
+				block_size_log2 = 16;
+				break;
+			case AMD_FMT_MOD_TILE_GFX12_256K_2D:
+				block_size_log2 = 18;
+				break;
+			default:
+				drm_dbg_kms(rfb->base.dev,
+					    "Gfx12 swizzle mode with unknown block size: %d\n", swizzle);
+				return -EINVAL;
+			}
+
+			get_block_dimensions(block_size_log2, format_info->cpp[i],
+					     &block_width, &block_height);
 		} else {
 			int swizzle = AMD_FMT_MOD_GET(TILE, modifier);
 
@@ -1077,7 +1100,8 @@
 			return ret;
 	}
 
-	if (AMD_FMT_MOD_GET(DCC, modifier)) {
+	if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) <= AMD_FMT_MOD_TILE_VER_GFX11 &&
+	    AMD_FMT_MOD_GET(DCC, modifier)) {
 		if (AMD_FMT_MOD_GET(DCC_RETILE, modifier)) {
 			block_size_log2 = get_dcc_block_size(modifier, false, false);
 			get_block_dimensions(block_size_log2 + 8, format_info->cpp[0],
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -849,12 +849,13 @@
  * the ABM algorithm, with 1 being the least reduction and 4 being the most
  * reduction.
  *
- * Defaults to 0, or disabled. Userspace can still override this level later
- * after boot.
+ * Defaults to -1, or disabled. Userspace can only override this level after
+ * boot if it's set to auto.
  */
-uint amdgpu_dm_abm_level;
-MODULE_PARM_DESC(abmlevel, "ABM level (0 = off (default), 1-4 = backlight reduction level) ");
-module_param_named(abmlevel, amdgpu_dm_abm_level, uint, 0444);
+int amdgpu_dm_abm_level = -1;
+MODULE_PARM_DESC(abmlevel,
+		 "ABM level (0 = off, 1-4 = backlight reduction level, -1 auto (default))");
+module_param_named(abmlevel, amdgpu_dm_abm_level, int, 0444);
 
 int amdgpu_backlight = -1;
 MODULE_PARM_DESC(backlight, "Backlight control (0 = pwm, 1 = aux, -1 auto (default))");
@@ -2451,8 +2452,11 @@
 	}
 	for (i = 0; i < mgpu_info.num_dgpu; i++) {
 		adev = mgpu_info.gpu_ins[i].adev;
-		if (!adev->kfd.init_complete)
+		if (!adev->kfd.init_complete) {
+			kgd2kfd_init_zone_device(adev);
 			amdgpu_amdkfd_device_init(adev);
+			amdgpu_amdkfd_drm_client_create(adev);
+		}
 		amdgpu_ttm_set_buffer_funcs_status(adev, true);
 	}
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.c
@@ -179,7 +179,7 @@
  * Returns the number of bytes read/written; -errno on error.
  */
 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;
 	u16 limit;
@@ -225,7 +225,7 @@
 
 int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap,
 		       u32 eeprom_addr, u8 *eeprom_buf,
-		       u16 bytes)
+		       u32 bytes)
 {
 	return amdgpu_eeprom_xfer(i2c_adap, eeprom_addr, eeprom_buf, bytes,
 				  true);
@@ -233,7 +233,7 @@
 
 int amdgpu_eeprom_write(struct i2c_adapter *i2c_adap,
 			u32 eeprom_addr, u8 *eeprom_buf,
-			u16 bytes)
+			u32 bytes)
 {
 	return amdgpu_eeprom_xfer(i2c_adap, eeprom_addr, eeprom_buf, bytes,
 				  false);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_eeprom.h
@@ -28,10 +28,10 @@
 
 int amdgpu_eeprom_read(struct i2c_adapter *i2c_adap,
 		       u32 eeprom_addr, u8 *eeprom_buf,
-		       u16 bytes);
+		       u32 bytes);
 
 int amdgpu_eeprom_write(struct i2c_adapter *i2c_adap,
 			u32 eeprom_addr, u8 *eeprom_buf,
-			u16 bytes);
+			u32 bytes);
 
 #endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c
@@ -97,6 +97,10 @@
 		   stats.requested_visible_vram/1024UL);
 	drm_printf(p, "amd-requested-gtt:\t%llu KiB\n",
 		   stats.requested_gtt/1024UL);
+	drm_printf(p, "drm-shared-vram:\t%llu KiB\n", stats.vram_shared/1024UL);
+	drm_printf(p, "drm-shared-gtt:\t%llu KiB\n", stats.gtt_shared/1024UL);
+	drm_printf(p, "drm-shared-cpu:\t%llu KiB\n", stats.cpu_shared/1024UL);
+
 	for (hw_ip = 0; hw_ip < AMDGPU_HW_IP_NUM; ++hw_ip) {
 		if (!usage[hw_ip])
 			continue;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_fw_attestation.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_fw_attestation.c
@@ -122,6 +122,10 @@
 	if (adev->flags & AMD_IS_APU)
 		return 0;
 
+	if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(14, 0, 2) ||
+	    amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(14, 0, 3))
+		return 0;
+
 	if (adev->asic_type >= CHIP_SIENNA_CICHLID)
 		return 1;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
@@ -34,6 +34,7 @@
 #include <asm/set_memory.h>
 #endif
 #include "amdgpu.h"
+#include "amdgpu_reset.h"
 #include <drm/drm_drv.h>
 #include <drm/ttm/ttm_tt.h>
 
@@ -408,7 +409,10 @@
 		return;
 
 	mb();
-	amdgpu_device_flush_hdp(adev, NULL);
+	if (down_read_trylock(&adev->reset_domain->sem)) {
+		amdgpu_device_flush_hdp(adev, NULL);
+		up_read(&adev->reset_domain->sem);
+	}
 	for_each_set_bit(i, adev->vmhubs_mask, AMDGPU_MAX_VMHUBS)
 		amdgpu_gmc_flush_gpu_tlb(adev, 0, i, 0);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -313,6 +313,9 @@
 		return -EINVAL;
 	}
 
+	/* always clear VRAM */
+	flags |= AMDGPU_GEM_CREATE_VRAM_CLEARED;
+
 	/* create a gem object to contain this object in */
 	if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS |
 	    AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
@@ -814,8 +814,11 @@
 	int r;
 
 	if (amdgpu_ras_is_supported(adev, ras_block->block)) {
-		if (!amdgpu_persistent_edc_harvesting_supported(adev))
-			amdgpu_ras_reset_error_status(adev, AMDGPU_RAS_BLOCK__GFX);
+		if (!amdgpu_persistent_edc_harvesting_supported(adev)) {
+			r = amdgpu_ras_reset_error_status(adev, AMDGPU_RAS_BLOCK__GFX);
+			if (r)
+				return r;
+		}
 
 		r = amdgpu_ras_block_late_init(adev, ras_block);
 		if (r)
@@ -959,7 +962,10 @@
 		pr_err("critical bug! too many kiq readers\n");
 		goto failed_unlock;
 	}
-	amdgpu_ring_alloc(ring, 32);
+	r = amdgpu_ring_alloc(ring, 32);
+	if (r)
+		goto failed_unlock;
+
 	amdgpu_ring_emit_rreg(ring, reg, reg_val_offs);
 	r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
 	if (r)
@@ -1025,7 +1031,10 @@
 	}
 
 	spin_lock_irqsave(&kiq->ring_lock, flags);
-	amdgpu_ring_alloc(ring, 32);
+	r = amdgpu_ring_alloc(ring, 32);
+	if (r)
+		goto failed_unlock;
+
 	amdgpu_ring_emit_wreg(ring, reg, v);
 	r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
 	if (r)
@@ -1061,6 +1070,7 @@
 
 failed_undo:
 	amdgpu_ring_undo(ring);
+failed_unlock:
 	spin_unlock_irqrestore(&kiq->ring_lock, flags);
 failed_kiq_write:
 	dev_err(adev->dev, "failed to write reg:%x\n", reg);
@@ -1205,7 +1215,8 @@
 		fw_size = le32_to_cpu(cp_hdr_v2_0->data_size_bytes);
 		break;
 	default:
-		break;
+		dev_err(adev->dev, "Invalid ucode id %u\n", ucode_id);
+		return;
 	}
 
 	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -684,12 +684,17 @@
 	struct amdgpu_ring *ring = &adev->gfx.kiq[inst].ring;
 	struct amdgpu_kiq *kiq = &adev->gfx.kiq[inst];
 	unsigned int ndw;
-	signed long r;
+	int r;
 	uint32_t seq;
 
-	if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready ||
-	    !down_read_trylock(&adev->reset_domain->sem)) {
+	/*
+	 * A GPU reset should flush all TLBs anyway, so no need to do
+	 * this while one is ongoing.
+	 */
+	if (!down_read_trylock(&adev->reset_domain->sem))
+		return 0;
 
+	if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready) {
 		if (adev->gmc.flush_tlb_needs_extra_type_2)
 			adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
 								 2, all_hub,
@@ -703,43 +708,44 @@
 		adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
 							 flush_type, all_hub,
 							 inst);
-		return 0;
-	}
+		r = 0;
+	} else {
+		/* 2 dwords flush + 8 dwords fence */
+		ndw = kiq->pmf->invalidate_tlbs_size + 8;
+
+		if (adev->gmc.flush_tlb_needs_extra_type_2)
+			ndw += kiq->pmf->invalidate_tlbs_size;
+
+		if (adev->gmc.flush_tlb_needs_extra_type_0)
+			ndw += kiq->pmf->invalidate_tlbs_size;
 
-	/* 2 dwords flush + 8 dwords fence */
-	ndw = kiq->pmf->invalidate_tlbs_size + 8;
+		spin_lock(&adev->gfx.kiq[inst].ring_lock);
+		r = amdgpu_ring_alloc(ring, ndw);
+		if (r) {
+			spin_unlock(&adev->gfx.kiq[inst].ring_lock);
+			goto error_unlock_reset;
+		}
+		if (adev->gmc.flush_tlb_needs_extra_type_2)
+			kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub);
 
-	if (adev->gmc.flush_tlb_needs_extra_type_2)
-		ndw += kiq->pmf->invalidate_tlbs_size;
+		if (flush_type == 2 && adev->gmc.flush_tlb_needs_extra_type_0)
+			kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 0, all_hub);
 
-	if (adev->gmc.flush_tlb_needs_extra_type_0)
-		ndw += kiq->pmf->invalidate_tlbs_size;
+		kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub);
+		r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
+		if (r) {
+			amdgpu_ring_undo(ring);
+			spin_unlock(&adev->gfx.kiq[inst].ring_lock);
+			goto error_unlock_reset;
+		}
 
-	spin_lock(&adev->gfx.kiq[inst].ring_lock);
-	amdgpu_ring_alloc(ring, ndw);
-	if (adev->gmc.flush_tlb_needs_extra_type_2)
-		kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub);
-
-	if (flush_type == 2 && adev->gmc.flush_tlb_needs_extra_type_0)
-		kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 0, all_hub);
-
-	kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub);
-	r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
-	if (r) {
-		amdgpu_ring_undo(ring);
+		amdgpu_ring_commit(ring);
 		spin_unlock(&adev->gfx.kiq[inst].ring_lock);
-		goto error_unlock_reset;
-	}
-
-	amdgpu_ring_commit(ring);
-	spin_unlock(&adev->gfx.kiq[inst].ring_lock);
-	r = amdgpu_fence_wait_polling(ring, seq, usec_timeout);
-	if (r < 1) {
-		dev_err(adev->dev, "wait for kiq fence error: %ld.\n", r);
-		r = -ETIME;
-		goto error_unlock_reset;
+		if (amdgpu_fence_wait_polling(ring, seq, usec_timeout) < 1) {
+			dev_err(adev->dev, "timeout waiting for kiq fence\n");
+			r = -ETIME;
+		}
 	}
-	r = 0;
 
 error_unlock_reset:
 	up_read(&adev->reset_domain->sem);
@@ -822,7 +828,6 @@
 	struct amdgpu_gmc *gmc = &adev->gmc;
 	uint32_t gc_ver = amdgpu_ip_version(adev, GC_HWIP, 0);
 	bool noretry_default = (gc_ver == IP_VERSION(9, 0, 1) ||
-				gc_ver == IP_VERSION(9, 3, 0) ||
 				gc_ver == IP_VERSION(9, 4, 0) ||
 				gc_ver == IP_VERSION(9, 4, 1) ||
 				gc_ver == IP_VERSION(9, 4, 2) ||
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c
@@ -129,13 +129,25 @@
  */
 int amdgpu_hmm_register(struct amdgpu_bo *bo, unsigned long addr)
 {
+	int r;
+
 	if (bo->kfd_bo)
-		return mmu_interval_notifier_insert(&bo->notifier, current->mm,
+		r = mmu_interval_notifier_insert(&bo->notifier, current->mm,
 						    addr, amdgpu_bo_size(bo),
 						    &amdgpu_hmm_hsa_ops);
-	return mmu_interval_notifier_insert(&bo->notifier, current->mm, addr,
-					    amdgpu_bo_size(bo),
-					    &amdgpu_hmm_gfx_ops);
+	else
+		r = mmu_interval_notifier_insert(&bo->notifier, current->mm, addr,
+							amdgpu_bo_size(bo),
+							&amdgpu_hmm_gfx_ops);
+	if (r)
+		/*
+		 * Make sure amdgpu_hmm_unregister() doesn't call
+		 * mmu_interval_notifier_remove() when the notifier isn't properly
+		 * initialized.
+		 */
+		bo->notifier.mm = NULL;
+
+	return r;
 }
 
 /**
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -193,8 +193,8 @@
 	need_ctx_switch = ring->current_ctx != fence_ctx;
 	if (ring->funcs->emit_pipeline_sync && job &&
 	    ((tmp = amdgpu_sync_get_fence(&job->explicit_sync)) ||
-	     (amdgpu_sriov_vf(adev) && need_ctx_switch) ||
-	     amdgpu_vm_need_pipeline_sync(ring, job))) {
+	     need_ctx_switch || amdgpu_vm_need_pipeline_sync(ring, job))) {
+
 		need_pipe_sync = true;
 
 		if (tmp)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
@@ -407,7 +407,7 @@
 	if (r || !idle)
 		goto error;
 
-	if (vm->reserved_vmid[vmhub] || (enforce_isolation && (vmhub == AMDGPU_GFXHUB(0)))) {
+	if (amdgpu_vmid_uses_reserved(vm, vmhub)) {
 		r = amdgpu_vmid_grab_reserved(vm, ring, job, &id, fence);
 		if (r || !id)
 			goto error;
@@ -457,6 +457,19 @@
 	return r;
 }
 
+/*
+ * amdgpu_vmid_uses_reserved - check if a VM will use a reserved VMID
+ * @vm: the VM to check
+ * @vmhub: the VMHUB which will be used
+ *
+ * Returns: True if the VM will use a reserved VMID.
+ */
+bool amdgpu_vmid_uses_reserved(struct amdgpu_vm *vm, unsigned int vmhub)
+{
+	return vm->reserved_vmid[vmhub] ||
+		(enforce_isolation && (vmhub == AMDGPU_GFXHUB(0)));
+}
+
 int amdgpu_vmid_alloc_reserved(struct amdgpu_device *adev,
 			       unsigned vmhub)
 {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h
@@ -78,6 +78,7 @@
 
 bool amdgpu_vmid_had_gpu_reset(struct amdgpu_device *adev,
 			       struct amdgpu_vmid *id);
+bool amdgpu_vmid_uses_reserved(struct amdgpu_vm *vm, unsigned int vmhub);
 int amdgpu_vmid_alloc_reserved(struct amdgpu_device *adev,
 				unsigned vmhub);
 void amdgpu_vmid_free_reserved(struct amdgpu_device *adev,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c
@@ -445,6 +445,14 @@
 
 	entry.ih = ih;
 	entry.iv_entry = (const uint32_t *)&ih->ring[ring_index];
+
+	/*
+	 * timestamp is not supported on some legacy SOCs (cik, cz, iceland,
+	 * si and tonga), so initialize timestamp and timestamp_src to 0
+	 */
+	entry.timestamp = 0;
+	entry.timestamp_src = 0;
+
 	amdgpu_ih_decode_iv(adev, &entry);
 
 	trace_amdgpu_iv(ih - &adev->irq.ih, &entry);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -159,7 +159,6 @@
 
 void amdgpu_job_free_resources(struct amdgpu_job *job)
 {
-	struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched);
 	struct dma_fence *f;
 	unsigned i;
 
@@ -172,7 +171,7 @@
 		f = NULL;
 
 	for (i = 0; i < job->num_ibs; ++i)
-		amdgpu_ib_free(ring->adev, &job->ibs[i], f);
+		amdgpu_ib_free(NULL, &job->ibs[i], f);
 }
 
 static void amdgpu_job_free_cb(struct drm_sched_job *s_job)
@@ -258,9 +257,8 @@
 	struct dma_fence *fence = NULL;
 	int r;
 
-	/* Ignore soft recovered fences here */
 	r = drm_sched_entity_error(s_entity);
-	if (r && r != -ENODATA)
+	if (r)
 		goto error;
 
 	if (!fence && job->gang_submit)
@@ -300,12 +298,15 @@
 		dma_fence_set_error(finished, -ECANCELED);
 
 	if (finished->error < 0) {
-		DRM_INFO("Skip scheduling IBs!\n");
+		dev_dbg(adev->dev, "Skip scheduling IBs in ring(%s)",
+			ring->name);
 	} else {
 		r = amdgpu_ib_schedule(ring, job->num_ibs, job->ibs, job,
 				       &fence);
 		if (r)
-			DRM_ERROR("Error scheduling IBs (%d)\n", r);
+			dev_err(adev->dev,
+				"Error scheduling IBs (%d) in ring(%s)", r,
+				ring->name);
 	}
 
 	job->job_run_counter++;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -43,6 +43,7 @@
 #include "amdgpu_gem.h"
 #include "amdgpu_display.h"
 #include "amdgpu_ras.h"
+#include "amdgpu_reset.h"
 #include "amd_pcie.h"
 
 void amdgpu_unregister_gpu_instance(struct amdgpu_device *adev)
@@ -654,25 +655,32 @@
 			switch (type) {
 			case AMD_IP_BLOCK_TYPE_GFX:
 				ret = amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_GFX, &inst_mask);
+				if (ret)
+					return ret;
 				count = hweight32(inst_mask);
 				break;
 			case AMD_IP_BLOCK_TYPE_SDMA:
 				ret = amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_SDMA, &inst_mask);
+				if (ret)
+					return ret;
 				count = hweight32(inst_mask);
 				break;
 			case AMD_IP_BLOCK_TYPE_JPEG:
 				ret = amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_VCN, &inst_mask);
+				if (ret)
+					return ret;
 				count = hweight32(inst_mask) * adev->jpeg.num_jpeg_rings;
 				break;
 			case AMD_IP_BLOCK_TYPE_VCN:
 				ret = amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_VCN, &inst_mask);
+				if (ret)
+					return ret;
 				count = hweight32(inst_mask);
 				break;
 			default:
 				return -EINVAL;
 			}
-			if (ret)
-				return ret;
+
 			return copy_to_user(out, &count, min(size, 4u)) ? -EFAULT : 0;
 		}
 
@@ -802,6 +810,7 @@
 				    ? -EFAULT : 0;
 	}
 	case AMDGPU_INFO_READ_MMR_REG: {
+		int ret = 0;
 		unsigned int n, alloc_size;
 		uint32_t *regs;
 		unsigned int se_num = (info->read_mmr_reg.instance >>
@@ -811,24 +820,37 @@
 				   AMDGPU_INFO_MMR_SH_INDEX_SHIFT) &
 				  AMDGPU_INFO_MMR_SH_INDEX_MASK;
 
+		if (!down_read_trylock(&adev->reset_domain->sem))
+			return -ENOENT;
+
 		/* set full masks if the userspace set all bits
 		 * in the bitfields
 		 */
-		if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK)
+		if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK) {
 			se_num = 0xffffffff;
-		else if (se_num >= AMDGPU_GFX_MAX_SE)
-			return -EINVAL;
-		if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK)
+		} else if (se_num >= AMDGPU_GFX_MAX_SE) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (sh_num == AMDGPU_INFO_MMR_SH_INDEX_MASK) {
 			sh_num = 0xffffffff;
-		else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE)
-			return -EINVAL;
+		} else if (sh_num >= AMDGPU_GFX_MAX_SH_PER_SE) {
+			ret = -EINVAL;
+			goto out;
+		}
 
-		if (info->read_mmr_reg.count > 128)
-			return -EINVAL;
+		if (info->read_mmr_reg.count > 128) {
+			ret = -EINVAL;
+			goto out;
+		}
 
 		regs = kmalloc_array(info->read_mmr_reg.count, sizeof(*regs), GFP_KERNEL);
-		if (!regs)
-			return -ENOMEM;
+		if (!regs) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
 		alloc_size = info->read_mmr_reg.count * sizeof(*regs);
 
 		amdgpu_gfx_off_ctrl(adev, false);
@@ -840,13 +862,17 @@
 					      info->read_mmr_reg.dword_offset + i);
 				kfree(regs);
 				amdgpu_gfx_off_ctrl(adev, true);
-				return -EFAULT;
+				ret = -EFAULT;
+				goto out;
 			}
 		}
 		amdgpu_gfx_off_ctrl(adev, true);
 		n = copy_to_user(out, regs, min(size, alloc_size));
 		kfree(regs);
-		return n ? -EFAULT : 0;
+		ret = (n ? -EFAULT : 0);
+out:
+		up_read(&adev->reset_domain->sem);
+		return ret;
 	}
 	case AMDGPU_INFO_DEV_INFO: {
 		struct drm_amdgpu_info_device *dev_info;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -1084,8 +1084,10 @@
 
 	r = amdgpu_ring_init(adev, ring, 1024, NULL, 0,
 			     AMDGPU_RING_PRIO_DEFAULT, NULL);
-	if (r)
+	if (r) {
+		amdgpu_mes_unlock(&adev->mes);
 		goto clean_up_memory;
+	}
 
 	amdgpu_mes_ring_to_queue_props(adev, ring, &qprops);
 
@@ -1118,7 +1120,6 @@
 	amdgpu_ring_fini(ring);
 clean_up_memory:
 	kfree(ring);
-	amdgpu_mes_unlock(&adev->mes);
 	return r;
 }
 
@@ -1129,6 +1130,7 @@
 		return;
 
 	amdgpu_mes_remove_hw_queue(adev, ring->hw_queue_id);
+	del_timer_sync(&ring->fence_drv.fallback_timer);
 	amdgpu_ring_fini(ring);
 	kfree(ring);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -608,6 +608,8 @@
 	else
 		amdgpu_bo_placement_from_domain(bo, bp->domain);
 	if (bp->type == ttm_bo_type_kernel)
+		bo->tbo.priority = 2;
+	else if (!(bp->flags & AMDGPU_GEM_CREATE_DISCARDABLE))
 		bo->tbo.priority = 1;
 
 	if (!bp->destroy)
@@ -620,8 +622,7 @@
 		return r;
 
 	if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
-	    bo->tbo.resource->mem_type == TTM_PL_VRAM &&
-	    amdgpu_bo_in_cpu_visible_vram(bo))
+	    amdgpu_res_cpu_visible(adev, bo->tbo.resource))
 		amdgpu_cs_report_moved_bytes(adev, ctx.bytes_moved,
 					     ctx.bytes_moved);
 	else
@@ -1245,14 +1246,18 @@
  * amdgpu_bo_move_notify - notification about a memory move
  * @bo: pointer to a buffer object
  * @evict: if this move is evicting the buffer from the graphics address space
+ * @new_mem: new resource for backing the BO
  *
  * Marks the corresponding &amdgpu_bo buffer object as invalid, also performs
  * bookkeeping.
  * TTM driver callback which is called when ttm moves a buffer.
  */
-void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict)
+void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
+			   bool evict,
+			   struct ttm_resource *new_mem)
 {
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
+	struct ttm_resource *old_mem = bo->resource;
 	struct amdgpu_bo *abo;
 
 	if (!amdgpu_bo_is_amdgpu_bo(bo))
@@ -1264,37 +1269,50 @@
 	amdgpu_bo_kunmap(abo);
 
 	if (abo->tbo.base.dma_buf && !abo->tbo.base.import_attach &&
-	    bo->resource->mem_type != TTM_PL_SYSTEM)
+	    old_mem && old_mem->mem_type != TTM_PL_SYSTEM)
 		dma_buf_move_notify(abo->tbo.base.dma_buf);
 
-	/* remember the eviction */
-	if (evict)
-		atomic64_inc(&adev->num_evictions);
+	/* move_notify is called before move happens */
+	trace_amdgpu_bo_move(abo, new_mem ? new_mem->mem_type : -1,
+			     old_mem ? old_mem->mem_type : -1);
 }
 
 void amdgpu_bo_get_memory(struct amdgpu_bo *bo,
 			  struct amdgpu_mem_stats *stats)
 {
+	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
+	struct ttm_resource *res = bo->tbo.resource;
 	uint64_t size = amdgpu_bo_size(bo);
+	struct drm_gem_object *obj;
 	unsigned int domain;
+	bool shared;
 
 	/* Abort if the BO doesn't currently have a backing store */
-	if (!bo->tbo.resource)
+	if (!res)
 		return;
 
-	domain = amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type);
+	obj = &bo->tbo.base;
+	shared = drm_gem_object_is_shared_for_memory_stats(obj);
+
+	domain = amdgpu_mem_type_to_domain(res->mem_type);
 	switch (domain) {
 	case AMDGPU_GEM_DOMAIN_VRAM:
 		stats->vram += size;
-		if (amdgpu_bo_in_cpu_visible_vram(bo))
+		if (amdgpu_res_cpu_visible(adev, bo->tbo.resource))
 			stats->visible_vram += size;
+		if (shared)
+			stats->vram_shared += size;
 		break;
 	case AMDGPU_GEM_DOMAIN_GTT:
 		stats->gtt += size;
+		if (shared)
+			stats->gtt_shared += size;
 		break;
 	case AMDGPU_GEM_DOMAIN_CPU:
 	default:
 		stats->cpu += size;
+		if (shared)
+			stats->cpu_shared += size;
 		break;
 	}
 
@@ -1381,10 +1399,7 @@
 	/* Remember that this BO was accessed by the CPU */
 	abo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
 
-	if (bo->resource->mem_type != TTM_PL_VRAM)
-		return 0;
-
-	if (amdgpu_bo_in_cpu_visible_vram(abo))
+	if (amdgpu_res_cpu_visible(adev, bo->resource))
 		return 0;
 
 	/* Can't move a pinned BO to visible VRAM */
@@ -1408,7 +1423,7 @@
 
 	/* this should never happen */
 	if (bo->resource->mem_type == TTM_PL_VRAM &&
-	    !amdgpu_bo_in_cpu_visible_vram(abo))
+	    !amdgpu_res_cpu_visible(adev, bo->resource))
 		return VM_FAULT_SIGBUS;
 
 	ttm_bo_move_to_lru_tail_unlocked(bo);
@@ -1572,6 +1587,7 @@
  */
 u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m)
 {
+	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 	struct dma_buf_attachment *attachment;
 	struct dma_buf *dma_buf;
 	const char *placement;
@@ -1580,10 +1596,11 @@
 
 	if (dma_resv_trylock(bo->tbo.base.resv)) {
 		unsigned int domain;
+
 		domain = amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type);
 		switch (domain) {
 		case AMDGPU_GEM_DOMAIN_VRAM:
-			if (amdgpu_bo_in_cpu_visible_vram(bo))
+			if (amdgpu_res_cpu_visible(adev, bo->tbo.resource))
 				placement = "VRAM VISIBLE";
 			else
 				placement = "VRAM";
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
@@ -138,12 +138,18 @@
 struct amdgpu_mem_stats {
 	/* current VRAM usage, includes visible VRAM */
 	uint64_t vram;
+	/* current shared VRAM usage, includes visible VRAM */
+	uint64_t vram_shared;
 	/* current visible VRAM usage */
 	uint64_t visible_vram;
 	/* current GTT usage */
 	uint64_t gtt;
+	/* current shared GTT usage */
+	uint64_t gtt_shared;
 	/* current system memory usage */
 	uint64_t cpu;
+	/* current shared system memory usage */
+	uint64_t cpu_shared;
 	/* sum of evicted buffers, includes visible VRAM */
 	uint64_t evicted_vram;
 	/* sum of evicted buffers due to CPU access */
@@ -245,28 +251,6 @@
 }
 
 /**
- * amdgpu_bo_in_cpu_visible_vram - check if BO is (partly) in visible VRAM
- */
-static inline bool amdgpu_bo_in_cpu_visible_vram(struct amdgpu_bo *bo)
-{
-	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
-	struct amdgpu_res_cursor cursor;
-
-	if (!bo->tbo.resource || bo->tbo.resource->mem_type != TTM_PL_VRAM)
-		return false;
-
-	amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor);
-	while (cursor.remaining) {
-		if (cursor.start < adev->gmc.visible_vram_size)
-			return true;
-
-		amdgpu_res_next(&cursor, cursor.size);
-	}
-
-	return false;
-}
-
-/**
  * amdgpu_bo_explicit_sync - return whether the bo is explicitly synced
  */
 static inline bool amdgpu_bo_explicit_sync(struct amdgpu_bo *bo)
@@ -344,7 +328,9 @@
 int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer,
 			   size_t buffer_size, uint32_t *metadata_size,
 			   uint64_t *flags);
-void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict);
+void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
+			   bool evict,
+			   struct ttm_resource *new_mem);
 void amdgpu_bo_release_notify(struct ttm_buffer_object *bo);
 vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
 void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -1340,6 +1340,9 @@
 	uint8_t dst_num_links = node_info.num_links;
 
 	hive = amdgpu_get_xgmi_hive(psp->adev);
+	if (WARN_ON(!hive))
+		return;
+
 	list_for_each_entry(mirror_adev, &hive->device_list, gmc.xgmi.head) {
 		struct psp_xgmi_topology_info *mirror_top_info;
 		int j;
@@ -1546,6 +1549,68 @@
 	}
 }
 
+static int psp_ras_send_cmd(struct psp_context *psp,
+		enum ras_command cmd_id, void *in, void *out)
+{
+	struct ta_ras_shared_memory *ras_cmd;
+	uint32_t cmd = cmd_id;
+	int ret = 0;
+
+	if (!in)
+		return -EINVAL;
+
+	mutex_lock(&psp->ras_context.mutex);
+	ras_cmd = (struct ta_ras_shared_memory *)psp->ras_context.context.mem_context.shared_buf;
+	memset(ras_cmd, 0, sizeof(struct ta_ras_shared_memory));
+
+	switch (cmd) {
+	case TA_RAS_COMMAND__ENABLE_FEATURES:
+	case TA_RAS_COMMAND__DISABLE_FEATURES:
+		memcpy(&ras_cmd->ras_in_message,
+			in, sizeof(ras_cmd->ras_in_message));
+		break;
+	case TA_RAS_COMMAND__TRIGGER_ERROR:
+		memcpy(&ras_cmd->ras_in_message.trigger_error,
+			in, sizeof(ras_cmd->ras_in_message.trigger_error));
+		break;
+	case TA_RAS_COMMAND__QUERY_ADDRESS:
+		memcpy(&ras_cmd->ras_in_message.address,
+			in, sizeof(ras_cmd->ras_in_message.address));
+		break;
+	default:
+		dev_err(psp->adev->dev, "Invalid ras cmd id: %u\n", cmd);
+		ret = -EINVAL;
+		goto err_out;
+	}
+
+	ras_cmd->cmd_id = cmd;
+	ret = psp_ras_invoke(psp, ras_cmd->cmd_id);
+
+	switch (cmd) {
+	case TA_RAS_COMMAND__TRIGGER_ERROR:
+		if (ret || psp->cmd_buf_mem->resp.status)
+			ret = -EINVAL;
+		else if (out)
+			memcpy(out, &ras_cmd->ras_status, sizeof(ras_cmd->ras_status));
+		break;
+	case TA_RAS_COMMAND__QUERY_ADDRESS:
+		if (ret || ras_cmd->ras_status || psp->cmd_buf_mem->resp.status)
+			ret = -EINVAL;
+		else if (out)
+			memcpy(out,
+				&ras_cmd->ras_out_message.address,
+				sizeof(ras_cmd->ras_out_message.address));
+		break;
+	default:
+		break;
+	}
+
+err_out:
+	mutex_unlock(&psp->ras_context.mutex);
+
+	return ret;
+}
+
 int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id)
 {
 	struct ta_ras_shared_memory *ras_cmd;
@@ -1587,23 +1652,15 @@
 int psp_ras_enable_features(struct psp_context *psp,
 		union ta_ras_cmd_input *info, bool enable)
 {
-	struct ta_ras_shared_memory *ras_cmd;
+	enum ras_command cmd_id;
 	int ret;
 
-	if (!psp->ras_context.context.initialized)
+	if (!psp->ras_context.context.initialized || !info)
 		return -EINVAL;
 
-	ras_cmd = (struct ta_ras_shared_memory *)psp->ras_context.context.mem_context.shared_buf;
-	memset(ras_cmd, 0, sizeof(struct ta_ras_shared_memory));
-
-	if (enable)
-		ras_cmd->cmd_id = TA_RAS_COMMAND__ENABLE_FEATURES;
-	else
-		ras_cmd->cmd_id = TA_RAS_COMMAND__DISABLE_FEATURES;
-
-	ras_cmd->ras_in_message = *info;
-
-	ret = psp_ras_invoke(psp, ras_cmd->cmd_id);
+	cmd_id = enable ?
+		TA_RAS_COMMAND__ENABLE_FEATURES : TA_RAS_COMMAND__DISABLE_FEATURES;
+	ret = psp_ras_send_cmd(psp, cmd_id, info, NULL);
 	if (ret)
 		return -EINVAL;
 
@@ -1627,6 +1684,8 @@
 
 	psp->ras_context.context.initialized = false;
 
+	mutex_destroy(&psp->ras_context.mutex);
+
 	return ret;
 }
 
@@ -1711,9 +1770,10 @@
 
 	ret = psp_ta_load(psp, &psp->ras_context.context);
 
-	if (!ret && !ras_cmd->ras_status)
+	if (!ret && !ras_cmd->ras_status) {
 		psp->ras_context.context.initialized = true;
-	else {
+		mutex_init(&psp->ras_context.mutex);
+	} else {
 		if (ras_cmd->ras_status)
 			dev_warn(psp->adev->dev, "RAS Init Status: 0x%X\n", ras_cmd->ras_status);
 
@@ -1727,12 +1787,12 @@
 int psp_ras_trigger_error(struct psp_context *psp,
 			  struct ta_ras_trigger_error_input *info, uint32_t instance_mask)
 {
-	struct ta_ras_shared_memory *ras_cmd;
 	struct amdgpu_device *adev = psp->adev;
 	int ret;
 	uint32_t dev_mask;
+	uint32_t ras_status = 0;
 
-	if (!psp->ras_context.context.initialized)
+	if (!psp->ras_context.context.initialized || !info)
 		return -EINVAL;
 
 	switch (info->block_id) {
@@ -1756,13 +1816,8 @@
 	dev_mask &= AMDGPU_RAS_INST_MASK;
 	info->sub_block_index |= dev_mask;
 
-	ras_cmd = (struct ta_ras_shared_memory *)psp->ras_context.context.mem_context.shared_buf;
-	memset(ras_cmd, 0, sizeof(struct ta_ras_shared_memory));
-
-	ras_cmd->cmd_id = TA_RAS_COMMAND__TRIGGER_ERROR;
-	ras_cmd->ras_in_message.trigger_error = *info;
-
-	ret = psp_ras_invoke(psp, ras_cmd->cmd_id);
+	ret = psp_ras_send_cmd(psp,
+			TA_RAS_COMMAND__TRIGGER_ERROR, info, &ras_status);
 	if (ret)
 		return -EINVAL;
 
@@ -1772,11 +1827,36 @@
 	if (amdgpu_ras_intr_triggered())
 		return 0;
 
-	if (ras_cmd->ras_status == TA_RAS_STATUS__TEE_ERROR_ACCESS_DENIED)
+	if (ras_status == TA_RAS_STATUS__TEE_ERROR_ACCESS_DENIED)
 		return -EACCES;
-	else if (ras_cmd->ras_status)
+	else if (ras_status)
+		return -EINVAL;
+
+	return 0;
+}
+
+int psp_ras_query_address(struct psp_context *psp,
+			  struct ta_ras_query_address_input *addr_in,
+			  struct ta_ras_query_address_output *addr_out)
+{
+	struct ta_ras_shared_memory *ras_cmd;
+	int ret;
+
+	if (!psp->ras_context.context.initialized)
 		return -EINVAL;
 
+	ras_cmd = (struct ta_ras_shared_memory *)psp->ras_context.context.mem_context.shared_buf;
+	memset(ras_cmd, 0, sizeof(struct ta_ras_shared_memory));
+
+	ras_cmd->cmd_id = TA_RAS_COMMAND__QUERY_ADDRESS;
+	ras_cmd->ras_in_message.address = *addr_in;
+
+	ret = psp_ras_invoke(psp, ras_cmd->cmd_id);
+	if (ret || ras_cmd->ras_status || psp->cmd_buf_mem->resp.status)
+		return -EINVAL;
+
+	*addr_out = ras_cmd->ras_out_message.address;
+
 	return 0;
 }
 // ras end
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
@@ -197,6 +197,7 @@
 struct psp_ras_context {
 	struct ta_context		context;
 	struct amdgpu_ras		*ras;
+	struct mutex			mutex;
 };
 
 #define MEM_TRAIN_SYSTEM_SIGNATURE		0x54534942
@@ -502,6 +503,9 @@
 int psp_ras_trigger_error(struct psp_context *psp,
 			  struct ta_ras_trigger_error_input *info, uint32_t instance_mask);
 int psp_ras_terminate(struct psp_context *psp);
+int psp_ras_query_address(struct psp_context *psp,
+			  struct ta_ras_query_address_input *addr_in,
+			  struct ta_ras_query_address_output *addr_out);
 
 int psp_hdcp_invoke(struct psp_context *psp, uint32_t ta_cmd_id);
 int psp_dtm_invoke(struct psp_context *psp, uint32_t ta_cmd_id);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c
@@ -166,6 +166,9 @@
 	if (ret)
 		return -EFAULT;
 
+	if (ta_bin_len > PSP_1_MEG)
+		return -EINVAL;
+
 	copy_pos += sizeof(uint32_t);
 
 	ta_bin = kzalloc(ta_bin_len, GFP_KERNEL);
@@ -334,7 +337,7 @@
 
 	set_ta_context_funcs(psp, ta_type, &context);
 
-	if (!context->initialized) {
+	if (!context || !context->initialized) {
 		dev_err(adev->dev, "TA is not initialized\n");
 		ret = -EINVAL;
 		goto err_free_shared_buf;
@@ -348,6 +351,7 @@
 
 	context->session_id = ta_id;
 
+	mutex_lock(&psp->ras_context.mutex);
 	ret = prep_ta_mem_context(&context->mem_context, shared_buf, shared_buf_len);
 	if (ret)
 		goto err_free_shared_buf;
@@ -366,6 +370,7 @@
 		ret = -EFAULT;
 
 err_free_shared_buf:
+	mutex_unlock(&psp->ras_context.mutex);
 	kfree(shared_buf);
 
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -1998,12 +1998,15 @@
 int amdgpu_ras_interrupt_dispatch(struct amdgpu_device *adev,
 		struct ras_dispatch_if *info)
 {
-	struct ras_manager *obj = amdgpu_ras_find_obj(adev, &info->head);
-	struct ras_ih_data *data = &obj->ih_data;
+	struct ras_manager *obj;
+	struct ras_ih_data *data;
 
+	obj = amdgpu_ras_find_obj(adev, &info->head);
 	if (!obj)
 		return -EINVAL;
 
+	data = &obj->ih_data;
+
 	if (data->inuse == 0)
 		return 0;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.h
@@ -38,6 +38,7 @@
  */
 #define AMDGPU_RAS_INST_MASK 0xfffff000
 #define AMDGPU_RAS_INST_SHIFT 0xc
+#define AMDGPU_RAS_GPU_ERR_HBM_ID(x)			AMDGPU_GET_REG_FIELD(x, 14, 13)
 
 enum amdgpu_ras_block {
 	AMDGPU_RAS_BLOCK__UMC = 0,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h
@@ -32,6 +32,7 @@
 
 	AMDGPU_NEED_FULL_RESET = 0,
 	AMDGPU_SKIP_HW_RESET = 1,
+	AMDGPU_HOST_FLR = 2,
 };
 
 struct amdgpu_reset_context {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -352,7 +352,7 @@
 	ring->max_dw = max_dw;
 	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;
 		num_sched = &adev->gpu_sched[hw_ip][hw_prio].num_scheds;
 		adev->gpu_sched[hw_ip][hw_prio].sched[(*num_sched)++] =
@@ -473,8 +473,9 @@
 					size_t size, loff_t *pos)
 {
 	struct amdgpu_ring *ring = file_inode(f)->i_private;
-	int r, i;
 	uint32_t value, result, early[3];
+	loff_t i;
+	int r;
 
 	if (*pos & 3 || size & 3)
 		return -EINVAL;
@@ -524,46 +525,58 @@
 {
 	struct amdgpu_ring *ring = file_inode(f)->i_private;
 	volatile u32 *mqd;
-	int r;
+	u32 *kbuf;
+	int r, i;
 	uint32_t value, result;
 
 	if (*pos & 3 || size & 3)
 		return -EINVAL;
 
-	result = 0;
+	kbuf = kmalloc(ring->mqd_size, GFP_KERNEL);
+	if (!kbuf)
+		return -ENOMEM;
 
 	r = amdgpu_bo_reserve(ring->mqd_obj, false);
 	if (unlikely(r != 0))
-		return r;
+		goto err_free;
 
 	r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&mqd);
-	if (r) {
-		amdgpu_bo_unreserve(ring->mqd_obj);
-		return r;
-	}
+	if (r)
+		goto err_unreserve;
+
+	/*
+	 * Copy to local buffer to avoid put_user(), which might fault
+	 * and acquire mmap_sem, under reservation_ww_class_mutex.
+	 */
+	for (i = 0; i < ring->mqd_size/sizeof(u32); i++)
+		kbuf[i] = mqd[i];
+
+	amdgpu_bo_kunmap(ring->mqd_obj);
+	amdgpu_bo_unreserve(ring->mqd_obj);
 
+	result = 0;
 	while (size) {
 		if (*pos >= ring->mqd_size)
-			goto done;
+			break;
 
-		value = mqd[*pos/4];
+		value = kbuf[*pos/4];
 		r = put_user(value, (uint32_t *)buf);
 		if (r)
-			goto done;
+			goto err_free;
 		buf += 4;
 		result += 4;
 		size -= 4;
 		*pos += 4;
 	}
 
-done:
-	amdgpu_bo_kunmap(ring->mqd_obj);
-	mqd = NULL;
-	amdgpu_bo_unreserve(ring->mqd_obj);
-	if (r)
-		return r;
-
+	kfree(kbuf);
 	return result;
+
+err_unreserve:
+	amdgpu_bo_unreserve(ring->mqd_obj);
+err_free:
+	kfree(kbuf);
+	return r;
 }
 
 static const struct file_operations amdgpu_debugfs_mqd_fops = {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_securedisplay.c
@@ -135,6 +135,10 @@
 		mutex_unlock(&psp->securedisplay_context.mutex);
 		break;
 	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);
 		psp_prep_securedisplay_cmd_buf(psp, &securedisplay_cmd,
 			TA_SECUREDISPLAY_COMMAND__SEND_ROI_CRC);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -137,7 +137,7 @@
 			amdgpu_bo_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_CPU);
 		} else if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
 			   !(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) &&
-			   amdgpu_bo_in_cpu_visible_vram(abo)) {
+			   amdgpu_res_cpu_visible(adev, bo->resource)) {
 
 			/* Try evicting to the CPU inaccessible part of VRAM
 			 * first, but only set GTT as busy placement, so this
@@ -408,40 +408,55 @@
 	return r;
 }
 
-/*
- * amdgpu_mem_visible - Check that memory can be accessed by ttm_bo_move_memcpy
+/**
+ * amdgpu_res_cpu_visible - Check that resource can be accessed by CPU
+ * @adev: amdgpu device
+ * @res: the resource to check
  *
- * Called by amdgpu_bo_move()
+ * Returns: true if the full resource is CPU visible, false otherwise.
  */
-static bool amdgpu_mem_visible(struct amdgpu_device *adev,
-			       struct ttm_resource *mem)
+bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
+			    struct ttm_resource *res)
 {
-	u64 mem_size = (u64)mem->size;
 	struct amdgpu_res_cursor cursor;
-	u64 end;
 
-	if (mem->mem_type == TTM_PL_SYSTEM ||
-	    mem->mem_type == TTM_PL_TT)
+	if (!res)
+		return false;
+
+	if (res->mem_type == TTM_PL_SYSTEM || res->mem_type == TTM_PL_TT ||
+	    res->mem_type == AMDGPU_PL_PREEMPT || res->mem_type == AMDGPU_PL_DOORBELL)
 		return true;
-	if (mem->mem_type != TTM_PL_VRAM)
+
+	if (res->mem_type != TTM_PL_VRAM)
 		return false;
 
-	amdgpu_res_first(mem, 0, mem_size, &cursor);
-	end = cursor.start + cursor.size;
+	amdgpu_res_first(res, 0, res->size, &cursor);
 	while (cursor.remaining) {
+		if ((cursor.start + cursor.size) > adev->gmc.visible_vram_size)
+			return false;
 		amdgpu_res_next(&cursor, cursor.size);
+	}
 
-		if (!cursor.remaining)
-			break;
+	return true;
+}
 
-		/* ttm_resource_ioremap only supports contiguous memory */
-		if (end != cursor.start)
-			return false;
+/*
+ * amdgpu_res_copyable - Check that memory can be accessed by ttm_bo_move_memcpy
+ *
+ * Called by amdgpu_bo_move()
+ */
+static bool amdgpu_res_copyable(struct amdgpu_device *adev,
+				struct ttm_resource *mem)
+{
+	if (!amdgpu_res_cpu_visible(adev, mem))
+		return false;
 
-		end = cursor.start + cursor.size;
-	}
+	/* ttm_resource_ioremap only supports contiguous memory */
+	if (mem->mem_type == TTM_PL_VRAM &&
+	    !(mem->placement & TTM_PL_FLAG_CONTIGUOUS))
+		return false;
 
-	return end <= adev->gmc.visible_vram_size;
+	return true;
 }
 
 /*
@@ -471,14 +486,16 @@
 
 	if (!old_mem || (old_mem->mem_type == TTM_PL_SYSTEM &&
 			 bo->ttm == NULL)) {
+		amdgpu_bo_move_notify(bo, evict, new_mem);
 		ttm_bo_move_null(bo, new_mem);
-		goto out;
+		return 0;
 	}
 	if (old_mem->mem_type == TTM_PL_SYSTEM &&
 	    (new_mem->mem_type == TTM_PL_TT ||
 	     new_mem->mem_type == AMDGPU_PL_PREEMPT)) {
+		amdgpu_bo_move_notify(bo, evict, new_mem);
 		ttm_bo_move_null(bo, new_mem);
-		goto out;
+		return 0;
 	}
 	if ((old_mem->mem_type == TTM_PL_TT ||
 	     old_mem->mem_type == AMDGPU_PL_PREEMPT) &&
@@ -488,9 +505,10 @@
 			return r;
 
 		amdgpu_ttm_backend_unbind(bo->bdev, bo->ttm);
+		amdgpu_bo_move_notify(bo, evict, new_mem);
 		ttm_resource_free(bo, &bo->resource);
 		ttm_bo_assign_mem(bo, new_mem);
-		goto out;
+		return 0;
 	}
 
 	if (old_mem->mem_type == AMDGPU_PL_GDS ||
@@ -502,8 +520,9 @@
 	    new_mem->mem_type == AMDGPU_PL_OA ||
 	    new_mem->mem_type == AMDGPU_PL_DOORBELL) {
 		/* Nothing to save here */
+		amdgpu_bo_move_notify(bo, evict, new_mem);
 		ttm_bo_move_null(bo, new_mem);
-		goto out;
+		return 0;
 	}
 
 	if (bo->type == ttm_bo_type_device &&
@@ -515,27 +534,28 @@
 		abo->flags &= ~AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
 	}
 
-	if (adev->mman.buffer_funcs_enabled) {
-		if (((old_mem->mem_type == TTM_PL_SYSTEM &&
-		      new_mem->mem_type == TTM_PL_VRAM) ||
-		     (old_mem->mem_type == TTM_PL_VRAM &&
-		      new_mem->mem_type == TTM_PL_SYSTEM))) {
-			hop->fpfn = 0;
-			hop->lpfn = 0;
-			hop->mem_type = TTM_PL_TT;
-			hop->flags = TTM_PL_FLAG_TEMPORARY;
-			return -EMULTIHOP;
-		}
+	if (adev->mman.buffer_funcs_enabled &&
+	    ((old_mem->mem_type == TTM_PL_SYSTEM &&
+	      new_mem->mem_type == TTM_PL_VRAM) ||
+	     (old_mem->mem_type == TTM_PL_VRAM &&
+	      new_mem->mem_type == TTM_PL_SYSTEM))) {
+		hop->fpfn = 0;
+		hop->lpfn = 0;
+		hop->mem_type = TTM_PL_TT;
+		hop->flags = TTM_PL_FLAG_TEMPORARY;
+		return -EMULTIHOP;
+	}
 
+	amdgpu_bo_move_notify(bo, evict, new_mem);
+	if (adev->mman.buffer_funcs_enabled)
 		r = amdgpu_move_blit(bo, evict, new_mem, old_mem);
-	} else {
+	else
 		r = -ENODEV;
-	}
 
 	if (r) {
 		/* Check that all memory is CPU accessible */
-		if (!amdgpu_mem_visible(adev, old_mem) ||
-		    !amdgpu_mem_visible(adev, new_mem)) {
+		if (!amdgpu_res_copyable(adev, old_mem) ||
+		    !amdgpu_res_copyable(adev, new_mem)) {
 			pr_err("Move buffer fallback to memcpy unavailable\n");
 			return r;
 		}
@@ -545,11 +565,10 @@
 			return r;
 	}
 
-	trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type);
-out:
-	/* update statistics */
+	/* update statistics after the move */
+	if (evict)
+		atomic64_inc(&adev->num_evictions);
 	atomic64_add(bo->base.size, &adev->num_bytes_moved);
-	amdgpu_bo_move_notify(bo, evict);
 	return 0;
 }
 
@@ -562,7 +581,6 @@
 				     struct ttm_resource *mem)
 {
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);
-	size_t bus_size = (size_t)mem->size;
 
 	switch (mem->mem_type) {
 	case TTM_PL_SYSTEM:
@@ -573,9 +591,6 @@
 		break;
 	case TTM_PL_VRAM:
 		mem->bus.offset = mem->start << PAGE_SHIFT;
-		/* check if it's visible */
-		if ((mem->bus.offset + bus_size) > adev->gmc.visible_vram_size)
-			return -EINVAL;
 
 		if (adev->mman.aper_base_kaddr &&
 		    mem->placement & TTM_PL_FLAG_CONTIGUOUS)
@@ -779,7 +794,7 @@
 	/* Map SG to device */
 	r = dma_map_sgtable(adev->dev, ttm->sg, direction, 0);
 	if (r)
-		goto release_sg;
+		goto release_sg_table;
 
 	/* convert SG to linear array of pages and dma addresses */
 	drm_prime_sg_to_dma_addr_array(ttm->sg, gtt->ttm.dma_address,
@@ -787,6 +802,8 @@
 
 	return 0;
 
+release_sg_table:
+	sg_free_table(ttm->sg);
 release_sg:
 	kfree(ttm->sg);
 	ttm->sg = NULL;
@@ -869,6 +886,7 @@
 		amdgpu_gart_bind(adev, gtt->offset, ttm->num_pages,
 				 gtt->ttm.dma_address, flags);
 	}
+	gtt->bound = true;
 }
 
 /*
@@ -1554,7 +1572,7 @@
 static void
 amdgpu_bo_delete_mem_notify(struct ttm_buffer_object *bo)
 {
-	amdgpu_bo_move_notify(bo, false);
+	amdgpu_bo_move_notify(bo, false, NULL);
 }
 
 static struct ttm_device_funcs amdgpu_bo_driver = {
@@ -1816,6 +1834,7 @@
 
 	mutex_init(&adev->mman.gtt_window_lock);
 
+	dma_set_max_seg_size(adev->dev, UINT_MAX);
 	/* No others user of address space so set it to 0 */
 	r = ttm_device_init(&adev->mman.bdev, &amdgpu_bo_driver, adev->dev,
 			       adev_to_drm(adev)->anon_inode->i_mapping,
@@ -2029,6 +2048,7 @@
 	ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_GDS);
 	ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_GWS);
 	ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_OA);
+	ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_DOORBELL);
 	ttm_device_fini(&adev->mman.bdev);
 	adev->mman.initialized = false;
 	DRM_INFO("amdgpu: ttm finalized\n");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
@@ -139,6 +139,9 @@
 int amdgpu_vram_mgr_query_page_status(struct amdgpu_vram_mgr *mgr,
 				      uint64_t start);
 
+bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
+			    struct ttm_resource *res);
+
 int amdgpu_ttm_init(struct amdgpu_device *adev);
 void amdgpu_ttm_fini(struct amdgpu_device *adev);
 void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
@@ -175,6 +175,7 @@
 	}
 
 	kfree(err_data->err_addr);
+	err_data->err_addr = NULL;
 	return AMDGPU_RAS_SUCCESS;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
@@ -766,6 +766,9 @@
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+	if (amdgpu_in_reset(adev) || adev->in_s0ix || adev->in_suspend)
+		return 0;
+
 	return umsch_mm_test(adev);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
@@ -214,15 +214,15 @@
 
 	drm_sched_entity_destroy(&adev->vce.entity);
 
-	amdgpu_bo_free_kernel(&adev->vce.vcpu_bo, &adev->vce.gpu_addr,
-		(void **)&adev->vce.cpu_addr);
-
 	for (i = 0; i < adev->vce.num_rings; i++)
 		amdgpu_ring_fini(&adev->vce.ring[i]);
 
 	amdgpu_ucode_release(&adev->vce.fw);
 	mutex_destroy(&adev->vce.idle_mutex);
 
+	amdgpu_bo_free_kernel(&adev->vce.vcpu_bo, &adev->vce.gpu_addr,
+		(void **)&adev->vce.cpu_addr);
+
 	return 0;
 }
 
@@ -743,7 +743,8 @@
 	uint32_t created = 0;
 	uint32_t allocated = 0;
 	uint32_t tmp, handle = 0;
-	uint32_t *size = &tmp;
+	uint32_t dummy = 0xffffffff;
+	uint32_t *size = &dummy;
 	unsigned int idx;
 	int i, r = 0;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
@@ -137,6 +137,10 @@
 		}
 	}
 
+	/* from vcn4 and above, only unified queue is used */
+	adev->vcn.using_unified_queue =
+		amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0);
+
 	hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
 	adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);
 
@@ -261,18 +265,6 @@
 	return 0;
 }
 
-/* from vcn4 and above, only unified queue is used */
-static bool amdgpu_vcn_using_unified_queue(struct amdgpu_ring *ring)
-{
-	struct amdgpu_device *adev = ring->adev;
-	bool ret = false;
-
-	if (amdgpu_ip_version(adev, UVD_HWIP, 0) >= IP_VERSION(4, 0, 0))
-		ret = true;
-
-	return ret;
-}
-
 bool amdgpu_vcn_is_disabled_vcn(struct amdgpu_device *adev, enum vcn_ring_type type, uint32_t vcn_instance)
 {
 	bool ret = false;
@@ -382,7 +374,9 @@
 		for (i = 0; i < adev->vcn.num_enc_rings; ++i)
 			fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]);
 
-		if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)	{
+		/* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */
+		if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
+		    !adev->vcn.using_unified_queue) {
 			struct dpg_pause_state new_state;
 
 			if (fence[j] ||
@@ -428,7 +422,9 @@
 	amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
 	       AMD_PG_STATE_UNGATE);
 
-	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)	{
+	/* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */
+	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
+	    !adev->vcn.using_unified_queue) {
 		struct dpg_pause_state new_state;
 
 		if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) {
@@ -454,8 +450,12 @@
 
 void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)
 {
+	struct amdgpu_device *adev = ring->adev;
+
+	/* Only set DPG pause for VCN3 or below, VCN4 and above will be handled by FW */
 	if (ring->adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
-		ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
+	    ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC &&
+	    !adev->vcn.using_unified_queue)
 		atomic_dec(&ring->adev->vcn.inst[ring->me].dpg_enc_submission_cnt);
 
 	atomic_dec(&ring->adev->vcn.total_submission_cnt);
@@ -709,12 +709,11 @@
 	struct amdgpu_job *job;
 	struct amdgpu_ib *ib;
 	uint64_t addr = AMDGPU_GPU_PAGE_ALIGN(ib_msg->gpu_addr);
-	bool sq = amdgpu_vcn_using_unified_queue(ring);
 	uint32_t *ib_checksum;
 	uint32_t ib_pack_in_dw;
 	int i, r;
 
-	if (sq)
+	if (adev->vcn.using_unified_queue)
 		ib_size_dw += 8;
 
 	r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
@@ -727,7 +726,7 @@
 	ib->length_dw = 0;
 
 	/* single queue headers */
-	if (sq) {
+	if (adev->vcn.using_unified_queue) {
 		ib_pack_in_dw = sizeof(struct amdgpu_vcn_decode_buffer) / sizeof(uint32_t)
 						+ 4 + 2; /* engine info + decoding ib in dw */
 		ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, ib_pack_in_dw, false);
@@ -746,7 +745,7 @@
 	for (i = ib->length_dw; i < ib_size_dw; ++i)
 		ib->ptr[i] = 0x0;
 
-	if (sq)
+	if (adev->vcn.using_unified_queue)
 		amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, ib_pack_in_dw);
 
 	r = amdgpu_job_submit_direct(job, ring, &f);
@@ -836,15 +835,15 @@
 					 struct dma_fence **fence)
 {
 	unsigned int ib_size_dw = 16;
+	struct amdgpu_device *adev = ring->adev;
 	struct amdgpu_job *job;
 	struct amdgpu_ib *ib;
 	struct dma_fence *f = NULL;
 	uint32_t *ib_checksum = NULL;
 	uint64_t addr;
-	bool sq = amdgpu_vcn_using_unified_queue(ring);
 	int i, r;
 
-	if (sq)
+	if (adev->vcn.using_unified_queue)
 		ib_size_dw += 8;
 
 	r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
@@ -858,7 +857,7 @@
 
 	ib->length_dw = 0;
 
-	if (sq)
+	if (adev->vcn.using_unified_queue)
 		ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, 0x11, true);
 
 	ib->ptr[ib->length_dw++] = 0x00000018;
@@ -880,7 +879,7 @@
 	for (i = ib->length_dw; i < ib_size_dw; ++i)
 		ib->ptr[i] = 0x0;
 
-	if (sq)
+	if (adev->vcn.using_unified_queue)
 		amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, 0x11);
 
 	r = amdgpu_job_submit_direct(job, ring, &f);
@@ -903,15 +902,15 @@
 					  struct dma_fence **fence)
 {
 	unsigned int ib_size_dw = 16;
+	struct amdgpu_device *adev = ring->adev;
 	struct amdgpu_job *job;
 	struct amdgpu_ib *ib;
 	struct dma_fence *f = NULL;
 	uint32_t *ib_checksum = NULL;
 	uint64_t addr;
-	bool sq = amdgpu_vcn_using_unified_queue(ring);
 	int i, r;
 
-	if (sq)
+	if (adev->vcn.using_unified_queue)
 		ib_size_dw += 8;
 
 	r = amdgpu_job_alloc_with_ib(ring->adev, NULL, NULL,
@@ -925,7 +924,7 @@
 
 	ib->length_dw = 0;
 
-	if (sq)
+	if (adev->vcn.using_unified_queue)
 		ib_checksum = amdgpu_vcn_unified_ring_ib_header(ib, 0x11, true);
 
 	ib->ptr[ib->length_dw++] = 0x00000018;
@@ -947,7 +946,7 @@
 	for (i = ib->length_dw; i < ib_size_dw; ++i)
 		ib->ptr[i] = 0x0;
 
-	if (sq)
+	if (adev->vcn.using_unified_queue)
 		amdgpu_vcn_unified_ring_ib_checksum(&ib_checksum, 0x11);
 
 	r = amdgpu_job_submit_direct(job, ring, &f);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
@@ -287,6 +287,7 @@
 
 	uint16_t inst_mask;
 	uint8_t	num_inst_per_aid;
+	bool using_unified_queue;
 };
 
 struct amdgpu_fw_shared_rb_ptrs_struct {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -138,8 +138,10 @@
 
 	if (virt->ops && virt->ops->req_full_gpu) {
 		r = virt->ops->req_full_gpu(adev, init);
-		if (r)
+		if (r) {
+			adev->no_hw_access = true;
 			return r;
+		}
 
 		adev->virt.caps &= ~AMDGPU_SRIOV_CAPS_RUNTIME;
 	}
@@ -437,6 +439,8 @@
 	else
 		vram_usage_va = adev->mman.drv_vram_usage_va;
 
+	memset(&bp, 0, sizeof(bp));
+
 	if (bp_block_size) {
 		bp_cnt = bp_block_size / sizeof(uint64_t);
 		for (bp_idx = 0; bp_idx < bp_cnt; bp_idx++) {
@@ -616,7 +620,7 @@
 	vf2pf_info->dummy_page_addr = (uint64_t)adev->dummy_page_addr;
 	vf2pf_info->checksum =
 		amd_sriov_msg_checksum(
-		vf2pf_info, vf2pf_info->header.size, 0, 0);
+		vf2pf_info, sizeof(*vf2pf_info), 0, 0);
 
 	return 0;
 }
@@ -999,11 +1003,17 @@
 		return 0;
 	}
 
+	if (amdgpu_device_skip_hw_access(adev))
+		return 0;
+
 	reg_access_ctrl = &adev->gfx.rlc.reg_access_ctrl[xcc_id];
 	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_reg2 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg2;
 	scratch_reg3 = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->scratch_reg3;
+
+	mutex_lock(&adev->virt.rlcg_reg_lock);
+
 	if (reg_access_ctrl->spare_int)
 		spare_int = (void __iomem *)adev->rmmio + 4 * reg_access_ctrl->spare_int;
 
@@ -1059,6 +1069,9 @@
 	}
 
 	ret = readl(scratch_reg0);
+
+	mutex_unlock(&adev->virt.rlcg_reg_lock);
+
 	return ret;
 }
 
@@ -1068,6 +1081,9 @@
 {
 	u32 rlcg_flag;
 
+	if (amdgpu_device_skip_hw_access(adev))
+		return;
+
 	if (!amdgpu_sriov_runtime(adev) &&
 		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);
@@ -1085,6 +1101,9 @@
 {
 	u32 rlcg_flag;
 
+	if (amdgpu_device_skip_hw_access(adev))
+		return 0;
+
 	if (!amdgpu_sriov_runtime(adev) &&
 		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);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
@@ -265,6 +265,8 @@
 
 	/* the ucode id to signal the autoload */
 	uint32_t autoload_ucode_id;
+
+	struct mutex rlcg_reg_lock;
 };
 
 struct amdgpu_video_codec_info;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c
@@ -3,6 +3,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_edid.h>
 #include <drm/drm_simple_kms_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_vblank.h>
 
 #include "amdgpu.h"
@@ -314,7 +315,13 @@
 		return 0;
 	}
 	afb = to_amdgpu_framebuffer(new_state->fb);
-	obj = new_state->fb->obj[0];
+
+	obj = drm_gem_fb_get_obj(new_state->fb, 0);
+	if (!obj) {
+		DRM_ERROR("Failed to get obj from framebuffer\n");
+		return -EINVAL;
+	}
+
 	rbo = gem_to_amdgpu_bo(obj);
 	adev = amdgpu_ttm_adev(rbo->tbo.bdev);
 
@@ -368,12 +375,19 @@
 				   struct drm_plane_state *old_state)
 {
 	struct amdgpu_bo *rbo;
+	struct drm_gem_object *obj;
 	int r;
 
 	if (!old_state->fb)
 		return;
 
-	rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]);
+	obj = drm_gem_fb_get_obj(old_state->fb, 0);
+	if (!obj) {
+		DRM_ERROR("Failed to get obj from framebuffer\n");
+		return;
+	}
+
+	rbo = gem_to_amdgpu_bo(obj);
 	r = amdgpu_bo_reserve(rbo, false);
 	if (unlikely(r)) {
 		DRM_ERROR("failed to reserve rbo before unpin\n");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -418,7 +418,7 @@
 	if (!vm)
 		return result;
 
-	result += vm->generation;
+	result += lower_32_bits(vm->generation);
 	/* Add one if the page tables will be re-generated on next CS */
 	if (drm_sched_entity_error(&vm->delayed))
 		++result;
@@ -443,13 +443,14 @@
 			      int (*validate)(void *p, struct amdgpu_bo *bo),
 			      void *param)
 {
+	uint64_t new_vm_generation = amdgpu_vm_generation(adev, vm);
 	struct amdgpu_vm_bo_base *bo_base;
 	struct amdgpu_bo *shadow;
 	struct amdgpu_bo *bo;
 	int r;
 
-	if (drm_sched_entity_error(&vm->delayed)) {
-		++vm->generation;
+	if (vm->generation != new_vm_generation) {
+		vm->generation = new_vm_generation;
 		amdgpu_vm_bo_reset_state_machine(vm);
 		amdgpu_vm_fini_entities(vm);
 		r = amdgpu_vm_init_entities(adev, vm);
@@ -1165,10 +1166,9 @@
 	 * next command submission.
 	 */
 	if (bo && bo->tbo.base.resv == vm->root.bo->tbo.base.resv) {
-		uint32_t mem_type = bo->tbo.resource->mem_type;
-
-		if (!(bo->preferred_domains &
-		      amdgpu_mem_type_to_domain(mem_type)))
+		if (bo->tbo.resource &&
+		    !(bo->preferred_domains &
+		      amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type)))
 			amdgpu_vm_bo_evicted(&bo_va->base);
 		else
 			amdgpu_vm_bo_idle(&bo_va->base);
@@ -1559,6 +1559,37 @@
 	trace_amdgpu_vm_bo_map(bo_va, mapping);
 }
 
+/* Validate operation parameters to prevent potential abuse */
+static int amdgpu_vm_verify_parameters(struct amdgpu_device *adev,
+					  struct amdgpu_bo *bo,
+					  uint64_t saddr,
+					  uint64_t offset,
+					  uint64_t size)
+{
+	uint64_t tmp, lpfn;
+
+	if (saddr & AMDGPU_GPU_PAGE_MASK
+	    || offset & AMDGPU_GPU_PAGE_MASK
+	    || size & AMDGPU_GPU_PAGE_MASK)
+		return -EINVAL;
+
+	if (check_add_overflow(saddr, size, &tmp)
+	    || check_add_overflow(offset, size, &tmp)
+	    || size == 0 /* which also leads to end < begin */)
+		return -EINVAL;
+
+	/* make sure object fit at this offset */
+	if (bo && offset + size > amdgpu_bo_size(bo))
+		return -EINVAL;
+
+	/* Ensure last pfn not exceed max_pfn */
+	lpfn = (saddr + size - 1) >> AMDGPU_GPU_PAGE_SHIFT;
+	if (lpfn >= adev->vm_manager.max_pfn)
+		return -EINVAL;
+
+	return 0;
+}
+
 /**
  * amdgpu_vm_bo_map - map bo inside a vm
  *
@@ -1585,21 +1616,14 @@
 	struct amdgpu_bo *bo = bo_va->base.bo;
 	struct amdgpu_vm *vm = bo_va->base.vm;
 	uint64_t eaddr;
+	int r;
 
-	/* validate the parameters */
-	if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK)
-		return -EINVAL;
-	if (saddr + size <= saddr || offset + size <= offset)
-		return -EINVAL;
-
-	/* make sure object fit at this offset */
-	eaddr = saddr + size - 1;
-	if ((bo && offset + size > amdgpu_bo_size(bo)) ||
-	    (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT))
-		return -EINVAL;
+	r = amdgpu_vm_verify_parameters(adev, bo, saddr, offset, size);
+	if (r)
+		return r;
 
 	saddr /= AMDGPU_GPU_PAGE_SIZE;
-	eaddr /= AMDGPU_GPU_PAGE_SIZE;
+	eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE;
 
 	tmp = amdgpu_vm_it_iter_first(&vm->va, saddr, eaddr);
 	if (tmp) {
@@ -1652,17 +1676,9 @@
 	uint64_t eaddr;
 	int r;
 
-	/* validate the parameters */
-	if (saddr & ~PAGE_MASK || offset & ~PAGE_MASK || size & ~PAGE_MASK)
-		return -EINVAL;
-	if (saddr + size <= saddr || offset + size <= offset)
-		return -EINVAL;
-
-	/* make sure object fit at this offset */
-	eaddr = saddr + size - 1;
-	if ((bo && offset + size > amdgpu_bo_size(bo)) ||
-	    (eaddr >= adev->vm_manager.max_pfn << AMDGPU_GPU_PAGE_SHIFT))
-		return -EINVAL;
+	r = amdgpu_vm_verify_parameters(adev, bo, saddr, offset, size);
+	if (r)
+		return r;
 
 	/* Allocate all the needed memory */
 	mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
@@ -1676,7 +1692,7 @@
 	}
 
 	saddr /= AMDGPU_GPU_PAGE_SIZE;
-	eaddr /= AMDGPU_GPU_PAGE_SIZE;
+	eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE;
 
 	mapping->start = saddr;
 	mapping->last = eaddr;
@@ -1763,10 +1779,14 @@
 	struct amdgpu_bo_va_mapping *before, *after, *tmp, *next;
 	LIST_HEAD(removed);
 	uint64_t eaddr;
+	int r;
+
+	r = amdgpu_vm_verify_parameters(adev, NULL, saddr, 0, size);
+	if (r)
+		return r;
 
-	eaddr = saddr + size - 1;
 	saddr /= AMDGPU_GPU_PAGE_SIZE;
-	eaddr /= AMDGPU_GPU_PAGE_SIZE;
+	eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE;
 
 	/* Allocate all the needed memory */
 	before = kzalloc(sizeof(*before), GFP_KERNEL);
@@ -2231,7 +2251,7 @@
 	vm->last_update = dma_fence_get_stub();
 	vm->last_unlocked = dma_fence_get_stub();
 	vm->last_tlb_flush = dma_fence_get_stub();
-	vm->generation = 0;
+	vm->generation = amdgpu_vm_generation(adev, NULL);
 
 	mutex_init(&vm->eviction_lock);
 	vm->evicting = false;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_pt.c
@@ -766,11 +766,15 @@
 			 struct amdgpu_vm_bo_base *entry)
 {
 	struct amdgpu_vm_bo_base *parent = amdgpu_vm_pt_parent(entry);
-	struct amdgpu_bo *bo = parent->bo, *pbo;
+	struct amdgpu_bo *bo, *pbo;
 	struct amdgpu_vm *vm = params->vm;
 	uint64_t pde, pt, flags;
 	unsigned int level;
 
+	if (WARN_ON(!parent))
+		return -EINVAL;
+
+	bo = parent->bo;
 	for (level = 0, pbo = bo->parent; pbo; ++level)
 		pbo = pbo->parent;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
@@ -102,6 +102,11 @@
 	if (!r)
 		r = amdgpu_sync_push_to_job(&sync, p->job);
 	amdgpu_sync_free(&sync);
+
+	if (r) {
+		p->num_dw_left = 0;
+		amdgpu_job_free(p->job);
+	}
 	return r;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c
@@ -390,6 +390,12 @@
 	struct amdgpu_vpe *vpe = &adev->vpe;
 	int ret;
 
+	/* Power on VPE */
+	ret = amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VPE,
+						     AMD_PG_STATE_UNGATE);
+	if (ret)
+		return ret;
+
 	ret = vpe_load_microcode(vpe);
 	if (ret)
 		return ret;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c
@@ -31,6 +31,8 @@
 #include "amdgpu_atomfirmware.h"
 #include "atom.h"
 
+#define AMDGPU_MAX_SG_SEGMENT_SIZE	(2UL << 30)
+
 struct amdgpu_vram_reservation {
 	u64 start;
 	u64 size;
@@ -516,9 +518,7 @@
 
 		BUG_ON(min_block_size < mm->chunk_size);
 
-		/* Limit maximum size to 2GiB due to SG table limitations */
-		size = min(remaining_size, 2ULL << 30);
-
+		size = remaining_size;
 		if ((size >= (u64)pages_per_block << PAGE_SHIFT) &&
 				!(size & (((u64)pages_per_block << PAGE_SHIFT) - 1)))
 			min_block_size = (u64)pages_per_block << PAGE_SHIFT;
@@ -646,7 +646,7 @@
 	amdgpu_res_first(res, offset, length, &cursor);
 	while (cursor.remaining) {
 		num_entries++;
-		amdgpu_res_next(&cursor, cursor.size);
+		amdgpu_res_next(&cursor, min(cursor.size, AMDGPU_MAX_SG_SEGMENT_SIZE));
 	}
 
 	r = sg_alloc_table(*sgt, num_entries, GFP_KERNEL);
@@ -666,7 +666,7 @@
 	amdgpu_res_first(res, offset, length, &cursor);
 	for_each_sgtable_sg((*sgt), sg, i) {
 		phys_addr_t phys = cursor.start + adev->gmc.aper_base;
-		size_t size = cursor.size;
+		unsigned long size = min(cursor.size, AMDGPU_MAX_SG_SEGMENT_SIZE);
 		dma_addr_t addr;
 
 		addr = dma_map_resource(dev, phys, size, dir,
@@ -679,7 +679,7 @@
 		sg_dma_address(sg) = addr;
 		sg_dma_len(sg) = size;
 
-		amdgpu_res_next(&cursor, cursor.size);
+		amdgpu_res_next(&cursor, size);
 	}
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.h
@@ -180,6 +180,6 @@
 
 #define for_each_xcp(xcp_mgr, xcp, i)                            \
 	for (i = 0, xcp = amdgpu_get_next_xcp(xcp_mgr, &i); xcp; \
-	     xcp = amdgpu_get_next_xcp(xcp_mgr, &i))
+	     ++i, xcp = amdgpu_get_next_xcp(xcp_mgr, &i))
 
 #endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c
@@ -434,6 +434,9 @@
 		}
 	}
 
+	if (i == top->num_nodes)
+		return -EINVAL;
+
 	for (i = 0; i < top->num_nodes; i++) {
 		for (j = 0; j < top->nodes[i].num_links; j++)
 			/* node id in sysfs starts from 1 rather than 0 so +1 here */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/amdgv_sriovmsg.h
@@ -210,7 +210,7 @@
 	uint32_t pcie_atomic_ops_support_flags;
 	/* reserved */
 	uint32_t reserved[256 - AMD_SRIOV_MSG_PF2VF_INFO_FILLED_SIZE];
-};
+} __packed;
 
 struct amd_sriov_msg_vf2pf_info_header {
 	/* the total structure size in byte */
@@ -268,7 +268,7 @@
 
 	/* reserved */
 	uint32_t reserved[256 - AMD_SRIOV_MSG_VF2PF_INFO_FILLED_SIZE];
-};
+} __packed;
 
 /* mailbox message send from guest to host  */
 enum amd_sriov_mailbox_request_message {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c
@@ -62,6 +62,11 @@
 	adev->doorbell_index.max_assignment = AMDGPU_DOORBELL_LAYOUT1_MAX_ASSIGNMENT << 1;
 }
 
+static bool aqua_vanjaram_xcp_vcn_shared(struct amdgpu_device *adev)
+{
+	return (adev->xcp_mgr->num_xcps > adev->vcn.num_vcn_inst);
+}
+
 static void aqua_vanjaram_set_xcp_id(struct amdgpu_device *adev,
 			     uint32_t inst_idx, struct amdgpu_ring *ring)
 {
@@ -87,7 +92,7 @@
 	case AMDGPU_RING_TYPE_VCN_ENC:
 	case AMDGPU_RING_TYPE_VCN_JPEG:
 		ip_blk = AMDGPU_XCP_VCN;
-		if (adev->xcp_mgr->mode == AMDGPU_CPX_PARTITION_MODE)
+		if (aqua_vanjaram_xcp_vcn_shared(adev))
 			inst_mask = 1 << (inst_idx * 2);
 		break;
 	default:
@@ -140,10 +145,12 @@
 
 		aqua_vanjaram_xcp_gpu_sched_update(adev, ring, ring->xcp_id);
 
-		/* VCN is shared by two partitions under CPX MODE */
+		/* VCN may be shared by two partitions under CPX MODE in certain
+		 * configs.
+		 */
 		if ((ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC ||
-			ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG) &&
-			adev->xcp_mgr->mode == AMDGPU_CPX_PARTITION_MODE)
+		     ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG) &&
+		    aqua_vanjaram_xcp_vcn_shared(adev))
 			aqua_vanjaram_xcp_gpu_sched_update(adev, ring, ring->xcp_id + 1);
 	}
 
@@ -434,7 +441,7 @@
 	case AMDGPU_SPX_PARTITION_MODE:
 		return adev->gmc.num_mem_partitions == 1 && num_xcc > 0;
 	case AMDGPU_DPX_PARTITION_MODE:
-		return adev->gmc.num_mem_partitions != 8 && (num_xcc % 4) == 0;
+		return adev->gmc.num_mem_partitions <= 2 && (num_xcc % 4) == 0;
 	case AMDGPU_TPX_PARTITION_MODE:
 		return (adev->gmc.num_mem_partitions == 1 ||
 			adev->gmc.num_mem_partitions == 3) &&
@@ -494,6 +501,12 @@
 
 	if (mode == AMDGPU_AUTO_COMPUTE_PARTITION_MODE) {
 		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)) {
 		dev_err(adev->dev,
 			"Invalid compute partition mode requested, requested: %s, available memory partitions: %d",
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/atom.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/atom.c
@@ -62,6 +62,7 @@
 typedef struct {
 	struct atom_context *ctx;
 	uint32_t *ps, *ws;
+	int ps_size, ws_size;
 	int ps_shift;
 	uint16_t start;
 	unsigned last_jump;
@@ -70,8 +71,8 @@
 } atom_exec_context;
 
 int amdgpu_atom_debug;
-static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t *params);
-int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t *params);
+static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t *params, int params_size);
+int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t *params, int params_size);
 
 static uint32_t atom_arg_mask[8] =
 	{ 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000,
@@ -223,7 +224,10 @@
 		(*ptr)++;
 		/* get_unaligned_le32 avoids unaligned accesses from atombios
 		 * tables, noticed on a DEC Alpha. */
-		val = get_unaligned_le32((u32 *)&ctx->ps[idx]);
+		if (idx < ctx->ps_size)
+			val = get_unaligned_le32((u32 *)&ctx->ps[idx]);
+		else
+			pr_info("PS index out of range: %i > %i\n", idx, ctx->ps_size);
 		if (print)
 			DEBUG("PS[0x%02X,0x%04X]", idx, val);
 		break;
@@ -261,7 +265,10 @@
 			val = gctx->reg_block;
 			break;
 		default:
-			val = ctx->ws[idx];
+			if (idx < ctx->ws_size)
+				val = ctx->ws[idx];
+			else
+				pr_info("WS index out of range: %i > %i\n", idx, ctx->ws_size);
 		}
 		break;
 	case ATOM_ARG_ID:
@@ -313,7 +320,7 @@
 				DEBUG("IMM 0x%02X\n", val);
 			return val;
 		}
-		return 0;
+		break;
 	case ATOM_ARG_PLL:
 		idx = U8(*ptr);
 		(*ptr)++;
@@ -495,6 +502,10 @@
 		idx = U8(*ptr);
 		(*ptr)++;
 		DEBUG("PS[0x%02X]", idx);
+		if (idx >= ctx->ps_size) {
+			pr_info("PS index out of range: %i > %i\n", idx, ctx->ps_size);
+			return;
+		}
 		ctx->ps[idx] = cpu_to_le32(val);
 		break;
 	case ATOM_ARG_WS:
@@ -527,6 +538,10 @@
 			gctx->reg_block = val;
 			break;
 		default:
+			if (idx >= ctx->ws_size) {
+				pr_info("WS index out of range: %i > %i\n", idx, ctx->ws_size);
+				return;
+			}
 			ctx->ws[idx] = val;
 		}
 		break;
@@ -624,7 +639,7 @@
 	else
 		SDEBUG("   table: %d\n", idx);
 	if (U16(ctx->ctx->cmd_table + 4 + 2 * idx))
-		r = amdgpu_atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
+		r = amdgpu_atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift, ctx->ps_size - ctx->ps_shift);
 	if (r) {
 		ctx->abort = true;
 	}
@@ -1203,7 +1218,7 @@
 	atom_op_div32, ATOM_ARG_WS},
 };
 
-static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t *params)
+static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t *params, int params_size)
 {
 	int base = CU16(ctx->cmd_table + 4 + 2 * index);
 	int len, ws, ps, ptr;
@@ -1225,12 +1240,16 @@
 	ectx.ps_shift = ps / 4;
 	ectx.start = base;
 	ectx.ps = params;
+	ectx.ps_size = params_size;
 	ectx.abort = false;
 	ectx.last_jump = 0;
-	if (ws)
+	if (ws) {
 		ectx.ws = kcalloc(4, ws, GFP_KERNEL);
-	else
+		ectx.ws_size = ws;
+	} else {
 		ectx.ws = NULL;
+		ectx.ws_size = 0;
+	}
 
 	debug_depth++;
 	while (1) {
@@ -1264,7 +1283,7 @@
 	return ret;
 }
 
-int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t *params)
+int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t *params, int params_size)
 {
 	int r;
 
@@ -1280,7 +1299,7 @@
 	/* reset divmul */
 	ctx->divmul[0] = 0;
 	ctx->divmul[1] = 0;
-	r = amdgpu_atom_execute_table_locked(ctx, index, params);
+	r = amdgpu_atom_execute_table_locked(ctx, index, params, params_size);
 	mutex_unlock(&ctx->mutex);
 	return r;
 }
@@ -1552,7 +1571,7 @@
 
 	if (!CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_INIT))
 		return 1;
-	ret = amdgpu_atom_execute_table(ctx, ATOM_CMD_INIT, ps);
+	ret = amdgpu_atom_execute_table(ctx, ATOM_CMD_INIT, ps, 16);
 	if (ret)
 		return ret;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/atom.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/atom.h
@@ -156,7 +156,7 @@
 extern int amdgpu_atom_debug;
 
 struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios);
-int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t *params);
+int amdgpu_atom_execute_table(struct atom_context *ctx, int index, uint32_t *params, int params_size);
 int amdgpu_atom_asic_init(struct atom_context *ctx);
 void amdgpu_atom_destroy(struct atom_context *ctx);
 bool amdgpu_atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/atombios_crtc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/atombios_crtc.c
@@ -77,7 +77,7 @@
 		args.usOverscanTop = cpu_to_le16(amdgpu_crtc->v_border);
 		break;
 	}
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 void amdgpu_atombios_crtc_scaler_setup(struct drm_crtc *crtc)
@@ -106,7 +106,7 @@
 		args.ucEnable = ATOM_SCALER_DISABLE;
 		break;
 	}
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 void amdgpu_atombios_crtc_lock(struct drm_crtc *crtc, int lock)
@@ -123,7 +123,7 @@
 	args.ucCRTC = amdgpu_crtc->crtc_id;
 	args.ucEnable = lock;
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 void amdgpu_atombios_crtc_enable(struct drm_crtc *crtc, int state)
@@ -139,7 +139,7 @@
 	args.ucCRTC = amdgpu_crtc->crtc_id;
 	args.ucEnable = state;
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 void amdgpu_atombios_crtc_blank(struct drm_crtc *crtc, int state)
@@ -155,7 +155,7 @@
 	args.ucCRTC = amdgpu_crtc->crtc_id;
 	args.ucBlanking = state;
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 void amdgpu_atombios_crtc_powergate(struct drm_crtc *crtc, int state)
@@ -171,7 +171,7 @@
 	args.ucDispPipeId = amdgpu_crtc->crtc_id;
 	args.ucEnable = state;
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 void amdgpu_atombios_crtc_powergate_init(struct amdgpu_device *adev)
@@ -183,7 +183,7 @@
 
 	args.ucEnable = ATOM_INIT;
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 void amdgpu_atombios_crtc_set_dtd_timing(struct drm_crtc *crtc,
@@ -228,7 +228,7 @@
 	args.susModeMiscInfo.usAccess = cpu_to_le16(misc);
 	args.ucCRTC = amdgpu_crtc->crtc_id;
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 union atom_enable_ss {
@@ -293,7 +293,7 @@
 	args.v3.usSpreadSpectrumStep = cpu_to_le16(ss->step);
 	args.v3.ucEnable = enable;
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 union adjust_pixel_clock {
@@ -395,7 +395,7 @@
 					ADJUST_DISPLAY_CONFIG_SS_ENABLE;
 
 			amdgpu_atom_execute_table(adev->mode_info.atom_context,
-					   index, (uint32_t *)&args);
+					   index, (uint32_t *)&args, sizeof(args));
 			adjusted_clock = le16_to_cpu(args.v1.usPixelClock) * 10;
 			break;
 		case 3:
@@ -428,7 +428,7 @@
 				args.v3.sInput.ucExtTransmitterID = 0;
 
 			amdgpu_atom_execute_table(adev->mode_info.atom_context,
-					   index, (uint32_t *)&args);
+					   index, (uint32_t *)&args, sizeof(args));
 			adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
 			if (args.v3.sOutput.ucRefDiv) {
 				amdgpu_crtc->pll_flags |= AMDGPU_PLL_USE_FRAC_FB_DIV;
@@ -514,7 +514,7 @@
 		DRM_ERROR("Unknown table version %d %d\n", frev, crev);
 		return;
 	}
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 union set_dce_clock {
@@ -544,7 +544,7 @@
 			args.v2_1.asParam.ulDCEClkFreq = cpu_to_le32(freq); /* 10kHz units */
 			args.v2_1.asParam.ucDCEClkType = clk_type;
 			args.v2_1.asParam.ucDCEClkSrc = clk_src;
-			amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+			amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 			ret_freq = le32_to_cpu(args.v2_1.asParam.ulDCEClkFreq) * 10;
 			break;
 		default:
@@ -740,7 +740,7 @@
 		return;
 	}
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 int amdgpu_atombios_crtc_prepare_pll(struct drm_crtc *crtc,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/atombios_dp.c
@@ -83,7 +83,7 @@
 	args.v2.ucDelay = delay / 10;
 	args.v2.ucHPD_ID = chan->rec.hpd;
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 
 	*ack = args.v2.ucReplyStatus;
 
@@ -301,7 +301,7 @@
 	args.ucLaneNum = lane_num;
 	args.ucStatus = 0;
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 	return args.ucStatus;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
@@ -335,7 +335,7 @@
 	args.ucDacStandard = ATOM_DAC1_PS2;
 	args.usPixelClock = cpu_to_le16(amdgpu_encoder->pixel_clock / 10);
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 
 }
 
@@ -432,7 +432,7 @@
 		break;
 	}
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 int amdgpu_atombios_encoder_get_encoder_mode(struct drm_encoder *encoder)
@@ -732,7 +732,7 @@
 		break;
 	}
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 
 }
 
@@ -1136,7 +1136,7 @@
 		break;
 	}
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 bool
@@ -1164,7 +1164,7 @@
 
 	args.v1.ucAction = action;
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 
 	/* wait for the panel to power up */
 	if (action == ATOM_TRANSMITTER_ACTION_POWER_ON) {
@@ -1288,7 +1288,7 @@
 		DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
 		return;
 	}
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 static void
@@ -1633,7 +1633,7 @@
 		return;
 	}
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
 
 /* This only needs to be called once at startup */
@@ -1706,7 +1706,7 @@
 				args.sDacload.ucMisc = DAC_LOAD_MISC_YPrPb;
 		}
 
-		amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+		amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 
 		return true;
 	} else
@@ -2065,26 +2065,29 @@
 					fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
 					if (fake_edid_record->ucFakeEDIDLength) {
 						struct edid *edid;
-						int edid_size =
-							max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
-						edid = kmalloc(edid_size, GFP_KERNEL);
-						if (edid) {
-							memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
-							       fake_edid_record->ucFakeEDIDLength);
+						int edid_size;
 
+						if (fake_edid_record->ucFakeEDIDLength == 128)
+							edid_size = fake_edid_record->ucFakeEDIDLength;
+						else
+							edid_size = fake_edid_record->ucFakeEDIDLength * 128;
+						edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0],
+							       edid_size, GFP_KERNEL);
+						if (edid) {
 							if (drm_edid_is_valid(edid)) {
 								adev->mode_info.bios_hardcoded_edid = edid;
 								adev->mode_info.bios_hardcoded_edid_size = edid_size;
-							} else
+							} else {
 								kfree(edid);
+							}
 						}
+						record += struct_size(fake_edid_record,
+								      ucFakeEDIDString,
+								      edid_size);
+					} else {
+						/* empty fake edid record must be 3 bytes long */
+						record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
 					}
-					record += fake_edid_record->ucFakeEDIDLength ?
-						  struct_size(fake_edid_record,
-							      ucFakeEDIDString,
-							      fake_edid_record->ucFakeEDIDLength) :
-						  /* empty fake edid record must be 3 bytes long */
-						  sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
 					break;
 				case LCD_PANEL_RESOLUTION_RECORD_TYPE:
 					panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/atombios_i2c.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/atombios_i2c.c
@@ -86,7 +86,7 @@
 	args.ucSlaveAddr = slave_addr << 1;
 	args.ucLineNumber = chan->rec.i2c_id;
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 
 	/* error */
 	if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) {
@@ -172,5 +172,5 @@
 	args.ucSlaveAddr = slave_addr;
 	args.ucLineNumber = line_number;
 
-	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args);
+	amdgpu_atom_execute_table(adev->mode_info.atom_context, index, (uint32_t *)&args, sizeof(args));
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/df_v1_7.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/df_v1_7.c
@@ -70,6 +70,8 @@
 	int fb_channel_number;
 
 	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];
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
@@ -8792,7 +8792,9 @@
 	value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01);
 	value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1);
 	value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid);
+	amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
 	WREG32_SOC15(GC, 0, mmSQ_CMD, value);
+	amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
 }
 
 static void
@@ -9194,7 +9196,7 @@
 		7 + /* PIPELINE_SYNC */
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 5 +
 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 +
-		2 + /* VM_FLUSH */
+		4 + /* VM_FLUSH */
 		8 + /* FENCE for VM_FLUSH */
 		20 + /* GDS switch */
 		4 + /* double SWITCH_BUFFER,
@@ -9285,7 +9287,6 @@
 		7 + /* gfx_v10_0_ring_emit_pipeline_sync */
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 5 +
 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 +
-		2 + /* gfx_v10_0_ring_emit_vm_flush */
 		8 + 8 + 8, /* gfx_v10_0_ring_emit_fence_kiq x3 for user fence, vm fence */
 	.emit_ib_size =	7, /* gfx_v10_0_ring_emit_ib_compute */
 	.emit_ib = gfx_v10_0_ring_emit_ib_compute,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -1630,7 +1630,7 @@
 			active_rb_bitmap |= (0x3 << (i * rb_bitmap_width_per_sa));
 	}
 
-	active_rb_bitmap |= global_active_rb_bitmap;
+	active_rb_bitmap &= global_active_rb_bitmap;
 	adev->gfx.config.backend_enable_mask = active_rb_bitmap;
 	adev->gfx.config.num_rbs = hweight32(active_rb_bitmap);
 }
@@ -4287,11 +4287,11 @@
 			/* RLC autoload sequence 1: Program rlc ram */
 			if (adev->gfx.imu.funcs->program_rlc_ram)
 				adev->gfx.imu.funcs->program_rlc_ram(adev);
+			/* rlc autoload firmware */
+			r = gfx_v11_0_rlc_backdoor_autoload_enable(adev);
+			if (r)
+				return r;
 		}
-		/* rlc autoload firmware */
-		r = gfx_v11_0_rlc_backdoor_autoload_enable(adev);
-		if (r)
-			return r;
 	} else {
 		if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
 			if (adev->gfx.imu.funcs && (amdgpu_dpm > 0)) {
@@ -4491,6 +4491,8 @@
 	int r, i, j, k;
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+	gfx_v11_0_set_safe_mode(adev, 0);
+
 	tmp = RREG32_SOC15(GC, 0, regCP_INT_CNTL);
 	tmp = REG_SET_FIELD(tmp, CP_INT_CNTL, CMP_BUSY_INT_ENABLE, 0);
 	tmp = REG_SET_FIELD(tmp, CP_INT_CNTL, CNTX_BUSY_INT_ENABLE, 0);
@@ -4498,8 +4500,6 @@
 	tmp = REG_SET_FIELD(tmp, CP_INT_CNTL, GFX_IDLE_INT_ENABLE, 0);
 	WREG32_SOC15(GC, 0, regCP_INT_CNTL, tmp);
 
-	gfx_v11_0_set_safe_mode(adev, 0);
-
 	for (i = 0; i < adev->gfx.mec.num_mec; ++i) {
 		for (j = 0; j < adev->gfx.mec.num_queue_per_pipe; j++) {
 			for (k = 0; k < adev->gfx.mec.num_pipe_per_mec; k++) {
@@ -5716,7 +5716,9 @@
 	value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01);
 	value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1);
 	value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid);
+	amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
 	WREG32_SOC15(GC, 0, regSQ_CMD, value);
+	amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
 }
 
 static void
@@ -6110,7 +6112,7 @@
 		7 + /* PIPELINE_SYNC */
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 5 +
 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 +
-		2 + /* VM_FLUSH */
+		4 + /* VM_FLUSH */
 		8 + /* FENCE for VM_FLUSH */
 		20 + /* GDS switch */
 		5 + /* COND_EXEC */
@@ -6195,7 +6197,6 @@
 		7 + /* gfx_v11_0_ring_emit_pipeline_sync */
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 5 +
 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 +
-		2 + /* gfx_v11_0_ring_emit_vm_flush */
 		8 + 8 + 8, /* gfx_v11_0_ring_emit_fence_kiq x3 for user fence, vm fence */
 	.emit_ib_size =	7, /* gfx_v11_0_ring_emit_ib_compute */
 	.emit_ib = gfx_v11_0_ring_emit_ib_compute,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
@@ -1172,6 +1172,10 @@
 	{ 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc6 },
 	/* Apple MacBook Pro (15-inch, 2019) Radeon Pro Vega 20 4 GB */
 	{ 0x1002, 0x69af, 0x106b, 0x019a, 0xc0 },
+	/* https://bbs.openkylin.top/t/topic/171497 */
+	{ 0x1002, 0x15d8, 0x19e5, 0x3e14, 0xc2 },
+	/* HP 705G4 DM with R5 2400G */
+	{ 0x1002, 0x15dd, 0x103c, 0x8464, 0xd6 },
 	{ 0, 0, 0, 0, 0 },
 };
 
@@ -2474,7 +2478,7 @@
 	tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CNTX_BUSY_INT_ENABLE, enable ? 1 : 0);
 	tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CNTX_EMPTY_INT_ENABLE, enable ? 1 : 0);
 	tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, CMP_BUSY_INT_ENABLE, enable ? 1 : 0);
-	if(adev->gfx.num_gfx_rings)
+	if (adev->gfx.num_gfx_rings)
 		tmp = REG_SET_FIELD(tmp, CP_INT_CNTL_RING0, GFX_IDLE_INT_ENABLE, enable ? 1 : 0);
 
 	WREG32_SOC15(GC, 0, mmCP_INT_CNTL_RING0, tmp);
@@ -5708,7 +5712,9 @@
 	value = REG_SET_FIELD(value, SQ_CMD, MODE, 0x01);
 	value = REG_SET_FIELD(value, SQ_CMD, CHECK_VMID, 1);
 	value = REG_SET_FIELD(value, SQ_CMD, VM_ID, vmid);
+	amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
 	WREG32_SOC15(GC, 0, mmSQ_CMD, value);
+	amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
 }
 
 static void gfx_v9_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev,
@@ -5779,17 +5785,59 @@
 	}
 }
 
+static u32 gfx_v9_0_get_cpc_int_cntl(struct amdgpu_device *adev,
+				     int me, int pipe)
+{
+	/*
+	 * amdgpu controls only the first MEC. That's why this function only
+	 * handles the setting of interrupts for this specific MEC. All other
+	 * pipes' interrupts are set by amdkfd.
+	 */
+	if (me != 1)
+		return 0;
+
+	switch (pipe) {
+	case 0:
+		return SOC15_REG_OFFSET(GC, 0, mmCP_ME1_PIPE0_INT_CNTL);
+	case 1:
+		return SOC15_REG_OFFSET(GC, 0, mmCP_ME1_PIPE1_INT_CNTL);
+	case 2:
+		return SOC15_REG_OFFSET(GC, 0, mmCP_ME1_PIPE2_INT_CNTL);
+	case 3:
+		return SOC15_REG_OFFSET(GC, 0, mmCP_ME1_PIPE3_INT_CNTL);
+	default:
+		return 0;
+	}
+}
+
 static int gfx_v9_0_set_priv_reg_fault_state(struct amdgpu_device *adev,
 					     struct amdgpu_irq_src *source,
 					     unsigned type,
 					     enum amdgpu_interrupt_state state)
 {
+	u32 cp_int_cntl_reg, cp_int_cntl;
+	int i, j;
+
 	switch (state) {
 	case AMDGPU_IRQ_STATE_DISABLE:
 	case AMDGPU_IRQ_STATE_ENABLE:
 		WREG32_FIELD15(GC, 0, CP_INT_CNTL_RING0,
 			       PRIV_REG_INT_ENABLE,
 			       state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
+		for (i = 0; i < adev->gfx.mec.num_mec; i++) {
+			for (j = 0; j < adev->gfx.mec.num_pipe_per_mec; j++) {
+				/* MECs start at 1 */
+				cp_int_cntl_reg = gfx_v9_0_get_cpc_int_cntl(adev, i + 1, j);
+
+				if (cp_int_cntl_reg) {
+					cp_int_cntl = RREG32_SOC15_IP(GC, cp_int_cntl_reg);
+					cp_int_cntl = REG_SET_FIELD(cp_int_cntl, CP_ME1_PIPE0_INT_CNTL,
+								    PRIV_REG_INT_ENABLE,
+								    state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
+					WREG32_SOC15_IP(GC, cp_int_cntl_reg, cp_int_cntl);
+				}
+			}
+		}
 		break;
 	default:
 		break;
@@ -6991,7 +7039,6 @@
 		7 + /* gfx_v9_0_ring_emit_pipeline_sync */
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 5 +
 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 +
-		2 + /* gfx_v9_0_ring_emit_vm_flush */
 		8 + 8 + 8 + /* gfx_v9_0_ring_emit_fence x3 for user fence, vm fence */
 		7 + /* gfx_v9_0_emit_mem_sync */
 		5 + /* gfx_v9_0_emit_wave_limit for updating mmSPI_WCL_PIPE_PERCENT_GFX register */
@@ -7029,7 +7076,6 @@
 		7 + /* gfx_v9_0_ring_emit_pipeline_sync */
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 5 +
 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 7 +
-		2 + /* gfx_v9_0_ring_emit_vm_flush */
 		8 + 8 + 8, /* gfx_v9_0_ring_emit_fence_kiq x3 for user fence, vm fence */
 	.emit_ib_size =	7, /* gfx_v9_0_ring_emit_ib_compute */
 	.emit_fence = gfx_v9_0_ring_emit_fence_kiq,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c
@@ -426,16 +426,16 @@
 
 static int gfx_v9_4_3_init_microcode(struct amdgpu_device *adev)
 {
-	const char *chip_name;
+	char ucode_prefix[15];
 	int r;
 
-	chip_name = "gc_9_4_3";
+	amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix));
 
-	r = gfx_v9_4_3_init_rlc_microcode(adev, chip_name);
+	r = gfx_v9_4_3_init_rlc_microcode(adev, ucode_prefix);
 	if (r)
 		return r;
 
-	r = gfx_v9_4_3_init_cp_compute_microcode(adev, chip_name);
+	r = gfx_v9_4_3_init_cp_compute_microcode(adev, ucode_prefix);
 	if (r)
 		return r;
 
@@ -2755,21 +2755,63 @@
 	}
 }
 
+static u32 gfx_v9_4_3_get_cpc_int_cntl(struct amdgpu_device *adev,
+				     int xcc_id, int me, int pipe)
+{
+	/*
+	 * amdgpu controls only the first MEC. That's why this function only
+	 * handles the setting of interrupts for this specific MEC. All other
+	 * pipes' interrupts are set by amdkfd.
+	 */
+	if (me != 1)
+		return 0;
+
+	switch (pipe) {
+	case 0:
+		return SOC15_REG_OFFSET(GC, GET_INST(GC, xcc_id), regCP_ME1_PIPE0_INT_CNTL);
+	case 1:
+		return SOC15_REG_OFFSET(GC, GET_INST(GC, xcc_id), regCP_ME1_PIPE1_INT_CNTL);
+	case 2:
+		return SOC15_REG_OFFSET(GC, GET_INST(GC, xcc_id), regCP_ME1_PIPE2_INT_CNTL);
+	case 3:
+		return SOC15_REG_OFFSET(GC, GET_INST(GC, xcc_id), regCP_ME1_PIPE3_INT_CNTL);
+	default:
+		return 0;
+	}
+}
+
 static int gfx_v9_4_3_set_priv_reg_fault_state(struct amdgpu_device *adev,
 					     struct amdgpu_irq_src *source,
 					     unsigned type,
 					     enum amdgpu_interrupt_state state)
 {
-	int i, num_xcc;
+	u32 mec_int_cntl_reg, mec_int_cntl;
+	int i, j, k, num_xcc;
 
 	num_xcc = NUM_XCC(adev->gfx.xcc_mask);
 	switch (state) {
 	case AMDGPU_IRQ_STATE_DISABLE:
 	case AMDGPU_IRQ_STATE_ENABLE:
-		for (i = 0; i < num_xcc; i++)
+		for (i = 0; i < num_xcc; i++) {
 			WREG32_FIELD15_PREREG(GC, GET_INST(GC, i), CP_INT_CNTL_RING0,
-				PRIV_REG_INT_ENABLE,
-				state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
+					      PRIV_REG_INT_ENABLE,
+					      state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
+			for (j = 0; j < adev->gfx.mec.num_mec; j++) {
+				for (k = 0; k < adev->gfx.mec.num_pipe_per_mec; k++) {
+					/* MECs start at 1 */
+					mec_int_cntl_reg = gfx_v9_4_3_get_cpc_int_cntl(adev, i, j + 1, k);
+
+					if (mec_int_cntl_reg) {
+						mec_int_cntl = RREG32_XCC(mec_int_cntl_reg, i);
+						mec_int_cntl = REG_SET_FIELD(mec_int_cntl, CP_ME1_PIPE0_INT_CNTL,
+									     PRIV_REG_INT_ENABLE,
+									     state == AMDGPU_IRQ_STATE_ENABLE ?
+									     1 : 0);
+						WREG32_XCC(mec_int_cntl_reg, mec_int_cntl, i);
+					}
+				}
+			}
+		}
 		break;
 	default:
 		break;
@@ -4121,9 +4163,10 @@
 static int gfx_v9_4_3_get_cu_info(struct amdgpu_device *adev,
 				 struct amdgpu_cu_info *cu_info)
 {
-	int i, j, k, counter, xcc_id, active_cu_number = 0;
-	u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0;
+	int i, j, k, prev_counter, counter, xcc_id, active_cu_number = 0;
+	u32 mask, bitmap, ao_bitmap, ao_cu_mask = 0, tmp;
 	unsigned disable_masks[4 * 4];
+	bool is_symmetric_cus;
 
 	if (!adev || !cu_info)
 		return -EINVAL;
@@ -4141,6 +4184,7 @@
 
 	mutex_lock(&adev->grbm_idx_mutex);
 	for (xcc_id = 0; xcc_id < NUM_XCC(adev->gfx.xcc_mask); xcc_id++) {
+		is_symmetric_cus = true;
 		for (i = 0; i < adev->gfx.config.max_shader_engines; i++) {
 			for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) {
 				mask = 1;
@@ -4168,6 +4212,15 @@
 					ao_cu_mask |= (ao_bitmap << (i * 16 + j * 8));
 				cu_info->ao_cu_bitmap[i][j] = ao_bitmap;
 			}
+			if (i && is_symmetric_cus && prev_counter != counter)
+				is_symmetric_cus = false;
+			prev_counter = counter;
+		}
+		if (is_symmetric_cus) {
+			tmp = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_CPC_DEBUG);
+			tmp = REG_SET_FIELD(tmp, CP_CPC_DEBUG, CPC_HARVESTING_RELAUNCH_DISABLE, 1);
+			tmp = REG_SET_FIELD(tmp, CP_CPC_DEBUG, CPC_HARVESTING_DISPATCH_DISABLE, 1);
+			WREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_CPC_DEBUG, tmp);
 		}
 		gfx_v9_4_3_xcc_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff,
 					    xcc_id);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
@@ -570,6 +570,7 @@
 		adev->mmhub.funcs = &mmhub_v3_0_2_funcs;
 		break;
 	case IP_VERSION(3, 3, 0):
+	case IP_VERSION(3, 3, 1):
 		adev->mmhub.funcs = &mmhub_v3_3_funcs;
 		break;
 	default:
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
@@ -1107,8 +1107,10 @@
 					 uint64_t *flags)
 {
 	struct amdgpu_device *bo_adev = amdgpu_ttm_adev(bo->tbo.bdev);
-	bool is_vram = bo->tbo.resource->mem_type == TTM_PL_VRAM;
-	bool coherent = bo->flags & (AMDGPU_GEM_CREATE_COHERENT | AMDGPU_GEM_CREATE_EXT_COHERENT);
+	bool is_vram = bo->tbo.resource &&
+		bo->tbo.resource->mem_type == TTM_PL_VRAM;
+	bool coherent = bo->flags & (AMDGPU_GEM_CREATE_COHERENT |
+				     AMDGPU_GEM_CREATE_EXT_COHERENT);
 	bool ext_coherent = bo->flags & AMDGPU_GEM_CREATE_EXT_COHERENT;
 	bool uncached = bo->flags & AMDGPU_GEM_CREATE_UNCACHED;
 	struct amdgpu_vm *vm = mapping->bo_va->base.vm;
@@ -1116,6 +1118,8 @@
 	bool snoop = false;
 	bool is_local;
 
+	dma_resv_assert_held(bo->tbo.base.resv);
+
 	switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
 	case IP_VERSION(9, 4, 1):
 	case IP_VERSION(9, 4, 2):
@@ -1233,9 +1237,8 @@
 		*flags &= ~AMDGPU_PTE_VALID;
 	}
 
-	if (bo && bo->tbo.resource)
-		gmc_v9_0_get_coherence_flags(adev, mapping->bo_va->base.bo,
-					     mapping, flags);
+	if ((*flags & AMDGPU_PTE_VALID) && bo)
+		gmc_v9_0_get_coherence_flags(adev, bo, mapping, flags);
 }
 
 static void gmc_v9_0_override_vm_pte_flags(struct amdgpu_device *adev,
@@ -1897,7 +1900,7 @@
 		break;
 	}
 
-	size = adev->gmc.real_vram_size >> AMDGPU_GPU_PAGE_SHIFT;
+	size = (adev->gmc.real_vram_size + SZ_16M) >> AMDGPU_GPU_PAGE_SHIFT;
 	size /= adev->gmc.num_mem_partitions;
 
 	for (i = 0; i < adev->gmc.num_mem_partitions; ++i) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c
@@ -40,10 +40,17 @@
 static void hdp_v4_0_flush_hdp(struct amdgpu_device *adev,
 				struct amdgpu_ring *ring)
 {
-	if (!ring || !ring->funcs->emit_wreg)
-		WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
-	else
+	if (!ring || !ring->funcs->emit_wreg) {
+		WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
+		/* We just need to read back a register to post the write.
+		 * Reading back the remapped register causes problems on
+		 * some platforms so just read back the memory size register.
+		 */
+		if (adev->nbio.funcs->get_memsize)
+			adev->nbio.funcs->get_memsize(adev);
+	} else {
 		amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
+	}
 }
 
 static void hdp_v4_0_invalidate_hdp(struct amdgpu_device *adev,
@@ -53,11 +60,13 @@
 	    amdgpu_ip_version(adev, HDP_HWIP, 0) == IP_VERSION(4, 4, 2))
 		return;
 
-	if (!ring || !ring->funcs->emit_wreg)
+	if (!ring || !ring->funcs->emit_wreg) {
 		WREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE, 1);
-	else
+		RREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE);
+	} else {
 		amdgpu_ring_emit_wreg(ring, SOC15_REG_OFFSET(
 			HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 1);
+	}
 }
 
 static void hdp_v4_0_query_ras_error_count(struct amdgpu_device *adev,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c
@@ -31,10 +31,17 @@
 static void hdp_v5_0_flush_hdp(struct amdgpu_device *adev,
 				struct amdgpu_ring *ring)
 {
-	if (!ring || !ring->funcs->emit_wreg)
-		WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
-	else
+	if (!ring || !ring->funcs->emit_wreg) {
+		WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
+		/* We just need to read back a register to post the write.
+		 * Reading back the remapped register causes problems on
+		 * some platforms so just read back the memory size register.
+		 */
+		if (adev->nbio.funcs->get_memsize)
+			adev->nbio.funcs->get_memsize(adev);
+	} else {
 		amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
+	}
 }
 
 static void hdp_v5_0_invalidate_hdp(struct amdgpu_device *adev,
@@ -42,6 +49,7 @@
 {
 	if (!ring || !ring->funcs->emit_wreg) {
 		WREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE, 1);
+		RREG32_SOC15_NO_KIQ(HDP, 0, mmHDP_READ_CACHE_INVALIDATE);
 	} else {
 		amdgpu_ring_emit_wreg(ring, SOC15_REG_OFFSET(
 					HDP, 0, mmHDP_READ_CACHE_INVALIDATE), 1);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c
@@ -31,13 +31,25 @@
 static void hdp_v5_2_flush_hdp(struct amdgpu_device *adev,
 				struct amdgpu_ring *ring)
 {
-	if (!ring || !ring->funcs->emit_wreg)
+	if (!ring || !ring->funcs->emit_wreg) {
 		WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2,
 			0);
-	else
+		if (amdgpu_sriov_vf(adev)) {
+			/* this is fine because SR_IOV doesn't remap the register */
+			RREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2);
+		} else {
+			/* We just need to read back a register to post the write.
+			 * Reading back the remapped register causes problems on
+			 * some platforms so just read back the memory size register.
+			 */
+			if (adev->nbio.funcs->get_memsize)
+				adev->nbio.funcs->get_memsize(adev);
+		}
+	} else {
 		amdgpu_ring_emit_wreg(ring,
 			(adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2,
 			0);
+	}
 }
 
 static void hdp_v5_2_update_mem_power_gating(struct amdgpu_device *adev,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c
@@ -34,10 +34,17 @@
 static void hdp_v6_0_flush_hdp(struct amdgpu_device *adev,
 				struct amdgpu_ring *ring)
 {
-	if (!ring || !ring->funcs->emit_wreg)
-		WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
-	else
+	if (!ring || !ring->funcs->emit_wreg) {
+		WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
+		/* We just need to read back a register to post the write.
+		 * Reading back the remapped register causes problems on
+		 * some platforms so just read back the memory size register.
+		 */
+		if (adev->nbio.funcs->get_memsize)
+			adev->nbio.funcs->get_memsize(adev);
+	} else {
 		amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0);
+	}
 }
 
 static void hdp_v6_0_update_clock_gating(struct amdgpu_device *adev,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c
@@ -135,6 +135,34 @@
 
 	tmp = RREG32(ih_regs->ih_rb_cntl);
 	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0));
+
+	if (enable) {
+		/* Unset the CLEAR_OVERFLOW bit to make sure the next step
+		 * is switching the bit from 0 to 1
+		 */
+		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
+		if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
+			if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
+				return -ETIMEDOUT;
+		} else {
+			WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
+		}
+
+		/* Clear RB_OVERFLOW bit */
+		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
+		if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
+			if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
+				return -ETIMEDOUT;
+		} else {
+			WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
+		}
+
+		/* Unset the CLEAR_OVERFLOW bit immediately so new overflows
+		 * can be detected.
+		 */
+		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
+	}
+
 	/* enable_intr field is only valid in ring0 */
 	if (ih == &adev->irq.ih)
 		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c
@@ -23,6 +23,7 @@
 
 #include "amdgpu.h"
 #include "amdgpu_jpeg.h"
+#include "amdgpu_cs.h"
 #include "soc15.h"
 #include "soc15d.h"
 #include "vcn_v1_0.h"
@@ -34,6 +35,9 @@
 static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
 static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev);
 static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring);
+static int jpeg_v1_dec_ring_parse_cs(struct amdgpu_cs_parser *parser,
+				     struct amdgpu_job *job,
+				     struct amdgpu_ib *ib);
 
 static void jpeg_v1_0_decode_ring_patch_wreg(struct amdgpu_ring *ring, uint32_t *ptr, uint32_t reg_offset, uint32_t val)
 {
@@ -300,7 +304,10 @@
 
 	amdgpu_ring_write(ring,
 		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_VMID), 0, 0, PACKETJ_TYPE0));
-	amdgpu_ring_write(ring, (vmid | (vmid << 4)));
+	if (ring->funcs->parse_cs)
+		amdgpu_ring_write(ring, 0);
+	else
+		amdgpu_ring_write(ring, (vmid | (vmid << 4)));
 
 	amdgpu_ring_write(ring,
 		PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JPEG_VMID), 0, 0, PACKETJ_TYPE0));
@@ -554,6 +561,7 @@
 	.get_rptr = jpeg_v1_0_decode_ring_get_rptr,
 	.get_wptr = jpeg_v1_0_decode_ring_get_wptr,
 	.set_wptr = jpeg_v1_0_decode_ring_set_wptr,
+	.parse_cs = jpeg_v1_dec_ring_parse_cs,
 	.emit_frame_size =
 		6 + 6 + /* hdp invalidate / flush */
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
@@ -612,3 +620,69 @@
 
 	vcn_v1_0_set_pg_for_begin_use(ring, set_clocks);
 }
+
+/**
+ * jpeg_v1_dec_ring_parse_cs - command submission parser
+ *
+ * @parser: Command submission parser context
+ * @job: the job to parse
+ * @ib: the IB to parse
+ *
+ * Parse the command stream, return -EINVAL for invalid packet,
+ * 0 otherwise
+ */
+static int jpeg_v1_dec_ring_parse_cs(struct amdgpu_cs_parser *parser,
+				     struct amdgpu_job *job,
+				     struct amdgpu_ib *ib)
+{
+	u32 i, reg, res, cond, type;
+	int ret = 0;
+	struct amdgpu_device *adev = parser->adev;
+
+	for (i = 0; i < ib->length_dw ; i += 2) {
+		reg  = CP_PACKETJ_GET_REG(ib->ptr[i]);
+		res  = CP_PACKETJ_GET_RES(ib->ptr[i]);
+		cond = CP_PACKETJ_GET_COND(ib->ptr[i]);
+		type = CP_PACKETJ_GET_TYPE(ib->ptr[i]);
+
+		if (res || cond != PACKETJ_CONDITION_CHECK0) /* only allow 0 for now */
+			return -EINVAL;
+
+		if (reg >= JPEG_V1_REG_RANGE_START && reg <= JPEG_V1_REG_RANGE_END)
+			continue;
+
+		switch (type) {
+		case PACKETJ_TYPE0:
+			if (reg != JPEG_V1_LMI_JPEG_WRITE_64BIT_BAR_HIGH &&
+			    reg != JPEG_V1_LMI_JPEG_WRITE_64BIT_BAR_LOW &&
+			    reg != JPEG_V1_LMI_JPEG_READ_64BIT_BAR_HIGH &&
+			    reg != JPEG_V1_LMI_JPEG_READ_64BIT_BAR_LOW &&
+			    reg != JPEG_V1_REG_CTX_INDEX &&
+			    reg != JPEG_V1_REG_CTX_DATA) {
+				ret = -EINVAL;
+			}
+			break;
+		case PACKETJ_TYPE1:
+			if (reg != JPEG_V1_REG_CTX_DATA)
+				ret = -EINVAL;
+			break;
+		case PACKETJ_TYPE3:
+			if (reg != JPEG_V1_REG_SOFT_RESET)
+				ret = -EINVAL;
+			break;
+		case PACKETJ_TYPE6:
+			if (ib->ptr[i] != CP_PACKETJ_NOP)
+				ret = -EINVAL;
+			break;
+		default:
+			ret = -EINVAL;
+		}
+
+		if (ret) {
+			dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]);
+			break;
+		}
+	}
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h
@@ -29,4 +29,15 @@
 void jpeg_v1_0_sw_fini(void *handle);
 void jpeg_v1_0_start(struct amdgpu_device *adev, int mode);
 
+#define JPEG_V1_REG_RANGE_START	0x8000
+#define JPEG_V1_REG_RANGE_END	0x803f
+
+#define JPEG_V1_LMI_JPEG_WRITE_64BIT_BAR_HIGH	0x8238
+#define JPEG_V1_LMI_JPEG_WRITE_64BIT_BAR_LOW	0x8239
+#define JPEG_V1_LMI_JPEG_READ_64BIT_BAR_HIGH	0x825a
+#define JPEG_V1_LMI_JPEG_READ_64BIT_BAR_LOW	0x825b
+#define JPEG_V1_REG_CTX_INDEX			0x8328
+#define JPEG_V1_REG_CTX_DATA			0x8329
+#define JPEG_V1_REG_SOFT_RESET			0x83a0
+
 #endif /*__JPEG_V1_0_H__*/
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
@@ -23,6 +23,7 @@
 
 #include "amdgpu.h"
 #include "amdgpu_jpeg.h"
+#include "amdgpu_cs.h"
 #include "amdgpu_pm.h"
 #include "soc15.h"
 #include "soc15d.h"
@@ -543,11 +544,15 @@
 
 	amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET,
 		0, 0, PACKETJ_TYPE0));
-	amdgpu_ring_write(ring, (vmid | (vmid << 4)));
+
+	if (ring->funcs->parse_cs)
+		amdgpu_ring_write(ring, 0);
+	else
+		amdgpu_ring_write(ring, (vmid | (vmid << 4) | (vmid << 8)));
 
 	amdgpu_ring_write(ring, PACKETJ(mmUVD_LMI_JPEG_VMID_INTERNAL_OFFSET,
 		0, 0, PACKETJ_TYPE0));
-	amdgpu_ring_write(ring, (vmid | (vmid << 4)));
+	amdgpu_ring_write(ring, (vmid | (vmid << 4) | (vmid << 8)));
 
 	amdgpu_ring_write(ring,	PACKETJ(mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET,
 		0, 0, PACKETJ_TYPE0));
@@ -767,6 +772,7 @@
 	.get_rptr = jpeg_v2_0_dec_ring_get_rptr,
 	.get_wptr = jpeg_v2_0_dec_ring_get_wptr,
 	.set_wptr = jpeg_v2_0_dec_ring_set_wptr,
+	.parse_cs = jpeg_v2_dec_ring_parse_cs,
 	.emit_frame_size =
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
@@ -814,3 +820,58 @@
 		.rev = 0,
 		.funcs = &jpeg_v2_0_ip_funcs,
 };
+
+/**
+ * jpeg_v2_dec_ring_parse_cs - command submission parser
+ *
+ * @parser: Command submission parser context
+ * @job: the job to parse
+ * @ib: the IB to parse
+ *
+ * Parse the command stream, return -EINVAL for invalid packet,
+ * 0 otherwise
+ */
+int jpeg_v2_dec_ring_parse_cs(struct amdgpu_cs_parser *parser,
+			      struct amdgpu_job *job,
+			      struct amdgpu_ib *ib)
+{
+	u32 i, reg, res, cond, type;
+	struct amdgpu_device *adev = parser->adev;
+
+	for (i = 0; i < ib->length_dw ; i += 2) {
+		reg  = CP_PACKETJ_GET_REG(ib->ptr[i]);
+		res  = CP_PACKETJ_GET_RES(ib->ptr[i]);
+		cond = CP_PACKETJ_GET_COND(ib->ptr[i]);
+		type = CP_PACKETJ_GET_TYPE(ib->ptr[i]);
+
+		if (res) /* only support 0 at the moment */
+			return -EINVAL;
+
+		switch (type) {
+		case PACKETJ_TYPE0:
+			if (cond != PACKETJ_CONDITION_CHECK0 || reg < JPEG_REG_RANGE_START ||
+			    reg > JPEG_REG_RANGE_END) {
+				dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]);
+				return -EINVAL;
+			}
+			break;
+		case PACKETJ_TYPE3:
+			if (cond != PACKETJ_CONDITION_CHECK3 || reg < JPEG_REG_RANGE_START ||
+			    reg > JPEG_REG_RANGE_END) {
+				dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]);
+				return -EINVAL;
+			}
+			break;
+		case PACKETJ_TYPE6:
+			if (ib->ptr[i] == CP_PACKETJ_NOP)
+				continue;
+			dev_err(adev->dev, "Invalid packet [0x%08x]!\n", ib->ptr[i]);
+			return -EINVAL;
+		default:
+			dev_err(adev->dev, "Unknown packet type %d !\n", type);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.h
@@ -45,6 +45,9 @@
 
 #define JRBC_DEC_EXTERNAL_REG_WRITE_ADDR				0x18000
 
+#define JPEG_REG_RANGE_START						0x4000
+#define JPEG_REG_RANGE_END						0x41c2
+
 void jpeg_v2_0_dec_ring_insert_start(struct amdgpu_ring *ring);
 void jpeg_v2_0_dec_ring_insert_end(struct amdgpu_ring *ring);
 void jpeg_v2_0_dec_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
@@ -57,6 +60,9 @@
 				unsigned vmid, uint64_t pd_addr);
 void jpeg_v2_0_dec_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg, uint32_t val);
 void jpeg_v2_0_dec_ring_nop(struct amdgpu_ring *ring, uint32_t count);
+int jpeg_v2_dec_ring_parse_cs(struct amdgpu_cs_parser *parser,
+			      struct amdgpu_job *job,
+			      struct amdgpu_ib *ib);
 
 extern const struct amdgpu_ip_block_version jpeg_v2_0_ip_block;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
@@ -660,6 +660,7 @@
 	.get_rptr = jpeg_v2_5_dec_ring_get_rptr,
 	.get_wptr = jpeg_v2_5_dec_ring_get_wptr,
 	.set_wptr = jpeg_v2_5_dec_ring_set_wptr,
+	.parse_cs = jpeg_v2_dec_ring_parse_cs,
 	.emit_frame_size =
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
@@ -689,6 +690,7 @@
 	.get_rptr = jpeg_v2_5_dec_ring_get_rptr,
 	.get_wptr = jpeg_v2_5_dec_ring_get_wptr,
 	.set_wptr = jpeg_v2_5_dec_ring_set_wptr,
+	.parse_cs = jpeg_v2_dec_ring_parse_cs,
 	.emit_frame_size =
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c
@@ -565,6 +565,7 @@
 	.get_rptr = jpeg_v3_0_dec_ring_get_rptr,
 	.get_wptr = jpeg_v3_0_dec_ring_get_wptr,
 	.set_wptr = jpeg_v3_0_dec_ring_set_wptr,
+	.parse_cs = jpeg_v2_dec_ring_parse_cs,
 	.emit_frame_size =
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c
@@ -727,6 +727,7 @@
 	.get_rptr = jpeg_v4_0_dec_ring_get_rptr,
 	.get_wptr = jpeg_v4_0_dec_ring_get_wptr,
 	.set_wptr = jpeg_v4_0_dec_ring_set_wptr,
+	.parse_cs = jpeg_v2_dec_ring_parse_cs,
 	.emit_frame_size =
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.h
@@ -32,5 +32,4 @@
 };
 
 extern const struct amdgpu_ip_block_version jpeg_v4_0_ip_block;
-
 #endif /* __JPEG_V4_0_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c
@@ -25,6 +25,7 @@
 #include "amdgpu_jpeg.h"
 #include "soc15.h"
 #include "soc15d.h"
+#include "jpeg_v2_0.h"
 #include "jpeg_v4_0_3.h"
 #include "mmsch_v4_0_3.h"
 
@@ -658,11 +659,12 @@
 		amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
 			0, 0, PACKETJ_TYPE0));
 		amdgpu_ring_write(ring, 0x62a04); /* PCTL0_MMHUB_DEEPSLEEP_IB */
-	}
 
-	amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
-		0, 0, PACKETJ_TYPE0));
-	amdgpu_ring_write(ring, 0x80004000);
+		amdgpu_ring_write(ring,
+				  PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, 0,
+					  0, PACKETJ_TYPE0));
+		amdgpu_ring_write(ring, 0x80004000);
+	}
 }
 
 /**
@@ -678,11 +680,12 @@
 		amdgpu_ring_write(ring, PACKETJ(regUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
 			0, 0, PACKETJ_TYPE0));
 		amdgpu_ring_write(ring, 0x62a04);
-	}
 
-	amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
-		0, 0, PACKETJ_TYPE0));
-	amdgpu_ring_write(ring, 0x00004000);
+		amdgpu_ring_write(ring,
+				  PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR, 0,
+					  0, PACKETJ_TYPE0));
+		amdgpu_ring_write(ring, 0x00004000);
+	}
 }
 
 /**
@@ -773,11 +776,15 @@
 
 	amdgpu_ring_write(ring, PACKETJ(regUVD_LMI_JRBC_IB_VMID_INTERNAL_OFFSET,
 		0, 0, PACKETJ_TYPE0));
-	amdgpu_ring_write(ring, (vmid | (vmid << 4)));
+
+	if (ring->funcs->parse_cs)
+		amdgpu_ring_write(ring, 0);
+	else
+		amdgpu_ring_write(ring, (vmid | (vmid << 4) | (vmid << 8)));
 
 	amdgpu_ring_write(ring, PACKETJ(regUVD_LMI_JPEG_VMID_INTERNAL_OFFSET,
 		0, 0, PACKETJ_TYPE0));
-	amdgpu_ring_write(ring, (vmid | (vmid << 4)));
+	amdgpu_ring_write(ring, (vmid | (vmid << 4) | (vmid << 8)));
 
 	amdgpu_ring_write(ring,	PACKETJ(regUVD_LMI_JRBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET,
 		0, 0, PACKETJ_TYPE0));
@@ -1061,6 +1068,7 @@
 	.get_rptr = jpeg_v4_0_3_dec_ring_get_rptr,
 	.get_wptr = jpeg_v4_0_3_dec_ring_get_wptr,
 	.set_wptr = jpeg_v4_0_3_dec_ring_set_wptr,
+	.parse_cs = jpeg_v2_dec_ring_parse_cs,
 	.emit_frame_size =
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c
@@ -153,7 +153,7 @@
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 	struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec;
-	int r;
+	int r = 0;
 
 	r = amdgpu_ring_test_helper(ring);
 	if (r)
@@ -564,6 +564,7 @@
 	.get_rptr = jpeg_v4_0_5_dec_ring_get_rptr,
 	.get_wptr = jpeg_v4_0_5_dec_ring_get_wptr,
 	.set_wptr = jpeg_v4_0_5_dec_ring_set_wptr,
+	.parse_cs = jpeg_v2_dec_ring_parse_cs,
 	.emit_frame_size =
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/mmhub_v1_7.c
@@ -544,7 +544,7 @@
 
 static void mmhub_v1_7_get_clockgating(struct amdgpu_device *adev, u64 *flags)
 {
-	int data, data1;
+	u32 data, data1;
 
 	if (amdgpu_sriov_vf(adev))
 		*flags = 0;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
@@ -671,7 +671,7 @@
 
 static void mmhub_v2_0_get_clockgating(struct amdgpu_device *adev, u64 *flags)
 {
-	int data, data1;
+	u32 data, data1;
 
 	if (amdgpu_sriov_vf(adev))
 		*flags = 0;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/mmhub_v3_3.c
@@ -98,16 +98,16 @@
 
 	switch (amdgpu_ip_version(adev, MMHUB_HWIP, 0)) {
 	case IP_VERSION(3, 3, 0):
-		mmhub_cid = mmhub_client_ids_v3_3[cid][rw];
+	case IP_VERSION(3, 3, 1):
+		mmhub_cid = cid < ARRAY_SIZE(mmhub_client_ids_v3_3) ?
+			    mmhub_client_ids_v3_3[cid][rw] :
+			    cid == 0x140 ? "UMSCH" : NULL;
 		break;
 	default:
 		mmhub_cid = NULL;
 		break;
 	}
 
-	if (!mmhub_cid && cid == 0x140)
-		mmhub_cid = "UMSCH";
-
 	dev_err(adev->dev, "\t Faulty UTCL2 client ID: %s (0x%x)\n",
 		mmhub_cid ? mmhub_cid : "unknown", cid);
 	dev_err(adev->dev, "\t MORE_FAULTS: 0x%lx\n",
@@ -560,7 +560,7 @@
 
 static void mmhub_v3_3_get_clockgating(struct amdgpu_device *adev, u64 *flags)
 {
-	int data;
+	u32 data;
 
 	if (amdgpu_sriov_vf(adev))
 		*flags = 0;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c
@@ -657,7 +657,7 @@
 
 static void mmhub_v9_4_get_clockgating(struct amdgpu_device *adev, u64 *flags)
 {
-	int data, data1;
+	u32 data, data1;
 
 	if (amdgpu_sriov_vf(adev))
 		*flags = 0;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/mxgpu_ai.c
@@ -290,6 +290,7 @@
 		reset_context.method = AMD_RESET_METHOD_NONE;
 		reset_context.reset_req_dev = adev;
 		clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
+		set_bit(AMDGPU_HOST_FLR, &reset_context.flags);
 
 		amdgpu_device_gpu_recover(adev, NULL, &reset_context);
 	}
@@ -317,7 +318,7 @@
 
 	switch (event) {
 		case IDH_FLR_NOTIFICATION:
-		if (amdgpu_sriov_runtime(adev) && !amdgpu_in_reset(adev))
+		if (amdgpu_sriov_runtime(adev))
 			WARN_ONCE(!amdgpu_reset_domain_schedule(adev->reset_domain,
 								&adev->virt.flr_work),
 				  "Failed to queue work! at %s",
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
@@ -315,6 +315,7 @@
 		reset_context.method = AMD_RESET_METHOD_NONE;
 		reset_context.reset_req_dev = adev;
 		clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
+		set_bit(AMDGPU_HOST_FLR, &reset_context.flags);
 
 		amdgpu_device_gpu_recover(adev, NULL, &reset_context);
 	}
@@ -345,7 +346,7 @@
 
 	switch (event) {
 	case IDH_FLR_NOTIFICATION:
-		if (amdgpu_sriov_runtime(adev) && !amdgpu_in_reset(adev))
+		if (amdgpu_sriov_runtime(adev))
 			WARN_ONCE(!amdgpu_reset_domain_schedule(adev->reset_domain,
 				   &adev->virt.flr_work),
 				  "Failed to queue work! at %s",
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/mxgpu_vi.c
@@ -529,6 +529,7 @@
 		reset_context.method = AMD_RESET_METHOD_NONE;
 		reset_context.reset_req_dev = adev;
 		clear_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
+		set_bit(AMDGPU_HOST_FLR, &reset_context.flags);
 
 		amdgpu_device_gpu_recover(adev, NULL, &reset_context);
 	}
@@ -560,7 +561,7 @@
 		r = xgpu_vi_mailbox_rcv_msg(adev, IDH_FLR_NOTIFICATION);
 
 		/* only handle FLR_NOTIFY now */
-		if (!r && !amdgpu_in_reset(adev))
+		if (!r)
 			WARN_ONCE(!amdgpu_reset_domain_schedule(adev->reset_domain,
 								&adev->virt.flr_work),
 				  "Failed to queue work! at %s",
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/nbio_v7_11.c
@@ -270,6 +270,15 @@
 	if (def != data)
 		WREG32_SOC15(NBIO, 0, regBIF_BIF256_CI256_RC3X4_USB4_PCIE_MST_CTRL_3, data);
 
+	switch (amdgpu_ip_version(adev, NBIO_HWIP, 0)) {
+	case IP_VERSION(7, 11, 0):
+	case IP_VERSION(7, 11, 1):
+	case IP_VERSION(7, 11, 2):
+	case IP_VERSION(7, 11, 3):
+		data = RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF5_STRAP4) & ~BIT(23);
+		WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF5_STRAP4, data);
+		break;
+	}
 }
 
 static void nbio_v7_11_update_medium_grain_clock_gating(struct amdgpu_device *adev,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c
@@ -387,7 +387,7 @@
 		else
 			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
 			 * according to hw team and count ue number
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/nbio_v7_7.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/nbio_v7_7.c
@@ -247,6 +247,12 @@
 	if (def != data)
 		WREG32_SOC15(NBIO, 0, regBIF0_PCIE_MST_CTRL_3, data);
 
+	switch (amdgpu_ip_version(adev, NBIO_HWIP, 0)) {
+	case IP_VERSION(7, 7, 0):
+		data = RREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF5_STRAP4) & ~BIT(23);
+		WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF5_STRAP4, data);
+		break;
+	}
 }
 
 static void nbio_v7_7_update_medium_grain_clock_gating(struct amdgpu_device *adev,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/nv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/nv.c
@@ -68,8 +68,8 @@
 
 /* Navi */
 static const struct amdgpu_video_codec_info nv_video_codecs_encode_array[] = {
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 0)},
 };
 
 static const struct amdgpu_video_codecs nv_video_codecs_encode = {
@@ -95,8 +95,8 @@
 
 /* Sienna Cichlid */
 static const struct amdgpu_video_codec_info sc_video_codecs_encode_array[] = {
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2160, 0)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 7680, 4352, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 0)},
 };
 
 static const struct amdgpu_video_codecs sc_video_codecs_encode = {
@@ -137,8 +137,8 @@
 
 /* SRIOV Sienna Cichlid, not const since data is controlled by host */
 static struct amdgpu_video_codec_info sriov_sc_video_codecs_encode_array[] = {
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2160, 0)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 7680, 4352, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 0)},
 };
 
 static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array_vcn0[] = {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
@@ -2017,10 +2017,13 @@
 				      struct amdgpu_irq_src *source,
 				      struct amdgpu_iv_entry *entry)
 {
-	uint32_t instance;
+	int instance;
 
 	DRM_DEBUG("IH: SDMA trap\n");
 	instance = sdma_v4_0_irq_id_to_seq(entry->client_id);
+	if (instance < 0)
+		return instance;
+
 	switch (entry->ring_id) {
 	case 0:
 		amdgpu_fence_process(&adev->sdma.instance[instance].ring);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c
@@ -366,7 +366,8 @@
 	u32 ref_and_mask = 0;
 	const struct nbio_hdp_flush_reg *nbio_hf_reg = adev->nbio.hdp_flush_reg;
 
-	ref_and_mask = nbio_hf_reg->ref_and_mask_sdma0 << ring->me;
+	ref_and_mask = nbio_hf_reg->ref_and_mask_sdma0
+		       << (ring->me % adev->sdma.num_inst_per_aid);
 
 	sdma_v4_4_2_wait_reg_mem(ring, 0, 1,
 			       adev->nbio.funcs->get_hdp_flush_done_offset(adev),
@@ -429,16 +430,11 @@
 	struct amdgpu_ring *sdma[AMDGPU_MAX_SDMA_INSTANCES];
 	u32 doorbell_offset, doorbell;
 	u32 rb_cntl, ib_cntl;
-	int i, unset = 0;
+	int i;
 
 	for_each_inst(i, inst_mask) {
 		sdma[i] = &adev->sdma.instance[i].ring;
 
-		if ((adev->mman.buffer_funcs_ring == sdma[i]) && unset != 1) {
-			amdgpu_ttm_set_buffer_funcs_status(adev, false);
-			unset = 1;
-		}
-
 		rb_cntl = RREG32_SDMA(i, regSDMA_GFX_RB_CNTL);
 		rb_cntl = REG_SET_FIELD(rb_cntl, SDMA_GFX_RB_CNTL, RB_ENABLE, 0);
 		WREG32_SDMA(i, regSDMA_GFX_RB_CNTL, rb_cntl);
@@ -485,20 +481,10 @@
 static void sdma_v4_4_2_inst_page_stop(struct amdgpu_device *adev,
 				       uint32_t inst_mask)
 {
-	struct amdgpu_ring *sdma[AMDGPU_MAX_SDMA_INSTANCES];
 	u32 rb_cntl, ib_cntl;
 	int i;
-	bool unset = false;
 
 	for_each_inst(i, inst_mask) {
-		sdma[i] = &adev->sdma.instance[i].page;
-
-		if ((adev->mman.buffer_funcs_ring == sdma[i]) &&
-			(!unset)) {
-			amdgpu_ttm_set_buffer_funcs_status(adev, false);
-			unset = true;
-		}
-
 		rb_cntl = RREG32_SDMA(i, regSDMA_PAGE_RB_CNTL);
 		rb_cntl = REG_SET_FIELD(rb_cntl, SDMA_PAGE_RB_CNTL,
 					RB_ENABLE, 0);
@@ -911,10 +897,12 @@
 		/* set utc l1 enable flag always to 1 */
 		temp = RREG32_SDMA(i, regSDMA_CNTL);
 		temp = REG_SET_FIELD(temp, SDMA_CNTL, UTC_L1_ENABLE, 1);
-		/* enable context empty interrupt during initialization */
-		temp = REG_SET_FIELD(temp, SDMA_CNTL, CTXEMPTY_INT_ENABLE, 1);
-		WREG32_SDMA(i, regSDMA_CNTL, temp);
 
+		if (amdgpu_ip_version(adev, SDMA0_HWIP, 0) < IP_VERSION(4, 4, 5)) {
+			/* enable context empty interrupt during initialization */
+			temp = REG_SET_FIELD(temp, SDMA_CNTL, CTXEMPTY_INT_ENABLE, 1);
+			WREG32_SDMA(i, regSDMA_CNTL, temp);
+		}
 		if (!amdgpu_sriov_vf(adev)) {
 			if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
 				/* unhalt engine */
@@ -948,13 +936,7 @@
 			r = amdgpu_ring_test_helper(page);
 			if (r)
 				return r;
-
-			if (adev->mman.buffer_funcs_ring == page)
-				amdgpu_ttm_set_buffer_funcs_status(adev, true);
 		}
-
-		if (adev->mman.buffer_funcs_ring == ring)
-			amdgpu_ttm_set_buffer_funcs_status(adev, true);
 	}
 
 	return r;
@@ -1621,19 +1603,9 @@
 	u32 sdma_cntl;
 
 	sdma_cntl = RREG32_SDMA(type, regSDMA_CNTL);
-	switch (state) {
-	case AMDGPU_IRQ_STATE_DISABLE:
-		sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA_CNTL,
-					  DRAM_ECC_INT_ENABLE, 0);
-		WREG32_SDMA(type, regSDMA_CNTL, sdma_cntl);
-		break;
-	/* sdma ecc interrupt is enabled by default
-	 * driver doesn't need to do anything to
-	 * enable the interrupt */
-	case AMDGPU_IRQ_STATE_ENABLE:
-	default:
-		break;
-	}
+	sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA_CNTL, DRAM_ECC_INT_ENABLE,
+					state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);
+	WREG32_SDMA(type, regSDMA_CNTL, sdma_cntl);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c
@@ -188,6 +188,16 @@
 		DRM_DEBUG("calling WDOORBELL64(0x%08x, 0x%016llx)\n",
 				ring->doorbell_index, ring->wptr << 2);
 		WDOORBELL64(ring->doorbell_index, ring->wptr << 2);
+		if (amdgpu_ip_version(adev, SDMA0_HWIP, 0) == IP_VERSION(5, 2, 1)) {
+			/* SDMA seems to miss doorbells sometimes when powergating kicks in.
+			 * Updating the wptr directly will wake it. This is only safe because
+			 * we disallow gfxoff in begin_use() and then allow it again in end_use().
+			 */
+			WREG32(sdma_v5_2_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR),
+			       lower_32_bits(ring->wptr << 2));
+			WREG32(sdma_v5_2_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI),
+			       upper_32_bits(ring->wptr << 2));
+		}
 	} else {
 		DRM_DEBUG("Not using doorbell -- "
 				"mmSDMA%i_GFX_RB_WPTR == 0x%08x "
@@ -292,17 +302,21 @@
 	u32 ref_and_mask = 0;
 	const struct nbio_hdp_flush_reg *nbio_hf_reg = adev->nbio.hdp_flush_reg;
 
-	ref_and_mask = nbio_hf_reg->ref_and_mask_sdma0 << ring->me;
+	if (ring->me > 1) {
+		amdgpu_asic_flush_hdp(adev, ring);
+	} else {
+		ref_and_mask = nbio_hf_reg->ref_and_mask_sdma0 << ring->me;
 
-	amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) |
-			  SDMA_PKT_POLL_REGMEM_HEADER_HDP_FLUSH(1) |
-			  SDMA_PKT_POLL_REGMEM_HEADER_FUNC(3)); /* == */
-	amdgpu_ring_write(ring, (adev->nbio.funcs->get_hdp_flush_done_offset(adev)) << 2);
-	amdgpu_ring_write(ring, (adev->nbio.funcs->get_hdp_flush_req_offset(adev)) << 2);
-	amdgpu_ring_write(ring, ref_and_mask); /* reference */
-	amdgpu_ring_write(ring, ref_and_mask); /* mask */
-	amdgpu_ring_write(ring, SDMA_PKT_POLL_REGMEM_DW5_RETRY_COUNT(0xfff) |
-			  SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(10)); /* retry count, poll interval */
+		amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) |
+				  SDMA_PKT_POLL_REGMEM_HEADER_HDP_FLUSH(1) |
+				  SDMA_PKT_POLL_REGMEM_HEADER_FUNC(3)); /* == */
+		amdgpu_ring_write(ring, (adev->nbio.funcs->get_hdp_flush_done_offset(adev)) << 2);
+		amdgpu_ring_write(ring, (adev->nbio.funcs->get_hdp_flush_req_offset(adev)) << 2);
+		amdgpu_ring_write(ring, ref_and_mask); /* reference */
+		amdgpu_ring_write(ring, ref_and_mask); /* mask */
+		amdgpu_ring_write(ring, SDMA_PKT_POLL_REGMEM_DW5_RETRY_COUNT(0xfff) |
+				  SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(10)); /* retry count, poll interval */
+	}
 }
 
 /**
@@ -1654,6 +1668,10 @@
 	 * but it shouldn't hurt for other parts since
 	 * this GFXOFF will be disallowed anyway when SDMA is
 	 * active, this just makes it explicit.
+	 * sdma_v5_2_ring_set_wptr() takes advantage of this
+	 * to update the wptr because sometimes SDMA seems to miss
+	 * doorbells when entering PG.  If you remove this, update
+	 * sdma_v5_2_ring_set_wptr() as well!
 	 */
 	amdgpu_gfx_off_ctrl(adev, false);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c
@@ -92,7 +92,7 @@
 		adev->ip_blocks[i].status.hw = false;
 	}
 
-	return r;
+	return 0;
 }
 
 static int
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c
@@ -91,7 +91,7 @@
 		adev->ip_blocks[i].status.hw = false;
 	}
 
-	return r;
+	return 0;
 }
 
 static int
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/soc15.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/soc15.c
@@ -90,8 +90,8 @@
 /* Vega, Raven, Arcturus */
 static const struct amdgpu_video_codec_info vega_video_codecs_encode_array[] =
 {
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 4096, 0)},
 };
 
 static const struct amdgpu_video_codecs vega_video_codecs_encode =
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/soc15d.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/soc15d.h
@@ -76,6 +76,12 @@
 			 ((cond & 0xF) << 24) |				\
 			 ((type & 0xF) << 28))
 
+#define CP_PACKETJ_NOP		0x60000000
+#define CP_PACKETJ_GET_REG(x)  ((x) & 0x3FFFF)
+#define CP_PACKETJ_GET_RES(x)  (((x) >> 18) & 0x3F)
+#define CP_PACKETJ_GET_COND(x) (((x) >> 24) & 0xF)
+#define CP_PACKETJ_GET_TYPE(x) (((x) >> 28) & 0xF)
+
 /* Packet 3 types */
 #define	PACKET3_NOP					0x10
 #define	PACKET3_SET_BASE				0x11
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/soc21.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/soc21.c
@@ -49,13 +49,13 @@
 
 /* SOC21 */
 static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_encode_array_vcn0[] = {
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 0)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
 };
 
 static const struct amdgpu_video_codec_info vcn_4_0_0_video_codecs_encode_array_vcn1[] = {
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 0)},
 };
 
@@ -96,14 +96,14 @@
 
 /* SRIOV SOC21, not const since data is controlled by host */
 static struct amdgpu_video_codec_info sriov_vcn_4_0_0_video_codecs_encode_array_vcn0[] = {
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 0)},
 	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
 };
 
 static struct amdgpu_video_codec_info sriov_vcn_4_0_0_video_codecs_encode_array_vcn1[] = {
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
-	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 0)},
+	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 0)},
 };
 
 static struct amdgpu_video_codecs sriov_vcn_4_0_0_video_codecs_encode_vcn0 = {
@@ -450,10 +450,8 @@
 {
 	switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
 	case IP_VERSION(11, 0, 0):
-		return amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC);
 	case IP_VERSION(11, 0, 2):
 	case IP_VERSION(11, 0, 3):
-		return false;
 	default:
 		return true;
 	}
@@ -714,7 +712,10 @@
 			AMD_PG_SUPPORT_VCN |
 			AMD_PG_SUPPORT_JPEG |
 			AMD_PG_SUPPORT_GFX_PG;
-		adev->external_rev_id = adev->rev_id + 0x1;
+		if (adev->rev_id == 0)
+			adev->external_rev_id = 0x1;
+		else
+			adev->external_rev_id = adev->rev_id + 0x10;
 		break;
 	default:
 		/* FIXME: not supported yet */
@@ -832,10 +833,35 @@
 	return soc21_common_hw_fini(adev);
 }
 
+static bool soc21_need_reset_on_resume(struct amdgpu_device *adev)
+{
+	u32 sol_reg1, sol_reg2;
+
+	/* Will reset for the following suspend abort cases.
+	 * 1) Only reset dGPU side.
+	 * 2) S3 suspend got aborted and TOS is active.
+	 */
+	if (!(adev->flags & AMD_IS_APU) && adev->in_s3 &&
+	    !adev->suspend_complete) {
+		sol_reg1 = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81);
+		msleep(100);
+		sol_reg2 = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_81);
+
+		return (sol_reg1 != sol_reg2);
+	}
+
+	return false;
+}
+
 static int soc21_common_resume(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
+	if (soc21_need_reset_on_resume(adev)) {
+		dev_info(adev->dev, "S3 suspend aborted, resetting...");
+		soc21_asic_reset(adev);
+	}
+
 	return soc21_common_hw_init(adev);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/ta_ras_if.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/ta_ras_if.h
@@ -36,6 +36,9 @@
 	TA_RAS_COMMAND__ENABLE_FEATURES = 0,
 	TA_RAS_COMMAND__DISABLE_FEATURES,
 	TA_RAS_COMMAND__TRIGGER_ERROR,
+	TA_RAS_COMMAND__QUERY_BLOCK_INFO,
+	TA_RAS_COMMAND__QUERY_SUB_BLOCK_INFO,
+	TA_RAS_COMMAND__QUERY_ADDRESS,
 };
 
 enum ta_ras_status {
@@ -105,6 +108,11 @@
 	TA_RAS_ERROR__POISON			= 8,
 };
 
+enum ta_ras_address_type {
+	TA_RAS_MCA_TO_PA,
+	TA_RAS_PA_TO_MCA,
+};
+
 /* Input/output structures for RAS commands */
 /**********************************************************/
 
@@ -133,12 +141,38 @@
 	uint8_t channel_dis_num;
 };
 
+struct ta_ras_mca_addr {
+	uint64_t err_addr;
+	uint32_t ch_inst;
+	uint32_t umc_inst;
+	uint32_t node_inst;
+};
+
+struct ta_ras_phy_addr {
+	uint64_t pa;
+	uint32_t bank;
+	uint32_t channel_idx;
+};
+
+struct ta_ras_query_address_input {
+	enum ta_ras_address_type addr_type;
+	struct ta_ras_mca_addr ma;
+	struct ta_ras_phy_addr pa;
+};
+
 struct ta_ras_output_flags {
 	uint8_t ras_init_success_flag;
 	uint8_t err_inject_switch_disable_flag;
 	uint8_t reg_access_failure_flag;
 };
 
+struct ta_ras_query_address_output {
+	/* don't use the flags here */
+	struct ta_ras_output_flags flags;
+	struct ta_ras_mca_addr ma;
+	struct ta_ras_phy_addr pa;
+};
+
 /* Common input structure for RAS callbacks */
 /**********************************************************/
 union ta_ras_cmd_input {
@@ -146,12 +180,14 @@
 	struct ta_ras_enable_features_input	enable_features;
 	struct ta_ras_disable_features_input	disable_features;
 	struct ta_ras_trigger_error_input	trigger_error;
+	struct ta_ras_query_address_input	address;
 
 	uint32_t reserve_pad[256];
 };
 
 union ta_ras_cmd_output {
 	struct ta_ras_output_flags flags;
+	struct ta_ras_query_address_output address;
 
 	uint32_t reserve_pad[256];
 };
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/umsch_mm_v4_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/umsch_mm_v4_0.c
@@ -225,6 +225,8 @@
 
 	WREG32_SOC15(VCN, 0, regVCN_UMSCH_RB_SIZE, ring->ring_size);
 
+	ring->wptr = 0;
+
 	data = RREG32_SOC15(VCN, 0, regVCN_RB_ENABLE);
 	data &= ~(VCN_RB_ENABLE__AUDIO_RB_EN_MASK);
 	WREG32_SOC15(VCN, 0, regVCN_RB_ENABLE, data);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c
@@ -1289,7 +1289,7 @@
 					   struct amdgpu_job *job,
 					   struct amdgpu_ib *ib)
 {
-	struct amdgpu_ring *ring = to_amdgpu_ring(job->base.sched);
+	struct amdgpu_ring *ring = amdgpu_job_ring(job);
 	unsigned i;
 
 	/* No patching necessary for the first instance */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
@@ -77,6 +77,20 @@
 	return amdgpu_vcn_early_init(adev);
 }
 
+static int vcn_v4_0_3_fw_shared_init(struct amdgpu_device *adev, int inst_idx)
+{
+	struct amdgpu_vcn4_fw_shared *fw_shared;
+
+	fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
+	fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);
+	fw_shared->sq.is_enabled = 1;
+
+	if (amdgpu_vcnfw_log)
+		amdgpu_vcn_fwlog_init(&adev->vcn.inst[inst_idx]);
+
+	return 0;
+}
+
 /**
  * vcn_v4_0_3_sw_init - sw init for VCN block
  *
@@ -107,8 +121,6 @@
 		return r;
 
 	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
-		volatile struct amdgpu_vcn4_fw_shared *fw_shared;
-
 		vcn_inst = GET_INST(VCN, i);
 
 		ring = &adev->vcn.inst[i].ring_enc[0];
@@ -131,12 +143,7 @@
 		if (r)
 			return r;
 
-		fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
-		fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);
-		fw_shared->sq.is_enabled = true;
-
-		if (amdgpu_vcnfw_log)
-			amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
+		vcn_v4_0_3_fw_shared_init(adev, i);
 	}
 
 	if (amdgpu_sriov_vf(adev)) {
@@ -221,6 +228,8 @@
 		}
 	} else {
 		for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
+			struct amdgpu_vcn4_fw_shared *fw_shared;
+
 			vcn_inst = GET_INST(VCN, i);
 			ring = &adev->vcn.inst[i].ring_enc[0];
 
@@ -244,6 +253,11 @@
 					regVCN_RB1_DB_CTRL);
 			}
 
+			/* Re-init fw_shared when RAS fatal error occurred */
+			fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
+			if (!fw_shared->sq.is_enabled)
+				vcn_v4_0_3_fw_shared_init(adev, i);
+
 			r = amdgpu_ring_test_helper(ring);
 			if (r)
 				goto done;
@@ -882,6 +896,8 @@
 	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
 		vcn_inst = GET_INST(VCN, i);
 
+		vcn_v4_0_3_fw_shared_init(adev, vcn_inst);
+
 		memset(&header, 0, sizeof(struct mmsch_v4_0_3_init_header));
 		header.version = MMSCH_VERSION;
 		header.total_size = sizeof(struct mmsch_v4_0_3_init_header) >> 2;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c
@@ -1346,170 +1346,6 @@
 	}
 }
 
-static int vcn_v4_0_5_limit_sched(struct amdgpu_cs_parser *p,
-				struct amdgpu_job *job)
-{
-	struct drm_gpu_scheduler **scheds;
-
-	/* The create msg must be in the first IB submitted */
-	if (atomic_read(&job->base.entity->fence_seq))
-		return -EINVAL;
-
-	/* if VCN0 is harvested, we can't support AV1 */
-	if (p->adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0)
-		return -EINVAL;
-
-	scheds = p->adev->gpu_sched[AMDGPU_HW_IP_VCN_ENC]
-		[AMDGPU_RING_PRIO_0].sched;
-	drm_sched_entity_modify_sched(job->base.entity, scheds, 1);
-	return 0;
-}
-
-static int vcn_v4_0_5_dec_msg(struct amdgpu_cs_parser *p, struct amdgpu_job *job,
-			    uint64_t addr)
-{
-	struct ttm_operation_ctx ctx = { false, false };
-	struct amdgpu_bo_va_mapping *map;
-	uint32_t *msg, num_buffers;
-	struct amdgpu_bo *bo;
-	uint64_t start, end;
-	unsigned int i;
-	void *ptr;
-	int r;
-
-	addr &= AMDGPU_GMC_HOLE_MASK;
-	r = amdgpu_cs_find_mapping(p, addr, &bo, &map);
-	if (r) {
-		DRM_ERROR("Can't find BO for addr 0x%08llx\n", addr);
-		return r;
-	}
-
-	start = map->start * AMDGPU_GPU_PAGE_SIZE;
-	end = (map->last + 1) * AMDGPU_GPU_PAGE_SIZE;
-	if (addr & 0x7) {
-		DRM_ERROR("VCN messages must be 8 byte aligned!\n");
-		return -EINVAL;
-	}
-
-	bo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
-	amdgpu_bo_placement_from_domain(bo, bo->allowed_domains);
-	r = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
-	if (r) {
-		DRM_ERROR("Failed validating the VCN message BO (%d)!\n", r);
-		return r;
-	}
-
-	r = amdgpu_bo_kmap(bo, &ptr);
-	if (r) {
-		DRM_ERROR("Failed mapping the VCN message (%d)!\n", r);
-		return r;
-	}
-
-	msg = ptr + addr - start;
-
-	/* Check length */
-	if (msg[1] > end - addr) {
-		r = -EINVAL;
-		goto out;
-	}
-
-	if (msg[3] != RDECODE_MSG_CREATE)
-		goto out;
-
-	num_buffers = msg[2];
-	for (i = 0, msg = &msg[6]; i < num_buffers; ++i, msg += 4) {
-		uint32_t offset, size, *create;
-
-		if (msg[0] != RDECODE_MESSAGE_CREATE)
-			continue;
-
-		offset = msg[1];
-		size = msg[2];
-
-		if (offset + size > end) {
-			r = -EINVAL;
-			goto out;
-		}
-
-		create = ptr + addr + offset - start;
-
-		/* H264, HEVC and VP9 can run on any instance */
-		if (create[0] == 0x7 || create[0] == 0x10 || create[0] == 0x11)
-			continue;
-
-		r = vcn_v4_0_5_limit_sched(p, job);
-		if (r)
-			goto out;
-	}
-
-out:
-	amdgpu_bo_kunmap(bo);
-	return r;
-}
-
-#define RADEON_VCN_ENGINE_TYPE_ENCODE			(0x00000002)
-#define RADEON_VCN_ENGINE_TYPE_DECODE			(0x00000003)
-
-#define RADEON_VCN_ENGINE_INFO				(0x30000001)
-#define RADEON_VCN_ENGINE_INFO_MAX_OFFSET		16
-
-#define RENCODE_ENCODE_STANDARD_AV1			2
-#define RENCODE_IB_PARAM_SESSION_INIT			0x00000003
-#define RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET	64
-
-/* return the offset in ib if id is found, -1 otherwise
- * to speed up the searching we only search upto max_offset
- */
-static int vcn_v4_0_5_enc_find_ib_param(struct amdgpu_ib *ib, uint32_t id, int max_offset)
-{
-	int i;
-
-	for (i = 0; i < ib->length_dw && i < max_offset && ib->ptr[i] >= 8; i += ib->ptr[i]/4) {
-		if (ib->ptr[i + 1] == id)
-			return i;
-	}
-	return -1;
-}
-
-static int vcn_v4_0_5_ring_patch_cs_in_place(struct amdgpu_cs_parser *p,
-					   struct amdgpu_job *job,
-					   struct amdgpu_ib *ib)
-{
-	struct amdgpu_ring *ring = amdgpu_job_ring(job);
-	struct amdgpu_vcn_decode_buffer *decode_buffer;
-	uint64_t addr;
-	uint32_t val;
-	int idx;
-
-	/* The first instance can decode anything */
-	if (!ring->me)
-		return 0;
-
-	/* RADEON_VCN_ENGINE_INFO is at the top of ib block */
-	idx = vcn_v4_0_5_enc_find_ib_param(ib, RADEON_VCN_ENGINE_INFO,
-			RADEON_VCN_ENGINE_INFO_MAX_OFFSET);
-	if (idx < 0) /* engine info is missing */
-		return 0;
-
-	val = amdgpu_ib_get_value(ib, idx + 2); /* RADEON_VCN_ENGINE_TYPE */
-	if (val == RADEON_VCN_ENGINE_TYPE_DECODE) {
-		decode_buffer = (struct amdgpu_vcn_decode_buffer *)&ib->ptr[idx + 6];
-
-		if (!(decode_buffer->valid_buf_flag  & 0x1))
-			return 0;
-
-		addr = ((u64)decode_buffer->msg_buffer_address_hi) << 32 |
-			decode_buffer->msg_buffer_address_lo;
-		return vcn_v4_0_5_dec_msg(p, job, addr);
-	} else if (val == RADEON_VCN_ENGINE_TYPE_ENCODE) {
-		idx = vcn_v4_0_5_enc_find_ib_param(ib, RENCODE_IB_PARAM_SESSION_INIT,
-			RENCODE_IB_PARAM_SESSION_INIT_MAX_OFFSET);
-		if (idx >= 0 && ib->ptr[idx + 2] == RENCODE_ENCODE_STANDARD_AV1)
-			return vcn_v4_0_5_limit_sched(p, job);
-	}
-	return 0;
-}
-
 static const struct amdgpu_ring_funcs vcn_v4_0_5_unified_ring_vm_funcs = {
 	.type = AMDGPU_RING_TYPE_VCN_ENC,
 	.align_mask = 0x3f,
@@ -1517,7 +1353,6 @@
 	.get_rptr = vcn_v4_0_5_unified_ring_get_rptr,
 	.get_wptr = vcn_v4_0_5_unified_ring_get_wptr,
 	.set_wptr = vcn_v4_0_5_unified_ring_set_wptr,
-	.patch_cs_in_place = vcn_v4_0_5_ring_patch_cs_in_place,
 	.emit_frame_size =
 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/vega20_ih.c
@@ -114,6 +114,33 @@
 	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0));
 	tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_GPU_TS_ENABLE, 1);
 
+	if (enable) {
+		/* Unset the CLEAR_OVERFLOW bit to make sure the next step
+		 * is switching the bit from 0 to 1
+		 */
+		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
+		if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
+			if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
+				return -ETIMEDOUT;
+		} else {
+			WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
+		}
+
+		/* Clear RB_OVERFLOW bit */
+		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
+		if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
+			if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
+				return -ETIMEDOUT;
+		} else {
+			WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
+		}
+
+		/* Unset the CLEAR_OVERFLOW bit immediately so new overflows
+		 * can be detected.
+		 */
+		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
+	}
+
 	/* enable_intr field is only valid in ring0 */
 	if (ih == &adev->irq.ih)
 		tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdgpu/vi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdgpu/vi.c
@@ -136,15 +136,15 @@
 	{
 		.codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC,
 		.max_width = 4096,
-		.max_height = 2304,
-		.max_pixels_per_frame = 4096 * 2304,
+		.max_height = 4096,
+		.max_pixels_per_frame = 4096 * 4096,
 		.max_level = 0,
 	},
 	{
 		.codec_type = AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC,
 		.max_width = 4096,
-		.max_height = 2304,
-		.max_pixels_per_frame = 4096 * 2304,
+		.max_height = 4096,
+		.max_pixels_per_frame = 4096 * 4096,
 		.max_level = 0,
 	},
 };
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -417,7 +417,7 @@
 
 err_create_queue:
 	if (wptr_bo)
-		amdgpu_amdkfd_free_gtt_mem(dev->adev, wptr_bo);
+		amdgpu_amdkfd_free_gtt_mem(dev->adev, (void **)&wptr_bo);
 err_wptr_map_gart:
 err_bind_process:
 err_pdd:
@@ -778,8 +778,8 @@
 	 * nodes, but not more than args->num_of_nodes as that is
 	 * the amount of memory allocated by user
 	 */
-	pa = kzalloc((sizeof(struct kfd_process_device_apertures) *
-				args->num_of_nodes), GFP_KERNEL);
+	pa = kcalloc(args->num_of_nodes, sizeof(struct kfd_process_device_apertures),
+		     GFP_KERNEL);
 	if (!pa)
 		return -ENOMEM;
 
@@ -1138,7 +1138,7 @@
 			goto err_unlock;
 		}
 		offset = dev->adev->rmmio_remap.bus_addr;
-		if (!offset) {
+		if (!offset || (PAGE_SIZE > 4096)) {
 			err = -ENOMEM;
 			goto err_unlock;
 		}
@@ -1164,7 +1164,7 @@
 
 		if (flags & KFD_IOC_ALLOC_MEM_FLAGS_AQL_QUEUE_MEM)
 			size >>= 1;
-		WRITE_ONCE(pdd->vram_usage, pdd->vram_usage + PAGE_ALIGN(size));
+		atomic64_add(PAGE_ALIGN(size), &pdd->vram_usage);
 	}
 
 	mutex_unlock(&p->mutex);
@@ -1235,7 +1235,7 @@
 		kfd_process_device_remove_obj_handle(
 			pdd, GET_IDR_HANDLE(args->handle));
 
-	WRITE_ONCE(pdd->vram_usage, pdd->vram_usage - size);
+	atomic64_sub(size, &pdd->vram_usage);
 
 err_unlock:
 err_pdd:
@@ -1522,7 +1522,7 @@
 
 	/* Find a KFD GPU device that supports the get_dmabuf_info query */
 	for (i = 0; kfd_topology_enum_kfd_devices(i, &dev) == 0; i++)
-		if (dev)
+		if (dev && !kfd_devcgroup_check_permission(dev))
 			break;
 	if (!dev)
 		return -EINVAL;
@@ -1544,7 +1544,7 @@
 	if (xcp_id >= 0)
 		args->gpu_id = dmabuf_adev->kfd.dev->nodes[xcp_id]->id;
 	else
-		args->gpu_id = dmabuf_adev->kfd.dev->nodes[0]->id;
+		args->gpu_id = dev->id;
 	args->flags = flags;
 
 	/* Copy metadata buffer to user mode */
@@ -2306,7 +2306,7 @@
 			return -EINVAL;
 		}
 		offset = pdd->dev->adev->rmmio_remap.bus_addr;
-		if (!offset) {
+		if (!offset || (PAGE_SIZE > 4096)) {
 			pr_err("amdgpu_amdkfd_get_mmio_remap_phys_addr failed\n");
 			return -ENOMEM;
 		}
@@ -2345,7 +2345,7 @@
 	} else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_VRAM) {
 		bo_bucket->restored_offset = offset;
 		/* Update the VRAM usage count */
-		WRITE_ONCE(pdd->vram_usage, pdd->vram_usage + bo_bucket->size);
+		atomic64_add(bo_bucket->size, &pdd->vram_usage);
 	}
 	return 0;
 }
@@ -3347,6 +3347,9 @@
 	if (vma->vm_end - vma->vm_start != PAGE_SIZE)
 		return -EINVAL;
 
+	if (PAGE_SIZE > 4096)
+		return -EINVAL;
+
 	address = dev->adev->rmmio_remap.bus_addr;
 
 	vm_flags_set(vma, VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE |
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_crat.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_crat.h
@@ -42,8 +42,6 @@
 #define CRAT_OEMTABLEID_LENGTH	8
 #define CRAT_RESERVED_LENGTH	6
 
-#define CRAT_OEMID_64BIT_MASK ((1ULL << (CRAT_OEMID_LENGTH * 8)) - 1)
-
 /* Compute Unit flags */
 #define COMPUTE_UNIT_CPU	(1 << 0)  /* Create Virtual CRAT for CPU */
 #define COMPUTE_UNIT_GPU	(1 << 1)  /* Create Virtual CRAT for GPU */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_debug.c
@@ -103,7 +103,8 @@
 			struct kfd_process,
 			debug_event_workarea);
 
-	kernel_write(process->dbg_ev_file, &write_data, 1, &pos);
+	if (process->debug_trap_enabled && process->dbg_ev_file)
+		kernel_write(process->dbg_ev_file, &write_data, 1, &pos);
 }
 
 /* update process/device/queue exception status, write to descriptor
@@ -348,10 +349,27 @@
 {
 	uint32_t spi_dbg_cntl = pdd->spi_dbg_override | pdd->spi_dbg_launch_mode;
 	uint32_t flags = pdd->process->dbg_flags;
+	struct amdgpu_device *adev = pdd->dev->adev;
+	int r;
 
 	if (!kfd_dbg_is_per_vmid_supported(pdd->dev))
 		return 0;
 
+	if (!pdd->proc_ctx_cpu_ptr) {
+			r = amdgpu_amdkfd_alloc_gtt_mem(adev,
+				AMDGPU_MES_PROC_CTX_SIZE,
+				&pdd->proc_ctx_bo,
+				&pdd->proc_ctx_gpu_addr,
+				&pdd->proc_ctx_cpu_ptr,
+				false);
+		if (r) {
+			dev_err(adev->dev,
+			"failed to allocate process context bo\n");
+			return r;
+		}
+		memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE);
+	}
+
 	return amdgpu_mes_set_shader_debugger(pdd->dev->adev, pdd->proc_ctx_gpu_addr, spi_dbg_cntl,
 						pdd->watch_points, flags, sq_trap_en);
 }
@@ -645,6 +663,7 @@
 	else if (target->runtime_info.runtime_state != DEBUG_RUNTIME_STATE_DISABLED)
 		target->runtime_info.runtime_state = DEBUG_RUNTIME_STATE_ENABLED;
 
+	cancel_work_sync(&target->debug_event_workarea);
 	fput(target->dbg_ev_file);
 	target->dbg_ev_file = NULL;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_device.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_device.c
@@ -405,15 +405,8 @@
 			f2g = &gfx_v11_kfd2kgd;
 			break;
 		case IP_VERSION(11, 0, 3):
-			if ((adev->pdev->device == 0x7460 &&
-			     adev->pdev->revision == 0x00) ||
-			    (adev->pdev->device == 0x7461 &&
-			     adev->pdev->revision == 0x00))
-				/* Note: Compiler version is 11.0.5 while HW version is 11.0.3 */
-				gfx_target_version = 110005;
-			else
-				/* Note: Compiler version is 11.0.1 while HW version is 11.0.3 */
-				gfx_target_version = 110001;
+			/* Note: Compiler version is 11.0.1 while HW version is 11.0.3 */
+			gfx_target_version = 110001;
 			f2g = &gfx_v11_kfd2kgd;
 			break;
 		case IP_VERSION(11, 5, 0):
@@ -586,6 +579,14 @@
 	struct kfd_node *knode;
 	unsigned int i;
 
+	/*
+	 * flush_work ensures that there are no outstanding
+	 * work-queue items that will access interrupt_ring. New work items
+	 * can't be created because we stopped interrupt handling above.
+	 */
+	flush_workqueue(kfd->ih_wq);
+	destroy_workqueue(kfd->ih_wq);
+
 	for (i = 0; i < num_nodes; i++) {
 		knode = kfd->nodes[i];
 		device_queue_manager_uninit(knode->dqm);
@@ -854,7 +855,7 @@
 kfd_doorbell_error:
 	kfd_gtt_sa_fini(kfd);
 kfd_gtt_sa_init_error:
-	amdgpu_amdkfd_free_gtt_mem(kfd->adev, kfd->gtt_mem);
+	amdgpu_amdkfd_free_gtt_mem(kfd->adev, &kfd->gtt_mem);
 alloc_gtt_mem_failure:
 	dev_err(kfd_device,
 		"device %x:%x NOT added due to errors\n",
@@ -872,7 +873,7 @@
 		kfd_doorbell_fini(kfd);
 		ida_destroy(&kfd->doorbell_ida);
 		kfd_gtt_sa_fini(kfd);
-		amdgpu_amdkfd_free_gtt_mem(kfd->adev, kfd->gtt_mem);
+		amdgpu_amdkfd_free_gtt_mem(kfd->adev, &kfd->gtt_mem);
 	}
 
 	kfree(kfd);
@@ -944,7 +945,6 @@
 {
 	struct kfd_node *node;
 	int i;
-	int count;
 
 	if (!kfd->init_complete)
 		return;
@@ -952,12 +952,10 @@
 	/* for runtime suspend, skip locking kfd */
 	if (!run_pm) {
 		mutex_lock(&kfd_processes_mutex);
-		count = ++kfd_locked;
-		mutex_unlock(&kfd_processes_mutex);
-
 		/* For first KFD device suspend all the KFD processes */
-		if (count == 1)
+		if (++kfd_locked == 1)
 			kfd_suspend_all_processes();
+		mutex_unlock(&kfd_processes_mutex);
 	}
 
 	for (i = 0; i < kfd->num_nodes; i++) {
@@ -968,7 +966,7 @@
 
 int kgd2kfd_resume(struct kfd_dev *kfd, bool run_pm)
 {
-	int ret, count, i;
+	int ret, i;
 
 	if (!kfd->init_complete)
 		return 0;
@@ -982,12 +980,10 @@
 	/* for runtime resume, skip unlocking kfd */
 	if (!run_pm) {
 		mutex_lock(&kfd_processes_mutex);
-		count = --kfd_locked;
-		mutex_unlock(&kfd_processes_mutex);
-
-		WARN_ONCE(count < 0, "KFD suspend / resume ref. error");
-		if (count == 0)
+		if (--kfd_locked == 0)
 			ret = kfd_resume_all_processes();
+		WARN_ONCE(kfd_locked < 0, "KFD suspend / resume ref. error");
+		mutex_unlock(&kfd_processes_mutex);
 	}
 
 	return ret;
@@ -1006,21 +1002,6 @@
 	return err;
 }
 
-static inline void kfd_queue_work(struct workqueue_struct *wq,
-				  struct work_struct *work)
-{
-	int cpu, new_cpu;
-
-	cpu = new_cpu = smp_processor_id();
-	do {
-		new_cpu = cpumask_next(new_cpu, cpu_online_mask) % nr_cpu_ids;
-		if (cpu_to_node(new_cpu) == numa_node_id())
-			break;
-	} while (cpu != new_cpu);
-
-	queue_work_on(new_cpu, wq, work);
-}
-
 /* This is called directly from KGD at ISR. */
 void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry)
 {
@@ -1046,7 +1027,7 @@
 			    	patched_ihre, &is_patched)
 		    && enqueue_ih_ring_entry(node,
 			    	is_patched ? patched_ihre : ih_ring_entry)) {
-			kfd_queue_work(node->ih_wq, &node->interrupt_work);
+			queue_work(node->kfd->ih_wq, &node->interrupt_work);
 			spin_unlock_irqrestore(&node->interrupt_lock, flags);
 			return;
 		}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -197,6 +197,21 @@
 	if (dqm->is_hws_hang)
 		return -EIO;
 
+	if (!pdd->proc_ctx_cpu_ptr) {
+		r = amdgpu_amdkfd_alloc_gtt_mem(adev,
+				AMDGPU_MES_PROC_CTX_SIZE,
+				&pdd->proc_ctx_bo,
+				&pdd->proc_ctx_gpu_addr,
+				&pdd->proc_ctx_cpu_ptr,
+				false);
+		if (r) {
+			dev_err(adev->dev,
+				"failed to allocate process context bo\n");
+			return r;
+		}
+		memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE);
+	}
+
 	memset(&queue_input, 0x0, sizeof(struct mes_add_queue_input));
 	queue_input.process_id = qpd->pqm->process->pasid;
 	queue_input.page_table_base_addr =  qpd->page_table_base;
@@ -1997,6 +2012,7 @@
 		dev_err(dev, "HIQ MQD's queue_doorbell_id0 is not 0, Queue preemption time out\n");
 		while (halt_if_hws_hang)
 			schedule();
+		kfd_hws_hang(dqm);
 		return -ETIME;
 	}
 
@@ -2629,7 +2645,7 @@
 {
 	WARN(!mqd, "No hiq sdma mqd trunk to free");
 
-	amdgpu_amdkfd_free_gtt_mem(dev->adev, mqd->gtt_mem);
+	amdgpu_amdkfd_free_gtt_mem(dev->adev, &mqd->gtt_mem);
 }
 
 void device_queue_manager_uninit(struct device_queue_manager *dqm)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c
@@ -373,7 +373,8 @@
 
 		pdd = kfd_create_process_device_data(dev, process);
 		if (!pdd) {
-			pr_err("Failed to create process device data\n");
+			dev_err(dev->adev->dev,
+				"Failed to create process device data\n");
 			return -ENOMEM;
 		}
 		/*
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v10.c
@@ -336,7 +336,8 @@
 				break;
 			}
 			kfd_signal_event_interrupt(pasid, context_id0 & 0x7fffff, 23);
-		} else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE) {
+		} else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE &&
+			   KFD_DBG_EC_TYPE_IS_PACKET(KFD_DEBUG_CP_BAD_OP_ECODE(context_id0))) {
 			kfd_set_dbg_ev_from_interrupt(dev, pasid,
 				KFD_DEBUG_DOORBELL_ID(context_id0),
 				KFD_EC_MASK(KFD_DEBUG_CP_BAD_OP_ECODE(context_id0)),
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v11.c
@@ -325,7 +325,8 @@
 		/* CP */
 		if (source_id == SOC15_INTSRC_CP_END_OF_PIPE)
 			kfd_signal_event_interrupt(pasid, context_id0, 32);
-		else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE)
+		else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE &&
+			 KFD_DBG_EC_TYPE_IS_PACKET(KFD_CTXID0_CP_BAD_OP_ECODE(context_id0)))
 			kfd_set_dbg_ev_from_interrupt(dev, pasid,
 				KFD_CTXID0_DOORBELL_ID(context_id0),
 				KFD_EC_MASK(KFD_CTXID0_CP_BAD_OP_ECODE(context_id0)),
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_int_process_v9.c
@@ -385,7 +385,8 @@
 				break;
 			}
 			kfd_signal_event_interrupt(pasid, sq_int_data, 24);
-		} else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE) {
+		} else if (source_id == SOC15_INTSRC_CP_BAD_OPCODE &&
+			   KFD_DBG_EC_TYPE_IS_PACKET(KFD_DEBUG_CP_BAD_OP_ECODE(context_id0))) {
 			kfd_set_dbg_ev_from_interrupt(dev, pasid,
 				KFD_DEBUG_DOORBELL_ID(context_id0),
 				KFD_EC_MASK(KFD_DEBUG_CP_BAD_OP_ECODE(context_id0)),
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c
@@ -62,11 +62,14 @@
 		return r;
 	}
 
-	node->ih_wq = alloc_workqueue("KFD IH", WQ_HIGHPRI, 1);
-	if (unlikely(!node->ih_wq)) {
-		kfifo_free(&node->ih_fifo);
-		dev_err(node->adev->dev, "Failed to allocate KFD IH workqueue\n");
-		return -ENOMEM;
+	if (!node->kfd->ih_wq) {
+		node->kfd->ih_wq = alloc_workqueue("KFD IH", WQ_HIGHPRI | WQ_UNBOUND,
+						   node->kfd->num_nodes);
+		if (unlikely(!node->kfd->ih_wq)) {
+			kfifo_free(&node->ih_fifo);
+			dev_err(node->adev->dev, "Failed to allocate KFD IH workqueue\n");
+			return -ENOMEM;
+		}
 	}
 	spin_lock_init(&node->interrupt_lock);
 
@@ -96,14 +99,6 @@
 	spin_lock_irqsave(&node->interrupt_lock, flags);
 	node->interrupts_active = false;
 	spin_unlock_irqrestore(&node->interrupt_lock, flags);
-
-	/*
-	 * flush_work ensures that there are no outstanding
-	 * work-queue items that will access interrupt_ring. New work items
-	 * can't be created because we stopped interrupt handling above.
-	 */
-	flush_workqueue(node->ih_wq);
-
 	kfifo_free(&node->ih_fifo);
 }
 
@@ -160,7 +155,7 @@
 			/* If we spent more than a second processing signals,
 			 * reschedule the worker to avoid soft-lockup warnings
 			 */
-			queue_work(dev->ih_wq, &dev->interrupt_work);
+			queue_work(dev->kfd->ih_wq, &dev->interrupt_work);
 			break;
 		}
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c
@@ -68,7 +68,7 @@
 		kq->mqd_mgr = dev->dqm->mqd_mgrs[KFD_MQD_TYPE_HIQ];
 		break;
 	default:
-		pr_err("Invalid queue type %d\n", type);
+		dev_err(dev->adev->dev, "Invalid queue type %d\n", type);
 		return false;
 	}
 
@@ -78,13 +78,14 @@
 	prop.doorbell_ptr = kfd_get_kernel_doorbell(dev->kfd, &prop.doorbell_off);
 
 	if (!prop.doorbell_ptr) {
-		pr_err("Failed to initialize doorbell");
+		dev_err(dev->adev->dev, "Failed to initialize doorbell");
 		goto err_get_kernel_doorbell;
 	}
 
 	retval = kfd_gtt_sa_allocate(dev, queue_size, &kq->pq);
 	if (retval != 0) {
-		pr_err("Failed to init pq queues size %d\n", queue_size);
+		dev_err(dev->adev->dev, "Failed to init pq queues size %d\n",
+			queue_size);
 		goto err_pq_allocate_vidmem;
 	}
 
@@ -123,7 +124,7 @@
 
 	memset(kq->pq_kernel_addr, 0, queue_size);
 	memset(kq->rptr_kernel, 0, sizeof(*kq->rptr_kernel));
-	memset(kq->wptr_kernel, 0, sizeof(*kq->wptr_kernel));
+	memset(kq->wptr_kernel, 0, dev->kfd->device_info.doorbell_size);
 
 	prop.queue_size = queue_size;
 	prop.is_interop = false;
@@ -332,7 +333,7 @@
 	if (kq_initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE))
 		return kq;
 
-	pr_err("Failed to init kernel queue\n");
+	dev_err(dev->adev->dev, "Failed to init kernel queue\n");
 
 	kfree(kq);
 	return NULL;
@@ -351,26 +352,26 @@
 	uint32_t *buffer, i;
 	int retval;
 
-	pr_err("Starting kernel queue test\n");
+	dev_err(dev->adev->dev, "Starting kernel queue test\n");
 
 	kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ);
 	if (unlikely(!kq)) {
-		pr_err("  Failed to initialize HIQ\n");
-		pr_err("Kernel queue test failed\n");
+		dev_err(dev->adev->dev, "  Failed to initialize HIQ\n");
+		dev_err(dev->adev->dev, "Kernel queue test failed\n");
 		return;
 	}
 
 	retval = kq_acquire_packet_buffer(kq, 5, &buffer);
 	if (unlikely(retval != 0)) {
-		pr_err("  Failed to acquire packet buffer\n");
-		pr_err("Kernel queue test failed\n");
+		dev_err(dev->adev->dev, "  Failed to acquire packet buffer\n");
+		dev_err(dev->adev->dev, "Kernel queue test failed\n");
 		return;
 	}
 	for (i = 0; i < 5; i++)
 		buffer[i] = kq->nop_packet;
 	kq_submit_packet(kq);
 
-	pr_err("Ending kernel queue test\n");
+	dev_err(dev->adev->dev, "Ending kernel queue test\n");
 }
 
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
@@ -306,7 +306,7 @@
 		spage = migrate_pfn_to_page(migrate->src[i]);
 		if (spage && !is_zone_device_page(spage)) {
 			src[i] = dma_map_page(dev, spage, 0, PAGE_SIZE,
-					      DMA_TO_DEVICE);
+					      DMA_BIDIRECTIONAL);
 			r = dma_mapping_error(dev, src[i]);
 			if (r) {
 				dev_err(dev, "%s: fail %d dma_map_page\n",
@@ -509,10 +509,19 @@
 	start = start_mgr << PAGE_SHIFT;
 	end = (last_mgr + 1) << PAGE_SHIFT;
 
+	r = amdgpu_amdkfd_reserve_mem_limit(node->adev,
+					prange->npages * PAGE_SIZE,
+					KFD_IOC_ALLOC_MEM_FLAGS_VRAM,
+					node->xcp ? node->xcp->id : 0);
+	if (r) {
+		dev_dbg(node->adev->dev, "failed to reserve VRAM, r: %ld\n", r);
+		return -ENOSPC;
+	}
+
 	r = svm_range_vram_node_new(node, prange, true);
 	if (r) {
 		dev_dbg(node->adev->dev, "fail %ld to alloc vram\n", r);
-		return r;
+		goto out;
 	}
 	ttm_res_offset = (start_mgr - prange->start + prange->offset) << PAGE_SHIFT;
 
@@ -545,6 +554,11 @@
 		svm_range_vram_node_free(prange);
 	}
 
+out:
+	amdgpu_amdkfd_unreserve_mem_limit(node->adev,
+					prange->npages * PAGE_SIZE,
+					KFD_IOC_ALLOC_MEM_FLAGS_VRAM,
+					node->xcp ? node->xcp->id : 0);
 	return r < 0 ? r : 0;
 }
 
@@ -616,7 +630,7 @@
 			goto out_oom;
 		}
 
-		dst[i] = dma_map_page(dev, dpage, 0, PAGE_SIZE, DMA_FROM_DEVICE);
+		dst[i] = dma_map_page(dev, dpage, 0, PAGE_SIZE, DMA_BIDIRECTIONAL);
 		r = dma_mapping_error(dev, dst[i]);
 		if (r) {
 			dev_err(adev->dev, "%s: fail %d dma_map_page\n", __func__, r);
@@ -1009,7 +1023,7 @@
 	if (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(9, 0, 1))
 		return -EINVAL;
 
-	if (adev->gmc.is_app_apu)
+	if (adev->gmc.is_app_apu || adev->flags & AMD_IS_APU)
 		return 0;
 
 	pgmap = &kfddev->pgmap;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c
@@ -118,12 +118,14 @@
 	 * attention grabbing.
 	 */
 	if (gfx_info->max_shader_engines > KFD_MAX_NUM_SE) {
-		pr_err("Exceeded KFD_MAX_NUM_SE, chip reports %d\n",
-		       gfx_info->max_shader_engines);
+		dev_err(mm->dev->adev->dev,
+			"Exceeded KFD_MAX_NUM_SE, chip reports %d\n",
+			gfx_info->max_shader_engines);
 		return;
 	}
 	if (gfx_info->max_sh_per_se > KFD_MAX_NUM_SH_PER_SE) {
-		pr_err("Exceeded KFD_MAX_NUM_SH, chip reports %d\n",
+		dev_err(mm->dev->adev->dev,
+			"Exceeded KFD_MAX_NUM_SH, chip reports %d\n",
 			gfx_info->max_sh_per_se * gfx_info->max_shader_engines);
 		return;
 	}
@@ -223,7 +225,7 @@
 	      struct kfd_mem_obj *mqd_mem_obj)
 {
 	if (mqd_mem_obj->gtt_mem) {
-		amdgpu_amdkfd_free_gtt_mem(mm->dev->adev, mqd_mem_obj->gtt_mem);
+		amdgpu_amdkfd_free_gtt_mem(mm->dev->adev, &mqd_mem_obj->gtt_mem);
 		kfree(mqd_mem_obj);
 	} else {
 		kfd_gtt_sa_free(mm->dev, mqd_mem_obj);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
@@ -695,7 +695,7 @@
 		m = get_mqd(mqd + size * xcc);
 		update_mqd(mm, m, q, minfo);
 
-		update_cu_mask(mm, mqd, minfo, xcc);
+		update_cu_mask(mm, m, minfo, xcc);
 
 		if (q->format == KFD_QUEUE_FORMAT_AQL) {
 			switch (xcc) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c
@@ -45,7 +45,8 @@
 	unsigned int process_count, queue_count, compute_queue_count, gws_queue_count;
 	unsigned int map_queue_size;
 	unsigned int max_proc_per_quantum = 1;
-	struct kfd_node *dev = pm->dqm->dev;
+	struct kfd_node *node = pm->dqm->dev;
+	struct device *dev = node->adev->dev;
 
 	process_count = pm->dqm->processes_count;
 	queue_count = pm->dqm->active_queue_count;
@@ -59,14 +60,14 @@
 	 */
 	*over_subscription = false;
 
-	if (dev->max_proc_per_quantum > 1)
-		max_proc_per_quantum = dev->max_proc_per_quantum;
+	if (node->max_proc_per_quantum > 1)
+		max_proc_per_quantum = node->max_proc_per_quantum;
 
 	if ((process_count > max_proc_per_quantum) ||
 	    compute_queue_count > get_cp_queues_num(pm->dqm) ||
 	    gws_queue_count > 1) {
 		*over_subscription = true;
-		pr_debug("Over subscribed runlist\n");
+		dev_dbg(dev, "Over subscribed runlist\n");
 	}
 
 	map_queue_size = pm->pmf->map_queues_size;
@@ -81,7 +82,7 @@
 	if (*over_subscription)
 		*rlib_size += pm->pmf->runlist_size;
 
-	pr_debug("runlist ib size %d\n", *rlib_size);
+	dev_dbg(dev, "runlist ib size %d\n", *rlib_size);
 }
 
 static int pm_allocate_runlist_ib(struct packet_manager *pm,
@@ -90,6 +91,8 @@
 				unsigned int *rl_buffer_size,
 				bool *is_over_subscription)
 {
+	struct kfd_node *node = pm->dqm->dev;
+	struct device *dev = node->adev->dev;
 	int retval;
 
 	if (WARN_ON(pm->allocated))
@@ -99,11 +102,10 @@
 
 	mutex_lock(&pm->lock);
 
-	retval = kfd_gtt_sa_allocate(pm->dqm->dev, *rl_buffer_size,
-					&pm->ib_buffer_obj);
+	retval = kfd_gtt_sa_allocate(node, *rl_buffer_size, &pm->ib_buffer_obj);
 
 	if (retval) {
-		pr_err("Failed to allocate runlist IB\n");
+		dev_err(dev, "Failed to allocate runlist IB\n");
 		goto out;
 	}
 
@@ -125,6 +127,8 @@
 {
 	unsigned int alloc_size_bytes;
 	unsigned int *rl_buffer, rl_wptr, i;
+	struct kfd_node *node = pm->dqm->dev;
+	struct device *dev = node->adev->dev;
 	int retval, processes_mapped;
 	struct device_process_node *cur;
 	struct qcm_process_device *qpd;
@@ -142,7 +146,7 @@
 	*rl_size_bytes = alloc_size_bytes;
 	pm->ib_size_bytes = alloc_size_bytes;
 
-	pr_debug("Building runlist ib process count: %d queues count %d\n",
+	dev_dbg(dev, "Building runlist ib process count: %d queues count %d\n",
 		pm->dqm->processes_count, pm->dqm->active_queue_count);
 
 	/* build the run list ib packet */
@@ -150,7 +154,7 @@
 		qpd = cur->qpd;
 		/* build map process packet */
 		if (processes_mapped >= pm->dqm->processes_count) {
-			pr_debug("Not enough space left in runlist IB\n");
+			dev_dbg(dev, "Not enough space left in runlist IB\n");
 			pm_release_ib(pm);
 			return -ENOMEM;
 		}
@@ -167,7 +171,8 @@
 			if (!kq->queue->properties.is_active)
 				continue;
 
-			pr_debug("static_queue, mapping kernel q %d, is debug status %d\n",
+			dev_dbg(dev,
+				"static_queue, mapping kernel q %d, is debug status %d\n",
 				kq->queue->queue, qpd->is_debug);
 
 			retval = pm->pmf->map_queues(pm,
@@ -186,7 +191,8 @@
 			if (!q->properties.is_active)
 				continue;
 
-			pr_debug("static_queue, mapping user queue %d, is debug status %d\n",
+			dev_dbg(dev,
+				"static_queue, mapping user queue %d, is debug status %d\n",
 				q->queue, qpd->is_debug);
 
 			retval = pm->pmf->map_queues(pm,
@@ -203,11 +209,13 @@
 		}
 	}
 
-	pr_debug("Finished map process and queues to runlist\n");
+	dev_dbg(dev, "Finished map process and queues to runlist\n");
 
 	if (is_over_subscription) {
 		if (!pm->is_over_subscription)
-			pr_warn("Runlist is getting oversubscribed. Expect reduced ROCm performance.\n");
+			dev_warn(
+				dev,
+				"Runlist is getting oversubscribed. Expect reduced ROCm performance.\n");
 		retval = pm->pmf->runlist(pm, &rl_buffer[rl_wptr],
 					*rl_gpu_addr,
 					alloc_size_bytes / sizeof(uint32_t),
@@ -272,6 +280,8 @@
 int pm_send_set_resources(struct packet_manager *pm,
 				struct scheduling_resources *res)
 {
+	struct kfd_node *node = pm->dqm->dev;
+	struct device *dev = node->adev->dev;
 	uint32_t *buffer, size;
 	int retval = 0;
 
@@ -281,7 +291,7 @@
 					size / sizeof(uint32_t),
 					(unsigned int **)&buffer);
 	if (!buffer) {
-		pr_err("Failed to allocate buffer on kernel queue\n");
+		dev_err(dev, "Failed to allocate buffer on kernel queue\n");
 		retval = -ENOMEM;
 		goto out;
 	}
@@ -343,6 +353,8 @@
 int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
 			uint64_t fence_value)
 {
+	struct kfd_node *node = pm->dqm->dev;
+	struct device *dev = node->adev->dev;
 	uint32_t *buffer, size;
 	int retval = 0;
 
@@ -354,7 +366,7 @@
 	kq_acquire_packet_buffer(pm->priv_queue,
 			size / sizeof(uint32_t), (unsigned int **)&buffer);
 	if (!buffer) {
-		pr_err("Failed to allocate buffer on kernel queue\n");
+		dev_err(dev, "Failed to allocate buffer on kernel queue\n");
 		retval = -ENOMEM;
 		goto out;
 	}
@@ -372,6 +384,8 @@
 
 int pm_update_grace_period(struct packet_manager *pm, uint32_t grace_period)
 {
+	struct kfd_node *node = pm->dqm->dev;
+	struct device *dev = node->adev->dev;
 	int retval = 0;
 	uint32_t *buffer, size;
 
@@ -385,7 +399,8 @@
 			(unsigned int **)&buffer);
 
 		if (!buffer) {
-			pr_err("Failed to allocate buffer on kernel queue\n");
+			dev_err(dev,
+				"Failed to allocate buffer on kernel queue\n");
 			retval = -ENOMEM;
 			goto out;
 		}
@@ -406,6 +421,8 @@
 			enum kfd_unmap_queues_filter filter,
 			uint32_t filter_param, bool reset)
 {
+	struct kfd_node *node = pm->dqm->dev;
+	struct device *dev = node->adev->dev;
 	uint32_t *buffer, size;
 	int retval = 0;
 
@@ -414,7 +431,7 @@
 	kq_acquire_packet_buffer(pm->priv_queue,
 			size / sizeof(uint32_t), (unsigned int **)&buffer);
 	if (!buffer) {
-		pr_err("Failed to allocate buffer on kernel queue\n");
+		dev_err(dev, "Failed to allocate buffer on kernel queue\n");
 		retval = -ENOMEM;
 		goto out;
 	}
@@ -463,6 +480,8 @@
 
 int pm_debugfs_hang_hws(struct packet_manager *pm)
 {
+	struct kfd_node *node = pm->dqm->dev;
+	struct device *dev = node->adev->dev;
 	uint32_t *buffer, size;
 	int r = 0;
 
@@ -474,16 +493,16 @@
 	kq_acquire_packet_buffer(pm->priv_queue,
 			size / sizeof(uint32_t), (unsigned int **)&buffer);
 	if (!buffer) {
-		pr_err("Failed to allocate buffer on kernel queue\n");
+		dev_err(dev, "Failed to allocate buffer on kernel queue\n");
 		r = -ENOMEM;
 		goto out;
 	}
 	memset(buffer, 0x55, size);
 	kq_submit_packet(pm->priv_queue);
 
-	pr_info("Submitting %x %x %x %x %x %x %x to HIQ to hang the HWS.",
-		buffer[0], buffer[1], buffer[2], buffer[3],
-		buffer[4], buffer[5], buffer[6]);
+	dev_info(dev, "Submitting %x %x %x %x %x %x %x to HIQ to hang the HWS.",
+		 buffer[0], buffer[1], buffer[2], buffer[3], buffer[4],
+		 buffer[5], buffer[6]);
 out:
 	mutex_unlock(&pm->lock);
 	return r;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -272,7 +272,6 @@
 
 	/* Interrupts */
 	struct kfifo ih_fifo;
-	struct workqueue_struct *ih_wq;
 	struct work_struct interrupt_work;
 	spinlock_t interrupt_lock;
 
@@ -365,6 +364,8 @@
 	uint32_t alloc_watch_ids;
 	spinlock_t watch_points_lock;
 
+	struct workqueue_struct *ih_wq;
+
 	/* Kernel doorbells for KFD device */
 	struct amdgpu_bo *doorbells;
 
@@ -765,7 +766,7 @@
 	enum kfd_pdd_bound bound;
 
 	/* VRAM usage */
-	uint64_t vram_usage;
+	atomic64_t vram_usage;
 	struct attribute attr_vram;
 	char vram_filename[MAX_SYSFS_FILENAME_LEN];
 
@@ -1473,7 +1474,7 @@
 
 static inline bool kfd_flush_tlb_after_unmap(struct kfd_dev *dev)
 {
-	return KFD_GC_VERSION(dev) > IP_VERSION(9, 4, 2) ||
+	return KFD_GC_VERSION(dev) >= IP_VERSION(9, 4, 2) ||
 	       (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 1) && dev->sdma_fw_version >= 18) ||
 	       KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 0);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -306,14 +306,14 @@
 	} else if (strncmp(attr->name, "vram_", 5) == 0) {
 		struct kfd_process_device *pdd = container_of(attr, struct kfd_process_device,
 							      attr_vram);
-		return snprintf(buffer, PAGE_SIZE, "%llu\n", READ_ONCE(pdd->vram_usage));
+		return snprintf(buffer, PAGE_SIZE, "%llu\n", atomic64_read(&pdd->vram_usage));
 	} else if (strncmp(attr->name, "sdma_", 5) == 0) {
 		struct kfd_process_device *pdd = container_of(attr, struct kfd_process_device,
 							      attr_sdma);
 		struct kfd_sdma_activity_handler_workarea sdma_activity_work_handler;
 
-		INIT_WORK(&sdma_activity_work_handler.sdma_activity_work,
-					kfd_sdma_activity_worker);
+		INIT_WORK_ONSTACK(&sdma_activity_work_handler.sdma_activity_work,
+				  kfd_sdma_activity_worker);
 
 		sdma_activity_work_handler.pdd = pdd;
 		sdma_activity_work_handler.sdma_activity_counter = 0;
@@ -321,6 +321,7 @@
 		schedule_work(&sdma_activity_work_handler.sdma_activity_work);
 
 		flush_work(&sdma_activity_work_handler.sdma_activity_work);
+		destroy_work_on_stack(&sdma_activity_work_handler.sdma_activity_work);
 
 		return snprintf(buffer, PAGE_SIZE, "%llu\n",
 				(sdma_activity_work_handler.sdma_activity_counter)/
@@ -819,9 +820,9 @@
 	mutex_lock(&kfd_processes_mutex);
 
 	if (kfd_is_locked()) {
-		mutex_unlock(&kfd_processes_mutex);
 		pr_debug("KFD is locked! Cannot create process");
-		return ERR_PTR(-EINVAL);
+		process = ERR_PTR(-EINVAL);
+		goto out;
 	}
 
 	/* A prior open of /dev/kfd could have already created the process. */
@@ -829,6 +830,14 @@
 	if (process) {
 		pr_debug("Process already found\n");
 	} else {
+		/* If the process just called exec(3), it is possible that the
+		 * cleanup of the kfd_process (following the release of the mm
+		 * of the old process image) is still in the cleanup work queue.
+		 * Make sure to drain any job before trying to recreate any
+		 * resource for this process.
+		 */
+		flush_workqueue(kfd_process_wq);
+
 		process = create_process(thread);
 		if (IS_ERR(process))
 			goto out;
@@ -1038,9 +1047,10 @@
 
 		kfd_free_process_doorbells(pdd->dev->kfd, pdd);
 
-		if (pdd->dev->kfd->shared_resources.enable_mes)
+		if (pdd->dev->kfd->shared_resources.enable_mes &&
+			pdd->proc_ctx_cpu_ptr)
 			amdgpu_amdkfd_free_gtt_mem(pdd->dev->adev,
-						   pdd->proc_ctx_bo);
+						   &pdd->proc_ctx_bo);
 		/*
 		 * before destroying pdd, make sure to report availability
 		 * for auto suspend
@@ -1121,7 +1131,8 @@
 	 */
 	synchronize_rcu();
 	ef = rcu_access_pointer(p->ef);
-	dma_fence_signal(ef);
+	if (ef)
+		dma_fence_signal(ef);
 
 	kfd_process_remove_sysfs(p);
 
@@ -1303,7 +1314,8 @@
 		if (IS_ERR_VALUE(qpd->tba_addr)) {
 			int err = qpd->tba_addr;
 
-			pr_err("Failure to set tba address. error %d.\n", err);
+			dev_err(dev->adev->dev,
+				"Failure to set tba address. error %d.\n", err);
 			qpd->tba_addr = 0;
 			qpd->cwsr_kaddr = NULL;
 			return err;
@@ -1571,7 +1583,6 @@
 							struct kfd_process *p)
 {
 	struct kfd_process_device *pdd = NULL;
-	int retval = 0;
 
 	if (WARN_ON_ONCE(p->n_pdds >= MAX_GPU_INSTANCE))
 		return NULL;
@@ -1590,25 +1601,11 @@
 	pdd->bound = PDD_UNBOUND;
 	pdd->already_dequeued = false;
 	pdd->runtime_inuse = false;
-	pdd->vram_usage = 0;
+	atomic64_set(&pdd->vram_usage, 0);
 	pdd->sdma_past_activity_counter = 0;
 	pdd->user_gpu_id = dev->id;
 	atomic64_set(&pdd->evict_duration_counter, 0);
 
-	if (dev->kfd->shared_resources.enable_mes) {
-		retval = amdgpu_amdkfd_alloc_gtt_mem(dev->adev,
-						AMDGPU_MES_PROC_CTX_SIZE,
-						&pdd->proc_ctx_bo,
-						&pdd->proc_ctx_gpu_addr,
-						&pdd->proc_ctx_cpu_ptr,
-						false);
-		if (retval) {
-			pr_err("failed to allocate process context bo\n");
-			goto err_free_pdd;
-		}
-		memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE);
-	}
-
 	p->pdds[p->n_pdds++] = pdd;
 	if (kfd_dbg_is_per_vmid_supported(pdd->dev))
 		pdd->spi_dbg_override = pdd->dev->kfd2kgd->disable_debug_trap(
@@ -1620,10 +1617,6 @@
 	idr_init(&pdd->alloc_idr);
 
 	return pdd;
-
-err_free_pdd:
-	kfree(pdd);
-	return NULL;
 }
 
 /**
@@ -1666,12 +1659,15 @@
 
 	ret = amdgpu_amdkfd_gpuvm_acquire_process_vm(dev->adev, avm,
 						     &p->kgd_process_info,
-						     &ef);
+						     p->ef ? NULL : &ef);
 	if (ret) {
-		pr_err("Failed to create process VM object\n");
+		dev_err(dev->adev->dev, "Failed to create process VM object\n");
 		return ret;
 	}
-	RCU_INIT_POINTER(p->ef, ef);
+
+	if (!p->ef)
+		RCU_INIT_POINTER(p->ef, ef);
+
 	pdd->drm_priv = drm_file->private_data;
 
 	ret = kfd_process_device_reserve_ib_mem(pdd);
@@ -1715,7 +1711,7 @@
 
 	pdd = kfd_get_process_device_data(dev, p);
 	if (!pdd) {
-		pr_err("Process device data doesn't exist\n");
+		dev_err(dev->adev->dev, "Process device data doesn't exist\n");
 		return ERR_PTR(-ENOMEM);
 	}
 
@@ -1825,6 +1821,7 @@
 
 	for (i = 0; i < p->n_pdds; i++) {
 		struct kfd_process_device *pdd = p->pdds[i];
+		struct device *dev = pdd->dev->adev->dev;
 
 		kfd_smi_event_queue_eviction(pdd->dev, p->lead_thread->pid,
 					     trigger);
@@ -1836,7 +1833,7 @@
 		 * them been add back since they actually not be saved right now.
 		 */
 		if (r && r != -EIO) {
-			pr_err("Failed to evict process queues\n");
+			dev_err(dev, "Failed to evict process queues\n");
 			goto fail;
 		}
 		n_evicted++;
@@ -1858,7 +1855,8 @@
 
 		if (pdd->dev->dqm->ops.restore_process_queues(pdd->dev->dqm,
 							      &pdd->qpd))
-			pr_err("Failed to restore queues\n");
+			dev_err(pdd->dev->adev->dev,
+				"Failed to restore queues\n");
 
 		n_evicted--;
 	}
@@ -1874,13 +1872,14 @@
 
 	for (i = 0; i < p->n_pdds; i++) {
 		struct kfd_process_device *pdd = p->pdds[i];
+		struct device *dev = pdd->dev->adev->dev;
 
 		kfd_smi_event_queue_restore(pdd->dev, p->lead_thread->pid);
 
 		r = pdd->dev->dqm->ops.restore_process_queues(pdd->dev->dqm,
 							      &pdd->qpd);
 		if (r) {
-			pr_err("Failed to restore process queues\n");
+			dev_err(dev, "Failed to restore process queues\n");
 			if (!ret)
 				ret = r;
 		}
@@ -1922,6 +1921,8 @@
 	rcu_read_lock();
 	ef = dma_fence_get_rcu_safe(&p->ef);
 	rcu_read_unlock();
+	if (!ef)
+		return -EINVAL;
 
 	ret = dma_fence_signal(ef);
 	dma_fence_put(ef);
@@ -1949,10 +1950,9 @@
 		 * they are responsible stopping the queues and scheduling
 		 * the restore work.
 		 */
-		if (!signal_eviction_fence(p))
-			queue_delayed_work(kfd_restore_wq, &p->restore_work,
-				msecs_to_jiffies(PROCESS_RESTORE_TIME_MS));
-		else
+		if (signal_eviction_fence(p) ||
+		    mod_delayed_work(kfd_restore_wq, &p->restore_work,
+				     msecs_to_jiffies(PROCESS_RESTORE_TIME_MS)))
 			kfd_process_restore_queues(p);
 
 		pr_debug("Finished evicting pasid 0x%x\n", p->pasid);
@@ -2011,9 +2011,9 @@
 	if (ret) {
 		pr_debug("Failed to restore BOs of pasid 0x%x, retry after %d ms\n",
 			 p->pasid, PROCESS_BACK_OFF_TIME_MS);
-		ret = queue_delayed_work(kfd_restore_wq, &p->restore_work,
-				msecs_to_jiffies(PROCESS_BACK_OFF_TIME_MS));
-		WARN(!ret, "reschedule restore work failed\n");
+		if (mod_delayed_work(kfd_restore_wq, &p->restore_work,
+				     msecs_to_jiffies(PROCESS_RESTORE_TIME_MS)))
+			kfd_process_restore_queues(p);
 	}
 }
 
@@ -2056,7 +2056,7 @@
 	struct qcm_process_device *qpd;
 
 	if ((vma->vm_end - vma->vm_start) != KFD_CWSR_TBA_TMA_SIZE) {
-		pr_err("Incorrect CWSR mapping size.\n");
+		dev_err(dev->adev->dev, "Incorrect CWSR mapping size.\n");
 		return -EINVAL;
 	}
 
@@ -2068,7 +2068,8 @@
 	qpd->cwsr_kaddr = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
 					get_order(KFD_CWSR_TBA_TMA_SIZE));
 	if (!qpd->cwsr_kaddr) {
-		pr_err("Error allocating per process CWSR buffer.\n");
+		dev_err(dev->adev->dev,
+			"Error allocating per process CWSR buffer.\n");
 		return -ENOMEM;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -28,6 +28,7 @@
 #include "kfd_priv.h"
 #include "kfd_kernel_queue.h"
 #include "amdgpu_amdkfd.h"
+#include "amdgpu_reset.h"
 
 static inline struct process_queue_node *get_queue_by_qid(
 			struct process_queue_manager *pqm, unsigned int qid)
@@ -85,10 +86,17 @@
 
 	if (pdd->already_dequeued)
 		return;
-
+	/* The MES context flush needs to filter out the case which the
+	 * KFD process is created without setting up the MES context and
+	 * queue for creating a compute queue.
+	 */
 	dev->dqm->ops.process_termination(dev->dqm, &pdd->qpd);
-	if (dev->kfd->shared_resources.enable_mes)
-		amdgpu_mes_flush_shader_debugger(dev->adev, pdd->proc_ctx_gpu_addr);
+	if (dev->kfd->shared_resources.enable_mes && !!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;
 }
 
@@ -196,9 +204,9 @@
 	}
 
 	if (dev->kfd->shared_resources.enable_mes) {
-		amdgpu_amdkfd_free_gtt_mem(dev->adev, pqn->q->gang_ctx_bo);
+		amdgpu_amdkfd_free_gtt_mem(dev->adev, &pqn->q->gang_ctx_bo);
 		if (pqn->q->wptr_bo)
-			amdgpu_amdkfd_free_gtt_mem(dev->adev, pqn->q->wptr_bo);
+			amdgpu_amdkfd_free_gtt_mem(dev->adev, (void **)&pqn->q->wptr_bo);
 	}
 }
 
@@ -979,6 +987,7 @@
 		pr_debug("Queue id %d was restored successfully\n", queue_id);
 
 	kfree(q_data);
+	kfree(q_extra_data);
 
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -404,6 +404,27 @@
 		spin_lock(&svm_bo->list_lock);
 	}
 	spin_unlock(&svm_bo->list_lock);
+
+	if (mmget_not_zero(svm_bo->eviction_fence->mm)) {
+		struct kfd_process_device *pdd;
+		struct kfd_process *p;
+		struct mm_struct *mm;
+
+		mm = svm_bo->eviction_fence->mm;
+		/*
+		 * The forked child process takes svm_bo device pages ref, svm_bo could be
+		 * released after parent process is gone.
+		 */
+		p = kfd_lookup_process_by_mm(mm);
+		if (p) {
+			pdd = kfd_get_process_device_data(svm_bo->node, p);
+			if (pdd)
+				atomic64_sub(amdgpu_bo_size(svm_bo->bo), &pdd->vram_usage);
+			kfd_unref_process(p);
+		}
+		mmput(mm);
+	}
+
 	if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base))
 		/* We're not in the eviction worker. Signal the fence. */
 		dma_fence_signal(&svm_bo->eviction_fence->base);
@@ -531,6 +552,7 @@
 svm_range_vram_node_new(struct kfd_node *node, struct svm_range *prange,
 			bool clear)
 {
+	struct kfd_process_device *pdd;
 	struct amdgpu_bo_param bp;
 	struct svm_range_bo *svm_bo;
 	struct amdgpu_bo_user *ubo;
@@ -622,6 +644,10 @@
 	list_add(&prange->svm_bo_list, &svm_bo->range_list);
 	spin_unlock(&svm_bo->list_lock);
 
+	pdd = svm_range_get_pdd_by_node(prange, node);
+	if (pdd)
+		atomic64_add(amdgpu_bo_size(bo), &pdd->vram_usage);
+
 	return 0;
 
 reserve_bo_failed:
@@ -1656,7 +1682,7 @@
 	start = map_start << PAGE_SHIFT;
 	end = (map_last + 1) << PAGE_SHIFT;
 	for (addr = start; !r && addr < end; ) {
-		struct hmm_range *hmm_range;
+		struct hmm_range *hmm_range = NULL;
 		unsigned long map_start_vma;
 		unsigned long map_last_vma;
 		struct vm_area_struct *vma;
@@ -1694,7 +1720,12 @@
 		}
 
 		svm_range_lock(prange);
-		if (!r && amdgpu_hmm_range_get_pages_done(hmm_range)) {
+
+		/* Free backing memory of hmm_range if it was initialized
+		 * Overrride return value to TRY AGAIN only if prior returns
+		 * were successful
+		 */
+		if (hmm_range && amdgpu_hmm_range_get_pages_done(hmm_range) && !r) {
 			pr_debug("hmm update the range, need validate again\n");
 			r = -EAGAIN;
 		}
@@ -2617,7 +2648,8 @@
 		return -1;
 	}
 
-	if (node->adev->gmc.is_app_apu)
+	if (node->adev->gmc.is_app_apu ||
+	    node->adev->flags & AMD_IS_APU)
 		return 0;
 
 	if (prange->preferred_loc == gpuid ||
@@ -3335,7 +3367,8 @@
 		goto out;
 	}
 
-	if (bo_node->adev->gmc.is_app_apu) {
+	if (bo_node->adev->gmc.is_app_apu ||
+	    bo_node->adev->flags & AMD_IS_APU) {
 		best_loc = 0;
 		goto out;
 	}
@@ -3424,7 +3457,7 @@
 				mm, KFD_MIGRATE_TRIGGER_PREFETCH);
 	*migrated = !r;
 
-	return r;
+	return 0;
 }
 
 int svm_range_schedule_evict_svm_bo(struct amdgpu_amdkfd_fence *fence)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_svm.h
@@ -201,7 +201,8 @@
  * is initialized to not 0 when page migration register device memory.
  */
 #define KFD_IS_SVM_API_SUPPORTED(adev) ((adev)->kfd.pgmap.type != 0 ||\
-					(adev)->gmc.is_app_apu)
+					(adev)->gmc.is_app_apu ||\
+					((adev)->flags & AMD_IS_APU))
 
 void svm_range_bo_unref_async(struct svm_range_bo *svm_bo);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_topology.c
@@ -958,8 +958,7 @@
 	dev = list_last_entry(&topology_device_list,
 			struct kfd_topology_device, list);
 	if (dev) {
-		sys_props.platform_id =
-			(*((uint64_t *)dev->oem_id)) & CRAT_OEMID_64BIT_MASK;
+		sys_props.platform_id = dev->oem_id64;
 		sys_props.platform_oem = *((uint64_t *)dev->oem_table_id);
 		sys_props.platform_rev = dev->oem_revision;
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_topology.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/amdkfd/kfd_topology.h
@@ -154,7 +154,10 @@
 	struct attribute		attr_gpuid;
 	struct attribute		attr_name;
 	struct attribute		attr_props;
-	uint8_t				oem_id[CRAT_OEMID_LENGTH];
+	union {
+		uint8_t				oem_id[CRAT_OEMID_LENGTH];
+		uint64_t			oem_id64;
+	};
 	uint8_t				oem_table_id[CRAT_OEMTABLEID_LENGTH];
 	uint32_t			oem_revision;
 };
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -147,6 +147,9 @@
 #define FIRMWARE_DCN_35_DMUB "amdgpu/dcn_3_5_dmcub.bin"
 MODULE_FIRMWARE(FIRMWARE_DCN_35_DMUB);
 
+#define FIRMWARE_DCN_351_DMUB "amdgpu/dcn_3_5_1_dmcub.bin"
+MODULE_FIRMWARE(FIRMWARE_DCN_351_DMUB);
+
 /* Number of bytes in PSP header for firmware. */
 #define PSP_HEADER_BYTES 0x100
 
@@ -270,7 +273,7 @@
 static int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc,
 				  u32 *vbl, u32 *position)
 {
-	u32 v_blank_start, v_blank_end, h_position, v_position;
+	u32 v_blank_start = 0, v_blank_end = 0, h_position = 0, v_position = 0;
 	struct amdgpu_crtc *acrtc = NULL;
 	struct dc *dc = adev->dm.dc;
 
@@ -590,12 +593,14 @@
 	if (!acrtc)
 		return;
 
-	if (acrtc->wb_pending) {
-		if (acrtc->wb_conn) {
-			spin_lock_irqsave(&acrtc->wb_conn->job_lock, flags);
+	if (acrtc->wb_conn) {
+		spin_lock_irqsave(&acrtc->wb_conn->job_lock, flags);
+
+		if (acrtc->wb_pending) {
 			job = list_first_entry_or_null(&acrtc->wb_conn->job_queue,
 						       struct drm_writeback_job,
 						       list_entry);
+			acrtc->wb_pending = false;
 			spin_unlock_irqrestore(&acrtc->wb_conn->job_lock, flags);
 
 			if (job) {
@@ -613,8 +618,7 @@
 							       acrtc->dm_irq_params.stream, 0);
 			}
 		} else
-			DRM_ERROR("%s: no amdgpu_crtc wb_conn\n", __func__);
-		acrtc->wb_pending = false;
+			spin_unlock_irqrestore(&acrtc->wb_conn->job_lock, flags);
 	}
 
 	vrr_active = amdgpu_dm_crtc_vrr_active_irq(acrtc);
@@ -753,6 +757,12 @@
 		return;
 	}
 
+	/* Skip DMUB HPD IRQ in suspend/resume. We will probe them later. */
+	if (notify->type == DMUB_NOTIFICATION_HPD && adev->in_suspend) {
+		DRM_INFO("Skip DMUB HPD IRQ callback in suspend/resume\n");
+		return;
+	}
+
 	link_index = notify->link_index;
 	link = adev->dm.dc->links[link_index];
 	dev = adev->dm.ddev;
@@ -844,7 +854,7 @@
  */
 static void dm_dmub_outbox1_low_irq(void *interrupt_params)
 {
-	struct dmub_notification notify;
+	struct dmub_notification notify = {0};
 	struct common_irq_params *irq_params = interrupt_params;
 	struct amdgpu_device *adev = irq_params->adev;
 	struct amdgpu_display_manager *dm = &adev->dm;
@@ -995,8 +1005,10 @@
 			continue;
 
 		*enabled = true;
+		mutex_lock(&connector->eld_mutex);
 		ret = drm_eld_size(connector->eld);
 		memcpy(buf, connector->eld, min(max_bytes, ret));
+		mutex_unlock(&connector->eld_mutex);
 
 		break;
 	}
@@ -1683,7 +1695,11 @@
 		else
 			init_data.flags.gpu_vm_support = (amdgpu_sg_display != 0);
 	} else {
-		init_data.flags.gpu_vm_support = (amdgpu_sg_display != 0) && (adev->flags & AMD_IS_APU);
+		if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(2, 0, 3))
+			init_data.flags.gpu_vm_support = (amdgpu_sg_display == 1);
+		else
+			init_data.flags.gpu_vm_support =
+				(amdgpu_sg_display != 0) && (adev->flags & AMD_IS_APU);
 	}
 
 	adev->mode_info.gpu_vm_support = init_data.flags.gpu_vm_support;
@@ -1929,17 +1945,15 @@
 		adev->dm.hdcp_workqueue = NULL;
 	}
 
-	if (adev->dm.dc)
+	if (adev->dm.dc) {
 		dc_deinit_callbacks(adev->dm.dc);
-
-	if (adev->dm.dc)
 		dc_dmub_srv_destroy(&adev->dm.dc->ctx->dmub_srv);
-
-	if (dc_enable_dmub_notifications(adev->dm.dc)) {
-		kfree(adev->dm.dmub_notify);
-		adev->dm.dmub_notify = NULL;
-		destroy_workqueue(adev->dm.delayed_hpd_wq);
-		adev->dm.delayed_hpd_wq = NULL;
+		if (dc_enable_dmub_notifications(adev->dm.dc)) {
+			kfree(adev->dm.dmub_notify);
+			adev->dm.dmub_notify = NULL;
+			destroy_workqueue(adev->dm.delayed_hpd_wq);
+			adev->dm.delayed_hpd_wq = NULL;
+		}
 	}
 
 	if (adev->dm.dmub_bo)
@@ -2667,7 +2681,8 @@
 
 		dm->cached_dc_state = dc_state_create_copy(dm->dc->current_state);
 
-		dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false);
+		if (dm->cached_dc_state)
+			dm_gpureset_toggle_interrupts(adev, dm->cached_dc_state, false);
 
 		amdgpu_dm_commit_zero_streams(dm->dc);
 
@@ -2690,6 +2705,10 @@
 	hpd_rx_irq_work_suspend(dm);
 
 	dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D3);
+
+	if (dm->dc->caps.ips_support && adev->in_s0ix)
+		dc_allow_idle_optimizations(dm->dc, true);
+
 	dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D3);
 
 	return 0;
@@ -2906,6 +2925,7 @@
 			dc_enable_dmub_outbox(adev->dm.dc);
 		}
 
+		dc_exit_ips_for_hw_access(dm->dc);
 		WARN_ON(!dc_commit_streams(dm->dc, dc_state->streams, dc_state->stream_count));
 
 		dm_gpureset_commit_state(dm->cached_dc_state, dm);
@@ -2978,7 +2998,8 @@
 			emulated_link_detect(aconnector->dc_link);
 		} else {
 			mutex_lock(&dm->dc_lock);
-			dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD);
+			dc_exit_ips_for_hw_access(dm->dc);
+			dc_link_detect(aconnector->dc_link, DETECT_REASON_RESUMEFROMS3S4);
 			mutex_unlock(&dm->dc_lock);
 		}
 
@@ -3009,6 +3030,7 @@
 			dc_stream_release(dm_new_crtc_state->stream);
 			dm_new_crtc_state->stream = NULL;
 		}
+		dm_new_crtc_state->base.color_mgmt_changed = true;
 	}
 
 	for_each_new_plane_in_state(dm->cached_state, plane, new_plane_state, i) {
@@ -3027,6 +3049,10 @@
 	/* Do mst topology probing after resuming cached state*/
 	drm_connector_list_iter_begin(ddev, &iter);
 	drm_for_each_connector_iter(connector, &iter) {
+
+		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+			continue;
+
 		aconnector = to_amdgpu_dm_connector(connector);
 		if (aconnector->dc_link->type != dc_connection_mst_branch ||
 		    aconnector->mst_root)
@@ -3307,6 +3333,7 @@
 	enum dc_connection_type new_connection_type = dc_connection_none;
 	struct amdgpu_device *adev = drm_to_adev(dev);
 	struct dm_connector_state *dm_con_state = to_dm_connector_state(connector->state);
+	struct dc *dc = aconnector->dc_link->ctx->dc;
 	bool ret = false;
 
 	if (adev->dm.disable_hpd_irq)
@@ -3341,6 +3368,7 @@
 			drm_kms_helper_connector_hotplug_event(connector);
 	} else {
 		mutex_lock(&adev->dm.dc_lock);
+		dc_exit_ips_for_hw_access(dc);
 		ret = dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD);
 		mutex_unlock(&adev->dm.dc_lock);
 		if (ret) {
@@ -3400,6 +3428,7 @@
 	bool has_left_work = false;
 	int idx = dc_link->link_index;
 	struct hpd_rx_irq_offload_work_queue *offload_wq = &adev->dm.hpd_rx_offload_wq[idx];
+	struct dc *dc = aconnector->dc_link->ctx->dc;
 
 	memset(&hpd_irq_data, 0, sizeof(hpd_irq_data));
 
@@ -3489,6 +3518,7 @@
 			bool ret = false;
 
 			mutex_lock(&adev->dm.dc_lock);
+			dc_exit_ips_for_hw_access(dc);
 			ret = dc_link_detect(dc_link, DETECT_REASON_HPDRX);
 			mutex_unlock(&adev->dm.dc_lock);
 
@@ -4075,8 +4105,11 @@
 	}
 
 #ifdef AMD_PRIVATE_COLOR
-	if (amdgpu_dm_create_color_properties(adev))
+	if (amdgpu_dm_create_color_properties(adev)) {
+		dc_state_release(state->context);
+		kfree(state);
 		return -ENOMEM;
+	}
 #endif
 
 	r = amdgpu_dm_audio_init(adev);
@@ -4091,6 +4124,7 @@
 
 #define AMDGPU_DM_DEFAULT_MIN_BACKLIGHT 12
 #define AMDGPU_DM_DEFAULT_MAX_BACKLIGHT 255
+#define AMDGPU_DM_MIN_SPREAD ((AMDGPU_DM_DEFAULT_MAX_BACKLIGHT - AMDGPU_DM_DEFAULT_MIN_BACKLIGHT) / 2)
 #define AUX_BL_DEFAULT_TRANSITION_TIME_MS 50
 
 static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm,
@@ -4105,6 +4139,21 @@
 		return;
 
 	amdgpu_acpi_get_backlight_caps(&caps);
+
+	/* validate the firmware value is sane */
+	if (caps.caps_valid) {
+		int spread = caps.max_input_signal - caps.min_input_signal;
+
+		if (caps.max_input_signal > AMDGPU_DM_DEFAULT_MAX_BACKLIGHT ||
+		    caps.min_input_signal < 0 ||
+		    spread > AMDGPU_DM_DEFAULT_MAX_BACKLIGHT ||
+		    spread < AMDGPU_DM_MIN_SPREAD) {
+			DRM_DEBUG_KMS("DM: Invalid backlight caps: min=%d, max=%d\n",
+				      caps.min_input_signal, caps.max_input_signal);
+			caps.caps_valid = false;
+		}
+	}
+
 	if (caps.caps_valid) {
 		dm->backlight_caps[bl_idx].caps_valid = true;
 		if (caps.aux_support)
@@ -4179,7 +4228,7 @@
 	struct amdgpu_dm_backlight_caps caps;
 	struct dc_link *link;
 	u32 brightness;
-	bool rc;
+	bool rc, reallow_idle = false;
 
 	amdgpu_dm_update_backlight_caps(dm, bl_idx);
 	caps = dm->backlight_caps[bl_idx];
@@ -4192,6 +4241,12 @@
 	link = (struct dc_link *)dm->backlight_link[bl_idx];
 
 	/* Change brightness based on AUX property */
+	mutex_lock(&dm->dc_lock);
+	if (dm->dc->caps.ips_support && dm->dc->ctx->dmub_srv->idle_allowed) {
+		dc_allow_idle_optimizations(dm->dc, false);
+		reallow_idle = true;
+	}
+
 	if (caps.aux_support) {
 		rc = dc_link_set_backlight_level_nits(link, true, brightness,
 						      AUX_BL_DEFAULT_TRANSITION_TIME_MS);
@@ -4203,6 +4258,11 @@
 			DRM_DEBUG("DM: Failed to update backlight on eDP[%d]\n", bl_idx);
 	}
 
+	if (dm->dc->caps.ips_support && reallow_idle)
+		dc_allow_idle_optimizations(dm->dc, true);
+
+	mutex_unlock(&dm->dc_lock);
+
 	if (rc)
 		dm->actual_brightness[bl_idx] = user_brightness;
 }
@@ -4411,7 +4471,10 @@
 
 	/* There is one primary plane per CRTC */
 	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.
@@ -4506,17 +4569,17 @@
 		}
 	}
 
+	if (link_cnt > MAX_LINKS) {
+		DRM_ERROR(
+			"KMS: Cannot support more than %d display indexes\n",
+				MAX_LINKS);
+		goto fail;
+	}
+
 	/* loops over all connectors on the board */
 	for (i = 0; i < link_cnt; i++) {
 		struct dc_link *link = NULL;
 
-		if (i > AMDGPU_DM_MAX_DISPLAY_INDEX) {
-			DRM_ERROR(
-				"KMS: Cannot support more than %d display indexes\n",
-					AMDGPU_DM_MAX_DISPLAY_INDEX);
-			continue;
-		}
-
 		link = dc_get_link_at_index(dm->dc, i);
 
 		if (link->connector_signal == SIGNAL_TYPE_VIRTUAL) {
@@ -4571,6 +4634,7 @@
 			bool ret = false;
 
 			mutex_lock(&dm->dc_lock);
+			dc_exit_ips_for_hw_access(dm->dc);
 			ret = dc_link_detect(link, DETECT_REASON_BOOT);
 			mutex_unlock(&dm->dc_lock);
 
@@ -4778,6 +4842,9 @@
 	case IP_VERSION(3, 5, 0):
 		fw_name_dmub = FIRMWARE_DCN_35_DMUB;
 		break;
+	case IP_VERSION(3, 5, 1):
+		fw_name_dmub = FIRMWARE_DCN_351_DMUB;
+		break;
 	default:
 		/* ASIC doesn't support DMUB. */
 		return 0;
@@ -4996,8 +5063,7 @@
 			    const u64 tiling_flags,
 			    struct dc_plane_info *plane_info,
 			    struct dc_plane_address *address,
-			    bool tmz_surface,
-			    bool force_disable_dcc)
+			    bool tmz_surface)
 {
 	const struct drm_framebuffer *fb = plane_state->fb;
 	const struct amdgpu_framebuffer *afb =
@@ -5096,7 +5162,7 @@
 					   &plane_info->tiling_info,
 					   &plane_info->plane_size,
 					   &plane_info->dcc, address,
-					   tmz_surface, force_disable_dcc);
+					   tmz_surface);
 	if (ret)
 		return ret;
 
@@ -5117,7 +5183,6 @@
 	struct dc_scaling_info scaling_info;
 	struct dc_plane_info plane_info;
 	int ret;
-	bool force_disable_dcc = false;
 
 	ret = amdgpu_dm_plane_fill_dc_scaling_info(adev, plane_state, &scaling_info);
 	if (ret)
@@ -5128,13 +5193,11 @@
 	dc_plane_state->clip_rect = scaling_info.clip_rect;
 	dc_plane_state->scaling_quality = scaling_info.scaling_quality;
 
-	force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend;
 	ret = fill_dc_plane_info_and_addr(adev, plane_state,
 					  afb->tiling_flags,
 					  &plane_info,
 					  &dc_plane_state->address,
-					  afb->tmz_surface,
-					  force_disable_dcc);
+					  afb->tmz_surface);
 	if (ret)
 		return ret;
 
@@ -5201,6 +5264,10 @@
  * @new_plane_state: New state of @plane
  * @crtc_state: New state of CRTC connected to the @plane
  * @flip_addrs: DC flip tracking struct, which also tracts dirty rects
+ * @is_psr_su: Flag indicating whether Panel Self Refresh Selective Update (PSR SU) is enabled.
+ *             If PSR SU is enabled and damage clips are available, only the regions of the screen
+ *             that have changed will be updated. If PSR SU is not enabled,
+ *             or if damage clips are not available, the entire screen will be updated.
  * @dirty_regions_changed: dirty regions changed
  *
  * For PSR SU, DC informs the DMUB uController of dirty rectangle regions
@@ -5871,6 +5938,9 @@
 		&aconnector->base.probed_modes :
 		&aconnector->base.modes;
 
+	if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
+		return NULL;
+
 	if (aconnector->freesync_vid_base.clock != 0)
 		return &aconnector->freesync_vid_base;
 
@@ -6254,27 +6324,31 @@
 
 	if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A)
 		mod_build_hf_vsif_infopacket(stream, &stream->vsp_infopacket);
-	else if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
-			 stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
-			 stream->signal == SIGNAL_TYPE_EDP) {
+
+	if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT ||
+	    stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST ||
+	    stream->signal == SIGNAL_TYPE_EDP) {
+		const struct dc_edid_caps *edid_caps;
+		unsigned int disable_colorimetry = 0;
+
+		if (aconnector->dc_sink) {
+			edid_caps = &aconnector->dc_sink->edid_caps;
+			disable_colorimetry = edid_caps->panel_patch.disable_colorimetry;
+		}
+
 		//
 		// should decide stream support vsc sdp colorimetry capability
 		// before building vsc info packet
 		//
-		stream->use_vsc_sdp_for_colorimetry = false;
-		if (aconnector->dc_sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
-			stream->use_vsc_sdp_for_colorimetry =
-				aconnector->dc_sink->is_vsc_sdp_colorimetry_supported;
-		} else {
-			if (stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED)
-				stream->use_vsc_sdp_for_colorimetry = true;
-		}
+		stream->use_vsc_sdp_for_colorimetry = stream->link->dpcd_caps.dpcd_rev.raw >= 0x14 &&
+						      stream->link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED &&
+						      !disable_colorimetry;
+
 		if (stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22)
 			tf = TRANSFER_FUNC_GAMMA_22;
 		mod_build_vsc_infopacket(stream, &stream->vsc_infopacket, stream->output_color_space, tf);
+		aconnector->sr_skip_count = AMDGPU_DM_PSR_ENTRY_DELAY;
 
-		if (stream->link->psr_settings.psr_feature_enabled)
-			aconnector->psr_skip_count = AMDGPU_DM_PSR_ENTRY_DELAY;
 	}
 finish:
 	dc_sink_release(sink);
@@ -6409,10 +6483,104 @@
 	return ret;
 }
 
+/**
+ * DOC: panel power savings
+ *
+ * The display manager allows you to set your desired **panel power savings**
+ * level (between 0-4, with 0 representing off), e.g. using the following::
+ *
+ *   # echo 3 > /sys/class/drm/card0-eDP-1/amdgpu/panel_power_savings
+ *
+ * Modifying this value can have implications on color accuracy, so tread
+ * carefully.
+ */
+
+static ssize_t panel_power_savings_show(struct device *device,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct drm_connector *connector = dev_get_drvdata(device);
+	struct drm_device *dev = connector->dev;
+	u8 val;
+
+	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+	val = to_dm_connector_state(connector->state)->abm_level ==
+		ABM_LEVEL_IMMEDIATE_DISABLE ? 0 :
+		to_dm_connector_state(connector->state)->abm_level;
+	drm_modeset_unlock(&dev->mode_config.connection_mutex);
+
+	return sysfs_emit(buf, "%u\n", val);
+}
+
+static ssize_t panel_power_savings_store(struct device *device,
+					 struct device_attribute *attr,
+					 const char *buf, size_t count)
+{
+	struct drm_connector *connector = dev_get_drvdata(device);
+	struct drm_device *dev = connector->dev;
+	long val;
+	int ret;
+
+	ret = kstrtol(buf, 0, &val);
+
+	if (ret)
+		return ret;
+
+	if (val < 0 || val > 4)
+		return -EINVAL;
+
+	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
+	to_dm_connector_state(connector->state)->abm_level = val ?:
+		ABM_LEVEL_IMMEDIATE_DISABLE;
+	drm_modeset_unlock(&dev->mode_config.connection_mutex);
+
+	drm_kms_helper_hotplug_event(dev);
+
+	return count;
+}
+
+static DEVICE_ATTR_RW(panel_power_savings);
+
+static struct attribute *amdgpu_attrs[] = {
+	&dev_attr_panel_power_savings.attr,
+	NULL
+};
+
+static const struct attribute_group amdgpu_group = {
+	.name = "amdgpu",
+	.attrs = amdgpu_attrs
+};
+
+static bool
+amdgpu_dm_should_create_sysfs(struct amdgpu_dm_connector *amdgpu_dm_connector)
+{
+	if (amdgpu_dm_abm_level >= 0)
+		return false;
+
+	if (amdgpu_dm_connector->base.connector_type != DRM_MODE_CONNECTOR_eDP)
+		return false;
+
+	/* check for OLED panels */
+	if (amdgpu_dm_connector->bl_idx >= 0) {
+		struct drm_device *drm = amdgpu_dm_connector->base.dev;
+		struct amdgpu_display_manager *dm = &drm_to_adev(drm)->dm;
+		struct amdgpu_dm_backlight_caps *caps;
+
+		caps = &dm->backlight_caps[amdgpu_dm_connector->bl_idx];
+		if (caps->aux_support)
+			return false;
+	}
+
+	return true;
+}
+
 static void amdgpu_dm_connector_unregister(struct drm_connector *connector)
 {
 	struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector);
 
+	if (amdgpu_dm_should_create_sysfs(amdgpu_dm_connector))
+		sysfs_remove_group(&connector->kdev->kobj, &amdgpu_group);
+
 	drm_dp_aux_unregister(&amdgpu_dm_connector->dm_dp_aux.aux);
 }
 
@@ -6474,9 +6642,12 @@
 		state->vcpi_slots = 0;
 		state->pbn = 0;
 
-		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
-			state->abm_level = amdgpu_dm_abm_level ?:
-				ABM_LEVEL_IMMEDIATE_DISABLE;
+		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+			if (amdgpu_dm_abm_level <= 0)
+				state->abm_level = ABM_LEVEL_IMMEDIATE_DISABLE;
+			else
+				state->abm_level = amdgpu_dm_abm_level;
+		}
 
 		__drm_atomic_helper_connector_reset(connector, &state->base);
 	}
@@ -6514,6 +6685,13 @@
 		to_amdgpu_dm_connector(connector);
 	int r;
 
+	if (amdgpu_dm_should_create_sysfs(amdgpu_dm_connector)) {
+		r = sysfs_create_group(&connector->kdev->kobj,
+				       &amdgpu_group);
+		if (r)
+			return r;
+	}
+
 	amdgpu_dm_register_backlight_device(amdgpu_dm_connector);
 
 	if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
@@ -6631,7 +6809,8 @@
 		aconnector->dc_sink = aconnector->dc_link->local_sink ?
 		aconnector->dc_link->local_sink :
 		aconnector->dc_em_sink;
-		dc_sink_retain(aconnector->dc_sink);
+		if (aconnector->dc_sink)
+			dc_sink_retain(aconnector->dc_sink);
 	}
 }
 
@@ -6726,6 +6905,14 @@
 	const struct drm_connector_state *drm_state = dm_state ? &dm_state->base : NULL;
 	int requested_bpc = drm_state ? drm_state->max_requested_bpc : 8;
 	enum dc_status dc_result = DC_OK;
+	uint8_t bpc_limit = 6;
+
+	if (!dm_state)
+		return NULL;
+
+	if (aconnector->dc_link->connector_signal == SIGNAL_TYPE_HDMI_TYPE_A ||
+	    aconnector->dc_link->dpcd_caps.dongle_type == DISPLAY_DONGLE_DP_HDMI_CONVERTER)
+		bpc_limit = 8;
 
 	do {
 		stream = create_stream_for_sink(connector, drm_mode,
@@ -6747,11 +6934,12 @@
 			dc_result = dm_validate_stream_and_context(adev->dm.dc, stream);
 
 		if (dc_result != DC_OK) {
-			DRM_DEBUG_KMS("Mode %dx%d (clk %d) failed DC validation with error %d (%s)\n",
+			DRM_DEBUG_KMS("Mode %dx%d (clk %d) pixel_encoding:%s color_depth:%s failed validation -- %s\n",
 				      drm_mode->hdisplay,
 				      drm_mode->vdisplay,
 				      drm_mode->clock,
-				      dc_result,
+				      dc_pixel_encoding_to_str(stream->timing.pixel_encoding),
+				      dc_color_depth_to_str(stream->timing.display_color_depth),
 				      dc_status_to_str(dc_result));
 
 			dc_stream_release(stream);
@@ -6759,10 +6947,13 @@
 			requested_bpc -= 2; /* lower bpc to retry validation */
 		}
 
-	} while (stream == NULL && requested_bpc >= 6);
+	} while (stream == NULL && requested_bpc >= bpc_limit);
 
-	if (dc_result == DC_FAIL_ENC_VALIDATE && !aconnector->force_yuv420_output) {
-		DRM_DEBUG_KMS("Retry forcing YCbCr420 encoding\n");
+	if ((dc_result == DC_FAIL_ENC_VALIDATE ||
+	     dc_result == DC_EXCEED_DONGLE_CAP) &&
+	     !aconnector->force_yuv420_output) {
+		DRM_DEBUG_KMS("%s:%d Retry forcing yuv420 encoding\n",
+				     __func__, __LINE__);
 
 		aconnector->force_yuv420_output = true;
 		stream = create_validate_stream_for_sink(aconnector, drm_mode,
@@ -7054,7 +7245,7 @@
 	struct amdgpu_dm_connector *aconnector;
 	struct dm_connector_state *dm_conn_state;
 	int i, j, ret;
-	int vcpi, pbn_div, pbn, slot_num = 0;
+	int vcpi, pbn_div, pbn = 0, slot_num = 0;
 
 	for_each_new_connector_in_state(state, connector, new_con_state, i) {
 
@@ -7094,7 +7285,7 @@
 			}
 		}
 
-		if (j == dc_state->stream_count)
+		if (j == dc_state->stream_count || pbn_div == 0)
 			continue;
 
 		slot_num = DIV_ROUND_UP(pbn, pbn_div);
@@ -7458,7 +7649,8 @@
 				drm_add_modes_noedid(connector, 1920, 1080);
 	} else {
 		amdgpu_dm_connector_ddc_get_modes(connector, edid);
-		amdgpu_dm_connector_add_common_modes(encoder, connector);
+		if (encoder)
+			amdgpu_dm_connector_add_common_modes(encoder, connector);
 		amdgpu_dm_connector_add_freesync_modes(connector, edid);
 	}
 	amdgpu_dm_fbc_init(connector);
@@ -7548,7 +7740,8 @@
 	aconnector->base.state->max_requested_bpc = aconnector->base.state->max_bpc;
 
 	if (connector_type == DRM_MODE_CONNECTOR_eDP &&
-	    (dc_is_dmcu_initialized(adev->dm.dc) || adev->dm.dc->ctx->dmub_srv)) {
+	    (dc_is_dmcu_initialized(adev->dm.dc) ||
+	     adev->dm.dc->ctx->dmub_srv) && amdgpu_dm_abm_level < 0) {
 		drm_object_attach_property(&aconnector->base.base,
 				adev->mode_info.abm_level_property, 0);
 	}
@@ -8302,7 +8495,7 @@
 			afb->tiling_flags,
 			&bundle->plane_infos[planes_count],
 			&bundle->flip_addrs[planes_count].address,
-			afb->tmz_surface, false);
+			afb->tmz_surface);
 
 		drm_dbg_state(state->dev, "plane: id=%d dcc_en=%d\n",
 				 new_plane_state->plane->index,
@@ -8327,7 +8520,7 @@
 			 * during the PSR-SU was disabled.
 			 */
 			if (acrtc_state->stream->link->psr_settings.psr_version >= DC_PSR_VERSION_SU_1 &&
-			    acrtc_attach->dm_irq_params.allow_psr_entry &&
+			    acrtc_attach->dm_irq_params.allow_sr_entry &&
 #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
 			    !amdgpu_dm_crc_window_is_activated(acrtc_state->base.crtc) &&
 #endif
@@ -8454,15 +8647,13 @@
 				bundle->stream_update.vrr_infopacket =
 					&acrtc_state->stream->vrr_infopacket;
 		}
-	} else if (cursor_update && acrtc_state->active_planes > 0 &&
-		   acrtc_attach->base.state->event) {
-		drm_crtc_vblank_get(pcrtc);
-
+	} else if (cursor_update && acrtc_state->active_planes > 0) {
 		spin_lock_irqsave(&pcrtc->dev->event_lock, flags);
-
-		acrtc_attach->event = acrtc_attach->base.state->event;
-		acrtc_attach->base.state->event = NULL;
-
+		if (acrtc_attach->base.state->event) {
+			drm_crtc_vblank_get(pcrtc);
+			acrtc_attach->event = acrtc_attach->base.state->event;
+			acrtc_attach->base.state->event = NULL;
+		}
 		spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
 	}
 
@@ -8551,27 +8742,27 @@
 				!acrtc_state->stream->link->psr_settings.psr_feature_enabled)
 			amdgpu_dm_link_setup_psr(acrtc_state->stream);
 
-		/* Decrement skip count when PSR is enabled and we're doing fast updates. */
+		/* Decrement skip count when SR is enabled and we're doing fast updates. */
 		if (acrtc_state->update_type == UPDATE_TYPE_FAST &&
 		    acrtc_state->stream->link->psr_settings.psr_feature_enabled) {
 			struct amdgpu_dm_connector *aconn =
 				(struct amdgpu_dm_connector *)acrtc_state->stream->dm_stream_context;
 
-			if (aconn->psr_skip_count > 0)
-				aconn->psr_skip_count--;
+			if (aconn->sr_skip_count > 0)
+				aconn->sr_skip_count--;
 
-			/* Allow PSR when skip count is 0. */
-			acrtc_attach->dm_irq_params.allow_psr_entry = !aconn->psr_skip_count;
+			/* Allow SR when skip count is 0. */
+			acrtc_attach->dm_irq_params.allow_sr_entry = !aconn->sr_skip_count;
 
 			/*
-			 * If sink supports PSR SU, there is no need to rely on
-			 * a vblank event disable request to enable PSR. PSR SU
+			 * If sink supports PSR SU/Panel Replay, there is no need to rely on
+			 * a vblank event disable request to enable PSR/RP. PSR SU/RP
 			 * can be enabled immediately once OS demonstrates an
 			 * adequate number of fast atomic commits to notify KMD
 			 * of update events. See `vblank_control_worker()`.
 			 */
-			if (acrtc_state->stream->link->psr_settings.psr_version >= DC_PSR_VERSION_SU_1 &&
-			    acrtc_attach->dm_irq_params.allow_psr_entry &&
+			if (acrtc_state->stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1 &&
+			    acrtc_attach->dm_irq_params.allow_sr_entry &&
 #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
 			    !amdgpu_dm_crc_window_is_activated(acrtc_state->base.crtc) &&
 #endif
@@ -8581,7 +8772,7 @@
 			    500000000)
 				amdgpu_dm_psr_enable(acrtc_state->stream);
 		} else {
-			acrtc_attach->dm_irq_params.allow_psr_entry = false;
+			acrtc_attach->dm_irq_params.allow_sr_entry = false;
 		}
 
 		mutex_unlock(&dm->dc_lock);
@@ -8630,10 +8821,10 @@
 		if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
 			continue;
 
+notify:
 		if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
 			continue;
 
-notify:
 		aconnector = to_amdgpu_dm_connector(connector);
 
 		mutex_lock(&adev->dm.audio_lock);
@@ -8713,6 +8904,7 @@
 	struct drm_connector *connector;
 	bool mode_set_reset_required = false;
 	u32 i;
+	bool set_backlight_level = false;
 
 	/* Disable writeback */
 	for_each_old_connector_in_state(state, connector, old_con_state, i) {
@@ -8732,7 +8924,7 @@
 		if (acrtc)
 			old_crtc_state = drm_atomic_get_old_crtc_state(state, &acrtc->base);
 
-		if (!acrtc->wb_enabled)
+		if (!acrtc || !acrtc->wb_enabled)
 			continue;
 
 		dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
@@ -8780,7 +8972,8 @@
 
 			memset(&position, 0, sizeof(position));
 			mutex_lock(&dm->dc_lock);
-			dc_stream_set_cursor_position(dm_old_crtc_state->stream, &position);
+			dc_exit_ips_for_hw_access(dm->dc);
+			dc_stream_program_cursor_position(dm_old_crtc_state->stream, &position);
 			mutex_unlock(&dm->dc_lock);
 		}
 
@@ -8828,6 +9021,7 @@
 			acrtc->hw_mode = new_crtc_state->mode;
 			crtc->hwmode = new_crtc_state->mode;
 			mode_set_reset_required = true;
+			set_backlight_level = true;
 		} else if (modereset_required(new_crtc_state)) {
 			DRM_DEBUG_ATOMIC("Atomic commit: RESET. crtc id %d:[%p]\n", acrtc->crtc_id, acrtc);
 			/* i.e. reset mode */
@@ -8848,6 +9042,7 @@
 
 	dm_enable_per_frame_crtc_master_sync(dc_state);
 	mutex_lock(&dm->dc_lock);
+	dc_exit_ips_for_hw_access(dm->dc);
 	WARN_ON(!dc_commit_streams(dm->dc, dc_state->streams, dc_state->stream_count));
 
 	/* Allow idle optimization when vblank count is 0 for display off */
@@ -8875,6 +9070,19 @@
 				acrtc->otg_inst = status->primary_otg_inst;
 		}
 	}
+
+	/* During boot up and resume the DC layer will reset the panel brightness
+	 * to fix a flicker issue.
+	 * It will cause the dm->actual_brightness is not the current panel brightness
+	 * level. (the dm->brightness is the correct panel level)
+	 * So we set the backlight level with dm->brightness value after set mode
+	 */
+	if (set_backlight_level) {
+		for (i = 0; i < dm->num_of_edps; i++) {
+			if (dm->backlight_dev[i])
+				amdgpu_dm_backlight_set_level(dm, i, dm->brightness[i]);
+		}
+	}
 }
 
 static void dm_set_writeback(struct amdgpu_display_manager *dm,
@@ -9003,9 +9211,6 @@
 
 	trace_amdgpu_dm_atomic_commit_tail_begin(state);
 
-	if (dm->dc->caps.ips_support && dm->dc->idle_optimizations_allowed)
-		dc_allow_idle_optimizations(dm->dc, false);
-
 	drm_atomic_helper_update_legacy_modeset_state(dev, state);
 	drm_dp_mst_atomic_wait_for_dependencies(state);
 
@@ -9131,9 +9336,10 @@
 
 			DRM_INFO("[HDCP_DM] hdcp_update_display enable_encryption = %x\n", enable_encryption);
 
-			hdcp_update_display(
-				adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector,
-				new_con_state->hdcp_content_type, enable_encryption);
+			if (aconnector->dc_link)
+				hdcp_update_display(
+					adev->dm.hdcp_workqueue, aconnector->dc_link->link_index, aconnector,
+					new_con_state->hdcp_content_type, enable_encryption);
 		}
 	}
 
@@ -9216,6 +9422,7 @@
 
 
 		mutex_lock(&dm->dc_lock);
+		dc_exit_ips_for_hw_access(dm->dc);
 		dc_update_planes_and_stream(dm->dc,
 					    dummy_updates,
 					    status->plane_count,
@@ -10280,8 +10487,8 @@
 	int plane_src_w, plane_src_h;
 
 	dm_get_oriented_plane_size(plane_state, &plane_src_w, &plane_src_h);
-	*out_plane_scale_w = plane_state->crtc_w * 1000 / plane_src_w;
-	*out_plane_scale_h = plane_state->crtc_h * 1000 / plane_src_h;
+	*out_plane_scale_w = plane_src_w ? plane_state->crtc_w * 1000 / plane_src_w : 0;
+	*out_plane_scale_h = plane_src_h ? plane_state->crtc_h * 1000 / plane_src_h : 0;
 }
 
 static int dm_check_crtc_cursor(struct drm_atomic_state *state,
@@ -10407,6 +10614,25 @@
 	return drm_dp_mst_add_affected_dsc_crtcs(state, &aconnector->mst_root->mst_mgr);
 }
 
+static bool amdgpu_dm_crtc_mem_type_changed(struct drm_device *dev,
+					    struct drm_atomic_state *state,
+					    struct drm_crtc_state *crtc_state)
+{
+	struct drm_plane *plane;
+	struct drm_plane_state *new_plane_state, *old_plane_state;
+
+	drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) {
+		new_plane_state = drm_atomic_get_plane_state(state, plane);
+		old_plane_state = drm_atomic_get_plane_state(state, plane);
+
+		if (old_plane_state->fb && new_plane_state->fb &&
+		    get_mem_type(old_plane_state->fb) != get_mem_type(new_plane_state->fb))
+			return true;
+	}
+
+	return false;
+}
+
 /**
  * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
  *
@@ -10451,7 +10677,7 @@
 	struct dm_crtc_state *dm_old_crtc_state, *dm_new_crtc_state;
 	struct drm_dp_mst_topology_mgr *mgr;
 	struct drm_dp_mst_topology_state *mst_state;
-	struct dsc_mst_fairness_vars vars[MAX_PIPES];
+	struct dsc_mst_fairness_vars vars[MAX_PIPES] = {0};
 
 	trace_amdgpu_dm_atomic_check_begin(state);
 
@@ -10578,10 +10804,6 @@
 
 	/* Remove exiting planes if they are modified */
 	for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
-		if (old_plane_state->fb && new_plane_state->fb &&
-		    get_mem_type(old_plane_state->fb) !=
-		    get_mem_type(new_plane_state->fb))
-			lock_and_validation_needed = true;
 
 		ret = dm_update_plane_state(dc, state, plane,
 					    old_plane_state,
@@ -10834,9 +11056,11 @@
 
 		/*
 		 * Only allow async flips for fast updates that don't change
-		 * the FB pitch, the DCC state, rotation, etc.
+		 * the FB pitch, the DCC state, rotation, mem_type, etc.
 		 */
-		if (new_crtc_state->async_flip && lock_and_validation_needed) {
+		if (new_crtc_state->async_flip &&
+		    (lock_and_validation_needed ||
+		     amdgpu_dm_crtc_mem_type_changed(dev, state, new_crtc_state))) {
 			drm_dbg_atomic(crtc->dev,
 				       "[CRTC:%d:%s] async flips are only supported for fast updates\n",
 				       crtc->base.id, crtc->name);
@@ -10868,25 +11092,6 @@
 	return ret;
 }
 
-static bool is_dp_capable_without_timing_msa(struct dc *dc,
-					     struct amdgpu_dm_connector *amdgpu_dm_connector)
-{
-	u8 dpcd_data;
-	bool capable = false;
-
-	if (amdgpu_dm_connector->dc_link &&
-		dm_helpers_dp_read_dpcd(
-				NULL,
-				amdgpu_dm_connector->dc_link,
-				DP_DOWN_STREAM_PORT_COUNT,
-				&dpcd_data,
-				sizeof(dpcd_data))) {
-		capable = (dpcd_data & DP_MSA_TIMING_PAR_IGNORED) ? true:false;
-	}
-
-	return capable;
-}
-
 static bool dm_edid_parser_send_cea(struct amdgpu_display_manager *dm,
 		unsigned int offset,
 		unsigned int total_length,
@@ -11017,6 +11222,49 @@
 	return ret;
 }
 
+static void parse_edid_displayid_vrr(struct drm_connector *connector,
+		struct edid *edid)
+{
+	u8 *edid_ext = NULL;
+	int i;
+	int j = 0;
+	u16 min_vfreq;
+	u16 max_vfreq;
+
+	if (edid == NULL || edid->extensions == 0)
+		return;
+
+	/* Find DisplayID extension */
+	for (i = 0; i < edid->extensions; i++) {
+		edid_ext = (void *)(edid + (i + 1));
+		if (edid_ext[0] == DISPLAYID_EXT)
+			break;
+	}
+
+	if (edid_ext == NULL)
+		return;
+
+	while (j < EDID_LENGTH) {
+		/* Get dynamic video timing range from DisplayID if available */
+		if (EDID_LENGTH - j > 13 && edid_ext[j] == 0x25	&&
+		    (edid_ext[j+1] & 0xFE) == 0 && (edid_ext[j+2] == 9)) {
+			min_vfreq = edid_ext[j+9];
+			if (edid_ext[j+1] & 7)
+				max_vfreq = edid_ext[j+10] + ((edid_ext[j+11] & 3) << 8);
+			else
+				max_vfreq = edid_ext[j+10];
+
+			if (max_vfreq && min_vfreq) {
+				connector->display_info.monitor_range.max_vfreq = max_vfreq;
+				connector->display_info.monitor_range.min_vfreq = min_vfreq;
+
+				return;
+			}
+		}
+		j++;
+	}
+}
+
 static int parse_amd_vsdb(struct amdgpu_dm_connector *aconnector,
 			  struct edid *edid, struct amdgpu_hdmi_vsdb_info *vsdb_info)
 {
@@ -11034,7 +11282,7 @@
 			break;
 	}
 
-	while (j < EDID_LENGTH) {
+	while (j < EDID_LENGTH - sizeof(struct amd_vsdb_block)) {
 		struct amd_vsdb_block *amd_vsdb = (struct amd_vsdb_block *)&edid_ext[j];
 		unsigned int ieeeId = (amd_vsdb->ieee_id[2] << 16) | (amd_vsdb->ieee_id[1] << 8) | (amd_vsdb->ieee_id[0]);
 
@@ -11138,18 +11386,31 @@
 	if (!adev->dm.freesync_module)
 		goto update;
 
-	if (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT
-		|| sink->sink_signal == SIGNAL_TYPE_EDP) {
+	/* Some eDP panels only have the refresh rate range info in DisplayID */
+	if ((connector->display_info.monitor_range.min_vfreq == 0 ||
+	     connector->display_info.monitor_range.max_vfreq == 0))
+		parse_edid_displayid_vrr(connector, edid);
+
+	if (edid && (sink->sink_signal == SIGNAL_TYPE_DISPLAY_PORT ||
+		     sink->sink_signal == SIGNAL_TYPE_EDP)) {
 		bool edid_check_required = false;
 
-		if (edid) {
-			edid_check_required = is_dp_capable_without_timing_msa(
-						adev->dm.dc,
-						amdgpu_dm_connector);
+		if (amdgpu_dm_connector->dc_link &&
+		    amdgpu_dm_connector->dc_link->dpcd_caps.allow_invalid_MSA_timing_param) {
+			if (edid->features & DRM_EDID_FEATURE_CONTINUOUS_FREQ) {
+				amdgpu_dm_connector->min_vfreq = connector->display_info.monitor_range.min_vfreq;
+				amdgpu_dm_connector->max_vfreq = connector->display_info.monitor_range.max_vfreq;
+				if (amdgpu_dm_connector->max_vfreq -
+				    amdgpu_dm_connector->min_vfreq > 10)
+					freesync_capable = true;
+			} else {
+				edid_check_required = edid->version > 1 ||
+						      (edid->version == 1 &&
+						       edid->revision > 1);
+			}
 		}
 
-		if (edid_check_required == true && (edid->version > 1 ||
-		   (edid->version == 1 && edid->revision > 1))) {
+		if (edid_check_required) {
 			for (i = 0; i < 4; i++) {
 
 				timing	= &edid->detailed_timings[i];
@@ -11243,6 +11504,12 @@
 	if (dm_con_state)
 		dm_con_state->freesync_capable = freesync_capable;
 
+	if (connector->state && amdgpu_dm_connector->dc_link && !freesync_capable &&
+	    amdgpu_dm_connector->dc_link->replay_settings.config.replay_supported) {
+		amdgpu_dm_connector->dc_link->replay_settings.config.replay_supported = false;
+		amdgpu_dm_connector->dc_link->replay_settings.replay_feature_enabled = false;
+	}
+
 	if (connector->vrr_capable_property)
 		drm_connector_set_vrr_capable_property(connector,
 						       freesync_capable);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
@@ -50,7 +50,7 @@
 
 #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 AMD_VSDB_VERSION_3_FEATURECAP_REPLAYMODE 0x40
@@ -692,7 +692,7 @@
 	/* Cached display modes */
 	struct drm_display_mode freesync_vid_base;
 
-	int psr_skip_count;
+	int sr_skip_count;
 
 	/* Record progress status of mst*/
 	uint8_t mst_status;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -108,9 +108,10 @@
 	else if (dm->active_vblank_irq_count)
 		dm->active_vblank_irq_count--;
 
-	dc_allow_idle_optimizations(dm->dc, dm->active_vblank_irq_count == 0);
-
-	DRM_DEBUG_KMS("Allow idle optimizations (MALL): %d\n", dm->active_vblank_irq_count == 0);
+	if (dm->active_vblank_irq_count > 0) {
+		DRM_DEBUG_KMS("Allow idle optimizations (MALL): false\n");
+		dc_allow_idle_optimizations(dm->dc, false);
+	}
 
 	/*
 	 * Control PSR based on vblank requirements from OS
@@ -132,11 +133,16 @@
 #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY
 			   !amdgpu_dm_crc_window_is_activated(&vblank_work->acrtc->base) &&
 #endif
-			   vblank_work->acrtc->dm_irq_params.allow_psr_entry) {
+			   vblank_work->acrtc->dm_irq_params.allow_sr_entry) {
 			amdgpu_dm_psr_enable(vblank_work->stream);
 		}
 	}
 
+	if (dm->active_vblank_irq_count == 0) {
+		DRM_DEBUG_KMS("Allow idle optimizations (MALL): true\n");
+		dc_allow_idle_optimizations(dm->dc, true);
+	}
+
 	mutex_unlock(&dm->dc_lock);
 
 	dc_stream_release(vblank_work->stream);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -1249,7 +1249,7 @@
 				 size_t size, loff_t *pos)
 {
 	int r;
-	uint8_t data[36];
+	uint8_t data[36] = {0};
 	struct amdgpu_dm_connector *connector = file_inode(f)->i_private;
 	struct dm_crtc_state *acrtc_state;
 	uint32_t write_size = 36;
@@ -1483,7 +1483,7 @@
 	const uint32_t rd_buf_size = 10;
 	struct pipe_ctx *pipe_ctx;
 	ssize_t result = 0;
-	int i, r, str_len = 30;
+	int i, r, str_len = 10;
 
 	rd_buf = kcalloc(rd_buf_size, sizeof(char), GFP_KERNEL);
 
@@ -1495,7 +1495,9 @@
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe_ctx->stream &&
-		    pipe_ctx->stream->link == aconnector->dc_link)
+		    pipe_ctx->stream->link == aconnector->dc_link &&
+		    pipe_ctx->stream->sink &&
+		    pipe_ctx->stream->sink == aconnector->dc_sink)
 			break;
 	}
 
@@ -1596,7 +1598,9 @@
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe_ctx->stream &&
-		    pipe_ctx->stream->link == aconnector->dc_link)
+		    pipe_ctx->stream->link == aconnector->dc_link &&
+		    pipe_ctx->stream->sink &&
+		    pipe_ctx->stream->sink == aconnector->dc_sink)
 			break;
 	}
 
@@ -1681,7 +1685,9 @@
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe_ctx->stream &&
-		    pipe_ctx->stream->link == aconnector->dc_link)
+		    pipe_ctx->stream->link == aconnector->dc_link &&
+		    pipe_ctx->stream->sink &&
+		    pipe_ctx->stream->sink == aconnector->dc_sink)
 			break;
 	}
 
@@ -1780,7 +1786,9 @@
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe_ctx->stream &&
-		    pipe_ctx->stream->link == aconnector->dc_link)
+		    pipe_ctx->stream->link == aconnector->dc_link &&
+		    pipe_ctx->stream->sink &&
+		    pipe_ctx->stream->sink == aconnector->dc_sink)
 			break;
 	}
 
@@ -1865,7 +1873,9 @@
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe_ctx->stream &&
-		    pipe_ctx->stream->link == aconnector->dc_link)
+		    pipe_ctx->stream->link == aconnector->dc_link &&
+		    pipe_ctx->stream->sink &&
+		    pipe_ctx->stream->sink == aconnector->dc_sink)
 			break;
 	}
 
@@ -1964,7 +1974,9 @@
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe_ctx->stream &&
-		    pipe_ctx->stream->link == aconnector->dc_link)
+		    pipe_ctx->stream->link == aconnector->dc_link &&
+		    pipe_ctx->stream->sink &&
+		    pipe_ctx->stream->sink == aconnector->dc_sink)
 			break;
 	}
 
@@ -2045,7 +2057,9 @@
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe_ctx->stream &&
-		    pipe_ctx->stream->link == aconnector->dc_link)
+		    pipe_ctx->stream->link == aconnector->dc_link &&
+		    pipe_ctx->stream->sink &&
+		    pipe_ctx->stream->sink == aconnector->dc_sink)
 			break;
 	}
 
@@ -2141,7 +2155,9 @@
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe_ctx->stream &&
-		    pipe_ctx->stream->link == aconnector->dc_link)
+		    pipe_ctx->stream->link == aconnector->dc_link &&
+		    pipe_ctx->stream->sink &&
+		    pipe_ctx->stream->sink == aconnector->dc_sink)
 			break;
 	}
 
@@ -2220,7 +2236,9 @@
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe_ctx->stream &&
-		    pipe_ctx->stream->link == aconnector->dc_link)
+		    pipe_ctx->stream->link == aconnector->dc_link &&
+		    pipe_ctx->stream->sink &&
+		    pipe_ctx->stream->sink == aconnector->dc_sink)
 			break;
 	}
 
@@ -2276,7 +2294,9 @@
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe_ctx->stream &&
-		    pipe_ctx->stream->link == aconnector->dc_link)
+		    pipe_ctx->stream->link == aconnector->dc_link &&
+		    pipe_ctx->stream->sink &&
+		    pipe_ctx->stream->sink == aconnector->dc_sink)
 			break;
 	}
 
@@ -2347,7 +2367,9 @@
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe_ctx->stream &&
-		    pipe_ctx->stream->link == aconnector->dc_link)
+		    pipe_ctx->stream->link == aconnector->dc_link &&
+		    pipe_ctx->stream->sink &&
+		    pipe_ctx->stream->sink == aconnector->dc_sink)
 			break;
 	}
 
@@ -2418,7 +2440,9 @@
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe_ctx = &aconnector->dc_link->dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe_ctx->stream &&
-		    pipe_ctx->stream->link == aconnector->dc_link)
+		    pipe_ctx->stream->link == aconnector->dc_link &&
+		    pipe_ctx->stream->sink &&
+		    pipe_ctx->stream->sink == aconnector->dc_sink)
 			break;
 	}
 
@@ -2936,7 +2960,7 @@
 {
 	struct amdgpu_dm_connector *connector = data;
 	struct dc_link *link = connector->dc_link;
-	u32 residency;
+	u32 residency = 0;
 
 	link->dc->link_srv->edp_get_psr_residency(link, &residency);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -72,6 +72,10 @@
 		DRM_DEBUG_DRIVER("Clearing DPCD 0x317 on monitor with panel id %X\n", panel_id);
 		edid_caps->panel_patch.remove_sink_ext_caps = true;
 		break;
+	case drm_edid_encode_panel_id('S', 'D', 'C', 0x4154):
+		DRM_DEBUG_DRIVER("Disabling VSC on monitor with panel id %X\n", panel_id);
+		edid_caps->panel_patch.disable_colorimetry = true;
+		break;
 	default:
 		return;
 	}
@@ -363,7 +367,7 @@
 	mst_state = to_drm_dp_mst_topology_state(mst_mgr->base.state);
 	new_payload = drm_atomic_get_mst_payload_state(mst_state, aconnector->mst_output_port);
 
-	ret = drm_dp_add_payload_part2(mst_mgr, mst_state->base.state, new_payload);
+	ret = drm_dp_add_payload_part2(mst_mgr, new_payload);
 
 	if (ret) {
 		amdgpu_dm_set_mst_status(&aconnector->mst_status,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h
@@ -33,7 +33,7 @@
 	struct mod_vrr_params vrr_params;
 	struct dc_stream_state *stream;
 	int active_planes;
-	bool allow_psr_entry;
+	bool allow_sr_entry;
 	struct mod_freesync_config freesync_config;
 
 #ifdef CONFIG_DEBUG_FS
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -182,6 +182,8 @@
 		dc_sink_release(dc_sink);
 		aconnector->dc_sink = NULL;
 		aconnector->edid = NULL;
+		aconnector->dsc_aux = NULL;
+		port->passthrough_aux = NULL;
 	}
 
 	aconnector->mst_status = MST_STATUS_DEFAULT;
@@ -249,7 +251,7 @@
 		aconnector->dsc_aux = &aconnector->mst_root->dm_dp_aux.aux;
 
 	/* synaptics cascaded MST hub case */
-	if (!aconnector->dsc_aux && is_synaptics_cascaded_panamera(aconnector->dc_link, port))
+	if (is_synaptics_cascaded_panamera(aconnector->dc_link, port))
 		aconnector->dsc_aux = port->mgr->aux;
 
 	if (!aconnector->dsc_aux)
@@ -494,6 +496,8 @@
 		dc_sink_release(aconnector->dc_sink);
 		aconnector->dc_sink = NULL;
 		aconnector->edid = NULL;
+		aconnector->dsc_aux = NULL;
+		port->passthrough_aux = NULL;
 
 		amdgpu_dm_set_mst_status(&aconnector->mst_status,
 			MST_REMOTE_EDID | MST_ALLOCATE_NEW_PAYLOAD | MST_CLEAR_ALLOCATED_PAYLOAD,
@@ -613,6 +617,9 @@
 		&connector->base,
 		dev->mode_config.tile_property,
 		0);
+	connector->colorspace_property = master->base.colorspace_property;
+	if (connector->colorspace_property)
+		drm_connector_attach_colorspace_property(connector);
 
 	drm_connector_set_path_property(connector, pathprop);
 
@@ -1012,6 +1019,7 @@
 	int remaining_to_try = 0;
 	int ret;
 	uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
+	int var_pbn;
 
 	for (i = 0; i < count; i++) {
 		if (vars[i + k].dsc_enabled
@@ -1041,26 +1049,34 @@
 		if (next_index == -1)
 			break;
 
+		var_pbn = vars[next_index].pbn;
 		vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps, fec_overhead_multiplier_x1000);
 		ret = drm_dp_atomic_find_time_slots(state,
 						    params[next_index].port->mgr,
 						    params[next_index].port,
 						    vars[next_index].pbn);
-		if (ret < 0)
+		if (ret < 0) {
+			DRM_DEBUG_DRIVER("%s:%d MST_DSC index #%d, failed to set pbn to the state, %d\n",
+						__func__, __LINE__, next_index, ret);
+			vars[next_index].pbn = var_pbn;
 			return ret;
+		}
 
 		ret = drm_dp_mst_atomic_check(state);
 		if (ret == 0) {
 			vars[next_index].dsc_enabled = false;
 			vars[next_index].bpp_x16 = 0;
 		} else {
-			vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps, fec_overhead_multiplier_x1000);
+			vars[next_index].pbn = var_pbn;
 			ret = drm_dp_atomic_find_time_slots(state,
 							    params[next_index].port->mgr,
 							    params[next_index].port,
 							    vars[next_index].pbn);
-			if (ret < 0)
+			if (ret < 0) {
+				DRM_DEBUG_DRIVER("%s:%d MST_DSC index #%d, failed to set pbn to the state, %d\n",
+							__func__, __LINE__, next_index, ret);
 				return ret;
+			}
 		}
 
 		tried[next_index] = true;
@@ -1084,6 +1100,7 @@
 	int i, k, ret;
 	bool debugfs_overwrite = false;
 	uint16_t fec_overhead_multiplier_x1000 = get_fec_overhead_multiplier(dc_link);
+	struct drm_connector_state *new_conn_state;
 
 	memset(params, 0, sizeof(params));
 
@@ -1106,6 +1123,14 @@
 		if (!aconnector->mst_output_port)
 			continue;
 
+		new_conn_state = drm_atomic_get_new_connector_state(state, &aconnector->base);
+
+		if (!new_conn_state) {
+			DRM_DEBUG_DRIVER("%s:%d MST_DSC Skip the stream 0x%p with invalid new_conn_state\n",
+					__func__, __LINE__, stream);
+			continue;
+		}
+
 		stream->timing.flags.DSC = 0;
 
 		params[count].timing = &stream->timing;
@@ -1119,7 +1144,7 @@
 		params[count].num_slices_v = aconnector->dsc_settings.dsc_num_slices_v;
 		params[count].bpp_overwrite = aconnector->dsc_settings.dsc_bits_per_pixel;
 		params[count].compression_possible = stream->sink->dsc_caps.dsc_dec_caps.is_dsc_supported;
-		dc_dsc_get_policy_for_timing(params[count].timing, 0, &dsc_policy);
+		dc_dsc_get_policy_for_timing(params[count].timing, 0, &dsc_policy, dc_link_get_highest_encoding_format(stream->link));
 		if (!dc_dsc_compute_bandwidth_range(
 				stream->sink->ctx->dc->res_pool->dscs[0],
 				stream->sink->ctx->dc->debug.dsc_min_slice_height_override,
@@ -1135,6 +1160,8 @@
 		count++;
 	}
 
+	DRM_DEBUG_DRIVER("%s: MST_DSC Params set up for %d streams\n", __func__, count);
+
 	if (count == 0) {
 		ASSERT(0);
 		return 0;
@@ -1219,10 +1246,6 @@
 	if (dc_link->type != dc_connection_mst_branch)
 		return false;
 
-	if (!(dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT ||
-		dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT))
-		return false;
-
 	for (i = 0; i < MAX_PIPES; i++)
 		stream_on_link[i] = NULL;
 
@@ -1243,6 +1266,18 @@
 		if (!aconnector)
 			continue;
 
+		/*
+		 *	Check if cached virtual MST DSC caps are available and DSC is supported
+		 *	this change takes care of newer MST DSC capable devices that report their
+		 *	DPCD caps as per specifications in their Virtual DPCD registers.
+
+		 *	TODO: implement the check for older MST DSC devices that do not conform to
+		 *	specifications.
+		*/
+		if (!(aconnector->dc_sink->dsc_caps.dsc_dec_caps.is_dsc_supported ||
+			aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT))
+			continue;
+
 		stream_on_link[new_stream_on_link_num] = aconnector;
 		new_stream_on_link_num++;
 
@@ -1569,16 +1604,16 @@
 	return ret;
 }
 
-static unsigned int kbps_from_pbn(unsigned int pbn)
+static uint32_t kbps_from_pbn(unsigned int pbn)
 {
-	unsigned int kbps = pbn;
+	uint64_t kbps = (uint64_t)pbn;
 
 	kbps *= (1000000 / PEAK_FACTOR_X1000);
 	kbps *= 8;
 	kbps *= 54;
 	kbps /= 64;
 
-	return kbps;
+	return (uint32_t)kbps;
 }
 
 static bool is_dsc_common_config_possible(struct dc_stream_state *stream,
@@ -1586,7 +1621,7 @@
 {
 	struct dc_dsc_policy dsc_policy = {0};
 
-	dc_dsc_get_policy_for_timing(&stream->timing, 0, &dsc_policy);
+	dc_dsc_get_policy_for_timing(&stream->timing, 0, &dsc_policy, dc_link_get_highest_encoding_format(stream->link));
 	dc_dsc_compute_bandwidth_range(stream->sink->ctx->dc->res_pool->dscs[0],
 				       stream->sink->ctx->dc->debug.dsc_min_slice_height_override,
 				       dsc_policy.min_target_bpp * 16,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -28,6 +28,7 @@
 #include <drm/drm_blend.h>
 #include <drm/drm_gem_atomic_helper.h>
 #include <drm/drm_plane_helper.h>
+#include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_fourcc.h>
 
 #include "amdgpu.h"
@@ -310,8 +311,7 @@
 								     const struct plane_size *plane_size,
 								     union dc_tiling_info *tiling_info,
 								     struct dc_plane_dcc_param *dcc,
-								     struct dc_plane_address *address,
-								     const bool force_disable_dcc)
+								     struct dc_plane_address *address)
 {
 	const uint64_t modifier = afb->base.modifier;
 	int ret = 0;
@@ -319,7 +319,7 @@
 	amdgpu_dm_plane_fill_gfx9_tiling_info_from_modifier(adev, tiling_info, modifier);
 	tiling_info->gfx9.swizzle = amdgpu_dm_plane_modifier_gfx9_swizzle_mode(modifier);
 
-	if (amdgpu_dm_plane_modifier_has_dcc(modifier) && !force_disable_dcc) {
+	if (amdgpu_dm_plane_modifier_has_dcc(modifier)) {
 		uint64_t dcc_address = afb->address + afb->base.offsets[1];
 		bool independent_64b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier);
 		bool independent_128b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_128B, modifier);
@@ -765,8 +765,7 @@
 			     struct plane_size *plane_size,
 			     struct dc_plane_dcc_param *dcc,
 			     struct dc_plane_address *address,
-			     bool tmz_surface,
-			     bool force_disable_dcc)
+			     bool tmz_surface)
 {
 	const struct drm_framebuffer *fb = &afb->base;
 	int ret;
@@ -826,8 +825,7 @@
 		ret = amdgpu_dm_plane_fill_gfx9_plane_attributes_from_modifiers(adev, afb, format,
 										rotation, plane_size,
 										tiling_info, dcc,
-										address,
-										force_disable_dcc);
+										address);
 		if (ret)
 			return ret;
 	} else {
@@ -854,10 +852,14 @@
 	}
 
 	afb = to_amdgpu_framebuffer(new_state->fb);
-	obj = new_state->fb->obj[0];
+	obj = drm_gem_fb_get_obj(new_state->fb, 0);
+	if (!obj) {
+		DRM_ERROR("Failed to get obj from framebuffer\n");
+		return -EINVAL;
+	}
+
 	rbo = gem_to_amdgpu_bo(obj);
 	adev = amdgpu_ttm_adev(rbo->tbo.bdev);
-
 	r = amdgpu_bo_reserve(rbo, true);
 	if (r) {
 		dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
@@ -913,14 +915,13 @@
 	    dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) {
 		struct dc_plane_state *plane_state =
 			dm_plane_state_new->dc_state;
-		bool force_disable_dcc = !plane_state->dcc.enable;
 
 		amdgpu_dm_plane_fill_plane_buffer_attributes(
 			adev, afb, plane_state->format, plane_state->rotation,
 			afb->tiling_flags,
 			&plane_state->tiling_info, &plane_state->plane_size,
 			&plane_state->dcc, &plane_state->address,
-			afb->tmz_surface, force_disable_dcc);
+			afb->tmz_surface);
 	}
 
 	return 0;
@@ -1254,7 +1255,7 @@
 		/* turn off cursor */
 		if (crtc_state && crtc_state->stream) {
 			mutex_lock(&adev->dm.dc_lock);
-			dc_stream_set_cursor_position(crtc_state->stream,
+			dc_stream_program_cursor_position(crtc_state->stream,
 						      &position);
 			mutex_unlock(&adev->dm.dc_lock);
 		}
@@ -1280,15 +1281,16 @@
 	    adev->dm.dc->caps.color.dpp.gamma_corr)
 		attributes.attribute_flags.bits.ENABLE_CURSOR_DEGAMMA = 1;
 
-	attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0];
+	if (afb)
+		attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0];
 
 	if (crtc_state->stream) {
 		mutex_lock(&adev->dm.dc_lock);
-		if (!dc_stream_set_cursor_attributes(crtc_state->stream,
+		if (!dc_stream_program_cursor_attributes(crtc_state->stream,
 							 &attributes))
 			DRM_ERROR("DC failed to set cursor attributes\n");
 
-		if (!dc_stream_set_cursor_position(crtc_state->stream,
+		if (!dc_stream_program_cursor_position(crtc_state->stream,
 						   &position))
 			DRM_ERROR("DC failed to set cursor position\n");
 		mutex_unlock(&adev->dm.dc_lock);
@@ -1395,8 +1397,6 @@
 	const struct drm_format_info *info = drm_format_info(format);
 	int i;
 
-	enum dm_micro_swizzle microtile = amdgpu_dm_plane_modifier_gfx9_swizzle_mode(modifier) & 3;
-
 	if (!info)
 		return false;
 
@@ -1418,29 +1418,34 @@
 	if (i == plane->modifier_count)
 		return false;
 
-	/*
-	 * For D swizzle the canonical modifier depends on the bpp, so check
-	 * it here.
-	 */
-	if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) == AMD_FMT_MOD_TILE_VER_GFX9 &&
-	    adev->family >= AMDGPU_FAMILY_NV) {
-		if (microtile == MICRO_SWIZZLE_D && info->cpp[0] == 4)
-			return false;
-	}
+	/* GFX12 doesn't have these limitations. */
+	if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) <= AMD_FMT_MOD_TILE_VER_GFX11) {
+		enum dm_micro_swizzle microtile = amdgpu_dm_plane_modifier_gfx9_swizzle_mode(modifier) & 3;
 
-	if (adev->family >= AMDGPU_FAMILY_RV && microtile == MICRO_SWIZZLE_D &&
-	    info->cpp[0] < 8)
-		return false;
-
-	if (amdgpu_dm_plane_modifier_has_dcc(modifier)) {
-		/* Per radeonsi comments 16/64 bpp are more complicated. */
-		if (info->cpp[0] != 4)
-			return false;
-		/* We support multi-planar formats, but not when combined with
-		 * additional DCC metadata planes.
+		/*
+		 * For D swizzle the canonical modifier depends on the bpp, so check
+		 * it here.
 		 */
-		if (info->num_planes > 1)
+		if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) == AMD_FMT_MOD_TILE_VER_GFX9 &&
+		    adev->family >= AMDGPU_FAMILY_NV) {
+			if (microtile == MICRO_SWIZZLE_D && info->cpp[0] == 4)
+				return false;
+		}
+
+		if (adev->family >= AMDGPU_FAMILY_RV && microtile == MICRO_SWIZZLE_D &&
+		    info->cpp[0] < 8)
 			return false;
+
+		if (amdgpu_dm_plane_modifier_has_dcc(modifier)) {
+			/* Per radeonsi comments 16/64 bpp are more complicated. */
+			if (info->cpp[0] != 4)
+				return false;
+			/* We support multi-planar formats, but not when combined with
+			 * additional DCC metadata planes.
+			 */
+			if (info->num_planes > 1)
+				return false;
+		}
 	}
 
 	return true;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h
@@ -48,8 +48,7 @@
 				 struct plane_size *plane_size,
 				 struct dc_plane_dcc_param *dcc,
 				 struct dc_plane_address *address,
-				 bool tmz_surface,
-				 bool force_disable_dcc);
+				 bool tmz_surface);
 
 int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
 			 struct drm_plane *plane,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
@@ -141,9 +141,8 @@
  * amdgpu_dm_psr_enable() - enable psr f/w
  * @stream: stream state
  *
- * Return: true if success
  */
-bool amdgpu_dm_psr_enable(struct dc_stream_state *stream)
+void amdgpu_dm_psr_enable(struct dc_stream_state *stream)
 {
 	struct dc_link *link = stream->link;
 	unsigned int vsync_rate_hz = 0;
@@ -190,7 +189,10 @@
 	if (link->psr_settings.psr_version < DC_PSR_VERSION_SU_1)
 		power_opt |= psr_power_opt_z10_static_screen;
 
-	return dc_link_set_psr_allow_active(link, &psr_enable, false, false, &power_opt);
+	dc_link_set_psr_allow_active(link, &psr_enable, false, false, &power_opt);
+
+	if (link->ctx->dc->caps.ips_support)
+		dc_allow_idle_optimizations(link->ctx->dc, true);
 }
 
 /*
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.h
@@ -32,7 +32,7 @@
 #define AMDGPU_DM_PSR_ENTRY_DELAY 5
 
 void amdgpu_dm_set_psr_caps(struct dc_link *link);
-bool amdgpu_dm_psr_enable(struct dc_stream_state *stream);
+void amdgpu_dm_psr_enable(struct dc_stream_state *stream);
 bool amdgpu_dm_link_setup_psr(struct dc_stream_state *stream);
 bool amdgpu_dm_psr_disable(struct dc_stream_state *stream);
 bool amdgpu_dm_psr_disable_all(struct amdgpu_display_manager *dm);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_wb.c
@@ -76,10 +76,8 @@
 
 static int amdgpu_dm_wb_connector_get_modes(struct drm_connector *connector)
 {
-	struct drm_device *dev = connector->dev;
-
-	return drm_add_modes_noedid(connector, dev->mode_config.max_width,
-				    dev->mode_config.max_height);
+	/* Maximum resolution supported by DWB */
+	return drm_add_modes_noedid(connector, 3840, 2160);
 }
 
 static int amdgpu_dm_wb_prepare_job(struct drm_writeback_connector *wb_connector,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c
@@ -667,6 +667,9 @@
 	ss_table_header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V3 *) bios_get_image(&bp->base,
 				DATA_TABLES(ASIC_InternalSS_Info),
 				struct_size(ss_table_header_include, asSpreadSpectrum, 1)));
+	if (!ss_table_header_include)
+		return BP_RESULT_UNSUPPORTED;
+
 	table_size =
 		(le16_to_cpu(ss_table_header_include->sHeader.usStructureSize)
 				- sizeof(ATOM_COMMON_TABLE_HEADER))
@@ -1036,6 +1039,8 @@
 				&bp->base,
 				DATA_TABLES(ASIC_InternalSS_Info),
 				struct_size(header, asSpreadSpectrum, 1)));
+	if (!header)
+		return result;
 
 	memset(info, 0, sizeof(struct spread_spectrum_info));
 
@@ -1109,6 +1114,8 @@
 	get_atom_data_table_revision(header, &revision);
 
 	tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO, DATA_TABLES(SS_Info));
+	if (!tbl)
+		return result;
 
 	if (1 != revision.major || 2 > revision.minor)
 		return result;
@@ -1636,6 +1643,8 @@
 
 	tbl = GET_IMAGE(ATOM_SPREAD_SPECTRUM_INFO,
 			DATA_TABLES(SS_Info));
+	if (!tbl)
+		return number;
 
 	if (1 != revision.major || 2 > revision.minor)
 		return number;
@@ -1718,6 +1727,8 @@
 				&bp->base,
 				DATA_TABLES(ASIC_InternalSS_Info),
 				struct_size(header_include, asSpreadSpectrum, 1)));
+	if (!header_include)
+		return 0;
 
 	size = (le16_to_cpu(header_include->sHeader.usStructureSize)
 			- sizeof(ATOM_COMMON_TABLE_HEADER))
@@ -1756,6 +1767,9 @@
 	header_include = ((ATOM_ASIC_INTERNAL_SS_INFO_V3 *) bios_get_image(&bp->base,
 				DATA_TABLES(ASIC_InternalSS_Info),
 				struct_size(header_include, asSpreadSpectrum, 1)));
+	if (!header_include)
+		return number;
+
 	size = (le16_to_cpu(header_include->sHeader.usStructureSize) -
 			sizeof(ATOM_COMMON_TABLE_HEADER)) /
 					sizeof(ATOM_ASIC_SS_ASSIGNMENT_V3);
@@ -2552,8 +2566,8 @@
 
 	/* Sort voltage table from low to high*/
 	if (result == BP_RESULT_OK) {
-		uint32_t i;
-		uint32_t j;
+		int32_t i;
+		int32_t j;
 
 		for (i = 1; i < NUMBER_OF_DISP_CLK_VOLTAGE; ++i) {
 			for (j = i; j > 0; --j) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c
@@ -2922,8 +2922,11 @@
 	struct atom_common_table_header *header;
 	struct atom_data_revision revision;
 
-	uint32_t i;
-	uint32_t j;
+	int32_t i;
+	int32_t j;
+
+	if (!info)
+		return result;
 
 	if (info && DATA_TABLES(integratedsysteminfo)) {
 		header = GET_IMAGE(struct atom_common_table_header,
@@ -2948,6 +2951,7 @@
 				result = get_integrated_info_v2_1(bp, info);
 				break;
 			case 2:
+			case 3:
 				result = get_integrated_info_v2_2(bp, info);
 				break;
 			default:
@@ -3037,7 +3041,7 @@
 		struct dc_vram_info *info)
 {
 	struct bios_parser *bp = BP_FROM_DCB(dcb);
-	static enum bp_result result = BP_RESULT_BADBIOSTABLE;
+	enum bp_result result = BP_RESULT_BADBIOSTABLE;
 	struct atom_common_table_header *header;
 	struct atom_data_revision revision;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/bios/command_table.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/bios/command_table.c
@@ -37,7 +37,7 @@
 #define EXEC_BIOS_CMD_TABLE(command, params)\
 	(amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
 		GetIndexIntoMasterTable(COMMAND, command), \
-		(uint32_t *)&params) == 0)
+		(uint32_t *)&params, sizeof(params)) == 0)
 
 #define BIOS_CMD_TABLE_REVISION(command, frev, crev)\
 	amdgpu_atom_parse_cmd_header(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/bios/command_table2.c
@@ -49,7 +49,7 @@
 #define EXEC_BIOS_CMD_TABLE(fname, params)\
 	(amdgpu_atom_execute_table(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
 		GET_INDEX_INTO_MASTER_TABLE(command, fname), \
-		(uint32_t *)&params) == 0)
+		(uint32_t *)&params, sizeof(params)) == 0)
 
 #define BIOS_CMD_TABLE_REVISION(fname, frev, crev)\
 	amdgpu_atom_parse_cmd_header(((struct amdgpu_device *)bp->base.ctx->driver_context)->mode_info.atom_context, \
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dce110/dce110_clk_mgr.c
@@ -195,7 +195,7 @@
 	 * , then change minimum memory clock based on real-time bandwidth
 	 * limitation.
 	 */
-	if ((dc->ctx->asic_id.chip_family == FAMILY_AI) &&
+	if (dc->bw_vbios && (dc->ctx->asic_id.chip_family == FAMILY_AI) &&
 	     ASICREV_IS_VEGA20_P(dc->ctx->asic_id.hw_internal_rev) && (context->stream_count >= 2)) {
 		pp_display_cfg->min_memory_clock_khz = max(pp_display_cfg->min_memory_clock_khz,
 							   (uint32_t) div64_s64(
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn20/dcn20_clk_mgr.c
@@ -503,7 +503,7 @@
 
 	clk_mgr->cur_phyclk_req_table[link->link_index] = link->cur_link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ;
 
-	for (i = 0; i < MAX_PIPES * 2; i++) {
+	for (i = 0; i < MAX_LINKS; i++) {
 		if (clk_mgr->cur_phyclk_req_table[i] > max_phyclk_req)
 			max_phyclk_req = clk_mgr->cur_phyclk_req_table[i];
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn21/rn_clk_mgr.c
@@ -484,7 +484,8 @@
 			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 */
-			ranges->reader_wm_sets[num_valid_sets - 1].max_fill_clk_mhz = PP_SMU_WM_SET_RANGE_CLK_UNCONSTRAINED_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;
 		}
 		num_valid_sets++;
 	}
@@ -548,7 +549,7 @@
 
 	clk_mgr->cur_phyclk_req_table[link->link_index] = link->cur_link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ;
 
-	for (i = 0; i < MAX_PIPES * 2; i++) {
+	for (i = 0; i < MAX_LINKS; i++) {
 		if (clk_mgr->cur_phyclk_req_table[i] > max_phyclk_req)
 			max_phyclk_req = clk_mgr->cur_phyclk_req_table[i];
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c
@@ -474,7 +474,7 @@
 
 	clk_mgr->cur_phyclk_req_table[link->link_index] = link->cur_link_settings.link_rate * LINK_RATE_REF_FREQ_IN_KHZ;
 
-	for (i = 0; i < MAX_PIPES * 2; i++) {
+	for (i = 0; i < MAX_LINKS; i++) {
 		if (clk_mgr->cur_phyclk_req_table[i] > max_phyclk_req)
 			max_phyclk_req = clk_mgr->cur_phyclk_req_table[i];
 	}
@@ -560,11 +560,19 @@
 	dce_clock_read_ss_info(clk_mgr);
 
 	clk_mgr->base.bw_params = kzalloc(sizeof(*clk_mgr->base.bw_params), GFP_KERNEL);
+	if (!clk_mgr->base.bw_params) {
+		BREAK_TO_DEBUGGER();
+		return;
+	}
 
 	/* need physical address of table to give to PMFW */
 	clk_mgr->wm_range_table = dm_helpers_allocate_gpu_mem(clk_mgr->base.ctx,
 			DC_MEM_ALLOC_TYPE_GART, sizeof(WatermarksExternal_t),
 			&clk_mgr->wm_range_table_addr);
+	if (!clk_mgr->wm_range_table) {
+		BREAK_TO_DEBUGGER();
+		return;
+	}
 }
 
 void dcn3_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c
@@ -145,6 +145,10 @@
 	 */
 	clk_mgr_base->clks.zstate_support = new_clocks->zstate_support;
 	if (safe_to_lower) {
+		if (clk_mgr_base->clks.dtbclk_en && !new_clocks->dtbclk_en) {
+			dcn315_smu_set_dtbclk(clk_mgr, false);
+			clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en;
+		}
 		/* check that we're not already in lower */
 		if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_LOW_POWER) {
 			display_count = dcn315_get_active_display_cnt_wa(dc, context);
@@ -160,6 +164,10 @@
 			}
 		}
 	} else {
+		if (!clk_mgr_base->clks.dtbclk_en && new_clocks->dtbclk_en) {
+			dcn315_smu_set_dtbclk(clk_mgr, true);
+			clk_mgr_base->clks.dtbclk_en = new_clocks->dtbclk_en;
+		}
 		/* check that we're not already in D0 */
 		if (clk_mgr_base->clks.pwr_state != DCN_PWR_STATE_MISSION_MODE) {
 			union display_idle_optimization_u idle_info = { 0 };
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c
@@ -99,20 +99,25 @@
 	return display_count;
 }
 
-static void dcn316_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable)
+static void dcn316_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context,
+		bool safe_to_lower, bool disable)
 {
 	struct dc *dc = clk_mgr_base->ctx->dc;
 	int i;
 
 	for (i = 0; i < dc->res_pool->pipe_count; ++i) {
-		struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+		struct pipe_ctx *pipe = safe_to_lower
+			? &context->res_ctx.pipe_ctx[i]
+			: &dc->current_state->res_ctx.pipe_ctx[i];
 
 		if (pipe->top_pipe || pipe->prev_odm_pipe)
 			continue;
-		if (pipe->stream && (pipe->stream->dpms_off || pipe->plane_state == NULL ||
-				     dc_is_virtual_signal(pipe->stream->signal))) {
+		if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal) ||
+				     !pipe->stream->link_enc)) {
 			if (disable) {
-				pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
+				if (pipe->stream_res.tg && pipe->stream_res.tg->funcs->immediate_disable_crtc)
+					pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg);
+
 				reset_sync_context_for_pipe(dc, context, i);
 			} else
 				pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg);
@@ -207,11 +212,11 @@
 	}
 
 	if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) {
-		dcn316_disable_otg_wa(clk_mgr_base, context, true);
+		dcn316_disable_otg_wa(clk_mgr_base, context, safe_to_lower, true);
 
 		clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz;
 		dcn316_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz);
-		dcn316_disable_otg_wa(clk_mgr_base, context, false);
+		dcn316_disable_otg_wa(clk_mgr_base, context, safe_to_lower, false);
 
 		update_dispclk = true;
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
@@ -216,6 +216,16 @@
 	if (clk_mgr_base->bw_params->dc_mode_limit.dispclk_mhz > 1950)
 		clk_mgr_base->bw_params->dc_mode_limit.dispclk_mhz = 1950;
 
+	/* DPPCLK */
+	dcn32_init_single_clock(clk_mgr, PPCLK_DPPCLK,
+			&clk_mgr_base->bw_params->clk_table.entries[0].dppclk_mhz,
+			&num_entries_per_clk->num_dppclk_levels);
+	num_levels = num_entries_per_clk->num_dppclk_levels;
+	clk_mgr_base->bw_params->dc_mode_limit.dppclk_mhz = dcn30_smu_get_dc_mode_max_dpm_freq(clk_mgr, PPCLK_DPPCLK);
+	//HW recommends limit of 1950 MHz in display clock for all DCN3.2.x
+	if (clk_mgr_base->bw_params->dc_mode_limit.dppclk_mhz > 1950)
+		clk_mgr_base->bw_params->dc_mode_limit.dppclk_mhz = 1950;
+
 	if (num_entries_per_clk->num_dcfclk_levels &&
 			num_entries_per_clk->num_dtbclk_levels &&
 			num_entries_per_clk->num_dispclk_levels)
@@ -240,6 +250,10 @@
 					= khz_to_mhz_ceil(clk_mgr_base->ctx->dc->debug.min_dpp_clk_khz);
 	}
 
+	for (i = 0; i < num_levels; i++)
+		if (clk_mgr_base->bw_params->clk_table.entries[i].dppclk_mhz > 1950)
+			clk_mgr_base->bw_params->clk_table.entries[i].dppclk_mhz = 1950;
+
 	/* Get UCLK, update bounding box */
 	clk_mgr_base->funcs->get_memclk_states_from_smu(clk_mgr_base);
 
@@ -682,8 +696,12 @@
 					 * since we calculate mode support based on softmax being the max UCLK
 					 * frequency.
 					 */
-					dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
-							dc->clk_mgr->bw_params->dc_mode_softmax_memclk);
+					if (dc->debug.disable_dc_mode_overwrite) {
+						dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK, dc->clk_mgr->bw_params->max_memclk_mhz);
+						dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, dc->clk_mgr->bw_params->max_memclk_mhz);
+					} else
+						dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK,
+								dc->clk_mgr->bw_params->dc_mode_softmax_memclk);
 				} else {
 					dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, dc->clk_mgr->bw_params->max_memclk_mhz);
 				}
@@ -716,8 +734,13 @@
 		/* set UCLK to requested value if P-State switching is supported, or to re-enable P-State switching */
 		if (clk_mgr_base->clks.p_state_change_support &&
 				(update_uclk || !clk_mgr_base->clks.prev_p_state_change_support) &&
-				!dc->work_arounds.clock_update_disable_mask.uclk)
+				!dc->work_arounds.clock_update_disable_mask.uclk) {
+			if (dc->clk_mgr->dc_mode_softmax_enabled && dc->debug.disable_dc_mode_overwrite)
+				dcn30_smu_set_hard_max_by_freq(clk_mgr, PPCLK_UCLK,
+						max((int)dc->clk_mgr->bw_params->dc_mode_softmax_memclk, khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz)));
+
 			dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_UCLK, khz_to_mhz_ceil(clk_mgr_base->clks.dramclk_khz));
+		}
 
 		if (clk_mgr_base->clks.num_ways != new_clocks->num_ways &&
 				clk_mgr_base->clks.num_ways > new_clocks->num_ways) {
@@ -1153,11 +1176,19 @@
 	clk_mgr->smu_present = false;
 
 	clk_mgr->base.bw_params = kzalloc(sizeof(*clk_mgr->base.bw_params), GFP_KERNEL);
+	if (!clk_mgr->base.bw_params) {
+		BREAK_TO_DEBUGGER();
+		return;
+	}
 
 	/* need physical address of table to give to PMFW */
 	clk_mgr->wm_range_table = dm_helpers_allocate_gpu_mem(clk_mgr->base.ctx,
 			DC_MEM_ALLOC_TYPE_GART, sizeof(WatermarksExternal_t),
 			&clk_mgr->wm_range_table_addr);
+	if (!clk_mgr->wm_range_table) {
+		BREAK_TO_DEBUGGER();
+		return;
+	}
 }
 
 void dcn32_clk_mgr_destroy(struct clk_mgr_internal *clk_mgr)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
@@ -384,19 +384,6 @@
 	dcn35_smu_enable_pme_wa(clk_mgr);
 }
 
-void dcn35_init_clocks(struct clk_mgr *clk_mgr)
-{
-	uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz;
-
-	memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks));
-
-	// Assumption is that boot state always supports pstate
-	clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk;	// restore ref_dtbclk
-	clk_mgr->clks.p_state_change_support = true;
-	clk_mgr->clks.prev_p_state_change_support = true;
-	clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN;
-	clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN;
-}
 
 bool dcn35_are_clock_states_equal(struct dc_clocks *a,
 		struct dc_clocks *b)
@@ -421,7 +408,19 @@
 		struct clk_mgr_dcn35 *clk_mgr)
 {
 }
+void dcn35_init_clocks(struct clk_mgr *clk_mgr)
+{
+	uint32_t ref_dtbclk = clk_mgr->clks.ref_dtbclk_khz;
 
+	memset(&(clk_mgr->clks), 0, sizeof(struct dc_clocks));
+
+	// Assumption is that boot state always supports pstate
+	clk_mgr->clks.ref_dtbclk_khz = ref_dtbclk;	// restore ref_dtbclk
+	clk_mgr->clks.p_state_change_support = true;
+	clk_mgr->clks.prev_p_state_change_support = true;
+	clk_mgr->clks.pwr_state = DCN_PWR_STATE_UNKNOWN;
+	clk_mgr->clks.zstate_support = DCN_ZSTATE_SUPPORT_UNKNOWN;
+}
 static struct clk_bw_params dcn35_bw_params = {
 	.vram_type = Ddr4MemType,
 	.num_channels = 1,
@@ -706,7 +705,7 @@
 		clock_table->NumFclkLevelsEnabled;
 	max_fclk = find_max_clk_value(clock_table->FclkClocks_Freq, num_fclk);
 
-	num_dcfclk = (clock_table->NumFclkLevelsEnabled > NUM_DCFCLK_DPM_LEVELS) ? NUM_DCFCLK_DPM_LEVELS :
+	num_dcfclk = (clock_table->NumDcfClkLevelsEnabled > NUM_DCFCLK_DPM_LEVELS) ? NUM_DCFCLK_DPM_LEVELS :
 		clock_table->NumDcfClkLevelsEnabled;
 	for (i = 0; i < num_dcfclk; i++) {
 		int j;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -212,7 +212,8 @@
 		connectors_num,
 		num_virtual_links);
 
-	for (i = 0; i < connectors_num; i++) {
+	// condition loop on link_count to allow skipping invalid indices
+	for (i = 0; dc->link_count < connectors_num && i < MAX_LINKS; i++) {
 		struct link_init_data link_init_params = {0};
 		struct dc_link *link;
 
@@ -411,9 +412,14 @@
 	 * avoid conflicting with firmware updates.
 	 */
 	if (dc->ctx->dce_version > DCE_VERSION_MAX)
-		if (dc->optimized_required || dc->wm_optimized_required)
+		if (dc->optimized_required)
 			return false;
 
+	if (!memcmp(&stream->adjust, adjust, sizeof(*adjust)))
+		return true;
+
+	dc_exit_ips_for_hw_access(dc);
+
 	stream->adjust.v_total_max = adjust->v_total_max;
 	stream->adjust.v_total_mid = adjust->v_total_mid;
 	stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num;
@@ -454,6 +460,8 @@
 
 	int i = 0;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	for (i = 0; i < MAX_PIPES; i++) {
 		struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
 
@@ -484,6 +492,8 @@
 	bool ret = false;
 	struct crtc_position position;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	for (i = 0; i < MAX_PIPES; i++) {
 		struct pipe_ctx *pipe =
 				&dc->current_state->res_ctx.pipe_ctx[i];
@@ -603,6 +613,8 @@
 	if (pipe == NULL)
 		return false;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	/* By default, capture the full frame */
 	param.windowa_x_start = 0;
 	param.windowa_y_start = 0;
@@ -662,6 +674,8 @@
 	struct pipe_ctx *pipe;
 	struct timing_generator *tg;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	for (i = 0; i < MAX_PIPES; i++) {
 		pipe = &dc->current_state->res_ctx.pipe_ctx[i];
 		if (pipe->stream == stream)
@@ -686,6 +700,8 @@
 	int i;
 	struct pipe_ctx *pipe_ctx;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	for (i = 0; i < MAX_PIPES; i++) {
 		if (dc->current_state->res_ctx.pipe_ctx[i].stream
 				== stream) {
@@ -721,6 +737,8 @@
 	if (option > DITHER_OPTION_MAX)
 		return;
 
+	dc_exit_ips_for_hw_access(stream->ctx->dc);
+
 	stream->dither_option = option;
 
 	memset(&params, 0, sizeof(params));
@@ -745,6 +763,8 @@
 	bool ret = false;
 	struct pipe_ctx *pipes;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	for (i = 0; i < MAX_PIPES; i++) {
 		if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) {
 			pipes = &dc->current_state->res_ctx.pipe_ctx[i];
@@ -762,6 +782,8 @@
 	bool ret = false;
 	struct pipe_ctx *pipes;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	for (i = 0; i < MAX_PIPES; i++) {
 		if (dc->current_state->res_ctx.pipe_ctx[i].stream
 				== stream) {
@@ -788,6 +810,8 @@
 	struct pipe_ctx *pipes_affected[MAX_PIPES];
 	int num_pipes_affected = 0;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	for (i = 0; i < num_streams; i++) {
 		struct dc_stream_state *stream = streams[i];
 
@@ -1282,6 +1306,54 @@
 	}
 }
 
+/**
+ * wait_for_blank_complete - wait for all active OPPs to finish pending blank
+ * pattern updates
+ *
+ * @dc: [in] dc reference
+ * @context: [in] hardware context in use
+ */
+static void wait_for_blank_complete(struct dc *dc,
+		struct dc_state *context)
+{
+	struct pipe_ctx *opp_head;
+	struct dce_hwseq *hws = dc->hwseq;
+	int i;
+
+	if (!hws->funcs.wait_for_blank_complete)
+		return;
+
+	for (i = 0; i < MAX_PIPES; i++) {
+		opp_head = &context->res_ctx.pipe_ctx[i];
+
+		if (!resource_is_pipe_type(opp_head, OPP_HEAD) ||
+				dc_state_get_pipe_subvp_type(context, opp_head) == SUBVP_PHANTOM)
+			continue;
+
+		hws->funcs.wait_for_blank_complete(opp_head->stream_res.opp);
+	}
+}
+
+static void wait_for_odm_update_pending_complete(struct dc *dc, struct dc_state *context)
+{
+	struct pipe_ctx *otg_master;
+	struct timing_generator *tg;
+	int i;
+
+	for (i = 0; i < MAX_PIPES; i++) {
+		otg_master = &context->res_ctx.pipe_ctx[i];
+		if (!resource_is_pipe_type(otg_master, OTG_MASTER) ||
+				dc_state_get_pipe_subvp_type(context, otg_master) == SUBVP_PHANTOM)
+			continue;
+		tg = otg_master->stream_res.tg;
+		if (tg->funcs->wait_odm_doublebuffer_pending_clear)
+			tg->funcs->wait_odm_doublebuffer_pending_clear(tg);
+	}
+
+	/* ODM update may require to reprogram blank pattern for each OPP */
+	wait_for_blank_complete(dc, context);
+}
+
 static void wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context)
 {
 	int i;
@@ -1319,6 +1391,7 @@
 		return NULL;
 
 	if (init_params->dce_environment == DCE_ENV_VIRTUAL_HW) {
+		dc->caps.linear_pitch_alignment = 64;
 		if (!dc_construct_ctx(dc, init_params))
 			goto destruct_dc;
 	} else {
@@ -1713,7 +1786,7 @@
 		if (crtc_timing->pix_clk_100hz != pix_clk_100hz)
 			return false;
 
-		if (!se->funcs->dp_get_pixel_format)
+		if (!se || !se->funcs->dp_get_pixel_format)
 			return false;
 
 		if (!se->funcs->dp_get_pixel_format(
@@ -1733,6 +1806,9 @@
 		return false;
 	}
 
+	if (link->dpcd_caps.channel_coding_cap.bits.DP_128b_132b_SUPPORTED)
+		return false;
+
 	if (dc->link_srv->edp_is_ilr_optimization_required(link, crtc_timing)) {
 		DC_LOG_EVENT_LINK_TRAINING("Seamless boot disabled to optimize eDP link rate\n");
 		return false;
@@ -1766,6 +1842,8 @@
 	int i, j;
 	struct pipe_ctx *pipe;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	for (i = 0; i < MAX_PIPES; i++) {
 		if (context != NULL) {
 			pipe = &context->res_ctx.pipe_ctx[i];
@@ -1785,6 +1863,8 @@
 void dc_trigger_sync(struct dc *dc, struct dc_state *context)
 {
 	if (context->stream_count > 1 && !dc->debug.disable_timing_sync) {
+		dc_exit_ips_for_hw_access(dc);
+
 		enable_timing_multisync(dc, context);
 		program_timing_sync(dc, context);
 	}
@@ -1965,10 +2045,15 @@
 
 	dc_enable_stereo(dc, context, dc_streams, context->stream_count);
 
-	if (context->stream_count > get_seamless_boot_stream_count(context) ||
+	if (get_seamless_boot_stream_count(context) == 0 ||
 		context->stream_count == 0) {
 		/* Must wait for no flips to be pending before doing optimize bw */
 		wait_for_no_pipes_pending(dc, context);
+		/*
+		 * optimized dispclk depends on ODM setup. Need to wait for ODM
+		 * update pending complete before optimizing bandwidth.
+		 */
+		wait_for_odm_update_pending_complete(dc, context);
 		/* pplib is notified if disp_num changed */
 		dc->hwss.optimize_bandwidth(dc, context);
 		/* Need to do otg sync again as otg could be out of sync due to otg
@@ -2041,6 +2126,8 @@
 	if (!streams_changed(dc, streams, stream_count))
 		return res;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	DC_LOG_DC("%s: %d streams\n", __func__, stream_count);
 
 	for (i = 0; i < stream_count; i++) {
@@ -2227,7 +2314,6 @@
 	}
 
 	dc->optimized_required = false;
-	dc->wm_optimized_required = false;
 }
 
 bool dc_set_generic_gpio_for_stereo(bool enable,
@@ -2650,8 +2736,6 @@
 		} else if (memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0) {
 			dc->optimized_required = true;
 		}
-
-		dc->optimized_required |= dc->wm_optimized_required;
 	}
 
 	return type;
@@ -2859,9 +2943,6 @@
 	if (update->vrr_active_fixed)
 		stream->vrr_active_fixed = *update->vrr_active_fixed;
 
-	if (update->crtc_timing_adjust)
-		stream->adjust = *update->crtc_timing_adjust;
-
 	if (update->dpms_off)
 		stream->dpms_off = *update->dpms_off;
 
@@ -2922,7 +3003,7 @@
 }
 
 static void backup_plane_states_for_stream(
-		struct dc_plane_state plane_states[MAX_SURFACE_NUM],
+		struct dc_plane_state plane_states[MAX_SURFACES],
 		struct dc_stream_state *stream)
 {
 	int i;
@@ -2936,7 +3017,7 @@
 }
 
 static void restore_plane_states_for_stream(
-		struct dc_plane_state plane_states[MAX_SURFACE_NUM],
+		struct dc_plane_state plane_states[MAX_SURFACES],
 		struct dc_stream_state *stream)
 {
 	int i;
@@ -2945,8 +3026,12 @@
 	if (!status)
 		return;
 
-	for (i = 0; i < status->plane_count; i++)
+	for (i = 0; i < status->plane_count; i++) {
+		/* refcount will always be valid, restore everything else */
+		struct kref refcount = status->plane_states[i]->refcount;
 		*status->plane_states[i] = plane_states[i];
+		status->plane_states[i]->refcount = refcount;
+	}
 }
 
 static bool update_planes_and_stream_state(struct dc *dc,
@@ -3223,6 +3308,9 @@
 	if (stream->link->replay_settings.config.replay_supported)
 		return true;
 
+	if (stream->ctx->dce_version >= DCN_VERSION_3_5 && stream->abm_level)
+		return true;
+
 	return false;
 }
 
@@ -3376,6 +3464,8 @@
 	int i, j;
 	struct pipe_ctx *top_pipe_to_program = NULL;
 	struct dc_stream_status *stream_status = NULL;
+	dc_exit_ips_for_hw_access(dc);
+
 	dc_z10_restore(dc);
 
 	top_pipe_to_program = resource_get_otg_master_for_stream(
@@ -3418,23 +3508,26 @@
 
 	stream_status = dc_state_get_stream_status(context, stream);
 
-	build_dmub_cmd_list(dc,
-			srf_updates,
-			surface_count,
-			stream,
-			context,
-			context->dc_dmub_cmd,
-			&(context->dmub_cmd_count));
-	hwss_build_fast_sequence(dc,
-			context->dc_dmub_cmd,
-			context->dmub_cmd_count,
-			context->block_sequence,
-			&(context->block_sequence_steps),
-			top_pipe_to_program,
-			stream_status);
-	hwss_execute_sequence(dc,
-			context->block_sequence,
-			context->block_sequence_steps);
+	if (stream_status) {
+		build_dmub_cmd_list(dc,
+				srf_updates,
+				surface_count,
+				stream,
+				context,
+				context->dc_dmub_cmd,
+				&(context->dmub_cmd_count));
+		hwss_build_fast_sequence(dc,
+				context->dc_dmub_cmd,
+				context->dmub_cmd_count,
+				context->block_sequence,
+				&(context->block_sequence_steps),
+				top_pipe_to_program,
+				stream_status);
+		hwss_execute_sequence(dc,
+				context->block_sequence,
+				context->block_sequence_steps);
+	}
+
 	/* Clear update flags so next flip doesn't have redundant programming
 	 * (if there's no stream update, the update flags are not cleared).
 	 * Surface updates are cleared unconditionally at the beginning of each flip,
@@ -3444,7 +3537,7 @@
 		top_pipe_to_program->stream->update_flags.raw = 0;
 }
 
-static void wait_for_outstanding_hw_updates(struct dc *dc, const struct dc_state *dc_context)
+static void wait_for_outstanding_hw_updates(struct dc *dc, struct dc_state *dc_context)
 {
 /*
  * This function calls HWSS to wait for any potentially double buffered
@@ -3482,6 +3575,7 @@
 			}
 		}
 	}
+	wait_for_odm_update_pending_complete(dc, dc_context);
 }
 
 static void commit_planes_for_stream(struct dc *dc,
@@ -3503,6 +3597,8 @@
 	// dc->current_state anymore, so we have to cache it before we apply
 	// the new SubVP context
 	subvp_prev_use = false;
+	dc_exit_ips_for_hw_access(dc);
+
 	dc_z10_restore(dc);
 	if (update_type == UPDATE_TYPE_FULL)
 		wait_for_outstanding_hw_updates(dc, context);
@@ -3772,7 +3868,8 @@
 	}
 
 	if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed)
-		if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
+		if (top_pipe_to_program &&
+		    top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) {
 			top_pipe_to_program->stream_res.tg->funcs->wait_for_state(
 				top_pipe_to_program->stream_res.tg,
 				CRTC_STATE_VACTIVE);
@@ -4293,8 +4390,7 @@
 			stream_update->mst_bw_update ||
 			stream_update->func_shaper ||
 			stream_update->lut3d_func ||
-			stream_update->pending_test_pattern ||
-			stream_update->crtc_timing_adjust))
+			stream_update->pending_test_pattern))
 		return true;
 
 	if (stream) {
@@ -4384,6 +4480,8 @@
 	bool is_plane_addition = 0;
 	bool is_fast_update_only;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	populate_fast_updates(fast_update, srf_updates, surface_count, stream_update);
 	is_fast_update_only = fast_update_only(dc, fast_update, srf_updates,
 			surface_count, stream_update, stream);
@@ -4504,6 +4602,8 @@
 	int i, j;
 	struct dc_fast_update fast_update[MAX_SURFACES] = {0};
 
+	dc_exit_ips_for_hw_access(dc);
+
 	populate_fast_updates(fast_update, srf_updates, surface_count, stream_update);
 	stream_status = dc_stream_get_status(stream);
 	context = dc->current_state;
@@ -4688,6 +4788,8 @@
 	case DC_ACPI_CM_POWER_STATE_D0:
 		dc_state_construct(dc, dc->current_state);
 
+		dc_exit_ips_for_hw_access(dc);
+
 		dc_z10_restore(dc);
 
 		dc->hwss.init_hw(dc);
@@ -4825,28 +4927,29 @@
 	if (allow == dc->idle_optimizations_allowed)
 		return;
 
-	if (dc->hwss.apply_idle_power_optimizations && dc->hwss.apply_idle_power_optimizations(dc, allow))
+	if (dc->hwss.apply_idle_power_optimizations && dc->clk_mgr != NULL &&
+	    dc->hwss.apply_idle_power_optimizations(dc, allow))
 		dc->idle_optimizations_allowed = allow;
 }
 
-bool dc_dmub_is_ips_idle_state(struct dc *dc)
+void dc_exit_ips_for_hw_access(struct dc *dc)
 {
-	uint32_t idle_state = 0;
+	if (dc->caps.ips_support)
+		dc_allow_idle_optimizations(dc, false);
+}
 
+bool dc_dmub_is_ips_idle_state(struct dc *dc)
+{
 	if (dc->debug.disable_idle_power_optimizations)
 		return false;
 
 	if (!dc->caps.ips_support || (dc->config.disable_ips == DMUB_IPS_DISABLE_ALL))
 		return false;
 
-	if (dc->hwss.get_idle_state)
-		idle_state = dc->hwss.get_idle_state(dc);
-
-	if (!(idle_state & DMUB_IPS1_ALLOW_MASK) ||
-		!(idle_state & DMUB_IPS2_ALLOW_MASK))
-		return true;
+	if (!dc->ctx->dmub_srv)
+		return false;
 
-	return false;
+	return dc->ctx->dmub_srv->idle_allowed;
 }
 
 /* set min and max memory clock to lowest and highest DPM level, respectively */
@@ -5445,3 +5548,20 @@
 	return profile;
 }
 
+/*
+ **********************************************************************************
+ * dc_get_det_buffer_size_from_state() - extracts detile buffer size from dc state
+ *
+ * Called when DM wants to log detile buffer size from dc_state
+ *
+ **********************************************************************************
+ */
+unsigned int dc_get_det_buffer_size_from_state(const struct dc_state *context)
+{
+	struct dc *dc = context->clk_mgr->ctx->dc;
+
+	if (dc->res_pool->funcs->get_det_buffer_size)
+		return dc->res_pool->funcs->get_det_buffer_size(context);
+	else
+		return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_debug.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/core/dc_debug.c
@@ -434,3 +434,43 @@
 
 	return "Unexpected status error";
 }
+
+char *dc_pixel_encoding_to_str(enum dc_pixel_encoding pixel_encoding)
+{
+	switch (pixel_encoding) {
+	case PIXEL_ENCODING_RGB:
+		return "RGB";
+	case PIXEL_ENCODING_YCBCR422:
+		return "YUV422";
+	case PIXEL_ENCODING_YCBCR444:
+		return "YUV444";
+	case PIXEL_ENCODING_YCBCR420:
+		return "YUV420";
+	default:
+		return "Unknown";
+	}
+}
+
+char *dc_color_depth_to_str(enum dc_color_depth color_depth)
+{
+	switch (color_depth) {
+	case COLOR_DEPTH_666:
+		return "6-bpc";
+	case COLOR_DEPTH_888:
+		return "8-bpc";
+	case COLOR_DEPTH_101010:
+		return "10-bpc";
+	case COLOR_DEPTH_121212:
+		return "12-bpc";
+	case COLOR_DEPTH_141414:
+		return "14-bpc";
+	case COLOR_DEPTH_161616:
+		return "16-bpc";
+	case COLOR_DEPTH_999:
+		return "9-bpc";
+	case COLOR_DEPTH_111111:
+		return "11-bpc";
+	default:
+		return "Unknown";
+	}
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -602,57 +602,59 @@
 	while (current_pipe) {
 		current_mpc_pipe = current_pipe;
 		while (current_mpc_pipe) {
-			if (dc->hwss.set_flip_control_gsl && current_mpc_pipe->plane_state && current_mpc_pipe->plane_state->update_flags.raw) {
-				block_sequence[*num_steps].params.set_flip_control_gsl_params.pipe_ctx = current_mpc_pipe;
-				block_sequence[*num_steps].params.set_flip_control_gsl_params.flip_immediate = current_mpc_pipe->plane_state->flip_immediate;
-				block_sequence[*num_steps].func = HUBP_SET_FLIP_CONTROL_GSL;
-				(*num_steps)++;
-			}
-			if (dc->hwss.program_triplebuffer && dc->debug.enable_tri_buf && current_mpc_pipe->plane_state->update_flags.raw) {
-				block_sequence[*num_steps].params.program_triplebuffer_params.dc = dc;
-				block_sequence[*num_steps].params.program_triplebuffer_params.pipe_ctx = current_mpc_pipe;
-				block_sequence[*num_steps].params.program_triplebuffer_params.enableTripleBuffer = current_mpc_pipe->plane_state->triplebuffer_flips;
-				block_sequence[*num_steps].func = HUBP_PROGRAM_TRIPLEBUFFER;
-				(*num_steps)++;
-			}
-			if (dc->hwss.update_plane_addr && current_mpc_pipe->plane_state->update_flags.bits.addr_update) {
-				if (resource_is_pipe_type(current_mpc_pipe, OTG_MASTER) &&
-						stream_status->mall_stream_config.type == SUBVP_MAIN) {
-					block_sequence[*num_steps].params.subvp_save_surf_addr.dc_dmub_srv = dc->ctx->dmub_srv;
-					block_sequence[*num_steps].params.subvp_save_surf_addr.addr = &current_mpc_pipe->plane_state->address;
-					block_sequence[*num_steps].params.subvp_save_surf_addr.subvp_index = current_mpc_pipe->subvp_index;
-					block_sequence[*num_steps].func = DMUB_SUBVP_SAVE_SURF_ADDR;
+			if (current_mpc_pipe->plane_state) {
+				if (dc->hwss.set_flip_control_gsl && current_mpc_pipe->plane_state->update_flags.raw) {
+					block_sequence[*num_steps].params.set_flip_control_gsl_params.pipe_ctx = current_mpc_pipe;
+					block_sequence[*num_steps].params.set_flip_control_gsl_params.flip_immediate = current_mpc_pipe->plane_state->flip_immediate;
+					block_sequence[*num_steps].func = HUBP_SET_FLIP_CONTROL_GSL;
+					(*num_steps)++;
+				}
+				if (dc->hwss.program_triplebuffer && dc->debug.enable_tri_buf && current_mpc_pipe->plane_state->update_flags.raw) {
+					block_sequence[*num_steps].params.program_triplebuffer_params.dc = dc;
+					block_sequence[*num_steps].params.program_triplebuffer_params.pipe_ctx = current_mpc_pipe;
+					block_sequence[*num_steps].params.program_triplebuffer_params.enableTripleBuffer = current_mpc_pipe->plane_state->triplebuffer_flips;
+					block_sequence[*num_steps].func = HUBP_PROGRAM_TRIPLEBUFFER;
+					(*num_steps)++;
+				}
+				if (dc->hwss.update_plane_addr && current_mpc_pipe->plane_state->update_flags.bits.addr_update) {
+					if (resource_is_pipe_type(current_mpc_pipe, OTG_MASTER) &&
+							stream_status->mall_stream_config.type == SUBVP_MAIN) {
+						block_sequence[*num_steps].params.subvp_save_surf_addr.dc_dmub_srv = dc->ctx->dmub_srv;
+						block_sequence[*num_steps].params.subvp_save_surf_addr.addr = &current_mpc_pipe->plane_state->address;
+						block_sequence[*num_steps].params.subvp_save_surf_addr.subvp_index = current_mpc_pipe->subvp_index;
+						block_sequence[*num_steps].func = DMUB_SUBVP_SAVE_SURF_ADDR;
+						(*num_steps)++;
+					}
+
+					block_sequence[*num_steps].params.update_plane_addr_params.dc = dc;
+					block_sequence[*num_steps].params.update_plane_addr_params.pipe_ctx = current_mpc_pipe;
+					block_sequence[*num_steps].func = HUBP_UPDATE_PLANE_ADDR;
 					(*num_steps)++;
 				}
 
-				block_sequence[*num_steps].params.update_plane_addr_params.dc = dc;
-				block_sequence[*num_steps].params.update_plane_addr_params.pipe_ctx = current_mpc_pipe;
-				block_sequence[*num_steps].func = HUBP_UPDATE_PLANE_ADDR;
-				(*num_steps)++;
-			}
-
-			if (hws->funcs.set_input_transfer_func && current_mpc_pipe->plane_state->update_flags.bits.gamma_change) {
-				block_sequence[*num_steps].params.set_input_transfer_func_params.dc = dc;
-				block_sequence[*num_steps].params.set_input_transfer_func_params.pipe_ctx = current_mpc_pipe;
-				block_sequence[*num_steps].params.set_input_transfer_func_params.plane_state = current_mpc_pipe->plane_state;
-				block_sequence[*num_steps].func = DPP_SET_INPUT_TRANSFER_FUNC;
-				(*num_steps)++;
-			}
+				if (hws->funcs.set_input_transfer_func && current_mpc_pipe->plane_state->update_flags.bits.gamma_change) {
+					block_sequence[*num_steps].params.set_input_transfer_func_params.dc = dc;
+					block_sequence[*num_steps].params.set_input_transfer_func_params.pipe_ctx = current_mpc_pipe;
+					block_sequence[*num_steps].params.set_input_transfer_func_params.plane_state = current_mpc_pipe->plane_state;
+					block_sequence[*num_steps].func = DPP_SET_INPUT_TRANSFER_FUNC;
+					(*num_steps)++;
+				}
 
-			if (dc->hwss.program_gamut_remap && current_mpc_pipe->plane_state->update_flags.bits.gamut_remap_change) {
-				block_sequence[*num_steps].params.program_gamut_remap_params.pipe_ctx = current_mpc_pipe;
-				block_sequence[*num_steps].func = DPP_PROGRAM_GAMUT_REMAP;
-				(*num_steps)++;
-			}
-			if (current_mpc_pipe->plane_state->update_flags.bits.input_csc_change) {
-				block_sequence[*num_steps].params.setup_dpp_params.pipe_ctx = current_mpc_pipe;
-				block_sequence[*num_steps].func = DPP_SETUP_DPP;
-				(*num_steps)++;
-			}
-			if (current_mpc_pipe->plane_state->update_flags.bits.coeff_reduction_change) {
-				block_sequence[*num_steps].params.program_bias_and_scale_params.pipe_ctx = current_mpc_pipe;
-				block_sequence[*num_steps].func = DPP_PROGRAM_BIAS_AND_SCALE;
-				(*num_steps)++;
+				if (dc->hwss.program_gamut_remap && current_mpc_pipe->plane_state->update_flags.bits.gamut_remap_change) {
+					block_sequence[*num_steps].params.program_gamut_remap_params.pipe_ctx = current_mpc_pipe;
+					block_sequence[*num_steps].func = DPP_PROGRAM_GAMUT_REMAP;
+					(*num_steps)++;
+				}
+				if (current_mpc_pipe->plane_state->update_flags.bits.input_csc_change) {
+					block_sequence[*num_steps].params.setup_dpp_params.pipe_ctx = current_mpc_pipe;
+					block_sequence[*num_steps].func = DPP_SETUP_DPP;
+					(*num_steps)++;
+				}
+				if (current_mpc_pipe->plane_state->update_flags.bits.coeff_reduction_change) {
+					block_sequence[*num_steps].params.program_bias_and_scale_params.pipe_ctx = current_mpc_pipe;
+					block_sequence[*num_steps].func = DPP_PROGRAM_BIAS_AND_SCALE;
+					(*num_steps)++;
+				}
 			}
 			if (hws->funcs.set_output_transfer_func && current_mpc_pipe->stream->update_flags.bits.out_tf) {
 				block_sequence[*num_steps].params.set_output_transfer_func_params.dc = dc;
@@ -830,6 +832,9 @@
 	struct dpp *dpp = pipe_ctx->plane_res.dpp;
 	struct dc_plane_state *plane_state = pipe_ctx->plane_state;
 
+	if (!plane_state)
+		return;
+
 	if (dpp && dpp->funcs->dpp_setup) {
 		// program the input csc
 		dpp->funcs->dpp_setup(dpp,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/core/dc_link_exports.c
@@ -37,6 +37,9 @@
 #include "dce/dce_i2c.h"
 struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_index)
 {
+	if (link_index >= MAX_LINKS)
+		return NULL;
+
 	return dc->links[link_index];
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -750,25 +750,6 @@
 		*flip_horz_scan_dir = !*flip_horz_scan_dir;
 }
 
-/*
- * This is a preliminary vp size calculation to allow us to check taps support.
- * The result is completely overridden afterwards.
- */
-static void calculate_viewport_size(struct pipe_ctx *pipe_ctx)
-{
-	struct scaler_data *data = &pipe_ctx->plane_res.scl_data;
-
-	data->viewport.width = dc_fixpt_ceil(dc_fixpt_mul_int(data->ratios.horz, data->recout.width));
-	data->viewport.height = dc_fixpt_ceil(dc_fixpt_mul_int(data->ratios.vert, data->recout.height));
-	data->viewport_c.width = dc_fixpt_ceil(dc_fixpt_mul_int(data->ratios.horz_c, data->recout.width));
-	data->viewport_c.height = dc_fixpt_ceil(dc_fixpt_mul_int(data->ratios.vert_c, data->recout.height));
-	if (pipe_ctx->plane_state->rotation == ROTATION_ANGLE_90 ||
-			pipe_ctx->plane_state->rotation == ROTATION_ANGLE_270) {
-		swap(data->viewport.width, data->viewport.height);
-		swap(data->viewport_c.width, data->viewport_c.height);
-	}
-}
-
 static struct rect intersect_rec(const struct rect *r0, const struct rect *r1)
 {
 	struct rect rec;
@@ -1478,6 +1459,7 @@
 	const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
 	struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
 	const struct rect odm_slice_rec = calculate_odm_slice_in_timing_active(pipe_ctx);
+	struct scaling_taps temp = {0};
 	bool res = false;
 	DC_LOGGER_INIT(pipe_ctx->stream->ctx->logger);
 
@@ -1509,8 +1491,6 @@
 	calculate_recout(pipe_ctx);
 	/* depends on pixel format */
 	calculate_scaling_ratios(pipe_ctx);
-	/* depends on scaling ratios and recout, does not calculate offset yet */
-	calculate_viewport_size(pipe_ctx);
 
 	/*
 	 * LB calculations depend on vp size, h/v_active and scaling ratios
@@ -1531,6 +1511,24 @@
 
 	pipe_ctx->plane_res.scl_data.lb_params.alpha_en = plane_state->per_pixel_alpha;
 
+	// get TAP value with 100x100 dummy data for max scaling qualify, override
+	// if a new scaling quality required
+	pipe_ctx->plane_res.scl_data.viewport.width = 100;
+	pipe_ctx->plane_res.scl_data.viewport.height = 100;
+	pipe_ctx->plane_res.scl_data.viewport_c.width = 100;
+	pipe_ctx->plane_res.scl_data.viewport_c.height = 100;
+	if (pipe_ctx->plane_res.xfm != NULL)
+		res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
+				pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
+
+	if (pipe_ctx->plane_res.dpp != NULL)
+		res = pipe_ctx->plane_res.dpp->funcs->dpp_get_optimal_number_of_taps(
+				pipe_ctx->plane_res.dpp, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
+
+	temp = pipe_ctx->plane_res.scl_data.taps;
+
+	calculate_inits_and_viewports(pipe_ctx);
+
 	if (pipe_ctx->plane_res.xfm != NULL)
 		res = pipe_ctx->plane_res.xfm->funcs->transform_get_optimal_number_of_taps(
 				pipe_ctx->plane_res.xfm, &pipe_ctx->plane_res.scl_data, &plane_state->scaling_quality);
@@ -1557,11 +1555,14 @@
 					&plane_state->scaling_quality);
 	}
 
-	/*
-	 * Depends on recout, scaling ratios, h_active and taps
-	 * May need to re-check lb size after this in some obscure scenario
-	 */
-	if (res)
+	/* Ignore scaler failure if pipe context plane is phantom plane */
+	if (!res && plane_state->is_phantom)
+		res = true;
+
+	if (res && (pipe_ctx->plane_res.scl_data.taps.v_taps != temp.v_taps ||
+		pipe_ctx->plane_res.scl_data.taps.h_taps != temp.h_taps ||
+		pipe_ctx->plane_res.scl_data.taps.v_taps_c != temp.v_taps_c ||
+		pipe_ctx->plane_res.scl_data.taps.h_taps_c != temp.h_taps_c))
 		calculate_inits_and_viewports(pipe_ctx);
 
 	/*
@@ -2179,50 +2180,98 @@
 	}
 }
 
-void resource_log_pipe_topology_update(struct dc *dc, struct dc_state *state)
+static void resource_log_pipe_for_stream(struct dc *dc, struct dc_state *state,
+		struct pipe_ctx *otg_master, int stream_idx)
 {
-	struct pipe_ctx *otg_master;
 	struct pipe_ctx *opp_heads[MAX_PIPES];
 	struct pipe_ctx *dpp_pipes[MAX_PIPES];
 
-	int stream_idx, slice_idx, dpp_idx, plane_idx, slice_count, dpp_count;
+	int slice_idx, dpp_idx, plane_idx, slice_count, dpp_count;
 	bool is_primary;
 	DC_LOGGER_INIT(dc->ctx->logger);
 
+	slice_count = resource_get_opp_heads_for_otg_master(otg_master,
+			&state->res_ctx, opp_heads);
+	for (slice_idx = 0; slice_idx < slice_count; slice_idx++) {
+		plane_idx = -1;
+		if (opp_heads[slice_idx]->plane_state) {
+			dpp_count = resource_get_dpp_pipes_for_opp_head(
+					opp_heads[slice_idx],
+					&state->res_ctx,
+					dpp_pipes);
+			for (dpp_idx = 0; dpp_idx < dpp_count; dpp_idx++) {
+				is_primary = !dpp_pipes[dpp_idx]->top_pipe ||
+						dpp_pipes[dpp_idx]->top_pipe->plane_state != dpp_pipes[dpp_idx]->plane_state;
+				if (is_primary)
+					plane_idx++;
+				resource_log_pipe(dc, dpp_pipes[dpp_idx],
+						stream_idx, slice_idx,
+						plane_idx, slice_count,
+						is_primary);
+			}
+		} else {
+			resource_log_pipe(dc, opp_heads[slice_idx],
+					stream_idx, slice_idx, plane_idx,
+					slice_count, true);
+		}
+
+	}
+}
+
+static int resource_stream_to_stream_idx(struct dc_state *state,
+		struct dc_stream_state *stream)
+{
+	int i, stream_idx = -1;
+
+	for (i = 0; i < state->stream_count; i++)
+		if (state->streams[i] == stream) {
+			stream_idx = i;
+			break;
+		}
+
+	/* never return negative array index */
+	if (stream_idx == -1) {
+		ASSERT(0);
+		return 0;
+	}
+
+	return stream_idx;
+}
+
+void resource_log_pipe_topology_update(struct dc *dc, struct dc_state *state)
+{
+	struct pipe_ctx *otg_master;
+	int stream_idx, phantom_stream_idx;
+	DC_LOGGER_INIT(dc->ctx->logger);
+
 	DC_LOG_DC("    pipe topology update");
 	DC_LOG_DC("  ________________________");
 	for (stream_idx = 0; stream_idx < state->stream_count; stream_idx++) {
+		if (state->streams[stream_idx]->is_phantom)
+			continue;
+
 		otg_master = resource_get_otg_master_for_stream(
 				&state->res_ctx, state->streams[stream_idx]);
-		if (!otg_master	|| otg_master->stream_res.tg == NULL) {
-			DC_LOG_DC("topology update: otg_master NULL stream_idx %d!\n", stream_idx);
-			return;
-		}
-		slice_count = resource_get_opp_heads_for_otg_master(otg_master,
-				&state->res_ctx, opp_heads);
-		for (slice_idx = 0; slice_idx < slice_count; slice_idx++) {
-			plane_idx = -1;
-			if (opp_heads[slice_idx]->plane_state) {
-				dpp_count = resource_get_dpp_pipes_for_opp_head(
-						opp_heads[slice_idx],
-						&state->res_ctx,
-						dpp_pipes);
-				for (dpp_idx = 0; dpp_idx < dpp_count; dpp_idx++) {
-					is_primary = !dpp_pipes[dpp_idx]->top_pipe ||
-							dpp_pipes[dpp_idx]->top_pipe->plane_state != dpp_pipes[dpp_idx]->plane_state;
-					if (is_primary)
-						plane_idx++;
-					resource_log_pipe(dc, dpp_pipes[dpp_idx],
-							stream_idx, slice_idx,
-							plane_idx, slice_count,
-							is_primary);
-				}
-			} else {
-				resource_log_pipe(dc, opp_heads[slice_idx],
-						stream_idx, slice_idx, plane_idx,
-						slice_count, true);
-			}
 
+		if (!otg_master)
+			continue;
+
+		resource_log_pipe_for_stream(dc, state, otg_master, stream_idx);
+	}
+	if (state->phantom_stream_count > 0) {
+		DC_LOG_DC(" |    (phantom pipes)     |");
+		for (stream_idx = 0; stream_idx < state->stream_count; stream_idx++) {
+			if (state->stream_status[stream_idx].mall_stream_config.type != SUBVP_MAIN)
+				continue;
+
+			phantom_stream_idx = resource_stream_to_stream_idx(state,
+					state->stream_status[stream_idx].mall_stream_config.paired_stream);
+			otg_master = resource_get_otg_master_for_stream(
+					&state->res_ctx, state->streams[phantom_stream_idx]);
+			if (!otg_master)
+				continue;
+
+			resource_log_pipe_for_stream(dc, state, otg_master, stream_idx);
 		}
 	}
 	DC_LOG_DC(" |________________________|\n");
@@ -2448,6 +2497,17 @@
 	}
 }
 
+static int get_num_of_free_pipes(const struct resource_pool *pool, const struct dc_state *context)
+{
+	int i;
+	int count = 0;
+
+	for (i = 0; i < pool->pipe_count; i++)
+		if (resource_is_pipe_type(&context->res_ctx.pipe_ctx[i], FREE_PIPE))
+			count++;
+	return count;
+}
+
 enum dc_status resource_add_otg_master_for_stream_output(struct dc_state *new_ctx,
 		const struct resource_pool *pool,
 		struct dc_stream_state *stream)
@@ -2581,37 +2641,33 @@
 		struct dc_state *cur_ctx,
 		struct resource_pool *pool)
 {
-	struct pipe_ctx *opp_head_pipe, *sec_pipe, *tail_pipe;
+	struct pipe_ctx *sec_pipe, *tail_pipe;
+	struct pipe_ctx *opp_heads[MAX_PIPES];
+	int opp_head_count;
+	int i;
 
 	if (!pool->funcs->acquire_free_pipe_as_secondary_dpp_pipe) {
 		ASSERT(0);
 		return false;
 	}
 
-	opp_head_pipe = otg_master_pipe;
-	while (opp_head_pipe) {
+	opp_head_count = resource_get_opp_heads_for_otg_master(otg_master_pipe,
+			&new_ctx->res_ctx, opp_heads);
+	if (get_num_of_free_pipes(pool, new_ctx) < opp_head_count)
+		/* not enough free pipes */
+		return false;
+
+	for (i = 0; i < opp_head_count; i++) {
 		sec_pipe = pool->funcs->acquire_free_pipe_as_secondary_dpp_pipe(
 				cur_ctx,
 				new_ctx,
 				pool,
-				opp_head_pipe);
-		if (!sec_pipe) {
-			/* try tearing down MPCC combine */
-			int pipe_idx = acquire_first_split_pipe(
-					&new_ctx->res_ctx, pool,
-					otg_master_pipe->stream);
-
-			if (pipe_idx >= 0)
-				sec_pipe = &new_ctx->res_ctx.pipe_ctx[pipe_idx];
-		}
-
-		if (!sec_pipe)
-			return false;
-
+				opp_heads[i]);
+		ASSERT(sec_pipe);
 		sec_pipe->plane_state = plane_state;
 
 		/* establish pipe relationship */
-		tail_pipe = get_tail_pipe(opp_head_pipe);
+		tail_pipe = get_tail_pipe(opp_heads[i]);
 		tail_pipe->bottom_pipe = sec_pipe;
 		sec_pipe->top_pipe = tail_pipe;
 		sec_pipe->bottom_pipe = NULL;
@@ -2622,8 +2678,6 @@
 		} else {
 			sec_pipe->prev_odm_pipe = NULL;
 		}
-
-		opp_head_pipe = opp_head_pipe->next_odm_pipe;
 	}
 	return true;
 }
@@ -3049,6 +3103,8 @@
 bool dc_is_stream_unchanged(
 	struct dc_stream_state *old_stream, struct dc_stream_state *stream)
 {
+	if (!old_stream || !stream)
+		return false;
 
 	if (!are_stream_backends_same(old_stream, stream))
 		return false;
@@ -3128,6 +3184,9 @@
 {
 	int i, available_audio_count;
 
+	if (id == ENGINE_ID_UNKNOWN)
+		return NULL;
+
 	available_audio_count = pool->audio_count;
 
 	for (i = 0; i < available_audio_count; i++) {
@@ -3403,7 +3462,7 @@
 		if (pool->dpps[pipe_idx])
 			pipe_ctx->plane_res.mpcc_inst = pool->dpps[pipe_idx]->inst;
 
-		if (pipe_idx >= pool->timing_generator_count) {
+		if (pipe_idx >= pool->timing_generator_count && pool->timing_generator_count != 0) {
 			int tg_inst = pool->timing_generator_count - 1;
 
 			pipe_ctx->stream_res.tg = pool->timing_generators[tg_inst];
@@ -3554,8 +3613,10 @@
 		}
 	}
 
-	if (!stream_status)
+	if (!stream_status) {
 		ASSERT(0);
+		return false;
+	}
 
 	for (i = 0; i < set_count; i++)
 		if (set[i].stream == stream)
@@ -4564,6 +4625,9 @@
 
 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 timing_generator *tg = dc->res_pool->timing_generators[0];
 	enum dc_status res = DC_OK;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_state.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/core/dc_state.c
@@ -200,8 +200,12 @@
 	dc_state_construct(dc, state);
 
 #ifdef CONFIG_DRM_AMD_DC_FP
-	if (dc->debug.using_dml2)
-		dml2_create(dc, &dc->dml2_options, &state->bw_ctx.dml2);
+	if (dc->debug.using_dml2) {
+		if (!dml2_create(dc, &dc->dml2_options, &state->bw_ctx.dml2)) {
+			dc_state_release(state);
+			return NULL;
+		}
+	}
 #endif
 
 	kref_init(&state->refcount);
@@ -240,6 +244,8 @@
 	dc_state_copy_internal(new_state, src_state);
 
 #ifdef CONFIG_DRM_AMD_DC_FP
+	new_state->bw_ctx.dml2 = NULL;
+
 	if (src_state->bw_ctx.dml2 &&
 			!dml2_create_copy(&new_state->bw_ctx.dml2, src_state->bw_ctx.dml2)) {
 		dc_state_release(new_state);
@@ -334,7 +340,8 @@
 
 void dc_state_release(struct dc_state *state)
 {
-	kref_put(&state->refcount, dc_state_free);
+	if (state != NULL)
+		kref_put(&state->refcount, dc_state_free);
 }
 /*
  * dc_state_add_stream() - Add a new dc_stream_state to a dc_state.
@@ -414,6 +421,19 @@
 	return DC_OK;
 }
 
+static void remove_mpc_combine_for_stream(const struct dc *dc,
+		struct dc_state *new_ctx,
+		const struct dc_state *cur_ctx,
+		struct dc_stream_status *status)
+{
+	int i;
+
+	for (i = 0; i < status->plane_count; i++)
+		resource_update_pipes_for_plane_with_slice_count(
+				new_ctx, cur_ctx, dc->res_pool,
+				status->plane_states[i], 1);
+}
+
 bool dc_state_add_plane(
 		const struct dc *dc,
 		struct dc_stream_state *stream,
@@ -424,22 +444,52 @@
 	struct pipe_ctx *otg_master_pipe;
 	struct dc_stream_status *stream_status = NULL;
 	bool added = false;
+	int odm_slice_count;
+	int i;
 
 	stream_status = dc_state_get_stream_status(state, stream);
+	otg_master_pipe = resource_get_otg_master_for_stream(
+			&state->res_ctx, stream);
 	if (stream_status == NULL) {
 		dm_error("Existing stream not found; failed to attach surface!\n");
 		goto out;
-	} else if (stream_status->plane_count == MAX_SURFACE_NUM) {
+	} else if (stream_status->plane_count == MAX_SURFACES) {
 		dm_error("Surface: can not attach plane_state %p! Maximum is: %d\n",
-				plane_state, MAX_SURFACE_NUM);
+				plane_state, MAX_SURFACES);
+		goto out;
+	} else if (!otg_master_pipe) {
 		goto out;
 	}
 
-	otg_master_pipe = resource_get_otg_master_for_stream(
-			&state->res_ctx, stream);
-	if (otg_master_pipe)
+	added = resource_append_dpp_pipes_for_plane_composition(state,
+			dc->current_state, pool, otg_master_pipe, plane_state);
+
+	if (!added) {
+		/* try to remove MPC combine to free up pipes */
+		for (i = 0; i < state->stream_count; i++)
+			remove_mpc_combine_for_stream(dc, state,
+					dc->current_state,
+					&state->stream_status[i]);
 		added = resource_append_dpp_pipes_for_plane_composition(state,
-				dc->current_state, pool, otg_master_pipe, plane_state);
+					dc->current_state, pool,
+					otg_master_pipe, plane_state);
+	}
+
+	if (!added) {
+		/* try to decrease ODM slice count gradually to free up pipes */
+		odm_slice_count = resource_get_odm_slice_count(otg_master_pipe);
+		for (i = odm_slice_count - 1; i > 0; i--) {
+			resource_update_pipes_for_stream_with_slice_count(state,
+					dc->current_state, dc->res_pool, stream,
+					i);
+			added = resource_append_dpp_pipes_for_plane_composition(
+					state,
+					dc->current_state, pool,
+					otg_master_pipe, plane_state);
+			if (added)
+				break;
+		}
+	}
 
 	if (added) {
 		stream_status->plane_states[stream_status->plane_count] =
@@ -499,15 +549,6 @@
 
 	stream_status->plane_states[stream_status->plane_count] = NULL;
 
-	if (stream_status->plane_count == 0 && dc->config.enable_windowed_mpo_odm)
-		/* ODM combine could prevent us from supporting more planes
-		 * we will reset ODM slice count back to 1 when all planes have
-		 * been removed to maximize the amount of planes supported when
-		 * new planes are added.
-		 */
-		resource_update_pipes_for_stream_with_slice_count(
-				state, dc->current_state, dc->res_pool, stream, 1);
-
 	return true;
 }
 
@@ -529,7 +570,7 @@
 {
 	int i, old_plane_count;
 	struct dc_stream_status *stream_status = NULL;
-	struct dc_plane_state *del_planes[MAX_SURFACE_NUM] = { 0 };
+	struct dc_plane_state *del_planes[MAX_SURFACES] = { 0 };
 
 	for (i = 0; i < state->stream_count; i++)
 		if (state->streams[i] == stream) {
@@ -796,7 +837,7 @@
 {
 	int i, old_plane_count;
 	struct dc_stream_status *stream_status = NULL;
-	struct dc_plane_state *del_planes[MAX_SURFACE_NUM] = { 0 };
+	struct dc_plane_state *del_planes[MAX_SURFACES] = { 0 };
 
 	for (i = 0; i < state->stream_count; i++)
 		if (state->streams[i] == phantom_stream) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -278,7 +278,6 @@
 	const struct dc_cursor_attributes *attributes)
 {
 	struct dc  *dc;
-	bool reset_idle_optimizations = false;
 
 	if (NULL == stream) {
 		dm_error("DC: dc_stream is NULL!\n");
@@ -309,20 +308,36 @@
 
 	stream->cursor_attributes = *attributes;
 
-	dc_z10_restore(dc);
-	/* disable idle optimizations while updating cursor */
-	if (dc->idle_optimizations_allowed) {
-		dc_allow_idle_optimizations(dc, false);
-		reset_idle_optimizations = true;
-	}
+	return true;
+}
 
-	program_cursor_attributes(dc, stream, attributes);
-
-	/* re-enable idle optimizations if necessary */
-	if (reset_idle_optimizations)
-		dc_allow_idle_optimizations(dc, true);
+bool dc_stream_program_cursor_attributes(
+	struct dc_stream_state *stream,
+	const struct dc_cursor_attributes *attributes)
+{
+	struct dc  *dc;
+	bool reset_idle_optimizations = false;
 
-	return true;
+	dc = stream ? stream->ctx->dc : NULL;
+
+	if (dc_stream_set_cursor_attributes(stream, attributes)) {
+		dc_z10_restore(dc);
+		/* disable idle optimizations while updating cursor */
+		if (dc->idle_optimizations_allowed) {
+			dc_allow_idle_optimizations(dc, false);
+			reset_idle_optimizations = true;
+		}
+
+		program_cursor_attributes(dc, stream, attributes);
+
+		/* re-enable idle optimizations if necessary */
+		if (reset_idle_optimizations && !dc->debug.disable_dmub_reallow_idle)
+			dc_allow_idle_optimizations(dc, true);
+
+		return true;
+	}
+
+	return false;
 }
 
 static void program_cursor_position(
@@ -367,9 +382,6 @@
 	struct dc_stream_state *stream,
 	const struct dc_cursor_position *position)
 {
-	struct dc *dc;
-	bool reset_idle_optimizations = false;
-
 	if (NULL == stream) {
 		dm_error("DC: dc_stream is NULL!\n");
 		return false;
@@ -380,24 +392,46 @@
 		return false;
 	}
 
+	stream->cursor_position = *position;
+
+
+	return true;
+}
+
+bool dc_stream_program_cursor_position(
+	struct dc_stream_state *stream,
+	const struct dc_cursor_position *position)
+{
+	struct dc *dc;
+	bool reset_idle_optimizations = false;
+	const struct dc_cursor_position *old_position;
+
+	if (!stream)
+		return false;
+
+	old_position = &stream->cursor_position;
 	dc = stream->ctx->dc;
-	dc_z10_restore(dc);
 
-	/* disable idle optimizations if enabling cursor */
-	if (dc->idle_optimizations_allowed && (!stream->cursor_position.enable || dc->debug.exit_idle_opt_for_cursor_updates)
-			&& position->enable) {
-		dc_allow_idle_optimizations(dc, false);
-		reset_idle_optimizations = true;
-	}
+	if (dc_stream_set_cursor_position(stream, position)) {
+		dc_z10_restore(dc);
 
-	stream->cursor_position = *position;
+		/* disable idle optimizations if enabling cursor */
+		if (dc->idle_optimizations_allowed &&
+		    (!old_position->enable || dc->debug.exit_idle_opt_for_cursor_updates) &&
+		    position->enable) {
+			dc_allow_idle_optimizations(dc, false);
+			reset_idle_optimizations = true;
+		}
 
-	program_cursor_position(dc, stream, position);
-	/* re-enable idle optimizations if necessary */
-	if (reset_idle_optimizations)
-		dc_allow_idle_optimizations(dc, true);
+		program_cursor_position(dc, stream, position);
+		/* re-enable idle optimizations if necessary */
+		if (reset_idle_optimizations && !dc->debug.disable_dmub_reallow_idle)
+			dc_allow_idle_optimizations(dc, true);
 
-	return true;
+		return true;
+	}
+
+	return false;
 }
 
 bool dc_stream_add_writeback(struct dc *dc,
@@ -423,6 +457,8 @@
 		return false;
 	}
 
+	dc_exit_ips_for_hw_access(dc);
+
 	wb_info->dwb_params.out_transfer_func = stream->out_transfer_func;
 
 	dwb = dc->res_pool->dwbc[wb_info->dwb_pipe_inst];
@@ -493,6 +529,8 @@
 		return false;
 	}
 
+	dc_exit_ips_for_hw_access(dc);
+
 	if (dwb->funcs->set_fc_enable)
 		dwb->funcs->set_fc_enable(dwb, DWB_FRAME_CAPTURE_DISABLE);
 
@@ -542,6 +580,8 @@
 		return false;
 	}
 
+	dc_exit_ips_for_hw_access(dc);
+
 	/* disable writeback */
 	if (dc->hwss.disable_writeback) {
 		struct dwbc *dwb = dc->res_pool->dwbc[dwb_pipe_inst];
@@ -557,6 +597,8 @@
 		int num_dwb,
 		struct dc_writeback_info *wb_info)
 {
+	dc_exit_ips_for_hw_access(dc);
+
 	if (dc->hwss.mmhubbub_warmup)
 		return dc->hwss.mmhubbub_warmup(dc, num_dwb, wb_info);
 	else
@@ -569,6 +611,8 @@
 	struct resource_context *res_ctx =
 		&dc->current_state->res_ctx;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	for (i = 0; i < MAX_PIPES; i++) {
 		struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg;
 
@@ -597,6 +641,8 @@
 	dc = stream->ctx->dc;
 	res_ctx = &dc->current_state->res_ctx;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	for (i = 0; i < MAX_PIPES; i++) {
 		struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
 
@@ -628,6 +674,8 @@
 	struct resource_context *res_ctx =
 		&dc->current_state->res_ctx;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	for (i = 0; i < MAX_PIPES; i++) {
 		struct timing_generator *tg = res_ctx->pipe_ctx[i].stream_res.tg;
 
@@ -664,6 +712,8 @@
 	if (i == MAX_PIPES)
 		return true;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	return dc->hwss.dmdata_status_done(pipe);
 }
 
@@ -698,6 +748,8 @@
 
 	pipe_ctx->stream->dmdata_address = attr->address;
 
+	dc_exit_ips_for_hw_access(dc);
+
 	dc->hwss.program_dmdata_engine(pipe_ctx);
 
 	if (hubp->funcs->dmdata_set_attributes != NULL &&
@@ -748,12 +800,12 @@
 			stream->dst.height,
 			stream->output_color_space);
 	DC_LOG_DC(
-			"\tpix_clk_khz: %d, h_total: %d, v_total: %d, pixelencoder:%d, displaycolorDepth:%d\n",
+			"\tpix_clk_khz: %d, h_total: %d, v_total: %d, pixel_encoding:%s, color_depth:%s\n",
 			stream->timing.pix_clk_100hz / 10,
 			stream->timing.h_total,
 			stream->timing.v_total,
-			stream->timing.pixel_encoding,
-			stream->timing.display_color_depth);
+			dc_pixel_encoding_to_str(stream->timing.pixel_encoding),
+			dc_color_depth_to_str(stream->timing.display_color_depth));
 	DC_LOG_DC(
 			"\tlink: %d\n",
 			stream->link->link_index);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
@@ -156,11 +156,14 @@
 		if (pipe_ctx->plane_state != plane_state)
 			continue;
 
-		pipe_ctx->plane_state->status.is_flip_pending = false;
+		if (pipe_ctx->plane_state)
+			pipe_ctx->plane_state->status.is_flip_pending = false;
 
 		break;
 	}
 
+	dc_exit_ips_for_hw_access(dc);
+
 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
 		struct pipe_ctx *pipe_ctx =
 				&dc->current_state->res_ctx.pipe_ctx[i];
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dc.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dc.h
@@ -53,7 +53,7 @@
 
 #define DC_VER "3.2.266"
 
-#define MAX_SURFACES 3
+#define MAX_SURFACES 4
 #define MAX_PLANES 6
 #define MAX_STREAMS 6
 #define MIN_VIEWPORT_SIZE 12
@@ -987,6 +987,7 @@
 	bool psp_disabled_wa;
 	unsigned int ips2_eval_delay_us;
 	unsigned int ips2_entry_delay_us;
+	bool disable_dmub_reallow_idle;
 	bool disable_timeout;
 	bool disable_extblankadj;
 	unsigned int static_screen_wait_frames;
@@ -1013,7 +1014,7 @@
 	struct dc_phy_addr_space_config vm_pa_config;
 
 	uint8_t link_count;
-	struct dc_link *links[MAX_PIPES * 2];
+	struct dc_link *links[MAX_LINKS];
 	struct link_service *link_srv;
 
 	struct dc_state *current_state;
@@ -1037,7 +1038,6 @@
 
 	/* Require to optimize clocks and bandwidth for added/removed planes */
 	bool optimized_required;
-	bool wm_optimized_required;
 	bool idle_optimizations_allowed;
 	bool enable_c20_dtm_b0;
 
@@ -2325,6 +2325,7 @@
 				struct dc_cursor_attributes *cursor_attr);
 
 void dc_allow_idle_optimizations(struct dc *dc, bool allow);
+void dc_exit_ips_for_hw_access(struct dc *dc);
 bool dc_dmub_is_ips_idle_state(struct dc *dc);
 
 /* set min and max memory clock to lowest and highest DPM level, respectively */
@@ -2390,6 +2391,8 @@
 
 struct dc_power_profile dc_get_power_profile_for_dc_state(const struct dc_state *context);
 
+unsigned int dc_get_det_buffer_size_from_state(const struct dc_state *context);
+
 /* DSC Interfaces */
 #include "dc_dsc.h"
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -231,7 +231,9 @@
 			if (status == DMUB_STATUS_POWER_STATE_D3)
 				return false;
 
-			dmub_srv_wait_for_idle(dmub, 100000);
+			status = dmub_srv_wait_for_idle(dmub, 100000);
+			if (status != DMUB_STATUS_OK)
+				return false;
 
 			/* Requeue the command. */
 			status = dmub_srv_cmd_queue(dmub, &cmd_list[i]);
@@ -497,7 +499,8 @@
 	union dmub_rb_cmd cmd = { 0 };
 	unsigned int panel_inst = 0;
 
-	dc_get_edp_link_panel_inst(dc, pipe_ctx->stream->link, &panel_inst);
+	if (!dc_get_edp_link_panel_inst(dc, pipe_ctx->stream->link, &panel_inst))
+		return;
 
 	memset(&cmd, 0, sizeof(cmd));
 
@@ -1320,16 +1323,27 @@
 	 * Powering up the hardware requires notifying PMFW and DMCUB.
 	 * Clearing the driver idle allow requires a DMCUB command.
 	 * DMCUB commands requires the DMCUB to be powered up and restored.
-	 *
-	 * Exit out early to prevent an infinite loop of DMCUB commands
-	 * triggering exit low power - use software state to track this.
 	 */
-	dc_dmub_srv->idle_allowed = allow_idle;
 
-	if (!allow_idle)
+	if (!allow_idle) {
 		dc_dmub_srv_exit_low_power_state(dc);
-	else
+		/*
+		 * Idle is considered fully exited only after the sequence above
+		 * fully completes. If we have a race of two threads exiting
+		 * at the same time then it's safe to perform the sequence
+		 * twice as long as we're not re-entering.
+		 *
+		 * Infinite command submission is avoided by using the
+		 * dm_execute_dmub_cmd submission instead of the "wake" helpers.
+		 */
+		dc_dmub_srv->idle_allowed = false;
+	} else {
+		/* Consider idle as notified prior to the actual submission to
+		 * prevent multiple entries. */
+		dc_dmub_srv->idle_allowed = true;
+
 		dc_dmub_srv_notify_idle(dc, allow_idle);
+	}
 }
 
 bool dc_wake_and_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cmd *cmd,
@@ -1364,7 +1378,7 @@
 	else
 		result = dm_execute_dmub_cmd(ctx, cmd, wait_type);
 
-	if (result && reallow_idle)
+	if (result && reallow_idle && !ctx->dc->debug.disable_dmub_reallow_idle)
 		dc_dmub_srv_apply_idle_power_optimizations(ctx->dc, true);
 
 	return result;
@@ -1413,7 +1427,7 @@
 
 	result = dc_dmub_execute_gpint(ctx, command_code, param, response, wait_type);
 
-	if (result && reallow_idle)
+	if (result && reallow_idle && !ctx->dc->debug.disable_dmub_reallow_idle)
 		dc_dmub_srv_apply_idle_power_optimizations(ctx->dc, true);
 
 	return result;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dc_dsc.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dc_dsc.h
@@ -100,7 +100,8 @@
  */
 void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing,
 		uint32_t max_target_bpp_limit_override_x16,
-		struct dc_dsc_policy *policy);
+		struct dc_dsc_policy *policy,
+		const enum dc_link_encoding_format link_encoding);
 
 void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -56,7 +56,7 @@
 	int plane_count;
 	int audio_inst;
 	struct timing_sync_info timing_sync_info;
-	struct dc_plane_state *plane_states[MAX_SURFACE_NUM];
+	struct dc_plane_state *plane_states[MAX_SURFACES];
 	bool is_abm_supported;
 	struct mall_stream_config mall_stream_config;
 };
@@ -139,7 +139,6 @@
 		uint32_t wb_update:1;
 		uint32_t dsc_changed : 1;
 		uint32_t mst_bw : 1;
-		uint32_t crtc_timing_adjust : 1;
 		uint32_t fams_changed : 1;
 	} bits;
 
@@ -326,7 +325,6 @@
 	struct dc_3dlut *lut3d_func;
 
 	struct test_pattern *pending_test_pattern;
-	struct dc_crtc_timing_adjust *crtc_timing_adjust;
 };
 
 bool dc_is_stream_unchanged(
@@ -478,10 +476,18 @@
 	struct dc_stream_state *stream,
 	const struct dc_cursor_attributes *attributes);
 
+bool dc_stream_program_cursor_attributes(
+	struct dc_stream_state *stream,
+	const struct dc_cursor_attributes *attributes);
+
 bool dc_stream_set_cursor_position(
 	struct dc_stream_state *stream,
 	const struct dc_cursor_position *position);
 
+bool dc_stream_program_cursor_position(
+	struct dc_stream_state *stream,
+	const struct dc_cursor_position *position);
+
 
 bool dc_stream_adjust_vmin_vmax(struct dc *dc,
 				struct dc_stream_state *stream,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dc_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dc_types.h
@@ -76,7 +76,6 @@
 	unsigned long last_entry_write;
 };
 
-#define MAX_SURFACE_NUM 6
 #define NUM_PIXEL_FORMATS 10
 
 enum tiling_mode {
@@ -178,6 +177,7 @@
 	unsigned int skip_avmute;
 	unsigned int mst_start_top_delay;
 	unsigned int remove_sink_ext_caps;
+	unsigned int disable_colorimetry;
 };
 
 struct dc_edid_caps {
@@ -1085,9 +1085,9 @@
 	/* SMU optimization is enabled */
 	bool replay_smu_opt_enable;
 	/* Current Coasting vtotal */
-	uint16_t coasting_vtotal;
+	uint32_t coasting_vtotal;
 	/* Coasting vtotal table */
-	uint16_t coasting_vtotal_table[PR_COASTING_TYPE_NUM];
+	uint32_t coasting_vtotal_table[PR_COASTING_TYPE_NUM];
 	/* Maximum link off frame count */
 	enum replay_link_off_frame_count_level link_off_frame_count_level;
 	/* Replay pseudo vtotal for abm + ips on full screen video which can improve ips residency */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c
@@ -262,7 +262,7 @@
 {
 	union dmub_rb_cmd cmd;
 	struct dc_context *dc = abm->ctx;
-	uint32_t ramping_boundary = 0xFFFF;
+	uint8_t ramping_boundary = 0xFF;
 
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.abm_set_pipe.header.type = DMUB_CMD__ABM;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c
@@ -84,7 +84,7 @@
 
 	cmd.replay_enable.header.payload_bytes = sizeof(struct dmub_rb_cmd_replay_enable_data);
 
-	dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+	dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
 
 	/* Below loops 1000 x 500us = 500 ms.
 	 *  Exit REPLAY may need to wait 1-2 frames to power up. Timeout after at
@@ -102,7 +102,8 @@
 					break;
 			}
 
-			fsleep(500);
+			/* must *not* be fsleep - this can be called from high irq levels */
+			udelay(500);
 		}
 
 		/* assert if max retry hit */
@@ -127,7 +128,7 @@
 	cmd.replay_set_power_opt.replay_set_power_opt_data.power_opt = power_opt;
 	cmd.replay_set_power_opt.replay_set_power_opt_data.panel_inst = panel_inst;
 
-	dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+	dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
 }
 
 /*
@@ -209,8 +210,7 @@
 	else
 		copy_settings_data->flags.bitfields.force_wakeup_by_tps3 = 0;
 
-
-	dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+	dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
 
 	return true;
 }
@@ -231,7 +231,7 @@
 	cmd.replay_set_coasting_vtotal.header.payload_bytes = sizeof(struct dmub_cmd_replay_set_coasting_vtotal_data);
 	cmd.replay_set_coasting_vtotal.replay_set_coasting_vtotal_data.coasting_vtotal = coasting_vtotal;
 
-	dm_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
+	dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
 }
 
 /*
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dce110/Makefile
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dce110/Makefile
@@ -23,7 +23,7 @@
 # Makefile for the 'controller' sub-component of DAL.
 # It provides the control and status of HW CRTC block.
 
-CFLAGS_$(AMDDALPATH)/dc/dce110/dce110_resource.o = $(call cc-disable-warning, override-init)
+CFLAGS_$(AMDDALPATH)/dc/dce110/dce110_resource.o = -Wno-override-init
 
 DCE110 = dce110_timing_generator.o \
 dce110_compressor.o dce110_opp_regamma_v.o \
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dce112/Makefile
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dce112/Makefile
@@ -23,7 +23,7 @@
 # Makefile for the 'controller' sub-component of DAL.
 # It provides the control and status of HW CRTC block.
 
-CFLAGS_$(AMDDALPATH)/dc/dce112/dce112_resource.o = $(call cc-disable-warning, override-init)
+CFLAGS_$(AMDDALPATH)/dc/dce112/dce112_resource.o = -Wno-override-init
 
 DCE112 = dce112_compressor.o
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dce120/Makefile
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dce120/Makefile
@@ -24,7 +24,7 @@
 # It provides the control and status of HW CRTC block.
 
 
-CFLAGS_$(AMDDALPATH)/dc/dce120/dce120_resource.o = $(call cc-disable-warning, override-init)
+CFLAGS_$(AMDDALPATH)/dc/dce120/dce120_resource.o = -Wno-override-init
 
 DCE120 = dce120_timing_generator.o
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dce60/Makefile
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dce60/Makefile
@@ -23,7 +23,7 @@
 # Makefile for the 'controller' sub-component of DAL.
 # It provides the control and status of HW CRTC block.
 
-CFLAGS_$(AMDDALPATH)/dc/dce60/dce60_resource.o = $(call cc-disable-warning, override-init)
+CFLAGS_$(AMDDALPATH)/dc/dce60/dce60_resource.o = -Wno-override-init
 
 DCE60 = dce60_timing_generator.o dce60_hw_sequencer.o \
 	dce60_resource.o
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dce80/Makefile
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dce80/Makefile
@@ -23,7 +23,7 @@
 # Makefile for the 'controller' sub-component of DAL.
 # It provides the control and status of HW CRTC block.
 
-CFLAGS_$(AMDDALPATH)/dc/dce80/dce80_resource.o = $(call cc-disable-warning, override-init)
+CFLAGS_$(AMDDALPATH)/dc/dce80/dce80_resource.o = -Wno-override-init
 
 DCE80 = dce80_timing_generator.o
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_cm_common.c
@@ -382,6 +382,11 @@
 				i += increment) {
 			if (j == hw_points - 1)
 				break;
+			if (i >= TRANSFER_FUNC_POINTS) {
+				DC_LOG_ERROR("Index out of bounds: i=%d, TRANSFER_FUNC_POINTS=%d\n",
+					     i, TRANSFER_FUNC_POINTS);
+				return false;
+			}
 			rgb_resulted[j].red = output_tf->tf_pts.red[i];
 			rgb_resulted[j].green = output_tf->tf_pts.green[i];
 			rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
@@ -566,6 +571,8 @@
 				i += increment) {
 			if (j == hw_points - 1)
 				break;
+			if (i >= TRANSFER_FUNC_POINTS)
+				return false;
 			rgb_resulted[j].red = output_tf->tf_pts.red[i];
 			rgb_resulted[j].green = output_tf->tf_pts.green[i];
 			rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
@@ -194,6 +194,9 @@
 	dpp->filter_h = NULL;
 	dpp->filter_v = NULL;
 
+	memset(&dpp_base->pos, 0, sizeof(dpp_base->pos));
+	memset(&dpp_base->att, 0, sizeof(dpp_base->att));
+
 	memset(&dpp->scl_data, 0, sizeof(dpp->scl_data));
 	memset(&dpp->pwl_data, 0, sizeof(dpp->pwl_data));
 }
@@ -480,10 +483,11 @@
 	if (src_y_offset + cursor_height <= 0)
 		cur_en = 0;  /* not visible beyond top edge*/
 
-	REG_UPDATE(CURSOR0_CONTROL,
-			CUR0_ENABLE, cur_en);
+	if (dpp_base->pos.cur0_ctl.bits.cur0_enable != cur_en) {
+		REG_UPDATE(CURSOR0_CONTROL, CUR0_ENABLE, cur_en);
 
-	dpp_base->pos.cur0_ctl.bits.cur0_enable = cur_en;
+		dpp_base->pos.cur0_ctl.bits.cur0_enable = cur_en;
+	}
 }
 
 void dpp1_cnv_set_optional_cursor_attributes(
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -532,6 +532,12 @@
 			SECONDARY_SURFACE_DCC_IND_64B_BLK, dcc_ind_64b_blk);
 }
 
+void hubp_reset(struct hubp *hubp)
+{
+	memset(&hubp->pos, 0, sizeof(hubp->pos));
+	memset(&hubp->att, 0, sizeof(hubp->att));
+}
+
 void hubp1_program_surface_config(
 	struct hubp *hubp,
 	enum surface_pixel_format format,
@@ -749,7 +755,8 @@
 	if (flip_pending)
 		return true;
 
-	if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
+	if (hubp &&
+	    earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
 		return true;
 
 	return false;
@@ -1336,8 +1343,9 @@
 
 void hubp1_init(struct hubp *hubp)
 {
-	//do nothing
+	hubp_reset(hubp);
 }
+
 static const struct hubp_funcs dcn10_hubp_funcs = {
 	.hubp_program_surface_flip_and_addr =
 			hubp1_program_surface_flip_and_addr,
@@ -1350,6 +1358,7 @@
 	.hubp_set_vm_context0_settings = hubp1_set_vm_context0_settings,
 	.set_blank = hubp1_set_blank,
 	.dcc_control = hubp1_dcc_control,
+	.hubp_reset = hubp_reset,
 	.mem_program_viewport = min_set_viewport,
 	.set_hubp_blank_en = hubp1_set_hubp_blank_en,
 	.set_cursor_attributes	= hubp1_cursor_set_attributes,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h
@@ -745,6 +745,8 @@
 		bool enable,
 		enum hubp_ind_block_size independent_64b_blks);
 
+void hubp_reset(struct hubp *hubp);
+
 bool hubp1_program_surface_flip_and_addr(
 	struct hubp *hubp,
 	const struct dc_plane_address *address,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_opp.c
@@ -377,6 +377,7 @@
 		.opp_set_disp_pattern_generator = NULL,
 		.opp_program_dpg_dimensions = NULL,
 		.dpg_is_blanked = NULL,
+		.dpg_is_pending = NULL,
 		.opp_destroy = opp1_destroy
 };
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_dwb_scl.c
@@ -690,6 +690,9 @@
 	int pair;
 	uint16_t odd_coef, even_coef;
 
+	if (!filter)
+		return;
+
 	for (phase = 0; phase < (NUM_PHASES / 2 + 1); phase++) {
 		for (pair = 0; pair < tap_pairs; pair++) {
 			even_coef = filter[phase * taps + 2 * pair];
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubbub.c
@@ -595,7 +595,8 @@
 		hubbub1->base.ctx->dc->clk_mgr->clks.p_state_change_support == false)
 		safe_to_lower = true;
 
-	hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower);
+	if (hubbub1_program_pstate_watermarks(hubbub, watermarks, refclk_mhz, safe_to_lower))
+		wm_pending = true;
 
 	REG_SET(DCHUBBUB_ARB_SAT_LEVEL, 0,
 			DCHUBBUB_ARB_SAT_LEVEL, 60 * refclk_mhz);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c
@@ -927,7 +927,8 @@
 	if (flip_pending)
 		return true;
 
-	if (earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
+	if (hubp &&
+	    earliest_inuse_address.grph.addr.quad_part != hubp->request_address.grph.addr.quad_part)
 		return true;
 
 	return false;
@@ -1043,11 +1044,13 @@
 	if (src_y_offset + cursor_height <= 0)
 		cur_en = 0;  /* not visible beyond top edge*/
 
-	if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
-		hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
+	if (hubp->pos.cur_ctl.bits.cur_enable != cur_en) {
+		if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
+			hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
 
-	REG_UPDATE(CURSOR_CONTROL,
+		REG_UPDATE(CURSOR_CONTROL,
 			CURSOR_ENABLE, cur_en);
+	}
 
 	REG_SET_2(CURSOR_POSITION, 0,
 			CURSOR_X_POSITION, pos->x,
@@ -1653,6 +1656,7 @@
 	.set_blank = hubp2_set_blank,
 	.set_blank_regs = hubp2_set_blank_regs,
 	.dcc_control = hubp2_dcc_control,
+	.hubp_reset = hubp_reset,
 	.mem_program_viewport = min_set_viewport,
 	.set_cursor_attributes	= hubp2_cursor_set_attributes,
 	.set_cursor_position	= hubp2_cursor_set_position,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.c
@@ -337,6 +337,19 @@
 		(double_buffer_pending == 0);
 }
 
+bool opp2_dpg_is_pending(struct output_pixel_processor *opp)
+{
+	struct dcn20_opp *oppn20 = TO_DCN20_OPP(opp);
+	uint32_t double_buffer_pending;
+	uint32_t dpg_en;
+
+	REG_GET(DPG_CONTROL, DPG_EN, &dpg_en);
+
+	REG_GET(DPG_STATUS, DPG_DOUBLE_BUFFER_PENDING, &double_buffer_pending);
+
+	return (dpg_en == 1 && double_buffer_pending == 1);
+}
+
 void opp2_program_left_edge_extra_pixel (
 		struct output_pixel_processor *opp,
 		bool count)
@@ -363,6 +376,7 @@
 		.opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator,
 		.opp_program_dpg_dimensions = opp2_program_dpg_dimensions,
 		.dpg_is_blanked = opp2_dpg_is_blanked,
+		.dpg_is_pending = opp2_dpg_is_pending,
 		.opp_dpg_set_blank_color = opp2_dpg_set_blank_color,
 		.opp_destroy = opp1_destroy,
 		.opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_opp.h
@@ -159,6 +159,8 @@
 
 bool opp2_dpg_is_blanked(struct output_pixel_processor *opp);
 
+bool opp2_dpg_is_pending(struct output_pixel_processor *opp);
+
 void opp2_dpg_set_blank_color(
 		struct output_pixel_processor *opp,
 		const struct tg_color *color);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_hubp.c
@@ -116,6 +116,7 @@
 	.set_cursor_position	= hubp1_cursor_set_position,
 	.set_blank = hubp1_set_blank,
 	.dcc_control = hubp1_dcc_control,
+	.hubp_reset = hubp_reset,
 	.mem_program_viewport = min_set_viewport,
 	.hubp_clk_cntl = hubp1_clk_cntl,
 	.hubp_vtg_sel = hubp1_vtg_sel,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_opp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn201/dcn201_opp.c
@@ -50,6 +50,7 @@
 		.opp_set_disp_pattern_generator = opp2_set_disp_pattern_generator,
 		.opp_program_dpg_dimensions = opp2_program_dpg_dimensions,
 		.dpg_is_blanked = opp2_dpg_is_blanked,
+		.dpg_is_pending = opp2_dpg_is_pending,
 		.opp_dpg_set_blank_color = opp2_dpg_set_blank_color,
 		.opp_destroy = opp1_destroy,
 		.opp_program_left_edge_extra_pixel = opp2_program_left_edge_extra_pixel,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c
@@ -811,6 +811,8 @@
 	struct dcn21_hubp *hubp21 = TO_DCN21_HUBP(hubp);
 	//hubp[i].HUBPREQ_DEBUG.HUBPREQ_DEBUG[26] = 1;
 	REG_WRITE(HUBPREQ_DEBUG, 1 << 26);
+
+	hubp_reset(hubp);
 }
 static struct hubp_funcs dcn21_hubp_funcs = {
 	.hubp_enable_tripleBuffer = hubp2_enable_triplebuffer,
@@ -823,6 +825,7 @@
 	.hubp_set_vm_system_aperture_settings = hubp21_set_vm_system_aperture_settings,
 	.set_blank = hubp1_set_blank,
 	.dcc_control = hubp1_dcc_control,
+	.hubp_reset = hubp_reset,
 	.mem_program_viewport = hubp21_set_viewport,
 	.set_cursor_attributes	= hubp2_cursor_set_attributes,
 	.set_cursor_position	= hubp1_cursor_set_position,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
@@ -177,6 +177,8 @@
 				i += increment) {
 			if (j == hw_points)
 				break;
+			if (i >= TRANSFER_FUNC_POINTS)
+				return false;
 			rgb_resulted[j].red = output_tf->tf_pts.red[i];
 			rgb_resulted[j].green = output_tf->tf_pts.green[i];
 			rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
@@ -335,6 +337,8 @@
 				i += increment) {
 			if (j == hw_points - 1)
 				break;
+			if (i >= TRANSFER_FUNC_POINTS)
+				return false;
 			rgb_resulted[j].red = output_tf->tf_pts.red[i];
 			rgb_resulted[j].green = output_tf->tf_pts.green[i];
 			rgb_resulted[j].blue = output_tf->tf_pts.blue[i];
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubbub.c
@@ -129,7 +129,8 @@
 	REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
 			DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 0x1FF);
 
-	hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
+	if (safe_to_lower || hubbub->ctx->dc->debug.disable_stutter)
+		hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
 
 	return wm_pending;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c
@@ -480,6 +480,10 @@
 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 	//hubp[i].HUBPREQ_DEBUG.HUBPREQ_DEBUG[26] = 1;
 	REG_WRITE(HUBPREQ_DEBUG, 1 << 26);
+
+	REG_UPDATE(DCHUBP_CNTL, HUBP_TTU_DISABLE, 0);
+
+	hubp_reset(hubp);
 }
 
 static struct hubp_funcs dcn30_hubp_funcs = {
@@ -494,6 +498,7 @@
 	.set_blank = hubp2_set_blank,
 	.set_blank_regs = hubp2_set_blank_regs,
 	.dcc_control = hubp3_dcc_control,
+	.hubp_reset = hubp_reset,
 	.mem_program_viewport = min_set_viewport,
 	.set_cursor_attributes	= hubp2_cursor_set_attributes,
 	.set_cursor_position	= hubp2_cursor_set_position,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c
@@ -44,6 +44,36 @@
 #define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
 
 
+void mpc3_mpc_init(struct mpc *mpc)
+{
+	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
+	int opp_id;
+
+	mpc1_mpc_init(mpc);
+
+	for (opp_id = 0; opp_id < MAX_OPP; opp_id++) {
+		if (REG(MUX[opp_id]))
+			/* disable mpc out rate and flow control */
+			REG_UPDATE_2(MUX[opp_id], MPC_OUT_RATE_CONTROL_DISABLE,
+					1, MPC_OUT_FLOW_CONTROL_COUNT, 0);
+	}
+}
+
+void mpc3_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_id)
+{
+	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
+
+	mpc1_mpc_init_single_inst(mpc, mpcc_id);
+
+	/* assuming mpc out mux is connected to opp with the same index at this
+	 * point in time (e.g. transitioning from vbios to driver)
+	 */
+	if (mpcc_id < MAX_OPP && REG(MUX[mpcc_id]))
+		/* disable mpc out rate and flow control */
+		REG_UPDATE_2(MUX[mpcc_id], MPC_OUT_RATE_CONTROL_DISABLE,
+				1, MPC_OUT_FLOW_CONTROL_COUNT, 0);
+}
+
 bool mpc3_is_dwb_idle(
 	struct mpc *mpc,
 	int dwb_id)
@@ -80,25 +110,6 @@
 		MPC_DWB0_MUX, 0xf);
 }
 
-void mpc3_set_out_rate_control(
-	struct mpc *mpc,
-	int opp_id,
-	bool enable,
-	bool rate_2x_mode,
-	struct mpc_dwb_flow_control *flow_control)
-{
-	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
-
-	REG_UPDATE_2(MUX[opp_id],
-			MPC_OUT_RATE_CONTROL_DISABLE, !enable,
-			MPC_OUT_RATE_CONTROL, rate_2x_mode);
-
-	if (flow_control)
-		REG_UPDATE_2(MUX[opp_id],
-			MPC_OUT_FLOW_CONTROL_MODE, flow_control->flow_ctrl_mode,
-			MPC_OUT_FLOW_CONTROL_COUNT, flow_control->flow_ctrl_cnt1);
-}
-
 enum dc_lut_mode mpc3_get_ogam_current(struct mpc *mpc, int mpcc_id)
 {
 	/*Contrary to DCN2 and DCN1 wherein a single status register field holds this info;
@@ -1386,8 +1397,8 @@
 	.read_mpcc_state = mpc1_read_mpcc_state,
 	.insert_plane = mpc1_insert_plane,
 	.remove_mpcc = mpc1_remove_mpcc,
-	.mpc_init = mpc1_mpc_init,
-	.mpc_init_single_inst = mpc1_mpc_init_single_inst,
+	.mpc_init = mpc3_mpc_init,
+	.mpc_init_single_inst = mpc3_mpc_init_single_inst,
 	.update_blending = mpc2_update_blending,
 	.cursor_lock = mpc1_cursor_lock,
 	.get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
@@ -1404,7 +1415,6 @@
 	.set_dwb_mux = mpc3_set_dwb_mux,
 	.disable_dwb_mux = mpc3_disable_dwb_mux,
 	.is_dwb_idle = mpc3_is_dwb_idle,
-	.set_out_rate_control = mpc3_set_out_rate_control,
 	.set_gamut_remap = mpc3_set_gamut_remap,
 	.program_shaper = mpc3_program_shaper,
 	.acquire_rmu = mpcc3_acquire_rmu,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.h
@@ -1007,6 +1007,13 @@
 	int num_mpcc,
 	int num_rmu);
 
+void mpc3_mpc_init(
+	struct mpc *mpc);
+
+void mpc3_mpc_init_single_inst(
+	struct mpc *mpc,
+	unsigned int mpcc_id);
+
 bool mpc3_program_shaper(
 		struct mpc *mpc,
 		const struct pwl_params *params,
@@ -1074,13 +1081,6 @@
 	struct mpc *mpc,
 	int dwb_id);
 
-void mpc3_set_out_rate_control(
-	struct mpc *mpc,
-	int opp_id,
-	bool enable,
-	bool rate_2x_mode,
-	struct mpc_dwb_flow_control *flow_control);
-
 void mpc3_power_on_ogam_lut(
 	struct mpc *mpc, int mpcc_id,
 	bool power_on);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hpo_dp_link_encoder.c
@@ -395,6 +395,12 @@
 				x),
 			25));
 
+	// If y rounds up to integer, carry it over to x.
+	if (y >> 25) {
+		x += 1;
+		y = 0;
+	}
+
 	switch (stream_encoder_inst) {
 	case 0:
 		REG_SET_2(DP_DPHY_SYM32_VC_RATE_CNTL0, 0,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubbub.c
@@ -750,7 +750,8 @@
 	REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
 			DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 0x1FF);*/
 
-	hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
+	if (safe_to_lower || hubbub->ctx->dc->debug.disable_stutter)
+		hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
 	return wm_pending;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hubp.c
@@ -79,6 +79,7 @@
 	.hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings,
 	.set_blank = hubp2_set_blank,
 	.dcc_control = hubp3_dcc_control,
+	.hubp_reset = hubp_reset,
 	.mem_program_viewport = min_set_viewport,
 	.set_cursor_attributes	= hubp2_cursor_set_attributes,
 	.set_cursor_position	= hubp2_cursor_set_position,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
@@ -34,6 +34,7 @@
 #include "dc_bios_types.h"
 #include "link_enc_cfg.h"
 
+#include "dc_dmub_srv.h"
 #include "gpio_service_interface.h"
 
 #ifndef MIN
@@ -61,6 +62,38 @@
 #define AUX_REG_WRITE(reg_name, val) \
 			dm_write_reg(CTX, AUX_REG(reg_name), val)
 
+static uint8_t phy_id_from_transmitter(enum transmitter t)
+{
+	uint8_t phy_id;
+
+	switch (t) {
+	case TRANSMITTER_UNIPHY_A:
+		phy_id = 0;
+		break;
+	case TRANSMITTER_UNIPHY_B:
+		phy_id = 1;
+		break;
+	case TRANSMITTER_UNIPHY_C:
+		phy_id = 2;
+		break;
+	case TRANSMITTER_UNIPHY_D:
+		phy_id = 3;
+		break;
+	case TRANSMITTER_UNIPHY_E:
+		phy_id = 4;
+		break;
+	case TRANSMITTER_UNIPHY_F:
+		phy_id = 5;
+		break;
+	case TRANSMITTER_UNIPHY_G:
+		phy_id = 6;
+		break;
+	default:
+		phy_id = 0;
+		break;
+	}
+	return phy_id;
+}
 
 void enc32_hw_init(struct link_encoder *enc)
 {
@@ -117,38 +150,50 @@
 	}
 }
 
-static bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc)
+static bool query_dp_alt_from_dmub(struct link_encoder *enc,
+	union dmub_rb_cmd *cmd)
 {
 	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
-	uint32_t dp_alt_mode_disable = 0;
-	bool is_usb_c_alt_mode = false;
 
-	if (enc->features.flags.bits.DP_IS_USB_C) {
-		/* if value == 1 alt mode is disabled, otherwise it is enabled */
-		REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
-		is_usb_c_alt_mode = (dp_alt_mode_disable == 0);
-	}
+	memset(cmd, 0, sizeof(*cmd));
+	cmd->query_dp_alt.header.type = DMUB_CMD__VBIOS;
+	cmd->query_dp_alt.header.sub_type =
+		DMUB_CMD__VBIOS_TRANSMITTER_QUERY_DP_ALT;
+	cmd->query_dp_alt.header.payload_bytes = sizeof(cmd->query_dp_alt.data);
+	cmd->query_dp_alt.data.phy_id = phy_id_from_transmitter(enc10->base.transmitter);
 
-	return is_usb_c_alt_mode;
+	if (!dc_wake_and_execute_dmub_cmd(enc->ctx, cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
+		return false;
+
+	return true;
 }
 
-static void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc,
+bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc)
+{
+	union dmub_rb_cmd cmd;
+
+	if (!query_dp_alt_from_dmub(enc, &cmd))
+		return false;
+
+	return (cmd.query_dp_alt.data.is_dp_alt_disable == 0);
+}
+
+void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc,
 	struct dc_link_settings *link_settings)
 {
-	struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
-	uint32_t is_in_usb_c_dp4_mode = 0;
+	union dmub_rb_cmd cmd;
 
 	dcn10_link_encoder_get_max_link_cap(enc, link_settings);
 
-	/* in usb c dp2 mode, max lane count is 2 */
-	if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) {
-		REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
-		if (!is_in_usb_c_dp4_mode)
-			link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
-	}
+	if (!query_dp_alt_from_dmub(enc, &cmd))
+		return;
 
+	if (cmd.query_dp_alt.data.is_usb &&
+			cmd.query_dp_alt.data.is_dp4 == 0)
+		link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
 }
 
+
 static const struct link_encoder_funcs dcn32_link_enc_funcs = {
 	.read_state = link_enc2_read_state,
 	.validate_output_with_stream =
@@ -203,12 +248,12 @@
 	enc10->base.hpd_source = init_data->hpd_source;
 	enc10->base.connector = init_data->connector;
 
+	if (enc10->base.connector.id == CONNECTOR_ID_USBC)
+		enc10->base.features.flags.bits.DP_IS_USB_C = 1;
 
 	enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
 
 	enc10->base.features = *enc_features;
-	if (enc10->base.connector.id == CONNECTOR_ID_USBC)
-		enc10->base.features.flags.bits.DP_IS_USB_C = 1;
 
 	enc10->base.transmitter = init_data->transmitter;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.h
@@ -53,4 +53,9 @@
 	const struct dc_link_settings *link_settings,
 	enum clock_source_id clock_source);
 
+bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc);
+
+void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc,
+	struct dc_link_settings *link_settings);
+
 #endif /* __DC_LINK_ENCODER__DCN32_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubbub.c
@@ -786,7 +786,8 @@
 	REG_UPDATE(DCHUBBUB_ARB_DF_REQ_OUTSTAND,
 			DCHUBBUB_ARB_MIN_REQ_OUTSTAND, 0x1FF);*/
 
-	hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
+	if (safe_to_lower || hubbub->ctx->dc->debug.disable_stutter)
+		hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
 
 	hubbub32_force_usr_retraining_allow(hubbub, hubbub->ctx->dc->debug.force_usr_allow);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hubp.c
@@ -168,6 +168,8 @@
 {
 	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);
 	REG_WRITE(HUBPREQ_DEBUG_DB, 1 << 8);
+
+	REG_UPDATE(DCHUBP_CNTL, HUBP_TTU_DISABLE, 0);
 }
 static struct hubp_funcs dcn32_hubp_funcs = {
 	.hubp_enable_tripleBuffer = hubp2_enable_triplebuffer,
@@ -181,6 +183,7 @@
 	.set_blank = hubp2_set_blank,
 	.set_blank_regs = hubp2_set_blank_regs,
 	.dcc_control = hubp3_dcc_control,
+	.hubp_reset = hubp_reset,
 	.mem_program_viewport = min_set_viewport,
 	.set_cursor_attributes	= hubp32_cursor_set_attributes,
 	.set_cursor_position	= hubp2_cursor_set_position,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_mpc.c
@@ -47,7 +47,7 @@
 	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 	int mpcc_id;
 
-	mpc1_mpc_init(mpc);
+	mpc3_mpc_init(mpc);
 
 	if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
 		if (mpc30->mpc_mask->MPCC_MCM_SHAPER_MEM_LOW_PWR_MODE && mpc30->mpc_mask->MPCC_MCM_3DLUT_MEM_LOW_PWR_MODE) {
@@ -991,7 +991,7 @@
 	.insert_plane = mpc1_insert_plane,
 	.remove_mpcc = mpc1_remove_mpcc,
 	.mpc_init = mpc32_mpc_init,
-	.mpc_init_single_inst = mpc1_mpc_init_single_inst,
+	.mpc_init_single_inst = mpc3_mpc_init_single_inst,
 	.update_blending = mpc2_update_blending,
 	.cursor_lock = mpc1_cursor_lock,
 	.get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
@@ -1008,7 +1008,6 @@
 	.set_dwb_mux = mpc3_set_dwb_mux,
 	.disable_dwb_mux = mpc3_disable_dwb_mux,
 	.is_dwb_idle = mpc3_is_dwb_idle,
-	.set_out_rate_control = mpc3_set_out_rate_control,
 	.set_gamut_remap = mpc3_set_gamut_remap,
 	.program_shaper = mpc32_program_shaper,
 	.program_3dlut = mpc32_program_3dlut,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_resource_helpers.c
@@ -234,12 +234,12 @@
 				pipe->stream->timing.v_addressable != pipe->stream->src.height) {
 			is_center_timing = true;
 		}
-	}
 
-	if (pipe->plane_state) {
-		if (pipe->stream->timing.v_addressable != pipe->plane_state->dst_rect.height &&
-				pipe->stream->timing.v_addressable != pipe->plane_state->src_rect.height) {
-			is_center_timing = true;
+		if (pipe->plane_state) {
+			if (pipe->stream->timing.v_addressable != pipe->plane_state->dst_rect.height &&
+					pipe->stream->timing.v_addressable != pipe->plane_state->src_rect.height) {
+				is_center_timing = true;
+			}
 		}
 	}
 
@@ -673,7 +673,7 @@
 
 				subvp_disallow |= disallow_subvp_in_active_plus_blank(pipe);
 				refresh_rate = (pipe->stream->timing.pix_clk_100hz * (uint64_t)100 +
-					pipe->stream->timing.v_total * pipe->stream->timing.h_total - (uint64_t)1);
+					pipe->stream->timing.v_total * (unsigned long long)pipe->stream->timing.h_total - (uint64_t)1);
 				refresh_rate = div_u64(refresh_rate, pipe->stream->timing.v_total);
 				refresh_rate = div_u64(refresh_rate, pipe->stream->timing.h_total);
 			}
@@ -734,7 +734,7 @@
 
 				subvp_disallow |= disallow_subvp_in_active_plus_blank(pipe);
 				refresh_rate = (pipe->stream->timing.pix_clk_100hz * (uint64_t)100 +
-					pipe->stream->timing.v_total * pipe->stream->timing.h_total - (uint64_t)1);
+					pipe->stream->timing.v_total * (unsigned long long)pipe->stream->timing.h_total - (uint64_t)1);
 				refresh_rate = div_u64(refresh_rate, pipe->stream->timing.v_total);
 				refresh_rate = div_u64(refresh_rate, pipe->stream->timing.h_total);
 			}
@@ -782,3 +782,9 @@
 		pipe_cnt++;
 	}
 }
+
+void dcn32_override_min_req_dcfclk(struct dc *dc, struct dc_state *context)
+{
+	if (dcn32_subvp_in_use(dc, context) && context->bw_ctx.bw.dcn.clk.dcfclk_khz <= MIN_SUBVP_DCFCLK_KHZ)
+		context->bw_ctx.bw.dcn.clk.dcfclk_khz = MIN_SUBVP_DCFCLK_KHZ;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dccg.c
@@ -290,10 +290,10 @@
 
 		/* The recommended programming sequence to enable DTBCLK DTO to generate
 		 * valid pixel HPO DPSTREAM ENCODER, specifies that DTO source select should
-		 * be set only after DTO is enabled
+		 * be set only after DTO is enabled.
+		 * PIPEx_DTO_SRC_SEL should not be programmed during DTBCLK update since OTG may still be on, and the
+		 * programming is handled in program_pix_clk() regardless, so it can be removed from here.
 		 */
-		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
-				PIPE_DTO_SRC_SEL[params->otg_inst], 2);
 	} else {
 		switch (params->otg_inst) {
 		case 0:
@@ -310,9 +310,12 @@
 			break;
 		}
 
-		REG_UPDATE_2(OTG_PIXEL_RATE_CNTL[params->otg_inst],
-				DTBCLK_DTO_ENABLE[params->otg_inst], 0,
-				PIPE_DTO_SRC_SEL[params->otg_inst], params->is_hdmi ? 0 : 1);
+		/**
+		 * PIPEx_DTO_SRC_SEL should not be programmed during DTBCLK update since OTG may still be on, and the
+		 * programming is handled in program_pix_clk() regardless, so it can be removed from here.
+		 */
+		REG_UPDATE(OTG_PIXEL_RATE_CNTL[params->otg_inst],
+				DTBCLK_DTO_ENABLE[params->otg_inst], 0);
 
 		REG_WRITE(DTBCLK_DTO_MODULO[params->otg_inst], 0);
 		REG_WRITE(DTBCLK_DTO_PHASE[params->otg_inst], 0);
@@ -768,7 +771,7 @@
 	/* for DPMST, this backend could be used by multiple front end.
 	only disable the backend if this stream_enc_ins is the last active stream enc connected to this back_end*/
 		uint8_t i;
-		for (i = 0; i != link_enc_inst && i < sizeof(fe_clk_en); i++) {
+		for (i = 0; i != link_enc_inst && i < ARRAY_SIZE(fe_clk_en); i++) {
 			if (fe_clk_en[i] && be_clk_sel[i] == link_enc_inst)
 				num_enabled_symclk_fe++;
 		}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c
@@ -184,6 +184,8 @@
 	enc10->base.hpd_source = init_data->hpd_source;
 	enc10->base.connector = init_data->connector;
 
+	if (enc10->base.connector.id == CONNECTOR_ID_USBC)
+		enc10->base.features.flags.bits.DP_IS_USB_C = 1;
 
 	enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
 
@@ -238,8 +240,6 @@
 	}
 
 	enc10->base.features.flags.bits.HDMI_6GB_EN = 1;
-	if (enc10->base.connector.id == CONNECTOR_ID_USBC)
-		enc10->base.features.flags.bits.DP_IS_USB_C = 1;
 
 	if (bp_funcs->get_connector_speed_cap_info)
 		result = bp_funcs->get_connector_speed_cap_info(enc10->base.ctx->dc_bios,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubbub.c
@@ -326,7 +326,8 @@
 			DCHUBBUB_ARB_MIN_REQ_OUTSTAND_COMMIT_THRESHOLD, 0xA);/*hw delta*/
 	REG_UPDATE(DCHUBBUB_ARB_HOSTVM_CNTL, DCHUBBUB_ARB_MAX_QOS_COMMIT_THRESHOLD, 0xF);
 
-	hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
+	if (safe_to_lower || hubbub->ctx->dc->debug.disable_stutter)
+		hubbub1_allow_self_refresh_control(hubbub, !hubbub->ctx->dc->debug.disable_stutter);
 
 	hubbub32_force_usr_retraining_allow(hubbub, hubbub->ctx->dc->debug.force_usr_allow);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_hubp.c
@@ -199,6 +199,7 @@
 	.hubp_set_vm_system_aperture_settings = hubp3_set_vm_system_aperture_settings,
 	.set_blank = hubp2_set_blank,
 	.dcc_control = hubp3_dcc_control,
+	.hubp_reset = hubp_reset,
 	.mem_program_viewport = min_set_viewport,
 	.set_cursor_attributes	= hubp2_cursor_set_attributes,
 	.set_cursor_position	= hubp2_cursor_set_position,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/calcs/dcn_calcs.c
@@ -1453,10 +1453,9 @@
 	ASSERT(fclks->num_levels);
 
 	vmin0p65_idx = 0;
-	vmid0p72_idx = fclks->num_levels -
-		(fclks->num_levels > 2 ? 3 : (fclks->num_levels > 1 ? 2 : 1));
-	vnom0p8_idx = fclks->num_levels - (fclks->num_levels > 1 ? 2 : 1);
-	vmax0p9_idx = fclks->num_levels - 1;
+	vmid0p72_idx = fclks->num_levels > 2 ? fclks->num_levels - 3 : 0;
+	vnom0p8_idx = fclks->num_levels > 1 ? fclks->num_levels - 2 : 0;
+	vmax0p9_idx = fclks->num_levels > 0 ? fclks->num_levels - 1 : 0;
 
 	dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 =
 		32 * (fclks->data[vmin0p65_idx].clocks_in_khz / 1000.0) / 1000.0;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
@@ -78,7 +78,7 @@
 
 static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
 {
-	unsigned int ret_val = 0;
+	unsigned int ret_val = 1;
 
 	if (source_format == dm_444_16) {
 		if (!is_chroma)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20v2.c
@@ -78,7 +78,7 @@
 
 static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
 {
-	unsigned int ret_val = 0;
+	unsigned int ret_val = 1;
 
 	if (source_format == dm_444_16) {
 		if (!is_chroma)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn21/display_rq_dlg_calc_21.c
@@ -53,7 +53,7 @@
 
 static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
 {
-	unsigned int ret_val = 0;
+	unsigned int ret_val = 1;
 
 	if (source_format == dm_444_16) {
 		if (!is_chroma)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn30/display_mode_vba_30.c
@@ -4273,7 +4273,7 @@
 
 	//Calculate Swath, DET Configuration, DCFCLKDeepSleep
 	//
-	for (i = 0; i < mode_lib->soc.num_states; ++i) {
+	for (i = start_state; i < mode_lib->soc.num_states; ++i) {
 		for (j = 0; j <= 1; ++j) {
 			for (k = 0; k < v->NumberOfActivePlanes; ++k) {
 				v->RequiredDPPCLKThisState[k] = v->RequiredDPPCLK[i][j][k];
@@ -4576,7 +4576,7 @@
 
 	//Calculate Return BW
 
-	for (i = 0; i < mode_lib->soc.num_states; ++i) {
+	for (i = start_state; i < mode_lib->soc.num_states; ++i) {
 		for (j = 0; j <= 1; ++j) {
 			for (k = 0; k <= v->NumberOfActivePlanes - 1; k++) {
 				if (v->BlendingAndTiming[k] == k) {
@@ -4635,7 +4635,7 @@
 					v->UrgentOutOfOrderReturnPerChannelVMDataOnly);
 	v->FinalDRAMClockChangeLatency = (v->DRAMClockChangeLatencyOverride > 0 ? v->DRAMClockChangeLatencyOverride : v->DRAMClockChangeLatency);
 
-	for (i = 0; i < mode_lib->soc.num_states; ++i) {
+	for (i = start_state; i < mode_lib->soc.num_states; ++i) {
 		for (j = 0; j <= 1; ++j) {
 			v->DCFCLKState[i][j] = v->DCFCLKPerState[i];
 		}
@@ -4646,7 +4646,7 @@
 
 		if (v->ClampMinDCFCLK) {
 			/* Clamp calculated values to actual minimum */
-			for (i = 0; i < mode_lib->soc.num_states; ++i) {
+			for (i = start_state; i < mode_lib->soc.num_states; ++i) {
 				for (j = 0; j <= 1; ++j) {
 					if (v->DCFCLKState[i][j] < mode_lib->soc.min_dcfclk) {
 						v->DCFCLKState[i][j] = mode_lib->soc.min_dcfclk;
@@ -4656,7 +4656,7 @@
 		}
 	}
 
-	for (i = 0; i < mode_lib->soc.num_states; ++i) {
+	for (i = start_state; i < mode_lib->soc.num_states; ++i) {
 		for (j = 0; j <= 1; ++j) {
 			v->IdealSDPPortBandwidthPerState[i][j] = dml_min3(
 					v->ReturnBusWidth * v->DCFCLKState[i][j],
@@ -4674,7 +4674,7 @@
 
 	//Re-ordering Buffer Support Check
 
-	for (i = 0; i < mode_lib->soc.num_states; ++i) {
+	for (i = start_state; i < mode_lib->soc.num_states; ++i) {
 		for (j = 0; j <= 1; ++j) {
 			if ((v->ROBBufferSizeInKByte - v->PixelChunkSizeInKByte) * 1024 / v->ReturnBWPerState[i][j]
 					> (v->RoundTripPingLatencyCycles + 32) / v->DCFCLKState[i][j] + ReorderingBytes / v->ReturnBWPerState[i][j]) {
@@ -4692,7 +4692,7 @@
 		MaxTotalVActiveRDBandwidth = MaxTotalVActiveRDBandwidth + v->ReadBandwidthLuma[k] + v->ReadBandwidthChroma[k];
 	}
 
-	for (i = 0; i < mode_lib->soc.num_states; ++i) {
+	for (i = start_state; i < mode_lib->soc.num_states; ++i) {
 		for (j = 0; j <= 1; ++j) {
 			v->MaxTotalVerticalActiveAvailableBandwidth[i][j] = dml_min(
 					v->IdealSDPPortBandwidthPerState[i][j] * v->MaxAveragePercentOfIdealSDPPortBWDisplayCanUseInNormalSystemOperation / 100,
@@ -4708,7 +4708,7 @@
 
 	//Prefetch Check
 
-	for (i = 0; i < mode_lib->soc.num_states; ++i) {
+	for (i = start_state; i < mode_lib->soc.num_states; ++i) {
 		for (j = 0; j <= 1; ++j) {
 			int NextPrefetchModeState = MinPrefetchMode;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn302/dcn302_fpu.c
@@ -304,6 +304,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;
 		for (i = 0; i < dcn3_02_soc.num_states; i++) {
 			dcn3_02_soc.clock_limits[i].state = i;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn303/dcn303_fpu.c
@@ -266,6 +266,17 @@
 					optimal_uclk_for_dcfclk_sta_targets[i] =
 							bw_params->clk_table.entries[j].memclk_mhz * 16;
 					break;
+				} else {
+					/* condition where (dcfclk_sta_targets[i] >= optimal_dcfclk_for_uclk[j]):
+					 * This is required for dcn303 because it just so happens that the memory
+					 * bandwidth is low enough such that all the optimal DCFCLK for each UCLK
+					 * is lower than the smallest DCFCLK STA target. In this case we need to
+					 * populate the optimal UCLK for each DCFCLK STA target to be the max UCLK.
+					 */
+					if (j == num_uclk_states - 1) {
+						optimal_uclk_for_dcfclk_sta_targets[i] =
+								bw_params->clk_table.entries[j].memclk_mhz * 16;
+					}
 				}
 			}
 		}
@@ -299,6 +310,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;
 		for (i = 0; i < dcn3_03_soc.num_states; i++) {
 			dcn3_03_soc.clock_limits[i].state = i;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn31/dcn31_fpu.c
@@ -291,6 +291,7 @@
 	.do_urgent_latency_adjustment = false,
 	.urgent_latency_adjustment_fabric_clock_component_us = 0,
 	.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
+	.dispclk_dppclk_vco_speed_mhz = 2400.0,
 	.num_chans = 4,
 	.dummy_pstate_latency_us = 10.0
 };
@@ -438,6 +439,7 @@
 	.do_urgent_latency_adjustment = false,
 	.urgent_latency_adjustment_fabric_clock_component_us = 0,
 	.urgent_latency_adjustment_fabric_clock_reference_mhz = 0,
+	.dispclk_dppclk_vco_speed_mhz = 2500.0,
 };
 
 void dcn31_zero_pipe_dcc_fraction(display_e2e_pipe_params_st *pipes,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c
@@ -868,8 +868,9 @@
 	 * for VBLANK: (VACTIVE region of the SubVP pipe can fit the MALL prefetch, VBLANK frame time,
 	 * and the max of (VBLANK blanking time, MALL region)).
 	 */
-	if (stretched_drr_us < (1 / (double)drr_timing->min_refresh_in_uhz) * 1000000 * 1000000 &&
-			subvp_active_us - prefetch_us - stretched_drr_us - max_vblank_mallregion > 0)
+	if (drr_timing &&
+	    stretched_drr_us < (1 / (double)drr_timing->min_refresh_in_uhz) * 1000000 * 1000000 &&
+	    subvp_active_us - prefetch_us - stretched_drr_us - max_vblank_mallregion > 0)
 		schedulable = true;
 
 	return schedulable;
@@ -934,7 +935,7 @@
 		if (!subvp_pipe && pipe_mall_type == SUBVP_MAIN)
 			subvp_pipe = pipe;
 	}
-	if (found) {
+	if (found && subvp_pipe) {
 		phantom_stream = dc_state_get_paired_subvp_stream(context, subvp_pipe->stream);
 		main_timing = &subvp_pipe->stream->timing;
 		phantom_timing = &phantom_stream->timing;
@@ -2760,7 +2761,7 @@
 	struct _vcs_dpi_voltage_scaling_st entry = {0};
 	struct clk_limit_table_entry max_clk_data = {0};
 
-	unsigned int min_dcfclk_mhz = 199, min_fclk_mhz = 299;
+	unsigned int min_dcfclk_mhz = 399, min_fclk_mhz = 599;
 
 	static const unsigned int num_dcfclk_stas = 5;
 	unsigned int dcfclk_sta_targets[DC__VOLTAGE_STATES] = {199, 615, 906, 1324, 1564};
@@ -3207,6 +3208,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;
 			for (i = 0; i < dcn3_2_soc.num_states; i++) {
 				dcn3_2_soc.clock_limits[i].state = i;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c
@@ -3364,6 +3364,9 @@
 							&mode_lib->vba.UrgentBurstFactorLumaPre[k],
 							&mode_lib->vba.UrgentBurstFactorChromaPre[k],
 							&mode_lib->vba.NotUrgentLatencyHidingPre[k]);
+
+					v->cursor_bw_pre[k] = mode_lib->vba.NumberOfCursors[k] * mode_lib->vba.CursorWidth[k][0] * mode_lib->vba.CursorBPP[k][0] /
+							8.0 / (mode_lib->vba.HTotal[k] / mode_lib->vba.PixelClock[k]) * v->VRatioPreY[i][j][k];
 				}
 
 				{
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn321/dcn321_fpu.c
@@ -803,6 +803,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;
 		for (i = 0; i < dcn3_21_soc.num_states; i++) {
 			dcn3_21_soc.clock_limits[i].state = i;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c
@@ -177,7 +177,7 @@
 	.urgent_latency_pixel_data_only_us = 4.0,
 	.urgent_latency_pixel_mixed_with_vm_data_us = 4.0,
 	.urgent_latency_vm_data_only_us = 4.0,
-	.dram_clock_change_latency_us = 11.72,
+	.dram_clock_change_latency_us = 34.0,
 	.urgent_out_of_order_return_per_channel_pixel_only_bytes = 4096,
 	.urgent_out_of_order_return_per_channel_pixel_and_vm_bytes = 4096,
 	.urgent_out_of_order_return_per_channel_vm_only_bytes = 4096,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.c
@@ -1099,8 +1099,13 @@
 
 	// Total Available Pipes Support Check
 	for (k = 0; k < mode_lib->vba.NumberOfActivePlanes; ++k) {
-		total_pipes += mode_lib->vba.DPPPerPlane[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)
 			mode_lib->vba.DPPCLK[k] = mode_lib->vba.cache_pipes[pipe_idx].clks_cfg.dppclk_mhz;
 		else
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dml1_display_rq_dlg_calc.c
@@ -39,7 +39,7 @@
 
 static unsigned int get_bytes_per_element(enum source_format_class source_format, bool is_chroma)
 {
-	unsigned int ret_val = 0;
+	unsigned int ret_val = 1;
 
 	if (source_format == dm_444_16) {
 		if (!is_chroma)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml/dml_inline_defs.h
@@ -66,11 +66,15 @@
 
 static inline double dml_ceil(double a, double granularity)
 {
+	if (granularity == 0)
+		return 0;
 	return (double) dcn_bw_ceil2(a, granularity);
 }
 
 static inline double dml_floor(double a, double granularity)
 {
+	if (granularity == 0)
+		return 0;
 	return (double) dcn_bw_floor2(a, granularity);
 }
 
@@ -114,11 +118,15 @@
 
 static inline double dml_ceil_ex(double x, double granularity)
 {
+	if (granularity == 0)
+		return 0;
 	return (double) dcn_bw_ceil2(x, granularity);
 }
 
 static inline double dml_floor_ex(double x, double granularity)
 {
+	if (granularity == 0)
+		return 0;
 	return (double) dcn_bw_floor2(x, granularity);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/Makefile
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/Makefile
@@ -61,7 +61,11 @@
 
 ifneq ($(CONFIG_FRAME_WARN),0)
 ifeq ($(filter y,$(CONFIG_KASAN)$(CONFIG_KCSAN)),y)
+ifeq ($(CONFIG_CC_IS_CLANG)$(CONFIG_COMPILE_TEST),yy)
+frame_warn_flag := -Wframe-larger-than=4096
+else
 frame_warn_flag := -Wframe-larger-than=3072
+endif
 else
 frame_warn_flag := -Wframe-larger-than=2048
 endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c
@@ -1219,6 +1219,7 @@
 	s->dst_y_prefetch_oto = s->Tvm_oto_lines + 2 * s->Tr0_oto_lines + s->Lsw_oto;
 
 	s->dst_y_prefetch_equ = p->VStartup - (*p->TSetup + dml_max(p->TWait + p->TCalc, *p->Tdmdl)) / s->LineTime - (*p->DSTYAfterScaler + (dml_float_t) *p->DSTXAfterScaler / (dml_float_t)p->myPipe->HTotal);
+	s->dst_y_prefetch_equ = dml_min(s->dst_y_prefetch_equ, 63.75); // limit to the reg limit of U6.2 for DST_Y_PREFETCH
 
 #ifdef __DML_VBA_DEBUG__
 	dml_print("DML::%s: HTotal = %u\n", __func__, p->myPipe->HTotal);
@@ -4282,7 +4283,7 @@
 	}
 
 	*p->compbuf_reserved_space_64b = 2 * p->PixelChunkSizeInKByte * 1024 / 64;
-	if (p->UnboundedRequestEnabled) {
+	if (*p->UnboundedRequestEnabled) {
 		*p->compbuf_reserved_space_64b = dml_max(*p->compbuf_reserved_space_64b,
 				(dml_float_t)(p->ROBBufferSizeInKByte * 1024/64)
 				- (dml_float_t)(RoundedUpSwathSizeBytesY[SurfaceDoingUnboundedRequest] * TTUFIFODEPTH / MAXIMUMCOMPRESSION/64));
@@ -6298,9 +6299,9 @@
 			mode_lib->ms.meta_row_bandwidth_this_state,
 			mode_lib->ms.dpte_row_bandwidth_this_state,
 			mode_lib->ms.NoOfDPPThisState,
-			mode_lib->ms.UrgentBurstFactorLuma,
-			mode_lib->ms.UrgentBurstFactorChroma,
-			mode_lib->ms.UrgentBurstFactorCursor);
+			mode_lib->ms.UrgentBurstFactorLuma[j],
+			mode_lib->ms.UrgentBurstFactorChroma[j],
+			mode_lib->ms.UrgentBurstFactorCursor[j]);
 
 		s->VMDataOnlyReturnBWPerState = dml_get_return_bw_mbps_vm_only(
 																	&mode_lib->ms.soc,
@@ -6431,7 +6432,7 @@
 							/* Output */
 							&mode_lib->ms.UrgentBurstFactorCursorPre[k],
 							&mode_lib->ms.UrgentBurstFactorLumaPre[k],
-							&mode_lib->ms.UrgentBurstFactorChroma[k],
+							&mode_lib->ms.UrgentBurstFactorChromaPre[k],
 							&mode_lib->ms.NotUrgentLatencyHidingPre[k]);
 
 					mode_lib->ms.cursor_bw_pre[k] = mode_lib->ms.cache_display_cfg.plane.NumberOfCursors[k] * mode_lib->ms.cache_display_cfg.plane.CursorWidth[k] *
@@ -6455,9 +6456,9 @@
 				mode_lib->ms.cursor_bw_pre,
 				mode_lib->ms.prefetch_vmrow_bw,
 				mode_lib->ms.NoOfDPPThisState,
-				mode_lib->ms.UrgentBurstFactorLuma,
-				mode_lib->ms.UrgentBurstFactorChroma,
-				mode_lib->ms.UrgentBurstFactorCursor,
+				mode_lib->ms.UrgentBurstFactorLuma[j],
+				mode_lib->ms.UrgentBurstFactorChroma[j],
+				mode_lib->ms.UrgentBurstFactorCursor[j],
 				mode_lib->ms.UrgentBurstFactorLumaPre,
 				mode_lib->ms.UrgentBurstFactorChromaPre,
 				mode_lib->ms.UrgentBurstFactorCursorPre,
@@ -6514,9 +6515,9 @@
 						mode_lib->ms.cursor_bw,
 						mode_lib->ms.cursor_bw_pre,
 						mode_lib->ms.NoOfDPPThisState,
-						mode_lib->ms.UrgentBurstFactorLuma,
-						mode_lib->ms.UrgentBurstFactorChroma,
-						mode_lib->ms.UrgentBurstFactorCursor,
+						mode_lib->ms.UrgentBurstFactorLuma[j],
+						mode_lib->ms.UrgentBurstFactorChroma[j],
+						mode_lib->ms.UrgentBurstFactorCursor[j],
 						mode_lib->ms.UrgentBurstFactorLumaPre,
 						mode_lib->ms.UrgentBurstFactorChromaPre,
 						mode_lib->ms.UrgentBurstFactorCursorPre);
@@ -6583,9 +6584,9 @@
 													mode_lib->ms.cursor_bw_pre,
 													mode_lib->ms.prefetch_vmrow_bw,
 													mode_lib->ms.NoOfDPP[j], // VBA_ERROR DPPPerSurface is not assigned at this point, should use NoOfDpp here
-													mode_lib->ms.UrgentBurstFactorLuma,
-													mode_lib->ms.UrgentBurstFactorChroma,
-													mode_lib->ms.UrgentBurstFactorCursor,
+													mode_lib->ms.UrgentBurstFactorLuma[j],
+													mode_lib->ms.UrgentBurstFactorChroma[j],
+													mode_lib->ms.UrgentBurstFactorCursor[j],
 													mode_lib->ms.UrgentBurstFactorLumaPre,
 													mode_lib->ms.UrgentBurstFactorChromaPre,
 													mode_lib->ms.UrgentBurstFactorCursorPre,
@@ -7799,9 +7800,9 @@
 				mode_lib->ms.DETBufferSizeYThisState[k],
 				mode_lib->ms.DETBufferSizeCThisState[k],
 				/* Output */
-				&mode_lib->ms.UrgentBurstFactorCursor[k],
-				&mode_lib->ms.UrgentBurstFactorLuma[k],
-				&mode_lib->ms.UrgentBurstFactorChroma[k],
+				&mode_lib->ms.UrgentBurstFactorCursor[j][k],
+				&mode_lib->ms.UrgentBurstFactorLuma[j][k],
+				&mode_lib->ms.UrgentBurstFactorChroma[j][k],
 				&mode_lib->ms.NotUrgentLatencyHiding[k]);
 		}
 
@@ -9180,6 +9181,8 @@
 			&locals->FractionOfUrgentBandwidth,
 			&s->dummy_boolean[0]); // dml_bool_t *PrefetchBandwidthSupport
 
+
+
 		if (s->VRatioPrefetchMoreThanMax != false || s->DestinationLineTimesForPrefetchLessThan2 != false) {
 			dml_print("DML::%s: VRatioPrefetchMoreThanMax                   = %u\n", __func__, s->VRatioPrefetchMoreThanMax);
 			dml_print("DML::%s: DestinationLineTimesForPrefetchLessThan2    = %u\n", __func__, s->DestinationLineTimesForPrefetchLessThan2);
@@ -9194,6 +9197,7 @@
 			}
 		}
 
+
 		if (locals->PrefetchModeSupported == true && mode_lib->ms.support.ImmediateFlipSupport == true) {
 			locals->BandwidthAvailableForImmediateFlip = CalculateBandwidthAvailableForImmediateFlip(
 																	mode_lib->ms.num_active_planes,
@@ -9460,8 +9464,10 @@
 
 		/* Copy the calculated watermarks to mp.Watermark as the getter functions are
 		 * implemented by the DML team to copy the calculated values from the mp.Watermark interface.
+		 * &mode_lib->mp.Watermark and &locals->Watermark are the same address, memcpy may lead to
+		 * unexpected behavior. memmove should be used.
 		 */
-		memcpy(&mode_lib->mp.Watermark, CalculateWatermarks_params->Watermark, sizeof(struct Watermarks));
+		memmove(&mode_lib->mp.Watermark, CalculateWatermarks_params->Watermark, sizeof(struct Watermarks));
 
 		for (k = 0; k < mode_lib->ms.num_active_planes; ++k) {
 			if (mode_lib->ms.cache_display_cfg.writeback.WritebackEnable[k] == true) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core_structs.h
@@ -882,11 +882,11 @@
 	dml_uint_t meta_row_height[__DML_NUM_PLANES__];
 	dml_uint_t meta_row_height_chroma[__DML_NUM_PLANES__];
 	dml_float_t UrgLatency;
-	dml_float_t UrgentBurstFactorCursor[__DML_NUM_PLANES__];
+	dml_float_t UrgentBurstFactorCursor[2][__DML_NUM_PLANES__];
 	dml_float_t UrgentBurstFactorCursorPre[__DML_NUM_PLANES__];
-	dml_float_t UrgentBurstFactorLuma[__DML_NUM_PLANES__];
+	dml_float_t UrgentBurstFactorLuma[2][__DML_NUM_PLANES__];
 	dml_float_t UrgentBurstFactorLumaPre[__DML_NUM_PLANES__];
-	dml_float_t UrgentBurstFactorChroma[__DML_NUM_PLANES__];
+	dml_float_t UrgentBurstFactorChroma[2][__DML_NUM_PLANES__];
 	dml_float_t UrgentBurstFactorChromaPre[__DML_NUM_PLANES__];
 	dml_float_t MaximumSwathWidthInLineBufferLuma;
 	dml_float_t MaximumSwathWidthInLineBufferChroma;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/dml2_dc_resource_mgmt.c
@@ -88,7 +88,8 @@
 			return  i;
 	}
 
-	return -1;
+	ASSERT(false);
+	return __DML2_WRAPPER_MAX_STREAMS_PLANES__;
 }
 
 static int find_disp_cfg_idx_by_stream_id(struct dml2_dml_to_dc_pipe_mapping *mapping, unsigned int stream_id)
@@ -100,7 +101,8 @@
 			return  i;
 	}
 
-	return -1;
+	ASSERT(false);
+	return __DML2_WRAPPER_MAX_STREAMS_PLANES__;
 }
 
 // The master pipe of a stream is defined as the top pipe in odm slice 0
@@ -237,12 +239,25 @@
 	 * However this condition comes with a caveat. We need to ignore pipes that will
 	 * require a change in OPP but still have the same stream id. For example during
 	 * an MPC to ODM transiton.
+	 *
+	 * Adding check to avoid pipe select on the head pipe by utilizing dc resource
+	 * helper function resource_get_primary_dpp_pipe and comparing the pipe index.
 	 */
 	if (existing_state) {
 		for (i = 0; i < pipe_count; i++) {
 			if (existing_state->res_ctx.pipe_ctx[i].stream && existing_state->res_ctx.pipe_ctx[i].stream->stream_id == stream_id) {
+				struct pipe_ctx *head_pipe =
+					resource_is_pipe_type(&existing_state->res_ctx.pipe_ctx[i], DPP_PIPE) ?
+						resource_get_primary_dpp_pipe(&existing_state->res_ctx.pipe_ctx[i]) :
+							NULL;
+
+				// we should always respect the head pipe from selection
+				if (head_pipe && head_pipe->pipe_idx == i)
+					continue;
 				if (existing_state->res_ctx.pipe_ctx[i].plane_res.hubp &&
-					existing_state->res_ctx.pipe_ctx[i].plane_res.hubp->opp_id != i)
+					existing_state->res_ctx.pipe_ctx[i].plane_res.hubp->opp_id != i &&
+						(existing_state->res_ctx.pipe_ctx[i].prev_odm_pipe ||
+						existing_state->res_ctx.pipe_ctx[i].next_odm_pipe))
 					continue;
 
 				preferred_pipe_candidates[num_preferred_candidates++] = i;
@@ -271,6 +286,14 @@
 	 */
 	if (existing_state) {
 		for (i  = 0; i < pipe_count; i++) {
+			struct pipe_ctx *head_pipe =
+				resource_is_pipe_type(&existing_state->res_ctx.pipe_ctx[i], DPP_PIPE) ?
+					resource_get_primary_dpp_pipe(&existing_state->res_ctx.pipe_ctx[i]) :
+						NULL;
+
+			// we should always respect the head pipe from selection
+			if (head_pipe && head_pipe->pipe_idx == i)
+				continue;
 			if ((existing_state->res_ctx.pipe_ctx[i].plane_res.hubp &&
 				existing_state->res_ctx.pipe_ctx[i].plane_res.hubp->opp_id != i) ||
 				existing_state->res_ctx.pipe_ctx[i].stream_res.tg)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/dml2_mall_phantom.c
@@ -750,6 +750,8 @@
 					ctx->config.svp_pstate.callbacks.dc,
 					state,
 					curr_pipe->plane_state);
+			if (!phantom_plane)
+				return;
 		}
 
 		memcpy(&phantom_plane->address, &curr_pipe->plane_state->address, sizeof(phantom_plane->address));
@@ -811,7 +813,7 @@
 {
 	int i, old_plane_count;
 	struct dc_stream_status *stream_status = NULL;
-	struct dc_plane_state *del_planes[MAX_SURFACE_NUM] = { 0 };
+	struct dc_plane_state *del_planes[MAX_SURFACES] = { 0 };
 
 	for (i = 0; i < context->stream_count; i++)
 			if (context->streams[i] == stream) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
@@ -228,17 +228,14 @@
 		break;
 
 	case dml_project_dcn35:
+	case dml_project_dcn351:
 		out->num_chans = 4;
 		out->round_trip_ping_latency_dcfclk_cycles = 106;
 		out->smn_latency_us = 2;
 		out->dispclk_dppclk_vco_speed_mhz = 3600;
+		out->pct_ideal_dram_bw_after_urgent_pixel_only = 65.0;
 		break;
 
-	case dml_project_dcn351:
-		out->num_chans = 16;
-		out->round_trip_ping_latency_dcfclk_cycles = 1100;
-		out->smn_latency_us = 2;
-		break;
 	}
 	/* ---Overrides if available--- */
 	if (dml2->config.bbox_overrides.dram_num_chan)
@@ -798,7 +795,7 @@
 	}
 }
 
-static struct scaler_data get_scaler_data_for_plane(const struct dc_plane_state *in, struct dc_state *context)
+static void get_scaler_data_for_plane(const struct dc_plane_state *in, struct dc_state *context, struct scaler_data *out)
 {
 	int i;
 	struct pipe_ctx *temp_pipe = &context->res_ctx.temp_pipe;
@@ -819,18 +816,32 @@
 	}
 
 	ASSERT(i < MAX_PIPES);
-	return temp_pipe->plane_res.scl_data;
+	memcpy(out, &temp_pipe->plane_res.scl_data, sizeof(*out));
 }
 
-static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned int location, const struct dc_stream_state *in)
+static void populate_dummy_dml_plane_cfg(struct dml_plane_cfg_st *out, unsigned int location,
+					 const struct dc_stream_state *in,
+					 const struct soc_bounding_box_st *soc)
 {
+	dml_uint_t width, height;
+
+	if (in->timing.h_addressable > 3840)
+		width = 3840;
+	else
+		width = in->timing.h_addressable;	// 4K max
+
+	if (in->timing.v_addressable > 2160)
+		height = 2160;
+	else
+		height = in->timing.v_addressable;	// 4K max
+
 	out->CursorBPP[location] = dml_cur_32bit;
 	out->CursorWidth[location] = 256;
 
-	out->GPUVMMinPageSizeKBytes[location] = 256;
+	out->GPUVMMinPageSizeKBytes[location] = soc->gpuvm_min_page_size_kbytes;
 
-	out->ViewportWidth[location] = in->timing.h_addressable;
-	out->ViewportHeight[location] = in->timing.v_addressable;
+	out->ViewportWidth[location] = width;
+	out->ViewportHeight[location] = height;
 	out->ViewportStationary[location] = false;
 	out->ViewportWidthChroma[location] = 0;
 	out->ViewportHeightChroma[location] = 0;
@@ -849,7 +860,7 @@
 	out->HTapsChroma[location] = 0;
 	out->VTapsChroma[location] = 0;
 	out->SourceScan[location] = dml_rotation_0;
-	out->ScalerRecoutWidth[location] = in->timing.h_addressable;
+	out->ScalerRecoutWidth[location] = width;
 
 	out->LBBitPerPixel[location] = 57;
 
@@ -864,29 +875,35 @@
 	out->ScalerEnabled[location] = false;
 }
 
-static void populate_dml_plane_cfg_from_plane_state(struct dml_plane_cfg_st *out, unsigned int location, const struct dc_plane_state *in, struct dc_state *context)
-{
-	const struct scaler_data scaler_data = get_scaler_data_for_plane(in, context);
+static void populate_dml_plane_cfg_from_plane_state(struct dml_plane_cfg_st *out, unsigned int location,
+						    const struct dc_plane_state *in, struct dc_state *context,
+						    const struct soc_bounding_box_st *soc)
+{
+	struct scaler_data *scaler_data = kzalloc(sizeof(*scaler_data), GFP_KERNEL);
+	if (!scaler_data)
+		return;
+
+	get_scaler_data_for_plane(in, context, scaler_data);
 
 	out->CursorBPP[location] = dml_cur_32bit;
 	out->CursorWidth[location] = 256;
 
-	out->GPUVMMinPageSizeKBytes[location] = 256;
+	out->GPUVMMinPageSizeKBytes[location] = soc->gpuvm_min_page_size_kbytes;
 
-	out->ViewportWidth[location] = scaler_data.viewport.width;
-	out->ViewportHeight[location] = scaler_data.viewport.height;
-	out->ViewportWidthChroma[location] = scaler_data.viewport_c.width;
-	out->ViewportHeightChroma[location] = scaler_data.viewport_c.height;
-	out->ViewportXStart[location] = scaler_data.viewport.x;
-	out->ViewportYStart[location] = scaler_data.viewport.y;
-	out->ViewportXStartC[location] = scaler_data.viewport_c.x;
-	out->ViewportYStartC[location] = scaler_data.viewport_c.y;
+	out->ViewportWidth[location] = scaler_data->viewport.width;
+	out->ViewportHeight[location] = scaler_data->viewport.height;
+	out->ViewportWidthChroma[location] = scaler_data->viewport_c.width;
+	out->ViewportHeightChroma[location] = scaler_data->viewport_c.height;
+	out->ViewportXStart[location] = scaler_data->viewport.x;
+	out->ViewportYStart[location] = scaler_data->viewport.y;
+	out->ViewportXStartC[location] = scaler_data->viewport_c.x;
+	out->ViewportYStartC[location] = scaler_data->viewport_c.y;
 	out->ViewportStationary[location] = false;
 
-	out->ScalerEnabled[location] = scaler_data.ratios.horz.value != dc_fixpt_one.value ||
-				scaler_data.ratios.horz_c.value != dc_fixpt_one.value ||
-				scaler_data.ratios.vert.value != dc_fixpt_one.value ||
-				scaler_data.ratios.vert_c.value != dc_fixpt_one.value;
+	out->ScalerEnabled[location] = scaler_data->ratios.horz.value != dc_fixpt_one.value ||
+				scaler_data->ratios.horz_c.value != dc_fixpt_one.value ||
+				scaler_data->ratios.vert.value != dc_fixpt_one.value ||
+				scaler_data->ratios.vert_c.value != dc_fixpt_one.value;
 
 	/* Current driver code base uses LBBitPerPixel as 57. There is a discrepancy
 	 * from the HW/DML teams about this value. Initialize LBBitPerPixel with the
@@ -902,25 +919,25 @@
 		out->VRatioChroma[location] = 1;
 	} else {
 		/* Follow the original dml_wrapper.c code direction to fix scaling issues */
-		out->HRatio[location] = (dml_float_t)scaler_data.ratios.horz.value / (1ULL << 32);
-		out->HRatioChroma[location] = (dml_float_t)scaler_data.ratios.horz_c.value / (1ULL << 32);
-		out->VRatio[location] = (dml_float_t)scaler_data.ratios.vert.value / (1ULL << 32);
-		out->VRatioChroma[location] = (dml_float_t)scaler_data.ratios.vert_c.value / (1ULL << 32);
+		out->HRatio[location] = (dml_float_t)scaler_data->ratios.horz.value / (1ULL << 32);
+		out->HRatioChroma[location] = (dml_float_t)scaler_data->ratios.horz_c.value / (1ULL << 32);
+		out->VRatio[location] = (dml_float_t)scaler_data->ratios.vert.value / (1ULL << 32);
+		out->VRatioChroma[location] = (dml_float_t)scaler_data->ratios.vert_c.value / (1ULL << 32);
 	}
 
-	if (!scaler_data.taps.h_taps) {
+	if (!scaler_data->taps.h_taps) {
 		out->HTaps[location] = 1;
 		out->HTapsChroma[location] = 1;
 	} else {
-		out->HTaps[location] = scaler_data.taps.h_taps;
-		out->HTapsChroma[location] = scaler_data.taps.h_taps_c;
+		out->HTaps[location] = scaler_data->taps.h_taps;
+		out->HTapsChroma[location] = scaler_data->taps.h_taps_c;
 	}
-	if (!scaler_data.taps.v_taps) {
+	if (!scaler_data->taps.v_taps) {
 		out->VTaps[location] = 1;
 		out->VTapsChroma[location] = 1;
 	} else {
-		out->VTaps[location] = scaler_data.taps.v_taps;
-		out->VTapsChroma[location] = scaler_data.taps.v_taps_c;
+		out->VTaps[location] = scaler_data->taps.v_taps;
+		out->VTapsChroma[location] = scaler_data->taps.v_taps_c;
 	}
 
 	out->SourceScan[location] = (enum dml_rotation_angle)in->rotation;
@@ -931,6 +948,8 @@
 	out->DynamicMetadataTransmittedBytes[location] = 0;
 
 	out->NumberOfCursors[location] = 1;
+
+	kfree(scaler_data);
 }
 
 static unsigned int map_stream_to_dml_display_cfg(const struct dml2_context *dml2,
@@ -1107,7 +1126,8 @@
 			disp_cfg_plane_location = dml_dispcfg->num_surfaces++;
 
 			populate_dummy_dml_surface_cfg(&dml_dispcfg->surface, disp_cfg_plane_location, context->streams[i]);
-			populate_dummy_dml_plane_cfg(&dml_dispcfg->plane, disp_cfg_plane_location, context->streams[i]);
+			populate_dummy_dml_plane_cfg(&dml_dispcfg->plane, disp_cfg_plane_location,
+						     context->streams[i], &dml2->v20.dml_core_ctx.soc);
 
 			dml_dispcfg->plane.BlendingAndTiming[disp_cfg_plane_location] = disp_cfg_stream_location;
 
@@ -1123,7 +1143,10 @@
 				ASSERT(disp_cfg_plane_location >= 0 && disp_cfg_plane_location <= __DML2_WRAPPER_MAX_STREAMS_PLANES__);
 
 				populate_dml_surface_cfg_from_plane_state(dml2->v20.dml_core_ctx.project, &dml_dispcfg->surface, disp_cfg_plane_location, context->stream_status[i].plane_states[j]);
-				populate_dml_plane_cfg_from_plane_state(&dml_dispcfg->plane, disp_cfg_plane_location, context->stream_status[i].plane_states[j], context);
+				populate_dml_plane_cfg_from_plane_state(
+					&dml_dispcfg->plane, disp_cfg_plane_location,
+					context->stream_status[i].plane_states[j], context,
+					&dml2->v20.dml_core_ctx.soc);
 
 				if (stream_mall_type == SUBVP_MAIN) {
 					dml_dispcfg->plane.UseMALLForPStateChange[disp_cfg_plane_location] = dml_use_mall_pstate_change_sub_viewport;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/dml2_utils.c
@@ -294,7 +294,7 @@
 	context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = (unsigned int)in_ctx->v20.dml_core_ctx.mp.DCFCLKDeepSleep * 1000;
 	context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;
 
-	if (in_ctx->v20.dml_core_ctx.ms.support.FCLKChangeSupport[in_ctx->v20.scratch.mode_support_params.out_lowest_state_idx] == dml_fclock_change_unsupported)
+	if (in_ctx->v20.dml_core_ctx.ms.support.FCLKChangeSupport[0] == dml_fclock_change_unsupported)
 		context->bw_ctx.bw.dcn.clk.fclk_p_state_change_support = false;
 	else
 		context->bw_ctx.bw.dcn.clk.fclk_p_state_change_support = true;
@@ -327,6 +327,8 @@
 			dml_pipe_idx = dml2_helper_find_dml_pipe_idx_by_stream_id(in_ctx, context->res_ctx.pipe_ctx[dc_pipe_ctx_index].stream->stream_id);
 		}
 
+		if (dml_pipe_idx == 0xFFFFFFFF)
+			continue;
 		ASSERT(in_ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_stream_id_valid[dml_pipe_idx]);
 		ASSERT(in_ctx->v20.scratch.dml_to_dc_pipe_mapping.dml_pipe_idx_to_stream_id[dml_pipe_idx] == context->res_ctx.pipe_ctx[dc_pipe_ctx_index].stream->stream_id);
 
@@ -468,6 +470,9 @@
 			dml_pipe_idx = find_dml_pipe_idx_by_plane_id(in_ctx, plane_id);
 		else
 			dml_pipe_idx = dml2_helper_find_dml_pipe_idx_by_stream_id(in_ctx, display_state->res_ctx.pipe_ctx[i].stream->stream_id);
+
+		if (dml_pipe_idx == 0xFFFFFFFF)
+			continue;
 		total_det_allocated += dml_get_det_buffer_size_kbytes(&in_ctx->v20.dml_core_ctx, dml_pipe_idx);
 		if (total_det_allocated > max_det_size) {
 			need_recalculation = true;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.c
@@ -534,14 +534,21 @@
 static bool call_dml_mode_support_and_programming(struct dc_state *context)
 {
 	unsigned int result = 0;
-	unsigned int min_state;
+	unsigned int min_state = 0;
 	int min_state_for_g6_temp_read = 0;
+
+
+	if (!context)
+		return false;
+
 	struct dml2_context *dml2 = context->bw_ctx.dml2;
 	struct dml2_wrapper_scratch *s = &dml2->v20.scratch;
 
-	min_state_for_g6_temp_read = calculate_lowest_supported_state_for_temp_read(dml2, context);
+	if (!context->streams[0]->sink->link->dc->caps.is_apu) {
+		min_state_for_g6_temp_read = calculate_lowest_supported_state_for_temp_read(dml2, context);
 
-	ASSERT(min_state_for_g6_temp_read >= 0);
+		ASSERT(min_state_for_g6_temp_read >= 0);
+	}
 
 	if (!dml2->config.use_native_pstate_optimization) {
 		result = optimize_pstate_with_svp_and_drr(dml2, context);
@@ -552,14 +559,20 @@
 	/* Upon trying to sett certain frequencies in FRL, min_state_for_g6_temp_read is reported as -1. This leads to an invalid value of min_state causing crashes later on.
 	 * Use the default logic for min_state only when min_state_for_g6_temp_read is a valid value. In other cases, use the value calculated by the DML directly.
 	 */
-	if (min_state_for_g6_temp_read >= 0)
-		min_state = min_state_for_g6_temp_read > s->mode_support_params.out_lowest_state_idx ? min_state_for_g6_temp_read : s->mode_support_params.out_lowest_state_idx;
-	else
-		min_state = s->mode_support_params.out_lowest_state_idx;
-
-	if (result)
-		result = dml_mode_programming(&dml2->v20.dml_core_ctx, min_state, &s->cur_display_config, true);
+	if (!context->streams[0]->sink->link->dc->caps.is_apu) {
+		if (min_state_for_g6_temp_read >= 0)
+			min_state = min_state_for_g6_temp_read > s->mode_support_params.out_lowest_state_idx ? min_state_for_g6_temp_read : s->mode_support_params.out_lowest_state_idx;
+		else
+			min_state = s->mode_support_params.out_lowest_state_idx;
+	}
 
+	if (result) {
+		if (!context->streams[0]->sink->link->dc->caps.is_apu) {
+			result = dml_mode_programming(&dml2->v20.dml_core_ctx, min_state, &s->cur_display_config, true);
+		} else {
+			result = dml_mode_programming(&dml2->v20.dml_core_ctx, s->mode_support_params.out_lowest_state_idx, &s->cur_display_config, true);
+		}
+	}
 	return result;
 }
 
@@ -663,6 +676,8 @@
 	build_unoptimized_policy_settings(dml2->v20.dml_core_ctx.project, &dml2->v20.dml_core_ctx.policy);
 
 	map_dc_state_into_dml_display_cfg(dml2, context, &dml2->v20.scratch.cur_display_config);
+	 if (!dml2->config.skip_hw_state_mapping)
+		 dml2_apply_det_buffer_allocation_policy(dml2, &dml2->v20.scratch.cur_display_config);
 
 	result = pack_and_call_dml_mode_support_ex(dml2,
 		&dml2->v20.scratch.cur_display_config,
@@ -703,13 +718,8 @@
 	return (struct dml2_context *) kzalloc(sizeof(struct dml2_context), GFP_KERNEL);
 }
 
-bool dml2_create(const struct dc *in_dc, const struct dml2_configuration_options *config, struct dml2_context **dml2)
+static void dml2_init(const struct dc *in_dc, const struct dml2_configuration_options *config, struct dml2_context **dml2)
 {
-	// Allocate Mode Lib Ctx
-	*dml2 = dml2_allocate_memory();
-
-	if (!(*dml2))
-		return false;
 
 	// Store config options
 	(*dml2)->config = *config;
@@ -737,9 +747,18 @@
 	initialize_dml2_soc_bbox(*dml2, in_dc, &(*dml2)->v20.dml_core_ctx.soc);
 
 	initialize_dml2_soc_states(*dml2, in_dc, &(*dml2)->v20.dml_core_ctx.soc, &(*dml2)->v20.dml_core_ctx.states);
+}
+
+bool dml2_create(const struct dc *in_dc, const struct dml2_configuration_options *config, struct dml2_context **dml2)
+{
+	// Allocate Mode Lib Ctx
+	*dml2 = dml2_allocate_memory();
+
+	if (!(*dml2))
+		return false;
+
+	dml2_init(in_dc, config, dml2);
 
-	/*Initialize DML20 instance which calls dml2_core_create, and core_dcn3_populate_informative*/
-	//dml2_initialize_instance(&(*dml_ctx)->v20.dml_init);
 	return true;
 }
 
@@ -779,3 +798,11 @@
 
 	return true;
 }
+
+void dml2_reinit(const struct dc *in_dc,
+				 const struct dml2_configuration_options *config,
+				 struct dml2_context **dml2)
+{
+
+	dml2_init(in_dc, config, dml2);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dml2/dml2_wrapper.h
@@ -214,6 +214,9 @@
 	struct dml2_context *src_dml2);
 bool dml2_create_copy(struct dml2_context **dst_dml2,
 	struct dml2_context *src_dml2);
+void dml2_reinit(const struct dc *in_dc,
+				 const struct dml2_configuration_options *config,
+				 struct dml2_context **dml2);
 
 /*
  * dml2_validate - Determines if a display configuration is supported or not.
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
@@ -878,7 +878,7 @@
 
 	memset(dsc_cfg, 0, sizeof(struct dc_dsc_config));
 
-	dc_dsc_get_policy_for_timing(timing, options->max_target_bpp_limit_override_x16, &policy);
+	dc_dsc_get_policy_for_timing(timing, options->max_target_bpp_limit_override_x16, &policy, link_encoding);
 	pic_width = timing->h_addressable + timing->h_border_left + timing->h_border_right;
 	pic_height = timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
 
@@ -1050,7 +1050,12 @@
 	if (!is_dsc_possible)
 		goto done;
 
-	dsc_cfg->num_slices_v = pic_height/slice_height;
+	if (slice_height > 0) {
+		dsc_cfg->num_slices_v = pic_height / slice_height;
+	} else {
+		is_dsc_possible = false;
+		goto done;
+	}
 
 	if (target_bandwidth_kbps > 0) {
 		is_dsc_possible = decide_dsc_target_bpp_x16(
@@ -1146,7 +1151,8 @@
 
 void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing,
 		uint32_t max_target_bpp_limit_override_x16,
-		struct dc_dsc_policy *policy)
+		struct dc_dsc_policy *policy,
+		const enum dc_link_encoding_format link_encoding)
 {
 	uint32_t bpc = 0;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c
@@ -56,7 +56,7 @@
 	struct dc_context *ctx)
 {
 	struct gpio_service *service;
-	uint32_t index_of_id;
+	int32_t index_of_id;
 
 	service = kzalloc(sizeof(struct gpio_service), GFP_KERNEL);
 
@@ -112,7 +112,7 @@
 	return service;
 
 failure_2:
-	while (index_of_id) {
+	while (index_of_id > 0) {
 		--index_of_id;
 		kfree(service->busyness[index_of_id]);
 	}
@@ -239,6 +239,9 @@
 	enum gpio_id id,
 	uint32_t en)
 {
+	if (id == GPIO_ID_UNKNOWN)
+		return false;
+
 	return service->busyness[id][en];
 }
 
@@ -247,6 +250,9 @@
 	enum gpio_id id,
 	uint32_t en)
 {
+	if (id == GPIO_ID_UNKNOWN)
+		return;
+
 	service->busyness[id][en] = true;
 }
 
@@ -255,6 +261,9 @@
 	enum gpio_id id,
 	uint32_t en)
 {
+	if (id == GPIO_ID_UNKNOWN)
+		return;
+
 	service->busyness[id][en] = false;
 }
 
@@ -263,7 +272,7 @@
 	enum gpio_id id,
 	uint32_t en)
 {
-	if (!service->busyness[id]) {
+	if (id != GPIO_ID_UNKNOWN && !service->busyness[id]) {
 		ASSERT_CRITICAL(false);
 		return GPIO_RESULT_OPEN_FAILED;
 	}
@@ -277,7 +286,7 @@
 	enum gpio_id id,
 	uint32_t en)
 {
-	if (!service->busyness[id]) {
+	if (id != GPIO_ID_UNKNOWN && !service->busyness[id]) {
 		ASSERT_CRITICAL(false);
 		return GPIO_RESULT_OPEN_FAILED;
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hdcp/hdcp_msg.c
@@ -130,13 +130,21 @@
 	const uint8_t hdcp_i2c_addr_link_primary = 0x3a; /* 0x74 >> 1*/
 	const uint8_t hdcp_i2c_addr_link_secondary = 0x3b; /* 0x76 >> 1*/
 	struct i2c_command i2c_command;
-	uint8_t offset = hdcp_i2c_offsets[message_info->msg_id];
+	uint8_t offset;
 	struct i2c_payload i2c_payloads[] = {
-		{ true, 0, 1, &offset },
+		{ true, 0, 1, 0 },
 		/* actual hdcp payload, will be filled later, zeroed for now*/
 		{ 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) {
 	case HDCP_LINK_SECONDARY:
 		i2c_payloads[0].address = hdcp_i2c_addr_link_secondary;
@@ -310,6 +318,11 @@
 	struct dc_link *link,
 	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(
 		link,
 		message_info->length,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c
@@ -57,6 +57,7 @@
 #include "panel_cntl.h"
 #include "dc_state_priv.h"
 #include "dpcd_defs.h"
+#include "dsc.h"
 /* include DCE11 register header files */
 #include "dce/dce_11_0_d.h"
 #include "dce/dce_11_0_sh_mask.h"
@@ -957,7 +958,7 @@
 {
 	struct dc_context *ctx = link->ctx;
 	struct bp_transmitter_control cntl = { 0 };
-	uint8_t pwrseq_instance;
+	uint8_t pwrseq_instance = 0;
 	unsigned int pre_T11_delay = OLED_PRE_T11_DELAY;
 	unsigned int post_T7_delay = OLED_POST_T7_DELAY;
 
@@ -1010,7 +1011,8 @@
 	 */
 	/* dc_service_sleep_in_milliseconds(50); */
 		/*edp 1.2*/
-	pwrseq_instance = link->panel_cntl->pwrseq_inst;
+	if (link->panel_cntl)
+		pwrseq_instance = link->panel_cntl->pwrseq_inst;
 
 	if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) {
 		if (!link->dc->config.edp_no_power_sequencing)
@@ -1185,7 +1187,8 @@
 		if (dccg) {
 			dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst);
 			dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst);
-			dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
+			if (dccg && dccg->funcs->set_dtbclk_dto)
+				dccg->funcs->set_dtbclk_dto(dccg, &dto_params);
 		}
 	} else if (dccg && dccg->funcs->disable_symclk_se) {
 		dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst,
@@ -1726,6 +1729,48 @@
 	}
 }
 
+static void clean_up_dsc_blocks(struct dc *dc)
+{
+	struct display_stream_compressor *dsc = NULL;
+	struct timing_generator *tg = NULL;
+	struct stream_encoder *se = NULL;
+	struct dccg *dccg = dc->res_pool->dccg;
+	struct pg_cntl *pg_cntl = dc->res_pool->pg_cntl;
+	int i;
+
+	if (dc->ctx->dce_version != DCN_VERSION_3_5 &&
+		dc->ctx->dce_version != DCN_VERSION_3_51)
+		return;
+
+	for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) {
+		struct dcn_dsc_state s  = {0};
+
+		dsc = dc->res_pool->dscs[i];
+		dsc->funcs->dsc_read_state(dsc, &s);
+		if (s.dsc_fw_en) {
+			/* disable DSC in OPTC */
+			if (i < dc->res_pool->timing_generator_count) {
+				tg = dc->res_pool->timing_generators[i];
+				tg->funcs->set_dsc_config(tg, OPTC_DSC_DISABLED, 0, 0);
+			}
+			/* disable DSC in stream encoder */
+			if (i < dc->res_pool->stream_enc_count) {
+				se = dc->res_pool->stream_enc[i];
+				se->funcs->dp_set_dsc_config(se, OPTC_DSC_DISABLED, 0, 0);
+				se->funcs->dp_set_dsc_pps_info_packet(se, false, NULL, true);
+			}
+			/* disable DSC block */
+			if (dccg->funcs->set_ref_dscclk)
+				dccg->funcs->set_ref_dscclk(dccg, dsc->inst);
+			dsc->funcs->dsc_disable(dsc);
+
+			/* power down DSC */
+			if (pg_cntl != NULL)
+				pg_cntl->funcs->dsc_pg_control(pg_cntl, dsc->inst, false);
+		}
+	}
+}
+
 /*
  * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need:
  *  1. Power down all DC HW blocks
@@ -1810,6 +1855,13 @@
 		clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
 
 		power_down_all_hw_blocks(dc);
+
+		/* DSC could be enabled on eDP during VBIOS post.
+		 * To clean up dsc blocks if eDP is in link but not active.
+		 */
+		if (edp_link_with_sink && (edp_stream_num == 0))
+			clean_up_dsc_blocks(dc);
+
 		disable_vga_and_power_gate_all_controllers(dc);
 		if (edp_link_with_sink && !keep_edp_vdd_on)
 			dc->hwss.edp_power_control(edp_link_with_sink, false);
@@ -1928,13 +1980,20 @@
 	 * as well.
 	 */
 	for (i = 0; i < num_pipes; i++) {
-		pipe_ctx[i]->stream_res.tg->funcs->set_drr(
-			pipe_ctx[i]->stream_res.tg, &params);
+		/* dc_state_destruct() might null the stream resources, so fetch tg
+		 * here first to avoid a race condition. The lifetime of the pointee
+		 * itself (the timing_generator object) is not a problem here.
+		 */
+		struct timing_generator *tg = pipe_ctx[i]->stream_res.tg;
 
-		if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
-			pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
-					pipe_ctx[i]->stream_res.tg,
-					event_triggers, num_frames);
+		if ((tg != NULL) && tg->funcs) {
+			if (tg->funcs->set_drr)
+				tg->funcs->set_drr(tg, &params);
+			if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
+				if (tg->funcs->set_static_screen_control)
+					tg->funcs->set_static_screen_control(
+						tg, event_triggers, num_frames);
+		}
 	}
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c
@@ -1246,6 +1246,7 @@
 		if (hws->funcs.hubp_pg_control)
 			hws->funcs.hubp_pg_control(hws, hubp->inst, false);
 
+		hubp->funcs->hubp_reset(hubp);
 		dpp->funcs->dpp_reset(dpp);
 
 		REG_SET(DC_IP_REQUEST_CNTL, 0,
@@ -1403,6 +1404,7 @@
 		/* Disable on the current state so the new one isn't cleared. */
 		pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
 
+		hubp->funcs->hubp_reset(hubp);
 		dpp->funcs->dpp_reset(dpp);
 
 		pipe_ctx->stream_res.tg = tg;
@@ -1497,7 +1499,7 @@
 		dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
 
 	/* Align bw context with hw config when system resume. */
-	if (dc->clk_mgr->clks.dispclk_khz != 0 && dc->clk_mgr->clks.dppclk_khz != 0) {
+	if (dc->clk_mgr && dc->clk_mgr->clks.dispclk_khz != 0 && dc->clk_mgr->clks.dppclk_khz != 0) {
 		dc->current_state->bw_ctx.bw.dcn.clk.dispclk_khz = dc->clk_mgr->clks.dispclk_khz;
 		dc->current_state->bw_ctx.bw.dcn.clk.dppclk_khz = dc->clk_mgr->clks.dppclk_khz;
 	}
@@ -1617,7 +1619,7 @@
 		REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);
 	}
 
-	if (dc->clk_mgr->funcs->notify_wm_ranges)
+	if (dc->clk_mgr && dc->clk_mgr->funcs->notify_wm_ranges)
 		dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
 }
 
@@ -1840,6 +1842,9 @@
 {
 	struct dpp *dpp = pipe_ctx->plane_res.dpp;
 
+	if (!stream)
+		return false;
+
 	if (dpp == NULL)
 		return false;
 
@@ -1862,8 +1867,8 @@
 	} else
 		dpp->funcs->dpp_program_regamma_pwl(dpp, NULL, OPP_REGAMMA_BYPASS);
 
-	if (stream != NULL && stream->ctx != NULL &&
-			stream->out_transfer_func != NULL) {
+	if (stream->ctx &&
+	    stream->out_transfer_func) {
 		log_tf(stream->ctx,
 				stream->out_transfer_func,
 				dpp->regamma_params.hw_points_num);
@@ -3076,7 +3081,7 @@
 			context,
 			false);
 
-	dc->wm_optimized_required = hubbub->funcs->program_watermarks(hubbub,
+	dc->optimized_required |= hubbub->funcs->program_watermarks(hubbub,
 			&context->bw_ctx.bw.dcn.watermarks,
 			dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
 			true);
@@ -3153,15 +3158,19 @@
 	 * as well.
 	 */
 	for (i = 0; i < num_pipes; i++) {
-		if ((pipe_ctx[i]->stream_res.tg != NULL) && pipe_ctx[i]->stream_res.tg->funcs) {
-			if (pipe_ctx[i]->stream_res.tg->funcs->set_drr)
-				pipe_ctx[i]->stream_res.tg->funcs->set_drr(
-					pipe_ctx[i]->stream_res.tg, &params);
+		/* dc_state_destruct() might null the stream resources, so fetch tg
+		 * here first to avoid a race condition. The lifetime of the pointee
+		 * itself (the timing_generator object) is not a problem here.
+		 */
+		struct timing_generator *tg = pipe_ctx[i]->stream_res.tg;
+
+		if ((tg != NULL) && tg->funcs) {
+			if (tg->funcs->set_drr)
+				tg->funcs->set_drr(tg, &params);
 			if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
-				if (pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control)
-					pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
-						pipe_ctx[i]->stream_res.tg,
-						event_triggers, num_frames);
+				if (tg->funcs->set_static_screen_control)
+					tg->funcs->set_static_screen_control(
+						tg, event_triggers, num_frames);
 		}
 	}
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c
@@ -934,7 +934,8 @@
 	/*
 	 * if above if is not executed then 'params' equal to 0 and set in bypass
 	 */
-	mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+	if (mpc->funcs->set_output_gamma)
+		mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
 
 	return true;
 }
@@ -1392,6 +1393,11 @@
 		return;
 	}
 
+	if (resource_is_pipe_type(new_pipe, OTG_MASTER) &&
+			resource_is_odm_topology_changed(new_pipe, old_pipe))
+		/* Detect odm changes */
+		new_pipe->update_flags.bits.odm = 1;
+
 	/* Exit on unchanged, unused pipe */
 	if (!old_pipe->plane_state && !new_pipe->plane_state)
 		return;
@@ -1445,10 +1451,6 @@
 
 	/* Detect top pipe only changes */
 	if (resource_is_pipe_type(new_pipe, OTG_MASTER)) {
-		/* Detect odm changes */
-		if (resource_is_odm_topology_changed(new_pipe, old_pipe))
-			new_pipe->update_flags.bits.odm = 1;
-
 		/* Detect global sync changes */
 		if (old_pipe->pipe_dlg_param.vready_offset != new_pipe->pipe_dlg_param.vready_offset
 				|| old_pipe->pipe_dlg_param.vstartup_start != new_pipe->pipe_dlg_param.vstartup_start
@@ -1812,17 +1814,26 @@
 		dc->res_pool->hubbub->funcs->program_det_size(
 			dc->res_pool->hubbub, pipe_ctx->plane_res.hubp->inst, pipe_ctx->det_buffer_size_kb);
 
-	if (pipe_ctx->update_flags.raw || pipe_ctx->plane_state->update_flags.raw || pipe_ctx->stream->update_flags.raw)
+	if (pipe_ctx->plane_state && (pipe_ctx->update_flags.raw ||
+	    pipe_ctx->plane_state->update_flags.raw ||
+	    pipe_ctx->stream->update_flags.raw))
 		dcn20_update_dchubp_dpp(dc, pipe_ctx, context);
 
-	if (pipe_ctx->update_flags.bits.enable
-			|| pipe_ctx->plane_state->update_flags.bits.hdr_mult)
+	if (pipe_ctx->update_flags.bits.enable ||
+	    (pipe_ctx->plane_state && pipe_ctx->plane_state->update_flags.bits.hdr_mult))
 		hws->funcs.set_hdr_multiplier(pipe_ctx);
 
-	if (pipe_ctx->update_flags.bits.enable ||
-	    pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
-	    pipe_ctx->plane_state->update_flags.bits.gamma_change ||
-	    pipe_ctx->plane_state->update_flags.bits.lut_3d)
+	if ((pipe_ctx->plane_state && pipe_ctx->plane_state->update_flags.bits.hdr_mult) ||
+	    pipe_ctx->update_flags.bits.enable)
+		hws->funcs.set_hdr_multiplier(pipe_ctx);
+
+	if ((pipe_ctx->plane_state &&
+	     pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change) ||
+	    (pipe_ctx->plane_state &&
+	     pipe_ctx->plane_state->update_flags.bits.gamma_change) ||
+	    (pipe_ctx->plane_state &&
+	     pipe_ctx->plane_state->update_flags.bits.lut_3d) ||
+	     pipe_ctx->update_flags.bits.enable)
 		hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
 
 	/* dcn10_translate_regamma_to_hw_format takes 750us to finish
@@ -1832,7 +1843,8 @@
 	if (pipe_ctx->update_flags.bits.enable ||
 			pipe_ctx->update_flags.bits.plane_changed ||
 			pipe_ctx->stream->update_flags.bits.out_tf ||
-			pipe_ctx->plane_state->update_flags.bits.output_tf_change)
+			(pipe_ctx->plane_state &&
+			 pipe_ctx->plane_state->update_flags.bits.output_tf_change))
 		hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
 
 	/* If the pipe has been enabled or has a different opp, we
@@ -1856,7 +1868,7 @@
 	}
 
 	/* Set ABM pipe after other pipe configurations done */
-	if (pipe_ctx->plane_state->visible) {
+	if ((pipe_ctx->plane_state && pipe_ctx->plane_state->visible)) {
 		if (pipe_ctx->stream_res.abm) {
 			dc->hwss.set_pipe(pipe_ctx);
 			pipe_ctx->stream_res.abm->funcs->set_abm_level(pipe_ctx->stream_res.abm,
@@ -1891,19 +1903,20 @@
 	DC_LOGGER_INIT(dc->ctx->logger);
 	unsigned int prev_hubp_count = 0;
 	unsigned int hubp_count = 0;
+	struct pipe_ctx *pipe;
 
 	if (resource_is_pipe_topology_changed(dc->current_state, context))
 		resource_log_pipe_topology_update(dc, context);
 
 	if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) {
 		for (i = 0; i < dc->res_pool->pipe_count; i++) {
-			struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+			pipe = &context->res_ctx.pipe_ctx[i];
 
-			if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe && pipe_ctx->plane_state) {
-				ASSERT(!pipe_ctx->plane_state->triplebuffer_flips);
+			if (!pipe->top_pipe && !pipe->prev_odm_pipe && pipe->plane_state) {
+				ASSERT(!pipe->plane_state->triplebuffer_flips);
 				/*turn off triple buffer for full update*/
 				dc->hwss.program_triplebuffer(
-						dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips);
+						dc, pipe, pipe->plane_state->triplebuffer_flips);
 			}
 		}
 	}
@@ -1978,12 +1991,22 @@
 			DC_LOG_DC("Reset mpcc for pipe %d\n", dc->current_state->res_ctx.pipe_ctx[i].pipe_idx);
 		}
 
+	/* update ODM for blanked OTG master pipes */
+	for (i = 0; i < dc->res_pool->pipe_count; i++) {
+		pipe = &context->res_ctx.pipe_ctx[i];
+		if (resource_is_pipe_type(pipe, OTG_MASTER) &&
+				!resource_is_pipe_type(pipe, DPP_PIPE) &&
+				pipe->update_flags.bits.odm &&
+				hws->funcs.update_odm)
+			hws->funcs.update_odm(dc, context, pipe);
+	}
+
 	/*
 	 * Program all updated pipes, order matters for mpcc setup. Start with
 	 * top pipe and program all pipes that follow in order
 	 */
 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
-		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+		pipe = &context->res_ctx.pipe_ctx[i];
 
 		if (pipe->plane_state && !pipe->top_pipe) {
 			while (pipe) {
@@ -2022,17 +2045,6 @@
 			context->stream_status[0].plane_count > 1) {
 			pipe->plane_res.hubp->funcs->hubp_wait_pipe_read_start(pipe->plane_res.hubp);
 		}
-
-		/* when dynamic ODM is active, pipes must be reconfigured when all planes are
-		 * disabled, as some transitions will leave software and hardware state
-		 * mismatched.
-		 */
-		if (dc->debug.enable_single_display_2to1_odm_policy &&
-			pipe->stream &&
-			pipe->update_flags.bits.disable &&
-			!pipe->prev_odm_pipe &&
-			hws->funcs.update_odm)
-			hws->funcs.update_odm(dc, context, pipe);
 	}
 }
 
@@ -2097,6 +2109,9 @@
 		}
 	}
 
+	if (!hwseq)
+		return;
+
 	/* P-State support transitions:
 	 * Natural -> FPO: 		P-State disabled in prepare, force disallow anytime is safe
 	 * FPO -> Natural: 		Unforce anytime after FW disable is safe (P-State will assert naturally)
@@ -2104,7 +2119,7 @@
 	 * FPO -> Unsupported:	P-State disabled in prepare, unforce disallow anytime is safe
 	 * FPO <-> SubVP:		Force disallow is maintained on the FPO / SubVP pipes
 	 */
-	if (hwseq && hwseq->funcs.update_force_pstate)
+	if (hwseq->funcs.update_force_pstate)
 		dc->hwseq->funcs.update_force_pstate(dc, context);
 
 	/* Only program the MALL registers after all the main and phantom pipes
@@ -2159,10 +2174,10 @@
 	}
 
 	/* program dchubbub watermarks:
-	 * For assigning wm_optimized_required, use |= operator since we don't want
+	 * For assigning optimized_required, use |= operator since we don't want
 	 * to clear the value if the optimize has not happened yet
 	 */
-	dc->wm_optimized_required |= hubbub->funcs->program_watermarks(hubbub,
+	dc->optimized_required |= hubbub->funcs->program_watermarks(hubbub,
 					&context->bw_ctx.bw.dcn.watermarks,
 					dc->res_pool->ref_clocks.dchub_ref_clock_inKhz / 1000,
 					false);
@@ -2175,10 +2190,10 @@
 	if (hubbub->funcs->program_compbuf_size) {
 		if (context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes) {
 			compbuf_size_kb = context->bw_ctx.dml.ip.min_comp_buffer_size_kbytes;
-			dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.dml.ip.min_comp_buffer_size_kbytes);
+			dc->optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.dml.ip.min_comp_buffer_size_kbytes);
 		} else {
 			compbuf_size_kb = context->bw_ctx.bw.dcn.compbuf_size_kb;
-			dc->wm_optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.bw.dcn.compbuf_size_kb);
+			dc->optimized_required |= (compbuf_size_kb != dc->current_state->bw_ctx.bw.dcn.compbuf_size_kb);
 		}
 
 		hubbub->funcs->program_compbuf_size(hubbub, compbuf_size_kb, false);
@@ -2343,8 +2358,11 @@
 {
 	int counter;
 
+	if (!opp)
+		return false;
+
 	for (counter = 0; counter < 1000; counter++) {
-		if (opp->funcs->dpg_is_blanked(opp))
+		if (!opp->funcs->dpg_is_pending(opp))
 			break;
 
 		udelay(100);
@@ -2355,7 +2373,7 @@
 		return false;
 	}
 
-	return true;
+	return opp->funcs->dpg_is_blanked(opp);
 }
 
 bool dcn20_dmdata_status_done(struct pipe_ctx *pipe_ctx)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c
@@ -95,8 +95,11 @@
 	} else if (hwseq->fb_offset.quad_part <= addr->quad_part &&
 			addr->quad_part <= hwseq->uma_top.quad_part) {
 		is_in_uma = true;
+	} else if (addr->quad_part == 0) {
+		is_in_uma = false;
 	} else {
 		is_in_uma = false;
+		BREAK_TO_DEBUGGER();
 	}
 	return is_in_uma;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c
@@ -142,7 +142,7 @@
 {
 	union dmub_rb_cmd cmd;
 	struct dc_context *dc = abm->ctx;
-	uint32_t ramping_boundary = 0xFFFF;
+	uint8_t ramping_boundary = 0xFF;
 
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.abm_set_pipe.header.type = DMUB_CMD__ABM;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
@@ -251,7 +251,11 @@
 		}
 	}
 
-	mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+	if (mpc->funcs->set_output_gamma)
+		mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+	else
+		DC_LOG_ERROR("%s: set_output_gamma function pointer is NULL.\n", __func__);
+
 	return ret;
 }
 
@@ -478,7 +482,7 @@
 	uint32_t backlight = MAX_BACKLIGHT_LEVEL;
 	uint32_t user_level = MAX_BACKLIGHT_LEVEL;
 
-	if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
+	if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks)
 		dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
 
 	// Initialize the dccg
@@ -639,11 +643,12 @@
 	if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
 		dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
 
-	if (dc->clk_mgr->funcs->notify_wm_ranges)
+	if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->notify_wm_ranges)
 		dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
 
 	//if softmax is enabled then hardmax will be set by a different call
-	if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+	if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->set_hard_max_memclk &&
+	    !dc->clk_mgr->dc_mode_softmax_enabled)
 		dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
 
 	if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
@@ -663,10 +668,20 @@
 	if (pipe_ctx == NULL)
 		return;
 
-	if (dc_is_hdmi_signal(pipe_ctx->stream->signal) && pipe_ctx->stream_res.stream_enc != NULL)
+	if (dc_is_hdmi_signal(pipe_ctx->stream->signal) && pipe_ctx->stream_res.stream_enc != NULL) {
 		pipe_ctx->stream_res.stream_enc->funcs->set_avmute(
 				pipe_ctx->stream_res.stream_enc,
 				enable);
+
+		/* Wait for two frame to make sure AV mute is sent out */
+		if (enable) {
+			pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
+			pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
+			pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
+			pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VBLANK);
+			pipe_ctx->stream_res.tg->funcs->wait_for_state(pipe_ctx->stream_res.tg, CRTC_STATE_VACTIVE);
+		}
+	}
 }
 
 void dcn30_update_info_frame(struct pipe_ctx *pipe_ctx)
@@ -765,6 +780,9 @@
 			stream = dc->current_state->streams[0];
 			plane = (stream ? dc->current_state->stream_status[0].plane_states[0] : NULL);
 
+			if (!stream || !plane)
+				return false;
+
 			if (stream && plane) {
 				cursor_cache_enable = stream->cursor_position.enable &&
 						plane->address.grph.cursor_cache_addr.quad_part;
@@ -883,7 +901,7 @@
 
 					/* Use copied cursor, and it's okay to not switch back */
 					cursor_attr.address.quad_part = cmd.mall.cursor_copy_dst.quad_part;
-					dc_stream_set_cursor_attributes(stream, &cursor_attr);
+					dc_stream_program_cursor_attributes(stream, &cursor_attr);
 				}
 
 				/* Enable MALL */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c
@@ -258,10 +258,10 @@
 	if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
 		dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
 
-	if (dc->clk_mgr->funcs->notify_wm_ranges)
+	if (dc->clk_mgr && dc->clk_mgr->funcs->notify_wm_ranges)
 		dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
 
-	if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+	if (dc->clk_mgr && dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
 		dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
 
 	if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c
@@ -69,29 +69,6 @@
 #define FN(reg_name, field_name) \
 	hws->shifts->field_name, hws->masks->field_name
 
-static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
-		int opp_cnt)
-{
-	bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
-	int flow_ctrl_cnt;
-
-	if (opp_cnt >= 2)
-		hblank_halved = true;
-
-	flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
-			stream->timing.h_border_left -
-			stream->timing.h_border_right;
-
-	if (hblank_halved)
-		flow_ctrl_cnt /= 2;
-
-	/* ODM combine 4:1 case */
-	if (opp_cnt == 4)
-		flow_ctrl_cnt /= 2;
-
-	return flow_ctrl_cnt;
-}
-
 static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 {
 	struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
@@ -183,10 +160,6 @@
 	struct pipe_ctx *odm_pipe;
 	int opp_cnt = 0;
 	int opp_inst[MAX_PIPES] = {0};
-	bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing));
-	struct mpc_dwb_flow_control flow_control;
-	struct mpc *mpc = dc->res_pool->mpc;
-	int i;
 
 	opp_cnt = get_odm_config(pipe_ctx, opp_inst);
 
@@ -199,20 +172,6 @@
 		pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
 				pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
 
-	rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
-	flow_control.flow_ctrl_mode = 0;
-	flow_control.flow_ctrl_cnt0 = 0x80;
-	flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt);
-	if (mpc->funcs->set_out_rate_control) {
-		for (i = 0; i < opp_cnt; ++i) {
-			mpc->funcs->set_out_rate_control(
-					mpc, opp_inst[i],
-					true,
-					rate_control_2x_pclk,
-					&flow_control);
-		}
-	}
-
 	for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
 		odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
 				odm_pipe->stream_res.opp,
@@ -402,7 +361,9 @@
 		if (pipe->top_pipe || pipe->prev_odm_pipe)
 			continue;
 
-		if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) {
+		if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal)) &&
+			!pipe->stream->apply_seamless_boot_optimization &&
+			!pipe->stream->apply_edp_fast_boot_optimization) {
 			pipe->stream_res.tg->funcs->disable_crtc(pipe->stream_res.tg);
 			reset_sync_context_for_pipe(dc, context, i);
 			otg_disabled[i] = true;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
@@ -584,7 +584,9 @@
 		}
 	}
 
-	mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+	if (mpc->funcs->set_output_gamma)
+		mpc->funcs->set_output_gamma(mpc, mpcc_id, params);
+
 	return ret;
 }
 
@@ -755,7 +757,7 @@
 	uint32_t backlight = MAX_BACKLIGHT_LEVEL;
 	uint32_t user_level = MAX_BACKLIGHT_LEVEL;
 
-	if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)
+	if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks)
 		dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);
 
 	// Initialize the dccg
@@ -934,10 +936,11 @@
 	if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
 		dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
 
-	if (dc->clk_mgr->funcs->notify_wm_ranges)
+	if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->notify_wm_ranges)
 		dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
 
-	if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+	if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->set_hard_max_memclk &&
+	    !dc->clk_mgr->dc_mode_softmax_enabled)
 		dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
 
 	if (dc->res_pool->hubbub->funcs->force_pstate_change_control)
@@ -966,29 +969,6 @@
 	}
 }
 
-static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
-		int opp_cnt)
-{
-	bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
-	int flow_ctrl_cnt;
-
-	if (opp_cnt >= 2)
-		hblank_halved = true;
-
-	flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
-			stream->timing.h_border_left -
-			stream->timing.h_border_right;
-
-	if (hblank_halved)
-		flow_ctrl_cnt /= 2;
-
-	/* ODM combine 4:1 case */
-	if (opp_cnt == 4)
-		flow_ctrl_cnt /= 2;
-
-	return flow_ctrl_cnt;
-}
-
 static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 {
 	struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
@@ -1017,6 +997,20 @@
 		struct dsc_config dsc_cfg;
 		struct dsc_optc_config dsc_optc_cfg;
 		enum optc_dsc_mode optc_dsc_mode;
+		struct dcn_dsc_state dsc_state = {0};
+
+		if (!dsc) {
+			DC_LOG_DSC("DSC is NULL for tg instance %d:", pipe_ctx->stream_res.tg->inst);
+			return;
+		}
+
+		if (dsc->funcs->dsc_read_state) {
+			dsc->funcs->dsc_read_state(dsc, &dsc_state);
+			if (!dsc_state.dsc_fw_en) {
+				DC_LOG_DSC("DSC has been disabled for tg instance %d:", pipe_ctx->stream_res.tg->inst);
+				return;
+			}
+		}
 
 		/* Enable DSC hw block */
 		dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
@@ -1103,10 +1097,6 @@
 	struct pipe_ctx *odm_pipe;
 	int opp_cnt = 0;
 	int opp_inst[MAX_PIPES] = {0};
-	bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing));
-	struct mpc_dwb_flow_control flow_control;
-	struct mpc *mpc = dc->res_pool->mpc;
-	int i;
 
 	opp_cnt = get_odm_config(pipe_ctx, opp_inst);
 
@@ -1119,20 +1109,6 @@
 		pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
 				pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
 
-	rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
-	flow_control.flow_ctrl_mode = 0;
-	flow_control.flow_ctrl_cnt0 = 0x80;
-	flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt);
-	if (mpc->funcs->set_out_rate_control) {
-		for (i = 0; i < opp_cnt; ++i) {
-			mpc->funcs->set_out_rate_control(
-					mpc, opp_inst[i],
-					true,
-					rate_control_2x_pclk,
-					&flow_control);
-		}
-	}
-
 	for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
 		odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
 				odm_pipe->stream_res.opp,
@@ -1156,6 +1132,13 @@
 			dsc->funcs->dsc_disconnect(dsc);
 		}
 	}
+
+	if (!resource_is_pipe_type(pipe_ctx, DPP_PIPE))
+		/*
+		 * blank pattern is generated by OPP, reprogram blank pattern
+		 * due to OPP count change
+		 */
+		dc->hwseq->funcs.blank_pixel_data(dc, pipe_ctx, true);
 }
 
 unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsigned int *k1_div, unsigned int *k2_div)
@@ -1778,3 +1761,26 @@
 		context->bw_ctx.bw.dcn.clk.p_state_change_support = p_state_change_support;
 	}
 }
+
+void dcn32_interdependent_update_lock(struct dc *dc,
+		struct dc_state *context, bool lock)
+{
+	unsigned int i;
+	struct pipe_ctx *pipe;
+	struct timing_generator *tg;
+
+	for (i = 0; i < dc->res_pool->pipe_count; i++) {
+		pipe = &context->res_ctx.pipe_ctx[i];
+		tg = pipe->stream_res.tg;
+
+		if (!resource_is_pipe_type(pipe, OTG_MASTER) ||
+				!tg->funcs->is_tg_enabled(tg) ||
+				dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_PHANTOM)
+			continue;
+
+		if (lock)
+			dc->hwss.pipe_control_lock(dc, pipe, true);
+		else
+			dc->hwss.pipe_control_lock(dc, pipe, false);
+	}
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.h
@@ -129,4 +129,6 @@
 void dcn32_prepare_bandwidth(struct dc *dc,
 	struct dc_state *context);
 
+void dcn32_interdependent_update_lock(struct dc *dc,
+		struct dc_state *context, bool lock);
 #endif /* __DC_HWSS_DCN32_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_init.c
@@ -58,7 +58,7 @@
 	.disable_plane = dcn20_disable_plane,
 	.disable_pixel_data = dcn20_disable_pixel_data,
 	.pipe_control_lock = dcn20_pipe_control_lock,
-	.interdependent_update_lock = dcn10_lock_all_pipes,
+	.interdependent_update_lock = dcn32_interdependent_update_lock,
 	.cursor_lock = dcn10_cursor_lock,
 	.prepare_bandwidth = dcn32_prepare_bandwidth,
 	.optimize_bandwidth = dcn20_optimize_bandwidth,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
@@ -235,7 +235,7 @@
 	if (hws->funcs.enable_power_gating_plane)
 		hws->funcs.enable_power_gating_plane(dc->hwseq, true);
 */
-	if (res_pool->hubbub->funcs->dchubbub_init)
+	if (res_pool->hubbub && res_pool->hubbub->funcs->dchubbub_init)
 		res_pool->hubbub->funcs->dchubbub_init(dc->res_pool->hubbub);
 	/* If taking control over from VBIOS, we may want to optimize our first
 	 * mode set, so we need to skip powering down pipes until we know which
@@ -267,7 +267,8 @@
 		}
 
 		hws->funcs.init_pipes(dc, dc->current_state);
-		if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)
+		if (dc->res_pool->hubbub->funcs->allow_self_refresh_control &&
+			!dc->res_pool->hubbub->ctx->dc->debug.disable_stutter)
 			dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,
 					!dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);
 	}
@@ -328,10 +329,10 @@
 	if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)
 		dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);
 
-	if (dc->clk_mgr->funcs->notify_wm_ranges)
+	if (dc->clk_mgr && dc->clk_mgr->funcs->notify_wm_ranges)
 		dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);
 
-	if (dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
+	if (dc->clk_mgr && dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)
 		dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);
 
 
@@ -358,29 +359,6 @@
 	}
 }
 
-static int calc_mpc_flow_ctrl_cnt(const struct dc_stream_state *stream,
-		int opp_cnt)
-{
-	bool hblank_halved = optc2_is_two_pixels_per_containter(&stream->timing);
-	int flow_ctrl_cnt;
-
-	if (opp_cnt >= 2)
-		hblank_halved = true;
-
-	flow_ctrl_cnt = stream->timing.h_total - stream->timing.h_addressable -
-			stream->timing.h_border_left -
-			stream->timing.h_border_right;
-
-	if (hblank_halved)
-		flow_ctrl_cnt /= 2;
-
-	/* ODM combine 4:1 case */
-	if (opp_cnt == 4)
-		flow_ctrl_cnt /= 2;
-
-	return flow_ctrl_cnt;
-}
-
 static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
 {
 	struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
@@ -398,7 +376,20 @@
 		struct dsc_config dsc_cfg;
 		struct dsc_optc_config dsc_optc_cfg;
 		enum optc_dsc_mode optc_dsc_mode;
+		struct dcn_dsc_state dsc_state = {0};
+
+		if (!dsc) {
+			DC_LOG_DSC("DSC is NULL for tg instance %d:", pipe_ctx->stream_res.tg->inst);
+			return;
+		}
 
+		if (dsc->funcs->dsc_read_state) {
+			dsc->funcs->dsc_read_state(dsc, &dsc_state);
+			if (!dsc_state.dsc_fw_en) {
+				DC_LOG_DSC("DSC has been disabled for tg instance %d:", pipe_ctx->stream_res.tg->inst);
+				return;
+			}
+		}
 		/* Enable DSC hw block */
 		dsc_cfg.pic_width = (stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right) / opp_cnt;
 		dsc_cfg.pic_height = stream->timing.v_addressable + stream->timing.v_border_top + stream->timing.v_border_bottom;
@@ -474,10 +465,6 @@
 	struct pipe_ctx *odm_pipe;
 	int opp_cnt = 0;
 	int opp_inst[MAX_PIPES] = {0};
-	bool rate_control_2x_pclk = (pipe_ctx->stream->timing.flags.INTERLACE || optc2_is_two_pixels_per_containter(&pipe_ctx->stream->timing));
-	struct mpc_dwb_flow_control flow_control;
-	struct mpc *mpc = dc->res_pool->mpc;
-	int i;
 
 	opp_cnt = get_odm_config(pipe_ctx, opp_inst);
 
@@ -490,20 +477,6 @@
 		pipe_ctx->stream_res.tg->funcs->set_odm_bypass(
 				pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);
 
-	rate_control_2x_pclk = rate_control_2x_pclk || opp_cnt > 1;
-	flow_control.flow_ctrl_mode = 0;
-	flow_control.flow_ctrl_cnt0 = 0x80;
-	flow_control.flow_ctrl_cnt1 = calc_mpc_flow_ctrl_cnt(pipe_ctx->stream, opp_cnt);
-	if (mpc->funcs->set_out_rate_control) {
-		for (i = 0; i < opp_cnt; ++i) {
-			mpc->funcs->set_out_rate_control(
-					mpc, opp_inst[i],
-					true,
-					rate_control_2x_pclk,
-					&flow_control);
-		}
-	}
-
 	for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
 		odm_pipe->stream_res.opp->funcs->opp_pipe_clock_control(
 				odm_pipe->stream_res.opp,
@@ -679,22 +652,43 @@
 
 bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable)
 {
-	struct dc_link *edp_links[MAX_NUM_EDP];
-	int i, edp_num;
 	if (dc->debug.dmcub_emulation)
 		return true;
 
 	if (enable) {
-		dc_get_edp_links(dc, edp_links, &edp_num);
-		if (edp_num == 0 || edp_num > 1)
-			return false;
+		uint32_t num_active_edp = 0;
+		int i;
 
 		for (i = 0; i < dc->current_state->stream_count; ++i) {
 			struct dc_stream_state *stream = dc->current_state->streams[i];
+			struct dc_link *link = stream->link;
+			bool is_psr = link && !link->panel_config.psr.disable_psr &&
+				      (link->psr_settings.psr_version == DC_PSR_VERSION_1 ||
+				       link->psr_settings.psr_version == DC_PSR_VERSION_SU_1);
+			bool is_replay = link && link->replay_settings.replay_feature_enabled;
+
+			/* Ignore streams that disabled. */
+			if (stream->dpms_off)
+				continue;
 
-			if (!stream->dpms_off && !dc_is_embedded_signal(stream->signal))
+			/* Active external displays block idle optimizations. */
+			if (!dc_is_embedded_signal(stream->signal))
 				return false;
+
+			/* If not PWRSEQ0 can't enter idle optimizations */
+			if (link && link->link_index != 0)
+				return false;
+
+			/* Check for panel power features required for idle optimizations. */
+			if (!is_psr && !is_replay)
+				return false;
+
+			num_active_edp += 1;
 		}
+
+		/* If more than one active eDP then disallow. */
+		if (num_active_edp > 1)
+			return false;
 	}
 
 	// TODO: review other cases when idle optimization is allowed
@@ -807,6 +801,7 @@
 		/* Disable on the current state so the new one isn't cleared. */
 		pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i];
 
+		hubp->funcs->hubp_reset(hubp);
 		dpp->funcs->dpp_reset(dpp);
 
 		pipe_ctx->stream_res.tg = tg;
@@ -946,6 +941,7 @@
 /*to do, need to support both case*/
 	hubp->power_gated = true;
 
+	hubp->funcs->hubp_reset(hubp);
 	dpp->funcs->dpp_reset(dpp);
 
 	pipe_ctx->stream = NULL;
@@ -1016,11 +1012,10 @@
 		if (pipe_ctx->plane_res.hubp)
 			update_state->pg_pipe_res_update[PG_HUBP][pipe_ctx->plane_res.hubp->inst] = false;
 
-		if (pipe_ctx->plane_res.dpp)
+		if (pipe_ctx->plane_res.dpp && pipe_ctx->plane_res.hubp)
 			update_state->pg_pipe_res_update[PG_DPP][pipe_ctx->plane_res.hubp->inst] = false;
 
-		if ((pipe_ctx->plane_res.dpp || pipe_ctx->stream_res.opp) &&
-			pipe_ctx->plane_res.mpcc_inst >= 0)
+		if (pipe_ctx->plane_res.dpp || pipe_ctx->stream_res.opp)
 			update_state->pg_pipe_res_update[PG_MPCC][pipe_ctx->plane_res.mpcc_inst] = false;
 
 		if (pipe_ctx->stream_res.dsc)
@@ -1065,7 +1060,8 @@
 			continue;
 
 		if ((!cur_pipe->plane_state && new_pipe->plane_state) ||
-			(!cur_pipe->stream && new_pipe->stream)) {
+			(!cur_pipe->stream && new_pipe->stream) ||
+			(cur_pipe->stream != new_pipe->stream && new_pipe->stream)) {
 			// New pipe addition
 			for (j = 0; j < PG_HW_PIPE_RESOURCES_NUM_ELEMENT; j++) {
 				if (j == PG_HUBP && new_pipe->plane_res.hubp)
@@ -1353,7 +1349,13 @@
 	params.vertical_total_mid_frame_num = adjust.v_total_mid_frame_num;
 
 	for (i = 0; i < num_pipes; i++) {
-		if ((pipe_ctx[i]->stream_res.tg != NULL) && pipe_ctx[i]->stream_res.tg->funcs) {
+		/* dc_state_destruct() might null the stream resources, so fetch tg
+		 * here first to avoid a race condition. The lifetime of the pointee
+		 * itself (the timing_generator object) is not a problem here.
+		 */
+		struct timing_generator *tg = pipe_ctx[i]->stream_res.tg;
+
+		if ((tg != NULL) && tg->funcs) {
 			struct dc_crtc_timing *timing = &pipe_ctx[i]->stream->timing;
 			struct dc *dc = pipe_ctx[i]->stream->ctx->dc;
 
@@ -1366,14 +1368,84 @@
 					num_frames = 2 * (frame_rate % 60);
 				}
 			}
-			if (pipe_ctx[i]->stream_res.tg->funcs->set_drr)
-				pipe_ctx[i]->stream_res.tg->funcs->set_drr(
-					pipe_ctx[i]->stream_res.tg, &params);
+			if (tg->funcs->set_drr)
+				tg->funcs->set_drr(tg, &params);
 			if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
-				if (pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control)
-					pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
-						pipe_ctx[i]->stream_res.tg,
-						event_triggers, num_frames);
+				if (tg->funcs->set_static_screen_control)
+					tg->funcs->set_static_screen_control(
+						tg, event_triggers, num_frames);
 		}
 	}
 }
+
+static bool should_avoid_empty_tu(struct pipe_ctx *pipe_ctx)
+{
+	/* Calculate average pixel count per TU, return false if under ~2.00 to
+	 * avoid empty TUs. This is only required for DPIA tunneling as empty TUs
+	 * are legal to generate for native DP links. Assume TU size 64 as there
+	 * is currently no scenario where it's reprogrammed from HW default.
+	 * MTPs have no such limitation, so this does not affect MST use cases.
+	 */
+	unsigned int pix_clk_mhz;
+	unsigned int symclk_mhz;
+	unsigned int avg_pix_per_tu_x1000;
+	unsigned int tu_size_bytes = 64;
+	struct dc_crtc_timing *timing = &pipe_ctx->stream->timing;
+	struct dc_link_settings *link_settings = &pipe_ctx->link_config.dp_link_settings;
+	const struct dc *dc = pipe_ctx->stream->link->dc;
+
+	if (pipe_ctx->stream->link->ep_type != DISPLAY_ENDPOINT_USB4_DPIA)
+		return false;
+
+	// Not necessary for MST configurations
+	if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
+		return false;
+
+	pix_clk_mhz = timing->pix_clk_100hz / 10000;
+
+	// If this is true, can't block due to dynamic ODM
+	if (pix_clk_mhz > dc->clk_mgr->bw_params->clk_table.entries[0].dispclk_mhz)
+		return false;
+
+	switch (link_settings->link_rate) {
+	case LINK_RATE_LOW:
+		symclk_mhz = 162;
+		break;
+	case LINK_RATE_HIGH:
+		symclk_mhz = 270;
+		break;
+	case LINK_RATE_HIGH2:
+		symclk_mhz = 540;
+		break;
+	case LINK_RATE_HIGH3:
+		symclk_mhz = 810;
+		break;
+	default:
+		// We shouldn't be tunneling any other rates, something is wrong
+		ASSERT(0);
+		return false;
+	}
+
+	avg_pix_per_tu_x1000 = (1000 * pix_clk_mhz * tu_size_bytes)
+		/ (symclk_mhz * link_settings->lane_count);
+
+	// Add small empirically-decided margin to account for potential jitter
+	return (avg_pix_per_tu_x1000 < 2020);
+}
+
+bool dcn35_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx)
+{
+	struct dc *dc = pipe_ctx->stream->ctx->dc;
+
+	if (!is_h_timing_divisible_by_2(pipe_ctx->stream))
+		return false;
+
+	if (should_avoid_empty_tu(pipe_ctx))
+		return false;
+
+	if (dc_is_dp_signal(pipe_ctx->stream->signal) && !dc->link_srv->dp_is_128b_132b_signal(pipe_ctx) &&
+		dc->debug.enable_dp_dig_pixel_rate_div_policy)
+		return true;
+
+	return false;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h
@@ -90,4 +90,6 @@
 void dcn35_set_drr(struct pipe_ctx **pipe_ctx,
 		int num_pipes, struct dc_crtc_timing_adjust adjust);
 
+bool dcn35_is_dp_dig_pixel_rate_div_policy(struct pipe_ctx *pipe_ctx);
+
 #endif /* __DC_HWSS_DCN35_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_init.c
@@ -158,7 +158,7 @@
 	.setup_hpo_hw_control = dcn35_setup_hpo_hw_control,
 	.calculate_dccg_k1_k2_values = dcn32_calculate_dccg_k1_k2_values,
 	.set_pixels_per_cycle = dcn32_set_pixels_per_cycle,
-	.is_dp_dig_pixel_rate_div_policy = dcn32_is_dp_dig_pixel_rate_div_policy,
+	.is_dp_dig_pixel_rate_div_policy = dcn35_is_dp_dig_pixel_rate_div_policy,
 	.dsc_pg_control = dcn35_dsc_pg_control,
 	.dsc_pg_status = dcn32_dsc_pg_status,
 	.enable_plane = dcn35_enable_plane,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/inc/core_status.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/inc/core_status.h
@@ -60,5 +60,7 @@
 };
 
 char *dc_status_to_str(enum dc_status status);
+char *dc_pixel_encoding_to_str(enum dc_pixel_encoding pixel_encoding);
+char *dc_color_depth_to_str(enum dc_color_depth color_depth);
 
 #endif /* _CORE_STATUS_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/inc/core_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/inc/core_types.h
@@ -202,6 +202,7 @@
 
 	void (*get_panel_config_defaults)(struct dc_panel_config *panel_config);
 	void (*build_pipe_pix_clk_params)(struct pipe_ctx *pipe_ctx);
+	unsigned int (*get_det_buffer_size)(const struct dc_state *context);
 };
 
 struct audio_support{
@@ -612,7 +613,7 @@
 		 * store current value in plane states so we can still recover
 		 * a valid current state during dc update.
 		 */
-		struct dc_plane_state plane_states[MAX_SURFACE_NUM];
+		struct dc_plane_state plane_states[MAX_SURFACES];
 	} scratch;
 };
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/inc/hw/clk_mgr_internal.h
@@ -349,7 +349,7 @@
 	enum dm_pp_clocks_state cur_min_clks_state;
 	bool periodic_retraining_disabled;
 
-	unsigned int cur_phyclk_req_table[MAX_PIPES * 2];
+	unsigned int cur_phyclk_req_table[MAX_LINKS];
 
 	bool smu_present;
 	void *wm_range_table;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/inc/hw/hubp.h
@@ -108,6 +108,8 @@
 	void (*dcc_control)(struct hubp *hubp, bool enable,
 			enum hubp_ind_block_size blk_size);
 
+	void (*hubp_reset)(struct hubp *hubp);
+
 	void (*mem_program_viewport)(
 			struct hubp *hubp,
 			const struct rect *viewport,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/inc/hw/hw_shared.h
@@ -44,6 +44,7 @@
  */
 #define MAX_PIPES 6
 #define MAX_PHANTOM_PIPES (MAX_PIPES / 2)
+#define MAX_LINKS (MAX_PIPES * 2 +2)
 #define MAX_DIG_LINK_ENCODERS 7
 #define MAX_DWB_PIPES	1
 #define MAX_HPO_DP2_ENCODERS	4
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/inc/hw/opp.h
@@ -321,6 +321,9 @@
 	bool (*dpg_is_blanked)(
 			struct output_pixel_processor *opp);
 
+	bool (*dpg_is_pending)(struct output_pixel_processor *opp);
+
+
 	void (*opp_dpg_set_blank_color)(
 			struct output_pixel_processor *opp,
 			const struct tg_color *color);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h
@@ -333,6 +333,7 @@
 
 	void (*init_odm)(struct timing_generator *tg);
 	void (*wait_drr_doublebuffer_pending_clear)(struct timing_generator *tg);
+	void (*wait_odm_doublebuffer_pending_clear)(struct timing_generator *tg);
 };
 
 #endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/inc/link.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/inc/link.h
@@ -285,12 +285,12 @@
 			enum replay_FW_Message_type msg,
 			union dmub_replay_cmd_set *cmd_data);
 	bool (*edp_set_coasting_vtotal)(
-			struct dc_link *link, uint16_t coasting_vtotal);
+			struct dc_link *link, uint32_t coasting_vtotal);
 	bool (*edp_replay_residency)(const struct dc_link *link,
 			unsigned int *residency, const bool is_start,
 			const bool is_alpm);
 	bool (*edp_set_replay_power_opt_and_coasting_vtotal)(struct dc_link *link,
-			const unsigned int *power_opts, uint16_t coasting_vtotal);
+			const unsigned int *power_opts, uint32_t coasting_vtotal);
 
 	bool (*edp_wait_for_t12)(struct dc_link *link);
 	bool (*edp_is_ilr_optimization_required)(struct dc_link *link,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c
@@ -211,8 +211,12 @@
 						   info->ext_id);
 	uint8_t pipe_offset = dal_irq_src - IRQ_TYPE_VBLANK;
 
-	struct timing_generator *tg =
-			dc->current_state->res_ctx.pipe_ctx[pipe_offset].stream_res.tg;
+	struct timing_generator *tg;
+
+	if (pipe_offset >= MAX_PIPES)
+		return false;
+
+	tg = dc->current_state->res_ctx.pipe_ctx[pipe_offset].stream_res.tg;
 
 	if (enable) {
 		if (!tg || !tg->funcs->arm_vert_intr(tg, 2)) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/link/accessories/link_dp_cts.c
@@ -816,8 +816,11 @@
 			break;
 		}
 
+		if (!pipe_ctx->stream)
+			return false;
+
 		if (pipe_ctx->stream_res.tg->funcs->lock_doublebuffer_enable) {
-			if (pipe_ctx->stream && should_use_dmub_lock(pipe_ctx->stream->link)) {
+			if (should_use_dmub_lock(pipe_ctx->stream->link)) {
 				union dmub_hw_lock_flags hw_locks = { 0 };
 				struct dmub_hw_lock_inst_flags inst_flags = { 0 };
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_dio.c
@@ -58,7 +58,10 @@
 	struct link_encoder *link_enc = link_enc_cfg_get_link_enc(pipe_ctx->stream->link);
 	struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc;
 
-	if (stream_enc && stream_enc->funcs->disable_fifo)
+	if (!stream_enc)
+		return;
+
+	if (stream_enc->funcs->disable_fifo)
 		stream_enc->funcs->disable_fifo(stream_enc);
 
 	link_enc->funcs->connect_dig_be_to_fe(
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_dp.c
@@ -28,6 +28,8 @@
 #include "dccg.h"
 #include "clk_mgr.h"
 
+#define DC_LOGGER link->ctx->logger
+
 void set_hpo_dp_throttled_vcp_size(struct pipe_ctx *pipe_ctx,
 		struct fixed31_32 throttled_vcp_size)
 {
@@ -108,6 +110,11 @@
 		enum clock_source_id clock_source,
 		const struct dc_link_settings *link_settings)
 {
+	if (!link_res->hpo_dp_link_enc) {
+		DC_LOG_ERROR("%s: invalid hpo_dp_link_enc\n", __func__);
+		return;
+	}
+
 	if (link->dc->res_pool->dccg->funcs->set_symclk32_le_root_clock_gating)
 		link->dc->res_pool->dccg->funcs->set_symclk32_le_root_clock_gating(
 				link->dc->res_pool->dccg,
@@ -124,6 +131,11 @@
 		const struct link_resource *link_res,
 		enum signal_type signal)
 {
+	if (!link_res->hpo_dp_link_enc) {
+		DC_LOG_ERROR("%s: invalid hpo_dp_link_enc\n", __func__);
+		return;
+	}
+
 		link_res->hpo_dp_link_enc->funcs->link_disable(link_res->hpo_dp_link_enc);
 		link_res->hpo_dp_link_enc->funcs->disable_link_phy(
 				link_res->hpo_dp_link_enc, signal);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_hpo_fixed_vs_pe_retimer_dp.c
@@ -162,7 +162,12 @@
 		link_res->hpo_dp_link_enc->funcs->set_link_test_pattern(
 				link_res->hpo_dp_link_enc, tp_params);
 	}
+
 	link->dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_SET_SOURCE_PATTERN);
+
+	// Give retimer extra time to lock before updating DP_TRAINING_PATTERN_SET to TPS1
+	if (tp_params->dp_phy_pattern == DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE)
+		msleep(30);
 }
 
 static void set_hpo_fixed_vs_pe_retimer_dp_lane_settings(struct dc_link *link,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/link_factory.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/link/link_factory.c
@@ -385,7 +385,7 @@
 	if (link->panel_cntl)
 		link->panel_cntl->funcs->destroy(&link->panel_cntl);
 
-	if (link->link_enc) {
+	if (link->link_enc && !link->is_dig_mapping_flexible) {
 		/* Update link encoder resource tracking variables. These are used for
 		 * the dynamic assignment of link encoders to streams. Virtual links
 		 * are not assigned encoder resources on creation.
@@ -611,14 +611,14 @@
 	link->link_enc =
 		link->dc->res_pool->funcs->link_enc_create(dc_ctx, &enc_init_data);
 
-	DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C);
-	DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE);
-
 	if (!link->link_enc) {
 		DC_ERROR("Failed to create link encoder!\n");
 		goto link_enc_create_fail;
 	}
 
+	DC_LOG_DC("BIOS object table - DP_IS_USB_C: %d", link->link_enc->features.flags.bits.DP_IS_USB_C);
+	DC_LOG_DC("BIOS object table - IS_DP2_CAPABLE: %d", link->link_enc->features.flags.bits.IS_DP2_CAPABLE);
+
 	/* Update link encoder tracking variables. These are used for the dynamic
 	 * assignment of link encoders to streams.
 	 */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
@@ -534,7 +534,7 @@
 		struct dc_link_settings *cur,
 		enum link_training_result training_result)
 {
-	uint8_t cur_idx = 0, next_idx;
+	uint32_t cur_idx = 0, next_idx;
 	bool found = false;
 
 	if (training_result == LINK_TRAINING_ABORT)
@@ -914,21 +914,17 @@
 
 	memset(link_setting, 0, sizeof(*link_setting));
 
-	/* if preferred is specified through AMDDP, use it, if it's enough
-	 * to drive the mode
-	 */
-	if (link->preferred_link_setting.lane_count !=
-			LANE_COUNT_UNKNOWN &&
-			link->preferred_link_setting.link_rate !=
-					LINK_RATE_UNKNOWN) {
+	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
+		 * to drive the mode
+		 */
 		*link_setting = link->preferred_link_setting;
-		return true;
-	}
-
-	/* MST doesn't perform link training for now
-	 * TODO: add MST specific link training routine
-	 */
-	if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
+	} else if (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
+		/* MST doesn't perform link training for now
+		 * TODO: add MST specific link training routine
+		 */
 		decide_mst_link_settings(link, link_setting);
 	} else if (link->connector_signal == SIGNAL_TYPE_EDP) {
 		/* enable edp link optimization for DSC eDP case */
@@ -1590,9 +1586,17 @@
 			return false;
 	}
 
-	if (dp_is_lttpr_present(link))
+	if (dp_is_lttpr_present(link)) {
 		configure_lttpr_mode_transparent(link);
 
+		// Echo TOTAL_LTTPR_CNT back downstream
+		core_link_write_dpcd(
+				link,
+				DP_TOTAL_LTTPR_CNT,
+				&link->dpcd_caps.lttpr_caps.phy_repeater_cnt,
+				sizeof(link->dpcd_caps.lttpr_caps.phy_repeater_cnt));
+	}
+
 	/* Read DP tunneling information. */
 	status = dpcd_get_tunneling_device_data(link);
 
@@ -2215,7 +2219,7 @@
 
 		memset(&link->verified_link_cap, 0,
 				sizeof(struct dc_link_settings));
-		if (!link_detect_connection_type(link, &type) || type == dc_connection_none) {
+		if (link->link_enc && (!link_detect_connection_type(link, &type) || type == dc_connection_none)) {
 			link->verified_link_cap = fail_safe_link_settings;
 			break;
 		} else if (dp_verify_link_cap(link, known_limit_link_setting, &fail_count)) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c
@@ -166,7 +166,7 @@
 	uint8_t idx = 0xFF;
 	int i;
 
-	for (i = 0; i < MAX_PIPES * 2; ++i) {
+	for (i = 0; i < MAX_LINKS; ++i) {
 
 		if (!dc_struct->links[i] ||
 				dc_struct->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA)
@@ -196,7 +196,7 @@
 	struct dc_link *link_dpia_primary, *link_dpia_secondary;
 	int total_bw = 0;
 
-	for (uint8_t i = 0; i < (MAX_PIPES * 2) - 1; ++i) {
+	for (uint8_t i = 0; i < MAX_LINKS - 1; ++i) {
 
 		if (!dc->links[i] || dc->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA)
 			continue;
@@ -270,7 +270,7 @@
 
 	/* Error check whether requested and allocated are equal */
 	req_bw = requested_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity);
-	if (req_bw == link->dpia_bw_alloc_config.allocated_bw) {
+	if (req_bw && (req_bw == link->dpia_bw_alloc_config.allocated_bw)) {
 		DC_LOG_ERROR("%s: Request bw equals to allocated bw for link(%d)\n",
 			__func__, link->link_index);
 	}
@@ -341,6 +341,14 @@
 			ret = true;
 			init_usb4_bw_struct(link);
 			link->dpia_bw_alloc_config.bw_alloc_enabled = true;
+
+			/*
+			 * During DP tunnel creation, CM preallocates BW and reduces estimated BW of other
+			 * DPIA. CM release preallocation only when allocation is complete. Do zero alloc
+			 * to make the CM to release preallocation and update estimated BW correctly for
+			 * all DPIAs per host router
+			 */
+			link_dp_dpia_allocate_usb4_bandwidth_for_stream(link, 0);
 		}
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_irq_handler.c
@@ -454,7 +454,8 @@
 	 * If we got sink count changed it means
 	 * Downstream port status changed,
 	 * then DM should call DC to do the detection.
-	 * NOTE: Do not handle link loss on eDP since it is internal link*/
+	 * NOTE: Do not handle link loss on eDP since it is internal link
+	 */
 	if ((link->connector_signal != SIGNAL_TYPE_EDP) &&
 			dp_parse_link_loss_status(
 					link,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_phy.c
@@ -143,32 +143,25 @@
 
 	link_enc = link_enc_cfg_get_link_enc(link);
 	ASSERT(link_enc);
+	if (link_enc->funcs->fec_set_ready == NULL)
+		return DC_NOT_SUPPORTED;
 
-	if (!dp_should_enable_fec(link))
-		return status;
+	if (ready && dp_should_enable_fec(link)) {
+		fec_config = 1;
 
-	if (link_enc->funcs->fec_set_ready &&
-			link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
-		if (ready) {
-			fec_config = 1;
-			status = core_link_write_dpcd(link,
-					DP_FEC_CONFIGURATION,
-					&fec_config,
-					sizeof(fec_config));
-			if (status == DC_OK) {
-				link_enc->funcs->fec_set_ready(link_enc, true);
-				link->fec_state = dc_link_fec_ready;
-			} else {
-				link_enc->funcs->fec_set_ready(link_enc, false);
-				link->fec_state = dc_link_fec_not_ready;
-				dm_error("dpcd write failed to set fec_ready");
-			}
-		} else if (link->fec_state == dc_link_fec_ready) {
+		status = core_link_write_dpcd(link, DP_FEC_CONFIGURATION,
+				&fec_config, sizeof(fec_config));
+
+		if (status == DC_OK) {
+			link_enc->funcs->fec_set_ready(link_enc, true);
+			link->fec_state = dc_link_fec_ready;
+		}
+	} else {
+		if (link->fec_state == dc_link_fec_ready) {
 			fec_config = 0;
-			status = core_link_write_dpcd(link,
-					DP_FEC_CONFIGURATION,
-					&fec_config,
-					sizeof(fec_config));
+			core_link_write_dpcd(link, DP_FEC_CONFIGURATION,
+				&fec_config, sizeof(fec_config));
+
 			link_enc->funcs->fec_set_ready(link_enc, false);
 			link->fec_state = dc_link_fec_not_ready;
 		}
@@ -183,14 +176,12 @@
 
 	link_enc = link_enc_cfg_get_link_enc(link);
 	ASSERT(link_enc);
-
-	if (!dp_should_enable_fec(link))
+	if (link_enc->funcs->fec_set_enable == NULL)
 		return;
 
-	if (link_enc->funcs->fec_set_enable &&
-			link->dpcd_caps.fec_cap.bits.FEC_CAPABLE) {
-		if (link->fec_state == dc_link_fec_ready && enable) {
-			/* Accord to DP spec, FEC enable sequence can first
+	if (enable && dp_should_enable_fec(link)) {
+		if (link->fec_state == dc_link_fec_ready) {
+			/* According to DP spec, FEC enable sequence can first
 			 * be transmitted anytime after 1000 LL codes have
 			 * been transmitted on the link after link training
 			 * completion. Using 1 lane RBR should have the maximum
@@ -200,7 +191,9 @@
 			udelay(7);
 			link_enc->funcs->fec_set_enable(link_enc, true);
 			link->fec_state = dc_link_fec_enabled;
-		} else if (link->fec_state == dc_link_fec_enabled && !enable) {
+		}
+	} else {
+		if (link->fec_state == dc_link_fec_enabled) {
 			link_enc->funcs->fec_set_enable(link_enc, false);
 			link->fec_state = dc_link_fec_ready;
 		}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c
@@ -914,10 +914,10 @@
 			/* Driver does not need to train the first hop. Skip DPCD read and clear
 			 * 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;
 
-			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 +
 						((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (repeater_id - 1));
 				core_link_read_dpcd(
@@ -1676,8 +1676,7 @@
 		if (status == LINK_TRAINING_ABORT) {
 			enum dc_connection_type type = dc_connection_none;
 
-			link_detect_connection_type(link, &type);
-			if (type == dc_connection_none) {
+			if (link_detect_connection_type(link, &type) && type == dc_connection_none) {
 				DC_LOG_HW_LINK_TRAINING("%s: Aborting training because sink unplugged\n", __func__);
 				break;
 			}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_dpcd.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dpcd.c
@@ -164,7 +164,8 @@
 	if (new_addr_range.start != in_address || new_addr_range.end != end_address) {
 		*out_address = new_addr_range.start;
 		*out_size = ADDRESS_RANGE_SIZE(new_addr_range.start, new_addr_range.end);
-		*out_data = kzalloc(*out_size * sizeof(**out_data), GFP_KERNEL);
+		*out_data = kcalloc(*out_size, sizeof(**out_data), GFP_KERNEL);
+		ASSERT(*out_data);
 	}
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
@@ -892,7 +892,8 @@
 
 	/* Set power optimization flag */
 	if (power_opts && link->replay_settings.replay_power_opt_active != *power_opts) {
-		if (link->replay_settings.replay_feature_enabled && replay->funcs->replay_set_power_opt) {
+		if (replay != NULL && link->replay_settings.replay_feature_enabled &&
+		    replay->funcs->replay_set_power_opt) {
 			replay->funcs->replay_set_power_opt(replay, *power_opts, panel_inst);
 			link->replay_settings.replay_power_opt_active = *power_opts;
 		}
@@ -1033,7 +1034,7 @@
 	return true;
 }
 
-bool edp_set_coasting_vtotal(struct dc_link *link, uint16_t coasting_vtotal)
+bool edp_set_coasting_vtotal(struct dc_link *link, uint32_t coasting_vtotal)
 {
 	struct dc *dc = link->ctx->dc;
 	struct dmub_replay *replay = dc->res_pool->replay;
@@ -1072,7 +1073,7 @@
 }
 
 bool edp_set_replay_power_opt_and_coasting_vtotal(struct dc_link *link,
-	const unsigned int *power_opts, uint16_t coasting_vtotal)
+	const unsigned int *power_opts, uint32_t coasting_vtotal)
 {
 	struct dc  *dc = link->ctx->dc;
 	struct dmub_replay *replay = dc->res_pool->replay;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.h
@@ -59,12 +59,12 @@
 bool edp_send_replay_cmd(struct dc_link *link,
 			enum replay_FW_Message_type msg,
 			union dmub_replay_cmd_set *cmd_data);
-bool edp_set_coasting_vtotal(struct dc_link *link, uint16_t coasting_vtotal);
+bool edp_set_coasting_vtotal(struct dc_link *link, uint32_t coasting_vtotal);
 bool edp_replay_residency(const struct dc_link *link,
 	unsigned int *residency, const bool is_start, const bool is_alpm);
 bool edp_get_replay_state(const struct dc_link *link, uint64_t *state);
 bool edp_set_replay_power_opt_and_coasting_vtotal(struct dc_link *link,
-	const unsigned int *power_opts, uint16_t coasting_vtotal);
+	const unsigned int *power_opts, uint32_t coasting_vtotal);
 bool edp_wait_for_t12(struct dc_link *link);
 bool edp_is_ilr_optimization_required(struct dc_link *link,
        struct dc_crtc_timing *crtc_timing);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h
@@ -557,7 +557,8 @@
 	type OTG_CRC_DATA_STREAM_SPLIT_MODE;\
 	type OTG_CRC_DATA_FORMAT;\
 	type OTG_V_TOTAL_LAST_USED_BY_DRR;\
-	type OTG_DRR_TIMING_DBUF_UPDATE_PENDING;
+	type OTG_DRR_TIMING_DBUF_UPDATE_PENDING;\
+	type OTG_H_TIMING_DIV_MODE_DB_UPDATE_PENDING;
 
 #define TG_REG_FIELD_LIST_DCN3_2(type) \
 	type OTG_H_TIMING_DIV_MODE_MANUAL;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.c
@@ -122,6 +122,13 @@
 	}
 }
 
+void optc32_wait_odm_doublebuffer_pending_clear(struct timing_generator *tg)
+{
+	struct optc *optc1 = DCN10TG_FROM_TG(tg);
+
+	REG_WAIT(OTG_DOUBLE_BUFFER_CONTROL, OTG_H_TIMING_DIV_MODE_DB_UPDATE_PENDING, 0, 2, 50000);
+}
+
 void optc32_set_h_timing_div_manual_mode(struct timing_generator *optc, bool manual_mode)
 {
 	struct optc *optc1 = DCN10TG_FROM_TG(optc);
@@ -260,9 +267,6 @@
 				OTG_V_TOTAL_MAX_SEL, 1,
 				OTG_FORCE_LOCK_ON_EVENT, 0,
 				OTG_SET_V_TOTAL_MIN_MASK, (1 << 1)); /* TRIGA */
-
-		// Setup manual flow control for EOF via TRIG_A
-		optc->funcs->setup_manual_trigger(optc);
 	}
 }
 
@@ -345,6 +349,7 @@
 		.set_odm_bypass = optc32_set_odm_bypass,
 		.set_odm_combine = optc32_set_odm_combine,
 		.get_odm_combine_segments = optc32_get_odm_combine_segments,
+		.wait_odm_doublebuffer_pending_clear = optc32_wait_odm_doublebuffer_pending_clear,
 		.set_h_timing_div_manual_mode = optc32_set_h_timing_div_manual_mode,
 		.get_optc_source = optc2_get_optc_source,
 		.set_out_mux = optc3_set_out_mux,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h
@@ -183,5 +183,6 @@
 void optc32_get_odm_combine_segments(struct timing_generator *tg, int *odm_combine_segments);
 void optc32_set_odm_bypass(struct timing_generator *optc,
 		const struct dc_crtc_timing *dc_crtc_timing);
+void optc32_wait_odm_doublebuffer_pending_clear(struct timing_generator *tg);
 
 #endif /* __DC_OPTC_DCN32_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c
@@ -1069,7 +1069,10 @@
 	struct dm_pp_clock_levels clks = {0};
 	int memory_type_multiplier = MEMORY_TYPE_MULTIPLIER_CZ;
 
-	if (dc->bw_vbios && dc->bw_vbios->memory_type == bw_def_hbm)
+	if (!dc->bw_vbios)
+		return;
+
+	if (dc->bw_vbios->memory_type == bw_def_hbm)
 		memory_type_multiplier = MEMORY_TYPE_HBM;
 
 	/*do system clock  TODO PPLIB: after PPLIB implement,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c
@@ -1539,6 +1539,7 @@
 	if (dce83_construct(num_virtual_links, dc, pool))
 		return &pool->base;
 
+	kfree(pool);
 	BREAK_TO_DEBUGGER();
 	return NULL;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c
@@ -2031,6 +2031,7 @@
 {
 	bool out = false;
 	int split[MAX_PIPES] = { 0 };
+	bool merge[MAX_PIPES] = { false };
 	int pipe_cnt, i, pipe_idx, vlevel;
 
 	ASSERT(pipes);
@@ -2055,7 +2056,7 @@
 	if (vlevel > context->bw_ctx.dml.soc.num_states)
 		goto validate_fail;
 
-	vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, NULL);
+	vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
 
 	/*initialize pipe_just_split_from to invalid idx*/
 	for (i = 0; i < MAX_PIPES; i++)
@@ -2191,10 +2192,11 @@
 		const struct dc_dcc_surface_param *input,
 		struct dc_surface_dcc_cap *output)
 {
-	return dc->res_pool->hubbub->funcs->get_dcc_compression_cap(
-			dc->res_pool->hubbub,
-			input,
-			output);
+	if (dc->res_pool->hubbub->funcs->get_dcc_compression_cap)
+		return dc->res_pool->hubbub->funcs->get_dcc_compression_cap(
+			dc->res_pool->hubbub, input, output);
+
+	return false;
 }
 
 static void dcn20_destroy_resource_pool(struct resource_pool **pool)
@@ -2451,6 +2453,7 @@
 	dc->caps.post_blend_color_processing = true;
 	dc->caps.force_dp_tps4_for_cp2520 = true;
 	dc->caps.extended_aux_timeout_support = true;
+	dc->caps.dmcub_support = true;
 
 	/* Color pipeline capabilities */
 	dc->caps.color.dpp.dcn_arch = 1;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c
@@ -1003,8 +1003,10 @@
 	struct pipe_ctx *head_pipe = resource_get_otg_master_for_stream(res_ctx, opp_head_pipe->stream);
 	struct pipe_ctx *idle_pipe = resource_find_free_secondary_pipe_legacy(res_ctx, pool, head_pipe);
 
-	if (!head_pipe)
+	if (!head_pipe) {
 		ASSERT(0);
+		return NULL;
+	}
 
 	if (!idle_pipe)
 		return NULL;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c
@@ -800,6 +800,7 @@
 {
 	bool out = false;
 	int split[MAX_PIPES] = { 0 };
+	bool merge[MAX_PIPES] = { false };
 	int pipe_cnt, i, pipe_idx, vlevel;
 
 	ASSERT(pipes);
@@ -842,7 +843,7 @@
 			goto validate_fail;
 	}
 
-	vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, NULL);
+	vlevel = dcn20_validate_apply_pipe_split_flags(dc, context, vlevel, split, merge);
 
 	for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
 		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
@@ -1323,7 +1324,7 @@
 		kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL);
 	int link_regs_id;
 
-	if (!enc21)
+	if (!enc21 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
 		return NULL;
 
 	link_regs_id =
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
@@ -2050,6 +2050,9 @@
 
 	BW_VAL_TRACE_COUNT();
 
+	if (!pipes)
+		goto validate_fail;
+
 	DC_FP_START();
 	out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, true);
 	DC_FP_END();
@@ -2169,6 +2172,17 @@
 					optimal_uclk_for_dcfclk_sta_targets[i] =
 							bw_params->clk_table.entries[j].memclk_mhz * 16;
 					break;
+				} else {
+					/* condition where (dcfclk_sta_targets[i] >= optimal_dcfclk_for_uclk[j]):
+					 * If it just so happens that the memory bandwidth is low enough such that
+					 * all the optimal DCFCLK for each UCLK is lower than the smallest DCFCLK STA
+					 * target, we need to populate the optimal UCLK for each DCFCLK STA target to
+					 * be the max UCLK.
+					 */
+					if (j == num_uclk_states - 1) {
+						optimal_uclk_for_dcfclk_sta_targets[i] =
+								bw_params->clk_table.entries[j].memclk_mhz * 16;
+					}
 				}
 			}
 		}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c
@@ -671,9 +671,9 @@
 
 	/* 6:1 downscaling ratio: 1000/6 = 166.666 */
 	.max_downscale_factor = {
-			.argb8888 = 167,
-			.nv12 = 167,
-			.fp16 = 167 
+			.argb8888 = 358,
+			.nv12 = 358,
+			.fp16 = 358
 	},
 	64,
 	64
@@ -694,7 +694,7 @@
 	.disable_dcc = DCC_ENABLE,
 	.vsr_support = true,
 	.performance_trace = false,
-	.max_downscale_src_width = 7680,/*upto 8K*/
+	.max_downscale_src_width = 4096,/*upto true 4k*/
 	.scl_reset_length10 = true,
 	.sanity_checks = false,
 	.underflow_assert_delay_us = 0xFFFFFFFF,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
@@ -892,7 +892,7 @@
 	.disable_z10 = true,
 	.enable_legacy_fast_update = true,
 	.enable_z9_disable_interface = true, /* Allow support for the PMFW interface for disable Z9*/
-	.dml_hostvm_override = DML_HOSTVM_OVERRIDE_FALSE,
+	.dml_hostvm_override = DML_HOSTVM_NO_OVERRIDE,
 	.using_dml2 = false,
 };
 
@@ -1311,6 +1311,8 @@
 
 	/* allocate HPO link encoder */
 	hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
+	if (!hpo_dp_enc31)
+		return NULL; /* out of memory */
 
 	hpo_dp_link_encoder31_construct(hpo_dp_enc31, ctx, inst,
 					&hpo_dp_link_enc_regs[inst],
@@ -1720,6 +1722,12 @@
 	return pipe_cnt;
 }
 
+unsigned int dcn31_get_det_buffer_size(
+	const struct dc_state *context)
+{
+	return context->bw_ctx.dml.ip.det_buffer_size_kbytes;
+}
+
 void dcn31_calculate_wm_and_dlg(
 		struct dc *dc, struct dc_state *context,
 		display_e2e_pipe_params_st *pipes,
@@ -1767,6 +1775,9 @@
 
 	BW_VAL_TRACE_COUNT();
 
+	if (!pipes)
+		goto validate_fail;
+
 	DC_FP_START();
 	out = dcn30_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate, true);
 	DC_FP_END();
@@ -1839,6 +1850,7 @@
 	.update_bw_bounding_box = dcn31_update_bw_bounding_box,
 	.patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
 	.get_panel_config_defaults = dcn31_get_panel_config_defaults,
+	.get_det_buffer_size = dcn31_get_det_buffer_size,
 };
 
 static struct clock_source *dcn30_clock_source_create(
@@ -1860,6 +1872,7 @@
 		return &clk_src->base;
 	}
 
+	kfree(clk_src);
 	BREAK_TO_DEBUGGER();
 	return NULL;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.h
@@ -63,6 +63,9 @@
 		const struct dc_init_data *init_data,
 		struct dc *dc);
 
+unsigned int dcn31_get_det_buffer_size(
+	const struct dc_state *context);
+
 /*temp: B0 specific before switch to dcn313 headers*/
 #ifndef regPHYPLLF_PIXCLK_RESYNC_CNTL
 #define regPHYPLLF_PIXCLK_RESYNC_CNTL 0x007e
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
@@ -1384,6 +1384,8 @@
 
 	/* allocate HPO link encoder */
 	hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
+	if (!hpo_dp_enc31)
+		return NULL; /* out of memory */
 
 	hpo_dp_link_encoder31_construct(hpo_dp_enc31, ctx, inst,
 					&hpo_dp_link_enc_regs[inst],
@@ -1675,8 +1677,8 @@
 		return &clk_src->base;
 	}
 
-	BREAK_TO_DEBUGGER();
 	kfree(clk_src);
+	BREAK_TO_DEBUGGER();
 	return NULL;
 }
 
@@ -1744,6 +1746,9 @@
 
 	BW_VAL_TRACE_COUNT();
 
+	if (!pipes)
+		goto validate_fail;
+
 	if (filter_modes_for_single_channel_workaround(dc, context))
 		goto validate_fail;
 
@@ -1812,6 +1817,7 @@
 	.patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
 	.get_panel_config_defaults = dcn314_get_panel_config_defaults,
 	.get_preferred_eng_id_dpia = dcn314_get_preferred_eng_id_dpia,
+	.get_det_buffer_size = dcn31_get_det_buffer_size,
 };
 
 static struct clock_source *dcn30_clock_source_create(
@@ -1833,8 +1839,8 @@
 		return &clk_src->base;
 	}
 
-	BREAK_TO_DEBUGGER();
 	kfree(clk_src);
+	BREAK_TO_DEBUGGER();
 	return NULL;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
@@ -1309,6 +1309,8 @@
 
 	/* allocate HPO link encoder */
 	hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
+	if (!hpo_dp_enc31)
+		return NULL; /* out of memory */
 
 	hpo_dp_link_encoder31_construct(hpo_dp_enc31, ctx, inst,
 					&hpo_dp_link_enc_regs[inst],
@@ -1754,7 +1756,7 @@
 				bool split_required = pipe->stream->timing.pix_clk_100hz >= dcn_get_max_non_odm_pix_rate_100hz(&dc->dml.soc)
 						|| (pipe->plane_state && pipe->plane_state->src_rect.width > 5120);
 
-				if (remaining_det_segs > MIN_RESERVED_DET_SEGS)
+				if (remaining_det_segs > MIN_RESERVED_DET_SEGS && crb_pipes != 0)
 					pipes[pipe_cnt].pipe.src.det_size_override += (remaining_det_segs - MIN_RESERVED_DET_SEGS) / crb_pipes +
 							(crb_idx < (remaining_det_segs - MIN_RESERVED_DET_SEGS) % crb_pipes ? 1 : 0);
 				if (pipes[pipe_cnt].pipe.src.det_size_override > 2 * DCN3_15_MAX_DET_SEGS) {
@@ -1834,6 +1836,7 @@
 	.update_bw_bounding_box = dcn315_update_bw_bounding_box,
 	.patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
 	.get_panel_config_defaults = dcn315_get_panel_config_defaults,
+	.get_det_buffer_size = dcn31_get_det_buffer_size,
 };
 
 static bool dcn315_resource_construct(
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
@@ -1306,6 +1306,8 @@
 
 	/* allocate HPO link encoder */
 	hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
+	if (!hpo_dp_enc31)
+		return NULL; /* out of memory */
 
 	hpo_dp_link_encoder31_construct(hpo_dp_enc31, ctx, inst,
 					&hpo_dp_link_enc_regs[inst],
@@ -1719,6 +1721,7 @@
 	.update_bw_bounding_box = dcn316_update_bw_bounding_box,
 	.patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
 	.get_panel_config_defaults = dcn316_get_panel_config_defaults,
+	.get_det_buffer_size = dcn31_get_det_buffer_size,
 };
 
 static bool dcn316_resource_construct(
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
@@ -1304,6 +1304,8 @@
 
 	/* allocate HPO link encoder */
 	hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
+	if (!hpo_dp_enc31)
+		return NULL; /* out of memory */
 
 #undef REG_STRUCT
 #define REG_STRUCT hpo_dp_link_enc_regs
@@ -1648,6 +1650,9 @@
 		else
 			phantom_plane = dc_state_create_phantom_plane(dc, context, curr_pipe->plane_state);
 
+		if (!phantom_plane)
+			continue;
+
 		memcpy(&phantom_plane->address, &curr_pipe->plane_state->address, sizeof(phantom_plane->address));
 		memcpy(&phantom_plane->scaling_quality, &curr_pipe->plane_state->scaling_quality,
 				sizeof(phantom_plane->scaling_quality));
@@ -1712,6 +1717,9 @@
 	// be a valid candidate for SubVP (i.e. has a plane, stream, doesn't
 	// already have phantom pipe assigned, etc.) by previous checks.
 	phantom_stream = dcn32_enable_phantom_stream(dc, context, pipes, pipe_cnt, index);
+	if (!phantom_stream)
+		return;
+
 	dcn32_enable_phantom_plane(dc, context, phantom_stream, index);
 
 	for (i = 0; i < dc->res_pool->pipe_count; i++) {
@@ -1751,6 +1759,9 @@
 
 	BW_VAL_TRACE_COUNT();
 
+	if (!pipes)
+		goto validate_fail;
+
 	DC_FP_START();
 	out = dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, fast_validate);
 	DC_FP_END();
@@ -1771,6 +1782,7 @@
 	dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel);
 
 	dcn32_override_min_req_memclk(dc, context);
+	dcn32_override_min_req_dcfclk(dc, context);
 
 	BW_VAL_TRACE_END_WATERMARKS();
 
@@ -1930,6 +1942,8 @@
 {
 	DC_FP_START();
 	dcn32_update_bw_bounding_box_fpu(dc, bw_params);
+	if (dc->debug.using_dml2 && dc->current_state && dc->current_state->bw_ctx.dml2)
+		dml2_reinit(dc, &dc->dml2_options, &dc->current_state->bw_ctx.dml2);
 	DC_FP_END();
 }
 
@@ -2589,8 +2603,10 @@
 	struct resource_context *old_ctx = &stream->ctx->dc->current_state->res_ctx;
 	int head_index;
 
-	if (!head_pipe)
+	if (!head_pipe) {
 		ASSERT(0);
+		return NULL;
+	}
 
 	/*
 	 * Modified from dcn20_acquire_idle_pipe_for_layer
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
@@ -42,6 +42,7 @@
 #define SUBVP_ACTIVE_MARGIN_LIST_LEN 2
 #define DCN3_2_MAX_SUBVP_PIXEL_RATE_MHZ 1800
 #define DCN3_2_VMIN_DISPCLK_HZ 717000000
+#define MIN_SUBVP_DCFCLK_KHZ 400000
 
 #define TO_DCN32_RES_POOL(pool)\
 	container_of(pool, struct dcn32_resource_pool, base)
@@ -181,6 +182,8 @@
 
 void dcn32_update_dml_pipes_odm_policy_based_on_context(struct dc *dc, struct dc_state *context, display_e2e_pipe_params_st *pipes);
 
+void dcn32_override_min_req_dcfclk(struct dc *dc, struct dc_state *context);
+
 /* definitions for run time init of reg offsets */
 
 /* CLK SRC */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
@@ -1288,6 +1288,8 @@
 
 	/* allocate HPO link encoder */
 	hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
+	if (!hpo_dp_enc31)
+		return NULL; /* out of memory */
 
 #undef REG_STRUCT
 #define REG_STRUCT hpo_dp_link_enc_regs
@@ -1581,6 +1583,8 @@
 {
 	DC_FP_START();
 	dcn321_update_bw_bounding_box_fpu(dc, bw_params);
+	if (dc->debug.using_dml2 && dc->current_state && dc->current_state->bw_ctx.dml2)
+		dml2_reinit(dc, &dc->dml2_options, &dc->current_state->bw_ctx.dml2);
 	DC_FP_END();
 }
 
@@ -1759,6 +1763,9 @@
 	dc->caps.color.mpc.ogam_rom_caps.hlg = 0;
 	dc->caps.color.mpc.ocsc = 1;
 
+	/* Use pipe context based otg sync logic */
+	dc->config.use_pipe_ctx_sync_logic = true;
+
 	dc->config.dc_mode_clk_limit_support = true;
 	/* read VBIOS LTTPR caps */
 	{
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
@@ -701,7 +701,7 @@
 
 	// 6:1 downscaling ratio: 1000/6 = 166.666
 	.max_downscale_factor = {
-			.argb8888 = 167,
+			.argb8888 = 250,
 			.nv12 = 167,
 			.fp16 = 167
 	},
@@ -782,7 +782,9 @@
 	.psp_disabled_wa = true,
 	.ips2_eval_delay_us = 2000,
 	.ips2_entry_delay_us = 800,
+	.disable_dmub_reallow_idle = true,
 	.static_screen_wait_frames = 2,
+	.disable_timeout = true,
 };
 
 static const struct dc_panel_config panel_config_defaults = {
@@ -1366,6 +1368,8 @@
 
 	/* allocate HPO link encoder */
 	hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
+	if (!hpo_dp_enc31)
+		return NULL; /* out of memory */
 
 #undef REG_STRUCT
 #define REG_STRUCT hpo_dp_link_enc_regs
@@ -1712,6 +1716,7 @@
 		return &clk_src->base;
 	}
 
+	kfree(clk_src);
 	BREAK_TO_DEBUGGER();
 	return NULL;
 }
@@ -1770,6 +1775,7 @@
 	.patch_unknown_plane_state = dcn20_patch_unknown_plane_state,
 	.get_panel_config_defaults = dcn35_get_panel_config_defaults,
 	.get_preferred_eng_id_dpia = dcn35_get_preferred_eng_id_dpia,
+	.get_det_buffer_size = dcn31_get_det_buffer_size,
 };
 
 static bool dcn35_resource_construct(
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h
@@ -3133,6 +3133,14 @@
 	 * Currently the support is only for 0 or 1
 	 */
 	uint8_t panel_inst;
+	/**
+	 * 16-bit value dicated by driver that indicates the coasting vtotal high byte part.
+	 */
+	uint16_t coasting_vtotal_high;
+	/**
+	 * Explicit padding to 4 byte boundary.
+	 */
+	uint8_t pad[2];
 };
 
 /**
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/dmub/src/dmub_dcn35.c
@@ -448,7 +448,7 @@
 void dmub_dcn35_get_diagnostic_data(struct dmub_srv *dmub, struct dmub_diagnostic_data *diag_data)
 {
 	uint32_t is_dmub_enabled, is_soft_reset, is_sec_reset;
-	uint32_t is_traceport_enabled, is_cw0_enabled, is_cw6_enabled;
+	uint32_t is_traceport_enabled, is_cw6_enabled;
 
 	if (!dmub || !diag_data)
 		return;
@@ -499,9 +499,6 @@
 	REG_GET(DMCUB_CNTL, DMCUB_TRACEPORT_EN, &is_traceport_enabled);
 	diag_data->is_traceport_en  = is_traceport_enabled;
 
-	REG_GET(DMCUB_REGION3_CW0_TOP_ADDRESS, DMCUB_REGION3_CW0_ENABLE, &is_cw0_enabled);
-	diag_data->is_cw0_enabled = is_cw0_enabled;
-
 	REG_GET(DMCUB_REGION3_CW6_TOP_ADDRESS, DMCUB_REGION3_CW6_ENABLE, &is_cw6_enabled);
 	diag_data->is_cw6_enabled = is_cw6_enabled;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/include/dpcd_defs.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/include/dpcd_defs.h
@@ -177,4 +177,9 @@
 #define DP_SINK_PR_PIXEL_DEVIATION_PER_LINE     0x379
 #define DP_SINK_PR_MAX_NUMBER_OF_DEVIATION_LINE 0x37A
 
+/* Remove once drm_dp_helper.h is updated upstream */
+#ifndef DP_TOTAL_LTTPR_CNT
+#define DP_TOTAL_LTTPR_CNT                                  0xF000A /* 2.1 */
+#endif
+
 #endif /* __DAL_DPCD_DEFS_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -134,7 +134,7 @@
 
 	v_total = div64_u64(div64_u64(((unsigned long long)(
 			frame_duration_in_ns) * (stream->timing.pix_clk_100hz / 10)),
-			stream->timing.h_total), 1000000);
+			stream->timing.h_total) + 500000, 1000000);
 
 	/* v_total cannot be less than nominal */
 	if (v_total < stream->timing.v_total) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
@@ -432,18 +432,18 @@
 		goto out;
 	}
 
-	if (status == MOD_HDCP_STATUS_SUCCESS)
-		mod_hdcp_execute_and_set(mod_hdcp_read_bstatus,
-				&input->bstatus_read, &status,
-				hdcp, "bstatus_read");
-	if (status == MOD_HDCP_STATUS_SUCCESS)
-		mod_hdcp_execute_and_set(check_link_integrity_dp,
-				&input->link_integrity_check, &status,
-				hdcp, "link_integrity_check");
-	if (status == MOD_HDCP_STATUS_SUCCESS)
-		mod_hdcp_execute_and_set(check_no_reauthentication_request_dp,
-				&input->reauth_request_check, &status,
-				hdcp, "reauth_request_check");
+	mod_hdcp_execute_and_set(mod_hdcp_read_bstatus,
+			&input->bstatus_read, &status,
+			hdcp, "bstatus_read");
+
+	mod_hdcp_execute_and_set(check_link_integrity_dp,
+			&input->link_integrity_check, &status,
+			hdcp, "link_integrity_check");
+
+	mod_hdcp_execute_and_set(check_no_reauthentication_request_dp,
+			&input->reauth_request_check, &status,
+			hdcp, "reauth_request_check");
+
 out:
 	return status;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c
@@ -156,7 +156,16 @@
 	uint32_t cur_size = 0;
 	uint32_t data_offset = 0;
 
+	if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID ||
+		msg_id >= MOD_HDCP_MESSAGE_ID_MAX)
+		return MOD_HDCP_STATUS_DDC_FAILURE;
+
 	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) {
 			cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);
 			success = hdcp->config.ddc.funcs.read_dpcd(hdcp->config.ddc.handle,
@@ -171,6 +180,11 @@
 			data_offset += cur_size;
 		}
 	} 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(
 				hdcp->config.ddc.handle,
 				HDCP_I2C_ADDR,
@@ -215,7 +229,16 @@
 	uint32_t cur_size = 0;
 	uint32_t data_offset = 0;
 
+	if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID ||
+		msg_id >= MOD_HDCP_MESSAGE_ID_MAX)
+		return MOD_HDCP_STATUS_DDC_FAILURE;
+
 	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) {
 			cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);
 			success = hdcp->config.ddc.funcs.write_dpcd(
@@ -231,6 +254,11 @@
 			data_offset += cur_size;
 		}
 	} 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];
 		memmove(&hdcp->buf[1], buf, buf_len);
 		success = hdcp->config.ddc.funcs.write_i2c(
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c
@@ -513,6 +513,9 @@
 	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
 	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
 
+	if (!display)
+		return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;
+
 	hdcp_cmd->in_msg.hdcp2_create_session_v2.display_handle = display->index;
 
 	if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_0)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/modules/inc/mod_stats.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/modules/inc/mod_stats.h
@@ -57,10 +57,10 @@
 		unsigned int length);
 
 void mod_stats_update_flip(struct mod_stats *mod_stats,
-		unsigned long timestamp_in_ns);
+		unsigned long long timestamp_in_ns);
 
 void mod_stats_update_vupdate(struct mod_stats *mod_stats,
-		unsigned long timestamp_in_ns);
+		unsigned long long timestamp_in_ns);
 
 void mod_stats_update_freesync(struct mod_stats *mod_stats,
 		unsigned int v_total_min,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c
@@ -147,15 +147,12 @@
 	}
 
 	/* VSC packet set to 4 for PSR-SU, or 2 for PSR1 */
-	if (stream->link->psr_settings.psr_feature_enabled) {
-		if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1)
-			vsc_packet_revision = vsc_packet_rev4;
-		else if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_1)
-			vsc_packet_revision = vsc_packet_rev2;
-	}
-
-	if (stream->link->replay_settings.config.replay_supported)
+	if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1)
+		vsc_packet_revision = vsc_packet_rev4;
+	else if (stream->link->replay_settings.config.replay_supported)
 		vsc_packet_revision = vsc_packet_rev4;
+	else if (stream->link->psr_settings.psr_version == DC_PSR_VERSION_1)
+		vsc_packet_revision = vsc_packet_rev2;
 
 	/* Update to revision 5 for extended colorimetry support */
 	if (stream->use_vsc_sdp_for_colorimetry)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/modules/power/power_helpers.c
@@ -841,6 +841,8 @@
 				isPSRSUSupported = false;
 			else if (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x03)
 				isPSRSUSupported = false;
+			else if (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x01)
+				isPSRSUSupported = false;
 			else if (dpcd_caps->psr_info.force_psrsu_cap == 0x1)
 				isPSRSUSupported = true;
 		}
@@ -975,7 +977,7 @@
 
 void set_replay_coasting_vtotal(struct dc_link *link,
 	enum replay_coasting_vtotal_type type,
-	uint16_t vtotal)
+	uint32_t vtotal)
 {
 	link->replay_settings.coasting_vtotal_table[type] = vtotal;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/display/modules/power/power_helpers.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/display/modules/power/power_helpers.h
@@ -56,7 +56,7 @@
 void init_replay_config(struct dc_link *link, struct replay_config *pr_config);
 void set_replay_coasting_vtotal(struct dc_link *link,
 	enum replay_coasting_vtotal_type type,
-	uint16_t vtotal);
+	uint32_t vtotal);
 void set_replay_ips_full_screen_video_src_vtotal(struct dc_link *link, uint16_t vtotal);
 void calculate_replay_link_off_frame_count(struct dc_link *link,
 	uint16_t vtotal, uint16_t htotal);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_offset.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_offset.h
@@ -7571,6 +7571,8 @@
 // base address: 0x10100000
 #define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0                                                              0xd000
 #define regRCC_STRAP0_RCC_DEV0_EPF0_STRAP0_BASE_IDX                                                     5
+#define regRCC_DEV0_EPF5_STRAP4                                                                         0xd284
+#define regRCC_DEV0_EPF5_STRAP4_BASE_IDX                                                                5
 
 
 // addressBlock: nbio_nbif0_bif_rst_bif_rst_regblk
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_sh_mask.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/include/asic_reg/nbio/nbio_7_11_0_sh_mask.h
@@ -50665,6 +50665,19 @@
 #define RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_D1_SUPPORT_DEV0_F0_MASK                                        0x40000000L
 #define RCC_STRAP0_RCC_DEV0_EPF0_STRAP0__STRAP_D2_SUPPORT_DEV0_F0_MASK                                        0x80000000L
 
+//RCC_DEV0_EPF5_STRAP4
+#define RCC_DEV0_EPF5_STRAP4__STRAP_ATOMIC_64BIT_EN_DEV0_F5__SHIFT                                            0x14
+#define RCC_DEV0_EPF5_STRAP4__STRAP_ATOMIC_EN_DEV0_F5__SHIFT                                                  0x15
+#define RCC_DEV0_EPF5_STRAP4__STRAP_FLR_EN_DEV0_F5__SHIFT                                                     0x16
+#define RCC_DEV0_EPF5_STRAP4__STRAP_PME_SUPPORT_DEV0_F5__SHIFT                                                0x17
+#define RCC_DEV0_EPF5_STRAP4__STRAP_INTERRUPT_PIN_DEV0_F5__SHIFT                                              0x1c
+#define RCC_DEV0_EPF5_STRAP4__STRAP_AUXPWR_SUPPORT_DEV0_F5__SHIFT                                             0x1f
+#define RCC_DEV0_EPF5_STRAP4__STRAP_ATOMIC_64BIT_EN_DEV0_F5_MASK                                              0x00100000L
+#define RCC_DEV0_EPF5_STRAP4__STRAP_ATOMIC_EN_DEV0_F5_MASK                                                    0x00200000L
+#define RCC_DEV0_EPF5_STRAP4__STRAP_FLR_EN_DEV0_F5_MASK                                                       0x00400000L
+#define RCC_DEV0_EPF5_STRAP4__STRAP_PME_SUPPORT_DEV0_F5_MASK                                                  0x0F800000L
+#define RCC_DEV0_EPF5_STRAP4__STRAP_INTERRUPT_PIN_DEV0_F5_MASK                                                0x70000000L
+#define RCC_DEV0_EPF5_STRAP4__STRAP_AUXPWR_SUPPORT_DEV0_F5_MASK                                               0x80000000L
 
 // addressBlock: nbio_nbif0_bif_rst_bif_rst_regblk
 //HARD_RST_CTRL
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/include/atomfirmware.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/include/atomfirmware.h
@@ -702,7 +702,7 @@
 {
   struct  atom_common_table_header  table_header;
   /*the real number of this included in the structure is calcualted by using the (whole structure size - the header size)/size of atom_gpio_pin_lut  */
-  struct  atom_gpio_pin_assignment  gpio_pin[8];
+  struct  atom_gpio_pin_assignment  gpio_pin[];
 };
 
 
@@ -1006,7 +1006,7 @@
   uint16_t  supporteddevices;
   uint8_t   number_of_path;
   uint8_t   reserved;
-  struct    atom_display_object_path_v2 display_path[8];   //the real number of this included in the structure is calculated by using the (whole structure size - the header size- number_of_path)/size of atom_display_object_path
+  struct    atom_display_object_path_v2 display_path[];   //the real number of this included in the structure is calculated by using the (whole structure size - the header size- number_of_path)/size of atom_display_object_path
 };
 
 struct display_object_info_table_v1_5 {
@@ -1016,7 +1016,7 @@
 	uint8_t reserved;
 	// the real number of this included in the structure is calculated by using the
 	// (whole structure size - the header size- number_of_path)/size of atom_display_object_path
-	struct atom_display_object_path_v3 display_path[8];
+	struct atom_display_object_path_v3 display_path[];
 };
 
 /* 
@@ -1625,6 +1625,49 @@
 	uint32_t  reserved4[189];
 };
 
+struct uma_carveout_option {
+  char       optionName[29];        //max length of string is 28chars + '\0'. Current design is for "minimum", "Medium", "High". This makes entire struct size 64bits
+  uint8_t    memoryCarvedGb;        //memory carved out with setting
+  uint8_t    memoryRemainingGb;     //memory remaining on system
+  union {
+    struct _flags {
+      uint8_t Auto     : 1;
+      uint8_t Custom   : 1;
+      uint8_t Reserved : 6;
+    } flags;
+    uint8_t all8;
+  } uma_carveout_option_flags;
+};
+
+struct atom_integrated_system_info_v2_3 {
+  struct  atom_common_table_header table_header;
+  uint32_t  vbios_misc; // enum of atom_system_vbiosmisc_def
+  uint32_t  gpucapinfo; // enum of atom_system_gpucapinf_def
+  uint32_t  system_config;
+  uint32_t  cpucapinfo;
+  uint16_t  gpuclk_ss_percentage; // unit of 0.001%,   1000 mean 1%
+  uint16_t  gpuclk_ss_type;
+  uint16_t  dpphy_override;  // bit vector, enum of atom_sysinfo_dpphy_override_def
+  uint8_t memorytype;       // enum of atom_dmi_t17_mem_type_def, APU memory type indication.
+  uint8_t umachannelnumber; // number of memory channels
+  uint8_t htc_hyst_limit;
+  uint8_t htc_tmp_limit;
+  uint8_t reserved1; // dp_ss_control
+  uint8_t gpu_package_id;
+  struct  edp_info_table  edp1_info;
+  struct  edp_info_table  edp2_info;
+  uint32_t  reserved2[8];
+  struct  atom_external_display_connection_info extdispconninfo;
+  uint8_t UMACarveoutVersion;
+  uint8_t UMACarveoutIndexMax;
+  uint8_t UMACarveoutTypeDefault;
+  uint8_t UMACarveoutIndexDefault;
+  uint8_t UMACarveoutType;           //Auto or Custom
+  uint8_t UMACarveoutIndex;
+  struct  uma_carveout_option UMASizeControlOption[20];
+  uint8_t reserved3[110];
+};
+
 // system_config
 enum atom_system_vbiosmisc_def{
   INTEGRATED_SYSTEM_INFO__GET_EDID_CALLBACK_FUNC_SUPPORT = 0x01,
@@ -3508,7 +3551,7 @@
    uint8_t  phase_delay_us;                      // phase delay in unit of micro second
    uint8_t  reserved;   
    uint32_t gpio_mask_val;                         // GPIO Mask value
-   struct atom_voltage_gpio_map_lut voltage_gpio_lut[1];
+   struct atom_voltage_gpio_map_lut voltage_gpio_lut[] __counted_by(gpio_entry_num);
 };
 
 struct  atom_svid2_voltage_object_v4
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/include/pptable.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/include/pptable.h
@@ -477,31 +477,30 @@
 } ATOM_PPLIB_STATE_V2;
 
 typedef struct _StateArray{
-    //how many states we have 
-    UCHAR ucNumEntries;
-    
-    ATOM_PPLIB_STATE_V2 states[1];
+	//how many states we have
+	UCHAR ucNumEntries;
+
+	ATOM_PPLIB_STATE_V2 states[] /* __counted_by(ucNumEntries) */;
 }StateArray;
 
 
 typedef struct _ClockInfoArray{
-    //how many clock levels we have
-    UCHAR ucNumEntries;
-    
-    //sizeof(ATOM_PPLIB_CLOCK_INFO)
-    UCHAR ucEntrySize;
-    
-    UCHAR clockInfo[1];
+	//how many clock levels we have
+	UCHAR ucNumEntries;
+
+	//sizeof(ATOM_PPLIB_CLOCK_INFO)
+	UCHAR ucEntrySize;
+
+	UCHAR clockInfo[];
 }ClockInfoArray;
 
 typedef struct _NonClockInfoArray{
+	//how many non-clock levels we have. normally should be same as number of states
+	UCHAR ucNumEntries;
+	//sizeof(ATOM_PPLIB_NONCLOCK_INFO)
+	UCHAR ucEntrySize;
 
-    //how many non-clock levels we have. normally should be same as number of states
-    UCHAR ucNumEntries;
-    //sizeof(ATOM_PPLIB_NONCLOCK_INFO)
-    UCHAR ucEntrySize;
-    
-    ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[1];
+	ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[] __counted_by(ucNumEntries);
 }NonClockInfoArray;
 
 typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record
@@ -513,8 +512,10 @@
 
 typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Table
 {
-    UCHAR ucNumEntries;                                                // Number of entries.
-    ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[1];             // Dynamically allocate entries.
+	// Number of entries.
+	UCHAR ucNumEntries;
+	// Dynamically allocate entries.
+	ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[] __counted_by(ucNumEntries);
 }ATOM_PPLIB_Clock_Voltage_Dependency_Table;
 
 typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Record
@@ -529,8 +530,10 @@
 
 typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Table
 {
-    UCHAR ucNumEntries;                                                // Number of entries.
-    ATOM_PPLIB_Clock_Voltage_Limit_Record entries[1];                  // Dynamically allocate entries.
+	// Number of entries.
+	UCHAR ucNumEntries;
+	// Dynamically allocate entries.
+	ATOM_PPLIB_Clock_Voltage_Limit_Record entries[] __counted_by(ucNumEntries);
 }ATOM_PPLIB_Clock_Voltage_Limit_Table;
 
 union _ATOM_PPLIB_CAC_Leakage_Record
@@ -553,8 +556,10 @@
 
 typedef struct _ATOM_PPLIB_CAC_Leakage_Table
 {
-    UCHAR ucNumEntries;                                                 // Number of entries.
-    ATOM_PPLIB_CAC_Leakage_Record entries[1];                           // Dynamically allocate entries.
+	// Number of entries.
+	UCHAR ucNumEntries;
+	// Dynamically allocate entries.
+	ATOM_PPLIB_CAC_Leakage_Record entries[] __counted_by(ucNumEntries);
 }ATOM_PPLIB_CAC_Leakage_Table;
 
 typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Record
@@ -568,8 +573,10 @@
 
 typedef struct _ATOM_PPLIB_PhaseSheddingLimits_Table
 {
-    UCHAR ucNumEntries;                                                 // Number of entries.
-    ATOM_PPLIB_PhaseSheddingLimits_Record entries[1];                   // Dynamically allocate entries.
+	// Number of entries.
+	UCHAR ucNumEntries;
+	// Dynamically allocate entries.
+	ATOM_PPLIB_PhaseSheddingLimits_Record entries[] __counted_by(ucNumEntries);
 }ATOM_PPLIB_PhaseSheddingLimits_Table;
 
 typedef struct _VCEClockInfo{
@@ -580,8 +587,8 @@
 }VCEClockInfo;
 
 typedef struct _VCEClockInfoArray{
-    UCHAR ucNumEntries;
-    VCEClockInfo entries[1];
+	UCHAR ucNumEntries;
+	VCEClockInfo entries[] __counted_by(ucNumEntries);
 }VCEClockInfoArray;
 
 typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record
@@ -592,8 +599,8 @@
 
 typedef struct _ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table
 {
-    UCHAR numEntries;
-    ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record entries[1];
+	UCHAR numEntries;
+	ATOM_PPLIB_VCE_Clock_Voltage_Limit_Record entries[] __counted_by(numEntries);
 }ATOM_PPLIB_VCE_Clock_Voltage_Limit_Table;
 
 typedef struct _ATOM_PPLIB_VCE_State_Record
@@ -604,8 +611,8 @@
 
 typedef struct _ATOM_PPLIB_VCE_State_Table
 {
-    UCHAR numEntries;
-    ATOM_PPLIB_VCE_State_Record entries[1];
+	UCHAR numEntries;
+	ATOM_PPLIB_VCE_State_Record entries[] __counted_by(numEntries);
 }ATOM_PPLIB_VCE_State_Table;
 
 
@@ -626,8 +633,8 @@
 }UVDClockInfo;
 
 typedef struct _UVDClockInfoArray{
-    UCHAR ucNumEntries;
-    UVDClockInfo entries[1];
+	UCHAR ucNumEntries;
+	UVDClockInfo entries[] __counted_by(ucNumEntries);
 }UVDClockInfoArray;
 
 typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record
@@ -638,8 +645,8 @@
 
 typedef struct _ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table
 {
-    UCHAR numEntries;
-    ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record entries[1];
+	UCHAR numEntries;
+	ATOM_PPLIB_UVD_Clock_Voltage_Limit_Record entries[] __counted_by(numEntries);
 }ATOM_PPLIB_UVD_Clock_Voltage_Limit_Table;
 
 typedef struct _ATOM_PPLIB_UVD_Table
@@ -657,8 +664,8 @@
 }ATOM_PPLIB_SAMClk_Voltage_Limit_Record;
 
 typedef struct _ATOM_PPLIB_SAMClk_Voltage_Limit_Table{
-    UCHAR numEntries;
-    ATOM_PPLIB_SAMClk_Voltage_Limit_Record entries[1];
+	UCHAR numEntries;
+	ATOM_PPLIB_SAMClk_Voltage_Limit_Record entries[] __counted_by(numEntries);
 }ATOM_PPLIB_SAMClk_Voltage_Limit_Table;
 
 typedef struct _ATOM_PPLIB_SAMU_Table
@@ -675,8 +682,8 @@
 }ATOM_PPLIB_ACPClk_Voltage_Limit_Record;
 
 typedef struct _ATOM_PPLIB_ACPClk_Voltage_Limit_Table{
-    UCHAR numEntries;
-    ATOM_PPLIB_ACPClk_Voltage_Limit_Record entries[1];
+	UCHAR numEntries;
+	ATOM_PPLIB_ACPClk_Voltage_Limit_Record entries[] __counted_by(numEntries);
 }ATOM_PPLIB_ACPClk_Voltage_Limit_Table;
 
 typedef struct _ATOM_PPLIB_ACP_Table
@@ -743,9 +750,9 @@
 } ATOM_PPLIB_VQ_Budgeting_Record;
 
 typedef struct ATOM_PPLIB_VQ_Budgeting_Table {
-    UCHAR revid;
-    UCHAR numEntries;
-    ATOM_PPLIB_VQ_Budgeting_Record         entries[1];
+	UCHAR revid;
+	UCHAR numEntries;
+	ATOM_PPLIB_VQ_Budgeting_Record entries[] __counted_by(numEntries);
 } ATOM_PPLIB_VQ_Budgeting_Table;
 
 #pragma pack()
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/amdgpu_pm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/amdgpu_pm.c
@@ -4217,6 +4217,13 @@
 		}
 	}
 
+	/*
+	 * If gpu_od is the only member in the list, that means gpu_od is an
+	 * empty directory, so remove it.
+	 */
+	if (list_is_singular(&adev->pm.od_kobj_list))
+		goto err_out;
+
 	return 0;
 
 err_out:
@@ -4244,8 +4251,8 @@
 	/* under multi-vf mode, the hwmon attributes are all not supported */
 	if (mode != SRIOV_VF_MODE_MULTI_VF) {
 		adev->pm.int_hwmon_dev = hwmon_device_register_with_groups(adev->dev,
-														DRIVER_NAME, adev,
-														hwmon_groups);
+									DRIVER_NAME, adev,
+									hwmon_groups);
 		if (IS_ERR(adev->pm.int_hwmon_dev)) {
 			ret = PTR_ERR(adev->pm.int_hwmon_dev);
 			dev_err(adev->dev, "Unable to register hwmon device: %d\n", ret);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c
@@ -164,6 +164,8 @@
 
 	for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) {
 		if (table[i].ulSupportedSCLK != 0) {
+			if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES)
+				continue;
 			vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit =
 				table[i].usVoltageID;
 			vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit =
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c
@@ -99,7 +99,7 @@
 	struct amdgpu_device *adev = hwmgr->adev;
 	struct amdgpu_dpm_thermal *range =
 				&adev->pm.dpm.thermal;
-	uint32_t gpu_temperature, size;
+	uint32_t gpu_temperature, size = sizeof(gpu_temperature);
 	int ret;
 
 	/*
@@ -927,7 +927,7 @@
 		enum PP_SMC_POWER_PROFILE type, bool en)
 {
 	struct pp_hwmgr *hwmgr = handle;
-	long workload;
+	long workload[1];
 	uint32_t index;
 
 	if (!hwmgr || !hwmgr->pm_en)
@@ -945,12 +945,12 @@
 		hwmgr->workload_mask &= ~(1 << hwmgr->workload_prority[type]);
 		index = fls(hwmgr->workload_mask);
 		index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0;
-		workload = hwmgr->workload_setting[index];
+		workload[0] = hwmgr->workload_setting[index];
 	} else {
 		hwmgr->workload_mask |= (1 << hwmgr->workload_prority[type]);
 		index = fls(hwmgr->workload_mask);
 		index = index <= Workload_Policy_Max ? index - 1 : 0;
-		workload = hwmgr->workload_setting[index];
+		workload[0] = hwmgr->workload_setting[index];
 	}
 
 	if (type == PP_SMC_POWER_PROFILE_COMPUTE &&
@@ -960,7 +960,7 @@
 	}
 
 	if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
-		hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0);
+		hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/pp_psm.c
@@ -30,9 +30,8 @@
 {
 	int result;
 	unsigned int i;
-	unsigned int table_entries;
 	struct pp_power_state *state;
-	int size;
+	int size, table_entries;
 
 	if (hwmgr->hwmgr_func->get_num_of_pp_table_entries == NULL)
 		return 0;
@@ -40,15 +39,19 @@
 	if (hwmgr->hwmgr_func->get_power_state_size == NULL)
 		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);
 
-	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");
+		hwmgr->num_ps = 0;
+		hwmgr->ps_size = 0;
 		return 0;
 	}
+	hwmgr->num_ps = table_entries;
+	hwmgr->ps_size = size;
 
 	hwmgr->ps = kcalloc(table_entries, size, GFP_KERNEL);
 	if (hwmgr->ps == NULL)
@@ -269,7 +272,7 @@
 						struct pp_power_state *new_ps)
 {
 	uint32_t index;
-	long workload;
+	long workload[1];
 
 	if (hwmgr->not_vf) {
 		if (!skip_display_settings)
@@ -294,10 +297,10 @@
 	if (hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) {
 		index = fls(hwmgr->workload_mask);
 		index = index > 0 && index <= Workload_Policy_Max ? index - 1 : 0;
-		workload = hwmgr->workload_setting[index];
+		workload[0] = hwmgr->workload_setting[index];
 
-		if (hwmgr->power_profile_mode != workload && hwmgr->hwmgr_func->set_power_profile_mode)
-			hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, &workload, 0);
+		if (hwmgr->power_profile_mode != workload[0] && hwmgr->hwmgr_func->set_power_profile_mode)
+			hwmgr->hwmgr_func->set_power_profile_mode(hwmgr, workload, 0);
 	}
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomctrl.c
@@ -73,8 +73,9 @@
 					j++;
 				} else if ((table->mc_reg_address[i].uc_pre_reg_data &
 							LOW_NIBBLE_MASK) == DATA_EQU_PREV) {
-					table->mc_reg_table_entry[num_ranges].mc_data[i] =
-						table->mc_reg_table_entry[num_ranges].mc_data[i-1];
+					if (i)
+						table->mc_reg_table_entry[num_ranges].mc_data[i] =
+							table->mc_reg_table_entry[num_ranges].mc_data[i-1];
 				}
 			}
 			num_ranges++;
@@ -226,7 +227,7 @@
 
 	return amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings),
-			(uint32_t *)&engine_clock_parameters);
+			(uint32_t *)&engine_clock_parameters, sizeof(engine_clock_parameters));
 }
 
 /*
@@ -297,7 +298,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 		 GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam),
-		(uint32_t *)&mpll_parameters);
+		(uint32_t *)&mpll_parameters, sizeof(mpll_parameters));
 
 	if (0 == result) {
 		mpll_param->mpll_fb_divider.clk_frac =
@@ -345,7 +346,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam),
-			(uint32_t *)&mpll_parameters);
+			(uint32_t *)&mpll_parameters, sizeof(mpll_parameters));
 
 	if (!result)
 		mpll_param->mpll_post_divider =
@@ -366,7 +367,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, ComputeMemoryClockParam),
-			(uint32_t *)&mpll_parameters);
+			(uint32_t *)&mpll_parameters, sizeof(mpll_parameters));
 
 	/* VEGAM's mpll takes sometime to finish computing */
 	udelay(10);
@@ -396,7 +397,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 		 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL),
-		(uint32_t *)&pll_parameters);
+		(uint32_t *)&pll_parameters, sizeof(pll_parameters));
 
 	if (0 == result) {
 		dividers->pll_post_divider = pll_parameters.ucPostDiv;
@@ -420,7 +421,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 		 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL),
-		(uint32_t *)&pll_patameters);
+		(uint32_t *)&pll_patameters, sizeof(pll_patameters));
 
 	if (0 == result) {
 		dividers->pll_post_divider =
@@ -457,7 +458,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 		 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL),
-		(uint32_t *)&pll_patameters);
+		(uint32_t *)&pll_patameters, sizeof(pll_patameters));
 
 	if (0 == result) {
 		dividers->usSclk_fcw_frac     = le16_to_cpu(pll_patameters.usSclk_fcw_frac);
@@ -490,7 +491,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 		 GetIndexIntoMasterTable(COMMAND, ComputeMemoryEnginePLL),
-		(uint32_t *)&pll_patameters);
+		(uint32_t *)&pll_patameters, sizeof(pll_patameters));
 
 	if (0 == result) {
 		dividers->pll_post_divider =
@@ -773,7 +774,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
-			(uint32_t *)&sOutput_FuseValues);
+			(uint32_t *)&sOutput_FuseValues, sizeof(sOutput_FuseValues));
 
 	if (result)
 		return result;
@@ -794,7 +795,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
-			(uint32_t *)&sOutput_FuseValues);
+			(uint32_t *)&sOutput_FuseValues, sizeof(sOutput_FuseValues));
 
 	if (result)
 		return result;
@@ -814,7 +815,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
-			(uint32_t *)&sOutput_FuseValues);
+			(uint32_t *)&sOutput_FuseValues, sizeof(sOutput_FuseValues));
 
 	if (result)
 		return result;
@@ -835,7 +836,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
-			(uint32_t *)&sOutput_FuseValues);
+			(uint32_t *)&sOutput_FuseValues, sizeof(sOutput_FuseValues));
 
 	if (result)
 		return result;
@@ -857,7 +858,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
-			(uint32_t *)&sOutput_FuseValues);
+			(uint32_t *)&sOutput_FuseValues, sizeof(sOutput_FuseValues));
 	if (result)
 		return result;
 
@@ -878,7 +879,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
-			(uint32_t *)&sOutput_FuseValues);
+			(uint32_t *)&sOutput_FuseValues, sizeof(sOutput_FuseValues));
 
 	if (result)
 		return result;
@@ -909,7 +910,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
-			(uint32_t *)&sOutput_FuseValues);
+			(uint32_t *)&sOutput_FuseValues, sizeof(sOutput_FuseValues));
 
 	if (result)
 		return result;
@@ -1134,7 +1135,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, GetVoltageInfo),
-			(uint32_t *)&get_voltage_info_param_space);
+			(uint32_t *)&get_voltage_info_param_space, sizeof(get_voltage_info_param_space));
 
 	*voltage = result ? 0 :
 			le16_to_cpu(((GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_2 *)
@@ -1179,7 +1180,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, GetVoltageInfo),
-			(uint32_t *)&get_voltage_info_param_space);
+			(uint32_t *)&get_voltage_info_param_space, sizeof(get_voltage_info_param_space));
 
 	if (0 != result)
 		return result;
@@ -1359,7 +1360,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, ReadEfuseValue),
-			(uint32_t *)&efuse_param);
+			(uint32_t *)&efuse_param, sizeof(efuse_param));
 	*efuse = result ? 0 : le32_to_cpu(efuse_param.ulEfuseValue) & mask;
 
 	return result;
@@ -1380,7 +1381,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 		 GetIndexIntoMasterTable(COMMAND, DynamicMemorySettings),
-		(uint32_t *)&memory_clock_parameters);
+		(uint32_t *)&memory_clock_parameters, sizeof(memory_clock_parameters));
 
 	return result;
 }
@@ -1399,7 +1400,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, GetVoltageInfo),
-			(uint32_t *)&get_voltage_info_param_space);
+			(uint32_t *)&get_voltage_info_param_space, sizeof(get_voltage_info_param_space));
 
 	*voltage = result ? 0 :
 		le32_to_cpu(((GET_EVV_VOLTAGE_INFO_OUTPUT_PARAMETER_V1_3 *)(&get_voltage_info_param_space))->ulVoltageLevel);
@@ -1419,6 +1420,8 @@
 			GetIndexIntoMasterTable(DATA, SMU_Info),
 			&size, &frev, &crev);
 
+	if (!psmu_info)
+		return -EINVAL;
 
 	for (i = 0; i < psmu_info->ucSclkEntryNum; i++) {
 		table->entry[i].ucVco_setting = psmu_info->asSclkFcwRangeEntry[i].ucVco_setting;
@@ -1526,7 +1529,7 @@
 
 	result = amdgpu_atom_execute_table(adev->mode_info.atom_context,
 			GetIndexIntoMasterTable(COMMAND, SetVoltage),
-			(uint32_t *)voltage_parameters);
+			(uint32_t *)voltage_parameters, sizeof(*voltage_parameters));
 
 	*virtual_voltage_id = voltage_parameters->usVoltageLevel;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppatomfwctrl.c
@@ -258,7 +258,7 @@
 	idx = GetIndexIntoMasterCmdTable(computegpuclockparam);
 
 	if (amdgpu_atom_execute_table(
-		adev->mode_info.atom_context, idx, (uint32_t *)&pll_parameters))
+		adev->mode_info.atom_context, idx, (uint32_t *)&pll_parameters, sizeof(pll_parameters)))
 		return -EINVAL;
 
 	pll_output = (struct compute_gpu_clock_output_parameter_v1_8 *)
@@ -505,7 +505,7 @@
 	ix = GetIndexIntoMasterCmdTable(getsmuclockinfo);
 
 	if (amdgpu_atom_execute_table(
-		adev->mode_info.atom_context, ix, (uint32_t *)&parameters))
+		adev->mode_info.atom_context, ix, (uint32_t *)&parameters, sizeof(parameters)))
 		return -EINVAL;
 
 	output = (struct atom_get_smu_clock_info_output_parameters_v3_1 *)&parameters;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c
@@ -1185,6 +1185,8 @@
 	fw_info = smu_atom_get_data_table(hwmgr->adev,
 			 GetIndexIntoMasterTable(DATA, FirmwareInfo),
 			 &size, &frev, &crev);
+	PP_ASSERT_WITH_CODE(fw_info != NULL,
+			    "Missing firmware info!", return -EINVAL);
 
 	if ((fw_info->ucTableFormatRevision == 1)
 	    && (le16_to_cpu(fw_info->usStructureSize) >= sizeof(ATOM_FIRMWARE_INFO_V1_4)))
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c
@@ -1036,7 +1036,9 @@
 
 	switch (type) {
 	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 */
 		if (now == data->gfx_max_freq_limit/100)
@@ -1057,7 +1059,9 @@
 					i == 2 ? "*" : "");
 		break;
 	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++)
 			size += sprintf(buf + size, "%d: %uMhz %s\n",
@@ -1550,7 +1554,10 @@
 		}
 
 		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) {
 				pr_err("Fine grain setting minimum sclk (%ld) MHz is less than the minimum allowed (%d) MHz\n",
 					input[1], min_freq);
@@ -1558,7 +1565,10 @@
 			}
 			smu10_data->gfx_actual_soft_min_freq = input[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) {
 				pr_err("Fine grain setting maximum sclk (%ld) MHz is greater than the maximum allowed (%d) MHz\n",
 					input[1], max_freq);
@@ -1573,10 +1583,15 @@
 			pr_err("Input parameter number not correct\n");
 			return -EINVAL;
 		}
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq);
-		smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency, &max_freq);
-
+		ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency, &min_freq);
+		if (ret)
+			return ret;
 		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;
 	} else if (type == PP_OD_COMMIT_DPM_TABLE) {
 		if (size != 0) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
@@ -2957,6 +2957,7 @@
 
 static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
 {
+	struct amdgpu_device *adev = hwmgr->adev;
 	struct smu7_hwmgr *data;
 	int result = 0;
 
@@ -2993,40 +2994,37 @@
 	/* Initalize Dynamic State Adjustment Rule Settings */
 	result = phm_initializa_dynamic_state_adjustment_rule_settings(hwmgr);
 
-	if (0 == result) {
-		struct amdgpu_device *adev = hwmgr->adev;
+	if (result)
+		goto fail;
 
-		data->is_tlu_enabled = false;
+	data->is_tlu_enabled = false;
 
-		hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
+	hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
 							SMU7_MAX_HARDWARE_POWERLEVELS;
-		hwmgr->platform_descriptor.hardwarePerformanceLevels = 2;
-		hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50;
+	hwmgr->platform_descriptor.hardwarePerformanceLevels = 2;
+	hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50;
 
-		data->pcie_gen_cap = adev->pm.pcie_gen_mask;
-		if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
-			data->pcie_spc_cap = 20;
-		else
-			data->pcie_spc_cap = 16;
-		data->pcie_lane_cap = adev->pm.pcie_mlw_mask;
+	data->pcie_gen_cap = adev->pm.pcie_gen_mask;
+	if (data->pcie_gen_cap & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)
+		data->pcie_spc_cap = 20;
+	else
+		data->pcie_spc_cap = 16;
+	data->pcie_lane_cap = adev->pm.pcie_mlw_mask;
 
-		hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */
-/* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */
-		hwmgr->platform_descriptor.clockStep.engineClock = 500;
-		hwmgr->platform_descriptor.clockStep.memoryClock = 500;
-		smu7_thermal_parameter_init(hwmgr);
-	} else {
-		/* Ignore return value in here, we are cleaning up a mess. */
-		smu7_hwmgr_backend_fini(hwmgr);
-	}
+	hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */
+	/* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */
+	hwmgr->platform_descriptor.clockStep.engineClock = 500;
+	hwmgr->platform_descriptor.clockStep.memoryClock = 500;
+	smu7_thermal_parameter_init(hwmgr);
 
 	result = smu7_update_edc_leakage_table(hwmgr);
-	if (result) {
-		smu7_hwmgr_backend_fini(hwmgr);
-		return result;
-	}
+	if (result)
+		goto fail;
 
 	return 0;
+fail:
+	smu7_hwmgr_backend_fini(hwmgr);
+	return result;
 }
 
 static int smu7_force_dpm_highest(struct pp_hwmgr *hwmgr)
@@ -3316,8 +3314,7 @@
 			const struct pp_power_state *current_ps)
 {
 	struct amdgpu_device *adev = hwmgr->adev;
-	struct smu7_power_state *smu7_ps =
-				cast_phw_smu7_power_state(&request_ps->hardware);
+	struct smu7_power_state *smu7_ps;
 	uint32_t sclk;
 	uint32_t mclk;
 	struct PP_Clocks minimum_clocks = {0};
@@ -3334,6 +3331,10 @@
 	uint32_t latency;
 	bool latency_allowed = false;
 
+	smu7_ps = cast_phw_smu7_power_state(&request_ps->hardware);
+	if (!smu7_ps)
+		return -EINVAL;
+
 	data->battery_state = (PP_StateUILabel_Battery ==
 			request_ps->classification.ui_label);
 	data->mclk_ignore_signal = false;
@@ -5640,7 +5641,7 @@
 	mode = input[size];
 	switch (mode) {
 	case PP_SMC_POWER_PROFILE_CUSTOM:
-		if (size < 8 && size != 0)
+		if (size != 8 && size != 0)
 			return -EINVAL;
 		/* If only CUSTOM is passed in, use the saved values. Check
 		 * that we actually have a CUSTOM profile by ensuring that
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c
@@ -584,6 +584,7 @@
 				hwmgr->dyn_state.uvd_clock_voltage_dependency_table;
 	unsigned long clock = 0;
 	uint32_t level;
+	int ret;
 
 	if (NULL == table || table->count <= 0)
 		return -EINVAL;
@@ -591,7 +592,9 @@
 	data->uvd_dpm.soft_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)
 		clock = table->entries[level].vclk;
@@ -611,6 +614,7 @@
 				hwmgr->dyn_state.vce_clock_voltage_dependency_table;
 	unsigned long clock = 0;
 	uint32_t level;
+	int ret;
 
 	if (NULL == table || table->count <= 0)
 		return -EINVAL;
@@ -618,7 +622,9 @@
 	data->vce_dpm.soft_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)
 		clock = table->entries[level].ecclk;
@@ -638,6 +644,7 @@
 				hwmgr->dyn_state.acp_clock_voltage_dependency_table;
 	unsigned long clock = 0;
 	uint32_t level;
+	int ret;
 
 	if (NULL == table || table->count <= 0)
 		return -EINVAL;
@@ -645,7 +652,9 @@
 	data->acp_dpm.soft_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)
 		clock = table->entries[level].acpclk;
@@ -1065,16 +1074,18 @@
 				struct pp_power_state  *prequest_ps,
 			const struct pp_power_state *pcurrent_ps)
 {
-	struct smu8_power_state *smu8_ps =
-				cast_smu8_power_state(&prequest_ps->hardware);
-
-	const struct smu8_power_state *smu8_current_ps =
-				cast_const_smu8_power_state(&pcurrent_ps->hardware);
-
+	struct smu8_power_state *smu8_ps;
+	const struct smu8_power_state *smu8_current_ps;
 	struct smu8_hwmgr *data = hwmgr->backend;
 	struct PP_Clocks clocks = {0, 0, 0, 0};
 	bool force_high;
 
+	smu8_ps = cast_smu8_power_state(&prequest_ps->hardware);
+	smu8_current_ps = cast_const_smu8_power_state(&pcurrent_ps->hardware);
+
+	if (!smu8_ps || !smu8_current_ps)
+		return -EINVAL;
+
 	smu8_ps->need_dfs_bypass = true;
 
 	data->battery_state = (PP_StateUILabel_Battery == prequest_ps->classification.ui_label);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c
@@ -354,13 +354,13 @@
 	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;
-	int i;
 	uint32_t sub_vendor_id, hw_revision;
 	uint32_t top32, bottom32;
 	struct amdgpu_device *adev = hwmgr->adev;
+	int ret, i;
 
 	vega10_initialize_power_tune_defaults(hwmgr);
 
@@ -485,9 +485,12 @@
 	if (data->registry_data.vr0hot_enabled)
 		data->smu_features[GNLD_VR0HOT].supported = true;
 
-	smum_send_msg_to_smc(hwmgr,
+	ret = smum_send_msg_to_smc(hwmgr,
 			PPSMC_MSG_GetSmuVersion,
 			&hwmgr->smu_version);
+	if (ret)
+		return ret;
+
 		/* ACG firmware has major version 5 */
 	if ((hwmgr->smu_version & 0xff000000) == 0x5000000)
 		data->smu_features[GNLD_ACG].supported = true;
@@ -505,10 +508,16 @@
 		data->smu_features[GNLD_PCC_LIMIT].supported = true;
 
 	/* Get the SN to turn into a Unique ID */
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32);
+	ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
+	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;
+	return 0;
 }
 
 #ifdef PPLIB_VEGA10_EVV_SUPPORT
@@ -882,7 +891,9 @@
 
 	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
 	/* Get leakage voltage based on leakage ID. */
@@ -2350,15 +2361,20 @@
 {
 	struct vega10_hwmgr *data = hwmgr->backend;
 	uint32_t agc_btc_response;
+	int ret;
 
 	if (data->smu_features[GNLD_ACG].supported) {
 		if (0 == vega10_enable_smc_features(hwmgr, true,
 					data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_bitmap))
 			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 == data->acg_loop_state)
@@ -2571,8 +2587,11 @@
 		}
 	}
 
-	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);
+	PP_ASSERT_WITH_CODE(!result,
+			"Failed to get voltage table!",
+			return result);
 	pp_table->MaxVidStep = voltage_table.max_vid_step;
 
 	pp_table->GfxDpmVoltageMode =
@@ -3259,8 +3278,7 @@
 			const struct pp_power_state *current_ps)
 {
 	struct amdgpu_device *adev = hwmgr->adev;
-	struct vega10_power_state *vega10_ps =
-				cast_phw_vega10_power_state(&request_ps->hardware);
+	struct vega10_power_state *vega10_ps;
 	uint32_t sclk;
 	uint32_t mclk;
 	struct PP_Clocks minimum_clocks = {0};
@@ -3278,6 +3296,10 @@
 	uint32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0;
 	uint32_t latency;
 
+	vega10_ps = cast_phw_vega10_power_state(&request_ps->hardware);
+	if (!vega10_ps)
+		return -EINVAL;
+
 	data->battery_state = (PP_StateUILabel_Battery ==
 			request_ps->classification.ui_label);
 
@@ -3415,13 +3437,17 @@
 	const struct vega10_power_state *vega10_ps =
 			cast_const_phw_vega10_power_state(states->pnew_state);
 	struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
-	uint32_t sclk = vega10_ps->performance_levels
-			[vega10_ps->performance_level_count - 1].gfx_clock;
 	struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
-	uint32_t mclk = vega10_ps->performance_levels
-			[vega10_ps->performance_level_count - 1].mem_clock;
+	uint32_t sclk, mclk;
 	uint32_t i;
 
+	if (vega10_ps == NULL)
+		return -EINVAL;
+	sclk = vega10_ps->performance_levels
+			[vega10_ps->performance_level_count - 1].gfx_clock;
+	mclk = vega10_ps->performance_levels
+			[vega10_ps->performance_level_count - 1].mem_clock;
+
 	for (i = 0; i < sclk_table->count; i++) {
 		if (sclk == sclk_table->dpm_levels[i].value)
 			break;
@@ -3728,6 +3754,9 @@
 			cast_const_phw_vega10_power_state(states->pnew_state);
 	int i;
 
+	if (vega10_ps == NULL)
+		return -EINVAL;
+
 	PP_ASSERT_WITH_CODE(!vega10_trim_dpm_states(hwmgr, vega10_ps),
 			"Attempt to Trim DPM States Failed!",
 			return -1);
@@ -3900,11 +3929,14 @@
 		uint32_t *query)
 {
 	uint32_t value;
+	int ret;
 
 	if (!query)
 		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 */
 	*query = value << 8;
@@ -4800,14 +4832,16 @@
 	uint32_t gen_speed, lane_width, current_gen_speed, current_lane_width;
 	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) {
 	case PP_SCLK:
 		if (data->registry_data.sclk_dpm_key_disabled)
 			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 &&
 		    (hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK))
@@ -4823,7 +4857,9 @@
 		if (data->registry_data.mclk_dpm_key_disabled)
 			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++)
 			size += sprintf(buf + size, "%d: %uMhz %s\n",
@@ -4834,7 +4870,9 @@
 		if (data->registry_data.socclk_dpm_key_disabled)
 			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++)
 			size += sprintf(buf + size, "%d: %uMhz %s\n",
@@ -4845,8 +4883,10 @@
 		if (data->registry_data.dcefclk_dpm_key_disabled)
 			break;
 
-		smum_send_msg_to_smc_with_parameter(hwmgr,
+		ret = smum_send_msg_to_smc_with_parameter(hwmgr,
 				PPSMC_MSG_GetClockFreqMHz, CLK_DCEFCLK, &now);
+		if (ret)
+			break;
 
 		for (i = 0; i < dcef_table->count; i++)
 			size += sprintf(buf + size, "%d: %uMhz %s\n",
@@ -4995,6 +5035,8 @@
 
 	vega10_psa = cast_const_phw_vega10_power_state(pstate1);
 	vega10_psb = cast_const_phw_vega10_power_state(pstate2);
+	if (vega10_psa == NULL || vega10_psb == NULL)
+		return -EINVAL;
 
 	/* If the two states don't even have the same number of performance levels
 	 * they cannot be the same state.
@@ -5128,6 +5170,8 @@
 		return -EINVAL;
 
 	vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
+	if (vega10_ps == NULL)
+		return -EINVAL;
 
 	vega10_ps->performance_levels
 	[vega10_ps->performance_level_count - 1].gfx_clock =
@@ -5179,6 +5223,8 @@
 		return -EINVAL;
 
 	vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
+	if (vega10_ps == NULL)
+		return -EINVAL;
 
 	vega10_ps->performance_levels
 	[vega10_ps->performance_level_count - 1].mem_clock =
@@ -5420,6 +5466,9 @@
 		return;
 
 	vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
+	if (vega10_ps == NULL)
+		return;
+
 	max_level = vega10_ps->performance_level_count - 1;
 
 	if (vega10_ps->performance_levels[max_level].gfx_clock !=
@@ -5442,6 +5491,9 @@
 
 	ps = (struct pp_power_state *)((unsigned long)(hwmgr->ps) + hwmgr->ps_size * (hwmgr->num_ps - 1));
 	vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
+	if (vega10_ps == NULL)
+		return;
+
 	max_level = vega10_ps->performance_level_count - 1;
 
 	if (vega10_ps->performance_levels[max_level].gfx_clock !=
@@ -5632,6 +5684,8 @@
 		return -EINVAL;
 
 	vega10_ps = cast_const_phw_vega10_power_state(state);
+	if (vega10_ps == NULL)
+		return -EINVAL;
 
 	i = index > vega10_ps->performance_level_count - 1 ?
 			vega10_ps->performance_level_count - 1 : index;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_powertune.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_powertune.c
@@ -1120,13 +1120,14 @@
 	result = vega10_program_didt_config_registers(hwmgr, SEEDCForceStallPatternConfig_Vega10, VEGA10_CONFIGREG_DIDT);
 	result |= vega10_program_didt_config_registers(hwmgr, SEEDCCtrlForceStallConfig_Vega10, VEGA10_CONFIGREG_DIDT);
 	if (0 != result)
-		return result;
+		goto exit_safe_mode;
 
 	vega10_didt_set_mask(hwmgr, false);
 
+exit_safe_mode:
 	amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
 
-	return 0;
+	return result;
 }
 
 static int vega10_disable_se_edc_force_stall_config(struct pp_hwmgr *hwmgr)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c
@@ -293,12 +293,12 @@
 	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 amdgpu_device *adev = hwmgr->adev;
 	uint32_t top32, bottom32;
-	int i;
+	int i, ret;
 
 	data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_id =
 			FEATURE_DPM_PREFETCHER_BIT;
@@ -364,10 +364,16 @@
 	}
 
 	/* Get the SN to turn into a Unique ID */
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32);
+	ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
+	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;
+
+	return 0;
 }
 
 static int vega12_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr)
@@ -410,7 +416,11 @@
 
 	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 */
 	vega12_set_private_data_based_on_pptable(hwmgr);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c
@@ -328,12 +328,12 @@
 	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 amdgpu_device *adev = hwmgr->adev;
 	uint32_t top32, bottom32;
-	int i;
+	int i, ret;
 
 	data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_id =
 			FEATURE_DPM_PREFETCHER_BIT;
@@ -404,10 +404,17 @@
 	}
 
 	/* Get the SN to turn into a Unique ID */
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
-	smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32, &bottom32);
+	ret = smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32, &top32);
+	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;
+
+	return 0;
 }
 
 static int vega20_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr)
@@ -427,6 +434,7 @@
 {
 	struct vega20_hwmgr *data;
 	struct amdgpu_device *adev = hwmgr->adev;
+	int result;
 
 	data = kzalloc(sizeof(struct vega20_hwmgr), GFP_KERNEL);
 	if (data == NULL)
@@ -452,8 +460,11 @@
 
 	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 */
 	vega20_set_private_data_based_on_pptable(hwmgr);
 
@@ -4091,9 +4102,11 @@
 	if (power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
 		struct vega20_hwmgr *data =
 			(struct vega20_hwmgr *)(hwmgr->backend);
-		if (size == 0 && !data->is_custom_profile_set)
+
+		if (size != 10 && size != 0)
 			return -EINVAL;
-		if (size < 10 && size != 0)
+
+		if (size == 0 && !data->is_custom_profile_set)
 			return -EINVAL;
 
 		result = vega20_get_activity_monitor_coeff(hwmgr,
@@ -4155,6 +4168,8 @@
 			activity_monitor.Fclk_PD_Data_error_coeff = input[8];
 			activity_monitor.Fclk_PD_Data_error_rate_coeff = input[9];
 			break;
+		default:
+			return -EINVAL;
 		}
 
 		result = vega20_set_activity_monitor_coeff(hwmgr,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c
@@ -130,13 +130,17 @@
 			    uint64_t *features_enabled)
 {
 	uint32_t enabled_features;
+	int ret;
 
 	if (features_enabled == NULL)
 		return -EINVAL;
 
-	smum_send_msg_to_smc(hwmgr,
+	ret = smum_send_msg_to_smc(hwmgr,
 			PPSMC_MSG_GetEnabledSmuFeatures,
 			&enabled_features);
+	if (ret)
+		return ret;
+
 	*features_enabled = enabled_features;
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c
@@ -734,7 +734,7 @@
 	smu->adev = adev;
 	smu->pm_enabled = !!amdgpu_dpm;
 	smu->is_apu = false;
-	smu->smu_baco.state = SMU_BACO_STATE_EXIT;
+	smu->smu_baco.state = SMU_BACO_STATE_NONE;
 	smu->smu_baco.platform_support = false;
 	smu->user_dpm_profile.fan_mode = -1;
 
@@ -1192,6 +1192,14 @@
 		smu->plpd_mode = XGMI_PLPD_NONE;
 }
 
+static bool smu_is_workload_profile_available(struct smu_context *smu,
+					      u32 profile)
+{
+	if (profile >= PP_SMC_POWER_PROFILE_COUNT)
+		return false;
+	return smu->workload_map && smu->workload_map[profile].valid_mapping;
+}
+
 static int smu_sw_init(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@@ -1215,7 +1223,6 @@
 	atomic_set(&smu->smu_power.power_gate.vpe_gated, 1);
 	atomic_set(&smu->smu_power.power_gate.umsch_mm_gated, 1);
 
-	smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];
 	smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT] = 0;
 	smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D] = 1;
 	smu->workload_prority[PP_SMC_POWER_PROFILE_POWERSAVING] = 2;
@@ -1224,6 +1231,12 @@
 	smu->workload_prority[PP_SMC_POWER_PROFILE_COMPUTE] = 5;
 	smu->workload_prority[PP_SMC_POWER_PROFILE_CUSTOM] = 6;
 
+	if (smu->is_apu ||
+	    !smu_is_workload_profile_available(smu, PP_SMC_POWER_PROFILE_FULLSCREEN3D))
+		smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];
+	else
+		smu->workload_mask = 1 << smu->workload_prority[PP_SMC_POWER_PROFILE_FULLSCREEN3D];
+
 	smu->workload_setting[0] = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
 	smu->workload_setting[1] = PP_SMC_POWER_PROFILE_FULLSCREEN3D;
 	smu->workload_setting[2] = PP_SMC_POWER_PROFILE_POWERSAVING;
@@ -1954,10 +1967,25 @@
 	return 0;
 }
 
+static int smu_reset_mp1_state(struct smu_context *smu)
+{
+	struct amdgpu_device *adev = smu->adev;
+	int ret = 0;
+
+	if ((!adev->in_runpm) && (!adev->in_suspend) &&
+		(!amdgpu_in_reset(adev)) && amdgpu_ip_version(adev, MP1_HWIP, 0) ==
+									IP_VERSION(13, 0, 10) &&
+		!amdgpu_device_has_display_hardware(adev))
+		ret = smu_set_mp1_state(smu, PP_MP1_STATE_UNLOAD);
+
+	return ret;
+}
+
 static int smu_hw_fini(void *handle)
 {
 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 	struct smu_context *smu = adev->powerplay.pp_handle;
+	int ret;
 
 	if (amdgpu_sriov_vf(adev) && !amdgpu_sriov_is_pp_one_vf(adev))
 		return 0;
@@ -1975,7 +2003,15 @@
 
 	adev->pm.dpm_enabled = false;
 
-	return smu_smc_hw_cleanup(smu);
+	ret = smu_smc_hw_cleanup(smu);
+	if (ret)
+		return ret;
+
+	ret = smu_reset_mp1_state(smu);
+	if (ret)
+		return ret;
+
+	return 0;
 }
 
 static void smu_late_fini(void *handle)
@@ -2161,12 +2197,13 @@
 }
 
 static int smu_adjust_power_state_dynamic(struct smu_context *smu,
-				   enum amd_dpm_forced_level level,
-				   bool skip_display_settings)
+					  enum amd_dpm_forced_level level,
+					  bool skip_display_settings,
+					  bool init)
 {
 	int ret = 0;
 	int index = 0;
-	long workload;
+	long workload[1];
 	struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
 
 	if (!skip_display_settings) {
@@ -2206,10 +2243,10 @@
 		smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {
 		index = fls(smu->workload_mask);
 		index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
-		workload = smu->workload_setting[index];
+		workload[0] = smu->workload_setting[index];
 
-		if (smu->power_profile_mode != workload)
-			smu_bump_power_profile_mode(smu, &workload, 0);
+		if (init || smu->power_profile_mode != workload[0])
+			smu_bump_power_profile_mode(smu, workload, 0);
 	}
 
 	return ret;
@@ -2229,11 +2266,13 @@
 		ret = smu_pre_display_config_changed(smu);
 		if (ret)
 			return ret;
-		ret = smu_adjust_power_state_dynamic(smu, level, false);
+		ret = smu_adjust_power_state_dynamic(smu, level, false, false);
 		break;
 	case AMD_PP_TASK_COMPLETE_INIT:
+		ret = smu_adjust_power_state_dynamic(smu, level, true, true);
+		break;
 	case AMD_PP_TASK_READJUST_POWER_STATE:
-		ret = smu_adjust_power_state_dynamic(smu, level, true);
+		ret = smu_adjust_power_state_dynamic(smu, level, true, false);
 		break;
 	default:
 		break;
@@ -2259,7 +2298,7 @@
 {
 	struct smu_context *smu = handle;
 	struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);
-	long workload;
+	long workload[1];
 	uint32_t index;
 
 	if (!smu->pm_enabled || !smu->adev->pm.dpm_enabled)
@@ -2272,17 +2311,17 @@
 		smu->workload_mask &= ~(1 << smu->workload_prority[type]);
 		index = fls(smu->workload_mask);
 		index = index > 0 && index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
-		workload = smu->workload_setting[index];
+		workload[0] = smu->workload_setting[index];
 	} else {
 		smu->workload_mask |= (1 << smu->workload_prority[type]);
 		index = fls(smu->workload_mask);
 		index = index <= WORKLOAD_POLICY_MAX ? index - 1 : 0;
-		workload = smu->workload_setting[index];
+		workload[0] = smu->workload_setting[index];
 	}
 
 	if (smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL &&
 		smu_dpm_ctx->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)
-		smu_bump_power_profile_mode(smu, &workload, 0);
+		smu_bump_power_profile_mode(smu, workload, 0);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
@@ -424,6 +424,7 @@
 enum smu_baco_state {
 	SMU_BACO_STATE_ENTER = 0,
 	SMU_BACO_STATE_EXIT,
+	SMU_BACO_STATE_NONE,
 };
 
 struct smu_baco_context {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h
@@ -298,5 +298,11 @@
 
 int smu_v13_0_set_wbrf_exclusion_ranges(struct smu_context *smu,
 						 struct freq_band_range *exclusion_ranges);
+
+int smu_v13_0_get_boot_freq_by_index(struct smu_context *smu,
+				     enum smu_clk_type clk_type,
+				     uint32_t *value);
+
+void smu_v13_0_interrupt_work(struct smu_context *smu);
 #endif
 #endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c
@@ -1283,10 +1283,8 @@
 					uint32_t *max_power_limit,
 					uint32_t *min_power_limit)
 {
-	struct smu_11_0_powerplay_table *powerplay_table =
-		(struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
 	PPTable_t *pptable = smu->smu_table.driver_pptable;
-	uint32_t power_limit, od_percent_upper, od_percent_lower;
+	uint32_t power_limit;
 
 	if (smu_v11_0_get_current_power_limit(smu, &power_limit)) {
 		/* the last hope to figure out the ppt limit */
@@ -1302,26 +1300,14 @@
 		*current_power_limit = power_limit;
 	if (default_power_limit)
 		*default_power_limit = power_limit;
-
-	if (smu->od_enabled)
-		od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
-	else
-		od_percent_upper = 0;
-
-	od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
-
-	dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
-							od_percent_upper, od_percent_lower, power_limit);
-
-	if (max_power_limit) {
-		*max_power_limit = power_limit * (100 + od_percent_upper);
-		*max_power_limit /= 100;
-	}
-
-	if (min_power_limit) {
-		*min_power_limit = power_limit * (100 - od_percent_lower);
-		*min_power_limit /= 100;
-	}
+	if (max_power_limit)
+		*max_power_limit = power_limit;
+	/**
+	 * No lower bound is imposed on the limit. Any unreasonable limit set
+	 * will result in frequent throttling.
+	 */
+	if (min_power_limit)
+		*min_power_limit = 0;
 
 	return 0;
 }
@@ -1434,6 +1420,9 @@
 
 	if ((profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) &&
 	     (smu->smc_fw_version >= 0x360d00)) {
+		if (size != 10)
+			return -EINVAL;
+
 		ret = smu_cmn_update_table(smu,
 				       SMU_TABLE_ACTIVITY_MONITOR_COEFF,
 				       WORKLOAD_PPLIB_CUSTOM_BIT,
@@ -1467,6 +1456,8 @@
 			activity_monitor.Mem_PD_Data_error_coeff = input[8];
 			activity_monitor.Mem_PD_Data_error_rate_coeff = input[9];
 			break;
+		default:
+			return -EINVAL;
 		}
 
 		ret = smu_cmn_update_table(smu,
@@ -2272,8 +2263,8 @@
 
 	/* TODO: confirm this on real target */
 	esm_ctrl = RREG32_PCIE(smnPCIE_ESM_CTRL);
-	if ((esm_ctrl >> 15) & 0x1FFFF)
-		return (uint16_t)(((esm_ctrl >> 8) & 0x3F) + 128);
+	if ((esm_ctrl >> 15) & 0x1)
+		return (uint16_t)(((esm_ctrl >> 8) & 0x7F) + 128);
 
 	return smu_v11_0_get_current_pcie_link_speed(smu);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c
@@ -1219,19 +1219,22 @@
 					   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;
 	DpmDescriptor_t *dpm_desc = NULL;
-	uint32_t clk_index = 0;
+	int clk_index = 0;
 
 	clk_index = smu_cmn_to_asic_specific_index(smu,
 						   CMN2ASIC_MAPPING_CLK,
 						   clk_type);
+	if (clk_index < 0)
+		return clk_index;
+
 	dpm_desc = &pptable->DpmDescriptor[clk_index];
 
 	/* 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)
@@ -1287,7 +1290,11 @@
 		if (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++) {
 				ret = smu_v11_0_get_dpm_freq_by_index(smu,
 								      clk_type, i, &value);
@@ -1496,7 +1503,11 @@
 		if (ret)
 			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++) {
 				ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value);
 				if (ret)
@@ -1665,7 +1676,11 @@
 	case SMU_UCLK:
 	case SMU_FCLK:
 		/* 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_min_level = (soft_min_level >= 1 ? 1 : 0);
 		}
@@ -2006,6 +2021,8 @@
 	}
 
 	if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
+		if (size != 10)
+			return -EINVAL;
 
 		ret = smu_cmn_update_table(smu,
 				       SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
@@ -2049,6 +2066,8 @@
 			activity_monitor.Mem_PD_Data_error_coeff = input[8];
 			activity_monitor.Mem_PD_Data_error_rate_coeff = input[9];
 			break;
+		default:
+			return -EINVAL;
 		}
 
 		ret = smu_cmn_update_table(smu,
@@ -2339,7 +2358,7 @@
 		(struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
 	struct smu_11_0_overdrive_table *od_settings = smu->od_settings;
 	PPTable_t *pptable = smu->smu_table.driver_pptable;
-	uint32_t power_limit, od_percent_upper, od_percent_lower;
+	uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0;
 
 	if (smu_v11_0_get_current_power_limit(smu, &power_limit)) {
 		/* the last hope to figure out the ppt limit */
@@ -2356,13 +2375,16 @@
 	if (default_power_limit)
 		*default_power_limit = power_limit;
 
-	if (smu->od_enabled &&
-		    navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT))
-		od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
-	else
-		od_percent_upper = 0;
-
-	od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
+	if (powerplay_table) {
+		if (smu->od_enabled &&
+			    navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) {
+			od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
+			od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
+		} else if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) {
+			od_percent_upper = 0;
+			od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
+		}
+	}
 
 	dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
 					od_percent_upper, od_percent_lower, power_limit);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c
@@ -617,6 +617,12 @@
 	return throttler_status;
 }
 
+static bool sienna_cichlid_is_od_feature_supported(struct smu_11_0_7_overdrive_table *od_table,
+						   enum SMU_11_0_7_ODFEATURE_CAP cap)
+{
+	return od_table->cap[cap];
+}
+
 static int sienna_cichlid_get_power_limit(struct smu_context *smu,
 					  uint32_t *current_power_limit,
 					  uint32_t *default_power_limit,
@@ -625,7 +631,8 @@
 {
 	struct smu_11_0_7_powerplay_table *powerplay_table =
 		(struct smu_11_0_7_powerplay_table *)smu->smu_table.power_play_table;
-	uint32_t power_limit, od_percent_upper, od_percent_lower;
+	struct smu_11_0_7_overdrive_table *od_settings = smu->od_settings;
+	uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0;
 	uint16_t *table_member;
 
 	GET_PPTABLE_MEMBER(SocketPowerLimitAc, &table_member);
@@ -640,12 +647,16 @@
 	if (default_power_limit)
 		*default_power_limit = power_limit;
 
-	if (smu->od_enabled)
-		od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
-	else
-		od_percent_upper = 0;
-
-	od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
+	if (powerplay_table) {
+		if (smu->od_enabled &&
+				sienna_cichlid_is_od_feature_supported(od_settings, SMU_11_0_7_ODCAP_POWER_LIMIT)) {
+			od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
+			od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
+		} else if ((sienna_cichlid_is_od_feature_supported(od_settings, SMU_11_0_7_ODCAP_POWER_LIMIT))) {
+			od_percent_upper = 0;
+			od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_11_0_7_ODSETTING_POWERPERCENTAGE]);
+		}
+	}
 
 	dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
 					od_percent_upper, od_percent_lower, power_limit);
@@ -1250,12 +1261,6 @@
 	return dpm_desc->SnapToDiscrete == 0;
 }
 
-static bool sienna_cichlid_is_od_feature_supported(struct smu_11_0_7_overdrive_table *od_table,
-						   enum SMU_11_0_7_ODFEATURE_CAP cap)
-{
-	return od_table->cap[cap];
-}
-
 static void sienna_cichlid_get_od_setting_range(struct smu_11_0_7_overdrive_table *od_table,
 						enum SMU_11_0_7_ODSETTING_ID setting,
 						uint32_t *min, uint32_t *max)
@@ -1717,6 +1722,8 @@
 	}
 
 	if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
+		if (size != 10)
+			return -EINVAL;
 
 		ret = smu_cmn_update_table(smu,
 				       SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
@@ -1760,6 +1767,8 @@
 			activity_monitor->Mem_PD_Data_error_coeff = input[8];
 			activity_monitor->Mem_PD_Data_error_rate_coeff = input[9];
 			break;
+		default:
+			return -EINVAL;
 		}
 
 		ret = smu_cmn_update_table(smu,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
@@ -514,7 +514,7 @@
 					    getsmuclockinfo);
 
 	ret = amdgpu_atom_execute_table(adev->mode_info.atom_context, index,
-					(uint32_t *)&input);
+					(uint32_t *)&input, sizeof(input));
 	if (ret)
 		return -EINVAL;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c
@@ -242,7 +242,9 @@
 		goto err0_out;
 	smu_table->metrics_time = 0;
 
-	smu_table->gpu_metrics_table_size = max(sizeof(struct gpu_metrics_v2_3), sizeof(struct gpu_metrics_v2_2));
+	smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_2);
+	smu_table->gpu_metrics_table_size = max(smu_table->gpu_metrics_table_size, sizeof(struct gpu_metrics_v2_3));
+	smu_table->gpu_metrics_table_size = max(smu_table->gpu_metrics_table_size, sizeof(struct gpu_metrics_v2_4));
 	smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
 	if (!smu_table->gpu_metrics_table)
 		goto err1_out;
@@ -976,6 +978,18 @@
 		}
 	}
 	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) {
 		case SMU_UCLK:
 		case SMU_MCLK:
@@ -2444,6 +2458,8 @@
 
 	ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_LogGfxOffResidency,
 					      start, &residency);
+	if (ret)
+		return ret;
 
 	if (!start)
 		adev->gfx.gfx_off_residency = residency;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
@@ -301,7 +301,7 @@
 					    getsmuclockinfo);
 
 	ret = amdgpu_atom_execute_table(adev->mode_info.atom_context, index,
-					(uint32_t *)&input);
+					(uint32_t *)&input, sizeof(input));
 	if (ret)
 		return -EINVAL;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c
@@ -1682,8 +1682,8 @@
 
 	/* TODO: confirm this on real target */
 	esm_ctrl = RREG32_PCIE(smnPCIE_ESM_CTRL);
-	if ((esm_ctrl >> 15) & 0x1FFFF)
-		return (((esm_ctrl >> 8) & 0x3F) + 128);
+	if ((esm_ctrl >> 15) & 0x1)
+		return (((esm_ctrl >> 8) & 0x7F) + 128);
 
 	return smu_v13_0_get_current_pcie_link_speed(smu);
 }
@@ -1714,7 +1714,6 @@
 
 	gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity;
 	gpu_metrics->average_umc_activity = metrics.AverageUclkActivity;
-	gpu_metrics->average_mm_activity = 0;
 
 	/* Valid power data is available only from primary die */
 	if (aldebaran_is_primary(smu)) {
@@ -1880,7 +1879,8 @@
 
 	index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG,
 						SMU_MSG_GfxDeviceDriverReset);
-
+	if (index < 0 )
+		return -EINVAL;
 	mutex_lock(&smu->message_lock);
 	if (smu->smc_fw_version >= 0x00441400) {
 		ret = smu_cmn_send_msg_without_waiting(smu, (uint16_t)index, SMU_RESET_MODE_2);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c
@@ -79,8 +79,8 @@
 #define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK 0x00000070L
 #define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT 0x4
 #define smnPCIE_LC_SPEED_CNTL			0x11140290
-#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK 0xC000
-#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0xE
+#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK 0xE0
+#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0x5
 
 #define ENABLE_IMU_ARG_GFXOFF_ENABLE		1
 
@@ -1321,11 +1321,11 @@
 	return 0;
 }
 
-static int smu_v13_0_ack_ac_dc_interrupt(struct smu_context *smu)
+void smu_v13_0_interrupt_work(struct smu_context *smu)
 {
-	return smu_cmn_send_smc_msg(smu,
-				    SMU_MSG_ReenableAcDcInterrupt,
-				    NULL);
+	smu_cmn_send_smc_msg(smu,
+			     SMU_MSG_ReenableAcDcInterrupt,
+			     NULL);
 }
 
 #define THM_11_0__SRCID__THM_DIG_THERM_L2H		0		/* ASIC_TEMP > CG_THERMAL_INT.DIG_THERM_INTH  */
@@ -1378,12 +1378,12 @@
 			switch (ctxid) {
 			case 0x3:
 				dev_dbg(adev->dev, "Switched to AC mode!\n");
-				smu_v13_0_ack_ac_dc_interrupt(smu);
+				schedule_work(&smu->interrupt_work);
 				adev->pm.ac_power = true;
 				break;
 			case 0x4:
 				dev_dbg(adev->dev, "Switched to DC mode!\n");
-				smu_v13_0_ack_ac_dc_interrupt(smu);
+				schedule_work(&smu->interrupt_work);
 				adev->pm.ac_power = false;
 				break;
 			case 0x7:
@@ -1555,22 +1555,9 @@
 	uint32_t clock_limit;
 
 	if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) {
-		switch (clk_type) {
-		case SMU_MCLK:
-		case SMU_UCLK:
-			clock_limit = smu->smu_table.boot_values.uclk;
-			break;
-		case SMU_GFXCLK:
-		case SMU_SCLK:
-			clock_limit = smu->smu_table.boot_values.gfxclk;
-			break;
-		case SMU_SOCCLK:
-			clock_limit = smu->smu_table.boot_values.socclk;
-			break;
-		default:
-			clock_limit = 0;
-			break;
-		}
+		ret = smu_v13_0_get_boot_freq_by_index(smu, clk_type, &clock_limit);
+		if (ret)
+			return ret;
 
 		/* clock in Mhz unit */
 		if (min)
@@ -1890,6 +1877,40 @@
 					       NULL);
 }
 
+int smu_v13_0_get_boot_freq_by_index(struct smu_context *smu,
+				     enum smu_clk_type clk_type,
+				     uint32_t *value)
+{
+	int ret = 0;
+
+	switch (clk_type) {
+	case SMU_MCLK:
+	case SMU_UCLK:
+		*value = smu->smu_table.boot_values.uclk;
+		break;
+	case SMU_FCLK:
+		*value = smu->smu_table.boot_values.fclk;
+		break;
+	case SMU_GFXCLK:
+	case SMU_SCLK:
+		*value = smu->smu_table.boot_values.gfxclk;
+		break;
+	case SMU_SOCCLK:
+		*value = smu->smu_table.boot_values.socclk;
+		break;
+	case SMU_VCLK:
+		*value = smu->smu_table.boot_values.vclk;
+		break;
+	case SMU_DCLK:
+		*value = smu->smu_table.boot_values.dclk;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
 int smu_v13_0_get_dpm_freq_by_index(struct smu_context *smu,
 				    enum smu_clk_type clk_type, uint16_t level,
 				    uint32_t *value)
@@ -1901,7 +1922,7 @@
 		return -EINVAL;
 
 	if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type))
-		return 0;
+		return smu_v13_0_get_boot_freq_by_index(smu, clk_type, value);
 
 	clk_id = smu_cmn_to_asic_specific_index(smu,
 						CMN2ASIC_MAPPING_CLK,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -2356,7 +2356,7 @@
 		(struct smu_13_0_0_powerplay_table *)table_context->power_play_table;
 	PPTable_t *pptable = table_context->driver_pptable;
 	SkuTable_t *skutable = &pptable->SkuTable;
-	uint32_t power_limit, od_percent_upper, od_percent_lower;
+	uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0;
 	uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
 
 	if (smu_v13_0_get_current_power_limit(smu, &power_limit))
@@ -2369,12 +2369,16 @@
 	if (default_power_limit)
 		*default_power_limit = power_limit;
 
-	if (smu->od_enabled)
-		od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]);
-	else
-		od_percent_upper = 0;
-
-	od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]);
+	if (powerplay_table) {
+		if (smu->od_enabled &&
+				smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_PPT_BIT)) {
+			od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]);
+			od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]);
+		} else if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_PPT_BIT)) {
+			od_percent_upper = 0;
+			od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_0_ODSETTING_POWERPERCENTAGE]);
+		}
+	}
 
 	dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
 					od_percent_upper, od_percent_lower, power_limit);
@@ -2491,6 +2495,9 @@
 	}
 
 	if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
+		if (size != 9)
+			return -EINVAL;
+
 		ret = smu_cmn_update_table(smu,
 					   SMU_TABLE_ACTIVITY_MONITOR_COEFF,
 					   WORKLOAD_PPLIB_CUSTOM_BIT,
@@ -2522,6 +2529,8 @@
 			activity_monitor->Fclk_PD_Data_error_coeff = input[7];
 			activity_monitor->Fclk_PD_Data_error_rate_coeff = input[8];
 			break;
+		default:
+			return -EINVAL;
 		}
 
 		ret = smu_cmn_update_table(smu,
@@ -2546,18 +2555,17 @@
 	workload_mask = 1 << workload_type;
 
 	/* Add optimizations for SMU13.0.0/10.  Reuse the power saving profile */
-	if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_COMPUTE) {
-		if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) &&
-			((smu->adev->pm.fw_version == 0x004e6601) ||
-			(smu->adev->pm.fw_version >= 0x004e7300))) ||
-			(amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) &&
-			 smu->adev->pm.fw_version >= 0x00504500)) {
-			workload_type = smu_cmn_to_asic_specific_index(smu,
-														   CMN2ASIC_MAPPING_WORKLOAD,
-														   PP_SMC_POWER_PROFILE_POWERSAVING);
-			if (workload_type >= 0)
-				workload_mask |= 1 << workload_type;
-		}
+	if ((workload_mask & (1 << PP_SMC_POWER_PROFILE_COMPUTE)) &&
+	    ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) &&
+	      ((smu->adev->pm.fw_version == 0x004e6601) ||
+	       (smu->adev->pm.fw_version >= 0x004e7300))) ||
+	     (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) &&
+	      smu->adev->pm.fw_version >= 0x00504500))) {
+		workload_type = smu_cmn_to_asic_specific_index(smu,
+							       CMN2ASIC_MAPPING_WORKLOAD,
+							       PP_SMC_POWER_PROFILE_POWERSAVING);
+		if (workload_type >= 0)
+			workload_mask |= 1 << workload_type;
 	}
 
 	return smu_cmn_send_smc_msg_with_param(smu,
@@ -2747,7 +2755,13 @@
 
 	switch (mp1_state) {
 	case PP_MP1_STATE_UNLOAD:
-		ret = smu_cmn_set_mp1_state(smu, mp1_state);
+		ret = smu_cmn_send_smc_msg_with_param(smu,
+											  SMU_MSG_PrepareMp1ForUnload,
+											  0x55, NULL);
+
+		if (!ret && smu->smu_baco.state == SMU_BACO_STATE_EXIT)
+			ret = smu_v13_0_disable_pmfw_state(smu);
+
 		break;
 	default:
 		/* Ignore others */
@@ -3083,6 +3097,7 @@
 	.is_asic_wbrf_supported = smu_v13_0_0_wbrf_support_check,
 	.enable_uclk_shadow = smu_v13_0_enable_uclk_shadow,
 	.set_wbrf_exclusion_ranges = smu_v13_0_set_wbrf_exclusion_ranges,
+	.interrupt_work = smu_v13_0_interrupt_work,
 };
 
 void smu_v13_0_0_set_ppt_funcs(struct smu_context *smu)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c
@@ -226,8 +226,20 @@
 	struct amdgpu_device *adev = smu->adev;
 	int ret = 0;
 
-	if (!en && !adev->in_s0ix)
+	if (!en && !adev->in_s0ix) {
+		if (adev->in_s4) {
+			/* Adds a GFX reset as workaround just before sending the
+			 * MP1_UNLOAD message to prevent GC/RLC/PMFW from entering
+			 * an invalid state.
+			 */
+			ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset,
+							      SMU_RESET_MODE_2, NULL);
+			if (ret)
+				return ret;
+		}
+
 		ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL);
+	}
 
 	return ret;
 }
@@ -740,31 +752,9 @@
 	int ret = 0;
 
 	if (!smu_v13_0_4_clk_dpm_is_enabled(smu, clk_type)) {
-		switch (clk_type) {
-		case SMU_MCLK:
-		case SMU_UCLK:
-			clock_limit = smu->smu_table.boot_values.uclk;
-			break;
-		case SMU_FCLK:
-			clock_limit = smu->smu_table.boot_values.fclk;
-			break;
-		case SMU_GFXCLK:
-		case SMU_SCLK:
-			clock_limit = smu->smu_table.boot_values.gfxclk;
-			break;
-		case SMU_SOCCLK:
-			clock_limit = smu->smu_table.boot_values.socclk;
-			break;
-		case SMU_VCLK:
-			clock_limit = smu->smu_table.boot_values.vclk;
-			break;
-		case SMU_DCLK:
-			clock_limit = smu->smu_table.boot_values.dclk;
-			break;
-		default:
-			clock_limit = 0;
-			break;
-		}
+		ret = smu_v13_0_get_boot_freq_by_index(smu, clk_type, &clock_limit);
+		if (ret)
+			return ret;
 
 		/* clock in Mhz unit */
 		if (min)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c
@@ -727,31 +727,9 @@
 	int ret = 0;
 
 	if (!smu_v13_0_5_clk_dpm_is_enabled(smu, clk_type)) {
-		switch (clk_type) {
-		case SMU_MCLK:
-		case SMU_UCLK:
-			clock_limit = smu->smu_table.boot_values.uclk;
-			break;
-		case SMU_FCLK:
-			clock_limit = smu->smu_table.boot_values.fclk;
-			break;
-		case SMU_GFXCLK:
-		case SMU_SCLK:
-			clock_limit = smu->smu_table.boot_values.gfxclk;
-			break;
-		case SMU_SOCCLK:
-			clock_limit = smu->smu_table.boot_values.socclk;
-			break;
-		case SMU_VCLK:
-			clock_limit = smu->smu_table.boot_values.vclk;
-			break;
-		case SMU_DCLK:
-			clock_limit = smu->smu_table.boot_values.dclk;
-			break;
-		default:
-			clock_limit = 0;
-			break;
-		}
+		ret = smu_v13_0_get_boot_freq_by_index(smu, clk_type, &clock_limit);
+		if (ret)
+			return ret;
 
 		/* clock in Mhz unit */
 		if (min)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
@@ -2060,8 +2060,8 @@
 
 	/* TODO: confirm this on real target */
 	esm_ctrl = RREG32_PCIE(smnPCIE_ESM_CTRL);
-	if ((esm_ctrl >> 15) & 0x1FFFF)
-		return (((esm_ctrl >> 8) & 0x3F) + 128);
+	if ((esm_ctrl >> 15) & 0x1)
+		return (((esm_ctrl >> 8) & 0x7F) + 128);
 
 	speed_level = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) &
 		PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK)
@@ -2205,6 +2205,17 @@
 	return sizeof(*gpu_metrics);
 }
 
+static void smu_v13_0_6_restore_pci_config(struct smu_context *smu)
+{
+	struct amdgpu_device *adev = smu->adev;
+	int i;
+
+	for (i = 0; i < 16; i++)
+		pci_write_config_dword(adev->pdev, i * 4,
+				       adev->pdev->saved_config_space[i]);
+	pci_restore_msi_state(adev->pdev);
+}
+
 static int smu_v13_0_6_mode2_reset(struct smu_context *smu)
 {
 	int ret = 0, index;
@@ -2213,6 +2224,8 @@
 
 	index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG,
 					       SMU_MSG_GfxDeviceDriverReset);
+	if (index < 0)
+		return index;
 
 	mutex_lock(&smu->message_lock);
 
@@ -2226,6 +2239,20 @@
 	/* Restore the config space saved during init */
 	amdgpu_device_load_pci_state(adev->pdev);
 
+	/* Certain platforms have switches which assign virtual BAR values to
+	 * devices. OS uses the virtual BAR values and device behind the switch
+	 * is assgined another BAR value. When device's config space registers
+	 * are queried, switch returns the virtual BAR values. When mode-2 reset
+	 * is performed, switch is unaware of it, and will continue to return
+	 * the same virtual values to the OS.This affects
+	 * pci_restore_config_space() API as it doesn't write the value saved if
+	 * the current value read from config space is the same as what is
+	 * saved. As a workaround, make sure the config space is restored
+	 * always.
+	 */
+	if (!(adev->flags & AMD_IS_APU))
+		smu_v13_0_6_restore_pci_config(smu);
+
 	dev_dbg(smu->adev->dev, "wait for reset ack\n");
 	do {
 		ret = smu_cmn_wait_for_response(smu);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
@@ -2061,6 +2061,8 @@
 	gpu_metrics->average_dclk1_frequency = metrics->AverageDclk1Frequency;
 
 	gpu_metrics->current_gfxclk = metrics->CurrClock[PPCLK_GFXCLK];
+	gpu_metrics->current_socclk = metrics->CurrClock[PPCLK_SOCCLK];
+	gpu_metrics->current_uclk = metrics->CurrClock[PPCLK_UCLK];
 	gpu_metrics->current_vclk0 = metrics->CurrClock[PPCLK_VCLK_0];
 	gpu_metrics->current_dclk0 = metrics->CurrClock[PPCLK_DCLK_0];
 	gpu_metrics->current_vclk1 = metrics->CurrClock[PPCLK_VCLK_1];
@@ -2320,7 +2322,7 @@
 		(struct smu_13_0_7_powerplay_table *)table_context->power_play_table;
 	PPTable_t *pptable = table_context->driver_pptable;
 	SkuTable_t *skutable = &pptable->SkuTable;
-	uint32_t power_limit, od_percent_upper, od_percent_lower;
+	uint32_t power_limit, od_percent_upper = 0, od_percent_lower = 0;
 	uint32_t msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
 
 	if (smu_v13_0_get_current_power_limit(smu, &power_limit))
@@ -2333,12 +2335,16 @@
 	if (default_power_limit)
 		*default_power_limit = power_limit;
 
-	if (smu->od_enabled)
-		od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]);
-	else
-		od_percent_upper = 0;
-
-	od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]);
+	if (powerplay_table) {
+		if (smu->od_enabled &&
+				(smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_PPT_BIT))) {
+			od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]);
+			od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]);
+		} else if (smu_v13_0_7_is_od_feature_supported(smu, PP_OD_FEATURE_PPT_BIT)) {
+			od_percent_upper = 0;
+			od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[SMU_13_0_7_ODSETTING_POWERPERCENTAGE]);
+		}
+	}
 
 	dev_dbg(smu->adev->dev, "od percent upper:%d, od percent lower:%d (default power: %d)\n",
 					od_percent_upper, od_percent_lower, power_limit);
@@ -2446,6 +2452,8 @@
 	}
 
 	if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
+		if (size != 8)
+			return -EINVAL;
 
 		ret = smu_cmn_update_table(smu,
 				       SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
@@ -2474,6 +2482,8 @@
 			activity_monitor->Fclk_MinActiveFreq = input[6];
 			activity_monitor->Fclk_BoosterFreq = input[7];
 			break;
+		default:
+			return -EINVAL;
 		}
 
 		ret = smu_cmn_update_table(smu,
@@ -2657,6 +2667,7 @@
 	.is_asic_wbrf_supported = smu_v13_0_7_wbrf_support_check,
 	.enable_uclk_shadow = smu_v13_0_enable_uclk_shadow,
 	.set_wbrf_exclusion_ranges = smu_v13_0_set_wbrf_exclusion_ranges,
+	.interrupt_work = smu_v13_0_interrupt_work,
 };
 
 void smu_v13_0_7_set_ppt_funcs(struct smu_context *smu)
@@ -2670,4 +2681,5 @@
 	smu->workload_map = smu_v13_0_7_workload_map;
 	smu->smc_driver_if_version = SMU13_0_7_DRIVER_IF_VERSION;
 	smu_v13_0_set_smu_mailbox_registers(smu);
+	smu->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c
@@ -861,31 +861,9 @@
 	int ret = 0;
 
 	if (!yellow_carp_clk_dpm_is_enabled(smu, clk_type)) {
-		switch (clk_type) {
-		case SMU_MCLK:
-		case SMU_UCLK:
-			clock_limit = smu->smu_table.boot_values.uclk;
-			break;
-		case SMU_FCLK:
-			clock_limit = smu->smu_table.boot_values.fclk;
-			break;
-		case SMU_GFXCLK:
-		case SMU_SCLK:
-			clock_limit = smu->smu_table.boot_values.gfxclk;
-			break;
-		case SMU_SOCCLK:
-			clock_limit = smu->smu_table.boot_values.socclk;
-			break;
-		case SMU_VCLK:
-			clock_limit = smu->smu_table.boot_values.vclk;
-			break;
-		case SMU_DCLK:
-			clock_limit = smu->smu_table.boot_values.dclk;
-			break;
-		default:
-			clock_limit = 0;
-			break;
-		}
+		ret = smu_v13_0_get_boot_freq_by_index(smu, clk_type, &clock_limit);
+		if (ret)
+			return ret;
 
 		/* clock in Mhz unit */
 		if (min)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c
@@ -836,7 +836,7 @@
 static int smu_v14_0_0_print_clk_levels(struct smu_context *smu,
 					enum smu_clk_type clk_type, char *buf)
 {
-	int i, size = 0, ret = 0;
+	int i, idx, ret = 0, size = 0;
 	uint32_t cur_value = 0, value = 0, count = 0;
 	uint32_t min, max;
 
@@ -870,7 +870,8 @@
 			break;
 
 		for (i = 0; i < count; i++) {
-			ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, i, &value);
+			idx = (clk_type == SMU_MCLK) ? (count - i - 1) : i;
+			ret = smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, idx, &value);
 			if (ret)
 				break;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -5,6 +5,7 @@
  *
  */
 #include <linux/clk.h>
+#include <linux/of.h>
 #include <linux/pm_runtime.h>
 #include <linux/spinlock.h>
 
@@ -610,12 +611,34 @@
 	return NULL;
 }
 
+static int komeda_attach_bridge(struct device *dev,
+				struct komeda_pipeline *pipe,
+				struct drm_encoder *encoder)
+{
+	struct drm_bridge *bridge;
+	int err;
+
+	bridge = devm_drm_of_get_bridge(dev, pipe->of_node,
+					KOMEDA_OF_PORT_OUTPUT, 0);
+	if (IS_ERR(bridge))
+		return dev_err_probe(dev, PTR_ERR(bridge), "remote bridge not found for pipe: %s\n",
+				     of_node_full_name(pipe->of_node));
+
+	err = drm_bridge_attach(encoder, bridge, NULL, 0);
+	if (err)
+		dev_err(dev, "bridge_attach() failed for pipe: %s\n",
+			of_node_full_name(pipe->of_node));
+
+	return err;
+}
+
 static int komeda_crtc_add(struct komeda_kms_dev *kms,
 			   struct komeda_crtc *kcrtc)
 {
 	struct drm_crtc *crtc = &kcrtc->base;
 	struct drm_device *base = &kms->base;
-	struct drm_bridge *bridge;
+	struct komeda_pipeline *pipe = kcrtc->master;
+	struct drm_encoder *encoder = &kcrtc->encoder;
 	int err;
 
 	err = drm_crtc_init_with_planes(base, crtc,
@@ -626,27 +649,25 @@
 
 	drm_crtc_helper_add(crtc, &komeda_crtc_helper_funcs);
 
-	crtc->port = kcrtc->master->of_output_port;
+	crtc->port = pipe->of_output_port;
 
 	/* Construct an encoder for each pipeline and attach it to the remote
 	 * bridge
 	 */
 	kcrtc->encoder.possible_crtcs = drm_crtc_mask(crtc);
-	err = drm_simple_encoder_init(base, &kcrtc->encoder,
-				      DRM_MODE_ENCODER_TMDS);
+	err = drm_simple_encoder_init(base, encoder, DRM_MODE_ENCODER_TMDS);
 	if (err)
 		return err;
 
-	bridge = devm_drm_of_get_bridge(base->dev, kcrtc->master->of_node,
-					KOMEDA_OF_PORT_OUTPUT, 0);
-	if (IS_ERR(bridge))
-		return PTR_ERR(bridge);
-
-	err = drm_bridge_attach(&kcrtc->encoder, bridge, NULL, 0);
+	if (pipe->of_output_links[0]) {
+		err = komeda_attach_bridge(base->dev, pipe, encoder);
+		if (err)
+			return err;
+	}
 
 	drm_crtc_enable_color_mgmt(crtc, 0, true, KOMEDA_COLOR_LUT_SIZE);
 
-	return err;
+	return 0;
 }
 
 int komeda_kms_add_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
@@ -160,6 +160,7 @@
 	struct drm_plane *plane;
 	struct list_head zorder_list;
 	int order = 0, err;
+	u32 slave_zpos = 0;
 
 	DRM_DEBUG_ATOMIC("[CRTC:%d:%s] calculating normalized zpos values\n",
 			 crtc->base.id, crtc->name);
@@ -199,10 +200,13 @@
 				 plane_st->zpos, plane_st->normalized_zpos);
 
 		/* calculate max slave zorder */
-		if (has_bit(drm_plane_index(plane), kcrtc->slave_planes))
+		if (has_bit(drm_plane_index(plane), kcrtc->slave_planes)) {
+			slave_zpos = plane_st->normalized_zpos;
+			if (to_kplane_st(plane_st)->layer_split)
+				slave_zpos++;
 			kcrtc_st->max_slave_zorder =
-				max(plane_st->normalized_zpos,
-				    kcrtc_st->max_slave_zorder);
+				max(slave_zpos, kcrtc_st->max_slave_zorder);
+		}
 	}
 
 	crtc_st->zpos_changed = true;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -259,7 +259,7 @@
 	u32 avail_scalers;
 
 	pipe_st = komeda_pipeline_get_state(c->pipeline, state);
-	if (!pipe_st)
+	if (IS_ERR_OR_NULL(pipe_st))
 		return NULL;
 
 	avail_scalers = (pipe_st->active_comps & KOMEDA_PIPELINE_SCALERS) ^
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
@@ -160,6 +160,10 @@
 	formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl,
 					       kwb_conn->wb_layer->layer_type,
 					       &n_formats);
+	if (!formats) {
+		kfree(kwb_conn);
+		return -ENOMEM;
+	}
 
 	err = drm_writeback_connector_init(&kms->base, wb_conn,
 					   &komeda_wb_connector_funcs,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/arm/malidp_mw.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/arm/malidp_mw.c
@@ -72,7 +72,10 @@
 		__drm_atomic_helper_connector_destroy_state(connector->state);
 
 	kfree(connector->state);
-	__drm_atomic_helper_connector_reset(connector, &mw_state->base);
+	connector->state = NULL;
+
+	if (mw_state)
+		__drm_atomic_helper_connector_reset(connector, &mw_state->base);
 }
 
 static enum drm_connector_status
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/ast/ast_dp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/ast/ast_dp.c
@@ -158,7 +158,14 @@
 			       ASTDP_HOST_EDID_READ_DONE);
 }
 
+bool ast_dp_power_is_on(struct ast_device *ast)
+{
+	u8 vgacre3;
+
+	vgacre3 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xe3);
 
+	return !(vgacre3 & AST_DP_PHY_SLEEP);
+}
 
 void ast_dp_power_on_off(struct drm_device *dev, bool on)
 {
@@ -180,6 +187,7 @@
 {
 	struct ast_device *ast = to_ast_device(dev);
 	u8 video_on_off = on;
+	u32 i = 0;
 
 	// Video On/Off
 	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on);
@@ -192,6 +200,8 @@
 						ASTDP_MIRROR_VIDEO_ENABLE) != video_on_off) {
 			// wait 1 ms
 			mdelay(1);
+			if (++i > 200)
+				break;
 		}
 	}
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/ast/ast_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/ast/ast_drv.c
@@ -390,6 +390,11 @@
 
 static int ast_drm_thaw(struct drm_device *dev)
 {
+	struct ast_device *ast = to_ast_device(dev);
+
+	ast_enable_vga(ast->ioregs);
+	ast_open_key(ast->ioregs);
+	ast_enable_mmio(dev->dev, ast->ioregs);
 	ast_post_gpu(dev);
 
 	return drm_mode_config_helper_resume(dev);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/ast/ast_drv.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/ast/ast_drv.h
@@ -505,6 +505,7 @@
 bool ast_astdp_is_connected(struct ast_device *ast);
 int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata);
 void ast_dp_launch(struct drm_device *dev);
+bool ast_dp_power_is_on(struct ast_device *ast);
 void ast_dp_power_on_off(struct drm_device *dev, bool no);
 void ast_dp_set_on_off(struct drm_device *dev, bool no);
 void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mode);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/ast/ast_mode.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/ast/ast_mode.c
@@ -28,6 +28,7 @@
  * Authors: Dave Airlie <airlied@redhat.com>
  */
 
+#include <linux/delay.h>
 #include <linux/export.h>
 #include <linux/pci.h>
 
@@ -44,7 +45,6 @@
 #include <drm/drm_gem_shmem_helper.h>
 #include <drm/drm_managed.h>
 #include <drm/drm_probe_helper.h>
-#include <drm/drm_simple_kms_helper.h>
 
 #include "ast_drv.h"
 #include "ast_tables.h"
@@ -302,7 +302,7 @@
 
 	/* Set SEQ; except Screen Disable field */
 	ast_set_index_reg(ast, AST_IO_VGASRI, 0x00, 0x03);
-	ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, stdtable->seq[0]);
+	ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0x20, stdtable->seq[0]);
 	for (i = 1; i < 4; i++) {
 		jreg = stdtable->seq[i];
 		ast_set_index_reg(ast, AST_IO_VGASRI, (i + 1), jreg);
@@ -648,12 +648,12 @@
 	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
 	struct drm_framebuffer *old_fb = old_plane_state->fb;
 	struct ast_plane *ast_plane = to_ast_plane(plane);
+	struct drm_crtc *crtc = plane_state->crtc;
+	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
 	struct drm_rect damage;
 	struct drm_atomic_helper_damage_iter iter;
 
-	if (!old_fb || (fb->format != old_fb->format)) {
-		struct drm_crtc *crtc = plane_state->crtc;
-		struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
+	if (!old_fb || (fb->format != old_fb->format) || crtc_state->mode_changed) {
 		struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
 		struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;
 
@@ -689,15 +689,15 @@
 	 * Therefore only reprogram the address after enabling the plane.
 	 */
 	ast_set_start_address_crt1(ast, (u32)ast_plane->offset);
-	ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x00);
 }
 
 static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane,
 						    struct drm_atomic_state *state)
 {
-	struct ast_device *ast = to_ast_device(plane->dev);
-
-	ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x20);
+	/*
+	 * Keep this empty function to avoid calling
+	 * atomic_update when disabling the plane.
+	 */
 }
 
 static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = {
@@ -1001,62 +1001,6 @@
  * CRTC
  */
 
-static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
-{
-	struct ast_device *ast = to_ast_device(crtc->dev);
-	u8 ch = AST_DPMS_VSYNC_OFF | AST_DPMS_HSYNC_OFF;
-	struct ast_crtc_state *ast_state;
-	const struct drm_format_info *format;
-	struct ast_vbios_mode_info *vbios_mode_info;
-
-	/* TODO: Maybe control display signal generation with
-	 *       Sync Enable (bit CR17.7).
-	 */
-	switch (mode) {
-	case DRM_MODE_DPMS_ON:
-		ast_set_index_reg_mask(ast, AST_IO_VGASRI,  0x01, 0xdf, 0);
-		ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, 0);
-		if (ast->tx_chip_types & AST_TX_DP501_BIT)
-			ast_set_dp501_video_output(crtc->dev, 1);
-
-		if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
-			ast_dp_power_on_off(crtc->dev, AST_DP_POWER_ON);
-			ast_wait_for_vretrace(ast);
-			ast_dp_set_on_off(crtc->dev, 1);
-		}
-
-		ast_state = to_ast_crtc_state(crtc->state);
-		format = ast_state->format;
-
-		if (format) {
-			vbios_mode_info = &ast_state->vbios_mode_info;
-
-			ast_set_color_reg(ast, format);
-			ast_set_vbios_color_reg(ast, format, vbios_mode_info);
-			if (crtc->state->gamma_lut)
-				ast_crtc_set_gamma(ast, format, crtc->state->gamma_lut->data);
-			else
-				ast_crtc_set_gamma_linear(ast, format);
-		}
-		break;
-	case DRM_MODE_DPMS_STANDBY:
-	case DRM_MODE_DPMS_SUSPEND:
-	case DRM_MODE_DPMS_OFF:
-		ch = mode;
-		if (ast->tx_chip_types & AST_TX_DP501_BIT)
-			ast_set_dp501_video_output(crtc->dev, 0);
-
-		if (ast->tx_chip_types & AST_TX_ASTDP_BIT) {
-			ast_dp_set_on_off(crtc->dev, 0);
-			ast_dp_power_on_off(crtc->dev, AST_DP_POWER_OFF);
-		}
-
-		ast_set_index_reg_mask(ast, AST_IO_VGASRI,  0x01, 0xdf, 0x20);
-		ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, ch);
-		break;
-	}
-}
-
 static enum drm_mode_status
 ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
 {
@@ -1129,6 +1073,33 @@
 	return status;
 }
 
+static void ast_crtc_helper_mode_set_nofb(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct ast_device *ast = to_ast_device(dev);
+	struct drm_crtc_state *crtc_state = crtc->state;
+	struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
+	struct ast_vbios_mode_info *vbios_mode_info =
+		&ast_crtc_state->vbios_mode_info;
+	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
+
+	/*
+	 * Ensure that no scanout takes place before reprogramming mode
+	 * and format registers.
+	 *
+	 * TODO: Get vblank interrupts working and remove this line.
+	 */
+	ast_wait_for_vretrace(ast);
+
+	ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info);
+	ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06);
+	ast_set_std_reg(ast, adjusted_mode, vbios_mode_info);
+	ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info);
+	ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info);
+	ast_set_crtthd_reg(ast);
+	ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info);
+}
+
 static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
 					struct drm_atomic_state *state)
 {
@@ -1188,7 +1159,6 @@
 	struct drm_device *dev = crtc->dev;
 	struct ast_device *ast = to_ast_device(dev);
 	struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
-	struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;
 
 	/*
 	 * The gamma LUT has to be reloaded after changing the primary
@@ -1202,40 +1172,27 @@
 		else
 			ast_crtc_set_gamma_linear(ast, ast_crtc_state->format);
 	}
-
-	//Set Aspeed Display-Port
-	if (ast->tx_chip_types & AST_TX_ASTDP_BIT)
-		ast_dp_set_mode(crtc, vbios_mode_info);
 }
 
 static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state)
 {
-	struct drm_device *dev = crtc->dev;
-	struct ast_device *ast = to_ast_device(dev);
-	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
-	struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
-	struct ast_vbios_mode_info *vbios_mode_info =
-		&ast_crtc_state->vbios_mode_info;
-	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
-
-	ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info);
-	ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06);
-	ast_set_std_reg(ast, adjusted_mode, vbios_mode_info);
-	ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info);
-	ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info);
-	ast_set_crtthd_reg(ast);
-	ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info);
+	struct ast_device *ast = to_ast_device(crtc->dev);
 
-	ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, 0x00);
+	ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0x00);
 }
 
 static void ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state)
 {
 	struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
-	struct drm_device *dev = crtc->dev;
-	struct ast_device *ast = to_ast_device(dev);
+	struct ast_device *ast = to_ast_device(crtc->dev);
+	u8 vgacrb6;
 
-	ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+	ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, AST_IO_VGASR1_SD);
+
+	vgacrb6 = AST_IO_VGACRB6_VSYNC_OFF |
+		  AST_IO_VGACRB6_HSYNC_OFF;
+	ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, vgacrb6);
 
 	/*
 	 * HW cursors require the underlying primary plane and CRTC to
@@ -1248,16 +1205,11 @@
 	 * simple pageflips on the planes.
 	 */
 	drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false);
-
-	/*
-	 * Ensure that no scanout takes place before reprogramming mode
-	 * and format registers.
-	 */
-	ast_wait_for_vretrace(ast);
 }
 
 static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
 	.mode_valid = ast_crtc_helper_mode_valid,
+	.mode_set_nofb = ast_crtc_helper_mode_set_nofb,
 	.atomic_check = ast_crtc_helper_atomic_check,
 	.atomic_flush = ast_crtc_helper_atomic_flush,
 	.atomic_enable = ast_crtc_helper_atomic_enable,
@@ -1340,6 +1292,14 @@
 }
 
 /*
+ * VGA Encoder
+ */
+
+static const struct drm_encoder_funcs ast_vga_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+/*
  * VGA Connector
  */
 
@@ -1429,7 +1389,8 @@
 	struct drm_connector *connector = &ast_vga_connector->base;
 	int ret;
 
-	ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC);
+	ret = drm_encoder_init(dev, encoder, &ast_vga_encoder_funcs,
+			       DRM_MODE_ENCODER_DAC, NULL);
 	if (ret)
 		return ret;
 	encoder->possible_crtcs = drm_crtc_mask(crtc);
@@ -1446,6 +1407,14 @@
 }
 
 /*
+ * SIL164 Encoder
+ */
+
+static const struct drm_encoder_funcs ast_sil164_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+/*
  * SIL164 Connector
  */
 
@@ -1535,7 +1504,8 @@
 	struct drm_connector *connector = &ast_sil164_connector->base;
 	int ret;
 
-	ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
+	ret = drm_encoder_init(dev, encoder, &ast_sil164_encoder_funcs,
+			       DRM_MODE_ENCODER_TMDS, NULL);
 	if (ret)
 		return ret;
 	encoder->possible_crtcs = drm_crtc_mask(crtc);
@@ -1552,6 +1522,35 @@
 }
 
 /*
+ * DP501 Encoder
+ */
+
+static const struct drm_encoder_funcs ast_dp501_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+static void ast_dp501_encoder_helper_atomic_enable(struct drm_encoder *encoder,
+						   struct drm_atomic_state *state)
+{
+	struct drm_device *dev = encoder->dev;
+
+	ast_set_dp501_video_output(dev, 1);
+}
+
+static void ast_dp501_encoder_helper_atomic_disable(struct drm_encoder *encoder,
+						    struct drm_atomic_state *state)
+{
+	struct drm_device *dev = encoder->dev;
+
+	ast_set_dp501_video_output(dev, 0);
+}
+
+static const struct drm_encoder_helper_funcs ast_dp501_encoder_helper_funcs = {
+	.atomic_enable = ast_dp501_encoder_helper_atomic_enable,
+	.atomic_disable = ast_dp501_encoder_helper_atomic_disable,
+};
+
+/*
  * DP501 Connector
  */
 
@@ -1633,9 +1632,12 @@
 	struct drm_connector *connector = &ast->output.dp501.connector;
 	int ret;
 
-	ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
+	ret = drm_encoder_init(dev, encoder, &ast_dp501_encoder_funcs,
+			       DRM_MODE_ENCODER_TMDS, NULL);
 	if (ret)
 		return ret;
+	drm_encoder_helper_add(encoder, &ast_dp501_encoder_helper_funcs);
+
 	encoder->possible_crtcs = drm_crtc_mask(crtc);
 
 	ret = ast_dp501_connector_init(dev, connector);
@@ -1650,6 +1652,51 @@
 }
 
 /*
+ * ASPEED Display-Port Encoder
+ */
+
+static const struct drm_encoder_funcs ast_astdp_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+static void ast_astdp_encoder_helper_atomic_mode_set(struct drm_encoder *encoder,
+						     struct drm_crtc_state *crtc_state,
+						     struct drm_connector_state *conn_state)
+{
+	struct drm_crtc *crtc = crtc_state->crtc;
+	struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state);
+	struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info;
+
+	ast_dp_set_mode(crtc, vbios_mode_info);
+}
+
+static void ast_astdp_encoder_helper_atomic_enable(struct drm_encoder *encoder,
+						   struct drm_atomic_state *state)
+{
+	struct drm_device *dev = encoder->dev;
+	struct ast_device *ast = to_ast_device(dev);
+
+	ast_dp_power_on_off(dev, AST_DP_POWER_ON);
+	ast_wait_for_vretrace(ast);
+	ast_dp_set_on_off(dev, 1);
+}
+
+static void ast_astdp_encoder_helper_atomic_disable(struct drm_encoder *encoder,
+						    struct drm_atomic_state *state)
+{
+	struct drm_device *dev = encoder->dev;
+
+	ast_dp_set_on_off(dev, 0);
+	ast_dp_power_on_off(dev, AST_DP_POWER_OFF);
+}
+
+static const struct drm_encoder_helper_funcs ast_astdp_encoder_helper_funcs = {
+	.atomic_mode_set = ast_astdp_encoder_helper_atomic_mode_set,
+	.atomic_enable = ast_astdp_encoder_helper_atomic_enable,
+	.atomic_disable = ast_astdp_encoder_helper_atomic_disable,
+};
+
+/*
  * ASPEED Display-Port Connector
  */
 
@@ -1696,11 +1743,35 @@
 						 struct drm_modeset_acquire_ctx *ctx,
 						 bool force)
 {
+	struct drm_device *dev = connector->dev;
 	struct ast_device *ast = to_ast_device(connector->dev);
+	enum drm_connector_status status = connector_status_disconnected;
+	struct drm_connector_state *connector_state = connector->state;
+	bool is_active = false;
+
+	mutex_lock(&ast->modeset_lock);
+
+	if (connector_state && connector_state->crtc) {
+		struct drm_crtc_state *crtc_state = connector_state->crtc->state;
+
+		if (crtc_state && crtc_state->active)
+			is_active = true;
+	}
+
+	if (!is_active && !ast_dp_power_is_on(ast)) {
+		ast_dp_power_on_off(dev, true);
+		msleep(50);
+	}
 
 	if (ast_astdp_is_connected(ast))
-		return connector_status_connected;
-	return connector_status_disconnected;
+		status = connector_status_connected;
+
+	if (!is_active && status == connector_status_disconnected)
+		ast_dp_power_on_off(dev, false);
+
+	mutex_unlock(&ast->modeset_lock);
+
+	return status;
 }
 
 static const struct drm_connector_helper_funcs ast_astdp_connector_helper_funcs = {
@@ -1743,9 +1814,12 @@
 	struct drm_connector *connector = &ast->output.astdp.connector;
 	int ret;
 
-	ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_TMDS);
+	ret = drm_encoder_init(dev, encoder, &ast_astdp_encoder_funcs,
+			       DRM_MODE_ENCODER_TMDS, NULL);
 	if (ret)
 		return ret;
+	drm_encoder_helper_add(encoder, &ast_astdp_encoder_helper_funcs);
+
 	encoder->possible_crtcs = drm_crtc_mask(crtc);
 
 	ret = ast_astdp_connector_init(dev, connector);
@@ -1871,7 +1945,7 @@
 	 * the I/O-register lock. Released in atomic_flush().
 	 */
 	mutex_lock(&ast->modeset_lock);
-	drm_atomic_helper_commit_tail_rpm(state);
+	drm_atomic_helper_commit_tail(state);
 	mutex_unlock(&ast->modeset_lock);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/ast/ast_reg.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/ast/ast_reg.h
@@ -22,6 +22,7 @@
 #define AST_IO_VGAER_VGA_ENABLE		BIT(0)
 
 #define AST_IO_VGASRI			(0x44)
+#define AST_IO_VGASR1_SD		BIT(5)
 #define AST_IO_VGADRR			(0x47)
 #define AST_IO_VGADWR			(0x48)
 #define AST_IO_VGAPDR		        (0x49)
@@ -31,6 +32,8 @@
 #define AST_IO_VGACR80_PASSWORD		(0xa8)
 #define AST_IO_VGACRA1_VGAIO_DISABLED	BIT(1)
 #define AST_IO_VGACRA1_MMIO_ENABLED	BIT(2)
+#define AST_IO_VGACRB6_HSYNC_OFF	BIT(0)
+#define AST_IO_VGACRB6_VSYNC_OFF	BIT(1)
 #define AST_IO_VGACRCB_HWC_16BPP	BIT(0) /* set: ARGB4444, cleared: 2bpp palette */
 #define AST_IO_VGACRCB_HWC_ENABLED	BIT(1)
 
@@ -76,13 +79,6 @@
 #define ASTDP_HOST_EDID_READ_DONE_MASK	GENMASK(0, 0)
 
 /*
- * CRB8[b1]: Enable VSYNC off
- * CRB8[b0]: Enable HSYNC off
- */
-#define AST_DPMS_VSYNC_OFF		BIT(1)
-#define AST_DPMS_HSYNC_OFF		BIT(0)
-
-/*
  * CRDF[b4]: Mirror of AST_DP_VIDEO_ENABLE
  * Precondition:	A. ~AST_DP_PHY_SLEEP  &&
  *			B. DP_HPD &&
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
@@ -153,7 +153,16 @@
 			   ADV7511_AUDIO_CFG3_LEN_MASK, len);
 	regmap_update_bits(adv7511->regmap, ADV7511_REG_I2C_FREQ_ID_CFG,
 			   ADV7511_I2C_FREQ_ID_CFG_RATE_MASK, rate << 4);
-	regmap_write(adv7511->regmap, 0x73, 0x1);
+
+	/* send current Audio infoframe values while updating */
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE,
+			   BIT(5), BIT(5));
+
+	regmap_write(adv7511->regmap, ADV7511_REG_AUDIO_INFOFRAME(0), 0x1);
+
+	/* use Audio infoframe updated info */
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE,
+			   BIT(5), 0);
 
 	return 0;
 }
@@ -184,8 +193,9 @@
 	regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(0),
 				BIT(7) | BIT(6), BIT(7));
 	/* use Audio infoframe updated info */
-	regmap_update_bits(adv7511->regmap, ADV7511_REG_GC(1),
+	regmap_update_bits(adv7511->regmap, ADV7511_REG_INFOFRAME_UPDATE,
 				BIT(5), 0);
+
 	/* enable SPDIF receiver */
 	if (adv7511->audio_source == ADV7511_AUDIO_SOURCE_SPDIF)
 		regmap_update_bits(adv7511->regmap, ADV7511_REG_AUDIO_CONFIG,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
@@ -1211,8 +1211,10 @@
 		return ret;
 
 	ret = adv7511_init_regulators(adv7511);
-	if (ret)
-		return dev_err_probe(dev, ret, "failed to init regulators\n");
+	if (ret) {
+		dev_err_probe(dev, ret, "failed to init regulators\n");
+		goto err_of_node_put;
+	}
 
 	/*
 	 * The power down GPIO is optional. If present, toggle it from active to
@@ -1277,17 +1279,6 @@
 
 	INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work);
 
-	if (i2c->irq) {
-		init_waitqueue_head(&adv7511->wq);
-
-		ret = devm_request_threaded_irq(dev, i2c->irq, NULL,
-						adv7511_irq_handler,
-						IRQF_ONESHOT, dev_name(dev),
-						adv7511);
-		if (ret)
-			goto err_unregister_cec;
-	}
-
 	adv7511_power_off(adv7511);
 
 	i2c_set_clientdata(i2c, adv7511);
@@ -1311,6 +1302,17 @@
 
 	adv7511_audio_init(dev, adv7511);
 
+	if (i2c->irq) {
+		init_waitqueue_head(&adv7511->wq);
+
+		ret = devm_request_threaded_irq(dev, i2c->irq, NULL,
+						adv7511_irq_handler,
+						IRQF_ONESHOT, dev_name(dev),
+						adv7511);
+		if (ret)
+			goto err_unregister_audio;
+	}
+
 	if (adv7511->info->has_dsi) {
 		ret = adv7533_attach_dsi(adv7511);
 		if (ret)
@@ -1332,6 +1334,8 @@
 	i2c_unregister_device(adv7511->i2c_edid);
 uninit_regulators:
 	adv7511_uninit_regulators(adv7511);
+err_of_node_put:
+	of_node_put(adv7511->host_node);
 
 	return ret;
 }
@@ -1340,6 +1344,8 @@
 {
 	struct adv7511 *adv7511 = i2c_get_clientdata(i2c);
 
+	of_node_put(adv7511->host_node);
+
 	adv7511_uninit_regulators(adv7511);
 
 	drm_bridge_remove(&adv7511->bridge);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/adv7511/adv7533.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/adv7511/adv7533.c
@@ -172,7 +172,7 @@
 
 	of_property_read_u32(np, "adi,dsi-lanes", &num_lanes);
 
-	if (num_lanes < 1 || num_lanes > 4)
+	if (num_lanes < 2 || num_lanes > 4)
 		return -EINVAL;
 
 	adv->num_dsi_lanes = num_lanes;
@@ -181,8 +181,6 @@
 	if (!adv->host_node)
 		return -ENODEV;
 
-	of_node_put(adv->host_node);
-
 	adv->use_timing_gen = !of_property_read_bool(np,
 						"adi,disable-timing-generator");
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -1027,7 +1027,6 @@
 	u32 status_reg;
 	u8 *buffer = msg->buffer;
 	unsigned int i;
-	int num_transferred = 0;
 	int ret;
 
 	/* Buffer size of AUX CH is 16 bytes */
@@ -1079,7 +1078,6 @@
 			reg = buffer[i];
 			writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
 			       4 * i);
-			num_transferred++;
 		}
 	}
 
@@ -1127,7 +1125,6 @@
 			reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
 				    4 * i);
 			buffer[i] = (unsigned char)reg;
-			num_transferred++;
 		}
 	}
 
@@ -1144,7 +1141,7 @@
 		 (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ)
 		msg->reply = DP_AUX_NATIVE_REPLY_ACK;
 
-	return num_transferred > 0 ? num_transferred : -EBUSY;
+	return msg->size;
 
 aux_error:
 	/* if aux err happen, reset aux */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/analogix/anx7625.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/analogix/anx7625.c
@@ -1255,10 +1255,10 @@
 	usleep_range(11000, 12000);
 
 	/* Power on pin enable */
-	gpiod_set_value(ctx->pdata.gpio_p_on, 1);
+	gpiod_set_value_cansleep(ctx->pdata.gpio_p_on, 1);
 	usleep_range(10000, 11000);
 	/* Power reset pin enable */
-	gpiod_set_value(ctx->pdata.gpio_reset, 1);
+	gpiod_set_value_cansleep(ctx->pdata.gpio_reset, 1);
 	usleep_range(10000, 11000);
 
 	DRM_DEV_DEBUG_DRIVER(dev, "power on !\n");
@@ -1278,9 +1278,9 @@
 		return;
 	}
 
-	gpiod_set_value(ctx->pdata.gpio_reset, 0);
+	gpiod_set_value_cansleep(ctx->pdata.gpio_reset, 0);
 	usleep_range(1000, 1100);
-	gpiod_set_value(ctx->pdata.gpio_p_on, 0);
+	gpiod_set_value_cansleep(ctx->pdata.gpio_p_on, 0);
 	usleep_range(1000, 1100);
 
 	ret = regulator_bulk_disable(ARRAY_SIZE(ctx->pdata.supplies),
@@ -1826,9 +1826,6 @@
 
 	DRM_DEV_DEBUG_DRIVER(dev, "sink detect\n");
 
-	if (ctx->pdata.panel_bridge)
-		return connector_status_connected;
-
 	return ctx->hpd_status ? connector_status_connected :
 				     connector_status_disconnected;
 }
@@ -2014,8 +2011,10 @@
 		memset(buf, 0, len);
 	} else {
 		dev_dbg(dev, "audio copy eld\n");
+		mutex_lock(&ctx->connector->eld_mutex);
 		memcpy(buf, ctx->connector->eld,
 		       min(sizeof(ctx->connector->eld), len));
+		mutex_unlock(&ctx->connector->eld_mutex);
 	}
 
 	return 0;
@@ -2076,10 +2075,8 @@
 	};
 
 	host = of_find_mipi_dsi_host_by_node(ctx->pdata.mipi_host_node);
-	if (!host) {
-		DRM_DEV_ERROR(dev, "fail to find dsi host.\n");
-		return -EPROBE_DEFER;
-	}
+	if (!host)
+		return dev_err_probe(dev, -EPROBE_DEFER, "fail to find dsi host.\n");
 
 	dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
 	if (IS_ERR(dsi)) {
@@ -2227,6 +2224,9 @@
 
 	ctx->bridge_attached = 1;
 
+	if (ctx->pdata.panel_bridge->type == DRM_MODE_CONNECTOR_DisplayPort)
+		pm_runtime_get_sync(dev);
+
 	return 0;
 }
 
@@ -2235,6 +2235,9 @@
 	struct anx7625_data *ctx = bridge_to_anx7625(bridge);
 
 	drm_dp_aux_unregister(&ctx->aux);
+
+	if (ctx->pdata.panel_bridge->type == DRM_MODE_CONNECTOR_DisplayPort)
+		pm_runtime_put_sync(ctx->dev);
 }
 
 static enum drm_mode_status
@@ -2481,15 +2484,22 @@
 	mutex_unlock(&ctx->aux_lock);
 }
 
+static void
+anx7625_audio_update_connector_status(struct anx7625_data *ctx,
+				      enum drm_connector_status status);
+
 static enum drm_connector_status
 anx7625_bridge_detect(struct drm_bridge *bridge)
 {
 	struct anx7625_data *ctx = bridge_to_anx7625(bridge);
 	struct device *dev = ctx->dev;
+	enum drm_connector_status status;
 
 	DRM_DEV_DEBUG_DRIVER(dev, "drm bridge detect\n");
 
-	return anx7625_sink_detect(ctx);
+	status = anx7625_sink_detect(ctx);
+	anx7625_audio_update_connector_status(ctx, status);
+	return status;
 }
 
 static struct edid *anx7625_bridge_get_edid(struct drm_bridge *bridge,
@@ -2568,6 +2578,8 @@
 	mutex_lock(&ctx->lock);
 
 	anx7625_stop_dp_work(ctx);
+	if (!ctx->pdata.panel_bridge)
+		anx7625_remove_edid(ctx);
 	anx7625_power_standby(ctx);
 
 	mutex_unlock(&ctx->lock);
@@ -2617,7 +2629,7 @@
 	platform->bridge.of_node = dev->of_node;
 	if (!anx7625_of_panel_on_aux_bus(dev))
 		platform->bridge.ops |= DRM_BRIDGE_OP_EDID;
-	if (!platform->pdata.panel_bridge)
+	if (platform->pdata.panel_bridge->type == DRM_MODE_CONNECTOR_DisplayPort)
 		platform->bridge.ops |= DRM_BRIDGE_OP_HPD |
 					DRM_BRIDGE_OP_DETECT;
 	platform->bridge.type = platform->pdata.panel_bridge ?
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/aux-bridge.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/aux-bridge.c
@@ -58,9 +58,10 @@
 	adev->id = ret;
 	adev->name = "aux_bridge";
 	adev->dev.parent = parent;
-	adev->dev.of_node = of_node_get(parent->of_node);
 	adev->dev.release = drm_aux_bridge_release;
 
+	device_set_of_node_from_dev(&adev->dev, parent);
+
 	ret = auxiliary_device_init(adev);
 	if (ret) {
 		ida_free(&drm_aux_bridge_ida, adev->id);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c
@@ -2057,6 +2057,9 @@
 	mhdp_state = to_cdns_mhdp_bridge_state(new_state);
 
 	mhdp_state->current_mode = drm_mode_duplicate(bridge->dev, mode);
+	if (!mhdp_state->current_mode)
+		return;
+
 	drm_mode_set_name(mhdp_state->current_mode);
 
 	dev_dbg(mhdp->dev, "%s: Enabling mode %s\n", __func__, mode->name);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/chipone-icn6211.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/chipone-icn6211.c
@@ -563,10 +563,8 @@
 
 	host = of_find_mipi_dsi_host_by_node(host_node);
 	of_node_put(host_node);
-	if (!host) {
-		dev_err(dev, "failed to find dsi host\n");
-		return -EPROBE_DEFER;
-	}
+	if (!host)
+		return dev_err_probe(dev, -EPROBE_DEFER, "failed to find dsi host\n");
 
 	dsi = mipi_dsi_device_register_full(host, &info);
 	if (IS_ERR(dsi)) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/ite-it6505.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/ite-it6505.c
@@ -295,11 +295,11 @@
 #define MAX_LANE_COUNT 4
 #define MAX_LINK_RATE HBR
 #define AUTO_TRAIN_RETRY 3
-#define MAX_HDCP_DOWN_STREAM_COUNT 10
+#define MAX_HDCP_DOWN_STREAM_COUNT 127
 #define MAX_CR_LEVEL 0x03
 #define MAX_EQ_LEVEL 0x03
 #define AUX_WAIT_TIMEOUT_MS 15
-#define AUX_FIFO_MAX_SIZE 32
+#define AUX_FIFO_MAX_SIZE 16
 #define PIXEL_CLK_DELAY 1
 #define PIXEL_CLK_INVERSE 0
 #define ADJUST_PHASE_THRESHOLD 80000
@@ -1306,9 +1306,15 @@
 	it6505_link_reset_step_train(it6505);
 	it6505_set_bits(it6505, REG_DATA_MUTE_CTRL, EN_VID_MUTE, EN_VID_MUTE);
 	it6505_set_bits(it6505, REG_INFOFRAME_CTRL, EN_VID_CTRL_PKT, 0x00);
-	it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, VIDEO_RESET);
+
+	it6505_set_bits(it6505, REG_VID_BUS_CTRL1, TX_FIFO_RESET, TX_FIFO_RESET);
+	it6505_set_bits(it6505, REG_VID_BUS_CTRL1, TX_FIFO_RESET, 0x00);
+
 	it6505_set_bits(it6505, REG_501_FIFO_CTRL, RST_501_FIFO, RST_501_FIFO);
 	it6505_set_bits(it6505, REG_501_FIFO_CTRL, RST_501_FIFO, 0x00);
+
+	it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, VIDEO_RESET);
+	usleep_range(1000, 2000);
 	it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, 0x00);
 }
 
@@ -2014,7 +2020,7 @@
 {
 	struct device *dev = it6505->dev;
 	u8 av[5][4], bv[5][4];
-	int i, err;
+	int i, err, retry;
 
 	i = it6505_setup_sha1_input(it6505, it6505->sha1_input);
 	if (i <= 0) {
@@ -2023,22 +2029,29 @@
 	}
 
 	it6505_sha1_digest(it6505, it6505->sha1_input, i, (u8 *)av);
+	/*1B-05 V' must retry 3 times */
+	for (retry = 0; retry < 3; retry++) {
+		err = it6505_get_dpcd(it6505, DP_AUX_HDCP_V_PRIME(0), (u8 *)bv,
+				      sizeof(bv));
 
-	err = it6505_get_dpcd(it6505, DP_AUX_HDCP_V_PRIME(0), (u8 *)bv,
-			      sizeof(bv));
+		if (err < 0) {
+			dev_err(dev, "Read V' value Fail %d", retry);
+			continue;
+		}
 
-	if (err < 0) {
-		dev_err(dev, "Read V' value Fail");
-		return false;
-	}
+		for (i = 0; i < 5; i++)
+			if (bv[i][3] != av[i][0] || bv[i][2] != av[i][1] ||
+			    bv[i][1] != av[i][2] || bv[i][0] != av[i][3])
+				break;
 
-	for (i = 0; i < 5; i++)
-		if (bv[i][3] != av[i][0] || bv[i][2] != av[i][1] ||
-		    bv[i][1] != av[i][2] || bv[i][0] != av[i][3])
-			return false;
+		if (i == 5) {
+			DRM_DEV_DEBUG_DRIVER(dev, "V' all match!! %d", retry);
+			return true;
+		}
+	}
 
-	DRM_DEV_DEBUG_DRIVER(dev, "V' all match!!");
-	return true;
+	DRM_DEV_DEBUG_DRIVER(dev, "V' NOT match!! %d", retry);
+	return false;
 }
 
 static void it6505_hdcp_wait_ksv_list(struct work_struct *work)
@@ -2046,12 +2059,13 @@
 	struct it6505 *it6505 = container_of(work, struct it6505,
 					     hdcp_wait_ksv_list);
 	struct device *dev = it6505->dev;
-	unsigned int timeout = 5000;
-	u8 bstatus = 0;
+	u8 bstatus;
 	bool ksv_list_check;
+	/* 1B-04 wait ksv list for 5s */
+	unsigned long timeout = jiffies +
+				msecs_to_jiffies(5000) + 1;
 
-	timeout /= 20;
-	while (timeout > 0) {
+	for (;;) {
 		if (!it6505_get_sink_hpd_status(it6505))
 			return;
 
@@ -2060,27 +2074,23 @@
 		if (bstatus & DP_BSTATUS_READY)
 			break;
 
-		msleep(20);
-		timeout--;
-	}
+		if (time_after(jiffies, timeout)) {
+			DRM_DEV_DEBUG_DRIVER(dev, "KSV list wait timeout");
+			goto timeout;
+		}
 
-	if (timeout == 0) {
-		DRM_DEV_DEBUG_DRIVER(dev, "timeout and ksv list wait failed");
-		goto timeout;
+		msleep(20);
 	}
 
 	ksv_list_check = it6505_hdcp_part2_ksvlist_check(it6505);
 	DRM_DEV_DEBUG_DRIVER(dev, "ksv list ready, ksv list check %s",
 			     ksv_list_check ? "pass" : "fail");
-	if (ksv_list_check) {
-		it6505_set_bits(it6505, REG_HDCP_TRIGGER,
-				HDCP_TRIGGER_KSV_DONE, HDCP_TRIGGER_KSV_DONE);
+
+	if (ksv_list_check)
 		return;
-	}
+
 timeout:
-	it6505_set_bits(it6505, REG_HDCP_TRIGGER,
-			HDCP_TRIGGER_KSV_DONE | HDCP_TRIGGER_KSV_FAIL,
-			HDCP_TRIGGER_KSV_DONE | HDCP_TRIGGER_KSV_FAIL);
+	it6505_start_hdcp(it6505);
 }
 
 static void it6505_hdcp_work(struct work_struct *work)
@@ -2240,14 +2250,15 @@
 	ret = it6505_link_start_auto_train(it6505);
 	DRM_DEV_DEBUG_DRIVER(dev, "auto train %s, auto_train_retry: %d",
 			     ret ? "pass" : "failed", it6505->auto_train_retry);
-	it6505->auto_train_retry--;
 
 	if (ret) {
+		it6505->auto_train_retry = AUTO_TRAIN_RETRY;
 		it6505_link_train_ok(it6505);
-		return;
+	} else {
+		it6505->auto_train_retry--;
+		it6505_dump(it6505);
 	}
 
-	it6505_dump(it6505);
 }
 
 static void it6505_plugged_status_to_codec(struct it6505 *it6505)
@@ -2302,14 +2313,20 @@
 	DRM_DEV_DEBUG_DRIVER(dev, "dp_irq_vector = 0x%02x", dp_irq_vector);
 
 	if (dp_irq_vector & DP_CP_IRQ) {
-		it6505_set_bits(it6505, REG_HDCP_TRIGGER, HDCP_TRIGGER_CPIRQ,
-				HDCP_TRIGGER_CPIRQ);
-
 		bstatus = it6505_dpcd_read(it6505, DP_AUX_HDCP_BSTATUS);
 		if (bstatus < 0)
 			return bstatus;
 
 		DRM_DEV_DEBUG_DRIVER(dev, "Bstatus = 0x%02x", bstatus);
+
+		/*Check BSTATUS when recive CP_IRQ */
+		if (bstatus & DP_BSTATUS_R0_PRIME_READY &&
+		    it6505->hdcp_status == HDCP_AUTH_GOING)
+			it6505_set_bits(it6505, REG_HDCP_TRIGGER, HDCP_TRIGGER_CPIRQ,
+					HDCP_TRIGGER_CPIRQ);
+		else if (bstatus & (DP_BSTATUS_REAUTH_REQ | DP_BSTATUS_LINK_FAILURE) &&
+			 it6505->hdcp_status == HDCP_AUTH_DONE)
+			it6505_start_hdcp(it6505);
 	}
 
 	ret = drm_dp_dpcd_read_link_status(&it6505->aux, link_status);
@@ -2446,7 +2463,11 @@
 {
 	struct device *dev = it6505->dev;
 
-	DRM_DEV_DEBUG_DRIVER(dev, "HDCP event Interrupt");
+	DRM_DEV_DEBUG_DRIVER(dev, "HDCP repeater R0 event Interrupt");
+	/* 1B01 HDCP encription should start when R0 is ready*/
+	it6505_set_bits(it6505, REG_HDCP_TRIGGER,
+			HDCP_TRIGGER_KSV_DONE, HDCP_TRIGGER_KSV_DONE);
+
 	schedule_work(&it6505->hdcp_wait_ksv_list);
 }
 
@@ -2468,31 +2489,53 @@
 	schedule_work(&it6505->link_works);
 }
 
-static void it6505_irq_video_fifo_error(struct it6505 *it6505)
+static bool it6505_test_bit(unsigned int bit, const unsigned int *addr)
 {
-	struct device *dev = it6505->dev;
-
-	DRM_DEV_DEBUG_DRIVER(dev, "video fifo overflow interrupt");
-	it6505->auto_train_retry = AUTO_TRAIN_RETRY;
-	flush_work(&it6505->link_works);
-	it6505_stop_hdcp(it6505);
-	it6505_video_reset(it6505);
+	return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE));
 }
 
-static void it6505_irq_io_latch_fifo_overflow(struct it6505 *it6505)
+static void it6505_irq_video_handler(struct it6505 *it6505, const int *int_status)
 {
 	struct device *dev = it6505->dev;
+	int reg_0d, reg_int03;
 
-	DRM_DEV_DEBUG_DRIVER(dev, "IO latch fifo overflow interrupt");
-	it6505->auto_train_retry = AUTO_TRAIN_RETRY;
-	flush_work(&it6505->link_works);
-	it6505_stop_hdcp(it6505);
-	it6505_video_reset(it6505);
-}
+	/*
+	 * When video SCDT change with video not stable,
+	 * Or video FIFO error, need video reset
+	 */
 
-static bool it6505_test_bit(unsigned int bit, const unsigned int *addr)
-{
-	return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE));
+	if ((!it6505_get_video_status(it6505) &&
+	     (it6505_test_bit(INT_SCDT_CHANGE, (unsigned int *)int_status))) ||
+	    (it6505_test_bit(BIT_INT_IO_FIFO_OVERFLOW,
+			     (unsigned int *)int_status)) ||
+	    (it6505_test_bit(BIT_INT_VID_FIFO_ERROR,
+			     (unsigned int *)int_status))) {
+		it6505->auto_train_retry = AUTO_TRAIN_RETRY;
+		flush_work(&it6505->link_works);
+		it6505_stop_hdcp(it6505);
+		it6505_video_reset(it6505);
+
+		usleep_range(10000, 11000);
+
+		/*
+		 * Clear FIFO error IRQ to prevent fifo error -> reset loop
+		 * HW will trigger SCDT change IRQ again when video stable
+		 */
+
+		reg_int03 = it6505_read(it6505, INT_STATUS_03);
+		reg_0d = it6505_read(it6505, REG_SYSTEM_STS);
+
+		reg_int03 &= (BIT(INT_VID_FIFO_ERROR) | BIT(INT_IO_LATCH_FIFO_OVERFLOW));
+		it6505_write(it6505, INT_STATUS_03, reg_int03);
+
+		DRM_DEV_DEBUG_DRIVER(dev, "reg08 = 0x%02x", reg_int03);
+		DRM_DEV_DEBUG_DRIVER(dev, "reg0D = 0x%02x", reg_0d);
+
+		return;
+	}
+
+	if (it6505_test_bit(INT_SCDT_CHANGE, (unsigned int *)int_status))
+		it6505_irq_scdt(it6505);
 }
 
 static irqreturn_t it6505_int_threaded_handler(int unused, void *data)
@@ -2505,15 +2548,12 @@
 	} irq_vec[] = {
 		{ BIT_INT_HPD, it6505_irq_hpd },
 		{ BIT_INT_HPD_IRQ, it6505_irq_hpd_irq },
-		{ BIT_INT_SCDT, it6505_irq_scdt },
 		{ BIT_INT_HDCP_FAIL, it6505_irq_hdcp_fail },
 		{ BIT_INT_HDCP_DONE, it6505_irq_hdcp_done },
 		{ BIT_INT_AUX_CMD_FAIL, it6505_irq_aux_cmd_fail },
 		{ BIT_INT_HDCP_KSV_CHECK, it6505_irq_hdcp_ksv_check },
 		{ BIT_INT_AUDIO_FIFO_ERROR, it6505_irq_audio_fifo_error },
 		{ BIT_INT_LINK_TRAIN_FAIL, it6505_irq_link_train_fail },
-		{ BIT_INT_VID_FIFO_ERROR, it6505_irq_video_fifo_error },
-		{ BIT_INT_IO_FIFO_OVERFLOW, it6505_irq_io_latch_fifo_overflow },
 	};
 	int int_status[3], i;
 
@@ -2543,6 +2583,7 @@
 			if (it6505_test_bit(irq_vec[i].bit, (unsigned int *)int_status))
 				irq_vec[i].handler(it6505);
 		}
+		it6505_irq_video_handler(it6505, (unsigned int *)int_status);
 	}
 
 	pm_runtime_put_sync(dev);
@@ -2584,10 +2625,10 @@
 	/* time interval between OVDD and SYSRSTN at least be 10ms */
 	if (pdata->gpiod_reset) {
 		usleep_range(10000, 20000);
-		gpiod_set_value_cansleep(pdata->gpiod_reset, 0);
-		usleep_range(1000, 2000);
 		gpiod_set_value_cansleep(pdata->gpiod_reset, 1);
-		usleep_range(10000, 20000);
+		usleep_range(1000, 2000);
+		gpiod_set_value_cansleep(pdata->gpiod_reset, 0);
+		usleep_range(25000, 35000);
 	}
 
 	it6505->powered = true;
@@ -2613,7 +2654,7 @@
 	}
 
 	if (pdata->gpiod_reset)
-		gpiod_set_value_cansleep(pdata->gpiod_reset, 0);
+		gpiod_set_value_cansleep(pdata->gpiod_reset, 1);
 
 	if (pdata->pwr18) {
 		err = regulator_disable(pdata->pwr18);
@@ -3077,6 +3118,8 @@
 {
 	struct it6505 *it6505 = dev_get_drvdata(dev);
 
+	it6505_remove_edid(it6505);
+
 	return it6505_poweroff(it6505);
 }
 
@@ -3103,7 +3146,7 @@
 		return PTR_ERR(pdata->ovdd);
 	}
 
-	pdata->gpiod_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	pdata->gpiod_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
 	if (IS_ERR(pdata->gpiod_reset)) {
 		dev_err(dev, "gpiod_reset gpio not found");
 		return PTR_ERR(pdata->gpiod_reset);
@@ -3474,6 +3517,7 @@
 	{ .compatible = "ite,it6505" },
 	{ }
 };
+MODULE_DEVICE_TABLE(of, it6505_of_match);
 
 static struct i2c_driver it6505_i2c_driver = {
 	.driver = {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/ite-it66121.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/ite-it66121.c
@@ -1452,8 +1452,10 @@
 		dev_dbg(dev, "No connector present, passing empty EDID data");
 		memset(buf, 0, len);
 	} else {
+		mutex_lock(&ctx->connector->eld_mutex);
 		memcpy(buf, ctx->connector->eld,
 		       min(sizeof(ctx->connector->eld), len));
+		mutex_unlock(&ctx->connector->eld_mutex);
 	}
 	mutex_unlock(&ctx->lock);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/lontium-lt8912b.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/lontium-lt8912b.c
@@ -422,50 +422,31 @@
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
-static enum drm_mode_status
-lt8912_connector_mode_valid(struct drm_connector *connector,
-			    struct drm_display_mode *mode)
-{
-	if (mode->clock > 150000)
-		return MODE_CLOCK_HIGH;
-
-	if (mode->hdisplay > 1920)
-		return MODE_BAD_HVALUE;
-
-	if (mode->vdisplay > 1080)
-		return MODE_BAD_VVALUE;
-
-	return MODE_OK;
-}
-
 static int lt8912_connector_get_modes(struct drm_connector *connector)
 {
-	struct edid *edid;
-	int ret = -1;
-	int num = 0;
+	const struct drm_edid *drm_edid;
 	struct lt8912 *lt = connector_to_lt8912(connector);
 	u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
+	int ret, num;
 
-	edid = drm_bridge_get_edid(lt->hdmi_port, connector);
-	if (edid) {
-		drm_connector_update_edid_property(connector, edid);
-		num = drm_add_edid_modes(connector, edid);
-	} else {
-		return ret;
-	}
+	drm_edid = drm_bridge_edid_read(lt->hdmi_port, connector);
+	drm_edid_connector_update(connector, drm_edid);
+	if (!drm_edid)
+		return 0;
+
+	num = drm_edid_connector_add_modes(connector);
 
 	ret = drm_display_info_set_bus_formats(&connector->display_info,
 					       &bus_format, 1);
-	if (ret)
-		num = ret;
+	if (ret < 0)
+		num = 0;
 
-	kfree(edid);
+	drm_edid_free(drm_edid);
 	return num;
 }
 
 static const struct drm_connector_helper_funcs lt8912_connector_helper_funcs = {
 	.get_modes = lt8912_connector_get_modes,
-	.mode_valid = lt8912_connector_mode_valid,
 };
 
 static void lt8912_bridge_mode_set(struct drm_bridge *bridge,
@@ -496,10 +477,8 @@
 						 };
 
 	host = of_find_mipi_dsi_host_by_node(lt->host_node);
-	if (!host) {
-		dev_err(dev, "failed to find dsi host\n");
-		return -EPROBE_DEFER;
-	}
+	if (!host)
+		return dev_err_probe(dev, -EPROBE_DEFER, "failed to find dsi host\n");
 
 	dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
 	if (IS_ERR(dsi)) {
@@ -609,6 +588,23 @@
 		drm_bridge_hpd_disable(lt->hdmi_port);
 }
 
+static enum drm_mode_status
+lt8912_bridge_mode_valid(struct drm_bridge *bridge,
+			 const struct drm_display_info *info,
+			 const struct drm_display_mode *mode)
+{
+	if (mode->clock > 150000)
+		return MODE_CLOCK_HIGH;
+
+	if (mode->hdisplay > 1920)
+		return MODE_BAD_HVALUE;
+
+	if (mode->vdisplay > 1080)
+		return MODE_BAD_VVALUE;
+
+	return MODE_OK;
+}
+
 static enum drm_connector_status
 lt8912_bridge_detect(struct drm_bridge *bridge)
 {
@@ -639,6 +635,7 @@
 static const struct drm_bridge_funcs lt8912_bridge_funcs = {
 	.attach = lt8912_bridge_attach,
 	.detach = lt8912_bridge_detach,
+	.mode_valid = lt8912_bridge_mode_valid,
 	.mode_set = lt8912_bridge_mode_set,
 	.enable = lt8912_bridge_enable,
 	.detect = lt8912_bridge_detect,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/lontium-lt9611.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/lontium-lt9611.c
@@ -4,70 +4,198 @@
  * Copyright (c) 2019-2020. Linaro Limited.
  */
 
+#include <linux/firmware.h>
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
-#include <linux/media-bus-format.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/of_graph.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <linux/of_platform.h>
 
 #include <sound/hdmi-codec.h>
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_mipi_dsi.h>
-#include <drm/drm_of.h>
 #include <drm/drm_print.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_file.h>
+#include <media/cec.h>
+#include <media/cec-notifier.h>
+
+#include <drm/drm_ext_display.h>
+#include <net/netlink.h>
+#include <net/net_namespace.h>
+
+static struct sock *nlsk;
+
+#define NETLINK_TEST 30
+#define EDID_EXT_FLAG_POS 126
+
+enum lt9611_connection_status {
+	LT9611_DISCONNECT = 0,
+	LT9611_CONNECTION = 1,
+};
+
+static const char *const lt9611_status_string[] = {
+	[LT9611_DISCONNECT] = "Hdmi Disconnect",
+	[LT9611_CONNECTION] = "Hdmi Connection",
+};
+
+static struct drm_display_mode default_mode_1080p = {
+	DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, 2052,
+		2200, 0, 1080, 1084, 1089, 1125, 0,
+		DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)
+};
+
+static struct drm_display_mode default_mode_1440p = {
+	DRM_MODE("2560x1440", DRM_MODE_TYPE_DRIVER, 241700, 2560, 2608, 2640,
+		2720, 0, 1440, 1443, 1448, 1481, 0,
+		DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)
+};
+
+static struct drm_display_mode default_mode_4k30 = {
+	DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 297000, 3840, 4016,
+		4104, 4400, 0, 2160, 2168, 2178, 2250, 0,
+		DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)
+};
+
+static struct drm_display_mode default_mode_720p = {
+	DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
+		1430, 1650, 0, 720, 725, 730, 750, 0,
+		DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC)
+};
+
+static int detect;
 
-#define EDID_SEG_SIZE	256
 #define EDID_LEN	32
 #define EDID_LOOP	8
-#define KEY_DDC_ACCS_DONE 0x02
-#define DDC_NO_ACK	0x50
+#define EDID_BLOCK_SIZE	128
+#define EDID_NUM_BLOCKS	2
 
-#define LT9611_4LANES	0
+#define MAX_NUMBER_ADB 5
+#define MAX_AUDIO_DATA_BLOCK_SIZE 30
+
+enum mipi_lane_counts {
+	MIPI_1LANE = 1,
+	MIPI_2LANE = 2,
+	MIPI_3LANE = 3,
+	MIPI_4LANE = 0,
+};
+
+enum audio_intf {
+	I2S = 0,
+	SPDIF = 1,
+};
+
+enum mipi_port_counts {
+	MIPI_1PORT = 0x00,
+	MIPI_2PORT = 0x03,
+};
+
+enum lt9611_aspect_ratio_type {
+	RATIO_UNKOWN = 0,
+	RATIO_4_3,
+	RATIO_16_9,
+	RATIO_16_10,
+	RATIO_64_27,
+	RATIO_256_135,
+};
+
+struct lt9611_mode {
+	u16 hdisplay;
+	u16 htotal;
+	u16 vdisplay;
+	u16 vtotal;
+	u8 vrefresh;
+};
 
 struct lt9611 {
 	struct device *dev;
 	struct drm_bridge bridge;
-	struct drm_bridge *next_bridge;
+	struct drm_connector connector;
+	struct edid *edid;
 
 	struct regmap *regmap;
+	/* Protects all accesses to registers by stopping the on-chip MCU */
+	struct mutex ocm_lock;
+
+	struct wait_queue_head wq;
+	struct work_struct work;
 
 	struct device_node *dsi0_node;
-	struct device_node *dsi1_node;
 	struct mipi_dsi_device *dsi0;
-	struct mipi_dsi_device *dsi1;
 	struct platform_device *audio_pdev;
 
-	bool ac_mode;
+	enum mipi_port_counts mipi_port_counts;
+	enum mipi_lane_counts mipi_lane_counts;
+	enum audio_intf audio_out_intf;
 
 	struct gpio_desc *reset_gpio;
 	struct gpio_desc *enable_gpio;
+	struct gpio_desc *ocb_gpio;
 
-	bool power_on;
-	bool sleep;
+	u8 pcr_m;
 
 	struct regulator_bulk_data supplies[2];
 
 	struct i2c_client *client;
 
-	enum drm_connector_status status;
-
-	u8 edid_buf[EDID_SEG_SIZE];
+	bool power_on;
+	/* can be accessed from different threads, so protect this with ocm_lock */
+	bool hdmi_connected;
+	bool edid_read_sts;
+	bool edid_read_en;
+	bool pm_enable;
+	bool pm_work_sts;
+
+	/* external display platform device */
+	struct platform_device *ext_pdev;
+	struct msm_ext_disp_init_data ext_audio_data;
+	struct msm_ext_disp_audio_edid_blk audio_edid_blk;
+	u8 raw_sad[MAX_NUMBER_ADB * MAX_AUDIO_DATA_BLOCK_SIZE];
+	bool audio_support;
+
+	/* CEC support */
+	struct cec_adapter *cec_adapter;
+	u8 cec_log_addr;
+	u8 cec_tx_data;
+	bool cec_en;
+	bool cec_support;
+	struct work_struct cec_recv_work;
+	struct work_struct cec_transmit_work;
+	bool cec_status;
+	unsigned int cec_tx_status;
+	struct cec_notifier *cec_notifier;
+
+	struct delayed_work pm_work;
+	/* Dynamic Mode Switch support */
+	struct drm_display_mode curr_mode;
+	u8 edid_buf[256];
+	bool fix_mode;
+	struct lt9611_mode debug_mode;
 };
 
 #define LT9611_PAGE_CONTROL	0xff
 
+#define	MPEG_PKT_EN 0x01
+#define	AIF_PKT_EN  0x02
+#define SPD_PKT_EN	0x04
+#define AVI_PKT_EN	0x08
+#define UD1_PKT_EN	0x10
+#define UD0_PKT_EN	0x20
+
 static const struct regmap_range_cfg lt9611_ranges[] = {
 	{
 		.name = "register_range",
 		.range_min =  0,
-		.range_max = 0x85ff,
+		.range_max = 0xd0ff,
 		.selector_reg = LT9611_PAGE_CONTROL,
 		.selector_mask = 0xff,
 		.selector_shift = 0,
@@ -84,188 +212,446 @@
 	.num_ranges = ARRAY_SIZE(lt9611_ranges),
 };
 
+#if !IS_ENABLED(CONFIG_CEC_CORE)
+static inline struct cec_adapter *cec_allocate_adapter(
+		const struct cec_adap_ops *ops, void *priv,
+		const char *name, u32 caps, u8 available_las)
+{
+	return NULL;
+}
+
+static inline int cec_s_log_addrs(struct cec_adapter *adap,
+		struct cec_log_addrs *log_addrs, bool block)
+{
+	return 0;
+}
+
+static inline void cec_transmit_attempt_done(struct cec_adapter *adap,
+		u8 status)
+{
+}
+
+static inline void cec_received_msg(struct cec_adapter *adap,
+		struct cec_msg *msg)
+{
+}
+#endif
+
 static struct lt9611 *bridge_to_lt9611(struct drm_bridge *bridge)
 {
 	return container_of(bridge, struct lt9611, bridge);
 }
 
-static int lt9611_mipi_input_analog(struct lt9611 *lt9611)
+static struct lt9611 *connector_to_lt9611(struct drm_connector *connector)
 {
-	const struct reg_sequence reg_cfg[] = {
-		{ 0x8106, 0x40 }, /* port A rx current */
-		{ 0x810a, 0xfe }, /* port A ldo voltage set */
-		{ 0x810b, 0xbf }, /* enable port A lprx */
-		{ 0x8111, 0x40 }, /* port B rx current */
-		{ 0x8115, 0xfe }, /* port B ldo voltage set */
-		{ 0x8116, 0xbf }, /* enable port B lprx */
+	return container_of(connector, struct lt9611, connector);
+}
 
-		{ 0x811c, 0x03 }, /* PortA clk lane no-LP mode */
-		{ 0x8120, 0x03 }, /* PortB clk lane with-LP mode */
-	};
+static void lt9611_lock(struct lt9611 *lt9611)
+{
+	mutex_lock(&lt9611->ocm_lock);
+	regmap_write(lt9611->regmap, 0x80ee, 0x01);
+}
 
-	return regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+static void lt9611_unlock(struct lt9611 *lt9611)
+{
+	regmap_write(lt9611->regmap, 0x80ee, 0x00);
+	msleep(50);
+	mutex_unlock(&lt9611->ocm_lock);
 }
 
-static int lt9611_mipi_input_digital(struct lt9611 *lt9611,
-				     const struct drm_display_mode *mode)
+static int lt9611_setup_audio_infoframes(struct lt9611 *lt9611,
+		struct msm_ext_disp_audio_setup_params *params)
 {
-	struct reg_sequence reg_cfg[] = {
-		{ 0x8300, LT9611_4LANES },
-		{ 0x830a, 0x00 },
-		{ 0x824f, 0x80 },
-		{ 0x8250, 0x10 },
-		{ 0x8302, 0x0a },
-		{ 0x8306, 0x0a },
-	};
+	struct hdmi_audio_infoframe frame;
+	u8 buffer[14];
+	ssize_t err;
+	u8 i = 0;
 
-	if (lt9611->dsi1_node)
-		reg_cfg[1].def = 0x03;
+	err = hdmi_audio_infoframe_init(&frame);
+	if (err < 0) {
+		dev_err(lt9611->dev, "Failed to setup audio infoframe: %zd\n", err);
+		return err;
+	}
 
-	return regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+	/* frame.coding_type */
+	frame.channels = params->num_of_channels;
+	frame.sample_frequency = params->sample_rate_hz;
+	/* frame.sample_size */
+	/* frame.coding_type_ext */
+	frame.channel_allocation = params->channel_allocation;
+	frame.downmix_inhibit = params->down_mix;
+	frame.level_shift_value = params->level_shift;
+
+	err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
+	if (err < 0) {
+		dev_err(lt9611->dev, "Failed to pack audio infoframe: %zd\n", err);
+		return err;
+	}
+
+	/* write checksum and byte 1 to byte 8 */
+	for (i = 0; i < 9; i++)
+		pr_err("hdmi_audio_infoframe_pack, buffer[3+%d]= %d\n", i, buffer[3+i]);
+
+	return 0;
 }
 
-static void lt9611_mipi_video_setup(struct lt9611 *lt9611,
-				    const struct drm_display_mode *mode)
+static void lt9611_cea_sad_to_raw_sad(struct cea_sad *sads, u8 sad_count,
+		u8 *blk)
 {
-	u32 h_total, hactive, hsync_len, hfront_porch, hsync_porch;
-	u32 v_total, vactive, vsync_len, vfront_porch, vsync_porch;
+	int i = 0;
 
-	h_total = mode->htotal;
-	v_total = mode->vtotal;
+	for (i = 0; i < sad_count; i++) {
+		blk[i * 3] = (sads[i].format << 3) + sads[i].channels;
+		blk[i * 3 + 1] = sads[i].freq;
+		blk[i * 3 + 2] = sads[i].byte2;
+	}
+}
 
-	hactive = mode->hdisplay;
-	hsync_len = mode->hsync_end - mode->hsync_start;
-	hfront_porch = mode->hsync_start - mode->hdisplay;
-	hsync_porch = mode->htotal - mode->hsync_start;
-
-	vactive = mode->vdisplay;
-	vsync_len = mode->vsync_end - mode->vsync_start;
-	vfront_porch = mode->vsync_start - mode->vdisplay;
-	vsync_porch = mode->vtotal - mode->vsync_start;
+static int lt9611_get_edid_audio_blk(struct msm_ext_disp_audio_edid_blk *blk,
+				struct edid *edid)
+{
+	struct lt9611 *lt9611 = container_of(blk, struct lt9611, audio_edid_blk);
+	int i = 0;
 
-	regmap_write(lt9611->regmap, 0x830d, (u8)(v_total / 256));
-	regmap_write(lt9611->regmap, 0x830e, (u8)(v_total % 256));
+	/* Short Audio Descriptor */
+	struct cea_sad *sads;
+	int sad_count = 0;
 
-	regmap_write(lt9611->regmap, 0x830f, (u8)(vactive / 256));
-	regmap_write(lt9611->regmap, 0x8310, (u8)(vactive % 256));
+	/* Speaker Allocation Data Block */
+	u8 *sadb = NULL;
+	int sadb_size = 0;
 
-	regmap_write(lt9611->regmap, 0x8311, (u8)(h_total / 256));
-	regmap_write(lt9611->regmap, 0x8312, (u8)(h_total % 256));
+	sad_count = drm_edid_to_sad(edid, &sads);
+	lt9611_cea_sad_to_raw_sad(sads, sad_count, lt9611->raw_sad);
+	sadb_size = drm_edid_to_speaker_allocation(edid, &sadb);
+	dev_err(lt9611->dev, "sad_count %d, sadb_size %d\n", sad_count, sadb_size);
 
-	regmap_write(lt9611->regmap, 0x8313, (u8)(hactive / 256));
-	regmap_write(lt9611->regmap, 0x8314, (u8)(hactive % 256));
+	blk->audio_data_blk = lt9611->raw_sad;
+	blk->audio_data_blk_size = sad_count * 3; /* SAD is 3B */
+	for (i = 0; i < blk->audio_data_blk_size; i++)
+		dev_err(lt9611->dev, "%02X\n", blk->audio_data_blk[i]);
 
-	regmap_write(lt9611->regmap, 0x8315, (u8)(vsync_len % 256));
-	regmap_write(lt9611->regmap, 0x8316, (u8)(hsync_len % 256));
+	blk->spk_alloc_data_blk = sadb;
+	blk->spk_alloc_data_blk_size = sadb_size;
 
-	regmap_write(lt9611->regmap, 0x8317, (u8)(vfront_porch % 256));
+	/* from CEA-861-F spec, the size is always 3 bytes */
+	for (i = 0; i < blk->spk_alloc_data_blk_size; i++)
+		dev_err(lt9611->dev, "%02X\n", blk->spk_alloc_data_blk[i]);
 
-	regmap_write(lt9611->regmap, 0x8318, (u8)(vsync_porch % 256));
+	return 0;
+}
 
-	regmap_write(lt9611->regmap, 0x8319, (u8)(hfront_porch % 256));
+static struct lt9611 *lt9611_audio_get_pdata(struct platform_device *pdev)
+{
+	struct msm_ext_disp_data *ext_data;
+	struct lt9611 *lt9611;
 
-	regmap_write(lt9611->regmap, 0x831a, (u8)(hsync_porch / 256) |
-						((hfront_porch / 256) << 4));
-	regmap_write(lt9611->regmap, 0x831b, (u8)(hsync_porch % 256));
+	if (!pdev) {
+		pr_err("%s:Invalid pdev\n", __func__);
+		return ERR_PTR(-ENODEV);
+	}
+
+	ext_data = platform_get_drvdata(pdev);
+	if (!ext_data) {
+		pr_err("%s:Invalid ext disp data\n", __func__);
+		return ERR_PTR(-EINVAL);
+	}
+
+	lt9611 = ext_data->intf_data;
+	if (!lt9611) {
+		pr_err("%s:Invalid intf data\n", __func__);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return lt9611;
 }
 
-static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode, unsigned int postdiv)
+static int hdmi_audio_info_setup(struct platform_device *pdev,
+		struct msm_ext_disp_audio_setup_params *params)
 {
-	unsigned int pcr_m = mode->clock * 5 * postdiv / 27000;
-	const struct reg_sequence reg_cfg[] = {
-		{ 0x830b, 0x01 },
-		{ 0x830c, 0x10 },
-		{ 0x8348, 0x00 },
-		{ 0x8349, 0x81 },
-
-		/* stage 1 */
-		{ 0x8321, 0x4a },
-		{ 0x8324, 0x71 },
-		{ 0x8325, 0x30 },
-		{ 0x832a, 0x01 },
-
-		/* stage 2 */
-		{ 0x834a, 0x40 },
-
-		/* MK limit */
-		{ 0x832d, 0x38 },
-		{ 0x8331, 0x08 },
-	};
-	u8 pol = 0x10;
+	struct lt9611 *lt9611 = lt9611_audio_get_pdata(pdev);
+	int rc = 0;
 
-	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
-		pol |= 0x2;
-	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
-		pol |= 0x1;
-	regmap_write(lt9611->regmap, 0x831d, pol);
+	rc = lt9611_setup_audio_infoframes(lt9611, params);
 
-	regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
-	if (lt9611->dsi1_node) {
-		unsigned int hact = mode->hdisplay;
+	return 0;
+}
+
+static int hdmi_audio_get_edid_blk(struct platform_device *pdev,
+		struct msm_ext_disp_audio_edid_blk *blk)
+{
+	struct lt9611 *lt9611 = lt9611_audio_get_pdata(pdev);
+
+	lt9611_get_edid_audio_blk(&lt9611->audio_edid_blk, lt9611->edid);
+
+	blk->audio_data_blk = lt9611->audio_edid_blk.audio_data_blk;
+	blk->audio_data_blk_size = lt9611->audio_edid_blk.audio_data_blk_size;
+
+	blk->spk_alloc_data_blk = lt9611->audio_edid_blk.spk_alloc_data_blk;
+	blk->spk_alloc_data_blk_size =
+		lt9611->audio_edid_blk.spk_alloc_data_blk_size;
+
+	return 0;
+}
+
+static int hdmi_audio_get_cable_status(struct platform_device *pdev, u32 vote)
+{
+	struct lt9611 *lt9611 = lt9611_audio_get_pdata(pdev);
+
+	return IS_ERR(lt9611) ? PTR_ERR(lt9611) : lt9611->hdmi_connected;
+}
+
+static int hdmi_audio_get_intf_id(struct platform_device *pdev)
+{
+	struct lt9611 *lt9611 = lt9611_audio_get_pdata(pdev);
+
+	return IS_ERR(lt9611) ? PTR_ERR(lt9611) : EXT_DISPLAY_TYPE_HDMI;
+}
+
+static void hdmi_audio_teardown_done(struct platform_device *pdev)
+{
+}
 
-		hact >>= 2;
-		hact += 0x50;
-		hact = min(hact, 0x3e0U);
-		regmap_write(lt9611->regmap, 0x830b, hact / 256);
-		regmap_write(lt9611->regmap, 0x830c, hact % 256);
-		regmap_write(lt9611->regmap, 0x8348, hact / 256);
-		regmap_write(lt9611->regmap, 0x8349, hact % 256);
+static int hdmi_audio_ack_done(struct platform_device *pdev, u32 ack)
+{
+	return 0;
+}
+
+static int hdmi_audio_codec_ready(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static int hdmi_audio_register_ext_disp(struct lt9611 *lt9611)
+{
+	struct msm_ext_disp_init_data *ext;
+	struct msm_ext_disp_audio_codec_ops *ops;
+	struct device_node *np = NULL;
+	const char *phandle = "lt,ext-disp";
+
+	int rc = 0;
+
+	ext = &lt9611->ext_audio_data;
+	ops = &ext->codec_ops;
+
+	ext->codec.type = EXT_DISPLAY_TYPE_HDMI;
+	ext->codec.ctrl_id = 1;
+	ext->codec.stream_id = 0;
+	ext->pdev = lt9611->audio_pdev;
+	ext->intf_data = lt9611;
+
+	ops->audio_info_setup   = hdmi_audio_info_setup;
+	ops->get_audio_edid_blk = hdmi_audio_get_edid_blk;
+	ops->cable_status       = hdmi_audio_get_cable_status;
+	ops->get_intf_id        = hdmi_audio_get_intf_id;
+	ops->teardown_done      = hdmi_audio_teardown_done;
+	ops->acknowledge        = hdmi_audio_ack_done;
+	ops->ready              = hdmi_audio_codec_ready;
+
+	if (!lt9611->dev->of_node) {
+		dev_err(lt9611->dev, "cannot find audio dev.of_node\n");
+		rc = -ENODEV;
+		goto end;
+	}
+
+	np = of_parse_phandle(lt9611->dev->of_node, phandle, 0);
+	if (!np) {
+		dev_err(lt9611->dev, "cannot parse %s handle\n", phandle);
+		rc = -ENODEV;
+		goto end;
+	}
+
+	lt9611->ext_pdev = of_find_device_by_node(np);
+	if (!lt9611->ext_pdev) {
+		dev_err(lt9611->dev, "cannot find %s pdev\n", phandle);
+		rc = -ENODEV;
+		goto end;
 	}
 
-	regmap_write(lt9611->regmap, 0x8326, pcr_m);
+	rc = msm_ext_disp_register_intf(lt9611->ext_pdev, ext);
+	if (rc)
+		dev_err(lt9611->dev, "failed to register ext disp\n");
 
-	/* pcr rst */
-	regmap_write(lt9611->regmap, 0x8011, 0x5a);
-	regmap_write(lt9611->regmap, 0x8011, 0xfa);
+end:
+	return rc;
+}
+
+static int hdmi_audio_deregister_ext_disp(struct lt9611 *lt9611)
+{
+	int rc = 0;
+	struct device_node *pd = NULL;
+	const char *phandle = "lt,ext-disp";
+	struct msm_ext_disp_init_data *ext;
+
+	ext = &lt9611->ext_audio_data;
+
+	if (!lt9611->dev->of_node) {
+		dev_err(lt9611->dev, "cannot find audio dev.of_node\n");
+		rc = -ENODEV;
+		goto end;
+	}
+
+	pd = of_parse_phandle(lt9611->dev->of_node, phandle, 0);
+	if (!pd) {
+		dev_err(lt9611->dev, "cannot parse %s handle\n", phandle);
+		rc = -ENODEV;
+		goto end;
+	}
+
+	lt9611->ext_pdev = of_find_device_by_node(pd);
+	if (!lt9611->ext_pdev) {
+		dev_err(lt9611->dev, "cannot find %s pdev\n", phandle);
+		rc = -ENODEV;
+		goto end;
+	}
+
+	rc = msm_ext_disp_deregister_intf(lt9611->ext_pdev, ext);
+	if (rc)
+		dev_err(lt9611->dev, "failed to deregister ext disp\n");
+
+end:
+	return rc;
 }
 
-static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode, unsigned int *postdiv)
+static int lt9611_sys_init(struct lt9611 *lt9611)
+{
+	int ret;
+	const struct reg_sequence seq[] = {
+		/* LT9611_System_Init */
+		{ 0x8101, 0x18 }, /* sel xtal clock */
+		{ 0x8251, 0x11 },
+
+		/* timer for frequency meter */
+		{ 0x821b, 0x69 }, /* timer 2 */
+		{ 0x821c, 0x78 },
+		{ 0x82cb, 0x69 }, /* timer 1 */
+		{ 0x82cc, 0x78 },
+
+		/* power consumption for work */
+		{ 0x8004, 0xf0 },
+		{ 0x8006, 0xf0 },
+		{ 0x800a, 0x80 },
+		{ 0x800b, 0x46 },
+		{ 0x800d, 0xef },
+		{ 0x8011, 0xfa },
+	};
+
+	ret = regmap_multi_reg_write(lt9611->regmap, seq, ARRAY_SIZE(seq));
+
+	return ret;
+}
+
+static int lt9611_mipi_input_analog(struct lt9611 *lt9611)
 {
-	unsigned int pclk = mode->clock;
 	const struct reg_sequence reg_cfg[] = {
-		/* txpll init */
-		{ 0x8123, 0x40 },
-		{ 0x8124, 0x64 },
-		{ 0x8125, 0x80 },
-		{ 0x8126, 0x55 },
-		{ 0x812c, 0x37 },
-		{ 0x812f, 0x01 },
-		{ 0x8126, 0x55 },
-		{ 0x8127, 0x66 },
-		{ 0x8128, 0x88 },
-		{ 0x812a, 0x20 },
+		{ 0x8106, 0x60 }, /* port A rx current */
+		{ 0x8107, 0x3f },
+		{ 0x8108, 0x3f },
+		{ 0x810a, 0xfe }, /* port A ldo voltage set */
+		{ 0x810b, 0xbf }, /* enable port A lprx */
+
+		{ 0x8111, 0x60 }, /* port B rx current */
+		{ 0x8112, 0x3f },
+		{ 0x8113, 0x3f },
+		{ 0x8115, 0xfe }, /* port B ldo voltage set */
+		{ 0x8116, 0xbf }, /* enable port B lprx */
+
+		{ 0x811c, 0x03 }, /* PortA clk lane no-LP mode */
+		{ 0x8120, 0x03 }, /* PortB clk lane with-LP mode */
 	};
 
-	regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+	return regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+}
 
-	if (pclk > 150000) {
-		regmap_write(lt9611->regmap, 0x812d, 0x88);
-		*postdiv = 1;
-	} else if (pclk > 70000) {
-		regmap_write(lt9611->regmap, 0x812d, 0x99);
-		*postdiv = 2;
-	} else {
-		regmap_write(lt9611->regmap, 0x812d, 0xaa);
-		*postdiv = 4;
-	}
+static int lt9611_mipi_input_digital(struct lt9611 *lt9611,
+				     const struct drm_display_mode *mode)
+{
+	u8 lanes = lt9611->mipi_lane_counts;
+	u8 ports = lt9611->mipi_port_counts;
+	int ret;
 
-	/*
-	 * first divide pclk by 2 first
-	 *  - write divide by 64k to 19:16 bits which means shift by 17
-	 *  - write divide by 256 to 15:8 bits which means shift by 9
-	 *  - write remainder to 7:0 bits, which means shift by 1
-	 */
-	regmap_write(lt9611->regmap, 0x82e3, pclk >> 17); /* pclk[19:16] */
-	regmap_write(lt9611->regmap, 0x82e4, pclk >> 9);  /* pclk[15:8]  */
-	regmap_write(lt9611->regmap, 0x82e5, pclk >> 1);  /* pclk[7:0]   */
+	struct reg_sequence reg_cfg[] = {
+		{ 0x8250, 0x14 },
+		{ 0x8303, 0x40 },
+		{ 0x824f, 0x80 },
+		{ 0x8300, lanes },
+		{ 0x8302, 0x0a },
+		{ 0x8306, 0x0a },
+		{ 0x830a, ports },
+	};
 
-	regmap_write(lt9611->regmap, 0x82de, 0x20);
-	regmap_write(lt9611->regmap, 0x82de, 0xe0);
+	ret = regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
 
-	regmap_write(lt9611->regmap, 0x8016, 0xf1);
-	regmap_write(lt9611->regmap, 0x8016, 0xf3);
+	return ret;
+}
 
-	return 0;
+static void lt9611_Audio_Init(struct lt9611 *lt9611)
+{
+	if (lt9611->audio_out_intf == I2S) {
+		regmap_write(lt9611->regmap, 0x82d7, 0x04);
+		regmap_write(lt9611->regmap, 0x8406, 0x08);
+		regmap_write(lt9611->regmap, 0x8407, 0x10);
+
+		/* 48K sampling frequency */
+		regmap_write(lt9611->regmap, 0x840f, 0x2b);
+		/* CTS_N 0xd5: sclk = 32fs, 0xd4: sclk = 64fs */
+		regmap_write(lt9611->regmap, 0x8434, 0xd4);
+
+		/* N value = 6144 */
+		regmap_write(lt9611->regmap, 0x8435, 0x00);
+		regmap_write(lt9611->regmap, 0x8436, 0x18);
+		regmap_write(lt9611->regmap, 0x8437, 0x00);
+	}
+
+	if (lt9611->audio_out_intf == SPDIF) {
+		regmap_write(lt9611->regmap, 0x8406, 0x0c);
+		regmap_write(lt9611->regmap, 0x8407, 0x10);
+
+		/* CTS_N */
+		regmap_write(lt9611->regmap, 0x8434, 0xd4);
+		regmap_write(lt9611->regmap, 0x8436, 0x20);
+	}
+}
+
+static void lt9611_hdmi_tx_phy(struct lt9611 *lt9611)
+{
+	struct reg_sequence reg_cfg[] = {
+		{ 0x8130, 0x6a },
+		{ 0x8131, 0x44 }, /* HDMI DC mode */
+		{ 0x8132, 0x4a },
+		{ 0x8133, 0x0b },
+		{ 0x8134, 0x00 },
+		{ 0x8135, 0x00 },
+		{ 0x8136, 0x00 },
+		{ 0x8137, 0x44 },
+		{ 0x813f, 0x0f },
+		{ 0x8140, 0x98 },
+		{ 0x8141, 0x98 }, /* clk swing */
+		{ 0x8142, 0x98 }, /* D0 swing */
+		{ 0x8143, 0x98 }, /* D1 swing */
+		{ 0x8144, 0x0a }, /* D2 swing */
+	};
+
+	regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+}
+
+static void lt9611_LowPower_mode(struct lt9611 *lt9611, bool on)
+{
+	/* only hpd irq is working for low power consumption */
+	/* 1.8V: 15 mA */
+	if (on) {
+		regmap_write(lt9611->regmap, 0x8102, 0x49);
+		regmap_write(lt9611->regmap, 0x8123, 0x80);
+		/* 0x00 --> 0xc0, tx phy and clk can not power down, otherwise dc det don't work */
+		regmap_write(lt9611->regmap, 0x8130, 0x00);
+		regmap_write(lt9611->regmap, 0x8011, 0x0a);
+	} else {
+		regmap_write(lt9611->regmap, 0x8102, 0x12);
+		regmap_write(lt9611->regmap, 0x8123, 0x40);
+		regmap_write(lt9611->regmap, 0x8130, 0xea);
+		regmap_write(lt9611->regmap, 0x8011, 0xfa);
+	}
 }
 
 static int lt9611_read_video_check(struct lt9611 *lt9611, unsigned int reg)
@@ -288,6 +674,7 @@
 {
 	u32 v_total, vactive, hactive_a, hactive_b, h_total_sysclk;
 	int temp;
+	unsigned int mipi_video_format = 0;
 
 	/* top module video check */
 
@@ -321,9 +708,17 @@
 		goto end;
 	hactive_b = temp / 3;
 
-	dev_info(lt9611->dev,
-		 "video check: hactive_a=%d, hactive_b=%d, vactive=%d, v_total=%d, h_total_sysclk=%d\n",
-		 hactive_a, hactive_b, vactive, v_total, h_total_sysclk);
+	regmap_read(lt9611->regmap, 0x8388, &mipi_video_format);
+
+	dev_err(lt9611->dev,
+		 "video check: hactive_a=%d, hactive_b=%d, vactive=%d, v_total=%d, h_total_sysclk=%d, mipi_video_format=%d\n",
+		 hactive_a, hactive_b, vactive, v_total, h_total_sysclk, mipi_video_format);
+
+	/* settle config */
+	if ((hactive_a == 3840) && (vactive == 2160)) {
+		regmap_write(lt9611->regmap, 0x8302, 0x10);
+		regmap_write(lt9611->regmap, 0x8306, 0x10);
+	}
 
 	return 0;
 
@@ -332,202 +727,461 @@
 	return temp;
 }
 
-static void lt9611_hdmi_set_infoframes(struct lt9611 *lt9611,
-				       struct drm_connector *connector,
-				       struct drm_display_mode *mode)
-{
-	union hdmi_infoframe infoframe;
-	ssize_t len;
-	u8 iframes = 0x0a; /* UD1 infoframe */
-	u8 buf[32];
-	int ret;
-	int i;
+static u8 pcr_m_ex;
+static void lt9611_pll_setup(struct lt9611 *lt9611)
+{
+	u32 pclk;
+	u8 pcr_m;
+	u8 hdmi_post_div;
+	unsigned int pll_lock_flag, cal_done_flag, band_out;
+	u8 i;
+	const struct reg_sequence reg_cfg[] = {
+		/* txpll init */
+		{ 0x8123, 0x40 },
+		{ 0x8124, 0x62 },
+		{ 0x8125, 0x80 },
+		{ 0x8126, 0x55 },
+		{ 0x812c, 0x37 },
+		{ 0x812f, 0x01 },
+		{ 0x8127, 0x66 },
+		{ 0x8128, 0x88 },
+		{ 0x812a, 0x20 },
+	};
 
-	ret = drm_hdmi_avi_infoframe_from_display_mode(&infoframe.avi,
-						       connector,
-						       mode);
-	if (ret < 0)
-		goto out;
+	pclk = lt9611->curr_mode.clock;
 
-	len = hdmi_infoframe_pack(&infoframe, buf, sizeof(buf));
-	if (len < 0)
-		goto out;
+	regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
 
-	for (i = 0; i < len; i++)
-		regmap_write(lt9611->regmap, 0x8440 + i, buf[i]);
+	if (pclk > 150000) {
+		regmap_write(lt9611->regmap, 0x812d, 0x88);
+		hdmi_post_div = 1;
+	} else if (pclk > 70000) {
+		regmap_write(lt9611->regmap, 0x812d, 0x99);
+		hdmi_post_div = 2;
+	} else {
+		regmap_write(lt9611->regmap, 0x812d, 0xaa);
+		hdmi_post_div = 4;
+	}
 
-	ret = drm_hdmi_vendor_infoframe_from_display_mode(&infoframe.vendor.hdmi,
-							  connector,
-							  mode);
-	if (ret < 0)
-		goto out;
+	pcr_m = (u8)((pclk * 5 * hdmi_post_div) / 27000);
+	pcr_m--;
+	pcr_m_ex = pcr_m;
 
-	len = hdmi_infoframe_pack(&infoframe, buf, sizeof(buf));
-	if (len < 0)
-		goto out;
+	regmap_write(lt9611->regmap, 0x832d, 0x40); /* M up limit */
+	regmap_write(lt9611->regmap, 0x8331, 0x08); /* M down limit */
+	regmap_write(lt9611->regmap, 0x8326, 0x80 | pcr_m);
+	lt9611->pcr_m = pcr_m;
 
-	for (i = 0; i < len; i++)
-		regmap_write(lt9611->regmap, 0x8474 + i, buf[i]);
+	pclk = pclk / 2;
+	regmap_write(lt9611->regmap, 0x82e3, pclk / 65536); /* 13.5M */
+
+	pclk = pclk % 65536;
+	regmap_write(lt9611->regmap, 0x82e4, pclk / 256);
+	regmap_write(lt9611->regmap, 0x82e5, pclk % 256);
+	regmap_write(lt9611->regmap, 0x82de, 0x20);
+	regmap_write(lt9611->regmap, 0x82de, 0xe0);
+
+	regmap_write(lt9611->regmap, 0x8011, 0x5a);
+	regmap_write(lt9611->regmap, 0x8011, 0xfa); /* Pcr clk reset */
+	regmap_write(lt9611->regmap, 0x8016, 0xf2);
+	regmap_write(lt9611->regmap, 0x8018, 0xdc);
+	regmap_write(lt9611->regmap, 0x8018, 0xfc); /* pll analog reset */
+	regmap_write(lt9611->regmap, 0x8016, 0xf3);
+
+	/* pll lock status */
+	for (i = 0; i < 5; i++) {
+		regmap_write(lt9611->regmap, 0x8016, 0xe3); /* pll lock logic reset */
+		regmap_write(lt9611->regmap, 0x8016, 0xf3);
+		regmap_read(lt9611->regmap, 0x8215, &pll_lock_flag);
+		regmap_read(lt9611->regmap, 0x82e6, &band_out);
+		regmap_read(lt9611->regmap, 0x82e7, &cal_done_flag);
+
+		if ((pll_lock_flag & 0x80) && (cal_done_flag & 0x80) && (band_out != 0xff))
+			break;
+
+		regmap_write(lt9611->regmap, 0x8011, 0x5a);
+		msleep(20);
+		regmap_write(lt9611->regmap, 0x8011, 0xfa); /* Pcr clk reset */
+		regmap_write(lt9611->regmap, 0x8016, 0xf2); /* pll cal reset*/
+		regmap_write(lt9611->regmap, 0x8018, 0xdc);
+		msleep(20);
+		regmap_write(lt9611->regmap, 0x8018, 0xfc); /* pll analog reset */
+		regmap_write(lt9611->regmap, 0x8016, 0xf3);
+		msleep(20);
+	}
+}
+
+static void lt9611_pcr_setup(struct lt9611 *lt9611)
+{
+	u8 POL;
+	struct drm_display_mode *mode = &lt9611->curr_mode;
+
+	POL = ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0x02 : 0x00) |
+			((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0x01 : 0x00);
+	POL = ~POL;
+	POL &= 0x03;
+
+	/* single port */
+	regmap_write(lt9611->regmap, 0x830b, 0x01); /* vsync mode */
+	regmap_write(lt9611->regmap, 0x830c, 0x10); /* =1/4 hact */
+	regmap_write(lt9611->regmap, 0x8348, 0x00); /* de mode delay */
+	regmap_write(lt9611->regmap, 0x8349, 0x81); /* =1/4 hact */
+
+	regmap_write(lt9611->regmap, 0x8321, 0x4a); /* bit[3:0] step[11:8] */
+	regmap_write(lt9611->regmap, 0x8324, 0x71); /* bit[7:4]v/h/de mode; line for clk */
+	regmap_write(lt9611->regmap, 0x8325, 0x30); /* line for clk stb[7:0] */
+	regmap_write(lt9611->regmap, 0x832a, 0x01); /* clk stable in */
+
+	regmap_write(lt9611->regmap, 0x834a, 0x40); /* offset 0x10 */
+	regmap_write(lt9611->regmap, 0x831d, 0x10|POL); /* PCR de mode step setting. */
+
+	/* 1024x600_60Hz */
+	if ((mode->hdisplay == 1024) &&
+		(mode->vdisplay == 600) &&
+		(drm_mode_vrefresh(mode)) == 60) {
+		regmap_write(lt9611->regmap, 0x8324, 0x70); /* bit[7:4]v/h/de mode; line for clk stb[11:8] */
+		regmap_write(lt9611->regmap, 0x8325, 0x80); /* line for clk stb[7:0] */
+		regmap_write(lt9611->regmap, 0x832a, 0x10); /* clk stable in */
+
+		regmap_write(lt9611->regmap, 0x8323, 0x04); /* pcr h mode step */
+		regmap_write(lt9611->regmap, 0x834a, 0x10); /* offset //0x10 */
+		regmap_write(lt9611->regmap, 0x831d, 0xf0); /* PCR de mode step setting. */
+	}
+}
+
+static void lt9611_mipi_video_setup(struct lt9611 *lt9611)
+{
+	u32 h_total, h_act, hpw, hfp, hss;
+	u32 v_total, v_act, vpw, vfp, vss;
+	struct drm_display_mode *mode = &lt9611->curr_mode;
+
+	h_total = mode->htotal;
+	v_total = mode->vtotal;
 
-	iframes |= 0x20;
+	h_act = mode->hdisplay;
+	hpw = mode->hsync_end - mode->hsync_start;
+	hfp = mode->hsync_start - mode->hdisplay;
+	hss = mode->htotal - mode->hsync_start;
+
+	v_act = mode->vdisplay;
+	vpw = mode->vsync_end - mode->vsync_start;
+	vfp = mode->vsync_start - mode->vdisplay;
+	vss = mode->vtotal - mode->vsync_start;
 
-out:
-	regmap_write(lt9611->regmap, 0x843d, iframes); /* UD1 infoframe */
+	regmap_write(lt9611->regmap, 0x830d, (u8)(v_total / 256));
+	regmap_write(lt9611->regmap, 0x830e, (u8)(v_total % 256));
+
+	regmap_write(lt9611->regmap, 0x830f, (u8)(v_act / 256));
+	regmap_write(lt9611->regmap, 0x8310, (u8)(v_act % 256));
+
+	regmap_write(lt9611->regmap, 0x8311, (u8)(h_total / 256));
+	regmap_write(lt9611->regmap, 0x8312, (u8)(h_total % 256));
+
+	regmap_write(lt9611->regmap, 0x8313, (u8)(h_act / 256));
+	regmap_write(lt9611->regmap, 0x8314, (u8)(h_act % 256));
+
+	regmap_write(lt9611->regmap, 0x8315, (u8)(vpw % 256));
+	regmap_write(lt9611->regmap, 0x8316, (u8)(hpw % 256));
+
+	regmap_write(lt9611->regmap, 0x8317, (u8)(vfp % 256));
+	regmap_write(lt9611->regmap, 0x8318, (u8)(vss % 256));
+	regmap_write(lt9611->regmap, 0x8319, (u8)(hfp % 256));
+
+	regmap_write(lt9611->regmap, 0x831a, (u8)(((hfp/256)<<4)+(hss/256)));
+	regmap_write(lt9611->regmap, 0x831b, (u8)(hss % 256));
 }
 
-static void lt9611_hdmi_tx_digital(struct lt9611 *lt9611, bool is_hdmi)
+static int lt9611_pcr_start(struct lt9611 *lt9611)
 {
-	if (is_hdmi)
-		regmap_write(lt9611->regmap, 0x82d6, 0x8c);
-	else
-		regmap_write(lt9611->regmap, 0x82d6, 0x0c);
-	regmap_write(lt9611->regmap, 0x82d7, 0x04);
+	regmap_write(lt9611->regmap, 0x8011, 0x5a);
+	msleep(20);
+	regmap_write(lt9611->regmap, 0x8011, 0xfa); /* Pcr reset */
+
+	return 0;
 }
 
-static void lt9611_hdmi_tx_phy(struct lt9611 *lt9611)
+static unsigned int gcd(unsigned int a, unsigned int b)
 {
-	struct reg_sequence reg_cfg[] = {
-		{ 0x8130, 0x6a },
-		{ 0x8131, 0x44 }, /* HDMI DC mode */
-		{ 0x8132, 0x4a },
-		{ 0x8133, 0x0b },
-		{ 0x8134, 0x00 },
-		{ 0x8135, 0x00 },
-		{ 0x8136, 0x00 },
-		{ 0x8137, 0x44 },
-		{ 0x813f, 0x0f },
-		{ 0x8140, 0xa0 },
-		{ 0x8141, 0xa0 },
-		{ 0x8142, 0xa0 },
-		{ 0x8143, 0xa0 },
-		{ 0x8144, 0x0a },
-	};
+	while (b != 0) {
+		unsigned int t = b;
 
-	/* HDMI AC mode */
-	if (lt9611->ac_mode)
-		reg_cfg[2].def = 0x73;
+		b = a % b;
+		a = t;
+	}
 
-	regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
+	return a;
 }
 
-static irqreturn_t lt9611_irq_thread_handler(int irq, void *dev_id)
+static enum lt9611_aspect_ratio_type lt9611_cal_aspect_ratio(const struct drm_display_mode *mode)
 {
-	struct lt9611 *lt9611 = dev_id;
-	unsigned int irq_flag0 = 0;
-	unsigned int irq_flag3 = 0;
+	unsigned int width = mode->hdisplay;
+	unsigned int height = mode->vdisplay;
+	unsigned int divisor, aspect_width, aspect_height;
 
-	regmap_read(lt9611->regmap, 0x820f, &irq_flag3);
-	regmap_read(lt9611->regmap, 0x820c, &irq_flag0);
+	divisor = gcd(width, height);
+	aspect_width = width / divisor;
+	aspect_height = height / divisor;
 
-	/* hpd changed low */
-	if (irq_flag3 & 0x80) {
-		dev_info(lt9611->dev, "hdmi cable disconnected\n");
+	pr_info("Aspect Ratio = %u : %u\n",  aspect_width, aspect_height);
 
-		regmap_write(lt9611->regmap, 0x8207, 0xbf);
-		regmap_write(lt9611->regmap, 0x8207, 0x3f);
-	}
+	if (aspect_width == 4 && aspect_height == 3)
+		return RATIO_4_3;
+	else if (aspect_width == 16 && aspect_height == 9)
+		return RATIO_16_9;
+	else if (aspect_width == 64 && aspect_height == 27)
+		return RATIO_64_27;
+	else if (aspect_width == 256 && aspect_height == 135)
+		return RATIO_256_135;
+	else
+		return RATIO_UNKOWN;
+}
 
-	/* hpd changed high */
-	if (irq_flag3 & 0x40) {
-		dev_info(lt9611->dev, "hdmi cable connected\n");
+static void lt9611_hdmi_tx_digital(struct lt9611 *lt9611, bool is_hdmi)
+{
+	u32 vic = drm_match_cea_mode(&lt9611->curr_mode);
+	u8 AR = lt9611_cal_aspect_ratio(&lt9611->curr_mode);
+	u8 pb0, pb2, pb4;
+	u8 infoFrame_en;
 
-		regmap_write(lt9611->regmap, 0x8207, 0x7f);
-		regmap_write(lt9611->regmap, 0x8207, 0x3f);
-	}
+	infoFrame_en = (AIF_PKT_EN | AVI_PKT_EN);
+	pb2 =  (AR << 4) + 0x08;
 
-	if (irq_flag3 & 0xc0 && lt9611->bridge.dev)
-		drm_kms_helper_hotplug_event(lt9611->bridge.dev);
+	if (vic == 95)
+		pb4 = 0x00;
+	else
+		pb4 =  vic;
 
-	/* video input changed */
-	if (irq_flag0 & 0x01) {
-		dev_info(lt9611->dev, "video input changed\n");
-		regmap_write(lt9611->regmap, 0x829e, 0xff);
-		regmap_write(lt9611->regmap, 0x829e, 0xf7);
-		regmap_write(lt9611->regmap, 0x8204, 0xff);
-		regmap_write(lt9611->regmap, 0x8204, 0xfe);
-	}
+	pb0 = (((pb2 + pb4) <= 0x5f)?(0x5f - pb2 - pb4):(0x15f - pb2 - pb4));
 
-	return IRQ_HANDLED;
+	if (is_hdmi)
+		regmap_write(lt9611->regmap, 0x82d6, 0x8e);
+	else
+		regmap_write(lt9611->regmap, 0x82d6, 0x0e);
+
+	/* audio_i2s */
+	if (lt9611->audio_out_intf == I2S)
+		regmap_write(lt9611->regmap, 0x82d7, 0x04);
+
+	/* audio_spdif */
+	if (lt9611->audio_out_intf == SPDIF)
+		regmap_write(lt9611->regmap, 0x82d7, 0x80);
+
+	regmap_write(lt9611->regmap, 0x8443, pb0); /* AVI_PB0 */
+	regmap_write(lt9611->regmap, 0x8445, pb2); /* AVI_PB2 */
+	regmap_write(lt9611->regmap, 0x8447, pb4); /* AVI_PB4 */
+
+	regmap_write(lt9611->regmap, 0x8410, 0x02); /* data iland */
+	regmap_write(lt9611->regmap, 0x8412, 0x64); /* act_h_blank */
+
+	if (vic == 95) {
+		regmap_write(lt9611->regmap, 0x843d, (infoFrame_en | UD0_PKT_EN));
+		regmap_write(lt9611->regmap, 0x8474, 0x81); /* HB0 */
+		regmap_write(lt9611->regmap, 0x8475, 0x01); /* HB1 */
+		regmap_write(lt9611->regmap, 0x8476, 0x05); /* HB2 */
+		regmap_write(lt9611->regmap, 0x8477, 0x49); /* PB0 */
+		regmap_write(lt9611->regmap, 0x8478, 0x03); /* PB1 */
+		regmap_write(lt9611->regmap, 0x8479, 0x0c); /* PB2 */
+		regmap_write(lt9611->regmap, 0x847a, 0x00); /* PB3 */
+		regmap_write(lt9611->regmap, 0x847b, 0x20); /* PB4 */
+		regmap_write(lt9611->regmap, 0x847c, 0x01); /* PB5 */
+	} else {
+		regmap_write(lt9611->regmap, 0x843d, infoFrame_en);
+	}
 }
 
-static void lt9611_enable_hpd_interrupts(struct lt9611 *lt9611)
+static void lt9611_HDP_Interrupt_Handle(struct lt9611 *lt9611)
 {
-	unsigned int val;
+	unsigned int reg;
 
-	regmap_read(lt9611->regmap, 0x8203, &val);
+	/* Disable HDMI output */
+	regmap_write(lt9611->regmap, 0x8130, 0x00);
+	regmap_write(lt9611->regmap, 0x8123, 0x80);
 
-	val &= ~0xc0;
-	regmap_write(lt9611->regmap, 0x8203, val);
-	regmap_write(lt9611->regmap, 0x8207, 0xff); /* clear */
-	regmap_write(lt9611->regmap, 0x8207, 0x3f);
+	regmap_read(lt9611->regmap, 0x825e, &reg);
+	if ((reg & 0x04) == 0x04) {
+		msleep(20);
+		regmap_read(lt9611->regmap, 0x825e, &reg);
+
+		if ((reg & 0x04) == 0x04) {
+			lt9611_LowPower_mode(lt9611, 0);
+			msleep(100);
+			lt9611_video_check(lt9611);
+			lt9611_pll_setup(lt9611);
+			lt9611_pcr_setup(lt9611);
+			lt9611_mipi_video_setup(lt9611);
+			regmap_write(lt9611->regmap, 0x8326, pcr_m_ex);
+			lt9611_pcr_start(lt9611);
+			lt9611_hdmi_tx_digital(lt9611, true);
+
+			/* Enable HDMI output */
+			regmap_write(lt9611->regmap, 0x8123, 0x40);
+			regmap_write(lt9611->regmap, 0x82de, 0x20);
+			regmap_write(lt9611->regmap, 0x82de, 0xe0);
+			regmap_write(lt9611->regmap, 0x8018, 0xdc);
+			regmap_write(lt9611->regmap, 0x8018, 0xfc);
+			regmap_write(lt9611->regmap, 0x8016, 0xf1);
+			regmap_write(lt9611->regmap, 0x8016, 0xf3);
+			regmap_write(lt9611->regmap, 0x8011, 0x5a); /* Pcr reset */
+			regmap_write(lt9611->regmap, 0x8011, 0xfa);
+			regmap_write(lt9611->regmap, 0x8130, 0xea);
+		}
+	} else {
+		lt9611_LowPower_mode(lt9611, 1);
+	}
 }
 
-static void lt9611_sleep_setup(struct lt9611 *lt9611)
+static void lt9611_power_on(struct lt9611 *lt9611)
 {
-	const struct reg_sequence sleep_setup[] = {
-		{ 0x8024, 0x76 },
-		{ 0x8023, 0x01 },
-		{ 0x8157, 0x03 }, /* set addr pin as output */
-		{ 0x8149, 0x0b },
+	if (lt9611->power_on)
+		return;
 
-		{ 0x8102, 0x48 }, /* MIPI Rx power down */
-		{ 0x8123, 0x80 },
-		{ 0x8130, 0x00 },
-		{ 0x8011, 0x0a },
-	};
+	lt9611_sys_init(lt9611);
+
+	lt9611_mipi_input_analog(lt9611);
+	lt9611_mipi_input_digital(lt9611, NULL);
+	lt9611_Audio_Init(lt9611);
+	lt9611_hdmi_tx_phy(lt9611);
 
-	regmap_multi_reg_write(lt9611->regmap,
-			       sleep_setup, ARRAY_SIZE(sleep_setup));
-	lt9611->sleep = true;
+	/* init and enable hpd interrupt */
+	regmap_write(lt9611->regmap, 0x8258, 0x0a); /* Det HPD 0x0a --> 0x08 */
+	regmap_write(lt9611->regmap, 0x8259, 0x00); /* HPD debounce width */
+	regmap_write(lt9611->regmap, 0x8207, 0xff); /* clear3 */
+	regmap_write(lt9611->regmap, 0x8207, 0x3f); /* clear3 */
+	regmap_write(lt9611->regmap, 0x8203, 0x3f); /* mask3  Tx_det */
+
+	/* cec init and enable cec interrupt */
+	regmap_write(lt9611->regmap, 0x800d, 0xff);
+	regmap_write(lt9611->regmap, 0x8015, 0xf1); /* reset cec logic */
+	regmap_write(lt9611->regmap, 0x8015, 0xf9);
+	regmap_write(lt9611->regmap, 0x86fe, 0xa5); /* clk div */
+
+	regmap_write(lt9611->regmap, 0x86fa, 0x00); /* cec interrup mask */
+	regmap_write(lt9611->regmap, 0x86fc, 0x7f); /* cec irq clr */
+	regmap_write(lt9611->regmap, 0x86fc, 0x00);
+	regmap_write(lt9611->regmap, 0x8201, 0x7f); /* mask bit[7] */
+	regmap_write(lt9611->regmap, 0x8205, 0xff); /* clr bit[7] */
+	regmap_write(lt9611->regmap, 0x8205, 0x7f);
+
+	msleep(200);
+	lt9611->power_on = true;
+}
+
+static void lt9611_on(struct lt9611 *lt9611, bool on)
+{
+	if (on) {
+		lt9611_power_on(lt9611);
+		lt9611_HDP_Interrupt_Handle(lt9611);
+	} else {
+		/* Disable HDMI output */
+		regmap_write(lt9611->regmap, 0x8130, 0x00);
+		regmap_write(lt9611->regmap, 0x8123, 0x80);
+	}
 }
 
-static int lt9611_power_on(struct lt9611 *lt9611)
+static irqreturn_t lt9611_irq_thread_handler(int irq, void *dev_id)
 {
-	int ret;
-	const struct reg_sequence seq[] = {
-		/* LT9611_System_Init */
-		{ 0x8101, 0x18 }, /* sel xtal clock */
+	struct lt9611 *lt9611 = dev_id;
+	unsigned int hpd_status = 0;
+	unsigned int irq_flag0, irq_flag1;
+	unsigned int cec_status;
+
+	lt9611_lock(lt9611);
+
+	regmap_read(lt9611->regmap, 0x820d, &irq_flag0); /* cec interrupt */
+	regmap_read(lt9611->regmap, 0x820f, &irq_flag1); /* hpd interrupt */
+
+	/* 0x80 disconnected, 0x40 connected */
+	if (irq_flag1 & 0xc0) {
+		regmap_write(lt9611->regmap, 0x8207, 0xff); /* clear hpd interrupt */
+		regmap_write(lt9611->regmap, 0x8207, 0x3f); /* clear hpd interrupt */
+
+		regmap_read(lt9611->regmap, 0x825e, &hpd_status);
+		if ((hpd_status & 0x04) == 0x04) {
+			msleep(20);
+			regmap_read(lt9611->regmap, 0x825e, &hpd_status);
+			if ((hpd_status & 0x04) == 0x04) {
+				lt9611->hdmi_connected = true;
+				lt9611->edid_read_en = false;
+				cec_queue_pin_hpd_event(lt9611->cec_adapter, true, 0);
+			}
+		} else {
+			lt9611->hdmi_connected = false;
+			cec_notifier_phys_addr_invalidate(lt9611->cec_notifier);
+			cec_queue_pin_hpd_event(lt9611->cec_adapter, false, 0);
+		}
+		wake_up_all(&lt9611->wq);
+		schedule_work(&lt9611->work);
+	}
 
-		/* timer for frequency meter */
-		{ 0x821b, 0x69 }, /* timer 2 */
-		{ 0x821c, 0x78 },
-		{ 0x82cb, 0x69 }, /* timer 1 */
-		{ 0x82cc, 0x78 },
+	if ((irq_flag0 & 0x80) == 0x80) {
+		regmap_read(lt9611->regmap, 0x86d2, &cec_status);
 
-		/* irq init */
-		{ 0x8251, 0x01 },
-		{ 0x8258, 0x0a }, /* hpd irq */
-		{ 0x8259, 0x80 }, /* hpd debounce width */
-		{ 0x829e, 0xf7 }, /* video check irq */
+		lt9611->cec_status = cec_status;
 
-		/* power consumption for work */
-		{ 0x8004, 0xf0 },
-		{ 0x8006, 0xf0 },
-		{ 0x800a, 0x80 },
-		{ 0x800b, 0x40 },
-		{ 0x800d, 0xef },
-		{ 0x8011, 0xfa },
-	};
+		regmap_write(lt9611->regmap, 0x86fc, 0x7f); /* cec irq clr */
+		regmap_write(lt9611->regmap, 0x86fc, 0x00);
 
-	if (lt9611->power_on)
-		return 0;
+		regmap_write(lt9611->regmap, 0x8205, 0xff); /* clear3 */
+		regmap_write(lt9611->regmap, 0x8205, 0x7f);
 
-	ret = regmap_multi_reg_write(lt9611->regmap, seq, ARRAY_SIZE(seq));
-	if (!ret)
-		lt9611->power_on = true;
+		if (lt9611->cec_status) {
+			schedule_work(&lt9611->cec_transmit_work);
+			schedule_work(&lt9611->cec_recv_work);
+		}
+	}
 
-	return ret;
+	lt9611_unlock(lt9611);
+
+	return IRQ_HANDLED;
 }
 
-static int lt9611_power_off(struct lt9611 *lt9611)
+static void lt9611_release_edid(struct lt9611 *lt9611)
 {
-	int ret;
+	dev_info(lt9611->dev, "release edid\n");
+	kfree(lt9611->edid);
+	lt9611->edid = NULL;
+	drm_connector_update_edid_property(&lt9611->connector, NULL);
+}
 
-	ret = regmap_write(lt9611->regmap, 0x8130, 0x6a);
-	if (!ret)
-		lt9611->power_on = false;
+static void lt9611_helper_hotplug_event(struct lt9611 *lt9611)
+{
+	struct drm_device *dev = NULL;
+	char name[32], status[32];
+	char *event_string = "HOTPLUG=1";
+	char *envp[5];
 
-	return ret;
+	dev = lt9611->connector.dev;
+
+	scnprintf(name, 32, "name=%s",
+		lt9611->connector.name);
+	scnprintf(status, 32, "status=%s",
+		drm_get_connector_status_name(lt9611->connector.status));
+	envp[0] = name;
+	envp[1] = status;
+	envp[2] = event_string;
+	envp[3] = NULL;
+	envp[4] = NULL;
+
+	dev_info(lt9611->dev, "[%s]:[%s]\n", name, status);
+	kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE,
+		envp);
+}
+static void lt9611_hpd_work(struct work_struct *work)
+{
+	struct lt9611 *lt9611 = container_of(work, struct lt9611, work);
+	bool connected;
+
+	mutex_lock(&lt9611->ocm_lock);
+	connected = lt9611->hdmi_connected;
+	mutex_unlock(&lt9611->ocm_lock);
+
+	if (connected == connector_status_disconnected)
+		lt9611_release_edid(lt9611);
+
+	drm_bridge_hpd_notify(&lt9611->bridge,
+			      connected ?
+			      connector_status_connected :
+			      connector_status_disconnected);
 }
 
 static void lt9611_reset(struct lt9611 *lt9611)
@@ -539,16 +1193,18 @@
 	msleep(20);
 
 	gpiod_set_value_cansleep(lt9611->reset_gpio, 1);
-	msleep(100);
+	msleep(200);
 }
 
 static void lt9611_assert_5v(struct lt9611 *lt9611)
 {
-	if (!lt9611->enable_gpio)
+	if ((!lt9611->enable_gpio) || (!lt9611->ocb_gpio))
 		return;
 
 	gpiod_set_value_cansleep(lt9611->enable_gpio, 1);
 	msleep(20);
+	gpiod_set_value_cansleep(lt9611->ocb_gpio, 1);
+	msleep(20);
 }
 
 static int lt9611_regulator_init(struct lt9611 *lt9611)
@@ -562,7 +1218,13 @@
 	if (ret < 0)
 		return ret;
 
-	return regulator_set_load(lt9611->supplies[0].consumer, 300000);
+	ret = regulator_set_voltage(lt9611->supplies[1].consumer, 3300000, 3500000);
+	if (ret) {
+		pr_err("%s:regulator set voltage failed %d", __func__, ret);
+		return ret;
+	}
+
+	return regulator_set_load(lt9611->supplies[0].consumer, 200000);
 }
 
 static int lt9611_regulator_enable(struct lt9611 *lt9611)
@@ -573,7 +1235,7 @@
 	if (ret < 0)
 		return ret;
 
-	usleep_range(1000, 10000);
+	usleep_range(1000, 10000); /* 50000 according to dtsi */
 
 	ret = regulator_enable(lt9611->supplies[1].consumer);
 	if (ret < 0) {
@@ -584,329 +1246,551 @@
 	return 0;
 }
 
-static enum drm_connector_status lt9611_bridge_detect(struct drm_bridge *bridge)
+static int lt9611_add_default_mode(struct drm_connector *connector, struct drm_display_mode *mode)
 {
-	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
-	unsigned int reg_val = 0;
-	int connected = 0;
+	struct lt9611 *lt9611 = connector_to_lt9611(connector);
+	struct drm_display_mode *m;
 
-	regmap_read(lt9611->regmap, 0x825e, &reg_val);
-	connected  = (reg_val & (BIT(2) | BIT(0)));
+	m = drm_mode_duplicate(connector->dev, mode);
+	if (!m) {
+		dev_err(lt9611->dev, "failed to set preferred mode:%s@%d\n",
+				mode->name, drm_mode_vrefresh(mode));
+		return -ENOMEM;
+	}
 
-	lt9611->status = connected ?  connector_status_connected :
-				connector_status_disconnected;
+	m->type &= ~DRM_MODE_TYPE_PREFERRED;
+	m->type |= DRM_MODE_TYPE_PREFERRED;
+	drm_mode_probed_add(connector, m);
 
-	return lt9611->status;
+	dev_info(lt9611->dev, "Set  preferred mode %s@%d\n", mode->name,
+				drm_mode_vrefresh(mode));
+	return 0;
 }
 
-static int lt9611_read_edid(struct lt9611 *lt9611)
+static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611,
+						    struct device_node *dsi_node)
 {
-	unsigned int temp;
-	int ret = 0;
-	int i, j;
-
-	/* memset to clear old buffer, if any */
-	memset(lt9611->edid_buf, 0, sizeof(lt9611->edid_buf));
+	const struct mipi_dsi_device_info info = { "lt9611", 0, NULL };
+	struct mipi_dsi_device *dsi;
+	struct mipi_dsi_host *host;
+	struct device *dev = lt9611->dev;
+	int ret;
 
-	regmap_write(lt9611->regmap, 0x8503, 0xc9);
+	host = of_find_mipi_dsi_host_by_node(dsi_node);
+	if (!host) {
+		dev_err(dev, "failed to find dsi host\n");
+		return ERR_PTR(-EPROBE_DEFER);
+	}
 
-	/* 0xA0 is EDID device address */
-	regmap_write(lt9611->regmap, 0x8504, 0xa0);
-	/* 0x00 is EDID offset address */
-	regmap_write(lt9611->regmap, 0x8505, 0x00);
+	dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
+	if (IS_ERR(dsi)) {
+		dev_err(dev, "failed to create dsi device\n");
+		return dsi;
+	}
 
-	/* length for read */
-	regmap_write(lt9611->regmap, 0x8506, EDID_LEN);
-	regmap_write(lt9611->regmap, 0x8514, 0x7f);
+	dsi->lanes = 4;
+	dsi->format = MIPI_DSI_FMT_RGB888;
+	dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
+			  MIPI_DSI_MODE_VIDEO_HSE;
 
-	for (i = 0; i < EDID_LOOP; i++) {
-		/* offset address */
-		regmap_write(lt9611->regmap, 0x8505, i * EDID_LEN);
-		regmap_write(lt9611->regmap, 0x8507, 0x36);
-		regmap_write(lt9611->regmap, 0x8507, 0x31);
-		regmap_write(lt9611->regmap, 0x8507, 0x37);
-		usleep_range(5000, 10000);
+	ret = devm_mipi_dsi_attach(dev, dsi);
+	if (ret < 0) {
+		dev_err(dev, "failed to attach dsi to host\n");
+		return ERR_PTR(ret);
+	}
 
-		regmap_read(lt9611->regmap, 0x8540, &temp);
+	return dsi;
+}
 
-		if (temp & KEY_DDC_ACCS_DONE) {
-			for (j = 0; j < EDID_LEN; j++) {
-				regmap_read(lt9611->regmap, 0x8583, &temp);
-				lt9611->edid_buf[i * EDID_LEN + j] = temp;
+static void lt9611_set_preferred_mode(struct drm_connector *connector)
+{
+	struct lt9611 *lt9611 = connector_to_lt9611(connector);
+	struct drm_display_mode *mode;
+	const char *string;
+	u16 vdisplay, hdisplay, vrefresh;
+	char new_string[32];
+	bool preferred_mode_set = false;
+
+	if (lt9611->fix_mode) {
+		list_for_each_entry(mode, &connector->probed_modes, head) {
+			mode->type &= ~DRM_MODE_TYPE_PREFERRED;
+			if (lt9611->debug_mode.vdisplay == mode->vdisplay &&
+				lt9611->debug_mode.hdisplay == mode->hdisplay &&
+				lt9611->debug_mode.vrefresh == drm_mode_vrefresh(mode) &&
+				mode->clock < 297000) {
+				mode->type |= DRM_MODE_TYPE_PREFERRED;
+			}
+		}
+	} else {
+		if (!of_property_read_string(lt9611->dev->of_node, "config-mode",
+					&string)) {
+			if (!strcmp("edidAdaptiveResolution", string)) {
+				dev_err(lt9611->dev, "edid Adaptive Resolution");
+			} else {
+				if (!strcmp("1920x1080x60", string)) {
+					lt9611_add_default_mode(&lt9611->connector,
+							&default_mode_1080p);
+				} else if (!strcmp("2560x1440x60", string)) {
+					lt9611_add_default_mode(&lt9611->connector,
+							&default_mode_1440p);
+				} else if (!strcmp("3840x2160x30", string)) {
+					lt9611_add_default_mode(&lt9611->connector,
+							&default_mode_4k30);
+				} else if (!strcmp("1280x720x60", string)) {
+					lt9611_add_default_mode(&lt9611->connector,
+							&default_mode_720p);
+				} else {
+					lt9611_add_default_mode(&lt9611->connector,
+							&default_mode_1080p);
+				}
 			}
-
-		} else if (temp & DDC_NO_ACK) { /* DDC No Ack or Abitration lost */
-			dev_err(lt9611->dev, "read edid failed: no ack\n");
-			ret = -EIO;
-			goto end;
-
 		} else {
-			dev_err(lt9611->dev, "read edid failed: access not done\n");
-			ret = -EIO;
-			goto end;
+			dev_err(lt9611->dev, "Failed to read config-mode property\n");
 		}
 	}
-
-end:
-	regmap_write(lt9611->regmap, 0x8507, 0x1f);
-	return ret;
 }
 
-static int
-lt9611_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
+static void drm_mode_remove(struct drm_connector *connector,
+			    struct drm_display_mode *mode)
 {
-	struct lt9611 *lt9611 = data;
-	int ret;
-
-	if (len > 128)
-		return -EINVAL;
-
-	/* supports up to 1 extension block */
-	/* TODO: add support for more extension blocks */
-	if (block > 1)
-		return -EINVAL;
+	list_del(&mode->head);
+	drm_mode_destroy(connector->dev, mode);
+}
 
-	if (block == 0) {
-		ret = lt9611_read_edid(lt9611);
-		if (ret) {
-			dev_err(lt9611->dev, "edid read failed\n");
-			return ret;
+static int lt9611_connector_get_modes(struct drm_connector *connector)
+{
+	struct lt9611 *lt9611 = connector_to_lt9611(connector);
+	struct cec_notifier *notify = lt9611->cec_notifier;
+	struct drm_display_mode *mode, *t;
+	unsigned int count;
+
+	lt9611->edid = lt9611->bridge.funcs->get_edid(&lt9611->bridge, connector);
+	drm_connector_update_edid_property(connector, lt9611->edid);
+	count = drm_add_edid_modes(connector, lt9611->edid);
+	list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {
+		if (mode->clock > 148500) {
+			drm_mode_remove(connector, mode);
+			count--;
+			dev_info(lt9611->dev, "Filtered out mode: %s@%d (clock: %d)\n",
+					mode->name, drm_mode_vrefresh(mode), mode->clock);
 		}
 	}
+	lt9611_set_preferred_mode(connector);
 
-	block %= 2;
-	memcpy(buf, lt9611->edid_buf + (block * 128), len);
+	/* TODO: add checks for num_of_edid_ext_blk == 0 case */
+	if (lt9611->cec_support)
+		cec_notifier_set_phys_addr_from_edid(notify, lt9611->edid);
 
-	return 0;
+	return count;
 }
 
-/* bridge funcs */
-static void
-lt9611_bridge_atomic_enable(struct drm_bridge *bridge,
-			    struct drm_bridge_state *old_bridge_state)
+static enum drm_connector_status lt9611_connector_detect(struct drm_connector *connector,
+							    bool force)
 {
-	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
-	struct drm_atomic_state *state = old_bridge_state->base.state;
-	struct drm_connector *connector;
-	struct drm_connector_state *conn_state;
-	struct drm_crtc_state *crtc_state;
-	struct drm_display_mode *mode;
-	unsigned int postdiv;
+	struct lt9611 *lt9611 = connector_to_lt9611(connector);
 
-	connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
-	if (WARN_ON(!connector))
-		return;
+	return lt9611->bridge.funcs->detect(&lt9611->bridge);
+}
 
-	conn_state = drm_atomic_get_new_connector_state(state, connector);
-	if (WARN_ON(!conn_state))
-		return;
+static enum drm_mode_status lt9611_connector_mode_valid(struct drm_connector *connector,
+							   struct drm_display_mode *mode)
+{
+	unsigned int pclk;
 
-	crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
-	if (WARN_ON(!crtc_state))
-		return;
+	/* Temporary: Maximum allowable: 1080P@60Hz (148500 kHz) */
+	const unsigned int MAX_ALLOWED_PCLK = 148500;
 
-	mode = &crtc_state->adjusted_mode;
+	pclk = mode->clock;
 
-	lt9611_mipi_input_digital(lt9611, mode);
-	lt9611_pll_setup(lt9611, mode, &postdiv);
-	lt9611_mipi_video_setup(lt9611, mode);
-	lt9611_pcr_setup(lt9611, mode, postdiv);
+	if (pclk > MAX_ALLOWED_PCLK) {
+		dev_info(connector->dev->dev,
+				"Rejecting mode %s: Clock %ukHz exceeds limit\n",
+				mode->name, pclk);
+		return MODE_BAD;
+	}
 
-	if (lt9611_power_on(lt9611)) {
-		dev_err(lt9611->dev, "power on failed\n");
-		return;
+	return MODE_OK;
+}
+
+static const struct drm_connector_helper_funcs lt9611_bridge_connector_helper_funcs = {
+	.get_modes = lt9611_connector_get_modes,
+	.mode_valid = lt9611_connector_mode_valid,
+};
+
+static const struct drm_connector_funcs lt9611_bridge_connector_funcs = {
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.detect = lt9611_connector_detect,
+	.destroy = drm_connector_cleanup,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int lt9611_connector_init(struct drm_bridge *bridge, struct lt9611 *lt9611)
+{
+	int ret;
+
+	if (!bridge->encoder) {
+		DRM_ERROR("Parent encoder object not found");
+		return -ENODEV;
 	}
 
-	lt9611_mipi_input_analog(lt9611);
-	lt9611_hdmi_set_infoframes(lt9611, connector, mode);
-	lt9611_hdmi_tx_digital(lt9611, connector->display_info.is_hdmi);
-	lt9611_hdmi_tx_phy(lt9611);
+	lt9611->connector.polled = DRM_CONNECTOR_POLL_HPD;
 
-	msleep(500);
+	drm_connector_helper_add(&lt9611->connector,
+				 &lt9611_bridge_connector_helper_funcs);
+	ret = drm_connector_init(bridge->dev, &lt9611->connector,
+				 &lt9611_bridge_connector_funcs,
+				 DRM_MODE_CONNECTOR_HDMIA);
+	if (ret) {
+		DRM_ERROR("Failed to initialize connector with drm\n");
+		return ret;
+	}
 
-	lt9611_video_check(lt9611);
+	ret = drm_connector_attach_encoder(&lt9611->connector, bridge->encoder);
+	if (ret) {
+		DRM_ERROR("Failed to link up connector to encoder: %d\n", ret);
+		return ret;
+	}
 
-	/* Enable HDMI output */
-	regmap_write(lt9611->regmap, 0x8130, 0xea);
+	return ret;
 }
 
-static void
-lt9611_bridge_atomic_disable(struct drm_bridge *bridge,
-			     struct drm_bridge_state *old_bridge_state)
+static int lt9611_bridge_attach(struct drm_bridge *bridge,
+				   enum drm_bridge_attach_flags flags)
 {
 	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
 	int ret;
 
-	/* Disable HDMI output */
-	ret = regmap_write(lt9611->regmap, 0x8130, 0x6a);
-	if (ret) {
-		dev_err(lt9611->dev, "video on failed\n");
-		return;
+	if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
+		ret = lt9611_connector_init(bridge, lt9611);
+		if (ret < 0)
+			return ret;
 	}
 
-	if (lt9611_power_off(lt9611)) {
-		dev_err(lt9611->dev, "power on failed\n");
+	return 0;
+}
+
+static enum drm_mode_status
+lt9611_bridge_mode_valid(struct drm_bridge *bridge,
+			    const struct drm_display_info *info,
+			    const struct drm_display_mode *mode)
+{
+	unsigned int pclk;
+
+	/* Temporary: Maximum allowable: 1080P@60Hz (148500 kHz) */
+	const unsigned int MAX_ALLOWED_PCLK = 148500;
+
+	pclk = mode->clock;
+
+	if (pclk > MAX_ALLOWED_PCLK)
+		return MODE_BAD;
+
+	return MODE_OK;
+}
+
+static void lt9611_bridge_enable(struct drm_bridge *bridge)
+{
+	struct lt9611 *lt9611;
+	int rc;
+
+	if (!bridge)
 		return;
+
+	pr_info("bridge enable\n");
+
+	lt9611 = bridge_to_lt9611(bridge);
+	if (lt9611->audio_support) {
+		pr_err("notify audio(%d)\n", EXT_DISPLAY_CABLE_CONNECT);
+		rc = hdmi_audio_register_ext_disp(lt9611);
+		if (rc) {
+			pr_err("hdmi audio register failed. rc=%d\n", rc);
+			return;
+		}
+		lt9611->ext_audio_data.intf_ops.audio_config(lt9611->ext_pdev,
+				&lt9611->ext_audio_data.codec,
+				EXT_DISPLAY_CABLE_CONNECT);
+		lt9611->ext_audio_data.intf_ops.audio_notify(lt9611->ext_pdev,
+				&lt9611->ext_audio_data.codec,
+				EXT_DISPLAY_CABLE_CONNECT);
+	}
+
+	if (!lt9611->pm_enable) {
+		lt9611_lock(lt9611);
+		lt9611_on(lt9611, true);
+		lt9611_unlock(lt9611);
 	}
 }
 
-static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611,
-						 struct device_node *dsi_node)
+static void lt9611_bridge_disable(struct drm_bridge *bridge)
 {
-	const struct mipi_dsi_device_info info = { "lt9611", 0, lt9611->dev->of_node};
-	struct mipi_dsi_device *dsi;
-	struct mipi_dsi_host *host;
-	struct device *dev = lt9611->dev;
-	int ret;
+	struct lt9611 *lt9611;
 
-	host = of_find_mipi_dsi_host_by_node(dsi_node);
-	if (!host) {
-		dev_err(lt9611->dev, "failed to find dsi host\n");
-		return ERR_PTR(-EPROBE_DEFER);
+	if (!bridge)
+		return;
+
+	lt9611 = bridge_to_lt9611(bridge);
+	dev_info(lt9611->dev, "bridge disable\n");
+
+	lt9611_lock(lt9611);
+	lt9611_on(lt9611, false);
+	lt9611_unlock(lt9611);
+
+	if (lt9611->audio_support) {
+		dev_err(lt9611->dev, "notify audio(%d)\n", EXT_DISPLAY_CABLE_DISCONNECT);
+		lt9611->ext_audio_data.intf_ops.audio_notify(lt9611->ext_pdev,
+				&lt9611->ext_audio_data.codec,
+				EXT_DISPLAY_CABLE_DISCONNECT);
+		lt9611->ext_audio_data.intf_ops.audio_config(lt9611->ext_pdev,
+				&lt9611->ext_audio_data.codec,
+				EXT_DISPLAY_CABLE_DISCONNECT);
+		hdmi_audio_deregister_ext_disp(lt9611);
 	}
+}
 
-	dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
-	if (IS_ERR(dsi)) {
-		dev_err(lt9611->dev, "failed to create dsi device\n");
-		return dsi;
+static void lt9611_pm_work(struct work_struct *work)
+{
+	struct delayed_work *lt9611_delayed_work = to_delayed_work(work);
+	struct lt9611 *lt9611 = container_of(lt9611_delayed_work, struct lt9611, pm_work);
+	unsigned int hpd_status;
+
+	lt9611_lock(lt9611);
+
+	regmap_read(lt9611->regmap, 0x825e, &hpd_status);
+
+	if ((hpd_status & 0x04) == 0x04) {
+		lt9611->hdmi_connected = true;
+		lt9611->edid_read_en = false;
+	} else {
+		lt9611->hdmi_connected = false;
 	}
 
-	dsi->lanes = 4;
-	dsi->format = MIPI_DSI_FMT_RGB888;
-	dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
-			  MIPI_DSI_MODE_VIDEO_HSE;
+	lt9611->pm_enable = false;
 
-	ret = devm_mipi_dsi_attach(dev, dsi);
-	if (ret < 0) {
-		dev_err(dev, "failed to attach dsi to host\n");
-		return ERR_PTR(ret);
+	if (lt9611->pm_work_sts) {
+		lt9611->hdmi_connected = false;
+
+		schedule_delayed_work(&lt9611->pm_work, msecs_to_jiffies(500));
+	} else {
+		enable_irq(lt9611->client->irq);
 	}
 
-	return dsi;
+	wake_up_all(&lt9611->wq);
+	schedule_work(&lt9611->work);
+
+	lt9611_unlock(lt9611);
 }
 
-static int lt9611_bridge_attach(struct drm_bridge *bridge,
-				enum drm_bridge_attach_flags flags)
+static int lt9611_pm_resume(struct device *dev)
 {
-	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+	struct lt9611 *lt9611;
+
+	if (!dev)
+		return -ENODEV;
+
+	lt9611 = dev_get_drvdata(dev);
+
+	dev_info(lt9611->dev, "bridge pm resume\n");
+
+	schedule_delayed_work(&lt9611->pm_work, msecs_to_jiffies(2000));
 
-	return drm_bridge_attach(bridge->encoder, lt9611->next_bridge,
-				 bridge, flags);
+	return 0;
 }
 
-static enum drm_mode_status lt9611_bridge_mode_valid(struct drm_bridge *bridge,
-						     const struct drm_display_info *info,
-						     const struct drm_display_mode *mode)
+static int lt9611_pm_suspend(struct device *dev)
 {
-	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+	struct lt9611 *lt9611;
 
-	if (mode->hdisplay > 3840)
-		return MODE_BAD_HVALUE;
+	if (!dev)
+		return -ENODEV;
 
-	if (mode->vdisplay > 2160)
-		return MODE_BAD_VVALUE;
+	lt9611 = dev_get_drvdata(dev);
 
-	if (mode->hdisplay == 3840 &&
-	    mode->vdisplay == 2160 &&
-	    drm_mode_vrefresh(mode) > 30)
-		return MODE_CLOCK_HIGH;
+	dev_info(lt9611->dev, "bridge pm suspend\n");
 
-	if (mode->hdisplay > 2000 && !lt9611->dsi1_node)
-		return MODE_PANEL;
-	else
-		return MODE_OK;
+	lt9611->pm_enable = true;
+	lt9611->pm_work_sts = true;
+	disable_irq(lt9611->client->irq);
+
+	return 0;
 }
 
-static void lt9611_bridge_atomic_pre_enable(struct drm_bridge *bridge,
-					    struct drm_bridge_state *old_bridge_state)
+static void lt9611_bridge_mode_set(struct drm_bridge *bridge,
+				      const struct drm_display_mode *mode,
+				      const struct drm_display_mode *adj_mode)
 {
 	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
-	static const struct reg_sequence reg_cfg[] = {
-		{ 0x8102, 0x12 },
-		{ 0x8123, 0x40 },
-		{ 0x8130, 0xea },
-		{ 0x8011, 0xfa },
-	};
 
-	if (!lt9611->sleep)
+	dev_info(lt9611->dev, "hdisplay=%d, vdisplay=%d, clock=%d\n",
+		mode->hdisplay, mode->vdisplay, mode->clock);
+	drm_mode_copy(&lt9611->curr_mode, mode);
+}
+
+static void lt9611_device_connect_status_notify(enum lt9611_connection_status status)
+{
+	const char *ptr = lt9611_status_string[status];
+	int len = strlen(ptr) + 1;
+	struct sk_buff *nl_skb;
+	struct nlmsghdr *nlh;
+	int ret;
+
+	if (!nlsk) {
+		pr_err("%s: nlsk is NULL\n", __func__);
+		return;
+	}
+
+	nl_skb = nlmsg_new(len, GFP_ATOMIC);
+	if (!nl_skb) {
+		pr_err("%s: netlink alloc failure\n", __func__);
 		return;
+	}
 
-	regmap_multi_reg_write(lt9611->regmap,
-			       reg_cfg, ARRAY_SIZE(reg_cfg));
+	nlh = nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0);
+	if (!nlh) {
+		pr_err("%s: nlmsg_put failaure\n", __func__);
+		nlmsg_free(nl_skb);
+		return;
+	}
 
-	lt9611->sleep = false;
+	memcpy(nlmsg_data(nlh), ptr, len);
+	ret = netlink_unicast(nlsk, nl_skb, 200, MSG_DONTWAIT);
+	pr_info("%s: send msg[%s] ret[%d]\n", __func__, ptr, ret);
 }
 
-static void
-lt9611_bridge_atomic_post_disable(struct drm_bridge *bridge,
-				  struct drm_bridge_state *old_bridge_state)
+static enum drm_connector_status lt9611_bridge_detect(struct drm_bridge *bridge)
 {
 	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+	unsigned int reg_val = 0;
+	int ret;
+	bool connected = true;
 
-	lt9611_sleep_setup(lt9611);
-}
+	if (lt9611->pm_work_sts) {
+		lt9611->pm_work_sts = false;
 
-static struct edid *lt9611_bridge_get_edid(struct drm_bridge *bridge,
-					   struct drm_connector *connector)
-{
-	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+		return connector_status_disconnected;
+	}
 
-	lt9611_power_on(lt9611);
-	return drm_do_get_edid(connector, lt9611_get_edid_block, lt9611);
+	lt9611_lock(lt9611);
+
+	ret = regmap_read(lt9611->regmap, 0x825e, &reg_val);
+
+	if (ret) {
+		dev_info(lt9611->dev, "failed to read hpd status: %d\n", ret);
+	} else {
+		dev_info(lt9611->dev, "success to read hpd status: %d\n", reg_val);
+		if ((reg_val & 0x04) == 0x04) {
+			connected  = true;
+			detect = 1;
+			lt9611_device_connect_status_notify(LT9611_CONNECTION);
+		} else {
+			connected  = false;
+			detect = 0;
+			lt9611_device_connect_status_notify(LT9611_DISCONNECT);
+			lt9611_on(lt9611, true);
+		}
+	}
+
+	lt9611->hdmi_connected = connected;
+
+	lt9611_unlock(lt9611);
+
+	return connected ? connector_status_connected :
+				connector_status_disconnected;
 }
 
-static void lt9611_bridge_hpd_enable(struct drm_bridge *bridge)
+static void lt9611_edid_read(struct lt9611 *lt9611)
 {
-	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
+	unsigned int reg, extended_flag;
+	u8 i, j;
 
-	lt9611_enable_hpd_interrupts(lt9611);
-}
+	lt9611_lock(lt9611);
 
-#define MAX_INPUT_SEL_FORMATS	1
+	regmap_write(lt9611->regmap, 0x8503, 0xc9);
+	/* 0xA0 is EDID device address */
+	regmap_write(lt9611->regmap, 0x8504, 0xA0);
+	/* 0x00 is EDID offset address */
+	regmap_write(lt9611->regmap, 0x8505, 0x00);
+	/* length for read */
+	regmap_write(lt9611->regmap, 0x8506, EDID_LEN);
+	regmap_write(lt9611->regmap, 0x8514, 0x7f);
 
-static u32 *
-lt9611_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
-				 struct drm_bridge_state *bridge_state,
-				 struct drm_crtc_state *crtc_state,
-				 struct drm_connector_state *conn_state,
-				 u32 output_fmt,
-				 unsigned int *num_input_fmts)
+	for (i = 0; i < EDID_LOOP; i++) {
+		regmap_write(lt9611->regmap, 0x8505, i * EDID_LEN);
+		regmap_write(lt9611->regmap, 0x8507, 0x36);
+		regmap_write(lt9611->regmap, 0x8507, 0x34);
+		regmap_write(lt9611->regmap, 0x8507, 0x37);
+		msleep(20);
+
+		regmap_read(lt9611->regmap, 0x8540, &reg);
+		/* KEY_DDC_ACCS_DONE=1 */
+		if (!(reg & 0x02))
+			break;
+
+		regmap_read(lt9611->regmap, 0x8540, &reg);
+		/* DDC No Ack or Abitration lost */
+		if (reg & 0x50)
+			break;
+
+		for (j = 0; j < EDID_LEN; j++) {
+			regmap_read(lt9611->regmap, 0x8583, &reg);
+			lt9611->edid_buf[i*EDID_LEN+j] = reg & 0xFF;
+			if ((i == 3) && (j == 30))
+				extended_flag = reg & 0x03;
+		}
+
+		if (i == 3 && extended_flag < 1)
+			/* no block 1, stop reading edid. */
+			break;
+	}
+
+	lt9611->edid_read_sts = true;
+	lt9611->edid_read_en = true;
+
+	lt9611_unlock(lt9611);
+}
+
+static int lt9611_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
 {
-	u32 *input_fmts;
+	struct lt9611 *lt9611 = data;
+	unsigned int i, j;
+	unsigned int reg;
+
+	if (len > EDID_BLOCK_SIZE || block >= EDID_NUM_BLOCKS)
+		return -EINVAL;
+
+	if (!lt9611->edid_read_en && !lt9611->edid_read_sts)
+		lt9611_edid_read(lt9611);
 
-	*num_input_fmts = 0;
+	if (block == 0) {
+		memcpy(buf, lt9611->edid_buf, len);
+	} else {
+		memcpy(buf, lt9611->edid_buf + len, len);
+		lt9611->edid_read_sts = false;
+	}
 
-	input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
-			     GFP_KERNEL);
-	if (!input_fmts)
-		return NULL;
+	return 0;
+}
 
-	/* This is the DSI-end bus format */
-	input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24;
-	*num_input_fmts = 1;
+static struct edid *lt9611_bridge_get_edid(struct drm_bridge *bridge,
+					      struct drm_connector *connector)
+{
+	struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
 
-	return input_fmts;
+	return drm_do_get_edid(connector, lt9611_get_edid_block, lt9611);
 }
 
 static const struct drm_bridge_funcs lt9611_bridge_funcs = {
 	.attach = lt9611_bridge_attach,
 	.mode_valid = lt9611_bridge_mode_valid,
+	.mode_set = lt9611_bridge_mode_set,
 	.detect = lt9611_bridge_detect,
 	.get_edid = lt9611_bridge_get_edid,
-	.hpd_enable = lt9611_bridge_hpd_enable,
-
-	.atomic_pre_enable = lt9611_bridge_atomic_pre_enable,
-	.atomic_enable = lt9611_bridge_atomic_enable,
-	.atomic_disable = lt9611_bridge_atomic_disable,
-	.atomic_post_disable = lt9611_bridge_atomic_post_disable,
-	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
-	.atomic_reset = drm_atomic_helper_bridge_reset,
-	.atomic_get_input_bus_fmts = lt9611_atomic_get_input_bus_fmts,
+	.enable = lt9611_bridge_enable,
+	.disable = lt9611_bridge_disable,
 };
 
 static int lt9611_parse_dt(struct device *dev,
-			   struct lt9611 *lt9611)
+			      struct lt9611 *lt9611)
 {
 	lt9611->dsi0_node = of_graph_get_remote_node(dev->of_node, 0, -1);
 	if (!lt9611->dsi0_node) {
@@ -914,11 +1798,10 @@
 		return -ENODEV;
 	}
 
-	lt9611->dsi1_node = of_graph_get_remote_node(dev->of_node, 1, -1);
+	lt9611->audio_support = of_property_read_bool(dev->of_node, "lt,audio-support");
+	dev_info(lt9611->dev, "audio support = %d\n", lt9611->audio_support);
 
-	lt9611->ac_mode = of_property_read_bool(dev->of_node, "lt,ac-mode");
-
-	return drm_of_find_panel_or_bridge(dev->of_node, 2, -1, NULL, &lt9611->next_bridge);
+	return 0;
 }
 
 static int lt9611_gpio_init(struct lt9611 *lt9611)
@@ -931,76 +1814,299 @@
 		return PTR_ERR(lt9611->reset_gpio);
 	}
 
-	lt9611->enable_gpio = devm_gpiod_get_optional(dev, "enable",
-						      GPIOD_OUT_LOW);
+	lt9611->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
 	if (IS_ERR(lt9611->enable_gpio)) {
 		dev_err(dev, "failed to acquire enable gpio\n");
 		return PTR_ERR(lt9611->enable_gpio);
 	}
 
+	lt9611->ocb_gpio = devm_gpiod_get_optional(dev, "ocb",
+						      GPIOD_OUT_HIGH);
+	if (IS_ERR(lt9611->ocb_gpio)) {
+		dev_err(dev, "failed to acquire ocb gpio\n");
+		return PTR_ERR(lt9611->ocb_gpio);
+	}
+
 	return 0;
 }
 
 static int lt9611_read_device_rev(struct lt9611 *lt9611)
 {
-	unsigned int rev;
+	unsigned int rev0, rev1, rev2;
 	int ret;
 
-	regmap_write(lt9611->regmap, 0x80ee, 0x01);
-	ret = regmap_read(lt9611->regmap, 0x8002, &rev);
+	lt9611_lock(lt9611);
+
+	ret = regmap_read(lt9611->regmap, 0x8002, &rev0);
+	ret |= regmap_read(lt9611->regmap, 0x8000, &rev1);
+	ret |= regmap_read(lt9611->regmap, 0x8001, &rev2);
 	if (ret)
 		dev_err(lt9611->dev, "failed to read revision: %d\n", ret);
 	else
-		dev_info(lt9611->dev, "LT9611 revision: 0x%x\n", rev);
+		dev_err(lt9611->dev, "LT9611 revision: 0x%02x.%02x.%02x\n", rev0, rev1, rev2);
+
+	lt9611_unlock(lt9611);
 
 	return ret;
 }
 
-static int lt9611_hdmi_hw_params(struct device *dev, void *data,
-				 struct hdmi_codec_daifmt *fmt,
-				 struct hdmi_codec_params *hparms)
+int lt9611_read_cec_msg(struct lt9611 *lt9611, struct cec_msg *msg)
 {
-	struct lt9611 *lt9611 = data;
+	unsigned int cec_val, cec_len, i;
+	int ret = 0;
 
-	if (hparms->sample_rate == 48000)
-		regmap_write(lt9611->regmap, 0x840f, 0x2b);
-	else if (hparms->sample_rate == 96000)
-		regmap_write(lt9611->regmap, 0x840f, 0xab);
-	else
-		return -EINVAL;
+	lt9611_lock(lt9611);
+	regmap_write(lt9611->regmap, 0x86f5, 0x01); /* lock rx data buff */
+	regmap_read(lt9611->regmap, 0x86d3, &cec_len);
+	msg->len = (cec_len > CEC_MAX_MSG_SIZE) ? CEC_MAX_MSG_SIZE : cec_len;
+
+	/* TODO: implement regmap_bulk_read */
+	for (i = 0; i < cec_len; i++) {
+		regmap_read(lt9611->regmap, 0x86d4 + i, &cec_val);
+		msg->msg[i] = cec_val;
+	}
+
+	regmap_write(lt9611->regmap, 0x86f5, 0x00); /* unlock rx data buff */
+	lt9611_unlock(lt9611);
+
+	/* TODO hexdump */
+	if (cec_len == 0) {
+		ret = -EINVAL;
+		pr_err("ERROR: CEC message length = %u, skip read CEC message.\n", cec_len);
+	} else {
+		for (i = 0; i < msg->len; i++)
+			dev_err(lt9611->dev, "received msg[%d] = %x", i, msg->msg[i]);
+	}
+
+	return ret;
+}
 
-	regmap_write(lt9611->regmap, 0x8435, 0x00);
-	regmap_write(lt9611->regmap, 0x8436, 0x18);
-	regmap_write(lt9611->regmap, 0x8437, 0x00);
+void lt9611_cec_transmit_work(struct work_struct *work)
+{
+	struct lt9611 *lt9611 = container_of(work, struct lt9611,
+					cec_transmit_work);
+
+	dev_info(lt9611->dev, "cec_status 0x%x : cec_tx_data %0x\n",
+			lt9611->cec_status, lt9611->cec_tx_data);
+	if ((lt9611->cec_tx_data == 0x44) || (lt9611->cec_tx_data == 0x88)
+			|| (lt9611->cec_tx_data == 0xbb)) {
+		lt9611->cec_tx_data = 0x00;
+		cec_transmit_attempt_done(lt9611->cec_adapter, CEC_TX_STATUS_NACK);
+		return;
+	}
+
+	if (lt9611->cec_status & BIT(2))
+		cec_transmit_attempt_done(lt9611->cec_adapter, CEC_TX_STATUS_NACK);
+	else if (lt9611->cec_status & BIT(0))
+		cec_transmit_attempt_done(lt9611->cec_adapter, CEC_TX_STATUS_OK);
+}
 
+void lt9611_cec_recv_work(struct work_struct *work)
+{
+	struct lt9611 *lt9611 = container_of(work, struct lt9611, cec_recv_work);
+	struct cec_msg cec_msg = {};
+
+	if (!lt9611->cec_status) {
+		dev_err(lt9611->dev, "cec message is receiving\n");
+		return;
+	}
+
+	if (lt9611_read_cec_msg(lt9611, &cec_msg) == 0)
+		cec_received_msg(lt9611->cec_adapter, &cec_msg);
+}
+
+static int lt9611_cec_enable(struct cec_adapter *adap, bool enable)
+{
+	struct lt9611 *lt9611 = cec_get_drvdata(adap);
+
+	lt9611->cec_en = enable;
 	return 0;
 }
 
-static int lt9611_audio_startup(struct device *dev, void *data)
+static int lt9611_cec_log_addr(struct cec_adapter *adap, u8 logical_addr)
 {
-	struct lt9611 *lt9611 = data;
+	struct lt9611 *lt9611 = cec_get_drvdata(adap);
+	unsigned int reg0 = 0x00, reg1 = 0x80;
 
-	regmap_write(lt9611->regmap, 0x82d6, 0x8c);
-	regmap_write(lt9611->regmap, 0x82d7, 0x04);
+	pr_info("%s: Enter , cec_log_addr 0x%x\n", __func__, logical_addr);
+	lt9611->cec_log_addr = logical_addr;
+	if (logical_addr != CEC_LOG_ADDR_INVALID) {
+		switch (logical_addr) {
+		case 0:
+			reg0 = 0x01;
+			reg1 = 0x00;
+			break;
+		case 1:
+			reg0 = 0x02;
+			reg1 = 0x00;
+			break;
+		case 2:
+			reg0 = 0x03;
+			reg1 = 0x00;
+			break;
+		case 3:
+			reg0 = 0x04;
+			reg1 = 0x00;
+			break;
+		case 4:
+			reg0 = 0x10;
+			reg1 = 0x00;
+			break;
+		case 5:
+			reg0 = 0x20;
+			reg1 = 0x00;
+			break;
+		case 6:
+			reg0 = 0x30;
+			reg1 = 0x00;
+			break;
+		case 7:
+			reg0 = 0x40;
+			reg1 = 0x00;
+			break;
+		case 8:
+			reg0 = 0x00;
+			reg1 = 0x01;
+			break;
+		case 9:
+			reg0 = 0x00;
+			reg1 = 0x02;
+			break;
+		case 10:
+			reg0 = 0x00;
+			reg1 = 0x03;
+			break;
+		case 11:
+			reg0 = 0x00;
+			reg1 = 0x04;
+			break;
+		case 12:
+			reg0 = 0x00;
+			reg1 = 0x10;
+			break;
+		case 13:
+			reg0 = 0x00;
+			reg1 = 0x20;
+			break;
+		case 14:
+			reg0 = 0x00;
+			reg1 = 0x30;
+			break;
+		case 15:
+			reg0 = 0x00;
+			reg1 = 0x40;
+			break;
+		default:
+			break;
+		}
 
-	regmap_write(lt9611->regmap, 0x8406, 0x08);
-	regmap_write(lt9611->regmap, 0x8407, 0x10);
+		lt9611_lock(lt9611);
+		regmap_write(lt9611->regmap, 0x86f7, reg0);
+		regmap_write(lt9611->regmap, 0x86f8, reg1);
+		lt9611_unlock(lt9611);
+	}
+
+	return 0;
+}
+
+static int lt9611_cec_transmit(struct cec_adapter *adap, u8 attempts,
+		u32 signal_free_time, struct cec_msg *msg)
+{
+	int i;
+	struct lt9611 *lt9611 = cec_get_drvdata(adap);
+	unsigned int len = (msg->len > CEC_MAX_MSG_SIZE) ? CEC_MAX_MSG_SIZE : msg->len;
+
+	lt9611_lock(lt9611);
+	regmap_write(lt9611->regmap, 0x86f5, 0x01); /* lock rx data buff */
+	regmap_write(lt9611->regmap, 0x86f4, len);
+
+	/* TODO check regmap_bulk_write */
+	for (i = 0; i < len; i++)
+		regmap_write(lt9611->regmap, 0x86e4 + i, msg->msg[i]);
+
+	regmap_write(lt9611->regmap, 0x86f9, 0x03); /* start send msg */
+	msleep(25 * i);
+	regmap_write(lt9611->regmap, 0x86f5, 0x00); /* unlock rx data buff */
+	regmap_write(lt9611->regmap, 0x86f9, 0x02);
+	lt9611_unlock(lt9611);
+
+	lt9611->cec_tx_data = msg->msg[0];
 
-	regmap_write(lt9611->regmap, 0x8434, 0xd5);
+	/* TODO: check hexdump */
+	for (i = 0; i < len; i++)
+		dev_err(lt9611->dev, "cec transmit msg[%d] = %x\n", i, msg->msg[i]);
 
 	return 0;
 }
 
+struct cec_adap_ops lt9611_cec_ops = {
+	.adap_enable = lt9611_cec_enable,
+	.adap_log_addr = lt9611_cec_log_addr,
+	.adap_transmit = lt9611_cec_transmit,
+};
+
+static int lt9611_cec_adap_init(struct lt9611 *lt9611)
+{
+	int ret = 0;
+	struct cec_adapter *adap = NULL;
+	unsigned int cec_flags = CEC_CAP_DEFAULTS;
+
+	adap = cec_allocate_adapter(&lt9611_cec_ops, lt9611,
+			"lt9611_cec", cec_flags, 1);
+	if (!adap) {
+		dev_err(lt9611->dev, "cec adapter allocate failed\n");
+		return -ENOMEM;
+	}
+
+	lt9611->cec_notifier = cec_notifier_cec_adap_register(lt9611->dev,
+						NULL, adap);
+	if (!lt9611->cec_notifier) {
+		dev_err(lt9611->dev, "get cec notifier failed\n");
+		cec_delete_adapter(adap);
+		lt9611->cec_adapter = NULL;
+		lt9611->cec_support = false;
+		lt9611->cec_en = false;
+		return -ENOMEM;
+	}
+
+	ret = cec_register_adapter(adap, lt9611->dev);
+	if (ret != 0) {
+		dev_err(lt9611->dev, "register cec adapter failed\n");
+		cec_delete_adapter(adap);
+		lt9611->cec_adapter = NULL;
+		lt9611->cec_support = false;
+		lt9611->cec_en = false;
+	} else {
+		dev_err(lt9611->dev, "CEC adapter registered\n");
+		lt9611->cec_en = true;
+		lt9611->cec_support = true;
+		lt9611->cec_log_addr = CEC_LOG_ADDR_PLAYBACK_1;
+
+		lt9611->cec_adapter = adap;
+		cec_s_log_addrs(lt9611->cec_adapter, NULL, false);
+	}
+
+	return ret;
+}
+
+static int lt9611_hdmi_hw_params(struct device *dev, void *data,
+				    struct hdmi_codec_daifmt *fmt,
+				    struct hdmi_codec_params *hparms)
+{
+	/*
+	 * LT9611 will automatically detect rate and sample size, so no need
+	 * to setup anything here.
+	 */
+	return 0;
+}
+
 static void lt9611_audio_shutdown(struct device *dev, void *data)
 {
-	struct lt9611 *lt9611 = data;
 
-	regmap_write(lt9611->regmap, 0x8406, 0x00);
-	regmap_write(lt9611->regmap, 0x8407, 0x00);
 }
 
 static int lt9611_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
-				      struct device_node *endpoint)
+					 struct device_node *endpoint)
 {
 	struct of_endpoint of_ep;
 	int ret;
@@ -1022,19 +2128,18 @@
 static const struct hdmi_codec_ops lt9611_codec_ops = {
 	.hw_params	= lt9611_hdmi_hw_params,
 	.audio_shutdown = lt9611_audio_shutdown,
-	.audio_startup	= lt9611_audio_startup,
 	.get_dai_id	= lt9611_hdmi_i2s_get_dai_id,
 };
 
-static struct hdmi_codec_pdata codec_data = {
-	.ops = &lt9611_codec_ops,
-	.max_i2s_channels = 8,
-	.i2s = 1,
-};
-
 static int lt9611_audio_init(struct device *dev, struct lt9611 *lt9611)
 {
-	codec_data.data = lt9611;
+	struct hdmi_codec_pdata codec_data = {
+		.ops = &lt9611_codec_ops,
+		.max_i2s_channels = 2,
+		.i2s = 1,
+		.data = lt9611,
+	};
+
 	lt9611->audio_pdev =
 		platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
 					      PLATFORM_DEVID_AUTO,
@@ -1051,6 +2156,84 @@
 	}
 }
 
+static ssize_t send_cec_msg_store(struct device *dev,
+	struct device_attribute *attr, const char *buf,
+	size_t count)
+{
+	int i, value, ret;
+	u8 len = (u8) strlen(buf);
+	__u8 msg[CEC_MAX_MSG_SIZE];
+	size_t j;
+	char hex[3];
+	struct lt9611 *lt9611 = dev_get_drvdata(dev);
+
+	if (!lt9611) {
+		pr_err("lt9611 is NULL\n");
+		return -EINVAL;
+	}
+
+	memset(msg, 0, CEC_MAX_MSG_SIZE);
+
+	len = (len > CEC_MAX_MSG_SIZE) ? 16 : len;
+	len = len / 2;
+	for (j = 0; j < len; j++) {
+		strscpy(hex, buf + j*2, 2);
+		hex[2] = '\0';
+
+		ret = sscanf(hex, "%x", &value);
+		if (ret != 1) {
+			pr_err("ERROR: sscanf failed, ret = %d\n", ret);
+			return -EINVAL;
+		}
+		msg[j] = (__u8)value;
+	}
+
+	lt9611_lock(lt9611);
+
+	regmap_write(lt9611->regmap, 0x86f5, 0x01); /* lock rx data buff */
+	regmap_write(lt9611->regmap, 0x86f4, len);
+
+	for (i = 0; i < len; i++)
+		regmap_write(lt9611->regmap, 0x86e4 + i, msg[i]);
+
+	regmap_write(lt9611->regmap, 0x86f9, 0x03); /* start send msg */
+	msleep(25 * i);
+	regmap_write(lt9611->regmap, 0x86f5, 0x00); /* unlock rx data buff */
+	regmap_write(lt9611->regmap, 0x86f9, 0x02);
+
+	lt9611_unlock(lt9611);
+
+	/* To check what message sent */
+	for (i = 0; i < len; i++)
+		pr_err("lt9611 transmitting msg[%d] = %x\n", i, msg[i]);
+
+	return count;
+}
+
+static ssize_t detect_info_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	return snprintf(buf, 4, "%d\n", detect);
+}
+
+static DEVICE_ATTR_WO(send_cec_msg);
+static DEVICE_ATTR_RO(detect_info);
+
+static struct attribute *lt9611_attrs[] = {
+	&dev_attr_send_cec_msg.attr,
+	&dev_attr_detect_info.attr,
+	NULL,
+};
+
+static const struct attribute_group lt9611_attr_group = {
+	.attrs = lt9611_attrs,
+};
+
+static const struct attribute_group *lt9611_attr_groups[] = {
+	&lt9611_attr_group,
+	NULL,
+};
+
 static int lt9611_probe(struct i2c_client *client)
 {
 	struct lt9611 *lt9611;
@@ -1068,7 +2251,7 @@
 
 	lt9611->dev = dev;
 	lt9611->client = client;
-	lt9611->sleep = false;
+	mutex_init(&lt9611->ocm_lock);
 
 	lt9611->regmap = devm_regmap_init_i2c(client, &lt9611_regmap_config);
 	if (IS_ERR(lt9611->regmap)) {
@@ -1096,17 +2279,27 @@
 	if (ret)
 		goto err_of_put;
 
+	lt9611->mipi_lane_counts = MIPI_4LANE;
+	lt9611->mipi_port_counts = MIPI_1PORT;
+	lt9611->audio_out_intf = I2S;
+	lt9611->power_on = false;
+
 	lt9611_reset(lt9611);
 
 	ret = lt9611_read_device_rev(lt9611);
-	if (ret) {
+	if (ret)
 		dev_err(dev, "failed to read chip rev\n");
-		goto err_disable_regulators;
-	}
+
+	init_waitqueue_head(&lt9611->wq);
+	INIT_WORK(&lt9611->work, lt9611_hpd_work);
+	INIT_WORK(&lt9611->cec_recv_work, lt9611_cec_recv_work);
+	INIT_WORK(&lt9611->cec_transmit_work, lt9611_cec_transmit_work);
+
+	INIT_DELAYED_WORK(&lt9611->pm_work, lt9611_pm_work);
 
 	ret = devm_request_threaded_irq(dev, client->irq, NULL,
 					lt9611_irq_thread_handler,
-					IRQF_ONESHOT, "lt9611", lt9611);
+					IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "lt9611", lt9611);
 	if (ret) {
 		dev_err(dev, "failed to request irq\n");
 		goto err_disable_regulators;
@@ -1116,8 +2309,14 @@
 
 	lt9611->bridge.funcs = &lt9611_bridge_funcs;
 	lt9611->bridge.of_node = client->dev.of_node;
-	lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
-			     DRM_BRIDGE_OP_HPD | DRM_BRIDGE_OP_MODES;
+	lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_MODES | DRM_BRIDGE_OP_HPD;
+
+	ret = lt9611_cec_adap_init(lt9611);
+	if (ret)
+		dev_err(dev, "CEC init failed. ret=%d\n", ret);
+	else
+		dev_info(dev, "CEC init success\n");
+
 	lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
 
 	drm_bridge_add(&lt9611->bridge);
@@ -1129,31 +2328,26 @@
 		goto err_remove_bridge;
 	}
 
-	/* Attach secondary DSI, if specified */
-	if (lt9611->dsi1_node) {
-		lt9611->dsi1 = lt9611_attach_dsi(lt9611, lt9611->dsi1_node);
-		if (IS_ERR(lt9611->dsi1)) {
-			ret = PTR_ERR(lt9611->dsi1);
-			goto err_remove_bridge;
-		}
-	}
-
-	lt9611_enable_hpd_interrupts(lt9611);
+	nlsk = netlink_kernel_create(&init_net, NETLINK_TEST, NULL);
+	if (!nlsk)
+		pr_err("%s: netlink_kernel_create error !\n", __func__);
 
-	ret = lt9611_audio_init(dev, lt9611);
-	if (ret)
-		goto err_remove_bridge;
-
-	return 0;
+	return lt9611_audio_init(dev, lt9611);
 
 err_remove_bridge:
+	disable_irq(client->irq);
+	cancel_work_sync(&lt9611->work);
+	cancel_work_sync(&lt9611->cec_recv_work);
+	cancel_work_sync(&lt9611->cec_transmit_work);
+	cancel_delayed_work_sync(&lt9611->pm_work);
 	drm_bridge_remove(&lt9611->bridge);
+	if (lt9611->cec_adapter)
+		cec_unregister_adapter(lt9611->cec_adapter);
 
 err_disable_regulators:
 	regulator_bulk_disable(ARRAY_SIZE(lt9611->supplies), lt9611->supplies);
 
 err_of_put:
-	of_node_put(lt9611->dsi1_node);
 	of_node_put(lt9611->dsi0_node);
 
 	return ret;
@@ -1164,31 +2358,45 @@
 	struct lt9611 *lt9611 = i2c_get_clientdata(client);
 
 	disable_irq(client->irq);
+	cancel_work_sync(&lt9611->work);
 	lt9611_audio_exit(lt9611);
 	drm_bridge_remove(&lt9611->bridge);
+	/* TODO check order of closing wq */
+	cancel_work_sync(&lt9611->cec_recv_work);
+	cancel_work_sync(&lt9611->cec_transmit_work);
+	cancel_delayed_work_sync(&lt9611->pm_work);
+	if (lt9611->cec_adapter)
+		cec_unregister_adapter(lt9611->cec_adapter);
+
+	mutex_destroy(&lt9611->ocm_lock);
 
 	regulator_bulk_disable(ARRAY_SIZE(lt9611->supplies), lt9611->supplies);
 
-	of_node_put(lt9611->dsi1_node);
 	of_node_put(lt9611->dsi0_node);
 }
 
 static struct i2c_device_id lt9611_id[] = {
 	{ "lontium,lt9611", 0 },
-	{}
+	{ /* sentinel */ }
 };
-MODULE_DEVICE_TABLE(i2c, lt9611_id);
 
 static const struct of_device_id lt9611_match_table[] = {
 	{ .compatible = "lontium,lt9611" },
-	{ }
+	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, lt9611_match_table);
 
+static const struct dev_pm_ops lt9611_pm_ops = {
+	.suspend = lt9611_pm_suspend,
+	.resume = lt9611_pm_resume,
+};
+
 static struct i2c_driver lt9611_driver = {
 	.driver = {
 		.name = "lt9611",
 		.of_match_table = lt9611_match_table,
+		.dev_groups = lt9611_attr_groups,
+		.pm = &lt9611_pm_ops,
 	},
 	.probe = lt9611_probe,
 	.remove = lt9611_remove,
@@ -1196,4 +2404,7 @@
 };
 module_i2c_driver(lt9611_driver);
 
+MODULE_AUTHOR("Dmitry Baryshkov <dmitry.baryshkov@linaro.org>");
+MODULE_AUTHOR("Tongtong Li <tongtong.li@thundersoft.com>");
+MODULE_AUTHOR("Hongyang zhao <hongyang.zhao@thundersoft.com>");
 MODULE_LICENSE("GPL v2");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/lontium-lt9611uxc.c
@@ -87,7 +87,9 @@
 
 struct lt9611uxc_mode {
 	u16 hdisplay;
+	u16 htotal;
 	u16 vdisplay;
+	u16 vtotal;
 	u8 vrefresh;
 };
 
@@ -96,22 +98,22 @@
  * Enumerate them here to check whether the mode is supported.
  */
 static struct lt9611uxc_mode lt9611uxc_modes[] = {
-	{ 1920, 1080, 60 },
-	{ 1920, 1080, 30 },
-	{ 1920, 1080, 25 },
-	{ 1366, 768, 60 },
-	{ 1360, 768, 60 },
-	{ 1280, 1024, 60 },
-	{ 1280, 800, 60 },
-	{ 1280, 720, 60 },
-	{ 1280, 720, 50 },
-	{ 1280, 720, 30 },
-	{ 1152, 864, 60 },
-	{ 1024, 768, 60 },
-	{ 800, 600, 60 },
-	{ 720, 576, 50 },
-	{ 720, 480, 60 },
-	{ 640, 480, 60 },
+	{ 1920, 2200, 1080, 1125, 60 },
+	{ 1920, 2200, 1080, 1125, 30 },
+	{ 1920, 2640, 1080, 1125, 25 },
+	{ 1366, 1792, 768, 798, 60 },
+	{ 1360, 1792, 768, 795, 60 },
+	{ 1280, 1688, 1024, 1066, 60 },
+	{ 1280, 1680, 800, 831, 60 },
+	{ 1280, 1650, 720, 750, 60 },
+	{ 1280, 1980, 720, 750, 50 },
+	{ 1280, 3300, 720, 750, 30 },
+	{ 1152, 1600, 864, 900, 60 },
+	{ 1024, 1344, 768, 806, 60 },
+	{ 800, 1056, 600, 628, 60 },
+	{ 720, 864, 576, 625, 50 },
+	{ 720, 858, 480, 525, 60 },
+	{ 640, 800, 480, 525, 60 },
 };
 
 static struct lt9611uxc *bridge_to_lt9611uxc(struct drm_bridge *bridge)
@@ -246,7 +248,9 @@
 
 	for (i = 0; i < ARRAY_SIZE(lt9611uxc_modes); i++) {
 		if (lt9611uxc_modes[i].hdisplay == mode->hdisplay &&
+		    lt9611uxc_modes[i].htotal == mode->htotal &&
 		    lt9611uxc_modes[i].vdisplay == mode->vdisplay &&
+		    lt9611uxc_modes[i].vtotal == mode->vtotal &&
 		    lt9611uxc_modes[i].vrefresh == drm_mode_vrefresh(mode)) {
 			return &lt9611uxc_modes[i];
 		}
@@ -265,10 +269,8 @@
 	int ret;
 
 	host = of_find_mipi_dsi_host_by_node(dsi_node);
-	if (!host) {
-		dev_err(dev, "failed to find dsi host\n");
-		return ERR_PTR(-EPROBE_DEFER);
-	}
+	if (!host)
+		return ERR_PTR(dev_err_probe(dev, -EPROBE_DEFER, "failed to find dsi host\n"));
 
 	dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
 	if (IS_ERR(dsi)) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/panel.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/panel.c
@@ -358,9 +358,12 @@
 
 static void devm_drm_panel_bridge_release(struct device *dev, void *res)
 {
-	struct drm_bridge **bridge = res;
+	struct drm_bridge *bridge = *(struct drm_bridge **)res;
 
-	drm_panel_bridge_remove(*bridge);
+	if (!bridge)
+		return;
+
+	drm_bridge_remove(bridge);
 }
 
 /**
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/samsung-dsim.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -573,8 +573,8 @@
 	u16 _m, best_m;
 	u8 _s, best_s;
 
-	p_min = DIV_ROUND_UP(fin, (12 * MHZ));
-	p_max = fin / (6 * MHZ);
+	p_min = DIV_ROUND_UP(fin, (driver_data->pll_fin_max * MHZ));
+	p_max = fin / (driver_data->pll_fin_min * MHZ);
 
 	for (_p = p_min; _p <= p_max; ++_p) {
 		for (_s = 0; _s <= 5; ++_s) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/tc358767.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/tc358767.c
@@ -1579,6 +1579,13 @@
 				struct drm_connector *connector)
 {
 	struct tc_data *tc = bridge_to_tc(bridge);
+	int ret;
+
+	ret = tc_get_display_props(tc);
+	if (ret < 0) {
+		dev_err(tc->dev, "failed to read display props: %d\n", ret);
+		return 0;
+	}
 
 	return drm_get_edid(connector, &tc->aux.ddc);
 }
@@ -2034,7 +2041,7 @@
 		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.
 		 *
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/tc358768.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/tc358768.c
@@ -125,6 +125,9 @@
 #define TC358768_DSI_CONFW_MODE_CLR	(6 << 29)
 #define TC358768_DSI_CONFW_ADDR_DSI_CONTROL	(0x3 << 24)
 
+/* TC358768_DSICMD_TX (0x0600) register */
+#define TC358768_DSI_CMDTX_DC_START	BIT(0)
+
 static const char * const tc358768_supplies[] = {
 	"vddc", "vddmipi", "vddio"
 };
@@ -229,6 +232,21 @@
 		tc358768_write(priv, reg, tmp);
 }
 
+static void tc358768_dsicmd_tx(struct tc358768_priv *priv)
+{
+	u32 val;
+
+	/* start transfer */
+	tc358768_write(priv, TC358768_DSICMD_TX, TC358768_DSI_CMDTX_DC_START);
+	if (priv->error)
+		return;
+
+	/* wait transfer completion */
+	priv->error = regmap_read_poll_timeout(priv->regmap, TC358768_DSICMD_TX, val,
+					       (val & TC358768_DSI_CMDTX_DC_START) == 0,
+					       100, 100000);
+}
+
 static int tc358768_sw_reset(struct tc358768_priv *priv)
 {
 	/* Assert Reset */
@@ -516,8 +534,7 @@
 		}
 	}
 
-	/* start transfer */
-	tc358768_write(priv, TC358768_DSICMD_TX, 1);
+	tc358768_dsicmd_tx(priv);
 
 	ret = tc358768_clear_error(priv);
 	if (ret)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/tc358775.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/tc358775.c
@@ -454,10 +454,6 @@
 	dev_dbg(tc->dev, "bus_formats %04x bpc %d\n",
 		connector->display_info.bus_formats[0],
 		tc->bpc);
-	/*
-	 * Default hardware register settings of tc358775 configured
-	 * with MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA jeida-24 format
-	 */
 	if (connector->display_info.bus_formats[0] ==
 		MEDIA_BUS_FMT_RGB888_1X7X4_SPWG) {
 		/* VESA-24 */
@@ -468,14 +464,15 @@
 		d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B6, LVI_B7, LVI_B1, LVI_B2));
 		d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, LVI_L0));
 		d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_R6));
-	} else { /*  MEDIA_BUS_FMT_RGB666_1X7X3_SPWG - JEIDA-18 */
-		d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, LVI_R3));
-		d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R4, LVI_L0, LVI_R5, LVI_G0));
-		d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_L0, LVI_L0));
-		d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G3, LVI_G4, LVI_G5, LVI_B0));
-		d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_L0, LVI_L0, LVI_B1, LVI_B2));
-		d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, LVI_L0));
-		d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_L0));
+	} else {
+		/* JEIDA-18 and JEIDA-24 */
+		d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R2, LVI_R3, LVI_R4, LVI_R5));
+		d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R6, LVI_R1, LVI_R7, LVI_G2));
+		d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G3, LVI_G4, LVI_G0, LVI_G1));
+		d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G5, LVI_G6, LVI_G7, LVI_B2));
+		d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B0, LVI_B1, LVI_B3, LVI_B4));
+		d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B5, LVI_B6, LVI_B7, LVI_L0));
+		d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_R0));
 	}
 
 	d2l_write(tc->i2c, VFUEN, VFUEN_EN);
@@ -610,10 +607,8 @@
 						};
 
 	host = of_find_mipi_dsi_host_by_node(tc->host_node);
-	if (!host) {
-		dev_err(dev, "failed to find dsi host\n");
-		return -EPROBE_DEFER;
-	}
+	if (!host)
+		return dev_err_probe(dev, -EPROBE_DEFER, "failed to find dsi host\n");
 
 	dsi = devm_mipi_dsi_device_register_full(dev, host, &info);
 	if (IS_ERR(dsi)) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/ti-dlpc3433.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/ti-dlpc3433.c
@@ -319,12 +319,11 @@
 		.channel = 0,
 		.node = NULL,
 	};
+	int ret;
 
 	host = of_find_mipi_dsi_host_by_node(dlpc->host_node);
-	if (!host) {
-		DRM_DEV_ERROR(dev, "failed to find dsi host\n");
-		return -EPROBE_DEFER;
-	}
+	if (!host)
+		return dev_err_probe(dev, -EPROBE_DEFER, "failed to find dsi host\n");
 
 	dlpc->dsi = mipi_dsi_device_register_full(host, &info);
 	if (IS_ERR(dlpc->dsi)) {
@@ -336,7 +335,11 @@
 	dlpc->dsi->format = MIPI_DSI_FMT_RGB565;
 	dlpc->dsi->lanes = dlpc->dsi_lanes;
 
-	return devm_mipi_dsi_attach(dev, dlpc->dsi);
+	ret = devm_mipi_dsi_attach(dev, dlpc->dsi);
+	if (ret)
+		DRM_DEV_ERROR(dev, "failed to attach dsi host\n");
+
+	return ret;
 }
 
 static int dlpc3433_probe(struct i2c_client *client)
@@ -367,10 +370,8 @@
 	drm_bridge_add(&dlpc->bridge);
 
 	ret = dlpc_host_attach(dlpc);
-	if (ret) {
-		DRM_DEV_ERROR(dev, "failed to attach dsi host\n");
+	if (ret)
 		goto err_remove_bridge;
-	}
 
 	return 0;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -478,7 +478,6 @@
 		dev_err(ctx->dev, "failed to lock PLL, ret=%i\n", ret);
 		/* On failure, disable PLL again and exit. */
 		regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00);
-		regulator_disable(ctx->vcc);
 		return;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/bridge/ti-sn65dsi86.c
@@ -1591,7 +1591,6 @@
 	pdata->pchip.ops = &ti_sn_pwm_ops;
 	pdata->pchip.npwm = 1;
 	pdata->pchip.of_xlate = of_pwm_single_xlate;
-	pdata->pchip.of_pwm_n_cells = 1;
 
 	devm_pm_runtime_enable(&adev->dev);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/ci/gitlab-ci.yml
+++ linux-qcom-6.8.0/drivers/gpu/drm/ci/gitlab-ci.yml
@@ -1,6 +1,6 @@
 variables:
   DRM_CI_PROJECT_PATH: &drm-ci-project-path mesa/mesa
-  DRM_CI_COMMIT_SHA: &drm-ci-commit-sha edfbf74df1d4d6ce54ffe24566108be0e1a98c3d
+  DRM_CI_COMMIT_SHA: &drm-ci-commit-sha 9d162de9a05155e1c4041857a5848842749164cf
 
   UPSTREAM_REPO: git://anongit.freedesktop.org/drm/drm
   TARGET_BRANCH: drm-next
@@ -25,7 +25,9 @@
   # per-job artifact storage on MinIO
   JOB_ARTIFACTS_BASE: ${PIPELINE_ARTIFACTS_BASE}/${CI_JOB_ID}
   # default kernel for rootfs before injecting the current kernel tree
-  KERNEL_IMAGE_BASE: https://${S3_HOST}/mesa-lava/gfx-ci/linux/v6.4.12-for-mesa-ci-f6b4ad45f48d
+  KERNEL_REPO: "gfx-ci/linux"
+  KERNEL_TAG: "v6.6.4-for-mesa-ci-e4f4c500f7fb"
+  KERNEL_IMAGE_BASE: https://${S3_HOST}/mesa-lava/${KERNEL_REPO}/${KERNEL_TAG}
   LAVA_TAGS: subset-1-gfx
   LAVA_JOB_PRIORITY: 30
 
@@ -133,6 +135,11 @@
     - if: &is-pre-merge-for-marge '$GITLAB_USER_LOGIN == "marge-bot" && $CI_PIPELINE_SOURCE == "merge_request_event"'
       when: on_success
 
+.never-post-merge-rules:
+  rules:
+    - if: *is-post-merge
+      when: never
+
 # Rule to filter for only scheduled pipelines.
 .scheduled_pipeline-rules:
   rules:
@@ -150,6 +157,7 @@
 .build-rules:
   rules:
     - !reference [.no_scheduled_pipelines-rules, rules]
+    - !reference [.never-post-merge-rules, rules]
     # Run automatically once all dependency jobs have passed
     - when: on_success
 
@@ -157,6 +165,7 @@
 .container+build-rules:
   rules:
     - !reference [.no_scheduled_pipelines-rules, rules]
+    - !reference [.never-post-merge-rules, rules]
     - when: manual
 
 .ci-deqp-artifacts:
@@ -175,6 +184,7 @@
 .container-rules:
   rules:
     - !reference [.no_scheduled_pipelines-rules, rules]
+    - !reference [.never-post-merge-rules, rules]
     # Run pipeline by default in the main project if any CI pipeline
     # configuration files were changed, to ensure docker images are up to date
     - if: *is-post-merge
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/ci/test.yml
+++ linux-qcom-6.8.0/drivers/gpu/drm/ci/test.yml
@@ -104,7 +104,10 @@
     DRIVER_NAME: msm
     BM_DTB: https://${PIPELINE_ARTIFACTS_BASE}/arm64/apq8016-sbc-usb-host.dtb
     GPU_VERSION: apq8016
-    BM_CMDLINE: "ip=dhcp console=ttyMSM0,115200n8 $BM_KERNEL_EXTRA_ARGS root=/dev/nfs rw nfsrootdebug nfsroot=,tcp,nfsvers=4.2 init=/init $BM_KERNELARGS"
+    # disabling unused clocks congests with the MDSS runtime PM trying to
+    # disable those clocks and causes boot to fail.
+    # Reproducer: DRM_MSM=y, DRM_I2C_ADV7511=m
+    BM_KERNEL_EXTRA_ARGS: clk_ignore_unused
     RUNNER_TAG: google-freedreno-db410c
   script:
     - ./install/bare-metal/fastboot.sh
@@ -234,11 +237,11 @@
 i915:tgl:
   extends:
     - .i915
-  parallel: 8
+  parallel: 5
   variables:
-    DEVICE_TYPE: asus-cx9400-volteer
+    DEVICE_TYPE: acer-cp514-2h-1130g7-volteer
     GPU_VERSION: tgl
-    RUNNER_TAG: mesa-ci-x86-64-lava-asus-cx9400-volteer
+    RUNNER_TAG: mesa-ci-x86-64-lava-acer-cp514-2h-1130g7-volteer
 
 .amdgpu:
   extends:
@@ -324,6 +327,7 @@
     GPU_VERSION: none
   extends:
     - .test-gl
+    - .test-rules
   tags:
     - kvm
   script:
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/display/drm_dp_cec.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/display/drm_dp_cec.c
@@ -311,16 +311,6 @@
 	if (!aux->transfer)
 		return;
 
-#ifndef CONFIG_MEDIA_CEC_RC
-	/*
-	 * CEC_CAP_RC is part of CEC_CAP_DEFAULTS, but it is stripped by
-	 * cec_allocate_adapter() if CONFIG_MEDIA_CEC_RC is undefined.
-	 *
-	 * Do this here as well to ensure the tests against cec_caps are
-	 * correct.
-	 */
-	cec_caps &= ~CEC_CAP_RC;
-#endif
 	cancel_delayed_work_sync(&aux->cec.unregister_work);
 
 	mutex_lock(&aux->cec.lock);
@@ -337,7 +327,9 @@
 		num_las = CEC_MAX_LOG_ADDRS;
 
 	if (aux->cec.adap) {
-		if (aux->cec.adap->capabilities == cec_caps &&
+		/* Check if the adapter properties have changed */
+		if ((aux->cec.adap->capabilities & CEC_CAP_MONITOR_ALL) ==
+		    (cec_caps & CEC_CAP_MONITOR_ALL) &&
 		    aux->cec.adap->available_log_addrs == num_las) {
 			/* Unchanged, so just set the phys addr */
 			cec_s_phys_addr(aux->cec.adap, source_physical_address, false);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/display/drm_dp_dual_mode_helper.c
@@ -160,11 +160,11 @@
 
 static bool is_hdmi_adaptor(const char hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN])
 {
-	static const char dp_dual_mode_hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN] =
+	static const char dp_dual_mode_hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN + 1] =
 		"DP-HDMI ADAPTOR\x04";
 
 	return memcmp(hdmi_id, dp_dual_mode_hdmi_id,
-		      sizeof(dp_dual_mode_hdmi_id)) == 0;
+		      DP_DUAL_MODE_HDMI_ID_LEN) == 0;
 }
 
 static bool is_type1_adaptor(uint8_t adaptor_id)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/display/drm_dp_helper.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/display/drm_dp_helper.c
@@ -533,6 +533,15 @@
 	mutex_lock(&aux->hw_mutex);
 
 	/*
+	 * If the device attached to the aux bus is powered down then there's
+	 * no reason to attempt a transfer. Error out immediately.
+	 */
+	if (aux->powered_down) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	/*
 	 * The specification doesn't give any recommendation on how often to
 	 * retry native transactions. We used to retry 7 times like for
 	 * aux i2c transactions but real world devices this wasn't
@@ -600,6 +609,29 @@
 EXPORT_SYMBOL(drm_dp_dpcd_probe);
 
 /**
+ * drm_dp_dpcd_set_powered() - Set whether the DP device is powered
+ * @aux: DisplayPort AUX channel; for convenience it's OK to pass NULL here
+ *       and the function will be a no-op.
+ * @powered: true if powered; false if not
+ *
+ * If the endpoint device on the DP AUX bus is known to be powered down
+ * then this function can be called to make future transfers fail immediately
+ * instead of needing to time out.
+ *
+ * If this function is never called then a device defaults to being powered.
+ */
+void drm_dp_dpcd_set_powered(struct drm_dp_aux *aux, bool powered)
+{
+	if (!aux)
+		return;
+
+	mutex_lock(&aux->hw_mutex);
+	aux->powered_down = !powered;
+	mutex_unlock(&aux->hw_mutex);
+}
+EXPORT_SYMBOL(drm_dp_dpcd_set_powered);
+
+/**
  * drm_dp_dpcd_read() - read a series of bytes from the DPCD
  * @aux: DisplayPort AUX channel (SST or MST)
  * @offset: address of the (first) register to read
@@ -1858,6 +1890,9 @@
 	struct drm_dp_aux_msg msg;
 	int err = 0;
 
+	if (aux->powered_down)
+		return -EBUSY;
+
 	dp_aux_i2c_transfer_size = clamp(dp_aux_i2c_transfer_size, 1, DP_AUX_MAX_PAYLOAD_BYTES);
 
 	memset(&msg, 0, sizeof(msg));
@@ -2917,6 +2952,103 @@
 EXPORT_SYMBOL(drm_dp_vsc_sdp_log);
 
 /**
+ * drm_dp_vsc_sdp_supported() - check if vsc sdp is supported
+ * @aux: DisplayPort AUX channel
+ * @dpcd: DisplayPort configuration data
+ *
+ * Returns true if vsc sdp is supported, else returns false
+ */
+bool drm_dp_vsc_sdp_supported(struct drm_dp_aux *aux, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+{
+	u8 rx_feature;
+
+	if (dpcd[DP_DPCD_REV] < DP_DPCD_REV_13)
+		return false;
+
+	if (drm_dp_dpcd_readb(aux, DP_DPRX_FEATURE_ENUMERATION_LIST, &rx_feature) != 1) {
+		drm_dbg_dp(aux->drm_dev, "failed to read DP_DPRX_FEATURE_ENUMERATION_LIST\n");
+		return false;
+	}
+
+	return (rx_feature & DP_VSC_SDP_EXT_FOR_COLORIMETRY_SUPPORTED);
+}
+EXPORT_SYMBOL(drm_dp_vsc_sdp_supported);
+
+/**
+ * drm_dp_vsc_sdp_pack() - pack a given vsc sdp into generic dp_sdp
+ * @vsc: vsc sdp initialized according to its purpose as defined in
+ *       table 2-118 - table 2-120 in DP 1.4a specification
+ * @sdp: valid handle to the generic dp_sdp which will be packed
+ *
+ * Returns length of sdp on success and error code on failure
+ */
+ssize_t drm_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc,
+			    struct dp_sdp *sdp)
+{
+	size_t length = sizeof(struct dp_sdp);
+
+	memset(sdp, 0, sizeof(struct dp_sdp));
+
+	/*
+	 * Prepare VSC Header for SU as per DP 1.4a spec, Table 2-119
+	 * VSC SDP Header Bytes
+	 */
+	sdp->sdp_header.HB0 = 0; /* Secondary-Data Packet ID = 0 */
+	sdp->sdp_header.HB1 = vsc->sdp_type; /* Secondary-data Packet Type */
+	sdp->sdp_header.HB2 = vsc->revision; /* Revision Number */
+	sdp->sdp_header.HB3 = vsc->length; /* Number of Valid Data Bytes */
+
+	if (vsc->revision == 0x6) {
+		sdp->db[0] = 1;
+		sdp->db[3] = 1;
+	}
+
+	/*
+	 * Revision 0x5 and revision 0x7 supports Pixel Encoding/Colorimetry
+	 * Format as per DP 1.4a spec and DP 2.0 respectively.
+	 */
+	if (!(vsc->revision == 0x5 || vsc->revision == 0x7))
+		goto out;
+
+	/* VSC SDP Payload for DB16 through DB18 */
+	/* Pixel Encoding and Colorimetry Formats  */
+	sdp->db[16] = (vsc->pixelformat & 0xf) << 4; /* DB16[7:4] */
+	sdp->db[16] |= vsc->colorimetry & 0xf; /* DB16[3:0] */
+
+	switch (vsc->bpc) {
+	case 6:
+		/* 6bpc: 0x0 */
+		break;
+	case 8:
+		sdp->db[17] = 0x1; /* DB17[3:0] */
+		break;
+	case 10:
+		sdp->db[17] = 0x2;
+		break;
+	case 12:
+		sdp->db[17] = 0x3;
+		break;
+	case 16:
+		sdp->db[17] = 0x4;
+		break;
+	default:
+		WARN(1, "Missing case %d\n", vsc->bpc);
+		return -EINVAL;
+	}
+
+	/* Dynamic Range and Component Bit Depth */
+	if (vsc->dynamic_range == DP_DYNAMIC_RANGE_CTA)
+		sdp->db[17] |= 0x80;  /* DB17[7] */
+
+	/* Content Type */
+	sdp->db[18] = vsc->content_type & 0x7;
+
+out:
+	return length;
+}
+EXPORT_SYMBOL(drm_dp_vsc_sdp_pack);
+
+/**
  * drm_dp_get_pcon_max_frl_bw() - maximum frl supported by PCON
  * @dpcd: DisplayPort configuration data
  * @port_cap: port capabilities
@@ -3982,6 +4114,13 @@
 	u32 overhead = 1000000;
 	int symbol_cycles;
 
+	if (lane_count == 0 || hactive == 0 || bpp_x16 == 0) {
+		DRM_DEBUG_KMS("Invalid BW overhead params: lane_count %d, hactive %d, bpp_x16 %d.%04d\n",
+			      lane_count, hactive,
+			      bpp_x16 >> 4, (bpp_x16 & 0xf) * 625);
+		return 0;
+	}
+
 	/*
 	 * DP Standard v2.1 2.6.4.1
 	 * SSC downspread and ref clock variation margin:
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/display/drm_dp_mst_topology.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/display/drm_dp_mst_topology.c
@@ -320,6 +320,9 @@
 	hdr->broadcast = (buf[idx] >> 7) & 0x1;
 	hdr->path_msg = (buf[idx] >> 6) & 0x1;
 	hdr->msg_len = buf[idx] & 0x3f;
+	if (hdr->msg_len < 1)		/* min space for body CRC */
+		return false;
+
 	idx++;
 	hdr->somt = (buf[idx] >> 7) & 0x1;
 	hdr->eomt = (buf[idx] >> 6) & 0x1;
@@ -2924,7 +2927,7 @@
 
 	/* FIXME: Actually do some real error handling here */
 	ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
-	if (ret <= 0) {
+	if (ret < 0) {
 		drm_err(mgr->dev, "Sending link address failed with %d\n", ret);
 		goto out;
 	}
@@ -2976,7 +2979,7 @@
 	mutex_unlock(&mgr->lock);
 
 out:
-	if (ret <= 0)
+	if (ret < 0)
 		mstb->link_address_sent = false;
 	kfree(txmsg);
 	return ret < 0 ? ret : changed;
@@ -3416,7 +3419,6 @@
 /**
  * drm_dp_add_payload_part2() - Execute payload update part 2
  * @mgr: Manager to use.
- * @state: The global atomic state
  * @payload: The payload to update
  *
  * If @payload was successfully assigned a starting time slot by drm_dp_add_payload_part1(), this
@@ -3425,14 +3427,13 @@
  * Returns: 0 on success, negative error code on failure.
  */
 int drm_dp_add_payload_part2(struct drm_dp_mst_topology_mgr *mgr,
-			     struct drm_atomic_state *state,
 			     struct drm_dp_mst_atomic_payload *payload)
 {
 	int ret = 0;
 
 	/* Skip failed payloads */
 	if (payload->payload_allocation_status != DRM_DP_MST_PAYLOAD_ALLOCATION_DFP) {
-		drm_dbg_kms(state->dev, "Part 1 of payload creation for %s failed, skipping part 2\n",
+		drm_dbg_kms(mgr->dev, "Part 1 of payload creation for %s failed, skipping part 2\n",
 			    payload->port->connector->name);
 		return -EIO;
 	}
@@ -3688,8 +3689,7 @@
 		ret = 0;
 		mgr->payload_id_table_cleared = false;
 
-		memset(&mgr->down_rep_recv, 0, sizeof(mgr->down_rep_recv));
-		memset(&mgr->up_req_recv, 0, sizeof(mgr->up_req_recv));
+		mgr->reset_rx_state = true;
 	}
 
 out_unlock:
@@ -3817,6 +3817,11 @@
 }
 EXPORT_SYMBOL(drm_dp_mst_topology_mgr_resume);
 
+static void reset_msg_rx_state(struct drm_dp_sideband_msg_rx *msg)
+{
+	memset(msg, 0, sizeof(*msg));
+}
+
 static bool
 drm_dp_get_one_sb_msg(struct drm_dp_mst_topology_mgr *mgr, bool up,
 		      struct drm_dp_mst_branch **mstb)
@@ -3895,6 +3900,34 @@
 	return true;
 }
 
+static int get_msg_request_type(u8 data)
+{
+	return data & 0x7f;
+}
+
+static bool verify_rx_request_type(struct drm_dp_mst_topology_mgr *mgr,
+				   const struct drm_dp_sideband_msg_tx *txmsg,
+				   const struct drm_dp_sideband_msg_rx *rxmsg)
+{
+	const struct drm_dp_sideband_msg_hdr *hdr = &rxmsg->initial_hdr;
+	const struct drm_dp_mst_branch *mstb = txmsg->dst;
+	int tx_req_type = get_msg_request_type(txmsg->msg[0]);
+	int rx_req_type = get_msg_request_type(rxmsg->msg[0]);
+	char rad_str[64];
+
+	if (tx_req_type == rx_req_type)
+		return true;
+
+	drm_dp_mst_rad_to_str(mstb->rad, mstb->lct, rad_str, sizeof(rad_str));
+	drm_dbg_kms(mgr->dev,
+		    "Got unexpected MST reply, mstb: %p seqno: %d lct: %d rad: %s rx_req_type: %s (%02x) != tx_req_type: %s (%02x)\n",
+		    mstb, hdr->seqno, mstb->lct, rad_str,
+		    drm_dp_mst_req_type_str(rx_req_type), rx_req_type,
+		    drm_dp_mst_req_type_str(tx_req_type), tx_req_type);
+
+	return false;
+}
+
 static int drm_dp_mst_handle_down_rep(struct drm_dp_mst_topology_mgr *mgr)
 {
 	struct drm_dp_sideband_msg_tx *txmsg;
@@ -3924,6 +3957,9 @@
 		goto out_clear_reply;
 	}
 
+	if (!verify_rx_request_type(mgr, txmsg, msg))
+		goto out_clear_reply;
+
 	drm_dp_sideband_parse_reply(mgr, msg, &txmsg->reply);
 
 	if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) {
@@ -4031,9 +4067,10 @@
 static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr)
 {
 	struct drm_dp_pending_up_req *up_req;
+	struct drm_dp_mst_branch *mst_primary;
 
 	if (!drm_dp_get_one_sb_msg(mgr, true, NULL))
-		goto out;
+		goto out_clear_reply;
 
 	if (!mgr->up_req_recv.have_eomt)
 		return 0;
@@ -4051,15 +4088,25 @@
 		drm_dbg_kms(mgr->dev, "Received unknown up req type, ignoring: %x\n",
 			    up_req->msg.req_type);
 		kfree(up_req);
-		goto out;
+		goto out_clear_reply;
 	}
 
-	drm_dp_send_up_ack_reply(mgr, mgr->mst_primary, up_req->msg.req_type,
+	mutex_lock(&mgr->lock);
+	mst_primary = mgr->mst_primary;
+	if (!mst_primary || !drm_dp_mst_topology_try_get_mstb(mst_primary)) {
+		mutex_unlock(&mgr->lock);
+		kfree(up_req);
+		goto out_clear_reply;
+	}
+	mutex_unlock(&mgr->lock);
+
+	drm_dp_send_up_ack_reply(mgr, mst_primary, up_req->msg.req_type,
 				 false);
 
 	if (up_req->msg.req_type == DP_CONNECTION_STATUS_NOTIFY) {
 		const struct drm_dp_connection_status_notify *conn_stat =
 			&up_req->msg.u.conn_stat;
+		bool handle_csn;
 
 		drm_dbg_kms(mgr->dev, "Got CSN: pn: %d ldps:%d ddps: %d mcs: %d ip: %d pdt: %d\n",
 			    conn_stat->port_number,
@@ -4068,6 +4115,16 @@
 			    conn_stat->message_capability_status,
 			    conn_stat->input_port,
 			    conn_stat->peer_device_type);
+
+		mutex_lock(&mgr->probe_lock);
+		handle_csn = mst_primary->link_address_sent;
+		mutex_unlock(&mgr->probe_lock);
+
+		if (!handle_csn) {
+			drm_dbg_kms(mgr->dev, "Got CSN before finish topology probing. Skip it.");
+			kfree(up_req);
+			goto out_put_primary;
+		}
 	} else if (up_req->msg.req_type == DP_RESOURCE_STATUS_NOTIFY) {
 		const struct drm_dp_resource_status_notify *res_stat =
 			&up_req->msg.u.resource_stat;
@@ -4083,11 +4140,24 @@
 	mutex_unlock(&mgr->up_req_lock);
 	queue_work(system_long_wq, &mgr->up_req_work);
 
-out:
+out_put_primary:
+	drm_dp_mst_topology_put_mstb(mst_primary);
+out_clear_reply:
 	memset(&mgr->up_req_recv, 0, sizeof(struct drm_dp_sideband_msg_rx));
 	return 0;
 }
 
+static void update_msg_rx_state(struct drm_dp_mst_topology_mgr *mgr)
+{
+	mutex_lock(&mgr->lock);
+	if (mgr->reset_rx_state) {
+		mgr->reset_rx_state = false;
+		reset_msg_rx_state(&mgr->down_rep_recv);
+		reset_msg_rx_state(&mgr->up_req_recv);
+	}
+	mutex_unlock(&mgr->lock);
+}
+
 /**
  * drm_dp_mst_hpd_irq_handle_event() - MST hotplug IRQ handle MST event
  * @mgr: manager to notify irq for.
@@ -4122,6 +4192,8 @@
 		*handled = true;
 	}
 
+	update_msg_rx_state(mgr);
+
 	if (esi[1] & DP_DOWN_REP_MSG_RDY) {
 		ret = drm_dp_mst_handle_down_rep(mgr);
 		*handled = true;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_atomic_helper.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_atomic_helper.c
@@ -1375,7 +1375,7 @@
 		mode = &new_crtc_state->mode;
 		adjusted_mode = &new_crtc_state->adjusted_mode;
 
-		if (!new_crtc_state->mode_changed)
+		if (!new_crtc_state->mode_changed && !new_crtc_state->connectors_changed)
 			continue;
 
 		drm_dbg_atomic(dev, "modeset on [ENCODER:%d:%s]\n",
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_atomic_uapi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_atomic_uapi.c
@@ -543,7 +543,7 @@
 					&state->fb_damage_clips,
 					val,
 					-1,
-					sizeof(struct drm_rect),
+					sizeof(struct drm_mode_rect),
 					&replaced);
 		return ret;
 	} else if (property == plane->scaling_filter_property) {
@@ -1066,21 +1066,17 @@
 			break;
 		}
 
-		if (async_flip && prop != config->prop_fb_id) {
+		if (async_flip &&
+		    (plane_state->plane->type != DRM_PLANE_TYPE_PRIMARY ||
+		     (prop != config->prop_fb_id &&
+		      prop != config->prop_in_fence_fd &&
+		      prop != config->prop_fb_damage_clips))) {
 			ret = drm_atomic_plane_get_property(plane, plane_state,
 							    prop, &old_val);
 			ret = drm_atomic_check_prop_changes(ret, old_val, prop_value, prop);
 			break;
 		}
 
-		if (async_flip && plane_state->plane->type != DRM_PLANE_TYPE_PRIMARY) {
-			drm_dbg_atomic(prop->dev,
-				       "[OBJECT:%d] Only primary planes can be changed during async flip\n",
-				       obj->id);
-			ret = -EINVAL;
-			break;
-		}
-
 		ret = drm_atomic_plane_set_property(plane,
 				plane_state, file_priv,
 				prop, prop_value);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_bridge.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_bridge.c
@@ -27,8 +27,9 @@
 #include <linux/mutex.h>
 
 #include <drm/drm_atomic_state_helper.h>
-#include <drm/drm_debugfs.h>
 #include <drm/drm_bridge.h>
+#include <drm/drm_debugfs.h>
+#include <drm/drm_edid.h>
 #include <drm/drm_encoder.h>
 #include <drm/drm_file.h>
 #include <drm/drm_of.h>
@@ -352,13 +353,8 @@
 	bridge->encoder = NULL;
 	list_del(&bridge->chain_node);
 
-#ifdef CONFIG_OF
 	DRM_ERROR("failed to attach bridge %pOF to encoder %s: %d\n",
 		  bridge->of_node, encoder->name, ret);
-#else
-	DRM_ERROR("failed to attach bridge to encoder %s: %d\n",
-		  encoder->name, ret);
-#endif
 
 	return ret;
 }
@@ -686,11 +682,17 @@
 				 */
 				list_for_each_entry_from(next, &encoder->bridge_chain,
 							 chain_node) {
-					if (next->pre_enable_prev_first) {
+					if (!next->pre_enable_prev_first) {
 						next = list_prev_entry(next, chain_node);
 						limit = next;
 						break;
 					}
+
+					if (list_is_last(&next->chain_node,
+							 &encoder->bridge_chain)) {
+						limit = next;
+						break;
+					}
 				}
 
 				/* Call these bridges in reverse order */
@@ -773,7 +775,7 @@
 					/* Found first bridge that does NOT
 					 * request prev to be enabled first
 					 */
-					limit = list_prev_entry(next, chain_node);
+					limit = next;
 					break;
 				}
 			}
@@ -1207,6 +1209,47 @@
 EXPORT_SYMBOL_GPL(drm_bridge_get_modes);
 
 /**
+ * drm_bridge_edid_read - read the EDID data of the connected display
+ * @bridge: bridge control structure
+ * @connector: the connector to read EDID for
+ *
+ * If the bridge supports output EDID retrieval, as reported by the
+ * DRM_BRIDGE_OP_EDID bridge ops flag, call &drm_bridge_funcs.edid_read to get
+ * the EDID and return it. Otherwise return NULL.
+ *
+ * If &drm_bridge_funcs.edid_read is not set, fall back to using
+ * drm_bridge_get_edid() and wrapping it in struct drm_edid.
+ *
+ * RETURNS:
+ * The retrieved EDID on success, or NULL otherwise.
+ */
+const struct drm_edid *drm_bridge_edid_read(struct drm_bridge *bridge,
+					    struct drm_connector *connector)
+{
+	if (!(bridge->ops & DRM_BRIDGE_OP_EDID))
+		return NULL;
+
+	/* Transitional: Fall back to ->get_edid. */
+	if (!bridge->funcs->edid_read) {
+		const struct drm_edid *drm_edid;
+		struct edid *edid;
+
+		edid = drm_bridge_get_edid(bridge, connector);
+		if (!edid)
+			return NULL;
+
+		drm_edid = drm_edid_alloc(edid, (edid->extensions + 1) * EDID_LENGTH);
+
+		kfree(edid);
+
+		return drm_edid;
+	}
+
+	return bridge->funcs->edid_read(bridge, connector);
+}
+EXPORT_SYMBOL_GPL(drm_bridge_edid_read);
+
+/**
  * drm_bridge_get_edid - get the EDID data of the connected display
  * @bridge: bridge control structure
  * @connector: the connector to read EDID for
@@ -1215,6 +1258,8 @@
  * DRM_BRIDGE_OP_EDID bridge ops flag, call &drm_bridge_funcs.get_edid to
  * get the EDID and return it. Otherwise return NULL.
  *
+ * Deprecated. Prefer using drm_bridge_edid_read().
+ *
  * RETURNS:
  * The retrieved EDID on success, or NULL otherwise.
  */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_bridge_connector.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_bridge_connector.c
@@ -335,11 +335,11 @@
 	bridge_connector->encoder = encoder;
 
 	/*
-	 * TODO: Handle doublescan_allowed, stereo_allowed and
-	 * ycbcr_420_allowed.
+	 * TODO: Handle doublescan_allowed and stereo_allowed.
 	 */
 	connector = &bridge_connector->base;
 	connector->interlace_allowed = true;
+	connector->ycbcr_420_allowed = true;
 
 	/*
 	 * Initialise connector status handling. First locate the furthest
@@ -352,6 +352,8 @@
 	drm_for_each_bridge_in_chain(encoder, bridge) {
 		if (!bridge->interlace_allowed)
 			connector->interlace_allowed = false;
+		if (!bridge->ycbcr_420_allowed)
+			connector->ycbcr_420_allowed = false;
 
 		if (bridge->ops & DRM_BRIDGE_OP_EDID)
 			bridge_connector->bridge_edid = bridge;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_client_modeset.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_client_modeset.c
@@ -730,6 +730,15 @@
 	if ((conn_configured & mask) != mask && conn_configured != conn_seq)
 		goto retry;
 
+	for (i = 0; i < count; i++) {
+		struct drm_connector *connector = connectors[i];
+
+		if (connector->has_tile)
+			drm_client_get_tile_offsets(connectors, connector_count,
+						    modes, offsets, i,
+						    connector->tile_h_loc, connector->tile_v_loc);
+	}
+
 	/*
 	 * If the BIOS didn't enable everything it could, fall back to have the
 	 * same user experiencing of lighting up as much as possible like the
@@ -777,6 +786,7 @@
 	unsigned int total_modes_count = 0;
 	struct drm_client_offset *offsets;
 	unsigned int connector_count = 0;
+	/* points to modes protected by mode_config.mutex */
 	struct drm_display_mode **modes;
 	struct drm_crtc **crtcs;
 	int i, ret = 0;
@@ -845,7 +855,6 @@
 		drm_client_pick_crtcs(client, connectors, connector_count,
 				      crtcs, modes, 0, width, height);
 	}
-	mutex_unlock(&dev->mode_config.mutex);
 
 	drm_client_modeset_release(client);
 
@@ -869,12 +878,18 @@
 
 			kfree(modeset->mode);
 			modeset->mode = drm_mode_duplicate(dev, mode);
+			if (!modeset->mode) {
+				ret = -ENOMEM;
+				break;
+			}
+
 			drm_connector_get(connector);
 			modeset->connectors[modeset->num_connectors++] = connector;
 			modeset->x = offset->x;
 			modeset->y = offset->y;
 		}
 	}
+	mutex_unlock(&dev->mode_config.mutex);
 
 	mutex_unlock(&client->modeset_mutex);
 out:
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_connector.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_connector.c
@@ -277,6 +277,7 @@
 	INIT_LIST_HEAD(&connector->probed_modes);
 	INIT_LIST_HEAD(&connector->modes);
 	mutex_init(&connector->mutex);
+	mutex_init(&connector->eld_mutex);
 	mutex_init(&connector->edid_override_mutex);
 	connector->edid_blob_ptr = NULL;
 	connector->epoch_counter = 0;
@@ -2940,7 +2941,7 @@
 						     dev->mode_config.max_width,
 						     dev->mode_config.max_height);
 		else
-			drm_dbg_kms(dev, "User-space requested a forced probe on [CONNECTOR:%d:%s] but is not the DRM master, demoting to read-only probe",
+			drm_dbg_kms(dev, "User-space requested a forced probe on [CONNECTOR:%d:%s] but is not the DRM master, demoting to read-only probe\n",
 				    connector->base.id, connector->name);
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_drv.c
@@ -34,6 +34,7 @@
 #include <linux/pseudo_fs.h>
 #include <linux/slab.h>
 #include <linux/srcu.h>
+#include <linux/xarray.h>
 
 #include <drm/drm_accel.h>
 #include <drm/drm_cache.h>
@@ -53,8 +54,7 @@
 MODULE_DESCRIPTION("DRM shared core routines");
 MODULE_LICENSE("GPL and additional rights");
 
-static DEFINE_SPINLOCK(drm_minor_lock);
-static struct idr drm_minors_idr;
+DEFINE_XARRAY_ALLOC(drm_minors_xa);
 
 /*
  * If the drm core fails to init for whatever reason,
@@ -82,6 +82,18 @@
  * registered and unregistered dynamically according to device-state.
  */
 
+static struct xarray *drm_minor_get_xa(enum drm_minor_type type)
+{
+	if (type == DRM_MINOR_PRIMARY || type == DRM_MINOR_RENDER)
+		return &drm_minors_xa;
+#if IS_ENABLED(CONFIG_DRM_ACCEL)
+	else if (type == DRM_MINOR_ACCEL)
+		return &accel_minors_xa;
+#endif
+	else
+		return ERR_PTR(-EOPNOTSUPP);
+}
+
 static struct drm_minor **drm_minor_get_slot(struct drm_device *dev,
 					     enum drm_minor_type type)
 {
@@ -100,25 +112,31 @@
 static void drm_minor_alloc_release(struct drm_device *dev, void *data)
 {
 	struct drm_minor *minor = data;
-	unsigned long flags;
 
 	WARN_ON(dev != minor->dev);
 
 	put_device(minor->kdev);
 
-	if (minor->type == DRM_MINOR_ACCEL) {
-		accel_minor_remove(minor->index);
-	} else {
-		spin_lock_irqsave(&drm_minor_lock, flags);
-		idr_remove(&drm_minors_idr, minor->index);
-		spin_unlock_irqrestore(&drm_minor_lock, flags);
-	}
+	xa_erase(drm_minor_get_xa(minor->type), minor->index);
 }
 
+/*
+ * DRM used to support 64 devices, for backwards compatibility we need to maintain the
+ * minor allocation scheme where minors 0-63 are primary nodes, 64-127 are control nodes,
+ * and 128-191 are render nodes.
+ * After reaching the limit, we're allocating minors dynamically - first-come, first-serve.
+ * Accel nodes are using a distinct major, so the minors are allocated in continuous 0-MAX
+ * range.
+ */
+#define DRM_MINOR_LIMIT(t) ({ \
+	typeof(t) _t = (t); \
+	_t == DRM_MINOR_ACCEL ? XA_LIMIT(0, ACCEL_MAX_MINORS) : XA_LIMIT(64 * _t, 64 * _t + 63); \
+})
+#define DRM_EXTENDED_MINOR_LIMIT XA_LIMIT(192, (1 << MINORBITS) - 1)
+
 static int drm_minor_alloc(struct drm_device *dev, enum drm_minor_type type)
 {
 	struct drm_minor *minor;
-	unsigned long flags;
 	int r;
 
 	minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
@@ -128,25 +146,14 @@
 	minor->type = type;
 	minor->dev = dev;
 
-	idr_preload(GFP_KERNEL);
-	if (type == DRM_MINOR_ACCEL) {
-		r = accel_minor_alloc();
-	} else {
-		spin_lock_irqsave(&drm_minor_lock, flags);
-		r = idr_alloc(&drm_minors_idr,
-			NULL,
-			64 * type,
-			64 * (type + 1),
-			GFP_NOWAIT);
-		spin_unlock_irqrestore(&drm_minor_lock, flags);
-	}
-	idr_preload_end();
-
+	r = xa_alloc(drm_minor_get_xa(type), &minor->index,
+		     NULL, DRM_MINOR_LIMIT(type), GFP_KERNEL);
+	if (r == -EBUSY && (type == DRM_MINOR_PRIMARY || type == DRM_MINOR_RENDER))
+		r = xa_alloc(&drm_minors_xa, &minor->index,
+			     NULL, DRM_EXTENDED_MINOR_LIMIT, GFP_KERNEL);
 	if (r < 0)
 		return r;
 
-	minor->index = r;
-
 	r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor);
 	if (r)
 		return r;
@@ -162,7 +169,7 @@
 static int drm_minor_register(struct drm_device *dev, enum drm_minor_type type)
 {
 	struct drm_minor *minor;
-	unsigned long flags;
+	void *entry;
 	int ret;
 
 	DRM_DEBUG("\n");
@@ -185,13 +192,12 @@
 		goto err_debugfs;
 
 	/* replace NULL with @minor so lookups will succeed from now on */
-	if (minor->type == DRM_MINOR_ACCEL) {
-		accel_minor_replace(minor, minor->index);
-	} else {
-		spin_lock_irqsave(&drm_minor_lock, flags);
-		idr_replace(&drm_minors_idr, minor, minor->index);
-		spin_unlock_irqrestore(&drm_minor_lock, flags);
+	entry = xa_store(drm_minor_get_xa(type), minor->index, minor, GFP_KERNEL);
+	if (xa_is_err(entry)) {
+		ret = xa_err(entry);
+		goto err_debugfs;
 	}
+	WARN_ON(entry);
 
 	DRM_DEBUG("new minor registered %d\n", minor->index);
 	return 0;
@@ -204,20 +210,13 @@
 static void drm_minor_unregister(struct drm_device *dev, enum drm_minor_type type)
 {
 	struct drm_minor *minor;
-	unsigned long flags;
 
 	minor = *drm_minor_get_slot(dev, type);
 	if (!minor || !device_is_registered(minor->kdev))
 		return;
 
 	/* replace @minor with NULL so lookups will fail from now on */
-	if (minor->type == DRM_MINOR_ACCEL) {
-		accel_minor_replace(NULL, minor->index);
-	} else {
-		spin_lock_irqsave(&drm_minor_lock, flags);
-		idr_replace(&drm_minors_idr, NULL, minor->index);
-		spin_unlock_irqrestore(&drm_minor_lock, flags);
-	}
+	xa_store(drm_minor_get_xa(type), minor->index, NULL, GFP_KERNEL);
 
 	device_del(minor->kdev);
 	dev_set_drvdata(minor->kdev, NULL); /* safety belt */
@@ -233,16 +232,15 @@
  * minor->dev pointer will stay valid! However, the device may get unplugged and
  * unregistered while you hold the minor.
  */
-struct drm_minor *drm_minor_acquire(unsigned int minor_id)
+struct drm_minor *drm_minor_acquire(struct xarray *minor_xa, unsigned int minor_id)
 {
 	struct drm_minor *minor;
-	unsigned long flags;
 
-	spin_lock_irqsave(&drm_minor_lock, flags);
-	minor = idr_find(&drm_minors_idr, minor_id);
+	xa_lock(minor_xa);
+	minor = xa_load(minor_xa, minor_id);
 	if (minor)
 		drm_dev_get(minor->dev);
-	spin_unlock_irqrestore(&drm_minor_lock, flags);
+	xa_unlock(minor_xa);
 
 	if (!minor) {
 		return ERR_PTR(-ENODEV);
@@ -1031,7 +1029,7 @@
 
 	DRM_DEBUG("\n");
 
-	minor = drm_minor_acquire(iminor(inode));
+	minor = drm_minor_acquire(&drm_minors_xa, iminor(inode));
 	if (IS_ERR(minor))
 		return PTR_ERR(minor);
 
@@ -1066,7 +1064,7 @@
 	unregister_chrdev(DRM_MAJOR, "drm");
 	debugfs_remove(drm_debugfs_root);
 	drm_sysfs_destroy();
-	idr_destroy(&drm_minors_idr);
+	WARN_ON(!xa_empty(&drm_minors_xa));
 	drm_connector_ida_destroy();
 }
 
@@ -1075,7 +1073,6 @@
 	int ret;
 
 	drm_connector_ida_init();
-	idr_init(&drm_minors_idr);
 	drm_memcpy_init_early();
 
 	ret = drm_sysfs_init();
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_edid.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_edid.c
@@ -5502,7 +5502,9 @@
 
 static void clear_eld(struct drm_connector *connector)
 {
+	mutex_lock(&connector->eld_mutex);
 	memset(connector->eld, 0, sizeof(connector->eld));
+	mutex_unlock(&connector->eld_mutex);
 
 	connector->latency_present[0] = false;
 	connector->latency_present[1] = false;
@@ -5554,6 +5556,8 @@
 	if (!drm_edid)
 		return;
 
+	mutex_lock(&connector->eld_mutex);
+
 	mnl = get_monitor_name(drm_edid, &eld[DRM_ELD_MONITOR_NAME_STRING]);
 	drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] ELD monitor %s\n",
 		    connector->base.id, connector->name,
@@ -5614,6 +5618,8 @@
 	drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s] ELD size %d, SAD count %d\n",
 		    connector->base.id, connector->name,
 		    drm_eld_size(eld), total_sad_count);
+
+	mutex_unlock(&connector->eld_mutex);
 }
 
 static int _drm_edid_to_sad(const struct drm_edid *drm_edid,
@@ -7345,7 +7351,7 @@
 static bool displayid_is_tiled_block(const struct displayid_iter *iter,
 				     const struct displayid_block *block)
 {
-	return (displayid_version(iter) == DISPLAY_ID_STRUCTURE_VER_12 &&
+	return (displayid_version(iter) < DISPLAY_ID_STRUCTURE_VER_20 &&
 		block->tag == DATA_BLOCK_TILED_DISPLAY) ||
 		(displayid_version(iter) == DISPLAY_ID_STRUCTURE_VER_20 &&
 		 block->tag == DATA_BLOCK_2_TILED_DISPLAY_TOPOLOGY);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_fb_helper.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_fb_helper.c
@@ -524,6 +524,9 @@
 	if (!info)
 		return ERR_PTR(-ENOMEM);
 
+	if (!drm_leak_fbdev_smem)
+		info->flags |= FBINFO_HIDE_SMEM_START;
+
 	ret = fb_alloc_cmap(&info->cmap, 256, 0);
 	if (ret)
 		goto err_release;
@@ -628,6 +631,17 @@
 static void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y,
 				 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);
 
 	schedule_work(&helper->damage_work);
@@ -1347,14 +1361,14 @@
 }
 EXPORT_SYMBOL(drm_fb_helper_set_par);
 
-static void pan_set(struct drm_fb_helper *fb_helper, int x, int y)
+static void pan_set(struct drm_fb_helper *fb_helper, int dx, int dy)
 {
 	struct drm_mode_set *mode_set;
 
 	mutex_lock(&fb_helper->client.modeset_mutex);
 	drm_client_for_each_modeset(mode_set, &fb_helper->client) {
-		mode_set->x = x;
-		mode_set->y = y;
+		mode_set->x += dx;
+		mode_set->y += dy;
 	}
 	mutex_unlock(&fb_helper->client.modeset_mutex);
 }
@@ -1363,16 +1377,18 @@
 			      struct fb_info *info)
 {
 	struct drm_fb_helper *fb_helper = info->par;
-	int ret;
+	int ret, dx, dy;
 
-	pan_set(fb_helper, var->xoffset, var->yoffset);
+	dx = var->xoffset - info->var.xoffset;
+	dy = var->yoffset - info->var.yoffset;
+	pan_set(fb_helper, dx, dy);
 
 	ret = drm_client_modeset_commit_locked(&fb_helper->client);
 	if (!ret) {
 		info->var.xoffset = var->xoffset;
 		info->var.yoffset = var->yoffset;
 	} else
-		pan_set(fb_helper, info->var.xoffset, info->var.yoffset);
+		pan_set(fb_helper, -dx, -dy);
 
 	return ret;
 }
@@ -1860,9 +1876,6 @@
 	info = fb_helper->info;
 	info->var.pixclock = 0;
 
-	if (!drm_leak_fbdev_smem)
-		info->flags |= FBINFO_HIDE_SMEM_START;
-
 	/* Need to drop locks to avoid recursive deadlock in
 	 * register_framebuffer. This is ok because the only thing left to do is
 	 * register the fbdev emulation instance in kernel_fb_helper_list. */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_fbdev_dma.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_fbdev_dma.c
@@ -90,7 +90,8 @@
 		    sizes->surface_width, sizes->surface_height,
 		    sizes->surface_bpp);
 
-	format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
+	format = drm_driver_legacy_fb_format(dev, sizes->surface_bpp,
+					     sizes->surface_depth);
 	buffer = drm_client_framebuffer_create(client, sizes->surface_width,
 					       sizes->surface_height, format);
 	if (IS_ERR(buffer))
@@ -130,7 +131,10 @@
 		info->flags |= FBINFO_READS_FAST; /* signal caching */
 	info->screen_size = sizes->surface_height * fb->pitches[0];
 	info->screen_buffer = map.vaddr;
-	info->fix.smem_start = page_to_phys(virt_to_page(info->screen_buffer));
+	if (!(info->flags & FBINFO_HIDE_SMEM_START)) {
+		if (!drm_WARN_ON(dev, is_vmalloc_addr(info->screen_buffer)))
+			info->fix.smem_start = page_to_phys(virt_to_page(info->screen_buffer));
+	}
 	info->fix.smem_len = info->screen_size;
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_fbdev_generic.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_fbdev_generic.c
@@ -84,7 +84,8 @@
 		    sizes->surface_width, sizes->surface_height,
 		    sizes->surface_bpp);
 
-	format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
+	format = drm_driver_legacy_fb_format(dev, sizes->surface_bpp,
+					     sizes->surface_depth);
 	buffer = drm_client_framebuffer_create(client, sizes->surface_width,
 					       sizes->surface_height, format);
 	if (IS_ERR(buffer))
@@ -113,7 +114,6 @@
 	/* screen */
 	info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST;
 	info->screen_buffer = screen_buffer;
-	info->fix.smem_start = page_to_phys(vmalloc_to_page(info->screen_buffer));
 	info->fix.smem_len = screen_size;
 
 	/* deferred I/O */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_file.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_file.c
@@ -138,7 +138,7 @@
  */
 struct drm_file *drm_file_alloc(struct drm_minor *minor)
 {
-	static atomic64_t ident = ATOMIC_INIT(0);
+	static atomic64_t ident = ATOMIC64_INIT(0);
 	struct drm_device *dev = minor->dev;
 	struct drm_file *file;
 	int ret;
@@ -364,7 +364,7 @@
 	struct drm_minor *minor;
 	int retcode;
 
-	minor = drm_minor_acquire(iminor(inode));
+	minor = drm_minor_acquire(&drm_minors_xa, iminor(inode));
 	if (IS_ERR(minor))
 		return PTR_ERR(minor);
 
@@ -469,14 +469,12 @@
 
 	dev = filp->minor->dev;
 	mutex_lock(&dev->filelist_mutex);
+	get_pid(pid);
 	old = rcu_replace_pointer(filp->pid, pid, 1);
 	mutex_unlock(&dev->filelist_mutex);
 
-	if (pid != old) {
-		get_pid(pid);
-		synchronize_rcu();
-		put_pid(old);
-	}
+	synchronize_rcu();
+	put_pid(old);
 }
 
 /**
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_gem_atomic_helper.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_gem_atomic_helper.c
@@ -224,8 +224,8 @@
 
 	__drm_atomic_helper_plane_duplicate_state(plane, &new_shadow_plane_state->base);
 
-	drm_format_conv_state_copy(&shadow_plane_state->fmtcnv_state,
-				   &new_shadow_plane_state->fmtcnv_state);
+	drm_format_conv_state_copy(&new_shadow_plane_state->fmtcnv_state,
+				   &shadow_plane_state->fmtcnv_state);
 }
 EXPORT_SYMBOL(__drm_gem_duplicate_shadow_plane_state);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -610,6 +610,9 @@
 		return ret;
 	}
 
+	if (is_cow_mapping(vma->vm_flags))
+		return -EINVAL;
+
 	dma_resv_lock(shmem->base.resv, NULL);
 	ret = drm_gem_shmem_get_pages(shmem);
 	dma_resv_unlock(shmem->base.resv);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_internal.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_internal.h
@@ -79,10 +79,6 @@
 void drm_prime_remove_buf_handle(struct drm_prime_file_private *prime_fpriv,
 				 uint32_t handle);
 
-/* drm_drv.c */
-struct drm_minor *drm_minor_acquire(unsigned int minor_id);
-void drm_minor_release(struct drm_minor *minor);
-
 /* drm_managed.c */
 void drm_managed_release(struct drm_device *dev);
 void drmm_add_final_kfree(struct drm_device *dev, void *container);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_mipi_dsi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_mipi_dsi.c
@@ -654,7 +654,7 @@
  *
  * Return: 0 on success or a negative error code on failure.
  */
-ssize_t mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
+int mipi_dsi_compression_mode(struct mipi_dsi_device *dsi, bool enable)
 {
 	/* Note: Needs updating for non-default PPS or algorithm */
 	u8 tx[2] = { enable << 0, 0 };
@@ -679,8 +679,8 @@
  *
  * Return: 0 on success or a negative error code on failure.
  */
-ssize_t mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
-				       const struct drm_dsc_picture_parameter_set *pps)
+int mipi_dsi_picture_parameter_set(struct mipi_dsi_device *dsi,
+				   const struct drm_dsc_picture_parameter_set *pps)
 {
 	struct mipi_dsi_msg msg = {
 		.channel = dsi->channel,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_mm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_mm.c
@@ -151,7 +151,7 @@
 
 INTERVAL_TREE_DEFINE(struct drm_mm_node, rb,
 		     u64, __subtree_last,
-		     START, LAST, static inline, drm_mm_interval_tree)
+		     START, LAST, static inline __maybe_unused, drm_mm_interval_tree)
 
 struct drm_mm_node *
 __drm_mm_interval_first(const struct drm_mm *mm, u64 start, u64 last)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_modes.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_modes.c
@@ -1285,14 +1285,11 @@
  */
 int drm_mode_vrefresh(const struct drm_display_mode *mode)
 {
-	unsigned int num, den;
+	unsigned int num = 1, den = 1;
 
 	if (mode->htotal == 0 || mode->vtotal == 0)
 		return 0;
 
-	num = mode->clock;
-	den = mode->htotal * mode->vtotal;
-
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
 		num *= 2;
 	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
@@ -1300,6 +1297,12 @@
 	if (mode->vscan > 1)
 		den *= mode->vscan;
 
+	if (check_mul_overflow(mode->clock, num, &num))
+		return 0;
+
+	if (check_mul_overflow(mode->htotal * mode->vtotal, den, &den))
+		return 0;
+
 	return DIV_ROUND_CLOSEST_ULL(mul_u32_u32(num, 1000), den);
 }
 EXPORT_SYMBOL(drm_mode_vrefresh);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_modeset_helper.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_modeset_helper.c
@@ -193,13 +193,22 @@
 
 	if (!dev)
 		return 0;
+	/*
+	 * Don't disable polling if it was never initialized
+	 */
+	if (dev->mode_config.poll_enabled)
+		drm_kms_helper_poll_disable(dev);
 
-	drm_kms_helper_poll_disable(dev);
 	drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 1);
 	state = drm_atomic_helper_suspend(dev);
 	if (IS_ERR(state)) {
 		drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0);
-		drm_kms_helper_poll_enable(dev);
+		/*
+		 * Don't enable polling if it was never initialized
+		 */
+		if (dev->mode_config.poll_enabled)
+			drm_kms_helper_poll_enable(dev);
+
 		return PTR_ERR(state);
 	}
 
@@ -239,7 +248,11 @@
 	dev->mode_config.suspend_state = NULL;
 
 	drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0);
-	drm_kms_helper_poll_enable(dev);
+	/*
+	 * Don't enable polling if it is not initialized
+	 */
+	if (dev->mode_config.poll_enabled)
+		drm_kms_helper_poll_enable(dev);
 
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_panel.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_panel.c
@@ -274,19 +274,24 @@
  * The modes probed from the panel are automatically added to the connector
  * that the panel is attached to.
  *
- * Return: The number of modes available from the panel on success or a
- * negative error code on failure.
+ * Return: The number of modes available from the panel on success, or 0 on
+ * failure (no modes).
  */
 int drm_panel_get_modes(struct drm_panel *panel,
 			struct drm_connector *connector)
 {
 	if (!panel)
-		return -EINVAL;
+		return 0;
 
-	if (panel->funcs && panel->funcs->get_modes)
-		return panel->funcs->get_modes(panel, connector);
+	if (panel->funcs && panel->funcs->get_modes) {
+		int num;
 
-	return -EOPNOTSUPP;
+		num = panel->funcs->get_modes(panel, connector);
+		if (num > 0)
+			return num;
+	}
+
+	return 0;
 }
 EXPORT_SYMBOL(drm_panel_get_modes);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_panel_backlight_quirks.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_panel_backlight_quirks.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/array_size.h>
+#include <linux/dmi.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_utils.h>
+
+struct drm_panel_min_backlight_quirk {
+	struct {
+		enum dmi_field field;
+		const char * const value;
+	} dmi_match;
+	struct drm_edid_ident ident;
+	u8 min_brightness;
+};
+
+static const struct drm_panel_min_backlight_quirk drm_panel_min_backlight_quirks[] = {
+	/* 13 inch matte panel */
+	{
+		.dmi_match.field = DMI_BOARD_VENDOR,
+		.dmi_match.value = "Framework",
+		.ident.panel_id = drm_edid_encode_panel_id('B', 'O', 'E', 0x0bca),
+		.ident.name = "NE135FBM-N41",
+		.min_brightness = 0,
+	},
+	/* 13 inch glossy panel */
+	{
+		.dmi_match.field = DMI_BOARD_VENDOR,
+		.dmi_match.value = "Framework",
+		.ident.panel_id = drm_edid_encode_panel_id('B', 'O', 'E', 0x095f),
+		.ident.name = "NE135FBM-N41",
+		.min_brightness = 0,
+	},
+	/* 13 inch 2.8k panel */
+	{
+		.dmi_match.field = DMI_BOARD_VENDOR,
+		.dmi_match.value = "Framework",
+		.ident.panel_id = drm_edid_encode_panel_id('B', 'O', 'E', 0x0cb4),
+		.ident.name = "NE135A1M-NY1",
+		.min_brightness = 0,
+	},
+};
+
+static bool drm_panel_min_backlight_quirk_matches(const struct drm_panel_min_backlight_quirk *quirk,
+						  const struct drm_edid *edid)
+{
+	if (!dmi_match(quirk->dmi_match.field, quirk->dmi_match.value))
+		return false;
+
+	if (!drm_edid_match(edid, &quirk->ident))
+		return false;
+
+	return true;
+}
+
+/**
+ * drm_get_panel_min_brightness_quirk - Get minimum supported brightness level for a panel.
+ * @edid: EDID of the panel to check
+ *
+ * This function checks for platform specific (e.g. DMI based) quirks
+ * providing info on the minimum backlight brightness for systems where this
+ * cannot be probed correctly from the hard-/firm-ware.
+ *
+ * Returns:
+ * A negative error value or
+ * an override value in the range [0, 255] representing 0-100% to be scaled to
+ * the drivers target range.
+ */
+int drm_get_panel_min_brightness_quirk(const struct drm_edid *edid)
+{
+	const struct drm_panel_min_backlight_quirk *quirk;
+	size_t i;
+
+	if (!IS_ENABLED(CONFIG_DMI))
+		return -ENODATA;
+
+	if (!edid)
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(drm_panel_min_backlight_quirks); i++) {
+		quirk = &drm_panel_min_backlight_quirks[i];
+
+		if (drm_panel_min_backlight_quirk_matches(quirk, edid))
+			return quirk->min_brightness;
+	}
+
+	return -ENODATA;
+}
+EXPORT_SYMBOL(drm_get_panel_min_brightness_quirk);
+
+MODULE_DESCRIPTION("Quirks for panel backlight overrides");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_panel_orientation_quirks.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_panel_orientation_quirks.c
@@ -117,6 +117,12 @@
 	.orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
 };
 
+static const struct drm_dmi_panel_orientation_data lcd1080x1920_rightside_up = {
+	.width = 1080,
+	.height = 1920,
+	.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
+};
+
 static const struct drm_dmi_panel_orientation_data lcd1200x1920_rightside_up = {
 	.width = 1200,
 	.height = 1920,
@@ -178,6 +184,12 @@
 		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T103HAF"),
 		},
 		.driver_data = (void *)&lcd800x1280_rightside_up,
+	}, {	/* AYA NEO AYANEO 2 */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "AYANEO 2"),
+		},
+		.driver_data = (void *)&lcd1200x1920_rightside_up,
 	}, {	/* AYA NEO 2021 */
 		.matches = {
 		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYADEVICE"),
@@ -190,12 +202,42 @@
 		  DMI_MATCH(DMI_PRODUCT_NAME, "AIR"),
 		},
 		.driver_data = (void *)&lcd1080x1920_leftside_up,
+	}, {	/* AYA NEO Founder */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYA NEO"),
+		  DMI_MATCH(DMI_PRODUCT_NAME, "AYA NEO Founder"),
+		},
+		.driver_data = (void *)&lcd800x1280_rightside_up,
+	}, {	/* AYA NEO GEEK */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"),
+		  DMI_MATCH(DMI_PRODUCT_NAME, "GEEK"),
+		},
+		.driver_data = (void *)&lcd800x1280_rightside_up,
 	}, {	/* AYA NEO NEXT */
 		.matches = {
 		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
 		  DMI_MATCH(DMI_BOARD_NAME, "NEXT"),
 		},
 		.driver_data = (void *)&lcd800x1280_rightside_up,
+	}, {	/* AYA NEO KUN */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
+		  DMI_MATCH(DMI_BOARD_NAME, "KUN"),
+		},
+		.driver_data = (void *)&lcd1600x2560_rightside_up,
+	}, {    /* AYN Loki Max */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ayn"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Loki Max"),
+		},
+		.driver_data = (void *)&lcd1080x1920_leftside_up,
+	}, {	/* AYN Loki Zero */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ayn"),
+			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Loki Zero"),
+		},
+		.driver_data = (void *)&lcd1080x1920_leftside_up,
 	}, {	/* Chuwi HiBook (CWI514) */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
@@ -279,6 +321,12 @@
 		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1618-03")
 		},
 		.driver_data = (void *)&lcd720x1280_rightside_up,
+	}, {	/* GPD Win Mini */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "GPD"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "G1617-01")
+		},
+		.driver_data = (void *)&lcd1080x1920_rightside_up,
 	}, {	/* I.T.Works TW891 */
 		.matches = {
 		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
@@ -373,7 +421,6 @@
 	}, {	/* Lenovo Yoga Tab 3 X90F */
 		.matches = {
 		 DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
-		 DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
 		 DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"),
 		},
 		.driver_data = (void *)&lcd1600x2560_rightside_up,
@@ -396,6 +443,12 @@
 		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ONE XPLAYER"),
 		},
 		.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 */
 		.matches = {
 		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
@@ -409,6 +462,13 @@
 		  DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"),
 		},
 		.driver_data = (void *)&lcd800x1280_rightside_up,
+	}, {	/* Valve Steam Deck */
+		.matches = {
+		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Valve"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Galileo"),
+		  DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "1"),
+		},
+		.driver_data = (void *)&lcd800x1280_rightside_up,
 	}, {	/* VIOS LTH17 */
 		.matches = {
 		  DMI_EXACT_MATCH(DMI_SYS_VENDOR, "VIOS"),
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_prime.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_prime.c
@@ -582,7 +582,12 @@
 {
 	struct drm_gem_object *obj = dma_buf->priv;
 
-	if (!obj->funcs->get_sg_table)
+	/*
+	 * drm_gem_map_dma_buf() requires obj->get_sg_table(), but drivers
+	 * that implement their own ->map_dma_buf() do not.
+	 */
+	if (dma_buf->ops->map_dma_buf == drm_gem_map_dma_buf &&
+	    !obj->funcs->get_sg_table)
 		return -ENOSYS;
 
 	return drm_gem_pin(obj);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_print.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_print.c
@@ -100,8 +100,9 @@
 			copy = iterator->remain;
 
 		/* Copy out the bit of the string that we need */
-		memcpy(iterator->data,
-			str + (iterator->start - iterator->offset), copy);
+		if (iterator->data)
+			memcpy(iterator->data,
+			       str + (iterator->start - iterator->offset), copy);
 
 		iterator->offset = iterator->start + copy;
 		iterator->remain -= copy;
@@ -110,7 +111,8 @@
 
 		len = min_t(ssize_t, strlen(str), iterator->remain);
 
-		memcpy(iterator->data + pos, str, len);
+		if (iterator->data)
+			memcpy(iterator->data + pos, str, len);
 
 		iterator->offset += len;
 		iterator->remain -= len;
@@ -140,8 +142,9 @@
 	if ((iterator->offset >= iterator->start) && (len < iterator->remain)) {
 		ssize_t pos = iterator->offset - iterator->start;
 
-		snprintf(((char *) iterator->data) + pos,
-			iterator->remain, "%pV", vaf);
+		if (iterator->data)
+			snprintf(((char *) iterator->data) + pos,
+				 iterator->remain, "%pV", vaf);
 
 		iterator->offset += len;
 		iterator->remain -= len;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_probe_helper.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_probe_helper.c
@@ -293,14 +293,17 @@
  * Drivers can call this helper from their device resume implementation. It is
  * not an error to call this even when output polling isn't enabled.
  *
+ * If device polling was never initialized before, this call will trigger a
+ * warning and return.
+ *
  * Note that calls to enable and disable polling must be strictly ordered, which
  * is automatically the case when they're only call from suspend/resume
  * callbacks.
  */
 void drm_kms_helper_poll_enable(struct drm_device *dev)
 {
-	if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll ||
-	    dev->mode_config.poll_running)
+	if (drm_WARN_ON_ONCE(dev, !dev->mode_config.poll_enabled) ||
+	    !drm_kms_helper_poll || dev->mode_config.poll_running)
 		return;
 
 	if (drm_kms_helper_enable_hpd(dev) ||
@@ -419,6 +422,13 @@
 
 	count = connector_funcs->get_modes(connector);
 
+	/* The .get_modes() callback should not return negative values. */
+	if (count < 0) {
+		drm_err(connector->dev, ".get_modes() returned %pe\n",
+			ERR_PTR(count));
+		count = 0;
+	}
+
 	/*
 	 * Fallback for when DDC probe failed in drm_get_edid() and thus skipped
 	 * override/firmware EDID.
@@ -619,8 +629,12 @@
 					 0);
 	}
 
-	/* Re-enable polling in case the global poll config changed. */
-	drm_kms_helper_poll_enable(dev);
+	/*
+	 * Re-enable polling in case the global poll config changed but polling
+	 * is still initialized.
+	 */
+	if (dev->mode_config.poll_enabled)
+		drm_kms_helper_poll_enable(dev);
 
 	if (connector->status == connector_status_disconnected) {
 		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
@@ -873,12 +887,18 @@
  * not an error to call this even when output polling isn't enabled or already
  * disabled. Polling is re-enabled by calling drm_kms_helper_poll_enable().
  *
+ * If however, the polling was never initialized, this call will trigger a
+ * warning and return
+ *
  * Note that calls to enable and disable polling must be strictly ordered, which
  * is automatically the case when they're only call from suspend/resume
  * callbacks.
  */
 void drm_kms_helper_poll_disable(struct drm_device *dev)
 {
+	if (drm_WARN_ON(dev, !dev->mode_config.poll_enabled))
+		return;
+
 	if (dev->mode_config.poll_running)
 		drm_kms_helper_disable_hpd(dev);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/drm_syncobj.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/drm_syncobj.c
@@ -1459,6 +1459,7 @@
 	struct drm_syncobj *syncobj;
 	struct eventfd_ctx *ev_fd_ctx;
 	struct syncobj_eventfd_entry *entry;
+	int ret;
 
 	if (!drm_core_check_feature(dev, DRIVER_SYNCOBJ_TIMELINE))
 		return -EOPNOTSUPP;
@@ -1474,13 +1475,15 @@
 		return -ENOENT;
 
 	ev_fd_ctx = eventfd_ctx_fdget(args->fd);
-	if (IS_ERR(ev_fd_ctx))
-		return PTR_ERR(ev_fd_ctx);
+	if (IS_ERR(ev_fd_ctx)) {
+		ret = PTR_ERR(ev_fd_ctx);
+		goto err_fdget;
+	}
 
 	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 	if (!entry) {
-		eventfd_ctx_put(ev_fd_ctx);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto err_kzalloc;
 	}
 	entry->syncobj = syncobj;
 	entry->ev_fd_ctx = ev_fd_ctx;
@@ -1491,6 +1494,12 @@
 	drm_syncobj_put(syncobj);
 
 	return 0;
+
+err_kzalloc:
+	eventfd_ctx_put(ev_fd_ctx);
+err_fdget:
+	drm_syncobj_put(syncobj);
+	return ret;
 }
 
 int
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
@@ -482,7 +482,8 @@
 	} else {
 		CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE,
 				       VIVS_GL_FLUSH_CACHE_DEPTH |
-				       VIVS_GL_FLUSH_CACHE_COLOR);
+				       VIVS_GL_FLUSH_CACHE_COLOR |
+				       VIVS_GL_FLUSH_CACHE_SHADER_L1);
 		if (has_blt) {
 			CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
 			CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -494,7 +494,7 @@
 	.desc               = "etnaviv DRM",
 	.date               = "20151214",
 	.major              = 1,
-	.minor              = 3,
+	.minor              = 4,
 };
 
 /*
@@ -527,6 +527,16 @@
 	priv->num_gpus = 0;
 	priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
 
+	/*
+	 * If the GPU is part of a system with DMA addressing limitations,
+	 * request pages for our SHM backend buffers from the DMA32 zone to
+	 * hopefully avoid performance killing SWIOTLB bounce buffering.
+	 */
+	if (dma_addressing_limited(dev)) {
+		priv->shm_gfp_mask |= GFP_DMA32;
+		priv->shm_gfp_mask &= ~__GFP_HIGHMEM;
+	}
+
 	priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
 	if (IS_ERR(priv->cmdbuf_suballoc)) {
 		dev_err(drm->dev, "Failed to create cmdbuf suballocator\n");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -343,6 +343,7 @@
 static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj)
 {
 	struct page **pages;
+	pgprot_t prot;
 
 	lockdep_assert_held(&obj->lock);
 
@@ -350,15 +351,28 @@
 	if (IS_ERR(pages))
 		return NULL;
 
-	return vmap(pages, obj->base.size >> PAGE_SHIFT,
-			VM_MAP, pgprot_writecombine(PAGE_KERNEL));
+	switch (obj->flags & ETNA_BO_CACHE_MASK) {
+	case ETNA_BO_CACHED:
+		prot = PAGE_KERNEL;
+		break;
+	case ETNA_BO_UNCACHED:
+		prot = pgprot_noncached(PAGE_KERNEL);
+		break;
+	case ETNA_BO_WC:
+	default:
+		prot = pgprot_writecombine(PAGE_KERNEL);
+	}
+
+	return vmap(pages, obj->base.size >> PAGE_SHIFT, VM_MAP, prot);
 }
 
 static inline enum dma_data_direction etnaviv_op_to_dma_dir(u32 op)
 {
-	if (op & ETNA_PREP_READ)
+	op &= ETNA_PREP_READ | ETNA_PREP_WRITE;
+
+	if (op == ETNA_PREP_READ)
 		return DMA_FROM_DEVICE;
-	else if (op & ETNA_PREP_WRITE)
+	else if (op == ETNA_PREP_WRITE)
 		return DMA_TO_DEVICE;
 	else
 		return DMA_BIDIRECTIONAL;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -632,8 +632,8 @@
 	/* Disable TX clock gating on affected core revisions. */
 	if (etnaviv_is_model_rev(gpu, GC4000, 0x5222) ||
 	    etnaviv_is_model_rev(gpu, GC2000, 0x5108) ||
-	    etnaviv_is_model_rev(gpu, GC2000, 0x6202) ||
-	    etnaviv_is_model_rev(gpu, GC2000, 0x6203))
+	    etnaviv_is_model_rev(gpu, GC7000, 0x6202) ||
+	    etnaviv_is_model_rev(gpu, GC7000, 0x6203))
 		pmc |= VIVS_PM_MODULE_CONTROLS_DISABLE_MODULE_CLOCK_GATING_TX;
 
 	/* Disable SE and RA clock gating on affected core revisions. */
@@ -820,14 +820,6 @@
 	if (ret)
 		goto fail;
 
-	/*
-	 * If the GPU is part of a system with DMA addressing limitations,
-	 * request pages for our SHM backend buffers from the DMA32 zone to
-	 * hopefully avoid performance killing SWIOTLB bounce buffering.
-	 */
-	if (dma_addressing_limited(gpu->dev))
-		priv->shm_gfp_mask |= GFP_DMA32;
-
 	/* Create buffer: */
 	ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer,
 				  PAGE_SIZE);
@@ -1308,6 +1300,8 @@
 {
 	u32 val;
 
+	mutex_lock(&gpu->lock);
+
 	/* disable clock gating */
 	val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
 	val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
@@ -1319,6 +1313,8 @@
 	gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val);
 
 	sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_PRE);
+
+	mutex_unlock(&gpu->lock);
 }
 
 static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
@@ -1328,13 +1324,9 @@
 	unsigned int i;
 	u32 val;
 
-	sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST);
-
-	for (i = 0; i < submit->nr_pmrs; i++) {
-		const struct etnaviv_perfmon_request *pmr = submit->pmrs + i;
+	mutex_lock(&gpu->lock);
 
-		*pmr->bo_vma = pmr->sequence;
-	}
+	sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST);
 
 	/* disable debug register */
 	val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
@@ -1345,6 +1337,14 @@
 	val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
 	val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
 	gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
+
+	mutex_unlock(&gpu->lock);
+
+	for (i = 0; i < submit->nr_pmrs; i++) {
+		const struct etnaviv_perfmon_request *pmr = submit->pmrs + i;
+
+		*pmr->bo_vma = pmr->sequence;
+	}
 }
 
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/etnaviv/etnaviv_hwdb.c
@@ -265,6 +265,9 @@
 bool etnaviv_fill_identity_from_hwdb(struct etnaviv_gpu *gpu)
 {
 	struct etnaviv_chip_identity *ident = &gpu->identity;
+	const u32 product_id = ident->product_id;
+	const u32 customer_id = ident->customer_id;
+	const u32 eco_id = ident->eco_id;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(etnaviv_chip_identities); i++) {
@@ -278,6 +281,12 @@
 			 etnaviv_chip_identities[i].eco_id == ~0U)) {
 			memcpy(ident, &etnaviv_chip_identities[i],
 			       sizeof(*ident));
+
+			/* Restore some id values as ~0U aka 'don't care' might been used. */
+			ident->product_id = product_id;
+			ident->customer_id = customer_id;
+			ident->eco_id = eco_id;
+
 			return true;
 		}
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/etnaviv/etnaviv_sched.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/etnaviv/etnaviv_sched.c
@@ -38,9 +38,6 @@
 	u32 dma_addr;
 	int change;
 
-	/* block scheduler */
-	drm_sched_stop(&gpu->sched, sched_job);
-
 	/*
 	 * If the GPU managed to complete this jobs fence, the timout is
 	 * spurious. Bail out.
@@ -63,6 +60,9 @@
 		goto out_no_timeout;
 	}
 
+	/* block scheduler */
+	drm_sched_stop(&gpu->sched, sched_job);
+
 	if(sched_job)
 		drm_sched_increase_karma(sched_job);
 
@@ -76,8 +76,7 @@
 	return DRM_GPU_SCHED_STAT_NOMINAL;
 
 out_no_timeout:
-	/* restart scheduler after GPU is usable again */
-	drm_sched_start(&gpu->sched, true);
+	list_add(&sched_job->list, &sched_job->sched->pending_list);
 	return DRM_GPU_SCHED_STAT_NOMINAL;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/exynos/exynos_dp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/exynos/exynos_dp.c
@@ -286,7 +286,6 @@
 	.remove_new	= exynos_dp_remove,
 	.driver		= {
 		.name	= "exynos-dp",
-		.owner	= THIS_MODULE,
 		.pm	= pm_ptr(&exynos_dp_pm_ops),
 		.of_match_table = exynos_dp_match,
 	},
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -1174,7 +1174,7 @@
 	struct exynos_drm_ipp *ipp = &ctx->ipp;
 
 	ctx->drm_dev = drm_dev;
-	ctx->drm_dev = drm_dev;
+	ipp->drm_dev = drm_dev;
 	exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv);
 
 	exynos_drm_ipp_register(dev, ipp, &ipp_funcs,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/exynos/exynos_drm_vidi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -309,6 +309,7 @@
 	struct vidi_context *ctx = ctx_from_connector(connector);
 	struct edid *edid;
 	int edid_len;
+	int count;
 
 	/*
 	 * the edid data comes from user side and it would be set
@@ -316,19 +317,23 @@
 	 */
 	if (!ctx->raw_edid) {
 		DRM_DEV_DEBUG_KMS(ctx->dev, "raw_edid is null.\n");
-		return -EFAULT;
+		return 0;
 	}
 
 	edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH;
 	edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL);
 	if (!edid) {
 		DRM_DEV_DEBUG_KMS(ctx->dev, "failed to allocate edid\n");
-		return -ENOMEM;
+		return 0;
 	}
 
 	drm_connector_update_edid_property(connector, edid);
 
-	return drm_add_edid_modes(connector, edid);
+	count = drm_add_edid_modes(connector, edid);
+
+	kfree(edid);
+
+	return count;
 }
 
 static const struct drm_connector_helper_funcs vidi_connector_helper_funcs = {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -887,11 +887,11 @@
 	int ret;
 
 	if (!hdata->ddc_adpt)
-		return -ENODEV;
+		goto no_edid;
 
 	edid = drm_get_edid(connector, hdata->ddc_adpt);
 	if (!edid)
-		return -ENODEV;
+		goto no_edid;
 
 	hdata->dvi_mode = !connector->display_info.is_hdmi;
 	DRM_DEV_DEBUG_KMS(hdata->dev, "%s : width[%d] x height[%d]\n",
@@ -906,6 +906,9 @@
 	kfree(edid);
 
 	return ret;
+
+no_edid:
+	return drm_add_modes_noedid(connector, 640, 480);
 }
 
 static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
@@ -1640,7 +1643,9 @@
 	struct hdmi_context *hdata = dev_get_drvdata(dev);
 	struct drm_connector *connector = &hdata->connector;
 
+	mutex_lock(&connector->eld_mutex);
 	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
+	mutex_unlock(&connector->eld_mutex);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/fsl-dcu/Kconfig
+++ linux-qcom-6.8.0/drivers/gpu/drm/fsl-dcu/Kconfig
@@ -8,6 +8,7 @@
 	select DRM_PANEL
 	select REGMAP_MMIO
 	select VIDEOMODE_HELPERS
+	select MFD_SYSCON if SOC_LS1021A
 	help
 	  Choose this option if you have an Freescale DCU chipset.
 	  If M is selected the module will be called fsl-dcu-drm.
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -100,6 +100,7 @@
 static int fsl_dcu_load(struct drm_device *dev, unsigned long flags)
 {
 	struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
+	struct regmap *scfg;
 	int ret;
 
 	ret = fsl_dcu_drm_modeset_init(fsl_dev);
@@ -108,6 +109,20 @@
 		return ret;
 	}
 
+	scfg = syscon_regmap_lookup_by_compatible("fsl,ls1021a-scfg");
+	if (PTR_ERR(scfg) != -ENODEV) {
+		/*
+		 * For simplicity, enable the PIXCLK unconditionally,
+		 * resulting in increased power consumption. Disabling
+		 * the clock in PM or on unload could be implemented as
+		 * a future improvement.
+		 */
+		ret = regmap_update_bits(scfg, SCFG_PIXCLKCR, SCFG_PIXCLKCR_PXCEN,
+					 SCFG_PIXCLKCR_PXCEN);
+		if (ret < 0)
+			return dev_err_probe(dev->dev, ret, "failed to enable pixclk\n");
+	}
+
 	ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
 	if (ret < 0) {
 		dev_err(dev->dev, "failed to initialize vblank\n");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
@@ -160,6 +160,9 @@
 #define FSL_DCU_ARGB4444		12
 #define FSL_DCU_YUV422			14
 
+#define SCFG_PIXCLKCR			0x28
+#define SCFG_PIXCLKCR_PXCEN		BIT(31)
+
 #define VF610_LAYER_REG_NUM		9
 #define LS1021A_LAYER_REG_NUM		10
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/gma500/Makefile
+++ linux-qcom-6.8.0/drivers/gpu/drm/gma500/Makefile
@@ -34,7 +34,6 @@
 	  psb_intel_lvds.o \
 	  psb_intel_modes.o \
 	  psb_intel_sdvo.o \
-	  psb_lid.o \
 	  psb_irq.o
 
 gma500_gfx-$(CONFIG_ACPI) +=  opregion.o
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/gma500/cdv_intel_lvds.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/gma500/cdv_intel_lvds.c
@@ -311,6 +311,9 @@
 	if (mode_dev->panel_fixed_mode != NULL) {
 		struct drm_display_mode *mode =
 		    drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
+		if (!mode)
+			return 0;
+
 		drm_mode_probed_add(connector, mode);
 		return 1;
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/gma500/psb_device.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/gma500/psb_device.c
@@ -73,8 +73,7 @@
 	}
 
 	psb_intel_lvds_set_brightness(dev, PSB_MAX_BRIGHTNESS);
-	/* This must occur after the backlight is properly initialised */
-	psb_lid_timer_init(dev_priv);
+
 	return 0;
 }
 
@@ -259,8 +258,6 @@
 
 static void psb_chip_teardown(struct drm_device *dev)
 {
-	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);
-	psb_lid_timer_takedown(dev_priv);
 	gma_intel_teardown_gmbus(dev);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/gma500/psb_drv.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/gma500/psb_drv.h
@@ -162,7 +162,6 @@
 #define PSB_NUM_VBLANKS 2
 
 #define PSB_WATCHDOG_DELAY (HZ * 2)
-#define PSB_LID_DELAY (HZ / 10)
 
 #define PSB_MAX_BRIGHTNESS		100
 
@@ -491,11 +490,7 @@
 	/* Hotplug handling */
 	struct work_struct hotplug_work;
 
-	/* LID-Switch */
-	spinlock_t lid_lock;
-	struct timer_list lid_timer;
 	struct psb_intel_opregion opregion;
-	u32 lid_last_state;
 
 	/* Watchdog */
 	uint32_t apm_reg;
@@ -591,10 +586,6 @@
 	int i2c_bus;		/* I2C bus identifier for Moorestown */
 };
 
-/* psb_lid.c */
-extern void psb_lid_timer_init(struct drm_psb_private *dev_priv);
-extern void psb_lid_timer_takedown(struct drm_psb_private *dev_priv);
-
 /* modesetting */
 extern void psb_modeset_init(struct drm_device *dev);
 extern void psb_modeset_cleanup(struct drm_device *dev);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/gma500/psb_intel_lvds.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/gma500/psb_intel_lvds.c
@@ -504,6 +504,9 @@
 	if (mode_dev->panel_fixed_mode != NULL) {
 		struct drm_display_mode *mode =
 		    drm_mode_duplicate(dev, mode_dev->panel_fixed_mode);
+		if (!mode)
+			return 0;
+
 		drm_mode_probed_add(connector, mode);
 		return 1;
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/Makefile
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/Makefile
@@ -33,9 +33,9 @@
 subdir-ccflags-$(CONFIG_DRM_I915_WERROR) += -Werror
 
 # Fine grained warnings disable
-CFLAGS_i915_pci.o = $(call cc-disable-warning, override-init)
-CFLAGS_display/intel_display_device.o = $(call cc-disable-warning, override-init)
-CFLAGS_display/intel_fbdev.o = $(call cc-disable-warning, override-init)
+CFLAGS_i915_pci.o = -Wno-override-init
+CFLAGS_display/intel_display_device.o = -Wno-override-init
+CFLAGS_display/intel_fbdev.o = -Wno-override-init
 
 # Support compiling the display code separately for both i915 and xe
 # drivers. Define I915 when building i915.
@@ -118,6 +118,7 @@
 	gt/intel_ggtt_fencing.o \
 	gt/intel_gt.o \
 	gt/intel_gt_buffer_pool.o \
+	gt/intel_gt_ccs_mode.o \
 	gt/intel_gt_clock_utils.o \
 	gt/intel_gt_debugfs.o \
 	gt/intel_gt_engines_debugfs.o \
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/g4x_dp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/g4x_dp.c
@@ -717,7 +717,6 @@
 {
 	intel_enable_dp(state, encoder, pipe_config, conn_state);
 	intel_edp_backlight_on(pipe_config, conn_state);
-	encoder->audio_enable(encoder, pipe_config, conn_state);
 }
 
 static void vlv_enable_dp(struct intel_atomic_state *state,
@@ -726,7 +725,6 @@
 			  const struct drm_connector_state *conn_state)
 {
 	intel_edp_backlight_on(pipe_config, conn_state);
-	encoder->audio_enable(encoder, pipe_config, conn_state);
 }
 
 static void g4x_pre_enable_dp(struct intel_atomic_state *state,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/icl_dsi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/icl_dsi.c
@@ -1155,7 +1155,6 @@
 	}
 
 	intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_INIT_OTP);
-	intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON);
 
 	/* ensure all panel commands dispatched before enabling transcoder */
 	wait_for_cmds_dispatched_to_panel(encoder);
@@ -1256,6 +1255,8 @@
 	/* step6d: enable dsi transcoder */
 	gen11_dsi_enable_transcoder(encoder);
 
+	intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_DISPLAY_ON);
+
 	/* step7: enable backlight */
 	intel_backlight_enable(crtc_state, conn_state);
 	intel_dsi_vbt_exec_sequence(intel_dsi, MIPI_SEQ_BACKLIGHT_ON);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_audio.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_audio.c
@@ -76,19 +76,6 @@
 				       struct intel_crtc_state *crtc_state);
 };
 
-/* DP N/M table */
-#define LC_810M	810000
-#define LC_540M	540000
-#define LC_270M	270000
-#define LC_162M	162000
-
-struct dp_aud_n_m {
-	int sample_rate;
-	int clock;
-	u16 m;
-	u16 n;
-};
-
 struct hdmi_aud_ncts {
 	int sample_rate;
 	int clock;
@@ -96,60 +83,6 @@
 	int cts;
 };
 
-/* Values according to DP 1.4 Table 2-104 */
-static const struct dp_aud_n_m dp_aud_n_m[] = {
-	{ 32000, LC_162M, 1024, 10125 },
-	{ 44100, LC_162M, 784, 5625 },
-	{ 48000, LC_162M, 512, 3375 },
-	{ 64000, LC_162M, 2048, 10125 },
-	{ 88200, LC_162M, 1568, 5625 },
-	{ 96000, LC_162M, 1024, 3375 },
-	{ 128000, LC_162M, 4096, 10125 },
-	{ 176400, LC_162M, 3136, 5625 },
-	{ 192000, LC_162M, 2048, 3375 },
-	{ 32000, LC_270M, 1024, 16875 },
-	{ 44100, LC_270M, 784, 9375 },
-	{ 48000, LC_270M, 512, 5625 },
-	{ 64000, LC_270M, 2048, 16875 },
-	{ 88200, LC_270M, 1568, 9375 },
-	{ 96000, LC_270M, 1024, 5625 },
-	{ 128000, LC_270M, 4096, 16875 },
-	{ 176400, LC_270M, 3136, 9375 },
-	{ 192000, LC_270M, 2048, 5625 },
-	{ 32000, LC_540M, 1024, 33750 },
-	{ 44100, LC_540M, 784, 18750 },
-	{ 48000, LC_540M, 512, 11250 },
-	{ 64000, LC_540M, 2048, 33750 },
-	{ 88200, LC_540M, 1568, 18750 },
-	{ 96000, LC_540M, 1024, 11250 },
-	{ 128000, LC_540M, 4096, 33750 },
-	{ 176400, LC_540M, 3136, 18750 },
-	{ 192000, LC_540M, 2048, 11250 },
-	{ 32000, LC_810M, 1024, 50625 },
-	{ 44100, LC_810M, 784, 28125 },
-	{ 48000, LC_810M, 512, 16875 },
-	{ 64000, LC_810M, 2048, 50625 },
-	{ 88200, LC_810M, 1568, 28125 },
-	{ 96000, LC_810M, 1024, 16875 },
-	{ 128000, LC_810M, 4096, 50625 },
-	{ 176400, LC_810M, 3136, 28125 },
-	{ 192000, LC_810M, 2048, 16875 },
-};
-
-static const struct dp_aud_n_m *
-audio_config_dp_get_n_m(const struct intel_crtc_state *crtc_state, int rate)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(dp_aud_n_m); i++) {
-		if (rate == dp_aud_n_m[i].sample_rate &&
-		    crtc_state->port_clock == dp_aud_n_m[i].clock)
-			return &dp_aud_n_m[i];
-	}
-
-	return NULL;
-}
-
 static const struct {
 	int clock;
 	u32 config;
@@ -387,47 +320,17 @@
 			   const struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
-	struct i915_audio_component *acomp = i915->display.audio.component;
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
-	enum port port = encoder->port;
-	const struct dp_aud_n_m *nm;
-	int rate;
-	u32 tmp;
-
-	rate = acomp ? acomp->aud_sample_rate[port] : 0;
-	nm = audio_config_dp_get_n_m(crtc_state, rate);
-	if (nm)
-		drm_dbg_kms(&i915->drm, "using Maud %u, Naud %u\n", nm->m,
-			    nm->n);
-	else
-		drm_dbg_kms(&i915->drm, "using automatic Maud, Naud\n");
-
-	tmp = intel_de_read(i915, HSW_AUD_CFG(cpu_transcoder));
-	tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
-	tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK;
-	tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
-	tmp |= AUD_CONFIG_N_VALUE_INDEX;
-
-	if (nm) {
-		tmp &= ~AUD_CONFIG_N_MASK;
-		tmp |= AUD_CONFIG_N(nm->n);
-		tmp |= AUD_CONFIG_N_PROG_ENABLE;
-	}
-
-	intel_de_write(i915, HSW_AUD_CFG(cpu_transcoder), tmp);
-
-	tmp = intel_de_read(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder));
-	tmp &= ~AUD_CONFIG_M_MASK;
-	tmp &= ~AUD_M_CTS_M_VALUE_INDEX;
-	tmp &= ~AUD_M_CTS_M_PROG_ENABLE;
 
-	if (nm) {
-		tmp |= nm->m;
-		tmp |= AUD_M_CTS_M_VALUE_INDEX;
-		tmp |= AUD_M_CTS_M_PROG_ENABLE;
-	}
+	/* Enable time stamps. Let HW calculate Maud/Naud values */
+	intel_de_rmw(i915, HSW_AUD_CFG(cpu_transcoder),
+		     AUD_CONFIG_N_VALUE_INDEX |
+		     AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK |
+		     AUD_CONFIG_UPPER_N_MASK |
+		     AUD_CONFIG_LOWER_N_MASK |
+		     AUD_CONFIG_N_PROG_ENABLE,
+		     AUD_CONFIG_N_VALUE_INDEX);
 
-	intel_de_write(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder), tmp);
 }
 
 static void
@@ -1349,17 +1252,6 @@
 static void i915_audio_component_init(struct drm_i915_private *i915)
 {
 	u32 aud_freq, aud_freq_init;
-	int ret;
-
-	ret = component_add_typed(i915->drm.dev,
-				  &i915_audio_component_bind_ops,
-				  I915_COMPONENT_AUDIO);
-	if (ret < 0) {
-		drm_err(&i915->drm,
-			"failed to add audio component (%d)\n", ret);
-		/* continue with reduced functionality */
-		return;
-	}
 
 	if (DISPLAY_VER(i915) >= 9) {
 		aud_freq_init = intel_de_read(i915, AUD_FREQ_CNTRL);
@@ -1382,6 +1274,21 @@
 
 	/* init with current cdclk */
 	intel_audio_cdclk_change_post(i915);
+}
+
+static void i915_audio_component_register(struct drm_i915_private *i915)
+{
+	int ret;
+
+	ret = component_add_typed(i915->drm.dev,
+				  &i915_audio_component_bind_ops,
+				  I915_COMPONENT_AUDIO);
+	if (ret < 0) {
+		drm_err(&i915->drm,
+			"failed to add audio component (%d)\n", ret);
+		/* continue with reduced functionality */
+		return;
+	}
 
 	i915->display.audio.component_registered = true;
 }
@@ -1414,6 +1321,12 @@
 		i915_audio_component_init(i915);
 }
 
+void intel_audio_register(struct drm_i915_private *i915)
+{
+	if (!i915->display.audio.lpe.platdev)
+		i915_audio_component_register(i915);
+}
+
 /**
  * intel_audio_deinit() - deinitialize the audio driver
  * @i915: the i915 drm device private data
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_audio.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_audio.h
@@ -28,6 +28,7 @@
 void intel_audio_cdclk_change_pre(struct drm_i915_private *dev_priv);
 void intel_audio_cdclk_change_post(struct drm_i915_private *dev_priv);
 void intel_audio_init(struct drm_i915_private *dev_priv);
+void intel_audio_register(struct drm_i915_private *i915);
 void intel_audio_deinit(struct drm_i915_private *dev_priv);
 void intel_audio_sdp_split_update(const struct intel_crtc_state *crtc_state);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_backlight.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_backlight.c
@@ -1011,7 +1011,7 @@
 {
 	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 
-	return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(i915)->rawclk_freq),
+	return DIV_ROUND_CLOSEST(KHz(DISPLAY_RUNTIME_INFO(i915)->rawclk_freq),
 				 pwm_freq_hz);
 }
 
@@ -1073,7 +1073,7 @@
 {
 	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 
-	return DIV_ROUND_CLOSEST(KHz(RUNTIME_INFO(i915)->rawclk_freq),
+	return DIV_ROUND_CLOSEST(KHz(DISPLAY_RUNTIME_INFO(i915)->rawclk_freq),
 				 pwm_freq_hz * 128);
 }
 
@@ -1091,7 +1091,7 @@
 	int clock;
 
 	if (IS_PINEVIEW(i915))
-		clock = KHz(RUNTIME_INFO(i915)->rawclk_freq);
+		clock = KHz(DISPLAY_RUNTIME_INFO(i915)->rawclk_freq);
 	else
 		clock = KHz(i915->display.cdclk.hw.cdclk);
 
@@ -1109,7 +1109,7 @@
 	int clock;
 
 	if (IS_G4X(i915))
-		clock = KHz(RUNTIME_INFO(i915)->rawclk_freq);
+		clock = KHz(DISPLAY_RUNTIME_INFO(i915)->rawclk_freq);
 	else
 		clock = KHz(i915->display.cdclk.hw.cdclk);
 
@@ -1133,7 +1133,7 @@
 			clock = MHz(25);
 		mul = 16;
 	} else {
-		clock = KHz(RUNTIME_INFO(i915)->rawclk_freq);
+		clock = KHz(DISPLAY_RUNTIME_INFO(i915)->rawclk_freq);
 		mul = 128;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_bios.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_bios.c
@@ -1042,22 +1042,11 @@
 	panel->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI;
 	panel->vbt.backlight.controller = 0;
 	if (i915->display.vbt.version >= 191) {
-		size_t exp_size;
+		const struct lfp_backlight_control_method *method;
 
-		if (i915->display.vbt.version >= 236)
-			exp_size = sizeof(struct bdb_lfp_backlight_data);
-		else if (i915->display.vbt.version >= 234)
-			exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_234;
-		else
-			exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_191;
-
-		if (get_blocksize(backlight_data) >= exp_size) {
-			const struct lfp_backlight_control_method *method;
-
-			method = &backlight_data->backlight_control[panel_type];
-			panel->vbt.backlight.type = method->type;
-			panel->vbt.backlight.controller = method->controller;
-		}
+		method = &backlight_data->backlight_control[panel_type];
+		panel->vbt.backlight.type = method->type;
+		panel->vbt.backlight.controller = method->controller;
 	}
 
 	panel->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
@@ -1952,16 +1941,12 @@
  * these devices we split the init OTP sequence into a deassert sequence and
  * the actual init OTP part.
  */
-static void fixup_mipi_sequences(struct drm_i915_private *i915,
-				 struct intel_panel *panel)
+static void vlv_fixup_mipi_sequences(struct drm_i915_private *i915,
+				     struct intel_panel *panel)
 {
 	u8 *init_otp;
 	int len;
 
-	/* Limit this to VLV for now. */
-	if (!IS_VALLEYVIEW(i915))
-		return;
-
 	/* Limit this to v1 vid-mode sequences */
 	if (panel->vbt.dsi.config->is_cmd_mode ||
 	    panel->vbt.dsi.seq_version != 1)
@@ -1997,6 +1982,41 @@
 	panel->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] = init_otp + len - 1;
 }
 
+/*
+ * Some machines (eg. Lenovo 82TQ) appear to have broken
+ * VBT sequences:
+ * - INIT_OTP is not present at all
+ * - what should be in INIT_OTP is in DISPLAY_ON
+ * - what should be in DISPLAY_ON is in BACKLIGHT_ON
+ *   (along with the actual backlight stuff)
+ *
+ * To make those work we simply swap DISPLAY_ON and INIT_OTP.
+ *
+ * TODO: Do we need to limit this to specific machines,
+ *       or examine the contents of the sequences to
+ *       avoid false positives?
+ */
+static void icl_fixup_mipi_sequences(struct drm_i915_private *i915,
+				     struct intel_panel *panel)
+{
+	if (!panel->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP] &&
+	    panel->vbt.dsi.sequence[MIPI_SEQ_DISPLAY_ON]) {
+		drm_dbg_kms(&i915->drm, "Broken VBT: Swapping INIT_OTP and DISPLAY_ON sequences\n");
+
+		swap(panel->vbt.dsi.sequence[MIPI_SEQ_INIT_OTP],
+		     panel->vbt.dsi.sequence[MIPI_SEQ_DISPLAY_ON]);
+	}
+}
+
+static void fixup_mipi_sequences(struct drm_i915_private *i915,
+				 struct intel_panel *panel)
+{
+	if (DISPLAY_VER(i915) >= 11)
+		icl_fixup_mipi_sequences(i915, panel);
+	else if (IS_VALLEYVIEW(i915))
+		vlv_fixup_mipi_sequences(i915, panel);
+}
+
 static void
 parse_mipi_sequence(struct drm_i915_private *i915,
 		    struct intel_panel *panel)
@@ -3344,6 +3364,9 @@
 {
 	const struct child_device_config *child = &devdata->child;
 
+	if (!devdata)
+		return false;
+
 	if (!intel_bios_encoder_supports_dp(devdata) ||
 	    !intel_bios_encoder_supports_hdmi(devdata))
 		return false;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_bw.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_bw.c
@@ -162,7 +162,9 @@
 				1);
 
 	if (ret < 0) {
-		drm_err(&dev_priv->drm, "Failed to disable qgv points (%d) points: 0x%x\n", ret, points_mask);
+		drm_err(&dev_priv->drm,
+			"Failed to disable qgv points (0x%x) points: 0x%x\n",
+			ret, points_mask);
 		return ret;
 	}
 
@@ -290,8 +292,10 @@
 		struct intel_qgv_point *sp = &qi->points[i];
 
 		ret = intel_read_qgv_point_info(dev_priv, sp, i);
-		if (ret)
+		if (ret) {
+			drm_dbg_kms(&dev_priv->drm, "Could not read QGV %d info\n", i);
 			return ret;
+		}
 
 		drm_dbg_kms(&dev_priv->drm,
 			    "QGV %d: DCLK=%d tRP=%d tRDPRE=%d tRAS=%d tRCD=%d tRC=%d\n",
@@ -659,6 +663,22 @@
 	return bi->psf_bw[psf_gv_point];
 }
 
+static unsigned int icl_qgv_bw(struct drm_i915_private *i915,
+			       int num_active_planes, int qgv_point)
+{
+	unsigned int idx;
+
+	if (DISPLAY_VER(i915) >= 12)
+		idx = tgl_max_bw_index(i915, num_active_planes, qgv_point);
+	else
+		idx = icl_max_bw_index(i915, num_active_planes, qgv_point);
+
+	if (idx >= ARRAY_SIZE(i915->display.bw.max))
+		return 0;
+
+	return i915->display.bw.max[idx].deratedbw[qgv_point];
+}
+
 void intel_bw_init_hw(struct drm_i915_private *dev_priv)
 {
 	if (!HAS_DISPLAY(dev_priv))
@@ -735,6 +755,7 @@
 		intel_bw_crtc_data_rate(crtc_state);
 	bw_state->num_active_planes[crtc->pipe] =
 		intel_bw_crtc_num_active_planes(crtc_state);
+	bw_state->force_check_qgv = true;
 
 	drm_dbg_kms(&i915->drm, "pipe %c data rate %u num active planes %u\n",
 		    pipe_name(crtc->pipe),
@@ -804,6 +825,80 @@
 	return to_intel_bw_state(bw_state);
 }
 
+static unsigned int icl_max_bw_qgv_point_mask(struct drm_i915_private *i915,
+					      int num_active_planes)
+{
+	unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points;
+	unsigned int max_bw_point = 0;
+	unsigned int max_bw = 0;
+	int i;
+
+	for (i = 0; i < num_qgv_points; i++) {
+		unsigned int max_data_rate =
+			icl_qgv_bw(i915, num_active_planes, i);
+
+		/*
+		 * We need to know which qgv point gives us
+		 * maximum bandwidth in order to disable SAGV
+		 * if we find that we exceed SAGV block time
+		 * with watermarks. By that moment we already
+		 * have those, as it is calculated earlier in
+		 * intel_atomic_check,
+		 */
+		if (max_data_rate > max_bw) {
+			max_bw_point = BIT(i);
+			max_bw = max_data_rate;
+		}
+	}
+
+	return max_bw_point;
+}
+
+static u16 icl_prepare_qgv_points_mask(struct drm_i915_private *i915,
+				       unsigned int qgv_points,
+				       unsigned int psf_points)
+{
+	return ~(ICL_PCODE_REQ_QGV_PT(qgv_points) |
+		 ADLS_PCODE_REQ_PSF_PT(psf_points)) & icl_qgv_points_mask(i915);
+}
+
+static unsigned int icl_max_bw_psf_gv_point_mask(struct drm_i915_private *i915)
+{
+	unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points;
+	unsigned int max_bw_point_mask = 0;
+	unsigned int max_bw = 0;
+	int i;
+
+	for (i = 0; i < num_psf_gv_points; i++) {
+		unsigned int max_data_rate = adl_psf_bw(i915, i);
+
+		if (max_data_rate > max_bw) {
+			max_bw_point_mask = BIT(i);
+			max_bw = max_data_rate;
+		} else if (max_data_rate == max_bw) {
+			max_bw_point_mask |= BIT(i);
+		}
+	}
+
+	return max_bw_point_mask;
+}
+
+static void icl_force_disable_sagv(struct drm_i915_private *i915,
+				   struct intel_bw_state *bw_state)
+{
+	unsigned int qgv_points = icl_max_bw_qgv_point_mask(i915, 0);
+	unsigned int psf_points = icl_max_bw_psf_gv_point_mask(i915);
+
+	bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(i915,
+								qgv_points,
+								psf_points);
+
+	drm_dbg_kms(&i915->drm, "Forcing SAGV disable: mask 0x%x\n",
+		    bw_state->qgv_points_mask);
+
+	icl_pcode_restrict_qgv_points(i915, bw_state->qgv_points_mask);
+}
+
 static int mtl_find_qgv_points(struct drm_i915_private *i915,
 			       unsigned int data_rate,
 			       unsigned int num_active_planes,
@@ -881,8 +976,6 @@
 			       const struct intel_bw_state *old_bw_state,
 			       struct intel_bw_state *new_bw_state)
 {
-	unsigned int max_bw_point = 0;
-	unsigned int max_bw = 0;
 	unsigned int num_psf_gv_points = i915->display.bw.max[0].num_psf_gv_points;
 	unsigned int num_qgv_points = i915->display.bw.max[0].num_qgv_points;
 	u16 psf_points = 0;
@@ -895,31 +988,8 @@
 		return ret;
 
 	for (i = 0; i < num_qgv_points; i++) {
-		unsigned int idx;
-		unsigned int max_data_rate;
-
-		if (DISPLAY_VER(i915) >= 12)
-			idx = tgl_max_bw_index(i915, num_active_planes, i);
-		else
-			idx = icl_max_bw_index(i915, num_active_planes, i);
-
-		if (idx >= ARRAY_SIZE(i915->display.bw.max))
-			continue;
-
-		max_data_rate = i915->display.bw.max[idx].deratedbw[i];
-
-		/*
-		 * We need to know which qgv point gives us
-		 * maximum bandwidth in order to disable SAGV
-		 * if we find that we exceed SAGV block time
-		 * with watermarks. By that moment we already
-		 * have those, as it is calculated earlier in
-		 * intel_atomic_check,
-		 */
-		if (max_data_rate > max_bw) {
-			max_bw_point = i;
-			max_bw = max_data_rate;
-		}
+		unsigned int max_data_rate = icl_qgv_bw(i915,
+							num_active_planes, i);
 		if (max_data_rate >= data_rate)
 			qgv_points |= BIT(i);
 
@@ -963,20 +1033,18 @@
 	 * cause.
 	 */
 	if (!intel_can_enable_sagv(i915, new_bw_state)) {
-		qgv_points = BIT(max_bw_point);
-		drm_dbg_kms(&i915->drm, "No SAGV, using single QGV point %d\n",
-			    max_bw_point);
+		qgv_points = icl_max_bw_qgv_point_mask(i915, num_active_planes);
+		drm_dbg_kms(&i915->drm, "No SAGV, using single QGV point mask 0x%x\n",
+			    qgv_points);
 	}
 
 	/*
 	 * We store the ones which need to be masked as that is what PCode
 	 * actually accepts as a parameter.
 	 */
-	new_bw_state->qgv_points_mask =
-		~(ICL_PCODE_REQ_QGV_PT(qgv_points) |
-		  ADLS_PCODE_REQ_PSF_PT(psf_points)) &
-		icl_qgv_points_mask(i915);
-
+	new_bw_state->qgv_points_mask = icl_prepare_qgv_points_mask(i915,
+								    qgv_points,
+								    psf_points);
 	/*
 	 * If the actual mask had changed we need to make sure that
 	 * the commits are serialized(in case this is a nomodeset, nonblocking)
@@ -1272,8 +1340,9 @@
 	new_bw_state = intel_atomic_get_new_bw_state(state);
 
 	if (new_bw_state &&
-	    intel_can_enable_sagv(i915, old_bw_state) !=
-	    intel_can_enable_sagv(i915, new_bw_state))
+	    (intel_can_enable_sagv(i915, old_bw_state) !=
+	     intel_can_enable_sagv(i915, new_bw_state) ||
+	     new_bw_state->force_check_qgv))
 		changed = true;
 
 	/*
@@ -1287,6 +1356,8 @@
 	if (ret)
 		return ret;
 
+	new_bw_state->force_check_qgv = false;
+
 	return 0;
 }
 
@@ -1313,7 +1384,7 @@
 	.atomic_destroy_state = intel_bw_destroy_state,
 };
 
-int intel_bw_init(struct drm_i915_private *dev_priv)
+int intel_bw_init(struct drm_i915_private *i915)
 {
 	struct intel_bw_state *state;
 
@@ -1321,8 +1392,15 @@
 	if (!state)
 		return -ENOMEM;
 
-	intel_atomic_global_obj_init(dev_priv, &dev_priv->display.bw.obj,
+	intel_atomic_global_obj_init(i915, &i915->display.bw.obj,
 				     &state->base, &intel_bw_funcs);
 
+	/*
+	 * Limit this only if we have SAGV. And for Display version 14 onwards
+	 * sagv is handled though pmdemand requests
+	 */
+	if (intel_has_sagv(i915) && IS_DISPLAY_VER(i915, 11, 13))
+		icl_force_disable_sagv(i915, state);
+
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_bw.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_bw.h
@@ -47,6 +47,12 @@
 	 */
 	u16 qgv_points_mask;
 
+	/*
+	 * Flag to force the QGV comparison in atomic check right after the
+	 * hw state readout
+	 */
+	bool force_check_qgv;
+
 	int min_cdclk[I915_MAX_PIPES];
 	unsigned int data_rate[I915_MAX_PIPES];
 	u8 num_active_planes[I915_MAX_PIPES];
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2512,7 +2512,8 @@
 		intel_atomic_get_old_cdclk_state(state);
 	const struct intel_cdclk_state *new_cdclk_state =
 		intel_atomic_get_new_cdclk_state(state);
-	enum pipe pipe = new_cdclk_state->pipe;
+	struct intel_cdclk_config cdclk_config;
+	enum pipe pipe;
 
 	if (!intel_cdclk_changed(&old_cdclk_state->actual,
 				 &new_cdclk_state->actual))
@@ -2521,12 +2522,25 @@
 	if (IS_DG2(i915))
 		intel_cdclk_pcode_pre_notify(state);
 
-	if (pipe == INVALID_PIPE ||
-	    old_cdclk_state->actual.cdclk <= new_cdclk_state->actual.cdclk) {
-		drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
+	if (new_cdclk_state->disable_pipes) {
+		cdclk_config = new_cdclk_state->actual;
+		pipe = INVALID_PIPE;
+	} else {
+		if (new_cdclk_state->actual.cdclk >= old_cdclk_state->actual.cdclk) {
+			cdclk_config = new_cdclk_state->actual;
+			pipe = new_cdclk_state->pipe;
+		} else {
+			cdclk_config = old_cdclk_state->actual;
+			pipe = INVALID_PIPE;
+		}
 
-		intel_set_cdclk(i915, &new_cdclk_state->actual, pipe);
+		cdclk_config.voltage_level = max(new_cdclk_state->actual.voltage_level,
+						 old_cdclk_state->actual.voltage_level);
 	}
+
+	drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
+
+	intel_set_cdclk(i915, &cdclk_config, pipe);
 }
 
 /**
@@ -2544,7 +2558,7 @@
 		intel_atomic_get_old_cdclk_state(state);
 	const struct intel_cdclk_state *new_cdclk_state =
 		intel_atomic_get_new_cdclk_state(state);
-	enum pipe pipe = new_cdclk_state->pipe;
+	enum pipe pipe;
 
 	if (!intel_cdclk_changed(&old_cdclk_state->actual,
 				 &new_cdclk_state->actual))
@@ -2553,12 +2567,15 @@
 	if (IS_DG2(i915))
 		intel_cdclk_pcode_post_notify(state);
 
-	if (pipe != INVALID_PIPE &&
-	    old_cdclk_state->actual.cdclk > new_cdclk_state->actual.cdclk) {
-		drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
+	if (!new_cdclk_state->disable_pipes &&
+	    new_cdclk_state->actual.cdclk < old_cdclk_state->actual.cdclk)
+		pipe = new_cdclk_state->pipe;
+	else
+		pipe = INVALID_PIPE;
 
-		intel_set_cdclk(i915, &new_cdclk_state->actual, pipe);
-	}
+	drm_WARN_ON(&i915->drm, !new_cdclk_state->base.changed);
+
+	intel_set_cdclk(i915, &new_cdclk_state->actual, pipe);
 }
 
 static int intel_pixel_rate_to_cdclk(const struct intel_crtc_state *crtc_state)
@@ -3036,6 +3053,7 @@
 		return NULL;
 
 	cdclk_state->pipe = INVALID_PIPE;
+	cdclk_state->disable_pipes = false;
 
 	return &cdclk_state->base;
 }
@@ -3214,6 +3232,8 @@
 		if (ret)
 			return ret;
 
+		new_cdclk_state->disable_pipes = true;
+
 		drm_dbg_kms(&dev_priv->drm,
 			    "Modeset required for cdclk change\n");
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_cdclk.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_cdclk.h
@@ -51,6 +51,9 @@
 
 	/* bitmask of active pipes */
 	u8 active_pipes;
+
+	/* update cdclk with pipes disabled */
+	bool disable_pipes;
 };
 
 int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_color.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_color.c
@@ -1328,19 +1328,29 @@
 	lut = blob->data;
 
 	/*
-	 * DSB fails to correctly load the legacy LUT
-	 * unless we either write each entry twice,
-	 * or use non-posted writes
+	 * DSB fails to correctly load the legacy LUT unless
+	 * we either write each entry twice when using posted
+	 * writes, or we use non-posted writes.
+	 *
+	 * If palette anti-collision is active during LUT
+	 * register writes:
+	 * - posted writes simply get dropped and thus the LUT
+	 *   contents may not be correctly updated
+	 * - non-posted writes are blocked and thus the LUT
+	 *   contents are always correct, but simultaneous CPU
+	 *   MMIO access will start to fail
+	 *
+	 * Choose the lesser of two evils and use posted writes.
+	 * Using posted writes is also faster, even when having
+	 * to write each register twice.
 	 */
-	if (crtc_state->dsb)
-		intel_dsb_nonpost_start(crtc_state->dsb);
-
-	for (i = 0; i < 256; i++)
+	for (i = 0; i < 256; i++) {
 		ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
 			      i9xx_lut_8(&lut[i]));
-
-	if (crtc_state->dsb)
-		intel_dsb_nonpost_end(crtc_state->dsb);
+		if (crtc_state->dsb)
+			ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
+				      i9xx_lut_8(&lut[i]));
+	}
 }
 
 static void ilk_load_lut_10(const struct intel_crtc_state *crtc_state,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_cursor.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -35,12 +35,10 @@
 {
 	struct drm_i915_private *dev_priv =
 		to_i915(plane_state->uapi.plane->dev);
-	const struct drm_framebuffer *fb = plane_state->hw.fb;
-	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
 	u32 base;
 
 	if (DISPLAY_INFO(dev_priv)->cursor_needs_physical)
-		base = i915_gem_object_get_dma_address(obj, 0);
+		base = plane_state->phys_dma_addr;
 	else
 		base = intel_plane_ggtt_offset(plane_state);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_cx0_phy.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_cx0_phy.c
@@ -1892,14 +1892,6 @@
 		      0, C10_VDR_CTRL_MSGBUS_ACCESS,
 		      MB_WRITE_COMMITTED);
 
-	/* Custom width needs to be programmed to 0 for both the phy lanes */
-	intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CUSTOM_WIDTH,
-		      C10_VDR_CUSTOM_WIDTH_MASK, C10_VDR_CUSTOM_WIDTH_8_10,
-		      MB_WRITE_COMMITTED);
-	intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),
-		      0, C10_VDR_CTRL_UPDATE_CFG,
-		      MB_WRITE_COMMITTED);
-
 	/* Program the pll values only for the master lane */
 	for (i = 0; i < ARRAY_SIZE(pll_state->pll); i++)
 		intel_cx0_write(i915, encoder->port, INTEL_CX0_LANE0, PHY_C10_VDR_PLL(i),
@@ -1909,6 +1901,10 @@
 	intel_cx0_write(i915, encoder->port, INTEL_CX0_LANE0, PHY_C10_VDR_CMN(0), pll_state->cmn, MB_WRITE_COMMITTED);
 	intel_cx0_write(i915, encoder->port, INTEL_CX0_LANE0, PHY_C10_VDR_TX(0), pll_state->tx, MB_WRITE_COMMITTED);
 
+	/* Custom width needs to be programmed to 0 for both the phy lanes */
+	intel_cx0_rmw(i915, encoder->port, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CUSTOM_WIDTH,
+		      C10_VDR_CUSTOM_WIDTH_MASK, C10_VDR_CUSTOM_WIDTH_8_10,
+		      MB_WRITE_COMMITTED);
 	intel_cx0_rmw(i915, encoder->port, INTEL_CX0_LANE0, PHY_C10_VDR_CONTROL(1),
 		      0, C10_VDR_CTRL_MASTER_LANE | C10_VDR_CTRL_UPDATE_CFG,
 		      MB_WRITE_COMMITTED);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_ddi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -907,7 +907,7 @@
 	 * instead of a specific AUX_IO_<port> reference without powering up any
 	 * extra wells.
 	 */
-	if (intel_encoder_can_psr(&dig_port->base))
+	if (intel_psr_needs_aux_io_power(&dig_port->base, crtc_state))
 		return intel_display_power_aux_io_domain(i915, dig_port->aux_ch);
 	else if (DISPLAY_VER(i915) < 14 &&
 		 (intel_crtc_has_dp_encoder(crtc_state) ||
@@ -4229,7 +4229,12 @@
 static bool crtcs_port_sync_compatible(const struct intel_crtc_state *crtc_state1,
 				       const struct intel_crtc_state *crtc_state2)
 {
+	/*
+	 * FIXME the modeset sequence is currently wrong and
+	 * can't deal with bigjoiner + port sync at the same time.
+	 */
 	return crtc_state1->hw.active && crtc_state2->hw.active &&
+		!crtc_state1->bigjoiner_pipes && !crtc_state2->bigjoiner_pipes &&
 		crtc_state1->output_types == crtc_state2->output_types &&
 		crtc_state1->output_format == crtc_state2->output_format &&
 		crtc_state1->lane_count == crtc_state2->lane_count &&
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_display_core.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_display_core.h
@@ -271,6 +271,9 @@
 };
 
 struct intel_display {
+	/* drm device backpointer */
+	struct drm_device *drm;
+
 	/* Display functions */
 	struct {
 		/* Top level crtc-ish functions */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_display_device.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_display_device.c
@@ -922,6 +922,9 @@
 	const struct intel_display_device_info *info;
 	u16 ver, rel, step;
 
+	/* Add drm device backpointer as early as possible. */
+	i915->display.drm = &i915->drm;
+
 	if (HAS_GMD_ID(i915))
 		info = probe_gmdid_display(i915, &ver, &rel, &step);
 	else
@@ -1095,6 +1098,9 @@
 		}
 	}
 
+	display_runtime->rawclk_freq = intel_read_rawclk(i915);
+	drm_dbg_kms(&i915->drm, "rawclk rate: %d kHz\n", display_runtime->rawclk_freq);
+
 	return;
 
 display_fused_off:
@@ -1137,6 +1143,8 @@
 	drm_printf(p, "has_hdcp: %s\n", str_yes_no(runtime->has_hdcp));
 	drm_printf(p, "has_dmc: %s\n", str_yes_no(runtime->has_dmc));
 	drm_printf(p, "has_dsc: %s\n", str_yes_no(runtime->has_dsc));
+
+	drm_printf(p, "rawclk rate: %u kHz\n", runtime->rawclk_freq);
 }
 
 /*
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_display_device.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_display_device.h
@@ -47,6 +47,7 @@
 #define HAS_DPT(i915)			(DISPLAY_VER(i915) >= 13)
 #define HAS_DSB(i915)			(DISPLAY_INFO(i915)->has_dsb)
 #define HAS_DSC(__i915)			(DISPLAY_RUNTIME_INFO(__i915)->has_dsc)
+#define HAS_DSC_MST(__i915)		(DISPLAY_VER(__i915) >= 12 && HAS_DSC(__i915))
 #define HAS_FBC(i915)			(DISPLAY_RUNTIME_INFO(i915)->fbc_mask != 0)
 #define HAS_FPGA_DBG_UNCLAIMED(i915)	(DISPLAY_INFO(i915)->has_fpga_dbg)
 #define HAS_FW_BLC(i915)		(DISPLAY_VER(i915) >= 3)
@@ -114,6 +115,8 @@
 		u16 step;
 	} ip;
 
+	u32 rawclk_freq;
+
 	u8 pipe_mask;
 	u8 cpu_transcoder_mask;
 	u16 port_mask;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_display_driver.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_display_driver.c
@@ -394,6 +394,8 @@
 
 	intel_audio_init(i915);
 
+	intel_audio_register(i915);
+
 	intel_display_debugfs_register(i915);
 
 	/*
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_display_power.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_display_power.c
@@ -1706,6 +1706,14 @@
 	/* Wa_14011503030:xelpd */
 	if (DISPLAY_VER(dev_priv) == 13)
 		intel_de_write(dev_priv, XELPD_DISPLAY_ERR_FATAL_MASK, ~0);
+
+	/* Wa_15013987218 */
+	if (DISPLAY_VER(dev_priv) == 20) {
+		intel_de_rmw(dev_priv, SOUTH_DSPCLK_GATE_D,
+			     0, PCH_GMBUSUNIT_CLOCK_GATE_DISABLE);
+		intel_de_rmw(dev_priv, SOUTH_DSPCLK_GATE_D,
+			     PCH_GMBUSUNIT_CLOCK_GATE_DISABLE, 0);
+	}
 }
 
 static void icl_display_core_uninit(struct drm_i915_private *dev_priv)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_display_power_well.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_display_power_well.c
@@ -1174,9 +1174,9 @@
 		       MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE);
 	intel_de_write(dev_priv, CBR1_VLV, 0);
 
-	drm_WARN_ON(&dev_priv->drm, RUNTIME_INFO(dev_priv)->rawclk_freq == 0);
+	drm_WARN_ON(&dev_priv->drm, DISPLAY_RUNTIME_INFO(dev_priv)->rawclk_freq == 0);
 	intel_de_write(dev_priv, RAWCLK_FREQ_VLV,
-		       DIV_ROUND_CLOSEST(RUNTIME_INFO(dev_priv)->rawclk_freq,
+		       DIV_ROUND_CLOSEST(DISPLAY_RUNTIME_INFO(dev_priv)->rawclk_freq,
 					 1000));
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_display_trace.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_display_trace.h
@@ -411,7 +411,7 @@
 			   struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev),
 									 plane->pipe);
 			   __assign_str(dev, __dev_name_kms(plane));
-			   __assign_str(name, plane->base.name)
+			   __assign_str(name, plane->base.name);
 			   __entry->pipe = crtc->pipe;
 			   __entry->frame = intel_crtc_get_vblank_counter(crtc);
 			   __entry->scanline = intel_get_crtc_scanline(crtc);
@@ -438,7 +438,7 @@
 			   struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev),
 									 plane->pipe);
 			   __assign_str(dev, __dev_name_kms(plane));
-			   __assign_str(name, plane->base.name)
+			   __assign_str(name, plane->base.name);
 			   __entry->pipe = crtc->pipe;
 			   __entry->frame = intel_crtc_get_vblank_counter(crtc);
 			   __entry->scanline = intel_get_crtc_scanline(crtc);
@@ -465,7 +465,7 @@
 			   struct intel_crtc *crtc = intel_crtc_for_pipe(to_i915(plane->base.dev),
 									 plane->pipe);
 			   __assign_str(dev, __dev_name_kms(plane));
-			   __assign_str(name, plane->base.name)
+			   __assign_str(name, plane->base.name);
 			   __entry->pipe = crtc->pipe;
 			   __entry->frame = intel_crtc_get_vblank_counter(crtc);
 			   __entry->scanline = intel_get_crtc_scanline(crtc);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_display_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -719,6 +719,7 @@
 #define PLANE_HAS_FENCE BIT(0)
 
 	struct intel_fb_view view;
+	u32 phys_dma_addr; /* for cursor_needs_physical */
 
 	/* Plane pxp decryption state */
 	bool decrypt;
@@ -1715,8 +1716,15 @@
 	bool psr2_sel_fetch_cff_enabled;
 	bool req_psr2_sdp_prior_scanline;
 	u8 sink_sync_latency;
-	u8 io_wake_lines;
-	u8 fast_wake_lines;
+
+	struct {
+		u8 io_wake_lines;
+		u8 fast_wake_lines;
+
+		/* LNL and beyond */
+		u8 check_entry_lines;
+	} alpm_parameters;
+
 	ktime_t last_entry_attempt;
 	ktime_t last_exit;
 	bool sink_not_reliable;
@@ -1840,6 +1848,10 @@
 
 	/* When we last wrote the OUI for eDP */
 	unsigned long last_oui_write;
+
+	struct {
+		unsigned long mask;
+	} quirks;
 };
 
 enum lspcon_vendor {
@@ -2153,4 +2165,41 @@
 	return bpp << 4;
 }
 
+/*
+ * Conversion functions/macros from various pointer types to struct
+ * intel_display pointer.
+ */
+#define __drm_device_to_intel_display(p) \
+	(&to_i915(p)->display)
+#define __intel_connector_to_intel_display(p)		\
+	__drm_device_to_intel_display((p)->base.dev)
+#define __intel_crtc_to_intel_display(p)		\
+	__drm_device_to_intel_display((p)->base.dev)
+#define __intel_crtc_state_to_intel_display(p)			\
+	__drm_device_to_intel_display((p)->uapi.crtc->dev)
+#define __intel_digital_port_to_intel_display(p)		\
+	__drm_device_to_intel_display((p)->base.base.dev)
+#define __intel_dp_to_intel_display(p)	\
+	__drm_device_to_intel_display(dp_to_dig_port(p)->base.base.dev)
+#define __intel_encoder_to_intel_display(p)		\
+	__drm_device_to_intel_display((p)->base.dev)
+#define __intel_hdmi_to_intel_display(p)	\
+	__drm_device_to_intel_display(hdmi_to_dig_port(p)->base.base.dev)
+
+/* Helper for generic association. Map types to conversion functions/macros. */
+#define __assoc(type, p) \
+	struct type: __##type##_to_intel_display((struct type *)(p))
+
+/* Convert various pointer types to struct intel_display pointer. */
+#define to_intel_display(p)				\
+	_Generic(*p,					\
+		 __assoc(drm_device, p),		\
+		 __assoc(intel_connector, p),		\
+		 __assoc(intel_crtc, p),		\
+		 __assoc(intel_crtc_state, p),		\
+		 __assoc(intel_digital_port, p),	\
+		 __assoc(intel_dp, p),			\
+		 __assoc(intel_encoder, p),		\
+		 __assoc(intel_hdmi, p))
+
 #endif /*  __INTEL_DISPLAY_TYPES_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_dp.c
@@ -75,6 +75,7 @@
 #include "intel_pch_display.h"
 #include "intel_pps.h"
 #include "intel_psr.h"
+#include "intel_quirks.h"
 #include "intel_tc.h"
 #include "intel_vdsc.h"
 #include "intel_vrr.h"
@@ -434,6 +435,10 @@
 	struct intel_encoder *encoder = &intel_dig_port->base;
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 
+	/* eDP MSO is not compatible with joiner */
+	if (intel_dp->mso_link_count)
+		return false;
+
 	return DISPLAY_VER(dev_priv) >= 12 ||
 		(DISPLAY_VER(dev_priv) == 11 &&
 		 encoder->port != PORT_A);
@@ -1422,7 +1427,8 @@
 	if (DISPLAY_VER(dev_priv) >= 12)
 		return true;
 
-	if (DISPLAY_VER(dev_priv) == 11 && encoder->port != PORT_A)
+	if (DISPLAY_VER(dev_priv) == 11 && encoder->port != PORT_A &&
+	    !intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST))
 		return true;
 
 	return false;
@@ -1914,10 +1920,10 @@
 	/* Compressed BPP should be less than the Input DSC bpp */
 	dsc_max_bpp = min(dsc_max_bpp, pipe_bpp - 1);
 
-	for (i = 0; i < ARRAY_SIZE(valid_dsc_bpp); i++) {
+	for (i = ARRAY_SIZE(valid_dsc_bpp) - 1; i >= 0; i--) {
 		if (valid_dsc_bpp[i] < dsc_min_bpp ||
 		    valid_dsc_bpp[i] > dsc_max_bpp)
-			break;
+			continue;
 
 		ret = dsc_compute_link_config(intel_dp,
 					      pipe_config,
@@ -2754,7 +2760,11 @@
 		intel_panel_downclock_mode(connector, &pipe_config->hw.adjusted_mode);
 	int pixel_clock;
 
-	if (has_seamless_m_n(connector))
+	/*
+	 * FIXME all joined pipes share the same transcoder.
+	 * Need to account for that when updating M/N live.
+	 */
+	if (has_seamless_m_n(connector) && !pipe_config->bigjoiner_pipes)
 		pipe_config->update_m_n = true;
 
 	if (!can_enable_drrs(connector, pipe_config, downclock_mode)) {
@@ -3896,6 +3906,7 @@
 
 	drm_dp_read_desc(&intel_dp->aux, &intel_dp->desc,
 			 drm_dp_is_branch(intel_dp->dpcd));
+	intel_init_dpcd_quirks(intel_dp, &intel_dp->desc.ident);
 
 	/*
 	 * Read the eDP display control registers.
@@ -4001,6 +4012,8 @@
 		drm_dp_read_desc(&intel_dp->aux, &intel_dp->desc,
 				 drm_dp_is_branch(intel_dp->dpcd));
 
+		intel_init_dpcd_quirks(intel_dp, &intel_dp->desc.ident);
+
 		intel_dp_set_sink_rates(intel_dp);
 		intel_dp_set_max_sink_lane_count(intel_dp);
 		intel_dp_set_common_rates(intel_dp);
@@ -4113,73 +4126,6 @@
 	return false;
 }
 
-static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc,
-				     struct dp_sdp *sdp, size_t size)
-{
-	size_t length = sizeof(struct dp_sdp);
-
-	if (size < length)
-		return -ENOSPC;
-
-	memset(sdp, 0, size);
-
-	/*
-	 * Prepare VSC Header for SU as per DP 1.4a spec, Table 2-119
-	 * VSC SDP Header Bytes
-	 */
-	sdp->sdp_header.HB0 = 0; /* Secondary-Data Packet ID = 0 */
-	sdp->sdp_header.HB1 = vsc->sdp_type; /* Secondary-data Packet Type */
-	sdp->sdp_header.HB2 = vsc->revision; /* Revision Number */
-	sdp->sdp_header.HB3 = vsc->length; /* Number of Valid Data Bytes */
-
-	if (vsc->revision == 0x6) {
-		sdp->db[0] = 1;
-		sdp->db[3] = 1;
-	}
-
-	/*
-	 * Revision 0x5 and revision 0x7 supports Pixel Encoding/Colorimetry
-	 * Format as per DP 1.4a spec and DP 2.0 respectively.
-	 */
-	if (!(vsc->revision == 0x5 || vsc->revision == 0x7))
-		goto out;
-
-	/* VSC SDP Payload for DB16 through DB18 */
-	/* Pixel Encoding and Colorimetry Formats  */
-	sdp->db[16] = (vsc->pixelformat & 0xf) << 4; /* DB16[7:4] */
-	sdp->db[16] |= vsc->colorimetry & 0xf; /* DB16[3:0] */
-
-	switch (vsc->bpc) {
-	case 6:
-		/* 6bpc: 0x0 */
-		break;
-	case 8:
-		sdp->db[17] = 0x1; /* DB17[3:0] */
-		break;
-	case 10:
-		sdp->db[17] = 0x2;
-		break;
-	case 12:
-		sdp->db[17] = 0x3;
-		break;
-	case 16:
-		sdp->db[17] = 0x4;
-		break;
-	default:
-		MISSING_CASE(vsc->bpc);
-		break;
-	}
-	/* Dynamic Range and Component Bit Depth */
-	if (vsc->dynamic_range == DP_DYNAMIC_RANGE_CTA)
-		sdp->db[17] |= 0x80;  /* DB17[7] */
-
-	/* Content Type */
-	sdp->db[18] = vsc->content_type & 0x7;
-
-out:
-	return length;
-}
-
 static ssize_t
 intel_dp_hdr_metadata_infoframe_sdp_pack(struct drm_i915_private *i915,
 					 const struct hdmi_drm_infoframe *drm_infoframe,
@@ -4272,8 +4218,7 @@
 
 	switch (type) {
 	case DP_SDP_VSC:
-		len = intel_dp_vsc_sdp_pack(&crtc_state->infoframes.vsc, &sdp,
-					    sizeof(sdp));
+		len = drm_dp_vsc_sdp_pack(&crtc_state->infoframes.vsc, &sdp);
 		break;
 	case HDMI_PACKET_TYPE_GAMUT_METADATA:
 		len = intel_dp_hdr_metadata_infoframe_sdp_pack(dev_priv,
@@ -4300,7 +4245,7 @@
 	struct dp_sdp sdp = {};
 	ssize_t len;
 
-	len = intel_dp_vsc_sdp_pack(vsc, &sdp, sizeof(sdp));
+	len = drm_dp_vsc_sdp_pack(vsc, &sdp);
 
 	if (drm_WARN_ON(&dev_priv->drm, len < 0))
 		return;
@@ -4325,8 +4270,11 @@
 	if (!enable && HAS_DSC(dev_priv))
 		val &= ~VDIP_ENABLE_PPS;
 
-	/* When PSR is enabled, this routine doesn't disable VSC DIP */
-	if (!crtc_state->has_psr)
+	/*
+	 * This routine disables VSC DIP if the function is called
+	 * to disable SDP or if it does not have PSR
+	 */
+	if (!enable || !crtc_state->has_psr)
 		val &= ~VIDEO_DIP_ENABLE_VSC_HSW;
 
 	intel_de_write(dev_priv, reg, val);
@@ -5145,6 +5093,8 @@
 		    !intel_dp_mst_is_master_trans(crtc_state))
 			continue;
 
+		intel_dp->link_trained = false;
+
 		intel_dp_check_frl_training(intel_dp);
 		intel_dp_pcon_dsc_configure(intel_dp, crtc_state);
 		intel_dp_start_link_train(intel_dp, crtc_state);
@@ -5498,6 +5448,17 @@
 	return drm_edid_read_ddc(&connector->base, &intel_dp->aux.ddc);
 }
 
+const struct edid *
+intel_dp_fetch_edid(struct intel_dp *intel_dp)
+{
+	const struct drm_edid * d_edid;
+	d_edid = intel_dp_get_edid(intel_dp);
+	if (d_edid)
+		return drm_edid_raw(d_edid);
+
+	return NULL;
+}
+
 static void
 intel_dp_update_dfp(struct intel_dp *intel_dp,
 		    const struct drm_edid *drm_edid)
@@ -5681,6 +5642,18 @@
 	else
 		status = connector_status_disconnected;
 
+	if (status != connector_status_disconnected &&
+	    !intel_dp_mst_verify_dpcd_state(intel_dp))
+		/*
+		 * This requires retrying detection for instance to re-enable
+		 * the MST mode that got reset via a long HPD pulse. The retry
+		 * will happen either via the hotplug handler's retry logic,
+		 * ensured by setting the connector here to SST/disconnected,
+		 * or via a userspace connector probing in response to the
+		 * hotplug uevent sent when removing the MST connectors.
+		 */
+		status = connector_status_disconnected;
+
 	if (status == connector_status_disconnected) {
 		memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance));
 		memset(intel_connector->dp.dsc_dpcd, 0, sizeof(intel_connector->dp.dsc_dpcd));
@@ -6523,6 +6496,7 @@
 		intel_connector->get_hw_state = intel_ddi_connector_get_hw_state;
 	else
 		intel_connector->get_hw_state = intel_connector_get_hw_state;
+	intel_connector->sync_state = intel_dp_connector_sync_state;
 
 	if (!intel_edp_init_connector(intel_dp, intel_connector)) {
 		intel_dp_aux_fini(intel_dp);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dp.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_dp.h
@@ -187,4 +187,6 @@
 
 void intel_dp_get_dsc_sink_cap(u8 dpcd_rev, struct intel_connector *connector);
 
+const struct edid *intel_dp_fetch_edid(struct intel_dp *intel_dp);
+
 #endif /* __INTEL_DP_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dp_aux.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_dp_aux.c
@@ -12,6 +12,7 @@
 #include "intel_dp_aux.h"
 #include "intel_dp_aux_regs.h"
 #include "intel_pps.h"
+#include "intel_quirks.h"
 #include "intel_tc.h"
 
 #define AUX_CH_NAME_BUFSIZE	6
@@ -83,7 +84,7 @@
 	 * The clock divider is based off the hrawclk, and would like to run at
 	 * 2MHz.  So, take the hrawclk value and divide by 2000 and use that
 	 */
-	return DIV_ROUND_CLOSEST(RUNTIME_INFO(i915)->rawclk_freq, 2000);
+	return DIV_ROUND_CLOSEST(DISPLAY_RUNTIME_INFO(i915)->rawclk_freq, 2000);
 }
 
 static u32 ilk_get_aux_clock_divider(struct intel_dp *intel_dp, int index)
@@ -103,7 +104,7 @@
 	if (dig_port->aux_ch == AUX_CH_A)
 		freq = i915->display.cdclk.hw.cdclk;
 	else
-		freq = RUNTIME_INFO(i915)->rawclk_freq;
+		freq = DISPLAY_RUNTIME_INFO(i915)->rawclk_freq;
 	return DIV_ROUND_CLOSEST(freq, 2000);
 }
 
@@ -142,11 +143,22 @@
 	return precharge + preamble;
 }
 
-static int intel_dp_aux_fw_sync_len(void)
+int intel_dp_aux_fw_sync_len(struct intel_dp *intel_dp)
 {
 	int precharge = 10; /* 10-16 */
 	int preamble = 8;
 
+	/*
+	 * We faced some glitches on Dell Precision 5490 MTL laptop with panel:
+	 * "Manufacturer: AUO, Model: 63898" when using HW default 18. Using 20
+	 * is fixing these problems with the panel. It is still within range
+	 * mentioned in eDP specification. Increasing Fast Wake sync length is
+	 * causing problems with other panels: increase length as a quirk for
+	 * this specific laptop.
+	 */
+	if (intel_has_dpcd_quirk(intel_dp, QUIRK_FW_SYNC_LEN))
+		precharge += 2;
+
 	return precharge + preamble;
 }
 
@@ -205,7 +217,7 @@
 		DP_AUX_CH_CTL_TIME_OUT_MAX |
 		DP_AUX_CH_CTL_RECEIVE_ERROR |
 		DP_AUX_CH_CTL_MESSAGE_SIZE(send_bytes) |
-		DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(intel_dp_aux_fw_sync_len()) |
+		DP_AUX_CH_CTL_FW_SYNC_PULSE_SKL(intel_dp_aux_fw_sync_len(intel_dp)) |
 		DP_AUX_CH_CTL_SYNC_PULSE_SKL(intel_dp_aux_sync_len());
 
 	if (intel_tc_port_in_tbt_alt_mode(dig_port))
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dp_aux.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_dp_aux.h
@@ -20,5 +20,6 @@
 
 void intel_dp_aux_irq_handler(struct drm_i915_private *i915);
 u32 intel_dp_aux_pack(const u8 *src, int src_bytes);
+int intel_dp_aux_fw_sync_len(struct intel_dp *intel_dp);
 
 #endif /* __INTEL_DP_AUX_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
@@ -637,12 +637,18 @@
 int intel_dp_hdcp2_capable(struct intel_connector *connector,
 			   bool *capable)
 {
-	struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
-	struct drm_dp_aux *aux = &dig_port->dp.aux;
+	struct intel_digital_port *dig_port;
+	struct drm_dp_aux *aux;
 	u8 rx_caps[3];
 	int ret;
 
 	*capable = false;
+	if (!intel_attached_encoder(connector))
+		return -EINVAL;
+
+	dig_port = intel_attached_dig_port(connector);
+	aux = &dig_port->dp.aux;
+
 	ret = drm_dp_dpcd_read(aux,
 			       DP_HDCP_2_2_REG_RX_CAPS_OFFSET,
 			       rx_caps, HDCP_2_2_RXCAPS_LEN);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -114,10 +114,24 @@
 	return drm_dp_dpcd_write(&intel_dp->aux, DP_PHY_REPEATER_MODE, &val, 1) == 1;
 }
 
-static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+static bool intel_dp_lttpr_transparent_mode_enabled(struct intel_dp *intel_dp)
+{
+	return intel_dp->lttpr_common_caps[DP_PHY_REPEATER_MODE -
+					   DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV] ==
+		DP_PHY_REPEATER_MODE_TRANSPARENT;
+}
+
+/*
+ * Read the LTTPR common capabilities and switch the LTTPR PHYs to
+ * non-transparent mode if this is supported. Preserve the
+ * transparent/non-transparent mode on an active link.
+ *
+ * Return the number of detected LTTPRs in non-transparent mode or 0 if the
+ * LTTPRs are in transparent mode or the detection failed.
+ */
+static int intel_dp_init_lttpr_phys(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
 {
 	int lttpr_count;
-	int i;
 
 	if (!intel_dp_read_lttpr_common_caps(intel_dp, dpcd))
 		return 0;
@@ -132,6 +146,19 @@
 		return 0;
 
 	/*
+	 * Don't change the mode on an active link, to prevent a loss of link
+	 * synchronization. See DP Standard v2.0 3.6.7. about the LTTPR
+	 * resetting its internal state when the mode is changed from
+	 * non-transparent to transparent.
+	 */
+	if (intel_dp->link_trained) {
+		if (lttpr_count < 0 || intel_dp_lttpr_transparent_mode_enabled(intel_dp))
+			goto out_reset_lttpr_count;
+
+		return lttpr_count;
+	}
+
+	/*
 	 * See DP Standard v2.0 3.6.6.1. about the explicit disabling of
 	 * non-transparent mode and the disable->enable non-transparent mode
 	 * sequence.
@@ -151,11 +178,25 @@
 		       "Switching to LTTPR non-transparent LT mode failed, fall-back to transparent mode\n");
 
 		intel_dp_set_lttpr_transparent_mode(intel_dp, true);
-		intel_dp_reset_lttpr_count(intel_dp);
 
-		return 0;
+		goto out_reset_lttpr_count;
 	}
 
+	return lttpr_count;
+
+out_reset_lttpr_count:
+	intel_dp_reset_lttpr_count(intel_dp);
+
+	return 0;
+}
+
+static int intel_dp_init_lttpr(struct intel_dp *intel_dp, const u8 dpcd[DP_RECEIVER_CAP_SIZE])
+{
+	int lttpr_count;
+	int i;
+
+	lttpr_count = intel_dp_init_lttpr_phys(intel_dp, dpcd);
+
 	for (i = 0; i < lttpr_count; i++)
 		intel_dp_read_lttpr_phy_caps(intel_dp, dpcd, DP_PHY_LTTPR(i));
 
@@ -1353,10 +1394,10 @@
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	bool passed;
-
 	/*
-	 * TODO: Reiniting LTTPRs here won't be needed once proper connector
-	 * HW state readout is added.
+	 * Reinit the LTTPRs here to ensure that they are switched to
+	 * non-transparent mode. During an earlier LTTPR detection this
+	 * could've been prevented by an active link.
 	 */
 	int lttpr_count = intel_dp_init_lttpr_and_dprx_caps(intel_dp);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -72,26 +72,19 @@
 
 static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state,
 				    const struct intel_connector *connector,
-				    bool ssc, bool dsc, int bpp_x16)
+				    bool ssc, int dsc_slice_count, int bpp_x16)
 {
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->hw.adjusted_mode;
 	unsigned long flags = DRM_DP_BW_OVERHEAD_MST;
-	int dsc_slice_count = 0;
 	int overhead;
 
 	flags |= intel_dp_is_uhbr(crtc_state) ? DRM_DP_BW_OVERHEAD_UHBR : 0;
 	flags |= ssc ? DRM_DP_BW_OVERHEAD_SSC_REF_CLK : 0;
 	flags |= crtc_state->fec_enable ? DRM_DP_BW_OVERHEAD_FEC : 0;
 
-	if (dsc) {
+	if (dsc_slice_count)
 		flags |= DRM_DP_BW_OVERHEAD_DSC;
-		/* TODO: add support for bigjoiner */
-		dsc_slice_count = intel_dp_dsc_get_slice_count(connector,
-							       adjusted_mode->clock,
-							       adjusted_mode->hdisplay,
-							       false);
-	}
 
 	overhead = drm_dp_bw_overhead(crtc_state->lane_count,
 				      adjusted_mode->hdisplay,
@@ -137,6 +130,19 @@
 	return DIV_ROUND_UP(effective_data_rate * 64, 54 * 1000);
 }
 
+static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connector,
+					    const struct intel_crtc_state *crtc_state)
+{
+	const struct drm_display_mode *adjusted_mode =
+		&crtc_state->hw.adjusted_mode;
+
+	/* TODO: add support for bigjoiner */
+	return intel_dp_dsc_get_slice_count(connector,
+					    adjusted_mode->clock,
+					    adjusted_mode->hdisplay,
+					    false);
+}
+
 static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder,
 						struct intel_crtc_state *crtc_state,
 						int max_bpp,
@@ -156,6 +162,7 @@
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->hw.adjusted_mode;
 	int bpp, slots = -EINVAL;
+	int dsc_slice_count = 0;
 	int ret = 0;
 
 	mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst_mgr);
@@ -179,6 +186,15 @@
 	drm_dbg_kms(&i915->drm, "Looking for slots in range min bpp %d max bpp %d\n",
 		    min_bpp, max_bpp);
 
+	if (dsc) {
+		dsc_slice_count = intel_dp_mst_dsc_get_slice_count(connector, crtc_state);
+		if (!dsc_slice_count) {
+			drm_dbg_kms(&i915->drm, "Can't get valid DSC slice count\n");
+
+			return -ENOSPC;
+		}
+	}
+
 	for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) {
 		int local_bw_overhead;
 		int remote_bw_overhead;
@@ -195,9 +211,9 @@
 					  intel_dp_output_bpp(crtc_state->output_format, bpp));
 
 		local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector,
-							     false, dsc, link_bpp_x16);
+							     false, dsc_slice_count, link_bpp_x16);
 		remote_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector,
-							      true, dsc, link_bpp_x16);
+							      true, dsc_slice_count, link_bpp_x16);
 
 		intel_dp_mst_compute_m_n(crtc_state, connector,
 					 local_bw_overhead,
@@ -413,6 +429,9 @@
 	if (mode_hblank_period_ns(adjusted_mode) > 300)
 		return false;
 
+	if (!intel_dp_mst_dsc_get_slice_count(connector, crtc_state))
+		return false;
+
 	return true;
 }
 
@@ -1148,7 +1167,7 @@
 	if (first_mst_stream)
 		intel_ddi_wait_for_fec_status(encoder, pipe_config, true);
 
-	drm_dp_add_payload_part2(&intel_dp->mst_mgr, &state->base,
+	drm_dp_add_payload_part2(&intel_dp->mst_mgr,
 				 drm_atomic_get_mst_payload_state(mst_state, connector->port));
 
 	if (DISPLAY_VER(dev_priv) >= 12)
@@ -1338,7 +1357,7 @@
 		return 0;
 	}
 
-	if (DISPLAY_VER(dev_priv) >= 10 &&
+	if (HAS_DSC_MST(dev_priv) &&
 	    drm_dp_sink_supports_dsc(intel_connector->dp.dsc_dpcd)) {
 		/*
 		 * TBD pass the connector BPC,
@@ -1872,3 +1891,43 @@
 
 	return false;
 }
+
+/*
+ * intel_dp_mst_verify_dpcd_state - verify the MST SW enabled state wrt. the DPCD
+ * @intel_dp: DP port object
+ *
+ * Verify if @intel_dp's MST enabled SW state matches the corresponding DPCD
+ * state. A long HPD pulse - not long enough to be detected as a disconnected
+ * state - could've reset the DPCD state, which requires tearing
+ * down/recreating the MST topology.
+ *
+ * Returns %true if the SW MST enabled and DPCD states match, %false
+ * otherwise.
+ */
+bool intel_dp_mst_verify_dpcd_state(struct intel_dp *intel_dp)
+{
+	struct intel_display *display = to_intel_display(intel_dp);
+	struct intel_connector *connector = intel_dp->attached_connector;
+	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+	struct intel_encoder *encoder = &dig_port->base;
+	int ret;
+	u8 val;
+
+	if (!intel_dp->is_mst)
+		return true;
+
+	ret = drm_dp_dpcd_readb(intel_dp->mst_mgr.aux, DP_MSTM_CTRL, &val);
+
+	/* Adjust the expected register value for SST + SideBand. */
+	if (ret < 0 || val != (DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC)) {
+		drm_dbg_kms(display->drm,
+			    "[CONNECTOR:%d:%s][ENCODER:%d:%s] MST mode got reset, removing topology (ret=%d, ctrl=0x%02x)\n",
+			    connector->base.base.id, connector->base.name,
+			    encoder->base.base.id, encoder->base.name,
+			    ret, val);
+
+		return false;
+	}
+
+	return true;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dp_mst.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_dp_mst.h
@@ -27,5 +27,6 @@
 				   struct intel_link_bw_limits *limits);
 bool intel_dp_mst_crtc_needs_modeset(struct intel_atomic_state *state,
 				     struct intel_crtc *crtc);
+bool intel_dp_mst_verify_dpcd_state(struct intel_dp *intel_dp);
 
 #endif /* __INTEL_DP_MST_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_dpll_mgr.c
@@ -1602,7 +1602,7 @@
 }
 
 static int
-skl_ddi_calculate_wrpll(int clock /* in Hz */,
+skl_ddi_calculate_wrpll(int clock,
 			int ref_clock,
 			struct skl_wrpll_params *wrpll_params)
 {
@@ -1627,7 +1627,7 @@
 	};
 	unsigned int dco, d, i;
 	unsigned int p0, p1, p2;
-	u64 afe_clock = clock * 5; /* AFE Clock is 5x Pixel clock */
+	u64 afe_clock = (u64)clock * 1000 * 5; /* AFE Clock is 5x Pixel clock, in Hz */
 
 	for (d = 0; d < ARRAY_SIZE(dividers); d++) {
 		for (dco = 0; dco < ARRAY_SIZE(dco_central_freq); dco++) {
@@ -1759,7 +1759,7 @@
 
 	ctrl1 |= DPLL_CTRL1_HDMI_MODE(0);
 
-	ret = skl_ddi_calculate_wrpll(crtc_state->port_clock * 1000,
+	ret = skl_ddi_calculate_wrpll(crtc_state->port_clock,
 				      i915->display.dpll.ref_clks.nssc, &wrpll_params);
 	if (ret)
 		return ret;
@@ -2509,7 +2509,7 @@
 static bool
 ehl_combo_pll_div_frac_wa_needed(struct drm_i915_private *i915)
 {
-	return (((IS_ELKHARTLAKE(i915) || IS_JASPERLAKE(i915)) &&
+	return ((IS_ELKHARTLAKE(i915) &&
 		 IS_DISPLAY_STEP(i915, STEP_B0, STEP_FOREVER)) ||
 		 IS_TIGERLAKE(i915) || IS_ALDERLAKE_S(i915) || IS_ALDERLAKE_P(i915)) &&
 		 i915->display.dpll.ref_clks.nssc == 38400;
@@ -3308,6 +3308,8 @@
 	struct drm_i915_private *i915 = to_i915(state->base.dev);
 	struct intel_crtc_state *crtc_state =
 		intel_atomic_get_new_crtc_state(state, crtc);
+	const struct intel_crtc_state *old_crtc_state =
+		intel_atomic_get_old_crtc_state(state, crtc);
 	struct icl_port_dpll *port_dpll =
 		&crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
 	struct skl_wrpll_params pll_params = {};
@@ -3326,7 +3328,11 @@
 		return ret;
 
 	/* this is mainly for the fastset check */
-	icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_MG_PHY);
+	if (old_crtc_state->shared_dpll &&
+	    old_crtc_state->shared_dpll->info->id == DPLL_ID_ICL_TBTPLL)
+		icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_DEFAULT);
+	else
+		icl_set_active_port_dpll(crtc_state, ICL_PORT_DPLL_MG_PHY);
 
 	crtc_state->port_clock = icl_ddi_mg_pll_get_freq(i915, NULL,
 							 &port_dpll->hw_state);
@@ -4023,7 +4029,8 @@
 static const struct dpll_info icl_plls[] = {
 	{ .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
 	{ .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
-	{ .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, },
+	{ .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL,
+	  .flags = INTEL_DPLL_IS_ALT_PORT_DPLL, },
 	{ .name = "MG PLL 1", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, },
 	{ .name = "MG PLL 2", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, },
 	{ .name = "MG PLL 3", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, },
@@ -4068,7 +4075,8 @@
 static const struct dpll_info tgl_plls[] = {
 	{ .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
 	{ .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
-	{ .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, },
+	{ .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL,
+	  .flags = INTEL_DPLL_IS_ALT_PORT_DPLL, },
 	{ .name = "TC PLL 1", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, },
 	{ .name = "TC PLL 2", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, },
 	{ .name = "TC PLL 3", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, },
@@ -4141,7 +4149,8 @@
 static const struct dpll_info adlp_plls[] = {
 	{ .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
 	{ .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
-	{ .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, },
+	{ .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL,
+	  .flags = INTEL_DPLL_IS_ALT_PORT_DPLL, },
 	{ .name = "TC PLL 1", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, },
 	{ .name = "TC PLL 2", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, },
 	{ .name = "TC PLL 3", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, },
@@ -4465,31 +4474,29 @@
 			 struct intel_crtc *crtc,
 			 const struct intel_crtc_state *new_crtc_state)
 {
-	struct intel_dpll_hw_state dpll_hw_state;
+	struct intel_dpll_hw_state dpll_hw_state = {};
 	u8 pipe_mask;
 	bool active;
 
-	memset(&dpll_hw_state, 0, sizeof(dpll_hw_state));
-
-	drm_dbg_kms(&i915->drm, "%s\n", pll->info->name);
-
 	active = intel_dpll_get_hw_state(i915, pll, &dpll_hw_state);
 
 	if (!(pll->info->flags & INTEL_DPLL_ALWAYS_ON)) {
 		I915_STATE_WARN(i915, !pll->on && pll->active_mask,
-				"pll in active use but not on in sw tracking\n");
+				"%s: pll in active use but not on in sw tracking\n",
+				pll->info->name);
 		I915_STATE_WARN(i915, pll->on && !pll->active_mask,
-				"pll is on but not used by any active pipe\n");
+				"%s: pll is on but not used by any active pipe\n",
+				pll->info->name);
 		I915_STATE_WARN(i915, pll->on != active,
-				"pll on state mismatch (expected %i, found %i)\n",
-				pll->on, active);
+				"%s: pll on state mismatch (expected %i, found %i)\n",
+				pll->info->name, pll->on, active);
 	}
 
 	if (!crtc) {
 		I915_STATE_WARN(i915,
 				pll->active_mask & ~pll->state.pipe_mask,
-				"more active pll users than references: 0x%x vs 0x%x\n",
-				pll->active_mask, pll->state.pipe_mask);
+				"%s: more active pll users than references: 0x%x vs 0x%x\n",
+				pll->info->name, pll->active_mask, pll->state.pipe_mask);
 
 		return;
 	}
@@ -4498,21 +4505,30 @@
 
 	if (new_crtc_state->hw.active)
 		I915_STATE_WARN(i915, !(pll->active_mask & pipe_mask),
-				"pll active mismatch (expected pipe %c in active mask 0x%x)\n",
-				pipe_name(crtc->pipe), pll->active_mask);
+				"%s: pll active mismatch (expected pipe %c in active mask 0x%x)\n",
+				pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
 	else
 		I915_STATE_WARN(i915, pll->active_mask & pipe_mask,
-				"pll active mismatch (didn't expect pipe %c in active mask 0x%x)\n",
-				pipe_name(crtc->pipe), pll->active_mask);
+				"%s: pll active mismatch (didn't expect pipe %c in active mask 0x%x)\n",
+				pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
 
 	I915_STATE_WARN(i915, !(pll->state.pipe_mask & pipe_mask),
-			"pll enabled crtcs mismatch (expected 0x%x in 0x%x)\n",
-			pipe_mask, pll->state.pipe_mask);
+			"%s: pll enabled crtcs mismatch (expected 0x%x in 0x%x)\n",
+			pll->info->name, pipe_mask, pll->state.pipe_mask);
 
 	I915_STATE_WARN(i915,
 			pll->on && memcmp(&pll->state.hw_state, &dpll_hw_state,
 					  sizeof(dpll_hw_state)),
-			"pll hw state mismatch\n");
+			"%s: pll hw state mismatch\n",
+			pll->info->name);
+}
+
+static bool has_alt_port_dpll(const struct intel_shared_dpll *old_pll,
+			      const struct intel_shared_dpll *new_pll)
+{
+	return old_pll && new_pll && old_pll != new_pll &&
+		(old_pll->info->flags & INTEL_DPLL_IS_ALT_PORT_DPLL ||
+		 new_pll->info->flags & INTEL_DPLL_IS_ALT_PORT_DPLL);
 }
 
 void intel_shared_dpll_state_verify(struct intel_atomic_state *state,
@@ -4534,11 +4550,15 @@
 		struct intel_shared_dpll *pll = old_crtc_state->shared_dpll;
 
 		I915_STATE_WARN(i915, pll->active_mask & pipe_mask,
-				"pll active mismatch (didn't expect pipe %c in active mask (0x%x))\n",
-				pipe_name(crtc->pipe), pll->active_mask);
-		I915_STATE_WARN(i915, pll->state.pipe_mask & pipe_mask,
-				"pll enabled crtcs mismatch (found pipe %c in enabled mask (0x%x))\n",
-				pipe_name(crtc->pipe), pll->state.pipe_mask);
+				"%s: pll active mismatch (didn't expect pipe %c in active mask (0x%x))\n",
+				pll->info->name, pipe_name(crtc->pipe), pll->active_mask);
+
+		/* TC ports have both MG/TC and TBT PLL referenced simultaneously */
+		I915_STATE_WARN(i915, !has_alt_port_dpll(old_crtc_state->shared_dpll,
+							 new_crtc_state->shared_dpll) &&
+				pll->state.pipe_mask & pipe_mask,
+				"%s: pll enabled crtcs mismatch (found pipe %c in enabled mask (0x%x))\n",
+				pll->info->name, pipe_name(crtc->pipe), pll->state.pipe_mask);
 	}
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_dpll_mgr.h
@@ -277,12 +277,16 @@
 	enum intel_display_power_domain power_domain;
 
 #define INTEL_DPLL_ALWAYS_ON	(1 << 0)
+#define INTEL_DPLL_IS_ALT_PORT_DPLL	(1 << 1)
 	/**
 	 * @flags:
 	 *
 	 * INTEL_DPLL_ALWAYS_ON
 	 *     Inform the state checker that the DPLL is kept enabled even if
 	 *     not in use by any CRTC.
+	 * INTEL_DPLL_IS_ALT_PORT_DPLL
+	 *     Inform the state checker that the DPLL can be used as a fallback
+	 *     (for TC->TBT fallback).
 	 */
 	u32 flags;
 };
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_dsb.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_dsb.c
@@ -340,6 +340,17 @@
 	return max(0, vblank_start - intel_usecs_to_scanlines(adjusted_mode, latency));
 }
 
+static u32 dsb_chicken(struct intel_crtc *crtc)
+{
+	if (crtc->mode_flags & I915_MODE_FLAG_VRR)
+		return DSB_CTRL_WAIT_SAFE_WINDOW |
+			DSB_CTRL_NO_WAIT_VBLANK |
+			DSB_INST_WAIT_SAFE_WINDOW |
+			DSB_INST_NO_WAIT_VBLANK;
+	else
+		return 0;
+}
+
 static void _intel_dsb_commit(struct intel_dsb *dsb, u32 ctrl,
 			      int dewake_scanline)
 {
@@ -361,6 +372,9 @@
 	intel_de_write_fw(dev_priv, DSB_CTRL(pipe, dsb->id),
 			  ctrl | DSB_ENABLE);
 
+	intel_de_write_fw(dev_priv, DSB_CHICKEN(pipe, dsb->id),
+			  dsb_chicken(crtc));
+
 	intel_de_write_fw(dev_priv, DSB_HEAD(pipe, dsb->id),
 			  intel_dsb_buffer_ggtt_offset(&dsb->dsb_buf));
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_fb.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_fb.c
@@ -1636,7 +1636,7 @@
 		 * arithmetic related to alignment and offset calculation.
 		 */
 		if (is_gen12_ccs_cc_plane(&fb->base, i)) {
-			if (IS_ALIGNED(fb->base.offsets[i], PAGE_SIZE))
+			if (IS_ALIGNED(fb->base.offsets[i], 64))
 				continue;
 			else
 				return -EINVAL;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_fb_pin.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_fb_pin.c
@@ -255,6 +255,16 @@
 			return PTR_ERR(vma);
 
 		plane_state->ggtt_vma = vma;
+
+		/*
+		 * Pre-populate the dma address before we enter the vblank
+		 * evade critical section as i915_gem_object_get_dma_address()
+		 * will trigger might_sleep() even if it won't actually sleep,
+		 * which is the case when the fb has already been pinned.
+		 */
+		if (phys_cursor)
+			plane_state->phys_dma_addr =
+				i915_gem_object_get_dma_address(intel_fb_obj(fb), 0);
 	} else {
 		struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -142,11 +142,16 @@
 /* Is HDCP1.4 capable on Platform and Sink */
 bool intel_hdcp_capable(struct intel_connector *connector)
 {
-	struct intel_digital_port *dig_port = intel_attached_dig_port(connector);
+	struct intel_digital_port *dig_port;
 	const struct intel_hdcp_shim *shim = connector->hdcp.shim;
 	bool capable = false;
 	u8 bksv[5];
 
+	if (!intel_attached_encoder(connector))
+		return capable;
+
+	dig_port = intel_attached_dig_port(connector);
+
 	if (!shim)
 		return capable;
 
@@ -998,7 +1003,8 @@
 	hdcp->value = value;
 	if (update_property) {
 		drm_connector_get(&connector->base);
-		queue_work(i915->unordered_wq, &hdcp->prop_work);
+		if (!queue_work(i915->unordered_wq, &hdcp->prop_work))
+			drm_connector_put(&connector->base);
 	}
 }
 
@@ -2490,7 +2496,8 @@
 		mutex_lock(&hdcp->mutex);
 		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
 		drm_connector_get(&connector->base);
-		queue_work(i915->unordered_wq, &hdcp->prop_work);
+		if (!queue_work(i915->unordered_wq, &hdcp->prop_work))
+			drm_connector_put(&connector->base);
 		mutex_unlock(&hdcp->mutex);
 	}
 
@@ -2507,7 +2514,9 @@
 		 */
 		if (!desired_and_not_enabled && !content_protection_type_changed) {
 			drm_connector_get(&connector->base);
-			queue_work(i915->unordered_wq, &hdcp->prop_work);
+			if (!queue_work(i915->unordered_wq, &hdcp->prop_work))
+				drm_connector_put(&connector->base);
+
 		}
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_hdcp_regs.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_hdcp_regs.h
@@ -249,7 +249,7 @@
 #define HDCP2_STREAM_STATUS(dev_priv, trans, port) \
 					(GRAPHICS_VER(dev_priv) >= 12 ? \
 					 TRANS_HDCP2_STREAM_STATUS(trans) : \
-					 PIPE_HDCP2_STREAM_STATUS(pipe))
+					 PIPE_HDCP2_STREAM_STATUS(port))
 
 #define _PORTA_HDCP2_AUTH_STREAM		0x66F00
 #define _PORTB_HDCP2_AUTH_STREAM		0x66F04
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_lpe_audio.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_lpe_audio.c
@@ -177,6 +177,14 @@
 				handle_simple_irq,
 				"hdmi_lpe_audio_irq_handler");
 
+	static const struct pci_device_id irq_quirk_ids[] = {
+		/* Dell Wyse 3040 */
+		{PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, 0x22b0, 0x1028, 0x07c1)},
+		{}
+	};
+
+	if (pci_dev_present(irq_quirk_ids))
+		return 0;
 	return irq_set_chip_data(irq, dev_priv);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_pps.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_pps.c
@@ -949,6 +949,14 @@
 		intel_de_posting_read(dev_priv, pp_ctrl_reg);
 	}
 
+	/*
+	 * WA: 22019252566
+	 * Disable DPLS gating around power sequence.
+	 */
+	if (IS_DISPLAY_VER(dev_priv, 13, 14))
+		intel_de_rmw(dev_priv, SOUTH_DSPCLK_GATE_D,
+			     0, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
+
 	pp |= PANEL_POWER_ON;
 	if (!IS_IRONLAKE(dev_priv))
 		pp |= PANEL_POWER_RESET;
@@ -959,6 +967,10 @@
 	wait_panel_on(intel_dp);
 	intel_dp->pps.last_power_on = jiffies;
 
+	if (IS_DISPLAY_VER(dev_priv, 13, 14))
+		intel_de_rmw(dev_priv, SOUTH_DSPCLK_GATE_D,
+			     PCH_DPLSUNIT_CLOCK_GATE_DISABLE, 0);
+
 	if (IS_IRONLAKE(dev_priv)) {
 		pp |= PANEL_POWER_RESET; /* restore panel reset bit */
 		intel_de_write(dev_priv, pp_ctrl_reg, pp);
@@ -1469,7 +1481,7 @@
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 	u32 pp_on, pp_off, port_sel = 0;
-	int div = RUNTIME_INFO(dev_priv)->rawclk_freq / 1000;
+	int div = DISPLAY_RUNTIME_INFO(dev_priv)->rawclk_freq / 1000;
 	struct pps_registers regs;
 	enum port port = dp_to_dig_port(intel_dp)->base.port;
 	const struct edp_power_seq *seq = &intel_dp->pps.pps_delays;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_psr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_psr.c
@@ -24,6 +24,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_damage_helper.h>
 #include <drm/drm_debugfs.h>
+#include <drm/drm_edid.h>
 
 #include "i915_drv.h"
 #include "i915_reg.h"
@@ -182,6 +183,25 @@
 		return false;
 }
 
+bool intel_psr_needs_aux_io_power(struct intel_encoder *encoder,
+				  const struct intel_crtc_state *crtc_state)
+{
+	/*
+	 * For PSR/PR modes only eDP requires the AUX IO power to be enabled whenever
+	 * the output is enabled. For non-eDP outputs the main link is always
+	 * on, hence it doesn't require the HW initiated AUX wake-up signaling used
+	 * for eDP.
+	 *
+	 * TODO:
+	 * - Consider leaving AUX IO disabled for eDP / PR as well, in case
+	 *   the ALPM with main-link off mode is not enabled.
+	 * - Leave AUX IO enabled for DP / PR, once support for ALPM with
+	 *   main-link off mode is added for it and this mode gets enabled.
+	 */
+	return intel_crtc_has_type(crtc_state, INTEL_OUTPUT_EDP) &&
+	       intel_encoder_can_psr(encoder);
+}
+
 static bool psr_global_enabled(struct intel_dp *intel_dp)
 {
 	struct intel_connector *connector = intel_dp->attached_connector;
@@ -762,8 +782,8 @@
 
 static int psr2_block_count_lines(struct intel_dp *intel_dp)
 {
-	return intel_dp->psr.io_wake_lines < 9 &&
-		intel_dp->psr.fast_wake_lines < 9 ? 8 : 12;
+	return intel_dp->psr.alpm_parameters.io_wake_lines < 9 &&
+		intel_dp->psr.alpm_parameters.fast_wake_lines < 9 ? 8 : 12;
 }
 
 static int psr2_block_count(struct intel_dp *intel_dp)
@@ -800,6 +820,7 @@
 static void hsw_activate_psr2(struct intel_dp *intel_dp)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	struct intel_psr *psr = &intel_dp->psr;
 	enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
 	u32 val = EDP_PSR2_ENABLE;
 	u32 psr_val = 0;
@@ -841,17 +862,18 @@
 		 */
 		int tmp;
 
-		tmp = map[intel_dp->psr.io_wake_lines - TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES];
+		tmp = map[psr->alpm_parameters.io_wake_lines -
+			  TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES];
 		val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(tmp + TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES);
 
-		tmp = map[intel_dp->psr.fast_wake_lines - TGL_EDP_PSR2_FAST_WAKE_MIN_LINES];
+		tmp = map[psr->alpm_parameters.fast_wake_lines - TGL_EDP_PSR2_FAST_WAKE_MIN_LINES];
 		val |= TGL_EDP_PSR2_FAST_WAKE(tmp + TGL_EDP_PSR2_FAST_WAKE_MIN_LINES);
 	} else if (DISPLAY_VER(dev_priv) >= 12) {
-		val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(intel_dp->psr.io_wake_lines);
-		val |= TGL_EDP_PSR2_FAST_WAKE(intel_dp->psr.fast_wake_lines);
+		val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(psr->alpm_parameters.io_wake_lines);
+		val |= TGL_EDP_PSR2_FAST_WAKE(psr->alpm_parameters.fast_wake_lines);
 	} else if (DISPLAY_VER(dev_priv) >= 9) {
-		val |= EDP_PSR2_IO_BUFFER_WAKE(intel_dp->psr.io_wake_lines);
-		val |= EDP_PSR2_FAST_WAKE(intel_dp->psr.fast_wake_lines);
+		val |= EDP_PSR2_IO_BUFFER_WAKE(psr->alpm_parameters.io_wake_lines);
+		val |= EDP_PSR2_FAST_WAKE(psr->alpm_parameters.fast_wake_lines);
 	}
 
 	if (intel_dp->psr.req_psr2_sdp_prior_scanline)
@@ -1013,11 +1035,57 @@
 	crtc_state->dc3co_exitline = crtc_vdisplay - exit_scanlines;
 }
 
+struct edid_mfgid_prodcode {
+	u8 mfg_id0;
+	u8 mfg_id1;
+	u8 prod_code0;
+	u8 prod_code1;
+};
+
+#define PSR2_DISABLE_QUIRK_ENTRY(id0, id1, code0, code1) \
+	{ .mfg_id0 = (id0), .mfg_id1 = (id1), .prod_code0 = (code0), .prod_code1 = (code1) }
+
+static struct edid_mfgid_prodcode psr2_disable_quirk_tbl[] = {
+	PSR2_DISABLE_QUIRK_ENTRY(0x4d, 0x10, 0x8f, 0x15), /* A sharp QHD panel */
+	PSR2_DISABLE_QUIRK_ENTRY(0x4d, 0x10, 0x93, 0x15), /* A sharp FHD panel */
+	PSR2_DISABLE_QUIRK_ENTRY(0x30, 0xe4, 0x8b, 0x07), /* A LG FHD panel */
+	PSR2_DISABLE_QUIRK_ENTRY(0x30, 0xe4, 0x78, 0x07), /* A LG OLED panel */
+	PSR2_DISABLE_QUIRK_ENTRY(0x30, 0xe4, 0x8c, 0x07), /* A LG QHD panel */
+	PSR2_DISABLE_QUIRK_ENTRY(0x06, 0xaf, 0x9a, 0xf9), /* An AUO panel */
+	PSR2_DISABLE_QUIRK_ENTRY(0x06, 0xaf, 0xa3, 0xc3), /* An AUO panel */
+	{ }
+};
+
+static bool is_edid_in_psr2_disable_quirk_tbl(struct intel_dp *intel_dp)
+{
+	const struct edid *p_edid;
+	int i;
+
+	p_edid = intel_dp_fetch_edid(intel_dp);
+	if (p_edid) {
+		for (i = 0; i < ARRAY_SIZE(psr2_disable_quirk_tbl); i ++) {
+			if (p_edid->mfg_id[0] == psr2_disable_quirk_tbl[i].mfg_id0 &&
+			    p_edid->mfg_id[1] == psr2_disable_quirk_tbl[i].mfg_id1 &&
+			    p_edid->prod_code[0] == psr2_disable_quirk_tbl[i].prod_code0 &&
+			    p_edid->prod_code[1] == psr2_disable_quirk_tbl[i].prod_code1)
+				return true;
+		}
+	}
+
+	return false;
+}
+
 static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
 					      struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
 
+	if (is_edid_in_psr2_disable_quirk_tbl(intel_dp)) {
+		drm_info_once(&dev_priv->drm,
+			      "PSR2 sel fetch disabled by the edid quirk table\n");
+		return false;
+	}
+
 	if (!dev_priv->display.params.enable_psr2_sel_fetch &&
 	    intel_dp->psr.debug != I915_PSR_DEBUG_ENABLE_SEL_FETCH) {
 		drm_dbg_kms(&dev_priv->drm,
@@ -1101,26 +1169,76 @@
 	return true;
 }
 
-static bool _compute_psr2_wake_times(struct intel_dp *intel_dp,
+static bool _lnl_compute_alpm_params(struct intel_dp *intel_dp,
 				     struct intel_crtc_state *crtc_state)
 {
 	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+	int check_entry_lines;
+
+	if (DISPLAY_VER(i915) < 20)
+		return true;
+
+	/* ALPM Entry Check = 2 + CEILING( 5us /tline ) */
+	check_entry_lines = 2 +
+		intel_usecs_to_scanlines(&crtc_state->hw.adjusted_mode, 5);
+
+	if (check_entry_lines > 15)
+		return false;
+
+	if (i915->display.params.psr_safest_params)
+		check_entry_lines = 15;
+
+	intel_dp->psr.alpm_parameters.check_entry_lines = check_entry_lines;
+
+	return true;
+}
+
+/*
+ * IO wake time for DISPLAY_VER < 12 is not directly mentioned in Bspec. There
+ * are 50 us io wake time and 32 us fast wake time. Clearly preharge pulses are
+ * not (improperly) included in 32 us fast wake time. 50 us - 32 us = 18 us.
+ */
+static int skl_io_buffer_wake_time(void)
+{
+	return 18;
+}
+
+static int tgl_io_buffer_wake_time(void)
+{
+	return 10;
+}
+
+static int io_buffer_wake_time(const struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+	if (DISPLAY_VER(i915) >= 12)
+		return tgl_io_buffer_wake_time();
+	else
+		return skl_io_buffer_wake_time();
+}
+
+static bool _compute_alpm_params(struct intel_dp *intel_dp,
+				 struct intel_crtc_state *crtc_state)
+{
+	struct drm_i915_private *i915 = dp_to_i915(intel_dp);
 	int io_wake_lines, io_wake_time, fast_wake_lines, fast_wake_time;
+	int tfw_exit_latency = 20; /* eDP spec */
+	int phy_wake = 4;	   /* eDP spec */
+	int preamble = 8;	   /* eDP spec */
+	int precharge = intel_dp_aux_fw_sync_len(intel_dp) - preamble;
 	u8 max_wake_lines;
 
-	if (DISPLAY_VER(i915) >= 12) {
-		io_wake_time = 42;
-		/*
-		 * According to Bspec it's 42us, but based on testing
-		 * it is not enough -> use 45 us.
-		 */
-		fast_wake_time = 45;
+	io_wake_time = max(precharge, io_buffer_wake_time(crtc_state)) +
+		preamble + phy_wake + tfw_exit_latency;
+	fast_wake_time = precharge + preamble + phy_wake +
+		tfw_exit_latency;
+
+	if (DISPLAY_VER(i915) >= 12)
+		/* TODO: Check how we can use ALPM_CTL fast wake extended field */
 		max_wake_lines = 12;
-	} else {
-		io_wake_time = 50;
-		fast_wake_time = 32;
+	else
 		max_wake_lines = 8;
-	}
 
 	io_wake_lines = intel_usecs_to_scanlines(
 		&crtc_state->hw.adjusted_mode, io_wake_time);
@@ -1131,12 +1249,15 @@
 	    fast_wake_lines > max_wake_lines)
 		return false;
 
+	if (!_lnl_compute_alpm_params(intel_dp, crtc_state))
+		return false;
+
 	if (i915->display.params.psr_safest_params)
 		io_wake_lines = fast_wake_lines = max_wake_lines;
 
 	/* According to Bspec lower limit should be set as 7 lines. */
-	intel_dp->psr.io_wake_lines = max(io_wake_lines, 7);
-	intel_dp->psr.fast_wake_lines = max(fast_wake_lines, 7);
+	intel_dp->psr.alpm_parameters.io_wake_lines = max(io_wake_lines, 7);
+	intel_dp->psr.alpm_parameters.fast_wake_lines = max(fast_wake_lines, 7);
 
 	return true;
 }
@@ -1268,7 +1389,7 @@
 		return false;
 	}
 
-	if (!_compute_psr2_wake_times(intel_dp, crtc_state)) {
+	if (!_compute_alpm_params(intel_dp, crtc_state)) {
 		drm_dbg_kms(&dev_priv->drm,
 			    "PSR2 not enabled, Unable to use long enough wake times\n");
 		return false;
@@ -1368,6 +1489,17 @@
 		return;
 	}
 
+	/*
+	 * FIXME figure out what is wrong with PSR+bigjoiner and
+	 * fix it. Presumably something related to the fact that
+	 * PSR is a transcoder level feature.
+	 */
+	if (crtc_state->bigjoiner_pipes) {
+		drm_dbg_kms(&dev_priv->drm,
+			    "PSR disabled due to bigjoiner\n");
+		return;
+	}
+
 	if (CAN_PANEL_REPLAY(intel_dp))
 		crtc_state->has_panel_replay = true;
 	else
@@ -1504,6 +1636,21 @@
 			     wa_16013835468_bit_get(intel_dp), 0);
 }
 
+static void lnl_alpm_configure(struct intel_dp *intel_dp)
+{
+	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+	enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
+	struct intel_psr *psr = &intel_dp->psr;
+
+	if (DISPLAY_VER(dev_priv) < 20)
+		return;
+
+	intel_de_write(dev_priv, ALPM_CTL(cpu_transcoder),
+		       ALPM_CTL_EXTENDED_FAST_WAKE_ENABLE |
+		       ALPM_CTL_ALPM_ENTRY_CHECK(psr->alpm_parameters.check_entry_lines) |
+		       ALPM_CTL_EXTENDED_FAST_WAKE_TIME(psr->alpm_parameters.fast_wake_lines));
+}
+
 static void intel_psr_enable_source(struct intel_dp *intel_dp,
 				    const struct intel_crtc_state *crtc_state)
 {
@@ -1569,6 +1716,8 @@
 			     intel_dp->psr.psr2_sel_fetch_enabled ?
 			     IGNORE_PSR2_HW_TRACKING : 0);
 
+	lnl_alpm_configure(intel_dp);
+
 	/*
 	 * Wa_16013835468
 	 * Wa_14015648006
@@ -3257,16 +3406,9 @@
 		"reserved",
 		"sink internal error",
 	};
-	static const char * const panel_replay_status[] = {
-		"Sink device frame is locked to the Source device",
-		"Sink device is coasting, using the VTotal target",
-		"Sink device is governing the frame rate (frame rate unlock is granted)",
-		"Sink device in the process of re-locking with the Source device",
-	};
 	const char *str;
 	int ret;
 	u8 status, error_status;
-	u32 idx;
 
 	if (!(CAN_PSR(intel_dp) || CAN_PANEL_REPLAY(intel_dp))) {
 		seq_puts(m, "PSR/Panel-Replay Unsupported\n");
@@ -3280,16 +3422,11 @@
 	if (ret)
 		return ret;
 
-	str = "unknown";
-	if (intel_dp->psr.panel_replay_enabled) {
-		idx = (status & DP_SINK_FRAME_LOCKED_MASK) >> DP_SINK_FRAME_LOCKED_SHIFT;
-		if (idx < ARRAY_SIZE(panel_replay_status))
-			str = panel_replay_status[idx];
-	} else if (intel_dp->psr.enabled) {
-		idx = status & DP_PSR_SINK_STATE_MASK;
-		if (idx < ARRAY_SIZE(sink_status))
-			str = sink_status[idx];
-	}
+	status &= DP_PSR_SINK_STATE_MASK;
+	if (status < ARRAY_SIZE(sink_status))
+		str = sink_status[status];
+	else
+		str = "unknown";
 
 	seq_printf(m, "Sink %s status: 0x%x [%s]\n", psr_mode_str(intel_dp), status, str);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_psr.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_psr.h
@@ -28,6 +28,8 @@
 				    (intel_dp)->psr.source_panel_replay_support)
 
 bool intel_encoder_can_psr(struct intel_encoder *encoder);
+bool intel_psr_needs_aux_io_power(struct intel_encoder *encoder,
+				  const struct intel_crtc_state *crtc_state);
 void intel_psr_init_dpcd(struct intel_dp *intel_dp);
 void intel_psr_pre_plane_update(struct intel_atomic_state *state,
 				struct intel_crtc *crtc);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_psr_regs.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_psr_regs.h
@@ -290,4 +290,61 @@
 						  _SEL_FETCH_PLANE_OFFSET_1_A - \
 						  _SEL_FETCH_PLANE_BASE_1_A)
 
+#define _ALPM_CTL_A	0x60950
+#define ALPM_CTL(tran)	_MMIO_TRANS2(tran, _ALPM_CTL_A)
+#define  ALPM_CTL_ALPM_ENABLE				REG_BIT(31)
+#define  ALPM_CTL_ALPM_AUX_LESS_ENABLE			REG_BIT(30)
+#define  ALPM_CTL_LOBF_ENABLE				REG_BIT(29)
+#define  ALPM_CTL_EXTENDED_FAST_WAKE_ENABLE		REG_BIT(28)
+#define  ALPM_CTL_KEEP_FEC_ENABLE_FOR_AUX_WAKE_SLEEP	REG_BIT(27)
+#define  ALPM_CTL_RESTORE_OCCURED			REG_BIT(26)
+#define  ALPM_CTL_RESTORE_TO_SLEEP			REG_BIT(25)
+#define  ALPM_CTL_RESTORE_TO_DEEP_SLEEP			REG_BIT(24)
+#define  ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_MASK		REG_GENMASK(23, 21)
+#define  ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_50_SYMBOLS	REG_FIELD_PREP(ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_MASK, 0)
+#define  ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_128_SYMBOLS	REG_FIELD_PREP(ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_MASK, 1)
+#define  ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_256_SYMBOLS	REG_FIELD_PREP(ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_MASK, 2)
+#define  ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_512_SYMBOLS	REG_FIELD_PREP(ALPM_CTL_AUX_LESS_SLEEP_HOLD_TIME_MASK, 3)
+#define  ALPM_CTL_AUX_WAKE_SLEEP_HOLD_ENABLE		REG_BIT(20)
+#define  ALPM_CTL_ALPM_ENTRY_CHECK_MASK			REG_GENMASK(19, 16)
+#define  ALPM_CTL_ALPM_ENTRY_CHECK(val)			REG_FIELD_PREP(ALPM_CTL_ALPM_ENTRY_CHECK_MASK, val)
+#define  ALPM_CTL_EXTENDED_FAST_WAKE_TIME_MASK		REG_GENMASK(13, 8)
+#define  ALPM_CTL_EXTENDED_FAST_WAKE_MIN_LINES		5
+#define  ALPM_CTL_EXTENDED_FAST_WAKE_TIME(lines)	REG_FIELD_PREP(ALPM_CTL_EXTENDED_FAST_WAKE_TIME_MASK, (lines) - ALPM_CTL_EXTENDED_FAST_WAKE_MIN_LINES)
+#define  ALPM_CTL_AUX_LESS_WAKE_TIME_MASK		REG_GENMASK(5, 0)
+#define  ALPM_CTL_AUX_LESS_WAKE_TIME(val)		REG_FIELD_PREP(ALPM_CTL_AUX_LESS_WAKE_TIME_MASK, val)
+
+#define _ALPM_CTL2_A	0x60954
+#define ALPM_CTL2(tran)	_MMIO_TRANS2(tran, _ALPM_CTL2_A)
+#define  ALPM_CTL2_SWITCH_TO_ACTIVE_LATENCY_MASK		REG_GENMASK(28, 24)
+#define  ALPM_CTL2_SWITCH_TO_ACTIVE_LATENCY(val)		REG_FIELD_PREP(ALPM_CTL2_SWITCH_TO_ACTIVE_LATENCY_MASK, val)
+#define  ALPM_CTL2_AUX_LESS_WAKE_TIME_EXTENSION_MASK		REG_GENMASK(19, 16)
+#define  ALPM_CTL2_AUX_LESS_WAKE_TIME_EXTENSION(val)		REG_FIELD_PREP(ALPM_CTL2_AUX_LESS_WAKE_TIME_EXTENSION_MASK, val)
+#define  ALPM_CTL2_NUMBER_OF_LTTPR_MASK				REG_GENMASK(15, 12)
+#define  ALPM_CTL2_NUMBER_OF_LTTPR(val)				REG_FIELD_PREP(ALPM_CTL2_NUMBER_OF_LTTPR_MASK, val)
+#define  ALPM_CTL2_LTTPR_AUX_LESS_SLEEP_HOLD_TIME_MASK		REG_GENMASK(10, 8)
+#define  ALPM_CTL2_LTTPR_AUX_LESS_SLEEP_HOLD_TIME(val)		REG_FIELD_PREP(ALPM_CTL2_LTTPR_AUX_LESS_SLEEP_HOLD_TIME_MASK, val)
+#define  ALPM_CTL2_FEC_DECODE_EN_POSITION_AFTER_WAKE_SR		REG_BIT(4)
+#define  ALPM_CTL2_NUMBER_AUX_LESS_ML_PHY_SLEEP_SEQUENCES_MASK	REG_GENMASK(2, 0)
+#define  ALPM_CTL2_NUMBER_AUX_LESS_ML_PHY_SLEEP_SEQUENCES(val)	REG_FIELD_PREP(ALPM_CTL2_NUMBER_AUX_LESS_ML_PHY_SLEEP_SEQUENCES_MASK, val)
+
+#define _PORT_ALPM_CTL_A			0x16fa2c
+#define PORT_ALPM_CTL(tran)			_MMIO_TRANS2(tran, _PORT_ALPM_CTL_A)
+#define  PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE	REG_BIT(31)
+#define  PORT_ALPM_CTL_MAX_PHY_SWING_SETUP_MASK	REG_GENMASK(23, 20)
+#define  PORT_ALPM_CTL_MAX_PHY_SWING_SETUP(val)	REG_FIELD_PREP(PORT_ALPM_CTL_MAX_PHY_SWING_SETUP_MASK, val)
+#define  PORT_ALPM_CTL_MAX_PHY_SWING_HOLD_MASK	REG_GENMASK(19, 16)
+#define  PORT_ALPM_CTL_MAX_PHY_SWING_HOLD(val)	REG_FIELD_PREP(PORT_ALPM_CTL_MAX_PHY_SWING_HOLD_MASK, val)
+#define  PORT_ALPM_CTL_SILENCE_PERIOD_MASK	REG_GENMASK(7, 0)
+#define  PORT_ALPM_CTL_SILENCE_PERIOD(val)	REG_FIELD_PREP(PORT_ALPM_CTL_SILENCE_PERIOD_MASK, val)
+
+#define _PORT_ALPM_LFPS_CTL_A					0x16fa30
+#define PORT_ALPM_LFPS_CTL(tran)				_MMIO_TRANS2(tran, _PORT_ALPM_LFPS_CTL_A)
+#define  PORT_ALPM_LFPS_CTL_LFPS_START_POLARITY			REG_BIT(31)
+#define  PORT_ALPM_LFPS_CTL_LFPS_CYCLE_COUNT_MASK		REG_GENMASK(27, 24)
+#define  ALPM_CTL_EXTENDED_FAST_WAKE_MIN_LINES		5
+#define  ALPM_CTL_EXTENDED_FAST_WAKE_TIME(lines)	REG_FIELD_PREP(ALPM_CTL_EXTENDED_FAST_WAKE_TIME_MASK, (lines) - ALPM_CTL_EXTENDED_FAST_WAKE_MIN_LINES)
+#define  ALPM_CTL_AUX_LESS_WAKE_TIME_MASK		REG_GENMASK(5, 0)
+#define  ALPM_CTL_AUX_LESS_WAKE_TIME(val)		REG_FIELD_PREP(ALPM_CTL_AUX_LESS_WAKE_TIME_MASK, val)
+
 #endif /* __INTEL_PSR_REGS_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_quirks.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_quirks.c
@@ -14,6 +14,11 @@
 	i915->display.quirks.mask |= BIT(quirk);
 }
 
+static void intel_set_dpcd_quirk(struct intel_dp *intel_dp, enum intel_quirk_id quirk)
+{
+	intel_dp->quirks.mask |= BIT(quirk);
+}
+
 /*
  * Some machines (Lenovo U160) do not work with SSC on LVDS for some reason
  */
@@ -65,6 +70,14 @@
 	drm_info(&i915->drm, "Applying no pps backlight power quirk\n");
 }
 
+static void quirk_fw_sync_len(struct intel_dp *intel_dp)
+{
+	struct intel_display *display = to_intel_display(intel_dp);
+
+	intel_set_dpcd_quirk(intel_dp, QUIRK_FW_SYNC_LEN);
+	drm_info(display->drm, "Applying Fast Wake sync pulse count quirk\n");
+}
+
 struct intel_quirk {
 	int device;
 	int subsystem_vendor;
@@ -72,6 +85,21 @@
 	void (*hook)(struct drm_i915_private *i915);
 };
 
+struct intel_dpcd_quirk {
+	int device;
+	int subsystem_vendor;
+	int subsystem_device;
+	u8 sink_oui[3];
+	u8 sink_device_id[6];
+	void (*hook)(struct intel_dp *intel_dp);
+};
+
+#define SINK_OUI(first, second, third) { (first), (second), (third) }
+#define SINK_DEVICE_ID(first, second, third, fourth, fifth, sixth) \
+	{ (first), (second), (third), (fourth), (fifth), (sixth) }
+
+#define SINK_DEVICE_ID_ANY	SINK_DEVICE_ID(0, 0, 0, 0, 0, 0)
+
 /* For systems that don't have a meaningful PCI subdevice/subvendor ID */
 struct intel_dmi_quirk {
 	void (*hook)(struct drm_i915_private *i915);
@@ -203,6 +231,18 @@
 	{ 0x0f31, 0x103c, 0x220f, quirk_invert_brightness },
 };
 
+static struct intel_dpcd_quirk intel_dpcd_quirks[] = {
+	/* Dell Precision 5490 */
+	{
+		.device = 0x7d55,
+		.subsystem_vendor = 0x1028,
+		.subsystem_device = 0x0cc7,
+		.sink_oui = SINK_OUI(0x38, 0xec, 0x11),
+		.hook = quirk_fw_sync_len,
+	},
+
+};
+
 void intel_init_quirks(struct drm_i915_private *i915)
 {
 	struct pci_dev *d = to_pci_dev(i915->drm.dev);
@@ -224,7 +264,35 @@
 	}
 }
 
+void intel_init_dpcd_quirks(struct intel_dp *intel_dp,
+			    const struct drm_dp_dpcd_ident *ident)
+{
+	struct intel_display *display = to_intel_display(intel_dp);
+	struct pci_dev *d = to_pci_dev(display->drm->dev);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(intel_dpcd_quirks); i++) {
+		struct intel_dpcd_quirk *q = &intel_dpcd_quirks[i];
+
+		if (d->device == q->device &&
+		    (d->subsystem_vendor == q->subsystem_vendor ||
+		     q->subsystem_vendor == PCI_ANY_ID) &&
+		    (d->subsystem_device == q->subsystem_device ||
+		     q->subsystem_device == PCI_ANY_ID) &&
+		    !memcmp(q->sink_oui, ident->oui, sizeof(ident->oui)) &&
+		    (!memcmp(q->sink_device_id, ident->device_id,
+			    sizeof(ident->device_id)) ||
+		     !memchr_inv(q->sink_device_id, 0, sizeof(q->sink_device_id))))
+			q->hook(intel_dp);
+	}
+}
+
 bool intel_has_quirk(struct drm_i915_private *i915, enum intel_quirk_id quirk)
 {
 	return i915->display.quirks.mask & BIT(quirk);
 }
+
+bool intel_has_dpcd_quirk(struct intel_dp *intel_dp, enum intel_quirk_id quirk)
+{
+	return intel_dp->quirks.mask & BIT(quirk);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_quirks.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_quirks.h
@@ -9,6 +9,8 @@
 #include <linux/types.h>
 
 struct drm_i915_private;
+struct intel_dp;
+struct drm_dp_dpcd_ident;
 
 enum intel_quirk_id {
 	QUIRK_BACKLIGHT_PRESENT,
@@ -17,9 +19,13 @@
 	QUIRK_INVERT_BRIGHTNESS,
 	QUIRK_LVDS_SSC_DISABLE,
 	QUIRK_NO_PPS_BACKLIGHT_POWER_HOOK,
+	QUIRK_FW_SYNC_LEN,
 };
 
 void intel_init_quirks(struct drm_i915_private *i915);
+void intel_init_dpcd_quirks(struct intel_dp *intel_dp,
+			    const struct drm_dp_dpcd_ident *ident);
 bool intel_has_quirk(struct drm_i915_private *i915, enum intel_quirk_id quirk);
+bool intel_has_dpcd_quirk(struct intel_dp *intel_dp, enum intel_quirk_id quirk);
 
 #endif /* __INTEL_QUIRKS_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_sdvo.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_sdvo.c
@@ -1830,8 +1830,6 @@
 	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 	u32 temp;
 
-	encoder->audio_disable(encoder, old_crtc_state, conn_state);
-
 	intel_sdvo_set_active_outputs(intel_sdvo, 0);
 	if (0)
 		intel_sdvo_set_encoder_power_state(intel_sdvo,
@@ -1923,8 +1921,6 @@
 		intel_sdvo_set_encoder_power_state(intel_sdvo,
 						   DRM_MODE_DPMS_ON);
 	intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo_connector->output_flag);
-
-	encoder->audio_enable(encoder, pipe_config, conn_state);
 }
 
 static enum drm_mode_status
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_tc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_tc.c
@@ -390,6 +390,9 @@
 	bool lane_reversal = dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL;
 	u32 val;
 
+	if (DISPLAY_VER(i915) >= 14)
+		return;
+
 	drm_WARN_ON(&i915->drm,
 		    lane_reversal && tc->mode != TC_PORT_LEGACY);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_vbt_defs.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_vbt_defs.h
@@ -897,11 +897,6 @@
 	u16 reserved;
 } __packed;
 
-#define EXP_BDB_LFP_BL_DATA_SIZE_REV_191 \
-	offsetof(struct bdb_lfp_backlight_data, brightness_level)
-#define EXP_BDB_LFP_BL_DATA_SIZE_REV_234 \
-	offsetof(struct bdb_lfp_backlight_data, brightness_precision_bits)
-
 struct bdb_lfp_backlight_data {
 	u8 entry_size;
 	struct lfp_backlight_data_entry data[16];
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/intel_vrr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/intel_vrr.c
@@ -117,6 +117,13 @@
 	const struct drm_display_info *info = &connector->base.display_info;
 	int vmin, vmax;
 
+	/*
+	 * FIXME all joined pipes share the same transcoder.
+	 * Need to account for that during VRR toggle/push/etc.
+	 */
+	if (crtc_state->bigjoiner_pipes)
+		return;
+
 	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
 		return;
 
@@ -187,10 +194,11 @@
 	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 
 	/*
-	 * TRANS_SET_CONTEXT_LATENCY with VRR enabled
-	 * requires this chicken bit on ADL/DG2.
+	 * This bit seems to have two meanings depending on the platform:
+	 * TGL: generate VRR "safe window" for DSB vblank waits
+	 * ADL/DG2: make TRANS_SET_CONTEXT_LATENCY effective with VRR
 	 */
-	if (DISPLAY_VER(dev_priv) == 13)
+	if (IS_DISPLAY_VER(dev_priv, 12, 13))
 		intel_de_rmw(dev_priv, CHICKEN_TRANS(cpu_transcoder),
 			     0, PIPE_VBLANK_WITH_DELAY);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -103,8 +103,6 @@
 	DRM_FORMAT_Y216,
 	DRM_FORMAT_XYUV8888,
 	DRM_FORMAT_XVYU2101010,
-	DRM_FORMAT_XVYU12_16161616,
-	DRM_FORMAT_XVYU16161616,
 };
 
 static const u32 icl_sdr_uv_plane_formats[] = {
@@ -131,8 +129,6 @@
 	DRM_FORMAT_Y216,
 	DRM_FORMAT_XYUV8888,
 	DRM_FORMAT_XVYU2101010,
-	DRM_FORMAT_XVYU12_16161616,
-	DRM_FORMAT_XVYU16161616,
 };
 
 static const u32 icl_hdr_plane_formats[] = {
@@ -2290,6 +2286,9 @@
 	if (HAS_4TILE(i915))
 		caps |= INTEL_PLANE_CAP_TILING_4;
 
+	if (!IS_ENABLED(I915) && !HAS_FLAT_CCS(i915))
+		return caps;
+
 	if (skl_plane_has_rc_ccs(i915, pipe, plane_id)) {
 		caps |= INTEL_PLANE_CAP_CCS_RC;
 		if (DISPLAY_VER(i915) >= 12)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/skl_watermark.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/skl_watermark.c
@@ -63,7 +63,7 @@
 	return DISPLAY_VER(i915) == 9;
 }
 
-static bool
+bool
 intel_has_sagv(struct drm_i915_private *i915)
 {
 	return HAS_SAGV(i915) &&
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/skl_watermark.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/skl_watermark.h
@@ -25,6 +25,7 @@
 void intel_sagv_post_plane_update(struct intel_atomic_state *state);
 bool intel_can_enable_sagv(struct drm_i915_private *i915,
 			   const struct intel_bw_state *bw_state);
+bool intel_has_sagv(struct drm_i915_private *i915);
 
 u32 skl_ddb_dbuf_slice_mask(struct drm_i915_private *i915,
 			    const struct skl_ddb_entry *entry);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/display/vlv_dsi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/display/vlv_dsi.c
@@ -1868,7 +1868,6 @@
 		/* Lenovo Yoga Tab 3 Pro YT3-X90F */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
 			DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"),
 		},
 		.driver_data = (void *)vlv_dsi_lenovo_yoga_tab3_backlight_fixup,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gem/i915_gem_mman.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gem/i915_gem_mman.c
@@ -290,6 +290,41 @@
 	return i915_error_to_vmf_fault(err);
 }
 
+static void set_address_limits(struct vm_area_struct *area,
+			       struct i915_vma *vma,
+			       unsigned long obj_offset,
+			       unsigned long *start_vaddr,
+			       unsigned long *end_vaddr)
+{
+	unsigned long vm_start, vm_end, vma_size; /* user's memory parameters */
+	long start, end; /* memory boundaries */
+
+	/*
+	 * Let's move into the ">> PAGE_SHIFT"
+	 * domain to be sure not to lose bits
+	 */
+	vm_start = area->vm_start >> PAGE_SHIFT;
+	vm_end = area->vm_end >> PAGE_SHIFT;
+	vma_size = vma->size >> PAGE_SHIFT;
+
+	/*
+	 * Calculate the memory boundaries by considering the offset
+	 * provided by the user during memory mapping and the offset
+	 * provided for the partial mapping.
+	 */
+	start = vm_start;
+	start -= obj_offset;
+	start += vma->gtt_view.partial.offset;
+	end = start + vma_size;
+
+	start = max_t(long, start, vm_start);
+	end = min_t(long, end, vm_end);
+
+	/* Let's move back into the "<< PAGE_SHIFT" domain */
+	*start_vaddr = (unsigned long)start << PAGE_SHIFT;
+	*end_vaddr = (unsigned long)end << PAGE_SHIFT;
+}
+
 static vm_fault_t vm_fault_gtt(struct vm_fault *vmf)
 {
 #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT)
@@ -302,14 +337,18 @@
 	struct i915_ggtt *ggtt = to_gt(i915)->ggtt;
 	bool write = area->vm_flags & VM_WRITE;
 	struct i915_gem_ww_ctx ww;
+	unsigned long obj_offset;
+	unsigned long start, end; /* memory boundaries */
 	intel_wakeref_t wakeref;
 	struct i915_vma *vma;
 	pgoff_t page_offset;
+	unsigned long pfn;
 	int srcu;
 	int ret;
 
-	/* We don't use vmf->pgoff since that has the fake offset */
+	obj_offset = area->vm_pgoff - drm_vma_node_start(&mmo->vma_node);
 	page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT;
+	page_offset += obj_offset;
 
 	trace_i915_gem_object_fault(obj, page_offset, true, write);
 
@@ -402,12 +441,14 @@
 	if (ret)
 		goto err_unpin;
 
+	set_address_limits(area, vma, obj_offset, &start, &end);
+
+	pfn = (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT;
+	pfn += (start - area->vm_start) >> PAGE_SHIFT;
+	pfn += obj_offset - vma->gtt_view.partial.offset;
+
 	/* Finally, remap it using the new GTT offset */
-	ret = remap_io_mapping(area,
-			       area->vm_start + (vma->gtt_view.partial.offset << PAGE_SHIFT),
-			       (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT,
-			       min_t(u64, vma->size, area->vm_end - area->vm_start),
-			       &ggtt->iomap);
+	ret = remap_io_mapping(area, start, pfn, end - start, &ggtt->iomap);
 	if (ret)
 		goto err_fence;
 
@@ -1084,6 +1125,8 @@
 		mmo = mmap_offset_attach(obj, mmap_type, NULL);
 		if (IS_ERR(mmo))
 			return PTR_ERR(mmo);
+
+		vma->vm_pgoff += drm_vma_node_start(&mmo->vma_node);
 	}
 
 	/*
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gem/i915_gem_object.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gem/i915_gem_object.h
@@ -284,7 +284,9 @@
 static inline bool
 i915_gem_object_is_shrinkable(const struct drm_i915_gem_object *obj)
 {
-	return i915_gem_object_type_has(obj, I915_GEM_OBJECT_IS_SHRINKABLE);
+	/* TODO: make DPT shrinkable when it has no bound vmas */
+	return i915_gem_object_type_has(obj, I915_GEM_OBJECT_IS_SHRINKABLE) &&
+		!obj->is_dpt;
 }
 
 static inline bool
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -209,8 +209,6 @@
 	struct address_space *mapping = obj->base.filp->f_mapping;
 	unsigned int max_segment = i915_sg_segment_size(i915->drm.dev);
 	struct sg_table *st;
-	struct sgt_iter sgt_iter;
-	struct page *page;
 	int ret;
 
 	/*
@@ -239,9 +237,7 @@
 		 * for PAGE_SIZE chunks instead may be helpful.
 		 */
 		if (max_segment > PAGE_SIZE) {
-			for_each_sgt_page(page, sgt_iter, st)
-				put_page(page);
-			sg_free_table(st);
+			shmem_sg_free_table(st, mapping, false, false);
 			kfree(st);
 
 			max_segment = PAGE_SIZE;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gem/i915_gem_stolen.c
@@ -944,7 +944,11 @@
 		dsm_size = ALIGN_DOWN(lmem_size - dsm_base, SZ_1M);
 	}
 
-	if (pci_resource_len(pdev, GEN12_LMEM_BAR) < lmem_size) {
+	if (i915_direct_stolen_access(i915)) {
+		drm_dbg(&i915->drm, "Using direct DSM access\n");
+		io_start = intel_uncore_read64(uncore, GEN12_DSMBASE) & GEN12_BDSM_MASK;
+		io_size = dsm_size;
+	} else if (pci_resource_len(pdev, GEN12_LMEM_BAR) < lmem_size) {
 		io_start = 0;
 		io_size = 0;
 	} else {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gem/i915_gem_ttm.c
@@ -1136,7 +1136,7 @@
 		GEM_WARN_ON(!i915_ttm_cpu_maps_iomem(bo->resource));
 	}
 
-	if (wakeref & CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND)
+	if (wakeref && CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND != 0)
 		intel_wakeref_auto(&to_i915(obj->base.dev)->runtime_pm.userfault_wakeref,
 				   msecs_to_jiffies_timeout(CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND));
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
@@ -226,7 +226,7 @@
 static int mtl_dummy_pipe_control(struct i915_request *rq)
 {
 	/* Wa_14016712196 */
-	if (IS_GFX_GT_IP_RANGE(rq->engine->gt, IP_VER(12, 70), IP_VER(12, 71)) ||
+	if (IS_GFX_GT_IP_RANGE(rq->engine->gt, IP_VER(12, 70), IP_VER(12, 74)) ||
 	    IS_DG2(rq->i915)) {
 		u32 *cs;
 
@@ -743,21 +743,25 @@
 }
 
 /* Wa_14014475959:dg2 */
-#define CCS_SEMAPHORE_PPHWSP_OFFSET	0x540
-static u32 ccs_semaphore_offset(struct i915_request *rq)
+/* Wa_16019325821 */
+/* Wa_14019159160 */
+#define HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET	0x540
+static u32 hold_switchout_semaphore_offset(struct i915_request *rq)
 {
 	return i915_ggtt_offset(rq->context->state) +
-		(LRC_PPHWSP_PN * PAGE_SIZE) + CCS_SEMAPHORE_PPHWSP_OFFSET;
+		(LRC_PPHWSP_PN * PAGE_SIZE) + HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET;
 }
 
 /* Wa_14014475959:dg2 */
-static u32 *ccs_emit_wa_busywait(struct i915_request *rq, u32 *cs)
+/* Wa_16019325821 */
+/* Wa_14019159160 */
+static u32 *hold_switchout_emit_wa_busywait(struct i915_request *rq, u32 *cs)
 {
 	int i;
 
 	*cs++ = MI_ATOMIC_INLINE | MI_ATOMIC_GLOBAL_GTT | MI_ATOMIC_CS_STALL |
 		MI_ATOMIC_MOVE;
-	*cs++ = ccs_semaphore_offset(rq);
+	*cs++ = hold_switchout_semaphore_offset(rq);
 	*cs++ = 0;
 	*cs++ = 1;
 
@@ -773,7 +777,7 @@
 		MI_SEMAPHORE_POLL |
 		MI_SEMAPHORE_SAD_EQ_SDD;
 	*cs++ = 0;
-	*cs++ = ccs_semaphore_offset(rq);
+	*cs++ = hold_switchout_semaphore_offset(rq);
 	*cs++ = 0;
 
 	return cs;
@@ -790,8 +794,10 @@
 		cs = gen12_emit_preempt_busywait(rq, cs);
 
 	/* Wa_14014475959:dg2 */
-	if (intel_engine_uses_wa_hold_ccs_switchout(rq->engine))
-		cs = ccs_emit_wa_busywait(rq, cs);
+	/* Wa_16019325821 */
+	/* Wa_14019159160 */
+	if (intel_engine_uses_wa_hold_switchout(rq->engine))
+		cs = hold_switchout_emit_wa_busywait(rq, cs);
 
 	rq->tail = intel_ring_offset(rq, cs);
 	assert_ring_tail_valid(rq->ring, rq->tail);
@@ -822,7 +828,7 @@
 		flags |= PIPE_CONTROL_FLUSH_L3;
 
 	/* Wa_14016712196 */
-	if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)) || IS_DG2(i915))
+	if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)) || IS_DG2(i915))
 		/* dummy PIPE_CONTROL + depth flush */
 		cs = gen12_emit_pipe_control(cs, 0,
 					     PIPE_CONTROL_DEPTH_CACHE_FLUSH, 0);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
@@ -961,6 +961,9 @@
 	struct i915_vma *vma;
 	int ret;
 
+	if (!intel_gt_needs_wa_16018031267(vm->gt))
+		return 0;
+
 	/* The memory will be used only by GPU. */
 	obj = i915_gem_object_create_lmem(i915, PAGE_SIZE,
 					  I915_BO_ALLOC_VOLATILE |
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c
@@ -263,8 +263,13 @@
 		i915_request_put(rq);
 	}
 
+	/* Lazy irq enabling after HW submission */
 	if (!READ_ONCE(b->irq_armed) && !list_empty(&b->signalers))
 		intel_breadcrumbs_arm_irq(b);
+
+	/* And confirm that we still want irqs enabled before we yield */
+	if (READ_ONCE(b->irq_armed) && !atomic_read(&b->active))
+		intel_breadcrumbs_disarm_irq(b);
 }
 
 struct intel_breadcrumbs *
@@ -315,13 +320,7 @@
 		return;
 
 	/* Kick the work once more to drain the signalers, and disarm the irq */
-	irq_work_sync(&b->irq_work);
-	while (READ_ONCE(b->irq_armed) && !atomic_read(&b->active)) {
-		local_irq_disable();
-		signal_irq_work(&b->irq_work);
-		local_irq_enable();
-		cond_resched();
-	}
+	irq_work_queue(&b->irq_work);
 }
 
 void intel_breadcrumbs_free(struct kref *kref)
@@ -404,7 +403,7 @@
 	 * the request as it may have completed and raised the interrupt as
 	 * we were attaching it into the lists.
 	 */
-	if (!b->irq_armed || __i915_request_is_complete(rq))
+	if (!READ_ONCE(b->irq_armed) || __i915_request_is_complete(rq))
 		irq_work_queue(&b->irq_work);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -908,6 +908,29 @@
 		info->engine_mask &= ~BIT(GSC0);
 	}
 
+	/*
+	 * Do not create the command streamer for CCS slices beyond the first.
+	 * All the workload submitted to the first engine will be shared among
+	 * all the slices.
+	 *
+	 * Once the user will be allowed to customize the CCS mode, then this
+	 * check needs to be removed.
+	 */
+	if (IS_DG2(gt->i915)) {
+		u8 first_ccs = __ffs(CCS_MASK(gt));
+
+		/*
+		 * Store the number of active cslices before
+		 * changing the CCS engine configuration
+		 */
+		gt->ccs.cslices = CCS_MASK(gt);
+
+		/* Mask off all the CCS engine */
+		info->engine_mask &= ~GENMASK(CCS3, CCS0);
+		/* Put back in the first CCS engine */
+		info->engine_mask |= BIT(_CCS(first_ccs));
+	}
+
 	return info->engine_mask;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_engine_pm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_engine_pm.c
@@ -279,9 +279,6 @@
 	intel_engine_park_heartbeat(engine);
 	intel_breadcrumbs_park(engine->breadcrumbs);
 
-	/* Must be reset upon idling, or we may miss the busy wakeup. */
-	GEM_BUG_ON(engine->sched_engine->queue_priority_hint != INT_MIN);
-
 	if (engine->park)
 		engine->park(engine);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -343,6 +343,11 @@
 	 * @start_gt_clk: GT clock time of last idle to active transition.
 	 */
 	u64 start_gt_clk;
+
+	/**
+	 * @total: The last value of total returned
+	 */
+	u64 total;
 };
 
 union intel_engine_tlb_inv_reg {
@@ -586,7 +591,7 @@
 #define I915_ENGINE_HAS_RCS_REG_STATE  BIT(9)
 #define I915_ENGINE_HAS_EU_PRIORITY    BIT(10)
 #define I915_ENGINE_FIRST_RENDER_COMPUTE BIT(11)
-#define I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT BIT(12)
+#define I915_ENGINE_USES_WA_HOLD_SWITCHOUT BIT(12)
 	unsigned int flags;
 
 	/*
@@ -696,10 +701,12 @@
 }
 
 /* Wa_14014475959:dg2 */
+/* Wa_16019325821 */
+/* Wa_14019159160 */
 static inline bool
-intel_engine_uses_wa_hold_ccs_switchout(struct intel_engine_cs *engine)
+intel_engine_uses_wa_hold_switchout(struct intel_engine_cs *engine)
 {
-	return engine->flags & I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT;
+	return engine->flags & I915_ENGINE_USES_WA_HOLD_SWITCHOUT;
 }
 
 #endif /* __INTEL_ENGINE_TYPES_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_execlists_submission.c
@@ -3272,6 +3272,9 @@
 {
 	cancel_timer(&engine->execlists.timer);
 	cancel_timer(&engine->execlists.preempt);
+
+	/* Reset upon idling, or we may delay the busy wakeup. */
+	WRITE_ONCE(engine->sched_engine->queue_priority_hint, INT_MIN);
 }
 
 static void add_to_engine(struct i915_request *rq)
@@ -3312,11 +3315,7 @@
 
 static bool can_preempt(struct intel_engine_cs *engine)
 {
-	if (GRAPHICS_VER(engine->i915) > 8)
-		return true;
-
-	/* GPGPU on bdw requires extra w/a; not implemented */
-	return engine->class != RENDER_CLASS;
+	return GRAPHICS_VER(engine->i915) > 8;
 }
 
 static void kick_execlists(const struct i915_request *rq, int prio)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -24,6 +24,7 @@
 #include "intel_ring.h"
 #include "i915_drv.h"
 #include "i915_pci.h"
+#include "i915_reg.h"
 #include "i915_request.h"
 #include "i915_scatterlist.h"
 #include "i915_utils.h"
@@ -1152,13 +1153,20 @@
 static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
 {
 	struct drm_i915_private *i915 = ggtt->vm.i915;
+	struct intel_uncore *uncore = ggtt->vm.gt->uncore;
 	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
 	phys_addr_t phys_addr;
 	u32 pte_flags;
 	int ret;
 
 	GEM_WARN_ON(pci_resource_len(pdev, GEN4_GTTMMADR_BAR) != gen6_gttmmadr_size(i915));
-	phys_addr = pci_resource_start(pdev, GEN4_GTTMMADR_BAR) + gen6_gttadr_offset(i915);
+
+	if (i915_direct_stolen_access(i915)) {
+		drm_dbg(&i915->drm, "Using direct GSM access\n");
+		phys_addr = intel_uncore_read64(uncore, GEN12_GSMBASE) & GEN12_BDSM_MASK;
+	} else {
+		phys_addr = pci_resource_start(pdev, GEN4_GTTMMADR_BAR) + gen6_gttadr_offset(i915);
+	}
 
 	if (needs_wc_ggtt_mapping(i915))
 		ggtt->gsm = ioremap_wc(phys_addr, size);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c
@@ -298,6 +298,7 @@
 		return;
 
 	GEM_BUG_ON(fence->vma != vma);
+	i915_active_wait(&fence->active);
 	GEM_BUG_ON(!i915_active_is_idle(&fence->active));
 	GEM_BUG_ON(atomic_read(&fence->pin_count));
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_gt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -1024,6 +1024,12 @@
 		return I915_MAP_WC;
 }
 
+bool intel_gt_needs_wa_16018031267(struct intel_gt *gt)
+{
+	/* Wa_16018031267, Wa_16018063123 */
+	return IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 55), IP_VER(12, 71));
+}
+
 bool intel_gt_needs_wa_22016122933(struct intel_gt *gt)
 {
 	return MEDIA_VER_FULL(gt->i915) == IP_VER(13, 0) && gt->type == GT_MEDIA;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_gt.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_gt.h
@@ -82,17 +82,18 @@
 		  ##__VA_ARGS__);					\
 } while (0)
 
-#define NEEDS_FASTCOLOR_BLT_WABB(engine) ( \
-	IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 55), IP_VER(12, 71)) && \
-	engine->class == COPY_ENGINE_CLASS && engine->instance == 0)
-
 static inline bool gt_is_root(struct intel_gt *gt)
 {
 	return !gt->info.id;
 }
 
+bool intel_gt_needs_wa_16018031267(struct intel_gt *gt);
 bool intel_gt_needs_wa_22016122933(struct intel_gt *gt);
 
+#define NEEDS_FASTCOLOR_BLT_WABB(engine) ( \
+	intel_gt_needs_wa_16018031267(engine->gt) && \
+	engine->class == COPY_ENGINE_CLASS && engine->instance == 0)
+
 static inline struct intel_gt *uc_to_gt(struct intel_uc *uc)
 {
 	return container_of(uc, struct intel_gt, uc);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_gt_ccs_mode.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_gt_ccs_mode.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include "i915_drv.h"
+#include "intel_gt.h"
+#include "intel_gt_ccs_mode.h"
+#include "intel_gt_regs.h"
+
+unsigned int intel_gt_apply_ccs_mode(struct intel_gt *gt)
+{
+	int cslice;
+	u32 mode = 0;
+	int first_ccs = __ffs(CCS_MASK(gt));
+
+	if (!IS_DG2(gt->i915))
+		return 0;
+
+	/* Build the value for the fixed CCS load balancing */
+	for (cslice = 0; cslice < I915_MAX_CCS; cslice++) {
+		if (gt->ccs.cslices & BIT(cslice))
+			/*
+			 * If available, assign the cslice
+			 * to the first available engine...
+			 */
+			mode |= XEHP_CCS_MODE_CSLICE(cslice, first_ccs);
+
+		else
+			/*
+			 * ... otherwise, mark the cslice as
+			 * unavailable if no CCS dispatches here
+			 */
+			mode |= XEHP_CCS_MODE_CSLICE(cslice,
+						     XEHP_CCS_MODE_CSLICE_MASK);
+	}
+
+	return mode;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_gt_ccs_mode.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_gt_ccs_mode.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#ifndef __INTEL_GT_CCS_MODE_H__
+#define __INTEL_GT_CCS_MODE_H__
+
+struct intel_gt;
+
+unsigned int intel_gt_apply_ccs_mode(struct intel_gt *gt);
+
+#endif /* __INTEL_GT_CCS_MODE_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_gt_clock_utils.c
@@ -151,7 +151,7 @@
 	 *
 	 * Testing on actual hardware has shown there is no /16.
 	 */
-	return RUNTIME_INFO(uncore->i915)->rawclk_freq * 1000;
+	return DISPLAY_RUNTIME_INFO(uncore->i915)->rawclk_freq * 1000;
 }
 
 static u32 read_clock_frequency(struct intel_uncore *uncore)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1477,8 +1477,14 @@
 #define   ECOBITS_PPGTT_CACHE4B			(0 << 8)
 
 #define GEN12_RCU_MODE				_MMIO(0x14800)
+#define   XEHP_RCU_MODE_FIXED_SLICE_CCS_MODE	REG_BIT(1)
 #define   GEN12_RCU_MODE_CCS_ENABLE		REG_BIT(0)
 
+#define XEHP_CCS_MODE				_MMIO(0x14804)
+#define   XEHP_CCS_MODE_CSLICE_MASK		REG_GENMASK(2, 0) /* CCS0-3 + rsvd */
+#define   XEHP_CCS_MODE_CSLICE_WIDTH		ilog2(XEHP_CCS_MODE_CSLICE_MASK + 1)
+#define   XEHP_CCS_MODE_CSLICE(cslice, ccs)	(ccs << (cslice * XEHP_CCS_MODE_CSLICE_WIDTH))
+
 #define CHV_FUSE_GT				_MMIO(VLV_GUNIT_BASE + 0x2168)
 #define   CHV_FGT_DISABLE_SS0			(1 << 10)
 #define   CHV_FGT_DISABLE_SS1			(1 << 11)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_gt_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_gt_types.h
@@ -207,6 +207,14 @@
 					    [MAX_ENGINE_INSTANCE + 1];
 	enum intel_submission_method submission_method;
 
+	struct {
+		/*
+		 * Mask of the non fused CCS slices
+		 * to be used for the load balancing
+		 */
+		intel_engine_mask_t cslices;
+	} ccs;
+
 	/*
 	 * Default address space (either GGTT or ppGTT depending on arch).
 	 *
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_rc6.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_rc6.c
@@ -133,7 +133,7 @@
 			GEN9_MEDIA_PG_ENABLE |
 			GEN11_MEDIA_SAMPLER_PG_ENABLE;
 
-	if (GRAPHICS_VER(gt->i915) >= 12) {
+	if (GRAPHICS_VER(gt->i915) >= 12 && !IS_DG1(gt->i915)) {
 		for (i = 0; i < I915_MAX_VCS; i++)
 			if (HAS_ENGINE(gt, _VCS(i)))
 				pg_enable |= (VDN_HCP_POWERGATE_ENABLE(i) |
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/intel_workarounds.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/intel_workarounds.c
@@ -10,6 +10,7 @@
 #include "intel_engine_regs.h"
 #include "intel_gpu_commands.h"
 #include "intel_gt.h"
+#include "intel_gt_ccs_mode.h"
 #include "intel_gt_mcr.h"
 #include "intel_gt_print.h"
 #include "intel_gt_regs.h"
@@ -51,7 +52,8 @@
  *   registers belonging to BCS, VCS or VECS should be implemented in
  *   xcs_engine_wa_init(). Workarounds for registers not belonging to a specific
  *   engine's MMIO range but that are part of of the common RCS/CCS reset domain
- *   should be implemented in general_render_compute_wa_init().
+ *   should be implemented in general_render_compute_wa_init(). The settings
+ *   about the CCS load balancing should be added in ccs_engine_wa_mode().
  *
  * - GT workarounds: the list of these WAs is applied whenever these registers
  *   revert to their default values: on GPU reset, suspend/resume [1]_, etc.
@@ -789,8 +791,13 @@
 
 	dg2_ctx_gt_tuning_init(engine, wal);
 
-	if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_B0, STEP_FOREVER) ||
-	    IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_B0, STEP_FOREVER))
+	/*
+	 * Due to Wa_16014892111, the DRAW_WATERMARK tuning must be done in
+	 * gen12_emit_indirect_ctx_rcs() rather than here on some early
+	 * steppings.
+	 */
+	if (!(IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||
+	      IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_A0, STEP_B0)))
 		wa_add(wal, DRAW_WATERMARK, VERT_WM_VAL, 0x3FF, 0, false);
 }
 
@@ -908,7 +915,7 @@
 	if (engine->class != RENDER_CLASS)
 		goto done;
 
-	if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 71)))
+	if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 74)))
 		xelpg_ctx_workarounds_init(engine, wal);
 	else if (IS_PONTEVECCHIO(i915))
 		; /* noop; none at this time */
@@ -1643,7 +1650,8 @@
 static void
 xelpg_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-	/* Wa_14018778641 / Wa_18018781329 */
+	/* Wa_14018575942 / Wa_18018781329 */
+	wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);
 	wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);
 
 	/* Wa_22016670082 */
@@ -1710,7 +1718,7 @@
  */
 static void gt_tuning_settings(struct intel_gt *gt, struct i915_wa_list *wal)
 {
-	if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
+	if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74))) {
 		wa_mcr_write_or(wal, XEHP_L3SCQREG7, BLEND_FILL_CACHING_OPT_DIS);
 		wa_mcr_write_or(wal, XEHP_SQCM, EN_32B_ACCESS);
 	}
@@ -1743,7 +1751,7 @@
 		return;
 	}
 
-	if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
+	if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)))
 		xelpg_gt_workarounds_init(gt, wal);
 	else if (IS_PONTEVECCHIO(i915))
 		pvc_gt_workarounds_init(gt, wal);
@@ -2216,7 +2224,7 @@
 
 	if (engine->gt->type == GT_MEDIA)
 		; /* none yet */
-	else if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 71)))
+	else if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 74)))
 		xelpg_whitelist_build(engine);
 	else if (IS_PONTEVECCHIO(i915))
 		pvc_whitelist_build(engine);
@@ -2828,7 +2836,7 @@
 {
 	struct drm_i915_private *i915 = gt->i915;
 
-	if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)) || IS_DG2(i915))
+	if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)) || IS_DG2(i915))
 		wa_mcr_write_clr_set(wal, RT_CTRL, STACKID_CTRL, STACKID_CTRL_512);
 
 	/*
@@ -2844,6 +2852,30 @@
 		wa_write_clr(wal, GEN8_GARBCNTL, GEN12_BUS_HASH_CTL_BIT_EXC);
 }
 
+static void ccs_engine_wa_mode(struct intel_engine_cs *engine, struct i915_wa_list *wal)
+{
+	struct intel_gt *gt = engine->gt;
+	u32 mode;
+
+	if (!IS_DG2(gt->i915))
+		return;
+
+	/*
+	 * Wa_14019159160: This workaround, along with others, leads to
+	 * significant challenges in utilizing load balancing among the
+	 * CCS slices. Consequently, an architectural decision has been
+	 * made to completely disable automatic CCS load balancing.
+	 */
+	wa_masked_en(wal, GEN12_RCU_MODE, XEHP_RCU_MODE_FIXED_SLICE_CCS_MODE);
+
+	/*
+	 * After having disabled automatic load balancing we need to
+	 * assign all slices to a single CCS. We will call it CCS mode 1
+	 */
+	mode = intel_gt_apply_ccs_mode(gt);
+	wa_masked_en(wal, XEHP_CCS_MODE, mode);
+}
+
 /*
  * The workarounds in this function apply to shared registers in
  * the general render reset domain that aren't tied to a
@@ -2881,7 +2913,8 @@
 	}
 
 	if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_B0, STEP_FOREVER) ||
-	    IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_B0, STEP_FOREVER))
+	    IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_B0, STEP_FOREVER) ||
+	    IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 74), IP_VER(12, 74)))
 		/* Wa_14017856879 */
 		wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN3, MTL_DISABLE_FIX_FOR_EOT_FLUSH);
 
@@ -2993,8 +3026,10 @@
 	 * to a single RCS/CCS engine's workaround list since
 	 * they're reset as part of the general render domain reset.
 	 */
-	if (engine->flags & I915_ENGINE_FIRST_RENDER_COMPUTE)
+	if (engine->flags & I915_ENGINE_FIRST_RENDER_COMPUTE) {
 		general_render_compute_wa_init(engine, wal);
+		ccs_engine_wa_mode(engine, wal);
+	}
 
 	if (engine->class == COMPUTE_CLASS)
 		ccs_engine_wa_init(engine, wal);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
@@ -36,6 +36,7 @@
 	INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_START,
 	INTEL_GUC_LOAD_STATUS_MPU_DATA_INVALID                 = 0x73,
 	INTEL_GUC_LOAD_STATUS_INIT_MMIO_SAVE_RESTORE_INVALID   = 0x74,
+	INTEL_GUC_LOAD_STATUS_KLV_WORKAROUND_INIT_ERROR        = 0x75,
 	INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_END,
 
 	INTEL_GUC_LOAD_STATUS_READY                            = 0xF0,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
@@ -29,9 +29,9 @@
  */
 
 #define GUC_KLV_LEN_MIN				1u
-#define GUC_KLV_0_KEY				(0xffff << 16)
-#define GUC_KLV_0_LEN				(0xffff << 0)
-#define GUC_KLV_n_VALUE				(0xffffffff << 0)
+#define GUC_KLV_0_KEY				(0xffffu << 16)
+#define GUC_KLV_0_LEN				(0xffffu << 0)
+#define GUC_KLV_n_VALUE				(0xffffffffu << 0)
 
 /**
  * DOC: GuC Self Config KLVs
@@ -101,4 +101,11 @@
 	GUC_CONTEXT_POLICIES_KLV_NUM_IDS = 5,
 };
 
+/*
+ * Workaround keys:
+ */
+enum {
+	GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE				= 0x9001,
+};
+
 #endif /* _ABI_GUC_KLVS_ABI_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -302,7 +302,7 @@
 {
 	struct intel_gt *gt = gsc_uc_to_gt(gsc);
 
-	if (!intel_uc_fw_is_loadable(&gsc->fw))
+	if (!intel_uc_fw_is_loadable(&gsc->fw) || intel_uc_fw_is_in_error(&gsc->fw))
 		return;
 
 	if (intel_gsc_uc_fw_init_done(gsc))
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -294,6 +294,11 @@
 	    IS_DG2(gt->i915))
 		flags |= GUC_WA_HOLD_CCS_SWITCHOUT;
 
+	/* Wa_16019325821 */
+	/* Wa_14019159160 */
+	if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
+		flags |= GUC_WA_RCS_CCS_SWITCHOUT;
+
 	/*
 	 * Wa_14012197797
 	 * Wa_22011391025
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -204,6 +204,8 @@
 	struct guc_mmio_reg *ads_regset;
 	/** @ads_golden_ctxt_size: size of the golden contexts in the ADS */
 	u32 ads_golden_ctxt_size;
+	/** @ads_waklv_size: size of workaround KLVs */
+	u32 ads_waklv_size;
 	/** @ads_capture_size: size of register lists in the ADS used for error capture */
 	u32 ads_capture_size;
 	/** @ads_engine_usage_size: size of engine usage in the ADS */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -46,6 +46,10 @@
  *      +---------------------------------------+
  *      | padding                               |
  *      +---------------------------------------+ <== 4K aligned
+ *      | w/a KLVs                              |
+ *      +---------------------------------------+
+ *      | padding                               |
+ *      +---------------------------------------+ <== 4K aligned
  *      | capture lists                         |
  *      +---------------------------------------+
  *      | padding                               |
@@ -88,6 +92,11 @@
 	return PAGE_ALIGN(guc->ads_golden_ctxt_size);
 }
 
+static u32 guc_ads_waklv_size(struct intel_guc *guc)
+{
+	return PAGE_ALIGN(guc->ads_waklv_size);
+}
+
 static u32 guc_ads_capture_size(struct intel_guc *guc)
 {
 	return PAGE_ALIGN(guc->ads_capture_size);
@@ -113,7 +122,7 @@
 	return PAGE_ALIGN(offset);
 }
 
-static u32 guc_ads_capture_offset(struct intel_guc *guc)
+static u32 guc_ads_waklv_offset(struct intel_guc *guc)
 {
 	u32 offset;
 
@@ -123,6 +132,16 @@
 	return PAGE_ALIGN(offset);
 }
 
+static u32 guc_ads_capture_offset(struct intel_guc *guc)
+{
+	u32 offset;
+
+	offset = guc_ads_waklv_offset(guc) +
+		 guc_ads_waklv_size(guc);
+
+	return PAGE_ALIGN(offset);
+}
+
 static u32 guc_ads_private_data_offset(struct intel_guc *guc)
 {
 	u32 offset;
@@ -791,6 +810,65 @@
 	return PAGE_ALIGN(total_size);
 }
 
+/* Wa_14019159160 */
+static u32 guc_waklv_ra_mode(struct intel_guc *guc, u32 offset, u32 remain)
+{
+	u32 size;
+	u32 klv_entry[] = {
+		/* 16:16 key/length */
+		FIELD_PREP(GUC_KLV_0_KEY, GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE) |
+		FIELD_PREP(GUC_KLV_0_LEN, 0),
+		/* 0 dwords data */
+	};
+
+	size = sizeof(klv_entry);
+	GEM_BUG_ON(remain < size);
+
+	iosys_map_memcpy_to(&guc->ads_map, offset, klv_entry, size);
+
+	return size;
+}
+
+static void guc_waklv_init(struct intel_guc *guc)
+{
+	struct intel_gt *gt = guc_to_gt(guc);
+	u32 offset, addr_ggtt, remain, size;
+
+	if (!intel_uc_uses_guc_submission(&gt->uc))
+		return;
+
+	if (GUC_FIRMWARE_VER(guc) < MAKE_GUC_VER(70, 10, 0))
+		return;
+
+	GEM_BUG_ON(iosys_map_is_null(&guc->ads_map));
+	offset = guc_ads_waklv_offset(guc);
+	remain = guc_ads_waklv_size(guc);
+
+	/* Wa_14019159160 */
+	if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
+		size = guc_waklv_ra_mode(guc, offset, remain);
+		offset += size;
+		remain -= size;
+	}
+
+	size = guc_ads_waklv_size(guc) - remain;
+	if (!size)
+		return;
+
+	offset = guc_ads_waklv_offset(guc);
+	addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
+
+	ads_blob_write(guc, ads.wa_klv_addr_lo, addr_ggtt);
+	ads_blob_write(guc, ads.wa_klv_addr_hi, 0);
+	ads_blob_write(guc, ads.wa_klv_size, size);
+}
+
+static int guc_prep_waklv(struct intel_guc *guc)
+{
+	/* Fudge something chunky for now: */
+	return PAGE_SIZE;
+}
+
 static void __guc_ads_init(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
@@ -838,6 +916,9 @@
 	/* MMIO save/restore list */
 	guc_mmio_reg_state_init(guc);
 
+	/* Workaround KLV list */
+	guc_waklv_init(guc);
+
 	/* Private Data */
 	ads_blob_write(guc, ads.private_data, base +
 		       guc_ads_private_data_offset(guc));
@@ -881,6 +962,12 @@
 		return ret;
 	guc->ads_capture_size = ret;
 
+	/* And don't forget the workaround KLVs: */
+	ret = guc_prep_waklv(guc);
+	if (ret < 0)
+		return ret;
+	guc->ads_waklv_size = ret;
+
 	/* Now the total size can be determined: */
 	size = guc_ads_blob_size(guc);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -115,6 +115,7 @@
 	case INTEL_GUC_LOAD_STATUS_INIT_DATA_INVALID:
 	case INTEL_GUC_LOAD_STATUS_MPU_DATA_INVALID:
 	case INTEL_GUC_LOAD_STATUS_INIT_MMIO_SAVE_RESTORE_INVALID:
+	case INTEL_GUC_LOAD_STATUS_KLV_WORKAROUND_INIT_ERROR:
 		*success = false;
 		return true;
 	}
@@ -184,7 +185,7 @@
 	 * in the seconds range. However, there is a limit on how long an
 	 * individual wait_for() can wait. So wrap it in a loop.
 	 */
-	before_freq = intel_rps_read_actual_frequency(&uncore->gt->rps);
+	before_freq = intel_rps_read_actual_frequency(&gt->rps);
 	before = ktime_get();
 	for (count = 0; count < GUC_LOAD_RETRY_LIMIT; count++) {
 		ret = wait_for(guc_load_done(uncore, &status, &success), 1000);
@@ -192,7 +193,7 @@
 			break;
 
 		guc_dbg(guc, "load still in progress, count = %d, freq = %dMHz, status = 0x%08X [0x%02X/%02X]\n",
-			count, intel_rps_read_actual_frequency(&uncore->gt->rps), status,
+			count, intel_rps_read_actual_frequency(&gt->rps), status,
 			REG_FIELD_GET(GS_BOOTROM_MASK, status),
 			REG_FIELD_GET(GS_UKERNEL_MASK, status));
 	}
@@ -204,7 +205,7 @@
 		u32 bootrom = REG_FIELD_GET(GS_BOOTROM_MASK, status);
 
 		guc_info(guc, "load failed: status = 0x%08X, time = %lldms, freq = %dMHz, ret = %d\n",
-			 status, delta_ms, intel_rps_read_actual_frequency(&uncore->gt->rps), ret);
+			 status, delta_ms, intel_rps_read_actual_frequency(&gt->rps), ret);
 		guc_info(guc, "load failed: status: Reset = %d, BootROM = 0x%02X, UKernel = 0x%02X, MIA = 0x%02X, Auth = 0x%02X\n",
 			 REG_FIELD_GET(GS_MIA_IN_RESET, status),
 			 bootrom, ukernel,
@@ -241,6 +242,11 @@
 			ret = -EPERM;
 			break;
 
+		case INTEL_GUC_LOAD_STATUS_KLV_WORKAROUND_INIT_ERROR:
+			guc_info(guc, "invalid w/a KLV entry\n");
+			ret = -EINVAL;
+			break;
+
 		case INTEL_GUC_LOAD_STATUS_HWCONFIG_START:
 			guc_info(guc, "still extracting hwconfig table.\n");
 			ret = -ETIMEDOUT;
@@ -254,11 +260,11 @@
 		guc_warn(guc, "excessive init time: %lldms! [status = 0x%08X, count = %d, ret = %d]\n",
 			 delta_ms, status, count, ret);
 		guc_warn(guc, "excessive init time: [freq = %dMHz, before = %dMHz, perf_limit_reasons = 0x%08X]\n",
-			 intel_rps_read_actual_frequency(&uncore->gt->rps), before_freq,
+			 intel_rps_read_actual_frequency(&gt->rps), before_freq,
 			 intel_uncore_read(uncore, intel_gt_perf_limit_reasons_reg(gt)));
 	} else {
 		guc_dbg(guc, "init took %lldms, freq = %dMHz, before = %dMHz, status = 0x%08X, count = %d, ret = %d\n",
-			delta_ms, intel_rps_read_actual_frequency(&uncore->gt->rps),
+			delta_ms, intel_rps_read_actual_frequency(&gt->rps),
 			before_freq, status, count, ret);
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -96,8 +96,9 @@
 #define   GUC_WA_GAM_CREDITS		BIT(10)
 #define   GUC_WA_DUAL_QUEUE		BIT(11)
 #define   GUC_WA_RCS_RESET_BEFORE_RC6	BIT(13)
-#define   GUC_WA_CONTEXT_ISOLATION	BIT(15)
 #define   GUC_WA_PRE_PARSER		BIT(14)
+#define   GUC_WA_CONTEXT_ISOLATION	BIT(15)
+#define   GUC_WA_RCS_CCS_SWITCHOUT	BIT(16)
 #define   GUC_WA_HOLD_CCS_SWITCHOUT	BIT(17)
 #define   GUC_WA_POLLCS			BIT(18)
 #define   GUC_WA_RCS_REGS_IN_CCS_REGS_LIST	BIT(21)
@@ -430,7 +431,10 @@
 	u32 capture_instance[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES];
 	u32 capture_class[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES];
 	u32 capture_global[GUC_CAPTURE_LIST_INDEX_MAX];
-	u32 reserved[14];
+	u32 wa_klv_addr_lo;
+	u32 wa_klv_addr_hi;
+	u32 wa_klv_size;
+	u32 reserved[11];
 } __packed;
 
 /* Engine usage stats */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1230,6 +1230,21 @@
 	} while (++i < 6);
 }
 
+static void __set_engine_usage_record(struct intel_engine_cs *engine,
+				      u32 last_in, u32 id, u32 total)
+{
+	struct iosys_map rec_map = intel_guc_engine_usage_record_map(engine);
+
+#define record_write(map_, field_, val_) \
+	iosys_map_wr_field(map_, 0, struct guc_engine_usage_record, field_, val_)
+
+	record_write(&rec_map, last_switch_in_stamp, last_in);
+	record_write(&rec_map, current_context_index, id);
+	record_write(&rec_map, total_runtime, total);
+
+#undef record_write
+}
+
 static void guc_update_engine_gt_clks(struct intel_engine_cs *engine)
 {
 	struct intel_engine_guc_stats *stats = &engine->stats.guc;
@@ -1350,9 +1365,12 @@
 		total += intel_gt_clock_interval_to_ns(gt, clk);
 	}
 
+	if (total > stats->total)
+		stats->total = total;
+
 	spin_unlock_irqrestore(&guc->timestamp.lock, flags);
 
-	return ns_to_ktime(total);
+	return ns_to_ktime(stats->total);
 }
 
 static void guc_enable_busyness_worker(struct intel_guc *guc)
@@ -1379,8 +1397,21 @@
 
 	guc_update_pm_timestamp(guc, &unused);
 	for_each_engine(engine, gt, id) {
+		struct intel_engine_guc_stats *stats = &engine->stats.guc;
+
 		guc_update_engine_gt_clks(engine);
-		engine->stats.guc.prev_total = 0;
+
+		/*
+		 * If resetting a running context, accumulate the active
+		 * time as well since there will be no context switch.
+		 */
+		if (stats->running) {
+			u64 clk = guc->timestamp.gt_stamp - stats->start_gt_clk;
+
+			stats->total_gt_clks += clk;
+		}
+		stats->prev_total = 0;
+		stats->running = 0;
 	}
 
 	spin_unlock_irqrestore(&guc->timestamp.lock, flags);
@@ -1491,6 +1522,9 @@
 
 static int guc_action_enable_usage_stats(struct intel_guc *guc)
 {
+	struct intel_gt *gt = guc_to_gt(guc);
+	struct intel_engine_cs *engine;
+	enum intel_engine_id id;
 	u32 offset = intel_guc_engine_usage_offset(guc);
 	u32 action[] = {
 		INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF,
@@ -1498,6 +1532,9 @@
 		0,
 	};
 
+	for_each_engine(engine, gt, id)
+		__set_engine_usage_record(engine, 0, 0xffffffff, 0);
+
 	return intel_guc_send(guc, action, ARRAY_SIZE(action));
 }
 
@@ -2778,9 +2815,9 @@
 		ce->parallel.guc.wqi_tail = 0;
 		ce->parallel.guc.wqi_head = 0;
 
-		wq_desc_offset = i915_ggtt_offset(ce->state) +
+		wq_desc_offset = (u64)i915_ggtt_offset(ce->state) +
 				 __get_parent_scratch_offset(ce);
-		wq_base_offset = i915_ggtt_offset(ce->state) +
+		wq_base_offset = (u64)i915_ggtt_offset(ce->state) +
 				 __get_wq_offset(ce);
 		info->wq_desc_lo = lower_32_bits(wq_desc_offset);
 		info->wq_desc_hi = upper_32_bits(wq_desc_offset);
@@ -4382,7 +4419,13 @@
 	if (engine->class == COMPUTE_CLASS)
 		if (IS_GFX_GT_IP_STEP(engine->gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||
 		    IS_DG2(engine->i915))
-			engine->flags |= I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT;
+			engine->flags |= I915_ENGINE_USES_WA_HOLD_SWITCHOUT;
+
+	/* Wa_16019325821 */
+	/* Wa_14019159160 */
+	if ((engine->class == COMPUTE_CLASS || engine->class == RENDER_CLASS) &&
+	    IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 71)))
+		engine->flags |= I915_ENGINE_USES_WA_HOLD_SWITCHOUT;
 
 	/*
 	 * TODO: GuC supports timeslicing and semaphores as well, but they're
@@ -5348,12 +5391,20 @@
 {
 	drm_printf(p, "GuC lrc descriptor %u:\n", ce->guc_id.id);
 	drm_printf(p, "\tHW Context Desc: 0x%08x\n", ce->lrc.lrca);
-	drm_printf(p, "\t\tLRC Head: Internal %u, Memory %u\n",
-		   ce->ring->head,
-		   ce->lrc_reg_state[CTX_RING_HEAD]);
-	drm_printf(p, "\t\tLRC Tail: Internal %u, Memory %u\n",
-		   ce->ring->tail,
-		   ce->lrc_reg_state[CTX_RING_TAIL]);
+	if (intel_context_pin_if_active(ce)) {
+		drm_printf(p, "\t\tLRC Head: Internal %u, Memory %u\n",
+			   ce->ring->head,
+			   ce->lrc_reg_state[CTX_RING_HEAD]);
+		drm_printf(p, "\t\tLRC Tail: Internal %u, Memory %u\n",
+			   ce->ring->tail,
+			   ce->lrc_reg_state[CTX_RING_TAIL]);
+		intel_context_unpin(ce);
+	} else {
+		drm_printf(p, "\t\tLRC Head: Internal %u, Memory not pinned\n",
+			   ce->ring->head);
+		drm_printf(p, "\t\tLRC Tail: Internal %u, Memory not pinned\n",
+			   ce->ring->tail);
+	}
 	drm_printf(p, "\t\tContext Pin Count: %u\n",
 		   atomic_read(&ce->pin_count));
 	drm_printf(p, "\t\tGuC ID Ref Count: %u\n",
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -6,6 +6,7 @@
 #include <linux/types.h>
 
 #include "gt/intel_gt.h"
+#include "gt/intel_rps.h"
 #include "intel_guc_reg.h"
 #include "intel_huc.h"
 #include "intel_huc_print.h"
@@ -447,17 +448,68 @@
 	return partial ? "clear media" : "all workloads";
 }
 
+/*
+ * Use a longer timeout for debug builds so that problems can be detected
+ * and analysed. But a shorter timeout for releases so that user's don't
+ * wait forever to find out there is a problem. Note that the only reason
+ * an end user should hit the timeout is in case of extreme thermal throttling.
+ * And a system that is that hot during boot is probably dead anyway!
+ */
+#if defined(CONFIG_DRM_I915_DEBUG_GEM)
+#define HUC_LOAD_RETRY_LIMIT   20
+#else
+#define HUC_LOAD_RETRY_LIMIT   3
+#endif
+
 int intel_huc_wait_for_auth_complete(struct intel_huc *huc,
 				     enum intel_huc_authentication_type type)
 {
 	struct intel_gt *gt = huc_to_gt(huc);
-	int ret;
-
-	ret = __intel_wait_for_register(gt->uncore,
-					huc->status[type].reg,
-					huc->status[type].mask,
-					huc->status[type].value,
-					2, 50, NULL);
+	struct intel_uncore *uncore = gt->uncore;
+	ktime_t before, after, delta;
+	int ret, count;
+	u64 delta_ms;
+	u32 before_freq;
+
+	/*
+	 * The KMD requests maximum frequency during driver load, however thermal
+	 * throttling can force the frequency down to minimum (although the board
+	 * really should never get that hot in real life!). IFWI  issues have been
+	 * seen to cause sporadic failures to grant the higher frequency. And at
+	 * minimum frequency, the authentication time can be in the seconds range.
+	 * Note that there is a limit on how long an individual wait_for() can wait.
+	 * So wrap it in a loop.
+	 */
+	before_freq = intel_rps_read_actual_frequency(&gt->rps);
+	before = ktime_get();
+	for (count = 0; count < HUC_LOAD_RETRY_LIMIT; count++) {
+		ret = __intel_wait_for_register(gt->uncore,
+						huc->status[type].reg,
+						huc->status[type].mask,
+						huc->status[type].value,
+						2, 1000, NULL);
+		if (!ret)
+			break;
+
+		huc_dbg(huc, "auth still in progress, count = %d, freq = %dMHz, status = 0x%08X\n",
+			count, intel_rps_read_actual_frequency(&gt->rps),
+			huc->status[type].reg.reg);
+	}
+	after = ktime_get();
+	delta = ktime_sub(after, before);
+	delta_ms = ktime_to_ms(delta);
+
+	if (delta_ms > 50) {
+		huc_warn(huc, "excessive auth time: %lldms! [status = 0x%08X, count = %d, ret = %d]\n",
+			 delta_ms, huc->status[type].reg.reg, count, ret);
+		huc_warn(huc, "excessive auth time: [freq = %dMHz, before = %dMHz, perf_limit_reasons = 0x%08X]\n",
+			 intel_rps_read_actual_frequency(&gt->rps), before_freq,
+			 intel_uncore_read(uncore, intel_gt_perf_limit_reasons_reg(gt)));
+	} else {
+		huc_dbg(huc, "auth took %lldms, freq = %dMHz, before = %dMHz, status = 0x%08X, count = %d, ret = %d\n",
+			delta_ms, intel_rps_read_actual_frequency(&gt->rps),
+			before_freq, huc->status[type].reg.reg, count, ret);
+	}
 
 	/* mark the load process as complete even if the wait failed */
 	delayed_huc_load_complete(huc);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
@@ -258,6 +258,11 @@
 	return __intel_uc_fw_status(uc_fw) == INTEL_UC_FIRMWARE_RUNNING;
 }
 
+static inline bool intel_uc_fw_is_in_error(struct intel_uc_fw *uc_fw)
+{
+	return intel_uc_fw_status_to_error(__intel_uc_fw_status(uc_fw)) != 0;
+}
+
 static inline bool intel_uc_fw_is_overridden(const struct intel_uc_fw *uc_fw)
 {
 	return uc_fw->user_overridden;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/i915_driver.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/i915_driver.c
@@ -799,7 +799,7 @@
 		goto out_cleanup_modeset2;
 
 	ret = intel_pxp_init(i915);
-	if (ret != -ENODEV)
+	if (ret && ret != -ENODEV)
 		drm_dbg(&i915->drm, "pxp init failed with %d\n", ret);
 
 	ret = intel_display_driver_probe(i915);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/i915_gpu_error.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -1650,9 +1650,21 @@
 		return NULL;
 
 	intel_engine_get_hung_entity(engine, &ce, &rq);
-	if (rq && !i915_request_started(rq))
-		drm_info(&engine->gt->i915->drm, "Got hung context on %s with active request %lld:%lld [0x%04X] not yet started\n",
-			 engine->name, rq->fence.context, rq->fence.seqno, ce->guc_id.id);
+	if (rq && !i915_request_started(rq)) {
+		/*
+		 * We want to know also what is the guc_id of the context,
+		 * but if we don't have the context reference, then skip
+		 * printing it.
+		 */
+		if (ce)
+			drm_info(&engine->gt->i915->drm,
+				 "Got hung context on %s with active request %lld:%lld [0x%04X] not yet started\n",
+				 engine->name, rq->fence.context, rq->fence.seqno, ce->guc_id.id);
+		else
+			drm_info(&engine->gt->i915->drm,
+				 "Got hung context on %s with active request %lld:%lld not yet started\n",
+				 engine->name, rq->fence.context, rq->fence.seqno);
+	}
 
 	if (rq) {
 		capture = intel_engine_coredump_add_request(ee, rq, ATOMIC_MAYFAIL);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/i915_hwmon.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/i915_hwmon.c
@@ -72,12 +72,13 @@
 	struct intel_uncore *uncore = ddat->uncore;
 	intel_wakeref_t wakeref;
 
-	mutex_lock(&hwmon->hwmon_lock);
+	with_intel_runtime_pm(uncore->rpm, wakeref) {
+		mutex_lock(&hwmon->hwmon_lock);
 
-	with_intel_runtime_pm(uncore->rpm, wakeref)
 		intel_uncore_rmw(uncore, reg, clear, set);
 
-	mutex_unlock(&hwmon->hwmon_lock);
+		mutex_unlock(&hwmon->hwmon_lock);
+	}
 }
 
 /*
@@ -136,20 +137,21 @@
 	else
 		rgaddr = hwmon->rg.energy_status_all;
 
-	mutex_lock(&hwmon->hwmon_lock);
+	with_intel_runtime_pm(uncore->rpm, wakeref) {
+		mutex_lock(&hwmon->hwmon_lock);
 
-	with_intel_runtime_pm(uncore->rpm, wakeref)
 		reg_val = intel_uncore_read(uncore, rgaddr);
 
-	if (reg_val >= ei->reg_val_prev)
-		ei->accum_energy += reg_val - ei->reg_val_prev;
-	else
-		ei->accum_energy += UINT_MAX - ei->reg_val_prev + reg_val;
-	ei->reg_val_prev = reg_val;
+		if (reg_val >= ei->reg_val_prev)
+			ei->accum_energy += reg_val - ei->reg_val_prev;
+		else
+			ei->accum_energy += UINT_MAX - ei->reg_val_prev + reg_val;
+		ei->reg_val_prev = reg_val;
 
-	*energy = mul_u64_u32_shr(ei->accum_energy, SF_ENERGY,
-				  hwmon->scl_shift_energy);
-	mutex_unlock(&hwmon->hwmon_lock);
+		*energy = mul_u64_u32_shr(ei->accum_energy, SF_ENERGY,
+					  hwmon->scl_shift_energy);
+		mutex_unlock(&hwmon->hwmon_lock);
+	}
 }
 
 static ssize_t
@@ -404,6 +406,7 @@
 
 	/* Block waiting for GuC reset to complete when needed */
 	for (;;) {
+		wakeref = intel_runtime_pm_get(ddat->uncore->rpm);
 		mutex_lock(&hwmon->hwmon_lock);
 
 		prepare_to_wait(&ddat->waitq, &wait, TASK_INTERRUPTIBLE);
@@ -417,14 +420,13 @@
 		}
 
 		mutex_unlock(&hwmon->hwmon_lock);
+		intel_runtime_pm_put(ddat->uncore->rpm, wakeref);
 
 		schedule();
 	}
 	finish_wait(&ddat->waitq, &wait);
 	if (ret)
-		goto unlock;
-
-	wakeref = intel_runtime_pm_get(ddat->uncore->rpm);
+		goto exit;
 
 	/* Disable PL1 limit and verify, because the limit cannot be disabled on all platforms */
 	if (val == PL1_DISABLE) {
@@ -444,9 +446,8 @@
 	intel_uncore_rmw(ddat->uncore, hwmon->rg.pkg_rapl_limit,
 			 PKG_PWR_LIM_1_EN | PKG_PWR_LIM_1, nval);
 exit:
-	intel_runtime_pm_put(ddat->uncore->rpm, wakeref);
-unlock:
 	mutex_unlock(&hwmon->hwmon_lock);
+	intel_runtime_pm_put(ddat->uncore->rpm, wakeref);
 	return ret;
 }
 
@@ -792,7 +793,7 @@
 	if (!IS_DGFX(i915))
 		return;
 
-	hwmon = devm_kzalloc(dev, sizeof(*hwmon), GFP_KERNEL);
+	hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL);
 	if (!hwmon)
 		return;
 
@@ -818,14 +819,12 @@
 	hwm_get_preregistration_info(i915);
 
 	/*  hwmon_dev points to device hwmon<i> */
-	hwmon_dev = devm_hwmon_device_register_with_info(dev, ddat->name,
-							 ddat,
-							 &hwm_chip_info,
-							 hwm_groups);
-	if (IS_ERR(hwmon_dev)) {
-		i915->hwmon = NULL;
-		return;
-	}
+	hwmon_dev = hwmon_device_register_with_info(dev, ddat->name,
+						    ddat,
+						    &hwm_chip_info,
+						    hwm_groups);
+	if (IS_ERR(hwmon_dev))
+		goto err;
 
 	ddat->hwmon_dev = hwmon_dev;
 
@@ -838,16 +837,36 @@
 		if (!hwm_gt_is_visible(ddat_gt, hwmon_energy, hwmon_energy_input, 0))
 			continue;
 
-		hwmon_dev = devm_hwmon_device_register_with_info(dev, ddat_gt->name,
-								 ddat_gt,
-								 &hwm_gt_chip_info,
-								 NULL);
+		hwmon_dev = hwmon_device_register_with_info(dev, ddat_gt->name,
+							    ddat_gt,
+							    &hwm_gt_chip_info,
+							    NULL);
 		if (!IS_ERR(hwmon_dev))
 			ddat_gt->hwmon_dev = hwmon_dev;
 	}
+	return;
+err:
+	i915_hwmon_unregister(i915);
 }
 
 void i915_hwmon_unregister(struct drm_i915_private *i915)
 {
-	fetch_and_zero(&i915->hwmon);
+	struct i915_hwmon *hwmon = i915->hwmon;
+	struct intel_gt *gt;
+	int i;
+
+	if (!hwmon)
+		return;
+
+	for_each_gt(gt, i915, i)
+		if (hwmon->ddat_gt[i].hwmon_dev)
+			hwmon_device_unregister(hwmon->ddat_gt[i].hwmon_dev);
+
+	if (hwmon->ddat.hwmon_dev)
+		hwmon_device_unregister(hwmon->ddat.hwmon_dev);
+
+	mutex_destroy(&hwmon->hwmon_lock);
+
+	kfree(i915->hwmon);
+	i915->hwmon = NULL;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/i915_perf.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/i915_perf.c
@@ -2749,26 +2749,6 @@
 }
 
 static int
-gen12_configure_all_contexts(struct i915_perf_stream *stream,
-			     const struct i915_oa_config *oa_config,
-			     struct i915_active *active)
-{
-	struct flex regs[] = {
-		{
-			GEN8_R_PWR_CLK_STATE(RENDER_RING_BASE),
-			CTX_R_PWR_CLK_STATE,
-		},
-	};
-
-	if (stream->engine->class != RENDER_CLASS)
-		return 0;
-
-	return oa_configure_all_contexts(stream,
-					 regs, ARRAY_SIZE(regs),
-					 active);
-}
-
-static int
 lrc_configure_all_contexts(struct i915_perf_stream *stream,
 			   const struct i915_oa_config *oa_config,
 			   struct i915_active *active)
@@ -2874,7 +2854,6 @@
 {
 	struct drm_i915_private *i915 = stream->perf->i915;
 	struct intel_uncore *uncore = stream->uncore;
-	struct i915_oa_config *oa_config = stream->oa_config;
 	bool periodic = stream->periodic;
 	u32 period_exponent = stream->period_exponent;
 	u32 sqcnt1;
@@ -2919,15 +2898,6 @@
 	intel_uncore_rmw(uncore, GEN12_SQCNT1, 0, sqcnt1);
 
 	/*
-	 * Update all contexts prior writing the mux configurations as we need
-	 * to make sure all slices/subslices are ON before writing to NOA
-	 * registers.
-	 */
-	ret = gen12_configure_all_contexts(stream, oa_config, active);
-	if (ret)
-		return ret;
-
-	/*
 	 * For Gen12, performance counters are context
 	 * saved/restored. Only enable it for the context that
 	 * requested this.
@@ -2981,9 +2951,6 @@
 				   _MASKED_BIT_DISABLE(GEN12_DISABLE_DOP_GATING));
 	}
 
-	/* Reset all contexts' slices/subslices configurations. */
-	gen12_configure_all_contexts(stream, NULL, NULL);
-
 	/* disable the context save/restore or OAR counters */
 	if (stream->ctx)
 		gen12_configure_oar_context(stream, NULL);
@@ -3225,7 +3192,7 @@
 	struct intel_gt *gt = to_gt(i915);
 
 	/* Wa_18013179988 */
-	if (IS_DG2(i915) || IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
+	if (IS_DG2(i915) || IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74))) {
 		intel_wakeref_t wakeref;
 		u32 reg, shift;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/i915_reg.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/i915_reg.h
@@ -4597,7 +4597,7 @@
 #define MTL_CHICKEN_TRANS(trans)	_MMIO_TRANS((trans), \
 						    _MTL_CHICKEN_TRANS_A, \
 						    _MTL_CHICKEN_TRANS_B)
-#define   PIPE_VBLANK_WITH_DELAY	REG_BIT(31) /* ADL/DG2 */
+#define   PIPE_VBLANK_WITH_DELAY	REG_BIT(31) /* tgl+ */
 #define   SKL_UNMASK_VBL_TO_PIPE_IN_SRD	REG_BIT(30) /* skl+ */
 #define   HSW_FRAME_START_DELAY_MASK	REG_GENMASK(28, 27)
 #define   HSW_FRAME_START_DELAY(x)	REG_FIELD_PREP(HSW_FRAME_START_DELAY_MASK, x)
@@ -5412,6 +5412,9 @@
 #define   GEN6_PCODE_FREQ_RING_RATIO_SHIFT	16
 #define GEN6_PCODE_DATA1			_MMIO(0x13812C)
 
+#define MTL_PCODE_STOLEN_ACCESS			_MMIO(0x138914)
+#define   STOLEN_ACCESS_ALLOWED			0x1
+
 /* IVYBRIDGE DPF */
 #define GEN7_L3CDERRST1(slice)		_MMIO(0xB008 + (slice) * 0x200) /* L3CD Error Status 1 */
 #define   GEN7_L3CDERRST1_ROW_MASK	(0x7ff << 14)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/i915_scheduler.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/i915_scheduler.c
@@ -506,6 +506,6 @@
 	return 0;
 
 err_priorities:
-	kmem_cache_destroy(slab_priorities);
+	kmem_cache_destroy(slab_dependencies);
 	return -ENOMEM;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/i915_sw_fence.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/i915_sw_fence.c
@@ -51,7 +51,7 @@
 	debug_object_init(fence, &i915_sw_fence_debug_descr);
 }
 
-static inline void debug_fence_init_onstack(struct i915_sw_fence *fence)
+static inline __maybe_unused void debug_fence_init_onstack(struct i915_sw_fence *fence)
 {
 	debug_object_init_on_stack(fence, &i915_sw_fence_debug_descr);
 }
@@ -77,7 +77,7 @@
 	debug_object_destroy(fence, &i915_sw_fence_debug_descr);
 }
 
-static inline void debug_fence_free(struct i915_sw_fence *fence)
+static inline __maybe_unused void debug_fence_free(struct i915_sw_fence *fence)
 {
 	debug_object_free(fence, &i915_sw_fence_debug_descr);
 	smp_wmb(); /* flush the change in state before reallocation */
@@ -94,7 +94,7 @@
 {
 }
 
-static inline void debug_fence_init_onstack(struct i915_sw_fence *fence)
+static inline __maybe_unused void debug_fence_init_onstack(struct i915_sw_fence *fence)
 {
 }
 
@@ -115,7 +115,7 @@
 {
 }
 
-static inline void debug_fence_free(struct i915_sw_fence *fence)
+static inline __maybe_unused void debug_fence_free(struct i915_sw_fence *fence)
 {
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/i915_utils.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/i915_utils.c
@@ -8,6 +8,7 @@
 #include <drm/drm_drv.h>
 
 #include "i915_drv.h"
+#include "i915_reg.h"
 #include "i915_utils.h"
 
 #define FDO_BUG_MSG "Please file a bug on drm/i915; see " FDO_BUG_URL " for details."
@@ -125,3 +126,19 @@
 	/* Running as a guest, we assume the host is enforcing VT'd */
 	return i915_run_as_guest();
 }
+
+bool i915_direct_stolen_access(struct drm_i915_private *i915)
+{
+	/*
+	 * Wa_22018444074
+	 *
+	 * Access via BAR can hang MTL, go directly to GSM/DSM,
+	 * except for VM guests which won't have access to it.
+	 *
+	 * Normally this would not work but on MTL the system firmware
+	 * should have relaxed the access permissions sufficiently.
+	 * 0x138914==0x1 indicates that the firmware has done its job.
+	 */
+	return IS_METEORLAKE(i915) && !i915_run_as_guest() &&
+		intel_uncore_read(&i915->uncore, MTL_PCODE_STOLEN_ACCESS) == STOLEN_ACCESS_ALLOWED;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/i915_utils.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/i915_utils.h
@@ -391,4 +391,6 @@
 
 bool i915_vtd_active(struct drm_i915_private *i915);
 
+bool i915_direct_stolen_access(struct drm_i915_private *i915);
+
 #endif /* !__I915_UTILS_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/i915_vma.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/i915_vma.c
@@ -34,6 +34,7 @@
 #include "gt/intel_engine.h"
 #include "gt/intel_engine_heartbeat.h"
 #include "gt/intel_gt.h"
+#include "gt/intel_gt_pm.h"
 #include "gt/intel_gt_requests.h"
 #include "gt/intel_tlb.h"
 
@@ -103,12 +104,42 @@
 
 static int __i915_vma_active(struct i915_active *ref)
 {
-	return i915_vma_tryget(active_to_vma(ref)) ? 0 : -ENOENT;
+	struct i915_vma *vma = active_to_vma(ref);
+
+	if (!i915_vma_tryget(vma))
+		return -ENOENT;
+
+	/*
+	 * Exclude global GTT VMA from holding a GT wakeref
+	 * while active, otherwise GPU never goes idle.
+	 */
+	if (!i915_vma_is_ggtt(vma)) {
+		/*
+		 * Since we and our _retire() counterpart can be
+		 * called asynchronously, storing a wakeref tracking
+		 * handle inside struct i915_vma is not safe, and
+		 * there is no other good place for that.  Hence,
+		 * use untracked variants of intel_gt_pm_get/put().
+		 */
+		intel_gt_pm_get_untracked(vma->vm->gt);
+	}
+
+	return 0;
 }
 
 static void __i915_vma_retire(struct i915_active *ref)
 {
-	i915_vma_put(active_to_vma(ref));
+	struct i915_vma *vma = active_to_vma(ref);
+
+	if (!i915_vma_is_ggtt(vma)) {
+		/*
+		 * Since we can be called from atomic contexts,
+		 * use an async variant of intel_gt_pm_put().
+		 */
+		intel_gt_pm_put_async_untracked(vma->vm->gt);
+	}
+
+	i915_vma_put(vma);
 }
 
 static struct i915_vma *
@@ -1404,7 +1435,7 @@
 	struct i915_vma_work *work = NULL;
 	struct dma_fence *moving = NULL;
 	struct i915_vma_resource *vma_res = NULL;
-	intel_wakeref_t wakeref = 0;
+	intel_wakeref_t wakeref;
 	unsigned int bound;
 	int err;
 
@@ -1424,8 +1455,14 @@
 	if (err)
 		return err;
 
-	if (flags & PIN_GLOBAL)
-		wakeref = intel_runtime_pm_get(&vma->vm->i915->runtime_pm);
+	/*
+	 * In case of a global GTT, we must hold a runtime-pm wakeref
+	 * while global PTEs are updated.  In other cases, we hold
+	 * the rpm reference while the VMA is active.  Since runtime
+	 * resume may require allocations, which are forbidden inside
+	 * vm->mutex, get the first rpm wakeref outside of the mutex.
+	 */
+	wakeref = intel_runtime_pm_get(&vma->vm->i915->runtime_pm);
 
 	if (flags & vma->vm->bind_async_flags) {
 		/* lock VM */
@@ -1561,8 +1598,7 @@
 	if (work)
 		dma_fence_work_commit_imm(&work->base);
 err_rpm:
-	if (wakeref)
-		intel_runtime_pm_put(&vma->vm->i915->runtime_pm, wakeref);
+	intel_runtime_pm_put(&vma->vm->i915->runtime_pm, wakeref);
 
 	if (moving)
 		dma_fence_put(moving);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/intel_device_info.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/intel_device_info.c
@@ -126,7 +126,6 @@
 #undef PRINT_FLAG
 
 	drm_printf(p, "has_pooled_eu: %s\n", str_yes_no(runtime->has_pooled_eu));
-	drm_printf(p, "rawclk rate: %u kHz\n", runtime->rawclk_freq);
 }
 
 #undef INTEL_VGA_DEVICE
@@ -372,10 +371,6 @@
 			 "Disabling ppGTT for VT-d support\n");
 		runtime->ppgtt_type = INTEL_PPGTT_NONE;
 	}
-
-	runtime->rawclk_freq = intel_read_rawclk(dev_priv);
-	drm_dbg(&dev_priv->drm, "rawclk rate: %d kHz\n", runtime->rawclk_freq);
-
 }
 
 /*
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/intel_device_info.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/intel_device_info.h
@@ -206,8 +206,6 @@
 
 	u16 device_id;
 
-	u32 rawclk_freq;
-
 	struct intel_step_info step;
 
 	unsigned int page_sizes; /* page sizes supported by the HW */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -246,7 +246,10 @@
 		 * function, since the power state is undefined. This applies
 		 * atm to the late/early system suspend/resume handlers.
 		 */
-		if (pm_runtime_get_if_active(rpm->kdev, ignore_usecount) <= 0)
+		if ((ignore_usecount &&
+		     pm_runtime_get_if_active(rpm->kdev) <= 0) ||
+		    (!ignore_usecount &&
+		     pm_runtime_get_if_in_use(rpm->kdev) <= 0))
 			return 0;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/i915/soc/intel_dram.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/i915/soc/intel_dram.c
@@ -681,6 +681,8 @@
 	if (ret)
 		return;
 
+	drm_dbg_kms(&i915->drm, "Num qgv points %u\n", dram_info->num_qgv_points);
+
 	drm_dbg_kms(&i915->drm, "DRAM channels: %u\n", dram_info->num_channels);
 
 	drm_dbg_kms(&i915->drm, "Watermark level 0 adjustment needed: %s\n",
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/imagination/pvr_ccb.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/imagination/pvr_ccb.c
@@ -321,7 +321,7 @@
 	bool reserved = false;
 	u32 retries = 0;
 
-	while ((jiffies - start_timestamp) < (u32)RESERVE_SLOT_TIMEOUT ||
+	while (time_before(jiffies, start_timestamp + RESERVE_SLOT_TIMEOUT) ||
 	       retries < RESERVE_SLOT_MIN_RETRIES) {
 		reserved = pvr_kccb_try_reserve_slot(pvr_dev);
 		if (reserved)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/imagination/pvr_context.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/imagination/pvr_context.c
@@ -17,10 +17,14 @@
 
 #include <drm/drm_auth.h>
 #include <drm/drm_managed.h>
+
+#include <linux/bug.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/list.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/xarray.h>
@@ -354,6 +358,10 @@
 		return err;
 	}
 
+	spin_lock(&pvr_dev->ctx_list_lock);
+	list_add_tail(&ctx->file_link, &pvr_file->contexts);
+	spin_unlock(&pvr_dev->ctx_list_lock);
+
 	return 0;
 
 err_destroy_fw_obj:
@@ -380,6 +388,11 @@
 		container_of(ref_count, struct pvr_context, ref_count);
 	struct pvr_device *pvr_dev = ctx->pvr_dev;
 
+	WARN_ON(in_interrupt());
+	spin_lock(&pvr_dev->ctx_list_lock);
+	list_del(&ctx->file_link);
+	spin_unlock(&pvr_dev->ctx_list_lock);
+
 	xa_erase(&pvr_dev->ctx_ids, ctx->ctx_id);
 	pvr_context_destroy_queues(ctx);
 	pvr_fw_object_destroy(ctx->fw_obj);
@@ -437,11 +450,30 @@
  */
 void pvr_destroy_contexts_for_file(struct pvr_file *pvr_file)
 {
+	struct pvr_device *pvr_dev = pvr_file->pvr_dev;
 	struct pvr_context *ctx;
 	unsigned long handle;
 
 	xa_for_each(&pvr_file->ctx_handles, handle, ctx)
 		pvr_context_destroy(pvr_file, handle);
+
+	spin_lock(&pvr_dev->ctx_list_lock);
+	ctx = list_first_entry(&pvr_file->contexts, struct pvr_context, file_link);
+
+	while (!list_entry_is_head(ctx, &pvr_file->contexts, file_link)) {
+		list_del_init(&ctx->file_link);
+
+		if (pvr_context_get_if_referenced(ctx)) {
+			spin_unlock(&pvr_dev->ctx_list_lock);
+
+			pvr_vm_unmap_all(ctx->vm_ctx);
+
+			pvr_context_put(ctx);
+			spin_lock(&pvr_dev->ctx_list_lock);
+		}
+		ctx = list_first_entry(&pvr_file->contexts, struct pvr_context, file_link);
+	}
+	spin_unlock(&pvr_dev->ctx_list_lock);
 }
 
 /**
@@ -451,6 +483,7 @@
 void pvr_context_device_init(struct pvr_device *pvr_dev)
 {
 	xa_init_flags(&pvr_dev->ctx_ids, XA_FLAGS_ALLOC1);
+	spin_lock_init(&pvr_dev->ctx_list_lock);
 }
 
 /**
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/imagination/pvr_context.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/imagination/pvr_context.h
@@ -85,6 +85,9 @@
 		/** @compute: Transfer queue. */
 		struct pvr_queue *transfer;
 	} queues;
+
+	/** @file_link: pvr_file PVR context list link. */
+	struct list_head file_link;
 };
 
 static __always_inline struct pvr_queue *
@@ -124,6 +127,24 @@
 }
 
 /**
+ * pvr_context_get_if_referenced() - Take an additional reference on a still
+ * referenced context.
+ * @ctx: Context pointer.
+ *
+ * Call pvr_context_put() to release.
+ *
+ * Returns:
+ *  * True on success, or
+ *  * false if no context pointer passed, or the context wasn't still
+ *  * referenced.
+ */
+static __always_inline bool
+pvr_context_get_if_referenced(struct pvr_context *ctx)
+{
+	return ctx != NULL && kref_get_unless_zero(&ctx->ref_count) != 0;
+}
+
+/**
  * pvr_context_lookup() - Lookup context pointer from handle and file.
  * @pvr_file: Pointer to pvr_file structure.
  * @handle: Context handle.
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/imagination/pvr_device.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/imagination/pvr_device.h
@@ -23,6 +23,7 @@
 #include <linux/kernel.h>
 #include <linux/math.h>
 #include <linux/mutex.h>
+#include <linux/spinlock_types.h>
 #include <linux/timer.h>
 #include <linux/types.h>
 #include <linux/wait.h>
@@ -293,6 +294,12 @@
 
 	/** @sched_wq: Workqueue for schedulers. */
 	struct workqueue_struct *sched_wq;
+
+	/**
+	 * @ctx_list_lock: Lock to be held when accessing the context list in
+	 *  struct pvr_file.
+	 */
+	spinlock_t ctx_list_lock;
 };
 
 /**
@@ -344,6 +351,9 @@
 	 * This array is used to allocate handles returned to userspace.
 	 */
 	struct xarray vm_ctx_handles;
+
+	/** @contexts: PVR context list. */
+	struct list_head contexts;
 };
 
 /**
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/imagination/pvr_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/imagination/pvr_drv.c
@@ -28,6 +28,7 @@
 #include <linux/export.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
+#include <linux/list.h>
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -1326,6 +1327,8 @@
 	 */
 	pvr_file->pvr_dev = pvr_dev;
 
+	INIT_LIST_HEAD(&pvr_file->contexts);
+
 	xa_init_flags(&pvr_file->ctx_handles, XA_FLAGS_ALLOC1);
 	xa_init_flags(&pvr_file->free_list_handles, XA_FLAGS_ALLOC1);
 	xa_init_flags(&pvr_file->hwrt_handles, XA_FLAGS_ALLOC1);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/imagination/pvr_fw_mips.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/imagination/pvr_fw_mips.h
@@ -7,13 +7,14 @@
 #include "pvr_rogue_mips.h"
 
 #include <asm/page.h>
+#include <linux/math.h>
 #include <linux/types.h>
 
 /* Forward declaration from pvr_gem.h. */
 struct pvr_gem_object;
 
-#define PVR_MIPS_PT_PAGE_COUNT ((ROGUE_MIPSFW_MAX_NUM_PAGETABLE_PAGES * ROGUE_MIPSFW_PAGE_SIZE_4K) \
-				>> PAGE_SHIFT)
+#define PVR_MIPS_PT_PAGE_COUNT DIV_ROUND_UP(ROGUE_MIPSFW_MAX_NUM_PAGETABLE_PAGES * ROGUE_MIPSFW_PAGE_SIZE_4K, PAGE_SIZE)
+
 /**
  * struct pvr_fw_mips_data - MIPS-specific data
  */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/imagination/pvr_vm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/imagination/pvr_vm.c
@@ -14,6 +14,7 @@
 #include <drm/drm_gem.h>
 #include <drm/drm_gpuvm.h>
 
+#include <linux/bug.h>
 #include <linux/container_of.h>
 #include <linux/err.h>
 #include <linux/errno.h>
@@ -114,6 +115,8 @@
 	struct drm_gpuva base;
 };
 
+#define to_pvr_vm_gpuva(va) container_of_const(va, struct pvr_vm_gpuva, base)
+
 enum pvr_vm_bind_type {
 	PVR_VM_BIND_TYPE_MAP,
 	PVR_VM_BIND_TYPE_UNMAP,
@@ -386,6 +389,7 @@
 
 	drm_gpuva_unmap(&op->unmap);
 	drm_gpuva_unlink(op->unmap.va);
+	kfree(to_pvr_vm_gpuva(op->unmap.va));
 
 	return 0;
 }
@@ -433,6 +437,7 @@
 	}
 
 	drm_gpuva_unlink(op->remap.unmap->va);
+	kfree(to_pvr_vm_gpuva(op->remap.unmap->va));
 
 	return 0;
 }
@@ -593,12 +598,26 @@
 }
 
 /**
- * pvr_vm_context_release() - Teardown a VM context.
- * @ref_count: Pointer to reference counter of the VM context.
+ * pvr_vm_unmap_all() - Unmap all mappings associated with a VM context.
+ * @vm_ctx: Target VM context.
  *
  * This function ensures that no mappings are left dangling by unmapping them
  * all in order of ascending device-virtual address.
  */
+void
+pvr_vm_unmap_all(struct pvr_vm_context *vm_ctx)
+{
+	WARN_ON(pvr_vm_unmap(vm_ctx, vm_ctx->gpuvm_mgr.mm_start,
+			     vm_ctx->gpuvm_mgr.mm_range));
+}
+
+/**
+ * pvr_vm_context_release() - Teardown a VM context.
+ * @ref_count: Pointer to reference counter of the VM context.
+ *
+ * This function also ensures that no mappings are left dangling by calling
+ * pvr_vm_unmap_all.
+ */
 static void
 pvr_vm_context_release(struct kref *ref_count)
 {
@@ -608,8 +627,7 @@
 	if (vm_ctx->fw_mem_ctx_obj)
 		pvr_fw_object_destroy(vm_ctx->fw_mem_ctx_obj);
 
-	WARN_ON(pvr_vm_unmap(vm_ctx, vm_ctx->gpuvm_mgr.mm_start,
-			     vm_ctx->gpuvm_mgr.mm_range));
+	pvr_vm_unmap_all(vm_ctx);
 
 	pvr_mmu_context_destroy(vm_ctx->mmu_ctx);
 	drm_gem_private_object_fini(&vm_ctx->dummy_gem);
@@ -636,9 +654,7 @@
 
 	xa_lock(&pvr_file->vm_ctx_handles);
 	vm_ctx = xa_load(&pvr_file->vm_ctx_handles, handle);
-	if (vm_ctx)
-		kref_get(&vm_ctx->ref_count);
-
+	pvr_vm_context_get(vm_ctx);
 	xa_unlock(&pvr_file->vm_ctx_handles);
 
 	return vm_ctx;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/imagination/pvr_vm.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/imagination/pvr_vm.h
@@ -39,6 +39,7 @@
 	       struct pvr_gem_object *pvr_obj, u64 pvr_obj_offset,
 	       u64 device_addr, u64 size);
 int pvr_vm_unmap(struct pvr_vm_context *vm_ctx, u64 device_addr, u64 size);
+void pvr_vm_unmap_all(struct pvr_vm_context *vm_ctx);
 
 dma_addr_t pvr_vm_get_page_table_root_addr(struct pvr_vm_context *vm_ctx);
 struct dma_resv *pvr_vm_get_dma_resv(struct pvr_vm_context *vm_ctx);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/imagination/pvr_vm_mips.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/imagination/pvr_vm_mips.c
@@ -46,7 +46,7 @@
 	if (!mips_data)
 		return -ENOMEM;
 
-	for (page_nr = 0; page_nr < ARRAY_SIZE(mips_data->pt_pages); page_nr++) {
+	for (page_nr = 0; page_nr < PVR_MIPS_PT_PAGE_COUNT; page_nr++) {
 		mips_data->pt_pages[page_nr] = alloc_page(GFP_KERNEL | __GFP_ZERO);
 		if (!mips_data->pt_pages[page_nr]) {
 			err = -ENOMEM;
@@ -102,7 +102,7 @@
 	int page_nr;
 
 	vunmap(mips_data->pt);
-	for (page_nr = ARRAY_SIZE(mips_data->pt_pages) - 1; page_nr >= 0; page_nr--) {
+	for (page_nr = PVR_MIPS_PT_PAGE_COUNT - 1; page_nr >= 0; page_nr--) {
 		dma_unmap_page(from_pvr_device(pvr_dev)->dev,
 			       mips_data->pt_dma_addr[page_nr], PAGE_SIZE, DMA_TO_DEVICE);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/imx/dcss/dcss-crtc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/imx/dcss/dcss-crtc.c
@@ -206,15 +206,13 @@
 	if (crtc->irq < 0)
 		return crtc->irq;
 
-	ret = request_irq(crtc->irq, dcss_crtc_irq_handler,
-			  0, "dcss_drm", crtc);
+	ret = request_irq(crtc->irq, dcss_crtc_irq_handler, IRQF_NO_AUTOEN,
+			  "dcss_drm", crtc);
 	if (ret) {
 		dev_err(dcss->dev, "irq request failed with %d.\n", ret);
 		return ret;
 	}
 
-	disable_irq(crtc->irq);
-
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c
@@ -410,14 +410,12 @@
 	}
 
 	ipu_crtc->irq = ipu_plane_irq(ipu_crtc->plane[0]);
-	ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0,
-			"imx_drm", ipu_crtc);
+	ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler,
+			       IRQF_NO_AUTOEN, "imx_drm", ipu_crtc);
 	if (ret < 0) {
 		dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret);
 		return ret;
 	}
-	/* Only enable IRQ when we actually need it to trigger work. */
-	disable_irq(ipu_crtc->irq);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/imx/ipuv3/parallel-display.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/imx/ipuv3/parallel-display.c
@@ -72,14 +72,14 @@
 		int ret;
 
 		if (!mode)
-			return -EINVAL;
+			return 0;
 
 		ret = of_get_drm_display_mode(np, &imxpd->mode,
 					      &imxpd->bus_flags,
 					      OF_USE_NATIVE_MODE);
 		if (ret) {
 			drm_mode_destroy(connector->dev, mode);
-			return ret;
+			return 0;
 		}
 
 		drm_mode_copy(mode, &imxpd->mode);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/lima/lima_bcast.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/lima/lima_bcast.c
@@ -43,6 +43,18 @@
 
 }
 
+int lima_bcast_mask_irq(struct lima_ip *ip)
+{
+	bcast_write(LIMA_BCAST_BROADCAST_MASK, 0);
+	bcast_write(LIMA_BCAST_INTERRUPT_MASK, 0);
+	return 0;
+}
+
+int lima_bcast_reset(struct lima_ip *ip)
+{
+	return lima_bcast_hw_init(ip);
+}
+
 int lima_bcast_init(struct lima_ip *ip)
 {
 	int i;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/lima/lima_bcast.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/lima/lima_bcast.h
@@ -13,4 +13,7 @@
 
 void lima_bcast_enable(struct lima_device *dev, int num_pp);
 
+int lima_bcast_mask_irq(struct lima_ip *ip);
+int lima_bcast_reset(struct lima_ip *ip);
+
 #endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/lima/lima_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/lima/lima_drv.c
@@ -486,3 +486,4 @@
 MODULE_AUTHOR("Lima Project Developers");
 MODULE_DESCRIPTION("Lima DRM Driver");
 MODULE_LICENSE("GPL v2");
+MODULE_SOFTDEP("pre: governor_simpleondemand");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/lima/lima_gem.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/lima/lima_gem.c
@@ -75,29 +75,34 @@
 	} else {
 		bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL);
 		if (!bo->base.sgt) {
-			sg_free_table(&sgt);
-			return -ENOMEM;
+			ret = -ENOMEM;
+			goto err_out0;
 		}
 	}
 
 	ret = dma_map_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0);
-	if (ret) {
-		sg_free_table(&sgt);
-		kfree(bo->base.sgt);
-		bo->base.sgt = NULL;
-		return ret;
-	}
+	if (ret)
+		goto err_out1;
 
 	*bo->base.sgt = sgt;
 
 	if (vm) {
 		ret = lima_vm_map_bo(vm, bo, old_size >> PAGE_SHIFT);
 		if (ret)
-			return ret;
+			goto err_out2;
 	}
 
 	bo->heap_size = new_size;
 	return 0;
+
+err_out2:
+	dma_unmap_sgtable(dev, &sgt, DMA_BIDIRECTIONAL, 0);
+err_out1:
+	kfree(bo->base.sgt);
+	bo->base.sgt = NULL;
+err_out0:
+	sg_free_table(&sgt);
+	return ret;
 }
 
 int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/lima/lima_gp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/lima/lima_gp.c
@@ -166,6 +166,11 @@
 	gp_write(LIMA_GP_CMD, cmd);
 }
 
+static int lima_gp_bus_stop_poll(struct lima_ip *ip)
+{
+	return !!(gp_read(LIMA_GP_STATUS) & LIMA_GP_STATUS_BUS_STOPPED);
+}
+
 static int lima_gp_hard_reset_poll(struct lima_ip *ip)
 {
 	gp_write(LIMA_GP_PERF_CNT_0_LIMIT, 0xC01A0000);
@@ -179,6 +184,13 @@
 
 	gp_write(LIMA_GP_PERF_CNT_0_LIMIT, 0xC0FFE000);
 	gp_write(LIMA_GP_INT_MASK, 0);
+
+	gp_write(LIMA_GP_CMD, LIMA_GP_CMD_STOP_BUS);
+	ret = lima_poll_timeout(ip, lima_gp_bus_stop_poll, 10, 100);
+	if (ret) {
+		dev_err(dev->dev, "%s bus stop timeout\n", lima_ip_name(ip));
+		return ret;
+	}
 	gp_write(LIMA_GP_CMD, LIMA_GP_CMD_RESET);
 	ret = lima_poll_timeout(ip, lima_gp_hard_reset_poll, 10, 100);
 	if (ret) {
@@ -212,6 +224,13 @@
 	lima_sched_pipe_task_done(pipe);
 }
 
+static void lima_gp_task_mask_irq(struct lima_sched_pipe *pipe)
+{
+	struct lima_ip *ip = pipe->processor[0];
+
+	gp_write(LIMA_GP_INT_MASK, 0);
+}
+
 static int lima_gp_task_recover(struct lima_sched_pipe *pipe)
 {
 	struct lima_ip *ip = pipe->processor[0];
@@ -317,7 +336,9 @@
 
 void lima_gp_fini(struct lima_ip *ip)
 {
+	struct lima_device *dev = ip->dev;
 
+	devm_free_irq(dev->dev, ip->irq, ip);
 }
 
 int lima_gp_pipe_init(struct lima_device *dev)
@@ -344,6 +365,7 @@
 	pipe->task_error = lima_gp_task_error;
 	pipe->task_mmu_error = lima_gp_task_mmu_error;
 	pipe->task_recover = lima_gp_task_recover;
+	pipe->task_mask_irq = lima_gp_task_mask_irq;
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/lima/lima_mmu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/lima/lima_mmu.c
@@ -118,7 +118,12 @@
 
 void lima_mmu_fini(struct lima_ip *ip)
 {
+	struct lima_device *dev = ip->dev;
 
+	if (ip->id == lima_ip_ppmmu_bcast)
+		return;
+
+	devm_free_irq(dev->dev, ip->irq, ip);
 }
 
 void lima_mmu_flush_tlb(struct lima_ip *ip)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/lima/lima_pp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/lima/lima_pp.c
@@ -266,7 +266,9 @@
 
 void lima_pp_fini(struct lima_ip *ip)
 {
+	struct lima_device *dev = ip->dev;
 
+	devm_free_irq(dev->dev, ip->irq, ip);
 }
 
 int lima_pp_bcast_resume(struct lima_ip *ip)
@@ -299,7 +301,9 @@
 
 void lima_pp_bcast_fini(struct lima_ip *ip)
 {
+	struct lima_device *dev = ip->dev;
 
+	devm_free_irq(dev->dev, ip->irq, ip);
 }
 
 static int lima_pp_task_validate(struct lima_sched_pipe *pipe,
@@ -408,6 +412,9 @@
 
 		lima_pp_hard_reset(ip);
 	}
+
+	if (pipe->bcast_processor)
+		lima_bcast_reset(pipe->bcast_processor);
 }
 
 static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe)
@@ -416,6 +423,20 @@
 		lima_sched_pipe_task_done(pipe);
 }
 
+static void lima_pp_task_mask_irq(struct lima_sched_pipe *pipe)
+{
+	int i;
+
+	for (i = 0; i < pipe->num_processor; i++) {
+		struct lima_ip *ip = pipe->processor[i];
+
+		pp_write(LIMA_PP_INT_MASK, 0);
+	}
+
+	if (pipe->bcast_processor)
+		lima_bcast_mask_irq(pipe->bcast_processor);
+}
+
 static struct kmem_cache *lima_pp_task_slab;
 static int lima_pp_task_slab_refcnt;
 
@@ -447,6 +468,7 @@
 	pipe->task_fini = lima_pp_task_fini;
 	pipe->task_error = lima_pp_task_error;
 	pipe->task_mmu_error = lima_pp_task_mmu_error;
+	pipe->task_mask_irq = lima_pp_task_mask_irq;
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/lima/lima_sched.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/lima/lima_sched.c
@@ -402,6 +402,13 @@
 	struct lima_sched_task *task = to_lima_task(job);
 	struct lima_device *ldev = pipe->ldev;
 
+	/*
+	 * The task might still finish while this timeout handler runs.
+	 * To prevent a race condition on its completion, mask all irqs
+	 * on the running core until the next hard reset completes.
+	 */
+	pipe->task_mask_irq(pipe);
+
 	if (!pipe->error)
 		DRM_ERROR("lima job timeout\n");
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/lima/lima_sched.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/lima/lima_sched.h
@@ -80,6 +80,7 @@
 	void (*task_error)(struct lima_sched_pipe *pipe);
 	void (*task_mmu_error)(struct lima_sched_pipe *pipe);
 	int (*task_recover)(struct lima_sched_pipe *pipe);
+	void (*task_mask_irq)(struct lima_sched_pipe *pipe);
 
 	struct work_struct recover_work;
 };
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mcde/mcde_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/mcde/mcde_drv.c
@@ -473,6 +473,7 @@
 	},
 	{},
 };
+MODULE_DEVICE_TABLE(of, mcde_of_match);
 
 static struct platform_driver mcde_driver = {
 	.driver = {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mediatek/Kconfig
+++ linux-qcom-6.8.0/drivers/gpu/drm/mediatek/Kconfig
@@ -10,9 +10,6 @@
 	select DRM_KMS_HELPER
 	select DRM_MIPI_DSI
 	select DRM_PANEL
-	select MEMORY
-	select MTK_SMI
-	select PHY_MTK_MIPI_DSI
 	select VIDEOMODE_HELPERS
 	help
 	  Choose this option if you have a Mediatek SoCs.
@@ -23,7 +20,6 @@
 config DRM_MEDIATEK_DP
 	tristate "DRM DPTX Support for MediaTek SoCs"
 	depends on DRM_MEDIATEK
-	select PHY_MTK_DP
 	select DRM_DISPLAY_HELPER
 	select DRM_DISPLAY_DP_HELPER
 	select DRM_DP_AUX_BUS
@@ -34,6 +30,5 @@
 	tristate "DRM HDMI Support for Mediatek SoCs"
 	depends on DRM_MEDIATEK
 	select SND_SOC_HDMI_CODEC if SND_SOC
-	select PHY_MTK_HDMI
 	help
 	  DRM/KMS HDMI driver for Mediatek SoCs
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
@@ -38,6 +38,7 @@
 #define DISP_REG_OVL_PITCH_MSB(n)		(0x0040 + 0x20 * (n))
 #define OVL_PITCH_MSB_2ND_SUBBUF			BIT(16)
 #define DISP_REG_OVL_PITCH(n)			(0x0044 + 0x20 * (n))
+#define OVL_CONST_BLEND					BIT(28)
 #define DISP_REG_OVL_RDMA_CTRL(n)		(0x00c0 + 0x20 * (n))
 #define DISP_REG_OVL_RDMA_GMC(n)		(0x00c8 + 0x20 * (n))
 #define DISP_REG_OVL_ADDR_MT2701		0x0040
@@ -71,6 +72,8 @@
 #define	OVL_CON_VIRT_FLIP	BIT(9)
 #define	OVL_CON_HORZ_FLIP	BIT(10)
 
+#define OVL_COLOR_ALPHA		GENMASK(31, 24)
+
 static const u32 mt8173_formats[] = {
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
@@ -273,7 +276,13 @@
 	if (w != 0 && h != 0)
 		mtk_ddp_write_relaxed(cmdq_pkt, h << 16 | w, &ovl->cmdq_reg, ovl->regs,
 				      DISP_REG_OVL_ROI_SIZE);
-	mtk_ddp_write_relaxed(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_ROI_BGCLR);
+
+	/*
+	 * The background color must be opaque black (ARGB),
+	 * otherwise the alpha blending will have no effect
+	 */
+	mtk_ddp_write_relaxed(cmdq_pkt, OVL_COLOR_ALPHA, &ovl->cmdq_reg,
+			      ovl->regs, DISP_REG_OVL_ROI_BGCLR);
 
 	mtk_ddp_write(cmdq_pkt, 0x1, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST);
 	mtk_ddp_write(cmdq_pkt, 0x0, &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_RST);
@@ -358,11 +367,6 @@
 
 static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
 {
-	/* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX"
-	 * is defined in mediatek HW data sheet.
-	 * The alphabet order in XXX is no relation to data
-	 * arrangement in memory.
-	 */
 	switch (fmt) {
 	default:
 	case DRM_FORMAT_RGB565:
@@ -394,6 +398,29 @@
 	}
 }
 
+static void mtk_ovl_afbc_layer_config(struct mtk_disp_ovl *ovl,
+				      unsigned int idx,
+				      struct mtk_plane_pending_state *pending,
+				      struct cmdq_pkt *cmdq_pkt)
+{
+	unsigned int pitch_msb = pending->pitch >> 16;
+	unsigned int hdr_pitch = pending->hdr_pitch;
+	unsigned int hdr_addr = pending->hdr_addr;
+
+	if (pending->modifier != DRM_FORMAT_MOD_LINEAR) {
+		mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,
+				      DISP_REG_OVL_HDR_ADDR(ovl, idx));
+		mtk_ddp_write_relaxed(cmdq_pkt,
+				      OVL_PITCH_MSB_2ND_SUBBUF | pitch_msb,
+				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
+		mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
+				      DISP_REG_OVL_HDR_PITCH(ovl, idx));
+	} else {
+		mtk_ddp_write_relaxed(cmdq_pkt, pitch_msb,
+				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
+	}
+}
+
 void mtk_ovl_layer_config(struct device *dev, unsigned int idx,
 			  struct mtk_plane_state *state,
 			  struct cmdq_pkt *cmdq_pkt)
@@ -401,23 +428,13 @@
 	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
 	struct mtk_plane_pending_state *pending = &state->pending;
 	unsigned int addr = pending->addr;
-	unsigned int hdr_addr = pending->hdr_addr;
-	unsigned int pitch = pending->pitch;
-	unsigned int hdr_pitch = pending->hdr_pitch;
+	unsigned int pitch_lsb = pending->pitch & GENMASK(15, 0);
 	unsigned int fmt = pending->format;
+	unsigned int rotation = pending->rotation;
 	unsigned int offset = (pending->y << 16) | pending->x;
 	unsigned int src_size = (pending->height << 16) | pending->width;
+	unsigned int ignore_pixel_alpha = 0;
 	unsigned int con;
-	bool is_afbc = pending->modifier != DRM_FORMAT_MOD_LINEAR;
-	union overlay_pitch {
-		struct split_pitch {
-			u16 lsb;
-			u16 msb;
-		} split_pitch;
-		u32 pitch;
-	} overlay_pitch;
-
-	overlay_pitch.pitch = pitch;
 
 	if (!pending->enable) {
 		mtk_ovl_layer_off(dev, idx, cmdq_pkt);
@@ -428,23 +445,39 @@
 	if (state->base.fb && state->base.fb->format->has_alpha)
 		con |= OVL_CON_AEN | OVL_CON_ALPHA;
 
-	if (pending->rotation & DRM_MODE_REFLECT_Y) {
+	/* CONST_BLD must be enabled for XRGB formats although the alpha channel
+	 * can be ignored, or OVL will still read the value from memory.
+	 * For RGB888 related formats, whether CONST_BLD is enabled or not won't
+	 * affect the result. Therefore we use !has_alpha as the condition.
+	 */
+	if (state->base.fb && !state->base.fb->format->has_alpha)
+		ignore_pixel_alpha = OVL_CONST_BLEND;
+
+	/*
+	 * Treat rotate 180 as flip x + flip y, and XOR the original rotation value
+	 * to flip x + flip y to support both in the same time.
+	 */
+	if (rotation & DRM_MODE_ROTATE_180)
+		rotation ^= DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y;
+
+	if (rotation & DRM_MODE_REFLECT_Y) {
 		con |= OVL_CON_VIRT_FLIP;
 		addr += (pending->height - 1) * pending->pitch;
 	}
 
-	if (pending->rotation & DRM_MODE_REFLECT_X) {
+	if (rotation & DRM_MODE_REFLECT_X) {
 		con |= OVL_CON_HORZ_FLIP;
 		addr += pending->pitch - 1;
 	}
 
 	if (ovl->data->supports_afbc)
-		mtk_ovl_set_afbc(ovl, cmdq_pkt, idx, is_afbc);
+		mtk_ovl_set_afbc(ovl, cmdq_pkt, idx,
+				 pending->modifier != DRM_FORMAT_MOD_LINEAR);
 
 	mtk_ddp_write_relaxed(cmdq_pkt, con, &ovl->cmdq_reg, ovl->regs,
 			      DISP_REG_OVL_CON(idx));
-	mtk_ddp_write_relaxed(cmdq_pkt, overlay_pitch.split_pitch.lsb, &ovl->cmdq_reg, ovl->regs,
-			      DISP_REG_OVL_PITCH(idx));
+	mtk_ddp_write_relaxed(cmdq_pkt, pitch_lsb | ignore_pixel_alpha,
+			      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH(idx));
 	mtk_ddp_write_relaxed(cmdq_pkt, src_size, &ovl->cmdq_reg, ovl->regs,
 			      DISP_REG_OVL_SRC_SIZE(idx));
 	mtk_ddp_write_relaxed(cmdq_pkt, offset, &ovl->cmdq_reg, ovl->regs,
@@ -452,19 +485,8 @@
 	mtk_ddp_write_relaxed(cmdq_pkt, addr, &ovl->cmdq_reg, ovl->regs,
 			      DISP_REG_OVL_ADDR(ovl, idx));
 
-	if (is_afbc) {
-		mtk_ddp_write_relaxed(cmdq_pkt, hdr_addr, &ovl->cmdq_reg, ovl->regs,
-				      DISP_REG_OVL_HDR_ADDR(ovl, idx));
-		mtk_ddp_write_relaxed(cmdq_pkt,
-				      OVL_PITCH_MSB_2ND_SUBBUF | overlay_pitch.split_pitch.msb,
-				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
-		mtk_ddp_write_relaxed(cmdq_pkt, hdr_pitch, &ovl->cmdq_reg, ovl->regs,
-				      DISP_REG_OVL_HDR_PITCH(ovl, idx));
-	} else {
-		mtk_ddp_write_relaxed(cmdq_pkt,
-				      overlay_pitch.split_pitch.msb,
-				      &ovl->cmdq_reg, ovl->regs, DISP_REG_OVL_PITCH_MSB(idx));
-	}
+	if (ovl->data->supports_afbc)
+		mtk_ovl_afbc_layer_config(ovl, idx, pending, cmdq_pkt);
 
 	mtk_ovl_set_bit_depth(dev, idx, fmt, cmdq_pkt);
 	mtk_ovl_layer_on(dev, idx, cmdq_pkt);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/mediatek/mtk_disp_ovl_adaptor.c
@@ -132,7 +132,7 @@
 	merge = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_MERGE0 + idx];
 	ethdr = ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0];
 
-	if (!pending->enable) {
+	if (!pending->enable || !pending->width || !pending->height) {
 		mtk_merge_stop_cmdq(merge, cmdq_pkt);
 		mtk_mdp_rdma_stop(rdma_l, cmdq_pkt);
 		mtk_mdp_rdma_stop(rdma_r, cmdq_pkt);
@@ -480,8 +480,10 @@
 		}
 
 		comp_pdev = of_find_device_by_node(node);
-		if (!comp_pdev)
+		if (!comp_pdev) {
+			of_node_put(node);
 			return -EPROBE_DEFER;
+		}
 
 		priv->ovl_adaptor_comp[id] = &comp_pdev->dev;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_dp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/mediatek/mtk_dp.c
@@ -145,6 +145,89 @@
 	u16 audio_m_div2_bit;
 };
 
+static const struct mtk_dp_efuse_fmt mt8188_dp_efuse_fmt[MTK_DP_CAL_MAX] = {
+	[MTK_DP_CAL_GLB_BIAS_TRIM] = {
+		.idx = 0,
+		.shift = 10,
+		.mask = 0x1f,
+		.min_val = 1,
+		.max_val = 0x1e,
+		.default_val = 0xf,
+	},
+	[MTK_DP_CAL_CLKTX_IMPSE] = {
+		.idx = 0,
+		.shift = 15,
+		.mask = 0xf,
+		.min_val = 1,
+		.max_val = 0xe,
+		.default_val = 0x8,
+	},
+	[MTK_DP_CAL_LN_TX_IMPSEL_PMOS_0] = {
+		.idx = 1,
+		.shift = 0,
+		.mask = 0xf,
+		.min_val = 1,
+		.max_val = 0xe,
+		.default_val = 0x8,
+	},
+	[MTK_DP_CAL_LN_TX_IMPSEL_PMOS_1] = {
+		.idx = 1,
+		.shift = 8,
+		.mask = 0xf,
+		.min_val = 1,
+		.max_val = 0xe,
+		.default_val = 0x8,
+	},
+	[MTK_DP_CAL_LN_TX_IMPSEL_PMOS_2] = {
+		.idx = 1,
+		.shift = 16,
+		.mask = 0xf,
+		.min_val = 1,
+		.max_val = 0xe,
+		.default_val = 0x8,
+	},
+	[MTK_DP_CAL_LN_TX_IMPSEL_PMOS_3] = {
+		.idx = 1,
+		.shift = 24,
+		.mask = 0xf,
+		.min_val = 1,
+		.max_val = 0xe,
+		.default_val = 0x8,
+	},
+	[MTK_DP_CAL_LN_TX_IMPSEL_NMOS_0] = {
+		.idx = 1,
+		.shift = 4,
+		.mask = 0xf,
+		.min_val = 1,
+		.max_val = 0xe,
+		.default_val = 0x8,
+	},
+	[MTK_DP_CAL_LN_TX_IMPSEL_NMOS_1] = {
+		.idx = 1,
+		.shift = 12,
+		.mask = 0xf,
+		.min_val = 1,
+		.max_val = 0xe,
+		.default_val = 0x8,
+	},
+	[MTK_DP_CAL_LN_TX_IMPSEL_NMOS_2] = {
+		.idx = 1,
+		.shift = 20,
+		.mask = 0xf,
+		.min_val = 1,
+		.max_val = 0xe,
+		.default_val = 0x8,
+	},
+	[MTK_DP_CAL_LN_TX_IMPSEL_NMOS_3] = {
+		.idx = 1,
+		.shift = 28,
+		.mask = 0xf,
+		.min_val = 1,
+		.max_val = 0xe,
+		.default_val = 0x8,
+	},
+};
+
 static const struct mtk_dp_efuse_fmt mt8195_edp_efuse_fmt[MTK_DP_CAL_MAX] = {
 	[MTK_DP_CAL_GLB_BIAS_TRIM] = {
 		.idx = 3,
@@ -460,18 +543,16 @@
 				   enum dp_pixelformat color_format)
 {
 	u32 val;
-
-	/* update MISC0 */
-	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
-			   color_format << DP_TEST_COLOR_FORMAT_SHIFT,
-			   DP_TEST_COLOR_FORMAT_MASK);
+	u32 misc0_color;
 
 	switch (color_format) {
 	case DP_PIXELFORMAT_YUV422:
 		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_YCBCR422;
+		misc0_color = DP_COLOR_FORMAT_YCbCr422;
 		break;
 	case DP_PIXELFORMAT_RGB:
 		val = PIXEL_ENCODE_FORMAT_DP_ENC0_P0_RGB;
+		misc0_color = DP_COLOR_FORMAT_RGB;
 		break;
 	default:
 		drm_warn(mtk_dp->drm_dev, "Unsupported color format: %d\n",
@@ -479,6 +560,11 @@
 		return -EINVAL;
 	}
 
+	/* update MISC0 */
+	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_3034,
+			   misc0_color,
+			   DP_TEST_COLOR_FORMAT_MASK);
+
 	mtk_dp_update_bits(mtk_dp, MTK_DP_ENC0_P0_303C,
 			   val, PIXEL_ENCODE_FORMAT_DP_ENC0_P0_MASK);
 	return 0;
@@ -2017,7 +2103,6 @@
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
 	enum drm_connector_status ret = connector_status_disconnected;
 	bool enabled = mtk_dp->enabled;
-	u8 sink_count = 0;
 
 	if (!mtk_dp->train_info.cable_plugged_in)
 		return ret;
@@ -2032,8 +2117,8 @@
 	 * function, we just need to check the HPD connection to check
 	 * whether we connect to a sink device.
 	 */
-	drm_dp_dpcd_readb(&mtk_dp->aux, DP_SINK_COUNT, &sink_count);
-	if (DP_GET_SINK_COUNT(sink_count))
+
+	if (drm_dp_read_sink_count(&mtk_dp->aux) > 0)
 		ret = connector_status_connected;
 
 	if (!enabled)
@@ -2042,12 +2127,12 @@
 	return ret;
 }
 
-static struct edid *mtk_dp_get_edid(struct drm_bridge *bridge,
-				    struct drm_connector *connector)
+static const struct drm_edid *mtk_dp_edid_read(struct drm_bridge *bridge,
+					       struct drm_connector *connector)
 {
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
 	bool enabled = mtk_dp->enabled;
-	struct edid *new_edid = NULL;
+	const struct drm_edid *drm_edid;
 	struct mtk_dp_audio_cfg *audio_caps = &mtk_dp->info.audio_cur_cfg;
 
 	if (!enabled) {
@@ -2055,7 +2140,7 @@
 		mtk_dp_aux_panel_poweron(mtk_dp, true);
 	}
 
-	new_edid = drm_get_edid(connector, &mtk_dp->aux.ddc);
+	drm_edid = drm_edid_read_ddc(connector, &mtk_dp->aux.ddc);
 
 	/*
 	 * Parse capability here to let atomic_get_input_bus_fmts and
@@ -2063,17 +2148,32 @@
 	 */
 	if (mtk_dp_parse_capabilities(mtk_dp)) {
 		drm_err(mtk_dp->drm_dev, "Can't parse capabilities\n");
-		kfree(new_edid);
-		new_edid = NULL;
+		drm_edid_free(drm_edid);
+		drm_edid = NULL;
 	}
 
-	if (new_edid) {
+	if (drm_edid) {
+		/*
+		 * FIXME: get rid of drm_edid_raw()
+		 */
+		const struct edid *edid = drm_edid_raw(drm_edid);
 		struct cea_sad *sads;
+		int ret;
 
-		audio_caps->sad_count = drm_edid_to_sad(new_edid, &sads);
-		kfree(sads);
+		ret = drm_edid_to_sad(edid, &sads);
+		/* Ignore any errors */
+		if (ret < 0)
+			ret = 0;
+		if (ret)
+			kfree(sads);
+		audio_caps->sad_count = ret;
 
-		audio_caps->detect_monitor = drm_detect_monitor_audio(new_edid);
+		/*
+		 * FIXME: This should use connector->display_info.has_audio from
+		 * a path that has read the EDID and called
+		 * drm_edid_connector_update().
+		 */
+		audio_caps->detect_monitor = drm_detect_monitor_audio(edid);
 	}
 
 	if (!enabled) {
@@ -2081,7 +2181,7 @@
 		drm_atomic_bridge_chain_post_disable(bridge, connector->state->state);
 	}
 
-	return new_edid;
+	return drm_edid;
 }
 
 static ssize_t mtk_dp_aux_transfer(struct drm_dp_aux *mtk_aux,
@@ -2095,7 +2195,7 @@
 
 	if (mtk_dp->bridge.type != DRM_MODE_CONNECTOR_eDP &&
 	    !mtk_dp->train_info.cable_plugged_in) {
-		ret = -EAGAIN;
+		ret = -EIO;
 		goto err;
 	}
 
@@ -2310,12 +2410,19 @@
 {
 	struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge);
 	u32 bpp = info->color_formats & DRM_COLOR_FORMAT_YCBCR422 ? 16 : 24;
-	u32 rate = min_t(u32, drm_dp_max_link_rate(mtk_dp->rx_cap) *
-			      drm_dp_max_lane_count(mtk_dp->rx_cap),
-			 drm_dp_bw_code_to_link_rate(mtk_dp->max_linkrate) *
-			 mtk_dp->max_lanes);
+	u32 lane_count_min = mtk_dp->train_info.lane_count;
+	u32 rate = drm_dp_bw_code_to_link_rate(mtk_dp->train_info.link_rate) *
+		   lane_count_min;
 
-	if (rate < mode->clock * bpp / 8)
+	/*
+	 *FEC overhead is approximately 2.4% from DP 1.4a spec 2.2.1.4.2.
+	 *The down-spread amplitude shall either be disabled (0.0%) or up
+	 *to 0.5% from 1.4a 3.5.2.6. Add up to approximately 3% total overhead.
+	 *
+	 *Because rate is already divided by 10,
+	 *mode->clock does not need to be multiplied by 10
+	 */
+	if ((rate * 97 / 100) < (mode->clock * bpp / 8))
 		return MODE_CLOCK_HIGH;
 
 	return MODE_OK;
@@ -2356,10 +2463,9 @@
 	struct drm_display_mode *mode = &crtc_state->adjusted_mode;
 	struct drm_display_info *display_info =
 		&conn_state->connector->display_info;
-	u32 rate = min_t(u32, drm_dp_max_link_rate(mtk_dp->rx_cap) *
-			      drm_dp_max_lane_count(mtk_dp->rx_cap),
-			 drm_dp_bw_code_to_link_rate(mtk_dp->max_linkrate) *
-			 mtk_dp->max_lanes);
+	u32 lane_count_min = mtk_dp->train_info.lane_count;
+	u32 rate = drm_dp_bw_code_to_link_rate(mtk_dp->train_info.link_rate) *
+		   lane_count_min;
 
 	*num_input_fmts = 0;
 
@@ -2368,8 +2474,8 @@
 	 * datarate of YUV422 and sink device supports YUV422, we output YUV422
 	 * format. Use this condition, we can support more resolution.
 	 */
-	if ((rate < (mode->clock * 24 / 8)) &&
-	    (rate > (mode->clock * 16 / 8)) &&
+	if (((rate * 97 / 100) < (mode->clock * 24 / 8)) &&
+	    ((rate * 97 / 100) > (mode->clock * 16 / 8)) &&
 	    (display_info->color_formats & DRM_COLOR_FORMAT_YCBCR422)) {
 		input_fmts = kcalloc(1, sizeof(*input_fmts), GFP_KERNEL);
 		if (!input_fmts)
@@ -2433,7 +2539,7 @@
 	.atomic_enable = mtk_dp_bridge_atomic_enable,
 	.atomic_disable = mtk_dp_bridge_atomic_disable,
 	.mode_valid = mtk_dp_bridge_mode_valid,
-	.get_edid = mtk_dp_get_edid,
+	.edid_read = mtk_dp_edid_read,
 	.detect = mtk_dp_bdg_detect,
 };
 
@@ -2758,7 +2864,7 @@
 static const struct mtk_dp_data mt8188_dp_data = {
 	.bridge_type = DRM_MODE_CONNECTOR_DisplayPort,
 	.smc_cmd = MTK_DP_SIP_ATF_VIDEO_UNMUTE,
-	.efuse_fmt = mt8195_dp_efuse_fmt,
+	.efuse_fmt = mt8188_dp_efuse_fmt,
 	.audio_supported = true,
 	.audio_pkt_in_hblank_area = true,
 	.audio_m_div2_bit = MT8188_AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/mediatek/mtk_drm_crtc.c
@@ -69,6 +69,8 @@
 	/* lock for display hardware access */
 	struct mutex			hw_lock;
 	bool				config_updating;
+	/* lock for config_updating to cmd buffer */
+	spinlock_t			config_lock;
 };
 
 struct mtk_crtc_state {
@@ -95,20 +97,32 @@
 	struct drm_crtc *crtc = &mtk_crtc->base;
 	unsigned long flags;
 
-	spin_lock_irqsave(&crtc->dev->event_lock, flags);
-	drm_crtc_send_vblank_event(crtc, mtk_crtc->event);
-	drm_crtc_vblank_put(crtc);
-	mtk_crtc->event = NULL;
-	spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+	if (mtk_crtc->event) {
+		spin_lock_irqsave(&crtc->dev->event_lock, flags);
+		drm_crtc_send_vblank_event(crtc, mtk_crtc->event);
+		drm_crtc_vblank_put(crtc);
+		mtk_crtc->event = NULL;
+		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+	}
 }
 
 static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
 {
+	unsigned long flags;
+
 	drm_crtc_handle_vblank(&mtk_crtc->base);
+
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	if (mtk_crtc->cmdq_client.chan)
+		return;
+#endif
+
+	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
 	if (!mtk_crtc->config_updating && mtk_crtc->pending_needs_vblank) {
 		mtk_drm_crtc_finish_page_flip(mtk_crtc);
 		mtk_crtc->pending_needs_vblank = false;
 	}
+	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
 }
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
@@ -291,12 +305,17 @@
 	struct mtk_drm_crtc *mtk_crtc = container_of(cmdq_cl, struct mtk_drm_crtc, cmdq_client);
 	struct mtk_crtc_state *state;
 	unsigned int i;
+	unsigned long flags;
 
 	if (data->sta < 0)
 		return;
 
 	state = to_mtk_crtc_state(mtk_crtc->base.state);
 
+	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
+	if (mtk_crtc->config_updating)
+		goto ddp_cmdq_cb_out;
+
 	state->pending_config = false;
 
 	if (mtk_crtc->pending_planes) {
@@ -323,6 +342,15 @@
 		mtk_crtc->pending_async_planes = false;
 	}
 
+ddp_cmdq_cb_out:
+
+	if (mtk_crtc->pending_needs_vblank) {
+		mtk_drm_crtc_finish_page_flip(mtk_crtc);
+		mtk_crtc->pending_needs_vblank = false;
+	}
+
+	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
+
 	mtk_crtc->cmdq_vblank_cnt = 0;
 	wake_up(&mtk_crtc->cb_blocking_queue);
 }
@@ -432,6 +460,7 @@
 {
 	struct drm_device *drm = mtk_crtc->base.dev;
 	struct drm_crtc *crtc = &mtk_crtc->base;
+	unsigned long flags;
 	int i;
 
 	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
@@ -463,10 +492,10 @@
 	pm_runtime_put(drm->dev);
 
 	if (crtc->state->event && !crtc->state->active) {
-		spin_lock_irq(&crtc->dev->event_lock);
+		spin_lock_irqsave(&crtc->dev->event_lock, flags);
 		drm_crtc_send_vblank_event(crtc, crtc->state->event);
 		crtc->state->event = NULL;
-		spin_unlock_irq(&crtc->dev->event_lock);
+		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
 	}
 }
 
@@ -555,9 +584,14 @@
 	struct mtk_drm_private *priv = crtc->dev->dev_private;
 	unsigned int pending_planes = 0, pending_async_planes = 0;
 	int i;
+	unsigned long flags;
 
 	mutex_lock(&mtk_crtc->hw_lock);
+
+	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
 	mtk_crtc->config_updating = true;
+	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
+
 	if (needs_vblank)
 		mtk_crtc->pending_needs_vblank = true;
 
@@ -607,11 +641,19 @@
 		 */
 		mtk_crtc->cmdq_vblank_cnt = 3;
 
+		spin_lock_irqsave(&mtk_crtc->config_lock, flags);
+		mtk_crtc->config_updating = false;
+		spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
+
 		mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
 		mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
 	}
-#endif
+#else
+	spin_lock_irqsave(&mtk_crtc->config_lock, flags);
 	mtk_crtc->config_updating = false;
+	spin_unlock_irqrestore(&mtk_crtc->config_lock, flags);
+#endif
+
 	mutex_unlock(&mtk_crtc->hw_lock);
 }
 
@@ -990,10 +1032,10 @@
 
 	mtk_crtc->mmsys_dev = priv->mmsys_dev;
 	mtk_crtc->ddp_comp_nr = path_len;
-	mtk_crtc->ddp_comp = devm_kmalloc_array(dev,
-						mtk_crtc->ddp_comp_nr + (conn_routes ? 1 : 0),
-						sizeof(*mtk_crtc->ddp_comp),
-						GFP_KERNEL);
+	mtk_crtc->ddp_comp = devm_kcalloc(dev,
+					  mtk_crtc->ddp_comp_nr + (conn_routes ? 1 : 0),
+					  sizeof(*mtk_crtc->ddp_comp),
+					  GFP_KERNEL);
 	if (!mtk_crtc->ddp_comp)
 		return -ENOMEM;
 
@@ -1057,6 +1099,7 @@
 		drm_mode_crtc_set_gamma_size(&mtk_crtc->base, gamma_lut_size);
 	drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, has_ctm, gamma_lut_size);
 	mutex_init(&mtk_crtc->hw_lock);
+	spin_lock_init(&mtk_crtc->config_lock);
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	i = priv->mbox_index++;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
@@ -587,7 +587,7 @@
 	int ret;
 #endif
 
-	if (comp_id < 0 || comp_id >= DDP_COMPONENT_DRM_ID_MAX)
+	if (comp_id >= DDP_COMPONENT_DRM_ID_MAX)
 		return -EINVAL;
 
 	type = mtk_ddp_matches[comp_id].type;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -294,6 +294,9 @@
 	.conn_routes = mt8188_mtk_ddp_main_routes,
 	.num_conn_routes = ARRAY_SIZE(mt8188_mtk_ddp_main_routes),
 	.mmsys_dev_num = 1,
+	.max_width = 8191,
+	.min_width = 1,
+	.min_height = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
@@ -308,6 +311,9 @@
 	.main_path = mt8195_mtk_ddp_main,
 	.main_len = ARRAY_SIZE(mt8195_mtk_ddp_main),
 	.mmsys_dev_num = 2,
+	.max_width = 8191,
+	.min_width = 1,
+	.min_height = 1,
 };
 
 static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
@@ -315,6 +321,9 @@
 	.ext_len = ARRAY_SIZE(mt8195_mtk_ddp_ext),
 	.mmsys_id = 1,
 	.mmsys_dev_num = 2,
+	.max_width = 8191,
+	.min_width = 2, /* 2-pixel align when ethdr is bypassed */
+	.min_height = 1,
 };
 
 static const struct of_device_id mtk_drm_of_ids[] = {
@@ -394,8 +403,10 @@
 		if (temp_drm_priv->mtk_drm_bound)
 			cnt++;
 
-		if (cnt == MAX_CRTC)
+		if (cnt == MAX_CRTC) {
+			of_node_put(node);
 			break;
+		}
 	}
 
 	if (drm_priv->data->mmsys_dev_num == cnt) {
@@ -491,6 +502,15 @@
 		for (j = 0; j < private->data->mmsys_dev_num; j++) {
 			priv_n = private->all_drm_private[j];
 
+			if (priv_n->data->max_width)
+				drm->mode_config.max_width = priv_n->data->max_width;
+
+			if (priv_n->data->min_width)
+				drm->mode_config.min_width = priv_n->data->min_width;
+
+			if (priv_n->data->min_height)
+				drm->mode_config.min_height = priv_n->data->min_height;
+
 			if (i == CRTC_MAIN && priv_n->data->main_len) {
 				ret = mtk_drm_crtc_create(drm, priv_n->data->main_path,
 							  priv_n->data->main_len, j,
@@ -518,6 +538,10 @@
 		}
 	}
 
+	/* IGT will check if the cursor size is configured */
+	drm->mode_config.cursor_width = 512;
+	drm->mode_config.cursor_height = 512;
+
 	/* Use OVL device for all DMA memory allocations */
 	crtc = drm_crtc_from_index(drm, 0);
 	if (crtc)
@@ -651,6 +675,8 @@
 err_free:
 	private->drm = NULL;
 	drm_dev_put(drm);
+	for (i = 0; i < private->data->mmsys_dev_num; i++)
+		private->all_drm_private[i]->drm = NULL;
 	return ret;
 }
 
@@ -739,6 +765,8 @@
 	  .data = (void *)MTK_DISP_OVL },
 	{ .compatible = "mediatek,mt8192-disp-ovl",
 	  .data = (void *)MTK_DISP_OVL },
+	{ .compatible = "mediatek,mt8195-disp-ovl",
+	  .data = (void *)MTK_DISP_OVL },
 	{ .compatible = "mediatek,mt8183-disp-ovl-2l",
 	  .data = (void *)MTK_DISP_OVL_2L },
 	{ .compatible = "mediatek,mt8192-disp-ovl-2l",
@@ -948,6 +976,13 @@
 		of_node_put(private->comp_node[i]);
 }
 
+static void mtk_drm_shutdown(struct platform_device *pdev)
+{
+	struct mtk_drm_private *private = platform_get_drvdata(pdev);
+
+	drm_atomic_helper_shutdown(private->drm);
+}
+
 static int mtk_drm_sys_prepare(struct device *dev)
 {
 	struct mtk_drm_private *private = dev_get_drvdata(dev);
@@ -979,6 +1014,7 @@
 static struct platform_driver mtk_drm_platform_driver = {
 	.probe	= mtk_drm_probe,
 	.remove_new = mtk_drm_remove,
+	.shutdown = mtk_drm_shutdown,
 	.driver	= {
 		.name	= "mediatek-drm",
 		.pm     = &mtk_drm_pm_ops,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_drm_drv.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/mediatek/mtk_drm_drv.h
@@ -46,6 +46,10 @@
 	bool shadow_register;
 	unsigned int mmsys_id;
 	unsigned int mmsys_dev_num;
+
+	u16 max_width;
+	u16 min_width;
+	u16 min_height;
 };
 
 struct mtk_drm_private {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_drm_gem.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/mediatek/mtk_drm_gem.c
@@ -38,6 +38,9 @@
 
 	size = round_up(size, PAGE_SIZE);
 
+	if (size == 0)
+		return ERR_PTR(-EINVAL);
+
 	mtk_gem_obj = kzalloc(sizeof(*mtk_gem_obj), GFP_KERNEL);
 	if (!mtk_gem_obj)
 		return ERR_PTR(-ENOMEM);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_drm_plane.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/mediatek/mtk_drm_plane.c
@@ -227,6 +227,8 @@
 	plane->state->src_y = new_state->src_y;
 	plane->state->src_h = new_state->src_h;
 	plane->state->src_w = new_state->src_w;
+	plane->state->dst.x1 = new_state->dst.x1;
+	plane->state->dst.y1 = new_state->dst.y1;
 
 	mtk_plane_update_new_state(new_state, new_plane_state);
 	swap(plane->state->fb, new_state->fb);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -71,8 +71,8 @@
 #define DSI_PS_WC			0x3fff
 #define DSI_PS_SEL			(3 << 16)
 #define PACKED_PS_16BIT_RGB565		(0 << 16)
-#define LOOSELY_PS_18BIT_RGB666		(1 << 16)
-#define PACKED_PS_18BIT_RGB666		(2 << 16)
+#define PACKED_PS_18BIT_RGB666		(1 << 16)
+#define LOOSELY_PS_24BIT_RGB666		(2 << 16)
 #define PACKED_PS_24BIT_RGB888		(3 << 16)
 
 #define DSI_VSA_NL		0x20
@@ -130,11 +130,11 @@
 #define CLK_HS_POST			(0xff << 8)
 #define CLK_HS_EXIT			(0xff << 16)
 
-#define DSI_VM_CMD_CON		0x130
+/* DSI_VM_CMD_CON */
 #define VM_CMD_EN			BIT(0)
 #define TS_VFP_EN			BIT(5)
 
-#define DSI_SHADOW_DEBUG	0x190U
+/* DSI_SHADOW_DEBUG */
 #define FORCE_COMMIT			BIT(0)
 #define BYPASS_SHADOW			BIT(1)
 
@@ -177,6 +177,8 @@
 
 struct mtk_dsi_driver_data {
 	const u32 reg_cmdq_off;
+	const u32 reg_vm_cmd_off;
+	const u32 reg_shadow_dbg_off;
 	bool has_shadow_ctl;
 	bool has_size_ctl;
 	bool cmdq_long_packet_ctl;
@@ -346,8 +348,8 @@
 
 static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
 {
-	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, VM_CMD_EN, VM_CMD_EN);
-	mtk_dsi_mask(dsi, DSI_VM_CMD_CON, TS_VFP_EN, TS_VFP_EN);
+	mtk_dsi_mask(dsi, dsi->driver_data->reg_vm_cmd_off, VM_CMD_EN, VM_CMD_EN);
+	mtk_dsi_mask(dsi, dsi->driver_data->reg_vm_cmd_off, TS_VFP_EN, TS_VFP_EN);
 }
 
 static void mtk_dsi_ps_control_vact(struct mtk_dsi *dsi)
@@ -369,10 +371,10 @@
 		ps_bpp_mode |= PACKED_PS_24BIT_RGB888;
 		break;
 	case MIPI_DSI_FMT_RGB666:
-		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
+		ps_bpp_mode |= LOOSELY_PS_24BIT_RGB666;
 		break;
 	case MIPI_DSI_FMT_RGB666_PACKED:
-		ps_bpp_mode |= LOOSELY_PS_18BIT_RGB666;
+		ps_bpp_mode |= PACKED_PS_18BIT_RGB666;
 		break;
 	case MIPI_DSI_FMT_RGB565:
 		ps_bpp_mode |= PACKED_PS_16BIT_RGB565;
@@ -426,7 +428,7 @@
 		dsi_tmp_buf_bpp = 3;
 		break;
 	case MIPI_DSI_FMT_RGB666:
-		tmp_reg = LOOSELY_PS_18BIT_RGB666;
+		tmp_reg = LOOSELY_PS_24BIT_RGB666;
 		dsi_tmp_buf_bpp = 3;
 		break;
 	case MIPI_DSI_FMT_RGB666_PACKED:
@@ -660,7 +662,7 @@
 
 	if (dsi->driver_data->has_shadow_ctl)
 		writel(FORCE_COMMIT | BYPASS_SHADOW,
-		       dsi->regs + DSI_SHADOW_DEBUG);
+		       dsi->regs + dsi->driver_data->reg_shadow_dbg_off);
 
 	mtk_dsi_reset_engine(dsi);
 	mtk_dsi_phy_timconfig(dsi);
@@ -1223,26 +1225,36 @@
 
 static const struct mtk_dsi_driver_data mt8173_dsi_driver_data = {
 	.reg_cmdq_off = 0x200,
+	.reg_vm_cmd_off = 0x130,
+	.reg_shadow_dbg_off = 0x190
 };
 
 static const struct mtk_dsi_driver_data mt2701_dsi_driver_data = {
 	.reg_cmdq_off = 0x180,
+	.reg_vm_cmd_off = 0x130,
+	.reg_shadow_dbg_off = 0x190
 };
 
 static const struct mtk_dsi_driver_data mt8183_dsi_driver_data = {
 	.reg_cmdq_off = 0x200,
+	.reg_vm_cmd_off = 0x130,
+	.reg_shadow_dbg_off = 0x190,
 	.has_shadow_ctl = true,
 	.has_size_ctl = true,
 };
 
 static const struct mtk_dsi_driver_data mt8186_dsi_driver_data = {
 	.reg_cmdq_off = 0xd00,
+	.reg_vm_cmd_off = 0x200,
+	.reg_shadow_dbg_off = 0xc00,
 	.has_shadow_ctl = true,
 	.has_size_ctl = true,
 };
 
 static const struct mtk_dsi_driver_data mt8188_dsi_driver_data = {
 	.reg_cmdq_off = 0xd00,
+	.reg_vm_cmd_off = 0x200,
+	.reg_shadow_dbg_off = 0xc00,
 	.has_shadow_ctl = true,
 	.has_size_ctl = true,
 	.cmdq_long_packet_ctl = true,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mediatek/mtk_ethdr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/mediatek/mtk_ethdr.c
@@ -50,7 +50,6 @@
 
 #define MIXER_INX_MODE_BYPASS			0
 #define MIXER_INX_MODE_EVEN_EXTEND		1
-#define DEFAULT_9BIT_ALPHA			0x100
 #define	MIXER_ALPHA_AEN				BIT(8)
 #define	MIXER_ALPHA				0xff
 #define ETHDR_CLK_NUM				13
@@ -154,13 +153,19 @@
 	unsigned int offset = (pending->x & 1) << 31 | pending->y << 16 | pending->x;
 	unsigned int align_width = ALIGN_DOWN(pending->width, 2);
 	unsigned int alpha_con = 0;
+	bool replace_src_a = false;
 
 	dev_dbg(dev, "%s+ idx:%d", __func__, idx);
 
 	if (idx >= 4)
 		return;
 
-	if (!pending->enable) {
+	if (!pending->enable || !pending->width || !pending->height) {
+		/*
+		 * instead of disabling layer with MIX_SRC_CON directly
+		 * set the size to 0 to avoid screen shift due to mixer
+		 * mode switch (hardware behavior)
+		 */
 		mtk_ddp_write(cmdq_pkt, 0, &mixer->cmdq_base, mixer->regs, MIX_L_SRC_SIZE(idx));
 		return;
 	}
@@ -168,8 +173,16 @@
 	if (state->base.fb && state->base.fb->format->has_alpha)
 		alpha_con = MIXER_ALPHA_AEN | MIXER_ALPHA;
 
-	mtk_mmsys_mixer_in_config(priv->mmsys_dev, idx + 1, alpha_con ? false : true,
-				  DEFAULT_9BIT_ALPHA,
+	if (state->base.fb && !state->base.fb->format->has_alpha) {
+		/*
+		 * Mixer doesn't support CONST_BLD mode,
+		 * use a trick to make the output equivalent
+		 */
+		replace_src_a = true;
+	}
+
+	mtk_mmsys_mixer_in_config(priv->mmsys_dev, idx + 1, replace_src_a,
+				  MIXER_ALPHA,
 				  pending->x & 1 ? MIXER_INX_MODE_EVEN_EXTEND :
 				  MIXER_INX_MODE_BYPASS, align_width / 2 - 1, cmdq_pkt);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/meson/meson_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/meson/meson_drv.c
@@ -250,29 +250,20 @@
 	if (ret)
 		goto free_drm;
 	ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_0);
-	if (ret) {
-		meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
-		goto free_drm;
-	}
+	if (ret)
+		goto free_canvas_osd1;
 	ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_1);
-	if (ret) {
-		meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
-		meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0);
-		goto free_drm;
-	}
+	if (ret)
+		goto free_canvas_vd1_0;
 	ret = meson_canvas_alloc(priv->canvas, &priv->canvas_id_vd1_2);
-	if (ret) {
-		meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
-		meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0);
-		meson_canvas_free(priv->canvas, priv->canvas_id_vd1_1);
-		goto free_drm;
-	}
+	if (ret)
+		goto free_canvas_vd1_1;
 
 	priv->vsync_irq = platform_get_irq(pdev, 0);
 
 	ret = drm_vblank_init(drm, 1);
 	if (ret)
-		goto free_drm;
+		goto free_canvas_vd1_2;
 
 	/* Assign limits per soc revision/package */
 	for (i = 0 ; i < ARRAY_SIZE(meson_drm_soc_attrs) ; ++i) {
@@ -288,11 +279,11 @@
 	 */
 	ret = drm_aperture_remove_framebuffers(&meson_driver);
 	if (ret)
-		goto free_drm;
+		goto free_canvas_vd1_2;
 
 	ret = drmm_mode_config_init(drm);
 	if (ret)
-		goto free_drm;
+		goto free_canvas_vd1_2;
 	drm->mode_config.max_width = 3840;
 	drm->mode_config.max_height = 2160;
 	drm->mode_config.funcs = &meson_mode_config_funcs;
@@ -307,7 +298,7 @@
 	if (priv->afbcd.ops) {
 		ret = priv->afbcd.ops->init(priv);
 		if (ret)
-			goto free_drm;
+			goto free_canvas_vd1_2;
 	}
 
 	/* Encoder Initialization */
@@ -371,6 +362,14 @@
 exit_afbcd:
 	if (priv->afbcd.ops)
 		priv->afbcd.ops->exit(priv);
+free_canvas_vd1_2:
+	meson_canvas_free(priv->canvas, priv->canvas_id_vd1_2);
+free_canvas_vd1_1:
+	meson_canvas_free(priv->canvas, priv->canvas_id_vd1_1);
+free_canvas_vd1_0:
+	meson_canvas_free(priv->canvas, priv->canvas_id_vd1_0);
+free_canvas_osd1:
+	meson_canvas_free(priv->canvas, priv->canvas_id_osd1);
 free_drm:
 	drm_dev_put(drm);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -106,6 +106,8 @@
 #define HHI_HDMI_CLK_CNTL	0x1cc /* 0x73 */
 #define HHI_HDMI_PHY_CNTL0	0x3a0 /* 0xe8 */
 #define HHI_HDMI_PHY_CNTL1	0x3a4 /* 0xe9 */
+#define  PHY_CNTL1_INIT		0x03900000
+#define  PHY_INVERT		BIT(17)
 #define HHI_HDMI_PHY_CNTL2	0x3a8 /* 0xea */
 #define HHI_HDMI_PHY_CNTL3	0x3ac /* 0xeb */
 #define HHI_HDMI_PHY_CNTL4	0x3b0 /* 0xec */
@@ -130,6 +132,8 @@
 				    unsigned int addr);
 	void		(*dwc_write)(struct meson_dw_hdmi *dw_hdmi,
 				     unsigned int addr, unsigned int data);
+	u32 cntl0_init;
+	u32 cntl1_init;
 };
 
 struct meson_dw_hdmi {
@@ -384,26 +388,6 @@
 	    dw_hdmi_bus_fmt_is_420(hdmi))
 		mode_is_420 = true;
 
-	/* Enable clocks */
-	regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100);
-
-	/* Bring HDMITX MEM output of power down */
-	regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0);
-
-	/* Bring out of reset */
-	dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_SW_RESET,  0);
-
-	/* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */
-	dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
-			       0x3, 0x3);
-
-	/* Enable cec_clk and hdcp22_tmdsclk_en */
-	dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
-			       0x3 << 4, 0x3 << 4);
-
-	/* Enable normal output to PHY */
-	dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
-
 	/* TMDS pattern setup */
 	if (mode->clock > 340000 && !mode_is_420) {
 		dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01,
@@ -425,20 +409,6 @@
 	/* Setup PHY parameters */
 	meson_hdmi_phy_setup_mode(dw_hdmi, mode, mode_is_420);
 
-	/* Setup PHY */
-	regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
-			   0xffff << 16, 0x0390 << 16);
-
-	/* BIT_INVERT */
-	if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
-	    dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi") ||
-	    dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-g12a-dw-hdmi"))
-		regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
-				   BIT(17), 0);
-	else
-		regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
-				   BIT(17), BIT(17));
-
 	/* Disable clock, fifo, fifo_wr */
 	regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0);
 
@@ -492,7 +462,9 @@
 
 	DRM_DEBUG_DRIVER("\n");
 
-	regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0);
+	/* Fallback to init mode */
+	regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL1, dw_hdmi->data->cntl1_init);
+	regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, dw_hdmi->data->cntl0_init);
 }
 
 static enum drm_connector_status dw_hdmi_read_hpd(struct dw_hdmi *hdmi,
@@ -610,11 +582,22 @@
 	.fast_io = true,
 };
 
-static const struct meson_dw_hdmi_data meson_dw_hdmi_gx_data = {
+static const struct meson_dw_hdmi_data meson_dw_hdmi_gxbb_data = {
 	.top_read = dw_hdmi_top_read,
 	.top_write = dw_hdmi_top_write,
 	.dwc_read = dw_hdmi_dwc_read,
 	.dwc_write = dw_hdmi_dwc_write,
+	.cntl0_init = 0x0,
+	.cntl1_init = PHY_CNTL1_INIT | PHY_INVERT,
+};
+
+static const struct meson_dw_hdmi_data meson_dw_hdmi_gxl_data = {
+	.top_read = dw_hdmi_top_read,
+	.top_write = dw_hdmi_top_write,
+	.dwc_read = dw_hdmi_dwc_read,
+	.dwc_write = dw_hdmi_dwc_write,
+	.cntl0_init = 0x0,
+	.cntl1_init = PHY_CNTL1_INIT,
 };
 
 static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
@@ -622,6 +605,8 @@
 	.top_write = dw_hdmi_g12a_top_write,
 	.dwc_read = dw_hdmi_g12a_dwc_read,
 	.dwc_write = dw_hdmi_g12a_dwc_write,
+	.cntl0_init = 0x000b4242, /* Bandgap */
+	.cntl1_init = PHY_CNTL1_INIT,
 };
 
 static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
@@ -656,6 +641,13 @@
 	meson_dw_hdmi->data->top_write(meson_dw_hdmi,
 				       HDMITX_TOP_CLK_CNTL, 0xff);
 
+	/* Enable normal output to PHY */
+	meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
+
+	/* Setup PHY */
+	regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL1, meson_dw_hdmi->data->cntl1_init);
+	regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, meson_dw_hdmi->data->cntl0_init);
+
 	/* Enable HDMI-TX Interrupt */
 	meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR,
 				       HDMITX_TOP_INTR_CORE);
@@ -865,11 +857,11 @@
 
 static const struct of_device_id meson_dw_hdmi_of_table[] = {
 	{ .compatible = "amlogic,meson-gxbb-dw-hdmi",
-	  .data = &meson_dw_hdmi_gx_data },
+	  .data = &meson_dw_hdmi_gxbb_data },
 	{ .compatible = "amlogic,meson-gxl-dw-hdmi",
-	  .data = &meson_dw_hdmi_gx_data },
+	  .data = &meson_dw_hdmi_gxl_data },
 	{ .compatible = "amlogic,meson-gxm-dw-hdmi",
-	  .data = &meson_dw_hdmi_gx_data },
+	  .data = &meson_dw_hdmi_gxl_data },
 	{ .compatible = "amlogic,meson-g12a-dw-hdmi",
 	  .data = &meson_dw_hdmi_g12a_data },
 	{ }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/meson/meson_dw_mipi_dsi.c
@@ -95,6 +95,7 @@
 		return ret;
 	}
 
+	clk_disable_unprepare(mipi_dsi->px_clk);
 	ret = clk_set_rate(mipi_dsi->px_clk, mipi_dsi->mode->clock * 1000);
 
 	if (ret) {
@@ -103,6 +104,12 @@
 		return ret;
 	}
 
+	ret = clk_prepare_enable(mipi_dsi->px_clk);
+	if (ret) {
+		dev_err(mipi_dsi->dev, "Failed to enable DSI Pixel clock (ret %d)\n", ret);
+		return ret;
+	}
+
 	switch (mipi_dsi->dsi_device->format) {
 	case MIPI_DSI_FMT_RGB888:
 		dpi_data_format = DPI_COLOR_24BIT;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/meson/meson_plane.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/meson/meson_plane.c
@@ -534,6 +534,7 @@
 	struct meson_plane *meson_plane;
 	struct drm_plane *plane;
 	const uint64_t *format_modifiers = format_modifiers_default;
+	int ret;
 
 	meson_plane = devm_kzalloc(priv->drm->dev, sizeof(*meson_plane),
 				   GFP_KERNEL);
@@ -548,12 +549,16 @@
 	else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A))
 		format_modifiers = format_modifiers_afbc_g12a;
 
-	drm_universal_plane_init(priv->drm, plane, 0xFF,
-				 &meson_plane_funcs,
-				 supported_drm_formats,
-				 ARRAY_SIZE(supported_drm_formats),
-				 format_modifiers,
-				 DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane");
+	ret = drm_universal_plane_init(priv->drm, plane, 0xFF,
+					&meson_plane_funcs,
+					supported_drm_formats,
+					ARRAY_SIZE(supported_drm_formats),
+					format_modifiers,
+					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);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/meson/meson_vclk.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/meson/meson_vclk.c
@@ -790,13 +790,13 @@
 				 FREQ_1000_1001(params[i].pixel_freq));
 		DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n",
 				 i, params[i].phy_freq,
-				 FREQ_1000_1001(params[i].phy_freq/10)*10);
+				 FREQ_1000_1001(params[i].phy_freq/1000)*1000);
 		/* Match strict frequency */
 		if (phy_freq == params[i].phy_freq &&
 		    vclk_freq == params[i].vclk_freq)
 			return MODE_OK;
 		/* Match 1000/1001 variant */
-		if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) &&
+		if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/1000)*1000) &&
 		    vclk_freq == FREQ_1000_1001(params[i].vclk_freq))
 			return MODE_OK;
 	}
@@ -1070,7 +1070,7 @@
 
 	for (freq = 0 ; params[freq].pixel_freq ; ++freq) {
 		if ((phy_freq == params[freq].phy_freq ||
-		     phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) &&
+		     phy_freq == FREQ_1000_1001(params[freq].phy_freq/1000)*1000) &&
 		    (vclk_freq == params[freq].vclk_freq ||
 		     vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) {
 			if (vclk_freq != params[freq].vclk_freq)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mgag200/mgag200_i2c.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/mgag200/mgag200_i2c.c
@@ -31,6 +31,8 @@
 #include <linux/i2c.h>
 #include <linux/pci.h>
 
+#include <drm/drm_managed.h>
+
 #include "mgag200_drv.h"
 
 static int mga_i2c_read_gpio(struct mga_device *mdev)
@@ -86,7 +88,7 @@
 	return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0;
 }
 
-static void mgag200_i2c_release(void *res)
+static void mgag200_i2c_release(struct drm_device *dev, void *res)
 {
 	struct mga_i2c_chan *i2c = res;
 
@@ -114,7 +116,7 @@
 	i2c->adapter.algo_data = &i2c->bit;
 
 	i2c->bit.udelay = 10;
-	i2c->bit.timeout = 2;
+	i2c->bit.timeout = usecs_to_jiffies(2200);
 	i2c->bit.data = i2c;
 	i2c->bit.setsda		= mga_gpio_setsda;
 	i2c->bit.setscl		= mga_gpio_setscl;
@@ -125,5 +127,5 @@
 	if (ret)
 		return ret;
 
-	return devm_add_action_or_reset(dev->dev, mgag200_i2c_release, i2c);
+	return drmm_add_action_or_reset(dev, mgag200_i2c_release, i2c);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/Kconfig
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/Kconfig
@@ -54,6 +54,14 @@
 	  Only use this if you are a driver developer.  This should *not*
 	  be enabled for production kernels.  If unsure, say N.
 
+config DRM_MSM_VALIDATE_XML
+	bool "Validate XML register files against schema"
+	depends on DRM_MSM && EXPERT && n
+	depends on $(success,$(PYTHON3) -c "import lxml")
+	help
+	  Validate XML files with register definitions against rules-fd schema.
+	  This option is mostly targeting DRM MSM developers. If unsure, say N.
+
 config DRM_MSM_MDSS
 	bool
 	depends on DRM_MSM
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/Makefile
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/Makefile
@@ -1,23 +1,34 @@
 # SPDX-License-Identifier: GPL-2.0
 ccflags-y := -I $(srctree)/$(src)
+ccflags-y += -I $(obj)/generated
 ccflags-y += -I $(srctree)/$(src)/disp/dpu1
 ccflags-$(CONFIG_DRM_MSM_DSI) += -I $(srctree)/$(src)/dsi
 ccflags-$(CONFIG_DRM_MSM_DP) += -I $(srctree)/$(src)/dp
 
-msm-y := \
+adreno-y := \
 	adreno/adreno_device.o \
 	adreno/adreno_gpu.o \
+	adreno/a2xx_catalog.o \
 	adreno/a2xx_gpu.o \
+	adreno/a2xx_gpummu.o \
+	adreno/a3xx_catalog.o \
 	adreno/a3xx_gpu.o \
+	adreno/a4xx_catalog.o \
 	adreno/a4xx_gpu.o \
+	adreno/a5xx_catalog.o \
 	adreno/a5xx_gpu.o \
 	adreno/a5xx_power.o \
 	adreno/a5xx_preempt.o \
+	adreno/a6xx_catalog.o \
 	adreno/a6xx_gpu.o \
 	adreno/a6xx_gmu.o \
 	adreno/a6xx_hfi.o \
 
-msm-$(CONFIG_DRM_MSM_HDMI) += \
+adreno-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \
+
+adreno-$(CONFIG_DRM_MSM_GPU_STATE)	+= adreno/a6xx_gpu_state.o
+
+msm-display-$(CONFIG_DRM_MSM_HDMI) += \
 	hdmi/hdmi.o \
 	hdmi/hdmi_audio.o \
 	hdmi/hdmi_bridge.o \
@@ -26,11 +37,12 @@
 	hdmi/hdmi_phy.o \
 	hdmi/hdmi_phy_8960.o \
 	hdmi/hdmi_phy_8996.o \
+	hdmi/hdmi_phy_8998.o \
 	hdmi/hdmi_phy_8x60.o \
 	hdmi/hdmi_phy_8x74.o \
 	hdmi/hdmi_pll_8960.o \
 
-msm-$(CONFIG_DRM_MSM_MDP4) += \
+msm-display-$(CONFIG_DRM_MSM_MDP4) += \
 	disp/mdp4/mdp4_crtc.o \
 	disp/mdp4/mdp4_dsi_encoder.o \
 	disp/mdp4/mdp4_dtv_encoder.o \
@@ -41,7 +53,7 @@
 	disp/mdp4/mdp4_kms.o \
 	disp/mdp4/mdp4_plane.o \
 
-msm-$(CONFIG_DRM_MSM_MDP5) += \
+msm-display-$(CONFIG_DRM_MSM_MDP5) += \
 	disp/mdp5/mdp5_cfg.o \
 	disp/mdp5/mdp5_cmd_encoder.o \
 	disp/mdp5/mdp5_ctl.o \
@@ -54,7 +66,7 @@
 	disp/mdp5/mdp5_plane.o \
 	disp/mdp5/mdp5_smp.o \
 
-msm-$(CONFIG_DRM_MSM_DPU) += \
+msm-display-$(CONFIG_DRM_MSM_DPU) += \
 	disp/dpu1/dpu_core_perf.o \
 	disp/dpu1/dpu_crtc.o \
 	disp/dpu1/dpu_encoder.o \
@@ -84,14 +96,16 @@
 	disp/dpu1/dpu_vbif.o \
 	disp/dpu1/dpu_writeback.o
 
-msm-$(CONFIG_DRM_MSM_MDSS) += \
+msm-display-$(CONFIG_DRM_MSM_MDSS) += \
 	msm_mdss.o \
 
-msm-y += \
+msm-display-y += \
 	disp/mdp_format.o \
 	disp/mdp_kms.o \
 	disp/msm_disp_snapshot.o \
 	disp/msm_disp_snapshot_util.o \
+
+msm-y += \
 	msm_atomic.o \
 	msm_atomic_tracepoints.o \
 	msm_debugfs.o \
@@ -113,39 +127,95 @@
 	msm_ringbuffer.o \
 	msm_submitqueue.o \
 	msm_gpu_tracepoints.o \
-	msm_gpummu.o
 
-msm-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \
-	dp/dp_debug.o
+msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
 
-msm-$(CONFIG_DRM_MSM_GPU_STATE)	+= adreno/a6xx_gpu_state.o
+msm-display-$(CONFIG_DEBUG_FS) += \
+	dp/dp_debug.o
 
-msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
+msm-display-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
 	dp/dp_catalog.o \
 	dp/dp_ctrl.o \
 	dp/dp_display.o \
 	dp/dp_drm.o \
 	dp/dp_link.o \
 	dp/dp_panel.o \
-	dp/dp_parser.o \
-	dp/dp_power.o \
-	dp/dp_audio.o
+	dp/dp_audio.o \
+	dp/dp_utils.o \
+	dp/dp_mst_drm.o
 
-msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
+msm-display-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o
 
-msm-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o
-
-msm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \
+msm-display-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \
 			dsi/dsi_cfg.o \
 			dsi/dsi_host.o \
 			dsi/dsi_manager.o \
 			dsi/phy/dsi_phy.o
 
-msm-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/phy/dsi_phy_28nm.o
-msm-$(CONFIG_DRM_MSM_DSI_20NM_PHY) += dsi/phy/dsi_phy_20nm.o
-msm-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/phy/dsi_phy_28nm_8960.o
-msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o
-msm-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/phy/dsi_phy_10nm.o
-msm-$(CONFIG_DRM_MSM_DSI_7NM_PHY) += dsi/phy/dsi_phy_7nm.o
+msm-display-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/phy/dsi_phy_28nm.o
+msm-display-$(CONFIG_DRM_MSM_DSI_20NM_PHY) += dsi/phy/dsi_phy_20nm.o
+msm-display-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/phy/dsi_phy_28nm_8960.o
+msm-display-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o
+msm-display-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/phy/dsi_phy_10nm.o
+msm-display-$(CONFIG_DRM_MSM_DSI_7NM_PHY) += dsi/phy/dsi_phy_7nm.o
+
+msm-y += $(adreno-y) $(msm-display-y)
+
+obj-$(CONFIG_DRM_MSM)	+= msm_display.o
+msm_display-y := $(msm-y)
+
+ifeq (y,$(CONFIG_DRM_MSM_VALIDATE_XML))
+	headergen-opts += --validate
+else
+	headergen-opts += --no-validate
+endif
+
+quiet_cmd_headergen = GENHDR  $@
+      cmd_headergen = mkdir -p $(obj)/generated && $(PYTHON3) $(srctree)/$(src)/registers/gen_header.py \
+		      $(headergen-opts) --rnn $(srctree)/$(src)/registers --xml $< c-defines > $@
+
+$(obj)/generated/%.xml.h: $(src)/registers/adreno/%.xml \
+		$(src)/registers/adreno/adreno_common.xml \
+		$(src)/registers/adreno/adreno_pm4.xml \
+		$(src)/registers/freedreno_copyright.xml \
+		$(src)/registers/gen_header.py \
+		$(src)/registers/rules-fd.xsd \
+		FORCE
+	$(call if_changed,headergen)
+
+$(obj)/generated/%.xml.h: $(src)/registers/display/%.xml \
+		$(src)/registers/freedreno_copyright.xml \
+		$(src)/registers/gen_header.py \
+		$(src)/registers/rules-fd.xsd \
+		FORCE
+	$(call if_changed,headergen)
+
+ADRENO_HEADERS = \
+	generated/a2xx.xml.h \
+	generated/a3xx.xml.h \
+	generated/a4xx.xml.h \
+	generated/a5xx.xml.h \
+	generated/a6xx.xml.h \
+	generated/a6xx_gmu.xml.h \
+	generated/adreno_common.xml.h \
+	generated/adreno_pm4.xml.h \
+
+DISPLAY_HEADERS = \
+	generated/dsi_phy_7nm.xml.h \
+	generated/dsi_phy_10nm.xml.h \
+	generated/dsi_phy_14nm.xml.h \
+	generated/dsi_phy_20nm.xml.h \
+	generated/dsi_phy_28nm_8960.xml.h \
+	generated/dsi_phy_28nm.xml.h \
+	generated/dsi.xml.h \
+	generated/hdmi.xml.h \
+	generated/mdp4.xml.h \
+	generated/mdp5.xml.h \
+	generated/mdp_common.xml.h \
+	generated/mdss.xml.h \
+	generated/sfpb.xml.h
+
+$(addprefix $(obj)/,$(adreno-y)): $(addprefix $(obj)/,$(ADRENO_HEADERS))
+$(addprefix $(obj)/,$(msm-display-y)): $(addprefix $(obj)/,$(DISPLAY_HEADERS))
 
-obj-$(CONFIG_DRM_MSM)	+= msm.o
+targets += $(ADRENO_HEADERS) $(DISPLAY_HEADERS)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a2xx_catalog.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a2xx_catalog.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013-2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
+ */
+
+#include "adreno_gpu.h"
+
+static const struct adreno_info a2xx_gpus[] = {
+	{
+		.chip_ids = ADRENO_CHIP_IDS(0x02000000),
+		.family = ADRENO_2XX_GEN1,
+		.revn  = 200,
+		.fw = {
+			[ADRENO_FW_PM4] = "yamato_pm4.fw",
+			[ADRENO_FW_PFP] = "yamato_pfp.fw",
+		},
+		.gmem  = SZ_256K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a2xx_gpu_init,
+	}, { /* a200 on i.mx51 has only 128kib gmem */
+		.chip_ids = ADRENO_CHIP_IDS(0x02000001),
+		.family = ADRENO_2XX_GEN1,
+		.revn  = 201,
+		.fw = {
+			[ADRENO_FW_PM4] = "yamato_pm4.fw",
+			[ADRENO_FW_PFP] = "yamato_pfp.fw",
+		},
+		.gmem  = SZ_128K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a2xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x02020000),
+		.family = ADRENO_2XX_GEN2,
+		.revn  = 220,
+		.fw = {
+			[ADRENO_FW_PM4] = "leia_pm4_470.fw",
+			[ADRENO_FW_PFP] = "leia_pfp_470.fw",
+		},
+		.gmem  = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a2xx_gpu_init,
+	}
+};
+DECLARE_ADRENO_GPULIST(a2xx);
+
+MODULE_FIRMWARE("qcom/leia_pfp_470.fw");
+MODULE_FIRMWARE("qcom/leia_pm4_470.fw");
+MODULE_FIRMWARE("qcom/yamato_pfp.fw");
+MODULE_FIRMWARE("qcom/yamato_pm4.fw");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a2xx_gpu.c
@@ -113,7 +113,7 @@
 	uint32_t *ptr, len;
 	int i, ret;
 
-	msm_gpummu_params(gpu->aspace->mmu, &pt_base, &tran_error);
+	a2xx_gpummu_params(gpu->aspace->mmu, &pt_base, &tran_error);
 
 	DBG("%s", gpu->name);
 
@@ -469,7 +469,7 @@
 static struct msm_gem_address_space *
 a2xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev)
 {
-	struct msm_mmu *mmu = msm_gpummu_new(&pdev->dev, gpu);
+	struct msm_mmu *mmu = a2xx_gpummu_new(&pdev->dev, gpu);
 	struct msm_gem_address_space *aspace;
 
 	aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a2xx_gpu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a2xx_gpu.h
@@ -19,4 +19,8 @@
 };
 #define to_a2xx_gpu(x) container_of(x, struct a2xx_gpu, base)
 
+struct msm_mmu *a2xx_gpummu_new(struct device *dev, struct msm_gpu *gpu);
+void a2xx_gpummu_params(struct msm_mmu *mmu, dma_addr_t *pt_base,
+		dma_addr_t *tran_error);
+
 #endif /* __A2XX_GPU_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a2xx_gpummu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a2xx_gpummu.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018 The Linux Foundation. All rights reserved. */
+
+#include <linux/dma-mapping.h>
+
+#include "msm_drv.h"
+#include "msm_mmu.h"
+
+#include "adreno_gpu.h"
+#include "a2xx_gpu.h"
+
+#include "a2xx.xml.h"
+
+struct a2xx_gpummu {
+	struct msm_mmu base;
+	struct msm_gpu *gpu;
+	dma_addr_t pt_base;
+	uint32_t *table;
+};
+#define to_a2xx_gpummu(x) container_of(x, struct a2xx_gpummu, base)
+
+#define GPUMMU_VA_START SZ_16M
+#define GPUMMU_VA_RANGE (0xfff * SZ_64K)
+#define GPUMMU_PAGE_SIZE SZ_4K
+#define TABLE_SIZE (sizeof(uint32_t) * GPUMMU_VA_RANGE / GPUMMU_PAGE_SIZE)
+
+static void a2xx_gpummu_detach(struct msm_mmu *mmu)
+{
+}
+
+static int a2xx_gpummu_map(struct msm_mmu *mmu, uint64_t iova,
+		struct sg_table *sgt, size_t len, int prot)
+{
+	struct a2xx_gpummu *gpummu = to_a2xx_gpummu(mmu);
+	unsigned idx = (iova - GPUMMU_VA_START) / GPUMMU_PAGE_SIZE;
+	struct sg_dma_page_iter dma_iter;
+	unsigned prot_bits = 0;
+
+	if (prot & IOMMU_WRITE)
+		prot_bits |= 1;
+	if (prot & IOMMU_READ)
+		prot_bits |= 2;
+
+	for_each_sgtable_dma_page(sgt, &dma_iter, 0) {
+		dma_addr_t addr = sg_page_iter_dma_address(&dma_iter);
+		int i;
+
+		for (i = 0; i < PAGE_SIZE; i += GPUMMU_PAGE_SIZE)
+			gpummu->table[idx++] = (addr + i) | prot_bits;
+	}
+
+	/* we can improve by deferring flush for multiple map() */
+	gpu_write(gpummu->gpu, REG_A2XX_MH_MMU_INVALIDATE,
+		A2XX_MH_MMU_INVALIDATE_INVALIDATE_ALL |
+		A2XX_MH_MMU_INVALIDATE_INVALIDATE_TC);
+	return 0;
+}
+
+static int a2xx_gpummu_unmap(struct msm_mmu *mmu, uint64_t iova, size_t len)
+{
+	struct a2xx_gpummu *gpummu = to_a2xx_gpummu(mmu);
+	unsigned idx = (iova - GPUMMU_VA_START) / GPUMMU_PAGE_SIZE;
+	unsigned i;
+
+	for (i = 0; i < len / GPUMMU_PAGE_SIZE; i++, idx++)
+                gpummu->table[idx] = 0;
+
+	gpu_write(gpummu->gpu, REG_A2XX_MH_MMU_INVALIDATE,
+		A2XX_MH_MMU_INVALIDATE_INVALIDATE_ALL |
+		A2XX_MH_MMU_INVALIDATE_INVALIDATE_TC);
+	return 0;
+}
+
+static void a2xx_gpummu_resume_translation(struct msm_mmu *mmu)
+{
+}
+
+static void a2xx_gpummu_destroy(struct msm_mmu *mmu)
+{
+	struct a2xx_gpummu *gpummu = to_a2xx_gpummu(mmu);
+
+	dma_free_attrs(mmu->dev, TABLE_SIZE, gpummu->table, gpummu->pt_base,
+		DMA_ATTR_FORCE_CONTIGUOUS);
+
+	kfree(gpummu);
+}
+
+static const struct msm_mmu_funcs funcs = {
+		.detach = a2xx_gpummu_detach,
+		.map = a2xx_gpummu_map,
+		.unmap = a2xx_gpummu_unmap,
+		.destroy = a2xx_gpummu_destroy,
+		.resume_translation = a2xx_gpummu_resume_translation,
+};
+
+struct msm_mmu *a2xx_gpummu_new(struct device *dev, struct msm_gpu *gpu)
+{
+	struct a2xx_gpummu *gpummu;
+
+	gpummu = kzalloc(sizeof(*gpummu), GFP_KERNEL);
+	if (!gpummu)
+		return ERR_PTR(-ENOMEM);
+
+	gpummu->table = dma_alloc_attrs(dev, TABLE_SIZE + 32, &gpummu->pt_base,
+		GFP_KERNEL | __GFP_ZERO, DMA_ATTR_FORCE_CONTIGUOUS);
+	if (!gpummu->table) {
+		kfree(gpummu);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	gpummu->gpu = gpu;
+	msm_mmu_init(&gpummu->base, dev, &funcs, MSM_MMU_GPUMMU);
+
+	return &gpummu->base;
+}
+
+void a2xx_gpummu_params(struct msm_mmu *mmu, dma_addr_t *pt_base,
+		dma_addr_t *tran_error)
+{
+	dma_addr_t base = to_a2xx_gpummu(mmu)->pt_base;
+
+	*pt_base = base;
+	*tran_error = base + TABLE_SIZE; /* 32-byte aligned */
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a3xx_catalog.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a3xx_catalog.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013-2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
+ */
+
+#include "adreno_gpu.h"
+
+static const struct adreno_info a3xx_gpus[] = {
+	{
+		.chip_ids = ADRENO_CHIP_IDS(0x03000512),
+		.family = ADRENO_3XX,
+		.fw = {
+			[ADRENO_FW_PM4] = "a330_pm4.fw",
+			[ADRENO_FW_PFP] = "a330_pfp.fw",
+		},
+		.gmem  = SZ_128K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a3xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x03000520),
+		.family = ADRENO_3XX,
+		.revn  = 305,
+		.fw = {
+			[ADRENO_FW_PM4] = "a300_pm4.fw",
+			[ADRENO_FW_PFP] = "a300_pfp.fw",
+		},
+		.gmem  = SZ_256K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a3xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x03000600),
+		.family = ADRENO_3XX,
+		.revn  = 307,        /* because a305c is revn==306 */
+		.fw = {
+			[ADRENO_FW_PM4] = "a300_pm4.fw",
+			[ADRENO_FW_PFP] = "a300_pfp.fw",
+		},
+		.gmem  = SZ_128K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a3xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(
+			0x03020000,
+			0x03020001,
+			0x03020002
+		),
+		.family = ADRENO_3XX,
+		.revn  = 320,
+		.fw = {
+			[ADRENO_FW_PM4] = "a300_pm4.fw",
+			[ADRENO_FW_PFP] = "a300_pfp.fw",
+		},
+		.gmem  = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a3xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(
+			0x03030000,
+			0x03030001,
+			0x03030002
+		),
+		.family = ADRENO_3XX,
+		.revn  = 330,
+		.fw = {
+			[ADRENO_FW_PM4] = "a330_pm4.fw",
+			[ADRENO_FW_PFP] = "a330_pfp.fw",
+		},
+		.gmem  = SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a3xx_gpu_init,
+	}
+};
+DECLARE_ADRENO_GPULIST(a3xx);
+
+MODULE_FIRMWARE("qcom/a300_pm4.fw");
+MODULE_FIRMWARE("qcom/a300_pfp.fw");
+MODULE_FIRMWARE("qcom/a330_pm4.fw");
+MODULE_FIRMWARE("qcom/a330_pfp.fw");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
@@ -134,6 +134,13 @@
 		/* Set up AOOO: */
 		gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003c);
 		gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO, 0x003c003c);
+	} else if (adreno_is_a305b(adreno_gpu)) {
+		gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x00181818);
+		gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x00181818);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x00000018);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x00000018);
+		gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x00000303);
+		gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003);
 	} else if (adreno_is_a306(adreno_gpu)) {
 		gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003);
 		gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x0000000a);
@@ -230,7 +237,7 @@
 	gpu_write(gpu, REG_A3XX_UCHE_CACHE_MODE_CONTROL_REG, 0x00000001);
 
 	/* Enable Clock gating: */
-	if (adreno_is_a306(adreno_gpu))
+	if (adreno_is_a305b(adreno_gpu) || adreno_is_a306(adreno_gpu))
 		gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0xaaaaaaaa);
 	else if (adreno_is_a320(adreno_gpu))
 		gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0xbfffffff);
@@ -333,7 +340,7 @@
 				AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB1_START(2) |
 				AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB2_START(6) |
 				AXXX_CP_QUEUE_THRESHOLDS_CSQ_ST_START(14));
-	} else if (adreno_is_a330(adreno_gpu)) {
+	} else if (adreno_is_a330(adreno_gpu) || adreno_is_a305b(adreno_gpu)) {
 		/* NOTE: this (value take from downstream android driver)
 		 * includes some bits outside of the known bitfields.  But
 		 * A330 has this "MERCIU queue" thing too, which might
@@ -559,7 +566,7 @@
 		goto fail;
 
 	/* if needed, allocate gmem: */
-	if (adreno_is_a330(adreno_gpu)) {
+	if (adreno_is_a330(adreno_gpu) || adreno_is_a305b(adreno_gpu)) {
 		ret = adreno_gpu_ocmem_init(&adreno_gpu->base.pdev->dev,
 					    adreno_gpu, &a3xx_gpu->ocmem);
 		if (ret)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a4xx_catalog.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a4xx_catalog.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013-2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
+ */
+
+#include "adreno_gpu.h"
+
+static const struct adreno_info a4xx_gpus[] = {
+	{
+		.chip_ids = ADRENO_CHIP_IDS(0x04000500),
+		.family = ADRENO_4XX,
+		.revn  = 405,
+		.fw = {
+			[ADRENO_FW_PM4] = "a420_pm4.fw",
+			[ADRENO_FW_PFP] = "a420_pfp.fw",
+		},
+		.gmem  = SZ_256K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a4xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x04020000),
+		.family = ADRENO_4XX,
+		.revn  = 420,
+		.fw = {
+			[ADRENO_FW_PM4] = "a420_pm4.fw",
+			[ADRENO_FW_PFP] = "a420_pfp.fw",
+		},
+		.gmem  = (SZ_1M + SZ_512K),
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a4xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x04030002),
+		.family = ADRENO_4XX,
+		.revn  = 430,
+		.fw = {
+			[ADRENO_FW_PM4] = "a420_pm4.fw",
+			[ADRENO_FW_PFP] = "a420_pfp.fw",
+		},
+		.gmem  = (SZ_1M + SZ_512K),
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a4xx_gpu_init,
+	}
+};
+DECLARE_ADRENO_GPULIST(a4xx);
+
+MODULE_FIRMWARE("qcom/a420_pm4.fw");
+MODULE_FIRMWARE("qcom/a420_pfp.fw");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a5xx_catalog.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a5xx_catalog.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013-2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
+ */
+
+#include "adreno_gpu.h"
+
+static const struct adreno_info a5xx_gpus[] = {
+	{
+		.chip_ids = ADRENO_CHIP_IDS(0x05000600),
+		.family = ADRENO_5XX,
+		.revn = 506,
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+		},
+		.gmem = (SZ_128K + SZ_8K),
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
+			  ADRENO_QUIRK_LMLOADKILL_DISABLE,
+		.init = a5xx_gpu_init,
+		.zapfw = "a506_zap.mdt",
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x05000800),
+		.family = ADRENO_5XX,
+		.revn = 508,
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+		},
+		.gmem = (SZ_128K + SZ_8K),
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
+		.init = a5xx_gpu_init,
+		.zapfw = "a508_zap.mdt",
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x05000900),
+		.family = ADRENO_5XX,
+		.revn = 509,
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+		},
+		.gmem = (SZ_256K + SZ_16K),
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
+		.init = a5xx_gpu_init,
+		/* Adreno 509 uses the same ZAP as 512 */
+		.zapfw = "a512_zap.mdt",
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x05010000),
+		.family = ADRENO_5XX,
+		.revn = 510,
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+		},
+		.gmem = SZ_256K,
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.init = a5xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x05010200),
+		.family = ADRENO_5XX,
+		.revn = 512,
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+		},
+		.gmem = (SZ_256K + SZ_16K),
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
+		.init = a5xx_gpu_init,
+		.zapfw = "a512_zap.mdt",
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(
+			0x05030002,
+			0x05030004
+		),
+		.family = ADRENO_5XX,
+		.revn = 530,
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+			[ADRENO_FW_GPMU] = "a530v3_gpmu.fw2",
+		},
+		.gmem = SZ_1M,
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
+			ADRENO_QUIRK_FAULT_DETECT_MASK,
+		.init = a5xx_gpu_init,
+		.zapfw = "a530_zap.mdt",
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x05040001),
+		.family = ADRENO_5XX,
+		.revn = 540,
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+			[ADRENO_FW_GPMU] = "a540_gpmu.fw2",
+		},
+		.gmem = SZ_1M,
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
+		.init = a5xx_gpu_init,
+		.zapfw = "a540_zap.mdt",
+	}
+};
+DECLARE_ADRENO_GPULIST(a5xx);
+
+MODULE_FIRMWARE("qcom/a530_pm4.fw");
+MODULE_FIRMWARE("qcom/a530_pfp.fw");
+MODULE_FIRMWARE("qcom/a530v3_gpmu.fw2");
+MODULE_FIRMWARE("qcom/a530_zap.mdt");
+MODULE_FIRMWARE("qcom/a530_zap.b00");
+MODULE_FIRMWARE("qcom/a530_zap.b01");
+MODULE_FIRMWARE("qcom/a530_zap.b02");
+MODULE_FIRMWARE("qcom/a540_gpmu.fw2");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
@@ -65,6 +65,8 @@
 
 static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit)
 {
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
 	struct msm_ringbuffer *ring = submit->ring;
 	struct drm_gem_object *obj;
 	uint32_t *ptr, dwords;
@@ -109,6 +111,7 @@
 		}
 	}
 
+	a5xx_gpu->last_seqno[ring->id] = submit->seqno;
 	a5xx_flush(gpu, ring, true);
 	a5xx_preempt_trigger(gpu);
 
@@ -150,9 +153,13 @@
 	OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
 	OUT_RING(ring, 1);
 
-	/* Enable local preemption for finegrain preemption */
+	/*
+	 * Disable local preemption by default because it requires
+	 * user-space to be aware of it and provide additional handling
+	 * to restore rendering state or do various flushes on switch.
+	 */
 	OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1);
-	OUT_RING(ring, 0x1);
+	OUT_RING(ring, 0x0);
 
 	/* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */
 	OUT_PKT7(ring, CP_YIELD_ENABLE, 1);
@@ -206,6 +213,7 @@
 	/* Write the fence to the scratch register */
 	OUT_PKT4(ring, REG_A5XX_CP_SCRATCH_REG(2), 1);
 	OUT_RING(ring, submit->seqno);
+	a5xx_gpu->last_seqno[ring->id] = submit->seqno;
 
 	/*
 	 * Execute a CACHE_FLUSH_TS event. This will ensure that the
@@ -1788,5 +1796,9 @@
 	else
 		adreno_gpu->ubwc_config.highest_bank_bit = 14;
 
+	/* a5xx only supports UBWC 1.0, these are not configurable */
+	adreno_gpu->ubwc_config.macrotile_mode = 0;
+	adreno_gpu->ubwc_config.ubwc_swizzle = 0x7;
+
 	return gpu;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a5xx_gpu.h
@@ -34,8 +34,10 @@
 	struct drm_gem_object *preempt_counters_bo[MSM_GPU_MAX_RINGS];
 	struct a5xx_preempt_record *preempt[MSM_GPU_MAX_RINGS];
 	uint64_t preempt_iova[MSM_GPU_MAX_RINGS];
+	uint32_t last_seqno[MSM_GPU_MAX_RINGS];
 
 	atomic_t preempt_state;
+	spinlock_t preempt_start_lock;
 	struct timer_list preempt_timer;
 
 	struct drm_gem_object *shadow_bo;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a5xx_preempt.c
@@ -55,6 +55,8 @@
 /* Return the highest priority ringbuffer with something in it */
 static struct msm_ringbuffer *get_next_ring(struct msm_gpu *gpu)
 {
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
 	unsigned long flags;
 	int i;
 
@@ -64,6 +66,8 @@
 
 		spin_lock_irqsave(&ring->preempt_lock, flags);
 		empty = (get_wptr(ring) == gpu->funcs->get_rptr(gpu, ring));
+		if (!empty && ring == a5xx_gpu->cur_ring)
+			empty = ring->memptrs->fence == a5xx_gpu->last_seqno[i];
 		spin_unlock_irqrestore(&ring->preempt_lock, flags);
 
 		if (!empty)
@@ -98,11 +102,18 @@
 		return;
 
 	/*
+	 * Serialize preemption start to ensure that we always make
+	 * decision on latest state. Otherwise we can get stuck in
+	 * lower priority or empty ring.
+	 */
+	spin_lock_irqsave(&a5xx_gpu->preempt_start_lock, flags);
+
+	/*
 	 * Try to start preemption by moving from NONE to START. If
 	 * unsuccessful, a preemption is already in flight
 	 */
 	if (!try_preempt_state(a5xx_gpu, PREEMPT_NONE, PREEMPT_START))
-		return;
+		goto out;
 
 	/* Get the next ring to preempt to */
 	ring = get_next_ring(gpu);
@@ -127,9 +138,11 @@
 		set_preempt_state(a5xx_gpu, PREEMPT_ABORT);
 		update_wptr(gpu, a5xx_gpu->cur_ring);
 		set_preempt_state(a5xx_gpu, PREEMPT_NONE);
-		return;
+		goto out;
 	}
 
+	spin_unlock_irqrestore(&a5xx_gpu->preempt_start_lock, flags);
+
 	/* Make sure the wptr doesn't update while we're in motion */
 	spin_lock_irqsave(&ring->preempt_lock, flags);
 	a5xx_gpu->preempt[ring->id]->wptr = get_wptr(ring);
@@ -152,6 +165,10 @@
 
 	/* And actually start the preemption */
 	gpu_write(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL, 1);
+	return;
+
+out:
+	spin_unlock_irqrestore(&a5xx_gpu->preempt_start_lock, flags);
 }
 
 void a5xx_preempt_irq(struct msm_gpu *gpu)
@@ -188,6 +205,12 @@
 	update_wptr(gpu, a5xx_gpu->cur_ring);
 
 	set_preempt_state(a5xx_gpu, PREEMPT_NONE);
+
+	/*
+	 * Try to trigger preemption again in case there was a submit or
+	 * retire during ring switch
+	 */
+	a5xx_preempt_trigger(gpu);
 }
 
 void a5xx_preempt_hw_init(struct msm_gpu *gpu)
@@ -204,6 +227,8 @@
 		return;
 
 	for (i = 0; i < gpu->nr_rings; i++) {
+		a5xx_gpu->preempt[i]->data = 0;
+		a5xx_gpu->preempt[i]->info = 0;
 		a5xx_gpu->preempt[i]->wptr = 0;
 		a5xx_gpu->preempt[i]->rptr = 0;
 		a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova;
@@ -298,5 +323,6 @@
 		}
 	}
 
+	spin_lock_init(&a5xx_gpu->preempt_start_lock);
 	timer_setup(&a5xx_gpu->preempt_timer, a5xx_preempt_timer, 0);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a6xx_catalog.c
@@ -0,0 +1,1339 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013-2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
+ */
+
+#include "adreno_gpu.h"
+#include "a6xx_gpu.h"
+#include "a6xx.xml.h"
+#include "a6xx_gmu.xml.h"
+
+static const struct adreno_reglist a612_hwcg[] = {
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000081},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01202222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05522022},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
+	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
+	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
+	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
+	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
+	{},
+};
+
+/* For a615 family (a615, a616, a618 and a619) */
+static const struct adreno_reglist a615_hwcg[] = {
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP0,  0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP0,  0x0000F3CF},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP0,  0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP1,  0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP1, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP1, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP0,  0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP1,  0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP1, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP1, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP1, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP1, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP1, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP1, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE,  0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_HYST_UCHE,  0x00000004},
+	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002020},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU1, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU2, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU3, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU1, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU2, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU3, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05022022},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
+	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
+	{},
+};
+
+static const struct adreno_reglist a630_hwcg[] = {
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP1, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP2, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP3, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02022220},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP1, 0x02022220},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP2, 0x02022220},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP3, 0x02022220},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP1, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP2, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP3, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP1, 0x0000f3cf},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP2, 0x0000f3cf},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP3, 0x0000f3cf},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP1, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP2, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP3, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP2, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP3, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP1, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP2, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP3, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP1, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP2, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP3, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP1, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP2, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP3, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP1, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP2, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP3, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP1, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP2, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP3, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP1, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP2, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP3, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP1, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP2, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP3, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP2, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP3, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP1, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP2, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP3, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP1, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP2, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP3, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
+	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB1, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB2, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB3, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB1, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB2, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB3, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU1, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU2, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU3, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU1, 0x00040f00},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU2, 0x00040f00},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU3, 0x00040f00},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05022022},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
+	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
+	{},
+};
+
+static const struct adreno_reglist a640_hwcg[] = {
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05222022},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
+	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
+	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
+	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
+	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
+	{},
+};
+
+static const struct adreno_reglist a650_hwcg[] = {
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
+	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000777},
+	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
+	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
+	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
+	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
+	{},
+};
+
+static const struct adreno_reglist a660_hwcg[] = {
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
+	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
+	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
+	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
+	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
+	{},
+};
+
+static const struct adreno_reglist a690_hwcg[] = {
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
+	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
+	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_CNTL, 0x8AA8AA82},
+	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
+	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
+	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
+	{REG_A6XX_GPU_GMU_AO_GMU_CGC_MODE_CNTL, 0x20200},
+	{REG_A6XX_GPU_GMU_AO_GMU_CGC_DELAY_CNTL, 0x10111},
+	{REG_A6XX_GPU_GMU_AO_GMU_CGC_HYST_CNTL, 0x5555},
+	{}
+};
+
+/* For a615, a616, a618, a619, a630, a640 and a680 */
+static const u32 a630_protect_regs[] = {
+	A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
+	A6XX_PROTECT_RDONLY(0x00501, 0x0005),
+	A6XX_PROTECT_RDONLY(0x0050b, 0x02f4),
+	A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00510, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00534, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00800, 0x0082),
+	A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
+	A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
+	A6XX_PROTECT_RDONLY(0x008de, 0x00ae),
+	A6XX_PROTECT_NORDWR(0x00900, 0x004d),
+	A6XX_PROTECT_NORDWR(0x0098d, 0x0272),
+	A6XX_PROTECT_NORDWR(0x00e00, 0x0001),
+	A6XX_PROTECT_NORDWR(0x00e03, 0x000c),
+	A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
+	A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
+	A6XX_PROTECT_NORDWR(0x09624, 0x01db),
+	A6XX_PROTECT_NORDWR(0x09e70, 0x0001),
+	A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
+	A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
+	A6XX_PROTECT_NORDWR(0x0ae50, 0x032f),
+	A6XX_PROTECT_NORDWR(0x0b604, 0x0000),
+	A6XX_PROTECT_NORDWR(0x0be02, 0x0001),
+	A6XX_PROTECT_NORDWR(0x0be20, 0x17df),
+	A6XX_PROTECT_NORDWR(0x0f000, 0x0bff),
+	A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x11c00, 0x0000), /* note: infinite range */
+};
+DECLARE_ADRENO_PROTECT(a630_protect, 32);
+
+/* These are for a620 and a650 */
+static const u32 a650_protect_regs[] = {
+	A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
+	A6XX_PROTECT_RDONLY(0x00501, 0x0005),
+	A6XX_PROTECT_RDONLY(0x0050b, 0x02f4),
+	A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00510, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00534, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00800, 0x0082),
+	A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
+	A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
+	A6XX_PROTECT_RDONLY(0x008de, 0x00ae),
+	A6XX_PROTECT_NORDWR(0x00900, 0x004d),
+	A6XX_PROTECT_NORDWR(0x0098d, 0x0272),
+	A6XX_PROTECT_NORDWR(0x00e00, 0x0001),
+	A6XX_PROTECT_NORDWR(0x00e03, 0x000c),
+	A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
+	A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
+	A6XX_PROTECT_NORDWR(0x08e80, 0x027f),
+	A6XX_PROTECT_NORDWR(0x09624, 0x01db),
+	A6XX_PROTECT_NORDWR(0x09e60, 0x0011),
+	A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
+	A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
+	A6XX_PROTECT_NORDWR(0x0ae50, 0x032f),
+	A6XX_PROTECT_NORDWR(0x0b604, 0x0000),
+	A6XX_PROTECT_NORDWR(0x0b608, 0x0007),
+	A6XX_PROTECT_NORDWR(0x0be02, 0x0001),
+	A6XX_PROTECT_NORDWR(0x0be20, 0x17df),
+	A6XX_PROTECT_NORDWR(0x0f000, 0x0bff),
+	A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x18400, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x1a800, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x1f400, 0x0443),
+	A6XX_PROTECT_RDONLY(0x1f844, 0x007b),
+	A6XX_PROTECT_NORDWR(0x1f887, 0x001b),
+	A6XX_PROTECT_NORDWR(0x1f8c0, 0x0000), /* note: infinite range */
+};
+DECLARE_ADRENO_PROTECT(a650_protect, 48);
+
+/* These are for a635 and a660 */
+static const u32 a660_protect_regs[] = {
+	A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
+	A6XX_PROTECT_RDONLY(0x00501, 0x0005),
+	A6XX_PROTECT_RDONLY(0x0050b, 0x02f4),
+	A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00510, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00534, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00800, 0x0082),
+	A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
+	A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
+	A6XX_PROTECT_RDONLY(0x008de, 0x00ae),
+	A6XX_PROTECT_NORDWR(0x00900, 0x004d),
+	A6XX_PROTECT_NORDWR(0x0098d, 0x0272),
+	A6XX_PROTECT_NORDWR(0x00e00, 0x0001),
+	A6XX_PROTECT_NORDWR(0x00e03, 0x000c),
+	A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
+	A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
+	A6XX_PROTECT_NORDWR(0x08e80, 0x027f),
+	A6XX_PROTECT_NORDWR(0x09624, 0x01db),
+	A6XX_PROTECT_NORDWR(0x09e60, 0x0011),
+	A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
+	A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
+	A6XX_PROTECT_NORDWR(0x0ae50, 0x012f),
+	A6XX_PROTECT_NORDWR(0x0b604, 0x0000),
+	A6XX_PROTECT_NORDWR(0x0b608, 0x0006),
+	A6XX_PROTECT_NORDWR(0x0be02, 0x0001),
+	A6XX_PROTECT_NORDWR(0x0be20, 0x015f),
+	A6XX_PROTECT_NORDWR(0x0d000, 0x05ff),
+	A6XX_PROTECT_NORDWR(0x0f000, 0x0bff),
+	A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x18400, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x1a400, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x1f400, 0x0443),
+	A6XX_PROTECT_RDONLY(0x1f844, 0x007b),
+	A6XX_PROTECT_NORDWR(0x1f860, 0x0000),
+	A6XX_PROTECT_NORDWR(0x1f887, 0x001b),
+	A6XX_PROTECT_NORDWR(0x1f8c0, 0x0000), /* note: infinite range */
+};
+DECLARE_ADRENO_PROTECT(a660_protect, 48);
+
+/* These are for a690 */
+static const u32 a690_protect_regs[] = {
+	A6XX_PROTECT_RDONLY(0x00000, 0x004ff),
+	A6XX_PROTECT_RDONLY(0x00501, 0x00001),
+	A6XX_PROTECT_RDONLY(0x0050b, 0x002f4),
+	A6XX_PROTECT_NORDWR(0x0050e, 0x00000),
+	A6XX_PROTECT_NORDWR(0x00510, 0x00000),
+	A6XX_PROTECT_NORDWR(0x00534, 0x00000),
+	A6XX_PROTECT_NORDWR(0x00800, 0x00082),
+	A6XX_PROTECT_NORDWR(0x008a0, 0x00008),
+	A6XX_PROTECT_NORDWR(0x008ab, 0x00024),
+	A6XX_PROTECT_RDONLY(0x008de, 0x000ae),
+	A6XX_PROTECT_NORDWR(0x00900, 0x0004d),
+	A6XX_PROTECT_NORDWR(0x0098d, 0x00272),
+	A6XX_PROTECT_NORDWR(0x00e00, 0x00001),
+	A6XX_PROTECT_NORDWR(0x00e03, 0x0000c),
+	A6XX_PROTECT_NORDWR(0x03c00, 0x000c3),
+	A6XX_PROTECT_RDONLY(0x03cc4, 0x01fff),
+	A6XX_PROTECT_NORDWR(0x08630, 0x001cf),
+	A6XX_PROTECT_NORDWR(0x08e00, 0x00000),
+	A6XX_PROTECT_NORDWR(0x08e08, 0x00007),
+	A6XX_PROTECT_NORDWR(0x08e50, 0x0001f),
+	A6XX_PROTECT_NORDWR(0x08e80, 0x0027f),
+	A6XX_PROTECT_NORDWR(0x09624, 0x001db),
+	A6XX_PROTECT_NORDWR(0x09e60, 0x00011),
+	A6XX_PROTECT_NORDWR(0x09e78, 0x00187),
+	A6XX_PROTECT_NORDWR(0x0a630, 0x001cf),
+	A6XX_PROTECT_NORDWR(0x0ae02, 0x00000),
+	A6XX_PROTECT_NORDWR(0x0ae50, 0x0012f),
+	A6XX_PROTECT_NORDWR(0x0b604, 0x00000),
+	A6XX_PROTECT_NORDWR(0x0b608, 0x00006),
+	A6XX_PROTECT_NORDWR(0x0be02, 0x00001),
+	A6XX_PROTECT_NORDWR(0x0be20, 0x0015f),
+	A6XX_PROTECT_NORDWR(0x0d000, 0x005ff),
+	A6XX_PROTECT_NORDWR(0x0f000, 0x00bff),
+	A6XX_PROTECT_RDONLY(0x0fc00, 0x01fff),
+	A6XX_PROTECT_NORDWR(0x11c00, 0x00000), /*note: infiite range */
+};
+DECLARE_ADRENO_PROTECT(a690_protect, 48);
+
+static const struct adreno_info a6xx_gpus[] = {
+	{
+		.chip_ids = ADRENO_CHIP_IDS(0x06010000),
+		.family = ADRENO_6XX_GEN1,
+		.revn = 610,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+		},
+		.gmem = (SZ_128K + SZ_4K),
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init = a6xx_gpu_init,
+		.zapfw = "a610_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a612_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00020202,
+			.prim_fifo_threshold = 0x00080000,
+		},
+		/*
+		 * There are (at least) three SoCs implementing A610: SM6125
+		 * (trinket), SM6115 (bengal) and SM6225 (khaje). Trinket does
+		 * not have speedbinning, as only a single SKU exists and we
+		 * don't support khaje upstream yet.  Hence, this matching
+		 * table is only valid for bengal.
+		 */
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 206, 1 },
+			{ 200, 2 },
+			{ 157, 3 },
+			{ 127, 4 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06010500),
+		.family = ADRENO_6XX_GEN1,
+		.revn = 615,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a630_gmu.bin",
+		},
+		.gmem = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init = a6xx_gpu_init,
+		.zapfw = "a615_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a615_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00000222,
+			.prim_fifo_threshold = 0x0018000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			/*
+			 * The default speed bin (0) has the same values as
+			 * speed bin 90 which goes up to 432 MHz.
+			 */
+			{ 0,   0 },
+			{ 90,  0 },
+			{ 105, 1 },
+			{ 146, 2 },
+			{ 163, 3 },
+		),
+	}, {
+		.machine = "qcom,sm7150",
+		.chip_ids = ADRENO_CHIP_IDS(0x06010800),
+		.family = ADRENO_6XX_GEN1,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a630_gmu.bin",
+		},
+		.gmem = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
+		.init = a6xx_gpu_init,
+		.zapfw = "a615_zap.mbn",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a615_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00000222,
+			.prim_fifo_threshold = 0x00180000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 128, 1 },
+			{ 146, 2 },
+			{ 167, 3 },
+			{ 172, 4 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06010800),
+		.family = ADRENO_6XX_GEN1,
+		.revn = 618,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a630_gmu.bin",
+		},
+		.gmem = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
+		.init = a6xx_gpu_init,
+		.a6xx = &(const struct a6xx_info) {
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00000222,
+			.prim_fifo_threshold = 0x00180000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 169, 1 },
+			{ 174, 2 },
+		),
+	}, {
+		.machine = "qcom,sm4350",
+		.chip_ids = ADRENO_CHIP_IDS(0x06010900),
+		.family = ADRENO_6XX_GEN1,
+		.revn = 619,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a619_gmu.bin",
+		},
+		.gmem = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init = a6xx_gpu_init,
+		.zapfw = "a615_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a615_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00000222,
+			.prim_fifo_threshold = 0x00018000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 138, 1 },
+			{ 92,  2 },
+		),
+	}, {
+		.machine = "qcom,sm6375",
+		.chip_ids = ADRENO_CHIP_IDS(0x06010901),
+		.family = ADRENO_6XX_GEN1,
+		.revn = 619,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a619_gmu.bin",
+		},
+		.gmem = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init = a6xx_gpu_init,
+		.zapfw = "a615_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a615_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00000222,
+			.prim_fifo_threshold = 0x00018000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 190, 1 },
+			{ 177, 2 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06010900),
+		.family = ADRENO_6XX_GEN1,
+		.revn = 619,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a619_gmu.bin",
+		},
+		.gmem = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
+		.init = a6xx_gpu_init,
+		.zapfw = "a615_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a615_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00000222,
+			.prim_fifo_threshold = 0x00018000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 120, 4 },
+			{ 138, 3 },
+			{ 169, 2 },
+			{ 180, 1 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(
+			0x06030001,
+			0x06030002
+		),
+		.family = ADRENO_6XX_GEN1,
+		.revn = 630,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a630_gmu.bin",
+		},
+		.gmem = SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
+		.init = a6xx_gpu_init,
+		.zapfw = "a630_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a630_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00020202,
+			.prim_fifo_threshold = 0x00180000,
+		},
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06040001),
+		.family = ADRENO_6XX_GEN2,
+		.revn = 640,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a640_gmu.bin",
+		},
+		.gmem = SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
+		.init = a6xx_gpu_init,
+		.zapfw = "a640_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a640_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00020202,
+			.prim_fifo_threshold = 0x00180000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0, 0 },
+			{ 1, 1 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06050002),
+		.family = ADRENO_6XX_GEN3,
+		.revn = 650,
+		.fw = {
+			[ADRENO_FW_SQE] = "a650_sqe.fw",
+			[ADRENO_FW_GMU] = "a650_gmu.bin",
+		},
+		.gmem = SZ_1M + SZ_128K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a650_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a650_hwcg,
+			.protect = &a650_protect,
+			.gmu_cgc_mode = 0x00020202,
+			.prim_fifo_threshold = 0x00300200,
+		},
+		.address_space_size = SZ_16G,
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0, 0 },
+			{ 1, 1 },
+			{ 2, 3 }, /* Yep, 2 and 3 are swapped! :/ */
+			{ 3, 2 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06060001),
+		.family = ADRENO_6XX_GEN4,
+		.revn = 660,
+		.fw = {
+			[ADRENO_FW_SQE] = "a660_sqe.fw",
+			[ADRENO_FW_GMU] = "a660_gmu.bin",
+		},
+		.gmem = SZ_1M + SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a660_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a660_hwcg,
+			.protect = &a660_protect,
+			.gmu_cgc_mode = 0x00020000,
+			.prim_fifo_threshold = 0x00300200,
+		},
+		.address_space_size = SZ_16G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06060300),
+		.family = ADRENO_6XX_GEN4,
+		.fw = {
+			[ADRENO_FW_SQE] = "a660_sqe.fw",
+			[ADRENO_FW_GMU] = "a663_gmu.bin",
+		},
+		.gmem = SZ_1M + SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a690_hwcg,
+			.protect = &a660_protect,
+			.gmu_cgc_mode = 0x00020200,
+			.prim_fifo_threshold = 0x00300200,
+		},
+		.address_space_size = SZ_16G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06030500),
+		.family = ADRENO_6XX_GEN4,
+		.fw = {
+			[ADRENO_FW_SQE] = "a660_sqe.fw",
+			[ADRENO_FW_GMU] = "a660_gmu.bin",
+		},
+		.gmem = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a660_zap.mbn",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a660_hwcg,
+			.protect = &a660_protect,
+			.gmu_cgc_mode = 0x00020202,
+			.prim_fifo_threshold = 0x00200200,
+		},
+		.address_space_size = SZ_16G,
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 117, 0 },
+			{ 172, 2 }, /* Called speedbin 1 downstream, but let's not break things! */
+			{ 190, 1 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06080001),
+		.family = ADRENO_6XX_GEN2,
+		.revn = 680,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a640_gmu.bin",
+		},
+		.gmem = SZ_2M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
+		.init = a6xx_gpu_init,
+		.zapfw = "a640_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a640_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00020202,
+			.prim_fifo_threshold = 0x00200200,
+		},
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06090000),
+		.family = ADRENO_6XX_GEN4,
+		.fw = {
+			[ADRENO_FW_SQE] = "a660_sqe.fw",
+			[ADRENO_FW_GMU] = "a660_gmu.bin",
+		},
+		.gmem = SZ_4M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a690_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a690_hwcg,
+			.protect = &a690_protect,
+			.gmu_cgc_mode = 0x00020200,
+			.prim_fifo_threshold = 0x00800200,
+		},
+		.address_space_size = SZ_16G,
+	}
+};
+DECLARE_ADRENO_GPULIST(a6xx);
+
+MODULE_FIRMWARE("qcom/a615_zap.mbn");
+MODULE_FIRMWARE("qcom/a619_gmu.bin");
+MODULE_FIRMWARE("qcom/a630_sqe.fw");
+MODULE_FIRMWARE("qcom/a630_gmu.bin");
+MODULE_FIRMWARE("qcom/a630_zap.mbn");
+MODULE_FIRMWARE("qcom/a640_gmu.bin");
+MODULE_FIRMWARE("qcom/a650_gmu.bin");
+MODULE_FIRMWARE("qcom/a650_sqe.fw");
+MODULE_FIRMWARE("qcom/a660_gmu.bin");
+MODULE_FIRMWARE("qcom/a660_sqe.fw");
+
+static const struct adreno_reglist a702_hwcg[] = {
+	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000081 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01202222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05522022 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002 },
+	{ REG_A6XX_RBBM_ISDB_CNT, 0x00000182 },
+	{ REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_FCHE, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_FCHE, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_FCHE, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_GLC, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GLC, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GLC, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_MHUB, 0x00000002 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_MHUB, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_MHUB, 0x00000000 },
+	{}
+};
+
+static const struct adreno_reglist a730_hwcg[] = {
+	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02022222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222220 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x44000f00 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00555555 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00440044 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE2_GRAS, 0x00000222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_GRAS, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222223 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_GPC, 0x00222222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_LRZ, 0x55555552 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_CP, 0x00000223 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL, 0x8aa8aa82 },
+	{ REG_A6XX_RBBM_ISDB_CNT, 0x00000182 },
+	{ REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555 },
+	{},
+};
+
+static const struct adreno_reglist a740_hwcg[] = {
+	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x22022222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x003cf3cf },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222220 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_UCHE, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000444 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x44000f00 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00555555 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00440044 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE2_GRAS, 0x00000222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_GRAS, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222223 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00222222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_GPC, 0x00222222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_LRZ, 0x55555552 },
+	{ REG_A7XX_RBBM_CLOCK_HYST2_VFD, 0x00000000 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_CP, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL, 0x8aa8aa82 },
+	{ REG_A6XX_RBBM_ISDB_CNT, 0x00000182 },
+	{ REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555 },
+	{},
+};
+
+static const u32 a730_protect_regs[] = {
+	A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
+	A6XX_PROTECT_RDONLY(0x0050b, 0x0058),
+	A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00510, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00534, 0x0000),
+	A6XX_PROTECT_RDONLY(0x005fb, 0x009d),
+	A6XX_PROTECT_NORDWR(0x00699, 0x01e9),
+	A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
+	A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
+	/* 0x008d0-0x008dd and 0x008e0-0x008e6 are unprotected on purpose for tools like perfetto */
+	A6XX_PROTECT_NORDWR(0x008de, 0x0001),
+	A6XX_PROTECT_RDONLY(0x008e7, 0x014b),
+	A6XX_PROTECT_NORDWR(0x00900, 0x004d),
+	A6XX_PROTECT_NORDWR(0x0098d, 0x00b2),
+	A6XX_PROTECT_NORDWR(0x00a41, 0x01be),
+	A6XX_PROTECT_NORDWR(0x00df0, 0x0001),
+	A6XX_PROTECT_NORDWR(0x00e01, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00e07, 0x0008),
+	A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
+	A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
+	A6XX_PROTECT_NORDWR(0x08e80, 0x0280),
+	A6XX_PROTECT_NORDWR(0x09624, 0x01db),
+	A6XX_PROTECT_NORDWR(0x09e40, 0x0000),
+	A6XX_PROTECT_NORDWR(0x09e64, 0x000d),
+	A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
+	A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
+	A6XX_PROTECT_NORDWR(0x0ae50, 0x000f),
+	A6XX_PROTECT_NORDWR(0x0ae66, 0x0003),
+	A6XX_PROTECT_NORDWR(0x0ae6f, 0x0003),
+	A6XX_PROTECT_NORDWR(0x0b604, 0x0003),
+	A6XX_PROTECT_NORDWR(0x0ec00, 0x0fff),
+	A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x18400, 0x0053),
+	A6XX_PROTECT_RDONLY(0x18454, 0x0004),
+	A6XX_PROTECT_NORDWR(0x18459, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x1a459, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x1c459, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x1f400, 0x0443),
+	A6XX_PROTECT_RDONLY(0x1f844, 0x007b),
+	A6XX_PROTECT_NORDWR(0x1f860, 0x0000),
+	A6XX_PROTECT_NORDWR(0x1f878, 0x002a),
+	/* CP_PROTECT_REG[45, 46] are left untouched! */
+	0,
+	0,
+	A6XX_PROTECT_NORDWR(0x1f8c0, 0x00000),
+};
+DECLARE_ADRENO_PROTECT(a730_protect, 48);
+
+static const struct adreno_info a7xx_gpus[] = {
+	{
+		.chip_ids = ADRENO_CHIP_IDS(0x07000200),
+		.family = ADRENO_6XX_GEN1, /* NOT a mistake! */
+		.fw = {
+			[ADRENO_FW_SQE] = "a702_sqe.fw",
+		},
+		.gmem = SZ_128K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a702_zap.mbn",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a702_hwcg,
+			.protect = &a650_protect,
+			.gmu_cgc_mode = 0x00020202,
+			.prim_fifo_threshold = 0x0000c000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 236, 1 },
+			{ 178, 2 },
+			{ 142, 3 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x07030001),
+		.family = ADRENO_7XX_GEN1,
+		.fw = {
+			[ADRENO_FW_SQE] = "a730_sqe.fw",
+			[ADRENO_FW_GMU] = "gmu_gen70000.bin",
+		},
+		.gmem = SZ_2M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			  ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a730_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a730_hwcg,
+			.protect = &a730_protect,
+			.gmu_cgc_mode = 0x00020000,
+		},
+		.address_space_size = SZ_16G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x43050a01), /* "C510v2" */
+		.family = ADRENO_7XX_GEN2,
+		.fw = {
+			[ADRENO_FW_SQE] = "a740_sqe.fw",
+			[ADRENO_FW_GMU] = "gmu_gen70200.bin",
+		},
+		.gmem = 3 * SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			  ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a740_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a740_hwcg,
+			.protect = &a730_protect,
+			.gmu_chipid = 0x7020100,
+			.gmu_cgc_mode = 0x00020202,
+		},
+		.address_space_size = SZ_16G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x43050c01), /* "C512v2" */
+		.family = ADRENO_7XX_GEN2,
+		.fw = {
+			[ADRENO_FW_SQE] = "gen70500_sqe.fw",
+			[ADRENO_FW_GMU] = "gen70500_gmu.bin",
+		},
+		.gmem = 3 * SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			  ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a740_hwcg,
+			.protect = &a730_protect,
+			.gmu_chipid = 0x7050001,
+			.gmu_cgc_mode = 0x00020202,
+		},
+		.address_space_size = SZ_256G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x43051401), /* "C520v2" */
+		.family = ADRENO_7XX_GEN3,
+		.fw = {
+			[ADRENO_FW_SQE] = "gen70900_sqe.fw",
+			[ADRENO_FW_GMU] = "gmu_gen70900.bin",
+		},
+		.gmem = 3 * SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			  ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "gen70900_zap.mbn",
+		.a6xx = &(const struct a6xx_info) {
+			.protect = &a730_protect,
+			.gmu_chipid = 0x7090100,
+			.gmu_cgc_mode = 0x00020202,
+		},
+		.address_space_size = SZ_16G,
+	}
+};
+DECLARE_ADRENO_GPULIST(a7xx);
+
+static inline void __build_asserts(void)
+{
+	BUILD_BUG_ON(a630_protect.count > a630_protect.count_max);
+	BUILD_BUG_ON(a650_protect.count > a650_protect.count_max);
+	BUILD_BUG_ON(a660_protect.count > a660_protect.count_max);
+	BUILD_BUG_ON(a690_protect.count > a690_protect.count_max);
+	BUILD_BUG_ON(a730_protect.count > a730_protect.count_max);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -223,7 +223,7 @@
 	 * note: downstream saves the value in poweroff and restores it here
 	 */
 	if (adreno_is_a7xx(adreno_gpu))
-		gmu_write(gmu, REG_A6XX_GMU_GENERAL_9, 0);
+		gmu_write(gmu, REG_A7XX_GMU_GENERAL_9, 0);
 	else
 		gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_RESP, 0);
 
@@ -769,8 +769,9 @@
 {
 	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
 	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	const struct a6xx_info *a6xx_info = adreno_gpu->info->a6xx;
 	u32 fence_range_lower, fence_range_upper;
-	u32 chipid, chipid_min = 0;
+	u32 chipid = 0;
 	int ret;
 
 	/* Vote veto for FAL10 */
@@ -830,25 +831,8 @@
 	 */
 	gmu_write(gmu, REG_A6XX_GMU_CM3_CFG, 0x4052);
 
-	/* NOTE: A730 may also fall in this if-condition with a future GMU fw update. */
-	if (adreno_is_a7xx(adreno_gpu) && !adreno_is_a730(adreno_gpu)) {
-		/* A7xx GPUs have obfuscated chip IDs. Use constant maj = 7 */
-		chipid = FIELD_PREP(GENMASK(31, 24), 0x7);
-
-		/*
-		 * The min part has a 1-1 mapping for each GPU SKU.
-		 * This chipid that the GMU expects corresponds to the "GENX_Y_Z" naming,
-		 * where X = major, Y = minor, Z = patchlevel, e.g. GEN7_2_1 for prod A740.
-		 */
-		if (adreno_is_a740(adreno_gpu))
-			chipid_min = 2;
-		else
-			return -EINVAL;
-
-		chipid |= FIELD_PREP(GENMASK(23, 16), chipid_min);
-
-		/* Get the patchid (which may vary) from the device tree */
-		chipid |= FIELD_PREP(GENMASK(15, 8), adreno_patchid(adreno_gpu));
+	if (a6xx_info->gmu_chipid) {
+		chipid = a6xx_info->gmu_chipid;
 	} else {
 		/*
 		 * Note that the GMU has a slightly different layout for
@@ -863,8 +847,8 @@
 	}
 
 	if (adreno_is_a7xx(adreno_gpu)) {
-		gmu_write(gmu, REG_A6XX_GMU_GENERAL_10, chipid);
-		gmu_write(gmu, REG_A6XX_GMU_GENERAL_8,
+		gmu_write(gmu, REG_A7XX_GMU_GENERAL_10, chipid);
+		gmu_write(gmu, REG_A7XX_GMU_GENERAL_8,
 			  (gmu->log.iova & GENMASK(31, 12)) |
 			  ((gmu->log.size / SZ_4K - 1) & GENMASK(7, 0)));
 	} else {
@@ -1327,7 +1311,13 @@
 	if (!pri_count)
 		return -EINVAL;
 
-	sec = cmd_db_read_aux_data("mx.lvl", &sec_count);
+	/*
+	 * Some targets have a separate gfx mxc rail. So try to read that first and then fall back
+	 * to regular mx rail if it is missing
+	 */
+	sec = cmd_db_read_aux_data("gmxc.lvl", &sec_count);
+	if (IS_ERR(sec) && sec != ERR_PTR(-EPROBE_DEFER))
+		sec = cmd_db_read_aux_data("mx.lvl", &sec_count);
 	if (IS_ERR(sec))
 		return PTR_ERR(sec);
 
@@ -1517,15 +1507,13 @@
 
 	irq = platform_get_irq_byname(pdev, name);
 
-	ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH, name, gmu);
+	ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH | IRQF_NO_AUTOEN, name, gmu);
 	if (ret) {
 		DRM_DEV_ERROR(&pdev->dev, "Unable to get interrupt %s %d\n",
 			      name, ret);
 		return ret;
 	}
 
-	disable_irq(irq);
-
 	return irq;
 }
 
@@ -1600,7 +1588,9 @@
 
 	gmu->dev = &pdev->dev;
 
-	of_dma_configure(gmu->dev, node, true);
+	ret = of_dma_configure(gmu->dev, node, true);
+	if (ret)
+		return ret;
 
 	pm_runtime_enable(gmu->dev);
 
@@ -1665,7 +1655,9 @@
 
 	gmu->dev = &pdev->dev;
 
-	of_dma_configure(gmu->dev, node, true);
+	ret = of_dma_configure(gmu->dev, node, true);
+	if (ret)
+		return ret;
 
 	/* Fow now, don't do anything fancy until we get our feet under us */
 	gmu->idle_level = GMU_IDLE_STATE_ACTIVE;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -100,9 +100,10 @@
 }
 
 static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
-		struct msm_ringbuffer *ring, struct msm_file_private *ctx)
+		struct msm_ringbuffer *ring, struct msm_gem_submit *submit)
 {
 	bool sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1;
+	struct msm_file_private *ctx = submit->queue->ctx;
 	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
 	phys_addr_t ttbr;
 	u32 asid;
@@ -114,6 +115,15 @@
 	if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid))
 		return;
 
+	if (adreno_gpu->info->family >= ADRENO_7XX_GEN1) {
+		/* Wait for previous submit to complete before continuing: */
+		OUT_PKT7(ring, CP_WAIT_TIMESTAMP, 4);
+		OUT_RING(ring, 0);
+		OUT_RING(ring, lower_32_bits(rbmemptr(ring, fence)));
+		OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence)));
+		OUT_RING(ring, submit->seqno - 1);
+	}
+
 	if (!sysprof) {
 		if (!adreno_is_a7xx(adreno_gpu)) {
 			/* Turn off protected mode to write to special registers */
@@ -192,7 +202,7 @@
 	struct msm_ringbuffer *ring = submit->ring;
 	unsigned int i, ibs = 0;
 
-	a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx);
+	a6xx_set_pagetable(a6xx_gpu, ring, submit);
 
 	get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0),
 		rbmemptr_stats(ring, index, cpcycles_start));
@@ -282,9 +292,9 @@
 	OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
 	OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BR);
 
-	a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx);
+	a6xx_set_pagetable(a6xx_gpu, ring, submit);
 
-	get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0),
+	get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0),
 		rbmemptr_stats(ring, index, cpcycles_start));
 	get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER,
 		rbmemptr_stats(ring, index, alwayson_start));
@@ -330,7 +340,7 @@
 	OUT_PKT7(ring, CP_SET_MARKER, 1);
 	OUT_RING(ring, 0x00e); /* IB1LIST end */
 
-	get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0),
+	get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0),
 		rbmemptr_stats(ring, index, cpcycles_end));
 	get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER,
 		rbmemptr_stats(ring, index, alwayson_end));
@@ -394,564 +404,6 @@
 	a6xx_flush(gpu, ring);
 }
 
-const struct adreno_reglist a612_hwcg[] = {
-	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
-	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000081},
-	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
-	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01202222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
-	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05522022},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
-	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
-	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
-	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
-	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
-	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
-	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
-	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
-	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
-	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
-	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
-	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
-	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
-	{},
-};
-
-/* For a615 family (a615, a616, a618 and a619) */
-const struct adreno_reglist a615_hwcg[] = {
-	{REG_A6XX_RBBM_CLOCK_CNTL_SP0,  0x02222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
-	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
-	{REG_A6XX_RBBM_CLOCK_HYST_SP0,  0x0000F3CF},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TP0,  0x02222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TP1,  0x02222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL3_TP1, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
-	{REG_A6XX_RBBM_CLOCK_CNTL4_TP1, 0x00022222},
-	{REG_A6XX_RBBM_CLOCK_HYST_TP0,  0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST_TP1,  0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST2_TP1, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST3_TP1, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
-	{REG_A6XX_RBBM_CLOCK_HYST4_TP1, 0x00077777},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TP1, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY3_TP1, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
-	{REG_A6XX_RBBM_CLOCK_DELAY4_TP1, 0x00011111},
-	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE,  0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222},
-	{REG_A6XX_RBBM_CLOCK_HYST_UCHE,  0x00000004},
-	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002020},
-	{REG_A6XX_RBBM_CLOCK_CNTL_CCU1, 0x00002220},
-	{REG_A6XX_RBBM_CLOCK_CNTL_CCU2, 0x00002220},
-	{REG_A6XX_RBBM_CLOCK_CNTL_CCU3, 0x00002220},
-	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
-	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU1, 0x00040F00},
-	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU2, 0x00040F00},
-	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU3, 0x00040F00},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05022022},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
-	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
-	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
-	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
-	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
-	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
-	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
-	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
-	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
-	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
-	{},
-};
-
-const struct adreno_reglist a630_hwcg[] = {
-	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_SP1, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_SP2, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_SP3, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02022220},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_SP1, 0x02022220},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_SP2, 0x02022220},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_SP3, 0x02022220},
-	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
-	{REG_A6XX_RBBM_CLOCK_DELAY_SP1, 0x00000080},
-	{REG_A6XX_RBBM_CLOCK_DELAY_SP2, 0x00000080},
-	{REG_A6XX_RBBM_CLOCK_DELAY_SP3, 0x00000080},
-	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf},
-	{REG_A6XX_RBBM_CLOCK_HYST_SP1, 0x0000f3cf},
-	{REG_A6XX_RBBM_CLOCK_HYST_SP2, 0x0000f3cf},
-	{REG_A6XX_RBBM_CLOCK_HYST_SP3, 0x0000f3cf},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x02222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TP1, 0x02222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TP2, 0x02222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TP3, 0x02222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_TP2, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_TP3, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL3_TP1, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL3_TP2, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL3_TP3, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
-	{REG_A6XX_RBBM_CLOCK_CNTL4_TP1, 0x00022222},
-	{REG_A6XX_RBBM_CLOCK_CNTL4_TP2, 0x00022222},
-	{REG_A6XX_RBBM_CLOCK_CNTL4_TP3, 0x00022222},
-	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST_TP1, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST_TP2, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST_TP3, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST2_TP1, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST2_TP2, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST2_TP3, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST3_TP1, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST3_TP2, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST3_TP3, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
-	{REG_A6XX_RBBM_CLOCK_HYST4_TP1, 0x00077777},
-	{REG_A6XX_RBBM_CLOCK_HYST4_TP2, 0x00077777},
-	{REG_A6XX_RBBM_CLOCK_HYST4_TP3, 0x00077777},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TP1, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TP2, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TP3, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY2_TP2, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY2_TP3, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY3_TP1, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY3_TP2, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY3_TP3, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
-	{REG_A6XX_RBBM_CLOCK_DELAY4_TP1, 0x00011111},
-	{REG_A6XX_RBBM_CLOCK_DELAY4_TP2, 0x00011111},
-	{REG_A6XX_RBBM_CLOCK_DELAY4_TP3, 0x00011111},
-	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222},
-	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
-	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RB1, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RB2, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RB3, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RB1, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RB2, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RB3, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
-	{REG_A6XX_RBBM_CLOCK_CNTL_CCU1, 0x00002220},
-	{REG_A6XX_RBBM_CLOCK_CNTL_CCU2, 0x00002220},
-	{REG_A6XX_RBBM_CLOCK_CNTL_CCU3, 0x00002220},
-	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00},
-	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU1, 0x00040f00},
-	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU2, 0x00040f00},
-	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU3, 0x00040f00},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05022022},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
-	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
-	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
-	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
-	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
-	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
-	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
-	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
-	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
-	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
-	{},
-};
-
-const struct adreno_reglist a640_hwcg[] = {
-	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
-	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
-	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x02222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
-	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
-	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05222022},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
-	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
-	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
-	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
-	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
-	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
-	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
-	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
-	{REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
-	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
-	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
-	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
-	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
-	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
-	{},
-};
-
-const struct adreno_reglist a650_hwcg[] = {
-	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
-	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
-	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x02222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
-	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
-	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
-	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
-	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
-	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
-	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
-	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
-	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
-	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
-	{REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000777},
-	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
-	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
-	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
-	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
-	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
-	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
-	{},
-};
-
-const struct adreno_reglist a660_hwcg[] = {
-	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
-	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
-	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
-	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
-	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
-	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
-	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
-	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
-	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
-	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
-	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
-	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
-	{REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
-	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
-	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
-	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
-	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
-	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
-	{},
-};
-
-const struct adreno_reglist a690_hwcg[] = {
-	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
-	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
-	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
-	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
-	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
-	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
-	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
-	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
-	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022},
-	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
-	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
-	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
-	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
-	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
-	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
-	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
-	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
-	{REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
-	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
-	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
-	{REG_A6XX_RBBM_CLOCK_CNTL, 0x8AA8AA82},
-	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
-	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
-	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
-	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
-	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
-	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
-	{REG_A6XX_GPU_GMU_AO_GMU_CGC_MODE_CNTL, 0x20200},
-	{REG_A6XX_GPU_GMU_AO_GMU_CGC_DELAY_CNTL, 0x10111},
-	{REG_A6XX_GPU_GMU_AO_GMU_CGC_HYST_CNTL, 0x5555},
-	{}
-};
-
-const struct adreno_reglist a730_hwcg[] = {
-	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02022222 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222220 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00222222 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
-	{ REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
-	{ REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777 },
-	{ REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x44000f00 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00555555 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00440044 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222 },
-	{ REG_A7XX_RBBM_CLOCK_MODE2_GRAS, 0x00000222 },
-	{ REG_A7XX_RBBM_CLOCK_MODE_BV_GRAS, 0x00222222 },
-	{ REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222223 },
-	{ REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222 },
-	{ REG_A7XX_RBBM_CLOCK_MODE_BV_GPC, 0x00222222 },
-	{ REG_A7XX_RBBM_CLOCK_MODE_BV_VFD, 0x00002222 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222 },
-	{ REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002 },
-	{ REG_A7XX_RBBM_CLOCK_MODE_BV_LRZ, 0x55555552 },
-	{ REG_A7XX_RBBM_CLOCK_MODE_CP, 0x00000223 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL, 0x8aa8aa82 },
-	{ REG_A6XX_RBBM_ISDB_CNT, 0x00000182 },
-	{ REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000 },
-	{ REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555 },
-	{},
-};
-
-const struct adreno_reglist a740_hwcg[] = {
-	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x22022222 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x003cf3cf },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222220 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00222222 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
-	{ REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
-	{ REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777 },
-	{ REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL2_UCHE, 0x00222222 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000444 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000222 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x44000f00 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00555555 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00440044 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222 },
-	{ REG_A7XX_RBBM_CLOCK_MODE2_GRAS, 0x00000222 },
-	{ REG_A7XX_RBBM_CLOCK_MODE_BV_GRAS, 0x00222222 },
-	{ REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222223 },
-	{ REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00222222 },
-	{ REG_A7XX_RBBM_CLOCK_MODE_BV_GPC, 0x00222222 },
-	{ REG_A7XX_RBBM_CLOCK_MODE_BV_VFD, 0x00002222 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00000000 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00000000 },
-	{ REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000 },
-	{ REG_A7XX_RBBM_CLOCK_MODE_BV_LRZ, 0x55555552 },
-	{ REG_A7XX_RBBM_CLOCK_HYST2_VFD, 0x00000000 },
-	{ REG_A7XX_RBBM_CLOCK_MODE_CP, 0x00000222 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL, 0x8aa8aa82 },
-	{ REG_A6XX_RBBM_ISDB_CNT, 0x00000182 },
-	{ REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000 },
-	{ REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000 },
-	{ REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222 },
-	{ REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111 },
-	{ REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555 },
-	{},
-};
-
 static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
 {
 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -961,13 +413,15 @@
 	unsigned int i;
 	u32 val, clock_cntl_on, cgc_mode;
 
-	if (!adreno_gpu->info->hwcg)
+	if (!(adreno_gpu->info->a6xx->hwcg || adreno_is_a7xx(adreno_gpu)))
 		return;
 
 	if (adreno_is_a630(adreno_gpu))
 		clock_cntl_on = 0x8aa8aa02;
 	else if (adreno_is_a610(adreno_gpu))
 		clock_cntl_on = 0xaaa8aa82;
+	else if (adreno_is_a702(adreno_gpu))
+		clock_cntl_on = 0xaaaaaa82;
 	else
 		clock_cntl_on = 0x8aa8aa82;
 
@@ -982,6 +436,25 @@
 			  state ? 0x5555 : 0);
 	}
 
+	if (!adreno_gpu->info->a6xx->hwcg) {
+		gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
+		gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
+
+		if (state) {
+			gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
+
+			if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
+					     val & A7XX_RBBM_CGC_P2S_STATUS_TXDONE, 1, 10)) {
+				dev_err(&gpu->pdev->dev, "RBBM_CGC_P2S_STATUS TXDONE Poll failed\n");
+				return;
+			}
+
+			gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 0);
+		}
+
+		return;
+	}
+
 	val = gpu_read(gpu, REG_A6XX_RBBM_CLOCK_CNTL);
 
 	/* Don't re-program the registers if they are already correct */
@@ -989,267 +462,24 @@
 		return;
 
 	/* Disable SP clock before programming HWCG registers */
-	if (!adreno_is_a610(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
+	if (!adreno_is_a610_family(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
 		gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 1, 0);
 
-	for (i = 0; (reg = &adreno_gpu->info->hwcg[i], reg->offset); i++)
+	for (i = 0; (reg = &adreno_gpu->info->a6xx->hwcg[i], reg->offset); i++)
 		gpu_write(gpu, reg->offset, state ? reg->value : 0);
 
 	/* Enable SP clock */
-	if (!adreno_is_a610(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
+	if (!adreno_is_a610_family(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
 		gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 0, 1);
 
 	gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? clock_cntl_on : 0);
 }
 
-/* For a615, a616, a618, a619, a630, a640 and a680 */
-static const u32 a6xx_protect[] = {
-	A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
-	A6XX_PROTECT_RDONLY(0x00501, 0x0005),
-	A6XX_PROTECT_RDONLY(0x0050b, 0x02f4),
-	A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
-	A6XX_PROTECT_NORDWR(0x00510, 0x0000),
-	A6XX_PROTECT_NORDWR(0x00534, 0x0000),
-	A6XX_PROTECT_NORDWR(0x00800, 0x0082),
-	A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
-	A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
-	A6XX_PROTECT_RDONLY(0x008de, 0x00ae),
-	A6XX_PROTECT_NORDWR(0x00900, 0x004d),
-	A6XX_PROTECT_NORDWR(0x0098d, 0x0272),
-	A6XX_PROTECT_NORDWR(0x00e00, 0x0001),
-	A6XX_PROTECT_NORDWR(0x00e03, 0x000c),
-	A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
-	A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
-	A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
-	A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
-	A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
-	A6XX_PROTECT_NORDWR(0x09624, 0x01db),
-	A6XX_PROTECT_NORDWR(0x09e70, 0x0001),
-	A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
-	A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
-	A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
-	A6XX_PROTECT_NORDWR(0x0ae50, 0x032f),
-	A6XX_PROTECT_NORDWR(0x0b604, 0x0000),
-	A6XX_PROTECT_NORDWR(0x0be02, 0x0001),
-	A6XX_PROTECT_NORDWR(0x0be20, 0x17df),
-	A6XX_PROTECT_NORDWR(0x0f000, 0x0bff),
-	A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x11c00, 0x0000), /* note: infinite range */
-};
-
-/* These are for a620 and a650 */
-static const u32 a650_protect[] = {
-	A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
-	A6XX_PROTECT_RDONLY(0x00501, 0x0005),
-	A6XX_PROTECT_RDONLY(0x0050b, 0x02f4),
-	A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
-	A6XX_PROTECT_NORDWR(0x00510, 0x0000),
-	A6XX_PROTECT_NORDWR(0x00534, 0x0000),
-	A6XX_PROTECT_NORDWR(0x00800, 0x0082),
-	A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
-	A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
-	A6XX_PROTECT_RDONLY(0x008de, 0x00ae),
-	A6XX_PROTECT_NORDWR(0x00900, 0x004d),
-	A6XX_PROTECT_NORDWR(0x0098d, 0x0272),
-	A6XX_PROTECT_NORDWR(0x00e00, 0x0001),
-	A6XX_PROTECT_NORDWR(0x00e03, 0x000c),
-	A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
-	A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
-	A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
-	A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
-	A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
-	A6XX_PROTECT_NORDWR(0x08e80, 0x027f),
-	A6XX_PROTECT_NORDWR(0x09624, 0x01db),
-	A6XX_PROTECT_NORDWR(0x09e60, 0x0011),
-	A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
-	A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
-	A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
-	A6XX_PROTECT_NORDWR(0x0ae50, 0x032f),
-	A6XX_PROTECT_NORDWR(0x0b604, 0x0000),
-	A6XX_PROTECT_NORDWR(0x0b608, 0x0007),
-	A6XX_PROTECT_NORDWR(0x0be02, 0x0001),
-	A6XX_PROTECT_NORDWR(0x0be20, 0x17df),
-	A6XX_PROTECT_NORDWR(0x0f000, 0x0bff),
-	A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x18400, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x1a800, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x1f400, 0x0443),
-	A6XX_PROTECT_RDONLY(0x1f844, 0x007b),
-	A6XX_PROTECT_NORDWR(0x1f887, 0x001b),
-	A6XX_PROTECT_NORDWR(0x1f8c0, 0x0000), /* note: infinite range */
-};
-
-/* These are for a635 and a660 */
-static const u32 a660_protect[] = {
-	A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
-	A6XX_PROTECT_RDONLY(0x00501, 0x0005),
-	A6XX_PROTECT_RDONLY(0x0050b, 0x02f4),
-	A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
-	A6XX_PROTECT_NORDWR(0x00510, 0x0000),
-	A6XX_PROTECT_NORDWR(0x00534, 0x0000),
-	A6XX_PROTECT_NORDWR(0x00800, 0x0082),
-	A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
-	A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
-	A6XX_PROTECT_RDONLY(0x008de, 0x00ae),
-	A6XX_PROTECT_NORDWR(0x00900, 0x004d),
-	A6XX_PROTECT_NORDWR(0x0098d, 0x0272),
-	A6XX_PROTECT_NORDWR(0x00e00, 0x0001),
-	A6XX_PROTECT_NORDWR(0x00e03, 0x000c),
-	A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
-	A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
-	A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
-	A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
-	A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
-	A6XX_PROTECT_NORDWR(0x08e80, 0x027f),
-	A6XX_PROTECT_NORDWR(0x09624, 0x01db),
-	A6XX_PROTECT_NORDWR(0x09e60, 0x0011),
-	A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
-	A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
-	A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
-	A6XX_PROTECT_NORDWR(0x0ae50, 0x012f),
-	A6XX_PROTECT_NORDWR(0x0b604, 0x0000),
-	A6XX_PROTECT_NORDWR(0x0b608, 0x0006),
-	A6XX_PROTECT_NORDWR(0x0be02, 0x0001),
-	A6XX_PROTECT_NORDWR(0x0be20, 0x015f),
-	A6XX_PROTECT_NORDWR(0x0d000, 0x05ff),
-	A6XX_PROTECT_NORDWR(0x0f000, 0x0bff),
-	A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x18400, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x1a400, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x1f400, 0x0443),
-	A6XX_PROTECT_RDONLY(0x1f844, 0x007b),
-	A6XX_PROTECT_NORDWR(0x1f860, 0x0000),
-	A6XX_PROTECT_NORDWR(0x1f887, 0x001b),
-	A6XX_PROTECT_NORDWR(0x1f8c0, 0x0000), /* note: infinite range */
-};
-
-/* These are for a690 */
-static const u32 a690_protect[] = {
-	A6XX_PROTECT_RDONLY(0x00000, 0x004ff),
-	A6XX_PROTECT_RDONLY(0x00501, 0x00001),
-	A6XX_PROTECT_RDONLY(0x0050b, 0x002f4),
-	A6XX_PROTECT_NORDWR(0x0050e, 0x00000),
-	A6XX_PROTECT_NORDWR(0x00510, 0x00000),
-	A6XX_PROTECT_NORDWR(0x00534, 0x00000),
-	A6XX_PROTECT_NORDWR(0x00800, 0x00082),
-	A6XX_PROTECT_NORDWR(0x008a0, 0x00008),
-	A6XX_PROTECT_NORDWR(0x008ab, 0x00024),
-	A6XX_PROTECT_RDONLY(0x008de, 0x000ae),
-	A6XX_PROTECT_NORDWR(0x00900, 0x0004d),
-	A6XX_PROTECT_NORDWR(0x0098d, 0x00272),
-	A6XX_PROTECT_NORDWR(0x00e00, 0x00001),
-	A6XX_PROTECT_NORDWR(0x00e03, 0x0000c),
-	A6XX_PROTECT_NORDWR(0x03c00, 0x000c3),
-	A6XX_PROTECT_RDONLY(0x03cc4, 0x01fff),
-	A6XX_PROTECT_NORDWR(0x08630, 0x001cf),
-	A6XX_PROTECT_NORDWR(0x08e00, 0x00000),
-	A6XX_PROTECT_NORDWR(0x08e08, 0x00007),
-	A6XX_PROTECT_NORDWR(0x08e50, 0x0001f),
-	A6XX_PROTECT_NORDWR(0x08e80, 0x0027f),
-	A6XX_PROTECT_NORDWR(0x09624, 0x001db),
-	A6XX_PROTECT_NORDWR(0x09e60, 0x00011),
-	A6XX_PROTECT_NORDWR(0x09e78, 0x00187),
-	A6XX_PROTECT_NORDWR(0x0a630, 0x001cf),
-	A6XX_PROTECT_NORDWR(0x0ae02, 0x00000),
-	A6XX_PROTECT_NORDWR(0x0ae50, 0x0012f),
-	A6XX_PROTECT_NORDWR(0x0b604, 0x00000),
-	A6XX_PROTECT_NORDWR(0x0b608, 0x00006),
-	A6XX_PROTECT_NORDWR(0x0be02, 0x00001),
-	A6XX_PROTECT_NORDWR(0x0be20, 0x0015f),
-	A6XX_PROTECT_NORDWR(0x0d000, 0x005ff),
-	A6XX_PROTECT_NORDWR(0x0f000, 0x00bff),
-	A6XX_PROTECT_RDONLY(0x0fc00, 0x01fff),
-	A6XX_PROTECT_NORDWR(0x11c00, 0x00000), /*note: infiite range */
-};
-
-static const u32 a730_protect[] = {
-	A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
-	A6XX_PROTECT_RDONLY(0x0050b, 0x0058),
-	A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
-	A6XX_PROTECT_NORDWR(0x00510, 0x0000),
-	A6XX_PROTECT_NORDWR(0x00534, 0x0000),
-	A6XX_PROTECT_RDONLY(0x005fb, 0x009d),
-	A6XX_PROTECT_NORDWR(0x00699, 0x01e9),
-	A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
-	A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
-	/* 0x008d0-0x008dd are unprotected on purpose for tools like perfetto */
-	A6XX_PROTECT_RDONLY(0x008de, 0x0154),
-	A6XX_PROTECT_NORDWR(0x00900, 0x004d),
-	A6XX_PROTECT_NORDWR(0x0098d, 0x00b2),
-	A6XX_PROTECT_NORDWR(0x00a41, 0x01be),
-	A6XX_PROTECT_NORDWR(0x00df0, 0x0001),
-	A6XX_PROTECT_NORDWR(0x00e01, 0x0000),
-	A6XX_PROTECT_NORDWR(0x00e07, 0x0008),
-	A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
-	A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
-	A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
-	A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
-	A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
-	A6XX_PROTECT_NORDWR(0x08e80, 0x0280),
-	A6XX_PROTECT_NORDWR(0x09624, 0x01db),
-	A6XX_PROTECT_NORDWR(0x09e40, 0x0000),
-	A6XX_PROTECT_NORDWR(0x09e64, 0x000d),
-	A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
-	A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
-	A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
-	A6XX_PROTECT_NORDWR(0x0ae50, 0x000f),
-	A6XX_PROTECT_NORDWR(0x0ae66, 0x0003),
-	A6XX_PROTECT_NORDWR(0x0ae6f, 0x0003),
-	A6XX_PROTECT_NORDWR(0x0b604, 0x0003),
-	A6XX_PROTECT_NORDWR(0x0ec00, 0x0fff),
-	A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x18400, 0x0053),
-	A6XX_PROTECT_RDONLY(0x18454, 0x0004),
-	A6XX_PROTECT_NORDWR(0x18459, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x1a459, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x1c459, 0x1fff),
-	A6XX_PROTECT_NORDWR(0x1f400, 0x0443),
-	A6XX_PROTECT_RDONLY(0x1f844, 0x007b),
-	A6XX_PROTECT_NORDWR(0x1f860, 0x0000),
-	A6XX_PROTECT_NORDWR(0x1f878, 0x002a),
-	/* CP_PROTECT_REG[44, 46] are left untouched! */
-	0,
-	0,
-	0,
-	A6XX_PROTECT_NORDWR(0x1f8c0, 0x00000),
-};
-
 static void a6xx_set_cp_protect(struct msm_gpu *gpu)
 {
 	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
-	const u32 *regs = a6xx_protect;
-	unsigned i, count, count_max;
-
-	if (adreno_is_a650(adreno_gpu)) {
-		regs = a650_protect;
-		count = ARRAY_SIZE(a650_protect);
-		count_max = 48;
-		BUILD_BUG_ON(ARRAY_SIZE(a650_protect) > 48);
-	} else if (adreno_is_a690(adreno_gpu)) {
-		regs = a690_protect;
-		count = ARRAY_SIZE(a690_protect);
-		count_max = 48;
-		BUILD_BUG_ON(ARRAY_SIZE(a690_protect) > 48);
-	} else if (adreno_is_a660_family(adreno_gpu)) {
-		regs = a660_protect;
-		count = ARRAY_SIZE(a660_protect);
-		count_max = 48;
-		BUILD_BUG_ON(ARRAY_SIZE(a660_protect) > 48);
-	} else if (adreno_is_a730(adreno_gpu) || adreno_is_a740(adreno_gpu)) {
-		regs = a730_protect;
-		count = ARRAY_SIZE(a730_protect);
-		count_max = 48;
-		BUILD_BUG_ON(ARRAY_SIZE(a730_protect) > 48);
-	} else {
-		regs = a6xx_protect;
-		count = ARRAY_SIZE(a6xx_protect);
-		count_max = 32;
-		BUILD_BUG_ON(ARRAY_SIZE(a6xx_protect) > 32);
-	}
+	const struct adreno_protect *protect = adreno_gpu->info->a6xx->protect;
+	unsigned i;
 
 	/*
 	 * Enable access protection to privileged registers, fault on an access
@@ -1261,40 +491,36 @@
 		  A6XX_CP_PROTECT_CNTL_ACCESS_FAULT_ON_VIOL_EN |
 		  A6XX_CP_PROTECT_CNTL_LAST_SPAN_INF_RANGE);
 
-	for (i = 0; i < count - 1; i++) {
+	for (i = 0; i < protect->count - 1; i++) {
 		/* Intentionally skip writing to some registers */
-		if (regs[i])
-			gpu_write(gpu, REG_A6XX_CP_PROTECT(i), regs[i]);
+		if (protect->regs[i])
+			gpu_write(gpu, REG_A6XX_CP_PROTECT(i), protect->regs[i]);
 	}
 	/* last CP_PROTECT to have "infinite" length on the last entry */
-	gpu_write(gpu, REG_A6XX_CP_PROTECT(count_max - 1), regs[i]);
+	gpu_write(gpu, REG_A6XX_CP_PROTECT(protect->count_max - 1), protect->regs[i]);
 }
 
 static void a6xx_calc_ubwc_config(struct adreno_gpu *gpu)
 {
-	/* Unknown, introduced with A650 family, related to UBWC mode/ver 4 */
 	gpu->ubwc_config.rgb565_predicator = 0;
-	/* Unknown, introduced with A650 family */
 	gpu->ubwc_config.uavflagprd_inv = 0;
-	/* Whether the minimum access length is 64 bits */
 	gpu->ubwc_config.min_acc_len = 0;
-	/* Entirely magic, per-GPU-gen value */
-	gpu->ubwc_config.ubwc_mode = 0;
-	/*
-	 * The Highest Bank Bit value represents the bit of the highest DDR bank.
-	 * This should ideally use DRAM type detection.
-	 */
+	gpu->ubwc_config.ubwc_swizzle = 0x6;
+	gpu->ubwc_config.macrotile_mode = 0;
 	gpu->ubwc_config.highest_bank_bit = 15;
 
 	if (adreno_is_a610(gpu)) {
 		gpu->ubwc_config.highest_bank_bit = 13;
 		gpu->ubwc_config.min_acc_len = 1;
-		gpu->ubwc_config.ubwc_mode = 1;
+		gpu->ubwc_config.ubwc_swizzle = 0x7;
 	}
 
-	/* a618 is using the hw default values */
 	if (adreno_is_a618(gpu))
-		return;
+		gpu->ubwc_config.highest_bank_bit = 14;
+
+	if (adreno_is_a619(gpu))
+		/* TODO: Should be 14 but causes corruption at e.g. 1920x1200 on DP */
+		gpu->ubwc_config.highest_bank_bit = 13;
 
 	if (adreno_is_a619_holi(gpu))
 		gpu->ubwc_config.highest_bank_bit = 13;
@@ -1312,6 +538,16 @@
 		gpu->ubwc_config.amsbc = 1;
 		gpu->ubwc_config.rgb565_predicator = 1;
 		gpu->ubwc_config.uavflagprd_inv = 2;
+		gpu->ubwc_config.macrotile_mode = 1;
+	}
+
+	if (adreno_is_a663(gpu)) {
+		gpu->ubwc_config.highest_bank_bit = 13;
+		gpu->ubwc_config.amsbc = 1;
+		gpu->ubwc_config.rgb565_predicator = 1;
+		gpu->ubwc_config.uavflagprd_inv = 2;
+		gpu->ubwc_config.macrotile_mode = 1;
+		gpu->ubwc_config.ubwc_swizzle = 0x4;
 	}
 
 	if (adreno_is_7c3(gpu)) {
@@ -1319,6 +555,12 @@
 		gpu->ubwc_config.amsbc = 1;
 		gpu->ubwc_config.rgb565_predicator = 1;
 		gpu->ubwc_config.uavflagprd_inv = 2;
+		gpu->ubwc_config.macrotile_mode = 1;
+	}
+
+	if (adreno_is_a702(gpu)) {
+		gpu->ubwc_config.highest_bank_bit = 14;
+		gpu->ubwc_config.min_acc_len = 1;
 	}
 }
 
@@ -1334,21 +576,26 @@
 	u32 hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13;
 	u32 hbb_hi = hbb >> 2;
 	u32 hbb_lo = hbb & 3;
+	u32 ubwc_mode = adreno_gpu->ubwc_config.ubwc_swizzle & 1;
+	u32 level2_swizzling_dis = !(adreno_gpu->ubwc_config.ubwc_swizzle & 2);
 
 	gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL,
+		  level2_swizzling_dis << 12 |
 		  adreno_gpu->ubwc_config.rgb565_predicator << 11 |
 		  hbb_hi << 10 | adreno_gpu->ubwc_config.amsbc << 4 |
 		  adreno_gpu->ubwc_config.min_acc_len << 3 |
-		  hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode);
+		  hbb_lo << 1 | ubwc_mode);
 
-	gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL, hbb_hi << 4 |
+	gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL,
+		  level2_swizzling_dis << 6 | hbb_hi << 4 |
 		  adreno_gpu->ubwc_config.min_acc_len << 3 |
-		  hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode);
+		  hbb_lo << 1 | ubwc_mode);
 
-	gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL, hbb_hi << 10 |
+	gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL,
+		  level2_swizzling_dis << 12 | hbb_hi << 10 |
 		  adreno_gpu->ubwc_config.uavflagprd_inv << 4 |
 		  adreno_gpu->ubwc_config.min_acc_len << 3 |
-		  hbb_lo << 1 | adreno_gpu->ubwc_config.ubwc_mode);
+		  hbb_lo << 1 | ubwc_mode);
 
 	if (adreno_is_a7xx(adreno_gpu))
 		gpu_write(gpu, REG_A7XX_GRAS_NC_MODE_CNTL,
@@ -1356,6 +603,9 @@
 
 	gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL,
 		  adreno_gpu->ubwc_config.min_acc_len << 23 | hbb_lo << 21);
+
+	gpu_write(gpu, REG_A6XX_RBBM_NC_MODE_CNTL,
+		  adreno_gpu->ubwc_config.macrotile_mode);
 }
 
 static int a6xx_cp_init(struct msm_gpu *gpu)
@@ -1453,7 +703,7 @@
 		return false;
 
 	/* A7xx is safe! */
-	if (adreno_is_a7xx(adreno_gpu))
+	if (adreno_is_a7xx(adreno_gpu) || adreno_is_a702(adreno_gpu))
 		return true;
 
 	/*
@@ -1671,7 +921,7 @@
 	a6xx_set_hwcg(gpu, true);
 
 	/* VBIF/GBIF start*/
-	if (adreno_is_a610(adreno_gpu) ||
+	if (adreno_is_a610_family(adreno_gpu) ||
 	    adreno_is_a640_family(adreno_gpu) ||
 	    adreno_is_a650_family(adreno_gpu) ||
 	    adreno_is_a7xx(adreno_gpu)) {
@@ -1705,6 +955,7 @@
 	}
 
 	if (!(adreno_is_a650_family(adreno_gpu) ||
+	      adreno_is_a702(adreno_gpu) ||
 	      adreno_is_a730(adreno_gpu))) {
 		gmem_range_min = adreno_is_a740_family(adreno_gpu) ? SZ_16M : SZ_1M;
 
@@ -1725,7 +976,7 @@
 	if (adreno_is_a640_family(adreno_gpu) || adreno_is_a650_family(adreno_gpu)) {
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140);
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
-	} else if (adreno_is_a610(adreno_gpu)) {
+	} else if (adreno_is_a610_family(adreno_gpu)) {
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x00800060);
 		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x40201b16);
 	} else if (!adreno_is_a7xx(adreno_gpu)) {
@@ -1740,26 +991,17 @@
 	if (adreno_is_a610(adreno_gpu)) {
 		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 48);
 		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_DBG_ADDR, 47);
+	} else if (adreno_is_a702(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 64);
+		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_DBG_ADDR, 63);
 	} else if (!adreno_is_a7xx(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 128);
 
-	/* Setting the primFifo thresholds default values,
-	 * and vccCacheSkipDis=1 bit (0x200) for A640 and newer
-	*/
-	if (adreno_is_a690(adreno_gpu))
-		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00800200);
-	else if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu))
-		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200);
-	else if (adreno_is_a640_family(adreno_gpu) || adreno_is_7c3(adreno_gpu))
-		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00200200);
-	else if (adreno_is_a650(adreno_gpu) || adreno_is_a660(adreno_gpu))
-		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00300200);
-	else if (adreno_is_a619(adreno_gpu))
-		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00018000);
-	else if (adreno_is_a610(adreno_gpu))
-		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00080000);
-	else if (!adreno_is_a7xx(adreno_gpu))
-		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL, 0x00180000);
+
+	/* Set the default primFifo threshold values */
+	if (adreno_gpu->info->a6xx->prim_fifo_threshold)
+		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL,
+			  adreno_gpu->info->a6xx->prim_fifo_threshold);
 
 	/* Set the AHB default slave response to "ERROR" */
 	gpu_write(gpu, REG_A6XX_CP_AHB_CNTL, 0x1);
@@ -1786,7 +1028,7 @@
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x4fffff);
 	else if (adreno_is_a619(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3fffff);
-	else if (adreno_is_a610(adreno_gpu))
+	else if (adreno_is_a610(adreno_gpu) || adreno_is_a702(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3ffff);
 	else
 		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x1fffff);
@@ -1794,7 +1036,7 @@
 	gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, BIT(7) | 0x1);
 
 	/* Set weights for bicubic filtering */
-	if (adreno_is_a650_family(adreno_gpu)) {
+	if (adreno_is_a650_family(adreno_gpu) || adreno_is_x185(adreno_gpu)) {
 		gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_0, 0);
 		gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_1,
 			0x3fe05ff4);
@@ -1822,12 +1064,15 @@
 		else
 			gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1);
 		gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x0);
+	} else if (adreno_is_a702(adreno_gpu)) {
+		/* Something to do with the HLSQ cluster */
+		gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, BIT(24));
 	}
 
 	if (adreno_is_a690(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x90);
 	/* Set dualQ + disable afull for A660 GPU */
-	else if (adreno_is_a660(adreno_gpu))
+	else if (adreno_is_a660(adreno_gpu) || adreno_is_a663(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x66906);
 	else if (adreno_is_a7xx(adreno_gpu))
 		gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG,
@@ -2427,7 +1672,7 @@
 
 	msm_devfreq_resume(gpu);
 
-	adreno_is_a7xx(adreno_gpu) ? a7xx_llc_activate : a6xx_llc_activate(a6xx_gpu);
+	adreno_is_a7xx(adreno_gpu) ? a7xx_llc_activate(a6xx_gpu) : a6xx_llc_activate(a6xx_gpu);
 
 	return ret;
 }
@@ -2880,13 +2125,15 @@
 
 	/* gpu->info only gets assigned in adreno_gpu_init() */
 	is_a7xx = config->info->family == ADRENO_7XX_GEN1 ||
-		  config->info->family == ADRENO_7XX_GEN2;
+		  config->info->family == ADRENO_7XX_GEN2 ||
+		  config->info->family == ADRENO_7XX_GEN3;
 
 	a6xx_llc_slices_init(pdev, a6xx_gpu, is_a7xx);
 
 	ret = a6xx_set_supported_hw(&pdev->dev, config->info);
 	if (ret) {
-		a6xx_destroy(&(a6xx_gpu->base.base));
+		a6xx_llc_slices_destroy(a6xx_gpu);
+		kfree(a6xx_gpu);
 		return ERR_PTR(ret);
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
@@ -12,6 +12,20 @@
 
 extern bool hang_debug;
 
+/**
+ * struct a6xx_info - a6xx specific information from device table
+ *
+ * @hwcg: hw clock gating register sequence
+ * @protect: CP_PROTECT settings
+ */
+struct a6xx_info {
+	const struct adreno_reglist *hwcg;
+	const struct adreno_protect *protect;
+	u32 gmu_chipid;
+	u32 gmu_cgc_mode;
+	u32 prim_fifo_threshold;
+};
+
 struct a6xx_gpu {
 	struct adreno_gpu base;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/a6xx_hfi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/a6xx_hfi.c
@@ -478,6 +478,37 @@
 	msg->cnoc_cmds_data[1][0] =  0x60000001;
 }
 
+static void a663_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
+{
+	/*
+	 * Send a single "off" entry just to get things running
+	 * TODO: bus scaling
+	 */
+	msg->bw_level_num = 1;
+
+	msg->ddr_cmds_num = 3;
+	msg->ddr_wait_bitmask = 0x07;
+
+	msg->ddr_cmds_addrs[0] = 0x50004;
+	msg->ddr_cmds_addrs[1] = 0x50000;
+	msg->ddr_cmds_addrs[2] = 0x500b4;
+
+	msg->ddr_cmds_data[0][0] =  0x40000000;
+	msg->ddr_cmds_data[0][1] =  0x40000000;
+	msg->ddr_cmds_data[0][2] =  0x40000000;
+
+	/*
+	 * These are the CX (CNOC) votes - these are used by the GMU but the
+	 * votes are known and fixed for the target
+	 */
+	msg->cnoc_cmds_num = 1;
+	msg->cnoc_wait_bitmask = 0x01;
+
+	msg->cnoc_cmds_addrs[0] = 0x50058;
+	msg->cnoc_cmds_data[0][0] =  0x40000000;
+	msg->cnoc_cmds_data[1][0] =  0x60000001;
+}
+
 static void adreno_7c3_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
 {
 	/*
@@ -646,6 +677,8 @@
 		adreno_7c3_build_bw_table(&msg);
 	else if (adreno_is_a660(adreno_gpu))
 		a660_build_bw_table(&msg);
+	else if (adreno_is_a663(adreno_gpu))
+		a663_build_bw_table(&msg);
 	else if (adreno_is_a690(adreno_gpu))
 		a690_build_bw_table(&msg);
 	else if (adreno_is_a730(adreno_gpu))
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/adreno_device.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/adreno_device.c
@@ -20,549 +20,36 @@
 MODULE_PARM_DESC(allow_vram_carveout, "Allow using VRAM Carveout, in place of IOMMU");
 module_param_named(allow_vram_carveout, allow_vram_carveout, bool, 0600);
 
-static const struct adreno_info gpulist[] = {
-	{
-		.chip_ids = ADRENO_CHIP_IDS(0x02000000),
-		.family = ADRENO_2XX_GEN1,
-		.revn  = 200,
-		.fw = {
-			[ADRENO_FW_PM4] = "yamato_pm4.fw",
-			[ADRENO_FW_PFP] = "yamato_pfp.fw",
-		},
-		.gmem  = SZ_256K,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.init  = a2xx_gpu_init,
-	}, { /* a200 on i.mx51 has only 128kib gmem */
-		.chip_ids = ADRENO_CHIP_IDS(0x02000001),
-		.family = ADRENO_2XX_GEN1,
-		.revn  = 201,
-		.fw = {
-			[ADRENO_FW_PM4] = "yamato_pm4.fw",
-			[ADRENO_FW_PFP] = "yamato_pfp.fw",
-		},
-		.gmem  = SZ_128K,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.init  = a2xx_gpu_init,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x02020000),
-		.family = ADRENO_2XX_GEN2,
-		.revn  = 220,
-		.fw = {
-			[ADRENO_FW_PM4] = "leia_pm4_470.fw",
-			[ADRENO_FW_PFP] = "leia_pfp_470.fw",
-		},
-		.gmem  = SZ_512K,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.init  = a2xx_gpu_init,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(
-			0x03000512,
-			0x03000520
-		),
-		.family = ADRENO_3XX,
-		.revn  = 305,
-		.fw = {
-			[ADRENO_FW_PM4] = "a300_pm4.fw",
-			[ADRENO_FW_PFP] = "a300_pfp.fw",
-		},
-		.gmem  = SZ_256K,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.init  = a3xx_gpu_init,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x03000600),
-		.family = ADRENO_3XX,
-		.revn  = 307,        /* because a305c is revn==306 */
-		.fw = {
-			[ADRENO_FW_PM4] = "a300_pm4.fw",
-			[ADRENO_FW_PFP] = "a300_pfp.fw",
-		},
-		.gmem  = SZ_128K,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.init  = a3xx_gpu_init,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(
-			0x03020000,
-			0x03020001,
-			0x03020002
-		),
-		.family = ADRENO_3XX,
-		.revn  = 320,
-		.fw = {
-			[ADRENO_FW_PM4] = "a300_pm4.fw",
-			[ADRENO_FW_PFP] = "a300_pfp.fw",
-		},
-		.gmem  = SZ_512K,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.init  = a3xx_gpu_init,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(
-			0x03030000,
-			0x03030001,
-			0x03030002
-		),
-		.family = ADRENO_3XX,
-		.revn  = 330,
-		.fw = {
-			[ADRENO_FW_PM4] = "a330_pm4.fw",
-			[ADRENO_FW_PFP] = "a330_pfp.fw",
-		},
-		.gmem  = SZ_1M,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.init  = a3xx_gpu_init,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x04000500),
-		.family = ADRENO_4XX,
-		.revn  = 405,
-		.fw = {
-			[ADRENO_FW_PM4] = "a420_pm4.fw",
-			[ADRENO_FW_PFP] = "a420_pfp.fw",
-		},
-		.gmem  = SZ_256K,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.init  = a4xx_gpu_init,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x04020000),
-		.family = ADRENO_4XX,
-		.revn  = 420,
-		.fw = {
-			[ADRENO_FW_PM4] = "a420_pm4.fw",
-			[ADRENO_FW_PFP] = "a420_pfp.fw",
-		},
-		.gmem  = (SZ_1M + SZ_512K),
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.init  = a4xx_gpu_init,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x04030002),
-		.family = ADRENO_4XX,
-		.revn  = 430,
-		.fw = {
-			[ADRENO_FW_PM4] = "a420_pm4.fw",
-			[ADRENO_FW_PFP] = "a420_pfp.fw",
-		},
-		.gmem  = (SZ_1M + SZ_512K),
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.init  = a4xx_gpu_init,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x05000600),
-		.family = ADRENO_5XX,
-		.revn = 506,
-		.fw = {
-			[ADRENO_FW_PM4] = "a530_pm4.fw",
-			[ADRENO_FW_PFP] = "a530_pfp.fw",
-		},
-		.gmem = (SZ_128K + SZ_8K),
-		/*
-		 * Increase inactive period to 250 to avoid bouncing
-		 * the GDSC which appears to make it grumpy
-		 */
-		.inactive_period = 250,
-		.quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
-			  ADRENO_QUIRK_LMLOADKILL_DISABLE,
-		.init = a5xx_gpu_init,
-		.zapfw = "a506_zap.mdt",
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x05000800),
-		.family = ADRENO_5XX,
-		.revn = 508,
-		.fw = {
-			[ADRENO_FW_PM4] = "a530_pm4.fw",
-			[ADRENO_FW_PFP] = "a530_pfp.fw",
-		},
-		.gmem = (SZ_128K + SZ_8K),
-		/*
-		 * Increase inactive period to 250 to avoid bouncing
-		 * the GDSC which appears to make it grumpy
-		 */
-		.inactive_period = 250,
-		.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
-		.init = a5xx_gpu_init,
-		.zapfw = "a508_zap.mdt",
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x05000900),
-		.family = ADRENO_5XX,
-		.revn = 509,
-		.fw = {
-			[ADRENO_FW_PM4] = "a530_pm4.fw",
-			[ADRENO_FW_PFP] = "a530_pfp.fw",
-		},
-		.gmem = (SZ_256K + SZ_16K),
-		/*
-		 * Increase inactive period to 250 to avoid bouncing
-		 * the GDSC which appears to make it grumpy
-		 */
-		.inactive_period = 250,
-		.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
-		.init = a5xx_gpu_init,
-		/* Adreno 509 uses the same ZAP as 512 */
-		.zapfw = "a512_zap.mdt",
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x05010000),
-		.family = ADRENO_5XX,
-		.revn = 510,
-		.fw = {
-			[ADRENO_FW_PM4] = "a530_pm4.fw",
-			[ADRENO_FW_PFP] = "a530_pfp.fw",
-		},
-		.gmem = SZ_256K,
-		/*
-		 * Increase inactive period to 250 to avoid bouncing
-		 * the GDSC which appears to make it grumpy
-		 */
-		.inactive_period = 250,
-		.init = a5xx_gpu_init,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x05010200),
-		.family = ADRENO_5XX,
-		.revn = 512,
-		.fw = {
-			[ADRENO_FW_PM4] = "a530_pm4.fw",
-			[ADRENO_FW_PFP] = "a530_pfp.fw",
-		},
-		.gmem = (SZ_256K + SZ_16K),
-		/*
-		 * Increase inactive period to 250 to avoid bouncing
-		 * the GDSC which appears to make it grumpy
-		 */
-		.inactive_period = 250,
-		.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
-		.init = a5xx_gpu_init,
-		.zapfw = "a512_zap.mdt",
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(
-			0x05030002,
-			0x05030004
-		),
-		.family = ADRENO_5XX,
-		.revn = 530,
-		.fw = {
-			[ADRENO_FW_PM4] = "a530_pm4.fw",
-			[ADRENO_FW_PFP] = "a530_pfp.fw",
-			[ADRENO_FW_GPMU] = "a530v3_gpmu.fw2",
-		},
-		.gmem = SZ_1M,
-		/*
-		 * Increase inactive period to 250 to avoid bouncing
-		 * the GDSC which appears to make it grumpy
-		 */
-		.inactive_period = 250,
-		.quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
-			ADRENO_QUIRK_FAULT_DETECT_MASK,
-		.init = a5xx_gpu_init,
-		.zapfw = "a530_zap.mdt",
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x05040001),
-		.family = ADRENO_5XX,
-		.revn = 540,
-		.fw = {
-			[ADRENO_FW_PM4] = "a530_pm4.fw",
-			[ADRENO_FW_PFP] = "a530_pfp.fw",
-			[ADRENO_FW_GPMU] = "a540_gpmu.fw2",
-		},
-		.gmem = SZ_1M,
-		/*
-		 * Increase inactive period to 250 to avoid bouncing
-		 * the GDSC which appears to make it grumpy
-		 */
-		.inactive_period = 250,
-		.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
-		.init = a5xx_gpu_init,
-		.zapfw = "a540_zap.mdt",
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x06010000),
-		.family = ADRENO_6XX_GEN1,
-		.revn = 610,
-		.fw = {
-			[ADRENO_FW_SQE] = "a630_sqe.fw",
-		},
-		.gmem = (SZ_128K + SZ_4K),
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.init = a6xx_gpu_init,
-		.zapfw = "a610_zap.mdt",
-		.hwcg = a612_hwcg,
-		/*
-		 * There are (at least) three SoCs implementing A610: SM6125
-		 * (trinket), SM6115 (bengal) and SM6225 (khaje). Trinket does
-		 * not have speedbinning, as only a single SKU exists and we
-		 * don't support khaje upstream yet.  Hence, this matching
-		 * table is only valid for bengal.
-		 */
-		.speedbins = ADRENO_SPEEDBINS(
-			{ 0,   0 },
-			{ 206, 1 },
-			{ 200, 2 },
-			{ 157, 3 },
-			{ 127, 4 },
-		),
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x06010800),
-		.family = ADRENO_6XX_GEN1,
-		.revn = 618,
-		.fw = {
-			[ADRENO_FW_SQE] = "a630_sqe.fw",
-			[ADRENO_FW_GMU] = "a630_gmu.bin",
-		},
-		.gmem = SZ_512K,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
-		.init = a6xx_gpu_init,
-		.speedbins = ADRENO_SPEEDBINS(
-			{ 0,   0 },
-			{ 169, 1 },
-			{ 174, 2 },
-		),
-	}, {
-		.machine = "qcom,sm4350",
-		.chip_ids = ADRENO_CHIP_IDS(0x06010900),
-		.family = ADRENO_6XX_GEN1,
-		.revn = 619,
-		.fw = {
-			[ADRENO_FW_SQE] = "a630_sqe.fw",
-			[ADRENO_FW_GMU] = "a619_gmu.bin",
-		},
-		.gmem = SZ_512K,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.init = a6xx_gpu_init,
-		.zapfw = "a615_zap.mdt",
-		.hwcg = a615_hwcg,
-		.speedbins = ADRENO_SPEEDBINS(
-			{ 0,   0 },
-			{ 138, 1 },
-			{ 92,  2 },
-		),
-	}, {
-		.machine = "qcom,sm6375",
-		.chip_ids = ADRENO_CHIP_IDS(0x06010901),
-		.family = ADRENO_6XX_GEN1,
-		.revn = 619,
-		.fw = {
-			[ADRENO_FW_SQE] = "a630_sqe.fw",
-			[ADRENO_FW_GMU] = "a619_gmu.bin",
-		},
-		.gmem = SZ_512K,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.init = a6xx_gpu_init,
-		.zapfw = "a615_zap.mdt",
-		.hwcg = a615_hwcg,
-		.speedbins = ADRENO_SPEEDBINS(
-			{ 0,   0 },
-			{ 190, 1 },
-			{ 177, 2 },
-		),
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x06010900),
-		.family = ADRENO_6XX_GEN1,
-		.revn = 619,
-		.fw = {
-			[ADRENO_FW_SQE] = "a630_sqe.fw",
-			[ADRENO_FW_GMU] = "a619_gmu.bin",
-		},
-		.gmem = SZ_512K,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
-		.init = a6xx_gpu_init,
-		.zapfw = "a615_zap.mdt",
-		.hwcg = a615_hwcg,
-		.speedbins = ADRENO_SPEEDBINS(
-			{ 0,   0 },
-			{ 120, 4 },
-			{ 138, 3 },
-			{ 169, 2 },
-			{ 180, 1 },
-		),
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(
-			0x06030001,
-			0x06030002
-		),
-		.family = ADRENO_6XX_GEN1,
-		.revn = 630,
-		.fw = {
-			[ADRENO_FW_SQE] = "a630_sqe.fw",
-			[ADRENO_FW_GMU] = "a630_gmu.bin",
-		},
-		.gmem = SZ_1M,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
-		.init = a6xx_gpu_init,
-		.zapfw = "a630_zap.mdt",
-		.hwcg = a630_hwcg,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x06040001),
-		.family = ADRENO_6XX_GEN2,
-		.revn = 640,
-		.fw = {
-			[ADRENO_FW_SQE] = "a630_sqe.fw",
-			[ADRENO_FW_GMU] = "a640_gmu.bin",
-		},
-		.gmem = SZ_1M,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
-		.init = a6xx_gpu_init,
-		.zapfw = "a640_zap.mdt",
-		.hwcg = a640_hwcg,
-		.speedbins = ADRENO_SPEEDBINS(
-			{ 0, 0 },
-			{ 1, 1 },
-		),
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x06050002),
-		.family = ADRENO_6XX_GEN3,
-		.revn = 650,
-		.fw = {
-			[ADRENO_FW_SQE] = "a650_sqe.fw",
-			[ADRENO_FW_GMU] = "a650_gmu.bin",
-		},
-		.gmem = SZ_1M + SZ_128K,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
-			ADRENO_QUIRK_HAS_HW_APRIV,
-		.init = a6xx_gpu_init,
-		.zapfw = "a650_zap.mdt",
-		.hwcg = a650_hwcg,
-		.address_space_size = SZ_16G,
-		.speedbins = ADRENO_SPEEDBINS(
-			{ 0, 0 },
-			{ 1, 1 },
-			{ 2, 3 }, /* Yep, 2 and 3 are swapped! :/ */
-			{ 3, 2 },
-		),
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x06060001),
-		.family = ADRENO_6XX_GEN4,
-		.revn = 660,
-		.fw = {
-			[ADRENO_FW_SQE] = "a660_sqe.fw",
-			[ADRENO_FW_GMU] = "a660_gmu.bin",
-		},
-		.gmem = SZ_1M + SZ_512K,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
-			ADRENO_QUIRK_HAS_HW_APRIV,
-		.init = a6xx_gpu_init,
-		.zapfw = "a660_zap.mdt",
-		.hwcg = a660_hwcg,
-		.address_space_size = SZ_16G,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x06030500),
-		.family = ADRENO_6XX_GEN4,
-		.fw = {
-			[ADRENO_FW_SQE] = "a660_sqe.fw",
-			[ADRENO_FW_GMU] = "a660_gmu.bin",
-		},
-		.gmem = SZ_512K,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
-			ADRENO_QUIRK_HAS_HW_APRIV,
-		.init = a6xx_gpu_init,
-		.zapfw = "a660_zap.mbn",
-		.hwcg = a660_hwcg,
-		.address_space_size = SZ_16G,
-		.speedbins = ADRENO_SPEEDBINS(
-			{ 0,   0 },
-			{ 117, 0 },
-			{ 172, 2 }, /* Called speedbin 1 downstream, but let's not break things! */
-			{ 190, 1 },
-		),
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x06080001),
-		.family = ADRENO_6XX_GEN2,
-		.revn = 680,
-		.fw = {
-			[ADRENO_FW_SQE] = "a630_sqe.fw",
-			[ADRENO_FW_GMU] = "a640_gmu.bin",
-		},
-		.gmem = SZ_2M,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
-		.init = a6xx_gpu_init,
-		.zapfw = "a640_zap.mdt",
-		.hwcg = a640_hwcg,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x06090000),
-		.family = ADRENO_6XX_GEN4,
-		.fw = {
-			[ADRENO_FW_SQE] = "a660_sqe.fw",
-			[ADRENO_FW_GMU] = "a660_gmu.bin",
-		},
-		.gmem = SZ_4M,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
-			ADRENO_QUIRK_HAS_HW_APRIV,
-		.init = a6xx_gpu_init,
-		.zapfw = "a690_zap.mdt",
-		.hwcg = a690_hwcg,
-		.address_space_size = SZ_16G,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x07030001),
-		.family = ADRENO_7XX_GEN1,
-		.fw = {
-			[ADRENO_FW_SQE] = "a730_sqe.fw",
-			[ADRENO_FW_GMU] = "gmu_gen70000.bin",
-		},
-		.gmem = SZ_2M,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
-			  ADRENO_QUIRK_HAS_HW_APRIV,
-		.init = a6xx_gpu_init,
-		.zapfw = "a730_zap.mdt",
-		.hwcg = a730_hwcg,
-		.address_space_size = SZ_16G,
-	}, {
-		.chip_ids = ADRENO_CHIP_IDS(0x43050a01), /* "C510v2" */
-		.family = ADRENO_7XX_GEN2,
-		.fw = {
-			[ADRENO_FW_SQE] = "a740_sqe.fw",
-			[ADRENO_FW_GMU] = "gmu_gen70200.bin",
-		},
-		.gmem = 3 * SZ_1M,
-		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
-		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
-			  ADRENO_QUIRK_HAS_HW_APRIV,
-		.init = a6xx_gpu_init,
-		.zapfw = "a740_zap.mdt",
-		.hwcg = a740_hwcg,
-		.address_space_size = SZ_16G,
-	},
-};
+extern const struct adreno_gpulist a2xx_gpulist;
+extern const struct adreno_gpulist a3xx_gpulist;
+extern const struct adreno_gpulist a4xx_gpulist;
+extern const struct adreno_gpulist a5xx_gpulist;
+extern const struct adreno_gpulist a6xx_gpulist;
+extern const struct adreno_gpulist a7xx_gpulist;
 
-MODULE_FIRMWARE("qcom/a300_pm4.fw");
-MODULE_FIRMWARE("qcom/a300_pfp.fw");
-MODULE_FIRMWARE("qcom/a330_pm4.fw");
-MODULE_FIRMWARE("qcom/a330_pfp.fw");
-MODULE_FIRMWARE("qcom/a420_pm4.fw");
-MODULE_FIRMWARE("qcom/a420_pfp.fw");
-MODULE_FIRMWARE("qcom/a530_pm4.fw");
-MODULE_FIRMWARE("qcom/a530_pfp.fw");
-MODULE_FIRMWARE("qcom/a530v3_gpmu.fw2");
-MODULE_FIRMWARE("qcom/a530_zap.mdt");
-MODULE_FIRMWARE("qcom/a530_zap.b00");
-MODULE_FIRMWARE("qcom/a530_zap.b01");
-MODULE_FIRMWARE("qcom/a530_zap.b02");
-MODULE_FIRMWARE("qcom/a540_gpmu.fw2");
-MODULE_FIRMWARE("qcom/a619_gmu.bin");
-MODULE_FIRMWARE("qcom/a630_sqe.fw");
-MODULE_FIRMWARE("qcom/a630_gmu.bin");
-MODULE_FIRMWARE("qcom/a630_zap.mbn");
-MODULE_FIRMWARE("qcom/a640_gmu.bin");
-MODULE_FIRMWARE("qcom/a650_gmu.bin");
-MODULE_FIRMWARE("qcom/a650_sqe.fw");
-MODULE_FIRMWARE("qcom/a660_gmu.bin");
-MODULE_FIRMWARE("qcom/a660_sqe.fw");
-MODULE_FIRMWARE("qcom/leia_pfp_470.fw");
-MODULE_FIRMWARE("qcom/leia_pm4_470.fw");
-MODULE_FIRMWARE("qcom/yamato_pfp.fw");
-MODULE_FIRMWARE("qcom/yamato_pm4.fw");
+static const struct adreno_gpulist *gpulists[] = {
+	&a2xx_gpulist,
+	&a3xx_gpulist,
+	&a4xx_gpulist,
+	&a5xx_gpulist,
+	&a6xx_gpulist,
+	&a6xx_gpulist,
+};
 
 static const struct adreno_info *adreno_info(uint32_t chip_id)
 {
 	/* identify gpu: */
-	for (int i = 0; i < ARRAY_SIZE(gpulist); i++) {
-		const struct adreno_info *info = &gpulist[i];
-		if (info->machine && !of_machine_is_compatible(info->machine))
-			continue;
-		for (int j = 0; info->chip_ids[j]; j++)
-			if (info->chip_ids[j] == chip_id)
-				return info;
+	for (int i = 0; i < ARRAY_SIZE(gpulists); i++) {
+		for (int j = 0; j < gpulists[i]->gpus_count; j++) {
+			const struct adreno_info *info = &gpulists[i]->gpus[j];
+
+			if (info->machine && !of_machine_is_compatible(info->machine))
+				continue;
+
+			for (int k = 0; info->chip_ids[k]; k++)
+				if (info->chip_ids[k] == chip_id)
+					return info;
+		}
 	}
 
 	return NULL;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -99,7 +99,7 @@
 		 * was a bad idea, and is only provided for backwards
 		 * compatibility for older targets.
 		 */
-		return -ENODEV;
+		return -ENOENT;
 	}
 
 	if (IS_ERR(fw)) {
@@ -475,7 +475,7 @@
 		ret = request_firmware_direct(&fw, fwname, drm->dev);
 		if (!ret) {
 			DRM_DEV_INFO(drm->dev, "loaded %s from legacy location\n",
-				newname);
+				fwname);
 			adreno_gpu->fwloc = FW_LOCATION_LEGACY;
 			goto out;
 		} else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {
@@ -563,8 +563,19 @@
 
 int adreno_hw_init(struct msm_gpu *gpu)
 {
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	int ret;
+
 	VERB("%s", gpu->name);
 
+	if (adreno_gpu->info->family >= ADRENO_6XX_GEN1 &&
+	    qcom_scm_set_gpu_smmu_aperture_is_available()) {
+		/* We currently always use context bank 0, so hard code this */
+		ret = qcom_scm_set_gpu_smmu_aperture(0);
+		if (ret)
+			DRM_DEV_ERROR(gpu->dev->dev, "unable to set SMMU aperture: %d\n", ret);
+	}
+
 	for (int i = 0; i < gpu->nr_rings; i++) {
 		struct msm_ringbuffer *ring = gpu->rb[i];
 
@@ -1079,6 +1090,7 @@
 	adreno_gpu->chip_id = config->chip_id;
 
 	gpu->allow_relocs = config->info->family < ADRENO_6XX_GEN1;
+	gpu->pdev = pdev;
 
 	/* Only handle the core clock when GMU is not in use (or is absent). */
 	if (adreno_has_gmu_wrapper(adreno_gpu) ||
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/adreno/adreno_gpu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/adreno/adreno_gpu.h
@@ -48,6 +48,7 @@
 	ADRENO_6XX_GEN4,  /* a660 family */
 	ADRENO_7XX_GEN1,  /* a730 family */
 	ADRENO_7XX_GEN2,  /* a740 family */
+	ADRENO_7XX_GEN3,  /* a750 family */
 };
 
 #define ADRENO_QUIRK_TWO_PASS_USE_WFI		BIT(0)
@@ -76,14 +77,13 @@
 	u32 value;
 };
 
-extern const struct adreno_reglist a612_hwcg[], a615_hwcg[], a630_hwcg[], a640_hwcg[], a650_hwcg[];
-extern const struct adreno_reglist a660_hwcg[], a690_hwcg[], a730_hwcg[], a740_hwcg[];
-
 struct adreno_speedbin {
 	uint16_t fuse;
 	uint16_t speedbin;
 };
 
+struct a6xx_info;
+
 struct adreno_info {
 	const char *machine;
 	/**
@@ -100,7 +100,9 @@
 	struct msm_gpu *(*init)(struct drm_device *dev);
 	const char *zapfw;
 	u32 inactive_period;
-	const struct adreno_reglist *hwcg;
+	union {
+		const struct a6xx_info *a6xx;
+	};
 	u64 address_space_size;
 	/**
 	 * @speedbins: Optional table of fuse to speedbin mappings
@@ -113,6 +115,16 @@
 
 #define ADRENO_CHIP_IDS(tbl...) (uint32_t[]) { tbl, 0 }
 
+struct adreno_gpulist {
+	const struct adreno_info *gpus;
+	unsigned gpus_count;
+};
+
+#define DECLARE_ADRENO_GPULIST(name)                  \
+const struct adreno_gpulist name ## _gpulist = {      \
+	name ## _gpus, ARRAY_SIZE(name ## _gpus)      \
+}
+
 /*
  * Helper to build a speedbin table, ie. the table:
  *      fuse | speedbin
@@ -131,6 +143,19 @@
  */
 #define ADRENO_SPEEDBINS(tbl...) (struct adreno_speedbin[]) { tbl {SHRT_MAX, 0} }
 
+struct adreno_protect {
+	const uint32_t *regs;
+	uint32_t count;
+	uint32_t count_max;
+};
+
+#define DECLARE_ADRENO_PROTECT(name, __count_max)	\
+static const struct adreno_protect name = {		\
+	.regs = name ## _regs,				\
+	.count = ARRAY_SIZE(name ## _regs),		\
+	.count_max = __count_max,			\
+};
+
 struct adreno_gpu {
 	struct msm_gpu base;
 	const struct adreno_info *info;
@@ -166,12 +191,42 @@
 	const struct firmware *fw[ADRENO_FW_MAX];
 
 	struct {
+		/**
+		 * @rgb565_predicator: Unknown, introduced with A650 family,
+		 * related to UBWC mode/ver 4
+		 */
 		u32 rgb565_predicator;
+		/** @uavflagprd_inv: Unknown, introduced with A650 family */
 		u32 uavflagprd_inv;
+		/** @min_acc_len: Whether the minimum access length is 64 bits */
 		u32 min_acc_len;
-		u32 ubwc_mode;
+		/**
+		 * @ubwc_swizzle: Whether to enable level 1, 2 & 3 bank swizzling.
+		 *
+		 * UBWC 1.0 always enables all three levels.
+		 * UBWC 2.0 removes level 1 bank swizzling, leaving levels 2 & 3.
+		 * UBWC 4.0 adds the optional ability to disable levels 2 & 3.
+		 *
+		 * This is a bitmask where BIT(0) enables level 1, BIT(1)
+		 * controls level 2, and BIT(2) enables level 3.
+		 */
+		u32 ubwc_swizzle;
+		/**
+		 * @highest_bank_bit: Highest Bank Bit
+		 *
+		 * The Highest Bank Bit value represents the bit of the highest
+		 * DDR bank.  This should ideally use DRAM type detection.
+		 */
 		u32 highest_bank_bit;
 		u32 amsbc;
+		/**
+		 * @macrotile_mode: Macrotile Mode
+		 *
+		 * Whether to use 4-channel macrotiling mode or the newer
+		 * 8-channel macrotiling mode introduced in UBWC 3.1. 0 is
+		 * 4-channel and 1 is 8-channel.
+		 */
+		u32 macrotile_mode;
 	} ubwc_config;
 
 	/*
@@ -256,6 +311,11 @@
 	return adreno_is_revn(gpu, 305);
 }
 
+static inline bool adreno_is_a305b(const struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x03000512;
+}
+
 static inline bool adreno_is_a306(const struct adreno_gpu *gpu)
 {
 	/* yes, 307, because a305c is 306 */
@@ -377,11 +437,30 @@
 	return adreno_is_revn(gpu, 680);
 }
 
+static inline int adreno_is_a663(const struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x06060300;
+}
+
 static inline int adreno_is_a690(const struct adreno_gpu *gpu)
 {
 	return gpu->info->chip_ids[0] == 0x06090000;
 }
 
+static inline int adreno_is_a702(const struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x07000200;
+}
+
+static inline int adreno_is_a610_family(const struct adreno_gpu *gpu)
+{
+	if (WARN_ON_ONCE(!gpu->info))
+		return false;
+
+	/* TODO: A612 */
+	return adreno_is_a610(gpu) || adreno_is_a702(gpu);
+}
+
 /* check for a615, a616, a618, a619 or any a630 derivatives */
 static inline int adreno_is_a630_family(const struct adreno_gpu *gpu)
 {
@@ -423,12 +502,22 @@
 	return gpu->info->chip_ids[0] == 0x43050a01;
 }
 
-/* Placeholder to make future diffs smaller */
+static inline int adreno_is_a750(struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x43051401;
+}
+
+static inline int adreno_is_x185(struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x43050c01;
+}
+
 static inline int adreno_is_a740_family(struct adreno_gpu *gpu)
 {
 	if (WARN_ON_ONCE(!gpu->info))
 		return false;
-	return gpu->info->family == ADRENO_7XX_GEN2;
+	return gpu->info->family == ADRENO_7XX_GEN2 ||
+	       gpu->info->family == ADRENO_7XX_GEN3;
 }
 
 static inline int adreno_is_a7xx(struct adreno_gpu *gpu)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_10_0_sm8650.h
@@ -160,6 +160,7 @@
 		.sblk = &sdm845_lm_sblk,
 		.lm_pair = LM_3,
 		.pingpong = PINGPONG_2,
+		.dspp = DSPP_2,
 	}, {
 		.name = "lm_3", .id = LM_3,
 		.base = 0x47000, .len = 0x400,
@@ -167,6 +168,7 @@
 		.sblk = &sdm845_lm_sblk,
 		.lm_pair = LM_2,
 		.pingpong = PINGPONG_3,
+		.dspp = DSPP_3,
 	}, {
 		.name = "lm_4", .id = LM_4,
 		.base = 0x48000, .len = 0x400,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
@@ -157,18 +157,6 @@
 		.lm_pair = LM_5,
 		.pingpong = PINGPONG_2,
 	}, {
-		.name = "lm_3", .id = LM_3,
-		.base = 0x47000, .len = 0x320,
-		.features = MIXER_MSM8998_MASK,
-		.sblk = &msm8998_lm_sblk,
-		.pingpong = PINGPONG_NONE,
-	}, {
-		.name = "lm_4", .id = LM_4,
-		.base = 0x48000, .len = 0x320,
-		.features = MIXER_MSM8998_MASK,
-		.sblk = &msm8998_lm_sblk,
-		.pingpong = PINGPONG_NONE,
-	}, {
 		.name = "lm_5", .id = LM_5,
 		.base = 0x49000, .len = 0x320,
 		.features = MIXER_MSM8998_MASK,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
@@ -156,25 +156,13 @@
 		.pingpong = PINGPONG_2,
 		.dspp = DSPP_2,
 	}, {
-		.name = "lm_3", .id = LM_3,
-		.base = 0x0, .len = 0x320,
-		.features = MIXER_SDM845_MASK,
-		.sblk = &sdm845_lm_sblk,
-		.pingpong = PINGPONG_NONE,
-		.dspp = DSPP_3,
-	}, {
-		.name = "lm_4", .id = LM_4,
-		.base = 0x0, .len = 0x320,
-		.features = MIXER_SDM845_MASK,
-		.sblk = &sdm845_lm_sblk,
-		.pingpong = PINGPONG_NONE,
-	}, {
 		.name = "lm_5", .id = LM_5,
 		.base = 0x49000, .len = 0x320,
 		.features = MIXER_SDM845_MASK,
 		.sblk = &sdm845_lm_sblk,
 		.lm_pair = LM_2,
 		.pingpong = PINGPONG_3,
+		.dspp = DSPP_3,
 	},
 };
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_1_sdm670.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_1_sdm670.h
@@ -65,6 +65,54 @@
 	},
 };
 
+static const struct dpu_lm_cfg sdm670_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_2,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+	},
+};
+
+static const struct dpu_dspp_cfg sdm670_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
 static const struct dpu_dsc_cfg sdm670_dsc[] = {
 	{
 		.name = "dsc_0", .id = DSC_0,
@@ -88,8 +136,10 @@
 	.ctl = sdm845_ctl,
 	.sspp_count = ARRAY_SIZE(sdm670_sspp),
 	.sspp = sdm670_sspp,
-	.mixer_count = ARRAY_SIZE(sdm845_lm),
-	.mixer = sdm845_lm,
+	.mixer_count = ARRAY_SIZE(sdm670_lm),
+	.mixer = sdm670_lm,
+	.dspp_count = ARRAY_SIZE(sdm670_dspp),
+	.dspp = sdm670_dspp,
 	.pingpong_count = ARRAY_SIZE(sdm845_pp),
 	.pingpong = sdm845_pp,
 	.dsc_count = ARRAY_SIZE(sdm670_dsc),
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
@@ -163,6 +163,7 @@
 		.sblk = &sdm845_lm_sblk,
 		.lm_pair = LM_3,
 		.pingpong = PINGPONG_2,
+		.dspp = DSPP_2,
 	}, {
 		.name = "lm_3", .id = LM_3,
 		.base = 0x47000, .len = 0x320,
@@ -170,6 +171,7 @@
 		.sblk = &sdm845_lm_sblk,
 		.lm_pair = LM_2,
 		.pingpong = PINGPONG_3,
+		.dspp = DSPP_3,
 	}, {
 		.name = "lm_4", .id = LM_4,
 		.base = 0x48000, .len = 0x320,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
@@ -162,6 +162,7 @@
 		.sblk = &sdm845_lm_sblk,
 		.lm_pair = LM_3,
 		.pingpong = PINGPONG_2,
+		.dspp = DSPP_2,
 	}, {
 		.name = "lm_3", .id = LM_3,
 		.base = 0x47000, .len = 0x320,
@@ -169,6 +170,7 @@
 		.sblk = &sdm845_lm_sblk,
 		.lm_pair = LM_2,
 		.pingpong = PINGPONG_3,
+		.dspp = DSPP_3,
 	}, {
 		.name = "lm_4", .id = LM_4,
 		.base = 0x48000, .len = 0x320,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
@@ -162,6 +162,7 @@
 		.sblk = &sdm845_lm_sblk,
 		.lm_pair = LM_3,
 		.pingpong = PINGPONG_2,
+		.dspp = DSPP_2,
 	}, {
 		.name = "lm_3", .id = LM_3,
 		.base = 0x47000, .len = 0x320,
@@ -169,6 +170,7 @@
 		.sblk = &sdm845_lm_sblk,
 		.lm_pair = LM_2,
 		.pingpong = PINGPONG_3,
+		.dspp = DSPP_3,
 	}, {
 		.name = "lm_4", .id = LM_4,
 		.base = 0x48000, .len = 0x320,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h
@@ -162,6 +162,7 @@
 		.sblk = &sdm845_lm_sblk,
 		.lm_pair = LM_3,
 		.pingpong = PINGPONG_2,
+		.dspp = DSPP_2,
 	}, {
 		.name = "lm_3", .id = LM_3,
 		.base = 0x47000, .len = 0x320,
@@ -169,6 +170,7 @@
 		.sblk = &sdm845_lm_sblk,
 		.lm_pair = LM_2,
 		.pingpong = PINGPONG_3,
+		.dspp = DSPP_3,
 	}, {
 		.name = "lm_4", .id = LM_4,
 		.base = 0x48000, .len = 0x320,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_qcs8300.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_qcs8300.h
@@ -0,0 +1,485 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024-2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_8_4_QCS8300_H
+#define _DPU_8_4_QCS8300_H
+
+static const struct dpu_caps qcs8300_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0xb,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.has_3d_merge = true,
+	.max_linewidth = 5120,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg qcs8300_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x494,
+	.features = BIT(DPU_MDP_PERIPH_0_REMOVED),
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
+		[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
+		[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
+	},
+};
+
+/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
+static const struct dpu_ctl_cfg qcs8300_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x15000, .len = 0x204,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x16000, .len = 0x204,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x17000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x18000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x19000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	}, {
+		.name = "ctl_5", .id = CTL_5,
+		.base = 0x1a000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+	},
+};
+
+static const struct dpu_sspp_cfg qcs8300_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG1,
+	}, {
+		.name = "sspp_2", .id = SSPP_VIG2,
+		.base = 0x8000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 8,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG2,
+	}, {
+		.name = "sspp_3", .id = SSPP_VIG3,
+		.base = 0xa000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 12,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG3,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x32c,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x32c,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x32c,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	}, {
+		.name = "sspp_11", .id = SSPP_DMA3,
+		.base = 0x2a000, .len = 0x32c,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 13,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA3,
+	},
+};
+
+static const struct dpu_lm_cfg qcs8300_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_3,
+		.pingpong = PINGPONG_2,
+		.dspp = DSPP_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x47000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+		.dspp = DSPP_3,
+	}, {
+		.name = "lm_4", .id = LM_4,
+		.base = 0x48000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_4,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_4,
+		.pingpong = PINGPONG_5,
+	},
+};
+
+static const struct dpu_dspp_cfg qcs8300_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_2", .id = DSPP_2,
+		.base = 0x58000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_3", .id = DSPP_3,
+		.base = 0x5a000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg qcs8300_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x69000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x6a000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x6b000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x6c000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+	}, {
+		.name = "pingpong_4", .id = PINGPONG_4,
+		.base = 0x6d000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+	}, {
+		.name = "pingpong_5", .id = PINGPONG_5,
+		.base = 0x6e000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+	}, {
+		.name = "pingpong_6", .id = PINGPONG_6,
+		.base = 0x65800, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_3,
+	}, {
+		.name = "pingpong_7", .id = PINGPONG_7,
+		.base = 0x65c00, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_3,
+	},
+};
+
+static const struct dpu_merge_3d_cfg qcs8300_merge_3d[] = {
+	{
+		.name = "merge_3d_0", .id = MERGE_3D_0,
+		.base = 0x4e000, .len = 0x8,
+	}, {
+		.name = "merge_3d_1", .id = MERGE_3D_1,
+		.base = 0x4f000, .len = 0x8,
+	}, {
+		.name = "merge_3d_2", .id = MERGE_3D_2,
+		.base = 0x50000, .len = 0x8,
+	}, {
+		.name = "merge_3d_3", .id = MERGE_3D_3,
+		.base = 0x65f00, .len = 0x8,
+	},
+};
+
+/*
+ * NOTE: Each display compression engine (DCE) contains dual hard
+ * slice DSC encoders so both share same base address but with
+ * its own different sub block address.
+ */
+static const struct dpu_dsc_cfg qcs8300_dsc[] = {
+	{
+		.name = "dce_0_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_0_1", .id = DSC_1,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_1_0", .id = DSC_2,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_1_1", .id = DSC_3,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_2_0", .id = DSC_4,
+		.base = 0x82000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_2_1", .id = DSC_5,
+		.base = 0x82000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_1,
+	},
+};
+
+static const struct dpu_wb_cfg qcs8300_wb[] = {
+	{
+		.name = "wb_2", .id = WB_2,
+		.base = 0x65000, .len = 0x2c8,
+		.features = WB_SM8250_MASK,
+		.format_list = wb2_formats_rgb_yuv,
+		.num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv),
+		.clk_ctrl = DPU_CLK_CTRL_WB2,
+		.xin_id = 6,
+		.vbif_idx = VBIF_RT,
+		.maxlinewidth = 4096,
+		.intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4),
+	},
+};
+/* TODO: INTF 3, 6, 7 and 8 are used for MST, marked as INTF_NONE for now */
+static const struct dpu_intf_cfg qcs8300_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x34000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x35000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	}, {
+		.name = "intf_2", .id = INTF_2,
+		.base = 0x36000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2),
+	}, {
+		.name = "intf_3", .id = INTF_3,
+		.base = 0x37000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,	/* pair with intf_0 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
+	}, {
+		.name = "intf_4", .id = INTF_4,
+		.base = 0x38000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 20),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 21),
+	}, {
+		.name = "intf_6", .id = INTF_6,
+		.base = 0x3A000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,	/* pair with intf_0 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 16),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 17),
+	}, {
+		.name = "intf_7", .id = INTF_7,
+		.base = 0x3b000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,	/* pair with intf_0 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 18),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 19),
+	}, {
+		.name = "intf_8", .id = INTF_8,
+		.base = 0x3c000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,	/* pair with intf_4 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
+	},
+};
+
+static const struct dpu_perf_cfg qcs8300_perf_data = {
+	.max_bw_low = 13600000,
+	.max_bw_high = 18200000,
+	.min_core_ib = 2500000,
+	.min_llcc_ib = 0,
+	.min_dram_ib = 800000,
+	.min_prefill_lines = 35,
+	/* FIXME: lut tables */
+	.danger_lut_tbl = {0x3ffff, 0x3ffff, 0x0},
+	.safe_lut_tbl = {0xfff0, 0xfff0, 0x1},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile),
+		.entries = sm6350_qos_linear_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile),
+		.entries = sm6350_qos_linear_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+		/* TODO: macrotile-qseed is different from macrotile */
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version qcs8300_mdss_ver = {
+	.core_major_ver = 8,
+	.core_minor_ver = 4,
+};
+
+const struct dpu_mdss_cfg dpu_qcs8300_cfg = {
+	.mdss_ver = &qcs8300_mdss_ver,
+	.caps = &qcs8300_dpu_caps,
+	.mdp = &qcs8300_mdp,
+	.cdm = &sc7280_cdm,
+	.ctl_count = ARRAY_SIZE(qcs8300_ctl),
+	.ctl = qcs8300_ctl,
+	.sspp_count = ARRAY_SIZE(qcs8300_sspp),
+	.sspp = qcs8300_sspp,
+	.mixer_count = ARRAY_SIZE(qcs8300_lm),
+	.mixer = qcs8300_lm,
+	.dspp_count = ARRAY_SIZE(qcs8300_dspp),
+	.dspp = qcs8300_dspp,
+	.pingpong_count = ARRAY_SIZE(qcs8300_pp),
+	.pingpong = qcs8300_pp,
+	.dsc_count = ARRAY_SIZE(qcs8300_dsc),
+	.dsc = qcs8300_dsc,
+	.merge_3d_count = ARRAY_SIZE(qcs8300_merge_3d),
+	.merge_3d = qcs8300_merge_3d,
+	.wb_count = ARRAY_SIZE(qcs8300_wb),
+	.wb = qcs8300_wb,
+	.intf_count = ARRAY_SIZE(qcs8300_intf),
+	.intf = qcs8300_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &qcs8300_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h
@@ -0,0 +1,485 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024-2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_8_4_SA8775P_H
+#define _DPU_8_4_SA8775P_H
+
+static const struct dpu_caps sa8775p_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0xb,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.has_3d_merge = true,
+	.max_linewidth = 5120,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg sa8775p_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x494,
+	.features = BIT(DPU_MDP_PERIPH_0_REMOVED),
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
+		[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
+		[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
+	},
+};
+
+/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
+static const struct dpu_ctl_cfg sa8775p_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x15000, .len = 0x204,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x16000, .len = 0x204,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x17000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x18000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x19000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	}, {
+		.name = "ctl_5", .id = CTL_5,
+		.base = 0x1a000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+	},
+};
+
+static const struct dpu_sspp_cfg sa8775p_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG1,
+	}, {
+		.name = "sspp_2", .id = SSPP_VIG2,
+		.base = 0x8000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 8,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG2,
+	}, {
+		.name = "sspp_3", .id = SSPP_VIG3,
+		.base = 0xa000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 12,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG3,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x32c,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x32c,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x32c,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	}, {
+		.name = "sspp_11", .id = SSPP_DMA3,
+		.base = 0x2a000, .len = 0x32c,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 13,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA3,
+	},
+};
+
+static const struct dpu_lm_cfg sa8775p_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_3,
+		.pingpong = PINGPONG_2,
+		.dspp = DSPP_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x47000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+		.dspp = DSPP_3,
+	}, {
+		.name = "lm_4", .id = LM_4,
+		.base = 0x48000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_4,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_4,
+		.pingpong = PINGPONG_5,
+	},
+};
+
+static const struct dpu_dspp_cfg sa8775p_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_2", .id = DSPP_2,
+		.base = 0x58000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_3", .id = DSPP_3,
+		.base = 0x5a000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sa8775p_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x69000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x6a000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x6b000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x6c000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+	}, {
+		.name = "pingpong_4", .id = PINGPONG_4,
+		.base = 0x6d000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+	}, {
+		.name = "pingpong_5", .id = PINGPONG_5,
+		.base = 0x6e000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+	}, {
+		.name = "pingpong_6", .id = PINGPONG_6,
+		.base = 0x65800, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_3,
+	}, {
+		.name = "pingpong_7", .id = PINGPONG_7,
+		.base = 0x65c00, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_3,
+	},
+};
+
+static const struct dpu_merge_3d_cfg sa8775p_merge_3d[] = {
+	{
+		.name = "merge_3d_0", .id = MERGE_3D_0,
+		.base = 0x4e000, .len = 0x8,
+	}, {
+		.name = "merge_3d_1", .id = MERGE_3D_1,
+		.base = 0x4f000, .len = 0x8,
+	}, {
+		.name = "merge_3d_2", .id = MERGE_3D_2,
+		.base = 0x50000, .len = 0x8,
+	}, {
+		.name = "merge_3d_3", .id = MERGE_3D_3,
+		.base = 0x65f00, .len = 0x8,
+	},
+};
+
+/*
+ * NOTE: Each display compression engine (DCE) contains dual hard
+ * slice DSC encoders so both share same base address but with
+ * its own different sub block address.
+ */
+static const struct dpu_dsc_cfg sa8775p_dsc[] = {
+	{
+		.name = "dce_0_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_0_1", .id = DSC_1,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_1_0", .id = DSC_2,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_1_1", .id = DSC_3,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_2_0", .id = DSC_4,
+		.base = 0x82000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_2_1", .id = DSC_5,
+		.base = 0x82000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_1,
+	},
+};
+
+static const struct dpu_wb_cfg sa8775p_wb[] = {
+	{
+		.name = "wb_2", .id = WB_2,
+		.base = 0x65000, .len = 0x2c8,
+		.features = WB_SM8250_MASK,
+		.format_list = wb2_formats_rgb_yuv,
+		.num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv),
+		.clk_ctrl = DPU_CLK_CTRL_WB2,
+		.xin_id = 6,
+		.vbif_idx = VBIF_RT,
+		.maxlinewidth = 4096,
+		.intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4),
+	},
+};
+/* TODO: INTF 3, 6, 7 and 8 are used for MST, marked as INTF_NONE for now */
+static const struct dpu_intf_cfg sa8775p_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x34000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x35000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	}, {
+		.name = "intf_2", .id = INTF_2,
+		.base = 0x36000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2),
+	}, {
+		.name = "intf_3", .id = INTF_3,
+		.base = 0x37000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,	/* pair with intf_0 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
+	}, {
+		.name = "intf_4", .id = INTF_4,
+		.base = 0x38000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 20),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 21),
+	}, {
+		.name = "intf_6", .id = INTF_6,
+		.base = 0x3A000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,	/* pair with intf_0 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 16),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 17),
+	}, {
+		.name = "intf_7", .id = INTF_7,
+		.base = 0x3b000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,	/* pair with intf_0 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 18),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 19),
+	}, {
+		.name = "intf_8", .id = INTF_8,
+		.base = 0x3c000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,	/* pair with intf_4 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
+	},
+};
+
+static const struct dpu_perf_cfg sa8775p_perf_data = {
+	.max_bw_low = 13600000,
+	.max_bw_high = 18200000,
+	.min_core_ib = 2500000,
+	.min_llcc_ib = 0,
+	.min_dram_ib = 800000,
+	.min_prefill_lines = 35,
+	/* FIXME: lut tables */
+	.danger_lut_tbl = {0x3ffff, 0x3ffff, 0x0},
+	.safe_lut_tbl = {0xfff0, 0xfff0, 0x1},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile),
+		.entries = sm6350_qos_linear_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile),
+		.entries = sm6350_qos_linear_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+		/* TODO: macrotile-qseed is different from macrotile */
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sa8775p_mdss_ver = {
+	.core_major_ver = 8,
+	.core_minor_ver = 4,
+};
+
+const struct dpu_mdss_cfg dpu_sa8775p_cfg = {
+	.mdss_ver = &sa8775p_mdss_ver,
+	.caps = &sa8775p_dpu_caps,
+	.mdp = &sa8775p_mdp,
+	.cdm = &sc7280_cdm,
+	.ctl_count = ARRAY_SIZE(sa8775p_ctl),
+	.ctl = sa8775p_ctl,
+	.sspp_count = ARRAY_SIZE(sa8775p_sspp),
+	.sspp = sa8775p_sspp,
+	.mixer_count = ARRAY_SIZE(sa8775p_lm),
+	.mixer = sa8775p_lm,
+	.dspp_count = ARRAY_SIZE(sa8775p_dspp),
+	.dspp = sa8775p_dspp,
+	.pingpong_count = ARRAY_SIZE(sa8775p_pp),
+	.pingpong = sa8775p_pp,
+	.dsc_count = ARRAY_SIZE(sa8775p_dsc),
+	.dsc = sa8775p_dsc,
+	.merge_3d_count = ARRAY_SIZE(sa8775p_merge_3d),
+	.merge_3d = sa8775p_merge_3d,
+	.wb_count = ARRAY_SIZE(sa8775p_wb),
+	.wb = sa8775p_wb,
+	.intf_count = ARRAY_SIZE(sa8775p_intf),
+	.intf = sa8775p_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sa8775p_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
@@ -160,6 +160,7 @@
 		.sblk = &sdm845_lm_sblk,
 		.lm_pair = LM_3,
 		.pingpong = PINGPONG_2,
+		.dspp = DSPP_2,
 	}, {
 		.name = "lm_3", .id = LM_3,
 		.base = 0x47000, .len = 0x320,
@@ -167,6 +168,7 @@
 		.sblk = &sdm845_lm_sblk,
 		.lm_pair = LM_2,
 		.pingpong = PINGPONG_3,
+		.dspp = DSPP_3,
 	}, {
 		.name = "lm_4", .id = LM_4,
 		.base = 0x48000, .len = 0x320,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -80,7 +80,7 @@
 
 	mode = &state->adjusted_mode;
 
-	crtc_clk = mode->vtotal * mode->hdisplay * drm_mode_vrefresh(mode);
+	crtc_clk = (u64)mode->vtotal * mode->hdisplay * drm_mode_vrefresh(mode);
 
 	drm_atomic_crtc_for_each_plane(plane, crtc) {
 		pstate = to_dpu_plane_state(plane->state);
@@ -459,15 +459,15 @@
 			&perf->core_clk_rate);
 	debugfs_create_u32("enable_bw_release", 0600, entry,
 			(u32 *)&perf->enable_bw_release);
-	debugfs_create_u32("threshold_low", 0600, entry,
+	debugfs_create_u32("threshold_low", 0400, entry,
 			(u32 *)&perf->perf_cfg->max_bw_low);
-	debugfs_create_u32("threshold_high", 0600, entry,
+	debugfs_create_u32("threshold_high", 0400, entry,
 			(u32 *)&perf->perf_cfg->max_bw_high);
-	debugfs_create_u32("min_core_ib", 0600, entry,
+	debugfs_create_u32("min_core_ib", 0400, entry,
 			(u32 *)&perf->perf_cfg->min_core_ib);
-	debugfs_create_u32("min_llcc_ib", 0600, entry,
+	debugfs_create_u32("min_llcc_ib", 0400, entry,
 			(u32 *)&perf->perf_cfg->min_llcc_ib);
-	debugfs_create_u32("min_dram_ib", 0600, entry,
+	debugfs_create_u32("min_dram_ib", 0400, entry,
 			(u32 *)&perf->perf_cfg->min_dram_ib);
 	debugfs_create_file("perf_mode", 0600, entry,
 			(u32 *)perf, &dpu_core_perf_mode_fops);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -658,18 +658,18 @@
 	DPU_ATRACE_END("crtc_frame_event");
 }
 
-/*
- * dpu_crtc_frame_event_cb - crtc frame event callback API. CRTC module
- * registers this API to encoder for all frame event callbacks like
- * frame_error, frame_done, idle_timeout, etc. Encoder may call different events
- * from different context - IRQ, user thread, commit_thread, etc. Each event
- * should be carefully reviewed and should be processed in proper task context
- * to avoid schedulin delay or properly manage the irq context's bottom half
- * processing.
+/**
+ * dpu_crtc_frame_event_cb - crtc frame event callback API
+ * @crtc: Pointer to crtc
+ * @event: Event to process
+ *
+ * Encoder may call this for different events from different context - IRQ,
+ * user thread, commit_thread, etc. Each event should be carefully reviewed and
+ * should be processed in proper task context to avoid schedulin delay or
+ * properly manage the irq context's bottom half processing.
  */
-static void dpu_crtc_frame_event_cb(void *data, u32 event)
+void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event)
 {
-	struct drm_crtc *crtc = (struct drm_crtc *)data;
 	struct dpu_crtc *dpu_crtc;
 	struct msm_drm_private *priv;
 	struct dpu_crtc_frame_event *fevent;
@@ -711,12 +711,13 @@
 	_dpu_crtc_complete_flip(crtc);
 }
 
-static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc,
+static int _dpu_crtc_check_and_setup_lm_bounds(struct drm_crtc *crtc,
 		struct drm_crtc_state *state)
 {
 	struct dpu_crtc_state *cstate = to_dpu_crtc_state(state);
 	struct drm_display_mode *adj_mode = &state->adjusted_mode;
 	u32 crtc_split_width = adj_mode->hdisplay / cstate->num_mixers;
+	struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
 	int i;
 
 	for (i = 0; i < cstate->num_mixers; i++) {
@@ -727,7 +728,12 @@
 		r->y2 = adj_mode->vdisplay;
 
 		trace_dpu_crtc_setup_lm_bounds(DRMID(crtc), i, r);
+
+		if (drm_rect_width(r) > dpu_kms->catalog->caps->max_mixer_width)
+			return -E2BIG;
 	}
+
+	return 0;
 }
 
 static void _dpu_crtc_get_pcc_coeff(struct drm_crtc_state *state,
@@ -803,7 +809,7 @@
 
 	DRM_DEBUG_ATOMIC("crtc%d\n", crtc->base.id);
 
-	_dpu_crtc_setup_lm_bounds(crtc, crtc->state);
+	_dpu_crtc_check_and_setup_lm_bounds(crtc, crtc->state);
 
 	/* encoder will trigger pending mask now */
 	drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
@@ -1091,12 +1097,6 @@
 
 	dpu_core_perf_crtc_update(crtc, 0);
 
-	drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
-		dpu_encoder_register_frame_event_callback(encoder, NULL, NULL);
-
-	memset(cstate->mixers, 0, sizeof(cstate->mixers));
-	cstate->num_mixers = 0;
-
 	/* disable clk & bw control until clk & bw properties are set */
 	cstate->bw_control = false;
 	cstate->bw_split_vote = false;
@@ -1132,8 +1132,6 @@
 		 */
 		if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_VIDEO)
 			request_bandwidth = true;
-		dpu_encoder_register_frame_event_callback(encoder,
-				dpu_crtc_frame_event_cb, (void *)crtc);
 	}
 
 	if (request_bandwidth)
@@ -1197,8 +1195,11 @@
 	if (crtc_state->active_changed)
 		crtc_state->mode_changed = true;
 
-	if (cstate->num_mixers)
-		_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
+	if (cstate->num_mixers) {
+		rc = _dpu_crtc_check_and_setup_lm_bounds(crtc, crtc_state);
+		if (rc)
+			return rc;
+	}
 
 	/* FIXME: move this to dpu_plane_atomic_check? */
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -300,4 +300,6 @@
 	return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT;
 }
 
+void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event);
+
 #endif /* _DPU_CRTC_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -126,6 +126,8 @@
  * @base:		drm_encoder base class for registration with DRM
  * @enc_spinlock:	Virtual-Encoder-Wide Spin Lock for IRQ purposes
  * @enabled:		True if the encoder is active, protected by enc_lock
+ * @commit_done_timedout: True if there has been a timeout on commit after
+ *			enabling the encoder.
  * @num_phys_encs:	Actual number of physical encoders contained.
  * @phys_encs:		Container of physical encoders managed.
  * @cur_master:		Pointer to the current master in this mode. Optimization
@@ -149,8 +151,6 @@
  * @frame_busy_mask:		Bitmask tracking which phys_enc we are still
  *				busy processing current command.
  *				Bit0 = phys_encs[0] etc.
- * @crtc_frame_event_cb:	callback handler for frame event
- * @crtc_frame_event_cb_data:	callback handler private data
  * @frame_done_timeout_ms:	frame done timeout in ms
  * @frame_done_timeout_cnt:	atomic counter tracking the number of frame
  * 				done timeouts
@@ -172,6 +172,7 @@
 	spinlock_t enc_spinlock;
 
 	bool enabled;
+	bool commit_done_timedout;
 
 	unsigned int num_phys_encs;
 	struct dpu_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL];
@@ -189,8 +190,6 @@
 
 	struct mutex enc_lock;
 	DECLARE_BITMAP(frame_busy_mask, MAX_PHYS_ENCODERS_PER_VIRTUAL);
-	void (*crtc_frame_event_cb)(void *, u32 event);
-	void *crtc_frame_event_cb_data;
 
 	atomic_t frame_done_timeout_ms;
 	atomic_t frame_done_timeout_cnt;
@@ -218,12 +217,66 @@
 	15, 7, 13, 5, 3, 11, 1, 9, 12, 4, 14, 6, 0, 8, 2, 10
 };
 
+u32 dpu_encoder_get_drm_fmt(struct dpu_encoder_phys *phys_enc)
+{
+	struct drm_encoder *drm_enc;
+	struct dpu_encoder_virt *dpu_enc;
+	struct drm_display_info *info;
+	struct drm_display_mode *mode;
+
+	drm_enc = phys_enc->parent;
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	info = &dpu_enc->connector->display_info;
+	mode = &phys_enc->cached_mode;
+
+	if (drm_mode_is_420_only(info, mode))
+		return DRM_FORMAT_YUV420;
+
+	return DRM_FORMAT_RGB888;
+}
+
+bool dpu_encoder_needs_periph_flush(struct dpu_encoder_phys *phys_enc)
+{
+	struct drm_encoder *drm_enc;
+	struct dpu_encoder_virt *dpu_enc;
+	struct msm_display_info *disp_info;
+	struct msm_drm_private *priv;
+	struct drm_display_mode *mode;
+
+	drm_enc = phys_enc->parent;
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	disp_info = &dpu_enc->disp_info;
+	priv = drm_enc->dev->dev_private;
+	mode = &phys_enc->cached_mode;
+
+	return phys_enc->hw_intf->cap->type == INTF_DP &&
+	       msm_dp_needs_periph_flush(priv->dp[disp_info->h_tile_instance[0]], mode);
+}
 
 bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc)
 {
+	const struct dpu_encoder_virt *dpu_enc;
+	struct msm_drm_private *priv = drm_enc->dev->dev_private;
+	const struct msm_display_info *disp_info;
+	int index;
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	disp_info = &dpu_enc->disp_info;
+	index = disp_info->h_tile_instance[0];
+
+	if (disp_info->intf_type == INTF_DP)
+		return msm_dp_wide_bus_available(priv->dp[index]);
+	else if (disp_info->intf_type == INTF_DSI)
+		return msm_dsi_wide_bus_enabled(priv->dsi[index]);
+
+	return false;
+}
+
+bool dpu_encoder_is_dsc_enabled(const struct drm_encoder *drm_enc)
+{
 	const struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
 
-	return dpu_enc->wide_bus_en;
+	return dpu_enc->dsc ? true : false;
 }
 
 int dpu_encoder_get_crc_values_cnt(const struct drm_encoder *drm_enc)
@@ -371,7 +424,7 @@
 		return -EWOULDBLOCK;
 	}
 
-	if (irq_idx < 0) {
+	if (irq_idx == 0) {
 		DRM_DEBUG_KMS("skip irq wait id=%u, callback=%ps\n",
 			      DRMID(phys_enc->parent), func);
 		return 0;
@@ -549,7 +602,8 @@
 	else if (!dpu_kms->catalog->caps->has_3d_merge)
 		topology.num_lm = 1;
 	else
-		topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
+		topology.num_lm = (mode->hdisplay > dpu_kms->catalog->caps->max_mixer_width) ?
+				   2 : 1;
 
 	if (crtc_state->ctm)
 		topology.num_dspp = topology.num_lm;
@@ -571,6 +625,40 @@
 	return topology;
 }
 
+static void dpu_encoder_assign_crtc_resources(struct dpu_kms *dpu_kms,
+					      struct drm_encoder *drm_enc,
+					      struct dpu_global_state *global_state,
+					      struct drm_crtc_state *crtc_state)
+{
+	struct dpu_crtc_state *cstate;
+	struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
+	struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
+	struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC];
+	int num_lm, num_ctl, num_dspp, i;
+
+	cstate = to_dpu_crtc_state(crtc_state);
+
+	memset(cstate->mixers, 0, sizeof(cstate->mixers));
+
+	num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+		drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
+	num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+		drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
+	num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+		drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
+		ARRAY_SIZE(hw_dspp));
+
+	for (i = 0; i < num_lm; i++) {
+		int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
+
+		cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
+		cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
+		cstate->mixers[i].hw_dspp = i < num_dspp ? to_dpu_hw_dspp(hw_dspp[i]) : NULL;
+	}
+
+	cstate->num_mixers = num_lm;
+}
+
 static int dpu_encoder_virt_atomic_check(
 		struct drm_encoder *drm_enc,
 		struct drm_crtc_state *crtc_state,
@@ -581,6 +669,7 @@
 	struct dpu_kms *dpu_kms;
 	struct drm_display_mode *adj_mode;
 	struct msm_display_topology topology;
+	struct msm_display_info *disp_info;
 	struct dpu_global_state *global_state;
 	struct drm_framebuffer *fb;
 	struct drm_dsc_config *dsc;
@@ -597,6 +686,7 @@
 	DPU_DEBUG_ENC(dpu_enc, "\n");
 
 	priv = drm_enc->dev->dev_private;
+	disp_info = &dpu_enc->disp_info;
 	dpu_kms = to_dpu_kms(priv->kms);
 	adj_mode = &crtc_state->adjusted_mode;
 	global_state = dpu_kms_get_global_state(crtc_state->state);
@@ -624,21 +714,24 @@
 	topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, dsc);
 
 	/*
-	 * Use CDM only for writeback at the moment as other interfaces cannot handle it.
-	 * if writeback itself cannot handle cdm for some reason it will fail in its atomic_check()
+	 * Use CDM only for writeback or DP at the moment as other interfaces cannot handle it.
+	 * If writeback itself cannot handle cdm for some reason it will fail in its atomic_check()
 	 * earlier.
 	 */
-	if (dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) {
+	if (disp_info->intf_type == INTF_WB && conn_state->writeback_job) {
 		fb = conn_state->writeback_job->fb;
 
 		if (fb && DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(fb))))
 			topology.needs_cdm = true;
-		if (topology.needs_cdm && !dpu_enc->cur_master->hw_cdm)
-			crtc_state->mode_changed = true;
-		else if (!topology.needs_cdm && dpu_enc->cur_master->hw_cdm)
-			crtc_state->mode_changed = true;
+	} else if (disp_info->intf_type == INTF_DP) {
+		if (msm_dp_is_yuv_420_enabled(priv->dp[disp_info->h_tile_instance[0]], adj_mode))
+			topology.needs_cdm = true;
 	}
 
+	if (topology.needs_cdm && !dpu_enc->cur_master->hw_cdm)
+		crtc_state->mode_changed = true;
+	else if (!topology.needs_cdm && dpu_enc->cur_master->hw_cdm)
+		crtc_state->mode_changed = true;
 	/*
 	 * Release and Allocate resources on every modeset
 	 * Dont allocate when active is false.
@@ -649,6 +742,9 @@
 		if (!crtc_state->active_changed || crtc_state->enable)
 			ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
 					drm_enc, crtc_state, topology);
+		if (!ret)
+			dpu_encoder_assign_crtc_resources(dpu_kms, drm_enc,
+							  global_state, crtc_state);
 	}
 
 	trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
@@ -1023,14 +1119,11 @@
 	struct dpu_encoder_virt *dpu_enc;
 	struct msm_drm_private *priv;
 	struct dpu_kms *dpu_kms;
-	struct dpu_crtc_state *cstate;
 	struct dpu_global_state *global_state;
 	struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
 	struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
-	struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
-	struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
 	struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
-	int num_lm, num_ctl, num_pp, num_dsc;
+	int num_ctl, num_pp, num_dsc;
 	unsigned int dsc_mask = 0;
 	int i;
 
@@ -1059,11 +1152,6 @@
 		ARRAY_SIZE(hw_pp));
 	num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
 		drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
-	num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
-		drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
-	dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
-		drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
-		ARRAY_SIZE(hw_dspp));
 
 	for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
 		dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
@@ -1079,7 +1167,8 @@
 
 	dpu_enc->dsc_mask = dsc_mask;
 
-	if (dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) {
+	if ((dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) ||
+	    dpu_enc->disp_info.intf_type == INTF_DP) {
 		struct dpu_hw_blk *hw_cdm = NULL;
 
 		dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
@@ -1088,38 +1177,23 @@
 		dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL;
 	}
 
-	cstate = to_dpu_crtc_state(crtc_state);
-
-	for (i = 0; i < num_lm; i++) {
-		int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
-
-		cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
-		cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
-		cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
-	}
-
-	cstate->num_mixers = num_lm;
-
-	dpu_enc->connector = conn_state->connector;
-
 	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
 		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
 
-		if (!dpu_enc->hw_pp[i]) {
+		phys->hw_pp = dpu_enc->hw_pp[i];
+		if (!phys->hw_pp) {
 			DPU_ERROR_ENC(dpu_enc,
 				"no pp block assigned at idx: %d\n", i);
 			return;
 		}
 
-		if (!hw_ctl[i]) {
+		phys->hw_ctl = i < num_ctl ? to_dpu_hw_ctl(hw_ctl[i]) : NULL;
+		if (!phys->hw_ctl) {
 			DPU_ERROR_ENC(dpu_enc,
 				"no ctl block assigned at idx: %d\n", i);
 			return;
 		}
 
-		phys->hw_pp = dpu_enc->hw_pp[i];
-		phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
-
 		phys->cached_mode = crtc_state->adjusted_mode;
 		if (phys->ops.atomic_mode_set)
 			phys->ops.atomic_mode_set(phys, crtc_state, conn_state);
@@ -1188,26 +1262,22 @@
 	struct dpu_encoder_virt *dpu_enc = NULL;
 	int ret = 0;
 	struct drm_display_mode *cur_mode = NULL;
-	struct msm_drm_private *priv = drm_enc->dev->dev_private;
-	struct msm_display_info *disp_info;
-	int index;
 
 	dpu_enc = to_dpu_encoder_virt(drm_enc);
-	disp_info = &dpu_enc->disp_info;
-	index = disp_info->h_tile_instance[0];
-
 	dpu_enc->dsc = dpu_encoder_get_dsc_config(drm_enc);
 
 	atomic_set(&dpu_enc->frame_done_timeout_cnt, 0);
 
-	if (disp_info->intf_type == INTF_DP)
-		dpu_enc->wide_bus_en = msm_dp_wide_bus_available(priv->dp[index]);
-	else if (disp_info->intf_type == INTF_DSI)
-		dpu_enc->wide_bus_en = msm_dsi_wide_bus_enabled(priv->dsi[index]);
-
 	mutex_lock(&dpu_enc->enc_lock);
+
+	dpu_enc->commit_done_timedout = false;
+
+	dpu_enc->connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc);
+
 	cur_mode = &dpu_enc->base.crtc->state->adjusted_mode;
 
+	dpu_enc->wide_bus_en = dpu_encoder_is_widebus_enabled(drm_enc);
+
 	trace_dpu_enc_enable(DRMID(drm_enc), cur_mode->hdisplay,
 			     cur_mode->vdisplay);
 
@@ -1261,7 +1331,7 @@
 	trace_dpu_enc_disable(DRMID(drm_enc));
 
 	/* wait for idle */
-	dpu_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
+	dpu_encoder_wait_for_tx_complete(drm_enc);
 
 	dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_PRE_STOP);
 
@@ -1383,28 +1453,6 @@
 	}
 }
 
-void dpu_encoder_register_frame_event_callback(struct drm_encoder *drm_enc,
-		void (*frame_event_cb)(void *, u32 event),
-		void *frame_event_cb_data)
-{
-	struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
-	unsigned long lock_flags;
-	bool enable;
-
-	enable = frame_event_cb ? true : false;
-
-	if (!drm_enc) {
-		DPU_ERROR("invalid encoder\n");
-		return;
-	}
-	trace_dpu_enc_frame_event_cb(DRMID(drm_enc), enable);
-
-	spin_lock_irqsave(&dpu_enc->enc_spinlock, lock_flags);
-	dpu_enc->crtc_frame_event_cb = frame_event_cb;
-	dpu_enc->crtc_frame_event_cb_data = frame_event_cb_data;
-	spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags);
-}
-
 void dpu_encoder_frame_done_callback(
 		struct drm_encoder *drm_enc,
 		struct dpu_encoder_phys *ready_phys, u32 event)
@@ -1444,15 +1492,12 @@
 			dpu_encoder_resource_control(drm_enc,
 					DPU_ENC_RC_EVENT_FRAME_DONE);
 
-			if (dpu_enc->crtc_frame_event_cb)
-				dpu_enc->crtc_frame_event_cb(
-					dpu_enc->crtc_frame_event_cb_data,
-					event);
+			if (dpu_enc->crtc)
+				dpu_crtc_frame_event_cb(dpu_enc->crtc, event);
 		}
 	} else {
-		if (dpu_enc->crtc_frame_event_cb)
-			dpu_enc->crtc_frame_event_cb(
-				dpu_enc->crtc_frame_event_cb_data, event);
+		if (dpu_enc->crtc)
+			dpu_crtc_frame_event_cb(dpu_enc->crtc, event);
 	}
 }
 
@@ -1670,8 +1715,7 @@
 		phys = dpu_enc->phys_encs[i];
 
 		ctl = phys->hw_ctl;
-		if (ctl->ops.clear_pending_flush)
-			ctl->ops.clear_pending_flush(ctl);
+		ctl->ops.clear_pending_flush(ctl);
 
 		/* update only for command mode primary ctl */
 		if ((phys == dpu_enc->cur_master) &&
@@ -1853,7 +1897,9 @@
 	dsc_common_mode = 0;
 	pic_width = dsc->pic_width;
 
-	dsc_common_mode = DSC_MODE_MULTIPLEX | DSC_MODE_SPLIT_PANEL;
+	dsc_common_mode = DSC_MODE_SPLIT_PANEL;
+	if (dpu_encoder_use_dsc_merge(enc_master->parent))
+		dsc_common_mode |= DSC_MODE_MULTIPLEX;
 	if (enc_master->intf_mode == INTF_MODE_VIDEO)
 		dsc_common_mode |= DSC_MODE_VIDEO;
 
@@ -2110,6 +2156,84 @@
 	ctl->ops.clear_pending_flush(ctl);
 }
 
+void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc,
+				       const struct dpu_format *dpu_fmt,
+				       u32 output_type)
+{
+	struct dpu_hw_cdm *hw_cdm;
+	struct dpu_hw_cdm_cfg *cdm_cfg;
+	struct dpu_hw_pingpong *hw_pp;
+	int ret;
+
+	if (!phys_enc)
+		return;
+
+	cdm_cfg = &phys_enc->cdm_cfg;
+	hw_pp = phys_enc->hw_pp;
+	hw_cdm = phys_enc->hw_cdm;
+
+	if (!hw_cdm)
+		return;
+
+	if (!DPU_FORMAT_IS_YUV(dpu_fmt)) {
+		DPU_DEBUG("[enc:%d] cdm_disable fmt:%x\n", DRMID(phys_enc->parent),
+			  dpu_fmt->base.pixel_format);
+		if (hw_cdm->ops.bind_pingpong_blk)
+			hw_cdm->ops.bind_pingpong_blk(hw_cdm, PINGPONG_NONE);
+
+		return;
+	}
+
+	memset(cdm_cfg, 0, sizeof(struct dpu_hw_cdm_cfg));
+
+	cdm_cfg->output_width = phys_enc->cached_mode.hdisplay;
+	cdm_cfg->output_height = phys_enc->cached_mode.vdisplay;
+	cdm_cfg->output_fmt = dpu_fmt;
+	cdm_cfg->output_type = output_type;
+	cdm_cfg->output_bit_depth = DPU_FORMAT_IS_DX(dpu_fmt) ?
+			CDM_CDWN_OUTPUT_10BIT : CDM_CDWN_OUTPUT_8BIT;
+	cdm_cfg->csc_cfg = &dpu_csc10_rgb2yuv_601l;
+
+	/* enable 10 bit logic */
+	switch (cdm_cfg->output_fmt->chroma_sample) {
+	case DPU_CHROMA_RGB:
+		cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE;
+		cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
+		break;
+	case DPU_CHROMA_H2V1:
+		cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE;
+		cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
+		break;
+	case DPU_CHROMA_420:
+		cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE;
+		cdm_cfg->v_cdwn_type = CDM_CDWN_OFFSITE;
+		break;
+	case DPU_CHROMA_H1V2:
+	default:
+		DPU_ERROR("[enc:%d] unsupported chroma sampling type\n",
+			  DRMID(phys_enc->parent));
+		cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE;
+		cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
+		break;
+	}
+
+	DPU_DEBUG("[enc:%d] cdm_enable:%d,%d,%X,%d,%d,%d,%d]\n",
+		  DRMID(phys_enc->parent), cdm_cfg->output_width,
+		  cdm_cfg->output_height, cdm_cfg->output_fmt->base.pixel_format,
+		  cdm_cfg->output_type, cdm_cfg->output_bit_depth,
+		  cdm_cfg->h_cdwn_type, cdm_cfg->v_cdwn_type);
+
+	if (hw_cdm->ops.enable) {
+		cdm_cfg->pp_id = hw_pp->idx;
+		ret = hw_cdm->ops.enable(hw_cdm, cdm_cfg);
+		if (ret < 0) {
+			DPU_ERROR("[enc:%d] failed to enable CDM; ret:%d\n",
+				  DRMID(phys_enc->parent), ret);
+			return;
+		}
+	}
+}
+
 #ifdef CONFIG_DEBUG_FS
 static int _dpu_encoder_status_show(struct seq_file *s, void *data)
 {
@@ -2214,17 +2338,23 @@
 
 static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
 				 struct dpu_kms *dpu_kms,
-				 struct msm_display_info *disp_info)
+				 struct msm_display_info *disp_info,
+				 int drm_enc_mode)
 {
 	int ret = 0;
 	int i = 0;
 	struct dpu_enc_phys_init_params phys_params;
+	unsigned int intf_id;
+	struct msm_drm_private *priv;
+	struct drm_encoder *drm_enc;
 
 	if (!dpu_enc) {
 		DPU_ERROR("invalid arg(s), enc %d\n", dpu_enc != NULL);
 		return -EINVAL;
 	}
 
+	drm_enc = &dpu_enc->base;
+	priv = drm_enc->dev->dev_private;
 	dpu_enc->cur_master = NULL;
 
 	memset(&phys_params, 0, sizeof(phys_params));
@@ -2261,9 +2391,18 @@
 		DPU_DEBUG("h_tile_instance %d = %d, split_role %d\n",
 				i, controller_id, phys_params.split_role);
 
-		phys_params.hw_intf = dpu_encoder_get_intf(dpu_kms->catalog, &dpu_kms->rm,
-							   disp_info->intf_type,
-							   controller_id);
+		if (drm_enc_mode == DRM_MODE_ENCODER_DPMST) {
+			intf_id = msm_dp_get_mst_intf_id(priv->dp[controller_id],
+							 disp_info->stream_id);
+			DPU_DEBUG("intf_id %d for disp_info->stream_id = %d\n", intf_id,
+				  disp_info->stream_id);
+			phys_params.hw_intf = dpu_rm_get_intf(&dpu_kms->rm, intf_id);
+
+		} else {
+			phys_params.hw_intf = dpu_encoder_get_intf(dpu_kms->catalog, &dpu_kms->rm,
+								   disp_info->intf_type,
+								   controller_id);
+		}
 
 		if (disp_info->intf_type == INTF_WB && controller_id < WB_MAX)
 			phys_params.hw_wb = dpu_rm_get_wb(&dpu_kms->rm, controller_id);
@@ -2306,7 +2445,7 @@
 		return;
 	}
 
-	if (!dpu_enc->frame_busy_mask[0] || !dpu_enc->crtc_frame_event_cb) {
+	if (!dpu_enc->frame_busy_mask[0] || !dpu_enc->crtc) {
 		DRM_DEBUG_KMS("id:%u invalid timeout frame_busy_mask=%lu\n",
 			      DRMID(drm_enc), dpu_enc->frame_busy_mask[0]);
 		return;
@@ -2322,7 +2461,7 @@
 
 	event = DPU_ENCODER_FRAME_EVENT_ERROR;
 	trace_dpu_enc_frame_done_timeout(DRMID(drm_enc), event);
-	dpu_enc->crtc_frame_event_cb(dpu_enc->crtc_frame_event_cb_data, event);
+	dpu_crtc_frame_event_cb(dpu_enc->crtc, event);
 }
 
 static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = {
@@ -2357,7 +2496,7 @@
 	mutex_init(&dpu_enc->enc_lock);
 	mutex_init(&dpu_enc->rc_lock);
 
-	ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info);
+	ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info, drm_enc_mode);
 	if (ret) {
 		DPU_ERROR("failed to setup encoder\n");
 		return ERR_PTR(-ENOMEM);
@@ -2379,10 +2518,18 @@
 	return &dpu_enc->base;
 }
 
-int dpu_encoder_wait_for_event(struct drm_encoder *drm_enc,
-	enum msm_event_wait event)
+/**
+ * dpu_encoder_wait_for_commit_done() - Wait for encoder to flush pending state
+ * @drm_enc:	encoder pointer
+ *
+ * Wait for hardware to have flushed the current pending changes to hardware at
+ * a vblank or CTL_START. Physical encoders will map this differently depending
+ * on the type: vid mode -> vsync_irq, cmd mode -> CTL_START.
+ *
+ * Return: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
+ */
+int dpu_encoder_wait_for_commit_done(struct drm_encoder *drm_enc)
 {
-	int (*fn_wait)(struct dpu_encoder_phys *phys_enc) = NULL;
 	struct dpu_encoder_virt *dpu_enc = NULL;
 	int i, ret = 0;
 
@@ -2396,23 +2543,51 @@
 	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
 		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
 
-		switch (event) {
-		case MSM_ENC_COMMIT_DONE:
-			fn_wait = phys->ops.wait_for_commit_done;
-			break;
-		case MSM_ENC_TX_COMPLETE:
-			fn_wait = phys->ops.wait_for_tx_complete;
-			break;
-		default:
-			DPU_ERROR_ENC(dpu_enc, "unknown wait event %d\n",
-					event);
-			return -EINVAL;
+		if (phys->ops.wait_for_commit_done) {
+			DPU_ATRACE_BEGIN("wait_for_commit_done");
+			ret = phys->ops.wait_for_commit_done(phys);
+			DPU_ATRACE_END("wait_for_commit_done");
+			if (ret == -ETIMEDOUT && !dpu_enc->commit_done_timedout) {
+				dpu_enc->commit_done_timedout = true;
+				msm_disp_snapshot_state(drm_enc->dev);
+			}
+			if (ret)
+				return ret;
 		}
+	}
+
+	return ret;
+}
+
+/**
+ * dpu_encoder_wait_for_tx_complete() - Wait for encoder to transfer pixels to panel
+ * @drm_enc:	encoder pointer
+ *
+ * Wait for the hardware to transfer all the pixels to the panel. Physical
+ * encoders will map this differently depending on the type: vid mode -> vsync_irq,
+ * cmd mode -> pp_done.
+ *
+ * Return: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
+ */
+int dpu_encoder_wait_for_tx_complete(struct drm_encoder *drm_enc)
+{
+	struct dpu_encoder_virt *dpu_enc = NULL;
+	int i, ret = 0;
+
+	if (!drm_enc) {
+		DPU_ERROR("invalid encoder\n");
+		return -EINVAL;
+	}
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	DPU_DEBUG_ENC(dpu_enc, "\n");
+
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
 
-		if (fn_wait) {
-			DPU_ATRACE_BEGIN("wait_for_completion_event");
-			ret = fn_wait(phys);
-			DPU_ATRACE_END("wait_for_completion_event");
+		if (phys->ops.wait_for_tx_complete) {
+			DPU_ATRACE_BEGIN("wait_for_tx_complete");
+			ret = phys->ops.wait_for_tx_complete(phys);
+			DPU_ATRACE_END("wait_for_tx_complete");
 			if (ret)
 				return ret;
 		}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h
@@ -26,6 +26,7 @@
  * @h_tile_instance:    Controller instance used per tile. Number of elements is
  *                      based on num_of_h_tiles
  * @is_cmd_mode		Boolean to indicate if the CMD mode is requested
+ * @stream_id		stream id for which the interface needs to be acquired
  * @is_te_using_watchdog_timer:  Boolean to indicate watchdog TE is
  *				 used instead of panel TE in cmd mode panels
  */
@@ -34,6 +35,7 @@
 	uint32_t num_of_h_tiles;
 	uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY];
 	bool is_cmd_mode;
+	int stream_id;
 	bool is_te_using_watchdog_timer;
 };
 
@@ -56,16 +58,6 @@
 					struct drm_crtc *crtc, bool enable);
 
 /**
- * dpu_encoder_register_frame_event_callback - provide callback to encoder that
- *	will be called after the request is complete, or other events.
- * @encoder:	encoder pointer
- * @cb:		callback pointer, provide NULL to deregister
- * @data:	user data provided to callback
- */
-void dpu_encoder_register_frame_event_callback(struct drm_encoder *encoder,
-		void (*cb)(void *, u32), void *data);
-
-/**
  * dpu_encoder_prepare_for_kickoff - schedule double buffer flip of the ctl
  *	path (i.e. ctl flush and start) at next appropriate time.
  *	Immediately: if no previous commit is outstanding.
@@ -93,25 +85,9 @@
  */
 int dpu_encoder_vsync_time(struct drm_encoder *drm_enc, ktime_t *wakeup_time);
 
-/**
- * dpu_encoder_wait_for_event - Waits for encoder events
- * @encoder:	encoder pointer
- * @event:      event to wait for
- * MSM_ENC_COMMIT_DONE -  Wait for hardware to have flushed the current pending
- *                        frames to hardware at a vblank or ctl_start
- *                        Encoders will map this differently depending on the
- *                        panel type.
- *	                  vid mode -> vsync_irq
- *                        cmd mode -> ctl_start
- * MSM_ENC_TX_COMPLETE -  Wait for the hardware to transfer all the pixels to
- *                        the panel. Encoders will map this differently
- *                        depending on the panel type.
- *                        vid mode -> vsync_irq
- *                        cmd mode -> pp_done
- * Returns: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
- */
-int dpu_encoder_wait_for_event(struct drm_encoder *drm_encoder,
-						enum msm_event_wait event);
+int dpu_encoder_wait_for_commit_done(struct drm_encoder *drm_encoder);
+
+int dpu_encoder_wait_for_tx_complete(struct drm_encoder *drm_encoder);
 
 /*
  * dpu_encoder_get_intf_mode - get interface mode of the given encoder
@@ -156,9 +132,20 @@
  */
 int dpu_encoder_get_vsync_count(struct drm_encoder *drm_enc);
 
+/**
+ * dpu_encoder_is_widebus_enabled - return bool value if widebus is enabled
+ * @drm_enc:    Pointer to previously created drm encoder structure
+ */
 bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc);
 
 /**
+ * dpu_encoder_is_dsc_enabled - indicate whether dsc is enabled
+ *				for the encoder.
+ * @drm_enc:    Pointer to previously created drm encoder structure
+ */
+bool dpu_encoder_is_dsc_enabled(const struct drm_encoder *drm_enc);
+
+/**
  * dpu_encoder_get_crc_values_cnt - get number of physical encoders contained
  *	in virtual encoder that can collect CRC values
  * @drm_enc:    Pointer to previously created drm encoder structure
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -154,6 +154,7 @@
  * @hw_wb:		Hardware interface to the wb registers
  * @hw_cdm:		Hardware interface to the CDM registers
  * @dpu_kms:		Pointer to the dpu_kms top level
+ * @cdm_cfg:		CDM block config needed to store WB/DP block's CDM configuration
  * @cached_mode:	DRM mode cached at mode_set time, acted on in enable
  * @vblank_ctl_lock:	Vblank ctl mutex lock to protect vblank_refcount
  * @enabled:		Whether the encoder has enabled and running a mode
@@ -184,6 +185,7 @@
 	struct dpu_hw_wb *hw_wb;
 	struct dpu_hw_cdm *hw_cdm;
 	struct dpu_kms *dpu_kms;
+	struct dpu_hw_cdm_cfg cdm_cfg;
 	struct drm_display_mode cached_mode;
 	struct mutex vblank_ctl_lock;
 	enum dpu_enc_split_role split_role;
@@ -213,7 +215,6 @@
  * @wbirq_refcount:     Reference count of writeback interrupt
  * @wb_done_timeout_cnt: number of wb done irq timeout errors
  * @wb_cfg:  writeback block config to store fb related details
- * @cdm_cfg: cdm block config needed to store writeback block's CDM configuration
  * @wb_conn: backpointer to writeback connector
  * @wb_job: backpointer to current writeback job
  * @dest:   dpu buffer layout for current writeback output buffer
@@ -223,7 +224,6 @@
 	atomic_t wbirq_refcount;
 	int wb_done_timeout_cnt;
 	struct dpu_hw_wb_cfg wb_cfg;
-	struct dpu_hw_cdm_cfg cdm_cfg;
 	struct drm_writeback_connector *wb_conn;
 	struct drm_writeback_job *wb_job;
 	struct dpu_hw_fmt_layout dest;
@@ -342,6 +342,19 @@
 unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc);
 
 /**
+ * dpu_encoder_get_drm_fmt - return DRM fourcc format
+ * @phys_enc: Pointer to physical encoder structure
+ */
+u32 dpu_encoder_get_drm_fmt(struct dpu_encoder_phys *phys_enc);
+
+/**
+ * dpu_encoder_needs_periph_flush - return true if physical encoder requires
+ *	peripheral flush
+ * @phys_enc: Pointer to physical encoder structure
+ */
+bool dpu_encoder_needs_periph_flush(struct dpu_encoder_phys *phys_enc);
+
+/**
  * dpu_encoder_helper_split_config - split display configuration helper function
  *	This helper function may be used by physical encoders to configure
  *	the split display related registers.
@@ -382,6 +395,15 @@
 void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc);
 
 /**
+ * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block
+ * @phys_enc: Pointer to physical encoder
+ * @output_type: HDMI/WB
+ */
+void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc,
+				       const struct dpu_format *dpu_fmt,
+				       u32 output_type);
+
+/**
  * dpu_encoder_vblank_callback - Notify virtual encoder of vblank IRQ reception
  * @drm_enc:    Pointer to drm encoder structure
  * @phys_enc:	Pointer to physical encoder
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -451,9 +451,6 @@
 
 	_dpu_encoder_phys_cmd_pingpong_config(phys_enc);
 
-	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
-		return;
-
 	ctl = phys_enc->hw_ctl;
 	ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -102,6 +102,7 @@
 	}
 
 	timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent);
+	timing->compression_en = dpu_encoder_is_dsc_enabled(phys_enc->parent);
 
 	/*
 	 * for DP, divide the horizonal parameters by 2 when
@@ -235,7 +236,7 @@
 	struct drm_display_mode mode;
 	struct dpu_hw_intf_timing_params timing_params = { 0 };
 	const struct dpu_format *fmt = NULL;
-	u32 fmt_fourcc = DRM_FORMAT_RGB888;
+	u32 fmt_fourcc;
 	unsigned long lock_flags;
 	struct dpu_hw_intf_cfg intf_cfg = { 0 };
 
@@ -254,17 +255,21 @@
 	DPU_DEBUG_VIDENC(phys_enc, "enabling mode:\n");
 	drm_mode_debug_printmodeline(&mode);
 
-	if (phys_enc->split_role != ENC_ROLE_SOLO) {
+	fmt_fourcc = dpu_encoder_get_drm_fmt(phys_enc);
+
+	if (phys_enc->split_role != ENC_ROLE_SOLO || fmt_fourcc == DRM_FORMAT_YUV420) {
 		mode.hdisplay >>= 1;
 		mode.htotal >>= 1;
 		mode.hsync_start >>= 1;
 		mode.hsync_end >>= 1;
+		mode.hskew >>= 1;
 
 		DPU_DEBUG_VIDENC(phys_enc,
-			"split_role %d, halve horizontal %d %d %d %d\n",
+			"split_role %d, halve horizontal %d %d %d %d %d\n",
 			phys_enc->split_role,
 			mode.hdisplay, mode.htotal,
-			mode.hsync_start, mode.hsync_end);
+			mode.hsync_start, mode.hsync_end,
+			mode.hskew);
 	}
 
 	drm_mode_to_intf_timing_params(phys_enc, &mode, &timing_params);
@@ -272,12 +277,14 @@
 	fmt = dpu_get_dpu_format(fmt_fourcc);
 	DPU_DEBUG_VIDENC(phys_enc, "fmt_fourcc 0x%X\n", fmt_fourcc);
 
+	if (phys_enc->hw_cdm)
+		intf_cfg.cdm = phys_enc->hw_cdm->idx;
 	intf_cfg.intf = phys_enc->hw_intf->idx;
 	intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID;
 	intf_cfg.stream_sel = 0; /* Don't care value for video mode */
 	intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
 	intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
-	if (phys_enc->hw_pp->merge_3d)
+	if (intf_cfg.mode_3d && phys_enc->hw_pp->merge_3d)
 		intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
 
 	spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
@@ -412,8 +419,14 @@
 static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
 {
 	struct dpu_hw_ctl *ctl;
+	const struct dpu_format *fmt;
+	u32 fmt_fourcc;
+	u32 mode_3d;
 
 	ctl = phys_enc->hw_ctl;
+	fmt_fourcc = dpu_encoder_get_drm_fmt(phys_enc);
+	fmt = dpu_get_dpu_format(fmt_fourcc);
+	mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
 
 	DPU_DEBUG_VIDENC(phys_enc, "\n");
 
@@ -422,6 +435,8 @@
 
 	dpu_encoder_helper_split_config(phys_enc, phys_enc->hw_intf->idx);
 
+	dpu_encoder_helper_phys_setup_cdm(phys_enc, fmt, CDM_CDWN_OUTPUT_HDMI);
+
 	dpu_encoder_phys_vid_setup_timing_engine(phys_enc);
 
 	/*
@@ -434,9 +449,20 @@
 		goto skip_flush;
 
 	ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx);
-	if (ctl->ops.update_pending_flush_merge_3d && phys_enc->hw_pp->merge_3d)
+	if (mode_3d && ctl->ops.update_pending_flush_merge_3d &&
+	    phys_enc->hw_pp->merge_3d)
 		ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx);
 
+	if (ctl->ops.update_pending_flush_cdm && phys_enc->hw_cdm)
+		ctl->ops.update_pending_flush_cdm(ctl, phys_enc->hw_cdm->idx);
+
+	/*
+	 * Peripheral flush must be updated whenever flushing SDP packets is needed.
+	 * SDP packets are required for any YUV format (YUV420, YUV422, YUV444).
+	 */
+	if (ctl->ops.update_pending_flush_periph && dpu_encoder_needs_periph_flush(phys_enc))
+		ctl->ops.update_pending_flush_periph(ctl, phys_enc->hw_intf->idx);
+
 skip_flush:
 	DPU_DEBUG_VIDENC(phys_enc,
 		"update pending flush ctl %d intf %d\n",
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c
@@ -265,149 +265,6 @@
 }
 
 /**
- * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block
- *                                     This API does not handle DPU_CHROMA_H1V2.
- * @phys_enc:Pointer to physical encoder
- */
-static void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc)
-{
-	struct dpu_hw_cdm *hw_cdm;
-	struct dpu_hw_cdm_cfg *cdm_cfg;
-	struct dpu_hw_pingpong *hw_pp;
-	struct dpu_encoder_phys_wb *wb_enc;
-	const struct msm_format *format;
-	const struct dpu_format *dpu_fmt;
-	struct drm_writeback_job *wb_job;
-	int ret;
-
-	if (!phys_enc)
-		return;
-
-	wb_enc = to_dpu_encoder_phys_wb(phys_enc);
-	cdm_cfg = &wb_enc->cdm_cfg;
-	hw_pp = phys_enc->hw_pp;
-	hw_cdm = phys_enc->hw_cdm;
-	wb_job = wb_enc->wb_job;
-
-	format = msm_framebuffer_format(wb_enc->wb_job->fb);
-	dpu_fmt = dpu_get_dpu_format_ext(format->pixel_format, wb_job->fb->modifier);
-
-	if (!hw_cdm)
-		return;
-
-	if (!DPU_FORMAT_IS_YUV(dpu_fmt)) {
-		DPU_DEBUG("[enc:%d] cdm_disable fmt:%x\n", DRMID(phys_enc->parent),
-			  dpu_fmt->base.pixel_format);
-		if (hw_cdm->ops.bind_pingpong_blk)
-			hw_cdm->ops.bind_pingpong_blk(hw_cdm, PINGPONG_NONE);
-
-		return;
-	}
-
-	memset(cdm_cfg, 0, sizeof(struct dpu_hw_cdm_cfg));
-
-	cdm_cfg->output_width = wb_job->fb->width;
-	cdm_cfg->output_height = wb_job->fb->height;
-	cdm_cfg->output_fmt = dpu_fmt;
-	cdm_cfg->output_type = CDM_CDWN_OUTPUT_WB;
-	cdm_cfg->output_bit_depth = DPU_FORMAT_IS_DX(dpu_fmt) ?
-			CDM_CDWN_OUTPUT_10BIT : CDM_CDWN_OUTPUT_8BIT;
-	cdm_cfg->csc_cfg = &dpu_csc10_rgb2yuv_601l;
-
-	/* enable 10 bit logic */
-	switch (cdm_cfg->output_fmt->chroma_sample) {
-	case DPU_CHROMA_RGB:
-		cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE;
-		cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
-		break;
-	case DPU_CHROMA_H2V1:
-		cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE;
-		cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
-		break;
-	case DPU_CHROMA_420:
-		cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE;
-		cdm_cfg->v_cdwn_type = CDM_CDWN_OFFSITE;
-		break;
-	case DPU_CHROMA_H1V2:
-	default:
-		DPU_ERROR("[enc:%d] unsupported chroma sampling type\n",
-			  DRMID(phys_enc->parent));
-		cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE;
-		cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
-		break;
-	}
-
-	DPU_DEBUG("[enc:%d] cdm_enable:%d,%d,%X,%d,%d,%d,%d]\n",
-		  DRMID(phys_enc->parent), cdm_cfg->output_width,
-		  cdm_cfg->output_height, cdm_cfg->output_fmt->base.pixel_format,
-		  cdm_cfg->output_type, cdm_cfg->output_bit_depth,
-		  cdm_cfg->h_cdwn_type, cdm_cfg->v_cdwn_type);
-
-	if (hw_cdm->ops.enable) {
-		cdm_cfg->pp_id = hw_pp->idx;
-		ret = hw_cdm->ops.enable(hw_cdm, cdm_cfg);
-		if (ret < 0) {
-			DPU_ERROR("[enc:%d] failed to enable CDM; ret:%d\n",
-				  DRMID(phys_enc->parent), ret);
-			return;
-		}
-	}
-}
-
-/**
- * dpu_encoder_phys_wb_atomic_check - verify and fixup given atomic states
- * @phys_enc:	Pointer to physical encoder
- * @crtc_state:	Pointer to CRTC atomic state
- * @conn_state:	Pointer to connector atomic state
- */
-static int dpu_encoder_phys_wb_atomic_check(
-		struct dpu_encoder_phys *phys_enc,
-		struct drm_crtc_state *crtc_state,
-		struct drm_connector_state *conn_state)
-{
-	struct drm_framebuffer *fb;
-	const struct drm_display_mode *mode = &crtc_state->mode;
-
-	DPU_DEBUG("[atomic_check:%d, \"%s\",%d,%d]\n",
-			phys_enc->hw_wb->idx, mode->name, mode->hdisplay, mode->vdisplay);
-
-	if (!conn_state || !conn_state->connector) {
-		DPU_ERROR("invalid connector state\n");
-		return -EINVAL;
-	} else if (conn_state->connector->status !=
-			connector_status_connected) {
-		DPU_ERROR("connector not connected %d\n",
-				conn_state->connector->status);
-		return -EINVAL;
-	}
-
-	if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
-		return 0;
-
-	fb = conn_state->writeback_job->fb;
-
-	DPU_DEBUG("[fb_id:%u][fb:%u,%u]\n", fb->base.id,
-			fb->width, fb->height);
-
-	if (fb->width != mode->hdisplay) {
-		DPU_ERROR("invalid fb w=%d, mode w=%d\n", fb->width,
-				mode->hdisplay);
-		return -EINVAL;
-	} else if (fb->height != mode->vdisplay) {
-		DPU_ERROR("invalid fb h=%d, mode h=%d\n", fb->height,
-				  mode->vdisplay);
-		return -EINVAL;
-	} else if (fb->width > phys_enc->hw_wb->caps->maxlinewidth) {
-		DPU_ERROR("invalid fb w=%d, maxlinewidth=%u\n",
-				  fb->width, phys_enc->hw_wb->caps->maxlinewidth);
-		return -EINVAL;
-	}
-
-	return drm_atomic_helper_check_wb_connector_state(conn_state->connector, conn_state->state);
-}
-
-
-/**
  * _dpu_encoder_phys_wb_update_flush - flush hardware update
  * @phys_enc:	Pointer to physical encoder
  */
@@ -418,6 +275,7 @@
 	struct dpu_hw_pingpong *hw_pp;
 	struct dpu_hw_cdm *hw_cdm;
 	u32 pending_flush = 0;
+	u32 mode_3d;
 
 	if (!phys_enc)
 		return;
@@ -426,6 +284,7 @@
 	hw_pp = phys_enc->hw_pp;
 	hw_ctl = phys_enc->hw_ctl;
 	hw_cdm = phys_enc->hw_cdm;
+	mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
 
 	DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0);
 
@@ -437,7 +296,8 @@
 	if (hw_ctl->ops.update_pending_flush_wb)
 		hw_ctl->ops.update_pending_flush_wb(hw_ctl, hw_wb->idx);
 
-	if (hw_ctl->ops.update_pending_flush_merge_3d && hw_pp && hw_pp->merge_3d)
+	if (mode_3d && hw_ctl->ops.update_pending_flush_merge_3d &&
+	    hw_pp && hw_pp->merge_3d)
 		hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl,
 				hw_pp->merge_3d->idx);
 
@@ -462,6 +322,14 @@
 	struct dpu_hw_wb *hw_wb = phys_enc->hw_wb;
 	struct drm_display_mode mode = phys_enc->cached_mode;
 	struct drm_framebuffer *fb = NULL;
+	struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc);
+	struct drm_writeback_job *wb_job;
+	const struct msm_format *format;
+	const struct dpu_format *dpu_fmt;
+
+	wb_job = wb_enc->wb_job;
+	format = msm_framebuffer_format(wb_enc->wb_job->fb);
+	dpu_fmt = dpu_get_dpu_format_ext(format->pixel_format, wb_job->fb->modifier);
 
 	DPU_DEBUG("[mode_set:%d, \"%s\",%d,%d]\n",
 			hw_wb->idx - WB_0, mode.name,
@@ -475,7 +343,7 @@
 
 	dpu_encoder_phys_wb_setup_fb(phys_enc, fb);
 
-	dpu_encoder_helper_phys_setup_cdm(phys_enc);
+	dpu_encoder_helper_phys_setup_cdm(phys_enc, dpu_fmt, CDM_CDWN_OUTPUT_WB);
 
 	dpu_encoder_phys_wb_setup_ctl(phys_enc);
 }
@@ -663,8 +531,7 @@
 	}
 
 	/* reset h/w before final flush */
-	if (phys_enc->hw_ctl->ops.clear_pending_flush)
-		phys_enc->hw_ctl->ops.clear_pending_flush(phys_enc->hw_ctl);
+	phys_enc->hw_ctl->ops.clear_pending_flush(phys_enc->hw_ctl);
 
 	/*
 	 * New CTL reset sequence from 5.0 MDP onwards.
@@ -777,7 +644,6 @@
 	ops->atomic_mode_set = dpu_encoder_phys_wb_atomic_mode_set;
 	ops->enable = dpu_encoder_phys_wb_enable;
 	ops->disable = dpu_encoder_phys_wb_disable;
-	ops->atomic_check = dpu_encoder_phys_wb_atomic_check;
 	ops->wait_for_commit_done = dpu_encoder_phys_wb_wait_for_commit_done;
 	ops->prepare_for_kickoff = dpu_encoder_phys_wb_prepare_for_kickoff;
 	ops->handle_post_kickoff = dpu_encoder_phys_wb_handle_post_kickoff;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2025, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
@@ -220,12 +220,9 @@
 	DRM_FORMAT_RGBA4444,
 	DRM_FORMAT_RGBX4444,
 	DRM_FORMAT_XRGB4444,
-	DRM_FORMAT_BGR565,
 	DRM_FORMAT_BGR888,
-	DRM_FORMAT_ABGR8888,
 	DRM_FORMAT_BGRA8888,
 	DRM_FORMAT_BGRX8888,
-	DRM_FORMAT_XBGR8888,
 	DRM_FORMAT_ABGR1555,
 	DRM_FORMAT_BGRA5551,
 	DRM_FORMAT_XBGR1555,
@@ -254,12 +251,9 @@
 	DRM_FORMAT_RGBA4444,
 	DRM_FORMAT_RGBX4444,
 	DRM_FORMAT_XRGB4444,
-	DRM_FORMAT_BGR565,
 	DRM_FORMAT_BGR888,
-	DRM_FORMAT_ABGR8888,
 	DRM_FORMAT_BGRA8888,
 	DRM_FORMAT_BGRX8888,
-	DRM_FORMAT_XBGR8888,
 	DRM_FORMAT_ABGR1555,
 	DRM_FORMAT_BGRA5551,
 	DRM_FORMAT_XBGR1555,
@@ -314,8 +308,8 @@
 	{ \
 	.maxdwnscale = SSPP_UNITY_SCALE, \
 	.maxupscale = SSPP_UNITY_SCALE, \
-	.format_list = plane_formats_yuv, \
-	.num_formats = ARRAY_SIZE(plane_formats_yuv), \
+	.format_list = plane_formats, \
+	.num_formats = ARRAY_SIZE(plane_formats), \
 	.virt_format_list = plane_formats, \
 	.virt_num_formats = ARRAY_SIZE(plane_formats), \
 	}
@@ -700,6 +694,8 @@
 
 #include "catalog/dpu_8_0_sc8280xp.h"
 #include "catalog/dpu_8_1_sm8450.h"
+#include "catalog/dpu_8_4_qcs8300.h"
+#include "catalog/dpu_8_4_sa8775p.h"
 
 #include "catalog/dpu_9_0_sm8550.h"
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
  */
 
@@ -847,6 +847,8 @@
 extern const struct dpu_mdss_cfg dpu_sc7280_cfg;
 extern const struct dpu_mdss_cfg dpu_sc8280xp_cfg;
 extern const struct dpu_mdss_cfg dpu_sm8450_cfg;
+extern const struct dpu_mdss_cfg dpu_qcs8300_cfg;
+extern const struct dpu_mdss_cfg dpu_sa8775p_cfg;
 extern const struct dpu_mdss_cfg dpu_sm8550_cfg;
 extern const struct dpu_mdss_cfg dpu_sm8650_cfg;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c
@@ -186,7 +186,7 @@
 	dpu_hw_cdm_setup_cdwn(ctx, cdm);
 
 	if (cdm->output_type == CDM_CDWN_OUTPUT_HDMI) {
-		if (fmt->chroma_sample != DPU_CHROMA_H1V2)
+		if (fmt->chroma_sample == DPU_CHROMA_H1V2)
 			return -EINVAL; /*unsupported format */
 		opmode = CDM_HDMI_PACK_OP_MODE_EN;
 		opmode |= (fmt->chroma_sample << 1);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -39,6 +39,7 @@
 #define   CTL_WB_FLUSH                  0x108
 #define   CTL_INTF_FLUSH                0x110
 #define   CTL_CDM_FLUSH                0x114
+#define   CTL_PERIPH_FLUSH              0x128
 #define   CTL_INTF_MASTER               0x134
 #define   CTL_DSPP_n_FLUSH(n)           ((0x13C) + ((n) * 4))
 
@@ -49,6 +50,7 @@
 #define  MERGE_3D_IDX   23
 #define  DSC_IDX        22
 #define CDM_IDX         26
+#define  PERIPH_IDX     30
 #define  INTF_IDX       31
 #define WB_IDX          16
 #define  DSPP_IDX       29  /* From DPU hw rev 7.x.x */
@@ -151,6 +153,10 @@
 				ctx->pending_dspp_flush_mask[dspp - DSPP_0]);
 		}
 
+	if (ctx->pending_flush_mask & BIT(PERIPH_IDX))
+		DPU_REG_WRITE(&ctx->hw, CTL_PERIPH_FLUSH,
+			      ctx->pending_periph_flush_mask);
+
 	if (ctx->pending_flush_mask & BIT(DSC_IDX))
 		DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH,
 			      ctx->pending_dsc_flush_mask);
@@ -311,6 +317,13 @@
 	ctx->pending_flush_mask |= BIT(INTF_IDX);
 }
 
+static void dpu_hw_ctl_update_pending_flush_periph_v1(struct dpu_hw_ctl *ctx,
+						      enum dpu_intf intf)
+{
+	ctx->pending_periph_flush_mask |= BIT(intf - INTF_0);
+	ctx->pending_flush_mask |= BIT(PERIPH_IDX);
+}
+
 static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx,
 		enum dpu_merge_3d merge_3d)
 {
@@ -532,6 +545,7 @@
 {
 	struct dpu_hw_blk_reg_map *c = &ctx->hw;
 	u32 intf_active = 0;
+	u32 dsc_active = 0;
 	u32 wb_active = 0;
 	u32 mode_sel = 0;
 
@@ -547,6 +561,7 @@
 
 	intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
 	wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);
+	dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE);
 
 	if (cfg->intf)
 		intf_active |= BIT(cfg->intf - INTF_0);
@@ -554,17 +569,18 @@
 	if (cfg->wb)
 		wb_active |= BIT(cfg->wb - WB_0);
 
+	if (cfg->dsc)
+		dsc_active |= cfg->dsc;
+
 	DPU_REG_WRITE(c, CTL_TOP, mode_sel);
 	DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
 	DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active);
+	DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active);
 
 	if (cfg->merge_3d)
 		DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE,
 			      BIT(cfg->merge_3d - MERGE_3D_0));
 
-	if (cfg->dsc)
-		DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc);
-
 	if (cfg->cdm)
 		DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cfg->cdm);
 }
@@ -680,6 +696,10 @@
 		ops->reset_intf_cfg = dpu_hw_ctl_reset_intf_cfg_v1;
 		ops->update_pending_flush_intf =
 			dpu_hw_ctl_update_pending_flush_intf_v1;
+
+		ops->update_pending_flush_periph =
+			dpu_hw_ctl_update_pending_flush_periph_v1;
+
 		ops->update_pending_flush_merge_3d =
 			dpu_hw_ctl_update_pending_flush_merge_3d_v1;
 		ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
@@ -83,7 +83,8 @@
 
 	/**
 	 * Clear the value of the cached pending_flush_mask
-	 * No effect on hardware
+	 * No effect on hardware.
+	 * Required to be implemented.
 	 * @ctx       : ctl path ctx pointer
 	 */
 	void (*clear_pending_flush)(struct dpu_hw_ctl *ctx);
@@ -123,6 +124,15 @@
 		enum dpu_intf blk);
 
 	/**
+	 * OR in the given flushbits to the cached pending_(periph_)flush_mask
+	 * No effect on hardware
+	 * @ctx       : ctl path ctx pointer
+	 * @blk       : interface block index
+	 */
+	void (*update_pending_flush_periph)(struct dpu_hw_ctl *ctx,
+					    enum dpu_intf blk);
+
+	/**
 	 * OR in the given flushbits to the cached pending_(merge_3d_)flush_mask
 	 * No effect on hardware
 	 * @ctx       : ctl path ctx pointer
@@ -264,6 +274,7 @@
 	u32 pending_flush_mask;
 	u32 pending_intf_flush_mask;
 	u32 pending_wb_flush_mask;
+	u32 pending_periph_flush_mask;
 	u32 pending_merge_3d_flush_mask;
 	u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0];
 	u32 pending_dsc_flush_mask;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
@@ -223,9 +223,11 @@
 
 	VERB("IRQ=[%d, %d]\n", DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
 
-	if (!irq_entry->cb)
+	if (!irq_entry->cb) {
 		DRM_ERROR("no registered cb, IRQ=[%d, %d]\n",
 			  DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+		return;
+	}
 
 	atomic_inc(&irq_entry->count);
 
@@ -525,14 +527,14 @@
 	int ret;
 
 	if (!irq_cb) {
-		DPU_ERROR("invalid IRQ=[%d, %d] irq_cb:%ps\n",
-			  DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), irq_cb);
+		DPU_ERROR("IRQ=[%d, %d] NULL callback\n",
+			  DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
 		return -EINVAL;
 	}
 
 	if (!dpu_core_irq_is_valid(irq_idx)) {
-		DPU_ERROR("invalid IRQ=[%d, %d]\n",
-			  DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+		DPU_ERROR("invalid IRQ=[%d, %d] irq_cb:%ps\n",
+			  DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), irq_cb);
 		return -EINVAL;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -163,13 +163,8 @@
 	hsync_ctl = (hsync_period << 16) | p->hsync_pulse_width;
 	display_hctl = (hsync_end_x << 16) | hsync_start_x;
 
-	/*
-	 * DATA_HCTL_EN controls data timing which can be different from
-	 * video timing. It is recommended to enable it for all cases, except
-	 * if compression is enabled in 1 pixel per clock mode
-	 */
 	if (p->wide_bus_en)
-		intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN | INTF_CFG2_DATA_HCTL_EN;
+		intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN;
 
 	data_width = p->width;
 
@@ -229,6 +224,14 @@
 	DPU_REG_WRITE(c, INTF_CONFIG, intf_cfg);
 	DPU_REG_WRITE(c, INTF_PANEL_FORMAT, panel_format);
 	if (ctx->cap->features & BIT(DPU_DATA_HCTL_EN)) {
+		/*
+		 * DATA_HCTL_EN controls data timing which can be different from
+		 * video timing. It is recommended to enable it for all cases, except
+		 * if compression is enabled in 1 pixel per clock mode
+		 */
+		if (!(p->compression_en && !p->wide_bus_en))
+			intf_cfg2 |= INTF_CFG2_DATA_HCTL_EN;
+
 		DPU_REG_WRITE(c, INTF_CONFIG2, intf_cfg2);
 		DPU_REG_WRITE(c, INTF_DISPLAY_DATA_HCTL, display_data_hctl);
 		DPU_REG_WRITE(c, INTF_ACTIVE_DATA_HCTL, active_data_hctl);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
@@ -33,6 +33,7 @@
 	u32 hsync_skew;
 
 	bool wide_bus_en;
+	bool compression_en;
 };
 
 struct dpu_hw_intf_prog_fetch {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -2,7 +2,7 @@
 /*
  * Copyright (C) 2013 Red Hat
  * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Author: Rob Clark <robdclark@gmail.com>
  */
@@ -374,6 +374,12 @@
 	return 0;
 }
 
+static void dpu_kms_global_obj_fini(struct dpu_kms *dpu_kms)
+{
+	drm_atomic_private_obj_fini(&dpu_kms->global_state);
+	drm_modeset_lock_fini(&dpu_kms->global_state_lock);
+}
+
 static int dpu_kms_parse_data_bus_icc_path(struct dpu_kms *dpu_kms)
 {
 	struct icc_path *path0;
@@ -478,7 +484,7 @@
 		 * mode panels. This may be a no-op for command mode panels.
 		 */
 		trace_dpu_kms_wait_for_commit_done(DRMID(crtc));
-		ret = dpu_encoder_wait_for_event(encoder, MSM_ENC_COMMIT_DONE);
+		ret = dpu_encoder_wait_for_commit_done(encoder);
 		if (ret && ret != -EWOULDBLOCK) {
 			DPU_ERROR("wait for commit done returned %d\n", ret);
 			break;
@@ -565,8 +571,10 @@
 {
 	struct drm_encoder *encoder = NULL;
 	struct msm_display_info info;
+	bool yuv_supported;
 	int rc;
-	int i;
+	int i, stream_id;
+	int stream_cnt;
 
 	for (i = 0; i < ARRAY_SIZE(priv->dp); i++) {
 		if (!priv->dp[i])
@@ -583,11 +591,38 @@
 			return PTR_ERR(encoder);
 		}
 
-		rc = msm_dp_modeset_init(priv->dp[i], dev, encoder);
+		yuv_supported = !!dpu_kms->catalog->cdm;
+		rc = msm_dp_modeset_init(priv->dp[i], dev, encoder, yuv_supported);
 		if (rc) {
 			DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
 			return rc;
 		}
+
+		stream_cnt = msm_dp_get_mst_max_stream(priv->dp[i]);
+
+		if (stream_cnt > 1) {
+			rc = msm_dp_mst_register(priv->dp[i]);
+			if (rc) {
+				DPU_ERROR("dp_mst_init failed for DP, rc = %d\n", rc);
+				return rc;
+			}
+
+			for (stream_id = 0; stream_id < stream_cnt; stream_id++) {
+				info.stream_id = stream_id;
+				encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_DPMST, &info);
+				if (IS_ERR(encoder)) {
+					DPU_ERROR("encoder init failed for dp mst display\n");
+					return PTR_ERR(encoder);
+				}
+
+				rc = msm_dp_mst_bridge_init(priv->dp[i], encoder);
+				if (rc) {
+					DPU_ERROR("dp mst bridge %d init failed, %d\n",
+						  stream_id, rc);
+					continue;
+				}
+			}
+		}
 	}
 
 	return 0;
@@ -630,23 +665,26 @@
 {
 	struct drm_encoder *encoder = NULL;
 	struct msm_display_info info;
+	const enum dpu_wb wb_idx = WB_2;
+	u32 maxlinewidth;
 	int rc;
 
 	memset(&info, 0, sizeof(info));
 
 	info.num_of_h_tiles = 1;
 	/* use only WB idx 2 instance for DPU */
-	info.h_tile_instance[0] = WB_2;
+	info.h_tile_instance[0] = wb_idx;
 	info.intf_type = INTF_WB;
 
+	maxlinewidth = dpu_rm_get_wb(&dpu_kms->rm, info.h_tile_instance[0])->caps->maxlinewidth;
+
 	encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_VIRTUAL, &info);
 	if (IS_ERR(encoder)) {
 		DPU_ERROR("encoder init failed for dsi display\n");
 		return PTR_ERR(encoder);
 	}
 
-	rc = dpu_writeback_init(dev, encoder, wb_formats,
-			n_formats);
+	rc = dpu_writeback_init(dev, encoder, wb_formats, n_formats, maxlinewidth);
 	if (rc) {
 		DPU_ERROR("dpu_writeback_init, rc = %d\n", rc);
 		return rc;
@@ -801,6 +839,8 @@
 		dpu_kms->hw_vbif[i] = NULL;
 	}
 
+	dpu_kms_global_obj_fini(dpu_kms);
+
 	dpu_kms->catalog = NULL;
 
 	dpu_kms->hw_mdp = NULL;
@@ -1332,6 +1372,8 @@
 	{ .compatible = "qcom,sm8250-dpu", .data = &dpu_sm8250_cfg, },
 	{ .compatible = "qcom,sm8350-dpu", .data = &dpu_sm8350_cfg, },
 	{ .compatible = "qcom,sm8450-dpu", .data = &dpu_sm8450_cfg, },
+	{ .compatible = "qcom,qcs8300-dpu", .data = &dpu_qcs8300_cfg, },
+	{ .compatible = "qcom,sa8775p-dpu", .data = &dpu_sa8775p_cfg, },
 	{ .compatible = "qcom,sm8550-dpu", .data = &dpu_sm8550_cfg, },
 	{ .compatible = "qcom,sm8650-dpu", .data = &dpu_sm8650_cfg, },
 	{}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -31,24 +31,14 @@
  * @fmt: Pointer to format string
  */
 #define DPU_DEBUG(fmt, ...)                                                \
-	do {                                                               \
-		if (drm_debug_enabled(DRM_UT_KMS))                         \
-			DRM_DEBUG(fmt, ##__VA_ARGS__); \
-		else                                                       \
-			pr_debug(fmt, ##__VA_ARGS__);                      \
-	} while (0)
+	DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__)
 
 /**
  * DPU_DEBUG_DRIVER - macro for hardware driver logging
  * @fmt: Pointer to format string
  */
 #define DPU_DEBUG_DRIVER(fmt, ...)                                         \
-	do {                                                               \
-		if (drm_debug_enabled(DRM_UT_DRIVER))                      \
-			DRM_ERROR(fmt, ##__VA_ARGS__); \
-		else                                                       \
-			pr_debug(fmt, ##__VA_ARGS__);                      \
-	} while (0)
+	DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__)
 
 #define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__)
 #define DPU_ERROR_RATELIMITED(fmt, ...) pr_err_ratelimited("[dpu error]" fmt, ##__VA_ARGS__)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -679,6 +679,9 @@
 			new_state->fb, &layout);
 	if (ret) {
 		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
+		if (pstate->aspace)
+			msm_framebuffer_cleanup(new_state->fb, pstate->aspace,
+						pstate->needs_dirtyfb);
 		return ret;
 	}
 
@@ -742,10 +745,9 @@
 	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
 
 	if (DPU_FORMAT_IS_YUV(fmt) &&
-	    (!pipe->sspp->cap->sblk->scaler_blk.len ||
-	     !pipe->sspp->cap->sblk->csc_blk.len)) {
+	    !pipe->sspp->cap->sblk->csc_blk.len) {
 		DPU_DEBUG_PLANE(pdpu,
-				"plane doesn't have scaler/csc for yuv\n");
+				"plane doesn't have csc for yuv\n");
 		return -EINVAL;
 	}
 
@@ -862,6 +864,10 @@
 
 	max_linewidth = pdpu->catalog->caps->max_linewidth;
 
+	drm_rect_rotate(&pipe_cfg->src_rect,
+			new_plane_state->fb->width, new_plane_state->fb->height,
+			new_plane_state->rotation);
+
 	if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) ||
 	     _dpu_plane_calc_clk(&crtc_state->adjusted_mode, pipe_cfg) > max_mdp_clk_rate) {
 		/*
@@ -911,6 +917,14 @@
 		r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2;
 	}
 
+	drm_rect_rotate_inv(&pipe_cfg->src_rect,
+			    new_plane_state->fb->width, new_plane_state->fb->height,
+			    new_plane_state->rotation);
+	if (r_pipe->sspp)
+		drm_rect_rotate_inv(&r_pipe_cfg->src_rect,
+				    new_plane_state->fb->width, new_plane_state->fb->height,
+				    new_plane_state->rotation);
+
 	ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt, &crtc_state->adjusted_mode);
 	if (ret)
 		return ret;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -350,10 +350,6 @@
 	TP_PROTO(uint32_t drm_id, bool enable),
 	TP_ARGS(drm_id, enable)
 );
-DEFINE_EVENT(dpu_enc_id_enable_template, dpu_enc_frame_event_cb,
-	TP_PROTO(uint32_t drm_id, bool enable),
-	TP_ARGS(drm_id, enable)
-);
 DEFINE_EVENT(dpu_enc_id_enable_template, dpu_enc_phys_cmd_connect_te,
 	TP_PROTO(uint32_t drm_id, bool enable),
 	TP_ARGS(drm_id, enable)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c
@@ -4,6 +4,7 @@
  */
 
 #include <drm/drm_edid.h>
+#include <drm/drm_framebuffer.h>
 
 #include "dpu_writeback.h"
 
@@ -24,6 +25,61 @@
 			dev->mode_config.max_height);
 }
 
+static int dpu_wb_conn_atomic_check(struct drm_connector *connector,
+				    struct drm_atomic_state *state)
+{
+	struct drm_writeback_connector *wb_conn = drm_connector_to_writeback(connector);
+	struct dpu_wb_connector *dpu_wb_conn = to_dpu_wb_conn(wb_conn);
+	struct drm_connector_state *conn_state =
+		drm_atomic_get_new_connector_state(state, connector);
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	const struct drm_display_mode *mode;
+	struct drm_framebuffer *fb;
+
+	DPU_DEBUG("[atomic_check:%d]\n", connector->base.id);
+
+	if (!conn_state || !conn_state->connector) {
+		DPU_ERROR("invalid connector state\n");
+		return -EINVAL;
+	} else if (conn_state->connector->status != connector_status_connected) {
+		DPU_ERROR("connector not connected %d\n", conn_state->connector->status);
+		return -EINVAL;
+	}
+
+	crtc = conn_state->crtc;
+	if (!crtc)
+		return 0;
+
+	if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
+		return 0;
+
+	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	if (IS_ERR(crtc_state))
+		return PTR_ERR(crtc_state);
+
+	mode = &crtc_state->mode;
+
+	fb = conn_state->writeback_job->fb;
+
+	DPU_DEBUG("[fb_id:%u][fb:%u,%u][mode:\"%s\":%ux%u]\n", fb->base.id, fb->width, fb->height,
+		  mode->name, mode->hdisplay, mode->vdisplay);
+
+	if (fb->width != mode->hdisplay) {
+		DPU_ERROR("invalid fb w=%d, mode w=%d\n", fb->width, mode->hdisplay);
+		return -EINVAL;
+	} else if (fb->height != mode->vdisplay) {
+		DPU_ERROR("invalid fb h=%d, mode h=%d\n", fb->height, mode->vdisplay);
+		return -EINVAL;
+	} else if (fb->width > dpu_wb_conn->maxlinewidth) {
+		DPU_ERROR("invalid fb w=%d, maxlinewidth=%u\n",
+			  fb->width, dpu_wb_conn->maxlinewidth);
+		return -EINVAL;
+	}
+
+	return drm_atomic_helper_check_wb_connector_state(conn_state->connector, conn_state->state);
+}
+
 static const struct drm_connector_funcs dpu_wb_conn_funcs = {
 	.reset = drm_atomic_helper_connector_reset,
 	.fill_modes = drm_helper_probe_single_connector_modes,
@@ -59,12 +115,13 @@
 
 static const struct drm_connector_helper_funcs dpu_wb_conn_helper_funcs = {
 	.get_modes = dpu_wb_conn_get_modes,
+	.atomic_check = dpu_wb_conn_atomic_check,
 	.prepare_writeback_job = dpu_wb_conn_prepare_job,
 	.cleanup_writeback_job = dpu_wb_conn_cleanup_job,
 };
 
 int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
-		const u32 *format_list, u32 num_formats)
+		const u32 *format_list, u32 num_formats, u32 maxlinewidth)
 {
 	struct dpu_wb_connector *dpu_wb_conn;
 	int rc = 0;
@@ -73,6 +130,8 @@
 	if (!dpu_wb_conn)
 		return -ENOMEM;
 
+	dpu_wb_conn->maxlinewidth = maxlinewidth;
+
 	drm_connector_helper_add(&dpu_wb_conn->base.base, &dpu_wb_conn_helper_funcs);
 
 	/* DPU initializes the encoder and sets it up completely for writeback
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h
@@ -18,6 +18,7 @@
 struct dpu_wb_connector {
 	struct drm_writeback_connector base;
 	struct drm_encoder *wb_enc;
+	u32 maxlinewidth;
 };
 
 static inline struct dpu_wb_connector *to_dpu_wb_conn(struct drm_writeback_connector *conn)
@@ -26,6 +27,6 @@
 }
 
 int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
-		const u32 *format_list, u32 num_formats);
+		const u32 *format_list, u32 num_formats, u32 maxlinewidth);
 
 #endif /*_DPU_WRITEBACK_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/mdp4/mdp4_lcdc_encoder.c
@@ -389,7 +389,7 @@
 
 	/* TODO: different regulators in other cases? */
 	mdp4_lcdc_encoder->regs[0].supply = "lvds-vccs-3p3v";
-	mdp4_lcdc_encoder->regs[1].supply = "lvds-vccs-3p3v";
+	mdp4_lcdc_encoder->regs[1].supply = "lvds-pll-vdda";
 	mdp4_lcdc_encoder->regs[2].supply = "lvds-vdda";
 
 	ret = devm_regulator_bulk_get(dev->dev,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/mdp5/mdp5_cfg.h
@@ -69,6 +69,16 @@
 	uint32_t caps;			/* MDP capabilities: MDP_CAP_xxx bits */
 };
 
+struct mdp5_wb_instance {
+	int id;
+	int lm;
+};
+
+struct mdp5_wb_block {
+	MDP5_SUB_BLOCK_DEFINITION;
+	struct mdp5_wb_instance instances[MAX_BASES];
+};
+
 #define MDP5_INTF_NUM_MAX	5
 
 struct mdp5_intf_block {
@@ -98,6 +108,7 @@
 	struct mdp5_sub_block pp;
 	struct mdp5_sub_block dsc;
 	struct mdp5_sub_block cdm;
+	struct mdp5_wb_block wb;
 	struct mdp5_intf_block intf;
 	struct mdp5_perf_block perf;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c
@@ -356,7 +356,7 @@
 
 			drm_printf(p, "%s:%d\t%d\t%s\n",
 				pipe2name(pipe), j, inuse,
-				plane ? plane->name : NULL);
+				plane ? plane->name : "(null)");
 
 			total += inuse;
 		}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c
@@ -26,7 +26,7 @@
 	end_addr = base_addr + aligned_len;
 
 	if (!(*reg))
-		*reg = kzalloc(len_padded, GFP_KERNEL);
+		*reg = kvzalloc(len_padded, GFP_KERNEL);
 
 	if (*reg)
 		dump_addr = *reg;
@@ -48,20 +48,21 @@
 	}
 }
 
-static void msm_disp_state_print_regs(u32 **reg, u32 len, void __iomem *base_addr,
-		struct drm_printer *p)
+static void msm_disp_state_print_regs(const u32 *dump_addr, u32 len,
+		void __iomem *base_addr, struct drm_printer *p)
 {
 	int i;
-	u32 *dump_addr = NULL;
 	void __iomem *addr;
 	u32 num_rows;
 
+	if (!dump_addr) {
+		drm_printf(p, "Registers not stored\n");
+		return;
+	}
+
 	addr = base_addr;
 	num_rows = len / REG_DUMP_ALIGN;
 
-	if (*reg)
-		dump_addr = *reg;
-
 	for (i = 0; i < num_rows; i++) {
 		drm_printf(p, "0x%lx : %08x %08x %08x %08x\n",
 				(unsigned long)(addr - base_addr),
@@ -89,7 +90,7 @@
 
 	list_for_each_entry_safe(block, tmp, &state->blocks, node) {
 		drm_printf(p, "====================%s================\n", block->name);
-		msm_disp_state_print_regs(&block->state, block->size, block->base_addr, p);
+		msm_disp_state_print_regs(block->state, block->size, block->base_addr, p);
 	}
 
 	drm_printf(p, "===================dpu drm state================\n");
@@ -161,7 +162,7 @@
 
 	list_for_each_entry_safe(block, tmp, &disp_state->blocks, node) {
 		list_del(&block->node);
-		kfree(block->state);
+		kvfree(block->state);
 		kfree(block);
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_audio.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_audio.c
@@ -15,363 +15,283 @@
 #include "dp_audio.h"
 #include "dp_panel.h"
 #include "dp_display.h"
+#include "dp_utils.h"
 
-#define HEADER_BYTE_2_BIT	 0
-#define PARITY_BYTE_2_BIT	 8
-#define HEADER_BYTE_1_BIT	16
-#define PARITY_BYTE_1_BIT	24
-#define HEADER_BYTE_3_BIT	16
-#define PARITY_BYTE_3_BIT	24
-
-struct dp_audio_private {
+struct msm_dp_audio_private {
 	struct platform_device *audio_pdev;
 	struct platform_device *pdev;
 	struct drm_device *drm_dev;
-	struct dp_catalog *catalog;
-	struct dp_panel *panel;
+	struct msm_dp_catalog *catalog;
 
-	bool engine_on;
 	u32 channels;
 
-	struct dp_audio dp_audio;
+	struct msm_dp_audio msm_dp_audio;
 };
 
-static u8 dp_audio_get_g0_value(u8 data)
-{
-	u8 c[4];
-	u8 g[4];
-	u8 ret_data = 0;
-	u8 i;
-
-	for (i = 0; i < 4; i++)
-		c[i] = (data >> i) & 0x01;
-
-	g[0] = c[3];
-	g[1] = c[0] ^ c[3];
-	g[2] = c[1];
-	g[3] = c[2];
-
-	for (i = 0; i < 4; i++)
-		ret_data = ((g[i] & 0x01) << i) | ret_data;
-
-	return ret_data;
-}
-
-static u8 dp_audio_get_g1_value(u8 data)
-{
-	u8 c[4];
-	u8 g[4];
-	u8 ret_data = 0;
-	u8 i;
-
-	for (i = 0; i < 4; i++)
-		c[i] = (data >> i) & 0x01;
-
-	g[0] = c[0] ^ c[3];
-	g[1] = c[0] ^ c[1] ^ c[3];
-	g[2] = c[1] ^ c[2];
-	g[3] = c[2] ^ c[3];
-
-	for (i = 0; i < 4; i++)
-		ret_data = ((g[i] & 0x01) << i) | ret_data;
-
-	return ret_data;
-}
-
-static u8 dp_audio_calculate_parity(u32 data)
-{
-	u8 x0 = 0;
-	u8 x1 = 0;
-	u8 ci = 0;
-	u8 iData = 0;
-	u8 i = 0;
-	u8 parity_byte;
-	u8 num_byte = (data & 0xFF00) > 0 ? 8 : 2;
-
-	for (i = 0; i < num_byte; i++) {
-		iData = (data >> i*4) & 0xF;
-
-		ci = iData ^ x1;
-		x1 = x0 ^ dp_audio_get_g1_value(ci);
-		x0 = dp_audio_get_g0_value(ci);
-	}
-
-	parity_byte = x1 | (x0 << 4);
-
-	return parity_byte;
-}
-
-static u32 dp_audio_get_header(struct dp_catalog *catalog,
-		enum dp_catalog_audio_sdp_type sdp,
-		enum dp_catalog_audio_header_type header)
+static u32 msm_dp_audio_get_header(struct msm_dp_catalog *catalog,
+		enum msm_dp_catalog_audio_sdp_type sdp,
+		enum msm_dp_catalog_audio_header_type header)
 {
-	catalog->sdp_type = sdp;
-	catalog->sdp_header = header;
-	dp_catalog_audio_get_header(catalog);
-
-	return catalog->audio_data;
+	return msm_dp_catalog_audio_get_header(catalog, sdp, header);
 }
 
-static void dp_audio_set_header(struct dp_catalog *catalog,
+static void msm_dp_audio_set_header(struct msm_dp_catalog *catalog,
 		u32 data,
-		enum dp_catalog_audio_sdp_type sdp,
-		enum dp_catalog_audio_header_type header)
+		enum msm_dp_catalog_audio_sdp_type sdp,
+		enum msm_dp_catalog_audio_header_type header)
 {
-	catalog->sdp_type = sdp;
-	catalog->sdp_header = header;
-	catalog->audio_data = data;
-	dp_catalog_audio_set_header(catalog);
+	msm_dp_catalog_audio_set_header(catalog, sdp, header, data);
 }
 
-static void dp_audio_stream_sdp(struct dp_audio_private *audio)
+static void msm_dp_audio_stream_sdp(struct msm_dp_audio_private *audio)
 {
-	struct dp_catalog *catalog = audio->catalog;
+	struct msm_dp_catalog *catalog = audio->catalog;
 	u32 value, new_value;
 	u8 parity_byte;
 
 	/* Config header and parity byte 1 */
-	value = dp_audio_get_header(catalog,
+	value = msm_dp_audio_get_header(catalog,
 			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
 
 	new_value = 0x02;
-	parity_byte = dp_audio_calculate_parity(new_value);
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
 	value |= ((new_value << HEADER_BYTE_1_BIT)
 			| (parity_byte << PARITY_BYTE_1_BIT));
 	drm_dbg_dp(audio->drm_dev,
 			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
 			value, parity_byte);
-	dp_audio_set_header(catalog, value,
+	msm_dp_audio_set_header(catalog, value,
 		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
 
 	/* Config header and parity byte 2 */
-	value = dp_audio_get_header(catalog,
+	value = msm_dp_audio_get_header(catalog,
 			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
 	new_value = value;
-	parity_byte = dp_audio_calculate_parity(new_value);
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
 	value |= ((new_value << HEADER_BYTE_2_BIT)
 			| (parity_byte << PARITY_BYTE_2_BIT));
 	drm_dbg_dp(audio->drm_dev,
 			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
 			value, parity_byte);
 
-	dp_audio_set_header(catalog, value,
+	msm_dp_audio_set_header(catalog, value,
 		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
 
 	/* Config header and parity byte 3 */
-	value = dp_audio_get_header(catalog,
+	value = msm_dp_audio_get_header(catalog,
 			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
 
 	new_value = audio->channels - 1;
-	parity_byte = dp_audio_calculate_parity(new_value);
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
 	value |= ((new_value << HEADER_BYTE_3_BIT)
 			| (parity_byte << PARITY_BYTE_3_BIT));
 	drm_dbg_dp(audio->drm_dev,
 			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
 		value, parity_byte);
 
-	dp_audio_set_header(catalog, value,
+	msm_dp_audio_set_header(catalog, value,
 		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
 }
 
-static void dp_audio_timestamp_sdp(struct dp_audio_private *audio)
+static void msm_dp_audio_timestamp_sdp(struct msm_dp_audio_private *audio)
 {
-	struct dp_catalog *catalog = audio->catalog;
+	struct msm_dp_catalog *catalog = audio->catalog;
 	u32 value, new_value;
 	u8 parity_byte;
 
 	/* Config header and parity byte 1 */
-	value = dp_audio_get_header(catalog,
+	value = msm_dp_audio_get_header(catalog,
 			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
 
 	new_value = 0x1;
-	parity_byte = dp_audio_calculate_parity(new_value);
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
 	value |= ((new_value << HEADER_BYTE_1_BIT)
 			| (parity_byte << PARITY_BYTE_1_BIT));
 	drm_dbg_dp(audio->drm_dev,
 			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
 			value, parity_byte);
-	dp_audio_set_header(catalog, value,
+	msm_dp_audio_set_header(catalog, value,
 		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
 
 	/* Config header and parity byte 2 */
-	value = dp_audio_get_header(catalog,
+	value = msm_dp_audio_get_header(catalog,
 			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
 
 	new_value = 0x17;
-	parity_byte = dp_audio_calculate_parity(new_value);
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
 	value |= ((new_value << HEADER_BYTE_2_BIT)
 			| (parity_byte << PARITY_BYTE_2_BIT));
 	drm_dbg_dp(audio->drm_dev,
 			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
 			value, parity_byte);
-	dp_audio_set_header(catalog, value,
+	msm_dp_audio_set_header(catalog, value,
 		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
 
 	/* Config header and parity byte 3 */
-	value = dp_audio_get_header(catalog,
+	value = msm_dp_audio_get_header(catalog,
 			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
 
 	new_value = (0x0 | (0x11 << 2));
-	parity_byte = dp_audio_calculate_parity(new_value);
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
 	value |= ((new_value << HEADER_BYTE_3_BIT)
 			| (parity_byte << PARITY_BYTE_3_BIT));
 	drm_dbg_dp(audio->drm_dev,
 			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
 			value, parity_byte);
-	dp_audio_set_header(catalog, value,
+	msm_dp_audio_set_header(catalog, value,
 		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
 }
 
-static void dp_audio_infoframe_sdp(struct dp_audio_private *audio)
+static void msm_dp_audio_infoframe_sdp(struct msm_dp_audio_private *audio)
 {
-	struct dp_catalog *catalog = audio->catalog;
+	struct msm_dp_catalog *catalog = audio->catalog;
 	u32 value, new_value;
 	u8 parity_byte;
 
 	/* Config header and parity byte 1 */
-	value = dp_audio_get_header(catalog,
+	value = msm_dp_audio_get_header(catalog,
 			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
 
 	new_value = 0x84;
-	parity_byte = dp_audio_calculate_parity(new_value);
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
 	value |= ((new_value << HEADER_BYTE_1_BIT)
 			| (parity_byte << PARITY_BYTE_1_BIT));
 	drm_dbg_dp(audio->drm_dev,
 			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
 			value, parity_byte);
-	dp_audio_set_header(catalog, value,
+	msm_dp_audio_set_header(catalog, value,
 		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
 
 	/* Config header and parity byte 2 */
-	value = dp_audio_get_header(catalog,
+	value = msm_dp_audio_get_header(catalog,
 			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
 
 	new_value = 0x1b;
-	parity_byte = dp_audio_calculate_parity(new_value);
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
 	value |= ((new_value << HEADER_BYTE_2_BIT)
 			| (parity_byte << PARITY_BYTE_2_BIT));
 	drm_dbg_dp(audio->drm_dev,
 			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
 			value, parity_byte);
-	dp_audio_set_header(catalog, value,
+	msm_dp_audio_set_header(catalog, value,
 		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
 
 	/* Config header and parity byte 3 */
-	value = dp_audio_get_header(catalog,
+	value = msm_dp_audio_get_header(catalog,
 			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
 
 	new_value = (0x0 | (0x11 << 2));
-	parity_byte = dp_audio_calculate_parity(new_value);
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
 	value |= ((new_value << HEADER_BYTE_3_BIT)
 			| (parity_byte << PARITY_BYTE_3_BIT));
 	drm_dbg_dp(audio->drm_dev,
 			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
 			new_value, parity_byte);
-	dp_audio_set_header(catalog, value,
+	msm_dp_audio_set_header(catalog, value,
 		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
 }
 
-static void dp_audio_copy_management_sdp(struct dp_audio_private *audio)
+static void msm_dp_audio_copy_management_sdp(struct msm_dp_audio_private *audio)
 {
-	struct dp_catalog *catalog = audio->catalog;
+	struct msm_dp_catalog *catalog = audio->catalog;
 	u32 value, new_value;
 	u8 parity_byte;
 
 	/* Config header and parity byte 1 */
-	value = dp_audio_get_header(catalog,
+	value = msm_dp_audio_get_header(catalog,
 			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
 
 	new_value = 0x05;
-	parity_byte = dp_audio_calculate_parity(new_value);
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
 	value |= ((new_value << HEADER_BYTE_1_BIT)
 			| (parity_byte << PARITY_BYTE_1_BIT));
 	drm_dbg_dp(audio->drm_dev,
 			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
 			value, parity_byte);
-	dp_audio_set_header(catalog, value,
+	msm_dp_audio_set_header(catalog, value,
 		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
 
 	/* Config header and parity byte 2 */
-	value = dp_audio_get_header(catalog,
+	value = msm_dp_audio_get_header(catalog,
 			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
 
 	new_value = 0x0F;
-	parity_byte = dp_audio_calculate_parity(new_value);
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
 	value |= ((new_value << HEADER_BYTE_2_BIT)
 			| (parity_byte << PARITY_BYTE_2_BIT));
 	drm_dbg_dp(audio->drm_dev,
 			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
 			value, parity_byte);
-	dp_audio_set_header(catalog, value,
+	msm_dp_audio_set_header(catalog, value,
 		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
 
 	/* Config header and parity byte 3 */
-	value = dp_audio_get_header(catalog,
+	value = msm_dp_audio_get_header(catalog,
 			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
 
 	new_value = 0x0;
-	parity_byte = dp_audio_calculate_parity(new_value);
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
 	value |= ((new_value << HEADER_BYTE_3_BIT)
 			| (parity_byte << PARITY_BYTE_3_BIT));
 	drm_dbg_dp(audio->drm_dev,
 			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
 			value, parity_byte);
-	dp_audio_set_header(catalog, value,
+	msm_dp_audio_set_header(catalog, value,
 		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
 }
 
-static void dp_audio_isrc_sdp(struct dp_audio_private *audio)
+static void msm_dp_audio_isrc_sdp(struct msm_dp_audio_private *audio)
 {
-	struct dp_catalog *catalog = audio->catalog;
+	struct msm_dp_catalog *catalog = audio->catalog;
 	u32 value, new_value;
 	u8 parity_byte;
 
 	/* Config header and parity byte 1 */
-	value = dp_audio_get_header(catalog,
+	value = msm_dp_audio_get_header(catalog,
 			DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
 
 	new_value = 0x06;
-	parity_byte = dp_audio_calculate_parity(new_value);
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
 	value |= ((new_value << HEADER_BYTE_1_BIT)
 			| (parity_byte << PARITY_BYTE_1_BIT));
 	drm_dbg_dp(audio->drm_dev,
 			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
 			value, parity_byte);
-	dp_audio_set_header(catalog, value,
+	msm_dp_audio_set_header(catalog, value,
 		DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
 
 	/* Config header and parity byte 2 */
-	value = dp_audio_get_header(catalog,
+	value = msm_dp_audio_get_header(catalog,
 			DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
 
 	new_value = 0x0F;
-	parity_byte = dp_audio_calculate_parity(new_value);
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
 	value |= ((new_value << HEADER_BYTE_2_BIT)
 			| (parity_byte << PARITY_BYTE_2_BIT));
 	drm_dbg_dp(audio->drm_dev,
 			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
 			value, parity_byte);
-	dp_audio_set_header(catalog, value,
+	msm_dp_audio_set_header(catalog, value,
 		DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
 }
 
-static void dp_audio_setup_sdp(struct dp_audio_private *audio)
+static void msm_dp_audio_setup_sdp(struct msm_dp_audio_private *audio)
 {
-	dp_catalog_audio_config_sdp(audio->catalog);
+	msm_dp_catalog_audio_config_sdp(audio->catalog);
 
-	dp_audio_stream_sdp(audio);
-	dp_audio_timestamp_sdp(audio);
-	dp_audio_infoframe_sdp(audio);
-	dp_audio_copy_management_sdp(audio);
-	dp_audio_isrc_sdp(audio);
+	msm_dp_audio_stream_sdp(audio);
+	msm_dp_audio_timestamp_sdp(audio);
+	msm_dp_audio_infoframe_sdp(audio);
+	msm_dp_audio_copy_management_sdp(audio);
+	msm_dp_audio_isrc_sdp(audio);
 }
 
-static void dp_audio_setup_acr(struct dp_audio_private *audio)
+static void msm_dp_audio_setup_acr(struct msm_dp_audio_private *audio)
 {
 	u32 select = 0;
-	struct dp_catalog *catalog = audio->catalog;
+	struct msm_dp_catalog *catalog = audio->catalog;
 
-	switch (audio->dp_audio.bw_code) {
+	switch (audio->msm_dp_audio.bw_code) {
 	case DP_LINK_BW_1_62:
 		select = 0;
 		break;
@@ -390,16 +310,15 @@
 		break;
 	}
 
-	catalog->audio_data = select;
-	dp_catalog_audio_config_acr(catalog);
+	msm_dp_catalog_audio_config_acr(catalog, select);
 }
 
-static void dp_audio_safe_to_exit_level(struct dp_audio_private *audio)
+static void msm_dp_audio_safe_to_exit_level(struct msm_dp_audio_private *audio)
 {
-	struct dp_catalog *catalog = audio->catalog;
+	struct msm_dp_catalog *catalog = audio->catalog;
 	u32 safe_to_exit_level = 0;
 
-	switch (audio->dp_audio.lane_count) {
+	switch (audio->msm_dp_audio.lane_count) {
 	case 1:
 		safe_to_exit_level = 14;
 		break;
@@ -410,60 +329,56 @@
 		safe_to_exit_level = 5;
 		break;
 	default:
+		safe_to_exit_level = 14;
 		drm_dbg_dp(audio->drm_dev,
 				"setting the default safe_to_exit_level = %u\n",
 				safe_to_exit_level);
-		safe_to_exit_level = 14;
 		break;
 	}
 
-	catalog->audio_data = safe_to_exit_level;
-	dp_catalog_audio_sfe_level(catalog);
+	msm_dp_catalog_audio_sfe_level(catalog, safe_to_exit_level);
 }
 
-static void dp_audio_enable(struct dp_audio_private *audio, bool enable)
+static void msm_dp_audio_enable(struct msm_dp_audio_private *audio, bool enable)
 {
-	struct dp_catalog *catalog = audio->catalog;
-
-	catalog->audio_data = enable;
-	dp_catalog_audio_enable(catalog);
+	struct msm_dp_catalog *catalog = audio->catalog;
 
-	audio->engine_on = enable;
+	msm_dp_catalog_audio_enable(catalog, enable);
 }
 
-static struct dp_audio_private *dp_audio_get_data(struct platform_device *pdev)
+static struct msm_dp_audio_private *msm_dp_audio_get_data(struct platform_device *pdev)
 {
-	struct dp_audio *dp_audio;
-	struct msm_dp *dp_display;
+	struct msm_dp_audio *msm_dp_audio;
+	struct msm_dp *msm_dp_display;
 
 	if (!pdev) {
 		DRM_ERROR("invalid input\n");
 		return ERR_PTR(-ENODEV);
 	}
 
-	dp_display = platform_get_drvdata(pdev);
-	if (!dp_display) {
+	msm_dp_display = platform_get_drvdata(pdev);
+	if (!msm_dp_display) {
 		DRM_ERROR("invalid input\n");
 		return ERR_PTR(-ENODEV);
 	}
 
-	dp_audio = dp_display->dp_audio;
+	msm_dp_audio = msm_dp_display->msm_dp_audio;
 
-	if (!dp_audio) {
-		DRM_ERROR("invalid dp_audio data\n");
+	if (!msm_dp_audio) {
+		DRM_ERROR("invalid msm_dp_audio data\n");
 		return ERR_PTR(-EINVAL);
 	}
 
-	return container_of(dp_audio, struct dp_audio_private, dp_audio);
+	return container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio);
 }
 
-static int dp_audio_hook_plugged_cb(struct device *dev, void *data,
+static int msm_dp_audio_hook_plugged_cb(struct device *dev, void *data,
 		hdmi_codec_plugged_cb fn,
 		struct device *codec_dev)
 {
 
 	struct platform_device *pdev;
-	struct msm_dp *dp_display;
+	struct msm_dp *msm_dp_display;
 
 	pdev = to_platform_device(dev);
 	if (!pdev) {
@@ -471,20 +386,20 @@
 		return -ENODEV;
 	}
 
-	dp_display = platform_get_drvdata(pdev);
-	if (!dp_display) {
+	msm_dp_display = platform_get_drvdata(pdev);
+	if (!msm_dp_display) {
 		pr_err("invalid input\n");
 		return -ENODEV;
 	}
 
-	return dp_display_set_plugged_cb(dp_display, fn, codec_dev);
+	return msm_dp_display_set_plugged_cb(msm_dp_display, fn, codec_dev);
 }
 
-static int dp_audio_get_eld(struct device *dev,
+static int msm_dp_audio_get_eld(struct device *dev,
 	void *data, uint8_t *buf, size_t len)
 {
 	struct platform_device *pdev;
-	struct msm_dp *dp_display;
+	struct msm_dp *msm_dp_display;
 
 	pdev = to_platform_device(dev);
 
@@ -493,30 +408,30 @@
 		return -ENODEV;
 	}
 
-	dp_display = platform_get_drvdata(pdev);
-	if (!dp_display) {
+	msm_dp_display = platform_get_drvdata(pdev);
+	if (!msm_dp_display) {
 		DRM_ERROR("invalid input\n");
 		return -ENODEV;
 	}
 
-	memcpy(buf, dp_display->connector->eld,
-		min(sizeof(dp_display->connector->eld), len));
+	memcpy(buf, msm_dp_display->connector->eld,
+		min(sizeof(msm_dp_display->connector->eld), len));
 
 	return 0;
 }
 
-int dp_audio_hw_params(struct device *dev,
+int msm_dp_audio_hw_params(struct device *dev,
 	void *data,
 	struct hdmi_codec_daifmt *daifmt,
 	struct hdmi_codec_params *params)
 {
 	int rc = 0;
-	struct dp_audio_private *audio;
+	struct msm_dp_audio_private *audio;
 	struct platform_device *pdev;
-	struct msm_dp *dp_display;
+	struct msm_dp *msm_dp_display;
 
 	pdev = to_platform_device(dev);
-	dp_display = platform_get_drvdata(pdev);
+	msm_dp_display = platform_get_drvdata(pdev);
 
 	/*
 	 * there could be cases where sound card can be opened even
@@ -526,12 +441,12 @@
 	 * such cases check for connection status and bail out if not
 	 * connected.
 	 */
-	if (!dp_display->power_on) {
+	if (!msm_dp_display_get_active_stream_cnt(msm_dp_display)) {
 		rc = -EINVAL;
 		goto end;
 	}
 
-	audio = dp_audio_get_data(pdev);
+	audio = msm_dp_audio_get_data(pdev);
 	if (IS_ERR(audio)) {
 		rc = PTR_ERR(audio);
 		goto end;
@@ -539,26 +454,26 @@
 
 	audio->channels = params->channels;
 
-	dp_audio_setup_sdp(audio);
-	dp_audio_setup_acr(audio);
-	dp_audio_safe_to_exit_level(audio);
-	dp_audio_enable(audio, true);
-	dp_display_signal_audio_start(dp_display);
-	dp_display->audio_enabled = true;
+	msm_dp_audio_setup_sdp(audio);
+	msm_dp_audio_setup_acr(audio);
+	msm_dp_audio_safe_to_exit_level(audio);
+	msm_dp_audio_enable(audio, true);
+	msm_dp_display_signal_audio_start(msm_dp_display);
+	msm_dp_display->audio_enabled = true;
 
 end:
 	return rc;
 }
 
-static void dp_audio_shutdown(struct device *dev, void *data)
+static void msm_dp_audio_shutdown(struct device *dev, void *data)
 {
-	struct dp_audio_private *audio;
+	struct msm_dp_audio_private *audio;
 	struct platform_device *pdev;
-	struct msm_dp *dp_display;
+	struct msm_dp *msm_dp_display;
 
 	pdev = to_platform_device(dev);
-	dp_display = platform_get_drvdata(pdev);
-	audio = dp_audio_get_data(pdev);
+	msm_dp_display = platform_get_drvdata(pdev);
+	audio = msm_dp_audio_get_data(pdev);
 	if (IS_ERR(audio)) {
 		DRM_ERROR("failed to get audio data\n");
 		return;
@@ -572,32 +487,32 @@
 	 * connected. is_connected cannot be used here as its set
 	 * to false earlier than this call
 	 */
-	if (!dp_display->audio_enabled)
+	if (!msm_dp_display->audio_enabled)
 		return;
 
-	dp_audio_enable(audio, false);
+	msm_dp_audio_enable(audio, false);
 	/* signal the dp display to safely shutdown clocks */
-	dp_display_signal_audio_complete(dp_display);
+	msm_dp_display_signal_audio_complete(msm_dp_display);
 }
 
-static const struct hdmi_codec_ops dp_audio_codec_ops = {
-	.hw_params = dp_audio_hw_params,
-	.audio_shutdown = dp_audio_shutdown,
-	.get_eld = dp_audio_get_eld,
-	.hook_plugged_cb = dp_audio_hook_plugged_cb,
+static const struct hdmi_codec_ops msm_dp_audio_codec_ops = {
+	.hw_params = msm_dp_audio_hw_params,
+	.audio_shutdown = msm_dp_audio_shutdown,
+	.get_eld = msm_dp_audio_get_eld,
+	.hook_plugged_cb = msm_dp_audio_hook_plugged_cb,
 };
 
 static struct hdmi_codec_pdata codec_data = {
-	.ops = &dp_audio_codec_ops,
+	.ops = &msm_dp_audio_codec_ops,
 	.max_i2s_channels = 8,
 	.i2s = 1,
 };
 
-void dp_unregister_audio_driver(struct device *dev, struct dp_audio *dp_audio)
+void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm_dp_audio)
 {
-	struct dp_audio_private *audio_priv;
+	struct msm_dp_audio_private *audio_priv;
 
-	audio_priv = container_of(dp_audio, struct dp_audio_private, dp_audio);
+	audio_priv = container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio);
 
 	if (audio_priv->audio_pdev) {
 		platform_device_unregister(audio_priv->audio_pdev);
@@ -605,13 +520,13 @@
 	}
 }
 
-int dp_register_audio_driver(struct device *dev,
-		struct dp_audio *dp_audio)
+int msm_dp_register_audio_driver(struct device *dev,
+		struct msm_dp_audio *msm_dp_audio)
 {
-	struct dp_audio_private *audio_priv;
+	struct msm_dp_audio_private *audio_priv;
 
-	audio_priv = container_of(dp_audio,
-			struct dp_audio_private, dp_audio);
+	audio_priv = container_of(msm_dp_audio,
+			struct msm_dp_audio_private, msm_dp_audio);
 
 	audio_priv->audio_pdev = platform_device_register_data(dev,
 						HDMI_CODEC_DRV_NAME,
@@ -621,13 +536,13 @@
 	return PTR_ERR_OR_ZERO(audio_priv->audio_pdev);
 }
 
-struct dp_audio *dp_audio_get(struct platform_device *pdev,
-			struct dp_panel *panel,
-			struct dp_catalog *catalog)
+struct msm_dp_audio *msm_dp_audio_get(struct platform_device *pdev,
+			struct msm_dp_panel *panel,
+			struct msm_dp_catalog *catalog)
 {
 	int rc = 0;
-	struct dp_audio_private *audio;
-	struct dp_audio *dp_audio;
+	struct msm_dp_audio_private *audio;
+	struct msm_dp_audio *msm_dp_audio;
 
 	if (!pdev || !panel || !catalog) {
 		DRM_ERROR("invalid input\n");
@@ -642,26 +557,25 @@
 	}
 
 	audio->pdev = pdev;
-	audio->panel = panel;
 	audio->catalog = catalog;
 
-	dp_audio = &audio->dp_audio;
+	msm_dp_audio = &audio->msm_dp_audio;
 
-	dp_catalog_audio_init(catalog);
+	msm_dp_catalog_audio_init(catalog);
 
-	return dp_audio;
+	return msm_dp_audio;
 error:
 	return ERR_PTR(rc);
 }
 
-void dp_audio_put(struct dp_audio *dp_audio)
+void msm_dp_audio_put(struct msm_dp_audio *msm_dp_audio)
 {
-	struct dp_audio_private *audio;
+	struct msm_dp_audio_private *audio;
 
-	if (!dp_audio)
+	if (!msm_dp_audio)
 		return;
 
-	audio = container_of(dp_audio, struct dp_audio_private, dp_audio);
+	audio = container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio);
 
 	devm_kfree(&audio->pdev->dev, audio);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_audio.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_audio.h
@@ -13,58 +13,58 @@
 #include <sound/hdmi-codec.h>
 
 /**
- * struct dp_audio
+ * struct msm_dp_audio
  * @lane_count: number of lanes configured in current session
  * @bw_code: link rate's bandwidth code for current session
  */
-struct dp_audio {
+struct msm_dp_audio {
 	u32 lane_count;
 	u32 bw_code;
 };
 
 /**
- * dp_audio_get()
+ * msm_dp_audio_get()
  *
  * Creates and instance of dp audio.
  *
  * @pdev: caller's platform device instance.
- * @panel: an instance of dp_panel module.
- * @catalog: an instance of dp_catalog module.
+ * @panel: an instance of msm_dp_panel module.
+ * @catalog: an instance of msm_dp_catalog module.
  *
  * Returns the error code in case of failure, otherwize
- * an instance of newly created dp_module.
+ * an instance of newly created msm_dp_module.
  */
-struct dp_audio *dp_audio_get(struct platform_device *pdev,
-			struct dp_panel *panel,
-			struct dp_catalog *catalog);
+struct msm_dp_audio *msm_dp_audio_get(struct platform_device *pdev,
+			struct msm_dp_panel *panel,
+			struct msm_dp_catalog *catalog);
 
 /**
- * dp_register_audio_driver()
+ * msm_dp_register_audio_driver()
  *
  * Registers DP device with hdmi_codec interface.
  *
  * @dev: DP device instance.
- * @dp_audio: an instance of dp_audio module.
+ * @msm_dp_audio: an instance of msm_dp_audio module.
  *
  *
  * Returns the error code in case of failure, otherwise
  * zero on success.
  */
-int dp_register_audio_driver(struct device *dev,
-		struct dp_audio *dp_audio);
+int msm_dp_register_audio_driver(struct device *dev,
+		struct msm_dp_audio *msm_dp_audio);
 
-void dp_unregister_audio_driver(struct device *dev, struct dp_audio *dp_audio);
+void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm_dp_audio);
 
 /**
- * dp_audio_put()
+ * msm_dp_audio_put()
  *
- * Cleans the dp_audio instance.
+ * Cleans the msm_dp_audio instance.
  *
- * @dp_audio: an instance of dp_audio.
+ * @msm_dp_audio: an instance of msm_dp_audio.
  */
-void dp_audio_put(struct dp_audio *dp_audio);
+void msm_dp_audio_put(struct msm_dp_audio *msm_dp_audio);
 
-int dp_audio_hw_params(struct device *dev,
+int msm_dp_audio_hw_params(struct device *dev,
 	void *data,
 	struct hdmi_codec_daifmt *daifmt,
 	struct hdmi_codec_params *params);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_aux.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_aux.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/phy/phy.h>
 #include <drm/drm_print.h>
 
 #include "dp_reg.h"
@@ -19,9 +20,11 @@
 	DP_AUX_ERR_PHY,
 };
 
-struct dp_aux_private {
+struct msm_dp_aux_private {
 	struct device *dev;
-	struct dp_catalog *catalog;
+	struct msm_dp_catalog *catalog;
+
+	struct phy *phy;
 
 	struct mutex mutex;
 	struct completion comp;
@@ -35,15 +38,16 @@
 	bool no_send_stop;
 	bool initted;
 	bool is_edp;
+	bool enable_xfers;
 	u32 offset;
 	u32 segment;
 
-	struct drm_dp_aux dp_aux;
+	struct drm_dp_aux msm_dp_aux;
 };
 
 #define MAX_AUX_RETRIES			5
 
-static ssize_t dp_aux_write(struct dp_aux_private *aux,
+static ssize_t msm_dp_aux_write(struct msm_dp_aux_private *aux,
 			struct drm_dp_aux_msg *msg)
 {
 	u8 data[4];
@@ -84,12 +88,11 @@
 		/* index = 0, write */
 		if (i == 0)
 			reg |= DP_AUX_DATA_INDEX_WRITE;
-		aux->catalog->aux_data = reg;
-		dp_catalog_aux_write_data(aux->catalog);
+		msm_dp_catalog_aux_write_data(aux->catalog, reg);
 	}
 
-	dp_catalog_aux_clear_trans(aux->catalog, false);
-	dp_catalog_aux_clear_hw_interrupts(aux->catalog);
+	msm_dp_catalog_aux_clear_trans(aux->catalog, false);
+	msm_dp_catalog_aux_clear_hw_interrupts(aux->catalog);
 
 	reg = 0; /* Transaction number == 1 */
 	if (!aux->native) { /* i2c */
@@ -103,13 +106,12 @@
 	}
 
 	reg |= DP_AUX_TRANS_CTRL_GO;
-	aux->catalog->aux_data = reg;
-	dp_catalog_aux_write_trans(aux->catalog);
+	msm_dp_catalog_aux_write_trans(aux->catalog, reg);
 
 	return len;
 }
 
-static ssize_t dp_aux_cmd_fifo_tx(struct dp_aux_private *aux,
+static ssize_t msm_dp_aux_cmd_fifo_tx(struct msm_dp_aux_private *aux,
 			      struct drm_dp_aux_msg *msg)
 {
 	ssize_t ret;
@@ -117,7 +119,7 @@
 
 	reinit_completion(&aux->comp);
 
-	ret = dp_aux_write(aux, msg);
+	ret = msm_dp_aux_write(aux, msg);
 	if (ret < 0)
 		return ret;
 
@@ -129,7 +131,7 @@
 	return ret;
 }
 
-static ssize_t dp_aux_cmd_fifo_rx(struct dp_aux_private *aux,
+static ssize_t msm_dp_aux_cmd_fifo_rx(struct msm_dp_aux_private *aux,
 		struct drm_dp_aux_msg *msg)
 {
 	u32 data;
@@ -137,21 +139,20 @@
 	u32 i, actual_i;
 	u32 len = msg->size;
 
-	dp_catalog_aux_clear_trans(aux->catalog, true);
+	msm_dp_catalog_aux_clear_trans(aux->catalog, true);
 
 	data = DP_AUX_DATA_INDEX_WRITE; /* INDEX_WRITE */
 	data |= DP_AUX_DATA_READ;  /* read */
 
-	aux->catalog->aux_data = data;
-	dp_catalog_aux_write_data(aux->catalog);
+	msm_dp_catalog_aux_write_data(aux->catalog, data);
 
 	dp = msg->buffer;
 
 	/* discard first byte */
-	data = dp_catalog_aux_read_data(aux->catalog);
+	data = msm_dp_catalog_aux_read_data(aux->catalog);
 
 	for (i = 0; i < len; i++) {
-		data = dp_catalog_aux_read_data(aux->catalog);
+		data = msm_dp_catalog_aux_read_data(aux->catalog);
 		*dp++ = (u8)((data >> DP_AUX_DATA_OFFSET) & 0xff);
 
 		actual_i = (data >> DP_AUX_DATA_INDEX_OFFSET) & 0xFF;
@@ -162,7 +163,7 @@
 	return i;
 }
 
-static void dp_aux_update_offset_and_segment(struct dp_aux_private *aux,
+static void msm_dp_aux_update_offset_and_segment(struct msm_dp_aux_private *aux,
 					     struct drm_dp_aux_msg *input_msg)
 {
 	u32 edid_address = 0x50;
@@ -184,7 +185,7 @@
 }
 
 /**
- * dp_aux_transfer_helper() - helper function for EDID read transactions
+ * msm_dp_aux_transfer_helper() - helper function for EDID read transactions
  *
  * @aux: DP AUX private structure
  * @input_msg: input message from DRM upstream APIs
@@ -195,7 +196,7 @@
  * This helper function is used to fix EDID reads for non-compliant
  * sinks that do not handle the i2c middle-of-transaction flag correctly.
  */
-static void dp_aux_transfer_helper(struct dp_aux_private *aux,
+static void msm_dp_aux_transfer_helper(struct msm_dp_aux_private *aux,
 				   struct drm_dp_aux_msg *input_msg,
 				   bool send_seg)
 {
@@ -237,7 +238,7 @@
 		helper_msg.address = segment_address;
 		helper_msg.buffer = &aux->segment;
 		helper_msg.size = 1;
-		dp_aux_cmd_fifo_tx(aux, &helper_msg);
+		msm_dp_aux_cmd_fifo_tx(aux, &helper_msg);
 	}
 
 	/*
@@ -251,7 +252,7 @@
 	helper_msg.address = input_msg->address;
 	helper_msg.buffer = &aux->offset;
 	helper_msg.size = 1;
-	dp_aux_cmd_fifo_tx(aux, &helper_msg);
+	msm_dp_aux_cmd_fifo_tx(aux, &helper_msg);
 
 end:
 	aux->offset += message_size;
@@ -264,15 +265,15 @@
  * It will call aux_reset() function to reset the AUX channel,
  * if the waiting is timeout.
  */
-static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux,
+static ssize_t msm_dp_aux_transfer(struct drm_dp_aux *msm_dp_aux,
 			       struct drm_dp_aux_msg *msg)
 {
 	ssize_t ret;
 	int const aux_cmd_native_max = 16;
 	int const aux_cmd_i2c_max = 128;
-	struct dp_aux_private *aux;
+	struct msm_dp_aux_private *aux;
 
-	aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
 
 	aux->native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
 
@@ -291,7 +292,7 @@
 		return -EINVAL;
 	}
 
-	ret = pm_runtime_resume_and_get(dp_aux->dev);
+	ret = pm_runtime_resume_and_get(msm_dp_aux->dev);
 	if (ret)
 		return  ret;
 
@@ -302,23 +303,18 @@
 	}
 
 	/*
-	 * For eDP it's important to give a reasonably long wait here for HPD
-	 * to be asserted. This is because the panel driver may have _just_
-	 * turned on the panel and then tried to do an AUX transfer. The panel
-	 * driver has no way of knowing when the panel is ready, so it's up
-	 * to us to wait. For DP we never get into this situation so let's
-	 * avoid ever doing the extra long wait for DP.
+	 * If we're using DP and an external display isn't connected then the
+	 * transfer won't succeed. Return right away. If we don't do this we
+	 * can end up with long timeouts if someone tries to access the DP AUX
+	 * character device when no DP device is connected.
 	 */
-	if (aux->is_edp) {
-		ret = dp_catalog_aux_wait_for_hpd_connect_state(aux->catalog);
-		if (ret) {
-			DRM_DEBUG_DP("Panel not ready for aux transactions\n");
-			goto exit;
-		}
+	if (!aux->is_edp && !aux->enable_xfers) {
+		ret = -ENXIO;
+		goto exit;
 	}
 
-	dp_aux_update_offset_and_segment(aux, msg);
-	dp_aux_transfer_helper(aux, msg, true);
+	msm_dp_aux_update_offset_and_segment(aux, msg);
+	msm_dp_aux_transfer_helper(aux, msg, true);
 
 	aux->read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
 	aux->cmd_busy = true;
@@ -331,22 +327,22 @@
 		aux->no_send_stop = true;
 	}
 
-	ret = dp_aux_cmd_fifo_tx(aux, msg);
+	ret = msm_dp_aux_cmd_fifo_tx(aux, msg);
 	if (ret < 0) {
 		if (aux->native) {
 			aux->retry_cnt++;
 			if (!(aux->retry_cnt % MAX_AUX_RETRIES))
-				dp_catalog_aux_update_cfg(aux->catalog);
+				phy_calibrate(aux->phy);
 		}
 		/* reset aux if link is in connected state */
-		if (dp_catalog_link_is_connected(aux->catalog))
-			dp_catalog_aux_reset(aux->catalog);
+		if (msm_dp_catalog_link_is_connected(aux->catalog))
+			msm_dp_catalog_aux_reset(aux->catalog);
 	} else {
 		aux->retry_cnt = 0;
 		switch (aux->aux_error_num) {
 		case DP_AUX_ERR_NONE:
 			if (aux->read)
-				ret = dp_aux_cmd_fifo_rx(aux, msg);
+				ret = msm_dp_aux_cmd_fifo_rx(aux, msg);
 			msg->reply = aux->native ? DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
 			break;
 		case DP_AUX_ERR_DEFER:
@@ -368,24 +364,24 @@
 
 exit:
 	mutex_unlock(&aux->mutex);
-	pm_runtime_put_sync(dp_aux->dev);
+	pm_runtime_put_sync(msm_dp_aux->dev);
 
 	return ret;
 }
 
-irqreturn_t dp_aux_isr(struct drm_dp_aux *dp_aux)
+irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux)
 {
 	u32 isr;
-	struct dp_aux_private *aux;
+	struct msm_dp_aux_private *aux;
 
-	if (!dp_aux) {
+	if (!msm_dp_aux) {
 		DRM_ERROR("invalid input\n");
 		return IRQ_NONE;
 	}
 
-	aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
 
-	isr = dp_catalog_aux_get_irq(aux->catalog);
+	isr = msm_dp_catalog_aux_get_irq(aux->catalog);
 
 	/* no interrupts pending, return immediately */
 	if (!isr)
@@ -407,7 +403,7 @@
 
 	if (isr & DP_INTR_AUX_ERROR) {
 		aux->aux_error_num = DP_AUX_ERR_PHY;
-		dp_catalog_aux_clear_hw_interrupts(aux->catalog);
+		msm_dp_catalog_aux_clear_hw_interrupts(aux->catalog);
 	} else if (isr & DP_INTR_NACK_DEFER) {
 		aux->aux_error_num = DP_AUX_ERR_NACK_DEFER;
 	} else if (isr & DP_INTR_WRONG_ADDR) {
@@ -433,60 +429,68 @@
 	return IRQ_HANDLED;
 }
 
-void dp_aux_reconfig(struct drm_dp_aux *dp_aux)
+void msm_dp_aux_enable_xfers(struct drm_dp_aux *msm_dp_aux, bool enabled)
+{
+	struct msm_dp_aux_private *aux;
+
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+	aux->enable_xfers = enabled;
+}
+
+void msm_dp_aux_reconfig(struct drm_dp_aux *msm_dp_aux)
 {
-	struct dp_aux_private *aux;
+	struct msm_dp_aux_private *aux;
 
-	aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
 
-	dp_catalog_aux_update_cfg(aux->catalog);
-	dp_catalog_aux_reset(aux->catalog);
+	phy_calibrate(aux->phy);
+	msm_dp_catalog_aux_reset(aux->catalog);
 }
 
-void dp_aux_init(struct drm_dp_aux *dp_aux)
+void msm_dp_aux_init(struct drm_dp_aux *msm_dp_aux)
 {
-	struct dp_aux_private *aux;
+	struct msm_dp_aux_private *aux;
 
-	if (!dp_aux) {
+	if (!msm_dp_aux) {
 		DRM_ERROR("invalid input\n");
 		return;
 	}
 
-	aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
 
 	mutex_lock(&aux->mutex);
 
-	dp_catalog_aux_enable(aux->catalog, true);
+	msm_dp_catalog_aux_enable(aux->catalog, true);
 	aux->retry_cnt = 0;
 	aux->initted = true;
 
 	mutex_unlock(&aux->mutex);
 }
 
-void dp_aux_deinit(struct drm_dp_aux *dp_aux)
+void msm_dp_aux_deinit(struct drm_dp_aux *msm_dp_aux)
 {
-	struct dp_aux_private *aux;
+	struct msm_dp_aux_private *aux;
 
-	aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
 
 	mutex_lock(&aux->mutex);
 
 	aux->initted = false;
-	dp_catalog_aux_enable(aux->catalog, false);
+	msm_dp_catalog_aux_enable(aux->catalog, false);
 
 	mutex_unlock(&aux->mutex);
 }
 
-int dp_aux_register(struct drm_dp_aux *dp_aux)
+int msm_dp_aux_register(struct drm_dp_aux *msm_dp_aux)
 {
 	int ret;
 
-	if (!dp_aux) {
+	if (!msm_dp_aux) {
 		DRM_ERROR("invalid input\n");
 		return -EINVAL;
 	}
 
-	ret = drm_dp_aux_register(dp_aux);
+	ret = drm_dp_aux_register(msm_dp_aux);
 	if (ret) {
 		DRM_ERROR("%s: failed to register drm aux: %d\n", __func__,
 				ret);
@@ -496,30 +500,35 @@
 	return 0;
 }
 
-void dp_aux_unregister(struct drm_dp_aux *dp_aux)
+void msm_dp_aux_unregister(struct drm_dp_aux *msm_dp_aux)
 {
-	drm_dp_aux_unregister(dp_aux);
+	drm_dp_aux_unregister(msm_dp_aux);
 }
 
-static int dp_wait_hpd_asserted(struct drm_dp_aux *dp_aux,
+static int msm_dp_wait_hpd_asserted(struct drm_dp_aux *msm_dp_aux,
 				 unsigned long wait_us)
 {
 	int ret;
-	struct dp_aux_private *aux;
+	struct msm_dp_aux_private *aux;
 
-	aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
 
 	pm_runtime_get_sync(aux->dev);
-	ret = dp_catalog_aux_wait_for_hpd_connect_state(aux->catalog);
+	ret = pm_runtime_resume_and_get(aux->dev);
+	if (ret)
+		return ret;
+
+	ret = msm_dp_catalog_aux_wait_for_hpd_connect_state(aux->catalog, wait_us);
 	pm_runtime_put_sync(aux->dev);
 
 	return ret;
 }
 
-struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog,
+struct drm_dp_aux *msm_dp_aux_get(struct device *dev, struct msm_dp_catalog *catalog,
+			      struct phy *phy,
 			      bool is_edp)
 {
-	struct dp_aux_private *aux;
+	struct msm_dp_aux_private *aux;
 
 	if (!catalog) {
 		DRM_ERROR("invalid input\n");
@@ -537,6 +546,7 @@
 
 	aux->dev = dev;
 	aux->catalog = catalog;
+	aux->phy = phy;
 	aux->retry_cnt = 0;
 
 	/*
@@ -544,23 +554,23 @@
 	 * before registering AUX with the DRM device so that
 	 * msm eDP panel can be detected by generic_dep_panel_probe().
 	 */
-	aux->dp_aux.name = "dpu_dp_aux";
-	aux->dp_aux.dev = dev;
-	aux->dp_aux.transfer = dp_aux_transfer;
-	aux->dp_aux.wait_hpd_asserted = dp_wait_hpd_asserted;
-	drm_dp_aux_init(&aux->dp_aux);
+	aux->msm_dp_aux.name = "dpu_dp_aux";
+	aux->msm_dp_aux.dev = dev;
+	aux->msm_dp_aux.transfer = msm_dp_aux_transfer;
+	aux->msm_dp_aux.wait_hpd_asserted = msm_dp_wait_hpd_asserted;
+	drm_dp_aux_init(&aux->msm_dp_aux);
 
-	return &aux->dp_aux;
+	return &aux->msm_dp_aux;
 }
 
-void dp_aux_put(struct drm_dp_aux *dp_aux)
+void msm_dp_aux_put(struct drm_dp_aux *msm_dp_aux)
 {
-	struct dp_aux_private *aux;
+	struct msm_dp_aux_private *aux;
 
-	if (!dp_aux)
+	if (!msm_dp_aux)
 		return;
 
-	aux = container_of(dp_aux, struct dp_aux_private, dp_aux);
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
 
 	mutex_destroy(&aux->mutex);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_aux.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_aux.h
@@ -8,16 +8,20 @@
 
 #include "dp_catalog.h"
 #include <drm/display/drm_dp_helper.h>
+#include <drm/display/drm_dp_mst_helper.h>
 
-int dp_aux_register(struct drm_dp_aux *dp_aux);
-void dp_aux_unregister(struct drm_dp_aux *dp_aux);
-irqreturn_t dp_aux_isr(struct drm_dp_aux *dp_aux);
-void dp_aux_init(struct drm_dp_aux *dp_aux);
-void dp_aux_deinit(struct drm_dp_aux *dp_aux);
-void dp_aux_reconfig(struct drm_dp_aux *dp_aux);
+int msm_dp_aux_register(struct drm_dp_aux *msm_dp_aux);
+void msm_dp_aux_unregister(struct drm_dp_aux *msm_dp_aux);
+irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux);
+void msm_dp_aux_enable_xfers(struct drm_dp_aux *msm_dp_aux, bool enabled);
+void msm_dp_aux_init(struct drm_dp_aux *msm_dp_aux);
+void msm_dp_aux_deinit(struct drm_dp_aux *msm_dp_aux);
+void msm_dp_aux_reconfig(struct drm_dp_aux *msm_dp_aux);
 
-struct drm_dp_aux *dp_aux_get(struct device *dev, struct dp_catalog *catalog,
+struct phy;
+struct drm_dp_aux *msm_dp_aux_get(struct device *dev, struct msm_dp_catalog *catalog,
+			      struct phy *phy,
 			      bool is_edp);
-void dp_aux_put(struct drm_dp_aux *aux);
+void msm_dp_aux_put(struct drm_dp_aux *aux);
 
 #endif /*__DP_AUX_H_*/
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -7,8 +7,7 @@
 
 #include <linux/delay.h>
 #include <linux/iopoll.h>
-#include <linux/phy/phy.h>
-#include <linux/phy/phy-dp.h>
+#include <linux/platform_device.h>
 #include <linux/rational.h>
 #include <drm/display/drm_dp_helper.h>
 #include <drm/drm_print.h>
@@ -51,155 +50,282 @@
 	(PSR_UPDATE_INT | PSR_CAPTURE_INT | PSR_EXIT_INT | \
 	PSR_UPDATE_ERROR_INT | PSR_WAKE_ERROR_INT)
 
+#define DP_INTERRUPT_STATUS5 \
+	(DP_INTR_DP0_VCPF_SENT | DP_INTR_DP1_VCPF_SENT)
+#define DP_INTERRUPT_STATUS5_MASK \
+	(DP_INTERRUPT_STATUS5 << DP_INTERRUPT_STATUS_MASK_SHIFT)
+
 #define DP_INTERRUPT_MASK4 \
 	(PSR_UPDATE_MASK | PSR_CAPTURE_MASK | PSR_EXIT_MASK | \
 	PSR_UPDATE_ERROR_MASK | PSR_WAKE_ERROR_MASK)
 
-struct dp_catalog_private {
+#define DP_DEFAULT_AHB_OFFSET	0x0000
+#define DP_DEFAULT_AHB_SIZE	0x0200
+#define DP_DEFAULT_AUX_OFFSET	0x0200
+#define DP_DEFAULT_AUX_SIZE	0x0200
+#define DP_DEFAULT_LINK_OFFSET	0x0400
+#define DP_DEFAULT_LINK_SIZE	0x0C00
+#define DP_DEFAULT_P0_OFFSET	0x1000
+#define DP_DEFAULT_P0_SIZE	0x0400
+
+struct dss_io_region {
+	size_t len;
+	void __iomem *base;
+};
+
+struct dss_io_data {
+	struct dss_io_region ahb;
+	struct dss_io_region aux;
+	struct dss_io_region link;
+	struct dss_io_region mst2_link;
+	struct dss_io_region mst3_link;
+	struct dss_io_region p0;
+	struct dss_io_region p1;
+	struct dss_io_region p2;
+	struct dss_io_region p3;
+};
+
+struct msm_dp_catalog_private {
 	struct device *dev;
 	struct drm_device *drm_dev;
-	struct dp_io *io;
+	struct dss_io_data io;
 	u32 (*audio_map)[DP_AUDIO_SDP_HEADER_MAX];
-	struct dp_catalog dp_catalog;
-	u8 aux_lut_cfg_index[PHY_AUX_CFG_MAX];
+	struct msm_dp_catalog msm_dp_catalog;
 };
 
-void dp_catalog_snapshot(struct dp_catalog *dp_catalog, struct msm_disp_state *disp_state)
+void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_disp_state *disp_state)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-			struct dp_catalog_private, dp_catalog);
-	struct dss_io_data *dss = &catalog->io->dp_controller;
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+			struct msm_dp_catalog_private, msm_dp_catalog);
+	struct dss_io_data *dss = &catalog->io;
 
 	msm_disp_snapshot_add_block(disp_state, dss->ahb.len, dss->ahb.base, "dp_ahb");
 	msm_disp_snapshot_add_block(disp_state, dss->aux.len, dss->aux.base, "dp_aux");
 	msm_disp_snapshot_add_block(disp_state, dss->link.len, dss->link.base, "dp_link");
+	msm_disp_snapshot_add_block(disp_state, dss->mst2_link.len, dss->mst2_link.base,
+				    "dp_mst2_link");
+	msm_disp_snapshot_add_block(disp_state, dss->mst3_link.len, dss->mst3_link.base,
+				    "dp_mst3_link");
 	msm_disp_snapshot_add_block(disp_state, dss->p0.len, dss->p0.base, "dp_p0");
+	msm_disp_snapshot_add_block(disp_state, dss->p1.len, dss->p1.base, "dp_p1");
+	msm_disp_snapshot_add_block(disp_state, dss->p2.len, dss->p2.base, "dp_p2");
+	msm_disp_snapshot_add_block(disp_state, dss->p3.len, dss->p3.base, "dp_p3");
 }
 
-static inline u32 dp_read_aux(struct dp_catalog_private *catalog, u32 offset)
+static inline u32 msm_dp_read_aux(struct msm_dp_catalog_private *catalog, u32 offset)
 {
-	return readl_relaxed(catalog->io->dp_controller.aux.base + offset);
+	return readl_relaxed(catalog->io.aux.base + offset);
 }
 
-static inline void dp_write_aux(struct dp_catalog_private *catalog,
+static inline void msm_dp_write_aux(struct msm_dp_catalog_private *catalog,
 			       u32 offset, u32 data)
 {
 	/*
 	 * To make sure aux reg writes happens before any other operation,
 	 * this function uses writel() instread of writel_relaxed()
 	 */
-	writel(data, catalog->io->dp_controller.aux.base + offset);
+	writel(data, catalog->io.aux.base + offset);
 }
 
-static inline u32 dp_read_ahb(const struct dp_catalog_private *catalog, u32 offset)
+static inline u32 msm_dp_read_ahb(const struct msm_dp_catalog_private *catalog, u32 offset)
 {
-	return readl_relaxed(catalog->io->dp_controller.ahb.base + offset);
+	return readl_relaxed(catalog->io.ahb.base + offset);
 }
 
-static inline void dp_write_ahb(struct dp_catalog_private *catalog,
+static inline void msm_dp_write_ahb(struct msm_dp_catalog_private *catalog,
 			       u32 offset, u32 data)
 {
 	/*
 	 * To make sure phy reg writes happens before any other operation,
 	 * this function uses writel() instread of writel_relaxed()
 	 */
-	writel(data, catalog->io->dp_controller.ahb.base + offset);
+	writel(data, catalog->io.ahb.base + offset);
 }
 
-static inline void dp_write_p0(struct dp_catalog_private *catalog,
+static inline void msm_dp_write_p0(struct msm_dp_catalog_private *catalog,
 			       u32 offset, u32 data)
 {
 	/*
 	 * To make sure interface reg writes happens before any other operation,
 	 * this function uses writel() instread of writel_relaxed()
 	 */
-	writel(data, catalog->io->dp_controller.p0.base + offset);
+	writel(data, catalog->io.p0.base + offset);
 }
 
-static inline u32 dp_read_p0(struct dp_catalog_private *catalog,
+static inline u32 msm_dp_read_p0(struct msm_dp_catalog_private *catalog,
 			       u32 offset)
 {
 	/*
 	 * To make sure interface reg writes happens before any other operation,
 	 * this function uses writel() instread of writel_relaxed()
 	 */
-	return readl_relaxed(catalog->io->dp_controller.p0.base + offset);
+	return readl_relaxed(catalog->io.p0.base + offset);
+}
+
+static inline void msm_dp_write_p1(struct msm_dp_catalog_private *catalog,
+				   u32 offset, u32 data)
+{
+	/*
+	 * To make sure interface reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	writel(data, catalog->io.p1.base + offset);
+}
+
+static inline u32 msm_dp_read_p1(struct msm_dp_catalog_private *catalog,
+				 u32 offset)
+{
+	/*
+	 * To make sure interface reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	return readl_relaxed(catalog->io.p1.base + offset);
+}
+
+static inline void msm_dp_write_p2(struct msm_dp_catalog_private *catalog,
+				   u32 offset, u32 data)
+{
+	/*
+	 * To make sure interface reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	writel(data, catalog->io.p2.base + offset);
+}
+
+static inline u32 msm_dp_read_p2(struct msm_dp_catalog_private *catalog,
+				 u32 offset)
+{
+	/*
+	 * To make sure interface reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	return readl_relaxed(catalog->io.p2.base + offset);
+}
+
+static inline void msm_dp_write_p3(struct msm_dp_catalog_private *catalog,
+				   u32 offset, u32 data)
+{
+	/*
+	 * To make sure interface reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	writel(data, catalog->io.p3.base + offset);
+}
+
+static inline u32 msm_dp_read_p3(struct msm_dp_catalog_private *catalog,
+				 u32 offset)
+{
+	/*
+	 * To make sure interface reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	return readl_relaxed(catalog->io.p3.base + offset);
 }
 
-static inline u32 dp_read_link(struct dp_catalog_private *catalog, u32 offset)
+static inline u32 msm_dp_read_link(struct msm_dp_catalog_private *catalog, u32 offset)
 {
-	return readl_relaxed(catalog->io->dp_controller.link.base + offset);
+	return readl_relaxed(catalog->io.link.base + offset);
 }
 
-static inline void dp_write_link(struct dp_catalog_private *catalog,
+static inline void msm_dp_write_link(struct msm_dp_catalog_private *catalog,
 			       u32 offset, u32 data)
 {
 	/*
 	 * To make sure link reg writes happens before any other operation,
 	 * this function uses writel() instread of writel_relaxed()
 	 */
-	writel(data, catalog->io->dp_controller.link.base + offset);
+	writel(data, catalog->io.link.base + offset);
+}
+
+static inline u32 msm_dp_read_mst2_link(struct msm_dp_catalog_private *catalog, u32 offset)
+{
+	return readl_relaxed(catalog->io.mst2_link.base + offset);
+}
+
+static inline void msm_dp_write_mst2_link(struct msm_dp_catalog_private *catalog,
+					  u32 offset, u32 data)
+{
+	/*
+	 * To make sure link reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	writel(data, catalog->io.mst2_link.base + offset);
+}
+
+static inline u32 msm_dp_read_mst3_link(struct msm_dp_catalog_private *catalog, u32 offset)
+{
+	return readl_relaxed(catalog->io.mst3_link.base + offset);
+}
+
+static inline void msm_dp_write_mst3_link(struct msm_dp_catalog_private *catalog,
+					  u32 offset, u32 data)
+{
+	/*
+	 * To make sure link reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	writel(data, catalog->io.mst3_link.base + offset);
 }
 
 /* aux related catalog functions */
-u32 dp_catalog_aux_read_data(struct dp_catalog *dp_catalog)
+u32 msm_dp_catalog_aux_read_data(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	return dp_read_aux(catalog, REG_DP_AUX_DATA);
+	return msm_dp_read_aux(catalog, REG_DP_AUX_DATA);
 }
 
-int dp_catalog_aux_write_data(struct dp_catalog *dp_catalog)
+int msm_dp_catalog_aux_write_data(struct msm_dp_catalog *msm_dp_catalog, u32 data)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	dp_write_aux(catalog, REG_DP_AUX_DATA, dp_catalog->aux_data);
+	msm_dp_write_aux(catalog, REG_DP_AUX_DATA, data);
 	return 0;
 }
 
-int dp_catalog_aux_write_trans(struct dp_catalog *dp_catalog)
+int msm_dp_catalog_aux_write_trans(struct msm_dp_catalog *msm_dp_catalog, u32 data)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, dp_catalog->aux_data);
+	msm_dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, data);
 	return 0;
 }
 
-int dp_catalog_aux_clear_trans(struct dp_catalog *dp_catalog, bool read)
+int msm_dp_catalog_aux_clear_trans(struct msm_dp_catalog *msm_dp_catalog, bool read)
 {
 	u32 data;
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
 	if (read) {
-		data = dp_read_aux(catalog, REG_DP_AUX_TRANS_CTRL);
+		data = msm_dp_read_aux(catalog, REG_DP_AUX_TRANS_CTRL);
 		data &= ~DP_AUX_TRANS_CTRL_GO;
-		dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, data);
+		msm_dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, data);
 	} else {
-		dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, 0);
+		msm_dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, 0);
 	}
 	return 0;
 }
 
-int dp_catalog_aux_clear_hw_interrupts(struct dp_catalog *dp_catalog)
+int msm_dp_catalog_aux_clear_hw_interrupts(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	dp_read_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_STATUS);
-	dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x1f);
-	dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x9f);
-	dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0);
+	msm_dp_read_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_STATUS);
+	msm_dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x1f);
+	msm_dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x9f);
+	msm_dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0);
 	return 0;
 }
 
 /**
- * dp_catalog_aux_reset() - reset AUX controller
+ * msm_dp_catalog_aux_reset() - reset AUX controller
  *
- * @dp_catalog: DP catalog structure
+ * @msm_dp_catalog: DP catalog structure
  *
  * return: void
  *
@@ -208,62 +334,53 @@
  * NOTE: reset AUX controller will also clear any pending HPD related interrupts
  * 
  */
-void dp_catalog_aux_reset(struct dp_catalog *dp_catalog)
+void msm_dp_catalog_aux_reset(struct msm_dp_catalog *msm_dp_catalog)
 {
 	u32 aux_ctrl;
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	aux_ctrl = dp_read_aux(catalog, REG_DP_AUX_CTRL);
+	aux_ctrl = msm_dp_read_aux(catalog, REG_DP_AUX_CTRL);
 
 	aux_ctrl |= DP_AUX_CTRL_RESET;
-	dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
+	msm_dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
 	usleep_range(1000, 1100); /* h/w recommended delay */
 
 	aux_ctrl &= ~DP_AUX_CTRL_RESET;
-	dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
+	msm_dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
 }
 
-void dp_catalog_aux_enable(struct dp_catalog *dp_catalog, bool enable)
+void msm_dp_catalog_aux_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable)
 {
 	u32 aux_ctrl;
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	aux_ctrl = dp_read_aux(catalog, REG_DP_AUX_CTRL);
+	aux_ctrl = msm_dp_read_aux(catalog, REG_DP_AUX_CTRL);
 
 	if (enable) {
-		dp_write_aux(catalog, REG_DP_TIMEOUT_COUNT, 0xffff);
-		dp_write_aux(catalog, REG_DP_AUX_LIMITS, 0xffff);
+		msm_dp_write_aux(catalog, REG_DP_TIMEOUT_COUNT, 0xffff);
+		msm_dp_write_aux(catalog, REG_DP_AUX_LIMITS, 0xffff);
 		aux_ctrl |= DP_AUX_CTRL_ENABLE;
 	} else {
 		aux_ctrl &= ~DP_AUX_CTRL_ENABLE;
 	}
 
-	dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
+	msm_dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
 }
 
-void dp_catalog_aux_update_cfg(struct dp_catalog *dp_catalog)
-{
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
-	struct dp_io *dp_io = catalog->io;
-	struct phy *phy = dp_io->phy;
-
-	phy_calibrate(phy);
-}
-
-int dp_catalog_aux_wait_for_hpd_connect_state(struct dp_catalog *dp_catalog)
+int msm_dp_catalog_aux_wait_for_hpd_connect_state(struct msm_dp_catalog *msm_dp_catalog,
+					      unsigned long wait_us)
 {
 	u32 state;
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	/* poll for hpd connected status every 2ms and timeout after 500ms */
-	return readl_poll_timeout(catalog->io->dp_controller.aux.base +
+	/* poll for hpd connected status every 2ms and timeout after wait_us */
+	return readl_poll_timeout(catalog->io.aux.base +
 				REG_DP_DP_HPD_INT_STATUS,
 				state, state & DP_DP_HPD_STATE_STATUS_CONNECTED,
-				2000, 500000);
+				min(wait_us, 2000), wait_us);
 }
 
 static void dump_regs(void __iomem *base, int len)
@@ -284,11 +401,11 @@
 	}
 }
 
-void dp_catalog_dump_regs(struct dp_catalog *dp_catalog)
+void msm_dp_catalog_dump_regs(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-		struct dp_catalog_private, dp_catalog);
-	struct dss_io_data *io = &catalog->io->dp_controller;
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
+	struct dss_io_data *io = &catalog->io;
 
 	pr_info("AHB regs\n");
 	dump_regs(io->ahb.base, io->ahb.len);
@@ -303,17 +420,17 @@
 	dump_regs(io->p0.base, io->p0.len);
 }
 
-u32 dp_catalog_aux_get_irq(struct dp_catalog *dp_catalog)
+u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 intr, intr_ack;
 
-	intr = dp_read_ahb(catalog, REG_DP_INTR_STATUS);
+	intr = msm_dp_read_ahb(catalog, REG_DP_INTR_STATUS);
 	intr &= ~DP_INTERRUPT_STATUS1_MASK;
 	intr_ack = (intr & DP_INTERRUPT_STATUS1)
 			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
-	dp_write_ahb(catalog, REG_DP_INTR_STATUS, intr_ack |
+	msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS, intr_ack |
 			DP_INTERRUPT_STATUS1_MASK);
 
 	return intr;
@@ -321,40 +438,66 @@
 }
 
 /* controller related catalog functions */
-void dp_catalog_ctrl_update_transfer_unit(struct dp_catalog *dp_catalog,
-				u32 dp_tu, u32 valid_boundary,
+void msm_dp_catalog_ctrl_update_transfer_unit(struct msm_dp_catalog *msm_dp_catalog,
+				u32 msm_dp_tu, u32 valid_boundary,
 				u32 valid_boundary2)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	msm_dp_write_link(catalog, REG_DP_VALID_BOUNDARY, valid_boundary);
+	msm_dp_write_link(catalog, REG_DP_TU, msm_dp_tu);
+	msm_dp_write_link(catalog, REG_DP_VALID_BOUNDARY_2, valid_boundary2);
+}
+
+void msm_dp_catalog_ctrl_state_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 state)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	dp_write_link(catalog, REG_DP_VALID_BOUNDARY, valid_boundary);
-	dp_write_link(catalog, REG_DP_TU, dp_tu);
-	dp_write_link(catalog, REG_DP_VALID_BOUNDARY_2, valid_boundary2);
+	msm_dp_write_link(catalog, REG_DP_STATE_CTRL, state);
 }
 
-void dp_catalog_ctrl_state_ctrl(struct dp_catalog *dp_catalog, u32 state)
+void msm_dp_catalog_ctrl_mst2_state_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 state)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	dp_write_link(catalog, REG_DP_STATE_CTRL, state);
+	msm_dp_write_mst2_link(catalog, REG_DP_MST2_MST3_STATE_CTRL, state);
 }
 
-void dp_catalog_ctrl_config_ctrl(struct dp_catalog *dp_catalog, u32 cfg)
+void msm_dp_catalog_ctrl_mst3_state_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 state)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	drm_dbg_dp(catalog->drm_dev, "DP_CONFIGURATION_CTRL=0x%x\n", cfg);
+	msm_dp_write_mst3_link(catalog, REG_DP_MST2_MST3_STATE_CTRL, state);
+}
+
+void msm_dp_catalog_ctrl_config_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 cfg)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+	u32 reg_offset = 0;
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_1)
+		reg_offset = REG_DP1_CONFIGURATION_CTRL - REG_DP_CONFIGURATION_CTRL;
 
-	dp_write_link(catalog, REG_DP_CONFIGURATION_CTRL, cfg);
+	drm_dbg_dp(catalog->drm_dev, "stream_id:%d DP_CONFIGURATION_CTRL=0x%x\n",
+		msm_dp_catalog->stream_id, cfg);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_3)
+		msm_dp_write_mst3_link(catalog, REG_DP_MST2_MST3_CONFIGURATION_CTRL, cfg);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_2)
+		msm_dp_write_mst2_link(catalog, REG_DP_MST2_MST3_CONFIGURATION_CTRL, cfg);
+	else
+		msm_dp_write_link(catalog, REG_DP_CONFIGURATION_CTRL + reg_offset, cfg);
 }
 
-void dp_catalog_ctrl_lane_mapping(struct dp_catalog *dp_catalog)
+void msm_dp_catalog_ctrl_lane_mapping(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 ln_0 = 0, ln_1 = 1, ln_2 = 2, ln_3 = 3; /* One-to-One mapping */
 	u32 ln_mapping;
 
@@ -363,71 +506,98 @@
 	ln_mapping |= ln_2 << LANE2_MAPPING_SHIFT;
 	ln_mapping |= ln_3 << LANE3_MAPPING_SHIFT;
 
-	dp_write_link(catalog, REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING,
+	msm_dp_write_link(catalog, REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING,
 			ln_mapping);
 }
 
-void dp_catalog_ctrl_psr_mainlink_enable(struct dp_catalog *dp_catalog,
+void msm_dp_catalog_ctrl_psr_mainlink_enable(struct msm_dp_catalog *msm_dp_catalog,
 						bool enable)
 {
 	u32 val;
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	val = dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+	val = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
 
 	if (enable)
 		val |= DP_MAINLINK_CTRL_ENABLE;
 	else
 		val &= ~DP_MAINLINK_CTRL_ENABLE;
 
-	dp_write_link(catalog, REG_DP_MAINLINK_CTRL, val);
+	msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, val);
 }
 
-void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog *dp_catalog,
-						bool enable)
+void msm_dp_catalog_mst_config(struct msm_dp_catalog *msm_dp_catalog, bool enable)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+							      struct msm_dp_catalog_private,
+							      msm_dp_catalog);
+
+	u32 mainlink_ctrl;
+
+	mainlink_ctrl = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+	if (enable)
+		mainlink_ctrl |= (0x04000100);
+	else
+		mainlink_ctrl &= ~(0x04000100);
+
+	msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+}
+
+void msm_dp_catalog_ctrl_mainlink_ctrl(struct msm_dp_catalog *msm_dp_catalog,
+				       bool enable)
 {
 	u32 mainlink_ctrl;
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
 	drm_dbg_dp(catalog->drm_dev, "enable=%d\n", enable);
 	if (enable) {
 		/*
 		 * To make sure link reg writes happens before other operation,
-		 * dp_write_link() function uses writel()
+		 * msm_dp_write_link() function uses writel()
 		 */
-		mainlink_ctrl = dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+		mainlink_ctrl = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
 
 		mainlink_ctrl &= ~(DP_MAINLINK_CTRL_RESET |
 						DP_MAINLINK_CTRL_ENABLE);
-		dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
 
 		mainlink_ctrl |= DP_MAINLINK_CTRL_RESET;
-		dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
 
 		mainlink_ctrl &= ~DP_MAINLINK_CTRL_RESET;
-		dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
 
 		mainlink_ctrl |= (DP_MAINLINK_CTRL_ENABLE |
 					DP_MAINLINK_FB_BOUNDARY_SEL);
-		dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
 	} else {
-		mainlink_ctrl = dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+		mainlink_ctrl = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
 		mainlink_ctrl &= ~DP_MAINLINK_CTRL_ENABLE;
-		dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
 	}
 }
 
-void dp_catalog_ctrl_config_misc(struct dp_catalog *dp_catalog,
+void msm_dp_catalog_ctrl_config_misc(struct msm_dp_catalog *msm_dp_catalog,
 					u32 colorimetry_cfg,
 					u32 test_bits_depth)
 {
 	u32 misc_val;
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	u32 reg_offset = 0;
+
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	if (msm_dp_catalog->stream_id >= DP_STREAM_MAX) {
+		DRM_ERROR("invalid stream_id:%d\n", msm_dp_catalog->stream_id);
+		return;
+	}
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_1)
+		reg_offset = REG_DP1_MISC1_MISC0 - REG_DP_MISC1_MISC0;
 
-	misc_val = dp_read_link(catalog, REG_DP_MISC1_MISC0);
+	misc_val = msm_dp_read_link(catalog, REG_DP_MISC1_MISC0 + reg_offset);
 
 	/* clear bpp bits */
 	misc_val &= ~(0x07 << DP_MISC0_TEST_BITS_DEPTH_SHIFT);
@@ -437,12 +607,34 @@
 	misc_val |= DP_MISC0_SYNCHRONOUS_CLK;
 
 	drm_dbg_dp(catalog->drm_dev, "misc settings = 0x%x\n", misc_val);
-	dp_write_link(catalog, REG_DP_MISC1_MISC0, misc_val);
+	if (msm_dp_catalog->stream_id == DP_STREAM_3)
+		msm_dp_write_mst3_link(catalog, REG_DP_MST2_MST3_MISC1_MISC0, misc_val);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_2)
+		msm_dp_write_mst2_link(catalog, REG_DP_MST2_MST3_MISC1_MISC0, misc_val);
+	else
+		msm_dp_write_link(catalog, REG_DP_MISC1_MISC0 + reg_offset, misc_val);
 }
 
-void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog,
+void msm_dp_catalog_setup_peripheral_flush(struct msm_dp_catalog *msm_dp_catalog)
+{
+	u32 mainlink_ctrl, hw_revision;
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	mainlink_ctrl = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+
+	hw_revision = msm_dp_catalog_hw_revision(msm_dp_catalog);
+	if (hw_revision >= DP_HW_VERSION_1_2)
+		mainlink_ctrl |= DP_MAINLINK_FLUSH_MODE_SDE_PERIPH_UPDATE;
+	else
+		mainlink_ctrl |= DP_MAINLINK_FLUSH_MODE_UPDATE_SDP;
+
+	msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+}
+
+void msm_dp_catalog_ctrl_config_msa(struct msm_dp_catalog *msm_dp_catalog,
 					u32 rate, u32 stream_rate_khz,
-					bool fixed_nvid)
+					bool is_ycbcr_420)
 {
 	u32 pixel_m, pixel_n;
 	u32 mvid, nvid, pixel_div = 0, dispcc_input_rate;
@@ -450,9 +642,20 @@
 	u32 const link_rate_hbr2 = 540000;
 	u32 const link_rate_hbr3 = 810000;
 	unsigned long den, num;
+	u32 mvid_reg_off = 0, nvid_reg_off = 0;
+
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	if (msm_dp_catalog->stream_id >= DP_STREAM_MAX) {
+		DRM_ERROR("invalid stream_id:%d\n", msm_dp_catalog->stream_id);
+		return;
+	}
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_1) {
+		mvid_reg_off = REG_DP1_SOFTWARE_MVID - REG_DP_SOFTWARE_MVID;
+		nvid_reg_off = REG_DP1_SOFTWARE_NVID - REG_DP_SOFTWARE_NVID;
+	}
 
 	if (rate == link_rate_hbr3)
 		pixel_div = 6;
@@ -485,6 +688,9 @@
 		nvid = temp;
 	}
 
+	if (is_ycbcr_420)
+		mvid /= 2;
+
 	if (link_rate_hbr2 == rate)
 		nvid *= 2;
 
@@ -492,27 +698,44 @@
 		nvid *= 3;
 
 	drm_dbg_dp(catalog->drm_dev, "mvid=0x%x, nvid=0x%x\n", mvid, nvid);
-	dp_write_link(catalog, REG_DP_SOFTWARE_MVID, mvid);
-	dp_write_link(catalog, REG_DP_SOFTWARE_NVID, nvid);
-	dp_write_p0(catalog, MMSS_DP_DSC_DTO, 0x0);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_3) {
+		msm_dp_write_mst3_link(catalog, REG_MST2_MST3_SOFTWARE_MVID, mvid);
+		msm_dp_write_mst3_link(catalog, REG_MST2_MST3_SOFTWARE_NVID, nvid);
+	} else if (msm_dp_catalog->stream_id == DP_STREAM_2) {
+		msm_dp_write_mst2_link(catalog, REG_MST2_MST3_SOFTWARE_MVID, mvid);
+		msm_dp_write_mst2_link(catalog, REG_MST2_MST3_SOFTWARE_NVID, nvid);
+	} else {
+		msm_dp_write_link(catalog, REG_DP_SOFTWARE_MVID + mvid_reg_off, mvid);
+		msm_dp_write_link(catalog, REG_DP_SOFTWARE_NVID + nvid_reg_off, nvid);
+	}
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_0)
+		msm_dp_write_p0(catalog, MMSS_DP_DSC_DTO, 0x0);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_1)
+		msm_dp_write_p1(catalog, MMSS_DP_DSC_DTO, 0x0);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_2)
+		msm_dp_write_p2(catalog, MMSS_DP_DSC_DTO, 0x0);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_3)
+		msm_dp_write_p3(catalog, MMSS_DP_DSC_DTO, 0x0);
 }
 
-int dp_catalog_ctrl_set_pattern_state_bit(struct dp_catalog *dp_catalog,
+int msm_dp_catalog_ctrl_set_pattern_state_bit(struct msm_dp_catalog *msm_dp_catalog,
 					u32 state_bit)
 {
 	int bit, ret;
 	u32 data;
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
 	bit = BIT(state_bit - 1);
 	drm_dbg_dp(catalog->drm_dev, "hw: bit=%d train=%d\n", bit, state_bit);
-	dp_catalog_ctrl_state_ctrl(dp_catalog, bit);
+	msm_dp_catalog_ctrl_state_ctrl(msm_dp_catalog, bit);
 
 	bit = BIT(state_bit - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT;
 
 	/* Poll for mainlink ready status */
-	ret = readx_poll_timeout(readl, catalog->io->dp_controller.link.base +
+	ret = readx_poll_timeout(readl, catalog->io.link.base +
 					REG_DP_MAINLINK_READY,
 					data, data & bit,
 					POLLING_SLEEP_US, POLLING_TIMEOUT_US);
@@ -524,25 +747,25 @@
 }
 
 /**
- * dp_catalog_hw_revision() - retrieve DP hw revision
+ * msm_dp_catalog_hw_revision() - retrieve DP hw revision
  *
- * @dp_catalog: DP catalog structure
+ * @msm_dp_catalog: DP catalog structure
  *
  * Return: DP controller hw revision
  *
  */
-u32 dp_catalog_hw_revision(const struct dp_catalog *dp_catalog)
+u32 msm_dp_catalog_hw_revision(const struct msm_dp_catalog *msm_dp_catalog)
 {
-	const struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	const struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	return dp_read_ahb(catalog, REG_DP_HW_VERSION);
+	return msm_dp_read_ahb(catalog, REG_DP_HW_VERSION);
 }
 
 /**
- * dp_catalog_ctrl_reset() - reset DP controller
+ * msm_dp_catalog_ctrl_reset() - reset DP controller
  *
- * @dp_catalog: DP catalog structure
+ * @msm_dp_catalog: DP catalog structure
  *
  * return: void
  *
@@ -551,31 +774,31 @@
  * NOTE: reset DP controller will also clear any pending HPD related interrupts
  * 
  */
-void dp_catalog_ctrl_reset(struct dp_catalog *dp_catalog)
+void msm_dp_catalog_ctrl_reset(struct msm_dp_catalog *msm_dp_catalog)
 {
 	u32 sw_reset;
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	sw_reset = dp_read_ahb(catalog, REG_DP_SW_RESET);
+	sw_reset = msm_dp_read_ahb(catalog, REG_DP_SW_RESET);
 
 	sw_reset |= DP_SW_RESET;
-	dp_write_ahb(catalog, REG_DP_SW_RESET, sw_reset);
+	msm_dp_write_ahb(catalog, REG_DP_SW_RESET, sw_reset);
 	usleep_range(1000, 1100); /* h/w recommended delay */
 
 	sw_reset &= ~DP_SW_RESET;
-	dp_write_ahb(catalog, REG_DP_SW_RESET, sw_reset);
+	msm_dp_write_ahb(catalog, REG_DP_SW_RESET, sw_reset);
 }
 
-bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog)
+bool msm_dp_catalog_ctrl_mainlink_ready(struct msm_dp_catalog *msm_dp_catalog)
 {
 	u32 data;
 	int ret;
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
 	/* Poll for mainlink ready status */
-	ret = readl_poll_timeout(catalog->io->dp_controller.link.base +
+	ret = readl_poll_timeout(catalog->io.link.base +
 				REG_DP_MAINLINK_READY,
 				data, data & DP_MAINLINK_READY_FOR_VIDEO,
 				POLLING_SLEEP_US, POLLING_TIMEOUT_US);
@@ -587,96 +810,99 @@
 	return true;
 }
 
-void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog,
+void msm_dp_catalog_ctrl_enable_irq(struct msm_dp_catalog *msm_dp_catalog,
 						bool enable)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
 	if (enable) {
-		dp_write_ahb(catalog, REG_DP_INTR_STATUS,
+		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS,
 				DP_INTERRUPT_STATUS1_MASK);
-		dp_write_ahb(catalog, REG_DP_INTR_STATUS2,
+		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS2,
 				DP_INTERRUPT_STATUS2_MASK);
+		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS5,
+				 DP_INTERRUPT_STATUS5_MASK);
 	} else {
-		dp_write_ahb(catalog, REG_DP_INTR_STATUS, 0x00);
-		dp_write_ahb(catalog, REG_DP_INTR_STATUS2, 0x00);
+		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS, 0x00);
+		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS2, 0x00);
+		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS5, 0x00);
 	}
 }
 
-void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog,
+void msm_dp_catalog_hpd_config_intr(struct msm_dp_catalog *msm_dp_catalog,
 			u32 intr_mask, bool en)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	u32 config = dp_read_aux(catalog, REG_DP_DP_HPD_INT_MASK);
+	u32 config = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_MASK);
 
 	config = (en ? config | intr_mask : config & ~intr_mask);
 
 	drm_dbg_dp(catalog->drm_dev, "intr_mask=%#x config=%#x\n",
 					intr_mask, config);
-	dp_write_aux(catalog, REG_DP_DP_HPD_INT_MASK,
+	msm_dp_write_aux(catalog, REG_DP_DP_HPD_INT_MASK,
 				config & DP_DP_HPD_INT_MASK);
 }
 
-void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog)
+void msm_dp_catalog_ctrl_hpd_enable(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER);
+	u32 reftimer = msm_dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER);
 
 	/* Configure REFTIMER and enable it */
 	reftimer |= DP_DP_HPD_REFTIMER_ENABLE;
-	dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
+	msm_dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
 
 	/* Enable HPD */
-	dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN);
+	msm_dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN);
 }
 
-void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog)
+void msm_dp_catalog_ctrl_hpd_disable(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER);
+	u32 reftimer = msm_dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER);
 
 	reftimer &= ~DP_DP_HPD_REFTIMER_ENABLE;
-	dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
+	msm_dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
 
-	dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, 0);
+	msm_dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, 0);
 }
 
-static void dp_catalog_enable_sdp(struct dp_catalog_private *catalog)
+static void msm_dp_catalog_enable_sdp(struct msm_dp_catalog_private *catalog)
 {
 	/* trigger sdp */
-	dp_write_link(catalog, MMSS_DP_SDP_CFG3, UPDATE_SDP);
-	dp_write_link(catalog, MMSS_DP_SDP_CFG3, 0x0);
+	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3, UPDATE_SDP);
+	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3, 0x0);
 }
 
-void dp_catalog_ctrl_config_psr(struct dp_catalog *dp_catalog)
+void msm_dp_catalog_ctrl_config_psr(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 config;
 
 	/* enable PSR1 function */
-	config = dp_read_link(catalog, REG_PSR_CONFIG);
+	config = msm_dp_read_link(catalog, REG_PSR_CONFIG);
 	config |= PSR1_SUPPORTED;
-	dp_write_link(catalog, REG_PSR_CONFIG, config);
+	msm_dp_write_link(catalog, REG_PSR_CONFIG, config);
 
-	dp_write_ahb(catalog, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
-	dp_catalog_enable_sdp(catalog);
+	msm_dp_write_ahb(catalog, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
+	msm_dp_catalog_enable_sdp(catalog);
 }
 
-void dp_catalog_ctrl_set_psr(struct dp_catalog *dp_catalog, bool enter)
+void msm_dp_catalog_ctrl_set_psr(struct msm_dp_catalog *msm_dp_catalog, bool enter)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-			struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+			struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 cmd;
 
-	cmd = dp_read_link(catalog, REG_PSR_CMD);
+	cmd = msm_dp_read_link(catalog, REG_PSR_CMD);
 
 	cmd &= ~(PSR_ENTER | PSR_EXIT);
 
@@ -685,17 +911,17 @@
 	else
 		cmd |= PSR_EXIT;
 
-	dp_catalog_enable_sdp(catalog);
-	dp_write_link(catalog, REG_PSR_CMD, cmd);
+	msm_dp_catalog_enable_sdp(catalog);
+	msm_dp_write_link(catalog, REG_PSR_CMD, cmd);
 }
 
-u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog)
+u32 msm_dp_catalog_link_is_connected(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 status;
 
-	status = dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS);
+	status = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS);
 	drm_dbg_dp(catalog->drm_dev, "aux status: %#x\n", status);
 	status >>= DP_DP_HPD_STATE_STATUS_BITS_SHIFT;
 	status &= DP_DP_HPD_STATE_STATUS_BITS_MASK;
@@ -703,16 +929,16 @@
 	return status;
 }
 
-u32 dp_catalog_hpd_get_intr_status(struct dp_catalog *dp_catalog)
+u32 msm_dp_catalog_hpd_get_intr_status(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 	int isr, mask;
 
-	isr = dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS);
-	dp_write_aux(catalog, REG_DP_DP_HPD_INT_ACK,
+	isr = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS);
+	msm_dp_write_aux(catalog, REG_DP_DP_HPD_INT_ACK,
 				 (isr & DP_DP_HPD_INT_MASK));
-	mask = dp_read_aux(catalog, REG_DP_DP_HPD_INT_MASK);
+	mask = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_MASK);
 
 	/*
 	 * We only want to return interrupts that are unmasked to the caller.
@@ -724,134 +950,132 @@
 	return isr & (mask | ~DP_DP_HPD_INT_MASK);
 }
 
-u32 dp_catalog_ctrl_read_psr_interrupt_status(struct dp_catalog *dp_catalog)
+u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 intr, intr_ack;
 
-	intr = dp_read_ahb(catalog, REG_DP_INTR_STATUS4);
+	intr = msm_dp_read_ahb(catalog, REG_DP_INTR_STATUS4);
 	intr_ack = (intr & DP_INTERRUPT_STATUS4)
 			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
-	dp_write_ahb(catalog, REG_DP_INTR_STATUS4, intr_ack);
+	msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS4, intr_ack);
 
 	return intr;
 }
 
-int dp_catalog_ctrl_get_interrupt(struct dp_catalog *dp_catalog)
+int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 intr, intr_ack;
 
-	intr = dp_read_ahb(catalog, REG_DP_INTR_STATUS2);
+	intr = msm_dp_read_ahb(catalog, REG_DP_INTR_STATUS2);
 	intr &= ~DP_INTERRUPT_STATUS2_MASK;
 	intr_ack = (intr & DP_INTERRUPT_STATUS2)
 			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
-	dp_write_ahb(catalog, REG_DP_INTR_STATUS2,
+	msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS2,
 			intr_ack | DP_INTERRUPT_STATUS2_MASK);
 
 	return intr;
 }
 
-void dp_catalog_ctrl_phy_reset(struct dp_catalog *dp_catalog)
+int msm_dp_catalog_ctrl_get_interrupt_5(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+							      struct msm_dp_catalog_private,
+							      msm_dp_catalog);
+	u32 intr, intr_ack;
 
-	dp_write_ahb(catalog, REG_DP_PHY_CTRL,
-			DP_PHY_CTRL_SW_RESET | DP_PHY_CTRL_SW_RESET_PLL);
-	usleep_range(1000, 1100); /* h/w recommended delay */
-	dp_write_ahb(catalog, REG_DP_PHY_CTRL, 0x0);
+	intr = msm_dp_read_ahb(catalog, REG_DP_INTR_STATUS5);
+	intr &= ~DP_INTERRUPT_STATUS5_MASK;
+	intr_ack = (intr & DP_INTERRUPT_STATUS5)
+			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
+	msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS5,
+			 intr_ack | DP_INTERRUPT_STATUS5_MASK);
+
+	return intr;
 }
 
-int dp_catalog_ctrl_update_vx_px(struct dp_catalog *dp_catalog,
-		u8 v_level, u8 p_level)
+void msm_dp_catalog_ctrl_phy_reset(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
-	struct dp_io *dp_io = catalog->io;
-	struct phy *phy = dp_io->phy;
-	struct phy_configure_opts_dp *opts_dp = &dp_io->phy_opts.dp;
-
-	/* TODO: Update for all lanes instead of just first one */
-	opts_dp->voltage[0] = v_level;
-	opts_dp->pre[0] = p_level;
-	opts_dp->set_voltages = 1;
-	phy_configure(phy, &dp_io->phy_opts);
-	opts_dp->set_voltages = 0;
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	return 0;
+	msm_dp_write_ahb(catalog, REG_DP_PHY_CTRL,
+			DP_PHY_CTRL_SW_RESET | DP_PHY_CTRL_SW_RESET_PLL);
+	usleep_range(1000, 1100); /* h/w recommended delay */
+	msm_dp_write_ahb(catalog, REG_DP_PHY_CTRL, 0x0);
 }
 
-void dp_catalog_ctrl_send_phy_pattern(struct dp_catalog *dp_catalog,
+void msm_dp_catalog_ctrl_send_phy_pattern(struct msm_dp_catalog *msm_dp_catalog,
 			u32 pattern)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 value = 0x0;
 
 	/* Make sure to clear the current pattern before starting a new one */
-	dp_write_link(catalog, REG_DP_STATE_CTRL, 0x0);
+	msm_dp_write_link(catalog, REG_DP_STATE_CTRL, 0x0);
 
 	drm_dbg_dp(catalog->drm_dev, "pattern: %#x\n", pattern);
 	switch (pattern) {
 	case DP_PHY_TEST_PATTERN_D10_2:
-		dp_write_link(catalog, REG_DP_STATE_CTRL,
+		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
 				DP_STATE_CTRL_LINK_TRAINING_PATTERN1);
 		break;
 	case DP_PHY_TEST_PATTERN_ERROR_COUNT:
 		value &= ~(1 << 16);
-		dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
 					value);
 		value |= SCRAMBLER_RESET_COUNT_VALUE;
-		dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
 					value);
-		dp_write_link(catalog, REG_DP_MAINLINK_LEVELS,
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_LEVELS,
 					DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2);
-		dp_write_link(catalog, REG_DP_STATE_CTRL,
+		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
 					DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE);
 		break;
 	case DP_PHY_TEST_PATTERN_PRBS7:
-		dp_write_link(catalog, REG_DP_STATE_CTRL,
+		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
 				DP_STATE_CTRL_LINK_PRBS7);
 		break;
 	case DP_PHY_TEST_PATTERN_80BIT_CUSTOM:
-		dp_write_link(catalog, REG_DP_STATE_CTRL,
+		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
 				DP_STATE_CTRL_LINK_TEST_CUSTOM_PATTERN);
 		/* 00111110000011111000001111100000 */
-		dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG0,
+		msm_dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG0,
 				0x3E0F83E0);
 		/* 00001111100000111110000011111000 */
-		dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG1,
+		msm_dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG1,
 				0x0F83E0F8);
 		/* 1111100000111110 */
-		dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG2,
+		msm_dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG2,
 				0x0000F83E);
 		break;
 	case DP_PHY_TEST_PATTERN_CP2520:
-		value = dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+		value = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
 		value &= ~DP_MAINLINK_CTRL_SW_BYPASS_SCRAMBLER;
-		dp_write_link(catalog, REG_DP_MAINLINK_CTRL, value);
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, value);
 
 		value = DP_HBR2_ERM_PATTERN;
-		dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
 				value);
 		value |= SCRAMBLER_RESET_COUNT_VALUE;
-		dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
 					value);
-		dp_write_link(catalog, REG_DP_MAINLINK_LEVELS,
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_LEVELS,
 					DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2);
-		dp_write_link(catalog, REG_DP_STATE_CTRL,
+		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
 					DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE);
-		value = dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+		value = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
 		value |= DP_MAINLINK_CTRL_ENABLE;
-		dp_write_link(catalog, REG_DP_MAINLINK_CTRL, value);
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, value);
 		break;
 	case DP_PHY_TEST_PATTERN_SEL_MASK:
-		dp_write_link(catalog, REG_DP_MAINLINK_CTRL,
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL,
 				DP_MAINLINK_CTRL_ENABLE);
-		dp_write_link(catalog, REG_DP_STATE_CTRL,
+		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
 				DP_STATE_CTRL_LINK_TRAINING_PATTERN4);
 		break;
 	default:
@@ -861,48 +1085,379 @@
 	}
 }
 
-u32 dp_catalog_ctrl_read_phy_pattern(struct dp_catalog *dp_catalog)
+u32 msm_dp_catalog_ctrl_read_phy_pattern(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	return dp_read_link(catalog, REG_DP_MAINLINK_READY);
+	return msm_dp_read_link(catalog, REG_DP_MAINLINK_READY);
 }
 
 /* panel related catalog functions */
-int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog)
+int msm_dp_catalog_panel_timing_cfg(struct msm_dp_catalog *msm_dp_catalog, u32 total,
+				u32 sync_start, u32 width_blanking, u32 msm_dp_active)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
-	u32 reg;
-
-	dp_write_link(catalog, REG_DP_TOTAL_HOR_VER,
-				dp_catalog->total);
-	dp_write_link(catalog, REG_DP_START_HOR_VER_FROM_SYNC,
-				dp_catalog->sync_start);
-	dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY,
-				dp_catalog->width_blanking);
-	dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER, dp_catalog->dp_active);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+	u32 reg = 0;
+	u32 offset = 0;
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_1)
+		offset = REG_DP1_TOTAL_HOR_VER - REG_DP_TOTAL_HOR_VER;
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_3) {
+		msm_dp_write_mst3_link(catalog, REG_DP_MST2_MST3_TOTAL_HOR_VER, total);
+		msm_dp_write_mst3_link(catalog, REG_DP_MST2_MST3_START_HOR_VER_FROM_SYNC,
+				       sync_start);
+		msm_dp_write_mst3_link(catalog, REG_DP_MST2_MST3_HSYNC_VSYNC_WIDTH_POLARITY,
+				       width_blanking);
+		msm_dp_write_mst3_link(catalog, REG_DP_MST2_MST3_ACTIVE_HOR_VER, msm_dp_active);
+	} else if (msm_dp_catalog->stream_id == DP_STREAM_2) {
+		msm_dp_write_mst2_link(catalog, REG_DP_MST2_MST3_TOTAL_HOR_VER, total);
+		msm_dp_write_mst2_link(catalog, REG_DP_MST2_MST3_START_HOR_VER_FROM_SYNC,
+				       sync_start);
+		msm_dp_write_mst2_link(catalog, REG_DP_MST2_MST3_HSYNC_VSYNC_WIDTH_POLARITY,
+				       width_blanking);
+		msm_dp_write_mst2_link(catalog, REG_DP_MST2_MST3_ACTIVE_HOR_VER, msm_dp_active);
+	} else {
+		msm_dp_write_link(catalog, REG_DP_TOTAL_HOR_VER + offset, total);
+		msm_dp_write_link(catalog, REG_DP_START_HOR_VER_FROM_SYNC + offset, sync_start);
+		msm_dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY + offset,
+				  width_blanking);
+		msm_dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER + offset, msm_dp_active);
+	}
 
-	reg = dp_read_p0(catalog, MMSS_DP_INTF_CONFIG);
+	if (msm_dp_catalog->stream_id == DP_STREAM_0)
+		reg = msm_dp_read_p0(catalog, MMSS_DP_INTF_CONFIG);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_1)
+		reg = msm_dp_read_p1(catalog, MMSS_DP_INTF_CONFIG);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_2)
+		reg = msm_dp_read_p2(catalog, MMSS_DP_INTF_CONFIG);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_3)
+		reg = msm_dp_read_p3(catalog, MMSS_DP_INTF_CONFIG);
 
-	if (dp_catalog->wide_bus_en)
+	if (msm_dp_catalog->wide_bus_en)
 		reg |= DP_INTF_CONFIG_DATABUS_WIDEN;
 	else
 		reg &= ~DP_INTF_CONFIG_DATABUS_WIDEN;
 
 
-	DRM_DEBUG_DP("wide_bus_en=%d reg=%#x\n", dp_catalog->wide_bus_en, reg);
+	DRM_DEBUG_DP("wide_bus_en=%d reg=%#x\n", msm_dp_catalog->wide_bus_en, reg);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_0)
+		msm_dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, reg);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_1)
+		msm_dp_write_p1(catalog, MMSS_DP_INTF_CONFIG, reg);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_2)
+		msm_dp_write_p2(catalog, MMSS_DP_INTF_CONFIG, reg);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_3)
+		msm_dp_write_p3(catalog, MMSS_DP_INTF_CONFIG, reg);
 
-	dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, reg);
 	return 0;
 }
 
-void dp_catalog_panel_tpg_enable(struct dp_catalog *dp_catalog,
+int msm_dp_catalog_mst_async_fifo(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+							      struct msm_dp_catalog_private,
+							      msm_dp_catalog);
+
+	u32 reg = 0;
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_0)
+		reg = msm_dp_read_p0(catalog, MMSS_DP_ASYNC_FIFO_CONFIG);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_1)
+		reg = msm_dp_read_p1(catalog, MMSS_DP_ASYNC_FIFO_CONFIG);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_2)
+		reg = msm_dp_read_p2(catalog, MMSS_DP_ASYNC_FIFO_CONFIG);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_3)
+		reg = msm_dp_read_p3(catalog, MMSS_DP_ASYNC_FIFO_CONFIG);
+
+	/* enable MST_FIFO_CONSTANT_FILL */
+	reg |= BIT(0);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_0)
+		msm_dp_write_p0(catalog, MMSS_DP_ASYNC_FIFO_CONFIG, reg);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_1)
+		msm_dp_write_p1(catalog, MMSS_DP_ASYNC_FIFO_CONFIG, reg);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_2)
+		msm_dp_write_p2(catalog, MMSS_DP_ASYNC_FIFO_CONFIG, reg);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_3)
+		msm_dp_write_p3(catalog, MMSS_DP_ASYNC_FIFO_CONFIG, reg);
+
+	return 0;
+}
+
+static void msm_dp_catalog_panel_send_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog, struct dp_sdp *vsc_sdp)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 header[2];
+	u32 val;
+	int i;
+	u32 msm_dp_generic_offset = 0;
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_1)
+		msm_dp_generic_offset = MMSS_DP1_GENERIC0_0 - MMSS_DP_GENERIC0_0;
+
+	msm_dp_utils_pack_sdp_header(&vsc_sdp->sdp_header, header);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_3) {
+		msm_dp_write_mst3_link(catalog, MMSS_DP_MST2_MST3_GENERIC0_0, header[0]);
+		msm_dp_write_mst3_link(catalog, MMSS_DP_MST2_MST3_GENERIC0_1, header[1]);
+	} else if (msm_dp_catalog->stream_id == DP_STREAM_2) {
+		msm_dp_write_mst2_link(catalog, MMSS_DP_MST2_MST3_GENERIC0_0, header[0]);
+		msm_dp_write_mst2_link(catalog, MMSS_DP_MST2_MST3_GENERIC0_1, header[1]);
+	} else {
+		msm_dp_write_link(catalog, MMSS_DP_GENERIC0_0 + msm_dp_generic_offset, header[0]);
+		msm_dp_write_link(catalog, MMSS_DP_GENERIC0_1 + msm_dp_generic_offset, header[1]);
+	}
+
+	for (i = 0; i < sizeof(vsc_sdp->db); i += 4) {
+		val = ((vsc_sdp->db[i]) | (vsc_sdp->db[i + 1] << 8) | (vsc_sdp->db[i + 2] << 16) |
+		       (vsc_sdp->db[i + 3] << 24));
+
+		if (msm_dp_catalog->stream_id == DP_STREAM_3)
+			msm_dp_write_mst3_link(catalog, MMSS_DP_MST2_MST3_GENERIC0_2 + i, val);
+		else if (msm_dp_catalog->stream_id == DP_STREAM_2)
+			msm_dp_write_mst2_link(catalog, MMSS_DP_MST2_MST3_GENERIC0_2 + i, val);
+		else
+			msm_dp_write_link(catalog, MMSS_DP_GENERIC0_2 + i + msm_dp_generic_offset,
+					  val);
+	}
+}
+
+static void msm_dp_catalog_panel_update_sdp(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 hw_revision;
+	u32 sdp_cfg3_offset = 0;
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_1)
+		sdp_cfg3_offset = MMSS_DP1_SDP_CFG3 - MMSS_DP_SDP_CFG3;
+
+	hw_revision = msm_dp_catalog_hw_revision(msm_dp_catalog);
+	if (hw_revision < DP_HW_VERSION_1_2 && hw_revision >= DP_HW_VERSION_1_0) {
+		if (msm_dp_catalog->stream_id == DP_STREAM_3) {
+			msm_dp_write_mst3_link(catalog, MMSS_DP_MST2_MST3_SDP_CFG3, 0x01);
+			msm_dp_write_mst3_link(catalog, MMSS_DP_MST2_MST3_SDP_CFG3, 0x00);
+		} else if (msm_dp_catalog->stream_id == DP_STREAM_2) {
+			msm_dp_write_mst2_link(catalog, MMSS_DP_MST2_MST3_SDP_CFG3, 0x01);
+			msm_dp_write_mst2_link(catalog, MMSS_DP_MST2_MST3_SDP_CFG3, 0x00);
+		} else {
+			msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3 + sdp_cfg3_offset, 0x01);
+			msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3 + sdp_cfg3_offset, 0x00);
+		}
+	}
+}
+
+void msm_dp_catalog_panel_enable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog, struct dp_sdp *vsc_sdp)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 cfg, cfg2, misc;
+	u32 misc_reg_offset = 0;
+	u32 sdp_cfg_offset = 0;
+	u32 sdp_cfg2_offset = 0;
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_1) {
+		misc_reg_offset = REG_DP1_MISC1_MISC0 - REG_DP_MISC1_MISC0;
+		sdp_cfg_offset = MMSS_DP1_SDP_CFG - MMSS_DP_SDP_CFG;
+		sdp_cfg2_offset = MMSS_DP1_SDP_CFG2 - MMSS_DP_SDP_CFG2;
+	}
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_3) {
+		cfg = msm_dp_read_link(catalog, MMSS_DP_MST2_MST3_SDP_CFG);
+		cfg2 = msm_dp_read_link(catalog, MMSS_DP_MST2_MST3_SDP_CFG2);
+		misc = msm_dp_read_link(catalog, REG_DP_MST2_MST3_MISC1_MISC0);
+	} else if (msm_dp_catalog->stream_id == DP_STREAM_2) {
+		cfg = msm_dp_read_link(catalog, MMSS_DP_MST2_MST3_SDP_CFG);
+		cfg2 = msm_dp_read_link(catalog, MMSS_DP_MST2_MST3_SDP_CFG2);
+		misc = msm_dp_read_link(catalog, REG_DP_MST2_MST3_MISC1_MISC0);
+	} else {
+		cfg = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG + sdp_cfg_offset);
+		cfg2 = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG2 + sdp_cfg2_offset);
+		misc = msm_dp_read_link(catalog, REG_DP_MISC1_MISC0 + misc_reg_offset);
+	}
+
+	cfg |= GEN0_SDP_EN;
+	if (msm_dp_catalog->stream_id == DP_STREAM_3)
+		msm_dp_write_mst3_link(catalog, MMSS_DP_MST2_MST3_SDP_CFG, cfg);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_2)
+		msm_dp_write_mst2_link(catalog, MMSS_DP_MST2_MST3_SDP_CFG, cfg);
+	else
+		msm_dp_write_link(catalog, MMSS_DP_SDP_CFG + sdp_cfg_offset, cfg);
+
+	cfg2 |= GENERIC0_SDPSIZE_VALID;
+	if (msm_dp_catalog->stream_id == DP_STREAM_3)
+		msm_dp_write_mst3_link(catalog, MMSS_DP_MST2_MST3_SDP_CFG2, cfg);
+	else if (msm_dp_catalog->stream_id == DP_STREAM_2)
+		msm_dp_write_mst2_link(catalog, MMSS_DP_MST2_MST3_SDP_CFG2, cfg);
+	else
+		msm_dp_write_link(catalog, MMSS_DP_SDP_CFG2 + sdp_cfg2_offset, cfg2);
+
+	msm_dp_catalog_panel_send_vsc_sdp(msm_dp_catalog, vsc_sdp);
+
+	/* indicates presence of VSC (BIT(6) of MISC1) */
+	misc |= DP_MISC1_VSC_SDP;
+
+	drm_dbg_dp(catalog->drm_dev, "vsc sdp enable=1\n");
+
+	pr_debug("misc settings = 0x%x\n", misc);
+
+	msm_dp_write_link(catalog, REG_DP_MISC1_MISC0 + misc_reg_offset, misc);
+
+	msm_dp_catalog_panel_update_sdp(msm_dp_catalog);
+}
+
+void msm_dp_catalog_panel_disable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 cfg, cfg2, misc;
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	cfg = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG);
+	cfg2 = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG2);
+	misc = msm_dp_read_link(catalog, REG_DP_MISC1_MISC0);
+
+	cfg &= ~GEN0_SDP_EN;
+	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG, cfg);
+
+	cfg2 &= ~GENERIC0_SDPSIZE_VALID;
+	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG2, cfg2);
+
+	/* switch back to MSA */
+	misc &= ~DP_MISC1_VSC_SDP;
+
+	drm_dbg_dp(catalog->drm_dev, "vsc sdp enable=0\n");
+
+	pr_debug("misc settings = 0x%x\n", misc);
+	msm_dp_write_link(catalog, REG_DP_MISC1_MISC0, misc);
+
+	msm_dp_catalog_panel_update_sdp(msm_dp_catalog);
+}
+
+void msm_dp_catalog_trigger_act(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog;
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	msm_dp_write_link(catalog, REG_DP_MST_ACT, 0x1);
+
+	/* make sure ACT signal is performed */
+	wmb();
+}
+
+bool msm_dp_catalog_read_act_complete_sts(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog;
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	return msm_dp_read_link(catalog, REG_DP_MST_ACT);
+}
+
+void msm_dp_catalog_mst_channel_alloc(struct msm_dp_catalog *msm_dp_catalog,
+				      u32 ch, u32 ch_start_slot, u32 tot_slot_cnt)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 i, slot_reg_1, slot_reg_2, slot;
+	u32 reg_off = 0;
+	int const num_slots_per_reg = 32;
+
+	if (!msm_dp_catalog || ch >= DP_STREAM_MAX) {
+		DRM_ERROR("invalid input. ch %d\n", ch);
+		return;
+	}
+
+	if (ch_start_slot > DP_MAX_TIME_SLOTS ||
+	    (ch_start_slot + tot_slot_cnt > DP_MAX_TIME_SLOTS)) {
+		DRM_ERROR("invalid slots start %d, tot %d\n",
+			  ch_start_slot, tot_slot_cnt);
+		return;
+	}
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	drm_dbg_dp(catalog->drm_dev, "ch %d, start_slot %d, tot_slot %d\n",
+		   ch, ch_start_slot, tot_slot_cnt);
+
+	if (ch == DP_STREAM_1)
+		reg_off = REG_DP_DP1_TIMESLOT_1_32 - REG_DP_DP0_TIMESLOT_1_32;
+
+	slot_reg_1 = 0;
+	slot_reg_2 = 0;
+
+	if (ch_start_slot && tot_slot_cnt) {
+		ch_start_slot--;
+		for (i = 0; i < tot_slot_cnt; i++) {
+			if (ch_start_slot < num_slots_per_reg) {
+				slot_reg_1 |= BIT(ch_start_slot);
+			} else {
+				slot = ch_start_slot - num_slots_per_reg;
+				slot_reg_2 |= BIT(slot);
+			}
+			ch_start_slot++;
+		}
+	}
+
+	drm_dbg_dp(catalog->drm_dev, "ch:%d slot_reg_1:0x%04X, slot_reg_2:0x%04X\n", ch,
+		   slot_reg_1, slot_reg_2);
+
+	if (ch == DP_STREAM_3) {
+		msm_dp_write_mst3_link(catalog, REG_DP_DP2_DP3_TIMESLOT_1_32, slot_reg_1);
+		msm_dp_write_mst3_link(catalog, REG_DP_DP2_DP3_TIMESLOT_33_63, slot_reg_2);
+	} else if (ch == DP_STREAM_2) {
+		msm_dp_write_mst2_link(catalog, REG_DP_DP2_DP3_TIMESLOT_1_32, slot_reg_1);
+		msm_dp_write_mst2_link(catalog, REG_DP_DP2_DP3_TIMESLOT_33_63, slot_reg_2);
+	} else {
+		msm_dp_write_link(catalog, REG_DP_DP0_TIMESLOT_1_32 + reg_off, slot_reg_1);
+		msm_dp_write_link(catalog, REG_DP_DP0_TIMESLOT_33_63 + reg_off, slot_reg_2);
+	}
+}
+
+void msm_dp_catalog_ctrl_update_rg(struct msm_dp_catalog *msm_dp_catalog, u32 stream,
+				   u32 x_int, u32 y_frac_enum)
+{
+	struct msm_dp_catalog_private *catalog;
+
+	u32 rg, reg_off = 0;
+
+	if (!msm_dp_catalog || stream >= DP_STREAM_MAX) {
+		DRM_ERROR("invalid input. stream %d\n", stream);
+		return;
+	}
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	rg = y_frac_enum;
+	rg |= (x_int << 16);
+
+	drm_dbg_dp(catalog->drm_dev, "stream: %d x_int:%d y_frac_enum:%d rg:%d\n",
+		   stream, x_int, y_frac_enum, rg);
+
+	if (stream == DP_STREAM_1)
+		reg_off = REG_DP_DP1_RG - REG_DP_DP0_RG;
+
+	if (stream == DP_STREAM_3)
+		msm_dp_write_mst3_link(catalog, REG_DP_MST2_MST3_DP_RG, rg);
+	else if (stream == DP_STREAM_2)
+		msm_dp_write_mst2_link(catalog, REG_DP_MST2_MST3_DP_RG, rg);
+	else
+		msm_dp_write_link(catalog, REG_DP_DP0_RG + reg_off, rg);
+}
+
+void msm_dp_catalog_panel_tpg_enable(struct msm_dp_catalog *msm_dp_catalog,
 				struct drm_display_mode *drm_mode)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 	u32 hsync_period, vsync_period;
 	u32 display_v_start, display_v_end;
 	u32 hsync_start_x, hsync_end_x;
@@ -934,144 +1489,216 @@
 	display_hctl = (hsync_end_x << 16) | hsync_start_x;
 
 
-	dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, 0x0);
-	dp_write_p0(catalog, MMSS_DP_INTF_HSYNC_CTL, hsync_ctl);
-	dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PERIOD_F0, vsync_period *
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, 0x0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_HSYNC_CTL, hsync_ctl);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PERIOD_F0, vsync_period *
 			hsync_period);
-	dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F0, v_sync_width *
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F0, v_sync_width *
 			hsync_period);
-	dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PERIOD_F1, 0);
-	dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F1, 0);
-	dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_HCTL, display_hctl);
-	dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_HCTL, 0);
-	dp_write_p0(catalog, MMSS_INTF_DISPLAY_V_START_F0, display_v_start);
-	dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_V_END_F0, display_v_end);
-	dp_write_p0(catalog, MMSS_INTF_DISPLAY_V_START_F1, 0);
-	dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_V_END_F1, 0);
-	dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_START_F0, 0);
-	dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_END_F0, 0);
-	dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_START_F1, 0);
-	dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_END_F1, 0);
-	dp_write_p0(catalog, MMSS_DP_INTF_POLARITY_CTL, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PERIOD_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_HCTL, display_hctl);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_HCTL, 0);
+	msm_dp_write_p0(catalog, MMSS_INTF_DISPLAY_V_START_F0, display_v_start);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_V_END_F0, display_v_end);
+	msm_dp_write_p0(catalog, MMSS_INTF_DISPLAY_V_START_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_V_END_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_START_F0, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_END_F0, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_START_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_END_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_POLARITY_CTL, 0);
 
-	dp_write_p0(catalog, MMSS_DP_TPG_MAIN_CONTROL,
+	msm_dp_write_p0(catalog, MMSS_DP_TPG_MAIN_CONTROL,
 				DP_TPG_CHECKERED_RECT_PATTERN);
-	dp_write_p0(catalog, MMSS_DP_TPG_VIDEO_CONFIG,
+	msm_dp_write_p0(catalog, MMSS_DP_TPG_VIDEO_CONFIG,
 				DP_TPG_VIDEO_CONFIG_BPP_8BIT |
 				DP_TPG_VIDEO_CONFIG_RGB);
-	dp_write_p0(catalog, MMSS_DP_BIST_ENABLE,
+	msm_dp_write_p0(catalog, MMSS_DP_BIST_ENABLE,
 				DP_BIST_ENABLE_DPBIST_EN);
-	dp_write_p0(catalog, MMSS_DP_TIMING_ENGINE_EN,
+	msm_dp_write_p0(catalog, MMSS_DP_TIMING_ENGINE_EN,
 				DP_TIMING_ENGINE_EN_EN);
 	drm_dbg_dp(catalog->drm_dev, "%s: enabled tpg\n", __func__);
 }
 
-void dp_catalog_panel_tpg_disable(struct dp_catalog *dp_catalog)
+void msm_dp_catalog_panel_tpg_disable(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog = container_of(dp_catalog,
-				struct dp_catalog_private, dp_catalog);
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
 
-	dp_write_p0(catalog, MMSS_DP_TPG_MAIN_CONTROL, 0x0);
-	dp_write_p0(catalog, MMSS_DP_BIST_ENABLE, 0x0);
-	dp_write_p0(catalog, MMSS_DP_TIMING_ENGINE_EN, 0x0);
+	msm_dp_write_p0(catalog, MMSS_DP_TPG_MAIN_CONTROL, 0x0);
+	msm_dp_write_p0(catalog, MMSS_DP_BIST_ENABLE, 0x0);
+	msm_dp_write_p0(catalog, MMSS_DP_TIMING_ENGINE_EN, 0x0);
 }
 
-struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io *io)
+static void __iomem *msm_dp_ioremap(struct platform_device *pdev, int idx, size_t *len)
 {
-	struct dp_catalog_private *catalog;
+	struct resource *res;
+	void __iomem *base;
+
+	base = devm_platform_get_and_ioremap_resource(pdev, idx, &res);
+	if (!IS_ERR(base))
+		*len = resource_size(res);
+
+	return base;
+}
+
+static int msm_dp_catalog_get_io(struct msm_dp_catalog_private *catalog)
+{
+	struct platform_device *pdev = to_platform_device(catalog->dev);
+	struct dss_io_data *dss = &catalog->io;
+
+	dss->ahb.base = msm_dp_ioremap(pdev, 0, &dss->ahb.len);
+	if (IS_ERR(dss->ahb.base))
+		return PTR_ERR(dss->ahb.base);
+
+	dss->aux.base = msm_dp_ioremap(pdev, 1, &dss->aux.len);
+	if (IS_ERR(dss->aux.base)) {
+		/*
+		 * The initial binding had a single reg, but in order to
+		 * support variation in the sub-region sizes this was split.
+		 * msm_dp_ioremap() will fail with -EINVAL here if only a single
+		 * reg is specified, so fill in the sub-region offsets and
+		 * lengths based on this single region.
+		 */
+		if (PTR_ERR(dss->aux.base) == -EINVAL) {
+			if (dss->ahb.len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) {
+				DRM_ERROR("legacy memory region not large enough\n");
+				return -EINVAL;
+			}
+
+			dss->ahb.len = DP_DEFAULT_AHB_SIZE;
+			dss->aux.base = dss->ahb.base + DP_DEFAULT_AUX_OFFSET;
+			dss->aux.len = DP_DEFAULT_AUX_SIZE;
+			dss->link.base = dss->ahb.base + DP_DEFAULT_LINK_OFFSET;
+			dss->link.len = DP_DEFAULT_LINK_SIZE;
+			dss->p0.base = dss->ahb.base + DP_DEFAULT_P0_OFFSET;
+			dss->p0.len = DP_DEFAULT_P0_SIZE;
+		} else {
+			DRM_ERROR("unable to remap aux region: %pe\n", dss->aux.base);
+			return PTR_ERR(dss->aux.base);
+		}
+	} else {
+		dss->link.base = msm_dp_ioremap(pdev, 2, &dss->link.len);
+		if (IS_ERR(dss->link.base)) {
+			DRM_ERROR("unable to remap link region: %pe\n", dss->link.base);
+			return PTR_ERR(dss->link.base);
+		}
+
+		dss->p0.base = msm_dp_ioremap(pdev, 3, &dss->p0.len);
+		if (IS_ERR(dss->p0.base)) {
+			DRM_ERROR("unable to remap p0 region: %pe\n", dss->p0.base);
+			return PTR_ERR(dss->p0.base);
+		}
+
+		dss->p1.base = msm_dp_ioremap(pdev, 4, &dss->p1.len);
+		if (IS_ERR(dss->p1.base))
+			DRM_DEBUG("unable to remap p1 region: %pe\n", dss->p1.base);
+
+		dss->p2.base = msm_dp_ioremap(pdev, 5, &dss->p2.len);
+		if (IS_ERR(dss->p2.base))
+			DRM_DEBUG("unable to remap p2 region: %pe\n", dss->p2.base);
+
+		dss->p3.base = msm_dp_ioremap(pdev, 6, &dss->p3.len);
+		if (IS_ERR(dss->p3.base))
+			DRM_DEBUG("unable to remap p3 region: %pe\n", dss->p3.base);
+
+		dss->mst2_link.base = msm_dp_ioremap(pdev, 7, &dss->mst2_link.len);
+		if (IS_ERR(dss->mst2_link.base))
+			DRM_DEBUG("unable to remap mst2_link region: %pe\n", dss->mst2_link.base);
+
+		dss->mst3_link.base = msm_dp_ioremap(pdev, 8, &dss->mst3_link.len);
+		if (IS_ERR(dss->mst3_link.base))
+			DRM_DEBUG("unable to remap mst3_link region: %pe\n", dss->mst3_link.base);
 
-	if (!io) {
-		DRM_ERROR("invalid input\n");
-		return ERR_PTR(-EINVAL);
 	}
 
+	return 0;
+}
+
+struct msm_dp_catalog *msm_dp_catalog_get(struct device *dev)
+{
+	struct msm_dp_catalog_private *catalog;
+	int ret;
+
 	catalog  = devm_kzalloc(dev, sizeof(*catalog), GFP_KERNEL);
 	if (!catalog)
 		return ERR_PTR(-ENOMEM);
 
 	catalog->dev = dev;
-	catalog->io = io;
 
-	return &catalog->dp_catalog;
+	ret = msm_dp_catalog_get_io(catalog);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &catalog->msm_dp_catalog;
 }
 
-void dp_catalog_audio_get_header(struct dp_catalog *dp_catalog)
+u32 msm_dp_catalog_audio_get_header(struct msm_dp_catalog *msm_dp_catalog,
+				enum msm_dp_catalog_audio_sdp_type sdp,
+				enum msm_dp_catalog_audio_header_type header)
 {
-	struct dp_catalog_private *catalog;
+	struct msm_dp_catalog_private *catalog;
 	u32 (*sdp_map)[DP_AUDIO_SDP_HEADER_MAX];
-	enum dp_catalog_audio_sdp_type sdp;
-	enum dp_catalog_audio_header_type header;
 
-	if (!dp_catalog)
-		return;
-
-	catalog = container_of(dp_catalog,
-		struct dp_catalog_private, dp_catalog);
+	catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
 
 	sdp_map = catalog->audio_map;
-	sdp     = dp_catalog->sdp_type;
-	header  = dp_catalog->sdp_header;
 
-	dp_catalog->audio_data = dp_read_link(catalog,
-			sdp_map[sdp][header]);
+	return msm_dp_read_link(catalog, sdp_map[sdp][header]);
 }
 
-void dp_catalog_audio_set_header(struct dp_catalog *dp_catalog)
+void msm_dp_catalog_audio_set_header(struct msm_dp_catalog *msm_dp_catalog,
+				 enum msm_dp_catalog_audio_sdp_type sdp,
+				 enum msm_dp_catalog_audio_header_type header,
+				 u32 data)
 {
-	struct dp_catalog_private *catalog;
+	struct msm_dp_catalog_private *catalog;
 	u32 (*sdp_map)[DP_AUDIO_SDP_HEADER_MAX];
-	enum dp_catalog_audio_sdp_type sdp;
-	enum dp_catalog_audio_header_type header;
-	u32 data;
 
-	if (!dp_catalog)
+	if (!msm_dp_catalog)
 		return;
 
-	catalog = container_of(dp_catalog,
-		struct dp_catalog_private, dp_catalog);
+	catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
 
 	sdp_map = catalog->audio_map;
-	sdp     = dp_catalog->sdp_type;
-	header  = dp_catalog->sdp_header;
-	data    = dp_catalog->audio_data;
 
-	dp_write_link(catalog, sdp_map[sdp][header], data);
+	msm_dp_write_link(catalog, sdp_map[sdp][header], data);
 }
 
-void dp_catalog_audio_config_acr(struct dp_catalog *dp_catalog)
+void msm_dp_catalog_audio_config_acr(struct msm_dp_catalog *msm_dp_catalog, u32 select)
 {
-	struct dp_catalog_private *catalog;
-	u32 acr_ctrl, select;
+	struct msm_dp_catalog_private *catalog;
+	u32 acr_ctrl;
 
-	if (!dp_catalog)
+	if (!msm_dp_catalog)
 		return;
 
-	catalog = container_of(dp_catalog,
-		struct dp_catalog_private, dp_catalog);
+	catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
 
-	select = dp_catalog->audio_data;
 	acr_ctrl = select << 4 | BIT(31) | BIT(8) | BIT(14);
 
 	drm_dbg_dp(catalog->drm_dev, "select: %#x, acr_ctrl: %#x\n",
 					select, acr_ctrl);
 
-	dp_write_link(catalog, MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl);
+	msm_dp_write_link(catalog, MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl);
 }
 
-void dp_catalog_audio_enable(struct dp_catalog *dp_catalog)
+void msm_dp_catalog_audio_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable)
 {
-	struct dp_catalog_private *catalog;
-	bool enable;
+	struct msm_dp_catalog_private *catalog;
 	u32 audio_ctrl;
 
-	if (!dp_catalog)
+	if (!msm_dp_catalog)
 		return;
 
-	catalog = container_of(dp_catalog,
-		struct dp_catalog_private, dp_catalog);
+	catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
 
-	enable = !!dp_catalog->audio_data;
-	audio_ctrl = dp_read_link(catalog, MMSS_DP_AUDIO_CFG);
+	audio_ctrl = msm_dp_read_link(catalog, MMSS_DP_AUDIO_CFG);
 
 	if (enable)
 		audio_ctrl |= BIT(0);
@@ -1080,24 +1707,24 @@
 
 	drm_dbg_dp(catalog->drm_dev, "dp_audio_cfg = 0x%x\n", audio_ctrl);
 
-	dp_write_link(catalog, MMSS_DP_AUDIO_CFG, audio_ctrl);
+	msm_dp_write_link(catalog, MMSS_DP_AUDIO_CFG, audio_ctrl);
 	/* make sure audio engine is disabled */
 	wmb();
 }
 
-void dp_catalog_audio_config_sdp(struct dp_catalog *dp_catalog)
+void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog;
+	struct msm_dp_catalog_private *catalog;
 	u32 sdp_cfg = 0;
 	u32 sdp_cfg2 = 0;
 
-	if (!dp_catalog)
+	if (!msm_dp_catalog)
 		return;
 
-	catalog = container_of(dp_catalog,
-		struct dp_catalog_private, dp_catalog);
+	catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
 
-	sdp_cfg = dp_read_link(catalog, MMSS_DP_SDP_CFG);
+	sdp_cfg = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG);
 	/* AUDIO_TIMESTAMP_SDP_EN */
 	sdp_cfg |= BIT(1);
 	/* AUDIO_STREAM_SDP_EN */
@@ -1111,9 +1738,9 @@
 
 	drm_dbg_dp(catalog->drm_dev, "sdp_cfg = 0x%x\n", sdp_cfg);
 
-	dp_write_link(catalog, MMSS_DP_SDP_CFG, sdp_cfg);
+	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG, sdp_cfg);
 
-	sdp_cfg2 = dp_read_link(catalog, MMSS_DP_SDP_CFG2);
+	sdp_cfg2 = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG2);
 	/* IFRM_REGSRC -> Do not use reg values */
 	sdp_cfg2 &= ~BIT(0);
 	/* AUDIO_STREAM_HB3_REGSRC-> Do not use reg values */
@@ -1121,12 +1748,12 @@
 
 	drm_dbg_dp(catalog->drm_dev, "sdp_cfg2 = 0x%x\n", sdp_cfg2);
 
-	dp_write_link(catalog, MMSS_DP_SDP_CFG2, sdp_cfg2);
+	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG2, sdp_cfg2);
 }
 
-void dp_catalog_audio_init(struct dp_catalog *dp_catalog)
+void msm_dp_catalog_audio_init(struct msm_dp_catalog *msm_dp_catalog)
 {
-	struct dp_catalog_private *catalog;
+	struct msm_dp_catalog_private *catalog;
 
 	static u32 sdp_map[][DP_AUDIO_SDP_HEADER_MAX] = {
 		{
@@ -1156,28 +1783,27 @@
 		},
 	};
 
-	if (!dp_catalog)
+	if (!msm_dp_catalog)
 		return;
 
-	catalog = container_of(dp_catalog,
-		struct dp_catalog_private, dp_catalog);
+	catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
 
 	catalog->audio_map = sdp_map;
 }
 
-void dp_catalog_audio_sfe_level(struct dp_catalog *dp_catalog)
+void msm_dp_catalog_audio_sfe_level(struct msm_dp_catalog *msm_dp_catalog, u32 safe_to_exit_level)
 {
-	struct dp_catalog_private *catalog;
-	u32 mainlink_levels, safe_to_exit_level;
+	struct msm_dp_catalog_private *catalog;
+	u32 mainlink_levels;
 
-	if (!dp_catalog)
+	if (!msm_dp_catalog)
 		return;
 
-	catalog = container_of(dp_catalog,
-		struct dp_catalog_private, dp_catalog);
+	catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
 
-	safe_to_exit_level = dp_catalog->audio_data;
-	mainlink_levels = dp_read_link(catalog, REG_DP_MAINLINK_LEVELS);
+	mainlink_levels = msm_dp_read_link(catalog, REG_DP_MAINLINK_LEVELS);
 	mainlink_levels &= 0xFE0;
 	mainlink_levels |= safe_to_exit_level;
 
@@ -1185,5 +1811,5 @@
 			"mainlink_level = 0x%x, safe_to_exit_level = 0x%x\n",
 			 mainlink_levels, safe_to_exit_level);
 
-	dp_write_link(catalog, REG_DP_MAINLINK_LEVELS, mainlink_levels);
+	msm_dp_write_link(catalog, REG_DP_MAINLINK_LEVELS, mainlink_levels);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_catalog.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_catalog.h
@@ -8,7 +8,7 @@
 
 #include <drm/drm_modes.h>
 
-#include "dp_parser.h"
+#include "dp_utils.h"
 #include "disp/msm_disp_snapshot.h"
 
 /* interrupts */
@@ -28,24 +28,15 @@
 #define DP_INTR_FRAME_END		BIT(6)
 #define DP_INTR_CRC_UPDATED		BIT(9)
 
-#define DP_AUX_CFG_MAX_VALUE_CNT 3
+#define DP_INTR_DP0_VCPF_SENT		BIT(0)
+#define DP_INTR_DP1_VCPF_SENT		BIT(3)
 
-/* PHY AUX config registers */
-enum dp_phy_aux_config_type {
-	PHY_AUX_CFG0,
-	PHY_AUX_CFG1,
-	PHY_AUX_CFG2,
-	PHY_AUX_CFG3,
-	PHY_AUX_CFG4,
-	PHY_AUX_CFG5,
-	PHY_AUX_CFG6,
-	PHY_AUX_CFG7,
-	PHY_AUX_CFG8,
-	PHY_AUX_CFG9,
-	PHY_AUX_CFG_MAX,
-};
+#define DP_HW_VERSION_1_0	0x10000000
+#define DP_HW_VERSION_1_2	0x10020000
+
+#define DP_MAX_TIME_SLOTS 64
 
-enum dp_catalog_audio_sdp_type {
+enum msm_dp_catalog_audio_sdp_type {
 	DP_AUDIO_SDP_STREAM,
 	DP_AUDIO_SDP_TIMESTAMP,
 	DP_AUDIO_SDP_INFOFRAME,
@@ -54,90 +45,112 @@
 	DP_AUDIO_SDP_MAX,
 };
 
-enum dp_catalog_audio_header_type {
+enum msm_dp_catalog_audio_header_type {
 	DP_AUDIO_SDP_HEADER_1,
 	DP_AUDIO_SDP_HEADER_2,
 	DP_AUDIO_SDP_HEADER_3,
 	DP_AUDIO_SDP_HEADER_MAX,
 };
 
-struct dp_catalog {
-	u32 aux_data;
-	u32 total;
-	u32 sync_start;
-	u32 width_blanking;
-	u32 dp_active;
-	enum dp_catalog_audio_sdp_type sdp_type;
-	enum dp_catalog_audio_header_type sdp_header;
-	u32 audio_data;
+/* stream id */
+enum msm_dp_stream_id {
+	DP_STREAM_0,
+	DP_STREAM_1,
+	DP_STREAM_2,
+	DP_STREAM_3,
+	DP_STREAM_MAX,
+};
+
+struct msm_dp_catalog {
 	bool wide_bus_en;
+	enum msm_dp_stream_id stream_id;
 };
 
 /* Debug module */
-void dp_catalog_snapshot(struct dp_catalog *dp_catalog, struct msm_disp_state *disp_state);
+void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_disp_state *disp_state);
 
 /* AUX APIs */
-u32 dp_catalog_aux_read_data(struct dp_catalog *dp_catalog);
-int dp_catalog_aux_write_data(struct dp_catalog *dp_catalog);
-int dp_catalog_aux_write_trans(struct dp_catalog *dp_catalog);
-int dp_catalog_aux_clear_trans(struct dp_catalog *dp_catalog, bool read);
-int dp_catalog_aux_clear_hw_interrupts(struct dp_catalog *dp_catalog);
-void dp_catalog_aux_reset(struct dp_catalog *dp_catalog);
-void dp_catalog_aux_enable(struct dp_catalog *dp_catalog, bool enable);
-void dp_catalog_aux_update_cfg(struct dp_catalog *dp_catalog);
-int dp_catalog_aux_wait_for_hpd_connect_state(struct dp_catalog *dp_catalog);
-u32 dp_catalog_aux_get_irq(struct dp_catalog *dp_catalog);
+u32 msm_dp_catalog_aux_read_data(struct msm_dp_catalog *msm_dp_catalog);
+int msm_dp_catalog_aux_write_data(struct msm_dp_catalog *msm_dp_catalog, u32 data);
+int msm_dp_catalog_aux_write_trans(struct msm_dp_catalog *msm_dp_catalog, u32 data);
+int msm_dp_catalog_aux_clear_trans(struct msm_dp_catalog *msm_dp_catalog, bool read);
+int msm_dp_catalog_aux_clear_hw_interrupts(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_aux_reset(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_aux_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable);
+int msm_dp_catalog_aux_wait_for_hpd_connect_state(struct msm_dp_catalog *msm_dp_catalog,
+					      unsigned long wait_us);
+u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog);
 
 /* DP Controller APIs */
-void dp_catalog_ctrl_state_ctrl(struct dp_catalog *dp_catalog, u32 state);
-void dp_catalog_ctrl_config_ctrl(struct dp_catalog *dp_catalog, u32 config);
-void dp_catalog_ctrl_lane_mapping(struct dp_catalog *dp_catalog);
-void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog *dp_catalog, bool enable);
-void dp_catalog_ctrl_psr_mainlink_enable(struct dp_catalog *dp_catalog, bool enable);
-void dp_catalog_ctrl_config_misc(struct dp_catalog *dp_catalog, u32 cc, u32 tb);
-void dp_catalog_ctrl_config_msa(struct dp_catalog *dp_catalog, u32 rate,
-				u32 stream_rate_khz, bool fixed_nvid);
-int dp_catalog_ctrl_set_pattern_state_bit(struct dp_catalog *dp_catalog, u32 pattern);
-u32 dp_catalog_hw_revision(const struct dp_catalog *dp_catalog);
-void dp_catalog_ctrl_reset(struct dp_catalog *dp_catalog);
-bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog);
-void dp_catalog_ctrl_enable_irq(struct dp_catalog *dp_catalog, bool enable);
-void dp_catalog_hpd_config_intr(struct dp_catalog *dp_catalog,
+void msm_dp_catalog_ctrl_state_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 state);
+void msm_dp_catalog_ctrl_mst2_state_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 state);
+void msm_dp_catalog_ctrl_mst3_state_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 state);
+void msm_dp_catalog_ctrl_config_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 config);
+void msm_dp_catalog_ctrl_lane_mapping(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_mainlink_ctrl(struct msm_dp_catalog *msm_dp_catalog, bool enable);
+void msm_dp_catalog_ctrl_psr_mainlink_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable);
+void msm_dp_catalog_setup_peripheral_flush(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_config_misc(struct msm_dp_catalog *msm_dp_catalog, u32 cc, u32 tb);
+void msm_dp_catalog_ctrl_config_msa(struct msm_dp_catalog *msm_dp_catalog, u32 rate,
+				u32 stream_rate_khz, bool is_ycbcr_420);
+int msm_dp_catalog_ctrl_set_pattern_state_bit(struct msm_dp_catalog *msm_dp_catalog, u32 pattern);
+u32 msm_dp_catalog_hw_revision(const struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_reset(struct msm_dp_catalog *msm_dp_catalog);
+bool msm_dp_catalog_ctrl_mainlink_ready(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_enable_irq(struct msm_dp_catalog *msm_dp_catalog, bool enable);
+void msm_dp_catalog_hpd_config_intr(struct msm_dp_catalog *msm_dp_catalog,
 			u32 intr_mask, bool en);
-void dp_catalog_ctrl_hpd_enable(struct dp_catalog *dp_catalog);
-void dp_catalog_ctrl_hpd_disable(struct dp_catalog *dp_catalog);
-void dp_catalog_ctrl_config_psr(struct dp_catalog *dp_catalog);
-void dp_catalog_ctrl_set_psr(struct dp_catalog *dp_catalog, bool enter);
-u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog);
-u32 dp_catalog_hpd_get_intr_status(struct dp_catalog *dp_catalog);
-void dp_catalog_ctrl_phy_reset(struct dp_catalog *dp_catalog);
-int dp_catalog_ctrl_update_vx_px(struct dp_catalog *dp_catalog, u8 v_level,
-				u8 p_level);
-int dp_catalog_ctrl_get_interrupt(struct dp_catalog *dp_catalog);
-u32 dp_catalog_ctrl_read_psr_interrupt_status(struct dp_catalog *dp_catalog);
-void dp_catalog_ctrl_update_transfer_unit(struct dp_catalog *dp_catalog,
-				u32 dp_tu, u32 valid_boundary,
+void msm_dp_catalog_ctrl_hpd_enable(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_hpd_disable(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_config_psr(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_set_psr(struct msm_dp_catalog *msm_dp_catalog, bool enter);
+u32 msm_dp_catalog_link_is_connected(struct msm_dp_catalog *msm_dp_catalog);
+u32 msm_dp_catalog_hpd_get_intr_status(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_phy_reset(struct msm_dp_catalog *msm_dp_catalog);
+int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog);
+int msm_dp_catalog_ctrl_get_interrupt_5(struct msm_dp_catalog *msm_dp_catalog);
+u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_update_transfer_unit(struct msm_dp_catalog *msm_dp_catalog,
+				u32 msm_dp_tu, u32 valid_boundary,
 				u32 valid_boundary2);
-void dp_catalog_ctrl_send_phy_pattern(struct dp_catalog *dp_catalog,
+void msm_dp_catalog_ctrl_send_phy_pattern(struct msm_dp_catalog *msm_dp_catalog,
 				u32 pattern);
-u32 dp_catalog_ctrl_read_phy_pattern(struct dp_catalog *dp_catalog);
+u32 msm_dp_catalog_ctrl_read_phy_pattern(struct msm_dp_catalog *msm_dp_catalog);
 
 /* DP Panel APIs */
-int dp_catalog_panel_timing_cfg(struct dp_catalog *dp_catalog);
-void dp_catalog_dump_regs(struct dp_catalog *dp_catalog);
-void dp_catalog_panel_tpg_enable(struct dp_catalog *dp_catalog,
+int msm_dp_catalog_panel_timing_cfg(struct msm_dp_catalog *msm_dp_catalog, u32 total,
+				u32 sync_start, u32 width_blanking, u32 msm_dp_active);
+void msm_dp_catalog_panel_enable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog, struct dp_sdp *vsc_sdp);
+void msm_dp_catalog_panel_disable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_dump_regs(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_panel_tpg_enable(struct msm_dp_catalog *msm_dp_catalog,
 				struct drm_display_mode *drm_mode);
-void dp_catalog_panel_tpg_disable(struct dp_catalog *dp_catalog);
+void msm_dp_catalog_panel_tpg_disable(struct msm_dp_catalog *msm_dp_catalog);
 
-struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io *io);
+struct msm_dp_catalog *msm_dp_catalog_get(struct device *dev);
 
 /* DP Audio APIs */
-void dp_catalog_audio_get_header(struct dp_catalog *catalog);
-void dp_catalog_audio_set_header(struct dp_catalog *catalog);
-void dp_catalog_audio_config_acr(struct dp_catalog *catalog);
-void dp_catalog_audio_enable(struct dp_catalog *catalog);
-void dp_catalog_audio_config_sdp(struct dp_catalog *catalog);
-void dp_catalog_audio_init(struct dp_catalog *catalog);
-void dp_catalog_audio_sfe_level(struct dp_catalog *catalog);
+u32 msm_dp_catalog_audio_get_header(struct msm_dp_catalog *msm_dp_catalog,
+				enum msm_dp_catalog_audio_sdp_type sdp,
+				enum msm_dp_catalog_audio_header_type header);
+void msm_dp_catalog_audio_set_header(struct msm_dp_catalog *msm_dp_catalog,
+				 enum msm_dp_catalog_audio_sdp_type sdp,
+				 enum msm_dp_catalog_audio_header_type header,
+				 u32 data);
+void msm_dp_catalog_audio_config_acr(struct msm_dp_catalog *catalog, u32 select);
+void msm_dp_catalog_audio_enable(struct msm_dp_catalog *catalog, bool enable);
+void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *catalog);
+void msm_dp_catalog_audio_init(struct msm_dp_catalog *catalog);
+void msm_dp_catalog_audio_sfe_level(struct msm_dp_catalog *catalog, u32 safe_to_exit_level);
+
+/* DP MST APIs */
+void msm_dp_catalog_trigger_act(struct msm_dp_catalog *msm_dp_catalog);
+bool msm_dp_catalog_read_act_complete_sts(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_mst_config(struct msm_dp_catalog *msm_dp_catalog, bool enable);
+void msm_dp_catalog_mst_channel_alloc(struct msm_dp_catalog *msm_dp_catalog,
+				      u32 ch, u32 ch_start_slot, u32 tot_slot_cnt);
+void msm_dp_catalog_ctrl_update_rg(struct msm_dp_catalog *msm_dp_catalog, u32 stream,
+				   u32 x_int, u32 y_frac_enum);
+int msm_dp_catalog_mst_async_fifo(struct msm_dp_catalog *msm_dp_catalog);
 
 #endif /* _DP_CATALOG_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_ctrl.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_ctrl.c
@@ -27,6 +27,12 @@
 
 #define DP_CTRL_INTR_READY_FOR_VIDEO     BIT(0)
 #define DP_CTRL_INTR_IDLE_PATTERN_SENT  BIT(3)
+#define DP_CTRL_INTR_DP0_VCPF_SENT       BIT(0)
+#define DP_CTRL_INTR_DP1_VCPF_SENT       BIT(3)
+
+#define MST_DP0_PUSH_VCPF		BIT(12)
+#define MST_DP1_PUSH_VCPF		BIT(14)
+#define MST_MST2_MST3_PUSH_VCPF		BIT(12)
 
 #define MR_LINK_TRAINING1  0x8
 #define MR_LINK_SYMBOL_ERM 0x80
@@ -40,7 +46,7 @@
 	DP_TRAINING_2,
 };
 
-struct dp_tu_calc_input {
+struct msm_dp_tu_calc_input {
 	u64 lclk;        /* 162, 270, 540 and 810 */
 	u64 pclk_khz;    /* in KHz */
 	u64 hactive;     /* active h-width */
@@ -55,7 +61,7 @@
 	int num_of_dsc_slices; /* number of slices per line */
 };
 
-struct dp_vc_tu_mapping_table {
+struct msm_dp_vc_tu_mapping_table {
 	u32 vic;
 	u8 lanes;
 	u8 lrate; /* DP_LINK_RATE -> 162(6), 270(10), 540(20), 810 (30) */
@@ -69,24 +75,46 @@
 	u8 tu_size_minus1;
 };
 
-struct dp_ctrl_private {
-	struct dp_ctrl dp_ctrl;
+struct msm_dp_mst_ch_slot_info {
+	u32 start_slot;
+	u32 tot_slots;
+};
+
+struct msm_dp_ctrl_private {
+	struct msm_dp_ctrl msm_dp_ctrl;
 	struct drm_device *drm_dev;
 	struct device *dev;
 	struct drm_dp_aux *aux;
-	struct dp_panel *panel;
-	struct dp_link *link;
-	struct dp_power *power;
-	struct dp_parser *parser;
-	struct dp_catalog *catalog;
+	struct msm_dp_panel *panel;
+	struct msm_dp_link *link;
+	struct msm_dp_catalog *catalog;
+
+	struct phy *phy;
+
+	unsigned int num_core_clks;
+	struct clk_bulk_data *core_clks;
+
+	unsigned int num_link_clks;
+	struct clk_bulk_data *link_clks;
+
+	struct clk *pixel_clk[DP_STREAM_MAX];
+
+	union phy_configure_opts phy_opts;
 
 	struct completion idle_comp;
 	struct completion psr_op_comp;
 	struct completion video_comp;
+
+	bool core_clks_on;
+	bool link_clks_on;
+	bool mst_active;
+	bool stream_clks_on[DP_STREAM_MAX];
+
+	struct msm_dp_mst_ch_slot_info mst_ch_info[DP_STREAM_MAX];
 };
 
-static int dp_aux_link_configure(struct drm_dp_aux *aux,
-					struct dp_link_info *link)
+static int msm_dp_aux_link_configure(struct drm_dp_aux *aux,
+					struct msm_dp_link_info *link)
 {
 	u8 values[2];
 	int err;
@@ -104,14 +132,14 @@
 	return 0;
 }
 
-void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl)
+void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl)
 {
-	struct dp_ctrl_private *ctrl;
+	struct msm_dp_ctrl_private *ctrl;
 
-	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 
 	reinit_completion(&ctrl->idle_comp);
-	dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_PUSH_IDLE);
+	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_PUSH_IDLE);
 
 	if (!wait_for_completion_timeout(&ctrl->idle_comp,
 			IDLE_PATTERN_COMPLETION_TIMEOUT_JIFFIES))
@@ -120,56 +148,105 @@
 	drm_dbg_dp(ctrl->drm_dev, "mainlink off\n");
 }
 
-static void dp_ctrl_config_ctrl(struct dp_ctrl_private *ctrl)
+void msm_dp_ctrl_push_vcpf(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *msm_dp_panel)
+{
+	u32 state = 0x0;
+	struct msm_dp_ctrl_private *ctrl;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	if (msm_dp_panel->stream_id >= DP_STREAM_MAX) {
+		DRM_ERROR("invalid input\n");
+		return;
+	}
+
+	if (msm_dp_panel->stream_id == DP_STREAM_0)
+		state |= MST_DP0_PUSH_VCPF;
+	else if (msm_dp_panel->stream_id == DP_STREAM_1)
+		state |= MST_DP1_PUSH_VCPF;
+	else
+		state |= MST_MST2_MST3_PUSH_VCPF;
+
+	reinit_completion(&ctrl->idle_comp);
+
+	if (msm_dp_panel->stream_id == DP_STREAM_3)
+		msm_dp_catalog_ctrl_mst3_state_ctrl(ctrl->catalog, state);
+	else if (msm_dp_panel->stream_id == DP_STREAM_2)
+		msm_dp_catalog_ctrl_mst2_state_ctrl(ctrl->catalog, state);
+	else
+		msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, state);
+
+	if (!wait_for_completion_timeout(&ctrl->idle_comp,
+					 IDLE_PATTERN_COMPLETION_TIMEOUT_JIFFIES))
+		pr_warn("PUSH_VCPF pattern timedout\n");
+
+	drm_dbg_dp(ctrl->drm_dev, "mainlink off\n");
+}
+
+static void msm_dp_ctrl_config_ctrl(struct msm_dp_ctrl_private *ctrl,
+		struct msm_dp_panel *msm_dp_panel)
 {
 	u32 config = 0, tbd;
 	const u8 *dpcd = ctrl->panel->dpcd;
 
-	/* Default-> LSCLK DIV: 1/4 LCLK  */
-	config |= (2 << DP_CONFIGURATION_CTRL_LSCLK_DIV_SHIFT);
+	if (msm_dp_panel->stream_id == DP_STREAM_0) {
+		/* Default-> LSCLK DIV: 1/4 LCLK  */
+		config |= (2 << DP_CONFIGURATION_CTRL_LSCLK_DIV_SHIFT);
 
-	/* Scrambler reset enable */
-	if (drm_dp_alternate_scrambler_reset_cap(dpcd))
-		config |= DP_CONFIGURATION_CTRL_ASSR;
+		/* Scrambler reset enable */
+		if (drm_dp_alternate_scrambler_reset_cap(dpcd))
+			config |= DP_CONFIGURATION_CTRL_ASSR;
 
-	tbd = dp_link_get_test_bits_depth(ctrl->link,
-			ctrl->panel->dp_mode.bpp);
+		/* Num of Lanes */
+		config |= ((ctrl->link->link_params.num_lanes - 1)
+				<< DP_CONFIGURATION_CTRL_NUM_OF_LANES_SHIFT);
 
-	config |= tbd << DP_CONFIGURATION_CTRL_BPC_SHIFT;
+		if (drm_dp_enhanced_frame_cap(dpcd))
+			config |= DP_CONFIGURATION_CTRL_ENHANCED_FRAMING;
+
+		config |= DP_CONFIGURATION_CTRL_P_INTERLACED; /* progressive video */
 
-	/* Num of Lanes */
-	config |= ((ctrl->link->link_params.num_lanes - 1)
-			<< DP_CONFIGURATION_CTRL_NUM_OF_LANES_SHIFT);
-
-	if (drm_dp_enhanced_frame_cap(dpcd))
-		config |= DP_CONFIGURATION_CTRL_ENHANCED_FRAMING;
-
-	config |= DP_CONFIGURATION_CTRL_P_INTERLACED; /* progressive video */
-
-	/* sync clock & static Mvid */
-	config |= DP_CONFIGURATION_CTRL_STATIC_DYNAMIC_CN;
-	config |= DP_CONFIGURATION_CTRL_SYNC_ASYNC_CLK;
+		/* sync clock & static Mvid */
+		config |= DP_CONFIGURATION_CTRL_STATIC_DYNAMIC_CN;
+		config |= DP_CONFIGURATION_CTRL_SYNC_ASYNC_CLK;
+	}
+
+	if (msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420)
+		config |= DP_CONFIGURATION_CTRL_RGB_YUV; /* YUV420 */
+
+	tbd = msm_dp_link_get_test_bits_depth(ctrl->link,
+		msm_dp_panel->msm_dp_mode.bpp);
+
+	config |= tbd << DP_CONFIGURATION_CTRL_BPC_SHIFT;
 
 	if (ctrl->panel->psr_cap.version)
 		config |= DP_CONFIGURATION_CTRL_SEND_VSC;
 
-	dp_catalog_ctrl_config_ctrl(ctrl->catalog, config);
+	msm_dp_catalog_ctrl_config_ctrl(ctrl->catalog, config);
 }
 
-static void dp_ctrl_configure_source_params(struct dp_ctrl_private *ctrl)
+static void msm_dp_ctrl_configure_source_params(struct msm_dp_ctrl_private *ctrl,
+		struct msm_dp_panel *msm_dp_panel)
 {
 	u32 cc, tb;
+	ctrl->catalog->stream_id = msm_dp_panel->stream_id;
+
+	msm_dp_catalog_ctrl_lane_mapping(ctrl->catalog);
+	msm_dp_catalog_setup_peripheral_flush(ctrl->catalog);
+
+	if (ctrl->mst_active)
+		msm_dp_catalog_mst_config(ctrl->catalog, true);
 
-	dp_catalog_ctrl_lane_mapping(ctrl->catalog);
-	dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, true);
+	msm_dp_ctrl_config_ctrl(ctrl, msm_dp_panel);
 
-	dp_ctrl_config_ctrl(ctrl);
+	tb = msm_dp_link_get_test_bits_depth(ctrl->link,
+		msm_dp_panel->msm_dp_mode.bpp);
+	cc = msm_dp_link_get_colorimetry_config(ctrl->link);
+	msm_dp_catalog_ctrl_config_misc(ctrl->catalog, cc, tb);
+	msm_dp_panel_timing_cfg(msm_dp_panel);
 
-	tb = dp_link_get_test_bits_depth(ctrl->link,
-		ctrl->panel->dp_mode.bpp);
-	cc = dp_link_get_colorimetry_config(ctrl->link);
-	dp_catalog_ctrl_config_misc(ctrl->catalog, cc, tb);
-	dp_panel_timing_cfg(ctrl->panel);
+	if (ctrl->mst_active)
+		msm_dp_catalog_mst_async_fifo(ctrl->catalog);
 }
 
 /*
@@ -292,7 +369,7 @@
 	}
 }
 
-static void dp_panel_update_tu_timings(struct dp_tu_calc_input *in,
+static void msm_dp_panel_update_tu_timings(struct msm_dp_tu_calc_input *in,
 					struct tu_algo_data *tu)
 {
 	int nlanes = in->nlanes;
@@ -604,9 +681,9 @@
 	}
 }
 
-static void _dp_ctrl_calc_tu(struct dp_ctrl_private *ctrl,
-				struct dp_tu_calc_input *in,
-				struct dp_vc_tu_mapping_table *tu_table)
+static void _dp_ctrl_calc_tu(struct msm_dp_ctrl_private *ctrl,
+				struct msm_dp_tu_calc_input *in,
+				struct msm_dp_vc_tu_mapping_table *tu_table)
 {
 	struct tu_algo_data *tu;
 	int compare_result_1, compare_result_2;
@@ -627,7 +704,7 @@
 	if (!tu)
 		return;
 
-	dp_panel_update_tu_timings(in, tu);
+	msm_dp_panel_update_tu_timings(in, tu);
 
 	tu->err_fp = drm_fixp_from_fraction(1000, 1); /* 1000 */
 
@@ -938,21 +1015,21 @@
 	kfree(tu);
 }
 
-static void dp_ctrl_calc_tu_parameters(struct dp_ctrl_private *ctrl,
-		struct dp_vc_tu_mapping_table *tu_table)
+static void msm_dp_ctrl_calc_tu_parameters(struct msm_dp_ctrl_private *ctrl,
+		struct msm_dp_vc_tu_mapping_table *tu_table)
 {
-	struct dp_tu_calc_input in;
+	struct msm_dp_tu_calc_input in;
 	struct drm_display_mode *drm_mode;
 
-	drm_mode = &ctrl->panel->dp_mode.drm_mode;
+	drm_mode = &ctrl->panel->msm_dp_mode.drm_mode;
 
 	in.lclk = ctrl->link->link_params.rate / 1000;
 	in.pclk_khz = drm_mode->clock;
 	in.hactive = drm_mode->hdisplay;
 	in.hporch = drm_mode->htotal - drm_mode->hdisplay;
 	in.nlanes = ctrl->link->link_params.num_lanes;
-	in.bpp = ctrl->panel->dp_mode.bpp;
-	in.pixel_enc = 444;
+	in.bpp = ctrl->panel->msm_dp_mode.bpp;
+	in.pixel_enc = ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420 ? 420 : 444;
 	in.dsc_en = 0;
 	in.async_en = 0;
 	in.fec_en = 0;
@@ -962,16 +1039,16 @@
 	_dp_ctrl_calc_tu(ctrl, &in, tu_table);
 }
 
-static void dp_ctrl_setup_tr_unit(struct dp_ctrl_private *ctrl)
+static void msm_dp_ctrl_setup_tr_unit(struct msm_dp_ctrl_private *ctrl)
 {
-	u32 dp_tu = 0x0;
+	u32 msm_dp_tu = 0x0;
 	u32 valid_boundary = 0x0;
 	u32 valid_boundary2 = 0x0;
-	struct dp_vc_tu_mapping_table tu_calc_table;
+	struct msm_dp_vc_tu_mapping_table tu_calc_table;
 
-	dp_ctrl_calc_tu_parameters(ctrl, &tu_calc_table);
+	msm_dp_ctrl_calc_tu_parameters(ctrl, &tu_calc_table);
 
-	dp_tu |= tu_calc_table.tu_size_minus1;
+	msm_dp_tu |= tu_calc_table.tu_size_minus1;
 	valid_boundary |= tu_calc_table.valid_boundary_link;
 	valid_boundary |= (tu_calc_table.delay_start_link << 16);
 
@@ -983,13 +1060,13 @@
 		valid_boundary2 |= BIT(0);
 
 	pr_debug("dp_tu=0x%x, valid_boundary=0x%x, valid_boundary2=0x%x\n",
-			dp_tu, valid_boundary, valid_boundary2);
+			msm_dp_tu, valid_boundary, valid_boundary2);
 
-	dp_catalog_ctrl_update_transfer_unit(ctrl->catalog,
-				dp_tu, valid_boundary, valid_boundary2);
+	msm_dp_catalog_ctrl_update_transfer_unit(ctrl->catalog,
+				msm_dp_tu, valid_boundary, valid_boundary2);
 }
 
-static int dp_ctrl_wait4video_ready(struct dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_wait4video_ready(struct msm_dp_ctrl_private *ctrl)
 {
 	int ret = 0;
 
@@ -1001,9 +1078,24 @@
 	return ret;
 }
 
-static int dp_ctrl_update_vx_px(struct dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_set_vx_px(struct msm_dp_ctrl_private *ctrl,
+			     u8 v_level, u8 p_level)
+{
+	union phy_configure_opts *phy_opts = &ctrl->phy_opts;
+
+	/* TODO: Update for all lanes instead of just first one */
+	phy_opts->dp.voltage[0] = v_level;
+	phy_opts->dp.pre[0] = p_level;
+	phy_opts->dp.set_voltages = 1;
+	phy_configure(ctrl->phy, phy_opts);
+	phy_opts->dp.set_voltages = 0;
+
+	return 0;
+}
+
+static int msm_dp_ctrl_update_vx_px(struct msm_dp_ctrl_private *ctrl)
 {
-	struct dp_link *link = ctrl->link;
+	struct msm_dp_link *link = ctrl->link;
 	int ret = 0, lane, lane_cnt;
 	u8 buf[4];
 	u32 max_level_reached = 0;
@@ -1013,20 +1105,20 @@
 	drm_dbg_dp(ctrl->drm_dev,
 		"voltage level: %d emphasis level: %d\n",
 			voltage_swing_level, pre_emphasis_level);
-	ret = dp_catalog_ctrl_update_vx_px(ctrl->catalog,
+	ret = msm_dp_ctrl_set_vx_px(ctrl,
 		voltage_swing_level, pre_emphasis_level);
 
 	if (ret)
 		return ret;
 
-	if (voltage_swing_level >= DP_TRAIN_VOLTAGE_SWING_MAX) {
+	if (voltage_swing_level >= DP_TRAIN_LEVEL_MAX) {
 		drm_dbg_dp(ctrl->drm_dev,
 				"max. voltage swing level reached %d\n",
 				voltage_swing_level);
 		max_level_reached |= DP_TRAIN_MAX_SWING_REACHED;
 	}
 
-	if (pre_emphasis_level >= DP_TRAIN_PRE_EMPHASIS_MAX) {
+	if (pre_emphasis_level >= DP_TRAIN_LEVEL_MAX) {
 		drm_dbg_dp(ctrl->drm_dev,
 				"max. pre-emphasis level reached %d\n",
 				pre_emphasis_level);
@@ -1050,7 +1142,7 @@
 	return ret;
 }
 
-static bool dp_ctrl_train_pattern_set(struct dp_ctrl_private *ctrl,
+static bool msm_dp_ctrl_train_pattern_set(struct msm_dp_ctrl_private *ctrl,
 		u8 pattern)
 {
 	u8 buf;
@@ -1067,7 +1159,7 @@
 	return ret == 1;
 }
 
-static int dp_ctrl_read_link_status(struct dp_ctrl_private *ctrl,
+static int msm_dp_ctrl_read_link_status(struct msm_dp_ctrl_private *ctrl,
 				    u8 *link_status)
 {
 	int ret = 0, len;
@@ -1081,24 +1173,24 @@
 	return ret;
 }
 
-static int dp_ctrl_link_train_1(struct dp_ctrl_private *ctrl,
+static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
 			int *training_step)
 {
 	int tries, old_v_level, ret = 0;
 	u8 link_status[DP_LINK_STATUS_SIZE];
 	int const maximum_retries = 4;
 
-	dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
 
 	*training_step = DP_TRAINING_1;
 
-	ret = dp_catalog_ctrl_set_pattern_state_bit(ctrl->catalog, 1);
+	ret = msm_dp_catalog_ctrl_set_pattern_state_bit(ctrl->catalog, 1);
 	if (ret)
 		return ret;
-	dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_1 |
+	msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_1 |
 		DP_LINK_SCRAMBLING_DISABLE);
 
-	ret = dp_ctrl_update_vx_px(ctrl);
+	ret = msm_dp_ctrl_update_vx_px(ctrl);
 	if (ret)
 		return ret;
 
@@ -1107,7 +1199,7 @@
 	for (tries = 0; tries < maximum_retries; tries++) {
 		drm_dp_link_train_clock_recovery_delay(ctrl->aux, ctrl->panel->dpcd);
 
-		ret = dp_ctrl_read_link_status(ctrl, link_status);
+		ret = msm_dp_ctrl_read_link_status(ctrl, link_status);
 		if (ret)
 			return ret;
 
@@ -1117,7 +1209,7 @@
 		}
 
 		if (ctrl->link->phy_params.v_level >=
-			DP_TRAIN_VOLTAGE_SWING_MAX) {
+			DP_TRAIN_LEVEL_MAX) {
 			DRM_ERROR_RATELIMITED("max v_level reached\n");
 			return -EAGAIN;
 		}
@@ -1127,8 +1219,8 @@
 			old_v_level = ctrl->link->phy_params.v_level;
 		}
 
-		dp_link_adjust_levels(ctrl->link, link_status);
-		ret = dp_ctrl_update_vx_px(ctrl);
+		msm_dp_link_adjust_levels(ctrl->link, link_status);
+		ret = msm_dp_ctrl_update_vx_px(ctrl);
 		if (ret)
 			return ret;
 	}
@@ -1137,7 +1229,7 @@
 	return -ETIMEDOUT;
 }
 
-static int dp_ctrl_link_rate_down_shift(struct dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_link_rate_down_shift(struct msm_dp_ctrl_private *ctrl)
 {
 	int ret = 0;
 
@@ -1165,7 +1257,7 @@
 	return ret;
 }
 
-static int dp_ctrl_link_lane_down_shift(struct dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_link_lane_down_shift(struct msm_dp_ctrl_private *ctrl)
 {
 
 	if (ctrl->link->link_params.num_lanes == 1)
@@ -1180,13 +1272,13 @@
 	return 0;
 }
 
-static void dp_ctrl_clear_training_pattern(struct dp_ctrl_private *ctrl)
+static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl)
 {
-	dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_DISABLE);
+	msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_DISABLE);
 	drm_dp_link_train_channel_eq_delay(ctrl->aux, ctrl->panel->dpcd);
 }
 
-static int dp_ctrl_link_train_2(struct dp_ctrl_private *ctrl,
+static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
 			int *training_step)
 {
 	int tries = 0, ret = 0;
@@ -1195,7 +1287,7 @@
 	int const maximum_retries = 5;
 	u8 link_status[DP_LINK_STATUS_SIZE];
 
-	dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
 
 	*training_step = DP_TRAINING_2;
 
@@ -1210,16 +1302,16 @@
 		state_ctrl_bit = 2;
 	}
 
-	ret = dp_catalog_ctrl_set_pattern_state_bit(ctrl->catalog, state_ctrl_bit);
+	ret = msm_dp_catalog_ctrl_set_pattern_state_bit(ctrl->catalog, state_ctrl_bit);
 	if (ret)
 		return ret;
 
-	dp_ctrl_train_pattern_set(ctrl, pattern);
+	msm_dp_ctrl_train_pattern_set(ctrl, pattern);
 
 	for (tries = 0; tries <= maximum_retries; tries++) {
 		drm_dp_link_train_channel_eq_delay(ctrl->aux, ctrl->panel->dpcd);
 
-		ret = dp_ctrl_read_link_status(ctrl, link_status);
+		ret = msm_dp_ctrl_read_link_status(ctrl, link_status);
 		if (ret)
 			return ret;
 
@@ -1228,8 +1320,8 @@
 			return 0;
 		}
 
-		dp_link_adjust_levels(ctrl->link, link_status);
-		ret = dp_ctrl_update_vx_px(ctrl);
+		msm_dp_link_adjust_levels(ctrl->link, link_status);
+		ret = msm_dp_ctrl_update_vx_px(ctrl);
 		if (ret)
 			return ret;
 
@@ -1238,22 +1330,24 @@
 	return -ETIMEDOUT;
 }
 
-static int dp_ctrl_link_train(struct dp_ctrl_private *ctrl,
+static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,
 			int *training_step)
 {
 	int ret = 0;
 	const u8 *dpcd = ctrl->panel->dpcd;
 	u8 encoding[] = { 0, DP_SET_ANSI_8B10B };
 	u8 assr;
-	struct dp_link_info link_info = {0};
+	struct msm_dp_link_info link_info = {0};
 
-	dp_ctrl_config_ctrl(ctrl);
+	msm_dp_ctrl_config_ctrl(ctrl, ctrl->panel);
 
 	link_info.num_lanes = ctrl->link->link_params.num_lanes;
 	link_info.rate = ctrl->link->link_params.rate;
 	link_info.capabilities = DP_LINK_CAP_ENHANCED_FRAMING;
 
-	dp_aux_link_configure(ctrl->aux, &link_info);
+	msm_dp_link_reset_phy_params_vx_px(ctrl->link);
+
+	msm_dp_aux_link_configure(ctrl->aux, &link_info);
 
 	if (drm_dp_max_downspread(dpcd))
 		encoding[0] |= DP_SPREAD_AMP_0_5;
@@ -1267,7 +1361,7 @@
 				&assr, 1);
 	}
 
-	ret = dp_ctrl_link_train_1(ctrl, training_step);
+	ret = msm_dp_ctrl_link_train_1(ctrl, training_step);
 	if (ret) {
 		DRM_ERROR("link training #1 failed. ret=%d\n", ret);
 		goto end;
@@ -1276,7 +1370,7 @@
 	/* print success info as this is a result of user initiated action */
 	drm_dbg_dp(ctrl->drm_dev, "link training #1 successful\n");
 
-	ret = dp_ctrl_link_train_2(ctrl, training_step);
+	ret = msm_dp_ctrl_link_train_2(ctrl, training_step);
 	if (ret) {
 		DRM_ERROR("link training #2 failed. ret=%d\n", ret);
 		goto end;
@@ -1286,17 +1380,17 @@
 	drm_dbg_dp(ctrl->drm_dev, "link training #2 successful\n");
 
 end:
-	dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
 
 	return ret;
 }
 
-static int dp_ctrl_setup_main_link(struct dp_ctrl_private *ctrl,
+static int msm_dp_ctrl_setup_main_link(struct msm_dp_ctrl_private *ctrl,
 			int *training_step)
 {
 	int ret = 0;
 
-	dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, true);
+	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, true);
 
 	if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN)
 		return ret;
@@ -1307,49 +1401,120 @@
 	 * a link training pattern, we have to first do soft reset.
 	 */
 
-	ret = dp_ctrl_link_train(ctrl, training_step);
+	ret = msm_dp_ctrl_link_train(ctrl, training_step);
 
 	return ret;
 }
 
-static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl,
-			enum dp_pm_type module, char *name, unsigned long rate)
+int msm_dp_ctrl_core_clk_enable(struct msm_dp_ctrl *msm_dp_ctrl)
 {
-	u32 num = ctrl->parser->mp[module].num_clk;
-	struct clk_bulk_data *cfg = ctrl->parser->mp[module].clocks;
+	struct msm_dp_ctrl_private *ctrl;
+	int ret = 0;
 
-	while (num && strcmp(cfg->id, name)) {
-		num--;
-		cfg++;
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	if (ctrl->core_clks_on) {
+		drm_dbg_dp(ctrl->drm_dev, "core clks already enabled\n");
+		return 0;
 	}
 
-	drm_dbg_dp(ctrl->drm_dev, "setting rate=%lu on clk=%s\n",
-						rate, name);
+	ret = clk_bulk_prepare_enable(ctrl->num_core_clks, ctrl->core_clks);
+	if (ret)
+		return ret;
 
-	if (num)
-		clk_set_rate(cfg->clk, rate);
-	else
-		DRM_ERROR("%s clock doesn't exit to set rate %lu\n",
-				name, rate);
+	ctrl->core_clks_on = true;
+
+	drm_dbg_dp(ctrl->drm_dev, "enable core clocks \n");
+	drm_dbg_dp(ctrl->drm_dev, "stream_clks:%s link_clks:%s core_clks:%s\n",
+		   ctrl->stream_clks_on ? "on" : "off",
+		   ctrl->link_clks_on ? "on" : "off",
+		   ctrl->core_clks_on ? "on" : "off");
+
+	return 0;
+}
+
+void msm_dp_ctrl_core_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	clk_bulk_disable_unprepare(ctrl->num_core_clks, ctrl->core_clks);
+
+	ctrl->core_clks_on = false;
+
+	drm_dbg_dp(ctrl->drm_dev, "disable core clocks \n");
+	drm_dbg_dp(ctrl->drm_dev, "stream_clks:%s link_clks:%s core_clks:%s\n",
+		   ctrl->stream_clks_on ? "on" : "off",
+		   ctrl->link_clks_on ? "on" : "off",
+		   ctrl->core_clks_on ? "on" : "off");
 }
 
-static int dp_ctrl_enable_mainlink_clocks(struct dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_link_clk_enable(struct msm_dp_ctrl *msm_dp_ctrl)
 {
+	struct msm_dp_ctrl_private *ctrl;
 	int ret = 0;
-	struct dp_io *dp_io = &ctrl->parser->io;
-	struct phy *phy = dp_io->phy;
-	struct phy_configure_opts_dp *opts_dp = &dp_io->phy_opts.dp;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	if (ctrl->link_clks_on) {
+		drm_dbg_dp(ctrl->drm_dev, "links clks already enabled\n");
+		return 0;
+	}
+
+	if (!ctrl->core_clks_on) {
+		drm_dbg_dp(ctrl->drm_dev, "Enable core clks before link clks\n");
+
+		msm_dp_ctrl_core_clk_enable(msm_dp_ctrl);
+	}
+
+	ret = clk_bulk_prepare_enable(ctrl->num_link_clks, ctrl->link_clks);
+	if (ret)
+		return ret;
+
+	ctrl->link_clks_on = true;
+
+	drm_dbg_dp(ctrl->drm_dev, "enable link clocks\n");
+	drm_dbg_dp(ctrl->drm_dev, "stream_clks:%s link_clks:%s core_clks:%s\n",
+		   ctrl->stream_clks_on ? "on" : "off",
+		   ctrl->link_clks_on ? "on" : "off",
+		   ctrl->core_clks_on ? "on" : "off");
+
+	return 0;
+}
+
+static void msm_dp_ctrl_link_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	clk_bulk_disable_unprepare(ctrl->num_link_clks, ctrl->link_clks);
+
+	ctrl->link_clks_on = false;
+
+	drm_dbg_dp(ctrl->drm_dev, "disabled link clocks\n");
+	drm_dbg_dp(ctrl->drm_dev, "stream_clks:%s link_clks:%s core_clks:%s\n",
+		   ctrl->stream_clks_on ? "on" : "off",
+		   ctrl->link_clks_on ? "on" : "off",
+		   ctrl->core_clks_on ? "on" : "off");
+}
+
+static int msm_dp_ctrl_enable_mainlink_clocks(struct msm_dp_ctrl_private *ctrl)
+{
+	int ret = 0;
+	struct phy *phy = ctrl->phy;
 	const u8 *dpcd = ctrl->panel->dpcd;
 
-	opts_dp->lanes = ctrl->link->link_params.num_lanes;
-	opts_dp->link_rate = ctrl->link->link_params.rate / 100;
-	opts_dp->ssc = drm_dp_max_downspread(dpcd);
+	ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;
+	ctrl->phy_opts.dp.link_rate = ctrl->link->link_params.rate / 100;
+	ctrl->phy_opts.dp.ssc = drm_dp_max_downspread(dpcd);
 
-	phy_configure(phy, &dp_io->phy_opts);
+	phy_configure(phy, &ctrl->phy_opts);
 	phy_power_on(phy);
 
 	dev_pm_opp_set_rate(ctrl->dev, ctrl->link->link_params.rate * 1000);
-	ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, true);
+	ret = msm_dp_ctrl_link_clk_enable(&ctrl->msm_dp_ctrl);
 	if (ret)
 		DRM_ERROR("Unable to start link clocks. ret=%d\n", ret);
 
@@ -1358,13 +1523,13 @@
 	return ret;
 }
 
-void dp_ctrl_reset_irq_ctrl(struct dp_ctrl *dp_ctrl, bool enable)
+void msm_dp_ctrl_reset_irq_ctrl(struct msm_dp_ctrl *msm_dp_ctrl, bool enable)
 {
-	struct dp_ctrl_private *ctrl;
+	struct msm_dp_ctrl_private *ctrl;
 
-	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 
-	dp_catalog_ctrl_reset(ctrl->catalog);
+	msm_dp_catalog_ctrl_reset(ctrl->catalog);
 
 	/*
 	 * all dp controller programmable registers will not
@@ -1372,28 +1537,28 @@
 	 * therefore interrupt mask bits have to be updated
 	 * to enable/disable interrupts
 	 */
-	dp_catalog_ctrl_enable_irq(ctrl->catalog, enable);
+	msm_dp_catalog_ctrl_enable_irq(ctrl->catalog, enable);
 }
 
-void dp_ctrl_config_psr(struct dp_ctrl *dp_ctrl)
+void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl)
 {
 	u8 cfg;
-	struct dp_ctrl_private *ctrl = container_of(dp_ctrl,
-			struct dp_ctrl_private, dp_ctrl);
+	struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,
+			struct msm_dp_ctrl_private, msm_dp_ctrl);
 
 	if (!ctrl->panel->psr_cap.version)
 		return;
 
-	dp_catalog_ctrl_config_psr(ctrl->catalog);
+	msm_dp_catalog_ctrl_config_psr(ctrl->catalog);
 
 	cfg = DP_PSR_ENABLE;
 	drm_dp_dpcd_write(ctrl->aux, DP_PSR_EN_CFG, &cfg, 1);
 }
 
-void dp_ctrl_set_psr(struct dp_ctrl *dp_ctrl, bool enter)
+void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl, bool enter)
 {
-	struct dp_ctrl_private *ctrl = container_of(dp_ctrl,
-			struct dp_ctrl_private, dp_ctrl);
+	struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,
+			struct msm_dp_ctrl_private, msm_dp_ctrl);
 
 	if (!ctrl->panel->psr_cap.version)
 		return;
@@ -1410,103 +1575,80 @@
 	 */
 	if (enter) {
 		reinit_completion(&ctrl->psr_op_comp);
-		dp_catalog_ctrl_set_psr(ctrl->catalog, true);
+		msm_dp_catalog_ctrl_set_psr(ctrl->catalog, true);
 
 		if (!wait_for_completion_timeout(&ctrl->psr_op_comp,
 			PSR_OPERATION_COMPLETION_TIMEOUT_JIFFIES)) {
 			DRM_ERROR("PSR_ENTRY timedout\n");
-			dp_catalog_ctrl_set_psr(ctrl->catalog, false);
+			msm_dp_catalog_ctrl_set_psr(ctrl->catalog, false);
 			return;
 		}
 
-		dp_ctrl_push_idle(dp_ctrl);
-		dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+		msm_dp_ctrl_push_idle(msm_dp_ctrl);
+		msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
 
-		dp_catalog_ctrl_psr_mainlink_enable(ctrl->catalog, false);
+		msm_dp_catalog_ctrl_psr_mainlink_enable(ctrl->catalog, false);
 	} else {
-		dp_catalog_ctrl_psr_mainlink_enable(ctrl->catalog, true);
+		msm_dp_catalog_ctrl_psr_mainlink_enable(ctrl->catalog, true);
 
-		dp_catalog_ctrl_set_psr(ctrl->catalog, false);
-		dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
-		dp_ctrl_wait4video_ready(ctrl);
-		dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+		msm_dp_catalog_ctrl_set_psr(ctrl->catalog, false);
+		msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
+		msm_dp_ctrl_wait4video_ready(ctrl);
+		msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
 	}
 }
 
-void dp_ctrl_phy_init(struct dp_ctrl *dp_ctrl)
+void msm_dp_ctrl_phy_init(struct msm_dp_ctrl *msm_dp_ctrl)
 {
-	struct dp_ctrl_private *ctrl;
-	struct dp_io *dp_io;
+	struct msm_dp_ctrl_private *ctrl;
 	struct phy *phy;
 
-	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
-	dp_io = &ctrl->parser->io;
-	phy = dp_io->phy;
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	phy = ctrl->phy;
 
-	dp_catalog_ctrl_phy_reset(ctrl->catalog);
+	msm_dp_catalog_ctrl_phy_reset(ctrl->catalog);
 	phy_init(phy);
 
 	drm_dbg_dp(ctrl->drm_dev, "phy=%p init=%d power_on=%d\n",
 			phy, phy->init_count, phy->power_count);
 }
 
-void dp_ctrl_phy_exit(struct dp_ctrl *dp_ctrl)
+void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl)
 {
-	struct dp_ctrl_private *ctrl;
-	struct dp_io *dp_io;
+	struct msm_dp_ctrl_private *ctrl;
 	struct phy *phy;
 
-	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
-	dp_io = &ctrl->parser->io;
-	phy = dp_io->phy;
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	phy = ctrl->phy;
 
-	dp_catalog_ctrl_phy_reset(ctrl->catalog);
+	msm_dp_catalog_ctrl_phy_reset(ctrl->catalog);
 	phy_exit(phy);
 	drm_dbg_dp(ctrl->drm_dev, "phy=%p init=%d power_on=%d\n",
 			phy, phy->init_count, phy->power_count);
 }
 
-static bool dp_ctrl_use_fixed_nvid(struct dp_ctrl_private *ctrl)
-{
-	const u8 *dpcd = ctrl->panel->dpcd;
-
-	/*
-	 * For better interop experience, used a fixed NVID=0x8000
-	 * whenever connected to a VGA dongle downstream.
-	 */
-	if (drm_dp_is_branch(dpcd))
-		return (drm_dp_has_quirk(&ctrl->panel->desc,
-					 DP_DPCD_QUIRK_CONSTANT_N));
-
-	return false;
-}
-
-static int dp_ctrl_reinitialize_mainlink(struct dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
 {
+	struct phy *phy = ctrl->phy;
 	int ret = 0;
-	struct dp_io *dp_io = &ctrl->parser->io;
-	struct phy *phy = dp_io->phy;
-	struct phy_configure_opts_dp *opts_dp = &dp_io->phy_opts.dp;
-
-	dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
-	opts_dp->lanes = ctrl->link->link_params.num_lanes;
-	phy_configure(phy, &dp_io->phy_opts);
+
+	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
+	ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;
+	phy_configure(phy, &ctrl->phy_opts);
 	/*
 	 * Disable and re-enable the mainlink clock since the
 	 * link clock might have been adjusted as part of the
 	 * link maintenance.
 	 */
 	dev_pm_opp_set_rate(ctrl->dev, 0);
-	ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
-	if (ret) {
-		DRM_ERROR("Failed to disable clocks. ret=%d\n", ret);
-		return ret;
-	}
+
+	msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
+
 	phy_power_off(phy);
 	/* hw recommended delay before re-enabling clocks */
 	msleep(20);
 
-	ret = dp_ctrl_enable_mainlink_clocks(ctrl);
+	ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl);
 	if (ret) {
 		DRM_ERROR("Failed to enable mainlink clks. ret=%d\n", ret);
 		return ret;
@@ -1515,24 +1657,18 @@
 	return ret;
 }
 
-static int dp_ctrl_deinitialize_mainlink(struct dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
 {
-	struct dp_io *dp_io;
 	struct phy *phy;
-	int ret;
 
-	dp_io = &ctrl->parser->io;
-	phy = dp_io->phy;
+	phy = ctrl->phy;
 
-	dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
+	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
 
-	dp_catalog_ctrl_reset(ctrl->catalog);
+	msm_dp_catalog_ctrl_reset(ctrl->catalog);
 
 	dev_pm_opp_set_rate(ctrl->dev, 0);
-	ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
-	if (ret) {
-		DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret);
-	}
+	msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
 
 	phy_power_off(phy);
 
@@ -1545,30 +1681,53 @@
 	return 0;
 }
 
-static int dp_ctrl_link_maintenance(struct dp_ctrl_private *ctrl)
+int msm_dp_ctrl_mst_send_act(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	bool act_complete;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	msm_dp_catalog_trigger_act(ctrl->catalog);
+	msleep(20); /* needs 1 frame time */
+
+	act_complete = msm_dp_catalog_read_act_complete_sts(ctrl->catalog);
+
+	if (!act_complete)
+		drm_dbg_dp(ctrl->drm_dev, "mst ACT trigger complete SUCCESS\n");
+	else
+		DRM_ERROR("mst ACT trigger complete failed\n");
+
+	return 0;
+}
+
+static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl)
 {
 	int ret = 0;
 	int training_step = DP_TRAINING_NONE;
 
-	dp_ctrl_push_idle(&ctrl->dp_ctrl);
+	msm_dp_ctrl_push_idle(&ctrl->msm_dp_ctrl);
 
 	ctrl->link->phy_params.p_level = 0;
 	ctrl->link->phy_params.v_level = 0;
 
-	ret = dp_ctrl_setup_main_link(ctrl, &training_step);
+	ret = msm_dp_ctrl_setup_main_link(ctrl, &training_step);
 	if (ret)
 		goto end;
 
-	dp_ctrl_clear_training_pattern(ctrl);
+	msm_dp_ctrl_clear_training_pattern(ctrl);
+
+	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
 
-	dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
+	if (ctrl->mst_active)
+		msm_dp_ctrl_mst_send_act(&ctrl->msm_dp_ctrl);
 
-	ret = dp_ctrl_wait4video_ready(ctrl);
+	ret = msm_dp_ctrl_wait4video_ready(ctrl);
 end:
 	return ret;
 }
 
-static bool dp_ctrl_send_phy_test_pattern(struct dp_ctrl_private *ctrl)
+static bool msm_dp_ctrl_send_phy_test_pattern(struct msm_dp_ctrl_private *ctrl)
 {
 	bool success = false;
 	u32 pattern_sent = 0x0;
@@ -1576,17 +1735,17 @@
 
 	drm_dbg_dp(ctrl->drm_dev, "request: 0x%x\n", pattern_requested);
 
-	if (dp_catalog_ctrl_update_vx_px(ctrl->catalog,
+	if (msm_dp_ctrl_set_vx_px(ctrl,
 			ctrl->link->phy_params.v_level,
 			ctrl->link->phy_params.p_level)) {
 		DRM_ERROR("Failed to set v/p levels\n");
 		return false;
 	}
-	dp_catalog_ctrl_send_phy_pattern(ctrl->catalog, pattern_requested);
-	dp_ctrl_update_vx_px(ctrl);
-	dp_link_send_test_response(ctrl->link);
+	msm_dp_catalog_ctrl_send_phy_pattern(ctrl->catalog, pattern_requested);
+	msm_dp_ctrl_update_vx_px(ctrl);
+	msm_dp_link_send_test_response(ctrl->link);
 
-	pattern_sent = dp_catalog_ctrl_read_phy_pattern(ctrl->catalog);
+	pattern_sent = msm_dp_catalog_ctrl_read_phy_pattern(ctrl->catalog);
 
 	switch (pattern_sent) {
 	case MR_LINK_TRAINING1:
@@ -1620,7 +1779,33 @@
 	return success;
 }
 
-static int dp_ctrl_process_phy_test_request(struct dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_stream_clk_on(struct msm_dp_ctrl_private *ctrl, unsigned long pixel_rate,
+				     enum msm_dp_stream_id stream_id)
+{
+	int ret;
+
+	ret = clk_set_rate(ctrl->pixel_clk[stream_id], pixel_rate * 1000);
+	if (ret) {
+		DRM_ERROR("Failed to set stream clk rate. ret=%d\n", ret);
+		return ret;
+	}
+
+	if (ctrl->stream_clks_on[stream_id]) {
+		drm_dbg_dp(ctrl->drm_dev, "stream clks already enabled\n");
+	} else {
+		ret = clk_prepare_enable(ctrl->pixel_clk[stream_id]);
+		if (ret) {
+			DRM_ERROR("Failed to start stream clks. ret=%d\n", ret);
+			return ret;
+		}
+		ctrl->stream_clks_on[stream_id] = true;
+	}
+
+	return ret;
+}
+
+static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl,
+		struct msm_dp_panel *msm_dp_panel)
 {
 	int ret;
 	unsigned long pixel_rate;
@@ -1636,70 +1821,61 @@
 	 * running. Add the global reset just before disabling the
 	 * link clocks and core clocks.
 	 */
-	ret = dp_ctrl_off(&ctrl->dp_ctrl);
-	if (ret) {
-		DRM_ERROR("failed to disable DP controller\n");
-		return ret;
-	}
+	msm_dp_ctrl_stream_clk_off(&ctrl->msm_dp_ctrl, msm_dp_panel);
+	msm_dp_ctrl_off_link(&ctrl->msm_dp_ctrl);
 
-	ret = dp_ctrl_on_link(&ctrl->dp_ctrl);
+	ret = msm_dp_ctrl_on_link(&ctrl->msm_dp_ctrl, ctrl->mst_active);
 	if (ret) {
 		DRM_ERROR("failed to enable DP link controller\n");
 		return ret;
 	}
 
-	pixel_rate = ctrl->panel->dp_mode.drm_mode.clock;
-	dp_ctrl_set_clock_rate(ctrl, DP_STREAM_PM, "stream_pixel", pixel_rate * 1000);
-
-	ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, true);
-	if (ret) {
-		DRM_ERROR("Failed to start pixel clocks. ret=%d\n", ret);
-		return ret;
-	}
+	pixel_rate = msm_dp_panel->msm_dp_mode.drm_mode.clock;
+	ret = msm_dp_ctrl_stream_clk_on(ctrl, pixel_rate, msm_dp_panel->stream_id);
 
-	dp_ctrl_send_phy_test_pattern(ctrl);
+	msm_dp_ctrl_send_phy_test_pattern(ctrl);
 
 	return 0;
 }
 
-void dp_ctrl_handle_sink_request(struct dp_ctrl *dp_ctrl)
+void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl)
 {
-	struct dp_ctrl_private *ctrl;
+	struct msm_dp_ctrl_private *ctrl;
 	u32 sink_request = 0x0;
 
-	if (!dp_ctrl) {
+	if (!msm_dp_ctrl) {
 		DRM_ERROR("invalid input\n");
 		return;
 	}
 
-	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 	sink_request = ctrl->link->sink_request;
 
 	if (sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
 		drm_dbg_dp(ctrl->drm_dev, "PHY_TEST_PATTERN request\n");
-		if (dp_ctrl_process_phy_test_request(ctrl)) {
+		if (msm_dp_ctrl_process_phy_test_request(ctrl, ctrl->panel)) {
 			DRM_ERROR("process phy_test_req failed\n");
 			return;
 		}
 	}
 
 	if (sink_request & DP_LINK_STATUS_UPDATED) {
-		if (dp_ctrl_link_maintenance(ctrl)) {
+		if (msm_dp_ctrl_link_maintenance(ctrl)) {
 			DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");
 			return;
 		}
 	}
 
 	if (sink_request & DP_TEST_LINK_TRAINING) {
-		dp_link_send_test_response(ctrl->link);
-		if (dp_ctrl_link_maintenance(ctrl)) {
+		msm_dp_link_send_test_response(ctrl->link);
+		if (msm_dp_ctrl_link_maintenance(ctrl)) {
 			DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");
 			return;
 		}
 	}
 }
 
-static bool dp_ctrl_clock_recovery_any_ok(
+static bool msm_dp_ctrl_clock_recovery_any_ok(
 			const u8 link_status[DP_LINK_STATUS_SIZE],
 			int lane_count)
 {
@@ -1718,20 +1894,20 @@
 	return drm_dp_clock_recovery_ok(link_status, reduced_cnt);
 }
 
-static bool dp_ctrl_channel_eq_ok(struct dp_ctrl_private *ctrl)
+static bool msm_dp_ctrl_channel_eq_ok(struct msm_dp_ctrl_private *ctrl)
 {
 	u8 link_status[DP_LINK_STATUS_SIZE];
 	int num_lanes = ctrl->link->link_params.num_lanes;
 
-	dp_ctrl_read_link_status(ctrl, link_status);
+	msm_dp_ctrl_read_link_status(ctrl, link_status);
 
 	return drm_dp_channel_eq_ok(link_status, num_lanes);
 }
 
-int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl)
+int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl, bool mst_active)
 {
 	int rc = 0;
-	struct dp_ctrl_private *ctrl;
+	struct msm_dp_ctrl_private *ctrl;
 	u32 rate;
 	int link_train_max_retries = 5;
 	u32 const phy_cts_pixel_clk_khz = 148500;
@@ -1739,15 +1915,16 @@
 	unsigned int training_step;
 	unsigned long pixel_rate;
 
-	if (!dp_ctrl)
+	if (!msm_dp_ctrl)
 		return -EINVAL;
 
-	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 
 	rate = ctrl->panel->link_info.rate;
-	pixel_rate = ctrl->panel->dp_mode.drm_mode.clock;
+	pixel_rate = ctrl->panel->msm_dp_mode.drm_mode.clock;
 
-	dp_power_clk_enable(ctrl->power, DP_CORE_PM, true);
+	ctrl->mst_active = mst_active;
+	msm_dp_ctrl_core_clk_enable(&ctrl->msm_dp_ctrl);
 
 	if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
 		drm_dbg_dp(ctrl->drm_dev,
@@ -1758,38 +1935,40 @@
 		ctrl->link->link_params.rate = rate;
 		ctrl->link->link_params.num_lanes =
 			ctrl->panel->link_info.num_lanes;
+		if (ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420)
+			pixel_rate >>= 1;
 	}
 
 	drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d, pixel_rate=%lu\n",
 		ctrl->link->link_params.rate, ctrl->link->link_params.num_lanes,
 		pixel_rate);
 
-	rc = dp_ctrl_enable_mainlink_clocks(ctrl);
+	rc = msm_dp_ctrl_enable_mainlink_clocks(ctrl);
 	if (rc)
 		return rc;
 
 	while (--link_train_max_retries) {
 		training_step = DP_TRAINING_NONE;
-		rc = dp_ctrl_setup_main_link(ctrl, &training_step);
+		rc = msm_dp_ctrl_setup_main_link(ctrl, &training_step);
 		if (rc == 0) {
 			/* training completed successfully */
 			break;
 		} else if (training_step == DP_TRAINING_1) {
 			/* link train_1 failed */
-			if (!dp_catalog_link_is_connected(ctrl->catalog))
+			if (!msm_dp_catalog_link_is_connected(ctrl->catalog))
 				break;
 
-			dp_ctrl_read_link_status(ctrl, link_status);
+			msm_dp_ctrl_read_link_status(ctrl, link_status);
 
-			rc = dp_ctrl_link_rate_down_shift(ctrl);
+			rc = msm_dp_ctrl_link_rate_down_shift(ctrl);
 			if (rc < 0) { /* already in RBR = 1.6G */
-				if (dp_ctrl_clock_recovery_any_ok(link_status,
+				if (msm_dp_ctrl_clock_recovery_any_ok(link_status,
 					ctrl->link->link_params.num_lanes)) {
 					/*
 					 * some lanes are ready,
 					 * reduce lane number
 					 */
-					rc = dp_ctrl_link_lane_down_shift(ctrl);
+					rc = msm_dp_ctrl_link_lane_down_shift(ctrl);
 					if (rc < 0) { /* lane == 1 already */
 						/* end with failure */
 						break;
@@ -1801,16 +1980,16 @@
 			}
 		} else if (training_step == DP_TRAINING_2) {
 			/* link train_2 failed */
-			if (!dp_catalog_link_is_connected(ctrl->catalog))
+			if (!msm_dp_catalog_link_is_connected(ctrl->catalog))
 				break;
 
-			dp_ctrl_read_link_status(ctrl, link_status);
+			msm_dp_ctrl_read_link_status(ctrl, link_status);
 
 			if (!drm_dp_clock_recovery_ok(link_status,
 					ctrl->link->link_params.num_lanes))
-				rc = dp_ctrl_link_rate_down_shift(ctrl);
+				rc = msm_dp_ctrl_link_rate_down_shift(ctrl);
 			else
-				rc = dp_ctrl_link_lane_down_shift(ctrl);
+				rc = msm_dp_ctrl_link_lane_down_shift(ctrl);
 
 			if (rc < 0) {
 				/* end with failure */
@@ -1818,10 +1997,10 @@
 			}
 
 			/* stop link training before start re training  */
-			dp_ctrl_clear_training_pattern(ctrl);
+			msm_dp_ctrl_clear_training_pattern(ctrl);
 		}
 
-		rc = dp_ctrl_reinitialize_mainlink(ctrl);
+		rc = msm_dp_ctrl_reinitialize_mainlink(ctrl);
 		if (rc) {
 			DRM_ERROR("Failed to reinitialize mainlink. rc=%d\n", rc);
 			break;
@@ -1842,65 +2021,178 @@
 		 * link training failed
 		 * end txing train pattern here
 		 */
-		dp_ctrl_clear_training_pattern(ctrl);
+		msm_dp_ctrl_clear_training_pattern(ctrl);
 
-		dp_ctrl_deinitialize_mainlink(ctrl);
+		msm_dp_ctrl_deinitialize_mainlink(ctrl);
 		rc = -ECONNRESET;
 	}
 
 	return rc;
 }
 
-static int dp_ctrl_link_retrain(struct dp_ctrl_private *ctrl)
+static int msm_dp_ctrl_link_retrain(struct msm_dp_ctrl_private *ctrl)
 {
 	int training_step = DP_TRAINING_NONE;
 
-	return dp_ctrl_setup_main_link(ctrl, &training_step);
+	return msm_dp_ctrl_setup_main_link(ctrl, &training_step);
 }
 
-int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool force_link_train)
+int msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train)
 {
 	int ret = 0;
-	bool mainlink_ready = false;
-	struct dp_ctrl_private *ctrl;
-	unsigned long pixel_rate;
-	unsigned long pixel_rate_orig;
+	struct msm_dp_ctrl_private *ctrl;
 
-	if (!dp_ctrl)
+	if (!msm_dp_ctrl)
 		return -EINVAL;
 
-	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 
-	pixel_rate = pixel_rate_orig = ctrl->panel->dp_mode.drm_mode.clock;
-
-	if (dp_ctrl->wide_bus_en)
-		pixel_rate >>= 1;
-
-	drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d, pixel_rate=%lu\n",
+	drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d\n",
 		ctrl->link->link_params.rate,
-		ctrl->link->link_params.num_lanes, pixel_rate);
+		ctrl->link->link_params.num_lanes);
+
+	drm_dbg_dp(ctrl->drm_dev,
+		"core_clk_on=%d link_clk_on=%d\n",
+		ctrl->core_clks_on, ctrl->link_clks_on);
 
-	if (!dp_power_clk_status(ctrl->power, DP_CTRL_PM)) { /* link clk is off */
-		ret = dp_ctrl_enable_mainlink_clocks(ctrl);
+	if (!ctrl->link_clks_on) { /* link clk is off */
+		ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl);
 		if (ret) {
 			DRM_ERROR("Failed to start link clocks. ret=%d\n", ret);
-			goto end;
+			return ret;
 		}
 	}
 
-	dp_ctrl_set_clock_rate(ctrl, DP_STREAM_PM, "stream_pixel", pixel_rate * 1000);
+	if (force_link_train || !msm_dp_ctrl_channel_eq_ok(ctrl))
+		msm_dp_ctrl_link_retrain(ctrl);
 
-	ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, true);
-	if (ret) {
-		DRM_ERROR("Unable to start pixel clocks. ret=%d\n", ret);
-		goto end;
+	/* stop txing train pattern to end link training */
+	msm_dp_ctrl_clear_training_pattern(ctrl);
+
+	return ret;
+}
+
+static void msm_dp_ctrl_mst_calculate_rg(struct msm_dp_ctrl_private *ctrl,
+					 struct msm_dp_panel *panel,
+					 u32 *p_x_int, u32 *p_y_frac_enum)
+{
+	u64 min_slot_cnt, max_slot_cnt;
+	u64 raw_target_sc, target_sc_fixp;
+	u64 ts_denom, ts_enum, ts_int;
+	u64 pclk = panel->msm_dp_mode.drm_mode.clock;
+	u64 lclk = 0;
+	u64 lanes = ctrl->link->link_params.num_lanes;
+	u64 bpp = panel->msm_dp_mode.bpp;
+	u64 pbn = panel->mst_caps.pbn;
+	u64 numerator, denominator, temp, temp1, temp2;
+	u32 x_int = 0, y_frac_enum = 0;
+	u64 target_strm_sym, ts_int_fixp, ts_frac_fixp, y_frac_enum_fixp;
+
+	lclk = ctrl->link->link_params.rate;
+
+	/* min_slot_cnt */
+	numerator = pclk * bpp * 64 * 1000;
+	denominator = lclk * lanes * 8 * 1000;
+	min_slot_cnt = drm_fixp_from_fraction(numerator, denominator);
+
+	/* max_slot_cnt */
+	numerator = pbn * 54 * 1000;
+	denominator = lclk * lanes;
+	max_slot_cnt = drm_fixp_from_fraction(numerator, denominator);
+
+	/* raw_target_sc */
+	numerator = max_slot_cnt + min_slot_cnt;
+	denominator = drm_fixp_from_fraction(2, 1);
+	raw_target_sc = drm_fixp_div(numerator, denominator);
+
+	/* target_sc */
+	temp = drm_fixp_from_fraction(256 * lanes, 1);
+	numerator = drm_fixp_mul(raw_target_sc, temp);
+	denominator = drm_fixp_from_fraction(256 * lanes, 1);
+	target_sc_fixp = drm_fixp_div(numerator, denominator);
+
+	ts_enum = 256 * lanes;
+	ts_denom = drm_fixp_from_fraction(256 * lanes, 1);
+	ts_int = drm_fixp2int(target_sc_fixp);
+
+	temp = drm_fixp2int_ceil(raw_target_sc);
+	if (temp != ts_int) {
+		temp = drm_fixp_from_fraction(ts_int, 1);
+		temp1 = raw_target_sc - temp;
+		temp2 = drm_fixp_mul(temp1, ts_denom);
+		ts_enum = drm_fixp2int(temp2);
 	}
 
-	if (force_link_train || !dp_ctrl_channel_eq_ok(ctrl))
-		dp_ctrl_link_retrain(ctrl);
+	/* target_strm_sym */
+	ts_int_fixp = drm_fixp_from_fraction(ts_int, 1);
+	ts_frac_fixp = drm_fixp_from_fraction(ts_enum, drm_fixp2int(ts_denom));
+	temp = ts_int_fixp + ts_frac_fixp;
+	temp1 = drm_fixp_from_fraction(lanes, 1);
+	target_strm_sym = drm_fixp_mul(temp, temp1);
 
-	/* stop txing train pattern to end link training */
-	dp_ctrl_clear_training_pattern(ctrl);
+	/* x_int */
+	x_int = drm_fixp2int(target_strm_sym);
+
+	/* y_enum_frac */
+	temp = drm_fixp_from_fraction(x_int, 1);
+	temp1 = target_strm_sym - temp;
+	temp2 = drm_fixp_from_fraction(256, 1);
+	y_frac_enum_fixp = drm_fixp_mul(temp1, temp2);
+
+	temp1 = drm_fixp2int(y_frac_enum_fixp);
+	temp2 = drm_fixp2int_ceil(y_frac_enum_fixp);
+
+	y_frac_enum = (u32)((temp1 == temp2) ? temp1 : temp1 + 1);
+
+	*p_x_int = x_int;
+	*p_y_frac_enum = y_frac_enum;
+
+	drm_dbg_dp(ctrl->drm_dev, "mst lane_cnt:%llu, rate:%llu x_int:%d, y_frac:%d\n",
+		   lanes, lclk, x_int, y_frac_enum);
+}
+
+static void msm_dp_ctrl_mst_stream_setup(struct msm_dp_ctrl_private *ctrl,
+					 struct msm_dp_panel *panel,
+					 u32 max_streams)
+{
+	u32 x_int, y_frac_enum;
+
+	drm_dbg_dp(ctrl->drm_dev, "mst stream channel allocation\n");
+
+	msm_dp_ctrl_mst_stream_channel_slot_setup(&ctrl->msm_dp_ctrl, max_streams);
+
+	msm_dp_ctrl_mst_calculate_rg(ctrl, panel, &x_int, &y_frac_enum);
+
+	msm_dp_catalog_ctrl_update_rg(ctrl->catalog, panel->stream_id,
+				      x_int, y_frac_enum);
+}
+
+int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl,
+			  struct msm_dp_panel *msm_dp_panel, u32 max_streams)
+{
+	int ret = 0;
+	bool mainlink_ready = false;
+	struct msm_dp_ctrl_private *ctrl;
+	unsigned long pixel_rate;
+	unsigned long pixel_rate_orig;
+
+	if (!msm_dp_ctrl)
+		return -EINVAL;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	pixel_rate = pixel_rate_orig = msm_dp_panel->msm_dp_mode.drm_mode.clock;
+
+	if (msm_dp_ctrl->wide_bus_en || msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420)
+		pixel_rate >>= 1;
+
+	drm_dbg_dp(ctrl->drm_dev, "pixel_rate=%lu\n", pixel_rate);
+
+	ret = msm_dp_ctrl_stream_clk_on(ctrl, pixel_rate, msm_dp_panel->stream_id);
+	if (ret) {
+		DRM_ERROR("failed to enable stream pixel clk\n");
+		return ret;
+	}
 
 	/*
 	 * Set up transfer unit values and set controller state to send
@@ -1908,60 +2200,73 @@
 	 */
 	reinit_completion(&ctrl->video_comp);
 
-	dp_ctrl_configure_source_params(ctrl);
+	msm_dp_ctrl_configure_source_params(ctrl, msm_dp_panel);
 
-	dp_catalog_ctrl_config_msa(ctrl->catalog,
+	msm_dp_catalog_ctrl_config_msa(ctrl->catalog,
 		ctrl->link->link_params.rate,
-		pixel_rate_orig, dp_ctrl_use_fixed_nvid(ctrl));
+		pixel_rate_orig,
+		msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420);
+
+	if (!ctrl->mst_active)
+		msm_dp_ctrl_setup_tr_unit(ctrl);
 
-	dp_ctrl_setup_tr_unit(ctrl);
+	if (ctrl->mst_active)
+		msm_dp_ctrl_mst_stream_setup(ctrl, msm_dp_panel, max_streams);
 
-	dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
+	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
 
-	ret = dp_ctrl_wait4video_ready(ctrl);
+	if (ctrl->mst_active)
+		msm_dp_ctrl_mst_send_act(msm_dp_ctrl);
+
+	ret = msm_dp_ctrl_wait4video_ready(ctrl);
 	if (ret)
 		return ret;
 
-	mainlink_ready = dp_catalog_ctrl_mainlink_ready(ctrl->catalog);
+	mainlink_ready = msm_dp_catalog_ctrl_mainlink_ready(ctrl->catalog);
 	drm_dbg_dp(ctrl->drm_dev,
 		"mainlink %s\n", mainlink_ready ? "READY" : "NOT READY");
 
-end:
 	return ret;
 }
 
-int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl)
+void msm_dp_ctrl_stream_clk_off(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *msm_dp_panel)
 {
-	struct dp_ctrl_private *ctrl;
-	struct dp_io *dp_io;
-	struct phy *phy;
-	int ret;
+	struct msm_dp_ctrl_private *ctrl;
 
-	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
-	dp_io = &ctrl->parser->io;
-	phy = dp_io->phy;
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 
-	/* set dongle to D3 (power off) mode */
-	dp_link_psm_config(ctrl->link, &ctrl->panel->link_info, true);
+	if (ctrl->stream_clks_on[msm_dp_panel->stream_id]) {
+		clk_disable_unprepare(ctrl->pixel_clk[msm_dp_panel->stream_id]);
+		ctrl->stream_clks_on[msm_dp_panel->stream_id] = false;
+	}
+}
 
-	dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
+void msm_dp_ctrl_clear_vsc_sdp_pkt(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *dp_panel)
+{
+	struct msm_dp_ctrl_private *ctrl;
 
-	if (dp_power_clk_status(ctrl->power, DP_STREAM_PM)) {
-		ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, false);
-		if (ret) {
-			DRM_ERROR("Failed to disable pclk. ret=%d\n", ret);
-			return ret;
-		}
-	}
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	ctrl->catalog->stream_id = dp_panel->stream_id;
+	msm_dp_catalog_panel_disable_vsc_sdp(ctrl->catalog);
+}
 
-	dev_pm_opp_set_rate(ctrl->dev, 0);
-	ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
-	if (ret) {
-		DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret);
-		return ret;
-	}
+void msm_dp_ctrl_psm_config(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
 
-	phy_power_off(phy);
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	/* set dongle to D3 (power off) mode */
+	msm_dp_link_psm_config(ctrl->link, &ctrl->panel->link_info, true);
+}
+
+void msm_dp_ctrl_reinit_phy(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	struct phy *phy;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	phy = ctrl->phy;
 
 	/* aux channel down, reinit phy */
 	phy_exit(phy);
@@ -1969,86 +2274,78 @@
 
 	drm_dbg_dp(ctrl->drm_dev, "phy=%p init=%d power_on=%d\n",
 			phy, phy->init_count, phy->power_count);
-	return ret;
 }
 
-int dp_ctrl_off_link(struct dp_ctrl *dp_ctrl)
+void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl)
 {
-	struct dp_ctrl_private *ctrl;
-	struct dp_io *dp_io;
+	struct msm_dp_ctrl_private *ctrl;
 	struct phy *phy;
-	int ret;
 
-	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
-	dp_io = &ctrl->parser->io;
-	phy = dp_io->phy;
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	phy = ctrl->phy;
 
-	dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
+	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
+	msm_dp_catalog_mst_config(ctrl->catalog, false);
 
-	ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
-	if (ret) {
-		DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret);
-	}
+	ctrl->mst_active = false;
 
-	DRM_DEBUG_DP("Before, phy=%p init_count=%d power_on=%d\n",
-		phy, phy->init_count, phy->power_count);
+	dev_pm_opp_set_rate(ctrl->dev, 0);
+	msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
 
-	phy_power_off(phy);
+	drm_dbg_dp(ctrl->drm_dev, "Before, phy=%p init_count=%d power_on=%d\n",
+		   phy, phy->init_count, phy->power_count);
 
-	DRM_DEBUG_DP("After, phy=%p init_count=%d power_on=%d\n",
-		phy, phy->init_count, phy->power_count);
+	phy_power_off(phy);
 
-	return ret;
+	drm_dbg_dp(ctrl->drm_dev, "After, phy=%p init_count=%d power_on=%d\n",
+		   phy, phy->init_count, phy->power_count);
 }
 
-int dp_ctrl_off(struct dp_ctrl *dp_ctrl)
+void msm_dp_ctrl_set_mst_channel_info(struct msm_dp_ctrl *msm_dp_ctrl,
+				      enum msm_dp_stream_id strm,
+				      u32 start_slot, u32 tot_slots)
 {
-	struct dp_ctrl_private *ctrl;
-	struct dp_io *dp_io;
-	struct phy *phy;
-	int ret = 0;
+	struct msm_dp_ctrl_private *ctrl;
 
-	if (!dp_ctrl)
-		return -EINVAL;
+	if (!msm_dp_ctrl || strm >= DP_STREAM_MAX) {
+		DRM_ERROR("invalid input\n");
+		return;
+	}
 
-	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
-	dp_io = &ctrl->parser->io;
-	phy = dp_io->phy;
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 
-	dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
+	ctrl->mst_ch_info[strm].start_slot = start_slot;
+	ctrl->mst_ch_info[strm].tot_slots = tot_slots;
+}
 
-	dp_catalog_ctrl_reset(ctrl->catalog);
+// TO-DO : Check if we can do a dealloc instead of this one during teardown
+void msm_dp_ctrl_mst_stream_channel_slot_setup(struct msm_dp_ctrl *msm_dp_ctrl, u32 max_streams)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	int i;
 
-	ret = dp_power_clk_enable(ctrl->power, DP_STREAM_PM, false);
-	if (ret)
-		DRM_ERROR("Failed to disable pixel clocks. ret=%d\n", ret);
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 
-	dev_pm_opp_set_rate(ctrl->dev, 0);
-	ret = dp_power_clk_enable(ctrl->power, DP_CTRL_PM, false);
-	if (ret) {
-		DRM_ERROR("Failed to disable link clocks. ret=%d\n", ret);
+	for (i = DP_STREAM_0; i < max_streams; i++) {
+		msm_dp_catalog_mst_channel_alloc(ctrl->catalog,
+						 i, ctrl->mst_ch_info[i].start_slot,
+						 ctrl->mst_ch_info[i].tot_slots);
 	}
-
-	phy_power_off(phy);
-	drm_dbg_dp(ctrl->drm_dev, "phy=%p init=%d power_on=%d\n",
-			phy, phy->init_count, phy->power_count);
-
-	return ret;
 }
 
-irqreturn_t dp_ctrl_isr(struct dp_ctrl *dp_ctrl)
+irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl)
 {
-	struct dp_ctrl_private *ctrl;
+	struct msm_dp_ctrl_private *ctrl;
 	u32 isr;
 	irqreturn_t ret = IRQ_NONE;
 
-	if (!dp_ctrl)
+	if (!msm_dp_ctrl)
 		return IRQ_NONE;
 
-	ctrl = container_of(dp_ctrl, struct dp_ctrl_private, dp_ctrl);
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
 
 	if (ctrl->panel->psr_cap.version) {
-		isr = dp_catalog_ctrl_read_psr_interrupt_status(ctrl->catalog);
+		isr = msm_dp_catalog_ctrl_read_psr_interrupt_status(ctrl->catalog);
 
 		if (isr)
 			complete(&ctrl->psr_op_comp);
@@ -2063,7 +2360,7 @@
 			drm_dbg_dp(ctrl->drm_dev, "PSR frame capture done\n");
 	}
 
-	isr = dp_catalog_ctrl_get_interrupt(ctrl->catalog);
+	isr = msm_dp_catalog_ctrl_get_interrupt(ctrl->catalog);
 
 
 	if (isr & DP_CTRL_INTR_READY_FOR_VIDEO) {
@@ -2078,15 +2375,84 @@
 		ret = IRQ_HANDLED;
 	}
 
+	isr = msm_dp_catalog_ctrl_get_interrupt_5(ctrl->catalog);
+	if (isr & (DP_INTR_DP0_VCPF_SENT | DP_INTR_DP1_VCPF_SENT)) {
+		drm_dbg_dp(ctrl->drm_dev, "vcpf sent\n");
+		complete(&ctrl->idle_comp);
+		ret = IRQ_HANDLED;
+	}
+
 	return ret;
 }
 
-struct dp_ctrl *dp_ctrl_get(struct device *dev, struct dp_link *link,
-			struct dp_panel *panel,	struct drm_dp_aux *aux,
-			struct dp_power *power, struct dp_catalog *catalog,
-			struct dp_parser *parser)
+static const char *core_clks[] = {
+	"core_iface",
+	"core_aux",
+};
+
+static const char *ctrl_clks[] = {
+	"ctrl_link",
+	"ctrl_link_iface",
+};
+
+static int msm_dp_ctrl_clk_init(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	struct device *dev;
+	int i, rc;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	dev = ctrl->dev;
+
+	ctrl->num_core_clks = ARRAY_SIZE(core_clks);
+	ctrl->core_clks = devm_kcalloc(dev, ctrl->num_core_clks, sizeof(*ctrl->core_clks), GFP_KERNEL);
+	if (!ctrl->core_clks)
+		return -ENOMEM;
+
+	for (i = 0; i < ctrl->num_core_clks; i++)
+		ctrl->core_clks[i].id = core_clks[i];
+
+	rc = devm_clk_bulk_get(dev, ctrl->num_core_clks, ctrl->core_clks);
+	if (rc)
+		return rc;
+
+	ctrl->num_link_clks = ARRAY_SIZE(ctrl_clks);
+	ctrl->link_clks = devm_kcalloc(dev, ctrl->num_link_clks, sizeof(*ctrl->link_clks), GFP_KERNEL);
+	if (!ctrl->link_clks)
+		return -ENOMEM;
+
+	for (i = 0; i < ctrl->num_link_clks; i++)
+		ctrl->link_clks[i].id = ctrl_clks[i];
+
+	rc = devm_clk_bulk_get(dev, ctrl->num_link_clks, ctrl->link_clks);
+	if (rc)
+		return rc;
+
+	ctrl->pixel_clk[DP_STREAM_0] = devm_clk_get(dev, "stream_pixel");
+	if (IS_ERR(ctrl->pixel_clk[DP_STREAM_0]))
+		return PTR_ERR(ctrl->pixel_clk[DP_STREAM_0]);
+
+	ctrl->pixel_clk[DP_STREAM_1] = devm_clk_get(dev, "stream_1_pixel");
+	if (IS_ERR(ctrl->pixel_clk[DP_STREAM_1]))
+		DRM_DEBUG("failed to get stream_pixel_1 clock");
+
+	ctrl->pixel_clk[DP_STREAM_2] = devm_clk_get(dev, "stream_2_pixel");
+	if (IS_ERR(ctrl->pixel_clk[DP_STREAM_2]))
+		DRM_DEBUG("failed to get stream_2_pixel clock");
+
+	ctrl->pixel_clk[DP_STREAM_3] = devm_clk_get(dev, "stream_3_pixel");
+	if (IS_ERR(ctrl->pixel_clk[DP_STREAM_3]))
+		DRM_DEBUG("failed to get stream_3_clock clock");
+
+	return 0;
+}
+
+struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link,
+			struct msm_dp_panel *panel,	struct drm_dp_aux *aux,
+			struct msm_dp_catalog *catalog,
+			struct phy *phy)
 {
-	struct dp_ctrl_private *ctrl;
+	struct msm_dp_ctrl_private *ctrl;
 	int ret;
 
 	if (!dev || !panel || !aux ||
@@ -2105,7 +2471,7 @@
 	if (ret) {
 		dev_err(dev, "invalid DP OPP table in device tree\n");
 		/* caller do PTR_ERR(opp_table) */
-		return (struct dp_ctrl *)ERR_PTR(ret);
+		return (struct msm_dp_ctrl *)ERR_PTR(ret);
 	}
 
 	/* OPP table is optional */
@@ -2118,13 +2484,19 @@
 	init_completion(&ctrl->video_comp);
 
 	/* in parameters */
-	ctrl->parser   = parser;
 	ctrl->panel    = panel;
-	ctrl->power    = power;
 	ctrl->aux      = aux;
 	ctrl->link     = link;
 	ctrl->catalog  = catalog;
 	ctrl->dev      = dev;
+	ctrl->phy      = phy;
+	ctrl->mst_active = false;
+
+	ret = msm_dp_ctrl_clk_init(&ctrl->msm_dp_ctrl);
+	if (ret) {
+		dev_err(dev, "failed to init clocks\n");
+		return ERR_PTR(ret);
+	}
 
-	return &ctrl->dp_ctrl;
+	return &ctrl->msm_dp_ctrl;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_ctrl.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_ctrl.h
@@ -9,34 +9,48 @@
 #include "dp_aux.h"
 #include "dp_panel.h"
 #include "dp_link.h"
-#include "dp_parser.h"
-#include "dp_power.h"
 #include "dp_catalog.h"
 
-struct dp_ctrl {
-	atomic_t aborted;
+struct msm_dp_ctrl {
 	bool wide_bus_en;
 };
 
-int dp_ctrl_on_link(struct dp_ctrl *dp_ctrl);
-int dp_ctrl_on_stream(struct dp_ctrl *dp_ctrl, bool force_link_train);
-int dp_ctrl_off_link_stream(struct dp_ctrl *dp_ctrl);
-int dp_ctrl_off_link(struct dp_ctrl *dp_ctrl);
-int dp_ctrl_off(struct dp_ctrl *dp_ctrl);
-void dp_ctrl_push_idle(struct dp_ctrl *dp_ctrl);
-irqreturn_t dp_ctrl_isr(struct dp_ctrl *dp_ctrl);
-void dp_ctrl_handle_sink_request(struct dp_ctrl *dp_ctrl);
-struct dp_ctrl *dp_ctrl_get(struct device *dev, struct dp_link *link,
-			struct dp_panel *panel,	struct drm_dp_aux *aux,
-			struct dp_power *power, struct dp_catalog *catalog,
-			struct dp_parser *parser);
-
-void dp_ctrl_reset_irq_ctrl(struct dp_ctrl *dp_ctrl, bool enable);
-void dp_ctrl_phy_init(struct dp_ctrl *dp_ctrl);
-void dp_ctrl_phy_exit(struct dp_ctrl *dp_ctrl);
-void dp_ctrl_irq_phy_exit(struct dp_ctrl *dp_ctrl);
+struct phy;
 
-void dp_ctrl_set_psr(struct dp_ctrl *dp_ctrl, bool enable);
-void dp_ctrl_config_psr(struct dp_ctrl *dp_ctrl);
+int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl, bool mst_active);
+int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl,
+			  struct msm_dp_panel *msm_dp_panel, u32 max_streams);
+int msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train);
+void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_stream_clk_off(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *msm_dp_panel);
+void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl);
+irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl);
+struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link,
+			struct msm_dp_panel *panel,	struct drm_dp_aux *aux,
+			struct msm_dp_catalog *catalog,
+			struct phy *phy);
 
+void msm_dp_ctrl_reset_irq_ctrl(struct msm_dp_ctrl *msm_dp_ctrl, bool enable);
+void msm_dp_ctrl_phy_init(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_irq_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);
+
+void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl, bool enable);
+void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl);
+
+int msm_dp_ctrl_core_clk_enable(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_core_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl);
+
+void msm_dp_ctrl_clear_vsc_sdp_pkt(struct msm_dp_ctrl *msm_dp_ctrl,
+		struct msm_dp_panel *msm_dp_panel);
+void msm_dp_ctrl_psm_config(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_reinit_phy(struct msm_dp_ctrl *msm_dp_ctrl);
+int msm_dp_ctrl_mst_send_act(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_mst_stream_channel_slot_setup(struct msm_dp_ctrl *msm_dp_ctrl, u32 max_streams);
+void msm_dp_ctrl_set_mst_channel_info(struct msm_dp_ctrl *msm_dp_ctrl,
+				      enum msm_dp_stream_id strm,
+				      u32 start_slot, u32 tot_slots);
+void msm_dp_ctrl_push_vcpf(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *msm_dp_panel);
 #endif /* _DP_CTRL_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_debug.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_debug.c
@@ -9,7 +9,6 @@
 #include <drm/drm_connector.h>
 #include <drm/drm_file.h>
 
-#include "dp_parser.h"
 #include "dp_catalog.h"
 #include "dp_aux.h"
 #include "dp_ctrl.h"
@@ -18,17 +17,15 @@
 
 #define DEBUG_NAME "msm_dp"
 
-struct dp_debug_private {
-	struct dp_link *link;
-	struct dp_panel *panel;
+struct msm_dp_debug_private {
+	struct msm_dp_link *link;
+	struct msm_dp_panel *panel;
 	struct drm_connector *connector;
-
-	struct dp_debug dp_debug;
 };
 
-static int dp_debug_show(struct seq_file *seq, void *p)
+static int msm_dp_debug_show(struct seq_file *seq, void *p)
 {
-	struct dp_debug_private *debug = seq->private;
+	struct msm_dp_debug_private *debug = seq->private;
 	u64 lclk = 0;
 	u32 link_params_rate;
 	const struct drm_display_mode *drm_mode;
@@ -36,7 +33,7 @@
 	if (!debug)
 		return -ENODEV;
 
-	drm_mode = &debug->panel->dp_mode.drm_mode;
+	drm_mode = &debug->panel->msm_dp_mode.drm_mode;
 
 	seq_printf(seq, "\tname = %s\n", DEBUG_NAME);
 	seq_printf(seq, "\tdrm_dp_link\n\t\trate = %u\n",
@@ -58,8 +55,8 @@
 			drm_mode->hsync_end - drm_mode->hsync_start,
 			drm_mode->vsync_end - drm_mode->vsync_start);
 	seq_printf(seq, "\t\tactive_low = %dx%d\n",
-			debug->panel->dp_mode.h_active_low,
-			debug->panel->dp_mode.v_active_low);
+			debug->panel->msm_dp_mode.h_active_low,
+			debug->panel->msm_dp_mode.v_active_low);
 	seq_printf(seq, "\t\th_skew = %d\n",
 			drm_mode->hskew);
 	seq_printf(seq, "\t\trefresh rate = %d\n",
@@ -67,7 +64,7 @@
 	seq_printf(seq, "\t\tpixel clock khz = %d\n",
 			drm_mode->clock);
 	seq_printf(seq, "\t\tbpp = %d\n",
-			debug->panel->dp_mode.bpp);
+			debug->panel->msm_dp_mode.bpp);
 
 	/* Link Information */
 	seq_printf(seq, "\tdp_link:\n\t\ttest_requested = %d\n",
@@ -86,11 +83,11 @@
 
 	return 0;
 }
-DEFINE_SHOW_ATTRIBUTE(dp_debug);
+DEFINE_SHOW_ATTRIBUTE(msm_dp_debug);
 
-static int dp_test_data_show(struct seq_file *m, void *data)
+static int msm_dp_test_data_show(struct seq_file *m, void *data)
 {
-	const struct dp_debug_private *debug = m->private;
+	const struct msm_dp_debug_private *debug = m->private;
 	const struct drm_connector *connector = debug->connector;
 	u32 bpc;
 
@@ -101,18 +98,18 @@
 		seq_printf(m, "vdisplay: %d\n",
 				debug->link->test_video.test_v_height);
 		seq_printf(m, "bpc: %u\n",
-				dp_link_bit_depth_to_bpc(bpc));
+				msm_dp_link_bit_depth_to_bpp(bpc) / 3);
 	} else {
 		seq_puts(m, "0");
 	}
 
 	return 0;
 }
-DEFINE_SHOW_ATTRIBUTE(dp_test_data);
+DEFINE_SHOW_ATTRIBUTE(msm_dp_test_data);
 
-static int dp_test_type_show(struct seq_file *m, void *data)
+static int msm_dp_test_type_show(struct seq_file *m, void *data)
 {
-	const struct dp_debug_private *debug = m->private;
+	const struct msm_dp_debug_private *debug = m->private;
 	const struct drm_connector *connector = debug->connector;
 
 	if (connector->status == connector_status_connected)
@@ -122,15 +119,15 @@
 
 	return 0;
 }
-DEFINE_SHOW_ATTRIBUTE(dp_test_type);
+DEFINE_SHOW_ATTRIBUTE(msm_dp_test_type);
 
-static ssize_t dp_test_active_write(struct file *file,
+static ssize_t msm_dp_test_active_write(struct file *file,
 		const char __user *ubuf,
 		size_t len, loff_t *offp)
 {
 	char *input_buffer;
 	int status = 0;
-	const struct dp_debug_private *debug;
+	const struct msm_dp_debug_private *debug;
 	const struct drm_connector *connector;
 	int val = 0;
 
@@ -167,9 +164,9 @@
 	return len;
 }
 
-static int dp_test_active_show(struct seq_file *m, void *data)
+static int msm_dp_test_active_show(struct seq_file *m, void *data)
 {
-	struct dp_debug_private *debug = m->private;
+	struct msm_dp_debug_private *debug = m->private;
 	struct drm_connector *connector = debug->connector;
 
 	if (connector->status == connector_status_connected) {
@@ -184,78 +181,57 @@
 	return 0;
 }
 
-static int dp_test_active_open(struct inode *inode,
+static int msm_dp_test_active_open(struct inode *inode,
 		struct file *file)
 {
-	return single_open(file, dp_test_active_show,
+	return single_open(file, msm_dp_test_active_show,
 			inode->i_private);
 }
 
 static const struct file_operations test_active_fops = {
 	.owner = THIS_MODULE,
-	.open = dp_test_active_open,
+	.open = msm_dp_test_active_open,
 	.read = seq_read,
 	.llseek = seq_lseek,
 	.release = single_release,
-	.write = dp_test_active_write
+	.write = msm_dp_test_active_write
 };
 
-static void dp_debug_init(struct dp_debug *dp_debug, struct dentry *root, bool is_edp)
+int msm_dp_debug_init(struct device *dev, struct msm_dp_panel *panel,
+		  struct msm_dp_link *link,
+		  struct drm_connector *connector,
+		  struct dentry *root, bool is_edp)
 {
-	struct dp_debug_private *debug = container_of(dp_debug,
-			struct dp_debug_private, dp_debug);
+	struct msm_dp_debug_private *debug;
+
+	if (!dev || !panel || !link) {
+		DRM_ERROR("invalid input\n");
+		return -EINVAL;
+	}
+
+	debug = devm_kzalloc(dev, sizeof(*debug), GFP_KERNEL);
+	if (!debug)
+		return -ENOMEM;
+
+	debug->link = link;
+	debug->panel = panel;
 
 	debugfs_create_file("dp_debug", 0444, root,
-			debug, &dp_debug_fops);
+			debug, &msm_dp_debug_fops);
 
 	if (!is_edp) {
-		debugfs_create_file("msm_dp_test_active", 0444,
+		debugfs_create_file("dp_test_active", 0444,
 				    root,
 				    debug, &test_active_fops);
 
-		debugfs_create_file("msm_dp_test_data", 0444,
+		debugfs_create_file("dp_test_data", 0444,
 				    root,
-				    debug, &dp_test_data_fops);
+				    debug, &msm_dp_test_data_fops);
 
-		debugfs_create_file("msm_dp_test_type", 0444,
+		debugfs_create_file("dp_test_type", 0444,
 				    root,
-				    debug, &dp_test_type_fops);
-	}
-}
-
-struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,
-		struct dp_link *link,
-		struct drm_connector *connector,
-		struct dentry *root, bool is_edp)
-{
-	struct dp_debug_private *debug;
-	struct dp_debug *dp_debug;
-	int rc;
-
-	if (!dev || !panel || !link) {
-		DRM_ERROR("invalid input\n");
-		rc = -EINVAL;
-		goto error;
-	}
-
-	debug = devm_kzalloc(dev, sizeof(*debug), GFP_KERNEL);
-	if (!debug) {
-		rc = -ENOMEM;
-		goto error;
+				    debug, &msm_dp_test_type_fops);
 	}
 
-	debug->dp_debug.debug_en = false;
-	debug->link = link;
-	debug->panel = panel;
-
-	dp_debug = &debug->dp_debug;
-	dp_debug->vdisplay = 0;
-	dp_debug->hdisplay = 0;
-	dp_debug->vrefresh = 0;
-
-	dp_debug_init(dp_debug, root, is_edp);
-
-	return dp_debug;
- error:
-	return ERR_PTR(rc);
+	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_debug.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_debug.h
@@ -9,26 +9,10 @@
 #include "dp_panel.h"
 #include "dp_link.h"
 
-/**
- * struct dp_debug
- * @debug_en: specifies whether debug mode enabled
- * @vdisplay: used to filter out vdisplay value
- * @hdisplay: used to filter out hdisplay value
- * @vrefresh: used to filter out vrefresh value
- * @tpg_state: specifies whether tpg feature is enabled
- */
-struct dp_debug {
-	bool debug_en;
-	int aspect_ratio;
-	int vdisplay;
-	int hdisplay;
-	int vrefresh;
-};
-
 #if defined(CONFIG_DEBUG_FS)
 
 /**
- * dp_debug_get() - configure and get the DisplayPlot debug module data
+ * msm_dp_debug_get() - configure and get the DisplayPlot debug module data
  *
  * @dev: device instance of the caller
  * @panel: instance of panel module
@@ -41,22 +25,22 @@
  * This function sets up the debug module and provides a way
  * for debugfs input to be communicated with existing modules
  */
-struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,
-		struct dp_link *link,
-		struct drm_connector *connector,
-		struct dentry *root,
-		bool is_edp);
+int msm_dp_debug_init(struct device *dev, struct msm_dp_panel *panel,
+		  struct msm_dp_link *link,
+		  struct drm_connector *connector,
+		  struct dentry *root,
+		  bool is_edp);
 
 #else
 
 static inline
-struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel,
-		struct dp_link *link,
-		struct drm_connector *connector,
-		struct dentry *root,
-		bool is_edp)
+int msm_dp_debug_init(struct device *dev, struct msm_dp_panel *panel,
+		  struct msm_dp_link *link,
+		  struct drm_connector *connector,
+		  struct dentry *root,
+		  bool is_edp)
 {
-	return ERR_PTR(-EINVAL);
+	return -EINVAL;
 }
 
 #endif /* defined(CONFIG_DEBUG_FS) */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_display.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_display.c
@@ -9,23 +9,23 @@
 #include <linux/debugfs.h>
 #include <linux/component.h>
 #include <linux/of_irq.h>
+#include <linux/phy/phy.h>
 #include <linux/delay.h>
 #include <drm/display/drm_dp_aux_bus.h>
 
 #include "msm_drv.h"
 #include "msm_kms.h"
-#include "dp_parser.h"
-#include "dp_power.h"
+#include "dp_ctrl.h"
 #include "dp_catalog.h"
 #include "dp_aux.h"
 #include "dp_reg.h"
 #include "dp_link.h"
 #include "dp_panel.h"
-#include "dp_ctrl.h"
 #include "dp_display.h"
 #include "dp_drm.h"
 #include "dp_audio.h"
 #include "dp_debug.h"
+#include "dp_mst_drm.h"
 
 static bool psr_enabled = false;
 module_param(psr_enabled, bool, 0);
@@ -33,6 +33,8 @@
 
 #define HPD_STRING_SIZE 30
 
+#define DEFAULT_STREAM_COUNT 1
+
 enum {
 	ISR_DISCONNECTED,
 	ISR_CONNECT_PENDING,
@@ -67,14 +69,15 @@
 
 #define WAIT_FOR_RESUME_TIMEOUT_JIFFIES (HZ / 2)
 
-struct dp_event {
+#define MAX_DPCD_TRANSACTION_BYTES 16
+
+struct msm_dp_event {
 	u32 event_id;
 	u32 data;
 	u32 delay;
 };
 
-struct dp_display_private {
-	char *name;
+struct msm_dp_display_private {
 	int irq;
 
 	unsigned int id;
@@ -82,27 +85,23 @@
 	/* state variables */
 	bool core_initialized;
 	bool phy_initialized;
-	bool hpd_irq_on;
 	bool audio_supported;
 
 	struct drm_device *drm_dev;
-	struct dentry *root;
 
-	struct dp_parser  *parser;
-	struct dp_power   *power;
-	struct dp_catalog *catalog;
+	struct msm_dp_catalog *catalog;
 	struct drm_dp_aux *aux;
-	struct dp_link    *link;
-	struct dp_panel   *panel;
-	struct dp_ctrl    *ctrl;
-	struct dp_debug   *debug;
+	struct msm_dp_link    *link;
+	struct msm_dp_panel   *panel;
+	struct msm_dp_ctrl    *ctrl;
 
-	struct dp_display_mode dp_mode;
-	struct msm_dp dp_display;
+	struct msm_dp msm_dp_display;
 
 	/* wait for audio signaling */
 	struct completion audio_comp;
 
+	unsigned int max_stream;
+
 	/* event related only access by event thread */
 	struct mutex event_mutex;
 	wait_queue_head_t event_q;
@@ -110,132 +109,188 @@
 	u32 event_pndx;
 	u32 event_gndx;
 	struct task_struct *ev_tsk;
-	struct dp_event event_list[DP_EVENT_Q_MAX];
+	struct msm_dp_event event_list[DP_EVENT_Q_MAX];
 	spinlock_t event_lock;
 
-	bool wide_bus_en;
+	bool wide_bus_supported;
 
-	struct dp_audio *audio;
+	u32 active_stream_cnt;
+
+	const unsigned int *intf_map;
+
+	struct msm_dp_audio *audio;
 };
 
 struct msm_dp_desc {
 	phys_addr_t io_start;
 	unsigned int id;
-	unsigned int connector_type;
-	bool wide_bus_en;
+	bool wide_bus_supported;
+	const unsigned int *intf_map;
+	unsigned int max_streams;
+};
+
+/* to be kept in sync with enum dpu_intf of dpu_hw_mdss.h */
+enum dp_mst_intf {
+	INTF_0 = 1,
+	INTF_1,
+	INTF_2,
+	INTF_3,
+	INTF_4,
+	INTF_5,
+	INTF_6,
+	INTF_7,
+	INTF_8,
+	INTF_MAX
+};
+
+static const unsigned int stream_intf_map_qcs8300[][DP_STREAM_MAX] = {
+	{INTF_0, INTF_3, INTF_6, INTF_7},
+	{}
+};
+
+static const unsigned int stream_intf_map_sa_8775p[][DP_STREAM_MAX] = {
+	{INTF_0, INTF_3},
+	{INTF_4, INTF_8},
+	{}
+};
+
+static const struct msm_dp_desc msm_dp_desc_qcs8300[] = {
+	{ .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true,
+	  .max_streams = 4, .intf_map = stream_intf_map_qcs8300[MSM_DP_CONTROLLER_0],
+	},
+	{}
 };
 
-static const struct msm_dp_desc sc7180_dp_descs[] = {
-	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
+static const struct msm_dp_desc msm_dp_desc_sa8775p[] = {
+	{ .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true,
+	  .max_streams = 2, .intf_map = stream_intf_map_sa_8775p[MSM_DP_CONTROLLER_0],
+	},
+	{ .io_start = 0x0af5c000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true,
+	  .max_streams = 2, .intf_map = stream_intf_map_sa_8775p[MSM_DP_CONTROLLER_1],
+	},
+	{ .io_start = 0x22154000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },
+	{ .io_start = 0x2215c000, .id = MSM_DP_CONTROLLER_3, .wide_bus_supported = true },
 	{}
 };
 
-static const struct msm_dp_desc sc7280_dp_descs[] = {
-	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
-	{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
+static const struct msm_dp_desc msm_dp_desc_sc7180[] = {
+	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
 	{}
 };
 
-static const struct msm_dp_desc sc8180x_dp_descs[] = {
-	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
-	{ .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
-	{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_eDP },
+static const struct msm_dp_desc msm_dp_desc_sc7280[] = {
+	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
 	{}
 };
 
-static const struct msm_dp_desc sc8280xp_dp_descs[] = {
-	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
-	{ .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
-	{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
-	{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
-	{ .io_start = 0x22090000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
-	{ .io_start = 0x22098000, .id = MSM_DP_CONTROLLER_1, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
-	{ .io_start = 0x2209a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
-	{ .io_start = 0x220a0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_DisplayPort, .wide_bus_en = true },
+static const struct msm_dp_desc msm_dp_desc_sc8180x[] = {
+	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{ .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
+	{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },
 	{}
 };
 
-static const struct msm_dp_desc sc8280xp_edp_descs[] = {
-	{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
-	{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
-	{ .io_start = 0x2209a000, .id = MSM_DP_CONTROLLER_2, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
-	{ .io_start = 0x220a0000, .id = MSM_DP_CONTROLLER_3, .connector_type = DRM_MODE_CONNECTOR_eDP, .wide_bus_en = true },
+static const struct msm_dp_desc msm_dp_desc_sc8280xp[] = {
+	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{ .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
+	{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },
+	{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .wide_bus_supported = true },
+	{ .io_start = 0x22090000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{ .io_start = 0x22098000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
+	{ .io_start = 0x2209a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },
+	{ .io_start = 0x220a0000, .id = MSM_DP_CONTROLLER_3, .wide_bus_supported = true },
 	{}
 };
 
-static const struct msm_dp_desc sm8350_dp_descs[] = {
-	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
+static const struct msm_dp_desc msm_dp_desc_sm8650[] = {
+	{ .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
 	{}
 };
 
-static const struct msm_dp_desc sm8650_dp_descs[] = {
-	{ .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
+static const struct msm_dp_desc msm_dp_desc_x1e80100[] = {
+	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{ .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
+	{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },
+	{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .wide_bus_supported = true },
 	{}
 };
 
-static const struct of_device_id dp_dt_match[] = {
-	{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
-	{ .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
-	{ .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_descs },
-	{ .compatible = "qcom,sc8180x-dp", .data = &sc8180x_dp_descs },
-	{ .compatible = "qcom,sc8180x-edp", .data = &sc8180x_dp_descs },
-	{ .compatible = "qcom,sc8280xp-dp", .data = &sc8280xp_dp_descs },
-	{ .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_edp_descs },
-	{ .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs },
-	{ .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_descs },
-	{ .compatible = "qcom,sm8650-dp", .data = &sm8650_dp_descs },
+static const struct of_device_id msm_dp_dt_match[] = {
+	{ .compatible = "qcom,qcs8300-dp", .data = &msm_dp_desc_qcs8300 },
+	{ .compatible = "qcom,sa8775p-dp", .data = &msm_dp_desc_sa8775p },
+	{ .compatible = "qcom,sc7180-dp", .data = &msm_dp_desc_sc7180 },
+	{ .compatible = "qcom,sc7280-dp", .data = &msm_dp_desc_sc7280 },
+	{ .compatible = "qcom,sc7280-edp", .data = &msm_dp_desc_sc7280 },
+	{ .compatible = "qcom,sc8180x-dp", .data = &msm_dp_desc_sc8180x },
+	{ .compatible = "qcom,sc8180x-edp", .data = &msm_dp_desc_sc8180x },
+	{ .compatible = "qcom,sc8280xp-dp", .data = &msm_dp_desc_sc8280xp },
+	{ .compatible = "qcom,sc8280xp-edp", .data = &msm_dp_desc_sc8280xp },
+	{ .compatible = "qcom,sdm845-dp", .data = &msm_dp_desc_sc7180 },
+	{ .compatible = "qcom,sm8350-dp", .data = &msm_dp_desc_sc7180 },
+	{ .compatible = "qcom,sm8650-dp", .data = &msm_dp_desc_sm8650 },
+	{ .compatible = "qcom,x1e80100-dp", .data = &msm_dp_desc_x1e80100 },
 	{}
 };
 
-static struct dp_display_private *dev_get_dp_display_private(struct device *dev)
+int msm_dp_display_get_active_stream_cnt(struct msm_dp *msm_dp)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(msm_dp, struct msm_dp_display_private, msm_dp_display);
+
+	return msm_dp_display->active_stream_cnt;
+}
+
+static struct msm_dp_display_private *dev_get_dp_display_private(struct device *dev)
 {
 	struct msm_dp *dp = dev_get_drvdata(dev);
 
-	return container_of(dp, struct dp_display_private, dp_display);
+	return container_of(dp, struct msm_dp_display_private, msm_dp_display);
 }
 
-static int dp_add_event(struct dp_display_private *dp_priv, u32 event,
+static int msm_dp_add_event(struct msm_dp_display_private *msm_dp_priv, u32 event,
 						u32 data, u32 delay)
 {
 	unsigned long flag;
-	struct dp_event *todo;
+	struct msm_dp_event *todo;
 	int pndx;
 
-	spin_lock_irqsave(&dp_priv->event_lock, flag);
-	pndx = dp_priv->event_pndx + 1;
+	spin_lock_irqsave(&msm_dp_priv->event_lock, flag);
+	pndx = msm_dp_priv->event_pndx + 1;
 	pndx %= DP_EVENT_Q_MAX;
-	if (pndx == dp_priv->event_gndx) {
+	if (pndx == msm_dp_priv->event_gndx) {
 		pr_err("event_q is full: pndx=%d gndx=%d\n",
-			dp_priv->event_pndx, dp_priv->event_gndx);
-		spin_unlock_irqrestore(&dp_priv->event_lock, flag);
+			msm_dp_priv->event_pndx, msm_dp_priv->event_gndx);
+		spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
 		return -EPERM;
 	}
-	todo = &dp_priv->event_list[dp_priv->event_pndx++];
-	dp_priv->event_pndx %= DP_EVENT_Q_MAX;
+	todo = &msm_dp_priv->event_list[msm_dp_priv->event_pndx++];
+	msm_dp_priv->event_pndx %= DP_EVENT_Q_MAX;
 	todo->event_id = event;
 	todo->data = data;
 	todo->delay = delay;
-	wake_up(&dp_priv->event_q);
-	spin_unlock_irqrestore(&dp_priv->event_lock, flag);
+	wake_up(&msm_dp_priv->event_q);
+	spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
 
 	return 0;
 }
 
-static int dp_del_event(struct dp_display_private *dp_priv, u32 event)
+static int msm_dp_del_event(struct msm_dp_display_private *msm_dp_priv, u32 event)
 {
 	unsigned long flag;
-	struct dp_event *todo;
+	struct msm_dp_event *todo;
 	u32	gndx;
 
-	spin_lock_irqsave(&dp_priv->event_lock, flag);
-	if (dp_priv->event_pndx == dp_priv->event_gndx) {
-		spin_unlock_irqrestore(&dp_priv->event_lock, flag);
+	spin_lock_irqsave(&msm_dp_priv->event_lock, flag);
+	if (msm_dp_priv->event_pndx == msm_dp_priv->event_gndx) {
+		spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
 		return -ENOENT;
 	}
 
-	gndx = dp_priv->event_gndx;
-	while (dp_priv->event_pndx != gndx) {
-		todo = &dp_priv->event_list[gndx];
+	gndx = msm_dp_priv->event_gndx;
+	while (msm_dp_priv->event_pndx != gndx) {
+		todo = &msm_dp_priv->event_list[gndx];
 		if (todo->event_id == event) {
 			todo->event_id = EV_NO_EVENT;	/* deleted */
 			todo->delay = 0;
@@ -243,60 +298,60 @@
 		gndx++;
 		gndx %= DP_EVENT_Q_MAX;
 	}
-	spin_unlock_irqrestore(&dp_priv->event_lock, flag);
+	spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
 
 	return 0;
 }
 
-void dp_display_signal_audio_start(struct msm_dp *dp_display)
+void msm_dp_display_signal_audio_start(struct msm_dp *msm_dp_display)
 {
-	struct dp_display_private *dp;
+	struct msm_dp_display_private *dp;
 
-	dp = container_of(dp_display, struct dp_display_private, dp_display);
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
 
 	reinit_completion(&dp->audio_comp);
 }
 
-void dp_display_signal_audio_complete(struct msm_dp *dp_display)
+void msm_dp_display_signal_audio_complete(struct msm_dp *msm_dp_display)
 {
-	struct dp_display_private *dp;
+	struct msm_dp_display_private *dp;
 
-	dp = container_of(dp_display, struct dp_display_private, dp_display);
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
 
 	complete_all(&dp->audio_comp);
 }
 
-static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv);
+static int msm_dp_hpd_event_thread_start(struct msm_dp_display_private *msm_dp_priv);
 
-static int dp_display_bind(struct device *dev, struct device *master,
+static int msm_dp_display_bind(struct device *dev, struct device *master,
 			   void *data)
 {
 	int rc = 0;
-	struct dp_display_private *dp = dev_get_dp_display_private(dev);
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
 	struct msm_drm_private *priv = dev_get_drvdata(master);
 	struct drm_device *drm = priv->dev;
 
-	dp->dp_display.drm_dev = drm;
-	priv->dp[dp->id] = &dp->dp_display;
+	dp->msm_dp_display.drm_dev = drm;
+	priv->dp[dp->id] = &dp->msm_dp_display;
 
 
 
 	dp->drm_dev = drm;
 	dp->aux->drm_dev = drm;
-	rc = dp_aux_register(dp->aux);
+	rc = msm_dp_aux_register(dp->aux);
 	if (rc) {
 		DRM_ERROR("DRM DP AUX register failed\n");
 		goto end;
 	}
 
 
-	rc = dp_register_audio_driver(dev, dp->audio);
+	rc = msm_dp_register_audio_driver(dev, dp->audio);
 	if (rc) {
 		DRM_ERROR("Audio registration Dp failed\n");
 		goto end;
 	}
 
-	rc = dp_hpd_event_thread_start(dp);
+	rc = msm_dp_hpd_event_thread_start(dp);
 	if (rc) {
 		DRM_ERROR("Event thread create failed\n");
 		goto end;
@@ -307,44 +362,44 @@
 	return rc;
 }
 
-static void dp_display_unbind(struct device *dev, struct device *master,
+static void msm_dp_display_unbind(struct device *dev, struct device *master,
 			      void *data)
 {
-	struct dp_display_private *dp = dev_get_dp_display_private(dev);
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
 	struct msm_drm_private *priv = dev_get_drvdata(master);
 
 	kthread_stop(dp->ev_tsk);
 
 	of_dp_aux_depopulate_bus(dp->aux);
 
-	dp_unregister_audio_driver(dev, dp->audio);
-	dp_aux_unregister(dp->aux);
+	msm_dp_unregister_audio_driver(dev, dp->audio);
+	msm_dp_aux_unregister(dp->aux);
 	dp->drm_dev = NULL;
 	dp->aux->drm_dev = NULL;
 	priv->dp[dp->id] = NULL;
 }
 
-static const struct component_ops dp_display_comp_ops = {
-	.bind = dp_display_bind,
-	.unbind = dp_display_unbind,
+static const struct component_ops msm_dp_display_comp_ops = {
+	.bind = msm_dp_display_bind,
+	.unbind = msm_dp_display_unbind,
 };
 
-static void dp_display_send_hpd_event(struct msm_dp *dp_display)
+static void msm_dp_display_send_hpd_event(struct msm_dp *msm_dp_display)
 {
-	struct dp_display_private *dp;
+	struct msm_dp_display_private *dp;
 	struct drm_connector *connector;
 
-	dp = container_of(dp_display, struct dp_display_private, dp_display);
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
 
-	connector = dp->dp_display.connector;
+	connector = dp->msm_dp_display.connector;
 	drm_helper_hpd_irq_event(connector->dev);
 }
 
-static int dp_display_send_hpd_notification(struct dp_display_private *dp,
+static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *dp,
 					    bool hpd)
 {
-	if ((hpd && dp->dp_display.link_ready) ||
-			(!hpd && !dp->dp_display.link_ready)) {
+	if ((hpd && dp->msm_dp_display.link_ready) ||
+			(!hpd && !dp->msm_dp_display.link_ready)) {
 		drm_dbg_dp(dp->drm_dev, "HPD already %s\n",
 				(hpd ? "on" : "off"));
 		return 0;
@@ -353,148 +408,197 @@
 	/* reset video pattern flag on disconnect */
 	if (!hpd) {
 		dp->panel->video_test = false;
-		if (!dp->dp_display.is_edp)
-			drm_dp_set_subconnector_property(dp->dp_display.connector,
+		if (!dp->msm_dp_display.is_edp)
+			drm_dp_set_subconnector_property(dp->msm_dp_display.connector,
 							 connector_status_disconnected,
 							 dp->panel->dpcd,
 							 dp->panel->downstream_ports);
 	}
 
-	dp->dp_display.link_ready = hpd;
+	dp->msm_dp_display.link_ready = hpd;
 
 	drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n",
-			dp->dp_display.connector_type, hpd);
-	dp_display_send_hpd_event(&dp->dp_display);
+			dp->msm_dp_display.connector_type, hpd);
+	msm_dp_display_send_hpd_event(&dp->msm_dp_display);
 
 	return 0;
 }
 
-static int dp_display_process_hpd_high(struct dp_display_private *dp)
+static void msm_dp_display_mst_init(struct msm_dp_display_private *dp)
 {
-	int rc = 0;
-	struct edid *edid;
+	const unsigned long clear_mstm_ctrl_timeout_us = 100000;
+	u8 old_mstm_ctrl;
+	struct msm_dp *msm_dp = &dp->msm_dp_display;
+	int ret;
+
+	/* clear sink mst state */
+	drm_dp_dpcd_readb(dp->aux, DP_MSTM_CTRL, &old_mstm_ctrl);
+	drm_dp_dpcd_writeb(dp->aux, DP_MSTM_CTRL, 0);
+
+	/* add extra delay if MST state is not cleared */
+	if (old_mstm_ctrl) {
+		drm_dbg_dp(dp->drm_dev, "MSTM_CTRL is not cleared, wait %luus\n",
+			   clear_mstm_ctrl_timeout_us);
+		usleep_range(clear_mstm_ctrl_timeout_us,
+			     clear_mstm_ctrl_timeout_us + 1000);
+	}
+
+	ret = drm_dp_dpcd_writeb(dp->aux, DP_MSTM_CTRL,
+				 DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC);
+	if (ret < 0) {
+		DRM_ERROR("sink mst enablement failed\n");
+		return;
+	}
 
-	dp->panel->max_dp_lanes = dp->parser->max_dp_lanes;
-	dp->panel->max_dp_link_rate = dp->parser->max_dp_link_rate;
+	msm_dp->mst_active = true;
+}
 
-	drm_dbg_dp(dp->drm_dev, "max_lanes=%d max_link_rate=%d\n",
-		dp->panel->max_dp_lanes, dp->panel->max_dp_link_rate);
+static void msm_dp_display_set_mst_mgr_state(struct msm_dp_display_private *dp,
+					     bool state)
+{
+	if (!dp->msm_dp_display.mst_active)
+		return;
 
-	rc = dp_panel_read_sink_caps(dp->panel, dp->dp_display.connector);
+	msm_dp_mst_display_set_mgr_state(&dp->msm_dp_display, state);
+
+	drm_dbg_dp(dp->drm_dev, "mst_mgr_state: %d\n", state);
+}
+
+static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
+{
+	struct drm_connector *connector = dp->msm_dp_display.connector;
+	const struct drm_display_info *info = &connector->display_info;
+	int rc = 0;
+	struct msm_dp *dp_display = &dp->msm_dp_display;
+
+	rc = msm_dp_panel_read_link_caps(dp->panel, connector);
 	if (rc)
 		goto end;
 
-	dp_link_process_request(dp->link);
+	if (dp->max_stream <= DEFAULT_STREAM_COUNT || !msm_dp_panel_read_mst_cap(dp->panel)) {
+		rc = msm_dp_panel_read_edid(dp->panel, connector);
+		if (rc)
+			goto end;
+	}
+
+	msm_dp_link_process_request(dp->link);
 
-	if (!dp->dp_display.is_edp)
-		drm_dp_set_subconnector_property(dp->dp_display.connector,
+	if (!dp->msm_dp_display.is_edp)
+		drm_dp_set_subconnector_property(connector,
 						 connector_status_connected,
 						 dp->panel->dpcd,
 						 dp->panel->downstream_ports);
 
-	edid = dp->panel->edid;
+	dp->msm_dp_display.psr_supported = dp->panel->psr_cap.version && psr_enabled;
 
-	dp->dp_display.psr_supported = dp->panel->psr_cap.version && psr_enabled;
-
-	dp->audio_supported = drm_detect_monitor_audio(edid);
-	dp_panel_handle_sink_request(dp->panel);
-
-	dp->dp_display.max_dp_lanes = dp->parser->max_dp_lanes;
+	dp->audio_supported = info->has_audio;
+	msm_dp_panel_handle_sink_request(dp->panel);
 
 	/*
 	 * set sink to normal operation mode -- D0
 	 * before dpcd read
 	 */
-	dp_link_psm_config(dp->link, &dp->panel->link_info, false);
+	msm_dp_link_psm_config(dp->link, &dp->panel->link_info, false);
 
-	dp_link_reset_phy_params_vx_px(dp->link);
-	rc = dp_ctrl_on_link(dp->ctrl);
+	if (dp->max_stream > DEFAULT_STREAM_COUNT && msm_dp_panel_read_mst_cap(dp->panel))
+		msm_dp_display_mst_init(dp);
+
+	msm_dp_link_reset_phy_params_vx_px(dp->link);
+	rc = msm_dp_ctrl_on_link(dp->ctrl, dp_display->mst_active);
 	if (rc) {
 		DRM_ERROR("failed to complete DP link training\n");
 		goto end;
 	}
 
-	dp_add_event(dp, EV_USER_NOTIFICATION, true, 0);
+	msm_dp_display_set_mst_mgr_state(dp, true);
+
+	msm_dp_add_event(dp, EV_USER_NOTIFICATION, true, 0);
 
 end:
 	return rc;
 }
 
-static void dp_display_host_phy_init(struct dp_display_private *dp)
+static void msm_dp_display_host_phy_init(struct msm_dp_display_private *dp)
 {
 	drm_dbg_dp(dp->drm_dev, "type=%d core_init=%d phy_init=%d\n",
-		dp->dp_display.connector_type, dp->core_initialized,
+		dp->msm_dp_display.connector_type, dp->core_initialized,
 		dp->phy_initialized);
 
 	if (!dp->phy_initialized) {
-		dp_ctrl_phy_init(dp->ctrl);
+		msm_dp_ctrl_phy_init(dp->ctrl);
 		dp->phy_initialized = true;
 	}
 }
 
-static void dp_display_host_phy_exit(struct dp_display_private *dp)
+static void msm_dp_display_host_phy_exit(struct msm_dp_display_private *dp)
 {
 	drm_dbg_dp(dp->drm_dev, "type=%d core_init=%d phy_init=%d\n",
-		dp->dp_display.connector_type, dp->core_initialized,
+		dp->msm_dp_display.connector_type, dp->core_initialized,
 		dp->phy_initialized);
 
 	if (dp->phy_initialized) {
-		dp_ctrl_phy_exit(dp->ctrl);
+		msm_dp_ctrl_phy_exit(dp->ctrl);
 		dp->phy_initialized = false;
 	}
 }
 
-static void dp_display_host_init(struct dp_display_private *dp)
+static void msm_dp_display_host_init(struct msm_dp_display_private *dp)
 {
 	drm_dbg_dp(dp->drm_dev, "type=%d core_init=%d phy_init=%d\n",
-		dp->dp_display.connector_type, dp->core_initialized,
+		dp->msm_dp_display.connector_type, dp->core_initialized,
 		dp->phy_initialized);
 
-	dp_power_init(dp->power);
-	dp_ctrl_reset_irq_ctrl(dp->ctrl, true);
-	dp_aux_init(dp->aux);
+	msm_dp_ctrl_core_clk_enable(dp->ctrl);
+	msm_dp_ctrl_reset_irq_ctrl(dp->ctrl, true);
+	msm_dp_aux_init(dp->aux);
 	dp->core_initialized = true;
 }
 
-static void dp_display_host_deinit(struct dp_display_private *dp)
+static void msm_dp_display_host_deinit(struct msm_dp_display_private *dp)
 {
 	drm_dbg_dp(dp->drm_dev, "type=%d core_init=%d phy_init=%d\n",
-		dp->dp_display.connector_type, dp->core_initialized,
+		dp->msm_dp_display.connector_type, dp->core_initialized,
 		dp->phy_initialized);
 
-	dp_ctrl_reset_irq_ctrl(dp->ctrl, false);
-	dp_aux_deinit(dp->aux);
-	dp_power_deinit(dp->power);
+	msm_dp_ctrl_reset_irq_ctrl(dp->ctrl, false);
+	msm_dp_aux_deinit(dp->aux);
+	msm_dp_ctrl_core_clk_disable(dp->ctrl);
 	dp->core_initialized = false;
 }
 
-static int dp_display_usbpd_configure_cb(struct device *dev)
+static int msm_dp_display_usbpd_configure_cb(struct device *dev)
 {
-	struct dp_display_private *dp = dev_get_dp_display_private(dev);
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
 
-	dp_display_host_phy_init(dp);
+	msm_dp_display_host_phy_init(dp);
 
-	return dp_display_process_hpd_high(dp);
+	return msm_dp_display_process_hpd_high(dp);
 }
 
-static int dp_display_notify_disconnect(struct device *dev)
+static int msm_dp_display_notify_disconnect(struct device *dev)
 {
-	struct dp_display_private *dp = dev_get_dp_display_private(dev);
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
+	struct msm_dp *dp_display = &dp->msm_dp_display;
 
-	dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);
+	if (dp_display->mst_active) {
+		msm_dp_mst_display_set_mgr_state(&dp->msm_dp_display, false);
+		dp_display->mst_active = false;
+	}
+
+	msm_dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);
 
 	return 0;
 }
 
-static void dp_display_handle_video_request(struct dp_display_private *dp)
+static void msm_dp_display_handle_video_request(struct msm_dp_display_private *dp)
 {
 	if (dp->link->sink_request & DP_TEST_LINK_VIDEO_PATTERN) {
 		dp->panel->video_test = true;
-		dp_link_send_test_response(dp->link);
+		msm_dp_link_send_test_response(dp->link);
 	}
 }
 
-static int dp_display_handle_port_ststus_changed(struct dp_display_private *dp)
+static int msm_dp_display_handle_port_status_changed(struct msm_dp_display_private *dp)
 {
 	int rc = 0;
 
@@ -502,12 +606,12 @@
 		drm_dbg_dp(dp->drm_dev, "sink count is zero, nothing to do\n");
 		if (dp->hpd_state != ST_DISCONNECTED) {
 			dp->hpd_state = ST_DISCONNECT_PENDING;
-			dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);
+			msm_dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);
 		}
 	} else {
 		if (dp->hpd_state == ST_DISCONNECTED) {
 			dp->hpd_state = ST_MAINLINK_READY;
-			rc = dp_display_process_hpd_high(dp);
+			rc = msm_dp_display_process_hpd_high(dp);
 			if (rc)
 				dp->hpd_state = ST_DISCONNECTED;
 		}
@@ -516,7 +620,7 @@
 	return rc;
 }
 
-static int dp_display_handle_irq_hpd(struct dp_display_private *dp)
+static int msm_dp_display_handle_irq_hpd(struct msm_dp_display_private *dp)
 {
 	u32 sink_request = dp->link->sink_request;
 
@@ -530,46 +634,52 @@
 		}
 	}
 
-	dp_ctrl_handle_sink_request(dp->ctrl);
+	msm_dp_ctrl_handle_sink_request(dp->ctrl);
 
 	if (sink_request & DP_TEST_LINK_VIDEO_PATTERN)
-		dp_display_handle_video_request(dp);
+		msm_dp_display_handle_video_request(dp);
 
 	return 0;
 }
 
-static int dp_display_usbpd_attention_cb(struct device *dev)
+static int msm_dp_display_usbpd_attention_cb(struct device *dev)
 {
 	int rc = 0;
 	u32 sink_request;
-	struct dp_display_private *dp = dev_get_dp_display_private(dev);
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
+	struct msm_dp *msm_dp_display = &dp->msm_dp_display;
 
 	/* check for any test request issued by sink */
-	rc = dp_link_process_request(dp->link);
+	rc = msm_dp_link_process_request(dp->link);
 	if (!rc) {
 		sink_request = dp->link->sink_request;
 		drm_dbg_dp(dp->drm_dev, "hpd_state=%d sink_request=%d\n",
 					dp->hpd_state, sink_request);
-		if (sink_request & DS_PORT_STATUS_CHANGED)
-			rc = dp_display_handle_port_ststus_changed(dp);
-		else
-			rc = dp_display_handle_irq_hpd(dp);
+		if (sink_request & DS_PORT_STATUS_CHANGED) {
+			if (!msm_dp_display->mst_active)
+				rc = msm_dp_display_handle_port_status_changed(dp);
+		} else {
+			rc = msm_dp_display_handle_irq_hpd(dp);
+		}
 	}
 
+	msm_dp_mst_display_hpd_irq(&dp->msm_dp_display);
 	return rc;
 }
 
-static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)
+static int msm_dp_hpd_plug_handle(struct msm_dp_display_private *dp, u32 data)
 {
 	u32 state;
 	int ret;
-	struct platform_device *pdev = dp->dp_display.pdev;
+	struct platform_device *pdev = dp->msm_dp_display.pdev;
+
+	msm_dp_aux_enable_xfers(dp->aux, true);
 
 	mutex_lock(&dp->event_mutex);
 
 	state =  dp->hpd_state;
 	drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
-			dp->dp_display.connector_type, state);
+			dp->msm_dp_display.connector_type, state);
 
 	if (state == ST_DISPLAY_OFF) {
 		mutex_unlock(&dp->event_mutex);
@@ -583,7 +693,7 @@
 
 	if (state == ST_DISCONNECT_PENDING) {
 		/* wait until ST_DISCONNECTED */
-		dp_add_event(dp, EV_HPD_PLUG_INT, 0, 1); /* delay = 1 */
+		msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0, 1); /* delay = 1 */
 		mutex_unlock(&dp->event_mutex);
 		return 0;
 	}
@@ -595,66 +705,70 @@
 		return ret;
 	}
 
-	ret = dp_display_usbpd_configure_cb(&pdev->dev);
+	ret = msm_dp_display_usbpd_configure_cb(&pdev->dev);
 	if (ret) {	/* link train failed */
 		dp->hpd_state = ST_DISCONNECTED;
+		pm_runtime_put_sync(&pdev->dev);
 	} else {
 		dp->hpd_state = ST_MAINLINK_READY;
 	}
 
 	drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
-			dp->dp_display.connector_type, state);
+			dp->msm_dp_display.connector_type, state);
 	mutex_unlock(&dp->event_mutex);
 
 	/* uevent will complete connection part */
 	return 0;
 };
 
-static void dp_display_handle_plugged_change(struct msm_dp *dp_display,
+static void msm_dp_display_handle_plugged_change(struct msm_dp *msm_dp_display,
 		bool plugged)
 {
-	struct dp_display_private *dp;
+	struct msm_dp_display_private *dp;
 
-	dp = container_of(dp_display,
-			struct dp_display_private, dp_display);
+	dp = container_of(msm_dp_display,
+			struct msm_dp_display_private, msm_dp_display);
 
 	/* notify audio subsystem only if sink supports audio */
-	if (dp_display->plugged_cb && dp_display->codec_dev &&
+	if (msm_dp_display->plugged_cb && msm_dp_display->codec_dev &&
 			dp->audio_supported)
-		dp_display->plugged_cb(dp_display->codec_dev, plugged);
+		msm_dp_display->plugged_cb(msm_dp_display->codec_dev, plugged);
 }
 
-static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
+static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp, u32 data)
 {
 	u32 state;
-	struct platform_device *pdev = dp->dp_display.pdev;
+	struct platform_device *pdev = dp->msm_dp_display.pdev;
+
+	msm_dp_aux_enable_xfers(dp->aux, false);
 
 	mutex_lock(&dp->event_mutex);
 
 	state = dp->hpd_state;
 
 	drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
-			dp->dp_display.connector_type, state);
+			dp->msm_dp_display.connector_type, state);
 
 	/* unplugged, no more irq_hpd handle */
-	dp_del_event(dp, EV_IRQ_HPD_INT);
+	msm_dp_del_event(dp, EV_IRQ_HPD_INT);
 
 	if (state == ST_DISCONNECTED) {
 		/* triggered by irq_hdp with sink_count = 0 */
 		if (dp->link->sink_count == 0) {
-			dp_display_host_phy_exit(dp);
+			msm_dp_display_host_phy_exit(dp);
 		}
-		dp_display_notify_disconnect(&dp->dp_display.pdev->dev);
+		msm_dp_display_notify_disconnect(&dp->msm_dp_display.pdev->dev);
 		mutex_unlock(&dp->event_mutex);
 		return 0;
 	} else if (state == ST_DISCONNECT_PENDING) {
 		mutex_unlock(&dp->event_mutex);
 		return 0;
 	} else if (state == ST_MAINLINK_READY) {
-		dp_ctrl_off_link(dp->ctrl);
-		dp_display_host_phy_exit(dp);
+		msm_dp_ctrl_off_link(dp->ctrl);
+		msm_dp_display_host_phy_exit(dp);
 		dp->hpd_state = ST_DISCONNECTED;
-		dp_display_notify_disconnect(&dp->dp_display.pdev->dev);
+		msm_dp_display_notify_disconnect(&dp->msm_dp_display.pdev->dev);
+		pm_runtime_put_sync(&pdev->dev);
 		mutex_unlock(&dp->event_mutex);
 		return 0;
 	}
@@ -663,7 +777,7 @@
 	 * We don't need separate work for disconnect as
 	 * connect/attention interrupts are disabled
 	 */
-	dp_display_notify_disconnect(&dp->dp_display.pdev->dev);
+	msm_dp_display_notify_disconnect(&dp->msm_dp_display.pdev->dev);
 
 	if (state == ST_DISPLAY_OFF) {
 		dp->hpd_state = ST_DISCONNECTED;
@@ -672,10 +786,10 @@
 	}
 
 	/* signal the disconnect event early to ensure proper teardown */
-	dp_display_handle_plugged_change(&dp->dp_display, false);
+	msm_dp_display_handle_plugged_change(&dp->msm_dp_display, false);
 
 	drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
-			dp->dp_display.connector_type, state);
+			dp->msm_dp_display.connector_type, state);
 
 	/* uevent will complete disconnection part */
 	pm_runtime_put_sync(&pdev->dev);
@@ -683,7 +797,7 @@
 	return 0;
 }
 
-static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data)
+static int msm_dp_irq_hpd_handle(struct msm_dp_display_private *dp, u32 data)
 {
 	u32 state;
 
@@ -692,54 +806,91 @@
 	/* irq_hpd can happen at either connected or disconnected state */
 	state =  dp->hpd_state;
 	drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
-			dp->dp_display.connector_type, state);
+			dp->msm_dp_display.connector_type, state);
 
-	if (state == ST_DISPLAY_OFF) {
+	/* irq hpd to indicate monitor disconnect/connect can happen even
+	 * after stream is disabled not necessarily due to hotplug disconnect
+	 */
+	if (state == ST_DISPLAY_OFF && !dp->msm_dp_display.mst_active) {
 		mutex_unlock(&dp->event_mutex);
 		return 0;
 	}
 
-	if (state == ST_MAINLINK_READY || state == ST_DISCONNECT_PENDING) {
+	if ((state == ST_MAINLINK_READY || state == ST_DISCONNECT_PENDING) &&
+			!dp->msm_dp_display.mst_active) {
 		/* wait until ST_CONNECTED */
-		dp_add_event(dp, EV_IRQ_HPD_INT, 0, 1); /* delay = 1 */
+		msm_dp_add_event(dp, EV_IRQ_HPD_INT, 0, 1); /* delay = 1 */
 		mutex_unlock(&dp->event_mutex);
 		return 0;
 	}
 
-	dp_display_usbpd_attention_cb(&dp->dp_display.pdev->dev);
+	msm_dp_display_usbpd_attention_cb(&dp->msm_dp_display.pdev->dev);
 
 	drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
-			dp->dp_display.connector_type, state);
+			dp->msm_dp_display.connector_type, state);
 
 	mutex_unlock(&dp->event_mutex);
 
 	return 0;
 }
 
-static void dp_display_deinit_sub_modules(struct dp_display_private *dp)
+struct msm_dp_panel *msm_dp_display_get_panel(struct msm_dp *dp_display)
+{
+	struct msm_dp_display_private *dp;
+	struct msm_dp_panel *dp_panel;
+
+	struct msm_dp_panel_in panel_in;
+
+	dp = container_of(dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	panel_in.dev = &dp_display->pdev->dev;
+	panel_in.aux = dp->aux;
+	panel_in.catalog = dp->catalog;
+	panel_in.link = dp->link;
+
+	dp_panel = msm_dp_panel_get(&panel_in);
+
+	if (IS_ERR(dp->panel)) {
+		DRM_ERROR("failed to initialize panel\n");
+		return NULL;
+	}
+
+	memcpy(dp_panel->dpcd, dp->panel->dpcd, DP_RECEIVER_CAP_SIZE + 1);
+	memcpy(&dp_panel->link_info, &dp->panel->link_info,
+	       sizeof(dp->panel->link_info));
+
+	return dp_panel;
+}
+
+static void msm_dp_display_deinit_sub_modules(struct msm_dp_display_private *dp)
 {
-	dp_audio_put(dp->audio);
-	dp_panel_put(dp->panel);
-	dp_aux_put(dp->aux);
+	msm_dp_audio_put(dp->audio);
+	msm_dp_panel_put(dp->panel);
+	msm_dp_aux_put(dp->aux);
 }
 
-static int dp_init_sub_modules(struct dp_display_private *dp)
+static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp)
 {
 	int rc = 0;
-	struct device *dev = &dp->dp_display.pdev->dev;
-	struct dp_panel_in panel_in = {
+	struct device *dev = &dp->msm_dp_display.pdev->dev;
+	struct msm_dp_panel_in panel_in = {
 		.dev = dev,
 	};
+	struct phy *phy;
+
+	phy = devm_phy_get(dev, "dp");
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
 
-	dp->parser = dp_parser_get(dp->dp_display.pdev);
-	if (IS_ERR(dp->parser)) {
-		rc = PTR_ERR(dp->parser);
-		DRM_ERROR("failed to initialize parser, rc = %d\n", rc);
-		dp->parser = NULL;
+	rc = phy_set_mode_ext(phy, PHY_MODE_DP,
+			      dp->msm_dp_display.is_edp ? PHY_SUBMODE_EDP : PHY_SUBMODE_DP);
+	if (rc) {
+		DRM_ERROR("failed to set phy submode, rc = %d\n", rc);
+		dp->catalog = NULL;
 		goto error;
 	}
 
-	dp->catalog = dp_catalog_get(dev, &dp->parser->io);
+	dp->catalog = msm_dp_catalog_get(dev);
 	if (IS_ERR(dp->catalog)) {
 		rc = PTR_ERR(dp->catalog);
 		DRM_ERROR("failed to initialize catalog, rc = %d\n", rc);
@@ -747,15 +898,9 @@
 		goto error;
 	}
 
-	dp->power = dp_power_get(dev, dp->parser);
-	if (IS_ERR(dp->power)) {
-		rc = PTR_ERR(dp->power);
-		DRM_ERROR("failed to initialize power, rc = %d\n", rc);
-		dp->power = NULL;
-		goto error;
-	}
-
-	dp->aux = dp_aux_get(dev, dp->catalog, dp->dp_display.is_edp);
+	dp->aux = msm_dp_aux_get(dev, dp->catalog,
+			     phy,
+			     dp->msm_dp_display.is_edp);
 	if (IS_ERR(dp->aux)) {
 		rc = PTR_ERR(dp->aux);
 		DRM_ERROR("failed to initialize aux, rc = %d\n", rc);
@@ -763,7 +908,7 @@
 		goto error;
 	}
 
-	dp->link = dp_link_get(dev, dp->aux);
+	dp->link = msm_dp_link_get(dev, dp->aux);
 	if (IS_ERR(dp->link)) {
 		rc = PTR_ERR(dp->link);
 		DRM_ERROR("failed to initialize link, rc = %d\n", rc);
@@ -775,7 +920,7 @@
 	panel_in.catalog = dp->catalog;
 	panel_in.link = dp->link;
 
-	dp->panel = dp_panel_get(&panel_in);
+	dp->panel = msm_dp_panel_get(&panel_in);
 	if (IS_ERR(dp->panel)) {
 		rc = PTR_ERR(dp->panel);
 		DRM_ERROR("failed to initialize panel, rc = %d\n", rc);
@@ -783,8 +928,9 @@
 		goto error_link;
 	}
 
-	dp->ctrl = dp_ctrl_get(dev, dp->link, dp->panel, dp->aux,
-			       dp->power, dp->catalog, dp->parser);
+	dp->ctrl = msm_dp_ctrl_get(dev, dp->link, dp->panel, dp->aux,
+			       dp->catalog,
+			       phy);
 	if (IS_ERR(dp->ctrl)) {
 		rc = PTR_ERR(dp->ctrl);
 		DRM_ERROR("failed to initialize ctrl, rc = %d\n", rc);
@@ -792,7 +938,7 @@
 		goto error_ctrl;
 	}
 
-	dp->audio = dp_audio_get(dp->dp_display.pdev, dp->panel, dp->catalog);
+	dp->audio = msm_dp_audio_get(dp->msm_dp_display.pdev, dp->panel, dp->catalog);
 	if (IS_ERR(dp->audio)) {
 		rc = PTR_ERR(dp->audio);
 		pr_err("failed to initialize audio, rc = %d\n", rc);
@@ -800,58 +946,107 @@
 		goto error_ctrl;
 	}
 
-	/* populate wide_bus_en to differernt layers */
-	dp->ctrl->wide_bus_en = dp->wide_bus_en;
-	dp->catalog->wide_bus_en = dp->wide_bus_en;
-
 	return rc;
 
 error_ctrl:
-	dp_panel_put(dp->panel);
+	msm_dp_panel_put(dp->panel);
 error_link:
-	dp_aux_put(dp->aux);
+	msm_dp_aux_put(dp->aux);
 error:
 	return rc;
 }
 
-static int dp_display_set_mode(struct msm_dp *dp_display,
-			       struct dp_display_mode *mode)
+static int msm_dp_display_set_mode(struct msm_dp *msm_dp_display,
+				   const struct drm_display_mode *adjusted_mode,
+				   struct msm_dp_panel *msm_dp_panel)
 {
-	struct dp_display_private *dp;
+	struct msm_dp_display_mode msm_dp_mode;
+
+	memset(&msm_dp_mode, 0x0, sizeof(struct msm_dp_display_mode));
+
+	if (msm_dp_display_check_video_test(msm_dp_display))
+		msm_dp_mode.bpp = msm_dp_display_get_test_bpp(msm_dp_display);
+	else /* Default num_components per px = 3 */
+		msm_dp_mode.bpp = msm_dp_panel->connector->display_info.bpc * 3;
+
+	if (!msm_dp_mode.bpp)
+		msm_dp_mode.bpp = 24; /* Default bpp */
+
+	drm_mode_copy(&msm_dp_mode.drm_mode, adjusted_mode);
+
+	msm_dp_mode.v_active_low =
+		!!(msm_dp_mode.drm_mode.flags & DRM_MODE_FLAG_NVSYNC);
+
+	msm_dp_mode.h_active_low =
+		!!(msm_dp_mode.drm_mode.flags & DRM_MODE_FLAG_NHSYNC);
 
-	dp = container_of(dp_display, struct dp_display_private, dp_display);
+	msm_dp_mode.out_fmt_is_yuv_420 =
+		drm_mode_is_420_only(&msm_dp_display->connector->display_info, adjusted_mode) &&
+		msm_dp_panel->vsc_sdp_supported;
+
+	drm_mode_copy(&msm_dp_panel->msm_dp_mode.drm_mode, &msm_dp_mode.drm_mode);
+	msm_dp_panel->msm_dp_mode.bpp = msm_dp_mode.bpp;
+	msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420 = msm_dp_mode.out_fmt_is_yuv_420;
+	msm_dp_panel->msm_dp_mode.v_active_low = msm_dp_mode.v_active_low;
+	msm_dp_panel->msm_dp_mode.h_active_low = msm_dp_mode.h_active_low;
+	msm_dp_panel_init_panel_info(msm_dp_panel);
 
-	drm_mode_copy(&dp->panel->dp_mode.drm_mode, &mode->drm_mode);
-	dp->panel->dp_mode.bpp = mode->bpp;
-	dp->panel->dp_mode.capabilities = mode->capabilities;
-	dp_panel_init_panel_info(dp->panel);
 	return 0;
 }
 
-static int dp_display_enable(struct dp_display_private *dp, bool force_link_train)
+static int msm_dp_display_prepare(struct msm_dp_display_private *dp)
 {
 	int rc = 0;
-	struct msm_dp *dp_display = &dp->dp_display;
+	struct msm_dp *msm_dp_display = &dp->msm_dp_display;
+	bool force_link_train = false;
+	u32 state;
 
 	drm_dbg_dp(dp->drm_dev, "sink_count=%d\n", dp->link->sink_count);
-	if (dp_display->power_on) {
+	if (msm_dp_display->prepared) {
 		drm_dbg_dp(dp->drm_dev, "Link already setup, return\n");
 		return 0;
 	}
 
-	rc = dp_ctrl_on_stream(dp->ctrl, force_link_train);
+	state = dp->hpd_state;
+	if (state != ST_DISPLAY_OFF && state != ST_MAINLINK_READY)
+		return -EINVAL;
+
+	rc = pm_runtime_resume_and_get(&msm_dp_display->pdev->dev);
+	if (rc) {
+		DRM_ERROR("failed to pm_runtime_resume\n");
+		return rc;
+	}
+
+	if (dp->hpd_state == ST_DISPLAY_OFF) {
+		msm_dp_display_host_phy_init(dp);
+		force_link_train = true;
+	}
+
+	rc = msm_dp_ctrl_prepare_stream_on(dp->ctrl, force_link_train);
 	if (!rc)
-		dp_display->power_on = true;
+		msm_dp_display->prepared = true;
 
 	return rc;
 }
 
-static int dp_display_post_enable(struct msm_dp *dp_display)
+static int msm_dp_display_enable(struct msm_dp_display_private *dp,
+				 struct msm_dp_panel *msm_dp_panel)
 {
-	struct dp_display_private *dp;
+	int rc = 0;
+
+	drm_dbg_dp(dp->drm_dev, "sink_count=%d\n", dp->link->sink_count);
+
+	rc = msm_dp_ctrl_on_stream(dp->ctrl, msm_dp_panel, dp->max_stream);
+
+	return rc;
+}
+
+static int msm_dp_display_post_enable(struct msm_dp *msm_dp_display)
+{
+	struct msm_dp_display_private *dp;
 	u32 rate;
 
-	dp = container_of(dp_display, struct dp_display_private, dp_display);
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
 
 	rate = dp->link->link_params.rate;
 
@@ -861,86 +1056,112 @@
 	}
 
 	/* signal the connect event late to synchronize video and display */
-	dp_display_handle_plugged_change(dp_display, true);
+	msm_dp_display_handle_plugged_change(msm_dp_display, true);
 
-	if (dp_display->psr_supported)
-		dp_ctrl_config_psr(dp->ctrl);
+	if (msm_dp_display->psr_supported)
+		msm_dp_ctrl_config_psr(dp->ctrl);
 
 	return 0;
 }
 
-static int dp_display_disable(struct dp_display_private *dp)
+static void msm_dp_display_audio_notify_disable(struct msm_dp_display_private *dp)
 {
-	struct msm_dp *dp_display = &dp->dp_display;
-
-	if (!dp_display->power_on)
-		return 0;
+	struct msm_dp *msm_dp_display = &dp->msm_dp_display;
 
 	/* wait only if audio was enabled */
-	if (dp_display->audio_enabled) {
+	if (msm_dp_display->audio_enabled) {
 		/* signal the disconnect event */
-		dp_display_handle_plugged_change(dp_display, false);
+		msm_dp_display_handle_plugged_change(msm_dp_display, false);
 		if (!wait_for_completion_timeout(&dp->audio_comp,
 				HZ * 5))
 			DRM_ERROR("audio comp timeout\n");
 	}
 
-	dp_display->audio_enabled = false;
+	msm_dp_display->audio_enabled = false;
+}
 
-	if (dp->link->sink_count == 0) {
-		/*
-		 * irq_hpd with sink_count = 0
-		 * hdmi unplugged out of dongle
-		 */
-		dp_ctrl_off_link_stream(dp->ctrl);
-	} else {
-		/*
-		 * unplugged interrupt
-		 * dongle unplugged out of DUT
-		 */
-		dp_ctrl_off(dp->ctrl);
-		dp_display_host_phy_exit(dp);
-	}
+static int msm_dp_display_disable(struct msm_dp_display_private *dp,
+				  struct msm_dp_panel *msm_dp_panel)
+{
+	if (!dp->active_stream_cnt)
+		return 0;
 
-	dp_display->power_on = false;
+	msm_dp_ctrl_clear_vsc_sdp_pkt(dp->ctrl, msm_dp_panel);
+
+	msm_dp_ctrl_stream_clk_off(dp->ctrl, msm_dp_panel);
+
+	dp->active_stream_cnt--;
 
 	drm_dbg_dp(dp->drm_dev, "sink count: %d\n", dp->link->sink_count);
 	return 0;
 }
 
-int dp_display_set_plugged_cb(struct msm_dp *dp_display,
+int msm_dp_display_set_plugged_cb(struct msm_dp *msm_dp_display,
 		hdmi_codec_plugged_cb fn, struct device *codec_dev)
 {
 	bool plugged;
 
-	dp_display->plugged_cb = fn;
-	dp_display->codec_dev = codec_dev;
-	plugged = dp_display->link_ready;
-	dp_display_handle_plugged_change(dp_display, plugged);
+	msm_dp_display->plugged_cb = fn;
+	msm_dp_display->codec_dev = codec_dev;
+	plugged = msm_dp_display->link_ready;
+	msm_dp_display_handle_plugged_change(msm_dp_display, plugged);
+
+	return 0;
+}
+
+int msm_dp_display_set_stream_info(struct msm_dp *dp,
+				   struct msm_dp_panel *panel, u32 strm_id, u32 start_slot,
+				   u32 num_slots, u32 pbn, int vcpi)
+{
+	struct msm_dp_display_private *msm_dp_display;
+	const int max_slots = 64;
+
+
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+	if (!msm_dp_display) {
+		DRM_ERROR("invalid input\n");
+		return -EINVAL;
+	}
+
+	if (strm_id >= DP_STREAM_MAX) {
+		DRM_ERROR("invalid stream id:%d\n", strm_id);
+		return -EINVAL;
+	}
+
+	if (start_slot + num_slots > max_slots) {
+		DRM_ERROR("invalid channel info received. start:%d, slots:%d\n",
+			  start_slot, num_slots);
+		return -EINVAL;
+	}
+
+	msm_dp_ctrl_set_mst_channel_info(msm_dp_display->ctrl, strm_id, start_slot, num_slots);
+
+	if (panel) {
+		panel->stream_id = strm_id;
+		panel->mst_caps.pbn = pbn;
+	}
 
 	return 0;
 }
 
 /**
- * dp_bridge_mode_valid - callback to determine if specified mode is valid
- * @bridge: Pointer to drm bridge structure
+ * msm_dp_bridge_mode_valid - callback to determine if specified mode is valid
+ * @dp: Pointer to dp display structure
  * @info: display info
  * @mode: Pointer to drm mode structure
  * Returns: Validity status for specified mode
  */
-enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
-					  const struct drm_display_info *info,
-					  const struct drm_display_mode *mode)
+enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
+					       const struct drm_display_info *info,
+					       const struct drm_display_mode *mode)
 {
 	const u32 num_components = 3, default_bpp = 24;
-	struct dp_display_private *dp_display;
-	struct dp_link_info *link_info;
+	struct msm_dp_display_private *msm_dp_display;
+	struct msm_dp_link_info *link_info;
 	u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
-	struct msm_dp *dp;
 	int mode_pclk_khz = mode->clock;
 
-	dp = to_dp_bridge(bridge)->dp_display;
-
 	if (!dp || !mode_pclk_khz || !dp->connector) {
 		DRM_ERROR("invalid params\n");
 		return -EINVAL;
@@ -949,14 +1170,18 @@
 	if (mode->clock > DP_MAX_PIXEL_CLK_KHZ)
 		return MODE_CLOCK_HIGH;
 
-	dp_display = container_of(dp, struct dp_display_private, dp_display);
-	link_info = &dp_display->panel->link_info;
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+	link_info = &msm_dp_display->panel->link_info;
+
+	if (drm_mode_is_420_only(&dp->connector->display_info, mode) &&
+	    msm_dp_display->panel->vsc_sdp_supported)
+		mode_pclk_khz /= 2;
 
 	mode_bpp = dp->connector->display_info.bpc * num_components;
 	if (!mode_bpp)
 		mode_bpp = default_bpp;
 
-	mode_bpp = dp_panel_get_mode_bpp(dp_display->panel,
+	mode_bpp = msm_dp_panel_get_mode_bpp(msm_dp_display->panel,
 			mode_bpp, mode_pclk_khz);
 
 	mode_rate_khz = mode_pclk_khz * mode_bpp;
@@ -968,50 +1193,50 @@
 	return MODE_OK;
 }
 
-int dp_display_get_modes(struct msm_dp *dp)
+int msm_dp_display_get_modes(struct msm_dp *dp)
 {
-	struct dp_display_private *dp_display;
+	struct msm_dp_display_private *msm_dp_display;
 
 	if (!dp) {
 		DRM_ERROR("invalid params\n");
 		return 0;
 	}
 
-	dp_display = container_of(dp, struct dp_display_private, dp_display);
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
 
-	return dp_panel_get_modes(dp_display->panel,
+	return msm_dp_panel_get_modes(msm_dp_display->panel,
 		dp->connector);
 }
 
-bool dp_display_check_video_test(struct msm_dp *dp)
+bool msm_dp_display_check_video_test(struct msm_dp *dp)
 {
-	struct dp_display_private *dp_display;
+	struct msm_dp_display_private *msm_dp_display;
 
-	dp_display = container_of(dp, struct dp_display_private, dp_display);
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
 
-	return dp_display->panel->video_test;
+	return msm_dp_display->panel->video_test;
 }
 
-int dp_display_get_test_bpp(struct msm_dp *dp)
+int msm_dp_display_get_test_bpp(struct msm_dp *dp)
 {
-	struct dp_display_private *dp_display;
+	struct msm_dp_display_private *msm_dp_display;
 
 	if (!dp) {
 		DRM_ERROR("invalid params\n");
 		return 0;
 	}
 
-	dp_display = container_of(dp, struct dp_display_private, dp_display);
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
 
-	return dp_link_bit_depth_to_bpp(
-		dp_display->link->test_video.test_bit_depth);
+	return msm_dp_link_bit_depth_to_bpp(
+		msm_dp_display->link->test_video.test_bit_depth);
 }
 
 void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp)
 {
-	struct dp_display_private *dp_display;
+	struct msm_dp_display_private *msm_dp_display;
 
-	dp_display = container_of(dp, struct dp_display_private, dp_display);
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
 
 	/*
 	 * if we are reading registers we need the link clocks to be on
@@ -1020,65 +1245,65 @@
 	 * power_on status before dumping DP registers to avoid crash due
 	 * to unclocked access
 	 */
-	mutex_lock(&dp_display->event_mutex);
+	mutex_lock(&msm_dp_display->event_mutex);
 
-	if (!dp->power_on) {
-		mutex_unlock(&dp_display->event_mutex);
+	if (!msm_dp_display->active_stream_cnt) {
+		mutex_unlock(&msm_dp_display->event_mutex);
 		return;
 	}
 
-	dp_catalog_snapshot(dp_display->catalog, disp_state);
+	msm_dp_catalog_snapshot(msm_dp_display->catalog, disp_state);
 
-	mutex_unlock(&dp_display->event_mutex);
+	mutex_unlock(&msm_dp_display->event_mutex);
 }
 
-void dp_display_set_psr(struct msm_dp *dp_display, bool enter)
+void msm_dp_display_set_psr(struct msm_dp *msm_dp_display, bool enter)
 {
-	struct dp_display_private *dp;
+	struct msm_dp_display_private *dp;
 
-	if (!dp_display) {
+	if (!msm_dp_display) {
 		DRM_ERROR("invalid params\n");
 		return;
 	}
 
-	dp = container_of(dp_display, struct dp_display_private, dp_display);
-	dp_ctrl_set_psr(dp->ctrl, enter);
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+	msm_dp_ctrl_set_psr(dp->ctrl, enter);
 }
 
 static int hpd_event_thread(void *data)
 {
-	struct dp_display_private *dp_priv;
+	struct msm_dp_display_private *msm_dp_priv;
 	unsigned long flag;
-	struct dp_event *todo;
+	struct msm_dp_event *todo;
 	int timeout_mode = 0;
 
-	dp_priv = (struct dp_display_private *)data;
+	msm_dp_priv = (struct msm_dp_display_private *)data;
 
 	while (1) {
 		if (timeout_mode) {
-			wait_event_timeout(dp_priv->event_q,
-				(dp_priv->event_pndx == dp_priv->event_gndx) ||
+			wait_event_timeout(msm_dp_priv->event_q,
+				(msm_dp_priv->event_pndx == msm_dp_priv->event_gndx) ||
 					kthread_should_stop(), EVENT_TIMEOUT);
 		} else {
-			wait_event_interruptible(dp_priv->event_q,
-				(dp_priv->event_pndx != dp_priv->event_gndx) ||
+			wait_event_interruptible(msm_dp_priv->event_q,
+				(msm_dp_priv->event_pndx != msm_dp_priv->event_gndx) ||
 					kthread_should_stop());
 		}
 
 		if (kthread_should_stop())
 			break;
 
-		spin_lock_irqsave(&dp_priv->event_lock, flag);
-		todo = &dp_priv->event_list[dp_priv->event_gndx];
+		spin_lock_irqsave(&msm_dp_priv->event_lock, flag);
+		todo = &msm_dp_priv->event_list[msm_dp_priv->event_gndx];
 		if (todo->delay) {
-			struct dp_event *todo_next;
+			struct msm_dp_event *todo_next;
 
-			dp_priv->event_gndx++;
-			dp_priv->event_gndx %= DP_EVENT_Q_MAX;
+			msm_dp_priv->event_gndx++;
+			msm_dp_priv->event_gndx %= DP_EVENT_Q_MAX;
 
 			/* re enter delay event into q */
-			todo_next = &dp_priv->event_list[dp_priv->event_pndx++];
-			dp_priv->event_pndx %= DP_EVENT_Q_MAX;
+			todo_next = &msm_dp_priv->event_list[msm_dp_priv->event_pndx++];
+			msm_dp_priv->event_pndx %= DP_EVENT_Q_MAX;
 			todo_next->event_id = todo->event_id;
 			todo_next->data = todo->data;
 			todo_next->delay = todo->delay - 1;
@@ -1089,33 +1314,33 @@
 
 			/* switch to timeout mode */
 			timeout_mode = 1;
-			spin_unlock_irqrestore(&dp_priv->event_lock, flag);
+			spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
 			continue;
 		}
 
 		/* timeout with no events in q */
-		if (dp_priv->event_pndx == dp_priv->event_gndx) {
-			spin_unlock_irqrestore(&dp_priv->event_lock, flag);
+		if (msm_dp_priv->event_pndx == msm_dp_priv->event_gndx) {
+			spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
 			continue;
 		}
 
-		dp_priv->event_gndx++;
-		dp_priv->event_gndx %= DP_EVENT_Q_MAX;
+		msm_dp_priv->event_gndx++;
+		msm_dp_priv->event_gndx %= DP_EVENT_Q_MAX;
 		timeout_mode = 0;
-		spin_unlock_irqrestore(&dp_priv->event_lock, flag);
+		spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
 
 		switch (todo->event_id) {
 		case EV_HPD_PLUG_INT:
-			dp_hpd_plug_handle(dp_priv, todo->data);
+			msm_dp_hpd_plug_handle(msm_dp_priv, todo->data);
 			break;
 		case EV_HPD_UNPLUG_INT:
-			dp_hpd_unplug_handle(dp_priv, todo->data);
+			msm_dp_hpd_unplug_handle(msm_dp_priv, todo->data);
 			break;
 		case EV_IRQ_HPD_INT:
-			dp_irq_hpd_handle(dp_priv, todo->data);
+			msm_dp_irq_hpd_handle(msm_dp_priv, todo->data);
 			break;
 		case EV_USER_NOTIFICATION:
-			dp_display_send_hpd_notification(dp_priv,
+			msm_dp_display_send_hpd_notification(msm_dp_priv,
 						todo->data);
 			break;
 		default:
@@ -1126,22 +1351,22 @@
 	return 0;
 }
 
-static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv)
+static int msm_dp_hpd_event_thread_start(struct msm_dp_display_private *msm_dp_priv)
 {
 	/* set event q to empty */
-	dp_priv->event_gndx = 0;
-	dp_priv->event_pndx = 0;
+	msm_dp_priv->event_gndx = 0;
+	msm_dp_priv->event_pndx = 0;
 
-	dp_priv->ev_tsk = kthread_run(hpd_event_thread, dp_priv, "dp_hpd_handler");
-	if (IS_ERR(dp_priv->ev_tsk))
-		return PTR_ERR(dp_priv->ev_tsk);
+	msm_dp_priv->ev_tsk = kthread_run(hpd_event_thread, msm_dp_priv, "dp_hpd_handler");
+	if (IS_ERR(msm_dp_priv->ev_tsk))
+		return PTR_ERR(msm_dp_priv->ev_tsk);
 
 	return 0;
 }
 
-static irqreturn_t dp_display_irq_handler(int irq, void *dev_id)
+static irqreturn_t msm_dp_display_irq_handler(int irq, void *dev_id)
 {
-	struct dp_display_private *dp = dev_id;
+	struct msm_dp_display_private *dp = dev_id;
 	irqreturn_t ret = IRQ_NONE;
 	u32 hpd_isr_status;
 
@@ -1150,43 +1375,43 @@
 		return IRQ_NONE;
 	}
 
-	hpd_isr_status = dp_catalog_hpd_get_intr_status(dp->catalog);
+	hpd_isr_status = msm_dp_catalog_hpd_get_intr_status(dp->catalog);
 
 	if (hpd_isr_status & 0x0F) {
 		drm_dbg_dp(dp->drm_dev, "type=%d isr=0x%x\n",
-			dp->dp_display.connector_type, hpd_isr_status);
+			dp->msm_dp_display.connector_type, hpd_isr_status);
 		/* hpd related interrupts */
 		if (hpd_isr_status & DP_DP_HPD_PLUG_INT_MASK)
-			dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
+			msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
 
 		if (hpd_isr_status & DP_DP_IRQ_HPD_INT_MASK) {
-			dp_add_event(dp, EV_IRQ_HPD_INT, 0, 0);
+			msm_dp_add_event(dp, EV_IRQ_HPD_INT, 0, 0);
 		}
 
 		if (hpd_isr_status & DP_DP_HPD_REPLUG_INT_MASK) {
-			dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
-			dp_add_event(dp, EV_HPD_PLUG_INT, 0, 3);
+			msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
+			msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0, 3);
 		}
 
 		if (hpd_isr_status & DP_DP_HPD_UNPLUG_INT_MASK)
-			dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
+			msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
 
 		ret = IRQ_HANDLED;
 	}
 
 	/* DP controller isr */
-	ret |= dp_ctrl_isr(dp->ctrl);
+	ret |= msm_dp_ctrl_isr(dp->ctrl);
 
 	/* DP aux isr */
-	ret |= dp_aux_isr(dp->aux);
+	ret |= msm_dp_aux_isr(dp->aux);
 
 	return ret;
 }
 
-static int dp_display_request_irq(struct dp_display_private *dp)
+static int msm_dp_display_request_irq(struct msm_dp_display_private *dp)
 {
 	int rc = 0;
-	struct platform_device *pdev = dp->dp_display.pdev;
+	struct platform_device *pdev = dp->msm_dp_display.pdev;
 
 	dp->irq = platform_get_irq(pdev, 0);
 	if (dp->irq < 0) {
@@ -1194,7 +1419,7 @@
 		return dp->irq;
 	}
 
-	rc = devm_request_irq(&pdev->dev, dp->irq, dp_display_irq_handler,
+	rc = devm_request_irq(&pdev->dev, dp->irq, msm_dp_display_irq_handler,
 			      IRQF_TRIGGER_HIGH|IRQF_NO_AUTOEN,
 			      "dp_display_isr", dp);
 
@@ -1207,7 +1432,7 @@
 	return 0;
 }
 
-static const struct msm_dp_desc *dp_display_get_desc(struct platform_device *pdev)
+static const struct msm_dp_desc *msm_dp_display_get_desc(struct platform_device *pdev)
 {
 	const struct msm_dp_desc *descs = of_device_get_match_data(&pdev->dev);
 	struct resource *res;
@@ -1226,33 +1451,75 @@
 	return NULL;
 }
 
-static int dp_display_get_next_bridge(struct msm_dp *dp);
-
-static int dp_display_probe_tail(struct device *dev)
+static int msm_dp_display_probe_tail(struct device *dev)
 {
 	struct msm_dp *dp = dev_get_drvdata(dev);
 	int ret;
 
-	ret = dp_display_get_next_bridge(dp);
-	if (ret)
-		return ret;
+	/*
+	 * External bridges are mandatory for eDP interfaces: one has to
+	 * provide at least an eDP panel (which gets wrapped into panel-bridge).
+	 *
+	 * For DisplayPort interfaces external bridges are optional, so
+	 * silently ignore an error if one is not present (-ENODEV).
+	 */
+	dp->next_bridge = devm_drm_of_get_bridge(&dp->pdev->dev, dp->pdev->dev.of_node, 1, 0);
+	if (IS_ERR(dp->next_bridge)) {
+		ret = PTR_ERR(dp->next_bridge);
+		dp->next_bridge = NULL;
+		if (dp->is_edp || ret != -ENODEV)
+			return ret;
+	}
 
-	ret = component_add(dev, &dp_display_comp_ops);
+	ret = component_add(dev, &msm_dp_display_comp_ops);
 	if (ret)
 		DRM_ERROR("component add failed, rc=%d\n", ret);
 
 	return ret;
 }
 
-static int dp_auxbus_done_probe(struct drm_dp_aux *aux)
+static int msm_dp_auxbus_done_probe(struct drm_dp_aux *aux)
+{
+	return msm_dp_display_probe_tail(aux->dev);
+}
+
+static int msm_dp_display_get_connector_type(struct platform_device *pdev,
+					 const struct msm_dp_desc *desc)
 {
-	return dp_display_probe_tail(aux->dev);
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *aux_bus = of_get_child_by_name(node, "aux-bus");
+	struct device_node *panel = of_get_child_by_name(aux_bus, "panel");
+	int connector_type;
+
+	if (panel)
+		connector_type = DRM_MODE_CONNECTOR_eDP;
+	else
+		connector_type = DRM_MODE_SUBCONNECTOR_DisplayPort;
+
+	of_node_put(panel);
+	of_node_put(aux_bus);
+
+	return connector_type;
 }
 
-static int dp_display_probe(struct platform_device *pdev)
+int msm_dp_get_mst_max_stream(const struct msm_dp *dp_display)
+{
+	struct msm_dp_display_private *dp_priv;
+
+	dp_priv = container_of(dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	return dp_priv->max_stream;
+}
+
+int msm_dp_mst_bridge_init(struct msm_dp *dp_display, struct drm_encoder *encoder)
+{
+	return msm_dp_mst_drm_bridge_init(dp_display, encoder);
+}
+
+static int msm_dp_display_probe(struct platform_device *pdev)
 {
 	int rc = 0;
-	struct dp_display_private *dp;
+	struct msm_dp_display_private *dp;
 	const struct msm_dp_desc *desc;
 
 	if (!pdev || !pdev->dev.of_node) {
@@ -1264,34 +1531,26 @@
 	if (!dp)
 		return -ENOMEM;
 
-	desc = dp_display_get_desc(pdev);
+	desc = msm_dp_display_get_desc(pdev);
 	if (!desc)
 		return -EINVAL;
 
-	dp->dp_display.pdev = pdev;
-	dp->name = "drm_dp";
+	dp->msm_dp_display.pdev = pdev;
 	dp->id = desc->id;
-	dp->dp_display.connector_type = desc->connector_type;
-	dp->wide_bus_en = desc->wide_bus_en;
-	dp->dp_display.is_edp =
-		(dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP);
+	dp->msm_dp_display.connector_type = msm_dp_display_get_connector_type(pdev, desc);
+	dp->wide_bus_supported = desc->wide_bus_supported;
+	dp->msm_dp_display.is_edp =
+		(dp->msm_dp_display.connector_type == DRM_MODE_CONNECTOR_eDP);
 
-	rc = dp_init_sub_modules(dp);
-	if (rc) {
-		DRM_ERROR("init sub module failed\n");
-		return -EPROBE_DEFER;
-	}
+	dp->max_stream = (desc->max_streams > DEFAULT_STREAM_COUNT) ?
+			  desc->max_streams : DEFAULT_STREAM_COUNT;
 
-	rc = dp->parser->parse(dp->parser);
-	if (rc) {
-		DRM_ERROR("device tree parsing failed\n");
-		goto err;
-	}
+	dp->intf_map = desc->intf_map;
 
-	rc = dp_power_client_init(dp->power);
+	rc = msm_dp_init_sub_modules(dp);
 	if (rc) {
-		DRM_ERROR("Power client create failed\n");
-		goto err;
+		DRM_ERROR("init sub module failed\n");
+		return -EPROBE_DEFER;
 	}
 
 	/* setup event q */
@@ -1300,28 +1559,28 @@
 	spin_lock_init(&dp->event_lock);
 
 	/* Store DP audio handle inside DP display */
-	dp->dp_display.dp_audio = dp->audio;
+	dp->msm_dp_display.msm_dp_audio = dp->audio;
 
 	init_completion(&dp->audio_comp);
 
-	platform_set_drvdata(pdev, &dp->dp_display);
+	platform_set_drvdata(pdev, &dp->msm_dp_display);
 
 	rc = devm_pm_runtime_enable(&pdev->dev);
 	if (rc)
 		goto err;
 
-	rc = dp_display_request_irq(dp);
+	rc = msm_dp_display_request_irq(dp);
 	if (rc)
 		goto err;
 
-	if (dp->dp_display.is_edp) {
-		rc = devm_of_dp_aux_populate_bus(dp->aux, dp_auxbus_done_probe);
+	if (dp->msm_dp_display.is_edp) {
+		rc = devm_of_dp_aux_populate_bus(dp->aux, msm_dp_auxbus_done_probe);
 		if (rc) {
 			DRM_ERROR("eDP auxbus population failed, rc=%d\n", rc);
 			goto err;
 		}
 	} else {
-		rc = dp_display_probe_tail(&pdev->dev);
+		rc = msm_dp_display_probe_tail(&pdev->dev);
 		if (rc)
 			goto err;
 	}
@@ -1329,70 +1588,70 @@
 	return rc;
 
 err:
-	dp_display_deinit_sub_modules(dp);
+	msm_dp_display_deinit_sub_modules(dp);
 	return rc;
 }
 
-static void dp_display_remove(struct platform_device *pdev)
+static void msm_dp_display_remove(struct platform_device *pdev)
 {
-	struct dp_display_private *dp = dev_get_dp_display_private(&pdev->dev);
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(&pdev->dev);
 
-	component_del(&pdev->dev, &dp_display_comp_ops);
-	dp_display_deinit_sub_modules(dp);
+	component_del(&pdev->dev, &msm_dp_display_comp_ops);
+	msm_dp_display_deinit_sub_modules(dp);
 	platform_set_drvdata(pdev, NULL);
 }
 
-static int dp_pm_runtime_suspend(struct device *dev)
+static int msm_dp_pm_runtime_suspend(struct device *dev)
 {
-	struct dp_display_private *dp = dev_get_dp_display_private(dev);
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
 
 	disable_irq(dp->irq);
 
-	if (dp->dp_display.is_edp) {
-		dp_display_host_phy_exit(dp);
-		dp_catalog_ctrl_hpd_disable(dp->catalog);
+	if (dp->msm_dp_display.is_edp) {
+		msm_dp_display_host_phy_exit(dp);
+		msm_dp_catalog_ctrl_hpd_disable(dp->catalog);
 	}
-	dp_display_host_deinit(dp);
+	msm_dp_display_host_deinit(dp);
 
 	return 0;
 }
 
-static int dp_pm_runtime_resume(struct device *dev)
+static int msm_dp_pm_runtime_resume(struct device *dev)
 {
-	struct dp_display_private *dp = dev_get_dp_display_private(dev);
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
 
 	/*
 	 * for eDP, host cotroller, HPD block and PHY are enabled here
 	 * but with HPD irq disabled
 	 *
 	 * for DP, only host controller is enabled here.
-	 * HPD block is enabled at dp_bridge_hpd_enable()
+	 * HPD block is enabled at msm_dp_bridge_hpd_enable()
 	 * PHY will be enabled at plugin handler later
 	 */
-	dp_display_host_init(dp);
-	if (dp->dp_display.is_edp) {
-		dp_catalog_ctrl_hpd_enable(dp->catalog);
-		dp_display_host_phy_init(dp);
+	msm_dp_display_host_init(dp);
+	if (dp->msm_dp_display.is_edp) {
+		msm_dp_catalog_ctrl_hpd_enable(dp->catalog);
+		msm_dp_display_host_phy_init(dp);
 	}
 
 	enable_irq(dp->irq);
 	return 0;
 }
 
-static const struct dev_pm_ops dp_pm_ops = {
-	SET_RUNTIME_PM_OPS(dp_pm_runtime_suspend, dp_pm_runtime_resume, NULL)
+static const struct dev_pm_ops msm_dp_pm_ops = {
+	SET_RUNTIME_PM_OPS(msm_dp_pm_runtime_suspend, msm_dp_pm_runtime_resume, NULL)
 	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
 				pm_runtime_force_resume)
 };
 
-static struct platform_driver dp_display_driver = {
-	.probe  = dp_display_probe,
-	.remove_new = dp_display_remove,
+static struct platform_driver msm_dp_display_driver = {
+	.probe  = msm_dp_display_probe,
+	.remove_new = msm_dp_display_remove,
 	.driver = {
 		.name = "msm-dp-display",
-		.of_match_table = dp_dt_match,
+		.of_match_table = msm_dp_dt_match,
 		.suppress_bind_attrs = true,
-		.pm = &dp_pm_ops,
+		.pm = &msm_dp_pm_ops,
 	},
 };
 
@@ -1400,7 +1659,7 @@
 {
 	int ret;
 
-	ret = platform_driver_register(&dp_display_driver);
+	ret = platform_driver_register(&msm_dp_display_driver);
 	if (ret)
 		DRM_ERROR("Dp display driver register failed");
 
@@ -1409,290 +1668,360 @@
 
 void __exit msm_dp_unregister(void)
 {
-	platform_driver_unregister(&dp_display_driver);
+	platform_driver_unregister(&msm_dp_display_driver);
 }
 
-bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)
+bool msm_dp_is_yuv_420_enabled(const struct msm_dp *msm_dp_display,
+			       const struct drm_display_mode *mode)
 {
-	struct dp_display_private *dp;
+	struct msm_dp_display_private *dp;
+	const struct drm_display_info *info;
 
-	dp = container_of(dp_display, struct dp_display_private, dp_display);
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+	info = &msm_dp_display->connector->display_info;
 
-	return dp->wide_bus_en;
+	return dp->panel->vsc_sdp_supported && drm_mode_is_420_only(info, mode);
 }
 
-void dp_display_debugfs_init(struct msm_dp *dp_display, struct dentry *root, bool is_edp)
+bool msm_dp_needs_periph_flush(const struct msm_dp *msm_dp_display,
+			       const struct drm_display_mode *mode)
 {
-	struct dp_display_private *dp;
-	struct device *dev;
-	int rc;
+	return msm_dp_is_yuv_420_enabled(msm_dp_display, mode);
+}
 
-	dp = container_of(dp_display, struct dp_display_private, dp_display);
-	dev = &dp->dp_display.pdev->dev;
+bool msm_dp_wide_bus_available(const struct msm_dp *msm_dp_display)
+{
+	struct msm_dp_display_private *dp;
 
-	dp->debug = dp_debug_get(dev, dp->panel,
-					dp->link, dp->dp_display.connector,
-					root, is_edp);
-	if (IS_ERR(dp->debug)) {
-		rc = PTR_ERR(dp->debug);
-		DRM_ERROR("failed to initialize debug, rc = %d\n", rc);
-		dp->debug = NULL;
-	}
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	if (dp->panel->msm_dp_mode.out_fmt_is_yuv_420)
+		return false;
+
+	return dp->wide_bus_supported;
 }
 
-static int dp_display_get_next_bridge(struct msm_dp *dp)
+int msm_dp_get_mst_intf_id(struct msm_dp *dp_display, int stream_id)
 {
-	int rc;
-	struct dp_display_private *dp_priv;
+	struct msm_dp_display_private *dp;
 
-	dp_priv = container_of(dp, struct dp_display_private, dp_display);
+	dp = container_of(dp_display, struct msm_dp_display_private, msm_dp_display);
 
-	/*
-	 * External bridges are mandatory for eDP interfaces: one has to
-	 * provide at least an eDP panel (which gets wrapped into panel-bridge).
-	 *
-	 * For DisplayPort interfaces external bridges are optional, so
-	 * silently ignore an error if one is not present (-ENODEV).
-	 */
-	rc = devm_dp_parser_find_next_bridge(&dp->pdev->dev, dp_priv->parser);
-	if (!dp->is_edp && rc == -ENODEV)
-		return 0;
+	if (dp->intf_map)
+		return dp->intf_map[stream_id];
 
-	if (!rc)
-		dp->next_bridge = dp_priv->parser->next_bridge;
+	return 0;
+}
 
-	return rc;
+void msm_dp_display_debugfs_init(struct msm_dp *msm_dp_display, struct dentry *root, bool is_edp)
+{
+	struct msm_dp_display_private *dp;
+	struct device *dev;
+	int rc;
+
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+	dev = &dp->msm_dp_display.pdev->dev;
+
+	rc = msm_dp_debug_init(dev, dp->panel, dp->link, dp->msm_dp_display.connector, root, is_edp);
+	if (rc)
+		DRM_ERROR("failed to initialize debug, rc = %d\n", rc);
 }
 
-int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
-			struct drm_encoder *encoder)
+int msm_dp_modeset_init(struct msm_dp *msm_dp_display, struct drm_device *dev,
+			struct drm_encoder *encoder, bool yuv_supported)
 {
-	struct dp_display_private *dp_priv;
+	struct msm_dp_display_private *msm_dp_priv;
 	int ret;
 
-	dp_display->drm_dev = dev;
+	msm_dp_display->drm_dev = dev;
 
-	dp_priv = container_of(dp_display, struct dp_display_private, dp_display);
+	msm_dp_priv = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
 
-	ret = dp_bridge_init(dp_display, dev, encoder);
+	ret = msm_dp_bridge_init(msm_dp_display, dev, encoder, yuv_supported);
 	if (ret) {
 		DRM_DEV_ERROR(dev->dev,
 			"failed to create dp bridge: %d\n", ret);
 		return ret;
 	}
 
-	dp_display->connector = dp_drm_connector_init(dp_display, encoder);
-	if (IS_ERR(dp_display->connector)) {
-		ret = PTR_ERR(dp_display->connector);
+	msm_dp_display->connector = msm_dp_drm_connector_init(msm_dp_display, encoder);
+	if (IS_ERR(msm_dp_display->connector)) {
+		ret = PTR_ERR(msm_dp_display->connector);
 		DRM_DEV_ERROR(dev->dev,
 			"failed to create dp connector: %d\n", ret);
-		dp_display->connector = NULL;
+		msm_dp_display->connector = NULL;
 		return ret;
 	}
 
-	dp_priv->panel->connector = dp_display->connector;
+	msm_dp_priv->panel->connector = msm_dp_display->connector;
 
 	return 0;
 }
 
-void dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
-			     struct drm_bridge_state *old_bridge_state)
+int msm_dp_mst_register(struct msm_dp *dp)
 {
-	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
-	struct msm_dp *dp = dp_bridge->dp_display;
-	int rc = 0;
-	struct dp_display_private *dp_display;
-	u32 state;
-	bool force_link_train = false;
+	struct msm_dp_display_private *dp_display;
 
-	dp_display = container_of(dp, struct dp_display_private, dp_display);
-	if (!dp_display->dp_mode.drm_mode.clock) {
-		DRM_ERROR("invalid params\n");
-		return;
-	}
+	dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
 
-	if (dp->is_edp)
-		dp_hpd_plug_handle(dp_display, 0);
+	return msm_dp_mst_init(dp, dp_display->max_stream,
+			   MAX_DPCD_TRANSACTION_BYTES, dp_display->aux);
+}
 
-	mutex_lock(&dp_display->event_mutex);
-	if (pm_runtime_resume_and_get(&dp->pdev->dev)) {
-		DRM_ERROR("failed to pm_runtime_resume\n");
-		mutex_unlock(&dp_display->event_mutex);
-		return;
-	}
+void msm_dp_display_atomic_prepare(struct msm_dp *dp)
+{
+	int rc = 0;
+	struct msm_dp_display_private *msm_dp_display;
 
-	state = dp_display->hpd_state;
-	if (state != ST_DISPLAY_OFF && state != ST_MAINLINK_READY) {
-		mutex_unlock(&dp_display->event_mutex);
-		return;
-	}
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+	mutex_lock(&msm_dp_display->event_mutex);
 
-	rc = dp_display_set_mode(dp, &dp_display->dp_mode);
+	rc = msm_dp_display_prepare(msm_dp_display);
 	if (rc) {
-		DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc);
-		mutex_unlock(&dp_display->event_mutex);
-		return;
+		DRM_ERROR("DP display prepare failed, rc=%d\n", rc);
 	}
 
-	state =  dp_display->hpd_state;
+	mutex_unlock(&msm_dp_display->event_mutex);
+}
 
-	if (state == ST_DISPLAY_OFF) {
-		dp_display_host_phy_init(dp_display);
-		force_link_train = true;
-	}
+void msm_dp_display_enable_helper(struct msm_dp *dp, struct msm_dp_panel *msm_dp_panel)
+{
+	int rc = 0;
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+	if (dp->is_edp)
+		msm_dp_hpd_plug_handle(msm_dp_display, 0);
 
-	dp_display_enable(dp_display, force_link_train);
+	mutex_lock(&msm_dp_display->event_mutex);
 
-	rc = dp_display_post_enable(dp);
+	rc = msm_dp_display_enable(msm_dp_display, msm_dp_panel);
+	if (rc)
+		DRM_ERROR("DP display enable failed, rc=%d\n", rc);
+
+	rc = msm_dp_display_post_enable(dp);
 	if (rc) {
 		DRM_ERROR("DP display post enable failed, rc=%d\n", rc);
-		dp_display_disable(dp_display);
+		msm_dp_display_disable(msm_dp_display, msm_dp_panel);
 	}
 
+	msm_dp_display->active_stream_cnt++;
+
 	/* completed connection */
-	dp_display->hpd_state = ST_CONNECTED;
+	msm_dp_display->hpd_state = ST_CONNECTED;
 
 	drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
-	mutex_unlock(&dp_display->event_mutex);
+	mutex_unlock(&msm_dp_display->event_mutex);
+}
+
+void msm_dp_display_atomic_enable(struct msm_dp *msm_dp)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(msm_dp, struct msm_dp_display_private, msm_dp_display);
+
+	// move this to a different commit
+	msm_dp_display_set_stream_info(msm_dp, msm_dp_display->panel, 0, 0, 0, 0, 0);
+
+	msm_dp_display_enable_helper(msm_dp, msm_dp_display->panel);
+}
+
+void msm_dp_display_disable_helper(struct msm_dp *dp, struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+	if (!msm_dp_display->active_stream_cnt) {
+		drm_dbg_dp(dp->drm_dev, "no active streams\n");
+		return;
+	}
+
+	msm_dp_ctrl_push_vcpf(msm_dp_display->ctrl, msm_dp_panel);
+	msm_dp_ctrl_mst_stream_channel_slot_setup(msm_dp_display->ctrl, msm_dp_display->max_stream);
+	msm_dp_ctrl_mst_send_act(msm_dp_display->ctrl);
 }
 
-void dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
-			      struct drm_bridge_state *old_bridge_state)
+void msm_dp_display_atomic_disable(struct msm_dp *msm_dp)
 {
-	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
-	struct msm_dp *dp = dp_bridge->dp_display;
-	struct dp_display_private *dp_display;
+	struct msm_dp_display_private *msm_dp_display;
 
-	dp_display = container_of(dp, struct dp_display_private, dp_display);
+	msm_dp_display = container_of(msm_dp, struct msm_dp_display_private, msm_dp_display);
 
-	dp_ctrl_push_idle(dp_display->ctrl);
+	msm_dp_ctrl_push_idle(msm_dp_display->ctrl);
 }
 
-void dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
-				   struct drm_bridge_state *old_bridge_state)
+void msm_dp_display_unprepare(struct msm_dp *msm_dp)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(msm_dp, struct msm_dp_display_private, msm_dp_display);
+	if (!msm_dp->prepared) {
+		drm_dbg_dp(msm_dp->drm_dev, "Link already unprepare, return\n");
+		return;
+	}
+
+	if (msm_dp_display->active_stream_cnt) {
+		drm_dbg_dp(msm_dp->drm_dev, "stream still active, return\n");
+		return;
+	}
+
+	/* dongle is still connected but sinks are disconnected */
+	if (msm_dp_display->link->sink_count == 0)
+		msm_dp_ctrl_psm_config(msm_dp_display->ctrl);
+
+	msm_dp_ctrl_off_link(msm_dp_display->ctrl);
+
+	/* re-init the PHY so that we can listen to Dongle disconnect */
+	if (msm_dp_display->link->sink_count == 0)
+		msm_dp_ctrl_reinit_phy(msm_dp_display->ctrl);
+	else
+		msm_dp_display_host_phy_exit(msm_dp_display);
+
+	pm_runtime_put_sync(&msm_dp->pdev->dev);
+
+	msm_dp->prepared = false;
+}
+
+void msm_dp_display_atomic_post_disable_helper(struct msm_dp *dp, struct msm_dp_panel *msm_dp_panel)
 {
-	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
-	struct msm_dp *dp = dp_bridge->dp_display;
 	u32 state;
-	struct dp_display_private *dp_display;
+	struct msm_dp_display_private *msm_dp_display;
 
-	dp_display = container_of(dp, struct dp_display_private, dp_display);
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
 
 	if (dp->is_edp)
-		dp_hpd_unplug_handle(dp_display, 0);
+		msm_dp_hpd_unplug_handle(msm_dp_display, 0);
 
-	mutex_lock(&dp_display->event_mutex);
+	mutex_lock(&msm_dp_display->event_mutex);
 
-	state = dp_display->hpd_state;
+	state = msm_dp_display->hpd_state;
 	if (state != ST_DISCONNECT_PENDING && state != ST_CONNECTED)
 		drm_dbg_dp(dp->drm_dev, "type=%d wrong hpd_state=%d\n",
 			   dp->connector_type, state);
 
-	dp_display_disable(dp_display);
+	msm_dp_display_audio_notify_disable(msm_dp_display);
 
-	state =  dp_display->hpd_state;
-	if (state == ST_DISCONNECT_PENDING) {
+	msm_dp_display_disable(msm_dp_display, msm_dp_panel);
+
+	state =  msm_dp_display->hpd_state;
+	if (state == ST_DISCONNECT_PENDING && !msm_dp_display->active_stream_cnt) {
 		/* completed disconnection */
-		dp_display->hpd_state = ST_DISCONNECTED;
-	} else {
-		dp_display->hpd_state = ST_DISPLAY_OFF;
+		msm_dp_display->hpd_state = ST_DISCONNECTED;
+	} else if (state != ST_DISCONNECT_PENDING && state != ST_DISCONNECTED) {
+		/* stay at pending till both streams are disabled, otherwise OFF */
+		msm_dp_display->hpd_state = ST_DISPLAY_OFF;
 	}
 
 	drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
 
-	pm_runtime_put_sync(&dp->pdev->dev);
-	mutex_unlock(&dp_display->event_mutex);
+	mutex_unlock(&msm_dp_display->event_mutex);
 }
 
-void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
-			const struct drm_display_mode *mode,
-			const struct drm_display_mode *adjusted_mode)
+void msm_dp_display_atomic_post_disable(struct msm_dp *msm_dp)
 {
-	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
-	struct msm_dp *dp = dp_bridge->dp_display;
-	struct dp_display_private *dp_display;
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(msm_dp, struct msm_dp_display_private, msm_dp_display);
+
+	msm_dp_display_atomic_post_disable_helper(msm_dp, msm_dp_display->panel);
+
+	msm_dp_display_unprepare(msm_dp);
+}
 
-	dp_display = container_of(dp, struct dp_display_private, dp_display);
+void msm_dp_display_mode_set_helper(struct msm_dp *msm_dp,
+				    const struct drm_display_mode *mode,
+				    const struct drm_display_mode *adjusted_mode,
+				    struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_display_private *msm_dp_display;
 
-	memset(&dp_display->dp_mode, 0x0, sizeof(struct dp_display_mode));
+	msm_dp_display = container_of(msm_dp, struct msm_dp_display_private, msm_dp_display);
 
-	if (dp_display_check_video_test(dp))
-		dp_display->dp_mode.bpp = dp_display_get_test_bpp(dp);
-	else /* Default num_components per pixel = 3 */
-		dp_display->dp_mode.bpp = dp->connector->display_info.bpc * 3;
+	msm_dp_display_set_mode(msm_dp, adjusted_mode, msm_dp_panel);
 
-	if (!dp_display->dp_mode.bpp)
-		dp_display->dp_mode.bpp = 24; /* Default bpp */
+	/* populate wide_bus_support to different layers */
+	msm_dp_display->ctrl->wide_bus_en =
+		msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420 ?
+		false : msm_dp_display->wide_bus_supported;
+	msm_dp_display->catalog->wide_bus_en =
+		msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420 ?
+		false : msm_dp_display->wide_bus_supported;
+}
 
-	drm_mode_copy(&dp_display->dp_mode.drm_mode, adjusted_mode);
+void msm_dp_display_mode_set(struct msm_dp *msm_dp,
+			     const struct drm_display_mode *mode,
+			     const struct drm_display_mode *adjusted_mode)
+{
+	struct msm_dp_display_private *msm_dp_display;
 
-	dp_display->dp_mode.v_active_low =
-		!!(dp_display->dp_mode.drm_mode.flags & DRM_MODE_FLAG_NVSYNC);
+	msm_dp_display = container_of(msm_dp, struct msm_dp_display_private, msm_dp_display);
 
-	dp_display->dp_mode.h_active_low =
-		!!(dp_display->dp_mode.drm_mode.flags & DRM_MODE_FLAG_NHSYNC);
+	msm_dp_display_mode_set_helper(msm_dp, mode, adjusted_mode, msm_dp_display->panel);
 }
 
-void dp_bridge_hpd_enable(struct drm_bridge *bridge)
+void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge)
 {
-	struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
-	struct msm_dp *dp_display = dp_bridge->dp_display;
-	struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);
+	struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(bridge);
+	struct msm_dp *msm_dp_display = msm_dp_bridge->msm_dp_display;
+	struct msm_dp_display_private *dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
 
 	/*
 	 * this is for external DP with hpd irq enabled case,
-	 * step-1: dp_pm_runtime_resume() enable dp host only
+	 * step-1: msm_dp_pm_runtime_resume() enable dp host only
 	 * step-2: enable hdp block and have hpd irq enabled here
 	 * step-3: waiting for plugin irq while phy is not initialized
 	 * step-4: DP PHY is initialized at plugin handler before link training
 	 *
 	 */
 	mutex_lock(&dp->event_mutex);
-	if (pm_runtime_resume_and_get(&dp_display->pdev->dev)) {
+	if (pm_runtime_resume_and_get(&msm_dp_display->pdev->dev)) {
 		DRM_ERROR("failed to resume power\n");
 		mutex_unlock(&dp->event_mutex);
 		return;
 	}
 
-	dp_catalog_ctrl_hpd_enable(dp->catalog);
+	msm_dp_catalog_ctrl_hpd_enable(dp->catalog);
 
 	/* enable HDP interrupts */
-	dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, true);
+	msm_dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, true);
 
-	dp_display->internal_hpd = true;
+	msm_dp_display->internal_hpd = true;
 	mutex_unlock(&dp->event_mutex);
 }
 
-void dp_bridge_hpd_disable(struct drm_bridge *bridge)
+void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge)
 {
-	struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
-	struct msm_dp *dp_display = dp_bridge->dp_display;
-	struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);
+	struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(bridge);
+	struct msm_dp *msm_dp_display = msm_dp_bridge->msm_dp_display;
+	struct msm_dp_display_private *dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
 
 	mutex_lock(&dp->event_mutex);
 	/* disable HDP interrupts */
-	dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
-	dp_catalog_ctrl_hpd_disable(dp->catalog);
+	msm_dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
+	msm_dp_catalog_ctrl_hpd_disable(dp->catalog);
 
-	dp_display->internal_hpd = false;
+	msm_dp_display->internal_hpd = false;
 
-	pm_runtime_put_sync(&dp_display->pdev->dev);
+	pm_runtime_put_sync(&msm_dp_display->pdev->dev);
 	mutex_unlock(&dp->event_mutex);
 }
 
-void dp_bridge_hpd_notify(struct drm_bridge *bridge,
+void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
 			  enum drm_connector_status status)
 {
-	struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);
-	struct msm_dp *dp_display = dp_bridge->dp_display;
-	struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);
+	struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(bridge);
+	struct msm_dp *msm_dp_display = msm_dp_bridge->msm_dp_display;
+	struct msm_dp_display_private *dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
 
 	/* Without next_bridge interrupts are handled by the DP core directly */
-	if (dp_display->internal_hpd)
+	if (msm_dp_display->internal_hpd)
 		return;
 
-	if (!dp_display->link_ready && status == connector_status_connected)
-		dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
-	else if (dp_display->link_ready && status == connector_status_disconnected)
-		dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
+	if (!msm_dp_display->link_ready && status == connector_status_connected)
+		msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
+	else if (msm_dp_display->link_ready && status == connector_status_disconnected)
+		msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_display.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_display.h
@@ -7,40 +7,68 @@
 #define _DP_DISPLAY_H_
 
 #include "dp_panel.h"
+#include "dp_mst_drm.h"
 #include <sound/hdmi-codec.h>
 #include "disp/msm_disp_snapshot.h"
 
+#define DP_MAX_PIXEL_CLK_KHZ	675000
+
 struct msm_dp {
 	struct drm_device *drm_dev;
 	struct platform_device *pdev;
 	struct device *codec_dev;
-	struct drm_bridge *bridge;
 	struct drm_connector *connector;
 	struct drm_bridge *next_bridge;
 	bool link_ready;
 	bool audio_enabled;
-	bool power_on;
+	bool prepared;
+	bool mst_active;
 	unsigned int connector_type;
 	bool is_edp;
 	bool internal_hpd;
 
+	struct msm_dp_mst *msm_dp_mst;
 	hdmi_codec_plugged_cb plugged_cb;
 
-	bool wide_bus_en;
-
-	u32 max_dp_lanes;
-	struct dp_audio *dp_audio;
+	struct msm_dp_audio *msm_dp_audio;
 	bool psr_supported;
 };
 
-int dp_display_set_plugged_cb(struct msm_dp *dp_display,
+int msm_dp_display_set_plugged_cb(struct msm_dp *msm_dp_display,
 		hdmi_codec_plugged_cb fn, struct device *codec_dev);
-int dp_display_get_modes(struct msm_dp *dp_display);
-bool dp_display_check_video_test(struct msm_dp *dp_display);
-int dp_display_get_test_bpp(struct msm_dp *dp_display);
-void dp_display_signal_audio_start(struct msm_dp *dp_display);
-void dp_display_signal_audio_complete(struct msm_dp *dp_display);
-void dp_display_set_psr(struct msm_dp *dp, bool enter);
-void dp_display_debugfs_init(struct msm_dp *dp_display, struct dentry *dentry, bool is_edp);
+int msm_dp_display_get_modes(struct msm_dp *msm_dp_display);
+bool msm_dp_display_check_video_test(struct msm_dp *msm_dp_display);
+int msm_dp_display_get_test_bpp(struct msm_dp *msm_dp_display);
+void msm_dp_display_signal_audio_start(struct msm_dp *msm_dp_display);
+void msm_dp_display_signal_audio_complete(struct msm_dp *msm_dp_display);
+void msm_dp_display_set_psr(struct msm_dp *dp, bool enter);
+void msm_dp_display_debugfs_init(struct msm_dp *msm_dp_display, struct dentry *dentry, bool is_edp);
+void msm_dp_display_atomic_post_disable(struct msm_dp *dp_display);
+void msm_dp_display_atomic_disable(struct msm_dp *dp_display);
+void msm_dp_display_atomic_enable(struct msm_dp *dp_display);
+void msm_dp_display_atomic_prepare(struct msm_dp *dp);
+void msm_dp_display_mode_set(struct msm_dp *dp,
+			     const struct drm_display_mode *mode,
+			     const struct drm_display_mode *adjusted_mode);
+enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
+					       const struct drm_display_info *info,
+					       const struct drm_display_mode *mode);
+int msm_dp_display_set_stream_info(struct msm_dp *dp,
+				   struct msm_dp_panel *panel, u32 strm_id,
+				   u32 start_slot, u32 num_slots, u32 pbn, int vcpi);
+void msm_dp_display_enable_helper(struct msm_dp *msm_dp, struct msm_dp_panel *msm_dp_panel);
+void msm_dp_display_disable_helper(struct msm_dp *msm_dp, struct msm_dp_panel *msm_dp_panel);
+void msm_dp_display_mode_set_helper(struct msm_dp *msm_dp,
+				    const struct drm_display_mode *mode,
+				    const struct drm_display_mode *adjusted_mode,
+				    struct msm_dp_panel *msm_dp_panel);
+void msm_dp_display_atomic_post_disable_helper(struct msm_dp *msm_dp,
+					       struct msm_dp_panel *msm_dp_panel);
+
+void msm_dp_display_unprepare(struct msm_dp *dp);
+
+int msm_dp_display_get_active_stream_cnt(struct msm_dp *msm_dp);
+
+struct msm_dp_panel *msm_dp_display_get_panel(struct msm_dp *dp_display);
 
 #endif /* _DP_DISPLAY_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_drm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -14,31 +14,31 @@
 #include "dp_drm.h"
 
 /**
- * dp_bridge_detect - callback to determine if connector is connected
+ * msm_dp_bridge_detect - callback to determine if connector is connected
  * @bridge: Pointer to drm bridge structure
  * Returns: Bridge's 'is connected' status
  */
-static enum drm_connector_status dp_bridge_detect(struct drm_bridge *bridge)
+static enum drm_connector_status msm_dp_bridge_detect(struct drm_bridge *bridge)
 {
 	struct msm_dp *dp;
 
-	dp = to_dp_bridge(bridge)->dp_display;
+	dp = to_dp_bridge(bridge)->msm_dp_display;
 
 	drm_dbg_dp(dp->drm_dev, "link_ready = %s\n",
 		(dp->link_ready) ? "true" : "false");
 
-	return (dp->link_ready) ? connector_status_connected :
+	return (dp->link_ready && !dp->mst_active) ? connector_status_connected :
 					connector_status_disconnected;
 }
 
-static int dp_bridge_atomic_check(struct drm_bridge *bridge,
+static int msm_dp_bridge_atomic_check(struct drm_bridge *bridge,
 			    struct drm_bridge_state *bridge_state,
 			    struct drm_crtc_state *crtc_state,
 			    struct drm_connector_state *conn_state)
 {
 	struct msm_dp *dp;
 
-	dp = to_dp_bridge(bridge)->dp_display;
+	dp = to_dp_bridge(bridge)->msm_dp_display;
 
 	drm_dbg_dp(dp->drm_dev, "link_ready = %s\n",
 		(dp->link_ready) ? "true" : "false");
@@ -62,12 +62,12 @@
 
 
 /**
- * dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add()
+ * msm_dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add()
  * @bridge: Poiner to drm bridge
  * @connector: Pointer to drm connector structure
  * Returns: Number of modes added
  */
-static int dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *connector)
+static int msm_dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *connector)
 {
 	int rc = 0;
 	struct msm_dp *dp;
@@ -75,11 +75,11 @@
 	if (!connector)
 		return 0;
 
-	dp = to_dp_bridge(bridge)->dp_display;
+	dp = to_dp_bridge(bridge)->msm_dp_display;
 
 	/* pluggable case assumes EDID is read when HPD */
 	if (dp->link_ready) {
-		rc = dp_display_get_modes(dp);
+		rc = msm_dp_display_get_modes(dp);
 		if (rc <= 0) {
 			DRM_ERROR("failed to get DP sink modes, rc=%d\n", rc);
 			return rc;
@@ -90,37 +90,85 @@
 	return rc;
 }
 
-static void dp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry *root)
+static void msm_dp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry *root)
 {
-	struct msm_dp *dp = to_dp_bridge(bridge)->dp_display;
+	struct msm_dp *dp = to_dp_bridge(bridge)->msm_dp_display;
 
-	dp_display_debugfs_init(dp, root, false);
+	msm_dp_display_debugfs_init(dp, root, false);
 }
 
-static const struct drm_bridge_funcs dp_bridge_ops = {
+static void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
+					struct drm_bridge_state *old_bridge_state)
+{
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+	msm_dp_display_atomic_prepare(dp);
+	msm_dp_display_atomic_enable(dp);
+}
+
+static void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
+					 struct drm_bridge_state *old_bridge_state)
+{
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+	msm_dp_display_atomic_disable(dp);
+}
+
+static void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
+					      struct drm_bridge_state *old_bridge_state)
+{
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+	msm_dp_display_atomic_post_disable(dp);
+}
+
+static void msm_dp_bridge_mode_set(struct drm_bridge *drm_bridge,
+				   const struct drm_display_mode *mode,
+				   const struct drm_display_mode *adjusted_mode)
+{
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+	msm_dp_display_mode_set(dp, mode, adjusted_mode);
+}
+
+static enum drm_mode_status msm_dp_bridge_mode_valid(struct drm_bridge *drm_bridge,
+						     const struct drm_display_info *info,
+						     const struct drm_display_mode *mode)
+{
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+	return msm_dp_display_mode_valid(dp, info, mode);
+}
+
+static const struct drm_bridge_funcs msm_dp_bridge_ops = {
 	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
 	.atomic_destroy_state   = drm_atomic_helper_bridge_destroy_state,
 	.atomic_reset           = drm_atomic_helper_bridge_reset,
-	.atomic_enable          = dp_bridge_atomic_enable,
-	.atomic_disable         = dp_bridge_atomic_disable,
-	.atomic_post_disable    = dp_bridge_atomic_post_disable,
-	.mode_set     = dp_bridge_mode_set,
-	.mode_valid   = dp_bridge_mode_valid,
-	.get_modes    = dp_bridge_get_modes,
-	.detect       = dp_bridge_detect,
-	.atomic_check = dp_bridge_atomic_check,
-	.hpd_enable   = dp_bridge_hpd_enable,
-	.hpd_disable  = dp_bridge_hpd_disable,
-	.hpd_notify   = dp_bridge_hpd_notify,
-	.debugfs_init = dp_bridge_debugfs_init,
+	.atomic_enable          = msm_dp_bridge_atomic_enable,
+	.atomic_disable         = msm_dp_bridge_atomic_disable,
+	.atomic_post_disable    = msm_dp_bridge_atomic_post_disable,
+	.mode_set     = msm_dp_bridge_mode_set,
+	.mode_valid   = msm_dp_bridge_mode_valid,
+	.get_modes    = msm_dp_bridge_get_modes,
+	.detect       = msm_dp_bridge_detect,
+	.atomic_check = msm_dp_bridge_atomic_check,
+	.hpd_enable   = msm_dp_bridge_hpd_enable,
+	.hpd_disable  = msm_dp_bridge_hpd_disable,
+	.hpd_notify   = msm_dp_bridge_hpd_notify,
+	.debugfs_init = msm_dp_bridge_debugfs_init,
 };
 
-static int edp_bridge_atomic_check(struct drm_bridge *drm_bridge,
+static int msm_edp_bridge_atomic_check(struct drm_bridge *drm_bridge,
 				   struct drm_bridge_state *bridge_state,
 				   struct drm_crtc_state *crtc_state,
 				   struct drm_connector_state *conn_state)
 {
-	struct msm_dp *dp = to_dp_bridge(drm_bridge)->dp_display;
+	struct msm_dp *dp = to_dp_bridge(drm_bridge)->msm_dp_display;
 
 	if (WARN_ON(!conn_state))
 		return -ENODEV;
@@ -136,18 +184,18 @@
 	return 0;
 }
 
-static void edp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
+static void msm_edp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
 				     struct drm_bridge_state *old_bridge_state)
 {
 	struct drm_atomic_state *atomic_state = old_bridge_state->base.state;
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *old_crtc_state;
-	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
-	struct msm_dp *dp = dp_bridge->dp_display;
+	struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
 
 	/*
 	 * Check the old state of the crtc to determine if the panel
-	 * was put into psr state previously by the edp_bridge_atomic_disable.
+	 * was put into psr state previously by the msm_edp_bridge_atomic_disable.
 	 * If the panel is in psr, just exit psr state and skip the full
 	 * bridge enable sequence.
 	 */
@@ -159,21 +207,22 @@
 	old_crtc_state = drm_atomic_get_old_crtc_state(atomic_state, crtc);
 
 	if (old_crtc_state && old_crtc_state->self_refresh_active) {
-		dp_display_set_psr(dp, false);
+		msm_dp_display_set_psr(dp, false);
 		return;
 	}
 
-	dp_bridge_atomic_enable(drm_bridge, old_bridge_state);
+	msm_dp_display_atomic_prepare(dp);
+	msm_dp_display_atomic_enable(dp);
 }
 
-static void edp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
+static void msm_edp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
 				      struct drm_bridge_state *old_bridge_state)
 {
 	struct drm_atomic_state *atomic_state = old_bridge_state->base.state;
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *new_crtc_state = NULL, *old_crtc_state = NULL;
-	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
-	struct msm_dp *dp = dp_bridge->dp_display;
+	struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
 
 	crtc = drm_atomic_get_old_crtc_for_encoder(atomic_state,
 						   drm_bridge->encoder);
@@ -194,24 +243,24 @@
 	 * If old crtc state is active, then this is a display disable
 	 * call while the sink is in psr state. So, exit psr here.
 	 * The eDP controller will be disabled in the
-	 * edp_bridge_atomic_post_disable function.
+	 * msm_edp_bridge_atomic_post_disable function.
 	 *
 	 * We observed sink is stuck in self refresh if psr exit is skipped
 	 * when display disable occurs while the sink is in psr state.
 	 */
 	if (new_crtc_state->self_refresh_active) {
-		dp_display_set_psr(dp, true);
+		msm_dp_display_set_psr(dp, true);
 		return;
 	} else if (old_crtc_state->self_refresh_active) {
-		dp_display_set_psr(dp, false);
+		msm_dp_display_set_psr(dp, false);
 		return;
 	}
 
 out:
-	dp_bridge_atomic_disable(drm_bridge, old_bridge_state);
+	msm_dp_bridge_atomic_disable(drm_bridge, old_bridge_state);
 }
 
-static void edp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
+static void msm_edp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
 				struct drm_bridge_state *old_bridge_state)
 {
 	struct drm_atomic_state *atomic_state = old_bridge_state->base.state;
@@ -228,29 +277,29 @@
 		return;
 
 	/*
-	 * Self refresh mode is already set in edp_bridge_atomic_disable.
+	 * Self refresh mode is already set in msm_edp_bridge_atomic_disable.
 	 */
 	if (new_crtc_state->self_refresh_active)
 		return;
 
-	dp_bridge_atomic_post_disable(drm_bridge, old_bridge_state);
+	msm_dp_bridge_atomic_post_disable(drm_bridge, old_bridge_state);
 }
 
 /**
- * edp_bridge_mode_valid - callback to determine if specified mode is valid
+ * msm_edp_bridge_mode_valid - callback to determine if specified mode is valid
  * @bridge: Pointer to drm bridge structure
  * @info: display info
  * @mode: Pointer to drm mode structure
  * Returns: Validity status for specified mode
  */
-static enum drm_mode_status edp_bridge_mode_valid(struct drm_bridge *bridge,
+static enum drm_mode_status msm_edp_bridge_mode_valid(struct drm_bridge *bridge,
 					  const struct drm_display_info *info,
 					  const struct drm_display_mode *mode)
 {
 	struct msm_dp *dp;
 	int mode_pclk_khz = mode->clock;
 
-	dp = to_dp_bridge(bridge)->dp_display;
+	dp = to_dp_bridge(bridge)->msm_dp_display;
 
 	if (!dp || !mode_pclk_khz || !dp->connector) {
 		DRM_ERROR("invalid params\n");
@@ -268,42 +317,43 @@
 	return MODE_OK;
 }
 
-static void edp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry *root)
+static void msm_edp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry *root)
 {
-	struct msm_dp *dp = to_dp_bridge(bridge)->dp_display;
+	struct msm_dp *dp = to_dp_bridge(bridge)->msm_dp_display;
 
-	dp_display_debugfs_init(dp, root, true);
+	msm_dp_display_debugfs_init(dp, root, true);
 }
 
-static const struct drm_bridge_funcs edp_bridge_ops = {
-	.atomic_enable = edp_bridge_atomic_enable,
-	.atomic_disable = edp_bridge_atomic_disable,
-	.atomic_post_disable = edp_bridge_atomic_post_disable,
-	.mode_set = dp_bridge_mode_set,
-	.mode_valid = edp_bridge_mode_valid,
+static const struct drm_bridge_funcs msm_edp_bridge_ops = {
+	.atomic_enable = msm_edp_bridge_atomic_enable,
+	.atomic_disable = msm_edp_bridge_atomic_disable,
+	.atomic_post_disable = msm_edp_bridge_atomic_post_disable,
+	.mode_set = msm_dp_bridge_mode_set,
+	.mode_valid = msm_edp_bridge_mode_valid,
 	.atomic_reset = drm_atomic_helper_bridge_reset,
 	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
-	.atomic_check = edp_bridge_atomic_check,
-	.debugfs_init = edp_bridge_debugfs_init,
+	.atomic_check = msm_edp_bridge_atomic_check,
+	.debugfs_init = msm_edp_bridge_debugfs_init,
 };
 
-int dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
-			struct drm_encoder *encoder)
+int msm_dp_bridge_init(struct msm_dp *msm_dp_display, struct drm_device *dev,
+		   struct drm_encoder *encoder, bool yuv_supported)
 {
 	int rc;
-	struct msm_dp_bridge *dp_bridge;
+	struct msm_dp_bridge *msm_dp_bridge;
 	struct drm_bridge *bridge;
 
-	dp_bridge = devm_kzalloc(dev->dev, sizeof(*dp_bridge), GFP_KERNEL);
-	if (!dp_bridge)
+	msm_dp_bridge = devm_kzalloc(dev->dev, sizeof(*msm_dp_bridge), GFP_KERNEL);
+	if (!msm_dp_bridge)
 		return -ENOMEM;
 
-	dp_bridge->dp_display = dp_display;
+	msm_dp_bridge->msm_dp_display = msm_dp_display;
 
-	bridge = &dp_bridge->bridge;
-	bridge->funcs = dp_display->is_edp ? &edp_bridge_ops : &dp_bridge_ops;
-	bridge->type = dp_display->connector_type;
+	bridge = &msm_dp_bridge->bridge;
+	bridge->funcs = msm_dp_display->is_edp ? &msm_edp_bridge_ops : &msm_dp_bridge_ops;
+	bridge->type = msm_dp_display->connector_type;
+	bridge->ycbcr_420_allowed = yuv_supported;
 
 	/*
 	 * Many ops only make sense for DP. Why?
@@ -316,7 +366,7 @@
 	 *   allows the panel driver to properly power itself on to read the
 	 *   modes.
 	 */
-	if (!dp_display->is_edp) {
+	if (!msm_dp_display->is_edp) {
 		bridge->ops =
 			DRM_BRIDGE_OP_DETECT |
 			DRM_BRIDGE_OP_HPD |
@@ -337,9 +387,9 @@
 		return rc;
 	}
 
-	if (dp_display->next_bridge) {
+	if (msm_dp_display->next_bridge) {
 		rc = drm_bridge_attach(encoder,
-					dp_display->next_bridge, bridge,
+					msm_dp_display->next_bridge, bridge,
 					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 		if (rc < 0) {
 			DRM_ERROR("failed to attach panel bridge: %d\n", rc);
@@ -347,21 +397,20 @@
 		}
 	}
 
-	dp_display->bridge = bridge;
-
 	return 0;
 }
 
 /* connector initialization */
-struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, struct drm_encoder *encoder)
+struct drm_connector *msm_dp_drm_connector_init(struct msm_dp *msm_dp_display,
+					    struct drm_encoder *encoder)
 {
 	struct drm_connector *connector = NULL;
 
-	connector = drm_bridge_connector_init(dp_display->drm_dev, encoder);
+	connector = drm_bridge_connector_init(msm_dp_display->drm_dev, encoder);
 	if (IS_ERR(connector))
 		return connector;
 
-	if (!dp_display->is_edp)
+	if (!msm_dp_display->is_edp)
 		drm_connector_attach_dp_subconnector_property(connector);
 
 	drm_connector_attach_encoder(connector, encoder);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_drm.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_drm.h
@@ -14,30 +14,20 @@
 
 struct msm_dp_bridge {
 	struct drm_bridge bridge;
-	struct msm_dp *dp_display;
+	struct msm_dp *msm_dp_display;
 };
 
 #define to_dp_bridge(x)     container_of((x), struct msm_dp_bridge, bridge)
 
-struct drm_connector *dp_drm_connector_init(struct msm_dp *dp_display, struct drm_encoder *encoder);
-int dp_bridge_init(struct msm_dp *dp_display, struct drm_device *dev,
-			struct drm_encoder *encoder);
+struct drm_connector *msm_dp_drm_connector_init(struct msm_dp *msm_dp_display,
+					    struct drm_encoder *encoder);
+int msm_dp_bridge_init(struct msm_dp *msm_dp_display, struct drm_device *dev,
+		   struct drm_encoder *encoder,
+		   bool yuv_supported);
 
-void dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
-			     struct drm_bridge_state *old_bridge_state);
-void dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
-			      struct drm_bridge_state *old_bridge_state);
-void dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
-				   struct drm_bridge_state *old_bridge_state);
-enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,
-					  const struct drm_display_info *info,
-					  const struct drm_display_mode *mode);
-void dp_bridge_mode_set(struct drm_bridge *drm_bridge,
-			const struct drm_display_mode *mode,
-			const struct drm_display_mode *adjusted_mode);
-void dp_bridge_hpd_enable(struct drm_bridge *bridge);
-void dp_bridge_hpd_disable(struct drm_bridge *bridge);
-void dp_bridge_hpd_notify(struct drm_bridge *bridge,
+void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge);
+void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge);
+void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
 			  enum drm_connector_status status);
 
 #endif /* _DP_DRM_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_link.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_link.c
@@ -28,26 +28,25 @@
 	AUDIO_TEST_PATTERN_SAWTOOTH		= 0x01,
 };
 
-struct dp_link_request {
+struct msm_dp_link_request {
 	u32 test_requested;
 	u32 test_link_rate;
 	u32 test_lane_count;
 };
 
-struct dp_link_private {
+struct msm_dp_link_private {
 	u32 prev_sink_count;
-	struct device *dev;
 	struct drm_device *drm_dev;
 	struct drm_dp_aux *aux;
-	struct dp_link dp_link;
+	struct msm_dp_link msm_dp_link;
 
-	struct dp_link_request request;
+	struct msm_dp_link_request request;
 	struct mutex psm_mutex;
 	u8 link_status[DP_LINK_STATUS_SIZE];
 };
 
-static int dp_aux_link_power_up(struct drm_dp_aux *aux,
-					struct dp_link_info *link)
+static int msm_dp_aux_link_power_up(struct drm_dp_aux *aux,
+					struct msm_dp_link_info *link)
 {
 	u8 value;
 	ssize_t len;
@@ -74,8 +73,8 @@
 	return 0;
 }
 
-static int dp_aux_link_power_down(struct drm_dp_aux *aux,
-					struct dp_link_info *link)
+static int msm_dp_aux_link_power_down(struct drm_dp_aux *aux,
+					struct msm_dp_link_info *link)
 {
 	u8 value;
 	int err;
@@ -97,7 +96,7 @@
 	return 0;
 }
 
-static int dp_link_get_period(struct dp_link_private *link, int const addr)
+static int msm_dp_link_get_period(struct msm_dp_link_private *link, int const addr)
 {
 	int ret = 0;
 	u8 data;
@@ -123,19 +122,19 @@
 	return ret;
 }
 
-static int dp_link_parse_audio_channel_period(struct dp_link_private *link)
+static int msm_dp_link_parse_audio_channel_period(struct msm_dp_link_private *link)
 {
 	int ret = 0;
-	struct dp_link_test_audio *req = &link->dp_link.test_audio;
+	struct msm_dp_link_test_audio *req = &link->msm_dp_link.test_audio;
 
-	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH1);
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH1);
 	if (ret == -EINVAL)
 		goto exit;
 
 	req->test_audio_period_ch_1 = ret;
 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_1 = 0x%x\n", ret);
 
-	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH2);
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH2);
 	if (ret == -EINVAL)
 		goto exit;
 
@@ -143,42 +142,42 @@
 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_2 = 0x%x\n", ret);
 
 	/* TEST_AUDIO_PERIOD_CH_3 (Byte 0x275) */
-	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH3);
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH3);
 	if (ret == -EINVAL)
 		goto exit;
 
 	req->test_audio_period_ch_3 = ret;
 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_3 = 0x%x\n", ret);
 
-	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH4);
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH4);
 	if (ret == -EINVAL)
 		goto exit;
 
 	req->test_audio_period_ch_4 = ret;
 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_4 = 0x%x\n", ret);
 
-	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH5);
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH5);
 	if (ret == -EINVAL)
 		goto exit;
 
 	req->test_audio_period_ch_5 = ret;
 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_5 = 0x%x\n", ret);
 
-	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH6);
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH6);
 	if (ret == -EINVAL)
 		goto exit;
 
 	req->test_audio_period_ch_6 = ret;
 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_6 = 0x%x\n", ret);
 
-	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH7);
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH7);
 	if (ret == -EINVAL)
 		goto exit;
 
 	req->test_audio_period_ch_7 = ret;
 	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_7 = 0x%x\n", ret);
 
-	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH8);
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH8);
 	if (ret == -EINVAL)
 		goto exit;
 
@@ -188,7 +187,7 @@
 	return ret;
 }
 
-static int dp_link_parse_audio_pattern_type(struct dp_link_private *link)
+static int msm_dp_link_parse_audio_pattern_type(struct msm_dp_link_private *link)
 {
 	int ret = 0;
 	u8 data;
@@ -209,13 +208,13 @@
 		goto exit;
 	}
 
-	link->dp_link.test_audio.test_audio_pattern_type = data;
+	link->msm_dp_link.test_audio.test_audio_pattern_type = data;
 	drm_dbg_dp(link->drm_dev, "audio pattern type = 0x%x\n", data);
 exit:
 	return ret;
 }
 
-static int dp_link_parse_audio_mode(struct dp_link_private *link)
+static int msm_dp_link_parse_audio_mode(struct msm_dp_link_private *link)
 {
 	int ret = 0;
 	u8 data;
@@ -249,8 +248,8 @@
 		goto exit;
 	}
 
-	link->dp_link.test_audio.test_audio_sampling_rate = sampling_rate;
-	link->dp_link.test_audio.test_audio_channel_count = channel_count;
+	link->msm_dp_link.test_audio.test_audio_sampling_rate = sampling_rate;
+	link->msm_dp_link.test_audio.test_audio_channel_count = channel_count;
 	drm_dbg_dp(link->drm_dev,
 			"sampling_rate = 0x%x, channel_count = 0x%x\n",
 			sampling_rate, channel_count);
@@ -258,25 +257,25 @@
 	return ret;
 }
 
-static int dp_link_parse_audio_pattern_params(struct dp_link_private *link)
+static int msm_dp_link_parse_audio_pattern_params(struct msm_dp_link_private *link)
 {
 	int ret = 0;
 
-	ret = dp_link_parse_audio_mode(link);
+	ret = msm_dp_link_parse_audio_mode(link);
 	if (ret)
 		goto exit;
 
-	ret = dp_link_parse_audio_pattern_type(link);
+	ret = msm_dp_link_parse_audio_pattern_type(link);
 	if (ret)
 		goto exit;
 
-	ret = dp_link_parse_audio_channel_period(link);
+	ret = msm_dp_link_parse_audio_channel_period(link);
 
 exit:
 	return ret;
 }
 
-static bool dp_link_is_video_pattern_valid(u32 pattern)
+static bool msm_dp_link_is_video_pattern_valid(u32 pattern)
 {
 	switch (pattern) {
 	case DP_NO_TEST_PATTERN:
@@ -290,12 +289,12 @@
 }
 
 /**
- * dp_link_is_bit_depth_valid() - validates the bit depth requested
+ * msm_dp_link_is_bit_depth_valid() - validates the bit depth requested
  * @tbd: bit depth requested by the sink
  *
  * Returns true if the requested bit depth is supported.
  */
-static bool dp_link_is_bit_depth_valid(u32 tbd)
+static bool msm_dp_link_is_bit_depth_valid(u32 tbd)
 {
 	/* DP_TEST_VIDEO_PATTERN_NONE is treated as invalid */
 	switch (tbd) {
@@ -308,7 +307,7 @@
 	}
 }
 
-static int dp_link_parse_timing_params1(struct dp_link_private *link,
+static int msm_dp_link_parse_timing_params1(struct msm_dp_link_private *link,
 					int addr, int len, u32 *val)
 {
 	u8 bp[2];
@@ -329,7 +328,7 @@
 	return 0;
 }
 
-static int dp_link_parse_timing_params2(struct dp_link_private *link,
+static int msm_dp_link_parse_timing_params2(struct msm_dp_link_private *link,
 					int addr, int len,
 					u32 *val1, u32 *val2)
 {
@@ -352,7 +351,7 @@
 	return 0;
 }
 
-static int dp_link_parse_timing_params3(struct dp_link_private *link,
+static int msm_dp_link_parse_timing_params3(struct msm_dp_link_private *link,
 					int addr, u32 *val)
 {
 	u8 bp;
@@ -370,13 +369,13 @@
 }
 
 /**
- * dp_link_parse_video_pattern_params() - parses video pattern parameters from DPCD
+ * msm_dp_link_parse_video_pattern_params() - parses video pattern parameters from DPCD
  * @link: Display Port Driver data
  *
  * Returns 0 if it successfully parses the video link pattern and the link
  * bit depth requested by the sink and, and if the values parsed are valid.
  */
-static int dp_link_parse_video_pattern_params(struct dp_link_private *link)
+static int msm_dp_link_parse_video_pattern_params(struct msm_dp_link_private *link)
 {
 	int ret = 0;
 	ssize_t rlen;
@@ -389,13 +388,13 @@
 		return rlen;
 	}
 
-	if (!dp_link_is_video_pattern_valid(bp)) {
+	if (!msm_dp_link_is_video_pattern_valid(bp)) {
 		DRM_ERROR("invalid link video pattern = 0x%x\n", bp);
 		ret = -EINVAL;
 		return ret;
 	}
 
-	link->dp_link.test_video.test_video_pattern = bp;
+	link->msm_dp_link.test_video.test_video_pattern = bp;
 
 	/* Read the requested color bit depth and dynamic range (Byte 0x232) */
 	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_MISC0, &bp);
@@ -405,88 +404,88 @@
 	}
 
 	/* Dynamic Range */
-	link->dp_link.test_video.test_dyn_range =
+	link->msm_dp_link.test_video.test_dyn_range =
 			(bp & DP_TEST_DYNAMIC_RANGE_CEA);
 
 	/* Color bit depth */
 	bp &= DP_TEST_BIT_DEPTH_MASK;
-	if (!dp_link_is_bit_depth_valid(bp)) {
+	if (!msm_dp_link_is_bit_depth_valid(bp)) {
 		DRM_ERROR("invalid link bit depth = 0x%x\n", bp);
 		ret = -EINVAL;
 		return ret;
 	}
 
-	link->dp_link.test_video.test_bit_depth = bp;
+	link->msm_dp_link.test_video.test_bit_depth = bp;
 
 	/* resolution timing params */
-	ret = dp_link_parse_timing_params1(link, DP_TEST_H_TOTAL_HI, 2,
-			&link->dp_link.test_video.test_h_total);
+	ret = msm_dp_link_parse_timing_params1(link, DP_TEST_H_TOTAL_HI, 2,
+			&link->msm_dp_link.test_video.test_h_total);
 	if (ret) {
 		DRM_ERROR("failed to parse test_htotal(DP_TEST_H_TOTAL_HI)\n");
 		return ret;
 	}
 
-	ret = dp_link_parse_timing_params1(link, DP_TEST_V_TOTAL_HI, 2,
-			&link->dp_link.test_video.test_v_total);
+	ret = msm_dp_link_parse_timing_params1(link, DP_TEST_V_TOTAL_HI, 2,
+			&link->msm_dp_link.test_video.test_v_total);
 	if (ret) {
 		DRM_ERROR("failed to parse test_v_total(DP_TEST_V_TOTAL_HI)\n");
 		return ret;
 	}
 
-	ret = dp_link_parse_timing_params1(link, DP_TEST_H_START_HI, 2,
-			&link->dp_link.test_video.test_h_start);
+	ret = msm_dp_link_parse_timing_params1(link, DP_TEST_H_START_HI, 2,
+			&link->msm_dp_link.test_video.test_h_start);
 	if (ret) {
 		DRM_ERROR("failed to parse test_h_start(DP_TEST_H_START_HI)\n");
 		return ret;
 	}
 
-	ret = dp_link_parse_timing_params1(link, DP_TEST_V_START_HI, 2,
-			&link->dp_link.test_video.test_v_start);
+	ret = msm_dp_link_parse_timing_params1(link, DP_TEST_V_START_HI, 2,
+			&link->msm_dp_link.test_video.test_v_start);
 	if (ret) {
 		DRM_ERROR("failed to parse test_v_start(DP_TEST_V_START_HI)\n");
 		return ret;
 	}
 
-	ret = dp_link_parse_timing_params2(link, DP_TEST_HSYNC_HI, 2,
-			&link->dp_link.test_video.test_hsync_pol,
-			&link->dp_link.test_video.test_hsync_width);
+	ret = msm_dp_link_parse_timing_params2(link, DP_TEST_HSYNC_HI, 2,
+			&link->msm_dp_link.test_video.test_hsync_pol,
+			&link->msm_dp_link.test_video.test_hsync_width);
 	if (ret) {
 		DRM_ERROR("failed to parse (DP_TEST_HSYNC_HI)\n");
 		return ret;
 	}
 
-	ret = dp_link_parse_timing_params2(link, DP_TEST_VSYNC_HI, 2,
-			&link->dp_link.test_video.test_vsync_pol,
-			&link->dp_link.test_video.test_vsync_width);
+	ret = msm_dp_link_parse_timing_params2(link, DP_TEST_VSYNC_HI, 2,
+			&link->msm_dp_link.test_video.test_vsync_pol,
+			&link->msm_dp_link.test_video.test_vsync_width);
 	if (ret) {
 		DRM_ERROR("failed to parse (DP_TEST_VSYNC_HI)\n");
 		return ret;
 	}
 
-	ret = dp_link_parse_timing_params1(link, DP_TEST_H_WIDTH_HI, 2,
-			&link->dp_link.test_video.test_h_width);
+	ret = msm_dp_link_parse_timing_params1(link, DP_TEST_H_WIDTH_HI, 2,
+			&link->msm_dp_link.test_video.test_h_width);
 	if (ret) {
 		DRM_ERROR("failed to parse test_h_width(DP_TEST_H_WIDTH_HI)\n");
 		return ret;
 	}
 
-	ret = dp_link_parse_timing_params1(link, DP_TEST_V_HEIGHT_HI, 2,
-			&link->dp_link.test_video.test_v_height);
+	ret = msm_dp_link_parse_timing_params1(link, DP_TEST_V_HEIGHT_HI, 2,
+			&link->msm_dp_link.test_video.test_v_height);
 	if (ret) {
 		DRM_ERROR("failed to parse test_v_height\n");
 		return ret;
 	}
 
-	ret = dp_link_parse_timing_params3(link, DP_TEST_MISC1,
-		&link->dp_link.test_video.test_rr_d);
-	link->dp_link.test_video.test_rr_d &= DP_TEST_REFRESH_DENOMINATOR;
+	ret = msm_dp_link_parse_timing_params3(link, DP_TEST_MISC1,
+		&link->msm_dp_link.test_video.test_rr_d);
+	link->msm_dp_link.test_video.test_rr_d &= DP_TEST_REFRESH_DENOMINATOR;
 	if (ret) {
 		DRM_ERROR("failed to parse test_rr_d (DP_TEST_MISC1)\n");
 		return ret;
 	}
 
-	ret = dp_link_parse_timing_params3(link, DP_TEST_REFRESH_RATE_NUMERATOR,
-		&link->dp_link.test_video.test_rr_n);
+	ret = msm_dp_link_parse_timing_params3(link, DP_TEST_REFRESH_RATE_NUMERATOR,
+		&link->msm_dp_link.test_video.test_rr_n);
 	if (ret) {
 		DRM_ERROR("failed to parse test_rr_n\n");
 		return ret;
@@ -506,34 +505,34 @@
 		"TEST_V_HEIGHT = %d\n"
 		"TEST_REFRESH_DENOMINATOR = %d\n"
 		 "TEST_REFRESH_NUMERATOR = %d\n",
-		link->dp_link.test_video.test_video_pattern,
-		link->dp_link.test_video.test_dyn_range,
-		link->dp_link.test_video.test_bit_depth,
-		link->dp_link.test_video.test_h_total,
-		link->dp_link.test_video.test_v_total,
-		link->dp_link.test_video.test_h_start,
-		link->dp_link.test_video.test_v_start,
-		link->dp_link.test_video.test_hsync_pol,
-		link->dp_link.test_video.test_hsync_width,
-		link->dp_link.test_video.test_vsync_pol,
-		link->dp_link.test_video.test_vsync_width,
-		link->dp_link.test_video.test_h_width,
-		link->dp_link.test_video.test_v_height,
-		link->dp_link.test_video.test_rr_d,
-		link->dp_link.test_video.test_rr_n);
+		link->msm_dp_link.test_video.test_video_pattern,
+		link->msm_dp_link.test_video.test_dyn_range,
+		link->msm_dp_link.test_video.test_bit_depth,
+		link->msm_dp_link.test_video.test_h_total,
+		link->msm_dp_link.test_video.test_v_total,
+		link->msm_dp_link.test_video.test_h_start,
+		link->msm_dp_link.test_video.test_v_start,
+		link->msm_dp_link.test_video.test_hsync_pol,
+		link->msm_dp_link.test_video.test_hsync_width,
+		link->msm_dp_link.test_video.test_vsync_pol,
+		link->msm_dp_link.test_video.test_vsync_width,
+		link->msm_dp_link.test_video.test_h_width,
+		link->msm_dp_link.test_video.test_v_height,
+		link->msm_dp_link.test_video.test_rr_d,
+		link->msm_dp_link.test_video.test_rr_n);
 
 	return ret;
 }
 
 /**
- * dp_link_parse_link_training_params() - parses link training parameters from
+ * msm_dp_link_parse_link_training_params() - parses link training parameters from
  * DPCD
  * @link: Display Port Driver data
  *
  * Returns 0 if it successfully parses the link rate (Byte 0x219) and lane
  * count (Byte 0x220), and if these values parse are valid.
  */
-static int dp_link_parse_link_training_params(struct dp_link_private *link)
+static int msm_dp_link_parse_link_training_params(struct msm_dp_link_private *link)
 {
 	u8 bp;
 	ssize_t rlen;
@@ -572,13 +571,13 @@
 }
 
 /**
- * dp_link_parse_phy_test_params() - parses the phy link parameters
+ * msm_dp_link_parse_phy_test_params() - parses the phy link parameters
  * @link: Display Port Driver data
  *
  * Parses the DPCD (Byte 0x248) for the DP PHY link pattern that is being
  * requested.
  */
-static int dp_link_parse_phy_test_params(struct dp_link_private *link)
+static int msm_dp_link_parse_phy_test_params(struct msm_dp_link_private *link)
 {
 	u8 data;
 	ssize_t rlen;
@@ -590,7 +589,7 @@
 		return rlen;
 	}
 
-	link->dp_link.phy_params.phy_test_pattern_sel = data & 0x07;
+	link->msm_dp_link.phy_params.phy_test_pattern_sel = data & 0x07;
 
 	drm_dbg_dp(link->drm_dev, "phy_test_pattern_sel = 0x%x\n", data);
 
@@ -609,12 +608,12 @@
 }
 
 /**
- * dp_link_is_video_audio_test_requested() - checks for audio/video link request
+ * msm_dp_link_is_video_audio_test_requested() - checks for audio/video link request
  * @link: link requested by the sink
  *
  * Returns true if the requested link is a permitted audio/video link.
  */
-static bool dp_link_is_video_audio_test_requested(u32 link)
+static bool msm_dp_link_is_video_audio_test_requested(u32 link)
 {
 	u8 video_audio_test = (DP_TEST_LINK_VIDEO_PATTERN |
 				DP_TEST_LINK_AUDIO_PATTERN |
@@ -625,13 +624,13 @@
 }
 
 /**
- * dp_link_parse_request() - parses link request parameters from sink
+ * msm_dp_link_parse_request() - parses link request parameters from sink
  * @link: Display Port Driver data
  *
  * Parses the DPCD to check if an automated link is requested (Byte 0x201),
  * and what type of link automation is being requested (Byte 0x218).
  */
-static int dp_link_parse_request(struct dp_link_private *link)
+static int msm_dp_link_parse_request(struct msm_dp_link_private *link)
 {
 	int ret = 0;
 	u8 data;
@@ -673,27 +672,27 @@
 	drm_dbg_dp(link->drm_dev, "Test:(0x%x) requested\n", data);
 	link->request.test_requested = data;
 	if (link->request.test_requested == DP_TEST_LINK_PHY_TEST_PATTERN) {
-		ret = dp_link_parse_phy_test_params(link);
+		ret = msm_dp_link_parse_phy_test_params(link);
 		if (ret)
 			goto end;
-		ret = dp_link_parse_link_training_params(link);
+		ret = msm_dp_link_parse_link_training_params(link);
 		if (ret)
 			goto end;
 	}
 
 	if (link->request.test_requested == DP_TEST_LINK_TRAINING) {
-		ret = dp_link_parse_link_training_params(link);
+		ret = msm_dp_link_parse_link_training_params(link);
 		if (ret)
 			goto end;
 	}
 
-	if (dp_link_is_video_audio_test_requested(
+	if (msm_dp_link_is_video_audio_test_requested(
 			link->request.test_requested)) {
-		ret = dp_link_parse_video_pattern_params(link);
+		ret = msm_dp_link_parse_video_pattern_params(link);
 		if (ret)
 			goto end;
 
-		ret = dp_link_parse_audio_pattern_params(link);
+		ret = msm_dp_link_parse_audio_pattern_params(link);
 	}
 end:
 	/*
@@ -701,29 +700,29 @@
 	 * a DP_TEST_NAK.
 	 */
 	if (ret) {
-		link->dp_link.test_response = DP_TEST_NAK;
+		link->msm_dp_link.test_response = DP_TEST_NAK;
 	} else {
 		if (link->request.test_requested != DP_TEST_LINK_EDID_READ)
-			link->dp_link.test_response = DP_TEST_ACK;
+			link->msm_dp_link.test_response = DP_TEST_ACK;
 		else
-			link->dp_link.test_response =
+			link->msm_dp_link.test_response =
 				DP_TEST_EDID_CHECKSUM_WRITE;
 	}
 
 	return ret;
 }
 
-static int dp_link_parse_sink_status_field(struct dp_link_private *link)
+static int msm_dp_link_parse_sink_status_field(struct msm_dp_link_private *link)
 {
 	int len;
 
-	link->prev_sink_count = link->dp_link.sink_count;
+	link->prev_sink_count = link->msm_dp_link.sink_count;
 	len = drm_dp_read_sink_count(link->aux);
 	if (len < 0) {
 		DRM_ERROR("DP parse sink count failed\n");
 		return len;
 	}
-	link->dp_link.sink_count = len;
+	link->msm_dp_link.sink_count = len;
 
 	len = drm_dp_dpcd_read_link_status(link->aux,
 		link->link_status);
@@ -732,11 +731,11 @@
 		return len;
 	}
 
-	return dp_link_parse_request(link);
+	return msm_dp_link_parse_request(link);
 }
 
 /**
- * dp_link_process_link_training_request() - processes new training requests
+ * msm_dp_link_process_link_training_request() - processes new training requests
  * @link: Display Port link data
  *
  * This function will handle new link training requests that are initiated by
@@ -746,7 +745,7 @@
  * The function will return 0 if a link training request has been processed,
  * otherwise it will return -EINVAL.
  */
-static int dp_link_process_link_training_request(struct dp_link_private *link)
+static int msm_dp_link_process_link_training_request(struct msm_dp_link_private *link)
 {
 	if (link->request.test_requested != DP_TEST_LINK_TRAINING)
 		return -EINVAL;
@@ -757,78 +756,76 @@
 			link->request.test_link_rate,
 			link->request.test_lane_count);
 
-	link->dp_link.link_params.num_lanes = link->request.test_lane_count;
-	link->dp_link.link_params.rate =
+	link->msm_dp_link.link_params.num_lanes = link->request.test_lane_count;
+	link->msm_dp_link.link_params.rate =
 		drm_dp_bw_code_to_link_rate(link->request.test_link_rate);
 
 	return 0;
 }
 
-bool dp_link_send_test_response(struct dp_link *dp_link)
+bool msm_dp_link_send_test_response(struct msm_dp_link *msm_dp_link)
 {
-	struct dp_link_private *link = NULL;
+	struct msm_dp_link_private *link = NULL;
 	int ret = 0;
 
-	if (!dp_link) {
+	if (!msm_dp_link) {
 		DRM_ERROR("invalid input\n");
 		return false;
 	}
 
-	link = container_of(dp_link, struct dp_link_private, dp_link);
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
 
 	ret = drm_dp_dpcd_writeb(link->aux, DP_TEST_RESPONSE,
-			dp_link->test_response);
+			msm_dp_link->test_response);
 
 	return ret == 1;
 }
 
-int dp_link_psm_config(struct dp_link *dp_link,
-			      struct dp_link_info *link_info, bool enable)
+int msm_dp_link_psm_config(struct msm_dp_link *msm_dp_link,
+			      struct msm_dp_link_info *link_info, bool enable)
 {
-	struct dp_link_private *link = NULL;
+	struct msm_dp_link_private *link = NULL;
 	int ret = 0;
 
-	if (!dp_link) {
+	if (!msm_dp_link) {
 		DRM_ERROR("invalid params\n");
 		return -EINVAL;
 	}
 
-	link = container_of(dp_link, struct dp_link_private, dp_link);
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
 
 	mutex_lock(&link->psm_mutex);
 	if (enable)
-		ret = dp_aux_link_power_down(link->aux, link_info);
+		ret = msm_dp_aux_link_power_down(link->aux, link_info);
 	else
-		ret = dp_aux_link_power_up(link->aux, link_info);
+		ret = msm_dp_aux_link_power_up(link->aux, link_info);
 
 	if (ret)
 		DRM_ERROR("Failed to %s low power mode\n", enable ?
 							"enter" : "exit");
-	else
-		dp_link->psm_enabled = enable;
 
 	mutex_unlock(&link->psm_mutex);
 	return ret;
 }
 
-bool dp_link_send_edid_checksum(struct dp_link *dp_link, u8 checksum)
+bool msm_dp_link_send_edid_checksum(struct msm_dp_link *msm_dp_link, u8 checksum)
 {
-	struct dp_link_private *link = NULL;
+	struct msm_dp_link_private *link = NULL;
 	int ret = 0;
 
-	if (!dp_link) {
+	if (!msm_dp_link) {
 		DRM_ERROR("invalid input\n");
 		return false;
 	}
 
-	link = container_of(dp_link, struct dp_link_private, dp_link);
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
 
 	ret = drm_dp_dpcd_writeb(link->aux, DP_TEST_EDID_CHECKSUM,
 						checksum);
 	return ret == 1;
 }
 
-static void dp_link_parse_vx_px(struct dp_link_private *link)
+static void msm_dp_link_parse_vx_px(struct msm_dp_link_private *link)
 {
 	drm_dbg_dp(link->drm_dev, "vx: 0=%d, 1=%d, 2=%d, 3=%d\n",
 		drm_dp_get_adjust_request_voltage(link->link_status, 0),
@@ -848,31 +845,31 @@
 	 */
 	drm_dbg_dp(link->drm_dev,
 			 "Current: v_level = 0x%x, p_level = 0x%x\n",
-			link->dp_link.phy_params.v_level,
-			link->dp_link.phy_params.p_level);
-	link->dp_link.phy_params.v_level =
+			link->msm_dp_link.phy_params.v_level,
+			link->msm_dp_link.phy_params.p_level);
+	link->msm_dp_link.phy_params.v_level =
 		drm_dp_get_adjust_request_voltage(link->link_status, 0);
-	link->dp_link.phy_params.p_level =
+	link->msm_dp_link.phy_params.p_level =
 		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 0);
 
-	link->dp_link.phy_params.p_level >>= DP_TRAIN_PRE_EMPHASIS_SHIFT;
+	link->msm_dp_link.phy_params.p_level >>= DP_TRAIN_PRE_EMPHASIS_SHIFT;
 
 	drm_dbg_dp(link->drm_dev,
 			"Requested: v_level = 0x%x, p_level = 0x%x\n",
-			link->dp_link.phy_params.v_level,
-			link->dp_link.phy_params.p_level);
+			link->msm_dp_link.phy_params.v_level,
+			link->msm_dp_link.phy_params.p_level);
 }
 
 /**
- * dp_link_process_phy_test_pattern_request() - process new phy link requests
+ * msm_dp_link_process_phy_test_pattern_request() - process new phy link requests
  * @link: Display Port Driver data
  *
  * This function will handle new phy link pattern requests that are initiated
  * by the sink. The function will return 0 if a phy link pattern has been
  * processed, otherwise it will return -EINVAL.
  */
-static int dp_link_process_phy_test_pattern_request(
-		struct dp_link_private *link)
+static int msm_dp_link_process_phy_test_pattern_request(
+		struct msm_dp_link_private *link)
 {
 	if (!(link->request.test_requested & DP_TEST_LINK_PHY_TEST_PATTERN)) {
 		drm_dbg_dp(link->drm_dev, "no phy test\n");
@@ -889,24 +886,24 @@
 
 	drm_dbg_dp(link->drm_dev,
 			"Current: rate = 0x%x, lane count = 0x%x\n",
-			link->dp_link.link_params.rate,
-			link->dp_link.link_params.num_lanes);
+			link->msm_dp_link.link_params.rate,
+			link->msm_dp_link.link_params.num_lanes);
 
 	drm_dbg_dp(link->drm_dev,
 			"Requested: rate = 0x%x, lane count = 0x%x\n",
 			link->request.test_link_rate,
 			link->request.test_lane_count);
 
-	link->dp_link.link_params.num_lanes = link->request.test_lane_count;
-	link->dp_link.link_params.rate =
+	link->msm_dp_link.link_params.num_lanes = link->request.test_lane_count;
+	link->msm_dp_link.link_params.rate =
 		drm_dp_bw_code_to_link_rate(link->request.test_link_rate);
 
-	dp_link_parse_vx_px(link);
+	msm_dp_link_parse_vx_px(link);
 
 	return 0;
 }
 
-static bool dp_link_read_psr_error_status(struct dp_link_private *link)
+static bool msm_dp_link_read_psr_error_status(struct msm_dp_link_private *link)
 {
 	u8 status;
 
@@ -924,7 +921,7 @@
 	return true;
 }
 
-static bool dp_link_psr_capability_changed(struct dp_link_private *link)
+static bool msm_dp_link_psr_capability_changed(struct msm_dp_link_private *link)
 {
 	u8 status;
 
@@ -944,7 +941,7 @@
 }
 
 /**
- * dp_link_process_link_status_update() - processes link status updates
+ * msm_dp_link_process_link_status_update() - processes link status updates
  * @link: Display Port link module data
  *
  * This function will check for changes in the link status, e.g. clock
@@ -954,13 +951,13 @@
  * The function will return 0 if the a link status update has been processed,
  * otherwise it will return -EINVAL.
  */
-static int dp_link_process_link_status_update(struct dp_link_private *link)
+static int msm_dp_link_process_link_status_update(struct msm_dp_link_private *link)
 {
 	bool channel_eq_done = drm_dp_channel_eq_ok(link->link_status,
-			link->dp_link.link_params.num_lanes);
+			link->msm_dp_link.link_params.num_lanes);
 
 	bool clock_recovery_done = drm_dp_clock_recovery_ok(link->link_status,
-			link->dp_link.link_params.num_lanes);
+			link->msm_dp_link.link_params.num_lanes);
 
 	drm_dbg_dp(link->drm_dev,
 		       "channel_eq_done = %d, clock_recovery_done = %d\n",
@@ -973,7 +970,7 @@
 }
 
 /**
- * dp_link_process_ds_port_status_change() - process port status changes
+ * msm_dp_link_process_ds_port_status_change() - process port status changes
  * @link: Display Port Driver data
  *
  * This function will handle downstream port updates that are initiated by
@@ -983,122 +980,122 @@
  * The function will return 0 if a downstream port update has been
  * processed, otherwise it will return -EINVAL.
  */
-static int dp_link_process_ds_port_status_change(struct dp_link_private *link)
+static int msm_dp_link_process_ds_port_status_change(struct msm_dp_link_private *link)
 {
 	if (get_link_status(link->link_status, DP_LANE_ALIGN_STATUS_UPDATED) &
 					DP_DOWNSTREAM_PORT_STATUS_CHANGED)
 		goto reset;
 
-	if (link->prev_sink_count == link->dp_link.sink_count)
+	if (link->prev_sink_count == link->msm_dp_link.sink_count)
 		return -EINVAL;
 
 reset:
 	/* reset prev_sink_count */
-	link->prev_sink_count = link->dp_link.sink_count;
+	link->prev_sink_count = link->msm_dp_link.sink_count;
 
 	return 0;
 }
 
-static bool dp_link_is_video_pattern_requested(struct dp_link_private *link)
+static bool msm_dp_link_is_video_pattern_requested(struct msm_dp_link_private *link)
 {
 	return (link->request.test_requested & DP_TEST_LINK_VIDEO_PATTERN)
 		&& !(link->request.test_requested &
 		DP_TEST_LINK_AUDIO_DISABLED_VIDEO);
 }
 
-static bool dp_link_is_audio_pattern_requested(struct dp_link_private *link)
+static bool msm_dp_link_is_audio_pattern_requested(struct msm_dp_link_private *link)
 {
 	return (link->request.test_requested & DP_TEST_LINK_AUDIO_PATTERN);
 }
 
-static void dp_link_reset_data(struct dp_link_private *link)
+static void msm_dp_link_reset_data(struct msm_dp_link_private *link)
 {
-	link->request = (const struct dp_link_request){ 0 };
-	link->dp_link.test_video = (const struct dp_link_test_video){ 0 };
-	link->dp_link.test_video.test_bit_depth = DP_TEST_BIT_DEPTH_UNKNOWN;
-	link->dp_link.test_audio = (const struct dp_link_test_audio){ 0 };
-	link->dp_link.phy_params.phy_test_pattern_sel = 0;
-	link->dp_link.sink_request = 0;
-	link->dp_link.test_response = 0;
+	link->request = (const struct msm_dp_link_request){ 0 };
+	link->msm_dp_link.test_video = (const struct msm_dp_link_test_video){ 0 };
+	link->msm_dp_link.test_video.test_bit_depth = DP_TEST_BIT_DEPTH_UNKNOWN;
+	link->msm_dp_link.test_audio = (const struct msm_dp_link_test_audio){ 0 };
+	link->msm_dp_link.phy_params.phy_test_pattern_sel = 0;
+	link->msm_dp_link.sink_request = 0;
+	link->msm_dp_link.test_response = 0;
 }
 
 /**
- * dp_link_process_request() - handle HPD IRQ transition to HIGH
- * @dp_link: pointer to link module data
+ * msm_dp_link_process_request() - handle HPD IRQ transition to HIGH
+ * @msm_dp_link: pointer to link module data
  *
  * This function will handle the HPD IRQ state transitions from LOW to HIGH
  * (including cases when there are back to back HPD IRQ HIGH) indicating
  * the start of a new link training request or sink status update.
  */
-int dp_link_process_request(struct dp_link *dp_link)
+int msm_dp_link_process_request(struct msm_dp_link *msm_dp_link)
 {
 	int ret = 0;
-	struct dp_link_private *link;
+	struct msm_dp_link_private *link;
 
-	if (!dp_link) {
+	if (!msm_dp_link) {
 		DRM_ERROR("invalid input\n");
 		return -EINVAL;
 	}
 
-	link = container_of(dp_link, struct dp_link_private, dp_link);
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
 
-	dp_link_reset_data(link);
+	msm_dp_link_reset_data(link);
 
-	ret = dp_link_parse_sink_status_field(link);
+	ret = msm_dp_link_parse_sink_status_field(link);
 	if (ret)
 		return ret;
 
 	if (link->request.test_requested == DP_TEST_LINK_EDID_READ) {
-		dp_link->sink_request |= DP_TEST_LINK_EDID_READ;
-	} else if (!dp_link_process_ds_port_status_change(link)) {
-		dp_link->sink_request |= DS_PORT_STATUS_CHANGED;
-	} else if (!dp_link_process_link_training_request(link)) {
-		dp_link->sink_request |= DP_TEST_LINK_TRAINING;
-	} else if (!dp_link_process_phy_test_pattern_request(link)) {
-		dp_link->sink_request |= DP_TEST_LINK_PHY_TEST_PATTERN;
-	} else if (dp_link_read_psr_error_status(link)) {
+		msm_dp_link->sink_request |= DP_TEST_LINK_EDID_READ;
+	} else if (!msm_dp_link_process_ds_port_status_change(link)) {
+		msm_dp_link->sink_request |= DS_PORT_STATUS_CHANGED;
+	} else if (!msm_dp_link_process_link_training_request(link)) {
+		msm_dp_link->sink_request |= DP_TEST_LINK_TRAINING;
+	} else if (!msm_dp_link_process_phy_test_pattern_request(link)) {
+		msm_dp_link->sink_request |= DP_TEST_LINK_PHY_TEST_PATTERN;
+	} else if (msm_dp_link_read_psr_error_status(link)) {
 		DRM_ERROR("PSR IRQ_HPD received\n");
-	} else if (dp_link_psr_capability_changed(link)) {
+	} else if (msm_dp_link_psr_capability_changed(link)) {
 		drm_dbg_dp(link->drm_dev, "PSR Capability changed\n");
 	} else {
-		ret = dp_link_process_link_status_update(link);
+		ret = msm_dp_link_process_link_status_update(link);
 		if (!ret) {
-			dp_link->sink_request |= DP_LINK_STATUS_UPDATED;
+			msm_dp_link->sink_request |= DP_LINK_STATUS_UPDATED;
 		} else {
-			if (dp_link_is_video_pattern_requested(link)) {
+			if (msm_dp_link_is_video_pattern_requested(link)) {
 				ret = 0;
-				dp_link->sink_request |= DP_TEST_LINK_VIDEO_PATTERN;
+				msm_dp_link->sink_request |= DP_TEST_LINK_VIDEO_PATTERN;
 			}
-			if (dp_link_is_audio_pattern_requested(link)) {
-				dp_link->sink_request |= DP_TEST_LINK_AUDIO_PATTERN;
+			if (msm_dp_link_is_audio_pattern_requested(link)) {
+				msm_dp_link->sink_request |= DP_TEST_LINK_AUDIO_PATTERN;
 				ret = -EINVAL;
 			}
 		}
 	}
 
 	drm_dbg_dp(link->drm_dev, "sink request=%#x\n",
-				dp_link->sink_request);
+				msm_dp_link->sink_request);
 	return ret;
 }
 
-int dp_link_get_colorimetry_config(struct dp_link *dp_link)
+int msm_dp_link_get_colorimetry_config(struct msm_dp_link *msm_dp_link)
 {
 	u32 cc = DP_MISC0_COLORIMERY_CFG_LEGACY_RGB;
-	struct dp_link_private *link;
+	struct msm_dp_link_private *link;
 
-	if (!dp_link) {
+	if (!msm_dp_link) {
 		DRM_ERROR("invalid input\n");
 		return -EINVAL;
 	}
 
-	link = container_of(dp_link, struct dp_link_private, dp_link);
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
 
 	/*
 	 * Unless a video pattern CTS test is ongoing, use RGB_VESA
 	 * Only RGB_VESA and RGB_CEA supported for now
 	 */
-	if (dp_link_is_video_pattern_requested(link)) {
-		if (link->dp_link.test_video.test_dyn_range &
+	if (msm_dp_link_is_video_pattern_requested(link)) {
+		if (link->msm_dp_link.test_video.test_dyn_range &
 					DP_TEST_DYNAMIC_RANGE_CEA)
 			cc = DP_MISC0_COLORIMERY_CFG_CEA_RGB;
 	}
@@ -1106,21 +1103,22 @@
 	return cc;
 }
 
-int dp_link_adjust_levels(struct dp_link *dp_link, u8 *link_status)
+int msm_dp_link_adjust_levels(struct msm_dp_link *msm_dp_link, u8 *link_status)
 {
 	int i;
+	u8 max_p_level;
 	int v_max = 0, p_max = 0;
-	struct dp_link_private *link;
+	struct msm_dp_link_private *link;
 
-	if (!dp_link) {
+	if (!msm_dp_link) {
 		DRM_ERROR("invalid input\n");
 		return -EINVAL;
 	}
 
-	link = container_of(dp_link, struct dp_link_private, dp_link);
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
 
 	/* use the max level across lanes */
-	for (i = 0; i < dp_link->link_params.num_lanes; i++) {
+	for (i = 0; i < msm_dp_link->link_params.num_lanes; i++) {
 		u8 data_v = drm_dp_get_adjust_request_voltage(link_status, i);
 		u8 data_p = drm_dp_get_adjust_request_pre_emphasis(link_status,
 									 i);
@@ -1133,57 +1131,56 @@
 			p_max = data_p;
 	}
 
-	dp_link->phy_params.v_level = v_max >> DP_TRAIN_VOLTAGE_SWING_SHIFT;
-	dp_link->phy_params.p_level = p_max >> DP_TRAIN_PRE_EMPHASIS_SHIFT;
+	msm_dp_link->phy_params.v_level = v_max >> DP_TRAIN_VOLTAGE_SWING_SHIFT;
+	msm_dp_link->phy_params.p_level = p_max >> DP_TRAIN_PRE_EMPHASIS_SHIFT;
 
 	/**
 	 * Adjust the voltage swing and pre-emphasis level combination to within
 	 * the allowable range.
 	 */
-	if (dp_link->phy_params.v_level > DP_TRAIN_VOLTAGE_SWING_MAX) {
+	if (msm_dp_link->phy_params.v_level > DP_TRAIN_LEVEL_MAX) {
 		drm_dbg_dp(link->drm_dev,
 			"Requested vSwingLevel=%d, change to %d\n",
-			dp_link->phy_params.v_level,
-			DP_TRAIN_VOLTAGE_SWING_MAX);
-		dp_link->phy_params.v_level = DP_TRAIN_VOLTAGE_SWING_MAX;
+			msm_dp_link->phy_params.v_level,
+			DP_TRAIN_LEVEL_MAX);
+		msm_dp_link->phy_params.v_level = DP_TRAIN_LEVEL_MAX;
 	}
 
-	if (dp_link->phy_params.p_level > DP_TRAIN_PRE_EMPHASIS_MAX) {
+	if (msm_dp_link->phy_params.p_level > DP_TRAIN_LEVEL_MAX) {
 		drm_dbg_dp(link->drm_dev,
 			"Requested preEmphasisLevel=%d, change to %d\n",
-			dp_link->phy_params.p_level,
-			DP_TRAIN_PRE_EMPHASIS_MAX);
-		dp_link->phy_params.p_level = DP_TRAIN_PRE_EMPHASIS_MAX;
+			msm_dp_link->phy_params.p_level,
+			DP_TRAIN_LEVEL_MAX);
+		msm_dp_link->phy_params.p_level = DP_TRAIN_LEVEL_MAX;
 	}
 
-	if ((dp_link->phy_params.p_level > DP_TRAIN_PRE_EMPHASIS_LVL_1)
-		&& (dp_link->phy_params.v_level ==
-			DP_TRAIN_VOLTAGE_SWING_LVL_2)) {
+	max_p_level = DP_TRAIN_LEVEL_MAX - msm_dp_link->phy_params.v_level;
+	if (msm_dp_link->phy_params.p_level > max_p_level) {
 		drm_dbg_dp(link->drm_dev,
 			"Requested preEmphasisLevel=%d, change to %d\n",
-			dp_link->phy_params.p_level,
-			DP_TRAIN_PRE_EMPHASIS_LVL_1);
-		dp_link->phy_params.p_level = DP_TRAIN_PRE_EMPHASIS_LVL_1;
+			msm_dp_link->phy_params.p_level,
+			max_p_level);
+		msm_dp_link->phy_params.p_level = max_p_level;
 	}
 
 	drm_dbg_dp(link->drm_dev, "adjusted: v_level=%d, p_level=%d\n",
-		dp_link->phy_params.v_level, dp_link->phy_params.p_level);
+		msm_dp_link->phy_params.v_level, msm_dp_link->phy_params.p_level);
 
 	return 0;
 }
 
-void dp_link_reset_phy_params_vx_px(struct dp_link *dp_link)
+void msm_dp_link_reset_phy_params_vx_px(struct msm_dp_link *msm_dp_link)
 {
-	dp_link->phy_params.v_level = 0;
-	dp_link->phy_params.p_level = 0;
+	msm_dp_link->phy_params.v_level = 0;
+	msm_dp_link->phy_params.p_level = 0;
 }
 
-u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp)
+u32 msm_dp_link_get_test_bits_depth(struct msm_dp_link *msm_dp_link, u32 bpp)
 {
 	u32 tbd;
-	struct dp_link_private *link;
+	struct msm_dp_link_private *link;
 
-	link = container_of(dp_link, struct dp_link_private, dp_link);
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
 
 	/*
 	 * Few simplistic rules and assumptions made here:
@@ -1212,10 +1209,10 @@
 	return tbd;
 }
 
-struct dp_link *dp_link_get(struct device *dev, struct drm_dp_aux *aux)
+struct msm_dp_link *msm_dp_link_get(struct device *dev, struct drm_dp_aux *aux)
 {
-	struct dp_link_private *link;
-	struct dp_link *dp_link;
+	struct msm_dp_link_private *link;
+	struct msm_dp_link *msm_dp_link;
 
 	if (!dev || !aux) {
 		DRM_ERROR("invalid input\n");
@@ -1226,11 +1223,10 @@
 	if (!link)
 		return ERR_PTR(-ENOMEM);
 
-	link->dev   = dev;
 	link->aux   = aux;
 
 	mutex_init(&link->psm_mutex);
-	dp_link = &link->dp_link;
+	msm_dp_link = &link->msm_dp_link;
 
-	return dp_link;
+	return msm_dp_link;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_link.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_link.h
@@ -12,28 +12,16 @@
 #define DP_TEST_BIT_DEPTH_UNKNOWN 0xFFFFFFFF
 #define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0)
 
-struct dp_link_info {
+struct msm_dp_link_info {
 	unsigned char revision;
 	unsigned int rate;
 	unsigned int num_lanes;
 	unsigned long capabilities;
 };
 
-enum dp_link_voltage_level {
-	DP_TRAIN_VOLTAGE_SWING_LVL_0	= 0,
-	DP_TRAIN_VOLTAGE_SWING_LVL_1	= 1,
-	DP_TRAIN_VOLTAGE_SWING_LVL_2	= 2,
-	DP_TRAIN_VOLTAGE_SWING_MAX	= DP_TRAIN_VOLTAGE_SWING_LVL_2,
-};
-
-enum dp_link_preemaphasis_level {
-	DP_TRAIN_PRE_EMPHASIS_LVL_0	= 0,
-	DP_TRAIN_PRE_EMPHASIS_LVL_1	= 1,
-	DP_TRAIN_PRE_EMPHASIS_LVL_2	= 2,
-	DP_TRAIN_PRE_EMPHASIS_MAX	= DP_TRAIN_PRE_EMPHASIS_LVL_2,
-};
+#define DP_TRAIN_LEVEL_MAX	3
 
-struct dp_link_test_video {
+struct msm_dp_link_test_video {
 	u32 test_video_pattern;
 	u32 test_bit_depth;
 	u32 test_dyn_range;
@@ -51,7 +39,7 @@
 	u32 test_rr_n;
 };
 
-struct dp_link_test_audio {
+struct msm_dp_link_test_audio {
 	u32 test_audio_sampling_rate;
 	u32 test_audio_channel_count;
 	u32 test_audio_pattern_type;
@@ -65,22 +53,21 @@
 	u32 test_audio_period_ch_8;
 };
 
-struct dp_link_phy_params {
+struct msm_dp_link_phy_params {
 	u32 phy_test_pattern_sel;
 	u8 v_level;
 	u8 p_level;
 };
 
-struct dp_link {
+struct msm_dp_link {
 	u32 sink_request;
 	u32 test_response;
-	bool psm_enabled;
 
 	u8 sink_count;
-	struct dp_link_test_video test_video;
-	struct dp_link_test_audio test_audio;
-	struct dp_link_phy_params phy_params;
-	struct dp_link_info link_params;
+	struct msm_dp_link_test_video test_video;
+	struct msm_dp_link_test_audio test_audio;
+	struct msm_dp_link_phy_params phy_params;
+	struct msm_dp_link_info link_params;
 };
 
 /**
@@ -91,7 +78,7 @@
  * git bit depth value. This function assumes that bit depth has
  * already been validated.
  */
-static inline u32 dp_link_bit_depth_to_bpp(u32 tbd)
+static inline u32 msm_dp_link_bit_depth_to_bpp(u32 tbd)
 {
 	/*
 	 * Few simplistic rules and assumptions made here:
@@ -112,45 +99,22 @@
 	}
 }
 
-/**
- * dp_test_bit_depth_to_bpc() - convert test bit depth to bpc
- * @tbd: test bit depth
- *
- * Returns the bits per comp (bpc) to be used corresponding to the
- * bit depth value. This function assumes that bit depth has
- * already been validated.
- */
-static inline u32 dp_link_bit_depth_to_bpc(u32 tbd)
-{
-	switch (tbd) {
-	case DP_TEST_BIT_DEPTH_6:
-		return 6;
-	case DP_TEST_BIT_DEPTH_8:
-		return 8;
-	case DP_TEST_BIT_DEPTH_10:
-		return 10;
-	case DP_TEST_BIT_DEPTH_UNKNOWN:
-	default:
-		return 0;
-	}
-}
-
-void dp_link_reset_phy_params_vx_px(struct dp_link *dp_link);
-u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp);
-int dp_link_process_request(struct dp_link *dp_link);
-int dp_link_get_colorimetry_config(struct dp_link *dp_link);
-int dp_link_adjust_levels(struct dp_link *dp_link, u8 *link_status);
-bool dp_link_send_test_response(struct dp_link *dp_link);
-int dp_link_psm_config(struct dp_link *dp_link,
-		struct dp_link_info *link_info, bool enable);
-bool dp_link_send_edid_checksum(struct dp_link *dp_link, u8 checksum);
+void msm_dp_link_reset_phy_params_vx_px(struct msm_dp_link *msm_dp_link);
+u32 msm_dp_link_get_test_bits_depth(struct msm_dp_link *msm_dp_link, u32 bpp);
+int msm_dp_link_process_request(struct msm_dp_link *msm_dp_link);
+int msm_dp_link_get_colorimetry_config(struct msm_dp_link *msm_dp_link);
+int msm_dp_link_adjust_levels(struct msm_dp_link *msm_dp_link, u8 *link_status);
+bool msm_dp_link_send_test_response(struct msm_dp_link *msm_dp_link);
+int msm_dp_link_psm_config(struct msm_dp_link *msm_dp_link,
+		struct msm_dp_link_info *link_info, bool enable);
+bool msm_dp_link_send_edid_checksum(struct msm_dp_link *msm_dp_link, u8 checksum);
 
 /**
- * dp_link_get() - get the functionalities of dp test module
+ * msm_dp_link_get() - get the functionalities of dp test module
  *
  *
- * return: a pointer to dp_link struct
+ * return: a pointer to msm_dp_link struct
  */
-struct dp_link *dp_link_get(struct device *dev, struct drm_dp_aux *aux);
+struct msm_dp_link *msm_dp_link_get(struct device *dev, struct drm_dp_aux *aux);
 
 #endif /* _DP_LINK_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_mst_drm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_mst_drm.c
@@ -0,0 +1,1097 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <drm/drm_edid.h>
+#include "dp_mst_drm.h"
+
+static struct drm_private_state *msm_dp_mst_duplicate_bridge_state(struct drm_private_obj *obj)
+{
+	struct msm_dp_mst_bridge_state *state;
+
+	state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return NULL;
+
+	__drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
+
+	return &state->base;
+}
+
+static void msm_dp_mst_destroy_bridge_state(struct drm_private_obj *obj,
+					    struct drm_private_state *state)
+{
+	struct msm_dp_mst_bridge_state *priv_state =
+		to_msm_dp_mst_bridge_priv_state(state);
+
+	kfree(priv_state);
+}
+
+static const struct drm_private_state_funcs msm_dp_mst_bridge_state_funcs = {
+	.atomic_duplicate_state = msm_dp_mst_duplicate_bridge_state,
+	.atomic_destroy_state = msm_dp_mst_destroy_bridge_state,
+};
+
+/**
+ * dp_mst_find_vcpi_slots() - Find VCPI slots for this PBN value
+ * @mgr: manager to use
+ * @pbn: payload bandwidth to convert into slots.
+ *
+ * Calculate the number of VCPI slots that will be required for the given PBN
+ * value.
+ *
+ * RETURNS:
+ * The total slots required for this port, or error.
+ */
+static int msm_dp_mst_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, int pbn)
+{
+	int num_slots;
+	struct drm_dp_mst_topology_state *state;
+
+	state = to_drm_dp_mst_topology_state(mgr->base.state);
+	num_slots = DIV_ROUND_UP(pbn, state->pbn_div.full);
+
+	/* max. time slots - one slot for MTP header */
+	if (num_slots > 63)
+		return -ENOSPC;
+	return num_slots;
+}
+
+static int msm_dp_mst_calc_pbn_mode(struct drm_display_mode *mode, u32 bpp)
+{
+	int pbn;
+
+	// note : we can even drop dp_mst_calc_pbn_mode and just use this
+	// directly
+	pbn = drm_dp_calc_pbn_mode(mode->clock, bpp << 4);
+
+	return pbn;
+}
+
+static int msm_dp_mst_get_mst_pbn_div(struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_link_info *link_info;
+
+	link_info = &msm_dp_panel->link_info;
+
+	return link_info->rate * link_info->num_lanes / 54000;
+}
+
+static int _msm_dp_mst_compute_config(struct drm_atomic_state *state,
+				      struct msm_dp_mst *mst, struct drm_connector *connector,
+				      struct drm_display_mode *mode)
+{
+	int slots = 0, pbn;
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(connector);
+	int rc = 0;
+	struct drm_dp_mst_topology_state *mst_state;
+
+	struct msm_dp *dp_display = mst->msm_dp;
+	u32 bpp;
+
+	bpp = connector->display_info.bpc * 3;
+	//default to 24
+	if (!bpp)
+		bpp = 24;
+
+	pbn = msm_dp_mst_calc_pbn_mode(mode, bpp);
+
+	mst_state = to_drm_dp_mst_topology_state(mst->mst_mgr.base.state);
+
+	if (!mst_state->pbn_div.full)
+		mst_state->pbn_div.full = msm_dp_mst_get_mst_pbn_div(mst_conn->dp_panel);
+
+	rc = drm_dp_atomic_find_time_slots(state, &mst->mst_mgr, mst_conn->mst_port, pbn);
+	if (rc < 0) {
+		DRM_ERROR("conn:%d failed to find vcpi slots. pbn:%d, rc:%d\n",
+			  connector->base.id, pbn, rc);
+		goto end;
+	}
+
+	slots = rc;
+
+	rc = drm_dp_mst_atomic_check(state);
+	if (rc) {
+		DRM_ERROR("conn:%d mst atomic check failed: rc=%d\n", connector->base.id, rc);
+		slots = 0;
+		goto end;
+	}
+
+	drm_dbg_dp(dp_display->drm_dev, "conn:%d pbn:%d slots:%d rc:%d\n",
+		   connector->base.id, pbn, slots, rc);
+
+end:
+	return (rc < 0 ? rc : slots);
+}
+
+static void _msm_dp_mst_update_timeslots(struct msm_dp_mst *mst,
+					 struct msm_dp_mst_bridge *mst_bridge,
+					 struct drm_dp_mst_port *port)
+{
+	int i;
+	struct msm_dp_mst_bridge *msm_dp_bridge;
+	struct drm_dp_mst_topology_state *mst_state;
+	struct drm_dp_mst_atomic_payload *payload;
+	int prev_start = 0;
+	int prev_slots = 0;
+
+	mst_state = to_drm_dp_mst_topology_state(mst->mst_mgr.base.state);
+	payload = drm_atomic_get_mst_payload_state(mst_state, port);
+
+	if (!payload) {
+		DRM_ERROR("mst bridge [%d] update_timeslots failed, null payload\n",
+			  mst_bridge->id);
+		return;
+	}
+
+	for (i = 0; i < mst->max_streams; i++) {
+		msm_dp_bridge = &mst->mst_bridge[i];
+		if (mst_bridge == msm_dp_bridge) {
+			/*
+			 * When a payload was removed make sure to move any payloads after it
+			 * to the left so all payloads are aligned to the left.
+			 */
+			if (payload->vc_start_slot < 0) {
+				// cache the payload
+				prev_start = msm_dp_bridge->start_slot;
+				prev_slots = msm_dp_bridge->num_slots;
+				msm_dp_bridge->pbn = 0;
+				msm_dp_bridge->start_slot = 1;
+				msm_dp_bridge->num_slots = 0;
+				msm_dp_bridge->vcpi = 0;
+			} else { //add payload
+				msm_dp_bridge->pbn = payload->pbn;
+				msm_dp_bridge->start_slot = payload->vc_start_slot;
+				msm_dp_bridge->num_slots = payload->time_slots;
+				msm_dp_bridge->vcpi = payload->vcpi;
+			}
+		}
+	}
+
+	// Now commit all the updated payloads
+	for (i = 0; i < mst->max_streams; i++) {
+		msm_dp_bridge = &mst->mst_bridge[i];
+
+		//Shift payloads to the left if there was a removed payload.
+		if (payload->vc_start_slot < 0 && msm_dp_bridge->start_slot > prev_start)
+			msm_dp_bridge->start_slot -= prev_slots;
+
+		msm_dp_display_set_stream_info(mst->msm_dp, msm_dp_bridge->msm_dp_panel,
+					       msm_dp_bridge->id, msm_dp_bridge->start_slot,
+					       msm_dp_bridge->num_slots,
+					       msm_dp_bridge->pbn, msm_dp_bridge->vcpi);
+		drm_dbg_dp(mst->msm_dp->drm_dev,
+			   "conn:%d vcpi:%d start_slot:%d num_slots:%d, pbn:%d\n",
+			   DP_MST_CONN_ID(msm_dp_bridge), msm_dp_bridge->vcpi,
+			   msm_dp_bridge->start_slot,
+			   msm_dp_bridge->num_slots, msm_dp_bridge->pbn);
+	}
+}
+
+static int _msm_dp_mst_bridge_pre_enable_part1(struct msm_dp_mst_bridge *dp_bridge)
+{
+	struct msm_dp *msm_dp = dp_bridge->display;
+	struct msm_dp_mst *mst = msm_dp->msm_dp_mst;
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(dp_bridge->connector);
+	struct drm_dp_mst_port *port = mst_conn->mst_port;
+	struct drm_dp_mst_topology_state *mst_state;
+	struct drm_dp_mst_atomic_payload *payload;
+	struct msm_dp_panel *dp_panel = mst_conn->dp_panel;
+	int pbn, slots;
+	int rc = 0;
+
+	pbn = msm_dp_mst_calc_pbn_mode(&dp_panel->msm_dp_mode.drm_mode,
+				       msm_dp->connector->display_info.bpc * 3);
+
+	slots = msm_dp_mst_find_vcpi_slots(&mst->mst_mgr, pbn);
+
+	drm_dbg_dp(msm_dp->drm_dev, "conn:%d pbn:%d, slots:%d\n", DP_MST_CONN_ID(dp_bridge),
+		   pbn, slots);
+
+	mst_state = to_drm_dp_mst_topology_state(mst->mst_mgr.base.state);
+	payload = drm_atomic_get_mst_payload_state(mst_state, port);
+	if (!payload || payload->time_slots <= 0) {
+		DRM_ERROR("time slots not allocated for conn:%d\n", DP_MST_CONN_ID(dp_bridge));
+		rc = -EINVAL;
+		return rc;
+	}
+
+	drm_dp_mst_update_slots(mst_state, DP_CAP_ANSI_8B10B);
+
+	rc = drm_dp_add_payload_part1(&mst->mst_mgr, mst_state, payload);
+	if (rc) {
+		DRM_ERROR("payload allocation failure for conn:%d\n", DP_MST_CONN_ID(dp_bridge));
+		return rc;
+	}
+
+	_msm_dp_mst_update_timeslots(mst, dp_bridge, port);
+
+	return rc;
+}
+
+static void _msm_dp_mst_bridge_pre_enable_part2(struct msm_dp_mst_bridge *dp_bridge)
+{
+	struct msm_dp *msm_dp = dp_bridge->display;
+	struct msm_dp_mst *mst = msm_dp->msm_dp_mst;
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(dp_bridge->connector);
+	struct drm_dp_mst_port *port = mst_conn->mst_port;
+	struct drm_dp_mst_topology_state *mst_state;
+	struct drm_dp_mst_atomic_payload *payload;
+
+	drm_dp_check_act_status(&mst->mst_mgr);
+
+	mst_state = to_drm_dp_mst_topology_state(mst->mst_mgr.base.state);
+	payload = drm_atomic_get_mst_payload_state(mst_state, port);
+
+	if (!payload) {
+		DRM_ERROR("mst bridge [%d] null payload\n", dp_bridge->id);
+		return;
+	}
+
+	if (!payload->port) {
+		DRM_ERROR("mst bridge [%d] null port\n", dp_bridge->id);
+		return;
+	}
+
+	if (!payload->port->connector) {
+		DRM_ERROR("mst bridge [%d] part-2 failed, null connector\n",
+			  dp_bridge->id);
+		return;
+	}
+
+	if (payload->vc_start_slot == -1) {
+		DRM_ERROR("mst bridge [%d] part-2 failed, payload alloc part 1 failed\n",
+			  dp_bridge->id);
+		return;
+	}
+
+	drm_dp_add_payload_part2(&mst->mst_mgr, payload);
+	drm_dbg_dp(msm_dp->drm_dev, "mst bridge [%d] _pre enable part-2 complete\n",
+		   dp_bridge->id);
+}
+
+static void _msm_dp_mst_bridge_pre_disable_part1(struct msm_dp_mst_bridge *dp_bridge)
+{
+	struct msm_dp *msm_dp = dp_bridge->display;
+	struct msm_dp_mst *mst = msm_dp->msm_dp_mst;
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(dp_bridge->connector);
+	struct drm_dp_mst_port *port = mst_conn->mst_port;
+	struct drm_dp_mst_topology_state *mst_state;
+	struct drm_dp_mst_atomic_payload *payload;
+
+	mst_state = to_drm_dp_mst_topology_state(mst->mst_mgr.base.state);
+	payload = drm_atomic_get_mst_payload_state(mst_state, port);
+
+	if (!payload) {
+		DRM_ERROR("mst bridge [%d] _pre disable part-1 failed, null payload\n",
+			  dp_bridge->id);
+		return;
+	}
+
+	drm_dp_remove_payload_part1(&mst->mst_mgr, mst_state, payload);
+	_msm_dp_mst_update_timeslots(mst, dp_bridge, port);
+
+	drm_dbg_dp(msm_dp->drm_dev, "mst bridge [%d] _pre disable part-1 complete\n",
+		   dp_bridge->id);
+}
+
+static void _msm_dp_mst_bridge_pre_disable_part2(struct msm_dp_mst_bridge *dp_bridge)
+{
+	struct msm_dp *msm_dp = dp_bridge->display;
+	struct msm_dp_mst *mst = msm_dp->msm_dp_mst;
+
+	drm_dp_check_act_status(&mst->mst_mgr);
+
+	drm_dbg_dp(msm_dp->drm_dev, "mst bridge [%d] _pre disable part-2 complete\n",
+		   dp_bridge->id);
+}
+
+static void msm_dp_mst_bridge_atomic_pre_enable(struct drm_bridge *drm_bridge,
+						struct drm_bridge_state *old_bridge_state)
+{
+	int rc = 0;
+	struct msm_dp_mst_bridge *bridge;
+	struct msm_dp *dp;
+	struct msm_dp_mst_bridge_state *msm_dp_bridge_state;
+	struct msm_dp_mst *dp_mst;
+
+	if (!drm_bridge) {
+		DRM_ERROR("Invalid params\n");
+		return;
+	}
+
+	bridge = to_msm_dp_mst_bridge(drm_bridge);
+	msm_dp_bridge_state = to_msm_dp_mst_bridge_state(bridge);
+	dp = bridge->display;
+	dp_mst = dp->msm_dp_mst;
+
+	/* to cover cases of bridge_disable/bridge_enable without modeset */
+	bridge->connector = msm_dp_bridge_state->connector;
+	bridge->msm_dp_panel = msm_dp_bridge_state->msm_dp_panel;
+
+	if (!bridge->connector) {
+		DRM_ERROR("Invalid connector\n");
+		return;
+	}
+
+	mutex_lock(&dp_mst->mst_lock);
+	msm_dp_display_atomic_prepare(dp);
+
+	rc = _msm_dp_mst_bridge_pre_enable_part1(bridge);
+	if (rc) {
+		DRM_ERROR("[%d] DP display pre-enable failed, rc=%d\n", bridge->id, rc);
+		msm_dp_display_unprepare(dp);
+		mutex_unlock(&dp_mst->mst_lock);
+		return;
+	}
+
+	msm_dp_display_enable_helper(dp, bridge->msm_dp_panel);
+
+	_msm_dp_mst_bridge_pre_enable_part2(bridge);
+
+	drm_dbg_dp(dp->drm_dev, "conn:%d mode:%s fps:%d vcpi:%d slots:%d to %d\n",
+		   DP_MST_CONN_ID(bridge), bridge->drm_mode.name,
+		   drm_mode_vrefresh(&bridge->drm_mode),
+		   bridge->vcpi, bridge->start_slot,
+		   bridge->start_slot + bridge->num_slots);
+
+	mutex_unlock(&dp_mst->mst_lock);
+}
+
+static void msm_dp_mst_bridge_atomic_disable(struct drm_bridge *drm_bridge,
+					     struct drm_bridge_state *old_bridge_state)
+{
+	struct msm_dp_mst_bridge *bridge;
+	struct msm_dp *dp;
+	struct msm_dp_mst *mst;
+
+	if (!drm_bridge) {
+		DRM_ERROR("Invalid params\n");
+		return;
+	}
+
+	bridge = to_msm_dp_mst_bridge(drm_bridge);
+	if (!bridge->connector) {
+		DRM_ERROR("Invalid connector\n");
+		return;
+	}
+
+	dp = bridge->display;
+	mst = dp->msm_dp_mst;
+
+	mutex_lock(&mst->mst_lock);
+
+	_msm_dp_mst_bridge_pre_disable_part1(bridge);
+
+	msm_dp_display_disable_helper(dp, bridge->msm_dp_panel);
+
+	_msm_dp_mst_bridge_pre_disable_part2(bridge);
+
+	drm_dbg_dp(dp->drm_dev, "mst bridge:%d conn:%d disable complete\n", bridge->id,
+		   DP_MST_CONN_ID(bridge));
+
+	mutex_unlock(&mst->mst_lock);
+}
+
+static void msm_dp_mst_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
+						  struct drm_bridge_state *old_bridge_state)
+{
+	int conn = 0;
+	struct msm_dp_mst_bridge *bridge;
+	struct msm_dp *dp;
+	struct msm_dp_mst *mst;
+
+	if (!drm_bridge) {
+		DRM_ERROR("Invalid params\n");
+		return;
+	}
+
+	bridge = to_msm_dp_mst_bridge(drm_bridge);
+	if (!bridge->connector) {
+		DRM_ERROR("Invalid connector\n");
+		return;
+	}
+
+	conn = DP_MST_CONN_ID(bridge);
+
+	dp = bridge->display;
+	mst = dp->msm_dp_mst;
+
+	mutex_lock(&mst->mst_lock);
+
+	msm_dp_display_atomic_post_disable_helper(dp, bridge->msm_dp_panel);
+
+	if (!dp->mst_active)
+		msm_dp_display_unprepare(dp);
+
+	bridge->connector = NULL;
+	bridge->msm_dp_panel =  NULL;
+
+	drm_dbg_dp(dp->drm_dev, "mst bridge:%d conn:%d post disable complete\n",
+		   bridge->id, conn);
+
+	mutex_unlock(&mst->mst_lock);
+}
+
+static void msm_dp_mst_bridge_mode_set(struct drm_bridge *drm_bridge,
+				       const struct drm_display_mode *mode,
+				       const struct drm_display_mode *adjusted_mode)
+{
+	struct msm_dp_mst_bridge *bridge;
+	struct msm_dp_mst_bridge_state *dp_bridge_state;
+	struct msm_dp *dp;
+	struct msm_dp_panel *msm_dp_panel;
+
+	if (!drm_bridge || !mode || !adjusted_mode) {
+		DRM_ERROR("Invalid params\n");
+		return;
+	}
+
+	bridge = to_msm_dp_mst_bridge(drm_bridge);
+
+	dp_bridge_state = to_msm_dp_mst_bridge_state(bridge);
+	bridge->connector = dp_bridge_state->connector;
+	bridge->msm_dp_panel = dp_bridge_state->msm_dp_panel;
+
+	msm_dp_panel = bridge->msm_dp_panel;
+
+	dp = bridge->display;
+
+	memset(&bridge->msm_dp_mode, 0x0, sizeof(struct msm_dp_display_mode));
+	memcpy(&bridge->drm_mode, adjusted_mode, sizeof(bridge->drm_mode));
+
+	msm_dp_display_mode_set_helper(dp, mode, adjusted_mode, bridge->msm_dp_panel);
+	msm_dp_panel->mst_caps.pbn = msm_dp_mst_calc_pbn_mode(&msm_dp_panel->msm_dp_mode.drm_mode,
+							      msm_dp_panel->msm_dp_mode.bpp);
+	memcpy(&bridge->msm_dp_mode, &bridge->msm_dp_panel->msm_dp_mode,
+	       sizeof(struct msm_dp_display_mode));
+
+	drm_dbg_dp(dp->drm_dev, "mst bridge:%d conn:%d mode set complete %s\n", bridge->id,
+		   DP_MST_CONN_ID(bridge), mode->name);
+}
+
+/* DP MST Bridge APIs */
+static const struct drm_bridge_funcs msm_dp_mst_bridge_ops = {
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state   = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset           = drm_atomic_helper_bridge_reset,
+	.atomic_pre_enable   = msm_dp_mst_bridge_atomic_pre_enable,
+	.atomic_disable      = msm_dp_mst_bridge_atomic_disable,
+	.atomic_post_disable = msm_dp_mst_bridge_atomic_post_disable,
+	.mode_set     = msm_dp_mst_bridge_mode_set,
+};
+
+int msm_dp_mst_drm_bridge_init(struct msm_dp *dp, struct drm_encoder *encoder)
+{
+	int rc = 0;
+	struct msm_dp_mst_bridge *bridge = NULL;
+	struct msm_dp_mst_bridge_state *state;
+	struct drm_device *dev;
+	struct msm_dp_mst *mst = dp->msm_dp_mst;
+	int i;
+
+	for (i = 0; i < mst->max_streams; i++) {
+		if (!mst->mst_bridge[i].in_use) {
+			bridge = &mst->mst_bridge[i];
+			bridge->encoder = encoder;
+			bridge->in_use = true;
+			bridge->id = i;
+			break;
+		}
+	}
+
+	if (i == mst->max_streams) {
+		DRM_ERROR("mst supports only %d bridges\n", i);
+		rc = -EACCES;
+		goto end;
+	}
+
+	dev = dp->drm_dev;
+	bridge->display = dp;
+	bridge->base.funcs = &msm_dp_mst_bridge_ops;
+	bridge->base.encoder = encoder;
+	bridge->base.type = dp->connector_type;
+	bridge->base.ops = DRM_BRIDGE_OP_MODES;
+	drm_bridge_add(&bridge->base);
+
+	rc = drm_bridge_attach(encoder, &bridge->base, NULL, 0);
+	if (rc) {
+		DRM_ERROR("failed to attach bridge, rc=%d\n", rc);
+		goto end;
+	}
+
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (!state) {
+		rc = -ENOMEM;
+		goto end;
+	}
+
+	drm_atomic_private_obj_init(dev, &bridge->obj,
+				    &state->base,
+				    &msm_dp_mst_bridge_state_funcs);
+
+	drm_dbg_dp(dp->drm_dev, "mst drm bridge init. bridge id:%d\n", i);
+
+	return 0;
+
+end:
+	return rc;
+}
+
+static struct msm_dp_mst_bridge_state *msm_dp_mst_br_priv_state(struct drm_atomic_state *st,
+								struct msm_dp_mst_bridge *bridge)
+{
+	struct drm_device *dev = bridge->base.dev;
+
+	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+
+	return to_msm_dp_mst_bridge_priv_state(drm_atomic_get_private_obj_state(st,
+										&bridge->obj));
+}
+
+static void msm_dp_mst_clear_panel_edid(struct msm_dp *dp_display)
+{
+	struct msm_dp_mst *mst = dp_display->msm_dp_mst;
+	struct msm_dp_mst_connector *mst_conn;
+	struct msm_dp_panel *dp_panel;
+	struct msm_dp_mst_bridge *dp_bridge;
+	int i;
+
+	if (!dp_display) {
+		DRM_ERROR("invalid input\n");
+		return;
+	}
+
+	for (i = 0; i < mst->max_streams; i++) {
+		dp_bridge = &mst->mst_bridge[i];
+		mst_conn = to_msm_dp_mst_connector(dp_bridge->connector);
+		dp_panel = dp_bridge->msm_dp_panel;
+
+		if (!dp_panel || !mst_conn || !mst_conn->mst_port)
+			continue;
+
+		if (dp_panel->drm_edid) {
+			drm_edid_free(dp_panel->drm_edid);
+			dp_panel->drm_edid = NULL;
+		}
+	}
+}
+
+/* DP MST HPD IRQ callback */
+void msm_dp_mst_display_hpd_irq(struct msm_dp *dp_display)
+{
+	int rc;
+	struct msm_dp_mst *mst = dp_display->msm_dp_mst;
+	u8 ack[8] = {};
+	u8 esi[14];
+	unsigned int esi_res = DP_SINK_COUNT_ESI + 1;
+	bool handled;
+
+	rc = drm_dp_dpcd_read(mst->dp_aux, DP_SINK_COUNT_ESI, esi, 14);
+	if (rc != 14) {
+		DRM_ERROR("dpcd sink status read failed, rlen=%d\n", rc);
+		return;
+	}
+
+	drm_dbg_dp(dp_display->drm_dev, "mst irq: esi1[0x%x] esi2[0x%x] esi3[0x%x]\n",
+		   esi[1], esi[2], esi[3]);
+
+	rc = drm_dp_mst_hpd_irq_handle_event(&mst->mst_mgr, esi, ack, &handled);
+
+	/* ack the request */
+	if (handled) {
+		rc = drm_dp_dpcd_writeb(mst->dp_aux, esi_res, ack[1]);
+
+		if (ack[1] & DP_UP_REQ_MSG_RDY)
+			msm_dp_mst_clear_panel_edid(dp_display);
+
+		if (rc != 1)
+			DRM_ERROR("dpcd esi_res failed. rc=%d\n", rc);
+
+		drm_dp_mst_hpd_irq_send_new_request(&mst->mst_mgr);
+	}
+	drm_dbg_dp(dp_display->drm_dev, "mst display hpd_irq handled:%d rc:%d\n", handled, rc);
+}
+
+/* DP MST Connector OPs */
+static int
+msm_dp_mst_connector_detect(struct drm_connector *connector,
+			    struct drm_modeset_acquire_ctx *ctx,
+			    bool force)
+{
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(connector);
+	struct msm_dp *dp_display = mst_conn->msm_dp;
+	struct msm_dp_mst *mst = dp_display->msm_dp_mst;
+	enum drm_connector_status status = connector_status_disconnected;
+
+	if (dp_display->link_ready && dp_display->mst_active)
+		status = drm_dp_mst_detect_port(connector,
+						ctx, &mst->mst_mgr, mst_conn->mst_port);
+
+	drm_dbg_dp(dp_display->drm_dev, "conn:%d status:%d\n", connector->base.id, status);
+
+	return (int)status;
+}
+
+static int msm_dp_mst_connector_get_modes(struct drm_connector *connector)
+{
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(connector);
+	struct msm_dp *dp_display = mst_conn->msm_dp;
+	struct msm_dp_mst *mst = dp_display->msm_dp_mst;
+	struct msm_dp_panel *dp_panel = mst_conn->dp_panel;
+
+	if (dp_panel->drm_edid)
+		goto duplicate_edid;
+
+	drm_edid_free(dp_panel->drm_edid);
+
+	dp_panel->drm_edid = drm_dp_mst_edid_read(connector, &mst->mst_mgr, mst_conn->mst_port);
+	if (!dp_panel->drm_edid) {
+		DRM_ERROR("get edid failed. id: %d\n", connector->base.id);
+		return -EINVAL;
+	}
+
+duplicate_edid:
+	drm_edid_connector_update(connector, dp_panel->drm_edid);
+
+	return drm_edid_connector_add_modes(connector);
+}
+
+static enum drm_mode_status msm_dp_mst_connector_mode_valid(struct drm_connector *connector,
+							    struct drm_display_mode *mode)
+{
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(connector);
+	struct msm_dp *dp_display = mst_conn->msm_dp;
+	struct drm_dp_mst_port *mst_port;
+	struct msm_dp_panel *dp_panel;
+	struct msm_dp_mst *mst;
+	u16 full_pbn, required_pbn;
+	int available_slots, required_slots;
+	struct msm_dp_mst_bridge_state *dp_bridge_state;
+	int i, slots_in_use = 0, active_enc_cnt = 0;
+	const u32 tot_slots = 63;
+
+	if (!connector || !mode || !dp_display) {
+		DRM_ERROR("invalid input\n");
+		return 0;
+	}
+
+	mst = dp_display->msm_dp_mst;
+	mst_conn = to_msm_dp_mst_connector(connector);
+	mst_port = mst_conn->mst_port;
+	dp_panel = mst_conn->dp_panel;
+
+	if (!dp_panel || !mst_port)
+		return MODE_ERROR;
+
+	/* dp bridge state is protected by drm_mode_config.connection_mutex */
+	for (i = 0; i < mst->max_streams; i++) {
+		dp_bridge_state = to_msm_dp_mst_bridge_state(&mst->mst_bridge[i]);
+		if (dp_bridge_state->connector &&
+		    dp_bridge_state->connector != connector) {
+			active_enc_cnt++;
+			slots_in_use += dp_bridge_state->num_slots;
+		}
+	}
+
+	if (active_enc_cnt < DP_STREAM_MAX) {
+		full_pbn = mst_port->full_pbn;
+		available_slots = tot_slots - slots_in_use;
+	} else {
+		DRM_ERROR("all mst streams are active\n");
+		return MODE_BAD;
+	}
+
+	required_pbn = msm_dp_mst_calc_pbn_mode(mode, connector->display_info.bpc * 3);
+
+	required_slots = msm_dp_mst_find_vcpi_slots(&mst->mst_mgr, required_pbn);
+
+	if (required_pbn > full_pbn || required_slots > available_slots) {
+		drm_dbg_dp(dp_display->drm_dev,
+			   "mode:%s not supported. pbn %d vs %d slots %d vs %d\n",
+			   mode->name, required_pbn, full_pbn,
+			   required_slots, available_slots);
+		return MODE_BAD;
+	}
+
+	return msm_dp_display_mode_valid(dp_display, &dp_display->connector->display_info, mode);
+}
+
+static struct drm_encoder *
+msm_dp_mst_atomic_best_encoder(struct drm_connector *connector, struct drm_atomic_state *state)
+{
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(connector);
+	struct msm_dp *dp_display = mst_conn->msm_dp;
+	struct msm_dp_mst *mst = dp_display->msm_dp_mst;
+	struct drm_encoder *enc = NULL;
+	struct msm_dp_mst_bridge_state *bridge_state;
+	u32 i;
+	struct drm_connector_state *conn_state = drm_atomic_get_new_connector_state(state,
+										    connector);
+
+	if (conn_state && conn_state->best_encoder)
+		return conn_state->best_encoder;
+
+	for (i = 0; i < mst->max_streams; i++) {
+		bridge_state = msm_dp_mst_br_priv_state(state, &mst->mst_bridge[i]);
+		if (IS_ERR(bridge_state))
+			goto end;
+
+		if (bridge_state->connector == connector) {
+			enc = mst->mst_bridge[i].encoder;
+			goto end;
+		}
+	}
+
+	for (i = 0; i < mst->max_streams; i++) {
+		bridge_state = msm_dp_mst_br_priv_state(state, &mst->mst_bridge[i]);
+
+		if (!bridge_state->connector) {
+			bridge_state->connector = connector;
+			bridge_state->msm_dp_panel = mst_conn->dp_panel;
+			enc = mst->mst_bridge[i].encoder;
+			break;
+		}
+	}
+
+end:
+	if (enc)
+		drm_dbg_dp(dp_display->drm_dev, "mst connector:%d atomic best encoder:%d\n",
+			   connector->base.id, i);
+	else
+		drm_dbg_dp(dp_display->drm_dev, "mst connector:%d atomic best encoder failed\n",
+			   connector->base.id);
+
+	return enc;
+}
+
+static int msm_dp_mst_connector_atomic_check(struct drm_connector *connector,
+					     struct drm_atomic_state *state)
+{
+	int rc = 0, slots, i;
+	bool vcpi_released = false;
+	struct drm_connector_state *old_conn_state;
+	struct drm_connector_state *new_conn_state;
+	struct drm_crtc *old_crtc;
+	struct drm_crtc_state *crtc_state;
+	struct msm_dp_mst_bridge *bridge;
+	struct msm_dp_mst_bridge_state *bridge_state;
+	struct drm_bridge *drm_bridge;
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(connector);
+	struct msm_dp *dp_display = mst_conn->msm_dp;
+	struct msm_dp_mst *mst = dp_display->msm_dp_mst;
+
+	if (!state)
+		return rc;
+
+	new_conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (!new_conn_state)
+		return rc;
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, connector);
+	if (!old_conn_state)
+		goto mode_set;
+
+	old_crtc = old_conn_state->crtc;
+	if (!old_crtc)
+		goto mode_set;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, old_crtc);
+
+	for (i = 0; i < mst->max_streams; i++) {
+		bridge = &mst->mst_bridge[i];
+		drm_dbg_dp(dp_display->drm_dev, "bridge id:%d, vcpi:%d, pbn:%d, slots:%d\n",
+			   bridge->id, bridge->vcpi, bridge->pbn,
+			   bridge->num_slots);
+	}
+
+	/*attempt to release vcpi slots on a modeset change for crtc state*/
+	if (drm_atomic_crtc_needs_modeset(crtc_state)) {
+		if (WARN_ON(!old_conn_state->best_encoder)) {
+			rc = -EINVAL;
+			goto end;
+		}
+
+		drm_bridge = drm_bridge_chain_get_first_bridge(old_conn_state->best_encoder);
+		if (WARN_ON(!drm_bridge)) {
+			rc = -EINVAL;
+			goto end;
+		}
+		bridge = to_msm_dp_mst_bridge(drm_bridge);
+
+		bridge_state = msm_dp_mst_br_priv_state(state, bridge);
+		if (IS_ERR(bridge_state)) {
+			rc = PTR_ERR(bridge_state);
+			goto end;
+		}
+
+		if (WARN_ON(bridge_state->connector != connector)) {
+			rc = -EINVAL;
+			goto end;
+		}
+
+		slots = bridge_state->num_slots;
+		if (slots > 0) {
+			rc = drm_dp_atomic_release_time_slots(state,
+							      &mst->mst_mgr,
+							      mst_conn->mst_port);
+			if (rc) {
+				DRM_ERROR("failed releasing %d vcpi slots %d\n", slots, rc);
+				goto end;
+			}
+			vcpi_released = true;
+		}
+
+		if (!new_conn_state->crtc) {
+			/* for cases where crtc is not disabled the slots are not
+			 * freed by drm_dp_atomic_release_time_slots. this results
+			 * in subsequent atomic_check failing since internal slots
+			 * were freed but not the dp mst mgr's
+			 */
+			bridge_state->num_slots = 0;
+			bridge_state->connector = NULL;
+			bridge_state->msm_dp_panel = NULL;
+
+			drm_dbg_dp(dp_display->drm_dev, "clear best encoder: %d\n", bridge->id);
+		}
+	}
+
+mode_set:
+	if (!new_conn_state->crtc)
+		goto end;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
+
+	if (drm_atomic_crtc_needs_modeset(crtc_state) && crtc_state->active) {
+		if (WARN_ON(!new_conn_state->best_encoder)) {
+			rc = -EINVAL;
+			goto end;
+		}
+
+		drm_bridge = drm_bridge_chain_get_first_bridge(new_conn_state->best_encoder);
+		if (WARN_ON(!drm_bridge)) {
+			rc = -EINVAL;
+			goto end;
+		}
+		bridge = to_msm_dp_mst_bridge(drm_bridge);
+
+		bridge_state = msm_dp_mst_br_priv_state(state, bridge);
+		if (IS_ERR(bridge_state)) {
+			rc = PTR_ERR(bridge_state);
+			goto end;
+		}
+
+		if (WARN_ON(bridge_state->connector != connector)) {
+			rc = -EINVAL;
+			goto end;
+		}
+
+		/*
+		 * check if vcpi slots are trying to get allocated in same phase
+		 * as deallocation. If so, go to end to avoid allocation.
+		 */
+		if (vcpi_released) {
+			drm_dbg_dp(dp_display->drm_dev,
+				   "skipping allocation since vcpi was released in the same state\n");
+			goto end;
+		}
+
+		if (WARN_ON(bridge_state->num_slots)) {
+			rc = -EINVAL;
+			goto end;
+		}
+
+		slots = _msm_dp_mst_compute_config(state, mst, connector, &crtc_state->mode);
+		if (slots < 0) {
+			rc = slots;
+			goto end;
+		}
+
+		bridge_state->num_slots = slots;
+	}
+
+end:
+	drm_dbg_dp(dp_display->drm_dev, "mst connector:%d atomic check ret %d\n",
+		   connector->base.id, rc);
+	return rc;
+}
+
+static void dp_mst_connector_destroy(struct drm_connector *connector)
+{
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(connector);
+	struct msm_dp_panel *dp_panel = mst_conn->dp_panel;
+
+	drm_connector_cleanup(connector);
+	drm_edid_free(dp_panel->drm_edid);
+	dp_panel->drm_edid = NULL;
+	drm_dp_mst_put_port_malloc(mst_conn->mst_port);
+	msm_dp_panel_put(mst_conn->dp_panel);
+}
+
+/* DRM MST callbacks */
+static const struct drm_connector_helper_funcs dp_drm_mst_connector_helper_funcs = {
+	.get_modes =    msm_dp_mst_connector_get_modes,
+	.detect_ctx =   msm_dp_mst_connector_detect,
+	.mode_valid =   msm_dp_mst_connector_mode_valid,
+	.atomic_best_encoder = msm_dp_mst_atomic_best_encoder,
+	.atomic_check = msm_dp_mst_connector_atomic_check,
+};
+
+static const struct drm_connector_funcs dp_drm_mst_connector_funcs = {
+	.reset = drm_atomic_helper_connector_reset,
+	.destroy = dp_mst_connector_destroy,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static struct drm_connector *
+msm_dp_mst_add_connector(struct drm_dp_mst_topology_mgr *mgr,
+			 struct drm_dp_mst_port *port, const char *pathprop)
+{
+	struct msm_dp_mst *dp_mst;
+	struct drm_device *dev;
+	struct msm_dp *dp_display;
+	struct msm_dp_mst_connector *mst_connector;
+	struct drm_connector *connector;
+	int rc, i;
+
+	dp_mst = container_of(mgr, struct msm_dp_mst, mst_mgr);
+
+	dp_display = dp_mst->msm_dp;
+	dev = dp_display->drm_dev;
+
+	mst_connector = devm_kzalloc(dev->dev, sizeof(*mst_connector), GFP_KERNEL);
+
+	/* make sure connector is not accessed before reset */
+	drm_modeset_lock_all(dev);
+
+	rc = drm_connector_init(dev, &mst_connector->connector, &dp_drm_mst_connector_funcs,
+				DRM_MODE_CONNECTOR_DisplayPort);
+	if (rc) {
+		drm_modeset_unlock_all(dev);
+		return NULL;
+	}
+
+	mst_connector->dp_panel = msm_dp_display_get_panel(dp_display);
+	if (!mst_connector->dp_panel) {
+		DRM_ERROR("failed to get dp_panel for connector\n");
+		drm_modeset_unlock_all(dev);
+		return NULL;
+	}
+
+	mst_connector->dp_panel->connector = &mst_connector->connector;
+	mst_connector->msm_dp = dp_display;
+	connector = &mst_connector->connector;
+	drm_connector_helper_add(&mst_connector->connector, &dp_drm_mst_connector_helper_funcs);
+
+	if (connector->funcs->reset)
+		connector->funcs->reset(connector);
+
+	/* add all encoders as possible encoders */
+	for (i = 0; i < dp_mst->max_streams; i++) {
+		rc = drm_connector_attach_encoder(&mst_connector->connector,
+						  dp_mst->mst_bridge[i].encoder);
+		if (rc) {
+			DRM_ERROR("failed to attach encoder to connector, %d\n", rc);
+			drm_modeset_unlock_all(dev);
+			return NULL;
+		}
+	}
+
+	mst_connector->mst_port = port;
+	drm_dp_mst_get_port_malloc(mst_connector->mst_port);
+
+	/* check if we need to call connector_reset here */
+
+	drm_object_attach_property(&mst_connector->connector.base,
+				   dev->mode_config.path_property, 0);
+	drm_object_attach_property(&mst_connector->connector.base,
+				   dev->mode_config.tile_property, 0);
+
+	/* unlock connector and make it accessible */
+	drm_modeset_unlock_all(dev);
+
+	drm_dbg_dp(dp_display->drm_dev, "add mst connector id:%d\n",
+		   mst_connector->connector.base.id);
+
+	return &mst_connector->connector;
+}
+
+int msm_dp_mst_display_set_mgr_state(struct msm_dp *dp_display, bool state)
+{
+	int rc;
+	struct msm_dp_mst *mst = dp_display->msm_dp_mst;
+
+	/*
+	 * on hpd high, set_mgr_state is called before hotplug event is sent
+	 * to usermode and mst_session_state should be updated here.
+	 * on hpd_low, set_mgr_state is called after hotplug event is sent and
+	 * the session_state was already updated prior to that.
+	 */
+	if (state)
+		mst->mst_session_hpd_state = state;
+
+	rc = drm_dp_mst_topology_mgr_set_mst(&mst->mst_mgr, state);
+	if (rc < 0) {
+		DRM_ERROR("failed to set topology mgr state to %d. rc %d\n",
+			  state, rc);
+	}
+
+	drm_dbg_dp(dp_display->drm_dev, "dp_mst_display_set_mgr_state state:%d\n", state);
+	return rc;
+}
+
+static const struct drm_dp_mst_topology_cbs msm_dp_mst_drm_cbs = {
+	.add_connector = msm_dp_mst_add_connector,
+};
+
+int msm_dp_mst_init(struct msm_dp *dp_display, u32 max_streams, u32 max_dpcd_transaction_bytes,
+		    struct drm_dp_aux *drm_aux)
+{
+	struct drm_device *dev;
+	int conn_base_id = 0;
+	int ret;
+	struct msm_dp_mst *msm_dp_mst;
+
+	if (!dp_display) {
+		DRM_ERROR("invalid params\n");
+		return 0;
+	}
+
+	dev = dp_display->drm_dev;
+
+	msm_dp_mst = devm_kzalloc(dev->dev, sizeof(*msm_dp_mst), GFP_KERNEL);
+	if (!msm_dp_mst)
+		return -ENOMEM;
+
+	// will expost the callbacks as direct APIs for hotplug
+	// lets drop install_info for now
+	memset(&msm_dp_mst->mst_mgr, 0, sizeof(msm_dp_mst->mst_mgr));
+	msm_dp_mst->mst_mgr.cbs = &msm_dp_mst_drm_cbs;
+	conn_base_id = dp_display->connector->base.id;
+	msm_dp_mst->msm_dp = dp_display;
+	msm_dp_mst->dp_aux = drm_aux;
+	msm_dp_mst->max_streams = max_streams;
+
+	ret = drm_dp_mst_topology_mgr_init(&msm_dp_mst->mst_mgr, dev,
+					   drm_aux,
+					   max_dpcd_transaction_bytes,
+					   max_streams,
+					   conn_base_id);
+	if (ret) {
+		DRM_ERROR("dp drm mst topology manager init failed\n");
+		return ret;
+	}
+
+	dp_display->msm_dp_mst = msm_dp_mst;
+
+	mutex_init(&msm_dp_mst->mst_lock);
+
+	msm_dp_mst->mst_initialized = true;
+
+	drm_dbg_dp(dp_display->drm_dev, "dp drm mst topology manager init completed\n");
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_mst_drm.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_mst_drm.h
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _DP_MST_DRM_H_
+#define _DP_MST_DRM_H_
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/version.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fixed.h>
+#include <drm/drm_connector.h>
+#include <drm/display/drm_dp_helper.h>
+#include <drm/display/drm_dp_mst_helper.h>
+
+#include "dp_panel.h"
+#include "dp_display.h"
+
+#define MAX_DP_MST_DRM_BRIDGES         4
+
+#define DP_MST_CONN_ID(bridge) ((bridge)->connector ? \
+		(bridge)->connector->base.id : 0)
+
+struct msm_dp_mst_bridge {
+	struct drm_bridge base;
+	struct drm_private_obj obj;
+	u32 id;
+
+	bool in_use;
+
+	struct msm_dp *display;
+	struct drm_encoder *encoder;
+
+	struct drm_display_mode drm_mode;
+	struct msm_dp_display_mode msm_dp_mode;
+	struct drm_connector *connector;
+	struct msm_dp_panel *msm_dp_panel;
+
+	int vcpi;
+	int pbn;
+	int num_slots;
+	int start_slot;
+};
+
+struct msm_dp_mst_bridge_state {
+	struct drm_private_state base;
+	struct drm_connector *connector;
+	struct msm_dp_panel *msm_dp_panel;
+	int num_slots;
+};
+
+struct msm_dp_mst {
+	bool mst_initialized;
+	struct drm_dp_mst_topology_mgr mst_mgr;
+	struct msm_dp_mst_bridge mst_bridge[MAX_DP_MST_DRM_BRIDGES];
+	struct msm_dp *msm_dp;
+	struct drm_dp_aux *dp_aux;
+	bool mst_session_hpd_state;
+	u32 max_streams;
+	struct mutex mst_lock;
+};
+
+struct msm_dp_mst_connector {
+	struct drm_connector connector;
+	struct drm_dp_mst_port *mst_port;
+	struct msm_dp *msm_dp;
+	struct msm_dp_panel *dp_panel;
+};
+
+#define to_msm_dp_mst_bridge(x)     container_of((x), struct msm_dp_mst_bridge, base)
+#define to_msm_dp_mst_bridge_priv(x) \
+		container_of((x), struct msm_dp_mst_bridge, obj)
+#define to_msm_dp_mst_bridge_priv_state(x) \
+		container_of((x), struct msm_dp_mst_bridge_state, base)
+#define to_msm_dp_mst_bridge_state(x) \
+		to_msm_dp_mst_bridge_priv_state((x)->obj.state)
+#define to_msm_dp_mst_connector(x) \
+		container_of((x), struct msm_dp_mst_connector, connector)
+int msm_dp_mst_drm_bridge_init(struct msm_dp *dp, struct drm_encoder *encoder);
+
+int msm_dp_mst_init(struct msm_dp *dp_display, u32 max_streams,
+		    u32 max_dpcd_transaction_bytes, struct drm_dp_aux *drm_aux);
+
+void msm_dp_mst_display_hpd_irq(struct msm_dp *dp_display);
+int msm_dp_mst_display_set_mgr_state(struct msm_dp *dp_display, bool state);
+
+#endif /* _DP_MST_DRM_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_panel.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_panel.c
@@ -4,56 +4,62 @@
  */
 
 #include "dp_panel.h"
+#include "dp_utils.h"
 
 #include <drm/drm_connector.h>
 #include <drm/drm_edid.h>
+#include <drm/drm_of.h>
 #include <drm/drm_print.h>
 
-struct dp_panel_private {
+#define DP_MAX_NUM_DP_LANES	4
+#define DP_LINK_RATE_HBR2	540000 /* kbytes */
+
+struct msm_dp_panel_private {
 	struct device *dev;
 	struct drm_device *drm_dev;
-	struct dp_panel dp_panel;
+	struct msm_dp_panel msm_dp_panel;
 	struct drm_dp_aux *aux;
-	struct dp_link *link;
-	struct dp_catalog *catalog;
+	struct msm_dp_link *link;
+	struct msm_dp_catalog *catalog;
 	bool panel_on;
 };
 
-static void dp_panel_read_psr_cap(struct dp_panel_private *panel)
+static void msm_dp_panel_read_psr_cap(struct msm_dp_panel_private *panel)
 {
 	ssize_t rlen;
-	struct dp_panel *dp_panel;
+	struct msm_dp_panel *msm_dp_panel;
 
-	dp_panel = &panel->dp_panel;
+	msm_dp_panel = &panel->msm_dp_panel;
 
 	/* edp sink */
-	if (dp_panel->dpcd[DP_EDP_CONFIGURATION_CAP]) {
+	if (msm_dp_panel->dpcd[DP_EDP_CONFIGURATION_CAP]) {
 		rlen = drm_dp_dpcd_read(panel->aux, DP_PSR_SUPPORT,
-				&dp_panel->psr_cap, sizeof(dp_panel->psr_cap));
-		if (rlen == sizeof(dp_panel->psr_cap)) {
+				&msm_dp_panel->psr_cap, sizeof(msm_dp_panel->psr_cap));
+		if (rlen == sizeof(msm_dp_panel->psr_cap)) {
 			drm_dbg_dp(panel->drm_dev,
 				"psr version: 0x%x, psr_cap: 0x%x\n",
-				dp_panel->psr_cap.version,
-				dp_panel->psr_cap.capabilities);
+				msm_dp_panel->psr_cap.version,
+				msm_dp_panel->psr_cap.capabilities);
 		} else
 			DRM_ERROR("failed to read psr info, rlen=%zd\n", rlen);
 	}
 }
 
-static int dp_panel_read_dpcd(struct dp_panel *dp_panel)
+static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel)
 {
 	int rc;
-	struct dp_panel_private *panel;
-	struct dp_link_info *link_info;
+	struct msm_dp_panel_private *panel;
+	struct msm_dp_link_info *link_info;
 	u8 *dpcd, major, minor;
 
-	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
-	dpcd = dp_panel->dpcd;
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+	dpcd = msm_dp_panel->dpcd;
 	rc = drm_dp_read_dpcd_caps(panel->aux, dpcd);
 	if (rc)
 		return rc;
 
-	link_info = &dp_panel->link_info;
+	msm_dp_panel->vsc_sdp_supported = drm_dp_vsc_sdp_supported(panel->aux, dpcd);
+	link_info = &msm_dp_panel->link_info;
 	link_info->revision = dpcd[DP_DPCD_REV];
 	major = (link_info->revision >> 4) & 0x0f;
 	minor = link_info->revision & 0x0f;
@@ -62,12 +68,12 @@
 	link_info->num_lanes = drm_dp_max_lane_count(dpcd);
 
 	/* Limit data lanes from data-lanes of endpoint property of dtsi */
-	if (link_info->num_lanes > dp_panel->max_dp_lanes)
-		link_info->num_lanes = dp_panel->max_dp_lanes;
+	if (link_info->num_lanes > msm_dp_panel->max_dp_lanes)
+		link_info->num_lanes = msm_dp_panel->max_dp_lanes;
 
 	/* Limit link rate from link-frequencies of endpoint property of dtsi */
-	if (link_info->rate > dp_panel->max_dp_link_rate)
-		link_info->rate = dp_panel->max_dp_link_rate;
+	if (link_info->rate > msm_dp_panel->max_dp_link_rate)
+		link_info->rate = msm_dp_panel->max_dp_link_rate;
 
 	drm_dbg_dp(panel->drm_dev, "version: %d.%d\n", major, minor);
 	drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate);
@@ -76,84 +82,79 @@
 	if (drm_dp_enhanced_frame_cap(dpcd))
 		link_info->capabilities |= DP_LINK_CAP_ENHANCED_FRAMING;
 
-	dp_panel_read_psr_cap(panel);
+	msm_dp_panel_read_psr_cap(panel);
 
 	return rc;
 }
 
-static u32 dp_panel_get_supported_bpp(struct dp_panel *dp_panel,
+static u32 msm_dp_panel_get_supported_bpp(struct msm_dp_panel *msm_dp_panel,
 		u32 mode_edid_bpp, u32 mode_pclk_khz)
 {
-	struct dp_link_info *link_info;
+	const struct msm_dp_link_info *link_info;
 	const u32 max_supported_bpp = 30, min_supported_bpp = 18;
-	u32 bpp = 0, data_rate_khz = 0;
+	u32 bpp, data_rate_khz;
 
-	bpp = min_t(u32, mode_edid_bpp, max_supported_bpp);
+	bpp = min(mode_edid_bpp, max_supported_bpp);
 
-	link_info = &dp_panel->link_info;
+	link_info = &msm_dp_panel->link_info;
 	data_rate_khz = link_info->num_lanes * link_info->rate * 8;
 
-	while (bpp > min_supported_bpp) {
+	do {
 		if (mode_pclk_khz * bpp <= data_rate_khz)
-			break;
+			return bpp;
 		bpp -= 6;
-	}
+	} while (bpp > min_supported_bpp);
 
-	return bpp;
+	return min_supported_bpp;
 }
 
-static int dp_panel_update_modes(struct drm_connector *connector,
-	struct edid *edid)
+bool msm_dp_panel_read_mst_cap(struct msm_dp_panel *msm_dp_panel)
 {
-	int rc = 0;
+	struct msm_dp_panel_private *panel;
 
-	if (edid) {
-		rc = drm_connector_update_edid_property(connector, edid);
-		if (rc) {
-			DRM_ERROR("failed to update edid property %d\n", rc);
-			return rc;
-		}
-		rc = drm_add_edid_modes(connector, edid);
-		return rc;
+	if (!msm_dp_panel) {
+		DRM_ERROR("invalid input\n");
+		return false;
 	}
 
-	rc = drm_connector_update_edid_property(connector, NULL);
-	if (rc)
-		DRM_ERROR("failed to update edid property %d\n", rc);
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
 
-	return rc;
+	return drm_dp_read_mst_cap(panel->aux, msm_dp_panel->dpcd);
 }
 
-int dp_panel_read_sink_caps(struct dp_panel *dp_panel,
-	struct drm_connector *connector)
+int msm_dp_panel_read_link_caps(struct msm_dp_panel *msm_dp_panel,
+		struct drm_connector *connector)
 {
 	int rc, bw_code;
 	int count;
-	struct dp_panel_private *panel;
+	struct msm_dp_panel_private *panel;
 
-	if (!dp_panel || !connector) {
+	if (!msm_dp_panel || !connector) {
 		DRM_ERROR("invalid input\n");
 		return -EINVAL;
 	}
 
-	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
 
-	rc = dp_panel_read_dpcd(dp_panel);
+	drm_dbg_dp(panel->drm_dev, "max_lanes=%d max_link_rate=%d\n",
+		msm_dp_panel->max_dp_lanes, msm_dp_panel->max_dp_link_rate);
+
+	rc = msm_dp_panel_read_dpcd(msm_dp_panel);
 	if (rc) {
 		DRM_ERROR("read dpcd failed %d\n", rc);
 		return rc;
 	}
 
-	bw_code = drm_dp_link_rate_to_bw_code(dp_panel->link_info.rate);
+	bw_code = drm_dp_link_rate_to_bw_code(msm_dp_panel->link_info.rate);
 	if (!is_link_rate_valid(bw_code) ||
-			!is_lane_count_valid(dp_panel->link_info.num_lanes) ||
-			(bw_code > dp_panel->max_bw_code)) {
-		DRM_ERROR("Illegal link rate=%d lane=%d\n", dp_panel->link_info.rate,
-				dp_panel->link_info.num_lanes);
+			!is_lane_count_valid(msm_dp_panel->link_info.num_lanes) ||
+			(bw_code > msm_dp_panel->max_bw_code)) {
+		DRM_ERROR("Illegal link rate=%d lane=%d\n", msm_dp_panel->link_info.rate,
+				msm_dp_panel->link_info.num_lanes);
 		return -EINVAL;
 	}
 
-	if (drm_dp_is_branch(dp_panel->dpcd)) {
+	if (drm_dp_is_branch(msm_dp_panel->dpcd)) {
 		count = drm_dp_read_sink_count(panel->aux);
 		if (!count) {
 			panel->link->sink_count = 0;
@@ -161,108 +162,119 @@
 		}
 	}
 
-	rc = drm_dp_read_downstream_info(panel->aux, dp_panel->dpcd,
-					 dp_panel->downstream_ports);
-	if (rc)
-		return rc;
+	return drm_dp_read_downstream_info(panel->aux, msm_dp_panel->dpcd,
+			 msm_dp_panel->downstream_ports);
+}
 
-	kfree(dp_panel->edid);
-	dp_panel->edid = NULL;
+int msm_dp_panel_read_edid(struct msm_dp_panel *msm_dp_panel, struct drm_connector *connector)
+{
+	struct msm_dp_panel_private *panel;
+
+	if (!msm_dp_panel || !connector) {
+		DRM_ERROR("invalid input\n");
+		return -EINVAL;
+	}
 
-	dp_panel->edid = drm_get_edid(connector,
-					      &panel->aux->ddc);
-	if (!dp_panel->edid) {
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+
+	drm_edid_free(msm_dp_panel->drm_edid);
+
+	msm_dp_panel->drm_edid = drm_edid_read_ddc(connector, &panel->aux->ddc);
+
+	drm_edid_connector_update(connector, msm_dp_panel->drm_edid);
+
+	if (!msm_dp_panel->drm_edid) {
 		DRM_ERROR("panel edid read failed\n");
 		/* check edid read fail is due to unplug */
-		if (!dp_catalog_link_is_connected(panel->catalog)) {
-			rc = -ETIMEDOUT;
-			goto end;
+		if (!msm_dp_catalog_link_is_connected(panel->catalog)) {
+			return -ETIMEDOUT;
 		}
 	}
 
-end:
-	return rc;
+	return 0;
 }
 
-u32 dp_panel_get_mode_bpp(struct dp_panel *dp_panel,
+u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel,
 		u32 mode_edid_bpp, u32 mode_pclk_khz)
 {
-	struct dp_panel_private *panel;
+	struct msm_dp_panel_private *panel;
 	u32 bpp;
 
-	if (!dp_panel || !mode_edid_bpp || !mode_pclk_khz) {
+	if (!msm_dp_panel || !mode_edid_bpp || !mode_pclk_khz) {
 		DRM_ERROR("invalid input\n");
 		return 0;
 	}
 
-	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
 
-	if (dp_panel->video_test)
-		bpp = dp_link_bit_depth_to_bpp(
+	if (msm_dp_panel->video_test)
+		bpp = msm_dp_link_bit_depth_to_bpp(
 				panel->link->test_video.test_bit_depth);
 	else
-		bpp = dp_panel_get_supported_bpp(dp_panel, mode_edid_bpp,
+		bpp = msm_dp_panel_get_supported_bpp(msm_dp_panel, mode_edid_bpp,
 				mode_pclk_khz);
 
 	return bpp;
 }
 
-int dp_panel_get_modes(struct dp_panel *dp_panel,
+int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel,
 	struct drm_connector *connector)
 {
-	if (!dp_panel) {
+	if (!msm_dp_panel) {
 		DRM_ERROR("invalid input\n");
 		return -EINVAL;
 	}
 
-	if (dp_panel->edid)
-		return dp_panel_update_modes(connector, dp_panel->edid);
+	if (msm_dp_panel->drm_edid)
+		return drm_edid_connector_add_modes(connector);
 
 	return 0;
 }
 
-static u8 dp_panel_get_edid_checksum(struct edid *edid)
+static u8 msm_dp_panel_get_edid_checksum(const struct edid *edid)
 {
 	edid += edid->extensions;
 
 	return edid->checksum;
 }
 
-void dp_panel_handle_sink_request(struct dp_panel *dp_panel)
+void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel)
 {
-	struct dp_panel_private *panel;
+	struct msm_dp_panel_private *panel;
 
-	if (!dp_panel) {
+	if (!msm_dp_panel) {
 		DRM_ERROR("invalid input\n");
 		return;
 	}
 
-	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
 
 	if (panel->link->sink_request & DP_TEST_LINK_EDID_READ) {
+		/* FIXME: get rid of drm_edid_raw() */
+		const struct edid *edid = drm_edid_raw(msm_dp_panel->drm_edid);
 		u8 checksum;
 
-		if (dp_panel->edid)
-			checksum = dp_panel_get_edid_checksum(dp_panel->edid);
+		if (edid)
+			checksum = msm_dp_panel_get_edid_checksum(edid);
 		else
-			checksum = dp_panel->connector->real_edid_checksum;
+			checksum = msm_dp_panel->connector->real_edid_checksum;
 
-		dp_link_send_edid_checksum(panel->link, checksum);
-		dp_link_send_test_response(panel->link);
+		msm_dp_link_send_edid_checksum(panel->link, checksum);
+		msm_dp_link_send_test_response(panel->link);
 	}
 }
 
-void dp_panel_tpg_config(struct dp_panel *dp_panel, bool enable)
+void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable)
 {
-	struct dp_catalog *catalog;
-	struct dp_panel_private *panel;
+	struct msm_dp_catalog *catalog;
+	struct msm_dp_panel_private *panel;
 
-	if (!dp_panel) {
+	if (!msm_dp_panel) {
 		DRM_ERROR("invalid input\n");
 		return;
 	}
 
-	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
 	catalog = panel->catalog;
 
 	if (!panel->panel_on) {
@@ -272,35 +284,87 @@
 	}
 
 	if (!enable) {
-		dp_catalog_panel_tpg_disable(catalog);
+		msm_dp_catalog_panel_tpg_disable(catalog);
 		return;
 	}
 
 	drm_dbg_dp(panel->drm_dev, "calling catalog tpg_enable\n");
-	dp_catalog_panel_tpg_enable(catalog, &panel->dp_panel.dp_mode.drm_mode);
+	msm_dp_catalog_panel_tpg_enable(catalog, &panel->msm_dp_panel.msm_dp_mode.drm_mode);
 }
 
-void dp_panel_dump_regs(struct dp_panel *dp_panel)
+static int msm_dp_panel_setup_vsc_sdp_yuv_420(struct msm_dp_panel *msm_dp_panel)
 {
-	struct dp_catalog *catalog;
-	struct dp_panel_private *panel;
+	struct msm_dp_catalog *catalog;
+	struct msm_dp_panel_private *panel;
+	struct msm_dp_display_mode *msm_dp_mode;
+	struct drm_dp_vsc_sdp vsc_sdp_data;
+	struct dp_sdp vsc_sdp;
+	ssize_t len;
 
-	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+	if (!msm_dp_panel) {
+		DRM_ERROR("invalid input\n");
+		return -EINVAL;
+	}
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
 	catalog = panel->catalog;
+	msm_dp_mode = &msm_dp_panel->msm_dp_mode;
+	catalog->stream_id = msm_dp_panel->stream_id;
+
+	memset(&vsc_sdp_data, 0, sizeof(vsc_sdp_data));
+
+	/* VSC SDP header as per table 2-118 of DP 1.4 specification */
+	vsc_sdp_data.sdp_type = DP_SDP_VSC;
+	vsc_sdp_data.revision = 0x05;
+	vsc_sdp_data.length = 0x13;
+
+	/* VSC SDP Payload for DB16 */
+	vsc_sdp_data.pixelformat = DP_PIXELFORMAT_YUV420;
+	vsc_sdp_data.colorimetry = DP_COLORIMETRY_DEFAULT;
+
+	/* VSC SDP Payload for DB17 */
+	vsc_sdp_data.bpc = msm_dp_mode->bpp / 3;
+	vsc_sdp_data.dynamic_range = DP_DYNAMIC_RANGE_CTA;
+
+	/* VSC SDP Payload for DB18 */
+	vsc_sdp_data.content_type = DP_CONTENT_TYPE_GRAPHICS;
+
+	len = drm_dp_vsc_sdp_pack(&vsc_sdp_data, &vsc_sdp);
+	if (len < 0) {
+		DRM_ERROR("unable to pack vsc sdp\n");
+		return len;
+	}
 
-	dp_catalog_dump_regs(catalog);
+	msm_dp_catalog_panel_enable_vsc_sdp(catalog, &vsc_sdp);
+
+	return 0;
 }
 
-int dp_panel_timing_cfg(struct dp_panel *dp_panel)
+void msm_dp_panel_dump_regs(struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_catalog *catalog;
+	struct msm_dp_panel_private *panel;
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+	catalog = panel->catalog;
+
+	msm_dp_catalog_dump_regs(catalog);
+}
+
+int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel)
 {
 	u32 data, total_ver, total_hor;
-	struct dp_catalog *catalog;
-	struct dp_panel_private *panel;
+	struct msm_dp_catalog *catalog;
+	struct msm_dp_panel_private *panel;
 	struct drm_display_mode *drm_mode;
+	u32 width_blanking;
+	u32 sync_start;
+	u32 msm_dp_active;
+	u32 total;
 
-	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
 	catalog = panel->catalog;
-	drm_mode = &panel->dp_panel.dp_mode.drm_mode;
+	drm_mode = &panel->msm_dp_panel.msm_dp_mode.drm_mode;
 
 	drm_dbg_dp(panel->drm_dev, "width=%d hporch= %d %d %d\n",
 		drm_mode->hdisplay, drm_mode->htotal - drm_mode->hsync_end,
@@ -320,42 +384,46 @@
 	data <<= 16;
 	data |= total_hor;
 
-	catalog->total = data;
+	total = data;
 
 	data = (drm_mode->vtotal - drm_mode->vsync_start);
 	data <<= 16;
 	data |= (drm_mode->htotal - drm_mode->hsync_start);
 
-	catalog->sync_start = data;
+	sync_start = data;
 
 	data = drm_mode->vsync_end - drm_mode->vsync_start;
 	data <<= 16;
-	data |= (panel->dp_panel.dp_mode.v_active_low << 31);
+	data |= (panel->msm_dp_panel.msm_dp_mode.v_active_low << 31);
 	data |= drm_mode->hsync_end - drm_mode->hsync_start;
-	data |= (panel->dp_panel.dp_mode.h_active_low << 15);
+	data |= (panel->msm_dp_panel.msm_dp_mode.h_active_low << 15);
 
-	catalog->width_blanking = data;
+	width_blanking = data;
 
 	data = drm_mode->vdisplay;
 	data <<= 16;
 	data |= drm_mode->hdisplay;
 
-	catalog->dp_active = data;
+	msm_dp_active = data;
+
+	msm_dp_catalog_panel_timing_cfg(catalog, total, sync_start, width_blanking, msm_dp_active);
+
+	if (msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420)
+		msm_dp_panel_setup_vsc_sdp_yuv_420(msm_dp_panel);
 
-	dp_catalog_panel_timing_cfg(catalog);
 	panel->panel_on = true;
 
 	return 0;
 }
 
-int dp_panel_init_panel_info(struct dp_panel *dp_panel)
+int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel)
 {
 	struct drm_display_mode *drm_mode;
-	struct dp_panel_private *panel;
+	struct msm_dp_panel_private *panel;
 
-	drm_mode = &dp_panel->dp_mode.drm_mode;
+	drm_mode = &msm_dp_panel->msm_dp_mode.drm_mode;
 
-	panel = container_of(dp_panel, struct dp_panel_private, dp_panel);
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
 
 	/*
 	 * print resolution info as this is a result
@@ -376,20 +444,76 @@
 			drm_mode->vsync_end - drm_mode->vsync_start);
 	drm_dbg_dp(panel->drm_dev, "pixel clock (KHz)=(%d)\n",
 				drm_mode->clock);
-	drm_dbg_dp(panel->drm_dev, "bpp = %d\n", dp_panel->dp_mode.bpp);
+	drm_dbg_dp(panel->drm_dev, "bpp = %d\n", msm_dp_panel->msm_dp_mode.bpp);
+
+	msm_dp_panel->msm_dp_mode.bpp = msm_dp_panel_get_mode_bpp(msm_dp_panel, msm_dp_panel->msm_dp_mode.bpp,
+						      msm_dp_panel->msm_dp_mode.drm_mode.clock);
 
-	dp_panel->dp_mode.bpp = max_t(u32, 18,
-				min_t(u32, dp_panel->dp_mode.bpp, 30));
 	drm_dbg_dp(panel->drm_dev, "updated bpp = %d\n",
-				dp_panel->dp_mode.bpp);
+				msm_dp_panel->msm_dp_mode.bpp);
+
+	return 0;
+}
+
+static u32 msm_dp_panel_link_frequencies(struct device_node *of_node)
+{
+	struct device_node *endpoint;
+	u64 frequency = 0;
+	int cnt;
+
+	endpoint = of_graph_get_endpoint_by_regs(of_node, 1, 0); /* port@1 */
+	if (!endpoint)
+		return 0;
+
+	cnt = of_property_count_u64_elems(endpoint, "link-frequencies");
+
+	if (cnt > 0)
+		of_property_read_u64_index(endpoint, "link-frequencies",
+						cnt - 1, &frequency);
+	of_node_put(endpoint);
+
+	do_div(frequency,
+		10 * /* from symbol rate to link rate */
+		1000); /* kbytes */
+
+	return frequency;
+}
+
+static int msm_dp_panel_parse_dt(struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_panel_private *panel;
+	struct device_node *of_node;
+	int cnt;
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+	of_node = panel->dev->of_node;
+
+	/*
+	 * data-lanes is the property of msm_dp_out endpoint
+	 */
+	cnt = drm_of_get_data_lanes_count_ep(of_node, 1, 0, 1, DP_MAX_NUM_DP_LANES);
+	if (cnt < 0) {
+		/* legacy code, data-lanes is the property of mdss_dp node */
+		cnt = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
+	}
+
+	if (cnt > 0)
+		msm_dp_panel->max_dp_lanes = cnt;
+	else
+		msm_dp_panel->max_dp_lanes = DP_MAX_NUM_DP_LANES; /* 4 lanes */
+
+	msm_dp_panel->max_dp_link_rate = msm_dp_panel_link_frequencies(of_node);
+	if (!msm_dp_panel->max_dp_link_rate)
+		msm_dp_panel->max_dp_link_rate = DP_LINK_RATE_HBR2;
 
 	return 0;
 }
 
-struct dp_panel *dp_panel_get(struct dp_panel_in *in)
+struct msm_dp_panel *msm_dp_panel_get(struct msm_dp_panel_in *in)
 {
-	struct dp_panel_private *panel;
-	struct dp_panel *dp_panel;
+	struct msm_dp_panel_private *panel;
+	struct msm_dp_panel *msm_dp_panel;
+	int ret;
 
 	if (!in->dev || !in->catalog || !in->aux || !in->link) {
 		DRM_ERROR("invalid input\n");
@@ -405,16 +529,20 @@
 	panel->catalog = in->catalog;
 	panel->link = in->link;
 
-	dp_panel = &panel->dp_panel;
-	dp_panel->max_bw_code = DP_LINK_BW_8_1;
+	msm_dp_panel = &panel->msm_dp_panel;
+	msm_dp_panel->max_bw_code = DP_LINK_BW_8_1;
+
+	ret = msm_dp_panel_parse_dt(msm_dp_panel);
+	if (ret)
+		return ERR_PTR(ret);
 
-	return dp_panel;
+	return msm_dp_panel;
 }
 
-void dp_panel_put(struct dp_panel *dp_panel)
+void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel)
 {
-	if (!dp_panel)
+	if (!msm_dp_panel)
 		return;
 
-	kfree(dp_panel->edid);
+	drm_edid_free(msm_dp_panel->drm_edid);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_panel.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_panel.h
@@ -13,58 +13,68 @@
 
 struct edid;
 
-struct dp_display_mode {
+struct msm_dp_display_mode {
 	struct drm_display_mode drm_mode;
-	u32 capabilities;
 	u32 bpp;
 	u32 h_active_low;
 	u32 v_active_low;
+	bool out_fmt_is_yuv_420;
 };
 
-struct dp_panel_in {
+struct msm_dp_panel_in {
 	struct device *dev;
 	struct drm_dp_aux *aux;
-	struct dp_link *link;
-	struct dp_catalog *catalog;
+	struct msm_dp_link *link;
+	struct msm_dp_catalog *catalog;
 };
 
-struct dp_panel_psr {
+struct msm_dp_panel_psr {
 	u8 version;
 	u8 capabilities;
 };
 
-struct dp_panel {
+struct mst_caps {
+	u32 pbn_no_overhead;
+	u32 pbn;
+};
+
+struct msm_dp_panel {
 	/* dpcd raw data */
 	u8 dpcd[DP_RECEIVER_CAP_SIZE];
 	u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
 
-	struct dp_link_info link_info;
-	struct drm_dp_desc desc;
-	struct edid *edid;
+	struct msm_dp_link_info link_info;
+	const struct drm_edid *drm_edid;
 	struct drm_connector *connector;
-	struct dp_display_mode dp_mode;
-	struct dp_panel_psr psr_cap;
+	struct msm_dp_display_mode msm_dp_mode;
+	struct msm_dp_panel_psr psr_cap;
 	bool video_test;
+	bool vsc_sdp_supported;
+
+	enum msm_dp_stream_id stream_id;
 
-	u32 vic;
 	u32 max_dp_lanes;
 	u32 max_dp_link_rate;
 
 	u32 max_bw_code;
+
+	struct mst_caps mst_caps;
 };
 
-int dp_panel_init_panel_info(struct dp_panel *dp_panel);
-int dp_panel_deinit(struct dp_panel *dp_panel);
-int dp_panel_timing_cfg(struct dp_panel *dp_panel);
-void dp_panel_dump_regs(struct dp_panel *dp_panel);
-int dp_panel_read_sink_caps(struct dp_panel *dp_panel,
+int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel);
+int msm_dp_panel_deinit(struct msm_dp_panel *msm_dp_panel);
+int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel);
+void msm_dp_panel_dump_regs(struct msm_dp_panel *msm_dp_panel);
+u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel, u32 mode_max_bpp,
+	u32 mode_pclk_khz);
+int msm_dp_panel_read_link_caps(struct msm_dp_panel *msm_dp_panel,
 		struct drm_connector *connector);
-u32 dp_panel_get_mode_bpp(struct dp_panel *dp_panel, u32 mode_max_bpp,
-			u32 mode_pclk_khz);
-int dp_panel_get_modes(struct dp_panel *dp_panel,
+int msm_dp_panel_read_edid(struct msm_dp_panel *msm_dp_panel, struct drm_connector *connector);
+int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel,
 		struct drm_connector *connector);
-void dp_panel_handle_sink_request(struct dp_panel *dp_panel);
-void dp_panel_tpg_config(struct dp_panel *dp_panel, bool enable);
+void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel);
+void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable);
+bool msm_dp_panel_read_mst_cap(struct msm_dp_panel *msm_dp_panel);
 
 /**
  * is_link_rate_valid() - validates the link rate
@@ -81,7 +91,7 @@
 }
 
 /**
- * dp_link_is_lane_count_valid() - validates the lane count
+ * msm_dp_link_is_lane_count_valid() - validates the lane count
  * @lane_count: lane count requested by the sink
  *
  * Returns true if the requested lane count is supported.
@@ -93,6 +103,6 @@
 		lane_count == 4);
 }
 
-struct dp_panel *dp_panel_get(struct dp_panel_in *in);
-void dp_panel_put(struct dp_panel *dp_panel);
+struct msm_dp_panel *msm_dp_panel_get(struct msm_dp_panel_in *in);
+void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel);
 #endif /* _DP_PANEL_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_reg.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_reg.h
@@ -6,6 +6,9 @@
 #ifndef _DP_REG_H_
 #define _DP_REG_H_
 
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+
 /* DP_TX Registers */
 #define REG_DP_HW_VERSION			(0x00000000)
 
@@ -21,8 +24,9 @@
 #define REG_DP_INTR_STATUS			(0x00000020)
 #define REG_DP_INTR_STATUS2			(0x00000024)
 #define REG_DP_INTR_STATUS3			(0x00000028)
-
 #define REG_DP_INTR_STATUS4			(0x0000002C)
+#define REG_DP_INTR_STATUS5			(0x00000034)
+
 #define PSR_UPDATE_INT				(0x00000001)
 #define PSR_CAPTURE_INT				(0x00000004)
 #define PSR_EXIT_INT				(0x00000010)
@@ -102,9 +106,13 @@
 #define DP_MAINLINK_CTRL_ENABLE			(0x00000001)
 #define DP_MAINLINK_CTRL_RESET			(0x00000002)
 #define DP_MAINLINK_CTRL_SW_BYPASS_SCRAMBLER	(0x00000010)
+#define DP_MAINLINK_CTRL_FLUSH_MODE_MASK	GENMASK(24, 23)
+#define DP_MAINLINK_FLUSH_MODE_UPDATE_SDP	FIELD_PREP(DP_MAINLINK_CTRL_FLUSH_MODE_MASK, 1)
+#define DP_MAINLINK_FLUSH_MODE_SDE_PERIPH_UPDATE	FIELD_PREP(DP_MAINLINK_CTRL_FLUSH_MODE_MASK, 3)
 #define DP_MAINLINK_FB_BOUNDARY_SEL		(0x02000000)
 
 #define REG_DP_STATE_CTRL			(0x00000004)
+#define REG_DP_MST2_MST3_STATE_CTRL		(0x00000000)
 #define DP_STATE_CTRL_LINK_TRAINING_PATTERN1	(0x00000001)
 #define DP_STATE_CTRL_LINK_TRAINING_PATTERN2	(0x00000002)
 #define DP_STATE_CTRL_LINK_TRAINING_PATTERN3	(0x00000004)
@@ -116,6 +124,8 @@
 #define DP_STATE_CTRL_PUSH_IDLE			(0x00000100)
 
 #define REG_DP_CONFIGURATION_CTRL		(0x00000008)
+#define REG_DP1_CONFIGURATION_CTRL		(0x00000400)
+#define REG_DP_MST2_MST3_CONFIGURATION_CTRL	(0x00000034)
 #define DP_CONFIGURATION_CTRL_SYNC_ASYNC_CLK	(0x00000001)
 #define DP_CONFIGURATION_CTRL_STATIC_DYNAMIC_CN (0x00000002)
 #define DP_CONFIGURATION_CTRL_P_INTERLACED	(0x00000004)
@@ -132,16 +142,28 @@
 #define DP_CONFIGURATION_CTRL_LSCLK_DIV_SHIFT	(0x0D)
 
 #define REG_DP_SOFTWARE_MVID			(0x00000010)
+#define REG_DP1_SOFTWARE_MVID			(0x00000414)
+#define REG_MST2_MST3_SOFTWARE_MVID		(0x00000040)
 #define REG_DP_SOFTWARE_NVID			(0x00000018)
+#define REG_DP1_SOFTWARE_NVID			(0x00000418)
+#define REG_MST2_MST3_SOFTWARE_NVID		(0x00000044)
 #define REG_DP_TOTAL_HOR_VER			(0x0000001C)
+#define REG_DP1_TOTAL_HOR_VER			(0x0000041C)
+#define REG_DP_MST2_MST3_TOTAL_HOR_VER		(0x00000048)
 #define REG_DP_START_HOR_VER_FROM_SYNC		(0x00000020)
+#define REG_DP_MST2_MST3_START_HOR_VER_FROM_SYNC	(0x0000004C)
 #define REG_DP_HSYNC_VSYNC_WIDTH_POLARITY	(0x00000024)
+#define REG_DP_MST2_MST3_HSYNC_VSYNC_WIDTH_POLARITY	(0x00000050)
 #define REG_DP_ACTIVE_HOR_VER			(0x00000028)
-
+#define REG_DP_MST2_MST3_ACTIVE_HOR_VER			(0x00000054)
 #define REG_DP_MISC1_MISC0			(0x0000002C)
+#define REG_DP1_MISC1_MISC0			(0x0000042C)
+#define REG_DP_MST2_MST3_MISC1_MISC0		(0x00000058)
+
 #define DP_MISC0_SYNCHRONOUS_CLK		(0x00000001)
 #define DP_MISC0_COLORIMETRY_CFG_SHIFT		(0x00000001)
 #define DP_MISC0_TEST_BITS_DEPTH_SHIFT		(0x00000005)
+#define DP_MISC1_VSC_SDP			(0x00004000)
 
 #define DP_MISC0_COLORIMERY_CFG_LEGACY_RGB	(0)
 #define DP_MISC0_COLORIMERY_CFG_CEA_RGB		(0x04)
@@ -204,14 +226,24 @@
 #define MMSS_DP_AUDIO_CTRL_RESET		(0x00000214)
 
 #define MMSS_DP_SDP_CFG				(0x00000228)
+#define MMSS_DP1_SDP_CFG			(0x000004E0)
+#define MMSS_DP_MST2_MST3_SDP_CFG		(0x0000010c)
+#define GEN0_SDP_EN				(0x00020000)
 #define MMSS_DP_SDP_CFG2			(0x0000022C)
+#define MMSS_DP1_SDP_CFG2			(0x000004E4)
+#define MMSS_DP_MST2_MST3_SDP_CFG2		(0x0000011c)
+
 #define MMSS_DP_AUDIO_TIMESTAMP_0		(0x00000230)
 #define MMSS_DP_AUDIO_TIMESTAMP_1		(0x00000234)
+#define GENERIC0_SDPSIZE_VALID			(0x00010000)
 
 #define MMSS_DP_AUDIO_STREAM_0			(0x00000240)
 #define MMSS_DP_AUDIO_STREAM_1			(0x00000244)
 
 #define MMSS_DP_SDP_CFG3			(0x0000024c)
+#define MMSS_DP1_SDP_CFG3			(0x000004E8)
+#define MMSS_DP_MST2_MST3_SDP_CFG3		(0x00000114)
+
 #define UPDATE_SDP				(0x00000001)
 
 #define MMSS_DP_EXTENSION_0			(0x00000250)
@@ -241,8 +273,11 @@
 #define MMSS_DP_AUDIO_INFOFRAME_2		(0x000002B0)
 
 #define MMSS_DP_GENERIC0_0			(0x00000300)
+#define MMSS_DP_MST2_MST3_GENERIC0_0		(0x000000BC)
 #define MMSS_DP_GENERIC0_1			(0x00000304)
+#define MMSS_DP_MST2_MST3_GENERIC0_1		(0x000000C0)
 #define MMSS_DP_GENERIC0_2			(0x00000308)
+#define MMSS_DP_MST2_MST3_GENERIC0_2		(0x000000C4)
 #define MMSS_DP_GENERIC0_3			(0x0000030C)
 #define MMSS_DP_GENERIC0_4			(0x00000310)
 #define MMSS_DP_GENERIC0_5			(0x00000314)
@@ -261,6 +296,8 @@
 #define MMSS_DP_GENERIC1_8			(0x00000348)
 #define MMSS_DP_GENERIC1_9			(0x0000034C)
 
+#define MMSS_DP1_GENERIC0_0			(0x00000490)
+
 #define MMSS_DP_VSCEXT_0			(0x000002D0)
 #define MMSS_DP_VSCEXT_1			(0x000002D4)
 #define MMSS_DP_VSCEXT_2			(0x000002D8)
@@ -310,6 +347,18 @@
 #define REG_DP_PHY_AUX_BIST_CFG			(0x00000050)
 #define REG_DP_PHY_AUX_INTERRUPT_STATUS         (0x000000BC)
 
+/* DP MST related registers */
+#define REG_DP_MST_ACT                          (0x00000500)
+#define REG_DP_DP0_RG				(0x000004F8)
+#define REG_DP_DP1_RG				(0x000004FC)
+#define REG_DP_MST2_MST3_DP_RG			(0X0000011C)
+#define REG_DP_DP0_TIMESLOT_1_32		(0x00000404)
+#define REG_DP_DP0_TIMESLOT_33_63		(0x00000408)
+#define REG_DP_DP1_TIMESLOT_1_32		(0x0000040C)
+#define REG_DP_DP1_TIMESLOT_33_63		(0x00000410)
+#define REG_DP_DP2_DP3_TIMESLOT_1_32		(0x00000038)
+#define REG_DP_DP2_DP3_TIMESLOT_33_63		(0x0000003C)
+
 /* DP HDCP 1.3 registers */
 #define DP_HDCP_CTRL                                   (0x0A0)
 #define DP_HDCP_STATUS                                 (0x0A4)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_utils.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_utils.c
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/types.h>
+
+#include "dp_utils.h"
+
+#define DP_SDP_HEADER_SIZE		8
+
+u8 msm_dp_utils_get_g0_value(u8 data)
+{
+	u8 c[4];
+	u8 g[4];
+	u8 ret_data = 0;
+	u8 i;
+
+	for (i = 0; i < 4; i++)
+		c[i] = (data >> i) & 0x01;
+
+	g[0] = c[3];
+	g[1] = c[0] ^ c[3];
+	g[2] = c[1];
+	g[3] = c[2];
+
+	for (i = 0; i < 4; i++)
+		ret_data = ((g[i] & 0x01) << i) | ret_data;
+
+	return ret_data;
+}
+
+u8 msm_dp_utils_get_g1_value(u8 data)
+{
+	u8 c[4];
+	u8 g[4];
+	u8 ret_data = 0;
+	u8 i;
+
+	for (i = 0; i < 4; i++)
+		c[i] = (data >> i) & 0x01;
+
+	g[0] = c[0] ^ c[3];
+	g[1] = c[0] ^ c[1] ^ c[3];
+	g[2] = c[1] ^ c[2];
+	g[3] = c[2] ^ c[3];
+
+	for (i = 0; i < 4; i++)
+		ret_data = ((g[i] & 0x01) << i) | ret_data;
+
+	return ret_data;
+}
+
+u8 msm_dp_utils_calculate_parity(u32 data)
+{
+	u8 x0 = 0;
+	u8 x1 = 0;
+	u8 ci = 0;
+	u8 iData = 0;
+	u8 i = 0;
+	u8 parity_byte;
+	u8 num_byte = (data & 0xFF00) > 0 ? 8 : 2;
+
+	for (i = 0; i < num_byte; i++) {
+		iData = (data >> i * 4) & 0xF;
+
+		ci = iData ^ x1;
+		x1 = x0 ^ msm_dp_utils_get_g1_value(ci);
+		x0 = msm_dp_utils_get_g0_value(ci);
+	}
+
+	parity_byte = x1 | (x0 << 4);
+
+	return parity_byte;
+}
+
+ssize_t msm_dp_utils_pack_sdp_header(struct dp_sdp_header *sdp_header, u32 *header_buff)
+{
+	size_t length;
+
+	length = sizeof(header_buff);
+	if (length < DP_SDP_HEADER_SIZE)
+		return -ENOSPC;
+
+	header_buff[0] = FIELD_PREP(HEADER_0_MASK, sdp_header->HB0) |
+		FIELD_PREP(PARITY_0_MASK, msm_dp_utils_calculate_parity(sdp_header->HB0)) |
+		FIELD_PREP(HEADER_1_MASK, sdp_header->HB1) |
+		FIELD_PREP(PARITY_1_MASK, msm_dp_utils_calculate_parity(sdp_header->HB1));
+
+	header_buff[1] = FIELD_PREP(HEADER_2_MASK, sdp_header->HB2) |
+		FIELD_PREP(PARITY_2_MASK, msm_dp_utils_calculate_parity(sdp_header->HB2)) |
+		FIELD_PREP(HEADER_3_MASK, sdp_header->HB3) |
+		FIELD_PREP(PARITY_3_MASK, msm_dp_utils_calculate_parity(sdp_header->HB3));
+
+	return length;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dp/dp_utils.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dp/dp_utils.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DP_UTILS_H_
+#define _DP_UTILS_H_
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <drm/display/drm_dp_helper.h>
+
+#define HEADER_BYTE_0_BIT	 0
+#define PARITY_BYTE_0_BIT	 8
+#define HEADER_BYTE_1_BIT	16
+#define PARITY_BYTE_1_BIT	24
+#define HEADER_BYTE_2_BIT	 0
+#define PARITY_BYTE_2_BIT	 8
+#define HEADER_BYTE_3_BIT	16
+#define PARITY_BYTE_3_BIT	24
+
+#define HEADER_0_MASK	    GENMASK(7, 0)
+#define PARITY_0_MASK	    GENMASK(15, 8)
+#define HEADER_1_MASK	    GENMASK(23, 16)
+#define PARITY_1_MASK	    GENMASK(31, 24)
+#define HEADER_2_MASK	    GENMASK(7, 0)
+#define PARITY_2_MASK	    GENMASK(15, 8)
+#define HEADER_3_MASK	    GENMASK(23, 16)
+#define PARITY_3_MASK	    GENMASK(31, 24)
+
+u8 msm_dp_utils_get_g0_value(u8 data);
+u8 msm_dp_utils_get_g1_value(u8 data);
+u8 msm_dp_utils_calculate_parity(u32 data);
+ssize_t msm_dp_utils_pack_sdp_header(struct dp_sdp_header *sdp_header, u32 *header_buff);
+
+#endif /* _DP_UTILS_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -221,6 +221,22 @@
 	},
 };
 
+static const struct regulator_bulk_data sa8775_dsi_regulators[] = {
+	{ .supply = "vdda", .init_load_uA = 30100 },    /* 1.2 V */
+	{ .supply = "refgen" },
+};
+
+static const struct msm_dsi_config sa8775_dsi_cfg = {
+	.io_offset = DSI_6G_REG_SHIFT,
+	.regulator_data = sa8775_dsi_regulators,
+	.num_regulators = ARRAY_SIZE(sa8775_dsi_regulators),
+	.bus_clk_names = dsi_v2_4_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_v2_4_clk_names),
+	.io_start = {
+		{ 0xae94000, 0xae96000 },
+	},
+};
+
 static const struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {
 	.link_clk_set_rate = dsi_link_clk_set_rate_v2,
 	.link_clk_enable = dsi_link_clk_enable_v2,
@@ -294,6 +310,8 @@
 		&sc7280_dsi_cfg, &msm_dsi_6g_v2_host_ops},
 	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_6_0,
 		&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_5_1,
+		&sa8775_dsi_cfg, &msm_dsi_6g_v2_host_ops},
 	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_7_0,
 		&sm8550_dsi_cfg, &msm_dsi_6g_v2_host_ops},
 	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_8_0,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dsi/dsi_cfg.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dsi/dsi_cfg.h
@@ -26,6 +26,7 @@
 #define MSM_DSI_6G_VER_MINOR_V2_4_0	0x20040000
 #define MSM_DSI_6G_VER_MINOR_V2_4_1	0x20040001
 #define MSM_DSI_6G_VER_MINOR_V2_5_0	0x20050000
+#define MSM_DSI_6G_VER_MINOR_V2_5_1	0x20050001
 #define MSM_DSI_6G_VER_MINOR_V2_6_0	0x20060000
 #define MSM_DSI_6G_VER_MINOR_V2_7_0	0x20070000
 #define MSM_DSI_6G_VER_MINOR_V2_8_0	0x20080000
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -366,8 +366,8 @@
 {
 	int ret;
 
-	DBG("Set clk rates: pclk=%d, byteclk=%lu",
-		msm_host->mode->clock, msm_host->byte_clk_rate);
+	DBG("Set clk rates: pclk=%lu, byteclk=%lu",
+	    msm_host->pixel_clk_rate, msm_host->byte_clk_rate);
 
 	ret = dev_pm_opp_set_rate(&msm_host->pdev->dev,
 				  msm_host->byte_clk_rate);
@@ -440,9 +440,9 @@
 {
 	int ret;
 
-	DBG("Set clk rates: pclk=%d, byteclk=%lu, esc_clk=%lu, dsi_src_clk=%lu",
-		msm_host->mode->clock, msm_host->byte_clk_rate,
-		msm_host->esc_clk_rate, msm_host->src_clk_rate);
+	DBG("Set clk rates: pclk=%lu, byteclk=%lu, esc_clk=%lu, dsi_src_clk=%lu",
+	    msm_host->pixel_clk_rate, msm_host->byte_clk_rate,
+	    msm_host->esc_clk_rate, msm_host->src_clk_rate);
 
 	ret = clk_set_rate(msm_host->byte_clk, msm_host->byte_clk_rate);
 	if (ret) {
@@ -537,7 +537,7 @@
 
 	int new_htotal = mode->htotal - mode->hdisplay + new_hdisplay;
 
-	return new_htotal * mode->vtotal * drm_mode_vrefresh(mode);
+	return mult_frac(mode->clock * 1000u, new_htotal, mode->htotal);
 }
 
 static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode,
@@ -545,7 +545,7 @@
 {
 	unsigned long pclk_rate;
 
-	pclk_rate = mode->clock * 1000;
+	pclk_rate = mode->clock * 1000u;
 
 	if (dsc)
 		pclk_rate = dsi_adjust_pclk_for_compression(mode, dsc);
@@ -745,6 +745,8 @@
 		data |= DSI_VID_CFG0_TRAFFIC_MODE(dsi_get_traffic_mode(flags));
 		data |= DSI_VID_CFG0_DST_FORMAT(dsi_get_vid_fmt(mipi_fmt));
 		data |= DSI_VID_CFG0_VIRT_CHANNEL(msm_host->channel);
+		if (msm_dsi_host_is_wide_bus_enabled(&msm_host->base))
+			data |= DSI_VID_CFG0_DATABUS_WIDEN;
 		dsi_write(msm_host, REG_DSI_VID_CFG0, data);
 
 		/* Do not swap RGB colors */
@@ -769,7 +771,6 @@
 			if (cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V1_3)
 				data |= DSI_CMD_MODE_MDP_CTRL2_BURST_MODE;
 
-			/* TODO: Allow for video-mode support once tested/fixed */
 			if (msm_dsi_host_is_wide_bus_enabled(&msm_host->base))
 				data |= DSI_CMD_MODE_MDP_CTRL2_DATABUS_WIDEN;
 
@@ -847,6 +848,7 @@
 	u32 slice_per_intf, total_bytes_per_intf;
 	u32 pkt_per_line;
 	u32 eol_byte_num;
+	u32 bytes_per_pkt;
 
 	/* first calculate dsc parameters and then program
 	 * compress mode registers
@@ -854,6 +856,7 @@
 	slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
 
 	total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
+	bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
 
 	eol_byte_num = total_bytes_per_intf % 3;
 
@@ -891,6 +894,7 @@
 		dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, reg_ctrl);
 		dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, reg_ctrl2);
 	} else {
+		reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_WC(bytes_per_pkt);
 		dsi_write(msm_host, REG_DSI_VIDEO_COMPRESSION_MODE_CTRL, reg);
 	}
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c
@@ -583,6 +583,8 @@
 	  .data = &dsi_phy_7nm_6375_cfgs },
 	{ .compatible = "qcom,sm8350-dsi-phy-5nm",
 	  .data = &dsi_phy_5nm_8350_cfgs },
+	{ .compatible = "qcom,sa8775p-dsi-phy-5nm",
+	  .data = &dsi_phy_5nm_8775_cfgs },
 	{ .compatible = "qcom,sm8450-dsi-phy-5nm",
 	  .data = &dsi_phy_5nm_8450_cfgs },
 	{ .compatible = "qcom,sm8550-dsi-phy-4nm",
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h
@@ -60,6 +60,7 @@
 extern const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8350_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8775_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs;
 extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8650_cfgs;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
@@ -135,7 +135,7 @@
 			config->pll_clock_inverters = 0x00;
 		else
 			config->pll_clock_inverters = 0x40;
-	} else {
+	} else if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
 		if (pll_freq <= 1000000000ULL)
 			config->pll_clock_inverters = 0xa0;
 		else if (pll_freq <= 2500000000ULL)
@@ -144,6 +144,16 @@
 			config->pll_clock_inverters = 0x00;
 		else
 			config->pll_clock_inverters = 0x40;
+	} else {
+		/* 4.2, 4.3 */
+		if (pll_freq <= 1000000000ULL)
+			config->pll_clock_inverters = 0xa0;
+		else if (pll_freq <= 2500000000ULL)
+			config->pll_clock_inverters = 0x20;
+		else if (pll_freq <= 3500000000ULL)
+			config->pll_clock_inverters = 0x00;
+		else
+			config->pll_clock_inverters = 0x40;
 	}
 
 	config->decimal_div_start = dec;
@@ -1121,6 +1131,10 @@
 	{ .supply = "vdds", .init_load_uA = 37550 },
 };
 
+static const struct regulator_bulk_data dsi_phy_7nm_115000uA_regulators[] = {
+	{ .supply = "vdds", .init_load_uA = 115000 },
+};
+
 static const struct regulator_bulk_data dsi_phy_7nm_98000uA_regulators[] = {
 	{ .supply = "vdds", .init_load_uA = 98000 },
 };
@@ -1224,6 +1238,29 @@
 	.ops = {
 		.enable = dsi_7nm_phy_enable,
 		.disable = dsi_7nm_phy_disable,
+		.pll_init = dsi_pll_7nm_init,
+		.save_pll_state = dsi_7nm_pll_save_state,
+		.restore_pll_state = dsi_7nm_pll_restore_state,
+		.set_continuous_clock = dsi_7nm_set_continuous_clock,
+	},
+	.min_pll_rate = 600000000UL,
+#ifdef CONFIG_64BIT
+	.max_pll_rate = 5000000000UL,
+#else
+	.max_pll_rate = ULONG_MAX,
+#endif
+	.io_start = { 0xae94400, 0xae96400 },
+	.num_dsi_phy = 2,
+	.quirks = DSI_PHY_7NM_QUIRK_V4_2,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_5nm_8775_cfgs = {
+	.has_phy_lane = true,
+	.regulator_data = dsi_phy_7nm_115000uA_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_115000uA_regulators),
+	.ops = {
+		.enable = dsi_7nm_phy_enable,
+		.disable = dsi_7nm_phy_disable,
 		.pll_init = dsi_pll_7nm_init,
 		.save_pll_state = dsi_7nm_pll_save_state,
 		.restore_pll_state = dsi_7nm_pll_restore_state,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -137,6 +137,7 @@
 	MSM_HDMI_PHY_8960,
 	MSM_HDMI_PHY_8x74,
 	MSM_HDMI_PHY_8996,
+	MSM_HDMI_PHY_8998,
 	MSM_HDMI_PHY_MAX,
 };
 
@@ -154,6 +155,7 @@
 extern const struct hdmi_phy_cfg msm_hdmi_phy_8960_cfg;
 extern const struct hdmi_phy_cfg msm_hdmi_phy_8x74_cfg;
 extern const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg;
+extern const struct hdmi_phy_cfg msm_hdmi_phy_8998_cfg;
 
 struct hdmi_phy {
 	struct platform_device *pdev;
@@ -184,6 +186,7 @@
 #ifdef CONFIG_COMMON_CLK
 int msm_hdmi_pll_8960_init(struct platform_device *pdev);
 int msm_hdmi_pll_8996_init(struct platform_device *pdev);
+int msm_hdmi_pll_8998_init(struct platform_device *pdev);
 #else
 static inline int msm_hdmi_pll_8960_init(struct platform_device *pdev)
 {
@@ -194,6 +197,11 @@
 {
 	return -ENODEV;
 }
+
+static inline int msm_hdmi_pll_8998_init(struct platform_device *pdev)
+{
+	return -ENODEV;
+}
 #endif
 
 /*
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
@@ -118,6 +118,9 @@
 	case MSM_HDMI_PHY_8996:
 		ret = msm_hdmi_pll_8996_init(pdev);
 		break;
+	case MSM_HDMI_PHY_8998:
+		ret = msm_hdmi_pll_8998_init(pdev);
+		break;
 	/*
 	 * we don't have PLL support for these, don't report an error for now
 	 */
@@ -193,6 +196,8 @@
 	  .data = &msm_hdmi_phy_8x74_cfg },
 	{ .compatible = "qcom,hdmi-phy-8996",
 	  .data = &msm_hdmi_phy_8996_cfg },
+	{ .compatible = "qcom,hdmi-phy-8998",
+	  .data = &msm_hdmi_phy_8998_cfg },
 	{}
 };
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/hdmi/hdmi_phy_8998.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/hdmi/hdmi_phy_8998.c
@@ -0,0 +1,779 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Freebox SAS
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+
+#include "hdmi.h"
+
+#define HDMI_VCO_MAX_FREQ			12000000000UL
+#define HDMI_VCO_MIN_FREQ			8000000000UL
+
+#define HDMI_PCLK_MAX_FREQ			600000000
+#define HDMI_PCLK_MIN_FREQ			25000000
+
+#define HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD	3400000000UL
+#define HDMI_DIG_FREQ_BIT_CLK_THRESHOLD		1500000000UL
+#define HDMI_MID_FREQ_BIT_CLK_THRESHOLD		750000000UL
+#define HDMI_CORECLK_DIV			5
+#define HDMI_DEFAULT_REF_CLOCK			19200000
+#define HDMI_PLL_CMP_CNT			1024
+
+#define HDMI_PLL_POLL_MAX_READS			100
+#define HDMI_PLL_POLL_TIMEOUT_US		150
+
+#define HDMI_NUM_TX_CHANNEL			4
+
+struct hdmi_pll_8998 {
+	struct platform_device *pdev;
+	struct clk_hw clk_hw;
+	unsigned long rate;
+
+	/* pll mmio base */
+	void __iomem *mmio_qserdes_com;
+	/* tx channel base */
+	void __iomem *mmio_qserdes_tx[HDMI_NUM_TX_CHANNEL];
+};
+
+#define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8998, clk_hw)
+
+struct hdmi_8998_phy_pll_reg_cfg {
+	u32 com_svs_mode_clk_sel;
+	u32 com_hsclk_sel;
+	u32 com_pll_cctrl_mode0;
+	u32 com_pll_rctrl_mode0;
+	u32 com_cp_ctrl_mode0;
+	u32 com_dec_start_mode0;
+	u32 com_div_frac_start1_mode0;
+	u32 com_div_frac_start2_mode0;
+	u32 com_div_frac_start3_mode0;
+	u32 com_integloop_gain0_mode0;
+	u32 com_integloop_gain1_mode0;
+	u32 com_lock_cmp_en;
+	u32 com_lock_cmp1_mode0;
+	u32 com_lock_cmp2_mode0;
+	u32 com_lock_cmp3_mode0;
+	u32 com_core_clk_en;
+	u32 com_coreclk_div_mode0;
+
+	u32 tx_lx_tx_band[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_tx_drv_lvl[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_tx_emp_post1_lvl[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_pre_driver_1[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_pre_driver_2[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_res_code_offset[HDMI_NUM_TX_CHANNEL];
+
+	u32 phy_mode;
+};
+
+struct hdmi_8998_post_divider {
+	u64 vco_freq;
+	int hsclk_divsel;
+	int vco_ratio;
+	int tx_band_sel;
+	int half_rate_mode;
+};
+
+static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8998 *pll)
+{
+	return platform_get_drvdata(pll->pdev);
+}
+
+static inline void hdmi_pll_write(struct hdmi_pll_8998 *pll, int offset,
+				  u32 data)
+{
+	writel(data, pll->mmio_qserdes_com + offset);
+}
+
+static inline u32 hdmi_pll_read(struct hdmi_pll_8998 *pll, int offset)
+{
+	return readl(pll->mmio_qserdes_com + offset);
+}
+
+static inline void hdmi_tx_chan_write(struct hdmi_pll_8998 *pll, int channel,
+				      int offset, int data)
+{
+	 writel(data, pll->mmio_qserdes_tx[channel] + offset);
+}
+
+static inline u32 pll_get_cpctrl(u64 frac_start, unsigned long ref_clk,
+				 bool gen_ssc)
+{
+	if ((frac_start != 0) || gen_ssc)
+		return 0x8;
+
+	return 0x30;
+}
+
+static inline u32 pll_get_rctrl(u64 frac_start, bool gen_ssc)
+{
+	if ((frac_start != 0) || gen_ssc)
+		return 0x16;
+
+	return 0x18;
+}
+
+static inline u32 pll_get_cctrl(u64 frac_start, bool gen_ssc)
+{
+	if ((frac_start != 0) || gen_ssc)
+		return 0x34;
+
+	return 0x2;
+}
+
+static inline u32 pll_get_integloop_gain(u64 frac_start, u64 bclk, u32 ref_clk,
+					 bool gen_ssc)
+{
+	int digclk_divsel = bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2;
+	u64 base;
+
+	if ((frac_start != 0) || gen_ssc)
+		base = 0x3F;
+	else
+		base = 0xC4;
+
+	base <<= (digclk_divsel == 2 ? 1 : 0);
+
+	return (base <= 2046 ? base : 2046);
+}
+
+static inline u32 pll_get_pll_cmp(u64 fdata, unsigned long ref_clk)
+{
+	u64 dividend = HDMI_PLL_CMP_CNT * fdata;
+	u32 divisor = ref_clk * 10;
+	u32 rem;
+
+	rem = do_div(dividend, divisor);
+	if (rem > (divisor >> 1))
+		dividend++;
+
+	return dividend - 1;
+}
+
+static inline u64 pll_cmp_to_fdata(u32 pll_cmp, unsigned long ref_clk)
+{
+	u64 fdata = ((u64)pll_cmp) * ref_clk * 10;
+
+	do_div(fdata, HDMI_PLL_CMP_CNT);
+
+	return fdata;
+}
+
+#define HDMI_REF_CLOCK_HZ ((u64)19200000)
+#define HDMI_MHZ_TO_HZ ((u64)1000000)
+static int pll_get_post_div(struct hdmi_8998_post_divider *pd, u64 bclk)
+{
+	u32 const ratio_list[] = {1, 2, 3, 4, 5, 6,
+				     9, 10, 12, 15, 25};
+	u32 const band_list[] = {0, 1, 2, 3};
+	u32 const sz_ratio = ARRAY_SIZE(ratio_list);
+	u32 const sz_band = ARRAY_SIZE(band_list);
+	u32 const cmp_cnt = 1024;
+	u32 const th_min = 500, th_max = 1000;
+	u32 half_rate_mode = 0;
+	u32 list_elements;
+	int optimal_index;
+	u32 i, j, k;
+	u32 found_hsclk_divsel = 0, found_vco_ratio;
+	u32 found_tx_band_sel;
+	u64 const min_freq = HDMI_VCO_MIN_FREQ, max_freq = HDMI_VCO_MAX_FREQ;
+	u64 freq_list[ARRAY_SIZE(ratio_list) * ARRAY_SIZE(band_list)];
+	u64 found_vco_freq;
+	u64 freq_optimal;
+
+find_optimal_index:
+	freq_optimal = max_freq;
+	optimal_index = -1;
+	list_elements = 0;
+
+	for (i = 0; i < sz_ratio; i++) {
+		for (j = 0; j < sz_band; j++) {
+			u64 freq = div_u64(bclk, (1 << half_rate_mode));
+
+			freq *= (ratio_list[i] * (1 << band_list[j]));
+			freq_list[list_elements++] = freq;
+		}
+	}
+
+	for (k = 0; k < ARRAY_SIZE(freq_list); k++) {
+		u32 const clks_pll_div = 2, core_clk_div = 5;
+		u32 const rng1 = 16, rng2 = 8;
+		u32 th1, th2;
+		u64 core_clk, rvar1, rem;
+
+		core_clk = div_u64(freq_list[k],
+				   ratio_list[k / sz_band] * clks_pll_div *
+				   core_clk_div);
+
+		rvar1 = HDMI_REF_CLOCK_HZ * rng1 * HDMI_MHZ_TO_HZ;
+		rvar1 = div64_u64_rem(rvar1, (cmp_cnt * core_clk), &rem);
+		if (rem > ((cmp_cnt * core_clk) >> 1))
+			rvar1++;
+		th1 = rvar1;
+
+		rvar1 = HDMI_REF_CLOCK_HZ * rng2 * HDMI_MHZ_TO_HZ;
+		rvar1 = div64_u64_rem(rvar1, (cmp_cnt * core_clk), &rem);
+		if (rem > ((cmp_cnt * core_clk) >> 1))
+			rvar1++;
+		th2 = rvar1;
+
+		if (freq_list[k] >= min_freq &&
+				freq_list[k] <= max_freq) {
+			if ((th1 >= th_min && th1 <= th_max) ||
+					(th2 >= th_min && th2 <= th_max)) {
+				if (freq_list[k] <= freq_optimal) {
+					freq_optimal = freq_list[k];
+					optimal_index = k;
+				}
+			}
+		}
+	}
+
+	if (optimal_index == -1) {
+		if (!half_rate_mode) {
+			half_rate_mode = 1;
+			goto find_optimal_index;
+		} else {
+			return -EINVAL;
+		}
+	} else {
+		found_vco_ratio = ratio_list[optimal_index / sz_band];
+		found_tx_band_sel = band_list[optimal_index % sz_band];
+		found_vco_freq = freq_optimal;
+	}
+
+	switch (found_vco_ratio) {
+	case 1:
+		found_hsclk_divsel = 15;
+		break;
+	case 2:
+		found_hsclk_divsel = 0;
+		break;
+	case 3:
+		found_hsclk_divsel = 4;
+		break;
+	case 4:
+		found_hsclk_divsel = 8;
+		break;
+	case 5:
+		found_hsclk_divsel = 12;
+		break;
+	case 6:
+		found_hsclk_divsel = 1;
+		break;
+	case 9:
+		found_hsclk_divsel = 5;
+		break;
+	case 10:
+		found_hsclk_divsel = 2;
+		break;
+	case 12:
+		found_hsclk_divsel = 9;
+		break;
+	case 15:
+		found_hsclk_divsel = 13;
+		break;
+	case 25:
+		found_hsclk_divsel = 14;
+		break;
+	};
+
+	pd->vco_freq = found_vco_freq;
+	pd->tx_band_sel = found_tx_band_sel;
+	pd->vco_ratio = found_vco_ratio;
+	pd->hsclk_divsel = found_hsclk_divsel;
+
+	return 0;
+}
+
+static int pll_calculate(unsigned long pix_clk, unsigned long ref_clk,
+			 struct hdmi_8998_phy_pll_reg_cfg *cfg)
+{
+	struct hdmi_8998_post_divider pd;
+	u64 bclk;
+	u64 dec_start;
+	u64 frac_start;
+	u64 fdata;
+	u32 pll_divisor;
+	u32 rem;
+	u32 cpctrl;
+	u32 rctrl;
+	u32 cctrl;
+	u32 integloop_gain;
+	u32 pll_cmp;
+	int i, ret;
+
+	/* bit clk = 10 * pix_clk */
+	bclk = ((u64)pix_clk) * 10;
+
+	ret = pll_get_post_div(&pd, bclk);
+	if (ret)
+		return ret;
+
+	dec_start = pd.vco_freq;
+	pll_divisor = 4 * ref_clk;
+	do_div(dec_start, pll_divisor);
+
+	frac_start = pd.vco_freq * (1 << 20);
+
+	rem = do_div(frac_start, pll_divisor);
+	frac_start -= dec_start * (1 << 20);
+	if (rem > (pll_divisor >> 1))
+		frac_start++;
+
+	cpctrl = pll_get_cpctrl(frac_start, ref_clk, false);
+	rctrl = pll_get_rctrl(frac_start, false);
+	cctrl = pll_get_cctrl(frac_start, false);
+	integloop_gain = pll_get_integloop_gain(frac_start, bclk,
+						ref_clk, false);
+
+	fdata = pd.vco_freq;
+	do_div(fdata, pd.vco_ratio);
+
+	pll_cmp = pll_get_pll_cmp(fdata, ref_clk);
+
+	/* Convert these values to register specific values */
+	if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD)
+		cfg->com_svs_mode_clk_sel = 1;
+	else
+		cfg->com_svs_mode_clk_sel = 2;
+
+	cfg->com_hsclk_sel = (0x20 | pd.hsclk_divsel);
+	cfg->com_pll_cctrl_mode0 = cctrl;
+	cfg->com_pll_rctrl_mode0 = rctrl;
+	cfg->com_cp_ctrl_mode0 = cpctrl;
+	cfg->com_dec_start_mode0 = dec_start;
+	cfg->com_div_frac_start1_mode0 = (frac_start & 0xff);
+	cfg->com_div_frac_start2_mode0 = ((frac_start & 0xff00) >> 8);
+	cfg->com_div_frac_start3_mode0 = ((frac_start & 0xf0000) >> 16);
+	cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xff);
+	cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xf00) >> 8);
+	cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xff);
+	cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xff00) >> 8);
+	cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16);
+	cfg->com_lock_cmp_en = 0x0;
+	cfg->com_core_clk_en = 0x2c;
+	cfg->com_coreclk_div_mode0 = HDMI_CORECLK_DIV;
+	cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x5 : 0x4;
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++)
+		cfg->tx_lx_tx_band[i] = pd.tx_band_sel;
+
+	if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) {
+		cfg->tx_lx_tx_drv_lvl[0] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[1] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[2] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[3] = 0x0f;
+		cfg->tx_lx_tx_emp_post1_lvl[0] = 0x03;
+		cfg->tx_lx_tx_emp_post1_lvl[1] = 0x02;
+		cfg->tx_lx_tx_emp_post1_lvl[2] = 0x03;
+		cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00;
+		cfg->tx_lx_pre_driver_1[0] = 0x00;
+		cfg->tx_lx_pre_driver_1[1] = 0x00;
+		cfg->tx_lx_pre_driver_1[2] = 0x00;
+		cfg->tx_lx_pre_driver_1[3] = 0x00;
+		cfg->tx_lx_pre_driver_2[0] = 0x1C;
+		cfg->tx_lx_pre_driver_2[1] = 0x1C;
+		cfg->tx_lx_pre_driver_2[2] = 0x1C;
+		cfg->tx_lx_pre_driver_2[3] = 0x00;
+		cfg->tx_lx_res_code_offset[0] = 0x03;
+		cfg->tx_lx_res_code_offset[1] = 0x00;
+		cfg->tx_lx_res_code_offset[2] = 0x00;
+		cfg->tx_lx_res_code_offset[3] = 0x03;
+	} else if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD) {
+		cfg->tx_lx_tx_drv_lvl[0] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[1] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[2] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[3] = 0x0f;
+		cfg->tx_lx_tx_emp_post1_lvl[0] = 0x03;
+		cfg->tx_lx_tx_emp_post1_lvl[1] = 0x03;
+		cfg->tx_lx_tx_emp_post1_lvl[2] = 0x03;
+		cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00;
+		cfg->tx_lx_pre_driver_1[0] = 0x00;
+		cfg->tx_lx_pre_driver_1[1] = 0x00;
+		cfg->tx_lx_pre_driver_1[2] = 0x00;
+		cfg->tx_lx_pre_driver_1[3] = 0x00;
+		cfg->tx_lx_pre_driver_2[0] = 0x16;
+		cfg->tx_lx_pre_driver_2[1] = 0x16;
+		cfg->tx_lx_pre_driver_2[2] = 0x16;
+		cfg->tx_lx_pre_driver_2[3] = 0x18;
+		cfg->tx_lx_res_code_offset[0] = 0x03;
+		cfg->tx_lx_res_code_offset[1] = 0x00;
+		cfg->tx_lx_res_code_offset[2] = 0x00;
+		cfg->tx_lx_res_code_offset[3] = 0x00;
+	} else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) {
+		cfg->tx_lx_tx_drv_lvl[0] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[1] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[2] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[3] = 0x0f;
+		cfg->tx_lx_tx_emp_post1_lvl[0] = 0x05;
+		cfg->tx_lx_tx_emp_post1_lvl[1] = 0x05;
+		cfg->tx_lx_tx_emp_post1_lvl[2] = 0x05;
+		cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00;
+		cfg->tx_lx_pre_driver_1[0] = 0x00;
+		cfg->tx_lx_pre_driver_1[1] = 0x00;
+		cfg->tx_lx_pre_driver_1[2] = 0x00;
+		cfg->tx_lx_pre_driver_1[3] = 0x00;
+		cfg->tx_lx_pre_driver_2[0] = 0x0E;
+		cfg->tx_lx_pre_driver_2[1] = 0x0E;
+		cfg->tx_lx_pre_driver_2[2] = 0x0E;
+		cfg->tx_lx_pre_driver_2[3] = 0x0E;
+		cfg->tx_lx_res_code_offset[0] = 0x00;
+		cfg->tx_lx_res_code_offset[1] = 0x00;
+		cfg->tx_lx_res_code_offset[2] = 0x00;
+		cfg->tx_lx_res_code_offset[3] = 0x00;
+	} else {
+		cfg->tx_lx_tx_drv_lvl[0] = 0x01;
+		cfg->tx_lx_tx_drv_lvl[1] = 0x01;
+		cfg->tx_lx_tx_drv_lvl[2] = 0x01;
+		cfg->tx_lx_tx_drv_lvl[3] = 0x00;
+		cfg->tx_lx_tx_emp_post1_lvl[0] = 0x00;
+		cfg->tx_lx_tx_emp_post1_lvl[1] = 0x00;
+		cfg->tx_lx_tx_emp_post1_lvl[2] = 0x00;
+		cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00;
+		cfg->tx_lx_pre_driver_1[0] = 0x00;
+		cfg->tx_lx_pre_driver_1[1] = 0x00;
+		cfg->tx_lx_pre_driver_1[2] = 0x00;
+		cfg->tx_lx_pre_driver_1[3] = 0x00;
+		cfg->tx_lx_pre_driver_2[0] = 0x16;
+		cfg->tx_lx_pre_driver_2[1] = 0x16;
+		cfg->tx_lx_pre_driver_2[2] = 0x16;
+		cfg->tx_lx_pre_driver_2[3] = 0x18;
+		cfg->tx_lx_res_code_offset[0] = 0x00;
+		cfg->tx_lx_res_code_offset[1] = 0x00;
+		cfg->tx_lx_res_code_offset[2] = 0x00;
+		cfg->tx_lx_res_code_offset[3] = 0x00;
+	}
+
+	return 0;
+}
+
+static int hdmi_8998_pll_set_clk_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long parent_rate)
+{
+	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
+	struct hdmi_phy *phy = pll_get_phy(pll);
+	struct hdmi_8998_phy_pll_reg_cfg cfg = {};
+	int i, ret;
+
+	ret = pll_calculate(rate, parent_rate, &cfg);
+	if (ret) {
+		DRM_ERROR("PLL calculation failed\n");
+		return ret;
+	}
+
+	/* Initially shut down PHY */
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_PD_CTL, 0x0);
+	udelay(500);
+
+	/* Power up sequence */
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_PD_CTL, 0x1);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_RESETSM_CNTRL, 0x20);
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CMN_CTRL, 0x6);
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_INTERFACE_SELECT_TX_BAND,
+				   cfg.tx_lx_tx_band[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_CLKBUF_TERM_ENABLE,
+				   0x1);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_LANE_MODE,
+				   0x20);
+	}
+
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SYSCLK_BUF_ENABLE, 0x02);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x0B);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SYSCLK_EN_SEL, 0x37);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SYS_CLK_CTRL, 0x02);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CLK_ENABLE1, 0x0E);
+
+	/* Bypass VCO calibration */
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SVS_MODE_CLK_SEL,
+		       cfg.com_svs_mode_clk_sel);
+
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_PLL_IVCO, 0x07);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_VCO_TUNE_CTRL, 0x00);
+
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CLK_SEL, 0x30);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_HSCLK_SEL,
+		       cfg.com_hsclk_sel);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP_EN,
+		       cfg.com_lock_cmp_en);
+
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_PLL_CCTRL_MODE0,
+		       cfg.com_pll_cctrl_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_PLL_RCTRL_MODE0,
+		       cfg.com_pll_rctrl_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CP_CTRL_MODE0,
+		       cfg.com_cp_ctrl_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DEC_START_MODE0,
+		       cfg.com_dec_start_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DIV_FRAC_START1_MODE0,
+		       cfg.com_div_frac_start1_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DIV_FRAC_START2_MODE0,
+		       cfg.com_div_frac_start2_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DIV_FRAC_START3_MODE0,
+		       cfg.com_div_frac_start3_mode0);
+
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_INTEGLOOP_GAIN0_MODE0,
+		       cfg.com_integloop_gain0_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_INTEGLOOP_GAIN1_MODE0,
+		       cfg.com_integloop_gain1_mode0);
+
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP1_MODE0,
+		       cfg.com_lock_cmp1_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP2_MODE0,
+		       cfg.com_lock_cmp2_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP3_MODE0,
+		       cfg.com_lock_cmp3_mode0);
+
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_VCO_TUNE_MAP, 0x00);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CORE_CLK_EN,
+		       cfg.com_core_clk_en);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CORECLK_DIV_MODE0,
+		       cfg.com_coreclk_div_mode0);
+
+	/* TX lanes setup (TX 0/1/2/3) */
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_DRV_LVL,
+				   cfg.tx_lx_tx_drv_lvl[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_EMP_POST1_LVL,
+				   cfg.tx_lx_tx_emp_post1_lvl[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_PRE_DRIVER_1,
+				   cfg.tx_lx_pre_driver_1[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_PRE_DRIVER_2,
+				   cfg.tx_lx_pre_driver_2[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_DRV_LVL_RES_CODE_OFFSET,
+				   cfg.tx_lx_res_code_offset[i]);
+	}
+
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_MODE, cfg.phy_mode);
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_LANE_CONFIG,
+				   0x10);
+	}
+
+	/*
+	 * Ensure that vco configuration gets flushed to hardware before
+	 * enabling the PLL
+	 */
+	wmb();
+
+	pll->rate = rate;
+
+	return 0;
+}
+
+static int hdmi_8998_phy_ready_status(struct hdmi_phy *phy)
+{
+	u32 nb_tries = HDMI_PLL_POLL_MAX_READS;
+	unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US;
+	u32 status;
+	int phy_ready = 0;
+
+	while (nb_tries--) {
+		status = hdmi_phy_read(phy, REG_HDMI_8998_PHY_STATUS);
+		phy_ready = status & BIT(0);
+
+		if (phy_ready)
+			break;
+
+		udelay(timeout);
+	}
+
+	return phy_ready;
+}
+
+static int hdmi_8998_pll_lock_status(struct hdmi_pll_8998 *pll)
+{
+	u32 status;
+	int nb_tries = HDMI_PLL_POLL_MAX_READS;
+	unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US;
+	int pll_locked = 0;
+
+	while (nb_tries--) {
+		status = hdmi_pll_read(pll,
+				       REG_HDMI_8998_PHY_QSERDES_COM_C_READY_STATUS);
+		pll_locked = status & BIT(0);
+
+		if (pll_locked)
+			break;
+
+		udelay(timeout);
+	}
+
+	return pll_locked;
+}
+
+static int hdmi_8998_pll_prepare(struct clk_hw *hw)
+{
+	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
+	struct hdmi_phy *phy = pll_get_phy(pll);
+	int i, ret = 0;
+
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x1);
+	udelay(100);
+
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x59);
+	udelay(100);
+
+	ret = hdmi_8998_pll_lock_status(pll);
+	if (!ret)
+		return ret;
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_LANE_CONFIG, 0x1F);
+	}
+
+	/* Ensure all registers are flushed to hardware */
+	wmb();
+
+	ret = hdmi_8998_phy_ready_status(phy);
+	if (!ret)
+		return ret;
+
+	/* Restart the retiming buffer */
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x58);
+	udelay(1);
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x59);
+
+	/* Ensure all registers are flushed to hardware */
+	wmb();
+
+	return 0;
+}
+
+static long hdmi_8998_pll_round_rate(struct clk_hw *hw,
+				     unsigned long rate,
+				     unsigned long *parent_rate)
+{
+	if (rate < HDMI_PCLK_MIN_FREQ)
+		return HDMI_PCLK_MIN_FREQ;
+	else if (rate > HDMI_PCLK_MAX_FREQ)
+		return HDMI_PCLK_MAX_FREQ;
+	else
+		return rate;
+}
+
+static unsigned long hdmi_8998_pll_recalc_rate(struct clk_hw *hw,
+					       unsigned long parent_rate)
+{
+	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
+	return pll->rate;
+}
+
+static void hdmi_8998_pll_unprepare(struct clk_hw *hw)
+{
+	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
+	struct hdmi_phy *phy = pll_get_phy(pll);
+
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_PD_CTL, 0);
+	usleep_range(100, 150);
+}
+
+static int hdmi_8998_pll_is_enabled(struct clk_hw *hw)
+{
+	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
+	u32 status;
+	int pll_locked;
+
+	status = hdmi_pll_read(pll, REG_HDMI_8998_PHY_QSERDES_COM_C_READY_STATUS);
+	pll_locked = status & BIT(0);
+
+	return pll_locked;
+}
+
+static const struct clk_ops hdmi_8998_pll_ops = {
+	.set_rate = hdmi_8998_pll_set_clk_rate,
+	.round_rate = hdmi_8998_pll_round_rate,
+	.recalc_rate = hdmi_8998_pll_recalc_rate,
+	.prepare = hdmi_8998_pll_prepare,
+	.unprepare = hdmi_8998_pll_unprepare,
+	.is_enabled = hdmi_8998_pll_is_enabled,
+};
+
+static const struct clk_init_data pll_init = {
+	.name = "hdmipll",
+	.ops = &hdmi_8998_pll_ops,
+	.parent_data = (const struct clk_parent_data[]){
+		{ .fw_name = "xo", .name = "xo_board" },
+	},
+	.num_parents = 1,
+	.flags = CLK_IGNORE_UNUSED,
+};
+
+int msm_hdmi_pll_8998_init(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct hdmi_pll_8998 *pll;
+	int ret, i;
+
+	pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return -ENOMEM;
+
+	pll->pdev = pdev;
+
+	pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll");
+	if (IS_ERR(pll->mmio_qserdes_com)) {
+		DRM_DEV_ERROR(dev, "failed to map pll base\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+		char name[32];
+
+		snprintf(name, sizeof(name), "hdmi_tx_l%d", i);
+
+		pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name);
+		if (IS_ERR(pll->mmio_qserdes_tx[i])) {
+			DRM_DEV_ERROR(dev, "failed to map pll base\n");
+			return -ENOMEM;
+		}
+	}
+	pll->clk_hw.init = &pll_init;
+
+	ret = devm_clk_hw_register(dev, &pll->clk_hw);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "failed to register pll clock\n");
+		return ret;
+	}
+
+	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &pll->clk_hw);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const char * const hdmi_phy_8998_reg_names[] = {
+	"vddio",
+	"vcca",
+};
+
+static const char * const hdmi_phy_8998_clk_names[] = {
+	"iface", "ref", "xo",
+};
+
+const struct hdmi_phy_cfg msm_hdmi_phy_8998_cfg = {
+	.type = MSM_HDMI_PHY_8998,
+	.reg_names = hdmi_phy_8998_reg_names,
+	.num_regs = ARRAY_SIZE(hdmi_phy_8998_reg_names),
+	.clk_names = hdmi_phy_8998_clk_names,
+	.num_clks = ARRAY_SIZE(hdmi_phy_8998_clk_names),
+};
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/msm_atomic.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/msm_atomic.c
@@ -210,6 +210,8 @@
 
 	trace_msm_atomic_commit_tail_start(async, crtc_mask);
 
+	drm_dp_mst_atomic_wait_for_dependencies(state);
+
 	kms->funcs->enable_commit(kms);
 
 	/*
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/msm_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/msm_drv.c
@@ -17,8 +17,9 @@
 
 #include "msm_drv.h"
 #include "msm_debugfs.h"
+#include "msm_gem.h"
+#include "msm_gpu.h"
 #include "msm_kms.h"
-#include "adreno/adreno_gpu.h"
 
 /*
  * MSM driver version:
@@ -1037,10 +1038,6 @@
 			return ret;
 	}
 
-	ret = add_gpu_components(master_dev, &match);
-	if (ret)
-		return ret;
-
 	/* on all devices that I am aware of, iommu's which can map
 	 * any address the cpu can see are used:
 	 */
@@ -1089,7 +1086,6 @@
 	msm_dsi_register();
 	msm_hdmi_register();
 	msm_dp_register();
-	adreno_register();
 	msm_mdp4_register();
 	msm_mdss_register();
 	return platform_driver_register(&msm_platform_driver);
@@ -1103,7 +1099,6 @@
 	msm_mdp4_unregister();
 	msm_dp_unregister();
 	msm_hdmi_unregister();
-	adreno_unregister();
 	msm_dsi_unregister();
 	msm_mdp_unregister();
 	msm_dpu_unregister();
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/msm_drv.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/msm_drv.h
@@ -30,6 +30,7 @@
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/display/drm_dsc.h>
+#include <drm/display/drm_dp_mst_helper.h>
 #include <drm/msm_drm.h>
 #include <drm/drm_gem.h>
 
@@ -75,16 +76,6 @@
 #define MAX_H_TILES_PER_DISPLAY 2
 
 /**
- * enum msm_event_wait - type of HW events to wait for
- * @MSM_ENC_COMMIT_DONE - wait for the driver to flush the registers to HW
- * @MSM_ENC_TX_COMPLETE - wait for the HW to transfer the frame to panel
- */
-enum msm_event_wait {
-	MSM_ENC_COMMIT_DONE = 0,
-	MSM_ENC_TX_COMPLETE,
-};
-
-/**
  * struct msm_display_topology - defines a display topology pipeline
  * @num_lm:       number of layer mixers used
  * @num_intf:     number of interfaces the panel is mounted on
@@ -385,11 +376,22 @@
 int __init msm_dp_register(void);
 void __exit msm_dp_unregister(void);
 int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
-			 struct drm_encoder *encoder);
+			 struct drm_encoder *encoder, bool yuv_supported);
 void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display);
-
+bool msm_dp_is_yuv_420_enabled(const struct msm_dp *dp_display,
+			       const struct drm_display_mode *mode);
+bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display,
+			       const struct drm_display_mode *mode);
 bool msm_dp_wide_bus_available(const struct msm_dp *dp_display);
 
+int msm_dp_get_mst_max_stream(const struct msm_dp *dp_display);
+
+int msm_dp_mst_bridge_init(struct msm_dp *dp_display, struct drm_encoder *encoder);
+
+int msm_dp_mst_register(struct msm_dp *dp_display);
+
+int msm_dp_get_mst_intf_id(struct msm_dp *dp_display, int stream_id);
+
 #else
 static inline int __init msm_dp_register(void)
 {
@@ -400,7 +402,23 @@
 }
 static inline int msm_dp_modeset_init(struct msm_dp *dp_display,
 				       struct drm_device *dev,
-				       struct drm_encoder *encoder)
+				       struct drm_encoder *encoder,
+				       bool yuv_supported)
+{
+	return -EINVAL;
+}
+
+static inline int msm_dp_get_mst_max_stream(struct msm_dp *dp_display)
+{
+	return -EINVAL;
+}
+
+static inline int msm_dp_mst_register(struct msm_dp *dp_display)
+{
+	return -EINVAL;
+}
+
+static inline int msm_dp_mst_bridge_init(struct msm_dp *dp_display, struct drm_encoder *encoder)
 {
 	return -EINVAL;
 }
@@ -409,11 +427,28 @@
 {
 }
 
+static inline bool msm_dp_is_yuv_420_enabled(const struct msm_dp *dp_display,
+					     const struct drm_display_mode *mode)
+{
+	return false;
+}
+
+static inline bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display,
+					     const struct drm_display_mode *mode)
+{
+	return false;
+}
+
 static inline bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)
 {
 	return false;
 }
 
+static inline int msm_dp_get_mst_intf_id(struct msm_dp *dp_display, int stream_id)
+{
+	return -EINVAL;
+}
+
 #endif
 
 #ifdef CONFIG_DRM_MSM_MDP4
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/msm_fb.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/msm_fb.c
@@ -89,7 +89,7 @@
 
 	for (i = 0; i < n; i++) {
 		ret = msm_gem_get_and_pin_iova(fb->obj[i], aspace, &msm_fb->iova[i]);
-		drm_dbg_state(fb->dev, "FB[%u]: iova[%d]: %08llx (%d)",
+		drm_dbg_state(fb->dev, "FB[%u]: iova[%d]: %08llx (%d)\n",
 			      fb->base.id, i, msm_fb->iova[i], ret);
 		if (ret)
 			return ret;
@@ -176,7 +176,7 @@
 	const struct msm_format *format;
 	int ret, i, n;
 
-	drm_dbg_state(dev, "create framebuffer: mode_cmd=%p (%dx%d@%4.4s)",
+	drm_dbg_state(dev, "create framebuffer: mode_cmd=%p (%dx%d@%4.4s)\n",
 			mode_cmd, mode_cmd->width, mode_cmd->height,
 			(char *)&mode_cmd->pixel_format);
 
@@ -232,7 +232,7 @@
 
 	refcount_set(&msm_fb->dirtyfb, 1);
 
-	drm_dbg_state(dev, "create: FB ID: %d (%p)", fb->base.id, fb);
+	drm_dbg_state(dev, "create: FB ID: %d (%p)\n", fb->base.id, fb);
 
 	return fb;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/msm_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/msm_gpu.c
@@ -11,7 +11,7 @@
 #include "msm_mmu.h"
 #include "msm_fence.h"
 #include "msm_gpu_trace.h"
-#include "adreno/adreno_gpu.h"
+//#include "adreno/adreno_gpu.h"
 
 #include <generated/utsrelease.h>
 #include <linux/string_helpers.h>
@@ -929,7 +929,6 @@
 	if (IS_ERR(gpu->gpu_cx))
 		gpu->gpu_cx = NULL;
 
-	gpu->pdev = pdev;
 	platform_set_drvdata(pdev, &gpu->adreno_smmu);
 
 	msm_devfreq_init(gpu);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/msm_gpu_devfreq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/msm_gpu_devfreq.c
@@ -140,6 +140,7 @@
 {
 	struct msm_gpu_devfreq *df = &gpu->devfreq;
 	struct msm_drm_private *priv = gpu->dev->dev_private;
+	int ret;
 
 	/* We need target support to do devfreq */
 	if (!gpu->funcs->gpu_busy)
@@ -156,8 +157,12 @@
 
 	mutex_init(&df->lock);
 
-	dev_pm_qos_add_request(&gpu->pdev->dev, &df->boost_freq,
-			       DEV_PM_QOS_MIN_FREQUENCY, 0);
+	ret = dev_pm_qos_add_request(&gpu->pdev->dev, &df->boost_freq,
+				     DEV_PM_QOS_MIN_FREQUENCY, 0);
+	if (ret < 0) {
+		DRM_DEV_ERROR(&gpu->pdev->dev, "Couldn't initialize QoS\n");
+		return;
+	}
 
 	msm_devfreq_profile.initial_freq = gpu->fast_rate;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/msm_kms.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/msm_kms.c
@@ -28,6 +28,7 @@
 
 static const struct drm_mode_config_helper_funcs mode_config_helper_funcs = {
 	.atomic_commit_tail = msm_atomic_commit_tail,
+	.atomic_commit_setup = drm_dp_mst_atomic_setup_commit,
 };
 
 static irqreturn_t msm_irq(int irq, void *arg)
@@ -149,7 +150,7 @@
 	struct msm_kms *kms = priv->kms;
 	if (!kms)
 		return -ENXIO;
-	drm_dbg_vbl(dev, "crtc=%u", crtc->base.id);
+	drm_dbg_vbl(dev, "crtc=%u\n", crtc->base.id);
 	return vblank_ctrl_queue_work(priv, crtc, true);
 }
 
@@ -160,7 +161,7 @@
 	struct msm_kms *kms = priv->kms;
 	if (!kms)
 		return;
-	drm_dbg_vbl(dev, "crtc=%u", crtc->base.id);
+	drm_dbg_vbl(dev, "crtc=%u\n", crtc->base.id);
 	vblank_ctrl_queue_work(priv, crtc, false);
 }
 
@@ -244,7 +245,6 @@
 	ret = priv->kms_init(ddev);
 	if (ret) {
 		DRM_DEV_ERROR(dev, "failed to load kms\n");
-		priv->kms = NULL;
 		return ret;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/msm_mdss.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/msm_mdss.c
@@ -526,7 +526,7 @@
 	.ubwc_enc_version = UBWC_2_0,
 	.ubwc_dec_version = UBWC_2_0,
 	.ubwc_static = 0x1e,
-	.highest_bank_bit = 0x3,
+	.highest_bank_bit = 0x1,
 	.reg_bus_bw = 76800,
 };
 
@@ -602,6 +602,7 @@
 	.ubwc_dec_version = UBWC_3_0,
 	.ubwc_swizzle = 1,
 	.highest_bank_bit = 1,
+	.reg_bus_bw = 76800,
 };
 
 static const struct msm_mdss_data sm8250_data = {
@@ -626,6 +627,24 @@
 	.reg_bus_bw = 74000,
 };
 
+static const struct msm_mdss_data qcs8300_data = {
+	.ubwc_enc_version = UBWC_4_0,
+	.ubwc_dec_version = UBWC_4_0,
+	.ubwc_swizzle = 6,
+	.ubwc_static = 1,
+	.highest_bank_bit = 3,
+	.macrotile_mode = 1,
+};
+
+static const struct msm_mdss_data sa8775p_data = {
+	.ubwc_enc_version = UBWC_4_0,
+	.ubwc_dec_version = UBWC_4_0,
+	.ubwc_swizzle = 4,
+	.ubwc_static = 1,
+	.highest_bank_bit = 0,
+	.macrotile_mode = 1,
+};
+
 static const struct msm_mdss_data sm8550_data = {
 	.ubwc_enc_version = UBWC_4_0,
 	.ubwc_dec_version = UBWC_4_3,
@@ -654,6 +673,8 @@
 	{ .compatible = "qcom,sm8250-mdss", .data = &sm8250_data },
 	{ .compatible = "qcom,sm8350-mdss", .data = &sm8350_data },
 	{ .compatible = "qcom,sm8450-mdss", .data = &sm8350_data },
+	{ .compatible = "qcom,qcs8300-mdss", .data = &qcs8300_data },
+	{ .compatible = "qcom,sa8775p-mdss", .data = &sa8775p_data },
 	{ .compatible = "qcom,sm8550-mdss", .data = &sm8550_data },
 	{ .compatible = "qcom,sm8650-mdss", .data = &sm8550_data},
 	{}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/msm_mmu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/msm_mmu.h
@@ -42,7 +42,6 @@
 
 struct msm_mmu *msm_iommu_new(struct device *dev, unsigned long quirks);
 struct msm_mmu *msm_iommu_gpu_new(struct device *dev, struct msm_gpu *gpu, unsigned long quirks);
-struct msm_mmu *msm_gpummu_new(struct device *dev, struct msm_gpu *gpu);
 
 static inline void msm_mmu_set_fault_handler(struct msm_mmu *mmu, void *arg,
 		int (*handler)(void *arg, unsigned long iova, int flags, void *data))
@@ -53,10 +52,6 @@
 
 struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent);
 
-void msm_gpummu_params(struct msm_mmu *mmu, dma_addr_t *pt_base,
-		dma_addr_t *tran_error);
-
-
 int msm_iommu_pagetable_params(struct msm_mmu *mmu, phys_addr_t *ttbr,
 		int *asid);
 struct iommu_domain_geometry *msm_iommu_get_geometry(struct msm_mmu *mmu);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/adreno/a2xx.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/adreno/a2xx.xml
@@ -0,0 +1,1865 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="adreno/adreno_common.xml"/>
+<import file="adreno/adreno_pm4.xml"/>
+
+
+<enum name="a2xx_rb_dither_type">
+	<value name="DITHER_PIXEL" value="0"/>
+	<value name="DITHER_SUBPIXEL" value="1"/>
+</enum>
+
+<enum name="a2xx_colorformatx">
+	<value name="COLORX_4_4_4_4" value="0"/>
+	<value name="COLORX_1_5_5_5" value="1"/>
+	<value name="COLORX_5_6_5" value="2"/>
+	<value name="COLORX_8" value="3"/>
+	<value name="COLORX_8_8" value="4"/>
+	<value name="COLORX_8_8_8_8" value="5"/>
+	<value name="COLORX_S8_8_8_8" value="6"/>
+	<value name="COLORX_16_FLOAT" value="7"/>
+	<value name="COLORX_16_16_FLOAT" value="8"/>
+	<value name="COLORX_16_16_16_16_FLOAT" value="9"/>
+	<value name="COLORX_32_FLOAT" value="10"/>
+	<value name="COLORX_32_32_FLOAT" value="11"/>
+	<value name="COLORX_32_32_32_32_FLOAT" value="12"/>
+	<value name="COLORX_2_3_3" value="13"/>
+	<value name="COLORX_8_8_8" value="14"/>
+</enum>
+
+<enum name="a2xx_sq_surfaceformat">
+	<value name="FMT_1_REVERSE" value="0"/>
+	<value name="FMT_1" value="1"/>
+	<value name="FMT_8" value="2"/>
+	<value name="FMT_1_5_5_5" value="3"/>
+	<value name="FMT_5_6_5" value="4"/>
+	<value name="FMT_6_5_5" value="5"/>
+	<value name="FMT_8_8_8_8" value="6"/>
+	<value name="FMT_2_10_10_10" value="7"/>
+	<value name="FMT_8_A" value="8"/>
+	<value name="FMT_8_B" value="9"/>
+	<value name="FMT_8_8" value="10"/>
+	<value name="FMT_Cr_Y1_Cb_Y0" value="11"/>
+	<value name="FMT_Y1_Cr_Y0_Cb" value="12"/>
+	<value name="FMT_5_5_5_1" value="13"/>
+	<value name="FMT_8_8_8_8_A" value="14"/>
+	<value name="FMT_4_4_4_4" value="15"/>
+	<value name="FMT_8_8_8" value="16"/>
+	<value name="FMT_DXT1" value="18"/>
+	<value name="FMT_DXT2_3" value="19"/>
+	<value name="FMT_DXT4_5" value="20"/>
+	<value name="FMT_10_10_10_2" value="21"/>
+	<value name="FMT_24_8" value="22"/>
+	<value name="FMT_16" value="24"/>
+	<value name="FMT_16_16" value="25"/>
+	<value name="FMT_16_16_16_16" value="26"/>
+	<value name="FMT_16_EXPAND" value="27"/>
+	<value name="FMT_16_16_EXPAND" value="28"/>
+	<value name="FMT_16_16_16_16_EXPAND" value="29"/>
+	<value name="FMT_16_FLOAT" value="30"/>
+	<value name="FMT_16_16_FLOAT" value="31"/>
+	<value name="FMT_16_16_16_16_FLOAT" value="32"/>
+	<value name="FMT_32" value="33"/>
+	<value name="FMT_32_32" value="34"/>
+	<value name="FMT_32_32_32_32" value="35"/>
+	<value name="FMT_32_FLOAT" value="36"/>
+	<value name="FMT_32_32_FLOAT" value="37"/>
+	<value name="FMT_32_32_32_32_FLOAT" value="38"/>
+	<value name="FMT_ATI_TC_RGB" value="39"/>
+	<value name="FMT_ATI_TC_RGBA" value="40"/>
+	<value name="FMT_ATI_TC_555_565_RGB" value="41"/>
+	<value name="FMT_ATI_TC_555_565_RGBA" value="42"/>
+	<value name="FMT_ATI_TC_RGBA_INTERP" value="43"/>
+	<value name="FMT_ATI_TC_555_565_RGBA_INTERP" value="44"/>
+	<value name="FMT_ETC1_RGBA_INTERP" value="46"/>
+	<value name="FMT_ETC1_RGB" value="47"/>
+	<value name="FMT_ETC1_RGBA" value="48"/>
+	<value name="FMT_DXN" value="49"/>
+	<value name="FMT_2_3_3" value="51"/>
+	<value name="FMT_2_10_10_10_AS_16_16_16_16" value="54"/>
+	<value name="FMT_10_10_10_2_AS_16_16_16_16" value="55"/>
+	<value name="FMT_32_32_32_FLOAT" value="57"/>
+	<value name="FMT_DXT3A" value="58"/>
+	<value name="FMT_DXT5A" value="59"/>
+	<value name="FMT_CTX1" value="60"/>
+</enum>
+
+<enum name="a2xx_sq_ps_vtx_mode">
+	<value name="POSITION_1_VECTOR" value="0"/>
+	<value name="POSITION_2_VECTORS_UNUSED" value="1"/>
+	<value name="POSITION_2_VECTORS_SPRITE" value="2"/>
+	<value name="POSITION_2_VECTORS_EDGE" value="3"/>
+	<value name="POSITION_2_VECTORS_KILL" value="4"/>
+	<value name="POSITION_2_VECTORS_SPRITE_KILL" value="5"/>
+	<value name="POSITION_2_VECTORS_EDGE_KILL" value="6"/>
+	<value name="MULTIPASS" value="7"/>
+</enum>
+
+<enum name="a2xx_sq_sample_cntl">
+	<value name="CENTROIDS_ONLY" value="0"/>
+	<value name="CENTERS_ONLY" value="1"/>
+	<value name="CENTROIDS_AND_CENTERS" value="2"/>
+</enum>
+
+<enum name="a2xx_dx_clip_space">
+	<value name="DXCLIP_OPENGL" value="0"/>
+	<value name="DXCLIP_DIRECTX" value="1"/>
+</enum>
+
+<enum name="a2xx_pa_su_sc_polymode">
+	<value name="POLY_DISABLED" value="0"/>
+	<value name="POLY_DUALMODE" value="1"/>
+</enum>
+
+<enum name="a2xx_rb_edram_mode">
+	<value name="EDRAM_NOP" value="0"/>
+	<value name="COLOR_DEPTH" value="4"/>
+	<value name="DEPTH_ONLY" value="5"/>
+	<value name="EDRAM_COPY" value="6"/>
+</enum>
+
+<enum name="a2xx_pa_sc_pattern_bit_order">
+	<value name="LITTLE" value="0"/>
+	<value name="BIG" value="1"/>
+</enum>
+
+<enum name="a2xx_pa_sc_auto_reset_cntl">
+	<value name="NEVER" value="0"/>
+	<value name="EACH_PRIMITIVE" value="1"/>
+	<value name="EACH_PACKET" value="2"/>
+</enum>
+
+<enum name="a2xx_pa_pixcenter">
+	<value name="PIXCENTER_D3D" value="0"/>
+	<value name="PIXCENTER_OGL" value="1"/>
+</enum>
+
+<enum name="a2xx_pa_roundmode">
+	<value name="TRUNCATE" value="0"/>
+	<value name="ROUND" value="1"/>
+	<value name="ROUNDTOEVEN" value="2"/>
+	<value name="ROUNDTOODD" value="3"/>
+</enum>
+
+<enum name="a2xx_pa_quantmode">
+	<value name="ONE_SIXTEENTH" value="0"/>
+	<value name="ONE_EIGTH" value="1"/>
+	<value name="ONE_QUARTER" value="2"/>
+	<value name="ONE_HALF" value="3"/>
+	<value name="ONE" value="4"/>
+</enum>
+
+<enum name="a2xx_rb_copy_sample_select">
+	<value name="SAMPLE_0" value="0"/>
+	<value name="SAMPLE_1" value="1"/>
+	<value name="SAMPLE_2" value="2"/>
+	<value name="SAMPLE_3" value="3"/>
+	<value name="SAMPLE_01" value="4"/>
+	<value name="SAMPLE_23" value="5"/>
+	<value name="SAMPLE_0123" value="6"/>
+</enum>
+
+<enum name="a2xx_rb_blend_opcode">
+	<value name="BLEND2_DST_PLUS_SRC" value="0"/>
+	<value name="BLEND2_SRC_MINUS_DST" value="1"/>
+	<value name="BLEND2_MIN_DST_SRC" value="2"/>
+	<value name="BLEND2_MAX_DST_SRC" value="3"/>
+	<value name="BLEND2_DST_MINUS_SRC" value="4"/>
+	<value name="BLEND2_DST_PLUS_SRC_BIAS" value="5"/>
+</enum>
+
+<enum name="a2xx_su_perfcnt_select">
+	<value value="0" name="PERF_PAPC_PASX_REQ"/>
+	<value value="2" name="PERF_PAPC_PASX_FIRST_VECTOR"/>
+	<value value="3" name="PERF_PAPC_PASX_SECOND_VECTOR"/>
+	<value value="4" name="PERF_PAPC_PASX_FIRST_DEAD"/>
+	<value value="5" name="PERF_PAPC_PASX_SECOND_DEAD"/>
+	<value value="6" name="PERF_PAPC_PASX_VTX_KILL_DISCARD"/>
+	<value value="7" name="PERF_PAPC_PASX_VTX_NAN_DISCARD"/>
+	<value value="8" name="PERF_PAPC_PA_INPUT_PRIM"/>
+	<value value="9" name="PERF_PAPC_PA_INPUT_NULL_PRIM"/>
+	<value value="10" name="PERF_PAPC_PA_INPUT_EVENT_FLAG"/>
+	<value value="11" name="PERF_PAPC_PA_INPUT_FIRST_PRIM_SLOT"/>
+	<value value="12" name="PERF_PAPC_PA_INPUT_END_OF_PACKET"/>
+	<value value="13" name="PERF_PAPC_CLPR_CULL_PRIM"/>
+	<value value="15" name="PERF_PAPC_CLPR_VV_CULL_PRIM"/>
+	<value value="17" name="PERF_PAPC_CLPR_VTX_KILL_CULL_PRIM"/>
+	<value value="18" name="PERF_PAPC_CLPR_VTX_NAN_CULL_PRIM"/>
+	<value value="19" name="PERF_PAPC_CLPR_CULL_TO_NULL_PRIM"/>
+	<value value="21" name="PERF_PAPC_CLPR_VV_CLIP_PRIM"/>
+	<value value="23" name="PERF_PAPC_CLPR_POINT_CLIP_CANDIDATE"/>
+	<value value="24" name="PERF_PAPC_CLPR_CLIP_PLANE_CNT_1"/>
+	<value value="25" name="PERF_PAPC_CLPR_CLIP_PLANE_CNT_2"/>
+	<value value="26" name="PERF_PAPC_CLPR_CLIP_PLANE_CNT_3"/>
+	<value value="27" name="PERF_PAPC_CLPR_CLIP_PLANE_CNT_4"/>
+	<value value="28" name="PERF_PAPC_CLPR_CLIP_PLANE_CNT_5"/>
+	<value value="29" name="PERF_PAPC_CLPR_CLIP_PLANE_CNT_6"/>
+	<value value="30" name="PERF_PAPC_CLPR_CLIP_PLANE_NEAR"/>
+	<value value="31" name="PERF_PAPC_CLPR_CLIP_PLANE_FAR"/>
+	<value value="32" name="PERF_PAPC_CLPR_CLIP_PLANE_LEFT"/>
+	<value value="33" name="PERF_PAPC_CLPR_CLIP_PLANE_RIGHT"/>
+	<value value="34" name="PERF_PAPC_CLPR_CLIP_PLANE_TOP"/>
+	<value value="35" name="PERF_PAPC_CLPR_CLIP_PLANE_BOTTOM"/>
+	<value value="36" name="PERF_PAPC_CLSM_NULL_PRIM"/>
+	<value value="37" name="PERF_PAPC_CLSM_TOTALLY_VISIBLE_PRIM"/>
+	<value value="38" name="PERF_PAPC_CLSM_CLIP_PRIM"/>
+	<value value="39" name="PERF_PAPC_CLSM_CULL_TO_NULL_PRIM"/>
+	<value value="40" name="PERF_PAPC_CLSM_OUT_PRIM_CNT_1"/>
+	<value value="41" name="PERF_PAPC_CLSM_OUT_PRIM_CNT_2"/>
+	<value value="42" name="PERF_PAPC_CLSM_OUT_PRIM_CNT_3"/>
+	<value value="43" name="PERF_PAPC_CLSM_OUT_PRIM_CNT_4"/>
+	<value value="44" name="PERF_PAPC_CLSM_OUT_PRIM_CNT_5"/>
+	<value value="45" name="PERF_PAPC_CLSM_OUT_PRIM_CNT_6_7"/>
+	<value value="46" name="PERF_PAPC_CLSM_NON_TRIVIAL_CULL"/>
+	<value value="47" name="PERF_PAPC_SU_INPUT_PRIM"/>
+	<value value="48" name="PERF_PAPC_SU_INPUT_CLIP_PRIM"/>
+	<value value="49" name="PERF_PAPC_SU_INPUT_NULL_PRIM"/>
+	<value value="50" name="PERF_PAPC_SU_ZERO_AREA_CULL_PRIM"/>
+	<value value="51" name="PERF_PAPC_SU_BACK_FACE_CULL_PRIM"/>
+	<value value="52" name="PERF_PAPC_SU_FRONT_FACE_CULL_PRIM"/>
+	<value value="53" name="PERF_PAPC_SU_POLYMODE_FACE_CULL"/>
+	<value value="54" name="PERF_PAPC_SU_POLYMODE_BACK_CULL"/>
+	<value value="55" name="PERF_PAPC_SU_POLYMODE_FRONT_CULL"/>
+	<value value="56" name="PERF_PAPC_SU_POLYMODE_INVALID_FILL"/>
+	<value value="57" name="PERF_PAPC_SU_OUTPUT_PRIM"/>
+	<value value="58" name="PERF_PAPC_SU_OUTPUT_CLIP_PRIM"/>
+	<value value="59" name="PERF_PAPC_SU_OUTPUT_NULL_PRIM"/>
+	<value value="60" name="PERF_PAPC_SU_OUTPUT_EVENT_FLAG"/>
+	<value value="61" name="PERF_PAPC_SU_OUTPUT_FIRST_PRIM_SLOT"/>
+	<value value="62" name="PERF_PAPC_SU_OUTPUT_END_OF_PACKET"/>
+	<value value="63" name="PERF_PAPC_SU_OUTPUT_POLYMODE_FACE"/>
+	<value value="64" name="PERF_PAPC_SU_OUTPUT_POLYMODE_BACK"/>
+	<value value="65" name="PERF_PAPC_SU_OUTPUT_POLYMODE_FRONT"/>
+	<value value="66" name="PERF_PAPC_SU_OUT_CLIP_POLYMODE_FACE"/>
+	<value value="67" name="PERF_PAPC_SU_OUT_CLIP_POLYMODE_BACK"/>
+	<value value="68" name="PERF_PAPC_SU_OUT_CLIP_POLYMODE_FRONT"/>
+	<value value="69" name="PERF_PAPC_PASX_REQ_IDLE"/>
+	<value value="70" name="PERF_PAPC_PASX_REQ_BUSY"/>
+	<value value="71" name="PERF_PAPC_PASX_REQ_STALLED"/>
+	<value value="72" name="PERF_PAPC_PASX_REC_IDLE"/>
+	<value value="73" name="PERF_PAPC_PASX_REC_BUSY"/>
+	<value value="74" name="PERF_PAPC_PASX_REC_STARVED_SX"/>
+	<value value="75" name="PERF_PAPC_PASX_REC_STALLED"/>
+	<value value="76" name="PERF_PAPC_PASX_REC_STALLED_POS_MEM"/>
+	<value value="77" name="PERF_PAPC_PASX_REC_STALLED_CCGSM_IN"/>
+	<value value="78" name="PERF_PAPC_CCGSM_IDLE"/>
+	<value value="79" name="PERF_PAPC_CCGSM_BUSY"/>
+	<value value="80" name="PERF_PAPC_CCGSM_STALLED"/>
+	<value value="81" name="PERF_PAPC_CLPRIM_IDLE"/>
+	<value value="82" name="PERF_PAPC_CLPRIM_BUSY"/>
+	<value value="83" name="PERF_PAPC_CLPRIM_STALLED"/>
+	<value value="84" name="PERF_PAPC_CLPRIM_STARVED_CCGSM"/>
+	<value value="85" name="PERF_PAPC_CLIPSM_IDLE"/>
+	<value value="86" name="PERF_PAPC_CLIPSM_BUSY"/>
+	<value value="87" name="PERF_PAPC_CLIPSM_WAIT_CLIP_VERT_ENGH"/>
+	<value value="88" name="PERF_PAPC_CLIPSM_WAIT_HIGH_PRI_SEQ"/>
+	<value value="89" name="PERF_PAPC_CLIPSM_WAIT_CLIPGA"/>
+	<value value="90" name="PERF_PAPC_CLIPSM_WAIT_AVAIL_VTE_CLIP"/>
+	<value value="91" name="PERF_PAPC_CLIPSM_WAIT_CLIP_OUTSM"/>
+	<value value="92" name="PERF_PAPC_CLIPGA_IDLE"/>
+	<value value="93" name="PERF_PAPC_CLIPGA_BUSY"/>
+	<value value="94" name="PERF_PAPC_CLIPGA_STARVED_VTE_CLIP"/>
+	<value value="95" name="PERF_PAPC_CLIPGA_STALLED"/>
+	<value value="96" name="PERF_PAPC_CLIP_IDLE"/>
+	<value value="97" name="PERF_PAPC_CLIP_BUSY"/>
+	<value value="98" name="PERF_PAPC_SU_IDLE"/>
+	<value value="99" name="PERF_PAPC_SU_BUSY"/>
+	<value value="100" name="PERF_PAPC_SU_STARVED_CLIP"/>
+	<value value="101" name="PERF_PAPC_SU_STALLED_SC"/>
+	<value value="102" name="PERF_PAPC_SU_FACENESS_CULL"/>
+</enum>
+
+<enum name="a2xx_sc_perfcnt_select">
+	<value value="0" name="SC_SR_WINDOW_VALID"/>
+	<value value="1" name="SC_CW_WINDOW_VALID"/>
+	<value value="2" name="SC_QM_WINDOW_VALID"/>
+	<value value="3" name="SC_FW_WINDOW_VALID"/>
+	<value value="4" name="SC_EZ_WINDOW_VALID"/>
+	<value value="5" name="SC_IT_WINDOW_VALID"/>
+	<value value="6" name="SC_STARVED_BY_PA"/>
+	<value value="7" name="SC_STALLED_BY_RB_TILE"/>
+	<value value="8" name="SC_STALLED_BY_RB_SAMP"/>
+	<value value="9" name="SC_STARVED_BY_RB_EZ"/>
+	<value value="10" name="SC_STALLED_BY_SAMPLE_FF"/>
+	<value value="11" name="SC_STALLED_BY_SQ"/>
+	<value value="12" name="SC_STALLED_BY_SP"/>
+	<value value="13" name="SC_TOTAL_NO_PRIMS"/>
+	<value value="14" name="SC_NON_EMPTY_PRIMS"/>
+	<value value="15" name="SC_NO_TILES_PASSING_QM"/>
+	<value value="16" name="SC_NO_PIXELS_PRE_EZ"/>
+	<value value="17" name="SC_NO_PIXELS_POST_EZ"/>
+</enum>
+
+<enum name="a2xx_vgt_perfcount_select">
+	<value value="0" name="VGT_SQ_EVENT_WINDOW_ACTIVE"/>
+	<value value="1" name="VGT_SQ_SEND"/>
+	<value value="2" name="VGT_SQ_STALLED"/>
+	<value value="3" name="VGT_SQ_STARVED_BUSY"/>
+	<value value="4" name="VGT_SQ_STARVED_IDLE"/>
+	<value value="5" name="VGT_SQ_STATIC"/>
+	<value value="6" name="VGT_PA_EVENT_WINDOW_ACTIVE"/>
+	<value value="7" name="VGT_PA_CLIP_V_SEND"/>
+	<value value="8" name="VGT_PA_CLIP_V_STALLED"/>
+	<value value="9" name="VGT_PA_CLIP_V_STARVED_BUSY"/>
+	<value value="10" name="VGT_PA_CLIP_V_STARVED_IDLE"/>
+	<value value="11" name="VGT_PA_CLIP_V_STATIC"/>
+	<value value="12" name="VGT_PA_CLIP_P_SEND"/>
+	<value value="13" name="VGT_PA_CLIP_P_STALLED"/>
+	<value value="14" name="VGT_PA_CLIP_P_STARVED_BUSY"/>
+	<value value="15" name="VGT_PA_CLIP_P_STARVED_IDLE"/>
+	<value value="16" name="VGT_PA_CLIP_P_STATIC"/>
+	<value value="17" name="VGT_PA_CLIP_S_SEND"/>
+	<value value="18" name="VGT_PA_CLIP_S_STALLED"/>
+	<value value="19" name="VGT_PA_CLIP_S_STARVED_BUSY"/>
+	<value value="20" name="VGT_PA_CLIP_S_STARVED_IDLE"/>
+	<value value="21" name="VGT_PA_CLIP_S_STATIC"/>
+	<value value="22" name="RBIU_FIFOS_EVENT_WINDOW_ACTIVE"/>
+	<value value="23" name="RBIU_IMMED_DATA_FIFO_STARVED"/>
+	<value value="24" name="RBIU_IMMED_DATA_FIFO_STALLED"/>
+	<value value="25" name="RBIU_DMA_REQUEST_FIFO_STARVED"/>
+	<value value="26" name="RBIU_DMA_REQUEST_FIFO_STALLED"/>
+	<value value="27" name="RBIU_DRAW_INITIATOR_FIFO_STARVED"/>
+	<value value="28" name="RBIU_DRAW_INITIATOR_FIFO_STALLED"/>
+	<value value="29" name="BIN_PRIM_NEAR_CULL"/>
+	<value value="30" name="BIN_PRIM_ZERO_CULL"/>
+	<value value="31" name="BIN_PRIM_FAR_CULL"/>
+	<value value="32" name="BIN_PRIM_BIN_CULL"/>
+	<value value="33" name="BIN_PRIM_FACE_CULL"/>
+	<value value="34" name="SPARE34"/>
+	<value value="35" name="SPARE35"/>
+	<value value="36" name="SPARE36"/>
+	<value value="37" name="SPARE37"/>
+	<value value="38" name="SPARE38"/>
+	<value value="39" name="SPARE39"/>
+	<value value="40" name="TE_SU_IN_VALID"/>
+	<value value="41" name="TE_SU_IN_READ"/>
+	<value value="42" name="TE_SU_IN_PRIM"/>
+	<value value="43" name="TE_SU_IN_EOP"/>
+	<value value="44" name="TE_SU_IN_NULL_PRIM"/>
+	<value value="45" name="TE_WK_IN_VALID"/>
+	<value value="46" name="TE_WK_IN_READ"/>
+	<value value="47" name="TE_OUT_PRIM_VALID"/>
+	<value value="48" name="TE_OUT_PRIM_READ"/>
+</enum>
+
+<enum name="a2xx_tcr_perfcount_select">
+	<value value="0" name="DGMMPD_IPMUX0_STALL"/>
+	<value value="4" name="DGMMPD_IPMUX_ALL_STALL"/>
+	<value value="5" name="OPMUX0_L2_WRITES"/>
+</enum>
+
+<enum name="a2xx_tp_perfcount_select">
+	<value value="0" name="POINT_QUADS"/>
+	<value value="1" name="BILIN_QUADS"/>
+	<value value="2" name="ANISO_QUADS"/>
+	<value value="3" name="MIP_QUADS"/>
+	<value value="4" name="VOL_QUADS"/>
+	<value value="5" name="MIP_VOL_QUADS"/>
+	<value value="6" name="MIP_ANISO_QUADS"/>
+	<value value="7" name="VOL_ANISO_QUADS"/>
+	<value value="8" name="ANISO_2_1_QUADS"/>
+	<value value="9" name="ANISO_4_1_QUADS"/>
+	<value value="10" name="ANISO_6_1_QUADS"/>
+	<value value="11" name="ANISO_8_1_QUADS"/>
+	<value value="12" name="ANISO_10_1_QUADS"/>
+	<value value="13" name="ANISO_12_1_QUADS"/>
+	<value value="14" name="ANISO_14_1_QUADS"/>
+	<value value="15" name="ANISO_16_1_QUADS"/>
+	<value value="16" name="MIP_VOL_ANISO_QUADS"/>
+	<value value="17" name="ALIGN_2_QUADS"/>
+	<value value="18" name="ALIGN_4_QUADS"/>
+	<value value="19" name="PIX_0_QUAD"/>
+	<value value="20" name="PIX_1_QUAD"/>
+	<value value="21" name="PIX_2_QUAD"/>
+	<value value="22" name="PIX_3_QUAD"/>
+	<value value="23" name="PIX_4_QUAD"/>
+	<value value="24" name="TP_MIPMAP_LOD0"/>
+	<value value="25" name="TP_MIPMAP_LOD1"/>
+	<value value="26" name="TP_MIPMAP_LOD2"/>
+	<value value="27" name="TP_MIPMAP_LOD3"/>
+	<value value="28" name="TP_MIPMAP_LOD4"/>
+	<value value="29" name="TP_MIPMAP_LOD5"/>
+	<value value="30" name="TP_MIPMAP_LOD6"/>
+	<value value="31" name="TP_MIPMAP_LOD7"/>
+	<value value="32" name="TP_MIPMAP_LOD8"/>
+	<value value="33" name="TP_MIPMAP_LOD9"/>
+	<value value="34" name="TP_MIPMAP_LOD10"/>
+	<value value="35" name="TP_MIPMAP_LOD11"/>
+	<value value="36" name="TP_MIPMAP_LOD12"/>
+	<value value="37" name="TP_MIPMAP_LOD13"/>
+	<value value="38" name="TP_MIPMAP_LOD14"/>
+</enum>
+
+<enum name="a2xx_tcm_perfcount_select">
+	<value value="0" name="QUAD0_RD_LAT_FIFO_EMPTY"/>
+	<value value="3" name="QUAD0_RD_LAT_FIFO_4TH_FULL"/>
+	<value value="4" name="QUAD0_RD_LAT_FIFO_HALF_FULL"/>
+	<value value="5" name="QUAD0_RD_LAT_FIFO_FULL"/>
+	<value value="6" name="QUAD0_RD_LAT_FIFO_LT_4TH_FULL"/>
+	<value value="28" name="READ_STARVED_QUAD0"/>
+	<value value="32" name="READ_STARVED"/>
+	<value value="33" name="READ_STALLED_QUAD0"/>
+	<value value="37" name="READ_STALLED"/>
+	<value value="38" name="VALID_READ_QUAD0"/>
+	<value value="42" name="TC_TP_STARVED_QUAD0"/>
+	<value value="46" name="TC_TP_STARVED"/>
+</enum>
+
+<enum name="a2xx_tcf_perfcount_select">
+	<value value="0" name="VALID_CYCLES"/>
+	<value value="1" name="SINGLE_PHASES"/>
+	<value value="2" name="ANISO_PHASES"/>
+	<value value="3" name="MIP_PHASES"/>
+	<value value="4" name="VOL_PHASES"/>
+	<value value="5" name="MIP_VOL_PHASES"/>
+	<value value="6" name="MIP_ANISO_PHASES"/>
+	<value value="7" name="VOL_ANISO_PHASES"/>
+	<value value="8" name="ANISO_2_1_PHASES"/>
+	<value value="9" name="ANISO_4_1_PHASES"/>
+	<value value="10" name="ANISO_6_1_PHASES"/>
+	<value value="11" name="ANISO_8_1_PHASES"/>
+	<value value="12" name="ANISO_10_1_PHASES"/>
+	<value value="13" name="ANISO_12_1_PHASES"/>
+	<value value="14" name="ANISO_14_1_PHASES"/>
+	<value value="15" name="ANISO_16_1_PHASES"/>
+	<value value="16" name="MIP_VOL_ANISO_PHASES"/>
+	<value value="17" name="ALIGN_2_PHASES"/>
+	<value value="18" name="ALIGN_4_PHASES"/>
+	<value value="19" name="TPC_BUSY"/>
+	<value value="20" name="TPC_STALLED"/>
+	<value value="21" name="TPC_STARVED"/>
+	<value value="22" name="TPC_WORKING"/>
+	<value value="23" name="TPC_WALKER_BUSY"/>
+	<value value="24" name="TPC_WALKER_STALLED"/>
+	<value value="25" name="TPC_WALKER_WORKING"/>
+	<value value="26" name="TPC_ALIGNER_BUSY"/>
+	<value value="27" name="TPC_ALIGNER_STALLED"/>
+	<value value="28" name="TPC_ALIGNER_STALLED_BY_BLEND"/>
+	<value value="29" name="TPC_ALIGNER_STALLED_BY_CACHE"/>
+	<value value="30" name="TPC_ALIGNER_WORKING"/>
+	<value value="31" name="TPC_BLEND_BUSY"/>
+	<value value="32" name="TPC_BLEND_SYNC"/>
+	<value value="33" name="TPC_BLEND_STARVED"/>
+	<value value="34" name="TPC_BLEND_WORKING"/>
+	<value value="35" name="OPCODE_0x00"/>
+	<value value="36" name="OPCODE_0x01"/>
+	<value value="37" name="OPCODE_0x04"/>
+	<value value="38" name="OPCODE_0x10"/>
+	<value value="39" name="OPCODE_0x11"/>
+	<value value="40" name="OPCODE_0x12"/>
+	<value value="41" name="OPCODE_0x13"/>
+	<value value="42" name="OPCODE_0x18"/>
+	<value value="43" name="OPCODE_0x19"/>
+	<value value="44" name="OPCODE_0x1A"/>
+	<value value="45" name="OPCODE_OTHER"/>
+	<value value="56" name="IN_FIFO_0_EMPTY"/>
+	<value value="57" name="IN_FIFO_0_LT_HALF_FULL"/>
+	<value value="58" name="IN_FIFO_0_HALF_FULL"/>
+	<value value="59" name="IN_FIFO_0_FULL"/>
+	<value value="72" name="IN_FIFO_TPC_EMPTY"/>
+	<value value="73" name="IN_FIFO_TPC_LT_HALF_FULL"/>
+	<value value="74" name="IN_FIFO_TPC_HALF_FULL"/>
+	<value value="75" name="IN_FIFO_TPC_FULL"/>
+	<value value="76" name="TPC_TC_XFC"/>
+	<value value="77" name="TPC_TC_STATE"/>
+	<value value="78" name="TC_STALL"/>
+	<value value="79" name="QUAD0_TAPS"/>
+	<value value="83" name="QUADS"/>
+	<value value="84" name="TCA_SYNC_STALL"/>
+	<value value="85" name="TAG_STALL"/>
+	<value value="88" name="TCB_SYNC_STALL"/>
+	<value value="89" name="TCA_VALID"/>
+	<value value="90" name="PROBES_VALID"/>
+	<value value="91" name="MISS_STALL"/>
+	<value value="92" name="FETCH_FIFO_STALL"/>
+	<value value="93" name="TCO_STALL"/>
+	<value value="94" name="ANY_STALL"/>
+	<value value="95" name="TAG_MISSES"/>
+	<value value="96" name="TAG_HITS"/>
+	<value value="97" name="SUB_TAG_MISSES"/>
+	<value value="98" name="SET0_INVALIDATES"/>
+	<value value="99" name="SET1_INVALIDATES"/>
+	<value value="100" name="SET2_INVALIDATES"/>
+	<value value="101" name="SET3_INVALIDATES"/>
+	<value value="102" name="SET0_TAG_MISSES"/>
+	<value value="103" name="SET1_TAG_MISSES"/>
+	<value value="104" name="SET2_TAG_MISSES"/>
+	<value value="105" name="SET3_TAG_MISSES"/>
+	<value value="106" name="SET0_TAG_HITS"/>
+	<value value="107" name="SET1_TAG_HITS"/>
+	<value value="108" name="SET2_TAG_HITS"/>
+	<value value="109" name="SET3_TAG_HITS"/>
+	<value value="110" name="SET0_SUB_TAG_MISSES"/>
+	<value value="111" name="SET1_SUB_TAG_MISSES"/>
+	<value value="112" name="SET2_SUB_TAG_MISSES"/>
+	<value value="113" name="SET3_SUB_TAG_MISSES"/>
+	<value value="114" name="SET0_EVICT1"/>
+	<value value="115" name="SET0_EVICT2"/>
+	<value value="116" name="SET0_EVICT3"/>
+	<value value="117" name="SET0_EVICT4"/>
+	<value value="118" name="SET0_EVICT5"/>
+	<value value="119" name="SET0_EVICT6"/>
+	<value value="120" name="SET0_EVICT7"/>
+	<value value="121" name="SET0_EVICT8"/>
+	<value value="130" name="SET1_EVICT1"/>
+	<value value="131" name="SET1_EVICT2"/>
+	<value value="132" name="SET1_EVICT3"/>
+	<value value="133" name="SET1_EVICT4"/>
+	<value value="134" name="SET1_EVICT5"/>
+	<value value="135" name="SET1_EVICT6"/>
+	<value value="136" name="SET1_EVICT7"/>
+	<value value="137" name="SET1_EVICT8"/>
+	<value value="146" name="SET2_EVICT1"/>
+	<value value="147" name="SET2_EVICT2"/>
+	<value value="148" name="SET2_EVICT3"/>
+	<value value="149" name="SET2_EVICT4"/>
+	<value value="150" name="SET2_EVICT5"/>
+	<value value="151" name="SET2_EVICT6"/>
+	<value value="152" name="SET2_EVICT7"/>
+	<value value="153" name="SET2_EVICT8"/>
+	<value value="162" name="SET3_EVICT1"/>
+	<value value="163" name="SET3_EVICT2"/>
+	<value value="164" name="SET3_EVICT3"/>
+	<value value="165" name="SET3_EVICT4"/>
+	<value value="166" name="SET3_EVICT5"/>
+	<value value="167" name="SET3_EVICT6"/>
+	<value value="168" name="SET3_EVICT7"/>
+	<value value="169" name="SET3_EVICT8"/>
+	<value value="178" name="FF_EMPTY"/>
+	<value value="179" name="FF_LT_HALF_FULL"/>
+	<value value="180" name="FF_HALF_FULL"/>
+	<value value="181" name="FF_FULL"/>
+	<value value="182" name="FF_XFC"/>
+	<value value="183" name="FF_STALLED"/>
+	<value value="184" name="FG_MASKS"/>
+	<value value="185" name="FG_LEFT_MASKS"/>
+	<value value="186" name="FG_LEFT_MASK_STALLED"/>
+	<value value="187" name="FG_LEFT_NOT_DONE_STALL"/>
+	<value value="188" name="FG_LEFT_FG_STALL"/>
+	<value value="189" name="FG_LEFT_SECTORS"/>
+	<value value="195" name="FG0_REQUESTS"/>
+	<value value="196" name="FG0_STALLED"/>
+	<value value="199" name="MEM_REQ512"/>
+	<value value="200" name="MEM_REQ_SENT"/>
+	<value value="202" name="MEM_LOCAL_READ_REQ"/>
+	<value value="203" name="TC0_MH_STALLED"/>
+</enum>
+
+<enum name="a2xx_sq_perfcnt_select">
+	<value value="0" name="SQ_PIXEL_VECTORS_SUB"/>
+	<value value="1" name="SQ_VERTEX_VECTORS_SUB"/>
+	<value value="2" name="SQ_ALU0_ACTIVE_VTX_SIMD0"/>
+	<value value="3" name="SQ_ALU1_ACTIVE_VTX_SIMD0"/>
+	<value value="4" name="SQ_ALU0_ACTIVE_PIX_SIMD0"/>
+	<value value="5" name="SQ_ALU1_ACTIVE_PIX_SIMD0"/>
+	<value value="6" name="SQ_ALU0_ACTIVE_VTX_SIMD1"/>
+	<value value="7" name="SQ_ALU1_ACTIVE_VTX_SIMD1"/>
+	<value value="8" name="SQ_ALU0_ACTIVE_PIX_SIMD1"/>
+	<value value="9" name="SQ_ALU1_ACTIVE_PIX_SIMD1"/>
+	<value value="10" name="SQ_EXPORT_CYCLES"/>
+	<value value="11" name="SQ_ALU_CST_WRITTEN"/>
+	<value value="12" name="SQ_TEX_CST_WRITTEN"/>
+	<value value="13" name="SQ_ALU_CST_STALL"/>
+	<value value="14" name="SQ_ALU_TEX_STALL"/>
+	<value value="15" name="SQ_INST_WRITTEN"/>
+	<value value="16" name="SQ_BOOLEAN_WRITTEN"/>
+	<value value="17" name="SQ_LOOPS_WRITTEN"/>
+	<value value="18" name="SQ_PIXEL_SWAP_IN"/>
+	<value value="19" name="SQ_PIXEL_SWAP_OUT"/>
+	<value value="20" name="SQ_VERTEX_SWAP_IN"/>
+	<value value="21" name="SQ_VERTEX_SWAP_OUT"/>
+	<value value="22" name="SQ_ALU_VTX_INST_ISSUED"/>
+	<value value="23" name="SQ_TEX_VTX_INST_ISSUED"/>
+	<value value="24" name="SQ_VC_VTX_INST_ISSUED"/>
+	<value value="25" name="SQ_CF_VTX_INST_ISSUED"/>
+	<value value="26" name="SQ_ALU_PIX_INST_ISSUED"/>
+	<value value="27" name="SQ_TEX_PIX_INST_ISSUED"/>
+	<value value="28" name="SQ_VC_PIX_INST_ISSUED"/>
+	<value value="29" name="SQ_CF_PIX_INST_ISSUED"/>
+	<value value="30" name="SQ_ALU0_FIFO_EMPTY_SIMD0"/>
+	<value value="31" name="SQ_ALU1_FIFO_EMPTY_SIMD0"/>
+	<value value="32" name="SQ_ALU0_FIFO_EMPTY_SIMD1"/>
+	<value value="33" name="SQ_ALU1_FIFO_EMPTY_SIMD1"/>
+	<value value="34" name="SQ_ALU_NOPS"/>
+	<value value="35" name="SQ_PRED_SKIP"/>
+	<value value="36" name="SQ_SYNC_ALU_STALL_SIMD0_VTX"/>
+	<value value="37" name="SQ_SYNC_ALU_STALL_SIMD1_VTX"/>
+	<value value="38" name="SQ_SYNC_TEX_STALL_VTX"/>
+	<value value="39" name="SQ_SYNC_VC_STALL_VTX"/>
+	<value value="40" name="SQ_CONSTANTS_USED_SIMD0"/>
+	<value value="41" name="SQ_CONSTANTS_SENT_SP_SIMD0"/>
+	<value value="42" name="SQ_GPR_STALL_VTX"/>
+	<value value="43" name="SQ_GPR_STALL_PIX"/>
+	<value value="44" name="SQ_VTX_RS_STALL"/>
+	<value value="45" name="SQ_PIX_RS_STALL"/>
+	<value value="46" name="SQ_SX_PC_FULL"/>
+	<value value="47" name="SQ_SX_EXP_BUFF_FULL"/>
+	<value value="48" name="SQ_SX_POS_BUFF_FULL"/>
+	<value value="49" name="SQ_INTERP_QUADS"/>
+	<value value="50" name="SQ_INTERP_ACTIVE"/>
+	<value value="51" name="SQ_IN_PIXEL_STALL"/>
+	<value value="52" name="SQ_IN_VTX_STALL"/>
+	<value value="53" name="SQ_VTX_CNT"/>
+	<value value="54" name="SQ_VTX_VECTOR2"/>
+	<value value="55" name="SQ_VTX_VECTOR3"/>
+	<value value="56" name="SQ_VTX_VECTOR4"/>
+	<value value="57" name="SQ_PIXEL_VECTOR1"/>
+	<value value="58" name="SQ_PIXEL_VECTOR23"/>
+	<value value="59" name="SQ_PIXEL_VECTOR4"/>
+	<value value="60" name="SQ_CONSTANTS_USED_SIMD1"/>
+	<value value="61" name="SQ_CONSTANTS_SENT_SP_SIMD1"/>
+	<value value="62" name="SQ_SX_MEM_EXP_FULL"/>
+	<value value="63" name="SQ_ALU0_ACTIVE_VTX_SIMD2"/>
+	<value value="64" name="SQ_ALU1_ACTIVE_VTX_SIMD2"/>
+	<value value="65" name="SQ_ALU0_ACTIVE_PIX_SIMD2"/>
+	<value value="66" name="SQ_ALU1_ACTIVE_PIX_SIMD2"/>
+	<value value="67" name="SQ_ALU0_ACTIVE_VTX_SIMD3"/>
+	<value value="68" name="SQ_PERFCOUNT_VTX_QUAL_TP_DONE"/>
+	<value value="69" name="SQ_ALU0_ACTIVE_PIX_SIMD3"/>
+	<value value="70" name="SQ_PERFCOUNT_PIX_QUAL_TP_DONE"/>
+	<value value="71" name="SQ_ALU0_FIFO_EMPTY_SIMD2"/>
+	<value value="72" name="SQ_ALU1_FIFO_EMPTY_SIMD2"/>
+	<value value="73" name="SQ_ALU0_FIFO_EMPTY_SIMD3"/>
+	<value value="74" name="SQ_ALU1_FIFO_EMPTY_SIMD3"/>
+	<value value="75" name="SQ_SYNC_ALU_STALL_SIMD2_VTX"/>
+	<value value="76" name="SQ_PERFCOUNT_VTX_POP_THREAD"/>
+	<value value="77" name="SQ_SYNC_ALU_STALL_SIMD0_PIX"/>
+	<value value="78" name="SQ_SYNC_ALU_STALL_SIMD1_PIX"/>
+	<value value="79" name="SQ_SYNC_ALU_STALL_SIMD2_PIX"/>
+	<value value="80" name="SQ_PERFCOUNT_PIX_POP_THREAD"/>
+	<value value="81" name="SQ_SYNC_TEX_STALL_PIX"/>
+	<value value="82" name="SQ_SYNC_VC_STALL_PIX"/>
+	<value value="83" name="SQ_CONSTANTS_USED_SIMD2"/>
+	<value value="84" name="SQ_CONSTANTS_SENT_SP_SIMD2"/>
+	<value value="85" name="SQ_PERFCOUNT_VTX_DEALLOC_ACK"/>
+	<value value="86" name="SQ_PERFCOUNT_PIX_DEALLOC_ACK"/>
+	<value value="87" name="SQ_ALU0_FIFO_FULL_SIMD0"/>
+	<value value="88" name="SQ_ALU1_FIFO_FULL_SIMD0"/>
+	<value value="89" name="SQ_ALU0_FIFO_FULL_SIMD1"/>
+	<value value="90" name="SQ_ALU1_FIFO_FULL_SIMD1"/>
+	<value value="91" name="SQ_ALU0_FIFO_FULL_SIMD2"/>
+	<value value="92" name="SQ_ALU1_FIFO_FULL_SIMD2"/>
+	<value value="93" name="SQ_ALU0_FIFO_FULL_SIMD3"/>
+	<value value="94" name="SQ_ALU1_FIFO_FULL_SIMD3"/>
+	<value value="95" name="VC_PERF_STATIC"/>
+	<value value="96" name="VC_PERF_STALLED"/>
+	<value value="97" name="VC_PERF_STARVED"/>
+	<value value="98" name="VC_PERF_SEND"/>
+	<value value="99" name="VC_PERF_ACTUAL_STARVED"/>
+	<value value="100" name="PIXEL_THREAD_0_ACTIVE"/>
+	<value value="101" name="VERTEX_THREAD_0_ACTIVE"/>
+	<value value="102" name="PIXEL_THREAD_0_NUMBER"/>
+	<value value="103" name="VERTEX_THREAD_0_NUMBER"/>
+	<value value="104" name="VERTEX_EVENT_NUMBER"/>
+	<value value="105" name="PIXEL_EVENT_NUMBER"/>
+	<value value="106" name="PTRBUFF_EF_PUSH"/>
+	<value value="107" name="PTRBUFF_EF_POP_EVENT"/>
+	<value value="108" name="PTRBUFF_EF_POP_NEW_VTX"/>
+	<value value="109" name="PTRBUFF_EF_POP_DEALLOC"/>
+	<value value="110" name="PTRBUFF_EF_POP_PVECTOR"/>
+	<value value="111" name="PTRBUFF_EF_POP_PVECTOR_X"/>
+	<value value="112" name="PTRBUFF_EF_POP_PVECTOR_VNZ"/>
+	<value value="113" name="PTRBUFF_PB_DEALLOC"/>
+	<value value="114" name="PTRBUFF_PI_STATE_PPB_POP"/>
+	<value value="115" name="PTRBUFF_PI_RTR"/>
+	<value value="116" name="PTRBUFF_PI_READ_EN"/>
+	<value value="117" name="PTRBUFF_PI_BUFF_SWAP"/>
+	<value value="118" name="PTRBUFF_SQ_FREE_BUFF"/>
+	<value value="119" name="PTRBUFF_SQ_DEC"/>
+	<value value="120" name="PTRBUFF_SC_VALID_CNTL_EVENT"/>
+	<value value="121" name="PTRBUFF_SC_VALID_IJ_XFER"/>
+	<value value="122" name="PTRBUFF_SC_NEW_VECTOR_1_Q"/>
+	<value value="123" name="PTRBUFF_QUAL_NEW_VECTOR"/>
+	<value value="124" name="PTRBUFF_QUAL_EVENT"/>
+	<value value="125" name="PTRBUFF_END_BUFFER"/>
+	<value value="126" name="PTRBUFF_FILL_QUAD"/>
+	<value value="127" name="VERTS_WRITTEN_SPI"/>
+	<value value="128" name="TP_FETCH_INSTR_EXEC"/>
+	<value value="129" name="TP_FETCH_INSTR_REQ"/>
+	<value value="130" name="TP_DATA_RETURN"/>
+	<value value="131" name="SPI_WRITE_CYCLES_SP"/>
+	<value value="132" name="SPI_WRITES_SP"/>
+	<value value="133" name="SP_ALU_INSTR_EXEC"/>
+	<value value="134" name="SP_CONST_ADDR_TO_SQ"/>
+	<value value="135" name="SP_PRED_KILLS_TO_SQ"/>
+	<value value="136" name="SP_EXPORT_CYCLES_TO_SX"/>
+	<value value="137" name="SP_EXPORTS_TO_SX"/>
+	<value value="138" name="SQ_CYCLES_ELAPSED"/>
+	<value value="139" name="SQ_TCFS_OPT_ALLOC_EXEC"/>
+	<value value="140" name="SQ_TCFS_NO_OPT_ALLOC"/>
+	<value value="141" name="SQ_ALU0_NO_OPT_ALLOC"/>
+	<value value="142" name="SQ_ALU1_NO_OPT_ALLOC"/>
+	<value value="143" name="SQ_TCFS_ARB_XFC_CNT"/>
+	<value value="144" name="SQ_ALU0_ARB_XFC_CNT"/>
+	<value value="145" name="SQ_ALU1_ARB_XFC_CNT"/>
+	<value value="146" name="SQ_TCFS_CFS_UPDATE_CNT"/>
+	<value value="147" name="SQ_ALU0_CFS_UPDATE_CNT"/>
+	<value value="148" name="SQ_ALU1_CFS_UPDATE_CNT"/>
+	<value value="149" name="SQ_VTX_PUSH_THREAD_CNT"/>
+	<value value="150" name="SQ_VTX_POP_THREAD_CNT"/>
+	<value value="151" name="SQ_PIX_PUSH_THREAD_CNT"/>
+	<value value="152" name="SQ_PIX_POP_THREAD_CNT"/>
+	<value value="153" name="SQ_PIX_TOTAL"/>
+	<value value="154" name="SQ_PIX_KILLED"/>
+</enum>
+
+<enum name="a2xx_sx_perfcnt_select">
+	<value value="0" name="SX_EXPORT_VECTORS"/>
+	<value value="1" name="SX_DUMMY_QUADS"/>
+	<value value="2" name="SX_ALPHA_FAIL"/>
+	<value value="3" name="SX_RB_QUAD_BUSY"/>
+	<value value="4" name="SX_RB_COLOR_BUSY"/>
+	<value value="5" name="SX_RB_QUAD_STALL"/>
+	<value value="6" name="SX_RB_COLOR_STALL"/>
+</enum>
+
+<enum name="a2xx_rbbm_perfcount1_sel">
+	<value value="0" name="RBBM1_COUNT"/>
+	<value value="1" name="RBBM1_NRT_BUSY"/>
+	<value value="2" name="RBBM1_RB_BUSY"/>
+	<value value="3" name="RBBM1_SQ_CNTX0_BUSY"/>
+	<value value="4" name="RBBM1_SQ_CNTX17_BUSY"/>
+	<value value="5" name="RBBM1_VGT_BUSY"/>
+	<value value="6" name="RBBM1_VGT_NODMA_BUSY"/>
+	<value value="7" name="RBBM1_PA_BUSY"/>
+	<value value="8" name="RBBM1_SC_CNTX_BUSY"/>
+	<value value="9" name="RBBM1_TPC_BUSY"/>
+	<value value="10" name="RBBM1_TC_BUSY"/>
+	<value value="11" name="RBBM1_SX_BUSY"/>
+	<value value="12" name="RBBM1_CP_COHER_BUSY"/>
+	<value value="13" name="RBBM1_CP_NRT_BUSY"/>
+	<value value="14" name="RBBM1_GFX_IDLE_STALL"/>
+	<value value="15" name="RBBM1_INTERRUPT"/>
+</enum>
+
+<enum name="a2xx_cp_perfcount_sel">
+	<value value="0" name="ALWAYS_COUNT"/>
+	<value value="1" name="TRANS_FIFO_FULL"/>
+	<value value="2" name="TRANS_FIFO_AF"/>
+	<value value="3" name="RCIU_PFPTRANS_WAIT"/>
+	<value value="6" name="RCIU_NRTTRANS_WAIT"/>
+	<value value="8" name="CSF_NRT_READ_WAIT"/>
+	<value value="9" name="CSF_I1_FIFO_FULL"/>
+	<value value="10" name="CSF_I2_FIFO_FULL"/>
+	<value value="11" name="CSF_ST_FIFO_FULL"/>
+	<value value="13" name="CSF_RING_ROQ_FULL"/>
+	<value value="14" name="CSF_I1_ROQ_FULL"/>
+	<value value="15" name="CSF_I2_ROQ_FULL"/>
+	<value value="16" name="CSF_ST_ROQ_FULL"/>
+	<value value="18" name="MIU_TAG_MEM_FULL"/>
+	<value value="19" name="MIU_WRITECLEAN"/>
+	<value value="22" name="MIU_NRT_WRITE_STALLED"/>
+	<value value="23" name="MIU_NRT_READ_STALLED"/>
+	<value value="24" name="ME_WRITE_CONFIRM_FIFO_FULL"/>
+	<value value="25" name="ME_VS_DEALLOC_FIFO_FULL"/>
+	<value value="26" name="ME_PS_DEALLOC_FIFO_FULL"/>
+	<value value="27" name="ME_REGS_VS_EVENT_FIFO_FULL"/>
+	<value value="28" name="ME_REGS_PS_EVENT_FIFO_FULL"/>
+	<value value="29" name="ME_REGS_CF_EVENT_FIFO_FULL"/>
+	<value value="30" name="ME_MICRO_RB_STARVED"/>
+	<value value="31" name="ME_MICRO_I1_STARVED"/>
+	<value value="32" name="ME_MICRO_I2_STARVED"/>
+	<value value="33" name="ME_MICRO_ST_STARVED"/>
+	<value value="40" name="RCIU_RBBM_DWORD_SENT"/>
+	<value value="41" name="ME_BUSY_CLOCKS"/>
+	<value value="42" name="ME_WAIT_CONTEXT_AVAIL"/>
+	<value value="43" name="PFP_TYPE0_PACKET"/>
+	<value value="44" name="PFP_TYPE3_PACKET"/>
+	<value value="45" name="CSF_RB_WPTR_NEQ_RPTR"/>
+	<value value="46" name="CSF_I1_SIZE_NEQ_ZERO"/>
+	<value value="47" name="CSF_I2_SIZE_NEQ_ZERO"/>
+	<value value="48" name="CSF_RBI1I2_FETCHING"/>
+</enum>
+
+<enum name="a2xx_rb_perfcnt_select">
+	<value value="0" name="RBPERF_CNTX_BUSY"/>
+	<value value="1" name="RBPERF_CNTX_BUSY_MAX"/>
+	<value value="2" name="RBPERF_SX_QUAD_STARVED"/>
+	<value value="3" name="RBPERF_SX_QUAD_STARVED_MAX"/>
+	<value value="4" name="RBPERF_GA_GC_CH0_SYS_REQ"/>
+	<value value="5" name="RBPERF_GA_GC_CH0_SYS_REQ_MAX"/>
+	<value value="6" name="RBPERF_GA_GC_CH1_SYS_REQ"/>
+	<value value="7" name="RBPERF_GA_GC_CH1_SYS_REQ_MAX"/>
+	<value value="8" name="RBPERF_MH_STARVED"/>
+	<value value="9" name="RBPERF_MH_STARVED_MAX"/>
+	<value value="10" name="RBPERF_AZ_BC_COLOR_BUSY"/>
+	<value value="11" name="RBPERF_AZ_BC_COLOR_BUSY_MAX"/>
+	<value value="12" name="RBPERF_AZ_BC_Z_BUSY"/>
+	<value value="13" name="RBPERF_AZ_BC_Z_BUSY_MAX"/>
+	<value value="14" name="RBPERF_RB_SC_TILE_RTR_N"/>
+	<value value="15" name="RBPERF_RB_SC_TILE_RTR_N_MAX"/>
+	<value value="16" name="RBPERF_RB_SC_SAMP_RTR_N"/>
+	<value value="17" name="RBPERF_RB_SC_SAMP_RTR_N_MAX"/>
+	<value value="18" name="RBPERF_RB_SX_QUAD_RTR_N"/>
+	<value value="19" name="RBPERF_RB_SX_QUAD_RTR_N_MAX"/>
+	<value value="20" name="RBPERF_RB_SX_COLOR_RTR_N"/>
+	<value value="21" name="RBPERF_RB_SX_COLOR_RTR_N_MAX"/>
+	<value value="22" name="RBPERF_RB_SC_SAMP_LZ_BUSY"/>
+	<value value="23" name="RBPERF_RB_SC_SAMP_LZ_BUSY_MAX"/>
+	<value value="24" name="RBPERF_ZXP_STALL"/>
+	<value value="25" name="RBPERF_ZXP_STALL_MAX"/>
+	<value value="26" name="RBPERF_EVENT_PENDING"/>
+	<value value="27" name="RBPERF_EVENT_PENDING_MAX"/>
+	<value value="28" name="RBPERF_RB_MH_VALID"/>
+	<value value="29" name="RBPERF_RB_MH_VALID_MAX"/>
+	<value value="30" name="RBPERF_SX_RB_QUAD_SEND"/>
+	<value value="31" name="RBPERF_SX_RB_COLOR_SEND"/>
+	<value value="32" name="RBPERF_SC_RB_TILE_SEND"/>
+	<value value="33" name="RBPERF_SC_RB_SAMPLE_SEND"/>
+	<value value="34" name="RBPERF_SX_RB_MEM_EXPORT"/>
+	<value value="35" name="RBPERF_SX_RB_QUAD_EVENT"/>
+	<value value="36" name="RBPERF_SC_RB_TILE_EVENT_FILTERED"/>
+	<value value="37" name="RBPERF_SC_RB_TILE_EVENT_ALL"/>
+	<value value="38" name="RBPERF_RB_SC_EZ_SEND"/>
+	<value value="39" name="RBPERF_RB_SX_INDEX_SEND"/>
+	<value value="40" name="RBPERF_GMEM_INTFO_RD"/>
+	<value value="41" name="RBPERF_GMEM_INTF1_RD"/>
+	<value value="42" name="RBPERF_GMEM_INTFO_WR"/>
+	<value value="43" name="RBPERF_GMEM_INTF1_WR"/>
+	<value value="44" name="RBPERF_RB_CP_CONTEXT_DONE"/>
+	<value value="45" name="RBPERF_RB_CP_CACHE_FLUSH"/>
+	<value value="46" name="RBPERF_ZPASS_DONE"/>
+	<value value="47" name="RBPERF_ZCMD_VALID"/>
+	<value value="48" name="RBPERF_CCMD_VALID"/>
+	<value value="49" name="RBPERF_ACCUM_GRANT"/>
+	<value value="50" name="RBPERF_ACCUM_C0_GRANT"/>
+	<value value="51" name="RBPERF_ACCUM_C1_GRANT"/>
+	<value value="52" name="RBPERF_ACCUM_FULL_BE_WR"/>
+	<value value="53" name="RBPERF_ACCUM_REQUEST_NO_GRANT"/>
+	<value value="54" name="RBPERF_ACCUM_TIMEOUT_PULSE"/>
+	<value value="55" name="RBPERF_ACCUM_LIN_TIMEOUT_PULSE"/>
+	<value value="56" name="RBPERF_ACCUM_CAM_HIT_FLUSHING"/>
+</enum>
+
+<enum name="a2xx_mh_perfcnt_select">
+	<value value="0" name="CP_R0_REQUESTS"/>
+	<value value="1" name="CP_R1_REQUESTS"/>
+	<value value="2" name="CP_R2_REQUESTS"/>
+	<value value="3" name="CP_R3_REQUESTS"/>
+	<value value="4" name="CP_R4_REQUESTS"/>
+	<value value="5" name="CP_TOTAL_READ_REQUESTS"/>
+	<value value="6" name="CP_TOTAL_WRITE_REQUESTS"/>
+	<value value="7" name="CP_TOTAL_REQUESTS"/>
+	<value value="8" name="CP_DATA_BYTES_WRITTEN"/>
+	<value value="9" name="CP_WRITE_CLEAN_RESPONSES"/>
+	<value value="10" name="CP_R0_READ_BURSTS_RECEIVED"/>
+	<value value="11" name="CP_R1_READ_BURSTS_RECEIVED"/>
+	<value value="12" name="CP_R2_READ_BURSTS_RECEIVED"/>
+	<value value="13" name="CP_R3_READ_BURSTS_RECEIVED"/>
+	<value value="14" name="CP_R4_READ_BURSTS_RECEIVED"/>
+	<value value="15" name="CP_TOTAL_READ_BURSTS_RECEIVED"/>
+	<value value="16" name="CP_R0_DATA_BEATS_READ"/>
+	<value value="17" name="CP_R1_DATA_BEATS_READ"/>
+	<value value="18" name="CP_R2_DATA_BEATS_READ"/>
+	<value value="19" name="CP_R3_DATA_BEATS_READ"/>
+	<value value="20" name="CP_R4_DATA_BEATS_READ"/>
+	<value value="21" name="CP_TOTAL_DATA_BEATS_READ"/>
+	<value value="22" name="VGT_R0_REQUESTS"/>
+	<value value="23" name="VGT_R1_REQUESTS"/>
+	<value value="24" name="VGT_TOTAL_REQUESTS"/>
+	<value value="25" name="VGT_R0_READ_BURSTS_RECEIVED"/>
+	<value value="26" name="VGT_R1_READ_BURSTS_RECEIVED"/>
+	<value value="27" name="VGT_TOTAL_READ_BURSTS_RECEIVED"/>
+	<value value="28" name="VGT_R0_DATA_BEATS_READ"/>
+	<value value="29" name="VGT_R1_DATA_BEATS_READ"/>
+	<value value="30" name="VGT_TOTAL_DATA_BEATS_READ"/>
+	<value value="31" name="TC_TOTAL_REQUESTS"/>
+	<value value="32" name="TC_ROQ_REQUESTS"/>
+	<value value="33" name="TC_INFO_SENT"/>
+	<value value="34" name="TC_READ_BURSTS_RECEIVED"/>
+	<value value="35" name="TC_DATA_BEATS_READ"/>
+	<value value="36" name="TCD_BURSTS_READ"/>
+	<value value="37" name="RB_REQUESTS"/>
+	<value value="38" name="RB_DATA_BYTES_WRITTEN"/>
+	<value value="39" name="RB_WRITE_CLEAN_RESPONSES"/>
+	<value value="40" name="AXI_READ_REQUESTS_ID_0"/>
+	<value value="41" name="AXI_READ_REQUESTS_ID_1"/>
+	<value value="42" name="AXI_READ_REQUESTS_ID_2"/>
+	<value value="43" name="AXI_READ_REQUESTS_ID_3"/>
+	<value value="44" name="AXI_READ_REQUESTS_ID_4"/>
+	<value value="45" name="AXI_READ_REQUESTS_ID_5"/>
+	<value value="46" name="AXI_READ_REQUESTS_ID_6"/>
+	<value value="47" name="AXI_READ_REQUESTS_ID_7"/>
+	<value value="48" name="AXI_TOTAL_READ_REQUESTS"/>
+	<value value="49" name="AXI_WRITE_REQUESTS_ID_0"/>
+	<value value="50" name="AXI_WRITE_REQUESTS_ID_1"/>
+	<value value="51" name="AXI_WRITE_REQUESTS_ID_2"/>
+	<value value="52" name="AXI_WRITE_REQUESTS_ID_3"/>
+	<value value="53" name="AXI_WRITE_REQUESTS_ID_4"/>
+	<value value="54" name="AXI_WRITE_REQUESTS_ID_5"/>
+	<value value="55" name="AXI_WRITE_REQUESTS_ID_6"/>
+	<value value="56" name="AXI_WRITE_REQUESTS_ID_7"/>
+	<value value="57" name="AXI_TOTAL_WRITE_REQUESTS"/>
+	<value value="58" name="AXI_TOTAL_REQUESTS_ID_0"/>
+	<value value="59" name="AXI_TOTAL_REQUESTS_ID_1"/>
+	<value value="60" name="AXI_TOTAL_REQUESTS_ID_2"/>
+	<value value="61" name="AXI_TOTAL_REQUESTS_ID_3"/>
+	<value value="62" name="AXI_TOTAL_REQUESTS_ID_4"/>
+	<value value="63" name="AXI_TOTAL_REQUESTS_ID_5"/>
+	<value value="64" name="AXI_TOTAL_REQUESTS_ID_6"/>
+	<value value="65" name="AXI_TOTAL_REQUESTS_ID_7"/>
+	<value value="66" name="AXI_TOTAL_REQUESTS"/>
+	<value value="67" name="AXI_READ_CHANNEL_BURSTS_ID_0"/>
+	<value value="68" name="AXI_READ_CHANNEL_BURSTS_ID_1"/>
+	<value value="69" name="AXI_READ_CHANNEL_BURSTS_ID_2"/>
+	<value value="70" name="AXI_READ_CHANNEL_BURSTS_ID_3"/>
+	<value value="71" name="AXI_READ_CHANNEL_BURSTS_ID_4"/>
+	<value value="72" name="AXI_READ_CHANNEL_BURSTS_ID_5"/>
+	<value value="73" name="AXI_READ_CHANNEL_BURSTS_ID_6"/>
+	<value value="74" name="AXI_READ_CHANNEL_BURSTS_ID_7"/>
+	<value value="75" name="AXI_READ_CHANNEL_TOTAL_BURSTS"/>
+	<value value="76" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_0"/>
+	<value value="77" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_1"/>
+	<value value="78" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_2"/>
+	<value value="79" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_3"/>
+	<value value="80" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_4"/>
+	<value value="81" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_5"/>
+	<value value="82" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_6"/>
+	<value value="83" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_7"/>
+	<value value="84" name="AXI_READ_CHANNEL_TOTAL_DATA_BEATS_READ"/>
+	<value value="85" name="AXI_WRITE_CHANNEL_BURSTS_ID_0"/>
+	<value value="86" name="AXI_WRITE_CHANNEL_BURSTS_ID_1"/>
+	<value value="87" name="AXI_WRITE_CHANNEL_BURSTS_ID_2"/>
+	<value value="88" name="AXI_WRITE_CHANNEL_BURSTS_ID_3"/>
+	<value value="89" name="AXI_WRITE_CHANNEL_BURSTS_ID_4"/>
+	<value value="90" name="AXI_WRITE_CHANNEL_BURSTS_ID_5"/>
+	<value value="91" name="AXI_WRITE_CHANNEL_BURSTS_ID_6"/>
+	<value value="92" name="AXI_WRITE_CHANNEL_BURSTS_ID_7"/>
+	<value value="93" name="AXI_WRITE_CHANNEL_TOTAL_BURSTS"/>
+	<value value="94" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_0"/>
+	<value value="95" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_1"/>
+	<value value="96" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_2"/>
+	<value value="97" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_3"/>
+	<value value="98" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_4"/>
+	<value value="99" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_5"/>
+	<value value="100" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_6"/>
+	<value value="101" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_7"/>
+	<value value="102" name="AXI_WRITE_CHANNEL_TOTAL_DATA_BYTES_WRITTEN"/>
+	<value value="103" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_0"/>
+	<value value="104" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_1"/>
+	<value value="105" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_2"/>
+	<value value="106" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_3"/>
+	<value value="107" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_4"/>
+	<value value="108" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_5"/>
+	<value value="109" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_6"/>
+	<value value="110" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_7"/>
+	<value value="111" name="AXI_WRITE_RESPONSE_CHANNEL_TOTAL_RESPONSES"/>
+	<value value="112" name="TOTAL_MMU_MISSES"/>
+	<value value="113" name="MMU_READ_MISSES"/>
+	<value value="114" name="MMU_WRITE_MISSES"/>
+	<value value="115" name="TOTAL_MMU_HITS"/>
+	<value value="116" name="MMU_READ_HITS"/>
+	<value value="117" name="MMU_WRITE_HITS"/>
+	<value value="118" name="SPLIT_MODE_TC_HITS"/>
+	<value value="119" name="SPLIT_MODE_TC_MISSES"/>
+	<value value="120" name="SPLIT_MODE_NON_TC_HITS"/>
+	<value value="121" name="SPLIT_MODE_NON_TC_MISSES"/>
+	<value value="122" name="STALL_AWAITING_TLB_MISS_FETCH"/>
+	<value value="123" name="MMU_TLB_MISS_READ_BURSTS_RECEIVED"/>
+	<value value="124" name="MMU_TLB_MISS_DATA_BEATS_READ"/>
+	<value value="125" name="CP_CYCLES_HELD_OFF"/>
+	<value value="126" name="VGT_CYCLES_HELD_OFF"/>
+	<value value="127" name="TC_CYCLES_HELD_OFF"/>
+	<value value="128" name="TC_ROQ_CYCLES_HELD_OFF"/>
+	<value value="129" name="TC_CYCLES_HELD_OFF_TCD_FULL"/>
+	<value value="130" name="RB_CYCLES_HELD_OFF"/>
+	<value value="131" name="TOTAL_CYCLES_ANY_CLNT_HELD_OFF"/>
+	<value value="132" name="TLB_MISS_CYCLES_HELD_OFF"/>
+	<value value="133" name="AXI_READ_REQUEST_HELD_OFF"/>
+	<value value="134" name="AXI_WRITE_REQUEST_HELD_OFF"/>
+	<value value="135" name="AXI_REQUEST_HELD_OFF"/>
+	<value value="136" name="AXI_REQUEST_HELD_OFF_INFLIGHT_LIMIT"/>
+	<value value="137" name="AXI_WRITE_DATA_HELD_OFF"/>
+	<value value="138" name="CP_SAME_PAGE_BANK_REQUESTS"/>
+	<value value="139" name="VGT_SAME_PAGE_BANK_REQUESTS"/>
+	<value value="140" name="TC_SAME_PAGE_BANK_REQUESTS"/>
+	<value value="141" name="TC_ARB_HOLD_SAME_PAGE_BANK_REQUESTS"/>
+	<value value="142" name="RB_SAME_PAGE_BANK_REQUESTS"/>
+	<value value="143" name="TOTAL_SAME_PAGE_BANK_REQUESTS"/>
+	<value value="144" name="CP_SAME_PAGE_BANK_REQUESTS_KILLED_FAIRNESS_LIMIT"/>
+	<value value="145" name="VGT_SAME_PAGE_BANK_REQUESTS_KILLED_FAIRNESS_LIMIT"/>
+	<value value="146" name="TC_SAME_PAGE_BANK_REQUESTS_KILLED_FAIRNESS_LIMIT"/>
+	<value value="147" name="RB_SAME_PAGE_BANK_REQUESTS_KILLED_FAIRNESS_LIMIT"/>
+	<value value="148" name="TOTAL_SAME_PAGE_BANK_KILLED_FAIRNESS_LIMIT"/>
+	<value value="149" name="TOTAL_MH_READ_REQUESTS"/>
+	<value value="150" name="TOTAL_MH_WRITE_REQUESTS"/>
+	<value value="151" name="TOTAL_MH_REQUESTS"/>
+	<value value="152" name="MH_BUSY"/>
+	<value value="153" name="CP_NTH_ACCESS_SAME_PAGE_BANK_SEQUENCE"/>
+	<value value="154" name="VGT_NTH_ACCESS_SAME_PAGE_BANK_SEQUENCE"/>
+	<value value="155" name="TC_NTH_ACCESS_SAME_PAGE_BANK_SEQUENCE"/>
+	<value value="156" name="RB_NTH_ACCESS_SAME_PAGE_BANK_SEQUENCE"/>
+	<value value="157" name="TC_ROQ_N_VALID_ENTRIES"/>
+	<value value="158" name="ARQ_N_ENTRIES"/>
+	<value value="159" name="WDB_N_ENTRIES"/>
+	<value value="160" name="MH_READ_LATENCY_OUTST_REQ_SUM"/>
+	<value value="161" name="MC_READ_LATENCY_OUTST_REQ_SUM"/>
+	<value value="162" name="MC_TOTAL_READ_REQUESTS"/>
+	<value value="163" name="ELAPSED_CYCLES_MH_GATED_CLK"/>
+	<value value="164" name="ELAPSED_CLK_CYCLES"/>
+	<value value="165" name="CP_W_16B_REQUESTS"/>
+	<value value="166" name="CP_W_32B_REQUESTS"/>
+	<value value="167" name="TC_16B_REQUESTS"/>
+	<value value="168" name="TC_32B_REQUESTS"/>
+	<value value="169" name="PA_REQUESTS"/>
+	<value value="170" name="PA_DATA_BYTES_WRITTEN"/>
+	<value value="171" name="PA_WRITE_CLEAN_RESPONSES"/>
+	<value value="172" name="PA_CYCLES_HELD_OFF"/>
+	<value value="173" name="AXI_READ_REQUEST_DATA_BEATS_ID_0"/>
+	<value value="174" name="AXI_READ_REQUEST_DATA_BEATS_ID_1"/>
+	<value value="175" name="AXI_READ_REQUEST_DATA_BEATS_ID_2"/>
+	<value value="176" name="AXI_READ_REQUEST_DATA_BEATS_ID_3"/>
+	<value value="177" name="AXI_READ_REQUEST_DATA_BEATS_ID_4"/>
+	<value value="178" name="AXI_READ_REQUEST_DATA_BEATS_ID_5"/>
+	<value value="179" name="AXI_READ_REQUEST_DATA_BEATS_ID_6"/>
+	<value value="180" name="AXI_READ_REQUEST_DATA_BEATS_ID_7"/>
+	<value value="181" name="AXI_TOTAL_READ_REQUEST_DATA_BEATS"/>
+</enum>
+
+<enum name="perf_mode_cnt">
+	<value name="PERF_STATE_RESET" value="0"/>
+	<value name="PERF_STATE_ENABLE" value="1"/>
+	<value name="PERF_STATE_FREEZE" value="2"/>
+</enum>
+
+<domain name="A2XX" width="32">
+
+	<bitset name="a2xx_vgt_current_bin_id_min_max" inline="yes">
+		<bitfield name="COLUMN" low="0" high="2" type="uint"/>
+		<bitfield name="ROW" low="3" high="5" type="uint"/>
+		<bitfield name="GUARD_BAND_MASK" low="6" high="8" type="uint"/>
+	</bitset>
+
+	<reg32 offset="0x0001" name="RBBM_PATCH_RELEASE"/>
+	<reg32 offset="0x003b" name="RBBM_CNTL"/>
+	<reg32 offset="0x003c" name="RBBM_SOFT_RESET"/>
+	<reg32 offset="0x00c0" name="CP_PFP_UCODE_ADDR"/>
+	<reg32 offset="0x00c1" name="CP_PFP_UCODE_DATA"/>
+
+	<enum name="adreno_mmu_clnt_beh">
+		<value name="BEH_NEVR" value="0"/>
+		<value name="BEH_TRAN_RNG" value="1"/>
+		<value name="BEH_TRAN_FLT" value="2"/>
+	</enum>
+
+	<!--
+		Note: these seem applicable only for a2xx devices with gpummu?  At
+		any rate, MH_MMU_CONFIG shows up in places in a3xx firmware where
+		it doesn't make sense, so I think offset 0x40 must be a different
+		register on a3xx.. so moving this back into A2XX domain:
+	 -->
+	<reg32 offset="0x0040" name="MH_MMU_CONFIG">
+		<bitfield name="MMU_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="SPLIT_MODE_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="RB_W_CLNT_BEHAVIOR" low="4" high="5" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="CP_W_CLNT_BEHAVIOR" low="6" high="7" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="CP_R0_CLNT_BEHAVIOR" low="8" high="9" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="CP_R1_CLNT_BEHAVIOR" low="10" high="11" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="CP_R2_CLNT_BEHAVIOR" low="12" high="13" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="CP_R3_CLNT_BEHAVIOR" low="14" high="15" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="CP_R4_CLNT_BEHAVIOR" low="16" high="17" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="VGT_R0_CLNT_BEHAVIOR" low="18" high="19" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="VGT_R1_CLNT_BEHAVIOR" low="20" high="21" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="TC_R_CLNT_BEHAVIOR" low="22" high="23" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="PA_W_CLNT_BEHAVIOR" low="24" high="25" type="adreno_mmu_clnt_beh"/>
+	</reg32>
+	<reg32 offset="0x0041" name="MH_MMU_VA_RANGE">
+		<bitfield name="NUM_64KB_REGIONS" low="0" high="11" type="uint"/>
+		<bitfield name="VA_BASE" low="12" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0042" name="MH_MMU_PT_BASE"/>
+	<reg32 offset="0x0043" name="MH_MMU_PAGE_FAULT"/>
+	<reg32 offset="0x0044" name="MH_MMU_TRAN_ERROR"/>
+	<reg32 offset="0x0045" name="MH_MMU_INVALIDATE">
+		<bitfield name="INVALIDATE_ALL" pos="0" type="boolean"/>
+		<bitfield name="INVALIDATE_TC" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0046" name="MH_MMU_MPU_BASE"/>
+	<reg32 offset="0x0047" name="MH_MMU_MPU_END"/>
+
+	<reg32 offset="0x0394" name="NQWAIT_UNTIL"/>
+	<reg32 offset="0x0395" name="RBBM_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0396" name="RBBM_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0397" name="RBBM_PERFCOUNTER0_LO"/>
+	<reg32 offset="0x0398" name="RBBM_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0399" name="RBBM_PERFCOUNTER1_LO"/>
+	<reg32 offset="0x039a" name="RBBM_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x039b" name="RBBM_DEBUG"/>
+	<reg32 offset="0x039c" name="RBBM_PM_OVERRIDE1">
+		<bitfield name="RBBM_AHBCLK_PM_OVERRIDE" pos="0" type="boolean"/>
+		<bitfield name="SC_REG_SCLK_PM_OVERRIDE" pos="1" type="boolean"/>
+		<bitfield name="SC_SCLK_PM_OVERRIDE" pos="2" type="boolean"/>
+		<bitfield name="SP_TOP_SCLK_PM_OVERRIDE" pos="3" type="boolean"/>
+		<bitfield name="SP_V0_SCLK_PM_OVERRIDE" pos="4" type="boolean"/>
+		<bitfield name="SQ_REG_SCLK_PM_OVERRIDE" pos="5" type="boolean"/>
+		<bitfield name="SQ_REG_FIFOS_SCLK_PM_OVERRIDE" pos="6" type="boolean"/>
+		<bitfield name="SQ_CONST_MEM_SCLK_PM_OVERRIDE" pos="7" type="boolean"/>
+		<bitfield name="SQ_SQ_SCLK_PM_OVERRIDE" pos="8" type="boolean"/>
+		<bitfield name="SX_SCLK_PM_OVERRIDE" pos="9" type="boolean"/>
+		<bitfield name="SX_REG_SCLK_PM_OVERRIDE" pos="10" type="boolean"/>
+		<bitfield name="TCM_TCO_SCLK_PM_OVERRIDE" pos="11" type="boolean"/>
+		<bitfield name="TCM_TCM_SCLK_PM_OVERRIDE" pos="12" type="boolean"/>
+		<bitfield name="TCM_TCD_SCLK_PM_OVERRIDE" pos="13" type="boolean"/>
+		<bitfield name="TCM_REG_SCLK_PM_OVERRIDE" pos="14" type="boolean"/>
+		<bitfield name="TPC_TPC_SCLK_PM_OVERRIDE" pos="15" type="boolean"/>
+		<bitfield name="TPC_REG_SCLK_PM_OVERRIDE" pos="16" type="boolean"/>
+		<bitfield name="TCF_TCA_SCLK_PM_OVERRIDE" pos="17" type="boolean"/>
+		<bitfield name="TCF_TCB_SCLK_PM_OVERRIDE" pos="18" type="boolean"/>
+		<bitfield name="TCF_TCB_READ_SCLK_PM_OVERRIDE" pos="19" type="boolean"/>
+		<bitfield name="TP_TP_SCLK_PM_OVERRIDE" pos="20" type="boolean"/>
+		<bitfield name="TP_REG_SCLK_PM_OVERRIDE" pos="21" type="boolean"/>
+		<bitfield name="CP_G_SCLK_PM_OVERRIDE" pos="22" type="boolean"/>
+		<bitfield name="CP_REG_SCLK_PM_OVERRIDE" pos="23" type="boolean"/>
+		<bitfield name="CP_G_REG_SCLK_PM_OVERRIDE" pos="24" type="boolean"/>
+		<bitfield name="SPI_SCLK_PM_OVERRIDE" pos="25" type="boolean"/>
+		<bitfield name="RB_REG_SCLK_PM_OVERRIDE" pos="26" type="boolean"/>
+		<bitfield name="RB_SCLK_PM_OVERRIDE" pos="27" type="boolean"/>
+		<bitfield name="MH_MH_SCLK_PM_OVERRIDE" pos="28" type="boolean"/>
+		<bitfield name="MH_REG_SCLK_PM_OVERRIDE" pos="29" type="boolean"/>
+		<bitfield name="MH_MMU_SCLK_PM_OVERRIDE" pos="30" type="boolean"/>
+		<bitfield name="MH_TCROQ_SCLK_PM_OVERRIDE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x039d" name="RBBM_PM_OVERRIDE2">
+		<bitfield name="PA_REG_SCLK_PM_OVERRIDE" pos="0" type="boolean"/>
+		<bitfield name="PA_PA_SCLK_PM_OVERRIDE" pos="1" type="boolean"/>
+		<bitfield name="PA_AG_SCLK_PM_OVERRIDE" pos="2" type="boolean"/>
+		<bitfield name="VGT_REG_SCLK_PM_OVERRIDE" pos="3" type="boolean"/>
+		<bitfield name="VGT_FIFOS_SCLK_PM_OVERRIDE" pos="4" type="boolean"/>
+		<bitfield name="VGT_VGT_SCLK_PM_OVERRIDE" pos="5" type="boolean"/>
+		<bitfield name="DEBUG_PERF_SCLK_PM_OVERRIDE" pos="6" type="boolean"/>
+		<bitfield name="PERM_SCLK_PM_OVERRIDE" pos="7" type="boolean"/>
+		<bitfield name="GC_GA_GMEM0_PM_OVERRIDE" pos="8" type="boolean"/>
+		<bitfield name="GC_GA_GMEM1_PM_OVERRIDE" pos="9" type="boolean"/>
+		<bitfield name="GC_GA_GMEM2_PM_OVERRIDE" pos="10" type="boolean"/>
+		<bitfield name="GC_GA_GMEM3_PM_OVERRIDE" pos="11" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x03a0" name="RBBM_DEBUG_OUT"/>
+	<reg32 offset="0x03a1" name="RBBM_DEBUG_CNTL"/>
+	<reg32 offset="0x03b3" name="RBBM_READ_ERROR"/>
+	<reg32 offset="0x03b4" name="RBBM_INT_CNTL">
+		<bitfield name="RDERR_INT_MASK" pos="0" type="boolean"/>
+		<bitfield name="DISPLAY_UPDATE_INT_MASK" pos="1" type="boolean"/>
+		<bitfield name="GUI_IDLE_INT_MASK" pos="19" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x03b5" name="RBBM_INT_STATUS"/>
+	<reg32 offset="0x03b6" name="RBBM_INT_ACK"/>
+	<reg32 offset="0x03b7" name="MASTER_INT_SIGNAL">
+		<bitfield name="MH_INT_STAT" pos="5" type="boolean"/>
+		<bitfield name="SQ_INT_STAT" pos="26" type="boolean"/>
+		<bitfield name="CP_INT_STAT" pos="30" type="boolean"/>
+		<bitfield name="RBBM_INT_STAT" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x03f9" name="RBBM_PERIPHID1"/>
+	<reg32 offset="0x03fa" name="RBBM_PERIPHID2"/>
+	<reg32 offset="0x0444" name="CP_PERFMON_CNTL">
+		<!-- The width is uncertain -->
+		<bitfield name="PERF_MODE_CNT" low="0" high="2" type="perf_mode_cnt"/>
+	</reg32>
+	<reg32 offset="0x0445" name="CP_PERFCOUNTER_SELECT"/>
+	<reg32 offset="0x0446" name="CP_PERFCOUNTER_LO"/>
+	<reg32 offset="0x0447" name="CP_PERFCOUNTER_HI"/>
+	<reg32 offset="0x05d0" name="RBBM_STATUS">
+		<bitfield name="CMDFIFO_AVAIL" low="0" high="4" type="uint"/>
+		<bitfield name="TC_BUSY" pos="5" type="boolean"/>
+		<bitfield name="HIRQ_PENDING" pos="8" type="boolean"/>
+		<bitfield name="CPRQ_PENDING" pos="9" type="boolean"/>
+		<bitfield name="CFRQ_PENDING" pos="10" type="boolean"/>
+		<bitfield name="PFRQ_PENDING" pos="11" type="boolean"/>
+		<bitfield name="VGT_BUSY_NO_DMA" pos="12" type="boolean"/>
+		<bitfield name="RBBM_WU_BUSY" pos="14" type="boolean"/>
+		<bitfield name="CP_NRT_BUSY" pos="16" type="boolean"/>
+		<bitfield name="MH_BUSY" pos="18" type="boolean"/>
+		<bitfield name="MH_COHERENCY_BUSY" pos="19" type="boolean"/>
+		<bitfield name="SX_BUSY" pos="21" type="boolean"/>
+		<bitfield name="TPC_BUSY" pos="22" type="boolean"/>
+		<bitfield name="SC_CNTX_BUSY" pos="24" type="boolean"/>
+		<bitfield name="PA_BUSY" pos="25" type="boolean"/>
+		<bitfield name="VGT_BUSY" pos="26" type="boolean"/>
+		<bitfield name="SQ_CNTX17_BUSY" pos="27" type="boolean"/>
+		<bitfield name="SQ_CNTX0_BUSY" pos="28" type="boolean"/>
+		<bitfield name="RB_CNTX_BUSY" pos="30" type="boolean"/>
+		<bitfield name="GUI_ACTIVE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0a40" name="MH_ARBITER_CONFIG">
+		<bitfield name="SAME_PAGE_LIMIT" low="0" high="5" type="uint"/>
+		<bitfield name="SAME_PAGE_GRANULARITY" pos="6" type="boolean"/>
+		<bitfield name="L1_ARB_ENABLE" pos="7" type="boolean"/>
+		<bitfield name="L1_ARB_HOLD_ENABLE" pos="8" type="boolean"/>
+		<bitfield name="L2_ARB_CONTROL" pos="9" type="boolean"/>
+		<bitfield name="PAGE_SIZE" low="10" high="12" type="uint"/>
+		<bitfield name="TC_REORDER_ENABLE" pos="13" type="boolean"/>
+		<bitfield name="TC_ARB_HOLD_ENABLE" pos="14" type="boolean"/>
+		<bitfield name="IN_FLIGHT_LIMIT_ENABLE" pos="15" type="boolean"/>
+		<bitfield name="IN_FLIGHT_LIMIT" low="16" high="21" type="uint"/>
+		<bitfield name="CP_CLNT_ENABLE" pos="22" type="boolean"/>
+		<bitfield name="VGT_CLNT_ENABLE" pos="23" type="boolean"/>
+		<bitfield name="TC_CLNT_ENABLE" pos="24" type="boolean"/>
+		<bitfield name="RB_CLNT_ENABLE" pos="25" type="boolean"/>
+		<bitfield name="PA_CLNT_ENABLE" pos="26" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0a42" name="MH_INTERRUPT_MASK">
+		<bitfield name="AXI_READ_ERROR" pos="0" type="boolean"/>
+		<bitfield name="AXI_WRITE_ERROR" pos="1" type="boolean"/>
+		<bitfield name="MMU_PAGE_FAULT" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0a43" name="MH_INTERRUPT_STATUS"/>
+	<reg32 offset="0x0a44" name="MH_INTERRUPT_CLEAR"/>
+	<reg32 offset="0x0a54" name="MH_CLNT_INTF_CTRL_CONFIG1"/>
+	<reg32 offset="0x0a55" name="MH_CLNT_INTF_CTRL_CONFIG2"/>
+	<reg32 offset="0x0c01" name="A220_VSC_BIN_SIZE">
+		<bitfield name="WIDTH" low="0" high="4" shr="5" type="uint"/>
+		<bitfield name="HEIGHT" low="5" high="9" shr="5" type="uint"/>
+	</reg32>
+	<array offset="0x0c06" name="VSC_PIPE" stride="3" length="8">
+		<reg32 offset="0x0" name="CONFIG"/>
+		<reg32 offset="0x1" name="DATA_ADDRESS"/>
+		<reg32 offset="0x2" name="DATA_LENGTH"/>
+	</array>
+	<reg32 offset="0x0c38" name="PC_DEBUG_CNTL"/>
+	<reg32 offset="0x0c39" name="PC_DEBUG_DATA"/>
+	<reg32 offset="0x0c44" name="PA_SC_VIZ_QUERY_STATUS"/>
+	<reg32 offset="0x0c80" name="GRAS_DEBUG_CNTL"/>
+	<reg32 offset="0x0c80" name="PA_SU_DEBUG_CNTL"/>
+	<reg32 offset="0x0c81" name="GRAS_DEBUG_DATA"/>
+	<reg32 offset="0x0c81" name="PA_SU_DEBUG_DATA"/>
+	<reg32 offset="0x0c86" name="PA_SU_FACE_DATA">
+		<bitfield name="BASE_ADDR" low="5" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0d00" name="SQ_GPR_MANAGEMENT">
+		<bitfield name="REG_DYNAMIC" pos="0" type="boolean"/>
+		<bitfield name="REG_SIZE_PIX" low="4" high="11" type="uint"/>
+		<bitfield name="REG_SIZE_VTX" low="12" high="19" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0d01" name="SQ_FLOW_CONTROL"/>
+	<reg32 offset="0x0d02" name="SQ_INST_STORE_MANAGMENT">
+		<bitfield name="INST_BASE_PIX" low="0" high="11" type="uint"/>
+		<bitfield name="INST_BASE_VTX" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0d05" name="SQ_DEBUG_MISC"/>
+	<reg32 offset="0x0d34" name="SQ_INT_CNTL"/>
+	<reg32 offset="0x0d35" name="SQ_INT_STATUS"/>
+	<reg32 offset="0x0d36" name="SQ_INT_ACK"/>
+	<reg32 offset="0x0dae" name="SQ_DEBUG_INPUT_FSM"/>
+	<reg32 offset="0x0daf" name="SQ_DEBUG_CONST_MGR_FSM"/>
+	<reg32 offset="0x0db0" name="SQ_DEBUG_TP_FSM"/>
+	<reg32 offset="0x0db1" name="SQ_DEBUG_FSM_ALU_0"/>
+	<reg32 offset="0x0db2" name="SQ_DEBUG_FSM_ALU_1"/>
+	<reg32 offset="0x0db3" name="SQ_DEBUG_EXP_ALLOC"/>
+	<reg32 offset="0x0db4" name="SQ_DEBUG_PTR_BUFF"/>
+	<reg32 offset="0x0db5" name="SQ_DEBUG_GPR_VTX"/>
+	<reg32 offset="0x0db6" name="SQ_DEBUG_GPR_PIX"/>
+	<reg32 offset="0x0db7" name="SQ_DEBUG_TB_STATUS_SEL"/>
+	<reg32 offset="0x0db8" name="SQ_DEBUG_VTX_TB_0"/>
+	<reg32 offset="0x0db9" name="SQ_DEBUG_VTX_TB_1"/>
+	<reg32 offset="0x0dba" name="SQ_DEBUG_VTX_TB_STATUS_REG"/>
+	<reg32 offset="0x0dbb" name="SQ_DEBUG_VTX_TB_STATE_MEM"/>
+	<reg32 offset="0x0dbc" name="SQ_DEBUG_PIX_TB_0"/>
+	<reg32 offset="0x0dbd" name="SQ_DEBUG_PIX_TB_STATUS_REG_0"/>
+	<reg32 offset="0x0dbe" name="SQ_DEBUG_PIX_TB_STATUS_REG_1"/>
+	<reg32 offset="0x0dbf" name="SQ_DEBUG_PIX_TB_STATUS_REG_2"/>
+	<reg32 offset="0x0dc0" name="SQ_DEBUG_PIX_TB_STATUS_REG_3"/>
+	<reg32 offset="0x0dc1" name="SQ_DEBUG_PIX_TB_STATE_MEM"/>
+	<reg32 offset="0x0e00" name="TC_CNTL_STATUS">
+		<bitfield name="L2_INVALIDATE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0e1e" name="TP0_CHICKEN"/>
+	<reg32 offset="0x0f01" name="RB_BC_CONTROL">
+		<bitfield name="ACCUM_LINEAR_MODE_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="ACCUM_TIMEOUT_SELECT" low="1" high="2" type="uint"/>
+		<bitfield name="DISABLE_EDRAM_CAM" pos="3" type="boolean"/>
+		<bitfield name="DISABLE_EZ_FAST_CONTEXT_SWITCH" pos="4" type="boolean"/>
+		<bitfield name="DISABLE_EZ_NULL_ZCMD_DROP" pos="5" type="boolean"/>
+		<bitfield name="DISABLE_LZ_NULL_ZCMD_DROP" pos="6" type="boolean"/>
+		<bitfield name="ENABLE_AZ_THROTTLE" pos="7" type="boolean"/>
+		<bitfield name="AZ_THROTTLE_COUNT" low="8" high="12" type="uint"/>
+		<bitfield name="ENABLE_CRC_UPDATE" pos="14" type="boolean"/>
+		<bitfield name="CRC_MODE" pos="15" type="boolean"/>
+		<bitfield name="DISABLE_SAMPLE_COUNTERS" pos="16" type="boolean"/>
+		<bitfield name="DISABLE_ACCUM" pos="17" type="boolean"/>
+		<bitfield name="ACCUM_ALLOC_MASK" low="18" high="21" type="uint"/>
+		<bitfield name="LINEAR_PERFORMANCE_ENABLE" pos="22" type="boolean"/>
+		<bitfield name="ACCUM_DATA_FIFO_LIMIT" low="23" high="26" type="uint"/>
+		<bitfield name="MEM_EXPORT_TIMEOUT_SELECT" low="27" high="28" type="uint"/>
+		<bitfield name="MEM_EXPORT_LINEAR_MODE_ENABLE" pos="29" type="boolean"/>
+		<bitfield name="CRC_SYSTEM" pos="30" type="boolean"/>
+		<bitfield name="RESERVED6" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0f02" name="RB_EDRAM_INFO"/>
+	<reg32 offset="0x0f26" name="RB_DEBUG_CNTL"/>
+	<reg32 offset="0x0f27" name="RB_DEBUG_DATA"/>
+	<reg32 offset="0x2000" name="RB_SURFACE_INFO">
+		<bitfield name="SURFACE_PITCH" low="0" high="13" type="uint"/>
+		<bitfield name="MSAA_SAMPLES" low="14" high="15" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2001" name="RB_COLOR_INFO">
+		<bitfield name="FORMAT" low="0" high="3" type="a2xx_colorformatx"/>
+		<bitfield name="ROUND_MODE" low="4" high="5" type="uint"/>
+		<bitfield name="LINEAR" pos="6" type="boolean"/>
+		<bitfield name="ENDIAN" low="7" high="8" type="uint"/>
+		<bitfield name="SWAP" low="9" high="10" type="uint"/>
+		<bitfield name="BASE" low="12" high="31" shr="12"/>
+	</reg32>
+	<reg32 offset="0x2002" name="RB_DEPTH_INFO">
+		<bitfield name="DEPTH_FORMAT" pos="0" type="adreno_rb_depth_format"/>
+		<bitfield name="DEPTH_BASE" low="12" high="31" type="uint" shr="12"/>
+	</reg32>
+	<reg32 offset="0x2005" name="A225_RB_COLOR_INFO3"/>
+	<reg32 offset="0x2006" name="COHER_DEST_BASE_0"/>
+	<reg32 offset="0x200e" name="PA_SC_SCREEN_SCISSOR_TL" type="adreno_reg_xy"/>
+	<reg32 offset="0x200f" name="PA_SC_SCREEN_SCISSOR_BR" type="adreno_reg_xy"/>
+	<reg32 offset="0x2080" name="PA_SC_WINDOW_OFFSET">
+		<bitfield name="X" low="0" high="14" type="int"/>
+		<bitfield name="Y" low="16" high="30" type="int"/>
+		<bitfield name="DISABLE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2081" name="PA_SC_WINDOW_SCISSOR_TL" type="adreno_reg_xy"/>
+	<reg32 offset="0x2082" name="PA_SC_WINDOW_SCISSOR_BR" type="adreno_reg_xy"/>
+	<reg32 offset="0x2010" name="UNKNOWN_2010"/>
+	<reg32 offset="0x2100" name="VGT_MAX_VTX_INDX"/>
+	<reg32 offset="0x2101" name="VGT_MIN_VTX_INDX"/>
+	<reg32 offset="0x2102" name="VGT_INDX_OFFSET"/>
+	<reg32 offset="0x2103" name="A225_PC_MULTI_PRIM_IB_RESET_INDX"/>
+	<reg32 offset="0x2104" name="RB_COLOR_MASK">
+		<bitfield name="WRITE_RED" pos="0" type="boolean"/>
+		<bitfield name="WRITE_GREEN" pos="1" type="boolean"/>
+		<bitfield name="WRITE_BLUE" pos="2" type="boolean"/>
+		<bitfield name="WRITE_ALPHA" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2105" name="RB_BLEND_RED"/>
+	<reg32 offset="0x2106" name="RB_BLEND_GREEN"/>
+	<reg32 offset="0x2107" name="RB_BLEND_BLUE"/>
+	<reg32 offset="0x2108" name="RB_BLEND_ALPHA"/>
+	<reg32 offset="0x2109" name="RB_FOG_COLOR">
+		<bitfield name="FOG_RED" low="0" high="7" type="uint"/>
+		<bitfield name="FOG_GREEN" low="8" high="15" type="uint"/>
+		<bitfield name="FOG_BLUE" low="16" high="23" type="uint"/>
+	</reg32>
+	<reg32 offset="0x210c" name="RB_STENCILREFMASK_BF" type="adreno_rb_stencilrefmask"/>
+	<reg32 offset="0x210d" name="RB_STENCILREFMASK" type="adreno_rb_stencilrefmask"/>
+	<reg32 offset="0x210e" name="RB_ALPHA_REF"/>
+	<reg32 offset="0x210f" name="PA_CL_VPORT_XSCALE" type="float"/>
+	<reg32 offset="0x2110" name="PA_CL_VPORT_XOFFSET" type="float"/>
+	<reg32 offset="0x2111" name="PA_CL_VPORT_YSCALE" type="float"/>
+	<reg32 offset="0x2112" name="PA_CL_VPORT_YOFFSET" type="float"/>
+	<reg32 offset="0x2113" name="PA_CL_VPORT_ZSCALE" type="float"/>
+	<reg32 offset="0x2114" name="PA_CL_VPORT_ZOFFSET" type="float"/>
+	<reg32 offset="0x2180" name="SQ_PROGRAM_CNTL">
+		<doc>
+			note: only 0x3f worth of valid register values for VS_REGS and
+			PS_REGS, but high bit is set to indicate '0 registers used':
+		</doc>
+		<bitfield name="VS_REGS" low="0" high="7" type="uint"/>
+		<bitfield name="PS_REGS" low="8" high="15" type="uint"/>
+		<bitfield name="VS_RESOURCE" pos="16" type="boolean"/>
+		<bitfield name="PS_RESOURCE" pos="17" type="boolean"/>
+		<bitfield name="PARAM_GEN" pos="18" type="boolean"/>
+		<bitfield name="GEN_INDEX_PIX" pos="19" type="boolean"/>
+		<bitfield name="VS_EXPORT_COUNT" low="20" high="23" type="uint"/>
+		<bitfield name="VS_EXPORT_MODE" low="24" high="26" type="a2xx_sq_ps_vtx_mode"/>
+		<bitfield name="PS_EXPORT_MODE" low="27" high="30" type="uint"/>
+		<bitfield name="GEN_INDEX_VTX" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2181" name="SQ_CONTEXT_MISC">
+		<bitfield name="INST_PRED_OPTIMIZE" pos="0" type="boolean"/>
+		<bitfield name="SC_OUTPUT_SCREEN_XY" pos="1" type="boolean"/>
+		<bitfield name="SC_SAMPLE_CNTL" low="2" high="3" type="a2xx_sq_sample_cntl"/>
+		<bitfield name="PARAM_GEN_POS" low="8" high="15" type="uint"/>
+		<bitfield name="PERFCOUNTER_REF" pos="16" type="boolean"/>
+		<bitfield name="YEILD_OPTIMIZE" pos="17" type="boolean"/>
+		<bitfield name="TX_CACHE_SEL" pos="18" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2182" name="SQ_INTERPOLATOR_CNTL">
+		<bitfield name="PARAM_SHADE" low="0" high="15" type="uint"/>
+		<bitfield name="SAMPLING_PATTERN" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2183" name="SQ_WRAPPING_0">
+		<bitfield name="PARAM_WRAP_0" low="0" high="3" type="uint"/>
+		<bitfield name="PARAM_WRAP_1" low="4" high="7" type="uint"/>
+		<bitfield name="PARAM_WRAP_2" low="8" high="11" type="uint"/>
+		<bitfield name="PARAM_WRAP_3" low="12" high="15" type="uint"/>
+		<bitfield name="PARAM_WRAP_4" low="16" high="19" type="uint"/>
+		<bitfield name="PARAM_WRAP_5" low="20" high="23" type="uint"/>
+		<bitfield name="PARAM_WRAP_6" low="24" high="27" type="uint"/>
+		<bitfield name="PARAM_WRAP_7" low="28" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2184" name="SQ_WRAPPING_1">
+		<bitfield name="PARAM_WRAP_8" low="0" high="3" type="uint"/>
+		<bitfield name="PARAM_WRAP_9" low="4" high="7" type="uint"/>
+		<bitfield name="PARAM_WRAP_10" low="8" high="11" type="uint"/>
+		<bitfield name="PARAM_WRAP_11" low="12" high="15" type="uint"/>
+		<bitfield name="PARAM_WRAP_12" low="16" high="19" type="uint"/>
+		<bitfield name="PARAM_WRAP_13" low="20" high="23" type="uint"/>
+		<bitfield name="PARAM_WRAP_14" low="24" high="27" type="uint"/>
+		<bitfield name="PARAM_WRAP_15" low="28" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x21f6" name="SQ_PS_PROGRAM">
+		<bitfield name="BASE" low="0" high="11" type="uint"/>
+		<bitfield name="SIZE" low="12" high="23" type="uint"/>
+	</reg32>
+	<reg32 offset="0x21f7" name="SQ_VS_PROGRAM">
+		<bitfield name="BASE" low="0" high="11" type="uint"/>
+		<bitfield name="SIZE" low="12" high="23" type="uint"/>
+	</reg32>
+	<reg32 offset="0x21f9" name="VGT_EVENT_INITIATOR"/>
+	<reg32 offset="0x21fc" name="VGT_DRAW_INITIATOR" type="vgt_draw_initiator"/>
+	<reg32 offset="0x21fd" name="VGT_IMMED_DATA"/>
+	<reg32 offset="0x2200" name="RB_DEPTHCONTROL">
+		<bitfield name="STENCIL_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="Z_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="Z_WRITE_ENABLE" pos="2" type="boolean"/>
+		<bitfield name="EARLY_Z_ENABLE" pos="3" type="boolean"/>
+		<bitfield name="ZFUNC" low="4" high="6" type="adreno_compare_func"/>
+		<bitfield name="BACKFACE_ENABLE" pos="7" type="boolean"/>
+		<bitfield name="STENCILFUNC" low="8" high="10" type="adreno_compare_func"/>
+		<bitfield name="STENCILFAIL" low="11" high="13" type="adreno_stencil_op"/>
+		<bitfield name="STENCILZPASS" low="14" high="16" type="adreno_stencil_op"/>
+		<bitfield name="STENCILZFAIL" low="17" high="19" type="adreno_stencil_op"/>
+		<bitfield name="STENCILFUNC_BF" low="20" high="22" type="adreno_compare_func"/>
+		<bitfield name="STENCILFAIL_BF" low="23" high="25" type="adreno_stencil_op"/>
+		<bitfield name="STENCILZPASS_BF" low="26" high="28" type="adreno_stencil_op"/>
+		<bitfield name="STENCILZFAIL_BF" low="29" high="31" type="adreno_stencil_op"/>
+	</reg32>
+	<reg32 offset="0x2201" name="RB_BLEND_CONTROL">
+		<bitfield name="COLOR_SRCBLEND" low="0" high="4" type="adreno_rb_blend_factor"/>
+		<bitfield name="COLOR_COMB_FCN" low="5" high="7" type="a2xx_rb_blend_opcode"/>
+		<bitfield name="COLOR_DESTBLEND" low="8" high="12" type="adreno_rb_blend_factor"/>
+		<bitfield name="ALPHA_SRCBLEND" low="16" high="20" type="adreno_rb_blend_factor"/>
+		<bitfield name="ALPHA_COMB_FCN" low="21" high="23" type="a2xx_rb_blend_opcode"/>
+		<bitfield name="ALPHA_DESTBLEND" low="24" high="28" type="adreno_rb_blend_factor"/>
+		<bitfield name="BLEND_FORCE_ENABLE" pos="29" type="boolean"/>
+		<bitfield name="BLEND_FORCE" pos="30" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2202" name="RB_COLORCONTROL">
+		<bitfield name="ALPHA_FUNC" low="0" high="2" type="adreno_compare_func"/>
+		<bitfield name="ALPHA_TEST_ENABLE" pos="3" type="boolean"/>
+		<bitfield name="ALPHA_TO_MASK_ENABLE" pos="4" type="boolean"/>
+		<bitfield name="BLEND_DISABLE" pos="5" type="boolean"/>
+		<bitfield name="VOB_ENABLE" pos="6" type="boolean"/>
+		<bitfield name="VS_EXPORTS_FOG" pos="7" type="boolean"/>
+		<bitfield name="ROP_CODE" low="8" high="11" type="uint"/>
+		<bitfield name="DITHER_MODE" low="12" high="13" type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_TYPE" low="14" high="15" type="a2xx_rb_dither_type"/>
+		<bitfield name="PIXEL_FOG" pos="16" type="boolean"/>
+		<bitfield name="ALPHA_TO_MASK_OFFSET0" low="24" high="25" type="uint"/>
+		<bitfield name="ALPHA_TO_MASK_OFFSET1" low="26" high="27" type="uint"/>
+		<bitfield name="ALPHA_TO_MASK_OFFSET2" low="28" high="29" type="uint"/>
+		<bitfield name="ALPHA_TO_MASK_OFFSET3" low="30" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2203" name="VGT_CURRENT_BIN_ID_MAX" type="a2xx_vgt_current_bin_id_min_max"/>
+	<reg32 offset="0x2204" name="PA_CL_CLIP_CNTL">
+		<bitfield name="CLIP_DISABLE" pos="16" type="boolean"/>
+		<bitfield name="BOUNDARY_EDGE_FLAG_ENA" pos="18" type="boolean"/>
+		<bitfield name="DX_CLIP_SPACE_DEF" pos="19" type="a2xx_dx_clip_space"/>
+		<bitfield name="DIS_CLIP_ERR_DETECT" pos="20" type="boolean"/>
+		<bitfield name="VTX_KILL_OR" pos="21" type="boolean"/>
+		<bitfield name="XY_NAN_RETAIN" pos="22" type="boolean"/>
+		<bitfield name="Z_NAN_RETAIN" pos="23" type="boolean"/>
+		<bitfield name="W_NAN_RETAIN" pos="24" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2205" name="PA_SU_SC_MODE_CNTL">
+		<bitfield name="CULL_FRONT" pos="0" type="boolean"/>
+		<bitfield name="CULL_BACK" pos="1" type="boolean"/>
+		<bitfield name="FACE" pos="2" type="boolean"/>
+		<bitfield name="POLYMODE" low="3" high="4" type="a2xx_pa_su_sc_polymode"/>
+		<bitfield name="FRONT_PTYPE" low="5" high="7" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="BACK_PTYPE" low="8" high="10" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="POLY_OFFSET_FRONT_ENABLE" pos="11" type="boolean"/>
+		<bitfield name="POLY_OFFSET_BACK_ENABLE" pos="12" type="boolean"/>
+		<bitfield name="POLY_OFFSET_PARA_ENABLE" pos="13" type="boolean"/>
+		<bitfield name="MSAA_ENABLE" pos="15" type="boolean"/>
+		<bitfield name="VTX_WINDOW_OFFSET_ENABLE" pos="16" type="boolean"/>
+		<bitfield name="LINE_STIPPLE_ENABLE" pos="18" type="boolean"/>
+		<bitfield name="PROVOKING_VTX_LAST" pos="19" type="boolean"/>
+		<bitfield name="PERSP_CORR_DIS" pos="20" type="boolean"/>
+		<bitfield name="MULTI_PRIM_IB_ENA" pos="21" type="boolean"/>
+		<bitfield name="QUAD_ORDER_ENABLE" pos="23" type="boolean"/>
+		<bitfield name="WAIT_RB_IDLE_ALL_TRI" pos="25" type="boolean"/>
+		<bitfield name="WAIT_RB_IDLE_FIRST_TRI_NEW_STATE" pos="26" type="boolean"/>
+		<bitfield name="CLAMPED_FACENESS" pos="28" type="boolean"/>
+		<bitfield name="ZERO_AREA_FACENESS" pos="29" type="boolean"/>
+		<bitfield name="FACE_KILL_ENABLE" pos="30" type="boolean"/>
+		<bitfield name="FACE_WRITE_ENABLE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2206" name="PA_CL_VTE_CNTL">
+		<bitfield name="VPORT_X_SCALE_ENA" pos="0" type="boolean"/>
+		<bitfield name="VPORT_X_OFFSET_ENA" pos="1" type="boolean"/>
+		<bitfield name="VPORT_Y_SCALE_ENA" pos="2" type="boolean"/>
+		<bitfield name="VPORT_Y_OFFSET_ENA" pos="3" type="boolean"/>
+		<bitfield name="VPORT_Z_SCALE_ENA" pos="4" type="boolean"/>
+		<bitfield name="VPORT_Z_OFFSET_ENA" pos="5" type="boolean"/>
+		<bitfield name="VTX_XY_FMT" pos="8" type="boolean"/>
+		<bitfield name="VTX_Z_FMT" pos="9" type="boolean"/>
+		<bitfield name="VTX_W0_FMT" pos="10" type="boolean"/>
+		<bitfield name="PERFCOUNTER_REF" pos="11" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2207" name="VGT_CURRENT_BIN_ID_MIN" type="a2xx_vgt_current_bin_id_min_max"/>
+	<reg32 offset="0x2208" name="RB_MODECONTROL">
+		<bitfield name="EDRAM_MODE" low="0" high="2" type="a2xx_rb_edram_mode"/>
+	</reg32>
+	<reg32 offset="0x2209" name="A220_RB_LRZ_VSC_CONTROL"/>
+	<reg32 offset="0x220a" name="RB_SAMPLE_POS"/>
+	<reg32 offset="0x220b" name="CLEAR_COLOR">
+		<bitfield name="RED" low="0" high="7"/>
+		<bitfield name="GREEN" low="8" high="15"/>
+		<bitfield name="BLUE" low="16" high="23"/>
+		<bitfield name="ALPHA" low="24" high="31"/>
+	</reg32>
+	<reg32 offset="0x2210" name="A220_GRAS_CONTROL"/>
+	<reg32 offset="0x2280" name="PA_SU_POINT_SIZE">
+		<bitfield name="HEIGHT" low="0" high="15" type="ufixed" radix="4"/>
+		<bitfield name="WIDTH" low="16" high="31" type="ufixed" radix="4"/>
+	</reg32>
+	<reg32 offset="0x2281" name="PA_SU_POINT_MINMAX">
+		<bitfield name="MIN" low="0" high="15" type="ufixed" radix="4"/>
+		<bitfield name="MAX" low="16" high="31" type="ufixed" radix="4"/>
+	</reg32>
+	<reg32 offset="0x2282" name="PA_SU_LINE_CNTL">
+		<bitfield name="WIDTH" low="0" high="15" type="ufixed" radix="4"/>
+	</reg32>
+	<reg32 offset="0x2283" name="PA_SC_LINE_STIPPLE">
+		<bitfield name="LINE_PATTERN" low="0" high="15" type="hex"/>
+		<bitfield name="REPEAT_COUNT" low="16" high="23" type="uint"/>
+		<bitfield name="PATTERN_BIT_ORDER" pos="28" type="a2xx_pa_sc_pattern_bit_order"/>
+		<bitfield name="AUTO_RESET_CNTL" low="29" high="30" type="a2xx_pa_sc_auto_reset_cntl"/>
+	</reg32>
+	<reg32 offset="0x2293" name="PA_SC_VIZ_QUERY">
+		<bitfield name="VIZ_QUERY_ENA" pos="0" type="boolean"/>
+		<bitfield name="VIZ_QUERY_ID" low="1" high="6" type="uint"/>
+		<bitfield name="KILL_PIX_POST_EARLY_Z" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2294" name="VGT_ENHANCE"/>
+	<reg32 offset="0x2300" name="PA_SC_LINE_CNTL">
+		<bitfield name="BRES_CNTL" low="0" high="15" type="uint"/>
+		<bitfield name="USE_BRES_CNTL" pos="8" type="boolean"/>
+		<bitfield name="EXPAND_LINE_WIDTH" pos="9" type="boolean"/>
+		<bitfield name="LAST_PIXEL" pos="10" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2301" name="PA_SC_AA_CONFIG">
+		<bitfield name="MSAA_NUM_SAMPLES" low="0" high="2" type="uint"/>
+		<bitfield name="MAX_SAMPLE_DIST" low="13" high="16" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2302" name="PA_SU_VTX_CNTL">
+		<bitfield name="PIX_CENTER" pos="0" type="a2xx_pa_pixcenter"/>
+		<bitfield name="ROUND_MODE" low="1" high="2" type="a2xx_pa_roundmode"/>
+		<bitfield name="QUANT_MODE" low="7" high="9" type="a2xx_pa_quantmode"/>
+	</reg32>
+	<reg32 offset="0x2303" name="PA_CL_GB_VERT_CLIP_ADJ" type="float"/>
+	<reg32 offset="0x2304" name="PA_CL_GB_VERT_DISC_ADJ" type="float"/>
+	<reg32 offset="0x2305" name="PA_CL_GB_HORZ_CLIP_ADJ" type="float"/>
+	<reg32 offset="0x2306" name="PA_CL_GB_HORZ_DISC_ADJ" type="float"/>
+	<reg32 offset="0x2307" name="SQ_VS_CONST">
+		<bitfield name="BASE" low="0" high="8" type="uint"/>
+		<bitfield name="SIZE" low="12" high="20" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2308" name="SQ_PS_CONST">
+		<bitfield name="BASE" low="0" high="8" type="uint"/>
+		<bitfield name="SIZE" low="12" high="20" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2309" name="SQ_DEBUG_MISC_0"/>
+	<reg32 offset="0x230a" name="SQ_DEBUG_MISC_1"/>
+	<reg32 offset="0x2312" name="PA_SC_AA_MASK"/>
+	<reg32 offset="0x2316" name="VGT_VERTEX_REUSE_BLOCK_CNTL">
+		<bitfield name="VTX_REUSE_DEPTH" low="0" high="2" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2317" name="VGT_OUT_DEALLOC_CNTL">
+		<bitfield name="DEALLOC_DIST" low="0" high="1" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2318" name="RB_COPY_CONTROL">
+		<bitfield name="COPY_SAMPLE_SELECT" low="0" high="2" type="a2xx_rb_copy_sample_select"/>
+		<bitfield name="DEPTH_CLEAR_ENABLE" pos="3" type="boolean"/>
+		<bitfield name="CLEAR_MASK" low="4" high="7" type="hex"/>
+	</reg32>
+	<reg32 offset="0x2319" name="RB_COPY_DEST_BASE"/>
+	<reg32 offset="0x231a" name="RB_COPY_DEST_PITCH" shr="5" type="uint"/>
+	<reg32 offset="0x231b" name="RB_COPY_DEST_INFO">
+		<bitfield name="DEST_ENDIAN" low="0" high="2" type="adreno_rb_surface_endian"/>
+		<bitfield name="LINEAR" pos="3" type="boolean"/>
+		<bitfield name="FORMAT" low="4" high="7" type="a2xx_colorformatx"/>
+		<bitfield name="SWAP" low="8" high="9" type="uint"/>
+		<bitfield name="DITHER_MODE" low="10" high="11" type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_TYPE" low="12" high="13" type="a2xx_rb_dither_type"/>
+		<bitfield name="WRITE_RED" pos="14" type="boolean"/>
+		<bitfield name="WRITE_GREEN" pos="15" type="boolean"/>
+		<bitfield name="WRITE_BLUE" pos="16" type="boolean"/>
+		<bitfield name="WRITE_ALPHA" pos="17" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x231c" name="RB_COPY_DEST_OFFSET">
+		<bitfield name="X" low="0" high="12" type="uint"/>
+		<bitfield name="Y" low="13" high="25" type="uint"/>
+	</reg32>
+	<reg32 offset="0x231d" name="RB_DEPTH_CLEAR"/>
+	<reg32 offset="0x2324" name="RB_SAMPLE_COUNT_CTL"/>
+	<reg32 offset="0x2326" name="RB_COLOR_DEST_MASK"/>
+	<reg32 offset="0x2340" name="A225_GRAS_UCP0X"/>
+	<reg32 offset="0x2357" name="A225_GRAS_UCP5W"/>
+	<reg32 offset="0x2360" name="A225_GRAS_UCP_ENABLED"/>
+	<reg32 offset="0x2380" name="PA_SU_POLY_OFFSET_FRONT_SCALE"/>
+	<reg32 offset="0x2381" name="PA_SU_POLY_OFFSET_FRONT_OFFSET"/>
+	<reg32 offset="0x2382" name="PA_SU_POLY_OFFSET_BACK_SCALE"/>
+	<reg32 offset="0x2383" name="PA_SU_POLY_OFFSET_BACK_OFFSET"/>
+	<reg32 offset="0x4000" name="SQ_CONSTANT_0"/>
+	<reg32 offset="0x4800" name="SQ_FETCH_0"/>
+	<reg32 offset="0x4900" name="SQ_CF_BOOLEANS"/>
+	<reg32 offset="0x4908" name="SQ_CF_LOOP"/>
+	<reg32 offset="0xa29" name="COHER_SIZE_PM4"/>
+	<reg32 offset="0xa2a" name="COHER_BASE_PM4"/>
+	<reg32 offset="0xa2b" name="COHER_STATUS_PM4"/>
+
+	<reg32 offset="0x0c88" name="PA_SU_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0c89" name="PA_SU_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0c8a" name="PA_SU_PERFCOUNTER2_SELECT"/>
+	<reg32 offset="0x0c8b" name="PA_SU_PERFCOUNTER3_SELECT"/>
+	<reg32 offset="0x0c8c" name="PA_SU_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0c8d" name="PA_SU_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0c8e" name="PA_SU_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0c8f" name="PA_SU_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0c90" name="PA_SU_PERFCOUNTER2_LOW"/>
+	<reg32 offset="0x0c91" name="PA_SU_PERFCOUNTER2_HI"/>
+	<reg32 offset="0x0c92" name="PA_SU_PERFCOUNTER3_LOW"/>
+	<reg32 offset="0x0c93" name="PA_SU_PERFCOUNTER3_HI"/>
+	<reg32 offset="0x0c98" name="PA_SC_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0c99" name="PA_SC_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0c9a" name="PA_SC_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0c48" name="VGT_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0c49" name="VGT_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0c4a" name="VGT_PERFCOUNTER2_SELECT"/>
+	<reg32 offset="0x0c4b" name="VGT_PERFCOUNTER3_SELECT"/>
+	<reg32 offset="0x0c4c" name="VGT_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0c4e" name="VGT_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0c50" name="VGT_PERFCOUNTER2_LOW"/>
+	<reg32 offset="0x0c52" name="VGT_PERFCOUNTER3_LOW"/>
+	<reg32 offset="0x0c4d" name="VGT_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0c4f" name="VGT_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0c51" name="VGT_PERFCOUNTER2_HI"/>
+	<reg32 offset="0x0c53" name="VGT_PERFCOUNTER3_HI"/>
+	<reg32 offset="0x0e05" name="TCR_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0e08" name="TCR_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0e06" name="TCR_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0e09" name="TCR_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0e07" name="TCR_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0e0a" name="TCR_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0e1f" name="TP0_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0e20" name="TP0_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0e21" name="TP0_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0e22" name="TP0_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0e23" name="TP0_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0e24" name="TP0_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0e54" name="TCM_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0e57" name="TCM_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0e55" name="TCM_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0e58" name="TCM_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0e56" name="TCM_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0e59" name="TCM_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0e5a" name="TCF_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0e5d" name="TCF_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0e60" name="TCF_PERFCOUNTER2_SELECT"/>
+	<reg32 offset="0x0e63" name="TCF_PERFCOUNTER3_SELECT"/>
+	<reg32 offset="0x0e66" name="TCF_PERFCOUNTER4_SELECT"/>
+	<reg32 offset="0x0e69" name="TCF_PERFCOUNTER5_SELECT"/>
+	<reg32 offset="0x0e6c" name="TCF_PERFCOUNTER6_SELECT"/>
+	<reg32 offset="0x0e6f" name="TCF_PERFCOUNTER7_SELECT"/>
+	<reg32 offset="0x0e72" name="TCF_PERFCOUNTER8_SELECT"/>
+	<reg32 offset="0x0e75" name="TCF_PERFCOUNTER9_SELECT"/>
+	<reg32 offset="0x0e78" name="TCF_PERFCOUNTER10_SELECT"/>
+	<reg32 offset="0x0e7b" name="TCF_PERFCOUNTER11_SELECT"/>
+	<reg32 offset="0x0e5b" name="TCF_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0e5e" name="TCF_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0e61" name="TCF_PERFCOUNTER2_HI"/>
+	<reg32 offset="0x0e64" name="TCF_PERFCOUNTER3_HI"/>
+	<reg32 offset="0x0e67" name="TCF_PERFCOUNTER4_HI"/>
+	<reg32 offset="0x0e6a" name="TCF_PERFCOUNTER5_HI"/>
+	<reg32 offset="0x0e6d" name="TCF_PERFCOUNTER6_HI"/>
+	<reg32 offset="0x0e70" name="TCF_PERFCOUNTER7_HI"/>
+	<reg32 offset="0x0e73" name="TCF_PERFCOUNTER8_HI"/>
+	<reg32 offset="0x0e76" name="TCF_PERFCOUNTER9_HI"/>
+	<reg32 offset="0x0e79" name="TCF_PERFCOUNTER10_HI"/>
+	<reg32 offset="0x0e7c" name="TCF_PERFCOUNTER11_HI"/>
+	<reg32 offset="0x0e5c" name="TCF_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0e5f" name="TCF_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0e62" name="TCF_PERFCOUNTER2_LOW"/>
+	<reg32 offset="0x0e65" name="TCF_PERFCOUNTER3_LOW"/>
+	<reg32 offset="0x0e68" name="TCF_PERFCOUNTER4_LOW"/>
+	<reg32 offset="0x0e6b" name="TCF_PERFCOUNTER5_LOW"/>
+	<reg32 offset="0x0e6e" name="TCF_PERFCOUNTER6_LOW"/>
+	<reg32 offset="0x0e71" name="TCF_PERFCOUNTER7_LOW"/>
+	<reg32 offset="0x0e74" name="TCF_PERFCOUNTER8_LOW"/>
+	<reg32 offset="0x0e77" name="TCF_PERFCOUNTER9_LOW"/>
+	<reg32 offset="0x0e7a" name="TCF_PERFCOUNTER10_LOW"/>
+	<reg32 offset="0x0e7d" name="TCF_PERFCOUNTER11_LOW"/>
+	<reg32 offset="0x0dc8" name="SQ_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0dc9" name="SQ_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0dca" name="SQ_PERFCOUNTER2_SELECT"/>
+	<reg32 offset="0x0dcb" name="SQ_PERFCOUNTER3_SELECT"/>
+	<reg32 offset="0x0dcc" name="SQ_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0dcd" name="SQ_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0dce" name="SQ_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0dcf" name="SQ_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0dd0" name="SQ_PERFCOUNTER2_LOW"/>
+	<reg32 offset="0x0dd1" name="SQ_PERFCOUNTER2_HI"/>
+	<reg32 offset="0x0dd2" name="SQ_PERFCOUNTER3_LOW"/>
+	<reg32 offset="0x0dd3" name="SQ_PERFCOUNTER3_HI"/>
+	<reg32 offset="0x0dd4" name="SX_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0dd8" name="SX_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0dd9" name="SX_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0a46" name="MH_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0a4a" name="MH_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0a47" name="MH_PERFCOUNTER0_CONFIG"/>
+	<reg32 offset="0x0a4b" name="MH_PERFCOUNTER1_CONFIG"/>
+	<reg32 offset="0x0a48" name="MH_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0a4c" name="MH_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0a49" name="MH_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0a4d" name="MH_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0f04" name="RB_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0f05" name="RB_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0f06" name="RB_PERFCOUNTER2_SELECT"/>
+	<reg32 offset="0x0f07" name="RB_PERFCOUNTER3_SELECT"/>
+	<reg32 offset="0x0f08" name="RB_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0f09" name="RB_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0f0a" name="RB_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0f0b" name="RB_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0f0c" name="RB_PERFCOUNTER2_LOW"/>
+	<reg32 offset="0x0f0d" name="RB_PERFCOUNTER2_HI"/>
+	<reg32 offset="0x0f0e" name="RB_PERFCOUNTER3_LOW"/>
+	<reg32 offset="0x0f0f" name="RB_PERFCOUNTER3_HI"/>
+</domain>
+
+<domain name="A2XX_SQ_TEX" width="32">
+	<doc>Texture state dwords</doc>
+	<enum name="sq_tex_clamp">
+		<value name="SQ_TEX_WRAP" value="0"/>
+		<value name="SQ_TEX_MIRROR" value="1"/>
+		<value name="SQ_TEX_CLAMP_LAST_TEXEL" value="2"/>
+		<value name="SQ_TEX_MIRROR_ONCE_LAST_TEXEL" value="3"/>
+		<value name="SQ_TEX_CLAMP_HALF_BORDER" value="4"/>
+		<value name="SQ_TEX_MIRROR_ONCE_HALF_BORDER" value="5"/>
+		<value name="SQ_TEX_CLAMP_BORDER" value="6"/>
+		<value name="SQ_TEX_MIRROR_ONCE_BORDER" value="7"/>
+	</enum>
+	<enum name="sq_tex_swiz">
+		<value name="SQ_TEX_X" value="0"/>
+		<value name="SQ_TEX_Y" value="1"/>
+		<value name="SQ_TEX_Z" value="2"/>
+		<value name="SQ_TEX_W" value="3"/>
+		<value name="SQ_TEX_ZERO" value="4"/>
+		<value name="SQ_TEX_ONE" value="5"/>
+	</enum>
+	<enum name="sq_tex_filter">
+		<value name="SQ_TEX_FILTER_POINT" value="0"/>
+		<value name="SQ_TEX_FILTER_BILINEAR" value="1"/>
+		<value name="SQ_TEX_FILTER_BASEMAP" value="2"/>
+		<value name="SQ_TEX_FILTER_USE_FETCH_CONST" value="3"/>
+	</enum>
+	<enum name="sq_tex_aniso_filter">
+		<value name="SQ_TEX_ANISO_FILTER_DISABLED" value="0"/>
+		<value name="SQ_TEX_ANISO_FILTER_MAX_1_1" value="1"/>
+		<value name="SQ_TEX_ANISO_FILTER_MAX_2_1" value="2"/>
+		<value name="SQ_TEX_ANISO_FILTER_MAX_4_1" value="3"/>
+		<value name="SQ_TEX_ANISO_FILTER_MAX_8_1" value="4"/>
+		<value name="SQ_TEX_ANISO_FILTER_MAX_16_1" value="5"/>
+		<value name="SQ_TEX_ANISO_FILTER_USE_FETCH_CONST" value="7"/>
+	</enum>
+	<enum name="sq_tex_dimension">
+		<value name="SQ_TEX_DIMENSION_1D" value="0"/>
+		<value name="SQ_TEX_DIMENSION_2D" value="1"/>
+		<value name="SQ_TEX_DIMENSION_3D" value="2"/>
+		<value name="SQ_TEX_DIMENSION_CUBE" value="3"/>
+	</enum>
+	<enum name="sq_tex_border_color">
+		<value name="SQ_TEX_BORDER_COLOR_BLACK" value="0"/>
+		<value name="SQ_TEX_BORDER_COLOR_WHITE" value="1"/>
+		<value name="SQ_TEX_BORDER_COLOR_ACBYCR_BLACK" value="2"/>
+		<value name="SQ_TEX_BORDER_COLOR_ACBCRY_BLACK" value="3"/>
+	</enum>
+	<enum name="sq_tex_sign">
+		<value name="SQ_TEX_SIGN_UNSIGNED" value="0"/>
+		<value name="SQ_TEX_SIGN_SIGNED" value="1"/>
+		<!-- biased: 2*color-1 (range -1,1 when sampling) -->
+		<value name="SQ_TEX_SIGN_UNSIGNED_BIASED" value="2"/>
+		<!-- gamma: sRGB to linear - doesn't seem to work on adreno? -->
+		<value name="SQ_TEX_SIGN_GAMMA" value="3"/>
+	</enum>
+	<enum name="sq_tex_endian">
+		<value name="SQ_TEX_ENDIAN_NONE" value="0"/>
+		<value name="SQ_TEX_ENDIAN_8IN16" value="1"/>
+		<value name="SQ_TEX_ENDIAN_8IN32" value="2"/>
+		<value name="SQ_TEX_ENDIAN_16IN32" value="3"/>
+	</enum>
+	<enum name="sq_tex_clamp_policy">
+		<value name="SQ_TEX_CLAMP_POLICY_D3D" value="0"/>
+		<value name="SQ_TEX_CLAMP_POLICY_OGL" value="1"/>
+	</enum>
+	<enum name="sq_tex_num_format">
+		<value name="SQ_TEX_NUM_FORMAT_FRAC" value="0"/>
+		<value name="SQ_TEX_NUM_FORMAT_INT" value="1"/>
+	</enum>
+	<enum name="sq_tex_type">
+		<value name="SQ_TEX_TYPE_0" value="0"/>
+		<value name="SQ_TEX_TYPE_1" value="1"/>
+		<value name="SQ_TEX_TYPE_2" value="2"/>
+		<value name="SQ_TEX_TYPE_3" value="3"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="TYPE" low="0" high="1" type="sq_tex_type"/>
+		<bitfield name="SIGN_X" low="2" high="3" type="sq_tex_sign"/>
+		<bitfield name="SIGN_Y" low="4" high="5" type="sq_tex_sign"/>
+		<bitfield name="SIGN_Z" low="6" high="7" type="sq_tex_sign"/>
+		<bitfield name="SIGN_W" low="8" high="9" type="sq_tex_sign"/>
+		<bitfield name="CLAMP_X" low="10" high="12" type="sq_tex_clamp"/>
+		<bitfield name="CLAMP_Y" low="13" high="15" type="sq_tex_clamp"/>
+		<bitfield name="CLAMP_Z" low="16" high="18" type="sq_tex_clamp"/>
+		<bitfield name="PITCH" low="22" high="30" shr="5" type="uint"/>
+		<bitfield name="TILED" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="FORMAT" low="0" high="5" type="a2xx_sq_surfaceformat"/>
+		<bitfield name="ENDIANNESS" low="6" high="7" type="sq_tex_endian"/>
+		<bitfield name="REQUEST_SIZE" low="8" high="9" type="uint"/>
+		<bitfield name="STACKED" pos="10" type="boolean"/>
+		<bitfield name="CLAMP_POLICY" pos="11" type="sq_tex_clamp_policy"/>
+		<bitfield name="BASE_ADDRESS" low="12" high="31" type="uint" shr="12"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="WIDTH" low="0" high="12" type="uint"/>
+		<bitfield name="HEIGHT" low="13" high="25" type="uint"/>
+		<bitfield name="DEPTH" low="26" high="31" type="uint"/>
+		<!-- 1d/3d have different bit configurations -->
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="NUM_FORMAT" pos="0" type="sq_tex_num_format"/>
+		<bitfield name="SWIZ_X" low="1" high="3" type="sq_tex_swiz"/>
+		<bitfield name="SWIZ_Y" low="4" high="6" type="sq_tex_swiz"/>
+		<bitfield name="SWIZ_Z" low="7" high="9" type="sq_tex_swiz"/>
+		<bitfield name="SWIZ_W" low="10" high="12" type="sq_tex_swiz"/>
+		<bitfield name="EXP_ADJUST" low="13" high="18" type="int"/>
+		<bitfield name="XY_MAG_FILTER" low="19" high="20" type="sq_tex_filter"/>
+		<bitfield name="XY_MIN_FILTER" low="21" high="22" type="sq_tex_filter"/>
+		<bitfield name="MIP_FILTER" low="23" high="24" type="sq_tex_filter"/>
+		<bitfield name="ANISO_FILTER" low="25" high="27" type="sq_tex_aniso_filter"/>
+		<bitfield name="BORDER_SIZE" pos="31" type="uint"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="VOL_MAG_FILTER" pos="0" type="sq_tex_filter"/>
+		<bitfield name="VOL_MIN_FILTER" pos="1" type="sq_tex_filter"/>
+		<bitfield name="MIP_MIN_LEVEL" low="2" high="5" type="uint"/>
+		<bitfield name="MIP_MAX_LEVEL" low="6" high="9" type="uint"/>
+		<bitfield name="MAX_ANISO_WALK" pos="10" type="boolean"/>
+		<bitfield name="MIN_ANISO_WALK" pos="11" type="boolean"/>
+		<bitfield name="LOD_BIAS" low="12" high="21" type="fixed" radix="5"/>
+		<bitfield name="GRAD_EXP_ADJUST_H" low="22" high="26" type="uint"/>
+		<bitfield name="GRAD_EXP_ADJUST_V" low="27" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="BORDER_COLOR" low="0" high="1" type="sq_tex_border_color"/>
+		<bitfield name="FORCE_BCW_MAX" pos="2" type="boolean"/>
+		<bitfield name="TRI_CLAMP" low="3" high="4" type="uint"/>
+		<bitfield name="ANISO_BIAS" low="5" high="8" type="fixed" radix="0"/> <!-- radix unknown -->
+		<bitfield name="DIMENSION" low="9" high="10" type="sq_tex_dimension"/>
+		<bitfield name="PACKED_MIPS" pos="11" type="boolean"/>
+		<bitfield name="MIP_ADDRESS" low="12" high="31" type="uint" shr="12"/>
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/adreno/a3xx.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/adreno/a3xx.xml
@@ -0,0 +1,1751 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="adreno/adreno_common.xml"/>
+<import file="adreno/adreno_pm4.xml"/>
+
+<enum name="a3xx_tile_mode">
+	<value name="LINEAR" value="0"/>
+	<value name="TILE_4X4" value="1"/>    <!-- "normal" case for textures -->
+	<value name="TILE_32X32" value="2"/>  <!-- only used in GMEM -->
+	<value name="TILE_4X2" value="3"/>    <!-- only used for CrCb -->
+</enum>
+
+<enum name="a3xx_state_block_id">
+	<value name="HLSQ_BLOCK_ID_TP_TEX" value="2"/>
+	<value name="HLSQ_BLOCK_ID_TP_MIPMAP" value="3"/>
+	<value name="HLSQ_BLOCK_ID_SP_VS" value="4"/>
+	<value name="HLSQ_BLOCK_ID_SP_FS" value="6"/>
+</enum>
+
+<enum name="a3xx_cache_opcode">
+	<value name="INVALIDATE" value="1"/>
+</enum>
+
+<enum name="a3xx_vtx_fmt">
+	<value name="VFMT_32_FLOAT" value="0x0"/>
+	<value name="VFMT_32_32_FLOAT" value="0x1"/>
+	<value name="VFMT_32_32_32_FLOAT" value="0x2"/>
+	<value name="VFMT_32_32_32_32_FLOAT" value="0x3"/>
+
+	<value name="VFMT_16_FLOAT" value="0x4"/>
+	<value name="VFMT_16_16_FLOAT" value="0x5"/>
+	<value name="VFMT_16_16_16_FLOAT" value="0x6"/>
+	<value name="VFMT_16_16_16_16_FLOAT" value="0x7"/>
+
+	<value name="VFMT_32_FIXED" value="0x8"/>
+	<value name="VFMT_32_32_FIXED" value="0x9"/>
+	<value name="VFMT_32_32_32_FIXED" value="0xa"/>
+	<value name="VFMT_32_32_32_32_FIXED" value="0xb"/>
+
+	<value name="VFMT_16_SINT" value="0x10"/>
+	<value name="VFMT_16_16_SINT" value="0x11"/>
+	<value name="VFMT_16_16_16_SINT" value="0x12"/>
+	<value name="VFMT_16_16_16_16_SINT" value="0x13"/>
+	<value name="VFMT_16_UINT" value="0x14"/>
+	<value name="VFMT_16_16_UINT" value="0x15"/>
+	<value name="VFMT_16_16_16_UINT" value="0x16"/>
+	<value name="VFMT_16_16_16_16_UINT" value="0x17"/>
+	<value name="VFMT_16_SNORM" value="0x18"/>
+	<value name="VFMT_16_16_SNORM" value="0x19"/>
+	<value name="VFMT_16_16_16_SNORM" value="0x1a"/>
+	<value name="VFMT_16_16_16_16_SNORM" value="0x1b"/>
+	<value name="VFMT_16_UNORM" value="0x1c"/>
+	<value name="VFMT_16_16_UNORM" value="0x1d"/>
+	<value name="VFMT_16_16_16_UNORM" value="0x1e"/>
+	<value name="VFMT_16_16_16_16_UNORM" value="0x1f"/>
+
+	<!-- seems to be no NORM variants for 32bit.. -->
+	<value name="VFMT_32_UINT" value="0x20"/>
+	<value name="VFMT_32_32_UINT" value="0x21"/>
+	<value name="VFMT_32_32_32_UINT" value="0x22"/>
+	<value name="VFMT_32_32_32_32_UINT" value="0x23"/>
+	<value name="VFMT_32_SINT" value="0x24"/>
+	<value name="VFMT_32_32_SINT" value="0x25"/>
+	<value name="VFMT_32_32_32_SINT" value="0x26"/>
+	<value name="VFMT_32_32_32_32_SINT" value="0x27"/>
+
+	<value name="VFMT_8_UINT" value="0x28"/>
+	<value name="VFMT_8_8_UINT" value="0x29"/>
+	<value name="VFMT_8_8_8_UINT" value="0x2a"/>
+	<value name="VFMT_8_8_8_8_UINT" value="0x2b"/>
+	<value name="VFMT_8_UNORM" value="0x2c"/>
+	<value name="VFMT_8_8_UNORM" value="0x2d"/>
+	<value name="VFMT_8_8_8_UNORM" value="0x2e"/>
+	<value name="VFMT_8_8_8_8_UNORM" value="0x2f"/>
+	<value name="VFMT_8_SINT" value="0x30"/>
+	<value name="VFMT_8_8_SINT" value="0x31"/>
+	<value name="VFMT_8_8_8_SINT" value="0x32"/>
+	<value name="VFMT_8_8_8_8_SINT" value="0x33"/>
+	<value name="VFMT_8_SNORM" value="0x34"/>
+	<value name="VFMT_8_8_SNORM" value="0x35"/>
+	<value name="VFMT_8_8_8_SNORM" value="0x36"/>
+	<value name="VFMT_8_8_8_8_SNORM" value="0x37"/>
+	<value name="VFMT_10_10_10_2_UINT" value="0x38"/>
+	<value name="VFMT_10_10_10_2_UNORM" value="0x39"/>
+	<value name="VFMT_10_10_10_2_SINT" value="0x3a"/>
+	<value name="VFMT_10_10_10_2_SNORM" value="0x3b"/>
+	<value name="VFMT_2_10_10_10_UINT" value="0x3c"/>
+	<value name="VFMT_2_10_10_10_UNORM" value="0x3d"/>
+	<value name="VFMT_2_10_10_10_SINT" value="0x3e"/>
+	<value name="VFMT_2_10_10_10_SNORM" value="0x3f"/>
+
+	<value name="VFMT_NONE" value="0xff"/>
+</enum>
+
+<enum name="a3xx_tex_fmt">
+	<value name="TFMT_5_6_5_UNORM" value="0x4"/>
+	<value name="TFMT_5_5_5_1_UNORM" value="0x5"/>
+	<value name="TFMT_4_4_4_4_UNORM" value="0x7"/>
+	<value name="TFMT_Z16_UNORM" value="0x9"/>
+	<value name="TFMT_X8Z24_UNORM" value="0xa"/>
+	<value name="TFMT_Z32_FLOAT" value="0xb"/>
+
+	<!--
+		The NV12 tiled/linear formats seem to require gang'd sampler
+		slots (ie. sampler state N plus N+1) for Y and UV planes.
+		They fetch yuv in single sam instruction, but still require
+		colorspace conversion in the shader.
+	 -->
+	<value name="TFMT_UV_64X32" value="0x10"/>
+	<value name="TFMT_VU_64X32" value="0x11"/>
+	<value name="TFMT_Y_64X32" value="0x12"/>
+	<value name="TFMT_NV12_64X32" value="0x13"/>
+	<value name="TFMT_UV_LINEAR" value="0x14"/>
+	<value name="TFMT_VU_LINEAR" value="0x15"/>
+	<value name="TFMT_Y_LINEAR" value="0x16"/>
+	<value name="TFMT_NV12_LINEAR" value="0x17"/>
+	<value name="TFMT_I420_Y" value="0x18"/>
+	<value name="TFMT_I420_U" value="0x1a"/>
+	<value name="TFMT_I420_V" value="0x1b"/>
+
+	<value name="TFMT_ATC_RGB" value="0x20"/>
+	<value name="TFMT_ATC_RGBA_EXPLICIT" value="0x21"/>
+	<value name="TFMT_ETC1" value="0x22"/>
+	<value name="TFMT_ATC_RGBA_INTERPOLATED" value="0x23"/>
+
+	<value name="TFMT_DXT1" value="0x24"/>
+	<value name="TFMT_DXT3" value="0x25"/>
+	<value name="TFMT_DXT5" value="0x26"/>
+
+	<value name="TFMT_2_10_10_10_UNORM" value="0x28"/>
+	<value name="TFMT_10_10_10_2_UNORM" value="0x29"/>
+	<value name="TFMT_9_9_9_E5_FLOAT" value="0x2a"/>
+	<value name="TFMT_11_11_10_FLOAT" value="0x2b"/>
+	<value name="TFMT_A8_UNORM" value="0x2c"/>    <!-- GL_ALPHA -->
+	<value name="TFMT_L8_UNORM" value="0x2d"/>
+	<value name="TFMT_L8_A8_UNORM" value="0x2f"/> <!-- GL_LUMINANCE_ALPHA -->
+
+	<!--
+		NOTE: GL_ALPHA and GL_LUMINANCE_ALPHA aren't handled in a similar way
+		to float16, float32.. but they seem to use non-standard swizzle too..
+		perhaps we can ditch that if the pattern follows of 0xn0, 0xn1, 0xn2,
+		0xn3 for 1, 2, 3, 4 components respectively..
+
+		Only formats filled in below are the ones that have been observed by
+		the blob or tested.. you can guess what the missing ones are..
+	 -->
+
+	<value name="TFMT_8_UNORM" value="0x30"/>     <!-- GL_LUMINANCE -->
+	<value name="TFMT_8_8_UNORM" value="0x31"/>
+	<value name="TFMT_8_8_8_UNORM" value="0x32"/>
+	<value name="TFMT_8_8_8_8_UNORM" value="0x33"/>
+
+	<value name="TFMT_8_SNORM" value="0x34"/>
+	<value name="TFMT_8_8_SNORM" value="0x35"/>
+	<value name="TFMT_8_8_8_SNORM" value="0x36"/>
+	<value name="TFMT_8_8_8_8_SNORM" value="0x37"/>
+
+	<value name="TFMT_8_UINT" value="0x38"/>
+	<value name="TFMT_8_8_UINT" value="0x39"/>
+	<value name="TFMT_8_8_8_UINT" value="0x3a"/>
+	<value name="TFMT_8_8_8_8_UINT" value="0x3b"/>
+
+	<value name="TFMT_8_SINT" value="0x3c"/>
+	<value name="TFMT_8_8_SINT" value="0x3d"/>
+	<value name="TFMT_8_8_8_SINT" value="0x3e"/>
+	<value name="TFMT_8_8_8_8_SINT" value="0x3f"/>
+
+	<value name="TFMT_16_FLOAT" value="0x40"/>
+	<value name="TFMT_16_16_FLOAT" value="0x41"/>
+	<!-- TFMT_FLOAT_16_16_16 -->
+	<value name="TFMT_16_16_16_16_FLOAT" value="0x43"/>
+
+	<value name="TFMT_16_UINT" value="0x44"/>
+	<value name="TFMT_16_16_UINT" value="0x45"/>
+	<value name="TFMT_16_16_16_16_UINT" value="0x47"/>
+
+	<value name="TFMT_16_SINT" value="0x48"/>
+	<value name="TFMT_16_16_SINT" value="0x49"/>
+	<value name="TFMT_16_16_16_16_SINT" value="0x4b"/>
+
+	<value name="TFMT_16_UNORM" value="0x4c"/>
+	<value name="TFMT_16_16_UNORM" value="0x4d"/>
+	<value name="TFMT_16_16_16_16_UNORM" value="0x4f"/>
+
+	<value name="TFMT_16_SNORM" value="0x50"/>
+	<value name="TFMT_16_16_SNORM" value="0x51"/>
+	<value name="TFMT_16_16_16_16_SNORM" value="0x53"/>
+
+	<value name="TFMT_32_FLOAT" value="0x54"/>
+	<value name="TFMT_32_32_FLOAT" value="0x55"/>
+	<!-- TFMT_32_32_32_FLOAT -->
+	<value name="TFMT_32_32_32_32_FLOAT" value="0x57"/>
+
+	<value name="TFMT_32_UINT" value="0x58"/>
+	<value name="TFMT_32_32_UINT" value="0x59"/>
+	<value name="TFMT_32_32_32_32_UINT" value="0x5b"/>
+
+	<value name="TFMT_32_SINT" value="0x5c"/>
+	<value name="TFMT_32_32_SINT" value="0x5d"/>
+	<value name="TFMT_32_32_32_32_SINT" value="0x5f"/>
+
+	<value name="TFMT_2_10_10_10_UINT" value="0x60"/>
+	<value name="TFMT_10_10_10_2_UINT" value="0x61"/>
+
+	<value name="TFMT_ETC2_RG11_SNORM" value="0x70"/>
+	<value name="TFMT_ETC2_RG11_UNORM" value="0x71"/>
+	<value name="TFMT_ETC2_R11_SNORM" value="0x72"/>
+	<value name="TFMT_ETC2_R11_UNORM" value="0x73"/>
+	<value name="TFMT_ETC2_RGBA8" value="0x74"/>
+	<value name="TFMT_ETC2_RGB8A1" value="0x75"/>
+	<value name="TFMT_ETC2_RGB8" value="0x76"/>
+
+	<value name="TFMT_NONE" value="0xff"/>
+</enum>
+
+<enum name="a3xx_color_fmt">
+	<value name="RB_R5G6B5_UNORM"       value="0x00"/>
+	<value name="RB_R5G5B5A1_UNORM"     value="0x01"/>
+	<value name="RB_R4G4B4A4_UNORM"     value="0x03"/>
+	<value name="RB_R8G8B8_UNORM"	    value="0x04"/>
+	<value name="RB_R8G8B8A8_UNORM"	    value="0x08"/>
+	<value name="RB_R8G8B8A8_SNORM"	    value="0x09"/>
+	<value name="RB_R8G8B8A8_UINT"	    value="0x0a"/>
+	<value name="RB_R8G8B8A8_SINT"	    value="0x0b"/>
+	<value name="RB_R8G8_UNORM"	    value="0x0c"/>
+	<value name="RB_R8G8_SNORM"	    value="0x0d"/>
+	<value name="RB_R8G8_UINT"	    value="0x0e"/>
+	<value name="RB_R8G8_SINT"	    value="0x0f"/>
+	<value name="RB_R10G10B10A2_UNORM"  value="0x10"/>
+	<value name="RB_A2R10G10B10_UNORM"  value="0x11"/>
+	<value name="RB_R10G10B10A2_UINT"   value="0x12"/>
+	<value name="RB_A2R10G10B10_UINT"   value="0x13"/>
+
+	<value name="RB_A8_UNORM"	    value="0x14"/>
+	<value name="RB_R8_UNORM"	    value="0x15"/>
+
+	<value name="RB_R16_FLOAT"          value="0x18"/>
+	<value name="RB_R16G16_FLOAT"       value="0x19"/>
+	<value name="RB_R16G16B16A16_FLOAT" value="0x1b"/> <!-- GL_HALF_FLOAT_OES -->
+	<value name="RB_R11G11B10_FLOAT"    value="0x1c"/>
+
+	<value name="RB_R16_SNORM"          value="0x20"/>
+	<value name="RB_R16G16_SNORM"       value="0x21"/>
+	<value name="RB_R16G16B16A16_SNORM" value="0x23"/>
+
+	<value name="RB_R16_UNORM"          value="0x24"/>
+	<value name="RB_R16G16_UNORM"       value="0x25"/>
+	<value name="RB_R16G16B16A16_UNORM" value="0x27"/>
+
+	<value name="RB_R16_SINT"	    value="0x28"/>
+	<value name="RB_R16G16_SINT"	    value="0x29"/>
+	<value name="RB_R16G16B16A16_SINT"  value="0x2b"/>
+
+	<value name="RB_R16_UINT"	    value="0x2c"/>
+	<value name="RB_R16G16_UINT"	    value="0x2d"/>
+	<value name="RB_R16G16B16A16_UINT"  value="0x2f"/>
+
+	<value name="RB_R32_FLOAT"          value="0x30"/>
+	<value name="RB_R32G32_FLOAT"       value="0x31"/>
+	<value name="RB_R32G32B32A32_FLOAT" value="0x33"/> <!-- GL_FLOAT -->
+
+	<value name="RB_R32_SINT"	    value="0x34"/>
+	<value name="RB_R32G32_SINT"	    value="0x35"/>
+	<value name="RB_R32G32B32A32_SINT"  value="0x37"/>
+
+	<value name="RB_R32_UINT"	    value="0x38"/>
+	<value name="RB_R32G32_UINT"	    value="0x39"/>
+	<value name="RB_R32G32B32A32_UINT"  value="0x3b"/>
+
+	<value name="RB_NONE"               value="0xff"/>
+</enum>
+
+<enum name="a3xx_cp_perfcounter_select">
+	<value value="0x00" name="CP_ALWAYS_COUNT"/>
+	<value value="0x03" name="CP_AHB_PFPTRANS_WAIT"/>
+	<value value="0x06" name="CP_AHB_NRTTRANS_WAIT"/>
+	<value value="0x08" name="CP_CSF_NRT_READ_WAIT"/>
+	<value value="0x09" name="CP_CSF_I1_FIFO_FULL"/>
+	<value value="0x0a" name="CP_CSF_I2_FIFO_FULL"/>
+	<value value="0x0b" name="CP_CSF_ST_FIFO_FULL"/>
+	<value value="0x0c" name="CP_RESERVED_12"/>
+	<value value="0x0d" name="CP_CSF_RING_ROQ_FULL"/>
+	<value value="0x0e" name="CP_CSF_I1_ROQ_FULL"/>
+	<value value="0x0f" name="CP_CSF_I2_ROQ_FULL"/>
+	<value value="0x10" name="CP_CSF_ST_ROQ_FULL"/>
+	<value value="0x11" name="CP_RESERVED_17"/>
+	<value value="0x12" name="CP_MIU_TAG_MEM_FULL"/>
+	<value value="0x16" name="CP_MIU_NRT_WRITE_STALLED"/>
+	<value value="0x17" name="CP_MIU_NRT_READ_STALLED"/>
+	<value value="0x1a" name="CP_ME_REGS_RB_DONE_FIFO_FULL"/>
+	<value value="0x1b" name="CP_ME_REGS_VS_EVENT_FIFO_FULL"/>
+	<value value="0x1c" name="CP_ME_REGS_PS_EVENT_FIFO_FULL"/>
+	<value value="0x1d" name="CP_ME_REGS_CF_EVENT_FIFO_FULL"/>
+	<value value="0x1e" name="CP_ME_MICRO_RB_STARVED"/>
+	<value value="0x28" name="CP_AHB_RBBM_DWORD_SENT"/>
+	<value value="0x29" name="CP_ME_BUSY_CLOCKS"/>
+	<value value="0x2a" name="CP_ME_WAIT_CONTEXT_AVAIL"/>
+	<value value="0x2b" name="CP_PFP_TYPE0_PACKET"/>
+	<value value="0x2c" name="CP_PFP_TYPE3_PACKET"/>
+	<value value="0x2d" name="CP_CSF_RB_WPTR_NEQ_RPTR"/>
+	<value value="0x2e" name="CP_CSF_I1_SIZE_NEQ_ZERO"/>
+	<value value="0x2f" name="CP_CSF_I2_SIZE_NEQ_ZERO"/>
+	<value value="0x30" name="CP_CSF_RBI1I2_FETCHING"/>
+</enum>
+
+<enum name="a3xx_gras_tse_perfcounter_select">
+	<value value="0x00" name="GRAS_TSEPERF_INPUT_PRIM"/>
+	<value value="0x01" name="GRAS_TSEPERF_INPUT_NULL_PRIM"/>
+	<value value="0x02" name="GRAS_TSEPERF_TRIVAL_REJ_PRIM"/>
+	<value value="0x03" name="GRAS_TSEPERF_CLIPPED_PRIM"/>
+	<value value="0x04" name="GRAS_TSEPERF_NEW_PRIM"/>
+	<value value="0x05" name="GRAS_TSEPERF_ZERO_AREA_PRIM"/>
+	<value value="0x06" name="GRAS_TSEPERF_FACENESS_CULLED_PRIM"/>
+	<value value="0x07" name="GRAS_TSEPERF_ZERO_PIXEL_PRIM"/>
+	<value value="0x08" name="GRAS_TSEPERF_OUTPUT_NULL_PRIM"/>
+	<value value="0x09" name="GRAS_TSEPERF_OUTPUT_VISIBLE_PRIM"/>
+	<value value="0x0a" name="GRAS_TSEPERF_PRE_CLIP_PRIM"/>
+	<value value="0x0b" name="GRAS_TSEPERF_POST_CLIP_PRIM"/>
+	<value value="0x0c" name="GRAS_TSEPERF_WORKING_CYCLES"/>
+	<value value="0x0d" name="GRAS_TSEPERF_PC_STARVE"/>
+	<value value="0x0e" name="GRAS_TSERASPERF_STALL"/>
+</enum>
+
+<enum name="a3xx_gras_ras_perfcounter_select">
+	<value value="0x00" name="GRAS_RASPERF_16X16_TILES"/>
+	<value value="0x01" name="GRAS_RASPERF_8X8_TILES"/>
+	<value value="0x02" name="GRAS_RASPERF_4X4_TILES"/>
+	<value value="0x03" name="GRAS_RASPERF_WORKING_CYCLES"/>
+	<value value="0x04" name="GRAS_RASPERF_STALL_CYCLES_BY_RB"/>
+	<value value="0x05" name="GRAS_RASPERF_STALL_CYCLES_BY_VSC"/>
+	<value value="0x06" name="GRAS_RASPERF_STARVE_CYCLES_BY_TSE"/>
+</enum>
+
+<enum name="a3xx_hlsq_perfcounter_select">
+	<value value="0x00" name="HLSQ_PERF_SP_VS_CONSTANT"/>
+	<value value="0x01" name="HLSQ_PERF_SP_VS_INSTRUCTIONS"/>
+	<value value="0x02" name="HLSQ_PERF_SP_FS_CONSTANT"/>
+	<value value="0x03" name="HLSQ_PERF_SP_FS_INSTRUCTIONS"/>
+	<value value="0x04" name="HLSQ_PERF_TP_STATE"/>
+	<value value="0x05" name="HLSQ_PERF_QUADS"/>
+	<value value="0x06" name="HLSQ_PERF_PIXELS"/>
+	<value value="0x07" name="HLSQ_PERF_VERTICES"/>
+	<value value="0x08" name="HLSQ_PERF_FS8_THREADS"/>
+	<value value="0x09" name="HLSQ_PERF_FS16_THREADS"/>
+	<value value="0x0a" name="HLSQ_PERF_FS32_THREADS"/>
+	<value value="0x0b" name="HLSQ_PERF_VS8_THREADS"/>
+	<value value="0x0c" name="HLSQ_PERF_VS16_THREADS"/>
+	<value value="0x0d" name="HLSQ_PERF_SP_VS_DATA_BYTES"/>
+	<value value="0x0e" name="HLSQ_PERF_SP_FS_DATA_BYTES"/>
+	<value value="0x0f" name="HLSQ_PERF_ACTIVE_CYCLES"/>
+	<value value="0x10" name="HLSQ_PERF_STALL_CYCLES_SP_STATE"/>
+	<value value="0x11" name="HLSQ_PERF_STALL_CYCLES_SP_VS"/>
+	<value value="0x12" name="HLSQ_PERF_STALL_CYCLES_SP_FS"/>
+	<value value="0x13" name="HLSQ_PERF_STALL_CYCLES_UCHE"/>
+	<value value="0x14" name="HLSQ_PERF_RBBM_LOAD_CYCLES"/>
+	<value value="0x15" name="HLSQ_PERF_DI_TO_VS_START_SP0"/>
+	<value value="0x16" name="HLSQ_PERF_DI_TO_FS_START_SP0"/>
+	<value value="0x17" name="HLSQ_PERF_VS_START_TO_DONE_SP0"/>
+	<value value="0x18" name="HLSQ_PERF_FS_START_TO_DONE_SP0"/>
+	<value value="0x19" name="HLSQ_PERF_SP_STATE_COPY_CYCLES_VS"/>
+	<value value="0x1a" name="HLSQ_PERF_SP_STATE_COPY_CYCLES_FS"/>
+	<value value="0x1b" name="HLSQ_PERF_UCHE_LATENCY_CYCLES"/>
+	<value value="0x1c" name="HLSQ_PERF_UCHE_LATENCY_COUNT"/>
+</enum>
+
+<enum name="a3xx_pc_perfcounter_select">
+	<value value="0x00" name="PC_PCPERF_VISIBILITY_STREAMS"/>
+	<value value="0x01" name="PC_PCPERF_TOTAL_INSTANCES"/>
+	<value value="0x02" name="PC_PCPERF_PRIMITIVES_PC_VPC"/>
+	<value value="0x03" name="PC_PCPERF_PRIMITIVES_KILLED_BY_VS"/>
+	<value value="0x04" name="PC_PCPERF_PRIMITIVES_VISIBLE_BY_VS"/>
+	<value value="0x05" name="PC_PCPERF_DRAWCALLS_KILLED_BY_VS"/>
+	<value value="0x06" name="PC_PCPERF_DRAWCALLS_VISIBLE_BY_VS"/>
+	<value value="0x07" name="PC_PCPERF_VERTICES_TO_VFD"/>
+	<value value="0x08" name="PC_PCPERF_REUSED_VERTICES"/>
+	<value value="0x09" name="PC_PCPERF_CYCLES_STALLED_BY_VFD"/>
+	<value value="0x0a" name="PC_PCPERF_CYCLES_STALLED_BY_TSE"/>
+	<value value="0x0b" name="PC_PCPERF_CYCLES_STALLED_BY_VBIF"/>
+	<value value="0x0c" name="PC_PCPERF_CYCLES_IS_WORKING"/>
+</enum>
+
+<enum name="a3xx_rb_perfcounter_select">
+	<value value="0x00" name="RB_RBPERF_ACTIVE_CYCLES_ANY"/>
+	<value value="0x01" name="RB_RBPERF_ACTIVE_CYCLES_ALL"/>
+	<value value="0x02" name="RB_RBPERF_STARVE_CYCLES_BY_SP"/>
+	<value value="0x03" name="RB_RBPERF_STARVE_CYCLES_BY_RAS"/>
+	<value value="0x04" name="RB_RBPERF_STARVE_CYCLES_BY_MARB"/>
+	<value value="0x05" name="RB_RBPERF_STALL_CYCLES_BY_MARB"/>
+	<value value="0x06" name="RB_RBPERF_STALL_CYCLES_BY_HLSQ"/>
+	<value value="0x07" name="RB_RBPERF_RB_MARB_DATA"/>
+	<value value="0x08" name="RB_RBPERF_SP_RB_QUAD"/>
+	<value value="0x09" name="RB_RBPERF_RAS_EARLY_Z_QUADS"/>
+	<value value="0x0a" name="RB_RBPERF_GMEM_CH0_READ"/>
+	<value value="0x0b" name="RB_RBPERF_GMEM_CH1_READ"/>
+	<value value="0x0c" name="RB_RBPERF_GMEM_CH0_WRITE"/>
+	<value value="0x0d" name="RB_RBPERF_GMEM_CH1_WRITE"/>
+	<value value="0x0e" name="RB_RBPERF_CP_CONTEXT_DONE"/>
+	<value value="0x0f" name="RB_RBPERF_CP_CACHE_FLUSH"/>
+	<value value="0x10" name="RB_RBPERF_CP_ZPASS_DONE"/>
+</enum>
+
+<enum name="a3xx_rbbm_perfcounter_select">
+	<value value="0" name="RBBM_ALAWYS_ON"/>
+	<value value="1" name="RBBM_VBIF_BUSY"/>
+	<value value="2" name="RBBM_TSE_BUSY"/>
+	<value value="3" name="RBBM_RAS_BUSY"/>
+	<value value="4" name="RBBM_PC_DCALL_BUSY"/>
+	<value value="5" name="RBBM_PC_VSD_BUSY"/>
+	<value value="6" name="RBBM_VFD_BUSY"/>
+	<value value="7" name="RBBM_VPC_BUSY"/>
+	<value value="8" name="RBBM_UCHE_BUSY"/>
+	<value value="9" name="RBBM_VSC_BUSY"/>
+	<value value="10" name="RBBM_HLSQ_BUSY"/>
+	<value value="11" name="RBBM_ANY_RB_BUSY"/>
+	<value value="12" name="RBBM_ANY_TEX_BUSY"/>
+	<value value="13" name="RBBM_ANY_USP_BUSY"/>
+	<value value="14" name="RBBM_ANY_MARB_BUSY"/>
+	<value value="15" name="RBBM_ANY_ARB_BUSY"/>
+	<value value="16" name="RBBM_AHB_STATUS_BUSY"/>
+	<value value="17" name="RBBM_AHB_STATUS_STALLED"/>
+	<value value="18" name="RBBM_AHB_STATUS_TXFR"/>
+	<value value="19" name="RBBM_AHB_STATUS_TXFR_SPLIT"/>
+	<value value="20" name="RBBM_AHB_STATUS_TXFR_ERROR"/>
+	<value value="21" name="RBBM_AHB_STATUS_LONG_STALL"/>
+	<value value="22" name="RBBM_RBBM_STATUS_MASKED"/>
+</enum>
+
+<enum name="a3xx_sp_perfcounter_select">
+	<value value="0x00" name="SP_LM_LOAD_INSTRUCTIONS"/>
+	<value value="0x01" name="SP_LM_STORE_INSTRUCTIONS"/>
+	<value value="0x02" name="SP_LM_ATOMICS"/>
+	<value value="0x03" name="SP_UCHE_LOAD_INSTRUCTIONS"/>
+	<value value="0x04" name="SP_UCHE_STORE_INSTRUCTIONS"/>
+	<value value="0x05" name="SP_UCHE_ATOMICS"/>
+	<value value="0x06" name="SP_VS_TEX_INSTRUCTIONS"/>
+	<value value="0x07" name="SP_VS_CFLOW_INSTRUCTIONS"/>
+	<value value="0x08" name="SP_VS_EFU_INSTRUCTIONS"/>
+	<value value="0x09" name="SP_VS_FULL_ALU_INSTRUCTIONS"/>
+	<value value="0x0a" name="SP_VS_HALF_ALU_INSTRUCTIONS"/>
+	<value value="0x0b" name="SP_FS_TEX_INSTRUCTIONS"/>
+	<value value="0x0c" name="SP_FS_CFLOW_INSTRUCTIONS"/>
+	<value value="0x0d" name="SP_FS_EFU_INSTRUCTIONS"/>
+	<value value="0x0e" name="SP_FS_FULL_ALU_INSTRUCTIONS"/>
+	<value value="0x0f" name="SP_FS_HALF_ALU_INSTRUCTIONS"/>
+	<value value="0x10" name="SP_FS_BARY_INSTRUCTIONS"/>
+	<value value="0x11" name="SP_VS_INSTRUCTIONS"/>
+	<value value="0x12" name="SP_FS_INSTRUCTIONS"/>
+	<value value="0x13" name="SP_ADDR_LOCK_COUNT"/>
+	<value value="0x14" name="SP_UCHE_READ_TRANS"/>
+	<value value="0x15" name="SP_UCHE_WRITE_TRANS"/>
+	<value value="0x16" name="SP_EXPORT_VPC_TRANS"/>
+	<value value="0x17" name="SP_EXPORT_RB_TRANS"/>
+	<value value="0x18" name="SP_PIXELS_KILLED"/>
+	<value value="0x19" name="SP_ICL1_REQUESTS"/>
+	<value value="0x1a" name="SP_ICL1_MISSES"/>
+	<value value="0x1b" name="SP_ICL0_REQUESTS"/>
+	<value value="0x1c" name="SP_ICL0_MISSES"/>
+	<value value="0x1d" name="SP_ALU_ACTIVE_CYCLES"/>
+	<value value="0x1e" name="SP_EFU_ACTIVE_CYCLES"/>
+	<value value="0x1f" name="SP_STALL_CYCLES_BY_VPC"/>
+	<value value="0x20" name="SP_STALL_CYCLES_BY_TP"/>
+	<value value="0x21" name="SP_STALL_CYCLES_BY_UCHE"/>
+	<value value="0x22" name="SP_STALL_CYCLES_BY_RB"/>
+	<value value="0x23" name="SP_ACTIVE_CYCLES_ANY"/>
+	<value value="0x24" name="SP_ACTIVE_CYCLES_ALL"/>
+</enum>
+
+<enum name="a3xx_tp_perfcounter_select">
+	<value value="0x00" name="TPL1_TPPERF_L1_REQUESTS"/>
+	<value value="0x01" name="TPL1_TPPERF_TP0_L1_REQUESTS"/>
+	<value value="0x02" name="TPL1_TPPERF_TP0_L1_MISSES"/>
+	<value value="0x03" name="TPL1_TPPERF_TP1_L1_REQUESTS"/>
+	<value value="0x04" name="TPL1_TPPERF_TP1_L1_MISSES"/>
+	<value value="0x05" name="TPL1_TPPERF_TP2_L1_REQUESTS"/>
+	<value value="0x06" name="TPL1_TPPERF_TP2_L1_MISSES"/>
+	<value value="0x07" name="TPL1_TPPERF_TP3_L1_REQUESTS"/>
+	<value value="0x08" name="TPL1_TPPERF_TP3_L1_MISSES"/>
+	<value value="0x09" name="TPL1_TPPERF_OUTPUT_TEXELS_POINT"/>
+	<value value="0x0a" name="TPL1_TPPERF_OUTPUT_TEXELS_BILINEAR"/>
+	<value value="0x0b" name="TPL1_TPPERF_OUTPUT_TEXELS_MIP"/>
+	<value value="0x0c" name="TPL1_TPPERF_OUTPUT_TEXELS_ANISO"/>
+	<value value="0x0d" name="TPL1_TPPERF_BILINEAR_OPS"/>
+	<value value="0x0e" name="TPL1_TPPERF_QUADSQUADS_OFFSET"/>
+	<value value="0x0f" name="TPL1_TPPERF_QUADQUADS_SHADOW"/>
+	<value value="0x10" name="TPL1_TPPERF_QUADS_ARRAY"/>
+	<value value="0x11" name="TPL1_TPPERF_QUADS_PROJECTION"/>
+	<value value="0x12" name="TPL1_TPPERF_QUADS_GRADIENT"/>
+	<value value="0x13" name="TPL1_TPPERF_QUADS_1D2D"/>
+	<value value="0x14" name="TPL1_TPPERF_QUADS_3DCUBE"/>
+	<value value="0x15" name="TPL1_TPPERF_ZERO_LOD"/>
+	<value value="0x16" name="TPL1_TPPERF_OUTPUT_TEXELS"/>
+	<value value="0x17" name="TPL1_TPPERF_ACTIVE_CYCLES_ANY"/>
+	<value value="0x18" name="TPL1_TPPERF_ACTIVE_CYCLES_ALL"/>
+	<value value="0x19" name="TPL1_TPPERF_STALL_CYCLES_BY_ARB"/>
+	<value value="0x1a" name="TPL1_TPPERF_LATENCY"/>
+	<value value="0x1b" name="TPL1_TPPERF_LATENCY_TRANS"/>
+</enum>
+
+<enum name="a3xx_vfd_perfcounter_select">
+	<value value="0" name="VFD_PERF_UCHE_BYTE_FETCHED"/>
+	<value value="1" name="VFD_PERF_UCHE_TRANS"/>
+	<value value="2" name="VFD_PERF_VPC_BYPASS_COMPONENTS"/>
+	<value value="3" name="VFD_PERF_FETCH_INSTRUCTIONS"/>
+	<value value="4" name="VFD_PERF_DECODE_INSTRUCTIONS"/>
+	<value value="5" name="VFD_PERF_ACTIVE_CYCLES"/>
+	<value value="6" name="VFD_PERF_STALL_CYCLES_UCHE"/>
+	<value value="7" name="VFD_PERF_STALL_CYCLES_HLSQ"/>
+	<value value="8" name="VFD_PERF_STALL_CYCLES_VPC_BYPASS"/>
+	<value value="9" name="VFD_PERF_STALL_CYCLES_VPC_ALLOC"/>
+</enum>
+
+<enum name="a3xx_vpc_perfcounter_select">
+	<value value="0" name="VPC_PERF_SP_LM_PRIMITIVES"/>
+	<value value="1" name="VPC_PERF_COMPONENTS_FROM_SP"/>
+	<value value="2" name="VPC_PERF_SP_LM_COMPONENTS"/>
+	<value value="3" name="VPC_PERF_ACTIVE_CYCLES"/>
+	<value value="4" name="VPC_PERF_STALL_CYCLES_LM"/>
+	<value value="5" name="VPC_PERF_STALL_CYCLES_RAS"/>
+</enum>
+
+<enum name="a3xx_uche_perfcounter_select">
+	<value value="0x00" name="UCHE_UCHEPERF_VBIF_READ_BEATS_TP"/>
+	<value value="0x01" name="UCHE_UCHEPERF_VBIF_READ_BEATS_VFD"/>
+	<value value="0x02" name="UCHE_UCHEPERF_VBIF_READ_BEATS_HLSQ"/>
+	<value value="0x03" name="UCHE_UCHEPERF_VBIF_READ_BEATS_MARB"/>
+	<value value="0x04" name="UCHE_UCHEPERF_VBIF_READ_BEATS_SP"/>
+	<value value="0x08" name="UCHE_UCHEPERF_READ_REQUESTS_TP"/>
+	<value value="0x09" name="UCHE_UCHEPERF_READ_REQUESTS_VFD"/>
+	<value value="0x0a" name="UCHE_UCHEPERF_READ_REQUESTS_HLSQ"/>
+	<value value="0x0b" name="UCHE_UCHEPERF_READ_REQUESTS_MARB"/>
+	<value value="0x0c" name="UCHE_UCHEPERF_READ_REQUESTS_SP"/>
+	<value value="0x0d" name="UCHE_UCHEPERF_WRITE_REQUESTS_MARB"/>
+	<value value="0x0e" name="UCHE_UCHEPERF_WRITE_REQUESTS_SP"/>
+	<value value="0x0f" name="UCHE_UCHEPERF_TAG_CHECK_FAILS"/>
+	<value value="0x10" name="UCHE_UCHEPERF_EVICTS"/>
+	<value value="0x11" name="UCHE_UCHEPERF_FLUSHES"/>
+	<value value="0x12" name="UCHE_UCHEPERF_VBIF_LATENCY_CYCLES"/>
+	<value value="0x13" name="UCHE_UCHEPERF_VBIF_LATENCY_SAMPLES"/>
+	<value value="0x14" name="UCHE_UCHEPERF_ACTIVE_CYCLES"/>
+</enum>
+
+<enum name="a3xx_intp_mode">
+	<value name="SMOOTH" value="0"/>
+	<value name="FLAT" value="1"/>
+	<value name="ZERO" value="2"/>
+	<value name="ONE" value="3"/>
+</enum>
+
+<enum name="a3xx_repl_mode">
+	<value name="S" value="1"/>
+	<value name="T" value="2"/>
+	<value name="ONE_T" value="3"/>
+</enum>
+
+<domain name="A3XX" width="32">
+	<!-- RBBM registers -->
+	<reg32 offset="0x0000" name="RBBM_HW_VERSION"/>
+	<reg32 offset="0x0001" name="RBBM_HW_RELEASE"/>
+	<reg32 offset="0x0002" name="RBBM_HW_CONFIGURATION"/>
+	<reg32 offset="0x0010" name="RBBM_CLOCK_CTL"/>
+	<reg32 offset="0x0012" name="RBBM_SP_HYST_CNT"/>
+	<reg32 offset="0x0018" name="RBBM_SW_RESET_CMD"/>
+	<reg32 offset="0x0020" name="RBBM_AHB_CTL0"/>
+	<reg32 offset="0x0021" name="RBBM_AHB_CTL1"/>
+	<reg32 offset="0x0022" name="RBBM_AHB_CMD"/>
+	<reg32 offset="0x0027" name="RBBM_AHB_ERROR_STATUS"/>
+	<reg32 offset="0x002e" name="RBBM_GPR0_CTL"/>
+	<reg32 offset="0x0030" name="RBBM_STATUS">
+		<bitfield name="HI_BUSY" pos="0" type="boolean"/>
+		<bitfield name="CP_ME_BUSY" pos="1" type="boolean"/>
+		<bitfield name="CP_PFP_BUSY" pos="2" type="boolean"/>
+		<bitfield name="CP_NRT_BUSY" pos="14" type="boolean"/>
+		<bitfield name="VBIF_BUSY" pos="15" type="boolean"/>
+		<bitfield name="TSE_BUSY" pos="16" type="boolean"/>
+		<bitfield name="RAS_BUSY" pos="17" type="boolean"/>
+		<bitfield name="RB_BUSY" pos="18" type="boolean"/>
+		<bitfield name="PC_DCALL_BUSY" pos="19" type="boolean"/>
+		<bitfield name="PC_VSD_BUSY" pos="20" type="boolean"/>
+		<bitfield name="VFD_BUSY" pos="21" type="boolean"/>
+		<bitfield name="VPC_BUSY" pos="22" type="boolean"/>
+		<bitfield name="UCHE_BUSY" pos="23" type="boolean"/>
+		<bitfield name="SP_BUSY" pos="24" type="boolean"/>
+		<bitfield name="TPL1_BUSY" pos="25" type="boolean"/>
+		<bitfield name="MARB_BUSY" pos="26" type="boolean"/>
+		<bitfield name="VSC_BUSY" pos="27" type="boolean"/>
+		<bitfield name="ARB_BUSY" pos="28" type="boolean"/>
+		<bitfield name="HLSQ_BUSY" pos="29" type="boolean"/>
+		<bitfield name="GPU_BUSY_NOHC" pos="30" type="boolean"/>
+		<bitfield name="GPU_BUSY" pos="31" type="boolean"/>
+	</reg32>
+	<!-- used in fw CP_WAIT_FOR_IDLE, similar to NQWAIT_UNTIL on a2xx: -->
+	<reg32 offset="0x0040" name="RBBM_NQWAIT_UNTIL"/>
+	<reg32 offset="0x0033" name="RBBM_WAIT_IDLE_CLOCKS_CTL"/>
+	<reg32 offset="0x0050" name="RBBM_INTERFACE_HANG_INT_CTL"/>
+	<reg32 offset="0x0051" name="RBBM_INTERFACE_HANG_MASK_CTL0"/>
+	<reg32 offset="0x0054" name="RBBM_INTERFACE_HANG_MASK_CTL1"/>
+	<reg32 offset="0x0057" name="RBBM_INTERFACE_HANG_MASK_CTL2"/>
+	<reg32 offset="0x005a" name="RBBM_INTERFACE_HANG_MASK_CTL3"/>
+
+	<bitset name="A3XX_INT0">
+		<bitfield name="RBBM_GPU_IDLE" pos="0" type="boolean"/>
+		<bitfield name="RBBM_AHB_ERROR" pos="1" type="boolean"/>
+		<bitfield name="RBBM_REG_TIMEOUT" pos="2" type="boolean"/>
+		<bitfield name="RBBM_ME_MS_TIMEOUT" pos="3" type="boolean"/>
+		<bitfield name="RBBM_PFP_MS_TIMEOUT" pos="4" type="boolean"/>
+		<bitfield name="RBBM_ATB_BUS_OVERFLOW" pos="5" type="boolean"/>
+		<bitfield name="VFD_ERROR" pos="6" type="boolean"/>
+		<bitfield name="CP_SW_INT" pos="7" type="boolean"/>
+		<bitfield name="CP_T0_PACKET_IN_IB" pos="8" type="boolean"/>
+		<bitfield name="CP_OPCODE_ERROR" pos="9" type="boolean"/>
+		<bitfield name="CP_RESERVED_BIT_ERROR" pos="10" type="boolean"/>
+		<bitfield name="CP_HW_FAULT" pos="11" type="boolean"/>
+		<bitfield name="CP_DMA" pos="12" type="boolean"/>
+		<bitfield name="CP_IB2_INT" pos="13" type="boolean"/>
+		<bitfield name="CP_IB1_INT" pos="14" type="boolean"/>
+		<bitfield name="CP_RB_INT" pos="15" type="boolean"/>
+		<bitfield name="CP_REG_PROTECT_FAULT" pos="16" type="boolean"/>
+		<bitfield name="CP_RB_DONE_TS" pos="17" type="boolean"/>
+		<bitfield name="CP_VS_DONE_TS" pos="18" type="boolean"/>
+		<bitfield name="CP_PS_DONE_TS" pos="19" type="boolean"/>
+		<bitfield name="CACHE_FLUSH_TS" pos="20" type="boolean"/>
+		<bitfield name="CP_AHB_ERROR_HALT" pos="21" type="boolean"/>
+		<bitfield name="MISC_HANG_DETECT" pos="24" type="boolean"/>
+		<bitfield name="UCHE_OOB_ACCESS" pos="25" type="boolean"/>
+	</bitset>
+
+
+	<!--
+		set in pm4 fw INVALID_JUMP_TABLE_ENTRY and CP_INTERRUPT (compare
+		to CP_INT_STATUS in a2xx firmware), so this seems to be the a3xx
+		way for fw to raise and irq:
+	 -->
+	<reg32 offset="0x0060" name="RBBM_INT_SET_CMD" type="A3XX_INT0"/>
+	<reg32 offset="0x0061" name="RBBM_INT_CLEAR_CMD" type="A3XX_INT0"/>
+	<reg32 offset="0x0063" name="RBBM_INT_0_MASK" type="A3XX_INT0"/>
+	<reg32 offset="0x0064" name="RBBM_INT_0_STATUS" type="A3XX_INT0"/>
+	<reg32 offset="0x0080" name="RBBM_PERFCTR_CTL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0081" name="RBBM_PERFCTR_LOAD_CMD0"/>
+	<reg32 offset="0x0082" name="RBBM_PERFCTR_LOAD_CMD1"/>
+	<reg32 offset="0x0084" name="RBBM_PERFCTR_LOAD_VALUE_LO"/>
+	<reg32 offset="0x0085" name="RBBM_PERFCTR_LOAD_VALUE_HI"/>
+	<reg32 offset="0x0086" name="RBBM_PERFCOUNTER0_SELECT" type="a3xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x0087" name="RBBM_PERFCOUNTER1_SELECT" type="a3xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x0088" name="RBBM_GPU_BUSY_MASKED"/>
+	<reg32 offset="0x0090" name="RBBM_PERFCTR_CP_0_LO"/>
+	<reg32 offset="0x0091" name="RBBM_PERFCTR_CP_0_HI"/>
+	<reg32 offset="0x0092" name="RBBM_PERFCTR_RBBM_0_LO"/>
+	<reg32 offset="0x0093" name="RBBM_PERFCTR_RBBM_0_HI"/>
+	<reg32 offset="0x0094" name="RBBM_PERFCTR_RBBM_1_LO"/>
+	<reg32 offset="0x0095" name="RBBM_PERFCTR_RBBM_1_HI"/>
+	<reg32 offset="0x0096" name="RBBM_PERFCTR_PC_0_LO"/>
+	<reg32 offset="0x0097" name="RBBM_PERFCTR_PC_0_HI"/>
+	<reg32 offset="0x0098" name="RBBM_PERFCTR_PC_1_LO"/>
+	<reg32 offset="0x0099" name="RBBM_PERFCTR_PC_1_HI"/>
+	<reg32 offset="0x009a" name="RBBM_PERFCTR_PC_2_LO"/>
+	<reg32 offset="0x009b" name="RBBM_PERFCTR_PC_2_HI"/>
+	<reg32 offset="0x009c" name="RBBM_PERFCTR_PC_3_LO"/>
+	<reg32 offset="0x009d" name="RBBM_PERFCTR_PC_3_HI"/>
+	<reg32 offset="0x009e" name="RBBM_PERFCTR_VFD_0_LO"/>
+	<reg32 offset="0x009f" name="RBBM_PERFCTR_VFD_0_HI"/>
+	<reg32 offset="0x00a0" name="RBBM_PERFCTR_VFD_1_LO"/>
+	<reg32 offset="0x00a1" name="RBBM_PERFCTR_VFD_1_HI"/>
+	<reg32 offset="0x00a2" name="RBBM_PERFCTR_HLSQ_0_LO"/>
+	<reg32 offset="0x00a3" name="RBBM_PERFCTR_HLSQ_0_HI"/>
+	<reg32 offset="0x00a4" name="RBBM_PERFCTR_HLSQ_1_LO"/>
+	<reg32 offset="0x00a5" name="RBBM_PERFCTR_HLSQ_1_HI"/>
+	<reg32 offset="0x00a6" name="RBBM_PERFCTR_HLSQ_2_LO"/>
+	<reg32 offset="0x00a7" name="RBBM_PERFCTR_HLSQ_2_HI"/>
+	<reg32 offset="0x00a8" name="RBBM_PERFCTR_HLSQ_3_LO"/>
+	<reg32 offset="0x00a9" name="RBBM_PERFCTR_HLSQ_3_HI"/>
+	<reg32 offset="0x00aa" name="RBBM_PERFCTR_HLSQ_4_LO"/>
+	<reg32 offset="0x00ab" name="RBBM_PERFCTR_HLSQ_4_HI"/>
+	<reg32 offset="0x00ac" name="RBBM_PERFCTR_HLSQ_5_LO"/>
+	<reg32 offset="0x00ad" name="RBBM_PERFCTR_HLSQ_5_HI"/>
+	<reg32 offset="0x00ae" name="RBBM_PERFCTR_VPC_0_LO"/>
+	<reg32 offset="0x00af" name="RBBM_PERFCTR_VPC_0_HI"/>
+	<reg32 offset="0x00b0" name="RBBM_PERFCTR_VPC_1_LO"/>
+	<reg32 offset="0x00b1" name="RBBM_PERFCTR_VPC_1_HI"/>
+	<reg32 offset="0x00b2" name="RBBM_PERFCTR_TSE_0_LO"/>
+	<reg32 offset="0x00b3" name="RBBM_PERFCTR_TSE_0_HI"/>
+	<reg32 offset="0x00b4" name="RBBM_PERFCTR_TSE_1_LO"/>
+	<reg32 offset="0x00b5" name="RBBM_PERFCTR_TSE_1_HI"/>
+	<reg32 offset="0x00b6" name="RBBM_PERFCTR_RAS_0_LO"/>
+	<reg32 offset="0x00b7" name="RBBM_PERFCTR_RAS_0_HI"/>
+	<reg32 offset="0x00b8" name="RBBM_PERFCTR_RAS_1_LO"/>
+	<reg32 offset="0x00b9" name="RBBM_PERFCTR_RAS_1_HI"/>
+	<reg32 offset="0x00ba" name="RBBM_PERFCTR_UCHE_0_LO"/>
+	<reg32 offset="0x00bb" name="RBBM_PERFCTR_UCHE_0_HI"/>
+	<reg32 offset="0x00bc" name="RBBM_PERFCTR_UCHE_1_LO"/>
+	<reg32 offset="0x00bd" name="RBBM_PERFCTR_UCHE_1_HI"/>
+	<reg32 offset="0x00be" name="RBBM_PERFCTR_UCHE_2_LO"/>
+	<reg32 offset="0x00bf" name="RBBM_PERFCTR_UCHE_2_HI"/>
+	<reg32 offset="0x00c0" name="RBBM_PERFCTR_UCHE_3_LO"/>
+	<reg32 offset="0x00c1" name="RBBM_PERFCTR_UCHE_3_HI"/>
+	<reg32 offset="0x00c2" name="RBBM_PERFCTR_UCHE_4_LO"/>
+	<reg32 offset="0x00c3" name="RBBM_PERFCTR_UCHE_4_HI"/>
+	<reg32 offset="0x00c4" name="RBBM_PERFCTR_UCHE_5_LO"/>
+	<reg32 offset="0x00c5" name="RBBM_PERFCTR_UCHE_5_HI"/>
+	<reg32 offset="0x00c6" name="RBBM_PERFCTR_TP_0_LO"/>
+	<reg32 offset="0x00c7" name="RBBM_PERFCTR_TP_0_HI"/>
+	<reg32 offset="0x00c8" name="RBBM_PERFCTR_TP_1_LO"/>
+	<reg32 offset="0x00c9" name="RBBM_PERFCTR_TP_1_HI"/>
+	<reg32 offset="0x00ca" name="RBBM_PERFCTR_TP_2_LO"/>
+	<reg32 offset="0x00cb" name="RBBM_PERFCTR_TP_2_HI"/>
+	<reg32 offset="0x00cc" name="RBBM_PERFCTR_TP_3_LO"/>
+	<reg32 offset="0x00cd" name="RBBM_PERFCTR_TP_3_HI"/>
+	<reg32 offset="0x00ce" name="RBBM_PERFCTR_TP_4_LO"/>
+	<reg32 offset="0x00cf" name="RBBM_PERFCTR_TP_4_HI"/>
+	<reg32 offset="0x00d0" name="RBBM_PERFCTR_TP_5_LO"/>
+	<reg32 offset="0x00d1" name="RBBM_PERFCTR_TP_5_HI"/>
+	<reg32 offset="0x00d2" name="RBBM_PERFCTR_SP_0_LO"/>
+	<reg32 offset="0x00d3" name="RBBM_PERFCTR_SP_0_HI"/>
+	<reg32 offset="0x00d4" name="RBBM_PERFCTR_SP_1_LO"/>
+	<reg32 offset="0x00d5" name="RBBM_PERFCTR_SP_1_HI"/>
+	<reg32 offset="0x00d6" name="RBBM_PERFCTR_SP_2_LO"/>
+	<reg32 offset="0x00d7" name="RBBM_PERFCTR_SP_2_HI"/>
+	<reg32 offset="0x00d8" name="RBBM_PERFCTR_SP_3_LO"/>
+	<reg32 offset="0x00d9" name="RBBM_PERFCTR_SP_3_HI"/>
+	<reg32 offset="0x00da" name="RBBM_PERFCTR_SP_4_LO"/>
+	<reg32 offset="0x00db" name="RBBM_PERFCTR_SP_4_HI"/>
+	<reg32 offset="0x00dc" name="RBBM_PERFCTR_SP_5_LO"/>
+	<reg32 offset="0x00dd" name="RBBM_PERFCTR_SP_5_HI"/>
+	<reg32 offset="0x00de" name="RBBM_PERFCTR_SP_6_LO"/>
+	<reg32 offset="0x00df" name="RBBM_PERFCTR_SP_6_HI"/>
+	<reg32 offset="0x00e0" name="RBBM_PERFCTR_SP_7_LO"/>
+	<reg32 offset="0x00e1" name="RBBM_PERFCTR_SP_7_HI"/>
+	<reg32 offset="0x00e2" name="RBBM_PERFCTR_RB_0_LO"/>
+	<reg32 offset="0x00e3" name="RBBM_PERFCTR_RB_0_HI"/>
+	<reg32 offset="0x00e4" name="RBBM_PERFCTR_RB_1_LO"/>
+	<reg32 offset="0x00e5" name="RBBM_PERFCTR_RB_1_HI"/>
+	<reg32 offset="0x00ea" name="RBBM_PERFCTR_PWR_0_LO"/>
+	<reg32 offset="0x00eb" name="RBBM_PERFCTR_PWR_0_HI"/>
+	<reg32 offset="0x00ec" name="RBBM_PERFCTR_PWR_1_LO"/>
+	<reg32 offset="0x00ed" name="RBBM_PERFCTR_PWR_1_HI"/>
+	<reg32 offset="0x0100" name="RBBM_RBBM_CTL"/>
+	<reg32 offset="0x0111" name="RBBM_DEBUG_BUS_CTL"/>
+	<reg32 offset="0x0112" name="RBBM_DEBUG_BUS_DATA_STATUS"/>
+
+	<!-- CP registers -->
+	<reg32 offset="0x01c9" name="CP_PFP_UCODE_ADDR"/>
+	<reg32 offset="0x01ca" name="CP_PFP_UCODE_DATA"/>
+	<reg32 offset="0x01cc" name="CP_ROQ_ADDR"/>
+	<reg32 offset="0x01cd" name="CP_ROQ_DATA"/>
+	<reg32 offset="0x01d1" name="CP_MERCIU_ADDR"/>
+	<reg32 offset="0x01d2" name="CP_MERCIU_DATA"/>
+	<reg32 offset="0x01d3" name="CP_MERCIU_DATA2"/>
+	<!-- see a3xx_snapshot_cp_meq().. looks like the way to dump queue between pfp and pm4 -->
+	<reg32 offset="0x01da" name="CP_MEQ_ADDR"/>
+	<reg32 offset="0x01db" name="CP_MEQ_DATA"/>
+	<reg32 offset="0x01f5" name="CP_WFI_PEND_CTR"/>
+	<reg32 offset="0x039d" name="RBBM_PM_OVERRIDE2"/>
+
+	<reg32 offset="0x0445" name="CP_PERFCOUNTER_SELECT" type="a3xx_cp_perfcounter_select"/>
+	<reg32 offset="0x045c" name="CP_HW_FAULT"/>
+	<reg32 offset="0x045e" name="CP_PROTECT_CTRL"/>
+	<reg32 offset="0x045f" name="CP_PROTECT_STATUS"/>
+	<array offset="0x0460" name="CP_PROTECT" stride="1" length="16">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<reg32 offset="0x054d" name="CP_AHB_FAULT"/>
+
+	<reg32 offset="0x0d00" name="SQ_GPR_MANAGEMENT"/>
+	<reg32 offset="0x0d02" name="SQ_INST_STORE_MANAGMENT"/>
+	<reg32 offset="0x0e1e" name="TP0_CHICKEN"/>
+
+	<!-- these I guess or either SP or HLSQ since related to shader core setup: -->
+	<reg32 offset="0x0e22" name="SP_GLOBAL_MEM_SIZE" type="uint">
+		<doc>
+			The pair of MEM_SIZE/ADDR registers get programmed
+			in sequence with the size/addr of each buffer.
+		</doc>
+	</reg32>
+	<reg32 offset="0x0e23" name="SP_GLOBAL_MEM_ADDR"/>
+
+	<!-- GRAS registers -->
+	<reg32 offset="0x2040" name="GRAS_CL_CLIP_CNTL">
+		<bitfield name="IJ_PERSP_CENTER" pos="12" type="boolean"/>
+		<bitfield name="IJ_NON_PERSP_CENTER" pos="13" type="boolean"/>
+		<bitfield name="IJ_PERSP_CENTROID" pos="14" type="boolean"/>
+		<bitfield name="IJ_NON_PERSP_CENTROID" pos="15" type="boolean"/>
+		<bitfield name="CLIP_DISABLE" pos="16" type="boolean"/>
+		<bitfield name="ZFAR_CLIP_DISABLE" pos="17" type="boolean"/>
+		<bitfield name="VP_CLIP_CODE_IGNORE" pos="19" type="boolean"/>
+		<bitfield name="VP_XFORM_DISABLE" pos="20" type="boolean"/>
+		<bitfield name="PERSP_DIVISION_DISABLE" pos="21" type="boolean"/>
+		<bitfield name="ZERO_GB_SCALE_Z" pos="22" type="boolean">
+			<doc>aka clip_halfz</doc>
+		</bitfield>
+		<!-- set when gl_FragCoord.z is enabled in frag shader: -->
+		<bitfield name="ZCOORD" pos="23" type="boolean"/>
+		<bitfield name="WCOORD" pos="24" type="boolean"/>
+		<!-- set when frag shader writes z (so early z test disabled: -->
+		<bitfield name="ZCLIP_DISABLE" pos="25" type="boolean"/>
+		<bitfield name="NUM_USER_CLIP_PLANES" low="26" high="28" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2044" name="GRAS_CL_GB_CLIP_ADJ">
+		<bitfield name="HORZ" low="0" high="9" type="uint"/>
+		<bitfield name="VERT" low="10" high="19" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2048" name="GRAS_CL_VPORT_XOFFSET" type="float"/>
+	<reg32 offset="0x2049" name="GRAS_CL_VPORT_XSCALE" type="float"/>
+	<reg32 offset="0x204a" name="GRAS_CL_VPORT_YOFFSET" type="float"/>
+	<reg32 offset="0x204b" name="GRAS_CL_VPORT_YSCALE" type="float"/>
+	<reg32 offset="0x204c" name="GRAS_CL_VPORT_ZOFFSET" type="float"/>
+	<reg32 offset="0x204d" name="GRAS_CL_VPORT_ZSCALE" type="float"/>
+	<reg32 offset="0x2068" name="GRAS_SU_POINT_MINMAX">
+		<bitfield name="MIN" low="0" high="15" type="ufixed" radix="4"/>
+		<bitfield name="MAX" low="16" high="31" type="ufixed" radix="4"/>
+	</reg32>
+	<reg32 offset="0x2069" name="GRAS_SU_POINT_SIZE" type="fixed" radix="4"/>
+	<reg32 offset="0x206c" name="GRAS_SU_POLY_OFFSET_SCALE">
+		<bitfield name="VAL" low="0" high="23" type="fixed" radix="20"/>
+		<doc>range of -8.0 to 8.0</doc>
+	</reg32>
+	<reg32 offset="0x206d" name="GRAS_SU_POLY_OFFSET_OFFSET" radix="6" type="fixed">
+		<doc>range of -512.0 to 512.0</doc>
+	</reg32>
+	<reg32 offset="0x2070" name="GRAS_SU_MODE_CONTROL">
+		<bitfield name="CULL_FRONT" pos="0" type="boolean"/>
+		<bitfield name="CULL_BACK" pos="1" type="boolean"/>
+		<bitfield name="FRONT_CW" pos="2" type="boolean"/>
+		<bitfield name="LINEHALFWIDTH" low="3" high="10" radix="2" type="fixed"/>
+		<bitfield name="POLY_OFFSET" pos="11" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2072" name="GRAS_SC_CONTROL">
+		<!-- complete wild-ass-guess for sizes of these bitfields.. -->
+		<bitfield name="RENDER_MODE" low="4" high="7" type="a3xx_render_mode"/>
+		<bitfield name="MSAA_SAMPLES" low="8" high="11" type="a3xx_msaa_samples"/>
+		<bitfield name="RASTER_MODE" low="12" high="15"/>
+	</reg32>
+
+	<reg32 offset="0x2074" name="GRAS_SC_SCREEN_SCISSOR_TL" type="adreno_reg_xy"/>
+	<reg32 offset="0x2075" name="GRAS_SC_SCREEN_SCISSOR_BR" type="adreno_reg_xy"/>
+	<reg32 offset="0x2079" name="GRAS_SC_WINDOW_SCISSOR_TL" type="adreno_reg_xy"/>
+	<reg32 offset="0x207a" name="GRAS_SC_WINDOW_SCISSOR_BR" type="adreno_reg_xy"/>
+
+	<!-- RB registers -->
+	<reg32 offset="0x20c0" name="RB_MODE_CONTROL">
+		<!-- guess on the # of bits here.. -->
+		<bitfield name="GMEM_BYPASS" pos="7" type="boolean"/>
+		<doc>
+			RENDER_MODE is RB_RESOLVE_PASS for gmem->mem, otherwise RB_RENDER_PASS
+		</doc>
+		<bitfield name="RENDER_MODE" low="8" high="10" type="a3xx_render_mode"/>
+		<bitfield name="MRT" low="12" high="13" type="uint">
+			<doc>render targets - 1</doc>
+		</bitfield>
+		<bitfield name="MARB_CACHE_SPLIT_MODE" pos="15" type="boolean"/>
+		<bitfield name="PACKER_TIMER_ENABLE" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x20c1" name="RB_RENDER_CONTROL">
+		<bitfield name="DUAL_COLOR_IN_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="YUV_IN_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="COV_VALUE_INPUT_ENABLE" pos="2" type="boolean"/>
+		<!-- set when gl_FrontFacing is accessed in frag shader: -->
+		<bitfield name="FACENESS" pos="3" type="boolean"/>
+		<bitfield name="BIN_WIDTH" low="4" high="11" shr="5" type="uint"/>
+		<bitfield name="DISABLE_COLOR_PIPE" pos="12" type="boolean"/>
+		<!--
+			ENABLE_GMEM not set on mem2gmem..  so possibly it is actually
+			controlling blend or readback from GMEM??
+		 -->
+		<bitfield name="ENABLE_GMEM" pos="13" type="boolean"/>
+		<bitfield name="COORD_MASK" low="14" high="17" type="hex"/>
+		<bitfield name="I_CLAMP_ENABLE" pos="19" type="boolean"/>
+		<bitfield name="COV_VALUE_OUTPUT_ENABLE" pos="20" type="boolean"/>
+		<bitfield name="ALPHA_TEST" pos="22" type="boolean"/>
+		<bitfield name="ALPHA_TEST_FUNC" low="24" high="26" type="adreno_compare_func"/>
+		<bitfield name="ALPHA_TO_COVERAGE" pos="30" type="boolean"/>
+		<bitfield name="ALPHA_TO_ONE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x20c2" name="RB_MSAA_CONTROL">
+		<bitfield name="DISABLE" pos="10" type="boolean"/>
+		<bitfield name="SAMPLES" low="12" high="15" type="a3xx_msaa_samples"/>
+		<bitfield name="SAMPLE_MASK" low="16" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="0x20c3" name="RB_ALPHA_REF">
+		<bitfield name="UINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<array offset="0x20c4" name="RB_MRT" stride="4" length="4">
+		<reg32 offset="0x0" name="CONTROL">
+			<bitfield name="READ_DEST_ENABLE" pos="3" type="boolean"/>
+			<!-- both these bits seem to get set when enabling GL_BLEND.. -->
+			<bitfield name="BLEND" pos="4" type="boolean"/>
+			<bitfield name="BLEND2" pos="5" type="boolean"/>
+			<bitfield name="ROP_CODE" low="8" high="11" type="a3xx_rop_code"/>
+			<bitfield name="DITHER_MODE" low="12" high="13" type="adreno_rb_dither_mode"/>
+			<bitfield name="COMPONENT_ENABLE" low="24" high="27" type="hex"/>
+		</reg32>
+		<reg32 offset="0x1" name="BUF_INFO">
+			<bitfield name="COLOR_FORMAT" low="0" high="5" type="a3xx_color_fmt"/>
+			<bitfield name="COLOR_TILE_MODE" low="6" high="7" type="a3xx_tile_mode"/>
+			<bitfield name="COLOR_SWAP" low="10" high="11" type="a3xx_color_swap"/>
+			<bitfield name="COLOR_SRGB" pos="14" type="boolean"/>
+			<doc>
+				Pitch (actually, appears to be pitch in bytes, so really is a stride)
+				in GMEM, so pitch of the current tile.
+			</doc>
+			<bitfield name="COLOR_BUF_PITCH" low="17" high="31" shr="5" type="uint"/>
+		</reg32>
+		<reg32 offset="0x2" name="BUF_BASE">
+			<doc>offset into GMEM (or system memory address in bypass mode)</doc>
+			<bitfield name="COLOR_BUF_BASE" low="4" high="31" shr="5" type="hex"/>
+		</reg32>
+		<reg32 offset="0x3" name="BLEND_CONTROL">
+			<bitfield name="RGB_SRC_FACTOR" low="0" high="4" type="adreno_rb_blend_factor"/>
+			<bitfield name="RGB_BLEND_OPCODE" low="5" high="7" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="RGB_DEST_FACTOR" low="8" high="12" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_SRC_FACTOR" low="16" high="20" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_BLEND_OPCODE" low="21" high="23" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="ALPHA_DEST_FACTOR" low="24" high="28" type="adreno_rb_blend_factor"/>
+			<bitfield name="CLAMP_ENABLE" pos="29" type="boolean"/>
+		</reg32>
+	</array>
+
+	<reg32 offset="0x20e4" name="RB_BLEND_RED">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0x20e5" name="RB_BLEND_GREEN">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0x20e6" name="RB_BLEND_BLUE">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0x20e7" name="RB_BLEND_ALPHA">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+
+	<reg32 offset="0x20e8" name="RB_CLEAR_COLOR_DW0"/>
+	<reg32 offset="0x20e9" name="RB_CLEAR_COLOR_DW1"/>
+	<reg32 offset="0x20ea" name="RB_CLEAR_COLOR_DW2"/>
+	<reg32 offset="0x20eb" name="RB_CLEAR_COLOR_DW3"/>
+	<reg32 offset="0x20ec" name="RB_COPY_CONTROL">
+		<!-- not sure # of bits -->
+		<bitfield name="MSAA_RESOLVE" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="DEPTHCLEAR" pos="3" type="boolean"/>
+		<bitfield name="MODE" low="4" high="6" type="adreno_rb_copy_control_mode"/>
+		<bitfield name="MSAA_SRGB_DOWNSAMPLE" pos="7" type="boolean"/>
+		<bitfield name="FASTCLEAR" low="8" high="11" type="hex"/>
+		<bitfield name="DEPTH32_RESOLVE" pos="12" type="boolean"/> <!-- enabled on a Z32F copy -->
+		<bitfield name="GMEM_BASE" low="14" high="31" shr="14" type="hex"/>
+	</reg32>
+	<reg32 offset="0x20ed" name="RB_COPY_DEST_BASE">
+		<bitfield name="BASE" low="4" high="31" shr="5" type="hex"/>
+	</reg32>
+	<reg32 offset="0x20ee" name="RB_COPY_DEST_PITCH">
+		<doc>actually, appears to be pitch in bytes, so really is a stride</doc>
+		<!-- not actually sure about max pitch... -->
+		<bitfield name="PITCH" low="0" high="31" shr="5" type="uint"/>
+	</reg32>
+	<reg32 offset="0x20ef" name="RB_COPY_DEST_INFO">
+		<bitfield name="TILE" low="0" high="1" type="a3xx_tile_mode"/>
+		<bitfield name="FORMAT" low="2" high="7" type="a3xx_color_fmt"/>
+		<bitfield name="SWAP" low="8" high="9" type="a3xx_color_swap"/>
+		<bitfield name="DITHER_MODE" low="10" high="11" type="adreno_rb_dither_mode"/>
+		<bitfield name="COMPONENT_ENABLE" low="14" high="17" type="hex"/>
+		<bitfield name="ENDIAN" low="18" high="20" type="adreno_rb_surface_endian"/>
+	</reg32>
+	<reg32 offset="0x2100" name="RB_DEPTH_CONTROL">
+		<!--
+			guessing that this matches a2xx with the stencil fields
+			moved out into RB_STENCIL_CONTROL?
+		 -->
+		<bitfield name="FRAG_WRITES_Z" pos="0" type="boolean"/>
+		<bitfield name="Z_TEST_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="Z_WRITE_ENABLE" pos="2" type="boolean"/>
+		<bitfield name="EARLY_Z_DISABLE" pos="3" type="boolean"/>
+		<bitfield name="ZFUNC" low="4" high="6" type="adreno_compare_func"/>
+		<bitfield name="Z_CLAMP_ENABLE" pos="7" type="boolean"/>
+		<doc>Z_READ_ENABLE bit is set for zfunc other than GL_ALWAYS or GL_NEVER</doc>
+		<bitfield name="Z_READ_ENABLE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2101" name="RB_DEPTH_CLEAR">
+		<doc>seems to be always set to 0x00000000</doc>
+	</reg32>
+	<reg32 offset="0x2102" name="RB_DEPTH_INFO">
+		<bitfield name="DEPTH_FORMAT" low="0" high="1" type="adreno_rb_depth_format"/>
+		<doc>
+			DEPTH_BASE is offset in GMEM to depth/stencil buffer, ie
+			bin_w * bin_h / 1024 (possible rounded up to multiple of
+			something??  ie. 39 becomes 40, 78 becomes 80.. 75 becomes
+			80.. so maybe it needs to be multiple of 8??
+		</doc>
+		<bitfield name="DEPTH_BASE" low="11" high="31" shr="12" type="hex"/>
+	</reg32>
+	<reg32 offset="0x2103" name="RB_DEPTH_PITCH" shr="3" type="uint">
+		<doc>
+			Pitch of depth buffer or combined depth+stencil buffer
+			in z24s8 cases.
+		</doc>
+	</reg32>
+	<reg32 offset="0x2104" name="RB_STENCIL_CONTROL">
+		<bitfield name="STENCIL_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="STENCIL_ENABLE_BF" pos="1" type="boolean"/>
+		<!--
+			set for stencil operations that require read from stencil
+			buffer, but not for example for stencil clear (which does
+			not require read).. so guessing this is analogous to
+			READ_DEST_ENABLE for color buffer..
+		 -->
+		<bitfield name="STENCIL_READ" pos="2" type="boolean"/>
+		<bitfield name="FUNC" low="8" high="10" type="adreno_compare_func"/>
+		<bitfield name="FAIL" low="11" high="13" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS" low="14" high="16" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL" low="17" high="19" type="adreno_stencil_op"/>
+		<bitfield name="FUNC_BF" low="20" high="22" type="adreno_compare_func"/>
+		<bitfield name="FAIL_BF" low="23" high="25" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS_BF" low="26" high="28" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL_BF" low="29" high="31" type="adreno_stencil_op"/>
+	</reg32>
+	<reg32 offset="0x2105" name="RB_STENCIL_CLEAR">
+		<doc>seems to be always set to 0x00000000</doc>
+	</reg32>
+	<reg32 offset="0x2106" name="RB_STENCIL_INFO">
+		<doc>Base address for stencil when not using interleaved depth/stencil</doc>
+		<bitfield name="STENCIL_BASE" low="11" high="31" shr="12" type="hex"/>
+	</reg32>
+	<reg32 offset="0x2107" name="RB_STENCIL_PITCH" shr="3" type="uint">
+		<doc>pitch of stencil buffer when not using interleaved depth/stencil</doc>
+	</reg32>
+	<reg32 offset="0x2108" name="RB_STENCILREFMASK" type="adreno_rb_stencilrefmask"/>
+	<reg32 offset="0x2109" name="RB_STENCILREFMASK_BF" type="adreno_rb_stencilrefmask"/>
+	<!-- VSC == visibility stream c?? -->
+	<reg32 offset="0x210c" name="RB_LRZ_VSC_CONTROL">
+		<doc>seems to be set to 0x00000002 during binning pass</doc>
+		<bitfield name="BINNING_ENABLE" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x210e" name="RB_WINDOW_OFFSET">
+		<doc>X/Y offset of current bin</doc>
+		<bitfield name="X" low="0" high="15" type="uint"/>
+		<bitfield name="Y" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2110" name="RB_SAMPLE_COUNT_CONTROL">
+		<bitfield name="RESET" pos="0" type="boolean"/>
+		<bitfield name="COPY" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2111" name="RB_SAMPLE_COUNT_ADDR"/>
+	<reg32 offset="0x2114" name="RB_Z_CLAMP_MIN"/>
+	<reg32 offset="0x2115" name="RB_Z_CLAMP_MAX"/>
+
+	<!-- PC registers -->
+	<reg32 offset="0x21e1" name="VGT_BIN_BASE">
+		<doc>
+			seems to be where firmware writes BIN_DATA_ADDR from
+			CP_SET_BIN_DATA packet..  probably should be called
+			PC_BIN_BASE (just using name from yamato for now)
+		</doc>
+	</reg32>
+	<reg32 offset="0x21e2" name="VGT_BIN_SIZE">
+		<doc>probably should be PC_BIN_SIZE</doc>
+	</reg32>
+	<reg32 offset="0x21e4" name="PC_VSTREAM_CONTROL">
+		<doc>SIZE is current pipe width * height (in tiles)</doc>
+		<bitfield name="SIZE" low="16" high="21" type="uint"/>
+		<doc>
+			N is some sort of slot # between 0..(SIZE-1).  In case
+			multiple tiles use same pipe, each tile gets unique slot #
+		</doc>
+		<bitfield name="N" low="22" high="26" type="uint"/>
+	</reg32>
+	<reg32 offset="0x21ea" name="PC_VERTEX_REUSE_BLOCK_CNTL"/>
+	<reg32 offset="0x21ec" name="PC_PRIM_VTX_CNTL">
+		<doc>
+			STRIDE_IN_VPC: ALIGN(next_outloc - 8, 4) / 4
+			(but, in cases where you'd expect 1, the blob driver uses
+			2, so possibly 0 (no varying) or minimum of 2)
+		</doc>
+		<bitfield name="STRIDE_IN_VPC" low="0" high="4" type="uint"/>
+		<bitfield name="POLYMODE_FRONT_PTYPE" low="5" high="7" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="POLYMODE_BACK_PTYPE" low="8" high="10" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="POLYMODE_ENABLE" pos="12" type="boolean"/>
+		<bitfield name="PRIMITIVE_RESTART" pos="20" type="boolean"/>
+		<bitfield name="PROVOKING_VTX_LAST" pos="25" type="boolean"/>
+		<!-- PSIZE bit set if gl_PointSize written: -->
+		<bitfield name="PSIZE" pos="26" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x21ed" name="PC_RESTART_INDEX"/>
+
+	<!-- HLSQ registers -->
+	<bitset name="a3xx_hlsq_vs_fs_control_reg" inline="yes">
+		<bitfield name="CONSTLENGTH" low="0" high="9" type="uint"/>
+		<bitfield name="CONSTSTARTOFFSET" low="12" high="20" type="uint"/>
+		<bitfield name="INSTRLENGTH" low="24" high="31" type="uint"/>
+	</bitset>
+	<bitset name="a3xx_hlsq_const_vs_fs_presv_range_reg" inline="yes">
+		<!-- are these a3xx_regid?? -->
+		<bitfield name="STARTENTRY" low="0" high="8"/>
+		<bitfield name="ENDENTRY" low="16" high="24"/>
+	</bitset>
+
+	<reg32 offset="0x2200" name="HLSQ_CONTROL_0_REG">
+		<bitfield name="FSTHREADSIZE" low="4" high="5" type="a3xx_threadsize"/>
+		<bitfield name="FSSUPERTHREADENABLE" pos="6" type="boolean"/>
+		<bitfield name="COMPUTEMODE" pos="8" type="boolean"/>
+		<bitfield name="SPSHADERRESTART" pos="9" type="boolean"/>
+		<bitfield name="RESERVED2" pos="10" type="boolean"/>
+		<bitfield name="CYCLETIMEOUTLIMITVPC" low="12" high="23" type="uint"/>
+		<bitfield name="FSONLYTEX" pos="25" type="boolean"/>
+		<bitfield name="CHUNKDISABLE" pos="26" type="boolean"/>
+		<bitfield name="CONSTMODE" pos="27" type="uint"/>
+		<bitfield name="LAZYUPDATEDISABLE" pos="28" type="boolean"/>
+		<bitfield name="SPCONSTFULLUPDATE" pos="29" type="boolean"/>
+		<bitfield name="TPFULLUPDATE" pos="30" type="boolean"/>
+		<bitfield name="SINGLECONTEXT" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2201" name="HLSQ_CONTROL_1_REG">
+		<bitfield name="VSTHREADSIZE" low="6" high="7" type="a3xx_threadsize"/>
+		<bitfield name="VSSUPERTHREADENABLE" pos="8" type="boolean"/>
+		<bitfield name="FRAGCOORDXYREGID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="FRAGCOORDZWREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x2202" name="HLSQ_CONTROL_2_REG">
+		<bitfield name="FACENESSREGID" low="2" high="9" type="a3xx_regid"/>
+		<bitfield name="COVVALUEREGID" low="18" high="25" type="a3xx_regid"/>
+		<bitfield name="PRIMALLOCTHRESHOLD" low="26" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2203" name="HLSQ_CONTROL_3_REG">
+		<bitfield name="IJPERSPCENTERREGID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="IJNONPERSPCENTERREGID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="IJPERSPCENTROIDREGID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="IJNONPERSPCENTROIDREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x2204" name="HLSQ_VS_CONTROL_REG" type="a3xx_hlsq_vs_fs_control_reg"/>
+	<reg32 offset="0x2205" name="HLSQ_FS_CONTROL_REG" type="a3xx_hlsq_vs_fs_control_reg"/>
+	<reg32 offset="0x2206" name="HLSQ_CONST_VSPRESV_RANGE_REG" type="a3xx_hlsq_const_vs_fs_presv_range_reg"/>
+	<reg32 offset="0x2207" name="HLSQ_CONST_FSPRESV_RANGE_REG" type="a3xx_hlsq_const_vs_fs_presv_range_reg"/>
+	<reg32 offset="0x220a" name="HLSQ_CL_NDRANGE_0_REG">
+		<bitfield name="WORKDIM" low="0" high="1" type="uint"/>
+		<bitfield name="LOCALSIZE0" low="2" high="11" type="uint"/>
+		<bitfield name="LOCALSIZE1" low="12" high="21" type="uint"/>
+		<bitfield name="LOCALSIZE2" low="22" high="31" type="uint"/>
+	</reg32>
+	<array offset="0x220b" name="HLSQ_CL_GLOBAL_WORK" stride="2" length="3">
+		<doc>indexed by dimension</doc>
+		<reg32 offset="0" name="SIZE" type="uint"/>
+		<reg32 offset="1" name="OFFSET" type="uint"/>
+	</array>
+	<reg32 offset="0x2211" name="HLSQ_CL_CONTROL_0_REG"/>
+	<reg32 offset="0x2212" name="HLSQ_CL_CONTROL_1_REG"/>
+	<reg32 offset="0x2214" name="HLSQ_CL_KERNEL_CONST_REG"/>
+	<array offset="0x2215" name="HLSQ_CL_KERNEL_GROUP" stride="1" length="3">
+		<doc>indexed by dimension, global_size / local_size</doc>
+		<reg32 offset="0" name="RATIO" type="uint"/>
+	</array>
+	<reg32 offset="0x2216" name="HLSQ_CL_KERNEL_GROUP_Y_REG" type="uint"/>
+	<reg32 offset="0x2217" name="HLSQ_CL_KERNEL_GROUP_Z_REG" type="uint"/>
+	<reg32 offset="0x221a" name="HLSQ_CL_WG_OFFSET_REG"/>
+
+	<!-- VFD registers -->
+	<reg32 offset="0x2240" name="VFD_CONTROL_0">
+		<doc>
+			TOTALATTRTOVS is # of attributes to vertex shader, in register
+			slots (ie. vec4+vec3 -> 7)
+		</doc>
+		<bitfield name="TOTALATTRTOVS" low="0" high="17" type="uint"/>
+		<bitfield name="PACKETSIZE" low="18" high="21" type="uint"/>
+		<doc>STRMDECINSTRCNT is # of VFD_DECODE_INSTR registers valid</doc>
+		<bitfield name="STRMDECINSTRCNT" low="22" high="26" type="uint"/>
+		<doc>STRMFETCHINSTRCNT is # of VFD_FETCH_INSTR registers valid</doc>
+		<bitfield name="STRMFETCHINSTRCNT" low="27" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2241" name="VFD_CONTROL_1">
+		<doc>MAXSTORAGE could be # of attributes/vbo's</doc>
+		<bitfield name="MAXSTORAGE" low="0" high="3" type="uint"/>
+		<bitfield name="MAXTHRESHOLD" low="4" high="7" type="uint"/>
+		<bitfield name="MINTHRESHOLD" low="8" high="11" type="uint"/>
+		<bitfield name="REGID4VTX" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="REGID4INST" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x2242" name="VFD_INDEX_MIN" type="uint"/>
+	<reg32 offset="0x2243" name="VFD_INDEX_MAX" type="uint"/>
+	<reg32 offset="0x2244" name="VFD_INSTANCEID_OFFSET" type="uint"/>
+	<reg32 offset="0x2245" name="VFD_INDEX_OFFSET" type="uint"/>
+	<array offset="0x2246" name="VFD_FETCH" stride="2" length="16">
+		<reg32 offset="0x0" name="INSTR_0">
+			<bitfield name="FETCHSIZE" low="0" high="6" type="uint"/>
+			<bitfield name="BUFSTRIDE" low="7" high="15" type="uint"/>
+			<bitfield name="INSTANCED" pos="16" type="boolean"/>
+			<bitfield name="SWITCHNEXT" pos="17" type="boolean"/>
+			<bitfield name="INDEXCODE" low="18" high="23" type="uint"/>
+			<bitfield name="STEPRATE" low="24" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x1" name="INSTR_1"/>
+	</array>
+	<array offset="0x2266" name="VFD_DECODE" stride="1" length="16">
+		<reg32 offset="0x0" name="INSTR">
+			<bitfield name="WRITEMASK" low="0" high="3" type="hex"/>
+			<!-- not sure if this is a bit flag and another flag above it, or?? -->
+			<bitfield name="CONSTFILL" pos="4" type="boolean"/>
+			<bitfield name="FORMAT" low="6" high="11" type="a3xx_vtx_fmt"/>
+			<bitfield name="REGID" low="12" high="19" type="a3xx_regid"/>
+			<bitfield name="INT" pos="20" type="boolean"/>
+			<doc>SHIFTCNT appears to be size, ie. FLOAT_32_32_32 is 12, and BYTE_8 is 1</doc>
+			<bitfield name="SWAP" low="22" high="23" type="a3xx_color_swap"/>
+			<bitfield name="SHIFTCNT" low="24" high="28" type="uint"/>
+			<bitfield name="LASTCOMPVALID" pos="29" type="boolean"/>
+			<bitfield name="SWITCHNEXT" pos="30" type="boolean"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x227e" name="VFD_VS_THREADING_THRESHOLD">
+		<bitfield name="REGID_THRESHOLD" low="0" high="3" type="uint"/>
+		<!-- <bitfield name="RESERVED6" low="4" high="7" type="uint"/> -->
+		<bitfield name="REGID_VTXCNT" low="8" high="15" type="a3xx_regid"/>
+	</reg32>
+
+	<!-- VPC registers -->
+	<reg32 offset="0x2280" name="VPC_ATTR">
+		<bitfield name="TOTALATTR" low="0" high="8" type="uint"/>
+		<!-- PSIZE bit set if gl_PointSize written: -->
+		<bitfield name="PSIZE" pos="9" type="boolean"/>
+		<bitfield name="THRDASSIGN" low="12" high="27" type="uint"/>
+		<bitfield name="LMSIZE" low="28" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2281" name="VPC_PACK">
+		<!-- these are always seem to be set to same as TOTALATTR -->
+		<bitfield name="NUMFPNONPOSVAR" low="8" high="15" type="uint"/>
+		<bitfield name="NUMNONPOSVSVAR" low="16" high="23" type="uint"/>
+	</reg32>
+	<!--
+		varying interpolate mode.  One field per scalar/component
+		(since varying slots are scalar, so things don't have to
+		be aligned to vec4).
+		4 regs * 16 scalar components each => 16 vec4
+	 -->
+	<array offset="0x2282" name="VPC_VARYING_INTERP" stride="1" length="4">
+		<reg32 offset="0x0" name="MODE">
+			<bitfield name="C0" low="0"  high="1"  type="a3xx_intp_mode"/>
+			<bitfield name="C1" low="2"  high="3"  type="a3xx_intp_mode"/>
+			<bitfield name="C2" low="4"  high="5"  type="a3xx_intp_mode"/>
+			<bitfield name="C3" low="6"  high="7"  type="a3xx_intp_mode"/>
+			<bitfield name="C4" low="8"  high="9"  type="a3xx_intp_mode"/>
+			<bitfield name="C5" low="10" high="11" type="a3xx_intp_mode"/>
+			<bitfield name="C6" low="12" high="13" type="a3xx_intp_mode"/>
+			<bitfield name="C7" low="14" high="15" type="a3xx_intp_mode"/>
+			<bitfield name="C8" low="16" high="17" type="a3xx_intp_mode"/>
+			<bitfield name="C9" low="18" high="19" type="a3xx_intp_mode"/>
+			<bitfield name="CA" low="20" high="21" type="a3xx_intp_mode"/>
+			<bitfield name="CB" low="22" high="23" type="a3xx_intp_mode"/>
+			<bitfield name="CC" low="24" high="25" type="a3xx_intp_mode"/>
+			<bitfield name="CD" low="26" high="27" type="a3xx_intp_mode"/>
+			<bitfield name="CE" low="28" high="29" type="a3xx_intp_mode"/>
+			<bitfield name="CF" low="30" high="31" type="a3xx_intp_mode"/>
+		</reg32>
+	</array>
+	<array offset="0x2286" name="VPC_VARYING_PS_REPL" stride="1" length="4">
+		<reg32 offset="0x0" name="MODE">
+			<bitfield name="C0" low="0"  high="1"  type="a3xx_repl_mode"/>
+			<bitfield name="C1" low="2"  high="3"  type="a3xx_repl_mode"/>
+			<bitfield name="C2" low="4"  high="5"  type="a3xx_repl_mode"/>
+			<bitfield name="C3" low="6"  high="7"  type="a3xx_repl_mode"/>
+			<bitfield name="C4" low="8"  high="9"  type="a3xx_repl_mode"/>
+			<bitfield name="C5" low="10" high="11" type="a3xx_repl_mode"/>
+			<bitfield name="C6" low="12" high="13" type="a3xx_repl_mode"/>
+			<bitfield name="C7" low="14" high="15" type="a3xx_repl_mode"/>
+			<bitfield name="C8" low="16" high="17" type="a3xx_repl_mode"/>
+			<bitfield name="C9" low="18" high="19" type="a3xx_repl_mode"/>
+			<bitfield name="CA" low="20" high="21" type="a3xx_repl_mode"/>
+			<bitfield name="CB" low="22" high="23" type="a3xx_repl_mode"/>
+			<bitfield name="CC" low="24" high="25" type="a3xx_repl_mode"/>
+			<bitfield name="CD" low="26" high="27" type="a3xx_repl_mode"/>
+			<bitfield name="CE" low="28" high="29" type="a3xx_repl_mode"/>
+			<bitfield name="CF" low="30" high="31" type="a3xx_repl_mode"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x228a" name="VPC_VARY_CYLWRAP_ENABLE_0"/>
+	<reg32 offset="0x228b" name="VPC_VARY_CYLWRAP_ENABLE_1"/>
+
+	<!-- SP registers -->
+	<bitset name="a3xx_vs_fs_length_reg" inline="yes">
+		<bitfield name="SHADERLENGTH" low="0" high="31" type="uint"/>
+	</bitset>
+
+	<bitset name="sp_vs_fs_obj_offset_reg" inline="yes">
+		<bitfield name="FIRSTEXECINSTROFFSET" low="0" high="15" type="uint"/>
+		<doc>
+			From register spec:
+			SP_FS_OBJ_OFFSET_REG.CONSTOBJECTSTARTOFFSET [16:24]: Constant object
+			start offset in on chip RAM,
+			128bit aligned
+		</doc>
+		<bitfield name="CONSTOBJECTOFFSET" low="16" high="24" type="uint"/>
+		<bitfield name="SHADEROBJOFFSET" low="25" high="31" type="uint"/>
+	</bitset>
+
+	<reg32 offset="0x22c0" name="SP_SP_CTRL_REG">
+		<!-- this bit is set during resolve pass: -->
+		<bitfield name="RESOLVE" pos="16" type="boolean"/>
+		<bitfield name="CONSTMODE" pos="18" type="uint"/>
+		<bitfield name="BINNING" pos="19" type="boolean"/>
+		<bitfield name="SLEEPMODE" low="20" high="21" type="uint"/>
+		<!-- L0MODE==1 when oxiliForceSpL0ModeBuffer=1 -->
+		<bitfield name="L0MODE" low="22" high="23" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22c4" name="SP_VS_CTRL_REG0">
+		<bitfield name="THREADMODE" pos="0" type="a3xx_threadmode"/>
+		<bitfield name="INSTRBUFFERMODE" pos="1" type="a3xx_instrbuffermode"/>
+		<!-- maybe CACHEINVALID is two bits?? -->
+		<bitfield name="CACHEINVALID" pos="2" type="boolean"/>
+		<bitfield name="ALUSCHMODE" pos="3" type="boolean"/>
+		<doc>
+			The full/half register footprint is in units of four components,
+			so if r0.x is used, that counts as all of r0.[xyzw] as used.
+			There are separate full/half register footprint values as the
+			full and half registers are independent (not overlapping).
+			Presumably the thread scheduler hardware allocates the full/half
+			register names from the actual physical register file and
+			handles the register renaming.
+		</doc>
+		<bitfield name="HALFREGFOOTPRINT" low="4" high="9" type="uint"/>
+		<bitfield name="FULLREGFOOTPRINT" low="10" high="15" type="uint"/>
+		<bitfield name="THREADSIZE" pos="20" type="a3xx_threadsize"/>
+		<bitfield name="SUPERTHREADMODE" pos="21" type="boolean"/>
+		<doc>
+			From regspec:
+			SP_FS_CTRL_REG0.FS_LENGTH [31:24]: FS length, unit = 256bits.
+			If bit31 is 1, it means overflow
+			or any long shader.
+		</doc>
+		<bitfield name="LENGTH" low="24" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22c5" name="SP_VS_CTRL_REG1">
+		<bitfield name="CONSTLENGTH" low="0" high="9" type="uint"/>
+		<!--
+			not sure about full vs half const.. I can't get blob generate
+			something with a mediump/lowp uniform.
+		 -->
+		<bitfield name="CONSTFOOTPRINT" low="10" high="19" type="uint"/>
+		<bitfield name="INITIALOUTSTANDING" low="24" high="30" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22c6" name="SP_VS_PARAM_REG">
+		<bitfield name="POSREGID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="PSIZEREGID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="POS2DMODE" pos="16" type="boolean"/>
+		<bitfield name="TOTALVSOUTVAR" low="20" high="24" type="uint"/>
+	</reg32>
+	<array offset="0x22c7" name="SP_VS_OUT" stride="1" length="8">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="A_HALF" pos="8" type="boolean"/>
+			<bitfield name="A_COMPMASK" low="9" high="12" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="23" type="a3xx_regid"/>
+			<bitfield name="B_HALF" pos="24" type="boolean"/>
+			<bitfield name="B_COMPMASK" low="25" high="28" type="hex"/>
+		</reg32>
+	</array>
+	<array offset="0x22d0" name="SP_VS_VPC_DST" stride="1" length="4">
+		<reg32 offset="0x0" name="REG">
+			<doc>
+				These seem to be offsets for storage of the varyings.
+				Always seems to start from 8, possibly loc 0 and 4
+				are for gl_Position and gl_PointSize?
+			</doc>
+			<bitfield name="OUTLOC0" low="0" high="6" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="14" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="22" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="30" type="uint"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x22d4" name="SP_VS_OBJ_OFFSET_REG" type="sp_vs_fs_obj_offset_reg"/>
+	<doc>
+		SP_VS_OBJ_START_REG contains pointer to the vertex shader program,
+		immediately followed by the binning shader program (although I
+		guess that is probably just re-using the same gpu buffer)
+	</doc>
+	<reg32 offset="0x22d5" name="SP_VS_OBJ_START_REG"/>
+	<reg32 offset="0x22d6" name="SP_VS_PVT_MEM_PARAM_REG">
+		<bitfield name="MEMSIZEPERITEM" low="0" high="7" shr="7">
+			<doc>The size of memory that ldp/stp can address, in 128 byte increments.</doc>
+		</bitfield>
+		<bitfield name="HWSTACKOFFSET" low="8" high="23" type="uint"/>
+		<bitfield name="HWSTACKSIZEPERTHREAD" low="24" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22d7" name="SP_VS_PVT_MEM_ADDR_REG">
+		<bitfield name="BURSTLEN" low="0" high="4"/>
+		<bitfield name="SHADERSTARTADDRESS" shr="5" low="5" high="31"/>
+	</reg32>
+	<reg32 offset="0x22d8" name="SP_VS_PVT_MEM_SIZE_REG"/>
+	<reg32 offset="0x22df" name="SP_VS_LENGTH_REG" type="a3xx_vs_fs_length_reg"/>
+	<reg32 offset="0x22e0" name="SP_FS_CTRL_REG0">
+		<bitfield name="THREADMODE" pos="0" type="a3xx_threadmode"/>
+		<bitfield name="INSTRBUFFERMODE" pos="1" type="a3xx_instrbuffermode"/>
+		<!-- maybe CACHEINVALID is two bits?? -->
+		<bitfield name="CACHEINVALID" pos="2" type="boolean"/>
+		<bitfield name="ALUSCHMODE" pos="3" type="boolean"/>
+		<doc>
+			The full/half register footprint is in units of four components,
+			so if r0.x is used, that counts as all of r0.[xyzw] as used.
+			There are separate full/half register footprint values as the
+			full and half registers are independent (not overlapping).
+			Presumably the thread scheduler hardware allocates the full/half
+			register names from the actual physical register file and
+			handles the register renaming.
+		</doc>
+		<bitfield name="HALFREGFOOTPRINT" low="4" high="9" type="uint"/>
+		<bitfield name="FULLREGFOOTPRINT" low="10" high="15" type="uint"/>
+		<bitfield name="FSBYPASSENABLE" pos="17" type="boolean"/>
+		<bitfield name="INOUTREGOVERLAP" pos="18" type="boolean"/>
+		<bitfield name="OUTORDERED" pos="19" type="boolean"/>
+		<bitfield name="THREADSIZE" pos="20" type="a3xx_threadsize"/>
+		<bitfield name="SUPERTHREADMODE" pos="21" type="boolean"/>
+		<bitfield name="PIXLODENABLE" pos="22" type="boolean"/>
+		<bitfield name="COMPUTEMODE" pos="23" type="boolean"/>
+		<doc>
+			From regspec:
+			SP_FS_CTRL_REG0.FS_LENGTH [31:24]: FS length, unit = 256bits.
+			If bit31 is 1, it means overflow
+			or any long shader.
+		</doc>
+		<bitfield name="LENGTH" low="24" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22e1" name="SP_FS_CTRL_REG1">
+		<bitfield name="CONSTLENGTH" low="0" high="9" type="uint"/>
+		<bitfield name="CONSTFOOTPRINT" low="10" high="19" type="uint"/>
+		<bitfield name="INITIALOUTSTANDING" low="20" high="23" type="uint"/>
+		<bitfield name="HALFPRECVAROFFSET" low="24" high="30" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22e2" name="SP_FS_OBJ_OFFSET_REG" type="sp_vs_fs_obj_offset_reg"/>
+	<doc>SP_FS_OBJ_START_REG contains pointer to fragment shader program</doc>
+	<reg32 offset="0x22e3" name="SP_FS_OBJ_START_REG"/>
+	<reg32 offset="0x22e4" name="SP_FS_PVT_MEM_PARAM_REG">
+		<bitfield name="MEMSIZEPERITEM" low="0" high="7" type="uint"/>
+		<bitfield name="HWSTACKOFFSET" low="8" high="23" type="uint"/>
+		<bitfield name="HWSTACKSIZEPERTHREAD" low="24" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22e5" name="SP_FS_PVT_MEM_ADDR_REG">
+		<bitfield name="BURSTLEN" low="0" high="4"/>
+		<bitfield name="SHADERSTARTADDRESS" shr="5" low="5" high="31"/>
+	</reg32>
+	<reg32 offset="0x22e6" name="SP_FS_PVT_MEM_SIZE_REG"/>
+	<reg32 offset="0x22e8" name="SP_FS_FLAT_SHAD_MODE_REG_0">
+		<doc>seems to be one bit per scalar, '1' for flat, '0' for smooth</doc>
+	</reg32>
+	<reg32 offset="0x22e9" name="SP_FS_FLAT_SHAD_MODE_REG_1">
+		<doc>seems to be one bit per scalar, '1' for flat, '0' for smooth</doc>
+	</reg32>
+	<reg32 offset="0x22ec" name="SP_FS_OUTPUT_REG">
+		<bitfield name="MRT" low="0" high="1" type="uint">
+			<doc>render targets - 1</doc>
+		</bitfield>
+		<bitfield name="DEPTH_ENABLE" pos="7" type="boolean"/>
+		<bitfield name="DEPTH_REGID" low="8" high="15" type="a3xx_regid"/>
+	</reg32>
+	<array offset="0x22f0" name="SP_FS_MRT" stride="1" length="4">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="HALF_PRECISION" pos="8" type="boolean"/>
+			<bitfield name="SINT" pos="10" type="boolean"/>
+			<bitfield name="UINT" pos="11" type="boolean"/>
+		</reg32>
+	</array>
+	<array offset="0x22f4" name="SP_FS_IMAGE_OUTPUT" stride="1" length="4">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="MRTFORMAT" low="0" high="5" type="a3xx_color_fmt"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x22ff" name="SP_FS_LENGTH_REG" type="a3xx_vs_fs_length_reg"/>
+
+	<reg32 offset="0x2301" name="PA_SC_AA_CONFIG"/>
+	<!-- TPL1 registers -->
+	<!-- assume VS/FS_TEX_OFFSET is same -->
+	<bitset name="a3xx_tpl1_tp_vs_fs_tex_offset" inline="yes">
+		<bitfield name="SAMPLEROFFSET" low="0" high="7" type="uint"/>
+		<bitfield name="MEMOBJOFFSET" low="8" high="15" type="uint"/>
+		<!-- not sure the size of this: -->
+		<bitfield name="BASETABLEPTR" low="16" high="31" type="uint"/>
+	</bitset>
+	<reg32 offset="0x2340" name="TPL1_TP_VS_TEX_OFFSET" type="a3xx_tpl1_tp_vs_fs_tex_offset"/>
+	<reg32 offset="0x2341" name="TPL1_TP_VS_BORDER_COLOR_BASE_ADDR"/>
+	<reg32 offset="0x2342" name="TPL1_TP_FS_TEX_OFFSET" type="a3xx_tpl1_tp_vs_fs_tex_offset"/>
+	<reg32 offset="0x2343" name="TPL1_TP_FS_BORDER_COLOR_BASE_ADDR"/>
+
+	<!-- VBIF registers -->
+	<reg32 offset="0x3001" name="VBIF_CLKON"/>
+	<reg32 offset="0x300c" name="VBIF_FIXED_SORT_EN"/>
+	<reg32 offset="0x300d" name="VBIF_FIXED_SORT_SEL0"/>
+	<reg32 offset="0x300e" name="VBIF_FIXED_SORT_SEL1"/>
+	<reg32 offset="0x301c" name="VBIF_ABIT_SORT"/>
+	<reg32 offset="0x301d" name="VBIF_ABIT_SORT_CONF"/>
+	<reg32 offset="0x302a" name="VBIF_GATE_OFF_WRREQ_EN"/>
+	<reg32 offset="0x302c" name="VBIF_IN_RD_LIM_CONF0"/>
+	<reg32 offset="0x302d" name="VBIF_IN_RD_LIM_CONF1"/>
+	<reg32 offset="0x3030" name="VBIF_IN_WR_LIM_CONF0"/>
+	<reg32 offset="0x3031" name="VBIF_IN_WR_LIM_CONF1"/>
+	<reg32 offset="0x3034" name="VBIF_OUT_RD_LIM_CONF0"/>
+	<reg32 offset="0x3035" name="VBIF_OUT_WR_LIM_CONF0"/>
+	<reg32 offset="0x3036" name="VBIF_DDR_OUT_MAX_BURST"/>
+	<reg32 offset="0x303c" name="VBIF_ARB_CTL"/>
+	<reg32 offset="0x3049" name="VBIF_ROUND_ROBIN_QOS_ARB"/>
+	<reg32 offset="0x3058" name="VBIF_OUT_AXI_AMEMTYPE_CONF0"/>
+	<reg32 offset="0x305e" name="VBIF_OUT_AXI_AOOO_EN"/>
+	<reg32 offset="0x305f" name="VBIF_OUT_AXI_AOOO"/>
+
+	<bitset name="a3xx_vbif_perf_cnt" inline="yes">
+		<bitfield name="CNT0" pos="0" type="boolean"/>
+		<bitfield name="CNT1" pos="1" type="boolean"/>
+		<bitfield name="PWRCNT0" pos="2" type="boolean"/>
+		<bitfield name="PWRCNT1" pos="3" type="boolean"/>
+		<bitfield name="PWRCNT2" pos="4" type="boolean"/>
+	</bitset>
+
+	<reg32 offset="0x3070" name="VBIF_PERF_CNT_EN" type="a3xx_vbif_perf_cnt"/>
+	<reg32 offset="0x3071" name="VBIF_PERF_CNT_CLR" type="a3xx_vbif_perf_cnt"/>
+	<reg32 offset="0x3072" name="VBIF_PERF_CNT_SEL"/>
+	<reg32 offset="0x3073" name="VBIF_PERF_CNT0_LO"/>
+	<reg32 offset="0x3074" name="VBIF_PERF_CNT0_HI"/>
+	<reg32 offset="0x3075" name="VBIF_PERF_CNT1_LO"/>
+	<reg32 offset="0x3076" name="VBIF_PERF_CNT1_HI"/>
+	<reg32 offset="0x3077" name="VBIF_PERF_PWR_CNT0_LO"/>
+	<reg32 offset="0x3078" name="VBIF_PERF_PWR_CNT0_HI"/>
+	<reg32 offset="0x3079" name="VBIF_PERF_PWR_CNT1_LO"/>
+	<reg32 offset="0x307a" name="VBIF_PERF_PWR_CNT1_HI"/>
+	<reg32 offset="0x307b" name="VBIF_PERF_PWR_CNT2_LO"/>
+	<reg32 offset="0x307c" name="VBIF_PERF_PWR_CNT2_HI"/>
+
+
+	<reg32 offset="0x0c01" name="VSC_BIN_SIZE">
+		<bitfield name="WIDTH" low="0" high="4" shr="5" type="uint"/>
+		<bitfield name="HEIGHT" low="5" high="9" shr="5" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x0c02" name="VSC_SIZE_ADDRESS"/>
+	<array offset="0x0c06" name="VSC_PIPE" stride="3" length="8">
+		<reg32 offset="0x0" name="CONFIG">
+			<doc>
+				Configures the mapping between VSC_PIPE buffer and
+				bin, X/Y specify the bin index in the horiz/vert
+				direction (0,0 is upper left, 0,1 is leftmost bin
+				on second row, and so on).  W/H specify the number
+				of bins assigned to this VSC_PIPE in the horiz/vert
+				dimension.
+			</doc>
+			<bitfield name="X" low="0" high="9" type="uint"/>
+			<bitfield name="Y" low="10" high="19" type="uint"/>
+			<bitfield name="W" low="20" high="23" type="uint"/>
+			<bitfield name="H" low="24" high="27" type="uint"/>
+		</reg32>
+		<reg32 offset="0x1" name="DATA_ADDRESS"/>
+		<reg32 offset="0x2" name="DATA_LENGTH"/>
+	</array>
+	<reg32 offset="0x0c3c" name="VSC_BIN_CONTROL">
+		<doc>seems to be set to 0x00000001 during binning pass</doc>
+		<bitfield name="BINNING_ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0c3d" name="UNKNOWN_0C3D">
+		<doc>seems to be always set to 0x00000001</doc>
+	</reg32>
+	<reg32 offset="0x0c48" name="PC_PERFCOUNTER0_SELECT" type="a3xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0c49" name="PC_PERFCOUNTER1_SELECT" type="a3xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0c4a" name="PC_PERFCOUNTER2_SELECT" type="a3xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0c4b" name="PC_PERFCOUNTER3_SELECT" type="a3xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0c81" name="GRAS_TSE_DEBUG_ECO">
+		<doc>seems to be always set to 0x00000001</doc>
+	</reg32>
+
+	<reg32 offset="0x0c88" name="GRAS_PERFCOUNTER0_SELECT" type="a3xx_gras_tse_perfcounter_select"/>
+	<reg32 offset="0x0c89" name="GRAS_PERFCOUNTER1_SELECT" type="a3xx_gras_tse_perfcounter_select"/>
+	<reg32 offset="0x0c8a" name="GRAS_PERFCOUNTER2_SELECT" type="a3xx_gras_ras_perfcounter_select"/>
+	<reg32 offset="0x0c8b" name="GRAS_PERFCOUNTER3_SELECT" type="a3xx_gras_ras_perfcounter_select"/>
+	<array offset="0x0ca0" name="GRAS_CL_USER_PLANE" stride="4" length="6">
+		<reg32 offset="0x0" name="X"/>
+		<reg32 offset="0x1" name="Y"/>
+		<reg32 offset="0x2" name="Z"/>
+		<reg32 offset="0x3" name="W"/>
+	</array>
+	<reg32 offset="0x0cc0" name="RB_GMEM_BASE_ADDR"/>
+	<reg32 offset="0x0cc1" name="RB_DEBUG_ECO_CONTROLS_ADDR"/>
+	<reg32 offset="0x0cc6" name="RB_PERFCOUNTER0_SELECT" type="a3xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cc7" name="RB_PERFCOUNTER1_SELECT" type="a3xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0ce0" name="RB_FRAME_BUFFER_DIMENSION">
+		<bitfield name="WIDTH" low="0" high="13" type="uint"/>
+		<bitfield name="HEIGHT" low="14" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0e00" name="HLSQ_PERFCOUNTER0_SELECT" type="a3xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e01" name="HLSQ_PERFCOUNTER1_SELECT" type="a3xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e02" name="HLSQ_PERFCOUNTER2_SELECT" type="a3xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e03" name="HLSQ_PERFCOUNTER3_SELECT" type="a3xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e04" name="HLSQ_PERFCOUNTER4_SELECT" type="a3xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e05" name="HLSQ_PERFCOUNTER5_SELECT" type="a3xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e43" name="UNKNOWN_0E43">
+		<doc>seems to be always set to 0x00000001</doc>
+	</reg32>
+	<reg32 offset="0x0e44" name="VFD_PERFCOUNTER0_SELECT" type="a3xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e45" name="VFD_PERFCOUNTER1_SELECT" type="a3xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e61" name="VPC_VPC_DEBUG_RAM_SEL"/>
+	<reg32 offset="0x0e62" name="VPC_VPC_DEBUG_RAM_READ"/>
+	<reg32 offset="0x0e64" name="VPC_PERFCOUNTER0_SELECT" type="a3xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e65" name="VPC_PERFCOUNTER1_SELECT" type="a3xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e82" name="UCHE_CACHE_MODE_CONTROL_REG"/>
+	<reg32 offset="0x0e84" name="UCHE_PERFCOUNTER0_SELECT" type="a3xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e85" name="UCHE_PERFCOUNTER1_SELECT" type="a3xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e86" name="UCHE_PERFCOUNTER2_SELECT" type="a3xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e87" name="UCHE_PERFCOUNTER3_SELECT" type="a3xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e88" name="UCHE_PERFCOUNTER4_SELECT" type="a3xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e89" name="UCHE_PERFCOUNTER5_SELECT" type="a3xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea0" name="UCHE_CACHE_INVALIDATE0_REG">
+		<!-- might be shifted right by 5, assuming 32byte cache line size.. -->
+		<bitfield name="ADDR" low="0" high="27" type="hex"/>
+	</reg32>
+	<reg32 offset="0x0ea1" name="UCHE_CACHE_INVALIDATE1_REG">
+		<!-- might be shifted right by 5, assuming 32byte cache line size.. -->
+		<bitfield name="ADDR" low="0" high="27" type="hex"/>
+		<!-- I'd assume 2 bits, for FLUSH/INVALIDATE/CLEAN? -->
+		<bitfield name="OPCODE" low="28" high="29" type="a3xx_cache_opcode"/>
+		<bitfield name="ENTIRE_CACHE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0ea6" name="UNKNOWN_0EA6"/>
+	<reg32 offset="0x0ec4" name="SP_PERFCOUNTER0_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec5" name="SP_PERFCOUNTER1_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec6" name="SP_PERFCOUNTER2_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec7" name="SP_PERFCOUNTER3_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec8" name="SP_PERFCOUNTER4_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec9" name="SP_PERFCOUNTER5_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0eca" name="SP_PERFCOUNTER6_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ecb" name="SP_PERFCOUNTER7_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ee0" name="UNKNOWN_0EE0">
+		<doc>seems to be always set to 0x00000003</doc>
+	</reg32>
+	<reg32 offset="0x0f03" name="UNKNOWN_0F03">
+		<doc>seems to be always set to 0x00000001</doc>
+	</reg32>
+	<reg32 offset="0x0f04" name="TP_PERFCOUNTER0_SELECT" type="a3xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f05" name="TP_PERFCOUNTER1_SELECT" type="a3xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f06" name="TP_PERFCOUNTER2_SELECT" type="a3xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f07" name="TP_PERFCOUNTER3_SELECT" type="a3xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f08" name="TP_PERFCOUNTER4_SELECT" type="a3xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f09" name="TP_PERFCOUNTER5_SELECT" type="a3xx_tp_perfcounter_select"/>
+
+	<!-- this seems to be the register that CP_RUN_OPENCL writes: -->
+	<reg32 offset="0x21f0" name="VGT_CL_INITIATOR"/>
+
+	<!-- seems to be same as a2xx according to fwdump.. -->
+	<reg32 offset="0x21f9" name="VGT_EVENT_INITIATOR"/>
+	<reg32 offset="0x21fc" name="VGT_DRAW_INITIATOR" type="vgt_draw_initiator"/>
+	<reg32 offset="0x21fd" name="VGT_IMMED_DATA"/>
+</domain>
+
+<domain name="A3XX_TEX_SAMP" width="32">
+	<doc>Texture sampler dwords</doc>
+	<enum name="a3xx_tex_filter">
+		<value name="A3XX_TEX_NEAREST" value="0"/>
+		<value name="A3XX_TEX_LINEAR" value="1"/>
+		<value name="A3XX_TEX_ANISO" value="2"/>
+	</enum>
+	<enum name="a3xx_tex_clamp">
+		<value name="A3XX_TEX_REPEAT" value="0"/>
+		<value name="A3XX_TEX_CLAMP_TO_EDGE" value="1"/>
+		<value name="A3XX_TEX_MIRROR_REPEAT" value="2"/>
+		<value name="A3XX_TEX_CLAMP_TO_BORDER" value="3"/>
+		<value name="A3XX_TEX_MIRROR_CLAMP" value="4"/>
+	</enum>
+	<enum name="a3xx_tex_aniso">
+		<value name="A3XX_TEX_ANISO_1" value="0"/>
+		<value name="A3XX_TEX_ANISO_2" value="1"/>
+		<value name="A3XX_TEX_ANISO_4" value="2"/>
+		<value name="A3XX_TEX_ANISO_8" value="3"/>
+		<value name="A3XX_TEX_ANISO_16" value="4"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="CLAMPENABLE" pos="0" type="boolean"/>
+		<bitfield name="MIPFILTER_LINEAR" pos="1" type="boolean"/>
+		<bitfield name="XY_MAG" low="2" high="3" type="a3xx_tex_filter"/>
+		<bitfield name="XY_MIN" low="4" high="5" type="a3xx_tex_filter"/>
+		<bitfield name="WRAP_S" low="6" high="8" type="a3xx_tex_clamp"/>
+		<bitfield name="WRAP_T" low="9" high="11" type="a3xx_tex_clamp"/>
+		<bitfield name="WRAP_R" low="12" high="14" type="a3xx_tex_clamp"/>
+		<bitfield name="ANISO" low="15" high="17" type="a3xx_tex_aniso"/>
+		<bitfield name="COMPARE_FUNC" low="20" high="22" type="adreno_compare_func"/>
+		<bitfield name="CUBEMAPSEAMLESSFILTOFF" pos="24" type="boolean"/>
+		<!-- UNNORM_COORDS == CLK_NORMALIZED_COORDS_FALSE -->
+		<bitfield name="UNNORM_COORDS" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="LOD_BIAS" low="0" high="10" type="fixed" radix="6"/>
+		<bitfield name="MAX_LOD" low="12" high="21" type="ufixed" radix="6"/>
+		<bitfield name="MIN_LOD" low="22" high="31" type="ufixed" radix="6"/>
+	</reg32>
+</domain>
+
+<domain name="A3XX_TEX_CONST" width="32">
+	<doc>Texture constant dwords</doc>
+	<enum name="a3xx_tex_swiz">
+		<!-- same as a2xx? -->
+		<value name="A3XX_TEX_X" value="0"/>
+		<value name="A3XX_TEX_Y" value="1"/>
+		<value name="A3XX_TEX_Z" value="2"/>
+		<value name="A3XX_TEX_W" value="3"/>
+		<value name="A3XX_TEX_ZERO" value="4"/>
+		<value name="A3XX_TEX_ONE" value="5"/>
+	</enum>
+	<enum name="a3xx_tex_type">
+		<value name="A3XX_TEX_1D" value="0"/>
+		<value name="A3XX_TEX_2D" value="1"/>
+		<value name="A3XX_TEX_CUBE" value="2"/>
+		<value name="A3XX_TEX_3D" value="3"/>
+	</enum>
+	<enum name="a3xx_tex_msaa">
+		<value name="A3XX_TPL1_MSAA1X" value="0"/>
+		<value name="A3XX_TPL1_MSAA2X" value="1"/>
+		<value name="A3XX_TPL1_MSAA4X" value="2"/>
+		<value name="A3XX_TPL1_MSAA8X" value="3"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="TILE_MODE" low="0" high="1" type="a3xx_tile_mode"/>
+		<bitfield name="SRGB" pos="2" type="boolean"/>
+		<bitfield name="SWIZ_X" low="4" high="6" type="a3xx_tex_swiz"/>
+		<bitfield name="SWIZ_Y" low="7" high="9" type="a3xx_tex_swiz"/>
+		<bitfield name="SWIZ_Z" low="10" high="12" type="a3xx_tex_swiz"/>
+		<bitfield name="SWIZ_W" low="13" high="15" type="a3xx_tex_swiz"/>
+		<bitfield name="MIPLVLS" low="16" high="19" type="uint"/>
+		<bitfield name="MSAATEX" low="20" high="21" type="a3xx_tex_msaa"/>
+		<bitfield name="FMT" low="22" high="28" type="a3xx_tex_fmt"/>
+		<bitfield name="NOCONVERT" pos="29" type="boolean"/>
+		<bitfield name="TYPE" low="30" high="31" type="a3xx_tex_type"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="HEIGHT" low="0" high="13" type="uint"/>
+		<bitfield name="WIDTH" low="14" high="27" type="uint"/>
+		<!-- minimum pitch (for mipmap levels): log2(pitchalign / 16) -->
+		<bitfield name="PITCHALIGN" low="28" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<doc>INDX is index of texture address(es) in MIPMAP state block</doc>
+		<bitfield name="INDX" low="0" high="8" type="uint"/>
+		<doc>Pitch in bytes (so actually stride)</doc>
+		<bitfield name="PITCH" low="12" high="29" type="uint"/>
+		<doc>SWAP bit is set for BGRA instead of RGBA</doc>
+		<bitfield name="SWAP" low="30" high="31" type="a3xx_color_swap"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<!--
+		Update: the two LAYERSZn seem not to be the same thing.
+		According to Ilia's experimentation the first one goes up
+		to at *least* bit 14..
+		 -->
+		<bitfield name="LAYERSZ1" low="0" high="16" shr="12" type="uint"/>
+		<bitfield name="DEPTH" low="17" high="27" type="uint"/>
+		<bitfield name="LAYERSZ2" low="28" high="31" shr="12" type="uint"/>
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/adreno/a4xx.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/adreno/a4xx.xml
@@ -0,0 +1,2409 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="adreno/adreno_common.xml"/>
+<import file="adreno/adreno_pm4.xml"/>
+
+<enum name="a4xx_color_fmt">
+	<value name="RB4_A8_UNORM" value="0x01"/>
+	<value name="RB4_R8_UNORM" value="0x02"/>
+	<value name="RB4_R8_SNORM" value="0x03"/>
+	<value name="RB4_R8_UINT" value="0x04"/>
+	<value name="RB4_R8_SINT" value="0x05"/>
+
+	<value name="RB4_R4G4B4A4_UNORM" value="0x08"/>
+	<value name="RB4_R5G5B5A1_UNORM" value="0x0a"/>
+	<value name="RB4_R5G6B5_UNORM" value="0x0e"/>
+	<value name="RB4_R8G8_UNORM" value="0x0f"/>
+	<value name="RB4_R8G8_SNORM" value="0x10"/>
+	<value name="RB4_R8G8_UINT" value="0x11"/>
+	<value name="RB4_R8G8_SINT" value="0x12"/>
+	<value name="RB4_R16_UNORM" value="0x13"/>
+	<value name="RB4_R16_SNORM" value="0x14"/>
+	<value name="RB4_R16_FLOAT" value="0x15"/>
+	<value name="RB4_R16_UINT" value="0x16"/>
+	<value name="RB4_R16_SINT" value="0x17"/>
+
+	<value name="RB4_R8G8B8_UNORM" value="0x19"/>
+
+	<value name="RB4_R8G8B8A8_UNORM" value="0x1a"/>
+	<value name="RB4_R8G8B8A8_SNORM" value="0x1c"/>
+	<value name="RB4_R8G8B8A8_UINT" value="0x1d"/>
+	<value name="RB4_R8G8B8A8_SINT" value="0x1e"/>
+	<value name="RB4_R10G10B10A2_UNORM" value="0x1f"/>
+	<value name="RB4_R10G10B10A2_UINT" value="0x22"/>
+	<value name="RB4_R11G11B10_FLOAT" value="0x27"/>
+	<value name="RB4_R16G16_UNORM" value="0x28"/>
+	<value name="RB4_R16G16_SNORM" value="0x29"/>
+	<value name="RB4_R16G16_FLOAT" value="0x2a"/>
+	<value name="RB4_R16G16_UINT" value="0x2b"/>
+	<value name="RB4_R16G16_SINT" value="0x2c"/>
+	<value name="RB4_R32_FLOAT" value="0x2d"/>
+	<value name="RB4_R32_UINT" value="0x2e"/>
+	<value name="RB4_R32_SINT" value="0x2f"/>
+
+	<value name="RB4_R16G16B16A16_UNORM" value="0x34"/>
+	<value name="RB4_R16G16B16A16_SNORM" value="0x35"/>
+	<value name="RB4_R16G16B16A16_FLOAT" value="0x36"/>
+	<value name="RB4_R16G16B16A16_UINT" value="0x37"/>
+	<value name="RB4_R16G16B16A16_SINT" value="0x38"/>
+	<value name="RB4_R32G32_FLOAT" value="0x39"/>
+	<value name="RB4_R32G32_UINT" value="0x3a"/>
+	<value name="RB4_R32G32_SINT" value="0x3b"/>
+
+	<value name="RB4_R32G32B32A32_FLOAT" value="0x3c"/>
+	<value name="RB4_R32G32B32A32_UINT" value="0x3d"/>
+	<value name="RB4_R32G32B32A32_SINT" value="0x3e"/>
+
+	<value name="RB4_NONE" value="0xff"/>
+</enum>
+
+<enum name="a4xx_tile_mode">
+	<value name="TILE4_LINEAR" value="0"/>
+	<value name="TILE4_2" value="2"/>
+	<value name="TILE4_3" value="3"/>
+</enum>
+
+<enum name="a4xx_vtx_fmt" prefix="chipset">
+	<!-- hmm, shifted one compared to a3xx?!?  -->
+	<value name="VFMT4_32_FLOAT" value="0x1"/>
+	<value name="VFMT4_32_32_FLOAT" value="0x2"/>
+	<value name="VFMT4_32_32_32_FLOAT" value="0x3"/>
+	<value name="VFMT4_32_32_32_32_FLOAT" value="0x4"/>
+
+	<value name="VFMT4_16_FLOAT" value="0x5"/>
+	<value name="VFMT4_16_16_FLOAT" value="0x6"/>
+	<value name="VFMT4_16_16_16_FLOAT" value="0x7"/>
+	<value name="VFMT4_16_16_16_16_FLOAT" value="0x8"/>
+
+	<value name="VFMT4_32_FIXED" value="0x9"/>
+	<value name="VFMT4_32_32_FIXED" value="0xa"/>
+	<value name="VFMT4_32_32_32_FIXED" value="0xb"/>
+	<value name="VFMT4_32_32_32_32_FIXED" value="0xc"/>
+
+	<value name="VFMT4_11_11_10_FLOAT" value="0xd"/>
+
+	<!-- beyond here it does not appear to be shifted -->
+	<value name="VFMT4_16_SINT" value="0x10"/>
+	<value name="VFMT4_16_16_SINT" value="0x11"/>
+	<value name="VFMT4_16_16_16_SINT" value="0x12"/>
+	<value name="VFMT4_16_16_16_16_SINT" value="0x13"/>
+	<value name="VFMT4_16_UINT" value="0x14"/>
+	<value name="VFMT4_16_16_UINT" value="0x15"/>
+	<value name="VFMT4_16_16_16_UINT" value="0x16"/>
+	<value name="VFMT4_16_16_16_16_UINT" value="0x17"/>
+	<value name="VFMT4_16_SNORM" value="0x18"/>
+	<value name="VFMT4_16_16_SNORM" value="0x19"/>
+	<value name="VFMT4_16_16_16_SNORM" value="0x1a"/>
+	<value name="VFMT4_16_16_16_16_SNORM" value="0x1b"/>
+	<value name="VFMT4_16_UNORM" value="0x1c"/>
+	<value name="VFMT4_16_16_UNORM" value="0x1d"/>
+	<value name="VFMT4_16_16_16_UNORM" value="0x1e"/>
+	<value name="VFMT4_16_16_16_16_UNORM" value="0x1f"/>
+
+	<value name="VFMT4_32_UINT" value="0x20"/>
+	<value name="VFMT4_32_32_UINT" value="0x21"/>
+	<value name="VFMT4_32_32_32_UINT" value="0x22"/>
+	<value name="VFMT4_32_32_32_32_UINT" value="0x23"/>
+	<value name="VFMT4_32_SINT" value="0x24"/>
+	<value name="VFMT4_32_32_SINT" value="0x25"/>
+	<value name="VFMT4_32_32_32_SINT" value="0x26"/>
+	<value name="VFMT4_32_32_32_32_SINT" value="0x27"/>
+
+	<value name="VFMT4_8_UINT" value="0x28"/>
+	<value name="VFMT4_8_8_UINT" value="0x29"/>
+	<value name="VFMT4_8_8_8_UINT" value="0x2a"/>
+	<value name="VFMT4_8_8_8_8_UINT" value="0x2b"/>
+	<value name="VFMT4_8_UNORM" value="0x2c"/>
+	<value name="VFMT4_8_8_UNORM" value="0x2d"/>
+	<value name="VFMT4_8_8_8_UNORM" value="0x2e"/>
+	<value name="VFMT4_8_8_8_8_UNORM" value="0x2f"/>
+	<value name="VFMT4_8_SINT" value="0x30"/>
+	<value name="VFMT4_8_8_SINT" value="0x31"/>
+	<value name="VFMT4_8_8_8_SINT" value="0x32"/>
+	<value name="VFMT4_8_8_8_8_SINT" value="0x33"/>
+	<value name="VFMT4_8_SNORM" value="0x34"/>
+	<value name="VFMT4_8_8_SNORM" value="0x35"/>
+	<value name="VFMT4_8_8_8_SNORM" value="0x36"/>
+	<value name="VFMT4_8_8_8_8_SNORM" value="0x37"/>
+
+	<value name="VFMT4_10_10_10_2_UINT" value="0x38"/>
+	<value name="VFMT4_10_10_10_2_UNORM" value="0x39"/>
+	<value name="VFMT4_10_10_10_2_SINT" value="0x3a"/>
+	<value name="VFMT4_10_10_10_2_SNORM" value="0x3b"/>
+	<value name="VFMT4_2_10_10_10_UINT" value="0x3c"/>
+	<value name="VFMT4_2_10_10_10_UNORM" value="0x3d"/>
+	<value name="VFMT4_2_10_10_10_SINT" value="0x3e"/>
+	<value name="VFMT4_2_10_10_10_SNORM" value="0x3f"/>
+
+	<value name="VFMT4_NONE" value="0xff"/>
+</enum>
+
+<enum name="a4xx_tex_fmt">
+	<!-- 0x00 .. 0x02 -->
+
+	<!-- 8-bit formats -->
+	<value name="TFMT4_A8_UNORM" value="0x03"/>
+	<value name="TFMT4_8_UNORM"  value="0x04"/>
+	<value name="TFMT4_8_SNORM"  value="0x05"/>
+	<value name="TFMT4_8_UINT"   value="0x06"/>
+	<value name="TFMT4_8_SINT"   value="0x07"/>
+
+	<!-- 16-bit formats -->
+	<value name="TFMT4_4_4_4_4_UNORM" value="0x08"/>
+	<value name="TFMT4_5_5_5_1_UNORM" value="0x09"/>
+	<!-- 0x0a -->
+	<value name="TFMT4_5_6_5_UNORM"   value="0x0b"/>
+
+	<!-- 0x0c -->
+
+	<value name="TFMT4_L8_A8_UNORM" value="0x0d"/>
+	<value name="TFMT4_8_8_UNORM"   value="0x0e"/>
+	<value name="TFMT4_8_8_SNORM"   value="0x0f"/>
+	<value name="TFMT4_8_8_UINT"    value="0x10"/>
+	<value name="TFMT4_8_8_SINT"    value="0x11"/>
+
+	<value name="TFMT4_16_UNORM" value="0x12"/>
+	<value name="TFMT4_16_SNORM" value="0x13"/>
+	<value name="TFMT4_16_FLOAT" value="0x14"/>
+	<value name="TFMT4_16_UINT"  value="0x15"/>
+	<value name="TFMT4_16_SINT"  value="0x16"/>
+
+	<!-- 0x17 .. 0x1b -->
+
+	<!-- 32-bit formats -->
+	<value name="TFMT4_8_8_8_8_UNORM" value="0x1c"/>
+	<value name="TFMT4_8_8_8_8_SNORM" value="0x1d"/>
+	<value name="TFMT4_8_8_8_8_UINT"  value="0x1e"/>
+	<value name="TFMT4_8_8_8_8_SINT"  value="0x1f"/>
+
+	<value name="TFMT4_9_9_9_E5_FLOAT"   value="0x20"/>
+	<value name="TFMT4_10_10_10_2_UNORM" value="0x21"/>
+	<value name="TFMT4_10_10_10_2_UINT"  value="0x22"/>
+	<!-- 0x23 .. 0x24 -->
+	<value name="TFMT4_11_11_10_FLOAT"   value="0x25"/>
+
+	<value name="TFMT4_16_16_UNORM" value="0x26"/>
+	<value name="TFMT4_16_16_SNORM" value="0x27"/>
+	<value name="TFMT4_16_16_FLOAT" value="0x28"/>
+	<value name="TFMT4_16_16_UINT"  value="0x29"/>
+	<value name="TFMT4_16_16_SINT"  value="0x2a"/>
+
+	<value name="TFMT4_32_FLOAT" value="0x2b"/>
+	<value name="TFMT4_32_UINT"  value="0x2c"/>
+	<value name="TFMT4_32_SINT"  value="0x2d"/>
+
+	<!-- 0x2e .. 0x32 -->
+
+	<!-- 64-bit formats -->
+	<value name="TFMT4_16_16_16_16_UNORM" value="0x33"/>
+	<value name="TFMT4_16_16_16_16_SNORM" value="0x34"/>
+	<value name="TFMT4_16_16_16_16_FLOAT" value="0x35"/>
+	<value name="TFMT4_16_16_16_16_UINT"  value="0x36"/>
+	<value name="TFMT4_16_16_16_16_SINT"  value="0x37"/>
+
+	<value name="TFMT4_32_32_FLOAT" value="0x38"/>
+	<value name="TFMT4_32_32_UINT"  value="0x39"/>
+	<value name="TFMT4_32_32_SINT"  value="0x3a"/>
+
+	<!-- 96-bit formats -->
+	<value name="TFMT4_32_32_32_FLOAT" value="0x3b"/>
+	<value name="TFMT4_32_32_32_UINT"  value="0x3c"/>
+	<value name="TFMT4_32_32_32_SINT"  value="0x3d"/>
+
+	<!-- 0x3e -->
+
+	<!-- 128-bit formats -->
+	<value name="TFMT4_32_32_32_32_FLOAT" value="0x3f"/>
+	<value name="TFMT4_32_32_32_32_UINT"  value="0x40"/>
+	<value name="TFMT4_32_32_32_32_SINT"  value="0x41"/>
+
+	<!-- 0x42 .. 0x46 -->
+	<value name="TFMT4_X8Z24_UNORM" value="0x47"/>
+	<!-- 0x48 .. 0x55 -->
+
+	<!-- compressed formats -->
+	<value name="TFMT4_DXT1"                  value="0x56"/>
+	<value name="TFMT4_DXT3"                  value="0x57"/>
+	<value name="TFMT4_DXT5"                  value="0x58"/>
+	<!-- 0x59 -->
+	<value name="TFMT4_RGTC1_UNORM"           value="0x5a"/>
+	<value name="TFMT4_RGTC1_SNORM"           value="0x5b"/>
+	<!-- 0x5c .. 0x5d -->
+	<value name="TFMT4_RGTC2_UNORM"           value="0x5e"/>
+	<value name="TFMT4_RGTC2_SNORM"           value="0x5f"/>
+	<!-- 0x60 -->
+	<value name="TFMT4_BPTC_UFLOAT"           value="0x61"/>
+	<value name="TFMT4_BPTC_FLOAT"            value="0x62"/>
+	<value name="TFMT4_BPTC"                  value="0x63"/>
+	<value name="TFMT4_ATC_RGB"               value="0x64"/>
+	<value name="TFMT4_ATC_RGBA_EXPLICIT"     value="0x65"/>
+	<value name="TFMT4_ATC_RGBA_INTERPOLATED" value="0x66"/>
+	<value name="TFMT4_ETC2_RG11_UNORM"       value="0x67"/>
+	<value name="TFMT4_ETC2_RG11_SNORM"       value="0x68"/>
+	<value name="TFMT4_ETC2_R11_UNORM"        value="0x69"/>
+	<value name="TFMT4_ETC2_R11_SNORM"        value="0x6a"/>
+	<value name="TFMT4_ETC1"                  value="0x6b"/>
+	<value name="TFMT4_ETC2_RGB8"             value="0x6c"/>
+	<value name="TFMT4_ETC2_RGBA8"            value="0x6d"/>
+	<value name="TFMT4_ETC2_RGB8A1"           value="0x6e"/>
+	<value name="TFMT4_ASTC_4x4"              value="0x6f"/>
+	<value name="TFMT4_ASTC_5x4"              value="0x70"/>
+	<value name="TFMT4_ASTC_5x5"              value="0x71"/>
+	<value name="TFMT4_ASTC_6x5"              value="0x72"/>
+	<value name="TFMT4_ASTC_6x6"              value="0x73"/>
+	<value name="TFMT4_ASTC_8x5"              value="0x74"/>
+	<value name="TFMT4_ASTC_8x6"              value="0x75"/>
+	<value name="TFMT4_ASTC_8x8"              value="0x76"/>
+	<value name="TFMT4_ASTC_10x5"             value="0x77"/>
+	<value name="TFMT4_ASTC_10x6"             value="0x78"/>
+	<value name="TFMT4_ASTC_10x8"             value="0x79"/>
+	<value name="TFMT4_ASTC_10x10"            value="0x7a"/>
+	<value name="TFMT4_ASTC_12x10"            value="0x7b"/>
+	<value name="TFMT4_ASTC_12x12"            value="0x7c"/>
+	<!-- 0x7d .. 0x7f -->
+
+	<value name="TFMT4_NONE"                  value="0xff"/>
+</enum>
+
+<enum name="a4xx_depth_format">
+	<value name="DEPTH4_NONE" value="0"/>
+	<value name="DEPTH4_16" value="1"/>
+	<value name="DEPTH4_24_8" value="2"/>
+	<value name="DEPTH4_32" value="3"/>
+</enum>
+
+<!--
+NOTE counters extracted from test-perf log with the following awful
+script:
+##################
+#!/bin/bash
+
+log=$1
+
+grep -F "counter
+countable
+group" $log | grep -v gl > shortlist.txt
+
+countable=""
+IFS=$'\n'; for line in $(cat shortlist.txt); do
+	# parse ######### group[$n]: $name
+	l=${line########### group}
+	if [ $l != $line ];  then
+		group=`echo $line | awk '{print $3}'`
+		echo "Group: $group"
+		continue
+	fi
+	# parse #########   counter[$n]: $name
+	l=${line###########   counter}
+	if [ $l != $line ]; then
+		countable=`echo $line | awk '{print $3}'`
+		#echo "  Countable: $countable"
+		continue
+	fi
+	# parse 		countable:
+	l=${line##		countable:}
+	if [ $l != $line ]; then
+		val=`echo $line | awk '{print $2}'`
+		echo "<value value=\"$val\" name=\"$countable\"/>"
+	fi
+
+done
+##################
+ -->
+<enum name="a4xx_ccu_perfcounter_select">
+	<value value="0" name="CCU_BUSY_CYCLES"/>
+	<value value="2" name="CCU_RB_DEPTH_RETURN_STALL"/>
+	<value value="3" name="CCU_RB_COLOR_RETURN_STALL"/>
+	<value value="6" name="CCU_DEPTH_BLOCKS"/>
+	<value value="7" name="CCU_COLOR_BLOCKS"/>
+	<value value="8" name="CCU_DEPTH_BLOCK_HIT"/>
+	<value value="9" name="CCU_COLOR_BLOCK_HIT"/>
+	<value value="10" name="CCU_DEPTH_FLAG1_COUNT"/>
+	<value value="11" name="CCU_DEPTH_FLAG2_COUNT"/>
+	<value value="12" name="CCU_DEPTH_FLAG3_COUNT"/>
+	<value value="13" name="CCU_DEPTH_FLAG4_COUNT"/>
+	<value value="14" name="CCU_COLOR_FLAG1_COUNT"/>
+	<value value="15" name="CCU_COLOR_FLAG2_COUNT"/>
+	<value value="16" name="CCU_COLOR_FLAG3_COUNT"/>
+	<value value="17" name="CCU_COLOR_FLAG4_COUNT"/>
+	<value value="18" name="CCU_PARTIAL_BLOCK_READ"/>
+</enum>
+
+<!--
+NOTE other than CP_ALWAYS_COUNT (which is the only one we use so far),
+on a3xx the countable #'s from AMD_performance_monitor disagreed with
+TRM.  All these #'s for a4xx come from AMD_performance_monitor, so
+perhaps they should be taken with a grain of salt
+-->
+<enum name="a4xx_cp_perfcounter_select">
+	<!-- first ctr at least seems same as a3xx, so we can measure freq -->
+	<value value="0" name="CP_ALWAYS_COUNT"/>
+	<value value="1" name="CP_BUSY"/>
+	<value value="2" name="CP_PFP_IDLE"/>
+	<value value="3" name="CP_PFP_BUSY_WORKING"/>
+	<value value="4" name="CP_PFP_STALL_CYCLES_ANY"/>
+	<value value="5" name="CP_PFP_STARVE_CYCLES_ANY"/>
+	<value value="6" name="CP_PFP_STARVED_PER_LOAD_ADDR"/>
+	<value value="7" name="CP_PFP_STALLED_PER_STORE_ADDR"/>
+	<value value="8" name="CP_PFP_PC_PROFILE"/>
+	<value value="9" name="CP_PFP_MATCH_PM4_PKT_PROFILE"/>
+	<value value="10" name="CP_PFP_COND_INDIRECT_DISCARDED"/>
+	<value value="11" name="CP_LONG_RESUMPTIONS"/>
+	<value value="12" name="CP_RESUME_CYCLES"/>
+	<value value="13" name="CP_RESUME_TO_BOUNDARY_CYCLES"/>
+	<value value="14" name="CP_LONG_PREEMPTIONS"/>
+	<value value="15" name="CP_PREEMPT_CYCLES"/>
+	<value value="16" name="CP_PREEMPT_TO_BOUNDARY_CYCLES"/>
+	<value value="17" name="CP_ME_FIFO_EMPTY_PFP_IDLE"/>
+	<value value="18" name="CP_ME_FIFO_EMPTY_PFP_BUSY"/>
+	<value value="19" name="CP_ME_FIFO_NOT_EMPTY_NOT_FULL"/>
+	<value value="20" name="CP_ME_FIFO_FULL_ME_BUSY"/>
+	<value value="21" name="CP_ME_FIFO_FULL_ME_NON_WORKING"/>
+	<value value="22" name="CP_ME_WAITING_FOR_PACKETS"/>
+	<value value="23" name="CP_ME_BUSY_WORKING"/>
+	<value value="24" name="CP_ME_STARVE_CYCLES_ANY"/>
+	<value value="25" name="CP_ME_STARVE_CYCLES_PER_PROFILE"/>
+	<value value="26" name="CP_ME_STALL_CYCLES_PER_PROFILE"/>
+	<value value="27" name="CP_ME_PC_PROFILE"/>
+	<value value="28" name="CP_RCIU_FIFO_EMPTY"/>
+	<value value="29" name="CP_RCIU_FIFO_NOT_EMPTY_NOT_FULL"/>
+	<value value="30" name="CP_RCIU_FIFO_FULL"/>
+	<value value="31" name="CP_RCIU_FIFO_FULL_NO_CONTEXT"/>
+	<value value="32" name="CP_RCIU_FIFO_FULL_AHB_MASTER"/>
+	<value value="33" name="CP_RCIU_FIFO_FULL_OTHER"/>
+	<value value="34" name="CP_AHB_IDLE"/>
+	<value value="35" name="CP_AHB_STALL_ON_GRANT_NO_SPLIT"/>
+	<value value="36" name="CP_AHB_STALL_ON_GRANT_SPLIT"/>
+	<value value="37" name="CP_AHB_STALL_ON_GRANT_SPLIT_PROFILE"/>
+	<value value="38" name="CP_AHB_BUSY_WORKING"/>
+	<value value="39" name="CP_AHB_BUSY_STALL_ON_HRDY"/>
+	<value value="40" name="CP_AHB_BUSY_STALL_ON_HRDY_PROFILE"/>
+</enum>
+
+<enum name="a4xx_gras_ras_perfcounter_select">
+	<value value="0" name="RAS_SUPER_TILES"/>
+	<value value="1" name="RAS_8X8_TILES"/>
+	<value value="2" name="RAS_4X4_TILES"/>
+	<value value="3" name="RAS_BUSY_CYCLES"/>
+	<value value="4" name="RAS_STALL_CYCLES_BY_RB"/>
+	<value value="5" name="RAS_STALL_CYCLES_BY_VSC"/>
+	<value value="6" name="RAS_STARVE_CYCLES_BY_TSE"/>
+	<value value="7" name="RAS_SUPERTILE_CYCLES"/>
+	<value value="8" name="RAS_TILE_CYCLES"/>
+	<value value="9" name="RAS_FULLY_COVERED_SUPER_TILES"/>
+	<value value="10" name="RAS_FULLY_COVERED_8X8_TILES"/>
+	<value value="11" name="RAS_4X4_PRIM"/>
+	<value value="12" name="RAS_8X4_4X8_PRIM"/>
+	<value value="13" name="RAS_8X8_PRIM"/>
+</enum>
+
+<enum name="a4xx_gras_tse_perfcounter_select">
+	<value value="0" name="TSE_INPUT_PRIM"/>
+	<value value="1" name="TSE_INPUT_NULL_PRIM"/>
+	<value value="2" name="TSE_TRIVAL_REJ_PRIM"/>
+	<value value="3" name="TSE_CLIPPED_PRIM"/>
+	<value value="4" name="TSE_NEW_PRIM"/>
+	<value value="5" name="TSE_ZERO_AREA_PRIM"/>
+	<value value="6" name="TSE_FACENESS_CULLED_PRIM"/>
+	<value value="7" name="TSE_ZERO_PIXEL_PRIM"/>
+	<value value="8" name="TSE_OUTPUT_NULL_PRIM"/>
+	<value value="9" name="TSE_OUTPUT_VISIBLE_PRIM"/>
+	<value value="10" name="TSE_PRE_CLIP_PRIM"/>
+	<value value="11" name="TSE_POST_CLIP_PRIM"/>
+	<value value="12" name="TSE_BUSY_CYCLES"/>
+	<value value="13" name="TSE_PC_STARVE"/>
+	<value value="14" name="TSE_RAS_STALL"/>
+	<value value="15" name="TSE_STALL_BARYPLANE_FIFO_FULL"/>
+	<value value="16" name="TSE_STALL_ZPLANE_FIFO_FULL"/>
+</enum>
+
+<enum name="a4xx_hlsq_perfcounter_select">
+	<value value="0" name="HLSQ_SP_VS_STAGE_CONSTANT"/>
+	<value value="1" name="HLSQ_SP_VS_STAGE_INSTRUCTIONS"/>
+	<value value="2" name="HLSQ_SP_FS_STAGE_CONSTANT"/>
+	<value value="3" name="HLSQ_SP_FS_STAGE_INSTRUCTIONS"/>
+	<value value="4" name="HLSQ_TP_STATE"/>
+	<value value="5" name="HLSQ_QUADS"/>
+	<value value="6" name="HLSQ_PIXELS"/>
+	<value value="7" name="HLSQ_VERTICES"/>
+	<value value="13" name="HLSQ_SP_VS_STAGE_DATA_BYTES"/>
+	<value value="14" name="HLSQ_SP_FS_STAGE_DATA_BYTES"/>
+	<value value="15" name="HLSQ_BUSY_CYCLES"/>
+	<value value="16" name="HLSQ_STALL_CYCLES_SP_STATE"/>
+	<value value="17" name="HLSQ_STALL_CYCLES_SP_VS_STAGE"/>
+	<value value="18" name="HLSQ_STALL_CYCLES_SP_FS_STAGE"/>
+	<value value="19" name="HLSQ_STALL_CYCLES_UCHE"/>
+	<value value="20" name="HLSQ_RBBM_LOAD_CYCLES"/>
+	<value value="21" name="HLSQ_DI_TO_VS_START_SP"/>
+	<value value="22" name="HLSQ_DI_TO_FS_START_SP"/>
+	<value value="23" name="HLSQ_VS_STAGE_START_TO_DONE_SP"/>
+	<value value="24" name="HLSQ_FS_STAGE_START_TO_DONE_SP"/>
+	<value value="25" name="HLSQ_SP_STATE_COPY_CYCLES_VS_STAGE"/>
+	<value value="26" name="HLSQ_SP_STATE_COPY_CYCLES_FS_STAGE"/>
+	<value value="27" name="HLSQ_UCHE_LATENCY_CYCLES"/>
+	<value value="28" name="HLSQ_UCHE_LATENCY_COUNT"/>
+	<value value="29" name="HLSQ_STARVE_CYCLES_VFD"/>
+</enum>
+
+<enum name="a4xx_pc_perfcounter_select">
+	<value value="0" name="PC_VIS_STREAMS_LOADED"/>
+	<value value="2" name="PC_VPC_PRIMITIVES"/>
+	<value value="3" name="PC_DEAD_PRIM"/>
+	<value value="4" name="PC_LIVE_PRIM"/>
+	<value value="5" name="PC_DEAD_DRAWCALLS"/>
+	<value value="6" name="PC_LIVE_DRAWCALLS"/>
+	<value value="7" name="PC_VERTEX_MISSES"/>
+	<value value="9" name="PC_STALL_CYCLES_VFD"/>
+	<value value="10" name="PC_STALL_CYCLES_TSE"/>
+	<value value="11" name="PC_STALL_CYCLES_UCHE"/>
+	<value value="12" name="PC_WORKING_CYCLES"/>
+	<value value="13" name="PC_IA_VERTICES"/>
+	<value value="14" name="PC_GS_PRIMITIVES"/>
+	<value value="15" name="PC_HS_INVOCATIONS"/>
+	<value value="16" name="PC_DS_INVOCATIONS"/>
+	<value value="17" name="PC_DS_PRIMITIVES"/>
+	<value value="20" name="PC_STARVE_CYCLES_FOR_INDEX"/>
+	<value value="21" name="PC_STARVE_CYCLES_FOR_TESS_FACTOR"/>
+	<value value="22" name="PC_STARVE_CYCLES_FOR_VIZ_STREAM"/>
+	<value value="23" name="PC_STALL_CYCLES_TESS"/>
+	<value value="24" name="PC_STARVE_CYCLES_FOR_POSITION"/>
+	<value value="25" name="PC_MODE0_DRAWCALL"/>
+	<value value="26" name="PC_MODE1_DRAWCALL"/>
+	<value value="27" name="PC_MODE2_DRAWCALL"/>
+	<value value="28" name="PC_MODE3_DRAWCALL"/>
+	<value value="29" name="PC_MODE4_DRAWCALL"/>
+	<value value="30" name="PC_PREDICATED_DEAD_DRAWCALL"/>
+	<value value="31" name="PC_STALL_CYCLES_BY_TSE_ONLY"/>
+	<value value="32" name="PC_STALL_CYCLES_BY_VPC_ONLY"/>
+	<value value="33" name="PC_VPC_POS_DATA_TRANSACTION"/>
+	<value value="34" name="PC_BUSY_CYCLES"/>
+	<value value="35" name="PC_STARVE_CYCLES_DI"/>
+	<value value="36" name="PC_STALL_CYCLES_VPC"/>
+	<value value="37" name="TESS_WORKING_CYCLES"/>
+	<value value="38" name="TESS_NUM_CYCLES_SETUP_WORKING"/>
+	<value value="39" name="TESS_NUM_CYCLES_PTGEN_WORKING"/>
+	<value value="40" name="TESS_NUM_CYCLES_CONNGEN_WORKING"/>
+	<value value="41" name="TESS_BUSY_CYCLES"/>
+	<value value="42" name="TESS_STARVE_CYCLES_PC"/>
+	<value value="43" name="TESS_STALL_CYCLES_PC"/>
+</enum>
+
+<enum name="a4xx_pwr_perfcounter_select">
+	<!-- NOTE not actually used.. see RBBM_RBBM_CTL.RESET_PWR_CTR0/1 -->
+	<value value="0" name="PWR_CORE_CLOCK_CYCLES"/>
+	<value value="1" name="PWR_BUSY_CLOCK_CYCLES"/>
+</enum>
+
+<enum name="a4xx_rb_perfcounter_select">
+	<value value="0" name="RB_BUSY_CYCLES"/>
+	<value value="1" name="RB_BUSY_CYCLES_BINNING"/>
+	<value value="2" name="RB_BUSY_CYCLES_RENDERING"/>
+	<value value="3" name="RB_BUSY_CYCLES_RESOLVE"/>
+	<value value="4" name="RB_STARVE_CYCLES_BY_SP"/>
+	<value value="5" name="RB_STARVE_CYCLES_BY_RAS"/>
+	<value value="6" name="RB_STARVE_CYCLES_BY_MARB"/>
+	<value value="7" name="RB_STALL_CYCLES_BY_MARB"/>
+	<value value="8" name="RB_STALL_CYCLES_BY_HLSQ"/>
+	<value value="9" name="RB_RB_RB_MARB_DATA"/>
+	<value value="10" name="RB_SP_RB_QUAD"/>
+	<value value="11" name="RB_RAS_RB_Z_QUADS"/>
+	<value value="12" name="RB_GMEM_CH0_READ"/>
+	<value value="13" name="RB_GMEM_CH1_READ"/>
+	<value value="14" name="RB_GMEM_CH0_WRITE"/>
+	<value value="15" name="RB_GMEM_CH1_WRITE"/>
+	<value value="16" name="RB_CP_CONTEXT_DONE"/>
+	<value value="17" name="RB_CP_CACHE_FLUSH"/>
+	<value value="18" name="RB_CP_ZPASS_DONE"/>
+	<value value="19" name="RB_STALL_FIFO0_FULL"/>
+	<value value="20" name="RB_STALL_FIFO1_FULL"/>
+	<value value="21" name="RB_STALL_FIFO2_FULL"/>
+	<value value="22" name="RB_STALL_FIFO3_FULL"/>
+	<value value="23" name="RB_RB_HLSQ_TRANSACTIONS"/>
+	<value value="24" name="RB_Z_READ"/>
+	<value value="25" name="RB_Z_WRITE"/>
+	<value value="26" name="RB_C_READ"/>
+	<value value="27" name="RB_C_WRITE"/>
+	<value value="28" name="RB_C_READ_LATENCY"/>
+	<value value="29" name="RB_Z_READ_LATENCY"/>
+	<value value="30" name="RB_STALL_BY_UCHE"/>
+	<value value="31" name="RB_MARB_UCHE_TRANSACTIONS"/>
+	<value value="32" name="RB_CACHE_STALL_MISS"/>
+	<value value="33" name="RB_CACHE_STALL_FIFO_FULL"/>
+	<value value="34" name="RB_8BIT_BLENDER_UNITS_ACTIVE"/>
+	<value value="35" name="RB_16BIT_BLENDER_UNITS_ACTIVE"/>
+	<value value="36" name="RB_SAMPLER_UNITS_ACTIVE"/>
+	<value value="38" name="RB_TOTAL_PASS"/>
+	<value value="39" name="RB_Z_PASS"/>
+	<value value="40" name="RB_Z_FAIL"/>
+	<value value="41" name="RB_S_FAIL"/>
+	<value value="42" name="RB_POWER0"/>
+	<value value="43" name="RB_POWER1"/>
+	<value value="44" name="RB_POWER2"/>
+	<value value="45" name="RB_POWER3"/>
+	<value value="46" name="RB_POWER4"/>
+	<value value="47" name="RB_POWER5"/>
+	<value value="48" name="RB_POWER6"/>
+	<value value="49" name="RB_POWER7"/>
+</enum>
+
+<enum name="a4xx_rbbm_perfcounter_select">
+	<value value="0" name="RBBM_ALWAYS_ON"/>
+	<value value="1" name="RBBM_VBIF_BUSY"/>
+	<value value="2" name="RBBM_TSE_BUSY"/>
+	<value value="3" name="RBBM_RAS_BUSY"/>
+	<value value="4" name="RBBM_PC_DCALL_BUSY"/>
+	<value value="5" name="RBBM_PC_VSD_BUSY"/>
+	<value value="6" name="RBBM_VFD_BUSY"/>
+	<value value="7" name="RBBM_VPC_BUSY"/>
+	<value value="8" name="RBBM_UCHE_BUSY"/>
+	<value value="9" name="RBBM_VSC_BUSY"/>
+	<value value="10" name="RBBM_HLSQ_BUSY"/>
+	<value value="11" name="RBBM_ANY_RB_BUSY"/>
+	<value value="12" name="RBBM_ANY_TPL1_BUSY"/>
+	<value value="13" name="RBBM_ANY_SP_BUSY"/>
+	<value value="14" name="RBBM_ANY_MARB_BUSY"/>
+	<value value="15" name="RBBM_ANY_ARB_BUSY"/>
+	<value value="16" name="RBBM_AHB_STATUS_BUSY"/>
+	<value value="17" name="RBBM_AHB_STATUS_STALLED"/>
+	<value value="18" name="RBBM_AHB_STATUS_TXFR"/>
+	<value value="19" name="RBBM_AHB_STATUS_TXFR_SPLIT"/>
+	<value value="20" name="RBBM_AHB_STATUS_TXFR_ERROR"/>
+	<value value="21" name="RBBM_AHB_STATUS_LONG_STALL"/>
+	<value value="22" name="RBBM_STATUS_MASKED"/>
+	<value value="23" name="RBBM_CP_BUSY_GFX_CORE_IDLE"/>
+	<value value="24" name="RBBM_TESS_BUSY"/>
+	<value value="25" name="RBBM_COM_BUSY"/>
+	<value value="32" name="RBBM_DCOM_BUSY"/>
+	<value value="33" name="RBBM_ANY_CCU_BUSY"/>
+	<value value="34" name="RBBM_DPM_BUSY"/>
+</enum>
+
+<enum name="a4xx_sp_perfcounter_select">
+	<value value="0" name="SP_LM_LOAD_INSTRUCTIONS"/>
+	<value value="1" name="SP_LM_STORE_INSTRUCTIONS"/>
+	<value value="2" name="SP_LM_ATOMICS"/>
+	<value value="3" name="SP_GM_LOAD_INSTRUCTIONS"/>
+	<value value="4" name="SP_GM_STORE_INSTRUCTIONS"/>
+	<value value="5" name="SP_GM_ATOMICS"/>
+	<value value="6" name="SP_VS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="7" name="SP_VS_STAGE_CFLOW_INSTRUCTIONS"/>
+	<value value="8" name="SP_VS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="9" name="SP_VS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="10" name="SP_VS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="11" name="SP_FS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="12" name="SP_FS_STAGE_CFLOW_INSTRUCTIONS"/>
+	<value value="13" name="SP_FS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="14" name="SP_FS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="15" name="SP_FS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="17" name="SP_VS_INSTRUCTIONS"/>
+	<value value="18" name="SP_FS_INSTRUCTIONS"/>
+	<value value="19" name="SP_ADDR_LOCK_COUNT"/>
+	<value value="20" name="SP_UCHE_READ_TRANS"/>
+	<value value="21" name="SP_UCHE_WRITE_TRANS"/>
+	<value value="22" name="SP_EXPORT_VPC_TRANS"/>
+	<value value="23" name="SP_EXPORT_RB_TRANS"/>
+	<value value="24" name="SP_PIXELS_KILLED"/>
+	<value value="25" name="SP_ICL1_REQUESTS"/>
+	<value value="26" name="SP_ICL1_MISSES"/>
+	<value value="27" name="SP_ICL0_REQUESTS"/>
+	<value value="28" name="SP_ICL0_MISSES"/>
+	<value value="29" name="SP_ALU_WORKING_CYCLES"/>
+	<value value="30" name="SP_EFU_WORKING_CYCLES"/>
+	<value value="31" name="SP_STALL_CYCLES_BY_VPC"/>
+	<value value="32" name="SP_STALL_CYCLES_BY_TP"/>
+	<value value="33" name="SP_STALL_CYCLES_BY_UCHE"/>
+	<value value="34" name="SP_STALL_CYCLES_BY_RB"/>
+	<value value="35" name="SP_BUSY_CYCLES"/>
+	<value value="36" name="SP_HS_INSTRUCTIONS"/>
+	<value value="37" name="SP_DS_INSTRUCTIONS"/>
+	<value value="38" name="SP_GS_INSTRUCTIONS"/>
+	<value value="39" name="SP_CS_INSTRUCTIONS"/>
+	<value value="40" name="SP_SCHEDULER_NON_WORKING"/>
+	<value value="41" name="SP_WAVE_CONTEXTS"/>
+	<value value="42" name="SP_WAVE_CONTEXT_CYCLES"/>
+	<value value="43" name="SP_POWER0"/>
+	<value value="44" name="SP_POWER1"/>
+	<value value="45" name="SP_POWER2"/>
+	<value value="46" name="SP_POWER3"/>
+	<value value="47" name="SP_POWER4"/>
+	<value value="48" name="SP_POWER5"/>
+	<value value="49" name="SP_POWER6"/>
+	<value value="50" name="SP_POWER7"/>
+	<value value="51" name="SP_POWER8"/>
+	<value value="52" name="SP_POWER9"/>
+	<value value="53" name="SP_POWER10"/>
+	<value value="54" name="SP_POWER11"/>
+	<value value="55" name="SP_POWER12"/>
+	<value value="56" name="SP_POWER13"/>
+	<value value="57" name="SP_POWER14"/>
+	<value value="58" name="SP_POWER15"/>
+</enum>
+
+<enum name="a4xx_tp_perfcounter_select">
+	<value value="0" name="TP_L1_REQUESTS"/>
+	<value value="1" name="TP_L1_MISSES"/>
+	<value value="8" name="TP_QUADS_OFFSET"/>
+	<value value="9" name="TP_QUAD_SHADOW"/>
+	<value value="10" name="TP_QUADS_ARRAY"/>
+	<value value="11" name="TP_QUADS_GRADIENT"/>
+	<value value="12" name="TP_QUADS_1D2D"/>
+	<value value="13" name="TP_QUADS_3DCUBE"/>
+	<value value="16" name="TP_BUSY_CYCLES"/>
+	<value value="17" name="TP_STALL_CYCLES_BY_ARB"/>
+	<value value="20" name="TP_STATE_CACHE_REQUESTS"/>
+	<value value="21" name="TP_STATE_CACHE_MISSES"/>
+	<value value="22" name="TP_POWER0"/>
+	<value value="23" name="TP_POWER1"/>
+	<value value="24" name="TP_POWER2"/>
+	<value value="25" name="TP_POWER3"/>
+	<value value="26" name="TP_POWER4"/>
+	<value value="27" name="TP_POWER5"/>
+	<value value="28" name="TP_POWER6"/>
+	<value value="29" name="TP_POWER7"/>
+</enum>
+
+<enum name="a4xx_uche_perfcounter_select">
+	<value value="0" name="UCHE_VBIF_READ_BEATS_TP"/>
+	<value value="1" name="UCHE_VBIF_READ_BEATS_VFD"/>
+	<value value="2" name="UCHE_VBIF_READ_BEATS_HLSQ"/>
+	<value value="3" name="UCHE_VBIF_READ_BEATS_MARB"/>
+	<value value="4" name="UCHE_VBIF_READ_BEATS_SP"/>
+	<value value="5" name="UCHE_READ_REQUESTS_TP"/>
+	<value value="6" name="UCHE_READ_REQUESTS_VFD"/>
+	<value value="7" name="UCHE_READ_REQUESTS_HLSQ"/>
+	<value value="8" name="UCHE_READ_REQUESTS_MARB"/>
+	<value value="9" name="UCHE_READ_REQUESTS_SP"/>
+	<value value="10" name="UCHE_WRITE_REQUESTS_MARB"/>
+	<value value="11" name="UCHE_WRITE_REQUESTS_SP"/>
+	<value value="12" name="UCHE_TAG_CHECK_FAILS"/>
+	<value value="13" name="UCHE_EVICTS"/>
+	<value value="14" name="UCHE_FLUSHES"/>
+	<value value="15" name="UCHE_VBIF_LATENCY_CYCLES"/>
+	<value value="16" name="UCHE_VBIF_LATENCY_SAMPLES"/>
+	<value value="17" name="UCHE_BUSY_CYCLES"/>
+	<value value="18" name="UCHE_VBIF_READ_BEATS_PC"/>
+	<value value="19" name="UCHE_READ_REQUESTS_PC"/>
+	<value value="20" name="UCHE_WRITE_REQUESTS_VPC"/>
+	<value value="21" name="UCHE_STALL_BY_VBIF"/>
+	<value value="22" name="UCHE_WRITE_REQUESTS_VSC"/>
+	<value value="23" name="UCHE_POWER0"/>
+	<value value="24" name="UCHE_POWER1"/>
+	<value value="25" name="UCHE_POWER2"/>
+	<value value="26" name="UCHE_POWER3"/>
+	<value value="27" name="UCHE_POWER4"/>
+	<value value="28" name="UCHE_POWER5"/>
+	<value value="29" name="UCHE_POWER6"/>
+	<value value="30" name="UCHE_POWER7"/>
+</enum>
+
+<enum name="a4xx_vbif_perfcounter_select">
+	<value value="0" name="AXI_READ_REQUESTS_ID_0"/>
+	<value value="1" name="AXI_READ_REQUESTS_ID_1"/>
+	<value value="2" name="AXI_READ_REQUESTS_ID_2"/>
+	<value value="3" name="AXI_READ_REQUESTS_ID_3"/>
+	<value value="4" name="AXI_READ_REQUESTS_ID_4"/>
+	<value value="5" name="AXI_READ_REQUESTS_ID_5"/>
+	<value value="6" name="AXI_READ_REQUESTS_ID_6"/>
+	<value value="7" name="AXI_READ_REQUESTS_ID_7"/>
+	<value value="8" name="AXI_READ_REQUESTS_ID_8"/>
+	<value value="9" name="AXI_READ_REQUESTS_ID_9"/>
+	<value value="10" name="AXI_READ_REQUESTS_ID_10"/>
+	<value value="11" name="AXI_READ_REQUESTS_ID_11"/>
+	<value value="12" name="AXI_READ_REQUESTS_ID_12"/>
+	<value value="13" name="AXI_READ_REQUESTS_ID_13"/>
+	<value value="14" name="AXI_READ_REQUESTS_ID_14"/>
+	<value value="15" name="AXI_READ_REQUESTS_ID_15"/>
+	<value value="16" name="AXI0_READ_REQUESTS_TOTAL"/>
+	<value value="17" name="AXI1_READ_REQUESTS_TOTAL"/>
+	<value value="18" name="AXI2_READ_REQUESTS_TOTAL"/>
+	<value value="19" name="AXI3_READ_REQUESTS_TOTAL"/>
+	<value value="20" name="AXI_READ_REQUESTS_TOTAL"/>
+	<value value="21" name="AXI_WRITE_REQUESTS_ID_0"/>
+	<value value="22" name="AXI_WRITE_REQUESTS_ID_1"/>
+	<value value="23" name="AXI_WRITE_REQUESTS_ID_2"/>
+	<value value="24" name="AXI_WRITE_REQUESTS_ID_3"/>
+	<value value="25" name="AXI_WRITE_REQUESTS_ID_4"/>
+	<value value="26" name="AXI_WRITE_REQUESTS_ID_5"/>
+	<value value="27" name="AXI_WRITE_REQUESTS_ID_6"/>
+	<value value="28" name="AXI_WRITE_REQUESTS_ID_7"/>
+	<value value="29" name="AXI_WRITE_REQUESTS_ID_8"/>
+	<value value="30" name="AXI_WRITE_REQUESTS_ID_9"/>
+	<value value="31" name="AXI_WRITE_REQUESTS_ID_10"/>
+	<value value="32" name="AXI_WRITE_REQUESTS_ID_11"/>
+	<value value="33" name="AXI_WRITE_REQUESTS_ID_12"/>
+	<value value="34" name="AXI_WRITE_REQUESTS_ID_13"/>
+	<value value="35" name="AXI_WRITE_REQUESTS_ID_14"/>
+	<value value="36" name="AXI_WRITE_REQUESTS_ID_15"/>
+	<value value="37" name="AXI0_WRITE_REQUESTS_TOTAL"/>
+	<value value="38" name="AXI1_WRITE_REQUESTS_TOTAL"/>
+	<value value="39" name="AXI2_WRITE_REQUESTS_TOTAL"/>
+	<value value="40" name="AXI3_WRITE_REQUESTS_TOTAL"/>
+	<value value="41" name="AXI_WRITE_REQUESTS_TOTAL"/>
+	<value value="42" name="AXI_TOTAL_REQUESTS"/>
+	<value value="43" name="AXI_READ_DATA_BEATS_ID_0"/>
+	<value value="44" name="AXI_READ_DATA_BEATS_ID_1"/>
+	<value value="45" name="AXI_READ_DATA_BEATS_ID_2"/>
+	<value value="46" name="AXI_READ_DATA_BEATS_ID_3"/>
+	<value value="47" name="AXI_READ_DATA_BEATS_ID_4"/>
+	<value value="48" name="AXI_READ_DATA_BEATS_ID_5"/>
+	<value value="49" name="AXI_READ_DATA_BEATS_ID_6"/>
+	<value value="50" name="AXI_READ_DATA_BEATS_ID_7"/>
+	<value value="51" name="AXI_READ_DATA_BEATS_ID_8"/>
+	<value value="52" name="AXI_READ_DATA_BEATS_ID_9"/>
+	<value value="53" name="AXI_READ_DATA_BEATS_ID_10"/>
+	<value value="54" name="AXI_READ_DATA_BEATS_ID_11"/>
+	<value value="55" name="AXI_READ_DATA_BEATS_ID_12"/>
+	<value value="56" name="AXI_READ_DATA_BEATS_ID_13"/>
+	<value value="57" name="AXI_READ_DATA_BEATS_ID_14"/>
+	<value value="58" name="AXI_READ_DATA_BEATS_ID_15"/>
+	<value value="59" name="AXI0_READ_DATA_BEATS_TOTAL"/>
+	<value value="60" name="AXI1_READ_DATA_BEATS_TOTAL"/>
+	<value value="61" name="AXI2_READ_DATA_BEATS_TOTAL"/>
+	<value value="62" name="AXI3_READ_DATA_BEATS_TOTAL"/>
+	<value value="63" name="AXI_READ_DATA_BEATS_TOTAL"/>
+	<value value="64" name="AXI_WRITE_DATA_BEATS_ID_0"/>
+	<value value="65" name="AXI_WRITE_DATA_BEATS_ID_1"/>
+	<value value="66" name="AXI_WRITE_DATA_BEATS_ID_2"/>
+	<value value="67" name="AXI_WRITE_DATA_BEATS_ID_3"/>
+	<value value="68" name="AXI_WRITE_DATA_BEATS_ID_4"/>
+	<value value="69" name="AXI_WRITE_DATA_BEATS_ID_5"/>
+	<value value="70" name="AXI_WRITE_DATA_BEATS_ID_6"/>
+	<value value="71" name="AXI_WRITE_DATA_BEATS_ID_7"/>
+	<value value="72" name="AXI_WRITE_DATA_BEATS_ID_8"/>
+	<value value="73" name="AXI_WRITE_DATA_BEATS_ID_9"/>
+	<value value="74" name="AXI_WRITE_DATA_BEATS_ID_10"/>
+	<value value="75" name="AXI_WRITE_DATA_BEATS_ID_11"/>
+	<value value="76" name="AXI_WRITE_DATA_BEATS_ID_12"/>
+	<value value="77" name="AXI_WRITE_DATA_BEATS_ID_13"/>
+	<value value="78" name="AXI_WRITE_DATA_BEATS_ID_14"/>
+	<value value="79" name="AXI_WRITE_DATA_BEATS_ID_15"/>
+	<value value="80" name="AXI0_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="81" name="AXI1_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="82" name="AXI2_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="83" name="AXI3_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="84" name="AXI_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="85" name="AXI_DATA_BEATS_TOTAL"/>
+	<value value="86" name="CYCLES_HELD_OFF_ID_0"/>
+	<value value="87" name="CYCLES_HELD_OFF_ID_1"/>
+	<value value="88" name="CYCLES_HELD_OFF_ID_2"/>
+	<value value="89" name="CYCLES_HELD_OFF_ID_3"/>
+	<value value="90" name="CYCLES_HELD_OFF_ID_4"/>
+	<value value="91" name="CYCLES_HELD_OFF_ID_5"/>
+	<value value="92" name="CYCLES_HELD_OFF_ID_6"/>
+	<value value="93" name="CYCLES_HELD_OFF_ID_7"/>
+	<value value="94" name="CYCLES_HELD_OFF_ID_8"/>
+	<value value="95" name="CYCLES_HELD_OFF_ID_9"/>
+	<value value="96" name="CYCLES_HELD_OFF_ID_10"/>
+	<value value="97" name="CYCLES_HELD_OFF_ID_11"/>
+	<value value="98" name="CYCLES_HELD_OFF_ID_12"/>
+	<value value="99" name="CYCLES_HELD_OFF_ID_13"/>
+	<value value="100" name="CYCLES_HELD_OFF_ID_14"/>
+	<value value="101" name="CYCLES_HELD_OFF_ID_15"/>
+	<value value="102" name="AXI_READ_REQUEST_HELD_OFF"/>
+	<value value="103" name="AXI_WRITE_REQUEST_HELD_OFF"/>
+	<value value="104" name="AXI_REQUEST_HELD_OFF"/>
+	<value value="105" name="AXI_WRITE_DATA_HELD_OFF"/>
+	<value value="106" name="OCMEM_AXI_READ_REQUEST_HELD_OFF"/>
+	<value value="107" name="OCMEM_AXI_WRITE_REQUEST_HELD_OFF"/>
+	<value value="108" name="OCMEM_AXI_REQUEST_HELD_OFF"/>
+	<value value="109" name="OCMEM_AXI_WRITE_DATA_HELD_OFF"/>
+	<value value="110" name="ELAPSED_CYCLES_DDR"/>
+	<value value="111" name="ELAPSED_CYCLES_OCMEM"/>
+</enum>
+
+<enum name="a4xx_vfd_perfcounter_select">
+	<value value="0" name="VFD_UCHE_BYTE_FETCHED"/>
+	<value value="1" name="VFD_UCHE_TRANS"/>
+	<value value="3" name="VFD_FETCH_INSTRUCTIONS"/>
+	<value value="5" name="VFD_BUSY_CYCLES"/>
+	<value value="6" name="VFD_STALL_CYCLES_UCHE"/>
+	<value value="7" name="VFD_STALL_CYCLES_HLSQ"/>
+	<value value="8" name="VFD_STALL_CYCLES_VPC_BYPASS"/>
+	<value value="9" name="VFD_STALL_CYCLES_VPC_ALLOC"/>
+	<value value="13" name="VFD_MODE_0_FIBERS"/>
+	<value value="14" name="VFD_MODE_1_FIBERS"/>
+	<value value="15" name="VFD_MODE_2_FIBERS"/>
+	<value value="16" name="VFD_MODE_3_FIBERS"/>
+	<value value="17" name="VFD_MODE_4_FIBERS"/>
+	<value value="18" name="VFD_BFIFO_STALL"/>
+	<value value="19" name="VFD_NUM_VERTICES_TOTAL"/>
+	<value value="20" name="VFD_PACKER_FULL"/>
+	<value value="21" name="VFD_UCHE_REQUEST_FIFO_FULL"/>
+	<value value="22" name="VFD_STARVE_CYCLES_PC"/>
+	<value value="23" name="VFD_STARVE_CYCLES_UCHE"/>
+</enum>
+
+<enum name="a4xx_vpc_perfcounter_select">
+	<value value="2" name="VPC_SP_LM_COMPONENTS"/>
+	<value value="3" name="VPC_SP0_LM_BYTES"/>
+	<value value="4" name="VPC_SP1_LM_BYTES"/>
+	<value value="5" name="VPC_SP2_LM_BYTES"/>
+	<value value="6" name="VPC_SP3_LM_BYTES"/>
+	<value value="7" name="VPC_WORKING_CYCLES"/>
+	<value value="8" name="VPC_STALL_CYCLES_LM"/>
+	<value value="9" name="VPC_STARVE_CYCLES_RAS"/>
+	<value value="10" name="VPC_STREAMOUT_CYCLES"/>
+	<value value="12" name="VPC_UCHE_TRANSACTIONS"/>
+	<value value="13" name="VPC_STALL_CYCLES_UCHE"/>
+	<value value="14" name="VPC_BUSY_CYCLES"/>
+	<value value="15" name="VPC_STARVE_CYCLES_SP"/>
+</enum>
+
+<enum name="a4xx_vsc_perfcounter_select">
+	<value value="0" name="VSC_BUSY_CYCLES"/>
+	<value value="1" name="VSC_WORKING_CYCLES"/>
+	<value value="2" name="VSC_STALL_CYCLES_UCHE"/>
+	<value value="3" name="VSC_STARVE_CYCLES_RAS"/>
+	<value value="4" name="VSC_EOT_NUM"/>
+</enum>
+
+<domain name="A4XX" width="32">
+	<!-- RB registers -->
+	<reg32 offset="0x0cc0" name="RB_GMEM_BASE_ADDR"/>
+	<reg32 offset="0x0cc7" name="RB_PERFCTR_RB_SEL_0" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cc8" name="RB_PERFCTR_RB_SEL_1" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cc9" name="RB_PERFCTR_RB_SEL_2" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cca" name="RB_PERFCTR_RB_SEL_3" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0ccb" name="RB_PERFCTR_RB_SEL_4" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0ccc" name="RB_PERFCTR_RB_SEL_5" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0ccd" name="RB_PERFCTR_RB_SEL_6" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cce" name="RB_PERFCTR_RB_SEL_7" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0ccf" name="RB_PERFCTR_CCU_SEL_0" type="a4xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0cd0" name="RB_PERFCTR_CCU_SEL_1" type="a4xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0cd1" name="RB_PERFCTR_CCU_SEL_2" type="a4xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0cd2" name="RB_PERFCTR_CCU_SEL_3" type="a4xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0ce0" name="RB_FRAME_BUFFER_DIMENSION">
+		<bitfield name="WIDTH" low="0" high="13" type="uint"/>
+		<bitfield name="HEIGHT" low="16" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="0x20cc" name="RB_CLEAR_COLOR_DW0"/>
+	<reg32 offset="0x20cd" name="RB_CLEAR_COLOR_DW1"/>
+	<reg32 offset="0x20ce" name="RB_CLEAR_COLOR_DW2"/>
+	<reg32 offset="0x20cf" name="RB_CLEAR_COLOR_DW3"/>
+	<reg32 offset="0x20a0" name="RB_MODE_CONTROL">
+		<!--
+		for non-bypass mode, these are bin width/height..  although
+		possibly bigger bitfields to hold entire width/height for
+		gmem-bypass??  Either way, it appears to need to be multiple
+		of 32..
+		-->
+		<bitfield name="WIDTH" low="0" high="5" shr="5" type="uint"/>
+		<bitfield name="HEIGHT" low="8" high="13" shr="5" type="uint"/>
+		<bitfield name="ENABLE_GMEM" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x20a1" name="RB_RENDER_CONTROL">
+		<bitfield name="BINNING_PASS" pos="0" type="boolean"/>
+		<!-- nearly everything has bit3 set.. -->
+		<!-- bit5 set on resolve and tiling pass -->
+		<bitfield name="DISABLE_COLOR_PIPE" pos="5" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x20a2" name="RB_MSAA_CONTROL">
+		<bitfield name="DISABLE" pos="12" type="boolean"/>
+		<bitfield name="SAMPLES" low="13" high="15" type="uint"/>
+	</reg32>
+	<reg32 offset="0x20a3" name="RB_RENDER_CONTROL2">
+		<bitfield name="COORD_MASK" low="0" high="3" type="hex"/>
+		<bitfield name="SAMPLEMASK" pos="4" type="boolean"/>
+		<bitfield name="FACENESS" pos="5" type="boolean"/>
+		<bitfield name="SAMPLEID" pos="6" type="boolean"/>
+		<bitfield name="MSAA_SAMPLES" low="7" high="9" type="uint"/>
+		<bitfield name="SAMPLEID_HR" pos="11" type="boolean"/>
+		<bitfield name="IJ_PERSP_PIXEL" pos="12" type="boolean"/>
+		<!-- the 2 below are just educated guesses -->
+		<bitfield name="IJ_PERSP_CENTROID" pos="13" type="boolean"/>
+		<bitfield name="IJ_PERSP_SAMPLE" pos="14" type="boolean"/>
+		<!-- needs to be enabled to get nopersp values,
+		     perhaps other cases too? -->
+		<bitfield name="SIZE" pos="15" type="boolean"/>
+	</reg32>
+	<array offset="0x20a4" name="RB_MRT" stride="5" length="8">
+		<reg32 offset="0x0" name="CONTROL">
+			<bitfield name="READ_DEST_ENABLE" pos="3" type="boolean"/>
+			<!-- both these bits seem to get set when enabling GL_BLEND.. -->
+			<bitfield name="BLEND" pos="4" type="boolean"/>
+			<bitfield name="BLEND2" pos="5" type="boolean"/>
+			<bitfield name="ROP_ENABLE" pos="6" type="boolean"/>
+			<bitfield name="ROP_CODE" low="8" high="11" type="a3xx_rop_code"/>
+			<bitfield name="COMPONENT_ENABLE" low="24" high="27" type="hex"/>
+		</reg32>
+		<reg32 offset="0x1" name="BUF_INFO">
+			<bitfield name="COLOR_FORMAT" low="0" high="5" type="a4xx_color_fmt"/>
+			<!--
+			    guestimate position of COLOR_TILE_MODE..  this works out if
+			    common value is 2, like on a3xx..
+			 -->
+			<bitfield name="COLOR_TILE_MODE" low="6" high="7" type="a4xx_tile_mode"/>
+			<bitfield name="DITHER_MODE" low="9" high="10" type="adreno_rb_dither_mode"/>
+			<bitfield name="COLOR_SWAP" low="11" high="12" type="a3xx_color_swap"/>
+			<bitfield name="COLOR_SRGB" pos="13" type="boolean"/>
+			<!-- note: possibly some # of lsb's aren't there: -->
+			<doc>
+				Pitch (actually, appears to be pitch in bytes, so really is a stride)
+				in GMEM, so pitch of the current tile.
+			</doc>
+			<bitfield name="COLOR_BUF_PITCH" low="14" high="31" shr="4" type="uint"/>
+		</reg32>
+		<reg32 offset="0x2" name="BASE"/>
+		<reg32 offset="0x3" name="CONTROL3">
+			<!-- probably missing some lsb's.. and guessing upper size -->
+			<!-- pitch * cpp * msaa: -->
+			<bitfield name="STRIDE" low="3" high="25" type="uint"/>
+		</reg32>
+		<reg32 offset="0x4" name="BLEND_CONTROL">
+			<bitfield name="RGB_SRC_FACTOR" low="0" high="4" type="adreno_rb_blend_factor"/>
+			<bitfield name="RGB_BLEND_OPCODE" low="5" high="7" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="RGB_DEST_FACTOR" low="8" high="12" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_SRC_FACTOR" low="16" high="20" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_BLEND_OPCODE" low="21" high="23" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="ALPHA_DEST_FACTOR" low="24" high="28" type="adreno_rb_blend_factor"/>
+		</reg32>
+	</array>
+
+	<reg32 offset="0x20f0" name="RB_BLEND_RED">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0x20f1" name="RB_BLEND_RED_F32" type="float"/>
+
+	<reg32 offset="0x20f2" name="RB_BLEND_GREEN">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0x20f3" name="RB_BLEND_GREEN_F32" type="float"/>
+
+	<reg32 offset="0x20f4" name="RB_BLEND_BLUE">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0x20f5" name="RB_BLEND_BLUE_F32" type="float"/>
+
+	<reg32 offset="0x20f6" name="RB_BLEND_ALPHA">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0x20f7" name="RB_BLEND_ALPHA_F32" type="float"/>
+
+	<reg32 offset="0x20f8" name="RB_ALPHA_CONTROL">
+		<bitfield name="ALPHA_REF" low="0" high="7" type="hex"/>
+		<bitfield name="ALPHA_TEST" pos="8" type="boolean"/>
+		<bitfield name="ALPHA_TEST_FUNC" low="9" high="11" type="adreno_compare_func"/>
+	</reg32>
+	<reg32 offset="0x20f9" name="RB_FS_OUTPUT">
+		<!-- per-mrt enable bit -->
+		<bitfield name="ENABLE_BLEND" low="0" high="7"/>
+		<bitfield name="INDEPENDENT_BLEND" pos="8" type="boolean"/>
+		<!-- a guess? -->
+		<bitfield name="SAMPLE_MASK" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="0x20fa" name="RB_SAMPLE_COUNT_CONTROL">
+		<bitfield name="COPY" pos="1" type="boolean"/>
+		<bitfield name="ADDR" low="2" high="31" shr="2"/>
+	</reg32>
+	<!-- always 00000000 for binning pass, else 0000000f: -->
+	<reg32 offset="0x20fb" name="RB_RENDER_COMPONENTS">
+		<bitfield name="RT0" low="0" high="3"/>
+		<bitfield name="RT1" low="4" high="7"/>
+		<bitfield name="RT2" low="8" high="11"/>
+		<bitfield name="RT3" low="12" high="15"/>
+		<bitfield name="RT4" low="16" high="19"/>
+		<bitfield name="RT5" low="20" high="23"/>
+		<bitfield name="RT6" low="24" high="27"/>
+		<bitfield name="RT7" low="28" high="31"/>
+	</reg32>
+
+	<reg32 offset="0x20fc" name="RB_COPY_CONTROL">
+		<!-- not sure # of bits -->
+		<bitfield name="MSAA_RESOLVE" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="MODE" low="4" high="6" type="adreno_rb_copy_control_mode"/>
+		<bitfield name="FASTCLEAR" low="8" high="11" type="hex"/>
+		<bitfield name="GMEM_BASE" low="14" high="31" shr="14" type="hex"/>
+	</reg32>
+	<reg32 offset="0x20fd" name="RB_COPY_DEST_BASE">
+		<bitfield name="BASE" low="5" high="31" shr="5" type="hex"/>
+	</reg32>
+	<reg32 offset="0x20fe" name="RB_COPY_DEST_PITCH">
+		<doc>actually, appears to be pitch in bytes, so really is a stride</doc>
+		<!-- not actually sure about max pitch... -->
+		<bitfield name="PITCH" low="0" high="31" shr="5" type="uint"/>
+	</reg32>
+	<reg32 offset="0x20ff" name="RB_COPY_DEST_INFO">
+		<bitfield name="FORMAT" low="2" high="7" type="a4xx_color_fmt"/>
+		<bitfield name="SWAP" low="8" high="9" type="a3xx_color_swap"/>
+		<bitfield name="DITHER_MODE" low="10" high="11" type="adreno_rb_dither_mode"/>
+		<bitfield name="COMPONENT_ENABLE" low="14" high="17" type="hex"/>
+		<bitfield name="ENDIAN" low="18" high="20" type="adreno_rb_surface_endian"/>
+		<bitfield name="TILE" low="24" high="25" type="a4xx_tile_mode"/>
+	</reg32>
+	<reg32 offset="0x2100" name="RB_FS_OUTPUT_REG">
+		<!-- bit0 set except for binning pass.. -->
+		<bitfield name="MRT" low="0" high="3" type="uint"/>
+		<bitfield name="FRAG_WRITES_Z" pos="5" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2101" name="RB_DEPTH_CONTROL">
+		<!--
+			guessing that this matches a2xx with the stencil fields
+			moved out into RB_STENCIL_CONTROL?
+		 -->
+		<bitfield name="FRAG_WRITES_Z" pos="0" type="boolean"/>
+		<bitfield name="Z_TEST_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="Z_WRITE_ENABLE" pos="2" type="boolean"/>
+		<bitfield name="ZFUNC" low="4" high="6" type="adreno_compare_func"/>
+		<bitfield name="Z_CLAMP_ENABLE" pos="7" type="boolean"/>
+		<bitfield name="EARLY_Z_DISABLE" pos="16" type="boolean"/>
+		<bitfield name="FORCE_FRAGZ_TO_FS" pos="17" type="boolean"/>
+		<doc>Z_READ_ENABLE bit is set for zfunc other than GL_ALWAYS or GL_NEVER</doc>
+		<bitfield name="Z_READ_ENABLE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2102" name="RB_DEPTH_CLEAR"/>
+	<reg32 offset="0x2103" name="RB_DEPTH_INFO">
+		<bitfield name="DEPTH_FORMAT" low="0" high="1" type="a4xx_depth_format"/>
+		<doc>
+			DEPTH_BASE is offset in GMEM to depth/stencil buffer, ie
+			bin_w * bin_h / 1024 (possible rounded up to multiple of
+			something??  ie. 39 becomes 40, 78 becomes 80.. 75 becomes
+			80.. so maybe it needs to be multiple of 8??
+		</doc>
+		<bitfield name="DEPTH_BASE" low="12" high="31" shr="12" type="hex"/>
+	</reg32>
+	<reg32 offset="0x2104" name="RB_DEPTH_PITCH" shr="5" type="uint">
+		<doc>stride of depth/stencil buffer</doc>
+	</reg32>
+	<reg32 offset="0x2105" name="RB_DEPTH_PITCH2" shr="5" type="uint">
+		<doc>???</doc>
+	</reg32>
+	<reg32 offset="0x2106" name="RB_STENCIL_CONTROL">
+		<bitfield name="STENCIL_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="STENCIL_ENABLE_BF" pos="1" type="boolean"/>
+		<!--
+			set for stencil operations that require read from stencil
+			buffer, but not for example for stencil clear (which does
+			not require read).. so guessing this is analogous to
+			READ_DEST_ENABLE for color buffer..
+		 -->
+		<bitfield name="STENCIL_READ" pos="2" type="boolean"/>
+		<bitfield name="FUNC" low="8" high="10" type="adreno_compare_func"/>
+		<bitfield name="FAIL" low="11" high="13" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS" low="14" high="16" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL" low="17" high="19" type="adreno_stencil_op"/>
+		<bitfield name="FUNC_BF" low="20" high="22" type="adreno_compare_func"/>
+		<bitfield name="FAIL_BF" low="23" high="25" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS_BF" low="26" high="28" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL_BF" low="29" high="31" type="adreno_stencil_op"/>
+	</reg32>
+	<reg32 offset="0x2107" name="RB_STENCIL_CONTROL2">
+		<!--
+		This seems to be set by blob if there is a stencil buffer
+		at all in GMEM, regardless of whether it is enabled for
+		a particular draw (ie. RB_STENCIL_CONTROL).  Not really
+		sure if that is required or just a quirk of the blob
+		-->
+		<bitfield name="STENCIL_BUFFER" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2108" name="RB_STENCIL_INFO">
+		<bitfield name="SEPARATE_STENCIL" pos="0" type="boolean"/>
+		<doc>Base address for stencil when not using interleaved depth/stencil</doc>
+		<bitfield name="STENCIL_BASE" low="12" high="31" shr="12" type="hex"/>
+	</reg32>
+	<reg32 offset="0x2109" name="RB_STENCIL_PITCH" shr="5" type="uint">
+		<doc>pitch of stencil buffer when not using interleaved depth/stencil</doc>
+	</reg32>
+
+	<reg32 offset="0x210b" name="RB_STENCILREFMASK" type="adreno_rb_stencilrefmask"/>
+	<reg32 offset="0x210c" name="RB_STENCILREFMASK_BF" type="adreno_rb_stencilrefmask"/>
+	<reg32 offset="0x210d" name="RB_BIN_OFFSET" type="adreno_reg_xy"/>
+	<array offset="0x2120" name="RB_VPORT_Z_CLAMP" stride="2" length="16">
+		<reg32 offset="0x0" name="MIN"/>
+		<reg32 offset="0x1" name="MAX"/>
+	</array>
+
+	<!-- RBBM registers -->
+	<reg32 offset="0x0000" name="RBBM_HW_VERSION"/>
+	<reg32 offset="0x0002" name="RBBM_HW_CONFIGURATION"/>
+	<array offset="0x4" name="RBBM_CLOCK_CTL_TP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x8" name="RBBM_CLOCK_CTL2_TP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0xc" name="RBBM_CLOCK_HYST_TP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x10" name="RBBM_CLOCK_DELAY_TP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<reg32 offset="0x0014" name="RBBM_CLOCK_CTL_UCHE "/>
+	<reg32 offset="0x0015" name="RBBM_CLOCK_CTL2_UCHE"/>
+	<reg32 offset="0x0016" name="RBBM_CLOCK_CTL3_UCHE"/>
+	<reg32 offset="0x0017" name="RBBM_CLOCK_CTL4_UCHE"/>
+	<reg32 offset="0x0018" name="RBBM_CLOCK_HYST_UCHE"/>
+	<reg32 offset="0x0019" name="RBBM_CLOCK_DELAY_UCHE"/>
+	<reg32 offset="0x001a" name="RBBM_CLOCK_MODE_GPC"/>
+	<reg32 offset="0x001b" name="RBBM_CLOCK_DELAY_GPC"/>
+	<reg32 offset="0x001c" name="RBBM_CLOCK_HYST_GPC"/>
+	<reg32 offset="0x001d" name="RBBM_CLOCK_CTL_TSE_RAS_RBBM"/>
+	<reg32 offset="0x001e" name="RBBM_CLOCK_HYST_TSE_RAS_RBBM"/>
+	<reg32 offset="0x001f" name="RBBM_CLOCK_DELAY_TSE_RAS_RBBM"/>
+	<reg32 offset="0x0020" name="RBBM_CLOCK_CTL"/>
+	<reg32 offset="0x0021" name="RBBM_SP_HYST_CNT"/>
+	<reg32 offset="0x0022" name="RBBM_SW_RESET_CMD"/>
+	<reg32 offset="0x0023" name="RBBM_AHB_CTL0"/>
+	<reg32 offset="0x0024" name="RBBM_AHB_CTL1"/>
+	<reg32 offset="0x0025" name="RBBM_AHB_CMD"/>
+	<reg32 offset="0x0026" name="RBBM_RB_SUB_BLOCK_SEL_CTL"/>
+	<reg32 offset="0x0028" name="RBBM_RAM_ACC_63_32"/>
+	<reg32 offset="0x002b" name="RBBM_WAIT_IDLE_CLOCKS_CTL"/>
+	<reg32 offset="0x002f" name="RBBM_INTERFACE_HANG_INT_CTL"/>
+	<reg32 offset="0x0034" name="RBBM_INTERFACE_HANG_MASK_CTL4"/>
+	<reg32 offset="0x0036" name="RBBM_INT_CLEAR_CMD"/>
+	<reg32 offset="0x0037" name="RBBM_INT_0_MASK"/>
+	<reg32 offset="0x003e" name="RBBM_RBBM_CTL"/>
+	<reg32 offset="0x003f" name="RBBM_AHB_DEBUG_CTL"/>
+	<reg32 offset="0x0041" name="RBBM_VBIF_DEBUG_CTL"/>
+	<reg32 offset="0x0042" name="RBBM_CLOCK_CTL2"/>
+	<reg32 offset="0x0045" name="RBBM_BLOCK_SW_RESET_CMD"/>
+	<reg32 offset="0x0047" name="RBBM_RESET_CYCLES"/>
+	<reg32 offset="0x0049" name="RBBM_EXT_TRACE_BUS_CTL"/>
+	<reg32 offset="0x004a" name="RBBM_CFG_DEBBUS_SEL_A"/>
+	<reg32 offset="0x004b" name="RBBM_CFG_DEBBUS_SEL_B"/>
+	<reg32 offset="0x004c" name="RBBM_CFG_DEBBUS_SEL_C"/>
+	<reg32 offset="0x004d" name="RBBM_CFG_DEBBUS_SEL_D"/>
+	<reg32 offset="0x0098" name="RBBM_POWER_CNTL_IP">
+		<bitfield name="SW_COLLAPSE" pos="0" type="boolean"/>
+		<bitfield name="SP_TP_PWR_ON" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x009c" name="RBBM_PERFCTR_CP_0_LO"/>
+	<reg32 offset="0x009d" name="RBBM_PERFCTR_CP_0_HI"/>
+	<reg32 offset="0x009e" name="RBBM_PERFCTR_CP_1_LO"/>
+	<reg32 offset="0x009f" name="RBBM_PERFCTR_CP_1_HI"/>
+	<reg32 offset="0x00a0" name="RBBM_PERFCTR_CP_2_LO"/>
+	<reg32 offset="0x00a1" name="RBBM_PERFCTR_CP_2_HI"/>
+	<reg32 offset="0x00a2" name="RBBM_PERFCTR_CP_3_LO"/>
+	<reg32 offset="0x00a3" name="RBBM_PERFCTR_CP_3_HI"/>
+	<reg32 offset="0x00a4" name="RBBM_PERFCTR_CP_4_LO"/>
+	<reg32 offset="0x00a5" name="RBBM_PERFCTR_CP_4_HI"/>
+	<reg32 offset="0x00a6" name="RBBM_PERFCTR_CP_5_LO"/>
+	<reg32 offset="0x00a7" name="RBBM_PERFCTR_CP_5_HI"/>
+	<reg32 offset="0x00a8" name="RBBM_PERFCTR_CP_6_LO"/>
+	<reg32 offset="0x00a9" name="RBBM_PERFCTR_CP_6_HI"/>
+	<reg32 offset="0x00aa" name="RBBM_PERFCTR_CP_7_LO"/>
+	<reg32 offset="0x00ab" name="RBBM_PERFCTR_CP_7_HI"/>
+	<reg32 offset="0x00ac" name="RBBM_PERFCTR_RBBM_0_LO"/>
+	<reg32 offset="0x00ad" name="RBBM_PERFCTR_RBBM_0_HI"/>
+	<reg32 offset="0x00ae" name="RBBM_PERFCTR_RBBM_1_LO"/>
+	<reg32 offset="0x00af" name="RBBM_PERFCTR_RBBM_1_HI"/>
+	<reg32 offset="0x00b0" name="RBBM_PERFCTR_RBBM_2_LO"/>
+	<reg32 offset="0x00b1" name="RBBM_PERFCTR_RBBM_2_HI"/>
+	<reg32 offset="0x00b2" name="RBBM_PERFCTR_RBBM_3_LO"/>
+	<reg32 offset="0x00b3" name="RBBM_PERFCTR_RBBM_3_HI"/>
+	<reg32 offset="0x00b4" name="RBBM_PERFCTR_PC_0_LO"/>
+	<reg32 offset="0x00b5" name="RBBM_PERFCTR_PC_0_HI"/>
+	<reg32 offset="0x00b6" name="RBBM_PERFCTR_PC_1_LO"/>
+	<reg32 offset="0x00b7" name="RBBM_PERFCTR_PC_1_HI"/>
+	<reg32 offset="0x00b8" name="RBBM_PERFCTR_PC_2_LO"/>
+	<reg32 offset="0x00b9" name="RBBM_PERFCTR_PC_2_HI"/>
+	<reg32 offset="0x00ba" name="RBBM_PERFCTR_PC_3_LO"/>
+	<reg32 offset="0x00bb" name="RBBM_PERFCTR_PC_3_HI"/>
+	<reg32 offset="0x00bc" name="RBBM_PERFCTR_PC_4_LO"/>
+	<reg32 offset="0x00bd" name="RBBM_PERFCTR_PC_4_HI"/>
+	<reg32 offset="0x00be" name="RBBM_PERFCTR_PC_5_LO"/>
+	<reg32 offset="0x00bf" name="RBBM_PERFCTR_PC_5_HI"/>
+	<reg32 offset="0x00c0" name="RBBM_PERFCTR_PC_6_LO"/>
+	<reg32 offset="0x00c1" name="RBBM_PERFCTR_PC_6_HI"/>
+	<reg32 offset="0x00c2" name="RBBM_PERFCTR_PC_7_LO"/>
+	<reg32 offset="0x00c3" name="RBBM_PERFCTR_PC_7_HI"/>
+	<reg32 offset="0x00c4" name="RBBM_PERFCTR_VFD_0_LO"/>
+	<reg32 offset="0x00c5" name="RBBM_PERFCTR_VFD_0_HI"/>
+	<reg32 offset="0x00c6" name="RBBM_PERFCTR_VFD_1_LO"/>
+	<reg32 offset="0x00c7" name="RBBM_PERFCTR_VFD_1_HI"/>
+	<reg32 offset="0x00c8" name="RBBM_PERFCTR_VFD_2_LO"/>
+	<reg32 offset="0x00c9" name="RBBM_PERFCTR_VFD_2_HI"/>
+	<reg32 offset="0x00ca" name="RBBM_PERFCTR_VFD_3_LO"/>
+	<reg32 offset="0x00cb" name="RBBM_PERFCTR_VFD_3_HI"/>
+	<reg32 offset="0x00cc" name="RBBM_PERFCTR_VFD_4_LO"/>
+	<reg32 offset="0x00cd" name="RBBM_PERFCTR_VFD_4_HI"/>
+	<reg32 offset="0x00ce" name="RBBM_PERFCTR_VFD_5_LO"/>
+	<reg32 offset="0x00cf" name="RBBM_PERFCTR_VFD_5_HI"/>
+	<reg32 offset="0x00d0" name="RBBM_PERFCTR_VFD_6_LO"/>
+	<reg32 offset="0x00d1" name="RBBM_PERFCTR_VFD_6_HI"/>
+	<reg32 offset="0x00d2" name="RBBM_PERFCTR_VFD_7_LO"/>
+	<reg32 offset="0x00d3" name="RBBM_PERFCTR_VFD_7_HI"/>
+	<reg32 offset="0x00d4" name="RBBM_PERFCTR_HLSQ_0_LO"/>
+	<reg32 offset="0x00d5" name="RBBM_PERFCTR_HLSQ_0_HI"/>
+	<reg32 offset="0x00d6" name="RBBM_PERFCTR_HLSQ_1_LO"/>
+	<reg32 offset="0x00d7" name="RBBM_PERFCTR_HLSQ_1_HI"/>
+	<reg32 offset="0x00d8" name="RBBM_PERFCTR_HLSQ_2_LO"/>
+	<reg32 offset="0x00d9" name="RBBM_PERFCTR_HLSQ_2_HI"/>
+	<reg32 offset="0x00da" name="RBBM_PERFCTR_HLSQ_3_LO"/>
+	<reg32 offset="0x00db" name="RBBM_PERFCTR_HLSQ_3_HI"/>
+	<reg32 offset="0x00dc" name="RBBM_PERFCTR_HLSQ_4_LO"/>
+	<reg32 offset="0x00dd" name="RBBM_PERFCTR_HLSQ_4_HI"/>
+	<reg32 offset="0x00de" name="RBBM_PERFCTR_HLSQ_5_LO"/>
+	<reg32 offset="0x00df" name="RBBM_PERFCTR_HLSQ_5_HI"/>
+	<reg32 offset="0x00e0" name="RBBM_PERFCTR_HLSQ_6_LO"/>
+	<reg32 offset="0x00e1" name="RBBM_PERFCTR_HLSQ_6_HI"/>
+	<reg32 offset="0x00e2" name="RBBM_PERFCTR_HLSQ_7_LO"/>
+	<reg32 offset="0x00e3" name="RBBM_PERFCTR_HLSQ_7_HI"/>
+	<reg32 offset="0x00e4" name="RBBM_PERFCTR_VPC_0_LO"/>
+	<reg32 offset="0x00e5" name="RBBM_PERFCTR_VPC_0_HI"/>
+	<reg32 offset="0x00e6" name="RBBM_PERFCTR_VPC_1_LO"/>
+	<reg32 offset="0x00e7" name="RBBM_PERFCTR_VPC_1_HI"/>
+	<reg32 offset="0x00e8" name="RBBM_PERFCTR_VPC_2_LO"/>
+	<reg32 offset="0x00e9" name="RBBM_PERFCTR_VPC_2_HI"/>
+	<reg32 offset="0x00ea" name="RBBM_PERFCTR_VPC_3_LO"/>
+	<reg32 offset="0x00eb" name="RBBM_PERFCTR_VPC_3_HI"/>
+	<reg32 offset="0x00ec" name="RBBM_PERFCTR_CCU_0_LO"/>
+	<reg32 offset="0x00ed" name="RBBM_PERFCTR_CCU_0_HI"/>
+	<reg32 offset="0x00ee" name="RBBM_PERFCTR_CCU_1_LO"/>
+	<reg32 offset="0x00ef" name="RBBM_PERFCTR_CCU_1_HI"/>
+	<reg32 offset="0x00f0" name="RBBM_PERFCTR_CCU_2_LO"/>
+	<reg32 offset="0x00f1" name="RBBM_PERFCTR_CCU_2_HI"/>
+	<reg32 offset="0x00f2" name="RBBM_PERFCTR_CCU_3_LO"/>
+	<reg32 offset="0x00f3" name="RBBM_PERFCTR_CCU_3_HI"/>
+	<reg32 offset="0x00f4" name="RBBM_PERFCTR_TSE_0_LO"/>
+	<reg32 offset="0x00f5" name="RBBM_PERFCTR_TSE_0_HI"/>
+	<reg32 offset="0x00f6" name="RBBM_PERFCTR_TSE_1_LO"/>
+	<reg32 offset="0x00f7" name="RBBM_PERFCTR_TSE_1_HI"/>
+	<reg32 offset="0x00f8" name="RBBM_PERFCTR_TSE_2_LO"/>
+	<reg32 offset="0x00f9" name="RBBM_PERFCTR_TSE_2_HI"/>
+	<reg32 offset="0x00fa" name="RBBM_PERFCTR_TSE_3_LO"/>
+	<reg32 offset="0x00fb" name="RBBM_PERFCTR_TSE_3_HI"/>
+	<reg32 offset="0x00fc" name="RBBM_PERFCTR_RAS_0_LO"/>
+	<reg32 offset="0x00fd" name="RBBM_PERFCTR_RAS_0_HI"/>
+	<reg32 offset="0x00fe" name="RBBM_PERFCTR_RAS_1_LO"/>
+	<reg32 offset="0x00ff" name="RBBM_PERFCTR_RAS_1_HI"/>
+	<reg32 offset="0x0100" name="RBBM_PERFCTR_RAS_2_LO"/>
+	<reg32 offset="0x0101" name="RBBM_PERFCTR_RAS_2_HI"/>
+	<reg32 offset="0x0102" name="RBBM_PERFCTR_RAS_3_LO"/>
+	<reg32 offset="0x0103" name="RBBM_PERFCTR_RAS_3_HI"/>
+	<reg32 offset="0x0104" name="RBBM_PERFCTR_UCHE_0_LO"/>
+	<reg32 offset="0x0105" name="RBBM_PERFCTR_UCHE_0_HI"/>
+	<reg32 offset="0x0106" name="RBBM_PERFCTR_UCHE_1_LO"/>
+	<reg32 offset="0x0107" name="RBBM_PERFCTR_UCHE_1_HI"/>
+	<reg32 offset="0x0108" name="RBBM_PERFCTR_UCHE_2_LO"/>
+	<reg32 offset="0x0109" name="RBBM_PERFCTR_UCHE_2_HI"/>
+	<reg32 offset="0x010a" name="RBBM_PERFCTR_UCHE_3_LO"/>
+	<reg32 offset="0x010b" name="RBBM_PERFCTR_UCHE_3_HI"/>
+	<reg32 offset="0x010c" name="RBBM_PERFCTR_UCHE_4_LO"/>
+	<reg32 offset="0x010d" name="RBBM_PERFCTR_UCHE_4_HI"/>
+	<reg32 offset="0x010e" name="RBBM_PERFCTR_UCHE_5_LO"/>
+	<reg32 offset="0x010f" name="RBBM_PERFCTR_UCHE_5_HI"/>
+	<reg32 offset="0x0110" name="RBBM_PERFCTR_UCHE_6_LO"/>
+	<reg32 offset="0x0111" name="RBBM_PERFCTR_UCHE_6_HI"/>
+	<reg32 offset="0x0112" name="RBBM_PERFCTR_UCHE_7_LO"/>
+	<reg32 offset="0x0113" name="RBBM_PERFCTR_UCHE_7_HI"/>
+	<reg32 offset="0x0114" name="RBBM_PERFCTR_TP_0_LO"/>
+	<reg32 offset="0x0115" name="RBBM_PERFCTR_TP_0_HI"/>
+	<reg32 offset="0x0116" name="RBBM_PERFCTR_TP_1_LO"/>
+	<reg32 offset="0x0117" name="RBBM_PERFCTR_TP_1_HI"/>
+	<reg32 offset="0x0118" name="RBBM_PERFCTR_TP_2_LO"/>
+	<reg32 offset="0x0119" name="RBBM_PERFCTR_TP_2_HI"/>
+	<reg32 offset="0x011a" name="RBBM_PERFCTR_TP_3_LO"/>
+	<reg32 offset="0x011b" name="RBBM_PERFCTR_TP_3_HI"/>
+	<reg32 offset="0x011c" name="RBBM_PERFCTR_TP_4_LO"/>
+	<reg32 offset="0x011d" name="RBBM_PERFCTR_TP_4_HI"/>
+	<reg32 offset="0x011e" name="RBBM_PERFCTR_TP_5_LO"/>
+	<reg32 offset="0x011f" name="RBBM_PERFCTR_TP_5_HI"/>
+	<reg32 offset="0x0120" name="RBBM_PERFCTR_TP_6_LO"/>
+	<reg32 offset="0x0121" name="RBBM_PERFCTR_TP_6_HI"/>
+	<reg32 offset="0x0122" name="RBBM_PERFCTR_TP_7_LO"/>
+	<reg32 offset="0x0123" name="RBBM_PERFCTR_TP_7_HI"/>
+	<reg32 offset="0x0124" name="RBBM_PERFCTR_SP_0_LO"/>
+	<reg32 offset="0x0125" name="RBBM_PERFCTR_SP_0_HI"/>
+	<reg32 offset="0x0126" name="RBBM_PERFCTR_SP_1_LO"/>
+	<reg32 offset="0x0127" name="RBBM_PERFCTR_SP_1_HI"/>
+	<reg32 offset="0x0128" name="RBBM_PERFCTR_SP_2_LO"/>
+	<reg32 offset="0x0129" name="RBBM_PERFCTR_SP_2_HI"/>
+	<reg32 offset="0x012a" name="RBBM_PERFCTR_SP_3_LO"/>
+	<reg32 offset="0x012b" name="RBBM_PERFCTR_SP_3_HI"/>
+	<reg32 offset="0x012c" name="RBBM_PERFCTR_SP_4_LO"/>
+	<reg32 offset="0x012d" name="RBBM_PERFCTR_SP_4_HI"/>
+	<reg32 offset="0x012e" name="RBBM_PERFCTR_SP_5_LO"/>
+	<reg32 offset="0x012f" name="RBBM_PERFCTR_SP_5_HI"/>
+	<reg32 offset="0x0130" name="RBBM_PERFCTR_SP_6_LO"/>
+	<reg32 offset="0x0131" name="RBBM_PERFCTR_SP_6_HI"/>
+	<reg32 offset="0x0132" name="RBBM_PERFCTR_SP_7_LO"/>
+	<reg32 offset="0x0133" name="RBBM_PERFCTR_SP_7_HI"/>
+	<reg32 offset="0x0134" name="RBBM_PERFCTR_SP_8_LO"/>
+	<reg32 offset="0x0135" name="RBBM_PERFCTR_SP_8_HI"/>
+	<reg32 offset="0x0136" name="RBBM_PERFCTR_SP_9_LO"/>
+	<reg32 offset="0x0137" name="RBBM_PERFCTR_SP_9_HI"/>
+	<reg32 offset="0x0138" name="RBBM_PERFCTR_SP_10_LO"/>
+	<reg32 offset="0x0139" name="RBBM_PERFCTR_SP_10_HI"/>
+	<reg32 offset="0x013a" name="RBBM_PERFCTR_SP_11_LO"/>
+	<reg32 offset="0x013b" name="RBBM_PERFCTR_SP_11_HI"/>
+	<reg32 offset="0x013c" name="RBBM_PERFCTR_RB_0_LO"/>
+	<reg32 offset="0x013d" name="RBBM_PERFCTR_RB_0_HI"/>
+	<reg32 offset="0x013e" name="RBBM_PERFCTR_RB_1_LO"/>
+	<reg32 offset="0x013f" name="RBBM_PERFCTR_RB_1_HI"/>
+	<reg32 offset="0x0140" name="RBBM_PERFCTR_RB_2_LO"/>
+	<reg32 offset="0x0141" name="RBBM_PERFCTR_RB_2_HI"/>
+	<reg32 offset="0x0142" name="RBBM_PERFCTR_RB_3_LO"/>
+	<reg32 offset="0x0143" name="RBBM_PERFCTR_RB_3_HI"/>
+	<reg32 offset="0x0144" name="RBBM_PERFCTR_RB_4_LO"/>
+	<reg32 offset="0x0145" name="RBBM_PERFCTR_RB_4_HI"/>
+	<reg32 offset="0x0146" name="RBBM_PERFCTR_RB_5_LO"/>
+	<reg32 offset="0x0147" name="RBBM_PERFCTR_RB_5_HI"/>
+	<reg32 offset="0x0148" name="RBBM_PERFCTR_RB_6_LO"/>
+	<reg32 offset="0x0149" name="RBBM_PERFCTR_RB_6_HI"/>
+	<reg32 offset="0x014a" name="RBBM_PERFCTR_RB_7_LO"/>
+	<reg32 offset="0x014b" name="RBBM_PERFCTR_RB_7_HI"/>
+	<reg32 offset="0x014c" name="RBBM_PERFCTR_VSC_0_LO"/>
+	<reg32 offset="0x014d" name="RBBM_PERFCTR_VSC_0_HI"/>
+	<reg32 offset="0x014e" name="RBBM_PERFCTR_VSC_1_LO"/>
+	<reg32 offset="0x014f" name="RBBM_PERFCTR_VSC_1_HI"/>
+	<reg32 offset="0x0166" name="RBBM_PERFCTR_PWR_0_LO"/>
+	<reg32 offset="0x0167" name="RBBM_PERFCTR_PWR_0_HI"/>
+	<reg32 offset="0x0168" name="RBBM_PERFCTR_PWR_1_LO"/>
+	<reg32 offset="0x0169" name="RBBM_PERFCTR_PWR_1_HI"/>
+	<reg32 offset="0x016e" name="RBBM_ALWAYSON_COUNTER_LO"/>
+	<reg32 offset="0x016f" name="RBBM_ALWAYSON_COUNTER_HI"/>
+	<array offset="0x0068" name="RBBM_CLOCK_CTL_SP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x006c" name="RBBM_CLOCK_CTL2_SP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x0070" name="RBBM_CLOCK_HYST_SP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x0074" name="RBBM_CLOCK_DELAY_SP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x0078" name="RBBM_CLOCK_CTL_RB" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x007c" name="RBBM_CLOCK_CTL2_RB" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x0082" name="RBBM_CLOCK_CTL_MARB_CCU" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x0086" name="RBBM_CLOCK_HYST_RB_MARB_CCU" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<reg32 offset="0x0080" name="RBBM_CLOCK_HYST_COM_DCOM"/>
+	<reg32 offset="0x0081" name="RBBM_CLOCK_CTL_COM_DCOM"/>
+	<reg32 offset="0x008a" name="RBBM_CLOCK_CTL_HLSQ"/>
+	<reg32 offset="0x008b" name="RBBM_CLOCK_HYST_HLSQ"/>
+	<reg32 offset="0x008c" name="RBBM_CLOCK_DELAY_HLSQ"/>
+	<bitset name="A4XX_CGC_HLSQ">
+		<bitfield name="EARLY_CYC" low="20" high="22" type="uint"/>
+	</bitset>
+	<reg32 offset="0x008d" name="RBBM_CLOCK_DELAY_COM_DCOM"/>
+	<array offset="0x008e" name="RBBM_CLOCK_DELAY_RB_MARB_CCU_L1" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<bitset name="A4XX_INT0">
+		<bitfield name="RBBM_GPU_IDLE" pos="0" type="boolean"/>
+		<bitfield name="RBBM_AHB_ERROR" pos="1" type="boolean"/>
+		<bitfield name="RBBM_REG_TIMEOUT" pos="2" type="boolean"/>
+		<bitfield name="RBBM_ME_MS_TIMEOUT" pos="3" type="boolean"/>
+		<bitfield name="RBBM_PFP_MS_TIMEOUT" pos="4" type="boolean"/>
+		<bitfield name="RBBM_ATB_BUS_OVERFLOW" pos="5" type="boolean"/>
+		<bitfield name="VFD_ERROR" pos="6" type="boolean"/>
+		<bitfield name="CP_SW_INT" pos="7" type="boolean"/>
+		<bitfield name="CP_T0_PACKET_IN_IB" pos="8" type="boolean"/>
+		<bitfield name="CP_OPCODE_ERROR" pos="9" type="boolean"/>
+		<bitfield name="CP_RESERVED_BIT_ERROR" pos="10" type="boolean"/>
+		<bitfield name="CP_HW_FAULT" pos="11" type="boolean"/>
+		<bitfield name="CP_DMA" pos="12" type="boolean"/>
+		<bitfield name="CP_IB2_INT" pos="13" type="boolean"/>
+		<bitfield name="CP_IB1_INT" pos="14" type="boolean"/>
+		<bitfield name="CP_RB_INT" pos="15" type="boolean"/>
+		<bitfield name="CP_REG_PROTECT_FAULT" pos="16" type="boolean"/>
+		<bitfield name="CP_RB_DONE_TS" pos="17" type="boolean"/>
+		<bitfield name="CP_VS_DONE_TS" pos="18" type="boolean"/>
+		<bitfield name="CP_PS_DONE_TS" pos="19" type="boolean"/>
+		<bitfield name="CACHE_FLUSH_TS" pos="20" type="boolean"/>
+		<bitfield name="CP_AHB_ERROR_HALT" pos="21" type="boolean"/>
+		<bitfield name="MISC_HANG_DETECT" pos="24" type="boolean"/>
+		<bitfield name="UCHE_OOB_ACCESS" pos="25" type="boolean"/>
+	</bitset>
+
+	<reg32 offset="0x0099" name="RBBM_SP_REGFILE_SLEEP_CNTL_0"/>
+	<reg32 offset="0x009a" name="RBBM_SP_REGFILE_SLEEP_CNTL_1"/>
+	<reg32 offset="0x0170" name="RBBM_PERFCTR_CTL"/>
+	<reg32 offset="0x0171" name="RBBM_PERFCTR_LOAD_CMD0"/>
+	<reg32 offset="0x0172" name="RBBM_PERFCTR_LOAD_CMD1"/>
+	<reg32 offset="0x0173" name="RBBM_PERFCTR_LOAD_CMD2"/>
+	<reg32 offset="0x0174" name="RBBM_PERFCTR_LOAD_VALUE_LO"/>
+	<reg32 offset="0x0175" name="RBBM_PERFCTR_LOAD_VALUE_HI"/>
+	<reg32 offset="0x0176" name="RBBM_PERFCTR_RBBM_SEL_0" type="a4xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x0177" name="RBBM_PERFCTR_RBBM_SEL_1" type="a4xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x0178" name="RBBM_PERFCTR_RBBM_SEL_2" type="a4xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x0179" name="RBBM_PERFCTR_RBBM_SEL_3" type="a4xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x017a" name="RBBM_GPU_BUSY_MASKED"/>
+	<reg32 offset="0x017d" name="RBBM_INT_0_STATUS"/>
+	<reg32 offset="0x0182" name="RBBM_CLOCK_STATUS"/>
+	<reg32 offset="0x0189" name="RBBM_AHB_STATUS"/>
+	<reg32 offset="0x018c" name="RBBM_AHB_ME_SPLIT_STATUS"/>
+	<reg32 offset="0x018d" name="RBBM_AHB_PFP_SPLIT_STATUS"/>
+	<reg32 offset="0x018f" name="RBBM_AHB_ERROR_STATUS"/>
+	<reg32 offset="0x0191" name="RBBM_STATUS">
+		<bitfield name="HI_BUSY" pos="0" type="boolean"/>
+		<bitfield name="CP_ME_BUSY" pos="1" type="boolean"/>
+		<bitfield name="CP_PFP_BUSY" pos="2" type="boolean"/>
+		<bitfield name="CP_NRT_BUSY" pos="14" type="boolean"/>
+		<bitfield name="VBIF_BUSY" pos="15" type="boolean"/>
+		<bitfield name="TSE_BUSY" pos="16" type="boolean"/>
+		<bitfield name="RAS_BUSY" pos="17" type="boolean"/>
+		<bitfield name="RB_BUSY" pos="18" type="boolean"/>
+		<bitfield name="PC_DCALL_BUSY" pos="19" type="boolean"/>
+		<bitfield name="PC_VSD_BUSY" pos="20" type="boolean"/>
+		<bitfield name="VFD_BUSY" pos="21" type="boolean"/>
+		<bitfield name="VPC_BUSY" pos="22" type="boolean"/>
+		<bitfield name="UCHE_BUSY" pos="23" type="boolean"/>
+		<bitfield name="SP_BUSY" pos="24" type="boolean"/>
+		<bitfield name="TPL1_BUSY" pos="25" type="boolean"/>
+		<bitfield name="MARB_BUSY" pos="26" type="boolean"/>
+		<bitfield name="VSC_BUSY" pos="27" type="boolean"/>
+		<bitfield name="ARB_BUSY" pos="28" type="boolean"/>
+		<bitfield name="HLSQ_BUSY" pos="29" type="boolean"/>
+		<bitfield name="GPU_BUSY_NOHC" pos="30" type="boolean"/>
+		<bitfield name="GPU_BUSY" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x019f" name="RBBM_INTERFACE_RRDY_STATUS5"/>
+	<reg32 offset="0x01b0" name="RBBM_POWER_STATUS">
+		<bitfield name="SP_TP_PWR_ON" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x01b8" name="RBBM_WAIT_IDLE_CLOCKS_CTL2"/>
+
+	<!-- CP registers -->
+	<reg32 offset="0x0228" name="CP_SCRATCH_UMASK"/>
+	<reg32 offset="0x0229" name="CP_SCRATCH_ADDR"/>
+	<reg32 offset="0x0200" name="CP_RB_BASE"/>
+	<reg32 offset="0x0201" name="CP_RB_CNTL"/>
+	<reg32 offset="0x0205" name="CP_RB_WPTR"/>
+	<reg32 offset="0x0203" name="CP_RB_RPTR_ADDR"/>
+	<reg32 offset="0x0204" name="CP_RB_RPTR"/>
+	<reg32 offset="0x0206" name="CP_IB1_BASE"/>
+	<reg32 offset="0x0207" name="CP_IB1_BUFSZ"/>
+	<reg32 offset="0x0208" name="CP_IB2_BASE"/>
+	<reg32 offset="0x0209" name="CP_IB2_BUFSZ"/>
+	<reg32 offset="0x020c" name="CP_ME_NRT_ADDR"/>
+	<reg32 offset="0x020d" name="CP_ME_NRT_DATA"/>
+	<reg32 offset="0x0217" name="CP_ME_RB_DONE_DATA"/>
+	<reg32 offset="0x0219" name="CP_QUEUE_THRESH2"/>
+	<reg32 offset="0x021b" name="CP_MERCIU_SIZE"/>
+	<reg32 offset="0x021c" name="CP_ROQ_ADDR"/>
+	<reg32 offset="0x021d" name="CP_ROQ_DATA"/>
+	<reg32 offset="0x021e" name="CP_MEQ_ADDR"/>
+	<reg32 offset="0x021f" name="CP_MEQ_DATA"/>
+	<reg32 offset="0x0220" name="CP_MERCIU_ADDR"/>
+	<reg32 offset="0x0221" name="CP_MERCIU_DATA"/>
+	<reg32 offset="0x0222" name="CP_MERCIU_DATA2"/>
+	<reg32 offset="0x0223" name="CP_PFP_UCODE_ADDR"/>
+	<reg32 offset="0x0224" name="CP_PFP_UCODE_DATA"/>
+	<reg32 offset="0x0225" name="CP_ME_RAM_WADDR"/>
+	<reg32 offset="0x0226" name="CP_ME_RAM_RADDR"/>
+	<reg32 offset="0x0227" name="CP_ME_RAM_DATA"/>
+	<reg32 offset="0x022a" name="CP_PREEMPT"/>
+	<reg32 offset="0x022c" name="CP_CNTL"/>
+	<reg32 offset="0x022d" name="CP_ME_CNTL"/>
+	<reg32 offset="0x022e" name="CP_DEBUG"/>
+	<reg32 offset="0x0231" name="CP_DEBUG_ECO_CONTROL"/>
+	<reg32 offset="0x0232" name="CP_DRAW_STATE_ADDR"/>
+	<array offset="0x0240" name="CP_PROTECT" stride="1" length="16">
+		<reg32 offset="0x0" name="REG" type="adreno_cp_protect"/>
+	</array>
+	<reg32 offset="0x0250" name="CP_PROTECT_CTRL"/>
+	<reg32 offset="0x04c0" name="CP_ST_BASE"/>
+	<reg32 offset="0x04ce" name="CP_STQ_AVAIL"/>
+	<reg32 offset="0x04d0" name="CP_MERCIU_STAT"/>
+	<reg32 offset="0x04d2" name="CP_WFI_PEND_CTR"/>
+	<reg32 offset="0x04d8" name="CP_HW_FAULT"/>
+	<reg32 offset="0x04da" name="CP_PROTECT_STATUS"/>
+	<reg32 offset="0x04dd" name="CP_EVENTS_IN_FLIGHT"/>
+	<reg32 offset="0x0500" name="CP_PERFCTR_CP_SEL_0" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0501" name="CP_PERFCTR_CP_SEL_1" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0502" name="CP_PERFCTR_CP_SEL_2" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0503" name="CP_PERFCTR_CP_SEL_3" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0504" name="CP_PERFCTR_CP_SEL_4" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0505" name="CP_PERFCTR_CP_SEL_5" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0506" name="CP_PERFCTR_CP_SEL_6" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0507" name="CP_PERFCTR_CP_SEL_7" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x050b" name="CP_PERFCOMBINER_SELECT"/>
+	<array offset="0x0578" name="CP_SCRATCH" stride="1" length="23">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+
+
+	<!-- SP registers -->
+	<reg32 offset="0x0ec0" name="SP_VS_STATUS"/>
+	<reg32 offset="0x0ec3" name="SP_MODE_CONTROL"/>
+
+	<reg32 offset="0x0ec4" name="SP_PERFCTR_SP_SEL_0" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec5" name="SP_PERFCTR_SP_SEL_1" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec6" name="SP_PERFCTR_SP_SEL_2" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec7" name="SP_PERFCTR_SP_SEL_3" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec8" name="SP_PERFCTR_SP_SEL_4" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec9" name="SP_PERFCTR_SP_SEL_5" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0eca" name="SP_PERFCTR_SP_SEL_6" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ecb" name="SP_PERFCTR_SP_SEL_7" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ecc" name="SP_PERFCTR_SP_SEL_8" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ecd" name="SP_PERFCTR_SP_SEL_9" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ece" name="SP_PERFCTR_SP_SEL_10" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ecf" name="SP_PERFCTR_SP_SEL_11" type="a4xx_sp_perfcounter_select"/>
+
+	<reg32 offset="0x22c0" name="SP_SP_CTRL_REG">
+		<bitfield name="BINNING_PASS" pos="19" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x22c1" name="SP_INSTR_CACHE_CTRL">
+		<!-- set when VS in buffer mode: -->
+		<bitfield name="VS_BUFFER" pos="7" type="boolean"/>
+		<!-- set when FS in buffer mode: -->
+		<bitfield name="FS_BUFFER" pos="8" type="boolean"/>
+		<!-- set when both VS or FS in buffer mode: -->
+		<bitfield name="INSTR_BUFFER" pos="10" type="boolean"/>
+		<!-- TODO other bits probably matter when other stages active? -->
+	</reg32>
+
+	<bitset name="a4xx_sp_vs_fs_ctrl_reg0" inline="yes">
+		<!--
+			NOTE that SP_{VS,FS}_CTRL_REG1 are different, but so far REG0
+			appears to be the same..
+		-->
+		<bitfield name="THREADMODE" pos="0" type="a3xx_threadmode"/>
+		<!-- VARYING bit only for FS.. think it controls emitting (ei) flag? -->
+		<bitfield name="VARYING" pos="1" type="boolean"/>
+		<!-- maybe CACHEINVALID is two bits?? -->
+		<bitfield name="CACHEINVALID" pos="2" type="boolean"/>
+		<doc>
+			The full/half register footprint is in units of four components,
+			so if r0.x is used, that counts as all of r0.[xyzw] as used.
+			There are separate full/half register footprint values as the
+			full and half registers are independent (not overlapping).
+			Presumably the thread scheduler hardware allocates the full/half
+			register names from the actual physical register file and
+			handles the register renaming.
+		</doc>
+		<bitfield name="HALFREGFOOTPRINT" low="4" high="9" type="uint"/>
+		<bitfield name="FULLREGFOOTPRINT" low="10" high="15" type="uint"/>
+		<!-- maybe INOUTREGOVERLAP is a bitflag? -->
+		<bitfield name="INOUTREGOVERLAP" low="18" high="19" type="uint"/>
+		<bitfield name="THREADSIZE" pos="20" type="a3xx_threadsize"/>
+		<bitfield name="SUPERTHREADMODE" pos="21" type="boolean"/>
+		<bitfield name="PIXLODENABLE" pos="22" type="boolean"/>
+	</bitset>
+
+	<reg32 offset="0x22c4" name="SP_VS_CTRL_REG0" type="a4xx_sp_vs_fs_ctrl_reg0"/>
+	<reg32 offset="0x22c5" name="SP_VS_CTRL_REG1">
+		<bitfield name="CONSTLENGTH" low="0" high="7" type="uint"/>
+		<bitfield name="INITIALOUTSTANDING" low="24" high="30" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22c6" name="SP_VS_PARAM_REG">
+		<bitfield name="POSREGID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="PSIZEREGID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="TOTALVSOUTVAR" low="20" high="31" type="uint"/>
+	</reg32>
+	<array offset="0x22c7" name="SP_VS_OUT" stride="1" length="16">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="8" type="a3xx_regid"/>
+			<bitfield name="A_COMPMASK" low="9" high="12" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="24" type="a3xx_regid"/>
+			<bitfield name="B_COMPMASK" low="25" high="28" type="hex"/>
+		</reg32>
+	</array>
+	<array offset="0x22d8" name="SP_VS_VPC_DST" stride="1" length="8">
+		<reg32 offset="0x0" name="REG">
+			<doc>
+				These seem to be offsets for storage of the varyings.
+				Always seems to start from 8, possibly loc 0 and 4
+				are for gl_Position and gl_PointSize?
+			</doc>
+			<bitfield name="OUTLOC0" low="0" high="7" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="15" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="23" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="31" type="uint"/>
+		</reg32>
+	</array>
+
+	<reg32 offset="0x22e0" name="SP_VS_OBJ_OFFSET_REG">
+		<!-- always 00000000: -->
+		<doc>
+			From register spec:
+			SP_FS_OBJ_OFFSET_REG.CONSTOBJECTSTARTOFFSET [16:24]: Constant object
+			start offset in on chip RAM,
+			128bit aligned
+		</doc>
+		<bitfield name="CONSTOBJECTOFFSET" low="16" high="24" type="uint"/>
+		<bitfield name="SHADEROBJOFFSET" low="25" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22e1" name="SP_VS_OBJ_START"/>
+	<reg32 offset="0x22e2" name="SP_VS_PVT_MEM_PARAM"/>
+	<reg32 offset="0x22e3" name="SP_VS_PVT_MEM_ADDR"/>
+	<reg32 offset="0x22e5" name="SP_VS_LENGTH_REG" type="uint"/>
+	<reg32 offset="0x22e8" name="SP_FS_CTRL_REG0" type="a4xx_sp_vs_fs_ctrl_reg0"/>
+	<reg32 offset="0x22e9" name="SP_FS_CTRL_REG1">
+		<bitfield name="CONSTLENGTH" low="0" high="7" type="uint"/>
+		<bitfield name="FACENESS" pos="19" type="boolean"/>
+		<bitfield name="VARYING" pos="20" type="boolean"/>
+		<bitfield name="FRAGCOORD" pos="21" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x22ea" name="SP_FS_OBJ_OFFSET_REG">
+		<bitfield name="CONSTOBJECTOFFSET" low="16" high="24" type="uint"/>
+		<bitfield name="SHADEROBJOFFSET" low="25" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22eb" name="SP_FS_OBJ_START"/>
+	<reg32 offset="0x22ec" name="SP_FS_PVT_MEM_PARAM"/>
+	<reg32 offset="0x22ed" name="SP_FS_PVT_MEM_ADDR"/>
+	<reg32 offset="0x22ef" name="SP_FS_LENGTH_REG" type="uint"/>
+	<reg32 offset="0x22f0" name="SP_FS_OUTPUT_REG">
+		<bitfield name="MRT" low="0" high="3" type="uint"/>
+		<bitfield name="DEPTH_ENABLE" pos="7" type="boolean"/>
+		<!-- TODO double check.. for now assume same as a3xx -->
+		<bitfield name="DEPTH_REGID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="SAMPLEMASK_REGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<array offset="0x22f1" name="SP_FS_MRT" stride="1" length="8">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="HALF_PRECISION" pos="8" type="boolean"/>
+			<bitfield name="COLOR_SINT" pos="10" type="boolean"/>
+			<bitfield name="COLOR_UINT" pos="11" type="boolean"/>
+			<bitfield name="MRTFORMAT" low="12" high="17" type="a4xx_color_fmt"/>
+			<bitfield name="COLOR_SRGB" pos="18" type="boolean"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x2300" name="SP_CS_CTRL_REG0" type="a4xx_sp_vs_fs_ctrl_reg0"/>
+	<reg32 offset="0x2301" name="SP_CS_OBJ_OFFSET_REG"/>
+	<reg32 offset="0x2302" name="SP_CS_OBJ_START"/>
+	<reg32 offset="0x2303" name="SP_CS_PVT_MEM_PARAM"/>
+	<reg32 offset="0x2304" name="SP_CS_PVT_MEM_ADDR"/>
+	<reg32 offset="0x2305" name="SP_CS_PVT_MEM_SIZE"/>
+	<reg32 offset="0x2306" name="SP_CS_LENGTH_REG" type="uint"/>
+	<reg32 offset="0x230d" name="SP_HS_OBJ_OFFSET_REG">
+		<bitfield name="CONSTOBJECTOFFSET" low="16" high="24" type="uint"/>
+		<bitfield name="SHADEROBJOFFSET" low="25" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x230e" name="SP_HS_OBJ_START"/>
+	<reg32 offset="0x230f" name="SP_HS_PVT_MEM_PARAM"/>
+	<reg32 offset="0x2310" name="SP_HS_PVT_MEM_ADDR"/>
+	<reg32 offset="0x2312" name="SP_HS_LENGTH_REG" type="uint"/>
+
+	<reg32 offset="0x231a" name="SP_DS_PARAM_REG">
+		<bitfield name="POSREGID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="TOTALGSOUTVAR" low="20" high="31" type="uint"/>
+	</reg32>
+	<array offset="0x231b" name="SP_DS_OUT" stride="1" length="16">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="8" type="a3xx_regid"/>
+			<bitfield name="A_COMPMASK" low="9" high="12" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="24" type="a3xx_regid"/>
+			<bitfield name="B_COMPMASK" low="25" high="28" type="hex"/>
+		</reg32>
+	</array>
+	<array offset="0x232c" name="SP_DS_VPC_DST" stride="1" length="8">
+		<reg32 offset="0x0" name="REG">
+			<doc>
+				These seem to be offsets for storage of the varyings.
+				Always seems to start from 8, possibly loc 0 and 4
+				are for gl_Position and gl_PointSize?
+			</doc>
+			<bitfield name="OUTLOC0" low="0" high="7" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="15" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="23" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="31" type="uint"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x2334" name="SP_DS_OBJ_OFFSET_REG">
+		<bitfield name="CONSTOBJECTOFFSET" low="16" high="24" type="uint"/>
+		<bitfield name="SHADEROBJOFFSET" low="25" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2335" name="SP_DS_OBJ_START"/>
+	<reg32 offset="0x2336" name="SP_DS_PVT_MEM_PARAM"/>
+	<reg32 offset="0x2337" name="SP_DS_PVT_MEM_ADDR"/>
+	<reg32 offset="0x2339" name="SP_DS_LENGTH_REG" type="uint"/>
+
+	<reg32 offset="0x2341" name="SP_GS_PARAM_REG">
+		<bitfield name="POSREGID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="PRIMREGID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="TOTALGSOUTVAR" low="20" high="31" type="uint"/>
+	</reg32>
+	<array offset="0x2342" name="SP_GS_OUT" stride="1" length="16">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="8" type="a3xx_regid"/>
+			<bitfield name="A_COMPMASK" low="9" high="12" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="24" type="a3xx_regid"/>
+			<bitfield name="B_COMPMASK" low="25" high="28" type="hex"/>
+		</reg32>
+	</array>
+	<array offset="0x2353" name="SP_GS_VPC_DST" stride="1" length="8">
+		<reg32 offset="0x0" name="REG">
+			<doc>
+				These seem to be offsets for storage of the varyings.
+				Always seems to start from 8, possibly loc 0 and 4
+				are for gl_Position and gl_PointSize?
+			</doc>
+			<bitfield name="OUTLOC0" low="0" high="7" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="15" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="23" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="31" type="uint"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x235b" name="SP_GS_OBJ_OFFSET_REG">
+		<bitfield name="CONSTOBJECTOFFSET" low="16" high="24" type="uint"/>
+		<bitfield name="SHADEROBJOFFSET" low="25" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x235c" name="SP_GS_OBJ_START"/>
+	<reg32 offset="0x235d" name="SP_GS_PVT_MEM_PARAM"/>
+	<reg32 offset="0x235e" name="SP_GS_PVT_MEM_ADDR"/>
+	<reg32 offset="0x2360" name="SP_GS_LENGTH_REG" type="uint"/>
+
+	<!-- VPC registers -->
+	<reg32 offset="0x0e60" name="VPC_DEBUG_RAM_SEL"/>
+	<reg32 offset="0x0e61" name="VPC_DEBUG_RAM_READ"/>
+	<reg32 offset="0x0e64" name="VPC_DEBUG_ECO_CONTROL"/>
+	<reg32 offset="0x0e65" name="VPC_PERFCTR_VPC_SEL_0" type="a4xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e66" name="VPC_PERFCTR_VPC_SEL_1" type="a4xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e67" name="VPC_PERFCTR_VPC_SEL_2" type="a4xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e68" name="VPC_PERFCTR_VPC_SEL_3" type="a4xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x2140" name="VPC_ATTR">
+		<bitfield name="TOTALATTR" low="0" high="8" type="uint"/>
+		<!-- PSIZE bit set if gl_PointSize written: -->
+		<bitfield name="PSIZE" pos="9" type="boolean"/>
+		<bitfield name="THRDASSIGN" low="12" high="13" type="uint"/>
+		<bitfield name="ENABLE" pos="25" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2141" name="VPC_PACK">
+		<bitfield name="NUMBYPASSVAR" low="0" high="7" type="uint"/>
+		<bitfield name="NUMFPNONPOSVAR" low="8" high="15" type="uint"/>
+		<bitfield name="NUMNONPOSVSVAR" low="16" high="23" type="uint"/>
+	</reg32>
+	<array offset="0x2142" name="VPC_VARYING_INTERP" stride="1" length="8">
+		<reg32 offset="0x0" name="MODE"/>
+	</array>
+	<array offset="0x214a" name="VPC_VARYING_PS_REPL" stride="1" length="8">
+		<reg32 offset="0x0" name="MODE"/>
+	</array>
+
+	<reg32 offset="0x216e" name="VPC_SO_FLUSH_WADDR_3"/>
+
+	<!-- VSC registers -->
+	<reg32 offset="0x0c00" name="VSC_BIN_SIZE">
+		<bitfield name="WIDTH" low="0" high="4" shr="5" type="uint"/>
+		<bitfield name="HEIGHT" low="5" high="9" shr="5" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0c01" name="VSC_SIZE_ADDRESS"/>
+	<reg32 offset="0x0c02" name="VSC_SIZE_ADDRESS2"/>
+	<reg32 offset="0x0c03" name="VSC_DEBUG_ECO_CONTROL"/>
+	<array offset="0x0c08" name="VSC_PIPE_CONFIG" stride="1" length="8">
+		<reg32 offset="0x0" name="REG">
+			<doc>
+				Configures the mapping between VSC_PIPE buffer and
+				bin, X/Y specify the bin index in the horiz/vert
+				direction (0,0 is upper left, 0,1 is leftmost bin
+				on second row, and so on).  W/H specify the number
+				of bins assigned to this VSC_PIPE in the horiz/vert
+				dimension.
+			</doc>
+			<bitfield name="X" low="0" high="9" type="uint"/>
+			<bitfield name="Y" low="10" high="19" type="uint"/>
+			<bitfield name="W" low="20" high="23" type="uint"/>
+			<bitfield name="H" low="24" high="27" type="uint"/>
+		</reg32>
+	</array>
+	<array offset="0x0c10" name="VSC_PIPE_DATA_ADDRESS" stride="1" length="8">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x0c18" name="VSC_PIPE_DATA_LENGTH" stride="1" length="8">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<reg32 offset="0x0c41" name="VSC_PIPE_PARTIAL_POSN_1"/>
+	<reg32 offset="0x0c50" name="VSC_PERFCTR_VSC_SEL_0" type="a4xx_vsc_perfcounter_select"/>
+	<reg32 offset="0x0c51" name="VSC_PERFCTR_VSC_SEL_1" type="a4xx_vsc_perfcounter_select"/>
+
+	<!-- VFD registers -->
+	<reg32 offset="0x0e40" name="VFD_DEBUG_CONTROL"/>
+	<reg32 offset="0x0e43" name="VFD_PERFCTR_VFD_SEL_0" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e44" name="VFD_PERFCTR_VFD_SEL_1" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e45" name="VFD_PERFCTR_VFD_SEL_2" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e46" name="VFD_PERFCTR_VFD_SEL_3" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e47" name="VFD_PERFCTR_VFD_SEL_4" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e48" name="VFD_PERFCTR_VFD_SEL_5" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e49" name="VFD_PERFCTR_VFD_SEL_6" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e4a" name="VFD_PERFCTR_VFD_SEL_7" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x21d0" name="VGT_CL_INITIATOR"/>
+	<reg32 offset="0x21d9" name="VGT_EVENT_INITIATOR"/>
+	<reg32 offset="0x2200" name="VFD_CONTROL_0">
+		<doc>
+			TOTALATTRTOVS is # of attributes to vertex shader, in register
+			slots (ie. vec4+vec3 -> 7)
+		</doc>
+		<bitfield name="TOTALATTRTOVS" low="0" high="7" type="uint"/>
+		<doc>
+		BYPASSATTROVS seems to count varyings that are just directly
+		assigned from attributes (ie, "vFoo = aFoo;")
+		</doc>
+		<bitfield name="BYPASSATTROVS" low="9" high="16" type="uint"/>
+		<doc>STRMDECINSTRCNT is # of VFD_DECODE_INSTR registers valid</doc>
+		<bitfield name="STRMDECINSTRCNT" low="20" high="25" type="uint"/>
+		<doc>STRMFETCHINSTRCNT is # of VFD_FETCH_INSTR registers valid</doc>
+		<bitfield name="STRMFETCHINSTRCNT" low="26" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2201" name="VFD_CONTROL_1">
+		<doc>MAXSTORAGE could be # of attributes/vbo's</doc>
+		<bitfield name="MAXSTORAGE" low="0" high="15" type="uint"/>
+		<bitfield name="REGID4VTX" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="REGID4INST" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x2202" name="VFD_CONTROL_2"/>
+	<reg32 offset="0x2203" name="VFD_CONTROL_3">
+		<bitfield name="REGID_VTXCNT" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="REGID_TESSX" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="REGID_TESSY" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x2204" name="VFD_CONTROL_4"/>
+	<reg32 offset="0x2208" name="VFD_INDEX_OFFSET"/>
+	<array offset="0x220a" name="VFD_FETCH" stride="4" length="32">
+		<reg32 offset="0x0" name="INSTR_0">
+			<bitfield name="FETCHSIZE" low="0" high="6" type="uint"/>
+			<bitfield name="BUFSTRIDE" low="7" high="16" type="uint"/>
+			<bitfield name="SWITCHNEXT" pos="19" type="boolean"/>
+			<bitfield name="INSTANCED" pos="20" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x1" name="INSTR_1"/>
+		<reg32 offset="0x2" name="INSTR_2">
+			<bitfield name="SIZE" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="0x3" name="INSTR_3">
+			<!-- might well be bigger.. -->
+			<bitfield name="STEPRATE" low="0" high="8" type="uint"/>
+		</reg32>
+	</array>
+	<array offset="0x228a" name="VFD_DECODE" stride="1" length="32">
+		<reg32 offset="0x0" name="INSTR">
+			<bitfield name="WRITEMASK" low="0" high="3" type="hex"/>
+			<!-- not sure if this is a bit flag and another flag above it, or?? -->
+			<bitfield name="CONSTFILL" pos="4" type="boolean"/>
+			<bitfield name="FORMAT" low="6" high="11" type="a4xx_vtx_fmt"/>
+			<bitfield name="REGID" low="12" high="19" type="a3xx_regid"/>
+			<bitfield name="INT" pos="20" type="boolean"/>
+			<doc>SHIFTCNT appears to be size, ie. FLOAT_32_32_32 is 12, and BYTE_8 is 1</doc>
+			<bitfield name="SWAP" low="22" high="23" type="a3xx_color_swap"/>
+			<bitfield name="SHIFTCNT" low="24" high="28" type="uint"/>
+			<bitfield name="LASTCOMPVALID" pos="29" type="boolean"/>
+			<bitfield name="SWITCHNEXT" pos="30" type="boolean"/>
+		</reg32>
+	</array>
+
+	<!-- TPL1 registers -->
+	<reg32 offset="0x0f00" name="TPL1_DEBUG_ECO_CONTROL"/>
+	<!-- always 0000003a: -->
+	<reg32 offset="0x0f03" name="TPL1_TP_MODE_CONTROL"/>
+	<reg32 offset="0x0f04" name="TPL1_PERFCTR_TP_SEL_0" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f05" name="TPL1_PERFCTR_TP_SEL_1" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f06" name="TPL1_PERFCTR_TP_SEL_2" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f07" name="TPL1_PERFCTR_TP_SEL_3" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f08" name="TPL1_PERFCTR_TP_SEL_4" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f09" name="TPL1_PERFCTR_TP_SEL_5" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f0a" name="TPL1_PERFCTR_TP_SEL_6" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f0b" name="TPL1_PERFCTR_TP_SEL_7" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x2380" name="TPL1_TP_TEX_OFFSET"/>
+	<reg32 offset="0x2381" name="TPL1_TP_TEX_COUNT">
+		<bitfield name="VS" low="0" high="7" type="uint"/>
+		<bitfield name="HS" low="8" high="15" type="uint"/>
+		<bitfield name="DS" low="16" high="23" type="uint"/>
+		<bitfield name="GS" low="24" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2384" name="TPL1_TP_VS_BORDER_COLOR_BASE_ADDR"/>
+	<reg32 offset="0x2387" name="TPL1_TP_HS_BORDER_COLOR_BASE_ADDR"/>
+	<reg32 offset="0x238a" name="TPL1_TP_DS_BORDER_COLOR_BASE_ADDR"/>
+	<reg32 offset="0x238d" name="TPL1_TP_GS_BORDER_COLOR_BASE_ADDR"/>
+	<reg32 offset="0x23a0" name="TPL1_TP_FS_TEX_COUNT">
+		<bitfield name="FS" low="0" high="7" type="uint"/>
+		<bitfield name="CS" low="8" high="15" type="uint"/>
+	</reg32>
+	<reg32 offset="0x23a1" name="TPL1_TP_FS_BORDER_COLOR_BASE_ADDR"/>
+	<reg32 offset="0x23a4" name="TPL1_TP_CS_BORDER_COLOR_BASE_ADDR"/>
+	<reg32 offset="0x23a5" name="TPL1_TP_CS_SAMPLER_BASE_ADDR"/>
+	<reg32 offset="0x23a6" name="TPL1_TP_CS_TEXMEMOBJ_BASE_ADDR"/>
+
+	<!-- GRAS registers -->
+	<reg32 offset="0x0c80" name="GRAS_TSE_STATUS"/>
+	<reg32 offset="0x0c81" name="GRAS_DEBUG_ECO_CONTROL"/>
+	<reg32 offset="0x0c88" name="GRAS_PERFCTR_TSE_SEL_0" type="a4xx_gras_tse_perfcounter_select"/>
+	<reg32 offset="0x0c89" name="GRAS_PERFCTR_TSE_SEL_1" type="a4xx_gras_tse_perfcounter_select"/>
+	<reg32 offset="0x0c8a" name="GRAS_PERFCTR_TSE_SEL_2" type="a4xx_gras_tse_perfcounter_select"/>
+	<reg32 offset="0x0c8b" name="GRAS_PERFCTR_TSE_SEL_3" type="a4xx_gras_tse_perfcounter_select"/>
+	<reg32 offset="0x0c8c" name="GRAS_PERFCTR_RAS_SEL_0" type="a4xx_gras_ras_perfcounter_select"/>
+	<reg32 offset="0x0c8d" name="GRAS_PERFCTR_RAS_SEL_1" type="a4xx_gras_ras_perfcounter_select"/>
+	<reg32 offset="0x0c8e" name="GRAS_PERFCTR_RAS_SEL_2" type="a4xx_gras_ras_perfcounter_select"/>
+	<reg32 offset="0x0c8f" name="GRAS_PERFCTR_RAS_SEL_3" type="a4xx_gras_ras_perfcounter_select"/>
+	<reg32 offset="0x2000" name="GRAS_CL_CLIP_CNTL">
+		<bitfield name="CLIP_DISABLE" pos="15" type="boolean"/>
+		<bitfield name="ZNEAR_CLIP_DISABLE" pos="16" type="boolean"/>
+		<bitfield name="ZFAR_CLIP_DISABLE" pos="17" type="boolean"/>
+		<bitfield name="ZERO_GB_SCALE_Z" pos="22" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2003" name="GRAS_CNTL">
+		<bitfield name="IJ_PERSP" pos="0" type="boolean"/>
+		<bitfield name="IJ_LINEAR" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2004" name="GRAS_CL_GB_CLIP_ADJ">
+		<bitfield name="HORZ" low="0" high="9" type="uint"/>
+		<bitfield name="VERT" low="10" high="19" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2008" name="GRAS_CL_VPORT_XOFFSET_0" type="float"/>
+	<reg32 offset="0x2009" name="GRAS_CL_VPORT_XSCALE_0" type="float"/>
+	<reg32 offset="0x200a" name="GRAS_CL_VPORT_YOFFSET_0" type="float"/>
+	<reg32 offset="0x200b" name="GRAS_CL_VPORT_YSCALE_0" type="float"/>
+	<reg32 offset="0x200c" name="GRAS_CL_VPORT_ZOFFSET_0" type="float"/>
+	<reg32 offset="0x200d" name="GRAS_CL_VPORT_ZSCALE_0" type="float"/>
+	<reg32 offset="0x2070" name="GRAS_SU_POINT_MINMAX">
+		<bitfield name="MIN" low="0" high="15" type="ufixed" radix="4"/>
+		<bitfield name="MAX" low="16" high="31" type="ufixed" radix="4"/>
+	</reg32>
+	<reg32 offset="0x2071" name="GRAS_SU_POINT_SIZE" type="fixed" radix="4"/>
+	<reg32 offset="0x2073" name="GRAS_ALPHA_CONTROL">
+		<bitfield name="ALPHA_TEST_ENABLE" pos="2" type="boolean"/>
+		<bitfield name="FORCE_FRAGZ_TO_FS" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2074" name="GRAS_SU_POLY_OFFSET_SCALE" type="float"/>
+	<reg32 offset="0x2075" name="GRAS_SU_POLY_OFFSET_OFFSET" type="float"/>
+	<reg32 offset="0x2076" name="GRAS_SU_POLY_OFFSET_CLAMP" type="float"/>
+	<reg32 offset="0x2077" name="GRAS_DEPTH_CONTROL">
+		<!-- guestimating that this is GRAS based on addr -->
+		<bitfield name="FORMAT" low="0" high="1" type="a4xx_depth_format"/>
+	</reg32>
+	<reg32 offset="0x2078" name="GRAS_SU_MODE_CONTROL">
+		<bitfield name="CULL_FRONT" pos="0" type="boolean"/>
+		<bitfield name="CULL_BACK" pos="1" type="boolean"/>
+		<bitfield name="FRONT_CW" pos="2" type="boolean"/>
+		<bitfield name="LINEHALFWIDTH" low="3" high="10" radix="2" type="fixed"/>
+		<bitfield name="POLY_OFFSET" pos="11" type="boolean"/>
+		<bitfield name="MSAA_ENABLE" pos="13" type="boolean"/>
+		<!-- bit20 set whenever RENDER_MODE = RB_RENDERING_PASS -->
+		<bitfield name="RENDERING_PASS" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x207b" name="GRAS_SC_CONTROL">
+		<!-- complete wild-ass-guess for sizes of these bitfields.. -->
+		<bitfield name="RENDER_MODE" low="2" high="3" type="a3xx_render_mode"/>
+		<bitfield name="MSAA_SAMPLES" low="7" high="9" type="uint"/>
+		<bitfield name="MSAA_DISABLE" pos="11" type="boolean"/>
+		<bitfield name="RASTER_MODE" low="12" high="15"/>
+	</reg32>
+	<reg32 offset="0x207c" name="GRAS_SC_SCREEN_SCISSOR_TL" type="adreno_reg_xy"/>
+	<reg32 offset="0x207d" name="GRAS_SC_SCREEN_SCISSOR_BR" type="adreno_reg_xy"/>
+	<reg32 offset="0x209c" name="GRAS_SC_WINDOW_SCISSOR_BR" type="adreno_reg_xy"/>
+	<reg32 offset="0x209d" name="GRAS_SC_WINDOW_SCISSOR_TL" type="adreno_reg_xy"/>
+	<reg32 offset="0x209e" name="GRAS_SC_EXTENT_WINDOW_BR" type="adreno_reg_xy"/>
+	<reg32 offset="0x209f" name="GRAS_SC_EXTENT_WINDOW_TL" type="adreno_reg_xy"/>
+
+	<!-- UCHE registers -->
+	<reg32 offset="0x0e80" name="UCHE_CACHE_MODE_CONTROL"/>
+	<reg32 offset="0x0e83" name="UCHE_TRAP_BASE_LO"/>
+	<reg32 offset="0x0e84" name="UCHE_TRAP_BASE_HI"/>
+	<reg32 offset="0x0e88" name="UCHE_CACHE_STATUS"/>
+	<reg32 offset="0x0e8a" name="UCHE_INVALIDATE0"/>
+	<reg32 offset="0x0e8b" name="UCHE_INVALIDATE1"/>
+	<reg32 offset="0x0e8c" name="UCHE_CACHE_WAYS_VFD"/>
+	<reg32 offset="0x0e8e" name="UCHE_PERFCTR_UCHE_SEL_0" type="a4xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e8f" name="UCHE_PERFCTR_UCHE_SEL_1" type="a4xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e90" name="UCHE_PERFCTR_UCHE_SEL_2" type="a4xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e91" name="UCHE_PERFCTR_UCHE_SEL_3" type="a4xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e92" name="UCHE_PERFCTR_UCHE_SEL_4" type="a4xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e93" name="UCHE_PERFCTR_UCHE_SEL_5" type="a4xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e94" name="UCHE_PERFCTR_UCHE_SEL_6" type="a4xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e95" name="UCHE_PERFCTR_UCHE_SEL_7" type="a4xx_uche_perfcounter_select"/>
+
+	<!-- HLSQ registers -->
+	<reg32 offset="0x0e00" name="HLSQ_TIMEOUT_THRESHOLD"/>
+	<reg32 offset="0x0e04" name="HLSQ_DEBUG_ECO_CONTROL"/>
+	<!-- always 00000000: -->
+	<reg32 offset="0x0e05" name="HLSQ_MODE_CONTROL"/>
+	<reg32 offset="0x0e0e" name="HLSQ_PERF_PIPE_MASK"/>
+	<reg32 offset="0x0e06" name="HLSQ_PERFCTR_HLSQ_SEL_0" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e07" name="HLSQ_PERFCTR_HLSQ_SEL_1" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e08" name="HLSQ_PERFCTR_HLSQ_SEL_2" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e09" name="HLSQ_PERFCTR_HLSQ_SEL_3" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e0a" name="HLSQ_PERFCTR_HLSQ_SEL_4" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e0b" name="HLSQ_PERFCTR_HLSQ_SEL_5" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e0c" name="HLSQ_PERFCTR_HLSQ_SEL_6" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e0d" name="HLSQ_PERFCTR_HLSQ_SEL_7" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x23c0" name="HLSQ_CONTROL_0_REG">
+		<!-- I guess same as a3xx, but so far only seen 08000050 -->
+		<bitfield name="FSTHREADSIZE" pos="4" type="a3xx_threadsize"/>
+		<bitfield name="FSSUPERTHREADENABLE" pos="6" type="boolean"/>
+		<bitfield name="SPSHADERRESTART" pos="9" type="boolean"/>
+		<bitfield name="RESERVED2" pos="10" type="boolean"/>
+		<bitfield name="CHUNKDISABLE" pos="26" type="boolean"/>
+		<bitfield name="CONSTMODE" pos="27" type="uint"/>
+		<bitfield name="LAZYUPDATEDISABLE" pos="28" type="boolean"/>
+		<bitfield name="SPCONSTFULLUPDATE" pos="29" type="boolean"/>
+		<bitfield name="TPFULLUPDATE" pos="30" type="boolean"/>
+		<bitfield name="SINGLECONTEXT" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x23c1" name="HLSQ_CONTROL_1_REG">
+		<bitfield name="VSTHREADSIZE" pos="6" type="a3xx_threadsize"/>
+		<bitfield name="VSSUPERTHREADENABLE" pos="8" type="boolean"/>
+		<bitfield name="RESERVED1" pos="9" type="boolean"/>
+		<bitfield name="COORDREGID" low="16" high="23" type="a3xx_regid"/>
+		<!-- set if gl_FragCoord.[zw] used in frag shader: -->
+		<bitfield name="ZWCOORDREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x23c2" name="HLSQ_CONTROL_2_REG">
+		<bitfield name="PRIMALLOCTHRESHOLD" low="26" high="31" type="uint"/>
+		<bitfield name="FACEREGID" low="2" high="9" type="a3xx_regid"/>
+		<bitfield name="SAMPLEID_REGID" low="10" high="17" type="a3xx_regid"/>
+		<bitfield name="SAMPLEMASK_REGID" low="18" high="25" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x23c3" name="HLSQ_CONTROL_3_REG">
+		<!-- register loaded with position (bary.f) -->
+		<bitfield name="IJ_PERSP_PIXEL" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_PIXEL" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="IJ_PERSP_CENTROID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_CENTROID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<!-- 0x23c4 3 regids, lowest one goes to 0 when *not* per-sample shading -->
+	<reg32 offset="0x23c4" name="HLSQ_CONTROL_4_REG">
+		<bitfield name="IJ_PERSP_SAMPLE" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_SAMPLE" low="8" high="15" type="a3xx_regid"/>
+	</reg32>
+
+	<bitset name="a4xx_xs_control_reg" inline="yes">
+		<bitfield name="CONSTLENGTH" low="0" high="7" type="uint"/>
+		<bitfield name="CONSTOBJECTOFFSET" low="8" high="14" type="uint"/>
+		<bitfield name="SSBO_ENABLE" pos="15" type="boolean"/>
+		<bitfield name="ENABLED" pos="16" type="boolean"/>
+		<bitfield name="SHADEROBJOFFSET" low="17" high="23" type="uint"/>
+		<bitfield name="INSTRLENGTH" low="24" high="31" type="uint"/>
+	</bitset>
+	<reg32 offset="0x23c5" name="HLSQ_VS_CONTROL_REG" type="a4xx_xs_control_reg"/>
+	<reg32 offset="0x23c6" name="HLSQ_FS_CONTROL_REG" type="a4xx_xs_control_reg"/>
+	<reg32 offset="0x23c7" name="HLSQ_HS_CONTROL_REG" type="a4xx_xs_control_reg"/>
+	<reg32 offset="0x23c8" name="HLSQ_DS_CONTROL_REG" type="a4xx_xs_control_reg"/>
+	<reg32 offset="0x23c9" name="HLSQ_GS_CONTROL_REG" type="a4xx_xs_control_reg"/>
+	<reg32 offset="0x23ca" name="HLSQ_CS_CONTROL_REG" type="a4xx_xs_control_reg"/>
+	<reg32 offset="0x23cd" name="HLSQ_CL_NDRANGE_0">
+		<bitfield name="KERNELDIM" low="0" high="1" type="uint"/>
+		<!-- localsize is value minus one: -->
+		<bitfield name="LOCALSIZEX" low="2" high="11" type="uint"/>
+		<bitfield name="LOCALSIZEY" low="12" high="21" type="uint"/>
+		<bitfield name="LOCALSIZEZ" low="22" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x23ce" name="HLSQ_CL_NDRANGE_1">
+		<bitfield name="SIZE_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x23cf" name="HLSQ_CL_NDRANGE_2"/>
+	<reg32 offset="0x23d0" name="HLSQ_CL_NDRANGE_3">
+		<bitfield name="SIZE_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x23d1" name="HLSQ_CL_NDRANGE_4"/>
+	<reg32 offset="0x23d2" name="HLSQ_CL_NDRANGE_5">
+		<bitfield name="SIZE_Z" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x23d3" name="HLSQ_CL_NDRANGE_6"/>
+	<reg32 offset="0x23d4" name="HLSQ_CL_CONTROL_0">
+		<bitfield name="WGIDCONSTID" low="0" high="11" type="a3xx_regid"/>
+		<bitfield name="KERNELDIMCONSTID" low="12" high="23" type="a3xx_regid"/>
+		<bitfield name="LOCALIDREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x23d5" name="HLSQ_CL_CONTROL_1">
+		<!-- GLOBALSIZECONSTID? "kernel size" -->
+		<bitfield name="UNK0CONSTID" low="0" high="11" type="a3xx_regid"/>
+		<bitfield name="WORKGROUPSIZECONSTID" low="12" high="23" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x23d6" name="HLSQ_CL_KERNEL_CONST">
+		<!-- GLOBALOFFSETCONSTID -->
+		<bitfield name="UNK0CONSTID" low="0" high="11" type="a3xx_regid"/>
+		<bitfield name="NUMWGCONSTID" low="12" high="23" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x23d7" name="HLSQ_CL_KERNEL_GROUP_X"/>
+	<reg32 offset="0x23d8" name="HLSQ_CL_KERNEL_GROUP_Y"/>
+	<reg32 offset="0x23d9" name="HLSQ_CL_KERNEL_GROUP_Z"/>
+	<reg32 offset="0x23da" name="HLSQ_CL_WG_OFFSET">
+		<!-- WGOFFSETCONSTID -->
+		<bitfield name="UNK0CONSTID" low="0" high="11" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x23db" name="HLSQ_UPDATE_CONTROL"/>
+
+	<!-- PC registers -->
+	<reg32 offset="0x0d00" name="PC_BINNING_COMMAND">
+		<bitfield name="BINNING_ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0d08" name="PC_TESSFACTOR_ADDR"/>
+	<reg32 offset="0x0d0c" name="PC_DRAWCALL_SETUP_OVERRIDE"/>
+	<reg32 offset="0x0d10" name="PC_PERFCTR_PC_SEL_0" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d11" name="PC_PERFCTR_PC_SEL_1" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d12" name="PC_PERFCTR_PC_SEL_2" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d13" name="PC_PERFCTR_PC_SEL_3" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d14" name="PC_PERFCTR_PC_SEL_4" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d15" name="PC_PERFCTR_PC_SEL_5" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d16" name="PC_PERFCTR_PC_SEL_6" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d17" name="PC_PERFCTR_PC_SEL_7" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x21c0" name="PC_BIN_BASE"/>
+	<reg32 offset="0x21c2" name="PC_VSTREAM_CONTROL">
+		<doc>SIZE is current pipe width * height (in tiles)</doc>
+		<bitfield name="SIZE" low="16" high="21" type="uint"/>
+		<doc>
+			N is some sort of slot # between 0..(SIZE-1).  In case
+			multiple tiles use same pipe, each tile gets unique slot #
+		</doc>
+		<bitfield name="N" low="22" high="26" type="uint"/>
+	</reg32>
+	<reg32 offset="0x21c4" name="PC_PRIM_VTX_CNTL">
+		<!-- bit0 set if there is >= 1 varying (actually used by FS) -->
+		<bitfield name="VAROUT" low="0" high="3" type="uint">
+			<doc>in groups of 4x vec4, blob only uses values
+			0, 1, 2, 4, 6, 8</doc>
+		</bitfield>
+		<bitfield name="PRIMITIVE_RESTART" pos="20" type="boolean"/>
+		<bitfield name="PROVOKING_VTX_LAST" pos="25" type="boolean"/>
+		<!-- PSIZE bit set if gl_PointSize written: -->
+		<bitfield name="PSIZE" pos="26" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x21c5" name="PC_PRIM_VTX_CNTL2">
+		<bitfield name="POLYMODE_FRONT_PTYPE" low="0" high="2" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="POLYMODE_BACK_PTYPE" low="3" high="5" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="POLYMODE_ENABLE" pos="6" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x21c6" name="PC_RESTART_INDEX"/>
+	<reg32 offset="0x21e5" name="PC_GS_PARAM">
+		<bitfield name="MAX_VERTICES" low="0" high="9" type="uint"/><!-- +1, i.e. max is 1024 -->
+		<bitfield name="INVOCATIONS" low="11" high="15" type="uint"/><!-- +1, i.e. max is 32 -->
+		<bitfield name="PRIMTYPE" low="23" high="24" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="LAYER" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x21e7" name="PC_HS_PARAM">
+		<bitfield name="VERTICES_OUT" low="0" high="5" type="uint"/>
+		<bitfield name="SPACING" low="21" high="22" type="a4xx_tess_spacing"/>
+		<bitfield name="CW" pos="23" type="boolean"/>
+		<bitfield name="CONNECTED" pos="24" type="boolean"/>
+	</reg32>
+
+	<!-- VBIF registers -->
+	<reg32 offset="0x3000" name="VBIF_VERSION"/>
+	<reg32 offset="0x3001" name="VBIF_CLKON">
+		<bitfield name="FORCE_ON_TESTBUS" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x301c" name="VBIF_ABIT_SORT"/>
+	<reg32 offset="0x301d" name="VBIF_ABIT_SORT_CONF"/>
+	<reg32 offset="0x302a" name="VBIF_GATE_OFF_WRREQ_EN"/>
+	<reg32 offset="0x302c" name="VBIF_IN_RD_LIM_CONF0"/>
+	<reg32 offset="0x302d" name="VBIF_IN_RD_LIM_CONF1"/>
+	<reg32 offset="0x3030" name="VBIF_IN_WR_LIM_CONF0"/>
+	<reg32 offset="0x3031" name="VBIF_IN_WR_LIM_CONF1"/>
+	<reg32 offset="0x3049" name="VBIF_ROUND_ROBIN_QOS_ARB"/>
+	<reg32 offset="0x30c0" name="VBIF_PERF_CNT_EN0"/>
+	<reg32 offset="0x30c1" name="VBIF_PERF_CNT_EN1"/>
+	<reg32 offset="0x30c2" name="VBIF_PERF_CNT_EN2"/>
+	<reg32 offset="0x30c3" name="VBIF_PERF_CNT_EN3"/>
+	<reg32 offset="0x30d0" name="VBIF_PERF_CNT_SEL0" type="a4xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d1" name="VBIF_PERF_CNT_SEL1" type="a4xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d2" name="VBIF_PERF_CNT_SEL2" type="a4xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d3" name="VBIF_PERF_CNT_SEL3" type="a4xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d8" name="VBIF_PERF_CNT_LOW0"/>
+	<reg32 offset="0x30d9" name="VBIF_PERF_CNT_LOW1"/>
+	<reg32 offset="0x30da" name="VBIF_PERF_CNT_LOW2"/>
+	<reg32 offset="0x30db" name="VBIF_PERF_CNT_LOW3"/>
+	<reg32 offset="0x30e0" name="VBIF_PERF_CNT_HIGH0"/>
+	<reg32 offset="0x30e1" name="VBIF_PERF_CNT_HIGH1"/>
+	<reg32 offset="0x30e2" name="VBIF_PERF_CNT_HIGH2"/>
+	<reg32 offset="0x30e3" name="VBIF_PERF_CNT_HIGH3"/>
+	<reg32 offset="0x3100" name="VBIF_PERF_PWR_CNT_EN0"/>
+	<reg32 offset="0x3101" name="VBIF_PERF_PWR_CNT_EN1"/>
+	<reg32 offset="0x3102" name="VBIF_PERF_PWR_CNT_EN2"/>
+
+	<!--
+	Unknown registers:
+	(mostly related to DX11 features not used yet, I guess?)
+	-->
+
+	<!-- always 00000006: -->
+	<reg32 offset="0x0cc5" name="UNKNOWN_0CC5"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x0cc6" name="UNKNOWN_0CC6"/>
+
+	<!-- always 00000001: -->
+	<reg32 offset="0x0d01" name="UNKNOWN_0D01"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x0e42" name="UNKNOWN_0E42"/>
+
+	<!-- always 00040000: -->
+	<reg32 offset="0x0ec2" name="UNKNOWN_0EC2"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2001" name="UNKNOWN_2001"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x209b" name="UNKNOWN_209B"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x20ef" name="UNKNOWN_20EF"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2152" name="UNKNOWN_2152"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2153" name="UNKNOWN_2153"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2154" name="UNKNOWN_2154"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2155" name="UNKNOWN_2155"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2156" name="UNKNOWN_2156"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2157" name="UNKNOWN_2157"/>
+
+	<!-- always 0000000b: -->
+	<reg32 offset="0x21c3" name="UNKNOWN_21C3"/>
+
+	<!-- always 00000001: -->
+	<reg32 offset="0x21e6" name="UNKNOWN_21E6"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2209" name="UNKNOWN_2209"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x22d7" name="UNKNOWN_22D7"/>
+
+        <!-- always 00fcfc00: -->
+        <reg32 offset="0x2352" name="UNKNOWN_2352"/>
+
+</domain>
+
+
+<domain name="A4XX_TEX_SAMP" width="32">
+	<doc>Texture sampler dwords</doc>
+	<enum name="a4xx_tex_filter">
+		<value name="A4XX_TEX_NEAREST" value="0"/>
+		<value name="A4XX_TEX_LINEAR" value="1"/>
+		<value name="A4XX_TEX_ANISO" value="2"/>
+	</enum>
+	<enum name="a4xx_tex_clamp">
+		<value name="A4XX_TEX_REPEAT" value="0"/>
+		<value name="A4XX_TEX_CLAMP_TO_EDGE" value="1"/>
+		<value name="A4XX_TEX_MIRROR_REPEAT" value="2"/>
+		<value name="A4XX_TEX_CLAMP_TO_BORDER" value="3"/>
+		<value name="A4XX_TEX_MIRROR_CLAMP" value="4"/>
+	</enum>
+	<enum name="a4xx_tex_aniso">
+		<value name="A4XX_TEX_ANISO_1" value="0"/>
+		<value name="A4XX_TEX_ANISO_2" value="1"/>
+		<value name="A4XX_TEX_ANISO_4" value="2"/>
+		<value name="A4XX_TEX_ANISO_8" value="3"/>
+		<value name="A4XX_TEX_ANISO_16" value="4"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="MIPFILTER_LINEAR_NEAR" pos="0" type="boolean"/>
+		<bitfield name="XY_MAG" low="1" high="2" type="a4xx_tex_filter"/>
+		<bitfield name="XY_MIN" low="3" high="4" type="a4xx_tex_filter"/>
+		<bitfield name="WRAP_S" low="5" high="7" type="a4xx_tex_clamp"/>
+		<bitfield name="WRAP_T" low="8" high="10" type="a4xx_tex_clamp"/>
+		<bitfield name="WRAP_R" low="11" high="13" type="a4xx_tex_clamp"/>
+		<bitfield name="ANISO" low="14" high="16" type="a4xx_tex_aniso"/>
+		<bitfield name="LOD_BIAS" low="19" high="31" type="fixed" radix="8"/><!-- no idea how many bits for real -->
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="COMPARE_FUNC" low="1" high="3" type="adreno_compare_func"/>
+		<bitfield name="CUBEMAPSEAMLESSFILTOFF" pos="4" type="boolean"/>
+		<bitfield name="UNNORM_COORDS" pos="5" type="boolean"/>
+		<bitfield name="MIPFILTER_LINEAR_FAR" pos="6" type="boolean"/>
+		<bitfield name="MAX_LOD" low="8" high="19" type="ufixed" radix="8"/>
+		<bitfield name="MIN_LOD" low="20" high="31" type="ufixed" radix="8"/>
+	</reg32>
+</domain>
+
+<domain name="A4XX_TEX_CONST" width="32">
+	<doc>Texture constant dwords</doc>
+	<enum name="a4xx_tex_swiz">
+		<!-- same as a2xx? -->
+		<value name="A4XX_TEX_X" value="0"/>
+		<value name="A4XX_TEX_Y" value="1"/>
+		<value name="A4XX_TEX_Z" value="2"/>
+		<value name="A4XX_TEX_W" value="3"/>
+		<value name="A4XX_TEX_ZERO" value="4"/>
+		<value name="A4XX_TEX_ONE" value="5"/>
+	</enum>
+	<enum name="a4xx_tex_type">
+		<value name="A4XX_TEX_1D" value="0"/>
+		<value name="A4XX_TEX_2D" value="1"/>
+		<value name="A4XX_TEX_CUBE" value="2"/>
+		<value name="A4XX_TEX_3D" value="3"/>
+		<value name="A4XX_TEX_BUFFER" value="4"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="TILED" pos="0" type="boolean"/>
+		<bitfield name="SRGB" pos="2" type="boolean"/>
+		<bitfield name="SWIZ_X" low="4" high="6" type="a4xx_tex_swiz"/>
+		<bitfield name="SWIZ_Y" low="7" high="9" type="a4xx_tex_swiz"/>
+		<bitfield name="SWIZ_Z" low="10" high="12" type="a4xx_tex_swiz"/>
+		<bitfield name="SWIZ_W" low="13" high="15" type="a4xx_tex_swiz"/>
+		<bitfield name="MIPLVLS" low="16" high="19" type="uint"/>
+		<bitfield name="FMT" low="22" high="28" type="a4xx_tex_fmt"/>
+		<bitfield name="TYPE" low="29" high="31" type="a4xx_tex_type"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="HEIGHT" low="0" high="14" type="uint"/>
+		<bitfield name="WIDTH" low="15" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<!-- minimum pitch (for mipmap levels): log2(pitchalign / 32) -->
+		<bitfield name="PITCHALIGN" low="0" high="3" type="uint"/>
+		<bitfield name="BUFFER" pos="6" type="boolean"/>
+		<doc>Pitch in bytes (so actually stride)</doc>
+		<bitfield name="PITCH" low="9" high="29" type="uint"/>
+		<bitfield name="SWAP" low="30" high="31" type="a3xx_color_swap"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="LAYERSZ" low="0" high="13" shr="12" type="uint"/>
+		<bitfield name="DEPTH" low="18" high="30" type="uint"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<!--
+		like a3xx we seem to have two LAYERSZ's.. although this one
+		seems too small to be useful, and when it overflows blob just
+		sets it to zero..
+		 -->
+		<bitfield name="LAYERSZ" low="0" high="3" shr="12" type="uint"/>
+		<bitfield name="BASE" low="5" high="31" shr="5"/>
+	</reg32>
+	<reg32 offset="5" name="5"/>
+	<reg32 offset="6" name="6"/>
+	<reg32 offset="7" name="7"/>
+</domain>
+
+<domain name="A4XX_SSBO_0" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="BASE" low="5" high="31" shr="5"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<doc>Pitch in bytes (so actually stride)</doc>
+		<bitfield name="PITCH" low="0" high="21" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="ARRAY_PITCH" low="12" high="25" shr="12" type="uint"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<!-- bytes per pixel: -->
+		<bitfield name="CPP" low="0" high="5" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="A4XX_SSBO_1" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="CPP" low="0" high="4" type="uint"/>
+		<bitfield name="FMT" low="8" high="15" type="a4xx_color_fmt"/>
+		<bitfield name="WIDTH" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="HEIGHT" low="0" high="15" type="uint"/>
+		<bitfield name="DEPTH" low="16" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/adreno/a5xx.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/adreno/a5xx.xml
@@ -0,0 +1,3039 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="adreno/adreno_common.xml"/>
+<import file="adreno/adreno_pm4.xml"/>
+
+<enum name="a5xx_color_fmt">
+	<value value="0x02" name="RB5_A8_UNORM"/>
+	<value value="0x03" name="RB5_R8_UNORM"/>
+	<value value="0x04" name="RB5_R8_SNORM"/>
+	<value value="0x05" name="RB5_R8_UINT"/>
+	<value value="0x06" name="RB5_R8_SINT"/>
+	<value value="0x08" name="RB5_R4G4B4A4_UNORM"/>
+	<value value="0x0a" name="RB5_R5G5B5A1_UNORM"/>
+	<value value="0x0e" name="RB5_R5G6B5_UNORM"/>
+	<value value="0x0f" name="RB5_R8G8_UNORM"/>
+	<value value="0x10" name="RB5_R8G8_SNORM"/>
+	<value value="0x11" name="RB5_R8G8_UINT"/>
+	<value value="0x12" name="RB5_R8G8_SINT"/>
+	<value value="0x15" name="RB5_R16_UNORM"/>
+	<value value="0x16" name="RB5_R16_SNORM"/>
+	<value value="0x17" name="RB5_R16_FLOAT"/>
+	<value value="0x18" name="RB5_R16_UINT"/>
+	<value value="0x19" name="RB5_R16_SINT"/>
+	<value value="0x30" name="RB5_R8G8B8A8_UNORM"/>
+	<value value="0x31" name="RB5_R8G8B8_UNORM"/>
+	<value value="0x32" name="RB5_R8G8B8A8_SNORM"/>
+	<value value="0x33" name="RB5_R8G8B8A8_UINT"/>
+	<value value="0x34" name="RB5_R8G8B8A8_SINT"/>
+	<value value="0x37" name="RB5_R10G10B10A2_UNORM"/>  <!-- GL_RGB10_A2 -->
+	<value value="0x3a" name="RB5_R10G10B10A2_UINT"/>   <!-- GL_RGB10_A2UI -->
+	<value value="0x42" name="RB5_R11G11B10_FLOAT"/>    <!-- GL_R11F_G11F_B10F -->
+	<value value="0x43" name="RB5_R16G16_UNORM"/>
+	<value value="0x44" name="RB5_R16G16_SNORM"/>
+	<value value="0x45" name="RB5_R16G16_FLOAT"/>
+	<value value="0x46" name="RB5_R16G16_UINT"/>
+	<value value="0x47" name="RB5_R16G16_SINT"/>
+	<value value="0x4a" name="RB5_R32_FLOAT"/>
+	<value value="0x4b" name="RB5_R32_UINT"/>
+	<value value="0x4c" name="RB5_R32_SINT"/>
+	<value value="0x60" name="RB5_R16G16B16A16_UNORM"/>
+	<value value="0x61" name="RB5_R16G16B16A16_SNORM"/>
+	<value value="0x62" name="RB5_R16G16B16A16_FLOAT"/>
+	<value value="0x63" name="RB5_R16G16B16A16_UINT"/>
+	<value value="0x64" name="RB5_R16G16B16A16_SINT"/>
+	<value value="0x67" name="RB5_R32G32_FLOAT"/>
+	<value value="0x68" name="RB5_R32G32_UINT"/>
+	<value value="0x69" name="RB5_R32G32_SINT"/>
+	<value value="0x82" name="RB5_R32G32B32A32_FLOAT"/>
+	<value value="0x83" name="RB5_R32G32B32A32_UINT"/>
+	<value value="0x84" name="RB5_R32G32B32A32_SINT"/>
+
+	<value value="0xff" name="RB5_NONE"/>
+</enum>
+
+<enum name="a5xx_tile_mode">
+	<value name="TILE5_LINEAR" value="0"/>
+	<value name="TILE5_2" value="2"/>
+	<value name="TILE5_3" value="3"/>
+</enum>
+
+<enum name="a5xx_vtx_fmt" prefix="chipset">
+	<value value="0x03" name="VFMT5_8_UNORM"/>
+	<value value="0x04" name="VFMT5_8_SNORM"/>
+	<value value="0x05" name="VFMT5_8_UINT"/>
+	<value value="0x06" name="VFMT5_8_SINT"/>
+
+	<value value="0x0f" name="VFMT5_8_8_UNORM"/>
+	<value value="0x10" name="VFMT5_8_8_SNORM"/>
+	<value value="0x11" name="VFMT5_8_8_UINT"/>
+	<value value="0x12" name="VFMT5_8_8_SINT"/>
+
+	<value value="0x15" name="VFMT5_16_UNORM"/>
+	<value value="0x16" name="VFMT5_16_SNORM"/>
+	<value value="0x17" name="VFMT5_16_FLOAT"/>
+	<value value="0x18" name="VFMT5_16_UINT"/>
+	<value value="0x19" name="VFMT5_16_SINT"/>
+
+	<value value="0x21" name="VFMT5_8_8_8_UNORM"/>
+	<value value="0x22" name="VFMT5_8_8_8_SNORM"/>
+	<value value="0x23" name="VFMT5_8_8_8_UINT"/>
+	<value value="0x24" name="VFMT5_8_8_8_SINT"/>
+
+	<value value="0x30" name="VFMT5_8_8_8_8_UNORM"/>
+	<value value="0x32" name="VFMT5_8_8_8_8_SNORM"/>
+	<value value="0x33" name="VFMT5_8_8_8_8_UINT"/>
+	<value value="0x34" name="VFMT5_8_8_8_8_SINT"/>
+
+	<value value="0x36" name="VFMT5_10_10_10_2_UNORM"/>
+	<value value="0x39" name="VFMT5_10_10_10_2_SNORM"/>
+	<value value="0x3a" name="VFMT5_10_10_10_2_UINT"/>
+	<value value="0x3b" name="VFMT5_10_10_10_2_SINT"/>
+
+	<value value="0x42" name="VFMT5_11_11_10_FLOAT"/>
+
+	<value value="0x43" name="VFMT5_16_16_UNORM"/>
+	<value value="0x44" name="VFMT5_16_16_SNORM"/>
+	<value value="0x45" name="VFMT5_16_16_FLOAT"/>
+	<value value="0x46" name="VFMT5_16_16_UINT"/>
+	<value value="0x47" name="VFMT5_16_16_SINT"/>
+
+	<value value="0x48" name="VFMT5_32_UNORM"/>
+	<value value="0x49" name="VFMT5_32_SNORM"/>
+	<value value="0x4a" name="VFMT5_32_FLOAT"/>
+	<value value="0x4b" name="VFMT5_32_UINT"/>
+	<value value="0x4c" name="VFMT5_32_SINT"/>
+	<value value="0x4d" name="VFMT5_32_FIXED"/>
+
+	<value value="0x58" name="VFMT5_16_16_16_UNORM"/>
+	<value value="0x59" name="VFMT5_16_16_16_SNORM"/>
+	<value value="0x5a" name="VFMT5_16_16_16_FLOAT"/>
+	<value value="0x5b" name="VFMT5_16_16_16_UINT"/>
+	<value value="0x5c" name="VFMT5_16_16_16_SINT"/>
+
+	<value value="0x60" name="VFMT5_16_16_16_16_UNORM"/>
+	<value value="0x61" name="VFMT5_16_16_16_16_SNORM"/>
+	<value value="0x62" name="VFMT5_16_16_16_16_FLOAT"/>
+	<value value="0x63" name="VFMT5_16_16_16_16_UINT"/>
+	<value value="0x64" name="VFMT5_16_16_16_16_SINT"/>
+
+	<value value="0x65" name="VFMT5_32_32_UNORM"/>
+	<value value="0x66" name="VFMT5_32_32_SNORM"/>
+	<value value="0x67" name="VFMT5_32_32_FLOAT"/>
+	<value value="0x68" name="VFMT5_32_32_UINT"/>
+	<value value="0x69" name="VFMT5_32_32_SINT"/>
+	<value value="0x6a" name="VFMT5_32_32_FIXED"/>
+
+	<value value="0x70" name="VFMT5_32_32_32_UNORM"/>
+	<value value="0x71" name="VFMT5_32_32_32_SNORM"/>
+	<value value="0x72" name="VFMT5_32_32_32_UINT"/>
+	<value value="0x73" name="VFMT5_32_32_32_SINT"/>
+	<value value="0x74" name="VFMT5_32_32_32_FLOAT"/>
+	<value value="0x75" name="VFMT5_32_32_32_FIXED"/>
+
+	<value value="0x80" name="VFMT5_32_32_32_32_UNORM"/>
+	<value value="0x81" name="VFMT5_32_32_32_32_SNORM"/>
+	<value value="0x82" name="VFMT5_32_32_32_32_FLOAT"/>
+	<value value="0x83" name="VFMT5_32_32_32_32_UINT"/>
+	<value value="0x84" name="VFMT5_32_32_32_32_SINT"/>
+	<value value="0x85" name="VFMT5_32_32_32_32_FIXED"/>
+
+	<value value="0xff" name="VFMT5_NONE"/>
+</enum>
+
+<enum name="a5xx_tex_fmt">
+	<value value="0x02" name="TFMT5_A8_UNORM"/>
+	<value value="0x03" name="TFMT5_8_UNORM"/>
+	<value value="0x04" name="TFMT5_8_SNORM"/>
+	<value value="0x05" name="TFMT5_8_UINT"/>
+	<value value="0x06" name="TFMT5_8_SINT"/>
+	<value value="0x08" name="TFMT5_4_4_4_4_UNORM"/>
+	<value value="0x0a" name="TFMT5_5_5_5_1_UNORM"/>
+	<value value="0x0e" name="TFMT5_5_6_5_UNORM"/>
+	<value value="0x0f" name="TFMT5_8_8_UNORM"/>
+	<value value="0x10" name="TFMT5_8_8_SNORM"/>
+	<value value="0x11" name="TFMT5_8_8_UINT"/>
+	<value value="0x12" name="TFMT5_8_8_SINT"/>
+	<value value="0x13" name="TFMT5_L8_A8_UNORM"/>
+	<value value="0x15" name="TFMT5_16_UNORM"/>
+	<value value="0x16" name="TFMT5_16_SNORM"/>
+	<value value="0x17" name="TFMT5_16_FLOAT"/>
+	<value value="0x18" name="TFMT5_16_UINT"/>
+	<value value="0x19" name="TFMT5_16_SINT"/>
+	<value value="0x30" name="TFMT5_8_8_8_8_UNORM"/>
+	<value value="0x31" name="TFMT5_8_8_8_UNORM"/>
+	<value value="0x32" name="TFMT5_8_8_8_8_SNORM"/>
+	<value value="0x33" name="TFMT5_8_8_8_8_UINT"/>
+	<value value="0x34" name="TFMT5_8_8_8_8_SINT"/>
+	<value value="0x35" name="TFMT5_9_9_9_E5_FLOAT"/>
+	<value value="0x36" name="TFMT5_10_10_10_2_UNORM"/>
+	<value value="0x3a" name="TFMT5_10_10_10_2_UINT"/>
+	<value value="0x42" name="TFMT5_11_11_10_FLOAT"/>
+	<value value="0x43" name="TFMT5_16_16_UNORM"/>
+	<value value="0x44" name="TFMT5_16_16_SNORM"/>
+	<value value="0x45" name="TFMT5_16_16_FLOAT"/>
+	<value value="0x46" name="TFMT5_16_16_UINT"/>
+	<value value="0x47" name="TFMT5_16_16_SINT"/>
+	<value value="0x4a" name="TFMT5_32_FLOAT"/>
+	<value value="0x4b" name="TFMT5_32_UINT"/>
+	<value value="0x4c" name="TFMT5_32_SINT"/>
+	<value value="0x60" name="TFMT5_16_16_16_16_UNORM"/>
+	<value value="0x61" name="TFMT5_16_16_16_16_SNORM"/>
+	<value value="0x62" name="TFMT5_16_16_16_16_FLOAT"/>
+	<value value="0x63" name="TFMT5_16_16_16_16_UINT"/>
+	<value value="0x64" name="TFMT5_16_16_16_16_SINT"/>
+	<value value="0x67" name="TFMT5_32_32_FLOAT"/>
+	<value value="0x68" name="TFMT5_32_32_UINT"/>
+	<value value="0x69" name="TFMT5_32_32_SINT"/>
+	<value value="0x72" name="TFMT5_32_32_32_UINT"/>
+	<value value="0x73" name="TFMT5_32_32_32_SINT"/>
+	<value value="0x74" name="TFMT5_32_32_32_FLOAT"/>
+	<value value="0x82" name="TFMT5_32_32_32_32_FLOAT"/>
+	<value value="0x83" name="TFMT5_32_32_32_32_UINT"/>
+	<value value="0x84" name="TFMT5_32_32_32_32_SINT"/>
+	<value value="0xa0" name="TFMT5_X8Z24_UNORM"/>
+
+	<value value="0xab" name="TFMT5_ETC2_RG11_UNORM"/>
+	<value value="0xac" name="TFMT5_ETC2_RG11_SNORM"/>
+	<value value="0xad" name="TFMT5_ETC2_R11_UNORM"/>
+	<value value="0xae" name="TFMT5_ETC2_R11_SNORM"/>
+	<value value="0xaf" name="TFMT5_ETC1"/>
+	<value value="0xb0" name="TFMT5_ETC2_RGB8"/>
+	<value value="0xb1" name="TFMT5_ETC2_RGBA8"/>
+	<value value="0xb2" name="TFMT5_ETC2_RGB8A1"/>
+	<value value="0xb3" name="TFMT5_DXT1"/>
+	<value value="0xb4" name="TFMT5_DXT3"/>
+	<value value="0xb5" name="TFMT5_DXT5"/>
+	<value value="0xb7" name="TFMT5_RGTC1_UNORM"/>
+	<value value="0xb8" name="TFMT5_RGTC1_SNORM"/>
+	<value value="0xbb" name="TFMT5_RGTC2_UNORM"/>
+	<value value="0xbc" name="TFMT5_RGTC2_SNORM"/>
+	<value value="0xbe" name="TFMT5_BPTC_UFLOAT"/>
+	<value value="0xbf" name="TFMT5_BPTC_FLOAT"/>
+	<value value="0xc0" name="TFMT5_BPTC"/>
+	<value value="0xc1" name="TFMT5_ASTC_4x4"/>
+	<value value="0xc2" name="TFMT5_ASTC_5x4"/>
+	<value value="0xc3" name="TFMT5_ASTC_5x5"/>
+	<value value="0xc4" name="TFMT5_ASTC_6x5"/>
+	<value value="0xc5" name="TFMT5_ASTC_6x6"/>
+	<value value="0xc6" name="TFMT5_ASTC_8x5"/>
+	<value value="0xc7" name="TFMT5_ASTC_8x6"/>
+	<value value="0xc8" name="TFMT5_ASTC_8x8"/>
+	<value value="0xc9" name="TFMT5_ASTC_10x5"/>
+	<value value="0xca" name="TFMT5_ASTC_10x6"/>
+	<value value="0xcb" name="TFMT5_ASTC_10x8"/>
+	<value value="0xcc" name="TFMT5_ASTC_10x10"/>
+	<value value="0xcd" name="TFMT5_ASTC_12x10"/>
+	<value value="0xce" name="TFMT5_ASTC_12x12"/>
+
+	<value value="0xff" name="TFMT5_NONE"/>
+</enum>
+
+<enum name="a5xx_depth_format">
+	<value name="DEPTH5_NONE" value="0"/>
+	<value name="DEPTH5_16" value="1"/>
+	<value name="DEPTH5_24_8" value="2"/>
+	<value name="DEPTH5_32" value="4"/>
+</enum>
+
+<enum name="a5xx_blit_buf">
+	<value value="0" name="BLIT_MRT0"/>
+	<value value="1" name="BLIT_MRT1"/>
+	<value value="2" name="BLIT_MRT2"/>
+	<value value="3" name="BLIT_MRT3"/>
+	<value value="4" name="BLIT_MRT4"/>
+	<value value="5" name="BLIT_MRT5"/>
+	<value value="6" name="BLIT_MRT6"/>
+	<value value="7" name="BLIT_MRT7"/>
+	<value value="8" name="BLIT_ZS"/>       <!-- depth or combined depth+stencil -->
+	<value value="9" name="BLIT_S"/>        <!-- separate stencil -->
+</enum>
+
+<!-- see comment in a4xx.xml about script to extract countables from test-perf output -->
+<enum name="a5xx_cp_perfcounter_select">
+	<value value="0" name="PERF_CP_ALWAYS_COUNT"/>
+	<value value="1" name="PERF_CP_BUSY_GFX_CORE_IDLE"/>
+	<value value="2" name="PERF_CP_BUSY_CYCLES"/>
+	<value value="3" name="PERF_CP_PFP_IDLE"/>
+	<value value="4" name="PERF_CP_PFP_BUSY_WORKING"/>
+	<value value="5" name="PERF_CP_PFP_STALL_CYCLES_ANY"/>
+	<value value="6" name="PERF_CP_PFP_STARVE_CYCLES_ANY"/>
+	<value value="7" name="PERF_CP_PFP_ICACHE_MISS"/>
+	<value value="8" name="PERF_CP_PFP_ICACHE_HIT"/>
+	<value value="9" name="PERF_CP_PFP_MATCH_PM4_PKT_PROFILE"/>
+	<value value="10" name="PERF_CP_ME_BUSY_WORKING"/>
+	<value value="11" name="PERF_CP_ME_IDLE"/>
+	<value value="12" name="PERF_CP_ME_STARVE_CYCLES_ANY"/>
+	<value value="13" name="PERF_CP_ME_FIFO_EMPTY_PFP_IDLE"/>
+	<value value="14" name="PERF_CP_ME_FIFO_EMPTY_PFP_BUSY"/>
+	<value value="15" name="PERF_CP_ME_FIFO_FULL_ME_BUSY"/>
+	<value value="16" name="PERF_CP_ME_FIFO_FULL_ME_NON_WORKING"/>
+	<value value="17" name="PERF_CP_ME_STALL_CYCLES_ANY"/>
+	<value value="18" name="PERF_CP_ME_ICACHE_MISS"/>
+	<value value="19" name="PERF_CP_ME_ICACHE_HIT"/>
+	<value value="20" name="PERF_CP_NUM_PREEMPTIONS"/>
+	<value value="21" name="PERF_CP_PREEMPTION_REACTION_DELAY"/>
+	<value value="22" name="PERF_CP_PREEMPTION_SWITCH_OUT_TIME"/>
+	<value value="23" name="PERF_CP_PREEMPTION_SWITCH_IN_TIME"/>
+	<value value="24" name="PERF_CP_DEAD_DRAWS_IN_BIN_RENDER"/>
+	<value value="25" name="PERF_CP_PREDICATED_DRAWS_KILLED"/>
+	<value value="26" name="PERF_CP_MODE_SWITCH"/>
+	<value value="27" name="PERF_CP_ZPASS_DONE"/>
+	<value value="28" name="PERF_CP_CONTEXT_DONE"/>
+	<value value="29" name="PERF_CP_CACHE_FLUSH"/>
+	<value value="30" name="PERF_CP_LONG_PREEMPTIONS"/>
+</enum>
+
+<enum name="a5xx_rbbm_perfcounter_select">
+	<value value="0" name="PERF_RBBM_ALWAYS_COUNT"/>
+	<value value="1" name="PERF_RBBM_ALWAYS_ON"/>
+	<value value="2" name="PERF_RBBM_TSE_BUSY"/>
+	<value value="3" name="PERF_RBBM_RAS_BUSY"/>
+	<value value="4" name="PERF_RBBM_PC_DCALL_BUSY"/>
+	<value value="5" name="PERF_RBBM_PC_VSD_BUSY"/>
+	<value value="6" name="PERF_RBBM_STATUS_MASKED"/>
+	<value value="7" name="PERF_RBBM_COM_BUSY"/>
+	<value value="8" name="PERF_RBBM_DCOM_BUSY"/>
+	<value value="9" name="PERF_RBBM_VBIF_BUSY"/>
+	<value value="10" name="PERF_RBBM_VSC_BUSY"/>
+	<value value="11" name="PERF_RBBM_TESS_BUSY"/>
+	<value value="12" name="PERF_RBBM_UCHE_BUSY"/>
+	<value value="13" name="PERF_RBBM_HLSQ_BUSY"/>
+</enum>
+
+<enum name="a5xx_pc_perfcounter_select">
+	<value value="0" name="PERF_PC_BUSY_CYCLES"/>
+	<value value="1" name="PERF_PC_WORKING_CYCLES"/>
+	<value value="2" name="PERF_PC_STALL_CYCLES_VFD"/>
+	<value value="3" name="PERF_PC_STALL_CYCLES_TSE"/>
+	<value value="4" name="PERF_PC_STALL_CYCLES_VPC"/>
+	<value value="5" name="PERF_PC_STALL_CYCLES_UCHE"/>
+	<value value="6" name="PERF_PC_STALL_CYCLES_TESS"/>
+	<value value="7" name="PERF_PC_STALL_CYCLES_TSE_ONLY"/>
+	<value value="8" name="PERF_PC_STALL_CYCLES_VPC_ONLY"/>
+	<value value="9" name="PERF_PC_PASS1_TF_STALL_CYCLES"/>
+	<value value="10" name="PERF_PC_STARVE_CYCLES_FOR_INDEX"/>
+	<value value="11" name="PERF_PC_STARVE_CYCLES_FOR_TESS_FACTOR"/>
+	<value value="12" name="PERF_PC_STARVE_CYCLES_FOR_VIZ_STREAM"/>
+	<value value="13" name="PERF_PC_STARVE_CYCLES_FOR_POSITION"/>
+	<value value="14" name="PERF_PC_STARVE_CYCLES_DI"/>
+	<value value="15" name="PERF_PC_VIS_STREAMS_LOADED"/>
+	<value value="16" name="PERF_PC_INSTANCES"/>
+	<value value="17" name="PERF_PC_VPC_PRIMITIVES"/>
+	<value value="18" name="PERF_PC_DEAD_PRIM"/>
+	<value value="19" name="PERF_PC_LIVE_PRIM"/>
+	<value value="20" name="PERF_PC_VERTEX_HITS"/>
+	<value value="21" name="PERF_PC_IA_VERTICES"/>
+	<value value="22" name="PERF_PC_IA_PRIMITIVES"/>
+	<value value="23" name="PERF_PC_GS_PRIMITIVES"/>
+	<value value="24" name="PERF_PC_HS_INVOCATIONS"/>
+	<value value="25" name="PERF_PC_DS_INVOCATIONS"/>
+	<value value="26" name="PERF_PC_VS_INVOCATIONS"/>
+	<value value="27" name="PERF_PC_GS_INVOCATIONS"/>
+	<value value="28" name="PERF_PC_DS_PRIMITIVES"/>
+	<value value="29" name="PERF_PC_VPC_POS_DATA_TRANSACTION"/>
+	<value value="30" name="PERF_PC_3D_DRAWCALLS"/>
+	<value value="31" name="PERF_PC_2D_DRAWCALLS"/>
+	<value value="32" name="PERF_PC_NON_DRAWCALL_GLOBAL_EVENTS"/>
+	<value value="33" name="PERF_TESS_BUSY_CYCLES"/>
+	<value value="34" name="PERF_TESS_WORKING_CYCLES"/>
+	<value value="35" name="PERF_TESS_STALL_CYCLES_PC"/>
+	<value value="36" name="PERF_TESS_STARVE_CYCLES_PC"/>
+</enum>
+
+<enum name="a5xx_vfd_perfcounter_select">
+	<value value="0" name="PERF_VFD_BUSY_CYCLES"/>
+	<value value="1" name="PERF_VFD_STALL_CYCLES_UCHE"/>
+	<value value="2" name="PERF_VFD_STALL_CYCLES_VPC_ALLOC"/>
+	<value value="3" name="PERF_VFD_STALL_CYCLES_MISS_VB"/>
+	<value value="4" name="PERF_VFD_STALL_CYCLES_MISS_Q"/>
+	<value value="5" name="PERF_VFD_STALL_CYCLES_SP_INFO"/>
+	<value value="6" name="PERF_VFD_STALL_CYCLES_SP_ATTR"/>
+	<value value="7" name="PERF_VFD_STALL_CYCLES_VFDP_VB"/>
+	<value value="8" name="PERF_VFD_STALL_CYCLES_VFDP_Q"/>
+	<value value="9" name="PERF_VFD_DECODER_PACKER_STALL"/>
+	<value value="10" name="PERF_VFD_STARVE_CYCLES_UCHE"/>
+	<value value="11" name="PERF_VFD_RBUFFER_FULL"/>
+	<value value="12" name="PERF_VFD_ATTR_INFO_FIFO_FULL"/>
+	<value value="13" name="PERF_VFD_DECODED_ATTRIBUTE_BYTES"/>
+	<value value="14" name="PERF_VFD_NUM_ATTRIBUTES"/>
+	<value value="15" name="PERF_VFD_INSTRUCTIONS"/>
+	<value value="16" name="PERF_VFD_UPPER_SHADER_FIBERS"/>
+	<value value="17" name="PERF_VFD_LOWER_SHADER_FIBERS"/>
+	<value value="18" name="PERF_VFD_MODE_0_FIBERS"/>
+	<value value="19" name="PERF_VFD_MODE_1_FIBERS"/>
+	<value value="20" name="PERF_VFD_MODE_2_FIBERS"/>
+	<value value="21" name="PERF_VFD_MODE_3_FIBERS"/>
+	<value value="22" name="PERF_VFD_MODE_4_FIBERS"/>
+	<value value="23" name="PERF_VFD_TOTAL_VERTICES"/>
+	<value value="24" name="PERF_VFD_NUM_ATTR_MISS"/>
+	<value value="25" name="PERF_VFD_1_BURST_REQ"/>
+	<value value="26" name="PERF_VFDP_STALL_CYCLES_VFD"/>
+	<value value="27" name="PERF_VFDP_STALL_CYCLES_VFD_INDEX"/>
+	<value value="28" name="PERF_VFDP_STALL_CYCLES_VFD_PROG"/>
+	<value value="29" name="PERF_VFDP_STARVE_CYCLES_PC"/>
+	<value value="30" name="PERF_VFDP_VS_STAGE_32_WAVES"/>
+</enum>
+
+<enum name="a5xx_hlsq_perfcounter_select">
+	<value value="0" name="PERF_HLSQ_BUSY_CYCLES"/>
+	<value value="1" name="PERF_HLSQ_STALL_CYCLES_UCHE"/>
+	<value value="2" name="PERF_HLSQ_STALL_CYCLES_SP_STATE"/>
+	<value value="3" name="PERF_HLSQ_STALL_CYCLES_SP_FS_STAGE"/>
+	<value value="4" name="PERF_HLSQ_UCHE_LATENCY_CYCLES"/>
+	<value value="5" name="PERF_HLSQ_UCHE_LATENCY_COUNT"/>
+	<value value="6" name="PERF_HLSQ_FS_STAGE_32_WAVES"/>
+	<value value="7" name="PERF_HLSQ_FS_STAGE_64_WAVES"/>
+	<value value="8" name="PERF_HLSQ_QUADS"/>
+	<value value="9" name="PERF_HLSQ_SP_STATE_COPY_TRANS_FS_STAGE"/>
+	<value value="10" name="PERF_HLSQ_SP_STATE_COPY_TRANS_VS_STAGE"/>
+	<value value="11" name="PERF_HLSQ_TP_STATE_COPY_TRANS_FS_STAGE"/>
+	<value value="12" name="PERF_HLSQ_TP_STATE_COPY_TRANS_VS_STAGE"/>
+	<value value="13" name="PERF_HLSQ_CS_INVOCATIONS"/>
+	<value value="14" name="PERF_HLSQ_COMPUTE_DRAWCALLS"/>
+</enum>
+
+<enum name="a5xx_vpc_perfcounter_select">
+	<value value="0" name="PERF_VPC_BUSY_CYCLES"/>
+	<value value="1" name="PERF_VPC_WORKING_CYCLES"/>
+	<value value="2" name="PERF_VPC_STALL_CYCLES_UCHE"/>
+	<value value="3" name="PERF_VPC_STALL_CYCLES_VFD_WACK"/>
+	<value value="4" name="PERF_VPC_STALL_CYCLES_HLSQ_PRIM_ALLOC"/>
+	<value value="5" name="PERF_VPC_STALL_CYCLES_PC"/>
+	<value value="6" name="PERF_VPC_STALL_CYCLES_SP_LM"/>
+	<value value="7" name="PERF_VPC_POS_EXPORT_STALL_CYCLES"/>
+	<value value="8" name="PERF_VPC_STARVE_CYCLES_SP"/>
+	<value value="9" name="PERF_VPC_STARVE_CYCLES_LRZ"/>
+	<value value="10" name="PERF_VPC_PC_PRIMITIVES"/>
+	<value value="11" name="PERF_VPC_SP_COMPONENTS"/>
+	<value value="12" name="PERF_VPC_SP_LM_PRIMITIVES"/>
+	<value value="13" name="PERF_VPC_SP_LM_COMPONENTS"/>
+	<value value="14" name="PERF_VPC_SP_LM_DWORDS"/>
+	<value value="15" name="PERF_VPC_STREAMOUT_COMPONENTS"/>
+	<value value="16" name="PERF_VPC_GRANT_PHASES"/>
+</enum>
+
+<enum name="a5xx_tse_perfcounter_select">
+	<value value="0" name="PERF_TSE_BUSY_CYCLES"/>
+	<value value="1" name="PERF_TSE_CLIPPING_CYCLES"/>
+	<value value="2" name="PERF_TSE_STALL_CYCLES_RAS"/>
+	<value value="3" name="PERF_TSE_STALL_CYCLES_LRZ_BARYPLANE"/>
+	<value value="4" name="PERF_TSE_STALL_CYCLES_LRZ_ZPLANE"/>
+	<value value="5" name="PERF_TSE_STARVE_CYCLES_PC"/>
+	<value value="6" name="PERF_TSE_INPUT_PRIM"/>
+	<value value="7" name="PERF_TSE_INPUT_NULL_PRIM"/>
+	<value value="8" name="PERF_TSE_TRIVAL_REJ_PRIM"/>
+	<value value="9" name="PERF_TSE_CLIPPED_PRIM"/>
+	<value value="10" name="PERF_TSE_ZERO_AREA_PRIM"/>
+	<value value="11" name="PERF_TSE_FACENESS_CULLED_PRIM"/>
+	<value value="12" name="PERF_TSE_ZERO_PIXEL_PRIM"/>
+	<value value="13" name="PERF_TSE_OUTPUT_NULL_PRIM"/>
+	<value value="14" name="PERF_TSE_OUTPUT_VISIBLE_PRIM"/>
+	<value value="15" name="PERF_TSE_CINVOCATION"/>
+	<value value="16" name="PERF_TSE_CPRIMITIVES"/>
+	<value value="17" name="PERF_TSE_2D_INPUT_PRIM"/>
+	<value value="18" name="PERF_TSE_2D_ALIVE_CLCLES"/>
+</enum>
+
+<enum name="a5xx_ras_perfcounter_select">
+	<value value="0" name="PERF_RAS_BUSY_CYCLES"/>
+	<value value="1" name="PERF_RAS_SUPERTILE_ACTIVE_CYCLES"/>
+	<value value="2" name="PERF_RAS_STALL_CYCLES_LRZ"/>
+	<value value="3" name="PERF_RAS_STARVE_CYCLES_TSE"/>
+	<value value="4" name="PERF_RAS_SUPER_TILES"/>
+	<value value="5" name="PERF_RAS_8X4_TILES"/>
+	<value value="6" name="PERF_RAS_MASKGEN_ACTIVE"/>
+	<value value="7" name="PERF_RAS_FULLY_COVERED_SUPER_TILES"/>
+	<value value="8" name="PERF_RAS_FULLY_COVERED_8X4_TILES"/>
+	<value value="9" name="PERF_RAS_PRIM_KILLED_INVISILBE"/>
+</enum>
+
+<enum name="a5xx_lrz_perfcounter_select">
+	<value value="0" name="PERF_LRZ_BUSY_CYCLES"/>
+	<value value="1" name="PERF_LRZ_STARVE_CYCLES_RAS"/>
+	<value value="2" name="PERF_LRZ_STALL_CYCLES_RB"/>
+	<value value="3" name="PERF_LRZ_STALL_CYCLES_VSC"/>
+	<value value="4" name="PERF_LRZ_STALL_CYCLES_VPC"/>
+	<value value="5" name="PERF_LRZ_STALL_CYCLES_FLAG_PREFETCH"/>
+	<value value="6" name="PERF_LRZ_STALL_CYCLES_UCHE"/>
+	<value value="7" name="PERF_LRZ_LRZ_READ"/>
+	<value value="8" name="PERF_LRZ_LRZ_WRITE"/>
+	<value value="9" name="PERF_LRZ_READ_LATENCY"/>
+	<value value="10" name="PERF_LRZ_MERGE_CACHE_UPDATING"/>
+	<value value="11" name="PERF_LRZ_PRIM_KILLED_BY_MASKGEN"/>
+	<value value="12" name="PERF_LRZ_PRIM_KILLED_BY_LRZ"/>
+	<value value="13" name="PERF_LRZ_VISIBLE_PRIM_AFTER_LRZ"/>
+	<value value="14" name="PERF_LRZ_FULL_8X8_TILES"/>
+	<value value="15" name="PERF_LRZ_PARTIAL_8X8_TILES"/>
+	<value value="16" name="PERF_LRZ_TILE_KILLED"/>
+	<value value="17" name="PERF_LRZ_TOTAL_PIXEL"/>
+	<value value="18" name="PERF_LRZ_VISIBLE_PIXEL_AFTER_LRZ"/>
+</enum>
+
+<enum name="a5xx_uche_perfcounter_select">
+	<value value="0" name="PERF_UCHE_BUSY_CYCLES"/>
+	<value value="1" name="PERF_UCHE_STALL_CYCLES_VBIF"/>
+	<value value="2" name="PERF_UCHE_VBIF_LATENCY_CYCLES"/>
+	<value value="3" name="PERF_UCHE_VBIF_LATENCY_SAMPLES"/>
+	<value value="4" name="PERF_UCHE_VBIF_READ_BEATS_TP"/>
+	<value value="5" name="PERF_UCHE_VBIF_READ_BEATS_VFD"/>
+	<value value="6" name="PERF_UCHE_VBIF_READ_BEATS_HLSQ"/>
+	<value value="7" name="PERF_UCHE_VBIF_READ_BEATS_LRZ"/>
+	<value value="8" name="PERF_UCHE_VBIF_READ_BEATS_SP"/>
+	<value value="9" name="PERF_UCHE_READ_REQUESTS_TP"/>
+	<value value="10" name="PERF_UCHE_READ_REQUESTS_VFD"/>
+	<value value="11" name="PERF_UCHE_READ_REQUESTS_HLSQ"/>
+	<value value="12" name="PERF_UCHE_READ_REQUESTS_LRZ"/>
+	<value value="13" name="PERF_UCHE_READ_REQUESTS_SP"/>
+	<value value="14" name="PERF_UCHE_WRITE_REQUESTS_LRZ"/>
+	<value value="15" name="PERF_UCHE_WRITE_REQUESTS_SP"/>
+	<value value="16" name="PERF_UCHE_WRITE_REQUESTS_VPC"/>
+	<value value="17" name="PERF_UCHE_WRITE_REQUESTS_VSC"/>
+	<value value="18" name="PERF_UCHE_EVICTS"/>
+	<value value="19" name="PERF_UCHE_BANK_REQ0"/>
+	<value value="20" name="PERF_UCHE_BANK_REQ1"/>
+	<value value="21" name="PERF_UCHE_BANK_REQ2"/>
+	<value value="22" name="PERF_UCHE_BANK_REQ3"/>
+	<value value="23" name="PERF_UCHE_BANK_REQ4"/>
+	<value value="24" name="PERF_UCHE_BANK_REQ5"/>
+	<value value="25" name="PERF_UCHE_BANK_REQ6"/>
+	<value value="26" name="PERF_UCHE_BANK_REQ7"/>
+	<value value="27" name="PERF_UCHE_VBIF_READ_BEATS_CH0"/>
+	<value value="28" name="PERF_UCHE_VBIF_READ_BEATS_CH1"/>
+	<value value="29" name="PERF_UCHE_GMEM_READ_BEATS"/>
+	<value value="30" name="PERF_UCHE_FLAG_COUNT"/>
+</enum>
+
+<enum name="a5xx_tp_perfcounter_select">
+	<value value="0" name="PERF_TP_BUSY_CYCLES"/>
+	<value value="1" name="PERF_TP_STALL_CYCLES_UCHE"/>
+	<value value="2" name="PERF_TP_LATENCY_CYCLES"/>
+	<value value="3" name="PERF_TP_LATENCY_TRANS"/>
+	<value value="4" name="PERF_TP_FLAG_CACHE_REQUEST_SAMPLES"/>
+	<value value="5" name="PERF_TP_FLAG_CACHE_REQUEST_LATENCY"/>
+	<value value="6" name="PERF_TP_L1_CACHELINE_REQUESTS"/>
+	<value value="7" name="PERF_TP_L1_CACHELINE_MISSES"/>
+	<value value="8" name="PERF_TP_SP_TP_TRANS"/>
+	<value value="9" name="PERF_TP_TP_SP_TRANS"/>
+	<value value="10" name="PERF_TP_OUTPUT_PIXELS"/>
+	<value value="11" name="PERF_TP_FILTER_WORKLOAD_16BIT"/>
+	<value value="12" name="PERF_TP_FILTER_WORKLOAD_32BIT"/>
+	<value value="13" name="PERF_TP_QUADS_RECEIVED"/>
+	<value value="14" name="PERF_TP_QUADS_OFFSET"/>
+	<value value="15" name="PERF_TP_QUADS_SHADOW"/>
+	<value value="16" name="PERF_TP_QUADS_ARRAY"/>
+	<value value="17" name="PERF_TP_QUADS_GRADIENT"/>
+	<value value="18" name="PERF_TP_QUADS_1D"/>
+	<value value="19" name="PERF_TP_QUADS_2D"/>
+	<value value="20" name="PERF_TP_QUADS_BUFFER"/>
+	<value value="21" name="PERF_TP_QUADS_3D"/>
+	<value value="22" name="PERF_TP_QUADS_CUBE"/>
+	<value value="23" name="PERF_TP_STATE_CACHE_REQUESTS"/>
+	<value value="24" name="PERF_TP_STATE_CACHE_MISSES"/>
+	<value value="25" name="PERF_TP_DIVERGENT_QUADS_RECEIVED"/>
+	<value value="26" name="PERF_TP_BINDLESS_STATE_CACHE_REQUESTS"/>
+	<value value="27" name="PERF_TP_BINDLESS_STATE_CACHE_MISSES"/>
+	<value value="28" name="PERF_TP_PRT_NON_RESIDENT_EVENTS"/>
+	<value value="29" name="PERF_TP_OUTPUT_PIXELS_POINT"/>
+	<value value="30" name="PERF_TP_OUTPUT_PIXELS_BILINEAR"/>
+	<value value="31" name="PERF_TP_OUTPUT_PIXELS_MIP"/>
+	<value value="32" name="PERF_TP_OUTPUT_PIXELS_ANISO"/>
+	<value value="33" name="PERF_TP_OUTPUT_PIXELS_ZERO_LOD"/>
+	<value value="34" name="PERF_TP_FLAG_CACHE_REQUESTS"/>
+	<value value="35" name="PERF_TP_FLAG_CACHE_MISSES"/>
+	<value value="36" name="PERF_TP_L1_5_L2_REQUESTS"/>
+	<value value="37" name="PERF_TP_2D_OUTPUT_PIXELS"/>
+	<value value="38" name="PERF_TP_2D_OUTPUT_PIXELS_POINT"/>
+	<value value="39" name="PERF_TP_2D_OUTPUT_PIXELS_BILINEAR"/>
+	<value value="40" name="PERF_TP_2D_FILTER_WORKLOAD_16BIT"/>
+	<value value="41" name="PERF_TP_2D_FILTER_WORKLOAD_32BIT"/>
+</enum>
+
+<enum name="a5xx_sp_perfcounter_select">
+	<value value="0" name="PERF_SP_BUSY_CYCLES"/>
+	<value value="1" name="PERF_SP_ALU_WORKING_CYCLES"/>
+	<value value="2" name="PERF_SP_EFU_WORKING_CYCLES"/>
+	<value value="3" name="PERF_SP_STALL_CYCLES_VPC"/>
+	<value value="4" name="PERF_SP_STALL_CYCLES_TP"/>
+	<value value="5" name="PERF_SP_STALL_CYCLES_UCHE"/>
+	<value value="6" name="PERF_SP_STALL_CYCLES_RB"/>
+	<value value="7" name="PERF_SP_SCHEDULER_NON_WORKING"/>
+	<value value="8" name="PERF_SP_WAVE_CONTEXTS"/>
+	<value value="9" name="PERF_SP_WAVE_CONTEXT_CYCLES"/>
+	<value value="10" name="PERF_SP_FS_STAGE_WAVE_CYCLES"/>
+	<value value="11" name="PERF_SP_FS_STAGE_WAVE_SAMPLES"/>
+	<value value="12" name="PERF_SP_VS_STAGE_WAVE_CYCLES"/>
+	<value value="13" name="PERF_SP_VS_STAGE_WAVE_SAMPLES"/>
+	<value value="14" name="PERF_SP_FS_STAGE_DURATION_CYCLES"/>
+	<value value="15" name="PERF_SP_VS_STAGE_DURATION_CYCLES"/>
+	<value value="16" name="PERF_SP_WAVE_CTRL_CYCLES"/>
+	<value value="17" name="PERF_SP_WAVE_LOAD_CYCLES"/>
+	<value value="18" name="PERF_SP_WAVE_EMIT_CYCLES"/>
+	<value value="19" name="PERF_SP_WAVE_NOP_CYCLES"/>
+	<value value="20" name="PERF_SP_WAVE_WAIT_CYCLES"/>
+	<value value="21" name="PERF_SP_WAVE_FETCH_CYCLES"/>
+	<value value="22" name="PERF_SP_WAVE_IDLE_CYCLES"/>
+	<value value="23" name="PERF_SP_WAVE_END_CYCLES"/>
+	<value value="24" name="PERF_SP_WAVE_LONG_SYNC_CYCLES"/>
+	<value value="25" name="PERF_SP_WAVE_SHORT_SYNC_CYCLES"/>
+	<value value="26" name="PERF_SP_WAVE_JOIN_CYCLES"/>
+	<value value="27" name="PERF_SP_LM_LOAD_INSTRUCTIONS"/>
+	<value value="28" name="PERF_SP_LM_STORE_INSTRUCTIONS"/>
+	<value value="29" name="PERF_SP_LM_ATOMICS"/>
+	<value value="30" name="PERF_SP_GM_LOAD_INSTRUCTIONS"/>
+	<value value="31" name="PERF_SP_GM_STORE_INSTRUCTIONS"/>
+	<value value="32" name="PERF_SP_GM_ATOMICS"/>
+	<value value="33" name="PERF_SP_VS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="34" name="PERF_SP_VS_STAGE_CFLOW_INSTRUCTIONS"/>
+	<value value="35" name="PERF_SP_VS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="36" name="PERF_SP_VS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="37" name="PERF_SP_VS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="38" name="PERF_SP_FS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="39" name="PERF_SP_FS_STAGE_CFLOW_INSTRUCTIONS"/>
+	<value value="40" name="PERF_SP_FS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="41" name="PERF_SP_FS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="42" name="PERF_SP_FS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="43" name="PERF_SP_FS_STAGE_BARY_INSTRUCTIONS"/>
+	<value value="44" name="PERF_SP_VS_INSTRUCTIONS"/>
+	<value value="45" name="PERF_SP_FS_INSTRUCTIONS"/>
+	<value value="46" name="PERF_SP_ADDR_LOCK_COUNT"/>
+	<value value="47" name="PERF_SP_UCHE_READ_TRANS"/>
+	<value value="48" name="PERF_SP_UCHE_WRITE_TRANS"/>
+	<value value="49" name="PERF_SP_EXPORT_VPC_TRANS"/>
+	<value value="50" name="PERF_SP_EXPORT_RB_TRANS"/>
+	<value value="51" name="PERF_SP_PIXELS_KILLED"/>
+	<value value="52" name="PERF_SP_ICL1_REQUESTS"/>
+	<value value="53" name="PERF_SP_ICL1_MISSES"/>
+	<value value="54" name="PERF_SP_ICL0_REQUESTS"/>
+	<value value="55" name="PERF_SP_ICL0_MISSES"/>
+	<value value="56" name="PERF_SP_HS_INSTRUCTIONS"/>
+	<value value="57" name="PERF_SP_DS_INSTRUCTIONS"/>
+	<value value="58" name="PERF_SP_GS_INSTRUCTIONS"/>
+	<value value="59" name="PERF_SP_CS_INSTRUCTIONS"/>
+	<value value="60" name="PERF_SP_GPR_READ"/>
+	<value value="61" name="PERF_SP_GPR_WRITE"/>
+	<value value="62" name="PERF_SP_LM_CH0_REQUESTS"/>
+	<value value="63" name="PERF_SP_LM_CH1_REQUESTS"/>
+	<value value="64" name="PERF_SP_LM_BANK_CONFLICTS"/>
+</enum>
+
+<enum name="a5xx_rb_perfcounter_select">
+	<value value="0" name="PERF_RB_BUSY_CYCLES"/>
+	<value value="1" name="PERF_RB_STALL_CYCLES_CCU"/>
+	<value value="2" name="PERF_RB_STALL_CYCLES_HLSQ"/>
+	<value value="3" name="PERF_RB_STALL_CYCLES_FIFO0_FULL"/>
+	<value value="4" name="PERF_RB_STALL_CYCLES_FIFO1_FULL"/>
+	<value value="5" name="PERF_RB_STALL_CYCLES_FIFO2_FULL"/>
+	<value value="6" name="PERF_RB_STARVE_CYCLES_SP"/>
+	<value value="7" name="PERF_RB_STARVE_CYCLES_LRZ_TILE"/>
+	<value value="8" name="PERF_RB_STARVE_CYCLES_CCU"/>
+	<value value="9" name="PERF_RB_STARVE_CYCLES_Z_PLANE"/>
+	<value value="10" name="PERF_RB_STARVE_CYCLES_BARY_PLANE"/>
+	<value value="11" name="PERF_RB_Z_WORKLOAD"/>
+	<value value="12" name="PERF_RB_HLSQ_ACTIVE"/>
+	<value value="13" name="PERF_RB_Z_READ"/>
+	<value value="14" name="PERF_RB_Z_WRITE"/>
+	<value value="15" name="PERF_RB_C_READ"/>
+	<value value="16" name="PERF_RB_C_WRITE"/>
+	<value value="17" name="PERF_RB_TOTAL_PASS"/>
+	<value value="18" name="PERF_RB_Z_PASS"/>
+	<value value="19" name="PERF_RB_Z_FAIL"/>
+	<value value="20" name="PERF_RB_S_FAIL"/>
+	<value value="21" name="PERF_RB_BLENDED_FXP_COMPONENTS"/>
+	<value value="22" name="PERF_RB_BLENDED_FP16_COMPONENTS"/>
+	<value value="23" name="RB_RESERVED"/>
+	<value value="24" name="PERF_RB_2D_ALIVE_CYCLES"/>
+	<value value="25" name="PERF_RB_2D_STALL_CYCLES_A2D"/>
+	<value value="26" name="PERF_RB_2D_STARVE_CYCLES_SRC"/>
+	<value value="27" name="PERF_RB_2D_STARVE_CYCLES_SP"/>
+	<value value="28" name="PERF_RB_2D_STARVE_CYCLES_DST"/>
+	<value value="29" name="PERF_RB_2D_VALID_PIXELS"/>
+</enum>
+
+<enum name="a5xx_rb_samples_perfcounter_select">
+	<value value="0" name="TOTAL_SAMPLES"/>
+	<value value="1" name="ZPASS_SAMPLES"/>
+	<value value="2" name="ZFAIL_SAMPLES"/>
+	<value value="3" name="SFAIL_SAMPLES"/>
+</enum>
+
+<enum name="a5xx_vsc_perfcounter_select">
+	<value value="0" name="PERF_VSC_BUSY_CYCLES"/>
+	<value value="1" name="PERF_VSC_WORKING_CYCLES"/>
+	<value value="2" name="PERF_VSC_STALL_CYCLES_UCHE"/>
+	<value value="3" name="PERF_VSC_EOT_NUM"/>
+</enum>
+
+<enum name="a5xx_ccu_perfcounter_select">
+	<value value="0" name="PERF_CCU_BUSY_CYCLES"/>
+	<value value="1" name="PERF_CCU_STALL_CYCLES_RB_DEPTH_RETURN"/>
+	<value value="2" name="PERF_CCU_STALL_CYCLES_RB_COLOR_RETURN"/>
+	<value value="3" name="PERF_CCU_STARVE_CYCLES_FLAG_RETURN"/>
+	<value value="4" name="PERF_CCU_DEPTH_BLOCKS"/>
+	<value value="5" name="PERF_CCU_COLOR_BLOCKS"/>
+	<value value="6" name="PERF_CCU_DEPTH_BLOCK_HIT"/>
+	<value value="7" name="PERF_CCU_COLOR_BLOCK_HIT"/>
+	<value value="8" name="PERF_CCU_PARTIAL_BLOCK_READ"/>
+	<value value="9" name="PERF_CCU_GMEM_READ"/>
+	<value value="10" name="PERF_CCU_GMEM_WRITE"/>
+	<value value="11" name="PERF_CCU_DEPTH_READ_FLAG0_COUNT"/>
+	<value value="12" name="PERF_CCU_DEPTH_READ_FLAG1_COUNT"/>
+	<value value="13" name="PERF_CCU_DEPTH_READ_FLAG2_COUNT"/>
+	<value value="14" name="PERF_CCU_DEPTH_READ_FLAG3_COUNT"/>
+	<value value="15" name="PERF_CCU_DEPTH_READ_FLAG4_COUNT"/>
+	<value value="16" name="PERF_CCU_COLOR_READ_FLAG0_COUNT"/>
+	<value value="17" name="PERF_CCU_COLOR_READ_FLAG1_COUNT"/>
+	<value value="18" name="PERF_CCU_COLOR_READ_FLAG2_COUNT"/>
+	<value value="19" name="PERF_CCU_COLOR_READ_FLAG3_COUNT"/>
+	<value value="20" name="PERF_CCU_COLOR_READ_FLAG4_COUNT"/>
+	<value value="21" name="PERF_CCU_2D_BUSY_CYCLES"/>
+	<value value="22" name="PERF_CCU_2D_RD_REQ"/>
+	<value value="23" name="PERF_CCU_2D_WR_REQ"/>
+	<value value="24" name="PERF_CCU_2D_REORDER_STARVE_CYCLES"/>
+	<value value="25" name="PERF_CCU_2D_PIXELS"/>
+</enum>
+
+<enum name="a5xx_cmp_perfcounter_select">
+	<value value="0" name="PERF_CMPDECMP_STALL_CYCLES_VBIF"/>
+	<value value="1" name="PERF_CMPDECMP_VBIF_LATENCY_CYCLES"/>
+	<value value="2" name="PERF_CMPDECMP_VBIF_LATENCY_SAMPLES"/>
+	<value value="3" name="PERF_CMPDECMP_VBIF_READ_DATA_CCU"/>
+	<value value="4" name="PERF_CMPDECMP_VBIF_WRITE_DATA_CCU"/>
+	<value value="5" name="PERF_CMPDECMP_VBIF_READ_REQUEST"/>
+	<value value="6" name="PERF_CMPDECMP_VBIF_WRITE_REQUEST"/>
+	<value value="7" name="PERF_CMPDECMP_VBIF_READ_DATA"/>
+	<value value="8" name="PERF_CMPDECMP_VBIF_WRITE_DATA"/>
+	<value value="9" name="PERF_CMPDECMP_FLAG_FETCH_CYCLES"/>
+	<value value="10" name="PERF_CMPDECMP_FLAG_FETCH_SAMPLES"/>
+	<value value="11" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG1_COUNT"/>
+	<value value="12" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG2_COUNT"/>
+	<value value="13" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG3_COUNT"/>
+	<value value="14" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG4_COUNT"/>
+	<value value="15" name="PERF_CMPDECMP_COLOR_WRITE_FLAG1_COUNT"/>
+	<value value="16" name="PERF_CMPDECMP_COLOR_WRITE_FLAG2_COUNT"/>
+	<value value="17" name="PERF_CMPDECMP_COLOR_WRITE_FLAG3_COUNT"/>
+	<value value="18" name="PERF_CMPDECMP_COLOR_WRITE_FLAG4_COUNT"/>
+	<value value="19" name="PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_REQ"/>
+	<value value="20" name="PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_WR"/>
+	<value value="21" name="PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_RETURN"/>
+	<value value="22" name="PERF_CMPDECMP_2D_RD_DATA"/>
+	<value value="23" name="PERF_CMPDECMP_2D_WR_DATA"/>
+</enum>
+
+<enum name="a5xx_vbif_perfcounter_select">
+	<value value="0" name="AXI_READ_REQUESTS_ID_0"/>
+	<value value="1" name="AXI_READ_REQUESTS_ID_1"/>
+	<value value="2" name="AXI_READ_REQUESTS_ID_2"/>
+	<value value="3" name="AXI_READ_REQUESTS_ID_3"/>
+	<value value="4" name="AXI_READ_REQUESTS_ID_4"/>
+	<value value="5" name="AXI_READ_REQUESTS_ID_5"/>
+	<value value="6" name="AXI_READ_REQUESTS_ID_6"/>
+	<value value="7" name="AXI_READ_REQUESTS_ID_7"/>
+	<value value="8" name="AXI_READ_REQUESTS_ID_8"/>
+	<value value="9" name="AXI_READ_REQUESTS_ID_9"/>
+	<value value="10" name="AXI_READ_REQUESTS_ID_10"/>
+	<value value="11" name="AXI_READ_REQUESTS_ID_11"/>
+	<value value="12" name="AXI_READ_REQUESTS_ID_12"/>
+	<value value="13" name="AXI_READ_REQUESTS_ID_13"/>
+	<value value="14" name="AXI_READ_REQUESTS_ID_14"/>
+	<value value="15" name="AXI_READ_REQUESTS_ID_15"/>
+	<value value="16" name="AXI0_READ_REQUESTS_TOTAL"/>
+	<value value="17" name="AXI1_READ_REQUESTS_TOTAL"/>
+	<value value="18" name="AXI2_READ_REQUESTS_TOTAL"/>
+	<value value="19" name="AXI3_READ_REQUESTS_TOTAL"/>
+	<value value="20" name="AXI_READ_REQUESTS_TOTAL"/>
+	<value value="21" name="AXI_WRITE_REQUESTS_ID_0"/>
+	<value value="22" name="AXI_WRITE_REQUESTS_ID_1"/>
+	<value value="23" name="AXI_WRITE_REQUESTS_ID_2"/>
+	<value value="24" name="AXI_WRITE_REQUESTS_ID_3"/>
+	<value value="25" name="AXI_WRITE_REQUESTS_ID_4"/>
+	<value value="26" name="AXI_WRITE_REQUESTS_ID_5"/>
+	<value value="27" name="AXI_WRITE_REQUESTS_ID_6"/>
+	<value value="28" name="AXI_WRITE_REQUESTS_ID_7"/>
+	<value value="29" name="AXI_WRITE_REQUESTS_ID_8"/>
+	<value value="30" name="AXI_WRITE_REQUESTS_ID_9"/>
+	<value value="31" name="AXI_WRITE_REQUESTS_ID_10"/>
+	<value value="32" name="AXI_WRITE_REQUESTS_ID_11"/>
+	<value value="33" name="AXI_WRITE_REQUESTS_ID_12"/>
+	<value value="34" name="AXI_WRITE_REQUESTS_ID_13"/>
+	<value value="35" name="AXI_WRITE_REQUESTS_ID_14"/>
+	<value value="36" name="AXI_WRITE_REQUESTS_ID_15"/>
+	<value value="37" name="AXI0_WRITE_REQUESTS_TOTAL"/>
+	<value value="38" name="AXI1_WRITE_REQUESTS_TOTAL"/>
+	<value value="39" name="AXI2_WRITE_REQUESTS_TOTAL"/>
+	<value value="40" name="AXI3_WRITE_REQUESTS_TOTAL"/>
+	<value value="41" name="AXI_WRITE_REQUESTS_TOTAL"/>
+	<value value="42" name="AXI_TOTAL_REQUESTS"/>
+	<value value="43" name="AXI_READ_DATA_BEATS_ID_0"/>
+	<value value="44" name="AXI_READ_DATA_BEATS_ID_1"/>
+	<value value="45" name="AXI_READ_DATA_BEATS_ID_2"/>
+	<value value="46" name="AXI_READ_DATA_BEATS_ID_3"/>
+	<value value="47" name="AXI_READ_DATA_BEATS_ID_4"/>
+	<value value="48" name="AXI_READ_DATA_BEATS_ID_5"/>
+	<value value="49" name="AXI_READ_DATA_BEATS_ID_6"/>
+	<value value="50" name="AXI_READ_DATA_BEATS_ID_7"/>
+	<value value="51" name="AXI_READ_DATA_BEATS_ID_8"/>
+	<value value="52" name="AXI_READ_DATA_BEATS_ID_9"/>
+	<value value="53" name="AXI_READ_DATA_BEATS_ID_10"/>
+	<value value="54" name="AXI_READ_DATA_BEATS_ID_11"/>
+	<value value="55" name="AXI_READ_DATA_BEATS_ID_12"/>
+	<value value="56" name="AXI_READ_DATA_BEATS_ID_13"/>
+	<value value="57" name="AXI_READ_DATA_BEATS_ID_14"/>
+	<value value="58" name="AXI_READ_DATA_BEATS_ID_15"/>
+	<value value="59" name="AXI0_READ_DATA_BEATS_TOTAL"/>
+	<value value="60" name="AXI1_READ_DATA_BEATS_TOTAL"/>
+	<value value="61" name="AXI2_READ_DATA_BEATS_TOTAL"/>
+	<value value="62" name="AXI3_READ_DATA_BEATS_TOTAL"/>
+	<value value="63" name="AXI_READ_DATA_BEATS_TOTAL"/>
+	<value value="64" name="AXI_WRITE_DATA_BEATS_ID_0"/>
+	<value value="65" name="AXI_WRITE_DATA_BEATS_ID_1"/>
+	<value value="66" name="AXI_WRITE_DATA_BEATS_ID_2"/>
+	<value value="67" name="AXI_WRITE_DATA_BEATS_ID_3"/>
+	<value value="68" name="AXI_WRITE_DATA_BEATS_ID_4"/>
+	<value value="69" name="AXI_WRITE_DATA_BEATS_ID_5"/>
+	<value value="70" name="AXI_WRITE_DATA_BEATS_ID_6"/>
+	<value value="71" name="AXI_WRITE_DATA_BEATS_ID_7"/>
+	<value value="72" name="AXI_WRITE_DATA_BEATS_ID_8"/>
+	<value value="73" name="AXI_WRITE_DATA_BEATS_ID_9"/>
+	<value value="74" name="AXI_WRITE_DATA_BEATS_ID_10"/>
+	<value value="75" name="AXI_WRITE_DATA_BEATS_ID_11"/>
+	<value value="76" name="AXI_WRITE_DATA_BEATS_ID_12"/>
+	<value value="77" name="AXI_WRITE_DATA_BEATS_ID_13"/>
+	<value value="78" name="AXI_WRITE_DATA_BEATS_ID_14"/>
+	<value value="79" name="AXI_WRITE_DATA_BEATS_ID_15"/>
+	<value value="80" name="AXI0_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="81" name="AXI1_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="82" name="AXI2_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="83" name="AXI3_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="84" name="AXI_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="85" name="AXI_DATA_BEATS_TOTAL"/>
+</enum>
+
+<domain name="A5XX" width="32">
+	<bitset name="A5XX_INT0">
+		<bitfield name="RBBM_GPU_IDLE" pos="0" type="boolean"/>
+		<bitfield name="RBBM_AHB_ERROR" pos="1" type="boolean"/>
+		<bitfield name="RBBM_TRANSFER_TIMEOUT" pos="2" type="boolean"/>
+		<bitfield name="RBBM_ME_MS_TIMEOUT" pos="3" type="boolean"/>
+		<bitfield name="RBBM_PFP_MS_TIMEOUT" pos="4" type="boolean"/>
+		<bitfield name="RBBM_ETS_MS_TIMEOUT" pos="5" type="boolean"/>
+		<bitfield name="RBBM_ATB_ASYNC_OVERFLOW" pos="6" type="boolean"/>
+		<bitfield name="RBBM_GPC_ERROR" pos="7" type="boolean"/>
+		<bitfield name="CP_SW" pos="8" type="boolean"/>
+		<bitfield name="CP_HW_ERROR" pos="9" type="boolean"/>
+		<bitfield name="CP_CCU_FLUSH_DEPTH_TS" pos="10" type="boolean"/>
+		<bitfield name="CP_CCU_FLUSH_COLOR_TS" pos="11" type="boolean"/>
+		<bitfield name="CP_CCU_RESOLVE_TS" pos="12" type="boolean"/>
+		<bitfield name="CP_IB2" pos="13" type="boolean"/>
+		<bitfield name="CP_IB1" pos="14" type="boolean"/>
+		<bitfield name="CP_RB" pos="15" type="boolean"/>
+		<bitfield name="CP_UNUSED_1" pos="16" type="boolean"/>
+		<bitfield name="CP_RB_DONE_TS" pos="17" type="boolean"/>
+		<bitfield name="CP_WT_DONE_TS" pos="18" type="boolean"/>
+		<bitfield name="UNKNOWN_1" pos="19" type="boolean"/>
+		<bitfield name="CP_CACHE_FLUSH_TS" pos="20" type="boolean"/>
+		<bitfield name="UNUSED_2" pos="21" type="boolean"/>
+		<bitfield name="RBBM_ATB_BUS_OVERFLOW" pos="22" type="boolean"/>
+		<bitfield name="MISC_HANG_DETECT" pos="23" type="boolean"/>
+		<bitfield name="UCHE_OOB_ACCESS" pos="24" type="boolean"/>
+		<bitfield name="UCHE_TRAP_INTR" pos="25" type="boolean"/>
+		<bitfield name="DEBBUS_INTR_0" pos="26" type="boolean"/>
+		<bitfield name="DEBBUS_INTR_1" pos="27" type="boolean"/>
+		<bitfield name="GPMU_VOLTAGE_DROOP" pos="28" type="boolean"/>
+		<bitfield name="GPMU_FIRMWARE" pos="29" type="boolean"/>
+		<bitfield name="ISDB_CPU_IRQ" pos="30" type="boolean"/>
+		<bitfield name="ISDB_UNDER_DEBUG" pos="31" type="boolean"/>
+	</bitset>
+
+	<!-- CP Interrupt bits -->
+	<bitset name="A5XX_CP_INT">
+		<bitfield name="CP_OPCODE_ERROR" pos="0" type="boolean"/>
+		<bitfield name="CP_RESERVED_BIT_ERROR" pos="1" type="boolean"/>
+		<bitfield name="CP_HW_FAULT_ERROR" pos="2" type="boolean"/>
+		<bitfield name="CP_DMA_ERROR" pos="3" type="boolean"/>
+		<bitfield name="CP_REGISTER_PROTECTION_ERROR" pos="4" type="boolean"/>
+		<bitfield name="CP_AHB_ERROR" pos="5" type="boolean"/>
+	</bitset>
+
+	<!-- CP registers -->
+	<reg32 offset="0x0800" name="CP_RB_BASE"/>
+	<reg32 offset="0x0801" name="CP_RB_BASE_HI"/>
+	<reg32 offset="0x0802" name="CP_RB_CNTL"/>
+	<reg32 offset="0x0804" name="CP_RB_RPTR_ADDR"/>
+	<reg32 offset="0x0805" name="CP_RB_RPTR_ADDR_HI"/>
+	<reg32 offset="0x0806" name="CP_RB_RPTR"/>
+	<reg32 offset="0x0807" name="CP_RB_WPTR"/>
+	<reg32 offset="0x0808" name="CP_PFP_STAT_ADDR"/>
+	<reg32 offset="0x0809" name="CP_PFP_STAT_DATA"/>
+	<reg32 offset="0x080b" name="CP_DRAW_STATE_ADDR"/>
+	<reg32 offset="0x080c" name="CP_DRAW_STATE_DATA"/>
+	<reg32 offset="0x080d" name="CP_ME_NRT_ADDR_LO"/>
+	<reg32 offset="0x080e" name="CP_ME_NRT_ADDR_HI"/>
+	<reg32 offset="0x0810" name="CP_ME_NRT_DATA"/>
+	<reg32 offset="0x0817" name="CP_CRASH_SCRIPT_BASE_LO"/>
+	<reg32 offset="0x0818" name="CP_CRASH_SCRIPT_BASE_HI"/>
+	<reg32 offset="0x0819" name="CP_CRASH_DUMP_CNTL"/>
+	<reg32 offset="0x081a" name="CP_ME_STAT_ADDR"/>
+	<reg32 offset="0x081f" name="CP_ROQ_THRESHOLDS_1"/>
+	<reg32 offset="0x0820" name="CP_ROQ_THRESHOLDS_2"/>
+	<reg32 offset="0x0821" name="CP_ROQ_DBG_ADDR"/>
+	<reg32 offset="0x0822" name="CP_ROQ_DBG_DATA"/>
+	<reg32 offset="0x0823" name="CP_MEQ_DBG_ADDR"/>
+	<reg32 offset="0x0824" name="CP_MEQ_DBG_DATA"/>
+	<reg32 offset="0x0825" name="CP_MEQ_THRESHOLDS"/>
+	<reg32 offset="0x0826" name="CP_MERCIU_SIZE"/>
+	<reg32 offset="0x0827" name="CP_MERCIU_DBG_ADDR"/>
+	<reg32 offset="0x0828" name="CP_MERCIU_DBG_DATA_1"/>
+	<reg32 offset="0x0829" name="CP_MERCIU_DBG_DATA_2"/>
+	<reg32 offset="0x082a" name="CP_PFP_UCODE_DBG_ADDR"/>
+	<reg32 offset="0x082b" name="CP_PFP_UCODE_DBG_DATA"/>
+	<reg32 offset="0x082f" name="CP_ME_UCODE_DBG_ADDR"/>
+	<reg32 offset="0x0830" name="CP_ME_UCODE_DBG_DATA"/>
+	<reg32 offset="0x0831" name="CP_CNTL"/>
+	<reg32 offset="0x0832" name="CP_PFP_ME_CNTL"/>
+	<reg32 offset="0x0833" name="CP_CHICKEN_DBG"/>
+	<reg32 offset="0x0835" name="CP_PFP_INSTR_BASE_LO"/>
+	<reg32 offset="0x0836" name="CP_PFP_INSTR_BASE_HI"/>
+	<reg32 offset="0x0838" name="CP_ME_INSTR_BASE_LO"/>
+	<reg32 offset="0x0839" name="CP_ME_INSTR_BASE_HI"/>
+	<reg32 offset="0x083b" name="CP_CONTEXT_SWITCH_CNTL"/>
+	<reg32 offset="0x083c" name="CP_CONTEXT_SWITCH_RESTORE_ADDR_LO"/>
+	<reg32 offset="0x083d" name="CP_CONTEXT_SWITCH_RESTORE_ADDR_HI"/>
+	<reg32 offset="0x083e" name="CP_CONTEXT_SWITCH_SAVE_ADDR_LO"/>
+	<reg32 offset="0x083f" name="CP_CONTEXT_SWITCH_SAVE_ADDR_HI"/>
+	<reg32 offset="0x0840" name="CP_CONTEXT_SWITCH_SMMU_INFO_LO"/>
+	<reg32 offset="0x0841" name="CP_CONTEXT_SWITCH_SMMU_INFO_HI"/>
+	<reg32 offset="0x0860" name="CP_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0b14" name="CP_ME_STAT_DATA"/>
+	<reg32 offset="0x0b15" name="CP_WFI_PEND_CTR"/>
+	<reg32 offset="0x0b18" name="CP_INTERRUPT_STATUS"/>
+	<reg32 offset="0x0b1a" name="CP_HW_FAULT"/>
+	<reg32 offset="0x0b1c" name="CP_PROTECT_STATUS"/>
+	<reg32 offset="0x0b1f" name="CP_IB1_BASE"/>
+	<reg32 offset="0x0b20" name="CP_IB1_BASE_HI"/>
+	<reg32 offset="0x0b21" name="CP_IB1_BUFSZ"/>
+	<reg32 offset="0x0b22" name="CP_IB2_BASE"/>
+	<reg32 offset="0x0b23" name="CP_IB2_BASE_HI"/>
+	<reg32 offset="0x0b24" name="CP_IB2_BUFSZ"/>
+	<array offset="0x0b78" name="CP_SCRATCH" stride="1" length="8">
+		<reg32 offset="0x0" name="REG" type="uint"/>
+	</array>
+	<array offset="0x0880" name="CP_PROTECT" stride="1" length="32">
+		<reg32 offset="0x0" name="REG" type="adreno_cp_protect"/>
+	</array>
+	<reg32 offset="0x08a0" name="CP_PROTECT_CNTL"/>
+	<reg32 offset="0x0b1b" name="CP_AHB_FAULT"/>
+	<reg32 offset="0x0bb0" name="CP_PERFCTR_CP_SEL_0" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bb1" name="CP_PERFCTR_CP_SEL_1" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bb2" name="CP_PERFCTR_CP_SEL_2" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bb3" name="CP_PERFCTR_CP_SEL_3" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bb4" name="CP_PERFCTR_CP_SEL_4" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bb5" name="CP_PERFCTR_CP_SEL_5" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bb6" name="CP_PERFCTR_CP_SEL_6" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bb7" name="CP_PERFCTR_CP_SEL_7" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bc1" name="VSC_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0bba" name="CP_POWERCTR_CP_SEL_0"/>
+	<reg32 offset="0x0bbb" name="CP_POWERCTR_CP_SEL_1"/>
+	<reg32 offset="0x0bbc" name="CP_POWERCTR_CP_SEL_2"/>
+	<reg32 offset="0x0bbd" name="CP_POWERCTR_CP_SEL_3"/>
+
+	<!-- RBBM registers -->
+	<reg32 offset="0x0004" name="RBBM_CFG_DBGBUS_SEL_A"/>
+	<reg32 offset="0x0005" name="RBBM_CFG_DBGBUS_SEL_B"/>
+	<reg32 offset="0x0006" name="RBBM_CFG_DBGBUS_SEL_C"/>
+	<reg32 offset="0x0007" name="RBBM_CFG_DBGBUS_SEL_D"/>
+<!--
+#define A5XX_RBBM_CFG_DBGBUS_SEL_PING_INDEX_SHIFT    0x0
+#define A5XX_RBBM_CFG_DBGBUS_SEL_PING_BLK_SEL_SHIFT  0x8
+#define A5XX_RBBM_CFG_DBGBUS_SEL_PONG_INDEX_SHIFT    0x10
+#define A5XX_RBBM_CFG_DBGBUS_SEL_PONG_BLK_SEL_SHIFT  0x18
+ -->
+	<reg32 offset="0x0008" name="RBBM_CFG_DBGBUS_CNTLT"/>
+	<reg32 offset="0x0009" name="RBBM_CFG_DBGBUS_CNTLM"/>
+	<reg32 offset="0x0018" name="RBBM_CFG_DEBBUS_CTLTM_ENABLE_SHIFT"/>
+	<reg32 offset="0x000a" name="RBBM_CFG_DBGBUS_OPL"/>
+	<reg32 offset="0x000b" name="RBBM_CFG_DBGBUS_OPE"/>
+	<reg32 offset="0x000c" name="RBBM_CFG_DBGBUS_IVTL_0"/>
+	<reg32 offset="0x000d" name="RBBM_CFG_DBGBUS_IVTL_1"/>
+	<reg32 offset="0x000e" name="RBBM_CFG_DBGBUS_IVTL_2"/>
+	<reg32 offset="0x000f" name="RBBM_CFG_DBGBUS_IVTL_3"/>
+	<reg32 offset="0x0010" name="RBBM_CFG_DBGBUS_MASKL_0"/>
+	<reg32 offset="0x0011" name="RBBM_CFG_DBGBUS_MASKL_1"/>
+	<reg32 offset="0x0012" name="RBBM_CFG_DBGBUS_MASKL_2"/>
+	<reg32 offset="0x0013" name="RBBM_CFG_DBGBUS_MASKL_3"/>
+	<reg32 offset="0x0014" name="RBBM_CFG_DBGBUS_BYTEL_0"/>
+	<reg32 offset="0x0015" name="RBBM_CFG_DBGBUS_BYTEL_1"/>
+	<reg32 offset="0x0016" name="RBBM_CFG_DBGBUS_IVTE_0"/>
+	<reg32 offset="0x0017" name="RBBM_CFG_DBGBUS_IVTE_1"/>
+	<reg32 offset="0x0018" name="RBBM_CFG_DBGBUS_IVTE_2"/>
+	<reg32 offset="0x0019" name="RBBM_CFG_DBGBUS_IVTE_3"/>
+	<reg32 offset="0x001a" name="RBBM_CFG_DBGBUS_MASKE_0"/>
+	<reg32 offset="0x001b" name="RBBM_CFG_DBGBUS_MASKE_1"/>
+	<reg32 offset="0x001c" name="RBBM_CFG_DBGBUS_MASKE_2"/>
+	<reg32 offset="0x001d" name="RBBM_CFG_DBGBUS_MASKE_3"/>
+	<reg32 offset="0x001e" name="RBBM_CFG_DBGBUS_NIBBLEE"/>
+	<reg32 offset="0x001f" name="RBBM_CFG_DBGBUS_PTRC0"/>
+	<reg32 offset="0x0020" name="RBBM_CFG_DBGBUS_PTRC1"/>
+	<reg32 offset="0x0021" name="RBBM_CFG_DBGBUS_LOADREG"/>
+	<reg32 offset="0x0022" name="RBBM_CFG_DBGBUS_IDX"/>
+	<reg32 offset="0x0023" name="RBBM_CFG_DBGBUS_CLRC"/>
+	<reg32 offset="0x0024" name="RBBM_CFG_DBGBUS_LOADIVT"/>
+	<reg32 offset="0x002f" name="RBBM_INTERFACE_HANG_INT_CNTL"/>
+	<reg32 offset="0x0037" name="RBBM_INT_CLEAR_CMD"/>
+	<reg32 offset="0x0038" name="RBBM_INT_0_MASK">
+		<bitfield name="RBBM_GPU_IDLE" pos="0" type="boolean"/>
+		<bitfield name="RBBM_AHB_ERROR" pos="1" type="boolean"/>
+		<bitfield name="RBBM_TRANSFER_TIMEOUT" pos="2" type="boolean"/>
+		<bitfield name="RBBM_ME_MS_TIMEOUT" pos="3" type="boolean"/>
+		<bitfield name="RBBM_PFP_MS_TIMEOUT" pos="4" type="boolean"/>
+		<bitfield name="RBBM_ETS_MS_TIMEOUT" pos="5" type="boolean"/>
+		<bitfield name="RBBM_ATB_ASYNC_OVERFLOW" pos="6" type="boolean"/>
+		<bitfield name="RBBM_GPC_ERROR" pos="7" type="boolean"/>
+		<bitfield name="CP_SW" pos="8" type="boolean"/>
+		<bitfield name="CP_HW_ERROR" pos="9" type="boolean"/>
+		<bitfield name="CP_CCU_FLUSH_DEPTH_TS" pos="10" type="boolean"/>
+		<bitfield name="CP_CCU_FLUSH_COLOR_TS" pos="11" type="boolean"/>
+		<bitfield name="CP_CCU_RESOLVE_TS" pos="12" type="boolean"/>
+		<bitfield name="CP_IB2" pos="13" type="boolean"/>
+		<bitfield name="CP_IB1" pos="14" type="boolean"/>
+		<bitfield name="CP_RB" pos="15" type="boolean"/>
+		<bitfield name="CP_RB_DONE_TS" pos="17" type="boolean"/>
+		<bitfield name="CP_WT_DONE_TS" pos="18" type="boolean"/>
+		<bitfield name="CP_CACHE_FLUSH_TS" pos="20" type="boolean"/>
+		<bitfield name="RBBM_ATB_BUS_OVERFLOW" pos="22" type="boolean"/>
+		<bitfield name="MISC_HANG_DETECT" pos="23" type="boolean"/>
+		<bitfield name="UCHE_OOB_ACCESS" pos="24" type="boolean"/>
+		<bitfield name="UCHE_TRAP_INTR" pos="25" type="boolean"/>
+		<bitfield name="DEBBUS_INTR_0" pos="26" type="boolean"/>
+		<bitfield name="DEBBUS_INTR_1" pos="27" type="boolean"/>
+		<bitfield name="GPMU_VOLTAGE_DROOP" pos="28" type="boolean"/>
+		<bitfield name="GPMU_FIRMWARE" pos="29" type="boolean"/>
+		<bitfield name="ISDB_CPU_IRQ" pos="30" type="boolean"/>
+		<bitfield name="ISDB_UNDER_DEBUG" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x003f" name="RBBM_AHB_DBG_CNTL"/>
+	<reg32 offset="0x0041" name="RBBM_EXT_VBIF_DBG_CNTL"/>
+	<reg32 offset="0x0043" name="RBBM_SW_RESET_CMD"/>
+	<reg32 offset="0x0045" name="RBBM_BLOCK_SW_RESET_CMD"/>
+	<reg32 offset="0x0046" name="RBBM_BLOCK_SW_RESET_CMD2"/>
+	<reg32 offset="0x0048" name="RBBM_DBG_LO_HI_GPIO"/>
+	<reg32 offset="0x0049" name="RBBM_EXT_TRACE_BUS_CNTL"/>
+	<reg32 offset="0x004a" name="RBBM_CLOCK_CNTL_TP0"/>
+	<reg32 offset="0x004b" name="RBBM_CLOCK_CNTL_TP1"/>
+	<reg32 offset="0x004c" name="RBBM_CLOCK_CNTL_TP2"/>
+	<reg32 offset="0x004d" name="RBBM_CLOCK_CNTL_TP3"/>
+	<reg32 offset="0x004e" name="RBBM_CLOCK_CNTL2_TP0"/>
+	<reg32 offset="0x004f" name="RBBM_CLOCK_CNTL2_TP1"/>
+	<reg32 offset="0x0050" name="RBBM_CLOCK_CNTL2_TP2"/>
+	<reg32 offset="0x0051" name="RBBM_CLOCK_CNTL2_TP3"/>
+	<reg32 offset="0x0052" name="RBBM_CLOCK_CNTL3_TP0"/>
+	<reg32 offset="0x0053" name="RBBM_CLOCK_CNTL3_TP1"/>
+	<reg32 offset="0x0054" name="RBBM_CLOCK_CNTL3_TP2"/>
+	<reg32 offset="0x0055" name="RBBM_CLOCK_CNTL3_TP3"/>
+	<reg32 offset="0x0059" name="RBBM_READ_AHB_THROUGH_DBG"/>
+	<reg32 offset="0x005a" name="RBBM_CLOCK_CNTL_UCHE"/>
+	<reg32 offset="0x005b" name="RBBM_CLOCK_CNTL2_UCHE"/>
+	<reg32 offset="0x005c" name="RBBM_CLOCK_CNTL3_UCHE"/>
+	<reg32 offset="0x005d" name="RBBM_CLOCK_CNTL4_UCHE"/>
+	<reg32 offset="0x005e" name="RBBM_CLOCK_HYST_UCHE"/>
+	<reg32 offset="0x005f" name="RBBM_CLOCK_DELAY_UCHE"/>
+	<reg32 offset="0x0060" name="RBBM_CLOCK_MODE_GPC"/>
+	<reg32 offset="0x0061" name="RBBM_CLOCK_DELAY_GPC"/>
+	<reg32 offset="0x0062" name="RBBM_CLOCK_HYST_GPC"/>
+	<reg32 offset="0x0063" name="RBBM_CLOCK_CNTL_TSE_RAS_RBBM"/>
+	<reg32 offset="0x0064" name="RBBM_CLOCK_HYST_TSE_RAS_RBBM"/>
+	<reg32 offset="0x0065" name="RBBM_CLOCK_DELAY_TSE_RAS_RBBM"/>
+	<reg32 offset="0x0066" name="RBBM_CLOCK_DELAY_HLSQ"/>
+	<reg32 offset="0x0067" name="RBBM_CLOCK_CNTL"/>
+	<reg32 offset="0x0068" name="RBBM_CLOCK_CNTL_SP0"/>
+	<reg32 offset="0x0069" name="RBBM_CLOCK_CNTL_SP1"/>
+	<reg32 offset="0x006a" name="RBBM_CLOCK_CNTL_SP2"/>
+	<reg32 offset="0x006b" name="RBBM_CLOCK_CNTL_SP3"/>
+	<reg32 offset="0x006c" name="RBBM_CLOCK_CNTL2_SP0"/>
+	<reg32 offset="0x006d" name="RBBM_CLOCK_CNTL2_SP1"/>
+	<reg32 offset="0x006e" name="RBBM_CLOCK_CNTL2_SP2"/>
+	<reg32 offset="0x006f" name="RBBM_CLOCK_CNTL2_SP3"/>
+	<reg32 offset="0x0070" name="RBBM_CLOCK_HYST_SP0"/>
+	<reg32 offset="0x0071" name="RBBM_CLOCK_HYST_SP1"/>
+	<reg32 offset="0x0072" name="RBBM_CLOCK_HYST_SP2"/>
+	<reg32 offset="0x0073" name="RBBM_CLOCK_HYST_SP3"/>
+	<reg32 offset="0x0074" name="RBBM_CLOCK_DELAY_SP0"/>
+	<reg32 offset="0x0075" name="RBBM_CLOCK_DELAY_SP1"/>
+	<reg32 offset="0x0076" name="RBBM_CLOCK_DELAY_SP2"/>
+	<reg32 offset="0x0077" name="RBBM_CLOCK_DELAY_SP3"/>
+	<reg32 offset="0x0078" name="RBBM_CLOCK_CNTL_RB0"/>
+	<reg32 offset="0x0079" name="RBBM_CLOCK_CNTL_RB1"/>
+	<reg32 offset="0x007a" name="RBBM_CLOCK_CNTL_RB2"/>
+	<reg32 offset="0x007b" name="RBBM_CLOCK_CNTL_RB3"/>
+	<reg32 offset="0x007c" name="RBBM_CLOCK_CNTL2_RB0"/>
+	<reg32 offset="0x007d" name="RBBM_CLOCK_CNTL2_RB1"/>
+	<reg32 offset="0x007e" name="RBBM_CLOCK_CNTL2_RB2"/>
+	<reg32 offset="0x007f" name="RBBM_CLOCK_CNTL2_RB3"/>
+	<reg32 offset="0x0080" name="RBBM_CLOCK_HYST_RAC"/>
+	<reg32 offset="0x0081" name="RBBM_CLOCK_DELAY_RAC"/>
+	<reg32 offset="0x0082" name="RBBM_CLOCK_CNTL_CCU0"/>
+	<reg32 offset="0x0083" name="RBBM_CLOCK_CNTL_CCU1"/>
+	<reg32 offset="0x0084" name="RBBM_CLOCK_CNTL_CCU2"/>
+	<reg32 offset="0x0085" name="RBBM_CLOCK_CNTL_CCU3"/>
+	<reg32 offset="0x0086" name="RBBM_CLOCK_HYST_RB_CCU0"/>
+	<reg32 offset="0x0087" name="RBBM_CLOCK_HYST_RB_CCU1"/>
+	<reg32 offset="0x0088" name="RBBM_CLOCK_HYST_RB_CCU2"/>
+	<reg32 offset="0x0089" name="RBBM_CLOCK_HYST_RB_CCU3"/>
+	<reg32 offset="0x008a" name="RBBM_CLOCK_CNTL_RAC"/>
+	<reg32 offset="0x008b" name="RBBM_CLOCK_CNTL2_RAC"/>
+	<reg32 offset="0x008c" name="RBBM_CLOCK_DELAY_RB_CCU_L1_0"/>
+	<reg32 offset="0x008d" name="RBBM_CLOCK_DELAY_RB_CCU_L1_1"/>
+	<reg32 offset="0x008e" name="RBBM_CLOCK_DELAY_RB_CCU_L1_2"/>
+	<reg32 offset="0x008f" name="RBBM_CLOCK_DELAY_RB_CCU_L1_3"/>
+	<reg32 offset="0x0090" name="RBBM_CLOCK_HYST_VFD"/>
+	<reg32 offset="0x0091" name="RBBM_CLOCK_MODE_VFD"/>
+	<reg32 offset="0x0092" name="RBBM_CLOCK_DELAY_VFD"/>
+	<reg32 offset="0x0093" name="RBBM_AHB_CNTL0"/>
+	<reg32 offset="0x0094" name="RBBM_AHB_CNTL1"/>
+	<reg32 offset="0x0095" name="RBBM_AHB_CNTL2"/>
+	<reg32 offset="0x0096" name="RBBM_AHB_CMD"/>
+	<reg32 offset="0x009c" name="RBBM_INTERFACE_HANG_MASK_CNTL11"/>
+	<reg32 offset="0x009d" name="RBBM_INTERFACE_HANG_MASK_CNTL12"/>
+	<reg32 offset="0x009e" name="RBBM_INTERFACE_HANG_MASK_CNTL13"/>
+	<reg32 offset="0x009f" name="RBBM_INTERFACE_HANG_MASK_CNTL14"/>
+	<reg32 offset="0x00a0" name="RBBM_INTERFACE_HANG_MASK_CNTL15"/>
+	<reg32 offset="0x00a1" name="RBBM_INTERFACE_HANG_MASK_CNTL16"/>
+	<reg32 offset="0x00a2" name="RBBM_INTERFACE_HANG_MASK_CNTL17"/>
+	<reg32 offset="0x00a3" name="RBBM_INTERFACE_HANG_MASK_CNTL18"/>
+	<reg32 offset="0x00a4" name="RBBM_CLOCK_DELAY_TP0"/>
+	<reg32 offset="0x00a5" name="RBBM_CLOCK_DELAY_TP1"/>
+	<reg32 offset="0x00a6" name="RBBM_CLOCK_DELAY_TP2"/>
+	<reg32 offset="0x00a7" name="RBBM_CLOCK_DELAY_TP3"/>
+	<reg32 offset="0x00a8" name="RBBM_CLOCK_DELAY2_TP0"/>
+	<reg32 offset="0x00a9" name="RBBM_CLOCK_DELAY2_TP1"/>
+	<reg32 offset="0x00aa" name="RBBM_CLOCK_DELAY2_TP2"/>
+	<reg32 offset="0x00ab" name="RBBM_CLOCK_DELAY2_TP3"/>
+	<reg32 offset="0x00ac" name="RBBM_CLOCK_DELAY3_TP0"/>
+	<reg32 offset="0x00ad" name="RBBM_CLOCK_DELAY3_TP1"/>
+	<reg32 offset="0x00ae" name="RBBM_CLOCK_DELAY3_TP2"/>
+	<reg32 offset="0x00af" name="RBBM_CLOCK_DELAY3_TP3"/>
+	<reg32 offset="0x00b0" name="RBBM_CLOCK_HYST_TP0"/>
+	<reg32 offset="0x00b1" name="RBBM_CLOCK_HYST_TP1"/>
+	<reg32 offset="0x00b2" name="RBBM_CLOCK_HYST_TP2"/>
+	<reg32 offset="0x00b3" name="RBBM_CLOCK_HYST_TP3"/>
+	<reg32 offset="0x00b4" name="RBBM_CLOCK_HYST2_TP0"/>
+	<reg32 offset="0x00b5" name="RBBM_CLOCK_HYST2_TP1"/>
+	<reg32 offset="0x00b6" name="RBBM_CLOCK_HYST2_TP2"/>
+	<reg32 offset="0x00b7" name="RBBM_CLOCK_HYST2_TP3"/>
+	<reg32 offset="0x00b8" name="RBBM_CLOCK_HYST3_TP0"/>
+	<reg32 offset="0x00b9" name="RBBM_CLOCK_HYST3_TP1"/>
+	<reg32 offset="0x00ba" name="RBBM_CLOCK_HYST3_TP2"/>
+	<reg32 offset="0x00bb" name="RBBM_CLOCK_HYST3_TP3"/>
+	<reg32 offset="0x00c8" name="RBBM_CLOCK_CNTL_GPMU"/>
+	<reg32 offset="0x00c9" name="RBBM_CLOCK_DELAY_GPMU"/>
+	<reg32 offset="0x00ca" name="RBBM_CLOCK_HYST_GPMU"/>
+	<reg32 offset="0x03a0" name="RBBM_PERFCTR_CP_0_LO"/>
+	<reg32 offset="0x03a1" name="RBBM_PERFCTR_CP_0_HI"/>
+	<reg32 offset="0x03a2" name="RBBM_PERFCTR_CP_1_LO"/>
+	<reg32 offset="0x03a3" name="RBBM_PERFCTR_CP_1_HI"/>
+	<reg32 offset="0x03a4" name="RBBM_PERFCTR_CP_2_LO"/>
+	<reg32 offset="0x03a5" name="RBBM_PERFCTR_CP_2_HI"/>
+	<reg32 offset="0x03a6" name="RBBM_PERFCTR_CP_3_LO"/>
+	<reg32 offset="0x03a7" name="RBBM_PERFCTR_CP_3_HI"/>
+	<reg32 offset="0x03a8" name="RBBM_PERFCTR_CP_4_LO"/>
+	<reg32 offset="0x03a9" name="RBBM_PERFCTR_CP_4_HI"/>
+	<reg32 offset="0x03aa" name="RBBM_PERFCTR_CP_5_LO"/>
+	<reg32 offset="0x03ab" name="RBBM_PERFCTR_CP_5_HI"/>
+	<reg32 offset="0x03ac" name="RBBM_PERFCTR_CP_6_LO"/>
+	<reg32 offset="0x03ad" name="RBBM_PERFCTR_CP_6_HI"/>
+	<reg32 offset="0x03ae" name="RBBM_PERFCTR_CP_7_LO"/>
+	<reg32 offset="0x03af" name="RBBM_PERFCTR_CP_7_HI"/>
+	<reg32 offset="0x03b0" name="RBBM_PERFCTR_RBBM_0_LO"/>
+	<reg32 offset="0x03b1" name="RBBM_PERFCTR_RBBM_0_HI"/>
+	<reg32 offset="0x03b2" name="RBBM_PERFCTR_RBBM_1_LO"/>
+	<reg32 offset="0x03b3" name="RBBM_PERFCTR_RBBM_1_HI"/>
+	<reg32 offset="0x03b4" name="RBBM_PERFCTR_RBBM_2_LO"/>
+	<reg32 offset="0x03b5" name="RBBM_PERFCTR_RBBM_2_HI"/>
+	<reg32 offset="0x03b6" name="RBBM_PERFCTR_RBBM_3_LO"/>
+	<reg32 offset="0x03b7" name="RBBM_PERFCTR_RBBM_3_HI"/>
+	<reg32 offset="0x03b8" name="RBBM_PERFCTR_PC_0_LO"/>
+	<reg32 offset="0x03b9" name="RBBM_PERFCTR_PC_0_HI"/>
+	<reg32 offset="0x03ba" name="RBBM_PERFCTR_PC_1_LO"/>
+	<reg32 offset="0x03bb" name="RBBM_PERFCTR_PC_1_HI"/>
+	<reg32 offset="0x03bc" name="RBBM_PERFCTR_PC_2_LO"/>
+	<reg32 offset="0x03bd" name="RBBM_PERFCTR_PC_2_HI"/>
+	<reg32 offset="0x03be" name="RBBM_PERFCTR_PC_3_LO"/>
+	<reg32 offset="0x03bf" name="RBBM_PERFCTR_PC_3_HI"/>
+	<reg32 offset="0x03c0" name="RBBM_PERFCTR_PC_4_LO"/>
+	<reg32 offset="0x03c1" name="RBBM_PERFCTR_PC_4_HI"/>
+	<reg32 offset="0x03c2" name="RBBM_PERFCTR_PC_5_LO"/>
+	<reg32 offset="0x03c3" name="RBBM_PERFCTR_PC_5_HI"/>
+	<reg32 offset="0x03c4" name="RBBM_PERFCTR_PC_6_LO"/>
+	<reg32 offset="0x03c5" name="RBBM_PERFCTR_PC_6_HI"/>
+	<reg32 offset="0x03c6" name="RBBM_PERFCTR_PC_7_LO"/>
+	<reg32 offset="0x03c7" name="RBBM_PERFCTR_PC_7_HI"/>
+	<reg32 offset="0x03c8" name="RBBM_PERFCTR_VFD_0_LO"/>
+	<reg32 offset="0x03c9" name="RBBM_PERFCTR_VFD_0_HI"/>
+	<reg32 offset="0x03ca" name="RBBM_PERFCTR_VFD_1_LO"/>
+	<reg32 offset="0x03cb" name="RBBM_PERFCTR_VFD_1_HI"/>
+	<reg32 offset="0x03cc" name="RBBM_PERFCTR_VFD_2_LO"/>
+	<reg32 offset="0x03cd" name="RBBM_PERFCTR_VFD_2_HI"/>
+	<reg32 offset="0x03ce" name="RBBM_PERFCTR_VFD_3_LO"/>
+	<reg32 offset="0x03cf" name="RBBM_PERFCTR_VFD_3_HI"/>
+	<reg32 offset="0x03d0" name="RBBM_PERFCTR_VFD_4_LO"/>
+	<reg32 offset="0x03d1" name="RBBM_PERFCTR_VFD_4_HI"/>
+	<reg32 offset="0x03d2" name="RBBM_PERFCTR_VFD_5_LO"/>
+	<reg32 offset="0x03d3" name="RBBM_PERFCTR_VFD_5_HI"/>
+	<reg32 offset="0x03d4" name="RBBM_PERFCTR_VFD_6_LO"/>
+	<reg32 offset="0x03d5" name="RBBM_PERFCTR_VFD_6_HI"/>
+	<reg32 offset="0x03d6" name="RBBM_PERFCTR_VFD_7_LO"/>
+	<reg32 offset="0x03d7" name="RBBM_PERFCTR_VFD_7_HI"/>
+	<reg32 offset="0x03d8" name="RBBM_PERFCTR_HLSQ_0_LO"/>
+	<reg32 offset="0x03d9" name="RBBM_PERFCTR_HLSQ_0_HI"/>
+	<reg32 offset="0x03da" name="RBBM_PERFCTR_HLSQ_1_LO"/>
+	<reg32 offset="0x03db" name="RBBM_PERFCTR_HLSQ_1_HI"/>
+	<reg32 offset="0x03dc" name="RBBM_PERFCTR_HLSQ_2_LO"/>
+	<reg32 offset="0x03dd" name="RBBM_PERFCTR_HLSQ_2_HI"/>
+	<reg32 offset="0x03de" name="RBBM_PERFCTR_HLSQ_3_LO"/>
+	<reg32 offset="0x03df" name="RBBM_PERFCTR_HLSQ_3_HI"/>
+	<reg32 offset="0x03e0" name="RBBM_PERFCTR_HLSQ_4_LO"/>
+	<reg32 offset="0x03e1" name="RBBM_PERFCTR_HLSQ_4_HI"/>
+	<reg32 offset="0x03e2" name="RBBM_PERFCTR_HLSQ_5_LO"/>
+	<reg32 offset="0x03e3" name="RBBM_PERFCTR_HLSQ_5_HI"/>
+	<reg32 offset="0x03e4" name="RBBM_PERFCTR_HLSQ_6_LO"/>
+	<reg32 offset="0x03e5" name="RBBM_PERFCTR_HLSQ_6_HI"/>
+	<reg32 offset="0x03e6" name="RBBM_PERFCTR_HLSQ_7_LO"/>
+	<reg32 offset="0x03e7" name="RBBM_PERFCTR_HLSQ_7_HI"/>
+	<reg32 offset="0x03e8" name="RBBM_PERFCTR_VPC_0_LO"/>
+	<reg32 offset="0x03e9" name="RBBM_PERFCTR_VPC_0_HI"/>
+	<reg32 offset="0x03ea" name="RBBM_PERFCTR_VPC_1_LO"/>
+	<reg32 offset="0x03eb" name="RBBM_PERFCTR_VPC_1_HI"/>
+	<reg32 offset="0x03ec" name="RBBM_PERFCTR_VPC_2_LO"/>
+	<reg32 offset="0x03ed" name="RBBM_PERFCTR_VPC_2_HI"/>
+	<reg32 offset="0x03ee" name="RBBM_PERFCTR_VPC_3_LO"/>
+	<reg32 offset="0x03ef" name="RBBM_PERFCTR_VPC_3_HI"/>
+	<reg32 offset="0x03f0" name="RBBM_PERFCTR_CCU_0_LO"/>
+	<reg32 offset="0x03f1" name="RBBM_PERFCTR_CCU_0_HI"/>
+	<reg32 offset="0x03f2" name="RBBM_PERFCTR_CCU_1_LO"/>
+	<reg32 offset="0x03f3" name="RBBM_PERFCTR_CCU_1_HI"/>
+	<reg32 offset="0x03f4" name="RBBM_PERFCTR_CCU_2_LO"/>
+	<reg32 offset="0x03f5" name="RBBM_PERFCTR_CCU_2_HI"/>
+	<reg32 offset="0x03f6" name="RBBM_PERFCTR_CCU_3_LO"/>
+	<reg32 offset="0x03f7" name="RBBM_PERFCTR_CCU_3_HI"/>
+	<reg32 offset="0x03f8" name="RBBM_PERFCTR_TSE_0_LO"/>
+	<reg32 offset="0x03f9" name="RBBM_PERFCTR_TSE_0_HI"/>
+	<reg32 offset="0x03fa" name="RBBM_PERFCTR_TSE_1_LO"/>
+	<reg32 offset="0x03fb" name="RBBM_PERFCTR_TSE_1_HI"/>
+	<reg32 offset="0x03fc" name="RBBM_PERFCTR_TSE_2_LO"/>
+	<reg32 offset="0x03fd" name="RBBM_PERFCTR_TSE_2_HI"/>
+	<reg32 offset="0x03fe" name="RBBM_PERFCTR_TSE_3_LO"/>
+	<reg32 offset="0x03ff" name="RBBM_PERFCTR_TSE_3_HI"/>
+	<reg32 offset="0x0400" name="RBBM_PERFCTR_RAS_0_LO"/>
+	<reg32 offset="0x0401" name="RBBM_PERFCTR_RAS_0_HI"/>
+	<reg32 offset="0x0402" name="RBBM_PERFCTR_RAS_1_LO"/>
+	<reg32 offset="0x0403" name="RBBM_PERFCTR_RAS_1_HI"/>
+	<reg32 offset="0x0404" name="RBBM_PERFCTR_RAS_2_LO"/>
+	<reg32 offset="0x0405" name="RBBM_PERFCTR_RAS_2_HI"/>
+	<reg32 offset="0x0406" name="RBBM_PERFCTR_RAS_3_LO"/>
+	<reg32 offset="0x0407" name="RBBM_PERFCTR_RAS_3_HI"/>
+	<reg32 offset="0x0408" name="RBBM_PERFCTR_UCHE_0_LO"/>
+	<reg32 offset="0x0409" name="RBBM_PERFCTR_UCHE_0_HI"/>
+	<reg32 offset="0x040a" name="RBBM_PERFCTR_UCHE_1_LO"/>
+	<reg32 offset="0x040b" name="RBBM_PERFCTR_UCHE_1_HI"/>
+	<reg32 offset="0x040c" name="RBBM_PERFCTR_UCHE_2_LO"/>
+	<reg32 offset="0x040d" name="RBBM_PERFCTR_UCHE_2_HI"/>
+	<reg32 offset="0x040e" name="RBBM_PERFCTR_UCHE_3_LO"/>
+	<reg32 offset="0x040f" name="RBBM_PERFCTR_UCHE_3_HI"/>
+	<reg32 offset="0x0410" name="RBBM_PERFCTR_UCHE_4_LO"/>
+	<reg32 offset="0x0411" name="RBBM_PERFCTR_UCHE_4_HI"/>
+	<reg32 offset="0x0412" name="RBBM_PERFCTR_UCHE_5_LO"/>
+	<reg32 offset="0x0413" name="RBBM_PERFCTR_UCHE_5_HI"/>
+	<reg32 offset="0x0414" name="RBBM_PERFCTR_UCHE_6_LO"/>
+	<reg32 offset="0x0415" name="RBBM_PERFCTR_UCHE_6_HI"/>
+	<reg32 offset="0x0416" name="RBBM_PERFCTR_UCHE_7_LO"/>
+	<reg32 offset="0x0417" name="RBBM_PERFCTR_UCHE_7_HI"/>
+	<reg32 offset="0x0418" name="RBBM_PERFCTR_TP_0_LO"/>
+	<reg32 offset="0x0419" name="RBBM_PERFCTR_TP_0_HI"/>
+	<reg32 offset="0x041a" name="RBBM_PERFCTR_TP_1_LO"/>
+	<reg32 offset="0x041b" name="RBBM_PERFCTR_TP_1_HI"/>
+	<reg32 offset="0x041c" name="RBBM_PERFCTR_TP_2_LO"/>
+	<reg32 offset="0x041d" name="RBBM_PERFCTR_TP_2_HI"/>
+	<reg32 offset="0x041e" name="RBBM_PERFCTR_TP_3_LO"/>
+	<reg32 offset="0x041f" name="RBBM_PERFCTR_TP_3_HI"/>
+	<reg32 offset="0x0420" name="RBBM_PERFCTR_TP_4_LO"/>
+	<reg32 offset="0x0421" name="RBBM_PERFCTR_TP_4_HI"/>
+	<reg32 offset="0x0422" name="RBBM_PERFCTR_TP_5_LO"/>
+	<reg32 offset="0x0423" name="RBBM_PERFCTR_TP_5_HI"/>
+	<reg32 offset="0x0424" name="RBBM_PERFCTR_TP_6_LO"/>
+	<reg32 offset="0x0425" name="RBBM_PERFCTR_TP_6_HI"/>
+	<reg32 offset="0x0426" name="RBBM_PERFCTR_TP_7_LO"/>
+	<reg32 offset="0x0427" name="RBBM_PERFCTR_TP_7_HI"/>
+	<reg32 offset="0x0428" name="RBBM_PERFCTR_SP_0_LO"/>
+	<reg32 offset="0x0429" name="RBBM_PERFCTR_SP_0_HI"/>
+	<reg32 offset="0x042a" name="RBBM_PERFCTR_SP_1_LO"/>
+	<reg32 offset="0x042b" name="RBBM_PERFCTR_SP_1_HI"/>
+	<reg32 offset="0x042c" name="RBBM_PERFCTR_SP_2_LO"/>
+	<reg32 offset="0x042d" name="RBBM_PERFCTR_SP_2_HI"/>
+	<reg32 offset="0x042e" name="RBBM_PERFCTR_SP_3_LO"/>
+	<reg32 offset="0x042f" name="RBBM_PERFCTR_SP_3_HI"/>
+	<reg32 offset="0x0430" name="RBBM_PERFCTR_SP_4_LO"/>
+	<reg32 offset="0x0431" name="RBBM_PERFCTR_SP_4_HI"/>
+	<reg32 offset="0x0432" name="RBBM_PERFCTR_SP_5_LO"/>
+	<reg32 offset="0x0433" name="RBBM_PERFCTR_SP_5_HI"/>
+	<reg32 offset="0x0434" name="RBBM_PERFCTR_SP_6_LO"/>
+	<reg32 offset="0x0435" name="RBBM_PERFCTR_SP_6_HI"/>
+	<reg32 offset="0x0436" name="RBBM_PERFCTR_SP_7_LO"/>
+	<reg32 offset="0x0437" name="RBBM_PERFCTR_SP_7_HI"/>
+	<reg32 offset="0x0438" name="RBBM_PERFCTR_SP_8_LO"/>
+	<reg32 offset="0x0439" name="RBBM_PERFCTR_SP_8_HI"/>
+	<reg32 offset="0x043a" name="RBBM_PERFCTR_SP_9_LO"/>
+	<reg32 offset="0x043b" name="RBBM_PERFCTR_SP_9_HI"/>
+	<reg32 offset="0x043c" name="RBBM_PERFCTR_SP_10_LO"/>
+	<reg32 offset="0x043d" name="RBBM_PERFCTR_SP_10_HI"/>
+	<reg32 offset="0x043e" name="RBBM_PERFCTR_SP_11_LO"/>
+	<reg32 offset="0x043f" name="RBBM_PERFCTR_SP_11_HI"/>
+	<reg32 offset="0x0440" name="RBBM_PERFCTR_RB_0_LO"/>
+	<reg32 offset="0x0441" name="RBBM_PERFCTR_RB_0_HI"/>
+	<reg32 offset="0x0442" name="RBBM_PERFCTR_RB_1_LO"/>
+	<reg32 offset="0x0443" name="RBBM_PERFCTR_RB_1_HI"/>
+	<reg32 offset="0x0444" name="RBBM_PERFCTR_RB_2_LO"/>
+	<reg32 offset="0x0445" name="RBBM_PERFCTR_RB_2_HI"/>
+	<reg32 offset="0x0446" name="RBBM_PERFCTR_RB_3_LO"/>
+	<reg32 offset="0x0447" name="RBBM_PERFCTR_RB_3_HI"/>
+	<reg32 offset="0x0448" name="RBBM_PERFCTR_RB_4_LO"/>
+	<reg32 offset="0x0449" name="RBBM_PERFCTR_RB_4_HI"/>
+	<reg32 offset="0x044a" name="RBBM_PERFCTR_RB_5_LO"/>
+	<reg32 offset="0x044b" name="RBBM_PERFCTR_RB_5_HI"/>
+	<reg32 offset="0x044c" name="RBBM_PERFCTR_RB_6_LO"/>
+	<reg32 offset="0x044d" name="RBBM_PERFCTR_RB_6_HI"/>
+	<reg32 offset="0x044e" name="RBBM_PERFCTR_RB_7_LO"/>
+	<reg32 offset="0x044f" name="RBBM_PERFCTR_RB_7_HI"/>
+	<reg32 offset="0x0450" name="RBBM_PERFCTR_VSC_0_LO"/>
+	<reg32 offset="0x0451" name="RBBM_PERFCTR_VSC_0_HI"/>
+	<reg32 offset="0x0452" name="RBBM_PERFCTR_VSC_1_LO"/>
+	<reg32 offset="0x0453" name="RBBM_PERFCTR_VSC_1_HI"/>
+	<reg32 offset="0x0454" name="RBBM_PERFCTR_LRZ_0_LO"/>
+	<reg32 offset="0x0455" name="RBBM_PERFCTR_LRZ_0_HI"/>
+	<reg32 offset="0x0456" name="RBBM_PERFCTR_LRZ_1_LO"/>
+	<reg32 offset="0x0457" name="RBBM_PERFCTR_LRZ_1_HI"/>
+	<reg32 offset="0x0458" name="RBBM_PERFCTR_LRZ_2_LO"/>
+	<reg32 offset="0x0459" name="RBBM_PERFCTR_LRZ_2_HI"/>
+	<reg32 offset="0x045a" name="RBBM_PERFCTR_LRZ_3_LO"/>
+	<reg32 offset="0x045b" name="RBBM_PERFCTR_LRZ_3_HI"/>
+	<reg32 offset="0x045c" name="RBBM_PERFCTR_CMP_0_LO"/>
+	<reg32 offset="0x045d" name="RBBM_PERFCTR_CMP_0_HI"/>
+	<reg32 offset="0x045e" name="RBBM_PERFCTR_CMP_1_LO"/>
+	<reg32 offset="0x045f" name="RBBM_PERFCTR_CMP_1_HI"/>
+	<reg32 offset="0x0460" name="RBBM_PERFCTR_CMP_2_LO"/>
+	<reg32 offset="0x0461" name="RBBM_PERFCTR_CMP_2_HI"/>
+	<reg32 offset="0x0462" name="RBBM_PERFCTR_CMP_3_LO"/>
+	<reg32 offset="0x0463" name="RBBM_PERFCTR_CMP_3_HI"/>
+	<reg32 offset="0x046b" name="RBBM_PERFCTR_RBBM_SEL_0" type="a5xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x046c" name="RBBM_PERFCTR_RBBM_SEL_1" type="a5xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x046d" name="RBBM_PERFCTR_RBBM_SEL_2" type="a5xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x046e" name="RBBM_PERFCTR_RBBM_SEL_3" type="a5xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x04d2" name="RBBM_ALWAYSON_COUNTER_LO"/>
+	<reg32 offset="0x04d3" name="RBBM_ALWAYSON_COUNTER_HI"/>
+	<reg32 offset="0x04f5" name="RBBM_STATUS">
+		<bitfield high="31" low="31" name="GPU_BUSY_IGN_AHB" />
+		<bitfield high="30" low="30" name="GPU_BUSY_IGN_AHB_CP" />
+		<bitfield high="29" low="29" name="HLSQ_BUSY" />
+		<bitfield high="28" low="28" name="VSC_BUSY" />
+		<bitfield high="27" low="27" name="TPL1_BUSY" />
+		<bitfield high="26" low="26" name="SP_BUSY" />
+		<bitfield high="25" low="25" name="UCHE_BUSY" />
+		<bitfield high="24" low="24" name="VPC_BUSY" />
+		<bitfield high="23" low="23" name="VFDP_BUSY" />
+		<bitfield high="22" low="22" name="VFD_BUSY" />
+		<bitfield high="21" low="21" name="TESS_BUSY" />
+		<bitfield high="20" low="20" name="PC_VSD_BUSY" />
+		<bitfield high="19" low="19" name="PC_DCALL_BUSY" />
+		<bitfield high="18" low="18" name="GPMU_SLAVE_BUSY" />
+		<bitfield high="17" low="17" name="DCOM_BUSY" />
+		<bitfield high="16" low="16" name="COM_BUSY" />
+		<bitfield high="15" low="15" name="LRZ_BUZY" />
+		<bitfield high="14" low="14" name="A2D_DSP_BUSY" />
+		<bitfield high="13" low="13" name="CCUFCHE_BUSY" />
+		<bitfield high="12" low="12" name="RB_BUSY" />
+		<bitfield high="11" low="11" name="RAS_BUSY" />
+		<bitfield high="10" low="10" name="TSE_BUSY" />
+		<bitfield high="9" low="9" name="VBIF_BUSY" />
+		<bitfield high="8" low="8" name="GPU_BUSY_IGN_AHB_HYST" />
+		<bitfield high="7" low="7" name="CP_BUSY_IGN_HYST" />
+		<bitfield high="6" low="6" name="CP_BUSY" />
+		<bitfield high="5" low="5" name="GPMU_MASTER_BUSY" />
+		<bitfield high="4" low="4" name="CP_CRASH_BUSY" />
+		<bitfield high="3" low="3" name="CP_ETS_BUSY" />
+		<bitfield high="2" low="2" name="CP_PFP_BUSY" />
+		<bitfield high="1" low="1" name="CP_ME_BUSY" />
+		<bitfield high="0" low="0" name="HI_BUSY" />
+	</reg32>
+	<reg32 offset="0x0530" name="RBBM_STATUS3">
+		<bitfield pos="24" name="SMMU_STALLED_ON_FAULT" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x04e1" name="RBBM_INT_0_STATUS"/>
+	<reg32 offset="0x04f0" name="RBBM_AHB_ME_SPLIT_STATUS"/>
+	<reg32 offset="0x04f1" name="RBBM_AHB_PFP_SPLIT_STATUS"/>
+	<reg32 offset="0x04f3" name="RBBM_AHB_ETS_SPLIT_STATUS"/>
+	<reg32 offset="0x04f4" name="RBBM_AHB_ERROR_STATUS"/>
+	<reg32 offset="0x0464" name="RBBM_PERFCTR_CNTL"/>
+	<reg32 offset="0x0465" name="RBBM_PERFCTR_LOAD_CMD0"/>
+	<reg32 offset="0x0466" name="RBBM_PERFCTR_LOAD_CMD1"/>
+	<reg32 offset="0x0467" name="RBBM_PERFCTR_LOAD_CMD2"/>
+	<reg32 offset="0x0468" name="RBBM_PERFCTR_LOAD_CMD3"/>
+	<reg32 offset="0x0469" name="RBBM_PERFCTR_LOAD_VALUE_LO"/>
+	<reg32 offset="0x046a" name="RBBM_PERFCTR_LOAD_VALUE_HI"/>
+	<reg32 offset="0x046f" name="RBBM_PERFCTR_GPU_BUSY_MASKED"/>
+	<reg32 offset="0x04ed" name="RBBM_AHB_ERROR"/>
+	<reg32 offset="0x0504" name="RBBM_CFG_DBGBUS_EVENT_LOGIC"/>
+	<reg32 offset="0x0505" name="RBBM_CFG_DBGBUS_OVER"/>
+	<reg32 offset="0x0506" name="RBBM_CFG_DBGBUS_COUNT0"/>
+	<reg32 offset="0x0507" name="RBBM_CFG_DBGBUS_COUNT1"/>
+	<reg32 offset="0x0508" name="RBBM_CFG_DBGBUS_COUNT2"/>
+	<reg32 offset="0x0509" name="RBBM_CFG_DBGBUS_COUNT3"/>
+	<reg32 offset="0x050a" name="RBBM_CFG_DBGBUS_COUNT4"/>
+	<reg32 offset="0x050b" name="RBBM_CFG_DBGBUS_COUNT5"/>
+	<reg32 offset="0x050c" name="RBBM_CFG_DBGBUS_TRACE_ADDR"/>
+	<reg32 offset="0x050d" name="RBBM_CFG_DBGBUS_TRACE_BUF0"/>
+	<reg32 offset="0x050e" name="RBBM_CFG_DBGBUS_TRACE_BUF1"/>
+	<reg32 offset="0x050f" name="RBBM_CFG_DBGBUS_TRACE_BUF2"/>
+	<reg32 offset="0x0510" name="RBBM_CFG_DBGBUS_TRACE_BUF3"/>
+	<reg32 offset="0x0511" name="RBBM_CFG_DBGBUS_TRACE_BUF4"/>
+	<reg32 offset="0x0512" name="RBBM_CFG_DBGBUS_MISR0"/>
+	<reg32 offset="0x0513" name="RBBM_CFG_DBGBUS_MISR1"/>
+	<reg32 offset="0x0533" name="RBBM_ISDB_CNT"/>
+	<reg32 offset="0xf000" name="RBBM_SECVID_TRUST_CONFIG"/>
+	<reg32 offset="0xf400" name="RBBM_SECVID_TRUST_CNTL"/>
+	<reg32 offset="0xf800" name="RBBM_SECVID_TSB_TRUSTED_BASE_LO"/>
+	<reg32 offset="0xf801" name="RBBM_SECVID_TSB_TRUSTED_BASE_HI"/>
+	<reg32 offset="0xf802" name="RBBM_SECVID_TSB_TRUSTED_SIZE"/>
+	<reg32 offset="0xf803" name="RBBM_SECVID_TSB_CNTL"/>
+	<reg32 offset="0xf804" name="RBBM_SECVID_TSB_COMP_STATUS_LO"/>
+	<reg32 offset="0xf805" name="RBBM_SECVID_TSB_COMP_STATUS_HI"/>
+	<reg32 offset="0xf806" name="RBBM_SECVID_TSB_UCHE_STATUS_LO"/>
+	<reg32 offset="0xf807" name="RBBM_SECVID_TSB_UCHE_STATUS_HI"/>
+	<reg32 offset="0xf810" name="RBBM_SECVID_TSB_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+
+	<!-- VSC registers -->
+	<reg32 offset="0x0bc2" name="VSC_BIN_SIZE">
+		<bitfield name="WIDTH" low="0" high="7" shr="5" type="uint"/>
+		<bitfield name="HEIGHT" low="9" high="16" shr="5" type="uint"/>
+		<!-- b17 maybe BYPASS like RB_CNTL, but reg not written for bypass -->
+	</reg32>
+	<reg32 offset="0x0bc3" name="VSC_SIZE_ADDRESS_LO"/>
+	<reg32 offset="0x0bc4" name="VSC_SIZE_ADDRESS_HI"/>
+	<reg32 offset="0x0bc5" name="UNKNOWN_0BC5"/> <!-- always 00000000? -->
+	<reg32 offset="0x0bc6" name="UNKNOWN_0BC6"/> <!-- always 00000000? -->
+	<array offset="0x0bd0" name="VSC_PIPE_CONFIG" stride="1" length="16">
+		<reg32 offset="0x0" name="REG">
+			<doc>
+				Configures the mapping between VSC_PIPE buffer and
+				bin, X/Y specify the bin index in the horiz/vert
+				direction (0,0 is upper left, 0,1 is leftmost bin
+				on second row, and so on).  W/H specify the number
+				of bins assigned to this VSC_PIPE in the horiz/vert
+				dimension.
+			</doc>
+			<bitfield name="X" low="0" high="9" type="uint"/>
+			<bitfield name="Y" low="10" high="19" type="uint"/>
+			<bitfield name="W" low="20" high="23" type="uint"/>
+			<bitfield name="H" low="24" high="27" type="uint"/>
+		</reg32>
+	</array>
+	<array offset="0x0be0" name="VSC_PIPE_DATA_ADDRESS" stride="2" length="16">
+		<reg32 offset="0x0" name="LO"/>
+		<reg32 offset="0x1" name="HI"/>
+	</array>
+	<array offset="0x0c00" name="VSC_PIPE_DATA_LENGTH" stride="1" length="16">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<reg32 offset="0x0c60" name="VSC_PERFCTR_VSC_SEL_0" type="a5xx_vsc_perfcounter_select"/>
+	<reg32 offset="0x0c61" name="VSC_PERFCTR_VSC_SEL_1" type="a5xx_vsc_perfcounter_select"/>
+
+	<!-- used for some blits?? -->
+	<reg32 offset="0x0cdd" name="VSC_RESOLVE_CNTL" type="adreno_reg_xy"/>
+
+	<!-- GRAS registers -->
+	<reg32 offset="0x0c81" name="GRAS_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0c90" name="GRAS_PERFCTR_TSE_SEL_0" type="a5xx_tse_perfcounter_select"/>
+	<reg32 offset="0x0c91" name="GRAS_PERFCTR_TSE_SEL_1" type="a5xx_tse_perfcounter_select"/>
+	<reg32 offset="0x0c92" name="GRAS_PERFCTR_TSE_SEL_2" type="a5xx_tse_perfcounter_select"/>
+	<reg32 offset="0x0c93" name="GRAS_PERFCTR_TSE_SEL_3" type="a5xx_tse_perfcounter_select"/>
+	<reg32 offset="0x0c94" name="GRAS_PERFCTR_RAS_SEL_0" type="a5xx_ras_perfcounter_select"/>
+	<reg32 offset="0x0c95" name="GRAS_PERFCTR_RAS_SEL_1" type="a5xx_ras_perfcounter_select"/>
+	<reg32 offset="0x0c96" name="GRAS_PERFCTR_RAS_SEL_2" type="a5xx_ras_perfcounter_select"/>
+	<reg32 offset="0x0c97" name="GRAS_PERFCTR_RAS_SEL_3" type="a5xx_ras_perfcounter_select"/>
+	<reg32 offset="0x0c98" name="GRAS_PERFCTR_LRZ_SEL_0" type="a5xx_lrz_perfcounter_select"/>
+	<reg32 offset="0x0c99" name="GRAS_PERFCTR_LRZ_SEL_1" type="a5xx_lrz_perfcounter_select"/>
+	<reg32 offset="0x0c9a" name="GRAS_PERFCTR_LRZ_SEL_2" type="a5xx_lrz_perfcounter_select"/>
+	<reg32 offset="0x0c9b" name="GRAS_PERFCTR_LRZ_SEL_3" type="a5xx_lrz_perfcounter_select"/>
+
+	<reg32 offset="0x0cc4" name="RB_DBG_ECO_CNTL"/> <!-- always 00100000? -->
+	<reg32 offset="0x0cc5" name="RB_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0cc6" name="RB_MODE_CNTL"/> <!-- always 00000044? -->
+	<reg32 offset="0x0cc7" name="RB_CCU_CNTL"/> <!-- always b0056080 or 10000000? -->
+	<reg32 offset="0x0cd0" name="RB_PERFCTR_RB_SEL_0" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd1" name="RB_PERFCTR_RB_SEL_1" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd2" name="RB_PERFCTR_RB_SEL_2" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd3" name="RB_PERFCTR_RB_SEL_3" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd4" name="RB_PERFCTR_RB_SEL_4" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd5" name="RB_PERFCTR_RB_SEL_5" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd6" name="RB_PERFCTR_RB_SEL_6" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd7" name="RB_PERFCTR_RB_SEL_7" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd8" name="RB_PERFCTR_CCU_SEL_0" type="a5xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0cd9" name="RB_PERFCTR_CCU_SEL_1" type="a5xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0cda" name="RB_PERFCTR_CCU_SEL_2" type="a5xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0cdb" name="RB_PERFCTR_CCU_SEL_3" type="a5xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0ce0" name="RB_POWERCTR_RB_SEL_0"/>
+	<reg32 offset="0x0ce1" name="RB_POWERCTR_RB_SEL_1"/>
+	<reg32 offset="0x0ce2" name="RB_POWERCTR_RB_SEL_2"/>
+	<reg32 offset="0x0ce3" name="RB_POWERCTR_RB_SEL_3"/>
+	<reg32 offset="0x0ce4" name="RB_POWERCTR_CCU_SEL_0"/>
+	<reg32 offset="0x0ce5" name="RB_POWERCTR_CCU_SEL_1"/>
+	<reg32 offset="0x0cec" name="RB_PERFCTR_CMP_SEL_0" type="a5xx_cmp_perfcounter_select"/>
+	<reg32 offset="0x0ced" name="RB_PERFCTR_CMP_SEL_1" type="a5xx_cmp_perfcounter_select"/>
+	<reg32 offset="0x0cee" name="RB_PERFCTR_CMP_SEL_2" type="a5xx_cmp_perfcounter_select"/>
+	<reg32 offset="0x0cef" name="RB_PERFCTR_CMP_SEL_3" type="a5xx_cmp_perfcounter_select"/>
+
+	<reg32 offset="0x0d00" name="PC_DBG_ECO_CNTL">
+		<bitfield name="TWOPASSUSEWFI" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0d01" name="PC_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0d02" name="PC_MODE_CNTL"/> <!-- always 0000001f? -->
+	<reg32 offset="0x0d04" name="PC_INDEX_BUF_LO"/>
+	<reg32 offset="0x0d05" name="PC_INDEX_BUF_HI"/>
+	<reg32 offset="0x0d06" name="PC_START_INDEX"/>
+	<reg32 offset="0x0d07" name="PC_MAX_INDEX"/>
+	<reg32 offset="0x0d08" name="PC_TESSFACTOR_ADDR_LO"/>
+	<reg32 offset="0x0d09" name="PC_TESSFACTOR_ADDR_HI"/>
+	<reg32 offset="0x0d10" name="PC_PERFCTR_PC_SEL_0" type="a5xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d11" name="PC_PERFCTR_PC_SEL_1" type="a5xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d12" name="PC_PERFCTR_PC_SEL_2" type="a5xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d13" name="PC_PERFCTR_PC_SEL_3" type="a5xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d14" name="PC_PERFCTR_PC_SEL_4" type="a5xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d15" name="PC_PERFCTR_PC_SEL_5" type="a5xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d16" name="PC_PERFCTR_PC_SEL_6" type="a5xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d17" name="PC_PERFCTR_PC_SEL_7" type="a5xx_pc_perfcounter_select"/>
+
+	<reg32 offset="0x0e00" name="HLSQ_TIMEOUT_THRESHOLD_0"/>
+	<reg32 offset="0x0e01" name="HLSQ_TIMEOUT_THRESHOLD_1"/>
+	<reg32 offset="0x0e04" name="HLSQ_DBG_ECO_CNTL"/>
+	<reg32 offset="0x0e05" name="HLSQ_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0e06" name="HLSQ_MODE_CNTL"/> <!-- always 00000001? -->
+	<reg32 offset="0x0e10" name="HLSQ_PERFCTR_HLSQ_SEL_0" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e11" name="HLSQ_PERFCTR_HLSQ_SEL_1" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e12" name="HLSQ_PERFCTR_HLSQ_SEL_2" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e13" name="HLSQ_PERFCTR_HLSQ_SEL_3" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e14" name="HLSQ_PERFCTR_HLSQ_SEL_4" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e15" name="HLSQ_PERFCTR_HLSQ_SEL_5" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e16" name="HLSQ_PERFCTR_HLSQ_SEL_6" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e17" name="HLSQ_PERFCTR_HLSQ_SEL_7" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0f08" name="HLSQ_SPTP_RDSEL"/>
+	<reg32 offset="0xbc00" name="HLSQ_DBG_READ_SEL"/>
+	<reg32 offset="0xa000" name="HLSQ_DBG_AHB_READ_APERTURE"/>
+
+	<reg32 offset="0x0e41" name="VFD_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0e42" name="VFD_MODE_CNTL"/> <!-- always 00000000? -->
+	<reg32 offset="0x0e50" name="VFD_PERFCTR_VFD_SEL_0" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e51" name="VFD_PERFCTR_VFD_SEL_1" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e52" name="VFD_PERFCTR_VFD_SEL_2" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e53" name="VFD_PERFCTR_VFD_SEL_3" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e54" name="VFD_PERFCTR_VFD_SEL_4" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e55" name="VFD_PERFCTR_VFD_SEL_5" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e56" name="VFD_PERFCTR_VFD_SEL_6" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e57" name="VFD_PERFCTR_VFD_SEL_7" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e60" name="VPC_DBG_ECO_CNTL">
+		<bitfield name="ALLFLATOPTDIS" pos="10" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0e61" name="VPC_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0e62" name="VPC_MODE_CNTL">
+		<bitfield name="BINNING_PASS" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0e64" name="VPC_PERFCTR_VPC_SEL_0" type="a5xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e65" name="VPC_PERFCTR_VPC_SEL_1" type="a5xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e66" name="VPC_PERFCTR_VPC_SEL_2" type="a5xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e67" name="VPC_PERFCTR_VPC_SEL_3" type="a5xx_vpc_perfcounter_select"/>
+
+	<reg32 offset="0x0e80" name="UCHE_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0e81" name="UCHE_MODE_CNTL"/>
+	<reg32 offset="0x0e82" name="UCHE_SVM_CNTL"/>
+	<reg32 offset="0x0e87" name="UCHE_WRITE_THRU_BASE_LO"/>
+	<reg32 offset="0x0e88" name="UCHE_WRITE_THRU_BASE_HI"/>
+	<reg32 offset="0x0e89" name="UCHE_TRAP_BASE_LO"/>
+	<reg32 offset="0x0e8a" name="UCHE_TRAP_BASE_HI"/>
+	<reg32 offset="0x0e8b" name="UCHE_GMEM_RANGE_MIN_LO"/>
+	<reg32 offset="0x0e8c" name="UCHE_GMEM_RANGE_MIN_HI"/>
+	<reg32 offset="0x0e8d" name="UCHE_GMEM_RANGE_MAX_LO"/>
+	<reg32 offset="0x0e8e" name="UCHE_GMEM_RANGE_MAX_HI"/>
+	<reg32 offset="0x0e8f" name="UCHE_DBG_ECO_CNTL_2"/>
+	<reg32 offset="0x0e90" name="UCHE_DBG_ECO_CNTL"/>
+	<reg32 offset="0x0e91" name="UCHE_CACHE_INVALIDATE_MIN_LO"/>
+	<reg32 offset="0x0e92" name="UCHE_CACHE_INVALIDATE_MIN_HI"/>
+	<reg32 offset="0x0e93" name="UCHE_CACHE_INVALIDATE_MAX_LO"/>
+	<reg32 offset="0x0e94" name="UCHE_CACHE_INVALIDATE_MAX_HI"/>
+	<reg32 offset="0x0e95" name="UCHE_CACHE_INVALIDATE"/>
+	<reg32 offset="0x0e96" name="UCHE_CACHE_WAYS"/>
+	<reg32 offset="0x0ea0" name="UCHE_PERFCTR_UCHE_SEL_0" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea1" name="UCHE_PERFCTR_UCHE_SEL_1" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea2" name="UCHE_PERFCTR_UCHE_SEL_2" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea3" name="UCHE_PERFCTR_UCHE_SEL_3" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea4" name="UCHE_PERFCTR_UCHE_SEL_4" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea5" name="UCHE_PERFCTR_UCHE_SEL_5" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea6" name="UCHE_PERFCTR_UCHE_SEL_6" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea7" name="UCHE_PERFCTR_UCHE_SEL_7" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea8" name="UCHE_POWERCTR_UCHE_SEL_0"/>
+	<reg32 offset="0x0ea9" name="UCHE_POWERCTR_UCHE_SEL_1"/>
+	<reg32 offset="0x0eaa" name="UCHE_POWERCTR_UCHE_SEL_2"/>
+	<reg32 offset="0x0eab" name="UCHE_POWERCTR_UCHE_SEL_3"/>
+	<reg32 offset="0x0eb1" name="UCHE_TRAP_LOG_LO"/>
+	<reg32 offset="0x0eb2" name="UCHE_TRAP_LOG_HI"/>
+
+	<reg32 offset="0x0ec0" name="SP_DBG_ECO_CNTL"/>
+	<reg32 offset="0x0ec1" name="SP_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0ec2" name="SP_MODE_CNTL"/> <!-- always 0000001e? -->
+	<reg32 offset="0x0ed0" name="SP_PERFCTR_SP_SEL_0"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed1" name="SP_PERFCTR_SP_SEL_1"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed2" name="SP_PERFCTR_SP_SEL_2"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed3" name="SP_PERFCTR_SP_SEL_3"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed4" name="SP_PERFCTR_SP_SEL_4"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed5" name="SP_PERFCTR_SP_SEL_5"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed6" name="SP_PERFCTR_SP_SEL_6"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed7" name="SP_PERFCTR_SP_SEL_7"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed8" name="SP_PERFCTR_SP_SEL_8"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed9" name="SP_PERFCTR_SP_SEL_9"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0eda" name="SP_PERFCTR_SP_SEL_10" type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0edb" name="SP_PERFCTR_SP_SEL_11" type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0edc" name="SP_POWERCTR_SP_SEL_0"/>
+	<reg32 offset="0x0edd" name="SP_POWERCTR_SP_SEL_1"/>
+	<reg32 offset="0x0ede" name="SP_POWERCTR_SP_SEL_2"/>
+	<reg32 offset="0x0edf" name="SP_POWERCTR_SP_SEL_3"/>
+
+	<reg32 offset="0x0f01" name="TPL1_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0f02" name="TPL1_MODE_CNTL"/> <!-- always 00000544? -->
+	<reg32 offset="0x0f10" name="TPL1_PERFCTR_TP_SEL_0" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f11" name="TPL1_PERFCTR_TP_SEL_1" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f12" name="TPL1_PERFCTR_TP_SEL_2" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f13" name="TPL1_PERFCTR_TP_SEL_3" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f14" name="TPL1_PERFCTR_TP_SEL_4" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f15" name="TPL1_PERFCTR_TP_SEL_5" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f16" name="TPL1_PERFCTR_TP_SEL_6" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f17" name="TPL1_PERFCTR_TP_SEL_7" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f18" name="TPL1_POWERCTR_TP_SEL_0"/>
+	<reg32 offset="0x0f19" name="TPL1_POWERCTR_TP_SEL_1"/>
+	<reg32 offset="0x0f1a" name="TPL1_POWERCTR_TP_SEL_2"/>
+	<reg32 offset="0x0f1b" name="TPL1_POWERCTR_TP_SEL_3"/>
+
+	<reg32 offset="0x3000" name="VBIF_VERSION"/>
+	<reg32 offset="0x3001" name="VBIF_CLKON"/>
+<!--
+#define A5XX_VBIF_CLKON_FORCE_ON_TESTBUS_MASK   0x1
+#define A5XX_VBIF_CLKON_FORCE_ON_TESTBUS_SHIFT  0x1
+ -->
+	<reg32 offset="0x3028" name="VBIF_ABIT_SORT"/>
+	<reg32 offset="0x3029" name="VBIF_ABIT_SORT_CONF"/>
+	<reg32 offset="0x3049" name="VBIF_ROUND_ROBIN_QOS_ARB"/>
+	<reg32 offset="0x302a" name="VBIF_GATE_OFF_WRREQ_EN"/>
+	<reg32 offset="0x302c" name="VBIF_IN_RD_LIM_CONF0"/>
+	<reg32 offset="0x302d" name="VBIF_IN_RD_LIM_CONF1"/>
+	<reg32 offset="0x3080" name="VBIF_XIN_HALT_CTRL0"/>
+<!--
+#define A5XX_VBIF_XIN_HALT_CTRL0_MASK	   0xF
+#define A510_VBIF_XIN_HALT_CTRL0_MASK	   0x7
+ -->
+	<reg32 offset="0x3081" name="VBIF_XIN_HALT_CTRL1"/>
+	<reg32 offset="0x3084" name="VBIF_TEST_BUS_OUT_CTRL"/>
+<!--
+#define A5XX_VBIF_TEST_BUS_OUT_CTRL_EN_MASK    0x1
+#define A5XX_VBIF_TEST_BUS_OUT_CTRL_EN_SHIFT   0x0
+ -->
+	<reg32 offset="0x3085" name="VBIF_TEST_BUS1_CTRL0"/>
+	<reg32 offset="0x3086" name="VBIF_TEST_BUS1_CTRL1"/>
+<!--
+#define A5XX_VBIF_TEST_BUS1_CTRL1_DATA_SEL_MASK  0xF
+#define A5XX_VBIF_TEST_BUS1_CTRL1_DATA_SEL_SHIFT 0x0
+ -->
+	<reg32 offset="0x3087" name="VBIF_TEST_BUS2_CTRL0"/>
+	<reg32 offset="0x3088" name="VBIF_TEST_BUS2_CTRL1"/>
+<!--
+#define A5XX_VBIF_TEST_BUS2_CTRL1_DATA_SEL_MASK     0xF
+#define A5XX_VBIF_TEST_BUS2_CTRL1_DATA_SEL_SHIFT    0x0
+ -->
+	<reg32 offset="0x308c" name="VBIF_TEST_BUS_OUT"/>
+	<reg32 offset="0x30c0" name="VBIF_PERF_CNT_EN0"/>
+	<reg32 offset="0x30c1" name="VBIF_PERF_CNT_EN1"/>
+	<reg32 offset="0x30c2" name="VBIF_PERF_CNT_EN2"/>
+	<reg32 offset="0x30c3" name="VBIF_PERF_CNT_EN3"/>
+	<reg32 offset="0x30c8" name="VBIF_PERF_CNT_CLR0"/>
+	<reg32 offset="0x30c9" name="VBIF_PERF_CNT_CLR1"/>
+	<reg32 offset="0x30ca" name="VBIF_PERF_CNT_CLR2"/>
+	<reg32 offset="0x30cb" name="VBIF_PERF_CNT_CLR3"/>
+	<reg32 offset="0x30d0" name="VBIF_PERF_CNT_SEL0" type="a5xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d1" name="VBIF_PERF_CNT_SEL1" type="a5xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d2" name="VBIF_PERF_CNT_SEL2" type="a5xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d3" name="VBIF_PERF_CNT_SEL3" type="a5xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d8" name="VBIF_PERF_CNT_LOW0"/>
+	<reg32 offset="0x30d9" name="VBIF_PERF_CNT_LOW1"/>
+	<reg32 offset="0x30da" name="VBIF_PERF_CNT_LOW2"/>
+	<reg32 offset="0x30db" name="VBIF_PERF_CNT_LOW3"/>
+	<reg32 offset="0x30e0" name="VBIF_PERF_CNT_HIGH0"/>
+	<reg32 offset="0x30e1" name="VBIF_PERF_CNT_HIGH1"/>
+	<reg32 offset="0x30e2" name="VBIF_PERF_CNT_HIGH2"/>
+	<reg32 offset="0x30e3" name="VBIF_PERF_CNT_HIGH3"/>
+	<reg32 offset="0x3100" name="VBIF_PERF_PWR_CNT_EN0"/>
+	<reg32 offset="0x3101" name="VBIF_PERF_PWR_CNT_EN1"/>
+	<reg32 offset="0x3102" name="VBIF_PERF_PWR_CNT_EN2"/>
+	<reg32 offset="0x3110" name="VBIF_PERF_PWR_CNT_LOW0"/>
+	<reg32 offset="0x3111" name="VBIF_PERF_PWR_CNT_LOW1"/>
+	<reg32 offset="0x3112" name="VBIF_PERF_PWR_CNT_LOW2"/>
+	<reg32 offset="0x3118" name="VBIF_PERF_PWR_CNT_HIGH0"/>
+	<reg32 offset="0x3119" name="VBIF_PERF_PWR_CNT_HIGH1"/>
+	<reg32 offset="0x311a" name="VBIF_PERF_PWR_CNT_HIGH2"/>
+
+	<reg32 offset="0x8800" name="GPMU_INST_RAM_BASE"/>
+	<reg32 offset="0x9800" name="GPMU_DATA_RAM_BASE"/>
+
+<!--
+/* COUNTABLE FOR SP PERFCOUNTER */
+#define A5XX_SP_ALU_ACTIVE_CYCLES          0x1
+#define A5XX_SP0_ICL1_MISSES               0x35
+#define A5XX_SP_FS_CFLOW_INSTRUCTIONS      0x27
+
+/* COUNTABLE FOR TSE PERFCOUNTER */
+#define A5XX_TSE_INPUT_PRIM_NUM            0x6
+ -->
+	<reg32 offset="0xa840" name="SP_POWER_COUNTER_0_LO"/>
+	<reg32 offset="0xa841" name="SP_POWER_COUNTER_0_HI"/>
+	<reg32 offset="0xa842" name="SP_POWER_COUNTER_1_LO"/>
+	<reg32 offset="0xa843" name="SP_POWER_COUNTER_1_HI"/>
+	<reg32 offset="0xa844" name="SP_POWER_COUNTER_2_LO"/>
+	<reg32 offset="0xa845" name="SP_POWER_COUNTER_2_HI"/>
+	<reg32 offset="0xa846" name="SP_POWER_COUNTER_3_LO"/>
+	<reg32 offset="0xa847" name="SP_POWER_COUNTER_3_HI"/>
+	<reg32 offset="0xa848" name="TP_POWER_COUNTER_0_LO"/>
+	<reg32 offset="0xa849" name="TP_POWER_COUNTER_0_HI"/>
+	<reg32 offset="0xa84a" name="TP_POWER_COUNTER_1_LO"/>
+	<reg32 offset="0xa84b" name="TP_POWER_COUNTER_1_HI"/>
+	<reg32 offset="0xa84c" name="TP_POWER_COUNTER_2_LO"/>
+	<reg32 offset="0xa84d" name="TP_POWER_COUNTER_2_HI"/>
+	<reg32 offset="0xa84e" name="TP_POWER_COUNTER_3_LO"/>
+	<reg32 offset="0xa84f" name="TP_POWER_COUNTER_3_HI"/>
+	<reg32 offset="0xa850" name="RB_POWER_COUNTER_0_LO"/>
+	<reg32 offset="0xa851" name="RB_POWER_COUNTER_0_HI"/>
+	<reg32 offset="0xa852" name="RB_POWER_COUNTER_1_LO"/>
+	<reg32 offset="0xa853" name="RB_POWER_COUNTER_1_HI"/>
+	<reg32 offset="0xa854" name="RB_POWER_COUNTER_2_LO"/>
+	<reg32 offset="0xa855" name="RB_POWER_COUNTER_2_HI"/>
+	<reg32 offset="0xa856" name="RB_POWER_COUNTER_3_LO"/>
+	<reg32 offset="0xa857" name="RB_POWER_COUNTER_3_HI"/>
+	<reg32 offset="0xa858" name="CCU_POWER_COUNTER_0_LO"/>
+	<reg32 offset="0xa859" name="CCU_POWER_COUNTER_0_HI"/>
+	<reg32 offset="0xa85a" name="CCU_POWER_COUNTER_1_LO"/>
+	<reg32 offset="0xa85b" name="CCU_POWER_COUNTER_1_HI"/>
+	<reg32 offset="0xa85c" name="UCHE_POWER_COUNTER_0_LO"/>
+	<reg32 offset="0xa85d" name="UCHE_POWER_COUNTER_0_HI"/>
+	<reg32 offset="0xa85e" name="UCHE_POWER_COUNTER_1_LO"/>
+	<reg32 offset="0xa85f" name="UCHE_POWER_COUNTER_1_HI"/>
+	<reg32 offset="0xa860" name="UCHE_POWER_COUNTER_2_LO"/>
+	<reg32 offset="0xa861" name="UCHE_POWER_COUNTER_2_HI"/>
+	<reg32 offset="0xa862" name="UCHE_POWER_COUNTER_3_LO"/>
+	<reg32 offset="0xa863" name="UCHE_POWER_COUNTER_3_HI"/>
+	<reg32 offset="0xa864" name="CP_POWER_COUNTER_0_LO"/>
+	<reg32 offset="0xa865" name="CP_POWER_COUNTER_0_HI"/>
+	<reg32 offset="0xa866" name="CP_POWER_COUNTER_1_LO"/>
+	<reg32 offset="0xa867" name="CP_POWER_COUNTER_1_HI"/>
+	<reg32 offset="0xa868" name="CP_POWER_COUNTER_2_LO"/>
+	<reg32 offset="0xa869" name="CP_POWER_COUNTER_2_HI"/>
+	<reg32 offset="0xa86a" name="CP_POWER_COUNTER_3_LO"/>
+	<reg32 offset="0xa86b" name="CP_POWER_COUNTER_3_HI"/>
+	<reg32 offset="0xa86c" name="GPMU_POWER_COUNTER_0_LO"/>
+	<reg32 offset="0xa86d" name="GPMU_POWER_COUNTER_0_HI"/>
+	<reg32 offset="0xa86e" name="GPMU_POWER_COUNTER_1_LO"/>
+	<reg32 offset="0xa86f" name="GPMU_POWER_COUNTER_1_HI"/>
+	<reg32 offset="0xa870" name="GPMU_POWER_COUNTER_2_LO"/>
+	<reg32 offset="0xa871" name="GPMU_POWER_COUNTER_2_HI"/>
+	<reg32 offset="0xa872" name="GPMU_POWER_COUNTER_3_LO"/>
+	<reg32 offset="0xa873" name="GPMU_POWER_COUNTER_3_HI"/>
+	<reg32 offset="0xa874" name="GPMU_POWER_COUNTER_4_LO"/>
+	<reg32 offset="0xa875" name="GPMU_POWER_COUNTER_4_HI"/>
+	<reg32 offset="0xa876" name="GPMU_POWER_COUNTER_5_LO"/>
+	<reg32 offset="0xa877" name="GPMU_POWER_COUNTER_5_HI"/>
+	<reg32 offset="0xa878" name="GPMU_POWER_COUNTER_ENABLE"/>
+	<reg32 offset="0xa879" name="GPMU_ALWAYS_ON_COUNTER_LO"/>
+	<reg32 offset="0xa87a" name="GPMU_ALWAYS_ON_COUNTER_HI"/>
+	<reg32 offset="0xa87b" name="GPMU_ALWAYS_ON_COUNTER_RESET"/>
+	<reg32 offset="0xa87c" name="GPMU_POWER_COUNTER_SELECT_0"/>
+	<reg32 offset="0xa87d" name="GPMU_POWER_COUNTER_SELECT_1"/>
+
+	<reg32 offset="0xa880" name="GPMU_GPMU_SP_CLOCK_CONTROL"/>
+	<reg32 offset="0xa881" name="GPMU_SP_POWER_CNTL"/>
+	<reg32 offset="0xa886" name="GPMU_RBCCU_CLOCK_CNTL"/>
+	<reg32 offset="0xa887" name="GPMU_RBCCU_POWER_CNTL"/>
+	<reg32 offset="0xa88b" name="GPMU_SP_PWR_CLK_STATUS">
+		<bitfield name="PWR_ON" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa88d" name="GPMU_RBCCU_PWR_CLK_STATUS">
+		<bitfield name="PWR_ON" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa891" name="GPMU_PWR_COL_STAGGER_DELAY"/>
+	<reg32 offset="0xa892" name="GPMU_PWR_COL_INTER_FRAME_CTRL"/>
+	<reg32 offset="0xa893" name="GPMU_PWR_COL_INTER_FRAME_HYST"/>
+	<reg32 offset="0xa894" name="GPMU_PWR_COL_BINNING_CTRL"/>
+	<reg32 offset="0xa8a3" name="GPMU_CLOCK_THROTTLE_CTRL"/>
+	<reg32 offset="0xa8a8" name="GPMU_THROTTLE_UNMASK_FORCE_CTRL"/>
+	<reg32 offset="0xa8c1" name="GPMU_WFI_CONFIG"/>
+	<reg32 offset="0xa8d6" name="GPMU_RBBM_INTR_INFO"/>
+	<reg32 offset="0xa8d8" name="GPMU_CM3_SYSRESET"/>
+	<reg32 offset="0xa8e0" name="GPMU_GENERAL_0"/>
+	<reg32 offset="0xa8e1" name="GPMU_GENERAL_1"/>
+	<reg32 offset="0xac00" name="GPMU_TEMP_SENSOR_ID"/>
+	<reg32 offset="0xac01" name="GPMU_TEMP_SENSOR_CONFIG"/>
+	<reg32 offset="0xac02" name="GPMU_TEMP_VAL"/>
+	<reg32 offset="0xac03" name="GPMU_DELTA_TEMP_THRESHOLD"/>
+	<reg32 offset="0xac05" name="GPMU_TEMP_THRESHOLD_INTR_STATUS"/>
+	<reg32 offset="0xac06" name="GPMU_TEMP_THRESHOLD_INTR_EN_MASK"/>
+	<reg32 offset="0xac40" name="GPMU_LEAKAGE_TEMP_COEFF_0_1"/>
+	<reg32 offset="0xac41" name="GPMU_LEAKAGE_TEMP_COEFF_2_3"/>
+	<reg32 offset="0xac42" name="GPMU_LEAKAGE_VTG_COEFF_0_1"/>
+	<reg32 offset="0xac43" name="GPMU_LEAKAGE_VTG_COEFF_2_3"/>
+	<reg32 offset="0xac46" name="GPMU_BASE_LEAKAGE"/>
+	<reg32 offset="0xac60" name="GPMU_GPMU_VOLTAGE"/>
+	<reg32 offset="0xac61" name="GPMU_GPMU_VOLTAGE_INTR_STATUS"/>
+	<reg32 offset="0xac62" name="GPMU_GPMU_VOLTAGE_INTR_EN_MASK"/>
+	<reg32 offset="0xac80" name="GPMU_GPMU_PWR_THRESHOLD"/>
+	<reg32 offset="0xacc4" name="GPMU_GPMU_LLM_GLM_SLEEP_CTRL"/>
+	<reg32 offset="0xacc5" name="GPMU_GPMU_LLM_GLM_SLEEP_STATUS"/>
+	<reg32 offset="0xb80c" name="GDPM_CONFIG1"/>
+	<reg32 offset="0xb80d" name="GDPM_CONFIG2"/>
+	<reg32 offset="0xb80f" name="GDPM_INT_EN"/>
+	<reg32 offset="0xb811" name="GDPM_INT_MASK"/>
+	<reg32 offset="0xb9a0" name="GPMU_BEC_ENABLE"/>
+	<reg32 offset="0xc41a" name="GPU_CS_SENSOR_GENERAL_STATUS"/>
+	<reg32 offset="0xc41d" name="GPU_CS_AMP_CALIBRATION_STATUS1_0"/>
+	<reg32 offset="0xc41f" name="GPU_CS_AMP_CALIBRATION_STATUS1_2"/>
+	<reg32 offset="0xc421" name="GPU_CS_AMP_CALIBRATION_STATUS1_4"/>
+	<reg32 offset="0xc520" name="GPU_CS_ENABLE_REG"/>
+	<reg32 offset="0xc557" name="GPU_CS_AMP_CALIBRATION_CONTROL1"/>
+
+
+	<reg32 offset="0xe000" name="GRAS_CL_CNTL">
+		<bitfield name="ZERO_GB_SCALE_Z" pos="6" type="boolean"/>
+	</reg32>
+	<bitset name="a5xx_gras_xs_cl_cntl" inline="yes">
+		<bitfield name="CLIP_MASK" low="0" high="7"/>
+		<bitfield name="CULL_MASK" low="8" high="15"/>
+	</bitset>
+	<reg32 offset="0xe001" name="GRAS_VS_CL_CNTL" type="a5xx_gras_xs_cl_cntl"/>
+	<reg32 offset="0xe004" name="UNKNOWN_E004"/> <!-- always 00000000? -->
+	<reg32 offset="0xe005" name="GRAS_CNTL">
+		<!-- see also RB_RENDER_CONTROL0 -->
+		<bitfield name="IJ_PERSP_PIXEL" pos="0" type="boolean"/>
+		<bitfield name="IJ_PERSP_CENTROID" pos="1" type="boolean"/>
+		<bitfield name="IJ_PERSP_SAMPLE" pos="2" type="boolean"/>
+		<bitfield name="IJ_LINEAR_PIXEL" pos="3" type="boolean"/>
+		<bitfield name="IJ_LINEAR_CENTROID" pos="4" type="boolean"/>
+		<bitfield name="IJ_LINEAR_SAMPLE" pos="5" type="boolean"/>
+		<bitfield name="COORD_MASK" low="6" high="9" type="hex"/>
+	</reg32>
+	<reg32 offset="0xe006" name="GRAS_CL_GUARDBAND_CLIP_ADJ">
+		<bitfield name="HORZ" low="0" high="9" type="uint"/>
+		<bitfield name="VERT" low="10" high="19" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe010" name="GRAS_CL_VPORT_XOFFSET_0" type="float"/>
+	<reg32 offset="0xe011" name="GRAS_CL_VPORT_XSCALE_0" type="float"/>
+	<reg32 offset="0xe012" name="GRAS_CL_VPORT_YOFFSET_0" type="float"/>
+	<reg32 offset="0xe013" name="GRAS_CL_VPORT_YSCALE_0" type="float"/>
+	<reg32 offset="0xe014" name="GRAS_CL_VPORT_ZOFFSET_0" type="float"/>
+	<reg32 offset="0xe015" name="GRAS_CL_VPORT_ZSCALE_0" type="float"/>
+	<reg32 offset="0xe090" name="GRAS_SU_CNTL">
+		<bitfield name="CULL_FRONT" pos="0" type="boolean"/>
+		<bitfield name="CULL_BACK" pos="1" type="boolean"/>
+		<bitfield name="FRONT_CW" pos="2" type="boolean"/>
+		<bitfield name="LINEHALFWIDTH" low="3" high="10" radix="2" type="fixed"/>
+		<bitfield name="POLY_OFFSET" pos="11" type="boolean"/>
+		<bitfield name="LINE_MODE" pos="13" type="a5xx_line_mode"/>
+		<!-- probably LINEHALFWIDTH is the same as a4xx.. -->
+	</reg32>
+	<reg32 offset="0xe091" name="GRAS_SU_POINT_MINMAX">
+		<bitfield name="MIN" low="0" high="15" type="ufixed" radix="4"/>
+		<bitfield name="MAX" low="16" high="31" type="ufixed" radix="4"/>
+	</reg32>
+	<reg32 offset="0xe092" name="GRAS_SU_POINT_SIZE" type="fixed" radix="4"/>
+	<reg32 offset="0xe093" name="GRAS_SU_LAYERED"/>
+	<reg32 offset="0xe094" name="GRAS_SU_DEPTH_PLANE_CNTL">
+		<bitfield name="FRAG_WRITES_Z" pos="0" type="boolean"/>
+		<bitfield name="UNK1" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe095" name="GRAS_SU_POLY_OFFSET_SCALE" type="float"/>
+	<reg32 offset="0xe096" name="GRAS_SU_POLY_OFFSET_OFFSET" type="float"/>
+	<reg32 offset="0xe097" name="GRAS_SU_POLY_OFFSET_OFFSET_CLAMP" type="float"/>
+	<!-- duplicates RB_DEPTH_INFO0: -->
+	<reg32 offset="0xe098" name="GRAS_SU_DEPTH_BUFFER_INFO">
+		<bitfield name="DEPTH_FORMAT" low="0" high="2" type="a5xx_depth_format"/>
+	</reg32>
+	<reg32 offset="0xe099" name="GRAS_SU_CONSERVATIVE_RAS_CNTL"/> <!-- always 00000000? -->
+	<!--
+	guessing about window/screen/extent, I think they can in the end be
+	used interchangeably?
+	 -->
+	<reg32 offset="0xe0a0" name="GRAS_SC_CNTL">
+		<bitfield name="BINNING_PASS" pos="0" type="boolean"/>
+		<bitfield name="SAMPLES_PASSED" pos="15" type="boolean"/>
+	</reg32>
+	<!-- note, 0x4 for binning pass when frag writes z?? -->
+	<reg32 offset="0xe0a1" name="GRAS_SC_BIN_CNTL"/> <!-- always 00000000? -->
+	<reg32 offset="0xe0a2" name="GRAS_SC_RAS_MSAA_CNTL">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+	</reg32>
+	<reg32 offset="0xe0a3" name="GRAS_SC_DEST_MSAA_CNTL">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="MSAA_DISABLE" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe0a4" name="GRAS_SC_SCREEN_SCISSOR_CNTL"/> <!-- always 00000000? -->
+	<reg32 offset="0xe0aa" name="GRAS_SC_SCREEN_SCISSOR_TL_0" type="adreno_reg_xy"/>
+	<reg32 offset="0xe0ab" name="GRAS_SC_SCREEN_SCISSOR_BR_0" type="adreno_reg_xy"/>
+	<reg32 offset="0xe0ca" name="GRAS_SC_VIEWPORT_SCISSOR_TL_0" type="adreno_reg_xy"/>
+	<reg32 offset="0xe0cb" name="GRAS_SC_VIEWPORT_SCISSOR_BR_0" type="adreno_reg_xy"/>
+	<reg32 offset="0xe0ea" name="GRAS_SC_WINDOW_SCISSOR_TL" type="adreno_reg_xy"/>
+	<reg32 offset="0xe0eb" name="GRAS_SC_WINDOW_SCISSOR_BR" type="adreno_reg_xy"/>
+
+	<doc>
+		LRZ:  (Low Resolution Z ??)
+		----
+
+		I think it serves two functions, early discard of primitives in binning
+		pass without needing full resolution depth buffer, and also functions as
+		a depth-prepass, used during the GMEM draws to discard primitives that
+		would not be visible due to later draws.
+
+		The LRZ buffer always seems to be z16 format, regardless of actual
+		depth buffer format.
+
+		Note that LRZ write should be disabled when blend/stencil/etc is enabled,
+		since the occluded primitive can still contribute to final color value
+		of a fragment.
+
+		Only enabled for GL_LESS/GL_LEQUAL/GL_GREATER/GL_GEQUAL?
+	</doc>
+	<reg32 offset="0xe100" name="GRAS_LRZ_CNTL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<doc>LRZ write also disabled for blend/etc.</doc>
+		<bitfield name="LRZ_WRITE" pos="1" type="boolean"/>
+		<doc>update MAX instead of MIN value, ie. GL_GREATER/GL_GEQUAL</doc>
+		<bitfield name="GREATER" pos="2" type="boolean"/>
+		<!--
+		b3 set sometimes, when depth buffer isn't cleared.. maybe it
+		invalidates the LRZ buffer?  (Or just the covered positions?
+		 -->
+	</reg32>
+	<reg32 offset="0xe101" name="GRAS_LRZ_BUFFER_BASE_LO"/>
+	<reg32 offset="0xe102" name="GRAS_LRZ_BUFFER_BASE_HI"/>
+	<!--
+	lzr pitch is depth pitch (in pixels) / 8 (aligned to 32)..
+	 -->
+	<doc>
+		Pitch is depth width (in pixels) / 8 (aligned to 32).  Height
+		is also divided by 8 (ie. covers 8x8 pixels)
+	</doc>
+	<reg32 offset="0xe103" name="GRAS_LRZ_BUFFER_PITCH" shr="5" type="uint"/>
+	<reg32 offset="0xe104" name="GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_LO"/>
+	<reg32 offset="0xe105" name="GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_HI"/>
+
+	<reg32 offset="0xe140" name="RB_CNTL">
+		<bitfield name="WIDTH" low="0" high="7" shr="5" type="uint"/>
+		<bitfield name="HEIGHT" low="9" high="16" shr="5" type="uint"/>
+		<bitfield name="BYPASS" pos="17" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe141" name="RB_RENDER_CNTL">
+<!--
+bit 3 set for normal draws
+bit 7 for RECTLIST (clear) when z32s8 (used for clear of depth32?  not set
+	for z32 with no stencil, but maybe in that case separate z/s not used?
+	see mrt-fbo-* zs=2)
+ -->
+		<bitfield name="BINNING_PASS" pos="0" type="boolean"/>
+		<bitfield name="SAMPLES_PASSED" pos="6" type="boolean"/>
+		<bitfield name="DISABLE_COLOR_PIPE" pos="7" type="boolean"/>
+		<!-- why everything twice?? maybe read vs write? -->
+		<!-- UBWC flag buffer enabled for depth/stencil: -->
+		<bitfield name="FLAG_DEPTH" pos="14" type="boolean"/>
+		<bitfield name="FLAG_DEPTH2" pos="15" type="boolean"/>
+		<!-- bitmask of MRTs using UBWC flag buffer: -->
+		<bitfield name="FLAG_MRTS" low="16" high="23"/>
+		<bitfield name="FLAG_MRTS2" low="24" high="31"/>
+	</reg32>
+	<reg32 offset="0xe142" name="RB_RAS_MSAA_CNTL">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+	</reg32>
+	<reg32 offset="0xe143" name="RB_DEST_MSAA_CNTL">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="MSAA_DISABLE" pos="2" type="boolean"/>
+	</reg32>
+	<!--
+	note: maybe not actually called RB_RENDER_CONTROLn (since RB_RENDER_CNTL
+	name comes from kernel and is probably right)
+	 -->
+	<reg32 offset="0xe144" name="RB_RENDER_CONTROL0">
+		<!-- see also GRAS_CNTL -->
+		<bitfield name="IJ_PERSP_PIXEL" pos="0" type="boolean"/>
+		<bitfield name="IJ_PERSP_CENTROID" pos="1" type="boolean"/>
+		<bitfield name="IJ_PERSP_SAMPLE" pos="2" type="boolean"/>
+		<bitfield name="IJ_LINEAR_PIXEL" pos="3" type="boolean"/>
+		<bitfield name="IJ_LINEAR_CENTROID" pos="4" type="boolean"/>
+		<bitfield name="IJ_LINEAR_SAMPLE" pos="5" type="boolean"/>
+		<bitfield name="COORD_MASK" low="6" high="9" type="hex"/>
+	</reg32>
+	<reg32 offset="0xe145" name="RB_RENDER_CONTROL1">
+		<bitfield name="SAMPLEMASK" pos="0" type="boolean"/>
+		<bitfield name="FACENESS" pos="1" type="boolean"/>
+		<bitfield name="SAMPLEID" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe146" name="RB_FS_OUTPUT_CNTL">
+		<!-- bit0 set except for binning pass.. -->
+		<bitfield name="MRT" low="0" high="3" type="uint"/>
+		<bitfield name="FRAG_WRITES_Z" pos="5" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe147" name="RB_RENDER_COMPONENTS">
+		<bitfield name="RT0" low="0" high="3"/>
+		<bitfield name="RT1" low="4" high="7"/>
+		<bitfield name="RT2" low="8" high="11"/>
+		<bitfield name="RT3" low="12" high="15"/>
+		<bitfield name="RT4" low="16" high="19"/>
+		<bitfield name="RT5" low="20" high="23"/>
+		<bitfield name="RT6" low="24" high="27"/>
+		<bitfield name="RT7" low="28" high="31"/>
+	</reg32>
+	<array offset="0xe150" name="RB_MRT" stride="7" length="8">
+		<reg32 offset="0x0" name="CONTROL">
+			<bitfield name="BLEND" pos="0" type="boolean"/>
+			<bitfield name="BLEND2" pos="1" type="boolean"/>
+			<bitfield name="ROP_ENABLE" pos="2" type="boolean"/>
+			<bitfield name="ROP_CODE" low="3" high="6" type="a3xx_rop_code"/>
+			<bitfield name="COMPONENT_ENABLE" low="7" high="10" type="hex"/>
+		</reg32>
+		<reg32 offset="0x1" name="BLEND_CONTROL">
+			<bitfield name="RGB_SRC_FACTOR" low="0" high="4" type="adreno_rb_blend_factor"/>
+			<bitfield name="RGB_BLEND_OPCODE" low="5" high="7" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="RGB_DEST_FACTOR" low="8" high="12" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_SRC_FACTOR" low="16" high="20" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_BLEND_OPCODE" low="21" high="23" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="ALPHA_DEST_FACTOR" low="24" high="28" type="adreno_rb_blend_factor"/>
+		</reg32>
+		<reg32 offset="0x2" name="BUF_INFO">
+			<!--
+			not sure if there is a separate COLOR_SWAP field like on a3xx/a4xx,
+			or if it is inherent in the format.  Will have to play with bits
+			once we get things working and see what happens.  If it is a diff
+			field, it doesn't seem to have the same encoding as a3xx/a4xx.
+			 -->
+			<bitfield name="COLOR_FORMAT" low="0" high="7" type="a5xx_color_fmt"/>
+			<bitfield name="COLOR_TILE_MODE" low="8" high="9" type="a5xx_tile_mode"/>
+			<bitfield name="DITHER_MODE" low="11" high="12" type="adreno_rb_dither_mode"/>
+			<bitfield name="COLOR_SWAP" low="13" high="14" type="a3xx_color_swap"/>
+			<bitfield name="COLOR_SRGB" pos="15" type="boolean"/>
+		</reg32>
+		<!--
+		at least in gmem, things seem to be aligned to pitch of 64..
+		maybe an artifact of tiled format used in gmem?
+		 -->
+		<reg32 offset="0x3" name="PITCH" shr="6" type="uint"/>
+		<reg32 offset="0x4" name="ARRAY_PITCH" shr="6" type="uint"/>
+		<reg32 offset="0x5" name="BASE_LO"/>
+		<reg32 offset="0x6" name="BASE_HI"/>
+	</array>
+	<reg32 offset="0xe1a0" name="RB_BLEND_RED">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0xe1a1" name="RB_BLEND_RED_F32" type="float"/>
+	<reg32 offset="0xe1a2" name="RB_BLEND_GREEN">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0xe1a3" name="RB_BLEND_GREEN_F32" type="float"/>
+	<reg32 offset="0xe1a4" name="RB_BLEND_BLUE">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0xe1a5" name="RB_BLEND_BLUE_F32" type="float"/>
+	<reg32 offset="0xe1a6" name="RB_BLEND_ALPHA">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0xe1a7" name="RB_BLEND_ALPHA_F32" type="float"/>
+	<reg32 offset="0xe1a8" name="RB_ALPHA_CONTROL">
+		<bitfield name="ALPHA_REF" low="0" high="7" type="hex"/>
+		<bitfield name="ALPHA_TEST" pos="8" type="boolean"/>
+		<bitfield name="ALPHA_TEST_FUNC" low="9" high="11" type="adreno_compare_func"/>
+	</reg32>
+	<reg32 offset="0xe1a9" name="RB_BLEND_CNTL">
+		<!-- per-mrt enable bit -->
+		<bitfield name="ENABLE_BLEND" low="0" high="7"/>
+		<bitfield name="INDEPENDENT_BLEND" pos="8" type="boolean"/>
+		<bitfield name="ALPHA_TO_COVERAGE" pos="10" type="boolean"/>
+		<!-- a guess? -->
+		<bitfield name="SAMPLE_MASK" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="0xe1b0" name="RB_DEPTH_PLANE_CNTL">
+		<bitfield name="FRAG_WRITES_Z" pos="0" type="boolean"/>
+		<bitfield name="UNK1" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe1b1" name="RB_DEPTH_CNTL">
+		<bitfield name="Z_TEST_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="Z_WRITE_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="ZFUNC" low="2" high="4" type="adreno_compare_func"/>
+		<doc>Z_READ_ENABLE bit is set for zfunc other than GL_ALWAYS or GL_NEVER</doc>
+		<bitfield name="Z_READ_ENABLE" pos="6" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe1b2" name="RB_DEPTH_BUFFER_INFO">
+		<bitfield name="DEPTH_FORMAT" low="0" high="2" type="a5xx_depth_format"/>
+	</reg32>
+	<reg32 offset="0xe1b3" name="RB_DEPTH_BUFFER_BASE_LO"/>
+	<reg32 offset="0xe1b4" name="RB_DEPTH_BUFFER_BASE_HI"/>
+	<reg32 offset="0xe1b5" name="RB_DEPTH_BUFFER_PITCH" shr="6" type="uint">
+		<doc>stride of depth/stencil buffer</doc>
+	</reg32>
+	<reg32 offset="0xe1b6" name="RB_DEPTH_BUFFER_ARRAY_PITCH" shr="6" type="uint">
+		<doc>size of layer</doc>
+	</reg32>
+	<reg32 offset="0xe1c0" name="RB_STENCIL_CONTROL">
+		<bitfield name="STENCIL_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="STENCIL_ENABLE_BF" pos="1" type="boolean"/>
+		<!--
+			set for stencil operations that require read from stencil
+			buffer, but not for example for stencil clear (which does
+			not require read).. so guessing this is analogous to
+			READ_DEST_ENABLE for color buffer..
+		 -->
+		<bitfield name="STENCIL_READ" pos="2" type="boolean"/>
+		<bitfield name="FUNC" low="8" high="10" type="adreno_compare_func"/>
+		<bitfield name="FAIL" low="11" high="13" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS" low="14" high="16" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL" low="17" high="19" type="adreno_stencil_op"/>
+		<bitfield name="FUNC_BF" low="20" high="22" type="adreno_compare_func"/>
+		<bitfield name="FAIL_BF" low="23" high="25" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS_BF" low="26" high="28" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL_BF" low="29" high="31" type="adreno_stencil_op"/>
+	</reg32>
+	<reg32 offset="0xe1c1" name="RB_STENCIL_INFO">
+		<bitfield name="SEPARATE_STENCIL" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe1c2" name="RB_STENCIL_BASE_LO"/>
+	<reg32 offset="0xe1c3" name="RB_STENCIL_BASE_HI"/>
+	<reg32 offset="0xe1c4" name="RB_STENCIL_PITCH" shr="6" type="uint"/>
+	<reg32 offset="0xe1c5" name="RB_STENCIL_ARRAY_PITCH" shr="6" type="uint"/>
+	<reg32 offset="0xe1c6" name="RB_STENCILREFMASK" type="adreno_rb_stencilrefmask"/>
+	<reg32 offset="0xe1c7" name="RB_STENCILREFMASK_BF" type="adreno_rb_stencilrefmask"/>
+	<reg32 offset="0xe1d0" name="RB_WINDOW_OFFSET" type="adreno_reg_xy"/>
+	<reg32 offset="0xe1d1" name="RB_SAMPLE_COUNT_CONTROL">
+		<bitfield name="COPY" pos="1" type="boolean"/>
+	</reg32>
+
+	<doc>
+		Blits:
+		------
+
+		Blits are triggered by CP_EVENT_WRITE:BLIT, compared to previous
+		generations where they shared most of the gl pipeline and were
+		triggered by CP_DRAW_INDX*
+
+		For gmem->mem blob uses RB_BLIT_CNTL.BUF to specify src of
+		blit (ie MRTn, ZS, etc) and RB_BLIT_DST_LO/HI for destination
+		gpuaddr.  The gmem offset is taken from RB_MRT[n].BASE_LO/HI
+
+		For mem->gmem blob uses just MRT0 or ZS and RB_BLIT_DST_LO/HI
+		for the GMEM offset, and gpuaddr from RB_MRT[0].BASE_LO/HI
+		(I suppose this is just to avoid trashing RB_MRT[1..7]??)
+	</doc>
+	<reg32 offset="0xe210" name="RB_BLIT_CNTL">
+		<bitfield name="BUF" low="0" high="3" type="a5xx_blit_buf"/>
+	</reg32>
+	<reg32 offset="0xe211" name="RB_RESOLVE_CNTL_1" type="adreno_reg_xy"/>
+	<reg32 offset="0xe212" name="RB_RESOLVE_CNTL_2" type="adreno_reg_xy"/>
+	<reg32 offset="0xe213" name="RB_RESOLVE_CNTL_3">
+		<!-- if b0 set, output is in TILE5_3 format -->
+		<bitfield name="TILED" pos="0" type="boolean"/>
+	<!--
+		0xe213:
+		        0x0 mem->gmem
+		        0xf gmem->mem with flag buffer (color)
+		        0x4 gmem->mem without flag buffer (color)
+		        0x7 BYPASS mode flag buffer result (ie. on readpix)
+		            also for gmem->mem preserving tiling
+	-->
+	</reg32>
+	<reg32 offset="0xe214" name="RB_BLIT_DST_LO"/>
+	<reg32 offset="0xe215" name="RB_BLIT_DST_HI"/>
+	<reg32 offset="0xe216" name="RB_BLIT_DST_PITCH" shr="6" type="uint"/>
+	<!-- array-pitch is size of layer -->
+	<reg32 offset="0xe217" name="RB_BLIT_DST_ARRAY_PITCH" shr="6" type="uint"/>
+	<reg32 offset="0xe218" name="RB_CLEAR_COLOR_DW0"/>
+	<reg32 offset="0xe219" name="RB_CLEAR_COLOR_DW1"/>
+	<reg32 offset="0xe21a" name="RB_CLEAR_COLOR_DW2"/>
+	<reg32 offset="0xe21b" name="RB_CLEAR_COLOR_DW3"/>
+	<reg32 offset="0xe21c" name="RB_CLEAR_CNTL">
+		<bitfield name="FAST_CLEAR" pos="1" type="boolean"/>
+		<bitfield name="MSAA_RESOLVE" pos="2" type="boolean"/>
+		<doc>
+			For MASK, if RB_BLIT_CNTL.BUF=BLIT_ZS:
+				1 - depth
+				2 - stencil
+				3 - depth+stencil
+			if RB_BLIT_CNTL.BUF=BLIT_MRTn
+				then probably a component mask, I always see 0xf
+		</doc>
+		<bitfield name="MASK" low="4" high="7"/>
+	</reg32>
+
+	<doc>
+		Buffer Metadata (flag buffers):
+		-------------------------------
+
+		Blob seems to stick some metadata at the front of the buffer,
+		both z/s and MRT.  I think this is same as UBWC (bandwidth
+		compression) metadata that mdp 1.7 and later supports.  See
+		1d3fae5698ce5358caab87a15383b690941697e8 in downstream kernel.
+		UBWC seems to stand for "universal bandwidth compression".
+
+		Before glReadPixels() it does a pair of BYPASS blits (at least
+		if metadata is used) presumably to resolve metadata.
+
+		NOTES: see: getUBwcBlockSize(), getUBwcMetaBufferSize() at
+		https://android.googlesource.com/platform/hardware/qcom/display/+/android-6.0.1_r40/msm8994/libgralloc/alloc_controller.cpp
+		(note that bpp in bytes, not bits, so really cpp)
+
+		Example Layout 2d w/ mipmap levels:
+
+			100x2000, ifmt=GL_RG, fmt=GL_RG16F, type=GL_FLOAT, meta=64x512@0x8000 (7x500)
+				base=c072e000, offset=16384, size=1703936
+
+				color		flags
+			0	c073a000	c0732000	- level 0 flags is address
+			1	c0838000	c0834000	  programmed in texture state
+			2	c0879000	c0877000
+			3	c089a000	c0899000
+			4	c08ab000	c08aa000
+			5	c08b4000	c08b3000
+			6	c08b9000	c08b8000
+			7	c08bc000	c08bb000
+			8	c08be000	c08bd000
+			9	c08c0000	c08bf000
+			10	c08c2000	c08c1000
+
+		ARRAY_PITCH is the combined size of all the levels plus flags,
+		so 0xc08c3000 - 0xc0732000 = 0x00191000 (1642496); each level
+		takes up a minimum of 2 pages (since color and flags parts are
+		each page aligned.
+
+			{ TILE_MODE = TILE5_3 | SWIZ_X = A5XX_TEX_X | SWIZ_Y = A5XX_TEX_Y | SWIZ_Z = A5XX_TEX_ZERO | SWIZ_W = A5XX_TEX_ONE | MIPLVLS = 0 | FMT = TFMT5_16_16_FLOAT | SWAP = WZYX }
+			{ WIDTH = 100 | HEIGHT = 2000 }
+			{ FETCHSIZE = TFETCH5_4_BYTE | PITCH = 512 | TYPE = A5XX_TEX_2D }
+			{ ARRAY_PITCH = 1642496 | 0x18800000 }  - NOTE c2dc always has 0x18800000 but
+			{ BASE_LO = 0xc0732000 }                  this varies for blob gles driver..
+			{ BASE_HI = 0 | DEPTH = 1 }               not sure what it is
+
+
+	</doc>
+	<reg32 offset="0xe240" name="RB_DEPTH_FLAG_BUFFER_BASE_LO"/>
+	<reg32 offset="0xe241" name="RB_DEPTH_FLAG_BUFFER_BASE_HI"/>
+	<reg32 offset="0xe242" name="RB_DEPTH_FLAG_BUFFER_PITCH">
+	</reg32>
+	<array offset="0xe243" name="RB_MRT_FLAG_BUFFER" stride="4" length="8">
+		<reg32 offset="0" name="ADDR_LO"/>
+		<reg32 offset="1" name="ADDR_HI"/>
+		<reg32 offset="2" name="PITCH" shr="6" type="uint"/>
+		<!-- array-pitch is size of layer -->
+		<reg32 offset="3" name="ARRAY_PITCH" shr="6" type="uint"/>
+	</array>
+	<reg32 offset="0xe263" name="RB_BLIT_FLAG_DST_LO"/>
+	<reg32 offset="0xe264" name="RB_BLIT_FLAG_DST_HI"/>
+	<reg32 offset="0xe265" name="RB_BLIT_FLAG_DST_PITCH" shr="6" type="uint"/>
+	<!-- array-pitch is size of layer -->
+	<reg32 offset="0xe266" name="RB_BLIT_FLAG_DST_ARRAY_PITCH" shr="6" type="uint"/>
+
+	<reg32 offset="0xe267" name="RB_SAMPLE_COUNT_ADDR_LO"/>
+	<reg32 offset="0xe268" name="RB_SAMPLE_COUNT_ADDR_HI"/>
+
+	<reg32 offset="0xe280" name="VPC_CNTL_0">
+		<doc>
+			num of varyings plus four for gl_Position (plus one if gl_PointSize)
+			plus # of transform-feedback (streamout) varyings if using the
+			hw streamout (rather than stg instructions in shader)
+		</doc>
+		<bitfield name="STRIDE_IN_VPC" low="0" high="6" type="uint"/>
+		<bitfield name="VARYING" pos="11" type="boolean"/>
+	</reg32>
+	<array offset="0xe282" name="VPC_VARYING_INTERP" stride="1" length="8">
+		<reg32 offset="0x0" name="MODE"/>
+	</array>
+	<array offset="0xe28a" name="VPC_VARYING_PS_REPL" stride="1" length="8">
+		<reg32 offset="0x0" name="MODE"/>
+	</array>
+	<reg32 offset="0xe292" name="UNKNOWN_E292"/>
+	<reg32 offset="0xe293" name="UNKNOWN_E293"/>
+	<array offset="0xe294" name="VPC_VAR" stride="1" length="4">
+		<!-- one bit per varying component: -->
+		<reg32 offset="0" name="DISABLE"/>
+	</array>
+	<reg32 offset="0xe298" name="VPC_GS_SIV_CNTL"/>
+	<reg32 offset="0xe29a" name="VPC_CLIP_CNTL">
+		<bitfield name="CLIP_MASK" low="0" high="7" type="uint"/>
+		<!-- there can be up to 8 total clip/cull distance outputs,
+		     but apparenly VPC can only deal with vec4, so when there are
+		     more than 4 outputs a second location needs to be programmed
+		-->
+		<bitfield name="CLIP_DIST_03_LOC" low="8" high="15" type="uint"/>
+		<bitfield name="CLIP_DIST_47_LOC" low="16" high="23" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0xe29d" name="VPC_PACK">
+		<bitfield name="NUMNONPOSVAR" low="0" high="7" type="uint"/>
+		<!--
+		This seems to be the OUTLOC for the psize output.  It could possibly
+		be the max-OUTLOC position, but it is only set when VS writes psize
+		(and blob always puts psize at highest OUTLOC)
+		 -->
+		<bitfield name="PSIZELOC" low="8" high="15" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe2a0" name="VPC_FS_PRIMITIVEID_CNTL"/>
+
+	<doc>
+		Stream-Out:
+		-----------
+
+		VPC_SO[0..3] registers setup details about streamout buffers, and
+		number of components to write to each.
+
+		VPC_SO_PROG provides the mapping between output varyings and the SO
+		buffers.  It is written multiple times (via a CP_CONTEXT_REG_BUNCH
+		packet, not sure if that matters), each write can handle up to two
+		components of stream-out output.  Order matches up to OUTLOC,
+		including padding.  So, if outputting first 3 varyings:
+
+			SP_VS_OUT[0].REG: { A_REGID = r0.w | A_COMPMASK = 0xf | B_REGID = r0.x | B_COMPMASK = 0x7 }
+			SP_VS_OUT[0x1].REG: { A_REGID = r1.w | A_COMPMASK = 0x3 | B_REGID = r2.y | B_COMPMASK = 0xf }
+			SP_VS_VPC_DST[0].REG: { OUTLOC0 = 0 | OUTLOC1 = 4 | OUTLOC2 = 8 | OUTLOC3 = 12 }
+
+		Then:
+
+			VPC_SO_PROG: { A_BUF = 0 | A_OFF = 0 | A_EN | A_BUF = 0 | B_OFF = 4 | B_EN }
+			VPC_SO_PROG: { A_BUF = 0 | A_OFF = 8 | A_EN | A_BUF = 0 | B_OFF = 12 | B_EN }
+			VPC_SO_PROG: { A_BUF = 2 | A_OFF = 0 | A_EN | A_BUF = 2 | B_OFF = 4 | B_EN }
+			VPC_SO_PROG: { A_BUF = 2 | A_OFF = 8 | A_EN | A_BUF = 0 | B_OFF = 0 }
+			VPC_SO_PROG: { A_BUF = 1 | A_OFF = 0 | A_EN | A_BUF = 1 | B_OFF = 4 | B_EN }
+
+		Note that varying order is OUTLOC0, OUTLOC2, OUTLOC1, and note
+		the padding between OUTLOC1 and OUTLOC2.
+
+		The BUF bitfield indicates which of the four streamout buffers
+		to write into at the specified offset.
+
+		The VPC_SO[n].FLUSH_BASE_LO/HI is used for hw to write back next
+		offset which gets loaded back into VPC_SO[n].BUFFER_OFFSET via a
+		CP_MEM_TO_REG.  Probably can be ignored until we have GS/etc, at
+		which point we can't calculate the offset on the CPU.
+	</doc>
+	<reg32 offset="0xe2a1" name="VPC_SO_BUF_CNTL">
+		<bitfield name="BUF0" pos="0" type="boolean"/>
+		<bitfield name="BUF1" pos="3" type="boolean"/>
+		<bitfield name="BUF2" pos="6" type="boolean"/>
+		<bitfield name="BUF3" pos="9" type="boolean"/>
+		<bitfield name="ENABLE" pos="15" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe2a2" name="VPC_SO_OVERRIDE">
+		<bitfield name="SO_DISABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe2a3" name="VPC_SO_CNTL">
+		<!-- always 0x10000 when SO enabled.. -->
+		<bitfield name="ENABLE" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe2a4" name="VPC_SO_PROG">
+		<bitfield name="A_BUF" low="0" high="1" type="uint"/>
+		<bitfield name="A_OFF" low="2" high="10" shr="2" type="uint"/>
+		<bitfield name="A_EN" pos="11" type="boolean"/>
+		<bitfield name="B_BUF" low="12" high="13" type="uint"/>
+		<bitfield name="B_OFF" low="14" high="22" shr="2" type="uint"/>
+		<bitfield name="B_EN" pos="23" type="boolean"/>
+	</reg32>
+	<array offset="0xe2a7" name="VPC_SO" stride="7" length="4">
+		<reg32 offset="0" name="BUFFER_BASE_LO"/>
+		<reg32 offset="1" name="BUFFER_BASE_HI"/>
+		<reg32 offset="2" name="BUFFER_SIZE"/>
+		<reg32 offset="3" name="NCOMP"/>  <!-- component count -->
+		<reg32 offset="4" name="BUFFER_OFFSET"/>
+		<reg32 offset="5" name="FLUSH_BASE_LO"/>
+		<reg32 offset="6" name="FLUSH_BASE_HI"/>
+	</array>
+
+	<reg32 offset="0xe384" name="PC_PRIMITIVE_CNTL">
+		<!-- # of varyings plus four for gl_Position (plus one if gl_PointSize) -->
+		<bitfield name="STRIDE_IN_VPC" low="0" high="6" type="uint"/>
+		<bitfield name="PRIMITIVE_RESTART" pos="8" type="boolean"/>
+		<bitfield name="COUNT_PRIMITIVES" pos="9" type="boolean"/><!-- enabled when gl_PrimitiveIDIn is used -->
+		<bitfield name="PROVOKING_VTX_LAST" pos="10" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe385" name="PC_PRIM_VTX_CNTL">
+		<bitfield name="PSIZE" pos="11" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe388" name="PC_RASTER_CNTL">
+		<bitfield name="POLYMODE_FRONT_PTYPE" low="0" high="2" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="POLYMODE_BACK_PTYPE" low="3" high="5" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="POLYMODE_ENABLE" pos="6" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe389" name="PC_CLIP_CNTL">
+		<bitfield name="CLIP_MASK" low="0" high="7"/>
+	</reg32>
+	<reg32 offset="0xe38c" name="PC_RESTART_INDEX"/>
+	<reg32 offset="0xe38d" name="PC_GS_LAYERED"/>
+	<reg32 offset="0xe38e" name="PC_GS_PARAM">
+		<bitfield name="MAX_VERTICES" low="0" high="9" type="uint"/><!-- vertices - 1 -->
+		<bitfield name="INVOCATIONS" low="11" high="15" type="uint"/><!-- invoc - 1 -->
+		<bitfield name="PRIMTYPE" low="23" high="24" type="adreno_pa_su_sc_draw"/>
+	</reg32>
+	<reg32 offset="0xe38f" name="PC_HS_PARAM">
+		<bitfield name="VERTICES_OUT" low="0" high="5" type="uint"/>
+		<bitfield name="SPACING" low="21" high="22" type="a4xx_tess_spacing"/>
+		<bitfield name="CW" pos="23" type="boolean"/>
+		<bitfield name="CONNECTED" pos="24" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe3b0" name="PC_POWER_CNTL"/>
+
+	<reg32 offset="0xe400" name="VFD_CONTROL_0">
+		<bitfield name="VTXCNT" low="0" high="5" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe401" name="VFD_CONTROL_1">
+		<bitfield name="REGID4VTX" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="REGID4INST" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="REGID4PRIMID" low="16" high="23" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xe402" name="VFD_CONTROL_2">
+		<bitfield name="REGID_PATCHID" low="0" high="7" type="a3xx_regid"/><!-- same as VFD_CONTROL_3.REGID_PATCHID? -->
+	</reg32>
+	<reg32 offset="0xe403" name="VFD_CONTROL_3">
+		<bitfield name="REGID_PATCHID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="REGID_TESSX" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="REGID_TESSY" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xe404" name="VFD_CONTROL_4">
+	</reg32>
+	<reg32 offset="0xe405" name="VFD_CONTROL_5">
+		<!-- b0 set if gl_PrimitiveID used in fs ?? -->
+	</reg32>
+	<reg32 offset="0xe408" name="VFD_INDEX_OFFSET"/>
+	<reg32 offset="0xe409" name="VFD_INSTANCE_START_OFFSET"/>
+	<array offset="0xe40a" name="VFD_FETCH" stride="4" length="32">
+		<reg32 offset="0x0" name="BASE_LO"/>
+		<reg32 offset="0x1" name="BASE_HI"/>
+		<reg32 offset="0x2" name="SIZE" type="uint"/>
+		<reg32 offset="0x3" name="STRIDE" type="uint"/>
+	</array>
+	<array offset="0xe48a" name="VFD_DECODE" stride="2" length="32">
+		<reg32 offset="0x0" name="INSTR">
+			<!-- IDX appears to index into VFD_FETCH[] -->
+			<bitfield name="IDX" low="0" high="4" type="uint"/>
+			<bitfield name="INSTANCED" pos="17" type="boolean"/>
+			<bitfield name="FORMAT" low="20" high="27" type="a5xx_vtx_fmt"/>
+			<bitfield name="SWAP" low="28" high="29" type="a3xx_color_swap"/>
+			<bitfield name="UNK30" pos="30" type="boolean"/>
+			<bitfield name="FLOAT" pos="31" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x1" name="STEP_RATE"/> <!-- ??? -->
+	</array>
+	<array offset="0xe4ca" name="VFD_DEST_CNTL" stride="1" length="32">
+		<reg32 offset="0x0" name="INSTR">
+			<bitfield name="WRITEMASK" low="0" high="3" type="hex"/>
+			<bitfield name="REGID" low="4" high="11" type="a3xx_regid"/>
+		</reg32>
+	</array>
+	<reg32 offset="0xe4f0" name="VFD_POWER_CNTL"/>
+
+	<!-- 0x0 for compute, 0x10 for 3d? -->
+	<reg32 offset="0xe580" name="SP_SP_CNTL"/>
+
+	<bitset name="a5xx_xs_config" inline="yes">
+		<bitfield name="ENABLED" pos="0" type="boolean"/>
+		<bitfield name="CONSTOBJECTOFFSET" low="1" high="7" type="uint"/>
+		<bitfield name="SHADEROBJOFFSET" low="8" high="14" type="uint"/>
+	</bitset>
+	<bitset name="a5xx_xs_cntl" inline="yes">
+		<bitfield name="SSBO_ENABLE" pos="0" type="boolean"/>
+		<!--
+		no idea high bit.. could be this is amount of on-chip memory used
+		rather than total size?
+		 -->
+		<bitfield name="INSTRLEN" low="1" high="31" type="uint"/>
+	</bitset>
+	<bitset name="a5xx_sp_xs_ctrl_reg0" inline="yes">
+		<!-- bit1 almost always set -->
+		<!-- set for "buffer mode" (ie. shader small enough to fit internally) -->
+		<bitfield name="BUFFER" pos="2" type="boolean"/>
+		<!-- 24 or more (full size) GPRS and blob uses TWO_QUADS instead of FOUR_QUADS -->
+		<bitfield name="THREADSIZE" pos="3" type="a3xx_threadsize"/>
+		<bitfield name="HALFREGFOOTPRINT" low="4" high="9" type="uint"/>
+		<bitfield name="FULLREGFOOTPRINT" low="10" high="15" type="uint"/>
+		<bitfield name="VARYING" pos="16" type="boolean"/>
+		<bitfield name="PIXLODENABLE" pos="20" type="boolean"/>
+		<!-- seems to be nesting level for flow control:.. -->
+		<bitfield name="BRANCHSTACK" low="25" high="31" type="uint"/>
+	</bitset>
+	<!-- assuming things appear in same relative order as a4xx: -->
+	<!-- duplicated exactly w/ corresponding HLSQ_ regs starting at 0xe78b.. -->
+	<reg32 offset="0xe584" name="SP_VS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe585" name="SP_FS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe586" name="SP_HS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe587" name="SP_DS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe588" name="SP_GS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe589" name="SP_CS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe58a" name="SP_VS_CONFIG_MAX_CONST"/>
+	<reg32 offset="0xe58b" name="SP_FS_CONFIG_MAX_CONST"/>
+	<reg32 offset="0xe590" name="SP_VS_CTRL_REG0" type="a5xx_sp_xs_ctrl_reg0"/>
+	<reg32 offset="0xe592" name="SP_PRIMITIVE_CNTL">
+		<!-- # of VS outputs including pos/psize -->
+		<bitfield name="VSOUT" low="0" high="4" type="uint"/>
+	</reg32>
+	<array offset="0xe593" name="SP_VS_OUT" stride="1" length="16">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="A_COMPMASK" low="8" high="11" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="23" type="a3xx_regid"/>
+			<bitfield name="B_COMPMASK" low="24" high="27" type="hex"/>
+		</reg32>
+	</array>
+	<!--
+	Starting with a5xx, position/psize outputs from shader end up in the
+	SP_VS_OUT map, with highest OUTLOCn position.  (Generally they are
+	the last entries too, except when gl_PointCoord is used, blob inserts
+	an extra varying after, but with a lower OUTLOC position.  If present,
+	psize is last, preceded by position.
+	 -->
+	<array offset="0xe5a3" name="SP_VS_VPC_DST" stride="1" length="8">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="OUTLOC0" low="0" high="7" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="15" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="23" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="31" type="uint"/>
+		</reg32>
+	</array>
+	<reg32 offset="0xe5ab" name="UNKNOWN_E5AB"/>
+	<reg32 offset="0xe5ac" name="SP_VS_OBJ_START_LO"/>
+	<reg32 offset="0xe5ad" name="SP_VS_OBJ_START_HI"/>
+
+	<bitset name="a5xx_sp_xs_pvt_mem_param" inline="yes">
+		<bitfield name="MEMSIZEPERITEM" low="0" high="7" shr="9">
+			<doc>The size of memory that ldp/stp can address.</doc>
+		</bitfield>
+		<bitfield name="HWSTACKOFFSET" low="8" high="23" shr="11" type="uint"/>
+		<bitfield name="HWSTACKSIZEPERTHREAD" low="24" high="31">
+                        <doc>Guessing that this is the same as a3xx/a6xx.</doc>
+		</bitfield>
+	</bitset>
+
+	<bitset name="a5xx_sp_xs_pvt_mem_size" inline="yes">
+		<bitfield name="TOTALPVTMEMSIZE" low="0" high="17" shr="12"/>
+	</bitset>
+
+	<reg32 offset="0xe5ae" name="SP_VS_PVT_MEM_PARAM" type="a5xx_sp_xs_pvt_mem_param"/>
+	<reg64 offset="0xe5af" name="SP_VS_PVT_MEM_ADDR" type="waddress" align="32"/>
+	<reg32 offset="0xe5b1" name="SP_VS_PVT_MEM_SIZE" type="a5xx_sp_xs_pvt_mem_size"/>
+	<reg32 offset="0xe5c0" name="SP_FS_CTRL_REG0" type="a5xx_sp_xs_ctrl_reg0"/>
+	<reg32 offset="0xe5c2" name="UNKNOWN_E5C2"/>
+	<reg32 offset="0xe5c3" name="SP_FS_OBJ_START_LO"/>
+	<reg32 offset="0xe5c4" name="SP_FS_OBJ_START_HI"/>
+	<reg32 offset="0xe5c5" name="SP_FS_PVT_MEM_PARAM" type="a5xx_sp_xs_pvt_mem_param"/>
+	<reg64 offset="0xe5c6" name="SP_FS_PVT_MEM_ADDR" type="waddress" align="32"/>
+	<reg32 offset="0xe5c8" name="SP_FS_PVT_MEM_SIZE" type="a5xx_sp_xs_pvt_mem_size"/>
+	<reg32 offset="0xe5c9" name="SP_BLEND_CNTL">
+		<!-- per-mrt enable bit -->
+		<bitfield name="ENABLE_BLEND" low="0" high="7"/>
+		<bitfield name="UNK8" pos="8" type="boolean"/>
+		<bitfield name="ALPHA_TO_COVERAGE" pos="10" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe5ca" name="SP_FS_OUTPUT_CNTL">
+		<bitfield name="MRT" low="0" high="3" type="uint"/>
+		<bitfield name="DEPTH_REGID" low="5" high="12" type="a3xx_regid"/>
+		<bitfield name="SAMPLEMASK_REGID" low="13" high="20" type="a3xx_regid"/>
+	</reg32>
+	<array offset="0xe5cb" name="SP_FS_OUTPUT" stride="1" length="8">
+		<doc>per MRT</doc>
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="HALF_PRECISION" pos="8" type="boolean"/>
+		</reg32>
+	</array>
+	<array offset="0xe5d3" name="SP_FS_MRT" stride="1" length="8">
+		<reg32 offset="0" name="REG">
+			<bitfield name="COLOR_FORMAT" low="0" high="7" type="a5xx_color_fmt"/>
+			<bitfield name="COLOR_SINT" pos="8" type="boolean"/>
+			<bitfield name="COLOR_UINT" pos="9" type="boolean"/>
+			<bitfield name="COLOR_SRGB" pos="10" type="boolean"/>
+		</reg32>
+	</array>
+	<!--
+	e5db/e5dc seems to look related to some optimization to do sample from
+	texture using varying value directly before shader thread starts?  I
+	guess that could optimize common simple frag shaders..
+	 -->
+	<reg32 offset="0xe5db" name="UNKNOWN_E5DB"/>
+	<reg32 offset="0xe5f0" name="SP_CS_CTRL_REG0" type="a5xx_sp_xs_ctrl_reg0"/>
+	<reg32 offset="0xe5f2" name="UNKNOWN_E5F2"/>
+	<reg32 offset="0xe5f3" name="SP_CS_OBJ_START_LO"/>
+	<reg32 offset="0xe5f4" name="SP_CS_OBJ_START_HI"/>
+	<reg32 offset="0xe5f5" name="SP_CS_PVT_MEM_PARAM" type="a5xx_sp_xs_pvt_mem_param"/>
+	<reg64 offset="0xe5f6" name="SP_CS_PVT_MEM_ADDR" type="waddress" align="32"/>
+	<reg32 offset="0xe5f8" name="SP_CS_PVT_MEM_SIZE" type="a5xx_sp_xs_pvt_mem_size"/>
+
+	<!-- e5f9 something compute related.. seems to change when HLSQ_CS_CNTL_1 changes -->
+
+	<reg32 offset="0xe600" name="SP_HS_CTRL_REG0" type="a5xx_sp_xs_ctrl_reg0"/>
+	<reg32 offset="0xe602" name="UNKNOWN_E602"/>
+	<reg32 offset="0xe603" name="SP_HS_OBJ_START_LO"/>
+	<reg32 offset="0xe604" name="SP_HS_OBJ_START_HI"/>
+	<reg32 offset="0xe605" name="SP_HS_PVT_MEM_PARAM" type="a5xx_sp_xs_pvt_mem_param"/>
+	<reg64 offset="0xe606" name="SP_HS_PVT_MEM_ADDR" type="waddress" align="32"/>
+	<reg32 offset="0xe608" name="SP_HS_PVT_MEM_SIZE" type="a5xx_sp_xs_pvt_mem_size"/>
+	<reg32 offset="0xe610" name="SP_DS_CTRL_REG0" type="a5xx_sp_xs_ctrl_reg0"/>
+	<reg32 offset="0xe62b" name="UNKNOWN_E62B"/>
+	<reg32 offset="0xe62c" name="SP_DS_OBJ_START_LO"/>
+	<reg32 offset="0xe62d" name="SP_DS_OBJ_START_HI"/>
+	<reg32 offset="0xe62e" name="SP_DS_PVT_MEM_PARAM" type="a5xx_sp_xs_pvt_mem_param"/>
+	<reg64 offset="0xe62f" name="SP_DS_PVT_MEM_ADDR" type="waddress" align="32"/>
+	<reg32 offset="0xe631" name="SP_DS_PVT_MEM_SIZE" type="a5xx_sp_xs_pvt_mem_size"/>
+	<reg32 offset="0xe640" name="SP_GS_CTRL_REG0" type="a5xx_sp_xs_ctrl_reg0"/>
+	<reg32 offset="0xe65b" name="UNKNOWN_E65B"/>
+	<reg32 offset="0xe65c" name="SP_GS_OBJ_START_LO"/>
+	<reg32 offset="0xe65d" name="SP_GS_OBJ_START_HI"/>
+	<reg32 offset="0xe65e" name="SP_GS_PVT_MEM_PARAM" type="a5xx_sp_xs_pvt_mem_param"/>
+	<reg64 offset="0xe65f" name="SP_GS_PVT_MEM_ADDR" type="waddress" align="32"/>
+	<reg32 offset="0xe661" name="SP_GS_PVT_MEM_SIZE" type="a5xx_sp_xs_pvt_mem_size"/>
+
+	<reg32 offset="0xe704" name="TPL1_TP_RAS_MSAA_CNTL">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+	</reg32>
+	<reg32 offset="0xe705" name="TPL1_TP_DEST_MSAA_CNTL">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="MSAA_DISABLE" pos="2" type="boolean"/>
+	</reg32>
+	<!-- either blob is doing it wrong, or this is not per-stage anymore: -->
+	<reg32 offset="0xe706" name="TPL1_TP_BORDER_COLOR_BASE_ADDR_LO"/>
+	<reg32 offset="0xe707" name="TPL1_TP_BORDER_COLOR_BASE_ADDR_HI"/>
+
+	<!--
+	so these have the same info that is normally in the CP_LOAD_STATE
+	packets.. not sure if they are normally written by pm4/me or if the
+	CP_LOAD_STATE mechanism is deprecated?
+	 -->
+	<reg32 offset="0xe700" name="TPL1_VS_TEX_COUNT" type="uint"/>
+	<reg32 offset="0xe701" name="TPL1_HS_TEX_COUNT" type="uint"/>
+	<reg32 offset="0xe702" name="TPL1_DS_TEX_COUNT" type="uint"/>
+	<reg32 offset="0xe703" name="TPL1_GS_TEX_COUNT" type="uint"/>
+
+	<reg32 offset="0xe722" name="TPL1_VS_TEX_SAMP_LO"/>
+	<reg32 offset="0xe723" name="TPL1_VS_TEX_SAMP_HI"/>
+	<reg32 offset="0xe724" name="TPL1_HS_TEX_SAMP_LO"/>
+	<reg32 offset="0xe725" name="TPL1_HS_TEX_SAMP_HI"/>
+	<reg32 offset="0xe726" name="TPL1_DS_TEX_SAMP_LO"/>
+	<reg32 offset="0xe727" name="TPL1_DS_TEX_SAMP_HI"/>
+	<reg32 offset="0xe728" name="TPL1_GS_TEX_SAMP_LO"/>
+	<reg32 offset="0xe729" name="TPL1_GS_TEX_SAMP_HI"/>
+
+	<reg32 offset="0xe72a" name="TPL1_VS_TEX_CONST_LO"/>
+	<reg32 offset="0xe72b" name="TPL1_VS_TEX_CONST_HI"/>
+	<reg32 offset="0xe72c" name="TPL1_HS_TEX_CONST_LO"/>
+	<reg32 offset="0xe72d" name="TPL1_HS_TEX_CONST_HI"/>
+	<reg32 offset="0xe72e" name="TPL1_DS_TEX_CONST_LO"/>
+	<reg32 offset="0xe72f" name="TPL1_DS_TEX_CONST_HI"/>
+	<reg32 offset="0xe730" name="TPL1_GS_TEX_CONST_LO"/>
+	<reg32 offset="0xe731" name="TPL1_GS_TEX_CONST_HI"/>
+
+	<reg32 offset="0xe750" name="TPL1_FS_TEX_COUNT" type="uint"/>
+	<reg32 offset="0xe751" name="TPL1_CS_TEX_COUNT" type="uint"/>
+
+	<reg32 offset="0xe75a" name="TPL1_FS_TEX_SAMP_LO"/>
+	<reg32 offset="0xe75b" name="TPL1_FS_TEX_SAMP_HI"/>
+	<reg32 offset="0xe75c" name="TPL1_CS_TEX_SAMP_LO"/>
+	<reg32 offset="0xe75d" name="TPL1_CS_TEX_SAMP_HI"/>
+	<reg32 offset="0xe75e" name="TPL1_FS_TEX_CONST_LO"/>
+	<reg32 offset="0xe75f" name="TPL1_FS_TEX_CONST_HI"/>
+	<reg32 offset="0xe760" name="TPL1_CS_TEX_CONST_LO"/>
+	<reg32 offset="0xe761" name="TPL1_CS_TEX_CONST_HI"/>
+
+	<reg32 offset="0xe764" name="TPL1_TP_FS_ROTATION_CNTL"/>
+
+	<reg32 offset="0xe784" name="HLSQ_CONTROL_0_REG">
+		<!-- 24 or more (full size) GPRS and blob uses TWO_QUADS instead of FOUR_QUADS -->
+		<bitfield name="FSTHREADSIZE" pos="0" type="a3xx_threadsize"/>
+		<bitfield name="CSTHREADSIZE" pos="2" type="a3xx_threadsize"/>
+	</reg32>
+	<reg32 offset="0xe785" name="HLSQ_CONTROL_1_REG">
+		<!-- I guess.. not set exactly same as a4xx, but similar: -->
+		<bitfield name="PRIMALLOCTHRESHOLD" low="0" high="5" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe786" name="HLSQ_CONTROL_2_REG">
+		<bitfield name="FACEREGID" low="0" high="7" type="a3xx_regid"/>
+		<!-- SAMPLEID is loaded into a half-precision register: -->
+		<bitfield name="SAMPLEID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="SAMPLEMASK" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="CENTERRHW" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xe787" name="HLSQ_CONTROL_3_REG">
+		<!-- register loaded with position (bary.f) -->
+		<bitfield name="IJ_PERSP_PIXEL" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_PIXEL" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="IJ_PERSP_CENTROID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_CENTROID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xe788" name="HLSQ_CONTROL_4_REG">
+		<bitfield name="IJ_PERSP_SAMPLE" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_SAMPLE" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="XYCOORDREGID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="ZWCOORDREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<!--
+	0x020fffff for normal draws, 0x1f00000 for compute.. maybe what state
+	is enabled?  We could probably try disabling different bits and see
+	what breaks to figure out which is what:
+	 -->
+	<reg32 offset="0xe78a" name="HLSQ_UPDATE_CNTL"/>
+	<reg32 offset="0xe78b" name="HLSQ_VS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe78c" name="HLSQ_FS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe78d" name="HLSQ_HS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe78e" name="HLSQ_DS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe78f" name="HLSQ_GS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe790" name="HLSQ_CS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe791" name="HLSQ_VS_CNTL" type="a5xx_xs_cntl"/>
+	<reg32 offset="0xe792" name="HLSQ_FS_CNTL" type="a5xx_xs_cntl"/>
+	<reg32 offset="0xe793" name="HLSQ_HS_CNTL" type="a5xx_xs_cntl"/>
+	<reg32 offset="0xe794" name="HLSQ_DS_CNTL" type="a5xx_xs_cntl"/>
+	<reg32 offset="0xe795" name="HLSQ_GS_CNTL" type="a5xx_xs_cntl"/>
+	<reg32 offset="0xe796" name="HLSQ_CS_CNTL" type="a5xx_xs_cntl"/>
+	<reg32 offset="0xe7b9" name="HLSQ_CS_KERNEL_GROUP_X"/>
+	<reg32 offset="0xe7ba" name="HLSQ_CS_KERNEL_GROUP_Y"/>
+	<reg32 offset="0xe7bb" name="HLSQ_CS_KERNEL_GROUP_Z"/>
+	<reg32 offset="0xe7b0" name="HLSQ_CS_NDRANGE_0">
+		<bitfield name="KERNELDIM" low="0" high="1" type="uint"/>
+		<!-- localsize is value minus one: -->
+		<bitfield name="LOCALSIZEX" low="2" high="11" type="uint"/>
+		<bitfield name="LOCALSIZEY" low="12" high="21" type="uint"/>
+		<bitfield name="LOCALSIZEZ" low="22" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe7b1" name="HLSQ_CS_NDRANGE_1">
+		<bitfield name="GLOBALSIZE_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe7b2" name="HLSQ_CS_NDRANGE_2">
+		<bitfield name="GLOBALOFF_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe7b3" name="HLSQ_CS_NDRANGE_3">
+		<bitfield name="GLOBALSIZE_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe7b4" name="HLSQ_CS_NDRANGE_4">
+		<bitfield name="GLOBALOFF_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe7b5" name="HLSQ_CS_NDRANGE_5">
+		<bitfield name="GLOBALSIZE_Z" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe7b6" name="HLSQ_CS_NDRANGE_6">
+		<bitfield name="GLOBALOFF_Z" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe7b7" name="HLSQ_CS_CNTL_0">
+		<bitfield name="WGIDCONSTID" low="0" high="7" type="a3xx_regid"/>
+		<!-- possibly one of these is KERNELDIMCONSTID? -->
+		<!--
+		UNK0 appears to be NUMWGCONSTID.. but only works in certain
+		cases?  Blob doesn't appear to use it, but instead emits
+		these via const (uniform).  Which requires some shenanigans
+		for indirect draws when the offset is not strongly aligned
+		enough to use as EXT_SRC_ADDR in CP_LOAD_STATE
+		 -->
+		<bitfield name="UNK0" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="UNK1" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="LOCALIDREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xe7b8" name="HLSQ_CS_CNTL_1"/>
+	<reg32 offset="0xe7c0" name="UNKNOWN_E7C0"/>
+	<reg32 offset="0xe7c3" name="HLSQ_VS_CONSTLEN" type="uint"/>
+	<reg32 offset="0xe7c4" name="HLSQ_VS_INSTRLEN" type="uint"/>
+	<reg32 offset="0xe7c5" name="UNKNOWN_E7C5"/>
+	<reg32 offset="0xe7c8" name="HLSQ_HS_CONSTLEN" type="uint"/>
+	<reg32 offset="0xe7c9" name="HLSQ_HS_INSTRLEN" type="uint"/>
+	<reg32 offset="0xe7ca" name="UNKNOWN_E7CA"/>
+	<reg32 offset="0xe7cd" name="HLSQ_DS_CONSTLEN" type="uint"/>
+	<reg32 offset="0xe7ce" name="HLSQ_DS_INSTRLEN" type="uint"/>
+	<reg32 offset="0xe7cf" name="UNKNOWN_E7CF"/>
+	<reg32 offset="0xe7d2" name="HLSQ_GS_CONSTLEN" type="uint"/>
+	<reg32 offset="0xe7d3" name="HLSQ_GS_INSTRLEN" type="uint"/>
+	<reg32 offset="0xe7d4" name="UNKNOWN_E7D4"/>
+	<reg32 offset="0xe7d7" name="HLSQ_FS_CONSTLEN" type="uint"/>
+	<reg32 offset="0xe7d8" name="HLSQ_FS_INSTRLEN" type="uint"/>
+	<reg32 offset="0xe7d9" name="UNKNOWN_E7D9"/>
+	<reg32 offset="0xe7dc" name="HLSQ_CS_CONSTLEN" type="uint"/>
+	<reg32 offset="0xe7dd" name="HLSQ_CS_INSTRLEN" type="uint"/>
+
+	<!--
+		Separate blit/2d or dma engine?  Seems to get used sometimes for
+		texture uploads, where a4xx blob would use normal draws.  Used
+		in render-mode 0x5..
+
+		Note seems mostly to be used for small blits, large blits seem
+		to use the CP_EVENT_WRITE:BLIT style of doing things.  See
+		cubemap-0003 (40x40) vs cubemap-0004 (256x256).
+
+		see cube-0000, cubemap-(1..3 but not 4+), quad-textured-10..17
+
+		Other nearby registers are probably color formats, etc.  The
+		blit coords are in CP packet.  Play more w/ glTexSubImage2D()
+		to work it out.
+
+		Separate this into a different domain??  Would that help to
+		restrict which registers we dump based on mode?
+
+		regs 0x2000 to 0x2004 (plus all-zero regs 0x2005-0x2009) look
+		like 2nd source for blending?  Used in mipmap generation.. but
+		maybe layout is a bit different.  (Possibly used for reading
+		src via sampler, to enable scaling??)  0x2040 also used in this
+		case.
+	 -->
+	<reg32 offset="0x2100" name="RB_2D_BLIT_CNTL"/>  <!-- same as 0x2180 -->
+	<reg32 offset="0x2101" name="RB_2D_SRC_SOLID_DW0"/>
+	<reg32 offset="0x2102" name="RB_2D_SRC_SOLID_DW1"/>
+	<reg32 offset="0x2103" name="RB_2D_SRC_SOLID_DW2"/>
+	<reg32 offset="0x2104" name="RB_2D_SRC_SOLID_DW3"/>
+
+	<bitset name="a5xx_2d_surf_info" inline="yes">
+		<bitfield name="COLOR_FORMAT" low="0" high="7" type="a5xx_color_fmt"/>
+		<bitfield name="TILE_MODE" low="8" high="9" type="a5xx_tile_mode"/>
+		<bitfield name="COLOR_SWAP" low="10" high="11" type="a3xx_color_swap"/>
+		<!-- b12 seems to be set when UBWC "FLAGS" buffer enabled -->
+		<bitfield name="FLAGS" pos="12" type="boolean"/>
+		<bitfield name="SRGB" pos="13" type="boolean"/>
+	</bitset>
+
+	<reg32 offset="0x2107" name="RB_2D_SRC_INFO" type="a5xx_2d_surf_info"/>
+	<reg32 offset="0x2108" name="RB_2D_SRC_LO"/>
+	<reg32 offset="0x2109" name="RB_2D_SRC_HI"/>
+	<reg32 offset="0x210a" name="RB_2D_SRC_SIZE">
+		<bitfield name="PITCH" low="0" high="15" shr="6" type="uint"/>
+		<bitfield name="ARRAY_PITCH" low="16" high="31" shr="6" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x2110" name="RB_2D_DST_INFO" type="a5xx_2d_surf_info"/>
+	<reg32 offset="0x2111" name="RB_2D_DST_LO"/>
+	<reg32 offset="0x2112" name="RB_2D_DST_HI"/>
+	<reg32 offset="0x2113" name="RB_2D_DST_SIZE">
+		<bitfield name="PITCH" low="0" high="15" shr="6" type="uint"/>
+		<bitfield name="ARRAY_PITCH" low="16" high="31" shr="6" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2140" name="RB_2D_SRC_FLAGS_LO"/>
+	<reg32 offset="0x2141" name="RB_2D_SRC_FLAGS_HI"/>
+        <reg32 offset="0x2142" name="RB_2D_SRC_FLAGS_PITCH" shr="6" type="uint"/>
+	<reg32 offset="0x2143" name="RB_2D_DST_FLAGS_LO"/>
+	<reg32 offset="0x2144" name="RB_2D_DST_FLAGS_HI"/>
+        <reg32 offset="0x2145" name="RB_2D_DST_FLAGS_PITCH" shr="6" type="uint"/>
+	<reg32 offset="0x2180" name="GRAS_2D_BLIT_CNTL"/> <!-- same as 0x2100 -->
+	<!-- looks same as 0x2107: -->
+	<reg32 offset="0x2181" name="GRAS_2D_SRC_INFO" type="a5xx_2d_surf_info"/>
+	<!-- looks same as 0x2110: -->
+	<reg32 offset="0x2182" name="GRAS_2D_DST_INFO" type="a5xx_2d_surf_info"/>
+<!--
+0x2100 and 0x2180 look like same thing (RB and GRAS versions)..
+   0x86000000 for copy, 0x00000000 for fill?
+
+0x2184 0x9 for copy, 0x1 for blit (maybe bitmask of enabled src/dst???)
+ -->
+	<reg32 offset="0x2184" name="UNKNOWN_2184"/>
+</domain>
+
+<domain name="A5XX_TEX_SAMP" width="32">
+	<doc>Texture sampler dwords</doc>
+	<enum name="a5xx_tex_filter"> <!-- same as a4xx? -->
+		<value name="A5XX_TEX_NEAREST" value="0"/>
+		<value name="A5XX_TEX_LINEAR" value="1"/>
+		<value name="A5XX_TEX_ANISO" value="2"/>
+	</enum>
+	<enum name="a5xx_tex_clamp"> <!-- same as a4xx? -->
+		<value name="A5XX_TEX_REPEAT" value="0"/>
+		<value name="A5XX_TEX_CLAMP_TO_EDGE" value="1"/>
+		<value name="A5XX_TEX_MIRROR_REPEAT" value="2"/>
+		<value name="A5XX_TEX_CLAMP_TO_BORDER" value="3"/>
+		<value name="A5XX_TEX_MIRROR_CLAMP" value="4"/>
+	</enum>
+	<enum name="a5xx_tex_aniso"> <!-- same as a4xx? -->
+		<value name="A5XX_TEX_ANISO_1" value="0"/>
+		<value name="A5XX_TEX_ANISO_2" value="1"/>
+		<value name="A5XX_TEX_ANISO_4" value="2"/>
+		<value name="A5XX_TEX_ANISO_8" value="3"/>
+		<value name="A5XX_TEX_ANISO_16" value="4"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="MIPFILTER_LINEAR_NEAR" pos="0" type="boolean"/>
+		<bitfield name="XY_MAG" low="1" high="2" type="a5xx_tex_filter"/>
+		<bitfield name="XY_MIN" low="3" high="4" type="a5xx_tex_filter"/>
+		<bitfield name="WRAP_S" low="5" high="7" type="a5xx_tex_clamp"/>
+		<bitfield name="WRAP_T" low="8" high="10" type="a5xx_tex_clamp"/>
+		<bitfield name="WRAP_R" low="11" high="13" type="a5xx_tex_clamp"/>
+		<bitfield name="ANISO" low="14" high="16" type="a5xx_tex_aniso"/>
+		<bitfield name="LOD_BIAS" low="19" high="31" type="fixed" radix="8"/><!-- no idea how many bits for real -->
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="COMPARE_FUNC" low="1" high="3" type="adreno_compare_func"/>
+		<bitfield name="CUBEMAPSEAMLESSFILTOFF" pos="4" type="boolean"/>
+		<bitfield name="UNNORM_COORDS" pos="5" type="boolean"/>
+		<bitfield name="MIPFILTER_LINEAR_FAR" pos="6" type="boolean"/>
+		<bitfield name="MAX_LOD" low="8" high="19" type="ufixed" radix="8"/>
+		<bitfield name="MIN_LOD" low="20" high="31" type="ufixed" radix="8"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<!--
+		offset into border-color buffer?  Blob always uses 0x80 for FS state
+		if both VS and FS have border-color.
+Seems like when both VS and FS have bcolor, one starts 0x300 after other..
+and 0x80 in TEX_SAMP.2 ..  blob doesn't seem to be able to cope w/ multiple
+different border-color states per texture..  Looks something like:
+0000: 3f000000 00000000 00000000 3f800000 00008000 ffff0000 00004000 7fff0000
+0020: 00003800 3c000000 80100010 0000f008 ff000080 7f000040 c0000200 00800000
+0040: 00003800 3c000000 00000000 00000000 00000000 00000000 00000000 00000000
+*
+0300: 3f800000 3f800000 3f800000 3f800000 ffffffff ffffffff 7fff7fff 7fff7fff
+0320: 3c003c00 3c003c00 ffffffff 0000ffff ffffffff 7f7f7f7f ffffffff 00ffffff
+0340: 3c003c00 3c003c00 00000000 00000000 00000000 00000000 00000000 00000000
+
+		 -->
+		<bitfield name="BCOLOR_OFFSET" low="7" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3"/>
+</domain>
+
+<domain name="A5XX_TEX_CONST" width="32">
+	<doc>Texture constant dwords</doc>
+	<enum name="a5xx_tex_swiz"> <!-- same as a4xx? -->
+		<value name="A5XX_TEX_X" value="0"/>
+		<value name="A5XX_TEX_Y" value="1"/>
+		<value name="A5XX_TEX_Z" value="2"/>
+		<value name="A5XX_TEX_W" value="3"/>
+		<value name="A5XX_TEX_ZERO" value="4"/>
+		<value name="A5XX_TEX_ONE" value="5"/>
+	</enum>
+	<enum name="a5xx_tex_type"> <!-- same as a4xx? -->
+		<value name="A5XX_TEX_1D" value="0"/>
+		<value name="A5XX_TEX_2D" value="1"/>
+		<value name="A5XX_TEX_CUBE" value="2"/>
+		<value name="A5XX_TEX_3D" value="3"/>
+		<value name="A5XX_TEX_BUFFER" value="4"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="TILE_MODE" low="0" high="1" type="a5xx_tile_mode"/>
+		<bitfield name="SRGB" pos="2" type="boolean"/>
+		<bitfield name="SWIZ_X" low="4" high="6" type="a5xx_tex_swiz"/>
+		<bitfield name="SWIZ_Y" low="7" high="9" type="a5xx_tex_swiz"/>
+		<bitfield name="SWIZ_Z" low="10" high="12" type="a5xx_tex_swiz"/>
+		<bitfield name="SWIZ_W" low="13" high="15" type="a5xx_tex_swiz"/>
+		<bitfield name="MIPLVLS" low="16" high="19" type="uint"/>
+		<bitfield name="SAMPLES" low="20" high="21" type="a3xx_msaa_samples"/>
+		<bitfield name="FMT" low="22" high="29" type="a5xx_tex_fmt"/>
+		<bitfield name="SWAP" low="30" high="31" type="a3xx_color_swap"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="WIDTH" low="0" high="14" type="uint"/>
+		<bitfield name="HEIGHT" low="15" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<!--
+		b4 and b31 set for buffer/ssbo case, in which case low 15 bits
+		of size encoded in WIDTH, and high 15 bits encoded in HEIGHT
+
+		b31 is probably the 'BUFFER' bit.. it is the one that changes
+		behavior of texture in dEQP-GLES31.functional.texture.texture_buffer.render.as_fragment_texture.buffer_size_131071
+		 -->
+		<bitfield name="BUFFER" pos="4" type="boolean"/>
+		<!-- minimum pitch (for mipmap levels): log2(pitchalign / 64) -->
+		<bitfield name="PITCHALIGN" low="0" high="3" type="uint"/>
+		<doc>Pitch in bytes (so actually stride)</doc>
+		<bitfield name="PITCH" low="7" high="28" type="uint"/>
+		<bitfield name="TYPE" low="29" high="31" type="a5xx_tex_type"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<!--
+		ARRAY_PITCH is basically LAYERSZ for the first mipmap level, and
+		for 3d textures (laid out mipmap level first) MIN_LAYERSZ is the
+		layer size at the point that it stops being reduced moving to
+		higher (smaller) mipmap levels
+		 -->
+		<bitfield name="ARRAY_PITCH" low="0" high="13" shr="12" type="uint"/>
+		<bitfield name="MIN_LAYERSZ" low="23" high="26" shr="12"/>
+		<!--
+		by default levels with w < 16 are linear
+		TILE_ALL makes all levels have tiling
+		seems required when using UBWC, since all levels have UBWC (can possibly be disabled?)
+		 -->
+		<bitfield name="TILE_ALL" pos="27" type="boolean"/>
+		<bitfield name="FLAG" pos="28" type="boolean"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="BASE_LO" low="5" high="31" shr="5"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="BASE_HI" low="0" high="16"/>
+		<bitfield name="DEPTH" low="17" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="6" name="6"/>
+	<reg32 offset="7" name="7"/>
+	<reg32 offset="8" name="8"/>
+	<reg32 offset="9" name="9"/>
+	<reg32 offset="10" name="10"/>
+	<reg32 offset="11" name="11"/>
+</domain>
+
+<!--
+Note the "SSBO" state blocks are actually used for both images and SSBOs,
+naming is just because I r/e'd SSBOs first.  I should probably come up
+with a better name.
+-->
+<domain name="A5XX_SSBO_0" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="BASE_LO" low="5" high="31" shr="5"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<!-- no BASE_HI here?  Maybe this is only used for 32b mode? -->
+		<doc>Pitch in bytes (so actually stride)</doc>
+		<bitfield name="PITCH" low="0" high="21" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="ARRAY_PITCH" low="12" high="25" shr="12" type="uint"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<!-- bytes per pixel: -->
+		<bitfield name="CPP" low="0" high="5" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="A5XX_SSBO_1" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="FMT" low="8" high="15" type="a5xx_tex_fmt"/>
+		<bitfield name="WIDTH" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="HEIGHT" low="0" high="15" type="uint"/>
+		<bitfield name="DEPTH" low="16" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="A5XX_SSBO_2" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="BASE_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="BASE_HI" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="A5XX_UBO" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="BASE_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="BASE_HI" low="0" high="16"/>
+		<!-- size probably in high bits -->
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/adreno/a6xx.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/adreno/a6xx.xml
@@ -0,0 +1,6092 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="adreno/adreno_common.xml"/>
+<import file="adreno/adreno_pm4.xml"/>
+
+<!--
+Each register that is actually being used by driver should have "usage" defined,
+currently there are following usages:
+- "cmd" - the register is used outside of renderpass and blits,
+		roughly corresponds to registers used in ib1 for Freedreno
+- "rp_blit" - the register is used inside renderpass or blits
+		(ib2 for Freedreno)
+
+It is expected that register with "cmd" usage may be written into only at
+the start of the command buffer (ib1), while "rp_blit" usage indicates that register
+is either overwritten by renderpass/blit (ib2) or not used if not overwritten
+by a particular renderpass/blit.
+-->
+
+<!-- these might be same as a5xx -->
+<enum name="a6xx_tile_mode">
+	<value name="TILE6_LINEAR" value="0"/>
+	<value name="TILE6_2" value="2"/>
+	<value name="TILE6_3" value="3"/>
+</enum>
+
+<enum name="a6xx_format">
+	<value value="0x02" name="FMT6_A8_UNORM"/>
+	<value value="0x03" name="FMT6_8_UNORM"/>
+	<value value="0x04" name="FMT6_8_SNORM"/>
+	<value value="0x05" name="FMT6_8_UINT"/>
+	<value value="0x06" name="FMT6_8_SINT"/>
+
+	<value value="0x08" name="FMT6_4_4_4_4_UNORM"/>
+	<value value="0x0a" name="FMT6_5_5_5_1_UNORM"/>
+	<value value="0x0c" name="FMT6_1_5_5_5_UNORM"/> <!-- read only -->
+	<value value="0x0e" name="FMT6_5_6_5_UNORM"/>
+
+	<value value="0x0f" name="FMT6_8_8_UNORM"/>
+	<value value="0x10" name="FMT6_8_8_SNORM"/>
+	<value value="0x11" name="FMT6_8_8_UINT"/>
+	<value value="0x12" name="FMT6_8_8_SINT"/>
+	<value value="0x13" name="FMT6_L8_A8_UNORM"/>
+
+	<value value="0x15" name="FMT6_16_UNORM"/>
+	<value value="0x16" name="FMT6_16_SNORM"/>
+	<value value="0x17" name="FMT6_16_FLOAT"/>
+	<value value="0x18" name="FMT6_16_UINT"/>
+	<value value="0x19" name="FMT6_16_SINT"/>
+
+	<value value="0x21" name="FMT6_8_8_8_UNORM"/>
+	<value value="0x22" name="FMT6_8_8_8_SNORM"/>
+	<value value="0x23" name="FMT6_8_8_8_UINT"/>
+	<value value="0x24" name="FMT6_8_8_8_SINT"/>
+
+	<value value="0x30" name="FMT6_8_8_8_8_UNORM"/>
+	<value value="0x31" name="FMT6_8_8_8_X8_UNORM"/> <!-- samples 1 for alpha -->
+	<value value="0x32" name="FMT6_8_8_8_8_SNORM"/>
+	<value value="0x33" name="FMT6_8_8_8_8_UINT"/>
+	<value value="0x34" name="FMT6_8_8_8_8_SINT"/>
+
+	<value value="0x35" name="FMT6_9_9_9_E5_FLOAT"/>
+
+	<value value="0x36" name="FMT6_10_10_10_2_UNORM"/>
+	<value value="0x37" name="FMT6_10_10_10_2_UNORM_DEST"/>
+	<value value="0x39" name="FMT6_10_10_10_2_SNORM"/>
+	<value value="0x3a" name="FMT6_10_10_10_2_UINT"/>
+	<value value="0x3b" name="FMT6_10_10_10_2_SINT"/>
+
+	<value value="0x42" name="FMT6_11_11_10_FLOAT"/>
+
+	<value value="0x43" name="FMT6_16_16_UNORM"/>
+	<value value="0x44" name="FMT6_16_16_SNORM"/>
+	<value value="0x45" name="FMT6_16_16_FLOAT"/>
+	<value value="0x46" name="FMT6_16_16_UINT"/>
+	<value value="0x47" name="FMT6_16_16_SINT"/>
+
+	<value value="0x48" name="FMT6_32_UNORM"/>
+	<value value="0x49" name="FMT6_32_SNORM"/>
+	<value value="0x4a" name="FMT6_32_FLOAT"/>
+	<value value="0x4b" name="FMT6_32_UINT"/>
+	<value value="0x4c" name="FMT6_32_SINT"/>
+	<value value="0x4d" name="FMT6_32_FIXED"/>
+
+	<value value="0x58" name="FMT6_16_16_16_UNORM"/>
+	<value value="0x59" name="FMT6_16_16_16_SNORM"/>
+	<value value="0x5a" name="FMT6_16_16_16_FLOAT"/>
+	<value value="0x5b" name="FMT6_16_16_16_UINT"/>
+	<value value="0x5c" name="FMT6_16_16_16_SINT"/>
+
+	<value value="0x60" name="FMT6_16_16_16_16_UNORM"/>
+	<value value="0x61" name="FMT6_16_16_16_16_SNORM"/>
+	<value value="0x62" name="FMT6_16_16_16_16_FLOAT"/>
+	<value value="0x63" name="FMT6_16_16_16_16_UINT"/>
+	<value value="0x64" name="FMT6_16_16_16_16_SINT"/>
+
+	<value value="0x65" name="FMT6_32_32_UNORM"/>
+	<value value="0x66" name="FMT6_32_32_SNORM"/>
+	<value value="0x67" name="FMT6_32_32_FLOAT"/>
+	<value value="0x68" name="FMT6_32_32_UINT"/>
+	<value value="0x69" name="FMT6_32_32_SINT"/>
+	<value value="0x6a" name="FMT6_32_32_FIXED"/>
+
+	<value value="0x70" name="FMT6_32_32_32_UNORM"/>
+	<value value="0x71" name="FMT6_32_32_32_SNORM"/>
+	<value value="0x72" name="FMT6_32_32_32_UINT"/>
+	<value value="0x73" name="FMT6_32_32_32_SINT"/>
+	<value value="0x74" name="FMT6_32_32_32_FLOAT"/>
+	<value value="0x75" name="FMT6_32_32_32_FIXED"/>
+
+	<value value="0x80" name="FMT6_32_32_32_32_UNORM"/>
+	<value value="0x81" name="FMT6_32_32_32_32_SNORM"/>
+	<value value="0x82" name="FMT6_32_32_32_32_FLOAT"/>
+	<value value="0x83" name="FMT6_32_32_32_32_UINT"/>
+	<value value="0x84" name="FMT6_32_32_32_32_SINT"/>
+	<value value="0x85" name="FMT6_32_32_32_32_FIXED"/>
+
+	<value value="0x8c" name="FMT6_G8R8B8R8_422_UNORM"/> <!-- UYVY -->
+	<value value="0x8d" name="FMT6_R8G8R8B8_422_UNORM"/> <!-- YUYV -->
+	<value value="0x8e" name="FMT6_R8_G8B8_2PLANE_420_UNORM"/> <!-- NV12 -->
+	<value value="0x8f" name="FMT6_NV21"/>
+	<value value="0x90" name="FMT6_R8_G8_B8_3PLANE_420_UNORM"/> <!-- YV12 -->
+
+	<value value="0x91" name="FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8"/>
+
+	<!-- Note: tiling/UBWC for these may be different from equivalent formats
+	For example FMT6_NV12_Y is not compatible with FMT6_8_UNORM
+	-->
+	<value value="0x94" name="FMT6_NV12_Y"/>
+	<value value="0x95" name="FMT6_NV12_UV"/>
+	<value value="0x96" name="FMT6_NV12_VU"/>
+	<value value="0x97" name="FMT6_NV12_4R"/>
+	<value value="0x98" name="FMT6_NV12_4R_Y"/>
+	<value value="0x99" name="FMT6_NV12_4R_UV"/>
+	<value value="0x9a" name="FMT6_P010"/>
+	<value value="0x9b" name="FMT6_P010_Y"/>
+	<value value="0x9c" name="FMT6_P010_UV"/>
+	<value value="0x9d" name="FMT6_TP10"/>
+	<value value="0x9e" name="FMT6_TP10_Y"/>
+	<value value="0x9f" name="FMT6_TP10_UV"/>
+
+	<value value="0xa0" name="FMT6_Z24_UNORM_S8_UINT"/>
+
+	<value value="0xab" name="FMT6_ETC2_RG11_UNORM"/>
+	<value value="0xac" name="FMT6_ETC2_RG11_SNORM"/>
+	<value value="0xad" name="FMT6_ETC2_R11_UNORM"/>
+	<value value="0xae" name="FMT6_ETC2_R11_SNORM"/>
+	<value value="0xaf" name="FMT6_ETC1"/>
+	<value value="0xb0" name="FMT6_ETC2_RGB8"/>
+	<value value="0xb1" name="FMT6_ETC2_RGBA8"/>
+	<value value="0xb2" name="FMT6_ETC2_RGB8A1"/>
+	<value value="0xb3" name="FMT6_DXT1"/>
+	<value value="0xb4" name="FMT6_DXT3"/>
+	<value value="0xb5" name="FMT6_DXT5"/>
+	<value value="0xb7" name="FMT6_RGTC1_UNORM"/>
+	<value value="0xb8" name="FMT6_RGTC1_SNORM"/>
+	<value value="0xbb" name="FMT6_RGTC2_UNORM"/>
+	<value value="0xbc" name="FMT6_RGTC2_SNORM"/>
+	<value value="0xbe" name="FMT6_BPTC_UFLOAT"/>
+	<value value="0xbf" name="FMT6_BPTC_FLOAT"/>
+	<value value="0xc0" name="FMT6_BPTC"/>
+	<value value="0xc1" name="FMT6_ASTC_4x4"/>
+	<value value="0xc2" name="FMT6_ASTC_5x4"/>
+	<value value="0xc3" name="FMT6_ASTC_5x5"/>
+	<value value="0xc4" name="FMT6_ASTC_6x5"/>
+	<value value="0xc5" name="FMT6_ASTC_6x6"/>
+	<value value="0xc6" name="FMT6_ASTC_8x5"/>
+	<value value="0xc7" name="FMT6_ASTC_8x6"/>
+	<value value="0xc8" name="FMT6_ASTC_8x8"/>
+	<value value="0xc9" name="FMT6_ASTC_10x5"/>
+	<value value="0xca" name="FMT6_ASTC_10x6"/>
+	<value value="0xcb" name="FMT6_ASTC_10x8"/>
+	<value value="0xcc" name="FMT6_ASTC_10x10"/>
+	<value value="0xcd" name="FMT6_ASTC_12x10"/>
+	<value value="0xce" name="FMT6_ASTC_12x12"/>
+
+	<!-- for sampling stencil (integer, 2nd channel), not available on a630 -->
+	<value value="0xea" name="FMT6_Z24_UINT_S8_UINT"/>
+
+	<!-- Not a hw enum, used internally in driver -->
+	<value value="0xff" name="FMT6_NONE"/>
+
+</enum>
+
+<!-- probably same as a5xx -->
+<enum name="a6xx_polygon_mode">
+	<value name="POLYMODE6_POINTS" value="1"/>
+	<value name="POLYMODE6_LINES" value="2"/>
+	<value name="POLYMODE6_TRIANGLES" value="3"/>
+</enum>
+
+<enum name="a6xx_depth_format">
+	<value name="DEPTH6_NONE" value="0"/>
+	<value name="DEPTH6_16" value="1"/>
+	<value name="DEPTH6_24_8" value="2"/>
+	<value name="DEPTH6_32" value="4"/>
+</enum>
+
+<bitset name="a6x_cp_protect" inline="yes">
+	<bitfield name="BASE_ADDR" low="0" high="17"/>
+	<bitfield name="MASK_LEN" low="18" high="30"/>
+	<bitfield name="READ" pos="31" type="boolean"/>
+</bitset>
+
+<enum name="a6xx_shader_id">
+	<value value="0x9" name="A6XX_TP0_TMO_DATA"/>
+	<value value="0xa" name="A6XX_TP0_SMO_DATA"/>
+	<value value="0xb" name="A6XX_TP0_MIPMAP_BASE_DATA"/>
+	<value value="0x19" name="A6XX_TP1_TMO_DATA"/>
+	<value value="0x1a" name="A6XX_TP1_SMO_DATA"/>
+	<value value="0x1b" name="A6XX_TP1_MIPMAP_BASE_DATA"/>
+	<value value="0x29" name="A6XX_SP_INST_DATA"/>
+	<value value="0x2a" name="A6XX_SP_LB_0_DATA"/>
+	<value value="0x2b" name="A6XX_SP_LB_1_DATA"/>
+	<value value="0x2c" name="A6XX_SP_LB_2_DATA"/>
+	<value value="0x2d" name="A6XX_SP_LB_3_DATA"/>
+	<value value="0x2e" name="A6XX_SP_LB_4_DATA"/>
+	<value value="0x2f" name="A6XX_SP_LB_5_DATA"/>
+	<value value="0x30" name="A6XX_SP_CB_BINDLESS_DATA"/>
+	<value value="0x31" name="A6XX_SP_CB_LEGACY_DATA"/>
+	<value value="0x32" name="A6XX_SP_UAV_DATA"/>
+	<value value="0x33" name="A6XX_SP_INST_TAG"/>
+	<value value="0x34" name="A6XX_SP_CB_BINDLESS_TAG"/>
+	<value value="0x35" name="A6XX_SP_TMO_UMO_TAG"/>
+	<value value="0x36" name="A6XX_SP_SMO_TAG"/>
+	<value value="0x37" name="A6XX_SP_STATE_DATA"/>
+	<value value="0x49" name="A6XX_HLSQ_CHUNK_CVS_RAM"/>
+	<value value="0x4a" name="A6XX_HLSQ_CHUNK_CPS_RAM"/>
+	<value value="0x4b" name="A6XX_HLSQ_CHUNK_CVS_RAM_TAG"/>
+	<value value="0x4c" name="A6XX_HLSQ_CHUNK_CPS_RAM_TAG"/>
+	<value value="0x4d" name="A6XX_HLSQ_ICB_CVS_CB_BASE_TAG"/>
+	<value value="0x4e" name="A6XX_HLSQ_ICB_CPS_CB_BASE_TAG"/>
+	<value value="0x50" name="A6XX_HLSQ_CVS_MISC_RAM"/>
+	<value value="0x51" name="A6XX_HLSQ_CPS_MISC_RAM"/>
+	<value value="0x52" name="A6XX_HLSQ_INST_RAM"/>
+	<value value="0x53" name="A6XX_HLSQ_GFX_CVS_CONST_RAM"/>
+	<value value="0x54" name="A6XX_HLSQ_GFX_CPS_CONST_RAM"/>
+	<value value="0x55" name="A6XX_HLSQ_CVS_MISC_RAM_TAG"/>
+	<value value="0x56" name="A6XX_HLSQ_CPS_MISC_RAM_TAG"/>
+	<value value="0x57" name="A6XX_HLSQ_INST_RAM_TAG"/>
+	<value value="0x58" name="A6XX_HLSQ_GFX_CVS_CONST_RAM_TAG"/>
+	<value value="0x59" name="A6XX_HLSQ_GFX_CPS_CONST_RAM_TAG"/>
+	<value value="0x5a" name="A6XX_HLSQ_PWR_REST_RAM"/>
+	<value value="0x5b" name="A6XX_HLSQ_PWR_REST_TAG"/>
+	<value value="0x60" name="A6XX_HLSQ_DATAPATH_META"/>
+	<value value="0x61" name="A6XX_HLSQ_FRONTEND_META"/>
+	<value value="0x62" name="A6XX_HLSQ_INDIRECT_META"/>
+	<value value="0x63" name="A6XX_HLSQ_BACKEND_META"/>
+	<value value="0x70" name="A6XX_SP_LB_6_DATA"/>
+	<value value="0x71" name="A6XX_SP_LB_7_DATA"/>
+	<value value="0x73" name="A6XX_HLSQ_INST_RAM_1"/>
+</enum>
+
+<enum name="a7xx_statetype_id">
+	<value value="0" name="A7XX_TP0_NCTX_REG"/>
+	<value value="1" name="A7XX_TP0_CTX0_3D_CVS_REG"/>
+	<value value="2" name="A7XX_TP0_CTX0_3D_CPS_REG"/>
+	<value value="3" name="A7XX_TP0_CTX1_3D_CVS_REG"/>
+	<value value="4" name="A7XX_TP0_CTX1_3D_CPS_REG"/>
+	<value value="5" name="A7XX_TP0_CTX2_3D_CPS_REG"/>
+	<value value="6" name="A7XX_TP0_CTX3_3D_CPS_REG"/>
+	<value value="9" name="A7XX_TP0_TMO_DATA"/>
+	<value value="10" name="A7XX_TP0_SMO_DATA"/>
+	<value value="11" name="A7XX_TP0_MIPMAP_BASE_DATA"/>
+	<value value="32" name="A7XX_SP_NCTX_REG"/>
+	<value value="33" name="A7XX_SP_CTX0_3D_CVS_REG"/>
+	<value value="34" name="A7XX_SP_CTX0_3D_CPS_REG"/>
+	<value value="35" name="A7XX_SP_CTX1_3D_CVS_REG"/>
+	<value value="36" name="A7XX_SP_CTX1_3D_CPS_REG"/>
+	<value value="37" name="A7XX_SP_CTX2_3D_CPS_REG"/>
+	<value value="38" name="A7XX_SP_CTX3_3D_CPS_REG"/>
+	<value value="39" name="A7XX_SP_INST_DATA"/>
+	<value value="40" name="A7XX_SP_INST_DATA_1"/>
+	<value value="41" name="A7XX_SP_LB_0_DATA"/>
+	<value value="42" name="A7XX_SP_LB_1_DATA"/>
+	<value value="43" name="A7XX_SP_LB_2_DATA"/>
+	<value value="44" name="A7XX_SP_LB_3_DATA"/>
+	<value value="45" name="A7XX_SP_LB_4_DATA"/>
+	<value value="46" name="A7XX_SP_LB_5_DATA"/>
+	<value value="47" name="A7XX_SP_LB_6_DATA"/>
+	<value value="48" name="A7XX_SP_LB_7_DATA"/>
+	<value value="49" name="A7XX_SP_CB_RAM"/>
+	<value value="50" name="A7XX_SP_LB_13_DATA"/>
+	<value value="51" name="A7XX_SP_LB_14_DATA"/>
+	<value value="52" name="A7XX_SP_INST_TAG"/>
+	<value value="53" name="A7XX_SP_INST_DATA_2"/>
+	<value value="54" name="A7XX_SP_TMO_TAG"/>
+	<value value="55" name="A7XX_SP_SMO_TAG"/>
+	<value value="56" name="A7XX_SP_STATE_DATA"/>
+	<value value="57" name="A7XX_SP_HWAVE_RAM"/>
+	<value value="58" name="A7XX_SP_L0_INST_BUF"/>
+	<value value="59" name="A7XX_SP_LB_8_DATA"/>
+	<value value="60" name="A7XX_SP_LB_9_DATA"/>
+	<value value="61" name="A7XX_SP_LB_10_DATA"/>
+	<value value="62" name="A7XX_SP_LB_11_DATA"/>
+	<value value="63" name="A7XX_SP_LB_12_DATA"/>
+	<value value="64" name="A7XX_HLSQ_DATAPATH_DSTR_META"/>
+	<value value="67" name="A7XX_HLSQ_L2STC_TAG_RAM"/>
+	<value value="68" name="A7XX_HLSQ_L2STC_INFO_CMD"/>
+	<value value="69" name="A7XX_HLSQ_CVS_BE_CTXT_BUF_RAM_TAG"/>
+	<value value="70" name="A7XX_HLSQ_CPS_BE_CTXT_BUF_RAM_TAG"/>
+	<value value="71" name="A7XX_HLSQ_GFX_CVS_BE_CTXT_BUF_RAM"/>
+	<value value="72" name="A7XX_HLSQ_GFX_CPS_BE_CTXT_BUF_RAM"/>
+	<value value="73" name="A7XX_HLSQ_CHUNK_CVS_RAM"/>
+	<value value="74" name="A7XX_HLSQ_CHUNK_CPS_RAM"/>
+	<value value="75" name="A7XX_HLSQ_CHUNK_CVS_RAM_TAG"/>
+	<value value="76" name="A7XX_HLSQ_CHUNK_CPS_RAM_TAG"/>
+	<value value="77" name="A7XX_HLSQ_ICB_CVS_CB_BASE_TAG"/>
+	<value value="78" name="A7XX_HLSQ_ICB_CPS_CB_BASE_TAG"/>
+	<value value="79" name="A7XX_HLSQ_CVS_MISC_RAM"/>
+	<value value="80" name="A7XX_HLSQ_CPS_MISC_RAM"/>
+	<value value="81" name="A7XX_HLSQ_CPS_MISC_RAM_1"/>
+	<value value="82" name="A7XX_HLSQ_INST_RAM"/>
+	<value value="83" name="A7XX_HLSQ_GFX_CVS_CONST_RAM"/>
+	<value value="84" name="A7XX_HLSQ_GFX_CPS_CONST_RAM"/>
+	<value value="85" name="A7XX_HLSQ_CVS_MISC_RAM_TAG"/>
+	<value value="86" name="A7XX_HLSQ_CPS_MISC_RAM_TAG"/>
+	<value value="87" name="A7XX_HLSQ_INST_RAM_TAG"/>
+	<value value="88" name="A7XX_HLSQ_GFX_CVS_CONST_RAM_TAG"/>
+	<value value="89" name="A7XX_HLSQ_GFX_CPS_CONST_RAM_TAG"/>
+	<value value="90" name="A7XX_HLSQ_GFX_LOCAL_MISC_RAM"/>
+	<value value="91" name="A7XX_HLSQ_GFX_LOCAL_MISC_RAM_TAG"/>
+	<value value="92" name="A7XX_HLSQ_INST_RAM_1"/>
+	<value value="93" name="A7XX_HLSQ_STPROC_META"/>
+	<value value="94" name="A7XX_HLSQ_BV_BE_META"/>
+	<value value="95" name="A7XX_HLSQ_INST_RAM_2"/>
+	<value value="96" name="A7XX_HLSQ_DATAPATH_META"/>
+	<value value="97" name="A7XX_HLSQ_FRONTEND_META"/>
+	<value value="98" name="A7XX_HLSQ_INDIRECT_META"/>
+	<value value="99" name="A7XX_HLSQ_BACKEND_META"/>
+</enum>
+
+<enum name="a6xx_debugbus_id">
+	<value value="0x1" name="A6XX_DBGBUS_CP"/>
+	<value value="0x2" name="A6XX_DBGBUS_RBBM"/>
+	<value value="0x3" name="A6XX_DBGBUS_VBIF"/>
+	<value value="0x4" name="A6XX_DBGBUS_HLSQ"/>
+	<value value="0x5" name="A6XX_DBGBUS_UCHE"/>
+	<value value="0x6" name="A6XX_DBGBUS_DPM"/>
+	<value value="0x7" name="A6XX_DBGBUS_TESS"/>
+	<value value="0x8" name="A6XX_DBGBUS_PC"/>
+	<value value="0x9" name="A6XX_DBGBUS_VFDP"/>
+	<value value="0xa" name="A6XX_DBGBUS_VPC"/>
+	<value value="0xb" name="A6XX_DBGBUS_TSE"/>
+	<value value="0xc" name="A6XX_DBGBUS_RAS"/>
+	<value value="0xd" name="A6XX_DBGBUS_VSC"/>
+	<value value="0xe" name="A6XX_DBGBUS_COM"/>
+	<value value="0x10" name="A6XX_DBGBUS_LRZ"/>
+	<value value="0x11" name="A6XX_DBGBUS_A2D"/>
+	<value value="0x12" name="A6XX_DBGBUS_CCUFCHE"/>
+	<value value="0x13" name="A6XX_DBGBUS_GMU_CX"/>
+	<value value="0x14" name="A6XX_DBGBUS_RBP"/>
+	<value value="0x15" name="A6XX_DBGBUS_DCS"/>
+	<value value="0x16" name="A6XX_DBGBUS_DBGC"/>
+	<value value="0x17" name="A6XX_DBGBUS_CX"/>
+	<value value="0x18" name="A6XX_DBGBUS_GMU_GX"/>
+	<value value="0x19" name="A6XX_DBGBUS_TPFCHE"/>
+	<value value="0x1a" name="A6XX_DBGBUS_GBIF_GX"/>
+	<value value="0x1d" name="A6XX_DBGBUS_GPC"/>
+	<value value="0x1e" name="A6XX_DBGBUS_LARC"/>
+	<value value="0x1f" name="A6XX_DBGBUS_HLSQ_SPTP"/>
+	<value value="0x20" name="A6XX_DBGBUS_RB_0"/>
+	<value value="0x21" name="A6XX_DBGBUS_RB_1"/>
+	<value value="0x22" name="A6XX_DBGBUS_RB_2"/>
+	<value value="0x24" name="A6XX_DBGBUS_UCHE_WRAPPER"/>
+	<value value="0x28" name="A6XX_DBGBUS_CCU_0"/>
+	<value value="0x29" name="A6XX_DBGBUS_CCU_1"/>
+	<value value="0x2a" name="A6XX_DBGBUS_CCU_2"/>
+	<value value="0x38" name="A6XX_DBGBUS_VFD_0"/>
+	<value value="0x39" name="A6XX_DBGBUS_VFD_1"/>
+	<value value="0x3a" name="A6XX_DBGBUS_VFD_2"/>
+	<value value="0x3b" name="A6XX_DBGBUS_VFD_3"/>
+	<value value="0x3c" name="A6XX_DBGBUS_VFD_4"/>
+	<value value="0x3d" name="A6XX_DBGBUS_VFD_5"/>
+	<value value="0x40" name="A6XX_DBGBUS_SP_0"/>
+	<value value="0x41" name="A6XX_DBGBUS_SP_1"/>
+	<value value="0x42" name="A6XX_DBGBUS_SP_2"/>
+	<value value="0x48" name="A6XX_DBGBUS_TPL1_0"/>
+	<value value="0x49" name="A6XX_DBGBUS_TPL1_1"/>
+	<value value="0x4a" name="A6XX_DBGBUS_TPL1_2"/>
+	<value value="0x4b" name="A6XX_DBGBUS_TPL1_3"/>
+	<value value="0x4c" name="A6XX_DBGBUS_TPL1_4"/>
+	<value value="0x4d" name="A6XX_DBGBUS_TPL1_5"/>
+	<value value="0x58" name="A6XX_DBGBUS_SPTP_0"/>
+	<value value="0x59" name="A6XX_DBGBUS_SPTP_1"/>
+	<value value="0x5a" name="A6XX_DBGBUS_SPTP_2"/>
+	<value value="0x5b" name="A6XX_DBGBUS_SPTP_3"/>
+	<value value="0x5c" name="A6XX_DBGBUS_SPTP_4"/>
+	<value value="0x5d" name="A6XX_DBGBUS_SPTP_5"/>
+</enum>
+
+<enum name="a7xx_state_location">
+	<value value="0" name="A7XX_HLSQ_STATE"/>
+	<value value="1" name="A7XX_HLSQ_DP"/>
+	<value value="2" name="A7XX_SP_TOP"/>
+	<value value="3" name="A7XX_USPTP"/>
+	<value value="4" name="A7XX_HLSQ_DP_STR"/>
+</enum>
+
+<enum name="a7xx_pipe">
+	<value value="0" name="A7XX_PIPE_NONE"/>
+	<value value="1" name="A7XX_PIPE_BR"/>
+	<value value="2" name="A7XX_PIPE_BV"/>
+	<value value="3" name="A7XX_PIPE_LPAC"/>
+</enum>
+
+<enum name="a7xx_cluster">
+	<value value="0" name="A7XX_CLUSTER_NONE"/>
+	<value value="1" name="A7XX_CLUSTER_FE"/>
+	<value value="2" name="A7XX_CLUSTER_SP_VS"/>
+	<value value="3" name="A7XX_CLUSTER_PC_VS"/>
+	<value value="4" name="A7XX_CLUSTER_GRAS"/>
+	<value value="5" name="A7XX_CLUSTER_SP_PS"/>
+	<value value="6" name="A7XX_CLUSTER_VPC_PS"/>
+	<value value="7" name="A7XX_CLUSTER_PS"/>
+</enum>
+
+<enum name="a7xx_debugbus_id">
+	<value value="1" name="A7XX_DBGBUS_CP_0_0"/>
+	<value value="2" name="A7XX_DBGBUS_CP_0_1"/>
+	<value value="3" name="A7XX_DBGBUS_RBBM"/>
+	<value value="5" name="A7XX_DBGBUS_GBIF_GX"/>
+	<value value="6" name="A7XX_DBGBUS_GBIF_CX"/>
+	<value value="7" name="A7XX_DBGBUS_HLSQ"/>
+	<value value="9" name="A7XX_DBGBUS_UCHE_0"/>
+	<value value="10" name="A7XX_DBGBUS_UCHE_1"/>
+	<value value="13" name="A7XX_DBGBUS_TESS_BR"/>
+	<value value="14" name="A7XX_DBGBUS_TESS_BV"/>
+	<value value="17" name="A7XX_DBGBUS_PC_BR"/>
+	<value value="18" name="A7XX_DBGBUS_PC_BV"/>
+	<value value="21" name="A7XX_DBGBUS_VFDP_BR"/>
+	<value value="22" name="A7XX_DBGBUS_VFDP_BV"/>
+	<value value="25" name="A7XX_DBGBUS_VPC_BR"/>
+	<value value="26" name="A7XX_DBGBUS_VPC_BV"/>
+	<value value="29" name="A7XX_DBGBUS_TSE_BR"/>
+	<value value="30" name="A7XX_DBGBUS_TSE_BV"/>
+	<value value="33" name="A7XX_DBGBUS_RAS_BR"/>
+	<value value="34" name="A7XX_DBGBUS_RAS_BV"/>
+	<value value="37" name="A7XX_DBGBUS_VSC"/>
+	<value value="39" name="A7XX_DBGBUS_COM_0"/>
+	<value value="43" name="A7XX_DBGBUS_LRZ_BR"/>
+	<value value="44" name="A7XX_DBGBUS_LRZ_BV"/>
+	<value value="47" name="A7XX_DBGBUS_UFC_0"/>
+	<value value="48" name="A7XX_DBGBUS_UFC_1"/>
+	<value value="55" name="A7XX_DBGBUS_GMU_GX"/>
+	<value value="59" name="A7XX_DBGBUS_DBGC"/>
+	<value value="60" name="A7XX_DBGBUS_CX"/>
+	<value value="61" name="A7XX_DBGBUS_GMU_CX"/>
+	<value value="62" name="A7XX_DBGBUS_GPC_BR"/>
+	<value value="63" name="A7XX_DBGBUS_GPC_BV"/>
+	<value value="66" name="A7XX_DBGBUS_LARC"/>
+	<value value="68" name="A7XX_DBGBUS_HLSQ_SPTP"/>
+	<value value="70" name="A7XX_DBGBUS_RB_0"/>
+	<value value="71" name="A7XX_DBGBUS_RB_1"/>
+	<value value="72" name="A7XX_DBGBUS_RB_2"/>
+	<value value="73" name="A7XX_DBGBUS_RB_3"/>
+	<value value="74" name="A7XX_DBGBUS_RB_4"/>
+	<value value="75" name="A7XX_DBGBUS_RB_5"/>
+	<value value="102" name="A7XX_DBGBUS_UCHE_WRAPPER"/>
+	<value value="106" name="A7XX_DBGBUS_CCU_0"/>
+	<value value="107" name="A7XX_DBGBUS_CCU_1"/>
+	<value value="108" name="A7XX_DBGBUS_CCU_2"/>
+	<value value="109" name="A7XX_DBGBUS_CCU_3"/>
+	<value value="110" name="A7XX_DBGBUS_CCU_4"/>
+	<value value="111" name="A7XX_DBGBUS_CCU_5"/>
+	<value value="138" name="A7XX_DBGBUS_VFD_BR_0"/>
+	<value value="139" name="A7XX_DBGBUS_VFD_BR_1"/>
+	<value value="140" name="A7XX_DBGBUS_VFD_BR_2"/>
+	<value value="141" name="A7XX_DBGBUS_VFD_BR_3"/>
+	<value value="142" name="A7XX_DBGBUS_VFD_BR_4"/>
+	<value value="143" name="A7XX_DBGBUS_VFD_BR_5"/>
+	<value value="144" name="A7XX_DBGBUS_VFD_BR_6"/>
+	<value value="145" name="A7XX_DBGBUS_VFD_BR_7"/>
+	<value value="202" name="A7XX_DBGBUS_VFD_BV_0"/>
+	<value value="203" name="A7XX_DBGBUS_VFD_BV_1"/>
+	<value value="204" name="A7XX_DBGBUS_VFD_BV_2"/>
+	<value value="205" name="A7XX_DBGBUS_VFD_BV_3"/>
+	<value value="234" name="A7XX_DBGBUS_USP_0"/>
+	<value value="235" name="A7XX_DBGBUS_USP_1"/>
+	<value value="236" name="A7XX_DBGBUS_USP_2"/>
+	<value value="237" name="A7XX_DBGBUS_USP_3"/>
+	<value value="238" name="A7XX_DBGBUS_USP_4"/>
+	<value value="239" name="A7XX_DBGBUS_USP_5"/>
+	<value value="266" name="A7XX_DBGBUS_TP_0"/>
+	<value value="267" name="A7XX_DBGBUS_TP_1"/>
+	<value value="268" name="A7XX_DBGBUS_TP_2"/>
+	<value value="269" name="A7XX_DBGBUS_TP_3"/>
+	<value value="270" name="A7XX_DBGBUS_TP_4"/>
+	<value value="271" name="A7XX_DBGBUS_TP_5"/>
+	<value value="272" name="A7XX_DBGBUS_TP_6"/>
+	<value value="273" name="A7XX_DBGBUS_TP_7"/>
+	<value value="274" name="A7XX_DBGBUS_TP_8"/>
+	<value value="275" name="A7XX_DBGBUS_TP_9"/>
+	<value value="276" name="A7XX_DBGBUS_TP_10"/>
+	<value value="277" name="A7XX_DBGBUS_TP_11"/>
+	<value value="330" name="A7XX_DBGBUS_USPTP_0"/>
+	<value value="331" name="A7XX_DBGBUS_USPTP_1"/>
+	<value value="332" name="A7XX_DBGBUS_USPTP_2"/>
+	<value value="333" name="A7XX_DBGBUS_USPTP_3"/>
+	<value value="334" name="A7XX_DBGBUS_USPTP_4"/>
+	<value value="335" name="A7XX_DBGBUS_USPTP_5"/>
+	<value value="336" name="A7XX_DBGBUS_USPTP_6"/>
+	<value value="337" name="A7XX_DBGBUS_USPTP_7"/>
+	<value value="338" name="A7XX_DBGBUS_USPTP_8"/>
+	<value value="339" name="A7XX_DBGBUS_USPTP_9"/>
+	<value value="340" name="A7XX_DBGBUS_USPTP_10"/>
+	<value value="341" name="A7XX_DBGBUS_USPTP_11"/>
+	<value value="396" name="A7XX_DBGBUS_CCHE_0"/>
+	<value value="397" name="A7XX_DBGBUS_CCHE_1"/>
+	<value value="398" name="A7XX_DBGBUS_CCHE_2"/>
+	<value value="408" name="A7XX_DBGBUS_VPC_DSTR_0"/>
+	<value value="409" name="A7XX_DBGBUS_VPC_DSTR_1"/>
+	<value value="410" name="A7XX_DBGBUS_VPC_DSTR_2"/>
+	<value value="411" name="A7XX_DBGBUS_HLSQ_DP_STR_0"/>
+	<value value="412" name="A7XX_DBGBUS_HLSQ_DP_STR_1"/>
+	<value value="413" name="A7XX_DBGBUS_HLSQ_DP_STR_2"/>
+	<value value="414" name="A7XX_DBGBUS_HLSQ_DP_STR_3"/>
+	<value value="415" name="A7XX_DBGBUS_HLSQ_DP_STR_4"/>
+	<value value="416" name="A7XX_DBGBUS_HLSQ_DP_STR_5"/>
+	<value value="443" name="A7XX_DBGBUS_UFC_DSTR_0"/>
+	<value value="444" name="A7XX_DBGBUS_UFC_DSTR_1"/>
+	<value value="445" name="A7XX_DBGBUS_UFC_DSTR_2"/>
+	<value value="446" name="A7XX_DBGBUS_CGC_SUBCORE"/>
+	<value value="447" name="A7XX_DBGBUS_CGC_CORE"/>
+</enum>
+
+<enum name="a6xx_cp_perfcounter_select">
+	<value value="0" name="PERF_CP_ALWAYS_COUNT"/>
+	<value value="1" name="PERF_CP_BUSY_GFX_CORE_IDLE"/>
+	<value value="2" name="PERF_CP_BUSY_CYCLES"/>
+	<value value="3" name="PERF_CP_NUM_PREEMPTIONS"/>
+	<value value="4" name="PERF_CP_PREEMPTION_REACTION_DELAY"/>
+	<value value="5" name="PERF_CP_PREEMPTION_SWITCH_OUT_TIME"/>
+	<value value="6" name="PERF_CP_PREEMPTION_SWITCH_IN_TIME"/>
+	<value value="7" name="PERF_CP_DEAD_DRAWS_IN_BIN_RENDER"/>
+	<value value="8" name="PERF_CP_PREDICATED_DRAWS_KILLED"/>
+	<value value="9" name="PERF_CP_MODE_SWITCH"/>
+	<value value="10" name="PERF_CP_ZPASS_DONE"/>
+	<value value="11" name="PERF_CP_CONTEXT_DONE"/>
+	<value value="12" name="PERF_CP_CACHE_FLUSH"/>
+	<value value="13" name="PERF_CP_LONG_PREEMPTIONS"/>
+	<value value="14" name="PERF_CP_SQE_I_CACHE_STARVE"/>
+	<value value="15" name="PERF_CP_SQE_IDLE"/>
+	<value value="16" name="PERF_CP_SQE_PM4_STARVE_RB_IB"/>
+	<value value="17" name="PERF_CP_SQE_PM4_STARVE_SDS"/>
+	<value value="18" name="PERF_CP_SQE_MRB_STARVE"/>
+	<value value="19" name="PERF_CP_SQE_RRB_STARVE"/>
+	<value value="20" name="PERF_CP_SQE_VSD_STARVE"/>
+	<value value="21" name="PERF_CP_VSD_DECODE_STARVE"/>
+	<value value="22" name="PERF_CP_SQE_PIPE_OUT_STALL"/>
+	<value value="23" name="PERF_CP_SQE_SYNC_STALL"/>
+	<value value="24" name="PERF_CP_SQE_PM4_WFI_STALL"/>
+	<value value="25" name="PERF_CP_SQE_SYS_WFI_STALL"/>
+	<value value="26" name="PERF_CP_SQE_T4_EXEC"/>
+	<value value="27" name="PERF_CP_SQE_LOAD_STATE_EXEC"/>
+	<value value="28" name="PERF_CP_SQE_SAVE_SDS_STATE"/>
+	<value value="29" name="PERF_CP_SQE_DRAW_EXEC"/>
+	<value value="30" name="PERF_CP_SQE_CTXT_REG_BUNCH_EXEC"/>
+	<value value="31" name="PERF_CP_SQE_EXEC_PROFILED"/>
+	<value value="32" name="PERF_CP_MEMORY_POOL_EMPTY"/>
+	<value value="33" name="PERF_CP_MEMORY_POOL_SYNC_STALL"/>
+	<value value="34" name="PERF_CP_MEMORY_POOL_ABOVE_THRESH"/>
+	<value value="35" name="PERF_CP_AHB_WR_STALL_PRE_DRAWS"/>
+	<value value="36" name="PERF_CP_AHB_STALL_SQE_GMU"/>
+	<value value="37" name="PERF_CP_AHB_STALL_SQE_WR_OTHER"/>
+	<value value="38" name="PERF_CP_AHB_STALL_SQE_RD_OTHER"/>
+	<value value="39" name="PERF_CP_CLUSTER0_EMPTY"/>
+	<value value="40" name="PERF_CP_CLUSTER1_EMPTY"/>
+	<value value="41" name="PERF_CP_CLUSTER2_EMPTY"/>
+	<value value="42" name="PERF_CP_CLUSTER3_EMPTY"/>
+	<value value="43" name="PERF_CP_CLUSTER4_EMPTY"/>
+	<value value="44" name="PERF_CP_CLUSTER5_EMPTY"/>
+	<value value="45" name="PERF_CP_PM4_DATA"/>
+	<value value="46" name="PERF_CP_PM4_HEADERS"/>
+	<value value="47" name="PERF_CP_VBIF_READ_BEATS"/>
+	<value value="48" name="PERF_CP_VBIF_WRITE_BEATS"/>
+	<value value="49" name="PERF_CP_SQE_INSTR_COUNTER"/>
+</enum>
+
+<enum name="a6xx_rbbm_perfcounter_select">
+	<value value="0" name="PERF_RBBM_ALWAYS_COUNT"/>
+	<value value="1" name="PERF_RBBM_ALWAYS_ON"/>
+	<value value="2" name="PERF_RBBM_TSE_BUSY"/>
+	<value value="3" name="PERF_RBBM_RAS_BUSY"/>
+	<value value="4" name="PERF_RBBM_PC_DCALL_BUSY"/>
+	<value value="5" name="PERF_RBBM_PC_VSD_BUSY"/>
+	<value value="6" name="PERF_RBBM_STATUS_MASKED"/>
+	<value value="7" name="PERF_RBBM_COM_BUSY"/>
+	<value value="8" name="PERF_RBBM_DCOM_BUSY"/>
+	<value value="9" name="PERF_RBBM_VBIF_BUSY"/>
+	<value value="10" name="PERF_RBBM_VSC_BUSY"/>
+	<value value="11" name="PERF_RBBM_TESS_BUSY"/>
+	<value value="12" name="PERF_RBBM_UCHE_BUSY"/>
+	<value value="13" name="PERF_RBBM_HLSQ_BUSY"/>
+</enum>
+
+<enum name="a6xx_pc_perfcounter_select">
+	<value value="0" name="PERF_PC_BUSY_CYCLES"/>
+	<value value="1" name="PERF_PC_WORKING_CYCLES"/>
+	<value value="2" name="PERF_PC_STALL_CYCLES_VFD"/>
+	<value value="3" name="PERF_PC_STALL_CYCLES_TSE"/>
+	<value value="4" name="PERF_PC_STALL_CYCLES_VPC"/>
+	<value value="5" name="PERF_PC_STALL_CYCLES_UCHE"/>
+	<value value="6" name="PERF_PC_STALL_CYCLES_TESS"/>
+	<value value="7" name="PERF_PC_STALL_CYCLES_TSE_ONLY"/>
+	<value value="8" name="PERF_PC_STALL_CYCLES_VPC_ONLY"/>
+	<value value="9" name="PERF_PC_PASS1_TF_STALL_CYCLES"/>
+	<value value="10" name="PERF_PC_STARVE_CYCLES_FOR_INDEX"/>
+	<value value="11" name="PERF_PC_STARVE_CYCLES_FOR_TESS_FACTOR"/>
+	<value value="12" name="PERF_PC_STARVE_CYCLES_FOR_VIZ_STREAM"/>
+	<value value="13" name="PERF_PC_STARVE_CYCLES_FOR_POSITION"/>
+	<value value="14" name="PERF_PC_STARVE_CYCLES_DI"/>
+	<value value="15" name="PERF_PC_VIS_STREAMS_LOADED"/>
+	<value value="16" name="PERF_PC_INSTANCES"/>
+	<value value="17" name="PERF_PC_VPC_PRIMITIVES"/>
+	<value value="18" name="PERF_PC_DEAD_PRIM"/>
+	<value value="19" name="PERF_PC_LIVE_PRIM"/>
+	<value value="20" name="PERF_PC_VERTEX_HITS"/>
+	<value value="21" name="PERF_PC_IA_VERTICES"/>
+	<value value="22" name="PERF_PC_IA_PRIMITIVES"/>
+	<value value="23" name="PERF_PC_GS_PRIMITIVES"/>
+	<value value="24" name="PERF_PC_HS_INVOCATIONS"/>
+	<value value="25" name="PERF_PC_DS_INVOCATIONS"/>
+	<value value="26" name="PERF_PC_VS_INVOCATIONS"/>
+	<value value="27" name="PERF_PC_GS_INVOCATIONS"/>
+	<value value="28" name="PERF_PC_DS_PRIMITIVES"/>
+	<value value="29" name="PERF_PC_VPC_POS_DATA_TRANSACTION"/>
+	<value value="30" name="PERF_PC_3D_DRAWCALLS"/>
+	<value value="31" name="PERF_PC_2D_DRAWCALLS"/>
+	<value value="32" name="PERF_PC_NON_DRAWCALL_GLOBAL_EVENTS"/>
+	<value value="33" name="PERF_TESS_BUSY_CYCLES"/>
+	<value value="34" name="PERF_TESS_WORKING_CYCLES"/>
+	<value value="35" name="PERF_TESS_STALL_CYCLES_PC"/>
+	<value value="36" name="PERF_TESS_STARVE_CYCLES_PC"/>
+	<value value="37" name="PERF_PC_TSE_TRANSACTION"/>
+	<value value="38" name="PERF_PC_TSE_VERTEX"/>
+	<value value="39" name="PERF_PC_TESS_PC_UV_TRANS"/>
+	<value value="40" name="PERF_PC_TESS_PC_UV_PATCHES"/>
+	<value value="41" name="PERF_PC_TESS_FACTOR_TRANS"/>
+</enum>
+
+<enum name="a6xx_vfd_perfcounter_select">
+	<value value="0" name="PERF_VFD_BUSY_CYCLES"/>
+	<value value="1" name="PERF_VFD_STALL_CYCLES_UCHE"/>
+	<value value="2" name="PERF_VFD_STALL_CYCLES_VPC_ALLOC"/>
+	<value value="3" name="PERF_VFD_STALL_CYCLES_SP_INFO"/>
+	<value value="4" name="PERF_VFD_STALL_CYCLES_SP_ATTR"/>
+	<value value="5" name="PERF_VFD_STARVE_CYCLES_UCHE"/>
+	<value value="6" name="PERF_VFD_RBUFFER_FULL"/>
+	<value value="7" name="PERF_VFD_ATTR_INFO_FIFO_FULL"/>
+	<value value="8" name="PERF_VFD_DECODED_ATTRIBUTE_BYTES"/>
+	<value value="9" name="PERF_VFD_NUM_ATTRIBUTES"/>
+	<value value="10" name="PERF_VFD_UPPER_SHADER_FIBERS"/>
+	<value value="11" name="PERF_VFD_LOWER_SHADER_FIBERS"/>
+	<value value="12" name="PERF_VFD_MODE_0_FIBERS"/>
+	<value value="13" name="PERF_VFD_MODE_1_FIBERS"/>
+	<value value="14" name="PERF_VFD_MODE_2_FIBERS"/>
+	<value value="15" name="PERF_VFD_MODE_3_FIBERS"/>
+	<value value="16" name="PERF_VFD_MODE_4_FIBERS"/>
+	<value value="17" name="PERF_VFD_TOTAL_VERTICES"/>
+	<value value="18" name="PERF_VFDP_STALL_CYCLES_VFD"/>
+	<value value="19" name="PERF_VFDP_STALL_CYCLES_VFD_INDEX"/>
+	<value value="20" name="PERF_VFDP_STALL_CYCLES_VFD_PROG"/>
+	<value value="21" name="PERF_VFDP_STARVE_CYCLES_PC"/>
+	<value value="22" name="PERF_VFDP_VS_STAGE_WAVES"/>
+</enum>
+
+<enum name="a6xx_hlsq_perfcounter_select">
+	<value value="0" name="PERF_HLSQ_BUSY_CYCLES"/>
+	<value value="1" name="PERF_HLSQ_STALL_CYCLES_UCHE"/>
+	<value value="2" name="PERF_HLSQ_STALL_CYCLES_SP_STATE"/>
+	<value value="3" name="PERF_HLSQ_STALL_CYCLES_SP_FS_STAGE"/>
+	<value value="4" name="PERF_HLSQ_UCHE_LATENCY_CYCLES"/>
+	<value value="5" name="PERF_HLSQ_UCHE_LATENCY_COUNT"/>
+	<value value="6" name="PERF_HLSQ_FS_STAGE_1X_WAVES"/>
+	<value value="7" name="PERF_HLSQ_FS_STAGE_2X_WAVES"/>
+	<value value="8" name="PERF_HLSQ_QUADS"/>
+	<value value="9" name="PERF_HLSQ_CS_INVOCATIONS"/>
+	<value value="10" name="PERF_HLSQ_COMPUTE_DRAWCALLS"/>
+	<value value="11" name="PERF_HLSQ_FS_DATA_WAIT_PROGRAMMING"/>
+	<value value="12" name="PERF_HLSQ_DUAL_FS_PROG_ACTIVE"/>
+	<value value="13" name="PERF_HLSQ_DUAL_VS_PROG_ACTIVE"/>
+	<value value="14" name="PERF_HLSQ_FS_BATCH_COUNT_ZERO"/>
+	<value value="15" name="PERF_HLSQ_VS_BATCH_COUNT_ZERO"/>
+	<value value="16" name="PERF_HLSQ_WAVE_PENDING_NO_QUAD"/>
+	<value value="17" name="PERF_HLSQ_WAVE_PENDING_NO_PRIM_BASE"/>
+	<value value="18" name="PERF_HLSQ_STALL_CYCLES_VPC"/>
+	<value value="19" name="PERF_HLSQ_PIXELS"/>
+	<value value="20" name="PERF_HLSQ_DRAW_MODE_SWITCH_VSFS_SYNC"/>
+</enum>
+
+<enum name="a6xx_vpc_perfcounter_select">
+	<value value="0" name="PERF_VPC_BUSY_CYCLES"/>
+	<value value="1" name="PERF_VPC_WORKING_CYCLES"/>
+	<value value="2" name="PERF_VPC_STALL_CYCLES_UCHE"/>
+	<value value="3" name="PERF_VPC_STALL_CYCLES_VFD_WACK"/>
+	<value value="4" name="PERF_VPC_STALL_CYCLES_HLSQ_PRIM_ALLOC"/>
+	<value value="5" name="PERF_VPC_STALL_CYCLES_PC"/>
+	<value value="6" name="PERF_VPC_STALL_CYCLES_SP_LM"/>
+	<value value="7" name="PERF_VPC_STARVE_CYCLES_SP"/>
+	<value value="8" name="PERF_VPC_STARVE_CYCLES_LRZ"/>
+	<value value="9" name="PERF_VPC_PC_PRIMITIVES"/>
+	<value value="10" name="PERF_VPC_SP_COMPONENTS"/>
+	<value value="11" name="PERF_VPC_STALL_CYCLES_VPCRAM_POS"/>
+	<value value="12" name="PERF_VPC_LRZ_ASSIGN_PRIMITIVES"/>
+	<value value="13" name="PERF_VPC_RB_VISIBLE_PRIMITIVES"/>
+	<value value="14" name="PERF_VPC_LM_TRANSACTION"/>
+	<value value="15" name="PERF_VPC_STREAMOUT_TRANSACTION"/>
+	<value value="16" name="PERF_VPC_VS_BUSY_CYCLES"/>
+	<value value="17" name="PERF_VPC_PS_BUSY_CYCLES"/>
+	<value value="18" name="PERF_VPC_VS_WORKING_CYCLES"/>
+	<value value="19" name="PERF_VPC_PS_WORKING_CYCLES"/>
+	<value value="20" name="PERF_VPC_STARVE_CYCLES_RB"/>
+	<value value="21" name="PERF_VPC_NUM_VPCRAM_READ_POS"/>
+	<value value="22" name="PERF_VPC_WIT_FULL_CYCLES"/>
+	<value value="23" name="PERF_VPC_VPCRAM_FULL_CYCLES"/>
+	<value value="24" name="PERF_VPC_LM_FULL_WAIT_FOR_INTP_END"/>
+	<value value="25" name="PERF_VPC_NUM_VPCRAM_WRITE"/>
+	<value value="26" name="PERF_VPC_NUM_VPCRAM_READ_SO"/>
+	<value value="27" name="PERF_VPC_NUM_ATTR_REQ_LM"/>
+</enum>
+
+<enum name="a6xx_tse_perfcounter_select">
+	<value value="0" name="PERF_TSE_BUSY_CYCLES"/>
+	<value value="1" name="PERF_TSE_CLIPPING_CYCLES"/>
+	<value value="2" name="PERF_TSE_STALL_CYCLES_RAS"/>
+	<value value="3" name="PERF_TSE_STALL_CYCLES_LRZ_BARYPLANE"/>
+	<value value="4" name="PERF_TSE_STALL_CYCLES_LRZ_ZPLANE"/>
+	<value value="5" name="PERF_TSE_STARVE_CYCLES_PC"/>
+	<value value="6" name="PERF_TSE_INPUT_PRIM"/>
+	<value value="7" name="PERF_TSE_INPUT_NULL_PRIM"/>
+	<value value="8" name="PERF_TSE_TRIVAL_REJ_PRIM"/>
+	<value value="9" name="PERF_TSE_CLIPPED_PRIM"/>
+	<value value="10" name="PERF_TSE_ZERO_AREA_PRIM"/>
+	<value value="11" name="PERF_TSE_FACENESS_CULLED_PRIM"/>
+	<value value="12" name="PERF_TSE_ZERO_PIXEL_PRIM"/>
+	<value value="13" name="PERF_TSE_OUTPUT_NULL_PRIM"/>
+	<value value="14" name="PERF_TSE_OUTPUT_VISIBLE_PRIM"/>
+	<value value="15" name="PERF_TSE_CINVOCATION"/>
+	<value value="16" name="PERF_TSE_CPRIMITIVES"/>
+	<value value="17" name="PERF_TSE_2D_INPUT_PRIM"/>
+	<value value="18" name="PERF_TSE_2D_ALIVE_CYCLES"/>
+	<value value="19" name="PERF_TSE_CLIP_PLANES"/>
+</enum>
+
+<enum name="a6xx_ras_perfcounter_select">
+	<value value="0" name="PERF_RAS_BUSY_CYCLES"/>
+	<value value="1" name="PERF_RAS_SUPERTILE_ACTIVE_CYCLES"/>
+	<value value="2" name="PERF_RAS_STALL_CYCLES_LRZ"/>
+	<value value="3" name="PERF_RAS_STARVE_CYCLES_TSE"/>
+	<value value="4" name="PERF_RAS_SUPER_TILES"/>
+	<value value="5" name="PERF_RAS_8X4_TILES"/>
+	<value value="6" name="PERF_RAS_MASKGEN_ACTIVE"/>
+	<value value="7" name="PERF_RAS_FULLY_COVERED_SUPER_TILES"/>
+	<value value="8" name="PERF_RAS_FULLY_COVERED_8X4_TILES"/>
+	<value value="9" name="PERF_RAS_PRIM_KILLED_INVISILBE"/>
+	<value value="10" name="PERF_RAS_SUPERTILE_GEN_ACTIVE_CYCLES"/>
+	<value value="11" name="PERF_RAS_LRZ_INTF_WORKING_CYCLES"/>
+	<value value="12" name="PERF_RAS_BLOCKS"/>
+</enum>
+
+<enum name="a6xx_uche_perfcounter_select">
+	<value value="0" name="PERF_UCHE_BUSY_CYCLES"/>
+	<value value="1" name="PERF_UCHE_STALL_CYCLES_ARBITER"/>
+	<value value="2" name="PERF_UCHE_VBIF_LATENCY_CYCLES"/>
+	<value value="3" name="PERF_UCHE_VBIF_LATENCY_SAMPLES"/>
+	<value value="4" name="PERF_UCHE_VBIF_READ_BEATS_TP"/>
+	<value value="5" name="PERF_UCHE_VBIF_READ_BEATS_VFD"/>
+	<value value="6" name="PERF_UCHE_VBIF_READ_BEATS_HLSQ"/>
+	<value value="7" name="PERF_UCHE_VBIF_READ_BEATS_LRZ"/>
+	<value value="8" name="PERF_UCHE_VBIF_READ_BEATS_SP"/>
+	<value value="9" name="PERF_UCHE_READ_REQUESTS_TP"/>
+	<value value="10" name="PERF_UCHE_READ_REQUESTS_VFD"/>
+	<value value="11" name="PERF_UCHE_READ_REQUESTS_HLSQ"/>
+	<value value="12" name="PERF_UCHE_READ_REQUESTS_LRZ"/>
+	<value value="13" name="PERF_UCHE_READ_REQUESTS_SP"/>
+	<value value="14" name="PERF_UCHE_WRITE_REQUESTS_LRZ"/>
+	<value value="15" name="PERF_UCHE_WRITE_REQUESTS_SP"/>
+	<value value="16" name="PERF_UCHE_WRITE_REQUESTS_VPC"/>
+	<value value="17" name="PERF_UCHE_WRITE_REQUESTS_VSC"/>
+	<value value="18" name="PERF_UCHE_EVICTS"/>
+	<value value="19" name="PERF_UCHE_BANK_REQ0"/>
+	<value value="20" name="PERF_UCHE_BANK_REQ1"/>
+	<value value="21" name="PERF_UCHE_BANK_REQ2"/>
+	<value value="22" name="PERF_UCHE_BANK_REQ3"/>
+	<value value="23" name="PERF_UCHE_BANK_REQ4"/>
+	<value value="24" name="PERF_UCHE_BANK_REQ5"/>
+	<value value="25" name="PERF_UCHE_BANK_REQ6"/>
+	<value value="26" name="PERF_UCHE_BANK_REQ7"/>
+	<value value="27" name="PERF_UCHE_VBIF_READ_BEATS_CH0"/>
+	<value value="28" name="PERF_UCHE_VBIF_READ_BEATS_CH1"/>
+	<value value="29" name="PERF_UCHE_GMEM_READ_BEATS"/>
+	<value value="30" name="PERF_UCHE_TPH_REF_FULL"/>
+	<value value="31" name="PERF_UCHE_TPH_VICTIM_FULL"/>
+	<value value="32" name="PERF_UCHE_TPH_EXT_FULL"/>
+	<value value="33" name="PERF_UCHE_VBIF_STALL_WRITE_DATA"/>
+	<value value="34" name="PERF_UCHE_DCMP_LATENCY_SAMPLES"/>
+	<value value="35" name="PERF_UCHE_DCMP_LATENCY_CYCLES"/>
+	<value value="36" name="PERF_UCHE_VBIF_READ_BEATS_PC"/>
+	<value value="37" name="PERF_UCHE_READ_REQUESTS_PC"/>
+	<value value="38" name="PERF_UCHE_RAM_READ_REQ"/>
+	<value value="39" name="PERF_UCHE_RAM_WRITE_REQ"/>
+</enum>
+
+<enum name="a6xx_tp_perfcounter_select">
+	<value value="0" name="PERF_TP_BUSY_CYCLES"/>
+	<value value="1" name="PERF_TP_STALL_CYCLES_UCHE"/>
+	<value value="2" name="PERF_TP_LATENCY_CYCLES"/>
+	<value value="3" name="PERF_TP_LATENCY_TRANS"/>
+	<value value="4" name="PERF_TP_FLAG_CACHE_REQUEST_SAMPLES"/>
+	<value value="5" name="PERF_TP_FLAG_CACHE_REQUEST_LATENCY"/>
+	<value value="6" name="PERF_TP_L1_CACHELINE_REQUESTS"/>
+	<value value="7" name="PERF_TP_L1_CACHELINE_MISSES"/>
+	<value value="8" name="PERF_TP_SP_TP_TRANS"/>
+	<value value="9" name="PERF_TP_TP_SP_TRANS"/>
+	<value value="10" name="PERF_TP_OUTPUT_PIXELS"/>
+	<value value="11" name="PERF_TP_FILTER_WORKLOAD_16BIT"/>
+	<value value="12" name="PERF_TP_FILTER_WORKLOAD_32BIT"/>
+	<value value="13" name="PERF_TP_QUADS_RECEIVED"/>
+	<value value="14" name="PERF_TP_QUADS_OFFSET"/>
+	<value value="15" name="PERF_TP_QUADS_SHADOW"/>
+	<value value="16" name="PERF_TP_QUADS_ARRAY"/>
+	<value value="17" name="PERF_TP_QUADS_GRADIENT"/>
+	<value value="18" name="PERF_TP_QUADS_1D"/>
+	<value value="19" name="PERF_TP_QUADS_2D"/>
+	<value value="20" name="PERF_TP_QUADS_BUFFER"/>
+	<value value="21" name="PERF_TP_QUADS_3D"/>
+	<value value="22" name="PERF_TP_QUADS_CUBE"/>
+	<value value="23" name="PERF_TP_DIVERGENT_QUADS_RECEIVED"/>
+	<value value="24" name="PERF_TP_PRT_NON_RESIDENT_EVENTS"/>
+	<value value="25" name="PERF_TP_OUTPUT_PIXELS_POINT"/>
+	<value value="26" name="PERF_TP_OUTPUT_PIXELS_BILINEAR"/>
+	<value value="27" name="PERF_TP_OUTPUT_PIXELS_MIP"/>
+	<value value="28" name="PERF_TP_OUTPUT_PIXELS_ANISO"/>
+	<value value="29" name="PERF_TP_OUTPUT_PIXELS_ZERO_LOD"/>
+	<value value="30" name="PERF_TP_FLAG_CACHE_REQUESTS"/>
+	<value value="31" name="PERF_TP_FLAG_CACHE_MISSES"/>
+	<value value="32" name="PERF_TP_L1_5_L2_REQUESTS"/>
+	<value value="33" name="PERF_TP_2D_OUTPUT_PIXELS"/>
+	<value value="34" name="PERF_TP_2D_OUTPUT_PIXELS_POINT"/>
+	<value value="35" name="PERF_TP_2D_OUTPUT_PIXELS_BILINEAR"/>
+	<value value="36" name="PERF_TP_2D_FILTER_WORKLOAD_16BIT"/>
+	<value value="37" name="PERF_TP_2D_FILTER_WORKLOAD_32BIT"/>
+	<value value="38" name="PERF_TP_TPA2TPC_TRANS"/>
+	<value value="39" name="PERF_TP_L1_MISSES_ASTC_1TILE"/>
+	<value value="40" name="PERF_TP_L1_MISSES_ASTC_2TILE"/>
+	<value value="41" name="PERF_TP_L1_MISSES_ASTC_4TILE"/>
+	<value value="42" name="PERF_TP_L1_5_L2_COMPRESS_REQS"/>
+	<value value="43" name="PERF_TP_L1_5_L2_COMPRESS_MISS"/>
+	<value value="44" name="PERF_TP_L1_BANK_CONFLICT"/>
+	<value value="45" name="PERF_TP_L1_5_MISS_LATENCY_CYCLES"/>
+	<value value="46" name="PERF_TP_L1_5_MISS_LATENCY_TRANS"/>
+	<value value="47" name="PERF_TP_QUADS_CONSTANT_MULTIPLIED"/>
+	<value value="48" name="PERF_TP_FRONTEND_WORKING_CYCLES"/>
+	<value value="49" name="PERF_TP_L1_TAG_WORKING_CYCLES"/>
+	<value value="50" name="PERF_TP_L1_DATA_WRITE_WORKING_CYCLES"/>
+	<value value="51" name="PERF_TP_PRE_L1_DECOM_WORKING_CYCLES"/>
+	<value value="52" name="PERF_TP_BACKEND_WORKING_CYCLES"/>
+	<value value="53" name="PERF_TP_FLAG_CACHE_WORKING_CYCLES"/>
+	<value value="54" name="PERF_TP_L1_5_CACHE_WORKING_CYCLES"/>
+	<value value="55" name="PERF_TP_STARVE_CYCLES_SP"/>
+	<value value="56" name="PERF_TP_STARVE_CYCLES_UCHE"/>
+</enum>
+
+<enum name="a6xx_sp_perfcounter_select">
+	<value value="0" name="PERF_SP_BUSY_CYCLES"/>
+	<value value="1" name="PERF_SP_ALU_WORKING_CYCLES"/>
+	<value value="2" name="PERF_SP_EFU_WORKING_CYCLES"/>
+	<value value="3" name="PERF_SP_STALL_CYCLES_VPC"/>
+	<value value="4" name="PERF_SP_STALL_CYCLES_TP"/>
+	<value value="5" name="PERF_SP_STALL_CYCLES_UCHE"/>
+	<value value="6" name="PERF_SP_STALL_CYCLES_RB"/>
+	<value value="7" name="PERF_SP_NON_EXECUTION_CYCLES"/>
+	<value value="8" name="PERF_SP_WAVE_CONTEXTS"/>
+	<value value="9" name="PERF_SP_WAVE_CONTEXT_CYCLES"/>
+	<value value="10" name="PERF_SP_FS_STAGE_WAVE_CYCLES"/>
+	<value value="11" name="PERF_SP_FS_STAGE_WAVE_SAMPLES"/>
+	<value value="12" name="PERF_SP_VS_STAGE_WAVE_CYCLES"/>
+	<value value="13" name="PERF_SP_VS_STAGE_WAVE_SAMPLES"/>
+	<value value="14" name="PERF_SP_FS_STAGE_DURATION_CYCLES"/>
+	<value value="15" name="PERF_SP_VS_STAGE_DURATION_CYCLES"/>
+	<value value="16" name="PERF_SP_WAVE_CTRL_CYCLES"/>
+	<value value="17" name="PERF_SP_WAVE_LOAD_CYCLES"/>
+	<value value="18" name="PERF_SP_WAVE_EMIT_CYCLES"/>
+	<value value="19" name="PERF_SP_WAVE_NOP_CYCLES"/>
+	<value value="20" name="PERF_SP_WAVE_WAIT_CYCLES"/>
+	<value value="21" name="PERF_SP_WAVE_FETCH_CYCLES"/>
+	<value value="22" name="PERF_SP_WAVE_IDLE_CYCLES"/>
+	<value value="23" name="PERF_SP_WAVE_END_CYCLES"/>
+	<value value="24" name="PERF_SP_WAVE_LONG_SYNC_CYCLES"/>
+	<value value="25" name="PERF_SP_WAVE_SHORT_SYNC_CYCLES"/>
+	<value value="26" name="PERF_SP_WAVE_JOIN_CYCLES"/>
+	<value value="27" name="PERF_SP_LM_LOAD_INSTRUCTIONS"/>
+	<value value="28" name="PERF_SP_LM_STORE_INSTRUCTIONS"/>
+	<value value="29" name="PERF_SP_LM_ATOMICS"/>
+	<value value="30" name="PERF_SP_GM_LOAD_INSTRUCTIONS"/>
+	<value value="31" name="PERF_SP_GM_STORE_INSTRUCTIONS"/>
+	<value value="32" name="PERF_SP_GM_ATOMICS"/>
+	<value value="33" name="PERF_SP_VS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="34" name="PERF_SP_VS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="35" name="PERF_SP_VS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="36" name="PERF_SP_VS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="37" name="PERF_SP_FS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="38" name="PERF_SP_FS_STAGE_CFLOW_INSTRUCTIONS"/>
+	<value value="39" name="PERF_SP_FS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="40" name="PERF_SP_FS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="41" name="PERF_SP_FS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="42" name="PERF_SP_FS_STAGE_BARY_INSTRUCTIONS"/>
+	<value value="43" name="PERF_SP_VS_INSTRUCTIONS"/>
+	<value value="44" name="PERF_SP_FS_INSTRUCTIONS"/>
+	<value value="45" name="PERF_SP_ADDR_LOCK_COUNT"/>
+	<value value="46" name="PERF_SP_UCHE_READ_TRANS"/>
+	<value value="47" name="PERF_SP_UCHE_WRITE_TRANS"/>
+	<value value="48" name="PERF_SP_EXPORT_VPC_TRANS"/>
+	<value value="49" name="PERF_SP_EXPORT_RB_TRANS"/>
+	<value value="50" name="PERF_SP_PIXELS_KILLED"/>
+	<value value="51" name="PERF_SP_ICL1_REQUESTS"/>
+	<value value="52" name="PERF_SP_ICL1_MISSES"/>
+	<value value="53" name="PERF_SP_HS_INSTRUCTIONS"/>
+	<value value="54" name="PERF_SP_DS_INSTRUCTIONS"/>
+	<value value="55" name="PERF_SP_GS_INSTRUCTIONS"/>
+	<value value="56" name="PERF_SP_CS_INSTRUCTIONS"/>
+	<value value="57" name="PERF_SP_GPR_READ"/>
+	<value value="58" name="PERF_SP_GPR_WRITE"/>
+	<value value="59" name="PERF_SP_FS_STAGE_HALF_EFU_INSTRUCTIONS"/>
+	<value value="60" name="PERF_SP_VS_STAGE_HALF_EFU_INSTRUCTIONS"/>
+	<value value="61" name="PERF_SP_LM_BANK_CONFLICTS"/>
+	<value value="62" name="PERF_SP_TEX_CONTROL_WORKING_CYCLES"/>
+	<value value="63" name="PERF_SP_LOAD_CONTROL_WORKING_CYCLES"/>
+	<value value="64" name="PERF_SP_FLOW_CONTROL_WORKING_CYCLES"/>
+	<value value="65" name="PERF_SP_LM_WORKING_CYCLES"/>
+	<value value="66" name="PERF_SP_DISPATCHER_WORKING_CYCLES"/>
+	<value value="67" name="PERF_SP_SEQUENCER_WORKING_CYCLES"/>
+	<value value="68" name="PERF_SP_LOW_EFFICIENCY_STARVED_BY_TP"/>
+	<value value="69" name="PERF_SP_STARVE_CYCLES_HLSQ"/>
+	<value value="70" name="PERF_SP_NON_EXECUTION_LS_CYCLES"/>
+	<value value="71" name="PERF_SP_WORKING_EU"/>
+	<value value="72" name="PERF_SP_ANY_EU_WORKING"/>
+	<value value="73" name="PERF_SP_WORKING_EU_FS_STAGE"/>
+	<value value="74" name="PERF_SP_ANY_EU_WORKING_FS_STAGE"/>
+	<value value="75" name="PERF_SP_WORKING_EU_VS_STAGE"/>
+	<value value="76" name="PERF_SP_ANY_EU_WORKING_VS_STAGE"/>
+	<value value="77" name="PERF_SP_WORKING_EU_CS_STAGE"/>
+	<value value="78" name="PERF_SP_ANY_EU_WORKING_CS_STAGE"/>
+	<value value="79" name="PERF_SP_GPR_READ_PREFETCH"/>
+	<value value="80" name="PERF_SP_GPR_READ_CONFLICT"/>
+	<value value="81" name="PERF_SP_GPR_WRITE_CONFLICT"/>
+	<value value="82" name="PERF_SP_GM_LOAD_LATENCY_CYCLES"/>
+	<value value="83" name="PERF_SP_GM_LOAD_LATENCY_SAMPLES"/>
+	<value value="84" name="PERF_SP_EXECUTABLE_WAVES"/>
+</enum>
+
+<enum name="a6xx_rb_perfcounter_select">
+	<value value="0" name="PERF_RB_BUSY_CYCLES"/>
+	<value value="1" name="PERF_RB_STALL_CYCLES_HLSQ"/>
+	<value value="2" name="PERF_RB_STALL_CYCLES_FIFO0_FULL"/>
+	<value value="3" name="PERF_RB_STALL_CYCLES_FIFO1_FULL"/>
+	<value value="4" name="PERF_RB_STALL_CYCLES_FIFO2_FULL"/>
+	<value value="5" name="PERF_RB_STARVE_CYCLES_SP"/>
+	<value value="6" name="PERF_RB_STARVE_CYCLES_LRZ_TILE"/>
+	<value value="7" name="PERF_RB_STARVE_CYCLES_CCU"/>
+	<value value="8" name="PERF_RB_STARVE_CYCLES_Z_PLANE"/>
+	<value value="9" name="PERF_RB_STARVE_CYCLES_BARY_PLANE"/>
+	<value value="10" name="PERF_RB_Z_WORKLOAD"/>
+	<value value="11" name="PERF_RB_HLSQ_ACTIVE"/>
+	<value value="12" name="PERF_RB_Z_READ"/>
+	<value value="13" name="PERF_RB_Z_WRITE"/>
+	<value value="14" name="PERF_RB_C_READ"/>
+	<value value="15" name="PERF_RB_C_WRITE"/>
+	<value value="16" name="PERF_RB_TOTAL_PASS"/>
+	<value value="17" name="PERF_RB_Z_PASS"/>
+	<value value="18" name="PERF_RB_Z_FAIL"/>
+	<value value="19" name="PERF_RB_S_FAIL"/>
+	<value value="20" name="PERF_RB_BLENDED_FXP_COMPONENTS"/>
+	<value value="21" name="PERF_RB_BLENDED_FP16_COMPONENTS"/>
+	<value value="22" name="PERF_RB_PS_INVOCATIONS"/>
+	<value value="23" name="PERF_RB_2D_ALIVE_CYCLES"/>
+	<value value="24" name="PERF_RB_2D_STALL_CYCLES_A2D"/>
+	<value value="25" name="PERF_RB_2D_STARVE_CYCLES_SRC"/>
+	<value value="26" name="PERF_RB_2D_STARVE_CYCLES_SP"/>
+	<value value="27" name="PERF_RB_2D_STARVE_CYCLES_DST"/>
+	<value value="28" name="PERF_RB_2D_VALID_PIXELS"/>
+	<value value="29" name="PERF_RB_3D_PIXELS"/>
+	<value value="30" name="PERF_RB_BLENDER_WORKING_CYCLES"/>
+	<value value="31" name="PERF_RB_ZPROC_WORKING_CYCLES"/>
+	<value value="32" name="PERF_RB_CPROC_WORKING_CYCLES"/>
+	<value value="33" name="PERF_RB_SAMPLER_WORKING_CYCLES"/>
+	<value value="34" name="PERF_RB_STALL_CYCLES_CCU_COLOR_READ"/>
+	<value value="35" name="PERF_RB_STALL_CYCLES_CCU_COLOR_WRITE"/>
+	<value value="36" name="PERF_RB_STALL_CYCLES_CCU_DEPTH_READ"/>
+	<value value="37" name="PERF_RB_STALL_CYCLES_CCU_DEPTH_WRITE"/>
+	<value value="38" name="PERF_RB_STALL_CYCLES_VPC"/>
+	<value value="39" name="PERF_RB_2D_INPUT_TRANS"/>
+	<value value="40" name="PERF_RB_2D_OUTPUT_RB_DST_TRANS"/>
+	<value value="41" name="PERF_RB_2D_OUTPUT_RB_SRC_TRANS"/>
+	<value value="42" name="PERF_RB_BLENDED_FP32_COMPONENTS"/>
+	<value value="43" name="PERF_RB_COLOR_PIX_TILES"/>
+	<value value="44" name="PERF_RB_STALL_CYCLES_CCU"/>
+	<value value="45" name="PERF_RB_EARLY_Z_ARB3_GRANT"/>
+	<value value="46" name="PERF_RB_LATE_Z_ARB3_GRANT"/>
+	<value value="47" name="PERF_RB_EARLY_Z_SKIP_GRANT"/>
+</enum>
+
+<enum name="a6xx_vsc_perfcounter_select">
+	<value value="0" name="PERF_VSC_BUSY_CYCLES"/>
+	<value value="1" name="PERF_VSC_WORKING_CYCLES"/>
+	<value value="2" name="PERF_VSC_STALL_CYCLES_UCHE"/>
+	<value value="3" name="PERF_VSC_EOT_NUM"/>
+	<value value="4" name="PERF_VSC_INPUT_TILES"/>
+</enum>
+
+<enum name="a6xx_ccu_perfcounter_select">
+	<value value="0" name="PERF_CCU_BUSY_CYCLES"/>
+	<value value="1" name="PERF_CCU_STALL_CYCLES_RB_DEPTH_RETURN"/>
+	<value value="2" name="PERF_CCU_STALL_CYCLES_RB_COLOR_RETURN"/>
+	<value value="3" name="PERF_CCU_STARVE_CYCLES_FLAG_RETURN"/>
+	<value value="4" name="PERF_CCU_DEPTH_BLOCKS"/>
+	<value value="5" name="PERF_CCU_COLOR_BLOCKS"/>
+	<value value="6" name="PERF_CCU_DEPTH_BLOCK_HIT"/>
+	<value value="7" name="PERF_CCU_COLOR_BLOCK_HIT"/>
+	<value value="8" name="PERF_CCU_PARTIAL_BLOCK_READ"/>
+	<value value="9" name="PERF_CCU_GMEM_READ"/>
+	<value value="10" name="PERF_CCU_GMEM_WRITE"/>
+	<value value="11" name="PERF_CCU_DEPTH_READ_FLAG0_COUNT"/>
+	<value value="12" name="PERF_CCU_DEPTH_READ_FLAG1_COUNT"/>
+	<value value="13" name="PERF_CCU_DEPTH_READ_FLAG2_COUNT"/>
+	<value value="14" name="PERF_CCU_DEPTH_READ_FLAG3_COUNT"/>
+	<value value="15" name="PERF_CCU_DEPTH_READ_FLAG4_COUNT"/>
+	<value value="16" name="PERF_CCU_DEPTH_READ_FLAG5_COUNT"/>
+	<value value="17" name="PERF_CCU_DEPTH_READ_FLAG6_COUNT"/>
+	<value value="18" name="PERF_CCU_DEPTH_READ_FLAG8_COUNT"/>
+	<value value="19" name="PERF_CCU_COLOR_READ_FLAG0_COUNT"/>
+	<value value="20" name="PERF_CCU_COLOR_READ_FLAG1_COUNT"/>
+	<value value="21" name="PERF_CCU_COLOR_READ_FLAG2_COUNT"/>
+	<value value="22" name="PERF_CCU_COLOR_READ_FLAG3_COUNT"/>
+	<value value="23" name="PERF_CCU_COLOR_READ_FLAG4_COUNT"/>
+	<value value="24" name="PERF_CCU_COLOR_READ_FLAG5_COUNT"/>
+	<value value="25" name="PERF_CCU_COLOR_READ_FLAG6_COUNT"/>
+	<value value="26" name="PERF_CCU_COLOR_READ_FLAG8_COUNT"/>
+	<value value="27" name="PERF_CCU_2D_RD_REQ"/>
+	<value value="28" name="PERF_CCU_2D_WR_REQ"/>
+</enum>
+
+<enum name="a6xx_lrz_perfcounter_select">
+	<value value="0" name="PERF_LRZ_BUSY_CYCLES"/>
+	<value value="1" name="PERF_LRZ_STARVE_CYCLES_RAS"/>
+	<value value="2" name="PERF_LRZ_STALL_CYCLES_RB"/>
+	<value value="3" name="PERF_LRZ_STALL_CYCLES_VSC"/>
+	<value value="4" name="PERF_LRZ_STALL_CYCLES_VPC"/>
+	<value value="5" name="PERF_LRZ_STALL_CYCLES_FLAG_PREFETCH"/>
+	<value value="6" name="PERF_LRZ_STALL_CYCLES_UCHE"/>
+	<value value="7" name="PERF_LRZ_LRZ_READ"/>
+	<value value="8" name="PERF_LRZ_LRZ_WRITE"/>
+	<value value="9" name="PERF_LRZ_READ_LATENCY"/>
+	<value value="10" name="PERF_LRZ_MERGE_CACHE_UPDATING"/>
+	<value value="11" name="PERF_LRZ_PRIM_KILLED_BY_MASKGEN"/>
+	<value value="12" name="PERF_LRZ_PRIM_KILLED_BY_LRZ"/>
+	<value value="13" name="PERF_LRZ_VISIBLE_PRIM_AFTER_LRZ"/>
+	<value value="14" name="PERF_LRZ_FULL_8X8_TILES"/>
+	<value value="15" name="PERF_LRZ_PARTIAL_8X8_TILES"/>
+	<value value="16" name="PERF_LRZ_TILE_KILLED"/>
+	<value value="17" name="PERF_LRZ_TOTAL_PIXEL"/>
+	<value value="18" name="PERF_LRZ_VISIBLE_PIXEL_AFTER_LRZ"/>
+	<value value="19" name="PERF_LRZ_FULLY_COVERED_TILES"/>
+	<value value="20" name="PERF_LRZ_PARTIAL_COVERED_TILES"/>
+	<value value="21" name="PERF_LRZ_FEEDBACK_ACCEPT"/>
+	<value value="22" name="PERF_LRZ_FEEDBACK_DISCARD"/>
+	<value value="23" name="PERF_LRZ_FEEDBACK_STALL"/>
+	<value value="24" name="PERF_LRZ_STALL_CYCLES_RB_ZPLANE"/>
+	<value value="25" name="PERF_LRZ_STALL_CYCLES_RB_BPLANE"/>
+	<value value="26" name="PERF_LRZ_STALL_CYCLES_VC"/>
+	<value value="27" name="PERF_LRZ_RAS_MASK_TRANS"/>
+</enum>
+
+<enum name="a6xx_cmp_perfcounter_select">
+	<value value="0" name="PERF_CMPDECMP_STALL_CYCLES_ARB"/>
+	<value value="1" name="PERF_CMPDECMP_VBIF_LATENCY_CYCLES"/>
+	<value value="2" name="PERF_CMPDECMP_VBIF_LATENCY_SAMPLES"/>
+	<value value="3" name="PERF_CMPDECMP_VBIF_READ_DATA_CCU"/>
+	<value value="4" name="PERF_CMPDECMP_VBIF_WRITE_DATA_CCU"/>
+	<value value="5" name="PERF_CMPDECMP_VBIF_READ_REQUEST"/>
+	<value value="6" name="PERF_CMPDECMP_VBIF_WRITE_REQUEST"/>
+	<value value="7" name="PERF_CMPDECMP_VBIF_READ_DATA"/>
+	<value value="8" name="PERF_CMPDECMP_VBIF_WRITE_DATA"/>
+	<value value="9" name="PERF_CMPDECMP_FLAG_FETCH_CYCLES"/>
+	<value value="10" name="PERF_CMPDECMP_FLAG_FETCH_SAMPLES"/>
+	<value value="11" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG1_COUNT"/>
+	<value value="12" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG2_COUNT"/>
+	<value value="13" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG3_COUNT"/>
+	<value value="14" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG4_COUNT"/>
+	<value value="15" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG5_COUNT"/>
+	<value value="16" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG6_COUNT"/>
+	<value value="17" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG8_COUNT"/>
+	<value value="18" name="PERF_CMPDECMP_COLOR_WRITE_FLAG1_COUNT"/>
+	<value value="19" name="PERF_CMPDECMP_COLOR_WRITE_FLAG2_COUNT"/>
+	<value value="20" name="PERF_CMPDECMP_COLOR_WRITE_FLAG3_COUNT"/>
+	<value value="21" name="PERF_CMPDECMP_COLOR_WRITE_FLAG4_COUNT"/>
+	<value value="22" name="PERF_CMPDECMP_COLOR_WRITE_FLAG5_COUNT"/>
+	<value value="23" name="PERF_CMPDECMP_COLOR_WRITE_FLAG6_COUNT"/>
+	<value value="24" name="PERF_CMPDECMP_COLOR_WRITE_FLAG8_COUNT"/>
+	<value value="25" name="PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_REQ"/>
+	<value value="26" name="PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_WR"/>
+	<value value="27" name="PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_RETURN"/>
+	<value value="28" name="PERF_CMPDECMP_2D_RD_DATA"/>
+	<value value="29" name="PERF_CMPDECMP_2D_WR_DATA"/>
+	<value value="30" name="PERF_CMPDECMP_VBIF_READ_DATA_UCHE_CH0"/>
+	<value value="31" name="PERF_CMPDECMP_VBIF_READ_DATA_UCHE_CH1"/>
+	<value value="32" name="PERF_CMPDECMP_2D_OUTPUT_TRANS"/>
+	<value value="33" name="PERF_CMPDECMP_VBIF_WRITE_DATA_UCHE"/>
+	<value value="34" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG0_COUNT"/>
+	<value value="35" name="PERF_CMPDECMP_COLOR_WRITE_FLAG0_COUNT"/>
+	<value value="36" name="PERF_CMPDECMP_COLOR_WRITE_FLAGALPHA_COUNT"/>
+	<value value="37" name="PERF_CMPDECMP_2D_BUSY_CYCLES"/>
+	<value value="38" name="PERF_CMPDECMP_2D_REORDER_STARVE_CYCLES"/>
+	<value value="39" name="PERF_CMPDECMP_2D_PIXELS"/>
+</enum>
+
+<!--
+Used in a6xx_2d_blit_cntl.. the value mostly seems to correlate to the
+component type/size, so I think it relates to internal format used for
+blending?  The one exception is that 16b unorm and 32b float use the
+same value... maybe 16b unorm is uncommon enough that it was just easier
+to upconvert to 32b float internally?
+
+ 8b unorm:  10 (sometimes 0, is the high bit part of something else?)
+16b unorm:   4
+
+32b int:     7
+16b int:     6
+ 8b int:     5
+
+32b float:   4
+16b float:   3
+ -->
+<enum name="a6xx_2d_ifmt">
+	<value value="0x10" name="R2D_UNORM8"/>
+	<value value="0x7"  name="R2D_INT32"/>
+	<value value="0x6"  name="R2D_INT16"/>
+	<value value="0x5"  name="R2D_INT8"/>
+	<value value="0x4"  name="R2D_FLOAT32"/>
+	<value value="0x3"  name="R2D_FLOAT16"/>
+	<value value="0x1"  name="R2D_UNORM8_SRGB"/>
+	<value value="0x0"  name="R2D_RAW"/>
+</enum>
+
+<enum name="a6xx_ztest_mode">
+	<doc>Allow early z-test and early-lrz (if applicable)</doc>
+	<value value="0x0" name="A6XX_EARLY_Z"/>
+	<doc>Disable early z-test and early-lrz test (if applicable)</doc>
+	<value value="0x1" name="A6XX_LATE_Z"/>
+	<doc>
+		A special mode that allows early-lrz test but disables
+		early-z test.  Which might sound a bit funny, since
+		lrz-test happens before z-test.  But as long as a couple
+		conditions are maintained this allows using lrz-test in
+		cases where fragment shader has kill/discard:
+
+		1) Disable lrz-write in cases where it is uncertain during
+		   binning pass that a fragment will pass.  Ie.  if frag
+		   shader has-kill, writes-z, or alpha/stencil test is
+		   enabled.  (For correctness, lrz-write must be disabled
+		   when blend is enabled.)  This is analogous to how a
+		   z-prepass works.
+
+		2) Disable lrz-write and test if a depth-test direction
+		   reversal is detected.  Due to condition (1), the contents
+		   of the lrz buffer are a conservative estimation of the
+		   depth buffer during the draw pass.  Meaning that geometry
+		   that we know for certain will not be visible will not pass
+		   lrz-test.  But geometry which may be (or contributes to
+		   blend) will pass the lrz-test.
+
+		This allows us to keep early-lrz-test in cases where the frag
+		shader does not write-z (ie. we know the z-value before FS)
+		and does not have side-effects (image/ssbo writes, etc), but
+		does have kill/discard.  Which turns out to be a common
+		enough case that it is useful to keep early-lrz test against
+		the conservative lrz buffer to discard fragments that we
+		know will definitely not be visible.
+	</doc>
+	<value value="0x2" name="A6XX_EARLY_LRZ_LATE_Z"/>
+	<doc>Not a real hw value, used internally by mesa</doc>
+	<value value="0x3" name="A6XX_INVALID_ZTEST"/>
+</enum>
+
+<enum name="a6xx_tess_spacing">
+	<value value="0x0" name="TESS_EQUAL"/>
+	<value value="0x2" name="TESS_FRACTIONAL_ODD"/>
+	<value value="0x3" name="TESS_FRACTIONAL_EVEN"/>
+</enum>
+<enum name="a6xx_tess_output">
+	<value value="0x0" name="TESS_POINTS"/>
+	<value value="0x1" name="TESS_LINES"/>
+	<value value="0x2" name="TESS_CW_TRIS"/>
+	<value value="0x3" name="TESS_CCW_TRIS"/>
+</enum>
+
+<enum name="a7xx_cp_perfcounter_select">
+	<value value="0" name="A7XX_PERF_CP_ALWAYS_COUNT"/>
+	<value value="1" name="A7XX_PERF_CP_BUSY_GFX_CORE_IDLE"/>
+	<value value="2" name="A7XX_PERF_CP_BUSY_CYCLES"/>
+	<value value="3" name="A7XX_PERF_CP_NUM_PREEMPTIONS"/>
+	<value value="4" name="A7XX_PERF_CP_PREEMPTION_REACTION_DELAY"/>
+	<value value="5" name="A7XX_PERF_CP_PREEMPTION_SWITCH_OUT_TIME"/>
+	<value value="6" name="A7XX_PERF_CP_PREEMPTION_SWITCH_IN_TIME"/>
+	<value value="7" name="A7XX_PERF_CP_DEAD_DRAWS_IN_BIN_RENDER"/>
+	<value value="8" name="A7XX_PERF_CP_PREDICATED_DRAWS_KILLED"/>
+	<value value="9" name="A7XX_PERF_CP_MODE_SWITCH"/>
+	<value value="10" name="A7XX_PERF_CP_ZPASS_DONE"/>
+	<value value="11" name="A7XX_PERF_CP_CONTEXT_DONE"/>
+	<value value="12" name="A7XX_PERF_CP_CACHE_FLUSH"/>
+	<value value="13" name="A7XX_PERF_CP_LONG_PREEMPTIONS"/>
+	<value value="14" name="A7XX_PERF_CP_SQE_I_CACHE_STARVE"/>
+	<value value="15" name="A7XX_PERF_CP_SQE_IDLE"/>
+	<value value="16" name="A7XX_PERF_CP_SQE_PM4_STARVE_RB_IB"/>
+	<value value="17" name="A7XX_PERF_CP_SQE_PM4_STARVE_SDS"/>
+	<value value="18" name="A7XX_PERF_CP_SQE_MRB_STARVE"/>
+	<value value="19" name="A7XX_PERF_CP_SQE_RRB_STARVE"/>
+	<value value="20" name="A7XX_PERF_CP_SQE_VSD_STARVE"/>
+	<value value="21" name="A7XX_PERF_CP_VSD_DECODE_STARVE"/>
+	<value value="22" name="A7XX_PERF_CP_SQE_PIPE_OUT_STALL"/>
+	<value value="23" name="A7XX_PERF_CP_SQE_SYNC_STALL"/>
+	<value value="24" name="A7XX_PERF_CP_SQE_PM4_WFI_STALL"/>
+	<value value="25" name="A7XX_PERF_CP_SQE_SYS_WFI_STALL"/>
+	<value value="26" name="A7XX_PERF_CP_SQE_T4_EXEC"/>
+	<value value="27" name="A7XX_PERF_CP_SQE_LOAD_STATE_EXEC"/>
+	<value value="28" name="A7XX_PERF_CP_SQE_SAVE_SDS_STATE"/>
+	<value value="29" name="A7XX_PERF_CP_SQE_DRAW_EXEC"/>
+	<value value="30" name="A7XX_PERF_CP_SQE_CTXT_REG_BUNCH_EXEC"/>
+	<value value="31" name="A7XX_PERF_CP_SQE_EXEC_PROFILED"/>
+	<value value="32" name="A7XX_PERF_CP_MEMORY_POOL_EMPTY"/>
+	<value value="33" name="A7XX_PERF_CP_MEMORY_POOL_SYNC_STALL"/>
+	<value value="34" name="A7XX_PERF_CP_MEMORY_POOL_ABOVE_THRESH"/>
+	<value value="35" name="A7XX_PERF_CP_AHB_WR_STALL_PRE_DRAWS"/>
+	<value value="36" name="A7XX_PERF_CP_AHB_STALL_SQE_GMU"/>
+	<value value="37" name="A7XX_PERF_CP_AHB_STALL_SQE_WR_OTHER"/>
+	<value value="38" name="A7XX_PERF_CP_AHB_STALL_SQE_RD_OTHER"/>
+	<value value="39" name="A7XX_PERF_CP_CLUSTER0_EMPTY"/>
+	<value value="40" name="A7XX_PERF_CP_CLUSTER1_EMPTY"/>
+	<value value="41" name="A7XX_PERF_CP_CLUSTER2_EMPTY"/>
+	<value value="42" name="A7XX_PERF_CP_CLUSTER3_EMPTY"/>
+	<value value="43" name="A7XX_PERF_CP_CLUSTER4_EMPTY"/>
+	<value value="44" name="A7XX_PERF_CP_CLUSTER5_EMPTY"/>
+	<value value="45" name="A7XX_PERF_CP_PM4_DATA"/>
+	<value value="46" name="A7XX_PERF_CP_PM4_HEADERS"/>
+	<value value="47" name="A7XX_PERF_CP_VBIF_READ_BEATS"/>
+	<value value="48" name="A7XX_PERF_CP_VBIF_WRITE_BEATS"/>
+	<value value="49" name="A7XX_PERF_CP_SQE_INSTR_COUNTER"/>
+	<value value="50" name="A7XX_PERF_CP_RESERVED_50"/>
+	<value value="51" name="A7XX_PERF_CP_RESERVED_51"/>
+	<value value="52" name="A7XX_PERF_CP_RESERVED_52"/>
+	<value value="53" name="A7XX_PERF_CP_RESERVED_53"/>
+	<value value="54" name="A7XX_PERF_CP_RESERVED_54"/>
+	<value value="55" name="A7XX_PERF_CP_RESERVED_55"/>
+	<value value="56" name="A7XX_PERF_CP_RESERVED_56"/>
+	<value value="57" name="A7XX_PERF_CP_RESERVED_57"/>
+	<value value="58" name="A7XX_PERF_CP_RESERVED_58"/>
+	<value value="59" name="A7XX_PERF_CP_RESERVED_59"/>
+	<value value="60" name="A7XX_PERF_CP_CLUSTER0_FULL"/>
+	<value value="61" name="A7XX_PERF_CP_CLUSTER1_FULL"/>
+	<value value="62" name="A7XX_PERF_CP_CLUSTER2_FULL"/>
+	<value value="63" name="A7XX_PERF_CP_CLUSTER3_FULL"/>
+	<value value="64" name="A7XX_PERF_CP_CLUSTER4_FULL"/>
+	<value value="65" name="A7XX_PERF_CP_CLUSTER5_FULL"/>
+	<value value="66" name="A7XX_PERF_CP_CLUSTER6_FULL"/>
+	<value value="67" name="A7XX_PERF_CP_CLUSTER6_EMPTY"/>
+	<value value="68" name="A7XX_PERF_CP_ICACHE_MISSES"/>
+	<value value="69" name="A7XX_PERF_CP_ICACHE_HITS"/>
+	<value value="70" name="A7XX_PERF_CP_ICACHE_STALL"/>
+	<value value="71" name="A7XX_PERF_CP_DCACHE_MISSES"/>
+	<value value="72" name="A7XX_PERF_CP_DCACHE_HITS"/>
+	<value value="73" name="A7XX_PERF_CP_DCACHE_STALLS"/>
+	<value value="74" name="A7XX_PERF_CP_AQE_SQE_STALL"/>
+	<value value="75" name="A7XX_PERF_CP_SQE_AQE_STARVE"/>
+	<value value="76" name="A7XX_PERF_CP_PREEMPT_LATENCY"/>
+	<value value="77" name="A7XX_PERF_CP_SQE_MD8_STALL_CYCLES"/>
+	<value value="78" name="A7XX_PERF_CP_SQE_MESH_EXEC_CYCLES"/>
+	<value value="79" name="A7XX_PERF_CP_AQE_NUM_AS_CHUNKS"/>
+	<value value="80" name="A7XX_PERF_CP_AQE_NUM_MS_CHUNKS"/>
+</enum>
+
+<enum name="a7xx_rbbm_perfcounter_select">
+	<value value="0" name="A7XX_PERF_RBBM_ALWAYS_COUNT"/>
+	<value value="1" name="A7XX_PERF_RBBM_ALWAYS_ON"/>
+	<value value="2" name="A7XX_PERF_RBBM_TSE_BUSY"/>
+	<value value="3" name="A7XX_PERF_RBBM_RAS_BUSY"/>
+	<value value="4" name="A7XX_PERF_RBBM_PC_DCALL_BUSY"/>
+	<value value="5" name="A7XX_PERF_RBBM_PC_VSD_BUSY"/>
+	<value value="6" name="A7XX_PERF_RBBM_STATUS_MASKED"/>
+	<value value="7" name="A7XX_PERF_RBBM_COM_BUSY"/>
+	<value value="8" name="A7XX_PERF_RBBM_DCOM_BUSY"/>
+	<value value="9" name="A7XX_PERF_RBBM_VBIF_BUSY"/>
+	<value value="10" name="A7XX_PERF_RBBM_VSC_BUSY"/>
+	<value value="11" name="A7XX_PERF_RBBM_TESS_BUSY"/>
+	<value value="12" name="A7XX_PERF_RBBM_UCHE_BUSY"/>
+	<value value="13" name="A7XX_PERF_RBBM_HLSQ_BUSY"/>
+</enum>
+
+<enum name="a7xx_pc_perfcounter_select">
+	<value value="0" name="A7XX_PERF_PC_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_PC_WORKING_CYCLES"/>
+	<value value="2" name="A7XX_PERF_PC_STALL_CYCLES_VFD"/>
+	<value value="3" name="A7XX_PERF_PC_RESERVED"/>
+	<value value="4" name="A7XX_PERF_PC_STALL_CYCLES_VPC"/>
+	<value value="5" name="A7XX_PERF_PC_STALL_CYCLES_UCHE"/>
+	<value value="6" name="A7XX_PERF_PC_STALL_CYCLES_TESS"/>
+	<value value="7" name="A7XX_PERF_PC_STALL_CYCLES_VFD_ONLY"/>
+	<value value="8" name="A7XX_PERF_PC_STALL_CYCLES_VPC_ONLY"/>
+	<value value="9" name="A7XX_PERF_PC_PASS1_TF_STALL_CYCLES"/>
+	<value value="10" name="A7XX_PERF_PC_STARVE_CYCLES_FOR_INDEX"/>
+	<value value="11" name="A7XX_PERF_PC_STARVE_CYCLES_FOR_TESS_FACTOR"/>
+	<value value="12" name="A7XX_PERF_PC_STARVE_CYCLES_FOR_VIZ_STREAM"/>
+	<value value="13" name="A7XX_PERF_PC_STARVE_CYCLES_DI"/>
+	<value value="14" name="A7XX_PERF_PC_VIS_STREAMS_LOADED"/>
+	<value value="15" name="A7XX_PERF_PC_INSTANCES"/>
+	<value value="16" name="A7XX_PERF_PC_VPC_PRIMITIVES"/>
+	<value value="17" name="A7XX_PERF_PC_DEAD_PRIM"/>
+	<value value="18" name="A7XX_PERF_PC_LIVE_PRIM"/>
+	<value value="19" name="A7XX_PERF_PC_VERTEX_HITS"/>
+	<value value="20" name="A7XX_PERF_PC_IA_VERTICES"/>
+	<value value="21" name="A7XX_PERF_PC_IA_PRIMITIVES"/>
+	<value value="22" name="A7XX_PERF_PC_RESERVED_22"/>
+	<value value="23" name="A7XX_PERF_PC_HS_INVOCATIONS"/>
+	<value value="24" name="A7XX_PERF_PC_DS_INVOCATIONS"/>
+	<value value="25" name="A7XX_PERF_PC_VS_INVOCATIONS"/>
+	<value value="26" name="A7XX_PERF_PC_GS_INVOCATIONS"/>
+	<value value="27" name="A7XX_PERF_PC_DS_PRIMITIVES"/>
+	<value value="28" name="A7XX_PERF_PC_3D_DRAWCALLS"/>
+	<value value="29" name="A7XX_PERF_PC_2D_DRAWCALLS"/>
+	<value value="30" name="A7XX_PERF_PC_NON_DRAWCALL_GLOBAL_EVENTS"/>
+	<value value="31" name="A7XX_PERF_PC_TESS_BUSY_CYCLES"/>
+	<value value="32" name="A7XX_PERF_PC_TESS_WORKING_CYCLES"/>
+	<value value="33" name="A7XX_PERF_PC_TESS_STALL_CYCLES_PC"/>
+	<value value="34" name="A7XX_PERF_PC_TESS_STARVE_CYCLES_PC"/>
+	<value value="35" name="A7XX_PERF_PC_TESS_SINGLE_PRIM_CYCLES"/>
+	<value value="36" name="A7XX_PERF_PC_TESS_PC_UV_TRANS"/>
+	<value value="37" name="A7XX_PERF_PC_TESS_PC_UV_PATCHES"/>
+	<value value="38" name="A7XX_PERF_PC_TESS_FACTOR_TRANS"/>
+	<value value="39" name="A7XX_PERF_PC_TAG_CHECKED_VERTICES"/>
+	<value value="40" name="A7XX_PERF_PC_MESH_VS_WAVES"/>
+	<value value="41" name="A7XX_PERF_PC_MESH_DRAWS"/>
+	<value value="42" name="A7XX_PERF_PC_MESH_DEAD_DRAWS"/>
+	<value value="43" name="A7XX_PERF_PC_MESH_MVIS_EN_DRAWS"/>
+	<value value="44" name="A7XX_PERF_PC_MESH_DEAD_PRIM"/>
+	<value value="45" name="A7XX_PERF_PC_MESH_LIVE_PRIM"/>
+	<value value="46" name="A7XX_PERF_PC_MESH_PA_EN_PRIM"/>
+	<value value="47" name="A7XX_PERF_PC_STARVE_CYCLES_FOR_MVIS_STREAM"/>
+	<value value="48" name="A7XX_PERF_PC_STARVE_CYCLES_PREDRAW"/>
+	<value value="49" name="A7XX_PERF_PC_STALL_CYCLES_COMPUTE_GFX"/>
+	<value value="50" name="A7XX_PERF_PC_STALL_CYCLES_GFX_COMPUTE"/>
+	<value value="51" name="A7XX_PERF_PC_TESS_PC_MULTI_PATCH_TRANS"/>
+</enum>
+
+<enum name="a7xx_vfd_perfcounter_select">
+	<value value="0" name="A7XX_PERF_VFD_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_VFD_STALL_CYCLES_UCHE"/>
+	<value value="2" name="A7XX_PERF_VFD_STALL_CYCLES_VPC_ALLOC"/>
+	<value value="3" name="A7XX_PERF_VFD_STALL_CYCLES_SP_INFO"/>
+	<value value="4" name="A7XX_PERF_VFD_STALL_CYCLES_SP_ATTR"/>
+	<value value="5" name="A7XX_PERF_VFD_STARVE_CYCLES_UCHE"/>
+	<value value="6" name="A7XX_PERF_VFD_RBUFFER_FULL"/>
+	<value value="7" name="A7XX_PERF_VFD_ATTR_INFO_FIFO_FULL"/>
+	<value value="8" name="A7XX_PERF_VFD_DECODED_ATTRIBUTE_BYTES"/>
+	<value value="9" name="A7XX_PERF_VFD_NUM_ATTRIBUTES"/>
+	<value value="10" name="A7XX_PERF_VFD_UPPER_SHADER_FIBERS"/>
+	<value value="11" name="A7XX_PERF_VFD_LOWER_SHADER_FIBERS"/>
+	<value value="12" name="A7XX_PERF_VFD_MODE_0_FIBERS"/>
+	<value value="13" name="A7XX_PERF_VFD_MODE_1_FIBERS"/>
+	<value value="14" name="A7XX_PERF_VFD_MODE_2_FIBERS"/>
+	<value value="15" name="A7XX_PERF_VFD_MODE_3_FIBERS"/>
+	<value value="16" name="A7XX_PERF_VFD_MODE_4_FIBERS"/>
+	<value value="17" name="A7XX_PERF_VFD_TOTAL_VERTICES"/>
+	<value value="18" name="A7XX_PERF_VFDP_STALL_CYCLES_VFD"/>
+	<value value="19" name="A7XX_PERF_VFDP_STALL_CYCLES_VFD_INDEX"/>
+	<value value="20" name="A7XX_PERF_VFDP_STALL_CYCLES_VFD_PROG"/>
+	<value value="21" name="A7XX_PERF_VFDP_STARVE_CYCLES_PC"/>
+	<value value="22" name="A7XX_PERF_VFDP_VS_STAGE_WAVES"/>
+	<value value="23" name="A7XX_PERF_VFD_STALL_CYCLES_PRG_END_FE"/>
+	<value value="24" name="A7XX_PERF_VFD_STALL_CYCLES_CBSYNC"/>
+</enum>
+
+<enum name="a7xx_hlsq_perfcounter_select">
+	<value value="0" name="A7XX_PERF_HLSQ_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_HLSQ_STALL_CYCLES_UCHE"/>
+	<value value="2" name="A7XX_PERF_HLSQ_STALL_CYCLES_SP_STATE"/>
+	<value value="3" name="A7XX_PERF_HLSQ_STALL_CYCLES_SP_FS_STAGE"/>
+	<value value="4" name="A7XX_PERF_HLSQ_UCHE_LATENCY_CYCLES"/>
+	<value value="5" name="A7XX_PERF_HLSQ_UCHE_LATENCY_COUNT"/>
+	<value value="6" name="A7XX_PERF_HLSQ_RESERVED_6"/>
+	<value value="7" name="A7XX_PERF_HLSQ_RESERVED_7"/>
+	<value value="8" name="A7XX_PERF_HLSQ_RESERVED_8"/>
+	<value value="9" name="A7XX_PERF_HLSQ_RESERVED_9"/>
+	<value value="10" name="A7XX_PERF_HLSQ_COMPUTE_DRAWCALLS"/>
+	<value value="11" name="A7XX_PERF_HLSQ_FS_DATA_WAIT_PROGRAMMING"/>
+	<value value="12" name="A7XX_PERF_HLSQ_DUAL_FS_PROG_ACTIVE"/>
+	<value value="13" name="A7XX_PERF_HLSQ_DUAL_VS_PROG_ACTIVE"/>
+	<value value="14" name="A7XX_PERF_HLSQ_FS_BATCH_COUNT_ZERO"/>
+	<value value="15" name="A7XX_PERF_HLSQ_VS_BATCH_COUNT_ZERO"/>
+	<value value="16" name="A7XX_PERF_HLSQ_WAVE_PENDING_NO_QUAD"/>
+	<value value="17" name="A7XX_PERF_HLSQ_WAVE_PENDING_NO_PRIM_BASE"/>
+	<value value="18" name="A7XX_PERF_HLSQ_STALL_CYCLES_VPC"/>
+	<value value="19" name="A7XX_PERF_HLSQ_RESERVED_19"/>
+	<value value="20" name="A7XX_PERF_HLSQ_DRAW_MODE_SWITCH_VSFS_SYNC"/>
+	<value value="21" name="A7XX_PERF_HLSQ_VSBR_STALL_CYCLES"/>
+	<value value="22" name="A7XX_PERF_HLSQ_FS_STALL_CYCLES"/>
+	<value value="23" name="A7XX_PERF_HLSQ_LPAC_STALL_CYCLES"/>
+	<value value="24" name="A7XX_PERF_HLSQ_BV_STALL_CYCLES"/>
+	<value value="25" name="A7XX_PERF_HLSQ_VSBR_DEREF_CYCLES"/>
+	<value value="26" name="A7XX_PERF_HLSQ_FS_DEREF_CYCLES"/>
+	<value value="27" name="A7XX_PERF_HLSQ_LPAC_DEREF_CYCLES"/>
+	<value value="28" name="A7XX_PERF_HLSQ_BV_DEREF_CYCLES"/>
+	<value value="29" name="A7XX_PERF_HLSQ_VSBR_S2W_CYCLES"/>
+	<value value="30" name="A7XX_PERF_HLSQ_FS_S2W_CYCLES"/>
+	<value value="31" name="A7XX_PERF_HLSQ_LPAC_S2W_CYCLES"/>
+	<value value="32" name="A7XX_PERF_HLSQ_BV_S2W_CYCLES"/>
+	<value value="33" name="A7XX_PERF_HLSQ_VSBR_WAIT_FS_S2W"/>
+	<value value="34" name="A7XX_PERF_HLSQ_FS_WAIT_VS_S2W"/>
+	<value value="35" name="A7XX_PERF_HLSQ_LPAC_WAIT_VS_S2W"/>
+	<value value="36" name="A7XX_PERF_HLSQ_BV_WAIT_FS_S2W"/>
+	<value value="37" name="A7XX_PERF_HLSQ_VS_WAIT_CONST_RESOURCE"/>
+	<value value="38" name="A7XX_PERF_HLSQ_FS_WAIT_SAME_VS_S2W"/>
+	<value value="39" name="A7XX_PERF_HLSQ_FS_STARVING_SP"/>
+	<value value="40" name="A7XX_PERF_HLSQ_VS_DATA_WAIT_PROGRAMMING"/>
+	<value value="41" name="A7XX_PERF_HLSQ_BV_DATA_WAIT_PROGRAMMING"/>
+	<value value="42" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXTS_VS"/>
+	<value value="43" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXT_CYCLES_VS"/>
+	<value value="44" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXTS_FS"/>
+	<value value="45" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXT_CYCLES_FS"/>
+	<value value="46" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXTS_BV"/>
+	<value value="47" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXT_CYCLES_BV"/>
+	<value value="48" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXTS_LPAC"/>
+	<value value="49" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXT_CYCLES_LPAC"/>
+	<value value="50" name="A7XX_PERF_HLSQ_SPTROC_STCHE_WARMUP_INC_VS"/>
+	<value value="51" name="A7XX_PERF_HLSQ_SPTROC_STCHE_WARMUP_INC_FS"/>
+	<value value="52" name="A7XX_PERF_HLSQ_SPTROC_STCHE_WARMUP_INC_BV"/>
+	<value value="53" name="A7XX_PERF_HLSQ_SPTROC_STCHE_WARMUP_INC_LPAC"/>
+	<value value="54" name="A7XX_PERF_HLSQ_SPTROC_STCHE_MISS_INC_VS"/>
+	<value value="55" name="A7XX_PERF_HLSQ_SPTROC_STCHE_MISS_INC_FS"/>
+	<value value="56" name="A7XX_PERF_HLSQ_SPTROC_STCHE_MISS_INC_BV"/>
+	<value value="57" name="A7XX_PERF_HLSQ_SPTROC_STCHE_MISS_INC_LPAC"/>
+</enum>
+
+<enum name="a7xx_vpc_perfcounter_select">
+	<value value="0" name="A7XX_PERF_VPC_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_VPC_WORKING_CYCLES"/>
+	<value value="2" name="A7XX_PERF_VPC_STALL_CYCLES_UCHE"/>
+	<value value="3" name="A7XX_PERF_VPC_STALL_CYCLES_VFD_WACK"/>
+	<value value="4" name="A7XX_PERF_VPC_STALL_CYCLES_HLSQ_PRIM_ALLOC"/>
+	<value value="5" name="A7XX_PERF_VPC_RESERVED_5"/>
+	<value value="6" name="A7XX_PERF_VPC_STALL_CYCLES_SP_LM"/>
+	<value value="7" name="A7XX_PERF_VPC_STARVE_CYCLES_SP"/>
+	<value value="8" name="A7XX_PERF_VPC_STARVE_CYCLES_LRZ"/>
+	<value value="9" name="A7XX_PERF_VPC_PC_PRIMITIVES"/>
+	<value value="10" name="A7XX_PERF_VPC_SP_COMPONENTS"/>
+	<value value="11" name="A7XX_PERF_VPC_STALL_CYCLES_VPCRAM_POS"/>
+	<value value="12" name="A7XX_PERF_VPC_LRZ_ASSIGN_PRIMITIVES"/>
+	<value value="13" name="A7XX_PERF_VPC_RB_VISIBLE_PRIMITIVES"/>
+	<value value="14" name="A7XX_PERF_VPC_LM_TRANSACTION"/>
+	<value value="15" name="A7XX_PERF_VPC_STREAMOUT_TRANSACTION"/>
+	<value value="16" name="A7XX_PERF_VPC_VS_BUSY_CYCLES"/>
+	<value value="17" name="A7XX_PERF_VPC_PS_BUSY_CYCLES"/>
+	<value value="18" name="A7XX_PERF_VPC_VS_WORKING_CYCLES"/>
+	<value value="19" name="A7XX_PERF_VPC_PS_WORKING_CYCLES"/>
+	<value value="20" name="A7XX_PERF_VPC_STARVE_CYCLES_RB"/>
+	<value value="21" name="A7XX_PERF_VPC_NUM_VPCRAM_READ_POS"/>
+	<value value="22" name="A7XX_PERF_VPC_WIT_FULL_CYCLES"/>
+	<value value="23" name="A7XX_PERF_VPC_VPCRAM_FULL_CYCLES"/>
+	<value value="24" name="A7XX_PERF_VPC_LM_FULL_WAIT_FOR_INTP_END"/>
+	<value value="25" name="A7XX_PERF_VPC_NUM_VPCRAM_WRITE"/>
+	<value value="26" name="A7XX_PERF_VPC_NUM_VPCRAM_READ_SO"/>
+	<value value="27" name="A7XX_PERF_VPC_NUM_ATTR_REQ_LM"/>
+	<value value="28" name="A7XX_PERF_VPC_STALL_CYCLE_TSE"/>
+	<value value="29" name="A7XX_PERF_VPC_TSE_PRIMITIVES"/>
+	<value value="30" name="A7XX_PERF_VPC_GS_PRIMITIVES"/>
+	<value value="31" name="A7XX_PERF_VPC_TSE_TRANSACTIONS"/>
+	<value value="32" name="A7XX_PERF_VPC_STALL_CYCLES_CCU"/>
+	<value value="33" name="A7XX_PERF_VPC_NUM_WM_HIT"/>
+	<value value="34" name="A7XX_PERF_VPC_STALL_DQ_WACK"/>
+	<value value="35" name="A7XX_PERF_VPC_STALL_CYCLES_CCHE"/>
+	<value value="36" name="A7XX_PERF_VPC_STARVE_CYCLES_CCHE"/>
+	<value value="37" name="A7XX_PERF_VPC_NUM_PA_REQ"/>
+	<value value="38" name="A7XX_PERF_VPC_NUM_LM_REQ_HIT"/>
+	<value value="39" name="A7XX_PERF_VPC_CCHE_REQBUF_FULL"/>
+	<value value="40" name="A7XX_PERF_VPC_STALL_CYCLES_LM_ACK"/>
+	<value value="41" name="A7XX_PERF_VPC_STALL_CYCLES_PRG_END_FE"/>
+	<value value="42" name="A7XX_PERF_VPC_STALL_CYCLES_PRG_END_PCVS"/>
+	<value value="43" name="A7XX_PERF_VPC_STALL_CYCLES_PRG_END_VPCPS"/>
+</enum>
+
+<enum name="a7xx_tse_perfcounter_select">
+	<value value="0" name="A7XX_PERF_TSE_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_TSE_CLIPPING_CYCLES"/>
+	<value value="2" name="A7XX_PERF_TSE_STALL_CYCLES_RAS"/>
+	<value value="3" name="A7XX_PERF_TSE_STALL_CYCLES_LRZ_BARYPLANE"/>
+	<value value="4" name="A7XX_PERF_TSE_STALL_CYCLES_LRZ_ZPLANE"/>
+	<value value="5" name="A7XX_PERF_TSE_STARVE_CYCLES_PC"/>
+	<value value="6" name="A7XX_PERF_TSE_INPUT_PRIM"/>
+	<value value="7" name="A7XX_PERF_TSE_INPUT_NULL_PRIM"/>
+	<value value="8" name="A7XX_PERF_TSE_TRIVAL_REJ_PRIM"/>
+	<value value="9" name="A7XX_PERF_TSE_CLIPPED_PRIM"/>
+	<value value="10" name="A7XX_PERF_TSE_ZERO_AREA_PRIM"/>
+	<value value="11" name="A7XX_PERF_TSE_FACENESS_CULLED_PRIM"/>
+	<value value="12" name="A7XX_PERF_TSE_ZERO_PIXEL_PRIM"/>
+	<value value="13" name="A7XX_PERF_TSE_OUTPUT_NULL_PRIM"/>
+	<value value="14" name="A7XX_PERF_TSE_OUTPUT_VISIBLE_PRIM"/>
+	<value value="15" name="A7XX_PERF_TSE_CINVOCATION"/>
+	<value value="16" name="A7XX_PERF_TSE_CPRIMITIVES"/>
+	<value value="17" name="A7XX_PERF_TSE_2D_INPUT_PRIM"/>
+	<value value="18" name="A7XX_PERF_TSE_2D_ALIVE_CYCLES"/>
+	<value value="19" name="A7XX_PERF_TSE_CLIP_PLANES"/>
+</enum>
+
+<enum name="a7xx_ras_perfcounter_select">
+	<value value="0" name="A7XX_PERF_RAS_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_RAS_SUPERTILE_ACTIVE_CYCLES"/>
+	<value value="2" name="A7XX_PERF_RAS_STALL_CYCLES_LRZ"/>
+	<value value="3" name="A7XX_PERF_RAS_STARVE_CYCLES_TSE"/>
+	<value value="4" name="A7XX_PERF_RAS_SUPER_TILES"/>
+	<value value="5" name="A7XX_PERF_RAS_8X4_TILES"/>
+	<value value="6" name="A7XX_PERF_RAS_MASKGEN_ACTIVE"/>
+	<value value="7" name="A7XX_PERF_RAS_FULLY_COVERED_SUPER_TILES"/>
+	<value value="8" name="A7XX_PERF_RAS_FULLY_COVERED_8X4_TILES"/>
+	<value value="9" name="A7XX_PERF_RAS_PRIM_KILLED_INVISILBE"/>
+	<value value="10" name="A7XX_PERF_RAS_SUPERTILE_GEN_ACTIVE_CYCLES"/>
+	<value value="11" name="A7XX_PERF_RAS_LRZ_INTF_WORKING_CYCLES"/>
+	<value value="12" name="A7XX_PERF_RAS_BLOCKS"/>
+	<value value="13" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_0_WORKING_CC_l2"/>
+	<value value="14" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_1_WORKING_CC_l2"/>
+	<value value="15" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_2_WORKING_CC_l2"/>
+	<value value="16" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_3_WORKING_CC_l2"/>
+	<value value="17" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_4_WORKING_CC_l2"/>
+	<value value="18" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_5_WORKING_CC_l2"/>
+	<value value="19" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_6_WORKING_CC_l2"/>
+	<value value="20" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_7_WORKING_CC_l2"/>
+	<value value="21" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_8_WORKING_CC_l2"/>
+	<value value="22" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_9_WORKING_CC_l2"/>
+	<value value="23" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_10_WORKING_CC_l2"/>
+	<value value="24" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_11_WORKING_CC_l2"/>
+	<value value="25" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_12_WORKING_CC_l2"/>
+	<value value="26" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_13_WORKING_CC_l2"/>
+	<value value="27" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_14_WORKING_CC_l2"/>
+	<value value="28" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_15_WORKING_CC_l2"/>
+	<value value="29" name="A7XX_PERF_RAS_FALSE_PARTIAL_STILE"/>
+
+</enum>
+
+<enum name="a7xx_uche_perfcounter_select">
+	<value value="0" name="A7XX_PERF_UCHE_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_UCHE_STALL_CYCLES_ARBITER"/>
+	<value value="2" name="A7XX_PERF_UCHE_VBIF_LATENCY_CYCLES"/>
+	<value value="3" name="A7XX_PERF_UCHE_VBIF_LATENCY_SAMPLES"/>
+	<value value="4" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_TP"/>
+	<value value="5" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_VFD"/>
+	<value value="6" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_HLSQ"/>
+	<value value="7" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_LRZ"/>
+	<value value="8" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_SP"/>
+	<value value="9" name="A7XX_PERF_UCHE_READ_REQUESTS_TP"/>
+	<value value="10" name="A7XX_PERF_UCHE_READ_REQUESTS_VFD"/>
+	<value value="11" name="A7XX_PERF_UCHE_READ_REQUESTS_HLSQ"/>
+	<value value="12" name="A7XX_PERF_UCHE_READ_REQUESTS_LRZ"/>
+	<value value="13" name="A7XX_PERF_UCHE_READ_REQUESTS_SP"/>
+	<value value="14" name="A7XX_PERF_UCHE_WRITE_REQUESTS_LRZ"/>
+	<value value="15" name="A7XX_PERF_UCHE_WRITE_REQUESTS_SP"/>
+	<value value="16" name="A7XX_PERF_UCHE_WRITE_REQUESTS_VPC"/>
+	<value value="17" name="A7XX_PERF_UCHE_WRITE_REQUESTS_VSC"/>
+	<value value="18" name="A7XX_PERF_UCHE_EVICTS"/>
+	<value value="19" name="A7XX_PERF_UCHE_BANK_REQ0"/>
+	<value value="20" name="A7XX_PERF_UCHE_BANK_REQ1"/>
+	<value value="21" name="A7XX_PERF_UCHE_BANK_REQ2"/>
+	<value value="22" name="A7XX_PERF_UCHE_BANK_REQ3"/>
+	<value value="23" name="A7XX_PERF_UCHE_BANK_REQ4"/>
+	<value value="24" name="A7XX_PERF_UCHE_BANK_REQ5"/>
+	<value value="25" name="A7XX_PERF_UCHE_BANK_REQ6"/>
+	<value value="26" name="A7XX_PERF_UCHE_BANK_REQ7"/>
+	<value value="27" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_CH0"/>
+	<value value="28" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_CH1"/>
+	<value value="29" name="A7XX_PERF_UCHE_GMEM_READ_BEATS"/>
+	<value value="30" name="A7XX_PERF_UCHE_TPH_REF_FULL"/>
+	<value value="31" name="A7XX_PERF_UCHE_TPH_VICTIM_FULL"/>
+	<value value="32" name="A7XX_PERF_UCHE_TPH_EXT_FULL"/>
+	<value value="33" name="A7XX_PERF_UCHE_VBIF_STALL_WRITE_DATA"/>
+	<value value="34" name="A7XX_PERF_UCHE_DCMP_LATENCY_SAMPLES"/>
+	<value value="35" name="A7XX_PERF_UCHE_DCMP_LATENCY_CYCLES"/>
+	<value value="36" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_PC"/>
+	<value value="37" name="A7XX_PERF_UCHE_READ_REQUESTS_PC"/>
+	<value value="38" name="A7XX_PERF_UCHE_RAM_READ_REQ"/>
+	<value value="39" name="A7XX_PERF_UCHE_RAM_WRITE_REQ"/>
+	<value value="40" name="A7XX_PERF_UCHE_STARVED_CYCLES_VBIF_DECMP"/>
+	<value value="41" name="A7XX_PERF_UCHE_STALL_CYCLES_DECMP"/>
+	<value value="42" name="A7XX_PERF_UCHE_ARBITER_STALL_CYCLES_VBIF"/>
+	<value value="43" name="A7XX_PERF_UCHE_READ_REQUESTS_TP_UBWC"/>
+	<value value="44" name="A7XX_PERF_UCHE_READ_REQUESTS_TP_NONUBWC"/>
+	<value value="45" name="A7XX_PERF_UCHE_READ_REQUESTS_TP_GMEM"/>
+	<value value="46" name="A7XX_PERF_UCHE_LONG_LINE_ALL_EVICTS_KAILUA"/>
+	<value value="47" name="A7XX_PERF_UCHE_LONG_LINE_PARTIAL_EVICTS_KAILUA"/>
+	<value value="48" name="A7XX_PERF_UCHE_TPH_CONFLICT_CL_CCHE"/>
+	<value value="49" name="A7XX_PERF_UCHE_TPH_CONFLICT_CL_OTHER_KAILUA"/>
+	<value value="50" name="A7XX_PERF_UCHE_DBANK_CONFLICT_CL_CCHE"/>
+	<value value="51" name="A7XX_PERF_UCHE_DBANK_CONFLICT_CL_OTHER_CLIENTS"/>
+	<value value="52" name="A7XX_PERF_UCHE_VBIF_WRITE_BEATS_CH0"/>
+	<value value="53" name="A7XX_PERF_UCHE_VBIF_WRITE_BEATS_CH1"/>
+	<value value="54" name="A7XX_PERF_UCHE_CCHE_TPH_QUEUE_FULL"/>
+	<value value="55" name="A7XX_PERF_UCHE_CCHE_DPH_QUEUE_FULL"/>
+	<value value="56" name="A7XX_PERF_UCHE_GMEM_WRITE_BEATS"/>
+	<value value="57" name="A7XX_PERF_UCHE_UBWC_READ_BEATS"/>
+	<value value="58" name="A7XX_PERF_UCHE_UBWC_WRITE_BEATS"/>
+</enum>
+
+<enum name="a7xx_tp_perfcounter_select">
+	<value value="0" name="A7XX_PERF_TP_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_TP_STALL_CYCLES_UCHE"/>
+	<value value="2" name="A7XX_PERF_TP_LATENCY_CYCLES"/>
+	<value value="3" name="A7XX_PERF_TP_LATENCY_TRANS"/>
+	<value value="4" name="A7XX_PERF_TP_FLAG_FIFO_DELAY_SAMPLES"/>
+	<value value="5" name="A7XX_PERF_TP_FLAG_FIFO_DELAY_CYCLES"/>
+	<value value="6" name="A7XX_PERF_TP_L1_CACHELINE_REQUESTS"/>
+	<value value="7" name="A7XX_PERF_TP_L1_CACHELINE_MISSES"/>
+	<value value="8" name="A7XX_PERF_TP_SP_TP_TRANS"/>
+	<value value="9" name="A7XX_PERF_TP_TP_SP_TRANS"/>
+	<value value="10" name="A7XX_PERF_TP_OUTPUT_PIXELS"/>
+	<value value="11" name="A7XX_PERF_TP_FILTER_WORKLOAD_16BIT"/>
+	<value value="12" name="A7XX_PERF_TP_FILTER_WORKLOAD_32BIT"/>
+	<value value="13" name="A7XX_PERF_TP_QUADS_RECEIVED"/>
+	<value value="14" name="A7XX_PERF_TP_QUADS_OFFSET"/>
+	<value value="15" name="A7XX_PERF_TP_QUADS_SHADOW"/>
+	<value value="16" name="A7XX_PERF_TP_QUADS_ARRAY"/>
+	<value value="17" name="A7XX_PERF_TP_QUADS_GRADIENT"/>
+	<value value="18" name="A7XX_PERF_TP_QUADS_1D"/>
+	<value value="19" name="A7XX_PERF_TP_QUADS_2D"/>
+	<value value="20" name="A7XX_PERF_TP_QUADS_BUFFER"/>
+	<value value="21" name="A7XX_PERF_TP_QUADS_3D"/>
+	<value value="22" name="A7XX_PERF_TP_QUADS_CUBE"/>
+	<value value="23" name="A7XX_PERF_TP_DIVERGENT_QUADS_RECEIVED"/>
+	<value value="24" name="A7XX_PERF_TP_PRT_NON_RESIDENT_EVENTS"/>
+	<value value="25" name="A7XX_PERF_TP_OUTPUT_PIXELS_POINT"/>
+	<value value="26" name="A7XX_PERF_TP_OUTPUT_PIXELS_BILINEAR"/>
+	<value value="27" name="A7XX_PERF_TP_OUTPUT_PIXELS_MIP"/>
+	<value value="28" name="A7XX_PERF_TP_OUTPUT_PIXELS_ANISO"/>
+	<value value="29" name="A7XX_PERF_TP_OUTPUT_PIXELS_ZERO_LOD"/>
+	<value value="30" name="A7XX_PERF_TP_FLAG_CACHE_REQUESTS"/>
+	<value value="31" name="A7XX_PERF_TP_FLAG_CACHE_MISSES"/>
+	<value value="32" name="A7XX_PERF_TP_L1_5_L2_REQUESTS"/>
+	<value value="33" name="A7XX_PERF_TP_2D_OUTPUT_PIXELS"/>
+	<value value="34" name="A7XX_PERF_TP_2D_OUTPUT_PIXELS_POINT"/>
+	<value value="35" name="A7XX_PERF_TP_2D_OUTPUT_PIXELS_BILINEAR"/>
+	<value value="36" name="A7XX_PERF_TP_2D_FILTER_WORKLOAD_16BIT"/>
+	<value value="37" name="A7XX_PERF_TP_2D_FILTER_WORKLOAD_32BIT"/>
+	<value value="38" name="A7XX_PERF_TP_TPA2TPC_TRANS"/>
+	<value value="39" name="A7XX_PERF_TP_L1_MISSES_ASTC_1TILE"/>
+	<value value="40" name="A7XX_PERF_TP_L1_MISSES_ASTC_2TILE"/>
+	<value value="41" name="A7XX_PERF_TP_L1_MISSES_ASTC_4TILE"/>
+	<value value="42" name="A7XX_PERF_TP_L1_5_COMPRESS_REQS"/>
+	<value value="43" name="A7XX_PERF_TP_L1_5_L2_COMPRESS_MISS"/>
+	<value value="44" name="A7XX_PERF_TP_L1_BANK_CONFLICT"/>
+	<value value="45" name="A7XX_PERF_TP_L1_5_MISS_LATENCY_CYCLES"/>
+	<value value="46" name="A7XX_PERF_TP_L1_5_MISS_LATENCY_TRANS"/>
+	<value value="47" name="A7XX_PERF_TP_QUADS_CONSTANT_MULTIPLIED"/>
+	<value value="48" name="A7XX_PERF_TP_FRONTEND_WORKING_CYCLES"/>
+	<value value="49" name="A7XX_PERF_TP_L1_TAG_WORKING_CYCLES"/>
+	<value value="50" name="A7XX_PERF_TP_L1_DATA_WRITE_WORKING_CYCLES"/>
+	<value value="51" name="A7XX_PERF_TP_PRE_L1_DECOM_WORKING_CYCLES"/>
+	<value value="52" name="A7XX_PERF_TP_BACKEND_WORKING_CYCLES"/>
+	<value value="53" name="A7XX_PERF_TP_L1_5_CACHE_WORKING_CYCLES"/>
+	<value value="54" name="A7XX_PERF_TP_STARVE_CYCLES_SP"/>
+	<value value="55" name="A7XX_PERF_TP_STARVE_CYCLES_UCHE"/>
+	<value value="56" name="A7XX_PERF_TP_STALL_CYCLES_UFC"/>
+	<value value="57" name="A7XX_PERF_TP_FORMAT_DECOMP"/>
+	<value value="58" name="A7XX_PERF_TP_FILTER_POINT_FP16"/>
+	<value value="59" name="A7XX_PERF_TP_FILTER_POINT_FP32"/>
+	<value value="60" name="A7XX_PERF_TP_LATENCY_FIFO_FULL"/>
+	<value value="61" name="A7XX_PERF_TP_RESERVED_61"/>
+	<value value="62" name="A7XX_PERF_TP_RESERVED_62"/>
+	<value value="63" name="A7XX_PERF_TP_RESERVED_63"/>
+	<value value="64" name="A7XX_PERF_TP_RESERVED_64"/>
+	<value value="65" name="A7XX_PERF_TP_RESERVED_65"/>
+	<value value="66" name="A7XX_PERF_TP_RESERVED_66"/>
+	<value value="67" name="A7XX_PERF_TP_RESERVED_67"/>
+	<value value="68" name="A7XX_PERF_TP_RESERVED_68"/>
+	<value value="69" name="A7XX_PERF_TP_RESERVED_69"/>
+	<value value="70" name="A7XX_PERF_TP_RESERVED_70"/>
+	<value value="71" name="A7XX_PERF_TP_RESERVED_71"/>
+	<value value="72" name="A7XX_PERF_TP_RESERVED_72"/>
+	<value value="73" name="A7XX_PERF_TP_RESERVED_73"/>
+	<value value="74" name="A7XX_PERF_TP_RESERVED_74"/>
+	<value value="75" name="A7XX_PERF_TP_RESERVED_75"/>
+	<value value="76" name="A7XX_PERF_TP_RESERVED_76"/>
+	<value value="77" name="A7XX_PERF_TP_RESERVED_77"/>
+	<value value="78" name="A7XX_PERF_TP_RESERVED_78"/>
+	<value value="79" name="A7XX_PERF_TP_RESERVED_79"/>
+	<value value="80" name="A7XX_PERF_TP_RESERVED_80"/>
+	<value value="81" name="A7XX_PERF_TP_RESERVED_81"/>
+	<value value="82" name="A7XX_PERF_TP_RESERVED_82"/>
+	<value value="83" name="A7XX_PERF_TP_RESERVED_83"/>
+	<value value="84" name="A7XX_PERF_TP_RESERVED_84"/>
+	<value value="85" name="A7XX_PERF_TP_RESERVED_85"/>
+	<value value="86" name="A7XX_PERF_TP_RESERVED_86"/>
+	<value value="87" name="A7XX_PERF_TP_RESERVED_87"/>
+	<value value="88" name="A7XX_PERF_TP_RESERVED_88"/>
+	<value value="89" name="A7XX_PERF_TP_RESERVED_89"/>
+	<value value="90" name="A7XX_PERF_TP_RESERVED_90"/>
+	<value value="91" name="A7XX_PERF_TP_RESERVED_91"/>
+	<value value="92" name="A7XX_PERF_TP_RESERVED_92"/>
+	<value value="93" name="A7XX_PERF_TP_RESERVED_93"/>
+	<value value="94" name="A7XX_PERF_TP_RESERVED_94"/>
+	<value value="95" name="A7XX_PERF_TP_RESERVED_95"/>
+	<value value="96" name="A7XX_PERF_TP_RESERVED_96"/>
+	<value value="97" name="A7XX_PERF_TP_RESERVED_97"/>
+	<value value="98" name="A7XX_PERF_TP_RESERVED_98"/>
+	<value value="99" name="A7XX_PERF_TP_RESERVED_99"/>
+	<value value="100" name="A7XX_PERF_TP_RESERVED_100"/>
+	<value value="101" name="A7XX_PERF_TP_RESERVED_101"/>
+	<value value="102" name="A7XX_PERF_TP_RESERVED_102"/>
+	<value value="103" name="A7XX_PERF_TP_RESERVED_103"/>
+	<value value="104" name="A7XX_PERF_TP_RESERVED_104"/>
+	<value value="105" name="A7XX_PERF_TP_RESERVED_105"/>
+	<value value="106" name="A7XX_PERF_TP_RESERVED_106"/>
+	<value value="107" name="A7XX_PERF_TP_RESERVED_107"/>
+	<value value="108" name="A7XX_PERF_TP_RESERVED_108"/>
+	<value value="109" name="A7XX_PERF_TP_RESERVED_109"/>
+	<value value="110" name="A7XX_PERF_TP_RESERVED_110"/>
+	<value value="111" name="A7XX_PERF_TP_RESERVED_111"/>
+	<value value="112" name="A7XX_PERF_TP_RESERVED_112"/>
+	<value value="113" name="A7XX_PERF_TP_RESERVED_113"/>
+	<value value="114" name="A7XX_PERF_TP_RESERVED_114"/>
+	<value value="115" name="A7XX_PERF_TP_RESERVED_115"/>
+	<value value="116" name="A7XX_PERF_TP_RESERVED_116"/>
+	<value value="117" name="A7XX_PERF_TP_RESERVED_117"/>
+	<value value="118" name="A7XX_PERF_TP_RESERVED_118"/>
+	<value value="119" name="A7XX_PERF_TP_RESERVED_119"/>
+	<value value="120" name="A7XX_PERF_TP_RESERVED_120"/>
+	<value value="121" name="A7XX_PERF_TP_RESERVED_121"/>
+	<value value="122" name="A7XX_PERF_TP_RESERVED_122"/>
+	<value value="123" name="A7XX_PERF_TP_RESERVED_123"/>
+	<value value="124" name="A7XX_PERF_TP_RESERVED_124"/>
+	<value value="125" name="A7XX_PERF_TP_RESERVED_125"/>
+	<value value="126" name="A7XX_PERF_TP_RESERVED_126"/>
+	<value value="127" name="A7XX_PERF_TP_RESERVED_127"/>
+	<value value="128" name="A7XX_PERF_TP_FORMAT_DECOMP_BILINEAR"/>
+	<value value="129" name="A7XX_PERF_TP_PACKED_POINT_BOTH_VALID_FP16"/>
+	<value value="130" name="A7XX_PERF_TP_PACKED_POINT_SINGLE_VALID_FP16"/>
+	<value value="131" name="A7XX_PERF_TP_PACKED_POINT_BOTH_VALID_FP32"/>
+	<value value="132" name="A7XX_PERF_TP_PACKED_POINT_SINGLE_VALID_FP32"/>
+</enum>
+
+<enum name="a7xx_sp_perfcounter_select">
+	<value value="0" name="A7XX_PERF_SP_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_SP_ALU_WORKING_CYCLES"/>
+	<value value="2" name="A7XX_PERF_SP_EFU_WORKING_CYCLES"/>
+	<value value="3" name="A7XX_PERF_SP_STALL_CYCLES_VPC"/>
+	<value value="4" name="A7XX_PERF_SP_STALL_CYCLES_TP"/>
+	<value value="5" name="A7XX_PERF_SP_STALL_CYCLES_UCHE"/>
+	<value value="6" name="A7XX_PERF_SP_STALL_CYCLES_RB"/>
+	<value value="7" name="A7XX_PERF_SP_NON_EXECUTION_CYCLES"/>
+	<value value="8" name="A7XX_PERF_SP_WAVE_CONTEXTS"/>
+	<value value="9" name="A7XX_PERF_SP_WAVE_CONTEXT_CYCLES"/>
+	<value value="10" name="A7XX_PERF_SP_STAGE_WAVE_CYCLES"/>
+	<value value="11" name="A7XX_PERF_SP_STAGE_WAVE_SAMPLES"/>
+	<value value="12" name="A7XX_PERF_SP_VS_STAGE_WAVE_CYCLES"/>
+	<value value="13" name="A7XX_PERF_SP_VS_STAGE_WAVE_SAMPLES"/>
+	<value value="14" name="A7XX_PERF_SP_FS_STAGE_DURATION_CYCLES"/>
+	<value value="15" name="A7XX_PERF_SP_VS_STAGE_DURATION_CYCLES"/>
+	<value value="16" name="A7XX_PERF_SP_WAVE_CTRL_CYCLES"/>
+	<value value="17" name="A7XX_PERF_SP_WAVE_LOAD_CYCLES"/>
+	<value value="18" name="A7XX_PERF_SP_WAVE_EMIT_CYCLES"/>
+	<value value="19" name="A7XX_PERF_SP_WAVE_NOP_CYCLES"/>
+	<value value="20" name="A7XX_PERF_SP_WAVE_WAIT_CYCLES"/>
+	<value value="21" name="A7XX_PERF_SP_WAVE_FETCH_CYCLES"/>
+	<value value="22" name="A7XX_PERF_SP_WAVE_IDLE_CYCLES"/>
+	<value value="23" name="A7XX_PERF_SP_WAVE_END_CYCLES"/>
+	<value value="24" name="A7XX_PERF_SP_WAVE_LONG_SYNC_CYCLES"/>
+	<value value="25" name="A7XX_PERF_SP_WAVE_SHORT_SYNC_CYCLES"/>
+	<value value="26" name="A7XX_PERF_SP_WAVE_JOIN_CYCLES"/>
+	<value value="27" name="A7XX_PERF_SP_LM_LOAD_INSTRUCTIONS"/>
+	<value value="28" name="A7XX_PERF_SP_LM_STORE_INSTRUCTIONS"/>
+	<value value="29" name="A7XX_PERF_SP_LM_ATOMICS"/>
+	<value value="30" name="A7XX_PERF_SP_GM_LOAD_INSTRUCTIONS"/>
+	<value value="31" name="A7XX_PERF_SP_GM_STORE_INSTRUCTIONS"/>
+	<value value="32" name="A7XX_PERF_SP_GM_ATOMICS"/>
+	<value value="33" name="A7XX_PERF_SP_VS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="34" name="A7XX_PERF_SP_VS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="35" name="A7XX_PERF_SP_VS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="36" name="A7XX_PERF_SP_VS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="37" name="A7XX_PERF_SP_FS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="38" name="A7XX_PERF_SP_FS_STAGE_CFLOW_INSTRUCTIONS"/>
+	<value value="39" name="A7XX_PERF_SP_FS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="40" name="A7XX_PERF_SP_FS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="41" name="A7XX_PERF_SP_FS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="42" name="A7XX_PERF_SP_FS_STAGE_BARY_INSTRUCTIONS"/>
+	<value value="43" name="A7XX_PERF_SP_VS_INSTRUCTIONS"/>
+	<value value="44" name="A7XX_PERF_SP_FS_INSTRUCTIONS"/>
+	<value value="45" name="A7XX_PERF_SP_ADDR_LOCK_COUNT"/>
+	<value value="46" name="A7XX_PERF_SP_UCHE_READ_TRANS"/>
+	<value value="47" name="A7XX_PERF_SP_UCHE_WRITE_TRANS"/>
+	<value value="48" name="A7XX_PERF_SP_EXPORT_VPC_TRANS"/>
+	<value value="49" name="A7XX_PERF_SP_EXPORT_RB_TRANS"/>
+	<value value="50" name="A7XX_PERF_SP_PIXELS_KILLED"/>
+	<value value="51" name="A7XX_PERF_SP_ICL1_REQUESTS"/>
+	<value value="52" name="A7XX_PERF_SP_ICL1_MISSES"/>
+	<value value="53" name="A7XX_PERF_SP_HS_INSTRUCTIONS"/>
+	<value value="54" name="A7XX_PERF_SP_DS_INSTRUCTIONS"/>
+	<value value="55" name="A7XX_PERF_SP_GS_INSTRUCTIONS"/>
+	<value value="56" name="A7XX_PERF_SP_CS_INSTRUCTIONS"/>
+	<value value="57" name="A7XX_PERF_SP_GPR_READ"/>
+	<value value="58" name="A7XX_PERF_SP_GPR_WRITE"/>
+	<value value="59" name="A7XX_PERF_SP_FS_STAGE_HALF_EFU_INSTRUCTIONS"/>
+	<value value="60" name="A7XX_PERF_SP_VS_STAGE_HALF_EFU_INSTRUCTIONS"/>
+	<value value="61" name="A7XX_PERF_SP_LM_BANK_CONFLICTS"/>
+	<value value="62" name="A7XX_PERF_SP_TEX_CONTROL_WORKING_CYCLES"/>
+	<value value="63" name="A7XX_PERF_SP_LOAD_CONTROL_WORKING_CYCLES"/>
+	<value value="64" name="A7XX_PERF_SP_FLOW_CONTROL_WORKING_CYCLES"/>
+	<value value="65" name="A7XX_PERF_SP_LM_WORKING_CYCLES"/>
+	<value value="66" name="A7XX_PERF_SP_DISPATCHER_WORKING_CYCLES"/>
+	<value value="67" name="A7XX_PERF_SP_SEQUENCER_WORKING_CYCLES"/>
+	<value value="68" name="A7XX_PERF_SP_LOW_EFFICIENCY_STARVED_BY_TP"/>
+	<value value="69" name="A7XX_PERF_SP_STARVE_CYCLES_HLSQ"/>
+	<value value="70" name="A7XX_PERF_SP_NON_EXECUTION_LS_CYCLES"/>
+	<value value="71" name="A7XX_PERF_SP_WORKING_EU"/>
+	<value value="72" name="A7XX_PERF_SP_ANY_EU_WORKING"/>
+	<value value="73" name="A7XX_PERF_SP_WORKING_EU_FS_STAGE"/>
+	<value value="74" name="A7XX_PERF_SP_ANY_EU_WORKING_FS_STAGE"/>
+	<value value="75" name="A7XX_PERF_SP_WORKING_EU_VS_STAGE"/>
+	<value value="76" name="A7XX_PERF_SP_ANY_EU_WORKING_VS_STAGE"/>
+	<value value="77" name="A7XX_PERF_SP_WORKING_EU_CS_STAGE"/>
+	<value value="78" name="A7XX_PERF_SP_ANY_EU_WORKING_CS_STAGE"/>
+	<value value="79" name="A7XX_PERF_SP_GPR_READ_PREFETCH"/>
+	<value value="80" name="A7XX_PERF_SP_GPR_READ_CONFLICT"/>
+	<value value="81" name="A7XX_PERF_SP_GPR_WRITE_CONFLICT"/>
+	<value value="82" name="A7XX_PERF_SP_GM_LOAD_LATENCY_CYCLES"/>
+	<value value="83" name="A7XX_PERF_SP_GM_LOAD_LATENCY_SAMPLES"/>
+	<value value="84" name="A7XX_PERF_SP_EXECUTABLE_WAVES"/>
+	<value value="85" name="A7XX_PERF_SP_ICL1_MISS_FETCH_CYCLES"/>
+	<value value="86" name="A7XX_PERF_SP_WORKING_EU_LPAC"/>
+	<value value="87" name="A7XX_PERF_SP_BYPASS_BUSY_CYCLES"/>
+	<value value="88" name="A7XX_PERF_SP_ANY_EU_WORKING_LPAC"/>
+	<value value="89" name="A7XX_PERF_SP_WAVE_ALU_CYCLES"/>
+	<value value="90" name="A7XX_PERF_SP_WAVE_EFU_CYCLES"/>
+	<value value="91" name="A7XX_PERF_SP_WAVE_INT_CYCLES"/>
+	<value value="92" name="A7XX_PERF_SP_WAVE_CSP_CYCLES"/>
+	<value value="93" name="A7XX_PERF_SP_EWAVE_CONTEXTS"/>
+	<value value="94" name="A7XX_PERF_SP_EWAVE_CONTEXT_CYCLES"/>
+	<value value="95" name="A7XX_PERF_SP_LPAC_BUSY_CYCLES"/>
+	<value value="96" name="A7XX_PERF_SP_LPAC_INSTRUCTIONS"/>
+	<value value="97" name="A7XX_PERF_SP_FS_STAGE_1X_WAVES"/>
+	<value value="98" name="A7XX_PERF_SP_FS_STAGE_2X_WAVES"/>
+	<value value="99" name="A7XX_PERF_SP_QUADS"/>
+	<value value="100" name="A7XX_PERF_SP_CS_INVOCATIONS"/>
+	<value value="101" name="A7XX_PERF_SP_PIXELS"/>
+	<value value="102" name="A7XX_PERF_SP_LPAC_DRAWCALLS"/>
+	<value value="103" name="A7XX_PERF_SP_PI_WORKING_CYCLES"/>
+	<value value="104" name="A7XX_PERF_SP_WAVE_INPUT_CYCLES"/>
+	<value value="105" name="A7XX_PERF_SP_WAVE_OUTPUT_CYCLES"/>
+	<value value="106" name="A7XX_PERF_SP_WAVE_HWAVE_WAIT_CYCLES"/>
+	<value value="107" name="A7XX_PERF_SP_WAVE_HWAVE_SYNC"/>
+	<value value="108" name="A7XX_PERF_SP_OUTPUT_3D_PIXELS"/>
+	<value value="109" name="A7XX_PERF_SP_FULL_ALU_MAD_INSTRUCTIONS"/>
+	<value value="110" name="A7XX_PERF_SP_HALF_ALU_MAD_INSTRUCTIONS"/>
+	<value value="111" name="A7XX_PERF_SP_FULL_ALU_MUL_INSTRUCTIONS"/>
+	<value value="112" name="A7XX_PERF_SP_HALF_ALU_MUL_INSTRUCTIONS"/>
+	<value value="113" name="A7XX_PERF_SP_FULL_ALU_ADD_INSTRUCTIONS"/>
+	<value value="114" name="A7XX_PERF_SP_HALF_ALU_ADD_INSTRUCTIONS"/>
+	<value value="115" name="A7XX_PERF_SP_BARY_FP32_INSTRUCTIONS"/>
+	<value value="116" name="A7XX_PERF_SP_ALU_GPR_READ_CYCLES"/>
+	<value value="117" name="A7XX_PERF_SP_ALU_DATA_FORWARDING_CYCLES"/>
+	<value value="118" name="A7XX_PERF_SP_LM_FULL_CYCLES"/>
+	<value value="119" name="A7XX_PERF_SP_TEXTURE_FETCH_LATENCY_CYCLES"/>
+	<value value="120" name="A7XX_PERF_SP_TEXTURE_FETCH_LATENCY_SAMPLES"/>
+	<value value="121" name="A7XX_PERF_SP_FS_STAGE_PI_TEX_INSTRUCTION"/>
+	<value value="122" name="A7XX_PERF_SP_RAY_QUERY_INSTRUCTIONS"/>
+	<value value="123" name="A7XX_PERF_SP_RBRT_KICKOFF_FIBERS"/>
+	<value value="124" name="A7XX_PERF_SP_RBRT_KICKOFF_DQUADS"/>
+	<value value="125" name="A7XX_PERF_SP_RTU_BUSY_CYCLES"/>
+	<value value="126" name="A7XX_PERF_SP_RTU_L0_HITS"/>
+	<value value="127" name="A7XX_PERF_SP_RTU_L0_MISSES"/>
+	<value value="128" name="A7XX_PERF_SP_RTU_L0_HIT_ON_MISS"/>
+	<value value="129" name="A7XX_PERF_SP_RTU_STALL_CYCLES_WAVE_QUEUE"/>
+	<value value="130" name="A7XX_PERF_SP_RTU_STALL_CYCLES_L0_HIT_QUEUE"/>
+	<value value="131" name="A7XX_PERF_SP_RTU_STALL_CYCLES_L0_MISS_QUEUE"/>
+	<value value="132" name="A7XX_PERF_SP_RTU_STALL_CYCLES_L0D_IDX_QUEUE"/>
+	<value value="133" name="A7XX_PERF_SP_RTU_STALL_CYCLES_L0DATA"/>
+	<value value="134" name="A7XX_PERF_SP_RTU_STALL_CYCLES_REPLACE_CNT"/>
+	<value value="135" name="A7XX_PERF_SP_RTU_STALL_CYCLES_MRG_CNT"/>
+	<value value="136" name="A7XX_PERF_SP_RTU_STALL_CYCLES_UCHE"/>
+	<value value="137" name="A7XX_PERF_SP_RTU_OPERAND_FETCH_STALL_CYCLES_L0"/>
+	<value value="138" name="A7XX_PERF_SP_RTU_OPERAND_FETCH_STALL_CYCLES_INS_FIFO"/>
+	<value value="139" name="A7XX_PERF_SP_RTU_BVH_FETCH_LATENCY_CYCLES"/>
+	<value value="140" name="A7XX_PERF_SP_RTU_BVH_FETCH_LATENCY_SAMPLES"/>
+	<value value="141" name="A7XX_PERF_SP_STCHE_MISS_INC_VS"/>
+	<value value="142" name="A7XX_PERF_SP_STCHE_MISS_INC_FS"/>
+	<value value="143" name="A7XX_PERF_SP_STCHE_MISS_INC_BV"/>
+	<value value="144" name="A7XX_PERF_SP_STCHE_MISS_INC_LPAC"/>
+	<value value="145" name="A7XX_PERF_SP_VGPR_ACTIVE_CONTEXTS"/>
+	<value value="146" name="A7XX_PERF_SP_PGPR_ALLOC_CONTEXTS"/>
+	<value value="147" name="A7XX_PERF_SP_VGPR_ALLOC_CONTEXTS"/>
+	<value value="148" name="A7XX_PERF_SP_RTU_RAY_BOX_INTERSECTIONS"/>
+	<value value="149" name="A7XX_PERF_SP_RTU_RAY_TRIANGLE_INTERSECTIONS"/>
+	<value value="150" name="A7XX_PERF_SP_SCH_STALL_CYCLES_RTU"/>
+</enum>
+
+<enum name="a7xx_rb_perfcounter_select">
+	<value value="0" name="A7XX_PERF_RB_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_RB_STALL_CYCLES_HLSQ"/>
+	<value value="2" name="A7XX_PERF_RB_STALL_CYCLES_FIFO0_FULL"/>
+	<value value="3" name="A7XX_PERF_RB_STALL_CYCLES_FIFO1_FULL"/>
+	<value value="4" name="A7XX_PERF_RB_STALL_CYCLES_FIFO2_FULL"/>
+	<value value="5" name="A7XX_PERF_RB_STARVE_CYCLES_SP"/>
+	<value value="6" name="A7XX_PERF_RB_STARVE_CYCLES_LRZ_TILE"/>
+	<value value="7" name="A7XX_PERF_RB_STARVE_CYCLES_CCU"/>
+	<value value="8" name="A7XX_PERF_RB_STARVE_CYCLES_Z_PLANE"/>
+	<value value="9" name="A7XX_PERF_RB_STARVE_CYCLES_BARY_PLANE"/>
+	<value value="10" name="A7XX_PERF_RB_Z_WORKLOAD"/>
+	<value value="11" name="A7XX_PERF_RB_HLSQ_ACTIVE"/>
+	<value value="12" name="A7XX_PERF_RB_Z_READ"/>
+	<value value="13" name="A7XX_PERF_RB_Z_WRITE"/>
+	<value value="14" name="A7XX_PERF_RB_C_READ"/>
+	<value value="15" name="A7XX_PERF_RB_C_WRITE"/>
+	<value value="16" name="A7XX_PERF_RB_TOTAL_PASS"/>
+	<value value="17" name="A7XX_PERF_RB_Z_PASS"/>
+	<value value="18" name="A7XX_PERF_RB_Z_FAIL"/>
+	<value value="19" name="A7XX_PERF_RB_S_FAIL"/>
+	<value value="20" name="A7XX_PERF_RB_BLENDED_FXP_COMPONENTS"/>
+	<value value="21" name="A7XX_PERF_RB_BLENDED_FP16_COMPONENTS"/>
+	<value value="22" name="A7XX_PERF_RB_PS_INVOCATIONS"/>
+	<value value="23" name="A7XX_PERF_RB_2D_ALIVE_CYCLES"/>
+	<value value="24" name="A7XX_PERF_RB_2D_STALL_CYCLES_A2D"/>
+	<value value="25" name="A7XX_PERF_RB_2D_STARVE_CYCLES_SRC"/>
+	<value value="26" name="A7XX_PERF_RB_2D_STARVE_CYCLES_SP"/>
+	<value value="27" name="A7XX_PERF_RB_2D_STARVE_CYCLES_DST"/>
+	<value value="28" name="A7XX_PERF_RB_2D_VALID_PIXELS"/>
+	<value value="29" name="A7XX_PERF_RB_3D_PIXELS"/>
+	<value value="30" name="A7XX_PERF_RB_BLENDER_WORKING_CYCLES"/>
+	<value value="31" name="A7XX_PERF_RB_ZPROC_WORKING_CYCLES"/>
+	<value value="32" name="A7XX_PERF_RB_CPROC_WORKING_CYCLES"/>
+	<value value="33" name="A7XX_PERF_RB_SAMPLER_WORKING_CYCLES"/>
+	<value value="34" name="A7XX_PERF_RB_STALL_CYCLES_CCU_COLOR_READ"/>
+	<value value="35" name="A7XX_PERF_RB_STALL_CYCLES_CCU_COLOR_WRITE"/>
+	<value value="36" name="A7XX_PERF_RB_STALL_CYCLES_CCU_DEPTH_READ"/>
+	<value value="37" name="A7XX_PERF_RB_STALL_CYCLES_CCU_DEPTH_WRITE"/>
+	<value value="38" name="A7XX_PERF_RB_STALL_CYCLES_VPC"/>
+	<value value="39" name="A7XX_PERF_RB_2D_INPUT_TRANS"/>
+	<value value="40" name="A7XX_PERF_RB_2D_OUTPUT_RB_DST_TRANS"/>
+	<value value="41" name="A7XX_PERF_RB_2D_OUTPUT_RB_SRC_TRANS"/>
+	<value value="42" name="A7XX_PERF_RB_BLENDED_FP32_COMPONENTS"/>
+	<value value="43" name="A7XX_PERF_RB_COLOR_PIX_TILES"/>
+	<value value="44" name="A7XX_PERF_RB_STALL_CYCLES_CCU"/>
+	<value value="45" name="A7XX_PERF_RB_EARLY_Z_ARB3_GRANT"/>
+	<value value="46" name="A7XX_PERF_RB_LATE_Z_ARB3_GRANT"/>
+	<value value="47" name="A7XX_PERF_RB_EARLY_Z_SKIP_GRANT"/>
+	<value value="48" name="A7XX_PERF_RB_VRS_1x1_QUADS"/>
+	<value value="49" name="A7XX_PERF_RB_VRS_2x1_QUADS"/>
+	<value value="50" name="A7XX_PERF_RB_VRS_1x2_QUADS"/>
+	<value value="51" name="A7XX_PERF_RB_VRS_2x2_QUADS"/>
+	<value value="52" name="A7XX_PERF_RB_VRS_4x2_QUADS"/>
+	<value value="53" name="A7XX_PERF_RB_VRS_4x4_QUADS"/>
+</enum>
+
+<enum name="a7xx_vsc_perfcounter_select">
+	<value value="0" name="A7XX_PERF_VSC_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_VSC_WORKING_CYCLES"/>
+	<value value="2" name="A7XX_PERF_VSC_STALL_CYCLES_UCHE"/>
+	<value value="3" name="A7XX_PERF_VSC_EOT_NUM"/>
+	<value value="4" name="A7XX_PERF_VSC_INPUT_TILES"/>
+</enum>
+
+<enum name="a7xx_ccu_perfcounter_select">
+	<value value="0" name="A7XX_PERF_CCU_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_CCU_STALL_CYCLES_RB_DEPTH_RETURN"/>
+	<value value="2" name="A7XX_PERF_CCU_STALL_CYCLES_RB_COLOR_RETURN"/>
+	<value value="3" name="A7XX_PERF_CCU_DEPTH_BLOCKS"/>
+	<value value="4" name="A7XX_PERF_CCU_COLOR_BLOCKS"/>
+	<value value="5" name="A7XX_PERF_CCU_DEPTH_BLOCK_HIT"/>
+	<value value="6" name="A7XX_PERF_CCU_COLOR_BLOCK_HIT"/>
+	<value value="7" name="A7XX_PERF_CCU_PARTIAL_BLOCK_READ"/>
+	<value value="8" name="A7XX_PERF_CCU_GMEM_READ"/>
+	<value value="9" name="A7XX_PERF_CCU_GMEM_WRITE"/>
+	<value value="10" name="A7XX_PERF_CCU_2D_RD_REQ"/>
+	<value value="11" name="A7XX_PERF_CCU_2D_WR_REQ"/>
+	<value value="12" name="A7XX_PERF_CCU_UBWC_COLOR_BLOCKS_CONCURRENT"/>
+	<value value="13" name="A7XX_PERF_CCU_UBWC_DEPTH_BLOCKS_CONCURRENT"/>
+	<value value="14" name="A7XX_PERF_CCU_COLOR_RESOLVE_DROPPED"/>
+	<value value="15" name="A7XX_PERF_CCU_DEPTH_RESOLVE_DROPPED"/>
+	<value value="16" name="A7XX_PERF_CCU_COLOR_RENDER_CONCURRENT"/>
+	<value value="17" name="A7XX_PERF_CCU_DEPTH_RENDER_CONCURRENT"/>
+	<value value="18" name="A7XX_PERF_CCU_COLOR_RESOLVE_AFTER_RENDER"/>
+	<value value="19" name="A7XX_PERF_CCU_DEPTH_RESOLVE_AFTER_RENDER"/>
+	<value value="20" name="A7XX_PERF_CCU_GMEM_EXTRA_DEPTH_READ"/>
+	<value value="21" name="A7XX_PERF_CCU_GMEM_COLOR_READ_4AA"/>
+	<value value="22" name="A7XX_PERF_CCU_GMEM_COLOR_READ_4AA_FULL"/>
+</enum>
+
+<enum name="a7xx_lrz_perfcounter_select">
+	<value value="0" name="A7XX_PERF_LRZ_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_LRZ_STARVE_CYCLES_RAS"/>
+	<value value="2" name="A7XX_PERF_LRZ_STALL_CYCLES_RB"/>
+	<value value="3" name="A7XX_PERF_LRZ_STALL_CYCLES_VSC"/>
+	<value value="4" name="A7XX_PERF_LRZ_STALL_CYCLES_VPC"/>
+	<value value="5" name="A7XX_PERF_LRZ_STALL_CYCLES_FLAG_PREFETCH"/>
+	<value value="6" name="A7XX_PERF_LRZ_STALL_CYCLES_UCHE"/>
+	<value value="7" name="A7XX_PERF_LRZ_LRZ_READ"/>
+	<value value="8" name="A7XX_PERF_LRZ_LRZ_WRITE"/>
+	<value value="9" name="A7XX_PERF_LRZ_READ_LATENCY"/>
+	<value value="10" name="A7XX_PERF_LRZ_MERGE_CACHE_UPDATING"/>
+	<value value="11" name="A7XX_PERF_LRZ_PRIM_KILLED_BY_MASKGEN"/>
+	<value value="12" name="A7XX_PERF_LRZ_PRIM_KILLED_BY_LRZ"/>
+	<value value="13" name="A7XX_PERF_LRZ_VISIBLE_PRIM_AFTER_LRZ"/>
+	<value value="14" name="A7XX_PERF_LRZ_FULL_8X8_TILES"/>
+	<value value="15" name="A7XX_PERF_LRZ_PARTIAL_8X8_TILES"/>
+	<value value="16" name="A7XX_PERF_LRZ_TILE_KILLED"/>
+	<value value="17" name="A7XX_PERF_LRZ_TOTAL_PIXEL"/>
+	<value value="18" name="A7XX_PERF_LRZ_VISIBLE_PIXEL_AFTER_LRZ"/>
+	<value value="19" name="A7XX_PERF_LRZ_FEEDBACK_ACCEPT"/>
+	<value value="20" name="A7XX_PERF_LRZ_FEEDBACK_DISCARD"/>
+	<value value="21" name="A7XX_PERF_LRZ_FEEDBACK_STALL"/>
+	<value value="22" name="A7XX_PERF_LRZ_STALL_CYCLES_RB_ZPLANE"/>
+	<value value="23" name="A7XX_PERF_LRZ_STALL_CYCLES_RB_BPLANE"/>
+	<value value="24" name="A7XX_PERF_LRZ_RAS_MASK_TRANS"/>
+	<value value="25" name="A7XX_PERF_LRZ_STALL_CYCLES_MVC"/>
+	<value value="26" name="A7XX_PERF_LRZ_TILE_KILLED_BY_IMAGE_VRS"/>
+	<value value="27" name="A7XX_PERF_LRZ_TILE_KILLED_BY_Z"/>
+</enum>
+
+<enum name="a7xx_cmp_perfcounter_select">
+	<value value="0" name="A7XX_PERF_CMPDECMP_STALL_CYCLES_ARB"/>
+	<value value="1" name="A7XX_PERF_CMPDECMP_VBIF_LATENCY_CYCLES"/>
+	<value value="2" name="A7XX_PERF_CMPDECMP_VBIF_LATENCY_SAMPLES"/>
+	<value value="3" name="A7XX_PERF_CMPDECMP_VBIF_READ_DATA_CCU"/>
+	<value value="4" name="A7XX_PERF_CMPDECMP_VBIF_WRITE_DATA_CCU"/>
+	<value value="5" name="A7XX_PERF_CMPDECMP_VBIF_READ_REQUEST"/>
+	<value value="6" name="A7XX_PERF_CMPDECMP_VBIF_WRITE_REQUEST"/>
+	<value value="7" name="A7XX_PERF_CMPDECMP_VBIF_READ_DATA"/>
+	<value value="8" name="A7XX_PERF_CMPDECMP_VBIF_WRITE_DATA"/>
+	<value value="9" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG1_COUNT"/>
+	<value value="10" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG2_COUNT"/>
+	<value value="11" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG3_COUNT"/>
+	<value value="12" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG4_COUNT"/>
+	<value value="13" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG5_COUNT"/>
+	<value value="14" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG6_COUNT"/>
+	<value value="15" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG8_COUNT"/>
+	<value value="16" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG1_COUNT"/>
+	<value value="17" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG2_COUNT"/>
+	<value value="18" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG3_COUNT"/>
+	<value value="19" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG4_COUNT"/>
+	<value value="20" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG5_COUNT"/>
+	<value value="21" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG6_COUNT"/>
+	<value value="22" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG8_COUNT"/>
+	<value value="23" name="A7XX_PERF_CMPDECMP_VBIF_READ_DATA_UCHE_CH0"/>
+	<value value="24" name="A7XX_PERF_CMPDECMP_VBIF_READ_DATA_UCHE_CH1"/>
+	<value value="25" name="A7XX_PERF_CMPDECMP_VBIF_WRITE_DATA_UCHE"/>
+	<value value="26" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG0_COUNT"/>
+	<value value="27" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG0_COUNT"/>
+	<value value="28" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAGALPHA_COUNT"/>
+	<value value="29" name="A7XX_PERF_CMPDECMP_RESOLVE_EVENTS"/>
+	<value value="30" name="A7XX_PERF_CMPDECMP_CONCURRENT_RESOLVE_EVENTS"/>
+	<value value="31" name="A7XX_PERF_CMPDECMP_DROPPED_CLEAR_EVENTS"/>
+	<value value="32" name="A7XX_PERF_CMPDECMP_ST_BLOCKS_CONCURRENT"/>
+	<value value="33" name="A7XX_PERF_CMPDECMP_LRZ_ST_BLOCKS_CONCURRENT"/>
+	<value value="34" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG0_COUNT"/>
+	<value value="35" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG1_COUNT"/>
+	<value value="36" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG2_COUNT"/>
+	<value value="37" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG3_COUNT"/>
+	<value value="38" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG4_COUNT"/>
+	<value value="39" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG5_COUNT"/>
+	<value value="40" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG6_COUNT"/>
+	<value value="41" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG8_COUNT"/>
+	<value value="42" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG0_COUNT"/>
+	<value value="43" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG1_COUNT"/>
+	<value value="44" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG2_COUNT"/>
+	<value value="45" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG3_COUNT"/>
+	<value value="46" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG4_COUNT"/>
+	<value value="47" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG5_COUNT"/>
+	<value value="48" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG6_COUNT"/>
+	<value value="49" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG8_COUNT"/>
+</enum>
+
+<enum name="a7xx_gbif_perfcounter_select">
+	<value value="0" name="A7XX_PERF_GBIF_RESERVED_0"/>
+	<value value="1" name="A7XX_PERF_GBIF_RESERVED_1"/>
+	<value value="2" name="A7XX_PERF_GBIF_RESERVED_2"/>
+	<value value="3" name="A7XX_PERF_GBIF_RESERVED_3"/>
+	<value value="4" name="A7XX_PERF_GBIF_RESERVED_4"/>
+	<value value="5" name="A7XX_PERF_GBIF_RESERVED_5"/>
+	<value value="6" name="A7XX_PERF_GBIF_RESERVED_6"/>
+	<value value="7" name="A7XX_PERF_GBIF_RESERVED_7"/>
+	<value value="8" name="A7XX_PERF_GBIF_RESERVED_8"/>
+	<value value="9" name="A7XX_PERF_GBIF_RESERVED_9"/>
+	<value value="10" name="A7XX_PERF_GBIF_AXI0_READ_REQUESTS_TOTAL"/>
+	<value value="11" name="A7XX_PERF_GBIF_AXI1_READ_REQUESTS_TOTAL"/>
+	<value value="12" name="A7XX_PERF_GBIF_RESERVED_12"/>
+	<value value="13" name="A7XX_PERF_GBIF_RESERVED_13"/>
+	<value value="14" name="A7XX_PERF_GBIF_RESERVED_14"/>
+	<value value="15" name="A7XX_PERF_GBIF_RESERVED_15"/>
+	<value value="16" name="A7XX_PERF_GBIF_RESERVED_16"/>
+	<value value="17" name="A7XX_PERF_GBIF_RESERVED_17"/>
+	<value value="18" name="A7XX_PERF_GBIF_RESERVED_18"/>
+	<value value="19" name="A7XX_PERF_GBIF_RESERVED_19"/>
+	<value value="20" name="A7XX_PERF_GBIF_RESERVED_20"/>
+	<value value="21" name="A7XX_PERF_GBIF_RESERVED_21"/>
+	<value value="22" name="A7XX_PERF_GBIF_AXI0_WRITE_REQUESTS_TOTAL"/>
+	<value value="23" name="A7XX_PERF_GBIF_AXI1_WRITE_REQUESTS_TOTAL"/>
+	<value value="24" name="A7XX_PERF_GBIF_RESERVED_24"/>
+	<value value="25" name="A7XX_PERF_GBIF_RESERVED_25"/>
+	<value value="26" name="A7XX_PERF_GBIF_RESERVED_26"/>
+	<value value="27" name="A7XX_PERF_GBIF_RESERVED_27"/>
+	<value value="28" name="A7XX_PERF_GBIF_RESERVED_28"/>
+	<value value="29" name="A7XX_PERF_GBIF_RESERVED_29"/>
+	<value value="30" name="A7XX_PERF_GBIF_RESERVED_30"/>
+	<value value="31" name="A7XX_PERF_GBIF_RESERVED_31"/>
+	<value value="32" name="A7XX_PERF_GBIF_RESERVED_32"/>
+	<value value="33" name="A7XX_PERF_GBIF_RESERVED_33"/>
+	<value value="34" name="A7XX_PERF_GBIF_AXI0_READ_DATA_BEATS_TOTAL"/>
+	<value value="35" name="A7XX_PERF_GBIF_AXI1_READ_DATA_BEATS_TOTAL"/>
+	<value value="36" name="A7XX_PERF_GBIF_RESERVED_36"/>
+	<value value="37" name="A7XX_PERF_GBIF_RESERVED_37"/>
+	<value value="38" name="A7XX_PERF_GBIF_RESERVED_38"/>
+	<value value="39" name="A7XX_PERF_GBIF_RESERVED_39"/>
+	<value value="40" name="A7XX_PERF_GBIF_RESERVED_40"/>
+	<value value="41" name="A7XX_PERF_GBIF_RESERVED_41"/>
+	<value value="42" name="A7XX_PERF_GBIF_RESERVED_42"/>
+	<value value="43" name="A7XX_PERF_GBIF_RESERVED_43"/>
+	<value value="44" name="A7XX_PERF_GBIF_RESERVED_44"/>
+	<value value="45" name="A7XX_PERF_GBIF_RESERVED_45"/>
+	<value value="46" name="A7XX_PERF_GBIF_AXI0_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="47" name="A7XX_PERF_GBIF_AXI1_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="48" name="A7XX_PERF_GBIF_RESERVED_48"/>
+	<value value="49" name="A7XX_PERF_GBIF_RESERVED_49"/>
+	<value value="50" name="A7XX_PERF_GBIF_RESERVED_50"/>
+	<value value="51" name="A7XX_PERF_GBIF_RESERVED_51"/>
+	<value value="52" name="A7XX_PERF_GBIF_RESERVED_52"/>
+	<value value="53" name="A7XX_PERF_GBIF_RESERVED_53"/>
+	<value value="54" name="A7XX_PERF_GBIF_RESERVED_54"/>
+	<value value="55" name="A7XX_PERF_GBIF_RESERVED_55"/>
+	<value value="56" name="A7XX_PERF_GBIF_RESERVED_56"/>
+	<value value="57" name="A7XX_PERF_GBIF_RESERVED_57"/>
+	<value value="58" name="A7XX_PERF_GBIF_RESERVED_58"/>
+	<value value="59" name="A7XX_PERF_GBIF_RESERVED_59"/>
+	<value value="60" name="A7XX_PERF_GBIF_RESERVED_60"/>
+	<value value="61" name="A7XX_PERF_GBIF_RESERVED_61"/>
+	<value value="62" name="A7XX_PERF_GBIF_RESERVED_62"/>
+	<value value="63" name="A7XX_PERF_GBIF_RESERVED_63"/>
+	<value value="64" name="A7XX_PERF_GBIF_RESERVED_64"/>
+	<value value="65" name="A7XX_PERF_GBIF_RESERVED_65"/>
+	<value value="66" name="A7XX_PERF_GBIF_RESERVED_66"/>
+	<value value="67" name="A7XX_PERF_GBIF_RESERVED_67"/>
+	<value value="68" name="A7XX_PERF_GBIF_CYCLES_CH0_HELD_OFF_RD_ALL"/>
+	<value value="69" name="A7XX_PERF_GBIF_CYCLES_CH1_HELD_OFF_RD_ALL"/>
+	<value value="70" name="A7XX_PERF_GBIF_CYCLES_CH0_HELD_OFF_WR_ALL"/>
+	<value value="71" name="A7XX_PERF_GBIF_CYCLES_CH1_HELD_OFF_WR_ALL"/>
+	<value value="72" name="A7XX_PERF_GBIF_AXI_CH0_REQUEST_HELD_OFF"/>
+	<value value="73" name="A7XX_PERF_GBIF_AXI_CH1_REQUEST_HELD_OFF"/>
+	<value value="74" name="A7XX_PERF_GBIF_AXI_REQUEST_HELD_OFF"/>
+	<value value="75" name="A7XX_PERF_GBIF_AXI_CH0_WRITE_DATA_HELD_OFF"/>
+	<value value="76" name="A7XX_PERF_GBIF_AXI_CH1_WRITE_DATA_HELD_OFF"/>
+	<value value="77" name="A7XX_PERF_GBIF_AXI_ALL_WRITE_DATA_HELD_OFF"/>
+	<value value="78" name="A7XX_PERF_GBIF_AXI_ALL_READ_BEATS"/>
+	<value value="79" name="A7XX_PERF_GBIF_AXI_ALL_WRITE_BEATS"/>
+	<value value="80" name="A7XX_PERF_GBIF_AXI_ALL_BEATS"/>
+</enum>
+
+<enum name="a7xx_ufc_perfcounter_select">
+	<value value="0" name="A7XX_PERF_UFC_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_UFC_READ_DATA_VBIF"/>
+	<value value="2" name="A7XX_PERF_UFC_WRITE_DATA_VBIF"/>
+	<value value="3" name="A7XX_PERF_UFC_READ_REQUEST_VBIF"/>
+	<value value="4" name="A7XX_PERF_UFC_WRITE_REQUEST_VBIF"/>
+	<value value="5" name="A7XX_PERF_UFC_LRZ_FILTER_HIT"/>
+	<value value="6" name="A7XX_PERF_UFC_LRZ_FILTER_MISS"/>
+	<value value="7" name="A7XX_PERF_UFC_CRE_FILTER_HIT"/>
+	<value value="8" name="A7XX_PERF_UFC_CRE_FILTER_MISS"/>
+	<value value="9" name="A7XX_PERF_UFC_SP_FILTER_HIT"/>
+	<value value="10" name="A7XX_PERF_UFC_SP_FILTER_MISS"/>
+	<value value="11" name="A7XX_PERF_UFC_SP_REQUESTS"/>
+	<value value="12" name="A7XX_PERF_UFC_TP_FILTER_HIT"/>
+	<value value="13" name="A7XX_PERF_UFC_TP_FILTER_MISS"/>
+	<value value="14" name="A7XX_PERF_UFC_TP_REQUESTS"/>
+	<value value="15" name="A7XX_PERF_UFC_MAIN_HIT_LRZ_PREFETCH"/>
+	<value value="16" name="A7XX_PERF_UFC_MAIN_HIT_CRE_PREFETCH"/>
+	<value value="17" name="A7XX_PERF_UFC_MAIN_HIT_SP_PREFETCH"/>
+	<value value="18" name="A7XX_PERF_UFC_MAIN_HIT_TP_PREFETCH"/>
+	<value value="19" name="A7XX_PERF_UFC_MAIN_HIT_UBWC_READ"/>
+	<value value="20" name="A7XX_PERF_UFC_MAIN_HIT_UBWC_WRITE"/>
+	<value value="21" name="A7XX_PERF_UFC_MAIN_MISS_LRZ_PREFETCH"/>
+	<value value="22" name="A7XX_PERF_UFC_MAIN_MISS_CRE_PREFETCH"/>
+	<value value="23" name="A7XX_PERF_UFC_MAIN_MISS_SP_PREFETCH"/>
+	<value value="24" name="A7XX_PERF_UFC_MAIN_MISS_TP_PREFETCH"/>
+	<value value="25" name="A7XX_PERF_UFC_MAIN_MISS_UBWC_READ"/>
+	<value value="26" name="A7XX_PERF_UFC_MAIN_MISS_UBWC_WRITE"/>
+	<value value="27" name="A7XX_PERF_UFC_UBWC_READ_UFC_TRANS"/>
+	<value value="28" name="A7XX_PERF_UFC_UBWC_WRITE_UFC_TRANS"/>
+	<value value="29" name="A7XX_PERF_UFC_STALL_CYCLES_GBIF_CMD"/>
+	<value value="30" name="A7XX_PERF_UFC_STALL_CYCLES_GBIF_RDATA"/>
+	<value value="31" name="A7XX_PERF_UFC_STALL_CYCLES_GBIF_WDATA"/>
+	<value value="32" name="A7XX_PERF_UFC_STALL_CYCLES_UBWC_WR_FLAG"/>
+	<value value="33" name="A7XX_PERF_UFC_STALL_CYCLES_UBWC_FLAG_RTN"/>
+	<value value="34" name="A7XX_PERF_UFC_STALL_CYCLES_UBWC_EVENT"/>
+	<value value="35" name="A7XX_PERF_UFC_LRZ_PREFETCH_STALLED_CYCLES"/>
+	<value value="36" name="A7XX_PERF_UFC_CRE_PREFETCH_STALLED_CYCLES"/>
+	<value value="37" name="A7XX_PERF_UFC_SPTP_PREFETCH_STALLED_CYCLES"/>
+	<value value="38" name="A7XX_PERF_UFC_UBWC_RD_STALLED_CYCLES"/>
+	<value value="39" name="A7XX_PERF_UFC_UBWC_WR_STALLED_CYCLES"/>
+	<value value="40" name="A7XX_PERF_UFC_PREFETCH_STALLED_CYCLES"/>
+	<value value="41" name="A7XX_PERF_UFC_EVICTION_STALLED_CYCLES"/>
+	<value value="42" name="A7XX_PERF_UFC_LOCK_STALLED_CYCLES"/>
+	<value value="43" name="A7XX_PERF_UFC_MISS_LATENCY_CYCLES"/>
+	<value value="44" name="A7XX_PERF_UFC_MISS_LATENCY_SAMPLES"/>
+	<value value="45" name="A7XX_PERF_UFC_UBWC_REQ_STALLED_CYCLES"/>
+	<value value="46" name="A7XX_PERF_UFC_TP_HINT_TAG_MISS"/>
+	<value value="47" name="A7XX_PERF_UFC_TP_HINT_TAG_HIT_RDY"/>
+	<value value="48" name="A7XX_PERF_UFC_TP_HINT_TAG_HIT_NRDY"/>
+	<value value="49" name="A7XX_PERF_UFC_TP_HINT_IS_FCLEAR"/>
+	<value value="50" name="A7XX_PERF_UFC_TP_HINT_IS_ALPHA0"/>
+	<value value="51" name="A7XX_PERF_UFC_SP_L1_FILTER_HIT"/>
+	<value value="52" name="A7XX_PERF_UFC_SP_L1_FILTER_MISS"/>
+	<value value="53" name="A7XX_PERF_UFC_SP_L1_FILTER_REQUESTS"/>
+	<value value="54" name="A7XX_PERF_UFC_TP_L1_TAG_HIT_RDY"/>
+	<value value="55" name="A7XX_PERF_UFC_TP_L1_TAG_HIT_NRDY"/>
+	<value value="56" name="A7XX_PERF_UFC_TP_L1_TAG_MISS"/>
+	<value value="57" name="A7XX_PERF_UFC_TP_L1_FILTER_REQUESTS"/>
+</enum>
+
+<domain name="A6XX" width="32" prefix="variant" varset="chip">
+	<bitset name="A6XX_RBBM_INT_0_MASK" inline="no" varset="chip">
+		<bitfield name="RBBM_GPU_IDLE" pos="0" type="boolean"/>
+		<bitfield name="CP_AHB_ERROR" pos="1" type="boolean"/>
+		<bitfield name="CP_IPC_INTR_0" pos="4" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_IPC_INTR_1" pos="5" type="boolean" variants="A7XX-"/>
+		<bitfield name="RBBM_ATB_ASYNCFIFO_OVERFLOW" pos="6" type="boolean"/>
+		<bitfield name="RBBM_GPC_ERROR" pos="7" type="boolean"/>
+		<bitfield name="CP_SW" pos="8" type="boolean"/>
+		<bitfield name="CP_HW_ERROR" pos="9" type="boolean"/>
+		<bitfield name="CP_CCU_FLUSH_DEPTH_TS" pos="10" type="boolean"/>
+		<bitfield name="CP_CCU_FLUSH_COLOR_TS" pos="11" type="boolean"/>
+		<bitfield name="CP_CCU_RESOLVE_TS" pos="12" type="boolean"/>
+		<bitfield name="CP_IB2" pos="13" type="boolean"/>
+		<bitfield name="CP_IB1" pos="14" type="boolean"/>
+		<bitfield name="CP_RB" pos="15" type="boolean" variants="A6XX"/>
+		<!-- Same as above but different name??: -->
+		<bitfield name="PM4CPINTERRUPT" pos="15" type="boolean" variants="A7XX-"/>
+		<bitfield name="PM4CPINTERRUPTLPAC" pos="16" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_RB_DONE_TS" pos="17" type="boolean"/>
+		<bitfield name="CP_WT_DONE_TS" pos="18" type="boolean"/>
+		<bitfield name="CP_CACHE_FLUSH_TS" pos="20" type="boolean"/>
+		<bitfield name="CP_CACHE_FLUSH_TS_LPAC" pos="21" type="boolean" variants="A7XX-"/>
+		<bitfield name="RBBM_ATB_BUS_OVERFLOW" pos="22" type="boolean"/>
+		<bitfield name="RBBM_HANG_DETECT" pos="23" type="boolean"/>
+		<bitfield name="UCHE_OOB_ACCESS" pos="24" type="boolean"/>
+		<bitfield name="UCHE_TRAP_INTR" pos="25" type="boolean"/>
+		<bitfield name="DEBBUS_INTR_0" pos="26" type="boolean"/>
+		<bitfield name="DEBBUS_INTR_1" pos="27" type="boolean"/>
+		<bitfield name="TSBWRITEERROR" pos="28" type="boolean" variants="A7XX-"/>
+		<bitfield name="SWFUSEVIOLATION" pos="29" type="boolean" variants="A7XX-"/>
+		<bitfield name="ISDB_CPU_IRQ" pos="30" type="boolean"/>
+		<bitfield name="ISDB_UNDER_DEBUG" pos="31" type="boolean"/>
+	</bitset>
+
+	<!--
+		Note the _LPAC bits probably *actually* first appeared in a660, but the
+		_BV bits are new in a7xx
+	 -->
+	<bitset name="A6XX_CP_INT" varset="chip">
+		<bitfield name="CP_OPCODE_ERROR" pos="0" type="boolean"/>
+		<bitfield name="CP_UCODE_ERROR" pos="1" type="boolean"/>
+		<bitfield name="CP_HW_FAULT_ERROR" pos="2" type="boolean"/>
+		<bitfield name="CP_REGISTER_PROTECTION_ERROR" pos="4" type="boolean"/>
+		<bitfield name="CP_AHB_ERROR" pos="5" type="boolean"/>
+		<bitfield name="CP_VSD_PARITY_ERROR" pos="6" type="boolean"/>
+		<bitfield name="CP_ILLEGAL_INSTR_ERROR" pos="7" type="boolean"/>
+		<bitfield name="CP_OPCODE_ERROR_LPAC" pos="8" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_UCODE_ERROR_LPAC" pos="9" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_HW_FAULT_ERROR_LPAC" pos="10" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_REGISTER_PROTECTION_ERROR_LPAC" pos="11" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_ILLEGAL_INSTR_ERROR_LPAC" pos="12" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_OPCODE_ERROR_BV" pos="13" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_UCODE_ERROR_BV" pos="14" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_HW_FAULT_ERROR_BV" pos="15" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_REGISTER_PROTECTION_ERROR_BV" pos="16" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_ILLEGAL_INSTR_ERROR_BV" pos="17" type="boolean" variants="A7XX-"/>
+	</bitset>
+
+	<reg64 offset="0x0800" name="CP_RB_BASE"/>
+	<reg32 offset="0x0802" name="CP_RB_CNTL"/>
+	<reg64 offset="0x0804" name="CP_RB_RPTR_ADDR"/>
+	<reg32 offset="0x0806" name="CP_RB_RPTR"/>
+	<reg32 offset="0x0807" name="CP_RB_WPTR"/>
+	<reg32 offset="0x0808" name="CP_SQE_CNTL"/>
+	<reg32 offset="0x0812" name="CP_CP2GMU_STATUS">
+		<bitfield name="IFPC" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0821" name="CP_HW_FAULT"/>
+	<reg32 offset="0x0823" name="CP_INTERRUPT_STATUS" type="A6XX_CP_INT"/>
+	<reg32 offset="0x0824" name="CP_PROTECT_STATUS"/>
+	<reg32 offset="0x0825" name="CP_STATUS_1"/>
+	<reg64 offset="0x0830" name="CP_SQE_INSTR_BASE"/>
+	<reg32 offset="0x0840" name="CP_MISC_CNTL"/>
+	<reg32 offset="0x0844" name="CP_APRIV_CNTL">
+		<!-- Crashdumper writes -->
+		<bitfield pos="6" name="CDWRITE" type="boolean"/>
+		<!-- Crashdumper reads -->
+		<bitfield pos="5" name="CDREAD" type="boolean"/>
+
+		<!-- 4 is unknown -->
+
+		<!-- RPTR shadow writes -->
+		<bitfield pos="3" name="RBRPWB" type="boolean"/>
+		<!-- Memory accesses from PM4 packets in the ringbuffer -->
+		<bitfield pos="2" name="RBPRIVLEVEL" type="boolean"/>
+		<!-- Ringbuffer reads -->
+		<bitfield pos="1" name="RBFETCH" type="boolean"/>
+		<!-- Instruction cache fetches -->
+		<bitfield pos="0" name="ICACHE" type="boolean"/>
+	</reg32>
+	<!-- Preemptions taking longer than this threshold increment PERF_CP_LONG_PREEMPTIONS: -->
+	<reg32 offset="0x08C0" name="CP_PREEMPT_THRESHOLD"/>
+	<!-- all the threshold values seem to be in units of quad-dwords: -->
+	<reg32 offset="0x08C1" name="CP_ROQ_THRESHOLDS_1">
+		<doc>
+			b0..7 identifies where MRB data starts (and RB data ends)
+			b8.15 identifies where VSD data starts (and MRB data ends)
+			b16..23 identifies where IB1 data starts (and RB data ends)
+			b24..31 identifies where IB2 data starts (and IB1 data ends)
+		</doc>
+		<bitfield name="MRB_START" low="0" high="7" shr="2"/>
+		<bitfield name="VSD_START" low="8" high="15" shr="2"/>
+		<bitfield name="IB1_START" low="16" high="23" shr="2"/>
+		<bitfield name="IB2_START" low="24" high="31" shr="2"/>
+	</reg32>
+	<reg32 offset="0x08C2" name="CP_ROQ_THRESHOLDS_2">
+		<doc>
+			low bits identify where CP_SET_DRAW_STATE stateobj
+			processing starts (and IB2 data ends). I'm guessing
+			b8 is part of this since (from downstream kgsl):
+
+				/* ROQ sizes are twice as big on a640/a680 than on a630 */
+				if (adreno_is_a640(adreno_dev) || adreno_is_a680(adreno_dev)) {
+					kgsl_regwrite(device, A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140);
+					kgsl_regwrite(device, A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362C);
+				} ...
+		</doc>
+		<bitfield name="SDS_START" low="0" high="8" shr="2"/>
+		<!-- total ROQ size: -->
+		<bitfield name="ROQ_SIZE" low="16" high="31" shr="2"/>
+	</reg32>
+	<reg32 offset="0x08C3" name="CP_MEM_POOL_SIZE"/>
+	<reg32 offset="0x0841" name="CP_CHICKEN_DBG"/>
+	<reg32 offset="0x0842" name="CP_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0843" name="CP_DBG_ECO_CNTL"/>
+	<reg32 offset="0x084F" name="CP_PROTECT_CNTL">
+		<bitfield pos="3" name="LAST_SPAN_INF_RANGE" type="boolean"/>
+		<bitfield pos="1" name="ACCESS_FAULT_ON_VIOL_EN" type="boolean"/>
+		<bitfield pos="0" name="ACCESS_PROT_EN" type="boolean"/>
+	</reg32>
+
+	<array offset="0x0883" name="CP_SCRATCH" stride="1" length="8">
+		<reg32 offset="0x0" name="REG" type="uint"/>
+	</array>
+	<array offset="0x0850" name="CP_PROTECT" stride="1" length="32">
+		<reg32 offset="0x0" name="REG" type="a6x_cp_protect"/>
+	</array>
+
+	<reg32 offset="0x08A0" name="CP_CONTEXT_SWITCH_CNTL">
+		<bitfield name="STOP" pos="0" type="boolean"/>
+		<bitfield name="LEVEL" low="6" high="7"/>
+		<bitfield name="USES_GMEM" pos="8" type="boolean"/>
+		<bitfield name="SKIP_SAVE_RESTORE" pos="9" type="boolean"/>
+	</reg32>
+	<reg64 offset="0x08A1" name="CP_CONTEXT_SWITCH_SMMU_INFO"/>
+	<reg64 offset="0x08A3" name="CP_CONTEXT_SWITCH_PRIV_NON_SECURE_RESTORE_ADDR"/>
+	<reg64 offset="0x08A5" name="CP_CONTEXT_SWITCH_PRIV_SECURE_RESTORE_ADDR"/>
+	<reg64 offset="0x08A7" name="CP_CONTEXT_SWITCH_NON_PRIV_RESTORE_ADDR"/>
+	<reg32 offset="0x08ab" name="CP_CONTEXT_SWITCH_LEVEL_STATUS" variants="A7XX-"/>
+	<array offset="0x08D0" name="CP_PERFCTR_CP_SEL" stride="1" length="14"/>
+	<array offset="0x08e0" name="CP_BV_PERFCTR_CP_SEL" stride="1" length="7" variants="A7XX-"/>
+	<reg64 offset="0x0900" name="CP_CRASH_SCRIPT_BASE"/>
+	<reg32 offset="0x0902" name="CP_CRASH_DUMP_CNTL"/>
+	<reg32 offset="0x0903" name="CP_CRASH_DUMP_STATUS"/>
+	<reg32 offset="0x0908" name="CP_SQE_STAT_ADDR"/>
+	<reg32 offset="0x0909" name="CP_SQE_STAT_DATA"/>
+	<reg32 offset="0x090A" name="CP_DRAW_STATE_ADDR"/>
+	<reg32 offset="0x090B" name="CP_DRAW_STATE_DATA"/>
+	<reg32 offset="0x090C" name="CP_ROQ_DBG_ADDR"/>
+	<reg32 offset="0x090D" name="CP_ROQ_DBG_DATA"/>
+	<reg32 offset="0x090E" name="CP_MEM_POOL_DBG_ADDR"/>
+	<reg32 offset="0x090F" name="CP_MEM_POOL_DBG_DATA"/>
+	<reg32 offset="0x0910" name="CP_SQE_UCODE_DBG_ADDR"/>
+	<reg32 offset="0x0911" name="CP_SQE_UCODE_DBG_DATA"/>
+	<reg64 offset="0x0928" name="CP_IB1_BASE"/>
+	<reg32 offset="0x092A" name="CP_IB1_REM_SIZE"/>
+	<reg64 offset="0x092B" name="CP_IB2_BASE"/>
+	<reg32 offset="0x092D" name="CP_IB2_REM_SIZE"/>
+	<!-- SDS == CP_SET_DRAW_STATE: -->
+	<reg64 offset="0x092e" name="CP_SDS_BASE"/>
+	<reg32 offset="0x0930" name="CP_SDS_REM_SIZE"/>
+	<!-- MRB == MEM_READ_ADDR/$addr in SQE firmware -->
+	<reg64 offset="0x0931" name="CP_MRB_BASE"/>
+	<reg32 offset="0x0933" name="CP_MRB_REM_SIZE"/>
+	<!--
+	VSD == Visibility Stream Decode
+	This is used by CP to read the draw stream and skip empty draws
+	-->
+	<reg64 offset="0x0934" name="CP_VSD_BASE"/>
+
+	<bitset name="a6xx_roq_stat" inline="yes">
+		<bitfield name="RPTR" low="0" high="9"/>
+		<bitfield name="WPTR" low="16" high="25"/>
+	</bitset>
+	<reg32 offset="0x0939" name="CP_ROQ_RB_STAT" type="a6xx_roq_stat"/>
+	<reg32 offset="0x093a" name="CP_ROQ_IB1_STAT" type="a6xx_roq_stat"/>
+	<reg32 offset="0x093b" name="CP_ROQ_IB2_STAT" type="a6xx_roq_stat"/>
+	<reg32 offset="0x093c" name="CP_ROQ_SDS_STAT" type="a6xx_roq_stat"/>
+	<reg32 offset="0x093d" name="CP_ROQ_MRB_STAT" type="a6xx_roq_stat"/>
+	<reg32 offset="0x093e" name="CP_ROQ_VSD_STAT" type="a6xx_roq_stat"/>
+
+	<reg32 offset="0x0943" name="CP_IB1_DWORDS"/>
+	<reg32 offset="0x0944" name="CP_IB2_DWORDS"/>
+	<reg32 offset="0x0945" name="CP_SDS_DWORDS"/>
+	<reg32 offset="0x0946" name="CP_MRB_DWORDS"/>
+	<reg32 offset="0x0947" name="CP_VSD_DWORDS"/>
+
+	<reg32 offset="0x0948" name="CP_ROQ_AVAIL_RB">
+		<doc>number of remaining dwords incl current dword being consumed?</doc>
+		<bitfield name="REM" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="0x0949" name="CP_ROQ_AVAIL_IB1">
+		<doc>number of remaining dwords incl current dword being consumed?</doc>
+		<bitfield name="REM" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="0x094a" name="CP_ROQ_AVAIL_IB2">
+		<doc>number of remaining dwords incl current dword being consumed?</doc>
+		<bitfield name="REM" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="0x094b" name="CP_ROQ_AVAIL_SDS">
+		<doc>number of remaining dwords incl current dword being consumed?</doc>
+		<bitfield name="REM" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="0x094c" name="CP_ROQ_AVAIL_MRB">
+		<doc>number of dwords that have already been read but haven't been consumed by $addr</doc>
+		<bitfield name="REM" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="0x094d" name="CP_ROQ_AVAIL_VSD">
+		<doc>number of remaining dwords incl current dword being consumed?</doc>
+		<bitfield name="REM" low="16" high="31"/>
+	</reg32>
+
+	<bitset name="a7xx_aperture_cntl" inline="yes">
+		<bitfield name="PIPE" low="12" high="13" type="a7xx_pipe"/>
+		<bitfield name="CLUSTER" low="8" high="10" type="a7xx_cluster"/>
+		<bitfield name="CONTEXT" low="4" high="5"/>
+	</bitset>
+	<reg64 offset="0x0980" name="CP_ALWAYS_ON_COUNTER"/>
+	<reg32 offset="0x098D" name="CP_AHB_CNTL"/>
+	<reg32 offset="0x0A00" name="CP_APERTURE_CNTL_HOST" variants="A6XX"/>
+	<reg32 offset="0x0A00" name="CP_APERTURE_CNTL_HOST" type="a7xx_aperture_cntl" variants="A7XX-"/>
+	<reg32 offset="0x0A03" name="CP_APERTURE_CNTL_CD" variants="A6XX"/>
+	<reg32 offset="0x0A03" name="CP_APERTURE_CNTL_CD" type="a7xx_aperture_cntl" variants="A7XX-"/>
+
+	<reg32 offset="0x0a61" name="CP_BV_PROTECT_STATUS" variants="A7XX-"/>
+	<reg32 offset="0x0a64" name="CP_BV_HW_FAULT" variants="A7XX-"/>
+	<reg32 offset="0x0a81" name="CP_BV_DRAW_STATE_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0a82" name="CP_BV_DRAW_STATE_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0a83" name="CP_BV_ROQ_DBG_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0a84" name="CP_BV_ROQ_DBG_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0a85" name="CP_BV_SQE_UCODE_DBG_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0a86" name="CP_BV_SQE_UCODE_DBG_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0a87" name="CP_BV_SQE_STAT_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0a88" name="CP_BV_SQE_STAT_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0a96" name="CP_BV_MEM_POOL_DBG_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0a97" name="CP_BV_MEM_POOL_DBG_DATA" variants="A7XX-"/>
+	<reg64 offset="0x0a98" name="CP_BV_RB_RPTR_ADDR" variants="A7XX-"/>
+
+	<reg32 offset="0x0a9a" name="CP_RESOURCE_TBL_DBG_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0a9b" name="CP_RESOURCE_TBL_DBG_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0ad0" name="CP_BV_APRIV_CNTL" variants="A7XX-"/>
+	<reg32 offset="0x0ada" name="CP_BV_CHICKEN_DBG" variants="A7XX-"/>
+
+	<reg32 offset="0x0b0a" name="CP_LPAC_DRAW_STATE_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0b0b" name="CP_LPAC_DRAW_STATE_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0b0c" name="CP_LPAC_ROQ_DBG_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0b27" name="CP_SQE_AC_UCODE_DBG_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0b28" name="CP_SQE_AC_UCODE_DBG_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0b29" name="CP_SQE_AC_STAT_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0b2a" name="CP_SQE_AC_STAT_DATA" variants="A7XX-"/>
+
+	<reg32 offset="0x0b31" name="CP_LPAC_APRIV_CNTL" variants="A7XX-"/>
+	<reg32 offset="0x0B34" name="CP_LPAC_PROG_FIFO_SIZE"/>
+	<reg32 offset="0x0b35" name="CP_LPAC_ROQ_DBG_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0b36" name="CP_LPAC_FIFO_DBG_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0b40" name="CP_LPAC_FIFO_DBG_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0b81" name="CP_LPAC_SQE_CNTL"/>
+	<reg64 offset="0x0b82" name="CP_LPAC_SQE_INSTR_BASE"/>
+
+	<reg64 offset="0x0b70" name="CP_AQE_INSTR_BASE_0" variants="A7XX-"/>
+	<reg64 offset="0x0b72" name="CP_AQE_INSTR_BASE_1" variants="A7XX-"/>
+	<reg32 offset="0x0b78" name="CP_AQE_APRIV_CNTL" variants="A7XX-"/>
+
+	<reg32 offset="0x0ba8" name="CP_AQE_ROQ_DBG_ADDR_0" variants="A7XX-"/>
+	<reg32 offset="0x0ba9" name="CP_AQE_ROQ_DBG_ADDR_1" variants="A7XX-"/>
+	<reg32 offset="0x0bac" name="CP_AQE_ROQ_DBG_DATA_0" variants="A7XX-"/>
+	<reg32 offset="0x0bad" name="CP_AQE_ROQ_DBG_DATA_1" variants="A7XX-"/>
+	<reg32 offset="0x0bb0" name="CP_AQE_UCODE_DBG_ADDR_0" variants="A7XX-"/>
+	<reg32 offset="0x0bb1" name="CP_AQE_UCODE_DBG_ADDR_1" variants="A7XX-"/>
+	<reg32 offset="0x0bb4" name="CP_AQE_UCODE_DBG_DATA_0" variants="A7XX-"/>
+	<reg32 offset="0x0bb5" name="CP_AQE_UCODE_DBG_DATA_1" variants="A7XX-"/>
+	<reg32 offset="0x0bb8" name="CP_AQE_STAT_ADDR_0" variants="A7XX-"/>
+	<reg32 offset="0x0bb9" name="CP_AQE_STAT_ADDR_1" variants="A7XX-"/>
+	<reg32 offset="0x0bbc" name="CP_AQE_STAT_DATA_0" variants="A7XX-"/>
+	<reg32 offset="0x0bbd" name="CP_AQE_STAT_DATA_1" variants="A7XX-"/>
+
+	<reg32 offset="0x0C01" name="VSC_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0018" name="RBBM_GPR0_CNTL"/>
+	<reg32 offset="0x0201" name="RBBM_INT_0_STATUS" type="A6XX_RBBM_INT_0_MASK"/>
+	<reg32 offset="0x0210" name="RBBM_STATUS">
+		<bitfield pos="23" name="GPU_BUSY_IGN_AHB" type="boolean"/>
+		<bitfield pos="22" name="GPU_BUSY_IGN_AHB_CP" type="boolean"/>
+		<bitfield pos="21" name="HLSQ_BUSY" type="boolean"/>
+		<bitfield pos="20" name="VSC_BUSY" type="boolean"/>
+		<bitfield pos="19" name="TPL1_BUSY" type="boolean"/>
+		<bitfield pos="18" name="SP_BUSY" type="boolean"/>
+		<bitfield pos="17" name="UCHE_BUSY" type="boolean"/>
+		<bitfield pos="16" name="VPC_BUSY" type="boolean"/>
+		<bitfield pos="15" name="VFD_BUSY" type="boolean"/>
+		<bitfield pos="14" name="TESS_BUSY" type="boolean"/>
+		<bitfield pos="13" name="PC_VSD_BUSY" type="boolean"/>
+		<bitfield pos="12" name="PC_DCALL_BUSY" type="boolean"/>
+		<bitfield pos="11" name="COM_DCOM_BUSY" type="boolean"/>
+		<bitfield pos="10" name="LRZ_BUSY" type="boolean"/>
+		<bitfield pos="9"  name="A2D_BUSY" type="boolean"/>
+		<bitfield pos="8"  name="CCU_BUSY" type="boolean"/>
+		<bitfield pos="7"  name="RB_BUSY" type="boolean"/>
+		<bitfield pos="6"  name="RAS_BUSY" type="boolean"/>
+		<bitfield pos="5"  name="TSE_BUSY" type="boolean"/>
+		<bitfield pos="4"  name="VBIF_BUSY" type="boolean"/>
+		<bitfield pos="3"  name="GFX_DBGC_BUSY" type="boolean"/>
+		<bitfield pos="2"  name="CP_BUSY" type="boolean"/>
+		<bitfield pos="1"  name="CP_AHB_BUSY_CP_MASTER" type="boolean"/>
+		<bitfield pos="0"  name="CP_AHB_BUSY_CX_MASTER" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0211" name="RBBM_STATUS1"/>
+	<reg32 offset="0x0212" name="RBBM_STATUS2"/>
+	<reg32 offset="0x0213" name="RBBM_STATUS3">
+		<bitfield pos="24" name="SMMU_STALLED_ON_FAULT" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0215" name="RBBM_VBIF_GX_RESET_STATUS"/>
+
+	<reg32 offset="0x0260" name="RBBM_CLOCK_MODE_CP" variants="A7XX-"/>
+	<reg32 offset="0x0284" name="RBBM_CLOCK_MODE_BV_LRZ" variants="A7XX-"/>
+	<reg32 offset="0x0285" name="RBBM_CLOCK_MODE_BV_GRAS" variants="A7XX-"/>
+	<reg32 offset="0x0286" name="RBBM_CLOCK_MODE2_GRAS" variants="A7XX-"/>
+	<reg32 offset="0x0287" name="RBBM_CLOCK_MODE_BV_VFD" variants="A7XX-"/>
+	<reg32 offset="0x0288" name="RBBM_CLOCK_MODE_BV_GPC" variants="A7XX-"/>
+
+	<reg32 offset="0x02c0" name="RBBM_SW_FUSE_INT_STATUS" variants="A7XX-"/>
+	<reg32 offset="0x02c1" name="RBBM_SW_FUSE_INT_MASK" variants="A7XX-"/>
+
+	<array offset="0x0400" name="RBBM_PERFCTR_CP" stride="2" length="14" variants="A6XX"/>
+	<array offset="0x041c" name="RBBM_PERFCTR_RBBM" stride="2" length="4" variants="A6XX"/>
+	<array offset="0x0424" name="RBBM_PERFCTR_PC" stride="2" length="8" variants="A6XX"/>
+	<array offset="0x0434" name="RBBM_PERFCTR_VFD" stride="2" length="8" variants="A6XX"/>
+	<array offset="0x0444" name="RBBM_PERFCTR_HLSQ" stride="2" length="6" variants="A6XX"/>
+	<array offset="0x0450" name="RBBM_PERFCTR_VPC" stride="2" length="6" variants="A6XX"/>
+	<array offset="0x045c" name="RBBM_PERFCTR_CCU" stride="2" length="5" variants="A6XX"/>
+	<array offset="0x0466" name="RBBM_PERFCTR_TSE" stride="2" length="4" variants="A6XX"/>
+	<array offset="0x046e" name="RBBM_PERFCTR_RAS" stride="2" length="4" variants="A6XX"/>
+	<array offset="0x0476" name="RBBM_PERFCTR_UCHE" stride="2" length="12" variants="A6XX"/>
+	<array offset="0x048e" name="RBBM_PERFCTR_TP" stride="2" length="12" variants="A6XX"/>
+	<array offset="0x04a6" name="RBBM_PERFCTR_SP" stride="2" length="24" variants="A6XX"/>
+	<array offset="0x04d6" name="RBBM_PERFCTR_RB" stride="2" length="8" variants="A6XX"/>
+	<array offset="0x04e6" name="RBBM_PERFCTR_VSC" stride="2" length="2" variants="A6XX"/>
+	<array offset="0x04ea" name="RBBM_PERFCTR_LRZ" stride="2" length="4" variants="A6XX"/>
+	<array offset="0x04f2" name="RBBM_PERFCTR_CMP" stride="2" length="4" variants="A6XX"/>
+
+	<array offset="0x0300" name="RBBM_PERFCTR_CP" stride="2" length="14" variants="A7XX-"/>
+	<array offset="0x031c" name="RBBM_PERFCTR_RBBM" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x0324" name="RBBM_PERFCTR_PC" stride="2" length="8" variants="A7XX-"/>
+	<array offset="0x0334" name="RBBM_PERFCTR_VFD" stride="2" length="8" variants="A7XX-"/>
+	<array offset="0x0344" name="RBBM_PERFCTR_HLSQ" stride="2" length="6" variants="A7XX-"/>
+	<array offset="0x0350" name="RBBM_PERFCTR_VPC" stride="2" length="6" variants="A7XX-"/>
+	<array offset="0x035c" name="RBBM_PERFCTR_CCU" stride="2" length="5" variants="A7XX-"/>
+	<array offset="0x0366" name="RBBM_PERFCTR_TSE" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x036e" name="RBBM_PERFCTR_RAS" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x0376" name="RBBM_PERFCTR_UCHE" stride="2" length="12" variants="A7XX-"/>
+	<array offset="0x038e" name="RBBM_PERFCTR_TP" stride="2" length="12" variants="A7XX-"/>
+	<array offset="0x03a6" name="RBBM_PERFCTR_SP" stride="2" length="24" variants="A7XX-"/>
+	<array offset="0x03d6" name="RBBM_PERFCTR_RB" stride="2" length="8" variants="A7XX-"/>
+	<array offset="0x03e6" name="RBBM_PERFCTR_VSC" stride="2" length="2" variants="A7XX-"/>
+	<array offset="0x03ea" name="RBBM_PERFCTR_LRZ" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x03f2" name="RBBM_PERFCTR_CMP" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x03fa" name="RBBM_PERFCTR_UFC" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x0410" name="RBBM_PERFCTR2_HLSQ" stride="2" length="6" variants="A7XX-"/>
+	<array offset="0x041c" name="RBBM_PERFCTR2_CP" stride="2" length="7" variants="A7XX-"/>
+	<array offset="0x042a" name="RBBM_PERFCTR2_SP" stride="2" length="12" variants="A7XX-"/>
+	<array offset="0x0442" name="RBBM_PERFCTR2_TP" stride="2" length="6" variants="A7XX-"/>
+	<array offset="0x044e" name="RBBM_PERFCTR2_UFC" stride="2" length="2" variants="A7XX-"/>
+	<array offset="0x0460" name="RBBM_PERFCTR_BV_PC" stride="2" length="8" variants="A7XX-"/>
+	<array offset="0x0470" name="RBBM_PERFCTR_BV_VFD" stride="2" length="8" variants="A7XX-"/>
+	<array offset="0x0480" name="RBBM_PERFCTR_BV_VPC" stride="2" length="6" variants="A7XX-"/>
+	<array offset="0x048c" name="RBBM_PERFCTR_BV_TSE" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x0494" name="RBBM_PERFCTR_BV_RAS" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x049c" name="RBBM_PERFCTR_BV_LRZ" stride="2" length="4" variants="A7XX-"/>
+
+	<reg32 offset="0x0500" name="RBBM_PERFCTR_CNTL"/>
+	<reg32 offset="0x0501" name="RBBM_PERFCTR_LOAD_CMD0"/>
+	<reg32 offset="0x0502" name="RBBM_PERFCTR_LOAD_CMD1"/>
+	<reg32 offset="0x0503" name="RBBM_PERFCTR_LOAD_CMD2"/>
+	<reg32 offset="0x0504" name="RBBM_PERFCTR_LOAD_CMD3"/>
+	<reg32 offset="0x0505" name="RBBM_PERFCTR_LOAD_VALUE_LO"/>
+	<reg32 offset="0x0506" name="RBBM_PERFCTR_LOAD_VALUE_HI"/>
+	<array offset="0x0507" name="RBBM_PERFCTR_RBBM_SEL" stride="1" length="4"/>
+	<reg32 offset="0x050B" name="RBBM_PERFCTR_GPU_BUSY_MASKED"/>
+	<reg32 offset="0x050e" name="RBBM_PERFCTR_SRAM_INIT_CMD"/>
+	<reg32 offset="0x050f" name="RBBM_PERFCTR_SRAM_INIT_STATUS"/>
+	<reg32 offset="0x0533" name="RBBM_ISDB_CNT"/>
+	<reg32 offset="0x0534" name="RBBM_NC_MODE_CNTL"/>
+	<reg32 offset="0x0535" name="RBBM_SNAPSHOT_STATUS" variants="A7XX-"/>
+
+	<!---
+	    This block of registers aren't tied to perf counters. They
+	    count various geometry stats, for example number of
+	    vertices in, number of primnitives assembled etc.
+	-->
+
+	<reg32 offset="0x0540" name="RBBM_PRIMCTR_0_LO"/>  <!-- vs vertices in -->
+	<reg32 offset="0x0541" name="RBBM_PRIMCTR_0_HI"/>
+	<reg32 offset="0x0542" name="RBBM_PRIMCTR_1_LO"/>  <!-- vs primitives out -->
+	<reg32 offset="0x0543" name="RBBM_PRIMCTR_1_HI"/>
+	<reg32 offset="0x0544" name="RBBM_PRIMCTR_2_LO"/>  <!-- hs vertices in -->
+	<reg32 offset="0x0545" name="RBBM_PRIMCTR_2_HI"/>
+	<reg32 offset="0x0546" name="RBBM_PRIMCTR_3_LO"/>  <!-- hs patches out -->
+	<reg32 offset="0x0547" name="RBBM_PRIMCTR_3_HI"/>
+	<reg32 offset="0x0548" name="RBBM_PRIMCTR_4_LO"/>  <!-- dss vertices in -->
+	<reg32 offset="0x0549" name="RBBM_PRIMCTR_4_HI"/>
+	<reg32 offset="0x054a" name="RBBM_PRIMCTR_5_LO"/>  <!-- ds primitives out -->
+	<reg32 offset="0x054b" name="RBBM_PRIMCTR_5_HI"/>
+	<reg32 offset="0x054c" name="RBBM_PRIMCTR_6_LO"/>  <!-- gs primitives in -->
+	<reg32 offset="0x054d" name="RBBM_PRIMCTR_6_HI"/>
+	<reg32 offset="0x054e" name="RBBM_PRIMCTR_7_LO"/>  <!-- gs primitives out -->
+	<reg32 offset="0x054f" name="RBBM_PRIMCTR_7_HI"/>
+	<reg32 offset="0x0550" name="RBBM_PRIMCTR_8_LO"/>  <!-- gs primitives out -->
+	<reg32 offset="0x0551" name="RBBM_PRIMCTR_8_HI"/>
+	<reg32 offset="0x0552" name="RBBM_PRIMCTR_9_LO"/>  <!-- raster primitives in -->
+	<reg32 offset="0x0553" name="RBBM_PRIMCTR_9_HI"/>
+	<reg32 offset="0x0554" name="RBBM_PRIMCTR_10_LO"/>
+	<reg32 offset="0x0555" name="RBBM_PRIMCTR_10_HI"/>
+
+	<reg32 offset="0xF400" name="RBBM_SECVID_TRUST_CNTL"/>
+	<reg64 offset="0xF800" name="RBBM_SECVID_TSB_TRUSTED_BASE"/>
+	<reg32 offset="0xF802" name="RBBM_SECVID_TSB_TRUSTED_SIZE"/>
+	<reg32 offset="0xF803" name="RBBM_SECVID_TSB_CNTL"/>
+	<reg32 offset="0xF810" name="RBBM_SECVID_TSB_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg64 offset="0xfc00" name="RBBM_SECVID_TSB_STATUS" variants="A7XX-"/>
+	<reg32 offset="0x00010" name="RBBM_VBIF_CLIENT_QOS_CNTL"/>
+	<reg32 offset="0x00011" name="RBBM_GBIF_CLIENT_QOS_CNTL"/>
+	<reg32 offset="0x00016" name="RBBM_GBIF_HALT"/>
+	<reg32 offset="0x00017" name="RBBM_GBIF_HALT_ACK"/>
+	<reg32 offset="0x0001c" name="RBBM_WAIT_FOR_GPU_IDLE_CMD">
+		<bitfield pos="0" name="WAIT_GPU_IDLE" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x00016" name="RBBM_GBIF_HALT" variants="A7XX-"/>
+	<reg32 offset="0x00017" name="RBBM_GBIF_HALT_ACK" variants="A7XX-"/>
+	<reg32 offset="0x0001f" name="RBBM_INTERFACE_HANG_INT_CNTL"/>
+	<reg32 offset="0x00037" name="RBBM_INT_CLEAR_CMD" type="A6XX_RBBM_INT_0_MASK"/>
+	<reg32 offset="0x00038" name="RBBM_INT_0_MASK" type="A6XX_RBBM_INT_0_MASK"/>
+	<reg32 offset="0x0003a" name="RBBM_INT_2_MASK" variants="A7XX-"/>
+	<reg32 offset="0x00042" name="RBBM_SP_HYST_CNT"/>
+	<reg32 offset="0x00043" name="RBBM_SW_RESET_CMD"/>
+	<reg32 offset="0x00044" name="RBBM_RAC_THRESHOLD_CNT"/>
+	<reg32 offset="0x00045" name="RBBM_BLOCK_SW_RESET_CMD"/>
+	<reg32 offset="0x00046" name="RBBM_BLOCK_SW_RESET_CMD2"/>
+	<reg32 offset="0x000ad" name="RBBM_CLOCK_CNTL_GLOBAL" variants="A7XX-"/>
+	<reg32 offset="0x000ae" name="RBBM_CLOCK_CNTL"/>
+	<reg32 offset="0x000b0" name="RBBM_CLOCK_CNTL_SP0"/>
+	<reg32 offset="0x000b1" name="RBBM_CLOCK_CNTL_SP1"/>
+	<reg32 offset="0x000b2" name="RBBM_CLOCK_CNTL_SP2"/>
+	<reg32 offset="0x000b3" name="RBBM_CLOCK_CNTL_SP3"/>
+	<reg32 offset="0x000b4" name="RBBM_CLOCK_CNTL2_SP0"/>
+	<reg32 offset="0x000b5" name="RBBM_CLOCK_CNTL2_SP1"/>
+	<reg32 offset="0x000b6" name="RBBM_CLOCK_CNTL2_SP2"/>
+	<reg32 offset="0x000b7" name="RBBM_CLOCK_CNTL2_SP3"/>
+	<reg32 offset="0x000b8" name="RBBM_CLOCK_DELAY_SP0"/>
+	<reg32 offset="0x000b9" name="RBBM_CLOCK_DELAY_SP1"/>
+	<reg32 offset="0x000ba" name="RBBM_CLOCK_DELAY_SP2"/>
+	<reg32 offset="0x000bb" name="RBBM_CLOCK_DELAY_SP3"/>
+	<reg32 offset="0x000bc" name="RBBM_CLOCK_HYST_SP0"/>
+	<reg32 offset="0x000bd" name="RBBM_CLOCK_HYST_SP1"/>
+	<reg32 offset="0x000be" name="RBBM_CLOCK_HYST_SP2"/>
+	<reg32 offset="0x000bf" name="RBBM_CLOCK_HYST_SP3"/>
+	<reg32 offset="0x000c0" name="RBBM_CLOCK_CNTL_TP0"/>
+	<reg32 offset="0x000c1" name="RBBM_CLOCK_CNTL_TP1"/>
+	<reg32 offset="0x000c2" name="RBBM_CLOCK_CNTL_TP2"/>
+	<reg32 offset="0x000c3" name="RBBM_CLOCK_CNTL_TP3"/>
+	<reg32 offset="0x000c4" name="RBBM_CLOCK_CNTL2_TP0"/>
+	<reg32 offset="0x000c5" name="RBBM_CLOCK_CNTL2_TP1"/>
+	<reg32 offset="0x000c6" name="RBBM_CLOCK_CNTL2_TP2"/>
+	<reg32 offset="0x000c7" name="RBBM_CLOCK_CNTL2_TP3"/>
+	<reg32 offset="0x000c8" name="RBBM_CLOCK_CNTL3_TP0"/>
+	<reg32 offset="0x000c9" name="RBBM_CLOCK_CNTL3_TP1"/>
+	<reg32 offset="0x000ca" name="RBBM_CLOCK_CNTL3_TP2"/>
+	<reg32 offset="0x000cb" name="RBBM_CLOCK_CNTL3_TP3"/>
+	<reg32 offset="0x000cc" name="RBBM_CLOCK_CNTL4_TP0"/>
+	<reg32 offset="0x000cd" name="RBBM_CLOCK_CNTL4_TP1"/>
+	<reg32 offset="0x000ce" name="RBBM_CLOCK_CNTL4_TP2"/>
+	<reg32 offset="0x000cf" name="RBBM_CLOCK_CNTL4_TP3"/>
+	<reg32 offset="0x000d0" name="RBBM_CLOCK_DELAY_TP0"/>
+	<reg32 offset="0x000d1" name="RBBM_CLOCK_DELAY_TP1"/>
+	<reg32 offset="0x000d2" name="RBBM_CLOCK_DELAY_TP2"/>
+	<reg32 offset="0x000d3" name="RBBM_CLOCK_DELAY_TP3"/>
+	<reg32 offset="0x000d4" name="RBBM_CLOCK_DELAY2_TP0"/>
+	<reg32 offset="0x000d5" name="RBBM_CLOCK_DELAY2_TP1"/>
+	<reg32 offset="0x000d6" name="RBBM_CLOCK_DELAY2_TP2"/>
+	<reg32 offset="0x000d7" name="RBBM_CLOCK_DELAY2_TP3"/>
+	<reg32 offset="0x000d8" name="RBBM_CLOCK_DELAY3_TP0"/>
+	<reg32 offset="0x000d9" name="RBBM_CLOCK_DELAY3_TP1"/>
+	<reg32 offset="0x000da" name="RBBM_CLOCK_DELAY3_TP2"/>
+	<reg32 offset="0x000db" name="RBBM_CLOCK_DELAY3_TP3"/>
+	<reg32 offset="0x000dc" name="RBBM_CLOCK_DELAY4_TP0"/>
+	<reg32 offset="0x000dd" name="RBBM_CLOCK_DELAY4_TP1"/>
+	<reg32 offset="0x000de" name="RBBM_CLOCK_DELAY4_TP2"/>
+	<reg32 offset="0x000df" name="RBBM_CLOCK_DELAY4_TP3"/>
+	<reg32 offset="0x000e0" name="RBBM_CLOCK_HYST_TP0"/>
+	<reg32 offset="0x000e1" name="RBBM_CLOCK_HYST_TP1"/>
+	<reg32 offset="0x000e2" name="RBBM_CLOCK_HYST_TP2"/>
+	<reg32 offset="0x000e3" name="RBBM_CLOCK_HYST_TP3"/>
+	<reg32 offset="0x000e4" name="RBBM_CLOCK_HYST2_TP0"/>
+	<reg32 offset="0x000e5" name="RBBM_CLOCK_HYST2_TP1"/>
+	<reg32 offset="0x000e6" name="RBBM_CLOCK_HYST2_TP2"/>
+	<reg32 offset="0x000e7" name="RBBM_CLOCK_HYST2_TP3"/>
+	<reg32 offset="0x000e8" name="RBBM_CLOCK_HYST3_TP0"/>
+	<reg32 offset="0x000e9" name="RBBM_CLOCK_HYST3_TP1"/>
+	<reg32 offset="0x000ea" name="RBBM_CLOCK_HYST3_TP2"/>
+	<reg32 offset="0x000eb" name="RBBM_CLOCK_HYST3_TP3"/>
+	<reg32 offset="0x000ec" name="RBBM_CLOCK_HYST4_TP0"/>
+	<reg32 offset="0x000ed" name="RBBM_CLOCK_HYST4_TP1"/>
+	<reg32 offset="0x000ee" name="RBBM_CLOCK_HYST4_TP2"/>
+	<reg32 offset="0x000ef" name="RBBM_CLOCK_HYST4_TP3"/>
+	<reg32 offset="0x000f0" name="RBBM_CLOCK_CNTL_RB0"/>
+	<reg32 offset="0x000f1" name="RBBM_CLOCK_CNTL_RB1"/>
+	<reg32 offset="0x000f2" name="RBBM_CLOCK_CNTL_RB2"/>
+	<reg32 offset="0x000f3" name="RBBM_CLOCK_CNTL_RB3"/>
+	<reg32 offset="0x000f4" name="RBBM_CLOCK_CNTL2_RB0"/>
+	<reg32 offset="0x000f5" name="RBBM_CLOCK_CNTL2_RB1"/>
+	<reg32 offset="0x000f6" name="RBBM_CLOCK_CNTL2_RB2"/>
+	<reg32 offset="0x000f7" name="RBBM_CLOCK_CNTL2_RB3"/>
+	<reg32 offset="0x000f8" name="RBBM_CLOCK_CNTL_CCU0"/>
+	<reg32 offset="0x000f9" name="RBBM_CLOCK_CNTL_CCU1"/>
+	<reg32 offset="0x000fa" name="RBBM_CLOCK_CNTL_CCU2"/>
+	<reg32 offset="0x000fb" name="RBBM_CLOCK_CNTL_CCU3"/>
+	<reg32 offset="0x00100" name="RBBM_CLOCK_HYST_RB_CCU0"/>
+	<reg32 offset="0x00101" name="RBBM_CLOCK_HYST_RB_CCU1"/>
+	<reg32 offset="0x00102" name="RBBM_CLOCK_HYST_RB_CCU2"/>
+	<reg32 offset="0x00103" name="RBBM_CLOCK_HYST_RB_CCU3"/>
+	<reg32 offset="0x00104" name="RBBM_CLOCK_CNTL_RAC"/>
+	<reg32 offset="0x00105" name="RBBM_CLOCK_CNTL2_RAC"/>
+	<reg32 offset="0x00106" name="RBBM_CLOCK_DELAY_RAC"/>
+	<reg32 offset="0x00107" name="RBBM_CLOCK_HYST_RAC"/>
+	<reg32 offset="0x00108" name="RBBM_CLOCK_CNTL_TSE_RAS_RBBM"/>
+	<reg32 offset="0x00109" name="RBBM_CLOCK_DELAY_TSE_RAS_RBBM"/>
+	<reg32 offset="0x0010a" name="RBBM_CLOCK_HYST_TSE_RAS_RBBM"/>
+	<reg32 offset="0x0010b" name="RBBM_CLOCK_CNTL_UCHE"/>
+	<reg32 offset="0x0010c" name="RBBM_CLOCK_CNTL2_UCHE"/>
+	<reg32 offset="0x0010d" name="RBBM_CLOCK_CNTL3_UCHE"/>
+	<reg32 offset="0x0010e" name="RBBM_CLOCK_CNTL4_UCHE"/>
+	<reg32 offset="0x0010f" name="RBBM_CLOCK_DELAY_UCHE"/>
+	<reg32 offset="0x00110" name="RBBM_CLOCK_HYST_UCHE"/>
+	<reg32 offset="0x00111" name="RBBM_CLOCK_MODE_VFD"/>
+	<reg32 offset="0x00112" name="RBBM_CLOCK_DELAY_VFD"/>
+	<reg32 offset="0x00113" name="RBBM_CLOCK_HYST_VFD"/>
+	<reg32 offset="0x00114" name="RBBM_CLOCK_MODE_GPC"/>
+	<reg32 offset="0x00115" name="RBBM_CLOCK_DELAY_GPC"/>
+	<reg32 offset="0x00116" name="RBBM_CLOCK_HYST_GPC"/>
+	<reg32 offset="0x00117" name="RBBM_CLOCK_DELAY_HLSQ_2"/>
+	<reg32 offset="0x00118" name="RBBM_CLOCK_CNTL_GMU_GX"/>
+	<reg32 offset="0x00119" name="RBBM_CLOCK_DELAY_GMU_GX"/>
+	<reg32 offset="0x0011a" name="RBBM_CLOCK_HYST_GMU_GX"/>
+	<reg32 offset="0x0011b" name="RBBM_CLOCK_MODE_HLSQ"/>
+	<reg32 offset="0x0011c" name="RBBM_CLOCK_DELAY_HLSQ"/>
+	<reg32 offset="0x0011d" name="RBBM_CLOCK_HYST_HLSQ"/>
+	<reg32 offset="0x0011e" name="RBBM_CGC_GLOBAL_LOAD_CMD" variants="A7XX-"/>
+	<reg32 offset="0x0011f" name="RBBM_CGC_P2S_TRIG_CMD" variants="A7XX-"/>
+	<reg32 offset="0x00120" name="RBBM_CLOCK_CNTL_TEX_FCHE"/>
+	<reg32 offset="0x00121" name="RBBM_CLOCK_DELAY_TEX_FCHE"/>
+	<reg32 offset="0x00122" name="RBBM_CLOCK_HYST_TEX_FCHE"/>
+	<reg32 offset="0x00122" name="RBBM_CGC_P2S_STATUS" variants="A7XX-">
+		<bitfield name="TXDONE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00123" name="RBBM_CLOCK_CNTL_FCHE"/>
+	<reg32 offset="0x00124" name="RBBM_CLOCK_DELAY_FCHE"/>
+	<reg32 offset="0x00125" name="RBBM_CLOCK_HYST_FCHE"/>
+	<reg32 offset="0x00126" name="RBBM_CLOCK_CNTL_MHUB"/>
+	<reg32 offset="0x00127" name="RBBM_CLOCK_DELAY_MHUB"/>
+	<reg32 offset="0x00128" name="RBBM_CLOCK_HYST_MHUB"/>
+	<reg32 offset="0x00129" name="RBBM_CLOCK_DELAY_GLC"/>
+	<reg32 offset="0x0012a" name="RBBM_CLOCK_HYST_GLC"/>
+	<reg32 offset="0x0012b" name="RBBM_CLOCK_CNTL_GLC"/>
+	<reg32 offset="0x0012f" name="RBBM_CLOCK_HYST2_VFD" variants="A7XX-"/>
+	<reg32 offset="0x005ff" name="RBBM_LPAC_GBIF_CLIENT_QOS_CNTL"/>
+
+	<reg32 offset="0x0600" name="DBGC_CFG_DBGBUS_SEL_A"/>
+	<reg32 offset="0x0601" name="DBGC_CFG_DBGBUS_SEL_B"/>
+	<reg32 offset="0x0602" name="DBGC_CFG_DBGBUS_SEL_C"/>
+	<reg32 offset="0x0603" name="DBGC_CFG_DBGBUS_SEL_D">
+		<bitfield high="7" low="0" name="PING_INDEX"/>
+		<bitfield high="15" low="8" name="PING_BLK_SEL"/>
+	</reg32>
+	<reg32 offset="0x0604" name="DBGC_CFG_DBGBUS_CNTLT">
+		<bitfield high="5" low="0" name="TRACEEN"/>
+		<bitfield high="14" low="12" name="GRANU"/>
+		<bitfield high="31" low="28" name="SEGT"/>
+	</reg32>
+	<reg32 offset="0x0605" name="DBGC_CFG_DBGBUS_CNTLM">
+		<bitfield high="27" low="24" name="ENABLE"/>
+	</reg32>
+	<reg32 offset="0x0608" name="DBGC_CFG_DBGBUS_IVTL_0"/>
+	<reg32 offset="0x0609" name="DBGC_CFG_DBGBUS_IVTL_1"/>
+	<reg32 offset="0x060a" name="DBGC_CFG_DBGBUS_IVTL_2"/>
+	<reg32 offset="0x060b" name="DBGC_CFG_DBGBUS_IVTL_3"/>
+	<reg32 offset="0x060c" name="DBGC_CFG_DBGBUS_MASKL_0"/>
+	<reg32 offset="0x060d" name="DBGC_CFG_DBGBUS_MASKL_1"/>
+	<reg32 offset="0x060e" name="DBGC_CFG_DBGBUS_MASKL_2"/>
+	<reg32 offset="0x060f" name="DBGC_CFG_DBGBUS_MASKL_3"/>
+	<reg32 offset="0x0610" name="DBGC_CFG_DBGBUS_BYTEL_0">
+		<bitfield high="3" low="0" name="BYTEL0"/>
+		<bitfield high="7" low="4" name="BYTEL1"/>
+		<bitfield high="11" low="8" name="BYTEL2"/>
+		<bitfield high="15" low="12" name="BYTEL3"/>
+		<bitfield high="19" low="16" name="BYTEL4"/>
+		<bitfield high="23" low="20" name="BYTEL5"/>
+		<bitfield high="27" low="24" name="BYTEL6"/>
+		<bitfield high="31" low="28" name="BYTEL7"/>
+	</reg32>
+	<reg32 offset="0x0611" name="DBGC_CFG_DBGBUS_BYTEL_1">
+		<bitfield high="3" low="0" name="BYTEL8"/>
+		<bitfield high="7" low="4" name="BYTEL9"/>
+		<bitfield high="11" low="8" name="BYTEL10"/>
+		<bitfield high="15" low="12" name="BYTEL11"/>
+		<bitfield high="19" low="16" name="BYTEL12"/>
+		<bitfield high="23" low="20" name="BYTEL13"/>
+		<bitfield high="27" low="24" name="BYTEL14"/>
+		<bitfield high="31" low="28" name="BYTEL15"/>
+	</reg32>
+	<reg32 offset="0x062f" name="DBGC_CFG_DBGBUS_TRACE_BUF1"/>
+	<reg32 offset="0x0630" name="DBGC_CFG_DBGBUS_TRACE_BUF2"/>
+	<array offset="0x0CD8" name="VSC_PERFCTR_VSC_SEL" stride="1" length="2"/>
+	<reg32 offset="0x0CD8" name="VSC_UNKNOWN_0CD8" variants="A7XX">
+		<doc>
+			Set to true when binning, isn't changed afterwards
+		</doc>
+		<bitfield name="BINNING" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xC800" name="HLSQ_DBG_AHB_READ_APERTURE"/>
+	<reg32 offset="0xD000" name="HLSQ_DBG_READ_SEL"/>
+	<reg32 offset="0x0E00" name="UCHE_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0E01" name="UCHE_MODE_CNTL"/>
+	<reg64 offset="0x0E05" name="UCHE_WRITE_RANGE_MAX"/>
+	<reg64 offset="0x0E07" name="UCHE_WRITE_THRU_BASE"/>
+	<reg64 offset="0x0E09" name="UCHE_TRAP_BASE"/>
+	<reg64 offset="0x0E0B" name="UCHE_GMEM_RANGE_MIN"/>
+	<reg64 offset="0x0E0D" name="UCHE_GMEM_RANGE_MAX"/>
+	<reg32 offset="0x0E17" name="UCHE_CACHE_WAYS" usage="cmd"/>
+	<reg32 offset="0x0E18" name="UCHE_FILTER_CNTL"/>
+	<reg32 offset="0x0E19" name="UCHE_CLIENT_PF" usage="cmd">
+		<bitfield high="7" low="0" name="PERFSEL"/>
+	</reg32>
+	<array offset="0x0E1C" name="UCHE_PERFCTR_UCHE_SEL" stride="1" length="12"/>
+	<reg32 offset="0x0e3a" name="UCHE_GBIF_GX_CONFIG"/>
+	<reg32 offset="0x0e3c" name="UCHE_CMDQ_CONFIG"/>
+
+	<reg32 offset="0x3000" name="VBIF_VERSION"/>
+	<reg32 offset="0x3001" name="VBIF_CLKON">
+		<bitfield pos="1" name="FORCE_ON_TESTBUS" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x302A" name="VBIF_GATE_OFF_WRREQ_EN"/>
+	<reg32 offset="0x3080" name="VBIF_XIN_HALT_CTRL0"/>
+	<reg32 offset="0x3081" name="VBIF_XIN_HALT_CTRL1"/>
+	<reg32 offset="0x3084" name="VBIF_TEST_BUS_OUT_CTRL"/>
+	<reg32 offset="0x3085" name="VBIF_TEST_BUS1_CTRL0"/>
+	<reg32 offset="0x3086" name="VBIF_TEST_BUS1_CTRL1">
+		<bitfield low="0" high="3" name="DATA_SEL"/>
+	</reg32>
+	<reg32 offset="0x3087" name="VBIF_TEST_BUS2_CTRL0"/>
+	<reg32 offset="0x3088" name="VBIF_TEST_BUS2_CTRL1">
+		<bitfield low="0" high="8" name="DATA_SEL"/>
+	</reg32>
+	<reg32 offset="0x308c" name="VBIF_TEST_BUS_OUT"/>
+	<reg32 offset="0x30d0" name="VBIF_PERF_CNT_SEL0"/>
+	<reg32 offset="0x30d1" name="VBIF_PERF_CNT_SEL1"/>
+	<reg32 offset="0x30d2" name="VBIF_PERF_CNT_SEL2"/>
+	<reg32 offset="0x30d3" name="VBIF_PERF_CNT_SEL3"/>
+	<reg32 offset="0x30d8" name="VBIF_PERF_CNT_LOW0"/>
+	<reg32 offset="0x30d9" name="VBIF_PERF_CNT_LOW1"/>
+	<reg32 offset="0x30da" name="VBIF_PERF_CNT_LOW2"/>
+	<reg32 offset="0x30db" name="VBIF_PERF_CNT_LOW3"/>
+	<reg32 offset="0x30e0" name="VBIF_PERF_CNT_HIGH0"/>
+	<reg32 offset="0x30e1" name="VBIF_PERF_CNT_HIGH1"/>
+	<reg32 offset="0x30e2" name="VBIF_PERF_CNT_HIGH2"/>
+	<reg32 offset="0x30e3" name="VBIF_PERF_CNT_HIGH3"/>
+	<reg32 offset="0x3100" name="VBIF_PERF_PWR_CNT_EN0"/>
+	<reg32 offset="0x3101" name="VBIF_PERF_PWR_CNT_EN1"/>
+	<reg32 offset="0x3102" name="VBIF_PERF_PWR_CNT_EN2"/>
+	<reg32 offset="0x3110" name="VBIF_PERF_PWR_CNT_LOW0"/>
+	<reg32 offset="0x3111" name="VBIF_PERF_PWR_CNT_LOW1"/>
+	<reg32 offset="0x3112" name="VBIF_PERF_PWR_CNT_LOW2"/>
+	<reg32 offset="0x3118" name="VBIF_PERF_PWR_CNT_HIGH0"/>
+	<reg32 offset="0x3119" name="VBIF_PERF_PWR_CNT_HIGH1"/>
+	<reg32 offset="0x311a" name="VBIF_PERF_PWR_CNT_HIGH2"/>
+
+	<reg32 offset="0x3c01" name="GBIF_SCACHE_CNTL0"/>
+	<reg32 offset="0x3c02" name="GBIF_SCACHE_CNTL1"/>
+	<reg32 offset="0x3c03" name="GBIF_QSB_SIDE0"/>
+	<reg32 offset="0x3c04" name="GBIF_QSB_SIDE1"/>
+	<reg32 offset="0x3c05" name="GBIF_QSB_SIDE2"/>
+	<reg32 offset="0x3c06" name="GBIF_QSB_SIDE3"/>
+	<reg32 offset="0x3c45" name="GBIF_HALT"/>
+	<reg32 offset="0x3c46" name="GBIF_HALT_ACK"/>
+	<reg32 offset="0x3cc0" name="GBIF_PERF_PWR_CNT_EN"/>
+	<reg32 offset="0x3cc1" name="GBIF_PERF_PWR_CNT_CLR"/>
+	<reg32 offset="0x3cc2" name="GBIF_PERF_CNT_SEL"/>
+	<reg32 offset="0x3cc3" name="GBIF_PERF_PWR_CNT_SEL"/>
+	<reg32 offset="0x3cc4" name="GBIF_PERF_CNT_LOW0"/>
+	<reg32 offset="0x3cc5" name="GBIF_PERF_CNT_LOW1"/>
+	<reg32 offset="0x3cc6" name="GBIF_PERF_CNT_LOW2"/>
+	<reg32 offset="0x3cc7" name="GBIF_PERF_CNT_LOW3"/>
+	<reg32 offset="0x3cc8" name="GBIF_PERF_CNT_HIGH0"/>
+	<reg32 offset="0x3cc9" name="GBIF_PERF_CNT_HIGH1"/>
+	<reg32 offset="0x3cca" name="GBIF_PERF_CNT_HIGH2"/>
+	<reg32 offset="0x3ccb" name="GBIF_PERF_CNT_HIGH3"/>
+	<reg32 offset="0x3ccc" name="GBIF_PWR_CNT_LOW0"/>
+	<reg32 offset="0x3ccd" name="GBIF_PWR_CNT_LOW1"/>
+	<reg32 offset="0x3cce" name="GBIF_PWR_CNT_LOW2"/>
+	<reg32 offset="0x3ccf" name="GBIF_PWR_CNT_HIGH0"/>
+	<reg32 offset="0x3cd0" name="GBIF_PWR_CNT_HIGH1"/>
+	<reg32 offset="0x3cd1" name="GBIF_PWR_CNT_HIGH2"/>
+
+	<reg32 offset="0x0c00" name="VSC_DBG_ECO_CNTL"/>
+	<reg32 offset="0x0c02" name="VSC_BIN_SIZE" usage="rp_blit">
+		<bitfield name="WIDTH" low="0" high="7" shr="5" type="uint"/>
+		<bitfield name="HEIGHT" low="8" high="16" shr="4" type="uint"/>
+	</reg32>
+	<reg64 offset="0x0c03" name="VSC_DRAW_STRM_SIZE_ADDRESS" type="waddress" usage="cmd"/>
+	<reg32 offset="0x0c06" name="VSC_BIN_COUNT" usage="rp_blit">
+		<bitfield name="NX" low="1" high="10" type="uint"/>
+		<bitfield name="NY" low="11" high="20" type="uint"/>
+	</reg32>
+	<array offset="0x0c10" name="VSC_PIPE_CONFIG" stride="1" length="32" usage="rp_blit">
+		<reg32 offset="0x0" name="REG">
+			<doc>
+				Configures the mapping between VSC_PIPE buffer and
+				bin, X/Y specify the bin index in the horiz/vert
+				direction (0,0 is upper left, 0,1 is leftmost bin
+				on second row, and so on).  W/H specify the number
+				of bins assigned to this VSC_PIPE in the horiz/vert
+				dimension.
+			</doc>
+			<bitfield name="X" low="0" high="9" type="uint"/>
+			<bitfield name="Y" low="10" high="19" type="uint"/>
+			<bitfield name="W" low="20" high="25" type="uint"/>
+			<bitfield name="H" low="26" high="31" type="uint"/>
+		</reg32>
+	</array>
+	<!--
+	HW binning primitive & draw streams, which enable draws and primitives
+	within a draw to be skipped in the main tile pass.  See:
+	https://github.com/freedreno/freedreno/wiki/Visibility-Stream-Format
+
+	Compared to a5xx and earlier, we just program the address of the first
+	stream and hw adds (pipe_num * VSC_*_STRM_PITCH)
+
+	LIMIT is set to PITCH - 64, to make room for a bit of overflow
+	 -->
+	<reg64 offset="0x0c30" name="VSC_PRIM_STRM_ADDRESS" type="waddress" usage="cmd"/>
+	<reg32 offset="0x0c32" name="VSC_PRIM_STRM_PITCH" usage="cmd"/>
+	<reg32 offset="0x0c33" name="VSC_PRIM_STRM_LIMIT" usage="cmd"/>
+	<reg64 offset="0x0c34" name="VSC_DRAW_STRM_ADDRESS" type="waddress" usage="cmd"/>
+	<reg32 offset="0x0c36" name="VSC_DRAW_STRM_PITCH" usage="cmd"/>
+	<reg32 offset="0x0c37" name="VSC_DRAW_STRM_LIMIT" usage="cmd"/>
+
+	<array offset="0x0c38" name="VSC_STATE" stride="1" length="32" usage="rp_blit">
+		<doc>
+			Seems to be a bitmap of which tiles mapped to the VSC
+			pipe contain geometry.
+
+			I suppose we can connect a maximum of 32 tiles to a
+			single VSC pipe.
+		</doc>
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+
+	<array offset="0x0c58" name="VSC_PRIM_STRM_SIZE" stride="1" length="32" variants="A6XX" usage="rp_blit">
+		<doc>
+			Has the size of data written to corresponding VSC_PRIM_STRM
+			buffer.
+		</doc>
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+
+	<array offset="0x0c78" name="VSC_DRAW_STRM_SIZE" stride="1" length="32" variants="A6XX" usage="rp_blit">
+		<doc>
+			Has the size of data written to corresponding VSC pipe, ie.
+			same thing that is written out to VSC_DRAW_STRM_SIZE_ADDRESS_LO/HI
+		</doc>
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+
+	<reg32 offset="0x0d08" name="VSC_UNKNOWN_0D08" variants="A7XX-" usage="rp_blit"/>
+
+	<reg32 offset="0x0E10" name="UCHE_UNKNOWN_0E10" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0x0E11" name="UCHE_UNKNOWN_0E11" variants="A7XX-" usage="cmd"/>
+	<!-- always 0x03200000 ? -->
+	<reg32 offset="0x0e12" name="UCHE_UNKNOWN_0E12"  usage="cmd"/>
+
+	<!-- adreno_reg_xy has 15 bits per coordinate, but a6xx registers only have 14 -->
+	<bitset name="a6xx_reg_xy" inline="yes">
+		<bitfield name="X" low="0" high="13" type="uint"/>
+		<bitfield name="Y" low="16" high="29" type="uint"/>
+	</bitset>
+
+	<reg32 offset="0x8000" name="GRAS_CL_CNTL" usage="rp_blit">
+		<bitfield name="CLIP_DISABLE" pos="0" type="boolean"/>
+		<bitfield name="ZNEAR_CLIP_DISABLE" pos="1" type="boolean"/>
+		<bitfield name="ZFAR_CLIP_DISABLE" pos="2" type="boolean"/>
+		<bitfield name="Z_CLAMP_ENABLE" pos="5" type="boolean"/>
+		<!-- controls near z clip behavior (set for vulkan) -->
+		<bitfield name="ZERO_GB_SCALE_Z" pos="6" type="boolean"/>
+		<!-- guess based on a3xx and meaning of bits 8 and 9
+		     if the guess is right then this is related to point sprite clipping -->
+		<bitfield name="VP_CLIP_CODE_IGNORE" pos="7" type="boolean"/>
+		<bitfield name="VP_XFORM_DISABLE" pos="8" type="boolean"/>
+		<bitfield name="PERSP_DIVISION_DISABLE" pos="9" type="boolean"/>
+	</reg32>
+
+	<bitset name="a6xx_gras_xs_cl_cntl" inline="yes">
+		<bitfield name="CLIP_MASK" low="0" high="7"/>
+		<bitfield name="CULL_MASK" low="8" high="15"/>
+	</bitset>
+	<reg32 offset="0x8001" name="GRAS_VS_CL_CNTL" type="a6xx_gras_xs_cl_cntl" usage="rp_blit"/>
+	<reg32 offset="0x8002" name="GRAS_DS_CL_CNTL" type="a6xx_gras_xs_cl_cntl" usage="rp_blit"/>
+	<reg32 offset="0x8003" name="GRAS_GS_CL_CNTL" type="a6xx_gras_xs_cl_cntl" usage="rp_blit"/>
+	<reg32 offset="0x8004" name="GRAS_MAX_LAYER_INDEX" low="0" high="10" type="uint" usage="rp_blit"/>
+
+	<reg32 offset="0x8005" name="GRAS_CNTL" usage="rp_blit">
+		<!-- see also RB_RENDER_CONTROL0 -->
+		<bitfield name="IJ_PERSP_PIXEL" pos="0" type="boolean"/>
+		<bitfield name="IJ_PERSP_CENTROID" pos="1" type="boolean"/>
+		<bitfield name="IJ_PERSP_SAMPLE" pos="2" type="boolean"/>
+		<bitfield name="IJ_LINEAR_PIXEL" pos="3" type="boolean"/>
+		<bitfield name="IJ_LINEAR_CENTROID" pos="4" type="boolean"/>
+		<bitfield name="IJ_LINEAR_SAMPLE" pos="5" type="boolean"/>
+		<bitfield name="COORD_MASK" low="6" high="9" type="hex"/>
+		<bitfield name="UNK10" pos="10" type="boolean" variants="A7XX-"/>
+		<bitfield name="UNK11" pos="11" type="boolean" variants="A7XX-"/>
+	</reg32>
+	<reg32 offset="0x8006" name="GRAS_CL_GUARDBAND_CLIP_ADJ" usage="rp_blit">
+		<bitfield name="HORZ" low="0" high="8" type="uint"/>
+		<bitfield name="VERT" low="10" high="18" type="uint"/>
+	</reg32>
+
+	<!-- Something connected to depth-stencil attachment size -->
+	<reg32 offset="0x8007" name="GRAS_UNKNOWN_8007" variants="A7XX-" usage="rp_blit"/>
+
+	<reg32 offset="0x8008" name="GRAS_UNKNOWN_8008" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0x8009" name="GRAS_UNKNOWN_8009" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0x800a" name="GRAS_UNKNOWN_800A" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0x800b" name="GRAS_UNKNOWN_800B" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0x800c" name="GRAS_UNKNOWN_800C" variants="A7XX-" usage="cmd"/>
+
+	<!-- <reg32 offset="0x80f0" name="GRAS_UNKNOWN_80F0" type="a6xx_reg_xy"/> -->
+
+	<!-- 0x8006-0x800f invalid -->
+	<array offset="0x8010" name="GRAS_CL_VPORT" stride="6" length="16" usage="rp_blit">
+		<reg32 offset="0" name="XOFFSET" type="float"/>
+		<reg32 offset="1" name="XSCALE" type="float"/>
+		<reg32 offset="2" name="YOFFSET" type="float"/>
+		<reg32 offset="3" name="YSCALE" type="float"/>
+		<reg32 offset="4" name="ZOFFSET" type="float"/>
+		<reg32 offset="5" name="ZSCALE" type="float"/>
+	</array>
+	<array offset="0x8070" name="GRAS_CL_Z_CLAMP" stride="2" length="16" usage="rp_blit">
+		<reg32 offset="0" name="MIN" type="float"/>
+		<reg32 offset="1" name="MAX" type="float"/>
+	</array>
+
+	<reg32 offset="0x8090" name="GRAS_SU_CNTL" usage="rp_blit">
+		<bitfield name="CULL_FRONT" pos="0" type="boolean"/>
+		<bitfield name="CULL_BACK" pos="1" type="boolean"/>
+		<bitfield name="FRONT_CW" pos="2" type="boolean"/>
+		<bitfield name="LINEHALFWIDTH" low="3" high="10" radix="2" type="fixed"/>
+		<bitfield name="POLY_OFFSET" pos="11" type="boolean"/>
+		<bitfield name="UNK12" pos="12"/>
+		<bitfield name="LINE_MODE" pos="13" type="a5xx_line_mode"/>
+		<bitfield name="UNK15" low="15" high="16"/>
+		<!--
+                        On gen1 only MULTIVIEW_ENABLE exists. On gen3 we have
+                        the ability to add the view index to either the RT array
+                        index or the viewport index, and it seems that
+                        MULTIVIEW_ENABLE doesn't do anything, instead we need to
+                        set at least one of RENDERTARGETINDEXINCR or
+                        VIEWPORTINDEXINCR to enable multiview. The blob still
+                        sets MULTIVIEW_ENABLE regardless.
+                        TODO: what about gen2 (a640)?
+		-->
+		<bitfield name="MULTIVIEW_ENABLE" pos="17" type="boolean"/>
+		<bitfield name="RENDERTARGETINDEXINCR" pos="18" type="boolean"/>
+		<bitfield name="VIEWPORTINDEXINCR" pos="19" type="boolean"/>
+		<bitfield name="UNK20" low="20" high="22"/>
+	</reg32>
+	<reg32 offset="0x8091" name="GRAS_SU_POINT_MINMAX" usage="rp_blit">
+		<bitfield name="MIN" low="0" high="15" type="ufixed" radix="4"/>
+		<bitfield name="MAX" low="16" high="31" type="ufixed" radix="4"/>
+	</reg32>
+	<reg32 offset="0x8092" name="GRAS_SU_POINT_SIZE" low="0" high="15" type="fixed" radix="4" usage="rp_blit"/>
+	<!-- 0x8093 invalid -->
+	<reg32 offset="0x8094" name="GRAS_SU_DEPTH_PLANE_CNTL" usage="rp_blit">
+		<bitfield name="Z_MODE" low="0" high="1" type="a6xx_ztest_mode"/>
+	</reg32>
+	<reg32 offset="0x8095" name="GRAS_SU_POLY_OFFSET_SCALE" type="float" usage="rp_blit"/>
+	<reg32 offset="0x8096" name="GRAS_SU_POLY_OFFSET_OFFSET" type="float" usage="rp_blit"/>
+	<reg32 offset="0x8097" name="GRAS_SU_POLY_OFFSET_OFFSET_CLAMP" type="float" usage="rp_blit"/>
+	<!-- duplicates RB_DEPTH_BUFFER_INFO: -->
+	<reg32 offset="0x8098" name="GRAS_SU_DEPTH_BUFFER_INFO" usage="rp_blit">
+		<bitfield name="DEPTH_FORMAT" low="0" high="2" type="a6xx_depth_format"/>
+		<bitfield name="UNK3" pos="3"/>
+	</reg32>
+
+	<reg32 offset="0x8099" name="GRAS_SU_CONSERVATIVE_RAS_CNTL" usage="cmd">
+		<bitfield name="CONSERVATIVERASEN" pos="0" type="boolean"/>
+		<bitfield name="SHIFTAMOUNT" low="1" high="2"/>
+		<bitfield name="INNERCONSERVATIVERASEN" pos="3" type="boolean"/>
+		<bitfield name="UNK4" low="4" high="5"/>
+	</reg32>
+	<reg32 offset="0x809a" name="GRAS_SU_PATH_RENDERING_CNTL">
+		<bitfield name="UNK0" pos="0" type="boolean"/>
+		<bitfield name="LINELENGTHEN" pos="1" type="boolean"/>
+	</reg32>
+
+	<bitset name="a6xx_gras_layer_cntl" inline="yes">
+		<bitfield name="WRITES_LAYER" pos="0" type="boolean"/>
+		<bitfield name="WRITES_VIEW" pos="1" type="boolean"/>
+	</bitset>
+	<reg32 offset="0x809b" name="GRAS_VS_LAYER_CNTL" type="a6xx_gras_layer_cntl" usage="rp_blit"/>
+	<reg32 offset="0x809c" name="GRAS_GS_LAYER_CNTL" type="a6xx_gras_layer_cntl" usage="rp_blit"/>
+	<reg32 offset="0x809d" name="GRAS_DS_LAYER_CNTL" type="a6xx_gras_layer_cntl" usage="rp_blit"/>
+	<!-- 0x809e/0x809f invalid -->
+
+	<enum name="a6xx_sequenced_thread_dist">
+		<value value="0x0" name="DIST_SCREEN_COORD"/>
+		<value value="0x1" name="DIST_ALL_TO_RB0"/>
+	</enum>
+
+	<enum name="a6xx_single_prim_mode">
+		<value value="0x0" name="NO_FLUSH"/>
+		<doc>
+			In addition to FLUSH_PER_OVERLAP, guarantee that UCHE
+			and CCU don't get out of sync when fetching the previous
+			value for the current pixel. With NO_FLUSH, there's the
+			possibility that the flags for the current pixel are
+			flushed before the data or vice-versa, leading to
+			texture fetches via UCHE getting out of sync values.
+			This mode should eliminate that. It's used in bypass
+			mode for coherent blending
+			(GL_KHR_blend_equation_advanced_coherent) as well as
+			non-coherent blending.
+		</doc>
+		<value value="0x1" name="FLUSH_PER_OVERLAP_AND_OVERWRITE"/>
+		<doc>
+			Invalidate UCHE and wait for any pending work to finish
+			if there was possibly an overlapping primitive prior to
+			the current one. This is similar to a combination of
+			GRAS_SC_CONTROL::INJECT_L2_INVALIDATE_EVENT and
+			WAIT_RB_IDLE_ALL_TRI on a3xx. It's used in GMEM mode for
+			coherent blending
+			(GL_KHR_blend_equation_advanced_coherent).
+		</doc>
+		<value value="0x3" name="FLUSH_PER_OVERLAP"/>
+	</enum>
+
+	<!-- this probably has the same meaning as a3xx GRAS_SC_CONTROL::RASTER_MODE -->
+	<enum name="a6xx_raster_mode">
+		<value value="0x0" name="TYPE_TILED"/>
+		<value value="0x1" name="TYPE_WRITER"/>
+	</enum>
+
+	<!-- I'm guessing this is the same as a3xx -->
+	<enum name="a6xx_raster_direction">
+		<value value="0x0" name="LR_TB"/>
+		<value value="0x1" name="RL_TB"/>
+		<value value="0x2" name="LR_BT"/>
+		<value value="0x3" name="RB_BT"/>
+	</enum>
+
+	<reg32 offset="0x80a0" name="GRAS_SC_CNTL" usage="rp_blit">
+		<bitfield name="CCUSINGLECACHELINESIZE" low="0" high="2"/>
+		<bitfield name="SINGLE_PRIM_MODE" low="3" high="4" type="a6xx_single_prim_mode"/>
+		<bitfield name="RASTER_MODE" pos="5" type="a6xx_raster_mode"/>
+		<bitfield name="RASTER_DIRECTION" low="6" high="7" type="a6xx_raster_direction"/>
+		<bitfield name="SEQUENCED_THREAD_DISTRIBUTION" pos="8" type="a6xx_sequenced_thread_dist"/>
+		<!-- CCUSINGLECACHELINESIZE is ignored unless bit 9 is set -->
+		<bitfield name="UNK9" pos="9" type="boolean"/>
+		<bitfield name="ROTATION" low="10" high="11" type="uint"/>
+		<bitfield name="EARLYVIZOUTEN" pos="12" type="boolean"/>
+	</reg32>
+
+	<enum name="a6xx_render_mode">
+		<value value="0x0" name="RENDERING_PASS"/>
+		<value value="0x1" name="BINNING_PASS"/>
+	</enum>
+
+	<enum name="a6xx_buffers_location">
+		<value value="0" name="BUFFERS_IN_GMEM"/>
+		<value value="3" name="BUFFERS_IN_SYSMEM"/>
+	</enum>
+
+	<enum name="a6xx_lrz_feedback_mask">
+		<value value="0x0" name="LRZ_FEEDBACK_NONE"/>
+		<value value="0x1" name="LRZ_FEEDBACK_EARLY_Z"/>
+		<value value="0x2" name="LRZ_FEEDBACK_EARLY_LRZ_LATE_Z"/>
+		<!-- We don't have a flag type and this flags combination is often used -->
+		<value value="0x3" name="LRZ_FEEDBACK_EARLY_Z_OR_EARLY_LRZ_LATE_Z"/>
+		<value value="0x4" name="LRZ_FEEDBACK_LATE_Z"/>
+	</enum>
+
+	<reg32 offset="0x80a1" name="GRAS_BIN_CONTROL" usage="rp_blit">
+		<bitfield name="BINW" low="0" high="5" shr="5" type="uint"/>
+		<bitfield name="BINH" low="8" high="14" shr="4" type="uint"/>
+		<bitfield name="RENDER_MODE" low="18" high="20" type="a6xx_render_mode"/>
+		<doc>Disable LRZ feedback writes</doc>
+		<bitfield name="FORCE_LRZ_WRITE_DIS" pos="21" type="boolean"/>
+		<bitfield name="BUFFERS_LOCATION" low="22" high="23" type="a6xx_buffers_location" variants="A6XX"/>
+		<doc>
+			Allows draws that don't have GRAS_LRZ_CNTL.LRZ_WRITE but have
+			GRAS_LRZ_CNTL.ENABLE to contribute to LRZ during RENDERING pass.
+			In sysmem mode GRAS_LRZ_CNTL.LRZ_WRITE is not considered.
+		</doc>
+		<bitfield name="LRZ_FEEDBACK_ZMODE_MASK" low="24" high="26" type="a6xx_lrz_feedback_mask"/>
+		<bitfield name="UNK27" pos="27"/>
+	</reg32>
+
+	<reg32 offset="0x80a2" name="GRAS_RAS_MSAA_CNTL" usage="rp_blit">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="UNK2" pos="2"/>
+		<bitfield name="UNK3" pos="3"/>
+	</reg32>
+	<reg32 offset="0x80a3" name="GRAS_DEST_MSAA_CNTL" usage="rp_blit">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="MSAA_DISABLE" pos="2" type="boolean"/>
+	</reg32>
+
+	<bitset name="a6xx_sample_config" inline="yes">
+		<bitfield name="UNK0" pos="0"/>
+		<bitfield name="LOCATION_ENABLE" pos="1" type="boolean"/>
+	</bitset>
+
+	<bitset name="a6xx_sample_locations" inline="yes">
+		<bitfield name="SAMPLE_0_X" low="0" high="3" radix="4" type="fixed"/>
+		<bitfield name="SAMPLE_0_Y" low="4" high="7" radix="4" type="fixed"/>
+		<bitfield name="SAMPLE_1_X" low="8" high="11" radix="4" type="fixed"/>
+		<bitfield name="SAMPLE_1_Y" low="12" high="15" radix="4" type="fixed"/>
+		<bitfield name="SAMPLE_2_X" low="16" high="19" radix="4" type="fixed"/>
+		<bitfield name="SAMPLE_2_Y" low="20" high="23" radix="4" type="fixed"/>
+		<bitfield name="SAMPLE_3_X" low="24" high="27" radix="4" type="fixed"/>
+		<bitfield name="SAMPLE_3_Y" low="28" high="31" radix="4" type="fixed"/>
+	</bitset>
+
+	<reg32 offset="0x80a4" name="GRAS_SAMPLE_CONFIG" type="a6xx_sample_config" usage="rp_blit"/>
+	<reg32 offset="0x80a5" name="GRAS_SAMPLE_LOCATION_0" type="a6xx_sample_locations" usage="rp_blit"/>
+	<reg32 offset="0x80a6" name="GRAS_SAMPLE_LOCATION_1" type="a6xx_sample_locations" usage="rp_blit"/>
+
+	<reg32 offset="0x80a7" name="GRAS_UNKNOWN_80A7" variants="A7XX-" usage="cmd"/>
+
+	<!-- 0x80a7-0x80ae invalid -->
+	<reg32 offset="0x80af" name="GRAS_UNKNOWN_80AF" pos="0" usage="cmd"/>
+
+	<bitset name="a6xx_scissor_xy" inline="yes">
+		<bitfield name="X" low="0" high="15" type="uint"/>
+		<bitfield name="Y" low="16" high="31" type="uint"/>
+	</bitset>
+	<array offset="0x80b0" name="GRAS_SC_SCREEN_SCISSOR" stride="2" length="16" usage="rp_blit">
+		<reg32 offset="0" name="TL" type="a6xx_scissor_xy"/>
+		<reg32 offset="1" name="BR" type="a6xx_scissor_xy"/>
+	</array>
+	<array offset="0x80d0" name="GRAS_SC_VIEWPORT_SCISSOR" stride="2" length="16" usage="rp_blit">
+		<reg32 offset="0" name="TL" type="a6xx_scissor_xy"/>
+		<reg32 offset="1" name="BR" type="a6xx_scissor_xy"/>
+	</array>
+
+	<reg32 offset="0x80f0" name="GRAS_SC_WINDOW_SCISSOR_TL" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0x80f1" name="GRAS_SC_WINDOW_SCISSOR_BR" type="a6xx_reg_xy" usage="rp_blit"/>
+
+	<!-- 0x80f4 - 0x80fa are used for VK_KHR_fragment_shading_rate -->
+	<reg64 offset="0x80f4" name="GRAS_UNKNOWN_80F4" variants="A7XX-" usage="cmd"/>
+	<reg64 offset="0x80f5" name="GRAS_UNKNOWN_80F5" variants="A7XX-" usage="cmd"/>
+	<reg64 offset="0x80f6" name="GRAS_UNKNOWN_80F6" variants="A7XX-" usage="cmd"/>
+	<reg64 offset="0x80f8" name="GRAS_UNKNOWN_80F8" variants="A7XX-" usage="cmd"/>
+	<reg64 offset="0x80f9" name="GRAS_UNKNOWN_80F9" variants="A7XX-" usage="cmd"/>
+	<reg64 offset="0x80fa" name="GRAS_UNKNOWN_80FA" variants="A7XX-" usage="cmd"/>
+
+	<enum name="a6xx_lrz_dir_status">
+		<value value="0x1" name="LRZ_DIR_LE"/>
+		<value value="0x2" name="LRZ_DIR_GE"/>
+		<value value="0x3" name="LRZ_DIR_INVALID"/>
+	</enum>
+
+	<reg32 offset="0x8100" name="GRAS_LRZ_CNTL" usage="rp_blit">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<doc>LRZ write also disabled for blend/etc.</doc>
+		<bitfield name="LRZ_WRITE" pos="1" type="boolean"/>
+		<doc>update MAX instead of MIN value, ie. GL_GREATER/GL_GEQUAL</doc>
+		<bitfield name="GREATER" pos="2" type="boolean"/>
+		<doc>
+			Clears the LRZ block being touched to:
+			- 0.0 if GREATER
+			- 1.0 if LESS
+		</doc>
+		<bitfield name="FC_ENABLE" pos="3" type="boolean" variants="A6XX"/>
+		<!-- set when depth-test + depth-write enabled -->
+		<bitfield name="Z_TEST_ENABLE" pos="4" type="boolean"/>
+		<bitfield name="Z_BOUNDS_ENABLE" pos="5" type="boolean"/>
+		<bitfield name="DIR" low="6" high="7" type="a6xx_lrz_dir_status"/>
+		<doc>
+			If DISABLE_ON_WRONG_DIR enabled - write new LRZ direction into
+			buffer, in case of mismatched direction writes 0 (disables LRZ).
+		</doc>
+		<bitfield name="DIR_WRITE" pos="8" type="boolean"/>
+		<doc>
+			Disable LRZ based on previous direction and the current one.
+			If DIR_WRITE is not enabled - there is no write to direction buffer.
+		</doc>
+		<bitfield name="DISABLE_ON_WRONG_DIR" pos="9" type="boolean" variants="A6XX"/>
+		<bitfield name="Z_FUNC" low="11" high="13" type="adreno_compare_func" variants="A7XX-"/>
+	</reg32>
+
+	<enum name="a6xx_fragcoord_sample_mode">
+		<value value="0" name="FRAGCOORD_CENTER"/>
+		<value value="3" name="FRAGCOORD_SAMPLE"/>
+	</enum>
+
+	<reg32 offset="0x8101" name="GRAS_LRZ_PS_INPUT_CNTL" low="0" high="2" usage="rp_blit">
+		<bitfield name="SAMPLEID" pos="0" type="boolean"/>
+		<bitfield name="FRAGCOORDSAMPLEMODE" low="1" high="2" type="a6xx_fragcoord_sample_mode"/>
+	</reg32>
+
+	<reg32 offset="0x8102" name="GRAS_LRZ_MRT_BUF_INFO_0" usage="rp_blit">
+		<bitfield name="COLOR_FORMAT" low="0" high="7" type="a6xx_format"/>
+	</reg32>
+	<reg64 offset="0x8103" name="GRAS_LRZ_BUFFER_BASE" align="256" type="waddress" usage="rp_blit"/>
+	<reg32 offset="0x8105" name="GRAS_LRZ_BUFFER_PITCH" usage="rp_blit">
+		<!-- TODO: fix the shr fields -->
+		<bitfield name="PITCH" low="0" high="7" shr="5" type="uint"/>
+		<bitfield name="ARRAY_PITCH" low="10" high="28" shr="4" type="uint"/>
+	</reg32>
+
+	<!--
+	The LRZ "fast clear" buffer is initialized to zero's by blob, and
+	read/written when GRAS_LRZ_CNTL.FC_ENABLE (b3) is set.  It appears
+	to store 1b/block.  It appears that '0' means block has original
+	depth clear value, and '1' means that the corresponding block in
+	LRZ has been modified.  Ignoring alignment/padding, the size is
+	given by the formula:
+
+		// calculate LRZ size from depth size:
+		if (nr_samples == 4) {
+			width *= 2;
+			height *= 2;
+		} else if (nr_samples == 2) {
+			height *= 2;
+		}
+
+		lrz_width = div_round_up(width, 8);
+		lrz_heigh = div_round_up(height, 8);
+
+		// calculate # of blocks:
+		nblocksx = div_round_up(lrz_width, 16);
+		nblocksy = div_round_up(lrz_height, 4);
+
+		// fast-clear buffer is 1bit/block:
+		fc_sz = div_round_up(nblocksx * nblocksy, 8);
+
+	In practice the blob seems to switch off FC_ENABLE once the size
+	increases beyond 1 page.  Not sure if that is an actual limit or
+	not.
+	 -->
+	<reg64 offset="0x8106" name="GRAS_LRZ_FAST_CLEAR_BUFFER_BASE" align="64" type="waddress" usage="rp_blit"/>
+	<!-- 0x8108 invalid -->
+	<reg32 offset="0x8109" name="GRAS_SAMPLE_CNTL" usage="rp_blit">
+		<bitfield name="PER_SAMP_MODE" pos="0" type="boolean"/>
+	</reg32>
+	<!--
+	LRZ buffer represents a single array layer + mip level, and there is
+	a single buffer per depth image. Thus to reuse LRZ between renderpasses
+	it is necessary to track the depth view used in the past renderpass, which
+	GRAS_LRZ_DEPTH_VIEW is for.
+	GRAS_LRZ_CNTL checks if current value of GRAS_LRZ_DEPTH_VIEW is equal to
+	the value stored in the LRZ buffer, if not - LRZ is disabled.
+	-->
+	<reg32 offset="0x810a" name="GRAS_LRZ_DEPTH_VIEW" usage="cmd">
+		<bitfield name="BASE_LAYER" low="0" high="10" type="uint"/>
+		<bitfield name="LAYER_COUNT" low="16" high="26" type="uint"/>
+		<bitfield name="BASE_MIP_LEVEL" low="28" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x810b" name="GRAS_LRZ_CNTL2" variants="A7XX-" usage="rp_blit">
+		<bitfield name="DISABLE_ON_WRONG_DIR" pos="0" type="boolean"/>
+		<bitfield name="FC_ENABLE" pos="1" type="boolean"/>
+	</reg32>
+
+	<!-- 0x810c-0x810f invalid -->
+
+	<reg32 offset="0x8110" name="GRAS_UNKNOWN_8110" low="0" high="1" usage="cmd"/>
+
+	<!-- A bit tentative but it's a color and it is followed by LRZ_CLEAR -->
+	<reg32 offset="0x8111" name="GRAS_LRZ_CLEAR_DEPTH_F32" type="float" variants="A7XX-"/>
+
+	<reg32 offset="0x8113" name="GRAS_LRZ_DEPTH_BUFFER_INFO" variants="A7XX-" usage="rp_blit">
+		<bitfield name="DEPTH_FORMAT" low="0" high="2" type="a6xx_depth_format"/>
+		<bitfield name="UNK3" pos="3"/>
+	</reg32>
+
+	<!-- Always written together and always equal 09510840 00000a62 -->
+	<reg32 offset="0x8120" name="GRAS_UNKNOWN_8120" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0x8121" name="GRAS_UNKNOWN_8121" variants="A7XX-" usage="cmd"/>
+
+	<!-- 0x8112-0x83ff invalid -->
+
+	<enum name="a6xx_rotation">
+		<value value="0x0" name="ROTATE_0"/>
+		<value value="0x1" name="ROTATE_90"/>
+		<value value="0x2" name="ROTATE_180"/>
+		<value value="0x3" name="ROTATE_270"/>
+		<value value="0x4" name="ROTATE_HFLIP"/>
+		<value value="0x5" name="ROTATE_VFLIP"/>
+	</enum>
+
+	<bitset name="a6xx_2d_blit_cntl" inline="yes">
+		<bitfield name="ROTATE" low="0" high="2" type="a6xx_rotation"/>
+		<bitfield name="OVERWRITEEN" pos="3" type="boolean"/>
+		<bitfield name="UNK4" low="4" high="6"/>
+		<bitfield name="SOLID_COLOR" pos="7" type="boolean"/>
+		<bitfield name="COLOR_FORMAT" low="8" high="15" type="a6xx_format"/>
+		<bitfield name="SCISSOR" pos="16" type="boolean"/>
+		<bitfield name="UNK17" low="17" high="18"/>
+		<!-- required when blitting D24S8/D24X8 -->
+		<bitfield name="D24S8" pos="19" type="boolean"/>
+		<!-- some sort of channel mask, disabled channels are set to zero ? -->
+		<bitfield name="MASK" low="20" high="23"/>
+		<bitfield name="IFMT" low="24" high="28" type="a6xx_2d_ifmt"/>
+		<bitfield name="RASTER_MODE" pos="29" type="a6xx_raster_mode"/>
+		<bitfield name="UNK30" pos="30" type="boolean" variants="A7XX-"/>
+	</bitset>
+
+	<reg32 offset="0x8400" name="GRAS_2D_BLIT_CNTL" type="a6xx_2d_blit_cntl" usage="rp_blit"/>
+	<!-- note: the low 8 bits for src coords are valid, probably fixed point
+	     it would be a bit weird though, since we subtract 1 from BR coords
+	     apparently signed, gallium driver uses negative coords and it works?
+	 -->
+	<reg32 offset="0x8401" name="GRAS_2D_SRC_TL_X" low="8" high="24" type="int" usage="rp_blit"/>
+	<reg32 offset="0x8402" name="GRAS_2D_SRC_BR_X" low="8" high="24" type="int" usage="rp_blit"/>
+	<reg32 offset="0x8403" name="GRAS_2D_SRC_TL_Y" low="8" high="24" type="int" usage="rp_blit"/>
+	<reg32 offset="0x8404" name="GRAS_2D_SRC_BR_Y" low="8" high="24" type="int" usage="rp_blit"/>
+	<reg32 offset="0x8405" name="GRAS_2D_DST_TL" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0x8406" name="GRAS_2D_DST_BR" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0x8407" name="GRAS_2D_UNKNOWN_8407" low="0" high="31"/>
+	<reg32 offset="0x8408" name="GRAS_2D_UNKNOWN_8408" low="0" high="31"/>
+	<reg32 offset="0x8409" name="GRAS_2D_UNKNOWN_8409" low="0" high="31"/>
+	<reg32 offset="0x840a" name="GRAS_2D_RESOLVE_CNTL_1" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0x840b" name="GRAS_2D_RESOLVE_CNTL_2" type="a6xx_reg_xy" usage="rp_blit"/>
+	<!-- 0x840c-0x85ff invalid -->
+
+	<!-- always 0x880 ? (and 0 in a640/a650 traces?) -->
+	<reg32 offset="0x8600" name="GRAS_DBG_ECO_CNTL" usage="cmd">
+		<bitfield name="UNK7" pos="7" type="boolean"/>
+		<bitfield name="LRZCACHELOCKDIS" pos="11" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x8601" name="GRAS_ADDR_MODE_CNTL" pos="0" type="a5xx_address_mode"/>
+	<reg32 offset="0x8602" name="GRAS_NC_MODE_CNTL" variants="A7XX-"/>
+	<array offset="0x8610" name="GRAS_PERFCTR_TSE_SEL" stride="1" length="4"/>
+	<array offset="0x8614" name="GRAS_PERFCTR_RAS_SEL" stride="1" length="4"/>
+	<array offset="0x8618" name="GRAS_PERFCTR_LRZ_SEL" stride="1" length="4"/>
+
+	<!-- note 0x8620-0x87ff are not all invalid
+	(in particular, 0x8631/0x8632 have 0x3fff3fff mask and would be xy coords)
+	-->
+
+	<!-- same as GRAS_BIN_CONTROL, but without bit 27: -->
+	<reg32 offset="0x8800" name="RB_BIN_CONTROL" variants="A6XX" usage="rp_blit">
+		<bitfield name="BINW" low="0" high="5" shr="5" type="uint"/>
+		<bitfield name="BINH" low="8" high="14" shr="4" type="uint"/>
+		<bitfield name="RENDER_MODE" low="18" high="20" type="a6xx_render_mode"/>
+		<bitfield name="FORCE_LRZ_WRITE_DIS" pos="21" type="boolean"/>
+		<bitfield name="BUFFERS_LOCATION" low="22" high="23" type="a6xx_buffers_location"/>
+		<bitfield name="LRZ_FEEDBACK_ZMODE_MASK" low="24" high="26" type="a6xx_lrz_feedback_mask"/>
+	</reg32>
+
+	<reg32 offset="0x8800" name="RB_BIN_CONTROL" variants="A7XX-" usage="rp_blit">
+		<bitfield name="BINW" low="0" high="5" shr="5" type="uint"/>
+		<bitfield name="BINH" low="8" high="14" shr="4" type="uint"/>
+		<bitfield name="RENDER_MODE" low="18" high="20" type="a6xx_render_mode"/>
+		<bitfield name="FORCE_LRZ_WRITE_DIS" pos="21" type="boolean"/>
+		<bitfield name="LRZ_FEEDBACK_ZMODE_MASK" low="24" high="26" type="a6xx_lrz_feedback_mask"/>
+	</reg32>
+
+	<reg32 offset="0x8801" name="RB_RENDER_CNTL" variants="A6XX" usage="rp_blit">
+		<bitfield name="CCUSINGLECACHELINESIZE" low="3" high="5"/>
+		<bitfield name="EARLYVIZOUTEN" pos="6" type="boolean"/>
+		<!-- set during binning pass: -->
+		<bitfield name="BINNING" pos="7" type="boolean"/>
+		<bitfield name="UNK8" low="8" high="10"/>
+		<bitfield name="RASTER_MODE" pos="8" type="a6xx_raster_mode"/>
+		<bitfield name="RASTER_DIRECTION" low="9" high="10" type="a6xx_raster_direction"/>
+		<bitfield name="CONSERVATIVERASEN" pos="11" type="boolean"/>
+		<bitfield name="INNERCONSERVATIVERASEN" pos="12" type="boolean"/>
+		<!-- bit seems to be set whenever depth buffer enabled: -->
+		<bitfield name="FLAG_DEPTH" pos="14" type="boolean"/>
+		<!-- bitmask of MRTs using UBWC flag buffer: -->
+		<bitfield name="FLAG_MRTS" low="16" high="23"/>
+	</reg32>
+	<reg32 offset="0x8801" name="RB_RENDER_CNTL" variants="A7XX-" usage="rp_blit">
+		<bitfield name="EARLYVIZOUTEN" pos="6" type="boolean"/>
+		<!-- set during binning pass: -->
+		<bitfield name="BINNING" pos="7" type="boolean"/>
+		<bitfield name="RASTER_MODE" pos="8" type="a6xx_raster_mode"/>
+		<bitfield name="RASTER_DIRECTION" low="9" high="10" type="a6xx_raster_direction"/>
+		<bitfield name="CONSERVATIVERASEN" pos="11" type="boolean"/>
+		<bitfield name="INNERCONSERVATIVERASEN" pos="12" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x8116" name="GRAS_SU_RENDER_CNTL" variants="A7XX-" usage="rp_blit">
+		<bitfield name="BINNING" pos="7" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x8802" name="RB_RAS_MSAA_CNTL" usage="rp_blit">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="UNK2" pos="2"/>
+		<bitfield name="UNK3" pos="3"/>
+	</reg32>
+	<reg32 offset="0x8803" name="RB_DEST_MSAA_CNTL" usage="rp_blit">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="MSAA_DISABLE" pos="2" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x8804" name="RB_SAMPLE_CONFIG" type="a6xx_sample_config" usage="rp_blit"/>
+	<reg32 offset="0x8805" name="RB_SAMPLE_LOCATION_0" type="a6xx_sample_locations" usage="rp_blit"/>
+	<reg32 offset="0x8806" name="RB_SAMPLE_LOCATION_1" type="a6xx_sample_locations" usage="rp_blit"/>
+	<!-- 0x8807-0x8808 invalid -->
+	<!--
+	note: maybe not actually called RB_RENDER_CONTROLn (since RB_RENDER_CNTL
+	name comes from kernel and is probably right)
+	 -->
+	<reg32 offset="0x8809" name="RB_RENDER_CONTROL0" usage="rp_blit">
+		<!-- see also GRAS_CNTL -->
+		<bitfield name="IJ_PERSP_PIXEL" pos="0" type="boolean"/>
+		<bitfield name="IJ_PERSP_CENTROID" pos="1" type="boolean"/>
+		<bitfield name="IJ_PERSP_SAMPLE" pos="2" type="boolean"/>
+		<bitfield name="IJ_LINEAR_PIXEL" pos="3" type="boolean"/>
+		<bitfield name="IJ_LINEAR_CENTROID" pos="4" type="boolean"/>
+		<bitfield name="IJ_LINEAR_SAMPLE" pos="5" type="boolean"/>
+		<bitfield name="COORD_MASK" low="6" high="9" type="hex"/>
+		<bitfield name="UNK10" pos="10" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x880a" name="RB_RENDER_CONTROL1" usage="rp_blit">
+		<!-- enable bits for various FS sysvalue regs: -->
+		<bitfield name="SAMPLEMASK" pos="0" type="boolean"/>
+		<bitfield name="POSTDEPTHCOVERAGE" pos="1" type="boolean"/>
+		<bitfield name="FACENESS" pos="2" type="boolean"/>
+		<bitfield name="SAMPLEID" pos="3" type="boolean"/>
+		<bitfield name="FRAGCOORDSAMPLEMODE" low="4" high="5" type="a6xx_fragcoord_sample_mode"/>
+		<bitfield name="CENTERRHW" pos="6" type="boolean"/>
+		<bitfield name="LINELENGTHEN" pos="7" type="boolean"/>
+		<bitfield name="FOVEATION" pos="8" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x880b" name="RB_FS_OUTPUT_CNTL0" usage="rp_blit">
+		<bitfield name="DUAL_COLOR_IN_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="FRAG_WRITES_Z" pos="1" type="boolean"/>
+		<bitfield name="FRAG_WRITES_SAMPMASK" pos="2" type="boolean"/>
+		<bitfield name="FRAG_WRITES_STENCILREF" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x880c" name="RB_FS_OUTPUT_CNTL1" usage="rp_blit">
+		<bitfield name="MRT" low="0" high="3" type="uint"/>
+	</reg32>
+	<reg32 offset="0x880d" name="RB_RENDER_COMPONENTS" usage="rp_blit">
+		<bitfield name="RT0" low="0" high="3"/>
+		<bitfield name="RT1" low="4" high="7"/>
+		<bitfield name="RT2" low="8" high="11"/>
+		<bitfield name="RT3" low="12" high="15"/>
+		<bitfield name="RT4" low="16" high="19"/>
+		<bitfield name="RT5" low="20" high="23"/>
+		<bitfield name="RT6" low="24" high="27"/>
+		<bitfield name="RT7" low="28" high="31"/>
+	</reg32>
+	<reg32 offset="0x880e" name="RB_DITHER_CNTL" usage="cmd">
+		<bitfield name="DITHER_MODE_MRT0" low="0"  high="1"  type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_MODE_MRT1" low="2"  high="3"  type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_MODE_MRT2" low="4"  high="5"  type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_MODE_MRT3" low="6"  high="7"  type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_MODE_MRT4" low="8"  high="9"  type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_MODE_MRT5" low="10" high="11" type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_MODE_MRT6" low="12" high="13" type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_MODE_MRT7" low="14" high="15" type="adreno_rb_dither_mode"/>
+	</reg32>
+	<reg32 offset="0x880f" name="RB_SRGB_CNTL" usage="rp_blit">
+		<!-- Same as SP_SRGB_CNTL -->
+		<bitfield name="SRGB_MRT0" pos="0" type="boolean"/>
+		<bitfield name="SRGB_MRT1" pos="1" type="boolean"/>
+		<bitfield name="SRGB_MRT2" pos="2" type="boolean"/>
+		<bitfield name="SRGB_MRT3" pos="3" type="boolean"/>
+		<bitfield name="SRGB_MRT4" pos="4" type="boolean"/>
+		<bitfield name="SRGB_MRT5" pos="5" type="boolean"/>
+		<bitfield name="SRGB_MRT6" pos="6" type="boolean"/>
+		<bitfield name="SRGB_MRT7" pos="7" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x8810" name="RB_SAMPLE_CNTL" usage="rp_blit">
+		<bitfield name="PER_SAMP_MODE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x8811" name="RB_UNKNOWN_8811" low="4" high="6" usage="cmd"/>
+	<reg32 offset="0x8812" name="RB_UNKNOWN_8812" variants="A7XX-" usage="rp_blit"/>
+	<!-- 0x8813-0x8817 invalid -->
+	<!-- always 0x0 ? -->
+	<reg32 offset="0x8818" name="RB_UNKNOWN_8818" low="0" high="6" usage="cmd"/>
+	<!-- 0x8819-0x881e all 32 bits -->
+	<reg32 offset="0x8819" name="RB_UNKNOWN_8819" usage="cmd"/>
+	<reg32 offset="0x881a" name="RB_UNKNOWN_881A" usage="cmd"/>
+	<reg32 offset="0x881b" name="RB_UNKNOWN_881B" usage="cmd"/>
+	<reg32 offset="0x881c" name="RB_UNKNOWN_881C" usage="cmd"/>
+	<reg32 offset="0x881d" name="RB_UNKNOWN_881D" usage="cmd"/>
+	<reg32 offset="0x881e" name="RB_UNKNOWN_881E" usage="cmd"/>
+	<!-- 0x881f invalid -->
+	<array offset="0x8820" name="RB_MRT" stride="8" length="8" usage="rp_blit">
+		<reg32 offset="0x0" name="CONTROL">
+			<bitfield name="BLEND" pos="0" type="boolean"/>
+			<bitfield name="BLEND2" pos="1" type="boolean"/>
+			<bitfield name="ROP_ENABLE" pos="2" type="boolean"/>
+			<bitfield name="ROP_CODE" low="3" high="6" type="a3xx_rop_code"/>
+			<bitfield name="COMPONENT_ENABLE" low="7" high="10" type="hex"/>
+		</reg32>
+		<reg32 offset="0x1" name="BLEND_CONTROL">
+			<bitfield name="RGB_SRC_FACTOR" low="0" high="4" type="adreno_rb_blend_factor"/>
+			<bitfield name="RGB_BLEND_OPCODE" low="5" high="7" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="RGB_DEST_FACTOR" low="8" high="12" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_SRC_FACTOR" low="16" high="20" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_BLEND_OPCODE" low="21" high="23" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="ALPHA_DEST_FACTOR" low="24" high="28" type="adreno_rb_blend_factor"/>
+		</reg32>
+		<reg32 offset="0x2" name="BUF_INFO" variants="A6XX">
+			<bitfield name="COLOR_FORMAT" low="0" high="7" type="a6xx_format"/>
+			<bitfield name="COLOR_TILE_MODE" low="8" high="9" type="a6xx_tile_mode"/>
+			<bitfield name="UNK10" pos="10"/>
+			<bitfield name="COLOR_SWAP" low="13" high="14" type="a3xx_color_swap"/>
+		</reg32>
+		<reg32 offset="0x2" name="BUF_INFO" variants="A7XX-">
+			<bitfield name="COLOR_FORMAT" low="0" high="7" type="a6xx_format"/>
+			<bitfield name="COLOR_TILE_MODE" low="8" high="9" type="a6xx_tile_mode"/>
+			<bitfield name="UNK10" pos="10"/>
+			<bitfield name="LOSSLESSCOMPEN" pos="11" type="boolean"/>
+			<bitfield name="COLOR_SWAP" low="13" high="14" type="a3xx_color_swap"/>
+			<bitfield name="MUTABLEEN" pos="16" type="boolean" variants="A7XX-"/>
+		</reg32>
+		<!--
+		at least in gmem, things seem to be aligned to pitch of 64..
+		maybe an artifact of tiled format used in gmem?
+		 -->
+		<reg32 offset="0x3" name="PITCH" shr="6" high="15" type="uint"/>
+		<reg32 offset="0x4" name="ARRAY_PITCH" shr="6" high="28" type="uint"/>
+		<!--
+		Compared to a5xx and before, we configure both a GMEM base and
+		external base.  Not sure if this is to facilitate GMEM save/
+		restore for context switch, or just to simplify state setup to
+		not have to care about GMEM vs BYPASS mode.
+		 -->
+		<!-- maybe something in low bits since alignment of 1 doesn't make sense? -->
+		<reg64 offset="0x5" name="BASE" type="waddress" align="1"/>
+
+		<reg32 offset="0x7" name="BASE_GMEM" low="12" high="31" shr="12"/>
+	</array>
+
+	<reg32 offset="0x8860" name="RB_BLEND_RED_F32" type="float" usage="rp_blit"/>
+	<reg32 offset="0x8861" name="RB_BLEND_GREEN_F32" type="float" usage="rp_blit"/>
+	<reg32 offset="0x8862" name="RB_BLEND_BLUE_F32" type="float" usage="rp_blit"/>
+	<reg32 offset="0x8863" name="RB_BLEND_ALPHA_F32" type="float" usage="rp_blit"/>
+	<reg32 offset="0x8864" name="RB_ALPHA_CONTROL" usage="cmd">
+		<bitfield name="ALPHA_REF" low="0" high="7" type="hex"/>
+		<bitfield name="ALPHA_TEST" pos="8" type="boolean"/>
+		<bitfield name="ALPHA_TEST_FUNC" low="9" high="11" type="adreno_compare_func"/>
+	</reg32>
+	<reg32 offset="0x8865" name="RB_BLEND_CNTL" usage="rp_blit">
+		<!-- per-mrt enable bit -->
+		<bitfield name="ENABLE_BLEND" low="0" high="7"/>
+		<bitfield name="INDEPENDENT_BLEND" pos="8" type="boolean"/>
+		<bitfield name="DUAL_COLOR_IN_ENABLE" pos="9" type="boolean"/>
+		<bitfield name="ALPHA_TO_COVERAGE" pos="10" type="boolean"/>
+		<bitfield name="ALPHA_TO_ONE" pos="11" type="boolean"/>
+		<bitfield name="SAMPLE_MASK" low="16" high="31"/>
+	</reg32>
+	<!-- 0x8866-0x886f invalid -->
+	<reg32 offset="0x8870" name="RB_DEPTH_PLANE_CNTL" usage="rp_blit">
+		<bitfield name="Z_MODE" low="0" high="1" type="a6xx_ztest_mode"/>
+	</reg32>
+
+	<reg32 offset="0x8871" name="RB_DEPTH_CNTL" usage="rp_blit">
+		<bitfield name="Z_TEST_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="Z_WRITE_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="ZFUNC" low="2" high="4" type="adreno_compare_func"/>
+		<bitfield name="Z_CLAMP_ENABLE" pos="5" type="boolean"/>
+		<doc>
+		Z_READ_ENABLE bit is set for zfunc other than GL_ALWAYS or GL_NEVER
+		also set when Z_BOUNDS_ENABLE is set
+		</doc>
+		<bitfield name="Z_READ_ENABLE" pos="6" type="boolean"/>
+		<bitfield name="Z_BOUNDS_ENABLE" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x8114" name="GRAS_SU_DEPTH_CNTL" usage="rp_blit">
+		<bitfield name="Z_TEST_ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<!-- duplicates GRAS_SU_DEPTH_BUFFER_INFO: -->
+	<reg32 offset="0x8872" name="RB_DEPTH_BUFFER_INFO" variants="A6XX" usage="rp_blit">
+		<bitfield name="DEPTH_FORMAT" low="0" high="2" type="a6xx_depth_format"/>
+		<bitfield name="UNK3" low="3" high="4"/>
+	</reg32>
+	<!-- first 4 bits duplicates GRAS_SU_DEPTH_BUFFER_INFO -->
+	<reg32 offset="0x8872" name="RB_DEPTH_BUFFER_INFO" variants="A7XX-" usage="rp_blit">
+		<bitfield name="DEPTH_FORMAT" low="0" high="2" type="a6xx_depth_format"/>
+		<bitfield name="UNK3" low="3" high="4"/>
+		<bitfield name="TILEMODE" low="5" high="6" type="a6xx_tile_mode"/>
+		<bitfield name="LOSSLESSCOMPEN" pos="7" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x8873" name="RB_DEPTH_BUFFER_PITCH" low="0" high="13" shr="6" type="uint" usage="rp_blit"/>
+	<reg32 offset="0x8874" name="RB_DEPTH_BUFFER_ARRAY_PITCH" low="0" high="27" shr="6" type="uint" usage="rp_blit"/>
+	<reg64 offset="0x8875" name="RB_DEPTH_BUFFER_BASE" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x8877" name="RB_DEPTH_BUFFER_BASE_GMEM" low="12" high="31" shr="12" usage="rp_blit"/>
+
+	<reg32 offset="0x8878" name="RB_Z_BOUNDS_MIN" type="float" usage="rp_blit"/>
+	<reg32 offset="0x8879" name="RB_Z_BOUNDS_MAX" type="float" usage="rp_blit"/>
+	<!-- 0x887a-0x887f invalid -->
+	<reg32 offset="0x8880" name="RB_STENCIL_CONTROL" usage="rp_blit">
+		<bitfield name="STENCIL_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="STENCIL_ENABLE_BF" pos="1" type="boolean"/>
+		<!--
+			set for stencil operations that require read from stencil
+			buffer, but not for example for stencil clear (which does
+			not require read).. so guessing this is analogous to
+			READ_DEST_ENABLE for color buffer..
+		 -->
+		<bitfield name="STENCIL_READ" pos="2" type="boolean"/>
+		<bitfield name="FUNC" low="8" high="10" type="adreno_compare_func"/>
+		<bitfield name="FAIL" low="11" high="13" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS" low="14" high="16" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL" low="17" high="19" type="adreno_stencil_op"/>
+		<bitfield name="FUNC_BF" low="20" high="22" type="adreno_compare_func"/>
+		<bitfield name="FAIL_BF" low="23" high="25" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS_BF" low="26" high="28" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL_BF" low="29" high="31" type="adreno_stencil_op"/>
+	</reg32>
+	<reg32 offset="0x8115" name="GRAS_SU_STENCIL_CNTL" usage="rp_blit">
+		<bitfield name="STENCIL_ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x8881" name="RB_STENCIL_INFO" variants="A6XX" usage="rp_blit">
+		<bitfield name="SEPARATE_STENCIL" pos="0" type="boolean"/>
+		<bitfield name="UNK1" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x8881" name="RB_STENCIL_INFO" variants="A7XX-" usage="rp_blit">
+		<bitfield name="SEPARATE_STENCIL" pos="0" type="boolean"/>
+		<bitfield name="UNK1" pos="1" type="boolean"/>
+		<bitfield name="TILEMODE" low="2" high="3" type="a6xx_tile_mode"/>
+	</reg32>
+	<reg32 offset="0x8882" name="RB_STENCIL_BUFFER_PITCH" low="0" high="11" shr="6" type="uint" usage="rp_blit"/>
+	<reg32 offset="0x8883" name="RB_STENCIL_BUFFER_ARRAY_PITCH" low="0" high="23" shr="6" type="uint" usage="rp_blit"/>
+	<reg64 offset="0x8884" name="RB_STENCIL_BUFFER_BASE" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x8886" name="RB_STENCIL_BUFFER_BASE_GMEM" low="12" high="31" shr="12" usage="rp_blit"/>
+	<reg32 offset="0x8887" name="RB_STENCILREF" usage="rp_blit">
+		<bitfield name="REF" low="0" high="7"/>
+		<bitfield name="BFREF" low="8" high="15"/>
+	</reg32>
+	<reg32 offset="0x8888" name="RB_STENCILMASK" usage="rp_blit">
+		<bitfield name="MASK" low="0" high="7"/>
+		<bitfield name="BFMASK" low="8" high="15"/>
+	</reg32>
+	<reg32 offset="0x8889" name="RB_STENCILWRMASK" usage="rp_blit">
+		<bitfield name="WRMASK" low="0" high="7"/>
+		<bitfield name="BFWRMASK" low="8" high="15"/>
+	</reg32>
+	<!-- 0x888a-0x888f invalid -->
+	<reg32 offset="0x8890" name="RB_WINDOW_OFFSET" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0x8891" name="RB_SAMPLE_COUNT_CONTROL" usage="cmd">
+		<bitfield name="DISABLE" pos="0" type="boolean"/>
+		<bitfield name="COPY" pos="1" type="boolean"/>
+	</reg32>
+	<!-- 0x8892-0x8897 invalid -->
+	<reg32 offset="0x8898" name="RB_LRZ_CNTL" usage="rp_blit">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x8899" name="RB_UNKNOWN_8899" variants="A7XX-" usage="cmd"/>
+	<!-- 0x8899-0x88bf invalid -->
+	<!-- clamps depth value for depth test/write -->
+	<reg32 offset="0x88c0" name="RB_Z_CLAMP_MIN" type="float" usage="rp_blit"/>
+	<reg32 offset="0x88c1" name="RB_Z_CLAMP_MAX" type="float" usage="rp_blit"/>
+	<!-- 0x88c2-0x88cf invalid-->
+	<reg32 offset="0x88d0" name="RB_UNKNOWN_88D0" usage="rp_blit">
+		<bitfield name="UNK0" low="0" high="12"/>
+		<bitfield name="UNK16" low="16" high="26"/>
+	</reg32>
+	<reg32 offset="0x88d1" name="RB_BLIT_SCISSOR_TL" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0x88d2" name="RB_BLIT_SCISSOR_BR" type="a6xx_reg_xy" usage="rp_blit"/>
+	<!-- weird to duplicate other regs from same block?? -->
+	<reg32 offset="0x88d3" name="RB_BIN_CONTROL2" usage="rp_blit">
+		<bitfield name="BINW" low="0" high="5" shr="5" type="uint"/>
+		<bitfield name="BINH" low="8" high="14" shr="4" type="uint"/>
+	</reg32>
+	<reg32 offset="0x88d4" name="RB_WINDOW_OFFSET2" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0x88d5" name="RB_BLIT_GMEM_MSAA_CNTL" usage="rp_blit">
+		<bitfield name="SAMPLES" low="3" high="4" type="a3xx_msaa_samples"/>
+	</reg32>
+	<reg32 offset="0x88d6" name="RB_BLIT_BASE_GMEM" low="12" high="31" shr="12" usage="rp_blit"/>
+	<!-- s/DST_FORMAT/DST_INFO/ probably: -->
+	<reg32 offset="0x88d7" name="RB_BLIT_DST_INFO" usage="rp_blit">
+		<bitfield name="TILE_MODE" low="0" high="1" type="a6xx_tile_mode"/>
+		<bitfield name="FLAGS" pos="2" type="boolean"/>
+		<bitfield name="SAMPLES" low="3" high="4" type="a3xx_msaa_samples"/>
+		<bitfield name="COLOR_SWAP" low="5" high="6" type="a3xx_color_swap"/>
+		<bitfield name="COLOR_FORMAT" low="7" high="14" type="a6xx_format"/>
+		<bitfield name="UNK15" pos="15" type="boolean"/>
+		<bitfield name="MUTABLEEN" pos="16" type="boolean" variants="A7XX-"/>
+	</reg32>
+	<reg64 offset="0x88d8" name="RB_BLIT_DST" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x88da" name="RB_BLIT_DST_PITCH" low="0" high="15" shr="6" type="uint" usage="rp_blit"/>
+	<!-- array-pitch is size of layer -->
+	<reg32 offset="0x88db" name="RB_BLIT_DST_ARRAY_PITCH" low="0" high="28" shr="6" type="uint" usage="rp_blit"/>
+	<reg64 offset="0x88dc" name="RB_BLIT_FLAG_DST" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x88de" name="RB_BLIT_FLAG_DST_PITCH" usage="rp_blit">
+		<bitfield name="PITCH" low="0" high="10" shr="6" type="uint"/>
+		<bitfield name="ARRAY_PITCH" low="11" high="27" shr="7" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x88df" name="RB_BLIT_CLEAR_COLOR_DW0" usage="rp_blit"/>
+	<reg32 offset="0x88e0" name="RB_BLIT_CLEAR_COLOR_DW1" usage="rp_blit"/>
+	<reg32 offset="0x88e1" name="RB_BLIT_CLEAR_COLOR_DW2" usage="rp_blit"/>
+	<reg32 offset="0x88e2" name="RB_BLIT_CLEAR_COLOR_DW3" usage="rp_blit"/>
+
+	<!-- seems somewhat similar to what we called RB_CLEAR_CNTL on a5xx: -->
+	<reg32 offset="0x88e3" name="RB_BLIT_INFO" usage="rp_blit">
+		<bitfield name="UNK0" pos="0" type="boolean"/> <!-- s8 stencil restore/clear?  But also color restore? -->
+		<bitfield name="GMEM" pos="1" type="boolean"/> <!-- set for restore and clear to gmem? -->
+		<bitfield name="SAMPLE_0" pos="2" type="boolean"/> <!-- takes sample 0 instead of averaging -->
+		<bitfield name="DEPTH" pos="3" type="boolean"/> <!-- z16/z32/z24s8/x24x8 clear or resolve? -->
+		<doc>
+			For clearing depth/stencil
+				1 - depth
+				2 - stencil
+				3 - depth+stencil
+			For clearing color buffer:
+				then probably a component mask, I always see 0xf
+		</doc>
+		<bitfield name="CLEAR_MASK" low="4" high="7"/>
+		<!-- set when this is the last resolve on a650+ -->
+		<bitfield name="LAST" low="8" high="9"/>
+		<!--
+			a618 GLES: color render target number being resolved for RM6_RESOLVE, 0x8 for depth, 0x9 for separate stencil.
+			a618 VK: 0x8 for depth RM6_RESOLVE, 0x9 for separate stencil, 0 otherwise.
+
+			We believe this is related to concurrent resolves
+		 -->
+		<bitfield name="BUFFER_ID" low="12" high="15"/>
+	</reg32>
+	<reg32 offset="0x88e4" name="RB_UNKNOWN_88E4" variants="A7XX-" usage="rp_blit">
+		<!-- Value conditioned based on predicate, changed before blits -->
+		<bitfield name="UNK0" pos="0" type="boolean"/>
+	</reg32>
+
+	<enum name="a6xx_ccu_cache_size">
+		<value value="0x0" name="CCU_CACHE_SIZE_FULL"/>
+		<value value="0x1" name="CCU_CACHE_SIZE_HALF"/>
+		<value value="0x2" name="CCU_CACHE_SIZE_QUARTER"/>
+		<value value="0x3" name="CCU_CACHE_SIZE_EIGHTH"/>
+	</enum>
+	<reg32 offset="0x88e5" name="RB_CCU_CNTL2" variants="A7XX-" usage="cmd">
+		<bitfield name="DEPTH_OFFSET_HI" pos="0" type="hex"/>
+		<bitfield name="COLOR_OFFSET_HI" pos="2" type="hex"/>
+		<bitfield name="DEPTH_CACHE_SIZE" low="10" high="11" type="a6xx_ccu_cache_size"/>
+		<!-- GMEM offset of CCU depth cache -->
+		<bitfield name="DEPTH_OFFSET" low="12" high="20" shr="12" type="hex"/>
+		<bitfield name="COLOR_CACHE_SIZE" low="21" high="22" type="a6xx_ccu_cache_size"/>
+		<!-- GMEM offset of CCU color cache
+			for GMEM rendering, we set it to GMEM size minus the minimum
+			CCU color cache size. CCU color cache will be needed in some
+			resolve cases, and in those cases we need to reserve the end
+			of GMEM for color cache.
+		-->
+		<bitfield name="COLOR_OFFSET" low="23" high="31" shr="12" type="hex"/>
+	</reg32>
+	<!-- 0x88e6-0x88ef invalid -->
+	<!-- always 0x0 ? -->
+	<reg32 offset="0x88f0" name="RB_UNKNOWN_88F0" low="0" high="11" usage="cmd"/>
+	<!-- could be for separate stencil? (or may not be a flag buffer at all) -->
+	<reg64 offset="0x88f1" name="RB_UNK_FLAG_BUFFER_BASE" type="waddress" align="64"/>
+	<reg32 offset="0x88f3" name="RB_UNK_FLAG_BUFFER_PITCH">
+		<bitfield name="PITCH" low="0" high="10" shr="6" type="uint"/>
+		<bitfield name="ARRAY_PITCH" low="11" high="23" shr="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x88f4" name="RB_UNKNOWN_88F4" low="0" high="2"/>
+	<!-- Connected to VK_EXT_fragment_density_map? -->
+	<reg32 offset="0x88f5" name="RB_UNKNOWN_88F5" variants="A7XX-"/>
+	<!-- 0x88f6-0x88ff invalid -->
+	<reg64 offset="0x8900" name="RB_DEPTH_FLAG_BUFFER_BASE" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x8902" name="RB_DEPTH_FLAG_BUFFER_PITCH" usage="rp_blit">
+		<bitfield name="PITCH" low="0" high="6" shr="6" type="uint"/>
+		<!-- TODO: actually part of array pitch -->
+		<bitfield name="UNK8" low="8" high="10"/>
+		<bitfield name="ARRAY_PITCH" low="11" high="27" shr="7" type="uint"/>
+	</reg32>
+	<array offset="0x8903" name="RB_MRT_FLAG_BUFFER" stride="3" length="8" usage="rp_blit">
+		<reg64 offset="0" name="ADDR" type="waddress" align="64"/>
+		<reg32 offset="2" name="PITCH">
+			<bitfield name="PITCH" low="0" high="10" shr="6" type="uint"/>
+			<bitfield name="ARRAY_PITCH" low="11" high="28" shr="7" type="uint"/>
+		</reg32>
+	</array>
+	<!-- 0x891b-0x8926 invalid -->
+	<doc>
+		RB_SAMPLE_COUNT_ADDR register is used up to (and including) a730. After that
+		the address is specified through CP_EVENT_WRITE7::WRITE_SAMPLE_COUNT.
+	</doc>
+	<reg64 offset="0x8927" name="RB_SAMPLE_COUNT_ADDR" type="waddress" align="16" usage="cmd"/>
+	<!-- 0x8929-0x89ff invalid -->
+
+	<!-- TODO: there are some registers in the 0x8a00-0x8bff range -->
+
+	<!--
+		These show up in a6xx gen3+ but so far haven't found an example of
+		blob writing non-zero:
+	 -->
+	<reg32 offset="0x8a00" name="RB_UNKNOWN_8A00" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0x8a10" name="RB_UNKNOWN_8A10" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0x8a20" name="RB_UNKNOWN_8A20" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0x8a30" name="RB_UNKNOWN_8A30" variants="A6XX" usage="rp_blit"/>
+
+	<reg32 offset="0x8c00" name="RB_2D_BLIT_CNTL" type="a6xx_2d_blit_cntl" usage="rp_blit"/>
+	<reg32 offset="0x8c01" name="RB_2D_UNKNOWN_8C01" low="0" high="31" usage="rp_blit"/>
+
+	<bitset name="a6xx_2d_src_surf_info" inline="yes">
+		<bitfield name="COLOR_FORMAT" low="0" high="7" type="a6xx_format"/>
+		<bitfield name="TILE_MODE" low="8" high="9" type="a6xx_tile_mode"/>
+		<bitfield name="COLOR_SWAP" low="10" high="11" type="a3xx_color_swap"/>
+		<bitfield name="FLAGS" pos="12" type="boolean"/>
+		<bitfield name="SRGB" pos="13" type="boolean"/>
+		<bitfield name="SAMPLES" low="14" high="15" type="a3xx_msaa_samples"/>
+		<bitfield name="FILTER" pos="16" type="boolean"/>
+		<bitfield name="UNK17" pos="17" type="boolean"/>
+		<bitfield name="SAMPLES_AVERAGE" pos="18" type="boolean"/>
+		<bitfield name="UNK19" pos="19" type="boolean"/>
+		<bitfield name="UNK20" pos="20" type="boolean"/>
+		<bitfield name="UNK21" pos="21" type="boolean"/>
+		<bitfield name="UNK22" pos="22" type="boolean"/>
+		<bitfield name="UNK23" low="23" high="26"/>
+		<bitfield name="UNK28" pos="28" type="boolean"/>
+		<bitfield name="MUTABLEEN" pos="29" type="boolean" variants="A7XX-"/>
+	</bitset>
+
+	<bitset name="a6xx_2d_dst_surf_info" inline="yes">
+		<bitfield name="COLOR_FORMAT" low="0" high="7" type="a6xx_format"/>
+		<bitfield name="TILE_MODE" low="8" high="9" type="a6xx_tile_mode"/>
+		<bitfield name="COLOR_SWAP" low="10" high="11" type="a3xx_color_swap"/>
+		<bitfield name="FLAGS" pos="12" type="boolean"/>
+		<bitfield name="SRGB" pos="13" type="boolean"/>
+		<bitfield name="SAMPLES" low="14" high="15" type="a3xx_msaa_samples"/>
+		<bitfield name="MUTABLEEN" pos="17" type="boolean" variants="A7XX-"/>
+	</bitset>
+
+	<!-- 0x8c02-0x8c16 invalid -->
+	<reg32 offset="0x8c17" name="RB_2D_DST_INFO" type="a6xx_2d_dst_surf_info" usage="rp_blit"/>
+	<reg64 offset="0x8c18" name="RB_2D_DST" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x8c1a" name="RB_2D_DST_PITCH" low="0" high="15" shr="6" type="uint" usage="rp_blit"/>
+	<!-- this is a guess but seems likely (for NV12/IYUV): -->
+	<reg64 offset="0x8c1b" name="RB_2D_DST_PLANE1" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x8c1d" name="RB_2D_DST_PLANE_PITCH" low="0" high="15" shr="6" type="uint" usage="rp_blit"/>
+	<reg64 offset="0x8c1e" name="RB_2D_DST_PLANE2" type="waddress" align="64" usage="rp_blit"/>
+
+	<reg64 offset="0x8c20" name="RB_2D_DST_FLAGS" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x8c22" name="RB_2D_DST_FLAGS_PITCH" low="0" high="7" shr="6" type="uint" usage="rp_blit"/>
+	<!-- this is a guess but seems likely (for NV12 with UBWC): -->
+	<reg64 offset="0x8c23" name="RB_2D_DST_FLAGS_PLANE" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x8c25" name="RB_2D_DST_FLAGS_PLANE_PITCH" low="0" high="7" shr="6" type="uint" usage="rp_blit"/>
+
+	<!-- TODO: 0x8c26-0x8c33 are all full 32-bit registers -->
+	<!-- unlike a5xx, these are per channel values rather than packed -->
+	<reg32 offset="0x8c2c" name="RB_2D_SRC_SOLID_C0" usage="rp_blit"/>
+	<reg32 offset="0x8c2d" name="RB_2D_SRC_SOLID_C1" usage="rp_blit"/>
+	<reg32 offset="0x8c2e" name="RB_2D_SRC_SOLID_C2" usage="rp_blit"/>
+	<reg32 offset="0x8c2f" name="RB_2D_SRC_SOLID_C3" usage="rp_blit"/>
+
+	<reg32 offset="0x8c34" name="RB_UNKNOWN_8C34" variants="A7XX-" usage="cmd"/>
+
+	<!-- 0x8c35-0x8dff invalid -->
+
+	<!-- always 0x1 ? either doesn't exist for a650 or write-only: -->
+	<reg32 offset="0x8e01" name="RB_UNKNOWN_8E01" usage="cmd"/>
+	<!-- 0x8e00-0x8e03 invalid -->
+	<reg32 offset="0x8e04" name="RB_DBG_ECO_CNTL" usage="cmd"/> <!-- TODO: valid mask 0xfffffeff -->
+	<reg32 offset="0x8e05" name="RB_ADDR_MODE_CNTL" pos="0" type="a5xx_address_mode"/>
+	<!-- 0x02080000 in GMEM, zero otherwise?  -->
+	<reg32 offset="0x8e06" name="RB_UNKNOWN_8E06" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0x8e07" name="RB_CCU_CNTL" usage="cmd" variants="A6XX">
+		<bitfield name="GMEM_FAST_CLEAR_DISABLE" pos="0" type="boolean"/>
+		<!-- concurrent resolves are apparently a 2-bit enum on a650+ -->
+		<bitfield name="CONCURRENT_RESOLVE" pos="2" type="boolean"/>
+		<bitfield name="DEPTH_OFFSET_HI" pos="7" type="hex"/>
+		<bitfield name="COLOR_OFFSET_HI" pos="9" type="hex"/>
+		<bitfield name="DEPTH_CACHE_SIZE" low="10" high="11" type="a6xx_ccu_cache_size"/>
+		<!-- GMEM offset of CCU depth cache -->
+		<bitfield name="DEPTH_OFFSET" low="12" high="20" shr="12" type="hex"/>
+		<bitfield name="COLOR_CACHE_SIZE" low="21" high="22" type="a6xx_ccu_cache_size"/>
+		<!-- GMEM offset of CCU color cache
+			for GMEM rendering, we set it to GMEM size minus the minimum
+			CCU color cache size. CCU color cache will be needed in some
+			resolve cases, and in those cases we need to reserve the end
+			of GMEM for color cache.
+		-->
+		<bitfield name="COLOR_OFFSET" low="23" high="31" shr="12" type="hex"/>
+		<!--TODO: valid mask 0xfffffc1f -->
+	</reg32>
+	<reg32 offset="0x8e07" name="RB_CCU_CNTL" usage="cmd" variants="A7XX-">
+		<bitfield name="GMEM_FAST_CLEAR_DISABLE" pos="0" type="boolean"/>
+		<bitfield name="CONCURRENT_RESOLVE" pos="2" type="boolean"/>
+		<!-- rest of the bits were moved to RB_CCU_CNTL2 -->
+	</reg32>
+	<reg32 offset="0x8e08" name="RB_NC_MODE_CNTL">
+		<bitfield name="MODE" pos="0" type="boolean"/>
+		<bitfield name="LOWER_BIT" low="1" high="2" type="uint"/>
+		<bitfield name="MIN_ACCESS_LENGTH" pos="3" type="boolean"/> <!-- true=64b false=32b -->
+		<bitfield name="AMSBC" pos="4" type="boolean"/>
+		<bitfield name="UPPER_BIT" pos="10" type="uint"/>
+		<bitfield name="RGB565_PREDICATOR" pos="11" type="boolean"/>
+		<bitfield name="UNK12" low="12" high="13"/>
+	</reg32>
+	<reg32 offset="0x8e09" name="RB_UNKNOWN_8E09" variants="A7XX-" usage="cmd"/>
+	<!-- 0x8e09-0x8e0f invalid -->
+	<array offset="0x8e10" name="RB_PERFCTR_RB_SEL" stride="1" length="8"/>
+	<array offset="0x8e18" name="RB_PERFCTR_CCU_SEL" stride="1" length="5"/>
+	<!-- 0x8e1d-0x8e1f invalid -->
+	<!-- 0x8e20-0x8e25 more perfcntr sel? -->
+	<!-- 0x8e26-0x8e27 invalid -->
+	<reg32 offset="0x8e28" name="RB_CMP_DBG_ECO_CNTL"/>
+	<!-- 0x8e29-0x8e2b invalid -->
+	<array offset="0x8e2c" name="RB_PERFCTR_CMP_SEL" stride="1" length="4"/>
+	<array offset="0x8e30" name="RB_PERFCTR_UFC_SEL" stride="1" length="6" variants="A7XX-"/>
+	<reg32 offset="0x8e3b" name="RB_RB_SUB_BLOCK_SEL_CNTL_HOST"/>
+	<reg32 offset="0x8e3d" name="RB_RB_SUB_BLOCK_SEL_CNTL_CD"/>
+	<!-- 0x8e3e-0x8e4f invalid -->
+	<!-- GMEM save/restore for preemption: -->
+	<reg32 offset="0x8e50" name="RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE" pos="0" type="boolean"/>
+	<!-- address for GMEM save/restore? -->
+	<reg32 offset="0x8e51" name="RB_UNKNOWN_8E51" type="waddress" align="1"/>
+	<!-- 0x8e53-0x8e7f invalid -->
+	<reg32 offset="0x8e79" name="RB_UNKNOWN_8E79" variants="A7XX-" usage="cmd"/>
+	<!-- 0x8e80-0x8e83 are valid -->
+	<!-- 0x8e84-0x90ff invalid -->
+
+	<!-- 0x9000-0x90ff invalid -->
+
+	<reg32 offset="0x9100" name="VPC_GS_PARAM" variants="A6XX" usage="rp_blit">
+		<bitfield name="LINELENGTHLOC" low="0" high="7" type="uint"/>
+	</reg32>
+
+	<bitset name="a6xx_vpc_xs_clip_cntl" inline="yes">
+		<bitfield name="CLIP_MASK" low="0" high="7" type="uint"/>
+		<!-- there can be up to 8 total clip/cull distance outputs,
+		     but apparenly VPC can only deal with vec4, so when there are
+		     more than 4 outputs a second location needs to be programmed
+		-->
+		<bitfield name="CLIP_DIST_03_LOC" low="8" high="15" type="uint"/>
+		<bitfield name="CLIP_DIST_47_LOC" low="16" high="23" type="uint"/>
+	</bitset>
+	<reg32 offset="0x9101" name="VPC_VS_CLIP_CNTL" type="a6xx_vpc_xs_clip_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9102" name="VPC_GS_CLIP_CNTL" type="a6xx_vpc_xs_clip_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9103" name="VPC_DS_CLIP_CNTL" type="a6xx_vpc_xs_clip_cntl" usage="rp_blit"/>
+
+	<reg32 offset="0x9311" name="VPC_VS_CLIP_CNTL_V2" type="a6xx_vpc_xs_clip_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9312" name="VPC_GS_CLIP_CNTL_V2" type="a6xx_vpc_xs_clip_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9313" name="VPC_DS_CLIP_CNTL_V2" type="a6xx_vpc_xs_clip_cntl" usage="rp_blit"/>
+
+	<bitset name="a6xx_vpc_xs_layer_cntl" inline="yes">
+		<bitfield name="LAYERLOC" low="0" high="7" type="uint"/>
+		<bitfield name="VIEWLOC" low="8" high="15" type="uint"/>
+		<bitfield name="SHADINGRATELOC" low="16" high="23" type="uint" variants="A7XX-"/>
+	</bitset>
+
+	<reg32 offset="0x9104" name="VPC_VS_LAYER_CNTL" type="a6xx_vpc_xs_layer_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9105" name="VPC_GS_LAYER_CNTL" type="a6xx_vpc_xs_layer_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9106" name="VPC_DS_LAYER_CNTL" type="a6xx_vpc_xs_layer_cntl" usage="rp_blit"/>
+
+	<reg32 offset="0x9314" name="VPC_VS_LAYER_CNTL_V2" type="a6xx_vpc_xs_layer_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9315" name="VPC_GS_LAYER_CNTL_V2" type="a6xx_vpc_xs_layer_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9316" name="VPC_DS_LAYER_CNTL_V2" type="a6xx_vpc_xs_layer_cntl" usage="rp_blit"/>
+
+	<reg32 offset="0x9107" name="VPC_UNKNOWN_9107" variants="A6XX" usage="rp_blit">
+		<!-- this mirrors PC_RASTER_CNTL::DISCARD, although it seems it's unused -->
+		<bitfield name="RASTER_DISCARD" pos="0" type="boolean"/>
+		<bitfield name="UNK2" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x9108" name="VPC_POLYGON_MODE" usage="rp_blit">
+		<bitfield name="MODE" low="0" high="1" type="a6xx_polygon_mode"/>
+	</reg32>
+
+	<bitset name="a6xx_primitive_cntl_0" inline="yes">
+		<bitfield name="PRIMITIVE_RESTART" pos="0" type="boolean"/>
+		<bitfield name="PROVOKING_VTX_LAST" pos="1" type="boolean"/>
+		<bitfield name="D3D_VERTEX_ORDERING" pos="2" type="boolean">
+			<doc>
+				Swaps TESS_CW_TRIS/TESS_CCW_TRIS, and also makes
+				triangle fans and triangle strips use the D3D
+				order instead of the OpenGL order.
+			</doc>
+		</bitfield>
+		<bitfield name="UNK3" pos="3" type="boolean"/>
+	</bitset>
+
+	<bitset name="a6xx_primitive_cntl_5" inline="yes">
+		<doc>
+		  geometry shader
+		</doc>
+		<!-- TODO: first 16 bits are valid so something is wrong or missing here -->
+		<bitfield name="GS_VERTICES_OUT" low="0" high="7" type="uint"/>
+		<bitfield name="GS_INVOCATIONS" low="10" high="14" type="uint"/>
+		<bitfield name="LINELENGTHEN" pos="15" type="boolean"/>
+		<bitfield name="GS_OUTPUT" low="16" high="17" type="a6xx_tess_output"/>
+		<bitfield name="UNK18" pos="18"/>
+	</bitset>
+
+	<bitset name="a6xx_multiview_cntl" inline="yes">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="DISABLEMULTIPOS" pos="1" type="boolean">
+			<doc>
+				Multi-position output lets the last geometry
+				stage shader write multiple copies of
+				gl_Position. If disabled then the VS is run once
+				for each view, and ViewID is passed as a
+				register to the VS.
+			</doc>
+		</bitfield>
+		<bitfield name="VIEWS" low="2" high="6" type="uint"/>
+	</bitset>
+
+	<reg32 offset="0x9109" name="VPC_PRIMITIVE_CNTL_0" type="a6xx_primitive_cntl_0" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0x910a" name="VPC_PRIMITIVE_CNTL_5" type="a6xx_primitive_cntl_5" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0x910b" name="VPC_MULTIVIEW_MASK" type="hex" low="0" high="15" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0x910c" name="VPC_MULTIVIEW_CNTL" type="a6xx_multiview_cntl" variants="A7XX-" usage="rp_blit"/>
+
+	<enum name="a6xx_varying_interp_mode">
+		<value value="0" name="INTERP_SMOOTH"/>
+		<value value="1" name="INTERP_FLAT"/>
+		<value value="2" name="INTERP_ZERO"/>
+		<value value="3" name="INTERP_ONE"/>
+	</enum>
+
+	<enum name="a6xx_varying_ps_repl_mode">
+		<value value="0" name="PS_REPL_NONE"/>
+		<value value="1" name="PS_REPL_S"/>
+		<value value="2" name="PS_REPL_T"/>
+		<value value="3" name="PS_REPL_ONE_MINUS_T"/>
+	</enum>
+
+	<!-- 0x9109-0x91ff invalid -->
+	<array offset="0x9200" name="VPC_VARYING_INTERP" stride="1" length="8" usage="rp_blit">
+		<doc>Packed array of a6xx_varying_interp_mode</doc>
+		<reg32 offset="0x0" name="MODE"/>
+	</array>
+	<array offset="0x9208" name="VPC_VARYING_PS_REPL" stride="1" length="8" usage="rp_blit">
+		<doc>Packed array of a6xx_varying_ps_repl_mode</doc>
+		<reg32 offset="0x0" name="MODE"/>
+	</array>
+
+	<!-- always 0x0 -->
+	<reg32 offset="0x9210" name="VPC_UNKNOWN_9210" low="0" high="31" variants="A6XX" usage="cmd"/>
+	<reg32 offset="0x9211" name="VPC_UNKNOWN_9211" low="0" high="31" variants="A6XX" usage="cmd"/>
+
+	<array offset="0x9212" name="VPC_VAR" stride="1" length="4" usage="rp_blit">
+		<!-- one bit per varying component: -->
+		<reg32 offset="0" name="DISABLE"/>
+	</array>
+
+	<reg32 offset="0x9216" name="VPC_SO_CNTL" usage="rp_blit">
+		<!--
+			Choose which DWORD to write to. There is an array of
+			(4 * 64) DWORD's, dumped in the devcoredump at
+			HLSQ_INST_RAM dword 0x400. Each DWORD corresponds to a
+			(VPC location, stream) pair like so:
+
+			location 0, stream 0
+			location 2, stream 0
+			...
+			location 126, stream 0
+			location 0, stream 1
+			location 2, stream 1
+			...
+			location 126, stream 1
+			location 0, stream 2
+			...
+
+			When EmitStreamVertex(N) happens, the HW goes to DWORD
+			64 * N and then "executes" the next 64 DWORD's.
+
+			This field is auto-incremented when VPC_SO_PROG is
+			written to.
+		-->
+		<bitfield name="ADDR" low="0" high="7" type="hex"/>
+		<!-- clear all A_EN and B_EN bits for all DWORD's -->
+		<bitfield name="RESET" pos="16" type="boolean"/>
+	</reg32>
+	<!-- special register, write multiple times to load SO program (not readable) -->
+	<reg32 offset="0x9217" name="VPC_SO_PROG" usage="rp_blit">
+		<bitfield name="A_BUF" low="0" high="1" type="uint"/>
+		<bitfield name="A_OFF" low="2" high="10" shr="2" type="uint"/>
+		<bitfield name="A_EN" pos="11" type="boolean"/>
+		<bitfield name="B_BUF" low="12" high="13" type="uint"/>
+		<bitfield name="B_OFF" low="14" high="22" shr="2" type="uint"/>
+		<bitfield name="B_EN" pos="23" type="boolean"/>
+	</reg32>
+
+	<reg64 offset="0x9218" name="VPC_SO_STREAM_COUNTS" type="waddress" align="32" usage="cmd"/>
+
+	<array offset="0x921a" name="VPC_SO" stride="7" length="4" usage="cmd">
+		<reg64 offset="0" name="BUFFER_BASE" type="waddress" align="32"/>
+		<reg32 offset="2" name="BUFFER_SIZE" low="2" high="31" shr="2"/>
+		<reg32 offset="3" name="BUFFER_STRIDE" low="0" high="9" shr="2"/>
+		<reg32 offset="4" name="BUFFER_OFFSET" low="2" high="31" shr="2"/>
+		<reg64 offset="5" name="FLUSH_BASE" type="waddress" align="32"/>
+	</array>
+
+	<reg32 offset="0x9236" name="VPC_POINT_COORD_INVERT" usage="cmd">
+		<bitfield name="INVERT" pos="0" type="boolean"/>
+	</reg32>
+	<!-- 0x9237-0x92ff invalid -->
+	<!-- always 0x0 ? -->
+	<reg32 offset="0x9300" name="VPC_UNKNOWN_9300" low="0" high="2" usage="cmd"/>
+
+	<bitset name="a6xx_vpc_xs_pack" inline="yes">
+		<doc>
+			num of varyings plus four for gl_Position (plus one if gl_PointSize)
+			plus # of transform-feedback (streamout) varyings if using the
+			hw streamout (rather than stg instructions in shader)
+		</doc>
+		<bitfield name="STRIDE_IN_VPC" low="0" high="7" type="uint"/>
+		<bitfield name="POSITIONLOC" low="8" high="15" type="uint"/>
+		<bitfield name="PSIZELOC" low="16" high="23" type="uint"/>
+		<bitfield name="EXTRAPOS" low="24" high="27" type="uint">
+			<doc>
+				The number of extra copies of POSITION, i.e.
+				number of views minus one when multi-position
+				output is enabled, otherwise 0.
+			</doc>
+		</bitfield>
+	</bitset>
+	<reg32 offset="0x9301" name="VPC_VS_PACK" type="a6xx_vpc_xs_pack" usage="rp_blit"/>
+	<reg32 offset="0x9302" name="VPC_GS_PACK" type="a6xx_vpc_xs_pack" usage="rp_blit"/>
+	<reg32 offset="0x9303" name="VPC_DS_PACK" type="a6xx_vpc_xs_pack" usage="rp_blit"/>
+
+	<reg32 offset="0x9304" name="VPC_CNTL_0" usage="rp_blit">
+		<bitfield name="NUMNONPOSVAR" low="0" high="7" type="uint"/>
+		<!-- for fixed-function (i.e. no GS) gl_PrimitiveID in FS -->
+		<bitfield name="PRIMIDLOC" low="8" high="15" type="uint"/>
+		<bitfield name="VARYING" pos="16" type="boolean"/>
+		<bitfield name="VIEWIDLOC" low="24" high="31" type="uint">
+			<doc>
+				This VPC location will be overwritten with
+				ViewID when multiview is enabled. It's used when
+				fragment shaders read ViewID. It's only
+				strictly required for multi-position output,
+				where the same VS invocation is used for all the
+				views at once, but it can be used when multi-pos
+				output is disabled too, to avoid having to pass
+				ViewID through the VS.
+			</doc>
+		</bitfield>
+	</reg32>
+
+	<reg32 offset="0x9305" name="VPC_SO_STREAM_CNTL" usage="rp_blit">
+		<!--
+		It's offset by 1, and 0 means "disabled"
+		-->
+		<bitfield name="BUF0_STREAM" low="0" high="2" type="uint"/>
+		<bitfield name="BUF1_STREAM" low="3" high="5" type="uint"/>
+		<bitfield name="BUF2_STREAM" low="6" high="8" type="uint"/>
+		<bitfield name="BUF3_STREAM" low="9" high="11" type="uint"/>
+		<bitfield name="STREAM_ENABLE" low="15" high="18" type="hex"/>
+	</reg32>
+	<reg32 offset="0x9306" name="VPC_SO_DISABLE" usage="rp_blit">
+		<bitfield name="DISABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x9307" name="VPC_POLYGON_MODE2" variants="A7XX-" usage="rp_blit">
+		<bitfield name="MODE" low="0" high="1" type="a6xx_polygon_mode"/>
+	</reg32>
+	<reg32 offset="0x9308" name="VPC_ATTR_BUF_SIZE_GMEM" variants="A7XX-" usage="rp_blit">
+		<bitfield name="SIZE_GMEM" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="0x9309" name="VPC_ATTR_BUF_BASE_GMEM" variants="A7XX-" usage="rp_blit">
+		<bitfield name="BASE_GMEM" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="0x9b09" name="PC_ATTR_BUF_SIZE_GMEM" variants="A7XX-" usage="rp_blit">
+		<bitfield name="SIZE_GMEM" low="0" high="31"/>
+	</reg32>
+
+	<!-- 0x9307-0x95ff invalid -->
+
+	<!-- TODO: 0x9600-0x97ff range -->
+	<reg32 offset="0x9600" name="VPC_DBG_ECO_CNTL" usage="cmd"/> <!-- always 0x0 ? TODO: 0x1fbf37ff valid mask -->
+	<reg32 offset="0x9601" name="VPC_ADDR_MODE_CNTL" pos="0" type="a5xx_address_mode" usage="cmd"/>
+	<reg32 offset="0x9602" name="VPC_UNKNOWN_9602" pos="0" usage="cmd"/> <!-- always 0x0 ? -->
+	<reg32 offset="0x9603" name="VPC_UNKNOWN_9603" low="0" high="26"/>
+	<array offset="0x9604" name="VPC_PERFCTR_VPC_SEL" stride="1" length="6" variants="A6XX"/>
+	<array offset="0x960b" name="VPC_PERFCTR_VPC_SEL" stride="1" length="12" variants="A7XX-"/>
+	<!-- 0x960a-0x9623 invalid -->
+	<!-- TODO: regs from 0x9624-0x963a -->
+	<!-- 0x963b-0x97ff invalid -->
+
+	<reg32 offset="0x9800" name="PC_TESS_NUM_VERTEX" low="0" high="5" type="uint" usage="rp_blit"/>
+
+	<!-- always 0x0 ? -->
+	<reg32 offset="0x9801" name="PC_HS_INPUT_SIZE" usage="rp_blit">
+		<bitfield name="SIZE" low="0" high="10" type="uint"/>
+		<bitfield name="UNK13" pos="13"/>
+	</reg32>
+
+	<reg32 offset="0x9802" name="PC_TESS_CNTL" usage="rp_blit">
+		<bitfield name="SPACING" low="0" high="1" type="a6xx_tess_spacing"/>
+		<bitfield name="OUTPUT" low="2" high="3" type="a6xx_tess_output"/>
+	</reg32>
+
+	<reg32 offset="0x9803" name="PC_RESTART_INDEX" low="0" high="31" type="uint" usage="rp_blit"/>
+	<reg32 offset="0x9804" name="PC_MODE_CNTL" low="0" high="7" usage="rp_blit"/>
+
+	<reg32 offset="0x9805" name="PC_POWER_CNTL" low="0" high="2" usage="rp_blit"/>
+
+	<reg32 offset="0x9806" name="PC_PS_CNTL" usage="rp_blit">
+		<bitfield name="PRIMITIVEIDEN" pos="0" type="boolean"/>
+	</reg32>
+
+	<!-- New in a6xx gen3+ -->
+	<reg32 offset="0x9808" name="PC_SO_STREAM_CNTL" usage="rp_blit">
+		<bitfield name="STREAM_ENABLE" low="15" high="18" type="hex"/>
+	</reg32>
+
+	<reg32 offset="0x980a" name="PC_DGEN_SU_CONSERVATIVE_RAS_CNTL">
+		<bitfield name="CONSERVATIVERASEN" pos="0" type="boolean"/>
+	</reg32>
+	<!-- 0x980b-0x983f invalid -->
+
+	<!-- 0x9840 - 0x9842 are not readable -->
+	<reg32 offset="0x9840" name="PC_DRAW_CMD">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+
+	<reg32 offset="0x9841" name="PC_DISPATCH_CMD">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+
+	<reg32 offset="0x9842" name="PC_EVENT_CMD">
+		<!-- I think only the low bit is actually used? -->
+		<bitfield name="STATE_ID" low="16" high="23"/>
+		<bitfield name="EVENT" low="0" high="6" type="vgt_event_type"/>
+	</reg32>
+
+	<!--
+		0x9880 written in a lot of places by SQE, same value gets written
+		to control reg 0x12a.  Set by CP_SET_MARKER, so lets name it after
+		that
+	 -->
+	<reg32 offset="0x9880" name="PC_MARKER"/>
+
+	<!-- 0x9843-0x997f invalid -->
+
+	<reg32 offset="0x9981" name="PC_POLYGON_MODE" variants="A6XX" usage="rp_blit">
+		<bitfield name="MODE" low="0" high="1" type="a6xx_polygon_mode"/>
+	</reg32>
+	<reg32 offset="0x9809" name="PC_POLYGON_MODE" variants="A7XX-" usage="rp_blit">
+		<bitfield name="MODE" low="0" high="1" type="a6xx_polygon_mode"/>
+	</reg32>
+
+	<reg32 offset="0x9980" name="PC_RASTER_CNTL" variants="A6XX" usage="rp_blit">
+		<!-- which stream to send to GRAS -->
+		<bitfield name="STREAM" low="0" high="1" type="uint"/>
+		<!-- discard primitives before rasterization -->
+		<bitfield name="DISCARD" pos="2" type="boolean"/>
+	</reg32>
+	<!-- VPC_RASTER_CNTL -->
+	<reg32 offset="0x9107" name="PC_RASTER_CNTL" variants="A7XX-" usage="rp_blit">
+		<!-- which stream to send to GRAS -->
+		<bitfield name="STREAM" low="0" high="1" type="uint"/>
+		<!-- discard primitives before rasterization -->
+		<bitfield name="DISCARD" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x9317" name="PC_RASTER_CNTL_V2" variants="A7XX-" usage="rp_blit">
+		<!-- which stream to send to GRAS -->
+		<bitfield name="STREAM" low="0" high="1" type="uint"/>
+		<!-- discard primitives before rasterization -->
+		<bitfield name="DISCARD" pos="2" type="boolean"/>
+	</reg32>
+
+	<!-- Both are a750+.
+	     Probably needed to correctly overlap execution of several draws.
+	-->
+	<reg32 offset="0x9885" name="PC_TESS_PARAM_SIZE" variants="A7XX-" usage="cmd"/>
+	<!-- Blob adds a bit more space {0x10, 0x20, 0x30, 0x40} bytes, but the meaning of
+	     this additional space is not known.
+	-->
+	<reg32 offset="0x9886" name="PC_TESS_FACTOR_SIZE" variants="A7XX-" usage="cmd"/>
+
+	<!-- 0x9982-0x9aff invalid -->
+
+	<reg32 offset="0x9b00" name="PC_PRIMITIVE_CNTL_0" type="a6xx_primitive_cntl_0" usage="rp_blit"/>
+
+	<bitset name="a6xx_xs_out_cntl" inline="yes">
+		<doc>
+			num of varyings plus four for gl_Position (plus one if gl_PointSize)
+			plus # of transform-feedback (streamout) varyings if using the
+			hw streamout (rather than stg instructions in shader)
+		</doc>
+		<bitfield name="STRIDE_IN_VPC" low="0" high="7" type="uint"/>
+		<bitfield name="PSIZE" pos="8" type="boolean"/>
+		<bitfield name="LAYER" pos="9" type="boolean"/>
+		<bitfield name="VIEW" pos="10" type="boolean"/>
+		<!-- note: PC_VS_OUT_CNTL doesn't have the PRIMITIVE_ID bit -->
+		<bitfield name="PRIMITIVE_ID" pos="11" type="boolean"/>
+		<bitfield name="CLIP_MASK" low="16" high="23" type="uint"/>
+		<bitfield name="SHADINGRATE" pos="24" type="boolean" variants="A7XX-"/>
+	</bitset>
+
+	<reg32 offset="0x9b01" name="PC_VS_OUT_CNTL" type="a6xx_xs_out_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9b02" name="PC_GS_OUT_CNTL" type="a6xx_xs_out_cntl" usage="rp_blit"/>
+	<!-- since HS can't output anything, only PRIMITIVE_ID is valid -->
+	<reg32 offset="0x9b03" name="PC_HS_OUT_CNTL" type="a6xx_xs_out_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9b04" name="PC_DS_OUT_CNTL" type="a6xx_xs_out_cntl" usage="rp_blit"/>
+
+	<reg32 offset="0x9b05" name="PC_PRIMITIVE_CNTL_5" type="a6xx_primitive_cntl_5" usage="rp_blit"/>
+
+	<reg32 offset="0x9b06" name="PC_PRIMITIVE_CNTL_6" variants="A6XX" usage="rp_blit">
+		<doc>
+		  size in vec4s of per-primitive storage for gs. TODO: not actually in VPC
+		</doc>
+		<bitfield name="STRIDE_IN_VPC" low="0" high="10" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x9b07" name="PC_MULTIVIEW_CNTL" type="a6xx_multiview_cntl" usage="rp_blit"/>
+	<!-- mask of enabled views, doesn't exist on A630 -->
+	<reg32 offset="0x9b08" name="PC_MULTIVIEW_MASK" type="hex" low="0" high="15" usage="rp_blit"/>
+	<!-- 0x9b09-0x9bff invalid -->
+	<reg32 offset="0x9c00" name="PC_2D_EVENT_CMD">
+		<!-- special register (but note first 8 bits can be written/read) -->
+		<bitfield name="EVENT" low="0" high="6" type="vgt_event_type"/>
+		<bitfield name="STATE_ID" low="8" high="15"/>
+	</reg32>
+	<!-- 0x9c01-0x9dff invalid -->
+	<!-- TODO: 0x9e00-0xa000 range incomplete -->
+	<reg32 offset="0x9e00" name="PC_DBG_ECO_CNTL"/>
+	<reg32 offset="0x9e01" name="PC_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg64 offset="0x9e04" name="PC_DRAW_INDX_BASE"/>
+	<reg32 offset="0x9e06" name="PC_DRAW_FIRST_INDX" type="uint"/>
+	<reg32 offset="0x9e07" name="PC_DRAW_MAX_INDICES" type="uint"/>
+	<reg64 offset="0x9e08" name="PC_TESSFACTOR_ADDR" variants="A6XX" type="waddress" align="32" usage="cmd"/>
+	<reg64 offset="0x9810" name="PC_TESSFACTOR_ADDR" variants="A7XX-" type="waddress" align="32" usage="cmd"/>
+
+	<reg32 offset="0x9e0b" name="PC_DRAW_INITIATOR" type="vgt_draw_initiator_a4xx">
+		<doc>
+			Possibly not really "initiating" the draw but the layout is similar
+			to VGT_DRAW_INITIATOR on older gens
+		</doc>
+	</reg32>
+	<reg32 offset="0x9e0c" name="PC_DRAW_NUM_INSTANCES" type="uint"/>
+	<reg32 offset="0x9e0d" name="PC_DRAW_NUM_INDICES" type="uint"/>
+
+	<!-- These match the contents of CP_SET_BIN_DATA (not written directly) -->
+	<reg32 offset="0x9e11" name="PC_VSTREAM_CONTROL">
+		<bitfield name="UNK0" low="0" high="15"/>
+		<bitfield name="VSC_SIZE" low="16" high="21" type="uint"/>
+		<bitfield name="VSC_N" low="22" high="26" type="uint"/>
+	</reg32>
+	<reg64 offset="0x9e12" name="PC_BIN_PRIM_STRM" type="waddress" align="32"/>
+	<reg64 offset="0x9e14" name="PC_BIN_DRAW_STRM" type="waddress" align="32"/>
+
+	<reg32 offset="0x9e1c" name="PC_VISIBILITY_OVERRIDE">
+		<doc>Written by CP_SET_VISIBILITY_OVERRIDE handler</doc>
+		<bitfield name="OVERRIDE" pos="0" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x9e24" name="PC_UNKNOWN_9E24" variants="A7XX-" usage="cmd"/>
+
+	<array offset="0x9e34" name="PC_PERFCTR_PC_SEL" stride="1" length="8" variants="A6XX"/>
+	<array offset="0x9e42" name="PC_PERFCTR_PC_SEL" stride="1" length="16" variants="A7XX-"/>
+
+	<!-- always 0x0 -->
+	<reg32 offset="0x9e72" name="PC_UNKNOWN_9E72" usage="cmd"/>
+
+	<reg32 offset="0xa000" name="VFD_CONTROL_0" usage="rp_blit">
+		<bitfield name="FETCH_CNT" low="0" high="5" type="uint"/>
+		<bitfield name="DECODE_CNT" low="8" high="13" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa001" name="VFD_CONTROL_1" usage="rp_blit">
+		<bitfield name="REGID4VTX" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="REGID4INST" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="REGID4PRIMID" low="16" high="23" type="a3xx_regid"/>
+		<!-- only used for VS in non-multi-position-output case -->
+		<bitfield name="REGID4VIEWID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xa002" name="VFD_CONTROL_2" usage="rp_blit">
+		<bitfield name="REGID_HSRELPATCHID" low="0" high="7" type="a3xx_regid">
+			<doc>
+				This is the ID of the current patch within the
+				subdraw, used to calculate the offset of the
+				patch within the HS->DS buffers. When a draw is
+				split into multiple subdraws then this differs
+				from gl_PrimitiveID on the second, third, etc.
+				subdraws.
+			</doc>
+		</bitfield>
+		<bitfield name="REGID_INVOCATIONID" low="8" high="15" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xa003" name="VFD_CONTROL_3" usage="rp_blit">
+		<bitfield name="REGID_DSPRIMID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="REGID_DSRELPATCHID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="REGID_TESSX" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="REGID_TESSY" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xa004" name="VFD_CONTROL_4" usage="rp_blit">
+		<bitfield name="UNK0" low="0" high="7" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xa005" name="VFD_CONTROL_5" usage="rp_blit">
+		<bitfield name="REGID_GSHEADER" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="UNK8" low="8" high="15" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xa006" name="VFD_CONTROL_6" usage="rp_blit">
+		<!--
+			True if gl_PrimitiveID is read via the FS
+		-->
+		<bitfield name="PRIMID4PSEN" pos="0" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0xa007" name="VFD_MODE_CNTL" usage="cmd">
+		<bitfield name="RENDER_MODE" low="0" high="2" type="a6xx_render_mode"/>
+	</reg32>
+
+	<reg32 offset="0xa008" name="VFD_MULTIVIEW_CNTL" type="a6xx_multiview_cntl" usage="rp_blit"/>
+	<reg32 offset="0xa009" name="VFD_ADD_OFFSET" usage="cmd">
+		<!-- add VFD_INDEX_OFFSET to REGID4VTX -->
+		<bitfield name="VERTEX" pos="0" type="boolean"/>
+		<!-- add VFD_INSTANCE_START_OFFSET to REGID4INST -->
+		<bitfield name="INSTANCE" pos="1" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0xa00e" name="VFD_INDEX_OFFSET" usage="rp_blit"/>
+	<reg32 offset="0xa00f" name="VFD_INSTANCE_START_OFFSET" usage="rp_blit"/>
+	<array offset="0xa010" name="VFD_FETCH" stride="4" length="32" usage="rp_blit">
+		<reg64 offset="0x0" name="BASE" type="address" align="1"/>
+		<reg32 offset="0x2" name="SIZE" type="uint"/>
+		<reg32 offset="0x3" name="STRIDE" low="0" high="11" type="uint"/>
+	</array>
+	<array offset="0xa090" name="VFD_DECODE" stride="2" length="32" usage="rp_blit">
+		<reg32 offset="0x0" name="INSTR">
+			<!-- IDX and byte OFFSET into VFD_FETCH -->
+			<bitfield name="IDX" low="0" high="4" type="uint"/>
+			<bitfield name="OFFSET" low="5" high="16"/>
+			<bitfield name="INSTANCED" pos="17" type="boolean"/>
+			<bitfield name="FORMAT" low="20" high="27" type="a6xx_format"/>
+			<bitfield name="SWAP" low="28" high="29" type="a3xx_color_swap"/>
+			<bitfield name="UNK30" pos="30" type="boolean"/>
+			<bitfield name="FLOAT" pos="31" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x1" name="STEP_RATE" type="uint"/>
+	</array>
+	<array offset="0xa0d0" name="VFD_DEST_CNTL" stride="1" length="32" usage="rp_blit">
+		<reg32 offset="0x0" name="INSTR">
+			<bitfield name="WRITEMASK" low="0" high="3" type="hex"/>
+			<bitfield name="REGID" low="4" high="11" type="a3xx_regid"/>
+		</reg32>
+	</array>
+
+	<reg32 offset="0xa0f8" name="VFD_POWER_CNTL" low="0" high="2" usage="rp_blit"/>
+
+	<reg32 offset="0xa600" name="VFD_UNKNOWN_A600" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xa601" name="VFD_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<array offset="0xa610" name="VFD_PERFCTR_VFD_SEL" stride="1" length="8" variants="A6XX"/>
+	<array offset="0xa610" name="VFD_PERFCTR_VFD_SEL" stride="1" length="16" variants="A7XX-"/>
+
+	<!--
+	Note: this seems to always be paired with another bit in another
+	block.
+	-->
+	<enum name="a6xx_threadsize">
+		<value value="0" name="THREAD64"/>
+		<value value="1" name="THREAD128"/>
+	</enum>
+
+	<bitset name="a6xx_sp_xs_ctrl_reg0" inline="yes">
+		<!-- if set to SINGLE, only use 1 concurrent wave on each SP -->
+		<bitfield name="THREADMODE" pos="0" type="a3xx_threadmode"/>
+		<!--
+		When b31 set we just see FULLREGFOOTPRINT set.  The pattern of
+		used registers is a bit odd too:
+			- used (half): 0-15 68-179 (cnt=128, max=179)
+			- used (full): 0-33 50-69 71 73 75 77 79 81 83 85 87 89-105 107 109 111 113 115 117 119 121 123 125 127>
+		whereas we usually see a (mostly) contiguous range of regs used.  But if
+		I merge the full and half ranges (ie. rN counts as hr(N*2) and hr(N*2+1)),
+		then:
+			- used (merged): 0-191 (cnt=192, max=191)
+		So I think if b31 is set, then the half precision registers overlap
+		the full precision registers.  (Which seems like a pretty sensible
+		feature, actually I'm not sure when you *wouldn't* want to use that,
+		since it gives register allocation more flexibility)
+		 -->
+		<bitfield name="HALFREGFOOTPRINT" low="1" high="6" type="uint"/>
+		<bitfield name="FULLREGFOOTPRINT" low="7" high="12" type="uint"/>
+		<!-- could it be a low bit of branchstack? -->
+		<bitfield name="UNK13" pos="13" type="boolean"/>
+		<!-- seems to be nesting level for flow control:.. -->
+		<bitfield name="BRANCHSTACK" low="14" high="19" type="uint"/>
+	</bitset>
+
+	<bitset name="a6xx_sp_xs_config" inline="yes">
+		<!--
+		Each of these are set if the given resource type is used
+		with the Vulkan/bindless binding model.
+		-->
+		<bitfield name="BINDLESS_TEX" pos="0" type="boolean"/>
+		<bitfield name="BINDLESS_SAMP" pos="1" type="boolean"/>
+		<bitfield name="BINDLESS_IBO" pos="2" type="boolean"/>
+		<bitfield name="BINDLESS_UBO" pos="3" type="boolean"/>
+
+		<bitfield name="ENABLED" pos="8" type="boolean"/>
+		<!--
+		number of textures and samplers.. these might be swapped, with GL I
+		always see the same value for both.
+		 -->
+		<bitfield name="NTEX" low="9" high="16" type="uint"/>
+		<bitfield name="NSAMP" low="17" high="21" type="uint"/>
+		<bitfield name="NIBO" low="22" high="28" type="uint"/>
+	</bitset>
+
+	<bitset name="a6xx_sp_xs_prim_cntl" inline="yes">
+		<!-- # of VS outputs including pos/psize -->
+		<bitfield name="OUT" low="0" high="5" type="uint"/>
+		<!-- FLAGS_REGID only for GS -->
+		<bitfield name="FLAGS_REGID" low="6" high="13" type="a3xx_regid"/>
+	</bitset>
+
+	<reg32 offset="0xa800" name="SP_VS_CTRL_REG0" type="a6xx_sp_xs_ctrl_reg0" usage="rp_blit">
+		<!--
+		This field actually controls all geometry stages. TCS, TES, and
+		GS must have the same mergedregs setting as VS.
+		-->
+		<bitfield name="MERGEDREGS" pos="20" type="boolean"/>
+		<!--
+		Creates a separate preamble-only thread?
+
+		Early preamble has the following limitations:
+		- Only shared, a1, and consts regs could be used
+		  (accessing other regs would result in GPU fault);
+		- No cat5/cat6, only stc/ldc variants are working;
+		- Values writen to shared regs are not accessible by the rest
+		  of the shader;
+		- Instructions before shps are also considered to be a part of
+		  early preamble;
+
+		Note, for all shaders from d3d11 games blob produced preambles
+		compatible with early preamble mode.
+		-->
+		<bitfield name="EARLYPREAMBLE" pos="21" type="boolean"/>
+	</reg32>
+	<!-- bitmask of true/false conditions for VS brac.N instructions,
+	     bit N corresponds to brac.N -->
+	<reg32 offset="0xa801" name="SP_VS_BRANCH_COND" type="hex"/>
+	<!-- # of VS outputs including pos/psize -->
+	<reg32 offset="0xa802" name="SP_VS_PRIMITIVE_CNTL" type="a6xx_sp_xs_prim_cntl" usage="rp_blit"/>
+	<array offset="0xa803" name="SP_VS_OUT" stride="1" length="16" usage="rp_blit">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="A_COMPMASK" low="8" high="11" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="23" type="a3xx_regid"/>
+			<bitfield name="B_COMPMASK" low="24" high="27" type="hex"/>
+		</reg32>
+	</array>
+	<!--
+	Starting with a5xx, position/psize outputs from shader end up in the
+	SP_VS_OUT map, with highest OUTLOCn position.  (Generally they are
+	the last entries too, except when gl_PointCoord is used, blob inserts
+	an extra varying after, but with a lower OUTLOC position.  If present,
+	psize is last, preceded by position.
+	 -->
+	<array offset="0xa813" name="SP_VS_VPC_DST" stride="1" length="8" usage="rp_blit">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="OUTLOC0" low="0" high="7" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="15" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="23" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="31" type="uint"/>
+		</reg32>
+	</array>
+
+	<bitset name="a6xx_sp_xs_pvt_mem_param" inline="yes">
+		<bitfield name="MEMSIZEPERITEM" low="0" high="7" shr="9">
+			<doc>The size of memory that ldp/stp can address.</doc>
+		</bitfield>
+		<bitfield name="HWSTACKSIZEPERTHREAD" low="24" high="31">
+                        <doc>
+				Seems to be the same as a3xx. The maximum stack
+				size in units of 4 calls, so a call depth of 7
+				would result in a value of 2.
+				TODO: What's the actual size per call, i.e. the
+				size of the PC? a3xx docs say it's 16 bits
+				there, but the length register now takes 28 bits
+				so it's probably been bumped to 32 bits.
+                        </doc>
+		</bitfield>
+	</bitset>
+
+	<bitset name="a6xx_sp_xs_pvt_mem_size" inline="yes">
+		<bitfield name="TOTALPVTMEMSIZE" low="0" high="17" shr="12"/>
+		<bitfield name="PERWAVEMEMLAYOUT" pos="31" type="boolean">
+			<doc>
+				There are four indices used to compute the
+				private memory location for an access:
+
+				- stp/ldp offset
+				- fiber id
+				- wavefront id (a swizzled version of what "getwid" returns)
+				- SP ID (the same as what "getspid" returns)
+
+				The stride for the SP ID is always set by
+				TOTALPVTMEMSIZE. In the per-wave layout, the
+				indices are used in this order:
+
+				- offset % 4 (offset within dword)
+				- fiber id
+				- offset / 4
+				- wavefront id
+				- SP ID
+
+				and the stride for the wavefront ID is
+				MEMSIZEPERITEM, multiplied by 128 (fibers per
+				wavefront). In the per-fiber layout, the indices
+				are used in this order:
+
+				- offset
+				- fiber id % 4
+				- wavefront id
+				- fiber id / 4
+				- SP ID
+
+				and the stride for the fiber id/wavefront id
+				combo is MEMSIZEPERITEM.
+
+				Note: Accesses of more than 1 dword do not work
+				with per-fiber layout. The blob will fall back
+				to per-wave instead.
+			</doc>
+		</bitfield>
+	</bitset>
+
+	<bitset name="a6xx_sp_xs_pvt_mem_hw_stack_offset" inline="yes">
+		<doc>
+			This seems to be be the equivalent of HWSTACKOFFSET in
+			a3xx. The ldp/stp offset formula above isn't affected by
+			HWSTACKSIZEPERTHREAD at all, so the HW return address
+			stack seems to be after all the normal per-SP private
+			memory.
+		</doc>
+		<bitfield name="OFFSET" low="0" high="18" shr="11"/>
+	</bitset>
+
+	<reg32 offset="0xa81b" name="SP_VS_OBJ_FIRST_EXEC_OFFSET" type="uint" usage="rp_blit"/>
+	<reg64 offset="0xa81c" name="SP_VS_OBJ_START" type="address" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa81e" name="SP_VS_PVT_MEM_PARAM" type="a6xx_sp_xs_pvt_mem_param" usage="rp_blit"/>
+	<reg64 offset="0xa81f" name="SP_VS_PVT_MEM_ADDR" type="waddress" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa821" name="SP_VS_PVT_MEM_SIZE" type="a6xx_sp_xs_pvt_mem_size" usage="rp_blit"/>
+	<reg32 offset="0xa822" name="SP_VS_TEX_COUNT" low="0" high="7" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa823" name="SP_VS_CONFIG" type="a6xx_sp_xs_config" usage="rp_blit"/>
+	<reg32 offset="0xa824" name="SP_VS_INSTRLEN" low="0" high="27" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa825" name="SP_VS_PVT_MEM_HW_STACK_OFFSET" type="a6xx_sp_xs_pvt_mem_hw_stack_offset" usage="rp_blit"/>
+	<reg32 offset="0xa82d" name="SP_VS_VGPR_CONFIG" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xa830" name="SP_HS_CTRL_REG0" type="a6xx_sp_xs_ctrl_reg0" usage="rp_blit">
+		<!-- There is no mergedregs bit, that comes from the VS. -->
+		<bitfield name="EARLYPREAMBLE" pos="20" type="boolean"/>
+	</reg32>
+	<!--
+	Total size of local storage in dwords divided by the wave size.
+	The maximum value is 64. With the wave size being always 64 for HS,
+	the maximum size of local storage should be:
+	 64 (wavesize) * 64 (SP_HS_WAVE_INPUT_SIZE) * 4 = 16k
+	-->
+	<reg32 offset="0xa831" name="SP_HS_WAVE_INPUT_SIZE" low="0" high="7" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa832" name="SP_HS_BRANCH_COND" type="hex" usage="rp_blit"/>
+
+	<!-- TODO: exact same layout as 0xa81b-0xa825 -->
+	<reg32 offset="0xa833" name="SP_HS_OBJ_FIRST_EXEC_OFFSET" type="uint" usage="rp_blit"/>
+	<reg64 offset="0xa834" name="SP_HS_OBJ_START" type="address" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa836" name="SP_HS_PVT_MEM_PARAM" type="a6xx_sp_xs_pvt_mem_param" usage="rp_blit"/>
+	<reg64 offset="0xa837" name="SP_HS_PVT_MEM_ADDR" type="waddress" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa839" name="SP_HS_PVT_MEM_SIZE" type="a6xx_sp_xs_pvt_mem_size" usage="rp_blit"/>
+	<reg32 offset="0xa83a" name="SP_HS_TEX_COUNT" low="0" high="7" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa83b" name="SP_HS_CONFIG" type="a6xx_sp_xs_config" usage="rp_blit"/>
+	<reg32 offset="0xa83c" name="SP_HS_INSTRLEN" low="0" high="27" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa83d" name="SP_HS_PVT_MEM_HW_STACK_OFFSET" type="a6xx_sp_xs_pvt_mem_hw_stack_offset" usage="rp_blit"/>
+	<reg32 offset="0xa82f" name="SP_HS_VGPR_CONFIG" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xa840" name="SP_DS_CTRL_REG0" type="a6xx_sp_xs_ctrl_reg0" usage="rp_blit">
+		<!-- There is no mergedregs bit, that comes from the VS. -->
+		<bitfield name="EARLYPREAMBLE" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa841" name="SP_DS_BRANCH_COND" type="hex"/>
+
+	<!-- TODO: exact same layout as 0xa802-0xa81a -->
+	<reg32 offset="0xa842" name="SP_DS_PRIMITIVE_CNTL" type="a6xx_sp_xs_prim_cntl" usage="rp_blit"/>
+	<array offset="0xa843" name="SP_DS_OUT" stride="1" length="16" usage="rp_blit">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="A_COMPMASK" low="8" high="11" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="23" type="a3xx_regid"/>
+			<bitfield name="B_COMPMASK" low="24" high="27" type="hex"/>
+		</reg32>
+	</array>
+	<array offset="0xa853" name="SP_DS_VPC_DST" stride="1" length="8" usage="rp_blit">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="OUTLOC0" low="0" high="7" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="15" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="23" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="31" type="uint"/>
+		</reg32>
+	</array>
+
+	<!-- TODO: exact same layout as 0xa81b-0xa825 -->
+	<reg32 offset="0xa85b" name="SP_DS_OBJ_FIRST_EXEC_OFFSET" type="uint" usage="rp_blit"/>
+	<reg64 offset="0xa85c" name="SP_DS_OBJ_START" type="address" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa85e" name="SP_DS_PVT_MEM_PARAM" type="a6xx_sp_xs_pvt_mem_param" usage="rp_blit"/>
+	<reg64 offset="0xa85f" name="SP_DS_PVT_MEM_ADDR" type="waddress" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa861" name="SP_DS_PVT_MEM_SIZE" type="a6xx_sp_xs_pvt_mem_size" usage="rp_blit"/>
+	<reg32 offset="0xa862" name="SP_DS_TEX_COUNT" low="0" high="7" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa863" name="SP_DS_CONFIG" type="a6xx_sp_xs_config" usage="rp_blit"/>
+	<reg32 offset="0xa864" name="SP_DS_INSTRLEN" low="0" high="27" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa865" name="SP_DS_PVT_MEM_HW_STACK_OFFSET" type="a6xx_sp_xs_pvt_mem_hw_stack_offset" usage="rp_blit"/>
+	<reg32 offset="0xa868" name="SP_DS_VGPR_CONFIG" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xa870" name="SP_GS_CTRL_REG0" type="a6xx_sp_xs_ctrl_reg0" usage="rp_blit">
+		<!-- There is no mergedregs bit, that comes from the VS. -->
+		<bitfield name="EARLYPREAMBLE" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa871" name="SP_GS_PRIM_SIZE" low="0" high="7" type="uint" usage="rp_blit">
+		<doc>
+			Normally the size of the output of the last stage in
+			dwords. It should be programmed as follows:
+
+			size less than 63    - size
+			size of 63 (?) or 64 - 63
+			size greater than 64 - 64
+
+			What to program when the size is 61-63 is a guess, but
+			both the blob and ir3 align the size to 4 dword's so it
+			doesn't matter in practice.
+		</doc>
+	</reg32>
+	<reg32 offset="0xa872" name="SP_GS_BRANCH_COND" type="hex" usage="rp_blit"/>
+
+	<!-- TODO: exact same layout as 0xa802-0xa81a -->
+	<reg32 offset="0xa873" name="SP_GS_PRIMITIVE_CNTL" type="a6xx_sp_xs_prim_cntl" usage="rp_blit"/>
+	<array offset="0xa874" name="SP_GS_OUT" stride="1" length="16" usage="rp_blit">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="A_COMPMASK" low="8" high="11" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="23" type="a3xx_regid"/>
+			<bitfield name="B_COMPMASK" low="24" high="27" type="hex"/>
+		</reg32>
+	</array>
+
+	<array offset="0xa884" name="SP_GS_VPC_DST" stride="1" length="8" usage="rp_blit">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="OUTLOC0" low="0" high="7" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="15" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="23" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="31" type="uint"/>
+		</reg32>
+	</array>
+
+	<!-- TODO: exact same layout as 0xa81b-0xa825 -->
+	<reg32 offset="0xa88c" name="SP_GS_OBJ_FIRST_EXEC_OFFSET" type="uint" usage="rp_blit"/>
+	<reg64 offset="0xa88d" name="SP_GS_OBJ_START" type="address" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa88f" name="SP_GS_PVT_MEM_PARAM" type="a6xx_sp_xs_pvt_mem_param" usage="rp_blit"/>
+	<reg64 offset="0xa890" name="SP_GS_PVT_MEM_ADDR" type="waddress" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa892" name="SP_GS_PVT_MEM_SIZE" type="a6xx_sp_xs_pvt_mem_size" usage="rp_blit"/>
+	<reg32 offset="0xa893" name="SP_GS_TEX_COUNT" low="0" high="7" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa894" name="SP_GS_CONFIG" type="a6xx_sp_xs_config" usage="rp_blit"/>
+	<reg32 offset="0xa895" name="SP_GS_INSTRLEN" low="0" high="27" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa896" name="SP_GS_PVT_MEM_HW_STACK_OFFSET" type="a6xx_sp_xs_pvt_mem_hw_stack_offset" usage="rp_blit"/>
+	<reg32 offset="0xa899" name="SP_GS_VGPR_CONFIG" variants="A7XX-" usage="cmd"/>
+
+	<reg64 offset="0xa8a0" name="SP_VS_TEX_SAMP" type="address" align="16" usage="cmd"/>
+	<reg64 offset="0xa8a2" name="SP_HS_TEX_SAMP" type="address" align="16" usage="cmd"/>
+	<reg64 offset="0xa8a4" name="SP_DS_TEX_SAMP" type="address" align="16" usage="cmd"/>
+	<reg64 offset="0xa8a6" name="SP_GS_TEX_SAMP" type="address" align="16" usage="cmd"/>
+	<reg64 offset="0xa8a8" name="SP_VS_TEX_CONST" type="address" align="64" usage="cmd"/>
+	<reg64 offset="0xa8aa" name="SP_HS_TEX_CONST" type="address" align="64" usage="cmd"/>
+	<reg64 offset="0xa8ac" name="SP_DS_TEX_CONST" type="address" align="64" usage="cmd"/>
+	<reg64 offset="0xa8ae" name="SP_GS_TEX_CONST" type="address" align="64" usage="cmd"/>
+
+	<!-- TODO: 4 unknown bool registers 0xa8c0-0xa8c3 -->
+
+	<reg32 offset="0xa980" name="SP_FS_CTRL_REG0" type="a6xx_sp_xs_ctrl_reg0" usage="rp_blit">
+		<bitfield name="THREADSIZE" pos="20" type="a6xx_threadsize"/>
+		<bitfield name="UNK21" pos="21" type="boolean"/>
+		<bitfield name="VARYING" pos="22" type="boolean"/>
+		<bitfield name="LODPIXMASK" pos="23" type="boolean">
+			<doc>
+				Enable ALL helper invocations in a quad. Necessary for
+				fine derivatives and quad subgroup ops.
+			</doc>
+		</bitfield>
+		<!-- note: vk blob uses bit24 -->
+		<bitfield name="UNK24" pos="24" type="boolean"/>
+		<bitfield name="UNK25" pos="25" type="boolean"/>
+		<bitfield name="PIXLODENABLE" pos="26" type="boolean">
+			<doc>
+				Enable helper invocations. Enables 3 out of 4 fragments,
+				because the coarse derivatives only use half of the quad
+				and so one pixel's value is always unused.
+			</doc>
+		</bitfield>
+		<bitfield name="UNK27" pos="27" type="boolean"/>
+		<bitfield name="EARLYPREAMBLE" pos="28" type="boolean"/>
+		<bitfield name="MERGEDREGS" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa981" name="SP_FS_BRANCH_COND" type="hex"/>
+	<reg32 offset="0xa982" name="SP_FS_OBJ_FIRST_EXEC_OFFSET" type="uint" usage="rp_blit"/>
+	<reg64 offset="0xa983" name="SP_FS_OBJ_START" type="address" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa985" name="SP_FS_PVT_MEM_PARAM" type="a6xx_sp_xs_pvt_mem_param" usage="rp_blit"/>
+	<reg64 offset="0xa986" name="SP_FS_PVT_MEM_ADDR" type="waddress" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa988" name="SP_FS_PVT_MEM_SIZE" type="a6xx_sp_xs_pvt_mem_size" usage="rp_blit"/>
+
+	<reg32 offset="0xa989" name="SP_BLEND_CNTL" usage="rp_blit">
+		<!-- per-mrt enable bit -->
+		<bitfield name="ENABLE_BLEND" low="0" high="7"/>
+		<bitfield name="UNK8" pos="8" type="boolean"/>
+		<bitfield name="DUAL_COLOR_IN_ENABLE" pos="9" type="boolean"/>
+		<bitfield name="ALPHA_TO_COVERAGE" pos="10" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa98a" name="SP_SRGB_CNTL" usage="rp_blit">
+		<!-- Same as RB_SRGB_CNTL -->
+		<bitfield name="SRGB_MRT0" pos="0" type="boolean"/>
+		<bitfield name="SRGB_MRT1" pos="1" type="boolean"/>
+		<bitfield name="SRGB_MRT2" pos="2" type="boolean"/>
+		<bitfield name="SRGB_MRT3" pos="3" type="boolean"/>
+		<bitfield name="SRGB_MRT4" pos="4" type="boolean"/>
+		<bitfield name="SRGB_MRT5" pos="5" type="boolean"/>
+		<bitfield name="SRGB_MRT6" pos="6" type="boolean"/>
+		<bitfield name="SRGB_MRT7" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa98b" name="SP_FS_RENDER_COMPONENTS" usage="rp_blit">
+		<bitfield name="RT0" low="0" high="3"/>
+		<bitfield name="RT1" low="4" high="7"/>
+		<bitfield name="RT2" low="8" high="11"/>
+		<bitfield name="RT3" low="12" high="15"/>
+		<bitfield name="RT4" low="16" high="19"/>
+		<bitfield name="RT5" low="20" high="23"/>
+		<bitfield name="RT6" low="24" high="27"/>
+		<bitfield name="RT7" low="28" high="31"/>
+	</reg32>
+	<reg32 offset="0xa98c" name="SP_FS_OUTPUT_CNTL0" usage="rp_blit">
+		<bitfield name="DUAL_COLOR_IN_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="DEPTH_REGID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="SAMPMASK_REGID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="STENCILREF_REGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xa98d" name="SP_FS_OUTPUT_CNTL1" usage="rp_blit">
+		<bitfield name="MRT" low="0" high="3" type="uint"/>
+	</reg32>
+
+	<array offset="0xa98e" name="SP_FS_OUTPUT" stride="1" length="8" usage="rp_blit">
+		<doc>per MRT</doc>
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="HALF_PRECISION" pos="8" type="boolean"/>
+		</reg32>
+	</array>
+
+	<array offset="0xa996" name="SP_FS_MRT" stride="1" length="8" usage="rp_blit">
+		<reg32 offset="0" name="REG">
+			<bitfield name="COLOR_FORMAT" low="0" high="7" type="a6xx_format"/>
+			<bitfield name="COLOR_SINT" pos="8" type="boolean"/>
+			<bitfield name="COLOR_UINT" pos="9" type="boolean"/>
+			<bitfield name="UNK10" pos="10" type="boolean"/>
+		</reg32>
+	</array>
+
+	<reg32 offset="0xa99e" name="SP_FS_PREFETCH_CNTL" usage="rp_blit">
+		<bitfield name="COUNT" low="0" high="2" type="uint"/>
+		<bitfield name="IJ_WRITE_DISABLE" pos="3" type="boolean"/>
+		<doc>
+			Similar to "(eq)" flag but disables helper invocations
+			after the texture prefetch.
+		</doc>
+		<bitfield name="ENDOFQUAD" pos="4" type="boolean" />
+		<doc>
+			Bypass writing to regs and overwrite output with color from
+			CONSTSLOTID const regs.
+		</doc>
+		<bitfield name="WRITE_COLOR_TO_OUTPUT" pos="5" type="boolean"/>
+		<bitfield name="CONSTSLOTID" low="6" high="14" type="uint"/>
+		<!-- Blob never uses it -->
+		<bitfield name="CONSTSLOTID4COORD" low="16" high="24" type="uint" variants="A7XX-"/>
+	</reg32>
+	<array offset="0xa99f" name="SP_FS_PREFETCH" stride="1" length="4" variants="A6XX" usage="rp_blit">
+		<reg32 offset="0" name="CMD" variants="A6XX">
+			<bitfield name="SRC" low="0" high="6" type="uint"/>
+			<bitfield name="SAMP_ID" low="7" high="10" type="uint"/>
+			<bitfield name="TEX_ID" low="11" high="15" type="uint"/>
+			<bitfield name="DST" low="16" high="21" type="a3xx_regid"/>
+			<bitfield name="WRMASK" low="22" high="25" type="hex"/>
+			<bitfield name="HALF" pos="26" type="boolean"/>
+			<doc>Results in color being zero</doc>
+			<bitfield name="UNK27" pos="27" type="boolean"/>
+			<bitfield name="BINDLESS" pos="28" type="boolean"/>
+			<bitfield name="CMD" low="29" high="31" type="a6xx_tex_prefetch_cmd"/>
+		</reg32>
+	</array>
+	<array offset="0xa99f" name="SP_FS_PREFETCH" stride="1" length="4" variants="A7XX-" usage="rp_blit">
+		<reg32 offset="0" name="CMD" variants="A7XX-">
+			<bitfield name="SRC" low="0" high="6" type="uint"/>
+			<bitfield name="SAMP_ID" low="7" high="9" type="uint"/>
+			<bitfield name="TEX_ID" low="10" high="12" type="uint"/>
+			<bitfield name="DST" low="13" high="18" type="a3xx_regid"/>
+			<bitfield name="WRMASK" low="19" high="22" type="hex"/>
+			<bitfield name="HALF" pos="23" type="boolean"/>
+			<bitfield name="BINDLESS" pos="25" type="boolean"/>
+			<bitfield name="CMD" low="26" high="29" type="a6xx_tex_prefetch_cmd"/>
+		</reg32>
+	</array>
+	<array offset="0xa9a3" name="SP_FS_BINDLESS_PREFETCH" stride="1" length="4" usage="rp_blit">
+		<reg32 offset="0" name="CMD">
+			<bitfield name="SAMP_ID" low="0" high="15" type="uint"/>
+			<bitfield name="TEX_ID" low="16" high="31" type="uint"/>
+		</reg32>
+	</array>
+	<reg32 offset="0xa9a7" name="SP_FS_TEX_COUNT" low="0" high="7" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa9a8" name="SP_UNKNOWN_A9A8" low="0" high="16" usage="cmd"/> <!-- always 0x0 ? -->
+	<reg32 offset="0xa9a9" name="SP_FS_PVT_MEM_HW_STACK_OFFSET" type="a6xx_sp_xs_pvt_mem_hw_stack_offset" usage="rp_blit"/>
+
+	<!-- TODO: unknown bool register at 0xa9aa, likely same as 0xa8c0-0xa8c3 but for FS -->
+
+
+
+
+	<reg32 offset="0xa9b0" name="SP_CS_CTRL_REG0" type="a6xx_sp_xs_ctrl_reg0" usage="cmd">
+		<bitfield name="THREADSIZE" pos="20" type="a6xx_threadsize"/>
+		<!-- seems to make SP use less concurrent threads when possible? -->
+		<bitfield name="UNK21" pos="21" type="boolean"/>
+		<!-- has a small impact on performance, not clear what it does -->
+		<bitfield name="UNK22" pos="22" type="boolean"/>
+		<bitfield name="EARLYPREAMBLE" pos="23" type="boolean"/>
+		<bitfield name="MERGEDREGS" pos="31" type="boolean"/>
+	</reg32>
+
+	<!-- set for compute shaders -->
+	<reg32 offset="0xa9b1" name="SP_CS_UNKNOWN_A9B1" usage="cmd">
+		<bitfield name="SHARED_SIZE" low="0" high="4" type="uint">
+			<doc>
+				If 0 - all 32k of shared storage is enabled, otherwise
+				(SHARED_SIZE + 1) * 1k is enabled.
+				The ldl/stl offset seems to be rewritten to 0 when it is beyond
+				this limit. This is different from ldlw/stlw, which wraps at
+				64k (and has 36k of storage on A640 - reads between 36k-64k
+				always return 0)
+			</doc>
+		</bitfield>
+		<bitfield name="UNK5" pos="5" type="boolean"/>
+		<!-- always 1 ? -->
+		<bitfield name="UNK6" pos="6" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa9b2" name="SP_CS_BRANCH_COND" type="hex" usage="cmd"/>
+	<reg32 offset="0xa9b3" name="SP_CS_OBJ_FIRST_EXEC_OFFSET" type="uint" usage="cmd"/>
+	<reg64 offset="0xa9b4" name="SP_CS_OBJ_START" type="address" align="32" usage="cmd"/>
+	<reg32 offset="0xa9b6" name="SP_CS_PVT_MEM_PARAM" type="a6xx_sp_xs_pvt_mem_param" usage="cmd"/>
+	<reg64 offset="0xa9b7" name="SP_CS_PVT_MEM_ADDR" align="32" usage="cmd"/>
+	<reg32 offset="0xa9b9" name="SP_CS_PVT_MEM_SIZE" type="a6xx_sp_xs_pvt_mem_size" usage="cmd"/>
+	<reg32 offset="0xa9ba" name="SP_CS_TEX_COUNT" low="0" high="7" type="uint" usage="cmd"/>
+	<reg32 offset="0xa9bb" name="SP_CS_CONFIG" type="a6xx_sp_xs_config" usage="cmd"/>
+	<reg32 offset="0xa9bc" name="SP_CS_INSTRLEN" low="0" high="27" type="uint" usage="cmd"/>
+	<reg32 offset="0xa9bd" name="SP_CS_PVT_MEM_HW_STACK_OFFSET" type="a6xx_sp_xs_pvt_mem_hw_stack_offset" usage="cmd"/>
+	<reg32 offset="0xa9be" name="SP_CS_UNKNOWN_A9BE" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xa9c5" name="SP_CS_VGPR_CONFIG" variants="A7XX-" usage="cmd"/>
+
+	<!-- new in a6xx gen4, matches HLSQ_CS_CNTL_0 -->
+	<reg32 offset="0xa9c2" name="SP_CS_CNTL_0" usage="cmd">
+		<bitfield name="WGIDCONSTID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="WGSIZECONSTID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="WGOFFSETCONSTID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="LOCALIDREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<!-- new in a6xx gen4, matches HLSQ_CS_CNTL_1 -->
+	<reg32 offset="0xa9c3" name="SP_CS_CNTL_1" variants="A6XX" usage="cmd">
+		<!-- gl_LocalInvocationIndex -->
+		<bitfield name="LINEARLOCALIDREGID" low="0" high="7" type="a3xx_regid"/>
+		<!-- a650 has 6 "SP cores" (but 3 "SP"). this makes it use only
+		     one of those 6 "SP cores" -->
+		<bitfield name="SINGLE_SP_CORE" pos="8" type="boolean"/>
+		<!-- Must match SP_CS_CTRL -->
+		<bitfield name="THREADSIZE" pos="9" type="a6xx_threadsize"/>
+		<!-- 1 thread per wave (ignored if bit9 set) -->
+		<bitfield name="THREADSIZE_SCALAR" pos="10" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0xa9c3" name="SP_CS_CNTL_1" variants="A7XX-" usage="cmd">
+		<!-- gl_LocalInvocationIndex -->
+		<bitfield name="LINEARLOCALIDREGID" low="0" high="7" type="a3xx_regid"/>
+		<!-- Must match SP_CS_CTRL -->
+		<bitfield name="THREADSIZE" pos="8" type="a6xx_threadsize"/>
+		<!-- 1 thread per wave (would hang if THREAD128 is also set) -->
+		<bitfield name="THREADSIZE_SCALAR" pos="9" type="boolean"/>
+
+		<!-- Affects getone. If enabled, getone sometimes executed 1? less times
+		     than there are subgroups.
+		 -->
+		<bitfield name="UNK15" pos="15" type="boolean"/>
+	</reg32>
+
+	<!-- TODO: two 64kb aligned addresses at a9d0/a9d2 -->
+
+	<reg64 offset="0xa9e0" name="SP_FS_TEX_SAMP" type="address" align="16" usage="rp_blit"/>
+	<reg64 offset="0xa9e2" name="SP_CS_TEX_SAMP" type="address" align="16" usage="cmd"/>
+	<reg64 offset="0xa9e4" name="SP_FS_TEX_CONST" type="address" align="64" usage="rp_blit"/>
+	<reg64 offset="0xa9e6" name="SP_CS_TEX_CONST" type="address" align="64" usage="cmd"/>
+
+	<enum name="a6xx_bindless_descriptor_size">
+		<doc>
+			This can alternatively be interpreted as a pitch shift, ie, the
+			descriptor size is 2 &lt;&lt; N dwords
+		</doc>
+		<value value="1" name="BINDLESS_DESCRIPTOR_16B"/>
+		<value value="3" name="BINDLESS_DESCRIPTOR_64B"/>
+	</enum>
+
+	<array offset="0xa9e8" name="SP_CS_BINDLESS_BASE" stride="2" length="5" variants="A6XX" usage="cmd">
+		<reg64 offset="0" name="DESCRIPTOR" variants="A6XX">
+			<bitfield name="DESC_SIZE" low="0" high="1" type="a6xx_bindless_descriptor_size"/>
+			<bitfield name="ADDR" low="2" high="63" shr="2" type="address"/>
+		</reg64>
+	</array>
+	<array offset="0xa9e8" name="SP_CS_BINDLESS_BASE" stride="2" length="8" variants="A7XX-" usage="cmd">
+		<reg64 offset="0" name="DESCRIPTOR" variants="A7XX-">
+			<bitfield name="DESC_SIZE" low="0" high="1" type="a6xx_bindless_descriptor_size"/>
+			<bitfield name="ADDR" low="2" high="63" shr="2" type="address"/>
+		</reg64>
+	</array>
+
+	<!--
+	IBO state for compute shader:
+	 -->
+	<reg64 offset="0xa9f2" name="SP_CS_IBO" type="address" align="16"/>
+	<reg32 offset="0xaa00" name="SP_CS_IBO_COUNT" low="0" high="6" type="uint"/>
+
+	<!-- Correlated with avgs/uvgs usage in FS -->
+	<reg32 offset="0xaa01" name="SP_FS_VGPR_CONFIG" type="uint" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xaa02" name="SP_PS_ALIASED_COMPONENTS_CONTROL" variants="A7XX-" usage="cmd">
+		<bitfield name="ENABLED" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xaa03" name="SP_PS_ALIASED_COMPONENTS" variants="A7XX-" usage="cmd">
+		<doc>
+			Specify for which components the output color should be read
+			from alias, e.g. for:
+
+				alias.1.b32.0 r3.x, c8.x
+				alias.1.b32.0 r2.x, c4.x
+				alias.1.b32.0 r1.x, c4.x
+				alias.1.b32.0 r0.x, c0.x
+
+			the SP_PS_ALIASED_COMPONENTS would be 0x00001111
+		</doc>
+
+		<bitfield name="RT0" low="0" high="3"/>
+		<bitfield name="RT1" low="4" high="7"/>
+		<bitfield name="RT2" low="8" high="11"/>
+		<bitfield name="RT3" low="12" high="15"/>
+		<bitfield name="RT4" low="16" high="19"/>
+		<bitfield name="RT5" low="20" high="23"/>
+		<bitfield name="RT6" low="24" high="27"/>
+		<bitfield name="RT7" low="28" high="31"/>
+	</reg32>
+
+	<reg32 offset="0xaaf2" name="SP_UNKNOWN_AAF2" type="uint" usage="cmd"/>
+
+	<!--
+                This enum is probably similar in purpose to SNORMMODE on a3xx,
+                minus the snorm stuff, i.e. it controls what happens with an
+                out-of-bounds isam/isamm. GL and Vulkan robustness require us to
+                return 0 on out-of-bound textureFetch().
+	-->
+	<enum name="a6xx_isam_mode">
+		<value value="0x1" name="ISAMMODE_CL"/>
+		<value value="0x2" name="ISAMMODE_GL"/>
+	</enum>
+
+	<reg32 offset="0xab00" name="SP_MODE_CONTROL" usage="rp_blit">
+	  <!--
+	  When set, half register loads from the constant file will
+	  load a 32-bit value (so hc0.y loads the same value as c0.y)
+	  and implicitly convert it to 16b (f2f16, or u2u16, based on
+	  operand type).  When unset, half register loads from the
+	  constant file will load 16 bits from the packed constant
+	  file (so hc0.y loads the top 16 bits of the value of c0.x)
+	  -->
+		<bitfield name="CONSTANT_DEMOTION_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="ISAMMODE" low="1" high="2" type="a6xx_isam_mode"/>
+		<bitfield name="SHARED_CONSTS_ENABLE" pos="3" type="boolean"/> <!-- see HLSQ_SHARED_CONSTS -->
+	</reg32>
+
+	<reg32 offset="0xab01" name="SP_UNKNOWN_AB01" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xab02" name="SP_UNKNOWN_AB02" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xab04" name="SP_FS_CONFIG" type="a6xx_sp_xs_config" usage="rp_blit"/>
+	<reg32 offset="0xab05" name="SP_FS_INSTRLEN" low="0" high="27" type="uint" usage="rp_blit"/>
+
+	<array offset="0xab10" name="SP_BINDLESS_BASE" stride="2" length="5" variants="A6XX" usage="rp_blit">
+		<reg64 offset="0" name="DESCRIPTOR" variants="A6XX">
+			<bitfield name="DESC_SIZE" low="0" high="1" type="a6xx_bindless_descriptor_size"/>
+			<bitfield name="ADDR" low="2" high="63" shr="2" type="address"/>
+		</reg64>
+	</array>
+	<array offset="0xab0a" name="SP_BINDLESS_BASE" stride="2" length="8" variants="A7XX-" usage="rp_blit">
+		<reg64 offset="0" name="DESCRIPTOR" variants="A7XX-">
+			<bitfield name="DESC_SIZE" low="0" high="1" type="a6xx_bindless_descriptor_size"/>
+			<bitfield name="ADDR" low="2" high="63" shr="2" type="address"/>
+		</reg64>
+	</array>
+
+	<!--
+	Combined IBO state for 3d pipe, used for Image and SSBO write/atomic
+	instructions VS/HS/DS/GS/FS.  See SP_CS_IBO_* for compute shaders.
+	 -->
+	<reg64 offset="0xab1a" name="SP_IBO" type="address" align="16" usage="cmd"/>
+	<reg32 offset="0xab20" name="SP_IBO_COUNT" low="0" high="6" type="uint" usage="cmd"/>
+
+	<reg32 offset="0xab22" name="SP_UNKNOWN_AB22" variants="A7XX-" usage="cmd"/>
+
+	<bitset name="a6xx_sp_2d_dst_format" inline="yes">
+		<bitfield name="NORM" pos="0" type="boolean"/>
+		<bitfield name="SINT" pos="1" type="boolean"/>
+		<bitfield name="UINT" pos="2" type="boolean"/>
+		<!-- looks like HW only cares about the base type of this format,
+		     which matches the ifmt? -->
+		<bitfield name="COLOR_FORMAT" low="3" high="10" type="a6xx_format"/>
+		<!-- set when ifmt is R2D_UNORM8_SRGB -->
+		<bitfield name="SRGB" pos="11" type="boolean"/>
+		<!-- some sort of channel mask, not sure what it is for -->
+		<bitfield name="MASK" low="12" high="15"/>
+	</bitset>
+
+	<reg32 offset="0xacc0" name="SP_2D_DST_FORMAT" type="a6xx_sp_2d_dst_format" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xa9bf" name="SP_2D_DST_FORMAT" type="a6xx_sp_2d_dst_format" variants="A7XX-" usage="rp_blit"/>
+
+	<reg32 offset="0xae00" name="SP_DBG_ECO_CNTL" usage="cmd"/>
+	<reg32 offset="0xae01" name="SP_ADDR_MODE_CNTL" pos="0" type="a5xx_address_mode"/>
+	<reg32 offset="0xae02" name="SP_NC_MODE_CNTL">
+		<!-- TODO: valid bits 0x3c3f, see kernel -->
+	</reg32>
+	<reg32 offset="0xae03" name="SP_CHICKEN_BITS" usage="cmd"/>
+	<reg32 offset="0xae04" name="SP_FLOAT_CNTL" usage="cmd">
+		<bitfield name="F16_NO_INF" pos="3" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0xae06" name="SP_UNKNOWN_AE06" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xae08" name="SP_UNKNOWN_AE08" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xae09" name="SP_UNKNOWN_AE09" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xae0a" name="SP_UNKNOWN_AE0A" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xae0f" name="SP_PERFCTR_ENABLE" usage="cmd">
+		<!-- some perfcntrs are affected by a per-stage enable bit
+		     (PERF_SP_ALU_WORKING_CYCLES for example)
+		     TODO: verify position of HS/DS/GS bits -->
+		<bitfield name="VS" pos="0" type="boolean"/>
+		<bitfield name="HS" pos="1" type="boolean"/>
+		<bitfield name="DS" pos="2" type="boolean"/>
+		<bitfield name="GS" pos="3" type="boolean"/>
+		<bitfield name="FS" pos="4" type="boolean"/>
+		<bitfield name="CS" pos="5" type="boolean"/>
+	</reg32>
+	<array offset="0xae10" name="SP_PERFCTR_SP_SEL" stride="1" length="24"/>
+	<array offset="0xae60" name="SP_PERFCTR_HLSQ_SEL" stride="1" length="6" variants="A7XX-"/>
+	<reg32 offset="0xae6a" name="SP_UNKNOWN_AE6A" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xae6b" name="SP_UNKNOWN_AE6B" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xae6c" name="SP_UNKNOWN_AE6C" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xae6d" name="SP_READ_SEL" variants="A7XX-">
+		<bitfield name="LOCATION" low="18" high="19" type="a7xx_state_location"/>
+		<bitfield name="PIPE" low="16" high="17" type="a7xx_pipe"/>
+		<bitfield name="STATETYPE" low="8" high="15" type="a7xx_statetype_id"/>
+		<bitfield name="USPTP" low="4" high="7"/>
+		<bitfield name="SPTP" low="0" high="3"/>
+	</reg32>
+	<reg32 offset="0xae71" name="SP_DBG_CNTL" variants="A7XX-"/>
+	<reg32 offset="0xae73" name="SP_UNKNOWN_AE73" variants="A7XX-" usage="cmd"/>
+	<array offset="0xae80" name="SP_PERFCTR_SP_SEL" stride="1" length="36" variants="A7XX-"/>
+	<!-- TODO: there are 4 more percntr select registers (0xae28-0xae2b) -->
+	<!-- TODO: there are a few unknown registers in the 0xae30-0xae52 range -->
+	<reg32 offset="0xbe22" name="SP_CONTEXT_SWITCH_GFX_PREEMPTION_SAFE_MODE"/>
+
+	<!--
+	The downstream kernel calls the debug cluster of registers
+	"a6xx_sp_ps_tp_cluster" but this actually specifies the border
+	color base for compute shaders.
+	-->
+	<reg64 offset="0xb180" name="SP_PS_TP_BORDER_COLOR_BASE_ADDR" type="address" align="128" usage="cmd"/>
+	<reg32 offset="0xb182" name="SP_UNKNOWN_B182" low="0" high="2" usage="cmd"/>
+	<reg32 offset="0xb183" name="SP_UNKNOWN_B183" low="0" high="23" usage="cmd"/>
+
+	<reg32 offset="0xb190" name="SP_UNKNOWN_B190"/>
+	<reg32 offset="0xb191" name="SP_UNKNOWN_B191"/>
+
+	<!-- could be all the stuff below here is actually TPL1?? -->
+
+	<reg32 offset="0xb300" name="SP_TP_RAS_MSAA_CNTL" usage="rp_blit">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="UNK2" low="2" high="3"/>
+	</reg32>
+	<reg32 offset="0xb301" name="SP_TP_DEST_MSAA_CNTL" usage="rp_blit">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="MSAA_DISABLE" pos="2" type="boolean"/>
+	</reg32>
+
+	<!-- looks to work in the same way as a5xx: -->
+	<reg64 offset="0xb302" name="SP_TP_BORDER_COLOR_BASE_ADDR" type="address" align="128" usage="cmd"/>
+	<reg32 offset="0xb304" name="SP_TP_SAMPLE_CONFIG" type="a6xx_sample_config" usage="rp_blit"/>
+	<reg32 offset="0xb305" name="SP_TP_SAMPLE_LOCATION_0" type="a6xx_sample_locations" usage="rp_blit"/>
+	<reg32 offset="0xb306" name="SP_TP_SAMPLE_LOCATION_1" type="a6xx_sample_locations" usage="rp_blit"/>
+	<reg32 offset="0xb307" name="SP_TP_WINDOW_OFFSET" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0xb309" name="SP_TP_MODE_CNTL" usage="cmd">
+		<bitfield name="ISAMMODE" low="0" high="1" type="a6xx_isam_mode"/>
+		<bitfield name="UNK3" low="2" high="7"/>
+	</reg32>
+	<reg32 offset="0xb310" name="SP_UNKNOWN_B310" variants="A7XX-" usage="cmd"/>
+
+	<!--
+	Equiv to corresponding RB_2D_SRC_* regs on a5xx.. which were either
+	badly named or the functionality moved in a6xx.  But downstream kernel
+	calls this "a6xx_sp_ps_tp_2d_cluster"
+	 -->
+	<reg32 offset="0xb4c0" name="SP_PS_2D_SRC_INFO" type="a6xx_2d_src_surf_info" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb4c1" name="SP_PS_2D_SRC_SIZE" variants="A6XX" usage="rp_blit">
+		<bitfield name="WIDTH" low="0" high="14" type="uint"/>
+		<bitfield name="HEIGHT" low="15" high="29" type="uint"/>
+	</reg32>
+	<reg64 offset="0xb4c2" name="SP_PS_2D_SRC" type="address" align="16" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb4c4" name="SP_PS_2D_SRC_PITCH" variants="A6XX" usage="rp_blit">
+		<bitfield name="UNK0" low="0" high="8"/>
+		<bitfield name="PITCH" low="9" high="23" shr="6" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0xb2c0" name="SP_PS_2D_SRC_INFO" type="a6xx_2d_src_surf_info" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xb2c1" name="SP_PS_2D_SRC_SIZE" variants="A7XX">
+		<bitfield name="WIDTH" low="0" high="14" type="uint"/>
+		<bitfield name="HEIGHT" low="15" high="29" type="uint"/>
+	</reg32>
+	<reg64 offset="0xb2c2" name="SP_PS_2D_SRC" type="address" align="16" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xb2c4" name="SP_PS_2D_SRC_PITCH" variants="A7XX">
+		<bitfield name="UNK0" low="0" high="8"/>
+		<bitfield name="PITCH" low="9" high="23" shr="6" type="uint"/>
+	</reg32>
+
+	<!-- planes for NV12, etc. (TODO: not tested) -->
+	<reg64 offset="0xb4c5" name="SP_PS_2D_SRC_PLANE1" type="address" align="16" variants="A6XX"/>
+	<reg32 offset="0xb4c7" name="SP_PS_2D_SRC_PLANE_PITCH" low="0" high="11" shr="6" type="uint" variants="A6XX"/>
+	<reg64 offset="0xb4c8" name="SP_PS_2D_SRC_PLANE2" type="address" align="16" variants="A6XX"/>
+
+	<reg64 offset="0xb2c5" name="SP_PS_2D_SRC_PLANE1" type="address" align="16" variants="A7XX-"/>
+	<reg32 offset="0xb2c7" name="SP_PS_2D_SRC_PLANE_PITCH" low="0" high="11" shr="6" type="uint" variants="A7XX-"/>
+	<reg64 offset="0xb2c8" name="SP_PS_2D_SRC_PLANE2" type="address" align="16" variants="A7XX-"/>
+
+	<reg64 offset="0xb4ca" name="SP_PS_2D_SRC_FLAGS" type="address" align="16" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb4cc" name="SP_PS_2D_SRC_FLAGS_PITCH" low="0" high="7" shr="6" type="uint" variants="A6XX" usage="rp_blit"/>
+
+	<reg64 offset="0xb2ca" name="SP_PS_2D_SRC_FLAGS" type="address" align="16" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xb2cc" name="SP_PS_2D_SRC_FLAGS_PITCH" low="0" high="7" shr="6" type="uint" variants="A7XX-" usage="rp_blit"/>
+
+	<reg32 offset="0xb4cd" name="SP_PS_UNKNOWN_B4CD" low="6" high="31" variants="A6XX"/>
+	<reg32 offset="0xb4ce" name="SP_PS_UNKNOWN_B4CE" low="0" high="31" variants="A6XX"/>
+	<reg32 offset="0xb4cf" name="SP_PS_UNKNOWN_B4CF" low="0" high="30" variants="A6XX"/>
+	<reg32 offset="0xb4d0" name="SP_PS_UNKNOWN_B4D0" low="0" high="29" variants="A6XX"/>
+	<reg32 offset="0xb4d1" name="SP_WINDOW_OFFSET" type="a6xx_reg_xy" variants="A6XX" usage="rp_blit"/>
+
+	<reg32 offset="0xb2cd" name="SP_PS_UNKNOWN_B4CD" low="6" high="31" variants="A7XX"/>
+	<reg32 offset="0xb2ce" name="SP_PS_UNKNOWN_B4CE" low="0" high="31" variants="A7XX"/>
+	<reg32 offset="0xb2cf" name="SP_PS_UNKNOWN_B4CF" low="0" high="30" variants="A7XX"/>
+	<reg32 offset="0xb2d0" name="SP_PS_UNKNOWN_B4D0" low="0" high="29" variants="A7XX"/>
+	<reg32 offset="0xb2d1" name="SP_PS_2D_WINDOW_OFFSET" type="a6xx_reg_xy" variants="A7XX"/>
+	<reg32 offset="0xb2d2" name="SP_PS_UNKNOWN_B2D2" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xab21" name="SP_WINDOW_OFFSET" type="a6xx_reg_xy" variants="A7XX-" usage="rp_blit"/>
+
+	<!-- always 0x100000 or 0x1000000? -->
+	<reg32 offset="0xb600" name="TPL1_DBG_ECO_CNTL" low="0" high="25" usage="cmd"/>
+	<reg32 offset="0xb601" name="TPL1_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0xb602" name="TPL1_DBG_ECO_CNTL1" usage="cmd">
+		<!-- Affects UBWC in some way, if BLIT_OP_SCALE is done with this bit set
+		     and if other blit is done without it - UBWC image may be copied incorrectly.
+		 -->
+		<bitfield name="TP_UBWC_FLAG_HINT" pos="18" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xb604" name="TPL1_NC_MODE_CNTL">
+		<bitfield name="MODE" pos="0" type="boolean"/>
+		<bitfield name="LOWER_BIT" low="1" high="2" type="uint"/>
+		<bitfield name="MIN_ACCESS_LENGTH" pos="3" type="boolean"/> <!-- true=64b false=32b -->
+		<bitfield name="UPPER_BIT" pos="4" type="uint"/>
+		<bitfield name="UNK6" low="6" high="7"/>
+	</reg32>
+	<reg32 offset="0xb605" name="TPL1_UNKNOWN_B605" low="0" high="7" type="uint" variants="A6XX" usage="cmd"/> <!-- always 0x0 or 0x44 ? -->
+
+	<reg32 offset="0xb608" name="TPL1_BICUBIC_WEIGHTS_TABLE_0" low="0" high="29" variants="A6XX"/>
+	<reg32 offset="0xb609" name="TPL1_BICUBIC_WEIGHTS_TABLE_1" low="0" high="29" variants="A6XX"/>
+	<reg32 offset="0xb60a" name="TPL1_BICUBIC_WEIGHTS_TABLE_2" low="0" high="29" variants="A6XX"/>
+	<reg32 offset="0xb60b" name="TPL1_BICUBIC_WEIGHTS_TABLE_3" low="0" high="29" variants="A6XX"/>
+	<reg32 offset="0xb60c" name="TPL1_BICUBIC_WEIGHTS_TABLE_4" low="0" high="29" variants="A6XX"/>
+
+	<reg32 offset="0xb608" name="TPL1_BICUBIC_WEIGHTS_TABLE_0" low="0" high="29" variants="A7XX" usage="cmd"/>
+	<reg32 offset="0xb609" name="TPL1_BICUBIC_WEIGHTS_TABLE_1" low="0" high="29" variants="A7XX" usage="cmd"/>
+	<reg32 offset="0xb60a" name="TPL1_BICUBIC_WEIGHTS_TABLE_2" low="0" high="29" variants="A7XX" usage="cmd"/>
+	<reg32 offset="0xb60b" name="TPL1_BICUBIC_WEIGHTS_TABLE_3" low="0" high="29" variants="A7XX" usage="cmd"/>
+	<reg32 offset="0xb60c" name="TPL1_BICUBIC_WEIGHTS_TABLE_4" low="0" high="29" variants="A7XX" usage="cmd"/>
+
+	<array offset="0xb610" name="TPL1_PERFCTR_TP_SEL" stride="1" length="12" variants="A6XX"/>
+	<array offset="0xb610" name="TPL1_PERFCTR_TP_SEL" stride="1" length="18" variants="A7XX"/>
+
+	<!-- TODO: 4 more perfcntr sel at 0xb620 ? -->
+
+	<bitset name="a6xx_hlsq_xs_cntl" inline="yes">
+		<bitfield name="CONSTLEN" low="0" high="7" shr="2" type="uint"/>
+		<bitfield name="ENABLED" pos="8" type="boolean"/>
+		<bitfield name="READ_IMM_SHARED_CONSTS" pos="9" type="boolean" variants="A7XX-"/>
+	</bitset>
+
+	<reg32 offset="0xb800" name="HLSQ_VS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb801" name="HLSQ_HS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb802" name="HLSQ_DS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb803" name="HLSQ_GS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A6XX" usage="rp_blit"/>
+
+	<reg32 offset="0xa827" name="HLSQ_VS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa83f" name="HLSQ_HS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa867" name="HLSQ_DS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa898" name="HLSQ_GS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A7XX-" usage="rp_blit"/>
+
+	<reg32 offset="0xa9aa" name="HLSQ_FS_UNKNOWN_A9AA" variants="A7XX-" usage="rp_blit">
+		<!-- Tentatively named, appears to disable consts being loaded via CP_LOAD_STATE6_FRAG -->
+		<bitfield name="CONSTS_LOAD_DISABLE" pos="0" type="boolean"/>
+	</reg32>
+
+	<!-- Always 0 -->
+	<reg32 offset="0xa9ac" name="HLSQ_UNKNOWN_A9AC" variants="A7XX-" usage="cmd"/>
+
+	<!-- Used in VK_KHR_fragment_shading_rate -->
+	<reg32 offset="0xa9ad" name="HLSQ_UNKNOWN_A9AD" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xa9ae" name="HLSQ_UNKNOWN_A9AE" variants="A7XX-" usage="rp_blit">
+		<bitfield name="SYSVAL_REGS_COUNT" low="0" high="7" type="uint"/>
+		<!-- UNK8 is set on a730/a740 -->
+		<bitfield name="UNK8" pos="8" type="boolean"/>
+		<!-- UNK9 is set on a750 -->
+		<bitfield name="UNK9" pos="9" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0xb820" name="HLSQ_LOAD_STATE_GEOM_CMD"/>
+	<reg64 offset="0xb821" name="HLSQ_LOAD_STATE_GEOM_EXT_SRC_ADDR" align="16" type="address"/>
+	<reg32 offset="0xb823" name="HLSQ_LOAD_STATE_GEOM_DATA"/>
+
+
+	<bitset name="a6xx_hlsq_fs_cntl_0" inline="yes">
+		<!-- must match SP_FS_CTRL -->
+		<bitfield name="THREADSIZE" pos="0" type="a6xx_threadsize"/>
+		<bitfield name="VARYINGS" pos="1" type="boolean"/>
+		<bitfield name="UNK2" low="2" high="11"/>
+	</bitset>
+	<bitset name="a6xx_hlsq_control_3_reg" inline="yes">
+		<!-- register loaded with position (bary.f) -->
+		<bitfield name="IJ_PERSP_PIXEL" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_PIXEL" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="IJ_PERSP_CENTROID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_CENTROID" low="24" high="31" type="a3xx_regid"/>
+	</bitset>
+	<bitset name="a6xx_hlsq_control_4_reg" inline="yes">
+		<bitfield name="IJ_PERSP_SAMPLE" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_SAMPLE" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="XYCOORDREGID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="ZWCOORDREGID" low="24" high="31" type="a3xx_regid"/>
+	</bitset>
+	<bitset name="a6xx_hlsq_control_5_reg" inline="yes">
+		<bitfield name="LINELENGTHREGID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="FOVEATIONQUALITYREGID" low="8" high="15" type="a3xx_regid"/>
+	</bitset>
+
+	<reg32 offset="0xb980" type="a6xx_hlsq_fs_cntl_0" name="HLSQ_FS_CNTL_0" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb981" name="HLSQ_UNKNOWN_B981" pos="0" type="boolean" variants="A6XX"/> <!-- never used by blob -->
+	<reg32 offset="0xb982" name="HLSQ_CONTROL_1_REG" low="0" high="2" variants="A6XX" usage="rp_blit">
+		<!-- Sets the maximum number of primitives allowed in one FS wave minus one, similarly to the
+				 A3xx field, except that it's not necessary to set it to anything but the maximum, since
+				 the hardware will simply emit smaller waves when it runs out of space.	-->
+		<bitfield name="PRIMALLOCTHRESHOLD" low="0" high="2" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb983" name="HLSQ_CONTROL_2_REG" variants="A6XX" usage="rp_blit">
+		<bitfield name="FACEREGID" low="0" high="7" type="a3xx_regid"/>
+		<!-- SAMPLEID is loaded into a half-precision register: -->
+		<bitfield name="SAMPLEID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="SAMPLEMASK" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="CENTERRHW" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xb984" type="a6xx_hlsq_control_3_reg" name="HLSQ_CONTROL_3_REG" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb985" type="a6xx_hlsq_control_4_reg" name="HLSQ_CONTROL_4_REG" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb986" type="a6xx_hlsq_control_5_reg" name="HLSQ_CONTROL_5_REG" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb987" name="HLSQ_CS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A6XX" usage="cmd"/>
+	<reg32 offset="0xa9c6" type="a6xx_hlsq_fs_cntl_0" name="HLSQ_FS_CNTL_0" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa9c7" name="HLSQ_CONTROL_1_REG" low="0" high="2" variants="A7XX-" usage="rp_blit">
+			<bitfield name="PRIMALLOCTHRESHOLD" low="0" high="2" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa9c8" name="HLSQ_CONTROL_2_REG" variants="A7XX-" usage="rp_blit">
+		<bitfield name="FACEREGID" low="0" high="7" type="a3xx_regid"/>
+		<!-- SAMPLEID is loaded into a half-precision register: -->
+		<bitfield name="SAMPLEID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="SAMPLEMASK" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="CENTERRHW" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xa9c9" type="a6xx_hlsq_control_3_reg" name="HLSQ_CONTROL_3_REG" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa9ca" type="a6xx_hlsq_control_4_reg" name="HLSQ_CONTROL_4_REG" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa9cb" type="a6xx_hlsq_control_5_reg" name="HLSQ_CONTROL_5_REG" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa9cd" name="HLSQ_CS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A7XX-" usage="cmd"/>
+
+	<!-- TODO: what does KERNELDIM do exactly (blob sets it differently from turnip) -->
+	<reg32 offset="0xb990" name="HLSQ_CS_NDRANGE_0" variants="A6XX" usage="rp_blit">
+		<bitfield name="KERNELDIM" low="0" high="1" type="uint"/>
+		<!-- localsize is value minus one: -->
+		<bitfield name="LOCALSIZEX" low="2" high="11" type="uint"/>
+		<bitfield name="LOCALSIZEY" low="12" high="21" type="uint"/>
+		<bitfield name="LOCALSIZEZ" low="22" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb991" name="HLSQ_CS_NDRANGE_1" variants="A6XX" usage="rp_blit">
+		<bitfield name="GLOBALSIZE_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb992" name="HLSQ_CS_NDRANGE_2" variants="A6XX" usage="rp_blit">
+		<bitfield name="GLOBALOFF_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb993" name="HLSQ_CS_NDRANGE_3" variants="A6XX" usage="rp_blit">
+		<bitfield name="GLOBALSIZE_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb994" name="HLSQ_CS_NDRANGE_4" variants="A6XX" usage="rp_blit">
+		<bitfield name="GLOBALOFF_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb995" name="HLSQ_CS_NDRANGE_5" variants="A6XX" usage="rp_blit">
+		<bitfield name="GLOBALSIZE_Z" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb996" name="HLSQ_CS_NDRANGE_6" variants="A6XX" usage="rp_blit">
+		<bitfield name="GLOBALOFF_Z" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb997" name="HLSQ_CS_CNTL_0" variants="A6XX" usage="rp_blit">
+		<!-- these are all vec3. first 3 need to be high regs
+		     WGSIZECONSTID is the local size (from HLSQ_CS_NDRANGE_0)
+		     WGOFFSETCONSTID is WGIDCONSTID*WGSIZECONSTID
+		-->
+		<bitfield name="WGIDCONSTID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="WGSIZECONSTID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="WGOFFSETCONSTID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="LOCALIDREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xb998" name="HLSQ_CS_CNTL_1" variants="A6XX" usage="rp_blit">
+		<!-- gl_LocalInvocationIndex -->
+		<bitfield name="LINEARLOCALIDREGID" low="0" high="7" type="a3xx_regid"/>
+		<!-- a650 has 6 "SP cores" (but 3 "SP"). this makes it use only
+		     one of those 6 "SP cores" -->
+		<bitfield name="SINGLE_SP_CORE" pos="8" type="boolean"/>
+		<!-- Must match SP_CS_CTRL -->
+		<bitfield name="THREADSIZE" pos="9" type="a6xx_threadsize"/>
+		<!-- 1 thread per wave (ignored if bit9 set) -->
+		<bitfield name="THREADSIZE_SCALAR" pos="10" type="boolean"/>
+	</reg32>
+	<!--note: vulkan blob doesn't use these -->
+	<reg32 offset="0xb999" name="HLSQ_CS_KERNEL_GROUP_X" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb99a" name="HLSQ_CS_KERNEL_GROUP_Y" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb99b" name="HLSQ_CS_KERNEL_GROUP_Z" variants="A6XX" usage="rp_blit"/>
+
+	<!-- TODO: what does KERNELDIM do exactly (blob sets it differently from turnip) -->
+	<reg32 offset="0xa9d4" name="HLSQ_CS_NDRANGE_0" variants="A7XX-" usage="rp_blit">
+		<bitfield name="KERNELDIM" low="0" high="1" type="uint"/>
+		<!-- localsize is value minus one: -->
+		<bitfield name="LOCALSIZEX" low="2" high="11" type="uint"/>
+		<bitfield name="LOCALSIZEY" low="12" high="21" type="uint"/>
+		<bitfield name="LOCALSIZEZ" low="22" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa9d5" name="HLSQ_CS_NDRANGE_1" variants="A7XX-" usage="rp_blit">
+		<bitfield name="GLOBALSIZE_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa9d6" name="HLSQ_CS_NDRANGE_2" variants="A7XX-" usage="rp_blit">
+		<bitfield name="GLOBALOFF_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa9d7" name="HLSQ_CS_NDRANGE_3" variants="A7XX-" usage="rp_blit">
+		<bitfield name="GLOBALSIZE_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa9d8" name="HLSQ_CS_NDRANGE_4" variants="A7XX-" usage="rp_blit">
+		<bitfield name="GLOBALOFF_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa9d9" name="HLSQ_CS_NDRANGE_5" variants="A7XX-" usage="rp_blit">
+		<bitfield name="GLOBALSIZE_Z" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa9da" name="HLSQ_CS_NDRANGE_6" variants="A7XX-" usage="rp_blit">
+		<bitfield name="GLOBALOFF_Z" low="0" high="31" type="uint"/>
+	</reg32>
+	<!--note: vulkan blob doesn't use these -->
+	<reg32 offset="0xa9dc" name="HLSQ_CS_KERNEL_GROUP_X" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa9dd" name="HLSQ_CS_KERNEL_GROUP_Y" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa9de" name="HLSQ_CS_KERNEL_GROUP_Z" variants="A7XX-" usage="rp_blit"/>
+
+	<enum name="a7xx_cs_yalign">
+		<value name="CS_YALIGN_1" value="8"/>
+		<value name="CS_YALIGN_2" value="4"/>
+		<value name="CS_YALIGN_4" value="2"/>
+		<value name="CS_YALIGN_8" value="1"/>
+	</enum>
+
+	<reg32 offset="0xa9db" name="HLSQ_CS_CNTL_1" variants="A7XX-" usage="rp_blit">
+		<!-- gl_LocalInvocationIndex -->
+		<bitfield name="LINEARLOCALIDREGID" low="0" high="7" type="a3xx_regid"/>
+		<!-- Must match SP_CS_CTRL -->
+		<bitfield name="THREADSIZE" pos="9" type="a6xx_threadsize"/>
+		<bitfield name="UNK11" pos="11" type="boolean"/>
+		<bitfield name="UNK22" pos="22" type="boolean"/>
+		<bitfield name="UNK26" pos="26" type="boolean"/>
+		<bitfield name="YALIGN" low="27" high="30" type="a7xx_cs_yalign"/>
+	</reg32>
+
+	<reg32 offset="0xa9df" name="HLSQ_CS_LOCAL_SIZE" variants="A7XX-" usage="cmd">
+		<!-- localsize is value minus one: -->
+		<bitfield name="LOCALSIZEX" low="2" high="11" type="uint"/>
+		<bitfield name="LOCALSIZEY" low="12" high="21" type="uint"/>
+		<bitfield name="LOCALSIZEZ" low="22" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0xb9a0" name="HLSQ_LOAD_STATE_FRAG_CMD"/>
+	<reg64 offset="0xb9a1" name="HLSQ_LOAD_STATE_FRAG_EXT_SRC_ADDR" align="16" type="address"/>
+	<reg32 offset="0xb9a3" name="HLSQ_LOAD_STATE_FRAG_DATA"/>
+
+	<!-- mirror of SP_CS_BINDLESS_BASE -->
+	<array offset="0xb9c0" name="HLSQ_CS_BINDLESS_BASE" stride="2" length="5" variants="A6XX" usage="rp_blit">
+		<reg64 offset="0" name="DESCRIPTOR">
+			<bitfield name="DESC_SIZE" low="0" high="1" type="a6xx_bindless_descriptor_size"/>
+			<bitfield name="ADDR" low="2" high="63" shr="2" type="address"/>
+		</reg64>
+	</array>
+
+	<!-- new in a6xx gen4, mirror of SP_CS_UNKNOWN_A9B1? -->
+	<reg32 offset="0xb9d0" name="HLSQ_CS_UNKNOWN_B9D0" variants="A6XX" usage="cmd">
+		<bitfield name="SHARED_SIZE" low="0" high="4" type="uint"/>
+		<bitfield name="UNK5" pos="5" type="boolean"/>
+		<!-- always 1 ? -->
+		<bitfield name="UNK6" pos="6" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0xbb00" name="HLSQ_DRAW_CMD" variants="A6XX">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+
+	<reg32 offset="0xbb01" name="HLSQ_DISPATCH_CMD" variants="A6XX">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+
+	<reg32 offset="0xbb02" name="HLSQ_EVENT_CMD" variants="A6XX">
+		<!-- I think only the low bit is actually used? -->
+		<bitfield name="STATE_ID" low="16" high="23"/>
+		<bitfield name="EVENT" low="0" high="6" type="vgt_event_type"/>
+	</reg32>
+
+	<reg32 offset="0xbb08" name="HLSQ_INVALIDATE_CMD" variants="A6XX" usage="cmd">
+		<doc>
+			This register clears pending loads queued up by
+			CP_LOAD_STATE6. Each bit resets a particular kind(s) of
+			CP_LOAD_STATE6.
+		</doc>
+
+		<!-- per-stage state: shader, non-bindless UBO, textures, and samplers -->
+		<bitfield name="VS_STATE" pos="0" type="boolean"/>
+		<bitfield name="HS_STATE" pos="1" type="boolean"/>
+		<bitfield name="DS_STATE" pos="2" type="boolean"/>
+		<bitfield name="GS_STATE" pos="3" type="boolean"/>
+		<bitfield name="FS_STATE" pos="4" type="boolean"/>
+		<bitfield name="CS_STATE" pos="5" type="boolean"/>
+
+		<bitfield name="CS_IBO" pos="6" type="boolean"/>
+		<bitfield name="GFX_IBO" pos="7" type="boolean"/>
+
+		<!-- Note: these only do something when HLSQ_SHARED_CONSTS is set to 1 -->
+		<bitfield name="CS_SHARED_CONST" pos="19" type="boolean"/>
+		<bitfield name="GFX_SHARED_CONST" pos="8" type="boolean"/>
+
+		<!-- SS6_BINDLESS: one bit per bindless base -->
+		<bitfield name="CS_BINDLESS" low="9" high="13" type="hex"/>
+		<bitfield name="GFX_BINDLESS" low="14" high="18" type="hex"/>
+	</reg32>
+
+	<reg32 offset="0xab1c" name="HLSQ_DRAW_CMD" variants="A7XX-">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+
+	<reg32 offset="0xab1d" name="HLSQ_DISPATCH_CMD" variants="A7XX-">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+
+	<reg32 offset="0xab1e" name="HLSQ_EVENT_CMD" variants="A7XX-">
+		<bitfield name="STATE_ID" low="16" high="23"/>
+		<bitfield name="EVENT" low="0" high="6" type="vgt_event_type"/>
+	</reg32>
+
+	<reg32 offset="0xab1f" name="HLSQ_INVALIDATE_CMD" variants="A7XX-" usage="cmd">
+		<doc>
+			This register clears pending loads queued up by
+			CP_LOAD_STATE6. Each bit resets a particular kind(s) of
+			CP_LOAD_STATE6.
+		</doc>
+
+		<!-- per-stage state: shader, non-bindless UBO, textures, and samplers -->
+		<bitfield name="VS_STATE" pos="0" type="boolean"/>
+		<bitfield name="HS_STATE" pos="1" type="boolean"/>
+		<bitfield name="DS_STATE" pos="2" type="boolean"/>
+		<bitfield name="GS_STATE" pos="3" type="boolean"/>
+		<bitfield name="FS_STATE" pos="4" type="boolean"/>
+		<bitfield name="CS_STATE" pos="5" type="boolean"/>
+
+		<bitfield name="CS_IBO" pos="6" type="boolean"/>
+		<bitfield name="GFX_IBO" pos="7" type="boolean"/>
+
+		<!-- SS6_BINDLESS: one bit per bindless base -->
+		<bitfield name="CS_BINDLESS" low="9" high="16" type="hex"/>
+		<bitfield name="GFX_BINDLESS" low="17" high="24" type="hex"/>
+	</reg32>
+
+	<reg32 offset="0xbb10" name="HLSQ_FS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xab03" name="HLSQ_FS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A7XX-" usage="rp_blit"/>
+
+	<array offset="0xab40" name="HLSQ_SHARED_CONSTS_IMM" stride="1" length="64" variants="A7XX-"/>
+
+	<reg32 offset="0xbb11" name="HLSQ_SHARED_CONSTS" variants="A6XX" usage="cmd">
+		<doc>
+			Shared constants are intended to be used for Vulkan push
+			constants. When enabled, 8 vec4's are reserved in the FS
+			const pool and 16 in the geometry const pool although
+			only 8 are actually used (why?) and they are mapped to
+			c504-c511 in each stage. Both VS and FS shared consts
+			are written using ST6_CONSTANTS/SB6_IBO, so that both
+			the geometry and FS shared consts can be written at once
+			by using CP_LOAD_STATE6 rather than
+			CP_LOAD_STATE6_FRAG/CP_LOAD_STATE6_GEOM. In addition
+			DST_OFF and NUM_UNIT are in units of dwords instead of
+			vec4's.
+
+			There is also a separate shared constant pool for CS,
+			which is loaded through CP_LOAD_STATE6_FRAG with
+			ST6_UBO/ST6_IBO. However the only real difference for CS
+			is the dword units.
+		</doc>
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+	</reg32>
+
+	<!-- mirror of SP_BINDLESS_BASE -->
+	<array offset="0xbb20" name="HLSQ_BINDLESS_BASE" stride="2" length="5" variants="A6XX" usage="cmd">
+		<reg64 offset="0" name="DESCRIPTOR">
+			<bitfield name="DESC_SIZE" low="0" high="1" type="a6xx_bindless_descriptor_size"/>
+			<bitfield name="ADDR" low="2" high="63" shr="2" type="address"/>
+		</reg64>
+	</array>
+
+	<reg32 offset="0xbd80" name="HLSQ_2D_EVENT_CMD">
+		<bitfield name="STATE_ID" low="8" high="15"/>
+		<bitfield name="EVENT" low="0" high="6" type="vgt_event_type"/>
+	</reg32>
+
+	<reg32 offset="0xbe00" name="HLSQ_UNKNOWN_BE00" variants="A6XX" usage="cmd"/> <!-- all bits valid except bit 29 -->
+	<reg32 offset="0xbe01" name="HLSQ_UNKNOWN_BE01" low="4" high="6" variants="A6XX" usage="cmd"/>
+	<reg32 offset="0xbe04" name="HLSQ_DBG_ECO_CNTL" variants="A6XX" usage="cmd"/>
+	<reg32 offset="0xbe05" name="HLSQ_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0xbe08" name="HLSQ_UNKNOWN_BE08" low="0" high="15"/>
+	<array offset="0xbe10" name="HLSQ_PERFCTR_HLSQ_SEL" stride="1" length="6"/>
+
+	<!-- TODO: some valid registers between 0xbe20 and 0xbe33 -->
+	<reg32 offset="0xbe22" name="HLSQ_CONTEXT_SWITCH_GFX_PREEMPTION_SAFE_MODE"/>
+
+	<reg32 offset="0xc000" name="SP_AHB_READ_APERTURE" variants="A7XX-"/>
+
+	<!-- Don't know if these are SP, always 0 -->
+	<reg64 offset="0x0ce2" name="SP_UNKNOWN_0CE2" variants="A7XX-" usage="cmd"/>
+	<reg64 offset="0x0ce4" name="SP_UNKNOWN_0CE4" variants="A7XX-" usage="cmd"/>
+	<reg64 offset="0x0ce6" name="SP_UNKNOWN_0CE6" variants="A7XX-" usage="cmd"/>
+
+	<!--
+		These special registers signal the beginning/end of an event
+		sequence. The sequence used internally for an event looks like:
+		- write EVENT_CMD pipe register
+		- write CP_EVENT_START
+		- write HLSQ_EVENT_CMD with event or HLSQ_DRAW_CMD
+		- write PC_EVENT_CMD with event or PC_DRAW_CMD
+		- write HLSQ_EVENT_CMD(CONTEXT_DONE)
+		- write PC_EVENT_CMD(CONTEXT_DONE)
+		- write CP_EVENT_END
+		Writing to CP_EVENT_END seems to actually trigger the context roll
+	-->
+	<reg32 offset="0xd600" name="CP_EVENT_START">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+	<reg32 offset="0xd601" name="CP_EVENT_END">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+	<reg32 offset="0xd700" name="CP_2D_EVENT_START">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+	<reg32 offset="0xd701" name="CP_2D_EVENT_END">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+</domain>
+
+<!-- Seems basically the same as a5xx, maybe move to common.xml.. -->
+<domain name="A6XX_TEX_SAMP" width="32">
+	<doc>Texture sampler dwords</doc>
+	<enum name="a6xx_tex_filter"> <!-- same as a4xx? -->
+		<value name="A6XX_TEX_NEAREST" value="0"/>
+		<value name="A6XX_TEX_LINEAR" value="1"/>
+		<value name="A6XX_TEX_ANISO" value="2"/>
+		<value name="A6XX_TEX_CUBIC" value="3"/> <!-- a650 only -->
+	</enum>
+	<enum name="a6xx_tex_clamp"> <!-- same as a4xx? -->
+		<value name="A6XX_TEX_REPEAT" value="0"/>
+		<value name="A6XX_TEX_CLAMP_TO_EDGE" value="1"/>
+		<value name="A6XX_TEX_MIRROR_REPEAT" value="2"/>
+		<value name="A6XX_TEX_CLAMP_TO_BORDER" value="3"/>
+		<value name="A6XX_TEX_MIRROR_CLAMP" value="4"/>
+	</enum>
+	<enum name="a6xx_tex_aniso"> <!-- same as a4xx? -->
+		<value name="A6XX_TEX_ANISO_1" value="0"/>
+		<value name="A6XX_TEX_ANISO_2" value="1"/>
+		<value name="A6XX_TEX_ANISO_4" value="2"/>
+		<value name="A6XX_TEX_ANISO_8" value="3"/>
+		<value name="A6XX_TEX_ANISO_16" value="4"/>
+	</enum>
+	<enum name="a6xx_reduction_mode">
+		<value name="A6XX_REDUCTION_MODE_AVERAGE" value="0"/>
+		<value name="A6XX_REDUCTION_MODE_MIN" value="1"/>
+		<value name="A6XX_REDUCTION_MODE_MAX" value="2"/>
+	</enum>
+
+	<reg32 offset="0" name="0">
+		<bitfield name="MIPFILTER_LINEAR_NEAR" pos="0" type="boolean"/>
+		<bitfield name="XY_MAG" low="1" high="2" type="a6xx_tex_filter"/>
+		<bitfield name="XY_MIN" low="3" high="4" type="a6xx_tex_filter"/>
+		<bitfield name="WRAP_S" low="5" high="7" type="a6xx_tex_clamp"/>
+		<bitfield name="WRAP_T" low="8" high="10" type="a6xx_tex_clamp"/>
+		<bitfield name="WRAP_R" low="11" high="13" type="a6xx_tex_clamp"/>
+		<bitfield name="ANISO" low="14" high="16" type="a6xx_tex_aniso"/>
+		<bitfield name="LOD_BIAS" low="19" high="31" type="fixed" radix="8"/><!-- no idea how many bits for real -->
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="CLAMPENABLE" pos="0" type="boolean">
+			<doc>
+				clamp result to [0, 1] if the format is unorm or
+				[-1, 1] if the format is snorm, *after*
+				filtering. Has no effect for other formats.
+			</doc>
+		</bitfield>
+		<bitfield name="COMPARE_FUNC" low="1" high="3" type="adreno_compare_func"/>
+		<bitfield name="CUBEMAPSEAMLESSFILTOFF" pos="4" type="boolean"/>
+		<bitfield name="UNNORM_COORDS" pos="5" type="boolean"/>
+		<bitfield name="MIPFILTER_LINEAR_FAR" pos="6" type="boolean"/>
+		<bitfield name="MAX_LOD" low="8" high="19" type="ufixed" radix="8"/>
+		<bitfield name="MIN_LOD" low="20" high="31" type="ufixed" radix="8"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="REDUCTION_MODE" low="0" high="1" type="a6xx_reduction_mode"/>
+		<bitfield name="CHROMA_LINEAR" pos="5" type="boolean"/>
+		<bitfield name="BCOLOR" low="7" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3"/>
+</domain>
+
+<domain name="A6XX_TEX_CONST" width="32" varset="chip">
+	<doc>Texture constant dwords</doc>
+	<enum name="a6xx_tex_swiz"> <!-- same as a4xx? -->
+		<value name="A6XX_TEX_X" value="0"/>
+		<value name="A6XX_TEX_Y" value="1"/>
+		<value name="A6XX_TEX_Z" value="2"/>
+		<value name="A6XX_TEX_W" value="3"/>
+		<value name="A6XX_TEX_ZERO" value="4"/>
+		<value name="A6XX_TEX_ONE" value="5"/>
+	</enum>
+	<enum name="a6xx_tex_type"> <!-- same as a4xx? -->
+		<value name="A6XX_TEX_1D" value="0"/>
+		<value name="A6XX_TEX_2D" value="1"/>
+		<value name="A6XX_TEX_CUBE" value="2"/>
+		<value name="A6XX_TEX_3D" value="3"/>
+		<value name="A6XX_TEX_BUFFER" value="4"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="TILE_MODE" low="0" high="1" type="a6xx_tile_mode"/>
+		<bitfield name="SRGB" pos="2" type="boolean"/>
+		<bitfield name="SWIZ_X" low="4" high="6" type="a6xx_tex_swiz"/>
+		<bitfield name="SWIZ_Y" low="7" high="9" type="a6xx_tex_swiz"/>
+		<bitfield name="SWIZ_Z" low="10" high="12" type="a6xx_tex_swiz"/>
+		<bitfield name="SWIZ_W" low="13" high="15" type="a6xx_tex_swiz"/>
+		<bitfield name="MIPLVLS" low="16" high="19" type="uint"/>
+		<!-- overlaps with MIPLVLS -->
+		<bitfield name="CHROMA_MIDPOINT_X" pos="16" type="boolean"/>
+		<bitfield name="CHROMA_MIDPOINT_Y" pos="18" type="boolean"/>
+		<bitfield name="SAMPLES" low="20" high="21" type="a3xx_msaa_samples"/>
+		<bitfield name="FMT" low="22" high="29" type="a6xx_format"/>
+		<!--
+			Why is the swap needed in addition to SWIZ_*? The swap
+			is performed before border color replacement, while the
+			swizzle is applied after after it.
+		-->
+		<bitfield name="SWAP" low="30" high="31" type="a3xx_color_swap"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="WIDTH" low="0" high="14" type="uint"/>
+		<bitfield name="HEIGHT" low="15" high="29" type="uint"/>
+		<bitfield name="MUTABLEEN" pos="31" type="boolean" variants="A7XX-"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<!--
+			These fields overlap PITCH, and are used instead of
+			PITCH/PITCHALIGN when TYPE is A6XX_TEX_BUFFER.
+		 -->
+		<doc> probably for D3D structured UAVs, normally set to 1 </doc>
+		<bitfield name="STRUCTSIZETEXELS" low="4" high="15" type="uint"/>
+		<bitfield name="STARTOFFSETTEXELS" low="16" high="21" type="uint"/>
+
+		<!-- minimum pitch (for mipmap levels): log2(pitchalign / 64) -->
+		<bitfield name="PITCHALIGN" low="0" high="3" type="uint"/>
+		<doc>Pitch in bytes (so actually stride)</doc>
+		<bitfield name="PITCH" low="7" high="28" type="uint"/>
+		<bitfield name="TYPE" low="29" high="31" type="a6xx_tex_type"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<!--
+		ARRAY_PITCH is basically LAYERSZ for the first mipmap level, and
+		for 3d textures (laid out mipmap level first) MIN_LAYERSZ is the
+		layer size at the point that it stops being reduced moving to
+		higher (smaller) mipmap levels
+		 -->
+		<bitfield name="ARRAY_PITCH" low="0" high="22" shr="12" type="uint"/>
+		<bitfield name="MIN_LAYERSZ" low="23" high="26" shr="12"/>
+		<!--
+		by default levels with w < 16 are linear
+		TILE_ALL makes all levels have tiling
+		seems required when using UBWC, since all levels have UBWC (can possibly be disabled?)
+		 -->
+		<bitfield name="TILE_ALL" pos="27" type="boolean"/>
+		<bitfield name="FLAG" pos="28" type="boolean"/>
+	</reg32>
+	<!-- for 2-3 plane format, BASE is flag buffer address (if enabled)
+	     the address of the non-flag base buffer is determined automatically,
+	     and must follow the flag buffer
+	 -->
+	<reg32 offset="4" name="4">
+		<bitfield name="BASE_LO" low="5" high="31" shr="5"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="BASE_HI" low="0" high="16"/>
+		<bitfield name="DEPTH" low="17" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="6" name="6">
+		<!-- overlaps with PLANE_PITCH -->
+		<bitfield name="MIN_LOD_CLAMP" low="0" high="11" type="ufixed" radix="8"/>
+		<!-- pitch for plane 2 / plane 3 -->
+		<bitfield name="PLANE_PITCH" low="8" high="31" type="uint"/>
+	</reg32>
+	<!-- 7/8 is plane 2 address for planar formats -->
+	<reg32 offset="7" name="7">
+		<bitfield name="FLAG_LO" low="5" high="31" shr="5"/>
+	</reg32>
+	<reg32 offset="8" name="8">
+		<bitfield name="FLAG_HI" low="0" high="16"/>
+	</reg32>
+	<!-- 9/10 is plane 3 address for planar formats -->
+	<reg32 offset="9" name="9">
+		<bitfield name="FLAG_BUFFER_ARRAY_PITCH" low="0" high="16" shr="4" type="uint"/>
+	</reg32>
+	<reg32 offset="10" name="10">
+		<bitfield name="FLAG_BUFFER_PITCH" low="0" high="6" shr="6" type="uint"/>
+		<!-- log2 size of the first level, required for mipmapping -->
+		<bitfield name="FLAG_BUFFER_LOGW" low="8" high="11" type="uint"/>
+		<bitfield name="FLAG_BUFFER_LOGH" low="12" high="15" type="uint"/>
+	</reg32>
+	<reg32 offset="11" name="11"/>
+	<reg32 offset="12" name="12"/>
+	<reg32 offset="13" name="13"/>
+	<reg32 offset="14" name="14"/>
+	<reg32 offset="15" name="15"/>
+</domain>
+
+<domain name="A6XX_UBO" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="BASE_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="BASE_HI" low="0" high="16"/>
+		<bitfield name="SIZE" low="17" high="31"/> <!-- size in vec4 (4xDWORD) units -->
+	</reg32>
+</domain>
+
+<domain name="A6XX_PDC" width="32">
+	<reg32 offset="0x1140" name="GPU_ENABLE_PDC"/>
+	<reg32 offset="0x1148" name="GPU_SEQ_START_ADDR"/>
+	<reg32 offset="0x1540" name="GPU_TCS0_CONTROL"/>
+	<reg32 offset="0x1541" name="GPU_TCS0_CMD_ENABLE_BANK"/>
+	<reg32 offset="0x1542" name="GPU_TCS0_CMD_WAIT_FOR_CMPL_BANK"/>
+	<reg32 offset="0x1543" name="GPU_TCS0_CMD0_MSGID"/>
+	<reg32 offset="0x1544" name="GPU_TCS0_CMD0_ADDR"/>
+	<reg32 offset="0x1545" name="GPU_TCS0_CMD0_DATA"/>
+	<reg32 offset="0x1572" name="GPU_TCS1_CONTROL"/>
+	<reg32 offset="0x1573" name="GPU_TCS1_CMD_ENABLE_BANK"/>
+	<reg32 offset="0x1574" name="GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK"/>
+	<reg32 offset="0x1575" name="GPU_TCS1_CMD0_MSGID"/>
+	<reg32 offset="0x1576" name="GPU_TCS1_CMD0_ADDR"/>
+	<reg32 offset="0x1577" name="GPU_TCS1_CMD0_DATA"/>
+	<reg32 offset="0x15A4" name="GPU_TCS2_CONTROL"/>
+	<reg32 offset="0x15A5" name="GPU_TCS2_CMD_ENABLE_BANK"/>
+	<reg32 offset="0x15A6" name="GPU_TCS2_CMD_WAIT_FOR_CMPL_BANK"/>
+	<reg32 offset="0x15A7" name="GPU_TCS2_CMD0_MSGID"/>
+	<reg32 offset="0x15A8" name="GPU_TCS2_CMD0_ADDR"/>
+	<reg32 offset="0x15A9" name="GPU_TCS2_CMD0_DATA"/>
+	<reg32 offset="0x15D6" name="GPU_TCS3_CONTROL"/>
+	<reg32 offset="0x15D7" name="GPU_TCS3_CMD_ENABLE_BANK"/>
+	<reg32 offset="0x15D8" name="GPU_TCS3_CMD_WAIT_FOR_CMPL_BANK"/>
+	<reg32 offset="0x15D9" name="GPU_TCS3_CMD0_MSGID"/>
+	<reg32 offset="0x15DA" name="GPU_TCS3_CMD0_ADDR"/>
+	<reg32 offset="0x15DB" name="GPU_TCS3_CMD0_DATA"/>
+</domain>
+
+<domain name="A6XX_PDC_GPU_SEQ" width="32">
+	<reg32 offset="0x0" name="MEM_0"/>
+</domain>
+
+<domain name="A6XX_CX_DBGC" width="32">
+	<reg32 offset="0x0000" name="CFG_DBGBUS_SEL_A">
+		<bitfield high="7" low="0" name="PING_INDEX"/>
+		<bitfield high="15" low="8" name="PING_BLK_SEL"/>
+	</reg32>
+	<reg32 offset="0x0001" name="CFG_DBGBUS_SEL_B"/>
+	<reg32 offset="0x0002" name="CFG_DBGBUS_SEL_C"/>
+	<reg32 offset="0x0003" name="CFG_DBGBUS_SEL_D"/>
+	<reg32 offset="0x0004" name="CFG_DBGBUS_CNTLT">
+		<bitfield high="5" low="0" name="TRACEEN"/>
+		<bitfield high="14" low="12" name="GRANU"/>
+		<bitfield high="31" low="28" name="SEGT"/>
+	</reg32>
+	<reg32 offset="0x0005" name="CFG_DBGBUS_CNTLM">
+		<bitfield high="27" low="24" name="ENABLE"/>
+	</reg32>
+	<reg32 offset="0x0008" name="CFG_DBGBUS_IVTL_0"/>
+	<reg32 offset="0x0009" name="CFG_DBGBUS_IVTL_1"/>
+	<reg32 offset="0x000a" name="CFG_DBGBUS_IVTL_2"/>
+	<reg32 offset="0x000b" name="CFG_DBGBUS_IVTL_3"/>
+	<reg32 offset="0x000c" name="CFG_DBGBUS_MASKL_0"/>
+	<reg32 offset="0x000d" name="CFG_DBGBUS_MASKL_1"/>
+	<reg32 offset="0x000e" name="CFG_DBGBUS_MASKL_2"/>
+	<reg32 offset="0x000f" name="CFG_DBGBUS_MASKL_3"/>
+	<reg32 offset="0x0010" name="CFG_DBGBUS_BYTEL_0">
+		<bitfield high="3" low="0" name="BYTEL0"/>
+		<bitfield high="7" low="4" name="BYTEL1"/>
+		<bitfield high="11" low="8" name="BYTEL2"/>
+		<bitfield high="15" low="12" name="BYTEL3"/>
+		<bitfield high="19" low="16" name="BYTEL4"/>
+		<bitfield high="23" low="20" name="BYTEL5"/>
+		<bitfield high="27" low="24" name="BYTEL6"/>
+		<bitfield high="31" low="28" name="BYTEL7"/>
+	</reg32>
+	<reg32 offset="0x0011" name="CFG_DBGBUS_BYTEL_1">
+		<bitfield high="3" low="0" name="BYTEL8"/>
+		<bitfield high="7" low="4" name="BYTEL9"/>
+		<bitfield high="11" low="8" name="BYTEL10"/>
+		<bitfield high="15" low="12" name="BYTEL11"/>
+		<bitfield high="19" low="16" name="BYTEL12"/>
+		<bitfield high="23" low="20" name="BYTEL13"/>
+		<bitfield high="27" low="24" name="BYTEL14"/>
+		<bitfield high="31" low="28" name="BYTEL15"/>
+	</reg32>
+
+	<reg32 offset="0x002f" name="CFG_DBGBUS_TRACE_BUF1"/>
+	<reg32 offset="0x0030" name="CFG_DBGBUS_TRACE_BUF2"/>
+</domain>
+
+<domain name="A6XX_CX_MISC" width="32" prefix="variant" varset="chip">
+	<reg32 offset="0x0001" name="SYSTEM_CACHE_CNTL_0"/>
+	<reg32 offset="0x0002" name="SYSTEM_CACHE_CNTL_1"/>
+	<reg32 offset="0x0039" name="CX_MISC_TCM_RET_CNTL" variants="A7XX-"/>
+	<reg32 offset="0x0400" name="CX_MISC_SW_FUSE_VALUE" variants="A7XX-">
+		<bitfield pos="0" name="FASTBLEND" type="boolean"/>
+		<bitfield pos="1" name="LPAC" type="boolean"/>
+		<bitfield pos="2" name="RAYTRACING" type="boolean"/>
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/adreno/a6xx_gmu.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/adreno/a6xx_gmu.xml
@@ -0,0 +1,228 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="adreno/adreno_common.xml"/>
+
+<domain name="A6XX" width="32" prefix="variant" varset="chip">
+
+	<bitset name="A6XX_GMU_GPU_IDLE_STATUS">
+		<bitfield name="BUSY_IGN_AHB" pos="23"/>
+		<bitfield name="CX_GX_CPU_BUSY_IGN_AHB" pos="30"/>
+	</bitset>
+
+	<bitset name="A6XX_GMU_OOB">
+		<bitfield name="BOOT_SLUMBER_SET_MASK" pos="22"/>
+		<bitfield name="BOOT_SLUMBER_CHECK_MASK" pos="30"/>
+		<bitfield name="BOOT_SLUMBER_CLEAR_MASK" pos="30"/>
+		<bitfield name="DCVS_SET_MASK" pos="23"/>
+		<bitfield name="DCVS_CHECK_MASK" pos="31"/>
+		<bitfield name="DCVS_CLEAR_MASK" pos="31"/>
+		<bitfield name="GPU_SET_MASK" pos="18"/>
+		<bitfield name="GPU_CHECK_MASK" pos="26"/>
+		<bitfield name="GPU_CLEAR_MASK" pos="26"/>
+		<bitfield name="PERFCNTR_SET_MASK" pos="17"/>
+		<bitfield name="PERFCNTR_CHECK_MASK" pos="25"/>
+		<bitfield name="PERFCNTR_CLEAR_MASK" pos="25"/>
+	</bitset>
+
+	<bitset name="A6XX_HFI_IRQ">
+		<bitfield name="MSGQ_MASK" pos="0" />
+		<bitfield name="DSGQ_MASK" pos="1"/>
+		<bitfield name="BLOCKED_MSG_MASK" pos="2"/>
+		<bitfield name="CM3_FAULT_MASK" pos="23"/>
+		<bitfield name="GMU_ERR_MASK" low="16" high="22"/>
+		<bitfield name="OOB_MASK" low="24" high="31"/>
+	</bitset>
+
+	<bitset name="A6XX_HFI_H2F">
+		<bitfield name="IRQ_MASK_BIT" pos="0" />
+	</bitset>
+
+	<reg32 offset="0x80" name="GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL"/>
+	<reg32 offset="0x81" name="GMU_GX_SPTPRAC_POWER_CONTROL"/>
+	<reg32 offset="0xc00" name="GMU_CM3_ITCM_START"/>
+	<reg32 offset="0x1c00" name="GMU_CM3_DTCM_START"/>
+	<reg32 offset="0x23f0" name="GMU_NMI_CONTROL_STATUS"/>
+	<reg32 offset="0x23f8" name="GMU_BOOT_SLUMBER_OPTION"/>
+	<reg32 offset="0x23f9" name="GMU_GX_VOTE_IDX"/>
+	<reg32 offset="0x23fa" name="GMU_MX_VOTE_IDX"/>
+	<reg32 offset="0x23fc" name="GMU_DCVS_ACK_OPTION"/>
+	<reg32 offset="0x23fd" name="GMU_DCVS_PERF_SETTING"/>
+	<reg32 offset="0x23fe" name="GMU_DCVS_BW_SETTING"/>
+	<reg32 offset="0x23ff" name="GMU_DCVS_RETURN"/>
+	<reg32 offset="0x4c00" name="GMU_ICACHE_CONFIG"/>
+	<reg32 offset="0x4c01" name="GMU_DCACHE_CONFIG"/>
+	<reg32 offset="0x4c0f" name="GMU_SYS_BUS_CONFIG"/>
+	<reg32 offset="0x5000" name="GMU_CM3_SYSRESET"/>
+	<reg32 offset="0x5001" name="GMU_CM3_BOOT_CONFIG"/>
+	<reg32 offset="0x501a" name="GMU_CM3_FW_BUSY"/>
+	<reg32 offset="0x501c" name="GMU_CM3_FW_INIT_RESULT"/>
+	<reg32 offset="0x502d" name="GMU_CM3_CFG"/>
+	<reg32 offset="0x5040" name="GMU_CX_GMU_POWER_COUNTER_ENABLE"/>
+	<reg32 offset="0x5041" name="GMU_CX_GMU_POWER_COUNTER_SELECT_0"/>
+	<reg32 offset="0x5042" name="GMU_CX_GMU_POWER_COUNTER_SELECT_1"/>
+	<reg32 offset="0x5044" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L"/>
+	<reg32 offset="0x5045" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H"/>
+	<reg32 offset="0x5046" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_1_L"/>
+	<reg32 offset="0x5047" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_1_H"/>
+	<reg32 offset="0x5048" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_2_L"/>
+	<reg32 offset="0x5049" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_2_H"/>
+	<reg32 offset="0x504a" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_3_L"/>
+	<reg32 offset="0x504b" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_3_H"/>
+	<reg32 offset="0x504c" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_4_L"/>
+	<reg32 offset="0x504d" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_4_H"/>
+	<reg32 offset="0x504e" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_5_L"/>
+	<reg32 offset="0x504f" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_5_H"/>
+	<reg32 offset="0x50c0" name="GMU_PWR_COL_INTER_FRAME_CTRL">
+		<bitfield name="IFPC_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="HM_POWER_COLLAPSE_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="SPTPRAC_POWER_CONTROL_ENABLE" pos="2" type="boolean"/>
+		<bitfield name="NUM_PASS_SKIPS" low="10" high="13"/>
+		<bitfield name="MIN_PASS_LENGTH" low="14" high="31"/>
+	</reg32>
+	<reg32 offset="0x50c1" name="GMU_PWR_COL_INTER_FRAME_HYST"/>
+	<reg32 offset="0x50c2" name="GMU_PWR_COL_SPTPRAC_HYST"/>
+	<reg32 offset="0x50d0" name="GMU_SPTPRAC_PWR_CLK_STATUS">
+		<bitfield name="SPTPRAC_GDSC_POWERING_OFF" pos="0" type="boolean"/>
+		<bitfield name="SPTPRAC_GDSC_POWERING_ON" pos="1" type="boolean"/>
+		<bitfield name="SPTPRAC_GDSC_POWER_OFF" pos="2" type="boolean"/>
+		<bitfield name="SPTPRAC_GDSC_POWER_ON" pos="3" type="boolean"/>
+		<bitfield name="SP_CLOCK_OFF" pos="4" type="boolean"/>
+		<bitfield name="GMU_UP_POWER_STATE" pos="5" type="boolean"/>
+		<bitfield name="GX_HM_GDSC_POWER_OFF" pos="6" type="boolean"/>
+		<bitfield name="GX_HM_CLK_OFF" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x50e4" name="GMU_GPU_NAP_CTRL">
+		<bitfield name="HW_NAP_ENABLE" pos="0"/>
+		<bitfield name="SID" low="4" high="8"/>
+	</reg32>
+	<reg32 offset="0x50e8" name="GMU_RPMH_CTRL">
+		<bitfield name="RPMH_INTERFACE_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="LLC_VOTE_ENABLE" pos="4" type="boolean"/>
+		<bitfield name="DDR_VOTE_ENABLE" pos="8" type="boolean"/>
+		<bitfield name="MX_VOTE_ENABLE" pos="9" type="boolean"/>
+		<bitfield name="CX_VOTE_ENABLE" pos="10" type="boolean"/>
+		<bitfield name="GFX_VOTE_ENABLE" pos="11" type="boolean"/>
+		<bitfield name="DDR_MIN_VOTE_ENABLE" pos="12" type="boolean"/>
+		<bitfield name="MX_MIN_VOTE_ENABLE" pos="13" type="boolean"/>
+		<bitfield name="CX_MIN_VOTE_ENABLE" pos="14" type="boolean"/>
+		<bitfield name="GFX_MIN_VOTE_ENABLE" pos="15" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x50e9" name="GMU_RPMH_HYST_CTRL"/>
+	<reg32 offset="0x50ec" name="GPU_GMU_CX_GMU_RPMH_POWER_STATE"/>
+	<reg32 offset="0x50f0" name="GPU_GMU_CX_GMU_CX_FAL_INTF"/>
+	<reg32 offset="0x50f1" name="GPU_GMU_CX_GMU_CX_FALNEXT_INTF"/>
+	<reg32 offset="0x5100" name="GPU_GMU_CX_GMU_PWR_COL_CP_MSG"/>
+	<reg32 offset="0x5101" name="GPU_GMU_CX_GMU_PWR_COL_CP_RESP"/>
+	<reg32 offset="0x51f0" name="GMU_BOOT_KMD_LM_HANDSHAKE"/>
+	<reg32 offset="0x5157" name="GMU_LLM_GLM_SLEEP_CTRL"/>
+	<reg32 offset="0x5158" name="GMU_LLM_GLM_SLEEP_STATUS"/>
+	<reg32 offset="0x5088" name="GMU_ALWAYS_ON_COUNTER_L"/>
+	<reg32 offset="0x5089" name="GMU_ALWAYS_ON_COUNTER_H"/>
+	<reg32 offset="0x50c3" name="GMU_GMU_PWR_COL_KEEPALIVE"/>
+	<reg32 offset="0x5180" name="GMU_HFI_CTRL_STATUS"/>
+	<reg32 offset="0x5181" name="GMU_HFI_VERSION_INFO"/>
+	<reg32 offset="0x5182" name="GMU_HFI_SFR_ADDR"/>
+	<reg32 offset="0x5183" name="GMU_HFI_MMAP_ADDR"/>
+	<reg32 offset="0x5184" name="GMU_HFI_QTBL_INFO"/>
+	<reg32 offset="0x5185" name="GMU_HFI_QTBL_ADDR"/>
+	<reg32 offset="0x5186" name="GMU_HFI_CTRL_INIT"/>
+	<reg32 offset="0x5190" name="GMU_GMU2HOST_INTR_SET"/>
+	<reg32 offset="0x5191" name="GMU_GMU2HOST_INTR_CLR"/>
+	<reg32 offset="0x5192" name="GMU_GMU2HOST_INTR_INFO">
+		<bitfield name="MSGQ" pos="0" type="boolean"/>
+		<bitfield name="CM3_FAULT" pos="23" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x5193" name="GMU_GMU2HOST_INTR_MASK"/>
+	<reg32 offset="0x5194" name="GMU_HOST2GMU_INTR_SET"/>
+	<reg32 offset="0x5195" name="GMU_HOST2GMU_INTR_CLR"/>
+	<reg32 offset="0x5196" name="GMU_HOST2GMU_INTR_RAW_INFO"/>
+	<reg32 offset="0x5197" name="GMU_HOST2GMU_INTR_EN_0"/>
+	<reg32 offset="0x5198" name="GMU_HOST2GMU_INTR_EN_1"/>
+	<reg32 offset="0x5199" name="GMU_HOST2GMU_INTR_EN_2"/>
+	<reg32 offset="0x519a" name="GMU_HOST2GMU_INTR_EN_3"/>
+	<reg32 offset="0x519b" name="GMU_HOST2GMU_INTR_INFO_0"/>
+	<reg32 offset="0x519c" name="GMU_HOST2GMU_INTR_INFO_1"/>
+	<reg32 offset="0x519d" name="GMU_HOST2GMU_INTR_INFO_2"/>
+	<reg32 offset="0x519e" name="GMU_HOST2GMU_INTR_INFO_3"/>
+	<reg32 offset="0x51c5" name="GMU_GENERAL_0"/>
+	<reg32 offset="0x51c6" name="GMU_GENERAL_1"/>
+	<reg32 offset="0x51cb" name="GMU_GENERAL_6"/>
+	<reg32 offset="0x51cc" name="GMU_GENERAL_7"/>
+	<reg32 offset="0x51cd" name="GMU_GENERAL_8" variants="A7XX"/>
+	<reg32 offset="0x51ce" name="GMU_GENERAL_9" variants="A7XX"/>
+	<reg32 offset="0x51cf" name="GMU_GENERAL_10" variants="A7XX"/>
+	<reg32 offset="0x515d" name="GMU_ISENSE_CTRL"/>
+	<reg32 offset="0x8920" name="GPU_CS_ENABLE_REG"/>
+	<reg32 offset="0x515d" name="GPU_GMU_CX_GMU_ISENSE_CTRL"/>
+	<reg32 offset="0x8578" name="GPU_CS_AMP_CALIBRATION_CONTROL3"/>
+	<reg32 offset="0x8558" name="GPU_CS_AMP_CALIBRATION_CONTROL2"/>
+	<reg32 offset="0x8580" name="GPU_CS_A_SENSOR_CTRL_0"/>
+	<reg32 offset="0x27ada" name="GPU_CS_A_SENSOR_CTRL_2"/>
+	<reg32 offset="0x881a" name="GPU_CS_SENSOR_GENERAL_STATUS"/>
+	<reg32 offset="0x8957" name="GPU_CS_AMP_CALIBRATION_CONTROL1"/>
+	<reg32 offset="0x881a" name="GPU_CS_SENSOR_GENERAL_STATUS"/>
+	<reg32 offset="0x881d" name="GPU_CS_AMP_CALIBRATION_STATUS1_0"/>
+	<reg32 offset="0x881f" name="GPU_CS_AMP_CALIBRATION_STATUS1_2"/>
+	<reg32 offset="0x8821" name="GPU_CS_AMP_CALIBRATION_STATUS1_4"/>
+	<reg32 offset="0x8965" name="GPU_CS_AMP_CALIBRATION_DONE"/>
+	<reg32 offset="0x896d" name="GPU_CS_AMP_PERIOD_CTRL"/>
+	<reg32 offset="0x8965" name="GPU_CS_AMP_CALIBRATION_DONE"/>
+	<reg32 offset="0x514d" name="GPU_GMU_CX_GMU_PWR_THRESHOLD"/>
+	<reg32 offset="0x9303" name="GMU_AO_INTERRUPT_EN"/>
+	<reg32 offset="0x9304" name="GMU_AO_HOST_INTERRUPT_CLR"/>
+	<reg32 offset="0x9305" name="GMU_AO_HOST_INTERRUPT_STATUS">
+		<bitfield name="WDOG_BITE" pos="0" type="boolean"/>
+		<bitfield name="RSCC_COMP" pos="1" type="boolean"/>
+		<bitfield name="VDROOP" pos="2" type="boolean"/>
+		<bitfield name="FENCE_ERR" pos="3" type="boolean"/>
+		<bitfield name="DBD_WAKEUP" pos="4" type="boolean"/>
+		<bitfield name="HOST_AHB_BUS_ERROR" pos="5" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x9306" name="GMU_AO_HOST_INTERRUPT_MASK"/>
+	<reg32 offset="0x9309" name="GPU_GMU_AO_GMU_CGC_MODE_CNTL"/>
+	<reg32 offset="0x930a" name="GPU_GMU_AO_GMU_CGC_DELAY_CNTL"/>
+	<reg32 offset="0x930b" name="GPU_GMU_AO_GMU_CGC_HYST_CNTL"/>
+	<reg32 offset="0x930c" name="GPU_GMU_AO_GPU_CX_BUSY_STATUS">
+		<bitfield name = "GPUBUSYIGNAHB" pos="23" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x930d" name="GPU_GMU_AO_GPU_CX_BUSY_STATUS2"/>
+	<reg32 offset="0x930e" name="GPU_GMU_AO_GPU_CX_BUSY_MASK"/>
+	<reg32 offset="0x9310" name="GMU_AO_AHB_FENCE_CTRL"/>
+	<reg32 offset="0x9313" name="GMU_AHB_FENCE_STATUS"/>
+	<reg32 offset="0x9314" name="GMU_AHB_FENCE_STATUS_CLR"/>
+	<reg32 offset="0x9315" name="GMU_RBBM_INT_UNMASKED_STATUS"/>
+	<reg32 offset="0x9316" name="GMU_AO_SPARE_CNTL"/>
+	<reg32 offset="0x9307" name="GMU_RSCC_CONTROL_REQ"/>
+	<reg32 offset="0x9308" name="GMU_RSCC_CONTROL_ACK"/>
+	<reg32 offset="0x9311" name="GMU_AHB_FENCE_RANGE_0"/>
+	<reg32 offset="0x9312" name="GMU_AHB_FENCE_RANGE_1"/>
+	<reg32 offset="0x9c03" name="GPU_CC_GX_GDSCR"/>
+	<reg32 offset="0x9d42" name="GPU_CC_GX_DOMAIN_MISC"/>
+	<reg32 offset="0xc001" name="GPU_CPR_FSM_CTL"/>
+
+	<!-- starts at offset 0x8c00 on most gpus -->
+	<reg32 offset="0x0004" name="GPU_RSCC_RSC_STATUS0_DRV0"/>
+	<reg32 offset="0x0008" name="RSCC_PDC_SEQ_START_ADDR"/>
+	<reg32 offset="0x0009" name="RSCC_PDC_MATCH_VALUE_LO"/>
+	<reg32 offset="0x000a" name="RSCC_PDC_MATCH_VALUE_HI"/>
+	<reg32 offset="0x000b" name="RSCC_PDC_SLAVE_ID_DRV0"/>
+	<reg32 offset="0x000d" name="RSCC_HIDDEN_TCS_CMD0_ADDR"/>
+	<reg32 offset="0x000e" name="RSCC_HIDDEN_TCS_CMD0_DATA"/>
+	<reg32 offset="0x0082" name="RSCC_TIMESTAMP_UNIT0_TIMESTAMP_L_DRV0"/>
+	<reg32 offset="0x0083" name="RSCC_TIMESTAMP_UNIT0_TIMESTAMP_H_DRV0"/>
+	<reg32 offset="0x0089" name="RSCC_TIMESTAMP_UNIT1_EN_DRV0"/>
+	<reg32 offset="0x008c" name="RSCC_TIMESTAMP_UNIT1_OUTPUT_DRV0"/>
+	<reg32 offset="0x0100" name="RSCC_OVERRIDE_START_ADDR"/>
+	<reg32 offset="0x0101" name="RSCC_SEQ_BUSY_DRV0"/>
+	<reg32 offset="0x0154" name="RSCC_SEQ_MEM_0_DRV0_A740" variants="A7XX"/>
+	<reg32 offset="0x0180" name="RSCC_SEQ_MEM_0_DRV0"/>
+	<reg32 offset="0x0346" name="RSCC_TCS0_DRV0_STATUS"/>
+	<reg32 offset="0x03ee" name="RSCC_TCS1_DRV0_STATUS"/>
+	<reg32 offset="0x0496" name="RSCC_TCS2_DRV0_STATUS"/>
+	<reg32 offset="0x053e" name="RSCC_TCS3_DRV0_STATUS"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/adreno/adreno_common.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/adreno/adreno_common.xml
@@ -0,0 +1,400 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<enum name="chip" bare="yes">
+	<value name="A2XX" value="2"/>
+	<value name="A3XX" value="3"/>
+	<value name="A4XX" value="4"/>
+	<value name="A5XX" value="5"/>
+	<value name="A6XX" value="6"/>
+	<value name="A7XX" value="7"/>
+</enum>
+
+<enum name="adreno_pa_su_sc_draw">
+	<value name="PC_DRAW_POINTS" value="0"/>
+	<value name="PC_DRAW_LINES" value="1"/>
+	<value name="PC_DRAW_TRIANGLES" value="2"/>
+</enum>
+
+<enum name="adreno_compare_func">
+	<value name="FUNC_NEVER" value="0"/>
+	<value name="FUNC_LESS" value="1"/>
+	<value name="FUNC_EQUAL" value="2"/>
+	<value name="FUNC_LEQUAL" value="3"/>
+	<value name="FUNC_GREATER" value="4"/>
+	<value name="FUNC_NOTEQUAL" value="5"/>
+	<value name="FUNC_GEQUAL" value="6"/>
+	<value name="FUNC_ALWAYS" value="7"/>
+</enum>
+
+<enum name="adreno_stencil_op">
+	<value name="STENCIL_KEEP" value="0"/>
+	<value name="STENCIL_ZERO" value="1"/>
+	<value name="STENCIL_REPLACE" value="2"/>
+	<value name="STENCIL_INCR_CLAMP" value="3"/>
+	<value name="STENCIL_DECR_CLAMP" value="4"/>
+	<value name="STENCIL_INVERT" value="5"/>
+	<value name="STENCIL_INCR_WRAP" value="6"/>
+	<value name="STENCIL_DECR_WRAP" value="7"/>
+</enum>
+
+<enum name="adreno_rb_blend_factor">
+	<value name="FACTOR_ZERO" value="0"/>
+	<value name="FACTOR_ONE" value="1"/>
+	<value name="FACTOR_SRC_COLOR" value="4"/>
+	<value name="FACTOR_ONE_MINUS_SRC_COLOR" value="5"/>
+	<value name="FACTOR_SRC_ALPHA" value="6"/>
+	<value name="FACTOR_ONE_MINUS_SRC_ALPHA" value="7"/>
+	<value name="FACTOR_DST_COLOR" value="8"/>
+	<value name="FACTOR_ONE_MINUS_DST_COLOR" value="9"/>
+	<value name="FACTOR_DST_ALPHA" value="10"/>
+	<value name="FACTOR_ONE_MINUS_DST_ALPHA" value="11"/>
+	<value name="FACTOR_CONSTANT_COLOR" value="12"/>
+	<value name="FACTOR_ONE_MINUS_CONSTANT_COLOR" value="13"/>
+	<value name="FACTOR_CONSTANT_ALPHA" value="14"/>
+	<value name="FACTOR_ONE_MINUS_CONSTANT_ALPHA" value="15"/>
+	<value name="FACTOR_SRC_ALPHA_SATURATE" value="16"/>
+	<value name="FACTOR_SRC1_COLOR" value="20"/>
+	<value name="FACTOR_ONE_MINUS_SRC1_COLOR" value="21"/>
+	<value name="FACTOR_SRC1_ALPHA" value="22"/>
+	<value name="FACTOR_ONE_MINUS_SRC1_ALPHA" value="23"/>
+</enum>
+
+<bitset name="adreno_rb_stencilrefmask" inline="yes">
+	<bitfield name="STENCILREF" low="0" high="7" type="hex"/>
+	<bitfield name="STENCILMASK" low="8" high="15" type="hex"/>
+	<bitfield name="STENCILWRITEMASK" low="16" high="23" type="hex"/>
+</bitset>
+
+<enum name="adreno_rb_surface_endian">
+	<value name="ENDIAN_NONE" value="0"/>
+	<value name="ENDIAN_8IN16" value="1"/>
+	<value name="ENDIAN_8IN32" value="2"/>
+	<value name="ENDIAN_16IN32" value="3"/>
+	<value name="ENDIAN_8IN64" value="4"/>
+	<value name="ENDIAN_8IN128" value="5"/>
+</enum>
+
+<enum name="adreno_rb_dither_mode">
+	<value name="DITHER_DISABLE" value="0"/>
+	<value name="DITHER_ALWAYS" value="1"/>
+	<value name="DITHER_IF_ALPHA_OFF" value="2"/>
+</enum>
+
+<enum name="adreno_rb_depth_format">
+	<value name="DEPTHX_16" value="0"/>
+	<value name="DEPTHX_24_8" value="1"/>
+	<value name="DEPTHX_32" value="2"/>
+</enum>
+
+<enum name="adreno_rb_copy_control_mode">
+	<value name="RB_COPY_RESOLVE" value="1"/>
+	<value name="RB_COPY_CLEAR" value="2"/>
+	<value name="RB_COPY_DEPTH_STENCIL" value="5"/>  <!-- not sure if this is part of MODE or another bitfield?? -->
+</enum>
+
+<bitset name="adreno_reg_xy" inline="yes">
+	<bitfield name="WINDOW_OFFSET_DISABLE" pos="31" type="boolean"/>
+	<bitfield name="X" low="0" high="14" type="uint"/>
+	<bitfield name="Y" low="16" high="30" type="uint"/>
+</bitset>
+
+<bitset name="adreno_cp_protect" inline="yes">
+	<bitfield name="BASE_ADDR" low="0" high="16"/>
+	<bitfield name="MASK_LEN" low="24" high="28"/>
+	<bitfield name="TRAP_WRITE" pos="29"/>
+	<bitfield name="TRAP_READ" pos="30"/>
+</bitset>
+
+<domain name="AXXX" width="32">
+	<brief>Registers in common between a2xx and a3xx</brief>
+
+	<reg32 offset="0x01c0" name="CP_RB_BASE"/>
+	<reg32 offset="0x01c1" name="CP_RB_CNTL">
+		<bitfield name="BUFSZ" low="0" high="5"/>
+		<bitfield name="BLKSZ" low="8" high="13"/>
+		<bitfield name="BUF_SWAP" low="16" high="17"/>
+		<bitfield name="POLL_EN" pos="20" type="boolean"/>
+		<bitfield name="NO_UPDATE" pos="27" type="boolean"/>
+		<bitfield name="RPTR_WR_EN" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x01c3" name="CP_RB_RPTR_ADDR">
+		<bitfield name="SWAP" low="0" high="1" type="uint"/>
+		<bitfield name="ADDR" low="2" high="31" shr="2"/>
+	</reg32>
+	<reg32 offset="0x01c4" name="CP_RB_RPTR" type="uint"/>
+	<reg32 offset="0x01c5" name="CP_RB_WPTR" type="uint"/>
+	<reg32 offset="0x01c6" name="CP_RB_WPTR_DELAY"/>
+	<reg32 offset="0x01c7" name="CP_RB_RPTR_WR"/>
+	<reg32 offset="0x01c8" name="CP_RB_WPTR_BASE"/>
+	<reg32 offset="0x01d5" name="CP_QUEUE_THRESHOLDS">
+		<bitfield name="CSQ_IB1_START" low="0" high="3" type="uint"/>
+		<bitfield name="CSQ_IB2_START" low="8" high="11" type="uint"/>
+		<bitfield name="CSQ_ST_START" low="16" high="19" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01d6" name="CP_MEQ_THRESHOLDS">
+		<bitfield name="MEQ_END" low="16" high="20" type="uint"/>
+		<bitfield name="ROQ_END" low="24" high="28" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01d7" name="CP_CSQ_AVAIL">
+		<bitfield name="RING" low="0" high="6" type="uint"/>
+		<bitfield name="IB1" low="8" high="14" type="uint"/>
+		<bitfield name="IB2" low="16" high="22" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01d8" name="CP_STQ_AVAIL">
+		<bitfield name="ST" low="0" high="6" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01d9" name="CP_MEQ_AVAIL">
+		<bitfield name="MEQ" low="0" high="4" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01dc" name="SCRATCH_UMSK">
+		<bitfield name="UMSK" low="0" high="7" type="uint"/>
+		<bitfield name="SWAP" low="16" high="17" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01dd" name="SCRATCH_ADDR"/>
+	<reg32 offset="0x01ea" name="CP_ME_RDADDR"/>
+
+	<reg32 offset="0x01ec" name="CP_STATE_DEBUG_INDEX"/>
+	<reg32 offset="0x01ed" name="CP_STATE_DEBUG_DATA"/>
+	<reg32 offset="0x01f2" name="CP_INT_CNTL">
+		<bitfield name="SW_INT_MASK" pos="19" type="boolean"/>
+		<bitfield name="T0_PACKET_IN_IB_MASK" pos="23" type="boolean"/>
+		<bitfield name="OPCODE_ERROR_MASK" pos="24" type="boolean"/>
+		<bitfield name="PROTECTED_MODE_ERROR_MASK" pos="25" type="boolean"/>
+		<bitfield name="RESERVED_BIT_ERROR_MASK" pos="26" type="boolean"/>
+		<bitfield name="IB_ERROR_MASK" pos="27" type="boolean"/>
+		<bitfield name="IB2_INT_MASK" pos="29" type="boolean"/>
+		<bitfield name="IB1_INT_MASK" pos="30" type="boolean"/>
+		<bitfield name="RB_INT_MASK" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x01f3" name="CP_INT_STATUS"/>
+	<reg32 offset="0x01f4" name="CP_INT_ACK"/>
+	<reg32 offset="0x01f6" name="CP_ME_CNTL">
+		<bitfield name="BUSY" pos="29" type="boolean"/>
+		<bitfield name="HALT" pos="28" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x01f7" name="CP_ME_STATUS"/>
+	<reg32 offset="0x01f8" name="CP_ME_RAM_WADDR"/>
+	<reg32 offset="0x01f9" name="CP_ME_RAM_RADDR"/>
+	<reg32 offset="0x01fa" name="CP_ME_RAM_DATA"/>
+	<reg32 offset="0x01fc" name="CP_DEBUG">
+		<bitfield name="PREDICATE_DISABLE" pos="23" type="boolean"/>
+		<bitfield name="PROG_END_PTR_ENABLE" pos="24" type="boolean"/>
+		<bitfield name="MIU_128BIT_WRITE_ENABLE" pos="25" type="boolean"/>
+		<bitfield name="PREFETCH_PASS_NOPS" pos="26" type="boolean"/>
+		<bitfield name="DYNAMIC_CLK_DISABLE" pos="27" type="boolean"/>
+		<bitfield name="PREFETCH_MATCH_DISABLE" pos="28" type="boolean"/>
+		<bitfield name="SIMPLE_ME_FLOW_CONTROL" pos="30" type="boolean"/>
+		<bitfield name="MIU_WRITE_PACK_DISABLE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x01fd" name="CP_CSQ_RB_STAT">
+		<bitfield name="RPTR" low="0" high="6" type="uint"/>
+		<bitfield name="WPTR" low="16" high="22" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01fe" name="CP_CSQ_IB1_STAT">
+		<bitfield name="RPTR" low="0" high="6" type="uint"/>
+		<bitfield name="WPTR" low="16" high="22" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01ff" name="CP_CSQ_IB2_STAT">
+		<bitfield name="RPTR" low="0" high="6" type="uint"/>
+		<bitfield name="WPTR" low="16" high="22" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x0440" name="CP_NON_PREFETCH_CNTRS"/>
+	<reg32 offset="0x0443" name="CP_STQ_ST_STAT"/>
+	<reg32 offset="0x044d" name="CP_ST_BASE"/>
+	<reg32 offset="0x044e" name="CP_ST_BUFSZ"/>
+	<reg32 offset="0x044f" name="CP_MEQ_STAT"/>
+	<reg32 offset="0x0452" name="CP_MIU_TAG_STAT"/>
+	<reg32 offset="0x0454" name="CP_BIN_MASK_LO"/>
+	<reg32 offset="0x0455" name="CP_BIN_MASK_HI"/>
+	<reg32 offset="0x0456" name="CP_BIN_SELECT_LO"/>
+	<reg32 offset="0x0457" name="CP_BIN_SELECT_HI"/>
+	<reg32 offset="0x0458" name="CP_IB1_BASE"/>
+	<reg32 offset="0x0459" name="CP_IB1_BUFSZ"/>
+	<reg32 offset="0x045a" name="CP_IB2_BASE"/>
+	<reg32 offset="0x045b" name="CP_IB2_BUFSZ"/>
+	<reg32 offset="0x047f" name="CP_STAT">
+		<bitfield pos="31" name="CP_BUSY"/>
+		<bitfield pos="30" name="VS_EVENT_FIFO_BUSY"/>
+		<bitfield pos="29" name="PS_EVENT_FIFO_BUSY"/>
+		<bitfield pos="28" name="CF_EVENT_FIFO_BUSY"/>
+		<bitfield pos="27" name="RB_EVENT_FIFO_BUSY"/>
+		<bitfield pos="26" name="ME_BUSY"/>
+		<bitfield pos="25" name="MIU_WR_C_BUSY"/>
+		<bitfield pos="23" name="CP_3D_BUSY"/>
+		<bitfield pos="22" name="CP_NRT_BUSY"/>
+		<bitfield pos="21" name="RBIU_SCRATCH_BUSY"/>
+		<bitfield pos="20" name="RCIU_ME_BUSY"/>
+		<bitfield pos="19" name="RCIU_PFP_BUSY"/>
+		<bitfield pos="18" name="MEQ_RING_BUSY"/>
+		<bitfield pos="17" name="PFP_BUSY"/>
+		<bitfield pos="16" name="ST_QUEUE_BUSY"/>
+		<bitfield pos="13" name="INDIRECT2_QUEUE_BUSY"/>
+		<bitfield pos="12" name="INDIRECTS_QUEUE_BUSY"/>
+		<bitfield pos="11" name="RING_QUEUE_BUSY"/>
+		<bitfield pos="10" name="CSF_BUSY"/>
+		<bitfield pos="9"  name="CSF_ST_BUSY"/>
+		<bitfield pos="8"  name="EVENT_BUSY"/>
+		<bitfield pos="7"  name="CSF_INDIRECT2_BUSY"/>
+		<bitfield pos="6"  name="CSF_INDIRECTS_BUSY"/>
+		<bitfield pos="5"  name="CSF_RING_BUSY"/>
+		<bitfield pos="4"  name="RCIU_BUSY"/>
+		<bitfield pos="3"  name="RBIU_BUSY"/>
+		<bitfield pos="2"  name="MIU_RD_RETURN_BUSY"/>
+		<bitfield pos="1"  name="MIU_RD_REQ_BUSY"/>
+		<bitfield pos="0"  name="MIU_WR_BUSY"/>
+	</reg32>
+	<reg32 offset="0x0578" name="CP_SCRATCH_REG0" type="uint"/>
+	<reg32 offset="0x0579" name="CP_SCRATCH_REG1" type="uint"/>
+	<reg32 offset="0x057a" name="CP_SCRATCH_REG2" type="uint"/>
+	<reg32 offset="0x057b" name="CP_SCRATCH_REG3" type="uint"/>
+	<reg32 offset="0x057c" name="CP_SCRATCH_REG4" type="uint"/>
+	<reg32 offset="0x057d" name="CP_SCRATCH_REG5" type="uint"/>
+	<reg32 offset="0x057e" name="CP_SCRATCH_REG6" type="uint"/>
+	<reg32 offset="0x057f" name="CP_SCRATCH_REG7" type="uint"/>
+
+	<reg32 offset="0x0600" name="CP_ME_VS_EVENT_SRC"/>
+	<reg32 offset="0x0601" name="CP_ME_VS_EVENT_ADDR"/>
+	<reg32 offset="0x0602" name="CP_ME_VS_EVENT_DATA"/>
+	<reg32 offset="0x0603" name="CP_ME_VS_EVENT_ADDR_SWM"/>
+	<reg32 offset="0x0604" name="CP_ME_VS_EVENT_DATA_SWM"/>
+	<reg32 offset="0x0605" name="CP_ME_PS_EVENT_SRC"/>
+	<reg32 offset="0x0606" name="CP_ME_PS_EVENT_ADDR"/>
+	<reg32 offset="0x0607" name="CP_ME_PS_EVENT_DATA"/>
+	<reg32 offset="0x0608" name="CP_ME_PS_EVENT_ADDR_SWM"/>
+	<reg32 offset="0x0609" name="CP_ME_PS_EVENT_DATA_SWM"/>
+	<reg32 offset="0x060a" name="CP_ME_CF_EVENT_SRC"/>
+	<reg32 offset="0x060b" name="CP_ME_CF_EVENT_ADDR"/>
+	<reg32 offset="0x060c" name="CP_ME_CF_EVENT_DATA" type="uint"/>
+	<reg32 offset="0x060d" name="CP_ME_NRT_ADDR"/>
+	<reg32 offset="0x060e" name="CP_ME_NRT_DATA"/>
+	<reg32 offset="0x0612" name="CP_ME_VS_FETCH_DONE_SRC"/>
+	<reg32 offset="0x0613" name="CP_ME_VS_FETCH_DONE_ADDR"/>
+	<reg32 offset="0x0614" name="CP_ME_VS_FETCH_DONE_DATA"/>
+
+</domain>
+
+<!--
+	Common between A3xx and A4xx:
+ -->
+
+<enum name="a3xx_rop_code">
+	<value name="ROP_CLEAR"         value="0"/>
+	<value name="ROP_NOR"           value="1"/>
+	<value name="ROP_AND_INVERTED"  value="2"/>
+	<value name="ROP_COPY_INVERTED" value="3"/>
+	<value name="ROP_AND_REVERSE"   value="4"/>
+	<value name="ROP_INVERT"        value="5"/>
+	<value name="ROP_XOR"           value="6"/>
+	<value name="ROP_NAND"          value="7"/>
+	<value name="ROP_AND"           value="8"/>
+	<value name="ROP_EQUIV"         value="9"/>
+	<value name="ROP_NOOP"          value="10"/>
+	<value name="ROP_OR_INVERTED"   value="11"/>
+	<value name="ROP_COPY"          value="12"/>
+	<value name="ROP_OR_REVERSE"    value="13"/>
+	<value name="ROP_OR"            value="14"/>
+	<value name="ROP_SET"           value="15"/>
+</enum>
+
+<enum name="a3xx_render_mode">
+	<value name="RB_RENDERING_PASS" value="0"/>
+	<value name="RB_TILING_PASS" value="1"/>
+	<value name="RB_RESOLVE_PASS" value="2"/>
+	<value name="RB_COMPUTE_PASS" value="3"/>
+</enum>
+
+<enum name="a3xx_msaa_samples">
+	<value name="MSAA_ONE" value="0"/>
+	<value name="MSAA_TWO" value="1"/>
+	<value name="MSAA_FOUR" value="2"/>
+	<value name="MSAA_EIGHT" value="3"/>
+</enum>
+
+<enum name="a3xx_threadmode">
+	<value value="0" name="MULTI"/>
+	<value value="1" name="SINGLE"/>
+</enum>
+
+<enum name="a3xx_instrbuffermode">
+	<!--
+	When shader size goes above ~128 or so, blob switches to '0'
+	and doesn't emit shader in cmdstream.  When either is '0' it
+	doesn't get emitted via CP_LOAD_STATE.  When only one is
+	'0' the other gets size 256-others_size.  So I think that:
+		BUFFER => execute out of state memory
+		CACHE  => use available state memory as local cache
+	NOTE that when CACHE mode, also set CACHEINVALID flag!
+
+	TODO check if that 256 size is same for all a3xx
+	 -->
+	<value value="0" name="CACHE"/>
+	<value value="1" name="BUFFER"/>
+</enum>
+
+<enum name="a3xx_threadsize">
+	<value value="0" name="TWO_QUADS"/>
+	<value value="1" name="FOUR_QUADS"/>
+</enum>
+
+<enum name="a3xx_color_swap">
+	<value name="WZYX" value="0"/>
+	<value name="WXYZ" value="1"/>
+	<value name="ZYXW" value="2"/>
+	<value name="XYZW" value="3"/>
+</enum>
+
+<enum name="a3xx_rb_blend_opcode">
+	<value name="BLEND_DST_PLUS_SRC" value="0"/>
+	<value name="BLEND_SRC_MINUS_DST" value="1"/>
+	<value name="BLEND_DST_MINUS_SRC" value="2"/>
+	<value name="BLEND_MIN_DST_SRC" value="3"/>
+	<value name="BLEND_MAX_DST_SRC" value="4"/>
+</enum>
+
+<enum name="a4xx_tess_spacing">
+	<value name="EQUAL_SPACING" value="0"/>
+	<value name="ODD_SPACING" value="2"/>
+	<value name="EVEN_SPACING" value="3"/>
+</enum>
+
+<doc>Address mode for a5xx+</doc>
+<enum name="a5xx_address_mode">
+	<value name="ADDR_32B" value="0"/>
+	<value name="ADDR_64B" value="1"/>
+</enum>
+
+<doc>
+    Line mode for a5xx+
+	Note that Bresenham lines are only supported with MSAA disabled.
+</doc>
+<enum name="a5xx_line_mode">
+	<value value="0x0"  name="BRESENHAM"/>
+	<value value="0x1"  name="RECTANGULAR"/>
+</enum>
+
+<doc>
+	Blob (v615) seem to only use SAM and I wasn't able to coerce
+	it to produce any other command.
+	Probably valid for a4xx+ but not enabled or tested on anything
+	but a6xx.
+</doc>
+<enum name="a6xx_tex_prefetch_cmd">
+	<doc> Produces garbage </doc>
+	<value value="0x0" name="TEX_PREFETCH_UNK0"/>
+	<value value="0x1" name="TEX_PREFETCH_SAM"/>
+	<value value="0x2" name="TEX_PREFETCH_GATHER4R"/>
+	<value value="0x3" name="TEX_PREFETCH_GATHER4G"/>
+	<value value="0x4" name="TEX_PREFETCH_GATHER4B"/>
+	<value value="0x5" name="TEX_PREFETCH_GATHER4A"/>
+	<doc> Causes reads from an invalid address </doc>
+	<value value="0x6" name="TEX_PREFETCH_UNK6"/>
+	<doc> Results in color being zero </doc>
+	<value value="0x7" name="TEX_PREFETCH_UNK7"/>
+</enum>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/adreno/adreno_pm4.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/adreno/adreno_pm4.xml
@@ -0,0 +1,2263 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="adreno/adreno_common.xml"/>
+
+<enum name="vgt_event_type" varset="chip">
+	<value name="VS_DEALLOC" value="0"/>
+	<value name="PS_DEALLOC" value="1" variants="A2XX-A6XX"/>
+	<value name="VS_DONE_TS" value="2"/>
+	<value name="PS_DONE_TS" value="3"/>
+	<doc>
+		Flushes dirty data from UCHE, and also writes a GPU timestamp to
+		the address if one is provided.
+	</doc>
+	<value name="CACHE_FLUSH_TS" value="4"/>
+	<value name="CONTEXT_DONE" value="5"/>
+	<value name="CACHE_FLUSH" value="6" variants="A2XX-A4XX"/>
+	<value name="VIZQUERY_START" value="7" variants="A2XX"/>
+	<value name="HLSQ_FLUSH" value="7" variants="A3XX-A4XX"/>
+	<value name="VIZQUERY_END" value="8" variants="A2XX"/>
+	<value name="SC_WAIT_WC" value="9" variants="A2XX"/>
+	<value name="WRITE_PRIMITIVE_COUNTS" value="9" variants="A6XX"/>
+	<value name="START_PRIMITIVE_CTRS" value="11" variants="A6XX"/>
+	<value name="STOP_PRIMITIVE_CTRS" value="12" variants="A6XX"/>
+	<!-- Not sure that these 4 events don't have the same meaning as on A5XX+ -->
+	<value name="RST_PIX_CNT" value="13" variants="A2XX-A4XX"/>
+	<value name="RST_VTX_CNT" value="14" variants="A2XX-A4XX"/>
+	<value name="TILE_FLUSH" value="15" variants="A2XX-A4XX"/>
+	<value name="STAT_EVENT" value="16" variants="A2XX-A4XX"/>
+	<value name="CACHE_FLUSH_AND_INV_TS_EVENT" value="20" variants="A2XX-A4XX"/>
+	<doc>
+		If A6XX_RB_SAMPLE_COUNT_CONTROL.copy is true, writes OQ Z passed
+		sample counts to RB_SAMPLE_COUNT_ADDR.  This writes to main
+		memory, skipping UCHE.
+	</doc>
+	<value name="ZPASS_DONE" value="21"/>
+	<value name="CACHE_FLUSH_AND_INV_EVENT" value="22" variants="A2XX"/>
+
+	<doc>
+		Writes the GPU timestamp to the address that follows, once RB
+		access and flushes are complete.
+	</doc>
+	<value name="RB_DONE_TS" value="22" variants="A3XX-"/>
+
+	<value name="PERFCOUNTER_START" value="23" variants="A2XX-A4XX"/>
+	<value name="PERFCOUNTER_STOP" value="24" variants="A2XX-A4XX"/>
+	<value name="VS_FETCH_DONE" value="27"/>
+	<value name="FACENESS_FLUSH" value="28" variants="A2XX-A4XX"/>
+
+	<!-- a5xx events -->
+	<value name="WT_DONE_TS" value="8" variants="A5XX-"/>
+	<value name="START_FRAGMENT_CTRS" value="13" variants="A5XX-"/>
+	<value name="STOP_FRAGMENT_CTRS" value="14" variants="A5XX-"/>
+	<value name="START_COMPUTE_CTRS" value="15" variants="A5XX-"/>
+	<value name="STOP_COMPUTE_CTRS" value="16" variants="A5XX-"/>
+	<value name="FLUSH_SO_0" value="17" variants="A5XX-"/>
+	<value name="FLUSH_SO_1" value="18" variants="A5XX-"/>
+	<value name="FLUSH_SO_2" value="19" variants="A5XX-"/>
+	<value name="FLUSH_SO_3" value="20" variants="A5XX-"/>
+
+	<doc>
+		Invalidates depth attachment data from the CCU.  We assume this
+		happens in the last stage.
+	</doc>
+	<value name="PC_CCU_INVALIDATE_DEPTH" value="24" variants="A5XX-"/>
+
+	<doc>
+		Invalidates color attachment data from the CCU.  We assume this
+		happens in the last stage.
+	</doc>
+	<value name="PC_CCU_INVALIDATE_COLOR" value="25" variants="A5XX-"/>
+
+	<doc>
+		Flushes the small cache used by CP_EVENT_WRITE::BLIT (which,
+		along with its registers, would be better named RESOLVE).
+	</doc>
+	<value name="PC_CCU_RESOLVE_TS" value="26" variants="A6XX"/>
+
+	<doc>
+		Flushes depth attachment data from the CCU.  We assume this
+		happens in the last stage.
+	</doc>
+	<value name="PC_CCU_FLUSH_DEPTH_TS" value="28" variants="A5XX-"/>
+
+	<doc>
+		Flushes color attachment data from the CCU.  We assume this
+		happens in the last stage.
+	</doc>
+	<value name="PC_CCU_FLUSH_COLOR_TS" value="29" variants="A5XX-"/>
+
+	<doc>
+		2D blit to resolve GMEM to system memory (skipping CCU) at the
+		end of a render pass.  Compare to CP_BLIT's BLIT_OP_SCALE for
+		more general blitting.
+	</doc>
+	<value name="BLIT" value="30" variants="A5XX-"/>
+
+	<doc>
+		Clears based on GRAS_LRZ_CNTL configuration, could clear
+		fast-clear buffer or LRZ direction.
+		LRZ direction is stored at lrz_fc_offset + 0x200, has 1 byte which
+		could be expressed by enum:
+			CUR_DIR_DISABLED = 0x0
+			CUR_DIR_GE = 0x1
+			CUR_DIR_LE = 0x2
+			CUR_DIR_UNSET = 0x3
+		Clear of direction means setting the direction to CUR_DIR_UNSET.
+	</doc>
+	<value name="LRZ_CLEAR" value="37" variants="A5XX-"/>
+
+	<value name="LRZ_FLUSH" value="38" variants="A5XX-"/>
+	<value name="BLIT_OP_FILL_2D" value="39" variants="A5XX-"/>
+	<value name="BLIT_OP_COPY_2D" value="40" variants="A5XX-A6XX"/>
+	<value name="UNK_40" value="40" variants="A7XX"/>
+	<value name="BLIT_OP_SCALE_2D" value="42" variants="A5XX-"/>
+	<value name="CONTEXT_DONE_2D" value="43" variants="A5XX-"/>
+	<value name="UNK_2C" value="44" variants="A5XX-"/>
+	<value name="UNK_2D" value="45" variants="A5XX-"/>
+
+	<!-- a6xx events -->
+	<doc>
+		Invalidates UCHE.
+	</doc>
+	<value name="CACHE_INVALIDATE" value="49" variants="A6XX"/>
+
+	<value name="LABEL" value="63" variants="A6XX-"/>
+
+	<!-- note, some of these are the same as a6xx, just named differently -->
+
+	<doc> Doesn't seem to do anything </doc>
+	<value name="DUMMY_EVENT" value="1" variants="A7XX"/>
+	<value name="CCU_INVALIDATE_DEPTH" value="24" variants="A7XX"/>
+	<value name="CCU_INVALIDATE_COLOR" value="25" variants="A7XX"/>
+	<value name="CCU_RESOLVE_CLEAN" value="26" variants="A7XX"/>
+	<value name="CCU_FLUSH_DEPTH" value="28" variants="A7XX"/>
+	<value name="CCU_FLUSH_COLOR" value="29" variants="A7XX"/>
+	<value name="CCU_RESOLVE" value="30" variants="A7XX"/>
+	<value name="CCU_END_RESOLVE_GROUP" value="31" variants="A7XX"/>
+	<value name="CCU_CLEAN_DEPTH" value="32" variants="A7XX"/>
+	<value name="CCU_CLEAN_COLOR" value="33" variants="A7XX"/>
+	<value name="CACHE_RESET" value="48" variants="A7XX"/>
+	<value name="CACHE_CLEAN" value="49" variants="A7XX"/>
+	<!-- TODO: deal with name conflicts with other gens -->
+	<value name="CACHE_FLUSH7" value="50" variants="A7XX"/>
+	<value name="CACHE_INVALIDATE7" value="51" variants="A7XX"/>
+</enum>
+
+<enum name="pc_di_primtype">
+	<value name="DI_PT_NONE" value="0"/>
+	<!-- POINTLIST_PSIZE is used on a3xx/a4xx when gl_PointSize is written: -->
+	<value name="DI_PT_POINTLIST_PSIZE" value="1"/>
+	<value name="DI_PT_LINELIST" value="2"/>
+	<value name="DI_PT_LINESTRIP" value="3"/>
+	<value name="DI_PT_TRILIST" value="4"/>
+	<value name="DI_PT_TRIFAN" value="5"/>
+	<value name="DI_PT_TRISTRIP" value="6"/>
+	<value name="DI_PT_LINELOOP" value="7"/>  <!-- a22x, a3xx -->
+	<value name="DI_PT_RECTLIST" value="8"/>
+	<value name="DI_PT_POINTLIST" value="9"/>
+	<value name="DI_PT_LINE_ADJ" value="0xa"/>
+	<value name="DI_PT_LINESTRIP_ADJ" value="0xb"/>
+	<value name="DI_PT_TRI_ADJ" value="0xc"/>
+	<value name="DI_PT_TRISTRIP_ADJ" value="0xd"/>
+
+	<value name="DI_PT_PATCHES0" value="0x1f"/>
+	<value name="DI_PT_PATCHES1" value="0x20"/>
+	<value name="DI_PT_PATCHES2" value="0x21"/>
+	<value name="DI_PT_PATCHES3" value="0x22"/>
+	<value name="DI_PT_PATCHES4" value="0x23"/>
+	<value name="DI_PT_PATCHES5" value="0x24"/>
+	<value name="DI_PT_PATCHES6" value="0x25"/>
+	<value name="DI_PT_PATCHES7" value="0x26"/>
+	<value name="DI_PT_PATCHES8" value="0x27"/>
+	<value name="DI_PT_PATCHES9" value="0x28"/>
+	<value name="DI_PT_PATCHES10" value="0x29"/>
+	<value name="DI_PT_PATCHES11" value="0x2a"/>
+	<value name="DI_PT_PATCHES12" value="0x2b"/>
+	<value name="DI_PT_PATCHES13" value="0x2c"/>
+	<value name="DI_PT_PATCHES14" value="0x2d"/>
+	<value name="DI_PT_PATCHES15" value="0x2e"/>
+	<value name="DI_PT_PATCHES16" value="0x2f"/>
+	<value name="DI_PT_PATCHES17" value="0x30"/>
+	<value name="DI_PT_PATCHES18" value="0x31"/>
+	<value name="DI_PT_PATCHES19" value="0x32"/>
+	<value name="DI_PT_PATCHES20" value="0x33"/>
+	<value name="DI_PT_PATCHES21" value="0x34"/>
+	<value name="DI_PT_PATCHES22" value="0x35"/>
+	<value name="DI_PT_PATCHES23" value="0x36"/>
+	<value name="DI_PT_PATCHES24" value="0x37"/>
+	<value name="DI_PT_PATCHES25" value="0x38"/>
+	<value name="DI_PT_PATCHES26" value="0x39"/>
+	<value name="DI_PT_PATCHES27" value="0x3a"/>
+	<value name="DI_PT_PATCHES28" value="0x3b"/>
+	<value name="DI_PT_PATCHES29" value="0x3c"/>
+	<value name="DI_PT_PATCHES30" value="0x3d"/>
+	<value name="DI_PT_PATCHES31" value="0x3e"/>
+</enum>
+
+<enum name="pc_di_src_sel">
+	<value name="DI_SRC_SEL_DMA" value="0"/>
+	<value name="DI_SRC_SEL_IMMEDIATE" value="1"/>
+	<value name="DI_SRC_SEL_AUTO_INDEX" value="2"/>
+	<value name="DI_SRC_SEL_AUTO_XFB" value="3"/>
+</enum>
+
+<enum name="pc_di_face_cull_sel">
+	<value name="DI_FACE_CULL_NONE" value="0"/>
+	<value name="DI_FACE_CULL_FETCH" value="1"/>
+	<value name="DI_FACE_BACKFACE_CULL" value="2"/>
+	<value name="DI_FACE_FRONTFACE_CULL" value="3"/>
+</enum>
+
+<enum name="pc_di_index_size">
+	<value name="INDEX_SIZE_IGN" value="0"/>
+	<value name="INDEX_SIZE_16_BIT" value="0"/>
+	<value name="INDEX_SIZE_32_BIT" value="1"/>
+	<value name="INDEX_SIZE_8_BIT" value="2"/>
+	<value name="INDEX_SIZE_INVALID"/>
+</enum>
+
+<enum name="pc_di_vis_cull_mode">
+	<value name="IGNORE_VISIBILITY" value="0"/>
+	<value name="USE_VISIBILITY" value="1"/>
+</enum>
+
+<enum name="adreno_pm4_packet_type">
+	<value name="CP_TYPE0_PKT" value="0x00000000"/>
+	<value name="CP_TYPE1_PKT" value="0x40000000"/>
+	<value name="CP_TYPE2_PKT" value="0x80000000"/>
+	<value name="CP_TYPE3_PKT" value="0xc0000000"/>
+	<value name="CP_TYPE4_PKT" value="0x40000000"/>
+	<value name="CP_TYPE7_PKT" value="0x70000000"/>
+</enum>
+
+<!--
+   Note that in some cases, the same packet id is recycled on a later
+   generation, so variants attribute is used to distinguish.   They
+   may not be completely accurate, we would probably have to analyze
+   the pfp and me/pm4 firmware to verify the packet is actually
+   handled on a particular generation.  But it is at least enough to
+   disambiguate the packet-id's that were re-used for different
+   packets starting with a5xx.
+ -->
+<enum name="adreno_pm4_type3_packets" varset="chip">
+	<doc>initialize CP's micro-engine</doc>
+	<value name="CP_ME_INIT" value="0x48"/>
+	<doc>skip N 32-bit words to get to the next packet</doc>
+	<value name="CP_NOP" value="0x10"/>
+	<doc>
+		indirect buffer dispatch.  prefetch parser uses this packet
+		type to determine whether to pre-fetch the IB
+	</doc>
+	<value name="CP_PREEMPT_ENABLE" value="0x1c" variants="A5XX"/>
+	<value name="CP_PREEMPT_TOKEN" value="0x1e" variants="A5XX"/>
+	<value name="CP_INDIRECT_BUFFER" value="0x3f"/>
+	<doc>
+		Takes the same arguments as CP_INDIRECT_BUFFER, but jumps to
+		another buffer at the same level. Must be at the end of IB, and
+		doesn't work with draw state IB's.
+	</doc>
+	<value name="CP_INDIRECT_BUFFER_CHAIN" value="0x57" variants="A5XX-"/>
+	<doc>indirect buffer dispatch.  same as IB, but init is pipelined</doc>
+	<value name="CP_INDIRECT_BUFFER_PFD" value="0x37"/>
+	<doc>
+		Waits for the IDLE state of the engine before further drawing.
+		This is pipelined, so the CP may continue.
+	</doc>
+	<value name="CP_WAIT_FOR_IDLE" value="0x26"/>
+	<doc>wait until a register or memory location is a specific value</doc>
+	<value name="CP_WAIT_REG_MEM" value="0x3c"/>
+	<doc>wait until a register location is equal to a specific value</doc>
+	<value name="CP_WAIT_REG_EQ" value="0x52"/>
+	<doc>wait until a register location is >= a specific value</doc>
+	<value name="CP_WAIT_REG_GTE" value="0x53" variants="A2XX-A4XX"/>
+	<doc>wait until a read completes</doc>
+	<value name="CP_WAIT_UNTIL_READ" value="0x5c" variants="A2XX-A4XX"/>
+	<doc>wait until all base/size writes from an IB_PFD packet have completed</doc>
+	<!--
+		NOTE: CP_WAIT_IB_PFD_COMPLETE unimplemented at least since a5xx fw, and
+		recycled for something new on a7xx
+	 -->
+	<value name="CP_WAIT_IB_PFD_COMPLETE" value="0x5d" varset="chip" variants="A2XX-A4XX"/>
+	<doc>register read/modify/write</doc>
+	<value name="CP_REG_RMW" value="0x21"/>
+	<doc>Set binning configuration registers</doc>
+	<value name="CP_SET_BIN_DATA" value="0x2f" variants="A2XX-A4XX"/>
+	<value name="CP_SET_BIN_DATA5" value="0x2f" variants="A5XX-"/>
+	<doc>reads register in chip and writes to memory</doc>
+	<value name="CP_REG_TO_MEM" value="0x3e"/>
+	<doc>write N 32-bit words to memory</doc>
+	<value name="CP_MEM_WRITE" value="0x3d"/>
+	<doc>write CP_PROG_COUNTER value to memory</doc>
+	<value name="CP_MEM_WRITE_CNTR" value="0x4f"/>
+	<doc>conditional execution of a sequence of packets</doc>
+	<value name="CP_COND_EXEC" value="0x44"/>
+	<doc>conditional write to memory or register</doc>
+	<value name="CP_COND_WRITE" value="0x45" variants="A2XX-A4XX"/>
+	<value name="CP_COND_WRITE5" value="0x45" variants="A5XX-"/>
+	<doc>generate an event that creates a write to memory when completed</doc>
+	<value name="CP_EVENT_WRITE" value="0x46" variants="A2XX-A6XX"/>
+	<value name="CP_EVENT_WRITE7" value="0x46" variants="A7XX-"/>
+	<doc>generate a VS|PS_done event</doc>
+	<value name="CP_EVENT_WRITE_SHD" value="0x58"/>
+	<doc>generate a cache flush done event</doc>
+	<value name="CP_EVENT_WRITE_CFL" value="0x59"/>
+	<doc>generate a z_pass done event</doc>
+	<value name="CP_EVENT_WRITE_ZPD" value="0x5b"/>
+	<doc>
+		not sure the real name, but this seems to be what is used for
+		opencl, instead of CP_DRAW_INDX..
+	</doc>
+	<value name="CP_RUN_OPENCL" value="0x31"/>
+	<doc>initiate fetch of index buffer and draw</doc>
+	<value name="CP_DRAW_INDX" value="0x22"/>
+	<doc>draw using supplied indices in packet</doc>
+	<value name="CP_DRAW_INDX_2" value="0x36" variants="A2XX-A4XX"/>  <!-- this is something different on a6xx and unused on a5xx -->
+	<doc>initiate fetch of index buffer and binIDs and draw</doc>
+	<value name="CP_DRAW_INDX_BIN" value="0x34" variants="A2XX-A4XX"/>
+	<doc>initiate fetch of bin IDs and draw using supplied indices</doc>
+	<value name="CP_DRAW_INDX_2_BIN" value="0x35" variants="A2XX-A4XX"/>
+	<doc>begin/end initiator for viz query extent processing</doc>
+	<value name="CP_VIZ_QUERY" value="0x23" variants="A2XX-A4XX"/>
+	<doc>fetch state sub-blocks and initiate shader code DMAs</doc>
+	<value name="CP_SET_STATE" value="0x25"/>
+	<doc>load constant into chip and to memory</doc>
+	<value name="CP_SET_CONSTANT" value="0x2d" variants="A2XX"/>
+	<doc>load sequencer instruction memory (pointer-based)</doc>
+	<value name="CP_IM_LOAD" value="0x27"/>
+	<doc>load sequencer instruction memory (code embedded in packet)</doc>
+	<value name="CP_IM_LOAD_IMMEDIATE" value="0x2b"/>
+	<doc>load constants from a location in memory</doc>
+	<value name="CP_LOAD_CONSTANT_CONTEXT" value="0x2e" variants="A2XX"/>
+	<doc>selective invalidation of state pointers</doc>
+	<value name="CP_INVALIDATE_STATE" value="0x3b"/>
+	<doc>dynamically changes shader instruction memory partition</doc>
+	<value name="CP_SET_SHADER_BASES" value="0x4a" variants="A2XX-A4XX"/>
+	<doc>sets the 64-bit BIN_MASK register in the PFP</doc>
+	<value name="CP_SET_BIN_MASK" value="0x50" variants="A2XX-A4XX"/>
+	<doc>sets the 64-bit BIN_SELECT register in the PFP</doc>
+	<value name="CP_SET_BIN_SELECT" value="0x51" variants="A2XX-A4XX"/>
+	<doc>updates the current context, if needed</doc>
+	<value name="CP_CONTEXT_UPDATE" value="0x5e"/>
+	<doc>generate interrupt from the command stream</doc>
+	<value name="CP_INTERRUPT" value="0x40"/>
+	<doc>copy sequencer instruction memory to system memory</doc>
+	<value name="CP_IM_STORE" value="0x2c" variants="A2XX"/>
+
+	<!-- For a20x -->
+<!-- TODO handle variants..
+	<doc>
+		Program an offset that will added to the BIN_BASE value of
+		the 3D_DRAW_INDX_BIN packet
+	</doc>
+	<value name="CP_SET_BIN_BASE_OFFSET" value="0x4b"/>
+ -->
+
+	<!-- for a22x -->
+	<doc>
+		sets draw initiator flags register in PFP, gets bitwise-ORed into
+		every draw initiator
+	</doc>
+	<value name="CP_SET_DRAW_INIT_FLAGS" value="0x4b"/>
+	<doc>sets the register protection mode</doc>
+	<value name="CP_SET_PROTECTED_MODE" value="0x5f"/>
+
+	<value name="CP_BOOTSTRAP_UCODE" value="0x6f"/>
+
+	<!-- for a3xx -->
+	<doc>load high level sequencer command</doc>
+	<value name="CP_LOAD_STATE" value="0x30" variants="A3XX"/>
+	<value name="CP_LOAD_STATE4" value="0x30" variants="A4XX-A5XX"/>
+	<doc>Conditionally load a IB based on a flag, prefetch enabled</doc>
+	<value name="CP_COND_INDIRECT_BUFFER_PFE" value="0x3a"/>
+	<doc>Conditionally load a IB based on a flag, prefetch disabled</doc>
+	<value name="CP_COND_INDIRECT_BUFFER_PFD" value="0x32" variants="A3XX"/>
+	<doc>Load a buffer with pre-fetch enabled</doc>
+	<value name="CP_INDIRECT_BUFFER_PFE" value="0x3f" variants="A5XX"/>
+	<doc>Set bin (?)</doc>
+	<value name="CP_SET_BIN" value="0x4c" variants="A2XX"/>
+
+	<doc>test 2 memory locations to dword values specified</doc>
+	<value name="CP_TEST_TWO_MEMS" value="0x71"/>
+
+	<doc>Write register, ignoring context state for context sensitive registers</doc>
+	<value name="CP_REG_WR_NO_CTXT" value="0x78"/>
+
+	<doc>Record the real-time when this packet is processed by PFP</doc>
+	<value name="CP_RECORD_PFP_TIMESTAMP" value="0x11"/>
+
+	<!-- Used to switch GPU between secure and non-secure modes -->
+	<value name="CP_SET_SECURE_MODE" value="0x66"/>
+
+	<doc>PFP waits until the FIFO between the PFP and the ME is empty</doc>
+	<value name="CP_WAIT_FOR_ME" value="0x13"/>
+
+	<!-- for a4xx -->
+	<doc>
+		Used a bit like CP_SET_CONSTANT on a2xx, but can write multiple
+		groups of registers.  Looks like it can be used to create state
+		objects in GPU memory, and on state change only emit pointer
+		(via CP_SET_DRAW_STATE), which should be nice for reducing CPU
+		overhead:
+
+		(A4x) save PM4 stream pointers to execute upon a visible draw
+	</doc>
+	<value name="CP_SET_DRAW_STATE" value="0x43" variants="A4XX-"/>
+	<value name="CP_DRAW_INDX_OFFSET" value="0x38"/>
+	<value name="CP_DRAW_INDIRECT" value="0x28" variants="A4XX-"/>
+	<value name="CP_DRAW_INDX_INDIRECT" value="0x29" variants="A4XX-"/>
+	<value name="CP_DRAW_INDIRECT_MULTI" value="0x2a" variants="A6XX-"/>
+	<value name="CP_DRAW_AUTO" value="0x24"/>
+
+	<doc>
+		Enable or disable predication globally. Also resets the
+		predicate to "passing" and the local bit to enabled when
+		enabling global predication.
+	</doc>
+	<value name="CP_DRAW_PRED_ENABLE_GLOBAL" value="0x19"/>
+
+	<doc>
+		Enable or disable predication locally. Unlike globally enabling
+		predication, this packet doesn't touch any other state.
+		Predication only happens when enabled globally and locally and a
+		predicate has been set. This should be used for internal draws
+		which aren't supposed to use the predication state:
+
+		CP_DRAW_PRED_ENABLE_LOCAL(0)
+		... do draw...
+		CP_DRAW_PRED_ENABLE_LOCAL(1)
+	</doc>
+	<value name="CP_DRAW_PRED_ENABLE_LOCAL" value="0x1a"/>
+
+	<doc>
+		Latch a draw predicate into the internal register.
+	</doc>
+	<value name="CP_DRAW_PRED_SET" value="0x4e"/>
+
+	<doc>
+		for A4xx
+		Write to register with address that does not fit into type-0 pkt
+	</doc>
+	<value name="CP_WIDE_REG_WRITE" value="0x74" variants="A4XX"/>
+
+	<doc>copy from ME scratch RAM to a register</doc>
+	<value name="CP_SCRATCH_TO_REG" value="0x4d"/>
+
+	<doc>Copy from REG to ME scratch RAM</doc>
+	<value name="CP_REG_TO_SCRATCH" value="0x4a"/>
+
+	<doc>Wait for memory writes to complete</doc>
+	<value name="CP_WAIT_MEM_WRITES" value="0x12"/>
+
+	<doc>Conditional execution based on register comparison</doc>
+	<value name="CP_COND_REG_EXEC" value="0x47"/>
+
+	<doc>Memory to REG copy</doc>
+	<value name="CP_MEM_TO_REG" value="0x42"/>
+
+	<value name="CP_EXEC_CS_INDIRECT" value="0x41" variants="A4XX-"/>
+	<value name="CP_EXEC_CS" value="0x33"/>
+
+	<doc>
+		for a5xx
+	</doc>
+	<value name="CP_PERFCOUNTER_ACTION" value="0x50" variants="A5XX"/>
+	<!-- switches SMMU pagetable, used on a5xx+ only -->
+	<value name="CP_SMMU_TABLE_UPDATE" value="0x53" variants="A5XX-"/>
+	<!-- for a6xx -->
+	<doc>Tells CP the current mode of GPU operation</doc>
+	<value name="CP_SET_MARKER" value="0x65" variants="A6XX-"/>
+	<doc>Instruct CP to set a few internal CP registers</doc>
+	<value name="CP_SET_PSEUDO_REG" value="0x56" variants="A6XX-"/>
+	<!--
+	pairs of regid and value.. seems to be used to program some TF
+	related regs:
+	 -->
+	<value name="CP_CONTEXT_REG_BUNCH" value="0x5c" variants="A5XX-"/>
+	<!-- A5XX Enable yield in RB only -->
+	<value name="CP_YIELD_ENABLE" value="0x1c" variants="A5XX"/>
+	<doc>
+		Enables IB2 skipping.  If both GLOBAL and LOCAL are 1 and
+		nothing is left in the visibility stream, then
+		CP_INDIRECT_BUFFER will be skipped, and draws will early return
+		from their IB.
+	</doc>
+	<value name="CP_SKIP_IB2_ENABLE_GLOBAL" value="0x1d" variants="A5XX-"/>
+	<value name="CP_SKIP_IB2_ENABLE_LOCAL" value="0x23" variants="A5XX-"/>
+	<value name="CP_SET_SUBDRAW_SIZE" value="0x35" variants="A5XX-"/>
+	<value name="CP_WHERE_AM_I" value="0x62" variants="A5XX-"/>
+	<value name="CP_SET_VISIBILITY_OVERRIDE" value="0x64" variants="A5XX-"/>
+	<!-- Enable/Disable/Defer A5x global preemption model -->
+	<value name="CP_PREEMPT_ENABLE_GLOBAL" value="0x69" variants="A5XX"/>
+	<!-- Enable/Disable A5x local preemption model -->
+	<value name="CP_PREEMPT_ENABLE_LOCAL" value="0x6a" variants="A5XX"/>
+	<!-- Yield token on a5xx similar to CP_PREEMPT on a4xx -->
+	<value name="CP_CONTEXT_SWITCH_YIELD" value="0x6b" variants="A5XX-"/>
+	<!-- Inform CP about current render mode (needed for a5xx preemption) -->
+	<value name="CP_SET_RENDER_MODE" value="0x6c" variants="A5XX"/>
+	<value name="CP_COMPUTE_CHECKPOINT" value="0x6e" variants="A5XX"/>
+	<!-- check if this works on earlier.. -->
+	<value name="CP_MEM_TO_MEM" value="0x73" variants="A5XX-"/>
+
+	<doc>
+		General purpose 2D blit engine for image transfers and mipmap
+		generation.  Reads through UCHE, writes through the CCU cache in
+		the PS stage.
+	</doc>
+	<value name="CP_BLIT" value="0x2c" variants="A5XX-"/>
+
+	<!-- Test specified bit in specified register and set predicate -->
+	<value name="CP_REG_TEST" value="0x39" variants="A5XX-"/>
+
+	<!--
+	Seems to set the mode flags which control which CP_SET_DRAW_STATE
+	packets are executed, based on their ENABLE_MASK values
+	
+	CP_SET_MODE w/ payload of 0x1 seems to cause CP_SET_DRAW_STATE
+	packets w/ ENABLE_MASK & 0x6 to execute immediately
+	 -->
+	<value name="CP_SET_MODE" value="0x63" variants="A6XX-"/>
+
+	<!--
+	Seems like there are now separate blocks of state for VS vs FS/CS
+	(probably these amounts to geometry vs fragments so that geometry
+	stage of the pipeline for next draw can start while fragment stage
+	of current draw is still running.  The format of the payload of the
+	packets is the same, the only difference is the offsets of the regs
+	the firmware code that handles the packet writes.
+
+	Note that for CL, starting with a6xx, the preferred # of local
+	threads is no longer the same as the max, implying that the shader
+	core can now run warps from unrelated shaders (ie.
+	CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE vs
+	CL_KERNEL_WORK_GROUP_SIZE)
+	 -->
+	<value name="CP_LOAD_STATE6_GEOM" value="0x32" variants="A6XX-"/>
+	<value name="CP_LOAD_STATE6_FRAG" value="0x34" variants="A6XX-"/>
+	<!--
+	Note: For IBO state (Image/SSBOs) which have shared state across
+	shader stages, for 3d pipeline CP_LOAD_STATE6 is used.  But for
+	compute shaders, CP_LOAD_STATE6_FRAG is used.  Possibly they are
+	interchangable.
+	 -->
+	<value name="CP_LOAD_STATE6" value="0x36" variants="A6XX-"/>
+
+	<!-- internal packets: -->
+	<value name="IN_IB_PREFETCH_END" value="0x17" variants="A2XX"/>
+	<value name="IN_SUBBLK_PREFETCH" value="0x1f" variants="A2XX"/>
+	<value name="IN_INSTR_PREFETCH" value="0x20" variants="A2XX"/>
+	<value name="IN_INSTR_MATCH" value="0x47" variants="A2XX"/>
+	<value name="IN_CONST_PREFETCH" value="0x49" variants="A2XX"/>
+	<value name="IN_INCR_UPDT_STATE" value="0x55" variants="A2XX"/>
+	<value name="IN_INCR_UPDT_CONST" value="0x56" variants="A2XX"/>
+	<value name="IN_INCR_UPDT_INSTR" value="0x57" variants="A2XX"/>
+
+	<!-- internal jumptable entries on a6xx+, possibly a5xx: -->
+
+	<!-- jmptable entry used to handle type4 packet on a5xx+: -->
+	<value name="PKT4" value="0x04" variants="A5XX-"/>
+	<!-- called when ROQ is empty, "returns" from an IB or merged sequence of IBs -->
+	<value name="IN_IB_END" value="0x0a" variants="A6XX-"/>
+	<!-- handles IFPC save/restore -->
+	<value name="IN_GMU_INTERRUPT" value="0x0b" variants="A6XX-"/>
+	<!-- preemption/context-swtich routine -->
+	<value name="IN_PREEMPT" value="0x0f" variants="A6XX-"/>
+
+	<!-- TODO do these exist on A5xx? -->
+	<value name="CP_SCRATCH_WRITE" value="0x4c" variants="A6XX"/>
+	<value name="CP_REG_TO_MEM_OFFSET_MEM" value="0x74" variants="A6XX-"/>
+	<value name="CP_REG_TO_MEM_OFFSET_REG" value="0x72" variants="A6XX-"/>
+	<value name="CP_WAIT_MEM_GTE" value="0x14" variants="A6XX"/>
+	<value name="CP_WAIT_TWO_REGS" value="0x70" variants="A6XX"/>
+	<value name="CP_MEMCPY" value="0x75" variants="A6XX-"/>
+	<value name="CP_SET_BIN_DATA5_OFFSET" value="0x2e" variants="A6XX-"/>
+	<!-- A750+, set in place of CP_SET_BIN_DATA5_OFFSET but has different values -->
+	<value name="CP_SET_UNK_BIN_DATA" value="0x2d" variants="A7XX-"/>
+	<doc>
+                Write CP_CONTEXT_SWITCH_*_INFO from CP to the following dwords,
+                and forcibly switch to the indicated context.
+	</doc>
+	<value name="CP_CONTEXT_SWITCH" value="0x54" variants="A6XX"/>
+	<value name="CP_SET_AMBLE" value="0x55" variants="A6XX-"/>
+
+	<!--
+	Seems to always have the payload:
+	  00000002 00008801 00004010
+	or:
+	  00000002 00008801 00004090
+	or:
+	  00000002 00008801 00000010
+	  00000002 00008801 00010010
+	  00000002 00008801 00d64010
+	  ...
+	Note set for compute shaders..
+	Is 0x8801 a register offset?
+	This appears to be a special sort of register write packet
+	more or less, but the firmware has some special handling..
+	Seems like it intercepts/modifies certain register offsets,
+	but others are treated like a normal PKT4 reg write.  I
+	guess there are some registers that the fw controls certain
+	bits.
+	 -->
+	<value name="CP_REG_WRITE" value="0x6d" variants="A6XX"/>
+
+	<doc>
+		These first appear in a650_sqe.bin. They can in theory be used
+		to loop any sequence of IB1 commands, but in practice they are
+		used to loop over bins. There is a fixed-size per-iteration
+		prefix, used to set per-bin state, and then the following IB1
+		commands are executed until CP_END_BIN which are always the same
+		for each iteration and usually contain a list of
+		CP_INDIRECT_BUFFER calls to IB2 commands which setup state and
+		execute restore/draw/save commands. This replaces the previous
+		technique of just repeating the CP_INDIRECT_BUFFER calls and
+		"unrolling" the loop.
+	</doc>
+	<value name="CP_START_BIN" value="0x50" variants="A6XX-"/>
+	<value name="CP_END_BIN" value="0x51" variants="A6XX-"/>
+
+	<doc> Make next dword 1 to disable preemption, 0 to re-enable it. </doc>
+	<value name="CP_PREEMPT_DISABLE" value="0x6c" variants="A6XX"/>
+
+	<value name="CP_WAIT_TIMESTAMP" value="0x14" variants="A7XX-"/>
+	<value name="CP_GLOBAL_TIMESTAMP" value="0x15" variants="A7XX-"/>  <!-- payload 1 dword -->
+	<value name="CP_LOCAL_TIMESTAMP" value="0x16" variants="A7XX-"/>  <!-- payload 1 dword, follows 0x15 -->
+	<value name="CP_THREAD_CONTROL" value="0x17" variants="A7XX-"/>
+	<!-- payload 4 dwords, last two could be render target addr (one pkt per MRT), possibly used for GMEM save/restore?-->
+	<value name="CP_RESOURCE_LIST" value="0x18" variants="A7XX-"/>
+	<doc> Can clear BV/BR counters, or wait until one catches up to another </doc>
+	<value name="CP_BV_BR_COUNT_OPS" value="0x1b" variants="A7XX-"/>
+	<doc> Clears, adds to local, or adds to global timestamp </doc>
+	<value name="CP_MODIFY_TIMESTAMP" value="0x1c" variants="A7XX-"/>
+	<!-- similar to CP_CONTEXT_REG_BUNCH, but discards first two dwords?? -->
+	<value name="CP_CONTEXT_REG_BUNCH2" value="0x5d" variants="A7XX-"/>
+	<doc>
+		Write to a scratch memory that is read by CP_REG_TEST with
+		SOURCE_SCRATCH_MEM set. It's not the same scratch as scratch registers.
+		However it uses the same memory space.
+	</doc>
+	<value name="CP_MEM_TO_SCRATCH_MEM" value="0x49" variants="A7XX-"/>
+
+	<doc>
+		Executes an array of fixed-size command buffers where each
+		buffer is assumed to have one draw call, skipping buffers with
+		non-visible draw calls.
+	</doc>
+	<value name="CP_FIXED_STRIDE_DRAW_TABLE" value="0x7f" variants="A7XX-"/>
+
+	<doc>Reset various on-chip state used for synchronization</doc>
+	<value name="CP_RESET_CONTEXT_STATE" value="0x1f" variants="A7XX-"/>
+</enum>
+
+
+<domain name="CP_LOAD_STATE" width="32">
+	<doc>Load state, a3xx (and later?)</doc>
+	<enum name="adreno_state_block">
+		<value name="SB_VERT_TEX" value="0"/>
+		<value name="SB_VERT_MIPADDR" value="1"/>
+		<value name="SB_FRAG_TEX" value="2"/>
+		<value name="SB_FRAG_MIPADDR" value="3"/>
+		<value name="SB_VERT_SHADER" value="4"/>
+		<value name="SB_GEOM_SHADER" value="5"/>
+		<value name="SB_FRAG_SHADER" value="6"/>
+		<value name="SB_COMPUTE_SHADER" value="7"/>
+	</enum>
+	<enum name="adreno_state_type">
+		<value name="ST_SHADER" value="0"/>
+		<value name="ST_CONSTANTS" value="1"/>
+	</enum>
+	<enum name="adreno_state_src">
+		<value name="SS_DIRECT" value="0">
+			<doc>inline with the CP_LOAD_STATE packet</doc>
+		</value>
+		<value name="SS_INVALID_ALL_IC" value="2"/>
+		<value name="SS_INVALID_PART_IC" value="3"/>
+		<value name="SS_INDIRECT" value="4">
+			<doc>in buffer pointed to by EXT_SRC_ADDR</doc>
+		</value>
+		<value name="SS_INDIRECT_TCM" value="5"/>
+		<value name="SS_INDIRECT_STM" value="6"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="DST_OFF" low="0" high="15" type="uint"/>
+		<bitfield name="STATE_SRC" low="16" high="18" type="adreno_state_src"/>
+		<bitfield name="STATE_BLOCK" low="19" high="21" type="adreno_state_block"/>
+		<bitfield name="NUM_UNIT" low="22" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="STATE_TYPE" low="0" high="1" type="adreno_state_type"/>
+		<bitfield name="EXT_SRC_ADDR" low="2" high="31" shr="2"/>
+	</reg32>
+</domain>
+
+<domain name="CP_LOAD_STATE4" width="32" varset="chip">
+	<doc>Load state, a4xx+</doc>
+	<enum name="a4xx_state_block">
+		<!--
+		unknown: 0x7 and 0xf <- seen in compute shader
+
+		STATE_BLOCK = 0x6, STATE_TYPE = 0x2 possibly used for preemption?
+		Seen in some GL shaders.  Payload is NUM_UNIT dwords, and it contains
+		the gpuaddr of the following shader constants block.  DST_OFF seems
+		to specify which shader stage:
+
+		    16 -> vert
+		    36 -> tcs
+		    56 -> tes
+		    76 -> geom
+		    96 -> frag
+
+		Example:
+
+opcode: CP_LOAD_STATE4 (30) (12 dwords)
+        { DST_OFF = 16 | STATE_SRC = SS4_DIRECT | STATE_BLOCK = 0x6 | NUM_UNIT = 4 }
+        { STATE_TYPE = 0x2 | EXT_SRC_ADDR = 0 }
+        { EXT_SRC_ADDR_HI = 0 }
+                        0000: c0264100 00000000 00000000 00000000
+                0000: 70b0000b 01180010 00000002 00000000 c0264100 00000000 00000000 00000000
+
+opcode: CP_LOAD_STATE4 (30) (4 dwords)
+        { DST_OFF = 16 | STATE_SRC = SS4_INDIRECT | STATE_BLOCK = SB4_VS_SHADER | NUM_UNIT = 4 }
+        { STATE_TYPE = ST4_CONSTANTS | EXT_SRC_ADDR = 0xc0264100 }
+        { EXT_SRC_ADDR_HI = 0 }
+                        0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
+                        0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
+                        0000: 00000040 0000000c 00000000 00000000 00000000 00000000 00000000 00000000
+
+		STATE_BLOCK = 0x6, STATE_TYPE = 0x1, seen in compute shader.  NUM_UNITS * 2 dwords.
+
+		 -->
+		<value name="SB4_VS_TEX"    value="0x0"/>
+		<value name="SB4_HS_TEX"    value="0x1"/>    <!-- aka. TCS -->
+		<value name="SB4_DS_TEX"    value="0x2"/>    <!-- aka. TES -->
+		<value name="SB4_GS_TEX"    value="0x3"/>
+		<value name="SB4_FS_TEX"    value="0x4"/>
+		<value name="SB4_CS_TEX"    value="0x5"/>
+		<value name="SB4_VS_SHADER" value="0x8"/>
+		<value name="SB4_HS_SHADER" value="0x9"/>
+		<value name="SB4_DS_SHADER" value="0xa"/>
+		<value name="SB4_GS_SHADER" value="0xb"/>
+		<value name="SB4_FS_SHADER" value="0xc"/>
+		<value name="SB4_CS_SHADER" value="0xd"/>
+		<!--
+		for SSBO, STATE_TYPE=0 appears to be addresses (four dwords each),
+		STATE_TYPE=1 sizes, STATE_TYPE=2 addresses again (two dwords each)
+
+		Compute has it's own dedicated SSBO state, it seems, but the rest
+		of the stages share state
+		 -->
+		<value name="SB4_SSBO"   value="0xe"/>
+		<value name="SB4_CS_SSBO"   value="0xf"/>
+	</enum>
+	<enum name="a4xx_state_type">
+		<value name="ST4_SHADER" value="0"/>
+		<value name="ST4_CONSTANTS" value="1"/>
+		<value name="ST4_UBO" value="2"/>
+	</enum>
+	<enum name="a4xx_state_src">
+		<value name="SS4_DIRECT" value="0"/>
+		<value name="SS4_INDIRECT" value="2"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="DST_OFF" low="0" high="13" type="uint"/>
+		<bitfield name="STATE_SRC" low="16" high="17" type="a4xx_state_src"/>
+		<bitfield name="STATE_BLOCK" low="18" high="21" type="a4xx_state_block"/>
+		<bitfield name="NUM_UNIT" low="22" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="STATE_TYPE" low="0" high="1" type="a4xx_state_type"/>
+		<bitfield name="EXT_SRC_ADDR" low="2" high="31" shr="2"/>
+	</reg32>
+	<reg32 offset="2" name="2" varset="chip" variants="A5XX-">
+		<bitfield name="EXT_SRC_ADDR_HI" low="0" high="31" shr="0"/>
+	</reg32>
+</domain>
+
+<!-- looks basically same CP_LOAD_STATE4 -->
+<domain name="CP_LOAD_STATE6" width="32" varset="chip">
+	<doc>Load state, a6xx+</doc>
+	<enum name="a6xx_state_block">
+		<value name="SB6_VS_TEX"    value="0x0"/>
+		<value name="SB6_HS_TEX"    value="0x1"/>    <!-- aka. TCS -->
+		<value name="SB6_DS_TEX"    value="0x2"/>    <!-- aka. TES -->
+		<value name="SB6_GS_TEX"    value="0x3"/>
+		<value name="SB6_FS_TEX"    value="0x4"/>
+		<value name="SB6_CS_TEX"    value="0x5"/>
+		<value name="SB6_VS_SHADER" value="0x8"/>
+		<value name="SB6_HS_SHADER" value="0x9"/>
+		<value name="SB6_DS_SHADER" value="0xa"/>
+		<value name="SB6_GS_SHADER" value="0xb"/>
+		<value name="SB6_FS_SHADER" value="0xc"/>
+		<value name="SB6_CS_SHADER" value="0xd"/>
+		<value name="SB6_IBO"       value="0xe"/>
+		<value name="SB6_CS_IBO"    value="0xf"/>
+	</enum>
+	<enum name="a6xx_state_type">
+		<value name="ST6_SHADER" value="0"/>
+		<value name="ST6_CONSTANTS" value="1"/>
+		<value name="ST6_UBO" value="2"/>
+		<value name="ST6_IBO" value="3"/>
+	</enum>
+	<enum name="a6xx_state_src">
+		<value name="SS6_DIRECT" value="0"/>
+		<value name="SS6_BINDLESS" value="1"/> <!-- TODO does this exist on a4xx/a5xx? -->
+		<value name="SS6_INDIRECT" value="2"/>
+		<doc>
+		SS6_UBO used by the a6xx vulkan blob with tesselation constants
+		in this case, EXT_SRC_ADDR is (ubo_id shl 16 | offset)
+		to load constants from a UBO loaded with DST_OFF = 14 and offset 0,
+		EXT_SRC_ADDR = 0xe0000
+		(offset is a guess, should be in bytes given that maxUniformBufferRange=64k)
+		</doc>
+		<value name="SS6_UBO" value="3"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="DST_OFF" low="0" high="13" type="uint"/>
+		<bitfield name="STATE_TYPE" low="14" high="15" type="a6xx_state_type"/>
+		<bitfield name="STATE_SRC" low="16" high="17" type="a6xx_state_src"/>
+		<bitfield name="STATE_BLOCK" low="18" high="21" type="a6xx_state_block"/>
+		<bitfield name="NUM_UNIT" low="22" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="EXT_SRC_ADDR" low="2" high="31" shr="2"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="EXT_SRC_ADDR_HI" low="0" high="31" shr="0"/>
+	</reg32>
+	<reg64 offset="1" name="EXT_SRC_ADDR" type="address"/>
+</domain>
+
+<bitset name="vgt_draw_initiator" inline="yes">
+	<bitfield name="PRIM_TYPE" low="0" high="5" type="pc_di_primtype"/>
+	<bitfield name="SOURCE_SELECT" low="6" high="7" type="pc_di_src_sel"/>
+	<bitfield name="VIS_CULL" low="9" high="10" type="pc_di_vis_cull_mode"/>
+	<bitfield name="INDEX_SIZE" pos="11" type="pc_di_index_size"/>
+	<bitfield name="NOT_EOP" pos="12" type="boolean"/>
+	<bitfield name="SMALL_INDEX" pos="13" type="boolean"/>
+	<bitfield name="PRE_DRAW_INITIATOR_ENABLE" pos="14" type="boolean"/>
+	<bitfield name="NUM_INSTANCES" low="24" high="31" type="uint"/>
+</bitset>
+
+<!-- changed on a4xx: -->
+<enum name="a4xx_index_size">
+	<value name="INDEX4_SIZE_8_BIT" value="0"/>
+	<value name="INDEX4_SIZE_16_BIT" value="1"/>
+	<value name="INDEX4_SIZE_32_BIT" value="2"/>
+</enum>
+
+<enum name="a6xx_patch_type">
+  <value name="TESS_QUADS" value="0"/>
+  <value name="TESS_TRIANGLES" value="1"/>
+  <value name="TESS_ISOLINES" value="2"/>
+</enum>
+
+<bitset name="vgt_draw_initiator_a4xx" inline="yes">
+	<!-- When the 0x20 bit is set, it's the number of patch vertices - 1 -->
+	<bitfield name="PRIM_TYPE" low="0" high="5" type="pc_di_primtype"/>
+	<bitfield name="SOURCE_SELECT" low="6" high="7" type="pc_di_src_sel"/>
+	<bitfield name="VIS_CULL" low="8" high="9" type="pc_di_vis_cull_mode"/>
+	<bitfield name="INDEX_SIZE" low="10" high="11" type="a4xx_index_size"/>
+	<bitfield name="PATCH_TYPE" low="12" high="13" type="a6xx_patch_type"/>
+	<bitfield name="GS_ENABLE" pos="16" type="boolean"/>
+	<bitfield name="TESS_ENABLE" pos="17" type="boolean"/>
+</bitset>
+
+<domain name="CP_DRAW_INDX" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="VIZ_QUERY" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1" type="vgt_draw_initiator"/>
+	<reg32 offset="2" name="2">
+		<bitfield name="NUM_INDICES" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="INDX_BASE" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="INDX_SIZE" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_DRAW_INDX_2" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="VIZ_QUERY" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1" type="vgt_draw_initiator"/>
+	<reg32 offset="2" name="2">
+		<bitfield name="NUM_INDICES" low="0" high="31" type="uint"/>
+	</reg32>
+	<!-- followed by NUM_INDICES indices.. -->
+</domain>
+
+<domain name="CP_DRAW_INDX_OFFSET" width="32">
+	<reg32 offset="0" name="0" type="vgt_draw_initiator_a4xx"/>
+	<reg32 offset="1" name="1">
+		<bitfield name="NUM_INSTANCES" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="NUM_INDICES" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="FIRST_INDX" low="0" high="31"/>
+	</reg32>
+
+	<stripe varset="chip" variants="A5XX-">
+		<reg32 offset="4" name="4">
+			<bitfield name="INDX_BASE_LO" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="5" name="5">
+			<bitfield name="INDX_BASE_HI" low="0" high="31"/>
+		</reg32>
+		<reg64 offset="4" name="INDX_BASE" type="address"/>
+		<reg32 offset="6" name="6">
+			<!-- max # of elements in index buffer -->
+			<bitfield name="MAX_INDICES" low="0" high="31"/>
+		</reg32>
+	</stripe>
+
+	<reg32 offset="4" name="4">
+		<bitfield name="INDX_BASE" low="0" high="31" type="address"/>
+	</reg32>
+
+	<reg32 offset="5" name="5">
+		<bitfield name="INDX_SIZE" low="0" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_DRAW_INDIRECT" width="32" varset="chip" prefix="chip" variants="A4XX-">
+	<reg32 offset="0" name="0" type="vgt_draw_initiator_a4xx"/>
+	<stripe varset="chip" variants="A4XX">
+		<reg32 offset="1" name="1">
+			<bitfield name="INDIRECT" low="0" high="31"/>
+		</reg32>
+	</stripe>
+	<stripe varset="chip" variants="A5XX-">
+		<reg32 offset="1" name="1">
+			<bitfield name="INDIRECT_LO" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="2" name="2">
+			<bitfield name="INDIRECT_HI" low="0" high="31"/>
+		</reg32>
+		<reg64 offset="1" name="INDIRECT" type="address"/>
+	</stripe>
+</domain>
+
+<domain name="CP_DRAW_INDX_INDIRECT" width="32" varset="chip" prefix="chip" variants="A4XX-">
+	<reg32 offset="0" name="0" type="vgt_draw_initiator_a4xx"/>
+	<stripe varset="chip" variants="A4XX">
+		<reg32 offset="1" name="1">
+			<bitfield name="INDX_BASE" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="2" name="2">
+			<!-- max # of bytes in index buffer -->
+			<bitfield name="INDX_SIZE" low="0" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="3" name="3">
+			<bitfield name="INDIRECT" low="0" high="31"/>
+		</reg32>
+	</stripe>
+	<stripe varset="chip" variants="A5XX-">
+		<reg32 offset="1" name="1">
+			<bitfield name="INDX_BASE_LO" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="2" name="2">
+			<bitfield name="INDX_BASE_HI" low="0" high="31"/>
+		</reg32>
+		<reg64 offset="1" name="INDX_BASE" type="address"/>
+		<reg32 offset="3" name="3">
+			<!-- max # of elements in index buffer -->
+			<bitfield name="MAX_INDICES" low="0" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="4" name="4">
+			<bitfield name="INDIRECT_LO" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="5" name="5">
+			<bitfield name="INDIRECT_HI" low="0" high="31"/>
+		</reg32>
+		<reg64 offset="4" name="INDIRECT" type="address"/>
+	</stripe>
+</domain>
+
+<domain name="CP_DRAW_INDIRECT_MULTI" width="32" varset="chip" prefix="chip" variants="A6XX-">
+	<enum name="a6xx_draw_indirect_opcode">
+		<value name="INDIRECT_OP_NORMAL"  value="0x2"/>
+		<value name="INDIRECT_OP_INDEXED" value="0x4"/>
+		<value name="INDIRECT_OP_INDIRECT_COUNT" value="0x6"/>
+		<value name="INDIRECT_OP_INDIRECT_COUNT_INDEXED" value="0x7"/>
+	</enum>
+	<reg32 offset="0" name="0" type="vgt_draw_initiator_a4xx"/>
+	<reg32 offset="1" name="1">
+		<bitfield name="OPCODE" low="0" high="3" type="a6xx_draw_indirect_opcode" addvariant="yes"/>
+		<doc>
+		DST_OFF same as in CP_LOAD_STATE6 - vec4 VS const at this offset will
+		be updated for each draw to {draw_id, first_vertex, first_instance, 0}
+		value of 0 disables it
+		</doc>
+		<bitfield name="DST_OFF" low="8" high="21" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="DRAW_COUNT" type="uint"/>
+	<stripe varset="a6xx_draw_indirect_opcode" variants="INDIRECT_OP_NORMAL">
+		<reg64 offset="3" name="INDIRECT" type="address"/>
+		<reg32 offset="5" name="STRIDE" type="uint"/>
+	</stripe>
+	<stripe varset="a6xx_draw_indirect_opcode" variants="INDIRECT_OP_INDEXED" prefix="INDEXED">
+		<reg64 offset="3" name="INDEX" type="address"/>
+		<reg32 offset="5" name="MAX_INDICES" type="uint"/>
+		<reg64 offset="6" name="INDIRECT" type="address"/>
+		<reg32 offset="8" name="STRIDE" type="uint"/>
+	</stripe>
+	<stripe varset="a6xx_draw_indirect_opcode" variants="INDIRECT_OP_INDIRECT_COUNT" prefix="INDIRECT">
+		<reg64 offset="3" name="INDIRECT" type="address"/>
+		<reg64 offset="5" name="INDIRECT_COUNT" type="address"/>
+		<reg32 offset="7" name="STRIDE" type="uint"/>
+	</stripe>
+	<stripe varset="a6xx_draw_indirect_opcode" variants="INDIRECT_OP_INDIRECT_COUNT_INDEXED" prefix="INDIRECT_INDEXED">
+		<reg64 offset="3" name="INDEX" type="address"/>
+		<reg32 offset="5" name="MAX_INDICES" type="uint"/>
+		<reg64 offset="6" name="INDIRECT" type="address"/>
+		<reg64 offset="8" name="INDIRECT_COUNT" type="address"/>
+		<reg32 offset="10" name="STRIDE" type="uint"/>
+	</stripe>
+</domain>
+
+<domain name="CP_DRAW_AUTO" width="32">
+	<reg32 offset="0" name="0" type="vgt_draw_initiator_a4xx"/>
+	<reg32 offset="1" name="1">
+		<bitfield name="NUM_INSTANCES" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg64 offset="2" name="NUM_VERTICES_BASE" type="address"/>
+	<reg32 offset="4" name="4">
+		<bitfield name="NUM_VERTICES_OFFSET" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="STRIDE" low="0" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_DRAW_PRED_ENABLE_GLOBAL" width="32" varset="chip">
+	<reg32 offset="0" name="0">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+	</reg32>
+</domain>
+
+<domain name="CP_DRAW_PRED_ENABLE_LOCAL" width="32" varset="chip">
+	<reg32 offset="0" name="0">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+	</reg32>
+</domain>
+
+<domain name="CP_DRAW_PRED_SET" width="32" varset="chip">
+	<enum name="cp_draw_pred_src">
+		<!--
+			Sources 1-4 seem to be about combining reading
+			SO/primitive queries and setting the predicate, which is
+			a DX11-specific optimization (since in DX11 you can only
+			predicate on the result of queries).
+		-->
+		<value name="PRED_SRC_MEM" value="5">
+			<doc>
+				Read a 64-bit value at the given address and
+				test if it equals/doesn't equal 0.
+			</doc>
+		</value>
+	</enum>
+	<enum name="cp_draw_pred_test">
+		<value name="NE_0_PASS" value="0"/>
+		<value name="EQ_0_PASS" value="1"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="SRC" low="4" high="7" type="cp_draw_pred_src"/>
+		<bitfield name="TEST" pos="8" type="cp_draw_pred_test"/>
+	</reg32>
+	<reg64 offset="1" name="MEM_ADDR" type="address"/>
+</domain>
+
+<domain name="CP_SET_DRAW_STATE" width="32" varset="chip" variants="A4XX-">
+	<array offset="0" stride="3" length="100">
+		<reg32 offset="0" name="0">
+			<bitfield name="COUNT" low="0" high="15" type="uint"/>
+			<bitfield name="DIRTY" pos="16" type="boolean"/>
+			<bitfield name="DISABLE" pos="17" type="boolean"/>
+			<bitfield name="DISABLE_ALL_GROUPS" pos="18" type="boolean"/>
+			<bitfield name="LOAD_IMMED" pos="19" type="boolean"/>
+			<bitfield name="BINNING" pos="20" varset="chip" variants="A6XX-" type="boolean"/>
+			<bitfield name="GMEM" pos="21" varset="chip" variants="A6XX-" type="boolean"/>
+			<bitfield name="SYSMEM" pos="22" varset="chip" variants="A6XX-" type="boolean"/>
+			<bitfield name="GROUP_ID" low="24" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="1" name="1">
+			<bitfield name="ADDR_LO" low="0" high="31" type="hex"/>
+		</reg32>
+		<reg32 offset="2" name="2" varset="chip" variants="A5XX-">
+			<bitfield name="ADDR_HI" low="0" high="31" type="hex"/>
+		</reg32>
+	</array>
+</domain>
+
+<domain name="CP_SET_BIN" width="32">
+	<doc>value at offset 0 always seems to be 0x00000000..</doc>
+	<reg32 offset="0" name="0"/>
+	<reg32 offset="1" name="1">
+		<bitfield name="X1" low="0" high="15" type="uint"/>
+		<bitfield name="Y1" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="X2" low="0" high="15" type="uint"/>
+		<bitfield name="Y2" low="16" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_SET_BIN_DATA" width="32">
+	<reg32 offset="0" name="0">
+		<!-- corresponds to VSC_PIPE[n].DATA_ADDR -->
+		<bitfield name="BIN_DATA_ADDR" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<!-- seesm to correspond to VSC_SIZE_ADDRESS -->
+		<bitfield name="BIN_SIZE_ADDRESS" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_SET_BIN_DATA5" width="32">
+	<reg32 offset="0" name="0">
+		<!-- equiv to PC_VSTREAM_CONTROL.SIZE on a3xx/a4xx: -->
+		<bitfield name="VSC_SIZE" low="16" high="21" type="uint"/>
+		<!-- equiv to PC_VSTREAM_CONTROL.N on a3xx/a4xx: -->
+		<bitfield name="VSC_N" low="22" high="26" type="uint"/>
+	</reg32>
+	<!-- BIN_DATA_ADDR -> VSC_PIPE[p].DATA_ADDRESS -->
+	<reg32 offset="1" name="1">
+		<bitfield name="BIN_DATA_ADDR_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="BIN_DATA_ADDR_HI" low="0" high="31" type="hex"/>
+	</reg32>
+	<!-- BIN_SIZE_ADDRESS -> VSC_SIZE_ADDRESS + (p * 4)-->
+	<reg32 offset="3" name="3">
+		<bitfield name="BIN_SIZE_ADDRESS_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="BIN_SIZE_ADDRESS_HI" low="0" high="31"/>
+	</reg32>
+	<!-- new on a6xx, where BIN_DATA_ADDR is the DRAW_STRM: -->
+	<reg32 offset="5" name="5">
+		<bitfield name="BIN_PRIM_STRM_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="6" name="6">
+		<bitfield name="BIN_PRIM_STRM_HI" low="0" high="31"/>
+	</reg32>
+	<!--
+		a7xx adds a few more addresses to the end of the pkt
+	 -->
+	<reg64 offset="7" name="7"/>
+	<reg64 offset="9" name="9"/>
+</domain>
+
+<domain name="CP_SET_BIN_DATA5_OFFSET" width="32">
+	<doc>
+                Like CP_SET_BIN_DATA5, but set the pointers as offsets from the
+                pointers stored in VSC_PIPE_{DATA,DATA2,SIZE}_ADDRESS. Useful
+                for Vulkan where these values aren't known when the command
+                stream is recorded.
+	</doc>
+	<reg32 offset="0" name="0">
+		<!-- equiv to PC_VSTREAM_CONTROL.SIZE on a3xx/a4xx: -->
+		<bitfield name="VSC_SIZE" low="16" high="21" type="uint"/>
+		<!-- equiv to PC_VSTREAM_CONTROL.N on a3xx/a4xx: -->
+		<bitfield name="VSC_N" low="22" high="26" type="uint"/>
+	</reg32>
+	<!-- BIN_DATA_ADDR -> VSC_PIPE[p].DATA_ADDRESS -->
+	<reg32 offset="1" name="1">
+		<bitfield name="BIN_DATA_OFFSET" low="0" high="31" type="uint"/>
+	</reg32>
+	<!-- BIN_SIZE_ADDRESS -> VSC_SIZE_ADDRESS + (p * 4)-->
+	<reg32 offset="2" name="2">
+		<bitfield name="BIN_SIZE_OFFSET" low="0" high="31" type="uint"/>
+	</reg32>
+	<!-- BIN_DATA2_ADDR -> VSC_PIPE[p].DATA2_ADDRESS -->
+	<reg32 offset="3" name="3">
+		<bitfield name="BIN_DATA2_OFFSET" low="0" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_REG_RMW" width="32">
+	<doc>
+                Modifies DST_REG using two sources that can either be registers
+                or immediates. If SRC1_ADD is set, then do the following:
+
+			$dst = (($dst &amp; $src0) rot $rotate) + $src1
+
+		Otherwise:
+
+			$dst = (($dst &amp; $src0) rot $rotate) | $src1
+
+		Here "rot" means rotate left.
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="DST_REG" low="0" high="17" type="hex"/>
+		<bitfield name="ROTATE" low="24" high="28" type="uint"/>
+		<bitfield name="SRC1_ADD" pos="29" type="boolean"/>
+		<bitfield name="SRC1_IS_REG" pos="30" type="boolean"/>
+		<bitfield name="SRC0_IS_REG" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="SRC0" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="SRC1" low="0" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_REG_TO_MEM" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="REG" low="0" high="17" type="hex"/>
+		<!-- number of registers/dwords copied is max(CNT, 1). -->
+		<bitfield name="CNT" low="18" high="29" type="uint"/>
+		<bitfield name="64B" pos="30" type="boolean"/>
+		<bitfield name="ACCUMULATE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="DEST" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2" varset="chip" variants="A5XX-">
+		<bitfield name="DEST_HI" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_REG_TO_MEM_OFFSET_REG" width="32">
+	<doc>
+                Like CP_REG_TO_MEM, but the memory address to write to can be
+                offsetted using either one or two registers or scratch
+                registers.
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="REG" low="0" high="17" type="hex"/>
+		<!-- number of registers/dwords copied is max(CNT, 1). -->
+		<bitfield name="CNT" low="18" high="29" type="uint"/>
+		<bitfield name="64B" pos="30" type="boolean"/>
+		<bitfield name="ACCUMULATE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="DEST" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2" varset="chip" variants="A5XX-">
+		<bitfield name="DEST_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="OFFSET0" low="0" high="17" type="hex"/>
+		<bitfield name="OFFSET0_SCRATCH" pos="19" type="boolean"/>
+	</reg32>
+	<!-- followed by an optional identical OFFSET1 dword -->
+</domain>
+
+<domain name="CP_REG_TO_MEM_OFFSET_MEM" width="32">
+	<doc>
+                Like CP_REG_TO_MEM, but the memory address to write to can be
+                offsetted using a DWORD in memory.
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="REG" low="0" high="17" type="hex"/>
+		<!-- number of registers/dwords copied is max(CNT, 1). -->
+		<bitfield name="CNT" low="18" high="29" type="uint"/>
+		<bitfield name="64B" pos="30" type="boolean"/>
+		<bitfield name="ACCUMULATE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="DEST" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2" varset="chip" variants="A5XX-">
+		<bitfield name="DEST_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="OFFSET_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="OFFSET_HI" low="0" high="31" type="hex"/>
+	</reg32>
+</domain>
+
+<domain name="CP_MEM_TO_REG" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="REG" low="0" high="17" type="hex"/>
+		<!-- number of registers/dwords copied is max(CNT, 1). -->
+		<bitfield name="CNT" low="19" high="29" type="uint"/>
+		<!-- shift each DWORD left by 2 while copying -->
+		<bitfield name="SHIFT_BY_2" pos="30" type="boolean"/>
+		<!-- does the same thing as CP_MEM_TO_MEM::UNK31 -->
+		<bitfield name="UNK31" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="SRC" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2" varset="chip" variants="A5XX-">
+		<bitfield name="SRC_HI" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_MEM_TO_MEM" width="32">
+	<reg32 offset="0" name="0">
+		<!--
+		not sure how many src operands we have, but the low
+		bits negate the n'th src argument.
+		 -->
+		<bitfield name="NEG_A" pos="0" type="boolean"/>
+		<bitfield name="NEG_B" pos="1" type="boolean"/>
+		<bitfield name="NEG_C" pos="2" type="boolean"/>
+
+		<!-- if set treat src/dst as 64bit values -->
+		<bitfield name="DOUBLE" pos="29" type="boolean"/>
+		<!-- execute CP_WAIT_FOR_MEM_WRITES beforehand -->
+		<bitfield name="WAIT_FOR_MEM_WRITES" pos="30" type="boolean"/>
+		<!-- some other kind of wait -->
+		<bitfield name="UNK31" pos="31" type="boolean"/>
+	</reg32>
+	<!--
+	followed by sequence of addresses.. the first is the
+	destination and the rest are N src addresses which are
+	summed (after being negated if NEG_x bit set) allowing
+	to do things like 'result += end - start' (which turns
+	out to be useful for queries and accumulating results
+	across multiple tiles)
+	 -->
+</domain>
+
+<domain name="CP_MEMCPY" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="DWORDS" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="SRC_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="SRC_HI" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="DST_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="DST_HI" low="0" high="31" type="hex"/>
+	</reg32>
+</domain>
+
+<domain name="CP_REG_TO_SCRATCH" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="REG" low="0" high="17" type="hex"/>
+		<bitfield name="SCRATCH" low="20" high="22" type="uint"/>
+		<!-- number of registers/dwords copied is CNT + 1. -->
+		<bitfield name="CNT" low="24" high="26" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_SCRATCH_TO_REG" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="REG" low="0" high="17" type="hex"/>
+		<!-- note: CP_MEM_TO_REG always sets this when writing to the register -->
+		<bitfield name="UNK18" pos="18" type="boolean"/>
+		<bitfield name="SCRATCH" low="20" high="22" type="uint"/>
+		<!-- number of registers/dwords copied is CNT + 1. -->
+		<bitfield name="CNT" low="24" high="26" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_SCRATCH_WRITE" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="SCRATCH" low="20" high="22" type="uint"/>
+	</reg32>
+	<!-- followed by one or more DWORDs to write to scratch registers -->
+</domain>
+
+<domain name="CP_MEM_WRITE" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="ADDR_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="ADDR_HI" low="0" high="31"/>
+	</reg32>
+	<!-- followed by the DWORDs to write -->
+</domain>
+
+<enum name="cp_cond_function">
+	<value value="0" name="WRITE_ALWAYS"/>
+	<value value="1" name="WRITE_LT"/>
+	<value value="2" name="WRITE_LE"/>
+	<value value="3" name="WRITE_EQ"/>
+	<value value="4" name="WRITE_NE"/>
+	<value value="5" name="WRITE_GE"/>
+	<value value="6" name="WRITE_GT"/>
+</enum>
+
+<domain name="CP_COND_WRITE" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="FUNCTION" low="0" high="2" type="cp_cond_function"/>
+		<bitfield name="POLL_MEMORY" pos="4" type="boolean"/>
+		<bitfield name="WRITE_MEMORY" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="POLL_ADDR" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="REF" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="MASK" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="WRITE_ADDR" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="WRITE_DATA" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<enum name="poll_memory_type">
+	<value value="0" name="POLL_REGISTER"/>
+	<value value="1" name="POLL_MEMORY"/>
+	<value value="2" name="POLL_SCRATCH"/>
+	<value value="3" name="POLL_ON_CHIP" varset="chip" variants="A7XX-"/>
+</enum>
+
+<domain name="CP_COND_WRITE5" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="FUNCTION" low="0" high="2" type="cp_cond_function"/>
+		<bitfield name="SIGNED_COMPARE" pos="3" type="boolean"/>
+		<!-- POLL_REGISTER polls a register at POLL_ADDR_LO. -->
+		<bitfield name="POLL" low="4" high="5" type="poll_memory_type"/>
+		<bitfield name="WRITE_MEMORY" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="POLL_ADDR_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="POLL_ADDR_HI" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="REF" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="MASK" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="WRITE_ADDR_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="6" name="6">
+		<bitfield name="WRITE_ADDR_HI" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="7" name="7">
+		<bitfield name="WRITE_DATA" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_WAIT_MEM_GTE" width="32">
+        <doc>
+                Wait until a memory value is greater than or equal to the
+                reference, using signed comparison.
+	</doc>
+	<reg32 offset="0" name="0">
+		<!-- Reserved for flags, presumably? Unused in FW -->
+		<bitfield name="RESERVED" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="POLL_ADDR_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="POLL_ADDR_HI" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="REF" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_WAIT_REG_MEM" width="32">
+        <doc>
+                This uses the same internal comparison as CP_COND_WRITE,
+                but waits until the comparison is true instead. It busy-loops in
+                the CP for the given number of cycles before trying again.
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="FUNCTION" low="0" high="2" type="cp_cond_function"/>
+		<bitfield name="SIGNED_COMPARE" pos="3" type="boolean"/>
+		<bitfield name="POLL" low="4" high="5" type="poll_memory_type"/>
+		<bitfield name="WRITE_MEMORY" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="POLL_ADDR_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="POLL_ADDR_HI" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="REF" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="MASK" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="DELAY_LOOP_CYCLES" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_WAIT_TWO_REGS" width="32">
+	<doc>
+		Waits for REG0 to not be 0 or REG1 to not equal REF
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="REG0" low="0" high="17" type="hex"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="REG1" low="0" high="17" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="REF" low="0" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_DISPATCH_COMPUTE" width="32">
+	<reg32 offset="0" name="0"/>
+	<reg32 offset="1" name="1">
+		<bitfield name="X" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="Y" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="Z" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_SET_RENDER_MODE" width="32">
+	<enum name="render_mode_cmd">
+		<value value="1" name="BYPASS"/>
+		<value value="2" name="BINNING"/>
+		<value value="3" name="GMEM"/>
+		<value value="5" name="BLIT2D"/>
+		<!-- placeholder name.. used when CP_BLIT packets with BLIT_OP_SCALE?? -->
+		<value value="7" name="BLIT2DSCALE"/>
+		<!-- 8 set before going back to BYPASS exiting 2D -->
+		<value value="8" name="END2D"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="MODE" low="0" high="8" type="render_mode_cmd"/>
+		<!--
+		normally 0x1/0x3, sometimes see 0x5/0x8 with unknown registers in
+		0x21xx range.. possibly (at least some) a5xx variants have a
+		2d core?
+		 -->
+	</reg32>
+	<!-- I think first buffer is for GPU to save context in case of ctx switch? -->
+	<reg32 offset="1" name="1">
+		<bitfield name="ADDR_0_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="ADDR_0_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<!--
+		set when in GMEM.. maybe indicates GMEM contents need to be
+		preserved on ctx switch?
+		 -->
+		<bitfield name="VSC_ENABLE" pos="3" type="boolean"/>
+		<bitfield name="GMEM_ENABLE" pos="4" type="boolean"/>
+	</reg32>
+	<reg32 offset="4" name="4"/>
+	<!-- second buffer looks like some cmdstream.. length in dwords: -->
+	<reg32 offset="5" name="5">
+		<bitfield name="ADDR_1_LEN" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="6" name="6">
+		<bitfield name="ADDR_1_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="7" name="7">
+		<bitfield name="ADDR_1_HI" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<!-- this looks fairly similar to CP_SET_RENDER_MODE minus first dword -->
+<domain name="CP_COMPUTE_CHECKPOINT" width="32">
+	<!-- I think first buffer is for GPU to save context in case of ctx switch? -->
+	<reg32 offset="0" name="0">
+		<bitfield name="ADDR_0_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="ADDR_0_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+	</reg32>
+	<reg32 offset="3" name="3"/>
+	<!-- second buffer looks like some cmdstream.. length in dwords: -->
+	<reg32 offset="4" name="4">
+		<bitfield name="ADDR_1_LEN" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="ADDR_1_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="6" name="6">
+		<bitfield name="ADDR_1_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="7" name="7"/>
+</domain>
+
+<domain name="CP_PERFCOUNTER_ACTION" width="32">
+	<reg32 offset="0" name="0">
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="ADDR_0_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="ADDR_0_HI" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain varset="chip" name="CP_EVENT_WRITE" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="EVENT" low="0" high="7" type="vgt_event_type"/>
+		<!-- when set, write back timestamp instead of value from packet: -->
+		<bitfield name="TIMESTAMP" pos="30" type="boolean"/>
+		<bitfield name="IRQ" pos="31" type="boolean"/>
+	</reg32>
+	<!--
+	TODO what is gpuaddr for, seems to be all 0's.. maybe needed for
+	context switch?
+	 -->
+	<reg32 offset="1" name="1">
+		<bitfield name="ADDR_0_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="ADDR_0_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<!-- ??? -->
+	</reg32>
+</domain>
+
+<domain varset="chip" name="CP_EVENT_WRITE7" width="32">
+	<enum name="event_write_src">
+		<!-- Write payload[0] -->
+		<value value="0" name="EV_WRITE_USER_32B"/>
+		<!-- Write payload[0] payload[1] -->
+		<value value="1" name="EV_WRITE_USER_64B"/>
+		<!-- Write (TIMESTAMP_GLOBAL + TIMESTAMP_LOCAL) -->
+		<value value="2" name="EV_WRITE_TIMESTAMP_SUM"/>
+		<value value="3" name="EV_WRITE_ALWAYSON"/>
+		<!-- Write payload[1] regs starting at payload[0] offset -->
+		<value value="4" name="EV_WRITE_REGS_CONTENT"/>
+	</enum>
+
+	<enum name="event_write_dst">
+		<value value="0" name="EV_DST_RAM"/>
+		<value value="1" name="EV_DST_ONCHIP"/>
+	</enum>
+
+	<reg32 offset="0" name="0">
+		<bitfield name="EVENT" low="0" high="7" type="vgt_event_type"/>
+		<bitfield name="WRITE_SAMPLE_COUNT" pos="12" type="boolean"/>
+		<!-- Write sample count at (iova + 16) -->
+		<bitfield name="SAMPLE_COUNT_END_OFFSET" pos="13" type="boolean"/>
+		<!-- *(iova + 8) = *(iova + 16) - *iova -->
+		<bitfield name="WRITE_SAMPLE_COUNT_DIFF" pos="14" type="boolean"/>
+
+		<!-- Next 4 flags are valid to set only when concurrent binning is enabled -->
+		<!-- Increment 16b BV counter. Valid only in BV pipe -->
+		<bitfield name="INC_BV_COUNT" pos="16" type="boolean"/>
+		<!-- Increment 16b BR counter. Valid only in BR pipe -->
+		<bitfield name="INC_BR_COUNT" pos="17" type="boolean"/>
+		<bitfield name="CLEAR_RENDER_RESOURCE" pos="18" type="boolean"/>
+		<bitfield name="CLEAR_LRZ_RESOURCE" pos="19" type="boolean"/>
+
+		<bitfield name="WRITE_SRC" low="20" high="22" type="event_write_src"/>
+		<bitfield name="WRITE_DST" pos="24" type="event_write_dst" addvariant="yes"/>
+		<!-- Writes into WRITE_DST from WRITE_SRC. RB_DONE_TS requires WRITE_ENABLED. -->
+		<bitfield name="WRITE_ENABLED" pos="27" type="boolean"/>
+	</reg32>
+
+	<stripe varset="event_write_dst" variants="EV_DST_RAM">
+		<reg32 offset="1" name="1">
+			<bitfield name="ADDR_0_LO" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="2" name="2">
+			<bitfield name="ADDR_0_HI" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="3" name="3">
+			<bitfield name="PAYLOAD_0" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="4" name="4">
+			<bitfield name="PAYLOAD_1" low="0" high="31"/>
+		</reg32>
+	</stripe>
+
+	<stripe varset="event_write_dst" variants="EV_DST_ONCHIP">
+		<reg32 offset="1" name="1">
+			<bitfield name="ONCHIP_ADDR_0" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="3" name="3">
+			<bitfield name="PAYLOAD_0" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="4" name="4">
+			<bitfield name="PAYLOAD_1" low="0" high="31"/>
+		</reg32>
+	</stripe>
+</domain>
+
+<domain name="CP_BLIT" width="32">
+	<enum name="cp_blit_cmd">
+		<value value="0" name="BLIT_OP_FILL"/>
+		<value value="1" name="BLIT_OP_COPY"/>
+		<value value="3" name="BLIT_OP_SCALE"/> <!-- used for mipmap generation -->
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="OP" low="0" high="3" type="cp_blit_cmd"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="SRC_X1" low="0" high="13" type="uint"/>
+		<bitfield name="SRC_Y1" low="16" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="SRC_X2" low="0" high="13" type="uint"/>
+		<bitfield name="SRC_Y2" low="16" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="DST_X1" low="0" high="13" type="uint"/>
+		<bitfield name="DST_Y1" low="16" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="DST_X2" low="0" high="13" type="uint"/>
+		<bitfield name="DST_Y2" low="16" high="29" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_EXEC_CS" width="32">
+	<reg32 offset="0" name="0">
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="NGROUPS_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="NGROUPS_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="NGROUPS_Z" low="0" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_EXEC_CS_INDIRECT" width="32" varset="chip" prefix="chip" variants="A4XX-">
+	<reg32 offset="0" name="0">
+	</reg32>
+	<stripe varset="chip" variants="A4XX">
+		<reg32 offset="1" name="1">
+			<bitfield name="ADDR" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="2" name="2">
+			<!-- localsize is value minus one: -->
+			<bitfield name="LOCALSIZEX" low="2" high="11" type="uint"/>
+			<bitfield name="LOCALSIZEY" low="12" high="21" type="uint"/>
+			<bitfield name="LOCALSIZEZ" low="22" high="31" type="uint"/>
+		</reg32>
+	</stripe>
+	<stripe varset="chip" variants="A5XX-">
+		<reg32 offset="1" name="1">
+			<bitfield name="ADDR_LO" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="2" name="2">
+			<bitfield name="ADDR_HI" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="3" name="3">
+			<!-- localsize is value minus one: -->
+			<bitfield name="LOCALSIZEX" low="2" high="11" type="uint"/>
+			<bitfield name="LOCALSIZEY" low="12" high="21" type="uint"/>
+			<bitfield name="LOCALSIZEZ" low="22" high="31" type="uint"/>
+		</reg32>
+	</stripe>
+</domain>
+
+<domain name="CP_SET_MARKER" width="32" varset="chip" prefix="chip" variants="A6XX-">
+	<doc>Tell CP the current operation mode, indicates save and restore procedure</doc>
+	<enum name="a6xx_marker">
+		<value value="1" name="RM6_BYPASS"/>
+		<value value="2" name="RM6_BINNING"/>
+		<value value="4" name="RM6_GMEM"/>
+		<value value="5" name="RM6_ENDVIS"/>
+		<value value="6" name="RM6_RESOLVE"/>
+		<value value="7" name="RM6_YIELD"/>
+		<value value="8" name="RM6_COMPUTE"/>
+		<value value="0xc" name="RM6_BLIT2DSCALE"/>  <!-- no-op (at least on current sqe fw) -->
+
+		<!--
+			These values come from a6xx_set_marker() in the
+			downstream kernel, and they can only be set by the kernel
+		-->
+		<value value="0xd" name="RM6_IB1LIST_START"/>
+		<value value="0xe" name="RM6_IB1LIST_END"/>
+		<!-- IFPC - inter-frame power collapse -->
+		<value value="0x100" name="RM6_IFPC_ENABLE"/>
+		<value value="0x101" name="RM6_IFPC_DISABLE"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<!--
+			NOTE: blob driver and some versions of freedreno/turnip set
+			b4, which is unused (at least by current sqe fw), but interferes
+			with parsing if we extend the size of the bitfield to include
+			b8 (only sent by kernel mode driver).  Really, the way the
+			parsing works in the firmware, only b0-b3 are considered, but
+			if b8 is set, the low bits are interpreted differently.  To
+			model this, without getting confused by spurious b4, this is
+			described as two overlapping bitfields:
+		 -->
+		<bitfield name="MODE" low="0" high="8" type="a6xx_marker"/>
+		<bitfield name="MARKER" low="0" high="3" type="a6xx_marker"/>
+	</reg32>
+</domain>
+
+<domain name="CP_SET_PSEUDO_REG" width="32" varset="chip" prefix="chip" variants="A6XX-">
+	<doc>Set internal CP registers, used to indicate context save data addresses</doc>
+	<enum name="pseudo_reg">
+		<value value="0" name="SMMU_INFO"/>
+		<value value="1" name="NON_SECURE_SAVE_ADDR"/>
+		<value value="2" name="SECURE_SAVE_ADDR"/>
+		<value value="3" name="NON_PRIV_SAVE_ADDR"/>
+		<value value="4" name="COUNTER"/>
+
+		<!--
+			On a6xx the registers are set directly and CP_SET_BIN_DATA5_OFFSET reads them,
+			but that doesn't work with concurrent binning because BR will be reading from
+			a different set of streams than BV is writing, so on a7xx we have these
+			pseudo-regs instead, which do the right thing.
+
+			The corresponding VSC registers exist, and they're written by BV when it
+			encounters CP_SET_PSEUDO_REG. When BR later encounters the same CP_SET_PSEUDO_REG
+			it will only write some private scratch registers which are read by
+			CP_SET_BIN_DATA5_OFFSET.
+
+			If concurrent binning is disabled then BR also does binning so it will also
+			write the "real" registers in BR.
+		-->
+		<value value="8" name="DRAW_STRM_ADDRESS"/>
+		<value value="9" name="DRAW_STRM_SIZE_ADDRESS"/>
+		<value value="10" name="PRIM_STRM_ADDRESS"/>
+		<value value="11" name="UNK_STRM_ADDRESS"/>
+		<value value="12" name="UNK_STRM_SIZE_ADDRESS"/>
+
+		<value value="16" name="BINDLESS_BASE_0_ADDR"/>
+		<value value="17" name="BINDLESS_BASE_1_ADDR"/>
+		<value value="18" name="BINDLESS_BASE_2_ADDR"/>
+		<value value="19" name="BINDLESS_BASE_3_ADDR"/>
+		<value value="20" name="BINDLESS_BASE_4_ADDR"/>
+		<value value="21" name="BINDLESS_BASE_5_ADDR"/>
+		<value value="22" name="BINDLESS_BASE_6_ADDR"/>
+	</enum>
+	<array offset="0" stride="3" length="100">
+		<reg32 offset="0" name="0">
+			<bitfield name="PSEUDO_REG" low="0" high="10" type="pseudo_reg"/>
+		</reg32>
+		<reg32 offset="1" name="1">
+			<bitfield name="LO" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="2" name="2">
+			<bitfield name="HI" low="0" high="31"/>
+		</reg32>
+	</array>
+</domain>
+
+<domain name="CP_REG_TEST" width="32" varset="chip" prefix="chip" variants="A6XX-">
+	<doc>
+		Tests bit in specified register and sets predicate for CP_COND_REG_EXEC.
+		So:
+
+			opcode: CP_REG_TEST (39) (2 dwords)
+			        { REG = 0xc10 | BIT = 0 }
+			               0000: 70b90001 00000c10
+			opcode: CP_COND_REG_EXEC (47) (3 dwords)
+			               0000: 70c70002 10000000 00000004
+			opcode: CP_INDIRECT_BUFFER (3f) (4 dwords)
+
+		Will execute the CP_INDIRECT_BUFFER only if b0 in the register at
+		offset 0x0c10 is 1
+	</doc>
+	<enum name="source_type">
+		<value value="0" name="SOURCE_REG"/>
+		<!-- Don't confuse with scratch registers, this is a separate memory
+			 written into by CP_MEM_TO_SCRATCH_MEM. -->
+		<value value="1" name="SOURCE_SCRATCH_MEM" varset="chip" variants="A7XX-"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<!-- the register to test -->
+		<bitfield name="REG" low="0" high="17" varset="source_type" variants="SOURCE_REG"/>
+		<bitfield name="SCRATCH_MEM_OFFSET" low="0" high="17" varset="source_type" variants="SOURCE_SCRATCH_MEM"/>
+		<bitfield name="SOURCE" pos="18" type="source_type" addvariant="yes"/>
+		<!-- the bit to test -->
+		<bitfield name="BIT" low="20" high="24" type="uint"/>
+		<!-- skip implied CP_WAIT_FOR_ME -->
+		<bitfield name="SKIP_WAIT_FOR_ME" pos="25" type="boolean"/>
+		<!-- the predicate bit to set (new in gen3+) -->
+		<bitfield name="PRED_BIT" low="26" high="30" type="uint"/>
+		<!-- update the predicate reg directly (new in gen3+) -->
+		<bitfield name="PRED_UPDATE" pos="31" type="boolean"/>
+	</reg32>
+
+        <!--
+		In PRED_UPDATE mode, the predicate reg is updated directly using two
+		more dwords, ignoring other bits:
+
+			PRED_REG = (PRED_REG & ~PRED_MASK) | (PRED_VAL & PRED_MASK);
+	-->
+	<reg32 offset="1" name="PRED_MASK" type="hex"/>
+	<reg32 offset="2" name="PRED_VAL" type="hex"/>
+</domain>
+
+<!-- I *think* this existed at least as far back as a4xx -->
+<domain name="CP_COND_REG_EXEC" width="32">
+	<enum name="compare_mode">
+		<!-- use the predicate bit set by CP_REG_TEST -->
+		<value value="1" name="PRED_TEST"/>
+		<!-- compare two registers directly for equality -->
+		<value value="2" name="REG_COMPARE"/>
+		<!-- test if certain render modes are set via CP_SET_MARKER -->
+		<value value="3" name="RENDER_MODE" varset="chip" variants="A6XX-"/>
+		<!-- compare REG0 for equality with immediate -->
+		<value value="4" name="REG_COMPARE_IMM" varset="chip" variants="A7XX-"/>
+		<!-- test which of BR/BV are enabled -->
+		<value value="5" name="THREAD_MODE" varset="chip" variants="A7XX-"/>
+	</enum>
+	<reg32 offset="0" name="0" varset="compare_mode">
+		<bitfield name="REG0" low="0" high="17" variants="REG_COMPARE" type="hex"/>
+
+		<!-- the predicate bit to test (new in gen3+) -->
+		<bitfield name="PRED_BIT" low="18" high="22" variants="PRED_TEST" type="uint"/>
+		<bitfield name="SKIP_WAIT_FOR_ME" pos="23" varset="chip" variants="A7XX-" type="boolean"/>
+		<!-- With REG_COMPARE instead of register read from ONCHIP memory -->
+		<bitfield name="ONCHIP_MEM" pos="24" varset="chip" variants="A7XX-" type="boolean"/>
+
+		<!--
+			Note: these bits have the same meaning, and use the same
+			internal mechanism as the bits in CP_SET_DRAW_STATE.
+			When RENDER_MODE is selected, they're used as
+			a bitmask of which modes pass the test.
+		-->
+
+		<!-- RM6_BINNING -->
+		<bitfield name="BINNING" pos="25" variants="RENDER_MODE" type="boolean"/>
+		<!-- all others -->
+		<bitfield name="GMEM" pos="26" variants="RENDER_MODE" type="boolean"/>
+		<!-- RM6_BYPASS -->
+		<bitfield name="SYSMEM" pos="27" variants="RENDER_MODE" type="boolean"/>
+
+		<bitfield name="BV" pos="25" variants="THREAD_MODE" type="boolean"/>
+		<bitfield name="BR" pos="26" variants="THREAD_MODE" type="boolean"/>
+		<bitfield name="LPAC" pos="27" variants="THREAD_MODE" type="boolean"/>
+
+		<bitfield name="MODE" low="28" high="31" type="compare_mode" addvariant="yes"/>
+	</reg32>
+
+	<stripe varset="compare_mode" variants="PRED_TEST">
+		<reg32 offset="1" name="1">
+			<bitfield name="DWORDS" low="0" high="23" type="uint"/>
+		</reg32>
+	</stripe>
+
+	<stripe varset="compare_mode" variants="REG_COMPARE">
+		<reg32 offset="1" name="1">
+			<bitfield name="REG1" low="0" high="17" type="hex"/>
+			<!-- Instead of register read from ONCHIP memory -->
+			<bitfield name="ONCHIP_MEM" pos="24" varset="chip" variants="A7XX-" type="boolean"/>
+		</reg32>
+	</stripe>
+
+	<stripe varset="compare_mode" variants="RENDER_MODE">
+		<reg32 offset="1" name="1">
+			<bitfield name="DWORDS" low="0" high="23" type="uint"/>
+		</reg32>
+	</stripe>
+
+	<stripe varset="compare_mode" variants="REG_COMPARE_IMM">
+		<reg32 offset="1" name="1">
+			<bitfield name="IMM" low="0" high="31"/>
+		</reg32>
+	</stripe>
+
+	<stripe varset="compare_mode" variants="THREAD_MODE">
+		<reg32 offset="1" name="1">
+			<bitfield name="DWORDS" low="0" high="23" type="uint"/>
+		</reg32>
+	</stripe>
+
+	<reg32 offset="2" name="2">
+		<bitfield name="DWORDS" low="0" high="23" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_COND_EXEC" width="32">
+	<doc>
+                Executes the following DWORDs of commands if the dword at ADDR0
+                is not equal to 0 and the dword at ADDR1 is less than REF
+                (signed comparison).
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="ADDR0_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="ADDR0_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="ADDR1_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="ADDR1_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="REF" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="DWORDS" low="0" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_SET_AMBLE" width="32">
+	<doc>
+                Used by the userspace and kernel drivers to set various IB's
+                which are executed during context save/restore for handling
+                state that isn't restored by the context switch routine itself.
+  </doc>
+	<enum name="amble_type">
+		<value name="PREAMBLE_AMBLE_TYPE" value="0">
+			<doc>Executed unconditionally when switching back to the context.</doc>
+		</value>
+		<value name="BIN_PREAMBLE_AMBLE_TYPE" value="1">
+                        <doc>
+				Executed when switching back after switching
+				away during execution of
+				a CP_SET_MARKER packet with RM6_BIN_RENDER_END as the
+				payload *and* skipsaverestore is set. This is
+				expected to restore static register values not
+				saved when skipsaverestore is set.
+			</doc>
+		</value>
+		<value name="POSTAMBLE_AMBLE_TYPE" value="2">
+                        <doc>
+				Executed when switching away from the context,
+				except for context switches initiated via
+				CP_YIELD.
+                        </doc>
+		</value>
+		<value name="KMD_AMBLE_TYPE" value="3">
+			<doc>
+				This can only be set by the RB (i.e. the kernel)
+				and executes with protected mode off, but
+				is otherwise similar to POSTAMBLE_AMBLE_TYPE.
+			</doc>
+		</value>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="ADDR_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="ADDR_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="DWORDS" low="0" high="19" type="uint"/>
+		<bitfield name="TYPE" low="20" high="21" type="amble_type"/>
+	</reg32>
+</domain>
+
+<domain name="CP_REG_WRITE" width="32">
+	<enum name="reg_tracker">
+		<doc>
+			Keep shadow copies of these registers and only set them
+			when drawing, avoiding redundant writes:
+			- VPC_CNTL_0
+			- HLSQ_CONTROL_1_REG
+			- HLSQ_UNKNOWN_B980
+		</doc>
+		<value name="TRACK_CNTL_REG" value="0x1"/>
+		<doc>
+			Track RB_RENDER_CNTL, and insert a WFI in the following
+			situation:
+			- There is a write that disables binning
+			- There was a draw with binning left enabled, but in
+			  BYPASS mode
+			Presumably this is a hang workaround?
+		</doc>
+		<value name="TRACK_RENDER_CNTL" value="0x2"/>
+		<doc>
+			Do a mysterious CP_EVENT_WRITE 0x3f when the low bit of
+			the data to write is 0. Used by the Vulkan blob with
+			PC_MULTIVIEW_CNTL, but this isn't predicated on particular
+			register(s) like the others.
+		</doc>
+		<value name="UNK_EVENT_WRITE" value="0x4"/>
+		<doc>
+			Tracks GRAS_LRZ_CNTL::GREATER, GRAS_LRZ_CNTL::DIR, and
+			GRAS_LRZ_DEPTH_VIEW with previous values, and if one of
+			the following is true:
+			- GRAS_LRZ_CNTL::GREATER has changed
+			- GRAS_LRZ_CNTL::DIR has changed, the old value is not
+			  CUR_DIR_GE, and the new value is not CUR_DIR_DISABLED
+			- GRAS_LRZ_DEPTH_VIEW has changed
+			then it does a LRZ_FLUSH with GRAS_LRZ_CNTL::ENABLE
+			forced to 1.
+			Only exists in a650_sqe.fw.
+		</doc>
+		<value name="TRACK_LRZ" value="0x8"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="TRACKER" low="0" high="3" type="reg_tracker"/>
+	</reg32>
+	<reg32 offset="1" name="1"/>
+	<reg32 offset="2" name="2"/>
+</domain>
+
+<domain name="CP_SMMU_TABLE_UPDATE" width="32">
+	<doc>
+		Note that the SMMU's definition of TTBRn can take different forms
+		depending on the pgtable format.  But a5xx+ only uses aarch64
+		format.
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="TTBR0_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="TTBR0_HI" low="0" high="15"/>
+		<bitfield name="ASID" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<doc>Unused, does not apply to aarch64 pgtable format</doc>
+		<bitfield name="CONTEXTIDR" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="CONTEXTBANK" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_START_BIN" width="32">
+	<reg32 offset="0" name="BIN_COUNT" type="uint"/>
+	<reg64 offset="1" name="PREFIX_ADDR" type="address"/>
+	<reg32 offset="3" name="PREFIX_DWORDS">
+		<doc>
+			Size of prefix for each bin. For each bin index i, the
+			prefix commands at PREFIX_ADDR + i * PREFIX_DWORDS are
+			executed in an IB2 before the IB1 commands following
+			this packet.
+		</doc>
+	</reg32>
+	<reg32 offset="4" name="BODY_DWORDS">
+		<doc>Number of dwords after this packet until CP_END_BIN</doc>
+	</reg32>
+</domain>
+
+<domain name="CP_WAIT_TIMESTAMP" width="32">
+	<enum name="ts_wait_value_src">
+		<!-- Wait for value at memory address to be >= SRC_0 (signed comparison) -->
+		<value value="0" name="TS_WAIT_GE_32B"/>
+		<!-- Wait for value at memory address to be >= SRC_0 (unsigned) -->
+		<value value="1" name="TS_WAIT_GE_64B"/>
+		<!-- Write (TIMESTAMP_GLOBAL + TIMESTAMP_LOCAL) -->
+		<value value="2" name="TS_WAIT_GE_TIMESTAMP_SUM"/>
+	</enum>
+
+	<enum name="ts_wait_type">
+		<value value="0" name="TS_WAIT_RAM"/>
+		<value value="1" name="TS_WAIT_ONCHIP"/>
+	</enum>
+
+	<reg32 offset="0" name="0">
+		<bitfield name="WAIT_VALUE_SRC" low="0" high="1" type="ts_wait_value_src"/>
+		<bitfield name="WAIT_DST" pos="4" type="ts_wait_type" addvariant="yes"/>
+	</reg32>
+
+	<stripe varset="ts_wait_type" variants="TS_WAIT_RAM">
+		<reg64 offset="1" name="ADDR" type="address"/>
+	</stripe>
+
+	<stripe varset="ts_wait_type" variants="TS_WAIT_ONCHIP">
+		<reg32 offset="1" name="ONCHIP_ADDR_0" low="0" high="31"/>
+	</stripe>
+
+	<reg32 offset="3" name="SRC_0"/>
+	<reg32 offset="4" name="SRC_1"/>
+</domain>
+
+<domain name="CP_BV_BR_COUNT_OPS" width="32">
+	<enum name="pipe_count_op">
+		<value name="PIPE_CLEAR_BV_BR" value="0x1"/>
+		<value name="PIPE_SET_BR_OFFSET" value="0x2"/>
+		<!-- Wait until for BV_counter > BR_counter -->
+		<value name="PIPE_BR_WAIT_FOR_BV" value="0x3"/>
+		<!-- Wait until (BR_counter + BR_OFFSET) > BV_counter -->
+		<value name="PIPE_BV_WAIT_FOR_BR" value="0x4"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="OP" low="0" high="3" type="pipe_count_op"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="BR_OFFSET" low="0" high="15" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_MODIFY_TIMESTAMP" width="32">
+	<enum name="timestamp_op">
+		<value name="MODIFY_TIMESTAMP_CLEAR" value="0"/>
+		<value name="MODIFY_TIMESTAMP_ADD_GLOBAL" value="1"/>
+		<value name="MODIFY_TIMESTAMP_ADD_LOCAL" value="2"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="ADD" low="0" high="7" type="uint"/>
+		<bitfield name="OP" low="28" high="31" type="timestamp_op"/>
+	</reg32>
+</domain>
+
+<domain name="CP_MEM_TO_SCRATCH_MEM" width="32">
+	<doc>
+		Best guess is that it is a faster way to fetch all the VSC_STATE registers
+		and keep them in a local scratch memory instead of fetching every time
+		when skipping IBs.
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="CNT" low="0" high="5" type="uint"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<doc>Scratch memory size is 48 dwords`</doc>
+		<bitfield name="OFFSET" low="0" high="5" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="SRC" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="SRC_HI" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_THREAD_CONTROL" width="32">
+	<enum name="cp_thread">
+		<value name="CP_SET_THREAD_BR" value="1"/>    <!-- Render -->
+		<value name="CP_SET_THREAD_BV" value="2"/>    <!-- Visibility -->
+		<value name="CP_SET_THREAD_BOTH" value="3"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield low="0" high="1" name="THREAD" type="cp_thread"/>
+		<bitfield pos="27" name="CONCURRENT_BIN_DISABLE" type="boolean"/>
+		<bitfield pos="31" name="SYNC_THREADS" type="boolean"/>
+	</reg32>
+</domain>
+
+<domain name="CP_FIXED_STRIDE_DRAW_TABLE" width="32">
+	<reg64 offset="0" name="IB_BASE"/>
+	<reg32 offset="2" name="2">
+		<!-- STRIDE * COUNT -->
+		<bitfield name="IB_SIZE" low="0" high="11"/>
+		<bitfield name="STRIDE" low="20" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="COUNT" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_RESET_CONTEXT_STATE" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="CLEAR_ON_CHIP_TS" pos="0" type="boolean"/>
+		<bitfield name="CLEAR_RESOURCE_TABLE" pos="1" type="boolean"/>
+		<bitfield name="CLEAR_GLOBAL_LOCAL_TS" pos="2" type="boolean"/>
+	</reg32>
+</domain>
+
+</database>
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/dsi.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/dsi.xml
@@ -0,0 +1,390 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="DSI" width="32">
+	<enum name="dsi_traffic_mode">
+		<value name="NON_BURST_SYNCH_PULSE" value="0"/>
+		<value name="NON_BURST_SYNCH_EVENT" value="1"/>
+		<value name="BURST_MODE" value="2"/>
+	</enum>
+	<enum name="dsi_vid_dst_format">
+		<value name="VID_DST_FORMAT_RGB565" value="0"/>
+		<value name="VID_DST_FORMAT_RGB666" value="1"/>
+		<value name="VID_DST_FORMAT_RGB666_LOOSE" value="2"/>
+		<value name="VID_DST_FORMAT_RGB888" value="3"/>
+	</enum>
+	<enum name="dsi_rgb_swap">
+		<value name="SWAP_RGB" value="0"/>
+		<value name="SWAP_RBG" value="1"/>
+		<value name="SWAP_BGR" value="2"/>
+		<value name="SWAP_BRG" value="3"/>
+		<value name="SWAP_GRB" value="4"/>
+		<value name="SWAP_GBR" value="5"/>
+	</enum>
+	<enum name="dsi_cmd_trigger">
+		<value name="TRIGGER_NONE" value="0"/>
+		<value name="TRIGGER_SEOF" value="1"/>
+		<value name="TRIGGER_TE" value="2"/>
+		<value name="TRIGGER_SW" value="4"/>
+		<value name="TRIGGER_SW_SEOF" value="5"/>
+		<value name="TRIGGER_SW_TE" value="6"/>
+	</enum>
+	<enum name="dsi_cmd_dst_format">
+		<value name="CMD_DST_FORMAT_RGB111" value="0"/>
+		<value name="CMD_DST_FORMAT_RGB332" value="3"/>
+		<value name="CMD_DST_FORMAT_RGB444" value="4"/>
+		<value name="CMD_DST_FORMAT_RGB565" value="6"/>
+		<value name="CMD_DST_FORMAT_RGB666" value="7"/>
+		<value name="CMD_DST_FORMAT_RGB888" value="8"/>
+	</enum>
+	<enum name="dsi_lane_swap">
+		<value name="LANE_SWAP_0123" value="0"/>
+		<value name="LANE_SWAP_3012" value="1"/>
+		<value name="LANE_SWAP_2301" value="2"/>
+		<value name="LANE_SWAP_1230" value="3"/>
+		<value name="LANE_SWAP_0321" value="4"/>
+		<value name="LANE_SWAP_1032" value="5"/>
+		<value name="LANE_SWAP_2103" value="6"/>
+		<value name="LANE_SWAP_3210" value="7"/>
+	</enum>
+		<enum name="video_config_bpp">
+		<value name="VIDEO_CONFIG_18BPP" value="0"/>
+		<value name="VIDEO_CONFIG_24BPP" value="1"/>
+	</enum>
+	<enum name="video_pattern_sel">
+		<value name="VID_PRBS" value="0"/>
+		<value name="VID_INCREMENTAL" value="1"/>
+		<value name="VID_FIXED" value="2"/>
+		<value name="VID_MDSS_GENERAL_PATTERN" value="3"/>
+	</enum>
+	<enum name="cmd_mdp_stream0_pattern_sel">
+		<value name="CMD_MDP_PRBS" value="0"/>
+		<value name="CMD_MDP_INCREMENTAL" value="1"/>
+		<value name="CMD_MDP_FIXED" value="2"/>
+		<value name="CMD_MDP_MDSS_GENERAL_PATTERN" value="3"/>
+	</enum>
+	<enum name="cmd_dma_pattern_sel">
+		<value name="CMD_DMA_PRBS" value="0"/>
+		<value name="CMD_DMA_INCREMENTAL" value="1"/>
+		<value name="CMD_DMA_FIXED" value="2"/>
+		<value name="CMD_DMA_CUSTOM_PATTERN_DMA_FIFO" value="3"/>
+	</enum>
+	<bitset name="DSI_IRQ">
+		<bitfield name="CMD_DMA_DONE" pos="0" type="boolean"/>
+		<bitfield name="MASK_CMD_DMA_DONE" pos="1" type="boolean"/>
+		<bitfield name="CMD_MDP_DONE" pos="8" type="boolean"/>
+		<bitfield name="MASK_CMD_MDP_DONE" pos="9" type="boolean"/>
+		<bitfield name="VIDEO_DONE" pos="16" type="boolean"/>
+		<bitfield name="MASK_VIDEO_DONE" pos="17" type="boolean"/>
+		<bitfield name="BTA_DONE" pos="20" type="boolean"/>
+		<bitfield name="MASK_BTA_DONE" pos="21" type="boolean"/>
+		<bitfield name="ERROR" pos="24" type="boolean"/>
+		<bitfield name="MASK_ERROR" pos="25" type="boolean"/>
+	</bitset>
+
+	<reg32 offset="0x00000" name="6G_HW_VERSION">
+		<bitfield name="MAJOR" low="28" high="31" type="uint"/>
+		<bitfield name="MINOR" low="16" high="27" type="uint"/>
+		<bitfield name="STEP" low="0" high="15" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00000" name="CTRL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="VID_MODE_EN" pos="1" type="boolean"/>
+		<bitfield name="CMD_MODE_EN" pos="2" type="boolean"/>
+		<bitfield name="LANE0" pos="4" type="boolean"/>
+		<bitfield name="LANE1" pos="5" type="boolean"/>
+		<bitfield name="LANE2" pos="6" type="boolean"/>
+		<bitfield name="LANE3" pos="7" type="boolean"/>
+		<bitfield name="CLK_EN" pos="8" type="boolean"/>
+		<bitfield name="ECC_CHECK" pos="20" type="boolean"/>
+		<bitfield name="CRC_CHECK" pos="24" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x00004" name="STATUS0">
+		<bitfield name="CMD_MODE_ENGINE_BUSY" pos="0" type="boolean"/>
+		<bitfield name="CMD_MODE_DMA_BUSY" pos="1" type="boolean"/>
+		<bitfield name="CMD_MODE_MDP_BUSY" pos="2" type="boolean"/>
+		<bitfield name="VIDEO_MODE_ENGINE_BUSY" pos="3" type="boolean"/>
+		<bitfield name="DSI_BUSY" pos="4" type="boolean"/>  <!-- see mipi_dsi_cmd_bta_sw_trigger() -->
+		<bitfield name="INTERLEAVE_OP_CONTENTION" pos="31" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x00008" name="FIFO_STATUS">
+		<bitfield name="VIDEO_MDP_FIFO_OVERFLOW" pos="0" type="boolean"/>
+		<bitfield name="VIDEO_MDP_FIFO_UNDERFLOW" pos="3" type="boolean"/>
+		<bitfield name="CMD_MDP_FIFO_UNDERFLOW" pos="7" type="boolean"/>
+		<bitfield name="CMD_DMA_FIFO_RD_WATERMARK_REACH" pos="8" type="boolean"/>
+		<bitfield name="CMD_DMA_FIFO_WR_WATERMARK_REACH" pos="9" type="boolean"/>
+		<bitfield name="CMD_DMA_FIFO_UNDERFLOW" pos="10" type="boolean"/>
+		<bitfield name="DLN0_LP_FIFO_EMPTY"     pos="12" type="boolean"/>
+		<bitfield name="DLN0_LP_FIFO_FULL"      pos="13" type="boolean"/>
+		<bitfield name="DLN0_LP_FIFO_OVERFLOW"  pos="14" type="boolean"/>
+		<bitfield name="DLN0_HS_FIFO_EMPTY"     pos="16" type="boolean"/>
+		<bitfield name="DLN0_HS_FIFO_FULL"      pos="17" type="boolean"/>
+		<bitfield name="DLN0_HS_FIFO_OVERFLOW"  pos="18" type="boolean"/>
+		<bitfield name="DLN0_HS_FIFO_UNDERFLOW" pos="19" type="boolean"/>
+		<bitfield name="DLN1_HS_FIFO_EMPTY"     pos="20" type="boolean"/>
+		<bitfield name="DLN1_HS_FIFO_FULL"      pos="21" type="boolean"/>
+		<bitfield name="DLN1_HS_FIFO_OVERFLOW"  pos="22" type="boolean"/>
+		<bitfield name="DLN1_HS_FIFO_UNDERFLOW" pos="23" type="boolean"/>
+		<bitfield name="DLN2_HS_FIFO_EMPTY"     pos="24" type="boolean"/>
+		<bitfield name="DLN2_HS_FIFO_FULL"      pos="25" type="boolean"/>
+		<bitfield name="DLN2_HS_FIFO_OVERFLOW"  pos="26" type="boolean"/>
+		<bitfield name="DLN2_HS_FIFO_UNDERFLOW" pos="27" type="boolean"/>
+		<bitfield name="DLN3_HS_FIFO_EMPTY"     pos="28" type="boolean"/>
+		<bitfield name="DLN3_HS_FIFO_FULL"      pos="29" type="boolean"/>
+		<bitfield name="DLN3_HS_FIFO_OVERFLOW"  pos="30" type="boolean"/>
+		<bitfield name="DLN3_HS_FIFO_UNDERFLOW" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0000c" name="VID_CFG0">
+		<bitfield name="VIRT_CHANNEL" low="0" high="1" type="uint"/>  <!-- always zero? -->
+		<bitfield name="DST_FORMAT" low="4" high="5" type="dsi_vid_dst_format"/>
+		<bitfield name="TRAFFIC_MODE" low="8" high="9" type="dsi_traffic_mode"/>
+		<bitfield name="BLLP_POWER_STOP" pos="12" type="boolean"/>
+		<bitfield name="EOF_BLLP_POWER_STOP" pos="15" type="boolean"/>
+		<bitfield name="HSA_POWER_STOP" pos="16" type="boolean"/>
+		<bitfield name="HBP_POWER_STOP" pos="20" type="boolean"/>
+		<bitfield name="HFP_POWER_STOP" pos="24" type="boolean"/>
+		<bitfield name="DATABUS_WIDEN" pos="25" type="boolean"/>
+		<bitfield name="PULSE_MODE_HSA_HE" pos="28" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0001c" name="VID_CFG1">
+		<bitfield name="R_SEL" pos="0" type="boolean"/>
+		<bitfield name="G_SEL" pos="4" type="boolean"/>
+		<bitfield name="B_SEL" pos="8" type="boolean"/>
+		<bitfield name="RGB_SWAP" low="12" high="14" type="dsi_rgb_swap"/>
+	</reg32>
+	<reg32 offset="0x00020" name="ACTIVE_H">
+		<bitfield name="START" low="0" high="11" type="uint"/>
+		<bitfield name="END" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00024" name="ACTIVE_V">
+		<bitfield name="START" low="0" high="11" type="uint"/>
+		<bitfield name="END" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00028" name="TOTAL">
+		<bitfield name="H_TOTAL" low="0" high="11" type="uint"/>
+		<bitfield name="V_TOTAL" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0002c" name="ACTIVE_HSYNC">
+		<bitfield name="START" low="0" high="11" type="uint"/>
+		<bitfield name="END" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00030" name="ACTIVE_VSYNC_HPOS">
+		<bitfield name="START" low="0" high="11" type="uint"/>
+		<bitfield name="END" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00034" name="ACTIVE_VSYNC_VPOS">
+		<bitfield name="START" low="0" high="11" type="uint"/>
+		<bitfield name="END" low="16" high="27" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00038" name="CMD_DMA_CTRL">
+		<bitfield name="BROADCAST_EN" pos="31" type="boolean"/>
+		<bitfield name="FROM_FRAME_BUFFER" pos="28" type="boolean"/>
+		<bitfield name="LOW_POWER" pos="26" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0003c" name="CMD_CFG0">
+		<bitfield name="DST_FORMAT" low="0" high="3" type="dsi_cmd_dst_format"/>
+		<bitfield name="R_SEL" pos="4" type="boolean"/>
+		<bitfield name="G_SEL" pos="8" type="boolean"/>
+		<bitfield name="B_SEL" pos="12" type="boolean"/>
+		<bitfield name="INTERLEAVE_MAX" low="20" high="23" type="uint"/>
+		<bitfield name="RGB_SWAP" low="16" high="18" type="dsi_rgb_swap"/>
+	</reg32>
+	<reg32 offset="0x00040" name="CMD_CFG1">
+		<bitfield name="WR_MEM_START" low="0" high="7" type="uint"/>
+		<bitfield name="WR_MEM_CONTINUE" low="8" high="15" type="uint"/>
+		<bitfield name="INSERT_DCS_COMMAND" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00044" name="DMA_BASE"/>
+	<reg32 offset="0x00048" name="DMA_LEN"/>
+	<reg32 offset="0x00054" name="CMD_MDP_STREAM0_CTRL">
+		<bitfield name="DATA_TYPE" low="0" high="5" type="uint"/>
+		<bitfield name="VIRTUAL_CHANNEL" low="8" high="9" type="uint"/>
+		<bitfield name="WORD_COUNT" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00058" name="CMD_MDP_STREAM0_TOTAL">
+		<bitfield name="H_TOTAL" low="0" high="11" type="uint"/>
+		<bitfield name="V_TOTAL" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0005c" name="CMD_MDP_STREAM1_CTRL">
+		<bitfield name="DATA_TYPE" low="0" high="5" type="uint"/>
+		<bitfield name="VIRTUAL_CHANNEL" low="8" high="9" type="uint"/>
+		<bitfield name="WORD_COUNT" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00060" name="CMD_MDP_STREAM1_TOTAL">
+		<bitfield name="H_TOTAL" low="0" high="15" type="uint"/>
+		<bitfield name="V_TOTAL" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00064" name="ACK_ERR_STATUS"/>
+	<array offset="0x00068" name="RDBK" length="4" stride="4">
+		<reg32 offset="0x0" name="DATA"/>
+	</array>
+	<reg32 offset="0x00080" name="TRIG_CTRL">
+		<bitfield name="DMA_TRIGGER" low="0" high="2" type="dsi_cmd_trigger"/>
+		<bitfield name="MDP_TRIGGER" low="4" high="6" type="dsi_cmd_trigger"/>
+		<bitfield name="STREAM" low="8" high="9" type="uint"/>
+		<bitfield name="BLOCK_DMA_WITHIN_FRAME" pos="12" type="boolean"/>
+		<bitfield name="TE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0008c" name="TRIG_DMA"/>
+	<reg32 offset="0x000b0" name="DLN0_PHY_ERR">
+		<bitfield name="DLN0_ERR_ESC" pos="0" type="boolean"/>
+		<bitfield name="DLN0_ERR_SYNC_ESC" pos="4" type="boolean"/>
+		<bitfield name="DLN0_ERR_CONTROL" pos="8" type="boolean"/>
+		<bitfield name="DLN0_ERR_CONTENTION_LP0" pos="12" type="boolean"/>
+		<bitfield name="DLN0_ERR_CONTENTION_LP1" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x000b4" name="LP_TIMER_CTRL">
+		<bitfield name="LP_RX_TO" low="0" high="15" type="uint"/>
+		<bitfield name="BTA_TO" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x000b8" name="HS_TIMER_CTRL">
+		<bitfield name="HS_TX_TO" low="0" high="15" type="uint"/>
+		<bitfield name="TIMER_RESOLUTION" low="16" high="19" type="uint"/>
+		<bitfield name="HS_TX_TO_STOP_EN" pos="28" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x000bc" name="TIMEOUT_STATUS"/>
+	<reg32 offset="0x000c0" name="CLKOUT_TIMING_CTRL">
+		<bitfield name="T_CLK_PRE" low="0" high="5" type="uint"/>
+		<bitfield name="T_CLK_POST" low="8" high="13" type="uint"/>
+	</reg32>
+	<reg32 offset="0x000c8" name="EOT_PACKET_CTRL">
+		<bitfield name="TX_EOT_APPEND" pos="0" type="boolean"/>
+		<bitfield name="RX_EOT_IGNORE" pos="4" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x000a4" name="LANE_STATUS">
+		<bitfield name="DLN0_STOPSTATE" pos="0" type="boolean"/>
+		<bitfield name="DLN1_STOPSTATE" pos="1" type="boolean"/>
+		<bitfield name="DLN2_STOPSTATE" pos="2" type="boolean"/>
+		<bitfield name="DLN3_STOPSTATE" pos="3" type="boolean"/>
+		<bitfield name="CLKLN_STOPSTATE" pos="4" type="boolean"/>
+		<bitfield name="DLN0_ULPS_ACTIVE_NOT" pos="8" type="boolean"/>
+		<bitfield name="DLN1_ULPS_ACTIVE_NOT" pos="9" type="boolean"/>
+		<bitfield name="DLN2_ULPS_ACTIVE_NOT" pos="10" type="boolean"/>
+		<bitfield name="DLN3_ULPS_ACTIVE_NOT" pos="11" type="boolean"/>
+		<bitfield name="CLKLN_ULPS_ACTIVE_NOT" pos="12" type="boolean"/>
+		<bitfield name="DLN0_DIRECTION" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x000a8" name="LANE_CTRL">
+		<bitfield name="HS_REQ_SEL_PHY" pos="24" type="boolean"/>
+		<bitfield name="CLKLN_HS_FORCE_REQUEST" pos="28" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x000ac" name="LANE_SWAP_CTRL">
+		<bitfield name="DLN_SWAP_SEL" low="0" high="2" type="dsi_lane_swap"/>
+	</reg32>
+	<reg32 offset="0x00108" name="ERR_INT_MASK0"/>
+	<reg32 offset="0x0010c" name="INTR_CTRL" type="DSI_IRQ"/>
+	<reg32 offset="0x00114" name="RESET"/>
+	<reg32 offset="0x00118" name="CLK_CTRL">
+		<bitfield name="AHBS_HCLK_ON" pos="0" type="boolean"/>
+		<bitfield name="AHBM_SCLK_ON" pos="1" type="boolean"/>
+		<bitfield name="PCLK_ON" pos="2" type="boolean"/>
+		<bitfield name="DSICLK_ON" pos="3" type="boolean"/>
+		<bitfield name="BYTECLK_ON" pos="4" type="boolean"/>
+		<bitfield name="ESCCLK_ON" pos="5" type="boolean"/>
+		<bitfield name="FORCE_ON_DYN_AHBM_HCLK" pos="9" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0011c" name="CLK_STATUS">
+		<bitfield name="DSI_AON_AHBM_HCLK_ACTIVE" pos="0" type="boolean"/>
+		<bitfield name="DSI_DYN_AHBM_HCLK_ACTIVE" pos="1" type="boolean"/>
+		<bitfield name="DSI_AON_AHBS_HCLK_ACTIVE" pos="2" type="boolean"/>
+		<bitfield name="DSI_DYN_AHBS_HCLK_ACTIVE" pos="3" type="boolean"/>
+		<bitfield name="DSI_AON_DSICLK_ACTIVE" pos="4" type="boolean"/>
+		<bitfield name="DSI_DYN_DSICLK_ACTIVE" pos="5" type="boolean"/>
+		<bitfield name="DSI_AON_BYTECLK_ACTIVE" pos="6" type="boolean"/>
+		<bitfield name="DSI_DYN_BYTECLK_ACTIVE" pos="7" type="boolean"/>
+		<bitfield name="DSI_AON_ESCCLK_ACTIVE" pos="8" type="boolean"/>
+		<bitfield name="DSI_AON_PCLK_ACTIVE" pos="9" type="boolean"/>
+		<bitfield name="DSI_DYN_PCLK_ACTIVE" pos="10" type="boolean"/>
+		<bitfield name="DSI_DYN_CMD_PCLK_ACTIVE" pos="12" type="boolean"/>
+		<bitfield name="DSI_CMD_PCLK_ACTIVE" pos="13" type="boolean"/>
+		<bitfield name="DSI_VID_PCLK_ACTIVE" pos="14" type="boolean"/>
+		<bitfield name="DSI_CAM_BIST_PCLK_ACT" pos="15" type="boolean"/>
+		<bitfield name="PLL_UNLOCKED" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00128" name="PHY_RESET">
+		<bitfield name="RESET" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00160" name="TEST_PATTERN_GEN_VIDEO_INIT_VAL"/>
+	<reg32 offset="0x00198" name="TPG_MAIN_CONTROL">
+		<bitfield name="CHECKERED_RECTANGLE_PATTERN" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x001a0" name="TPG_VIDEO_CONFIG">
+		<bitfield name="BPP" low="0" high="1" type="video_config_bpp"/>
+		<bitfield name="RGB" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00158" name="TEST_PATTERN_GEN_CTRL">
+		<bitfield name="CMD_DMA_PATTERN_SEL" low="16" high="17" type="cmd_dma_pattern_sel"/>
+		<bitfield name="CMD_MDP_STREAM0_PATTERN_SEL" low="8" high="9" type="cmd_mdp_stream0_pattern_sel"/>
+		<bitfield name="VIDEO_PATTERN_SEL" low="4" high="5" type="video_pattern_sel"/>
+		<bitfield name="TPG_DMA_FIFO_MODE" pos="2" type="boolean"/>
+		<bitfield name="CMD_DMA_TPG_EN" pos="1" type="boolean"/>
+		<bitfield name="EN" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00168" name="TEST_PATTERN_GEN_CMD_MDP_INIT_VAL0"/>
+	<reg32 offset="0x00180" name="TEST_PATTERN_GEN_CMD_STREAM0_TRIGGER">
+		<bitfield name="SW_TRIGGER" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0019c" name="TPG_MAIN_CONTROL2">
+		<bitfield name="CMD_MDP0_CHECKERED_RECTANGLE_PATTERN" pos="7" type="boolean"/>
+		<bitfield name="CMD_MDP1_CHECKERED_RECTANGLE_PATTERN" pos="16" type="boolean"/>
+		<bitfield name="CMD_MDP2_CHECKERED_RECTANGLE_PATTERN" pos="25" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0017c" name="T_CLK_PRE_EXTEND">
+		<bitfield name="INC_BY_2_BYTECLK" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x001b4" name="CMD_MODE_MDP_CTRL2">
+		<bitfield name="DST_FORMAT2" low="0" high="3" type="dsi_cmd_dst_format"/>
+		<bitfield name="R_SEL" pos="4" type="boolean"/>
+		<bitfield name="G_SEL" pos="5" type="boolean"/>
+		<bitfield name="B_SEL" pos="6" type="boolean"/>
+		<bitfield name="BYTE_MSB_LSB_FLIP" pos="7" type="boolean"/>
+		<bitfield name="RGB_SWAP" low="8" high="10" type="dsi_rgb_swap"/>
+		<bitfield name="INPUT_RGB_SWAP" low="12" high="14" type="dsi_rgb_swap"/>
+		<bitfield name="BURST_MODE" pos="16" type="boolean"/>
+		<bitfield name="DATABUS_WIDEN" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x001b8" name="CMD_MODE_MDP_STREAM2_CTRL">
+		<bitfield name="DATA_TYPE" low="0" high="5" type="uint"/>
+		<bitfield name="VIRTUAL_CHANNEL" low="8" high="9" type="uint"/>
+		<bitfield name="WORD_COUNT" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x001d0" name="RDBK_DATA_CTRL">
+		<bitfield name="COUNT" low="16" high="23" type="uint"/>
+		<bitfield name="CLR" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x001f0" name="VERSION">
+		<bitfield name="MAJOR" low="24" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002d4" name="CPHY_MODE_CTRL"/>
+	<reg32 offset="0x0029c" name="VIDEO_COMPRESSION_MODE_CTRL">
+		<bitfield name="WC" low="16" high="31" type="uint"/>
+		<bitfield name="DATATYPE" low="8" high="13" type="uint"/>
+		<bitfield name="PKT_PER_LINE" low="6" high="7" type="uint"/>
+		<bitfield name="EOL_BYTE_NUM" low="4" high="5" type="uint"/>
+		<bitfield name="EN" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x002a4" name="COMMAND_COMPRESSION_MODE_CTRL">
+		<bitfield name="STREAM1_DATATYPE" low="24" high="29" type="uint"/>
+		<bitfield name="STREAM1_PKT_PER_LINE" low="22" high="23" type="uint"/>
+		<bitfield name="STREAM1_EOL_BYTE_NUM" low="20" high="21" type="uint"/>
+		<bitfield name="STREAM1_EN" pos="16" type="boolean"/>
+		<bitfield name="STREAM0_DATATYPE" low="8" high="13" type="uint"/>
+		<bitfield name="STREAM0_PKT_PER_LINE" low="6" high="7" type="uint"/>
+		<bitfield name="STREAM0_EOL_BYTE_NUM" low="4" high="5" type="uint"/>
+		<bitfield name="STREAM0_EN" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x002a8" name="COMMAND_COMPRESSION_MODE_CTRL2">
+		<bitfield name="STREAM1_SLICE_WIDTH" low="16" high="31" type="uint"/>
+		<bitfield name="STREAM0_SLICE_WIDTH" low="0" high="15" type="uint"/>
+	</reg32>
+
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/dsi_phy_10nm.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/dsi_phy_10nm.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="DSI_10nm_PHY_CMN" width="32">
+	<reg32 offset="0x00000" name="REVISION_ID0"/>
+	<reg32 offset="0x00004" name="REVISION_ID1"/>
+	<reg32 offset="0x00008" name="REVISION_ID2"/>
+	<reg32 offset="0x0000c" name="REVISION_ID3"/>
+	<reg32 offset="0x00010" name="CLK_CFG0"/>
+	<reg32 offset="0x00014" name="CLK_CFG1"/>
+	<reg32 offset="0x00018" name="GLBL_CTRL"/>
+	<reg32 offset="0x0001c" name="RBUF_CTRL"/>
+	<reg32 offset="0x00020" name="VREG_CTRL"/>
+	<reg32 offset="0x00024" name="CTRL_0"/>
+	<reg32 offset="0x00028" name="CTRL_1"/>
+	<reg32 offset="0x0002c" name="CTRL_2"/>
+	<reg32 offset="0x00030" name="LANE_CFG0"/>
+	<reg32 offset="0x00034" name="LANE_CFG1"/>
+	<reg32 offset="0x00038" name="PLL_CNTRL"/>
+	<reg32 offset="0x00098" name="LANE_CTRL0"/>
+	<reg32 offset="0x0009c" name="LANE_CTRL1"/>
+	<reg32 offset="0x000a0" name="LANE_CTRL2"/>
+	<reg32 offset="0x000a4" name="LANE_CTRL3"/>
+	<reg32 offset="0x000a8" name="LANE_CTRL4"/>
+	<reg32 offset="0x000ac" name="TIMING_CTRL_0"/>
+	<reg32 offset="0x000b0" name="TIMING_CTRL_1"/>
+	<reg32 offset="0x000b4" name="TIMING_CTRL_2"/>
+	<reg32 offset="0x000b8" name="TIMING_CTRL_3"/>
+	<reg32 offset="0x000bc" name="TIMING_CTRL_4"/>
+	<reg32 offset="0x000c0" name="TIMING_CTRL_5"/>
+	<reg32 offset="0x000c4" name="TIMING_CTRL_6"/>
+	<reg32 offset="0x000c8" name="TIMING_CTRL_7"/>
+	<reg32 offset="0x000cc" name="TIMING_CTRL_8"/>
+	<reg32 offset="0x000d0" name="TIMING_CTRL_9"/>
+	<reg32 offset="0x000d4" name="TIMING_CTRL_10"/>
+	<reg32 offset="0x000d8" name="TIMING_CTRL_11"/>
+	<reg32 offset="0x000ec" name="PHY_STATUS"/>
+	<reg32 offset="0x000f4" name="LANE_STATUS0"/>
+	<reg32 offset="0x000f8" name="LANE_STATUS1"/>
+</domain>
+
+<domain name="DSI_10nm_PHY" width="32">
+	<array offset="0x00000" name="LN" length="5" stride="0x80">
+		<reg32 offset="0x00" name="CFG0"/>
+		<reg32 offset="0x04" name="CFG1"/>
+		<reg32 offset="0x08" name="CFG2"/>
+		<reg32 offset="0x0c" name="CFG3"/>
+		<reg32 offset="0x10" name="TEST_DATAPATH"/>
+		<reg32 offset="0x14" name="PIN_SWAP"/>
+		<reg32 offset="0x18" name="HSTX_STR_CTRL"/>
+		<reg32 offset="0x1c" name="OFFSET_TOP_CTRL"/>
+		<reg32 offset="0x20" name="OFFSET_BOT_CTRL"/>
+		<reg32 offset="0x24" name="LPTX_STR_CTRL"/>
+		<reg32 offset="0x28" name="LPRX_CTRL"/>
+		<reg32 offset="0x2c" name="TX_DCTRL"/>
+	</array>
+</domain>
+
+<domain name="DSI_10nm_PHY_PLL" width="32">
+	<reg32 offset="0x0000" name="ANALOG_CONTROLS_ONE"/>
+	<reg32 offset="0x0004" name="ANALOG_CONTROLS_TWO"/>
+	<reg32 offset="0x0010" name="ANALOG_CONTROLS_THREE"/>
+	<reg32 offset="0x001c" name="DSM_DIVIDER"/>
+	<reg32 offset="0x0020" name="FEEDBACK_DIVIDER"/>
+	<reg32 offset="0x0024" name="SYSTEM_MUXES"/>
+	<reg32 offset="0x002c" name="CMODE"/>
+	<reg32 offset="0x0030" name="CALIBRATION_SETTINGS"/>
+	<reg32 offset="0x0054" name="BAND_SEL_CAL_SETTINGS_THREE"/>
+	<reg32 offset="0x0064" name="FREQ_DETECT_SETTINGS_ONE"/>
+	<reg32 offset="0x007c" name="PFILT"/>
+	<reg32 offset="0x0080" name="IFILT"/>
+	<reg32 offset="0x0094" name="OUTDIV"/>
+	<reg32 offset="0x00a4" name="CORE_OVERRIDE"/>
+	<reg32 offset="0x00a8" name="CORE_INPUT_OVERRIDE"/>
+	<reg32 offset="0x00b4" name="PLL_DIGITAL_TIMERS_TWO"/>
+	<reg32 offset="0x00cc" name="DECIMAL_DIV_START_1"/>
+	<reg32 offset="0x00d0" name="FRAC_DIV_START_LOW_1"/>
+	<reg32 offset="0x00d4" name="FRAC_DIV_START_MID_1"/>
+	<reg32 offset="0x00d8" name="FRAC_DIV_START_HIGH_1"/>
+	<reg32 offset="0x010c" name="SSC_STEPSIZE_LOW_1"/>
+	<reg32 offset="0x0110" name="SSC_STEPSIZE_HIGH_1"/>
+	<reg32 offset="0x0114" name="SSC_DIV_PER_LOW_1"/>
+	<reg32 offset="0x0118" name="SSC_DIV_PER_HIGH_1"/>
+	<reg32 offset="0x011c" name="SSC_DIV_ADJPER_LOW_1"/>
+	<reg32 offset="0x0120" name="SSC_DIV_ADJPER_HIGH_1"/>
+	<reg32 offset="0x013c" name="SSC_CONTROL"/>
+	<reg32 offset="0x0140" name="PLL_OUTDIV_RATE"/>
+	<reg32 offset="0x0144" name="PLL_LOCKDET_RATE_1"/>
+	<reg32 offset="0x014c" name="PLL_PROP_GAIN_RATE_1"/>
+	<reg32 offset="0x0154" name="PLL_BAND_SET_RATE_1"/>
+	<reg32 offset="0x015c" name="PLL_INT_GAIN_IFILT_BAND_1"/>
+	<reg32 offset="0x0164" name="PLL_FL_INT_GAIN_PFILT_BAND_1"/>
+	<reg32 offset="0x0180" name="PLL_LOCK_OVERRIDE"/>
+	<reg32 offset="0x0184" name="PLL_LOCK_DELAY"/>
+	<reg32 offset="0x018c" name="CLOCK_INVERTERS"/>
+	<reg32 offset="0x01a0" name="COMMON_STATUS_ONE"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/dsi_phy_14nm.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/dsi_phy_14nm.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="DSI_14nm_PHY_CMN" width="32">
+	<reg32 offset="0x00000" name="REVISION_ID0"/>
+	<reg32 offset="0x00004" name="REVISION_ID1"/>
+	<reg32 offset="0x00008" name="REVISION_ID2"/>
+	<reg32 offset="0x0000c" name="REVISION_ID3"/>
+	<reg32 offset="0x00010" name="CLK_CFG0">
+		<bitfield name="DIV_CTRL_3_0" low="4" high="7" type="uint"/>
+		<bitfield name="DIV_CTRL_7_4" low="4" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00014" name="CLK_CFG1">
+		<bitfield name="DSICLK_SEL" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00018" name="GLBL_TEST_CTRL">
+		<bitfield name="BITCLK_HS_SEL" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0001C" name="CTRL_0"/>
+	<reg32 offset="0x00020" name="CTRL_1">
+	</reg32>
+	<reg32 offset="0x00024" name="HW_TRIGGER"/>
+	<reg32 offset="0x00028" name="SW_CFG0"/>
+	<reg32 offset="0x0002C" name="SW_CFG1"/>
+	<reg32 offset="0x00030" name="SW_CFG2"/>
+	<reg32 offset="0x00034" name="HW_CFG0"/>
+	<reg32 offset="0x00038" name="HW_CFG1"/>
+	<reg32 offset="0x0003C" name="HW_CFG2"/>
+	<reg32 offset="0x00040" name="HW_CFG3"/>
+	<reg32 offset="0x00044" name="HW_CFG4"/>
+	<reg32 offset="0x00048" name="PLL_CNTRL">
+		<bitfield name="PLL_START" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0004C" name="LDO_CNTRL">
+		<bitfield name="VREG_CTRL" low="0" high="5" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="DSI_14nm_PHY" width="32">
+	<array offset="0x00000" name="LN" length="5" stride="0x80">
+		<reg32 offset="0x00" name="CFG0">
+			<bitfield name="PREPARE_DLY" low="6" high="7" type="uint"/>
+		</reg32>
+		<reg32 offset="0x04" name="CFG1">
+			<bitfield name="HALFBYTECLK_EN" pos="0" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x08" name="CFG2"/>
+		<reg32 offset="0x0c" name="CFG3"/>
+		<reg32 offset="0x10" name="TEST_DATAPATH"/>
+		<reg32 offset="0x14" name="TEST_STR"/>
+		<reg32 offset="0x18" name="TIMING_CTRL_4">
+			<bitfield name="HS_EXIT" low="0" high="7" type="uint"/>
+		</reg32>
+		<reg32 offset="0x1c" name="TIMING_CTRL_5">
+			<bitfield name="HS_ZERO" low="0" high="7" type="uint"/>
+		</reg32>
+		<reg32 offset="0x20" name="TIMING_CTRL_6">
+			<bitfield name="HS_PREPARE" low="0" high="7" type="uint"/>
+		</reg32>
+		<reg32 offset="0x24" name="TIMING_CTRL_7">
+			<bitfield name="HS_TRAIL" low="0" high="7" type="uint"/>
+		</reg32>
+		<reg32 offset="0x28" name="TIMING_CTRL_8">
+			<bitfield name="HS_RQST" low="0" high="7" type="uint"/>
+		</reg32>
+		<reg32 offset="0x2c" name="TIMING_CTRL_9">
+			<bitfield name="TA_GO" low="0" high="2" type="uint"/>
+			<bitfield name="TA_SURE" low="4" high="6" type="uint"/>
+		</reg32>
+		<reg32 offset="0x30" name="TIMING_CTRL_10">
+			<bitfield name="TA_GET" low="0" high="2" type="uint"/>
+		</reg32>
+		<reg32 offset="0x34" name="TIMING_CTRL_11">
+			<bitfield name="TRIG3_CMD" low="0" high="7" type="uint"/>
+		</reg32>
+		<reg32 offset="0x38" name="STRENGTH_CTRL_0"/>
+		<reg32 offset="0x3c" name="STRENGTH_CTRL_1"/>
+		<reg32 offset="0x64" name="VREG_CNTRL"/>
+	</array>
+</domain>
+
+<domain name="DSI_14nm_PHY_PLL" width="32">
+	<reg32 offset="0x000" name="IE_TRIM"/>
+	<reg32 offset="0x004" name="IP_TRIM"/>
+	<reg32 offset="0x010" name="IPTAT_TRIM"/>
+	<reg32 offset="0x01c" name="CLKBUFLR_EN"/>
+	<reg32 offset="0x028" name="SYSCLK_EN_RESET"/>
+	<reg32 offset="0x02c" name="RESETSM_CNTRL"/>
+	<reg32 offset="0x030" name="RESETSM_CNTRL2"/>
+	<reg32 offset="0x034" name="RESETSM_CNTRL3"/>
+	<reg32 offset="0x038" name="RESETSM_CNTRL4"/>
+	<reg32 offset="0x03c" name="RESETSM_CNTRL5"/>
+	<reg32 offset="0x040" name="KVCO_DIV_REF1"/>
+	<reg32 offset="0x044" name="KVCO_DIV_REF2"/>
+	<reg32 offset="0x048" name="KVCO_COUNT1"/>
+	<reg32 offset="0x04c" name="KVCO_COUNT2"/>
+	<reg32 offset="0x05c" name="VREF_CFG1"/>
+	<reg32 offset="0x058" name="KVCO_CODE"/>
+	<reg32 offset="0x06c" name="VCO_DIV_REF1"/>
+	<reg32 offset="0x070" name="VCO_DIV_REF2"/>
+	<reg32 offset="0x074" name="VCO_COUNT1"/>
+	<reg32 offset="0x078" name="VCO_COUNT2"/>
+	<reg32 offset="0x07c" name="PLLLOCK_CMP1"/>
+	<reg32 offset="0x080" name="PLLLOCK_CMP2"/>
+	<reg32 offset="0x084" name="PLLLOCK_CMP3"/>
+	<reg32 offset="0x088" name="PLLLOCK_CMP_EN"/>
+	<reg32 offset="0x08c" name="PLL_VCO_TUNE"/>
+	<reg32 offset="0x090" name="DEC_START"/>
+	<reg32 offset="0x094" name="SSC_EN_CENTER"/>
+	<reg32 offset="0x098" name="SSC_ADJ_PER1"/>
+	<reg32 offset="0x09c" name="SSC_ADJ_PER2"/>
+	<reg32 offset="0x0a0" name="SSC_PER1"/>
+	<reg32 offset="0x0a4" name="SSC_PER2"/>
+	<reg32 offset="0x0a8" name="SSC_STEP_SIZE1"/>
+	<reg32 offset="0x0ac" name="SSC_STEP_SIZE2"/>
+	<reg32 offset="0x0b4" name="DIV_FRAC_START1"/>
+	<reg32 offset="0x0b8" name="DIV_FRAC_START2"/>
+	<reg32 offset="0x0bc" name="DIV_FRAC_START3"/>
+	<reg32 offset="0x0c0" name="TXCLK_EN"/>
+	<reg32 offset="0x0c4" name="PLL_CRCTRL"/>
+	<reg32 offset="0x0cc" name="RESET_SM_READY_STATUS"/>
+	<reg32 offset="0x0e8" name="PLL_MISC1"/>
+	<reg32 offset="0x0f0" name="CP_SET_CUR"/>
+	<reg32 offset="0x0f4" name="PLL_ICPMSET"/>
+	<reg32 offset="0x0f8" name="PLL_ICPCSET"/>
+	<reg32 offset="0x0fc" name="PLL_ICP_SET"/>
+	<reg32 offset="0x100" name="PLL_LPF1"/>
+	<reg32 offset="0x104" name="PLL_LPF2_POSTDIV"/>
+	<reg32 offset="0x108" name="PLL_BANDGAP"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/dsi_phy_20nm.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/dsi_phy_20nm.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="DSI_20nm_PHY" width="32">
+	<array offset="0x00000" name="LN" length="4" stride="0x40">
+		<reg32 offset="0x00" name="CFG_0"/>
+		<reg32 offset="0x04" name="CFG_1"/>
+		<reg32 offset="0x08" name="CFG_2"/>
+		<reg32 offset="0x0c" name="CFG_3"/>
+		<reg32 offset="0x10" name="CFG_4"/>
+		<reg32 offset="0x14" name="TEST_DATAPATH"/>
+		<reg32 offset="0x18" name="DEBUG_SEL"/>
+		<reg32 offset="0x1c" name="TEST_STR_0"/>
+		<reg32 offset="0x20" name="TEST_STR_1"/>
+	</array>
+
+	<reg32 offset="0x00100" name="LNCK_CFG_0"/>
+	<reg32 offset="0x00104" name="LNCK_CFG_1"/>
+	<reg32 offset="0x00108" name="LNCK_CFG_2"/>
+	<reg32 offset="0x0010c" name="LNCK_CFG_3"/>
+	<reg32 offset="0x00110" name="LNCK_CFG_4"/>
+	<reg32 offset="0x00114" name="LNCK_TEST_DATAPATH"/>
+	<reg32 offset="0x00118" name="LNCK_DEBUG_SEL"/>
+	<reg32 offset="0x0011c" name="LNCK_TEST_STR0"/>
+	<reg32 offset="0x00120" name="LNCK_TEST_STR1"/>
+
+	<reg32 offset="0x00140" name="TIMING_CTRL_0">
+		<bitfield name="CLK_ZERO" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00144" name="TIMING_CTRL_1">
+		<bitfield name="CLK_TRAIL" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00148" name="TIMING_CTRL_2">
+		<bitfield name="CLK_PREPARE" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0014c" name="TIMING_CTRL_3">
+		<bitfield name="CLK_ZERO_8" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00150" name="TIMING_CTRL_4">
+		<bitfield name="HS_EXIT" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00154" name="TIMING_CTRL_5">
+		<bitfield name="HS_ZERO" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00158" name="TIMING_CTRL_6">
+		<bitfield name="HS_PREPARE" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0015c" name="TIMING_CTRL_7">
+		<bitfield name="HS_TRAIL" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00160" name="TIMING_CTRL_8">
+		<bitfield name="HS_RQST" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00164" name="TIMING_CTRL_9">
+		<bitfield name="TA_GO" low="0" high="2" type="uint"/>
+		<bitfield name="TA_SURE" low="4" high="6" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00168" name="TIMING_CTRL_10">
+		<bitfield name="TA_GET" low="0" high="2" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0016c" name="TIMING_CTRL_11">
+		<bitfield name="TRIG3_CMD" low="0" high="7" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00170" name="CTRL_0"/>
+	<reg32 offset="0x00174" name="CTRL_1"/>
+	<reg32 offset="0x00178" name="CTRL_2"/>
+	<reg32 offset="0x0017c" name="CTRL_3"/>
+	<reg32 offset="0x00180" name="CTRL_4"/>
+
+	<reg32 offset="0x00184" name="STRENGTH_0"/>
+	<reg32 offset="0x00188" name="STRENGTH_1"/>
+
+	<reg32 offset="0x001b4" name="BIST_CTRL_0"/>
+	<reg32 offset="0x001b8" name="BIST_CTRL_1"/>
+	<reg32 offset="0x001bc" name="BIST_CTRL_2"/>
+	<reg32 offset="0x001c0" name="BIST_CTRL_3"/>
+	<reg32 offset="0x001c4" name="BIST_CTRL_4"/>
+	<reg32 offset="0x001c8" name="BIST_CTRL_5"/>
+
+	<reg32 offset="0x001d4" name="GLBL_TEST_CTRL">
+		<bitfield name="BITCLK_HS_SEL" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x001dc" name="LDO_CNTRL"/>
+</domain>
+
+<domain name="DSI_20nm_PHY_REGULATOR" width="32">
+	<reg32 offset="0x00000" name="CTRL_0"/>
+	<reg32 offset="0x00004" name="CTRL_1"/>
+	<reg32 offset="0x00008" name="CTRL_2"/>
+	<reg32 offset="0x0000c" name="CTRL_3"/>
+	<reg32 offset="0x00010" name="CTRL_4"/>
+	<reg32 offset="0x00014" name="CTRL_5"/>
+	<reg32 offset="0x00018" name="CAL_PWR_CFG"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/dsi_phy_28nm.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/dsi_phy_28nm.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="DSI_28nm_PHY" width="32">
+	<array offset="0x00000" name="LN" length="4" stride="0x40">
+		<reg32 offset="0x00" name="CFG_0"/>
+		<reg32 offset="0x04" name="CFG_1"/>
+		<reg32 offset="0x08" name="CFG_2"/>
+		<reg32 offset="0x0c" name="CFG_3"/>
+		<reg32 offset="0x10" name="CFG_4"/>
+		<reg32 offset="0x14" name="TEST_DATAPATH"/>
+		<reg32 offset="0x18" name="DEBUG_SEL"/>
+		<reg32 offset="0x1c" name="TEST_STR_0"/>
+		<reg32 offset="0x20" name="TEST_STR_1"/>
+	</array>
+
+	<reg32 offset="0x00100" name="LNCK_CFG_0"/>
+	<reg32 offset="0x00104" name="LNCK_CFG_1"/>
+	<reg32 offset="0x00108" name="LNCK_CFG_2"/>
+	<reg32 offset="0x0010c" name="LNCK_CFG_3"/>
+	<reg32 offset="0x00110" name="LNCK_CFG_4"/>
+	<reg32 offset="0x00114" name="LNCK_TEST_DATAPATH"/>
+	<reg32 offset="0x00118" name="LNCK_DEBUG_SEL"/>
+	<reg32 offset="0x0011c" name="LNCK_TEST_STR0"/>
+	<reg32 offset="0x00120" name="LNCK_TEST_STR1"/>
+
+	<reg32 offset="0x00140" name="TIMING_CTRL_0">
+		<bitfield name="CLK_ZERO" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00144" name="TIMING_CTRL_1">
+		<bitfield name="CLK_TRAIL" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00148" name="TIMING_CTRL_2">
+		<bitfield name="CLK_PREPARE" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0014c" name="TIMING_CTRL_3">
+		<bitfield name="CLK_ZERO_8" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00150" name="TIMING_CTRL_4">
+		<bitfield name="HS_EXIT" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00154" name="TIMING_CTRL_5">
+		<bitfield name="HS_ZERO" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00158" name="TIMING_CTRL_6">
+		<bitfield name="HS_PREPARE" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0015c" name="TIMING_CTRL_7">
+		<bitfield name="HS_TRAIL" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00160" name="TIMING_CTRL_8">
+		<bitfield name="HS_RQST" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00164" name="TIMING_CTRL_9">
+		<bitfield name="TA_GO" low="0" high="2" type="uint"/>
+		<bitfield name="TA_SURE" low="4" high="6" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00168" name="TIMING_CTRL_10">
+		<bitfield name="TA_GET" low="0" high="2" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0016c" name="TIMING_CTRL_11">
+		<bitfield name="TRIG3_CMD" low="0" high="7" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00170" name="CTRL_0"/>
+	<reg32 offset="0x00174" name="CTRL_1"/>
+	<reg32 offset="0x00178" name="CTRL_2"/>
+	<reg32 offset="0x0017c" name="CTRL_3"/>
+	<reg32 offset="0x00180" name="CTRL_4"/>
+
+	<reg32 offset="0x00184" name="STRENGTH_0"/>
+	<reg32 offset="0x00188" name="STRENGTH_1"/>
+
+	<reg32 offset="0x001b4" name="BIST_CTRL_0"/>
+	<reg32 offset="0x001b8" name="BIST_CTRL_1"/>
+	<reg32 offset="0x001bc" name="BIST_CTRL_2"/>
+	<reg32 offset="0x001c0" name="BIST_CTRL_3"/>
+	<reg32 offset="0x001c4" name="BIST_CTRL_4"/>
+	<reg32 offset="0x001c8" name="BIST_CTRL_5"/>
+
+	<reg32 offset="0x001d4" name="GLBL_TEST_CTRL">
+		<bitfield name="BITCLK_HS_SEL" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x001dc" name="LDO_CNTRL"/>
+</domain>
+
+<domain name="DSI_28nm_PHY_REGULATOR" width="32">
+	<reg32 offset="0x00000" name="CTRL_0"/>
+	<reg32 offset="0x00004" name="CTRL_1"/>
+	<reg32 offset="0x00008" name="CTRL_2"/>
+	<reg32 offset="0x0000c" name="CTRL_3"/>
+	<reg32 offset="0x00010" name="CTRL_4"/>
+	<reg32 offset="0x00014" name="CTRL_5"/>
+	<reg32 offset="0x00018" name="CAL_PWR_CFG"/>
+</domain>
+
+<domain name="DSI_28nm_PHY_PLL" width="32">
+	<reg32 offset="0x00000" name="REFCLK_CFG">
+		<bitfield name="DBLR" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00004" name="POSTDIV1_CFG"/>
+	<reg32 offset="0x00008" name="CHGPUMP_CFG"/>
+	<reg32 offset="0x0000C" name="VCOLPF_CFG"/>
+	<reg32 offset="0x00010" name="VREG_CFG">
+		<bitfield name="POSTDIV1_BYPASS_B" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00014" name="PWRGEN_CFG"/>
+	<reg32 offset="0x00018" name="DMUX_CFG"/>
+	<reg32 offset="0x0001C" name="AMUX_CFG"/>
+	<reg32 offset="0x00020" name="GLB_CFG">
+		<bitfield name="PLL_PWRDN_B" pos="0" type="boolean"/>
+		<bitfield name="PLL_LDO_PWRDN_B" pos="1" type="boolean"/>
+		<bitfield name="PLL_PWRGEN_PWRDN_B" pos="2" type="boolean"/>
+		<bitfield name="PLL_ENABLE" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00024" name="POSTDIV2_CFG"/>
+	<reg32 offset="0x00028" name="POSTDIV3_CFG"/>
+	<reg32 offset="0x0002C" name="LPFR_CFG"/>
+	<reg32 offset="0x00030" name="LPFC1_CFG"/>
+	<reg32 offset="0x00034" name="LPFC2_CFG"/>
+	<reg32 offset="0x00038" name="SDM_CFG0">
+		<bitfield name="BYP_DIV" low="0" high="5" type="uint"/>
+		<bitfield name="BYP" pos="6" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0003C" name="SDM_CFG1">
+		<bitfield name="DC_OFFSET" low="0" high="5" type="uint"/>
+		<bitfield name="DITHER_EN" pos="6" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00040" name="SDM_CFG2">
+		<bitfield name="FREQ_SEED_7_0" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00044" name="SDM_CFG3">
+		<bitfield name="FREQ_SEED_15_8" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00048" name="SDM_CFG4"/>
+	<reg32 offset="0x0004C" name="SSC_CFG0"/>
+	<reg32 offset="0x00050" name="SSC_CFG1"/>
+	<reg32 offset="0x00054" name="SSC_CFG2"/>
+	<reg32 offset="0x00058" name="SSC_CFG3"/>
+	<reg32 offset="0x0005C" name="LKDET_CFG0"/>
+	<reg32 offset="0x00060" name="LKDET_CFG1"/>
+	<reg32 offset="0x00064" name="LKDET_CFG2"/>
+	<reg32 offset="0x00068" name="TEST_CFG">
+		<bitfield name="PLL_SW_RESET" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0006C" name="CAL_CFG0"/>
+	<reg32 offset="0x00070" name="CAL_CFG1"/>
+	<reg32 offset="0x00074" name="CAL_CFG2"/>
+	<reg32 offset="0x00078" name="CAL_CFG3"/>
+	<reg32 offset="0x0007C" name="CAL_CFG4"/>
+	<reg32 offset="0x00080" name="CAL_CFG5"/>
+	<reg32 offset="0x00084" name="CAL_CFG6"/>
+	<reg32 offset="0x00088" name="CAL_CFG7"/>
+	<reg32 offset="0x0008C" name="CAL_CFG8"/>
+	<reg32 offset="0x00090" name="CAL_CFG9"/>
+	<reg32 offset="0x00094" name="CAL_CFG10"/>
+	<reg32 offset="0x00098" name="CAL_CFG11"/>
+	<reg32 offset="0x0009C" name="EFUSE_CFG"/>
+	<reg32 offset="0x000A0" name="DEBUG_BUS_SEL"/>
+	<reg32 offset="0x000A4" name="CTRL_42"/>
+	<reg32 offset="0x000A8" name="CTRL_43"/>
+	<reg32 offset="0x000AC" name="CTRL_44"/>
+	<reg32 offset="0x000B0" name="CTRL_45"/>
+	<reg32 offset="0x000B4" name="CTRL_46"/>
+	<reg32 offset="0x000B8" name="CTRL_47"/>
+	<reg32 offset="0x000BC" name="CTRL_48"/>
+	<reg32 offset="0x000C0" name="STATUS">
+		<bitfield name="PLL_RDY" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x000C4" name="DEBUG_BUS0"/>
+	<reg32 offset="0x000C8" name="DEBUG_BUS1"/>
+	<reg32 offset="0x000CC" name="DEBUG_BUS2"/>
+	<reg32 offset="0x000D0" name="DEBUG_BUS3"/>
+	<reg32 offset="0x000D4" name="CTRL_54"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/dsi_phy_28nm_8960.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/dsi_phy_28nm_8960.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="DSI_28nm_8960_PHY" width="32">
+
+	<array offset="0x00000" name="LN" length="4" stride="0x40">
+		<reg32 offset="0x00" name="CFG_0"/>
+		<reg32 offset="0x04" name="CFG_1"/>
+		<reg32 offset="0x08" name="CFG_2"/>
+		<reg32 offset="0x0c" name="TEST_DATAPATH"/>
+		<reg32 offset="0x14" name="TEST_STR_0"/>
+		<reg32 offset="0x18" name="TEST_STR_1"/>
+	</array>
+
+	<reg32 offset="0x00100" name="LNCK_CFG_0"/>
+	<reg32 offset="0x00104" name="LNCK_CFG_1"/>
+	<reg32 offset="0x00108" name="LNCK_CFG_2"/>
+
+	<reg32 offset="0x0010c" name="LNCK_TEST_DATAPATH"/>
+	<reg32 offset="0x00114" name="LNCK_TEST_STR0"/>
+	<reg32 offset="0x00118" name="LNCK_TEST_STR1"/>
+
+	<reg32 offset="0x00140" name="TIMING_CTRL_0">
+		<bitfield name="CLK_ZERO" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00144" name="TIMING_CTRL_1">
+		<bitfield name="CLK_TRAIL" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00148" name="TIMING_CTRL_2">
+		<bitfield name="CLK_PREPARE" low="0" high="7" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x0014c" name="TIMING_CTRL_3"/>
+
+	<reg32 offset="0x00150" name="TIMING_CTRL_4">
+		<bitfield name="HS_EXIT" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00154" name="TIMING_CTRL_5">
+		<bitfield name="HS_ZERO" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00158" name="TIMING_CTRL_6">
+		<bitfield name="HS_PREPARE" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0015c" name="TIMING_CTRL_7">
+		<bitfield name="HS_TRAIL" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00160" name="TIMING_CTRL_8">
+		<bitfield name="HS_RQST" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00164" name="TIMING_CTRL_9">
+		<bitfield name="TA_GO" low="0" high="2" type="uint"/>
+		<bitfield name="TA_SURE" low="4" high="6" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00168" name="TIMING_CTRL_10">
+		<bitfield name="TA_GET" low="0" high="2" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0016c" name="TIMING_CTRL_11">
+		<bitfield name="TRIG3_CMD" low="0" high="7" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00170" name="CTRL_0"/>
+	<reg32 offset="0x00174" name="CTRL_1"/>
+	<reg32 offset="0x00178" name="CTRL_2"/>
+	<reg32 offset="0x0017c" name="CTRL_3"/>
+
+	<reg32 offset="0x00180" name="STRENGTH_0"/>
+	<reg32 offset="0x00184" name="STRENGTH_1"/>
+	<reg32 offset="0x00188" name="STRENGTH_2"/>
+
+	<reg32 offset="0x0018c" name="BIST_CTRL_0"/>
+	<reg32 offset="0x00190" name="BIST_CTRL_1"/>
+	<reg32 offset="0x00194" name="BIST_CTRL_2"/>
+	<reg32 offset="0x00198" name="BIST_CTRL_3"/>
+	<reg32 offset="0x0019c" name="BIST_CTRL_4"/>
+
+	<reg32 offset="0x001b0" name="LDO_CTRL"/>
+</domain>
+
+<domain name="DSI_28nm_8960_PHY_MISC" width="32">
+	<reg32 offset="0x00000" name="REGULATOR_CTRL_0"/>
+	<reg32 offset="0x00004" name="REGULATOR_CTRL_1"/>
+	<reg32 offset="0x00008" name="REGULATOR_CTRL_2"/>
+	<reg32 offset="0x0000c" name="REGULATOR_CTRL_3"/>
+	<reg32 offset="0x00010" name="REGULATOR_CTRL_4"/>
+	<reg32 offset="0x00014" name="REGULATOR_CTRL_5"/>
+	<reg32 offset="0x00018" name="REGULATOR_CAL_PWR_CFG"/>
+	<reg32 offset="0x00028" name="CAL_HW_TRIGGER"/>
+	<reg32 offset="0x0002c" name="CAL_SW_CFG_0"/>
+	<reg32 offset="0x00030" name="CAL_SW_CFG_1"/>
+	<reg32 offset="0x00034" name="CAL_SW_CFG_2"/>
+	<reg32 offset="0x00038" name="CAL_HW_CFG_0"/>
+	<reg32 offset="0x0003c" name="CAL_HW_CFG_1"/>
+	<reg32 offset="0x00040" name="CAL_HW_CFG_2"/>
+	<reg32 offset="0x00044" name="CAL_HW_CFG_3"/>
+	<reg32 offset="0x00048" name="CAL_HW_CFG_4"/>
+	<reg32 offset="0x00050" name="CAL_STATUS">
+		<bitfield name="CAL_BUSY" pos="4" type="boolean"/>
+	</reg32>
+</domain>
+
+<domain name="DSI_28nm_8960_PHY_PLL" width="32">
+	<reg32 offset="0x00000" name="CTRL_0">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00004" name="CTRL_1"/>
+	<reg32 offset="0x00008" name="CTRL_2"/>
+	<reg32 offset="0x0000c" name="CTRL_3"/>
+	<reg32 offset="0x00010" name="CTRL_4"/>
+	<reg32 offset="0x00014" name="CTRL_5"/>
+	<reg32 offset="0x00018" name="CTRL_6"/>
+	<reg32 offset="0x0001c" name="CTRL_7"/>
+	<reg32 offset="0x00020" name="CTRL_8"/>
+	<reg32 offset="0x00024" name="CTRL_9"/>
+	<reg32 offset="0x00028" name="CTRL_10"/>
+	<reg32 offset="0x0002c" name="CTRL_11"/>
+	<reg32 offset="0x00030" name="CTRL_12"/>
+	<reg32 offset="0x00034" name="CTRL_13"/>
+	<reg32 offset="0x00038" name="CTRL_14"/>
+	<reg32 offset="0x0003c" name="CTRL_15"/>
+	<reg32 offset="0x00040" name="CTRL_16"/>
+	<reg32 offset="0x00044" name="CTRL_17"/>
+	<reg32 offset="0x00048" name="CTRL_18"/>
+	<reg32 offset="0x0004c" name="CTRL_19"/>
+	<reg32 offset="0x00050" name="CTRL_20"/>
+
+	<reg32 offset="0x00080" name="RDY">
+		<bitfield name="PLL_RDY" pos="0" type="boolean"/>
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/dsi_phy_7nm.xml
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="DSI_7nm_PHY_CMN" width="32">
+	<reg32 offset="0x00000" name="REVISION_ID0"/>
+	<reg32 offset="0x00004" name="REVISION_ID1"/>
+	<reg32 offset="0x00008" name="REVISION_ID2"/>
+	<reg32 offset="0x0000c" name="REVISION_ID3"/>
+	<reg32 offset="0x00010" name="CLK_CFG0"/>
+	<reg32 offset="0x00014" name="CLK_CFG1"/>
+	<reg32 offset="0x00018" name="GLBL_CTRL"/>
+	<reg32 offset="0x0001c" name="RBUF_CTRL"/>
+	<reg32 offset="0x00020" name="VREG_CTRL_0"/>
+	<reg32 offset="0x00024" name="CTRL_0"/>
+	<reg32 offset="0x00028" name="CTRL_1"/>
+	<reg32 offset="0x0002c" name="CTRL_2"/>
+	<reg32 offset="0x00030" name="CTRL_3"/>
+	<reg32 offset="0x00034" name="LANE_CFG0"/>
+	<reg32 offset="0x00038" name="LANE_CFG1"/>
+	<reg32 offset="0x0003c" name="PLL_CNTRL"/>
+	<reg32 offset="0x00040" name="DPHY_SOT"/>
+	<reg32 offset="0x000a0" name="LANE_CTRL0"/>
+	<reg32 offset="0x000a4" name="LANE_CTRL1"/>
+	<reg32 offset="0x000a8" name="LANE_CTRL2"/>
+	<reg32 offset="0x000ac" name="LANE_CTRL3"/>
+	<reg32 offset="0x000b0" name="LANE_CTRL4"/>
+	<reg32 offset="0x000b4" name="TIMING_CTRL_0"/>
+	<reg32 offset="0x000b8" name="TIMING_CTRL_1"/>
+	<reg32 offset="0x000bc" name="TIMING_CTRL_2"/>
+	<reg32 offset="0x000c0" name="TIMING_CTRL_3"/>
+	<reg32 offset="0x000c4" name="TIMING_CTRL_4"/>
+	<reg32 offset="0x000c8" name="TIMING_CTRL_5"/>
+	<reg32 offset="0x000cc" name="TIMING_CTRL_6"/>
+	<reg32 offset="0x000d0" name="TIMING_CTRL_7"/>
+	<reg32 offset="0x000d4" name="TIMING_CTRL_8"/>
+	<reg32 offset="0x000d8" name="TIMING_CTRL_9"/>
+	<reg32 offset="0x000dc" name="TIMING_CTRL_10"/>
+	<reg32 offset="0x000e0" name="TIMING_CTRL_11"/>
+	<reg32 offset="0x000e4" name="TIMING_CTRL_12"/>
+	<reg32 offset="0x000e8" name="TIMING_CTRL_13"/>
+	<reg32 offset="0x000ec" name="GLBL_HSTX_STR_CTRL_0"/>
+	<reg32 offset="0x000f0" name="GLBL_HSTX_STR_CTRL_1"/>
+	<reg32 offset="0x000f4" name="GLBL_RESCODE_OFFSET_TOP_CTRL"/>
+	<reg32 offset="0x000f8" name="GLBL_RESCODE_OFFSET_BOT_CTRL"/>
+	<reg32 offset="0x000fc" name="GLBL_RESCODE_OFFSET_MID_CTRL"/>
+	<reg32 offset="0x00100" name="GLBL_LPTX_STR_CTRL"/>
+	<reg32 offset="0x00104" name="GLBL_PEMPH_CTRL_0"/>
+	<reg32 offset="0x00108" name="GLBL_PEMPH_CTRL_1"/>
+	<reg32 offset="0x0010c" name="GLBL_STR_SWI_CAL_SEL_CTRL"/>
+	<reg32 offset="0x00110" name="VREG_CTRL_1"/>
+	<reg32 offset="0x00114" name="CTRL_4"/>
+	<reg32 offset="0x00128" name="GLBL_DIGTOP_SPARE4"/>
+	<reg32 offset="0x00140" name="PHY_STATUS"/>
+	<reg32 offset="0x00148" name="LANE_STATUS0"/>
+	<reg32 offset="0x0014c" name="LANE_STATUS1"/>
+	<reg32 offset="0x001ac" name="GLBL_DIGTOP_SPARE10"/>
+</domain>
+
+<domain name="DSI_7nm_PHY" width="32">
+	<array offset="0x00000" name="LN" length="5" stride="0x80">
+		<reg32 offset="0x00" name="CFG0"/>
+		<reg32 offset="0x04" name="CFG1"/>
+		<reg32 offset="0x08" name="CFG2"/>
+		<reg32 offset="0x0c" name="TEST_DATAPATH"/>
+		<reg32 offset="0x10" name="PIN_SWAP"/>
+		<reg32 offset="0x14" name="LPRX_CTRL"/>
+		<reg32 offset="0x18" name="TX_DCTRL"/>
+	</array>
+</domain>
+
+<domain name="DSI_7nm_PHY_PLL" width="32">
+	<reg32 offset="0x0000" name="ANALOG_CONTROLS_ONE"/>
+	<reg32 offset="0x0004" name="ANALOG_CONTROLS_TWO"/>
+	<reg32 offset="0x0008" name="INT_LOOP_SETTINGS"/>
+	<reg32 offset="0x000c" name="INT_LOOP_SETTINGS_TWO"/>
+	<reg32 offset="0x0010" name="ANALOG_CONTROLS_THREE"/>
+	<reg32 offset="0x0014" name="ANALOG_CONTROLS_FOUR"/>
+	<reg32 offset="0x0018" name="ANALOG_CONTROLS_FIVE"/>
+	<reg32 offset="0x001c" name="INT_LOOP_CONTROLS"/>
+	<reg32 offset="0x0020" name="DSM_DIVIDER"/>
+	<reg32 offset="0x0024" name="FEEDBACK_DIVIDER"/>
+	<reg32 offset="0x0028" name="SYSTEM_MUXES"/>
+	<reg32 offset="0x002c" name="FREQ_UPDATE_CONTROL_OVERRIDES"/>
+	<reg32 offset="0x0030" name="CMODE"/>
+	<reg32 offset="0x0034" name="PSM_CTRL"/>
+	<reg32 offset="0x0038" name="RSM_CTRL"/>
+	<reg32 offset="0x003c" name="VCO_TUNE_MAP"/>
+	<reg32 offset="0x0040" name="PLL_CNTRL"/>
+	<reg32 offset="0x0044" name="CALIBRATION_SETTINGS"/>
+	<reg32 offset="0x0048" name="BAND_SEL_CAL_TIMER_LOW"/>
+	<reg32 offset="0x004c" name="BAND_SEL_CAL_TIMER_HIGH"/>
+	<reg32 offset="0x0050" name="BAND_SEL_CAL_SETTINGS"/>
+	<reg32 offset="0x0054" name="BAND_SEL_MIN"/>
+	<reg32 offset="0x0058" name="BAND_SEL_MAX"/>
+	<reg32 offset="0x005c" name="BAND_SEL_PFILT"/>
+	<reg32 offset="0x0060" name="BAND_SEL_IFILT"/>
+	<reg32 offset="0x0064" name="BAND_SEL_CAL_SETTINGS_TWO"/>
+	<reg32 offset="0x0068" name="BAND_SEL_CAL_SETTINGS_THREE"/>
+	<reg32 offset="0x006c" name="BAND_SEL_CAL_SETTINGS_FOUR"/>
+	<reg32 offset="0x0070" name="BAND_SEL_ICODE_HIGH"/>
+	<reg32 offset="0x0074" name="BAND_SEL_ICODE_LOW"/>
+	<reg32 offset="0x0078" name="FREQ_DETECT_SETTINGS_ONE"/>
+	<reg32 offset="0x007c" name="FREQ_DETECT_THRESH"/>
+	<reg32 offset="0x0080" name="FREQ_DET_REFCLK_HIGH"/>
+	<reg32 offset="0x0084" name="FREQ_DET_REFCLK_LOW"/>
+	<reg32 offset="0x0088" name="FREQ_DET_PLLCLK_HIGH"/>
+	<reg32 offset="0x008c" name="FREQ_DET_PLLCLK_LOW"/>
+	<reg32 offset="0x0090" name="PFILT"/>
+	<reg32 offset="0x0094" name="IFILT"/>
+	<reg32 offset="0x0098" name="PLL_GAIN"/>
+	<reg32 offset="0x009c" name="ICODE_LOW"/>
+	<reg32 offset="0x00a0" name="ICODE_HIGH"/>
+	<reg32 offset="0x00a4" name="LOCKDET"/>
+	<reg32 offset="0x00a8" name="OUTDIV"/>
+	<reg32 offset="0x00ac" name="FASTLOCK_CONTROL"/>
+	<reg32 offset="0x00b0" name="PASS_OUT_OVERRIDE_ONE"/>
+	<reg32 offset="0x00b4" name="PASS_OUT_OVERRIDE_TWO"/>
+	<reg32 offset="0x00b8" name="CORE_OVERRIDE"/>
+	<reg32 offset="0x00bc" name="CORE_INPUT_OVERRIDE"/>
+	<reg32 offset="0x00c0" name="RATE_CHANGE"/>
+	<reg32 offset="0x00c4" name="PLL_DIGITAL_TIMERS"/>
+	<reg32 offset="0x00c8" name="PLL_DIGITAL_TIMERS_TWO"/>
+	<reg32 offset="0x00cc" name="DECIMAL_DIV_START"/>
+	<reg32 offset="0x00d0" name="FRAC_DIV_START_LOW"/>
+	<reg32 offset="0x00d4" name="FRAC_DIV_START_MID"/>
+	<reg32 offset="0x00d8" name="FRAC_DIV_START_HIGH"/>
+	<reg32 offset="0x00dc" name="DEC_FRAC_MUXES"/>
+	<reg32 offset="0x00e0" name="DECIMAL_DIV_START_1"/>
+	<reg32 offset="0x00e4" name="FRAC_DIV_START_LOW_1"/>
+	<reg32 offset="0x00e8" name="FRAC_DIV_START_MID_1"/>
+	<reg32 offset="0x00ec" name="FRAC_DIV_START_HIGH_1"/>
+	<reg32 offset="0x00f0" name="DECIMAL_DIV_START_2"/>
+	<reg32 offset="0x00f4" name="FRAC_DIV_START_LOW_2"/>
+	<reg32 offset="0x00f8" name="FRAC_DIV_START_MID_2"/>
+	<reg32 offset="0x00fc" name="FRAC_DIV_START_HIGH_2"/>
+	<reg32 offset="0x0100" name="MASH_CONTROL"/>
+	<reg32 offset="0x0104" name="SSC_STEPSIZE_LOW"/>
+	<reg32 offset="0x0108" name="SSC_STEPSIZE_HIGH"/>
+	<reg32 offset="0x010c" name="SSC_DIV_PER_LOW"/>
+	<reg32 offset="0x0110" name="SSC_DIV_PER_HIGH"/>
+	<reg32 offset="0x0114" name="SSC_ADJPER_LOW"/>
+	<reg32 offset="0x0118" name="SSC_ADJPER_HIGH"/>
+	<reg32 offset="0x011c" name="SSC_MUX_CONTROL"/>
+	<reg32 offset="0x0120" name="SSC_STEPSIZE_LOW_1"/>
+	<reg32 offset="0x0124" name="SSC_STEPSIZE_HIGH_1"/>
+	<reg32 offset="0x0128" name="SSC_DIV_PER_LOW_1"/>
+	<reg32 offset="0x012c" name="SSC_DIV_PER_HIGH_1"/>
+	<reg32 offset="0x0130" name="SSC_ADJPER_LOW_1"/>
+	<reg32 offset="0x0134" name="SSC_ADJPER_HIGH_1"/>
+	<reg32 offset="0x0138" name="SSC_STEPSIZE_LOW_2"/>
+	<reg32 offset="0x013c" name="SSC_STEPSIZE_HIGH_2"/>
+	<reg32 offset="0x0140" name="SSC_DIV_PER_LOW_2"/>
+	<reg32 offset="0x0144" name="SSC_DIV_PER_HIGH_2"/>
+	<reg32 offset="0x0148" name="SSC_ADJPER_LOW_2"/>
+	<reg32 offset="0x014c" name="SSC_ADJPER_HIGH_2"/>
+	<reg32 offset="0x0150" name="SSC_CONTROL"/>
+	<reg32 offset="0x0154" name="PLL_OUTDIV_RATE"/>
+	<reg32 offset="0x0158" name="PLL_LOCKDET_RATE_1"/>
+	<reg32 offset="0x015c" name="PLL_LOCKDET_RATE_2"/>
+	<reg32 offset="0x0160" name="PLL_PROP_GAIN_RATE_1"/>
+	<reg32 offset="0x0164" name="PLL_PROP_GAIN_RATE_2"/>
+	<reg32 offset="0x0168" name="PLL_BAND_SEL_RATE_1"/>
+	<reg32 offset="0x016c" name="PLL_BAND_SEL_RATE_2"/>
+	<reg32 offset="0x0170" name="PLL_INT_GAIN_IFILT_BAND_1"/>
+	<reg32 offset="0x0174" name="PLL_INT_GAIN_IFILT_BAND_2"/>
+	<reg32 offset="0x0178" name="PLL_FL_INT_GAIN_PFILT_BAND_1"/>
+	<reg32 offset="0x017c" name="PLL_FL_INT_GAIN_PFILT_BAND_2"/>
+	<reg32 offset="0x0180" name="PLL_FASTLOCK_EN_BAND"/>
+	<reg32 offset="0x0184" name="FREQ_TUNE_ACCUM_INIT_MID"/>
+	<reg32 offset="0x0188" name="FREQ_TUNE_ACCUM_INIT_HIGH"/>
+	<reg32 offset="0x018c" name="FREQ_TUNE_ACCUM_INIT_MUX"/>
+	<reg32 offset="0x0190" name="PLL_LOCK_OVERRIDE"/>
+	<reg32 offset="0x0194" name="PLL_LOCK_DELAY"/>
+	<reg32 offset="0x0198" name="PLL_LOCK_MIN_DELAY"/>
+	<reg32 offset="0x019c" name="CLOCK_INVERTERS"/>
+	<reg32 offset="0x01a0" name="SPARE_AND_JPC_OVERRIDES"/>
+	<reg32 offset="0x01a4" name="BIAS_CONTROL_1"/>
+	<reg32 offset="0x01a8" name="BIAS_CONTROL_2"/>
+	<reg32 offset="0x01ac" name="ALOG_OBSV_BUS_CTRL_1"/>
+	<reg32 offset="0x01b0" name="COMMON_STATUS_ONE"/>
+	<reg32 offset="0x01b4" name="COMMON_STATUS_TWO"/>
+	<reg32 offset="0x01b8" name="BAND_SEL_CAL"/>
+	<reg32 offset="0x01bc" name="ICODE_ACCUM_STATUS_LOW"/>
+	<reg32 offset="0x01c0" name="ICODE_ACCUM_STATUS_HIGH"/>
+	<reg32 offset="0x01c4" name="FD_OUT_LOW"/>
+	<reg32 offset="0x01c8" name="FD_OUT_HIGH"/>
+	<reg32 offset="0x01cc" name="ALOG_OBSV_BUS_STATUS_1"/>
+	<reg32 offset="0x01d0" name="PLL_MISC_CONFIG"/>
+	<reg32 offset="0x01d4" name="FLL_CONFIG"/>
+	<reg32 offset="0x01d8" name="FLL_FREQ_ACQ_TIME"/>
+	<reg32 offset="0x01dc" name="FLL_CODE0"/>
+	<reg32 offset="0x01e0" name="FLL_CODE1"/>
+	<reg32 offset="0x01e4" name="FLL_GAIN0"/>
+	<reg32 offset="0x01e8" name="FLL_GAIN1"/>
+	<reg32 offset="0x01ec" name="SW_RESET"/>
+	<reg32 offset="0x01f0" name="FAST_PWRUP"/>
+	<reg32 offset="0x01f4" name="LOCKTIME0"/>
+	<reg32 offset="0x01f8" name="LOCKTIME1"/>
+	<reg32 offset="0x01fc" name="DEBUG_BUS_SEL"/>
+	<reg32 offset="0x0200" name="DEBUG_BUS0"/>
+	<reg32 offset="0x0204" name="DEBUG_BUS1"/>
+	<reg32 offset="0x0208" name="DEBUG_BUS2"/>
+	<reg32 offset="0x020c" name="DEBUG_BUS3"/>
+	<reg32 offset="0x0210" name="ANALOG_FLL_CONTROL_OVERRIDES"/>
+	<reg32 offset="0x0214" name="VCO_CONFIG"/>
+	<reg32 offset="0x0218" name="VCO_CAL_CODE1_MODE0_STATUS"/>
+	<reg32 offset="0x021c" name="VCO_CAL_CODE1_MODE1_STATUS"/>
+	<reg32 offset="0x0220" name="RESET_SM_STATUS"/>
+	<reg32 offset="0x0224" name="TDC_OFFSET"/>
+	<reg32 offset="0x0228" name="PS3_PWRDOWN_CONTROLS"/>
+	<reg32 offset="0x022c" name="PS4_PWRDOWN_CONTROLS"/>
+	<reg32 offset="0x0230" name="PLL_RST_CONTROLS"/>
+	<reg32 offset="0x0234" name="GEAR_BAND_SELECT_CONTROLS"/>
+	<reg32 offset="0x0238" name="PSM_CLK_CONTROLS"/>
+	<reg32 offset="0x023c" name="SYSTEM_MUXES_2"/>
+	<reg32 offset="0x0240" name="VCO_CONFIG_1"/>
+	<reg32 offset="0x0244" name="VCO_CONFIG_2"/>
+	<reg32 offset="0x0248" name="CLOCK_INVERTERS_1"/>
+	<reg32 offset="0x024c" name="CLOCK_INVERTERS_2"/>
+	<reg32 offset="0x0250" name="CMODE_1"/>
+	<reg32 offset="0x0254" name="CMODE_2"/>
+	<reg32 offset="0x0258" name="ANALOG_CONTROLS_FIVE_1"/>
+	<reg32 offset="0x025c" name="ANALOG_CONTROLS_FIVE_2"/>
+	<reg32 offset="0x0260" name="PERF_OPTIMIZE"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/edp.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/edp.xml
@@ -0,0 +1,239 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="EDP" width="32">
+	<enum name="edp_color_depth">
+		<value name="EDP_6BIT"  value="0"/>
+		<value name="EDP_8BIT"  value="1"/>
+		<value name="EDP_10BIT" value="2"/>
+		<value name="EDP_12BIT" value="3"/>
+		<value name="EDP_16BIT" value="4"/>
+	</enum>
+
+	<enum name="edp_component_format">
+		<value name="EDP_RGB" value="0"/>
+		<value name="EDP_YUV422" value="1"/>
+		<value name="EDP_YUV444" value="2"/>
+	</enum>
+
+	<reg32 offset="0x0004" name="MAINLINK_CTRL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="RESET"  pos="1" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0008" name="STATE_CTRL">
+		<bitfield name="TRAIN_PATTERN_1"       pos="0" type="boolean"/>
+		<bitfield name="TRAIN_PATTERN_2"       pos="1" type="boolean"/>
+		<bitfield name="TRAIN_PATTERN_3"       pos="2" type="boolean"/>
+		<bitfield name="SYMBOL_ERR_RATE_MEAS"  pos="3" type="boolean"/>
+		<bitfield name="PRBS7"                 pos="4" type="boolean"/>
+		<bitfield name="CUSTOM_80_BIT_PATTERN" pos="5" type="boolean"/>
+		<bitfield name="SEND_VIDEO"            pos="6" type="boolean"/>
+		<bitfield name="PUSH_IDLE"             pos="7" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x000c" name="CONFIGURATION_CTRL">
+		<!-- next two may be swapped? -->
+		<bitfield name="SYNC_CLK" pos="0" type="boolean"/>
+		<bitfield name="STATIC_MVID" pos="1" type="boolean"/>
+		<bitfield name="PROGRESSIVE" pos="2" type="boolean"/>
+		<!-- # of lanes minus one: -->
+		<bitfield name="LANES" low="4" high="5" type="uint"/>
+		<bitfield name="ENHANCED_FRAMING" pos="6" type="boolean"/>
+		<!--
+		   NOTE: only 6bit and 8bit valid
+		 -->
+		<bitfield name="COLOR" pos="8" type="edp_color_depth"/>
+	</reg32>
+
+	<reg32 offset="0x0014" name="SOFTWARE_MVID" type="uint"/>
+	<reg32 offset="0x0018" name="SOFTWARE_NVID" type="uint"/>
+
+	<reg32 offset="0x001c" name="TOTAL_HOR_VER">
+		<bitfield name="HORIZ" low="0" high="15" type="uint"/>
+		<bitfield name="VERT"  low="16" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x0020" name="START_HOR_VER_FROM_SYNC">
+		<bitfield name="HORIZ" low="0" high="15" type="uint"/>
+		<bitfield name="VERT"  low="16" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x0024" name="HSYNC_VSYNC_WIDTH_POLARITY">
+		<bitfield name="HORIZ"  low="0" high="14" type="uint"/>
+		<bitfield name="NHSYNC" pos="15" type="boolean"/>
+		<bitfield name="VERT"   low="16" high="30" type="uint"/>
+		<bitfield name="NVSYNC" pos="31" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0028" name="ACTIVE_HOR_VER">
+		<bitfield name="HORIZ" low="0" high="15" type="uint"/>
+		<bitfield name="VERT"  low="16" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x002c" name="MISC1_MISC0">
+		<!-- MISC0 from DisplayPort v1.2 spec: -->
+		<bitfield name="MISC0" low="0" high="7"/>
+		<!-- aliased MISC0 bitfields: -->
+		<bitfield name="SYNC" pos="0" type="boolean"/>
+		<bitfield name="COMPONENT_FORMAT" low="1" high="2" type="edp_component_format"/>
+		<!-- CEA (vs VESA) color range: -->
+		<bitfield name="CEA" pos="3" type="boolean"/>
+		<!-- YCbCr Colorimetry ITU-R BT709-5 (vs ITU-R BT601-5): -->
+		<bitfield name="BT709_5" pos="4" type="boolean"/>
+		<bitfield name="COLOR" low="5" high="7" type="edp_color_depth"/>
+
+		<!-- MISC1 from DisplayPort v1.2 spec: -->
+		<bitfield name="MISC1" low="8" high="15"/>
+		<!-- aliased MISC1 bitfields: -->
+		<bitfield name="INTERLACED_ODD" pos="8" type="boolean"/>
+		<bitfield name="STEREO" low="9" high="10" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x0074" name="PHY_CTRL">
+		<bitfield name="SW_RESET_PLL" pos="0" type="boolean"/>
+		<bitfield name="SW_RESET" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0084" name="MAINLINK_READY">
+		<bitfield name="TRAIN_PATTERN_1_READY" pos="3" type="boolean"/>
+		<bitfield name="TRAIN_PATTERN_2_READY" pos="4" type="boolean"/>
+		<bitfield name="TRAIN_PATTERN_3_READY" pos="5" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0300" name="AUX_CTRL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="RESET"  pos="1" type="boolean"/>
+	</reg32>
+
+	<!-- interrupt registers come in sets of 3 bits, status/ack/en -->
+	<reg32 offset="0x0308" name="INTERRUPT_REG_1">
+		<bitfield name="HPD"                    pos="0"  type="boolean"/>
+		<bitfield name="HPD_ACK"                pos="1"  type="boolean"/>
+		<bitfield name="HPD_EN"                 pos="2"  type="boolean"/>
+		<bitfield name="AUX_I2C_DONE"           pos="3"  type="boolean"/>
+		<bitfield name="AUX_I2C_DONE_ACK"       pos="4"  type="boolean"/>
+		<bitfield name="AUX_I2C_DONE_EN"        pos="5"  type="boolean"/>
+		<bitfield name="WRONG_ADDR"             pos="6"  type="boolean"/>
+		<bitfield name="WRONG_ADDR_ACK"         pos="7"  type="boolean"/>
+		<bitfield name="WRONG_ADDR_EN"          pos="8"  type="boolean"/>
+		<bitfield name="TIMEOUT"                pos="9"  type="boolean"/>
+		<bitfield name="TIMEOUT_ACK"            pos="10" type="boolean"/>
+		<bitfield name="TIMEOUT_EN"             pos="11" type="boolean"/>
+		<bitfield name="NACK_DEFER"             pos="12" type="boolean"/>
+		<bitfield name="NACK_DEFER_ACK"         pos="13" type="boolean"/>
+		<bitfield name="NACK_DEFER_EN"          pos="14" type="boolean"/>
+		<bitfield name="WRONG_DATA_CNT"         pos="15" type="boolean"/>
+		<bitfield name="WRONG_DATA_CNT_ACK"     pos="16" type="boolean"/>
+		<bitfield name="WRONG_DATA_CNT_EN"      pos="17" type="boolean"/>
+		<bitfield name="I2C_NACK"               pos="18" type="boolean"/>
+		<bitfield name="I2C_NACK_ACK"           pos="19" type="boolean"/>
+		<bitfield name="I2C_NACK_EN"            pos="20" type="boolean"/>
+		<bitfield name="I2C_DEFER"              pos="21" type="boolean"/>
+		<bitfield name="I2C_DEFER_ACK"          pos="22" type="boolean"/>
+		<bitfield name="I2C_DEFER_EN"           pos="23" type="boolean"/>
+		<bitfield name="PLL_UNLOCK"             pos="24" type="boolean"/>
+		<bitfield name="PLL_UNLOCK_ACK"         pos="25" type="boolean"/>
+		<bitfield name="PLL_UNLOCK_EN"          pos="26" type="boolean"/>
+		<bitfield name="AUX_ERROR"              pos="27" type="boolean"/>
+		<bitfield name="AUX_ERROR_ACK"          pos="28" type="boolean"/>
+		<bitfield name="AUX_ERROR_EN"           pos="29" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x030c" name="INTERRUPT_REG_2">
+		<bitfield name="READY_FOR_VIDEO"        pos="0"  type="boolean"/>
+		<bitfield name="READY_FOR_VIDEO_ACK"    pos="1"  type="boolean"/>
+		<bitfield name="READY_FOR_VIDEO_EN"     pos="2"  type="boolean"/>
+		<bitfield name="IDLE_PATTERNs_SENT"     pos="3"  type="boolean"/>
+		<bitfield name="IDLE_PATTERNs_SENT_ACK" pos="4"  type="boolean"/>
+		<bitfield name="IDLE_PATTERNs_SENT_EN"  pos="5"  type="boolean"/>
+		<bitfield name="FRAME_END"              pos="9"  type="boolean"/>
+		<bitfield name="FRAME_END_ACK"          pos="7"  type="boolean"/>
+		<bitfield name="FRAME_END_EN"           pos="8"  type="boolean"/>
+		<bitfield name="CRC_UPDATED"            pos="9"  type="boolean"/>
+		<bitfield name="CRC_UPDATED_ACK"        pos="10" type="boolean"/>
+		<bitfield name="CRC_UPDATED_EN"         pos="11" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0310" name="INTERRUPT_TRANS_NUM"/>
+	<reg32 offset="0x0314" name="AUX_DATA">
+		<bitfield name="READ" pos="0" type="boolean"/>
+		<bitfield name="DATA" low="8" high="15"/>
+		<bitfield name="INDEX" low="16" high="23"/>
+		<bitfield name="INDEX_WRITE" pos="31" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0318" name="AUX_TRANS_CTRL">
+		<bitfield name="I2C" pos="8" type="boolean"/>
+		<bitfield name="GO"  pos="9" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0324" name="AUX_STATUS"/>
+</domain>
+
+<domain name="EDP_PHY" width="32">
+	<array offset="0x0400" name="LN" length="4" stride="0x40">
+		<reg32 offset="0x04" name="PD_CTL"/>
+	</array>
+	<reg32 offset="0x0510" name="GLB_VM_CFG0"/>
+	<reg32 offset="0x0514" name="GLB_VM_CFG1"/>
+	<reg32 offset="0x0518" name="GLB_MISC9"/>
+	<reg32 offset="0x0528" name="GLB_CFG"/>
+	<reg32 offset="0x052c" name="GLB_PD_CTL"/>
+	<reg32 offset="0x0598" name="GLB_PHY_STATUS"/>
+</domain>
+
+<domain name="EDP_28nm_PHY_PLL" width="32">
+	<reg32 offset="0x00000" name="REFCLK_CFG"/>
+	<reg32 offset="0x00004" name="POSTDIV1_CFG"/>
+	<reg32 offset="0x00008" name="CHGPUMP_CFG"/>
+	<reg32 offset="0x0000C" name="VCOLPF_CFG"/>
+	<reg32 offset="0x00010" name="VREG_CFG"/>
+	<reg32 offset="0x00014" name="PWRGEN_CFG"/>
+	<reg32 offset="0x00018" name="DMUX_CFG"/>
+	<reg32 offset="0x0001C" name="AMUX_CFG"/>
+	<reg32 offset="0x00020" name="GLB_CFG">
+		<bitfield name="PLL_PWRDN_B" pos="0" type="boolean"/>
+		<bitfield name="PLL_LDO_PWRDN_B" pos="1" type="boolean"/>
+		<bitfield name="PLL_PWRGEN_PWRDN_B" pos="2" type="boolean"/>
+		<bitfield name="PLL_ENABLE" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00024" name="POSTDIV2_CFG"/>
+	<reg32 offset="0x00028" name="POSTDIV3_CFG"/>
+	<reg32 offset="0x0002C" name="LPFR_CFG"/>
+	<reg32 offset="0x00030" name="LPFC1_CFG"/>
+	<reg32 offset="0x00034" name="LPFC2_CFG"/>
+	<reg32 offset="0x00038" name="SDM_CFG0"/>
+	<reg32 offset="0x0003C" name="SDM_CFG1"/>
+	<reg32 offset="0x00040" name="SDM_CFG2"/>
+	<reg32 offset="0x00044" name="SDM_CFG3"/>
+	<reg32 offset="0x00048" name="SDM_CFG4"/>
+	<reg32 offset="0x0004C" name="SSC_CFG0"/>
+	<reg32 offset="0x00050" name="SSC_CFG1"/>
+	<reg32 offset="0x00054" name="SSC_CFG2"/>
+	<reg32 offset="0x00058" name="SSC_CFG3"/>
+	<reg32 offset="0x0005C" name="LKDET_CFG0"/>
+	<reg32 offset="0x00060" name="LKDET_CFG1"/>
+	<reg32 offset="0x00064" name="LKDET_CFG2"/>
+	<reg32 offset="0x00068" name="TEST_CFG">
+		<bitfield name="PLL_SW_RESET" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0006C" name="CAL_CFG0"/>
+	<reg32 offset="0x00070" name="CAL_CFG1"/>
+	<reg32 offset="0x00074" name="CAL_CFG2"/>
+	<reg32 offset="0x00078" name="CAL_CFG3"/>
+	<reg32 offset="0x0007C" name="CAL_CFG4"/>
+	<reg32 offset="0x00080" name="CAL_CFG5"/>
+	<reg32 offset="0x00084" name="CAL_CFG6"/>
+	<reg32 offset="0x00088" name="CAL_CFG7"/>
+	<reg32 offset="0x0008C" name="CAL_CFG8"/>
+	<reg32 offset="0x00090" name="CAL_CFG9"/>
+	<reg32 offset="0x00094" name="CAL_CFG10"/>
+	<reg32 offset="0x00098" name="CAL_CFG11"/>
+	<reg32 offset="0x0009C" name="EFUSE_CFG"/>
+	<reg32 offset="0x000A0" name="DEBUG_BUS_SEL"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/hdmi.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/hdmi.xml
@@ -0,0 +1,1104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<!--
+	NOTE: also see mdss_hdmi_util.h.. newer devices using MDSS appear
+	to have the same HDMI block (or maybe a newer version?) but for
+	some reason duplicate the code under drivers/video/msm/mdss
+ -->
+
+<domain name="HDMI" width="32">
+	<enum name="hdmi_hdcp_key_state">
+		<value name="HDCP_KEYS_STATE_NO_KEYS" value="0"/>
+		<value name="HDCP_KEYS_STATE_NOT_CHECKED" value="1"/>
+		<value name="HDCP_KEYS_STATE_CHECKING" value="2"/>
+		<value name="HDCP_KEYS_STATE_VALID" value="3"/>
+		<value name="HDCP_KEYS_STATE_AKSV_NOT_VALID" value="4"/>
+		<value name="HDCP_KEYS_STATE_CHKSUM_MISMATCH" value="5"/>
+		<value name="HDCP_KEYS_STATE_PROD_AKSV" value="6"/>
+		<value name="HDCP_KEYS_STATE_RESERVED" value="7"/>
+	</enum>
+	<enum name="hdmi_ddc_read_write">
+		<value name="DDC_WRITE" value="0"/>
+		<value name="DDC_READ" value="1"/>
+	</enum>
+	<enum name="hdmi_acr_cts">
+		<value name="ACR_NONE" value="0"/>
+		<value name="ACR_32" value="1"/>
+		<value name="ACR_44" value="2"/>
+		<value name="ACR_48" value="3"/>
+	</enum>
+
+	<enum name="hdmi_cec_tx_status">
+		<value name="CEC_TX_OK" value="0"/>
+		<value name="CEC_TX_NACK" value="1"/>
+		<value name="CEC_TX_ARB_LOSS" value="2"/>
+		<value name="CEC_TX_MAX_RETRIES" value="3"/>
+	</enum>
+
+	<reg32 offset="0x00000" name="CTRL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="HDMI" pos="1" type="boolean"/>
+		<bitfield name="ENCRYPTED" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00020" name="AUDIO_PKT_CTRL1">
+		<bitfield name="AUDIO_SAMPLE_SEND" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00024" name="ACR_PKT_CTRL">
+		<!--
+			Guessing on order of bitfields from these comments:
+				/* AUDIO_PRIORITY | SOURCE */
+				acr_pck_ctrl_reg |= 0x80000100;
+				/* N_MULTIPLE(multiplier) */
+				acr_pck_ctrl_reg |= (multiplier & 7) << 16;
+				/* SEND | CONT */
+				acr_pck_ctrl_reg |= 0x00000003;
+		 -->
+		<bitfield name="CONT" pos="0" type="boolean"/>
+		<bitfield name="SEND" pos="1" type="boolean"/>
+		<bitfield name="SELECT" low="4" high="5" type="hdmi_acr_cts"/>
+		<bitfield name="SOURCE" pos="8" type="boolean"/>
+		<bitfield name="N_MULTIPLIER" low="16" high="18" type="uint"/>
+		<bitfield name="AUDIO_PRIORITY" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0028" name="VBI_PKT_CTRL">
+		<!--
+			Guessing on the order of bits from:
+				/* GC packet enable (every frame) */
+				/* HDMI_VBI_PKT_CTRL[0x0028] */
+				hdmi_msm_rmw32or(0x0028, 3 << 4);
+				/* HDMI_VBI_PKT_CTRL[0x0028] */
+				/* ISRC Send + Continuous */
+				hdmi_msm_rmw32or(0x0028, 3 << 8);
+				/* HDMI_VBI_PKT_CTRL[0x0028] */
+				/* ACP send, s/w source */
+				hdmi_msm_rmw32or(0x0028, 3 << 12);
+		 -->
+		<bitfield name="GC_ENABLE" pos="4" type="boolean"/>
+		<bitfield name="GC_EVERY_FRAME" pos="5" type="boolean"/>
+		<bitfield name="ISRC_SEND" pos="8" type="boolean"/>
+		<bitfield name="ISRC_CONTINUOUS" pos="9" type="boolean"/>
+		<bitfield name="ACP_SEND" pos="12" type="boolean"/>
+		<bitfield name="ACP_SRC_SW" pos="13" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0002c" name="INFOFRAME_CTRL0">
+		<!--
+			Guessing on the order of these flags, from this comment:
+				/* Set these flags */
+				/* AUDIO_INFO_UPDATE | AUDIO_INFO_SOURCE | AUDIO_INFO_CONT
+				 | AUDIO_INFO_SEND */
+				audio_info_ctrl_reg |= 0x000000F0;
+				/* 0x3 for AVI InfFrame enable (every frame) */
+				HDMI_OUTP(0x002C, HDMI_INP(0x002C) | 0x00000003L);
+		 -->
+		<bitfield name="AVI_SEND" pos="0" type="boolean"/>
+		<bitfield name="AVI_CONT" pos="1" type="boolean"/>           <!-- every frame -->
+		<bitfield name="AUDIO_INFO_SEND" pos="4" type="boolean"/>
+		<bitfield name="AUDIO_INFO_CONT" pos="5" type="boolean"/>    <!-- every frame -->
+		<bitfield name="AUDIO_INFO_SOURCE" pos="6" type="boolean"/>
+		<bitfield name="AUDIO_INFO_UPDATE" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00030" name="INFOFRAME_CTRL1">
+		<bitfield name="AVI_INFO_LINE" low="0" high="5" type="uint"/>
+		<bitfield name="AUDIO_INFO_LINE" low="8" high="13" type="uint"/>
+		<bitfield name="MPEG_INFO_LINE" low="16" high="21" type="uint"/>
+		<bitfield name="VENSPEC_INFO_LINE" low="24" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00034" name="GEN_PKT_CTRL">
+		<!--
+			0x0034 GEN_PKT_CTRL
+			  GENERIC0_SEND   0      0 = Disable Generic0 Packet Transmission
+			                         1 = Enable Generic0 Packet Transmission
+			  GENERIC0_CONT   1      0 = Send Generic0 Packet on next frame only
+			                         1 = Send Generic0 Packet on every frame
+			  GENERIC0_UPDATE 2      NUM
+			  GENERIC1_SEND   4      0 = Disable Generic1 Packet Transmission
+			                         1 = Enable Generic1 Packet Transmission
+			  GENERIC1_CONT   5      0 = Send Generic1 Packet on next frame only
+			                         1 = Send Generic1 Packet on every frame
+			  GENERIC0_LINE   21:16  NUM
+			  GENERIC1_LINE   29:24  NUM
+			
+			GENERIC0_LINE | GENERIC0_UPDATE | GENERIC0_CONT | GENERIC0_SEND
+			Setup HDMI TX generic packet control
+			Enable this packet to transmit every frame
+			Enable this packet to transmit every frame
+			Enable HDMI TX engine to transmit Generic packet 0
+			  HDMI_OUTP(0x0034, (1 << 16) | (1 << 2) | BIT(1) | BIT(0));
+		 -->
+		<bitfield name="GENERIC0_SEND" pos="0" type="boolean"/>
+		<bitfield name="GENERIC0_CONT" pos="1" type="boolean"/>
+		<bitfield name="GENERIC0_UPDATE" low="2" high="3" type="uint"/> <!-- ??? -->
+		<bitfield name="GENERIC1_SEND" pos="4" type="boolean"/>
+		<bitfield name="GENERIC1_CONT" pos="5" type="boolean"/>
+		<bitfield name="GENERIC0_LINE" low="16" high="21" type="uint"/>
+		<bitfield name="GENERIC1_LINE" low="24" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00040" name="GC">
+		<bitfield name="MUTE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00044" name="AUDIO_PKT_CTRL2">
+		<bitfield name="OVERRIDE" pos="0" type="boolean"/>
+		<bitfield name="LAYOUT" pos="1" type="boolean"/> <!-- 1 for >2 channels -->
+	</reg32>
+
+	<!--
+		AVI_INFO appears to be the infoframe in a slightly weird order..
+		starts with PB0 (checksum), and ends with version..
+	-->
+	<reg32 offset="0x0006c" name="AVI_INFO" stride="4" length="4"/>
+
+	<reg32 offset="0x00084" name="GENERIC0_HDR"/>
+	<reg32 offset="0x00088" name="GENERIC0" stride="4" length="7"/>
+
+	<reg32 offset="0x000a4" name="GENERIC1_HDR"/>
+	<reg32 offset="0x000a8" name="GENERIC1" stride="4" length="7"/>
+
+	<!--
+		TODO add a way to show symbolic offsets into array: hdmi_acr_cts-1
+	 -->
+	<array offset="0x00c4" name="ACR" length="3" stride="8" index="hdmi_acr_cts">
+		<reg32 offset="0" name="0">
+			<bitfield name="CTS" low="12" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="4" name="1">
+			<!-- not sure the actual # of bits.. -->
+			<bitfield name="N" low="0" high="31" type="uint"/>
+		</reg32>
+	</array>
+
+	<reg32 offset="0x000e4" name="AUDIO_INFO0">
+		<bitfield name="CHECKSUM" low="0" high="7"/>
+		<bitfield name="CC" low="8" high="10" type="uint"/> <!-- channel count -->
+	</reg32>
+	<reg32 offset="0x000e8" name="AUDIO_INFO1">
+		<bitfield name="CA" low="0" high="7"/>        <!-- Channel Allocation -->
+		<bitfield name="LSV" low="11" high="14"/>     <!-- Level Shift -->
+		<bitfield name="DM_INH" pos="15" type="boolean"/>  <!-- down-mix inhibit flag -->
+	</reg32>
+	<reg32 offset="0x00110" name="HDCP_CTRL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="ENCRYPTION_ENABLE" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00114" name="HDCP_DEBUG_CTRL">
+		<bitfield name="RNG_CIPHER" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00118" name="HDCP_INT_CTRL">
+		<bitfield name="AUTH_SUCCESS_INT" pos="0" type="boolean"/>
+		<bitfield name="AUTH_SUCCESS_ACK" pos="1" type="boolean"/>
+		<bitfield name="AUTH_SUCCESS_MASK" pos="2" type="boolean"/>
+		<bitfield name="AUTH_FAIL_INT" pos="4" type="boolean"/>
+		<bitfield name="AUTH_FAIL_ACK" pos="5" type="boolean"/>
+		<bitfield name="AUTH_FAIL_MASK" pos="6" type="boolean"/>
+		<bitfield name="AUTH_FAIL_INFO_ACK" pos="7" type="boolean"/>
+		<bitfield name="AUTH_XFER_REQ_INT" pos="8" type="boolean"/>
+		<bitfield name="AUTH_XFER_REQ_ACK" pos="9" type="boolean"/>
+		<bitfield name="AUTH_XFER_REQ_MASK" pos="10" type="boolean"/>
+		<bitfield name="AUTH_XFER_DONE_INT" pos="12" type="boolean"/>
+		<bitfield name="AUTH_XFER_DONE_ACK" pos="13" type="boolean"/>
+		<bitfield name="AUTH_XFER_DONE_MASK" pos="14" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0011c" name="HDCP_LINK0_STATUS">
+		<bitfield name="AN_0_READY" pos="8" type="boolean"/>
+		<bitfield name="AN_1_READY" pos="9" type="boolean"/>
+		<bitfield name="RI_MATCHES" pos="12" type="boolean"/>
+		<bitfield name="V_MATCHES" pos="20" type="boolean"/>
+		<bitfield name="KEY_STATE" low="28" high="30" type="hdmi_hdcp_key_state"/>
+	</reg32>
+	<reg32 offset="0x00120" name="HDCP_DDC_CTRL_0">
+		<bitfield name="DISABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00124" name="HDCP_DDC_CTRL_1">
+		<bitfield name="FAILED_ACK" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00128" name="HDCP_DDC_STATUS">
+		<bitfield name="XFER_REQ" pos="4" type="boolean"/>
+		<bitfield name="XFER_DONE" pos="10" type="boolean"/>
+		<bitfield name="ABORTED" pos="12" type="boolean"/>
+		<bitfield name="TIMEOUT" pos="13" type="boolean"/>
+		<bitfield name="NACK0" pos="14" type="boolean"/>
+		<bitfield name="NACK1" pos="15" type="boolean"/>
+		<bitfield name="FAILED" pos="16" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0012c" name="HDCP_ENTROPY_CTRL0"/>
+	<reg32 offset="0x0025c" name="HDCP_ENTROPY_CTRL1"/>
+
+	<reg32 offset="0x00130" name="HDCP_RESET">
+		<bitfield name="LINK0_DEAUTHENTICATE" pos="0" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x00134" name="HDCP_RCVPORT_DATA0"/>
+	<reg32 offset="0x00138" name="HDCP_RCVPORT_DATA1"/>
+	<reg32 offset="0x0013C" name="HDCP_RCVPORT_DATA2_0"/>
+	<reg32 offset="0x00140" name="HDCP_RCVPORT_DATA2_1"/>
+	<reg32 offset="0x00144" name="HDCP_RCVPORT_DATA3"/>
+	<reg32 offset="0x00148" name="HDCP_RCVPORT_DATA4"/>
+	<reg32 offset="0x0014c" name="HDCP_RCVPORT_DATA5"/>
+	<reg32 offset="0x00150" name="HDCP_RCVPORT_DATA6"/>
+	<reg32 offset="0x00154" name="HDCP_RCVPORT_DATA7"/>
+	<reg32 offset="0x00158" name="HDCP_RCVPORT_DATA8"/>
+	<reg32 offset="0x0015c" name="HDCP_RCVPORT_DATA9"/>
+	<reg32 offset="0x00160" name="HDCP_RCVPORT_DATA10"/>
+	<reg32 offset="0x00164" name="HDCP_RCVPORT_DATA11"/>
+	<reg32 offset="0x00168" name="HDCP_RCVPORT_DATA12"/>
+
+	<reg32 offset="0x0016c" name="VENSPEC_INFO0"/>
+	<reg32 offset="0x00170" name="VENSPEC_INFO1"/>
+	<reg32 offset="0x00174" name="VENSPEC_INFO2"/>
+	<reg32 offset="0x00178" name="VENSPEC_INFO3"/>
+	<reg32 offset="0x0017c" name="VENSPEC_INFO4"/>
+	<reg32 offset="0x00180" name="VENSPEC_INFO5"/>
+	<reg32 offset="0x00184" name="VENSPEC_INFO6"/>
+
+	<reg32 offset="0x001d0" name="AUDIO_CFG">
+		<bitfield name="ENGINE_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="FIFO_WATERMARK" low="4" high="7" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00208" name="USEC_REFTIMER"/>
+	<reg32 offset="0x0020c" name="DDC_CTRL">
+		<!--
+			 0x020C HDMI_DDC_CTRL
+			[21:20] TRANSACTION_CNT
+				Number of transactions to be done in current transfer.
+				* 0x0: transaction0 only
+				* 0x1: transaction0, transaction1
+				* 0x2: transaction0, transaction1, transaction2
+				* 0x3: transaction0, transaction1, transaction2, transaction3
+			[3] SW_STATUS_RESET
+				Write 1 to reset HDMI_DDC_SW_STATUS flags, will reset SW_DONE,
+				ABORTED, TIMEOUT, SW_INTERRUPTED, BUFFER_OVERFLOW,
+				STOPPED_ON_NACK, NACK0, NACK1, NACK2, NACK3
+			[2] SEND_RESET Set to 1 to send reset sequence (9 clocks with no
+				data) at start of transfer.  This sequence is sent after GO is
+				written to 1, before the first transaction only.
+			[1] SOFT_RESET Write 1 to reset DDC controller
+			[0] GO WRITE ONLY. Write 1 to start DDC transfer.
+		 -->
+		<bitfield name="GO" pos="0" type="boolean"/>
+		<bitfield name="SOFT_RESET" pos="1" type="boolean"/>
+		<bitfield name="SEND_RESET" pos="2" type="boolean"/>
+		<bitfield name="SW_STATUS_RESET" pos="3" type="boolean"/>
+		<bitfield name="TRANSACTION_CNT" low="20" high="21" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00210" name="DDC_ARBITRATION">
+		<bitfield name="HW_ARBITRATION" pos="4" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00214" name="DDC_INT_CTRL">
+		<!--
+			HDMI_DDC_INT_CTRL[0x0214]
+			   [2] SW_DONE_MK Mask bit for SW_DONE_INT. Set to 1 to enable
+			       interrupt.
+			   [1] SW_DONE_ACK WRITE ONLY. Acknowledge bit for SW_DONE_INT.
+			       Write 1 to clear interrupt.
+			   [0] SW_DONE_INT READ ONLY. SW_DONE interrupt status */
+		 -->
+		<bitfield name="SW_DONE_INT" pos="0" type="boolean"/>
+		<bitfield name="SW_DONE_ACK" pos="1" type="boolean"/>
+		<bitfield name="SW_DONE_MASK" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00218" name="DDC_SW_STATUS">
+		<bitfield name="NACK0" pos="12" type="boolean"/>
+		<bitfield name="NACK1" pos="13" type="boolean"/>
+		<bitfield name="NACK2" pos="14" type="boolean"/>
+		<bitfield name="NACK3" pos="15" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0021c" name="DDC_HW_STATUS">
+		<bitfield name="DONE" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00220" name="DDC_SPEED">
+		<!--
+		   0x0220 HDMI_DDC_SPEED
+		   [31:16] PRESCALE prescale = (m * xtal_frequency) /
+			(desired_i2c_speed), where m is multiply
+			factor, default: m = 1
+		   [1:0]   THRESHOLD Select threshold to use to determine whether value
+			sampled on SDA is a 1 or 0. Specified in terms of the ratio
+			between the number of sampled ones and the total number of times
+			SDA is sampled.
+			* 0x0: >0
+			* 0x1: 1/4 of total samples
+			* 0x2: 1/2 of total samples
+			* 0x3: 3/4 of total samples */
+		 -->
+		<bitfield name="THRESHOLD" low="0" high="1" type="uint"/>
+		<bitfield name="PRESCALE" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00224" name="DDC_SETUP">
+		<!--
+			 * 0x0224 HDMI_DDC_SETUP
+			 * Setting 31:24 bits : Time units to wait before timeout
+			 * when clock is being stalled by external sink device
+		 -->
+		<bitfield name="TIMEOUT" low="24" high="31" type="uint"/>
+	</reg32>
+	<!-- Guessing length is 4, as elsewhere the are references to trans0 thru trans3 -->
+	<array offset="0x00228" name="I2C_TRANSACTION" length="4" stride="4">
+		<reg32 offset="0" name="REG">
+			<!--
+				0x0228 HDMI_DDC_TRANS0
+				[23:16] CNT0 Byte count for first transaction (excluding the first
+					byte, which is usually the address).
+				[13] STOP0 Determines whether a stop bit will be sent after the first
+					transaction
+					* 0: NO STOP
+					* 1: STOP
+				[12] START0 Determines whether a start bit will be sent before the
+					first transaction
+					* 0: NO START
+					* 1: START
+				[8] STOP_ON_NACK0 Determines whether the current transfer will stop
+					if a NACK is received during the first transaction (current
+					transaction always stops).
+					* 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
+					* 1: STOP ALL TRANSACTIONS, SEND STOP BIT
+				[0] RW0 Read/write indicator for first transaction - set to 0 for
+					write, 1 for read. This bit only controls HDMI_DDC behaviour -
+					the R/W bit in the transaction is programmed into the DDC buffer
+					as the LSB of the address byte.
+					* 0: WRITE
+					* 1: READ
+			 -->
+			<bitfield name="RW" pos="0" type="hdmi_ddc_read_write"/>
+			<bitfield name="STOP_ON_NACK" pos="8" type="boolean"/>
+			<bitfield name="START" pos="12" type="boolean"/>
+			<bitfield name="STOP" pos="13" type="boolean"/>
+			<bitfield name="CNT" low="16" high="23" type="uint"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x00238" name="DDC_DATA">
+		<!--
+			0x0238 HDMI_DDC_DATA
+			[31] INDEX_WRITE WRITE ONLY. To write index field, set this bit to
+				1 while writing HDMI_DDC_DATA.
+			[23:16] INDEX Use to set index into DDC buffer for next read or
+				current write, or to read index of current read or next write.
+				Writable only when INDEX_WRITE=1.
+			[15:8] DATA Use to fill or read the DDC buffer
+			[0] DATA_RW Select whether buffer access will be a read or write.
+				For writes, address auto-increments on write to HDMI_DDC_DATA.
+				For reads, address autoincrements on reads to HDMI_DDC_DATA.
+				* 0: Write
+				* 1: Read
+		 -->
+		<bitfield name="DATA_RW" pos="0" type="hdmi_ddc_read_write"/>
+		<bitfield name="DATA" low="8" high="15" type="uint"/>
+		<bitfield name="INDEX" low="16" high="23" type="uint"/>
+		<bitfield name="INDEX_WRITE" pos="31" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0023c" name="HDCP_SHA_CTRL"/>
+	<reg32 offset="0x00240" name="HDCP_SHA_STATUS">
+		<bitfield name="BLOCK_DONE" pos="0" type="boolean"/>
+		<bitfield name="COMP_DONE" pos="4" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00244" name="HDCP_SHA_DATA">
+		<bitfield name="DONE" pos="0" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x00250" name="HPD_INT_STATUS">
+		<bitfield name="INT" pos="0" type="boolean"/>  <!-- an irq has occurred -->
+		<bitfield name="CABLE_DETECTED" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00254" name="HPD_INT_CTRL">
+		<!-- (this useful comment was removed in df6b645.. git archaeology is fun)
+			HPD_INT_CTRL[0x0254]
+			31:10 Reserved
+			9     RCV_PLUGIN_DET_MASK  receiver plug in interrupt mask.
+			                           When programmed to 1,
+			                           RCV_PLUGIN_DET_INT will toggle
+			                           the interrupt line
+			8:6   Reserved
+			5     RX_INT_EN            Panel RX interrupt enable
+			      0: Disable
+			      1: Enable
+			4     RX_INT_ACK           WRITE ONLY. Panel RX interrupt
+			                           ack
+			3     Reserved
+			2     INT_EN               Panel interrupt control
+			      0: Disable
+			      1: Enable
+			1     INT_POLARITY         Panel interrupt polarity
+			      0: generate interrupt on disconnect
+			      1: generate interrupt on connect
+			0     INT_ACK              WRITE ONLY. Panel interrupt ack
+		 -->
+		<bitfield name="INT_ACK" pos="0" type="boolean"/>
+		<bitfield name="INT_CONNECT" pos="1" type="boolean"/>
+		<bitfield name="INT_EN" pos="2" type="boolean"/>
+		<bitfield name="RX_INT_ACK" pos="4" type="boolean"/>
+		<bitfield name="RX_INT_EN" pos="5" type="boolean"/>
+		<bitfield name="RCV_PLUGIN_DET_MASK" pos="9" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00258" name="HPD_CTRL">
+		<bitfield name="TIMEOUT" low="0" high="12" type="uint"/>
+		<bitfield name="ENABLE" pos="28" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0027c" name="DDC_REF">
+		<!--
+			0x027C HDMI_DDC_REF
+			[16] REFTIMER_ENABLE	Enable the timer
+				* 0: Disable
+				* 1: Enable
+			[15:0] REFTIMER	Value to set the register in order to generate
+				DDC strobe. This register counts on HDCP application clock
+
+			/* Enable reference timer
+			 * 27 micro-seconds */
+			HDMI_OUTP_ND(0x027C, (1 << 16) | (27 << 0));
+		 -->
+		<bitfield name="REFTIMER_ENABLE" pos="16" type="boolean"/>
+		<bitfield name="REFTIMER" low="0" high="15" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00284" name="HDCP_SW_UPPER_AKSV"/>
+	<reg32 offset="0x00288" name="HDCP_SW_LOWER_AKSV"/>
+
+	<reg32 offset="0x0028c" name="CEC_CTRL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="SEND_TRIGGER" pos="1" type="boolean"/>
+		<bitfield name="FRAME_SIZE" low="4" high="8" type="uint"/>
+		<bitfield name="LINE_OE" pos="9" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00290" name="CEC_WR_DATA">
+		<bitfield name="BROADCAST" pos="0" type="boolean"/>
+		<bitfield name="DATA" low="8" high="15" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00294" name="CEC_RETRANSMIT">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="COUNT" low="1" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00298" name="CEC_STATUS">
+		<bitfield name="BUSY" pos="0" type="boolean"/>
+		<bitfield name="TX_FRAME_DONE" pos="3" type="boolean"/>
+		<bitfield name="TX_STATUS" low="4" high="7" type="hdmi_cec_tx_status"/>
+	</reg32>
+	<reg32 offset="0x0029c" name="CEC_INT">
+		<bitfield name="TX_DONE" pos="0" type="boolean"/>
+		<bitfield name="TX_DONE_MASK" pos="1" type="boolean"/>
+		<bitfield name="TX_ERROR" pos="2" type="boolean"/>
+		<bitfield name="TX_ERROR_MASK" pos="3" type="boolean"/>
+		<bitfield name="MONITOR" pos="4" type="boolean"/>
+		<bitfield name="MONITOR_MASK" pos="5" type="boolean"/>
+		<bitfield name="RX_DONE" pos="6" type="boolean"/>
+		<bitfield name="RX_DONE_MASK" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x002a0" name="CEC_ADDR"/>
+	<reg32 offset="0x002a4" name="CEC_TIME">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="SIGNAL_FREE_TIME" low="7" high="15" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002a8" name="CEC_REFTIMER">
+		<bitfield name="REFTIMER" low="0" high="15" type="uint"/>
+		<bitfield name="ENABLE" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x002ac" name="CEC_RD_DATA">
+		<bitfield name="DATA" low="0" high="7" type="uint"/>
+		<bitfield name="SIZE" low="8" high="12" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002b0" name="CEC_RD_FILTER"/>
+
+	<reg32 offset="0x002b4" name="ACTIVE_HSYNC">
+		<bitfield name="START" low="0" high="12" type="uint"/>
+		<bitfield name="END" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002b8" name="ACTIVE_VSYNC">
+		<bitfield name="START" low="0" high="12" type="uint"/>
+		<bitfield name="END" low="16" high="28" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002bc" name="VSYNC_ACTIVE_F2">
+		<!-- interlaced, frame 2 -->
+		<bitfield name="START" low="0" high="12" type="uint"/>
+		<bitfield name="END" low="16" high="28" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002c0" name="TOTAL">
+		<bitfield name="H_TOTAL" low="0" high="12" type="uint"/>
+		<bitfield name="V_TOTAL" low="16" high="28" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002c4" name="VSYNC_TOTAL_F2">
+		<!-- interlaced, frame 2 -->
+		<bitfield name="V_TOTAL" low="0" high="12" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002c8" name="FRAME_CTRL">
+		<bitfield name="RGB_MUX_SEL_BGR" pos="12" type="boolean"/>
+		<bitfield name="VSYNC_LOW" pos="28" type="boolean"/>
+		<bitfield name="HSYNC_LOW" pos="29" type="boolean"/>
+		<bitfield name="INTERLACED_EN" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x002cc" name="AUD_INT">
+		<!--
+			HDMI_AUD_INT[0x02CC]
+			[3] AUD_SAM_DROP_MASK [R/W]
+			[2] AUD_SAM_DROP_ACK [W], AUD_SAM_DROP_INT [R]
+			[1] AUD_FIFO_URUN_MASK [R/W]
+			[0] AUD_FIFO_URUN_ACK [W], AUD_FIFO_URUN_INT [R]
+		 -->
+		<bitfield name="AUD_FIFO_URUN_INT" pos="0" type="boolean"/>  <!-- write to ack irq -->
+		<bitfield name="AUD_FIFO_URAN_MASK" pos="1" type="boolean"/> <!-- r/w, enables irq -->
+		<bitfield name="AUD_SAM_DROP_INT" pos="2" type="boolean"/>   <!-- write to ack irq -->
+		<bitfield name="AUD_SAM_DROP_MASK" pos="3" type="boolean"/>  <!-- r/w, enables irq -->
+	</reg32>
+	<reg32 offset="0x002d4" name="PHY_CTRL">
+		<!--
+			in hdmi_phy_reset() it appears to be toggling SW_RESET/
+			SW_RESET_PLL based on the value of the bit above, so
+			I'm guessing the bit above is a polarit bit
+		 -->
+		<bitfield name="SW_RESET_PLL" pos="0" type="boolean"/>
+		<bitfield name="SW_RESET_PLL_LOW" pos="1" type="boolean"/>
+		<bitfield name="SW_RESET" pos="2" type="boolean"/>
+		<bitfield name="SW_RESET_LOW" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x002dc" name="CEC_WR_RANGE"/>
+	<reg32 offset="0x002e0" name="CEC_RD_RANGE"/>
+	<reg32 offset="0x002e4" name="VERSION"/>
+	<reg32 offset="0x00360" name="CEC_COMPL_CTL"/>
+	<reg32 offset="0x00364" name="CEC_RD_START_RANGE"/>
+	<reg32 offset="0x00368" name="CEC_RD_TOTAL_RANGE"/>
+	<reg32 offset="0x0036c" name="CEC_RD_ERR_RESP_LO"/>
+	<reg32 offset="0x00370" name="CEC_WR_CHECK_CONFIG"/>
+
+</domain>
+
+<domain name="HDMI_8x60" width="32">
+	<reg32 offset="0x00000" name="PHY_REG0">
+		<bitfield name="DESER_DEL_CTRL" low="2" high="4" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00004" name="PHY_REG1">
+		<bitfield name="DTEST_MUX_SEL" low="4" high="7" type="uint"/>
+		<bitfield name="OUTVOL_SWING_CTRL" low="0" high="3" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00008" name="PHY_REG2">
+		<bitfield name="PD_DESER" pos="0" type="boolean"/>
+		<bitfield name="PD_DRIVE_1" pos="1" type="boolean"/>
+		<bitfield name="PD_DRIVE_2" pos="2" type="boolean"/>
+		<bitfield name="PD_DRIVE_3" pos="3" type="boolean"/>
+		<bitfield name="PD_DRIVE_4" pos="4" type="boolean"/>
+		<bitfield name="PD_PLL" pos="5" type="boolean"/>
+		<bitfield name="PD_PWRGEN" pos="6" type="boolean"/>
+		<bitfield name="RCV_SENSE_EN" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0000c" name="PHY_REG3">
+		<bitfield name="PLL_ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00010" name="PHY_REG4"/>
+	<reg32 offset="0x00014" name="PHY_REG5"/>
+	<reg32 offset="0x00018" name="PHY_REG6"/>
+	<reg32 offset="0x0001c" name="PHY_REG7"/>
+	<reg32 offset="0x00020" name="PHY_REG8"/>
+	<reg32 offset="0x00024" name="PHY_REG9"/>
+	<reg32 offset="0x00028" name="PHY_REG10"/>
+	<reg32 offset="0x0002c" name="PHY_REG11"/>
+	<reg32 offset="0x00030" name="PHY_REG12">
+		<bitfield name="RETIMING_EN" pos="0" type="boolean"/>
+		<bitfield name="PLL_LOCK_DETECT_EN" pos="1" type="boolean"/>
+		<bitfield name="FORCE_LOCK" pos="4" type="boolean"/>
+	</reg32>
+</domain>
+
+<domain name="HDMI_8960" width="32">
+	<!--
+		some of the bitfields may be same as 8x60.. but no helpful comments
+		in msm_dss_io_8960.c
+	 -->
+	<reg32 offset="0x00000" name="PHY_REG0"/>
+	<reg32 offset="0x00004" name="PHY_REG1"/>
+	<reg32 offset="0x00008" name="PHY_REG2"/>
+	<reg32 offset="0x0000c" name="PHY_REG3"/>
+	<reg32 offset="0x00010" name="PHY_REG4"/>
+	<reg32 offset="0x00014" name="PHY_REG5"/>
+	<reg32 offset="0x00018" name="PHY_REG6"/>
+	<reg32 offset="0x0001c" name="PHY_REG7"/>
+	<reg32 offset="0x00020" name="PHY_REG8"/>
+	<reg32 offset="0x00024" name="PHY_REG9"/>
+	<reg32 offset="0x00028" name="PHY_REG10"/>
+	<reg32 offset="0x0002c" name="PHY_REG11"/>
+	<reg32 offset="0x00030" name="PHY_REG12">
+		<bitfield name="SW_RESET" pos="5" type="boolean"/>
+		<bitfield name="PWRDN_B" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00034" name="PHY_REG_BIST_CFG"/>
+	<reg32 offset="0x00038" name="PHY_DEBUG_BUS_SEL"/>
+	<reg32 offset="0x0003c" name="PHY_REG_MISC0"/>
+	<reg32 offset="0x00040" name="PHY_REG13"/>
+	<reg32 offset="0x00044" name="PHY_REG14"/>
+	<reg32 offset="0x00048" name="PHY_REG15"/>
+</domain>
+
+<domain name="HDMI_8960_PHY_PLL" width="32">
+	<reg32 offset="0x00000" name="REFCLK_CFG"/>
+	<reg32 offset="0x00004" name="CHRG_PUMP_CFG"/>
+	<reg32 offset="0x00008" name="LOOP_FLT_CFG0"/>
+	<reg32 offset="0x0000c" name="LOOP_FLT_CFG1"/>
+	<reg32 offset="0x00010" name="IDAC_ADJ_CFG"/>
+	<reg32 offset="0x00014" name="I_VI_KVCO_CFG"/>
+	<reg32 offset="0x00018" name="PWRDN_B">
+		<bitfield name="PD_PLL" pos="1" type="boolean"/>
+		<bitfield name="PLL_PWRDN_B" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0001c" name="SDM_CFG0"/>
+	<reg32 offset="0x00020" name="SDM_CFG1"/>
+	<reg32 offset="0x00024" name="SDM_CFG2"/>
+	<reg32 offset="0x00028" name="SDM_CFG3"/>
+	<reg32 offset="0x0002c" name="SDM_CFG4"/>
+	<reg32 offset="0x00030" name="SSC_CFG0"/>
+	<reg32 offset="0x00034" name="SSC_CFG1"/>
+	<reg32 offset="0x00038" name="SSC_CFG2"/>
+	<reg32 offset="0x0003c" name="SSC_CFG3"/>
+	<reg32 offset="0x00040" name="LOCKDET_CFG0"/>
+	<reg32 offset="0x00044" name="LOCKDET_CFG1"/>
+	<reg32 offset="0x00048" name="LOCKDET_CFG2"/>
+	<reg32 offset="0x0004c" name="VCOCAL_CFG0"/>
+	<reg32 offset="0x00050" name="VCOCAL_CFG1"/>
+	<reg32 offset="0x00054" name="VCOCAL_CFG2"/>
+	<reg32 offset="0x00058" name="VCOCAL_CFG3"/>
+	<reg32 offset="0x0005c" name="VCOCAL_CFG4"/>
+	<reg32 offset="0x00060" name="VCOCAL_CFG5"/>
+	<reg32 offset="0x00064" name="VCOCAL_CFG6"/>
+	<reg32 offset="0x00068" name="VCOCAL_CFG7"/>
+	<reg32 offset="0x0006c" name="DEBUG_SEL"/>
+	<reg32 offset="0x00070" name="MISC0"/>
+	<reg32 offset="0x00074" name="MISC1"/>
+	<reg32 offset="0x00078" name="MISC2"/>
+	<reg32 offset="0x0007c" name="MISC3"/>
+	<reg32 offset="0x00080" name="MISC4"/>
+	<reg32 offset="0x00084" name="MISC5"/>
+	<reg32 offset="0x00088" name="MISC6"/>
+	<reg32 offset="0x0008c" name="DEBUG_BUS0"/>
+	<reg32 offset="0x00090" name="DEBUG_BUS1"/>
+	<reg32 offset="0x00094" name="DEBUG_BUS2"/>
+	<reg32 offset="0x00098" name="STATUS0">
+		<bitfield name="PLL_LOCK" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0009c" name="STATUS1"/>
+</domain>
+
+<domain name="HDMI_8x74" width="32">
+	<!--
+		seems to be all mdp5+ have same?
+	 -->
+	<reg32 offset="0x00000" name="ANA_CFG0"/>
+	<reg32 offset="0x00004" name="ANA_CFG1"/>
+	<reg32 offset="0x00008" name="ANA_CFG2"/>
+	<reg32 offset="0x0000c" name="ANA_CFG3"/>
+	<reg32 offset="0x00010" name="PD_CTRL0"/>
+	<reg32 offset="0x00014" name="PD_CTRL1"/>
+	<reg32 offset="0x00018" name="GLB_CFG"/>
+	<reg32 offset="0x0001c" name="DCC_CFG0"/>
+	<reg32 offset="0x00020" name="DCC_CFG1"/>
+	<reg32 offset="0x00024" name="TXCAL_CFG0"/>
+	<reg32 offset="0x00028" name="TXCAL_CFG1"/>
+	<reg32 offset="0x0002c" name="TXCAL_CFG2"/>
+	<reg32 offset="0x00030" name="TXCAL_CFG3"/>
+	<reg32 offset="0x00034" name="BIST_CFG0"/>
+	<reg32 offset="0x0003c" name="BIST_PATN0"/>
+	<reg32 offset="0x00040" name="BIST_PATN1"/>
+	<reg32 offset="0x00044" name="BIST_PATN2"/>
+	<reg32 offset="0x00048" name="BIST_PATN3"/>
+	<reg32 offset="0x0005c" name="STATUS"/>
+</domain>
+
+<domain name="HDMI_28nm_PHY_PLL" width="32">
+	<reg32 offset="0x00000" name="REFCLK_CFG"/>
+	<reg32 offset="0x00004" name="POSTDIV1_CFG"/>
+	<reg32 offset="0x00008" name="CHGPUMP_CFG"/>
+	<reg32 offset="0x0000C" name="VCOLPF_CFG"/>
+	<reg32 offset="0x00010" name="VREG_CFG"/>
+	<reg32 offset="0x00014" name="PWRGEN_CFG"/>
+	<reg32 offset="0x00018" name="DMUX_CFG"/>
+	<reg32 offset="0x0001C" name="AMUX_CFG"/>
+	<reg32 offset="0x00020" name="GLB_CFG">
+		<bitfield name="PLL_PWRDN_B" pos="0" type="boolean"/>
+		<bitfield name="PLL_LDO_PWRDN_B" pos="1" type="boolean"/>
+		<bitfield name="PLL_PWRGEN_PWRDN_B" pos="2" type="boolean"/>
+		<bitfield name="PLL_ENABLE" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00024" name="POSTDIV2_CFG"/>
+	<reg32 offset="0x00028" name="POSTDIV3_CFG"/>
+	<reg32 offset="0x0002C" name="LPFR_CFG"/>
+	<reg32 offset="0x00030" name="LPFC1_CFG"/>
+	<reg32 offset="0x00034" name="LPFC2_CFG"/>
+	<reg32 offset="0x00038" name="SDM_CFG0"/>
+	<reg32 offset="0x0003C" name="SDM_CFG1"/>
+	<reg32 offset="0x00040" name="SDM_CFG2"/>
+	<reg32 offset="0x00044" name="SDM_CFG3"/>
+	<reg32 offset="0x00048" name="SDM_CFG4"/>
+	<reg32 offset="0x0004C" name="SSC_CFG0"/>
+	<reg32 offset="0x00050" name="SSC_CFG1"/>
+	<reg32 offset="0x00054" name="SSC_CFG2"/>
+	<reg32 offset="0x00058" name="SSC_CFG3"/>
+	<reg32 offset="0x0005C" name="LKDET_CFG0"/>
+	<reg32 offset="0x00060" name="LKDET_CFG1"/>
+	<reg32 offset="0x00064" name="LKDET_CFG2"/>
+	<reg32 offset="0x00068" name="TEST_CFG">
+		<bitfield name="PLL_SW_RESET" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0006C" name="CAL_CFG0"/>
+	<reg32 offset="0x00070" name="CAL_CFG1"/>
+	<reg32 offset="0x00074" name="CAL_CFG2"/>
+	<reg32 offset="0x00078" name="CAL_CFG3"/>
+	<reg32 offset="0x0007C" name="CAL_CFG4"/>
+	<reg32 offset="0x00080" name="CAL_CFG5"/>
+	<reg32 offset="0x00084" name="CAL_CFG6"/>
+	<reg32 offset="0x00088" name="CAL_CFG7"/>
+	<reg32 offset="0x0008C" name="CAL_CFG8"/>
+	<reg32 offset="0x00090" name="CAL_CFG9"/>
+	<reg32 offset="0x00094" name="CAL_CFG10"/>
+	<reg32 offset="0x00098" name="CAL_CFG11"/>
+	<reg32 offset="0x0009C" name="EFUSE_CFG"/>
+	<reg32 offset="0x000A0" name="DEBUG_BUS_SEL"/>
+	<reg32 offset="0x000C0" name="STATUS"/>
+</domain>
+
+<domain name="HDMI_8996_PHY" width="32">
+	<reg32 offset="0x00000" name="CFG"/>
+	<reg32 offset="0x00004" name="PD_CTL"/>
+	<reg32 offset="0x00008" name="MODE"/>
+	<reg32 offset="0x0000C" name="MISR_CLEAR"/>
+	<reg32 offset="0x00010" name="TX0_TX1_BIST_CFG0"/>
+	<reg32 offset="0x00014" name="TX0_TX1_BIST_CFG1"/>
+	<reg32 offset="0x00018" name="TX0_TX1_PRBS_SEED_BYTE0"/>
+	<reg32 offset="0x0001C" name="TX0_TX1_PRBS_SEED_BYTE1"/>
+	<reg32 offset="0x00020" name="TX0_TX1_BIST_PATTERN0"/>
+	<reg32 offset="0x00024" name="TX0_TX1_BIST_PATTERN1"/>
+	<reg32 offset="0x00028" name="TX2_TX3_BIST_CFG0"/>
+	<reg32 offset="0x0002C" name="TX2_TX3_BIST_CFG1"/>
+	<reg32 offset="0x00030" name="TX2_TX3_PRBS_SEED_BYTE0"/>
+	<reg32 offset="0x00034" name="TX2_TX3_PRBS_SEED_BYTE1"/>
+	<reg32 offset="0x00038" name="TX2_TX3_BIST_PATTERN0"/>
+	<reg32 offset="0x0003C" name="TX2_TX3_BIST_PATTERN1"/>
+	<reg32 offset="0x00040" name="DEBUG_BUS_SEL"/>
+	<reg32 offset="0x00044" name="TXCAL_CFG0"/>
+	<reg32 offset="0x00048" name="TXCAL_CFG1"/>
+	<reg32 offset="0x0004C" name="TX0_TX1_LANE_CTL"/>
+	<reg32 offset="0x00050" name="TX2_TX3_LANE_CTL"/>
+	<reg32 offset="0x00054" name="LANE_BIST_CONFIG"/>
+	<reg32 offset="0x00058" name="CLOCK"/>
+	<reg32 offset="0x0005C" name="MISC1"/>
+	<reg32 offset="0x00060" name="MISC2"/>
+	<reg32 offset="0x00064" name="TX0_TX1_BIST_STATUS0"/>
+	<reg32 offset="0x00068" name="TX0_TX1_BIST_STATUS1"/>
+	<reg32 offset="0x0006C" name="TX0_TX1_BIST_STATUS2"/>
+	<reg32 offset="0x00070" name="TX2_TX3_BIST_STATUS0"/>
+	<reg32 offset="0x00074" name="TX2_TX3_BIST_STATUS1"/>
+	<reg32 offset="0x00078" name="TX2_TX3_BIST_STATUS2"/>
+	<reg32 offset="0x0007C" name="PRE_MISR_STATUS0"/>
+	<reg32 offset="0x00080" name="PRE_MISR_STATUS1"/>
+	<reg32 offset="0x00084" name="PRE_MISR_STATUS2"/>
+	<reg32 offset="0x00088" name="PRE_MISR_STATUS3"/>
+	<reg32 offset="0x0008C" name="POST_MISR_STATUS0"/>
+	<reg32 offset="0x00090" name="POST_MISR_STATUS1"/>
+	<reg32 offset="0x00094" name="POST_MISR_STATUS2"/>
+	<reg32 offset="0x00098" name="POST_MISR_STATUS3"/>
+	<reg32 offset="0x0009C" name="STATUS"/>
+	<reg32 offset="0x000A0" name="MISC3_STATUS"/>
+	<reg32 offset="0x000A4" name="MISC4_STATUS"/>
+	<reg32 offset="0x000A8" name="DEBUG_BUS0"/>
+	<reg32 offset="0x000AC" name="DEBUG_BUS1"/>
+	<reg32 offset="0x000B0" name="DEBUG_BUS2"/>
+	<reg32 offset="0x000B4" name="DEBUG_BUS3"/>
+	<reg32 offset="0x000B8" name="PHY_REVISION_ID0"/>
+	<reg32 offset="0x000BC" name="PHY_REVISION_ID1"/>
+	<reg32 offset="0x000C0" name="PHY_REVISION_ID2"/>
+	<reg32 offset="0x000C4" name="PHY_REVISION_ID3"/>
+</domain>
+
+<domain name="HDMI_PHY_QSERDES_COM" width="32">
+	<reg32 offset="0x00000" name="ATB_SEL1"/>
+	<reg32 offset="0x00004" name="ATB_SEL2"/>
+	<reg32 offset="0x00008" name="FREQ_UPDATE"/>
+	<reg32 offset="0x0000C" name="BG_TIMER"/>
+	<reg32 offset="0x00010" name="SSC_EN_CENTER"/>
+	<reg32 offset="0x00014" name="SSC_ADJ_PER1"/>
+	<reg32 offset="0x00018" name="SSC_ADJ_PER2"/>
+	<reg32 offset="0x0001C" name="SSC_PER1"/>
+	<reg32 offset="0x00020" name="SSC_PER2"/>
+	<reg32 offset="0x00024" name="SSC_STEP_SIZE1"/>
+	<reg32 offset="0x00028" name="SSC_STEP_SIZE2"/>
+	<reg32 offset="0x0002C" name="POST_DIV"/>
+	<reg32 offset="0x00030" name="POST_DIV_MUX"/>
+	<reg32 offset="0x00034" name="BIAS_EN_CLKBUFLR_EN"/>
+	<reg32 offset="0x00038" name="CLK_ENABLE1"/>
+	<reg32 offset="0x0003C" name="SYS_CLK_CTRL"/>
+	<reg32 offset="0x00040" name="SYSCLK_BUF_ENABLE"/>
+	<reg32 offset="0x00044" name="PLL_EN"/>
+	<reg32 offset="0x00048" name="PLL_IVCO"/>
+	<reg32 offset="0x0004C" name="LOCK_CMP1_MODE0"/>
+	<reg32 offset="0x00050" name="LOCK_CMP2_MODE0"/>
+	<reg32 offset="0x00054" name="LOCK_CMP3_MODE0"/>
+	<reg32 offset="0x00058" name="LOCK_CMP1_MODE1"/>
+	<reg32 offset="0x0005C" name="LOCK_CMP2_MODE1"/>
+	<reg32 offset="0x00060" name="LOCK_CMP3_MODE1"/>
+	<reg32 offset="0x00064" name="LOCK_CMP1_MODE2"/>
+	<reg32 offset="0x00064" name="CMN_RSVD0"/>
+	<reg32 offset="0x00068" name="LOCK_CMP2_MODE2"/>
+	<reg32 offset="0x00068" name="EP_CLOCK_DETECT_CTRL"/>
+	<reg32 offset="0x0006C" name="LOCK_CMP3_MODE2"/>
+	<reg32 offset="0x0006C" name="SYSCLK_DET_COMP_STATUS"/>
+	<reg32 offset="0x00070" name="BG_TRIM"/>
+	<reg32 offset="0x00074" name="CLK_EP_DIV"/>
+	<reg32 offset="0x00078" name="CP_CTRL_MODE0"/>
+	<reg32 offset="0x0007C" name="CP_CTRL_MODE1"/>
+	<reg32 offset="0x00080" name="CP_CTRL_MODE2"/>
+	<reg32 offset="0x00080" name="CMN_RSVD1"/>
+	<reg32 offset="0x00084" name="PLL_RCTRL_MODE0"/>
+	<reg32 offset="0x00088" name="PLL_RCTRL_MODE1"/>
+	<reg32 offset="0x0008C" name="PLL_RCTRL_MODE2"/>
+	<reg32 offset="0x0008C" name="CMN_RSVD2"/>
+	<reg32 offset="0x00090" name="PLL_CCTRL_MODE0"/>
+	<reg32 offset="0x00094" name="PLL_CCTRL_MODE1"/>
+	<reg32 offset="0x00098" name="PLL_CCTRL_MODE2"/>
+	<reg32 offset="0x00098" name="CMN_RSVD3"/>
+	<reg32 offset="0x0009C" name="PLL_CNTRL"/>
+	<reg32 offset="0x000A0" name="PHASE_SEL_CTRL"/>
+	<reg32 offset="0x000A4" name="PHASE_SEL_DC"/>
+	<reg32 offset="0x000A8" name="CORE_CLK_IN_SYNC_SEL"/>
+	<reg32 offset="0x000A8" name="BIAS_EN_CTRL_BY_PSM"/>
+	<reg32 offset="0x000AC" name="SYSCLK_EN_SEL"/>
+	<reg32 offset="0x000B0" name="CML_SYSCLK_SEL"/>
+	<reg32 offset="0x000B4" name="RESETSM_CNTRL"/>
+	<reg32 offset="0x000B8" name="RESETSM_CNTRL2"/>
+	<reg32 offset="0x000BC" name="RESTRIM_CTRL"/>
+	<reg32 offset="0x000C0" name="RESTRIM_CTRL2"/>
+	<reg32 offset="0x000C4" name="RESCODE_DIV_NUM"/>
+	<reg32 offset="0x000C8" name="LOCK_CMP_EN"/>
+	<reg32 offset="0x000CC" name="LOCK_CMP_CFG"/>
+	<reg32 offset="0x000D0" name="DEC_START_MODE0"/>
+	<reg32 offset="0x000D4" name="DEC_START_MODE1"/>
+	<reg32 offset="0x000D8" name="DEC_START_MODE2"/>
+	<reg32 offset="0x000D8" name="VCOCAL_DEADMAN_CTRL"/>
+	<reg32 offset="0x000DC" name="DIV_FRAC_START1_MODE0"/>
+	<reg32 offset="0x000E0" name="DIV_FRAC_START2_MODE0"/>
+	<reg32 offset="0x000E4" name="DIV_FRAC_START3_MODE0"/>
+	<reg32 offset="0x000E8" name="DIV_FRAC_START1_MODE1"/>
+	<reg32 offset="0x000EC" name="DIV_FRAC_START2_MODE1"/>
+	<reg32 offset="0x000F0" name="DIV_FRAC_START3_MODE1"/>
+	<reg32 offset="0x000F4" name="DIV_FRAC_START1_MODE2"/>
+	<reg32 offset="0x000F4" name="VCO_TUNE_MINVAL1"/>
+	<reg32 offset="0x000F8" name="DIV_FRAC_START2_MODE2"/>
+	<reg32 offset="0x000F8" name="VCO_TUNE_MINVAL2"/>
+	<reg32 offset="0x000FC" name="DIV_FRAC_START3_MODE2"/>
+	<reg32 offset="0x000FC" name="CMN_RSVD4"/>
+	<reg32 offset="0x00100" name="INTEGLOOP_INITVAL"/>
+	<reg32 offset="0x00104" name="INTEGLOOP_EN"/>
+	<reg32 offset="0x00108" name="INTEGLOOP_GAIN0_MODE0"/>
+	<reg32 offset="0x0010C" name="INTEGLOOP_GAIN1_MODE0"/>
+	<reg32 offset="0x00110" name="INTEGLOOP_GAIN0_MODE1"/>
+	<reg32 offset="0x00114" name="INTEGLOOP_GAIN1_MODE1"/>
+	<reg32 offset="0x00118" name="INTEGLOOP_GAIN0_MODE2"/>
+	<reg32 offset="0x00118" name="VCO_TUNE_MAXVAL1"/>
+	<reg32 offset="0x0011C" name="INTEGLOOP_GAIN1_MODE2"/>
+	<reg32 offset="0x0011C" name="VCO_TUNE_MAXVAL2"/>
+	<reg32 offset="0x00120" name="RES_TRIM_CONTROL2"/>
+	<reg32 offset="0x00124" name="VCO_TUNE_CTRL"/>
+	<reg32 offset="0x00128" name="VCO_TUNE_MAP"/>
+	<reg32 offset="0x0012C" name="VCO_TUNE1_MODE0"/>
+	<reg32 offset="0x00130" name="VCO_TUNE2_MODE0"/>
+	<reg32 offset="0x00134" name="VCO_TUNE1_MODE1"/>
+	<reg32 offset="0x00138" name="VCO_TUNE2_MODE1"/>
+	<reg32 offset="0x0013C" name="VCO_TUNE1_MODE2"/>
+	<reg32 offset="0x0013C" name="VCO_TUNE_INITVAL1"/>
+	<reg32 offset="0x00140" name="VCO_TUNE2_MODE2"/>
+	<reg32 offset="0x00140" name="VCO_TUNE_INITVAL2"/>
+	<reg32 offset="0x00144" name="VCO_TUNE_TIMER1"/>
+	<reg32 offset="0x00148" name="VCO_TUNE_TIMER2"/>
+	<reg32 offset="0x0014C" name="SAR"/>
+	<reg32 offset="0x00150" name="SAR_CLK"/>
+	<reg32 offset="0x00154" name="SAR_CODE_OUT_STATUS"/>
+	<reg32 offset="0x00158" name="SAR_CODE_READY_STATUS"/>
+	<reg32 offset="0x0015C" name="CMN_STATUS"/>
+	<reg32 offset="0x00160" name="RESET_SM_STATUS"/>
+	<reg32 offset="0x00164" name="RESTRIM_CODE_STATUS"/>
+	<reg32 offset="0x00168" name="PLLCAL_CODE1_STATUS"/>
+	<reg32 offset="0x0016C" name="PLLCAL_CODE2_STATUS"/>
+	<reg32 offset="0x00170" name="BG_CTRL"/>
+	<reg32 offset="0x00174" name="CLK_SELECT"/>
+	<reg32 offset="0x00178" name="HSCLK_SEL"/>
+	<reg32 offset="0x0017C" name="INTEGLOOP_BINCODE_STATUS"/>
+	<reg32 offset="0x00180" name="PLL_ANALOG"/>
+	<reg32 offset="0x00184" name="CORECLK_DIV"/>
+	<reg32 offset="0x00188" name="SW_RESET"/>
+	<reg32 offset="0x0018C" name="CORE_CLK_EN"/>
+	<reg32 offset="0x00190" name="C_READY_STATUS"/>
+	<reg32 offset="0x00194" name="CMN_CONFIG"/>
+	<reg32 offset="0x00198" name="CMN_RATE_OVERRIDE"/>
+	<reg32 offset="0x0019C" name="SVS_MODE_CLK_SEL"/>
+	<reg32 offset="0x001A0" name="DEBUG_BUS0"/>
+	<reg32 offset="0x001A4" name="DEBUG_BUS1"/>
+	<reg32 offset="0x001A8" name="DEBUG_BUS2"/>
+	<reg32 offset="0x001AC" name="DEBUG_BUS3"/>
+	<reg32 offset="0x001B0" name="DEBUG_BUS_SEL"/>
+	<reg32 offset="0x001B4" name="CMN_MISC1"/>
+	<reg32 offset="0x001B8" name="CMN_MISC2"/>
+	<reg32 offset="0x001BC" name="CORECLK_DIV_MODE1"/>
+	<reg32 offset="0x001C0" name="CORECLK_DIV_MODE2"/>
+	<reg32 offset="0x001C4" name="CMN_RSVD5"/>
+</domain>
+
+
+<domain name="HDMI_PHY_QSERDES_TX_LX" width="32">
+		<reg32 offset="0x00000" name="BIST_MODE_LANENO"/>
+		<reg32 offset="0x00004" name="BIST_INVERT"/>
+		<reg32 offset="0x00008" name="CLKBUF_ENABLE"/>
+		<reg32 offset="0x0000C" name="CMN_CONTROL_ONE"/>
+		<reg32 offset="0x00010" name="CMN_CONTROL_TWO"/>
+		<reg32 offset="0x00014" name="CMN_CONTROL_THREE"/>
+		<reg32 offset="0x00018" name="TX_EMP_POST1_LVL"/>
+		<reg32 offset="0x0001C" name="TX_POST2_EMPH"/>
+		<reg32 offset="0x00020" name="TX_BOOST_LVL_UP_DN"/>
+		<reg32 offset="0x00024" name="HP_PD_ENABLES"/>
+		<reg32 offset="0x00028" name="TX_IDLE_LVL_LARGE_AMP"/>
+		<reg32 offset="0x0002C" name="TX_DRV_LVL"/>
+		<reg32 offset="0x00030" name="TX_DRV_LVL_OFFSET"/>
+		<reg32 offset="0x00034" name="RESET_TSYNC_EN"/>
+		<reg32 offset="0x00038" name="PRE_STALL_LDO_BOOST_EN"/>
+		<reg32 offset="0x0003C" name="TX_BAND"/>
+		<reg32 offset="0x00040" name="SLEW_CNTL"/>
+		<reg32 offset="0x00044" name="INTERFACE_SELECT"/>
+		<reg32 offset="0x00048" name="LPB_EN"/>
+		<reg32 offset="0x0004C" name="RES_CODE_LANE_TX"/>
+		<reg32 offset="0x00050" name="RES_CODE_LANE_RX"/>
+		<reg32 offset="0x00054" name="RES_CODE_LANE_OFFSET"/>
+		<reg32 offset="0x00058" name="PERL_LENGTH1"/>
+		<reg32 offset="0x0005C" name="PERL_LENGTH2"/>
+		<reg32 offset="0x00060" name="SERDES_BYP_EN_OUT"/>
+		<reg32 offset="0x00064" name="DEBUG_BUS_SEL"/>
+		<reg32 offset="0x00068" name="HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN"/>
+		<reg32 offset="0x0006C" name="TX_POL_INV"/>
+		<reg32 offset="0x00070" name="PARRATE_REC_DETECT_IDLE_EN"/>
+		<reg32 offset="0x00074" name="BIST_PATTERN1"/>
+		<reg32 offset="0x00078" name="BIST_PATTERN2"/>
+		<reg32 offset="0x0007C" name="BIST_PATTERN3"/>
+		<reg32 offset="0x00080" name="BIST_PATTERN4"/>
+		<reg32 offset="0x00084" name="BIST_PATTERN5"/>
+		<reg32 offset="0x00088" name="BIST_PATTERN6"/>
+		<reg32 offset="0x0008C" name="BIST_PATTERN7"/>
+		<reg32 offset="0x00090" name="BIST_PATTERN8"/>
+		<reg32 offset="0x00094" name="LANE_MODE"/>
+		<reg32 offset="0x00098" name="IDAC_CAL_LANE_MODE"/>
+		<reg32 offset="0x0009C" name="IDAC_CAL_LANE_MODE_CONFIGURATION"/>
+		<reg32 offset="0x000A0" name="ATB_SEL1"/>
+		<reg32 offset="0x000A4" name="ATB_SEL2"/>
+		<reg32 offset="0x000A8" name="RCV_DETECT_LVL"/>
+		<reg32 offset="0x000AC" name="RCV_DETECT_LVL_2"/>
+		<reg32 offset="0x000B0" name="PRBS_SEED1"/>
+		<reg32 offset="0x000B4" name="PRBS_SEED2"/>
+		<reg32 offset="0x000B8" name="PRBS_SEED3"/>
+		<reg32 offset="0x000BC" name="PRBS_SEED4"/>
+		<reg32 offset="0x000C0" name="RESET_GEN"/>
+		<reg32 offset="0x000C4" name="RESET_GEN_MUXES"/>
+		<reg32 offset="0x000C8" name="TRAN_DRVR_EMP_EN"/>
+		<reg32 offset="0x000CC" name="TX_INTERFACE_MODE"/>
+		<reg32 offset="0x000D0" name="PWM_CTRL"/>
+		<reg32 offset="0x000D4" name="PWM_ENCODED_OR_DATA"/>
+		<reg32 offset="0x000D8" name="PWM_GEAR_1_DIVIDER_BAND2"/>
+		<reg32 offset="0x000DC" name="PWM_GEAR_2_DIVIDER_BAND2"/>
+		<reg32 offset="0x000E0" name="PWM_GEAR_3_DIVIDER_BAND2"/>
+		<reg32 offset="0x000E4" name="PWM_GEAR_4_DIVIDER_BAND2"/>
+		<reg32 offset="0x000E8" name="PWM_GEAR_1_DIVIDER_BAND0_1"/>
+		<reg32 offset="0x000EC" name="PWM_GEAR_2_DIVIDER_BAND0_1"/>
+		<reg32 offset="0x000F0" name="PWM_GEAR_3_DIVIDER_BAND0_1"/>
+		<reg32 offset="0x000F4" name="PWM_GEAR_4_DIVIDER_BAND0_1"/>
+		<reg32 offset="0x000F8" name="VMODE_CTRL1"/>
+		<reg32 offset="0x000FC" name="VMODE_CTRL2"/>
+		<reg32 offset="0x00100" name="TX_ALOG_INTF_OBSV_CNTL"/>
+		<reg32 offset="0x00104" name="BIST_STATUS"/>
+		<reg32 offset="0x00108" name="BIST_ERROR_COUNT1"/>
+		<reg32 offset="0x0010C" name="BIST_ERROR_COUNT2"/>
+		<reg32 offset="0x00110" name="TX_ALOG_INTF_OBSV"/>
+</domain>
+
+<domain name="HDMI_8998_PHY" width="32">
+	<reg32 offset="0x00000" name="CFG"/>
+	<reg32 offset="0x00004" name="PD_CTL"/>
+	<reg32 offset="0x00010" name="MODE"/>
+	<reg32 offset="0x0005C" name="CLOCK"/>
+	<reg32 offset="0x00068" name="CMN_CTRL"/>
+	<reg32 offset="0x000B4" name="STATUS"/>
+</domain>
+
+<domain name="HDMI_8998_PHY_QSERDES_COM" width="32">
+	<reg32 offset="0x0000" name="ATB_SEL1"/>
+	<reg32 offset="0x0004" name="ATB_SEL2"/>
+	<reg32 offset="0x0008" name="FREQ_UPDATE"/>
+	<reg32 offset="0x000C" name="BG_TIMER"/>
+	<reg32 offset="0x0010" name="SSC_EN_CENTER"/>
+	<reg32 offset="0x0014" name="SSC_ADJ_PER1"/>
+	<reg32 offset="0x0018" name="SSC_ADJ_PER2"/>
+	<reg32 offset="0x001C" name="SSC_PER1"/>
+	<reg32 offset="0x0020" name="SSC_PER2"/>
+	<reg32 offset="0x0024" name="SSC_STEP_SIZE1"/>
+	<reg32 offset="0x0028" name="SSC_STEP_SIZE2"/>
+	<reg32 offset="0x002C" name="POST_DIV"/>
+	<reg32 offset="0x0030" name="POST_DIV_MUX"/>
+	<reg32 offset="0x0034" name="BIAS_EN_CLKBUFLR_EN"/>
+	<reg32 offset="0x0038" name="CLK_ENABLE1"/>
+	<reg32 offset="0x003C" name="SYS_CLK_CTRL"/>
+	<reg32 offset="0x0040" name="SYSCLK_BUF_ENABLE"/>
+	<reg32 offset="0x0044" name="PLL_EN"/>
+	<reg32 offset="0x0048" name="PLL_IVCO"/>
+	<reg32 offset="0x004C" name="CMN_IETRIM"/>
+	<reg32 offset="0x0050" name="CMN_IPTRIM"/>
+	<reg32 offset="0x0060" name="CP_CTRL_MODE0"/>
+	<reg32 offset="0x0064" name="CP_CTRL_MODE1"/>
+	<reg32 offset="0x0068" name="PLL_RCTRL_MODE0"/>
+	<reg32 offset="0x006C" name="PLL_RCTRL_MODE1"/>
+	<reg32 offset="0x0070" name="PLL_CCTRL_MODE0"/>
+	<reg32 offset="0x0074" name="PLL_CCTRL_MODE1"/>
+	<reg32 offset="0x0078" name="PLL_CNTRL"/>
+	<reg32 offset="0x007C" name="BIAS_EN_CTRL_BY_PSM"/>
+	<reg32 offset="0x0080" name="SYSCLK_EN_SEL"/>
+	<reg32 offset="0x0084" name="CML_SYSCLK_SEL"/>
+	<reg32 offset="0x0088" name="RESETSM_CNTRL"/>
+	<reg32 offset="0x008C" name="RESETSM_CNTRL2"/>
+	<reg32 offset="0x0090" name="LOCK_CMP_EN"/>
+	<reg32 offset="0x0094" name="LOCK_CMP_CFG"/>
+	<reg32 offset="0x0098" name="LOCK_CMP1_MODE0"/>
+	<reg32 offset="0x009C" name="LOCK_CMP2_MODE0"/>
+	<reg32 offset="0x00A0" name="LOCK_CMP3_MODE0"/>
+	<reg32 offset="0x00B0" name="DEC_START_MODE0"/>
+	<reg32 offset="0x00B4" name="DEC_START_MODE1"/>
+	<reg32 offset="0x00B8" name="DIV_FRAC_START1_MODE0"/>
+	<reg32 offset="0x00BC" name="DIV_FRAC_START2_MODE0"/>
+	<reg32 offset="0x00C0" name="DIV_FRAC_START3_MODE0"/>
+	<reg32 offset="0x00C4" name="DIV_FRAC_START1_MODE1"/>
+	<reg32 offset="0x00C8" name="DIV_FRAC_START2_MODE1"/>
+	<reg32 offset="0x00CC" name="DIV_FRAC_START3_MODE1"/>
+	<reg32 offset="0x00D0" name="INTEGLOOP_INITVAL"/>
+	<reg32 offset="0x00D4" name="INTEGLOOP_EN"/>
+	<reg32 offset="0x00D8" name="INTEGLOOP_GAIN0_MODE0"/>
+	<reg32 offset="0x00DC" name="INTEGLOOP_GAIN1_MODE0"/>
+	<reg32 offset="0x00E0" name="INTEGLOOP_GAIN0_MODE1"/>
+	<reg32 offset="0x00E4" name="INTEGLOOP_GAIN1_MODE1"/>
+	<reg32 offset="0x00E8" name="VCOCAL_DEADMAN_CTRL"/>
+	<reg32 offset="0x00EC" name="VCO_TUNE_CTRL"/>
+	<reg32 offset="0x00F0" name="VCO_TUNE_MAP"/>
+	<reg32 offset="0x0124" name="CMN_STATUS"/>
+	<reg32 offset="0x0128" name="RESET_SM_STATUS"/>
+	<reg32 offset="0x0138" name="CLK_SEL"/>
+	<reg32 offset="0x013C" name="HSCLK_SEL"/>
+	<reg32 offset="0x0148" name="CORECLK_DIV_MODE0"/>
+	<reg32 offset="0x0150" name="SW_RESET"/>
+	<reg32 offset="0x0154" name="CORE_CLK_EN"/>
+	<reg32 offset="0x0158" name="C_READY_STATUS"/>
+	<reg32 offset="0x015C" name="CMN_CONFIG"/>
+	<reg32 offset="0x0164" name="SVS_MODE_CLK_SEL"/>
+</domain>
+
+<domain name="HDMI_8998_PHY_TXn" width="32">
+	<reg32 offset="0x0000" name="EMP_POST1_LVL"/>
+	<reg32 offset="0x0008" name="INTERFACE_SELECT_TX_BAND"/>
+	<reg32 offset="0x000C" name="CLKBUF_TERM_ENABLE"/>
+	<reg32 offset="0x0014" name="DRV_LVL_RES_CODE_OFFSET"/>
+	<reg32 offset="0x0018" name="DRV_LVL"/>
+	<reg32 offset="0x001C" name="LANE_CONFIG"/>
+	<reg32 offset="0x0024" name="PRE_DRIVER_1"/>
+	<reg32 offset="0x0028" name="PRE_DRIVER_2"/>
+	<reg32 offset="0x002C" name="LANE_MODE"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/mdp4.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/mdp4.xml
@@ -0,0 +1,504 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="display/mdp_common.xml"/>
+
+<domain name="MDP4" width="32">
+	<enum name="mdp4_pipe">
+		<brief>pipe names, index into PIPE[]</brief>
+		<value name="VG1" value="0"/>
+		<value name="VG2" value="1"/>
+		<value name="RGB1" value="2"/>
+		<value name="RGB2" value="3"/>
+		<value name="RGB3" value="4"/>
+		<value name="VG3" value="5"/>
+		<value name="VG4" value="6"/>
+	</enum>
+
+	<enum name="mdp4_mixer">
+		<value name="MIXER0" value="0"/>
+		<value name="MIXER1" value="1"/>
+		<value name="MIXER2" value="2"/>
+	</enum>
+
+	<enum name="mdp4_intf">
+		<!--
+			A bit confusing the enums for interface selection:
+				enum {
+					LCDC_RGB_INTF,			/* 0 */
+					DTV_INTF = LCDC_RGB_INTF,	/* 0 */
+					MDDI_LCDC_INTF,			/* 1 */
+					MDDI_INTF,			/* 2 */
+					EBI2_INTF,			/* 3 */
+					TV_INTF = EBI2_INTF,		/* 3 */
+					DSI_VIDEO_INTF,
+					DSI_CMD_INTF
+				};
+			there is some overlap, and not all the values end up getting
+			written to hw (mdp4_display_intf_sel() remaps the last two
+			values to MDDI_LCDC_INTF/MDDI_INTF with extra bits set).. so
+			taking some liberties in guessing the actual meanings/names:
+		 -->
+		<value name="INTF_LCDC_DTV" value="0"/>  <!-- LCDC RGB or DTV (external) -->
+		<value name="INTF_DSI_VIDEO" value="1"/>
+		<value name="INTF_DSI_CMD" value="2"/>
+		<value name="INTF_EBI2_TV" value="3"/>   <!-- EBI2 or TV (external) -->
+	</enum>
+	<enum name="mdp4_cursor_format">
+		<value name="CURSOR_ARGB" value="1"/>
+		<value name="CURSOR_XRGB" value="2"/>
+	</enum>
+	<enum name="mdp4_frame_format">
+		<value name="FRAME_LINEAR" value="0"/>
+		<value name="FRAME_TILE_ARGB_4X4" value="1"/>
+		<value name="FRAME_TILE_YCBCR_420" value="2"/>
+	</enum>
+	<enum name="mdp4_scale_unit">
+		<value name="SCALE_FIR" value="0"/>
+		<value name="SCALE_MN_PHASE" value="1"/>
+		<value name="SCALE_PIXEL_RPT" value="2"/>
+	</enum>
+
+	<bitset name="mdp4_layermixer_in_cfg" inline="yes">
+		<brief>appears to map pipe to mixer stage</brief>
+		<bitfield name="PIPE0" low="0"  high="2"  type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE0_MIXER1" pos="3" type="boolean"/>
+		<bitfield name="PIPE1" low="4"  high="6"  type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE1_MIXER1" pos="7" type="boolean"/>
+		<bitfield name="PIPE2" low="8"  high="10" type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE2_MIXER1" pos="11" type="boolean"/>
+		<bitfield name="PIPE3" low="12" high="14" type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE3_MIXER1" pos="15" type="boolean"/>
+		<bitfield name="PIPE4" low="16" high="18" type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE4_MIXER1" pos="19" type="boolean"/>
+		<bitfield name="PIPE5" low="20" high="22" type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE5_MIXER1" pos="23" type="boolean"/>
+		<bitfield name="PIPE6" low="24" high="26" type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE6_MIXER1" pos="27" type="boolean"/>
+		<bitfield name="PIPE7" low="28" high="30" type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE7_MIXER1" pos="31" type="boolean"/>
+	</bitset>
+
+	<bitset name="MDP4_IRQ">
+		<bitfield name="OVERLAY0_DONE" pos="0" type="boolean"/>
+		<bitfield name="OVERLAY1_DONE" pos="1" type="boolean"/>
+		<bitfield name="DMA_S_DONE" pos="2" type="boolean"/>
+		<bitfield name="DMA_E_DONE" pos="3" type="boolean"/>
+		<bitfield name="DMA_P_DONE" pos="4" type="boolean"/>
+		<bitfield name="VG1_HISTOGRAM" pos="5" type="boolean"/>
+		<bitfield name="VG2_HISTOGRAM" pos="6" type="boolean"/>
+		<bitfield name="PRIMARY_VSYNC" pos="7" type="boolean"/>
+		<bitfield name="PRIMARY_INTF_UDERRUN" pos="8" type="boolean"/>
+		<bitfield name="EXTERNAL_VSYNC" pos="9" type="boolean"/>
+		<bitfield name="EXTERNAL_INTF_UDERRUN" pos="10" type="boolean"/>
+		<bitfield name="PRIMARY_RDPTR" pos="11" type="boolean"/>  <!-- read pointer -->
+		<bitfield name="DMA_P_HISTOGRAM" pos="17" type="boolean"/>
+		<bitfield name="DMA_S_HISTOGRAM" pos="26" type="boolean"/>
+		<bitfield name="OVERLAY2_DONE" pos="30" type="boolean"/>
+	</bitset>
+
+	<reg32 offset="0x00000" name="VERSION">
+		<!--
+			from mdp_probe() we can see minor rev starts at 16.. assume
+			major is above that.. not sure the rest of bits but doesn't
+			really seem to matter
+		 -->
+		<bitfield name="MINOR" low="16" high="23" type="uint"/>
+		<bitfield name="MAJOR" low="24" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00004" name="OVLP0_KICK"/>
+	<reg32 offset="0x00008" name="OVLP1_KICK"/>
+	<reg32 offset="0x000d0" name="OVLP2_KICK"/>
+	<reg32 offset="0x0000c" name="DMA_P_KICK"/>
+	<reg32 offset="0x00010" name="DMA_S_KICK"/>
+	<reg32 offset="0x00014" name="DMA_E_KICK"/>
+	<reg32 offset="0x00018" name="DISP_STATUS"/>
+
+	<reg32 offset="0x00038" name="DISP_INTF_SEL">
+		<bitfield name="PRIM" low="0" high="1" type="mdp4_intf"/>
+		<bitfield name="SEC" low="2" high="3" type="mdp4_intf"/>
+		<bitfield name="EXT" low="4" high="5" type="mdp4_intf"/>
+		<bitfield name="DSI_VIDEO" pos="6" type="boolean"/>
+		<bitfield name="DSI_CMD" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0003c" name="RESET_STATUS"/>  <!-- only mdp4 >v2.1 -->
+	<reg32 offset="0x0004c" name="READ_CNFG"/>  <!-- something about # of pending requests.. -->
+	<reg32 offset="0x00050" name="INTR_ENABLE" type="MDP4_IRQ"/>
+	<reg32 offset="0x00054" name="INTR_STATUS" type="MDP4_IRQ"/>
+	<reg32 offset="0x00058" name="INTR_CLEAR" type="MDP4_IRQ"/>
+	<reg32 offset="0x00060" name="EBI2_LCD0"/>
+	<reg32 offset="0x00064" name="EBI2_LCD1"/>
+	<reg32 offset="0x00070" name="PORTMAP_MODE"/>
+
+	<!-- mdp chip-select controller: -->
+	<reg32 offset="0x000c0" name="CS_CONTROLLER0"/>
+	<reg32 offset="0x000c4" name="CS_CONTROLLER1"/>
+
+	<reg32 offset="0x100f0" name="LAYERMIXER2_IN_CFG" type="mdp4_layermixer_in_cfg"/>
+	<reg32 offset="0x100fc" name="LAYERMIXER_IN_CFG_UPDATE_METHOD"/>
+	<reg32 offset="0x10100" name="LAYERMIXER_IN_CFG" type="mdp4_layermixer_in_cfg"/>
+
+	<reg32 offset="0x30050" name="VG2_SRC_FORMAT"/>
+	<reg32 offset="0x31008" name="VG2_CONST_COLOR"/>
+
+	<reg32 offset="0x18000" name="OVERLAY_FLUSH">
+		<bitfield name="OVLP0" pos="0" type="boolean"/>
+		<bitfield name="OVLP1" pos="1" type="boolean"/>
+		<bitfield name="VG1" pos="2" type="boolean"/>
+		<bitfield name="VG2" pos="3" type="boolean"/>
+		<bitfield name="RGB1" pos="4" type="boolean"/>
+		<bitfield name="RGB2" pos="5" type="boolean"/>
+	</reg32>
+
+	<array offsets="0x10000,0x18000,0x88000" name="OVLP" length="3" stride="0x8000">
+		<reg32 offset="0x0004" name="CFG"/>
+		<reg32 offset="0x0008" name="SIZE" type="reg_wh"/>
+		<reg32 offset="0x000c" name="BASE"/>
+		<reg32 offset="0x0010" name="STRIDE" type="uint"/>
+		<reg32 offset="0x0014" name="OPMODE"/>
+
+		<array offsets="0x0104,0x0124,0x0144,0x0160" name="STAGE" length="4" stride="0x1c">
+			<reg32 offset="0x00" name="OP">
+				<bitfield name="FG_ALPHA" low="0" high="1" type="mdp_alpha_type"/>
+				<bitfield name="FG_INV_ALPHA" pos="2" type="boolean"/>
+				<bitfield name="FG_MOD_ALPHA" pos="3" type="boolean"/>
+				<bitfield name="BG_ALPHA" low="4" high="5" type="mdp_alpha_type"/>
+				<bitfield name="BG_INV_ALPHA" pos="6" type="boolean"/>
+				<bitfield name="BG_MOD_ALPHA" pos="7" type="boolean"/>
+				<bitfield name="FG_TRANSP" pos="8" type="boolean"/>
+				<bitfield name="BG_TRANSP" pos="9" type="boolean"/>
+			</reg32>
+			<reg32 offset="0x04" name="FG_ALPHA"/>
+			<reg32 offset="0x08" name="BG_ALPHA"/>
+			<reg32 offset="0x0c" name="TRANSP_LOW0"/>
+			<reg32 offset="0x10" name="TRANSP_LOW1"/>
+			<reg32 offset="0x14" name="TRANSP_HIGH0"/>
+			<reg32 offset="0x18" name="TRANSP_HIGH1"/>
+		</array>
+
+		<array offsets="0x1004,0x1404,0x1804,0x1b84" name="STAGE_CO3" length="4" stride="4">
+			<reg32 offset="0" name="SEL">
+				<bitfield name="FG_ALPHA" pos="0" type="boolean"/> <!-- otherwise bg alpha -->
+			</reg32>
+		</array>
+
+		<reg32 offset="0x0180" name="TRANSP_LOW0"/>
+		<reg32 offset="0x0184" name="TRANSP_LOW1"/>
+		<reg32 offset="0x0188" name="TRANSP_HIGH0"/>
+		<reg32 offset="0x018c" name="TRANSP_HIGH1"/>
+
+		<reg32 offset="0x0200" name="CSC_CONFIG"/>
+
+		<array offset="0x2000" name="CSC" length="1" stride="0x700">
+			<array offset="0x400" name="MV" length="9" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x500" name="PRE_BV" length="3" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x580" name="POST_BV" length="3" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x600" name="PRE_LV" length="6" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x680" name="POST_LV" length="6" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+		</array>
+	</array>
+
+	<enum name="mdp4_dma">
+		<value name="DMA_P" value="0"/>
+		<value name="DMA_S" value="1"/>
+		<value name="DMA_E" value="2"/>
+	</enum>
+	<reg32 offset="0x90070" name="DMA_P_OP_MODE"/>
+	<array offset="0x94800" name="LUTN" length="2" stride="0x400">
+		<array offset="0" name="LUT" length="0x100" stride="4">
+			<reg32 offset="0" name="VAL"/>
+		</array>
+	</array>
+	<reg32 offset="0xa0028" name="DMA_S_OP_MODE"/>
+	<!-- I guess if DMA_S has an OP_MODE, it must have a LUT too.. -->
+	<reg32 offset="0xb0070" name="DMA_E_QUANT" length="3" stride="4"/>
+	<array offsets="0x90000,0xa0000,0xb0000" name="DMA" length="3" stride="0x10000" index="mdp4_dma">
+		<reg32 offset="0x0000" name="CONFIG">
+			<bitfield name="G_BPC" low="0" high="1" type="mdp_bpc"/>
+			<bitfield name="B_BPC" low="2" high="3" type="mdp_bpc"/>
+			<bitfield name="R_BPC" low="4" high="5" type="mdp_bpc"/>
+			<bitfield name="PACK_ALIGN_MSB" pos="7" type="boolean"/>
+			<bitfield name="PACK" low="8" high="15"/>
+			<!-- bit 24 is DITHER_EN on DMA_P, DEFLKR_EN on DMA_E -->
+			<bitfield name="DEFLKR_EN" pos="24" type="boolean"/>
+			<bitfield name="DITHER_EN" pos="24" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x0004" name="SRC_SIZE" type="reg_wh"/>
+		<reg32 offset="0x0008" name="SRC_BASE"/>
+		<reg32 offset="0x000c" name="SRC_STRIDE" type="uint"/>
+		<reg32 offset="0x0010" name="DST_SIZE" type="reg_wh"/>
+
+		<reg32 offset="0x0044" name="CURSOR_SIZE">
+			<!-- seems the limit is 64x64: -->
+			<bitfield name="WIDTH" low="0" high="6" type="uint"/>
+			<bitfield name="HEIGHT" low="16" high="22" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0048" name="CURSOR_BASE"/>
+		<reg32 offset="0x004c" name="CURSOR_POS">
+			<bitfield name="X" low="0" high="15" type="uint"/>
+			<bitfield name="Y" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0060" name="CURSOR_BLEND_CONFIG">
+			<bitfield name="CURSOR_EN" pos="0" type="boolean"/>
+			<bitfield name="FORMAT" low="1" high="2" type="mdp4_cursor_format"/>
+			<bitfield name="TRANSP_EN" pos="3" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x0064" name="CURSOR_BLEND_PARAM"/>
+		<reg32 offset="0x0068" name="BLEND_TRANS_LOW"/>
+		<reg32 offset="0x006c" name="BLEND_TRANS_HIGH"/>
+
+		<reg32 offset="0x1004" name="FETCH_CONFIG"/>
+		<array offset="0x3000" name="CSC" length="1" stride="0x700">
+			<array offset="0x400" name="MV" length="9" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x500" name="PRE_BV" length="3" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x580" name="POST_BV" length="3" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x600" name="PRE_LV" length="6" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x680" name="POST_LV" length="6" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+		</array>
+	</array>
+
+	<!--
+		TODO length should be 7, but that would collide w/ OVLP2..!?!
+		this register map is a bit strange..
+	 -->
+	<array offset="0x20000" name="PIPE" length="6" stride="0x10000" index="mdp4_pipe">
+		<reg32 offset="0x0000" name="SRC_SIZE" type="reg_wh"/>
+		<reg32 offset="0x0004" name="SRC_XY" type="reg_xy"/>
+		<reg32 offset="0x0008" name="DST_SIZE" type="reg_wh"/>
+		<reg32 offset="0x000c" name="DST_XY" type="reg_xy"/>
+		<reg32 offset="0x0010" name="SRCP0_BASE"/>
+		<reg32 offset="0x0014" name="SRCP1_BASE"/>
+		<reg32 offset="0x0018" name="SRCP2_BASE"/>
+		<reg32 offset="0x001c" name="SRCP3_BASE"/>
+		<reg32 offset="0x0040" name="SRC_STRIDE_A">
+			<bitfield name="P0" low="0" high="15" type="uint"/>
+			<bitfield name="P1" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0044" name="SRC_STRIDE_B">
+			<bitfield name="P2" low="0" high="15" type="uint"/>
+			<bitfield name="P3" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0048" name="SSTILE_FRAME_SIZE" type="reg_wh"/>
+		<reg32 offset="0x0050" name="SRC_FORMAT">
+			<bitfield name="G_BPC" low="0" high="1" type="mdp_bpc"/>
+			<bitfield name="B_BPC" low="2" high="3" type="mdp_bpc"/>
+			<bitfield name="R_BPC" low="4" high="5" type="mdp_bpc"/>
+			<bitfield name="A_BPC" low="6" high="7" type="mdp_bpc_alpha"/>
+			<bitfield name="ALPHA_ENABLE" pos="8" type="boolean"/>
+			<bitfield name="CPP" low="9" high="10" type="uint">
+				<brief>8bit characters per pixel minus 1</brief>
+			</bitfield>
+			<bitfield name="ROTATED_90" pos="12" type="boolean"/>
+			<bitfield name="UNPACK_COUNT" low="13" high="14" type="uint"/>
+			<bitfield name="UNPACK_TIGHT" pos="17" type="boolean"/>
+			<bitfield name="UNPACK_ALIGN_MSB" pos="18" type="boolean"/>
+			<bitfield name="FETCH_PLANES" low="19" high="20" type="uint"/>
+			<bitfield name="SOLID_FILL" pos="22" type="boolean"/>
+			<bitfield name="CHROMA_SAMP" low="26" high="27" type="mdp_chroma_samp_type"/>
+			<bitfield name="FRAME_FORMAT" low="29" high="30" type="mdp4_frame_format"/>
+		</reg32>
+		<reg32 offset="0x0054" name="SRC_UNPACK" type="mdp_unpack_pattern"/>
+		<reg32 offset="0x0058" name="OP_MODE">
+			<bitfield name="SCALEX_EN" pos="0" type="boolean"/>
+			<bitfield name="SCALEY_EN" pos="1" type="boolean"/>
+			<bitfield name="SCALEX_UNIT_SEL" low="2" high="3" type="mdp4_scale_unit"/>
+			<bitfield name="SCALEY_UNIT_SEL" low="4" high="5" type="mdp4_scale_unit"/>
+			<bitfield name="SRC_YCBCR" pos="9" type="boolean"/>
+			<bitfield name="DST_YCBCR" pos="10" type="boolean"/>
+			<bitfield name="CSC_EN" pos="11" type="boolean"/>
+			<bitfield name="FLIP_LR" pos="13" type="boolean"/>
+			<bitfield name="FLIP_UD" pos="14" type="boolean"/>
+			<bitfield name="DITHER_EN" pos="15" type="boolean"/>
+			<bitfield name="IGC_LUT_EN" pos="16" type="boolean"/>
+			<bitfield name="DEINT_EN" pos="18" type="boolean"/>
+			<bitfield name="DEINT_ODD_REF" pos="19" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x005c" name="PHASEX_STEP"/>
+		<reg32 offset="0x0060" name="PHASEY_STEP"/>
+		<reg32 offset="0x1004" name="FETCH_CONFIG"/>
+		<reg32 offset="0x1008" name="SOLID_COLOR"/>
+
+		<array offset="0x4000" name="CSC" length="1" stride="0x700">
+			<array offset="0x400" name="MV" length="9" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x500" name="PRE_BV" length="3" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x580" name="POST_BV" length="3" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x600" name="PRE_LV" length="6" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x680" name="POST_LV" length="6" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+		</array>
+	</array>
+
+	<!--
+		ENCODERS
+			LCDC and DSI seem the same, DTV is just slightly different..
+	 -->
+
+	<bitset name="mdp4_ctrl_polarity" inline="yes">
+		<!-- not entirely sure if these bits mean hi or low.. -->
+		<bitfield name="HSYNC_LOW" pos="0" type="boolean"/>
+		<bitfield name="VSYNC_LOW" pos="1" type="boolean"/>
+		<bitfield name="DATA_EN_LOW" pos="2" type="boolean"/>
+	</bitset>
+
+	<bitset name="mdp4_active_hctl" inline="yes">
+		<bitfield name="START" low="0" high="14" type="uint"/>
+		<bitfield name="END" low="16" high="30" type="uint"/>
+		<bitfield name="ACTIVE_START_X" pos="31" type="boolean"/>
+	</bitset>
+
+	<bitset name="mdp4_display_hctl" inline="yes">
+		<bitfield name="START" low="0" high="15" type="uint"/>
+		<bitfield name="END" low="16" high="31" type="uint"/>
+	</bitset>
+
+	<bitset name="mdp4_hsync_ctrl" inline="yes">
+		<bitfield name="PULSEW" low="0" high="15" type="uint"/>
+		<bitfield name="PERIOD" low="16" high="31" type="uint"/>
+	</bitset>
+
+	<bitset name="mdp4_underflow_clr" inline="yes">
+		<bitfield name="COLOR" low="0" high="23"/>
+		<bitfield name="ENABLE_RECOVERY" pos="31" type="boolean"/>
+	</bitset>
+
+	<!-- offset is 0xe0000 on !mdp4.. -->
+	<array offset="0xc0000" name="LCDC" length="1" stride="0x1000">
+		<reg32 offset="0x0000" name="ENABLE"/>
+		<reg32 offset="0x0004" name="HSYNC_CTRL" type="mdp4_hsync_ctrl"/>
+		<reg32 offset="0x0008" name="VSYNC_PERIOD" type="uint"/>
+		<reg32 offset="0x000c" name="VSYNC_LEN" type="uint"/>
+		<reg32 offset="0x0010" name="DISPLAY_HCTRL" type="mdp4_display_hctl"/>
+		<reg32 offset="0x0014" name="DISPLAY_VSTART" type="uint"/>
+		<reg32 offset="0x0018" name="DISPLAY_VEND" type="uint"/>
+		<reg32 offset="0x001c" name="ACTIVE_HCTL" type="mdp4_active_hctl"/>
+		<reg32 offset="0x0020" name="ACTIVE_VSTART" type="uint"/>
+		<reg32 offset="0x0024" name="ACTIVE_VEND" type="uint"/>
+		<reg32 offset="0x0028" name="BORDER_CLR"/>
+		<reg32 offset="0x002c" name="UNDERFLOW_CLR" type="mdp4_underflow_clr"/>
+		<reg32 offset="0x0030" name="HSYNC_SKEW"/>
+		<reg32 offset="0x0034" name="TEST_CNTL"/>
+		<reg32 offset="0x0038" name="CTRL_POLARITY" type="mdp4_ctrl_polarity"/>
+	</array>
+
+	<reg32 offset="0xc2000" name="LCDC_LVDS_INTF_CTL">
+		<bitfield name="MODE_SEL"           pos="2"  type="boolean"/>
+		<bitfield name="RGB_OUT"            pos="3"  type="boolean"/>
+		<bitfield name="CH_SWAP"            pos="4"  type="boolean"/>
+		<bitfield name="CH1_RES_BIT"        pos="5"  type="boolean"/>
+		<bitfield name="CH2_RES_BIT"        pos="6"  type="boolean"/>
+		<bitfield name="ENABLE"             pos="7"  type="boolean"/>
+		<bitfield name="CH1_DATA_LANE0_EN"  pos="8"  type="boolean"/>
+		<bitfield name="CH1_DATA_LANE1_EN"  pos="9"  type="boolean"/>
+		<bitfield name="CH1_DATA_LANE2_EN"  pos="10" type="boolean"/>
+		<bitfield name="CH1_DATA_LANE3_EN"  pos="11" type="boolean"/>
+		<bitfield name="CH2_DATA_LANE0_EN"  pos="12" type="boolean"/>
+		<bitfield name="CH2_DATA_LANE1_EN"  pos="13" type="boolean"/>
+		<bitfield name="CH2_DATA_LANE2_EN"  pos="14" type="boolean"/>
+		<bitfield name="CH2_DATA_LANE3_EN"  pos="15" type="boolean"/>
+		<bitfield name="CH1_CLK_LANE_EN"    pos="16" type="boolean"/>
+		<bitfield name="CH2_CLK_LANE_EN"    pos="17" type="boolean"/>
+	</reg32>
+
+	<array offset="0xc2014" name="LCDC_LVDS_MUX_CTL" length="4" stride="0x8">
+		<reg32 offset="0x0" name="3_TO_0">
+			<bitfield name="BIT0" low="0"  high="7"/>
+			<bitfield name="BIT1" low="8"  high="15"/>
+			<bitfield name="BIT2" low="16" high="23"/>
+			<bitfield name="BIT3" low="24" high="31"/>
+		</reg32>
+		<reg32 offset="0x4" name="6_TO_4">
+			<bitfield name="BIT4" low="0"  high="7"/>
+			<bitfield name="BIT5" low="8"  high="15"/>
+			<bitfield name="BIT6" low="16" high="23"/>
+		</reg32>
+	</array>
+
+	<reg32 offset="0xc2034" name="LCDC_LVDS_PHY_RESET"/>
+
+	<reg32 offset="0xc3000" name="LVDS_PHY_PLL_CTRL_0"/>
+	<reg32 offset="0xc3004" name="LVDS_PHY_PLL_CTRL_1"/>
+	<reg32 offset="0xc3008" name="LVDS_PHY_PLL_CTRL_2"/>
+	<reg32 offset="0xc300c" name="LVDS_PHY_PLL_CTRL_3"/>
+	<reg32 offset="0xc3014" name="LVDS_PHY_PLL_CTRL_5"/>
+	<reg32 offset="0xc3018" name="LVDS_PHY_PLL_CTRL_6"/>
+	<reg32 offset="0xc301c" name="LVDS_PHY_PLL_CTRL_7"/>
+	<reg32 offset="0xc3020" name="LVDS_PHY_PLL_CTRL_8"/>
+	<reg32 offset="0xc3024" name="LVDS_PHY_PLL_CTRL_9"/>
+	<reg32 offset="0xc3080" name="LVDS_PHY_PLL_LOCKED"/>
+	<reg32 offset="0xc3108" name="LVDS_PHY_CFG2"/>
+
+	<reg32 offset="0xc3100" name="LVDS_PHY_CFG0">
+		<bitfield name="SERIALIZATION_ENBLE" pos="4" type="boolean"/>
+		<bitfield name="CHANNEL0" pos="6" type="boolean"/>
+		<bitfield name="CHANNEL1" pos="7" type="boolean"/>
+	</reg32>
+
+	<array offset="0xd0000" name="DTV" length="1" stride="0x1000">
+		<reg32 offset="0x0000" name="ENABLE"/>
+		<reg32 offset="0x0004" name="HSYNC_CTRL" type="mdp4_hsync_ctrl"/>
+		<reg32 offset="0x0008" name="VSYNC_PERIOD" type="uint"/>
+		<reg32 offset="0x000c" name="VSYNC_LEN" type="uint"/>
+		<reg32 offset="0x0018" name="DISPLAY_HCTRL" type="mdp4_display_hctl"/>
+		<reg32 offset="0x001c" name="DISPLAY_VSTART" type="uint"/>
+		<reg32 offset="0x0020" name="DISPLAY_VEND" type="uint"/>
+		<reg32 offset="0x002c" name="ACTIVE_HCTL" type="mdp4_active_hctl"/>
+		<reg32 offset="0x0030" name="ACTIVE_VSTART" type="uint"/>
+		<reg32 offset="0x0038" name="ACTIVE_VEND" type="uint"/>
+		<reg32 offset="0x0040" name="BORDER_CLR"/>
+		<reg32 offset="0x0044" name="UNDERFLOW_CLR" type="mdp4_underflow_clr"/>
+		<reg32 offset="0x0048" name="HSYNC_SKEW"/>
+		<reg32 offset="0x004c" name="TEST_CNTL"/>
+		<reg32 offset="0x0050" name="CTRL_POLARITY" type="mdp4_ctrl_polarity"/>
+	</array>
+
+	<array offset="0xe0000" name="DSI" length="1" stride="0x1000">
+		<reg32 offset="0x0000" name="ENABLE"/>
+		<reg32 offset="0x0004" name="HSYNC_CTRL" type="mdp4_hsync_ctrl"/>
+		<reg32 offset="0x0008" name="VSYNC_PERIOD" type="uint"/>
+		<reg32 offset="0x000c" name="VSYNC_LEN" type="uint"/>
+		<reg32 offset="0x0010" name="DISPLAY_HCTRL" type="mdp4_display_hctl"/>
+		<reg32 offset="0x0014" name="DISPLAY_VSTART" type="uint"/>
+		<reg32 offset="0x0018" name="DISPLAY_VEND" type="uint"/>
+		<reg32 offset="0x001c" name="ACTIVE_HCTL" type="mdp4_active_hctl"/>
+		<reg32 offset="0x0020" name="ACTIVE_VSTART" type="uint"/>
+		<reg32 offset="0x0024" name="ACTIVE_VEND" type="uint"/>
+		<reg32 offset="0x0028" name="BORDER_CLR"/>
+		<reg32 offset="0x002c" name="UNDERFLOW_CLR" type="mdp4_underflow_clr"/>
+		<reg32 offset="0x0030" name="HSYNC_SKEW"/>
+		<reg32 offset="0x0034" name="TEST_CNTL"/>
+		<reg32 offset="0x0038" name="CTRL_POLARITY" type="mdp4_ctrl_polarity"/>
+	</array>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/mdp5.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/mdp5.xml
@@ -0,0 +1,790 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="display/mdp_common.xml"/>
+
+<!-- where does this belong? -->
+<domain name="VBIF" width="32">
+</domain>
+
+<domain name="MDP5" width="32">
+
+	<enum name="mdp5_intf_type">
+		<value name="INTF_DISABLED" value="0x0"/>
+		<value name="INTF_DSI"  value="0x1"/>
+		<value name="INTF_HDMI" value="0x3"/>
+		<value name="INTF_LCDC" value="0x5"/>
+		<value name="INTF_eDP"  value="0x9"/>
+		<value name="INTF_VIRTUAL"  value="0x64"/>
+		<!-- non-display interfaces are listed below: -->
+		<value name="INTF_WB"  value="0x65"/>
+	</enum>
+
+	<enum name="mdp5_intfnum">
+		<value name="NO_INTF" value="0"/>
+		<value name="INTF0"   value="1"/>
+		<value name="INTF1"   value="2"/>
+		<value name="INTF2"   value="3"/>
+		<value name="INTF3"   value="4"/>
+	</enum>
+
+	<enum name="mdp5_pipe">
+		<value name="SSPP_NONE" value="0"/>
+		<value name="SSPP_VIG0" value="1"/>
+		<value name="SSPP_VIG1" value="2"/>
+		<value name="SSPP_VIG2" value="3"/>
+		<value name="SSPP_RGB0" value="4"/>
+		<value name="SSPP_RGB1" value="5"/>
+		<value name="SSPP_RGB2" value="6"/>
+		<value name="SSPP_DMA0" value="7"/>
+		<value name="SSPP_DMA1" value="8"/>
+		<value name="SSPP_VIG3" value="9"/>
+		<value name="SSPP_RGB3" value="10"/>
+		<value name="SSPP_CURSOR0" value="11"/>
+		<value name="SSPP_CURSOR1" value="12"/>
+	</enum>
+
+	<enum name="mdp5_format">
+		<!-- TODO -->
+		<value name="DUMMY" value="0"/>
+	</enum>
+
+	<enum name="mdp5_ctl_mode">
+		<value name="MODE_NONE" value="0"/>
+		<value name="MODE_WB_0_BLOCK" value="1"/>
+		<value name="MODE_WB_1_BLOCK" value="2"/>
+		<value name="MODE_WB_0_LINE" value="3"/>
+		<value name="MODE_WB_1_LINE" value="4"/>
+		<value name="MODE_WB_2_LINE" value="5"/>
+	</enum>
+
+	<enum name="mdp5_pack_3d">
+		<value name="PACK_3D_FRAME_INT" value="0"/>
+		<value name="PACK_3D_H_ROW_INT" value="1"/>
+		<value name="PACK_3D_V_ROW_INT" value="2"/>
+		<value name="PACK_3D_COL_INT"   value="3"/>
+	</enum>
+
+	<enum name="mdp5_scale_filter">
+		<value name="SCALE_FILTER_NEAREST" value="0"/>
+		<value name="SCALE_FILTER_BIL" value="1"/>
+		<value name="SCALE_FILTER_PCMN" value="2"/>
+		<value name="SCALE_FILTER_CA" value="3"/>
+	</enum>
+
+	<enum name="mdp5_pipe_bwc">
+		<value name="BWC_LOSSLESS" value="0"/>
+		<value name="BWC_Q_HIGH"   value="1"/>
+		<value name="BWC_Q_MED"    value="2"/>
+	</enum>
+
+	<enum name="mdp5_cursor_format">
+		<value name="CURSOR_FMT_ARGB8888" value="0"/>
+		<value name="CURSOR_FMT_ARGB1555" value="2"/>
+		<value name="CURSOR_FMT_ARGB4444" value="4"/>
+	</enum>
+
+	<enum name="mdp5_cursor_alpha">
+		<value name="CURSOR_ALPHA_CONST" value="0"/>
+		<value name="CURSOR_ALPHA_PER_PIXEL" value="2"/>
+	</enum>
+
+	<bitset name="MDP5_IRQ">
+		<bitfield name="WB_0_DONE"                pos="0"  type="boolean"/>
+		<bitfield name="WB_1_DONE"                pos="1"  type="boolean"/>
+		<bitfield name="WB_2_DONE"                pos="4"  type="boolean"/>
+		<bitfield name="PING_PONG_0_DONE"         pos="8"  type="boolean"/>
+		<bitfield name="PING_PONG_1_DONE"         pos="9"  type="boolean"/>
+		<bitfield name="PING_PONG_2_DONE"         pos="10" type="boolean"/>
+		<bitfield name="PING_PONG_3_DONE"         pos="11" type="boolean"/>
+		<bitfield name="PING_PONG_0_RD_PTR"       pos="12" type="boolean"/>
+		<bitfield name="PING_PONG_1_RD_PTR"       pos="13" type="boolean"/>
+		<bitfield name="PING_PONG_2_RD_PTR"       pos="14" type="boolean"/>
+		<bitfield name="PING_PONG_3_RD_PTR"       pos="15" type="boolean"/>
+		<bitfield name="PING_PONG_0_WR_PTR"       pos="16" type="boolean"/>
+		<bitfield name="PING_PONG_1_WR_PTR"       pos="17" type="boolean"/>
+		<bitfield name="PING_PONG_2_WR_PTR"       pos="18" type="boolean"/>
+		<bitfield name="PING_PONG_3_WR_PTR"       pos="19" type="boolean"/>
+		<bitfield name="PING_PONG_0_AUTO_REF"     pos="20" type="boolean"/>
+		<bitfield name="PING_PONG_1_AUTO_REF"     pos="21" type="boolean"/>
+		<bitfield name="PING_PONG_2_AUTO_REF"     pos="22" type="boolean"/>
+		<bitfield name="PING_PONG_3_AUTO_REF"     pos="23" type="boolean"/>
+		<bitfield name="INTF0_UNDER_RUN"          pos="24" type="boolean"/>
+		<bitfield name="INTF0_VSYNC"              pos="25" type="boolean"/>
+		<bitfield name="INTF1_UNDER_RUN"          pos="26" type="boolean"/>
+		<bitfield name="INTF1_VSYNC"              pos="27" type="boolean"/>
+		<bitfield name="INTF2_UNDER_RUN"          pos="28" type="boolean"/>
+		<bitfield name="INTF2_VSYNC"              pos="29" type="boolean"/>
+		<bitfield name="INTF3_UNDER_RUN"          pos="30" type="boolean"/>
+		<bitfield name="INTF3_VSYNC"              pos="31" type="boolean"/>
+	</bitset>
+
+	<bitset name="mdp5_smp_alloc" inline="yes">
+        <!-- Use "mdp5_cfg->mdp.smp.clients[enum mdp5_pipe]" instead -->
+		<bitfield name="CLIENT0" low="0"  high="7"  type="uint"/>
+		<bitfield name="CLIENT1" low="8"  high="15" type="uint"/>
+		<bitfield name="CLIENT2" low="16" high="23" type="uint"/>
+	</bitset>
+
+	<reg32 offset="0x00000" name="HW_VERSION">
+		<bitfield name="STEP" low="0" high="15" type="uint"/>
+		<bitfield name="MINOR" low="16" high="27" type="uint"/>
+		<bitfield name="MAJOR" low="28" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00004" name="DISP_INTF_SEL">
+		<bitfield name="INTF0" low="0"  high="7"  type="mdp5_intf_type"/>
+		<bitfield name="INTF1" low="8"  high="15" type="mdp5_intf_type"/>
+		<bitfield name="INTF2" low="16" high="23" type="mdp5_intf_type"/>
+		<bitfield name="INTF3" low="24" high="31" type="mdp5_intf_type"/>
+	</reg32>
+	<reg32 offset="0x00010" name="INTR_EN" type="MDP5_IRQ"/>
+	<reg32 offset="0x00014" name="INTR_STATUS" type="MDP5_IRQ"/>
+	<reg32 offset="0x00018" name="INTR_CLEAR" type="MDP5_IRQ"/>
+	<reg32 offset="0x0001C" name="HIST_INTR_EN"/>
+	<reg32 offset="0x00020" name="HIST_INTR_STATUS"/>
+	<reg32 offset="0x00024" name="HIST_INTR_CLEAR"/>
+	<reg32 offset="0x00028" name="SPARE_0">
+		<bitfield name="SPLIT_DPL_SINGLE_FLUSH_EN" pos="0"/>
+	</reg32>
+
+	<array offset="0x00080" name="SMP_ALLOC_W" length="8" stride="4">
+		<reg32 offset="0" name="REG" type="mdp5_smp_alloc"/>
+	</array>
+	<array offset="0x00130" name="SMP_ALLOC_R" length="8" stride="4">
+		<reg32 offset="0" name="REG" type="mdp5_smp_alloc"/>
+	</array>
+
+	<enum name="mdp5_igc_type">
+		<value name="IGC_VIG" value="0"/>		<!-- 0x200 -->
+		<value name="IGC_RGB" value="1"/>		<!-- 0x210 -->
+		<value name="IGC_DMA" value="2"/>		<!-- 0x220 -->
+		<value name="IGC_DSPP" value="3"/>		<!-- 0x300 -->
+	</enum>
+	<array offsets="0x00200,0x00210,0x00220,0x00300" name="IGC" length="3" stride="0x10" index="mdp5_igc_type">
+		<array offset="0x00" name="LUT" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="VAL" low="0" high="11"/>
+				<bitfield name="INDEX_UPDATE" pos="25" type="boolean"/>
+				<!--
+					not sure about these:
+						/* INDEX_UPDATE */
+						data = (1 << 25) | (((~(1 << blk_idx)) & 0x7) << 28);
+						MDSS_MDP_REG_WRITE(offset, (cfg->c0_c1_data[0] & 0xFFF) | data);
+				-->
+				<bitfield name="DISABLE_PIPE_0" pos="28" type="boolean"/>
+				<bitfield name="DISABLE_PIPE_1" pos="29" type="boolean"/>
+				<bitfield name="DISABLE_PIPE_2" pos="30" type="boolean"/>
+			</reg32>
+		</array>
+	</array>
+	<reg32 offset="0x002f4" name="SPLIT_DPL_EN"/>
+	<reg32 offset="0x002f8" name="SPLIT_DPL_UPPER">
+		<bitfield name="SMART_PANEL" pos="1" type="boolean"/>
+		<bitfield name="SMART_PANEL_FREE_RUN" pos="2" type="boolean"/>
+		<bitfield name="INTF1_SW_TRG_MUX" pos="4" type="boolean"/>
+		<bitfield name="INTF2_SW_TRG_MUX" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x003f0" name="SPLIT_DPL_LOWER">
+		<bitfield name="SMART_PANEL" pos="1" type="boolean"/>
+		<bitfield name="SMART_PANEL_FREE_RUN" pos="2" type="boolean"/>
+		<bitfield name="INTF1_TG_SYNC" pos="4" type="boolean"/>
+		<bitfield name="INTF2_TG_SYNC" pos="8" type="boolean"/>
+	</reg32>
+
+<!-- check length/index.. -->
+	<array doffsets="mdp5_cfg->ctl.base[0],mdp5_cfg->ctl.base[1],mdp5_cfg->ctl.base[2],mdp5_cfg->ctl.base[3],mdp5_cfg->ctl.base[4]" name="CTL" length="5" stride="0x400">
+		<array offsets="0x000,0x004,0x008,0x00C,0x010,0x024" name="LAYER" length="6" stride="4">
+			<!--
+			NOTE: for backwards compat (from when there were fewer stages),
+			this register has the low three bits of mdp_mixer_stage_id, with
+			the high bit coming from LAYER_EXT
+			 -->
+			<reg32 offset="0" name="REG">
+				<bitfield name="VIG0"  low="0"  high="2"  type="uint"/>
+				<bitfield name="VIG1"  low="3"  high="5"  type="uint"/>
+				<bitfield name="VIG2"  low="6"  high="8"  type="uint"/>
+				<bitfield name="RGB0"  low="9"  high="11" type="uint"/>
+				<bitfield name="RGB1"  low="12" high="14" type="uint"/>
+				<bitfield name="RGB2"  low="15" high="17" type="uint"/>
+				<bitfield name="DMA0"  low="18" high="20" type="uint"/>
+				<bitfield name="DMA1"  low="21" high="23" type="uint"/>
+				<bitfield name="BORDER_COLOR" pos="24" type="boolean"/>
+				<bitfield name="CURSOR_OUT"   pos="25" type="boolean"/>
+				<bitfield name="VIG3"  low="26"  high="28"  type="uint"/>
+				<bitfield name="RGB3"  low="29" high="31" type="uint"/>
+			</reg32>
+		</array>
+		<reg32 offset="0x014" name="OP">
+			<bitfield name="MODE" low="0" high="3" type="mdp5_ctl_mode"/>
+			<bitfield name="INTF_NUM" low="4" high="6" type="mdp5_intfnum"/>
+			<bitfield name="CMD_MODE" pos="17" type="boolean"/>
+			<bitfield name="PACK_3D_ENABLE" pos="19" type="boolean"/>
+			<bitfield name="PACK_3D" low="20" high="21" type="mdp5_pack_3d"/>
+		</reg32>
+		<reg32 offset="0x018" name="FLUSH">
+			<bitfield name="VIG0" pos="0"  type="boolean"/>
+			<bitfield name="VIG1" pos="1"  type="boolean"/>
+			<bitfield name="VIG2" pos="2"  type="boolean"/>
+			<bitfield name="RGB0" pos="3"  type="boolean"/>
+			<bitfield name="RGB1" pos="4"  type="boolean"/>
+			<bitfield name="RGB2" pos="5"  type="boolean"/>
+			<bitfield name="LM0"  pos="6"  type="boolean"/>
+			<bitfield name="LM1"  pos="7"  type="boolean"/>
+			<bitfield name="LM2"  pos="8"  type="boolean"/>
+			<bitfield name="LM3"  pos="9"  type="boolean"/>
+			<bitfield name="LM4"  pos="10"  type="boolean"/>
+			<bitfield name="DMA0" pos="11" type="boolean"/>
+			<bitfield name="DMA1" pos="12" type="boolean"/>
+			<bitfield name="DSPP0" pos="13" type="boolean"/>
+			<bitfield name="DSPP1" pos="14" type="boolean"/>
+			<bitfield name="DSPP2" pos="15" type="boolean"/>
+			<bitfield name="WB"   pos="16" type="boolean"/>
+			<bitfield name="CTL"   pos="17" type="boolean"/>
+			<bitfield name="VIG3" pos="18"  type="boolean"/>
+			<bitfield name="RGB3" pos="19"  type="boolean"/>
+			<bitfield name="LM5"  pos="20"  type="boolean"/>
+			<bitfield name="DSPP3" pos="21" type="boolean"/>
+			<bitfield name="CURSOR_0" pos="22" type="boolean"/>
+			<bitfield name="CURSOR_1" pos="23" type="boolean"/>
+			<bitfield name="CHROMADOWN_0" pos="26" type="boolean"/>
+			<bitfield name="TIMING_3" pos="28" type="boolean"/>
+			<bitfield name="TIMING_2" pos="29" type="boolean"/>
+			<bitfield name="TIMING_1" pos="30" type="boolean"/>
+			<bitfield name="TIMING_0" pos="31" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x01C" name="START"/>
+		<reg32 offset="0x020" name="PACK_3D"/>
+		<array offsets="0x040,0x044,0x048,0x04C,0x050,0x054" name="LAYER_EXT" length="6" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="VIG0_BIT3"  pos="0"  type="boolean"/>
+				<bitfield name="VIG1_BIT3"  pos="2"  type="boolean"/>
+				<bitfield name="VIG2_BIT3"  pos="4"  type="boolean"/>
+				<bitfield name="VIG3_BIT3"  pos="6"  type="boolean"/>
+				<bitfield name="RGB0_BIT3"  pos="8"  type="boolean"/>
+				<bitfield name="RGB1_BIT3"  pos="10"  type="boolean"/>
+				<bitfield name="RGB2_BIT3"  pos="12"  type="boolean"/>
+				<bitfield name="RGB3_BIT3"  pos="14"  type="boolean"/>
+				<bitfield name="DMA0_BIT3"  pos="16"  type="boolean"/>
+				<bitfield name="DMA1_BIT3"  pos="18"  type="boolean"/>
+				<bitfield name="CURSOR0" low="20"  high="23"  type="mdp_mixer_stage_id"/>
+				<bitfield name="CURSOR1" low="26"  high="29"  type="mdp_mixer_stage_id"/>
+			</reg32>
+		</array>
+	</array>
+
+	<enum name="mdp5_data_format">
+		<value name="DATA_FORMAT_RGB" value="0"/>
+		<value name="DATA_FORMAT_YUV" value="1"/>
+	</enum>
+
+	<array doffsets="INVALID_IDX(idx),mdp5_cfg->pipe_vig.base[0],mdp5_cfg->pipe_vig.base[1],mdp5_cfg->pipe_vig.base[2],mdp5_cfg->pipe_rgb.base[0],mdp5_cfg->pipe_rgb.base[1],mdp5_cfg->pipe_rgb.base[2],mdp5_cfg->pipe_dma.base[0],mdp5_cfg->pipe_dma.base[1],mdp5_cfg->pipe_vig.base[3],mdp5_cfg->pipe_rgb.base[3],mdp5_cfg->pipe_cursor.base[0],mdp5_cfg->pipe_cursor.base[1]" name="PIPE" length="10" stride="0x400" index="mdp5_pipe">
+		<reg32 offset="0x200" name="OP_MODE">
+			<bitfield name="CSC_DST_DATA_FORMAT" pos="19" type="mdp5_data_format"/>
+			<bitfield name="CSC_SRC_DATA_FORMAT" pos="18" type="mdp5_data_format"/>
+			<bitfield name="CSC_1_EN" pos="17" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x2C4" name="HIST_CTL_BASE"/>
+		<reg32 offset="0x2F0" name="HIST_LUT_BASE"/>
+		<reg32 offset="0x300" name="HIST_LUT_SWAP"/>
+		<reg32 offset="0x320" name="CSC_1_MATRIX_COEFF_0">
+			<bitfield name="COEFF_11" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_12" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x324" name="CSC_1_MATRIX_COEFF_1">
+			<bitfield name="COEFF_13" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_21" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x328" name="CSC_1_MATRIX_COEFF_2">
+			<bitfield name="COEFF_22" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_23" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x32c" name="CSC_1_MATRIX_COEFF_3">
+			<bitfield name="COEFF_31" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_32" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x330" name="CSC_1_MATRIX_COEFF_4">
+			<bitfield name="COEFF_33" low="0" high="12" type="uint"/>
+		</reg32>
+		<array offset="0x334" name="CSC_1_PRE_CLAMP" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="HIGH"  low="0"  high="7"  type="uint"/>
+				<bitfield name="LOW"  low="8"  high="15"  type="uint"/>
+			</reg32>
+		</array>
+		<array offset="0x340" name="CSC_1_POST_CLAMP" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="HIGH"  low="0"  high="7"  type="uint"/>
+				<bitfield name="LOW"  low="8"  high="15"  type="uint"/>
+			</reg32>
+		</array>
+		<array offset="0x34c" name="CSC_1_PRE_BIAS" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="VALUE"  low="0"  high="8"  type="uint"/>
+			</reg32>
+		</array>
+		<array offset="0x358" name="CSC_1_POST_BIAS" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="VALUE"  low="0"  high="8"  type="uint"/>
+			</reg32>
+		</array>
+		<!-- SSPP: -->
+		<reg32 offset="0x000" name="SRC_SIZE" type="reg_wh"/>
+		<reg32 offset="0x004" name="SRC_IMG_SIZE" type="reg_wh"/>
+		<reg32 offset="0x008" name="SRC_XY" type="reg_xy"/>
+		<reg32 offset="0x00C" name="OUT_SIZE" type="reg_wh"/>
+		<reg32 offset="0x010" name="OUT_XY" type="reg_xy"/>
+		<reg32 offset="0x014" name="SRC0_ADDR"/>
+		<reg32 offset="0x018" name="SRC1_ADDR"/>
+		<reg32 offset="0x01C" name="SRC2_ADDR"/>
+		<reg32 offset="0x020" name="SRC3_ADDR"/>
+		<reg32 offset="0x024" name="SRC_STRIDE_A">
+			<bitfield name="P0" low="0" high="15" type="uint"/>
+			<bitfield name="P1" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x028" name="SRC_STRIDE_B">
+			<bitfield name="P2" low="0" high="15" type="uint"/>
+			<bitfield name="P3" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x02C" name="STILE_FRAME_SIZE"/>
+		<reg32 offset="0x030" name="SRC_FORMAT">
+			<bitfield name="G_BPC" low="0" high="1" type="mdp_bpc"/>
+			<bitfield name="B_BPC" low="2" high="3" type="mdp_bpc"/>
+			<bitfield name="R_BPC" low="4" high="5" type="mdp_bpc"/>
+			<bitfield name="A_BPC" low="6" high="7" type="mdp_bpc_alpha"/>
+			<bitfield name="ALPHA_ENABLE" pos="8" type="boolean"/>
+			<bitfield name="CPP" low="9" high="10" type="uint">
+				<brief>8bit characters per pixel minus 1</brief>
+			</bitfield>
+			<bitfield name="ROT90" pos="11" type="boolean"/>
+			<bitfield name="UNPACK_COUNT" low="12" high="13" type="uint"/>
+			<bitfield name="UNPACK_TIGHT" pos="17" type="boolean"/>
+			<bitfield name="UNPACK_ALIGN_MSB" pos="18" type="boolean"/>
+			<bitfield name="FETCH_TYPE" low="19" high="20" type="mdp_fetch_type"/>
+			<bitfield name="CHROMA_SAMP" low="23" high="24" type="mdp_chroma_samp_type"/>
+		</reg32>
+		<reg32 offset="0x034" name="SRC_UNPACK" type="mdp_unpack_pattern"/>
+		<reg32 offset="0x038" name="SRC_OP_MODE">
+			<bitfield name="BWC_EN" pos="0" type="boolean"/>
+			<bitfield name="BWC" low="1" high="2" type="mdp5_pipe_bwc"/>
+			<bitfield name="FLIP_LR" pos="13" type="boolean"/>
+			<bitfield name="FLIP_UD" pos="14" type="boolean"/>
+			<bitfield name="IGC_EN" pos="16" type="boolean"/>
+			<bitfield name="IGC_ROM_0" pos="17" type="boolean"/>
+			<bitfield name="IGC_ROM_1" pos="18" type="boolean"/>
+			<bitfield name="DEINTERLACE" pos="22" type="boolean"/>
+			<bitfield name="DEINTERLACE_ODD" pos="23" type="boolean"/>
+			<bitfield name="SW_PIX_EXT_OVERRIDE" pos="31" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x03c" name="SRC_CONSTANT_COLOR"/>
+		<reg32 offset="0x048" name="FETCH_CONFIG"/>
+		<reg32 offset="0x04c" name="VC1_RANGE"/>
+		<reg32 offset="0x050" name="REQPRIO_FIFO_WM_0"/>
+		<reg32 offset="0x054" name="REQPRIO_FIFO_WM_1"/>
+		<reg32 offset="0x058" name="REQPRIO_FIFO_WM_2"/>
+		<reg32 offset="0x070" name="SRC_ADDR_SW_STATUS"/>
+		<reg32 offset="0x0a4" name="CURRENT_SRC0_ADDR"/>
+		<reg32 offset="0x0a8" name="CURRENT_SRC1_ADDR"/>
+		<reg32 offset="0x0ac" name="CURRENT_SRC2_ADDR"/>
+		<reg32 offset="0x0b0" name="CURRENT_SRC3_ADDR"/>
+		<reg32 offset="0x0b4" name="DECIMATION">
+			<bitfield name="VERT" low="0" high="7" type="uint"/>
+			<bitfield name="HORZ" low="8" high="15" type="uint"/>
+		</reg32>
+		<array offsets="0x100,0x110,0x120" name="SW_PIX_EXT" length="3" stride="0x10" index="mdp_component_type">
+			<!--
+				Notes:
+				o These value only take effect if SW_PIX_EXT_OVERRIDE is set in SRC_OP_MODE register
+				o For signed values (int): + indicates overfetch, - indicates line drop
+			-->
+                        <reg32 offset="0x00" name="LR">
+				<bitfield name="LEFT_RPT" low="0" high="7" type="uint"/>
+				<bitfield name="LEFT_OVF" low="8" high="15" type="int"/>
+				<bitfield name="RIGHT_RPT" low="16" high="23" type="uint"/>
+				<bitfield name="RIGHT_OVF" low="24" high="31" type="int"/>
+			</reg32>
+			<reg32 offset="0x04" name="TB">
+				<bitfield name="TOP_RPT" low="0" high="7" type="uint"/>
+				<bitfield name="TOP_OVF" low="8" high="15" type="int"/>
+				<bitfield name="BOTTOM_RPT" low="16" high="23" type="uint"/>
+				<bitfield name="BOTTOM_OVF" low="24" high="31" type="int"/>
+			</reg32>
+			<reg32 offset="0x08" name="REQ_PIXELS">
+				<bitfield name="LEFT_RIGHT" low="0" high="15" type="uint"/>
+				<bitfield name="TOP_BOTTOM" low="16" high="31" type="uint"/>
+			</reg32>
+		</array>
+		<reg32 offset="0x204" name="SCALE_CONFIG">
+			<bitfield name="SCALEX_EN" pos="0" type="boolean"/>
+			<bitfield name="SCALEY_EN" pos="1" type="boolean"/>
+			<bitfield name="SCALEX_FILTER_COMP_0" low="8"  high="9"  type="mdp5_scale_filter"/>
+			<bitfield name="SCALEY_FILTER_COMP_0" low="10" high="11" type="mdp5_scale_filter"/>
+			<bitfield name="SCALEX_FILTER_COMP_1_2"  low="12" high="13" type="mdp5_scale_filter"/>
+			<bitfield name="SCALEY_FILTER_COMP_1_2"  low="14" high="15" type="mdp5_scale_filter"/>
+			<bitfield name="SCALEX_FILTER_COMP_3" low="16" high="17" type="mdp5_scale_filter"/>
+			<bitfield name="SCALEY_FILTER_COMP_3" low="18" high="19" type="mdp5_scale_filter"/>
+		</reg32>
+		<reg32 offset="0x210" name="SCALE_PHASE_STEP_X"/>
+		<reg32 offset="0x214" name="SCALE_PHASE_STEP_Y"/>
+		<reg32 offset="0x218" name="SCALE_CR_PHASE_STEP_X"/>
+		<reg32 offset="0x21c" name="SCALE_CR_PHASE_STEP_Y"/>
+		<reg32 offset="0x220" name="SCALE_INIT_PHASE_X"/>
+		<reg32 offset="0x224" name="SCALE_INIT_PHASE_Y"/>
+	</array>
+
+	<array doffsets="mdp5_cfg->lm.base[0],mdp5_cfg->lm.base[1],mdp5_cfg->lm.base[2],mdp5_cfg->lm.base[3],mdp5_cfg->lm.base[4],mdp5_cfg->lm.base[5]" name="LM" length="6" stride="0x400">
+		<reg32 offset="0x000" name="BLEND_COLOR_OUT">
+			<bitfield name="STAGE0_FG_ALPHA" pos="1" type="boolean"/>
+			<bitfield name="STAGE1_FG_ALPHA" pos="2" type="boolean"/>
+			<bitfield name="STAGE2_FG_ALPHA" pos="3" type="boolean"/>
+			<bitfield name="STAGE3_FG_ALPHA" pos="4" type="boolean"/>
+			<bitfield name="STAGE4_FG_ALPHA" pos="5" type="boolean"/>
+			<bitfield name="STAGE5_FG_ALPHA" pos="6" type="boolean"/>
+			<bitfield name="STAGE6_FG_ALPHA" pos="7" type="boolean"/>
+			<bitfield name="SPLIT_LEFT_RIGHT" pos="31" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x004" name="OUT_SIZE" type="reg_wh"/>
+		<reg32 offset="0x008" name="BORDER_COLOR_0"/>
+		<reg32 offset="0x010" name="BORDER_COLOR_1"/>
+		<array offsets="0x020,0x050,0x080,0x0B0,0x230,0x260,0x290" name="BLEND" length="7" stride="0x30">
+			<reg32 offset="0x00" name="OP_MODE">
+				<bitfield name="FG_ALPHA" low="0" high="1" type="mdp_alpha_type"/>
+				<bitfield name="FG_INV_ALPHA"     pos="2"  type="boolean"/>
+				<bitfield name="FG_MOD_ALPHA"     pos="3"  type="boolean"/>
+				<bitfield name="FG_INV_MOD_ALPHA" pos="4"  type="boolean"/>
+				<bitfield name="FG_TRANSP_EN"     pos="5"  type="boolean"/>
+				<bitfield name="BG_ALPHA" low="8" high="9" type="mdp_alpha_type"/>
+				<bitfield name="BG_INV_ALPHA"     pos="10" type="boolean"/>
+				<bitfield name="BG_MOD_ALPHA"     pos="11" type="boolean"/>
+				<bitfield name="BG_INV_MOD_ALPHA" pos="12" type="boolean"/>
+				<bitfield name="BG_TRANSP_EN"     pos="13" type="boolean"/>
+			</reg32>
+			<reg32 offset="0x04" name="FG_ALPHA"/>
+			<reg32 offset="0x08" name="BG_ALPHA"/>
+			<reg32 offset="0x0c" name="FG_TRANSP_LOW0"/>
+			<reg32 offset="0x10" name="FG_TRANSP_LOW1"/>
+			<reg32 offset="0x14" name="FG_TRANSP_HIGH0"/>
+			<reg32 offset="0x18" name="FG_TRANSP_HIGH1"/>
+			<reg32 offset="0x1c" name="BG_TRANSP_LOW0"/>
+			<reg32 offset="0x20" name="BG_TRANSP_LOW1"/>
+			<reg32 offset="0x24" name="BG_TRANSP_HIGH0"/>
+			<reg32 offset="0x28" name="BG_TRANSP_HIGH1"/>
+		</array>
+		<reg32 offset="0x0e0" name="CURSOR_IMG_SIZE">
+			<bitfield name="SRC_W" low="0" high="15" type="uint"/>
+			<bitfield name="SRC_H" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0e4" name="CURSOR_SIZE">
+			<bitfield name="ROI_W" low="0" high="15" type="uint"/>
+			<bitfield name="ROI_H" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0e8" name="CURSOR_XY">
+			<bitfield name="SRC_X" low="0" high="15" type="uint"/>
+			<bitfield name="SRC_Y" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0dc" name="CURSOR_STRIDE">
+			<bitfield name="STRIDE" low="0"  high="15"  type="uint"/>
+		</reg32>
+		<reg32 offset="0x0ec" name="CURSOR_FORMAT">
+			<bitfield name="FORMAT" low="0"  high="2"  type="mdp5_cursor_format"/>
+		</reg32>
+		<reg32 offset="0x0f0" name="CURSOR_BASE_ADDR"/>
+		<reg32 offset="0x0f4" name="CURSOR_START_XY">
+			<bitfield name="X_START" low="0" high="15" type="uint"/>
+			<bitfield name="Y_START" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0f8" name="CURSOR_BLEND_CONFIG">
+			<bitfield name="BLEND_EN" pos="0" type="boolean"/>
+			<bitfield name="BLEND_ALPHA_SEL" low="1"  high="2"  type="mdp5_cursor_alpha"/>
+			<bitfield name="BLEND_TRANSP_EN" pos="3" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x0fc" name="CURSOR_BLEND_PARAM"/>
+		<reg32 offset="0x100" name="CURSOR_BLEND_TRANSP_LOW0"/>
+		<reg32 offset="0x104" name="CURSOR_BLEND_TRANSP_LOW1"/>
+		<reg32 offset="0x108" name="CURSOR_BLEND_TRANSP_HIGH0"/>
+		<reg32 offset="0x10c" name="CURSOR_BLEND_TRANSP_HIGH1"/>
+		<reg32 offset="0x110" name="GC_LUT_BASE"/>
+	</array>
+
+	<array doffsets="mdp5_cfg->dspp.base[0],mdp5_cfg->dspp.base[1],mdp5_cfg->dspp.base[2],mdp5_cfg->dspp.base[3]" name="DSPP" length="4" stride="0x400">
+		<reg32 offset="0x000" name="OP_MODE">
+			<bitfield name="IGC_LUT_EN" pos="0" type="boolean"/>
+			<bitfield name="IGC_TBL_IDX" low="1" high="3" type="uint"/>
+			<bitfield name="PCC_EN" pos="4" type="boolean"/>
+			<bitfield name="DITHER_EN" pos="8" type="boolean"/>
+			<bitfield name="HIST_EN" pos="16" type="boolean"/>
+			<bitfield name="AUTO_CLEAR" pos="17" type="boolean"/>
+			<bitfield name="HIST_LUT_EN" pos="19" type="boolean"/>
+			<bitfield name="PA_EN" pos="20" type="boolean"/>
+			<bitfield name="GAMUT_EN" pos="23" type="boolean"/>
+			<bitfield name="GAMUT_ORDER" pos="24" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x030" name="PCC_BASE"/>
+		<reg32 offset="0x150" name="DITHER_DEPTH"/>
+		<reg32 offset="0x210" name="HIST_CTL_BASE"/>
+		<reg32 offset="0x230" name="HIST_LUT_BASE"/>
+		<reg32 offset="0x234" name="HIST_LUT_SWAP"/>
+		<reg32 offset="0x238" name="PA_BASE"/>
+		<reg32 offset="0x2dc" name="GAMUT_BASE"/>
+		<reg32 offset="0x2b0" name="GC_BASE"/>
+	</array>
+
+	<array doffsets="mdp5_cfg->pp.base[0],mdp5_cfg->pp.base[1],mdp5_cfg->pp.base[2],mdp5_cfg->pp.base[3]" name="PP" length="4" stride="0x100">
+		<reg32 offset="0x000" name="TEAR_CHECK_EN"/>
+		<reg32 offset="0x004" name="SYNC_CONFIG_VSYNC">
+			<bitfield name="COUNT" low="0" high="18" type="uint"/>
+			<bitfield name="COUNTER_EN" pos="19" type="boolean"/>
+			<bitfield name="IN_EN" pos="20" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x008" name="SYNC_CONFIG_HEIGHT"/>
+		<reg32 offset="0x00c" name="SYNC_WRCOUNT">
+			<bitfield name="LINE_COUNT" low="0" high="15" type="uint"/>
+			<bitfield name="FRAME_COUNT" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x010" name="VSYNC_INIT_VAL"/>
+		<reg32 offset="0x014" name="INT_COUNT_VAL">
+			<bitfield name="LINE_COUNT" low="0" high="15" type="uint"/>
+			<bitfield name="FRAME_COUNT" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x018" name="SYNC_THRESH">
+			<bitfield name="START" low="0" high="15" type="uint"/>
+			<bitfield name="CONTINUE" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x01c" name="START_POS"/>
+		<reg32 offset="0x020" name="RD_PTR_IRQ"/>
+		<reg32 offset="0x024" name="WR_PTR_IRQ"/>
+		<reg32 offset="0x028" name="OUT_LINE_COUNT"/>
+		<reg32 offset="0x02c" name="PP_LINE_COUNT"/>
+		<reg32 offset="0x030" name="AUTOREFRESH_CONFIG"/>
+		<reg32 offset="0x034" name="FBC_MODE"/>
+		<reg32 offset="0x038" name="FBC_BUDGET_CTL"/>
+		<reg32 offset="0x03c" name="FBC_LOSSY_MODE"/>
+	</array>
+
+	<enum name="mdp5_block_size">
+		<value name="BLOCK_SIZE_64" value="0"/>
+		<value name="BLOCK_SIZE_128" value="1"/>
+	</enum>
+
+	<enum name="mdp5_rotate_mode">
+		<value name="ROTATE_0" value="0"/>
+		<value name="ROTATE_90" value="1"/>
+	</enum>
+
+	<enum name="mdp5_chroma_downsample_method">
+		<value name="DS_MTHD_NO_PIXEL_DROP" value="0"/>
+		<value name="DS_MTHD_PIXEL_DROP" value="1"/>
+	</enum>
+
+	<array doffsets="mdp5_cfg->wb.base[0],mdp5_cfg->wb.base[1],mdp5_cfg->wb.base[2],mdp5_cfg->wb.base[3],mdp5_cfg->wb.base[4]" name="WB" length="5" stride="0x400">
+		<reg32 offset="0x000" name="DST_FORMAT">
+			<bitfield name="DSTC0_OUT" low="0" high="1" type="uint"/>
+			<bitfield name="DSTC1_OUT" low="2" high="3" type="uint"/>
+			<bitfield name="DSTC2_OUT" low="4" high="5" type="uint"/>
+			<bitfield name="DSTC3_OUT" low="6" high="7" type="uint"/>
+			<bitfield name="DSTC3_EN" pos="8" type="boolean"/>
+			<bitfield name="DST_BPP" low="9" high="10" type="uint"/>
+			<bitfield name="PACK_COUNT" low="12" high="13" type="uint"/>
+			<bitfield name="DST_ALPHA_X" pos="14" type="boolean"/>
+			<bitfield name="PACK_TIGHT" pos="17" type="boolean"/>
+			<bitfield name="PACK_ALIGN_MSB" pos="18" type="boolean"/>
+			<bitfield name="WRITE_PLANES" low="19" high="20" type="uint"/>
+			<bitfield name="DST_DITHER_EN" pos="22" type="boolean"/>
+			<bitfield name="DST_CHROMA_SAMP" low="23" high="25" type="uint"/>
+			<bitfield name="DST_CHROMA_SITE" low="26" high="29" type="uint"/>
+			<bitfield name="FRAME_FORMAT" low="30" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x004" name="DST_OP_MODE">
+			<bitfield name="BWC_ENC_EN" pos="0" type="boolean"/>
+			<bitfield name="BWC_ENC_OP" low="1" high="2" type="uint"/>
+			<bitfield name="BLOCK_SIZE" low="4" high="4" type="uint"/>
+			<bitfield name="ROT_MODE" low="5" high="5" type="uint"/>
+			<bitfield name="ROT_EN" pos="6" type="boolean"/>
+			<bitfield name="CSC_EN" pos="8" type="boolean"/>
+			<bitfield name="CSC_SRC_DATA_FORMAT" low="9" high="9" type="uint"/>
+			<bitfield name="CSC_DST_DATA_FORMAT" low="10" high="10" type="uint"/>
+			<bitfield name="CHROMA_DWN_SAMPLE_EN" pos="11" type="boolean"/>
+			<bitfield name="CHROMA_DWN_SAMPLE_FORMAT" low="12" high="12" type="uint"/>
+			<bitfield name="CHROMA_DWN_SAMPLE_H_MTHD" low="13" high="13" type="uint"/>
+			<bitfield name="CHROMA_DWN_SAMPLE_V_MTHD" low="14" high="14" type="uint"/>
+		</reg32>
+		<reg32 offset="0x008" name="DST_PACK_PATTERN">
+			<bitfield name="ELEMENT0" low="0" high="1" type="uint"/>
+			<bitfield name="ELEMENT1" low="8" high="9" type="uint"/>
+			<bitfield name="ELEMENT2" low="16" high="17" type="uint"/>
+			<bitfield name="ELEMENT3" low="24" high="25" type="uint"/>
+		</reg32>
+		<reg32 offset="0x00c" name="DST0_ADDR"/>
+		<reg32 offset="0x010" name="DST1_ADDR"/>
+		<reg32 offset="0x014" name="DST2_ADDR"/>
+		<reg32 offset="0x018" name="DST3_ADDR"/>
+		<reg32 offset="0x01c" name="DST_YSTRIDE0">
+			<bitfield name="DST0_YSTRIDE" low="0" high="15" type="uint"/>
+			<bitfield name="DST1_YSTRIDE" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x020" name="DST_YSTRIDE1">
+			<bitfield name="DST2_YSTRIDE" low="0" high="15" type="uint"/>
+			<bitfield name="DST3_YSTRIDE" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x024" name="DST_DITHER_BITDEPTH"/>
+		<reg32 offset="0x030" name="DITHER_MATRIX_ROW0"/>
+		<reg32 offset="0x034" name="DITHER_MATRIX_ROW1"/>
+		<reg32 offset="0x038" name="DITHER_MATRIX_ROW2"/>
+		<reg32 offset="0x03c" name="DITHER_MATRIX_ROW3"/>
+		<reg32 offset="0x048" name="DST_WRITE_CONFIG"/>
+		<reg32 offset="0x050" name="ROTATION_DNSCALER"/>
+		<reg32 offset="0x060" name="N16_INIT_PHASE_X_0_3"/>
+		<reg32 offset="0x064" name="N16_INIT_PHASE_X_1_2"/>
+		<reg32 offset="0x068" name="N16_INIT_PHASE_Y_0_3"/>
+		<reg32 offset="0x06c" name="N16_INIT_PHASE_Y_1_2"/>
+		<reg32 offset="0x074" name="OUT_SIZE">
+			<bitfield name="DST_W" low="0" high="15" type="uint"/>
+			<bitfield name="DST_H" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x078" name="ALPHA_X_VALUE"/>
+		<reg32 offset="0x260" name="CSC_MATRIX_COEFF_0">
+			<bitfield name="COEFF_11" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_12" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x264" name="CSC_MATRIX_COEFF_1">
+			<bitfield name="COEFF_13" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_21" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x268" name="CSC_MATRIX_COEFF_2">
+			<bitfield name="COEFF_22" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_23" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x26c" name="CSC_MATRIX_COEFF_3">
+			<bitfield name="COEFF_31" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_32" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x270" name="CSC_MATRIX_COEFF_4">
+			<bitfield name="COEFF_33" low="0" high="12" type="uint"/>
+		</reg32>
+		<array offset="0x274" name="CSC_COMP_PRECLAMP" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="HIGH"  low="0"  high="7"  type="uint"/>
+				<bitfield name="LOW"  low="8"  high="15"  type="uint"/>
+			</reg32>
+		</array>
+		<array offset="0x280" name="CSC_COMP_POSTCLAMP" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="HIGH"  low="0"  high="7"  type="uint"/>
+				<bitfield name="LOW"  low="8"  high="15"  type="uint"/>
+			</reg32>
+		</array>
+		<array offset="0x28c" name="CSC_COMP_PREBIAS" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="VALUE"  low="0"  high="8"  type="uint"/>
+			</reg32>
+		</array>
+		<array offset="0x298" name="CSC_COMP_POSTBIAS" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="VALUE"  low="0"  high="8"  type="uint"/>
+			</reg32>
+		</array>
+	</array>
+
+	<array doffsets="mdp5_cfg->intf.base[0],mdp5_cfg->intf.base[1],mdp5_cfg->intf.base[2],mdp5_cfg->intf.base[3],mdp5_cfg->intf.base[4]" name="INTF" length="5" stride="0x200">
+		<reg32 offset="0x000" name="TIMING_ENGINE_EN"/>
+		<reg32 offset="0x004" name="CONFIG"/>
+		<reg32 offset="0x008" name="HSYNC_CTL">
+			<bitfield name="PULSEW" low="0" high="15" type="uint"/>
+			<bitfield name="PERIOD" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x00c" name="VSYNC_PERIOD_F0" type="uint"/>
+		<reg32 offset="0x010" name="VSYNC_PERIOD_F1" type="uint"/>
+		<reg32 offset="0x014" name="VSYNC_LEN_F0" type="uint"/>
+		<reg32 offset="0x018" name="VSYNC_LEN_F1" type="uint"/>
+		<reg32 offset="0x01c" name="DISPLAY_VSTART_F0" type="uint"/>
+		<reg32 offset="0x020" name="DISPLAY_VSTART_F1" type="uint"/>
+		<reg32 offset="0x024" name="DISPLAY_VEND_F0" type="uint"/>
+		<reg32 offset="0x028" name="DISPLAY_VEND_F1" type="uint"/>
+		<reg32 offset="0x02c" name="ACTIVE_VSTART_F0">
+			<bitfield name="VAL" low="0" high="30" type="uint"/>
+			<bitfield name="ACTIVE_V_ENABLE" pos="31" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x030" name="ACTIVE_VSTART_F1">
+			<bitfield name="VAL" low="0" high="30" type="uint"/>
+		</reg32>
+		<reg32 offset="0x034" name="ACTIVE_VEND_F0" type="uint"/>
+		<reg32 offset="0x038" name="ACTIVE_VEND_F1" type="uint"/>
+		<reg32 offset="0x03c" name="DISPLAY_HCTL">
+			<bitfield name="START" low="0"  high="15" type="uint"/>
+			<bitfield name="END"   low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x040" name="ACTIVE_HCTL">
+			<bitfield name="START" low="0"  high="14" type="uint"/>
+			<bitfield name="END"   low="16" high="30" type="uint"/>
+			<bitfield name="ACTIVE_H_ENABLE" pos="31" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x044" name="BORDER_COLOR"/>
+		<reg32 offset="0x048" name="UNDERFLOW_COLOR"/>
+		<reg32 offset="0x04c" name="HSYNC_SKEW"/>
+		<reg32 offset="0x050" name="POLARITY_CTL">
+			<bitfield name="HSYNC_LOW" pos="0" type="boolean"/>
+			<bitfield name="VSYNC_LOW" pos="1" type="boolean"/>
+			<bitfield name="DATA_EN_LOW" pos="2" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x054" name="TEST_CTL"/>
+		<reg32 offset="0x058" name="TP_COLOR0"/>
+		<reg32 offset="0x05c" name="TP_COLOR1"/>
+		<reg32 offset="0x084" name="DSI_CMD_MODE_TRIGGER_EN"/>
+		<reg32 offset="0x090" name="PANEL_FORMAT" type="mdp5_format"/>
+		<reg32 offset="0x0a8" name="FRAME_LINE_COUNT_EN"/>
+		<reg32 offset="0x0ac" name="FRAME_COUNT"/>
+		<reg32 offset="0x0b0" name="LINE_COUNT"/>
+		<reg32 offset="0x0f0" name="DEFLICKER_CONFIG"/>
+		<reg32 offset="0x0f4" name="DEFLICKER_STRNG_COEFF"/>
+		<reg32 offset="0x0f8" name="DEFLICKER_WEAK_COEFF"/>
+		<reg32 offset="0x100" name="TPG_ENABLE"/>
+		<reg32 offset="0x104" name="TPG_MAIN_CONTROL"/>
+		<reg32 offset="0x108" name="TPG_VIDEO_CONFIG"/>
+		<reg32 offset="0x10c" name="TPG_COMPONENT_LIMITS"/>
+		<reg32 offset="0x110" name="TPG_RECTANGLE"/>
+		<reg32 offset="0x114" name="TPG_INITIAL_VALUE"/>
+		<reg32 offset="0x118" name="TPG_BLK_WHITE_PATTERN_FRAME"/>
+		<reg32 offset="0x11c" name="TPG_RGB_MAPPING"/>
+	</array>
+
+	<array doffsets="mdp5_cfg->ad.base[0],mdp5_cfg->ad.base[1]" name="AD" length="2" stride="0x200">
+		<reg32 offset="0x000" name="BYPASS"/>
+		<reg32 offset="0x004" name="CTRL_0"/>
+		<reg32 offset="0x008" name="CTRL_1"/>
+		<reg32 offset="0x00c" name="FRAME_SIZE"/>
+		<reg32 offset="0x010" name="CON_CTRL_0"/>
+		<reg32 offset="0x014" name="CON_CTRL_1"/>
+		<reg32 offset="0x018" name="STR_MAN"/>
+		<reg32 offset="0x01c" name="VAR"/>
+		<reg32 offset="0x020" name="DITH"/>
+		<reg32 offset="0x024" name="DITH_CTRL"/>
+		<reg32 offset="0x028" name="AMP_LIM"/>
+		<reg32 offset="0x02c" name="SLOPE"/>
+		<reg32 offset="0x030" name="BW_LVL"/>
+		<reg32 offset="0x034" name="LOGO_POS"/>
+		<reg32 offset="0x038" name="LUT_FI"/>
+		<reg32 offset="0x07c" name="LUT_CC"/>
+		<reg32 offset="0x0c8" name="STR_LIM"/>
+		<reg32 offset="0x0cc" name="CALIB_AB"/>
+		<reg32 offset="0x0d0" name="CALIB_CD"/>
+		<reg32 offset="0x0d4" name="MODE_SEL"/>
+		<reg32 offset="0x0d8" name="TFILT_CTRL"/>
+		<reg32 offset="0x0dc" name="BL_MINMAX"/>
+		<reg32 offset="0x0e0" name="BL"/>
+		<reg32 offset="0x0e8" name="BL_MAX"/>
+		<reg32 offset="0x0ec" name="AL"/>
+		<reg32 offset="0x0f0" name="AL_MIN"/>
+		<reg32 offset="0x0f4" name="AL_FILT"/>
+		<reg32 offset="0x0f8" name="CFG_BUF"/>
+		<reg32 offset="0x100" name="LUT_AL"/>
+		<reg32 offset="0x144" name="TARG_STR"/>
+		<reg32 offset="0x148" name="START_CALC"/>
+		<reg32 offset="0x14c" name="STR_OUT"/>
+		<reg32 offset="0x154" name="BL_OUT"/>
+		<reg32 offset="0x158" name="CALC_DONE"/>
+	</array>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/mdp_common.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/mdp_common.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+
+<!-- random bits that seem same between mdp4 and mdp5 (ie. not much) -->
+
+<enum name="mdp_chroma_samp_type">
+    <value name="CHROMA_FULL"  value="0"/>
+    <value name="CHROMA_H2V1" value="1"/>
+    <value name="CHROMA_H1V2" value="2"/>
+    <value name="CHROMA_420"  value="3"/>
+</enum>
+
+<enum name="mdp_fetch_type">
+    <value name="MDP_PLANE_INTERLEAVED"   value="0"/>
+    <value name="MDP_PLANE_PLANAR"        value="1"/>
+    <value name="MDP_PLANE_PSEUDO_PLANAR" value="2"/>
+</enum>
+
+<enum name="mdp_mixer_stage_id">
+	<value name="STAGE_UNUSED" value="0"/>
+	<value name="STAGE_BASE" value="1"/>
+	<value name="STAGE0" value="2"/>   <!-- zorder 0 -->
+	<value name="STAGE1" value="3"/>   <!-- zorder 1 -->
+	<value name="STAGE2" value="4"/>   <!-- zorder 2 -->
+	<value name="STAGE3" value="5"/>   <!-- zorder 3 -->
+	<value name="STAGE4" value="6"/>   <!-- zorder 4 -->
+	<value name="STAGE5" value="7"/>   <!-- zorder 5 -->
+	<value name="STAGE6" value="8"/>   <!-- zorder 6 -->
+	<value name="STAGE_MAX" value="8"/> <!-- maximum zorder -->
+</enum>
+
+<enum name="mdp_alpha_type">
+	<value name="FG_CONST" value="0"/>
+	<value name="BG_CONST" value="1"/>
+	<value name="FG_PIXEL" value="2"/>
+	<value name="BG_PIXEL" value="3"/>
+</enum>
+
+<enum name="mdp_component_type">
+        <value name="COMP_0" value="0"/>	<!-- Y component -->
+        <value name="COMP_1_2" value="1"/>	<!-- Cb/Cr comp. -->
+        <value name="COMP_3" value="2"/>	<!-- Trans comp. -->
+        <value name="COMP_MAX" value="3"/>
+</enum>
+
+<enum name="mdp_bpc">
+	<brief>bits per component (non-alpha channel)</brief>
+	<value name="BPC4" value="0"/> <!-- 4 bits -->
+	<value name="BPC5" value="1"/> <!-- 5 bits -->
+	<value name="BPC6" value="2"/> <!-- 6 bits -->
+	<value name="BPC8" value="3"/> <!-- 8 bits -->
+</enum>
+
+<enum name="mdp_bpc_alpha">
+	<brief>bits per component (alpha channel)</brief>
+	<value name="BPC1A" value="0"/> <!-- 1 bit -->
+	<value name="BPC4A" value="1"/> <!-- 4 bits -->
+	<value name="BPC6A" value="2"/> <!-- 6 bits -->
+	<value name="BPC8A" value="3"/> <!-- 8 bits -->
+</enum>
+
+<enum name="mdp_fetch_mode">
+	<value name="MDP_FETCH_LINEAR" value="0"/>
+	<value name="MDP_FETCH_TILE" value="1"/>
+	<value name="MDP_FETCH_UBWC" value="2"/>
+</enum>
+
+<bitset name="reg_wh" inline="yes">
+    <bitfield name="HEIGHT" low="16" high="31" type="uint"/>
+    <bitfield name="WIDTH" low="0" high="15" type="uint"/>
+</bitset>
+
+<bitset name="reg_xy" inline="yes">
+    <bitfield name="Y" low="16" high="31" type="uint"/>
+    <bitfield name="X" low="0" high="15" type="uint"/>
+</bitset>
+
+<bitset name="mdp_unpack_pattern" inline="yes">
+	<bitfield name="ELEM0" low="0"  high="7"/>
+	<bitfield name="ELEM1" low="8"  high="15"/>
+	<bitfield name="ELEM2" low="16" high="23"/>
+	<bitfield name="ELEM3" low="24" high="31"/>
+</bitset>
+
+</database>
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/mdss.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/mdss.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="MDSS" width="32">
+	<reg32 offset="0x00000" name="HW_VERSION">
+		<bitfield name="STEP" low="0" high="15" type="uint"/>
+		<bitfield name="MINOR" low="16" high="27" type="uint"/>
+		<bitfield name="MAJOR" low="28" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00010" name="HW_INTR_STATUS">
+		<bitfield name="INTR_MDP"  pos="0"  type="boolean"/>
+		<bitfield name="INTR_DSI0" pos="4"  type="boolean"/>
+		<bitfield name="INTR_DSI1" pos="5"  type="boolean"/>
+		<bitfield name="INTR_HDMI" pos="8"  type="boolean"/>
+		<bitfield name="INTR_EDP"  pos="12" type="boolean"/>
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/msm.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/msm.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<doc>
+	Register definitions for the display related hw blocks on
+	msm/snapdragon
+</doc>
+
+<!--
+<enum name="chipset">
+	<value name="MDP40"/>
+	<value name="MDP50"/>
+</enum>
+-->
+
+<import file="mdp4.xml"/>
+<import file="mdp5.xml"/>
+<import file="dsi.xml"/>
+<import file="dsi_phy_28nm_8960.xml"/>
+<import file="dsi_phy_28nm.xml"/>
+<import file="dsi_phy_20nm.xml"/>
+<import file="dsi_phy_14nm.xml"/>
+<import file="dsi_phy_10nm.xml"/>
+<import file="dsi_phy_7nm.xml"/>
+<import file="sfpb.xml"/>
+<import file="hdmi.xml"/>
+<import file="edp.xml"/>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/display/sfpb.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/display/sfpb.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="SFPB" width="32">
+	<enum name="sfpb_ahb_arb_master_port_en">
+		<value name="SFPB_MASTER_PORT_ENABLE" value="3"/>
+		<value name="SFPB_MASTER_PORT_DISABLE" value="0"/>
+	</enum>
+	<reg32 offset="0x0058" name="GPREG">
+		<bitfield name="MASTER_PORT_EN" low="11" high="12" type="sfpb_ahb_arb_master_port_en"/>
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/freedreno_copyright.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/freedreno_copyright.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+
+<copyright year="2013">
+
+<author name="Rob Clark" email="robdclark@gmail.com"><nick name="robclark"/>
+Initial Author.
+</author>
+
+<author name="Ilia Mirkin" email="imirkin@alum.mit.edu"><nick name="imirkin"/>
+many a3xx/a4xx contributions
+</author>
+
+<license>
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+</license>
+
+</copyright>
+</database>
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/gen_header.py
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/gen_header.py
@@ -0,0 +1,971 @@
+#!/usr/bin/python3
+#
+# Copyright © 2019-2024 Google, Inc.
+#
+# SPDX-License-Identifier: MIT
+
+import xml.parsers.expat
+import sys
+import os
+import collections
+import argparse
+import time
+import datetime
+
+class Error(Exception):
+	def __init__(self, message):
+		self.message = message
+
+class Enum(object):
+	def __init__(self, name):
+		self.name = name
+		self.values = []
+
+	def has_name(self, name):
+		for (n, value) in self.values:
+			if n == name:
+				return True
+		return False
+
+	def names(self):
+		return [n for (n, value) in self.values]
+
+	def dump(self):
+		use_hex = False
+		for (name, value) in self.values:
+			if value > 0x1000:
+				use_hex = True
+
+		print("enum %s {" % self.name)
+		for (name, value) in self.values:
+			if use_hex:
+				print("\t%s = 0x%08x," % (name, value))
+			else:
+				print("\t%s = %d," % (name, value))
+		print("};\n")
+
+	def dump_pack_struct(self):
+		pass
+
+class Field(object):
+	def __init__(self, name, low, high, shr, type, parser):
+		self.name = name
+		self.low = low
+		self.high = high
+		self.shr = shr
+		self.type = type
+
+		builtin_types = [ None, "a3xx_regid", "boolean", "uint", "hex", "int", "fixed", "ufixed", "float", "address", "waddress" ]
+
+		maxpos = parser.current_bitsize - 1
+
+		if low < 0 or low > maxpos:
+			raise parser.error("low attribute out of range: %d" % low)
+		if high < 0 or high > maxpos:
+			raise parser.error("high attribute out of range: %d" % high)
+		if high < low:
+			raise parser.error("low is greater than high: low=%d, high=%d" % (low, high))
+		if self.type == "boolean" and not low == high:
+			raise parser.error("booleans should be 1 bit fields")
+		elif self.type == "float" and not (high - low == 31 or high - low == 15):
+			raise parser.error("floats should be 16 or 32 bit fields")
+		elif not self.type in builtin_types and not self.type in parser.enums:
+			raise parser.error("unknown type '%s'" % self.type)
+
+	def ctype(self, var_name):
+		if self.type == None:
+			type = "uint32_t"
+			val = var_name
+		elif self.type == "boolean":
+			type = "bool"
+			val = var_name
+		elif self.type == "uint" or self.type == "hex" or self.type == "a3xx_regid":
+			type = "uint32_t"
+			val = var_name
+		elif self.type == "int":
+			type = "int32_t"
+			val = var_name
+		elif self.type == "fixed":
+			type = "float"
+			val = "((int32_t)(%s * %d.0))" % (var_name, 1 << self.radix)
+		elif self.type == "ufixed":
+			type = "float"
+			val = "((uint32_t)(%s * %d.0))" % (var_name, 1 << self.radix)
+		elif self.type == "float" and self.high - self.low == 31:
+			type = "float"
+			val = "fui(%s)" % var_name
+		elif self.type == "float" and self.high - self.low == 15:
+			type = "float"
+			val = "_mesa_float_to_half(%s)" % var_name
+		elif self.type in [ "address", "waddress" ]:
+			type = "uint64_t"
+			val = var_name
+		else:
+			type = "enum %s" % self.type
+			val = var_name
+
+		if self.shr > 0:
+			val = "(%s >> %d)" % (val, self.shr)
+
+		return (type, val)
+
+def tab_to(name, value):
+	tab_count = (68 - (len(name) & ~7)) // 8
+	if tab_count <= 0:
+		tab_count = 1
+	print(name + ('\t' * tab_count) + value)
+
+def mask(low, high):
+	return ((0xffffffffffffffff >> (64 - (high + 1 - low))) << low)
+
+def field_name(reg, f):
+	if f.name:
+		name = f.name.lower()
+	else:
+		# We hit this path when a reg is defined with no bitset fields, ie.
+		# 	<reg32 offset="0x88db" name="RB_BLIT_DST_ARRAY_PITCH" low="0" high="28" shr="6" type="uint"/>
+		name = reg.name.lower()
+
+	if (name in [ "double", "float", "int" ]) or not (name[0].isalpha()):
+			name = "_" + name
+
+	return name
+
+# indices - array of (ctype, stride, __offsets_NAME)
+def indices_varlist(indices):
+	return ", ".join(["i%d" % i for i in range(len(indices))])
+
+def indices_prototype(indices):
+	return ", ".join(["%s i%d" % (ctype, idx)
+			for (idx, (ctype, stride, offset)) in  enumerate(indices)])
+
+def indices_strides(indices):
+	return " + ".join(["0x%x*i%d" % (stride, idx)
+					if stride else
+					"%s(i%d)" % (offset, idx)
+			for (idx, (ctype, stride, offset)) in  enumerate(indices)])
+
+class Bitset(object):
+	def __init__(self, name, template):
+		self.name = name
+		self.inline = False
+		if template:
+			self.fields = template.fields[:]
+		else:
+			self.fields = []
+
+	# Get address field if there is one in the bitset, else return None:
+	def get_address_field(self):
+		for f in self.fields:
+			if f.type in [ "address", "waddress" ]:
+				return f
+		return None
+
+	def dump_regpair_builder(self, reg):
+		print("#ifndef NDEBUG")
+		known_mask = 0
+		for f in self.fields:
+			known_mask |= mask(f.low, f.high)
+			if f.type in [ "boolean", "address", "waddress" ]:
+				continue
+			type, val = f.ctype("fields.%s" % field_name(reg, f))
+			print("    assert((%-40s & 0x%08x) == 0);" % (val, 0xffffffff ^ mask(0 , f.high - f.low)))
+		print("    assert((%-40s & 0x%08x) == 0);" % ("fields.unknown", known_mask))
+		print("#endif\n")
+
+		print("    return (struct fd_reg_pair) {")
+		if reg.array:
+			print("        .reg = REG_%s(__i)," % reg.full_name)
+		else:
+			print("        .reg = REG_%s," % reg.full_name)
+
+		print("        .value =")
+		for f in self.fields:
+			if f.type in [ "address", "waddress" ]:
+				continue
+			else:
+				type, val = f.ctype("fields.%s" % field_name(reg, f))
+				print("            (%-40s << %2d) |" % (val, f.low))
+		value_name = "dword"
+		if reg.bit_size == 64:
+			value_name = "qword"
+		print("            fields.unknown | fields.%s," % (value_name,))
+
+		address = self.get_address_field()
+		if address:
+			print("        .bo = fields.bo,")
+			print("        .is_address = true,")
+			if f.type == "waddress":
+				print("        .bo_write = true,")
+			print("        .bo_offset = fields.bo_offset,")
+			print("        .bo_shift = %d," % address.shr)
+			print("        .bo_low = %d," % address.low)
+
+		print("    };")
+
+	def dump_pack_struct(self, reg=None):
+		if not reg:
+			return
+
+		prefix = reg.full_name
+
+		print("struct %s {" % prefix)
+		for f in self.fields:
+			if f.type in [ "address", "waddress" ]:
+				tab_to("    __bo_type", "bo;")
+				tab_to("    uint32_t", "bo_offset;")
+				continue
+			name = field_name(reg, f)
+
+			type, val = f.ctype("var")
+
+			tab_to("    %s" % type, "%s;" % name)
+		if reg.bit_size == 64:
+			tab_to("    uint64_t", "unknown;")
+			tab_to("    uint64_t", "qword;")
+		else:
+			tab_to("    uint32_t", "unknown;")
+			tab_to("    uint32_t", "dword;")
+		print("};\n")
+
+		if reg.array:
+			print("static inline struct fd_reg_pair\npack_%s(uint32_t __i, struct %s fields)\n{" %
+				  (prefix, prefix))
+		else:
+			print("static inline struct fd_reg_pair\npack_%s(struct %s fields)\n{" %
+				  (prefix, prefix))
+
+		self.dump_regpair_builder(reg)
+
+		print("\n}\n")
+
+		if self.get_address_field():
+			skip = ", { .reg = 0 }"
+		else:
+			skip = ""
+
+		if reg.array:
+			print("#define %s(__i, ...) pack_%s(__i, __struct_cast(%s) { __VA_ARGS__ })%s\n" %
+				  (prefix, prefix, prefix, skip))
+		else:
+			print("#define %s(...) pack_%s(__struct_cast(%s) { __VA_ARGS__ })%s\n" %
+				  (prefix, prefix, prefix, skip))
+
+
+	def dump(self, prefix=None):
+		if prefix == None:
+			prefix = self.name
+		for f in self.fields:
+			if f.name:
+				name = prefix + "_" + f.name
+			else:
+				name = prefix
+
+			if not f.name and f.low == 0 and f.shr == 0 and not f.type in ["float", "fixed", "ufixed"]:
+				pass
+			elif f.type == "boolean" or (f.type == None and f.low == f.high):
+				tab_to("#define %s" % name, "0x%08x" % (1 << f.low))
+			else:
+				tab_to("#define %s__MASK" % name, "0x%08x" % mask(f.low, f.high))
+				tab_to("#define %s__SHIFT" % name, "%d" % f.low)
+				type, val = f.ctype("val")
+
+				print("static inline uint32_t %s(%s val)\n{" % (name, type))
+				if f.shr > 0:
+					print("\tassert(!(val & 0x%x));" % mask(0, f.shr - 1))
+				print("\treturn ((%s) << %s__SHIFT) & %s__MASK;\n}" % (val, name, name))
+		print()
+
+class Array(object):
+	def __init__(self, attrs, domain, variant, parent, index_type):
+		if "name" in attrs:
+			self.local_name = attrs["name"]
+		else:
+			self.local_name = ""
+		self.domain = domain
+		self.variant = variant
+		self.parent = parent
+		if self.parent:
+			self.name = self.parent.name + "_" + self.local_name
+		else:
+			self.name = self.local_name
+		if "offsets" in attrs:
+			self.offsets = map(lambda i: "0x%08x" % int(i, 0), attrs["offsets"].split(","))
+			self.fixed_offsets = True
+		elif "doffsets" in attrs:
+			self.offsets = map(lambda s: "(%s)" % s , attrs["doffsets"].split(","))
+			self.fixed_offsets = True
+		else:
+			self.offset = int(attrs["offset"], 0)
+			self.stride = int(attrs["stride"], 0)
+			self.fixed_offsets = False
+		if "index" in attrs:
+			self.index_type = index_type
+		else:
+			self.index_type = None
+		self.length = int(attrs["length"], 0)
+		if "usage" in attrs:
+			self.usages = attrs["usage"].split(',')
+		else:
+			self.usages = None
+
+	def index_ctype(self):
+		if not self.index_type:
+			return "uint32_t"
+		else:
+			return "enum %s" % self.index_type.name
+
+	# Generate array of (ctype, stride, __offsets_NAME)
+	def indices(self):
+		if self.parent:
+			indices = self.parent.indices()
+		else:
+			indices = []
+		if self.length != 1:
+			if self.fixed_offsets:
+				indices.append((self.index_ctype(), None, "__offset_%s" % self.local_name))
+			else:
+				indices.append((self.index_ctype(), self.stride, None))
+		return indices
+
+	def total_offset(self):
+		offset = 0
+		if not self.fixed_offsets:
+			offset += self.offset
+		if self.parent:
+			offset += self.parent.total_offset()
+		return offset
+
+	def dump(self):
+		proto = indices_varlist(self.indices())
+		strides = indices_strides(self.indices())
+		array_offset = self.total_offset()
+		if self.fixed_offsets:
+			print("static inline uint32_t __offset_%s(%s idx)" % (self.local_name, self.index_ctype()))
+			print("{\n\tswitch (idx) {")
+			if self.index_type:
+				for val, offset in zip(self.index_type.names(), self.offsets):
+					print("\t\tcase %s: return %s;" % (val, offset))
+			else:
+				for idx, offset in enumerate(self.offsets):
+					print("\t\tcase %d: return %s;" % (idx, offset))
+			print("\t\tdefault: return INVALID_IDX(idx);")
+			print("\t}\n}")
+		if proto == '':
+			tab_to("#define REG_%s_%s" % (self.domain, self.name), "0x%08x\n" % array_offset)
+		else:
+			tab_to("#define REG_%s_%s(%s)" % (self.domain, self.name, proto), "(0x%08x + %s )\n" % (array_offset, strides))
+
+	def dump_pack_struct(self):
+		pass
+
+	def dump_regpair_builder(self):
+		pass
+
+class Reg(object):
+	def __init__(self, attrs, domain, array, bit_size):
+		self.name = attrs["name"]
+		self.domain = domain
+		self.array = array
+		self.offset = int(attrs["offset"], 0)
+		self.type = None
+		self.bit_size = bit_size
+		if array:
+			self.name = array.name + "_" + self.name
+		self.full_name = self.domain + "_" + self.name
+		if "stride" in attrs:
+			self.stride = int(attrs["stride"], 0)
+			self.length = int(attrs["length"], 0)
+		else:
+			self.stride = None
+			self.length = None
+
+	# Generate array of (ctype, stride, __offsets_NAME)
+	def indices(self):
+		if self.array:
+			indices = self.array.indices()
+		else:
+			indices = []
+		if self.stride:
+			indices.append(("uint32_t", self.stride, None))
+		return indices
+
+	def total_offset(self):
+		if self.array:
+			return self.array.total_offset() + self.offset
+		else:
+			return self.offset
+
+	def dump(self):
+		proto = indices_prototype(self.indices())
+		strides = indices_strides(self.indices())
+		offset = self.total_offset()
+		if proto == '':
+			tab_to("#define REG_%s" % self.full_name, "0x%08x" % offset)
+		else:
+			print("static inline uint32_t REG_%s(%s) { return 0x%08x + %s; }" % (self.full_name, proto, offset, strides))
+
+		if self.bitset.inline:
+			self.bitset.dump(self.full_name)
+
+	def dump_pack_struct(self):
+		if self.bitset.inline:
+			self.bitset.dump_pack_struct(self)
+
+	def dump_regpair_builder(self):
+		if self.bitset.inline:
+			self.bitset.dump_regpair_builder(self)
+
+	def dump_py(self):
+		print("\tREG_%s = 0x%08x" % (self.full_name, self.offset))
+
+
+class Parser(object):
+	def __init__(self):
+		self.current_array = None
+		self.current_domain = None
+		self.current_prefix = None
+		self.current_prefix_type = None
+		self.current_stripe = None
+		self.current_bitset = None
+		self.current_bitsize = 32
+		# The varset attribute on the domain specifies the enum which
+		# specifies all possible hw variants:
+		self.current_varset = None
+		# Regs that have multiple variants.. we only generated the C++
+		# template based struct-packers for these
+		self.variant_regs = {}
+		# Information in which contexts regs are used, to be used in
+		# debug options
+		self.usage_regs = collections.defaultdict(list)
+		self.bitsets = {}
+		self.enums = {}
+		self.variants = set()
+		self.file = []
+		self.xml_files = []
+		self.copyright_year = None
+		self.authors = []
+		self.license = None
+
+	def error(self, message):
+		parser, filename = self.stack[-1]
+		return Error("%s:%d:%d: %s" % (filename, parser.CurrentLineNumber, parser.CurrentColumnNumber, message))
+
+	def prefix(self, variant=None):
+		if self.current_prefix_type == "variant" and variant:
+			return variant
+		elif self.current_stripe:
+			return self.current_stripe + "_" + self.current_domain
+		elif self.current_prefix:
+			return self.current_prefix + "_" + self.current_domain
+		else:
+			return self.current_domain
+
+	def parse_field(self, name, attrs):
+		try:
+			if "pos" in attrs:
+				high = low = int(attrs["pos"], 0)
+			elif "high" in attrs and "low" in attrs:
+				high = int(attrs["high"], 0)
+				low = int(attrs["low"], 0)
+			else:
+				low = 0
+				high = self.current_bitsize - 1
+
+			if "type" in attrs:
+				type = attrs["type"]
+			else:
+				type = None
+
+			if "shr" in attrs:
+				shr = int(attrs["shr"], 0)
+			else:
+				shr = 0
+
+			b = Field(name, low, high, shr, type, self)
+
+			if type == "fixed" or type == "ufixed":
+				b.radix = int(attrs["radix"], 0)
+
+			self.current_bitset.fields.append(b)
+		except ValueError as e:
+			raise self.error(e)
+
+	def parse_varset(self, attrs):
+		# Inherit the varset from the enclosing domain if not overriden:
+		varset = self.current_varset
+		if "varset" in attrs:
+			varset = self.enums[attrs["varset"]]
+		return varset
+
+	def parse_variants(self, attrs):
+		if not "variants" in attrs:
+				return None
+		variant = attrs["variants"].split(",")[0]
+		if "-" in variant:
+			variant = variant[:variant.index("-")]
+
+		varset = self.parse_varset(attrs)
+
+		assert varset.has_name(variant)
+
+		return variant
+
+	def add_all_variants(self, reg, attrs, parent_variant):
+		# TODO this should really handle *all* variants, including dealing
+		# with open ended ranges (ie. "A2XX,A4XX-") (we have the varset
+		# enum now to make that possible)
+		variant = self.parse_variants(attrs)
+		if not variant:
+			variant = parent_variant
+
+		if reg.name not in self.variant_regs:
+			self.variant_regs[reg.name] = {}
+		else:
+			# All variants must be same size:
+			v = next(iter(self.variant_regs[reg.name]))
+			assert self.variant_regs[reg.name][v].bit_size == reg.bit_size
+
+		self.variant_regs[reg.name][variant] = reg
+
+	def add_all_usages(self, reg, usages):
+		if not usages:
+			return
+
+		for usage in usages:
+			self.usage_regs[usage].append(reg)
+
+		self.variants.add(reg.domain)
+
+	def do_validate(self, schemafile):
+		if not self.validate:
+			return
+
+		try:
+			from lxml import etree
+
+			parser, filename = self.stack[-1]
+			dirname = os.path.dirname(filename)
+
+			# we expect this to look like <namespace url> schema.xsd.. I think
+			# technically it is supposed to be just a URL, but that doesn't
+			# quite match up to what we do.. Just skip over everything up to
+			# and including the first whitespace character:
+			schemafile = schemafile[schemafile.rindex(" ")+1:]
+
+			# this is a bit cheezy, but the xml file to validate could be
+			# in a child director, ie. we don't really know where the schema
+			# file is, the way the rnn C code does.  So if it doesn't exist
+			# just look one level up
+			if not os.path.exists(dirname + "/" + schemafile):
+				schemafile = "../" + schemafile
+
+			if not os.path.exists(dirname + "/" + schemafile):
+				raise self.error("Cannot find schema for: " + filename)
+
+			xmlschema_doc = etree.parse(dirname + "/" + schemafile)
+			xmlschema = etree.XMLSchema(xmlschema_doc)
+
+			xml_doc = etree.parse(filename)
+			if not xmlschema.validate(xml_doc):
+				error_str = str(xmlschema.error_log.filter_from_errors()[0])
+				raise self.error("Schema validation failed for: " + filename + "\n" + error_str)
+		except ImportError as e:
+			if self.validate:
+				raise e
+
+			print("lxml not found, skipping validation", file=sys.stderr)
+
+	def do_parse(self, filename):
+		filepath = os.path.abspath(filename)
+		if filepath in self.xml_files:
+			return
+		self.xml_files.append(filepath)
+		file = open(filename, "rb")
+		parser = xml.parsers.expat.ParserCreate()
+		self.stack.append((parser, filename))
+		parser.StartElementHandler = self.start_element
+		parser.EndElementHandler = self.end_element
+		parser.CharacterDataHandler = self.character_data
+		parser.buffer_text = True
+		parser.ParseFile(file)
+		self.stack.pop()
+		file.close()
+
+	def parse(self, rnn_path, filename, validate):
+		self.path = rnn_path
+		self.stack = []
+		self.validate = validate
+		self.do_parse(filename)
+
+	def parse_reg(self, attrs, bit_size):
+		self.current_bitsize = bit_size
+		if "type" in attrs and attrs["type"] in self.bitsets:
+			bitset = self.bitsets[attrs["type"]]
+			if bitset.inline:
+				self.current_bitset = Bitset(attrs["name"], bitset)
+				self.current_bitset.inline = True
+			else:
+				self.current_bitset = bitset
+		else:
+			self.current_bitset = Bitset(attrs["name"], None)
+			self.current_bitset.inline = True
+			if "type" in attrs:
+				self.parse_field(None, attrs)
+
+		variant = self.parse_variants(attrs)
+		if not variant and self.current_array:
+			variant = self.current_array.variant
+
+		self.current_reg = Reg(attrs, self.prefix(variant), self.current_array, bit_size)
+		self.current_reg.bitset = self.current_bitset
+
+		if len(self.stack) == 1:
+			self.file.append(self.current_reg)
+
+		if variant is not None:
+			self.add_all_variants(self.current_reg, attrs, variant)
+
+		usages = None
+		if "usage" in attrs:
+			usages = attrs["usage"].split(',')
+		elif self.current_array:
+			usages = self.current_array.usages
+
+		self.add_all_usages(self.current_reg, usages)
+
+	def start_element(self, name, attrs):
+		self.cdata = ""
+		if name == "import":
+			filename = attrs["file"]
+			self.do_parse(os.path.join(self.path, filename))
+		elif name == "domain":
+			self.current_domain = attrs["name"]
+			if "prefix" in attrs:
+				self.current_prefix = self.parse_variants(attrs)
+				self.current_prefix_type = attrs["prefix"]
+			else:
+				self.current_prefix = None
+				self.current_prefix_type = None
+			if "varset" in attrs:
+				self.current_varset = self.enums[attrs["varset"]]
+		elif name == "stripe":
+			self.current_stripe = self.parse_variants(attrs)
+		elif name == "enum":
+			self.current_enum_value = 0
+			self.current_enum = Enum(attrs["name"])
+			self.enums[attrs["name"]] = self.current_enum
+			if len(self.stack) == 1:
+				self.file.append(self.current_enum)
+		elif name == "value":
+			if "value" in attrs:
+				value = int(attrs["value"], 0)
+			else:
+				value = self.current_enum_value
+			self.current_enum.values.append((attrs["name"], value))
+		elif name == "reg32":
+			self.parse_reg(attrs, 32)
+		elif name == "reg64":
+			self.parse_reg(attrs, 64)
+		elif name == "array":
+			self.current_bitsize = 32
+			variant = self.parse_variants(attrs)
+			index_type = self.enums[attrs["index"]] if "index" in attrs else None
+			self.current_array = Array(attrs, self.prefix(variant), variant, self.current_array, index_type)
+			if len(self.stack) == 1:
+				self.file.append(self.current_array)
+		elif name == "bitset":
+			self.current_bitset = Bitset(attrs["name"], None)
+			if "inline" in attrs and attrs["inline"] == "yes":
+				self.current_bitset.inline = True
+			self.bitsets[self.current_bitset.name] = self.current_bitset
+			if len(self.stack) == 1 and not self.current_bitset.inline:
+				self.file.append(self.current_bitset)
+		elif name == "bitfield" and self.current_bitset:
+			self.parse_field(attrs["name"], attrs)
+		elif name == "database":
+			self.do_validate(attrs["xsi:schemaLocation"])
+		elif name == "copyright":
+			self.copyright_year = attrs["year"]
+		elif name == "author":
+			self.authors.append(attrs["name"] + " <" + attrs["email"] + "> " + attrs["name"])
+
+	def end_element(self, name):
+		if name == "domain":
+			self.current_domain = None
+			self.current_prefix = None
+			self.current_prefix_type = None
+		elif name == "stripe":
+			self.current_stripe = None
+		elif name == "bitset":
+			self.current_bitset = None
+		elif name == "reg32":
+			self.current_reg = None
+		elif name == "array":
+			self.current_array = self.current_array.parent
+		elif name == "enum":
+			self.current_enum = None
+		elif name == "license":
+			self.license = self.cdata
+
+	def character_data(self, data):
+		self.cdata += data
+
+	def dump_reg_usages(self):
+		d = collections.defaultdict(list)
+		for usage, regs in self.usage_regs.items():
+			for reg in regs:
+				variants = self.variant_regs.get(reg.name)
+				if variants:
+					for variant, vreg in variants.items():
+						if reg == vreg:
+							d[(usage, variant)].append(reg)
+				else:
+					for variant in self.variants:
+						d[(usage, variant)].append(reg)
+
+		print("#ifdef __cplusplus")
+
+		for usage, regs in self.usage_regs.items():
+			print("template<chip CHIP> constexpr inline uint16_t %s_REGS[] = {};" % (usage.upper()))
+
+		for (usage, variant), regs in d.items():
+			offsets = []
+
+			for reg in regs:
+				if reg.array:
+					for i in range(reg.array.length):
+						offsets.append(reg.array.offset + reg.offset + i * reg.array.stride)
+						if reg.bit_size == 64:
+							offsets.append(offsets[-1] + 1)
+				else:
+					offsets.append(reg.offset)
+					if reg.bit_size == 64:
+						offsets.append(offsets[-1] + 1)
+
+			offsets.sort()
+
+			print("template<> constexpr inline uint16_t %s_REGS<%s>[] = {" % (usage.upper(), variant))
+			for offset in offsets:
+				print("\t%s," % hex(offset))
+			print("};")
+
+		print("#endif")
+
+	def dump(self):
+		enums = []
+		bitsets = []
+		regs = []
+		for e in self.file:
+			if isinstance(e, Enum):
+				enums.append(e)
+			elif isinstance(e, Bitset):
+				bitsets.append(e)
+			else:
+				regs.append(e)
+
+		for e in enums + bitsets + regs:
+			e.dump()
+
+		self.dump_reg_usages()
+
+
+	def dump_regs_py(self):
+		regs = []
+		for e in self.file:
+			if isinstance(e, Reg):
+				regs.append(e)
+
+		for e in regs:
+			e.dump_py()
+
+
+	def dump_reg_variants(self, regname, variants):
+		# Don't bother for things that only have a single variant:
+		if len(variants) == 1:
+			return
+		print("#ifdef __cplusplus")
+		print("struct __%s {" % regname)
+		# TODO be more clever.. we should probably figure out which
+		# fields have the same type in all variants (in which they
+		# appear) and stuff everything else in a variant specific
+		# sub-structure.
+		seen_fields = []
+		bit_size = 32
+		array = False
+		address = None
+		for variant in variants.keys():
+			print("    /* %s fields: */" % variant)
+			reg = variants[variant]
+			bit_size = reg.bit_size
+			array = reg.array
+			for f in reg.bitset.fields:
+				fld_name = field_name(reg, f)
+				if fld_name in seen_fields:
+					continue
+				seen_fields.append(fld_name)
+				name = fld_name.lower()
+				if f.type in [ "address", "waddress" ]:
+					if address:
+						continue
+					address = f
+					tab_to("    __bo_type", "bo;")
+					tab_to("    uint32_t", "bo_offset;")
+					continue
+				type, val = f.ctype("var")
+				tab_to("    %s" %type, "%s;" %name)
+		print("    /* fallback fields: */")
+		if bit_size == 64:
+			tab_to("    uint64_t", "unknown;")
+			tab_to("    uint64_t", "qword;")
+		else:
+			tab_to("    uint32_t", "unknown;")
+			tab_to("    uint32_t", "dword;")
+		print("};")
+		# TODO don't hardcode the varset enum name
+		varenum = "chip"
+		print("template <%s %s>" % (varenum, varenum.upper()))
+		print("static inline struct fd_reg_pair")
+		xtra = ""
+		xtravar = ""
+		if array:
+			xtra = "int __i, "
+			xtravar = "__i, "
+		print("__%s(%sstruct __%s fields) {" % (regname, xtra, regname))
+		for variant in variants.keys():
+			print("  if (%s == %s) {" % (varenum.upper(), variant))
+			reg = variants[variant]
+			reg.dump_regpair_builder()
+			print("  } else")
+		print("    assert(!\"invalid variant\");")
+		print("}")
+
+		if bit_size == 64:
+			skip = ", { .reg = 0 }"
+		else:
+			skip = ""
+
+		print("#define %s(VARIANT, %s...) __%s<VARIANT>(%s{__VA_ARGS__})%s" % (regname, xtravar, regname, xtravar, skip))
+		print("#endif /* __cplusplus */")
+
+	def dump_structs(self):
+		for e in self.file:
+			e.dump_pack_struct()
+
+		for regname in self.variant_regs:
+			self.dump_reg_variants(regname, self.variant_regs[regname])
+
+
+def dump_c(args, guard, func):
+	p = Parser()
+
+	try:
+		p.parse(args.rnn, args.xml, args.validate)
+	except Error as e:
+		print(e, file=sys.stderr)
+		exit(1)
+
+	print("#ifndef %s\n#define %s\n" % (guard, guard))
+
+	print("""/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng gen_header.py tool in this git repository:
+http://gitlab.freedesktop.org/mesa/mesa/
+git clone https://gitlab.freedesktop.org/mesa/mesa.git
+
+The rules-ng-ng source files this header was generated from are:
+""")
+	maxlen = 0
+	for filepath in p.xml_files:
+		maxlen = max(maxlen, len(filepath))
+	for filepath in p.xml_files:
+		pad = " " * (maxlen - len(filepath))
+		filesize = str(os.path.getsize(filepath))
+		filesize = " " * (7 - len(filesize)) + filesize
+		filetime = time.ctime(os.path.getmtime(filepath))
+		print("- " + filepath + pad + " (" + filesize + " bytes, from " + filetime + ")")
+	if p.copyright_year:
+		current_year = str(datetime.date.today().year)
+		print()
+		print("Copyright (C) %s-%s by the following authors:" % (p.copyright_year, current_year))
+		for author in p.authors:
+			print("- " + author)
+	if p.license:
+		print(p.license)
+	print("*/")
+
+	print()
+	print("#ifdef __KERNEL__")
+	print("#include <linux/bug.h>")
+	print("#define assert(x) BUG_ON(!(x))")
+	print("#else")
+	print("#include <assert.h>")
+	print("#endif")
+	print()
+
+	print("#ifdef __cplusplus")
+	print("#define __struct_cast(X)")
+	print("#else")
+	print("#define __struct_cast(X) (struct X)")
+	print("#endif")
+	print()
+
+	func(p)
+
+	print("\n#endif /* %s */" % guard)
+
+
+def dump_c_defines(args):
+	guard = str.replace(os.path.basename(args.xml), '.', '_').upper()
+	dump_c(args, guard, lambda p: p.dump())
+
+
+def dump_c_pack_structs(args):
+	guard = str.replace(os.path.basename(args.xml), '.', '_').upper() + '_STRUCTS'
+	dump_c(args, guard, lambda p: p.dump_structs())
+
+
+def dump_py_defines(args):
+	p = Parser()
+
+	try:
+		p.parse(args.rnn, args.xml)
+	except Error as e:
+		print(e, file=sys.stderr)
+		exit(1)
+
+	file_name = os.path.splitext(os.path.basename(args.xml))[0]
+
+	print("from enum import IntEnum")
+	print("class %sRegs(IntEnum):" % file_name.upper())
+
+	os.path.basename(args.xml)
+
+	p.dump_regs_py()
+
+
+def main():
+	parser = argparse.ArgumentParser()
+	parser.add_argument('--rnn', type=str, required=True)
+	parser.add_argument('--xml', type=str, required=True)
+	parser.add_argument('--validate', default=False, action='store_true')
+	parser.add_argument('--no-validate', dest='validate', action='store_false')
+
+	subparsers = parser.add_subparsers()
+	subparsers.required = True
+
+	parser_c_defines = subparsers.add_parser('c-defines')
+	parser_c_defines.set_defaults(func=dump_c_defines)
+
+	parser_c_pack_structs = subparsers.add_parser('c-pack-structs')
+	parser_c_pack_structs.set_defaults(func=dump_c_pack_structs)
+
+	parser_py_defines = subparsers.add_parser('py-defines')
+	parser_py_defines.set_defaults(func=dump_py_defines)
+
+	args = parser.parse_args()
+	args.func(args)
+
+
+if __name__ == '__main__':
+	main()
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm/registers/rules-fd.xsd
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm/registers/rules-fd.xsd
@@ -0,0 +1,404 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+	targetNamespace="http://nouveau.freedesktop.org/"
+	xmlns:rng="http://nouveau.freedesktop.org/"
+	elementFormDefault="qualified">
+
+	<annotation>
+		<documentation>
+			An updated version of the old rules.xml file from the
+			RivaTV project. Specifications by Pekka Paalanen,
+			preliminary attempt by KoalaBR,
+			first working version by Jakob Bornecrantz.
+			For specifications, see the file rules-ng-format.txt
+			in Nouveau CVS module 'rules-ng'.
+		</documentation>
+		<documentation>Version 0.1</documentation>
+	</annotation>
+
+
+	<!-- Elements -->
+
+	<element name="database"       type="rng:databaseType" />
+	<element name="import"         type="rng:importType" />
+	<element name="copyright"      type="rng:copyrightType" />
+	<element name="domain"         type="rng:domainType" />
+	<element name="array"          type="rng:arrayType" />
+	<element name="stripe"         type="rng:stripeType" />
+	<element name="reg64"          type="rng:registerType" />
+	<element name="reg32"          type="rng:registerType" />
+	<element name="bitset"         type="rng:bitsetType" />
+	<element name="bitfield"       type="rng:bitfieldType" />
+	<element name="enum"           type="rng:enumType" />
+	<element name="value"          type="rng:valueType" />
+
+	<!-- Copyright elements -->
+	<element name="author"         type="rng:authorType" />
+	<element name="nick"           type="rng:nickType" />
+	<element name="license"        type="rng:docType" />
+
+	<!-- Documentation elements -->
+	
+	<!-- FIXME: allowed only one  per parent element -->
+	<element name="brief" type="rng:briefType" />
+	
+	<element name="doc"  type="rng:docType" />
+	<element name="b"    type="rng:textformatType" />
+	<element name="i"    type="rng:textformatType" />
+	<element name="u"    type="rng:textformatType" />
+	<element name="code" type="rng:textcodeType" />
+	<element name="ul"   type="rng:listType" />
+	<element name="ol"   type="rng:listType" />
+	<element name="li"   type="rng:listitemType" />
+
+	<!-- Copyright element types -->
+
+	<complexType name="authorType" mixed="true">
+		<annotation>
+			<documentation>
+				register database author
+			</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<element ref="rng:nick" />
+		</choice>
+		<attribute name="name" type="string" use="required" />
+		<attribute name="email" type="string" use="required" />
+	</complexType>
+
+	<complexType name="nickType">
+		<annotation>
+			<documentation>nickType</documentation>
+		</annotation>
+		<attribute name="name" type="string" use="required" />
+	</complexType>
+
+	<!-- Database element types -->
+
+	<complexType name="databaseType">
+		<annotation>
+			<documentation>databaseType</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+		</choice>
+	</complexType>
+
+	<complexType name="importType">
+		<annotation>
+			<documentation>importType</documentation>
+		</annotation>
+		<attribute name="file" type="string" use="required" />
+	</complexType>
+
+	<complexType name="copyrightType">
+		<annotation>
+			<documentation>copyrightType</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+			<element ref="rng:author" />
+			<element ref="rng:license" />
+		</choice>
+		<attribute name="year" type="nonNegativeInteger" use="optional" />
+	</complexType>
+
+	<complexType name="domainType">
+		<annotation>
+			<documentation>domainType</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+			<group ref="rng:regarrayGroup" />
+		</choice>
+		<attribute name="name" type="NMTOKEN" use="required" />
+		<attribute name="prefix" type="NMTOKENS" use="optional" />
+		<attribute name="width" type="rng:DomainWidth" use="optional" />
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+		<attribute name="variants" type="string" use="optional" />
+	</complexType>
+
+	<complexType name="arrayType">
+		<annotation>
+			<documentation>arrayType</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+			<group ref="rng:regarrayGroup" />
+		</choice>
+		<attribute name="name" type="NMTOKEN" use="optional" />
+		<attribute name="offset" type="rng:HexOrNumber" use="optional" />
+		<attribute name="offsets" type="string" use="optional"/>
+		<attribute name="doffsets" type="string" use="optional"/>
+		<attribute name="index" type="NMTOKENS" use="optional"/>
+		<attribute name="stride" type="rng:HexOrNumber" use="required" />
+		<attribute name="length" type="rng:HexOrNumber" use="required" />
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+		<attribute name="variants" type="string" use="optional" />
+		<attribute name="usage" type="string" use="optional" />
+	</complexType>
+
+	<complexType name="stripeType">
+		<annotation>
+			<documentation>stripeType</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+			<group ref="rng:regarrayGroup" minOccurs="0" />
+		</choice>
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+		<attribute name="variants" type="string" use="optional" />
+		<attribute name="prefix" type="NMTOKENS" use="optional" />
+	</complexType>
+
+	<complexType name="registerType">
+		<annotation>
+			<documentation>
+				registerType used by reg32, reg64
+			</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+			<element ref="rng:value" />
+			<element ref="rng:bitfield" />
+		</choice>
+		<attribute name="name" type="NMTOKEN" use="required" />
+		<attribute name="offset" type="rng:HexOrNumber" use="required" />
+		<attribute name="type" type="NMTOKENS" use="optional" />
+		<attribute name="shr" type="nonNegativeInteger" use="optional" />
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+		<attribute name="variants" type="string" use="optional" />
+		<attribute name="stride" type="rng:HexOrNumber" use="optional" />
+		<attribute name="length" type="rng:HexOrNumber" use="optional" />
+		<attribute name="high" type="nonNegativeInteger" use="optional" />
+		<attribute name="low" type="nonNegativeInteger" use="optional" />
+		<attribute name="pos" type="nonNegativeInteger" use="optional" />
+		<attribute name="align" type="nonNegativeInteger" use="optional" />
+		<attribute name="radix" type="nonNegativeInteger" use="optional" />
+		<attribute name="usage" type="string" use="optional" />
+	</complexType>
+
+	<complexType name="bitsetType">
+		<annotation>
+			<documentation>bitsetType</documentation>
+		</annotation>
+		<choice maxOccurs="unbounded">
+			<element ref="rng:bitfield" />
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+		</choice>
+		<attribute name="name" type="NMTOKEN" use="required" />
+		<attribute name="inline" type="rng:Boolean" use="optional" />
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+	</complexType>
+
+	<complexType name="bitfieldType">
+		<annotation>
+			<documentation>bitfieldType</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<element ref="rng:value" maxOccurs="unbounded" />
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+		</choice>
+		<attribute name="name" type="NMTOKEN" use="required" />
+		<attribute name="high" type="nonNegativeInteger" use="optional" />
+		<attribute name="low" type="nonNegativeInteger" use="optional" />
+		<attribute name="pos" type="nonNegativeInteger" use="optional" />
+		<attribute name="radix" type="nonNegativeInteger" use="optional" />
+		<attribute name="type" type="NMTOKENS" use="optional" />
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+		<attribute name="variants" type="string" use="optional" />
+		<attribute name="addvariant" type="rng:Boolean" use="optional" />
+		<attribute name="shr" type="nonNegativeInteger" use="optional" />
+	</complexType>
+
+	<complexType name="enumType">
+		<annotation>
+			<documentation>enumType</documentation>
+		</annotation>
+		<choice maxOccurs="unbounded">
+			<element ref="rng:value" />
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+		</choice>
+		<attribute name="name" type="NMTOKEN" use="required" />
+		<attribute name="bare" type="rng:Boolean" use="optional" />
+		<attribute name="prefix" type="NMTOKENS" use="optional" />
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+	</complexType>
+
+	<complexType name="valueType">
+		<annotation>
+			<documentation>valueType</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+		</choice>
+		<attribute name="name" type="NMTOKEN" use="required" />
+		<attribute name="value" type="string" use="optional" />
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+		<attribute name="variants" type="string" use="optional" />
+	</complexType>
+
+	<!-- Documentation element types -->
+
+	<complexType name="briefType">
+		<annotation>
+			<documentation>
+				brief documentation, no markup
+			</documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="string" />
+		</simpleContent>
+	</complexType>
+	
+	<complexType name="docType" mixed="true">
+		<annotation>
+			<documentation>
+				root element of documentation sub-tree
+			</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:textformatGroup" />
+			<group ref="rng:listGroup" />
+			<element ref="rng:code" />
+		</choice>
+	</complexType>
+	
+	<complexType name="textformatType" mixed="true">
+		<annotation>
+			<documentation>
+				for bold, underline, italics
+			</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:textformatGroup" />
+		</choice>
+	</complexType>
+	
+	<complexType name="textcodeType">
+		<simpleContent>
+			<extension base="string">
+				<attribute name="title" type="string" />
+			</extension>
+		</simpleContent>
+	</complexType>
+	
+	<complexType name="listType">
+		<annotation>
+			<documentation>
+				definition of a list, ordered or unordered
+			</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<element ref="rng:li" />
+		</choice>
+	</complexType>
+	
+	<complexType name="listitemType" mixed="true">
+		<annotation>
+			<documentation>
+				items of a list
+			</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:textformatGroup" />
+			<group ref="rng:listGroup" />
+			<element ref="rng:code" />
+		</choice>
+	</complexType>
+
+
+
+	<!-- Attribute value types -->
+
+	<simpleType name="Hexadecimal">
+		<restriction base="string">
+			<pattern value="0x[0-9a-f]+" />
+			<pattern value="0x[0-9A-F]+" />
+			<pattern value="[0-9]" />
+		</restriction>
+	</simpleType>
+
+	<simpleType name="HexOrNumber">
+		<annotation>
+			<documentation>HexOrNumber</documentation>
+		</annotation>
+		<union memberTypes="rng:Hexadecimal nonNegativeInteger" />
+	</simpleType>
+
+	<simpleType name="Boolean">
+		<restriction base="string">
+			<enumeration value="true" />
+			<enumeration value="1" />
+			<enumeration value="yes" />
+			<enumeration value="false" />
+			<enumeration value="0" />
+			<enumeration value="no" />
+		</restriction>
+	</simpleType>
+
+	<simpleType name="DomainWidth">
+		<annotation>
+			<documentation>DomainWidth</documentation>
+		</annotation>
+		<restriction base="string">
+			<enumeration value="32" />
+		</restriction>
+	</simpleType>
+
+
+
+	<!-- Element groups -->
+
+	<group name="topGroup">
+		<choice>
+			<element ref="rng:copyright" />
+			<element ref="rng:domain" />
+			<element ref="rng:enum" />
+			<element ref="rng:bitset" />
+			<element ref="rng:import" />
+		</choice>
+	</group>
+	
+	<group name="regarrayGroup">
+		<choice>
+			<element ref="rng:reg64" />
+			<element ref="rng:reg32" />
+			<element ref="rng:array" />
+			<element ref="rng:stripe" />
+		</choice>
+	</group>
+	
+	<group name="docGroup">
+		<choice>
+			<element ref="rng:brief" />
+			<element ref="rng:doc" />
+		</choice>
+	</group>
+	
+	<group name="textformatGroup">
+		<choice>
+			<element ref="rng:b" />
+			<element ref="rng:i" />
+			<element ref="rng:u" />
+		</choice>
+	</group>
+	
+	<group name="listGroup">
+		<choice>
+			<element ref="rng:ul" />
+			<element ref="rng:ol" />
+		</choice>
+	</group>
+
+</schema>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/Kconfig
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/Kconfig
@@ -0,0 +1,178 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config DRM_MSM
+	tristate "MSM DRM"
+	depends on DRM
+	depends on ARCH_QCOM || SOC_IMX5 || COMPILE_TEST
+	depends on COMMON_CLK
+	depends on IOMMU_SUPPORT
+	depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n
+	depends on QCOM_OCMEM || QCOM_OCMEM=n
+	depends on QCOM_LLCC || QCOM_LLCC=n
+	depends on QCOM_COMMAND_DB || QCOM_COMMAND_DB=n
+	depends on PM
+	select IOMMU_IO_PGTABLE
+	select QCOM_MDT_LOADER if ARCH_QCOM
+	select REGULATOR
+	select DRM_DP_AUX_BUS
+	select DRM_DISPLAY_DP_HELPER
+	select DRM_DISPLAY_HELPER
+	select DRM_EXEC
+	select DRM_KMS_HELPER
+	select DRM_PANEL
+	select DRM_BRIDGE
+	select DRM_PANEL_BRIDGE
+	select DRM_SCHED
+	select FB_SYSMEM_HELPERS if DRM_FBDEV_EMULATION
+	select SHMEM
+	select TMPFS
+	select QCOM_SCM
+	select WANT_DEV_COREDUMP
+	select SND_SOC_HDMI_CODEC if SND_SOC
+	select SYNC_FILE
+	select PM_OPP
+	select NVMEM
+	select PM_GENERIC_DOMAINS
+	help
+	  DRM/KMS driver for MSM/snapdragon.
+
+config DRM_MSM_GPU_STATE
+	bool
+	depends on DRM_MSM && (DEBUG_FS || DEV_COREDUMP)
+	default y
+
+config DRM_MSM_GPU_SUDO
+	bool "Enable SUDO flag on submits"
+	depends on DRM_MSM && EXPERT
+	default n
+	help
+	  Enable userspace that has CAP_SYS_RAWIO to submit GPU commands
+	  that are run from RB instead of IB1.  This essentially gives
+	  userspace kernel level access, but is useful for firmware
+	  debugging.
+
+	  Only use this if you are a driver developer.  This should *not*
+	  be enabled for production kernels.  If unsure, say N.
+
+config DRM_MSM_VALIDATE_XML
+	bool "Validate XML register files against schema"
+	depends on DRM_MSM && EXPERT && n
+	depends on $(success,$(PYTHON3) -c "import lxml")
+	help
+	  Validate XML files with register definitions against rules-fd schema.
+	  This option is mostly targeting DRM MSM developers. If unsure, say N.
+
+config DRM_MSM_MDSS
+	bool
+	depends on DRM_MSM
+	default n
+
+config DRM_MSM_MDP4
+	bool "Enable MDP4 support in MSM DRM driver"
+	depends on DRM_MSM
+	default y
+	help
+	  Compile in support for the Mobile Display Processor v4 (MDP4) in
+	  the MSM DRM driver. It is the older display controller found in
+	  devices using APQ8064/MSM8960/MSM8x60 platforms.
+
+config DRM_MSM_MDP5
+	bool "Enable MDP5 support in MSM DRM driver"
+	depends on DRM_MSM
+	select DRM_MSM_MDSS
+	default y
+	help
+	  Compile in support for the Mobile Display Processor v5 (MDP5) in
+	  the MSM DRM driver. It is the display controller found in devices
+	  using e.g. APQ8016/MSM8916/APQ8096/MSM8996/MSM8974/SDM6x0 platforms.
+
+config DRM_MSM_DPU
+	bool "Enable DPU support in MSM DRM driver"
+	depends on DRM_MSM
+	select DRM_MSM_MDSS
+	default y
+	help
+	  Compile in support for the Display Processing Unit in
+	  the MSM DRM driver. It is the display controller found in devices
+	  using e.g. SDM845 and newer platforms.
+
+config DRM_MSM_DP
+	bool "Enable DisplayPort support in MSM DRM driver"
+	depends on DRM_MSM
+	select RATIONAL
+	default y
+	help
+	  Compile in support for DP driver in MSM DRM driver. DP external
+	  display support is enabled through this config option. It can
+	  be primary or secondary display on device.
+
+config DRM_MSM_DSI
+	bool "Enable DSI support in MSM DRM driver"
+	depends on DRM_MSM
+	select DRM_PANEL
+	select DRM_MIPI_DSI
+	default y
+	help
+	  Choose this option if you have a need for MIPI DSI connector
+	  support.
+
+config DRM_MSM_DSI_28NM_PHY
+	bool "Enable DSI 28nm PHY driver in MSM DRM"
+	depends on DRM_MSM_DSI
+	default y
+	help
+	  Choose this option if the 28nm DSI PHY is used on the platform.
+
+config DRM_MSM_DSI_20NM_PHY
+	bool "Enable DSI 20nm PHY driver in MSM DRM"
+	depends on DRM_MSM_DSI
+	default y
+	help
+	  Choose this option if the 20nm DSI PHY is used on the platform.
+
+config DRM_MSM_DSI_28NM_8960_PHY
+	bool "Enable DSI 28nm 8960 PHY driver in MSM DRM"
+	depends on DRM_MSM_DSI
+	default y
+	help
+	  Choose this option if the 28nm DSI PHY 8960 variant is used on the
+	  platform.
+
+config DRM_MSM_DSI_14NM_PHY
+	bool "Enable DSI 14nm PHY driver in MSM DRM (used by MSM8996/APQ8096)"
+	depends on DRM_MSM_DSI
+	default y
+	help
+	  Choose this option if DSI PHY on 8996 is used on the platform.
+
+config DRM_MSM_DSI_10NM_PHY
+	bool "Enable DSI 10nm PHY driver in MSM DRM (used by SDM845)"
+	depends on DRM_MSM_DSI
+	default y
+	help
+	  Choose this option if DSI PHY on SDM845 is used on the platform.
+
+config DRM_MSM_DSI_7NM_PHY
+	bool "Enable DSI 7nm/5nm/4nm PHY driver in MSM DRM"
+	depends on DRM_MSM_DSI
+	default y
+	help
+	  Choose this option if DSI PHY on SM8150/SM8250/SM8350/SM8450/SM8550/SC7280
+	  is used on the platform.
+
+config DRM_MSM_HDMI
+	bool "Enable HDMI support in MSM DRM driver"
+	depends on DRM_MSM
+	default y
+	help
+	  Compile in support for the HDMI output MSM DRM driver. It can
+	  be a primary or a secondary display on device. Note that this is used
+	  only for the direct HDMI output. If the device outputs HDMI data
+	  through some kind of DSI-to-HDMI bridge, this option can be disabled.
+
+config DRM_MSM_HDMI_HDCP
+	bool "Enable HDMI HDCP support in MSM DRM driver"
+	depends on DRM_MSM && DRM_MSM_HDMI
+	default y
+	help
+	  Choose this option to enable HDCP state machine
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/Makefile
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/Makefile
@@ -0,0 +1,220 @@
+# SPDX-License-Identifier: GPL-2.0
+ccflags-y := -I $(srctree)/$(src)
+ccflags-y += -I $(obj)/generated
+ccflags-y += -I $(srctree)/$(src)/disp/dpu1
+ccflags-$(CONFIG_DRM_MSM_DSI) += -I $(srctree)/$(src)/dsi
+ccflags-$(CONFIG_DRM_MSM_DP) += -I $(srctree)/$(src)/dp
+
+adreno-y := \
+	adreno/adreno_device.o \
+	adreno/adreno_gpu.o \
+	adreno/a2xx_catalog.o \
+	adreno/a2xx_gpu.o \
+	adreno/a2xx_gpummu.o \
+	adreno/a3xx_catalog.o \
+	adreno/a3xx_gpu.o \
+	adreno/a4xx_catalog.o \
+	adreno/a4xx_gpu.o \
+	adreno/a5xx_catalog.o \
+	adreno/a5xx_gpu.o \
+	adreno/a5xx_power.o \
+	adreno/a5xx_preempt.o \
+	adreno/a6xx_catalog.o \
+	adreno/a6xx_gpu.o \
+	adreno/a6xx_gmu.o \
+	adreno/a6xx_hfi.o \
+
+adreno-$(CONFIG_DEBUG_FS) += adreno/a5xx_debugfs.o \
+
+adreno-$(CONFIG_DRM_MSM_GPU_STATE)	+= adreno/a6xx_gpu_state.o
+
+msm-display-$(CONFIG_DRM_MSM_HDMI) += \
+	hdmi/hdmi.o \
+	hdmi/hdmi_audio.o \
+	hdmi/hdmi_bridge.o \
+	hdmi/hdmi_hpd.o \
+	hdmi/hdmi_i2c.o \
+	hdmi/hdmi_phy.o \
+	hdmi/hdmi_phy_8960.o \
+	hdmi/hdmi_phy_8996.o \
+	hdmi/hdmi_phy_8998.o \
+	hdmi/hdmi_phy_8x60.o \
+	hdmi/hdmi_phy_8x74.o \
+	hdmi/hdmi_pll_8960.o \
+
+msm-display-$(CONFIG_DRM_MSM_MDP4) += \
+	disp/mdp4/mdp4_crtc.o \
+	disp/mdp4/mdp4_dsi_encoder.o \
+	disp/mdp4/mdp4_dtv_encoder.o \
+	disp/mdp4/mdp4_lcdc_encoder.o \
+	disp/mdp4/mdp4_lvds_connector.o \
+	disp/mdp4/mdp4_lvds_pll.o \
+	disp/mdp4/mdp4_irq.o \
+	disp/mdp4/mdp4_kms.o \
+	disp/mdp4/mdp4_plane.o \
+
+msm-display-$(CONFIG_DRM_MSM_MDP5) += \
+	disp/mdp5/mdp5_cfg.o \
+	disp/mdp5/mdp5_cmd_encoder.o \
+	disp/mdp5/mdp5_ctl.o \
+	disp/mdp5/mdp5_crtc.o \
+	disp/mdp5/mdp5_encoder.o \
+	disp/mdp5/mdp5_irq.o \
+	disp/mdp5/mdp5_kms.o \
+	disp/mdp5/mdp5_pipe.o \
+	disp/mdp5/mdp5_mixer.o \
+	disp/mdp5/mdp5_plane.o \
+	disp/mdp5/mdp5_smp.o \
+
+msm-display-$(CONFIG_DRM_MSM_DPU) += \
+	disp/dpu1/dpu_core_perf.o \
+	disp/dpu1/dpu_crtc.o \
+	disp/dpu1/dpu_encoder.o \
+	disp/dpu1/dpu_encoder_phys_cmd.o \
+	disp/dpu1/dpu_encoder_phys_vid.o \
+	disp/dpu1/dpu_encoder_phys_wb.o \
+	disp/dpu1/dpu_formats.o \
+	disp/dpu1/dpu_hw_catalog.o \
+	disp/dpu1/dpu_hw_cdm.o \
+	disp/dpu1/dpu_hw_ctl.o \
+	disp/dpu1/dpu_hw_dsc.o \
+	disp/dpu1/dpu_hw_dsc_1_2.o \
+	disp/dpu1/dpu_hw_interrupts.o \
+	disp/dpu1/dpu_hw_intf.o \
+	disp/dpu1/dpu_hw_lm.o \
+	disp/dpu1/dpu_hw_pingpong.o \
+	disp/dpu1/dpu_hw_sspp.o \
+	disp/dpu1/dpu_hw_dspp.o \
+	disp/dpu1/dpu_hw_merge3d.o \
+	disp/dpu1/dpu_hw_top.o \
+	disp/dpu1/dpu_hw_util.o \
+	disp/dpu1/dpu_hw_vbif.o \
+	disp/dpu1/dpu_hw_wb.o \
+	disp/dpu1/dpu_kms.o \
+	disp/dpu1/dpu_plane.o \
+	disp/dpu1/dpu_rm.o \
+	disp/dpu1/dpu_vbif.o \
+	disp/dpu1/dpu_writeback.o
+
+msm-display-$(CONFIG_DRM_MSM_MDSS) += \
+	msm_mdss.o \
+
+msm-display-y += \
+	disp/mdp_format.o \
+	disp/mdp_kms.o \
+	disp/msm_disp_snapshot.o \
+	disp/msm_disp_snapshot_util.o \
+
+msm-y += \
+	msm_atomic.o \
+	msm_atomic_tracepoints.o \
+	msm_debugfs.o \
+	msm_drv.o \
+	msm_fb.o \
+	msm_fence.o \
+	msm_gem.o \
+	msm_gem_prime.o \
+	msm_gem_shrinker.o \
+	msm_gem_submit.o \
+	msm_gem_vma.o \
+	msm_gpu.o \
+	msm_gpu_devfreq.o \
+	msm_io_utils.o \
+	msm_iommu.o \
+	msm_kms.o \
+	msm_perf.o \
+	msm_rd.o \
+	msm_ringbuffer.o \
+	msm_submitqueue.o \
+	msm_gpu_tracepoints.o \
+
+msm-$(CONFIG_DRM_FBDEV_EMULATION) += msm_fbdev.o
+
+msm-display-$(CONFIG_DEBUG_FS) += \
+	dp/dp_debug.o
+
+msm-display-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
+	dp/dp_catalog.o \
+	dp/dp_ctrl.o \
+	dp/dp_display.o \
+	dp/dp_drm.o \
+	dp/dp_link.o \
+	dp/dp_panel.o \
+	dp/dp_audio.o \
+	dp/dp_utils.o \
+	dp/dp_mst_drm.o
+
+msm-display-$(CONFIG_DRM_MSM_HDMI_HDCP) += hdmi/hdmi_hdcp.o
+
+msm-display-$(CONFIG_DRM_MSM_DSI) += dsi/dsi.o \
+			dsi/dsi_cfg.o \
+			dsi/dsi_host.o \
+			dsi/dsi_manager.o \
+			dsi/phy/dsi_phy.o
+
+msm-display-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/phy/dsi_phy_28nm.o
+msm-display-$(CONFIG_DRM_MSM_DSI_20NM_PHY) += dsi/phy/dsi_phy_20nm.o
+msm-display-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/phy/dsi_phy_28nm_8960.o
+msm-display-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o
+msm-display-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/phy/dsi_phy_10nm.o
+msm-display-$(CONFIG_DRM_MSM_DSI_7NM_PHY) += dsi/phy/dsi_phy_7nm.o
+
+msm-y += $(adreno-y) $(msm-display-y)
+
+obj-$(CONFIG_DRM_MSM)	+= msm.o
+
+ifeq (y,$(CONFIG_DRM_MSM_VALIDATE_XML))
+	headergen-opts += --validate
+else
+	headergen-opts += --no-validate
+endif
+
+quiet_cmd_headergen = GENHDR  $@
+      cmd_headergen = mkdir -p $(obj)/generated && $(PYTHON3) $(srctree)/$(src)/registers/gen_header.py \
+		      $(headergen-opts) --rnn $(srctree)/$(src)/registers --xml $< c-defines > $@
+
+$(obj)/generated/%.xml.h: $(src)/registers/adreno/%.xml \
+		$(src)/registers/adreno/adreno_common.xml \
+		$(src)/registers/adreno/adreno_pm4.xml \
+		$(src)/registers/freedreno_copyright.xml \
+		$(src)/registers/gen_header.py \
+		$(src)/registers/rules-fd.xsd \
+		FORCE
+	$(call if_changed,headergen)
+
+$(obj)/generated/%.xml.h: $(src)/registers/display/%.xml \
+		$(src)/registers/freedreno_copyright.xml \
+		$(src)/registers/gen_header.py \
+		$(src)/registers/rules-fd.xsd \
+		FORCE
+	$(call if_changed,headergen)
+
+ADRENO_HEADERS = \
+	generated/a2xx.xml.h \
+	generated/a3xx.xml.h \
+	generated/a4xx.xml.h \
+	generated/a5xx.xml.h \
+	generated/a6xx.xml.h \
+	generated/a6xx_gmu.xml.h \
+	generated/adreno_common.xml.h \
+	generated/adreno_pm4.xml.h \
+
+DISPLAY_HEADERS = \
+	generated/dsi_phy_7nm.xml.h \
+	generated/dsi_phy_10nm.xml.h \
+	generated/dsi_phy_14nm.xml.h \
+	generated/dsi_phy_20nm.xml.h \
+	generated/dsi_phy_28nm_8960.xml.h \
+	generated/dsi_phy_28nm.xml.h \
+	generated/dsi.xml.h \
+	generated/hdmi.xml.h \
+	generated/mdp4.xml.h \
+	generated/mdp5.xml.h \
+	generated/mdp_common.xml.h \
+	generated/mdss.xml.h \
+	generated/sfpb.xml.h
+
+$(addprefix $(obj)/,$(adreno-y)): $(addprefix $(obj)/,$(ADRENO_HEADERS))
+$(addprefix $(obj)/,$(msm-display-y)): $(addprefix $(obj)/,$(DISPLAY_HEADERS))
+
+targets += $(ADRENO_HEADERS) $(DISPLAY_HEADERS)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/NOTES
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/NOTES
@@ -0,0 +1,87 @@
+NOTES about msm drm/kms driver:
+
+In the current snapdragon SoC's, we have (at least) 3 different
+display controller blocks at play:
+ + MDP3 - ?? seems to be what is on geeksphone peak device
+ + MDP4 - S3 (APQ8060, touchpad), S4-pro (APQ8064, nexus4 & ifc6410)
+ + MDP5 - snapdragon 800
+
+(I don't have a completely clear picture on which display controller
+maps to which part #)
+
+Plus a handful of blocks around them for HDMI/DSI/etc output.
+
+And on gpu side of things:
+ + zero, one, or two 2d cores (z180)
+ + and either a2xx or a3xx 3d core.
+
+But, HDMI/DSI/etc blocks seem like they can be shared across multiple
+display controller blocks.  And I for sure don't want to have to deal
+with N different kms devices from xf86-video-freedreno.  Plus, it
+seems like we can do some clever tricks like use GPU to trigger
+pageflip after rendering completes (ie. have the kms/crtc code build
+up gpu cmdstream to update scanout and write FLUSH register after).
+
+So, the approach is one drm driver, with some modularity.  Different
+'struct msm_kms' implementations, depending on display controller.
+And one or more 'struct msm_gpu' for the various different gpu sub-
+modules.
+
+(Second part is not implemented yet.  So far this is just basic KMS
+driver, and not exposing any custom ioctls to userspace for now.)
+
+The kms module provides the plane, crtc, and encoder objects, and
+loads whatever connectors are appropriate.
+
+For MDP4, the mapping is:
+
+  plane   -> PIPE{RGBn,VGn}              \
+  crtc    -> OVLP{n} + DMA{P,S,E} (??)   |-> MDP "device"
+  encoder -> DTV/LCDC/DSI (within MDP4)  /
+  connector -> HDMI/DSI/etc              --> other device(s)
+
+Since the irq's that drm core mostly cares about are vblank/framedone,
+we'll let msm_mdp4_kms provide the irq install/uninstall/etc functions
+and treat the MDP4 block's irq as "the" irq.  Even though the connectors
+may have their own irqs which they install themselves.  For this reason
+the display controller is the "master" device.
+
+For MDP5, the mapping is:
+
+  plane   -> PIPE{RGBn,VIGn}             \
+  crtc    -> LM (layer mixer)            |-> MDP "device"
+  encoder -> INTF                        /
+  connector -> HDMI/DSI/eDP/etc          --> other device(s)
+
+Unlike MDP4, it appears we can get by with a single encoder, rather
+than needing a different implementation for DTV, DSI, etc.  (Ie. the
+register interface is same, just different bases.)
+
+Also unlike MDP4, with MDP5 all the IRQs for other blocks (HDMI, DSI,
+etc) are routed through MDP.
+
+And finally, MDP5 has this "Shared Memory Pool" (called "SMP"), from
+which blocks need to be allocated to the active pipes based on fetch
+stride.
+
+Each connector probably ends up being a separate device, just for the
+logistics of finding/mapping io region, irq, etc.  Idealy we would
+have a better way than just stashing the platform device in a global
+(ie. like DT super-node.. but I don't have any snapdragon hw yet that
+is using DT).
+
+Note that so far I've not been able to get any docs on the hw, and it
+seems that access to such docs would prevent me from working on the
+freedreno gallium driver.  So there may be some mistakes in register
+names (I had to invent a few, since no sufficient hint was given in
+the downstream android fbdev driver), bitfield sizes, etc.  My current
+state of understanding the registers is given in the envytools rnndb
+files at:
+
+  https://github.com/freedreno/envytools/tree/master/rnndb
+  (the mdp4/hdmi/dsi directories)
+
+These files are used both for a parser tool (in the same tree) to
+parse logged register reads/writes (both from downstream android fbdev
+driver, and this driver with register logging enabled), as well as to
+generate the register level headers.
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a2xx_catalog.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a2xx_catalog.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013-2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
+ */
+
+#include "adreno_gpu.h"
+
+static const struct adreno_info a2xx_gpus[] = {
+	{
+		.chip_ids = ADRENO_CHIP_IDS(0x02000000),
+		.family = ADRENO_2XX_GEN1,
+		.revn  = 200,
+		.fw = {
+			[ADRENO_FW_PM4] = "yamato_pm4.fw",
+			[ADRENO_FW_PFP] = "yamato_pfp.fw",
+		},
+		.gmem  = SZ_256K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a2xx_gpu_init,
+	}, { /* a200 on i.mx51 has only 128kib gmem */
+		.chip_ids = ADRENO_CHIP_IDS(0x02000001),
+		.family = ADRENO_2XX_GEN1,
+		.revn  = 201,
+		.fw = {
+			[ADRENO_FW_PM4] = "yamato_pm4.fw",
+			[ADRENO_FW_PFP] = "yamato_pfp.fw",
+		},
+		.gmem  = SZ_128K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a2xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x02020000),
+		.family = ADRENO_2XX_GEN2,
+		.revn  = 220,
+		.fw = {
+			[ADRENO_FW_PM4] = "leia_pm4_470.fw",
+			[ADRENO_FW_PFP] = "leia_pfp_470.fw",
+		},
+		.gmem  = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a2xx_gpu_init,
+	}
+};
+DECLARE_ADRENO_GPULIST(a2xx);
+
+MODULE_FIRMWARE("qcom/leia_pfp_470.fw");
+MODULE_FIRMWARE("qcom/leia_pm4_470.fw");
+MODULE_FIRMWARE("qcom/yamato_pfp.fw");
+MODULE_FIRMWARE("qcom/yamato_pm4.fw");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a2xx_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a2xx_gpu.c
@@ -0,0 +1,569 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018 The Linux Foundation. All rights reserved. */
+
+#include "a2xx_gpu.h"
+#include "msm_gem.h"
+#include "msm_mmu.h"
+
+extern bool hang_debug;
+
+static void a2xx_dump(struct msm_gpu *gpu);
+static bool a2xx_idle(struct msm_gpu *gpu);
+
+static void a2xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+{
+	struct msm_ringbuffer *ring = submit->ring;
+	unsigned int i;
+
+	for (i = 0; i < submit->nr_cmds; i++) {
+		switch (submit->cmd[i].type) {
+		case MSM_SUBMIT_CMD_IB_TARGET_BUF:
+			/* ignore IB-targets */
+			break;
+		case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+			/* ignore if there has not been a ctx switch: */
+			if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
+				break;
+			fallthrough;
+		case MSM_SUBMIT_CMD_BUF:
+			OUT_PKT3(ring, CP_INDIRECT_BUFFER_PFD, 2);
+			OUT_RING(ring, lower_32_bits(submit->cmd[i].iova));
+			OUT_RING(ring, submit->cmd[i].size);
+			OUT_PKT2(ring);
+			break;
+		}
+	}
+
+	OUT_PKT0(ring, REG_AXXX_CP_SCRATCH_REG2, 1);
+	OUT_RING(ring, submit->seqno);
+
+	/* wait for idle before cache flush/interrupt */
+	OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
+	OUT_RING(ring, 0x00000000);
+
+	OUT_PKT3(ring, CP_EVENT_WRITE, 3);
+	OUT_RING(ring, CACHE_FLUSH_TS);
+	OUT_RING(ring, rbmemptr(ring, fence));
+	OUT_RING(ring, submit->seqno);
+	OUT_PKT3(ring, CP_INTERRUPT, 1);
+	OUT_RING(ring, 0x80000000);
+
+	adreno_flush(gpu, ring, REG_AXXX_CP_RB_WPTR);
+}
+
+static bool a2xx_me_init(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a2xx_gpu *a2xx_gpu = to_a2xx_gpu(adreno_gpu);
+	struct msm_ringbuffer *ring = gpu->rb[0];
+
+	OUT_PKT3(ring, CP_ME_INIT, 18);
+
+	/* All fields present (bits 9:0) */
+	OUT_RING(ring, 0x000003ff);
+	/* Disable/Enable Real-Time Stream processing (present but ignored) */
+	OUT_RING(ring, 0x00000000);
+	/* Enable (2D <-> 3D) implicit synchronization (present but ignored) */
+	OUT_RING(ring, 0x00000000);
+
+	OUT_RING(ring, REG_A2XX_RB_SURFACE_INFO - 0x2000);
+	OUT_RING(ring, REG_A2XX_PA_SC_WINDOW_OFFSET - 0x2000);
+	OUT_RING(ring, REG_A2XX_VGT_MAX_VTX_INDX - 0x2000);
+	OUT_RING(ring, REG_A2XX_SQ_PROGRAM_CNTL - 0x2000);
+	OUT_RING(ring, REG_A2XX_RB_DEPTHCONTROL - 0x2000);
+	OUT_RING(ring, REG_A2XX_PA_SU_POINT_SIZE - 0x2000);
+	OUT_RING(ring, REG_A2XX_PA_SC_LINE_CNTL - 0x2000);
+	OUT_RING(ring, REG_A2XX_PA_SU_POLY_OFFSET_FRONT_SCALE - 0x2000);
+
+	/* Vertex and Pixel Shader Start Addresses in instructions
+	 * (3 DWORDS per instruction) */
+	OUT_RING(ring, 0x80000180);
+	/* Maximum Contexts */
+	OUT_RING(ring, 0x00000001);
+	/* Write Confirm Interval and The CP will wait the
+	 * wait_interval * 16 clocks between polling  */
+	OUT_RING(ring, 0x00000000);
+	/* NQ and External Memory Swap */
+	OUT_RING(ring, 0x00000000);
+	/* protected mode error checking (0x1f2 is REG_AXXX_CP_INT_CNTL) */
+	if (a2xx_gpu->protection_disabled)
+		OUT_RING(ring, 0x00000000);
+	else
+		OUT_RING(ring, 0x200001f2);
+	/* Disable header dumping and Header dump address */
+	OUT_RING(ring, 0x00000000);
+	/* Header dump size */
+	OUT_RING(ring, 0x00000000);
+
+	if (!a2xx_gpu->protection_disabled) {
+		/* enable protected mode */
+		OUT_PKT3(ring, CP_SET_PROTECTED_MODE, 1);
+		OUT_RING(ring, 1);
+	}
+
+	adreno_flush(gpu, ring, REG_AXXX_CP_RB_WPTR);
+	return a2xx_idle(gpu);
+}
+
+static int a2xx_hw_init(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a2xx_gpu *a2xx_gpu = to_a2xx_gpu(adreno_gpu);
+	dma_addr_t pt_base, tran_error;
+	uint32_t *ptr, len;
+	int i, ret;
+
+	a2xx_gpummu_params(gpu->aspace->mmu, &pt_base, &tran_error);
+
+	DBG("%s", gpu->name);
+
+	/* halt ME to avoid ucode upload issues on a20x */
+	gpu_write(gpu, REG_AXXX_CP_ME_CNTL, AXXX_CP_ME_CNTL_HALT);
+
+	gpu_write(gpu, REG_A2XX_RBBM_PM_OVERRIDE1, 0xfffffffe);
+	gpu_write(gpu, REG_A2XX_RBBM_PM_OVERRIDE2, 0xffffffff);
+
+	/* note: kgsl uses 0x00000001 after first reset on a22x */
+	gpu_write(gpu, REG_A2XX_RBBM_SOFT_RESET, 0xffffffff);
+	msleep(30);
+	gpu_write(gpu, REG_A2XX_RBBM_SOFT_RESET, 0x00000000);
+
+	if (adreno_is_a225(adreno_gpu))
+		gpu_write(gpu, REG_A2XX_SQ_FLOW_CONTROL, 0x18000000);
+
+	/* note: kgsl uses 0x0000ffff for a20x */
+	gpu_write(gpu, REG_A2XX_RBBM_CNTL, 0x00004442);
+
+	/* MPU: physical range */
+	gpu_write(gpu, REG_A2XX_MH_MMU_MPU_BASE, 0x00000000);
+	gpu_write(gpu, REG_A2XX_MH_MMU_MPU_END, 0xfffff000);
+
+	gpu_write(gpu, REG_A2XX_MH_MMU_CONFIG, A2XX_MH_MMU_CONFIG_MMU_ENABLE |
+		A2XX_MH_MMU_CONFIG_RB_W_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
+		A2XX_MH_MMU_CONFIG_CP_W_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
+		A2XX_MH_MMU_CONFIG_CP_R0_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
+		A2XX_MH_MMU_CONFIG_CP_R1_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
+		A2XX_MH_MMU_CONFIG_CP_R2_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
+		A2XX_MH_MMU_CONFIG_CP_R3_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
+		A2XX_MH_MMU_CONFIG_CP_R4_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
+		A2XX_MH_MMU_CONFIG_VGT_R0_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
+		A2XX_MH_MMU_CONFIG_VGT_R1_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
+		A2XX_MH_MMU_CONFIG_TC_R_CLNT_BEHAVIOR(BEH_TRAN_RNG) |
+		A2XX_MH_MMU_CONFIG_PA_W_CLNT_BEHAVIOR(BEH_TRAN_RNG));
+
+	/* same as parameters in adreno_gpu */
+	gpu_write(gpu, REG_A2XX_MH_MMU_VA_RANGE, SZ_16M |
+		A2XX_MH_MMU_VA_RANGE_NUM_64KB_REGIONS(0xfff));
+
+	gpu_write(gpu, REG_A2XX_MH_MMU_PT_BASE, pt_base);
+	gpu_write(gpu, REG_A2XX_MH_MMU_TRAN_ERROR, tran_error);
+
+	gpu_write(gpu, REG_A2XX_MH_MMU_INVALIDATE,
+		A2XX_MH_MMU_INVALIDATE_INVALIDATE_ALL |
+		A2XX_MH_MMU_INVALIDATE_INVALIDATE_TC);
+
+	gpu_write(gpu, REG_A2XX_MH_ARBITER_CONFIG,
+		A2XX_MH_ARBITER_CONFIG_SAME_PAGE_LIMIT(16) |
+		A2XX_MH_ARBITER_CONFIG_L1_ARB_ENABLE |
+		A2XX_MH_ARBITER_CONFIG_L1_ARB_HOLD_ENABLE |
+		A2XX_MH_ARBITER_CONFIG_PAGE_SIZE(1) |
+		A2XX_MH_ARBITER_CONFIG_TC_REORDER_ENABLE |
+		A2XX_MH_ARBITER_CONFIG_TC_ARB_HOLD_ENABLE |
+		A2XX_MH_ARBITER_CONFIG_IN_FLIGHT_LIMIT_ENABLE |
+		A2XX_MH_ARBITER_CONFIG_IN_FLIGHT_LIMIT(8) |
+		A2XX_MH_ARBITER_CONFIG_CP_CLNT_ENABLE |
+		A2XX_MH_ARBITER_CONFIG_VGT_CLNT_ENABLE |
+		A2XX_MH_ARBITER_CONFIG_TC_CLNT_ENABLE |
+		A2XX_MH_ARBITER_CONFIG_RB_CLNT_ENABLE |
+		A2XX_MH_ARBITER_CONFIG_PA_CLNT_ENABLE);
+	if (!adreno_is_a20x(adreno_gpu))
+		gpu_write(gpu, REG_A2XX_MH_CLNT_INTF_CTRL_CONFIG1, 0x00032f07);
+
+	gpu_write(gpu, REG_A2XX_SQ_VS_PROGRAM, 0x00000000);
+	gpu_write(gpu, REG_A2XX_SQ_PS_PROGRAM, 0x00000000);
+
+	gpu_write(gpu, REG_A2XX_RBBM_PM_OVERRIDE1, 0); /* 0x200 for msm8960? */
+	gpu_write(gpu, REG_A2XX_RBBM_PM_OVERRIDE2, 0); /* 0x80/0x1a0 for a22x? */
+
+	/* note: gsl doesn't set this */
+	gpu_write(gpu, REG_A2XX_RBBM_DEBUG, 0x00080000);
+
+	gpu_write(gpu, REG_A2XX_RBBM_INT_CNTL,
+		A2XX_RBBM_INT_CNTL_RDERR_INT_MASK);
+	gpu_write(gpu, REG_AXXX_CP_INT_CNTL,
+		AXXX_CP_INT_CNTL_T0_PACKET_IN_IB_MASK |
+		AXXX_CP_INT_CNTL_OPCODE_ERROR_MASK |
+		AXXX_CP_INT_CNTL_PROTECTED_MODE_ERROR_MASK |
+		AXXX_CP_INT_CNTL_RESERVED_BIT_ERROR_MASK |
+		AXXX_CP_INT_CNTL_IB_ERROR_MASK |
+		AXXX_CP_INT_CNTL_IB1_INT_MASK |
+		AXXX_CP_INT_CNTL_RB_INT_MASK);
+	gpu_write(gpu, REG_A2XX_SQ_INT_CNTL, 0);
+	gpu_write(gpu, REG_A2XX_MH_INTERRUPT_MASK,
+		A2XX_MH_INTERRUPT_MASK_AXI_READ_ERROR |
+		A2XX_MH_INTERRUPT_MASK_AXI_WRITE_ERROR |
+		A2XX_MH_INTERRUPT_MASK_MMU_PAGE_FAULT);
+
+	for (i = 3; i <= 5; i++)
+		if ((SZ_16K << i) == adreno_gpu->info->gmem)
+			break;
+	gpu_write(gpu, REG_A2XX_RB_EDRAM_INFO, i);
+
+	ret = adreno_hw_init(gpu);
+	if (ret)
+		return ret;
+
+	gpu_write(gpu, REG_AXXX_CP_RB_CNTL,
+		MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE);
+
+	gpu_write(gpu, REG_AXXX_CP_RB_BASE, lower_32_bits(gpu->rb[0]->iova));
+
+	/* NOTE: PM4/micro-engine firmware registers look to be the same
+	 * for a2xx and a3xx.. we could possibly push that part down to
+	 * adreno_gpu base class.  Or push both PM4 and PFP but
+	 * parameterize the pfp ucode addr/data registers..
+	 */
+
+	/* Load PM4: */
+	ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PM4]->data);
+	len = adreno_gpu->fw[ADRENO_FW_PM4]->size / 4;
+	DBG("loading PM4 ucode version: %x", ptr[1]);
+
+	/*
+	 * New firmware files seem to have GPU and firmware version in this
+	 * word (0x20xxxx for A200, 0x220xxx for A220, 0x225xxx for A225).
+	 * Older firmware files, which lack protection support, have 0 instead.
+	 */
+	if (ptr[1] == 0) {
+		dev_warn(gpu->dev->dev,
+			 "Legacy firmware detected, disabling protection support\n");
+		a2xx_gpu->protection_disabled = true;
+	}
+
+	gpu_write(gpu, REG_AXXX_CP_DEBUG,
+			AXXX_CP_DEBUG_MIU_128BIT_WRITE_ENABLE);
+	gpu_write(gpu, REG_AXXX_CP_ME_RAM_WADDR, 0);
+	for (i = 1; i < len; i++)
+		gpu_write(gpu, REG_AXXX_CP_ME_RAM_DATA, ptr[i]);
+
+	/* Load PFP: */
+	ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PFP]->data);
+	len = adreno_gpu->fw[ADRENO_FW_PFP]->size / 4;
+	DBG("loading PFP ucode version: %x", ptr[5]);
+
+	gpu_write(gpu, REG_A2XX_CP_PFP_UCODE_ADDR, 0);
+	for (i = 1; i < len; i++)
+		gpu_write(gpu, REG_A2XX_CP_PFP_UCODE_DATA, ptr[i]);
+
+	gpu_write(gpu, REG_AXXX_CP_QUEUE_THRESHOLDS, 0x000C0804);
+
+	/* clear ME_HALT to start micro engine */
+	gpu_write(gpu, REG_AXXX_CP_ME_CNTL, 0);
+
+	return a2xx_me_init(gpu) ? 0 : -EINVAL;
+}
+
+static void a2xx_recover(struct msm_gpu *gpu)
+{
+	int i;
+
+	adreno_dump_info(gpu);
+
+	for (i = 0; i < 8; i++) {
+		printk("CP_SCRATCH_REG%d: %u\n", i,
+			gpu_read(gpu, REG_AXXX_CP_SCRATCH_REG0 + i));
+	}
+
+	/* dump registers before resetting gpu, if enabled: */
+	if (hang_debug)
+		a2xx_dump(gpu);
+
+	gpu_write(gpu, REG_A2XX_RBBM_SOFT_RESET, 1);
+	gpu_read(gpu, REG_A2XX_RBBM_SOFT_RESET);
+	gpu_write(gpu, REG_A2XX_RBBM_SOFT_RESET, 0);
+	adreno_recover(gpu);
+}
+
+static void a2xx_destroy(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a2xx_gpu *a2xx_gpu = to_a2xx_gpu(adreno_gpu);
+
+	DBG("%s", gpu->name);
+
+	adreno_gpu_cleanup(adreno_gpu);
+
+	kfree(a2xx_gpu);
+}
+
+static bool a2xx_idle(struct msm_gpu *gpu)
+{
+	/* wait for ringbuffer to drain: */
+	if (!adreno_idle(gpu, gpu->rb[0]))
+		return false;
+
+	/* then wait for GPU to finish: */
+	if (spin_until(!(gpu_read(gpu, REG_A2XX_RBBM_STATUS) &
+			A2XX_RBBM_STATUS_GUI_ACTIVE))) {
+		DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name);
+
+		/* TODO maybe we need to reset GPU here to recover from hang? */
+		return false;
+	}
+
+	return true;
+}
+
+static irqreturn_t a2xx_irq(struct msm_gpu *gpu)
+{
+	uint32_t mstatus, status;
+
+	mstatus = gpu_read(gpu, REG_A2XX_MASTER_INT_SIGNAL);
+
+	if (mstatus & A2XX_MASTER_INT_SIGNAL_MH_INT_STAT) {
+		status = gpu_read(gpu, REG_A2XX_MH_INTERRUPT_STATUS);
+
+		dev_warn(gpu->dev->dev, "MH_INT: %08X\n", status);
+		dev_warn(gpu->dev->dev, "MMU_PAGE_FAULT: %08X\n",
+			gpu_read(gpu, REG_A2XX_MH_MMU_PAGE_FAULT));
+
+		gpu_write(gpu, REG_A2XX_MH_INTERRUPT_CLEAR, status);
+	}
+
+	if (mstatus & A2XX_MASTER_INT_SIGNAL_CP_INT_STAT) {
+		status = gpu_read(gpu, REG_AXXX_CP_INT_STATUS);
+
+		/* only RB_INT is expected */
+		if (status & ~AXXX_CP_INT_CNTL_RB_INT_MASK)
+			dev_warn(gpu->dev->dev, "CP_INT: %08X\n", status);
+
+		gpu_write(gpu, REG_AXXX_CP_INT_ACK, status);
+	}
+
+	if (mstatus & A2XX_MASTER_INT_SIGNAL_RBBM_INT_STAT) {
+		status = gpu_read(gpu, REG_A2XX_RBBM_INT_STATUS);
+
+		dev_warn(gpu->dev->dev, "RBBM_INT: %08X\n", status);
+
+		gpu_write(gpu, REG_A2XX_RBBM_INT_ACK, status);
+	}
+
+	msm_gpu_retire(gpu);
+
+	return IRQ_HANDLED;
+}
+
+static const unsigned int a200_registers[] = {
+	0x0000, 0x0002, 0x0004, 0x000B, 0x003B, 0x003D, 0x0040, 0x0044,
+	0x0046, 0x0047, 0x01C0, 0x01C1, 0x01C3, 0x01C8, 0x01D5, 0x01D9,
+	0x01DC, 0x01DD, 0x01EA, 0x01EA, 0x01EE, 0x01F3, 0x01F6, 0x01F7,
+	0x01FC, 0x01FF, 0x0391, 0x0392, 0x039B, 0x039E, 0x03B2, 0x03B5,
+	0x03B7, 0x03B7, 0x03F8, 0x03FB, 0x0440, 0x0440, 0x0443, 0x0444,
+	0x044B, 0x044B, 0x044D, 0x044F, 0x0452, 0x0452, 0x0454, 0x045B,
+	0x047F, 0x047F, 0x0578, 0x0587, 0x05C9, 0x05C9, 0x05D0, 0x05D0,
+	0x0601, 0x0604, 0x0606, 0x0609, 0x060B, 0x060E, 0x0613, 0x0614,
+	0x0A29, 0x0A2B, 0x0A2F, 0x0A31, 0x0A40, 0x0A43, 0x0A45, 0x0A45,
+	0x0A4E, 0x0A4F, 0x0C2C, 0x0C2C, 0x0C30, 0x0C30, 0x0C38, 0x0C3C,
+	0x0C40, 0x0C40, 0x0C44, 0x0C44, 0x0C80, 0x0C86, 0x0C88, 0x0C94,
+	0x0C99, 0x0C9A, 0x0CA4, 0x0CA5, 0x0D00, 0x0D03, 0x0D06, 0x0D06,
+	0x0D08, 0x0D0B, 0x0D34, 0x0D35, 0x0DAE, 0x0DC1, 0x0DC8, 0x0DD4,
+	0x0DD8, 0x0DD9, 0x0E00, 0x0E00, 0x0E02, 0x0E04, 0x0E17, 0x0E1E,
+	0x0EC0, 0x0EC9, 0x0ECB, 0x0ECC, 0x0ED0, 0x0ED0, 0x0ED4, 0x0ED7,
+	0x0EE0, 0x0EE2, 0x0F01, 0x0F02, 0x0F0C, 0x0F0C, 0x0F0E, 0x0F12,
+	0x0F26, 0x0F2A, 0x0F2C, 0x0F2C, 0x2000, 0x2002, 0x2006, 0x200F,
+	0x2080, 0x2082, 0x2100, 0x2109, 0x210C, 0x2114, 0x2180, 0x2184,
+	0x21F5, 0x21F7, 0x2200, 0x2208, 0x2280, 0x2283, 0x2293, 0x2294,
+	0x2300, 0x2308, 0x2312, 0x2312, 0x2316, 0x231D, 0x2324, 0x2326,
+	0x2380, 0x2383, 0x2400, 0x2402, 0x2406, 0x240F, 0x2480, 0x2482,
+	0x2500, 0x2509, 0x250C, 0x2514, 0x2580, 0x2584, 0x25F5, 0x25F7,
+	0x2600, 0x2608, 0x2680, 0x2683, 0x2693, 0x2694, 0x2700, 0x2708,
+	0x2712, 0x2712, 0x2716, 0x271D, 0x2724, 0x2726, 0x2780, 0x2783,
+	0x4000, 0x4003, 0x4800, 0x4805, 0x4900, 0x4900, 0x4908, 0x4908,
+	~0   /* sentinel */
+};
+
+static const unsigned int a220_registers[] = {
+	0x0000, 0x0002, 0x0004, 0x000B, 0x003B, 0x003D, 0x0040, 0x0044,
+	0x0046, 0x0047, 0x01C0, 0x01C1, 0x01C3, 0x01C8, 0x01D5, 0x01D9,
+	0x01DC, 0x01DD, 0x01EA, 0x01EA, 0x01EE, 0x01F3, 0x01F6, 0x01F7,
+	0x01FC, 0x01FF, 0x0391, 0x0392, 0x039B, 0x039E, 0x03B2, 0x03B5,
+	0x03B7, 0x03B7, 0x03F8, 0x03FB, 0x0440, 0x0440, 0x0443, 0x0444,
+	0x044B, 0x044B, 0x044D, 0x044F, 0x0452, 0x0452, 0x0454, 0x045B,
+	0x047F, 0x047F, 0x0578, 0x0587, 0x05C9, 0x05C9, 0x05D0, 0x05D0,
+	0x0601, 0x0604, 0x0606, 0x0609, 0x060B, 0x060E, 0x0613, 0x0614,
+	0x0A29, 0x0A2B, 0x0A2F, 0x0A31, 0x0A40, 0x0A40, 0x0A42, 0x0A43,
+	0x0A45, 0x0A45, 0x0A4E, 0x0A4F, 0x0C30, 0x0C30, 0x0C38, 0x0C39,
+	0x0C3C, 0x0C3C, 0x0C80, 0x0C81, 0x0C88, 0x0C93, 0x0D00, 0x0D03,
+	0x0D05, 0x0D06, 0x0D08, 0x0D0B, 0x0D34, 0x0D35, 0x0DAE, 0x0DC1,
+	0x0DC8, 0x0DD4, 0x0DD8, 0x0DD9, 0x0E00, 0x0E00, 0x0E02, 0x0E04,
+	0x0E17, 0x0E1E, 0x0EC0, 0x0EC9, 0x0ECB, 0x0ECC, 0x0ED0, 0x0ED0,
+	0x0ED4, 0x0ED7, 0x0EE0, 0x0EE2, 0x0F01, 0x0F02, 0x2000, 0x2002,
+	0x2006, 0x200F, 0x2080, 0x2082, 0x2100, 0x2102, 0x2104, 0x2109,
+	0x210C, 0x2114, 0x2180, 0x2184, 0x21F5, 0x21F7, 0x2200, 0x2202,
+	0x2204, 0x2204, 0x2208, 0x2208, 0x2280, 0x2282, 0x2294, 0x2294,
+	0x2300, 0x2308, 0x2309, 0x230A, 0x2312, 0x2312, 0x2316, 0x2316,
+	0x2318, 0x231D, 0x2324, 0x2326, 0x2380, 0x2383, 0x2400, 0x2402,
+	0x2406, 0x240F, 0x2480, 0x2482, 0x2500, 0x2502, 0x2504, 0x2509,
+	0x250C, 0x2514, 0x2580, 0x2584, 0x25F5, 0x25F7, 0x2600, 0x2602,
+	0x2604, 0x2606, 0x2608, 0x2608, 0x2680, 0x2682, 0x2694, 0x2694,
+	0x2700, 0x2708, 0x2712, 0x2712, 0x2716, 0x2716, 0x2718, 0x271D,
+	0x2724, 0x2726, 0x2780, 0x2783, 0x4000, 0x4003, 0x4800, 0x4805,
+	0x4900, 0x4900, 0x4908, 0x4908,
+	~0   /* sentinel */
+};
+
+static const unsigned int a225_registers[] = {
+	0x0000, 0x0002, 0x0004, 0x000B, 0x003B, 0x003D, 0x0040, 0x0044,
+	0x0046, 0x0047, 0x013C, 0x013C, 0x0140, 0x014F, 0x01C0, 0x01C1,
+	0x01C3, 0x01C8, 0x01D5, 0x01D9, 0x01DC, 0x01DD, 0x01EA, 0x01EA,
+	0x01EE, 0x01F3, 0x01F6, 0x01F7, 0x01FC, 0x01FF, 0x0391, 0x0392,
+	0x039B, 0x039E, 0x03B2, 0x03B5, 0x03B7, 0x03B7, 0x03F8, 0x03FB,
+	0x0440, 0x0440, 0x0443, 0x0444, 0x044B, 0x044B, 0x044D, 0x044F,
+	0x0452, 0x0452, 0x0454, 0x045B, 0x047F, 0x047F, 0x0578, 0x0587,
+	0x05C9, 0x05C9, 0x05D0, 0x05D0, 0x0601, 0x0604, 0x0606, 0x0609,
+	0x060B, 0x060E, 0x0613, 0x0614, 0x0A29, 0x0A2B, 0x0A2F, 0x0A31,
+	0x0A40, 0x0A40, 0x0A42, 0x0A43, 0x0A45, 0x0A45, 0x0A4E, 0x0A4F,
+	0x0C01, 0x0C1D, 0x0C30, 0x0C30, 0x0C38, 0x0C39, 0x0C3C, 0x0C3C,
+	0x0C80, 0x0C81, 0x0C88, 0x0C93, 0x0D00, 0x0D03, 0x0D05, 0x0D06,
+	0x0D08, 0x0D0B, 0x0D34, 0x0D35, 0x0DAE, 0x0DC1, 0x0DC8, 0x0DD4,
+	0x0DD8, 0x0DD9, 0x0E00, 0x0E00, 0x0E02, 0x0E04, 0x0E17, 0x0E1E,
+	0x0EC0, 0x0EC9, 0x0ECB, 0x0ECC, 0x0ED0, 0x0ED0, 0x0ED4, 0x0ED7,
+	0x0EE0, 0x0EE2, 0x0F01, 0x0F02, 0x2000, 0x200F, 0x2080, 0x2082,
+	0x2100, 0x2109, 0x210C, 0x2114, 0x2180, 0x2184, 0x21F5, 0x21F7,
+	0x2200, 0x2202, 0x2204, 0x2206, 0x2208, 0x2210, 0x2220, 0x2222,
+	0x2280, 0x2282, 0x2294, 0x2294, 0x2297, 0x2297, 0x2300, 0x230A,
+	0x2312, 0x2312, 0x2315, 0x2316, 0x2318, 0x231D, 0x2324, 0x2326,
+	0x2340, 0x2357, 0x2360, 0x2360, 0x2380, 0x2383, 0x2400, 0x240F,
+	0x2480, 0x2482, 0x2500, 0x2509, 0x250C, 0x2514, 0x2580, 0x2584,
+	0x25F5, 0x25F7, 0x2600, 0x2602, 0x2604, 0x2606, 0x2608, 0x2610,
+	0x2620, 0x2622, 0x2680, 0x2682, 0x2694, 0x2694, 0x2697, 0x2697,
+	0x2700, 0x270A, 0x2712, 0x2712, 0x2715, 0x2716, 0x2718, 0x271D,
+	0x2724, 0x2726, 0x2740, 0x2757, 0x2760, 0x2760, 0x2780, 0x2783,
+	0x4000, 0x4003, 0x4800, 0x4806, 0x4808, 0x4808, 0x4900, 0x4900,
+	0x4908, 0x4908,
+	~0   /* sentinel */
+};
+
+/* would be nice to not have to duplicate the _show() stuff with printk(): */
+static void a2xx_dump(struct msm_gpu *gpu)
+{
+	printk("status:   %08x\n",
+			gpu_read(gpu, REG_A2XX_RBBM_STATUS));
+	adreno_dump(gpu);
+}
+
+static struct msm_gpu_state *a2xx_gpu_state_get(struct msm_gpu *gpu)
+{
+	struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
+
+	if (!state)
+		return ERR_PTR(-ENOMEM);
+
+	adreno_gpu_state_get(gpu, state);
+
+	state->rbbm_status = gpu_read(gpu, REG_A2XX_RBBM_STATUS);
+
+	return state;
+}
+
+static struct msm_gem_address_space *
+a2xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev)
+{
+	struct msm_mmu *mmu = a2xx_gpummu_new(&pdev->dev, gpu);
+	struct msm_gem_address_space *aspace;
+
+	aspace = msm_gem_address_space_create(mmu, "gpu", SZ_16M,
+		0xfff * SZ_64K);
+
+	if (IS_ERR(aspace) && !IS_ERR(mmu))
+		mmu->funcs->destroy(mmu);
+
+	return aspace;
+}
+
+static u32 a2xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+	ring->memptrs->rptr = gpu_read(gpu, REG_AXXX_CP_RB_RPTR);
+	return ring->memptrs->rptr;
+}
+
+static const struct adreno_gpu_funcs funcs = {
+	.base = {
+		.get_param = adreno_get_param,
+		.set_param = adreno_set_param,
+		.hw_init = a2xx_hw_init,
+		.pm_suspend = msm_gpu_pm_suspend,
+		.pm_resume = msm_gpu_pm_resume,
+		.recover = a2xx_recover,
+		.submit = a2xx_submit,
+		.active_ring = adreno_active_ring,
+		.irq = a2xx_irq,
+		.destroy = a2xx_destroy,
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
+		.show = adreno_show,
+#endif
+		.gpu_state_get = a2xx_gpu_state_get,
+		.gpu_state_put = adreno_gpu_state_put,
+		.create_address_space = a2xx_create_address_space,
+		.get_rptr = a2xx_get_rptr,
+	},
+};
+
+static const struct msm_gpu_perfcntr perfcntrs[] = {
+/* TODO */
+};
+
+struct msm_gpu *a2xx_gpu_init(struct drm_device *dev)
+{
+	struct a2xx_gpu *a2xx_gpu = NULL;
+	struct adreno_gpu *adreno_gpu;
+	struct msm_gpu *gpu;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct platform_device *pdev = priv->gpu_pdev;
+	int ret;
+
+	if (!pdev) {
+		dev_err(dev->dev, "no a2xx device\n");
+		ret = -ENXIO;
+		goto fail;
+	}
+
+	a2xx_gpu = kzalloc(sizeof(*a2xx_gpu), GFP_KERNEL);
+	if (!a2xx_gpu) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	adreno_gpu = &a2xx_gpu->base;
+	gpu = &adreno_gpu->base;
+
+	gpu->perfcntrs = perfcntrs;
+	gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs);
+
+	ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
+	if (ret)
+		goto fail;
+
+	if (adreno_is_a20x(adreno_gpu))
+		adreno_gpu->registers = a200_registers;
+	else if (adreno_is_a225(adreno_gpu))
+		adreno_gpu->registers = a225_registers;
+	else
+		adreno_gpu->registers = a220_registers;
+
+	if (!gpu->aspace) {
+		dev_err(dev->dev, "No memory protection without MMU\n");
+		if (!allow_vram_carveout) {
+			ret = -ENXIO;
+			goto fail;
+		}
+	}
+
+	return gpu;
+
+fail:
+	if (a2xx_gpu)
+		a2xx_destroy(&a2xx_gpu->base.base);
+
+	return ERR_PTR(ret);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a2xx_gpu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a2xx_gpu.h
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018 The Linux Foundation. All rights reserved. */
+
+#ifndef __A2XX_GPU_H__
+#define __A2XX_GPU_H__
+
+#include "adreno_gpu.h"
+
+/* arrg, somehow fb.h is getting pulled in: */
+#undef ROP_COPY
+#undef ROP_XOR
+
+#include "a2xx.xml.h"
+
+struct a2xx_gpu {
+	struct adreno_gpu base;
+	bool pm_enabled;
+	bool protection_disabled;
+};
+#define to_a2xx_gpu(x) container_of(x, struct a2xx_gpu, base)
+
+struct msm_mmu *a2xx_gpummu_new(struct device *dev, struct msm_gpu *gpu);
+void a2xx_gpummu_params(struct msm_mmu *mmu, dma_addr_t *pt_base,
+		dma_addr_t *tran_error);
+
+#endif /* __A2XX_GPU_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a2xx_gpummu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a2xx_gpummu.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018 The Linux Foundation. All rights reserved. */
+
+#include <linux/dma-mapping.h>
+
+#include "msm_drv.h"
+#include "msm_mmu.h"
+
+#include "adreno_gpu.h"
+#include "a2xx_gpu.h"
+
+#include "a2xx.xml.h"
+
+struct a2xx_gpummu {
+	struct msm_mmu base;
+	struct msm_gpu *gpu;
+	dma_addr_t pt_base;
+	uint32_t *table;
+};
+#define to_a2xx_gpummu(x) container_of(x, struct a2xx_gpummu, base)
+
+#define GPUMMU_VA_START SZ_16M
+#define GPUMMU_VA_RANGE (0xfff * SZ_64K)
+#define GPUMMU_PAGE_SIZE SZ_4K
+#define TABLE_SIZE (sizeof(uint32_t) * GPUMMU_VA_RANGE / GPUMMU_PAGE_SIZE)
+
+static void a2xx_gpummu_detach(struct msm_mmu *mmu)
+{
+}
+
+static int a2xx_gpummu_map(struct msm_mmu *mmu, uint64_t iova,
+		struct sg_table *sgt, size_t len, int prot)
+{
+	struct a2xx_gpummu *gpummu = to_a2xx_gpummu(mmu);
+	unsigned idx = (iova - GPUMMU_VA_START) / GPUMMU_PAGE_SIZE;
+	struct sg_dma_page_iter dma_iter;
+	unsigned prot_bits = 0;
+
+	if (prot & IOMMU_WRITE)
+		prot_bits |= 1;
+	if (prot & IOMMU_READ)
+		prot_bits |= 2;
+
+	for_each_sgtable_dma_page(sgt, &dma_iter, 0) {
+		dma_addr_t addr = sg_page_iter_dma_address(&dma_iter);
+		int i;
+
+		for (i = 0; i < PAGE_SIZE; i += GPUMMU_PAGE_SIZE)
+			gpummu->table[idx++] = (addr + i) | prot_bits;
+	}
+
+	/* we can improve by deferring flush for multiple map() */
+	gpu_write(gpummu->gpu, REG_A2XX_MH_MMU_INVALIDATE,
+		A2XX_MH_MMU_INVALIDATE_INVALIDATE_ALL |
+		A2XX_MH_MMU_INVALIDATE_INVALIDATE_TC);
+	return 0;
+}
+
+static int a2xx_gpummu_unmap(struct msm_mmu *mmu, uint64_t iova, size_t len)
+{
+	struct a2xx_gpummu *gpummu = to_a2xx_gpummu(mmu);
+	unsigned idx = (iova - GPUMMU_VA_START) / GPUMMU_PAGE_SIZE;
+	unsigned i;
+
+	for (i = 0; i < len / GPUMMU_PAGE_SIZE; i++, idx++)
+                gpummu->table[idx] = 0;
+
+	gpu_write(gpummu->gpu, REG_A2XX_MH_MMU_INVALIDATE,
+		A2XX_MH_MMU_INVALIDATE_INVALIDATE_ALL |
+		A2XX_MH_MMU_INVALIDATE_INVALIDATE_TC);
+	return 0;
+}
+
+static void a2xx_gpummu_resume_translation(struct msm_mmu *mmu)
+{
+}
+
+static void a2xx_gpummu_destroy(struct msm_mmu *mmu)
+{
+	struct a2xx_gpummu *gpummu = to_a2xx_gpummu(mmu);
+
+	dma_free_attrs(mmu->dev, TABLE_SIZE, gpummu->table, gpummu->pt_base,
+		DMA_ATTR_FORCE_CONTIGUOUS);
+
+	kfree(gpummu);
+}
+
+static const struct msm_mmu_funcs funcs = {
+		.detach = a2xx_gpummu_detach,
+		.map = a2xx_gpummu_map,
+		.unmap = a2xx_gpummu_unmap,
+		.destroy = a2xx_gpummu_destroy,
+		.resume_translation = a2xx_gpummu_resume_translation,
+};
+
+struct msm_mmu *a2xx_gpummu_new(struct device *dev, struct msm_gpu *gpu)
+{
+	struct a2xx_gpummu *gpummu;
+
+	gpummu = kzalloc(sizeof(*gpummu), GFP_KERNEL);
+	if (!gpummu)
+		return ERR_PTR(-ENOMEM);
+
+	gpummu->table = dma_alloc_attrs(dev, TABLE_SIZE + 32, &gpummu->pt_base,
+		GFP_KERNEL | __GFP_ZERO, DMA_ATTR_FORCE_CONTIGUOUS);
+	if (!gpummu->table) {
+		kfree(gpummu);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	gpummu->gpu = gpu;
+	msm_mmu_init(&gpummu->base, dev, &funcs, MSM_MMU_GPUMMU);
+
+	return &gpummu->base;
+}
+
+void a2xx_gpummu_params(struct msm_mmu *mmu, dma_addr_t *pt_base,
+		dma_addr_t *tran_error)
+{
+	dma_addr_t base = to_a2xx_gpummu(mmu)->pt_base;
+
+	*pt_base = base;
+	*tran_error = base + TABLE_SIZE; /* 32-byte aligned */
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a3xx_catalog.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a3xx_catalog.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013-2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
+ */
+
+#include "adreno_gpu.h"
+
+static const struct adreno_info a3xx_gpus[] = {
+	{
+		.chip_ids = ADRENO_CHIP_IDS(0x03000512),
+		.family = ADRENO_3XX,
+		.fw = {
+			[ADRENO_FW_PM4] = "a330_pm4.fw",
+			[ADRENO_FW_PFP] = "a330_pfp.fw",
+		},
+		.gmem  = SZ_128K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a3xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x03000520),
+		.family = ADRENO_3XX,
+		.revn  = 305,
+		.fw = {
+			[ADRENO_FW_PM4] = "a300_pm4.fw",
+			[ADRENO_FW_PFP] = "a300_pfp.fw",
+		},
+		.gmem  = SZ_256K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a3xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x03000600),
+		.family = ADRENO_3XX,
+		.revn  = 307,        /* because a305c is revn==306 */
+		.fw = {
+			[ADRENO_FW_PM4] = "a300_pm4.fw",
+			[ADRENO_FW_PFP] = "a300_pfp.fw",
+		},
+		.gmem  = SZ_128K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a3xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(
+			0x03020000,
+			0x03020001,
+			0x03020002
+		),
+		.family = ADRENO_3XX,
+		.revn  = 320,
+		.fw = {
+			[ADRENO_FW_PM4] = "a300_pm4.fw",
+			[ADRENO_FW_PFP] = "a300_pfp.fw",
+		},
+		.gmem  = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a3xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(
+			0x03030000,
+			0x03030001,
+			0x03030002
+		),
+		.family = ADRENO_3XX,
+		.revn  = 330,
+		.fw = {
+			[ADRENO_FW_PM4] = "a330_pm4.fw",
+			[ADRENO_FW_PFP] = "a330_pfp.fw",
+		},
+		.gmem  = SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a3xx_gpu_init,
+	}
+};
+DECLARE_ADRENO_GPULIST(a3xx);
+
+MODULE_FIRMWARE("qcom/a300_pm4.fw");
+MODULE_FIRMWARE("qcom/a300_pfp.fw");
+MODULE_FIRMWARE("qcom/a330_pm4.fw");
+MODULE_FIRMWARE("qcom/a330_pfp.fw");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a3xx_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a3xx_gpu.c
@@ -0,0 +1,622 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ */
+
+#include "a3xx_gpu.h"
+
+#define A3XX_INT0_MASK \
+	(A3XX_INT0_RBBM_AHB_ERROR |        \
+	 A3XX_INT0_RBBM_ATB_BUS_OVERFLOW | \
+	 A3XX_INT0_CP_T0_PACKET_IN_IB |    \
+	 A3XX_INT0_CP_OPCODE_ERROR |       \
+	 A3XX_INT0_CP_RESERVED_BIT_ERROR | \
+	 A3XX_INT0_CP_HW_FAULT |           \
+	 A3XX_INT0_CP_IB1_INT |            \
+	 A3XX_INT0_CP_IB2_INT |            \
+	 A3XX_INT0_CP_RB_INT |             \
+	 A3XX_INT0_CP_REG_PROTECT_FAULT |  \
+	 A3XX_INT0_CP_AHB_ERROR_HALT |     \
+	 A3XX_INT0_CACHE_FLUSH_TS |        \
+	 A3XX_INT0_UCHE_OOB_ACCESS)
+
+extern bool hang_debug;
+
+static void a3xx_dump(struct msm_gpu *gpu);
+static bool a3xx_idle(struct msm_gpu *gpu);
+
+static void a3xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+{
+	struct msm_ringbuffer *ring = submit->ring;
+	unsigned int i;
+
+	for (i = 0; i < submit->nr_cmds; i++) {
+		switch (submit->cmd[i].type) {
+		case MSM_SUBMIT_CMD_IB_TARGET_BUF:
+			/* ignore IB-targets */
+			break;
+		case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+			/* ignore if there has not been a ctx switch: */
+			if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
+				break;
+			fallthrough;
+		case MSM_SUBMIT_CMD_BUF:
+			OUT_PKT3(ring, CP_INDIRECT_BUFFER_PFD, 2);
+			OUT_RING(ring, lower_32_bits(submit->cmd[i].iova));
+			OUT_RING(ring, submit->cmd[i].size);
+			OUT_PKT2(ring);
+			break;
+		}
+	}
+
+	OUT_PKT0(ring, REG_AXXX_CP_SCRATCH_REG2, 1);
+	OUT_RING(ring, submit->seqno);
+
+	/* Flush HLSQ lazy updates to make sure there is nothing
+	 * pending for indirect loads after the timestamp has
+	 * passed:
+	 */
+	OUT_PKT3(ring, CP_EVENT_WRITE, 1);
+	OUT_RING(ring, HLSQ_FLUSH);
+
+	/* wait for idle before cache flush/interrupt */
+	OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
+	OUT_RING(ring, 0x00000000);
+
+	/* BIT(31) of CACHE_FLUSH_TS triggers CACHE_FLUSH_TS IRQ from GPU */
+	OUT_PKT3(ring, CP_EVENT_WRITE, 3);
+	OUT_RING(ring, CACHE_FLUSH_TS | CP_EVENT_WRITE_0_IRQ);
+	OUT_RING(ring, rbmemptr(ring, fence));
+	OUT_RING(ring, submit->seqno);
+
+#if 0
+	/* Dummy set-constant to trigger context rollover */
+	OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+	OUT_RING(ring, CP_REG(REG_A3XX_HLSQ_CL_KERNEL_GROUP_X_REG));
+	OUT_RING(ring, 0x00000000);
+#endif
+
+	adreno_flush(gpu, ring, REG_AXXX_CP_RB_WPTR);
+}
+
+static bool a3xx_me_init(struct msm_gpu *gpu)
+{
+	struct msm_ringbuffer *ring = gpu->rb[0];
+
+	OUT_PKT3(ring, CP_ME_INIT, 17);
+	OUT_RING(ring, 0x000003f7);
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000080);
+	OUT_RING(ring, 0x00000100);
+	OUT_RING(ring, 0x00000180);
+	OUT_RING(ring, 0x00006600);
+	OUT_RING(ring, 0x00000150);
+	OUT_RING(ring, 0x0000014e);
+	OUT_RING(ring, 0x00000154);
+	OUT_RING(ring, 0x00000001);
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+
+	adreno_flush(gpu, ring, REG_AXXX_CP_RB_WPTR);
+	return a3xx_idle(gpu);
+}
+
+static int a3xx_hw_init(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a3xx_gpu *a3xx_gpu = to_a3xx_gpu(adreno_gpu);
+	uint32_t *ptr, len;
+	int i, ret;
+
+	DBG("%s", gpu->name);
+
+	if (adreno_is_a305(adreno_gpu)) {
+		/* Set up 16 deep read/write request queues: */
+		gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x10101010);
+		gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF1, 0x10101010);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x10101010);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x10101010);
+		gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303);
+		gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x10101010);
+		gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF1, 0x10101010);
+		/* Enable WR-REQ: */
+		gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x0000ff);
+		/* Set up round robin arbitration between both AXI ports: */
+		gpu_write(gpu, REG_A3XX_VBIF_ARB_CTL, 0x00000030);
+		/* Set up AOOO: */
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003c);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO, 0x003c003c);
+	} else if (adreno_is_a305b(adreno_gpu)) {
+		gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x00181818);
+		gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x00181818);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x00000018);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x00000018);
+		gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x00000303);
+		gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003);
+	} else if (adreno_is_a306(adreno_gpu)) {
+		gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x0000000a);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x0000000a);
+	} else if (adreno_is_a320(adreno_gpu)) {
+		/* Set up 16 deep read/write request queues: */
+		gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x10101010);
+		gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF1, 0x10101010);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x10101010);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x10101010);
+		gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303);
+		gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x10101010);
+		gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF1, 0x10101010);
+		/* Enable WR-REQ: */
+		gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x0000ff);
+		/* Set up round robin arbitration between both AXI ports: */
+		gpu_write(gpu, REG_A3XX_VBIF_ARB_CTL, 0x00000030);
+		/* Set up AOOO: */
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003c);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO, 0x003c003c);
+		/* Enable 1K sort: */
+		gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT, 0x000000ff);
+		gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT_CONF, 0x000000a4);
+
+	} else if (adreno_is_a330v2(adreno_gpu)) {
+		/*
+		 * Most of the VBIF registers on 8974v2 have the correct
+		 * values at power on, so we won't modify those if we don't
+		 * need to
+		 */
+		/* Enable 1k sort: */
+		gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT, 0x0001003f);
+		gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT_CONF, 0x000000a4);
+		/* Enable WR-REQ: */
+		gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x00003f);
+		gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303);
+		/* Set up VBIF_ROUND_ROBIN_QOS_ARB: */
+		gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0003);
+
+	} else if (adreno_is_a330(adreno_gpu)) {
+		/* Set up 16 deep read/write request queues: */
+		gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x18181818);
+		gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF1, 0x18181818);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x18181818);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x18181818);
+		gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303);
+		gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x18181818);
+		gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF1, 0x18181818);
+		/* Enable WR-REQ: */
+		gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x00003f);
+		/* Set up round robin arbitration between both AXI ports: */
+		gpu_write(gpu, REG_A3XX_VBIF_ARB_CTL, 0x00000030);
+		/* Set up VBIF_ROUND_ROBIN_QOS_ARB: */
+		gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0001);
+		/* Set up AOOO: */
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003f);
+		gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO, 0x003f003f);
+		/* Enable 1K sort: */
+		gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT, 0x0001003f);
+		gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT_CONF, 0x000000a4);
+		/* Disable VBIF clock gating. This is to enable AXI running
+		 * higher frequency than GPU:
+		 */
+		gpu_write(gpu, REG_A3XX_VBIF_CLKON, 0x00000001);
+
+	} else {
+		BUG();
+	}
+
+	/* Make all blocks contribute to the GPU BUSY perf counter: */
+	gpu_write(gpu, REG_A3XX_RBBM_GPU_BUSY_MASKED, 0xffffffff);
+
+	/* Tune the hystersis counters for SP and CP idle detection: */
+	gpu_write(gpu, REG_A3XX_RBBM_SP_HYST_CNT, 0x10);
+	gpu_write(gpu, REG_A3XX_RBBM_WAIT_IDLE_CLOCKS_CTL, 0x10);
+
+	/* Enable the RBBM error reporting bits.  This lets us get
+	 * useful information on failure:
+	 */
+	gpu_write(gpu, REG_A3XX_RBBM_AHB_CTL0, 0x00000001);
+
+	/* Enable AHB error reporting: */
+	gpu_write(gpu, REG_A3XX_RBBM_AHB_CTL1, 0xa6ffffff);
+
+	/* Turn on the power counters: */
+	gpu_write(gpu, REG_A3XX_RBBM_RBBM_CTL, 0x00030000);
+
+	/* Turn on hang detection - this spews a lot of useful information
+	 * into the RBBM registers on a hang:
+	 */
+	gpu_write(gpu, REG_A3XX_RBBM_INTERFACE_HANG_INT_CTL, 0x00010fff);
+
+	/* Enable 64-byte cacheline size. HW Default is 32-byte (0x000000E0): */
+	gpu_write(gpu, REG_A3XX_UCHE_CACHE_MODE_CONTROL_REG, 0x00000001);
+
+	/* Enable Clock gating: */
+	if (adreno_is_a305b(adreno_gpu) || adreno_is_a306(adreno_gpu))
+		gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0xaaaaaaaa);
+	else if (adreno_is_a320(adreno_gpu))
+		gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0xbfffffff);
+	else if (adreno_is_a330v2(adreno_gpu))
+		gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0xaaaaaaaa);
+	else if (adreno_is_a330(adreno_gpu))
+		gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0xbffcffff);
+
+	if (adreno_is_a330v2(adreno_gpu))
+		gpu_write(gpu, REG_A3XX_RBBM_GPR0_CTL, 0x05515455);
+	else if (adreno_is_a330(adreno_gpu))
+		gpu_write(gpu, REG_A3XX_RBBM_GPR0_CTL, 0x00000000);
+
+	/* Set the OCMEM base address for A330, etc */
+	if (a3xx_gpu->ocmem.hdl) {
+		gpu_write(gpu, REG_A3XX_RB_GMEM_BASE_ADDR,
+			(unsigned int)(a3xx_gpu->ocmem.base >> 14));
+	}
+
+	/* Turn on performance counters: */
+	gpu_write(gpu, REG_A3XX_RBBM_PERFCTR_CTL, 0x01);
+
+	/* Enable the perfcntrs that we use.. */
+	for (i = 0; i < gpu->num_perfcntrs; i++) {
+		const struct msm_gpu_perfcntr *perfcntr = &gpu->perfcntrs[i];
+		gpu_write(gpu, perfcntr->select_reg, perfcntr->select_val);
+	}
+
+	gpu_write(gpu, REG_A3XX_RBBM_INT_0_MASK, A3XX_INT0_MASK);
+
+	ret = adreno_hw_init(gpu);
+	if (ret)
+		return ret;
+
+	/*
+	 * Use the default ringbuffer size and block size but disable the RPTR
+	 * shadow
+	 */
+	gpu_write(gpu, REG_AXXX_CP_RB_CNTL,
+		MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE);
+
+	/* Set the ringbuffer address */
+	gpu_write(gpu, REG_AXXX_CP_RB_BASE, lower_32_bits(gpu->rb[0]->iova));
+
+	/* setup access protection: */
+	gpu_write(gpu, REG_A3XX_CP_PROTECT_CTRL, 0x00000007);
+
+	/* RBBM registers */
+	gpu_write(gpu, REG_A3XX_CP_PROTECT(0), 0x63000040);
+	gpu_write(gpu, REG_A3XX_CP_PROTECT(1), 0x62000080);
+	gpu_write(gpu, REG_A3XX_CP_PROTECT(2), 0x600000cc);
+	gpu_write(gpu, REG_A3XX_CP_PROTECT(3), 0x60000108);
+	gpu_write(gpu, REG_A3XX_CP_PROTECT(4), 0x64000140);
+	gpu_write(gpu, REG_A3XX_CP_PROTECT(5), 0x66000400);
+
+	/* CP registers */
+	gpu_write(gpu, REG_A3XX_CP_PROTECT(6), 0x65000700);
+	gpu_write(gpu, REG_A3XX_CP_PROTECT(7), 0x610007d8);
+	gpu_write(gpu, REG_A3XX_CP_PROTECT(8), 0x620007e0);
+	gpu_write(gpu, REG_A3XX_CP_PROTECT(9), 0x61001178);
+	gpu_write(gpu, REG_A3XX_CP_PROTECT(10), 0x64001180);
+
+	/* RB registers */
+	gpu_write(gpu, REG_A3XX_CP_PROTECT(11), 0x60003300);
+
+	/* VBIF registers */
+	gpu_write(gpu, REG_A3XX_CP_PROTECT(12), 0x6b00c000);
+
+	/* NOTE: PM4/micro-engine firmware registers look to be the same
+	 * for a2xx and a3xx.. we could possibly push that part down to
+	 * adreno_gpu base class.  Or push both PM4 and PFP but
+	 * parameterize the pfp ucode addr/data registers..
+	 */
+
+	/* Load PM4: */
+	ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PM4]->data);
+	len = adreno_gpu->fw[ADRENO_FW_PM4]->size / 4;
+	DBG("loading PM4 ucode version: %x", ptr[1]);
+
+	gpu_write(gpu, REG_AXXX_CP_DEBUG,
+			AXXX_CP_DEBUG_DYNAMIC_CLK_DISABLE |
+			AXXX_CP_DEBUG_MIU_128BIT_WRITE_ENABLE);
+	gpu_write(gpu, REG_AXXX_CP_ME_RAM_WADDR, 0);
+	for (i = 1; i < len; i++)
+		gpu_write(gpu, REG_AXXX_CP_ME_RAM_DATA, ptr[i]);
+
+	/* Load PFP: */
+	ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PFP]->data);
+	len = adreno_gpu->fw[ADRENO_FW_PFP]->size / 4;
+	DBG("loading PFP ucode version: %x", ptr[5]);
+
+	gpu_write(gpu, REG_A3XX_CP_PFP_UCODE_ADDR, 0);
+	for (i = 1; i < len; i++)
+		gpu_write(gpu, REG_A3XX_CP_PFP_UCODE_DATA, ptr[i]);
+
+	/* CP ROQ queue sizes (bytes) - RB:16, ST:16, IB1:32, IB2:64 */
+	if (adreno_is_a305(adreno_gpu) || adreno_is_a306(adreno_gpu) ||
+			adreno_is_a320(adreno_gpu)) {
+		gpu_write(gpu, REG_AXXX_CP_QUEUE_THRESHOLDS,
+				AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB1_START(2) |
+				AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB2_START(6) |
+				AXXX_CP_QUEUE_THRESHOLDS_CSQ_ST_START(14));
+	} else if (adreno_is_a330(adreno_gpu) || adreno_is_a305b(adreno_gpu)) {
+		/* NOTE: this (value take from downstream android driver)
+		 * includes some bits outside of the known bitfields.  But
+		 * A330 has this "MERCIU queue" thing too, which might
+		 * explain a new bitfield or reshuffling:
+		 */
+		gpu_write(gpu, REG_AXXX_CP_QUEUE_THRESHOLDS, 0x003e2008);
+	}
+
+	/* clear ME_HALT to start micro engine */
+	gpu_write(gpu, REG_AXXX_CP_ME_CNTL, 0);
+
+	return a3xx_me_init(gpu) ? 0 : -EINVAL;
+}
+
+static void a3xx_recover(struct msm_gpu *gpu)
+{
+	int i;
+
+	adreno_dump_info(gpu);
+
+	for (i = 0; i < 8; i++) {
+		printk("CP_SCRATCH_REG%d: %u\n", i,
+			gpu_read(gpu, REG_AXXX_CP_SCRATCH_REG0 + i));
+	}
+
+	/* dump registers before resetting gpu, if enabled: */
+	if (hang_debug)
+		a3xx_dump(gpu);
+
+	gpu_write(gpu, REG_A3XX_RBBM_SW_RESET_CMD, 1);
+	gpu_read(gpu, REG_A3XX_RBBM_SW_RESET_CMD);
+	gpu_write(gpu, REG_A3XX_RBBM_SW_RESET_CMD, 0);
+	adreno_recover(gpu);
+}
+
+static void a3xx_destroy(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a3xx_gpu *a3xx_gpu = to_a3xx_gpu(adreno_gpu);
+
+	DBG("%s", gpu->name);
+
+	adreno_gpu_cleanup(adreno_gpu);
+
+	adreno_gpu_ocmem_cleanup(&a3xx_gpu->ocmem);
+
+	kfree(a3xx_gpu);
+}
+
+static bool a3xx_idle(struct msm_gpu *gpu)
+{
+	/* wait for ringbuffer to drain: */
+	if (!adreno_idle(gpu, gpu->rb[0]))
+		return false;
+
+	/* then wait for GPU to finish: */
+	if (spin_until(!(gpu_read(gpu, REG_A3XX_RBBM_STATUS) &
+			A3XX_RBBM_STATUS_GPU_BUSY))) {
+		DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name);
+
+		/* TODO maybe we need to reset GPU here to recover from hang? */
+		return false;
+	}
+
+	return true;
+}
+
+static irqreturn_t a3xx_irq(struct msm_gpu *gpu)
+{
+	uint32_t status;
+
+	status = gpu_read(gpu, REG_A3XX_RBBM_INT_0_STATUS);
+	DBG("%s: %08x", gpu->name, status);
+
+	// TODO
+
+	gpu_write(gpu, REG_A3XX_RBBM_INT_CLEAR_CMD, status);
+
+	msm_gpu_retire(gpu);
+
+	return IRQ_HANDLED;
+}
+
+static const unsigned int a3xx_registers[] = {
+	0x0000, 0x0002, 0x0010, 0x0012, 0x0018, 0x0018, 0x0020, 0x0027,
+	0x0029, 0x002b, 0x002e, 0x0033, 0x0040, 0x0042, 0x0050, 0x005c,
+	0x0060, 0x006c, 0x0080, 0x0082, 0x0084, 0x0088, 0x0090, 0x00e5,
+	0x00ea, 0x00ed, 0x0100, 0x0100, 0x0110, 0x0123, 0x01c0, 0x01c1,
+	0x01c3, 0x01c5, 0x01c7, 0x01c7, 0x01d5, 0x01d9, 0x01dc, 0x01dd,
+	0x01ea, 0x01ea, 0x01ee, 0x01f1, 0x01f5, 0x01f5, 0x01fc, 0x01ff,
+	0x0440, 0x0440, 0x0443, 0x0443, 0x0445, 0x0445, 0x044d, 0x044f,
+	0x0452, 0x0452, 0x0454, 0x046f, 0x047c, 0x047c, 0x047f, 0x047f,
+	0x0578, 0x057f, 0x0600, 0x0602, 0x0605, 0x0607, 0x060a, 0x060e,
+	0x0612, 0x0614, 0x0c01, 0x0c02, 0x0c06, 0x0c1d, 0x0c3d, 0x0c3f,
+	0x0c48, 0x0c4b, 0x0c80, 0x0c80, 0x0c88, 0x0c8b, 0x0ca0, 0x0cb7,
+	0x0cc0, 0x0cc1, 0x0cc6, 0x0cc7, 0x0ce4, 0x0ce5, 0x0e00, 0x0e05,
+	0x0e0c, 0x0e0c, 0x0e22, 0x0e23, 0x0e41, 0x0e45, 0x0e64, 0x0e65,
+	0x0e80, 0x0e82, 0x0e84, 0x0e89, 0x0ea0, 0x0ea1, 0x0ea4, 0x0ea7,
+	0x0ec4, 0x0ecb, 0x0ee0, 0x0ee0, 0x0f00, 0x0f01, 0x0f03, 0x0f09,
+	0x2040, 0x2040, 0x2044, 0x2044, 0x2048, 0x204d, 0x2068, 0x2069,
+	0x206c, 0x206d, 0x2070, 0x2070, 0x2072, 0x2072, 0x2074, 0x2075,
+	0x2079, 0x207a, 0x20c0, 0x20d3, 0x20e4, 0x20ef, 0x2100, 0x2109,
+	0x210c, 0x210c, 0x210e, 0x210e, 0x2110, 0x2111, 0x2114, 0x2115,
+	0x21e4, 0x21e4, 0x21ea, 0x21ea, 0x21ec, 0x21ed, 0x21f0, 0x21f0,
+	0x2200, 0x2212, 0x2214, 0x2217, 0x221a, 0x221a, 0x2240, 0x227e,
+	0x2280, 0x228b, 0x22c0, 0x22c0, 0x22c4, 0x22ce, 0x22d0, 0x22d8,
+	0x22df, 0x22e6, 0x22e8, 0x22e9, 0x22ec, 0x22ec, 0x22f0, 0x22f7,
+	0x22ff, 0x22ff, 0x2340, 0x2343, 0x2440, 0x2440, 0x2444, 0x2444,
+	0x2448, 0x244d, 0x2468, 0x2469, 0x246c, 0x246d, 0x2470, 0x2470,
+	0x2472, 0x2472, 0x2474, 0x2475, 0x2479, 0x247a, 0x24c0, 0x24d3,
+	0x24e4, 0x24ef, 0x2500, 0x2509, 0x250c, 0x250c, 0x250e, 0x250e,
+	0x2510, 0x2511, 0x2514, 0x2515, 0x25e4, 0x25e4, 0x25ea, 0x25ea,
+	0x25ec, 0x25ed, 0x25f0, 0x25f0, 0x2600, 0x2612, 0x2614, 0x2617,
+	0x261a, 0x261a, 0x2640, 0x267e, 0x2680, 0x268b, 0x26c0, 0x26c0,
+	0x26c4, 0x26ce, 0x26d0, 0x26d8, 0x26df, 0x26e6, 0x26e8, 0x26e9,
+	0x26ec, 0x26ec, 0x26f0, 0x26f7, 0x26ff, 0x26ff, 0x2740, 0x2743,
+	0x300c, 0x300e, 0x301c, 0x301d, 0x302a, 0x302a, 0x302c, 0x302d,
+	0x3030, 0x3031, 0x3034, 0x3036, 0x303c, 0x303c, 0x305e, 0x305f,
+	~0   /* sentinel */
+};
+
+/* would be nice to not have to duplicate the _show() stuff with printk(): */
+static void a3xx_dump(struct msm_gpu *gpu)
+{
+	printk("status:   %08x\n",
+			gpu_read(gpu, REG_A3XX_RBBM_STATUS));
+	adreno_dump(gpu);
+}
+
+static struct msm_gpu_state *a3xx_gpu_state_get(struct msm_gpu *gpu)
+{
+	struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
+
+	if (!state)
+		return ERR_PTR(-ENOMEM);
+
+	adreno_gpu_state_get(gpu, state);
+
+	state->rbbm_status = gpu_read(gpu, REG_A3XX_RBBM_STATUS);
+
+	return state;
+}
+
+static u64 a3xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate)
+{
+	u64 busy_cycles;
+
+	busy_cycles = gpu_read64(gpu, REG_A3XX_RBBM_PERFCTR_RBBM_1_LO);
+	*out_sample_rate = clk_get_rate(gpu->core_clk);
+
+	return busy_cycles;
+}
+
+static u32 a3xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+	ring->memptrs->rptr = gpu_read(gpu, REG_AXXX_CP_RB_RPTR);
+	return ring->memptrs->rptr;
+}
+
+static const struct adreno_gpu_funcs funcs = {
+	.base = {
+		.get_param = adreno_get_param,
+		.set_param = adreno_set_param,
+		.hw_init = a3xx_hw_init,
+		.pm_suspend = msm_gpu_pm_suspend,
+		.pm_resume = msm_gpu_pm_resume,
+		.recover = a3xx_recover,
+		.submit = a3xx_submit,
+		.active_ring = adreno_active_ring,
+		.irq = a3xx_irq,
+		.destroy = a3xx_destroy,
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
+		.show = adreno_show,
+#endif
+		.gpu_busy = a3xx_gpu_busy,
+		.gpu_state_get = a3xx_gpu_state_get,
+		.gpu_state_put = adreno_gpu_state_put,
+		.create_address_space = adreno_create_address_space,
+		.get_rptr = a3xx_get_rptr,
+	},
+};
+
+static const struct msm_gpu_perfcntr perfcntrs[] = {
+	{ REG_A3XX_SP_PERFCOUNTER6_SELECT, REG_A3XX_RBBM_PERFCTR_SP_6_LO,
+			SP_ALU_ACTIVE_CYCLES, "ALUACTIVE" },
+	{ REG_A3XX_SP_PERFCOUNTER7_SELECT, REG_A3XX_RBBM_PERFCTR_SP_7_LO,
+			SP_FS_FULL_ALU_INSTRUCTIONS, "ALUFULL" },
+};
+
+struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
+{
+	struct a3xx_gpu *a3xx_gpu = NULL;
+	struct adreno_gpu *adreno_gpu;
+	struct msm_gpu *gpu;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct platform_device *pdev = priv->gpu_pdev;
+	struct icc_path *ocmem_icc_path;
+	struct icc_path *icc_path;
+	int ret;
+
+	if (!pdev) {
+		DRM_DEV_ERROR(dev->dev, "no a3xx device\n");
+		ret = -ENXIO;
+		goto fail;
+	}
+
+	a3xx_gpu = kzalloc(sizeof(*a3xx_gpu), GFP_KERNEL);
+	if (!a3xx_gpu) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	adreno_gpu = &a3xx_gpu->base;
+	gpu = &adreno_gpu->base;
+
+	gpu->perfcntrs = perfcntrs;
+	gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs);
+
+	adreno_gpu->registers = a3xx_registers;
+
+	ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
+	if (ret)
+		goto fail;
+
+	/* if needed, allocate gmem: */
+	if (adreno_is_a330(adreno_gpu) || adreno_is_a305b(adreno_gpu)) {
+		ret = adreno_gpu_ocmem_init(&adreno_gpu->base.pdev->dev,
+					    adreno_gpu, &a3xx_gpu->ocmem);
+		if (ret)
+			goto fail;
+	}
+
+	if (!gpu->aspace) {
+		/* TODO we think it is possible to configure the GPU to
+		 * restrict access to VRAM carveout.  But the required
+		 * registers are unknown.  For now just bail out and
+		 * limp along with just modesetting.  If it turns out
+		 * to not be possible to restrict access, then we must
+		 * implement a cmdstream validator.
+		 */
+		DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n");
+		if (!allow_vram_carveout) {
+			ret = -ENXIO;
+			goto fail;
+		}
+	}
+
+	icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem");
+	if (IS_ERR(icc_path)) {
+		ret = PTR_ERR(icc_path);
+		goto fail;
+	}
+
+	ocmem_icc_path = devm_of_icc_get(&pdev->dev, "ocmem");
+	if (IS_ERR(ocmem_icc_path)) {
+		ret = PTR_ERR(ocmem_icc_path);
+		/* allow -ENODATA, ocmem icc is optional */
+		if (ret != -ENODATA)
+			goto fail;
+		ocmem_icc_path = NULL;
+	}
+
+
+	/*
+	 * Set the ICC path to maximum speed for now by multiplying the fastest
+	 * frequency by the bus width (8). We'll want to scale this later on to
+	 * improve battery life.
+	 */
+	icc_set_bw(icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8);
+	icc_set_bw(ocmem_icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8);
+
+	return gpu;
+
+fail:
+	if (a3xx_gpu)
+		a3xx_destroy(&a3xx_gpu->base.base);
+
+	return ERR_PTR(ret);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a3xx_gpu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a3xx_gpu.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __A3XX_GPU_H__
+#define __A3XX_GPU_H__
+
+#include "adreno_gpu.h"
+
+/* arrg, somehow fb.h is getting pulled in: */
+#undef ROP_COPY
+#undef ROP_XOR
+
+#include "a3xx.xml.h"
+
+struct a3xx_gpu {
+	struct adreno_gpu base;
+
+	/* if OCMEM is used for GMEM: */
+	struct adreno_ocmem ocmem;
+};
+#define to_a3xx_gpu(x) container_of(x, struct a3xx_gpu, base)
+
+#endif /* __A3XX_GPU_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a4xx_catalog.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a4xx_catalog.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013-2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
+ */
+
+#include "adreno_gpu.h"
+
+static const struct adreno_info a4xx_gpus[] = {
+	{
+		.chip_ids = ADRENO_CHIP_IDS(0x04000500),
+		.family = ADRENO_4XX,
+		.revn  = 405,
+		.fw = {
+			[ADRENO_FW_PM4] = "a420_pm4.fw",
+			[ADRENO_FW_PFP] = "a420_pfp.fw",
+		},
+		.gmem  = SZ_256K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a4xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x04020000),
+		.family = ADRENO_4XX,
+		.revn  = 420,
+		.fw = {
+			[ADRENO_FW_PM4] = "a420_pm4.fw",
+			[ADRENO_FW_PFP] = "a420_pfp.fw",
+		},
+		.gmem  = (SZ_1M + SZ_512K),
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a4xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x04030002),
+		.family = ADRENO_4XX,
+		.revn  = 430,
+		.fw = {
+			[ADRENO_FW_PM4] = "a420_pm4.fw",
+			[ADRENO_FW_PFP] = "a420_pfp.fw",
+		},
+		.gmem  = (SZ_1M + SZ_512K),
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init  = a4xx_gpu_init,
+	}
+};
+DECLARE_ADRENO_GPULIST(a4xx);
+
+MODULE_FIRMWARE("qcom/a420_pm4.fw");
+MODULE_FIRMWARE("qcom/a420_pfp.fw");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a4xx_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a4xx_gpu.c
@@ -0,0 +1,741 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ */
+#include "a4xx_gpu.h"
+
+#define A4XX_INT0_MASK \
+	(A4XX_INT0_RBBM_AHB_ERROR |        \
+	 A4XX_INT0_RBBM_ATB_BUS_OVERFLOW | \
+	 A4XX_INT0_CP_T0_PACKET_IN_IB |    \
+	 A4XX_INT0_CP_OPCODE_ERROR |       \
+	 A4XX_INT0_CP_RESERVED_BIT_ERROR | \
+	 A4XX_INT0_CP_HW_FAULT |           \
+	 A4XX_INT0_CP_IB1_INT |            \
+	 A4XX_INT0_CP_IB2_INT |            \
+	 A4XX_INT0_CP_RB_INT |             \
+	 A4XX_INT0_CP_REG_PROTECT_FAULT |  \
+	 A4XX_INT0_CP_AHB_ERROR_HALT |     \
+	 A4XX_INT0_CACHE_FLUSH_TS |        \
+	 A4XX_INT0_UCHE_OOB_ACCESS)
+
+extern bool hang_debug;
+static void a4xx_dump(struct msm_gpu *gpu);
+static bool a4xx_idle(struct msm_gpu *gpu);
+
+static void a4xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+{
+	struct msm_ringbuffer *ring = submit->ring;
+	unsigned int i;
+
+	for (i = 0; i < submit->nr_cmds; i++) {
+		switch (submit->cmd[i].type) {
+		case MSM_SUBMIT_CMD_IB_TARGET_BUF:
+			/* ignore IB-targets */
+			break;
+		case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+			/* ignore if there has not been a ctx switch: */
+			if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
+				break;
+			fallthrough;
+		case MSM_SUBMIT_CMD_BUF:
+			OUT_PKT3(ring, CP_INDIRECT_BUFFER_PFE, 2);
+			OUT_RING(ring, lower_32_bits(submit->cmd[i].iova));
+			OUT_RING(ring, submit->cmd[i].size);
+			OUT_PKT2(ring);
+			break;
+		}
+	}
+
+	OUT_PKT0(ring, REG_AXXX_CP_SCRATCH_REG2, 1);
+	OUT_RING(ring, submit->seqno);
+
+	/* Flush HLSQ lazy updates to make sure there is nothing
+	 * pending for indirect loads after the timestamp has
+	 * passed:
+	 */
+	OUT_PKT3(ring, CP_EVENT_WRITE, 1);
+	OUT_RING(ring, HLSQ_FLUSH);
+
+	/* wait for idle before cache flush/interrupt */
+	OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
+	OUT_RING(ring, 0x00000000);
+
+	/* BIT(31) of CACHE_FLUSH_TS triggers CACHE_FLUSH_TS IRQ from GPU */
+	OUT_PKT3(ring, CP_EVENT_WRITE, 3);
+	OUT_RING(ring, CACHE_FLUSH_TS | CP_EVENT_WRITE_0_IRQ);
+	OUT_RING(ring, rbmemptr(ring, fence));
+	OUT_RING(ring, submit->seqno);
+
+	adreno_flush(gpu, ring, REG_A4XX_CP_RB_WPTR);
+}
+
+/*
+ * a4xx_enable_hwcg() - Program the clock control registers
+ * @device: The adreno device pointer
+ */
+static void a4xx_enable_hwcg(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	unsigned int i;
+	for (i = 0; i < 4; i++)
+		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_TP(i), 0x02222202);
+	for (i = 0; i < 4; i++)
+		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_TP(i), 0x00002222);
+	for (i = 0; i < 4; i++)
+		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_TP(i), 0x0E739CE7);
+	for (i = 0; i < 4; i++)
+		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_TP(i), 0x00111111);
+	for (i = 0; i < 4; i++)
+		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_SP(i), 0x22222222);
+	for (i = 0; i < 4; i++)
+		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_SP(i), 0x00222222);
+	for (i = 0; i < 4; i++)
+		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_SP(i), 0x00000104);
+	for (i = 0; i < 4; i++)
+		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_SP(i), 0x00000081);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_UCHE, 0x22222222);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_UCHE, 0x02222222);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL3_UCHE, 0x00000000);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL4_UCHE, 0x00000000);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_UCHE, 0x00004444);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_UCHE, 0x00001112);
+	for (i = 0; i < 4; i++)
+		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_RB(i), 0x22222222);
+
+	/* Disable L1 clocking in A420 due to CCU issues with it */
+	for (i = 0; i < 4; i++) {
+		if (adreno_is_a420(adreno_gpu)) {
+			gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_RB(i),
+					0x00002020);
+		} else {
+			gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2_RB(i),
+					0x00022020);
+		}
+	}
+
+	/* No CCU for A405 */
+	if (!adreno_is_a405(adreno_gpu)) {
+		for (i = 0; i < 4; i++) {
+			gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_MARB_CCU(i),
+					0x00000922);
+		}
+
+		for (i = 0; i < 4; i++) {
+			gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_RB_MARB_CCU(i),
+					0x00000000);
+		}
+
+		for (i = 0; i < 4; i++) {
+			gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_RB_MARB_CCU_L1(i),
+					0x00000001);
+		}
+	}
+
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_MODE_GPC, 0x02222222);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_GPC, 0x04100104);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_GPC, 0x00022222);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_COM_DCOM, 0x00000022);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_COM_DCOM, 0x0000010F);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_COM_DCOM, 0x00000022);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_TSE_RAS_RBBM, 0x00222222);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00004104);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00000222);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL_HLSQ , 0x00000000);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_HLSQ, 0x00220000);
+	/* Early A430's have a timing issue with SP/TP power collapse;
+	   disabling HW clock gating prevents it. */
+	if (adreno_is_a430(adreno_gpu) && adreno_patchid(adreno_gpu) < 2)
+		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL, 0);
+	else
+		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL, 0xAAAAAAAA);
+	gpu_write(gpu, REG_A4XX_RBBM_CLOCK_CTL2, 0);
+}
+
+
+static bool a4xx_me_init(struct msm_gpu *gpu)
+{
+	struct msm_ringbuffer *ring = gpu->rb[0];
+
+	OUT_PKT3(ring, CP_ME_INIT, 17);
+	OUT_RING(ring, 0x000003f7);
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000080);
+	OUT_RING(ring, 0x00000100);
+	OUT_RING(ring, 0x00000180);
+	OUT_RING(ring, 0x00006600);
+	OUT_RING(ring, 0x00000150);
+	OUT_RING(ring, 0x0000014e);
+	OUT_RING(ring, 0x00000154);
+	OUT_RING(ring, 0x00000001);
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+
+	adreno_flush(gpu, ring, REG_A4XX_CP_RB_WPTR);
+	return a4xx_idle(gpu);
+}
+
+static int a4xx_hw_init(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a4xx_gpu *a4xx_gpu = to_a4xx_gpu(adreno_gpu);
+	uint32_t *ptr, len;
+	int i, ret;
+
+	if (adreno_is_a405(adreno_gpu)) {
+		gpu_write(gpu, REG_A4XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
+	} else if (adreno_is_a420(adreno_gpu)) {
+		gpu_write(gpu, REG_A4XX_VBIF_ABIT_SORT, 0x0001001F);
+		gpu_write(gpu, REG_A4XX_VBIF_ABIT_SORT_CONF, 0x000000A4);
+		gpu_write(gpu, REG_A4XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000001);
+		gpu_write(gpu, REG_A4XX_VBIF_IN_RD_LIM_CONF0, 0x18181818);
+		gpu_write(gpu, REG_A4XX_VBIF_IN_RD_LIM_CONF1, 0x00000018);
+		gpu_write(gpu, REG_A4XX_VBIF_IN_WR_LIM_CONF0, 0x18181818);
+		gpu_write(gpu, REG_A4XX_VBIF_IN_WR_LIM_CONF1, 0x00000018);
+		gpu_write(gpu, REG_A4XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
+	} else if (adreno_is_a430(adreno_gpu)) {
+		gpu_write(gpu, REG_A4XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000001);
+		gpu_write(gpu, REG_A4XX_VBIF_IN_RD_LIM_CONF0, 0x18181818);
+		gpu_write(gpu, REG_A4XX_VBIF_IN_RD_LIM_CONF1, 0x00000018);
+		gpu_write(gpu, REG_A4XX_VBIF_IN_WR_LIM_CONF0, 0x18181818);
+		gpu_write(gpu, REG_A4XX_VBIF_IN_WR_LIM_CONF1, 0x00000018);
+		gpu_write(gpu, REG_A4XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
+	} else {
+		BUG();
+	}
+
+	/* Make all blocks contribute to the GPU BUSY perf counter */
+	gpu_write(gpu, REG_A4XX_RBBM_GPU_BUSY_MASKED, 0xffffffff);
+
+	/* Tune the hystersis counters for SP and CP idle detection */
+	gpu_write(gpu, REG_A4XX_RBBM_SP_HYST_CNT, 0x10);
+	gpu_write(gpu, REG_A4XX_RBBM_WAIT_IDLE_CLOCKS_CTL, 0x10);
+
+	if (adreno_is_a430(adreno_gpu)) {
+		gpu_write(gpu, REG_A4XX_RBBM_WAIT_IDLE_CLOCKS_CTL2, 0x30);
+	}
+
+	 /* Enable the RBBM error reporting bits */
+	gpu_write(gpu, REG_A4XX_RBBM_AHB_CTL0, 0x00000001);
+
+	/* Enable AHB error reporting*/
+	gpu_write(gpu, REG_A4XX_RBBM_AHB_CTL1, 0xa6ffffff);
+
+	/* Enable power counters*/
+	gpu_write(gpu, REG_A4XX_RBBM_RBBM_CTL, 0x00000030);
+
+	/*
+	 * Turn on hang detection - this spews a lot of useful information
+	 * into the RBBM registers on a hang:
+	 */
+	gpu_write(gpu, REG_A4XX_RBBM_INTERFACE_HANG_INT_CTL,
+			(1 << 30) | 0xFFFF);
+
+	gpu_write(gpu, REG_A4XX_RB_GMEM_BASE_ADDR,
+			(unsigned int)(a4xx_gpu->ocmem.base >> 14));
+
+	/* Turn on performance counters: */
+	gpu_write(gpu, REG_A4XX_RBBM_PERFCTR_CTL, 0x01);
+
+	/* use the first CP counter for timestamp queries.. userspace may set
+	 * this as well but it selects the same counter/countable:
+	 */
+	gpu_write(gpu, REG_A4XX_CP_PERFCTR_CP_SEL_0, CP_ALWAYS_COUNT);
+
+	if (adreno_is_a430(adreno_gpu))
+		gpu_write(gpu, REG_A4XX_UCHE_CACHE_WAYS_VFD, 0x07);
+
+	/* Disable L2 bypass to avoid UCHE out of bounds errors */
+	gpu_write(gpu, REG_A4XX_UCHE_TRAP_BASE_LO, 0xffff0000);
+	gpu_write(gpu, REG_A4XX_UCHE_TRAP_BASE_HI, 0xffff0000);
+
+	gpu_write(gpu, REG_A4XX_CP_DEBUG, (1 << 25) |
+			(adreno_is_a420(adreno_gpu) ? (1 << 29) : 0));
+
+	/* On A430 enable SP regfile sleep for power savings */
+	/* TODO downstream does this for !420, so maybe applies for 405 too? */
+	if (!adreno_is_a420(adreno_gpu)) {
+		gpu_write(gpu, REG_A4XX_RBBM_SP_REGFILE_SLEEP_CNTL_0,
+			0x00000441);
+		gpu_write(gpu, REG_A4XX_RBBM_SP_REGFILE_SLEEP_CNTL_1,
+			0x00000441);
+	}
+
+	a4xx_enable_hwcg(gpu);
+
+	/*
+	 * For A420 set RBBM_CLOCK_DELAY_HLSQ.CGC_HLSQ_TP_EARLY_CYC >= 2
+	 * due to timing issue with HLSQ_TP_CLK_EN
+	 */
+	if (adreno_is_a420(adreno_gpu)) {
+		unsigned int val;
+		val = gpu_read(gpu, REG_A4XX_RBBM_CLOCK_DELAY_HLSQ);
+		val &= ~A4XX_CGC_HLSQ_EARLY_CYC__MASK;
+		val |= 2 << A4XX_CGC_HLSQ_EARLY_CYC__SHIFT;
+		gpu_write(gpu, REG_A4XX_RBBM_CLOCK_DELAY_HLSQ, val);
+	}
+
+	/* setup access protection: */
+	gpu_write(gpu, REG_A4XX_CP_PROTECT_CTRL, 0x00000007);
+
+	/* RBBM registers */
+	gpu_write(gpu, REG_A4XX_CP_PROTECT(0), 0x62000010);
+	gpu_write(gpu, REG_A4XX_CP_PROTECT(1), 0x63000020);
+	gpu_write(gpu, REG_A4XX_CP_PROTECT(2), 0x64000040);
+	gpu_write(gpu, REG_A4XX_CP_PROTECT(3), 0x65000080);
+	gpu_write(gpu, REG_A4XX_CP_PROTECT(4), 0x66000100);
+	gpu_write(gpu, REG_A4XX_CP_PROTECT(5), 0x64000200);
+
+	/* CP registers */
+	gpu_write(gpu, REG_A4XX_CP_PROTECT(6), 0x67000800);
+	gpu_write(gpu, REG_A4XX_CP_PROTECT(7), 0x64001600);
+
+
+	/* RB registers */
+	gpu_write(gpu, REG_A4XX_CP_PROTECT(8), 0x60003300);
+
+	/* HLSQ registers */
+	gpu_write(gpu, REG_A4XX_CP_PROTECT(9), 0x60003800);
+
+	/* VPC registers */
+	gpu_write(gpu, REG_A4XX_CP_PROTECT(10), 0x61003980);
+
+	/* SMMU registers */
+	gpu_write(gpu, REG_A4XX_CP_PROTECT(11), 0x6e010000);
+
+	gpu_write(gpu, REG_A4XX_RBBM_INT_0_MASK, A4XX_INT0_MASK);
+
+	ret = adreno_hw_init(gpu);
+	if (ret)
+		return ret;
+
+	/*
+	 * Use the default ringbuffer size and block size but disable the RPTR
+	 * shadow
+	 */
+	gpu_write(gpu, REG_A4XX_CP_RB_CNTL,
+		MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE);
+
+	/* Set the ringbuffer address */
+	gpu_write(gpu, REG_A4XX_CP_RB_BASE, lower_32_bits(gpu->rb[0]->iova));
+
+	/* Load PM4: */
+	ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PM4]->data);
+	len = adreno_gpu->fw[ADRENO_FW_PM4]->size / 4;
+	DBG("loading PM4 ucode version: %u", ptr[0]);
+	gpu_write(gpu, REG_A4XX_CP_ME_RAM_WADDR, 0);
+	for (i = 1; i < len; i++)
+		gpu_write(gpu, REG_A4XX_CP_ME_RAM_DATA, ptr[i]);
+
+	/* Load PFP: */
+	ptr = (uint32_t *)(adreno_gpu->fw[ADRENO_FW_PFP]->data);
+	len = adreno_gpu->fw[ADRENO_FW_PFP]->size / 4;
+	DBG("loading PFP ucode version: %u", ptr[0]);
+
+	gpu_write(gpu, REG_A4XX_CP_PFP_UCODE_ADDR, 0);
+	for (i = 1; i < len; i++)
+		gpu_write(gpu, REG_A4XX_CP_PFP_UCODE_DATA, ptr[i]);
+
+	/* clear ME_HALT to start micro engine */
+	gpu_write(gpu, REG_A4XX_CP_ME_CNTL, 0);
+
+	return a4xx_me_init(gpu) ? 0 : -EINVAL;
+}
+
+static void a4xx_recover(struct msm_gpu *gpu)
+{
+	int i;
+
+	adreno_dump_info(gpu);
+
+	for (i = 0; i < 8; i++) {
+		printk("CP_SCRATCH_REG%d: %u\n", i,
+			gpu_read(gpu, REG_AXXX_CP_SCRATCH_REG0 + i));
+	}
+
+	/* dump registers before resetting gpu, if enabled: */
+	if (hang_debug)
+		a4xx_dump(gpu);
+
+	gpu_write(gpu, REG_A4XX_RBBM_SW_RESET_CMD, 1);
+	gpu_read(gpu, REG_A4XX_RBBM_SW_RESET_CMD);
+	gpu_write(gpu, REG_A4XX_RBBM_SW_RESET_CMD, 0);
+	adreno_recover(gpu);
+}
+
+static void a4xx_destroy(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a4xx_gpu *a4xx_gpu = to_a4xx_gpu(adreno_gpu);
+
+	DBG("%s", gpu->name);
+
+	adreno_gpu_cleanup(adreno_gpu);
+
+	adreno_gpu_ocmem_cleanup(&a4xx_gpu->ocmem);
+
+	kfree(a4xx_gpu);
+}
+
+static bool a4xx_idle(struct msm_gpu *gpu)
+{
+	/* wait for ringbuffer to drain: */
+	if (!adreno_idle(gpu, gpu->rb[0]))
+		return false;
+
+	/* then wait for GPU to finish: */
+	if (spin_until(!(gpu_read(gpu, REG_A4XX_RBBM_STATUS) &
+					A4XX_RBBM_STATUS_GPU_BUSY))) {
+		DRM_ERROR("%s: timeout waiting for GPU to idle!\n", gpu->name);
+		/* TODO maybe we need to reset GPU here to recover from hang? */
+		return false;
+	}
+
+	return true;
+}
+
+static irqreturn_t a4xx_irq(struct msm_gpu *gpu)
+{
+	uint32_t status;
+
+	status = gpu_read(gpu, REG_A4XX_RBBM_INT_0_STATUS);
+	DBG("%s: Int status %08x", gpu->name, status);
+
+	if (status & A4XX_INT0_CP_REG_PROTECT_FAULT) {
+		uint32_t reg = gpu_read(gpu, REG_A4XX_CP_PROTECT_STATUS);
+		printk("CP | Protected mode error| %s | addr=%x\n",
+			reg & (1 << 24) ? "WRITE" : "READ",
+			(reg & 0xFFFFF) >> 2);
+	}
+
+	gpu_write(gpu, REG_A4XX_RBBM_INT_CLEAR_CMD, status);
+
+	msm_gpu_retire(gpu);
+
+	return IRQ_HANDLED;
+}
+
+static const unsigned int a4xx_registers[] = {
+	/* RBBM */
+	0x0000, 0x0002, 0x0004, 0x0021, 0x0023, 0x0024, 0x0026, 0x0026,
+	0x0028, 0x002B, 0x002E, 0x0034, 0x0037, 0x0044, 0x0047, 0x0066,
+	0x0068, 0x0095, 0x009C, 0x0170, 0x0174, 0x01AF,
+	/* CP */
+	0x0200, 0x0233, 0x0240, 0x0250, 0x04C0, 0x04DD, 0x0500, 0x050B,
+	0x0578, 0x058F,
+	/* VSC */
+	0x0C00, 0x0C03, 0x0C08, 0x0C41, 0x0C50, 0x0C51,
+	/* GRAS */
+	0x0C80, 0x0C81, 0x0C88, 0x0C8F,
+	/* RB */
+	0x0CC0, 0x0CC0, 0x0CC4, 0x0CD2,
+	/* PC */
+	0x0D00, 0x0D0C, 0x0D10, 0x0D17, 0x0D20, 0x0D23,
+	/* VFD */
+	0x0E40, 0x0E4A,
+	/* VPC */
+	0x0E60, 0x0E61, 0x0E63, 0x0E68,
+	/* UCHE */
+	0x0E80, 0x0E84, 0x0E88, 0x0E95,
+	/* VMIDMT */
+	0x1000, 0x1000, 0x1002, 0x1002, 0x1004, 0x1004, 0x1008, 0x100A,
+	0x100C, 0x100D, 0x100F, 0x1010, 0x1012, 0x1016, 0x1024, 0x1024,
+	0x1027, 0x1027, 0x1100, 0x1100, 0x1102, 0x1102, 0x1104, 0x1104,
+	0x1110, 0x1110, 0x1112, 0x1116, 0x1124, 0x1124, 0x1300, 0x1300,
+	0x1380, 0x1380,
+	/* GRAS CTX 0 */
+	0x2000, 0x2004, 0x2008, 0x2067, 0x2070, 0x2078, 0x207B, 0x216E,
+	/* PC CTX 0 */
+	0x21C0, 0x21C6, 0x21D0, 0x21D0, 0x21D9, 0x21D9, 0x21E5, 0x21E7,
+	/* VFD CTX 0 */
+	0x2200, 0x2204, 0x2208, 0x22A9,
+	/* GRAS CTX 1 */
+	0x2400, 0x2404, 0x2408, 0x2467, 0x2470, 0x2478, 0x247B, 0x256E,
+	/* PC CTX 1 */
+	0x25C0, 0x25C6, 0x25D0, 0x25D0, 0x25D9, 0x25D9, 0x25E5, 0x25E7,
+	/* VFD CTX 1 */
+	0x2600, 0x2604, 0x2608, 0x26A9,
+	/* XPU */
+	0x2C00, 0x2C01, 0x2C10, 0x2C10, 0x2C12, 0x2C16, 0x2C1D, 0x2C20,
+	0x2C28, 0x2C28, 0x2C30, 0x2C30, 0x2C32, 0x2C36, 0x2C40, 0x2C40,
+	0x2C50, 0x2C50, 0x2C52, 0x2C56, 0x2C80, 0x2C80, 0x2C94, 0x2C95,
+	/* VBIF */
+	0x3000, 0x3007, 0x300C, 0x3014, 0x3018, 0x301D, 0x3020, 0x3022,
+	0x3024, 0x3026, 0x3028, 0x302A, 0x302C, 0x302D, 0x3030, 0x3031,
+	0x3034, 0x3036, 0x3038, 0x3038, 0x303C, 0x303D, 0x3040, 0x3040,
+	0x3049, 0x3049, 0x3058, 0x3058, 0x305B, 0x3061, 0x3064, 0x3068,
+	0x306C, 0x306D, 0x3080, 0x3088, 0x308B, 0x308C, 0x3090, 0x3094,
+	0x3098, 0x3098, 0x309C, 0x309C, 0x30C0, 0x30C0, 0x30C8, 0x30C8,
+	0x30D0, 0x30D0, 0x30D8, 0x30D8, 0x30E0, 0x30E0, 0x3100, 0x3100,
+	0x3108, 0x3108, 0x3110, 0x3110, 0x3118, 0x3118, 0x3120, 0x3120,
+	0x3124, 0x3125, 0x3129, 0x3129, 0x3131, 0x3131, 0x330C, 0x330C,
+	0x3310, 0x3310, 0x3400, 0x3401, 0x3410, 0x3410, 0x3412, 0x3416,
+	0x341D, 0x3420, 0x3428, 0x3428, 0x3430, 0x3430, 0x3432, 0x3436,
+	0x3440, 0x3440, 0x3450, 0x3450, 0x3452, 0x3456, 0x3480, 0x3480,
+	0x3494, 0x3495, 0x4000, 0x4000, 0x4002, 0x4002, 0x4004, 0x4004,
+	0x4008, 0x400A, 0x400C, 0x400D, 0x400F, 0x4012, 0x4014, 0x4016,
+	0x401D, 0x401D, 0x4020, 0x4027, 0x4060, 0x4062, 0x4200, 0x4200,
+	0x4300, 0x4300, 0x4400, 0x4400, 0x4500, 0x4500, 0x4800, 0x4802,
+	0x480F, 0x480F, 0x4811, 0x4811, 0x4813, 0x4813, 0x4815, 0x4816,
+	0x482B, 0x482B, 0x4857, 0x4857, 0x4883, 0x4883, 0x48AF, 0x48AF,
+	0x48C5, 0x48C5, 0x48E5, 0x48E5, 0x4905, 0x4905, 0x4925, 0x4925,
+	0x4945, 0x4945, 0x4950, 0x4950, 0x495B, 0x495B, 0x4980, 0x498E,
+	0x4B00, 0x4B00, 0x4C00, 0x4C00, 0x4D00, 0x4D00, 0x4E00, 0x4E00,
+	0x4E80, 0x4E80, 0x4F00, 0x4F00, 0x4F08, 0x4F08, 0x4F10, 0x4F10,
+	0x4F18, 0x4F18, 0x4F20, 0x4F20, 0x4F30, 0x4F30, 0x4F60, 0x4F60,
+	0x4F80, 0x4F81, 0x4F88, 0x4F89, 0x4FEE, 0x4FEE, 0x4FF3, 0x4FF3,
+	0x6000, 0x6001, 0x6008, 0x600F, 0x6014, 0x6016, 0x6018, 0x601B,
+	0x61FD, 0x61FD, 0x623C, 0x623C, 0x6380, 0x6380, 0x63A0, 0x63A0,
+	0x63C0, 0x63C1, 0x63C8, 0x63C9, 0x63D0, 0x63D4, 0x63D6, 0x63D6,
+	0x63EE, 0x63EE, 0x6400, 0x6401, 0x6408, 0x640F, 0x6414, 0x6416,
+	0x6418, 0x641B, 0x65FD, 0x65FD, 0x663C, 0x663C, 0x6780, 0x6780,
+	0x67A0, 0x67A0, 0x67C0, 0x67C1, 0x67C8, 0x67C9, 0x67D0, 0x67D4,
+	0x67D6, 0x67D6, 0x67EE, 0x67EE, 0x6800, 0x6801, 0x6808, 0x680F,
+	0x6814, 0x6816, 0x6818, 0x681B, 0x69FD, 0x69FD, 0x6A3C, 0x6A3C,
+	0x6B80, 0x6B80, 0x6BA0, 0x6BA0, 0x6BC0, 0x6BC1, 0x6BC8, 0x6BC9,
+	0x6BD0, 0x6BD4, 0x6BD6, 0x6BD6, 0x6BEE, 0x6BEE,
+	~0 /* sentinel */
+};
+
+static const unsigned int a405_registers[] = {
+	/* RBBM */
+	0x0000, 0x0002, 0x0004, 0x0021, 0x0023, 0x0024, 0x0026, 0x0026,
+	0x0028, 0x002B, 0x002E, 0x0034, 0x0037, 0x0044, 0x0047, 0x0066,
+	0x0068, 0x0095, 0x009C, 0x0170, 0x0174, 0x01AF,
+	/* CP */
+	0x0200, 0x0233, 0x0240, 0x0250, 0x04C0, 0x04DD, 0x0500, 0x050B,
+	0x0578, 0x058F,
+	/* VSC */
+	0x0C00, 0x0C03, 0x0C08, 0x0C41, 0x0C50, 0x0C51,
+	/* GRAS */
+	0x0C80, 0x0C81, 0x0C88, 0x0C8F,
+	/* RB */
+	0x0CC0, 0x0CC0, 0x0CC4, 0x0CD2,
+	/* PC */
+	0x0D00, 0x0D0C, 0x0D10, 0x0D17, 0x0D20, 0x0D23,
+	/* VFD */
+	0x0E40, 0x0E4A,
+	/* VPC */
+	0x0E60, 0x0E61, 0x0E63, 0x0E68,
+	/* UCHE */
+	0x0E80, 0x0E84, 0x0E88, 0x0E95,
+	/* GRAS CTX 0 */
+	0x2000, 0x2004, 0x2008, 0x2067, 0x2070, 0x2078, 0x207B, 0x216E,
+	/* PC CTX 0 */
+	0x21C0, 0x21C6, 0x21D0, 0x21D0, 0x21D9, 0x21D9, 0x21E5, 0x21E7,
+	/* VFD CTX 0 */
+	0x2200, 0x2204, 0x2208, 0x22A9,
+	/* GRAS CTX 1 */
+	0x2400, 0x2404, 0x2408, 0x2467, 0x2470, 0x2478, 0x247B, 0x256E,
+	/* PC CTX 1 */
+	0x25C0, 0x25C6, 0x25D0, 0x25D0, 0x25D9, 0x25D9, 0x25E5, 0x25E7,
+	/* VFD CTX 1 */
+	0x2600, 0x2604, 0x2608, 0x26A9,
+	/* VBIF version 0x20050000*/
+	0x3000, 0x3007, 0x302C, 0x302C, 0x3030, 0x3030, 0x3034, 0x3036,
+	0x3038, 0x3038, 0x303C, 0x303D, 0x3040, 0x3040, 0x3049, 0x3049,
+	0x3058, 0x3058, 0x305B, 0x3061, 0x3064, 0x3068, 0x306C, 0x306D,
+	0x3080, 0x3088, 0x308B, 0x308C, 0x3090, 0x3094, 0x3098, 0x3098,
+	0x309C, 0x309C, 0x30C0, 0x30C0, 0x30C8, 0x30C8, 0x30D0, 0x30D0,
+	0x30D8, 0x30D8, 0x30E0, 0x30E0, 0x3100, 0x3100, 0x3108, 0x3108,
+	0x3110, 0x3110, 0x3118, 0x3118, 0x3120, 0x3120, 0x3124, 0x3125,
+	0x3129, 0x3129, 0x340C, 0x340C, 0x3410, 0x3410,
+	~0 /* sentinel */
+};
+
+static struct msm_gpu_state *a4xx_gpu_state_get(struct msm_gpu *gpu)
+{
+	struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
+
+	if (!state)
+		return ERR_PTR(-ENOMEM);
+
+	adreno_gpu_state_get(gpu, state);
+
+	state->rbbm_status = gpu_read(gpu, REG_A4XX_RBBM_STATUS);
+
+	return state;
+}
+
+static void a4xx_dump(struct msm_gpu *gpu)
+{
+	printk("status:   %08x\n",
+			gpu_read(gpu, REG_A4XX_RBBM_STATUS));
+	adreno_dump(gpu);
+}
+
+static int a4xx_pm_resume(struct msm_gpu *gpu) {
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	int ret;
+
+	ret = msm_gpu_pm_resume(gpu);
+	if (ret)
+		return ret;
+
+	if (adreno_is_a430(adreno_gpu)) {
+		unsigned int reg;
+		/* Set the default register values; set SW_COLLAPSE to 0 */
+		gpu_write(gpu, REG_A4XX_RBBM_POWER_CNTL_IP, 0x778000);
+		do {
+			udelay(5);
+			reg = gpu_read(gpu, REG_A4XX_RBBM_POWER_STATUS);
+		} while (!(reg & A4XX_RBBM_POWER_CNTL_IP_SP_TP_PWR_ON));
+	}
+	return 0;
+}
+
+static int a4xx_pm_suspend(struct msm_gpu *gpu) {
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	int ret;
+
+	ret = msm_gpu_pm_suspend(gpu);
+	if (ret)
+		return ret;
+
+	if (adreno_is_a430(adreno_gpu)) {
+		/* Set the default register values; set SW_COLLAPSE to 1 */
+		gpu_write(gpu, REG_A4XX_RBBM_POWER_CNTL_IP, 0x778001);
+	}
+	return 0;
+}
+
+static int a4xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
+{
+	*value = gpu_read64(gpu, REG_A4XX_RBBM_PERFCTR_CP_0_LO);
+
+	return 0;
+}
+
+static u64 a4xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate)
+{
+	u64 busy_cycles;
+
+	busy_cycles = gpu_read64(gpu, REG_A4XX_RBBM_PERFCTR_RBBM_1_LO);
+	*out_sample_rate = clk_get_rate(gpu->core_clk);
+
+	return busy_cycles;
+}
+
+static u32 a4xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+	ring->memptrs->rptr = gpu_read(gpu, REG_A4XX_CP_RB_RPTR);
+	return ring->memptrs->rptr;
+}
+
+static const struct adreno_gpu_funcs funcs = {
+	.base = {
+		.get_param = adreno_get_param,
+		.set_param = adreno_set_param,
+		.hw_init = a4xx_hw_init,
+		.pm_suspend = a4xx_pm_suspend,
+		.pm_resume = a4xx_pm_resume,
+		.recover = a4xx_recover,
+		.submit = a4xx_submit,
+		.active_ring = adreno_active_ring,
+		.irq = a4xx_irq,
+		.destroy = a4xx_destroy,
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
+		.show = adreno_show,
+#endif
+		.gpu_busy = a4xx_gpu_busy,
+		.gpu_state_get = a4xx_gpu_state_get,
+		.gpu_state_put = adreno_gpu_state_put,
+		.create_address_space = adreno_create_address_space,
+		.get_rptr = a4xx_get_rptr,
+	},
+	.get_timestamp = a4xx_get_timestamp,
+};
+
+struct msm_gpu *a4xx_gpu_init(struct drm_device *dev)
+{
+	struct a4xx_gpu *a4xx_gpu = NULL;
+	struct adreno_gpu *adreno_gpu;
+	struct msm_gpu *gpu;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct platform_device *pdev = priv->gpu_pdev;
+	struct icc_path *ocmem_icc_path;
+	struct icc_path *icc_path;
+	int ret;
+
+	if (!pdev) {
+		DRM_DEV_ERROR(dev->dev, "no a4xx device\n");
+		ret = -ENXIO;
+		goto fail;
+	}
+
+	a4xx_gpu = kzalloc(sizeof(*a4xx_gpu), GFP_KERNEL);
+	if (!a4xx_gpu) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	adreno_gpu = &a4xx_gpu->base;
+	gpu = &adreno_gpu->base;
+
+	gpu->perfcntrs = NULL;
+	gpu->num_perfcntrs = 0;
+
+	ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
+	if (ret)
+		goto fail;
+
+	adreno_gpu->registers = adreno_is_a405(adreno_gpu) ? a405_registers :
+							     a4xx_registers;
+
+	/* if needed, allocate gmem: */
+	ret = adreno_gpu_ocmem_init(dev->dev, adreno_gpu,
+				    &a4xx_gpu->ocmem);
+	if (ret)
+		goto fail;
+
+	if (!gpu->aspace) {
+		/* TODO we think it is possible to configure the GPU to
+		 * restrict access to VRAM carveout.  But the required
+		 * registers are unknown.  For now just bail out and
+		 * limp along with just modesetting.  If it turns out
+		 * to not be possible to restrict access, then we must
+		 * implement a cmdstream validator.
+		 */
+		DRM_DEV_ERROR(dev->dev, "No memory protection without IOMMU\n");
+		if (!allow_vram_carveout) {
+			ret = -ENXIO;
+			goto fail;
+		}
+	}
+
+	icc_path = devm_of_icc_get(&pdev->dev, "gfx-mem");
+	if (IS_ERR(icc_path)) {
+		ret = PTR_ERR(icc_path);
+		goto fail;
+	}
+
+	ocmem_icc_path = devm_of_icc_get(&pdev->dev, "ocmem");
+	if (IS_ERR(ocmem_icc_path)) {
+		ret = PTR_ERR(ocmem_icc_path);
+		/* allow -ENODATA, ocmem icc is optional */
+		if (ret != -ENODATA)
+			goto fail;
+		ocmem_icc_path = NULL;
+	}
+
+	/*
+	 * Set the ICC path to maximum speed for now by multiplying the fastest
+	 * frequency by the bus width (8). We'll want to scale this later on to
+	 * improve battery life.
+	 */
+	icc_set_bw(icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8);
+	icc_set_bw(ocmem_icc_path, 0, Bps_to_icc(gpu->fast_rate) * 8);
+
+	return gpu;
+
+fail:
+	if (a4xx_gpu)
+		a4xx_destroy(&a4xx_gpu->base.base);
+
+	return ERR_PTR(ret);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a4xx_gpu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a4xx_gpu.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ */
+#ifndef __A4XX_GPU_H__
+#define __A4XX_GPU_H__
+
+#include "adreno_gpu.h"
+
+/* arrg, somehow fb.h is getting pulled in: */
+#undef ROP_COPY
+#undef ROP_XOR
+
+#include "a4xx.xml.h"
+
+struct a4xx_gpu {
+	struct adreno_gpu base;
+
+	/* if OCMEM is used for GMEM: */
+	struct adreno_ocmem ocmem;
+};
+#define to_a4xx_gpu(x) container_of(x, struct a4xx_gpu, base)
+
+#endif /* __A4XX_GPU_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a5xx_catalog.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a5xx_catalog.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013-2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
+ */
+
+#include "adreno_gpu.h"
+
+static const struct adreno_info a5xx_gpus[] = {
+	{
+		.chip_ids = ADRENO_CHIP_IDS(0x05000600),
+		.family = ADRENO_5XX,
+		.revn = 506,
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+		},
+		.gmem = (SZ_128K + SZ_8K),
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
+			  ADRENO_QUIRK_LMLOADKILL_DISABLE,
+		.init = a5xx_gpu_init,
+		.zapfw = "a506_zap.mdt",
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x05000800),
+		.family = ADRENO_5XX,
+		.revn = 508,
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+		},
+		.gmem = (SZ_128K + SZ_8K),
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
+		.init = a5xx_gpu_init,
+		.zapfw = "a508_zap.mdt",
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x05000900),
+		.family = ADRENO_5XX,
+		.revn = 509,
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+		},
+		.gmem = (SZ_256K + SZ_16K),
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
+		.init = a5xx_gpu_init,
+		/* Adreno 509 uses the same ZAP as 512 */
+		.zapfw = "a512_zap.mdt",
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x05010000),
+		.family = ADRENO_5XX,
+		.revn = 510,
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+		},
+		.gmem = SZ_256K,
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.init = a5xx_gpu_init,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x05010200),
+		.family = ADRENO_5XX,
+		.revn = 512,
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+		},
+		.gmem = (SZ_256K + SZ_16K),
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
+		.init = a5xx_gpu_init,
+		.zapfw = "a512_zap.mdt",
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(
+			0x05030002,
+			0x05030004
+		),
+		.family = ADRENO_5XX,
+		.revn = 530,
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+			[ADRENO_FW_GPMU] = "a530v3_gpmu.fw2",
+		},
+		.gmem = SZ_1M,
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.quirks = ADRENO_QUIRK_TWO_PASS_USE_WFI |
+			ADRENO_QUIRK_FAULT_DETECT_MASK,
+		.init = a5xx_gpu_init,
+		.zapfw = "a530_zap.mdt",
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x05040001),
+		.family = ADRENO_5XX,
+		.revn = 540,
+		.fw = {
+			[ADRENO_FW_PM4] = "a530_pm4.fw",
+			[ADRENO_FW_PFP] = "a530_pfp.fw",
+			[ADRENO_FW_GPMU] = "a540_gpmu.fw2",
+		},
+		.gmem = SZ_1M,
+		/*
+		 * Increase inactive period to 250 to avoid bouncing
+		 * the GDSC which appears to make it grumpy
+		 */
+		.inactive_period = 250,
+		.quirks = ADRENO_QUIRK_LMLOADKILL_DISABLE,
+		.init = a5xx_gpu_init,
+		.zapfw = "a540_zap.mdt",
+	}
+};
+DECLARE_ADRENO_GPULIST(a5xx);
+
+MODULE_FIRMWARE("qcom/a530_pm4.fw");
+MODULE_FIRMWARE("qcom/a530_pfp.fw");
+MODULE_FIRMWARE("qcom/a530v3_gpmu.fw2");
+MODULE_FIRMWARE("qcom/a530_zap.mdt");
+MODULE_FIRMWARE("qcom/a530_zap.b00");
+MODULE_FIRMWARE("qcom/a530_zap.b01");
+MODULE_FIRMWARE("qcom/a530_zap.b02");
+MODULE_FIRMWARE("qcom/a540_gpmu.fw2");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a5xx_debugfs.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a5xx_debugfs.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/debugfs.h>
+
+#include <drm/drm_debugfs.h>
+#include <drm/drm_file.h>
+#include <drm/drm_print.h>
+
+#include "a5xx_gpu.h"
+
+static void pfp_print(struct msm_gpu *gpu, struct drm_printer *p)
+{
+	int i;
+
+	drm_printf(p, "PFP state:\n");
+
+	for (i = 0; i < 36; i++) {
+		gpu_write(gpu, REG_A5XX_CP_PFP_STAT_ADDR, i);
+		drm_printf(p, "  %02x: %08x\n", i,
+			gpu_read(gpu, REG_A5XX_CP_PFP_STAT_DATA));
+	}
+}
+
+static void me_print(struct msm_gpu *gpu, struct drm_printer *p)
+{
+	int i;
+
+	drm_printf(p, "ME state:\n");
+
+	for (i = 0; i < 29; i++) {
+		gpu_write(gpu, REG_A5XX_CP_ME_STAT_ADDR, i);
+		drm_printf(p, "  %02x: %08x\n", i,
+			gpu_read(gpu, REG_A5XX_CP_ME_STAT_DATA));
+	}
+}
+
+static void meq_print(struct msm_gpu *gpu, struct drm_printer *p)
+{
+	int i;
+
+	drm_printf(p, "MEQ state:\n");
+	gpu_write(gpu, REG_A5XX_CP_MEQ_DBG_ADDR, 0);
+
+	for (i = 0; i < 64; i++) {
+		drm_printf(p, "  %02x: %08x\n", i,
+			gpu_read(gpu, REG_A5XX_CP_MEQ_DBG_DATA));
+	}
+}
+
+static void roq_print(struct msm_gpu *gpu, struct drm_printer *p)
+{
+	int i;
+
+	drm_printf(p, "ROQ state:\n");
+	gpu_write(gpu, REG_A5XX_CP_ROQ_DBG_ADDR, 0);
+
+	for (i = 0; i < 512 / 4; i++) {
+		uint32_t val[4];
+		int j;
+		for (j = 0; j < 4; j++)
+			val[j] = gpu_read(gpu, REG_A5XX_CP_ROQ_DBG_DATA);
+		drm_printf(p, "  %02x: %08x %08x %08x %08x\n", i,
+			val[0], val[1], val[2], val[3]);
+	}
+}
+
+static int show(struct seq_file *m, void *arg)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct drm_printer p = drm_seq_file_printer(m);
+	void (*show)(struct msm_gpu *gpu, struct drm_printer *p) =
+		node->info_ent->data;
+
+	show(priv->gpu, &p);
+	return 0;
+}
+
+#define ENT(n) { .name = #n, .show = show, .data = n ##_print }
+static struct drm_info_list a5xx_debugfs_list[] = {
+	ENT(pfp),
+	ENT(me),
+	ENT(meq),
+	ENT(roq),
+};
+
+/* for debugfs files that can be written to, we can't use drm helper: */
+static int
+reset_set(void *data, u64 val)
+{
+	struct drm_device *dev = data;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_gpu *gpu = priv->gpu;
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EINVAL;
+
+	/* TODO do we care about trying to make sure the GPU is idle?
+	 * Since this is just a debug feature limited to CAP_SYS_ADMIN,
+	 * maybe it is fine to let the user keep both pieces if they
+	 * try to reset an active GPU.
+	 */
+
+	mutex_lock(&gpu->lock);
+
+	release_firmware(adreno_gpu->fw[ADRENO_FW_PM4]);
+	adreno_gpu->fw[ADRENO_FW_PM4] = NULL;
+
+	release_firmware(adreno_gpu->fw[ADRENO_FW_PFP]);
+	adreno_gpu->fw[ADRENO_FW_PFP] = NULL;
+
+	if (a5xx_gpu->pm4_bo) {
+		msm_gem_unpin_iova(a5xx_gpu->pm4_bo, gpu->aspace);
+		drm_gem_object_put(a5xx_gpu->pm4_bo);
+		a5xx_gpu->pm4_bo = NULL;
+	}
+
+	if (a5xx_gpu->pfp_bo) {
+		msm_gem_unpin_iova(a5xx_gpu->pfp_bo, gpu->aspace);
+		drm_gem_object_put(a5xx_gpu->pfp_bo);
+		a5xx_gpu->pfp_bo = NULL;
+	}
+
+	gpu->needs_hw_init = true;
+
+	pm_runtime_get_sync(&gpu->pdev->dev);
+	gpu->funcs->recover(gpu);
+
+	pm_runtime_put_sync(&gpu->pdev->dev);
+	mutex_unlock(&gpu->lock);
+
+	return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(reset_fops, NULL, reset_set, "%llx\n");
+
+
+void a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor)
+{
+	struct drm_device *dev;
+
+	if (!minor)
+		return;
+
+	dev = minor->dev;
+
+	drm_debugfs_create_files(a5xx_debugfs_list,
+				 ARRAY_SIZE(a5xx_debugfs_list),
+				 minor->debugfs_root, minor);
+
+	debugfs_create_file_unsafe("reset", S_IWUGO, minor->debugfs_root, dev,
+				&reset_fops);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a5xx_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a5xx_gpu.c
@@ -0,0 +1,1804 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/cpumask.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/pm_opp.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/slab.h>
+#include "msm_gem.h"
+#include "msm_mmu.h"
+#include "a5xx_gpu.h"
+
+extern bool hang_debug;
+static void a5xx_dump(struct msm_gpu *gpu);
+
+#define GPU_PAS_ID 13
+
+static void update_shadow_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+
+	if (a5xx_gpu->has_whereami) {
+		OUT_PKT7(ring, CP_WHERE_AM_I, 2);
+		OUT_RING(ring, lower_32_bits(shadowptr(a5xx_gpu, ring)));
+		OUT_RING(ring, upper_32_bits(shadowptr(a5xx_gpu, ring)));
+	}
+}
+
+void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring,
+		bool sync)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	uint32_t wptr;
+	unsigned long flags;
+
+	/*
+	 * Most flush operations need to issue a WHERE_AM_I opcode to sync up
+	 * the rptr shadow
+	 */
+	if (sync)
+		update_shadow_rptr(gpu, ring);
+
+	spin_lock_irqsave(&ring->preempt_lock, flags);
+
+	/* Copy the shadow to the actual register */
+	ring->cur = ring->next;
+
+	/* Make sure to wrap wptr if we need to */
+	wptr = get_wptr(ring);
+
+	spin_unlock_irqrestore(&ring->preempt_lock, flags);
+
+	/* Make sure everything is posted before making a decision */
+	mb();
+
+	/* Update HW if this is the current ring and we are not in preempt */
+	if (a5xx_gpu->cur_ring == ring && !a5xx_in_preempt(a5xx_gpu))
+		gpu_write(gpu, REG_A5XX_CP_RB_WPTR, wptr);
+}
+
+static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	struct msm_ringbuffer *ring = submit->ring;
+	struct drm_gem_object *obj;
+	uint32_t *ptr, dwords;
+	unsigned int i;
+
+	for (i = 0; i < submit->nr_cmds; i++) {
+		switch (submit->cmd[i].type) {
+		case MSM_SUBMIT_CMD_IB_TARGET_BUF:
+			break;
+		case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+			if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
+				break;
+			fallthrough;
+		case MSM_SUBMIT_CMD_BUF:
+			/* copy commands into RB: */
+			obj = submit->bos[submit->cmd[i].idx].obj;
+			dwords = submit->cmd[i].size;
+
+			ptr = msm_gem_get_vaddr(obj);
+
+			/* _get_vaddr() shouldn't fail at this point,
+			 * since we've already mapped it once in
+			 * submit_reloc()
+			 */
+			if (WARN_ON(IS_ERR_OR_NULL(ptr)))
+				return;
+
+			for (i = 0; i < dwords; i++) {
+				/* normally the OUT_PKTn() would wait
+				 * for space for the packet.  But since
+				 * we just OUT_RING() the whole thing,
+				 * need to call adreno_wait_ring()
+				 * ourself:
+				 */
+				adreno_wait_ring(ring, 1);
+				OUT_RING(ring, ptr[i]);
+			}
+
+			msm_gem_put_vaddr(obj);
+
+			break;
+		}
+	}
+
+	a5xx_gpu->last_seqno[ring->id] = submit->seqno;
+	a5xx_flush(gpu, ring, true);
+	a5xx_preempt_trigger(gpu);
+
+	/* we might not necessarily have a cmd from userspace to
+	 * trigger an event to know that submit has completed, so
+	 * do this manually:
+	 */
+	a5xx_idle(gpu, ring);
+	ring->memptrs->fence = submit->seqno;
+	msm_gpu_retire(gpu);
+}
+
+static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	struct msm_ringbuffer *ring = submit->ring;
+	unsigned int i, ibs = 0;
+
+	if (IS_ENABLED(CONFIG_DRM_MSM_GPU_SUDO) && submit->in_rb) {
+		gpu->cur_ctx_seqno = 0;
+		a5xx_submit_in_rb(gpu, submit);
+		return;
+	}
+
+	OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1);
+	OUT_RING(ring, 0x02);
+
+	/* Turn off protected mode to write to special registers */
+	OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
+	OUT_RING(ring, 0);
+
+	/* Set the save preemption record for the ring/command */
+	OUT_PKT4(ring, REG_A5XX_CP_CONTEXT_SWITCH_SAVE_ADDR_LO, 2);
+	OUT_RING(ring, lower_32_bits(a5xx_gpu->preempt_iova[submit->ring->id]));
+	OUT_RING(ring, upper_32_bits(a5xx_gpu->preempt_iova[submit->ring->id]));
+
+	/* Turn back on protected mode */
+	OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
+	OUT_RING(ring, 1);
+
+	/*
+	 * Disable local preemption by default because it requires
+	 * user-space to be aware of it and provide additional handling
+	 * to restore rendering state or do various flushes on switch.
+	 */
+	OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1);
+	OUT_RING(ring, 0x0);
+
+	/* Allow CP_CONTEXT_SWITCH_YIELD packets in the IB2 */
+	OUT_PKT7(ring, CP_YIELD_ENABLE, 1);
+	OUT_RING(ring, 0x02);
+
+	/* Submit the commands */
+	for (i = 0; i < submit->nr_cmds; i++) {
+		switch (submit->cmd[i].type) {
+		case MSM_SUBMIT_CMD_IB_TARGET_BUF:
+			break;
+		case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+			if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
+				break;
+			fallthrough;
+		case MSM_SUBMIT_CMD_BUF:
+			OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3);
+			OUT_RING(ring, lower_32_bits(submit->cmd[i].iova));
+			OUT_RING(ring, upper_32_bits(submit->cmd[i].iova));
+			OUT_RING(ring, submit->cmd[i].size);
+			ibs++;
+			break;
+		}
+
+		/*
+		 * Periodically update shadow-wptr if needed, so that we
+		 * can see partial progress of submits with large # of
+		 * cmds.. otherwise we could needlessly stall waiting for
+		 * ringbuffer state, simply due to looking at a shadow
+		 * rptr value that has not been updated
+		 */
+		if ((ibs % 32) == 0)
+			update_shadow_rptr(gpu, ring);
+	}
+
+	/*
+	 * Write the render mode to NULL (0) to indicate to the CP that the IBs
+	 * are done rendering - otherwise a lucky preemption would start
+	 * replaying from the last checkpoint
+	 */
+	OUT_PKT7(ring, CP_SET_RENDER_MODE, 5);
+	OUT_RING(ring, 0);
+	OUT_RING(ring, 0);
+	OUT_RING(ring, 0);
+	OUT_RING(ring, 0);
+	OUT_RING(ring, 0);
+
+	/* Turn off IB level preemptions */
+	OUT_PKT7(ring, CP_YIELD_ENABLE, 1);
+	OUT_RING(ring, 0x01);
+
+	/* Write the fence to the scratch register */
+	OUT_PKT4(ring, REG_A5XX_CP_SCRATCH_REG(2), 1);
+	OUT_RING(ring, submit->seqno);
+	a5xx_gpu->last_seqno[ring->id] = submit->seqno;
+
+	/*
+	 * Execute a CACHE_FLUSH_TS event. This will ensure that the
+	 * timestamp is written to the memory and then triggers the interrupt
+	 */
+	OUT_PKT7(ring, CP_EVENT_WRITE, 4);
+	OUT_RING(ring, CP_EVENT_WRITE_0_EVENT(CACHE_FLUSH_TS) |
+		CP_EVENT_WRITE_0_IRQ);
+	OUT_RING(ring, lower_32_bits(rbmemptr(ring, fence)));
+	OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence)));
+	OUT_RING(ring, submit->seqno);
+
+	/* Yield the floor on command completion */
+	OUT_PKT7(ring, CP_CONTEXT_SWITCH_YIELD, 4);
+	/*
+	 * If dword[2:1] are non zero, they specify an address for the CP to
+	 * write the value of dword[3] to on preemption complete. Write 0 to
+	 * skip the write
+	 */
+	OUT_RING(ring, 0x00);
+	OUT_RING(ring, 0x00);
+	/* Data value - not used if the address above is 0 */
+	OUT_RING(ring, 0x01);
+	/* Set bit 0 to trigger an interrupt on preempt complete */
+	OUT_RING(ring, 0x01);
+
+	/* A WHERE_AM_I packet is not needed after a YIELD */
+	a5xx_flush(gpu, ring, false);
+
+	/* Check to see if we need to start preemption */
+	a5xx_preempt_trigger(gpu);
+}
+
+static const struct adreno_five_hwcg_regs {
+	u32 offset;
+	u32 value;
+} a5xx_hwcg[] = {
+	{REG_A5XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_SP1, 0x02222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_SP2, 0x02222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_SP3, 0x02222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_SP1, 0x02222220},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_SP2, 0x02222220},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_SP3, 0x02222220},
+	{REG_A5XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
+	{REG_A5XX_RBBM_CLOCK_HYST_SP1, 0x0000F3CF},
+	{REG_A5XX_RBBM_CLOCK_HYST_SP2, 0x0000F3CF},
+	{REG_A5XX_RBBM_CLOCK_HYST_SP3, 0x0000F3CF},
+	{REG_A5XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A5XX_RBBM_CLOCK_DELAY_SP1, 0x00000080},
+	{REG_A5XX_RBBM_CLOCK_DELAY_SP2, 0x00000080},
+	{REG_A5XX_RBBM_CLOCK_DELAY_SP3, 0x00000080},
+	{REG_A5XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_TP1, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_TP2, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_TP3, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_TP2, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_TP3, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL3_TP0, 0x00002222},
+	{REG_A5XX_RBBM_CLOCK_CNTL3_TP1, 0x00002222},
+	{REG_A5XX_RBBM_CLOCK_CNTL3_TP2, 0x00002222},
+	{REG_A5XX_RBBM_CLOCK_CNTL3_TP3, 0x00002222},
+	{REG_A5XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A5XX_RBBM_CLOCK_HYST_TP1, 0x77777777},
+	{REG_A5XX_RBBM_CLOCK_HYST_TP2, 0x77777777},
+	{REG_A5XX_RBBM_CLOCK_HYST_TP3, 0x77777777},
+	{REG_A5XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A5XX_RBBM_CLOCK_HYST2_TP1, 0x77777777},
+	{REG_A5XX_RBBM_CLOCK_HYST2_TP2, 0x77777777},
+	{REG_A5XX_RBBM_CLOCK_HYST2_TP3, 0x77777777},
+	{REG_A5XX_RBBM_CLOCK_HYST3_TP0, 0x00007777},
+	{REG_A5XX_RBBM_CLOCK_HYST3_TP1, 0x00007777},
+	{REG_A5XX_RBBM_CLOCK_HYST3_TP2, 0x00007777},
+	{REG_A5XX_RBBM_CLOCK_HYST3_TP3, 0x00007777},
+	{REG_A5XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A5XX_RBBM_CLOCK_DELAY_TP1, 0x11111111},
+	{REG_A5XX_RBBM_CLOCK_DELAY_TP2, 0x11111111},
+	{REG_A5XX_RBBM_CLOCK_DELAY_TP3, 0x11111111},
+	{REG_A5XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A5XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111},
+	{REG_A5XX_RBBM_CLOCK_DELAY2_TP2, 0x11111111},
+	{REG_A5XX_RBBM_CLOCK_DELAY2_TP3, 0x11111111},
+	{REG_A5XX_RBBM_CLOCK_DELAY3_TP0, 0x00001111},
+	{REG_A5XX_RBBM_CLOCK_DELAY3_TP1, 0x00001111},
+	{REG_A5XX_RBBM_CLOCK_DELAY3_TP2, 0x00001111},
+	{REG_A5XX_RBBM_CLOCK_DELAY3_TP3, 0x00001111},
+	{REG_A5XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222},
+	{REG_A5XX_RBBM_CLOCK_HYST_UCHE, 0x00444444},
+	{REG_A5XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A5XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_RB1, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_RB2, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_RB3, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_RB0, 0x00222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_RB1, 0x00222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_RB2, 0x00222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_RB3, 0x00222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_CCU0, 0x00022220},
+	{REG_A5XX_RBBM_CLOCK_CNTL_CCU1, 0x00022220},
+	{REG_A5XX_RBBM_CLOCK_CNTL_CCU2, 0x00022220},
+	{REG_A5XX_RBBM_CLOCK_CNTL_CCU3, 0x00022220},
+	{REG_A5XX_RBBM_CLOCK_CNTL_RAC, 0x05522222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_RAC, 0x00505555},
+	{REG_A5XX_RBBM_CLOCK_HYST_RB_CCU0, 0x04040404},
+	{REG_A5XX_RBBM_CLOCK_HYST_RB_CCU1, 0x04040404},
+	{REG_A5XX_RBBM_CLOCK_HYST_RB_CCU2, 0x04040404},
+	{REG_A5XX_RBBM_CLOCK_HYST_RB_CCU3, 0x04040404},
+	{REG_A5XX_RBBM_CLOCK_HYST_RAC, 0x07444044},
+	{REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_0, 0x00000002},
+	{REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_1, 0x00000002},
+	{REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_2, 0x00000002},
+	{REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_3, 0x00000002},
+	{REG_A5XX_RBBM_CLOCK_DELAY_RAC, 0x00010011},
+	{REG_A5XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A5XX_RBBM_CLOCK_MODE_GPC, 0x02222222},
+	{REG_A5XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A5XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A5XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A5XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A5XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A5XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A5XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222}
+}, a50x_hwcg[] = {
+	{REG_A5XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A5XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
+	{REG_A5XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A5XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL3_TP0, 0x00002222},
+	{REG_A5XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A5XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A5XX_RBBM_CLOCK_HYST3_TP0, 0x00007777},
+	{REG_A5XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A5XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A5XX_RBBM_CLOCK_DELAY3_TP0, 0x00001111},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_HYST_UCHE, 0x00FFFFF4},
+	{REG_A5XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A5XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_RB0, 0x00222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_CCU0, 0x00022220},
+	{REG_A5XX_RBBM_CLOCK_CNTL_RAC, 0x05522222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_RAC, 0x00505555},
+	{REG_A5XX_RBBM_CLOCK_HYST_RB_CCU0, 0x04040404},
+	{REG_A5XX_RBBM_CLOCK_HYST_RAC, 0x07444044},
+	{REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_0, 0x00000002},
+	{REG_A5XX_RBBM_CLOCK_DELAY_RAC, 0x00010011},
+	{REG_A5XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A5XX_RBBM_CLOCK_MODE_GPC, 0x02222222},
+	{REG_A5XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A5XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A5XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A5XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A5XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A5XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A5XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+}, a512_hwcg[] = {
+	{REG_A5XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_SP1, 0x02222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_SP1, 0x02222220},
+	{REG_A5XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
+	{REG_A5XX_RBBM_CLOCK_HYST_SP1, 0x0000F3CF},
+	{REG_A5XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A5XX_RBBM_CLOCK_DELAY_SP1, 0x00000080},
+	{REG_A5XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_TP1, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL3_TP0, 0x00002222},
+	{REG_A5XX_RBBM_CLOCK_CNTL3_TP1, 0x00002222},
+	{REG_A5XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A5XX_RBBM_CLOCK_HYST_TP1, 0x77777777},
+	{REG_A5XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A5XX_RBBM_CLOCK_HYST2_TP1, 0x77777777},
+	{REG_A5XX_RBBM_CLOCK_HYST3_TP0, 0x00007777},
+	{REG_A5XX_RBBM_CLOCK_HYST3_TP1, 0x00007777},
+	{REG_A5XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A5XX_RBBM_CLOCK_DELAY_TP1, 0x11111111},
+	{REG_A5XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A5XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111},
+	{REG_A5XX_RBBM_CLOCK_DELAY3_TP0, 0x00001111},
+	{REG_A5XX_RBBM_CLOCK_DELAY3_TP1, 0x00001111},
+	{REG_A5XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222},
+	{REG_A5XX_RBBM_CLOCK_HYST_UCHE, 0x00444444},
+	{REG_A5XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A5XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_RB1, 0x22222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_RB0, 0x00222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_RB1, 0x00222222},
+	{REG_A5XX_RBBM_CLOCK_CNTL_CCU0, 0x00022220},
+	{REG_A5XX_RBBM_CLOCK_CNTL_CCU1, 0x00022220},
+	{REG_A5XX_RBBM_CLOCK_CNTL_RAC, 0x05522222},
+	{REG_A5XX_RBBM_CLOCK_CNTL2_RAC, 0x00505555},
+	{REG_A5XX_RBBM_CLOCK_HYST_RB_CCU0, 0x04040404},
+	{REG_A5XX_RBBM_CLOCK_HYST_RB_CCU1, 0x04040404},
+	{REG_A5XX_RBBM_CLOCK_HYST_RAC, 0x07444044},
+	{REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_0, 0x00000002},
+	{REG_A5XX_RBBM_CLOCK_DELAY_RB_CCU_L1_1, 0x00000002},
+	{REG_A5XX_RBBM_CLOCK_DELAY_RAC, 0x00010011},
+	{REG_A5XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A5XX_RBBM_CLOCK_MODE_GPC, 0x02222222},
+	{REG_A5XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A5XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A5XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A5XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A5XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A5XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A5XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A5XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+};
+
+void a5xx_set_hwcg(struct msm_gpu *gpu, bool state)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	const struct adreno_five_hwcg_regs *regs;
+	unsigned int i, sz;
+
+	if (adreno_is_a506(adreno_gpu) || adreno_is_a508(adreno_gpu)) {
+		regs = a50x_hwcg;
+		sz = ARRAY_SIZE(a50x_hwcg);
+	} else if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu)) {
+		regs = a512_hwcg;
+		sz = ARRAY_SIZE(a512_hwcg);
+	} else {
+		regs = a5xx_hwcg;
+		sz = ARRAY_SIZE(a5xx_hwcg);
+	}
+
+	for (i = 0; i < sz; i++)
+		gpu_write(gpu, regs[i].offset,
+			  state ? regs[i].value : 0);
+
+	if (adreno_is_a540(adreno_gpu)) {
+		gpu_write(gpu, REG_A5XX_RBBM_CLOCK_DELAY_GPMU, state ? 0x00000770 : 0);
+		gpu_write(gpu, REG_A5XX_RBBM_CLOCK_HYST_GPMU, state ? 0x00000004 : 0);
+	}
+
+	gpu_write(gpu, REG_A5XX_RBBM_CLOCK_CNTL, state ? 0xAAA8AA00 : 0);
+	gpu_write(gpu, REG_A5XX_RBBM_ISDB_CNT, state ? 0x182 : 0x180);
+}
+
+static int a5xx_me_init(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct msm_ringbuffer *ring = gpu->rb[0];
+
+	OUT_PKT7(ring, CP_ME_INIT, 8);
+
+	OUT_RING(ring, 0x0000002F);
+
+	/* Enable multiple hardware contexts */
+	OUT_RING(ring, 0x00000003);
+
+	/* Enable error detection */
+	OUT_RING(ring, 0x20000000);
+
+	/* Don't enable header dump */
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+
+	/* Specify workarounds for various microcode issues */
+	if (adreno_is_a506(adreno_gpu) || adreno_is_a530(adreno_gpu)) {
+		/* Workaround for token end syncs
+		 * Force a WFI after every direct-render 3D mode draw and every
+		 * 2D mode 3 draw
+		 */
+		OUT_RING(ring, 0x0000000B);
+	} else if (adreno_is_a510(adreno_gpu)) {
+		/* Workaround for token and syncs */
+		OUT_RING(ring, 0x00000001);
+	} else {
+		/* No workarounds enabled */
+		OUT_RING(ring, 0x00000000);
+	}
+
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+
+	a5xx_flush(gpu, ring, true);
+	return a5xx_idle(gpu, ring) ? 0 : -EINVAL;
+}
+
+static int a5xx_preempt_start(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	struct msm_ringbuffer *ring = gpu->rb[0];
+
+	if (gpu->nr_rings == 1)
+		return 0;
+
+	/* Turn off protected mode to write to special registers */
+	OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
+	OUT_RING(ring, 0);
+
+	/* Set the save preemption record for the ring/command */
+	OUT_PKT4(ring, REG_A5XX_CP_CONTEXT_SWITCH_SAVE_ADDR_LO, 2);
+	OUT_RING(ring, lower_32_bits(a5xx_gpu->preempt_iova[ring->id]));
+	OUT_RING(ring, upper_32_bits(a5xx_gpu->preempt_iova[ring->id]));
+
+	/* Turn back on protected mode */
+	OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
+	OUT_RING(ring, 1);
+
+	OUT_PKT7(ring, CP_PREEMPT_ENABLE_GLOBAL, 1);
+	OUT_RING(ring, 0x00);
+
+	OUT_PKT7(ring, CP_PREEMPT_ENABLE_LOCAL, 1);
+	OUT_RING(ring, 0x01);
+
+	OUT_PKT7(ring, CP_YIELD_ENABLE, 1);
+	OUT_RING(ring, 0x01);
+
+	/* Yield the floor on command completion */
+	OUT_PKT7(ring, CP_CONTEXT_SWITCH_YIELD, 4);
+	OUT_RING(ring, 0x00);
+	OUT_RING(ring, 0x00);
+	OUT_RING(ring, 0x01);
+	OUT_RING(ring, 0x01);
+
+	/* The WHERE_AMI_I packet is not needed after a YIELD is issued */
+	a5xx_flush(gpu, ring, false);
+
+	return a5xx_idle(gpu, ring) ? 0 : -EINVAL;
+}
+
+static void a5xx_ucode_check_version(struct a5xx_gpu *a5xx_gpu,
+		struct drm_gem_object *obj)
+{
+	u32 *buf = msm_gem_get_vaddr(obj);
+
+	if (IS_ERR(buf))
+		return;
+
+	/*
+	 * If the lowest nibble is 0xa that is an indication that this microcode
+	 * has been patched. The actual version is in dword [3] but we only care
+	 * about the patchlevel which is the lowest nibble of dword [3]
+	 */
+	if (((buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1)
+		a5xx_gpu->has_whereami = true;
+
+	msm_gem_put_vaddr(obj);
+}
+
+static int a5xx_ucode_load(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	int ret;
+
+	if (!a5xx_gpu->pm4_bo) {
+		a5xx_gpu->pm4_bo = adreno_fw_create_bo(gpu,
+			adreno_gpu->fw[ADRENO_FW_PM4], &a5xx_gpu->pm4_iova);
+
+
+		if (IS_ERR(a5xx_gpu->pm4_bo)) {
+			ret = PTR_ERR(a5xx_gpu->pm4_bo);
+			a5xx_gpu->pm4_bo = NULL;
+			DRM_DEV_ERROR(gpu->dev->dev, "could not allocate PM4: %d\n",
+				ret);
+			return ret;
+		}
+
+		msm_gem_object_set_name(a5xx_gpu->pm4_bo, "pm4fw");
+	}
+
+	if (!a5xx_gpu->pfp_bo) {
+		a5xx_gpu->pfp_bo = adreno_fw_create_bo(gpu,
+			adreno_gpu->fw[ADRENO_FW_PFP], &a5xx_gpu->pfp_iova);
+
+		if (IS_ERR(a5xx_gpu->pfp_bo)) {
+			ret = PTR_ERR(a5xx_gpu->pfp_bo);
+			a5xx_gpu->pfp_bo = NULL;
+			DRM_DEV_ERROR(gpu->dev->dev, "could not allocate PFP: %d\n",
+				ret);
+			return ret;
+		}
+
+		msm_gem_object_set_name(a5xx_gpu->pfp_bo, "pfpfw");
+		a5xx_ucode_check_version(a5xx_gpu, a5xx_gpu->pfp_bo);
+	}
+
+	if (a5xx_gpu->has_whereami) {
+		if (!a5xx_gpu->shadow_bo) {
+			a5xx_gpu->shadow = msm_gem_kernel_new(gpu->dev,
+				sizeof(u32) * gpu->nr_rings,
+				MSM_BO_WC | MSM_BO_MAP_PRIV,
+				gpu->aspace, &a5xx_gpu->shadow_bo,
+				&a5xx_gpu->shadow_iova);
+
+			if (IS_ERR(a5xx_gpu->shadow))
+				return PTR_ERR(a5xx_gpu->shadow);
+
+			msm_gem_object_set_name(a5xx_gpu->shadow_bo, "shadow");
+		}
+	} else if (gpu->nr_rings > 1) {
+		/* Disable preemption if WHERE_AM_I isn't available */
+		a5xx_preempt_fini(gpu);
+		gpu->nr_rings = 1;
+	}
+
+	return 0;
+}
+
+#define SCM_GPU_ZAP_SHADER_RESUME 0
+
+static int a5xx_zap_shader_resume(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	int ret;
+
+	/*
+	 * Adreno 506 have CPZ Retention feature and doesn't require
+	 * to resume zap shader
+	 */
+	if (adreno_is_a506(adreno_gpu))
+		return 0;
+
+	ret = qcom_scm_set_remote_state(SCM_GPU_ZAP_SHADER_RESUME, GPU_PAS_ID);
+	if (ret)
+		DRM_ERROR("%s: zap-shader resume failed: %d\n",
+			gpu->name, ret);
+
+	return ret;
+}
+
+static int a5xx_zap_shader_init(struct msm_gpu *gpu)
+{
+	static bool loaded;
+	int ret;
+
+	/*
+	 * If the zap shader is already loaded into memory we just need to kick
+	 * the remote processor to reinitialize it
+	 */
+	if (loaded)
+		return a5xx_zap_shader_resume(gpu);
+
+	ret = adreno_zap_shader_load(gpu, GPU_PAS_ID);
+
+	loaded = !ret;
+	return ret;
+}
+
+#define A5XX_INT_MASK (A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR | \
+	  A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT | \
+	  A5XX_RBBM_INT_0_MASK_RBBM_ME_MS_TIMEOUT | \
+	  A5XX_RBBM_INT_0_MASK_RBBM_PFP_MS_TIMEOUT | \
+	  A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT | \
+	  A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW | \
+	  A5XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
+	  A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT | \
+	  A5XX_RBBM_INT_0_MASK_CP_SW | \
+	  A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS | \
+	  A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
+	  A5XX_RBBM_INT_0_MASK_GPMU_VOLTAGE_DROOP)
+
+static int a5xx_hw_init(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	u32 hbb;
+	int ret;
+
+	gpu_write(gpu, REG_A5XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x00000003);
+
+	if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu) ||
+	    adreno_is_a540(adreno_gpu))
+		gpu_write(gpu, REG_A5XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000009);
+
+	/* Make all blocks contribute to the GPU BUSY perf counter */
+	gpu_write(gpu, REG_A5XX_RBBM_PERFCTR_GPU_BUSY_MASKED, 0xFFFFFFFF);
+
+	/* Enable RBBM error reporting bits */
+	gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL0, 0x00000001);
+
+	if (adreno_gpu->info->quirks & ADRENO_QUIRK_FAULT_DETECT_MASK) {
+		/*
+		 * Mask out the activity signals from RB1-3 to avoid false
+		 * positives
+		 */
+
+		gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL11,
+			0xF0000000);
+		gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL12,
+			0xFFFFFFFF);
+		gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL13,
+			0xFFFFFFFF);
+		gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL14,
+			0xFFFFFFFF);
+		gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL15,
+			0xFFFFFFFF);
+		gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL16,
+			0xFFFFFFFF);
+		gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL17,
+			0xFFFFFFFF);
+		gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_MASK_CNTL18,
+			0xFFFFFFFF);
+	}
+
+	/* Enable fault detection */
+	gpu_write(gpu, REG_A5XX_RBBM_INTERFACE_HANG_INT_CNTL,
+		(1 << 30) | 0xFFFF);
+
+	/* Turn on performance counters */
+	gpu_write(gpu, REG_A5XX_RBBM_PERFCTR_CNTL, 0x01);
+
+	/* Select CP0 to always count cycles */
+	gpu_write(gpu, REG_A5XX_CP_PERFCTR_CP_SEL_0, PERF_CP_ALWAYS_COUNT);
+
+	/* Select RBBM0 to countable 6 to get the busy status for devfreq */
+	gpu_write(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_SEL_0, 6);
+
+	/* Increase VFD cache access so LRZ and other data gets evicted less */
+	gpu_write(gpu, REG_A5XX_UCHE_CACHE_WAYS, 0x02);
+
+	/* Disable L2 bypass in the UCHE */
+	gpu_write(gpu, REG_A5XX_UCHE_TRAP_BASE_LO, 0xFFFF0000);
+	gpu_write(gpu, REG_A5XX_UCHE_TRAP_BASE_HI, 0x0001FFFF);
+	gpu_write(gpu, REG_A5XX_UCHE_WRITE_THRU_BASE_LO, 0xFFFF0000);
+	gpu_write(gpu, REG_A5XX_UCHE_WRITE_THRU_BASE_HI, 0x0001FFFF);
+
+	/* Set the GMEM VA range (0 to gpu->gmem) */
+	gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MIN_LO, 0x00100000);
+	gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MIN_HI, 0x00000000);
+	gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX_LO,
+		0x00100000 + adreno_gpu->info->gmem - 1);
+	gpu_write(gpu, REG_A5XX_UCHE_GMEM_RANGE_MAX_HI, 0x00000000);
+
+	if (adreno_is_a506(adreno_gpu) || adreno_is_a508(adreno_gpu) ||
+	    adreno_is_a510(adreno_gpu)) {
+		gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x20);
+		if (adreno_is_a506(adreno_gpu) || adreno_is_a508(adreno_gpu))
+			gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x400);
+		else
+			gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x20);
+		gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x40000030);
+		gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x20100D0A);
+	} else {
+		gpu_write(gpu, REG_A5XX_CP_MEQ_THRESHOLDS, 0x40);
+		if (adreno_is_a530(adreno_gpu))
+			gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x40);
+		else
+			gpu_write(gpu, REG_A5XX_CP_MERCIU_SIZE, 0x400);
+		gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_2, 0x80000060);
+		gpu_write(gpu, REG_A5XX_CP_ROQ_THRESHOLDS_1, 0x40201B16);
+	}
+
+	if (adreno_is_a506(adreno_gpu) || adreno_is_a508(adreno_gpu))
+		gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL,
+			  (0x100 << 11 | 0x100 << 22));
+	else if (adreno_is_a509(adreno_gpu) || adreno_is_a510(adreno_gpu) ||
+		 adreno_is_a512(adreno_gpu))
+		gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL,
+			  (0x200 << 11 | 0x200 << 22));
+	else
+		gpu_write(gpu, REG_A5XX_PC_DBG_ECO_CNTL,
+			  (0x400 << 11 | 0x300 << 22));
+
+	if (adreno_gpu->info->quirks & ADRENO_QUIRK_TWO_PASS_USE_WFI)
+		gpu_rmw(gpu, REG_A5XX_PC_DBG_ECO_CNTL, 0, (1 << 8));
+
+	/*
+	 * Disable the RB sampler datapath DP2 clock gating optimization
+	 * for 1-SP GPUs, as it is enabled by default.
+	 */
+	if (adreno_is_a506(adreno_gpu) || adreno_is_a508(adreno_gpu) ||
+	    adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu))
+		gpu_rmw(gpu, REG_A5XX_RB_DBG_ECO_CNTL, 0, (1 << 9));
+
+	/* Disable UCHE global filter as SP can invalidate/flush independently */
+	gpu_write(gpu, REG_A5XX_UCHE_MODE_CNTL, BIT(29));
+
+	/* Enable USE_RETENTION_FLOPS */
+	gpu_write(gpu, REG_A5XX_CP_CHICKEN_DBG, 0x02000000);
+
+	/* Enable ME/PFP split notification */
+	gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL1, 0xA6FFFFFF);
+
+	/*
+	 *  In A5x, CCU can send context_done event of a particular context to
+	 *  UCHE which ultimately reaches CP even when there is valid
+	 *  transaction of that context inside CCU. This can let CP to program
+	 *  config registers, which will make the "valid transaction" inside
+	 *  CCU to be interpreted differently. This can cause gpu fault. This
+	 *  bug is fixed in latest A510 revision. To enable this bug fix -
+	 *  bit[11] of RB_DBG_ECO_CNTL need to be set to 0, default is 1
+	 *  (disable). For older A510 version this bit is unused.
+	 */
+	if (adreno_is_a510(adreno_gpu))
+		gpu_rmw(gpu, REG_A5XX_RB_DBG_ECO_CNTL, (1 << 11), 0);
+
+	/* Enable HWCG */
+	a5xx_set_hwcg(gpu, true);
+
+	gpu_write(gpu, REG_A5XX_RBBM_AHB_CNTL2, 0x0000003F);
+
+	BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13);
+	hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13;
+
+	gpu_write(gpu, REG_A5XX_TPL1_MODE_CNTL, hbb << 7);
+	gpu_write(gpu, REG_A5XX_RB_MODE_CNTL, hbb << 1);
+
+	if (adreno_is_a509(adreno_gpu) || adreno_is_a512(adreno_gpu) ||
+	    adreno_is_a540(adreno_gpu))
+		gpu_write(gpu, REG_A5XX_UCHE_DBG_ECO_CNTL_2, hbb);
+
+	/* Disable All flat shading optimization (ALLFLATOPTDIS) */
+	gpu_rmw(gpu, REG_A5XX_VPC_DBG_ECO_CNTL, 0, (1 << 10));
+
+	/* Protect registers from the CP */
+	gpu_write(gpu, REG_A5XX_CP_PROTECT_CNTL, 0x00000007);
+
+	/* RBBM */
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(0), ADRENO_PROTECT_RW(0x04, 4));
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(1), ADRENO_PROTECT_RW(0x08, 8));
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(2), ADRENO_PROTECT_RW(0x10, 16));
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(3), ADRENO_PROTECT_RW(0x20, 32));
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(4), ADRENO_PROTECT_RW(0x40, 64));
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(5), ADRENO_PROTECT_RW(0x80, 64));
+
+	/* Content protect */
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(6),
+		ADRENO_PROTECT_RW(REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_LO,
+			16));
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(7),
+		ADRENO_PROTECT_RW(REG_A5XX_RBBM_SECVID_TRUST_CNTL, 2));
+
+	/* CP */
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(8), ADRENO_PROTECT_RW(0x800, 64));
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(9), ADRENO_PROTECT_RW(0x840, 8));
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(10), ADRENO_PROTECT_RW(0x880, 32));
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(11), ADRENO_PROTECT_RW(0xAA0, 1));
+
+	/* RB */
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(12), ADRENO_PROTECT_RW(0xCC0, 1));
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(13), ADRENO_PROTECT_RW(0xCF0, 2));
+
+	/* VPC */
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(14), ADRENO_PROTECT_RW(0xE68, 8));
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(15), ADRENO_PROTECT_RW(0xE70, 16));
+
+	/* UCHE */
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(16), ADRENO_PROTECT_RW(0xE80, 16));
+
+	/* SMMU */
+	gpu_write(gpu, REG_A5XX_CP_PROTECT(17),
+			ADRENO_PROTECT_RW(0x10000, 0x8000));
+
+	gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_CNTL, 0);
+	/*
+	 * Disable the trusted memory range - we don't actually supported secure
+	 * memory rendering at this point in time and we don't want to block off
+	 * part of the virtual memory space.
+	 */
+	gpu_write64(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_BASE_LO, 0x00000000);
+	gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_TRUSTED_SIZE, 0x00000000);
+
+	/* Put the GPU into 64 bit by default */
+	gpu_write(gpu, REG_A5XX_CP_ADDR_MODE_CNTL, 0x1);
+	gpu_write(gpu, REG_A5XX_VSC_ADDR_MODE_CNTL, 0x1);
+	gpu_write(gpu, REG_A5XX_GRAS_ADDR_MODE_CNTL, 0x1);
+	gpu_write(gpu, REG_A5XX_RB_ADDR_MODE_CNTL, 0x1);
+	gpu_write(gpu, REG_A5XX_PC_ADDR_MODE_CNTL, 0x1);
+	gpu_write(gpu, REG_A5XX_HLSQ_ADDR_MODE_CNTL, 0x1);
+	gpu_write(gpu, REG_A5XX_VFD_ADDR_MODE_CNTL, 0x1);
+	gpu_write(gpu, REG_A5XX_VPC_ADDR_MODE_CNTL, 0x1);
+	gpu_write(gpu, REG_A5XX_UCHE_ADDR_MODE_CNTL, 0x1);
+	gpu_write(gpu, REG_A5XX_SP_ADDR_MODE_CNTL, 0x1);
+	gpu_write(gpu, REG_A5XX_TPL1_ADDR_MODE_CNTL, 0x1);
+	gpu_write(gpu, REG_A5XX_RBBM_SECVID_TSB_ADDR_MODE_CNTL, 0x1);
+
+	/*
+	 * VPC corner case with local memory load kill leads to corrupt
+	 * internal state. Normal Disable does not work for all a5x chips.
+	 * So do the following setting to disable it.
+	 */
+	if (adreno_gpu->info->quirks & ADRENO_QUIRK_LMLOADKILL_DISABLE) {
+		gpu_rmw(gpu, REG_A5XX_VPC_DBG_ECO_CNTL, 0, BIT(23));
+		gpu_rmw(gpu, REG_A5XX_HLSQ_DBG_ECO_CNTL, BIT(18), 0);
+	}
+
+	ret = adreno_hw_init(gpu);
+	if (ret)
+		return ret;
+
+	if (adreno_is_a530(adreno_gpu) || adreno_is_a540(adreno_gpu))
+		a5xx_gpmu_ucode_init(gpu);
+
+	gpu_write64(gpu, REG_A5XX_CP_ME_INSTR_BASE_LO, a5xx_gpu->pm4_iova);
+	gpu_write64(gpu, REG_A5XX_CP_PFP_INSTR_BASE_LO, a5xx_gpu->pfp_iova);
+
+	/* Set the ringbuffer address */
+	gpu_write64(gpu, REG_A5XX_CP_RB_BASE, gpu->rb[0]->iova);
+
+	/*
+	 * If the microcode supports the WHERE_AM_I opcode then we can use that
+	 * in lieu of the RPTR shadow and enable preemption. Otherwise, we
+	 * can't safely use the RPTR shadow or preemption. In either case, the
+	 * RPTR shadow should be disabled in hardware.
+	 */
+	gpu_write(gpu, REG_A5XX_CP_RB_CNTL,
+		MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE);
+
+	/* Configure the RPTR shadow if needed: */
+	if (a5xx_gpu->shadow_bo) {
+		gpu_write64(gpu, REG_A5XX_CP_RB_RPTR_ADDR,
+			    shadowptr(a5xx_gpu, gpu->rb[0]));
+	}
+
+	a5xx_preempt_hw_init(gpu);
+
+	/* Disable the interrupts through the initial bringup stage */
+	gpu_write(gpu, REG_A5XX_RBBM_INT_0_MASK, A5XX_INT_MASK);
+
+	/* Clear ME_HALT to start the micro engine */
+	gpu_write(gpu, REG_A5XX_CP_PFP_ME_CNTL, 0);
+	ret = a5xx_me_init(gpu);
+	if (ret)
+		return ret;
+
+	ret = a5xx_power_init(gpu);
+	if (ret)
+		return ret;
+
+	/*
+	 * Send a pipeline event stat to get misbehaving counters to start
+	 * ticking correctly
+	 */
+	if (adreno_is_a530(adreno_gpu)) {
+		OUT_PKT7(gpu->rb[0], CP_EVENT_WRITE, 1);
+		OUT_RING(gpu->rb[0], CP_EVENT_WRITE_0_EVENT(STAT_EVENT));
+
+		a5xx_flush(gpu, gpu->rb[0], true);
+		if (!a5xx_idle(gpu, gpu->rb[0]))
+			return -EINVAL;
+	}
+
+	/*
+	 * If the chip that we are using does support loading one, then
+	 * try to load a zap shader into the secure world. If successful
+	 * we can use the CP to switch out of secure mode. If not then we
+	 * have no resource but to try to switch ourselves out manually. If we
+	 * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
+	 * be blocked and a permissions violation will soon follow.
+	 */
+	ret = a5xx_zap_shader_init(gpu);
+	if (!ret) {
+		OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
+		OUT_RING(gpu->rb[0], 0x00000000);
+
+		a5xx_flush(gpu, gpu->rb[0], true);
+		if (!a5xx_idle(gpu, gpu->rb[0]))
+			return -EINVAL;
+	} else if (ret == -ENODEV) {
+		/*
+		 * This device does not use zap shader (but print a warning
+		 * just in case someone got their dt wrong.. hopefully they
+		 * have a debug UART to realize the error of their ways...
+		 * if you mess this up you are about to crash horribly)
+		 */
+		dev_warn_once(gpu->dev->dev,
+			"Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
+		gpu_write(gpu, REG_A5XX_RBBM_SECVID_TRUST_CNTL, 0x0);
+	} else {
+		return ret;
+	}
+
+	/* Last step - yield the ringbuffer */
+	a5xx_preempt_start(gpu);
+
+	return 0;
+}
+
+static void a5xx_recover(struct msm_gpu *gpu)
+{
+	int i;
+
+	adreno_dump_info(gpu);
+
+	for (i = 0; i < 8; i++) {
+		printk("CP_SCRATCH_REG%d: %u\n", i,
+			gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(i)));
+	}
+
+	if (hang_debug)
+		a5xx_dump(gpu);
+
+	gpu_write(gpu, REG_A5XX_RBBM_SW_RESET_CMD, 1);
+	gpu_read(gpu, REG_A5XX_RBBM_SW_RESET_CMD);
+	gpu_write(gpu, REG_A5XX_RBBM_SW_RESET_CMD, 0);
+	adreno_recover(gpu);
+}
+
+static void a5xx_destroy(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+
+	DBG("%s", gpu->name);
+
+	a5xx_preempt_fini(gpu);
+
+	if (a5xx_gpu->pm4_bo) {
+		msm_gem_unpin_iova(a5xx_gpu->pm4_bo, gpu->aspace);
+		drm_gem_object_put(a5xx_gpu->pm4_bo);
+	}
+
+	if (a5xx_gpu->pfp_bo) {
+		msm_gem_unpin_iova(a5xx_gpu->pfp_bo, gpu->aspace);
+		drm_gem_object_put(a5xx_gpu->pfp_bo);
+	}
+
+	if (a5xx_gpu->gpmu_bo) {
+		msm_gem_unpin_iova(a5xx_gpu->gpmu_bo, gpu->aspace);
+		drm_gem_object_put(a5xx_gpu->gpmu_bo);
+	}
+
+	if (a5xx_gpu->shadow_bo) {
+		msm_gem_unpin_iova(a5xx_gpu->shadow_bo, gpu->aspace);
+		drm_gem_object_put(a5xx_gpu->shadow_bo);
+	}
+
+	adreno_gpu_cleanup(adreno_gpu);
+	kfree(a5xx_gpu);
+}
+
+static inline bool _a5xx_check_idle(struct msm_gpu *gpu)
+{
+	if (gpu_read(gpu, REG_A5XX_RBBM_STATUS) & ~A5XX_RBBM_STATUS_HI_BUSY)
+		return false;
+
+	/*
+	 * Nearly every abnormality ends up pausing the GPU and triggering a
+	 * fault so we can safely just watch for this one interrupt to fire
+	 */
+	return !(gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS) &
+		A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT);
+}
+
+bool a5xx_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+
+	if (ring != a5xx_gpu->cur_ring) {
+		WARN(1, "Tried to idle a non-current ringbuffer\n");
+		return false;
+	}
+
+	/* wait for CP to drain ringbuffer: */
+	if (!adreno_idle(gpu, ring))
+		return false;
+
+	if (spin_until(_a5xx_check_idle(gpu))) {
+		DRM_ERROR("%s: %ps: timeout waiting for GPU to idle: status %8.8X irq %8.8X rptr/wptr %d/%d\n",
+			gpu->name, __builtin_return_address(0),
+			gpu_read(gpu, REG_A5XX_RBBM_STATUS),
+			gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS),
+			gpu_read(gpu, REG_A5XX_CP_RB_RPTR),
+			gpu_read(gpu, REG_A5XX_CP_RB_WPTR));
+		return false;
+	}
+
+	return true;
+}
+
+static int a5xx_fault_handler(void *arg, unsigned long iova, int flags, void *data)
+{
+	struct msm_gpu *gpu = arg;
+	struct adreno_smmu_fault_info *info = data;
+	char block[12] = "unknown";
+	u32 scratch[] = {
+			gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(4)),
+			gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(5)),
+			gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(6)),
+			gpu_read(gpu, REG_A5XX_CP_SCRATCH_REG(7)),
+	};
+
+	if (info)
+		snprintf(block, sizeof(block), "%x", info->fsynr1);
+
+	return adreno_fault_handler(gpu, iova, flags, info, block, scratch);
+}
+
+static void a5xx_cp_err_irq(struct msm_gpu *gpu)
+{
+	u32 status = gpu_read(gpu, REG_A5XX_CP_INTERRUPT_STATUS);
+
+	if (status & A5XX_CP_INT_CP_OPCODE_ERROR) {
+		u32 val;
+
+		gpu_write(gpu, REG_A5XX_CP_PFP_STAT_ADDR, 0);
+
+		/*
+		 * REG_A5XX_CP_PFP_STAT_DATA is indexed, and we want index 1 so
+		 * read it twice
+		 */
+
+		gpu_read(gpu, REG_A5XX_CP_PFP_STAT_DATA);
+		val = gpu_read(gpu, REG_A5XX_CP_PFP_STAT_DATA);
+
+		dev_err_ratelimited(gpu->dev->dev, "CP | opcode error | possible opcode=0x%8.8X\n",
+			val);
+	}
+
+	if (status & A5XX_CP_INT_CP_HW_FAULT_ERROR)
+		dev_err_ratelimited(gpu->dev->dev, "CP | HW fault | status=0x%8.8X\n",
+			gpu_read(gpu, REG_A5XX_CP_HW_FAULT));
+
+	if (status & A5XX_CP_INT_CP_DMA_ERROR)
+		dev_err_ratelimited(gpu->dev->dev, "CP | DMA error\n");
+
+	if (status & A5XX_CP_INT_CP_REGISTER_PROTECTION_ERROR) {
+		u32 val = gpu_read(gpu, REG_A5XX_CP_PROTECT_STATUS);
+
+		dev_err_ratelimited(gpu->dev->dev,
+			"CP | protected mode error | %s | addr=0x%8.8X | status=0x%8.8X\n",
+			val & (1 << 24) ? "WRITE" : "READ",
+			(val & 0xFFFFF) >> 2, val);
+	}
+
+	if (status & A5XX_CP_INT_CP_AHB_ERROR) {
+		u32 status = gpu_read(gpu, REG_A5XX_CP_AHB_FAULT);
+		const char *access[16] = { "reserved", "reserved",
+			"timestamp lo", "timestamp hi", "pfp read", "pfp write",
+			"", "", "me read", "me write", "", "", "crashdump read",
+			"crashdump write" };
+
+		dev_err_ratelimited(gpu->dev->dev,
+			"CP | AHB error | addr=%X access=%s error=%d | status=0x%8.8X\n",
+			status & 0xFFFFF, access[(status >> 24) & 0xF],
+			(status & (1 << 31)), status);
+	}
+}
+
+static void a5xx_rbbm_err_irq(struct msm_gpu *gpu, u32 status)
+{
+	if (status & A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR) {
+		u32 val = gpu_read(gpu, REG_A5XX_RBBM_AHB_ERROR_STATUS);
+
+		dev_err_ratelimited(gpu->dev->dev,
+			"RBBM | AHB bus error | %s | addr=0x%X | ports=0x%X:0x%X\n",
+			val & (1 << 28) ? "WRITE" : "READ",
+			(val & 0xFFFFF) >> 2, (val >> 20) & 0x3,
+			(val >> 24) & 0xF);
+
+		/* Clear the error */
+		gpu_write(gpu, REG_A5XX_RBBM_AHB_CMD, (1 << 4));
+
+		/* Clear the interrupt */
+		gpu_write(gpu, REG_A5XX_RBBM_INT_CLEAR_CMD,
+			A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR);
+	}
+
+	if (status & A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT)
+		dev_err_ratelimited(gpu->dev->dev, "RBBM | AHB transfer timeout\n");
+
+	if (status & A5XX_RBBM_INT_0_MASK_RBBM_ME_MS_TIMEOUT)
+		dev_err_ratelimited(gpu->dev->dev, "RBBM | ME master split | status=0x%X\n",
+			gpu_read(gpu, REG_A5XX_RBBM_AHB_ME_SPLIT_STATUS));
+
+	if (status & A5XX_RBBM_INT_0_MASK_RBBM_PFP_MS_TIMEOUT)
+		dev_err_ratelimited(gpu->dev->dev, "RBBM | PFP master split | status=0x%X\n",
+			gpu_read(gpu, REG_A5XX_RBBM_AHB_PFP_SPLIT_STATUS));
+
+	if (status & A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT)
+		dev_err_ratelimited(gpu->dev->dev, "RBBM | ETS master split | status=0x%X\n",
+			gpu_read(gpu, REG_A5XX_RBBM_AHB_ETS_SPLIT_STATUS));
+
+	if (status & A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW)
+		dev_err_ratelimited(gpu->dev->dev, "RBBM | ATB ASYNC overflow\n");
+
+	if (status & A5XX_RBBM_INT_0_MASK_RBBM_ATB_BUS_OVERFLOW)
+		dev_err_ratelimited(gpu->dev->dev, "RBBM | ATB bus overflow\n");
+}
+
+static void a5xx_uche_err_irq(struct msm_gpu *gpu)
+{
+	uint64_t addr = (uint64_t) gpu_read(gpu, REG_A5XX_UCHE_TRAP_LOG_HI);
+
+	addr |= gpu_read(gpu, REG_A5XX_UCHE_TRAP_LOG_LO);
+
+	dev_err_ratelimited(gpu->dev->dev, "UCHE | Out of bounds access | addr=0x%llX\n",
+		addr);
+}
+
+static void a5xx_gpmu_err_irq(struct msm_gpu *gpu)
+{
+	dev_err_ratelimited(gpu->dev->dev, "GPMU | voltage droop\n");
+}
+
+static void a5xx_fault_detect_irq(struct msm_gpu *gpu)
+{
+	struct drm_device *dev = gpu->dev;
+	struct msm_ringbuffer *ring = gpu->funcs->active_ring(gpu);
+
+	/*
+	 * If stalled on SMMU fault, we could trip the GPU's hang detection,
+	 * but the fault handler will trigger the devcore dump, and we want
+	 * to otherwise resume normally rather than killing the submit, so
+	 * just bail.
+	 */
+	if (gpu_read(gpu, REG_A5XX_RBBM_STATUS3) & BIT(24))
+		return;
+
+	DRM_DEV_ERROR(dev->dev, "gpu fault ring %d fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n",
+		ring ? ring->id : -1, ring ? ring->fctx->last_fence : 0,
+		gpu_read(gpu, REG_A5XX_RBBM_STATUS),
+		gpu_read(gpu, REG_A5XX_CP_RB_RPTR),
+		gpu_read(gpu, REG_A5XX_CP_RB_WPTR),
+		gpu_read64(gpu, REG_A5XX_CP_IB1_BASE),
+		gpu_read(gpu, REG_A5XX_CP_IB1_BUFSZ),
+		gpu_read64(gpu, REG_A5XX_CP_IB2_BASE),
+		gpu_read(gpu, REG_A5XX_CP_IB2_BUFSZ));
+
+	/* Turn off the hangcheck timer to keep it from bothering us */
+	del_timer(&gpu->hangcheck_timer);
+
+	kthread_queue_work(gpu->worker, &gpu->recover_work);
+}
+
+#define RBBM_ERROR_MASK \
+	(A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR | \
+	A5XX_RBBM_INT_0_MASK_RBBM_TRANSFER_TIMEOUT | \
+	A5XX_RBBM_INT_0_MASK_RBBM_ME_MS_TIMEOUT | \
+	A5XX_RBBM_INT_0_MASK_RBBM_PFP_MS_TIMEOUT | \
+	A5XX_RBBM_INT_0_MASK_RBBM_ETS_MS_TIMEOUT | \
+	A5XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNC_OVERFLOW)
+
+static irqreturn_t a5xx_irq(struct msm_gpu *gpu)
+{
+	struct msm_drm_private *priv = gpu->dev->dev_private;
+	u32 status = gpu_read(gpu, REG_A5XX_RBBM_INT_0_STATUS);
+
+	/*
+	 * Clear all the interrupts except RBBM_AHB_ERROR - if we clear it
+	 * before the source is cleared the interrupt will storm.
+	 */
+	gpu_write(gpu, REG_A5XX_RBBM_INT_CLEAR_CMD,
+		status & ~A5XX_RBBM_INT_0_MASK_RBBM_AHB_ERROR);
+
+	if (priv->disable_err_irq) {
+		status &= A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS |
+			  A5XX_RBBM_INT_0_MASK_CP_SW;
+	}
+
+	/* Pass status to a5xx_rbbm_err_irq because we've already cleared it */
+	if (status & RBBM_ERROR_MASK)
+		a5xx_rbbm_err_irq(gpu, status);
+
+	if (status & A5XX_RBBM_INT_0_MASK_CP_HW_ERROR)
+		a5xx_cp_err_irq(gpu);
+
+	if (status & A5XX_RBBM_INT_0_MASK_MISC_HANG_DETECT)
+		a5xx_fault_detect_irq(gpu);
+
+	if (status & A5XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
+		a5xx_uche_err_irq(gpu);
+
+	if (status & A5XX_RBBM_INT_0_MASK_GPMU_VOLTAGE_DROOP)
+		a5xx_gpmu_err_irq(gpu);
+
+	if (status & A5XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS) {
+		a5xx_preempt_trigger(gpu);
+		msm_gpu_retire(gpu);
+	}
+
+	if (status & A5XX_RBBM_INT_0_MASK_CP_SW)
+		a5xx_preempt_irq(gpu);
+
+	return IRQ_HANDLED;
+}
+
+static const u32 a5xx_registers[] = {
+	0x0000, 0x0002, 0x0004, 0x0020, 0x0022, 0x0026, 0x0029, 0x002B,
+	0x002E, 0x0035, 0x0038, 0x0042, 0x0044, 0x0044, 0x0047, 0x0095,
+	0x0097, 0x00BB, 0x03A0, 0x0464, 0x0469, 0x046F, 0x04D2, 0x04D3,
+	0x04E0, 0x0533, 0x0540, 0x0555, 0x0800, 0x081A, 0x081F, 0x0841,
+	0x0860, 0x0860, 0x0880, 0x08A0, 0x0B00, 0x0B12, 0x0B15, 0x0B28,
+	0x0B78, 0x0B7F, 0x0BB0, 0x0BBD, 0x0BC0, 0x0BC6, 0x0BD0, 0x0C53,
+	0x0C60, 0x0C61, 0x0C80, 0x0C82, 0x0C84, 0x0C85, 0x0C90, 0x0C98,
+	0x0CA0, 0x0CA0, 0x0CB0, 0x0CB2, 0x2180, 0x2185, 0x2580, 0x2585,
+	0x0CC1, 0x0CC1, 0x0CC4, 0x0CC7, 0x0CCC, 0x0CCC, 0x0CD0, 0x0CD8,
+	0x0CE0, 0x0CE5, 0x0CE8, 0x0CE8, 0x0CEC, 0x0CF1, 0x0CFB, 0x0D0E,
+	0x2100, 0x211E, 0x2140, 0x2145, 0x2500, 0x251E, 0x2540, 0x2545,
+	0x0D10, 0x0D17, 0x0D20, 0x0D23, 0x0D30, 0x0D30, 0x20C0, 0x20C0,
+	0x24C0, 0x24C0, 0x0E40, 0x0E43, 0x0E4A, 0x0E4A, 0x0E50, 0x0E57,
+	0x0E60, 0x0E7C, 0x0E80, 0x0E8E, 0x0E90, 0x0E96, 0x0EA0, 0x0EA8,
+	0x0EB0, 0x0EB2, 0xE140, 0xE147, 0xE150, 0xE187, 0xE1A0, 0xE1A9,
+	0xE1B0, 0xE1B6, 0xE1C0, 0xE1C7, 0xE1D0, 0xE1D1, 0xE200, 0xE201,
+	0xE210, 0xE21C, 0xE240, 0xE268, 0xE000, 0xE006, 0xE010, 0xE09A,
+	0xE0A0, 0xE0A4, 0xE0AA, 0xE0EB, 0xE100, 0xE105, 0xE380, 0xE38F,
+	0xE3B0, 0xE3B0, 0xE400, 0xE405, 0xE408, 0xE4E9, 0xE4F0, 0xE4F0,
+	0xE280, 0xE280, 0xE282, 0xE2A3, 0xE2A5, 0xE2C2, 0xE940, 0xE947,
+	0xE950, 0xE987, 0xE9A0, 0xE9A9, 0xE9B0, 0xE9B6, 0xE9C0, 0xE9C7,
+	0xE9D0, 0xE9D1, 0xEA00, 0xEA01, 0xEA10, 0xEA1C, 0xEA40, 0xEA68,
+	0xE800, 0xE806, 0xE810, 0xE89A, 0xE8A0, 0xE8A4, 0xE8AA, 0xE8EB,
+	0xE900, 0xE905, 0xEB80, 0xEB8F, 0xEBB0, 0xEBB0, 0xEC00, 0xEC05,
+	0xEC08, 0xECE9, 0xECF0, 0xECF0, 0xEA80, 0xEA80, 0xEA82, 0xEAA3,
+	0xEAA5, 0xEAC2, 0xA800, 0xA800, 0xA820, 0xA828, 0xA840, 0xA87D,
+	0XA880, 0xA88D, 0xA890, 0xA8A3, 0xA8D0, 0xA8D8, 0xA8E0, 0xA8F5,
+	0xAC60, 0xAC60, ~0,
+};
+
+static void a5xx_dump(struct msm_gpu *gpu)
+{
+	DRM_DEV_INFO(gpu->dev->dev, "status:   %08x\n",
+		gpu_read(gpu, REG_A5XX_RBBM_STATUS));
+	adreno_dump(gpu);
+}
+
+static int a5xx_pm_resume(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	int ret;
+
+	/* Turn on the core power */
+	ret = msm_gpu_pm_resume(gpu);
+	if (ret)
+		return ret;
+
+	/* Adreno 506, 508, 509, 510, 512 needs manual RBBM sus/res control */
+	if (!(adreno_is_a530(adreno_gpu) || adreno_is_a540(adreno_gpu))) {
+		/* Halt the sp_input_clk at HM level */
+		gpu_write(gpu, REG_A5XX_RBBM_CLOCK_CNTL, 0x00000055);
+		a5xx_set_hwcg(gpu, true);
+		/* Turn on sp_input_clk at HM level */
+		gpu_rmw(gpu, REG_A5XX_RBBM_CLOCK_CNTL, 0xff, 0);
+		return 0;
+	}
+
+	/* Turn the RBCCU domain first to limit the chances of voltage droop */
+	gpu_write(gpu, REG_A5XX_GPMU_RBCCU_POWER_CNTL, 0x778000);
+
+	/* Wait 3 usecs before polling */
+	udelay(3);
+
+	ret = spin_usecs(gpu, 20, REG_A5XX_GPMU_RBCCU_PWR_CLK_STATUS,
+		(1 << 20), (1 << 20));
+	if (ret) {
+		DRM_ERROR("%s: timeout waiting for RBCCU GDSC enable: %X\n",
+			gpu->name,
+			gpu_read(gpu, REG_A5XX_GPMU_RBCCU_PWR_CLK_STATUS));
+		return ret;
+	}
+
+	/* Turn on the SP domain */
+	gpu_write(gpu, REG_A5XX_GPMU_SP_POWER_CNTL, 0x778000);
+	ret = spin_usecs(gpu, 20, REG_A5XX_GPMU_SP_PWR_CLK_STATUS,
+		(1 << 20), (1 << 20));
+	if (ret)
+		DRM_ERROR("%s: timeout waiting for SP GDSC enable\n",
+			gpu->name);
+
+	return ret;
+}
+
+static int a5xx_pm_suspend(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	u32 mask = 0xf;
+	int i, ret;
+
+	/* A506, A508, A510 have 3 XIN ports in VBIF */
+	if (adreno_is_a506(adreno_gpu) || adreno_is_a508(adreno_gpu) ||
+	    adreno_is_a510(adreno_gpu))
+		mask = 0x7;
+
+	/* Clear the VBIF pipe before shutting down */
+	gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, mask);
+	spin_until((gpu_read(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL1) &
+				mask) == mask);
+
+	gpu_write(gpu, REG_A5XX_VBIF_XIN_HALT_CTRL0, 0);
+
+	/*
+	 * Reset the VBIF before power collapse to avoid issue with FIFO
+	 * entries on Adreno A510 and A530 (the others will tend to lock up)
+	 */
+	if (adreno_is_a510(adreno_gpu) || adreno_is_a530(adreno_gpu)) {
+		gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x003C0000);
+		gpu_write(gpu, REG_A5XX_RBBM_BLOCK_SW_RESET_CMD, 0x00000000);
+	}
+
+	ret = msm_gpu_pm_suspend(gpu);
+	if (ret)
+		return ret;
+
+	if (a5xx_gpu->has_whereami)
+		for (i = 0; i < gpu->nr_rings; i++)
+			a5xx_gpu->shadow[i] = 0;
+
+	return 0;
+}
+
+static int a5xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
+{
+	*value = gpu_read64(gpu, REG_A5XX_RBBM_ALWAYSON_COUNTER_LO);
+
+	return 0;
+}
+
+struct a5xx_crashdumper {
+	void *ptr;
+	struct drm_gem_object *bo;
+	u64 iova;
+};
+
+struct a5xx_gpu_state {
+	struct msm_gpu_state base;
+	u32 *hlsqregs;
+};
+
+static int a5xx_crashdumper_init(struct msm_gpu *gpu,
+		struct a5xx_crashdumper *dumper)
+{
+	dumper->ptr = msm_gem_kernel_new(gpu->dev,
+		SZ_1M, MSM_BO_WC, gpu->aspace,
+		&dumper->bo, &dumper->iova);
+
+	if (!IS_ERR(dumper->ptr))
+		msm_gem_object_set_name(dumper->bo, "crashdump");
+
+	return PTR_ERR_OR_ZERO(dumper->ptr);
+}
+
+static int a5xx_crashdumper_run(struct msm_gpu *gpu,
+		struct a5xx_crashdumper *dumper)
+{
+	u32 val;
+
+	if (IS_ERR_OR_NULL(dumper->ptr))
+		return -EINVAL;
+
+	gpu_write64(gpu, REG_A5XX_CP_CRASH_SCRIPT_BASE_LO, dumper->iova);
+
+	gpu_write(gpu, REG_A5XX_CP_CRASH_DUMP_CNTL, 1);
+
+	return gpu_poll_timeout(gpu, REG_A5XX_CP_CRASH_DUMP_CNTL, val,
+		val & 0x04, 100, 10000);
+}
+
+/*
+ * These are a list of the registers that need to be read through the HLSQ
+ * aperture through the crashdumper.  These are not nominally accessible from
+ * the CPU on a secure platform.
+ */
+static const struct {
+	u32 type;
+	u32 regoffset;
+	u32 count;
+} a5xx_hlsq_aperture_regs[] = {
+	{ 0x35, 0xe00, 0x32 },   /* HSLQ non-context */
+	{ 0x31, 0x2080, 0x1 },   /* HLSQ 2D context 0 */
+	{ 0x33, 0x2480, 0x1 },   /* HLSQ 2D context 1 */
+	{ 0x32, 0xe780, 0x62 },  /* HLSQ 3D context 0 */
+	{ 0x34, 0xef80, 0x62 },  /* HLSQ 3D context 1 */
+	{ 0x3f, 0x0ec0, 0x40 },  /* SP non-context */
+	{ 0x3d, 0x2040, 0x1 },   /* SP 2D context 0 */
+	{ 0x3b, 0x2440, 0x1 },   /* SP 2D context 1 */
+	{ 0x3e, 0xe580, 0x170 }, /* SP 3D context 0 */
+	{ 0x3c, 0xed80, 0x170 }, /* SP 3D context 1 */
+	{ 0x3a, 0x0f00, 0x1c },  /* TP non-context */
+	{ 0x38, 0x2000, 0xa },   /* TP 2D context 0 */
+	{ 0x36, 0x2400, 0xa },   /* TP 2D context 1 */
+	{ 0x39, 0xe700, 0x80 },  /* TP 3D context 0 */
+	{ 0x37, 0xef00, 0x80 },  /* TP 3D context 1 */
+};
+
+static void a5xx_gpu_state_get_hlsq_regs(struct msm_gpu *gpu,
+		struct a5xx_gpu_state *a5xx_state)
+{
+	struct a5xx_crashdumper dumper = { 0 };
+	u32 offset, count = 0;
+	u64 *ptr;
+	int i;
+
+	if (a5xx_crashdumper_init(gpu, &dumper))
+		return;
+
+	/* The script will be written at offset 0 */
+	ptr = dumper.ptr;
+
+	/* Start writing the data at offset 256k */
+	offset = dumper.iova + (256 * SZ_1K);
+
+	/* Count how many additional registers to get from the HLSQ aperture */
+	for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_aperture_regs); i++)
+		count += a5xx_hlsq_aperture_regs[i].count;
+
+	a5xx_state->hlsqregs = kcalloc(count, sizeof(u32), GFP_KERNEL);
+	if (!a5xx_state->hlsqregs)
+		return;
+
+	/* Build the crashdump script */
+	for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_aperture_regs); i++) {
+		u32 type = a5xx_hlsq_aperture_regs[i].type;
+		u32 c = a5xx_hlsq_aperture_regs[i].count;
+
+		/* Write the register to select the desired bank */
+		*ptr++ = ((u64) type << 8);
+		*ptr++ = (((u64) REG_A5XX_HLSQ_DBG_READ_SEL) << 44) |
+			(1 << 21) | 1;
+
+		*ptr++ = offset;
+		*ptr++ = (((u64) REG_A5XX_HLSQ_DBG_AHB_READ_APERTURE) << 44)
+			| c;
+
+		offset += c * sizeof(u32);
+	}
+
+	/* Write two zeros to close off the script */
+	*ptr++ = 0;
+	*ptr++ = 0;
+
+	if (a5xx_crashdumper_run(gpu, &dumper)) {
+		kfree(a5xx_state->hlsqregs);
+		msm_gem_kernel_put(dumper.bo, gpu->aspace);
+		return;
+	}
+
+	/* Copy the data from the crashdumper to the state */
+	memcpy(a5xx_state->hlsqregs, dumper.ptr + (256 * SZ_1K),
+		count * sizeof(u32));
+
+	msm_gem_kernel_put(dumper.bo, gpu->aspace);
+}
+
+static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu)
+{
+	struct a5xx_gpu_state *a5xx_state = kzalloc(sizeof(*a5xx_state),
+			GFP_KERNEL);
+	bool stalled = !!(gpu_read(gpu, REG_A5XX_RBBM_STATUS3) & BIT(24));
+
+	if (!a5xx_state)
+		return ERR_PTR(-ENOMEM);
+
+	/* Temporarily disable hardware clock gating before reading the hw */
+	a5xx_set_hwcg(gpu, false);
+
+	/* First get the generic state from the adreno core */
+	adreno_gpu_state_get(gpu, &(a5xx_state->base));
+
+	a5xx_state->base.rbbm_status = gpu_read(gpu, REG_A5XX_RBBM_STATUS);
+
+	/*
+	 * Get the HLSQ regs with the help of the crashdumper, but only if
+	 * we are not stalled in an iommu fault (in which case the crashdumper
+	 * would not have access to memory)
+	 */
+	if (!stalled)
+		a5xx_gpu_state_get_hlsq_regs(gpu, a5xx_state);
+
+	a5xx_set_hwcg(gpu, true);
+
+	return &a5xx_state->base;
+}
+
+static void a5xx_gpu_state_destroy(struct kref *kref)
+{
+	struct msm_gpu_state *state = container_of(kref,
+		struct msm_gpu_state, ref);
+	struct a5xx_gpu_state *a5xx_state = container_of(state,
+		struct a5xx_gpu_state, base);
+
+	kfree(a5xx_state->hlsqregs);
+
+	adreno_gpu_state_destroy(state);
+	kfree(a5xx_state);
+}
+
+static int a5xx_gpu_state_put(struct msm_gpu_state *state)
+{
+	if (IS_ERR_OR_NULL(state))
+		return 1;
+
+	return kref_put(&state->ref, a5xx_gpu_state_destroy);
+}
+
+
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
+static void a5xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		      struct drm_printer *p)
+{
+	int i, j;
+	u32 pos = 0;
+	struct a5xx_gpu_state *a5xx_state = container_of(state,
+		struct a5xx_gpu_state, base);
+
+	if (IS_ERR_OR_NULL(state))
+		return;
+
+	adreno_show(gpu, state, p);
+
+	/* Dump the additional a5xx HLSQ registers */
+	if (!a5xx_state->hlsqregs)
+		return;
+
+	drm_printf(p, "registers-hlsq:\n");
+
+	for (i = 0; i < ARRAY_SIZE(a5xx_hlsq_aperture_regs); i++) {
+		u32 o = a5xx_hlsq_aperture_regs[i].regoffset;
+		u32 c = a5xx_hlsq_aperture_regs[i].count;
+
+		for (j = 0; j < c; j++, pos++, o++) {
+			/*
+			 * To keep the crashdump simple we pull the entire range
+			 * for each register type but not all of the registers
+			 * in the range are valid. Fortunately invalid registers
+			 * stick out like a sore thumb with a value of
+			 * 0xdeadbeef
+			 */
+			if (a5xx_state->hlsqregs[pos] == 0xdeadbeef)
+				continue;
+
+			drm_printf(p, "  - { offset: 0x%04x, value: 0x%08x }\n",
+				o << 2, a5xx_state->hlsqregs[pos]);
+		}
+	}
+}
+#endif
+
+static struct msm_ringbuffer *a5xx_active_ring(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+
+	return a5xx_gpu->cur_ring;
+}
+
+static u64 a5xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate)
+{
+	u64 busy_cycles;
+
+	busy_cycles = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_RBBM_0_LO);
+	*out_sample_rate = clk_get_rate(gpu->core_clk);
+
+	return busy_cycles;
+}
+
+static uint32_t a5xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+
+	if (a5xx_gpu->has_whereami)
+		return a5xx_gpu->shadow[ring->id];
+
+	return ring->memptrs->rptr = gpu_read(gpu, REG_A5XX_CP_RB_RPTR);
+}
+
+static const struct adreno_gpu_funcs funcs = {
+	.base = {
+		.get_param = adreno_get_param,
+		.set_param = adreno_set_param,
+		.hw_init = a5xx_hw_init,
+		.ucode_load = a5xx_ucode_load,
+		.pm_suspend = a5xx_pm_suspend,
+		.pm_resume = a5xx_pm_resume,
+		.recover = a5xx_recover,
+		.submit = a5xx_submit,
+		.active_ring = a5xx_active_ring,
+		.irq = a5xx_irq,
+		.destroy = a5xx_destroy,
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
+		.show = a5xx_show,
+#endif
+#if defined(CONFIG_DEBUG_FS)
+		.debugfs_init = a5xx_debugfs_init,
+#endif
+		.gpu_busy = a5xx_gpu_busy,
+		.gpu_state_get = a5xx_gpu_state_get,
+		.gpu_state_put = a5xx_gpu_state_put,
+		.create_address_space = adreno_create_address_space,
+		.get_rptr = a5xx_get_rptr,
+	},
+	.get_timestamp = a5xx_get_timestamp,
+};
+
+static void check_speed_bin(struct device *dev)
+{
+	struct nvmem_cell *cell;
+	u32 val;
+
+	/*
+	 * If the OPP table specifies a opp-supported-hw property then we have
+	 * to set something with dev_pm_opp_set_supported_hw() or the table
+	 * doesn't get populated so pick an arbitrary value that should
+	 * ensure the default frequencies are selected but not conflict with any
+	 * actual bins
+	 */
+	val = 0x80;
+
+	cell = nvmem_cell_get(dev, "speed_bin");
+
+	if (!IS_ERR(cell)) {
+		void *buf = nvmem_cell_read(cell, NULL);
+
+		if (!IS_ERR(buf)) {
+			u8 bin = *((u8 *) buf);
+
+			val = (1 << bin);
+			kfree(buf);
+		}
+
+		nvmem_cell_put(cell);
+	}
+
+	devm_pm_opp_set_supported_hw(dev, &val, 1);
+}
+
+struct msm_gpu *a5xx_gpu_init(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct platform_device *pdev = priv->gpu_pdev;
+	struct adreno_platform_config *config = pdev->dev.platform_data;
+	struct a5xx_gpu *a5xx_gpu = NULL;
+	struct adreno_gpu *adreno_gpu;
+	struct msm_gpu *gpu;
+	unsigned int nr_rings;
+	int ret;
+
+	if (!pdev) {
+		DRM_DEV_ERROR(dev->dev, "No A5XX device is defined\n");
+		return ERR_PTR(-ENXIO);
+	}
+
+	a5xx_gpu = kzalloc(sizeof(*a5xx_gpu), GFP_KERNEL);
+	if (!a5xx_gpu)
+		return ERR_PTR(-ENOMEM);
+
+	adreno_gpu = &a5xx_gpu->base;
+	gpu = &adreno_gpu->base;
+
+	adreno_gpu->registers = a5xx_registers;
+
+	a5xx_gpu->lm_leakage = 0x4E001A;
+
+	check_speed_bin(&pdev->dev);
+
+	nr_rings = 4;
+
+	if (config->info->revn == 510)
+		nr_rings = 1;
+
+	ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, nr_rings);
+	if (ret) {
+		a5xx_destroy(&(a5xx_gpu->base.base));
+		return ERR_PTR(ret);
+	}
+
+	if (gpu->aspace)
+		msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu, a5xx_fault_handler);
+
+	/* Set up the preemption specific bits and pieces for each ringbuffer */
+	a5xx_preempt_init(gpu);
+
+	/* Set the highest bank bit */
+	if (adreno_is_a540(adreno_gpu) || adreno_is_a530(adreno_gpu))
+		adreno_gpu->ubwc_config.highest_bank_bit = 15;
+	else
+		adreno_gpu->ubwc_config.highest_bank_bit = 14;
+
+	/* a5xx only supports UBWC 1.0, these are not configurable */
+	adreno_gpu->ubwc_config.macrotile_mode = 0;
+	adreno_gpu->ubwc_config.ubwc_swizzle = 0x7;
+
+	return gpu;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a5xx_gpu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a5xx_gpu.h
@@ -0,0 +1,176 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ */
+#ifndef __A5XX_GPU_H__
+#define __A5XX_GPU_H__
+
+#include "adreno_gpu.h"
+
+/* Bringing over the hack from the previous targets */
+#undef ROP_COPY
+#undef ROP_XOR
+
+#include "a5xx.xml.h"
+
+struct a5xx_gpu {
+	struct adreno_gpu base;
+
+	struct drm_gem_object *pm4_bo;
+	uint64_t pm4_iova;
+
+	struct drm_gem_object *pfp_bo;
+	uint64_t pfp_iova;
+
+	struct drm_gem_object *gpmu_bo;
+	uint64_t gpmu_iova;
+	uint32_t gpmu_dwords;
+
+	uint32_t lm_leakage;
+
+	struct msm_ringbuffer *cur_ring;
+	struct msm_ringbuffer *next_ring;
+
+	struct drm_gem_object *preempt_bo[MSM_GPU_MAX_RINGS];
+	struct drm_gem_object *preempt_counters_bo[MSM_GPU_MAX_RINGS];
+	struct a5xx_preempt_record *preempt[MSM_GPU_MAX_RINGS];
+	uint64_t preempt_iova[MSM_GPU_MAX_RINGS];
+	uint32_t last_seqno[MSM_GPU_MAX_RINGS];
+
+	atomic_t preempt_state;
+	spinlock_t preempt_start_lock;
+	struct timer_list preempt_timer;
+
+	struct drm_gem_object *shadow_bo;
+	uint64_t shadow_iova;
+	uint32_t *shadow;
+
+	/* True if the microcode supports the WHERE_AM_I opcode */
+	bool has_whereami;
+};
+
+#define to_a5xx_gpu(x) container_of(x, struct a5xx_gpu, base)
+
+#ifdef CONFIG_DEBUG_FS
+void a5xx_debugfs_init(struct msm_gpu *gpu, struct drm_minor *minor);
+#endif
+
+/*
+ * In order to do lockless preemption we use a simple state machine to progress
+ * through the process.
+ *
+ * PREEMPT_NONE - no preemption in progress.  Next state START.
+ * PREEMPT_START - The trigger is evaulating if preemption is possible. Next
+ * states: TRIGGERED, NONE
+ * PREEMPT_ABORT - An intermediate state before moving back to NONE. Next
+ * state: NONE.
+ * PREEMPT_TRIGGERED: A preemption has been executed on the hardware. Next
+ * states: FAULTED, PENDING
+ * PREEMPT_FAULTED: A preemption timed out (never completed). This will trigger
+ * recovery.  Next state: N/A
+ * PREEMPT_PENDING: Preemption complete interrupt fired - the callback is
+ * checking the success of the operation. Next state: FAULTED, NONE.
+ */
+
+enum preempt_state {
+	PREEMPT_NONE = 0,
+	PREEMPT_START,
+	PREEMPT_ABORT,
+	PREEMPT_TRIGGERED,
+	PREEMPT_FAULTED,
+	PREEMPT_PENDING,
+};
+
+/*
+ * struct a5xx_preempt_record is a shared buffer between the microcode and the
+ * CPU to store the state for preemption. The record itself is much larger
+ * (64k) but most of that is used by the CP for storage.
+ *
+ * There is a preemption record assigned per ringbuffer. When the CPU triggers a
+ * preemption, it fills out the record with the useful information (wptr, ring
+ * base, etc) and the microcode uses that information to set up the CP following
+ * the preemption.  When a ring is switched out, the CP will save the ringbuffer
+ * state back to the record. In this way, once the records are properly set up
+ * the CPU can quickly switch back and forth between ringbuffers by only
+ * updating a few registers (often only the wptr).
+ *
+ * These are the CPU aware registers in the record:
+ * @magic: Must always be 0x27C4BAFC
+ * @info: Type of the record - written 0 by the CPU, updated by the CP
+ * @data: Data field from SET_RENDER_MODE or a checkpoint. Written and used by
+ * the CP
+ * @cntl: Value of RB_CNTL written by CPU, save/restored by CP
+ * @rptr: Value of RB_RPTR written by CPU, save/restored by CP
+ * @wptr: Value of RB_WPTR written by CPU, save/restored by CP
+ * @rptr_addr: Value of RB_RPTR_ADDR written by CPU, save/restored by CP
+ * @rbase: Value of RB_BASE written by CPU, save/restored by CP
+ * @counter: GPU address of the storage area for the performance counters
+ */
+struct a5xx_preempt_record {
+	uint32_t magic;
+	uint32_t info;
+	uint32_t data;
+	uint32_t cntl;
+	uint32_t rptr;
+	uint32_t wptr;
+	uint64_t rptr_addr;
+	uint64_t rbase;
+	uint64_t counter;
+};
+
+/* Magic identifier for the preemption record */
+#define A5XX_PREEMPT_RECORD_MAGIC 0x27C4BAFCUL
+
+/*
+ * Even though the structure above is only a few bytes, we need a full 64k to
+ * store the entire preemption record from the CP
+ */
+#define A5XX_PREEMPT_RECORD_SIZE (64 * 1024)
+
+/*
+ * The preemption counter block is a storage area for the value of the
+ * preemption counters that are saved immediately before context switch. We
+ * append it on to the end of the allocation for the preemption record.
+ */
+#define A5XX_PREEMPT_COUNTER_SIZE (16 * 4)
+
+
+int a5xx_power_init(struct msm_gpu *gpu);
+void a5xx_gpmu_ucode_init(struct msm_gpu *gpu);
+
+static inline int spin_usecs(struct msm_gpu *gpu, uint32_t usecs,
+		uint32_t reg, uint32_t mask, uint32_t value)
+{
+	while (usecs--) {
+		udelay(1);
+		if ((gpu_read(gpu, reg) & mask) == value)
+			return 0;
+		cpu_relax();
+	}
+
+	return -ETIMEDOUT;
+}
+
+#define shadowptr(a5xx_gpu, ring) ((a5xx_gpu)->shadow_iova + \
+		((ring)->id * sizeof(uint32_t)))
+
+bool a5xx_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
+void a5xx_set_hwcg(struct msm_gpu *gpu, bool state);
+
+void a5xx_preempt_init(struct msm_gpu *gpu);
+void a5xx_preempt_hw_init(struct msm_gpu *gpu);
+void a5xx_preempt_trigger(struct msm_gpu *gpu);
+void a5xx_preempt_irq(struct msm_gpu *gpu);
+void a5xx_preempt_fini(struct msm_gpu *gpu);
+
+void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring, bool sync);
+
+/* Return true if we are in a preempt state */
+static inline bool a5xx_in_preempt(struct a5xx_gpu *a5xx_gpu)
+{
+	int preempt_state = atomic_read(&a5xx_gpu->preempt_state);
+
+	return !(preempt_state == PREEMPT_NONE ||
+			preempt_state == PREEMPT_ABORT);
+}
+
+#endif /* __A5XX_GPU_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a5xx_power.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a5xx_power.c
@@ -0,0 +1,390 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/pm_opp.h>
+#include "a5xx_gpu.h"
+
+/*
+ * The GPMU data block is a block of shared registers that can be used to
+ * communicate back and forth. These "registers" are by convention with the GPMU
+ * firwmare and not bound to any specific hardware design
+ */
+
+#define AGC_INIT_BASE REG_A5XX_GPMU_DATA_RAM_BASE
+#define AGC_INIT_MSG_MAGIC (AGC_INIT_BASE + 5)
+#define AGC_MSG_BASE (AGC_INIT_BASE + 7)
+
+#define AGC_MSG_STATE (AGC_MSG_BASE + 0)
+#define AGC_MSG_COMMAND (AGC_MSG_BASE + 1)
+#define AGC_MSG_PAYLOAD_SIZE (AGC_MSG_BASE + 3)
+#define AGC_MSG_PAYLOAD(_o) ((AGC_MSG_BASE + 5) + (_o))
+
+#define AGC_POWER_CONFIG_PRODUCTION_ID 1
+#define AGC_INIT_MSG_VALUE 0xBABEFACE
+
+/* AGC_LM_CONFIG (A540+) */
+#define AGC_LM_CONFIG (136/4)
+#define AGC_LM_CONFIG_GPU_VERSION_SHIFT 17
+#define AGC_LM_CONFIG_ENABLE_GPMU_ADAPTIVE 1
+#define AGC_LM_CONFIG_THROTTLE_DISABLE (2 << 8)
+#define AGC_LM_CONFIG_ISENSE_ENABLE (1 << 4)
+#define AGC_LM_CONFIG_ENABLE_ERROR (3 << 4)
+#define AGC_LM_CONFIG_LLM_ENABLED (1 << 16)
+#define AGC_LM_CONFIG_BCL_DISABLED (1 << 24)
+
+#define AGC_LEVEL_CONFIG (140/4)
+
+static struct {
+	uint32_t reg;
+	uint32_t value;
+} a5xx_sequence_regs[] = {
+	{ 0xB9A1, 0x00010303 },
+	{ 0xB9A2, 0x13000000 },
+	{ 0xB9A3, 0x00460020 },
+	{ 0xB9A4, 0x10000000 },
+	{ 0xB9A5, 0x040A1707 },
+	{ 0xB9A6, 0x00010000 },
+	{ 0xB9A7, 0x0E000904 },
+	{ 0xB9A8, 0x10000000 },
+	{ 0xB9A9, 0x01165000 },
+	{ 0xB9AA, 0x000E0002 },
+	{ 0xB9AB, 0x03884141 },
+	{ 0xB9AC, 0x10000840 },
+	{ 0xB9AD, 0x572A5000 },
+	{ 0xB9AE, 0x00000003 },
+	{ 0xB9AF, 0x00000000 },
+	{ 0xB9B0, 0x10000000 },
+	{ 0xB828, 0x6C204010 },
+	{ 0xB829, 0x6C204011 },
+	{ 0xB82A, 0x6C204012 },
+	{ 0xB82B, 0x6C204013 },
+	{ 0xB82C, 0x6C204014 },
+	{ 0xB90F, 0x00000004 },
+	{ 0xB910, 0x00000002 },
+	{ 0xB911, 0x00000002 },
+	{ 0xB912, 0x00000002 },
+	{ 0xB913, 0x00000002 },
+	{ 0xB92F, 0x00000004 },
+	{ 0xB930, 0x00000005 },
+	{ 0xB931, 0x00000005 },
+	{ 0xB932, 0x00000005 },
+	{ 0xB933, 0x00000005 },
+	{ 0xB96F, 0x00000001 },
+	{ 0xB970, 0x00000003 },
+	{ 0xB94F, 0x00000004 },
+	{ 0xB950, 0x0000000B },
+	{ 0xB951, 0x0000000B },
+	{ 0xB952, 0x0000000B },
+	{ 0xB953, 0x0000000B },
+	{ 0xB907, 0x00000019 },
+	{ 0xB927, 0x00000019 },
+	{ 0xB947, 0x00000019 },
+	{ 0xB967, 0x00000019 },
+	{ 0xB987, 0x00000019 },
+	{ 0xB906, 0x00220001 },
+	{ 0xB926, 0x00220001 },
+	{ 0xB946, 0x00220001 },
+	{ 0xB966, 0x00220001 },
+	{ 0xB986, 0x00300000 },
+	{ 0xAC40, 0x0340FF41 },
+	{ 0xAC41, 0x03BEFED0 },
+	{ 0xAC42, 0x00331FED },
+	{ 0xAC43, 0x021FFDD3 },
+	{ 0xAC44, 0x5555AAAA },
+	{ 0xAC45, 0x5555AAAA },
+	{ 0xB9BA, 0x00000008 },
+};
+
+/*
+ * Get the actual voltage value for the operating point at the specified
+ * frequency
+ */
+static inline uint32_t _get_mvolts(struct msm_gpu *gpu, uint32_t freq)
+{
+	struct drm_device *dev = gpu->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct platform_device *pdev = priv->gpu_pdev;
+	struct dev_pm_opp *opp;
+	u32 ret = 0;
+
+	opp = dev_pm_opp_find_freq_exact(&pdev->dev, freq, true);
+
+	if (!IS_ERR(opp)) {
+		ret = dev_pm_opp_get_voltage(opp) / 1000;
+		dev_pm_opp_put(opp);
+	}
+
+	return ret;
+}
+
+/* Setup thermal limit management */
+static void a530_lm_setup(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	unsigned int i;
+
+	/* Write the block of sequence registers */
+	for (i = 0; i < ARRAY_SIZE(a5xx_sequence_regs); i++)
+		gpu_write(gpu, a5xx_sequence_regs[i].reg,
+			a5xx_sequence_regs[i].value);
+
+	/* Hard code the A530 GPU thermal sensor ID for the GPMU */
+	gpu_write(gpu, REG_A5XX_GPMU_TEMP_SENSOR_ID, 0x60007);
+	gpu_write(gpu, REG_A5XX_GPMU_DELTA_TEMP_THRESHOLD, 0x01);
+	gpu_write(gpu, REG_A5XX_GPMU_TEMP_SENSOR_CONFIG, 0x01);
+
+	/* Until we get clock scaling 0 is always the active power level */
+	gpu_write(gpu, REG_A5XX_GPMU_GPMU_VOLTAGE, 0x80000000 | 0);
+
+	gpu_write(gpu, REG_A5XX_GPMU_BASE_LEAKAGE, a5xx_gpu->lm_leakage);
+
+	/* The threshold is fixed at 6000 for A530 */
+	gpu_write(gpu, REG_A5XX_GPMU_GPMU_PWR_THRESHOLD, 0x80000000 | 6000);
+
+	gpu_write(gpu, REG_A5XX_GPMU_BEC_ENABLE, 0x10001FFF);
+	gpu_write(gpu, REG_A5XX_GDPM_CONFIG1, 0x00201FF1);
+
+	/* Write the voltage table */
+	gpu_write(gpu, REG_A5XX_GPMU_BEC_ENABLE, 0x10001FFF);
+	gpu_write(gpu, REG_A5XX_GDPM_CONFIG1, 0x201FF1);
+
+	gpu_write(gpu, AGC_MSG_STATE, 1);
+	gpu_write(gpu, AGC_MSG_COMMAND, AGC_POWER_CONFIG_PRODUCTION_ID);
+
+	/* Write the max power - hard coded to 5448 for A530 */
+	gpu_write(gpu, AGC_MSG_PAYLOAD(0), 5448);
+	gpu_write(gpu, AGC_MSG_PAYLOAD(1), 1);
+
+	/*
+	 * For now just write the one voltage level - we will do more when we
+	 * can do scaling
+	 */
+	gpu_write(gpu, AGC_MSG_PAYLOAD(2), _get_mvolts(gpu, gpu->fast_rate));
+	gpu_write(gpu, AGC_MSG_PAYLOAD(3), gpu->fast_rate / 1000000);
+
+	gpu_write(gpu, AGC_MSG_PAYLOAD_SIZE, 4 * sizeof(uint32_t));
+	gpu_write(gpu, AGC_INIT_MSG_MAGIC, AGC_INIT_MSG_VALUE);
+}
+
+#define PAYLOAD_SIZE(_size) ((_size) * sizeof(u32))
+#define LM_DCVS_LIMIT 1
+#define LEVEL_CONFIG ~(0x303)
+
+static void a540_lm_setup(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	u32 config;
+
+	/* The battery current limiter isn't enabled for A540 */
+	config = AGC_LM_CONFIG_BCL_DISABLED;
+	config |= adreno_patchid(adreno_gpu) << AGC_LM_CONFIG_GPU_VERSION_SHIFT;
+
+	/* For now disable GPMU side throttling */
+	config |= AGC_LM_CONFIG_THROTTLE_DISABLE;
+
+	/* Until we get clock scaling 0 is always the active power level */
+	gpu_write(gpu, REG_A5XX_GPMU_GPMU_VOLTAGE, 0x80000000 | 0);
+
+	/* Fixed at 6000 for now */
+	gpu_write(gpu, REG_A5XX_GPMU_GPMU_PWR_THRESHOLD, 0x80000000 | 6000);
+
+	gpu_write(gpu, AGC_MSG_STATE, 0x80000001);
+	gpu_write(gpu, AGC_MSG_COMMAND, AGC_POWER_CONFIG_PRODUCTION_ID);
+
+	gpu_write(gpu, AGC_MSG_PAYLOAD(0), 5448);
+	gpu_write(gpu, AGC_MSG_PAYLOAD(1), 1);
+
+	gpu_write(gpu, AGC_MSG_PAYLOAD(2), _get_mvolts(gpu, gpu->fast_rate));
+	gpu_write(gpu, AGC_MSG_PAYLOAD(3), gpu->fast_rate / 1000000);
+
+	gpu_write(gpu, AGC_MSG_PAYLOAD(AGC_LM_CONFIG), config);
+	gpu_write(gpu, AGC_MSG_PAYLOAD(AGC_LEVEL_CONFIG), LEVEL_CONFIG);
+	gpu_write(gpu, AGC_MSG_PAYLOAD_SIZE,
+	PAYLOAD_SIZE(AGC_LEVEL_CONFIG + 1));
+
+	gpu_write(gpu, AGC_INIT_MSG_MAGIC, AGC_INIT_MSG_VALUE);
+}
+
+/* Enable SP/TP cpower collapse */
+static void a5xx_pc_init(struct msm_gpu *gpu)
+{
+	gpu_write(gpu, REG_A5XX_GPMU_PWR_COL_INTER_FRAME_CTRL, 0x7F);
+	gpu_write(gpu, REG_A5XX_GPMU_PWR_COL_BINNING_CTRL, 0);
+	gpu_write(gpu, REG_A5XX_GPMU_PWR_COL_INTER_FRAME_HYST, 0xA0080);
+	gpu_write(gpu, REG_A5XX_GPMU_PWR_COL_STAGGER_DELAY, 0x600040);
+}
+
+/* Enable the GPMU microcontroller */
+static int a5xx_gpmu_init(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	struct msm_ringbuffer *ring = gpu->rb[0];
+
+	if (!a5xx_gpu->gpmu_dwords)
+		return 0;
+
+	/* Turn off protected mode for this operation */
+	OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
+	OUT_RING(ring, 0);
+
+	/* Kick off the IB to load the GPMU microcode */
+	OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3);
+	OUT_RING(ring, lower_32_bits(a5xx_gpu->gpmu_iova));
+	OUT_RING(ring, upper_32_bits(a5xx_gpu->gpmu_iova));
+	OUT_RING(ring, a5xx_gpu->gpmu_dwords);
+
+	/* Turn back on protected mode */
+	OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
+	OUT_RING(ring, 1);
+
+	a5xx_flush(gpu, ring, true);
+
+	if (!a5xx_idle(gpu, ring)) {
+		DRM_ERROR("%s: Unable to load GPMU firmware. GPMU will not be active\n",
+			gpu->name);
+		return -EINVAL;
+	}
+
+	if (adreno_is_a530(adreno_gpu))
+		gpu_write(gpu, REG_A5XX_GPMU_WFI_CONFIG, 0x4014);
+
+	/* Kick off the GPMU */
+	gpu_write(gpu, REG_A5XX_GPMU_CM3_SYSRESET, 0x0);
+
+	/*
+	 * Wait for the GPMU to respond. It isn't fatal if it doesn't, we just
+	 * won't have advanced power collapse.
+	 */
+	if (spin_usecs(gpu, 25, REG_A5XX_GPMU_GENERAL_0, 0xFFFFFFFF,
+		0xBABEFACE))
+		DRM_ERROR("%s: GPMU firmware initialization timed out\n",
+			gpu->name);
+
+	if (!adreno_is_a530(adreno_gpu)) {
+		u32 val = gpu_read(gpu, REG_A5XX_GPMU_GENERAL_1);
+
+		if (val)
+			DRM_ERROR("%s: GPMU firmware initialization failed: %d\n",
+				  gpu->name, val);
+	}
+
+	return 0;
+}
+
+/* Enable limits management */
+static void a5xx_lm_enable(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+
+	/* This init sequence only applies to A530 */
+	if (!adreno_is_a530(adreno_gpu))
+		return;
+
+	gpu_write(gpu, REG_A5XX_GDPM_INT_MASK, 0x0);
+	gpu_write(gpu, REG_A5XX_GDPM_INT_EN, 0x0A);
+	gpu_write(gpu, REG_A5XX_GPMU_GPMU_VOLTAGE_INTR_EN_MASK, 0x01);
+	gpu_write(gpu, REG_A5XX_GPMU_TEMP_THRESHOLD_INTR_EN_MASK, 0x50000);
+	gpu_write(gpu, REG_A5XX_GPMU_THROTTLE_UNMASK_FORCE_CTRL, 0x30000);
+
+	gpu_write(gpu, REG_A5XX_GPMU_CLOCK_THROTTLE_CTRL, 0x011);
+}
+
+int a5xx_power_init(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	int ret;
+
+	/* Not all A5xx chips have a GPMU */
+	if (!(adreno_is_a530(adreno_gpu) || adreno_is_a540(adreno_gpu)))
+		return 0;
+
+	/* Set up the limits management */
+	if (adreno_is_a530(adreno_gpu))
+		a530_lm_setup(gpu);
+	else if (adreno_is_a540(adreno_gpu))
+		a540_lm_setup(gpu);
+
+	/* Set up SP/TP power collpase */
+	a5xx_pc_init(gpu);
+
+	/* Start the GPMU */
+	ret = a5xx_gpmu_init(gpu);
+	if (ret)
+		return ret;
+
+	/* Start the limits management */
+	a5xx_lm_enable(gpu);
+
+	return 0;
+}
+
+void a5xx_gpmu_ucode_init(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	struct drm_device *drm = gpu->dev;
+	uint32_t dwords = 0, offset = 0, bosize;
+	unsigned int *data, *ptr, *cmds;
+	unsigned int cmds_size;
+
+	if (!(adreno_is_a530(adreno_gpu) || adreno_is_a540(adreno_gpu)))
+		return;
+
+	if (a5xx_gpu->gpmu_bo)
+		return;
+
+	data = (unsigned int *) adreno_gpu->fw[ADRENO_FW_GPMU]->data;
+
+	/*
+	 * The first dword is the size of the remaining data in dwords. Use it
+	 * as a checksum of sorts and make sure it matches the actual size of
+	 * the firmware that we read
+	 */
+
+	if (adreno_gpu->fw[ADRENO_FW_GPMU]->size < 8 ||
+		(data[0] < 2) || (data[0] >=
+			(adreno_gpu->fw[ADRENO_FW_GPMU]->size >> 2)))
+		return;
+
+	/* The second dword is an ID - look for 2 (GPMU_FIRMWARE_ID) */
+	if (data[1] != 2)
+		return;
+
+	cmds = data + data[2] + 3;
+	cmds_size = data[0] - data[2] - 2;
+
+	/*
+	 * A single type4 opcode can only have so many values attached so
+	 * add enough opcodes to load the all the commands
+	 */
+	bosize = (cmds_size + (cmds_size / TYPE4_MAX_PAYLOAD) + 1) << 2;
+
+	ptr = msm_gem_kernel_new(drm, bosize,
+		MSM_BO_WC | MSM_BO_GPU_READONLY, gpu->aspace,
+		&a5xx_gpu->gpmu_bo, &a5xx_gpu->gpmu_iova);
+	if (IS_ERR(ptr))
+		return;
+
+	msm_gem_object_set_name(a5xx_gpu->gpmu_bo, "gpmufw");
+
+	while (cmds_size > 0) {
+		int i;
+		uint32_t _size = cmds_size > TYPE4_MAX_PAYLOAD ?
+			TYPE4_MAX_PAYLOAD : cmds_size;
+
+		ptr[dwords++] = PKT4(REG_A5XX_GPMU_INST_RAM_BASE + offset,
+			_size);
+
+		for (i = 0; i < _size; i++)
+			ptr[dwords++] = *cmds++;
+
+		offset += _size;
+		cmds_size -= _size;
+	}
+
+	msm_gem_put_vaddr(a5xx_gpu->gpmu_bo);
+	a5xx_gpu->gpmu_dwords = dwords;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a5xx_preempt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a5xx_preempt.c
@@ -0,0 +1,328 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ */
+
+#include "msm_gem.h"
+#include "a5xx_gpu.h"
+
+/*
+ * Try to transition the preemption state from old to new. Return
+ * true on success or false if the original state wasn't 'old'
+ */
+static inline bool try_preempt_state(struct a5xx_gpu *a5xx_gpu,
+		enum preempt_state old, enum preempt_state new)
+{
+	enum preempt_state cur = atomic_cmpxchg(&a5xx_gpu->preempt_state,
+		old, new);
+
+	return (cur == old);
+}
+
+/*
+ * Force the preemption state to the specified state.  This is used in cases
+ * where the current state is known and won't change
+ */
+static inline void set_preempt_state(struct a5xx_gpu *gpu,
+		enum preempt_state new)
+{
+	/*
+	 * preempt_state may be read by other cores trying to trigger a
+	 * preemption or in the interrupt handler so barriers are needed
+	 * before...
+	 */
+	smp_mb__before_atomic();
+	atomic_set(&gpu->preempt_state, new);
+	/* ... and after*/
+	smp_mb__after_atomic();
+}
+
+/* Write the most recent wptr for the given ring into the hardware */
+static inline void update_wptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+	unsigned long flags;
+	uint32_t wptr;
+
+	if (!ring)
+		return;
+
+	spin_lock_irqsave(&ring->preempt_lock, flags);
+	wptr = get_wptr(ring);
+	spin_unlock_irqrestore(&ring->preempt_lock, flags);
+
+	gpu_write(gpu, REG_A5XX_CP_RB_WPTR, wptr);
+}
+
+/* Return the highest priority ringbuffer with something in it */
+static struct msm_ringbuffer *get_next_ring(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	unsigned long flags;
+	int i;
+
+	for (i = 0; i < gpu->nr_rings; i++) {
+		bool empty;
+		struct msm_ringbuffer *ring = gpu->rb[i];
+
+		spin_lock_irqsave(&ring->preempt_lock, flags);
+		empty = (get_wptr(ring) == gpu->funcs->get_rptr(gpu, ring));
+		if (!empty && ring == a5xx_gpu->cur_ring)
+			empty = ring->memptrs->fence == a5xx_gpu->last_seqno[i];
+		spin_unlock_irqrestore(&ring->preempt_lock, flags);
+
+		if (!empty)
+			return ring;
+	}
+
+	return NULL;
+}
+
+static void a5xx_preempt_timer(struct timer_list *t)
+{
+	struct a5xx_gpu *a5xx_gpu = from_timer(a5xx_gpu, t, preempt_timer);
+	struct msm_gpu *gpu = &a5xx_gpu->base.base;
+	struct drm_device *dev = gpu->dev;
+
+	if (!try_preempt_state(a5xx_gpu, PREEMPT_TRIGGERED, PREEMPT_FAULTED))
+		return;
+
+	DRM_DEV_ERROR(dev->dev, "%s: preemption timed out\n", gpu->name);
+	kthread_queue_work(gpu->worker, &gpu->recover_work);
+}
+
+/* Try to trigger a preemption switch */
+void a5xx_preempt_trigger(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	unsigned long flags;
+	struct msm_ringbuffer *ring;
+
+	if (gpu->nr_rings == 1)
+		return;
+
+	/*
+	 * Serialize preemption start to ensure that we always make
+	 * decision on latest state. Otherwise we can get stuck in
+	 * lower priority or empty ring.
+	 */
+	spin_lock_irqsave(&a5xx_gpu->preempt_start_lock, flags);
+
+	/*
+	 * Try to start preemption by moving from NONE to START. If
+	 * unsuccessful, a preemption is already in flight
+	 */
+	if (!try_preempt_state(a5xx_gpu, PREEMPT_NONE, PREEMPT_START))
+		goto out;
+
+	/* Get the next ring to preempt to */
+	ring = get_next_ring(gpu);
+
+	/*
+	 * If no ring is populated or the highest priority ring is the current
+	 * one do nothing except to update the wptr to the latest and greatest
+	 */
+	if (!ring || (a5xx_gpu->cur_ring == ring)) {
+		/*
+		 * Its possible that while a preemption request is in progress
+		 * from an irq context, a user context trying to submit might
+		 * fail to update the write pointer, because it determines
+		 * that the preempt state is not PREEMPT_NONE.
+		 *
+		 * Close the race by introducing an intermediate
+		 * state PREEMPT_ABORT to let the submit path
+		 * know that the ringbuffer is not going to change
+		 * and can safely update the write pointer.
+		 */
+
+		set_preempt_state(a5xx_gpu, PREEMPT_ABORT);
+		update_wptr(gpu, a5xx_gpu->cur_ring);
+		set_preempt_state(a5xx_gpu, PREEMPT_NONE);
+		goto out;
+	}
+
+	spin_unlock_irqrestore(&a5xx_gpu->preempt_start_lock, flags);
+
+	/* Make sure the wptr doesn't update while we're in motion */
+	spin_lock_irqsave(&ring->preempt_lock, flags);
+	a5xx_gpu->preempt[ring->id]->wptr = get_wptr(ring);
+	spin_unlock_irqrestore(&ring->preempt_lock, flags);
+
+	/* Set the address of the incoming preemption record */
+	gpu_write64(gpu, REG_A5XX_CP_CONTEXT_SWITCH_RESTORE_ADDR_LO,
+		a5xx_gpu->preempt_iova[ring->id]);
+
+	a5xx_gpu->next_ring = ring;
+
+	/* Start a timer to catch a stuck preemption */
+	mod_timer(&a5xx_gpu->preempt_timer, jiffies + msecs_to_jiffies(10000));
+
+	/* Set the preemption state to triggered */
+	set_preempt_state(a5xx_gpu, PREEMPT_TRIGGERED);
+
+	/* Make sure everything is written before hitting the button */
+	wmb();
+
+	/* And actually start the preemption */
+	gpu_write(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL, 1);
+	return;
+
+out:
+	spin_unlock_irqrestore(&a5xx_gpu->preempt_start_lock, flags);
+}
+
+void a5xx_preempt_irq(struct msm_gpu *gpu)
+{
+	uint32_t status;
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	struct drm_device *dev = gpu->dev;
+
+	if (!try_preempt_state(a5xx_gpu, PREEMPT_TRIGGERED, PREEMPT_PENDING))
+		return;
+
+	/* Delete the preemption watchdog timer */
+	del_timer(&a5xx_gpu->preempt_timer);
+
+	/*
+	 * The hardware should be setting CP_CONTEXT_SWITCH_CNTL to zero before
+	 * firing the interrupt, but there is a non zero chance of a hardware
+	 * condition or a software race that could set it again before we have a
+	 * chance to finish. If that happens, log and go for recovery
+	 */
+	status = gpu_read(gpu, REG_A5XX_CP_CONTEXT_SWITCH_CNTL);
+	if (unlikely(status)) {
+		set_preempt_state(a5xx_gpu, PREEMPT_FAULTED);
+		DRM_DEV_ERROR(dev->dev, "%s: Preemption failed to complete\n",
+			gpu->name);
+		kthread_queue_work(gpu->worker, &gpu->recover_work);
+		return;
+	}
+
+	a5xx_gpu->cur_ring = a5xx_gpu->next_ring;
+	a5xx_gpu->next_ring = NULL;
+
+	update_wptr(gpu, a5xx_gpu->cur_ring);
+
+	set_preempt_state(a5xx_gpu, PREEMPT_NONE);
+
+	/*
+	 * Try to trigger preemption again in case there was a submit or
+	 * retire during ring switch
+	 */
+	a5xx_preempt_trigger(gpu);
+}
+
+void a5xx_preempt_hw_init(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	int i;
+
+	/* Always come up on rb 0 */
+	a5xx_gpu->cur_ring = gpu->rb[0];
+
+	/* No preemption if we only have one ring */
+	if (gpu->nr_rings == 1)
+		return;
+
+	for (i = 0; i < gpu->nr_rings; i++) {
+		a5xx_gpu->preempt[i]->data = 0;
+		a5xx_gpu->preempt[i]->info = 0;
+		a5xx_gpu->preempt[i]->wptr = 0;
+		a5xx_gpu->preempt[i]->rptr = 0;
+		a5xx_gpu->preempt[i]->rbase = gpu->rb[i]->iova;
+		a5xx_gpu->preempt[i]->rptr_addr = shadowptr(a5xx_gpu, gpu->rb[i]);
+	}
+
+	/* Write a 0 to signal that we aren't switching pagetables */
+	gpu_write64(gpu, REG_A5XX_CP_CONTEXT_SWITCH_SMMU_INFO_LO, 0);
+
+	/* Reset the preemption state */
+	set_preempt_state(a5xx_gpu, PREEMPT_NONE);
+}
+
+static int preempt_init_ring(struct a5xx_gpu *a5xx_gpu,
+		struct msm_ringbuffer *ring)
+{
+	struct adreno_gpu *adreno_gpu = &a5xx_gpu->base;
+	struct msm_gpu *gpu = &adreno_gpu->base;
+	struct a5xx_preempt_record *ptr;
+	void *counters;
+	struct drm_gem_object *bo = NULL, *counters_bo = NULL;
+	u64 iova = 0, counters_iova = 0;
+
+	ptr = msm_gem_kernel_new(gpu->dev,
+		A5XX_PREEMPT_RECORD_SIZE + A5XX_PREEMPT_COUNTER_SIZE,
+		MSM_BO_WC | MSM_BO_MAP_PRIV, gpu->aspace, &bo, &iova);
+
+	if (IS_ERR(ptr))
+		return PTR_ERR(ptr);
+
+	/* The buffer to store counters needs to be unprivileged */
+	counters = msm_gem_kernel_new(gpu->dev,
+		A5XX_PREEMPT_COUNTER_SIZE,
+		MSM_BO_WC, gpu->aspace, &counters_bo, &counters_iova);
+	if (IS_ERR(counters)) {
+		msm_gem_kernel_put(bo, gpu->aspace);
+		return PTR_ERR(counters);
+	}
+
+	msm_gem_object_set_name(bo, "preempt");
+	msm_gem_object_set_name(counters_bo, "preempt_counters");
+
+	a5xx_gpu->preempt_bo[ring->id] = bo;
+	a5xx_gpu->preempt_counters_bo[ring->id] = counters_bo;
+	a5xx_gpu->preempt_iova[ring->id] = iova;
+	a5xx_gpu->preempt[ring->id] = ptr;
+
+	/* Set up the defaults on the preemption record */
+
+	ptr->magic = A5XX_PREEMPT_RECORD_MAGIC;
+	ptr->info = 0;
+	ptr->data = 0;
+	ptr->cntl = MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE;
+
+	ptr->counter = counters_iova;
+
+	return 0;
+}
+
+void a5xx_preempt_fini(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	int i;
+
+	for (i = 0; i < gpu->nr_rings; i++) {
+		msm_gem_kernel_put(a5xx_gpu->preempt_bo[i], gpu->aspace);
+		msm_gem_kernel_put(a5xx_gpu->preempt_counters_bo[i], gpu->aspace);
+	}
+}
+
+void a5xx_preempt_init(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a5xx_gpu *a5xx_gpu = to_a5xx_gpu(adreno_gpu);
+	int i;
+
+	/* No preemption if we only have one ring */
+	if (gpu->nr_rings <= 1)
+		return;
+
+	for (i = 0; i < gpu->nr_rings; i++) {
+		if (preempt_init_ring(a5xx_gpu, gpu->rb[i])) {
+			/*
+			 * On any failure our adventure is over. Clean up and
+			 * set nr_rings to 1 to force preemption off
+			 */
+			a5xx_preempt_fini(gpu);
+			gpu->nr_rings = 1;
+
+			return;
+		}
+	}
+
+	spin_lock_init(&a5xx_gpu->preempt_start_lock);
+	timer_setup(&a5xx_gpu->preempt_timer, a5xx_preempt_timer, 0);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a6xx_catalog.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a6xx_catalog.c
@@ -0,0 +1,1339 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013-2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
+ */
+
+#include "adreno_gpu.h"
+#include "a6xx_gpu.h"
+#include "a6xx.xml.h"
+#include "a6xx_gmu.xml.h"
+
+static const struct adreno_reglist a612_hwcg[] = {
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000081},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01202222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05522022},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
+	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
+	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
+	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
+	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
+	{},
+};
+
+/* For a615 family (a615, a616, a618 and a619) */
+static const struct adreno_reglist a615_hwcg[] = {
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP0,  0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP0,  0x0000F3CF},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP0,  0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP1,  0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP1, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP1, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP0,  0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP1,  0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP1, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP1, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP1, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP1, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP1, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP1, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE,  0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_HYST_UCHE,  0x00000004},
+	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002020},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU1, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU2, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU3, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU1, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU2, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU3, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05022022},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
+	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
+	{},
+};
+
+static const struct adreno_reglist a630_hwcg[] = {
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP1, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP2, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP3, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02022220},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP1, 0x02022220},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP2, 0x02022220},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP3, 0x02022220},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP1, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP2, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP3, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP1, 0x0000f3cf},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP2, 0x0000f3cf},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP3, 0x0000f3cf},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP1, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP2, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP3, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP1, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP2, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP3, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP1, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP2, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP3, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP1, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP2, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP3, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP1, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP2, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP3, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP1, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP2, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP3, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP1, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP2, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP3, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP1, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP2, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP3, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP1, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP2, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP3, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP1, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP2, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP3, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP1, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP2, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP3, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP1, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP2, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP3, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_UCHE, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
+	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB1, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB2, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB3, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB1, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB2, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB3, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU1, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU2, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU3, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU1, 0x00040f00},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU2, 0x00040f00},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU3, 0x00040f00},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05022022},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
+	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
+	{},
+};
+
+static const struct adreno_reglist a640_hwcg[] = {
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05222022},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
+	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
+	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
+	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
+	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
+	{},
+};
+
+static const struct adreno_reglist a650_hwcg[] = {
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
+	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000777},
+	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
+	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
+	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
+	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
+	{},
+};
+
+static const struct adreno_reglist a660_hwcg[] = {
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
+	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
+	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
+	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
+	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
+	{},
+};
+
+static const struct adreno_reglist a690_hwcg[] = {
+	{REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220},
+	{REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080},
+	{REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000F3CF},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111},
+	{REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777},
+	{REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222},
+	{REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220},
+	{REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040F00},
+	{REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022},
+	{REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555},
+	{REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011},
+	{REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222},
+	{REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x00222222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000},
+	{REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200},
+	{REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004},
+	{REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_TEX_FCHE, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_TEX_FCHE, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_TEX_FCHE, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222},
+	{REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004},
+	{REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002},
+	{REG_A6XX_RBBM_CLOCK_CNTL, 0x8AA8AA82},
+	{REG_A6XX_RBBM_ISDB_CNT, 0x00000182},
+	{REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000},
+	{REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000},
+	{REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222},
+	{REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111},
+	{REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555},
+	{REG_A6XX_GPU_GMU_AO_GMU_CGC_MODE_CNTL, 0x20200},
+	{REG_A6XX_GPU_GMU_AO_GMU_CGC_DELAY_CNTL, 0x10111},
+	{REG_A6XX_GPU_GMU_AO_GMU_CGC_HYST_CNTL, 0x5555},
+	{}
+};
+
+/* For a615, a616, a618, a619, a630, a640 and a680 */
+static const u32 a630_protect_regs[] = {
+	A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
+	A6XX_PROTECT_RDONLY(0x00501, 0x0005),
+	A6XX_PROTECT_RDONLY(0x0050b, 0x02f4),
+	A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00510, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00534, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00800, 0x0082),
+	A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
+	A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
+	A6XX_PROTECT_RDONLY(0x008de, 0x00ae),
+	A6XX_PROTECT_NORDWR(0x00900, 0x004d),
+	A6XX_PROTECT_NORDWR(0x0098d, 0x0272),
+	A6XX_PROTECT_NORDWR(0x00e00, 0x0001),
+	A6XX_PROTECT_NORDWR(0x00e03, 0x000c),
+	A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
+	A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
+	A6XX_PROTECT_NORDWR(0x09624, 0x01db),
+	A6XX_PROTECT_NORDWR(0x09e70, 0x0001),
+	A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
+	A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
+	A6XX_PROTECT_NORDWR(0x0ae50, 0x032f),
+	A6XX_PROTECT_NORDWR(0x0b604, 0x0000),
+	A6XX_PROTECT_NORDWR(0x0be02, 0x0001),
+	A6XX_PROTECT_NORDWR(0x0be20, 0x17df),
+	A6XX_PROTECT_NORDWR(0x0f000, 0x0bff),
+	A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x11c00, 0x0000), /* note: infinite range */
+};
+DECLARE_ADRENO_PROTECT(a630_protect, 32);
+
+/* These are for a620 and a650 */
+static const u32 a650_protect_regs[] = {
+	A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
+	A6XX_PROTECT_RDONLY(0x00501, 0x0005),
+	A6XX_PROTECT_RDONLY(0x0050b, 0x02f4),
+	A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00510, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00534, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00800, 0x0082),
+	A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
+	A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
+	A6XX_PROTECT_RDONLY(0x008de, 0x00ae),
+	A6XX_PROTECT_NORDWR(0x00900, 0x004d),
+	A6XX_PROTECT_NORDWR(0x0098d, 0x0272),
+	A6XX_PROTECT_NORDWR(0x00e00, 0x0001),
+	A6XX_PROTECT_NORDWR(0x00e03, 0x000c),
+	A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
+	A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
+	A6XX_PROTECT_NORDWR(0x08e80, 0x027f),
+	A6XX_PROTECT_NORDWR(0x09624, 0x01db),
+	A6XX_PROTECT_NORDWR(0x09e60, 0x0011),
+	A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
+	A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
+	A6XX_PROTECT_NORDWR(0x0ae50, 0x032f),
+	A6XX_PROTECT_NORDWR(0x0b604, 0x0000),
+	A6XX_PROTECT_NORDWR(0x0b608, 0x0007),
+	A6XX_PROTECT_NORDWR(0x0be02, 0x0001),
+	A6XX_PROTECT_NORDWR(0x0be20, 0x17df),
+	A6XX_PROTECT_NORDWR(0x0f000, 0x0bff),
+	A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x18400, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x1a800, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x1f400, 0x0443),
+	A6XX_PROTECT_RDONLY(0x1f844, 0x007b),
+	A6XX_PROTECT_NORDWR(0x1f887, 0x001b),
+	A6XX_PROTECT_NORDWR(0x1f8c0, 0x0000), /* note: infinite range */
+};
+DECLARE_ADRENO_PROTECT(a650_protect, 48);
+
+/* These are for a635 and a660 */
+static const u32 a660_protect_regs[] = {
+	A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
+	A6XX_PROTECT_RDONLY(0x00501, 0x0005),
+	A6XX_PROTECT_RDONLY(0x0050b, 0x02f4),
+	A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00510, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00534, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00800, 0x0082),
+	A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
+	A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
+	A6XX_PROTECT_RDONLY(0x008de, 0x00ae),
+	A6XX_PROTECT_NORDWR(0x00900, 0x004d),
+	A6XX_PROTECT_NORDWR(0x0098d, 0x0272),
+	A6XX_PROTECT_NORDWR(0x00e00, 0x0001),
+	A6XX_PROTECT_NORDWR(0x00e03, 0x000c),
+	A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
+	A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
+	A6XX_PROTECT_NORDWR(0x08e80, 0x027f),
+	A6XX_PROTECT_NORDWR(0x09624, 0x01db),
+	A6XX_PROTECT_NORDWR(0x09e60, 0x0011),
+	A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
+	A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
+	A6XX_PROTECT_NORDWR(0x0ae50, 0x012f),
+	A6XX_PROTECT_NORDWR(0x0b604, 0x0000),
+	A6XX_PROTECT_NORDWR(0x0b608, 0x0006),
+	A6XX_PROTECT_NORDWR(0x0be02, 0x0001),
+	A6XX_PROTECT_NORDWR(0x0be20, 0x015f),
+	A6XX_PROTECT_NORDWR(0x0d000, 0x05ff),
+	A6XX_PROTECT_NORDWR(0x0f000, 0x0bff),
+	A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x18400, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x1a400, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x1f400, 0x0443),
+	A6XX_PROTECT_RDONLY(0x1f844, 0x007b),
+	A6XX_PROTECT_NORDWR(0x1f860, 0x0000),
+	A6XX_PROTECT_NORDWR(0x1f887, 0x001b),
+	A6XX_PROTECT_NORDWR(0x1f8c0, 0x0000), /* note: infinite range */
+};
+DECLARE_ADRENO_PROTECT(a660_protect, 48);
+
+/* These are for a690 */
+static const u32 a690_protect_regs[] = {
+	A6XX_PROTECT_RDONLY(0x00000, 0x004ff),
+	A6XX_PROTECT_RDONLY(0x00501, 0x00001),
+	A6XX_PROTECT_RDONLY(0x0050b, 0x002f4),
+	A6XX_PROTECT_NORDWR(0x0050e, 0x00000),
+	A6XX_PROTECT_NORDWR(0x00510, 0x00000),
+	A6XX_PROTECT_NORDWR(0x00534, 0x00000),
+	A6XX_PROTECT_NORDWR(0x00800, 0x00082),
+	A6XX_PROTECT_NORDWR(0x008a0, 0x00008),
+	A6XX_PROTECT_NORDWR(0x008ab, 0x00024),
+	A6XX_PROTECT_RDONLY(0x008de, 0x000ae),
+	A6XX_PROTECT_NORDWR(0x00900, 0x0004d),
+	A6XX_PROTECT_NORDWR(0x0098d, 0x00272),
+	A6XX_PROTECT_NORDWR(0x00e00, 0x00001),
+	A6XX_PROTECT_NORDWR(0x00e03, 0x0000c),
+	A6XX_PROTECT_NORDWR(0x03c00, 0x000c3),
+	A6XX_PROTECT_RDONLY(0x03cc4, 0x01fff),
+	A6XX_PROTECT_NORDWR(0x08630, 0x001cf),
+	A6XX_PROTECT_NORDWR(0x08e00, 0x00000),
+	A6XX_PROTECT_NORDWR(0x08e08, 0x00007),
+	A6XX_PROTECT_NORDWR(0x08e50, 0x0001f),
+	A6XX_PROTECT_NORDWR(0x08e80, 0x0027f),
+	A6XX_PROTECT_NORDWR(0x09624, 0x001db),
+	A6XX_PROTECT_NORDWR(0x09e60, 0x00011),
+	A6XX_PROTECT_NORDWR(0x09e78, 0x00187),
+	A6XX_PROTECT_NORDWR(0x0a630, 0x001cf),
+	A6XX_PROTECT_NORDWR(0x0ae02, 0x00000),
+	A6XX_PROTECT_NORDWR(0x0ae50, 0x0012f),
+	A6XX_PROTECT_NORDWR(0x0b604, 0x00000),
+	A6XX_PROTECT_NORDWR(0x0b608, 0x00006),
+	A6XX_PROTECT_NORDWR(0x0be02, 0x00001),
+	A6XX_PROTECT_NORDWR(0x0be20, 0x0015f),
+	A6XX_PROTECT_NORDWR(0x0d000, 0x005ff),
+	A6XX_PROTECT_NORDWR(0x0f000, 0x00bff),
+	A6XX_PROTECT_RDONLY(0x0fc00, 0x01fff),
+	A6XX_PROTECT_NORDWR(0x11c00, 0x00000), /*note: infiite range */
+};
+DECLARE_ADRENO_PROTECT(a690_protect, 48);
+
+static const struct adreno_info a6xx_gpus[] = {
+	{
+		.chip_ids = ADRENO_CHIP_IDS(0x06010000),
+		.family = ADRENO_6XX_GEN1,
+		.revn = 610,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+		},
+		.gmem = (SZ_128K + SZ_4K),
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init = a6xx_gpu_init,
+		.zapfw = "a610_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a612_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00020202,
+			.prim_fifo_threshold = 0x00080000,
+		},
+		/*
+		 * There are (at least) three SoCs implementing A610: SM6125
+		 * (trinket), SM6115 (bengal) and SM6225 (khaje). Trinket does
+		 * not have speedbinning, as only a single SKU exists and we
+		 * don't support khaje upstream yet.  Hence, this matching
+		 * table is only valid for bengal.
+		 */
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 206, 1 },
+			{ 200, 2 },
+			{ 157, 3 },
+			{ 127, 4 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06010500),
+		.family = ADRENO_6XX_GEN1,
+		.revn = 615,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a630_gmu.bin",
+		},
+		.gmem = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init = a6xx_gpu_init,
+		.zapfw = "a615_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a615_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00000222,
+			.prim_fifo_threshold = 0x0018000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			/*
+			 * The default speed bin (0) has the same values as
+			 * speed bin 90 which goes up to 432 MHz.
+			 */
+			{ 0,   0 },
+			{ 90,  0 },
+			{ 105, 1 },
+			{ 146, 2 },
+			{ 163, 3 },
+		),
+	}, {
+		.machine = "qcom,sm7150",
+		.chip_ids = ADRENO_CHIP_IDS(0x06010800),
+		.family = ADRENO_6XX_GEN1,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a630_gmu.bin",
+		},
+		.gmem = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
+		.init = a6xx_gpu_init,
+		.zapfw = "a615_zap.mbn",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a615_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00000222,
+			.prim_fifo_threshold = 0x00180000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 128, 1 },
+			{ 146, 2 },
+			{ 167, 3 },
+			{ 172, 4 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06010800),
+		.family = ADRENO_6XX_GEN1,
+		.revn = 618,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a630_gmu.bin",
+		},
+		.gmem = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
+		.init = a6xx_gpu_init,
+		.a6xx = &(const struct a6xx_info) {
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00000222,
+			.prim_fifo_threshold = 0x00180000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 169, 1 },
+			{ 174, 2 },
+		),
+	}, {
+		.machine = "qcom,sm4350",
+		.chip_ids = ADRENO_CHIP_IDS(0x06010900),
+		.family = ADRENO_6XX_GEN1,
+		.revn = 619,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a619_gmu.bin",
+		},
+		.gmem = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init = a6xx_gpu_init,
+		.zapfw = "a615_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a615_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00000222,
+			.prim_fifo_threshold = 0x00018000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 138, 1 },
+			{ 92,  2 },
+		),
+	}, {
+		.machine = "qcom,sm6375",
+		.chip_ids = ADRENO_CHIP_IDS(0x06010901),
+		.family = ADRENO_6XX_GEN1,
+		.revn = 619,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a619_gmu.bin",
+		},
+		.gmem = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.init = a6xx_gpu_init,
+		.zapfw = "a615_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a615_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00000222,
+			.prim_fifo_threshold = 0x00018000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 190, 1 },
+			{ 177, 2 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06010900),
+		.family = ADRENO_6XX_GEN1,
+		.revn = 619,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a619_gmu.bin",
+		},
+		.gmem = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
+		.init = a6xx_gpu_init,
+		.zapfw = "a615_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a615_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00000222,
+			.prim_fifo_threshold = 0x00018000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 120, 4 },
+			{ 138, 3 },
+			{ 169, 2 },
+			{ 180, 1 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(
+			0x06030001,
+			0x06030002
+		),
+		.family = ADRENO_6XX_GEN1,
+		.revn = 630,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a630_gmu.bin",
+		},
+		.gmem = SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
+		.init = a6xx_gpu_init,
+		.zapfw = "a630_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a630_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00020202,
+			.prim_fifo_threshold = 0x00180000,
+		},
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06040001),
+		.family = ADRENO_6XX_GEN2,
+		.revn = 640,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a640_gmu.bin",
+		},
+		.gmem = SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
+		.init = a6xx_gpu_init,
+		.zapfw = "a640_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a640_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00020202,
+			.prim_fifo_threshold = 0x00180000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0, 0 },
+			{ 1, 1 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06050002),
+		.family = ADRENO_6XX_GEN3,
+		.revn = 650,
+		.fw = {
+			[ADRENO_FW_SQE] = "a650_sqe.fw",
+			[ADRENO_FW_GMU] = "a650_gmu.bin",
+		},
+		.gmem = SZ_1M + SZ_128K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a650_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a650_hwcg,
+			.protect = &a650_protect,
+			.gmu_cgc_mode = 0x00020202,
+			.prim_fifo_threshold = 0x00300200,
+		},
+		.address_space_size = SZ_16G,
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0, 0 },
+			{ 1, 1 },
+			{ 2, 3 }, /* Yep, 2 and 3 are swapped! :/ */
+			{ 3, 2 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06060001),
+		.family = ADRENO_6XX_GEN4,
+		.revn = 660,
+		.fw = {
+			[ADRENO_FW_SQE] = "a660_sqe.fw",
+			[ADRENO_FW_GMU] = "a660_gmu.bin",
+		},
+		.gmem = SZ_1M + SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a660_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a660_hwcg,
+			.protect = &a660_protect,
+			.gmu_cgc_mode = 0x00020000,
+			.prim_fifo_threshold = 0x00300200,
+		},
+		.address_space_size = SZ_16G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06060300),
+		.family = ADRENO_6XX_GEN4,
+		.fw = {
+			[ADRENO_FW_SQE] = "a660_sqe.fw",
+			[ADRENO_FW_GMU] = "a663_gmu.bin",
+		},
+		.gmem = SZ_1M + SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a690_hwcg,
+			.protect = &a660_protect,
+			.gmu_cgc_mode = 0x00020200,
+			.prim_fifo_threshold = 0x00300200,
+		},
+		.address_space_size = SZ_16G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06030500),
+		.family = ADRENO_6XX_GEN4,
+		.fw = {
+			[ADRENO_FW_SQE] = "a660_sqe.fw",
+			[ADRENO_FW_GMU] = "a660_gmu.bin",
+		},
+		.gmem = SZ_512K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a660_zap.mbn",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a660_hwcg,
+			.protect = &a660_protect,
+			.gmu_cgc_mode = 0x00020202,
+			.prim_fifo_threshold = 0x00200200,
+		},
+		.address_space_size = SZ_16G,
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 117, 0 },
+			{ 172, 2 }, /* Called speedbin 1 downstream, but let's not break things! */
+			{ 190, 1 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06080001),
+		.family = ADRENO_6XX_GEN2,
+		.revn = 680,
+		.fw = {
+			[ADRENO_FW_SQE] = "a630_sqe.fw",
+			[ADRENO_FW_GMU] = "a640_gmu.bin",
+		},
+		.gmem = SZ_2M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT,
+		.init = a6xx_gpu_init,
+		.zapfw = "a640_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a640_hwcg,
+			.protect = &a630_protect,
+			.gmu_cgc_mode = 0x00020202,
+			.prim_fifo_threshold = 0x00200200,
+		},
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x06090000),
+		.family = ADRENO_6XX_GEN4,
+		.fw = {
+			[ADRENO_FW_SQE] = "a660_sqe.fw",
+			[ADRENO_FW_GMU] = "a660_gmu.bin",
+		},
+		.gmem = SZ_4M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a690_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a690_hwcg,
+			.protect = &a690_protect,
+			.gmu_cgc_mode = 0x00020200,
+			.prim_fifo_threshold = 0x00800200,
+		},
+		.address_space_size = SZ_16G,
+	}
+};
+DECLARE_ADRENO_GPULIST(a6xx);
+
+MODULE_FIRMWARE("qcom/a615_zap.mbn");
+MODULE_FIRMWARE("qcom/a619_gmu.bin");
+MODULE_FIRMWARE("qcom/a630_sqe.fw");
+MODULE_FIRMWARE("qcom/a630_gmu.bin");
+MODULE_FIRMWARE("qcom/a630_zap.mbn");
+MODULE_FIRMWARE("qcom/a640_gmu.bin");
+MODULE_FIRMWARE("qcom/a650_gmu.bin");
+MODULE_FIRMWARE("qcom/a650_sqe.fw");
+MODULE_FIRMWARE("qcom/a660_gmu.bin");
+MODULE_FIRMWARE("qcom/a660_sqe.fw");
+
+static const struct adreno_reglist a702_hwcg[] = {
+	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02222220 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000081 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00022222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01202222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x00040f00 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x05522022 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00005555 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00445044 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002 },
+	{ REG_A6XX_RBBM_ISDB_CNT, 0x00000182 },
+	{ REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_FCHE, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_FCHE, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_FCHE, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_GLC, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GLC, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GLC, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_MHUB, 0x00000002 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_MHUB, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_MHUB, 0x00000000 },
+	{}
+};
+
+static const struct adreno_reglist a730_hwcg[] = {
+	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x02022222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x0000f3cf },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222220 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000004 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000002 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x44000f00 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00555555 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00440044 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE2_GRAS, 0x00000222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_GRAS, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222223 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00002222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_GPC, 0x00222222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00004000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ_2, 0x00000002 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_LRZ, 0x55555552 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_CP, 0x00000223 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL, 0x8aa8aa82 },
+	{ REG_A6XX_RBBM_ISDB_CNT, 0x00000182 },
+	{ REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555 },
+	{},
+};
+
+static const struct adreno_reglist a740_hwcg[] = {
+	{ REG_A6XX_RBBM_CLOCK_CNTL_SP0, 0x02222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_SP0, 0x22022222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_SP0, 0x003cf3cf },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_SP0, 0x00000080 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TP0, 0x22222220 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL3_TP0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL4_TP0, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST2_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST3_TP0, 0x77777777 },
+	{ REG_A6XX_RBBM_CLOCK_HYST4_TP0, 0x00077777 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY2_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY3_TP0, 0x11111111 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY4_TP0, 0x00011111 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_UCHE, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_UCHE, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_UCHE, 0x00000444 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_UCHE, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RB0, 0x22222222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RB0, 0x01002222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_CCU0, 0x00002220 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RB_CCU0, 0x44000f00 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_RAC, 0x25222022 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL2_RAC, 0x00555555 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_RAC, 0x00000011 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_RAC, 0x00440044 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_TSE_RAS_RBBM, 0x04222222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE2_GRAS, 0x00000222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_GRAS, 0x00222222 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_GPC, 0x02222223 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_VFD, 0x00222222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_GPC, 0x00222222 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_VFD, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_TSE_RAS_RBBM, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GPC, 0x04104004 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_VFD, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_TSE_RAS_RBBM, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GPC, 0x00000200 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_VFD, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_MODE_HLSQ, 0x00002222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_HLSQ, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_HLSQ, 0x00000000 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_BV_LRZ, 0x55555552 },
+	{ REG_A7XX_RBBM_CLOCK_HYST2_VFD, 0x00000000 },
+	{ REG_A7XX_RBBM_CLOCK_MODE_CP, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL, 0x8aa8aa82 },
+	{ REG_A6XX_RBBM_ISDB_CNT, 0x00000182 },
+	{ REG_A6XX_RBBM_RAC_THRESHOLD_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_SP_HYST_CNT, 0x00000000 },
+	{ REG_A6XX_RBBM_CLOCK_CNTL_GMU_GX, 0x00000222 },
+	{ REG_A6XX_RBBM_CLOCK_DELAY_GMU_GX, 0x00000111 },
+	{ REG_A6XX_RBBM_CLOCK_HYST_GMU_GX, 0x00000555 },
+	{},
+};
+
+static const u32 a730_protect_regs[] = {
+	A6XX_PROTECT_RDONLY(0x00000, 0x04ff),
+	A6XX_PROTECT_RDONLY(0x0050b, 0x0058),
+	A6XX_PROTECT_NORDWR(0x0050e, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00510, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00534, 0x0000),
+	A6XX_PROTECT_RDONLY(0x005fb, 0x009d),
+	A6XX_PROTECT_NORDWR(0x00699, 0x01e9),
+	A6XX_PROTECT_NORDWR(0x008a0, 0x0008),
+	A6XX_PROTECT_NORDWR(0x008ab, 0x0024),
+	/* 0x008d0-0x008dd and 0x008e0-0x008e6 are unprotected on purpose for tools like perfetto */
+	A6XX_PROTECT_NORDWR(0x008de, 0x0001),
+	A6XX_PROTECT_RDONLY(0x008e7, 0x014b),
+	A6XX_PROTECT_NORDWR(0x00900, 0x004d),
+	A6XX_PROTECT_NORDWR(0x0098d, 0x00b2),
+	A6XX_PROTECT_NORDWR(0x00a41, 0x01be),
+	A6XX_PROTECT_NORDWR(0x00df0, 0x0001),
+	A6XX_PROTECT_NORDWR(0x00e01, 0x0000),
+	A6XX_PROTECT_NORDWR(0x00e07, 0x0008),
+	A6XX_PROTECT_NORDWR(0x03c00, 0x00c3),
+	A6XX_PROTECT_RDONLY(0x03cc4, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x08630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x08e00, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e08, 0x0000),
+	A6XX_PROTECT_NORDWR(0x08e50, 0x001f),
+	A6XX_PROTECT_NORDWR(0x08e80, 0x0280),
+	A6XX_PROTECT_NORDWR(0x09624, 0x01db),
+	A6XX_PROTECT_NORDWR(0x09e40, 0x0000),
+	A6XX_PROTECT_NORDWR(0x09e64, 0x000d),
+	A6XX_PROTECT_NORDWR(0x09e78, 0x0187),
+	A6XX_PROTECT_NORDWR(0x0a630, 0x01cf),
+	A6XX_PROTECT_NORDWR(0x0ae02, 0x0000),
+	A6XX_PROTECT_NORDWR(0x0ae50, 0x000f),
+	A6XX_PROTECT_NORDWR(0x0ae66, 0x0003),
+	A6XX_PROTECT_NORDWR(0x0ae6f, 0x0003),
+	A6XX_PROTECT_NORDWR(0x0b604, 0x0003),
+	A6XX_PROTECT_NORDWR(0x0ec00, 0x0fff),
+	A6XX_PROTECT_RDONLY(0x0fc00, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x18400, 0x0053),
+	A6XX_PROTECT_RDONLY(0x18454, 0x0004),
+	A6XX_PROTECT_NORDWR(0x18459, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x1a459, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x1c459, 0x1fff),
+	A6XX_PROTECT_NORDWR(0x1f400, 0x0443),
+	A6XX_PROTECT_RDONLY(0x1f844, 0x007b),
+	A6XX_PROTECT_NORDWR(0x1f860, 0x0000),
+	A6XX_PROTECT_NORDWR(0x1f878, 0x002a),
+	/* CP_PROTECT_REG[45, 46] are left untouched! */
+	0,
+	0,
+	A6XX_PROTECT_NORDWR(0x1f8c0, 0x00000),
+};
+DECLARE_ADRENO_PROTECT(a730_protect, 48);
+
+static const struct adreno_info a7xx_gpus[] = {
+	{
+		.chip_ids = ADRENO_CHIP_IDS(0x07000200),
+		.family = ADRENO_6XX_GEN1, /* NOT a mistake! */
+		.fw = {
+			[ADRENO_FW_SQE] = "a702_sqe.fw",
+		},
+		.gmem = SZ_128K,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a702_zap.mbn",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a702_hwcg,
+			.protect = &a650_protect,
+			.gmu_cgc_mode = 0x00020202,
+			.prim_fifo_threshold = 0x0000c000,
+		},
+		.speedbins = ADRENO_SPEEDBINS(
+			{ 0,   0 },
+			{ 236, 1 },
+			{ 178, 2 },
+			{ 142, 3 },
+		),
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x07030001),
+		.family = ADRENO_7XX_GEN1,
+		.fw = {
+			[ADRENO_FW_SQE] = "a730_sqe.fw",
+			[ADRENO_FW_GMU] = "gmu_gen70000.bin",
+		},
+		.gmem = SZ_2M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			  ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a730_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a730_hwcg,
+			.protect = &a730_protect,
+			.gmu_cgc_mode = 0x00020000,
+		},
+		.address_space_size = SZ_16G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x43050a01), /* "C510v2" */
+		.family = ADRENO_7XX_GEN2,
+		.fw = {
+			[ADRENO_FW_SQE] = "a740_sqe.fw",
+			[ADRENO_FW_GMU] = "gmu_gen70200.bin",
+		},
+		.gmem = 3 * SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			  ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "a740_zap.mdt",
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a740_hwcg,
+			.protect = &a730_protect,
+			.gmu_chipid = 0x7020100,
+			.gmu_cgc_mode = 0x00020202,
+		},
+		.address_space_size = SZ_16G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x43050c01), /* "C512v2" */
+		.family = ADRENO_7XX_GEN2,
+		.fw = {
+			[ADRENO_FW_SQE] = "gen70500_sqe.fw",
+			[ADRENO_FW_GMU] = "gen70500_gmu.bin",
+		},
+		.gmem = 3 * SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			  ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.a6xx = &(const struct a6xx_info) {
+			.hwcg = a740_hwcg,
+			.protect = &a730_protect,
+			.gmu_chipid = 0x7050001,
+			.gmu_cgc_mode = 0x00020202,
+		},
+		.address_space_size = SZ_256G,
+	}, {
+		.chip_ids = ADRENO_CHIP_IDS(0x43051401), /* "C520v2" */
+		.family = ADRENO_7XX_GEN3,
+		.fw = {
+			[ADRENO_FW_SQE] = "gen70900_sqe.fw",
+			[ADRENO_FW_GMU] = "gmu_gen70900.bin",
+		},
+		.gmem = 3 * SZ_1M,
+		.inactive_period = DRM_MSM_INACTIVE_PERIOD,
+		.quirks = ADRENO_QUIRK_HAS_CACHED_COHERENT |
+			  ADRENO_QUIRK_HAS_HW_APRIV,
+		.init = a6xx_gpu_init,
+		.zapfw = "gen70900_zap.mbn",
+		.a6xx = &(const struct a6xx_info) {
+			.protect = &a730_protect,
+			.gmu_chipid = 0x7090100,
+			.gmu_cgc_mode = 0x00020202,
+		},
+		.address_space_size = SZ_16G,
+	}
+};
+DECLARE_ADRENO_GPULIST(a7xx);
+
+static inline void __build_asserts(void)
+{
+	BUILD_BUG_ON(a630_protect.count > a630_protect.count_max);
+	BUILD_BUG_ON(a650_protect.count > a650_protect.count_max);
+	BUILD_BUG_ON(a660_protect.count > a660_protect.count_max);
+	BUILD_BUG_ON(a690_protect.count > a690_protect.count_max);
+	BUILD_BUG_ON(a730_protect.count > a730_protect.count_max);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a6xx_gmu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a6xx_gmu.c
@@ -0,0 +1,1829 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/interconnect.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
+#include <soc/qcom/cmd-db.h>
+#include <drm/drm_gem.h>
+
+#include "a6xx_gpu.h"
+#include "a6xx_gmu.xml.h"
+#include "msm_gem.h"
+#include "msm_gpu_trace.h"
+#include "msm_mmu.h"
+
+static void a6xx_gmu_fault(struct a6xx_gmu *gmu)
+{
+	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	struct msm_gpu *gpu = &adreno_gpu->base;
+
+	/* FIXME: add a banner here */
+	gmu->hung = true;
+
+	/* Turn off the hangcheck timer while we are resetting */
+	del_timer(&gpu->hangcheck_timer);
+
+	/* Queue the GPU handler because we need to treat this as a recovery */
+	kthread_queue_work(gpu->worker, &gpu->recover_work);
+}
+
+static irqreturn_t a6xx_gmu_irq(int irq, void *data)
+{
+	struct a6xx_gmu *gmu = data;
+	u32 status;
+
+	status = gmu_read(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_STATUS);
+	gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_CLR, status);
+
+	if (status & A6XX_GMU_AO_HOST_INTERRUPT_STATUS_WDOG_BITE) {
+		dev_err_ratelimited(gmu->dev, "GMU watchdog expired\n");
+
+		a6xx_gmu_fault(gmu);
+	}
+
+	if (status &  A6XX_GMU_AO_HOST_INTERRUPT_STATUS_HOST_AHB_BUS_ERROR)
+		dev_err_ratelimited(gmu->dev, "GMU AHB bus error\n");
+
+	if (status & A6XX_GMU_AO_HOST_INTERRUPT_STATUS_FENCE_ERR)
+		dev_err_ratelimited(gmu->dev, "GMU fence error: 0x%x\n",
+			gmu_read(gmu, REG_A6XX_GMU_AHB_FENCE_STATUS));
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t a6xx_hfi_irq(int irq, void *data)
+{
+	struct a6xx_gmu *gmu = data;
+	u32 status;
+
+	status = gmu_read(gmu, REG_A6XX_GMU_GMU2HOST_INTR_INFO);
+	gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR, status);
+
+	if (status & A6XX_GMU_GMU2HOST_INTR_INFO_CM3_FAULT) {
+		dev_err_ratelimited(gmu->dev, "GMU firmware fault\n");
+
+		a6xx_gmu_fault(gmu);
+	}
+
+	return IRQ_HANDLED;
+}
+
+bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu)
+{
+	u32 val;
+
+	/* This can be called from gpu state code so make sure GMU is valid */
+	if (!gmu->initialized)
+		return false;
+
+	val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS);
+
+	return !(val &
+		(A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_SPTPRAC_GDSC_POWER_OFF |
+		A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_SP_CLOCK_OFF));
+}
+
+/* Check to see if the GX rail is still powered */
+bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu)
+{
+	u32 val;
+
+	/* This can be called from gpu state code so make sure GMU is valid */
+	if (!gmu->initialized)
+		return false;
+
+	val = gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS);
+
+	return !(val &
+		(A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_GDSC_POWER_OFF |
+		A6XX_GMU_SPTPRAC_PWR_CLK_STATUS_GX_HM_CLK_OFF));
+}
+
+void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp,
+		       bool suspended)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+	u32 perf_index;
+	unsigned long gpu_freq;
+	int ret = 0;
+
+	gpu_freq = dev_pm_opp_get_freq(opp);
+
+	if (gpu_freq == gmu->freq)
+		return;
+
+	for (perf_index = 0; perf_index < gmu->nr_gpu_freqs - 1; perf_index++)
+		if (gpu_freq == gmu->gpu_freqs[perf_index])
+			break;
+
+	gmu->current_perf_index = perf_index;
+	gmu->freq = gmu->gpu_freqs[perf_index];
+
+	trace_msm_gmu_freq_change(gmu->freq, perf_index);
+
+	/*
+	 * This can get called from devfreq while the hardware is idle. Don't
+	 * bring up the power if it isn't already active. All we're doing here
+	 * is updating the frequency so that when we come back online we're at
+	 * the right rate.
+	 */
+	if (suspended)
+		return;
+
+	if (!gmu->legacy) {
+		a6xx_hfi_set_freq(gmu, perf_index);
+		dev_pm_opp_set_opp(&gpu->pdev->dev, opp);
+		return;
+	}
+
+	gmu_write(gmu, REG_A6XX_GMU_DCVS_ACK_OPTION, 0);
+
+	gmu_write(gmu, REG_A6XX_GMU_DCVS_PERF_SETTING,
+			((3 & 0xf) << 28) | perf_index);
+
+	/*
+	 * Send an invalid index as a vote for the bus bandwidth and let the
+	 * firmware decide on the right vote
+	 */
+	gmu_write(gmu, REG_A6XX_GMU_DCVS_BW_SETTING, 0xff);
+
+	/* Set and clear the OOB for DCVS to trigger the GMU */
+	a6xx_gmu_set_oob(gmu, GMU_OOB_DCVS_SET);
+	a6xx_gmu_clear_oob(gmu, GMU_OOB_DCVS_SET);
+
+	ret = gmu_read(gmu, REG_A6XX_GMU_DCVS_RETURN);
+	if (ret)
+		dev_err(gmu->dev, "GMU set GPU frequency error: %d\n", ret);
+
+	dev_pm_opp_set_opp(&gpu->pdev->dev, opp);
+}
+
+unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+
+	return  gmu->freq;
+}
+
+static bool a6xx_gmu_check_idle_level(struct a6xx_gmu *gmu)
+{
+	u32 val;
+	int local = gmu->idle_level;
+
+	/* SPTP and IFPC both report as IFPC */
+	if (gmu->idle_level == GMU_IDLE_STATE_SPTP)
+		local = GMU_IDLE_STATE_IFPC;
+
+	val = gmu_read(gmu, REG_A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE);
+
+	if (val == local) {
+		if (gmu->idle_level != GMU_IDLE_STATE_IFPC ||
+			!a6xx_gmu_gx_is_on(gmu))
+			return true;
+	}
+
+	return false;
+}
+
+/* Wait for the GMU to get to its most idle state */
+int a6xx_gmu_wait_for_idle(struct a6xx_gmu *gmu)
+{
+	return spin_until(a6xx_gmu_check_idle_level(gmu));
+}
+
+static int a6xx_gmu_start(struct a6xx_gmu *gmu)
+{
+	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	u32 mask, reset_val, val;
+	int ret;
+
+	val = gmu_read(gmu, REG_A6XX_GMU_CM3_DTCM_START + 0xff8);
+	if (val <= 0x20010004) {
+		mask = 0xffffffff;
+		reset_val = 0xbabeface;
+	} else {
+		mask = 0x1ff;
+		reset_val = 0x100;
+	}
+
+	gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);
+
+	/* Set the log wptr index
+	 * note: downstream saves the value in poweroff and restores it here
+	 */
+	if (adreno_is_a7xx(adreno_gpu))
+		gmu_write(gmu, REG_A7XX_GMU_GENERAL_9, 0);
+	else
+		gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_RESP, 0);
+
+
+	gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 0);
+
+	ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, val,
+		(val & mask) == reset_val, 100, 10000);
+
+	if (ret)
+		DRM_DEV_ERROR(gmu->dev, "GMU firmware initialization timed out\n");
+
+	return ret;
+}
+
+static int a6xx_gmu_hfi_start(struct a6xx_gmu *gmu)
+{
+	u32 val;
+	int ret;
+
+	gmu_write(gmu, REG_A6XX_GMU_HFI_CTRL_INIT, 1);
+
+	ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_HFI_CTRL_STATUS, val,
+		val & 1, 100, 10000);
+	if (ret)
+		DRM_DEV_ERROR(gmu->dev, "Unable to start the HFI queues\n");
+
+	return ret;
+}
+
+struct a6xx_gmu_oob_bits {
+	int set, ack, set_new, ack_new, clear, clear_new;
+	const char *name;
+};
+
+/* These are the interrupt / ack bits for each OOB request that are set
+ * in a6xx_gmu_set_oob and a6xx_clear_oob
+ */
+static const struct a6xx_gmu_oob_bits a6xx_gmu_oob_bits[] = {
+	[GMU_OOB_GPU_SET] = {
+		.name = "GPU_SET",
+		.set = 16,
+		.ack = 24,
+		.set_new = 30,
+		.ack_new = 31,
+		.clear = 24,
+		.clear_new = 31,
+	},
+
+	[GMU_OOB_PERFCOUNTER_SET] = {
+		.name = "PERFCOUNTER",
+		.set = 17,
+		.ack = 25,
+		.set_new = 28,
+		.ack_new = 30,
+		.clear = 25,
+		.clear_new = 29,
+	},
+
+	[GMU_OOB_BOOT_SLUMBER] = {
+		.name = "BOOT_SLUMBER",
+		.set = 22,
+		.ack = 30,
+		.clear = 30,
+	},
+
+	[GMU_OOB_DCVS_SET] = {
+		.name = "GPU_DCVS",
+		.set = 23,
+		.ack = 31,
+		.clear = 31,
+	},
+};
+
+/* Trigger a OOB (out of band) request to the GMU */
+int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
+{
+	int ret;
+	u32 val;
+	int request, ack;
+
+	WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));
+
+	if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))
+		return -EINVAL;
+
+	if (gmu->legacy) {
+		request = a6xx_gmu_oob_bits[state].set;
+		ack = a6xx_gmu_oob_bits[state].ack;
+	} else {
+		request = a6xx_gmu_oob_bits[state].set_new;
+		ack = a6xx_gmu_oob_bits[state].ack_new;
+		if (!request || !ack) {
+			DRM_DEV_ERROR(gmu->dev,
+				      "Invalid non-legacy GMU request %s\n",
+				      a6xx_gmu_oob_bits[state].name);
+			return -EINVAL;
+		}
+	}
+
+	/* Trigger the equested OOB operation */
+	gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 1 << request);
+
+	/* Wait for the acknowledge interrupt */
+	ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_GMU2HOST_INTR_INFO, val,
+		val & (1 << ack), 100, 10000);
+
+	if (ret)
+		DRM_DEV_ERROR(gmu->dev,
+			"Timeout waiting for GMU OOB set %s: 0x%x\n",
+				a6xx_gmu_oob_bits[state].name,
+				gmu_read(gmu, REG_A6XX_GMU_GMU2HOST_INTR_INFO));
+
+	/* Clear the acknowledge interrupt */
+	gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR, 1 << ack);
+
+	return ret;
+}
+
+/* Clear a pending OOB state in the GMU */
+void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
+{
+	int bit;
+
+	WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));
+
+	if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))
+		return;
+
+	if (gmu->legacy)
+		bit = a6xx_gmu_oob_bits[state].clear;
+	else
+		bit = a6xx_gmu_oob_bits[state].clear_new;
+
+	gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 1 << bit);
+}
+
+/* Enable CPU control of SPTP power power collapse */
+int a6xx_sptprac_enable(struct a6xx_gmu *gmu)
+{
+	int ret;
+	u32 val;
+
+	if (!gmu->legacy)
+		return 0;
+
+	gmu_write(gmu, REG_A6XX_GMU_GX_SPTPRAC_POWER_CONTROL, 0x778000);
+
+	ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS, val,
+		(val & 0x38) == 0x28, 1, 100);
+
+	if (ret) {
+		DRM_DEV_ERROR(gmu->dev, "Unable to power on SPTPRAC: 0x%x\n",
+			gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS));
+	}
+
+	return 0;
+}
+
+/* Disable CPU control of SPTP power power collapse */
+void a6xx_sptprac_disable(struct a6xx_gmu *gmu)
+{
+	u32 val;
+	int ret;
+
+	if (!gmu->legacy)
+		return;
+
+	/* Make sure retention is on */
+	gmu_rmw(gmu, REG_A6XX_GPU_CC_GX_GDSCR, 0, (1 << 11));
+
+	gmu_write(gmu, REG_A6XX_GMU_GX_SPTPRAC_POWER_CONTROL, 0x778001);
+
+	ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS, val,
+		(val & 0x04), 100, 10000);
+
+	if (ret)
+		DRM_DEV_ERROR(gmu->dev, "failed to power off SPTPRAC: 0x%x\n",
+			gmu_read(gmu, REG_A6XX_GMU_SPTPRAC_PWR_CLK_STATUS));
+}
+
+/* Let the GMU know we are starting a boot sequence */
+static int a6xx_gmu_gfx_rail_on(struct a6xx_gmu *gmu)
+{
+	u32 vote;
+
+	/* Let the GMU know we are getting ready for boot */
+	gmu_write(gmu, REG_A6XX_GMU_BOOT_SLUMBER_OPTION, 0);
+
+	/* Choose the "default" power level as the highest available */
+	vote = gmu->gx_arc_votes[gmu->nr_gpu_freqs - 1];
+
+	gmu_write(gmu, REG_A6XX_GMU_GX_VOTE_IDX, vote & 0xff);
+	gmu_write(gmu, REG_A6XX_GMU_MX_VOTE_IDX, (vote >> 8) & 0xff);
+
+	/* Let the GMU know the boot sequence has started */
+	return a6xx_gmu_set_oob(gmu, GMU_OOB_BOOT_SLUMBER);
+}
+
+/* Let the GMU know that we are about to go into slumber */
+static int a6xx_gmu_notify_slumber(struct a6xx_gmu *gmu)
+{
+	int ret;
+
+	/* Disable the power counter so the GMU isn't busy */
+	gmu_write(gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE, 0);
+
+	/* Disable SPTP_PC if the CPU is responsible for it */
+	if (gmu->idle_level < GMU_IDLE_STATE_SPTP)
+		a6xx_sptprac_disable(gmu);
+
+	if (!gmu->legacy) {
+		ret = a6xx_hfi_send_prep_slumber(gmu);
+		goto out;
+	}
+
+	/* Tell the GMU to get ready to slumber */
+	gmu_write(gmu, REG_A6XX_GMU_BOOT_SLUMBER_OPTION, 1);
+
+	ret = a6xx_gmu_set_oob(gmu, GMU_OOB_BOOT_SLUMBER);
+	a6xx_gmu_clear_oob(gmu, GMU_OOB_BOOT_SLUMBER);
+
+	if (!ret) {
+		/* Check to see if the GMU really did slumber */
+		if (gmu_read(gmu, REG_A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE)
+			!= 0x0f) {
+			DRM_DEV_ERROR(gmu->dev, "The GMU did not go into slumber\n");
+			ret = -ETIMEDOUT;
+		}
+	}
+
+out:
+	/* Put fence into allow mode */
+	gmu_write(gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0);
+	return ret;
+}
+
+static int a6xx_rpmh_start(struct a6xx_gmu *gmu)
+{
+	int ret;
+	u32 val;
+
+	gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 1 << 1);
+	/* Wait for the register to finish posting */
+	wmb();
+
+	ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_RSCC_CONTROL_ACK, val,
+		val & (1 << 1), 100, 10000);
+	if (ret) {
+		DRM_DEV_ERROR(gmu->dev, "Unable to power on the GPU RSC\n");
+		return ret;
+	}
+
+	ret = gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_SEQ_BUSY_DRV0, val,
+		!val, 100, 10000);
+
+	if (ret) {
+		DRM_DEV_ERROR(gmu->dev, "GPU RSC sequence stuck while waking up the GPU\n");
+		return ret;
+	}
+
+	gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 0);
+
+	return 0;
+}
+
+static void a6xx_rpmh_stop(struct a6xx_gmu *gmu)
+{
+	int ret;
+	u32 val;
+
+	gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 1);
+
+	ret = gmu_poll_timeout_rscc(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0,
+		val, val & (1 << 16), 100, 10000);
+	if (ret)
+		DRM_DEV_ERROR(gmu->dev, "Unable to power off the GPU RSC\n");
+
+	gmu_write(gmu, REG_A6XX_GMU_RSCC_CONTROL_REQ, 0);
+}
+
+static inline void pdc_write(void __iomem *ptr, u32 offset, u32 value)
+{
+	msm_writel(value, ptr + (offset << 2));
+}
+
+static void __iomem *a6xx_gmu_get_mmio(struct platform_device *pdev,
+		const char *name);
+
+static void a6xx_gmu_rpmh_init(struct a6xx_gmu *gmu)
+{
+	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	struct platform_device *pdev = to_platform_device(gmu->dev);
+	void __iomem *pdcptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc");
+	u32 seqmem0_drv0_reg = REG_A6XX_RSCC_SEQ_MEM_0_DRV0;
+	void __iomem *seqptr = NULL;
+	uint32_t pdc_address_offset;
+	bool pdc_in_aop = false;
+
+	if (IS_ERR(pdcptr))
+		goto err;
+
+	if (adreno_is_a650(adreno_gpu) ||
+	    adreno_is_a660_family(adreno_gpu) ||
+	    adreno_is_a7xx(adreno_gpu))
+		pdc_in_aop = true;
+	else if (adreno_is_a618(adreno_gpu) || adreno_is_a640_family(adreno_gpu))
+		pdc_address_offset = 0x30090;
+	else if (adreno_is_a619(adreno_gpu))
+		pdc_address_offset = 0x300a0;
+	else
+		pdc_address_offset = 0x30080;
+
+	if (!pdc_in_aop) {
+		seqptr = a6xx_gmu_get_mmio(pdev, "gmu_pdc_seq");
+		if (IS_ERR(seqptr))
+			goto err;
+	}
+
+	/* Disable SDE clock gating */
+	gmu_write_rscc(gmu, REG_A6XX_GPU_RSCC_RSC_STATUS0_DRV0, BIT(24));
+
+	/* Setup RSC PDC handshake for sleep and wakeup */
+	gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_SLAVE_ID_DRV0, 1);
+	gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA, 0);
+	gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR, 0);
+	gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 2, 0);
+	gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 2, 0);
+	gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_DATA + 4,
+		       adreno_is_a740_family(adreno_gpu) ? 0x80000021 : 0x80000000);
+	gmu_write_rscc(gmu, REG_A6XX_RSCC_HIDDEN_TCS_CMD0_ADDR + 4, 0);
+	gmu_write_rscc(gmu, REG_A6XX_RSCC_OVERRIDE_START_ADDR, 0);
+	gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_SEQ_START_ADDR, 0x4520);
+	gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_LO, 0x4510);
+	gmu_write_rscc(gmu, REG_A6XX_RSCC_PDC_MATCH_VALUE_HI, 0x4514);
+
+	/* The second spin of A7xx GPUs messed with some register offsets.. */
+	if (adreno_is_a740_family(adreno_gpu))
+		seqmem0_drv0_reg = REG_A7XX_RSCC_SEQ_MEM_0_DRV0_A740;
+
+	/* Load RSC sequencer uCode for sleep and wakeup */
+	if (adreno_is_a650_family(adreno_gpu) ||
+	    adreno_is_a7xx(adreno_gpu)) {
+		gmu_write_rscc(gmu, seqmem0_drv0_reg, 0xeaaae5a0);
+		gmu_write_rscc(gmu, seqmem0_drv0_reg + 1, 0xe1a1ebab);
+		gmu_write_rscc(gmu, seqmem0_drv0_reg + 2, 0xa2e0a581);
+		gmu_write_rscc(gmu, seqmem0_drv0_reg + 3, 0xecac82e2);
+		gmu_write_rscc(gmu, seqmem0_drv0_reg + 4, 0x0020edad);
+	} else {
+		gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0, 0xa7a506a0);
+		gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 1, 0xa1e6a6e7);
+		gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 2, 0xa2e081e1);
+		gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 3, 0xe9a982e2);
+		gmu_write_rscc(gmu, REG_A6XX_RSCC_SEQ_MEM_0_DRV0 + 4, 0x0020e8a8);
+	}
+
+	if (pdc_in_aop)
+		goto setup_pdc;
+
+	/* Load PDC sequencer uCode for power up and power down sequence */
+	pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0, 0xfebea1e1);
+	pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 1, 0xa5a4a3a2);
+	pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 2, 0x8382a6e0);
+	pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 3, 0xbce3e284);
+	pdc_write(seqptr, REG_A6XX_PDC_GPU_SEQ_MEM_0 + 4, 0x002081fc);
+
+	/* Set TCS commands used by PDC sequence for low power modes */
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD_ENABLE_BANK, 7);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK, 0);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CONTROL, 0);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID, 0x10108);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR, 0x30010);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA, 1);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID + 4, 0x10108);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 4, 0x30000);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 4, 0x0);
+
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_MSGID + 8, 0x10108);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_ADDR + 8, pdc_address_offset);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS1_CMD0_DATA + 8, 0x0);
+
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD_ENABLE_BANK, 7);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD_WAIT_FOR_CMPL_BANK, 0);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CONTROL, 0);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID, 0x10108);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR, 0x30010);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA, 2);
+
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 4, 0x10108);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 4, 0x30000);
+	if (adreno_is_a618(adreno_gpu) || adreno_is_a619(adreno_gpu) ||
+			adreno_is_a650_family(adreno_gpu))
+		pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x2);
+	else
+		pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 4, 0x3);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_MSGID + 8, 0x10108);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_ADDR + 8, pdc_address_offset);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_TCS3_CMD0_DATA + 8, 0x3);
+
+	/* Setup GPU PDC */
+setup_pdc:
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_SEQ_START_ADDR, 0);
+	pdc_write(pdcptr, REG_A6XX_PDC_GPU_ENABLE_PDC, 0x80000001);
+
+	/* ensure no writes happen before the uCode is fully written */
+	wmb();
+
+	a6xx_rpmh_stop(gmu);
+
+err:
+	if (!IS_ERR_OR_NULL(pdcptr))
+		iounmap(pdcptr);
+	if (!IS_ERR_OR_NULL(seqptr))
+		iounmap(seqptr);
+}
+
+/*
+ * The lowest 16 bits of this value are the number of XO clock cycles for main
+ * hysteresis which is set at 0x1680 cycles (300 us).  The higher 16 bits are
+ * for the shorter hysteresis that happens after main - this is 0xa (.5 us)
+ */
+
+#define GMU_PWR_COL_HYST 0x000a1680
+
+/* Set up the idle state for the GMU */
+static void a6xx_gmu_power_config(struct a6xx_gmu *gmu)
+{
+	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+
+	/* Disable GMU WB/RB buffer */
+	gmu_write(gmu, REG_A6XX_GMU_SYS_BUS_CONFIG, 0x1);
+	gmu_write(gmu, REG_A6XX_GMU_ICACHE_CONFIG, 0x1);
+	gmu_write(gmu, REG_A6XX_GMU_DCACHE_CONFIG, 0x1);
+
+	/* A7xx knows better by default! */
+	if (adreno_is_a7xx(adreno_gpu))
+		return;
+
+	gmu_write(gmu, REG_A6XX_GMU_PWR_COL_INTER_FRAME_CTRL, 0x9c40400);
+
+	switch (gmu->idle_level) {
+	case GMU_IDLE_STATE_IFPC:
+		gmu_write(gmu, REG_A6XX_GMU_PWR_COL_INTER_FRAME_HYST,
+			GMU_PWR_COL_HYST);
+		gmu_rmw(gmu, REG_A6XX_GMU_PWR_COL_INTER_FRAME_CTRL, 0,
+			A6XX_GMU_PWR_COL_INTER_FRAME_CTRL_IFPC_ENABLE |
+			A6XX_GMU_PWR_COL_INTER_FRAME_CTRL_HM_POWER_COLLAPSE_ENABLE);
+		fallthrough;
+	case GMU_IDLE_STATE_SPTP:
+		gmu_write(gmu, REG_A6XX_GMU_PWR_COL_SPTPRAC_HYST,
+			GMU_PWR_COL_HYST);
+		gmu_rmw(gmu, REG_A6XX_GMU_PWR_COL_INTER_FRAME_CTRL, 0,
+			A6XX_GMU_PWR_COL_INTER_FRAME_CTRL_IFPC_ENABLE |
+			A6XX_GMU_PWR_COL_INTER_FRAME_CTRL_SPTPRAC_POWER_CONTROL_ENABLE);
+	}
+
+	/* Enable RPMh GPU client */
+	gmu_rmw(gmu, REG_A6XX_GMU_RPMH_CTRL, 0,
+		A6XX_GMU_RPMH_CTRL_RPMH_INTERFACE_ENABLE |
+		A6XX_GMU_RPMH_CTRL_LLC_VOTE_ENABLE |
+		A6XX_GMU_RPMH_CTRL_DDR_VOTE_ENABLE |
+		A6XX_GMU_RPMH_CTRL_MX_VOTE_ENABLE |
+		A6XX_GMU_RPMH_CTRL_CX_VOTE_ENABLE |
+		A6XX_GMU_RPMH_CTRL_GFX_VOTE_ENABLE);
+}
+
+struct block_header {
+	u32 addr;
+	u32 size;
+	u32 type;
+	u32 value;
+	u32 data[];
+};
+
+static bool fw_block_mem(struct a6xx_gmu_bo *bo, const struct block_header *blk)
+{
+	if (!in_range(blk->addr, bo->iova, bo->size))
+		return false;
+
+	memcpy(bo->virt + blk->addr - bo->iova, blk->data, blk->size);
+	return true;
+}
+
+static int a6xx_gmu_fw_load(struct a6xx_gmu *gmu)
+{
+	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	const struct firmware *fw_image = adreno_gpu->fw[ADRENO_FW_GMU];
+	const struct block_header *blk;
+	u32 reg_offset;
+
+	u32 itcm_base = 0x00000000;
+	u32 dtcm_base = 0x00040000;
+
+	if (adreno_is_a650_family(adreno_gpu) || adreno_is_a7xx(adreno_gpu))
+		dtcm_base = 0x10004000;
+
+	if (gmu->legacy) {
+		/* Sanity check the size of the firmware that was loaded */
+		if (fw_image->size > 0x8000) {
+			DRM_DEV_ERROR(gmu->dev,
+				"GMU firmware is bigger than the available region\n");
+			return -EINVAL;
+		}
+
+		gmu_write_bulk(gmu, REG_A6XX_GMU_CM3_ITCM_START,
+			       (u32*) fw_image->data, fw_image->size);
+		return 0;
+	}
+
+
+	for (blk = (const struct block_header *) fw_image->data;
+	     (const u8*) blk < fw_image->data + fw_image->size;
+	     blk = (const struct block_header *) &blk->data[blk->size >> 2]) {
+		if (blk->size == 0)
+			continue;
+
+		if (in_range(blk->addr, itcm_base, SZ_16K)) {
+			reg_offset = (blk->addr - itcm_base) >> 2;
+			gmu_write_bulk(gmu,
+				REG_A6XX_GMU_CM3_ITCM_START + reg_offset,
+				blk->data, blk->size);
+		} else if (in_range(blk->addr, dtcm_base, SZ_16K)) {
+			reg_offset = (blk->addr - dtcm_base) >> 2;
+			gmu_write_bulk(gmu,
+				REG_A6XX_GMU_CM3_DTCM_START + reg_offset,
+				blk->data, blk->size);
+		} else if (!fw_block_mem(&gmu->icache, blk) &&
+			   !fw_block_mem(&gmu->dcache, blk) &&
+			   !fw_block_mem(&gmu->dummy, blk)) {
+			DRM_DEV_ERROR(gmu->dev,
+				"failed to match fw block (addr=%.8x size=%d data[0]=%.8x)\n",
+				blk->addr, blk->size, blk->data[0]);
+		}
+	}
+
+	return 0;
+}
+
+static int a6xx_gmu_fw_start(struct a6xx_gmu *gmu, unsigned int state)
+{
+	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	const struct a6xx_info *a6xx_info = adreno_gpu->info->a6xx;
+	u32 fence_range_lower, fence_range_upper;
+	u32 chipid = 0;
+	int ret;
+
+	/* Vote veto for FAL10 */
+	if (adreno_is_a650_family(adreno_gpu) || adreno_is_a7xx(adreno_gpu)) {
+		gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_CX_FALNEXT_INTF, 1);
+		gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_CX_FAL_INTF, 1);
+	}
+
+	/* Turn on TCM (Tightly Coupled Memory) retention */
+	if (adreno_is_a7xx(adreno_gpu))
+		a6xx_llc_write(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL, 1);
+	else
+		gmu_write(gmu, REG_A6XX_GMU_GENERAL_7, 1);
+
+	if (state == GMU_WARM_BOOT) {
+		ret = a6xx_rpmh_start(gmu);
+		if (ret)
+			return ret;
+	} else {
+		if (WARN(!adreno_gpu->fw[ADRENO_FW_GMU],
+			"GMU firmware is not loaded\n"))
+			return -ENOENT;
+
+		ret = a6xx_rpmh_start(gmu);
+		if (ret)
+			return ret;
+
+		ret = a6xx_gmu_fw_load(gmu);
+		if (ret)
+			return ret;
+	}
+
+	/* Clear init result to make sure we are getting a fresh value */
+	gmu_write(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, 0);
+	gmu_write(gmu, REG_A6XX_GMU_CM3_BOOT_CONFIG, 0x02);
+
+	/* Write the iova of the HFI table */
+	gmu_write(gmu, REG_A6XX_GMU_HFI_QTBL_ADDR, gmu->hfi.iova);
+	gmu_write(gmu, REG_A6XX_GMU_HFI_QTBL_INFO, 1);
+
+	if (adreno_is_a7xx(adreno_gpu)) {
+		fence_range_upper = 0x32;
+		fence_range_lower = 0x8a0;
+	} else {
+		fence_range_upper = 0xa;
+		fence_range_lower = 0xa0;
+	}
+
+	gmu_write(gmu, REG_A6XX_GMU_AHB_FENCE_RANGE_0,
+		  BIT(31) |
+		  FIELD_PREP(GENMASK(30, 18), fence_range_upper) |
+		  FIELD_PREP(GENMASK(17, 0), fence_range_lower));
+
+	/*
+	 * Snapshots toggle the NMI bit which will result in a jump to the NMI
+	 * handler instead of __main. Set the M3 config value to avoid that.
+	 */
+	gmu_write(gmu, REG_A6XX_GMU_CM3_CFG, 0x4052);
+
+	if (a6xx_info->gmu_chipid) {
+		chipid = a6xx_info->gmu_chipid;
+	} else {
+		/*
+		 * Note that the GMU has a slightly different layout for
+		 * chip_id, for whatever reason, so a bit of massaging
+		 * is needed.  The upper 16b are the same, but minor and
+		 * patchid are packed in four bits each with the lower
+		 * 8b unused:
+		 */
+		chipid  = adreno_gpu->chip_id & 0xffff0000;
+		chipid |= (adreno_gpu->chip_id << 4) & 0xf000; /* minor */
+		chipid |= (adreno_gpu->chip_id << 8) & 0x0f00; /* patchid */
+	}
+
+	if (adreno_is_a7xx(adreno_gpu)) {
+		gmu_write(gmu, REG_A7XX_GMU_GENERAL_10, chipid);
+		gmu_write(gmu, REG_A7XX_GMU_GENERAL_8,
+			  (gmu->log.iova & GENMASK(31, 12)) |
+			  ((gmu->log.size / SZ_4K - 1) & GENMASK(7, 0)));
+	} else {
+		gmu_write(gmu, REG_A6XX_GMU_HFI_SFR_ADDR, chipid);
+
+		gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_PWR_COL_CP_MSG,
+			  gmu->log.iova | (gmu->log.size / SZ_4K - 1));
+	}
+
+	/* Set up the lowest idle level on the GMU */
+	a6xx_gmu_power_config(gmu);
+
+	ret = a6xx_gmu_start(gmu);
+	if (ret)
+		return ret;
+
+	if (gmu->legacy) {
+		ret = a6xx_gmu_gfx_rail_on(gmu);
+		if (ret)
+			return ret;
+	}
+
+	/* Enable SPTP_PC if the CPU is responsible for it */
+	if (gmu->idle_level < GMU_IDLE_STATE_SPTP) {
+		ret = a6xx_sptprac_enable(gmu);
+		if (ret)
+			return ret;
+	}
+
+	ret = a6xx_gmu_hfi_start(gmu);
+	if (ret)
+		return ret;
+
+	/* FIXME: Do we need this wmb() here? */
+	wmb();
+
+	return 0;
+}
+
+#define A6XX_HFI_IRQ_MASK \
+	(A6XX_GMU_GMU2HOST_INTR_INFO_CM3_FAULT)
+
+#define A6XX_GMU_IRQ_MASK \
+	(A6XX_GMU_AO_HOST_INTERRUPT_STATUS_WDOG_BITE | \
+	 A6XX_GMU_AO_HOST_INTERRUPT_STATUS_HOST_AHB_BUS_ERROR | \
+	 A6XX_GMU_AO_HOST_INTERRUPT_STATUS_FENCE_ERR)
+
+static void a6xx_gmu_irq_disable(struct a6xx_gmu *gmu)
+{
+	disable_irq(gmu->gmu_irq);
+	disable_irq(gmu->hfi_irq);
+
+	gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_MASK, ~0);
+	gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_MASK, ~0);
+}
+
+static void a6xx_gmu_rpmh_off(struct a6xx_gmu *gmu)
+{
+	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	u32 val, seqmem_off = 0;
+
+	/* The second spin of A7xx GPUs messed with some register offsets.. */
+	if (adreno_is_a740_family(adreno_gpu))
+		seqmem_off = 4;
+
+	/* Make sure there are no outstanding RPMh votes */
+	gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS0_DRV0_STATUS + seqmem_off,
+		val, (val & 1), 100, 10000);
+	gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS1_DRV0_STATUS + seqmem_off,
+		val, (val & 1), 100, 10000);
+	gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS2_DRV0_STATUS + seqmem_off,
+		val, (val & 1), 100, 10000);
+	gmu_poll_timeout_rscc(gmu, REG_A6XX_RSCC_TCS3_DRV0_STATUS + seqmem_off,
+		val, (val & 1), 100, 1000);
+}
+
+/* Force the GMU off in case it isn't responsive */
+static void a6xx_gmu_force_off(struct a6xx_gmu *gmu)
+{
+	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	struct msm_gpu *gpu = &adreno_gpu->base;
+
+	/*
+	 * Turn off keep alive that might have been enabled by the hang
+	 * interrupt
+	 */
+	gmu_write(&a6xx_gpu->gmu, REG_A6XX_GMU_GMU_PWR_COL_KEEPALIVE, 0);
+
+	/* Flush all the queues */
+	a6xx_hfi_stop(gmu);
+
+	/* Stop the interrupts */
+	a6xx_gmu_irq_disable(gmu);
+
+	/* Force off SPTP in case the GMU is managing it */
+	a6xx_sptprac_disable(gmu);
+
+	/* Make sure there are no outstanding RPMh votes */
+	a6xx_gmu_rpmh_off(gmu);
+
+	/* Clear the WRITEDROPPED fields and put fence into allow mode */
+	gmu_write(gmu, REG_A6XX_GMU_AHB_FENCE_STATUS_CLR, 0x7);
+	gmu_write(gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0);
+
+	/* Make sure the above writes go through */
+	wmb();
+
+	/* Halt the gmu cm3 core */
+	gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);
+
+	a6xx_bus_clear_pending_transactions(adreno_gpu, true);
+
+	/* Reset GPU core blocks */
+	a6xx_gpu_sw_reset(gpu, true);
+}
+
+static void a6xx_gmu_set_initial_freq(struct msm_gpu *gpu, struct a6xx_gmu *gmu)
+{
+	struct dev_pm_opp *gpu_opp;
+	unsigned long gpu_freq = gmu->gpu_freqs[gmu->current_perf_index];
+
+	gpu_opp = dev_pm_opp_find_freq_exact(&gpu->pdev->dev, gpu_freq, true);
+	if (IS_ERR(gpu_opp))
+		return;
+
+	gmu->freq = 0; /* so a6xx_gmu_set_freq() doesn't exit early */
+	a6xx_gmu_set_freq(gpu, gpu_opp, false);
+	dev_pm_opp_put(gpu_opp);
+}
+
+static void a6xx_gmu_set_initial_bw(struct msm_gpu *gpu, struct a6xx_gmu *gmu)
+{
+	struct dev_pm_opp *gpu_opp;
+	unsigned long gpu_freq = gmu->gpu_freqs[gmu->current_perf_index];
+
+	gpu_opp = dev_pm_opp_find_freq_exact(&gpu->pdev->dev, gpu_freq, true);
+	if (IS_ERR(gpu_opp))
+		return;
+
+	dev_pm_opp_set_opp(&gpu->pdev->dev, gpu_opp);
+	dev_pm_opp_put(gpu_opp);
+}
+
+int a6xx_gmu_resume(struct a6xx_gpu *a6xx_gpu)
+{
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	struct msm_gpu *gpu = &adreno_gpu->base;
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+	int status, ret;
+
+	if (WARN(!gmu->initialized, "The GMU is not set up yet\n"))
+		return -EINVAL;
+
+	gmu->hung = false;
+
+	/* Notify AOSS about the ACD state (unimplemented for now => disable it) */
+	if (!IS_ERR(gmu->qmp)) {
+		ret = qmp_send(gmu->qmp, "{class: gpu, res: acd, val: %d}",
+			       0 /* Hardcode ACD to be disabled for now */);
+		if (ret)
+			dev_err(gmu->dev, "failed to send GPU ACD state\n");
+	}
+
+	/* Turn on the resources */
+	pm_runtime_get_sync(gmu->dev);
+
+	/*
+	 * "enable" the GX power domain which won't actually do anything but it
+	 * will make sure that the refcounting is correct in case we need to
+	 * bring down the GX after a GMU failure
+	 */
+	if (!IS_ERR_OR_NULL(gmu->gxpd))
+		pm_runtime_get_sync(gmu->gxpd);
+
+	/* Use a known rate to bring up the GMU */
+	clk_set_rate(gmu->core_clk, 200000000);
+	clk_set_rate(gmu->hub_clk, adreno_is_a740_family(adreno_gpu) ?
+		     200000000 : 150000000);
+	ret = clk_bulk_prepare_enable(gmu->nr_clocks, gmu->clocks);
+	if (ret) {
+		pm_runtime_put(gmu->gxpd);
+		pm_runtime_put(gmu->dev);
+		return ret;
+	}
+
+	/* Set the bus quota to a reasonable value for boot */
+	a6xx_gmu_set_initial_bw(gpu, gmu);
+
+	/* Enable the GMU interrupt */
+	gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_CLR, ~0);
+	gmu_write(gmu, REG_A6XX_GMU_AO_HOST_INTERRUPT_MASK, ~A6XX_GMU_IRQ_MASK);
+	enable_irq(gmu->gmu_irq);
+
+	/* Check to see if we are doing a cold or warm boot */
+	if (adreno_is_a7xx(adreno_gpu)) {
+		status = a6xx_llc_read(a6xx_gpu, REG_A7XX_CX_MISC_TCM_RET_CNTL) == 1 ?
+			GMU_WARM_BOOT : GMU_COLD_BOOT;
+	} else if (gmu->legacy) {
+		status = gmu_read(gmu, REG_A6XX_GMU_GENERAL_7) == 1 ?
+			GMU_WARM_BOOT : GMU_COLD_BOOT;
+	} else {
+		/*
+		 * Warm boot path does not work on newer A6xx GPUs
+		 * Presumably this is because icache/dcache regions must be restored
+		 */
+		status = GMU_COLD_BOOT;
+	}
+
+	ret = a6xx_gmu_fw_start(gmu, status);
+	if (ret)
+		goto out;
+
+	ret = a6xx_hfi_start(gmu, status);
+	if (ret)
+		goto out;
+
+	/*
+	 * Turn on the GMU firmware fault interrupt after we know the boot
+	 * sequence is successful
+	 */
+	gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR, ~0);
+	gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_MASK, ~A6XX_HFI_IRQ_MASK);
+	enable_irq(gmu->hfi_irq);
+
+	/* Set the GPU to the current freq */
+	a6xx_gmu_set_initial_freq(gpu, gmu);
+
+out:
+	/* On failure, shut down the GMU to leave it in a good state */
+	if (ret) {
+		disable_irq(gmu->gmu_irq);
+		a6xx_rpmh_stop(gmu);
+		pm_runtime_put(gmu->gxpd);
+		pm_runtime_put(gmu->dev);
+	}
+
+	return ret;
+}
+
+bool a6xx_gmu_isidle(struct a6xx_gmu *gmu)
+{
+	u32 reg;
+
+	if (!gmu->initialized)
+		return true;
+
+	reg = gmu_read(gmu, REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS);
+
+	if (reg &  A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS_GPUBUSYIGNAHB)
+		return false;
+
+	return true;
+}
+
+/* Gracefully try to shut down the GMU and by extension the GPU */
+static void a6xx_gmu_shutdown(struct a6xx_gmu *gmu)
+{
+	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	u32 val;
+
+	/*
+	 * The GMU may still be in slumber unless the GPU started so check and
+	 * skip putting it back into slumber if so
+	 */
+	val = gmu_read(gmu, REG_A6XX_GPU_GMU_CX_GMU_RPMH_POWER_STATE);
+
+	if (val != 0xf) {
+		int ret = a6xx_gmu_wait_for_idle(gmu);
+
+		/* If the GMU isn't responding assume it is hung */
+		if (ret) {
+			a6xx_gmu_force_off(gmu);
+			return;
+		}
+
+		a6xx_bus_clear_pending_transactions(adreno_gpu, a6xx_gpu->hung);
+
+		/* tell the GMU we want to slumber */
+		ret = a6xx_gmu_notify_slumber(gmu);
+		if (ret) {
+			a6xx_gmu_force_off(gmu);
+			return;
+		}
+
+		ret = gmu_poll_timeout(gmu,
+			REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS, val,
+			!(val & A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS_GPUBUSYIGNAHB),
+			100, 10000);
+
+		/*
+		 * Let the user know we failed to slumber but don't worry too
+		 * much because we are powering down anyway
+		 */
+
+		if (ret)
+			DRM_DEV_ERROR(gmu->dev,
+				"Unable to slumber GMU: status = 0%x/0%x\n",
+				gmu_read(gmu,
+					REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS),
+				gmu_read(gmu,
+					REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_STATUS2));
+	}
+
+	/* Turn off HFI */
+	a6xx_hfi_stop(gmu);
+
+	/* Stop the interrupts and mask the hardware */
+	a6xx_gmu_irq_disable(gmu);
+
+	/* Tell RPMh to power off the GPU */
+	a6xx_rpmh_stop(gmu);
+}
+
+
+int a6xx_gmu_stop(struct a6xx_gpu *a6xx_gpu)
+{
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+	struct msm_gpu *gpu = &a6xx_gpu->base.base;
+
+	if (!pm_runtime_active(gmu->dev))
+		return 0;
+
+	/*
+	 * Force the GMU off if we detected a hang, otherwise try to shut it
+	 * down gracefully
+	 */
+	if (gmu->hung)
+		a6xx_gmu_force_off(gmu);
+	else
+		a6xx_gmu_shutdown(gmu);
+
+	/* Remove the bus vote */
+	dev_pm_opp_set_opp(&gpu->pdev->dev, NULL);
+
+	/*
+	 * Make sure the GX domain is off before turning off the GMU (CX)
+	 * domain. Usually the GMU does this but only if the shutdown sequence
+	 * was successful
+	 */
+	if (!IS_ERR_OR_NULL(gmu->gxpd))
+		pm_runtime_put_sync(gmu->gxpd);
+
+	clk_bulk_disable_unprepare(gmu->nr_clocks, gmu->clocks);
+
+	pm_runtime_put_sync(gmu->dev);
+
+	return 0;
+}
+
+static void a6xx_gmu_memory_free(struct a6xx_gmu *gmu)
+{
+	msm_gem_kernel_put(gmu->hfi.obj, gmu->aspace);
+	msm_gem_kernel_put(gmu->debug.obj, gmu->aspace);
+	msm_gem_kernel_put(gmu->icache.obj, gmu->aspace);
+	msm_gem_kernel_put(gmu->dcache.obj, gmu->aspace);
+	msm_gem_kernel_put(gmu->dummy.obj, gmu->aspace);
+	msm_gem_kernel_put(gmu->log.obj, gmu->aspace);
+
+	gmu->aspace->mmu->funcs->detach(gmu->aspace->mmu);
+	msm_gem_address_space_put(gmu->aspace);
+}
+
+static int a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu, struct a6xx_gmu_bo *bo,
+		size_t size, u64 iova, const char *name)
+{
+	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+	struct drm_device *dev = a6xx_gpu->base.base.dev;
+	uint32_t flags = MSM_BO_WC;
+	u64 range_start, range_end;
+	int ret;
+
+	size = PAGE_ALIGN(size);
+	if (!iova) {
+		/* no fixed address - use GMU's uncached range */
+		range_start = 0x60000000 + PAGE_SIZE; /* skip dummy page */
+		range_end = 0x80000000;
+	} else {
+		/* range for fixed address */
+		range_start = iova;
+		range_end = iova + size;
+		/* use IOMMU_PRIV for icache/dcache */
+		flags |= MSM_BO_MAP_PRIV;
+	}
+
+	bo->obj = msm_gem_new(dev, size, flags);
+	if (IS_ERR(bo->obj))
+		return PTR_ERR(bo->obj);
+
+	ret = msm_gem_get_and_pin_iova_range(bo->obj, gmu->aspace, &bo->iova,
+					     range_start, range_end);
+	if (ret) {
+		drm_gem_object_put(bo->obj);
+		return ret;
+	}
+
+	bo->virt = msm_gem_get_vaddr(bo->obj);
+	bo->size = size;
+
+	msm_gem_object_set_name(bo->obj, name);
+
+	return 0;
+}
+
+static int a6xx_gmu_memory_probe(struct a6xx_gmu *gmu)
+{
+	struct msm_mmu *mmu;
+
+	mmu = msm_iommu_new(gmu->dev, 0);
+	if (!mmu)
+		return -ENODEV;
+	if (IS_ERR(mmu))
+		return PTR_ERR(mmu);
+
+	gmu->aspace = msm_gem_address_space_create(mmu, "gmu", 0x0, 0x80000000);
+	if (IS_ERR(gmu->aspace))
+		return PTR_ERR(gmu->aspace);
+
+	return 0;
+}
+
+/* Return the 'arc-level' for the given frequency */
+static unsigned int a6xx_gmu_get_arc_level(struct device *dev,
+					   unsigned long freq)
+{
+	struct dev_pm_opp *opp;
+	unsigned int val;
+
+	if (!freq)
+		return 0;
+
+	opp = dev_pm_opp_find_freq_exact(dev, freq, true);
+	if (IS_ERR(opp))
+		return 0;
+
+	val = dev_pm_opp_get_level(opp);
+
+	dev_pm_opp_put(opp);
+
+	return val;
+}
+
+static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes,
+		unsigned long *freqs, int freqs_count, const char *id)
+{
+	int i, j;
+	const u16 *pri, *sec;
+	size_t pri_count, sec_count;
+
+	pri = cmd_db_read_aux_data(id, &pri_count);
+	if (IS_ERR(pri))
+		return PTR_ERR(pri);
+	/*
+	 * The data comes back as an array of unsigned shorts so adjust the
+	 * count accordingly
+	 */
+	pri_count >>= 1;
+	if (!pri_count)
+		return -EINVAL;
+
+	/*
+	 * Some targets have a separate gfx mxc rail. So try to read that first and then fall back
+	 * to regular mx rail if it is missing
+	 */
+	sec = cmd_db_read_aux_data("gmxc.lvl", &sec_count);
+	if (IS_ERR(sec) && sec != ERR_PTR(-EPROBE_DEFER))
+		sec = cmd_db_read_aux_data("mx.lvl", &sec_count);
+	if (IS_ERR(sec))
+		return PTR_ERR(sec);
+
+	sec_count >>= 1;
+	if (!sec_count)
+		return -EINVAL;
+
+	/* Construct a vote for each frequency */
+	for (i = 0; i < freqs_count; i++) {
+		u8 pindex = 0, sindex = 0;
+		unsigned int level = a6xx_gmu_get_arc_level(dev, freqs[i]);
+
+		/* Get the primary index that matches the arc level */
+		for (j = 0; j < pri_count; j++) {
+			if (pri[j] >= level) {
+				pindex = j;
+				break;
+			}
+		}
+
+		if (j == pri_count) {
+			DRM_DEV_ERROR(dev,
+				      "Level %u not found in the RPMh list\n",
+				      level);
+			DRM_DEV_ERROR(dev, "Available levels:\n");
+			for (j = 0; j < pri_count; j++)
+				DRM_DEV_ERROR(dev, "  %u\n", pri[j]);
+
+			return -EINVAL;
+		}
+
+		/*
+		 * Look for a level in in the secondary list that matches. If
+		 * nothing fits, use the maximum non zero vote
+		 */
+
+		for (j = 0; j < sec_count; j++) {
+			if (sec[j] >= level) {
+				sindex = j;
+				break;
+			} else if (sec[j]) {
+				sindex = j;
+			}
+		}
+
+		/* Construct the vote */
+		votes[i] = ((pri[pindex] & 0xffff) << 16) |
+			(sindex << 8) | pindex;
+	}
+
+	return 0;
+}
+
+/*
+ * The GMU votes with the RPMh for itself and on behalf of the GPU but we need
+ * to construct the list of votes on the CPU and send it over. Query the RPMh
+ * voltage levels and build the votes
+ */
+
+static int a6xx_gmu_rpmh_votes_init(struct a6xx_gmu *gmu)
+{
+	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	struct msm_gpu *gpu = &adreno_gpu->base;
+	int ret;
+
+	/* Build the GX votes */
+	ret = a6xx_gmu_rpmh_arc_votes_init(&gpu->pdev->dev, gmu->gx_arc_votes,
+		gmu->gpu_freqs, gmu->nr_gpu_freqs, "gfx.lvl");
+
+	/* Build the CX votes */
+	ret |= a6xx_gmu_rpmh_arc_votes_init(gmu->dev, gmu->cx_arc_votes,
+		gmu->gmu_freqs, gmu->nr_gmu_freqs, "cx.lvl");
+
+	return ret;
+}
+
+static int a6xx_gmu_build_freq_table(struct device *dev, unsigned long *freqs,
+		u32 size)
+{
+	int count = dev_pm_opp_get_opp_count(dev);
+	struct dev_pm_opp *opp;
+	int i, index = 0;
+	unsigned long freq = 1;
+
+	/*
+	 * The OPP table doesn't contain the "off" frequency level so we need to
+	 * add 1 to the table size to account for it
+	 */
+
+	if (WARN(count + 1 > size,
+		"The GMU frequency table is being truncated\n"))
+		count = size - 1;
+
+	/* Set the "off" frequency */
+	freqs[index++] = 0;
+
+	for (i = 0; i < count; i++) {
+		opp = dev_pm_opp_find_freq_ceil(dev, &freq);
+		if (IS_ERR(opp))
+			break;
+
+		dev_pm_opp_put(opp);
+		freqs[index++] = freq++;
+	}
+
+	return index;
+}
+
+static int a6xx_gmu_pwrlevels_probe(struct a6xx_gmu *gmu)
+{
+	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	struct msm_gpu *gpu = &adreno_gpu->base;
+
+	int ret = 0;
+
+	/*
+	 * The GMU handles its own frequency switching so build a list of
+	 * available frequencies to send during initialization
+	 */
+	ret = devm_pm_opp_of_add_table(gmu->dev);
+	if (ret) {
+		DRM_DEV_ERROR(gmu->dev, "Unable to set the OPP table for the GMU\n");
+		return ret;
+	}
+
+	gmu->nr_gmu_freqs = a6xx_gmu_build_freq_table(gmu->dev,
+		gmu->gmu_freqs, ARRAY_SIZE(gmu->gmu_freqs));
+
+	/*
+	 * The GMU also handles GPU frequency switching so build a list
+	 * from the GPU OPP table
+	 */
+	gmu->nr_gpu_freqs = a6xx_gmu_build_freq_table(&gpu->pdev->dev,
+		gmu->gpu_freqs, ARRAY_SIZE(gmu->gpu_freqs));
+
+	gmu->current_perf_index = gmu->nr_gpu_freqs - 1;
+
+	/* Build the list of RPMh votes that we'll send to the GMU */
+	return a6xx_gmu_rpmh_votes_init(gmu);
+}
+
+static int a6xx_gmu_clocks_probe(struct a6xx_gmu *gmu)
+{
+	int ret = devm_clk_bulk_get_all(gmu->dev, &gmu->clocks);
+
+	if (ret < 1)
+		return ret;
+
+	gmu->nr_clocks = ret;
+
+	gmu->core_clk = msm_clk_bulk_get_clock(gmu->clocks,
+		gmu->nr_clocks, "gmu");
+
+	gmu->hub_clk = msm_clk_bulk_get_clock(gmu->clocks,
+		gmu->nr_clocks, "hub");
+
+	return 0;
+}
+
+static void __iomem *a6xx_gmu_get_mmio(struct platform_device *pdev,
+		const char *name)
+{
+	void __iomem *ret;
+	struct resource *res = platform_get_resource_byname(pdev,
+			IORESOURCE_MEM, name);
+
+	if (!res) {
+		DRM_DEV_ERROR(&pdev->dev, "Unable to find the %s registers\n", name);
+		return ERR_PTR(-EINVAL);
+	}
+
+	ret = ioremap(res->start, resource_size(res));
+	if (!ret) {
+		DRM_DEV_ERROR(&pdev->dev, "Unable to map the %s registers\n", name);
+		return ERR_PTR(-EINVAL);
+	}
+
+	return ret;
+}
+
+static int a6xx_gmu_get_irq(struct a6xx_gmu *gmu, struct platform_device *pdev,
+		const char *name, irq_handler_t handler)
+{
+	int irq, ret;
+
+	irq = platform_get_irq_byname(pdev, name);
+
+	ret = request_irq(irq, handler, IRQF_TRIGGER_HIGH, name, gmu);
+	if (ret) {
+		DRM_DEV_ERROR(&pdev->dev, "Unable to get interrupt %s %d\n",
+			      name, ret);
+		return ret;
+	}
+
+	disable_irq(irq);
+
+	return irq;
+}
+
+void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu)
+{
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+	struct platform_device *pdev = to_platform_device(gmu->dev);
+
+	mutex_lock(&gmu->lock);
+	if (!gmu->initialized) {
+		mutex_unlock(&gmu->lock);
+		return;
+	}
+
+	gmu->initialized = false;
+
+	mutex_unlock(&gmu->lock);
+
+	pm_runtime_force_suspend(gmu->dev);
+
+	/*
+	 * Since cxpd is a virt device, the devlink with gmu-dev will be removed
+	 * automatically when we do detach
+	 */
+	dev_pm_domain_detach(gmu->cxpd, false);
+
+	if (!IS_ERR_OR_NULL(gmu->gxpd)) {
+		pm_runtime_disable(gmu->gxpd);
+		dev_pm_domain_detach(gmu->gxpd, false);
+	}
+
+	if (!IS_ERR_OR_NULL(gmu->qmp))
+		qmp_put(gmu->qmp);
+
+	iounmap(gmu->mmio);
+	if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "rscc"))
+		iounmap(gmu->rscc);
+	gmu->mmio = NULL;
+	gmu->rscc = NULL;
+
+	if (!adreno_has_gmu_wrapper(adreno_gpu)) {
+		a6xx_gmu_memory_free(gmu);
+
+		free_irq(gmu->gmu_irq, gmu);
+		free_irq(gmu->hfi_irq, gmu);
+	}
+
+	/* Drop reference taken in of_find_device_by_node */
+	put_device(gmu->dev);
+}
+
+static int cxpd_notifier_cb(struct notifier_block *nb,
+			unsigned long action, void *data)
+{
+	struct a6xx_gmu *gmu = container_of(nb, struct a6xx_gmu, pd_nb);
+
+	if (action == GENPD_NOTIFY_OFF)
+		complete_all(&gmu->pd_gate);
+
+	return 0;
+}
+
+int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
+{
+	struct platform_device *pdev = of_find_device_by_node(node);
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+	int ret;
+
+	if (!pdev)
+		return -ENODEV;
+
+	gmu->dev = &pdev->dev;
+
+	of_dma_configure(gmu->dev, node, true);
+
+	pm_runtime_enable(gmu->dev);
+
+	/* Mark legacy for manual SPTPRAC control */
+	gmu->legacy = true;
+
+	/* Map the GMU registers */
+	gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu");
+	if (IS_ERR(gmu->mmio)) {
+		ret = PTR_ERR(gmu->mmio);
+		goto err_mmio;
+	}
+
+	gmu->cxpd = dev_pm_domain_attach_by_name(gmu->dev, "cx");
+	if (IS_ERR(gmu->cxpd)) {
+		ret = PTR_ERR(gmu->cxpd);
+		goto err_mmio;
+	}
+
+	if (!device_link_add(gmu->dev, gmu->cxpd, DL_FLAG_PM_RUNTIME)) {
+		ret = -ENODEV;
+		goto detach_cxpd;
+	}
+
+	init_completion(&gmu->pd_gate);
+	complete_all(&gmu->pd_gate);
+	gmu->pd_nb.notifier_call = cxpd_notifier_cb;
+
+	/* Get a link to the GX power domain to reset the GPU */
+	gmu->gxpd = dev_pm_domain_attach_by_name(gmu->dev, "gx");
+	if (IS_ERR(gmu->gxpd)) {
+		ret = PTR_ERR(gmu->gxpd);
+		goto err_mmio;
+	}
+
+	gmu->initialized = true;
+
+	return 0;
+
+detach_cxpd:
+	dev_pm_domain_detach(gmu->cxpd, false);
+
+err_mmio:
+	iounmap(gmu->mmio);
+
+	/* Drop reference taken in of_find_device_by_node */
+	put_device(gmu->dev);
+
+	return ret;
+}
+
+int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node)
+{
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+	struct platform_device *pdev = of_find_device_by_node(node);
+	struct device_link *link;
+	int ret;
+
+	if (!pdev)
+		return -ENODEV;
+
+	gmu->dev = &pdev->dev;
+
+	of_dma_configure(gmu->dev, node, true);
+
+	/* Fow now, don't do anything fancy until we get our feet under us */
+	gmu->idle_level = GMU_IDLE_STATE_ACTIVE;
+
+	pm_runtime_enable(gmu->dev);
+
+	/* Get the list of clocks */
+	ret = a6xx_gmu_clocks_probe(gmu);
+	if (ret)
+		goto err_put_device;
+
+	ret = a6xx_gmu_memory_probe(gmu);
+	if (ret)
+		goto err_put_device;
+
+
+	/* A660 now requires handling "prealloc requests" in GMU firmware
+	 * For now just hardcode allocations based on the known firmware.
+	 * note: there is no indication that these correspond to "dummy" or
+	 * "debug" regions, but this "guess" allows reusing these BOs which
+	 * are otherwise unused by a660.
+	 */
+	gmu->dummy.size = SZ_4K;
+	if (adreno_is_a660_family(adreno_gpu) ||
+	    adreno_is_a7xx(adreno_gpu)) {
+		ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_4K * 7,
+					    0x60400000, "debug");
+		if (ret)
+			goto err_memory;
+
+		gmu->dummy.size = SZ_8K;
+	}
+
+	/* Allocate memory for the GMU dummy page */
+	ret = a6xx_gmu_memory_alloc(gmu, &gmu->dummy, gmu->dummy.size,
+				    0x60000000, "dummy");
+	if (ret)
+		goto err_memory;
+
+	/* Note that a650 family also includes a660 family: */
+	if (adreno_is_a650_family(adreno_gpu) ||
+	    adreno_is_a7xx(adreno_gpu)) {
+		ret = a6xx_gmu_memory_alloc(gmu, &gmu->icache,
+			SZ_16M - SZ_16K, 0x04000, "icache");
+		if (ret)
+			goto err_memory;
+	/*
+	 * NOTE: when porting legacy ("pre-650-family") GPUs you may be tempted to add a condition
+	 * to allocate icache/dcache here, as per downstream code flow, but it may not actually be
+	 * necessary. If you omit this step and you don't get random pagefaults, you are likely
+	 * good to go without this!
+	 */
+	} else if (adreno_is_a640_family(adreno_gpu)) {
+		ret = a6xx_gmu_memory_alloc(gmu, &gmu->icache,
+			SZ_256K - SZ_16K, 0x04000, "icache");
+		if (ret)
+			goto err_memory;
+
+		ret = a6xx_gmu_memory_alloc(gmu, &gmu->dcache,
+			SZ_256K - SZ_16K, 0x44000, "dcache");
+		if (ret)
+			goto err_memory;
+	} else if (adreno_is_a630_family(adreno_gpu)) {
+		/* HFI v1, has sptprac */
+		gmu->legacy = true;
+
+		/* Allocate memory for the GMU debug region */
+		ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_16K, 0, "debug");
+		if (ret)
+			goto err_memory;
+	}
+
+	/* Allocate memory for the GMU log region */
+	ret = a6xx_gmu_memory_alloc(gmu, &gmu->log, SZ_16K, 0, "log");
+	if (ret)
+		goto err_memory;
+
+	/* Allocate memory for for the HFI queues */
+	ret = a6xx_gmu_memory_alloc(gmu, &gmu->hfi, SZ_16K, 0, "hfi");
+	if (ret)
+		goto err_memory;
+
+	/* Map the GMU registers */
+	gmu->mmio = a6xx_gmu_get_mmio(pdev, "gmu");
+	if (IS_ERR(gmu->mmio)) {
+		ret = PTR_ERR(gmu->mmio);
+		goto err_memory;
+	}
+
+	if (adreno_is_a650_family(adreno_gpu) ||
+	    adreno_is_a7xx(adreno_gpu)) {
+		gmu->rscc = a6xx_gmu_get_mmio(pdev, "rscc");
+		if (IS_ERR(gmu->rscc)) {
+			ret = -ENODEV;
+			goto err_mmio;
+		}
+	} else {
+		gmu->rscc = gmu->mmio + 0x23000;
+	}
+
+	/* Get the HFI and GMU interrupts */
+	gmu->hfi_irq = a6xx_gmu_get_irq(gmu, pdev, "hfi", a6xx_hfi_irq);
+	gmu->gmu_irq = a6xx_gmu_get_irq(gmu, pdev, "gmu", a6xx_gmu_irq);
+
+	if (gmu->hfi_irq < 0 || gmu->gmu_irq < 0) {
+		ret = -ENODEV;
+		goto err_mmio;
+	}
+
+	gmu->cxpd = dev_pm_domain_attach_by_name(gmu->dev, "cx");
+	if (IS_ERR(gmu->cxpd)) {
+		ret = PTR_ERR(gmu->cxpd);
+		goto err_mmio;
+	}
+
+	link = device_link_add(gmu->dev, gmu->cxpd, DL_FLAG_PM_RUNTIME);
+	if (!link) {
+		ret = -ENODEV;
+		goto detach_cxpd;
+	}
+
+	gmu->qmp = qmp_get(gmu->dev);
+	if (IS_ERR(gmu->qmp) && adreno_is_a7xx(adreno_gpu)) {
+		ret = PTR_ERR(gmu->qmp);
+		goto remove_device_link;
+	}
+
+	init_completion(&gmu->pd_gate);
+	complete_all(&gmu->pd_gate);
+	gmu->pd_nb.notifier_call = cxpd_notifier_cb;
+
+	/*
+	 * Get a link to the GX power domain to reset the GPU in case of GMU
+	 * crash
+	 */
+	gmu->gxpd = dev_pm_domain_attach_by_name(gmu->dev, "gx");
+
+	/* Get the power levels for the GMU and GPU */
+	a6xx_gmu_pwrlevels_probe(gmu);
+
+	/* Set up the HFI queues */
+	a6xx_hfi_init(gmu);
+
+	/* Initialize RPMh */
+	a6xx_gmu_rpmh_init(gmu);
+
+	gmu->initialized = true;
+
+	return 0;
+
+remove_device_link:
+	device_link_del(link);
+
+detach_cxpd:
+	dev_pm_domain_detach(gmu->cxpd, false);
+
+err_mmio:
+	iounmap(gmu->mmio);
+	if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "rscc"))
+		iounmap(gmu->rscc);
+	free_irq(gmu->gmu_irq, gmu);
+	free_irq(gmu->hfi_irq, gmu);
+
+err_memory:
+	a6xx_gmu_memory_free(gmu);
+err_put_device:
+	/* Drop reference taken in of_find_device_by_node */
+	put_device(gmu->dev);
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a6xx_gmu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a6xx_gmu.h
@@ -0,0 +1,202 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2017 The Linux Foundation. All rights reserved. */
+
+#ifndef _A6XX_GMU_H_
+#define _A6XX_GMU_H_
+
+#include <linux/completion.h>
+#include <linux/iopoll.h>
+#include <linux/interrupt.h>
+#include <linux/notifier.h>
+#include <linux/soc/qcom/qcom_aoss.h>
+#include "msm_drv.h"
+#include "a6xx_hfi.h"
+
+struct a6xx_gmu_bo {
+	struct drm_gem_object *obj;
+	void *virt;
+	size_t size;
+	u64 iova;
+};
+
+/*
+ * These define the different GMU wake up options - these define how both the
+ * CPU and the GMU bring up the hardware
+ */
+
+/* THe GMU has already been booted and the rentention registers are active */
+#define GMU_WARM_BOOT 0
+
+/* the GMU is coming up for the first time or back from a power collapse */
+#define GMU_COLD_BOOT 1
+
+/*
+ * These define the level of control that the GMU has - the higher the number
+ * the more things that the GMU hardware controls on its own.
+ */
+
+/* The GMU does not do any idle state management */
+#define GMU_IDLE_STATE_ACTIVE 0
+
+/* The GMU manages SPTP power collapse */
+#define GMU_IDLE_STATE_SPTP 2
+
+/* The GMU does automatic IFPC (intra-frame power collapse) */
+#define GMU_IDLE_STATE_IFPC 3
+
+struct a6xx_gmu {
+	struct device *dev;
+
+	/* For serializing communication with the GMU: */
+	struct mutex lock;
+
+	struct msm_gem_address_space *aspace;
+
+	void __iomem *mmio;
+	void __iomem *rscc;
+
+	int hfi_irq;
+	int gmu_irq;
+
+	struct device *gxpd;
+	struct device *cxpd;
+
+	int idle_level;
+
+	struct a6xx_gmu_bo hfi;
+	struct a6xx_gmu_bo debug;
+	struct a6xx_gmu_bo icache;
+	struct a6xx_gmu_bo dcache;
+	struct a6xx_gmu_bo dummy;
+	struct a6xx_gmu_bo log;
+
+	int nr_clocks;
+	struct clk_bulk_data *clocks;
+	struct clk *core_clk;
+	struct clk *hub_clk;
+
+	/* current performance index set externally */
+	int current_perf_index;
+
+	int nr_gpu_freqs;
+	unsigned long gpu_freqs[16];
+	u32 gx_arc_votes[16];
+
+	int nr_gmu_freqs;
+	unsigned long gmu_freqs[4];
+	u32 cx_arc_votes[4];
+
+	unsigned long freq;
+
+	struct a6xx_hfi_queue queues[2];
+
+	bool initialized;
+	bool hung;
+	bool legacy; /* a618 or a630 */
+
+	/* For power domain callback */
+	struct notifier_block pd_nb;
+	struct completion pd_gate;
+
+	struct qmp *qmp;
+};
+
+static inline u32 gmu_read(struct a6xx_gmu *gmu, u32 offset)
+{
+	return msm_readl(gmu->mmio + (offset << 2));
+}
+
+static inline void gmu_write(struct a6xx_gmu *gmu, u32 offset, u32 value)
+{
+	msm_writel(value, gmu->mmio + (offset << 2));
+}
+
+static inline void
+gmu_write_bulk(struct a6xx_gmu *gmu, u32 offset, const u32 *data, u32 size)
+{
+	memcpy_toio(gmu->mmio + (offset << 2), data, size);
+	wmb();
+}
+
+static inline void gmu_rmw(struct a6xx_gmu *gmu, u32 reg, u32 mask, u32 or)
+{
+	u32 val = gmu_read(gmu, reg);
+
+	val &= ~mask;
+
+	gmu_write(gmu, reg, val | or);
+}
+
+static inline u64 gmu_read64(struct a6xx_gmu *gmu, u32 lo, u32 hi)
+{
+	u64 val;
+
+	val = (u64) msm_readl(gmu->mmio + (lo << 2));
+	val |= ((u64) msm_readl(gmu->mmio + (hi << 2)) << 32);
+
+	return val;
+}
+
+#define gmu_poll_timeout(gmu, addr, val, cond, interval, timeout) \
+	readl_poll_timeout((gmu)->mmio + ((addr) << 2), val, cond, \
+		interval, timeout)
+
+static inline u32 gmu_read_rscc(struct a6xx_gmu *gmu, u32 offset)
+{
+	return msm_readl(gmu->rscc + (offset << 2));
+}
+
+static inline void gmu_write_rscc(struct a6xx_gmu *gmu, u32 offset, u32 value)
+{
+	msm_writel(value, gmu->rscc + (offset << 2));
+}
+
+#define gmu_poll_timeout_rscc(gmu, addr, val, cond, interval, timeout) \
+	readl_poll_timeout((gmu)->rscc + ((addr) << 2), val, cond, \
+		interval, timeout)
+
+/*
+ * These are the available OOB (out of band requests) to the GMU where "out of
+ * band" means that the CPU talks to the GMU directly and not through HFI.
+ * Normally this works by writing a ITCM/DTCM register and then triggering a
+ * interrupt (the "request" bit) and waiting for an acknowledgment (the "ack"
+ * bit). The state is cleared by writing the "clear' bit to the GMU interrupt.
+ *
+ * These are used to force the GMU/GPU to stay on during a critical sequence or
+ * for hardware workarounds.
+ */
+
+enum a6xx_gmu_oob_state {
+	/*
+	 * Let the GMU know that a boot or slumber operation has started. The value in
+	 * REG_A6XX_GMU_BOOT_SLUMBER_OPTION lets the GMU know which operation we are
+	 * doing
+	 */
+	GMU_OOB_BOOT_SLUMBER = 0,
+	/*
+	 * Let the GMU know to not turn off any GPU registers while the CPU is in a
+	 * critical section
+	 */
+	GMU_OOB_GPU_SET,
+	/*
+	 * Set a new power level for the GPU when the CPU is doing frequency scaling
+	 */
+	GMU_OOB_DCVS_SET,
+	/*
+	 * Used to keep the GPU on for CPU-side reads of performance counters.
+	 */
+	GMU_OOB_PERFCOUNTER_SET,
+};
+
+void a6xx_hfi_init(struct a6xx_gmu *gmu);
+int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state);
+void a6xx_hfi_stop(struct a6xx_gmu *gmu);
+int a6xx_hfi_send_prep_slumber(struct a6xx_gmu *gmu);
+int a6xx_hfi_set_freq(struct a6xx_gmu *gmu, int index);
+
+bool a6xx_gmu_gx_is_on(struct a6xx_gmu *gmu);
+bool a6xx_gmu_sptprac_is_on(struct a6xx_gmu *gmu);
+void a6xx_sptprac_disable(struct a6xx_gmu *gmu);
+int a6xx_sptprac_enable(struct a6xx_gmu *gmu);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a6xx_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a6xx_gpu.c
@@ -0,0 +1,2165 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. */
+
+
+#include "msm_gem.h"
+#include "msm_mmu.h"
+#include "msm_gpu_trace.h"
+#include "a6xx_gpu.h"
+#include "a6xx_gmu.xml.h"
+
+#include <linux/bitfield.h>
+#include <linux/devfreq.h>
+#include <linux/pm_domain.h>
+#include <linux/soc/qcom/llcc-qcom.h>
+
+#define GPU_PAS_ID 13
+
+static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+
+	/* Check that the GMU is idle */
+	if (!adreno_has_gmu_wrapper(adreno_gpu) && !a6xx_gmu_isidle(&a6xx_gpu->gmu))
+		return false;
+
+	/* Check tha the CX master is idle */
+	if (gpu_read(gpu, REG_A6XX_RBBM_STATUS) &
+			~A6XX_RBBM_STATUS_CP_AHB_BUSY_CX_MASTER)
+		return false;
+
+	return !(gpu_read(gpu, REG_A6XX_RBBM_INT_0_STATUS) &
+		A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT);
+}
+
+static bool a6xx_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+	/* wait for CP to drain ringbuffer: */
+	if (!adreno_idle(gpu, ring))
+		return false;
+
+	if (spin_until(_a6xx_check_idle(gpu))) {
+		DRM_ERROR("%s: %ps: timeout waiting for GPU to idle: status %8.8X irq %8.8X rptr/wptr %d/%d\n",
+			gpu->name, __builtin_return_address(0),
+			gpu_read(gpu, REG_A6XX_RBBM_STATUS),
+			gpu_read(gpu, REG_A6XX_RBBM_INT_0_STATUS),
+			gpu_read(gpu, REG_A6XX_CP_RB_RPTR),
+			gpu_read(gpu, REG_A6XX_CP_RB_WPTR));
+		return false;
+	}
+
+	return true;
+}
+
+static void update_shadow_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+
+	/* Expanded APRIV doesn't need to issue the WHERE_AM_I opcode */
+	if (a6xx_gpu->has_whereami && !adreno_gpu->base.hw_apriv) {
+		OUT_PKT7(ring, CP_WHERE_AM_I, 2);
+		OUT_RING(ring, lower_32_bits(shadowptr(a6xx_gpu, ring)));
+		OUT_RING(ring, upper_32_bits(shadowptr(a6xx_gpu, ring)));
+	}
+}
+
+static void a6xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+	uint32_t wptr;
+	unsigned long flags;
+
+	update_shadow_rptr(gpu, ring);
+
+	spin_lock_irqsave(&ring->preempt_lock, flags);
+
+	/* Copy the shadow to the actual register */
+	ring->cur = ring->next;
+
+	/* Make sure to wrap wptr if we need to */
+	wptr = get_wptr(ring);
+
+	spin_unlock_irqrestore(&ring->preempt_lock, flags);
+
+	/* Make sure everything is posted before making a decision */
+	mb();
+
+	gpu_write(gpu, REG_A6XX_CP_RB_WPTR, wptr);
+}
+
+static void get_stats_counter(struct msm_ringbuffer *ring, u32 counter,
+		u64 iova)
+{
+	OUT_PKT7(ring, CP_REG_TO_MEM, 3);
+	OUT_RING(ring, CP_REG_TO_MEM_0_REG(counter) |
+		CP_REG_TO_MEM_0_CNT(2) |
+		CP_REG_TO_MEM_0_64B);
+	OUT_RING(ring, lower_32_bits(iova));
+	OUT_RING(ring, upper_32_bits(iova));
+}
+
+static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu,
+		struct msm_ringbuffer *ring, struct msm_file_private *ctx)
+{
+	bool sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1;
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	phys_addr_t ttbr;
+	u32 asid;
+	u64 memptr = rbmemptr(ring, ttbr0);
+
+	if (ctx->seqno == a6xx_gpu->base.base.cur_ctx_seqno)
+		return;
+
+	if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid))
+		return;
+
+	if (!sysprof) {
+		if (!adreno_is_a7xx(adreno_gpu)) {
+			/* Turn off protected mode to write to special registers */
+			OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
+			OUT_RING(ring, 0);
+		}
+
+		OUT_PKT4(ring, REG_A6XX_RBBM_PERFCTR_SRAM_INIT_CMD, 1);
+		OUT_RING(ring, 1);
+	}
+
+	/* Execute the table update */
+	OUT_PKT7(ring, CP_SMMU_TABLE_UPDATE, 4);
+	OUT_RING(ring, CP_SMMU_TABLE_UPDATE_0_TTBR0_LO(lower_32_bits(ttbr)));
+
+	OUT_RING(ring,
+		CP_SMMU_TABLE_UPDATE_1_TTBR0_HI(upper_32_bits(ttbr)) |
+		CP_SMMU_TABLE_UPDATE_1_ASID(asid));
+	OUT_RING(ring, CP_SMMU_TABLE_UPDATE_2_CONTEXTIDR(0));
+	OUT_RING(ring, CP_SMMU_TABLE_UPDATE_3_CONTEXTBANK(0));
+
+	/*
+	 * Write the new TTBR0 to the memstore. This is good for debugging.
+	 */
+	OUT_PKT7(ring, CP_MEM_WRITE, 4);
+	OUT_RING(ring, CP_MEM_WRITE_0_ADDR_LO(lower_32_bits(memptr)));
+	OUT_RING(ring, CP_MEM_WRITE_1_ADDR_HI(upper_32_bits(memptr)));
+	OUT_RING(ring, lower_32_bits(ttbr));
+	OUT_RING(ring, (asid << 16) | upper_32_bits(ttbr));
+
+	/*
+	 * Sync both threads after switching pagetables and enable BR only
+	 * to make sure BV doesn't race ahead while BR is still switching
+	 * pagetables.
+	 */
+	if (adreno_is_a7xx(&a6xx_gpu->base)) {
+		OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
+		OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BR);
+	}
+
+	/*
+	 * And finally, trigger a uche flush to be sure there isn't anything
+	 * lingering in that part of the GPU
+	 */
+
+	OUT_PKT7(ring, CP_EVENT_WRITE, 1);
+	OUT_RING(ring, CACHE_INVALIDATE);
+
+	if (!sysprof) {
+		/*
+		 * Wait for SRAM clear after the pgtable update, so the
+		 * two can happen in parallel:
+		 */
+		OUT_PKT7(ring, CP_WAIT_REG_MEM, 6);
+		OUT_RING(ring, CP_WAIT_REG_MEM_0_FUNCTION(WRITE_EQ));
+		OUT_RING(ring, CP_WAIT_REG_MEM_1_POLL_ADDR_LO(
+				REG_A6XX_RBBM_PERFCTR_SRAM_INIT_STATUS));
+		OUT_RING(ring, CP_WAIT_REG_MEM_2_POLL_ADDR_HI(0));
+		OUT_RING(ring, CP_WAIT_REG_MEM_3_REF(0x1));
+		OUT_RING(ring, CP_WAIT_REG_MEM_4_MASK(0x1));
+		OUT_RING(ring, CP_WAIT_REG_MEM_5_DELAY_LOOP_CYCLES(0));
+
+		if (!adreno_is_a7xx(adreno_gpu)) {
+			/* Re-enable protected mode: */
+			OUT_PKT7(ring, CP_SET_PROTECTED_MODE, 1);
+			OUT_RING(ring, 1);
+		}
+	}
+}
+
+static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+{
+	unsigned int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT;
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	struct msm_ringbuffer *ring = submit->ring;
+	unsigned int i, ibs = 0;
+
+	a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx);
+
+	get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0),
+		rbmemptr_stats(ring, index, cpcycles_start));
+
+	/*
+	 * For PM4 the GMU register offsets are calculated from the base of the
+	 * GPU registers so we need to add 0x1a800 to the register value on A630
+	 * to get the right value from PM4.
+	 */
+	get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER,
+		rbmemptr_stats(ring, index, alwayson_start));
+
+	/* Invalidate CCU depth and color */
+	OUT_PKT7(ring, CP_EVENT_WRITE, 1);
+	OUT_RING(ring, CP_EVENT_WRITE_0_EVENT(PC_CCU_INVALIDATE_DEPTH));
+
+	OUT_PKT7(ring, CP_EVENT_WRITE, 1);
+	OUT_RING(ring, CP_EVENT_WRITE_0_EVENT(PC_CCU_INVALIDATE_COLOR));
+
+	/* Submit the commands */
+	for (i = 0; i < submit->nr_cmds; i++) {
+		switch (submit->cmd[i].type) {
+		case MSM_SUBMIT_CMD_IB_TARGET_BUF:
+			break;
+		case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+			if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
+				break;
+			fallthrough;
+		case MSM_SUBMIT_CMD_BUF:
+			OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3);
+			OUT_RING(ring, lower_32_bits(submit->cmd[i].iova));
+			OUT_RING(ring, upper_32_bits(submit->cmd[i].iova));
+			OUT_RING(ring, submit->cmd[i].size);
+			ibs++;
+			break;
+		}
+
+		/*
+		 * Periodically update shadow-wptr if needed, so that we
+		 * can see partial progress of submits with large # of
+		 * cmds.. otherwise we could needlessly stall waiting for
+		 * ringbuffer state, simply due to looking at a shadow
+		 * rptr value that has not been updated
+		 */
+		if ((ibs % 32) == 0)
+			update_shadow_rptr(gpu, ring);
+	}
+
+	get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0),
+		rbmemptr_stats(ring, index, cpcycles_end));
+	get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER,
+		rbmemptr_stats(ring, index, alwayson_end));
+
+	/* Write the fence to the scratch register */
+	OUT_PKT4(ring, REG_A6XX_CP_SCRATCH_REG(2), 1);
+	OUT_RING(ring, submit->seqno);
+
+	/*
+	 * Execute a CACHE_FLUSH_TS event. This will ensure that the
+	 * timestamp is written to the memory and then triggers the interrupt
+	 */
+	OUT_PKT7(ring, CP_EVENT_WRITE, 4);
+	OUT_RING(ring, CP_EVENT_WRITE_0_EVENT(CACHE_FLUSH_TS) |
+		CP_EVENT_WRITE_0_IRQ);
+	OUT_RING(ring, lower_32_bits(rbmemptr(ring, fence)));
+	OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence)));
+	OUT_RING(ring, submit->seqno);
+
+	trace_msm_gpu_submit_flush(submit,
+		gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER));
+
+	a6xx_flush(gpu, ring);
+}
+
+static void a7xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+{
+	unsigned int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT;
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	struct msm_ringbuffer *ring = submit->ring;
+	unsigned int i, ibs = 0;
+
+	/*
+	 * Toggle concurrent binning for pagetable switch and set the thread to
+	 * BR since only it can execute the pagetable switch packets.
+	 */
+	OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
+	OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BR);
+
+	a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx);
+
+	get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0),
+		rbmemptr_stats(ring, index, cpcycles_start));
+	get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER,
+		rbmemptr_stats(ring, index, alwayson_start));
+
+	OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
+	OUT_RING(ring, CP_SET_THREAD_BOTH);
+
+	OUT_PKT7(ring, CP_SET_MARKER, 1);
+	OUT_RING(ring, 0x101); /* IFPC disable */
+
+	OUT_PKT7(ring, CP_SET_MARKER, 1);
+	OUT_RING(ring, 0x00d); /* IB1LIST start */
+
+	/* Submit the commands */
+	for (i = 0; i < submit->nr_cmds; i++) {
+		switch (submit->cmd[i].type) {
+		case MSM_SUBMIT_CMD_IB_TARGET_BUF:
+			break;
+		case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+			if (gpu->cur_ctx_seqno == submit->queue->ctx->seqno)
+				break;
+			fallthrough;
+		case MSM_SUBMIT_CMD_BUF:
+			OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3);
+			OUT_RING(ring, lower_32_bits(submit->cmd[i].iova));
+			OUT_RING(ring, upper_32_bits(submit->cmd[i].iova));
+			OUT_RING(ring, submit->cmd[i].size);
+			ibs++;
+			break;
+		}
+
+		/*
+		 * Periodically update shadow-wptr if needed, so that we
+		 * can see partial progress of submits with large # of
+		 * cmds.. otherwise we could needlessly stall waiting for
+		 * ringbuffer state, simply due to looking at a shadow
+		 * rptr value that has not been updated
+		 */
+		if ((ibs % 32) == 0)
+			update_shadow_rptr(gpu, ring);
+	}
+
+	OUT_PKT7(ring, CP_SET_MARKER, 1);
+	OUT_RING(ring, 0x00e); /* IB1LIST end */
+
+	get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0),
+		rbmemptr_stats(ring, index, cpcycles_end));
+	get_stats_counter(ring, REG_A6XX_CP_ALWAYS_ON_COUNTER,
+		rbmemptr_stats(ring, index, alwayson_end));
+
+	/* Write the fence to the scratch register */
+	OUT_PKT4(ring, REG_A6XX_CP_SCRATCH_REG(2), 1);
+	OUT_RING(ring, submit->seqno);
+
+	OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
+	OUT_RING(ring, CP_SET_THREAD_BR);
+
+	OUT_PKT7(ring, CP_EVENT_WRITE, 1);
+	OUT_RING(ring, CCU_INVALIDATE_DEPTH);
+
+	OUT_PKT7(ring, CP_EVENT_WRITE, 1);
+	OUT_RING(ring, CCU_INVALIDATE_COLOR);
+
+	OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
+	OUT_RING(ring, CP_SET_THREAD_BV);
+
+	/*
+	 * Make sure the timestamp is committed once BV pipe is
+	 * completely done with this submission.
+	 */
+	OUT_PKT7(ring, CP_EVENT_WRITE, 4);
+	OUT_RING(ring, CACHE_CLEAN | BIT(27));
+	OUT_RING(ring, lower_32_bits(rbmemptr(ring, bv_fence)));
+	OUT_RING(ring, upper_32_bits(rbmemptr(ring, bv_fence)));
+	OUT_RING(ring, submit->seqno);
+
+	OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
+	OUT_RING(ring, CP_SET_THREAD_BR);
+
+	/*
+	 * This makes sure that BR doesn't race ahead and commit
+	 * timestamp to memstore while BV is still processing
+	 * this submission.
+	 */
+	OUT_PKT7(ring, CP_WAIT_TIMESTAMP, 4);
+	OUT_RING(ring, 0);
+	OUT_RING(ring, lower_32_bits(rbmemptr(ring, bv_fence)));
+	OUT_RING(ring, upper_32_bits(rbmemptr(ring, bv_fence)));
+	OUT_RING(ring, submit->seqno);
+
+	/* write the ringbuffer timestamp */
+	OUT_PKT7(ring, CP_EVENT_WRITE, 4);
+	OUT_RING(ring, CACHE_CLEAN | CP_EVENT_WRITE_0_IRQ | BIT(27));
+	OUT_RING(ring, lower_32_bits(rbmemptr(ring, fence)));
+	OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence)));
+	OUT_RING(ring, submit->seqno);
+
+	OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
+	OUT_RING(ring, CP_SET_THREAD_BOTH);
+
+	OUT_PKT7(ring, CP_SET_MARKER, 1);
+	OUT_RING(ring, 0x100); /* IFPC enable */
+
+	trace_msm_gpu_submit_flush(submit,
+		gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER));
+
+	a6xx_flush(gpu, ring);
+}
+
+static void a6xx_set_hwcg(struct msm_gpu *gpu, bool state)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+	const struct adreno_reglist *reg;
+	unsigned int i;
+	u32 val, clock_cntl_on, cgc_mode;
+
+	if (!(adreno_gpu->info->a6xx->hwcg || adreno_is_a7xx(adreno_gpu)))
+		return;
+
+	if (adreno_is_a630(adreno_gpu))
+		clock_cntl_on = 0x8aa8aa02;
+	else if (adreno_is_a610(adreno_gpu))
+		clock_cntl_on = 0xaaa8aa82;
+	else if (adreno_is_a702(adreno_gpu))
+		clock_cntl_on = 0xaaaaaa82;
+	else
+		clock_cntl_on = 0x8aa8aa82;
+
+	if (adreno_is_a7xx(adreno_gpu)) {
+		cgc_mode = adreno_is_a740_family(adreno_gpu) ? 0x20222 : 0x20000;
+
+		gmu_write(&a6xx_gpu->gmu, REG_A6XX_GPU_GMU_AO_GMU_CGC_MODE_CNTL,
+			  state ? cgc_mode : 0);
+		gmu_write(&a6xx_gpu->gmu, REG_A6XX_GPU_GMU_AO_GMU_CGC_DELAY_CNTL,
+			  state ? 0x10111 : 0);
+		gmu_write(&a6xx_gpu->gmu, REG_A6XX_GPU_GMU_AO_GMU_CGC_HYST_CNTL,
+			  state ? 0x5555 : 0);
+	}
+
+	if (!adreno_gpu->info->a6xx->hwcg) {
+		gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 1);
+		gpu_write(gpu, REG_A7XX_RBBM_CGC_GLOBAL_LOAD_CMD, state ? 1 : 0);
+
+		if (state) {
+			gpu_write(gpu, REG_A7XX_RBBM_CGC_P2S_TRIG_CMD, 1);
+
+			if (gpu_poll_timeout(gpu, REG_A7XX_RBBM_CGC_P2S_STATUS, val,
+					     val & A7XX_RBBM_CGC_P2S_STATUS_TXDONE, 1, 10)) {
+				dev_err(&gpu->pdev->dev, "RBBM_CGC_P2S_STATUS TXDONE Poll failed\n");
+				return;
+			}
+
+			gpu_write(gpu, REG_A7XX_RBBM_CLOCK_CNTL_GLOBAL, 0);
+		}
+
+		return;
+	}
+
+	val = gpu_read(gpu, REG_A6XX_RBBM_CLOCK_CNTL);
+
+	/* Don't re-program the registers if they are already correct */
+	if ((!state && !val) || (state && (val == clock_cntl_on)))
+		return;
+
+	/* Disable SP clock before programming HWCG registers */
+	if (!adreno_is_a610_family(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
+		gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 1, 0);
+
+	for (i = 0; (reg = &adreno_gpu->info->a6xx->hwcg[i], reg->offset); i++)
+		gpu_write(gpu, reg->offset, state ? reg->value : 0);
+
+	/* Enable SP clock */
+	if (!adreno_is_a610_family(adreno_gpu) && !adreno_is_a7xx(adreno_gpu))
+		gmu_rmw(gmu, REG_A6XX_GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL, 0, 1);
+
+	gpu_write(gpu, REG_A6XX_RBBM_CLOCK_CNTL, state ? clock_cntl_on : 0);
+}
+
+static void a6xx_set_cp_protect(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	const struct adreno_protect *protect = adreno_gpu->info->a6xx->protect;
+	unsigned i;
+
+	/*
+	 * Enable access protection to privileged registers, fault on an access
+	 * protect violation and select the last span to protect from the start
+	 * address all the way to the end of the register address space
+	 */
+	gpu_write(gpu, REG_A6XX_CP_PROTECT_CNTL,
+		  A6XX_CP_PROTECT_CNTL_ACCESS_PROT_EN |
+		  A6XX_CP_PROTECT_CNTL_ACCESS_FAULT_ON_VIOL_EN |
+		  A6XX_CP_PROTECT_CNTL_LAST_SPAN_INF_RANGE);
+
+	for (i = 0; i < protect->count - 1; i++) {
+		/* Intentionally skip writing to some registers */
+		if (protect->regs[i])
+			gpu_write(gpu, REG_A6XX_CP_PROTECT(i), protect->regs[i]);
+	}
+	/* last CP_PROTECT to have "infinite" length on the last entry */
+	gpu_write(gpu, REG_A6XX_CP_PROTECT(protect->count_max - 1), protect->regs[i]);
+}
+
+static void a6xx_calc_ubwc_config(struct adreno_gpu *gpu)
+{
+	gpu->ubwc_config.rgb565_predicator = 0;
+	gpu->ubwc_config.uavflagprd_inv = 0;
+	gpu->ubwc_config.min_acc_len = 0;
+	gpu->ubwc_config.ubwc_swizzle = 0x6;
+	gpu->ubwc_config.macrotile_mode = 0;
+	gpu->ubwc_config.highest_bank_bit = 15;
+
+	if (adreno_is_a610(gpu)) {
+		gpu->ubwc_config.highest_bank_bit = 13;
+		gpu->ubwc_config.min_acc_len = 1;
+		gpu->ubwc_config.ubwc_swizzle = 0x7;
+	}
+
+	if (adreno_is_a618(gpu))
+		gpu->ubwc_config.highest_bank_bit = 14;
+
+	if (adreno_is_a619(gpu))
+		/* TODO: Should be 14 but causes corruption at e.g. 1920x1200 on DP */
+		gpu->ubwc_config.highest_bank_bit = 13;
+
+	if (adreno_is_a619_holi(gpu))
+		gpu->ubwc_config.highest_bank_bit = 13;
+
+	if (adreno_is_a640_family(gpu))
+		gpu->ubwc_config.amsbc = 1;
+
+	if (adreno_is_a650(gpu) ||
+	    adreno_is_a660(gpu) ||
+	    adreno_is_a690(gpu) ||
+	    adreno_is_a730(gpu) ||
+	    adreno_is_a740_family(gpu)) {
+		/* TODO: get ddr type from bootloader and use 2 for LPDDR4 */
+		gpu->ubwc_config.highest_bank_bit = 16;
+		gpu->ubwc_config.amsbc = 1;
+		gpu->ubwc_config.rgb565_predicator = 1;
+		gpu->ubwc_config.uavflagprd_inv = 2;
+		gpu->ubwc_config.macrotile_mode = 1;
+	}
+
+	if (adreno_is_a663(gpu)) {
+		gpu->ubwc_config.highest_bank_bit = 13;
+		gpu->ubwc_config.amsbc = 1;
+		gpu->ubwc_config.rgb565_predicator = 1;
+		gpu->ubwc_config.uavflagprd_inv = 2;
+		gpu->ubwc_config.macrotile_mode = 1;
+		gpu->ubwc_config.ubwc_swizzle = 0x4;
+	}
+
+	if (adreno_is_7c3(gpu)) {
+		gpu->ubwc_config.highest_bank_bit = 14;
+		gpu->ubwc_config.amsbc = 1;
+		gpu->ubwc_config.rgb565_predicator = 1;
+		gpu->ubwc_config.uavflagprd_inv = 2;
+		gpu->ubwc_config.macrotile_mode = 1;
+	}
+
+	if (adreno_is_a702(gpu)) {
+		gpu->ubwc_config.highest_bank_bit = 14;
+		gpu->ubwc_config.min_acc_len = 1;
+	}
+}
+
+static void a6xx_set_ubwc_config(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	/*
+	 * We subtract 13 from the highest bank bit (13 is the minimum value
+	 * allowed by hw) and write the lowest two bits of the remaining value
+	 * as hbb_lo and the one above it as hbb_hi to the hardware.
+	 */
+	BUG_ON(adreno_gpu->ubwc_config.highest_bank_bit < 13);
+	u32 hbb = adreno_gpu->ubwc_config.highest_bank_bit - 13;
+	u32 hbb_hi = hbb >> 2;
+	u32 hbb_lo = hbb & 3;
+	u32 ubwc_mode = adreno_gpu->ubwc_config.ubwc_swizzle & 1;
+	u32 level2_swizzling_dis = !(adreno_gpu->ubwc_config.ubwc_swizzle & 2);
+
+	gpu_write(gpu, REG_A6XX_RB_NC_MODE_CNTL,
+		  level2_swizzling_dis << 12 |
+		  adreno_gpu->ubwc_config.rgb565_predicator << 11 |
+		  hbb_hi << 10 | adreno_gpu->ubwc_config.amsbc << 4 |
+		  adreno_gpu->ubwc_config.min_acc_len << 3 |
+		  hbb_lo << 1 | ubwc_mode);
+
+	gpu_write(gpu, REG_A6XX_TPL1_NC_MODE_CNTL,
+		  level2_swizzling_dis << 6 | hbb_hi << 4 |
+		  adreno_gpu->ubwc_config.min_acc_len << 3 |
+		  hbb_lo << 1 | ubwc_mode);
+
+	gpu_write(gpu, REG_A6XX_SP_NC_MODE_CNTL,
+		  level2_swizzling_dis << 12 | hbb_hi << 10 |
+		  adreno_gpu->ubwc_config.uavflagprd_inv << 4 |
+		  adreno_gpu->ubwc_config.min_acc_len << 3 |
+		  hbb_lo << 1 | ubwc_mode);
+
+	if (adreno_is_a7xx(adreno_gpu))
+		gpu_write(gpu, REG_A7XX_GRAS_NC_MODE_CNTL,
+			  FIELD_PREP(GENMASK(8, 5), hbb_lo));
+
+	gpu_write(gpu, REG_A6XX_UCHE_MODE_CNTL,
+		  adreno_gpu->ubwc_config.min_acc_len << 23 | hbb_lo << 21);
+
+	gpu_write(gpu, REG_A6XX_RBBM_NC_MODE_CNTL,
+		  adreno_gpu->ubwc_config.macrotile_mode);
+}
+
+static int a6xx_cp_init(struct msm_gpu *gpu)
+{
+	struct msm_ringbuffer *ring = gpu->rb[0];
+
+	OUT_PKT7(ring, CP_ME_INIT, 8);
+
+	OUT_RING(ring, 0x0000002f);
+
+	/* Enable multiple hardware contexts */
+	OUT_RING(ring, 0x00000003);
+
+	/* Enable error detection */
+	OUT_RING(ring, 0x20000000);
+
+	/* Don't enable header dump */
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+
+	/* No workarounds enabled */
+	OUT_RING(ring, 0x00000000);
+
+	/* Pad rest of the cmds with 0's */
+	OUT_RING(ring, 0x00000000);
+	OUT_RING(ring, 0x00000000);
+
+	a6xx_flush(gpu, ring);
+	return a6xx_idle(gpu, ring) ? 0 : -EINVAL;
+}
+
+static int a7xx_cp_init(struct msm_gpu *gpu)
+{
+	struct msm_ringbuffer *ring = gpu->rb[0];
+	u32 mask;
+
+	/* Disable concurrent binning before sending CP init */
+	OUT_PKT7(ring, CP_THREAD_CONTROL, 1);
+	OUT_RING(ring, BIT(27));
+
+	OUT_PKT7(ring, CP_ME_INIT, 7);
+
+	/* Use multiple HW contexts */
+	mask = BIT(0);
+
+	/* Enable error detection */
+	mask |= BIT(1);
+
+	/* Set default reset state */
+	mask |= BIT(3);
+
+	/* Disable save/restore of performance counters across preemption */
+	mask |= BIT(6);
+
+	/* Enable the register init list with the spinlock */
+	mask |= BIT(8);
+
+	OUT_RING(ring, mask);
+
+	/* Enable multiple hardware contexts */
+	OUT_RING(ring, 0x00000003);
+
+	/* Enable error detection */
+	OUT_RING(ring, 0x20000000);
+
+	/* Operation mode mask */
+	OUT_RING(ring, 0x00000002);
+
+	/* *Don't* send a power up reg list for concurrent binning (TODO) */
+	/* Lo address */
+	OUT_RING(ring, 0x00000000);
+	/* Hi address */
+	OUT_RING(ring, 0x00000000);
+	/* BIT(31) set => read the regs from the list */
+	OUT_RING(ring, 0x00000000);
+
+	a6xx_flush(gpu, ring);
+	return a6xx_idle(gpu, ring) ? 0 : -EINVAL;
+}
+
+/*
+ * Check that the microcode version is new enough to include several key
+ * security fixes. Return true if the ucode is safe.
+ */
+static bool a6xx_ucode_check_version(struct a6xx_gpu *a6xx_gpu,
+		struct drm_gem_object *obj)
+{
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	struct msm_gpu *gpu = &adreno_gpu->base;
+	const char *sqe_name = adreno_gpu->info->fw[ADRENO_FW_SQE];
+	u32 *buf = msm_gem_get_vaddr(obj);
+	bool ret = false;
+
+	if (IS_ERR(buf))
+		return false;
+
+	/* A7xx is safe! */
+	if (adreno_is_a7xx(adreno_gpu) || adreno_is_a702(adreno_gpu))
+		return true;
+
+	/*
+	 * Targets up to a640 (a618, a630 and a640) need to check for a
+	 * microcode version that is patched to support the whereami opcode or
+	 * one that is new enough to include it by default.
+	 *
+	 * a650 tier targets don't need whereami but still need to be
+	 * equal to or newer than 0.95 for other security fixes
+	 *
+	 * a660 targets have all the critical security fixes from the start
+	 */
+	if (!strcmp(sqe_name, "a630_sqe.fw")) {
+		/*
+		 * If the lowest nibble is 0xa that is an indication that this
+		 * microcode has been patched. The actual version is in dword
+		 * [3] but we only care about the patchlevel which is the lowest
+		 * nibble of dword [3]
+		 *
+		 * Otherwise check that the firmware is greater than or equal
+		 * to 1.90 which was the first version that had this fix built
+		 * in
+		 */
+		if ((((buf[0] & 0xf) == 0xa) && (buf[2] & 0xf) >= 1) ||
+			(buf[0] & 0xfff) >= 0x190) {
+			a6xx_gpu->has_whereami = true;
+			ret = true;
+			goto out;
+		}
+
+		DRM_DEV_ERROR(&gpu->pdev->dev,
+			"a630 SQE ucode is too old. Have version %x need at least %x\n",
+			buf[0] & 0xfff, 0x190);
+	} else if (!strcmp(sqe_name, "a650_sqe.fw")) {
+		if ((buf[0] & 0xfff) >= 0x095) {
+			ret = true;
+			goto out;
+		}
+
+		DRM_DEV_ERROR(&gpu->pdev->dev,
+			"a650 SQE ucode is too old. Have version %x need at least %x\n",
+			buf[0] & 0xfff, 0x095);
+	} else if (!strcmp(sqe_name, "a660_sqe.fw")) {
+		ret = true;
+	} else {
+		DRM_DEV_ERROR(&gpu->pdev->dev,
+			"unknown GPU, add it to a6xx_ucode_check_version()!!\n");
+	}
+out:
+	msm_gem_put_vaddr(obj);
+	return ret;
+}
+
+static int a6xx_ucode_load(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+
+	if (!a6xx_gpu->sqe_bo) {
+		a6xx_gpu->sqe_bo = adreno_fw_create_bo(gpu,
+			adreno_gpu->fw[ADRENO_FW_SQE], &a6xx_gpu->sqe_iova);
+
+		if (IS_ERR(a6xx_gpu->sqe_bo)) {
+			int ret = PTR_ERR(a6xx_gpu->sqe_bo);
+
+			a6xx_gpu->sqe_bo = NULL;
+			DRM_DEV_ERROR(&gpu->pdev->dev,
+				"Could not allocate SQE ucode: %d\n", ret);
+
+			return ret;
+		}
+
+		msm_gem_object_set_name(a6xx_gpu->sqe_bo, "sqefw");
+		if (!a6xx_ucode_check_version(a6xx_gpu, a6xx_gpu->sqe_bo)) {
+			msm_gem_unpin_iova(a6xx_gpu->sqe_bo, gpu->aspace);
+			drm_gem_object_put(a6xx_gpu->sqe_bo);
+
+			a6xx_gpu->sqe_bo = NULL;
+			return -EPERM;
+		}
+	}
+
+	/*
+	 * Expanded APRIV and targets that support WHERE_AM_I both need a
+	 * privileged buffer to store the RPTR shadow
+	 */
+	if ((adreno_gpu->base.hw_apriv || a6xx_gpu->has_whereami) &&
+	    !a6xx_gpu->shadow_bo) {
+		a6xx_gpu->shadow = msm_gem_kernel_new(gpu->dev,
+						      sizeof(u32) * gpu->nr_rings,
+						      MSM_BO_WC | MSM_BO_MAP_PRIV,
+						      gpu->aspace, &a6xx_gpu->shadow_bo,
+						      &a6xx_gpu->shadow_iova);
+
+		if (IS_ERR(a6xx_gpu->shadow))
+			return PTR_ERR(a6xx_gpu->shadow);
+
+		msm_gem_object_set_name(a6xx_gpu->shadow_bo, "shadow");
+	}
+
+	return 0;
+}
+
+static int a6xx_zap_shader_init(struct msm_gpu *gpu)
+{
+	static bool loaded;
+	int ret;
+
+	if (loaded)
+		return 0;
+
+	ret = adreno_zap_shader_load(gpu, GPU_PAS_ID);
+
+	loaded = !ret;
+	return ret;
+}
+
+#define A6XX_INT_MASK (A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR | \
+		       A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW | \
+		       A6XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
+		       A6XX_RBBM_INT_0_MASK_CP_IB2 | \
+		       A6XX_RBBM_INT_0_MASK_CP_IB1 | \
+		       A6XX_RBBM_INT_0_MASK_CP_RB | \
+		       A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS | \
+		       A6XX_RBBM_INT_0_MASK_RBBM_ATB_BUS_OVERFLOW | \
+		       A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
+		       A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
+		       A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR)
+
+#define A7XX_INT_MASK (A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR | \
+		       A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW | \
+		       A6XX_RBBM_INT_0_MASK_RBBM_GPC_ERROR | \
+		       A6XX_RBBM_INT_0_MASK_CP_SW | \
+		       A6XX_RBBM_INT_0_MASK_CP_HW_ERROR | \
+		       A6XX_RBBM_INT_0_MASK_PM4CPINTERRUPT | \
+		       A6XX_RBBM_INT_0_MASK_CP_RB_DONE_TS | \
+		       A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS | \
+		       A6XX_RBBM_INT_0_MASK_RBBM_ATB_BUS_OVERFLOW | \
+		       A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT | \
+		       A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS | \
+		       A6XX_RBBM_INT_0_MASK_UCHE_TRAP_INTR | \
+		       A6XX_RBBM_INT_0_MASK_TSBWRITEERROR)
+
+#define A7XX_APRIV_MASK (A6XX_CP_APRIV_CNTL_ICACHE | \
+			 A6XX_CP_APRIV_CNTL_RBFETCH | \
+			 A6XX_CP_APRIV_CNTL_RBPRIVLEVEL | \
+			 A6XX_CP_APRIV_CNTL_RBRPWB)
+
+#define A7XX_BR_APRIVMASK (A7XX_APRIV_MASK | \
+			   A6XX_CP_APRIV_CNTL_CDREAD | \
+			   A6XX_CP_APRIV_CNTL_CDWRITE)
+
+static int hw_init(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+	u64 gmem_range_min;
+	int ret;
+
+	if (!adreno_has_gmu_wrapper(adreno_gpu)) {
+		/* Make sure the GMU keeps the GPU on while we set it up */
+		ret = a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
+		if (ret)
+			return ret;
+	}
+
+	/* Clear GBIF halt in case GX domain was not collapsed */
+	if (adreno_is_a619_holi(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_GBIF_HALT, 0);
+		gpu_write(gpu, REG_A6XX_RBBM_GPR0_CNTL, 0);
+		/* Let's make extra sure that the GPU can access the memory.. */
+		mb();
+	} else if (a6xx_has_gbif(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_GBIF_HALT, 0);
+		gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 0);
+		/* Let's make extra sure that the GPU can access the memory.. */
+		mb();
+	}
+
+	/* Some GPUs are stubborn and take their sweet time to unhalt GBIF! */
+	if (adreno_is_a7xx(adreno_gpu) && a6xx_has_gbif(adreno_gpu))
+		spin_until(!gpu_read(gpu, REG_A6XX_GBIF_HALT_ACK));
+
+	gpu_write(gpu, REG_A6XX_RBBM_SECVID_TSB_CNTL, 0);
+
+	if (adreno_is_a619_holi(adreno_gpu))
+		a6xx_sptprac_enable(gmu);
+
+	/*
+	 * Disable the trusted memory range - we don't actually supported secure
+	 * memory rendering at this point in time and we don't want to block off
+	 * part of the virtual memory space.
+	 */
+	gpu_write64(gpu, REG_A6XX_RBBM_SECVID_TSB_TRUSTED_BASE, 0x00000000);
+	gpu_write(gpu, REG_A6XX_RBBM_SECVID_TSB_TRUSTED_SIZE, 0x00000000);
+
+	if (!adreno_is_a7xx(adreno_gpu)) {
+		/* Turn on 64 bit addressing for all blocks */
+		gpu_write(gpu, REG_A6XX_CP_ADDR_MODE_CNTL, 0x1);
+		gpu_write(gpu, REG_A6XX_VSC_ADDR_MODE_CNTL, 0x1);
+		gpu_write(gpu, REG_A6XX_GRAS_ADDR_MODE_CNTL, 0x1);
+		gpu_write(gpu, REG_A6XX_RB_ADDR_MODE_CNTL, 0x1);
+		gpu_write(gpu, REG_A6XX_PC_ADDR_MODE_CNTL, 0x1);
+		gpu_write(gpu, REG_A6XX_HLSQ_ADDR_MODE_CNTL, 0x1);
+		gpu_write(gpu, REG_A6XX_VFD_ADDR_MODE_CNTL, 0x1);
+		gpu_write(gpu, REG_A6XX_VPC_ADDR_MODE_CNTL, 0x1);
+		gpu_write(gpu, REG_A6XX_UCHE_ADDR_MODE_CNTL, 0x1);
+		gpu_write(gpu, REG_A6XX_SP_ADDR_MODE_CNTL, 0x1);
+		gpu_write(gpu, REG_A6XX_TPL1_ADDR_MODE_CNTL, 0x1);
+		gpu_write(gpu, REG_A6XX_RBBM_SECVID_TSB_ADDR_MODE_CNTL, 0x1);
+	}
+
+	/* enable hardware clockgating */
+	a6xx_set_hwcg(gpu, true);
+
+	/* VBIF/GBIF start*/
+	if (adreno_is_a610_family(adreno_gpu) ||
+	    adreno_is_a640_family(adreno_gpu) ||
+	    adreno_is_a650_family(adreno_gpu) ||
+	    adreno_is_a7xx(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE0, 0x00071620);
+		gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE1, 0x00071620);
+		gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE2, 0x00071620);
+		gpu_write(gpu, REG_A6XX_GBIF_QSB_SIDE3, 0x00071620);
+		gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL,
+			  adreno_is_a7xx(adreno_gpu) ? 0x2120212 : 0x3);
+	} else {
+		gpu_write(gpu, REG_A6XX_RBBM_VBIF_CLIENT_QOS_CNTL, 0x3);
+	}
+
+	if (adreno_is_a630(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_VBIF_GATE_OFF_WRREQ_EN, 0x00000009);
+
+	if (adreno_is_a7xx(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_UCHE_GBIF_GX_CONFIG, 0x10240e0);
+
+	/* Make all blocks contribute to the GPU BUSY perf counter */
+	gpu_write(gpu, REG_A6XX_RBBM_PERFCTR_GPU_BUSY_MASKED, 0xffffffff);
+
+	/* Disable L2 bypass in the UCHE */
+	if (adreno_is_a7xx(adreno_gpu)) {
+		gpu_write64(gpu, REG_A6XX_UCHE_TRAP_BASE, 0x0001fffffffff000llu);
+		gpu_write64(gpu, REG_A6XX_UCHE_WRITE_THRU_BASE, 0x0001fffffffff000llu);
+	} else {
+		gpu_write64(gpu, REG_A6XX_UCHE_WRITE_RANGE_MAX, 0x0001ffffffffffc0llu);
+		gpu_write64(gpu, REG_A6XX_UCHE_TRAP_BASE, 0x0001fffffffff000llu);
+		gpu_write64(gpu, REG_A6XX_UCHE_WRITE_THRU_BASE, 0x0001fffffffff000llu);
+	}
+
+	if (!(adreno_is_a650_family(adreno_gpu) ||
+	      adreno_is_a702(adreno_gpu) ||
+	      adreno_is_a730(adreno_gpu))) {
+		gmem_range_min = adreno_is_a740_family(adreno_gpu) ? SZ_16M : SZ_1M;
+
+		/* Set the GMEM VA range [0x100000:0x100000 + gpu->gmem - 1] */
+		gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MIN, gmem_range_min);
+
+		gpu_write64(gpu, REG_A6XX_UCHE_GMEM_RANGE_MAX,
+			gmem_range_min + adreno_gpu->info->gmem - 1);
+	}
+
+	if (adreno_is_a7xx(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_UCHE_CACHE_WAYS, BIT(23));
+	else {
+		gpu_write(gpu, REG_A6XX_UCHE_FILTER_CNTL, 0x804);
+		gpu_write(gpu, REG_A6XX_UCHE_CACHE_WAYS, 0x4);
+	}
+
+	if (adreno_is_a640_family(adreno_gpu) || adreno_is_a650_family(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140);
+		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
+	} else if (adreno_is_a610_family(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x00800060);
+		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x40201b16);
+	} else if (!adreno_is_a7xx(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2, 0x010000c0);
+		gpu_write(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362c);
+	}
+
+	if (adreno_is_a660_family(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_CP_LPAC_PROG_FIFO_SIZE, 0x00000020);
+
+	/* Setting the mem pool size */
+	if (adreno_is_a610(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 48);
+		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_DBG_ADDR, 47);
+	} else if (adreno_is_a702(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 64);
+		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_DBG_ADDR, 63);
+	} else if (!adreno_is_a7xx(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 128);
+
+
+	/* Set the default primFifo threshold values */
+	if (adreno_gpu->info->a6xx->prim_fifo_threshold)
+		gpu_write(gpu, REG_A6XX_PC_DBG_ECO_CNTL,
+			  adreno_gpu->info->a6xx->prim_fifo_threshold);
+
+	/* Set the AHB default slave response to "ERROR" */
+	gpu_write(gpu, REG_A6XX_CP_AHB_CNTL, 0x1);
+
+	/* Turn on performance counters */
+	gpu_write(gpu, REG_A6XX_RBBM_PERFCTR_CNTL, 0x1);
+
+	if (adreno_is_a7xx(adreno_gpu)) {
+		/* Turn on the IFPC counter (countable 4 on XOCLK4) */
+		gmu_write(&a6xx_gpu->gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_SELECT_1,
+			  FIELD_PREP(GENMASK(7, 0), 0x4));
+	}
+
+	/* Select CP0 to always count cycles */
+	gpu_write(gpu, REG_A6XX_CP_PERFCTR_CP_SEL(0), PERF_CP_ALWAYS_COUNT);
+
+	a6xx_set_ubwc_config(gpu);
+
+	/* Enable fault detection */
+	if (adreno_is_a730(adreno_gpu) ||
+	    adreno_is_a740_family(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0xcfffff);
+	else if (adreno_is_a690(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x4fffff);
+	else if (adreno_is_a619(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3fffff);
+	else if (adreno_is_a610(adreno_gpu) || adreno_is_a702(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x3ffff);
+	else
+		gpu_write(gpu, REG_A6XX_RBBM_INTERFACE_HANG_INT_CNTL, (1 << 30) | 0x1fffff);
+
+	gpu_write(gpu, REG_A6XX_UCHE_CLIENT_PF, BIT(7) | 0x1);
+
+	/* Set weights for bicubic filtering */
+	if (adreno_is_a650_family(adreno_gpu) || adreno_is_x185(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_0, 0);
+		gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_1,
+			0x3fe05ff4);
+		gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_2,
+			0x3fa0ebee);
+		gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_3,
+			0x3f5193ed);
+		gpu_write(gpu, REG_A6XX_TPL1_BICUBIC_WEIGHTS_TABLE_4,
+			0x3f0243f0);
+	}
+
+	/* Set up the CX GMU counter 0 to count busy ticks */
+	gmu_write(gmu, REG_A6XX_GPU_GMU_AO_GPU_CX_BUSY_MASK, 0xff000000);
+
+	/* Enable the power counter */
+	gmu_rmw(gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_SELECT_0, 0xff, BIT(5));
+	gmu_write(gmu, REG_A6XX_GMU_CX_GMU_POWER_COUNTER_ENABLE, 1);
+
+	/* Protect registers from the CP */
+	a6xx_set_cp_protect(gpu);
+
+	if (adreno_is_a660_family(adreno_gpu)) {
+		if (adreno_is_a690(adreno_gpu))
+			gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x00028801);
+		else
+			gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, 0x1);
+		gpu_write(gpu, REG_A6XX_RBBM_GBIF_CLIENT_QOS_CNTL, 0x0);
+	} else if (adreno_is_a702(adreno_gpu)) {
+		/* Something to do with the HLSQ cluster */
+		gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, BIT(24));
+	}
+
+	if (adreno_is_a690(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x90);
+	/* Set dualQ + disable afull for A660 GPU */
+	else if (adreno_is_a660(adreno_gpu) || adreno_is_a663(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG, 0x66906);
+	else if (adreno_is_a7xx(adreno_gpu))
+		gpu_write(gpu, REG_A6XX_UCHE_CMDQ_CONFIG,
+			  FIELD_PREP(GENMASK(19, 16), 6) |
+			  FIELD_PREP(GENMASK(15, 12), 6) |
+			  FIELD_PREP(GENMASK(11, 8), 9) |
+			  BIT(3) | BIT(2) |
+			  FIELD_PREP(GENMASK(1, 0), 2));
+
+	/* Enable expanded apriv for targets that support it */
+	if (gpu->hw_apriv) {
+		if (adreno_is_a7xx(adreno_gpu)) {
+			gpu_write(gpu, REG_A6XX_CP_APRIV_CNTL,
+				  A7XX_BR_APRIVMASK);
+			gpu_write(gpu, REG_A7XX_CP_BV_APRIV_CNTL,
+				  A7XX_APRIV_MASK);
+			gpu_write(gpu, REG_A7XX_CP_LPAC_APRIV_CNTL,
+				  A7XX_APRIV_MASK);
+		} else
+			gpu_write(gpu, REG_A6XX_CP_APRIV_CNTL,
+				  BIT(6) | BIT(5) | BIT(3) | BIT(2) | BIT(1));
+	}
+
+	/* Enable interrupts */
+	gpu_write(gpu, REG_A6XX_RBBM_INT_0_MASK,
+		  adreno_is_a7xx(adreno_gpu) ? A7XX_INT_MASK : A6XX_INT_MASK);
+
+	ret = adreno_hw_init(gpu);
+	if (ret)
+		goto out;
+
+	gpu_write64(gpu, REG_A6XX_CP_SQE_INSTR_BASE, a6xx_gpu->sqe_iova);
+
+	/* Set the ringbuffer address */
+	gpu_write64(gpu, REG_A6XX_CP_RB_BASE, gpu->rb[0]->iova);
+
+	/* Targets that support extended APRIV can use the RPTR shadow from
+	 * hardware but all the other ones need to disable the feature. Targets
+	 * that support the WHERE_AM_I opcode can use that instead
+	 */
+	if (adreno_gpu->base.hw_apriv)
+		gpu_write(gpu, REG_A6XX_CP_RB_CNTL, MSM_GPU_RB_CNTL_DEFAULT);
+	else
+		gpu_write(gpu, REG_A6XX_CP_RB_CNTL,
+			MSM_GPU_RB_CNTL_DEFAULT | AXXX_CP_RB_CNTL_NO_UPDATE);
+
+	/* Configure the RPTR shadow if needed: */
+	if (a6xx_gpu->shadow_bo) {
+		gpu_write64(gpu, REG_A6XX_CP_RB_RPTR_ADDR,
+			shadowptr(a6xx_gpu, gpu->rb[0]));
+	}
+
+	/* ..which means "always" on A7xx, also for BV shadow */
+	if (adreno_is_a7xx(adreno_gpu)) {
+		gpu_write64(gpu, REG_A7XX_CP_BV_RB_RPTR_ADDR,
+			    rbmemptr(gpu->rb[0], bv_fence));
+	}
+
+	/* Always come up on rb 0 */
+	a6xx_gpu->cur_ring = gpu->rb[0];
+
+	gpu->cur_ctx_seqno = 0;
+
+	/* Enable the SQE_to start the CP engine */
+	gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 1);
+
+	ret = adreno_is_a7xx(adreno_gpu) ? a7xx_cp_init(gpu) : a6xx_cp_init(gpu);
+	if (ret)
+		goto out;
+
+	/*
+	 * Try to load a zap shader into the secure world. If successful
+	 * we can use the CP to switch out of secure mode. If not then we
+	 * have no resource but to try to switch ourselves out manually. If we
+	 * guessed wrong then access to the RBBM_SECVID_TRUST_CNTL register will
+	 * be blocked and a permissions violation will soon follow.
+	 */
+	ret = a6xx_zap_shader_init(gpu);
+	if (!ret) {
+		OUT_PKT7(gpu->rb[0], CP_SET_SECURE_MODE, 1);
+		OUT_RING(gpu->rb[0], 0x00000000);
+
+		a6xx_flush(gpu, gpu->rb[0]);
+		if (!a6xx_idle(gpu, gpu->rb[0]))
+			return -EINVAL;
+	} else if (ret == -ENODEV) {
+		/*
+		 * This device does not use zap shader (but print a warning
+		 * just in case someone got their dt wrong.. hopefully they
+		 * have a debug UART to realize the error of their ways...
+		 * if you mess this up you are about to crash horribly)
+		 */
+		dev_warn_once(gpu->dev->dev,
+			"Zap shader not enabled - using SECVID_TRUST_CNTL instead\n");
+		gpu_write(gpu, REG_A6XX_RBBM_SECVID_TRUST_CNTL, 0x0);
+		ret = 0;
+	} else {
+		return ret;
+	}
+
+out:
+	if (adreno_has_gmu_wrapper(adreno_gpu))
+		return ret;
+	/*
+	 * Tell the GMU that we are done touching the GPU and it can start power
+	 * management
+	 */
+	a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
+
+	if (a6xx_gpu->gmu.legacy) {
+		/* Take the GMU out of its special boot mode */
+		a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_BOOT_SLUMBER);
+	}
+
+	return ret;
+}
+
+static int a6xx_hw_init(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	int ret;
+
+	mutex_lock(&a6xx_gpu->gmu.lock);
+	ret = hw_init(gpu);
+	mutex_unlock(&a6xx_gpu->gmu.lock);
+
+	return ret;
+}
+
+static void a6xx_dump(struct msm_gpu *gpu)
+{
+	DRM_DEV_INFO(&gpu->pdev->dev, "status:   %08x\n",
+			gpu_read(gpu, REG_A6XX_RBBM_STATUS));
+	adreno_dump(gpu);
+}
+
+static void a6xx_recover(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+	int i, active_submits;
+
+	adreno_dump_info(gpu);
+
+	for (i = 0; i < 8; i++)
+		DRM_DEV_INFO(&gpu->pdev->dev, "CP_SCRATCH_REG%d: %u\n", i,
+			gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(i)));
+
+	if (hang_debug)
+		a6xx_dump(gpu);
+
+	/*
+	 * To handle recovery specific sequences during the rpm suspend we are
+	 * about to trigger
+	 */
+	a6xx_gpu->hung = true;
+
+	/* Halt SQE first */
+	gpu_write(gpu, REG_A6XX_CP_SQE_CNTL, 3);
+
+	pm_runtime_dont_use_autosuspend(&gpu->pdev->dev);
+
+	/* active_submit won't change until we make a submission */
+	mutex_lock(&gpu->active_lock);
+	active_submits = gpu->active_submits;
+
+	/*
+	 * Temporarily clear active_submits count to silence a WARN() in the
+	 * runtime suspend cb
+	 */
+	gpu->active_submits = 0;
+
+	if (adreno_has_gmu_wrapper(adreno_gpu)) {
+		/* Drain the outstanding traffic on memory buses */
+		a6xx_bus_clear_pending_transactions(adreno_gpu, true);
+
+		/* Reset the GPU to a clean state */
+		a6xx_gpu_sw_reset(gpu, true);
+		a6xx_gpu_sw_reset(gpu, false);
+	}
+
+	reinit_completion(&gmu->pd_gate);
+	dev_pm_genpd_add_notifier(gmu->cxpd, &gmu->pd_nb);
+	dev_pm_genpd_synced_poweroff(gmu->cxpd);
+
+	/* Drop the rpm refcount from active submits */
+	if (active_submits)
+		pm_runtime_put(&gpu->pdev->dev);
+
+	/* And the final one from recover worker */
+	pm_runtime_put_sync(&gpu->pdev->dev);
+
+	if (!wait_for_completion_timeout(&gmu->pd_gate, msecs_to_jiffies(1000)))
+		DRM_DEV_ERROR(&gpu->pdev->dev, "cx gdsc didn't collapse\n");
+
+	dev_pm_genpd_remove_notifier(gmu->cxpd);
+
+	pm_runtime_use_autosuspend(&gpu->pdev->dev);
+
+	if (active_submits)
+		pm_runtime_get(&gpu->pdev->dev);
+
+	pm_runtime_get_sync(&gpu->pdev->dev);
+
+	gpu->active_submits = active_submits;
+	mutex_unlock(&gpu->active_lock);
+
+	msm_gpu_hw_init(gpu);
+	a6xx_gpu->hung = false;
+}
+
+static const char *a6xx_uche_fault_block(struct msm_gpu *gpu, u32 mid)
+{
+	static const char *uche_clients[7] = {
+		"VFD", "SP", "VSC", "VPC", "HLSQ", "PC", "LRZ",
+	};
+	u32 val;
+
+	if (mid < 1 || mid > 3)
+		return "UNKNOWN";
+
+	/*
+	 * The source of the data depends on the mid ID read from FSYNR1.
+	 * and the client ID read from the UCHE block
+	 */
+	val = gpu_read(gpu, REG_A6XX_UCHE_CLIENT_PF);
+
+	/* mid = 3 is most precise and refers to only one block per client */
+	if (mid == 3)
+		return uche_clients[val & 7];
+
+	/* For mid=2 the source is TP or VFD except when the client id is 0 */
+	if (mid == 2)
+		return ((val & 7) == 0) ? "TP" : "TP|VFD";
+
+	/* For mid=1 just return "UCHE" as a catchall for everything else */
+	return "UCHE";
+}
+
+static const char *a6xx_fault_block(struct msm_gpu *gpu, u32 id)
+{
+	if (id == 0)
+		return "CP";
+	else if (id == 4)
+		return "CCU";
+	else if (id == 6)
+		return "CDP Prefetch";
+
+	return a6xx_uche_fault_block(gpu, id);
+}
+
+static int a6xx_fault_handler(void *arg, unsigned long iova, int flags, void *data)
+{
+	struct msm_gpu *gpu = arg;
+	struct adreno_smmu_fault_info *info = data;
+	const char *block = "unknown";
+
+	u32 scratch[] = {
+			gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(4)),
+			gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(5)),
+			gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(6)),
+			gpu_read(gpu, REG_A6XX_CP_SCRATCH_REG(7)),
+	};
+
+	if (info)
+		block = a6xx_fault_block(gpu, info->fsynr1 & 0xff);
+
+	return adreno_fault_handler(gpu, iova, flags, info, block, scratch);
+}
+
+static void a6xx_cp_hw_err_irq(struct msm_gpu *gpu)
+{
+	u32 status = gpu_read(gpu, REG_A6XX_CP_INTERRUPT_STATUS);
+
+	if (status & A6XX_CP_INT_CP_OPCODE_ERROR) {
+		u32 val;
+
+		gpu_write(gpu, REG_A6XX_CP_SQE_STAT_ADDR, 1);
+		val = gpu_read(gpu, REG_A6XX_CP_SQE_STAT_DATA);
+		dev_err_ratelimited(&gpu->pdev->dev,
+			"CP | opcode error | possible opcode=0x%8.8X\n",
+			val);
+	}
+
+	if (status & A6XX_CP_INT_CP_UCODE_ERROR)
+		dev_err_ratelimited(&gpu->pdev->dev,
+			"CP ucode error interrupt\n");
+
+	if (status & A6XX_CP_INT_CP_HW_FAULT_ERROR)
+		dev_err_ratelimited(&gpu->pdev->dev, "CP | HW fault | status=0x%8.8X\n",
+			gpu_read(gpu, REG_A6XX_CP_HW_FAULT));
+
+	if (status & A6XX_CP_INT_CP_REGISTER_PROTECTION_ERROR) {
+		u32 val = gpu_read(gpu, REG_A6XX_CP_PROTECT_STATUS);
+
+		dev_err_ratelimited(&gpu->pdev->dev,
+			"CP | protected mode error | %s | addr=0x%8.8X | status=0x%8.8X\n",
+			val & (1 << 20) ? "READ" : "WRITE",
+			(val & 0x3ffff), val);
+	}
+
+	if (status & A6XX_CP_INT_CP_AHB_ERROR && !adreno_is_a7xx(to_adreno_gpu(gpu)))
+		dev_err_ratelimited(&gpu->pdev->dev, "CP AHB error interrupt\n");
+
+	if (status & A6XX_CP_INT_CP_VSD_PARITY_ERROR)
+		dev_err_ratelimited(&gpu->pdev->dev, "CP VSD decoder parity error\n");
+
+	if (status & A6XX_CP_INT_CP_ILLEGAL_INSTR_ERROR)
+		dev_err_ratelimited(&gpu->pdev->dev, "CP illegal instruction error\n");
+
+}
+
+static void a6xx_fault_detect_irq(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	struct msm_ringbuffer *ring = gpu->funcs->active_ring(gpu);
+
+	/*
+	 * If stalled on SMMU fault, we could trip the GPU's hang detection,
+	 * but the fault handler will trigger the devcore dump, and we want
+	 * to otherwise resume normally rather than killing the submit, so
+	 * just bail.
+	 */
+	if (gpu_read(gpu, REG_A6XX_RBBM_STATUS3) & A6XX_RBBM_STATUS3_SMMU_STALLED_ON_FAULT)
+		return;
+
+	/*
+	 * Force the GPU to stay on until after we finish
+	 * collecting information
+	 */
+	if (!adreno_has_gmu_wrapper(adreno_gpu))
+		gmu_write(&a6xx_gpu->gmu, REG_A6XX_GMU_GMU_PWR_COL_KEEPALIVE, 1);
+
+	DRM_DEV_ERROR(&gpu->pdev->dev,
+		"gpu fault ring %d fence %x status %8.8X rb %4.4x/%4.4x ib1 %16.16llX/%4.4x ib2 %16.16llX/%4.4x\n",
+		ring ? ring->id : -1, ring ? ring->fctx->last_fence : 0,
+		gpu_read(gpu, REG_A6XX_RBBM_STATUS),
+		gpu_read(gpu, REG_A6XX_CP_RB_RPTR),
+		gpu_read(gpu, REG_A6XX_CP_RB_WPTR),
+		gpu_read64(gpu, REG_A6XX_CP_IB1_BASE),
+		gpu_read(gpu, REG_A6XX_CP_IB1_REM_SIZE),
+		gpu_read64(gpu, REG_A6XX_CP_IB2_BASE),
+		gpu_read(gpu, REG_A6XX_CP_IB2_REM_SIZE));
+
+	/* Turn off the hangcheck timer to keep it from bothering us */
+	del_timer(&gpu->hangcheck_timer);
+
+	kthread_queue_work(gpu->worker, &gpu->recover_work);
+}
+
+static irqreturn_t a6xx_irq(struct msm_gpu *gpu)
+{
+	struct msm_drm_private *priv = gpu->dev->dev_private;
+	u32 status = gpu_read(gpu, REG_A6XX_RBBM_INT_0_STATUS);
+
+	gpu_write(gpu, REG_A6XX_RBBM_INT_CLEAR_CMD, status);
+
+	if (priv->disable_err_irq)
+		status &= A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS;
+
+	if (status & A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT)
+		a6xx_fault_detect_irq(gpu);
+
+	if (status & A6XX_RBBM_INT_0_MASK_CP_AHB_ERROR)
+		dev_err_ratelimited(&gpu->pdev->dev, "CP | AHB bus error\n");
+
+	if (status & A6XX_RBBM_INT_0_MASK_CP_HW_ERROR)
+		a6xx_cp_hw_err_irq(gpu);
+
+	if (status & A6XX_RBBM_INT_0_MASK_RBBM_ATB_ASYNCFIFO_OVERFLOW)
+		dev_err_ratelimited(&gpu->pdev->dev, "RBBM | ATB ASYNC overflow\n");
+
+	if (status & A6XX_RBBM_INT_0_MASK_RBBM_ATB_BUS_OVERFLOW)
+		dev_err_ratelimited(&gpu->pdev->dev, "RBBM | ATB bus overflow\n");
+
+	if (status & A6XX_RBBM_INT_0_MASK_UCHE_OOB_ACCESS)
+		dev_err_ratelimited(&gpu->pdev->dev, "UCHE | Out of bounds access\n");
+
+	if (status & A6XX_RBBM_INT_0_MASK_CP_CACHE_FLUSH_TS)
+		msm_gpu_retire(gpu);
+
+	return IRQ_HANDLED;
+}
+
+static void a6xx_llc_deactivate(struct a6xx_gpu *a6xx_gpu)
+{
+	llcc_slice_deactivate(a6xx_gpu->llc_slice);
+	llcc_slice_deactivate(a6xx_gpu->htw_llc_slice);
+}
+
+static void a6xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
+{
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	struct msm_gpu *gpu = &adreno_gpu->base;
+	u32 cntl1_regval = 0;
+
+	if (IS_ERR(a6xx_gpu->llc_mmio))
+		return;
+
+	if (!llcc_slice_activate(a6xx_gpu->llc_slice)) {
+		u32 gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice);
+
+		gpu_scid &= 0x1f;
+		cntl1_regval = (gpu_scid << 0) | (gpu_scid << 5) | (gpu_scid << 10) |
+			       (gpu_scid << 15) | (gpu_scid << 20);
+
+		/* On A660, the SCID programming for UCHE traffic is done in
+		 * A6XX_GBIF_SCACHE_CNTL0[14:10]
+		 */
+		if (adreno_is_a660_family(adreno_gpu))
+			gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL0, (0x1f << 10) |
+				(1 << 8), (gpu_scid << 10) | (1 << 8));
+	}
+
+	/*
+	 * For targets with a MMU500, activate the slice but don't program the
+	 * register.  The XBL will take care of that.
+	 */
+	if (!llcc_slice_activate(a6xx_gpu->htw_llc_slice)) {
+		if (!a6xx_gpu->have_mmu500) {
+			u32 gpuhtw_scid = llcc_get_slice_id(a6xx_gpu->htw_llc_slice);
+
+			gpuhtw_scid &= 0x1f;
+			cntl1_regval |= FIELD_PREP(GENMASK(29, 25), gpuhtw_scid);
+		}
+	}
+
+	if (!cntl1_regval)
+		return;
+
+	/*
+	 * Program the slice IDs for the various GPU blocks and GPU MMU
+	 * pagetables
+	 */
+	if (!a6xx_gpu->have_mmu500) {
+		a6xx_llc_write(a6xx_gpu,
+			REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_1, cntl1_regval);
+
+		/*
+		 * Program cacheability overrides to not allocate cache
+		 * lines on a write miss
+		 */
+		a6xx_llc_rmw(a6xx_gpu,
+			REG_A6XX_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF, 0x03);
+		return;
+	}
+
+	gpu_rmw(gpu, REG_A6XX_GBIF_SCACHE_CNTL1, GENMASK(24, 0), cntl1_regval);
+}
+
+static void a7xx_llc_activate(struct a6xx_gpu *a6xx_gpu)
+{
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+	struct msm_gpu *gpu = &adreno_gpu->base;
+
+	if (IS_ERR(a6xx_gpu->llc_mmio))
+		return;
+
+	if (!llcc_slice_activate(a6xx_gpu->llc_slice)) {
+		u32 gpu_scid = llcc_get_slice_id(a6xx_gpu->llc_slice);
+
+		gpu_scid &= GENMASK(4, 0);
+
+		gpu_write(gpu, REG_A6XX_GBIF_SCACHE_CNTL1,
+			  FIELD_PREP(GENMASK(29, 25), gpu_scid) |
+			  FIELD_PREP(GENMASK(24, 20), gpu_scid) |
+			  FIELD_PREP(GENMASK(19, 15), gpu_scid) |
+			  FIELD_PREP(GENMASK(14, 10), gpu_scid) |
+			  FIELD_PREP(GENMASK(9, 5), gpu_scid) |
+			  FIELD_PREP(GENMASK(4, 0), gpu_scid));
+
+		gpu_write(gpu, REG_A6XX_GBIF_SCACHE_CNTL0,
+			  FIELD_PREP(GENMASK(14, 10), gpu_scid) |
+			  BIT(8));
+	}
+
+	llcc_slice_activate(a6xx_gpu->htw_llc_slice);
+}
+
+static void a6xx_llc_slices_destroy(struct a6xx_gpu *a6xx_gpu)
+{
+	/* No LLCC on non-RPMh (and by extension, non-GMU) SoCs */
+	if (adreno_has_gmu_wrapper(&a6xx_gpu->base))
+		return;
+
+	llcc_slice_putd(a6xx_gpu->llc_slice);
+	llcc_slice_putd(a6xx_gpu->htw_llc_slice);
+}
+
+static void a6xx_llc_slices_init(struct platform_device *pdev,
+		struct a6xx_gpu *a6xx_gpu, bool is_a7xx)
+{
+	struct device_node *phandle;
+
+	/* No LLCC on non-RPMh (and by extension, non-GMU) SoCs */
+	if (adreno_has_gmu_wrapper(&a6xx_gpu->base))
+		return;
+
+	/*
+	 * There is a different programming path for A6xx targets with an
+	 * mmu500 attached, so detect if that is the case
+	 */
+	phandle = of_parse_phandle(pdev->dev.of_node, "iommus", 0);
+	a6xx_gpu->have_mmu500 = (phandle &&
+		of_device_is_compatible(phandle, "arm,mmu-500"));
+	of_node_put(phandle);
+
+	if (is_a7xx || !a6xx_gpu->have_mmu500)
+		a6xx_gpu->llc_mmio = msm_ioremap(pdev, "cx_mem");
+	else
+		a6xx_gpu->llc_mmio = NULL;
+
+	a6xx_gpu->llc_slice = llcc_slice_getd(LLCC_GPU);
+	a6xx_gpu->htw_llc_slice = llcc_slice_getd(LLCC_GPUHTW);
+
+	if (IS_ERR_OR_NULL(a6xx_gpu->llc_slice) && IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice))
+		a6xx_gpu->llc_mmio = ERR_PTR(-EINVAL);
+}
+
+#define GBIF_CLIENT_HALT_MASK		BIT(0)
+#define GBIF_ARB_HALT_MASK		BIT(1)
+#define VBIF_XIN_HALT_CTRL0_MASK	GENMASK(3, 0)
+#define VBIF_RESET_ACK_MASK		0xF0
+#define GPR0_GBIF_HALT_REQUEST		0x1E0
+
+void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_off)
+{
+	struct msm_gpu *gpu = &adreno_gpu->base;
+
+	if (adreno_is_a619_holi(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_RBBM_GPR0_CNTL, GPR0_GBIF_HALT_REQUEST);
+		spin_until((gpu_read(gpu, REG_A6XX_RBBM_VBIF_GX_RESET_STATUS) &
+				(VBIF_RESET_ACK_MASK)) == VBIF_RESET_ACK_MASK);
+	} else if (!a6xx_has_gbif(adreno_gpu)) {
+		gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, VBIF_XIN_HALT_CTRL0_MASK);
+		spin_until((gpu_read(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL1) &
+				(VBIF_XIN_HALT_CTRL0_MASK)) == VBIF_XIN_HALT_CTRL0_MASK);
+		gpu_write(gpu, REG_A6XX_VBIF_XIN_HALT_CTRL0, 0);
+
+		return;
+	}
+
+	if (gx_off) {
+		/* Halt the gx side of GBIF */
+		gpu_write(gpu, REG_A6XX_RBBM_GBIF_HALT, 1);
+		spin_until(gpu_read(gpu, REG_A6XX_RBBM_GBIF_HALT_ACK) & 1);
+	}
+
+	/* Halt new client requests on GBIF */
+	gpu_write(gpu, REG_A6XX_GBIF_HALT, GBIF_CLIENT_HALT_MASK);
+	spin_until((gpu_read(gpu, REG_A6XX_GBIF_HALT_ACK) &
+			(GBIF_CLIENT_HALT_MASK)) == GBIF_CLIENT_HALT_MASK);
+
+	/* Halt all AXI requests on GBIF */
+	gpu_write(gpu, REG_A6XX_GBIF_HALT, GBIF_ARB_HALT_MASK);
+	spin_until((gpu_read(gpu,  REG_A6XX_GBIF_HALT_ACK) &
+			(GBIF_ARB_HALT_MASK)) == GBIF_ARB_HALT_MASK);
+
+	/* The GBIF halt needs to be explicitly cleared */
+	gpu_write(gpu, REG_A6XX_GBIF_HALT, 0x0);
+}
+
+void a6xx_gpu_sw_reset(struct msm_gpu *gpu, bool assert)
+{
+	/* 11nm chips (e.g. ones with A610) have hw issues with the reset line! */
+	if (adreno_is_a610(to_adreno_gpu(gpu)))
+		return;
+
+	gpu_write(gpu, REG_A6XX_RBBM_SW_RESET_CMD, assert);
+	/* Perform a bogus read and add a brief delay to ensure ordering. */
+	gpu_read(gpu, REG_A6XX_RBBM_SW_RESET_CMD);
+	udelay(1);
+
+	/* The reset line needs to be asserted for at least 100 us */
+	if (assert)
+		udelay(100);
+}
+
+static int a6xx_gmu_pm_resume(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	int ret;
+
+	gpu->needs_hw_init = true;
+
+	trace_msm_gpu_resume(0);
+
+	mutex_lock(&a6xx_gpu->gmu.lock);
+	ret = a6xx_gmu_resume(a6xx_gpu);
+	mutex_unlock(&a6xx_gpu->gmu.lock);
+	if (ret)
+		return ret;
+
+	msm_devfreq_resume(gpu);
+
+	adreno_is_a7xx(adreno_gpu) ? a7xx_llc_activate(a6xx_gpu) : a6xx_llc_activate(a6xx_gpu);
+
+	return ret;
+}
+
+static int a6xx_pm_resume(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+	unsigned long freq = gpu->fast_rate;
+	struct dev_pm_opp *opp;
+	int ret;
+
+	gpu->needs_hw_init = true;
+
+	trace_msm_gpu_resume(0);
+
+	mutex_lock(&a6xx_gpu->gmu.lock);
+
+	opp = dev_pm_opp_find_freq_ceil(&gpu->pdev->dev, &freq);
+	if (IS_ERR(opp)) {
+		ret = PTR_ERR(opp);
+		goto err_set_opp;
+	}
+	dev_pm_opp_put(opp);
+
+	/* Set the core clock and bus bw, having VDD scaling in mind */
+	dev_pm_opp_set_opp(&gpu->pdev->dev, opp);
+
+	pm_runtime_resume_and_get(gmu->dev);
+	pm_runtime_resume_and_get(gmu->gxpd);
+
+	ret = clk_bulk_prepare_enable(gpu->nr_clocks, gpu->grp_clks);
+	if (ret)
+		goto err_bulk_clk;
+
+	if (adreno_is_a619_holi(adreno_gpu))
+		a6xx_sptprac_enable(gmu);
+
+	/* If anything goes south, tear the GPU down piece by piece.. */
+	if (ret) {
+err_bulk_clk:
+		pm_runtime_put(gmu->gxpd);
+		pm_runtime_put(gmu->dev);
+		dev_pm_opp_set_opp(&gpu->pdev->dev, NULL);
+	}
+err_set_opp:
+	mutex_unlock(&a6xx_gpu->gmu.lock);
+
+	if (!ret)
+		msm_devfreq_resume(gpu);
+
+	return ret;
+}
+
+static int a6xx_gmu_pm_suspend(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	int i, ret;
+
+	trace_msm_gpu_suspend(0);
+
+	a6xx_llc_deactivate(a6xx_gpu);
+
+	msm_devfreq_suspend(gpu);
+
+	mutex_lock(&a6xx_gpu->gmu.lock);
+	ret = a6xx_gmu_stop(a6xx_gpu);
+	mutex_unlock(&a6xx_gpu->gmu.lock);
+	if (ret)
+		return ret;
+
+	if (a6xx_gpu->shadow_bo)
+		for (i = 0; i < gpu->nr_rings; i++)
+			a6xx_gpu->shadow[i] = 0;
+
+	gpu->suspend_count++;
+
+	return 0;
+}
+
+static int a6xx_pm_suspend(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+	int i;
+
+	trace_msm_gpu_suspend(0);
+
+	msm_devfreq_suspend(gpu);
+
+	mutex_lock(&a6xx_gpu->gmu.lock);
+
+	/* Drain the outstanding traffic on memory buses */
+	a6xx_bus_clear_pending_transactions(adreno_gpu, true);
+
+	if (adreno_is_a619_holi(adreno_gpu))
+		a6xx_sptprac_disable(gmu);
+
+	clk_bulk_disable_unprepare(gpu->nr_clocks, gpu->grp_clks);
+
+	pm_runtime_put_sync(gmu->gxpd);
+	dev_pm_opp_set_opp(&gpu->pdev->dev, NULL);
+	pm_runtime_put_sync(gmu->dev);
+
+	mutex_unlock(&a6xx_gpu->gmu.lock);
+
+	if (a6xx_gpu->shadow_bo)
+		for (i = 0; i < gpu->nr_rings; i++)
+			a6xx_gpu->shadow[i] = 0;
+
+	gpu->suspend_count++;
+
+	return 0;
+}
+
+static int a6xx_gmu_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+
+	mutex_lock(&a6xx_gpu->gmu.lock);
+
+	/* Force the GPU power on so we can read this register */
+	a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);
+
+	*value = gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER);
+
+	a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_PERFCOUNTER_SET);
+
+	mutex_unlock(&a6xx_gpu->gmu.lock);
+
+	return 0;
+}
+
+static int a6xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
+{
+	*value = gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER);
+	return 0;
+}
+
+static struct msm_ringbuffer *a6xx_active_ring(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+
+	return a6xx_gpu->cur_ring;
+}
+
+static void a6xx_destroy(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+
+	if (a6xx_gpu->sqe_bo) {
+		msm_gem_unpin_iova(a6xx_gpu->sqe_bo, gpu->aspace);
+		drm_gem_object_put(a6xx_gpu->sqe_bo);
+	}
+
+	if (a6xx_gpu->shadow_bo) {
+		msm_gem_unpin_iova(a6xx_gpu->shadow_bo, gpu->aspace);
+		drm_gem_object_put(a6xx_gpu->shadow_bo);
+	}
+
+	a6xx_llc_slices_destroy(a6xx_gpu);
+
+	a6xx_gmu_remove(a6xx_gpu);
+
+	adreno_gpu_cleanup(adreno_gpu);
+
+	kfree(a6xx_gpu);
+}
+
+static u64 a6xx_gpu_busy(struct msm_gpu *gpu, unsigned long *out_sample_rate)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	u64 busy_cycles;
+
+	/* 19.2MHz */
+	*out_sample_rate = 19200000;
+
+	busy_cycles = gmu_read64(&a6xx_gpu->gmu,
+			REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L,
+			REG_A6XX_GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H);
+
+	return busy_cycles;
+}
+
+static void a6xx_gpu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp,
+			      bool suspended)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+
+	mutex_lock(&a6xx_gpu->gmu.lock);
+	a6xx_gmu_set_freq(gpu, opp, suspended);
+	mutex_unlock(&a6xx_gpu->gmu.lock);
+}
+
+static struct msm_gem_address_space *
+a6xx_create_address_space(struct msm_gpu *gpu, struct platform_device *pdev)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	unsigned long quirks = 0;
+
+	/*
+	 * This allows GPU to set the bus attributes required to use system
+	 * cache on behalf of the iommu page table walker.
+	 */
+	if (!IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice) &&
+	    !device_iommu_capable(&pdev->dev, IOMMU_CAP_CACHE_COHERENCY))
+		quirks |= IO_PGTABLE_QUIRK_ARM_OUTER_WBWA;
+
+	return adreno_iommu_create_address_space(gpu, pdev, quirks);
+}
+
+static struct msm_gem_address_space *
+a6xx_create_private_address_space(struct msm_gpu *gpu)
+{
+	struct msm_mmu *mmu;
+
+	mmu = msm_iommu_pagetable_create(gpu->aspace->mmu);
+
+	if (IS_ERR(mmu))
+		return ERR_CAST(mmu);
+
+	return msm_gem_address_space_create(mmu,
+		"gpu", 0x100000000ULL,
+		adreno_private_address_space_size(gpu));
+}
+
+static uint32_t a6xx_get_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+
+	if (adreno_gpu->base.hw_apriv || a6xx_gpu->has_whereami)
+		return a6xx_gpu->shadow[ring->id];
+
+	return ring->memptrs->rptr = gpu_read(gpu, REG_A6XX_CP_RB_RPTR);
+}
+
+static bool a6xx_progress(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+	struct msm_cp_state cp_state = {
+		.ib1_base = gpu_read64(gpu, REG_A6XX_CP_IB1_BASE),
+		.ib2_base = gpu_read64(gpu, REG_A6XX_CP_IB2_BASE),
+		.ib1_rem  = gpu_read(gpu, REG_A6XX_CP_IB1_REM_SIZE),
+		.ib2_rem  = gpu_read(gpu, REG_A6XX_CP_IB2_REM_SIZE),
+	};
+	bool progress;
+
+	/*
+	 * Adjust the remaining data to account for what has already been
+	 * fetched from memory, but not yet consumed by the SQE.
+	 *
+	 * This is not *technically* correct, the amount buffered could
+	 * exceed the IB size due to hw prefetching ahead, but:
+	 *
+	 * (1) We aren't trying to find the exact position, just whether
+	 *     progress has been made
+	 * (2) The CP_REG_TO_MEM at the end of a submit should be enough
+	 *     to prevent prefetching into an unrelated submit.  (And
+	 *     either way, at some point the ROQ will be full.)
+	 */
+	cp_state.ib1_rem += gpu_read(gpu, REG_A6XX_CP_ROQ_AVAIL_IB1) >> 16;
+	cp_state.ib2_rem += gpu_read(gpu, REG_A6XX_CP_ROQ_AVAIL_IB2) >> 16;
+
+	progress = !!memcmp(&cp_state, &ring->last_cp_state, sizeof(cp_state));
+
+	ring->last_cp_state = cp_state;
+
+	return progress;
+}
+
+static u32 fuse_to_supp_hw(const struct adreno_info *info, u32 fuse)
+{
+	if (!info->speedbins)
+		return UINT_MAX;
+
+	for (int i = 0; info->speedbins[i].fuse != SHRT_MAX; i++)
+		if (info->speedbins[i].fuse == fuse)
+			return BIT(info->speedbins[i].speedbin);
+
+	return UINT_MAX;
+}
+
+static int a6xx_set_supported_hw(struct device *dev, const struct adreno_info *info)
+{
+	u32 supp_hw;
+	u32 speedbin;
+	int ret;
+
+	ret = adreno_read_speedbin(dev, &speedbin);
+	/*
+	 * -ENOENT means that the platform doesn't support speedbin which is
+	 * fine
+	 */
+	if (ret == -ENOENT) {
+		return 0;
+	} else if (ret) {
+		dev_err_probe(dev, ret,
+			      "failed to read speed-bin. Some OPPs may not be supported by hardware\n");
+		return ret;
+	}
+
+	supp_hw = fuse_to_supp_hw(info, speedbin);
+
+	if (supp_hw == UINT_MAX) {
+		DRM_DEV_ERROR(dev,
+			"missing support for speed-bin: %u. Some OPPs may not be supported by hardware\n",
+			speedbin);
+		supp_hw = BIT(0); /* Default */
+	}
+
+	ret = devm_pm_opp_set_supported_hw(dev, &supp_hw, 1);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static const struct adreno_gpu_funcs funcs = {
+	.base = {
+		.get_param = adreno_get_param,
+		.set_param = adreno_set_param,
+		.hw_init = a6xx_hw_init,
+		.ucode_load = a6xx_ucode_load,
+		.pm_suspend = a6xx_gmu_pm_suspend,
+		.pm_resume = a6xx_gmu_pm_resume,
+		.recover = a6xx_recover,
+		.submit = a6xx_submit,
+		.active_ring = a6xx_active_ring,
+		.irq = a6xx_irq,
+		.destroy = a6xx_destroy,
+#if defined(CONFIG_DRM_MSM_GPU_STATE)
+		.show = a6xx_show,
+#endif
+		.gpu_busy = a6xx_gpu_busy,
+		.gpu_get_freq = a6xx_gmu_get_freq,
+		.gpu_set_freq = a6xx_gpu_set_freq,
+#if defined(CONFIG_DRM_MSM_GPU_STATE)
+		.gpu_state_get = a6xx_gpu_state_get,
+		.gpu_state_put = a6xx_gpu_state_put,
+#endif
+		.create_address_space = a6xx_create_address_space,
+		.create_private_address_space = a6xx_create_private_address_space,
+		.get_rptr = a6xx_get_rptr,
+		.progress = a6xx_progress,
+	},
+	.get_timestamp = a6xx_gmu_get_timestamp,
+};
+
+static const struct adreno_gpu_funcs funcs_gmuwrapper = {
+	.base = {
+		.get_param = adreno_get_param,
+		.set_param = adreno_set_param,
+		.hw_init = a6xx_hw_init,
+		.ucode_load = a6xx_ucode_load,
+		.pm_suspend = a6xx_pm_suspend,
+		.pm_resume = a6xx_pm_resume,
+		.recover = a6xx_recover,
+		.submit = a6xx_submit,
+		.active_ring = a6xx_active_ring,
+		.irq = a6xx_irq,
+		.destroy = a6xx_destroy,
+#if defined(CONFIG_DRM_MSM_GPU_STATE)
+		.show = a6xx_show,
+#endif
+		.gpu_busy = a6xx_gpu_busy,
+#if defined(CONFIG_DRM_MSM_GPU_STATE)
+		.gpu_state_get = a6xx_gpu_state_get,
+		.gpu_state_put = a6xx_gpu_state_put,
+#endif
+		.create_address_space = a6xx_create_address_space,
+		.create_private_address_space = a6xx_create_private_address_space,
+		.get_rptr = a6xx_get_rptr,
+		.progress = a6xx_progress,
+	},
+	.get_timestamp = a6xx_get_timestamp,
+};
+
+static const struct adreno_gpu_funcs funcs_a7xx = {
+	.base = {
+		.get_param = adreno_get_param,
+		.set_param = adreno_set_param,
+		.hw_init = a6xx_hw_init,
+		.ucode_load = a6xx_ucode_load,
+		.pm_suspend = a6xx_gmu_pm_suspend,
+		.pm_resume = a6xx_gmu_pm_resume,
+		.recover = a6xx_recover,
+		.submit = a7xx_submit,
+		.active_ring = a6xx_active_ring,
+		.irq = a6xx_irq,
+		.destroy = a6xx_destroy,
+#if defined(CONFIG_DRM_MSM_GPU_STATE)
+		.show = a6xx_show,
+#endif
+		.gpu_busy = a6xx_gpu_busy,
+		.gpu_get_freq = a6xx_gmu_get_freq,
+		.gpu_set_freq = a6xx_gpu_set_freq,
+#if defined(CONFIG_DRM_MSM_GPU_STATE)
+		.gpu_state_get = a6xx_gpu_state_get,
+		.gpu_state_put = a6xx_gpu_state_put,
+#endif
+		.create_address_space = a6xx_create_address_space,
+		.create_private_address_space = a6xx_create_private_address_space,
+		.get_rptr = a6xx_get_rptr,
+		.progress = a6xx_progress,
+	},
+	.get_timestamp = a6xx_gmu_get_timestamp,
+};
+
+struct msm_gpu *a6xx_gpu_init(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct platform_device *pdev = priv->gpu_pdev;
+	struct adreno_platform_config *config = pdev->dev.platform_data;
+	struct device_node *node;
+	struct a6xx_gpu *a6xx_gpu;
+	struct adreno_gpu *adreno_gpu;
+	struct msm_gpu *gpu;
+	bool is_a7xx;
+	int ret;
+
+	a6xx_gpu = kzalloc(sizeof(*a6xx_gpu), GFP_KERNEL);
+	if (!a6xx_gpu)
+		return ERR_PTR(-ENOMEM);
+
+	adreno_gpu = &a6xx_gpu->base;
+	gpu = &adreno_gpu->base;
+
+	mutex_init(&a6xx_gpu->gmu.lock);
+
+	adreno_gpu->registers = NULL;
+
+	/* Check if there is a GMU phandle and set it up */
+	node = of_parse_phandle(pdev->dev.of_node, "qcom,gmu", 0);
+	/* FIXME: How do we gracefully handle this? */
+	BUG_ON(!node);
+
+	adreno_gpu->gmu_is_wrapper = of_device_is_compatible(node, "qcom,adreno-gmu-wrapper");
+
+	adreno_gpu->base.hw_apriv =
+		!!(config->info->quirks & ADRENO_QUIRK_HAS_HW_APRIV);
+
+	/* gpu->info only gets assigned in adreno_gpu_init() */
+	is_a7xx = config->info->family == ADRENO_7XX_GEN1 ||
+		  config->info->family == ADRENO_7XX_GEN2 ||
+		  config->info->family == ADRENO_7XX_GEN3;
+
+	a6xx_llc_slices_init(pdev, a6xx_gpu, is_a7xx);
+
+	ret = a6xx_set_supported_hw(&pdev->dev, config->info);
+	if (ret) {
+		a6xx_llc_slices_destroy(a6xx_gpu);
+		kfree(a6xx_gpu);
+		return ERR_PTR(ret);
+	}
+
+	if (is_a7xx)
+		ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs_a7xx, 1);
+	else if (adreno_has_gmu_wrapper(adreno_gpu))
+		ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs_gmuwrapper, 1);
+	else
+		ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1);
+	if (ret) {
+		a6xx_destroy(&(a6xx_gpu->base.base));
+		return ERR_PTR(ret);
+	}
+
+	/*
+	 * For now only clamp to idle freq for devices where this is known not
+	 * to cause power supply issues:
+	 */
+	if (adreno_is_a618(adreno_gpu) || adreno_is_7c3(adreno_gpu))
+		priv->gpu_clamp_to_idle = true;
+
+	if (adreno_has_gmu_wrapper(adreno_gpu))
+		ret = a6xx_gmu_wrapper_init(a6xx_gpu, node);
+	else
+		ret = a6xx_gmu_init(a6xx_gpu, node);
+	of_node_put(node);
+	if (ret) {
+		a6xx_destroy(&(a6xx_gpu->base.base));
+		return ERR_PTR(ret);
+	}
+
+	if (gpu->aspace)
+		msm_mmu_set_fault_handler(gpu->aspace->mmu, gpu,
+				a6xx_fault_handler);
+
+	a6xx_calc_ubwc_config(adreno_gpu);
+
+	return gpu;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a6xx_gpu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a6xx_gpu.h
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2017, 2019 The Linux Foundation. All rights reserved. */
+
+#ifndef __A6XX_GPU_H__
+#define __A6XX_GPU_H__
+
+
+#include "adreno_gpu.h"
+#include "a6xx.xml.h"
+
+#include "a6xx_gmu.h"
+
+extern bool hang_debug;
+
+/**
+ * struct a6xx_info - a6xx specific information from device table
+ *
+ * @hwcg: hw clock gating register sequence
+ * @protect: CP_PROTECT settings
+ */
+struct a6xx_info {
+	const struct adreno_reglist *hwcg;
+	const struct adreno_protect *protect;
+	u32 gmu_chipid;
+	u32 gmu_cgc_mode;
+	u32 prim_fifo_threshold;
+};
+
+struct a6xx_gpu {
+	struct adreno_gpu base;
+
+	struct drm_gem_object *sqe_bo;
+	uint64_t sqe_iova;
+
+	struct msm_ringbuffer *cur_ring;
+
+	struct a6xx_gmu gmu;
+
+	struct drm_gem_object *shadow_bo;
+	uint64_t shadow_iova;
+	uint32_t *shadow;
+
+	bool has_whereami;
+
+	void __iomem *llc_mmio;
+	void *llc_slice;
+	void *htw_llc_slice;
+	bool have_mmu500;
+	bool hung;
+};
+
+#define to_a6xx_gpu(x) container_of(x, struct a6xx_gpu, base)
+
+/*
+ * Given a register and a count, return a value to program into
+ * REG_CP_PROTECT_REG(n) - this will block both reads and writes for
+ * _len + 1 registers starting at _reg.
+ */
+#define A6XX_PROTECT_NORDWR(_reg, _len) \
+	((1 << 31) | \
+	(((_len) & 0x3FFF) << 18) | ((_reg) & 0x3FFFF))
+
+/*
+ * Same as above, but allow reads over the range. For areas of mixed use (such
+ * as performance counters) this allows us to protect a much larger range with a
+ * single register
+ */
+#define A6XX_PROTECT_RDONLY(_reg, _len) \
+	((((_len) & 0x3FFF) << 18) | ((_reg) & 0x3FFFF))
+
+static inline bool a6xx_has_gbif(struct adreno_gpu *gpu)
+{
+	if(adreno_is_a630(gpu))
+		return false;
+
+	return true;
+}
+
+static inline void a6xx_llc_rmw(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 mask, u32 or)
+{
+	return msm_rmw(a6xx_gpu->llc_mmio + (reg << 2), mask, or);
+}
+
+static inline u32 a6xx_llc_read(struct a6xx_gpu *a6xx_gpu, u32 reg)
+{
+	return msm_readl(a6xx_gpu->llc_mmio + (reg << 2));
+}
+
+static inline void a6xx_llc_write(struct a6xx_gpu *a6xx_gpu, u32 reg, u32 value)
+{
+	msm_writel(value, a6xx_gpu->llc_mmio + (reg << 2));
+}
+
+#define shadowptr(_a6xx_gpu, _ring) ((_a6xx_gpu)->shadow_iova + \
+		((_ring)->id * sizeof(uint32_t)))
+
+int a6xx_gmu_resume(struct a6xx_gpu *gpu);
+int a6xx_gmu_stop(struct a6xx_gpu *gpu);
+
+int a6xx_gmu_wait_for_idle(struct a6xx_gmu *gmu);
+
+bool a6xx_gmu_isidle(struct a6xx_gmu *gmu);
+
+int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state);
+void a6xx_gmu_clear_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state);
+
+int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node);
+int a6xx_gmu_wrapper_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node);
+void a6xx_gmu_remove(struct a6xx_gpu *a6xx_gpu);
+
+void a6xx_gmu_set_freq(struct msm_gpu *gpu, struct dev_pm_opp *opp,
+		       bool suspended);
+unsigned long a6xx_gmu_get_freq(struct msm_gpu *gpu);
+
+void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		struct drm_printer *p);
+
+struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu);
+int a6xx_gpu_state_put(struct msm_gpu_state *state);
+
+void a6xx_bus_clear_pending_transactions(struct adreno_gpu *adreno_gpu, bool gx_off);
+void a6xx_gpu_sw_reset(struct msm_gpu *gpu, bool assert);
+
+#endif /* __A6XX_GPU_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a6xx_gpu_state.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a6xx_gpu_state.c
@@ -0,0 +1,1460 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */
+
+#include <linux/ascii85.h>
+#include "msm_gem.h"
+#include "a6xx_gpu.h"
+#include "a6xx_gmu.h"
+#include "a6xx_gpu_state.h"
+#include "a6xx_gmu.xml.h"
+
+struct a6xx_gpu_state_obj {
+	const void *handle;
+	u32 *data;
+};
+
+struct a6xx_gpu_state {
+	struct msm_gpu_state base;
+
+	struct a6xx_gpu_state_obj *gmu_registers;
+	int nr_gmu_registers;
+
+	struct a6xx_gpu_state_obj *registers;
+	int nr_registers;
+
+	struct a6xx_gpu_state_obj *shaders;
+	int nr_shaders;
+
+	struct a6xx_gpu_state_obj *clusters;
+	int nr_clusters;
+
+	struct a6xx_gpu_state_obj *dbgahb_clusters;
+	int nr_dbgahb_clusters;
+
+	struct a6xx_gpu_state_obj *indexed_regs;
+	int nr_indexed_regs;
+
+	struct a6xx_gpu_state_obj *debugbus;
+	int nr_debugbus;
+
+	struct a6xx_gpu_state_obj *vbif_debugbus;
+
+	struct a6xx_gpu_state_obj *cx_debugbus;
+	int nr_cx_debugbus;
+
+	struct msm_gpu_state_bo *gmu_log;
+	struct msm_gpu_state_bo *gmu_hfi;
+	struct msm_gpu_state_bo *gmu_debug;
+
+	s32 hfi_queue_history[2][HFI_HISTORY_SZ];
+
+	struct list_head objs;
+
+	bool gpu_initialized;
+};
+
+static inline int CRASHDUMP_WRITE(u64 *in, u32 reg, u32 val)
+{
+	in[0] = val;
+	in[1] = (((u64) reg) << 44 | (1 << 21) | 1);
+
+	return 2;
+}
+
+static inline int CRASHDUMP_READ(u64 *in, u32 reg, u32 dwords, u64 target)
+{
+	in[0] = target;
+	in[1] = (((u64) reg) << 44 | dwords);
+
+	return 2;
+}
+
+static inline int CRASHDUMP_FINI(u64 *in)
+{
+	in[0] = 0;
+	in[1] = 0;
+
+	return 2;
+}
+
+struct a6xx_crashdumper {
+	void *ptr;
+	struct drm_gem_object *bo;
+	u64 iova;
+};
+
+struct a6xx_state_memobj {
+	struct list_head node;
+	unsigned long long data[];
+};
+
+static void *state_kcalloc(struct a6xx_gpu_state *a6xx_state, int nr, size_t objsize)
+{
+	struct a6xx_state_memobj *obj =
+		kvzalloc((nr * objsize) + sizeof(*obj), GFP_KERNEL);
+
+	if (!obj)
+		return NULL;
+
+	list_add_tail(&obj->node, &a6xx_state->objs);
+	return &obj->data;
+}
+
+static void *state_kmemdup(struct a6xx_gpu_state *a6xx_state, void *src,
+		size_t size)
+{
+	void *dst = state_kcalloc(a6xx_state, 1, size);
+
+	if (dst)
+		memcpy(dst, src, size);
+	return dst;
+}
+
+/*
+ * Allocate 1MB for the crashdumper scratch region - 8k for the script and
+ * the rest for the data
+ */
+#define A6XX_CD_DATA_OFFSET 8192
+#define A6XX_CD_DATA_SIZE  (SZ_1M - 8192)
+
+static int a6xx_crashdumper_init(struct msm_gpu *gpu,
+		struct a6xx_crashdumper *dumper)
+{
+	dumper->ptr = msm_gem_kernel_new(gpu->dev,
+		SZ_1M, MSM_BO_WC, gpu->aspace,
+		&dumper->bo, &dumper->iova);
+
+	if (!IS_ERR(dumper->ptr))
+		msm_gem_object_set_name(dumper->bo, "crashdump");
+
+	return PTR_ERR_OR_ZERO(dumper->ptr);
+}
+
+static int a6xx_crashdumper_run(struct msm_gpu *gpu,
+		struct a6xx_crashdumper *dumper)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	u32 val;
+	int ret;
+
+	if (IS_ERR_OR_NULL(dumper->ptr))
+		return -EINVAL;
+
+	if (!a6xx_gmu_sptprac_is_on(&a6xx_gpu->gmu))
+		return -EINVAL;
+
+	/* Make sure all pending memory writes are posted */
+	wmb();
+
+	gpu_write64(gpu, REG_A6XX_CP_CRASH_SCRIPT_BASE, dumper->iova);
+
+	gpu_write(gpu, REG_A6XX_CP_CRASH_DUMP_CNTL, 1);
+
+	ret = gpu_poll_timeout(gpu, REG_A6XX_CP_CRASH_DUMP_STATUS, val,
+		val & 0x02, 100, 10000);
+
+	gpu_write(gpu, REG_A6XX_CP_CRASH_DUMP_CNTL, 0);
+
+	return ret;
+}
+
+/* read a value from the GX debug bus */
+static int debugbus_read(struct msm_gpu *gpu, u32 block, u32 offset,
+		u32 *data)
+{
+	u32 reg = A6XX_DBGC_CFG_DBGBUS_SEL_D_PING_INDEX(offset) |
+		A6XX_DBGC_CFG_DBGBUS_SEL_D_PING_BLK_SEL(block);
+
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_SEL_A, reg);
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_SEL_B, reg);
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_SEL_C, reg);
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_SEL_D, reg);
+
+	/* Wait 1 us to make sure the data is flowing */
+	udelay(1);
+
+	data[0] = gpu_read(gpu, REG_A6XX_DBGC_CFG_DBGBUS_TRACE_BUF2);
+	data[1] = gpu_read(gpu, REG_A6XX_DBGC_CFG_DBGBUS_TRACE_BUF1);
+
+	return 2;
+}
+
+#define cxdbg_write(ptr, offset, val) \
+	msm_writel((val), (ptr) + ((offset) << 2))
+
+#define cxdbg_read(ptr, offset) \
+	msm_readl((ptr) + ((offset) << 2))
+
+/* read a value from the CX debug bus */
+static int cx_debugbus_read(void __iomem *cxdbg, u32 block, u32 offset,
+		u32 *data)
+{
+	u32 reg = A6XX_CX_DBGC_CFG_DBGBUS_SEL_A_PING_INDEX(offset) |
+		A6XX_CX_DBGC_CFG_DBGBUS_SEL_A_PING_BLK_SEL(block);
+
+	cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_SEL_A, reg);
+	cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_SEL_B, reg);
+	cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_SEL_C, reg);
+	cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_SEL_D, reg);
+
+	/* Wait 1 us to make sure the data is flowing */
+	udelay(1);
+
+	data[0] = cxdbg_read(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF2);
+	data[1] = cxdbg_read(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_TRACE_BUF1);
+
+	return 2;
+}
+
+/* Read a chunk of data from the VBIF debug bus */
+static int vbif_debugbus_read(struct msm_gpu *gpu, u32 ctrl0, u32 ctrl1,
+		u32 reg, int count, u32 *data)
+{
+	int i;
+
+	gpu_write(gpu, ctrl0, reg);
+
+	for (i = 0; i < count; i++) {
+		gpu_write(gpu, ctrl1, i);
+		data[i] = gpu_read(gpu, REG_A6XX_VBIF_TEST_BUS_OUT);
+	}
+
+	return count;
+}
+
+#define AXI_ARB_BLOCKS 2
+#define XIN_AXI_BLOCKS 5
+#define XIN_CORE_BLOCKS 4
+
+#define VBIF_DEBUGBUS_BLOCK_SIZE \
+	((16 * AXI_ARB_BLOCKS) + \
+	 (18 * XIN_AXI_BLOCKS) + \
+	 (12 * XIN_CORE_BLOCKS))
+
+static void a6xx_get_vbif_debugbus_block(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state,
+		struct a6xx_gpu_state_obj *obj)
+{
+	u32 clk, *ptr;
+	int i;
+
+	obj->data = state_kcalloc(a6xx_state, VBIF_DEBUGBUS_BLOCK_SIZE,
+		sizeof(u32));
+	if (!obj->data)
+		return;
+
+	obj->handle = NULL;
+
+	/* Get the current clock setting */
+	clk = gpu_read(gpu, REG_A6XX_VBIF_CLKON);
+
+	/* Force on the bus so we can read it */
+	gpu_write(gpu, REG_A6XX_VBIF_CLKON,
+		clk | A6XX_VBIF_CLKON_FORCE_ON_TESTBUS);
+
+	/* We will read from BUS2 first, so disable BUS1 */
+	gpu_write(gpu, REG_A6XX_VBIF_TEST_BUS1_CTRL0, 0);
+
+	/* Enable the VBIF bus for reading */
+	gpu_write(gpu, REG_A6XX_VBIF_TEST_BUS_OUT_CTRL, 1);
+
+	ptr = obj->data;
+
+	for (i = 0; i < AXI_ARB_BLOCKS; i++)
+		ptr += vbif_debugbus_read(gpu,
+			REG_A6XX_VBIF_TEST_BUS2_CTRL0,
+			REG_A6XX_VBIF_TEST_BUS2_CTRL1,
+			1 << (i + 16), 16, ptr);
+
+	for (i = 0; i < XIN_AXI_BLOCKS; i++)
+		ptr += vbif_debugbus_read(gpu,
+			REG_A6XX_VBIF_TEST_BUS2_CTRL0,
+			REG_A6XX_VBIF_TEST_BUS2_CTRL1,
+			1 << i, 18, ptr);
+
+	/* Stop BUS2 so we can turn on BUS1 */
+	gpu_write(gpu, REG_A6XX_VBIF_TEST_BUS2_CTRL0, 0);
+
+	for (i = 0; i < XIN_CORE_BLOCKS; i++)
+		ptr += vbif_debugbus_read(gpu,
+			REG_A6XX_VBIF_TEST_BUS1_CTRL0,
+			REG_A6XX_VBIF_TEST_BUS1_CTRL1,
+			1 << i, 12, ptr);
+
+	/* Restore the VBIF clock setting */
+	gpu_write(gpu, REG_A6XX_VBIF_CLKON, clk);
+}
+
+static void a6xx_get_debugbus_block(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state,
+		const struct a6xx_debugbus_block *block,
+		struct a6xx_gpu_state_obj *obj)
+{
+	int i;
+	u32 *ptr;
+
+	obj->data = state_kcalloc(a6xx_state, block->count, sizeof(u64));
+	if (!obj->data)
+		return;
+
+	obj->handle = block;
+
+	for (ptr = obj->data, i = 0; i < block->count; i++)
+		ptr += debugbus_read(gpu, block->id, i, ptr);
+}
+
+static void a6xx_get_cx_debugbus_block(void __iomem *cxdbg,
+		struct a6xx_gpu_state *a6xx_state,
+		const struct a6xx_debugbus_block *block,
+		struct a6xx_gpu_state_obj *obj)
+{
+	int i;
+	u32 *ptr;
+
+	obj->data = state_kcalloc(a6xx_state, block->count, sizeof(u64));
+	if (!obj->data)
+		return;
+
+	obj->handle = block;
+
+	for (ptr = obj->data, i = 0; i < block->count; i++)
+		ptr += cx_debugbus_read(cxdbg, block->id, i, ptr);
+}
+
+static void a6xx_get_debugbus(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state)
+{
+	struct resource *res;
+	void __iomem *cxdbg = NULL;
+	int nr_debugbus_blocks;
+
+	/* Set up the GX debug bus */
+
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_CNTLT,
+		A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT(0xf));
+
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_CNTLM,
+		A6XX_DBGC_CFG_DBGBUS_CNTLM_ENABLE(0xf));
+
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_0, 0);
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_1, 0);
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_2, 0);
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_IVTL_3, 0);
+
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_BYTEL_0, 0x76543210);
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_BYTEL_1, 0xFEDCBA98);
+
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_0, 0);
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_1, 0);
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_2, 0);
+	gpu_write(gpu, REG_A6XX_DBGC_CFG_DBGBUS_MASKL_3, 0);
+
+	/* Set up the CX debug bus - it lives elsewhere in the system so do a
+	 * temporary ioremap for the registers
+	 */
+	res = platform_get_resource_byname(gpu->pdev, IORESOURCE_MEM,
+			"cx_dbgc");
+
+	if (res)
+		cxdbg = ioremap(res->start, resource_size(res));
+
+	if (cxdbg) {
+		cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_CNTLT,
+			A6XX_DBGC_CFG_DBGBUS_CNTLT_SEGT(0xf));
+
+		cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_CNTLM,
+			A6XX_DBGC_CFG_DBGBUS_CNTLM_ENABLE(0xf));
+
+		cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_IVTL_0, 0);
+		cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_IVTL_1, 0);
+		cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_IVTL_2, 0);
+		cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_IVTL_3, 0);
+
+		cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_0,
+			0x76543210);
+		cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_BYTEL_1,
+			0xFEDCBA98);
+
+		cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_MASKL_0, 0);
+		cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_MASKL_1, 0);
+		cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_MASKL_2, 0);
+		cxdbg_write(cxdbg, REG_A6XX_CX_DBGC_CFG_DBGBUS_MASKL_3, 0);
+	}
+
+	nr_debugbus_blocks = ARRAY_SIZE(a6xx_debugbus_blocks) +
+		(a6xx_has_gbif(to_adreno_gpu(gpu)) ? 1 : 0);
+
+	if (adreno_is_a650_family(to_adreno_gpu(gpu)))
+		nr_debugbus_blocks += ARRAY_SIZE(a650_debugbus_blocks);
+
+	a6xx_state->debugbus = state_kcalloc(a6xx_state, nr_debugbus_blocks,
+			sizeof(*a6xx_state->debugbus));
+
+	if (a6xx_state->debugbus) {
+		int i;
+
+		for (i = 0; i < ARRAY_SIZE(a6xx_debugbus_blocks); i++)
+			a6xx_get_debugbus_block(gpu,
+				a6xx_state,
+				&a6xx_debugbus_blocks[i],
+				&a6xx_state->debugbus[i]);
+
+		a6xx_state->nr_debugbus = ARRAY_SIZE(a6xx_debugbus_blocks);
+
+		/*
+		 * GBIF has same debugbus as of other GPU blocks, fall back to
+		 * default path if GPU uses GBIF, also GBIF uses exactly same
+		 * ID as of VBIF.
+		 */
+		if (a6xx_has_gbif(to_adreno_gpu(gpu))) {
+			a6xx_get_debugbus_block(gpu, a6xx_state,
+				&a6xx_gbif_debugbus_block,
+				&a6xx_state->debugbus[i]);
+
+			a6xx_state->nr_debugbus += 1;
+		}
+
+
+		if (adreno_is_a650_family(to_adreno_gpu(gpu))) {
+			for (i = 0; i < ARRAY_SIZE(a650_debugbus_blocks); i++)
+				a6xx_get_debugbus_block(gpu,
+					a6xx_state,
+					&a650_debugbus_blocks[i],
+					&a6xx_state->debugbus[i]);
+		}
+	}
+
+	/*  Dump the VBIF debugbus on applicable targets */
+	if (!a6xx_has_gbif(to_adreno_gpu(gpu))) {
+		a6xx_state->vbif_debugbus =
+			state_kcalloc(a6xx_state, 1,
+					sizeof(*a6xx_state->vbif_debugbus));
+
+		if (a6xx_state->vbif_debugbus)
+			a6xx_get_vbif_debugbus_block(gpu, a6xx_state,
+					a6xx_state->vbif_debugbus);
+	}
+
+	if (cxdbg) {
+		a6xx_state->cx_debugbus =
+			state_kcalloc(a6xx_state,
+			ARRAY_SIZE(a6xx_cx_debugbus_blocks),
+			sizeof(*a6xx_state->cx_debugbus));
+
+		if (a6xx_state->cx_debugbus) {
+			int i;
+
+			for (i = 0; i < ARRAY_SIZE(a6xx_cx_debugbus_blocks); i++)
+				a6xx_get_cx_debugbus_block(cxdbg,
+					a6xx_state,
+					&a6xx_cx_debugbus_blocks[i],
+					&a6xx_state->cx_debugbus[i]);
+
+			a6xx_state->nr_cx_debugbus =
+				ARRAY_SIZE(a6xx_cx_debugbus_blocks);
+		}
+
+		iounmap(cxdbg);
+	}
+}
+
+#define RANGE(reg, a) ((reg)[(a) + 1] - (reg)[(a)] + 1)
+
+/* Read a data cluster from behind the AHB aperture */
+static void a6xx_get_dbgahb_cluster(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state,
+		const struct a6xx_dbgahb_cluster *dbgahb,
+		struct a6xx_gpu_state_obj *obj,
+		struct a6xx_crashdumper *dumper)
+{
+	u64 *in = dumper->ptr;
+	u64 out = dumper->iova + A6XX_CD_DATA_OFFSET;
+	size_t datasize;
+	int i, regcount = 0;
+
+	for (i = 0; i < A6XX_NUM_CONTEXTS; i++) {
+		int j;
+
+		in += CRASHDUMP_WRITE(in, REG_A6XX_HLSQ_DBG_READ_SEL,
+			(dbgahb->statetype + i * 2) << 8);
+
+		for (j = 0; j < dbgahb->count; j += 2) {
+			int count = RANGE(dbgahb->registers, j);
+			u32 offset = REG_A6XX_HLSQ_DBG_AHB_READ_APERTURE +
+				dbgahb->registers[j] - (dbgahb->base >> 2);
+
+			in += CRASHDUMP_READ(in, offset, count, out);
+
+			out += count * sizeof(u32);
+
+			if (i == 0)
+				regcount += count;
+		}
+	}
+
+	CRASHDUMP_FINI(in);
+
+	datasize = regcount * A6XX_NUM_CONTEXTS * sizeof(u32);
+
+	if (WARN_ON(datasize > A6XX_CD_DATA_SIZE))
+		return;
+
+	if (a6xx_crashdumper_run(gpu, dumper))
+		return;
+
+	obj->handle = dbgahb;
+	obj->data = state_kmemdup(a6xx_state, dumper->ptr + A6XX_CD_DATA_OFFSET,
+		datasize);
+}
+
+static void a6xx_get_dbgahb_clusters(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state,
+		struct a6xx_crashdumper *dumper)
+{
+	int i;
+
+	a6xx_state->dbgahb_clusters = state_kcalloc(a6xx_state,
+		ARRAY_SIZE(a6xx_dbgahb_clusters),
+		sizeof(*a6xx_state->dbgahb_clusters));
+
+	if (!a6xx_state->dbgahb_clusters)
+		return;
+
+	a6xx_state->nr_dbgahb_clusters = ARRAY_SIZE(a6xx_dbgahb_clusters);
+
+	for (i = 0; i < ARRAY_SIZE(a6xx_dbgahb_clusters); i++)
+		a6xx_get_dbgahb_cluster(gpu, a6xx_state,
+			&a6xx_dbgahb_clusters[i],
+			&a6xx_state->dbgahb_clusters[i], dumper);
+}
+
+/* Read a data cluster from the CP aperture with the crashdumper */
+static void a6xx_get_cluster(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state,
+		const struct a6xx_cluster *cluster,
+		struct a6xx_gpu_state_obj *obj,
+		struct a6xx_crashdumper *dumper)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	u64 *in = dumper->ptr;
+	u64 out = dumper->iova + A6XX_CD_DATA_OFFSET;
+	size_t datasize;
+	int i, regcount = 0;
+	u32 id = cluster->id;
+
+	/* Skip registers that are not present on older generation */
+	if (!adreno_is_a660_family(adreno_gpu) &&
+			cluster->registers == a660_fe_cluster)
+		return;
+
+	if (adreno_is_a650_family(adreno_gpu) &&
+			cluster->registers == a6xx_ps_cluster)
+		id = CLUSTER_VPC_PS;
+
+	/* Some clusters need a selector register to be programmed too */
+	if (cluster->sel_reg)
+		in += CRASHDUMP_WRITE(in, cluster->sel_reg, cluster->sel_val);
+
+	for (i = 0; i < A6XX_NUM_CONTEXTS; i++) {
+		int j;
+
+		in += CRASHDUMP_WRITE(in, REG_A6XX_CP_APERTURE_CNTL_CD,
+			(id << 8) | (i << 4) | i);
+
+		for (j = 0; j < cluster->count; j += 2) {
+			int count = RANGE(cluster->registers, j);
+
+			in += CRASHDUMP_READ(in, cluster->registers[j],
+				count, out);
+
+			out += count * sizeof(u32);
+
+			if (i == 0)
+				regcount += count;
+		}
+	}
+
+	CRASHDUMP_FINI(in);
+
+	datasize = regcount * A6XX_NUM_CONTEXTS * sizeof(u32);
+
+	if (WARN_ON(datasize > A6XX_CD_DATA_SIZE))
+		return;
+
+	if (a6xx_crashdumper_run(gpu, dumper))
+		return;
+
+	obj->handle = cluster;
+	obj->data = state_kmemdup(a6xx_state, dumper->ptr + A6XX_CD_DATA_OFFSET,
+		datasize);
+}
+
+static void a6xx_get_clusters(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state,
+		struct a6xx_crashdumper *dumper)
+{
+	int i;
+
+	a6xx_state->clusters = state_kcalloc(a6xx_state,
+		ARRAY_SIZE(a6xx_clusters), sizeof(*a6xx_state->clusters));
+
+	if (!a6xx_state->clusters)
+		return;
+
+	a6xx_state->nr_clusters = ARRAY_SIZE(a6xx_clusters);
+
+	for (i = 0; i < ARRAY_SIZE(a6xx_clusters); i++)
+		a6xx_get_cluster(gpu, a6xx_state, &a6xx_clusters[i],
+			&a6xx_state->clusters[i], dumper);
+}
+
+/* Read a shader / debug block from the HLSQ aperture with the crashdumper */
+static void a6xx_get_shader_block(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state,
+		const struct a6xx_shader_block *block,
+		struct a6xx_gpu_state_obj *obj,
+		struct a6xx_crashdumper *dumper)
+{
+	u64 *in = dumper->ptr;
+	size_t datasize = block->size * A6XX_NUM_SHADER_BANKS * sizeof(u32);
+	int i;
+
+	if (WARN_ON(datasize > A6XX_CD_DATA_SIZE))
+		return;
+
+	for (i = 0; i < A6XX_NUM_SHADER_BANKS; i++) {
+		in += CRASHDUMP_WRITE(in, REG_A6XX_HLSQ_DBG_READ_SEL,
+			(block->type << 8) | i);
+
+		in += CRASHDUMP_READ(in, REG_A6XX_HLSQ_DBG_AHB_READ_APERTURE,
+			block->size, dumper->iova + A6XX_CD_DATA_OFFSET);
+	}
+
+	CRASHDUMP_FINI(in);
+
+	if (a6xx_crashdumper_run(gpu, dumper))
+		return;
+
+	obj->handle = block;
+	obj->data = state_kmemdup(a6xx_state, dumper->ptr + A6XX_CD_DATA_OFFSET,
+		datasize);
+}
+
+static void a6xx_get_shaders(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state,
+		struct a6xx_crashdumper *dumper)
+{
+	int i;
+
+	a6xx_state->shaders = state_kcalloc(a6xx_state,
+		ARRAY_SIZE(a6xx_shader_blocks), sizeof(*a6xx_state->shaders));
+
+	if (!a6xx_state->shaders)
+		return;
+
+	a6xx_state->nr_shaders = ARRAY_SIZE(a6xx_shader_blocks);
+
+	for (i = 0; i < ARRAY_SIZE(a6xx_shader_blocks); i++)
+		a6xx_get_shader_block(gpu, a6xx_state, &a6xx_shader_blocks[i],
+			&a6xx_state->shaders[i], dumper);
+}
+
+/* Read registers from behind the HLSQ aperture with the crashdumper */
+static void a6xx_get_crashdumper_hlsq_registers(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state,
+		const struct a6xx_registers *regs,
+		struct a6xx_gpu_state_obj *obj,
+		struct a6xx_crashdumper *dumper)
+
+{
+	u64 *in = dumper->ptr;
+	u64 out = dumper->iova + A6XX_CD_DATA_OFFSET;
+	int i, regcount = 0;
+
+	in += CRASHDUMP_WRITE(in, REG_A6XX_HLSQ_DBG_READ_SEL, regs->val1);
+
+	for (i = 0; i < regs->count; i += 2) {
+		u32 count = RANGE(regs->registers, i);
+		u32 offset = REG_A6XX_HLSQ_DBG_AHB_READ_APERTURE +
+			regs->registers[i] - (regs->val0 >> 2);
+
+		in += CRASHDUMP_READ(in, offset, count, out);
+
+		out += count * sizeof(u32);
+		regcount += count;
+	}
+
+	CRASHDUMP_FINI(in);
+
+	if (WARN_ON((regcount * sizeof(u32)) > A6XX_CD_DATA_SIZE))
+		return;
+
+	if (a6xx_crashdumper_run(gpu, dumper))
+		return;
+
+	obj->handle = regs;
+	obj->data = state_kmemdup(a6xx_state, dumper->ptr + A6XX_CD_DATA_OFFSET,
+		regcount * sizeof(u32));
+}
+
+/* Read a block of registers using the crashdumper */
+static void a6xx_get_crashdumper_registers(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state,
+		const struct a6xx_registers *regs,
+		struct a6xx_gpu_state_obj *obj,
+		struct a6xx_crashdumper *dumper)
+
+{
+	u64 *in = dumper->ptr;
+	u64 out = dumper->iova + A6XX_CD_DATA_OFFSET;
+	int i, regcount = 0;
+
+	/* Skip unsupported registers on older generations */
+	if (!adreno_is_a660_family(to_adreno_gpu(gpu)) &&
+			(regs->registers == a660_registers))
+		return;
+
+	/* Some blocks might need to program a selector register first */
+	if (regs->val0)
+		in += CRASHDUMP_WRITE(in, regs->val0, regs->val1);
+
+	for (i = 0; i < regs->count; i += 2) {
+		u32 count = RANGE(regs->registers, i);
+
+		in += CRASHDUMP_READ(in, regs->registers[i], count, out);
+
+		out += count * sizeof(u32);
+		regcount += count;
+	}
+
+	CRASHDUMP_FINI(in);
+
+	if (WARN_ON((regcount * sizeof(u32)) > A6XX_CD_DATA_SIZE))
+		return;
+
+	if (a6xx_crashdumper_run(gpu, dumper))
+		return;
+
+	obj->handle = regs;
+	obj->data = state_kmemdup(a6xx_state, dumper->ptr + A6XX_CD_DATA_OFFSET,
+		regcount * sizeof(u32));
+}
+
+/* Read a block of registers via AHB */
+static void a6xx_get_ahb_gpu_registers(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state,
+		const struct a6xx_registers *regs,
+		struct a6xx_gpu_state_obj *obj)
+{
+	int i, regcount = 0, index = 0;
+
+	/* Skip unsupported registers on older generations */
+	if (!adreno_is_a660_family(to_adreno_gpu(gpu)) &&
+			(regs->registers == a660_registers))
+		return;
+
+	for (i = 0; i < regs->count; i += 2)
+		regcount += RANGE(regs->registers, i);
+
+	obj->handle = (const void *) regs;
+	obj->data = state_kcalloc(a6xx_state, regcount, sizeof(u32));
+	if (!obj->data)
+		return;
+
+	for (i = 0; i < regs->count; i += 2) {
+		u32 count = RANGE(regs->registers, i);
+		int j;
+
+		for (j = 0; j < count; j++)
+			obj->data[index++] = gpu_read(gpu,
+				regs->registers[i] + j);
+	}
+}
+
+/* Read a block of GMU registers */
+static void _a6xx_get_gmu_registers(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state,
+		const struct a6xx_registers *regs,
+		struct a6xx_gpu_state_obj *obj,
+		bool rscc)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+	int i, regcount = 0, index = 0;
+
+	for (i = 0; i < regs->count; i += 2)
+		regcount += RANGE(regs->registers, i);
+
+	obj->handle = (const void *) regs;
+	obj->data = state_kcalloc(a6xx_state, regcount, sizeof(u32));
+	if (!obj->data)
+		return;
+
+	for (i = 0; i < regs->count; i += 2) {
+		u32 count = RANGE(regs->registers, i);
+		int j;
+
+		for (j = 0; j < count; j++) {
+			u32 offset = regs->registers[i] + j;
+			u32 val;
+
+			if (rscc)
+				val = gmu_read_rscc(gmu, offset);
+			else
+				val = gmu_read(gmu, offset);
+
+			obj->data[index++] = val;
+		}
+	}
+}
+
+static void a6xx_get_gmu_registers(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+
+	a6xx_state->gmu_registers = state_kcalloc(a6xx_state,
+		3, sizeof(*a6xx_state->gmu_registers));
+
+	if (!a6xx_state->gmu_registers)
+		return;
+
+	a6xx_state->nr_gmu_registers = 3;
+
+	/* Get the CX GMU registers from AHB */
+	_a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[0],
+		&a6xx_state->gmu_registers[0], false);
+	_a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[1],
+		&a6xx_state->gmu_registers[1], true);
+
+	if (!a6xx_gmu_gx_is_on(&a6xx_gpu->gmu))
+		return;
+
+	/* Set the fence to ALLOW mode so we can access the registers */
+	gpu_write(gpu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0);
+
+	_a6xx_get_gmu_registers(gpu, a6xx_state, &a6xx_gmu_reglist[2],
+		&a6xx_state->gmu_registers[2], false);
+}
+
+static struct msm_gpu_state_bo *a6xx_snapshot_gmu_bo(
+		struct a6xx_gpu_state *a6xx_state, struct a6xx_gmu_bo *bo)
+{
+	struct msm_gpu_state_bo *snapshot;
+
+	if (!bo->size)
+		return NULL;
+
+	snapshot = state_kcalloc(a6xx_state, 1, sizeof(*snapshot));
+	if (!snapshot)
+		return NULL;
+
+	snapshot->iova = bo->iova;
+	snapshot->size = bo->size;
+	snapshot->data = kvzalloc(snapshot->size, GFP_KERNEL);
+	if (!snapshot->data)
+		return NULL;
+
+	memcpy(snapshot->data, bo->virt, bo->size);
+
+	return snapshot;
+}
+
+static void a6xx_snapshot_gmu_hfi_history(struct msm_gpu *gpu,
+					  struct a6xx_gpu_state *a6xx_state)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	struct a6xx_gmu *gmu = &a6xx_gpu->gmu;
+	unsigned i, j;
+
+	BUILD_BUG_ON(ARRAY_SIZE(gmu->queues) != ARRAY_SIZE(a6xx_state->hfi_queue_history));
+
+	for (i = 0; i < ARRAY_SIZE(gmu->queues); i++) {
+		struct a6xx_hfi_queue *queue = &gmu->queues[i];
+		for (j = 0; j < HFI_HISTORY_SZ; j++) {
+			unsigned idx = (j + queue->history_idx) % HFI_HISTORY_SZ;
+			a6xx_state->hfi_queue_history[i][j] = queue->history[idx];
+		}
+	}
+}
+
+#define A6XX_REGLIST_SIZE        1
+#define A6XX_GBIF_REGLIST_SIZE   1
+static void a6xx_get_registers(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state,
+		struct a6xx_crashdumper *dumper)
+{
+	int i, count = A6XX_REGLIST_SIZE +
+		ARRAY_SIZE(a6xx_reglist) +
+		ARRAY_SIZE(a6xx_hlsq_reglist) + A6XX_GBIF_REGLIST_SIZE;
+	int index = 0;
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+
+	a6xx_state->registers = state_kcalloc(a6xx_state,
+		count, sizeof(*a6xx_state->registers));
+
+	if (!a6xx_state->registers)
+		return;
+
+	a6xx_state->nr_registers = count;
+
+	if (adreno_is_a7xx(adreno_gpu))
+		a6xx_get_ahb_gpu_registers(gpu,
+			a6xx_state, &a7xx_ahb_reglist,
+			&a6xx_state->registers[index++]);
+	else
+		a6xx_get_ahb_gpu_registers(gpu,
+			a6xx_state, &a6xx_ahb_reglist,
+			&a6xx_state->registers[index++]);
+
+	if (adreno_is_a7xx(adreno_gpu))
+		a6xx_get_ahb_gpu_registers(gpu,
+				a6xx_state, &a7xx_gbif_reglist,
+				&a6xx_state->registers[index++]);
+	else if (a6xx_has_gbif(adreno_gpu))
+		a6xx_get_ahb_gpu_registers(gpu,
+				a6xx_state, &a6xx_gbif_reglist,
+				&a6xx_state->registers[index++]);
+	else
+		a6xx_get_ahb_gpu_registers(gpu,
+				a6xx_state, &a6xx_vbif_reglist,
+				&a6xx_state->registers[index++]);
+	if (!dumper) {
+		/*
+		 * We can't use the crashdumper when the SMMU is stalled,
+		 * because the GPU has no memory access until we resume
+		 * translation (but we don't want to do that until after
+		 * we have captured as much useful GPU state as possible).
+		 * So instead collect registers via the CPU:
+		 */
+		for (i = 0; i < ARRAY_SIZE(a6xx_reglist); i++)
+			a6xx_get_ahb_gpu_registers(gpu,
+				a6xx_state, &a6xx_reglist[i],
+				&a6xx_state->registers[index++]);
+		return;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(a6xx_reglist); i++)
+		a6xx_get_crashdumper_registers(gpu,
+			a6xx_state, &a6xx_reglist[i],
+			&a6xx_state->registers[index++],
+			dumper);
+
+	for (i = 0; i < ARRAY_SIZE(a6xx_hlsq_reglist); i++)
+		a6xx_get_crashdumper_hlsq_registers(gpu,
+			a6xx_state, &a6xx_hlsq_reglist[i],
+			&a6xx_state->registers[index++],
+			dumper);
+}
+
+static u32 a6xx_get_cp_roq_size(struct msm_gpu *gpu)
+{
+	/* The value at [16:31] is in 4dword units. Convert it to dwords */
+	return gpu_read(gpu, REG_A6XX_CP_ROQ_THRESHOLDS_2) >> 14;
+}
+
+static u32 a7xx_get_cp_roq_size(struct msm_gpu *gpu)
+{
+	/*
+	 * The value at CP_ROQ_THRESHOLDS_2[20:31] is in 4dword units.
+	 * That register however is not directly accessible from APSS on A7xx.
+	 * Program the SQE_UCODE_DBG_ADDR with offset=0x70d3 and read the value.
+	 */
+	gpu_write(gpu, REG_A6XX_CP_SQE_UCODE_DBG_ADDR, 0x70d3);
+
+	return 4 * (gpu_read(gpu, REG_A6XX_CP_SQE_UCODE_DBG_DATA) >> 20);
+}
+
+/* Read a block of data from an indexed register pair */
+static void a6xx_get_indexed_regs(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state,
+		struct a6xx_indexed_registers *indexed,
+		struct a6xx_gpu_state_obj *obj)
+{
+	int i;
+
+	obj->handle = (const void *) indexed;
+	if (indexed->count_fn)
+		indexed->count = indexed->count_fn(gpu);
+
+	obj->data = state_kcalloc(a6xx_state, indexed->count, sizeof(u32));
+	if (!obj->data)
+		return;
+
+	/* All the indexed banks start at address 0 */
+	gpu_write(gpu, indexed->addr, 0);
+
+	/* Read the data - each read increments the internal address by 1 */
+	for (i = 0; i < indexed->count; i++)
+		obj->data[i] = gpu_read(gpu, indexed->data);
+}
+
+static void a6xx_get_indexed_registers(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state)
+{
+	u32 mempool_size;
+	int count = ARRAY_SIZE(a6xx_indexed_reglist) + 1;
+	int i;
+
+	a6xx_state->indexed_regs = state_kcalloc(a6xx_state, count,
+		sizeof(*a6xx_state->indexed_regs));
+	if (!a6xx_state->indexed_regs)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(a6xx_indexed_reglist); i++)
+		a6xx_get_indexed_regs(gpu, a6xx_state, &a6xx_indexed_reglist[i],
+			&a6xx_state->indexed_regs[i]);
+
+	if (adreno_is_a650_family(to_adreno_gpu(gpu))) {
+		u32 val;
+
+		val = gpu_read(gpu, REG_A6XX_CP_CHICKEN_DBG);
+		gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, val | 4);
+
+		/* Get the contents of the CP mempool */
+		a6xx_get_indexed_regs(gpu, a6xx_state, &a6xx_cp_mempool_indexed,
+			&a6xx_state->indexed_regs[i]);
+
+		gpu_write(gpu, REG_A6XX_CP_CHICKEN_DBG, val);
+		a6xx_state->nr_indexed_regs = count;
+		return;
+	}
+
+	/* Set the CP mempool size to 0 to stabilize it while dumping */
+	mempool_size = gpu_read(gpu, REG_A6XX_CP_MEM_POOL_SIZE);
+	gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, 0);
+
+	/* Get the contents of the CP mempool */
+	a6xx_get_indexed_regs(gpu, a6xx_state, &a6xx_cp_mempool_indexed,
+		&a6xx_state->indexed_regs[i]);
+
+	/*
+	 * Offset 0x2000 in the mempool is the size - copy the saved size over
+	 * so the data is consistent
+	 */
+	a6xx_state->indexed_regs[i].data[0x2000] = mempool_size;
+
+	/* Restore the size in the hardware */
+	gpu_write(gpu, REG_A6XX_CP_MEM_POOL_SIZE, mempool_size);
+}
+
+static void a7xx_get_indexed_registers(struct msm_gpu *gpu,
+		struct a6xx_gpu_state *a6xx_state)
+{
+	int i, indexed_count, mempool_count;
+
+	indexed_count = ARRAY_SIZE(a7xx_indexed_reglist);
+	mempool_count = ARRAY_SIZE(a7xx_cp_bv_mempool_indexed);
+
+	a6xx_state->indexed_regs = state_kcalloc(a6xx_state,
+					indexed_count + mempool_count,
+					sizeof(*a6xx_state->indexed_regs));
+	if (!a6xx_state->indexed_regs)
+		return;
+
+	a6xx_state->nr_indexed_regs = indexed_count + mempool_count;
+
+	/* First read the common regs */
+	for (i = 0; i < indexed_count; i++)
+		a6xx_get_indexed_regs(gpu, a6xx_state, &a7xx_indexed_reglist[i],
+			&a6xx_state->indexed_regs[i]);
+
+	gpu_rmw(gpu, REG_A6XX_CP_CHICKEN_DBG, 0, BIT(2));
+	gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, 0, BIT(2));
+
+	/* Get the contents of the CP_BV mempool */
+	for (i = 0; i < mempool_count; i++)
+		a6xx_get_indexed_regs(gpu, a6xx_state, a7xx_cp_bv_mempool_indexed,
+			&a6xx_state->indexed_regs[indexed_count - 1 + i]);
+
+	gpu_rmw(gpu, REG_A6XX_CP_CHICKEN_DBG, BIT(2), 0);
+	gpu_rmw(gpu, REG_A7XX_CP_BV_CHICKEN_DBG, BIT(2), 0);
+	return;
+}
+
+struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu)
+{
+	struct a6xx_crashdumper _dumper = { 0 }, *dumper = NULL;
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+	struct a6xx_gpu_state *a6xx_state = kzalloc(sizeof(*a6xx_state),
+		GFP_KERNEL);
+	bool stalled = !!(gpu_read(gpu, REG_A6XX_RBBM_STATUS3) &
+			A6XX_RBBM_STATUS3_SMMU_STALLED_ON_FAULT);
+
+	if (!a6xx_state)
+		return ERR_PTR(-ENOMEM);
+
+	INIT_LIST_HEAD(&a6xx_state->objs);
+
+	/* Get the generic state from the adreno core */
+	adreno_gpu_state_get(gpu, &a6xx_state->base);
+
+	if (!adreno_has_gmu_wrapper(adreno_gpu)) {
+		a6xx_get_gmu_registers(gpu, a6xx_state);
+
+		a6xx_state->gmu_log = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.log);
+		a6xx_state->gmu_hfi = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.hfi);
+		a6xx_state->gmu_debug = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.debug);
+
+		a6xx_snapshot_gmu_hfi_history(gpu, a6xx_state);
+	}
+
+	/* If GX isn't on the rest of the data isn't going to be accessible */
+	if (!adreno_has_gmu_wrapper(adreno_gpu) && !a6xx_gmu_gx_is_on(&a6xx_gpu->gmu))
+		return &a6xx_state->base;
+
+	/* Get the banks of indexed registers */
+	if (adreno_is_a7xx(adreno_gpu)) {
+		a7xx_get_indexed_registers(gpu, a6xx_state);
+		/* Further codeflow is untested on A7xx. */
+		return &a6xx_state->base;
+	}
+
+	a6xx_get_indexed_registers(gpu, a6xx_state);
+
+	/*
+	 * Try to initialize the crashdumper, if we are not dumping state
+	 * with the SMMU stalled.  The crashdumper needs memory access to
+	 * write out GPU state, so we need to skip this when the SMMU is
+	 * stalled in response to an iova fault
+	 */
+	if (!stalled && !gpu->needs_hw_init &&
+	    !a6xx_crashdumper_init(gpu, &_dumper)) {
+		dumper = &_dumper;
+	}
+
+	a6xx_get_registers(gpu, a6xx_state, dumper);
+
+	if (dumper) {
+		a6xx_get_shaders(gpu, a6xx_state, dumper);
+		a6xx_get_clusters(gpu, a6xx_state, dumper);
+		a6xx_get_dbgahb_clusters(gpu, a6xx_state, dumper);
+
+		msm_gem_kernel_put(dumper->bo, gpu->aspace);
+	}
+
+	if (snapshot_debugbus)
+		a6xx_get_debugbus(gpu, a6xx_state);
+
+	a6xx_state->gpu_initialized = !gpu->needs_hw_init;
+
+	return  &a6xx_state->base;
+}
+
+static void a6xx_gpu_state_destroy(struct kref *kref)
+{
+	struct a6xx_state_memobj *obj, *tmp;
+	struct msm_gpu_state *state = container_of(kref,
+			struct msm_gpu_state, ref);
+	struct a6xx_gpu_state *a6xx_state = container_of(state,
+			struct a6xx_gpu_state, base);
+
+	if (a6xx_state->gmu_log)
+		kvfree(a6xx_state->gmu_log->data);
+
+	if (a6xx_state->gmu_hfi)
+		kvfree(a6xx_state->gmu_hfi->data);
+
+	if (a6xx_state->gmu_debug)
+		kvfree(a6xx_state->gmu_debug->data);
+
+	list_for_each_entry_safe(obj, tmp, &a6xx_state->objs, node) {
+		list_del(&obj->node);
+		kvfree(obj);
+	}
+
+	adreno_gpu_state_destroy(state);
+	kfree(a6xx_state);
+}
+
+int a6xx_gpu_state_put(struct msm_gpu_state *state)
+{
+	if (IS_ERR_OR_NULL(state))
+		return 1;
+
+	return kref_put(&state->ref, a6xx_gpu_state_destroy);
+}
+
+static void a6xx_show_registers(const u32 *registers, u32 *data, size_t count,
+		struct drm_printer *p)
+{
+	int i, index = 0;
+
+	if (!data)
+		return;
+
+	for (i = 0; i < count; i += 2) {
+		u32 count = RANGE(registers, i);
+		u32 offset = registers[i];
+		int j;
+
+		for (j = 0; j < count; index++, offset++, j++) {
+			if (data[index] == 0xdeafbead)
+				continue;
+
+			drm_printf(p, "  - { offset: 0x%06x, value: 0x%08x }\n",
+				offset << 2, data[index]);
+		}
+	}
+}
+
+static void print_ascii85(struct drm_printer *p, size_t len, u32 *data)
+{
+	char out[ASCII85_BUFSZ];
+	long i, l, datalen = 0;
+
+	for (i = 0; i < len >> 2; i++) {
+		if (data[i])
+			datalen = (i + 1) << 2;
+	}
+
+	if (datalen == 0)
+		return;
+
+	drm_puts(p, "    data: !!ascii85 |\n");
+	drm_puts(p, "      ");
+
+
+	l = ascii85_encode_len(datalen);
+
+	for (i = 0; i < l; i++)
+		drm_puts(p, ascii85_encode(data[i], out));
+
+	drm_puts(p, "\n");
+}
+
+static void print_name(struct drm_printer *p, const char *fmt, const char *name)
+{
+	drm_puts(p, fmt);
+	drm_puts(p, name);
+	drm_puts(p, "\n");
+}
+
+static void a6xx_show_shader(struct a6xx_gpu_state_obj *obj,
+		struct drm_printer *p)
+{
+	const struct a6xx_shader_block *block = obj->handle;
+	int i;
+
+	if (!obj->handle)
+		return;
+
+	print_name(p, "  - type: ", block->name);
+
+	for (i = 0; i < A6XX_NUM_SHADER_BANKS; i++) {
+		drm_printf(p, "    - bank: %d\n", i);
+		drm_printf(p, "      size: %d\n", block->size);
+
+		if (!obj->data)
+			continue;
+
+		print_ascii85(p, block->size << 2,
+			obj->data + (block->size * i));
+	}
+}
+
+static void a6xx_show_cluster_data(const u32 *registers, int size, u32 *data,
+		struct drm_printer *p)
+{
+	int ctx, index = 0;
+
+	for (ctx = 0; ctx < A6XX_NUM_CONTEXTS; ctx++) {
+		int j;
+
+		drm_printf(p, "    - context: %d\n", ctx);
+
+		for (j = 0; j < size; j += 2) {
+			u32 count = RANGE(registers, j);
+			u32 offset = registers[j];
+			int k;
+
+			for (k = 0; k < count; index++, offset++, k++) {
+				if (data[index] == 0xdeafbead)
+					continue;
+
+				drm_printf(p, "      - { offset: 0x%06x, value: 0x%08x }\n",
+					offset << 2, data[index]);
+			}
+		}
+	}
+}
+
+static void a6xx_show_dbgahb_cluster(struct a6xx_gpu_state_obj *obj,
+		struct drm_printer *p)
+{
+	const struct a6xx_dbgahb_cluster *dbgahb = obj->handle;
+
+	if (dbgahb) {
+		print_name(p, "  - cluster-name: ", dbgahb->name);
+		a6xx_show_cluster_data(dbgahb->registers, dbgahb->count,
+			obj->data, p);
+	}
+}
+
+static void a6xx_show_cluster(struct a6xx_gpu_state_obj *obj,
+		struct drm_printer *p)
+{
+	const struct a6xx_cluster *cluster = obj->handle;
+
+	if (cluster) {
+		print_name(p, "  - cluster-name: ", cluster->name);
+		a6xx_show_cluster_data(cluster->registers, cluster->count,
+			obj->data, p);
+	}
+}
+
+static void a6xx_show_indexed_regs(struct a6xx_gpu_state_obj *obj,
+		struct drm_printer *p)
+{
+	const struct a6xx_indexed_registers *indexed = obj->handle;
+
+	if (!indexed)
+		return;
+
+	print_name(p, "  - regs-name: ", indexed->name);
+	drm_printf(p, "    dwords: %d\n", indexed->count);
+
+	print_ascii85(p, indexed->count << 2, obj->data);
+}
+
+static void a6xx_show_debugbus_block(const struct a6xx_debugbus_block *block,
+		u32 *data, struct drm_printer *p)
+{
+	if (block) {
+		print_name(p, "  - debugbus-block: ", block->name);
+
+		/*
+		 * count for regular debugbus data is in quadwords,
+		 * but print the size in dwords for consistency
+		 */
+		drm_printf(p, "    count: %d\n", block->count << 1);
+
+		print_ascii85(p, block->count << 3, data);
+	}
+}
+
+static void a6xx_show_debugbus(struct a6xx_gpu_state *a6xx_state,
+		struct drm_printer *p)
+{
+	int i;
+
+	for (i = 0; i < a6xx_state->nr_debugbus; i++) {
+		struct a6xx_gpu_state_obj *obj = &a6xx_state->debugbus[i];
+
+		a6xx_show_debugbus_block(obj->handle, obj->data, p);
+	}
+
+	if (a6xx_state->vbif_debugbus) {
+		struct a6xx_gpu_state_obj *obj = a6xx_state->vbif_debugbus;
+
+		drm_puts(p, "  - debugbus-block: A6XX_DBGBUS_VBIF\n");
+		drm_printf(p, "    count: %d\n", VBIF_DEBUGBUS_BLOCK_SIZE);
+
+		/* vbif debugbus data is in dwords.  Confusing, huh? */
+		print_ascii85(p, VBIF_DEBUGBUS_BLOCK_SIZE << 2, obj->data);
+	}
+
+	for (i = 0; i < a6xx_state->nr_cx_debugbus; i++) {
+		struct a6xx_gpu_state_obj *obj = &a6xx_state->cx_debugbus[i];
+
+		a6xx_show_debugbus_block(obj->handle, obj->data, p);
+	}
+}
+
+void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		struct drm_printer *p)
+{
+	struct a6xx_gpu_state *a6xx_state = container_of(state,
+			struct a6xx_gpu_state, base);
+	int i;
+
+	if (IS_ERR_OR_NULL(state))
+		return;
+
+	drm_printf(p, "gpu-initialized: %d\n", a6xx_state->gpu_initialized);
+
+	adreno_show(gpu, state, p);
+
+	drm_puts(p, "gmu-log:\n");
+	if (a6xx_state->gmu_log) {
+		struct msm_gpu_state_bo *gmu_log = a6xx_state->gmu_log;
+
+		drm_printf(p, "    iova: 0x%016llx\n", gmu_log->iova);
+		drm_printf(p, "    size: %zu\n", gmu_log->size);
+		adreno_show_object(p, &gmu_log->data, gmu_log->size,
+				&gmu_log->encoded);
+	}
+
+	drm_puts(p, "gmu-hfi:\n");
+	if (a6xx_state->gmu_hfi) {
+		struct msm_gpu_state_bo *gmu_hfi = a6xx_state->gmu_hfi;
+		unsigned i, j;
+
+		drm_printf(p, "    iova: 0x%016llx\n", gmu_hfi->iova);
+		drm_printf(p, "    size: %zu\n", gmu_hfi->size);
+		for (i = 0; i < ARRAY_SIZE(a6xx_state->hfi_queue_history); i++) {
+			drm_printf(p, "    queue-history[%u]:", i);
+			for (j = 0; j < HFI_HISTORY_SZ; j++) {
+				drm_printf(p, " %d", a6xx_state->hfi_queue_history[i][j]);
+			}
+			drm_printf(p, "\n");
+		}
+		adreno_show_object(p, &gmu_hfi->data, gmu_hfi->size,
+				&gmu_hfi->encoded);
+	}
+
+	drm_puts(p, "gmu-debug:\n");
+	if (a6xx_state->gmu_debug) {
+		struct msm_gpu_state_bo *gmu_debug = a6xx_state->gmu_debug;
+
+		drm_printf(p, "    iova: 0x%016llx\n", gmu_debug->iova);
+		drm_printf(p, "    size: %zu\n", gmu_debug->size);
+		adreno_show_object(p, &gmu_debug->data, gmu_debug->size,
+				&gmu_debug->encoded);
+	}
+
+	drm_puts(p, "registers:\n");
+	for (i = 0; i < a6xx_state->nr_registers; i++) {
+		struct a6xx_gpu_state_obj *obj = &a6xx_state->registers[i];
+		const struct a6xx_registers *regs = obj->handle;
+
+		if (!obj->handle)
+			continue;
+
+		a6xx_show_registers(regs->registers, obj->data, regs->count, p);
+	}
+
+	drm_puts(p, "registers-gmu:\n");
+	for (i = 0; i < a6xx_state->nr_gmu_registers; i++) {
+		struct a6xx_gpu_state_obj *obj = &a6xx_state->gmu_registers[i];
+		const struct a6xx_registers *regs = obj->handle;
+
+		if (!obj->handle)
+			continue;
+
+		a6xx_show_registers(regs->registers, obj->data, regs->count, p);
+	}
+
+	drm_puts(p, "indexed-registers:\n");
+	for (i = 0; i < a6xx_state->nr_indexed_regs; i++)
+		a6xx_show_indexed_regs(&a6xx_state->indexed_regs[i], p);
+
+	drm_puts(p, "shader-blocks:\n");
+	for (i = 0; i < a6xx_state->nr_shaders; i++)
+		a6xx_show_shader(&a6xx_state->shaders[i], p);
+
+	drm_puts(p, "clusters:\n");
+	for (i = 0; i < a6xx_state->nr_clusters; i++)
+		a6xx_show_cluster(&a6xx_state->clusters[i], p);
+
+	for (i = 0; i < a6xx_state->nr_dbgahb_clusters; i++)
+		a6xx_show_dbgahb_cluster(&a6xx_state->dbgahb_clusters[i], p);
+
+	drm_puts(p, "debugbus:\n");
+	a6xx_show_debugbus(a6xx_state, p);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a6xx_gpu_state.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a6xx_gpu_state.h
@@ -0,0 +1,537 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. */
+
+#ifndef _A6XX_CRASH_DUMP_H_
+#define _A6XX_CRASH_DUMP_H_
+
+#include "a6xx.xml.h"
+
+#define A6XX_NUM_CONTEXTS 2
+#define A6XX_NUM_SHADER_BANKS 3
+
+static const u32 a6xx_gras_cluster[] = {
+	0x8000, 0x8006, 0x8010, 0x8092, 0x8094, 0x809d, 0x80a0, 0x80a6,
+	0x80af, 0x80f1, 0x8100, 0x8107, 0x8109, 0x8109, 0x8110, 0x8110,
+	0x8400, 0x840b,
+};
+
+static const u32 a6xx_ps_cluster_rac[] = {
+	0x8800, 0x8806, 0x8809, 0x8811, 0x8818, 0x881e, 0x8820, 0x8865,
+	0x8870, 0x8879, 0x8880, 0x8889, 0x8890, 0x8891, 0x8898, 0x8898,
+	0x88c0, 0x88c1, 0x88d0, 0x88e3, 0x8900, 0x890c, 0x890f, 0x891a,
+	0x8c00, 0x8c01, 0x8c08, 0x8c10, 0x8c17, 0x8c1f, 0x8c26, 0x8c33,
+};
+
+static const u32 a6xx_ps_cluster_rbp[] = {
+	0x88f0, 0x88f3, 0x890d, 0x890e, 0x8927, 0x8928, 0x8bf0, 0x8bf1,
+	0x8c02, 0x8c07, 0x8c11, 0x8c16, 0x8c20, 0x8c25,
+};
+
+static const u32 a6xx_ps_cluster[] = {
+	0x9200, 0x9216, 0x9218, 0x9236, 0x9300, 0x9306,
+};
+
+static const u32 a6xx_fe_cluster[] = {
+	0x9300, 0x9306, 0x9800, 0x9806, 0x9b00, 0x9b07, 0xa000, 0xa009,
+	0xa00e, 0xa0ef, 0xa0f8, 0xa0f8,
+};
+
+static const u32 a660_fe_cluster[] = {
+	0x9807, 0x9807,
+};
+
+static const u32 a6xx_pc_vs_cluster[] = {
+	0x9100, 0x9108, 0x9300, 0x9306, 0x9980, 0x9981, 0x9b00, 0x9b07,
+};
+
+#define CLUSTER_FE	0
+#define CLUSTER_SP_VS	1
+#define CLUSTER_PC_VS	2
+#define CLUSTER_GRAS	3
+#define CLUSTER_SP_PS	4
+#define CLUSTER_PS	5
+#define CLUSTER_VPC_PS	6
+
+#define CLUSTER(_id, _reg, _sel_reg, _sel_val) \
+	{ .id = _id, .name = #_id,\
+		.registers = _reg, \
+		.count = ARRAY_SIZE(_reg), \
+		.sel_reg = _sel_reg, .sel_val = _sel_val }
+
+static const struct a6xx_cluster {
+	u32 id;
+	const char *name;
+	const u32 *registers;
+	size_t count;
+	u32 sel_reg;
+	u32 sel_val;
+} a6xx_clusters[] = {
+	CLUSTER(CLUSTER_GRAS, a6xx_gras_cluster, 0, 0),
+	CLUSTER(CLUSTER_PS, a6xx_ps_cluster_rac, REG_A6XX_RB_RB_SUB_BLOCK_SEL_CNTL_CD, 0x0),
+	CLUSTER(CLUSTER_PS, a6xx_ps_cluster_rbp, REG_A6XX_RB_RB_SUB_BLOCK_SEL_CNTL_CD, 0x9),
+	CLUSTER(CLUSTER_PS, a6xx_ps_cluster, 0, 0),
+	CLUSTER(CLUSTER_FE, a6xx_fe_cluster, 0, 0),
+	CLUSTER(CLUSTER_PC_VS, a6xx_pc_vs_cluster, 0, 0),
+	CLUSTER(CLUSTER_FE, a660_fe_cluster, 0, 0),
+};
+
+static const u32 a6xx_sp_vs_hlsq_cluster[] = {
+	0xb800, 0xb803, 0xb820, 0xb822,
+};
+
+static const u32 a6xx_sp_vs_sp_cluster[] = {
+	0xa800, 0xa824, 0xa830, 0xa83c, 0xa840, 0xa864, 0xa870, 0xa895,
+	0xa8a0, 0xa8af, 0xa8c0, 0xa8c3,
+};
+
+static const u32 a6xx_hlsq_duplicate_cluster[] = {
+	0xbb10, 0xbb11, 0xbb20, 0xbb29,
+};
+
+static const u32 a6xx_hlsq_2d_duplicate_cluster[] = {
+	0xbd80, 0xbd80,
+};
+
+static const u32 a6xx_sp_duplicate_cluster[] = {
+	0xab00, 0xab00, 0xab04, 0xab05, 0xab10, 0xab1b, 0xab20, 0xab20,
+};
+
+static const u32 a6xx_tp_duplicate_cluster[] = {
+	0xb300, 0xb307, 0xb309, 0xb309, 0xb380, 0xb382,
+};
+
+static const u32 a6xx_sp_ps_hlsq_cluster[] = {
+	0xb980, 0xb980, 0xb982, 0xb987, 0xb990, 0xb99b, 0xb9a0, 0xb9a2,
+	0xb9c0, 0xb9c9,
+};
+
+static const u32 a6xx_sp_ps_hlsq_2d_cluster[] = {
+	0xbd80, 0xbd80,
+};
+
+static const u32 a6xx_sp_ps_sp_cluster[] = {
+	0xa980, 0xa9a8, 0xa9b0, 0xa9bc, 0xa9d0, 0xa9d3, 0xa9e0, 0xa9f3,
+	0xaa00, 0xaa00, 0xaa30, 0xaa31, 0xaaf2, 0xaaf2,
+};
+
+static const u32 a6xx_sp_ps_sp_2d_cluster[] = {
+	0xacc0, 0xacc0,
+};
+
+static const u32 a6xx_sp_ps_tp_cluster[] = {
+	0xb180, 0xb183, 0xb190, 0xb191,
+};
+
+static const u32 a6xx_sp_ps_tp_2d_cluster[] = {
+	0xb4c0, 0xb4d1,
+};
+
+#define CLUSTER_DBGAHB(_id, _base, _type, _reg) \
+	{ .name = #_id, .statetype = _type, .base = _base, \
+		.registers = _reg, .count = ARRAY_SIZE(_reg) }
+
+static const struct a6xx_dbgahb_cluster {
+	const char *name;
+	u32 statetype;
+	u32 base;
+	const u32 *registers;
+	size_t count;
+} a6xx_dbgahb_clusters[] = {
+	CLUSTER_DBGAHB(CLUSTER_SP_VS, 0x0002e000, 0x41, a6xx_sp_vs_hlsq_cluster),
+	CLUSTER_DBGAHB(CLUSTER_SP_VS, 0x0002a000, 0x21, a6xx_sp_vs_sp_cluster),
+	CLUSTER_DBGAHB(CLUSTER_SP_VS, 0x0002e000, 0x41, a6xx_hlsq_duplicate_cluster),
+	CLUSTER_DBGAHB(CLUSTER_SP_VS, 0x0002f000, 0x45, a6xx_hlsq_2d_duplicate_cluster),
+	CLUSTER_DBGAHB(CLUSTER_SP_VS, 0x0002a000, 0x21, a6xx_sp_duplicate_cluster),
+	CLUSTER_DBGAHB(CLUSTER_SP_VS, 0x0002c000, 0x1, a6xx_tp_duplicate_cluster),
+	CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002e000, 0x42, a6xx_sp_ps_hlsq_cluster),
+	CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002f000, 0x46, a6xx_sp_ps_hlsq_2d_cluster),
+	CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002a000, 0x22, a6xx_sp_ps_sp_cluster),
+	CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002b000, 0x26, a6xx_sp_ps_sp_2d_cluster),
+	CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002c000, 0x2, a6xx_sp_ps_tp_cluster),
+	CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002d000, 0x6, a6xx_sp_ps_tp_2d_cluster),
+	CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002e000, 0x42, a6xx_hlsq_duplicate_cluster),
+	CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002a000, 0x22, a6xx_sp_duplicate_cluster),
+	CLUSTER_DBGAHB(CLUSTER_SP_PS, 0x0002c000, 0x2, a6xx_tp_duplicate_cluster),
+};
+
+static const u32 a6xx_hlsq_registers[] = {
+	0xbe00, 0xbe01, 0xbe04, 0xbe05, 0xbe08, 0xbe09, 0xbe10, 0xbe15,
+	0xbe20, 0xbe23,
+};
+
+static const u32 a6xx_sp_registers[] = {
+	0xae00, 0xae04, 0xae0c, 0xae0c, 0xae0f, 0xae2b, 0xae30, 0xae32,
+	0xae35, 0xae35, 0xae3a, 0xae3f, 0xae50, 0xae52,
+};
+
+static const u32 a6xx_tp_registers[] = {
+	0xb600, 0xb601, 0xb604, 0xb605, 0xb610, 0xb61b, 0xb620, 0xb623,
+};
+
+struct a6xx_registers {
+	const u32 *registers;
+	size_t count;
+	u32 val0;
+	u32 val1;
+};
+
+#define HLSQ_DBG_REGS(_base, _type, _array) \
+	{ .val0 = _base, .val1 = _type, .registers = _array, \
+		.count = ARRAY_SIZE(_array), }
+
+static const struct a6xx_registers a6xx_hlsq_reglist[] = {
+	HLSQ_DBG_REGS(0x0002F800, 0x40, a6xx_hlsq_registers),
+	HLSQ_DBG_REGS(0x0002B800, 0x20, a6xx_sp_registers),
+	HLSQ_DBG_REGS(0x0002D800, 0x0, a6xx_tp_registers),
+};
+
+#define SHADER(_type, _size) \
+	{ .type = _type, .name = #_type, .size = _size }
+
+static const struct a6xx_shader_block {
+	const char *name;
+	u32 type;
+	u32 size;
+} a6xx_shader_blocks[] = {
+	SHADER(A6XX_TP0_TMO_DATA, 0x200),
+	SHADER(A6XX_TP0_SMO_DATA, 0x80),
+	SHADER(A6XX_TP0_MIPMAP_BASE_DATA, 0x3c0),
+	SHADER(A6XX_TP1_TMO_DATA, 0x200),
+	SHADER(A6XX_TP1_SMO_DATA, 0x80),
+	SHADER(A6XX_TP1_MIPMAP_BASE_DATA, 0x3c0),
+	SHADER(A6XX_SP_INST_DATA, 0x800),
+	SHADER(A6XX_SP_LB_0_DATA, 0x800),
+	SHADER(A6XX_SP_LB_1_DATA, 0x800),
+	SHADER(A6XX_SP_LB_2_DATA, 0x800),
+	SHADER(A6XX_SP_LB_3_DATA, 0x800),
+	SHADER(A6XX_SP_LB_4_DATA, 0x800),
+	SHADER(A6XX_SP_LB_5_DATA, 0x200),
+	SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x800),
+	SHADER(A6XX_SP_CB_LEGACY_DATA, 0x280),
+	SHADER(A6XX_SP_UAV_DATA, 0x80),
+	SHADER(A6XX_SP_INST_TAG, 0x80),
+	SHADER(A6XX_SP_CB_BINDLESS_TAG, 0x80),
+	SHADER(A6XX_SP_TMO_UMO_TAG, 0x80),
+	SHADER(A6XX_SP_SMO_TAG, 0x80),
+	SHADER(A6XX_SP_STATE_DATA, 0x3f),
+	SHADER(A6XX_HLSQ_CHUNK_CVS_RAM, 0x1c0),
+	SHADER(A6XX_HLSQ_CHUNK_CPS_RAM, 0x280),
+	SHADER(A6XX_HLSQ_CHUNK_CVS_RAM_TAG, 0x40),
+	SHADER(A6XX_HLSQ_CHUNK_CPS_RAM_TAG, 0x40),
+	SHADER(A6XX_HLSQ_ICB_CVS_CB_BASE_TAG, 0x4),
+	SHADER(A6XX_HLSQ_ICB_CPS_CB_BASE_TAG, 0x4),
+	SHADER(A6XX_HLSQ_CVS_MISC_RAM, 0x1c0),
+	SHADER(A6XX_HLSQ_CPS_MISC_RAM, 0x580),
+	SHADER(A6XX_HLSQ_INST_RAM, 0x800),
+	SHADER(A6XX_HLSQ_GFX_CVS_CONST_RAM, 0x800),
+	SHADER(A6XX_HLSQ_GFX_CPS_CONST_RAM, 0x800),
+	SHADER(A6XX_HLSQ_CVS_MISC_RAM_TAG, 0x8),
+	SHADER(A6XX_HLSQ_CPS_MISC_RAM_TAG, 0x4),
+	SHADER(A6XX_HLSQ_INST_RAM_TAG, 0x80),
+	SHADER(A6XX_HLSQ_GFX_CVS_CONST_RAM_TAG, 0xc),
+	SHADER(A6XX_HLSQ_GFX_CPS_CONST_RAM_TAG, 0x10),
+	SHADER(A6XX_HLSQ_PWR_REST_RAM, 0x28),
+	SHADER(A6XX_HLSQ_PWR_REST_TAG, 0x14),
+	SHADER(A6XX_HLSQ_DATAPATH_META, 0x40),
+	SHADER(A6XX_HLSQ_FRONTEND_META, 0x40),
+	SHADER(A6XX_HLSQ_INDIRECT_META, 0x40),
+	SHADER(A6XX_SP_LB_6_DATA, 0x200),
+	SHADER(A6XX_SP_LB_7_DATA, 0x200),
+	SHADER(A6XX_HLSQ_INST_RAM_1, 0x200),
+};
+
+static const u32 a6xx_rb_rac_registers[] = {
+	0x8e04, 0x8e05, 0x8e07, 0x8e08, 0x8e10, 0x8e1c, 0x8e20, 0x8e25,
+	0x8e28, 0x8e28, 0x8e2c, 0x8e2f, 0x8e50, 0x8e52,
+};
+
+static const u32 a6xx_rb_rbp_registers[] = {
+	0x8e01, 0x8e01, 0x8e0c, 0x8e0c, 0x8e3b, 0x8e3e, 0x8e40, 0x8e43,
+	0x8e53, 0x8e5f, 0x8e70, 0x8e77,
+};
+
+static const u32 a6xx_registers[] = {
+	/* RBBM */
+	0x0000, 0x0002, 0x0010, 0x0010, 0x0012, 0x0012, 0x0018, 0x001b,
+	0x001e, 0x0032, 0x0038, 0x003c, 0x0042, 0x0042, 0x0044, 0x0044,
+	0x0047, 0x0047, 0x0056, 0x0056, 0x00ad, 0x00ae, 0x00b0, 0x00fb,
+	0x0100, 0x011d, 0x0200, 0x020d, 0x0218, 0x023d, 0x0400, 0x04f9,
+	0x0500, 0x0500, 0x0505, 0x050b, 0x050e, 0x0511, 0x0533, 0x0533,
+	0x0540, 0x0555,
+	/* CP */
+	0x0800, 0x0808, 0x0810, 0x0813, 0x0820, 0x0821, 0x0823, 0x0824,
+	0x0826, 0x0827, 0x0830, 0x0833, 0x0840, 0x0845, 0x084f, 0x086f,
+	0x0880, 0x088a, 0x08a0, 0x08ab, 0x08c0, 0x08c4, 0x08d0, 0x08dd,
+	0x08f0, 0x08f3, 0x0900, 0x0903, 0x0908, 0x0911, 0x0928, 0x093e,
+	0x0942, 0x094d, 0x0980, 0x0984, 0x098d, 0x0996, 0x0998, 0x099e,
+	0x09a0, 0x09a6, 0x09a8, 0x09ae, 0x09b0, 0x09b1, 0x09c2, 0x09c8,
+	0x0a00, 0x0a03,
+	/* VSC */
+	0x0c00, 0x0c04, 0x0c06, 0x0c06, 0x0c10, 0x0cd9, 0x0e00, 0x0e0e,
+	/* UCHE */
+	0x0e10, 0x0e13, 0x0e17, 0x0e19, 0x0e1c, 0x0e2b, 0x0e30, 0x0e32,
+	0x0e38, 0x0e39,
+	/* GRAS */
+	0x8600, 0x8601, 0x8610, 0x861b, 0x8620, 0x8620, 0x8628, 0x862b,
+	0x8630, 0x8637,
+	/* VPC */
+	0x9600, 0x9604, 0x9624, 0x9637,
+	/* PC */
+	0x9e00, 0x9e01, 0x9e03, 0x9e0e, 0x9e11, 0x9e16, 0x9e19, 0x9e19,
+	0x9e1c, 0x9e1c, 0x9e20, 0x9e23, 0x9e30, 0x9e31, 0x9e34, 0x9e34,
+	0x9e70, 0x9e72, 0x9e78, 0x9e79, 0x9e80, 0x9fff,
+	/* VFD */
+	0xa600, 0xa601, 0xa603, 0xa603, 0xa60a, 0xa60a, 0xa610, 0xa617,
+	0xa630, 0xa630,
+	/* HLSQ */
+	0xd002, 0xd003,
+};
+
+static const u32 a660_registers[] = {
+	/* UCHE */
+	0x0e3c, 0x0e3c,
+};
+
+#define REGS(_array, _sel_reg, _sel_val) \
+	{ .registers = _array, .count = ARRAY_SIZE(_array), \
+		.val0 = _sel_reg, .val1 = _sel_val }
+
+static const struct a6xx_registers a6xx_reglist[] = {
+	REGS(a6xx_registers, 0, 0),
+	REGS(a660_registers, 0, 0),
+	REGS(a6xx_rb_rac_registers, REG_A6XX_RB_RB_SUB_BLOCK_SEL_CNTL_CD, 0),
+	REGS(a6xx_rb_rbp_registers, REG_A6XX_RB_RB_SUB_BLOCK_SEL_CNTL_CD, 9),
+};
+
+static const u32 a6xx_ahb_registers[] = {
+	/* RBBM_STATUS - RBBM_STATUS3 */
+	0x210, 0x213,
+	/* CP_STATUS_1 */
+	0x825, 0x825,
+};
+
+static const u32 a6xx_vbif_registers[] = {
+	0x3000, 0x3007, 0x300c, 0x3014, 0x3018, 0x302d, 0x3030, 0x3031,
+	0x3034, 0x3036, 0x303c, 0x303d, 0x3040, 0x3040, 0x3042, 0x3042,
+	0x3049, 0x3049, 0x3058, 0x3058, 0x305a, 0x3061, 0x3064, 0x3068,
+	0x306c, 0x306d, 0x3080, 0x3088, 0x308b, 0x308c, 0x3090, 0x3094,
+	0x3098, 0x3098, 0x309c, 0x309c, 0x30c0, 0x30c0, 0x30c8, 0x30c8,
+	0x30d0, 0x30d0, 0x30d8, 0x30d8, 0x30e0, 0x30e0, 0x3100, 0x3100,
+	0x3108, 0x3108, 0x3110, 0x3110, 0x3118, 0x3118, 0x3120, 0x3120,
+	0x3124, 0x3125, 0x3129, 0x3129, 0x3131, 0x3131, 0x3154, 0x3154,
+	0x3156, 0x3156, 0x3158, 0x3158, 0x315a, 0x315a, 0x315c, 0x315c,
+	0x315e, 0x315e, 0x3160, 0x3160, 0x3162, 0x3162, 0x340c, 0x340c,
+	0x3410, 0x3410, 0x3800, 0x3801,
+};
+
+static const u32 a6xx_gbif_registers[] = {
+	0x3C00, 0X3C0B, 0X3C40, 0X3C47, 0X3CC0, 0X3CD1, 0xE3A, 0xE3A,
+};
+
+static const struct a6xx_registers a6xx_ahb_reglist =
+	REGS(a6xx_ahb_registers, 0, 0);
+
+static const struct a6xx_registers a6xx_vbif_reglist =
+			REGS(a6xx_vbif_registers, 0, 0);
+
+static const struct a6xx_registers a6xx_gbif_reglist =
+			REGS(a6xx_gbif_registers, 0, 0);
+
+static const u32 a7xx_ahb_registers[] = {
+	/* RBBM_STATUS */
+	0x210, 0x210,
+	/* RBBM_STATUS2-3 */
+	0x212, 0x213,
+};
+
+static const u32 a7xx_gbif_registers[] = {
+	0x3c00, 0x3c0b,
+	0x3c40, 0x3c42,
+	0x3c45, 0x3c47,
+	0x3c49, 0x3c4a,
+	0x3cc0, 0x3cd1,
+};
+
+static const struct a6xx_registers a7xx_ahb_reglist=
+	REGS(a7xx_ahb_registers, 0, 0);
+
+static const struct a6xx_registers a7xx_gbif_reglist =
+	REGS(a7xx_gbif_registers, 0, 0);
+
+static const u32 a6xx_gmu_gx_registers[] = {
+	/* GMU GX */
+	0x0000, 0x0000, 0x0010, 0x0013, 0x0016, 0x0016, 0x0018, 0x001b,
+	0x001e, 0x001e, 0x0020, 0x0023, 0x0026, 0x0026, 0x0028, 0x002b,
+	0x002e, 0x002e, 0x0030, 0x0033, 0x0036, 0x0036, 0x0038, 0x003b,
+	0x003e, 0x003e, 0x0040, 0x0043, 0x0046, 0x0046, 0x0080, 0x0084,
+	0x0100, 0x012b, 0x0140, 0x0140,
+};
+
+static const u32 a6xx_gmu_cx_registers[] = {
+	/* GMU CX */
+	0x4c00, 0x4c07, 0x4c10, 0x4c12, 0x4d00, 0x4d00, 0x4d07, 0x4d0a,
+	0x5000, 0x5004, 0x5007, 0x5008, 0x500b, 0x500c, 0x500f, 0x501c,
+	0x5024, 0x502a, 0x502d, 0x5030, 0x5040, 0x5053, 0x5087, 0x5089,
+	0x50a0, 0x50a2, 0x50a4, 0x50af, 0x50c0, 0x50c3, 0x50d0, 0x50d0,
+	0x50e4, 0x50e4, 0x50e8, 0x50ec, 0x5100, 0x5103, 0x5140, 0x5140,
+	0x5142, 0x5144, 0x514c, 0x514d, 0x514f, 0x5151, 0x5154, 0x5154,
+	0x5157, 0x5158, 0x515d, 0x515d, 0x5162, 0x5162, 0x5164, 0x5165,
+	0x5180, 0x5186, 0x5190, 0x519e, 0x51c0, 0x51c0, 0x51c5, 0x51cc,
+	0x51e0, 0x51e2, 0x51f0, 0x51f0, 0x5200, 0x5201,
+	/* GMU AO */
+	0x9300, 0x9316, 0x9400, 0x9400,
+	/* GPU CC */
+	0x9800, 0x9812, 0x9840, 0x9852, 0x9c00, 0x9c04, 0x9c07, 0x9c0b,
+	0x9c15, 0x9c1c, 0x9c1e, 0x9c2d, 0x9c3c, 0x9c3d, 0x9c3f, 0x9c40,
+	0x9c42, 0x9c49, 0x9c58, 0x9c5a, 0x9d40, 0x9d5e, 0xa000, 0xa002,
+	0xa400, 0xa402, 0xac00, 0xac02, 0xb000, 0xb002, 0xb400, 0xb402,
+	0xb800, 0xb802,
+	/* GPU CC ACD */
+	0xbc00, 0xbc16, 0xbc20, 0xbc27,
+};
+
+static const u32 a6xx_gmu_cx_rscc_registers[] = {
+	/* GPU RSCC */
+	0x008c, 0x008c, 0x0101, 0x0102, 0x0340, 0x0342, 0x0344, 0x0347,
+	0x034c, 0x0387, 0x03ec, 0x03ef, 0x03f4, 0x042f, 0x0494, 0x0497,
+	0x049c, 0x04d7, 0x053c, 0x053f, 0x0544, 0x057f,
+};
+
+static const struct a6xx_registers a6xx_gmu_reglist[] = {
+	REGS(a6xx_gmu_cx_registers, 0, 0),
+	REGS(a6xx_gmu_cx_rscc_registers, 0, 0),
+	REGS(a6xx_gmu_gx_registers, 0, 0),
+};
+
+static u32 a6xx_get_cp_roq_size(struct msm_gpu *gpu);
+static u32 a7xx_get_cp_roq_size(struct msm_gpu *gpu);
+
+struct a6xx_indexed_registers {
+	const char *name;
+	u32 addr;
+	u32 data;
+	u32 count;
+	u32 (*count_fn)(struct msm_gpu *gpu);
+};
+
+static struct a6xx_indexed_registers a6xx_indexed_reglist[] = {
+	{ "CP_SQE_STAT", REG_A6XX_CP_SQE_STAT_ADDR,
+		REG_A6XX_CP_SQE_STAT_DATA, 0x33, NULL },
+	{ "CP_DRAW_STATE", REG_A6XX_CP_DRAW_STATE_ADDR,
+		REG_A6XX_CP_DRAW_STATE_DATA, 0x100, NULL },
+	{ "CP_UCODE_DBG_DATA", REG_A6XX_CP_SQE_UCODE_DBG_ADDR,
+		REG_A6XX_CP_SQE_UCODE_DBG_DATA, 0x8000, NULL },
+	{ "CP_ROQ", REG_A6XX_CP_ROQ_DBG_ADDR,
+		REG_A6XX_CP_ROQ_DBG_DATA, 0, a6xx_get_cp_roq_size},
+};
+
+static struct a6xx_indexed_registers a7xx_indexed_reglist[] = {
+	{ "CP_SQE_STAT", REG_A6XX_CP_SQE_STAT_ADDR,
+		REG_A6XX_CP_SQE_STAT_DATA, 0x33, NULL },
+	{ "CP_DRAW_STATE", REG_A6XX_CP_DRAW_STATE_ADDR,
+		REG_A6XX_CP_DRAW_STATE_DATA, 0x100, NULL },
+	{ "CP_UCODE_DBG_DATA", REG_A6XX_CP_SQE_UCODE_DBG_ADDR,
+		REG_A6XX_CP_SQE_UCODE_DBG_DATA, 0x8000, NULL },
+	{ "CP_BV_SQE_STAT_ADDR", REG_A7XX_CP_BV_SQE_STAT_ADDR,
+		REG_A7XX_CP_BV_SQE_STAT_DATA, 0x33, NULL },
+	{ "CP_BV_DRAW_STATE_ADDR", REG_A7XX_CP_BV_DRAW_STATE_ADDR,
+		REG_A7XX_CP_BV_DRAW_STATE_DATA, 0x100, NULL },
+	{ "CP_BV_SQE_UCODE_DBG_ADDR", REG_A7XX_CP_BV_SQE_UCODE_DBG_ADDR,
+		REG_A7XX_CP_BV_SQE_UCODE_DBG_DATA, 0x8000, NULL },
+	{ "CP_SQE_AC_STAT_ADDR", REG_A7XX_CP_SQE_AC_STAT_ADDR,
+		REG_A7XX_CP_SQE_AC_STAT_DATA, 0x33, NULL },
+	{ "CP_LPAC_DRAW_STATE_ADDR", REG_A7XX_CP_LPAC_DRAW_STATE_ADDR,
+		REG_A7XX_CP_LPAC_DRAW_STATE_DATA, 0x100, NULL },
+	{ "CP_SQE_AC_UCODE_DBG_ADDR", REG_A7XX_CP_SQE_AC_UCODE_DBG_ADDR,
+		REG_A7XX_CP_SQE_AC_UCODE_DBG_DATA, 0x8000, NULL },
+	{ "CP_LPAC_FIFO_DBG_ADDR", REG_A7XX_CP_LPAC_FIFO_DBG_ADDR,
+		REG_A7XX_CP_LPAC_FIFO_DBG_DATA, 0x40, NULL },
+	{ "CP_ROQ", REG_A6XX_CP_ROQ_DBG_ADDR,
+		REG_A6XX_CP_ROQ_DBG_DATA, 0, a7xx_get_cp_roq_size },
+};
+
+static struct a6xx_indexed_registers a6xx_cp_mempool_indexed = {
+	"CP_MEMPOOL", REG_A6XX_CP_MEM_POOL_DBG_ADDR,
+		REG_A6XX_CP_MEM_POOL_DBG_DATA, 0x2060, NULL,
+};
+
+static struct a6xx_indexed_registers a7xx_cp_bv_mempool_indexed[] = {
+	{ "CP_MEMPOOL", REG_A6XX_CP_MEM_POOL_DBG_ADDR,
+		REG_A6XX_CP_MEM_POOL_DBG_DATA, 0x2100, NULL },
+	{ "CP_BV_MEMPOOL", REG_A7XX_CP_BV_MEM_POOL_DBG_ADDR,
+		REG_A7XX_CP_BV_MEM_POOL_DBG_DATA, 0x2100, NULL },
+};
+
+#define DEBUGBUS(_id, _count) { .id = _id, .name = #_id, .count = _count }
+
+static const struct a6xx_debugbus_block {
+	const char *name;
+	u32 id;
+	u32 count;
+} a6xx_debugbus_blocks[] = {
+	DEBUGBUS(A6XX_DBGBUS_CP, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_RBBM, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_HLSQ, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_UCHE, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_DPM, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_TESS, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_PC, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_VFDP, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_VPC, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_TSE, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_RAS, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_VSC, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_COM, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_LRZ, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_A2D, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_CCUFCHE, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_RBP, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_DCS, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_DBGC, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_GMU_GX, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_TPFCHE, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_GPC, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_LARC, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_HLSQ_SPTP, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_RB_0, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_RB_1, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_UCHE_WRAPPER, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_CCU_0, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_CCU_1, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_VFD_0, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_VFD_1, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_VFD_2, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_VFD_3, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_SP_0, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_SP_1, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_TPL1_0, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_TPL1_1, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_TPL1_2, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_TPL1_3, 0x100),
+};
+
+static const struct a6xx_debugbus_block a6xx_gbif_debugbus_block =
+			DEBUGBUS(A6XX_DBGBUS_VBIF, 0x100);
+
+static const struct a6xx_debugbus_block a6xx_cx_debugbus_blocks[] = {
+	DEBUGBUS(A6XX_DBGBUS_GMU_CX, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_CX, 0x100),
+};
+
+static const struct a6xx_debugbus_block a650_debugbus_blocks[] = {
+	DEBUGBUS(A6XX_DBGBUS_RB_2, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_CCU_2, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_VFD_4, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_VFD_5, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_SP_2, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_TPL1_4, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_TPL1_5, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_SPTP_0, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_SPTP_1, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_SPTP_2, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_SPTP_3, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_SPTP_4, 0x100),
+	DEBUGBUS(A6XX_DBGBUS_SPTP_5, 0x100),
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a6xx_hfi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a6xx_hfi.c
@@ -0,0 +1,888 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. */
+
+#include <linux/completion.h>
+#include <linux/circ_buf.h>
+#include <linux/list.h>
+
+#include <soc/qcom/cmd-db.h>
+
+#include "a6xx_gmu.h"
+#include "a6xx_gmu.xml.h"
+#include "a6xx_gpu.h"
+
+#define HFI_MSG_ID(val) [val] = #val
+
+static const char * const a6xx_hfi_msg_id[] = {
+	HFI_MSG_ID(HFI_H2F_MSG_INIT),
+	HFI_MSG_ID(HFI_H2F_MSG_FW_VERSION),
+	HFI_MSG_ID(HFI_H2F_MSG_BW_TABLE),
+	HFI_MSG_ID(HFI_H2F_MSG_PERF_TABLE),
+	HFI_MSG_ID(HFI_H2F_MSG_TEST),
+	HFI_MSG_ID(HFI_H2F_MSG_START),
+	HFI_MSG_ID(HFI_H2F_MSG_CORE_FW_START),
+	HFI_MSG_ID(HFI_H2F_MSG_GX_BW_PERF_VOTE),
+	HFI_MSG_ID(HFI_H2F_MSG_PREPARE_SLUMBER),
+};
+
+static int a6xx_hfi_queue_read(struct a6xx_gmu *gmu,
+	struct a6xx_hfi_queue *queue, u32 *data, u32 dwords)
+{
+	struct a6xx_hfi_queue_header *header = queue->header;
+	u32 i, hdr, index = header->read_index;
+
+	if (header->read_index == header->write_index) {
+		header->rx_request = 1;
+		return 0;
+	}
+
+	hdr = queue->data[index];
+
+	queue->history[(queue->history_idx++) % HFI_HISTORY_SZ] = index;
+
+	/*
+	 * If we are to assume that the GMU firmware is in fact a rational actor
+	 * and is programmed to not send us a larger response than we expect
+	 * then we can also assume that if the header size is unexpectedly large
+	 * that it is due to memory corruption and/or hardware failure. In this
+	 * case the only reasonable course of action is to BUG() to help harden
+	 * the failure.
+	 */
+
+	BUG_ON(HFI_HEADER_SIZE(hdr) > dwords);
+
+	for (i = 0; i < HFI_HEADER_SIZE(hdr); i++) {
+		data[i] = queue->data[index];
+		index = (index + 1) % header->size;
+	}
+
+	if (!gmu->legacy)
+		index = ALIGN(index, 4) % header->size;
+
+	header->read_index = index;
+	return HFI_HEADER_SIZE(hdr);
+}
+
+static int a6xx_hfi_queue_write(struct a6xx_gmu *gmu,
+	struct a6xx_hfi_queue *queue, u32 *data, u32 dwords)
+{
+	struct a6xx_hfi_queue_header *header = queue->header;
+	u32 i, space, index = header->write_index;
+
+	spin_lock(&queue->lock);
+
+	space = CIRC_SPACE(header->write_index, header->read_index,
+		header->size);
+	if (space < dwords) {
+		header->dropped++;
+		spin_unlock(&queue->lock);
+		return -ENOSPC;
+	}
+
+	queue->history[(queue->history_idx++) % HFI_HISTORY_SZ] = index;
+
+	for (i = 0; i < dwords; i++) {
+		queue->data[index] = data[i];
+		index = (index + 1) % header->size;
+	}
+
+	/* Cookify any non used data at the end of the write buffer */
+	if (!gmu->legacy) {
+		for (; index % 4; index = (index + 1) % header->size)
+			queue->data[index] = 0xfafafafa;
+	}
+
+	header->write_index = index;
+	spin_unlock(&queue->lock);
+
+	gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 0x01);
+	return 0;
+}
+
+static int a6xx_hfi_wait_for_ack(struct a6xx_gmu *gmu, u32 id, u32 seqnum,
+		u32 *payload, u32 payload_size)
+{
+	struct a6xx_hfi_queue *queue = &gmu->queues[HFI_RESPONSE_QUEUE];
+	u32 val;
+	int ret;
+
+	/* Wait for a response */
+	ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_GMU2HOST_INTR_INFO, val,
+		val & A6XX_GMU_GMU2HOST_INTR_INFO_MSGQ, 100, 5000);
+
+	if (ret) {
+		DRM_DEV_ERROR(gmu->dev,
+			"Message %s id %d timed out waiting for response\n",
+			a6xx_hfi_msg_id[id], seqnum);
+		return -ETIMEDOUT;
+	}
+
+	/* Clear the interrupt */
+	gmu_write(gmu, REG_A6XX_GMU_GMU2HOST_INTR_CLR,
+		A6XX_GMU_GMU2HOST_INTR_INFO_MSGQ);
+
+	for (;;) {
+		struct a6xx_hfi_msg_response resp;
+
+		/* Get the next packet */
+		ret = a6xx_hfi_queue_read(gmu, queue, (u32 *) &resp,
+			sizeof(resp) >> 2);
+
+		/* If the queue is empty our response never made it */
+		if (!ret) {
+			DRM_DEV_ERROR(gmu->dev,
+				"The HFI response queue is unexpectedly empty\n");
+
+			return -ENOENT;
+		}
+
+		if (HFI_HEADER_ID(resp.header) == HFI_F2H_MSG_ERROR) {
+			struct a6xx_hfi_msg_error *error =
+				(struct a6xx_hfi_msg_error *) &resp;
+
+			DRM_DEV_ERROR(gmu->dev, "GMU firmware error %d\n",
+				error->code);
+			continue;
+		}
+
+		if (seqnum != HFI_HEADER_SEQNUM(resp.ret_header)) {
+			DRM_DEV_ERROR(gmu->dev,
+				"Unexpected message id %d on the response queue\n",
+				HFI_HEADER_SEQNUM(resp.ret_header));
+			continue;
+		}
+
+		if (resp.error) {
+			DRM_DEV_ERROR(gmu->dev,
+				"Message %s id %d returned error %d\n",
+				a6xx_hfi_msg_id[id], seqnum, resp.error);
+			return -EINVAL;
+		}
+
+		/* All is well, copy over the buffer */
+		if (payload && payload_size)
+			memcpy(payload, resp.payload,
+				min_t(u32, payload_size, sizeof(resp.payload)));
+
+		return 0;
+	}
+}
+
+static int a6xx_hfi_send_msg(struct a6xx_gmu *gmu, int id,
+		void *data, u32 size, u32 *payload, u32 payload_size)
+{
+	struct a6xx_hfi_queue *queue = &gmu->queues[HFI_COMMAND_QUEUE];
+	int ret, dwords = size >> 2;
+	u32 seqnum;
+
+	seqnum = atomic_inc_return(&queue->seqnum) % 0xfff;
+
+	/* First dword of the message is the message header - fill it in */
+	*((u32 *) data) = (seqnum << 20) | (HFI_MSG_CMD << 16) |
+		(dwords << 8) | id;
+
+	ret = a6xx_hfi_queue_write(gmu, queue, data, dwords);
+	if (ret) {
+		DRM_DEV_ERROR(gmu->dev, "Unable to send message %s id %d\n",
+			a6xx_hfi_msg_id[id], seqnum);
+		return ret;
+	}
+
+	return a6xx_hfi_wait_for_ack(gmu, id, seqnum, payload, payload_size);
+}
+
+static int a6xx_hfi_send_gmu_init(struct a6xx_gmu *gmu, int boot_state)
+{
+	struct a6xx_hfi_msg_gmu_init_cmd msg = { 0 };
+
+	msg.dbg_buffer_addr = (u32) gmu->debug.iova;
+	msg.dbg_buffer_size = (u32) gmu->debug.size;
+	msg.boot_state = boot_state;
+
+	return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_INIT, &msg, sizeof(msg),
+		NULL, 0);
+}
+
+static int a6xx_hfi_get_fw_version(struct a6xx_gmu *gmu, u32 *version)
+{
+	struct a6xx_hfi_msg_fw_version msg = { 0 };
+
+	/* Currently supporting version 1.10 */
+	msg.supported_version = (1 << 28) | (1 << 19) | (1 << 17);
+
+	return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_FW_VERSION, &msg, sizeof(msg),
+		version, sizeof(*version));
+}
+
+static int a6xx_hfi_send_perf_table_v1(struct a6xx_gmu *gmu)
+{
+	struct a6xx_hfi_msg_perf_table_v1 msg = { 0 };
+	int i;
+
+	msg.num_gpu_levels = gmu->nr_gpu_freqs;
+	msg.num_gmu_levels = gmu->nr_gmu_freqs;
+
+	for (i = 0; i < gmu->nr_gpu_freqs; i++) {
+		msg.gx_votes[i].vote = gmu->gx_arc_votes[i];
+		msg.gx_votes[i].freq = gmu->gpu_freqs[i] / 1000;
+	}
+
+	for (i = 0; i < gmu->nr_gmu_freqs; i++) {
+		msg.cx_votes[i].vote = gmu->cx_arc_votes[i];
+		msg.cx_votes[i].freq = gmu->gmu_freqs[i] / 1000;
+	}
+
+	return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_PERF_TABLE, &msg, sizeof(msg),
+		NULL, 0);
+}
+
+static int a6xx_hfi_send_perf_table(struct a6xx_gmu *gmu)
+{
+	struct a6xx_hfi_msg_perf_table msg = { 0 };
+	int i;
+
+	msg.num_gpu_levels = gmu->nr_gpu_freqs;
+	msg.num_gmu_levels = gmu->nr_gmu_freqs;
+
+	for (i = 0; i < gmu->nr_gpu_freqs; i++) {
+		msg.gx_votes[i].vote = gmu->gx_arc_votes[i];
+		msg.gx_votes[i].acd = 0xffffffff;
+		msg.gx_votes[i].freq = gmu->gpu_freqs[i] / 1000;
+	}
+
+	for (i = 0; i < gmu->nr_gmu_freqs; i++) {
+		msg.cx_votes[i].vote = gmu->cx_arc_votes[i];
+		msg.cx_votes[i].freq = gmu->gmu_freqs[i] / 1000;
+	}
+
+	return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_PERF_TABLE, &msg, sizeof(msg),
+		NULL, 0);
+}
+
+static void a618_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
+{
+	/* Send a single "off" entry since the 618 GMU doesn't do bus scaling */
+	msg->bw_level_num = 1;
+
+	msg->ddr_cmds_num = 3;
+	msg->ddr_wait_bitmask = 0x01;
+
+	msg->ddr_cmds_addrs[0] = 0x50000;
+	msg->ddr_cmds_addrs[1] = 0x5003c;
+	msg->ddr_cmds_addrs[2] = 0x5000c;
+
+	msg->ddr_cmds_data[0][0] =  0x40000000;
+	msg->ddr_cmds_data[0][1] =  0x40000000;
+	msg->ddr_cmds_data[0][2] =  0x40000000;
+
+	/*
+	 * These are the CX (CNOC) votes - these are used by the GMU but the
+	 * votes are known and fixed for the target
+	 */
+	msg->cnoc_cmds_num = 1;
+	msg->cnoc_wait_bitmask = 0x01;
+
+	msg->cnoc_cmds_addrs[0] = 0x5007c;
+	msg->cnoc_cmds_data[0][0] =  0x40000000;
+	msg->cnoc_cmds_data[1][0] =  0x60000001;
+}
+
+static void a619_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
+{
+	msg->bw_level_num = 13;
+
+	msg->ddr_cmds_num = 3;
+	msg->ddr_wait_bitmask = 0x0;
+
+	msg->ddr_cmds_addrs[0] = 0x50000;
+	msg->ddr_cmds_addrs[1] = 0x50004;
+	msg->ddr_cmds_addrs[2] = 0x50080;
+
+	msg->ddr_cmds_data[0][0]  = 0x40000000;
+	msg->ddr_cmds_data[0][1]  = 0x40000000;
+	msg->ddr_cmds_data[0][2]  = 0x40000000;
+	msg->ddr_cmds_data[1][0]  = 0x6000030c;
+	msg->ddr_cmds_data[1][1]  = 0x600000db;
+	msg->ddr_cmds_data[1][2]  = 0x60000008;
+	msg->ddr_cmds_data[2][0]  = 0x60000618;
+	msg->ddr_cmds_data[2][1]  = 0x600001b6;
+	msg->ddr_cmds_data[2][2]  = 0x60000008;
+	msg->ddr_cmds_data[3][0]  = 0x60000925;
+	msg->ddr_cmds_data[3][1]  = 0x60000291;
+	msg->ddr_cmds_data[3][2]  = 0x60000008;
+	msg->ddr_cmds_data[4][0]  = 0x60000dc1;
+	msg->ddr_cmds_data[4][1]  = 0x600003dc;
+	msg->ddr_cmds_data[4][2]  = 0x60000008;
+	msg->ddr_cmds_data[5][0]  = 0x600010ad;
+	msg->ddr_cmds_data[5][1]  = 0x600004ae;
+	msg->ddr_cmds_data[5][2]  = 0x60000008;
+	msg->ddr_cmds_data[6][0]  = 0x600014c3;
+	msg->ddr_cmds_data[6][1]  = 0x600005d4;
+	msg->ddr_cmds_data[6][2]  = 0x60000008;
+	msg->ddr_cmds_data[7][0]  = 0x6000176a;
+	msg->ddr_cmds_data[7][1]  = 0x60000693;
+	msg->ddr_cmds_data[7][2]  = 0x60000008;
+	msg->ddr_cmds_data[8][0]  = 0x60001f01;
+	msg->ddr_cmds_data[8][1]  = 0x600008b5;
+	msg->ddr_cmds_data[8][2]  = 0x60000008;
+	msg->ddr_cmds_data[9][0]  = 0x60002940;
+	msg->ddr_cmds_data[9][1]  = 0x60000b95;
+	msg->ddr_cmds_data[9][2]  = 0x60000008;
+	msg->ddr_cmds_data[10][0] = 0x60002f68;
+	msg->ddr_cmds_data[10][1] = 0x60000d50;
+	msg->ddr_cmds_data[10][2] = 0x60000008;
+	msg->ddr_cmds_data[11][0] = 0x60003700;
+	msg->ddr_cmds_data[11][1] = 0x60000f71;
+	msg->ddr_cmds_data[11][2] = 0x60000008;
+	msg->ddr_cmds_data[12][0] = 0x60003fce;
+	msg->ddr_cmds_data[12][1] = 0x600011ea;
+	msg->ddr_cmds_data[12][2] = 0x60000008;
+
+	msg->cnoc_cmds_num = 1;
+	msg->cnoc_wait_bitmask = 0x0;
+
+	msg->cnoc_cmds_addrs[0] = 0x50054;
+
+	msg->cnoc_cmds_data[0][0] = 0x40000000;
+}
+
+static void a640_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
+{
+	/*
+	 * Send a single "off" entry just to get things running
+	 * TODO: bus scaling
+	 */
+	msg->bw_level_num = 1;
+
+	msg->ddr_cmds_num = 3;
+	msg->ddr_wait_bitmask = 0x01;
+
+	msg->ddr_cmds_addrs[0] = 0x50000;
+	msg->ddr_cmds_addrs[1] = 0x5003c;
+	msg->ddr_cmds_addrs[2] = 0x5000c;
+
+	msg->ddr_cmds_data[0][0] =  0x40000000;
+	msg->ddr_cmds_data[0][1] =  0x40000000;
+	msg->ddr_cmds_data[0][2] =  0x40000000;
+
+	/*
+	 * These are the CX (CNOC) votes - these are used by the GMU but the
+	 * votes are known and fixed for the target
+	 */
+	msg->cnoc_cmds_num = 3;
+	msg->cnoc_wait_bitmask = 0x01;
+
+	msg->cnoc_cmds_addrs[0] = 0x50034;
+	msg->cnoc_cmds_addrs[1] = 0x5007c;
+	msg->cnoc_cmds_addrs[2] = 0x5004c;
+
+	msg->cnoc_cmds_data[0][0] =  0x40000000;
+	msg->cnoc_cmds_data[0][1] =  0x00000000;
+	msg->cnoc_cmds_data[0][2] =  0x40000000;
+
+	msg->cnoc_cmds_data[1][0] =  0x60000001;
+	msg->cnoc_cmds_data[1][1] =  0x20000001;
+	msg->cnoc_cmds_data[1][2] =  0x60000001;
+}
+
+static void a650_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
+{
+	/*
+	 * Send a single "off" entry just to get things running
+	 * TODO: bus scaling
+	 */
+	msg->bw_level_num = 1;
+
+	msg->ddr_cmds_num = 3;
+	msg->ddr_wait_bitmask = 0x01;
+
+	msg->ddr_cmds_addrs[0] = 0x50000;
+	msg->ddr_cmds_addrs[1] = 0x50004;
+	msg->ddr_cmds_addrs[2] = 0x5007c;
+
+	msg->ddr_cmds_data[0][0] =  0x40000000;
+	msg->ddr_cmds_data[0][1] =  0x40000000;
+	msg->ddr_cmds_data[0][2] =  0x40000000;
+
+	/*
+	 * These are the CX (CNOC) votes - these are used by the GMU but the
+	 * votes are known and fixed for the target
+	 */
+	msg->cnoc_cmds_num = 1;
+	msg->cnoc_wait_bitmask = 0x01;
+
+	msg->cnoc_cmds_addrs[0] = 0x500a4;
+	msg->cnoc_cmds_data[0][0] =  0x40000000;
+	msg->cnoc_cmds_data[1][0] =  0x60000001;
+}
+
+static void a690_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
+{
+	/*
+	 * Send a single "off" entry just to get things running
+	 * TODO: bus scaling
+	 */
+	msg->bw_level_num = 1;
+
+	msg->ddr_cmds_num = 3;
+	msg->ddr_wait_bitmask = 0x01;
+
+	msg->ddr_cmds_addrs[0] = 0x50004;
+	msg->ddr_cmds_addrs[1] = 0x50000;
+	msg->ddr_cmds_addrs[2] = 0x500ac;
+
+	msg->ddr_cmds_data[0][0] =  0x40000000;
+	msg->ddr_cmds_data[0][1] =  0x40000000;
+	msg->ddr_cmds_data[0][2] =  0x40000000;
+
+	/*
+	 * These are the CX (CNOC) votes - these are used by the GMU but the
+	 * votes are known and fixed for the target
+	 */
+	msg->cnoc_cmds_num = 1;
+	msg->cnoc_wait_bitmask = 0x01;
+
+	msg->cnoc_cmds_addrs[0] = 0x5003c;
+	msg->cnoc_cmds_data[0][0] =  0x40000000;
+	msg->cnoc_cmds_data[1][0] =  0x60000001;
+}
+
+static void a660_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
+{
+	/*
+	 * Send a single "off" entry just to get things running
+	 * TODO: bus scaling
+	 */
+	msg->bw_level_num = 1;
+
+	msg->ddr_cmds_num = 3;
+	msg->ddr_wait_bitmask = 0x01;
+
+	msg->ddr_cmds_addrs[0] = 0x50004;
+	msg->ddr_cmds_addrs[1] = 0x500a0;
+	msg->ddr_cmds_addrs[2] = 0x50000;
+
+	msg->ddr_cmds_data[0][0] =  0x40000000;
+	msg->ddr_cmds_data[0][1] =  0x40000000;
+	msg->ddr_cmds_data[0][2] =  0x40000000;
+
+	/*
+	 * These are the CX (CNOC) votes - these are used by the GMU but the
+	 * votes are known and fixed for the target
+	 */
+	msg->cnoc_cmds_num = 1;
+	msg->cnoc_wait_bitmask = 0x01;
+
+	msg->cnoc_cmds_addrs[0] = 0x50070;
+	msg->cnoc_cmds_data[0][0] =  0x40000000;
+	msg->cnoc_cmds_data[1][0] =  0x60000001;
+}
+
+static void a663_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
+{
+	/*
+	 * Send a single "off" entry just to get things running
+	 * TODO: bus scaling
+	 */
+	msg->bw_level_num = 1;
+
+	msg->ddr_cmds_num = 3;
+	msg->ddr_wait_bitmask = 0x07;
+
+	msg->ddr_cmds_addrs[0] = 0x50004;
+	msg->ddr_cmds_addrs[1] = 0x50000;
+	msg->ddr_cmds_addrs[2] = 0x500b4;
+
+	msg->ddr_cmds_data[0][0] =  0x40000000;
+	msg->ddr_cmds_data[0][1] =  0x40000000;
+	msg->ddr_cmds_data[0][2] =  0x40000000;
+
+	/*
+	 * These are the CX (CNOC) votes - these are used by the GMU but the
+	 * votes are known and fixed for the target
+	 */
+	msg->cnoc_cmds_num = 1;
+	msg->cnoc_wait_bitmask = 0x01;
+
+	msg->cnoc_cmds_addrs[0] = 0x50058;
+	msg->cnoc_cmds_data[0][0] =  0x40000000;
+	msg->cnoc_cmds_data[1][0] =  0x60000001;
+}
+
+static void adreno_7c3_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
+{
+	/*
+	 * Send a single "off" entry just to get things running
+	 * TODO: bus scaling
+	 */
+	msg->bw_level_num = 1;
+
+	msg->ddr_cmds_num = 3;
+	msg->ddr_wait_bitmask = 0x07;
+
+	msg->ddr_cmds_addrs[0] = 0x50004;
+	msg->ddr_cmds_addrs[1] = 0x50000;
+	msg->ddr_cmds_addrs[2] = 0x50088;
+
+	msg->ddr_cmds_data[0][0] =  0x40000000;
+	msg->ddr_cmds_data[0][1] =  0x40000000;
+	msg->ddr_cmds_data[0][2] =  0x40000000;
+
+	/*
+	 * These are the CX (CNOC) votes - these are used by the GMU but the
+	 * votes are known and fixed for the target
+	 */
+	msg->cnoc_cmds_num = 1;
+	msg->cnoc_wait_bitmask = 0x01;
+
+	msg->cnoc_cmds_addrs[0] = 0x5006c;
+	msg->cnoc_cmds_data[0][0] =  0x40000000;
+	msg->cnoc_cmds_data[1][0] =  0x60000001;
+}
+
+static void a730_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
+{
+	msg->bw_level_num = 12;
+
+	msg->ddr_cmds_num = 3;
+	msg->ddr_wait_bitmask = 0x7;
+
+	msg->ddr_cmds_addrs[0] = cmd_db_read_addr("SH0");
+	msg->ddr_cmds_addrs[1] = cmd_db_read_addr("MC0");
+	msg->ddr_cmds_addrs[2] = cmd_db_read_addr("ACV");
+
+	msg->ddr_cmds_data[0][0] = 0x40000000;
+	msg->ddr_cmds_data[0][1] = 0x40000000;
+	msg->ddr_cmds_data[0][2] = 0x40000000;
+	msg->ddr_cmds_data[1][0] = 0x600002e8;
+	msg->ddr_cmds_data[1][1] = 0x600003d0;
+	msg->ddr_cmds_data[1][2] = 0x60000008;
+	msg->ddr_cmds_data[2][0] = 0x6000068d;
+	msg->ddr_cmds_data[2][1] = 0x6000089a;
+	msg->ddr_cmds_data[2][2] = 0x60000008;
+	msg->ddr_cmds_data[3][0] = 0x600007f2;
+	msg->ddr_cmds_data[3][1] = 0x60000a6e;
+	msg->ddr_cmds_data[3][2] = 0x60000008;
+	msg->ddr_cmds_data[4][0] = 0x600009e5;
+	msg->ddr_cmds_data[4][1] = 0x60000cfd;
+	msg->ddr_cmds_data[4][2] = 0x60000008;
+	msg->ddr_cmds_data[5][0] = 0x60000b29;
+	msg->ddr_cmds_data[5][1] = 0x60000ea6;
+	msg->ddr_cmds_data[5][2] = 0x60000008;
+	msg->ddr_cmds_data[6][0] = 0x60001698;
+	msg->ddr_cmds_data[6][1] = 0x60001da8;
+	msg->ddr_cmds_data[6][2] = 0x60000008;
+	msg->ddr_cmds_data[7][0] = 0x600018d2;
+	msg->ddr_cmds_data[7][1] = 0x60002093;
+	msg->ddr_cmds_data[7][2] = 0x60000008;
+	msg->ddr_cmds_data[8][0] = 0x60001e66;
+	msg->ddr_cmds_data[8][1] = 0x600027e6;
+	msg->ddr_cmds_data[8][2] = 0x60000008;
+	msg->ddr_cmds_data[9][0] = 0x600027c2;
+	msg->ddr_cmds_data[9][1] = 0x6000342f;
+	msg->ddr_cmds_data[9][2] = 0x60000008;
+	msg->ddr_cmds_data[10][0] = 0x60002e71;
+	msg->ddr_cmds_data[10][1] = 0x60003cf5;
+	msg->ddr_cmds_data[10][2] = 0x60000008;
+	msg->ddr_cmds_data[11][0] = 0x600030ae;
+	msg->ddr_cmds_data[11][1] = 0x60003fe5;
+	msg->ddr_cmds_data[11][2] = 0x60000008;
+
+	msg->cnoc_cmds_num = 1;
+	msg->cnoc_wait_bitmask = 0x1;
+
+	msg->cnoc_cmds_addrs[0] = cmd_db_read_addr("CN0");
+	msg->cnoc_cmds_data[0][0] = 0x40000000;
+	msg->cnoc_cmds_data[1][0] = 0x60000001;
+}
+
+static void a740_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
+{
+	msg->bw_level_num = 1;
+
+	msg->ddr_cmds_num = 3;
+	msg->ddr_wait_bitmask = 0x7;
+
+	msg->ddr_cmds_addrs[0] = cmd_db_read_addr("SH0");
+	msg->ddr_cmds_addrs[1] = cmd_db_read_addr("MC0");
+	msg->ddr_cmds_addrs[2] = cmd_db_read_addr("ACV");
+
+	msg->ddr_cmds_data[0][0] = 0x40000000;
+	msg->ddr_cmds_data[0][1] = 0x40000000;
+	msg->ddr_cmds_data[0][2] = 0x40000000;
+
+	/* TODO: add a proper dvfs table */
+
+	msg->cnoc_cmds_num = 1;
+	msg->cnoc_wait_bitmask = 0x1;
+
+	msg->cnoc_cmds_addrs[0] = cmd_db_read_addr("CN0");
+	msg->cnoc_cmds_data[0][0] = 0x40000000;
+	msg->cnoc_cmds_data[1][0] = 0x60000001;
+}
+
+static void a6xx_build_bw_table(struct a6xx_hfi_msg_bw_table *msg)
+{
+	/* Send a single "off" entry since the 630 GMU doesn't do bus scaling */
+	msg->bw_level_num = 1;
+
+	msg->ddr_cmds_num = 3;
+	msg->ddr_wait_bitmask = 0x07;
+
+	msg->ddr_cmds_addrs[0] = 0x50000;
+	msg->ddr_cmds_addrs[1] = 0x5005c;
+	msg->ddr_cmds_addrs[2] = 0x5000c;
+
+	msg->ddr_cmds_data[0][0] =  0x40000000;
+	msg->ddr_cmds_data[0][1] =  0x40000000;
+	msg->ddr_cmds_data[0][2] =  0x40000000;
+
+	/*
+	 * These are the CX (CNOC) votes.  This is used but the values for the
+	 * sdm845 GMU are known and fixed so we can hard code them.
+	 */
+
+	msg->cnoc_cmds_num = 3;
+	msg->cnoc_wait_bitmask = 0x05;
+
+	msg->cnoc_cmds_addrs[0] = 0x50034;
+	msg->cnoc_cmds_addrs[1] = 0x5007c;
+	msg->cnoc_cmds_addrs[2] = 0x5004c;
+
+	msg->cnoc_cmds_data[0][0] =  0x40000000;
+	msg->cnoc_cmds_data[0][1] =  0x00000000;
+	msg->cnoc_cmds_data[0][2] =  0x40000000;
+
+	msg->cnoc_cmds_data[1][0] =  0x60000001;
+	msg->cnoc_cmds_data[1][1] =  0x20000001;
+	msg->cnoc_cmds_data[1][2] =  0x60000001;
+}
+
+
+static int a6xx_hfi_send_bw_table(struct a6xx_gmu *gmu)
+{
+	struct a6xx_hfi_msg_bw_table msg = { 0 };
+	struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
+	struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
+
+	if (adreno_is_a618(adreno_gpu))
+		a618_build_bw_table(&msg);
+	else if (adreno_is_a619(adreno_gpu))
+		a619_build_bw_table(&msg);
+	else if (adreno_is_a640_family(adreno_gpu))
+		a640_build_bw_table(&msg);
+	else if (adreno_is_a650(adreno_gpu))
+		a650_build_bw_table(&msg);
+	else if (adreno_is_7c3(adreno_gpu))
+		adreno_7c3_build_bw_table(&msg);
+	else if (adreno_is_a660(adreno_gpu))
+		a660_build_bw_table(&msg);
+	else if (adreno_is_a663(adreno_gpu))
+		a663_build_bw_table(&msg);
+	else if (adreno_is_a690(adreno_gpu))
+		a690_build_bw_table(&msg);
+	else if (adreno_is_a730(adreno_gpu))
+		a730_build_bw_table(&msg);
+	else if (adreno_is_a740_family(adreno_gpu))
+		a740_build_bw_table(&msg);
+	else
+		a6xx_build_bw_table(&msg);
+
+	return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_BW_TABLE, &msg, sizeof(msg),
+		NULL, 0);
+}
+
+static int a6xx_hfi_send_test(struct a6xx_gmu *gmu)
+{
+	struct a6xx_hfi_msg_test msg = { 0 };
+
+	return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_TEST, &msg, sizeof(msg),
+		NULL, 0);
+}
+
+static int a6xx_hfi_send_start(struct a6xx_gmu *gmu)
+{
+	struct a6xx_hfi_msg_start msg = { 0 };
+
+	return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_START, &msg, sizeof(msg),
+		NULL, 0);
+}
+
+static int a6xx_hfi_send_core_fw_start(struct a6xx_gmu *gmu)
+{
+	struct a6xx_hfi_msg_core_fw_start msg = { 0 };
+
+	return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_CORE_FW_START, &msg,
+		sizeof(msg), NULL, 0);
+}
+
+int a6xx_hfi_set_freq(struct a6xx_gmu *gmu, int index)
+{
+	struct a6xx_hfi_gx_bw_perf_vote_cmd msg = { 0 };
+
+	msg.ack_type = 1; /* blocking */
+	msg.freq = index;
+	msg.bw = 0; /* TODO: bus scaling */
+
+	return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_GX_BW_PERF_VOTE, &msg,
+		sizeof(msg), NULL, 0);
+}
+
+int a6xx_hfi_send_prep_slumber(struct a6xx_gmu *gmu)
+{
+	struct a6xx_hfi_prep_slumber_cmd msg = { 0 };
+
+	/* TODO: should freq and bw fields be non-zero ? */
+
+	return a6xx_hfi_send_msg(gmu, HFI_H2F_MSG_PREPARE_SLUMBER, &msg,
+		sizeof(msg), NULL, 0);
+}
+
+static int a6xx_hfi_start_v1(struct a6xx_gmu *gmu, int boot_state)
+{
+	int ret;
+
+	ret = a6xx_hfi_send_gmu_init(gmu, boot_state);
+	if (ret)
+		return ret;
+
+	ret = a6xx_hfi_get_fw_version(gmu, NULL);
+	if (ret)
+		return ret;
+
+	/*
+	 * We have to get exchange version numbers per the sequence but at this
+	 * point th kernel driver doesn't need to know the exact version of
+	 * the GMU firmware
+	 */
+
+	ret = a6xx_hfi_send_perf_table_v1(gmu);
+	if (ret)
+		return ret;
+
+	ret = a6xx_hfi_send_bw_table(gmu);
+	if (ret)
+		return ret;
+
+	/*
+	 * Let the GMU know that there won't be any more HFI messages until next
+	 * boot
+	 */
+	a6xx_hfi_send_test(gmu);
+
+	return 0;
+}
+
+int a6xx_hfi_start(struct a6xx_gmu *gmu, int boot_state)
+{
+	int ret;
+
+	if (gmu->legacy)
+		return a6xx_hfi_start_v1(gmu, boot_state);
+
+
+	ret = a6xx_hfi_send_perf_table(gmu);
+	if (ret)
+		return ret;
+
+	ret = a6xx_hfi_send_bw_table(gmu);
+	if (ret)
+		return ret;
+
+	ret = a6xx_hfi_send_core_fw_start(gmu);
+	if (ret)
+		return ret;
+
+	/*
+	 * Downstream driver sends this in its "a6xx_hw_init" equivalent,
+	 * but seems to be no harm in sending it here
+	 */
+	ret = a6xx_hfi_send_start(gmu);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+void a6xx_hfi_stop(struct a6xx_gmu *gmu)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(gmu->queues); i++) {
+		struct a6xx_hfi_queue *queue = &gmu->queues[i];
+
+		if (!queue->header)
+			continue;
+
+		if (queue->header->read_index != queue->header->write_index)
+			DRM_DEV_ERROR(gmu->dev, "HFI queue %d is not empty\n", i);
+
+		queue->header->read_index = 0;
+		queue->header->write_index = 0;
+
+		memset(&queue->history, 0xff, sizeof(queue->history));
+		queue->history_idx = 0;
+	}
+}
+
+static void a6xx_hfi_queue_init(struct a6xx_hfi_queue *queue,
+		struct a6xx_hfi_queue_header *header, void *virt, u64 iova,
+		u32 id)
+{
+	spin_lock_init(&queue->lock);
+	queue->header = header;
+	queue->data = virt;
+	atomic_set(&queue->seqnum, 0);
+
+	memset(&queue->history, 0xff, sizeof(queue->history));
+	queue->history_idx = 0;
+
+	/* Set up the shared memory header */
+	header->iova = iova;
+	header->type =  10 << 8 | id;
+	header->status = 1;
+	header->size = SZ_4K >> 2;
+	header->msg_size = 0;
+	header->dropped = 0;
+	header->rx_watermark = 1;
+	header->tx_watermark = 1;
+	header->rx_request = 1;
+	header->tx_request = 0;
+	header->read_index = 0;
+	header->write_index = 0;
+}
+
+void a6xx_hfi_init(struct a6xx_gmu *gmu)
+{
+	struct a6xx_gmu_bo *hfi = &gmu->hfi;
+	struct a6xx_hfi_queue_table_header *table = hfi->virt;
+	struct a6xx_hfi_queue_header *headers = hfi->virt + sizeof(*table);
+	u64 offset;
+	int table_size;
+
+	/*
+	 * The table size is the size of the table header plus all of the queue
+	 * headers
+	 */
+	table_size = sizeof(*table);
+	table_size += (ARRAY_SIZE(gmu->queues) *
+		sizeof(struct a6xx_hfi_queue_header));
+
+	table->version = 0;
+	table->size = table_size;
+	/* First queue header is located immediately after the table header */
+	table->qhdr0_offset = sizeof(*table) >> 2;
+	table->qhdr_size = sizeof(struct a6xx_hfi_queue_header) >> 2;
+	table->num_queues = ARRAY_SIZE(gmu->queues);
+	table->active_queues = ARRAY_SIZE(gmu->queues);
+
+	/* Command queue */
+	offset = SZ_4K;
+	a6xx_hfi_queue_init(&gmu->queues[0], &headers[0], hfi->virt + offset,
+		hfi->iova + offset, 0);
+
+	/* GMU response queue */
+	offset += SZ_4K;
+	a6xx_hfi_queue_init(&gmu->queues[1], &headers[1], hfi->virt + offset,
+		hfi->iova + offset, gmu->legacy ? 4 : 1);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/a6xx_hfi.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/a6xx_hfi.h
@@ -0,0 +1,184 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2017 The Linux Foundation. All rights reserved. */
+
+#ifndef _A6XX_HFI_H_
+#define _A6XX_HFI_H_
+
+struct a6xx_hfi_queue_table_header {
+	u32 version;
+	u32 size;		/* Size of the queue table in dwords */
+	u32 qhdr0_offset;	/* Offset of the first queue header */
+	u32 qhdr_size;		/* Size of the queue headers */
+	u32 num_queues;		/* Number of total queues */
+	u32 active_queues;	/* Number of active queues */
+};
+
+struct a6xx_hfi_queue_header {
+	u32 status;
+	u32 iova;
+	u32 type;
+	u32 size;
+	u32 msg_size;
+	u32 dropped;
+	u32 rx_watermark;
+	u32 tx_watermark;
+	u32 rx_request;
+	u32 tx_request;
+	u32 read_index;
+	u32 write_index;
+};
+
+struct a6xx_hfi_queue {
+	struct a6xx_hfi_queue_header *header;
+	spinlock_t lock;
+	u32 *data;
+	atomic_t seqnum;
+
+	/*
+	 * Tracking for the start index of the last N messages in the
+	 * queue, for the benefit of devcore dump / crashdec (since
+	 * parsing in the reverse direction to decode the last N
+	 * messages is difficult to do and would rely on heuristics
+	 * which are not guaranteed to be correct)
+	 */
+#define HFI_HISTORY_SZ 8
+	s32 history[HFI_HISTORY_SZ];
+	u8  history_idx;
+};
+
+/* This is the outgoing queue to the GMU */
+#define HFI_COMMAND_QUEUE 0
+
+/* THis is the incoming response queue from the GMU */
+#define HFI_RESPONSE_QUEUE 1
+
+#define HFI_HEADER_ID(msg) ((msg) & 0xff)
+#define HFI_HEADER_SIZE(msg) (((msg) >> 8) & 0xff)
+#define HFI_HEADER_SEQNUM(msg) (((msg) >> 20) & 0xfff)
+
+/* FIXME: Do we need this or can we use ARRAY_SIZE? */
+#define HFI_RESPONSE_PAYLOAD_SIZE 16
+
+/* HFI message types */
+
+#define HFI_MSG_CMD 0
+#define HFI_MSG_ACK 1
+#define HFI_MSG_ACK_V1 2
+
+#define HFI_F2H_MSG_ACK 126
+
+struct a6xx_hfi_msg_response {
+	u32 header;
+	u32 ret_header;
+	u32 error;
+	u32 payload[HFI_RESPONSE_PAYLOAD_SIZE];
+};
+
+#define HFI_F2H_MSG_ERROR 100
+
+struct a6xx_hfi_msg_error {
+	u32 header;
+	u32 code;
+	u32 payload[2];
+};
+
+#define HFI_H2F_MSG_INIT 0
+
+struct a6xx_hfi_msg_gmu_init_cmd {
+	u32 header;
+	u32 seg_id;
+	u32 dbg_buffer_addr;
+	u32 dbg_buffer_size;
+	u32 boot_state;
+};
+
+#define HFI_H2F_MSG_FW_VERSION 1
+
+struct a6xx_hfi_msg_fw_version {
+	u32 header;
+	u32 supported_version;
+};
+
+#define HFI_H2F_MSG_PERF_TABLE 4
+
+struct perf_level {
+	u32 vote;
+	u32 freq;
+};
+
+struct perf_gx_level {
+	u32 vote;
+	u32 acd;
+	u32 freq;
+};
+
+struct a6xx_hfi_msg_perf_table_v1 {
+	u32 header;
+	u32 num_gpu_levels;
+	u32 num_gmu_levels;
+
+	struct perf_level gx_votes[16];
+	struct perf_level cx_votes[4];
+};
+
+struct a6xx_hfi_msg_perf_table {
+	u32 header;
+	u32 num_gpu_levels;
+	u32 num_gmu_levels;
+
+	struct perf_gx_level gx_votes[16];
+	struct perf_level cx_votes[4];
+};
+
+#define HFI_H2F_MSG_BW_TABLE 3
+
+struct a6xx_hfi_msg_bw_table {
+	u32 header;
+	u32 bw_level_num;
+	u32 cnoc_cmds_num;
+	u32 ddr_cmds_num;
+	u32 cnoc_wait_bitmask;
+	u32 ddr_wait_bitmask;
+	u32 cnoc_cmds_addrs[6];
+	u32 cnoc_cmds_data[2][6];
+	u32 ddr_cmds_addrs[8];
+	u32 ddr_cmds_data[16][8];
+};
+
+#define HFI_H2F_MSG_TEST 5
+
+struct a6xx_hfi_msg_test {
+	u32 header;
+};
+
+#define HFI_H2F_MSG_START 10
+
+struct a6xx_hfi_msg_start {
+	u32 header;
+};
+
+#define HFI_H2F_MSG_CORE_FW_START 14
+
+struct a6xx_hfi_msg_core_fw_start {
+	u32 header;
+	u32 handle;
+};
+
+#define HFI_H2F_MSG_GX_BW_PERF_VOTE 30
+
+struct a6xx_hfi_gx_bw_perf_vote_cmd {
+	u32 header;
+	u32 ack_type;
+	u32 freq;
+	u32 bw;
+};
+
+#define HFI_H2F_MSG_PREPARE_SLUMBER 33
+
+struct a6xx_hfi_prep_slumber_cmd {
+	u32 header;
+	u32 bw;
+	u32 freq;
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/adreno_device.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/adreno_device.c
@@ -0,0 +1,409 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013-2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
+ */
+
+#include "adreno_gpu.h"
+
+bool hang_debug = false;
+MODULE_PARM_DESC(hang_debug, "Dump registers when hang is detected (can be slow!)");
+module_param_named(hang_debug, hang_debug, bool, 0600);
+
+bool snapshot_debugbus = false;
+MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)");
+module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600);
+
+bool allow_vram_carveout = false;
+MODULE_PARM_DESC(allow_vram_carveout, "Allow using VRAM Carveout, in place of IOMMU");
+module_param_named(allow_vram_carveout, allow_vram_carveout, bool, 0600);
+
+extern const struct adreno_gpulist a2xx_gpulist;
+extern const struct adreno_gpulist a3xx_gpulist;
+extern const struct adreno_gpulist a4xx_gpulist;
+extern const struct adreno_gpulist a5xx_gpulist;
+extern const struct adreno_gpulist a6xx_gpulist;
+extern const struct adreno_gpulist a7xx_gpulist;
+
+static const struct adreno_gpulist *gpulists[] = {
+	&a2xx_gpulist,
+	&a3xx_gpulist,
+	&a4xx_gpulist,
+	&a5xx_gpulist,
+	&a6xx_gpulist,
+	&a6xx_gpulist,
+};
+
+static const struct adreno_info *adreno_info(uint32_t chip_id)
+{
+	/* identify gpu: */
+	for (int i = 0; i < ARRAY_SIZE(gpulists); i++) {
+		for (int j = 0; j < gpulists[i]->gpus_count; j++) {
+			const struct adreno_info *info = &gpulists[i]->gpus[j];
+
+			if (info->machine && !of_machine_is_compatible(info->machine))
+				continue;
+
+			for (int k = 0; info->chip_ids[k]; k++)
+				if (info->chip_ids[k] == chip_id)
+					return info;
+		}
+	}
+
+	return NULL;
+}
+
+struct msm_gpu *adreno_load_gpu(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct platform_device *pdev = priv->gpu_pdev;
+	struct msm_gpu *gpu = NULL;
+	struct adreno_gpu *adreno_gpu;
+	int ret;
+
+	if (pdev)
+		gpu = dev_to_gpu(&pdev->dev);
+
+	if (!gpu) {
+		dev_err_once(dev->dev, "no GPU device was found\n");
+		return NULL;
+	}
+
+	adreno_gpu = to_adreno_gpu(gpu);
+
+	/*
+	 * The number one reason for HW init to fail is if the firmware isn't
+	 * loaded yet. Try that first and don't bother continuing on
+	 * otherwise
+	 */
+
+	ret = adreno_load_fw(adreno_gpu);
+	if (ret)
+		return NULL;
+
+	if (gpu->funcs->ucode_load) {
+		ret = gpu->funcs->ucode_load(gpu);
+		if (ret)
+			return NULL;
+	}
+
+	/*
+	 * Now that we have firmware loaded, and are ready to begin
+	 * booting the gpu, go ahead and enable runpm:
+	 */
+	pm_runtime_enable(&pdev->dev);
+
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0) {
+		pm_runtime_put_noidle(&pdev->dev);
+		DRM_DEV_ERROR(dev->dev, "Couldn't power up the GPU: %d\n", ret);
+		goto err_disable_rpm;
+	}
+
+	mutex_lock(&gpu->lock);
+	ret = msm_gpu_hw_init(gpu);
+	mutex_unlock(&gpu->lock);
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev, "gpu hw init failed: %d\n", ret);
+		goto err_put_rpm;
+	}
+
+	pm_runtime_put_autosuspend(&pdev->dev);
+
+#ifdef CONFIG_DEBUG_FS
+	if (gpu->funcs->debugfs_init) {
+		gpu->funcs->debugfs_init(gpu, dev->primary);
+		gpu->funcs->debugfs_init(gpu, dev->render);
+	}
+#endif
+
+	return gpu;
+
+err_put_rpm:
+	pm_runtime_put_sync_suspend(&pdev->dev);
+err_disable_rpm:
+	pm_runtime_disable(&pdev->dev);
+
+	return NULL;
+}
+
+static int find_chipid(struct device *dev, uint32_t *chipid)
+{
+	struct device_node *node = dev->of_node;
+	const char *compat;
+	int ret;
+
+	/* first search the compat strings for qcom,adreno-XYZ.W: */
+	ret = of_property_read_string_index(node, "compatible", 0, &compat);
+	if (ret == 0) {
+		unsigned int r, patch;
+
+		if (sscanf(compat, "qcom,adreno-%u.%u", &r, &patch) == 2 ||
+		    sscanf(compat, "amd,imageon-%u.%u", &r, &patch) == 2) {
+			uint32_t core, major, minor;
+
+			core = r / 100;
+			r %= 100;
+			major = r / 10;
+			r %= 10;
+			minor = r;
+
+			*chipid = (core << 24) |
+				(major << 16) |
+				(minor << 8) |
+				patch;
+
+			return 0;
+		}
+
+		if (sscanf(compat, "qcom,adreno-%08x", chipid) == 1)
+			return 0;
+	}
+
+	/* and if that fails, fall back to legacy "qcom,chipid" property: */
+	ret = of_property_read_u32(node, "qcom,chipid", chipid);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "could not parse qcom,chipid: %d\n", ret);
+		return ret;
+	}
+
+	dev_warn(dev, "Using legacy qcom,chipid binding!\n");
+
+	return 0;
+}
+
+static int adreno_bind(struct device *dev, struct device *master, void *data)
+{
+	static struct adreno_platform_config config = {};
+	const struct adreno_info *info;
+	struct msm_drm_private *priv = dev_get_drvdata(master);
+	struct drm_device *drm = priv->dev;
+	struct msm_gpu *gpu;
+	int ret;
+
+	ret = find_chipid(dev, &config.chip_id);
+	if (ret)
+		return ret;
+
+	dev->platform_data = &config;
+	priv->gpu_pdev = to_platform_device(dev);
+
+	info = adreno_info(config.chip_id);
+	if (!info) {
+		dev_warn(drm->dev, "Unknown GPU revision: %"ADRENO_CHIPID_FMT"\n",
+			ADRENO_CHIPID_ARGS(config.chip_id));
+		return -ENXIO;
+	}
+
+	config.info = info;
+
+	DBG("Found GPU: %"ADRENO_CHIPID_FMT, ADRENO_CHIPID_ARGS(config.chip_id));
+
+	priv->is_a2xx = info->family < ADRENO_3XX;
+	priv->has_cached_coherent =
+		!!(info->quirks & ADRENO_QUIRK_HAS_CACHED_COHERENT);
+
+	gpu = info->init(drm);
+	if (IS_ERR(gpu)) {
+		dev_warn(drm->dev, "failed to load adreno gpu\n");
+		return PTR_ERR(gpu);
+	}
+
+	ret = dev_pm_opp_of_find_icc_paths(dev, NULL);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int adreno_system_suspend(struct device *dev);
+static void adreno_unbind(struct device *dev, struct device *master,
+		void *data)
+{
+	struct msm_drm_private *priv = dev_get_drvdata(master);
+	struct msm_gpu *gpu = dev_to_gpu(dev);
+
+	if (pm_runtime_enabled(dev))
+		WARN_ON_ONCE(adreno_system_suspend(dev));
+	gpu->funcs->destroy(gpu);
+
+	priv->gpu_pdev = NULL;
+}
+
+static const struct component_ops a3xx_ops = {
+	.bind   = adreno_bind,
+	.unbind = adreno_unbind,
+};
+
+static void adreno_device_register_headless(void)
+{
+	/* on imx5, we don't have a top-level mdp/dpu node
+	 * this creates a dummy node for the driver for that case
+	 */
+	struct platform_device_info dummy_info = {
+		.parent = NULL,
+		.name = "msm",
+		.id = -1,
+		.res = NULL,
+		.num_res = 0,
+		.data = NULL,
+		.size_data = 0,
+		.dma_mask = ~0,
+	};
+	platform_device_register_full(&dummy_info);
+}
+
+static int adreno_probe(struct platform_device *pdev)
+{
+
+	int ret;
+
+	ret = component_add(&pdev->dev, &a3xx_ops);
+	if (ret)
+		return ret;
+
+	if (of_device_is_compatible(pdev->dev.of_node, "amd,imageon"))
+		adreno_device_register_headless();
+
+	return 0;
+}
+
+static void adreno_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &a3xx_ops);
+}
+
+static void adreno_shutdown(struct platform_device *pdev)
+{
+	WARN_ON_ONCE(adreno_system_suspend(&pdev->dev));
+}
+
+static const struct of_device_id dt_match[] = {
+	{ .compatible = "qcom,adreno" },
+	{ .compatible = "qcom,adreno-3xx" },
+	/* for compatibility with imx5 gpu: */
+	{ .compatible = "amd,imageon" },
+	/* for backwards compat w/ downstream kgsl DT files: */
+	{ .compatible = "qcom,kgsl-3d0" },
+	{}
+};
+
+static int adreno_runtime_resume(struct device *dev)
+{
+	struct msm_gpu *gpu = dev_to_gpu(dev);
+
+	return gpu->funcs->pm_resume(gpu);
+}
+
+static int adreno_runtime_suspend(struct device *dev)
+{
+	struct msm_gpu *gpu = dev_to_gpu(dev);
+
+	/*
+	 * We should be holding a runpm ref, which will prevent
+	 * runtime suspend.  In the system suspend path, we've
+	 * already waited for active jobs to complete.
+	 */
+	WARN_ON_ONCE(gpu->active_submits);
+
+	return gpu->funcs->pm_suspend(gpu);
+}
+
+static void suspend_scheduler(struct msm_gpu *gpu)
+{
+	int i;
+
+	/*
+	 * Shut down the scheduler before we force suspend, so that
+	 * suspend isn't racing with scheduler kthread feeding us
+	 * more work.
+	 *
+	 * Note, we just want to park the thread, and let any jobs
+	 * that are already on the hw queue complete normally, as
+	 * opposed to the drm_sched_stop() path used for handling
+	 * faulting/timed-out jobs.  We can't really cancel any jobs
+	 * already on the hw queue without racing with the GPU.
+	 */
+	for (i = 0; i < gpu->nr_rings; i++) {
+		struct drm_gpu_scheduler *sched = &gpu->rb[i]->sched;
+
+		drm_sched_wqueue_stop(sched);
+	}
+}
+
+static void resume_scheduler(struct msm_gpu *gpu)
+{
+	int i;
+
+	for (i = 0; i < gpu->nr_rings; i++) {
+		struct drm_gpu_scheduler *sched = &gpu->rb[i]->sched;
+
+		drm_sched_wqueue_start(sched);
+	}
+}
+
+static int adreno_system_suspend(struct device *dev)
+{
+	struct msm_gpu *gpu = dev_to_gpu(dev);
+	int remaining, ret;
+
+	if (!gpu)
+		return 0;
+
+	suspend_scheduler(gpu);
+
+	remaining = wait_event_timeout(gpu->retire_event,
+				       gpu->active_submits == 0,
+				       msecs_to_jiffies(1000));
+	if (remaining == 0) {
+		dev_err(dev, "Timeout waiting for GPU to suspend\n");
+		ret = -EBUSY;
+		goto out;
+	}
+
+	ret = pm_runtime_force_suspend(dev);
+out:
+	if (ret)
+		resume_scheduler(gpu);
+
+	return ret;
+}
+
+static int adreno_system_resume(struct device *dev)
+{
+	struct msm_gpu *gpu = dev_to_gpu(dev);
+
+	if (!gpu)
+		return 0;
+
+	resume_scheduler(gpu);
+	return pm_runtime_force_resume(dev);
+}
+
+static const struct dev_pm_ops adreno_pm_ops = {
+	SYSTEM_SLEEP_PM_OPS(adreno_system_suspend, adreno_system_resume)
+	RUNTIME_PM_OPS(adreno_runtime_suspend, adreno_runtime_resume, NULL)
+};
+
+static struct platform_driver adreno_driver = {
+	.probe = adreno_probe,
+	.remove_new = adreno_remove,
+	.shutdown = adreno_shutdown,
+	.driver = {
+		.name = "adreno",
+		.of_match_table = dt_match,
+		.pm = &adreno_pm_ops,
+	},
+};
+
+void __init adreno_register(void)
+{
+	platform_driver_register(&adreno_driver);
+}
+
+void __exit adreno_unregister(void)
+{
+	platform_driver_unregister(&adreno_driver);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/adreno_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/adreno_gpu.c
@@ -0,0 +1,1151 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/ascii85.h>
+#include <linux/interconnect.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
+#include <linux/soc/qcom/mdt_loader.h>
+#include <linux/nvmem-consumer.h>
+#include <soc/qcom/ocmem.h>
+#include "adreno_gpu.h"
+#include "a6xx_gpu.h"
+#include "msm_gem.h"
+#include "msm_mmu.h"
+
+static u64 address_space_size = 0;
+MODULE_PARM_DESC(address_space_size, "Override for size of processes private GPU address space");
+module_param(address_space_size, ullong, 0600);
+
+static bool zap_available = true;
+
+static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname,
+		u32 pasid)
+{
+	struct device *dev = &gpu->pdev->dev;
+	const struct firmware *fw;
+	const char *signed_fwname = NULL;
+	struct device_node *np, *mem_np;
+	struct resource r;
+	phys_addr_t mem_phys;
+	ssize_t mem_size;
+	void *mem_region = NULL;
+	int ret;
+
+	if (!IS_ENABLED(CONFIG_ARCH_QCOM)) {
+		zap_available = false;
+		return -EINVAL;
+	}
+
+	np = of_get_child_by_name(dev->of_node, "zap-shader");
+	if (!np) {
+		zap_available = false;
+		return -ENODEV;
+	}
+
+	mem_np = of_parse_phandle(np, "memory-region", 0);
+	of_node_put(np);
+	if (!mem_np) {
+		zap_available = false;
+		return -EINVAL;
+	}
+
+	ret = of_address_to_resource(mem_np, 0, &r);
+	of_node_put(mem_np);
+	if (ret)
+		return ret;
+
+	mem_phys = r.start;
+
+	/*
+	 * Check for a firmware-name property.  This is the new scheme
+	 * to handle firmware that may be signed with device specific
+	 * keys, allowing us to have a different zap fw path for different
+	 * devices.
+	 *
+	 * If the firmware-name property is found, we bypass the
+	 * adreno_request_fw() mechanism, because we don't need to handle
+	 * the /lib/firmware/qcom/... vs /lib/firmware/... case.
+	 *
+	 * If the firmware-name property is not found, for backwards
+	 * compatibility we fall back to the fwname from the gpulist
+	 * table.
+	 */
+	of_property_read_string_index(np, "firmware-name", 0, &signed_fwname);
+	if (signed_fwname) {
+		fwname = signed_fwname;
+		ret = request_firmware_direct(&fw, fwname, gpu->dev->dev);
+		if (ret)
+			fw = ERR_PTR(ret);
+	} else if (fwname) {
+		/* Request the MDT file from the default location: */
+		fw = adreno_request_fw(to_adreno_gpu(gpu), fwname);
+	} else {
+		/*
+		 * For new targets, we require the firmware-name property,
+		 * if a zap-shader is required, rather than falling back
+		 * to a firmware name specified in gpulist.
+		 *
+		 * Because the firmware is signed with a (potentially)
+		 * device specific key, having the name come from gpulist
+		 * was a bad idea, and is only provided for backwards
+		 * compatibility for older targets.
+		 */
+		return -ENOENT;
+	}
+
+	if (IS_ERR(fw)) {
+		DRM_DEV_ERROR(dev, "Unable to load %s\n", fwname);
+		return PTR_ERR(fw);
+	}
+
+	/* Figure out how much memory we need */
+	mem_size = qcom_mdt_get_size(fw);
+	if (mem_size < 0) {
+		ret = mem_size;
+		goto out;
+	}
+
+	if (mem_size > resource_size(&r)) {
+		DRM_DEV_ERROR(dev,
+			"memory region is too small to load the MDT\n");
+		ret = -E2BIG;
+		goto out;
+	}
+
+	/* Allocate memory for the firmware image */
+	mem_region = memremap(mem_phys, mem_size,  MEMREMAP_WC);
+	if (!mem_region) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/*
+	 * Load the rest of the MDT
+	 *
+	 * Note that we could be dealing with two different paths, since
+	 * with upstream linux-firmware it would be in a qcom/ subdir..
+	 * adreno_request_fw() handles this, but qcom_mdt_load() does
+	 * not.  But since we've already gotten through adreno_request_fw()
+	 * we know which of the two cases it is:
+	 */
+	if (signed_fwname || (to_adreno_gpu(gpu)->fwloc == FW_LOCATION_LEGACY)) {
+		ret = qcom_mdt_load(dev, fw, fwname, pasid,
+				mem_region, mem_phys, mem_size, NULL);
+	} else {
+		char *newname;
+
+		newname = kasprintf(GFP_KERNEL, "qcom/%s", fwname);
+
+		ret = qcom_mdt_load(dev, fw, newname, pasid,
+				mem_region, mem_phys, mem_size, NULL);
+		kfree(newname);
+	}
+	if (ret)
+		goto out;
+
+	/* Send the image to the secure world */
+	ret = qcom_scm_pas_auth_and_reset(pasid);
+
+	/*
+	 * If the scm call returns -EOPNOTSUPP we assume that this target
+	 * doesn't need/support the zap shader so quietly fail
+	 */
+	if (ret == -EOPNOTSUPP)
+		zap_available = false;
+	else if (ret)
+		DRM_DEV_ERROR(dev, "Unable to authorize the image\n");
+
+out:
+	if (mem_region)
+		memunmap(mem_region);
+
+	release_firmware(fw);
+
+	return ret;
+}
+
+int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	struct platform_device *pdev = gpu->pdev;
+
+	/* Short cut if we determine the zap shader isn't available/needed */
+	if (!zap_available)
+		return -ENODEV;
+
+	/* We need SCM to be able to load the firmware */
+	if (!qcom_scm_is_available()) {
+		DRM_DEV_ERROR(&pdev->dev, "SCM is not available\n");
+		return -EPROBE_DEFER;
+	}
+
+	return zap_shader_load_mdt(gpu, adreno_gpu->info->zapfw, pasid);
+}
+
+struct msm_gem_address_space *
+adreno_create_address_space(struct msm_gpu *gpu,
+			    struct platform_device *pdev)
+{
+	return adreno_iommu_create_address_space(gpu, pdev, 0);
+}
+
+struct msm_gem_address_space *
+adreno_iommu_create_address_space(struct msm_gpu *gpu,
+				  struct platform_device *pdev,
+				  unsigned long quirks)
+{
+	struct iommu_domain_geometry *geometry;
+	struct msm_mmu *mmu;
+	struct msm_gem_address_space *aspace;
+	u64 start, size;
+
+	mmu = msm_iommu_gpu_new(&pdev->dev, gpu, quirks);
+	if (IS_ERR_OR_NULL(mmu))
+		return ERR_CAST(mmu);
+
+	geometry = msm_iommu_get_geometry(mmu);
+	if (IS_ERR(geometry))
+		return ERR_CAST(geometry);
+
+	/*
+	 * Use the aperture start or SZ_16M, whichever is greater. This will
+	 * ensure that we align with the allocated pagetable range while still
+	 * allowing room in the lower 32 bits for GMEM and whatnot
+	 */
+	start = max_t(u64, SZ_16M, geometry->aperture_start);
+	size = geometry->aperture_end - start + 1;
+
+	aspace = msm_gem_address_space_create(mmu, "gpu",
+		start & GENMASK_ULL(48, 0), size);
+
+	if (IS_ERR(aspace) && !IS_ERR(mmu))
+		mmu->funcs->destroy(mmu);
+
+	return aspace;
+}
+
+u64 adreno_private_address_space_size(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+
+	if (address_space_size)
+		return address_space_size;
+
+	if (adreno_gpu->info->address_space_size)
+		return adreno_gpu->info->address_space_size;
+
+	return SZ_4G;
+}
+
+#define ARM_SMMU_FSR_TF                 BIT(1)
+#define ARM_SMMU_FSR_PF			BIT(3)
+#define ARM_SMMU_FSR_EF			BIT(4)
+
+int adreno_fault_handler(struct msm_gpu *gpu, unsigned long iova, int flags,
+			 struct adreno_smmu_fault_info *info, const char *block,
+			 u32 scratch[4])
+{
+	const char *type = "UNKNOWN";
+	bool do_devcoredump = info && !READ_ONCE(gpu->crashstate);
+
+	/*
+	 * If we aren't going to be resuming later from fault_worker, then do
+	 * it now.
+	 */
+	if (!do_devcoredump) {
+		gpu->aspace->mmu->funcs->resume_translation(gpu->aspace->mmu);
+	}
+
+	/*
+	 * Print a default message if we couldn't get the data from the
+	 * adreno-smmu-priv
+	 */
+	if (!info) {
+		pr_warn_ratelimited("*** gpu fault: iova=%.16lx flags=%d (%u,%u,%u,%u)\n",
+			iova, flags,
+			scratch[0], scratch[1], scratch[2], scratch[3]);
+
+		return 0;
+	}
+
+	if (info->fsr & ARM_SMMU_FSR_TF)
+		type = "TRANSLATION";
+	else if (info->fsr & ARM_SMMU_FSR_PF)
+		type = "PERMISSION";
+	else if (info->fsr & ARM_SMMU_FSR_EF)
+		type = "EXTERNAL";
+
+	pr_warn_ratelimited("*** gpu fault: ttbr0=%.16llx iova=%.16lx dir=%s type=%s source=%s (%u,%u,%u,%u)\n",
+			info->ttbr0, iova,
+			flags & IOMMU_FAULT_WRITE ? "WRITE" : "READ",
+			type, block,
+			scratch[0], scratch[1], scratch[2], scratch[3]);
+
+	if (do_devcoredump) {
+		/* Turn off the hangcheck timer to keep it from bothering us */
+		del_timer(&gpu->hangcheck_timer);
+
+		gpu->fault_info.ttbr0 = info->ttbr0;
+		gpu->fault_info.iova  = iova;
+		gpu->fault_info.flags = flags;
+		gpu->fault_info.type  = type;
+		gpu->fault_info.block = block;
+
+		kthread_queue_work(gpu->worker, &gpu->fault_work);
+	}
+
+	return 0;
+}
+
+int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
+		     uint32_t param, uint64_t *value, uint32_t *len)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+
+	/* No pointer params yet */
+	if (*len != 0)
+		return -EINVAL;
+
+	switch (param) {
+	case MSM_PARAM_GPU_ID:
+		*value = adreno_gpu->info->revn;
+		return 0;
+	case MSM_PARAM_GMEM_SIZE:
+		*value = adreno_gpu->info->gmem;
+		return 0;
+	case MSM_PARAM_GMEM_BASE:
+		if (adreno_is_a650_family(adreno_gpu) ||
+		    adreno_is_a740_family(adreno_gpu))
+			*value = 0;
+		else
+			*value = 0x100000;
+		return 0;
+	case MSM_PARAM_CHIP_ID:
+		*value = adreno_gpu->chip_id;
+		if (!adreno_gpu->info->revn)
+			*value |= ((uint64_t) adreno_gpu->speedbin) << 32;
+		return 0;
+	case MSM_PARAM_MAX_FREQ:
+		*value = adreno_gpu->base.fast_rate;
+		return 0;
+	case MSM_PARAM_TIMESTAMP:
+		if (adreno_gpu->funcs->get_timestamp) {
+			int ret;
+
+			pm_runtime_get_sync(&gpu->pdev->dev);
+			ret = adreno_gpu->funcs->get_timestamp(gpu, value);
+			pm_runtime_put_autosuspend(&gpu->pdev->dev);
+
+			return ret;
+		}
+		return -EINVAL;
+	case MSM_PARAM_PRIORITIES:
+		*value = gpu->nr_rings * NR_SCHED_PRIORITIES;
+		return 0;
+	case MSM_PARAM_PP_PGTABLE:
+		*value = 0;
+		return 0;
+	case MSM_PARAM_FAULTS:
+		if (ctx->aspace)
+			*value = gpu->global_faults + ctx->aspace->faults;
+		else
+			*value = gpu->global_faults;
+		return 0;
+	case MSM_PARAM_SUSPENDS:
+		*value = gpu->suspend_count;
+		return 0;
+	case MSM_PARAM_VA_START:
+		if (ctx->aspace == gpu->aspace)
+			return -EINVAL;
+		*value = ctx->aspace->va_start;
+		return 0;
+	case MSM_PARAM_VA_SIZE:
+		if (ctx->aspace == gpu->aspace)
+			return -EINVAL;
+		*value = ctx->aspace->va_size;
+		return 0;
+	case MSM_PARAM_HIGHEST_BANK_BIT:
+		*value = adreno_gpu->ubwc_config.highest_bank_bit;
+		return 0;
+	default:
+		DBG("%s: invalid param: %u", gpu->name, param);
+		return -EINVAL;
+	}
+}
+
+int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
+		     uint32_t param, uint64_t value, uint32_t len)
+{
+	switch (param) {
+	case MSM_PARAM_COMM:
+	case MSM_PARAM_CMDLINE:
+		/* kstrdup_quotable_cmdline() limits to PAGE_SIZE, so
+		 * that should be a reasonable upper bound
+		 */
+		if (len > PAGE_SIZE)
+			return -EINVAL;
+		break;
+	default:
+		if (len != 0)
+			return -EINVAL;
+	}
+
+	switch (param) {
+	case MSM_PARAM_COMM:
+	case MSM_PARAM_CMDLINE: {
+		char *str, **paramp;
+
+		str = memdup_user_nul(u64_to_user_ptr(value), len);
+		if (IS_ERR(str))
+			return PTR_ERR(str);
+
+		mutex_lock(&gpu->lock);
+
+		if (param == MSM_PARAM_COMM) {
+			paramp = &ctx->comm;
+		} else {
+			paramp = &ctx->cmdline;
+		}
+
+		kfree(*paramp);
+		*paramp = str;
+
+		mutex_unlock(&gpu->lock);
+
+		return 0;
+	}
+	case MSM_PARAM_SYSPROF:
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+		return msm_file_private_set_sysprof(ctx, gpu, value);
+	default:
+		DBG("%s: invalid param: %u", gpu->name, param);
+		return -EINVAL;
+	}
+}
+
+const struct firmware *
+adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname)
+{
+	struct drm_device *drm = adreno_gpu->base.dev;
+	const struct firmware *fw = NULL;
+	char *newname;
+	int ret;
+
+	newname = kasprintf(GFP_KERNEL, "qcom/%s", fwname);
+	if (!newname)
+		return ERR_PTR(-ENOMEM);
+
+	/*
+	 * Try first to load from qcom/$fwfile using a direct load (to avoid
+	 * a potential timeout waiting for usermode helper)
+	 */
+	if ((adreno_gpu->fwloc == FW_LOCATION_UNKNOWN) ||
+	    (adreno_gpu->fwloc == FW_LOCATION_NEW)) {
+
+		ret = request_firmware_direct(&fw, newname, drm->dev);
+		if (!ret) {
+			DRM_DEV_INFO(drm->dev, "loaded %s from new location\n",
+				newname);
+			adreno_gpu->fwloc = FW_LOCATION_NEW;
+			goto out;
+		} else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {
+			DRM_DEV_ERROR(drm->dev, "failed to load %s: %d\n",
+				newname, ret);
+			fw = ERR_PTR(ret);
+			goto out;
+		}
+	}
+
+	/*
+	 * Then try the legacy location without qcom/ prefix
+	 */
+	if ((adreno_gpu->fwloc == FW_LOCATION_UNKNOWN) ||
+	    (adreno_gpu->fwloc == FW_LOCATION_LEGACY)) {
+
+		ret = request_firmware_direct(&fw, fwname, drm->dev);
+		if (!ret) {
+			DRM_DEV_INFO(drm->dev, "loaded %s from legacy location\n",
+				fwname);
+			adreno_gpu->fwloc = FW_LOCATION_LEGACY;
+			goto out;
+		} else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {
+			DRM_DEV_ERROR(drm->dev, "failed to load %s: %d\n",
+				fwname, ret);
+			fw = ERR_PTR(ret);
+			goto out;
+		}
+	}
+
+	/*
+	 * Finally fall back to request_firmware() for cases where the
+	 * usermode helper is needed (I think mainly android)
+	 */
+	if ((adreno_gpu->fwloc == FW_LOCATION_UNKNOWN) ||
+	    (adreno_gpu->fwloc == FW_LOCATION_HELPER)) {
+
+		ret = request_firmware(&fw, newname, drm->dev);
+		if (!ret) {
+			DRM_DEV_INFO(drm->dev, "loaded %s with helper\n",
+				newname);
+			adreno_gpu->fwloc = FW_LOCATION_HELPER;
+			goto out;
+		} else if (adreno_gpu->fwloc != FW_LOCATION_UNKNOWN) {
+			DRM_DEV_ERROR(drm->dev, "failed to load %s: %d\n",
+				newname, ret);
+			fw = ERR_PTR(ret);
+			goto out;
+		}
+	}
+
+	DRM_DEV_ERROR(drm->dev, "failed to load %s\n", fwname);
+	fw = ERR_PTR(-ENOENT);
+out:
+	kfree(newname);
+	return fw;
+}
+
+int adreno_load_fw(struct adreno_gpu *adreno_gpu)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++) {
+		const struct firmware *fw;
+
+		if (!adreno_gpu->info->fw[i])
+			continue;
+
+		/* Skip loading GMU firwmare with GMU Wrapper */
+		if (adreno_has_gmu_wrapper(adreno_gpu) && i == ADRENO_FW_GMU)
+			continue;
+
+		/* Skip if the firmware has already been loaded */
+		if (adreno_gpu->fw[i])
+			continue;
+
+		fw = adreno_request_fw(adreno_gpu, adreno_gpu->info->fw[i]);
+		if (IS_ERR(fw))
+			return PTR_ERR(fw);
+
+		adreno_gpu->fw[i] = fw;
+	}
+
+	return 0;
+}
+
+struct drm_gem_object *adreno_fw_create_bo(struct msm_gpu *gpu,
+		const struct firmware *fw, u64 *iova)
+{
+	struct drm_gem_object *bo;
+	void *ptr;
+
+	ptr = msm_gem_kernel_new(gpu->dev, fw->size - 4,
+		MSM_BO_WC | MSM_BO_GPU_READONLY, gpu->aspace, &bo, iova);
+
+	if (IS_ERR(ptr))
+		return ERR_CAST(ptr);
+
+	memcpy(ptr, &fw->data[4], fw->size - 4);
+
+	msm_gem_put_vaddr(bo);
+
+	return bo;
+}
+
+int adreno_hw_init(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	int ret;
+
+	VERB("%s", gpu->name);
+
+	if (adreno_gpu->info->family >= ADRENO_6XX_GEN1 &&
+	    qcom_scm_set_gpu_smmu_aperture_is_available()) {
+		/* We currently always use context bank 0, so hard code this */
+		ret = qcom_scm_set_gpu_smmu_aperture(0);
+		if (ret)
+			DRM_DEV_ERROR(gpu->dev->dev, "unable to set SMMU aperture: %d\n", ret);
+	}
+
+	for (int i = 0; i < gpu->nr_rings; i++) {
+		struct msm_ringbuffer *ring = gpu->rb[i];
+
+		if (!ring)
+			continue;
+
+		ring->cur = ring->start;
+		ring->next = ring->start;
+		ring->memptrs->rptr = 0;
+		ring->memptrs->bv_fence = ring->fctx->completed_fence;
+
+		/* Detect and clean up an impossible fence, ie. if GPU managed
+		 * to scribble something invalid, we don't want that to confuse
+		 * us into mistakingly believing that submits have completed.
+		 */
+		if (fence_before(ring->fctx->last_fence, ring->memptrs->fence)) {
+			ring->memptrs->fence = ring->fctx->last_fence;
+		}
+	}
+
+	return 0;
+}
+
+/* Use this helper to read rptr, since a430 doesn't update rptr in memory */
+static uint32_t get_rptr(struct adreno_gpu *adreno_gpu,
+		struct msm_ringbuffer *ring)
+{
+	struct msm_gpu *gpu = &adreno_gpu->base;
+
+	return gpu->funcs->get_rptr(gpu, ring);
+}
+
+struct msm_ringbuffer *adreno_active_ring(struct msm_gpu *gpu)
+{
+	return gpu->rb[0];
+}
+
+void adreno_recover(struct msm_gpu *gpu)
+{
+	struct drm_device *dev = gpu->dev;
+	int ret;
+
+	// XXX pm-runtime??  we *need* the device to be off after this
+	// so maybe continuing to call ->pm_suspend/resume() is better?
+
+	gpu->funcs->pm_suspend(gpu);
+	gpu->funcs->pm_resume(gpu);
+
+	ret = msm_gpu_hw_init(gpu);
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev, "gpu hw init failed: %d\n", ret);
+		/* hmm, oh well? */
+	}
+}
+
+void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring, u32 reg)
+{
+	uint32_t wptr;
+
+	/* Copy the shadow to the actual register */
+	ring->cur = ring->next;
+
+	/*
+	 * Mask wptr value that we calculate to fit in the HW range. This is
+	 * to account for the possibility that the last command fit exactly into
+	 * the ringbuffer and rb->next hasn't wrapped to zero yet
+	 */
+	wptr = get_wptr(ring);
+
+	/* ensure writes to ringbuffer have hit system memory: */
+	mb();
+
+	gpu_write(gpu, reg, wptr);
+}
+
+bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	uint32_t wptr = get_wptr(ring);
+
+	/* wait for CP to drain ringbuffer: */
+	if (!spin_until(get_rptr(adreno_gpu, ring) == wptr))
+		return true;
+
+	/* TODO maybe we need to reset GPU here to recover from hang? */
+	DRM_ERROR("%s: timeout waiting to drain ringbuffer %d rptr/wptr = %X/%X\n",
+		gpu->name, ring->id, get_rptr(adreno_gpu, ring), wptr);
+
+	return false;
+}
+
+int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	int i, count = 0;
+
+	WARN_ON(!mutex_is_locked(&gpu->lock));
+
+	kref_init(&state->ref);
+
+	ktime_get_real_ts64(&state->time);
+
+	for (i = 0; i < gpu->nr_rings; i++) {
+		int size = 0, j;
+
+		state->ring[i].fence = gpu->rb[i]->memptrs->fence;
+		state->ring[i].iova = gpu->rb[i]->iova;
+		state->ring[i].seqno = gpu->rb[i]->fctx->last_fence;
+		state->ring[i].rptr = get_rptr(adreno_gpu, gpu->rb[i]);
+		state->ring[i].wptr = get_wptr(gpu->rb[i]);
+
+		/* Copy at least 'wptr' dwords of the data */
+		size = state->ring[i].wptr;
+
+		/* After wptr find the last non zero dword to save space */
+		for (j = state->ring[i].wptr; j < MSM_GPU_RINGBUFFER_SZ >> 2; j++)
+			if (gpu->rb[i]->start[j])
+				size = j + 1;
+
+		if (size) {
+			state->ring[i].data = kvmalloc(size << 2, GFP_KERNEL);
+			if (state->ring[i].data) {
+				memcpy(state->ring[i].data, gpu->rb[i]->start, size << 2);
+				state->ring[i].data_size = size << 2;
+			}
+		}
+	}
+
+	/* Some targets prefer to collect their own registers */
+	if (!adreno_gpu->registers)
+		return 0;
+
+	/* Count the number of registers */
+	for (i = 0; adreno_gpu->registers[i] != ~0; i += 2)
+		count += adreno_gpu->registers[i + 1] -
+			adreno_gpu->registers[i] + 1;
+
+	state->registers = kcalloc(count * 2, sizeof(u32), GFP_KERNEL);
+	if (state->registers) {
+		int pos = 0;
+
+		for (i = 0; adreno_gpu->registers[i] != ~0; i += 2) {
+			u32 start = adreno_gpu->registers[i];
+			u32 end   = adreno_gpu->registers[i + 1];
+			u32 addr;
+
+			for (addr = start; addr <= end; addr++) {
+				state->registers[pos++] = addr;
+				state->registers[pos++] = gpu_read(gpu, addr);
+			}
+		}
+
+		state->nr_registers = count;
+	}
+
+	return 0;
+}
+
+void adreno_gpu_state_destroy(struct msm_gpu_state *state)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(state->ring); i++)
+		kvfree(state->ring[i].data);
+
+	for (i = 0; state->bos && i < state->nr_bos; i++)
+		kvfree(state->bos[i].data);
+
+	kfree(state->bos);
+	kfree(state->comm);
+	kfree(state->cmd);
+	kfree(state->registers);
+}
+
+static void adreno_gpu_state_kref_destroy(struct kref *kref)
+{
+	struct msm_gpu_state *state = container_of(kref,
+		struct msm_gpu_state, ref);
+
+	adreno_gpu_state_destroy(state);
+	kfree(state);
+}
+
+int adreno_gpu_state_put(struct msm_gpu_state *state)
+{
+	if (IS_ERR_OR_NULL(state))
+		return 1;
+
+	return kref_put(&state->ref, adreno_gpu_state_kref_destroy);
+}
+
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
+
+static char *adreno_gpu_ascii85_encode(u32 *src, size_t len)
+{
+	void *buf;
+	size_t buf_itr = 0, buffer_size;
+	char out[ASCII85_BUFSZ];
+	long l;
+	int i;
+
+	if (!src || !len)
+		return NULL;
+
+	l = ascii85_encode_len(len);
+
+	/*
+	 * Ascii85 outputs either a 5 byte string or a 1 byte string. So we
+	 * account for the worst case of 5 bytes per dword plus the 1 for '\0'
+	 */
+	buffer_size = (l * 5) + 1;
+
+	buf = kvmalloc(buffer_size, GFP_KERNEL);
+	if (!buf)
+		return NULL;
+
+	for (i = 0; i < l; i++)
+		buf_itr += scnprintf(buf + buf_itr, buffer_size - buf_itr, "%s",
+				ascii85_encode(src[i], out));
+
+	return buf;
+}
+
+/* len is expected to be in bytes
+ *
+ * WARNING: *ptr should be allocated with kvmalloc or friends.  It can be free'd
+ * with kvfree() and replaced with a newly kvmalloc'd buffer on the first call
+ * when the unencoded raw data is encoded
+ */
+void adreno_show_object(struct drm_printer *p, void **ptr, int len,
+		bool *encoded)
+{
+	if (!*ptr || !len)
+		return;
+
+	if (!*encoded) {
+		long datalen, i;
+		u32 *buf = *ptr;
+
+		/*
+		 * Only dump the non-zero part of the buffer - rarely will
+		 * any data completely fill the entire allocated size of
+		 * the buffer.
+		 */
+		for (datalen = 0, i = 0; i < len >> 2; i++)
+			if (buf[i])
+				datalen = ((i + 1) << 2);
+
+		/*
+		 * If we reach here, then the originally captured binary buffer
+		 * will be replaced with the ascii85 encoded string
+		 */
+		*ptr = adreno_gpu_ascii85_encode(buf, datalen);
+
+		kvfree(buf);
+
+		*encoded = true;
+	}
+
+	if (!*ptr)
+		return;
+
+	drm_puts(p, "    data: !!ascii85 |\n");
+	drm_puts(p, "     ");
+
+	drm_puts(p, *ptr);
+
+	drm_puts(p, "\n");
+}
+
+void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		struct drm_printer *p)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	int i;
+
+	if (IS_ERR_OR_NULL(state))
+		return;
+
+	drm_printf(p, "revision: %u (%"ADRENO_CHIPID_FMT")\n",
+			adreno_gpu->info->revn,
+			ADRENO_CHIPID_ARGS(adreno_gpu->chip_id));
+	/*
+	 * If this is state collected due to iova fault, so fault related info
+	 *
+	 * TTBR0 would not be zero, so this is a good way to distinguish
+	 */
+	if (state->fault_info.ttbr0) {
+		const struct msm_gpu_fault_info *info = &state->fault_info;
+
+		drm_puts(p, "fault-info:\n");
+		drm_printf(p, "  - ttbr0=%.16llx\n", info->ttbr0);
+		drm_printf(p, "  - iova=%.16lx\n", info->iova);
+		drm_printf(p, "  - dir=%s\n", info->flags & IOMMU_FAULT_WRITE ? "WRITE" : "READ");
+		drm_printf(p, "  - type=%s\n", info->type);
+		drm_printf(p, "  - source=%s\n", info->block);
+	}
+
+	drm_printf(p, "rbbm-status: 0x%08x\n", state->rbbm_status);
+
+	drm_puts(p, "ringbuffer:\n");
+
+	for (i = 0; i < gpu->nr_rings; i++) {
+		drm_printf(p, "  - id: %d\n", i);
+		drm_printf(p, "    iova: 0x%016llx\n", state->ring[i].iova);
+		drm_printf(p, "    last-fence: %u\n", state->ring[i].seqno);
+		drm_printf(p, "    retired-fence: %u\n", state->ring[i].fence);
+		drm_printf(p, "    rptr: %u\n", state->ring[i].rptr);
+		drm_printf(p, "    wptr: %u\n", state->ring[i].wptr);
+		drm_printf(p, "    size: %u\n", MSM_GPU_RINGBUFFER_SZ);
+
+		adreno_show_object(p, &state->ring[i].data,
+			state->ring[i].data_size, &state->ring[i].encoded);
+	}
+
+	if (state->bos) {
+		drm_puts(p, "bos:\n");
+
+		for (i = 0; i < state->nr_bos; i++) {
+			drm_printf(p, "  - iova: 0x%016llx\n",
+				state->bos[i].iova);
+			drm_printf(p, "    size: %zd\n", state->bos[i].size);
+			drm_printf(p, "    name: %-32s\n", state->bos[i].name);
+
+			adreno_show_object(p, &state->bos[i].data,
+				state->bos[i].size, &state->bos[i].encoded);
+		}
+	}
+
+	if (state->nr_registers) {
+		drm_puts(p, "registers:\n");
+
+		for (i = 0; i < state->nr_registers; i++) {
+			drm_printf(p, "  - { offset: 0x%04x, value: 0x%08x }\n",
+				state->registers[i * 2] << 2,
+				state->registers[(i * 2) + 1]);
+		}
+	}
+}
+#endif
+
+/* Dump common gpu status and scratch registers on any hang, to make
+ * the hangcheck logs more useful.  The scratch registers seem always
+ * safe to read when GPU has hung (unlike some other regs, depending
+ * on how the GPU hung), and they are useful to match up to cmdstream
+ * dumps when debugging hangs:
+ */
+void adreno_dump_info(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	int i;
+
+	printk("revision: %u (%"ADRENO_CHIPID_FMT")\n",
+			adreno_gpu->info->revn,
+			ADRENO_CHIPID_ARGS(adreno_gpu->chip_id));
+
+	for (i = 0; i < gpu->nr_rings; i++) {
+		struct msm_ringbuffer *ring = gpu->rb[i];
+
+		printk("rb %d: fence:    %d/%d\n", i,
+			ring->memptrs->fence,
+			ring->fctx->last_fence);
+
+		printk("rptr:     %d\n", get_rptr(adreno_gpu, ring));
+		printk("rb wptr:  %d\n", get_wptr(ring));
+	}
+}
+
+/* would be nice to not have to duplicate the _show() stuff with printk(): */
+void adreno_dump(struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	int i;
+
+	if (!adreno_gpu->registers)
+		return;
+
+	/* dump these out in a form that can be parsed by demsm: */
+	printk("IO:region %s 00000000 00020000\n", gpu->name);
+	for (i = 0; adreno_gpu->registers[i] != ~0; i += 2) {
+		uint32_t start = adreno_gpu->registers[i];
+		uint32_t end   = adreno_gpu->registers[i+1];
+		uint32_t addr;
+
+		for (addr = start; addr <= end; addr++) {
+			uint32_t val = gpu_read(gpu, addr);
+			printk("IO:R %08x %08x\n", addr<<2, val);
+		}
+	}
+}
+
+static uint32_t ring_freewords(struct msm_ringbuffer *ring)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(ring->gpu);
+	uint32_t size = MSM_GPU_RINGBUFFER_SZ >> 2;
+	/* Use ring->next to calculate free size */
+	uint32_t wptr = ring->next - ring->start;
+	uint32_t rptr = get_rptr(adreno_gpu, ring);
+	return (rptr + (size - 1) - wptr) % size;
+}
+
+void adreno_wait_ring(struct msm_ringbuffer *ring, uint32_t ndwords)
+{
+	if (spin_until(ring_freewords(ring) >= ndwords))
+		DRM_DEV_ERROR(ring->gpu->dev->dev,
+			"timeout waiting for space in ringbuffer %d\n",
+			ring->id);
+}
+
+static int adreno_get_pwrlevels(struct device *dev,
+		struct msm_gpu *gpu)
+{
+	struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+	unsigned long freq = ULONG_MAX;
+	struct dev_pm_opp *opp;
+	int ret;
+
+	gpu->fast_rate = 0;
+
+	/* devm_pm_opp_of_add_table may error out but will still create an OPP table */
+	ret = devm_pm_opp_of_add_table(dev);
+	if (ret == -ENODEV) {
+		/* Special cases for ancient hw with ancient DT bindings */
+		if (adreno_is_a2xx(adreno_gpu)) {
+			dev_warn(dev, "Unable to find the OPP table. Falling back to 200 MHz.\n");
+			dev_pm_opp_add(dev, 200000000, 0);
+		} else if (adreno_is_a320(adreno_gpu)) {
+			dev_warn(dev, "Unable to find the OPP table. Falling back to 450 MHz.\n");
+			dev_pm_opp_add(dev, 450000000, 0);
+		} else {
+			DRM_DEV_ERROR(dev, "Unable to find the OPP table\n");
+			return -ENODEV;
+		}
+	} else if (ret) {
+		DRM_DEV_ERROR(dev, "Unable to set the OPP table\n");
+		return ret;
+	}
+
+	/* Find the fastest defined rate */
+	opp = dev_pm_opp_find_freq_floor(dev, &freq);
+	if (IS_ERR(opp))
+		return PTR_ERR(opp);
+
+	gpu->fast_rate = freq;
+	dev_pm_opp_put(opp);
+
+	DBG("fast_rate=%u, slow_rate=27000000", gpu->fast_rate);
+
+	return 0;
+}
+
+int adreno_gpu_ocmem_init(struct device *dev, struct adreno_gpu *adreno_gpu,
+			  struct adreno_ocmem *adreno_ocmem)
+{
+	struct ocmem_buf *ocmem_hdl;
+	struct ocmem *ocmem;
+
+	ocmem = of_get_ocmem(dev);
+	if (IS_ERR(ocmem)) {
+		if (PTR_ERR(ocmem) == -ENODEV) {
+			/*
+			 * Return success since either the ocmem property was
+			 * not specified in device tree, or ocmem support is
+			 * not compiled into the kernel.
+			 */
+			return 0;
+		}
+
+		return PTR_ERR(ocmem);
+	}
+
+	ocmem_hdl = ocmem_allocate(ocmem, OCMEM_GRAPHICS, adreno_gpu->info->gmem);
+	if (IS_ERR(ocmem_hdl))
+		return PTR_ERR(ocmem_hdl);
+
+	adreno_ocmem->ocmem = ocmem;
+	adreno_ocmem->base = ocmem_hdl->addr;
+	adreno_ocmem->hdl = ocmem_hdl;
+
+	if (WARN_ON(ocmem_hdl->len != adreno_gpu->info->gmem))
+		return -ENOMEM;
+
+	return 0;
+}
+
+void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *adreno_ocmem)
+{
+	if (adreno_ocmem && adreno_ocmem->base)
+		ocmem_free(adreno_ocmem->ocmem, OCMEM_GRAPHICS,
+			   adreno_ocmem->hdl);
+}
+
+int adreno_read_speedbin(struct device *dev, u32 *speedbin)
+{
+	return nvmem_cell_read_variable_le_u32(dev, "speed_bin", speedbin);
+}
+
+int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
+		struct adreno_gpu *adreno_gpu,
+		const struct adreno_gpu_funcs *funcs, int nr_rings)
+{
+	struct device *dev = &pdev->dev;
+	struct adreno_platform_config *config = dev->platform_data;
+	struct msm_gpu_config adreno_gpu_config  = { 0 };
+	struct msm_gpu *gpu = &adreno_gpu->base;
+	const char *gpu_name;
+	u32 speedbin;
+	int ret;
+
+	adreno_gpu->funcs = funcs;
+	adreno_gpu->info = config->info;
+	adreno_gpu->chip_id = config->chip_id;
+
+	gpu->allow_relocs = config->info->family < ADRENO_6XX_GEN1;
+	gpu->pdev = pdev;
+
+	/* Only handle the core clock when GMU is not in use (or is absent). */
+	if (adreno_has_gmu_wrapper(adreno_gpu) ||
+	    adreno_gpu->info->family < ADRENO_6XX_GEN1) {
+		/*
+		 * This can only be done before devm_pm_opp_of_add_table(), or
+		 * dev_pm_opp_set_config() will WARN_ON()
+		 */
+		if (IS_ERR(devm_clk_get(dev, "core"))) {
+			/*
+			 * If "core" is absent, go for the legacy clock name.
+			 * If we got this far in probing, it's a given one of
+			 * them exists.
+			 */
+			devm_pm_opp_set_clkname(dev, "core_clk");
+		} else
+			devm_pm_opp_set_clkname(dev, "core");
+	}
+
+	if (adreno_read_speedbin(dev, &speedbin) || !speedbin)
+		speedbin = 0xffff;
+	adreno_gpu->speedbin = (uint16_t) (0xffff & speedbin);
+
+	gpu_name = devm_kasprintf(dev, GFP_KERNEL, "%"ADRENO_CHIPID_FMT,
+			ADRENO_CHIPID_ARGS(config->chip_id));
+	if (!gpu_name)
+		return -ENOMEM;
+
+	adreno_gpu_config.ioname = "kgsl_3d0_reg_memory";
+
+	adreno_gpu_config.nr_rings = nr_rings;
+
+	ret = adreno_get_pwrlevels(dev, gpu);
+	if (ret)
+		return ret;
+
+	pm_runtime_set_autosuspend_delay(dev,
+		adreno_gpu->info->inactive_period);
+	pm_runtime_use_autosuspend(dev);
+
+	return msm_gpu_init(drm, pdev, &adreno_gpu->base, &funcs->base,
+			gpu_name, &adreno_gpu_config);
+}
+
+void adreno_gpu_cleanup(struct adreno_gpu *adreno_gpu)
+{
+	struct msm_gpu *gpu = &adreno_gpu->base;
+	struct msm_drm_private *priv = gpu->dev ? gpu->dev->dev_private : NULL;
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++)
+		release_firmware(adreno_gpu->fw[i]);
+
+	if (priv && pm_runtime_enabled(&priv->gpu_pdev->dev))
+		pm_runtime_disable(&priv->gpu_pdev->dev);
+
+	msm_gpu_cleanup(&adreno_gpu->base);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/adreno/adreno_gpu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/adreno/adreno_gpu.h
@@ -0,0 +1,688 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * Copyright (c) 2014,2017, 2019 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __ADRENO_GPU_H__
+#define __ADRENO_GPU_H__
+
+#include <linux/firmware.h>
+#include <linux/iopoll.h>
+
+#include "msm_gpu.h"
+
+#include "adreno_common.xml.h"
+#include "adreno_pm4.xml.h"
+
+extern bool snapshot_debugbus;
+extern bool allow_vram_carveout;
+
+enum {
+	ADRENO_FW_PM4 = 0,
+	ADRENO_FW_SQE = 0, /* a6xx */
+	ADRENO_FW_PFP = 1,
+	ADRENO_FW_GMU = 1, /* a6xx */
+	ADRENO_FW_GPMU = 2,
+	ADRENO_FW_MAX,
+};
+
+/**
+ * @enum adreno_family: identify generation and possibly sub-generation
+ *
+ * In some cases there are distinct sub-generations within a major revision
+ * so it helps to be able to group the GPU devices by generation and if
+ * necessary sub-generation.
+ */
+enum adreno_family {
+	ADRENO_2XX_GEN1,  /* a20x */
+	ADRENO_2XX_GEN2,  /* a22x */
+	ADRENO_3XX,
+	ADRENO_4XX,
+	ADRENO_5XX,
+	ADRENO_6XX_GEN1,  /* a630 family */
+	ADRENO_6XX_GEN2,  /* a640 family */
+	ADRENO_6XX_GEN3,  /* a650 family */
+	ADRENO_6XX_GEN4,  /* a660 family */
+	ADRENO_7XX_GEN1,  /* a730 family */
+	ADRENO_7XX_GEN2,  /* a740 family */
+	ADRENO_7XX_GEN3,  /* a750 family */
+};
+
+#define ADRENO_QUIRK_TWO_PASS_USE_WFI		BIT(0)
+#define ADRENO_QUIRK_FAULT_DETECT_MASK		BIT(1)
+#define ADRENO_QUIRK_LMLOADKILL_DISABLE		BIT(2)
+#define ADRENO_QUIRK_HAS_HW_APRIV		BIT(3)
+#define ADRENO_QUIRK_HAS_CACHED_COHERENT	BIT(4)
+
+/* Helper for formating the chip_id in the way that userspace tools like
+ * crashdec expect.
+ */
+#define ADRENO_CHIPID_FMT "u.%u.%u.%u"
+#define ADRENO_CHIPID_ARGS(_c) \
+	(((_c) >> 24) & 0xff), \
+	(((_c) >> 16) & 0xff), \
+	(((_c) >> 8)  & 0xff), \
+	((_c) & 0xff)
+
+struct adreno_gpu_funcs {
+	struct msm_gpu_funcs base;
+	int (*get_timestamp)(struct msm_gpu *gpu, uint64_t *value);
+};
+
+struct adreno_reglist {
+	u32 offset;
+	u32 value;
+};
+
+struct adreno_speedbin {
+	uint16_t fuse;
+	uint16_t speedbin;
+};
+
+struct a6xx_info;
+
+struct adreno_info {
+	const char *machine;
+	/**
+	 * @chipids: Table of matching chip-ids
+	 *
+	 * Terminated with 0 sentinal
+	 */
+	uint32_t *chip_ids;
+	enum adreno_family family;
+	uint32_t revn;
+	const char *fw[ADRENO_FW_MAX];
+	uint32_t gmem;
+	u64 quirks;
+	struct msm_gpu *(*init)(struct drm_device *dev);
+	const char *zapfw;
+	u32 inactive_period;
+	union {
+		const struct a6xx_info *a6xx;
+	};
+	u64 address_space_size;
+	/**
+	 * @speedbins: Optional table of fuse to speedbin mappings
+	 *
+	 * Consists of pairs of fuse, index mappings, terminated with
+	 * {SHRT_MAX, 0} sentinal.
+	 */
+	struct adreno_speedbin *speedbins;
+};
+
+#define ADRENO_CHIP_IDS(tbl...) (uint32_t[]) { tbl, 0 }
+
+struct adreno_gpulist {
+	const struct adreno_info *gpus;
+	unsigned gpus_count;
+};
+
+#define DECLARE_ADRENO_GPULIST(name)                  \
+const struct adreno_gpulist name ## _gpulist = {      \
+	name ## _gpus, ARRAY_SIZE(name ## _gpus)      \
+}
+
+/*
+ * Helper to build a speedbin table, ie. the table:
+ *      fuse | speedbin
+ *      -----+---------
+ *        0  |   0
+ *       169 |   1
+ *       174 |   2
+ *
+ * would be declared as:
+ *
+ *     .speedbins = ADRENO_SPEEDBINS(
+ *                      { 0,   0 },
+ *                      { 169, 1 },
+ *                      { 174, 2 },
+ *     ),
+ */
+#define ADRENO_SPEEDBINS(tbl...) (struct adreno_speedbin[]) { tbl {SHRT_MAX, 0} }
+
+struct adreno_protect {
+	const uint32_t *regs;
+	uint32_t count;
+	uint32_t count_max;
+};
+
+#define DECLARE_ADRENO_PROTECT(name, __count_max)	\
+static const struct adreno_protect name = {		\
+	.regs = name ## _regs,				\
+	.count = ARRAY_SIZE(name ## _regs),		\
+	.count_max = __count_max,			\
+};
+
+struct adreno_gpu {
+	struct msm_gpu base;
+	const struct adreno_info *info;
+	uint32_t chip_id;
+	uint16_t speedbin;
+	const struct adreno_gpu_funcs *funcs;
+
+	/* interesting register offsets to dump: */
+	const unsigned int *registers;
+
+	/*
+	 * Are we loading fw from legacy path?  Prior to addition
+	 * of gpu firmware to linux-firmware, the fw files were
+	 * placed in toplevel firmware directory, following qcom's
+	 * android kernel.  But linux-firmware preferred they be
+	 * placed in a 'qcom' subdirectory.
+	 *
+	 * For backwards compatibility, we try first to load from
+	 * the new path, using request_firmware_direct() to avoid
+	 * any potential timeout waiting for usermode helper, then
+	 * fall back to the old path (with direct load).  And
+	 * finally fall back to request_firmware() with the new
+	 * path to allow the usermode helper.
+	 */
+	enum {
+		FW_LOCATION_UNKNOWN = 0,
+		FW_LOCATION_NEW,       /* /lib/firmware/qcom/$fwfile */
+		FW_LOCATION_LEGACY,    /* /lib/firmware/$fwfile */
+		FW_LOCATION_HELPER,
+	} fwloc;
+
+	/* firmware: */
+	const struct firmware *fw[ADRENO_FW_MAX];
+
+	struct {
+		/**
+		 * @rgb565_predicator: Unknown, introduced with A650 family,
+		 * related to UBWC mode/ver 4
+		 */
+		u32 rgb565_predicator;
+		/** @uavflagprd_inv: Unknown, introduced with A650 family */
+		u32 uavflagprd_inv;
+		/** @min_acc_len: Whether the minimum access length is 64 bits */
+		u32 min_acc_len;
+		/**
+		 * @ubwc_swizzle: Whether to enable level 1, 2 & 3 bank swizzling.
+		 *
+		 * UBWC 1.0 always enables all three levels.
+		 * UBWC 2.0 removes level 1 bank swizzling, leaving levels 2 & 3.
+		 * UBWC 4.0 adds the optional ability to disable levels 2 & 3.
+		 *
+		 * This is a bitmask where BIT(0) enables level 1, BIT(1)
+		 * controls level 2, and BIT(2) enables level 3.
+		 */
+		u32 ubwc_swizzle;
+		/**
+		 * @highest_bank_bit: Highest Bank Bit
+		 *
+		 * The Highest Bank Bit value represents the bit of the highest
+		 * DDR bank.  This should ideally use DRAM type detection.
+		 */
+		u32 highest_bank_bit;
+		u32 amsbc;
+		/**
+		 * @macrotile_mode: Macrotile Mode
+		 *
+		 * Whether to use 4-channel macrotiling mode or the newer
+		 * 8-channel macrotiling mode introduced in UBWC 3.1. 0 is
+		 * 4-channel and 1 is 8-channel.
+		 */
+		u32 macrotile_mode;
+	} ubwc_config;
+
+	/*
+	 * Register offsets are different between some GPUs.
+	 * GPU specific offsets will be exported by GPU specific
+	 * code (a3xx_gpu.c) and stored in this common location.
+	 */
+	const unsigned int *reg_offsets;
+	bool gmu_is_wrapper;
+};
+#define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base)
+
+struct adreno_ocmem {
+	struct ocmem *ocmem;
+	unsigned long base;
+	void *hdl;
+};
+
+/* platform config data (ie. from DT, or pdata) */
+struct adreno_platform_config {
+	uint32_t chip_id;
+	const struct adreno_info *info;
+};
+
+#define ADRENO_IDLE_TIMEOUT msecs_to_jiffies(1000)
+
+#define spin_until(X) ({                                   \
+	int __ret = -ETIMEDOUT;                            \
+	unsigned long __t = jiffies + ADRENO_IDLE_TIMEOUT; \
+	do {                                               \
+		if (X) {                                   \
+			__ret = 0;                         \
+			break;                             \
+		}                                          \
+	} while (time_before(jiffies, __t));               \
+	__ret;                                             \
+})
+
+static inline uint8_t adreno_patchid(const struct adreno_gpu *gpu)
+{
+	/* It is probably ok to assume legacy "adreno_rev" format
+	 * for all a6xx devices, but probably best to limit this
+	 * to older things.
+	 */
+	WARN_ON_ONCE(gpu->info->family >= ADRENO_6XX_GEN1);
+	return gpu->chip_id & 0xff;
+}
+
+static inline bool adreno_is_revn(const struct adreno_gpu *gpu, uint32_t revn)
+{
+	if (WARN_ON_ONCE(!gpu->info))
+		return false;
+	return gpu->info->revn == revn;
+}
+
+static inline bool adreno_has_gmu_wrapper(const struct adreno_gpu *gpu)
+{
+	return gpu->gmu_is_wrapper;
+}
+
+static inline bool adreno_is_a2xx(const struct adreno_gpu *gpu)
+{
+	if (WARN_ON_ONCE(!gpu->info))
+		return false;
+	return gpu->info->family <= ADRENO_2XX_GEN2;
+}
+
+static inline bool adreno_is_a20x(const struct adreno_gpu *gpu)
+{
+	if (WARN_ON_ONCE(!gpu->info))
+		return false;
+	return gpu->info->family == ADRENO_2XX_GEN1;
+}
+
+static inline bool adreno_is_a225(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 225);
+}
+
+static inline bool adreno_is_a305(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 305);
+}
+
+static inline bool adreno_is_a305b(const struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x03000512;
+}
+
+static inline bool adreno_is_a306(const struct adreno_gpu *gpu)
+{
+	/* yes, 307, because a305c is 306 */
+	return adreno_is_revn(gpu, 307);
+}
+
+static inline bool adreno_is_a320(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 320);
+}
+
+static inline bool adreno_is_a330(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 330);
+}
+
+static inline bool adreno_is_a330v2(const struct adreno_gpu *gpu)
+{
+	return adreno_is_a330(gpu) && (adreno_patchid(gpu) > 0);
+}
+
+static inline int adreno_is_a405(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 405);
+}
+
+static inline int adreno_is_a420(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 420);
+}
+
+static inline int adreno_is_a430(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 430);
+}
+
+static inline int adreno_is_a506(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 506);
+}
+
+static inline int adreno_is_a508(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 508);
+}
+
+static inline int adreno_is_a509(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 509);
+}
+
+static inline int adreno_is_a510(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 510);
+}
+
+static inline int adreno_is_a512(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 512);
+}
+
+static inline int adreno_is_a530(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 530);
+}
+
+static inline int adreno_is_a540(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 540);
+}
+
+static inline int adreno_is_a610(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 610);
+}
+
+static inline int adreno_is_a618(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 618);
+}
+
+static inline int adreno_is_a619(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 619);
+}
+
+static inline int adreno_is_a619_holi(const struct adreno_gpu *gpu)
+{
+	return adreno_is_a619(gpu) && adreno_has_gmu_wrapper(gpu);
+}
+
+static inline int adreno_is_a630(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 630);
+}
+
+static inline int adreno_is_a640(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 640);
+}
+
+static inline int adreno_is_a650(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 650);
+}
+
+static inline int adreno_is_7c3(const struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x06030500;
+}
+
+static inline int adreno_is_a660(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 660);
+}
+
+static inline int adreno_is_a680(const struct adreno_gpu *gpu)
+{
+	return adreno_is_revn(gpu, 680);
+}
+
+static inline int adreno_is_a663(const struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x06060300;
+}
+
+static inline int adreno_is_a690(const struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x06090000;
+}
+
+static inline int adreno_is_a702(const struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x07000200;
+}
+
+static inline int adreno_is_a610_family(const struct adreno_gpu *gpu)
+{
+	if (WARN_ON_ONCE(!gpu->info))
+		return false;
+
+	/* TODO: A612 */
+	return adreno_is_a610(gpu) || adreno_is_a702(gpu);
+}
+
+/* check for a615, a616, a618, a619 or any a630 derivatives */
+static inline int adreno_is_a630_family(const struct adreno_gpu *gpu)
+{
+	if (WARN_ON_ONCE(!gpu->info))
+		return false;
+	return gpu->info->family == ADRENO_6XX_GEN1;
+}
+
+static inline int adreno_is_a660_family(const struct adreno_gpu *gpu)
+{
+	if (WARN_ON_ONCE(!gpu->info))
+		return false;
+	return gpu->info->family == ADRENO_6XX_GEN4;
+}
+
+/* check for a650, a660, or any derivatives */
+static inline int adreno_is_a650_family(const struct adreno_gpu *gpu)
+{
+	if (WARN_ON_ONCE(!gpu->info))
+		return false;
+	return gpu->info->family == ADRENO_6XX_GEN3 ||
+	       gpu->info->family == ADRENO_6XX_GEN4;
+}
+
+static inline int adreno_is_a640_family(const struct adreno_gpu *gpu)
+{
+	if (WARN_ON_ONCE(!gpu->info))
+		return false;
+	return gpu->info->family == ADRENO_6XX_GEN2;
+}
+
+static inline int adreno_is_a730(struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x07030001;
+}
+
+static inline int adreno_is_a740(struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x43050a01;
+}
+
+static inline int adreno_is_a750(struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x43051401;
+}
+
+static inline int adreno_is_x185(struct adreno_gpu *gpu)
+{
+	return gpu->info->chip_ids[0] == 0x43050c01;
+}
+
+static inline int adreno_is_a740_family(struct adreno_gpu *gpu)
+{
+	if (WARN_ON_ONCE(!gpu->info))
+		return false;
+	return gpu->info->family == ADRENO_7XX_GEN2 ||
+	       gpu->info->family == ADRENO_7XX_GEN3;
+}
+
+static inline int adreno_is_a7xx(struct adreno_gpu *gpu)
+{
+	/* Update with non-fake (i.e. non-A702) Gen 7 GPUs */
+	return gpu->info->family == ADRENO_7XX_GEN1 ||
+	       adreno_is_a740_family(gpu);
+}
+
+u64 adreno_private_address_space_size(struct msm_gpu *gpu);
+int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
+		     uint32_t param, uint64_t *value, uint32_t *len);
+int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx,
+		     uint32_t param, uint64_t value, uint32_t len);
+const struct firmware *adreno_request_fw(struct adreno_gpu *adreno_gpu,
+		const char *fwname);
+struct drm_gem_object *adreno_fw_create_bo(struct msm_gpu *gpu,
+		const struct firmware *fw, u64 *iova);
+int adreno_hw_init(struct msm_gpu *gpu);
+void adreno_recover(struct msm_gpu *gpu);
+void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring, u32 reg);
+bool adreno_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
+void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
+		struct drm_printer *p);
+#endif
+void adreno_dump_info(struct msm_gpu *gpu);
+void adreno_dump(struct msm_gpu *gpu);
+void adreno_wait_ring(struct msm_ringbuffer *ring, uint32_t ndwords);
+struct msm_ringbuffer *adreno_active_ring(struct msm_gpu *gpu);
+
+int adreno_gpu_ocmem_init(struct device *dev, struct adreno_gpu *adreno_gpu,
+			  struct adreno_ocmem *ocmem);
+void adreno_gpu_ocmem_cleanup(struct adreno_ocmem *ocmem);
+
+int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
+		struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs,
+		int nr_rings);
+void adreno_gpu_cleanup(struct adreno_gpu *gpu);
+int adreno_load_fw(struct adreno_gpu *adreno_gpu);
+
+void adreno_gpu_state_destroy(struct msm_gpu_state *state);
+
+int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state);
+int adreno_gpu_state_put(struct msm_gpu_state *state);
+void adreno_show_object(struct drm_printer *p, void **ptr, int len,
+		bool *encoded);
+
+/*
+ * Common helper function to initialize the default address space for arm-smmu
+ * attached targets
+ */
+struct msm_gem_address_space *
+adreno_create_address_space(struct msm_gpu *gpu,
+			    struct platform_device *pdev);
+
+struct msm_gem_address_space *
+adreno_iommu_create_address_space(struct msm_gpu *gpu,
+				  struct platform_device *pdev,
+				  unsigned long quirks);
+
+int adreno_fault_handler(struct msm_gpu *gpu, unsigned long iova, int flags,
+			 struct adreno_smmu_fault_info *info, const char *block,
+			 u32 scratch[4]);
+
+int adreno_read_speedbin(struct device *dev, u32 *speedbin);
+
+/*
+ * For a5xx and a6xx targets load the zap shader that is used to pull the GPU
+ * out of secure mode
+ */
+int adreno_zap_shader_load(struct msm_gpu *gpu, u32 pasid);
+
+/* ringbuffer helpers (the parts that are adreno specific) */
+
+static inline void
+OUT_PKT0(struct msm_ringbuffer *ring, uint16_t regindx, uint16_t cnt)
+{
+	adreno_wait_ring(ring, cnt+1);
+	OUT_RING(ring, CP_TYPE0_PKT | ((cnt-1) << 16) | (regindx & 0x7FFF));
+}
+
+/* no-op packet: */
+static inline void
+OUT_PKT2(struct msm_ringbuffer *ring)
+{
+	adreno_wait_ring(ring, 1);
+	OUT_RING(ring, CP_TYPE2_PKT);
+}
+
+static inline void
+OUT_PKT3(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt)
+{
+	adreno_wait_ring(ring, cnt+1);
+	OUT_RING(ring, CP_TYPE3_PKT | ((cnt-1) << 16) | ((opcode & 0xFF) << 8));
+}
+
+static inline u32 PM4_PARITY(u32 val)
+{
+	return (0x9669 >> (0xF & (val ^
+		(val >> 4) ^ (val >> 8) ^ (val >> 12) ^
+		(val >> 16) ^ ((val) >> 20) ^ (val >> 24) ^
+		(val >> 28)))) & 1;
+}
+
+/* Maximum number of values that can be executed for one opcode */
+#define TYPE4_MAX_PAYLOAD 127
+
+#define PKT4(_reg, _cnt) \
+	(CP_TYPE4_PKT | ((_cnt) << 0) | (PM4_PARITY((_cnt)) << 7) | \
+	 (((_reg) & 0x3FFFF) << 8) | (PM4_PARITY((_reg)) << 27))
+
+static inline void
+OUT_PKT4(struct msm_ringbuffer *ring, uint16_t regindx, uint16_t cnt)
+{
+	adreno_wait_ring(ring, cnt + 1);
+	OUT_RING(ring, PKT4(regindx, cnt));
+}
+
+static inline void
+OUT_PKT7(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt)
+{
+	adreno_wait_ring(ring, cnt + 1);
+	OUT_RING(ring, CP_TYPE7_PKT | (cnt << 0) | (PM4_PARITY(cnt) << 15) |
+		((opcode & 0x7F) << 16) | (PM4_PARITY(opcode) << 23));
+}
+
+struct msm_gpu *a2xx_gpu_init(struct drm_device *dev);
+struct msm_gpu *a3xx_gpu_init(struct drm_device *dev);
+struct msm_gpu *a4xx_gpu_init(struct drm_device *dev);
+struct msm_gpu *a5xx_gpu_init(struct drm_device *dev);
+struct msm_gpu *a6xx_gpu_init(struct drm_device *dev);
+
+static inline uint32_t get_wptr(struct msm_ringbuffer *ring)
+{
+	return (ring->cur - ring->start) % (MSM_GPU_RINGBUFFER_SZ >> 2);
+}
+
+/*
+ * Given a register and a count, return a value to program into
+ * REG_CP_PROTECT_REG(n) - this will block both reads and writes for _len
+ * registers starting at _reg.
+ *
+ * The register base needs to be a multiple of the length. If it is not, the
+ * hardware will quietly mask off the bits for you and shift the size. For
+ * example, if you intend the protection to start at 0x07 for a length of 4
+ * (0x07-0x0A) the hardware will actually protect (0x04-0x07) which might
+ * expose registers you intended to protect!
+ */
+#define ADRENO_PROTECT_RW(_reg, _len) \
+	((1 << 30) | (1 << 29) | \
+	((ilog2((_len)) & 0x1F) << 24) | (((_reg) << 2) & 0xFFFFF))
+
+/*
+ * Same as above, but allow reads over the range. For areas of mixed use (such
+ * as performance counters) this allows us to protect a much larger range with a
+ * single register
+ */
+#define ADRENO_PROTECT_RDONLY(_reg, _len) \
+	((1 << 29) \
+	((ilog2((_len)) & 0x1F) << 24) | (((_reg) << 2) & 0xFFFFF))
+
+
+#define gpu_poll_timeout(gpu, addr, val, cond, interval, timeout) \
+	readl_poll_timeout((gpu)->mmio + ((addr) << 2), val, cond, \
+		interval, timeout)
+
+#endif /* __ADRENO_GPU_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_10_0_sm8650.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_10_0_sm8650.h
@@ -0,0 +1,457 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_10_0_SM8650_H
+#define _DPU_10_0_SM8650_H
+
+static const struct dpu_caps sm8650_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0xb,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.has_3d_merge = true,
+	.max_linewidth = 8192,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg sm8650_mdp = {
+	.name = "top_0",
+	.base = 0, .len = 0x494,
+	.features = BIT(DPU_MDP_PERIPH_0_REMOVED),
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
+	},
+};
+
+/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
+static const struct dpu_ctl_cfg sm8650_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x15000, .len = 0x1000,
+		.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x16000, .len = 0x1000,
+		.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x17000, .len = 0x1000,
+		.features = CTL_SM8550_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x18000, .len = 0x1000,
+		.features = CTL_SM8550_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x19000, .len = 0x1000,
+		.features = CTL_SM8550_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	}, {
+		.name = "ctl_5", .id = CTL_5,
+		.base = 0x1a000, .len = 0x1000,
+		.features = CTL_SM8550_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+	},
+};
+
+static const struct dpu_sspp_cfg sm8650_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x344,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_3,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x344,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_3,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+	}, {
+		.name = "sspp_2", .id = SSPP_VIG2,
+		.base = 0x8000, .len = 0x344,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_3,
+		.xin_id = 8,
+		.type = SSPP_TYPE_VIG,
+	}, {
+		.name = "sspp_3", .id = SSPP_VIG3,
+		.base = 0xa000, .len = 0x344,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_3,
+		.xin_id = 12,
+		.type = SSPP_TYPE_VIG,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x344,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x344,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x344,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+	}, {
+		.name = "sspp_11", .id = SSPP_DMA3,
+		.base = 0x2a000, .len = 0x344,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 13,
+		.type = SSPP_TYPE_DMA,
+	}, {
+		.name = "sspp_12", .id = SSPP_DMA4,
+		.base = 0x2c000, .len = 0x344,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 14,
+		.type = SSPP_TYPE_DMA,
+	}, {
+		.name = "sspp_13", .id = SSPP_DMA5,
+		.base = 0x2e000, .len = 0x344,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 15,
+		.type = SSPP_TYPE_DMA,
+	},
+};
+
+static const struct dpu_lm_cfg sm8650_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_3,
+		.pingpong = PINGPONG_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x47000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+	}, {
+		.name = "lm_4", .id = LM_4,
+		.base = 0x48000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_4,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_4,
+		.pingpong = PINGPONG_5,
+	},
+};
+
+static const struct dpu_dspp_cfg sm8650_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_2", .id = DSPP_2,
+		.base = 0x58000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_3", .id = DSPP_3,
+		.base = 0x5a000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sm8650_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x69000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x6a000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x6b000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x6c000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+	}, {
+		.name = "pingpong_4", .id = PINGPONG_4,
+		.base = 0x6d000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+	}, {
+		.name = "pingpong_5", .id = PINGPONG_5,
+		.base = 0x6e000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+	}, {
+		.name = "pingpong_6", .id = PINGPONG_6,
+		.base = 0x66000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_3,
+	}, {
+		.name = "pingpong_7", .id = PINGPONG_7,
+		.base = 0x66400, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_3,
+	}, {
+		.name = "pingpong_8", .id = PINGPONG_8,
+		.base = 0x7e000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_4,
+	}, {
+		.name = "pingpong_9", .id = PINGPONG_9,
+		.base = 0x7e400, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_4,
+	},
+};
+
+static const struct dpu_merge_3d_cfg sm8650_merge_3d[] = {
+	{
+		.name = "merge_3d_0", .id = MERGE_3D_0,
+		.base = 0x4e000, .len = 0x8,
+	}, {
+		.name = "merge_3d_1", .id = MERGE_3D_1,
+		.base = 0x4f000, .len = 0x8,
+	}, {
+		.name = "merge_3d_2", .id = MERGE_3D_2,
+		.base = 0x50000, .len = 0x8,
+	}, {
+		.name = "merge_3d_3", .id = MERGE_3D_3,
+		.base = 0x66700, .len = 0x8,
+	}, {
+		.name = "merge_3d_4", .id = MERGE_3D_4,
+		.base = 0x7e700, .len = 0x8,
+	},
+};
+
+/*
+ * NOTE: Each display compression engine (DCE) contains dual hard
+ * slice DSC encoders so both share same base address but with
+ * its own different sub block address.
+ */
+static const struct dpu_dsc_cfg sm8650_dsc[] = {
+	{
+		.name = "dce_0_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x6,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_0_1", .id = DSC_1,
+		.base = 0x80000, .len = 0x6,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_1_0", .id = DSC_2,
+		.base = 0x81000, .len = 0x6,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_1_1", .id = DSC_3,
+		.base = 0x81000, .len = 0x6,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_2_0", .id = DSC_4,
+		.base = 0x82000, .len = 0x6,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_2_1", .id = DSC_5,
+		.base = 0x82000, .len = 0x6,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_1,
+	},
+};
+
+static const struct dpu_wb_cfg sm8650_wb[] = {
+	{
+		.name = "wb_2", .id = WB_2,
+		.base = 0x65000, .len = 0x2c8,
+		.features = WB_SM8250_MASK,
+		.format_list = wb2_formats_rgb,
+		.num_formats = ARRAY_SIZE(wb2_formats_rgb),
+		.xin_id = 6,
+		.vbif_idx = VBIF_RT,
+		.maxlinewidth = 4096,
+		.intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4),
+	},
+};
+
+static const struct dpu_intf_cfg sm8650_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x34000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x35000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	}, {
+		.name = "intf_2", .id = INTF_2,
+		.base = 0x36000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2),
+	}, {
+		.name = "intf_3", .id = INTF_3,
+		.base = 0x37000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
+	},
+};
+
+static const struct dpu_perf_cfg sm8650_perf_data = {
+	.max_bw_low = 17000000,
+	.max_bw_high = 27000000,
+	.min_core_ib = 2500000,
+	.min_llcc_ib = 0,
+	.min_dram_ib = 800000,
+	.min_prefill_lines = 35,
+	/* FIXME: lut tables */
+	.danger_lut_tbl = {0x3ffff, 0x3ffff, 0x0},
+	.safe_lut_tbl = {0xfe00, 0xfe00, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sc7180_qos_linear),
+		.entries = sc7180_qos_linear
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+		.entries = sc7180_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+		/* TODO: macrotile-qseed is different from macrotile */
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sm8650_mdss_ver = {
+	.core_major_ver = 10,
+	.core_minor_ver = 0,
+};
+
+const struct dpu_mdss_cfg dpu_sm8650_cfg = {
+	.mdss_ver = &sm8650_mdss_ver,
+	.caps = &sm8650_dpu_caps,
+	.mdp = &sm8650_mdp,
+	.ctl_count = ARRAY_SIZE(sm8650_ctl),
+	.ctl = sm8650_ctl,
+	.sspp_count = ARRAY_SIZE(sm8650_sspp),
+	.sspp = sm8650_sspp,
+	.mixer_count = ARRAY_SIZE(sm8650_lm),
+	.mixer = sm8650_lm,
+	.dspp_count = ARRAY_SIZE(sm8650_dspp),
+	.dspp = sm8650_dspp,
+	.pingpong_count = ARRAY_SIZE(sm8650_pp),
+	.pingpong = sm8650_pp,
+	.dsc_count = ARRAY_SIZE(sm8650_dsc),
+	.dsc = sm8650_dsc,
+	.merge_3d_count = ARRAY_SIZE(sm8650_merge_3d),
+	.merge_3d = sm8650_merge_3d,
+	.wb_count = ARRAY_SIZE(sm8650_wb),
+	.wb = sm8650_wb,
+	.intf_count = ARRAY_SIZE(sm8650_intf),
+	.intf = sm8650_intf,
+	.vbif_count = ARRAY_SIZE(sm8650_vbif),
+	.vbif = sm8650_vbif,
+	.perf = &sm8650_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_3_0_msm8998.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_3_0_msm8998.h
@@ -0,0 +1,336 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_3_0_MSM8998_H
+#define _DPU_3_0_MSM8998_H
+
+static const struct dpu_caps msm8998_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0x7,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.has_3d_merge = true,
+	.max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+	.max_hdeci_exp = MAX_HORZ_DECIMATION,
+	.max_vdeci_exp = MAX_VERT_DECIMATION,
+};
+
+static const struct dpu_mdp_cfg msm8998_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x458,
+	.features = BIT(DPU_MDP_VSYNC_SEL),
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 12 },
+		[DPU_CLK_CTRL_CURSOR0] = { .reg_off = 0x3a8, .bit_off = 16 },
+		[DPU_CLK_CTRL_CURSOR1] = { .reg_off = 0x3b0, .bit_off = 16 },
+	},
+};
+
+static const struct dpu_ctl_cfg msm8998_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x1000, .len = 0x94,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x1200, .len = 0x94,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x1400, .len = 0x94,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x1600, .len = 0x94,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x1800, .len = 0x94,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	},
+};
+
+static const struct dpu_sspp_cfg msm8998_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x1ac,
+		.features = VIG_MSM8998_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_1_2,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x1ac,
+		.features = VIG_MSM8998_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_1_2,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG1,
+	}, {
+		.name = "sspp_2", .id = SSPP_VIG2,
+		.base = 0x8000, .len = 0x1ac,
+		.features = VIG_MSM8998_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_1_2,
+		.xin_id = 8,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG2,
+	}, {
+		.name = "sspp_3", .id = SSPP_VIG3,
+		.base = 0xa000, .len = 0x1ac,
+		.features = VIG_MSM8998_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_1_2,
+		.xin_id = 12,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG3,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x1ac,
+		.features = DMA_MSM8998_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x1ac,
+		.features = DMA_MSM8998_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x1ac,
+		.features = DMA_CURSOR_MSM8998_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	}, {
+		.name = "sspp_11", .id = SSPP_DMA3,
+		.base = 0x2a000, .len = 0x1ac,
+		.features = DMA_CURSOR_MSM8998_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 13,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA3,
+	},
+};
+
+static const struct dpu_lm_cfg msm8998_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_MSM8998_MASK,
+		.sblk = &msm8998_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x320,
+		.features = MIXER_MSM8998_MASK,
+		.sblk = &msm8998_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x320,
+		.features = MIXER_MSM8998_MASK,
+		.sblk = &msm8998_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x47000, .len = 0x320,
+		.features = MIXER_MSM8998_MASK,
+		.sblk = &msm8998_lm_sblk,
+		.pingpong = PINGPONG_NONE,
+	}, {
+		.name = "lm_4", .id = LM_4,
+		.base = 0x48000, .len = 0x320,
+		.features = MIXER_MSM8998_MASK,
+		.sblk = &msm8998_lm_sblk,
+		.pingpong = PINGPONG_NONE,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x320,
+		.features = MIXER_MSM8998_MASK,
+		.sblk = &msm8998_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+	},
+};
+
+static const struct dpu_pingpong_cfg msm8998_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x70000, .len = 0xd4,
+		.features = PINGPONG_SDM845_TE2_MASK,
+		.sblk = &sdm845_pp_sblk_te,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x70800, .len = 0xd4,
+		.features = PINGPONG_SDM845_TE2_MASK,
+		.sblk = &sdm845_pp_sblk_te,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x71000, .len = 0xd4,
+		.features = PINGPONG_SDM845_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x71800, .len = 0xd4,
+		.features = PINGPONG_SDM845_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15),
+	},
+};
+
+static const struct dpu_dsc_cfg msm8998_dsc[] = {
+	{
+		.name = "dsc_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x140,
+	}, {
+		.name = "dsc_1", .id = DSC_1,
+		.base = 0x80400, .len = 0x140,
+	},
+};
+
+static const struct dpu_dspp_cfg msm8998_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &msm8998_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &msm8998_dspp_sblk,
+	},
+};
+
+static const struct dpu_intf_cfg msm8998_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x6a000, .len = 0x280,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 21,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x6a800, .len = 0x280,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 21,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+	}, {
+		.name = "intf_2", .id = INTF_2,
+		.base = 0x6b000, .len = 0x280,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 21,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
+	}, {
+		.name = "intf_3", .id = INTF_3,
+		.base = 0x6b800, .len = 0x280,
+		.type = INTF_HDMI,
+		.prog_fetch_lines_worst_case = 21,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
+	},
+};
+
+static const struct dpu_perf_cfg msm8998_perf_data = {
+	.max_bw_low = 6700000,
+	.max_bw_high = 6700000,
+	.min_core_ib = 2400000,
+	.min_llcc_ib = 800000,
+	.min_dram_ib = 800000,
+	.undersized_prefill_lines = 2,
+	.xtra_prefill_lines = 2,
+	.dest_scale_prefill_lines = 3,
+	.macrotile_prefill_lines = 4,
+	.yuv_nv12_prefill_lines = 8,
+	.linear_prefill_lines = 1,
+	.downscaling_prefill_lines = 1,
+	.amortizable_threshold = 25,
+	.min_prefill_lines = 25,
+	.danger_lut_tbl = {0xf, 0xffff, 0x0},
+	.safe_lut_tbl = {0xfffc, 0xff00, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(msm8998_qos_linear),
+		.entries = msm8998_qos_linear
+		},
+		{.nentry = ARRAY_SIZE(msm8998_qos_macrotile),
+		.entries = msm8998_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(msm8998_qos_nrt),
+		.entries = msm8998_qos_nrt
+		},
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 200,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version msm8998_mdss_ver = {
+	.core_major_ver = 3,
+	.core_minor_ver = 0,
+};
+
+const struct dpu_mdss_cfg dpu_msm8998_cfg = {
+	.mdss_ver = &msm8998_mdss_ver,
+	.caps = &msm8998_dpu_caps,
+	.mdp = &msm8998_mdp,
+	.ctl_count = ARRAY_SIZE(msm8998_ctl),
+	.ctl = msm8998_ctl,
+	.sspp_count = ARRAY_SIZE(msm8998_sspp),
+	.sspp = msm8998_sspp,
+	.mixer_count = ARRAY_SIZE(msm8998_lm),
+	.mixer = msm8998_lm,
+	.dspp_count = ARRAY_SIZE(msm8998_dspp),
+	.dspp = msm8998_dspp,
+	.pingpong_count = ARRAY_SIZE(msm8998_pp),
+	.pingpong = msm8998_pp,
+	.dsc_count = ARRAY_SIZE(msm8998_dsc),
+	.dsc = msm8998_dsc,
+	.intf_count = ARRAY_SIZE(msm8998_intf),
+	.intf = msm8998_intf,
+	.vbif_count = ARRAY_SIZE(msm8998_vbif),
+	.vbif = msm8998_vbif,
+	.perf = &msm8998_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_4_0_sdm845.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_4_0_sdm845.h
@@ -0,0 +1,353 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_4_0_SDM845_H
+#define _DPU_4_0_SDM845_H
+
+static const struct dpu_caps sdm845_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0xb,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.has_3d_merge = true,
+	.max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+	.max_hdeci_exp = MAX_HORZ_DECIMATION,
+	.max_vdeci_exp = MAX_VERT_DECIMATION,
+};
+
+static const struct dpu_mdp_cfg sdm845_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x45c,
+	.features = BIT(DPU_MDP_AUDIO_SELECT) | BIT(DPU_MDP_VSYNC_SEL),
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
+	},
+};
+
+static const struct dpu_ctl_cfg sdm845_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x1000, .len = 0xe4,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x1200, .len = 0xe4,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x1400, .len = 0xe4,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x1600, .len = 0xe4,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x1800, .len = 0xe4,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	},
+};
+
+static const struct dpu_sspp_cfg sdm845_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x1c8,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_1_3,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x1c8,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_1_3,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG1,
+	}, {
+		.name = "sspp_2", .id = SSPP_VIG2,
+		.base = 0x8000, .len = 0x1c8,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_1_3,
+		.xin_id = 8,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG2,
+	}, {
+		.name = "sspp_3", .id = SSPP_VIG3,
+		.base = 0xa000, .len = 0x1c8,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_1_3,
+		.xin_id = 12,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG3,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x1c8,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x1c8,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x1c8,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	}, {
+		.name = "sspp_11", .id = SSPP_DMA3,
+		.base = 0x2a000, .len = 0x1c8,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 13,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA3,
+	},
+};
+
+static const struct dpu_lm_cfg sdm845_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_2,
+		.dspp = DSPP_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x0, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.pingpong = PINGPONG_NONE,
+		.dspp = DSPP_3,
+	}, {
+		.name = "lm_4", .id = LM_4,
+		.base = 0x0, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.pingpong = PINGPONG_NONE,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+	},
+};
+
+static const struct dpu_dspp_cfg sdm845_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_2", .id = DSPP_2,
+		.base = 0x58000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_3", .id = DSPP_3,
+		.base = 0x5a000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sdm845_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x70000, .len = 0xd4,
+		.features = PINGPONG_SDM845_TE2_MASK,
+		.sblk = &sdm845_pp_sblk_te,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x70800, .len = 0xd4,
+		.features = PINGPONG_SDM845_TE2_MASK,
+		.sblk = &sdm845_pp_sblk_te,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x71000, .len = 0xd4,
+		.features = PINGPONG_SDM845_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x71800, .len = 0xd4,
+		.features = PINGPONG_SDM845_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+		.intr_rdptr = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15),
+	},
+};
+
+static const struct dpu_dsc_cfg sdm845_dsc[] = {
+	{
+		.name = "dsc_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x140,
+	}, {
+		.name = "dsc_1", .id = DSC_1,
+		.base = 0x80400, .len = 0x140,
+	}, {
+		.name = "dsc_2", .id = DSC_2,
+		.base = 0x80800, .len = 0x140,
+	}, {
+		.name = "dsc_3", .id = DSC_3,
+		.base = 0x80c00, .len = 0x140,
+	},
+};
+
+static const struct dpu_intf_cfg sdm845_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x6a000, .len = 0x280,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x6a800, .len = 0x280,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+	}, {
+		.name = "intf_2", .id = INTF_2,
+		.base = 0x6b000, .len = 0x280,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
+	}, {
+		.name = "intf_3", .id = INTF_3,
+		.base = 0x6b800, .len = 0x280,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
+	},
+};
+
+static const struct dpu_perf_cfg sdm845_perf_data = {
+	.max_bw_low = 6800000,
+	.max_bw_high = 6800000,
+	.min_core_ib = 2400000,
+	.min_llcc_ib = 800000,
+	.min_dram_ib = 800000,
+	.undersized_prefill_lines = 2,
+	.xtra_prefill_lines = 2,
+	.dest_scale_prefill_lines = 3,
+	.macrotile_prefill_lines = 4,
+	.yuv_nv12_prefill_lines = 8,
+	.linear_prefill_lines = 1,
+	.downscaling_prefill_lines = 1,
+	.amortizable_threshold = 25,
+	.min_prefill_lines = 24,
+	.danger_lut_tbl = {0xf, 0xffff, 0x0},
+	.safe_lut_tbl = {0xfff0, 0xf000, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sdm845_qos_linear),
+		.entries = sdm845_qos_linear
+		},
+		{.nentry = ARRAY_SIZE(sdm845_qos_macrotile),
+		.entries = sdm845_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sdm845_qos_nrt),
+		.entries = sdm845_qos_nrt
+		},
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sdm845_mdss_ver = {
+	.core_major_ver = 4,
+	.core_minor_ver = 0,
+};
+
+const struct dpu_mdss_cfg dpu_sdm845_cfg = {
+	.mdss_ver = &sdm845_mdss_ver,
+	.caps = &sdm845_dpu_caps,
+	.mdp = &sdm845_mdp,
+	.ctl_count = ARRAY_SIZE(sdm845_ctl),
+	.ctl = sdm845_ctl,
+	.sspp_count = ARRAY_SIZE(sdm845_sspp),
+	.sspp = sdm845_sspp,
+	.mixer_count = ARRAY_SIZE(sdm845_lm),
+	.mixer = sdm845_lm,
+	.dspp_count = ARRAY_SIZE(sdm845_dspp),
+	.dspp = sdm845_dspp,
+	.pingpong_count = ARRAY_SIZE(sdm845_pp),
+	.pingpong = sdm845_pp,
+	.dsc_count = ARRAY_SIZE(sdm845_dsc),
+	.dsc = sdm845_dsc,
+	.intf_count = ARRAY_SIZE(sdm845_intf),
+	.intf = sdm845_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sdm845_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_4_1_sdm670.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_4_1_sdm670.h
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023, Richard Acayan. All rights reserved.
+ */
+
+#ifndef _DPU_4_1_SDM670_H
+#define _DPU_4_1_SDM670_H
+
+static const struct dpu_mdp_cfg sdm670_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x45c,
+	.features = BIT(DPU_MDP_AUDIO_SELECT),
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
+	},
+};
+
+static const struct dpu_sspp_cfg sdm670_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x1c8,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_1_3,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x1c8,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_1_3,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x1c8,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x1c8,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x1c8,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	},
+};
+
+static const struct dpu_dsc_cfg sdm670_dsc[] = {
+	{
+		.name = "dsc_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x140,
+	}, {
+		.name = "dsc_1", .id = DSC_1,
+		.base = 0x80400, .len = 0x140,
+	},
+};
+
+static const struct dpu_mdss_version sdm670_mdss_ver = {
+	.core_major_ver = 4,
+	.core_minor_ver = 1,
+};
+
+const struct dpu_mdss_cfg dpu_sdm670_cfg = {
+	.mdss_ver = &sdm670_mdss_ver,
+	.caps = &sdm845_dpu_caps,
+	.mdp = &sdm670_mdp,
+	.ctl_count = ARRAY_SIZE(sdm845_ctl),
+	.ctl = sdm845_ctl,
+	.sspp_count = ARRAY_SIZE(sdm670_sspp),
+	.sspp = sdm670_sspp,
+	.mixer_count = ARRAY_SIZE(sdm845_lm),
+	.mixer = sdm845_lm,
+	.pingpong_count = ARRAY_SIZE(sdm845_pp),
+	.pingpong = sdm845_pp,
+	.dsc_count = ARRAY_SIZE(sdm670_dsc),
+	.dsc = sdm670_dsc,
+	.intf_count = ARRAY_SIZE(sdm845_intf),
+	.intf = sdm845_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sdm845_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_5_0_sm8150.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_5_0_sm8150.h
@@ -0,0 +1,394 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_5_0_SM8150_H
+#define _DPU_5_0_SM8150_H
+
+static const struct dpu_caps sm8150_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0xb,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.has_3d_merge = true,
+	.max_linewidth = 4096,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+	.max_hdeci_exp = MAX_HORZ_DECIMATION,
+	.max_vdeci_exp = MAX_VERT_DECIMATION,
+};
+
+static const struct dpu_mdp_cfg sm8150_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x45c,
+	.features = BIT(DPU_MDP_AUDIO_SELECT),
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
+	},
+};
+
+/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
+static const struct dpu_ctl_cfg sm8150_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x1000, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x1200, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x1400, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x1600, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x1800, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	}, {
+		.name = "ctl_5", .id = CTL_5,
+		.base = 0x1a00, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+	},
+};
+
+static const struct dpu_sspp_cfg sm8150_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x1f0,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_1_4,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x1f0,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_1_4,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG1,
+	}, {
+		.name = "sspp_2", .id = SSPP_VIG2,
+		.base = 0x8000, .len = 0x1f0,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_1_4,
+		.xin_id = 8,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG2,
+	}, {
+		.name = "sspp_3", .id = SSPP_VIG3,
+		.base = 0xa000, .len = 0x1f0,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_1_4,
+		.xin_id = 12,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG3,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x1f0,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x1f0,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x1f0,
+		.features = DMA_CURSOR_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	}, {
+		.name = "sspp_11", .id = SSPP_DMA3,
+		.base = 0x2a000, .len = 0x1f0,
+		.features = DMA_CURSOR_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 13,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA3,
+	},
+};
+
+static const struct dpu_lm_cfg sm8150_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_3,
+		.pingpong = PINGPONG_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x47000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+	}, {
+		.name = "lm_4", .id = LM_4,
+		.base = 0x48000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_4,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_4,
+		.pingpong = PINGPONG_5,
+	},
+};
+
+static const struct dpu_dspp_cfg sm8150_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_2", .id = DSPP_2,
+		.base = 0x58000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_3", .id = DSPP_3,
+		.base = 0x5a000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sm8150_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x70000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x70800, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x71000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x71800, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+	}, {
+		.name = "pingpong_4", .id = PINGPONG_4,
+		.base = 0x72000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+	}, {
+		.name = "pingpong_5", .id = PINGPONG_5,
+		.base = 0x72800, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+	},
+};
+
+static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
+	{
+		.name = "merge_3d_0", .id = MERGE_3D_0,
+		.base = 0x83000, .len = 0x8,
+	}, {
+		.name = "merge_3d_1", .id = MERGE_3D_1,
+		.base = 0x83100, .len = 0x8,
+	}, {
+		.name = "merge_3d_2", .id = MERGE_3D_2,
+		.base = 0x83200, .len = 0x8,
+	},
+};
+
+static const struct dpu_dsc_cfg sm8150_dsc[] = {
+	{
+		.name = "dsc_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	}, {
+		.name = "dsc_1", .id = DSC_1,
+		.base = 0x80400, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	}, {
+		.name = "dsc_2", .id = DSC_2,
+		.base = 0x80800, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	}, {
+		.name = "dsc_3", .id = DSC_3,
+		.base = 0x80c00, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	},
+};
+
+static const struct dpu_intf_cfg sm8150_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x6a000, .len = 0x280,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x6a800, .len = 0x2bc,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	}, {
+		.name = "intf_2", .id = INTF_2,
+		.base = 0x6b000, .len = 0x2bc,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2),
+	}, {
+		.name = "intf_3", .id = INTF_3,
+		.base = 0x6b800, .len = 0x280,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
+	},
+};
+
+static const struct dpu_perf_cfg sm8150_perf_data = {
+	.max_bw_low = 12800000,
+	.max_bw_high = 12800000,
+	.min_core_ib = 2400000,
+	.min_llcc_ib = 800000,
+	.min_dram_ib = 800000,
+	.min_prefill_lines = 24,
+	.danger_lut_tbl = {0xf, 0xffff, 0x0},
+	.safe_lut_tbl = {0xfff8, 0xf000, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sm8150_qos_linear),
+		.entries = sm8150_qos_linear
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+		.entries = sc7180_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+		/* TODO: macrotile-qseed is different from macrotile */
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sm8150_mdss_ver = {
+	.core_major_ver = 5,
+	.core_minor_ver = 0,
+};
+
+const struct dpu_mdss_cfg dpu_sm8150_cfg = {
+	.mdss_ver = &sm8150_mdss_ver,
+	.caps = &sm8150_dpu_caps,
+	.mdp = &sm8150_mdp,
+	.ctl_count = ARRAY_SIZE(sm8150_ctl),
+	.ctl = sm8150_ctl,
+	.sspp_count = ARRAY_SIZE(sm8150_sspp),
+	.sspp = sm8150_sspp,
+	.mixer_count = ARRAY_SIZE(sm8150_lm),
+	.mixer = sm8150_lm,
+	.dspp_count = ARRAY_SIZE(sm8150_dspp),
+	.dspp = sm8150_dspp,
+	.dsc_count = ARRAY_SIZE(sm8150_dsc),
+	.dsc = sm8150_dsc,
+	.pingpong_count = ARRAY_SIZE(sm8150_pp),
+	.pingpong = sm8150_pp,
+	.merge_3d_count = ARRAY_SIZE(sm8150_merge_3d),
+	.merge_3d = sm8150_merge_3d,
+	.intf_count = ARRAY_SIZE(sm8150_intf),
+	.intf = sm8150_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sm8150_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_5_1_sc8180x.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_5_1_sc8180x.h
@@ -0,0 +1,420 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_5_1_SC8180X_H
+#define _DPU_5_1_SC8180X_H
+
+static const struct dpu_caps sc8180x_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0xb,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.has_3d_merge = true,
+	.max_linewidth = 4096,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+	.max_hdeci_exp = MAX_HORZ_DECIMATION,
+	.max_vdeci_exp = MAX_VERT_DECIMATION,
+};
+
+static const struct dpu_mdp_cfg sc8180x_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x45c,
+	.features = BIT(DPU_MDP_AUDIO_SELECT),
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
+	},
+};
+
+static const struct dpu_ctl_cfg sc8180x_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x1000, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x1200, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x1400, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x1600, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x1800, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	}, {
+		.name = "ctl_5", .id = CTL_5,
+		.base = 0x1a00, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+	},
+};
+
+static const struct dpu_sspp_cfg sc8180x_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x1f0,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_1_4,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x1f0,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_1_4,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG1,
+	}, {
+		.name = "sspp_2", .id = SSPP_VIG2,
+		.base = 0x8000, .len = 0x1f0,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_1_4,
+		.xin_id = 8,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG2,
+	}, {
+		.name = "sspp_3", .id = SSPP_VIG3,
+		.base = 0xa000, .len = 0x1f0,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_1_4,
+		.xin_id = 12,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG3,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x1f0,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x1f0,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x1f0,
+		.features = DMA_CURSOR_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	}, {
+		.name = "sspp_11", .id = SSPP_DMA3,
+		.base = 0x2a000, .len = 0x1f0,
+		.features = DMA_CURSOR_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 13,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA3,
+	},
+};
+
+static const struct dpu_lm_cfg sc8180x_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_3,
+		.pingpong = PINGPONG_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x47000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+	}, {
+		.name = "lm_4", .id = LM_4,
+		.base = 0x48000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_4,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_4,
+		.pingpong = PINGPONG_5,
+	},
+};
+
+static const struct dpu_dspp_cfg sc8180x_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_2", .id = DSPP_2,
+		.base = 0x58000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_3", .id = DSPP_3,
+		.base = 0x5a000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sc8180x_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x70000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x70800, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x71000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x71800, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+	}, {
+		.name = "pingpong_4", .id = PINGPONG_4,
+		.base = 0x72000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+	}, {
+		.name = "pingpong_5", .id = PINGPONG_5,
+		.base = 0x72800, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+	},
+};
+
+static const struct dpu_merge_3d_cfg sc8180x_merge_3d[] = {
+	{
+		.name = "merge_3d_0", .id = MERGE_3D_0,
+		.base = 0x83000, .len = 0x8,
+	}, {
+		.name = "merge_3d_1", .id = MERGE_3D_1,
+		.base = 0x83100, .len = 0x8,
+	}, {
+		.name = "merge_3d_2", .id = MERGE_3D_2,
+		.base = 0x83200, .len = 0x8,
+	},
+};
+
+static const struct dpu_dsc_cfg sc8180x_dsc[] = {
+	{
+		.name = "dsc_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	}, {
+		.name = "dsc_1", .id = DSC_1,
+		.base = 0x80400, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	}, {
+		.name = "dsc_2", .id = DSC_2,
+		.base = 0x80800, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	}, {
+		.name = "dsc_3", .id = DSC_3,
+		.base = 0x80c00, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	}, {
+		.name = "dsc_4", .id = DSC_4,
+		.base = 0x81000, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	}, {
+		.name = "dsc_5", .id = DSC_5,
+		.base = 0x81400, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	},
+};
+
+static const struct dpu_intf_cfg sc8180x_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x6a000, .len = 0x280,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x6a800, .len = 0x2bc,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	}, {
+		.name = "intf_2", .id = INTF_2,
+		.base = 0x6b000, .len = 0x2bc,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2),
+	},
+	/* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until this is supported */
+	{
+		.name = "intf_3", .id = INTF_3,
+		.base = 0x6b800, .len = 0x280,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DP,
+		.controller_id = 999,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
+	}, {
+		.name = "intf_4", .id = INTF_4,
+		.base = 0x6c000, .len = 0x280,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 20),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 21),
+	}, {
+		.name = "intf_5", .id = INTF_5,
+		.base = 0x6c800, .len = 0x280,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_2,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 22),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 23),
+	},
+};
+
+static const struct dpu_perf_cfg sc8180x_perf_data = {
+	.max_bw_low = 9600000,
+	.max_bw_high = 9600000,
+	.min_core_ib = 2400000,
+	.min_llcc_ib = 800000,
+	.min_dram_ib = 800000,
+	.danger_lut_tbl = {0xf, 0xffff, 0x0},
+	.safe_lut_tbl = {0xfff0, 0xf000, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sc7180_qos_linear),
+		.entries = sc7180_qos_linear
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+		.entries = sc7180_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+		/* TODO: macrotile-qseed is different from macrotile */
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sc8180x_mdss_ver = {
+	.core_major_ver = 5,
+	.core_minor_ver = 1,
+};
+
+const struct dpu_mdss_cfg dpu_sc8180x_cfg = {
+	.mdss_ver = &sc8180x_mdss_ver,
+	.caps = &sc8180x_dpu_caps,
+	.mdp = &sc8180x_mdp,
+	.ctl_count = ARRAY_SIZE(sc8180x_ctl),
+	.ctl = sc8180x_ctl,
+	.sspp_count = ARRAY_SIZE(sc8180x_sspp),
+	.sspp = sc8180x_sspp,
+	.mixer_count = ARRAY_SIZE(sc8180x_lm),
+	.mixer = sc8180x_lm,
+	.dspp_count = ARRAY_SIZE(sc8180x_dspp),
+	.dspp = sc8180x_dspp,
+	.dsc_count = ARRAY_SIZE(sc8180x_dsc),
+	.dsc = sc8180x_dsc,
+	.pingpong_count = ARRAY_SIZE(sc8180x_pp),
+	.pingpong = sc8180x_pp,
+	.merge_3d_count = ARRAY_SIZE(sc8180x_merge_3d),
+	.merge_3d = sc8180x_merge_3d,
+	.intf_count = ARRAY_SIZE(sc8180x_intf),
+	.intf = sc8180x_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sc8180x_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_5_4_sm6125.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_5_4_sm6125.h
@@ -0,0 +1,220 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023 Marijn Suijten <marijn.suijten@somainline.org>. All rights reserved.
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_5_4_SM6125_H
+#define _DPU_5_4_SM6125_H
+
+static const struct dpu_caps sm6125_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0x6,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.max_linewidth = 2160,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+	.max_hdeci_exp = MAX_HORZ_DECIMATION,
+	.max_vdeci_exp = MAX_VERT_DECIMATION,
+};
+
+static const struct dpu_mdp_cfg sm6125_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x45c,
+	.features = 0,
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+	},
+};
+
+static const struct dpu_ctl_cfg sm6125_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x1000, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x1200, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x1400, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x1600, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x1800, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	}, {
+		.name = "ctl_5", .id = CTL_5,
+		.base = 0x1a00, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+	},
+};
+
+static const struct dpu_sspp_cfg sm6125_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x1f0,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_2_4,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x1f0,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x1f0,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	},
+};
+
+static const struct dpu_lm_cfg sm6125_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_QCM2290_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+		.lm_pair = LM_1,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x320,
+		.features = MIXER_QCM2290_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.pingpong = PINGPONG_1,
+		.dspp = 0,
+		.lm_pair = LM_0,
+	},
+};
+
+static const struct dpu_dspp_cfg sm6125_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sm6125_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x70000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.merge_3d = 0,
+		.sblk = &sdm845_pp_sblk,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x70800, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.merge_3d = 0,
+		.sblk = &sdm845_pp_sblk,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	},
+};
+
+static const struct dpu_intf_cfg sm6125_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x6a000, .len = 0x280,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x6a800, .len = 0x2c0,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DSI,
+		.controller_id = 0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	},
+};
+
+static const struct dpu_perf_cfg sm6125_perf_data = {
+	.max_bw_low = 4100000,
+	.max_bw_high = 4100000,
+	.min_core_ib = 2400000,
+	.min_llcc_ib = 0, /* No LLCC on this SoC */
+	.min_dram_ib = 800000,
+	.min_prefill_lines = 24,
+	.danger_lut_tbl = {0xf, 0xffff, 0x0},
+	.safe_lut_tbl = {0xfff8, 0xf000, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sm8150_qos_linear),
+		.entries = sm8150_qos_linear
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+		.entries = sc7180_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+		/* TODO: macrotile-qseed is different from macrotile */
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sm6125_mdss_ver = {
+	.core_major_ver = 5,
+	.core_minor_ver = 4,
+};
+
+const struct dpu_mdss_cfg dpu_sm6125_cfg = {
+	.mdss_ver = &sm6125_mdss_ver,
+	.caps = &sm6125_dpu_caps,
+	.mdp = &sm6125_mdp,
+	.ctl_count = ARRAY_SIZE(sm6125_ctl),
+	.ctl = sm6125_ctl,
+	.sspp_count = ARRAY_SIZE(sm6125_sspp),
+	.sspp = sm6125_sspp,
+	.mixer_count = ARRAY_SIZE(sm6125_lm),
+	.mixer = sm6125_lm,
+	.dspp_count = ARRAY_SIZE(sm6125_dspp),
+	.dspp = sm6125_dspp,
+	.pingpong_count = ARRAY_SIZE(sm6125_pp),
+	.pingpong = sm6125_pp,
+	.intf_count = ARRAY_SIZE(sm6125_intf),
+	.intf = sm6125_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sm6125_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_6_0_sm8250.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_6_0_sm8250.h
@@ -0,0 +1,411 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_6_0_SM8250_H
+#define _DPU_6_0_SM8250_H
+
+static const struct dpu_caps sm8250_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0xb,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.has_3d_merge = true,
+	.max_linewidth = 4096,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg sm8250_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x494,
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
+		[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
+		[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
+	},
+};
+
+/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
+static const struct dpu_ctl_cfg sm8250_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x1000, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x1200, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_SPLIT_DISPLAY),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x1400, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x1600, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x1800, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	}, {
+		.name = "ctl_5", .id = CTL_5,
+		.base = 0x1a00, .len = 0x1e0,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+	},
+};
+
+static const struct dpu_sspp_cfg sm8250_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x1f8,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x1f8,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG1,
+	}, {
+		.name = "sspp_2", .id = SSPP_VIG2,
+		.base = 0x8000, .len = 0x1f8,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 8,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG2,
+	}, {
+		.name = "sspp_3", .id = SSPP_VIG3,
+		.base = 0xa000, .len = 0x1f8,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 12,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG3,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x1f8,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x1f8,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x1f8,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	}, {
+		.name = "sspp_11", .id = SSPP_DMA3,
+		.base = 0x2a000, .len = 0x1f8,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 13,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA3,
+	},
+};
+
+static const struct dpu_lm_cfg sm8250_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_3,
+		.pingpong = PINGPONG_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x47000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+	}, {
+		.name = "lm_4", .id = LM_4,
+		.base = 0x48000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_4,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_4,
+		.pingpong = PINGPONG_5,
+	},
+};
+
+static const struct dpu_dspp_cfg sm8250_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_2", .id = DSPP_2,
+		.base = 0x58000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_3", .id = DSPP_3,
+		.base = 0x5a000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sm8250_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x70000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x70800, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x71000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x71800, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+	}, {
+		.name = "pingpong_4", .id = PINGPONG_4,
+		.base = 0x72000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+	}, {
+		.name = "pingpong_5", .id = PINGPONG_5,
+		.base = 0x72800, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+	},
+};
+
+static const struct dpu_merge_3d_cfg sm8250_merge_3d[] = {
+	{
+		.name = "merge_3d_0", .id = MERGE_3D_0,
+		.base = 0x83000, .len = 0x8,
+	}, {
+		.name = "merge_3d_1", .id = MERGE_3D_1,
+		.base = 0x83100, .len = 0x8,
+	}, {
+		.name = "merge_3d_2", .id = MERGE_3D_2,
+		.base = 0x83200, .len = 0x8,
+	},
+};
+
+static const struct dpu_dsc_cfg sm8250_dsc[] = {
+	{
+		.name = "dsc_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	}, {
+		.name = "dsc_1", .id = DSC_1,
+		.base = 0x80400, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	}, {
+		.name = "dsc_2", .id = DSC_2,
+		.base = 0x80800, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	}, {
+		.name = "dsc_3", .id = DSC_3,
+		.base = 0x80c00, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	},
+};
+
+static const struct dpu_intf_cfg sm8250_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x6a000, .len = 0x280,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x6a800, .len = 0x2c0,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	}, {
+		.name = "intf_2", .id = INTF_2,
+		.base = 0x6b000, .len = 0x2c0,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2),
+	}, {
+		.name = "intf_3", .id = INTF_3,
+		.base = 0x6b800, .len = 0x280,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
+	},
+};
+
+static const struct dpu_wb_cfg sm8250_wb[] = {
+	{
+		.name = "wb_2", .id = WB_2,
+		.base = 0x65000, .len = 0x2c8,
+		.features = WB_SM8250_MASK,
+		.format_list = wb2_formats_rgb_yuv,
+		.num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv),
+		.clk_ctrl = DPU_CLK_CTRL_WB2,
+		.xin_id = 6,
+		.vbif_idx = VBIF_RT,
+		.maxlinewidth = 4096,
+		.intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4),
+	},
+};
+
+static const struct dpu_perf_cfg sm8250_perf_data = {
+	.max_bw_low = 13700000,
+	.max_bw_high = 16600000,
+	.min_core_ib = 4800000,
+	.min_llcc_ib = 0,
+	.min_dram_ib = 800000,
+	.min_prefill_lines = 35,
+	.danger_lut_tbl = {0xf, 0xffff, 0x0},
+	.safe_lut_tbl = {0xfff0, 0xff00, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sc7180_qos_linear),
+		.entries = sc7180_qos_linear
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+		.entries = sc7180_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+		/* TODO: macrotile-qseed is different from macrotile */
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sm8250_mdss_ver = {
+	.core_major_ver = 6,
+	.core_minor_ver = 0,
+};
+
+const struct dpu_mdss_cfg dpu_sm8250_cfg = {
+	.mdss_ver = &sm8250_mdss_ver,
+	.caps = &sm8250_dpu_caps,
+	.mdp = &sm8250_mdp,
+	.cdm = &sc7280_cdm,
+	.ctl_count = ARRAY_SIZE(sm8250_ctl),
+	.ctl = sm8250_ctl,
+	.sspp_count = ARRAY_SIZE(sm8250_sspp),
+	.sspp = sm8250_sspp,
+	.mixer_count = ARRAY_SIZE(sm8250_lm),
+	.mixer = sm8250_lm,
+	.dspp_count = ARRAY_SIZE(sm8250_dspp),
+	.dspp = sm8250_dspp,
+	.dsc_count = ARRAY_SIZE(sm8250_dsc),
+	.dsc = sm8250_dsc,
+	.pingpong_count = ARRAY_SIZE(sm8250_pp),
+	.pingpong = sm8250_pp,
+	.merge_3d_count = ARRAY_SIZE(sm8250_merge_3d),
+	.merge_3d = sm8250_merge_3d,
+	.intf_count = ARRAY_SIZE(sm8250_intf),
+	.intf = sm8250_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.wb_count = ARRAY_SIZE(sm8250_wb),
+	.wb = sm8250_wb,
+	.perf = &sm8250_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_6_2_sc7180.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_6_2_sc7180.h
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_6_2_SC7180_H
+#define _DPU_6_2_SC7180_H
+
+static const struct dpu_caps sc7180_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0x9,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg sc7180_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x494,
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 },
+		[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
+	},
+};
+
+static const struct dpu_ctl_cfg sc7180_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x1000, .len = 0x1dc,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x1200, .len = 0x1dc,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x1400, .len = 0x1dc,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	},
+};
+
+static const struct dpu_sspp_cfg sc7180_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x1f8,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x1f8,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x1f8,
+		.features = DMA_CURSOR_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x1f8,
+		.features = DMA_CURSOR_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	},
+};
+
+static const struct dpu_lm_cfg sc7180_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sc7180_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sc7180_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+	},
+};
+
+static const struct dpu_dspp_cfg sc7180_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sc7180_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x70000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = 0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x70800, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = 0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	},
+};
+
+static const struct dpu_intf_cfg sc7180_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x6a000, .len = 0x280,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x6a800, .len = 0x2c0,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	},
+};
+
+static const struct dpu_wb_cfg sc7180_wb[] = {
+	{
+		.name = "wb_2", .id = WB_2,
+		.base = 0x65000, .len = 0x2c8,
+		.features = WB_SM8250_MASK,
+		.format_list = wb2_formats_rgb,
+		.num_formats = ARRAY_SIZE(wb2_formats_rgb),
+		.clk_ctrl = DPU_CLK_CTRL_WB2,
+		.xin_id = 6,
+		.vbif_idx = VBIF_RT,
+		.maxlinewidth = 4096,
+		.intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4),
+	},
+};
+
+static const struct dpu_perf_cfg sc7180_perf_data = {
+	.max_bw_low = 6800000,
+	.max_bw_high = 6800000,
+	.min_core_ib = 2400000,
+	.min_llcc_ib = 800000,
+	.min_dram_ib = 1600000,
+	.min_prefill_lines = 24,
+	.danger_lut_tbl = {0xff, 0xffff, 0x0},
+	.safe_lut_tbl = {0xfff0, 0xff00, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sc7180_qos_linear),
+		.entries = sc7180_qos_linear
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+		.entries = sc7180_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sc7180_mdss_ver = {
+	.core_major_ver = 6,
+	.core_minor_ver = 2,
+};
+
+const struct dpu_mdss_cfg dpu_sc7180_cfg = {
+	.mdss_ver = &sc7180_mdss_ver,
+	.caps = &sc7180_dpu_caps,
+	.mdp = &sc7180_mdp,
+	.ctl_count = ARRAY_SIZE(sc7180_ctl),
+	.ctl = sc7180_ctl,
+	.sspp_count = ARRAY_SIZE(sc7180_sspp),
+	.sspp = sc7180_sspp,
+	.mixer_count = ARRAY_SIZE(sc7180_lm),
+	.mixer = sc7180_lm,
+	.dspp_count = ARRAY_SIZE(sc7180_dspp),
+	.dspp = sc7180_dspp,
+	.pingpong_count = ARRAY_SIZE(sc7180_pp),
+	.pingpong = sc7180_pp,
+	.intf_count = ARRAY_SIZE(sc7180_intf),
+	.intf = sc7180_intf,
+	.wb_count = ARRAY_SIZE(sc7180_wb),
+	.wb = sc7180_wb,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sc7180_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_6_3_sm6115.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_6_3_sm6115.h
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_6_3_SM6115_H
+#define _DPU_6_3_SM6115_H
+
+static const struct dpu_caps sm6115_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
+	.max_mixer_blendstages = 0x4,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.max_linewidth = 2160,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg sm6115_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x494,
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+	},
+};
+
+static const struct dpu_ctl_cfg sm6115_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x1000, .len = 0x1dc,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	},
+};
+
+static const struct dpu_sspp_cfg sm6115_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x1f8,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x1f8,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	},
+};
+
+static const struct dpu_lm_cfg sm6115_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_QCM2290_MASK,
+		.sblk = &qcm2290_lm_sblk,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	},
+};
+
+static const struct dpu_dspp_cfg sm6115_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sm6115_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x70000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = 0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	},
+};
+
+static const struct dpu_intf_cfg sm6115_intf[] = {
+	{
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x6a800, .len = 0x2c0,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	},
+};
+
+static const struct dpu_perf_cfg sm6115_perf_data = {
+	.max_bw_low = 3100000,
+	.max_bw_high = 4000000,
+	.min_core_ib = 2400000,
+	.min_llcc_ib = 800000,
+	.min_dram_ib = 800000,
+	.min_prefill_lines = 24,
+	.danger_lut_tbl = {0xff, 0xffff, 0x0},
+	.safe_lut_tbl = {0xfff0, 0xff00, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sc7180_qos_linear),
+		.entries = sc7180_qos_linear
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+		.entries = sc7180_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+		/* TODO: macrotile-qseed is different from macrotile */
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sm6115_mdss_ver = {
+	.core_major_ver = 6,
+	.core_minor_ver = 3,
+};
+
+const struct dpu_mdss_cfg dpu_sm6115_cfg = {
+	.mdss_ver = &sm6115_mdss_ver,
+	.caps = &sm6115_dpu_caps,
+	.mdp = &sm6115_mdp,
+	.ctl_count = ARRAY_SIZE(sm6115_ctl),
+	.ctl = sm6115_ctl,
+	.sspp_count = ARRAY_SIZE(sm6115_sspp),
+	.sspp = sm6115_sspp,
+	.mixer_count = ARRAY_SIZE(sm6115_lm),
+	.mixer = sm6115_lm,
+	.dspp_count = ARRAY_SIZE(sm6115_dspp),
+	.dspp = sm6115_dspp,
+	.pingpong_count = ARRAY_SIZE(sm6115_pp),
+	.pingpong = sm6115_pp,
+	.intf_count = ARRAY_SIZE(sm6115_intf),
+	.intf = sm6115_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sm6115_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_6_4_sm6350.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_6_4_sm6350.h
@@ -0,0 +1,228 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef _DPU_6_4_SM6350_H
+#define _DPU_6_4_SM6350_H
+
+static const struct dpu_caps sm6350_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0x7,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg sm6350_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x494,
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 },
+		[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
+	},
+};
+
+static const struct dpu_ctl_cfg sm6350_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x1000, .len = 0x1dc,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x1200, .len = 0x1dc,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x1400, .len = 0x1dc,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x1600, .len = 0x1dc,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	},
+};
+
+static const struct dpu_sspp_cfg sm6350_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x1f8,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x1f8,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x1f8,
+		.features = DMA_CURSOR_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x1f8,
+		.features = DMA_CURSOR_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	},
+};
+
+static const struct dpu_lm_cfg sm6350_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sc7180_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sc7180_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = 0,
+	},
+};
+
+static const struct dpu_dspp_cfg sm6350_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static struct dpu_pingpong_cfg sm6350_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x70000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = 0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x70800, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = 0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	},
+};
+
+static const struct dpu_dsc_cfg sm6350_dsc[] = {
+	{
+		.name = "dsc_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	},
+};
+
+static const struct dpu_intf_cfg sm6350_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x6a000, .len = 0x280,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 35,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x6a800, .len = 0x2c0,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 35,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	},
+};
+
+static const struct dpu_perf_cfg sm6350_perf_data = {
+	.max_bw_low = 4200000,
+	.max_bw_high = 5100000,
+	.min_core_ib = 2500000,
+	.min_llcc_ib = 0,
+	.min_dram_ib = 1600000,
+	.min_prefill_lines = 35,
+	/* TODO: confirm danger_lut_tbl */
+	.danger_lut_tbl = {0xffff, 0xffff, 0x0},
+	.safe_lut_tbl = {0xff00, 0xff00, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile),
+		.entries = sm6350_qos_linear_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile),
+		.entries = sm6350_qos_linear_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sm6350_mdss_ver = {
+	.core_major_ver = 6,
+	.core_minor_ver = 4,
+};
+
+const struct dpu_mdss_cfg dpu_sm6350_cfg = {
+	.mdss_ver = &sm6350_mdss_ver,
+	.caps = &sm6350_dpu_caps,
+	.mdp = &sm6350_mdp,
+	.ctl_count = ARRAY_SIZE(sm6350_ctl),
+	.ctl = sm6350_ctl,
+	.sspp_count = ARRAY_SIZE(sm6350_sspp),
+	.sspp = sm6350_sspp,
+	.mixer_count = ARRAY_SIZE(sm6350_lm),
+	.mixer = sm6350_lm,
+	.dspp_count = ARRAY_SIZE(sm6350_dspp),
+	.dspp = sm6350_dspp,
+	.dsc_count = ARRAY_SIZE(sm6350_dsc),
+	.dsc = sm6350_dsc,
+	.pingpong_count = ARRAY_SIZE(sm6350_pp),
+	.pingpong = sm6350_pp,
+	.intf_count = ARRAY_SIZE(sm6350_intf),
+	.intf = sm6350_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sm6350_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_6_5_qcm2290.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_6_5_qcm2290.h
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_6_5_QCM2290_H
+#define _DPU_6_5_QCM2290_H
+
+static const struct dpu_caps qcm2290_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
+	.max_mixer_blendstages = 0x4,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.max_linewidth = 2160,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg qcm2290_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x494,
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+	},
+};
+
+static const struct dpu_ctl_cfg qcm2290_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x1000, .len = 0x1dc,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	},
+};
+
+static const struct dpu_sspp_cfg qcm2290_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x1f8,
+		.features = VIG_QCM2290_MASK,
+		.sblk = &dpu_vig_sblk_noscale,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x1f8,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	},
+};
+
+static const struct dpu_lm_cfg qcm2290_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_QCM2290_MASK,
+		.sblk = &qcm2290_lm_sblk,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	},
+};
+
+static const struct dpu_dspp_cfg qcm2290_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg qcm2290_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x70000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = 0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	},
+};
+
+static const struct dpu_intf_cfg qcm2290_intf[] = {
+	{
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x6a800, .len = 0x2c0,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	},
+};
+
+static const struct dpu_perf_cfg qcm2290_perf_data = {
+	.max_bw_low = 2700000,
+	.max_bw_high = 2700000,
+	.min_core_ib = 1300000,
+	.min_llcc_ib = 0,
+	.min_dram_ib = 1600000,
+	.min_prefill_lines = 24,
+	.danger_lut_tbl = {0xff, 0x0, 0x0},
+	.safe_lut_tbl = {0xfff0, 0x0, 0x0},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(qcm2290_qos_linear),
+		.entries = qcm2290_qos_linear
+		},
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version qcm2290_mdss_ver = {
+	.core_major_ver = 6,
+	.core_minor_ver = 5,
+};
+
+const struct dpu_mdss_cfg dpu_qcm2290_cfg = {
+	.mdss_ver = &qcm2290_mdss_ver,
+	.caps = &qcm2290_dpu_caps,
+	.mdp = &qcm2290_mdp,
+	.ctl_count = ARRAY_SIZE(qcm2290_ctl),
+	.ctl = qcm2290_ctl,
+	.sspp_count = ARRAY_SIZE(qcm2290_sspp),
+	.sspp = qcm2290_sspp,
+	.mixer_count = ARRAY_SIZE(qcm2290_lm),
+	.mixer = qcm2290_lm,
+	.dspp_count = ARRAY_SIZE(qcm2290_dspp),
+	.dspp = qcm2290_dspp,
+	.pingpong_count = ARRAY_SIZE(qcm2290_pp),
+	.pingpong = qcm2290_pp,
+	.intf_count = ARRAY_SIZE(qcm2290_intf),
+	.intf = qcm2290_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &qcm2290_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_6_9_sm6375.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_6_9_sm6375.h
@@ -0,0 +1,169 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023, Linaro Limited
+ */
+
+#ifndef _DPU_6_9_SM6375_H
+#define _DPU_6_9_SM6375_H
+
+static const struct dpu_caps sm6375_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
+	.max_mixer_blendstages = 0x4,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.max_linewidth = 2160,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg sm6375_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x494,
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+	},
+};
+
+static const struct dpu_ctl_cfg sm6375_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x1000, .len = 0x1dc,
+		.features = BIT(DPU_CTL_ACTIVE_CFG),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	},
+};
+
+static const struct dpu_sspp_cfg sm6375_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x1f8,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x1f8,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	},
+};
+
+static const struct dpu_lm_cfg sm6375_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_QCM2290_MASK,
+		.sblk = &qcm2290_lm_sblk,
+		.lm_pair = 0,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	},
+};
+
+static const struct dpu_dspp_cfg sm6375_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sm6375_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x70000, .len = 0xd4,
+		.features = PINGPONG_SM8150_MASK,
+		.sblk = &sdm845_pp_sblk,
+		.merge_3d = 0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	},
+};
+
+static const struct dpu_dsc_cfg sm6375_dsc[] = {
+	{
+		.name = "dsc_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x140,
+		.features = BIT(DPU_DSC_OUTPUT_CTRL),
+	},
+};
+
+static const struct dpu_intf_cfg sm6375_intf[] = {
+	{
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x6a800, .len = 0x2c0,
+		.features = INTF_SC7180_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	},
+};
+
+static const struct dpu_perf_cfg sm6375_perf_data = {
+	.max_bw_low = 5200000,
+	.max_bw_high = 6200000,
+	.min_core_ib = 2500000,
+	.min_llcc_ib = 0, /* No LLCC on this SoC */
+	.min_dram_ib = 1600000,
+	.min_prefill_lines = 24,
+	/* TODO: confirm danger_lut_tbl */
+	.danger_lut_tbl = {0xffff, 0xffff, 0x0},
+	.safe_lut_tbl = {0xfe00, 0xfe00, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile),
+		.entries = sm6350_qos_linear_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile),
+		.entries = sm6350_qos_linear_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sm6375_mdss_ver = {
+	.core_major_ver = 6,
+	.core_minor_ver = 9,
+};
+
+const struct dpu_mdss_cfg dpu_sm6375_cfg = {
+	.mdss_ver = &sm6375_mdss_ver,
+	.caps = &sm6375_dpu_caps,
+	.mdp = &sm6375_mdp,
+	.ctl_count = ARRAY_SIZE(sm6375_ctl),
+	.ctl = sm6375_ctl,
+	.sspp_count = ARRAY_SIZE(sm6375_sspp),
+	.sspp = sm6375_sspp,
+	.mixer_count = ARRAY_SIZE(sm6375_lm),
+	.mixer = sm6375_lm,
+	.dspp_count = ARRAY_SIZE(sm6375_dspp),
+	.dspp = sm6375_dspp,
+	.dsc_count = ARRAY_SIZE(sm6375_dsc),
+	.dsc = sm6375_dsc,
+	.pingpong_count = ARRAY_SIZE(sm6375_pp),
+	.pingpong = sm6375_pp,
+	.intf_count = ARRAY_SIZE(sm6375_intf),
+	.intf = sm6375_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sm6375_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_7_0_sm8350.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_7_0_sm8350.h
@@ -0,0 +1,420 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_7_0_SM8350_H
+#define _DPU_7_0_SM8350_H
+
+static const struct dpu_caps sm8350_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0xb,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.has_3d_merge = true,
+	.max_linewidth = 4096,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg sm8350_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x494,
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
+		[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
+		[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
+	},
+};
+
+/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
+static const struct dpu_ctl_cfg sm8350_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x15000, .len = 0x1e8,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x16000, .len = 0x1e8,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x17000, .len = 0x1e8,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x18000, .len = 0x1e8,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x19000, .len = 0x1e8,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	}, {
+		.name = "ctl_5", .id = CTL_5,
+		.base = 0x1a000, .len = 0x1e8,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+	},
+};
+
+static const struct dpu_sspp_cfg sm8350_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x1f8,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x1f8,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG1,
+	}, {
+		.name = "sspp_2", .id = SSPP_VIG2,
+		.base = 0x8000, .len = 0x1f8,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 8,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG2,
+	}, {
+		.name = "sspp_3", .id = SSPP_VIG3,
+		.base = 0xa000, .len = 0x1f8,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 12,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG3,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x1f8,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x1f8,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x1f8,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	}, {
+		.name = "sspp_11", .id = SSPP_DMA3,
+		.base = 0x2a000, .len = 0x1f8,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 13,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA3,
+	},
+};
+
+static const struct dpu_lm_cfg sm8350_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_3,
+		.pingpong = PINGPONG_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x47000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+	}, {
+		.name = "lm_4", .id = LM_4,
+		.base = 0x48000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_4,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_4,
+		.pingpong = PINGPONG_5,
+	},
+};
+
+static const struct dpu_dspp_cfg sm8350_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_2", .id = DSPP_2,
+		.base = 0x58000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_3", .id = DSPP_3,
+		.base = 0x5a000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sm8350_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x69000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x6a000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x6b000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x6c000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+	}, {
+		.name = "pingpong_4", .id = PINGPONG_4,
+		.base = 0x6d000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+	}, {
+		.name = "pingpong_5", .id = PINGPONG_5,
+		.base = 0x6e000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+	},
+};
+
+static const struct dpu_merge_3d_cfg sm8350_merge_3d[] = {
+	{
+		.name = "merge_3d_0", .id = MERGE_3D_0,
+		.base = 0x4e000, .len = 0x8,
+	}, {
+		.name = "merge_3d_1", .id = MERGE_3D_1,
+		.base = 0x4f000, .len = 0x8,
+	}, {
+		.name = "merge_3d_2", .id = MERGE_3D_2,
+		.base = 0x50000, .len = 0x8,
+	},
+};
+
+/*
+ * NOTE: Each display compression engine (DCE) contains dual hard
+ * slice DSC encoders so both share same base address but with
+ * its own different sub block address.
+ */
+static const struct dpu_dsc_cfg sm8350_dsc[] = {
+	{
+		.name = "dce_0_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_0_1", .id = DSC_1,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_1_0", .id = DSC_2,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_1_1", .id = DSC_3,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_1,
+	},
+};
+
+static const struct dpu_wb_cfg sm8350_wb[] = {
+	{
+		.name = "wb_2", .id = WB_2,
+		.base = 0x65000, .len = 0x2c8,
+		.features = WB_SM8250_MASK,
+		.format_list = wb2_formats_rgb,
+		.num_formats = ARRAY_SIZE(wb2_formats_rgb),
+		.clk_ctrl = DPU_CLK_CTRL_WB2,
+		.xin_id = 6,
+		.vbif_idx = VBIF_RT,
+		.maxlinewidth = 4096,
+		.intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4),
+	},
+};
+
+static const struct dpu_intf_cfg sm8350_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x34000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x35000, .len = 0x2c4,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	}, {
+		.name = "intf_2", .id = INTF_2,
+		.base = 0x36000, .len = 0x2c4,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2),
+	}, {
+		.name = "intf_3", .id = INTF_3,
+		.base = 0x37000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
+	},
+};
+
+static const struct dpu_perf_cfg sm8350_perf_data = {
+	.max_bw_low = 11800000,
+	.max_bw_high = 15500000,
+	.min_core_ib = 2500000,
+	.min_llcc_ib = 0,
+	.min_dram_ib = 800000,
+	.min_prefill_lines = 40,
+	/* FIXME: lut tables */
+	.danger_lut_tbl = {0x3ffff, 0x3ffff, 0x0},
+	.safe_lut_tbl = {0xfe00, 0xfe00, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sc7180_qos_linear),
+		.entries = sc7180_qos_linear
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+		.entries = sc7180_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+		/* TODO: macrotile-qseed is different from macrotile */
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sm8350_mdss_ver = {
+	.core_major_ver = 7,
+	.core_minor_ver = 0,
+};
+
+const struct dpu_mdss_cfg dpu_sm8350_cfg = {
+	.mdss_ver = &sm8350_mdss_ver,
+	.caps = &sm8350_dpu_caps,
+	.mdp = &sm8350_mdp,
+	.ctl_count = ARRAY_SIZE(sm8350_ctl),
+	.ctl = sm8350_ctl,
+	.sspp_count = ARRAY_SIZE(sm8350_sspp),
+	.sspp = sm8350_sspp,
+	.mixer_count = ARRAY_SIZE(sm8350_lm),
+	.mixer = sm8350_lm,
+	.dspp_count = ARRAY_SIZE(sm8350_dspp),
+	.dspp = sm8350_dspp,
+	.pingpong_count = ARRAY_SIZE(sm8350_pp),
+	.pingpong = sm8350_pp,
+	.dsc_count = ARRAY_SIZE(sm8350_dsc),
+	.dsc = sm8350_dsc,
+	.merge_3d_count = ARRAY_SIZE(sm8350_merge_3d),
+	.merge_3d = sm8350_merge_3d,
+	.wb_count = ARRAY_SIZE(sm8350_wb),
+	.wb = sm8350_wb,
+	.intf_count = ARRAY_SIZE(sm8350_intf),
+	.intf = sm8350_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sm8350_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_7_2_sc7280.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_7_2_sc7280.h
@@ -0,0 +1,273 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_7_2_SC7280_H
+#define _DPU_7_2_SC7280_H
+
+static const struct dpu_caps sc7280_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0x7,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.max_linewidth = 2400,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg sc7280_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x2014,
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 },
+		[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
+	},
+};
+
+static const struct dpu_ctl_cfg sc7280_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x15000, .len = 0x1e8,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x16000, .len = 0x1e8,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x17000, .len = 0x1e8,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x18000, .len = 0x1e8,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	},
+};
+
+static const struct dpu_sspp_cfg sc7280_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x1f8,
+		.features = VIG_SC7280_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_0_rot_v2,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x1f8,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x1f8,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x1f8,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	},
+};
+
+static const struct dpu_lm_cfg sc7280_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sc7180_lm_sblk,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sc7180_lm_sblk,
+		.lm_pair = LM_3,
+		.pingpong = PINGPONG_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x47000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sc7180_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+	},
+};
+
+static const struct dpu_dspp_cfg sc7280_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sc7280_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x69000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = 0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x6a000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = 0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x6b000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = 0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x6c000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = 0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+	},
+};
+
+/* NOTE: sc7280 only has one DSC hard slice encoder */
+static const struct dpu_dsc_cfg sc7280_dsc[] = {
+	{
+		.name = "dce_0_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_0,
+	},
+};
+
+static const struct dpu_wb_cfg sc7280_wb[] = {
+	{
+		.name = "wb_2", .id = WB_2,
+		.base = 0x65000, .len = 0x2c8,
+		.features = WB_SM8250_MASK,
+		.format_list = wb2_formats_rgb_yuv,
+		.num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv),
+		.clk_ctrl = DPU_CLK_CTRL_WB2,
+		.xin_id = 6,
+		.vbif_idx = VBIF_RT,
+		.maxlinewidth = 4096,
+		.intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4),
+	},
+};
+
+static const struct dpu_intf_cfg sc7280_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x34000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x35000, .len = 0x2c4,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	}, {
+		.name = "intf_5", .id = INTF_5,
+		.base = 0x39000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 22),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 23),
+	},
+};
+
+static const struct dpu_perf_cfg sc7280_perf_data = {
+	.max_bw_low = 4700000,
+	.max_bw_high = 8800000,
+	.min_core_ib = 2500000,
+	.min_llcc_ib = 0,
+	.min_dram_ib = 1600000,
+	.min_prefill_lines = 24,
+	.danger_lut_tbl = {0xffff, 0xffff, 0x0},
+	.safe_lut_tbl = {0xff00, 0xff00, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+		.entries = sc7180_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+		.entries = sc7180_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sc7280_mdss_ver = {
+	.core_major_ver = 7,
+	.core_minor_ver = 2,
+};
+
+const struct dpu_mdss_cfg dpu_sc7280_cfg = {
+	.mdss_ver = &sc7280_mdss_ver,
+	.caps = &sc7280_dpu_caps,
+	.mdp = &sc7280_mdp,
+	.cdm = &sc7280_cdm,
+	.ctl_count = ARRAY_SIZE(sc7280_ctl),
+	.ctl = sc7280_ctl,
+	.sspp_count = ARRAY_SIZE(sc7280_sspp),
+	.sspp = sc7280_sspp,
+	.dspp_count = ARRAY_SIZE(sc7280_dspp),
+	.dspp = sc7280_dspp,
+	.mixer_count = ARRAY_SIZE(sc7280_lm),
+	.mixer = sc7280_lm,
+	.pingpong_count = ARRAY_SIZE(sc7280_pp),
+	.pingpong = sc7280_pp,
+	.dsc_count = ARRAY_SIZE(sc7280_dsc),
+	.dsc = sc7280_dsc,
+	.wb_count = ARRAY_SIZE(sc7280_wb),
+	.wb = sc7280_wb,
+	.intf_count = ARRAY_SIZE(sc7280_intf),
+	.intf = sc7280_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sc7280_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_8_0_sc8280xp.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_8_0_sc8280xp.h
@@ -0,0 +1,459 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_8_0_SC8280XP_H
+#define _DPU_8_0_SC8280XP_H
+
+static const struct dpu_caps sc8280xp_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 11,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.has_3d_merge = true,
+	.max_linewidth = 5120,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg sc8280xp_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x494,
+	.features = BIT(DPU_MDP_PERIPH_0_REMOVED),
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
+		[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
+	},
+};
+
+/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
+static const struct dpu_ctl_cfg sc8280xp_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x15000, .len = 0x204,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x16000, .len = 0x204,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x17000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x18000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x19000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	}, {
+		.name = "ctl_5", .id = CTL_5,
+		.base = 0x1a000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+	},
+};
+
+static const struct dpu_sspp_cfg sc8280xp_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x2ac,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x2ac,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG1,
+	}, {
+		.name = "sspp_2", .id = SSPP_VIG2,
+		.base = 0x8000, .len = 0x2ac,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 8,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG2,
+	}, {
+		.name = "sspp_3", .id = SSPP_VIG3,
+		.base = 0xa000, .len = 0x2ac,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_3_0,
+		.xin_id = 12,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG3,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x2ac,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x2ac,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x2ac,
+		.features = DMA_CURSOR_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	}, {
+		.name = "sspp_11", .id = SSPP_DMA3,
+		.base = 0x2a000, .len = 0x2ac,
+		.features = DMA_CURSOR_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 13,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA3,
+	},
+};
+
+static const struct dpu_lm_cfg sc8280xp_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_3,
+		.pingpong = PINGPONG_2,
+		.dspp = DSPP_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x47000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+		.dspp = DSPP_3,
+	}, {
+		.name = "lm_4", .id = LM_4,
+		.base = 0x48000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_4,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_4,
+		.pingpong = PINGPONG_5,
+	},
+};
+
+static const struct dpu_dspp_cfg sc8280xp_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_2", .id = DSPP_2,
+		.base = 0x58000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_3", .id = DSPP_3,
+		.base = 0x5a000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sc8280xp_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x69000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x6a000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x6b000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x6c000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+	}, {
+		.name = "pingpong_4", .id = PINGPONG_4,
+		.base = 0x6d000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+	}, {
+		.name = "pingpong_5", .id = PINGPONG_5,
+		.base = 0x6e000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+	},
+};
+
+static const struct dpu_merge_3d_cfg sc8280xp_merge_3d[] = {
+	{
+		.name = "merge_3d_0", .id = MERGE_3D_0,
+		.base = 0x4e000, .len = 0x8,
+	}, {
+		.name = "merge_3d_1", .id = MERGE_3D_1,
+		.base = 0x4f000, .len = 0x8,
+	}, {
+		.name = "merge_3d_2", .id = MERGE_3D_2,
+		.base = 0x50000, .len = 0x8,
+	},
+};
+
+/*
+ * NOTE: Each display compression engine (DCE) contains dual hard
+ * slice DSC encoders so both share same base address but with
+ * its own different sub block address.
+ */
+static const struct dpu_dsc_cfg sc8280xp_dsc[] = {
+	{
+		.name = "dce_0_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_0_1", .id = DSC_1,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_1_0", .id = DSC_2,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_1_1", .id = DSC_3,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_2_0", .id = DSC_4,
+		.base = 0x82000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_2_1", .id = DSC_5,
+		.base = 0x82000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_1,
+	},
+};
+
+/* TODO: INTF 3, 8 and 7 are used for MST, marked as INTF_NONE for now */
+static const struct dpu_intf_cfg sc8280xp_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x34000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x35000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	}, {
+		.name = "intf_2", .id = INTF_2,
+		.base = 0x36000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2),
+	}, {
+		.name = "intf_3", .id = INTF_3,
+		.base = 0x37000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_NONE,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
+	}, {
+		.name = "intf_4", .id = INTF_4,
+		.base = 0x38000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 20),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 21),
+	}, {
+		.name = "intf_5", .id = INTF_5,
+		.base = 0x39000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_3,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 22),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 23),
+	}, {
+		.name = "intf_6", .id = INTF_6,
+		.base = 0x3a000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_2,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 16),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 17),
+	}, {
+		.name = "intf_7", .id = INTF_7,
+		.base = 0x3b000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_NONE,
+		.controller_id = MSM_DP_CONTROLLER_2,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 18),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 19),
+	}, {
+		.name = "intf_8", .id = INTF_8,
+		.base = 0x3c000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_NONE,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
+	},
+};
+
+static const struct dpu_perf_cfg sc8280xp_perf_data = {
+	.max_bw_low = 13600000,
+	.max_bw_high = 18200000,
+	.min_core_ib = 2500000,
+	.min_llcc_ib = 0,
+	.min_dram_ib = 800000,
+	.danger_lut_tbl = {0xf, 0xffff, 0x0},
+	.safe_lut_tbl = {0xfe00, 0xfe00, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sc8180x_qos_linear),
+		.entries = sc8180x_qos_linear
+		},
+		{.nentry = ARRAY_SIZE(sc8180x_qos_macrotile),
+		.entries = sc8180x_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+		/* TODO: macrotile-qseed is different from macrotile */
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sc8280xp_mdss_ver = {
+	.core_major_ver = 8,
+	.core_minor_ver = 0,
+};
+
+const struct dpu_mdss_cfg dpu_sc8280xp_cfg = {
+	.mdss_ver = &sc8280xp_mdss_ver,
+	.caps = &sc8280xp_dpu_caps,
+	.mdp = &sc8280xp_mdp,
+	.ctl_count = ARRAY_SIZE(sc8280xp_ctl),
+	.ctl = sc8280xp_ctl,
+	.sspp_count = ARRAY_SIZE(sc8280xp_sspp),
+	.sspp = sc8280xp_sspp,
+	.mixer_count = ARRAY_SIZE(sc8280xp_lm),
+	.mixer = sc8280xp_lm,
+	.dspp_count = ARRAY_SIZE(sc8280xp_dspp),
+	.dspp = sc8280xp_dspp,
+	.pingpong_count = ARRAY_SIZE(sc8280xp_pp),
+	.pingpong = sc8280xp_pp,
+	.dsc_count = ARRAY_SIZE(sc8280xp_dsc),
+	.dsc = sc8280xp_dsc,
+	.merge_3d_count = ARRAY_SIZE(sc8280xp_merge_3d),
+	.merge_3d = sc8280xp_merge_3d,
+	.intf_count = ARRAY_SIZE(sc8280xp_intf),
+	.intf = sc8280xp_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sc8280xp_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_8_1_sm8450.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_8_1_sm8450.h
@@ -0,0 +1,438 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_8_1_SM8450_H
+#define _DPU_8_1_SM8450_H
+
+static const struct dpu_caps sm8450_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0xb,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.has_3d_merge = true,
+	.max_linewidth = 5120,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg sm8450_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x494,
+	.features = BIT(DPU_MDP_PERIPH_0_REMOVED),
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
+		[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
+		[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
+	},
+};
+
+/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
+static const struct dpu_ctl_cfg sm8450_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x15000, .len = 0x204,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x16000, .len = 0x204,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x17000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x18000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x19000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	}, {
+		.name = "ctl_5", .id = CTL_5,
+		.base = 0x1a000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+	},
+};
+
+static const struct dpu_sspp_cfg sm8450_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG1,
+	}, {
+		.name = "sspp_2", .id = SSPP_VIG2,
+		.base = 0x8000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 8,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG2,
+	}, {
+		.name = "sspp_3", .id = SSPP_VIG3,
+		.base = 0xa000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 12,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG3,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x32c,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x32c,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x32c,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	}, {
+		.name = "sspp_11", .id = SSPP_DMA3,
+		.base = 0x2a000, .len = 0x32c,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 13,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA3,
+	},
+};
+
+static const struct dpu_lm_cfg sm8450_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_3,
+		.pingpong = PINGPONG_2,
+		.dspp = DSPP_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x47000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+		.dspp = DSPP_3,
+	}, {
+		.name = "lm_4", .id = LM_4,
+		.base = 0x48000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_4,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_4,
+		.pingpong = PINGPONG_5,
+	},
+};
+
+static const struct dpu_dspp_cfg sm8450_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_2", .id = DSPP_2,
+		.base = 0x58000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_3", .id = DSPP_3,
+		.base = 0x5a000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sm8450_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x69000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x6a000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x6b000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x6c000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+	}, {
+		.name = "pingpong_4", .id = PINGPONG_4,
+		.base = 0x6d000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+	}, {
+		.name = "pingpong_5", .id = PINGPONG_5,
+		.base = 0x6e000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+	}, {
+		.name = "pingpong_6", .id = PINGPONG_6,
+		.base = 0x65800, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_3,
+	}, {
+		.name = "pingpong_7", .id = PINGPONG_7,
+		.base = 0x65c00, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_3,
+	},
+};
+
+static const struct dpu_merge_3d_cfg sm8450_merge_3d[] = {
+	{
+		.name = "merge_3d_0", .id = MERGE_3D_0,
+		.base = 0x4e000, .len = 0x8,
+	}, {
+		.name = "merge_3d_1", .id = MERGE_3D_1,
+		.base = 0x4f000, .len = 0x8,
+	}, {
+		.name = "merge_3d_2", .id = MERGE_3D_2,
+		.base = 0x50000, .len = 0x8,
+	}, {
+		.name = "merge_3d_3", .id = MERGE_3D_3,
+		.base = 0x65f00, .len = 0x8,
+	},
+};
+
+/*
+ * NOTE: Each display compression engine (DCE) contains dual hard
+ * slice DSC encoders so both share same base address but with
+ * its own different sub block address.
+ */
+static const struct dpu_dsc_cfg sm8450_dsc[] = {
+	{
+		.name = "dce_0_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_0_1", .id = DSC_1,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_1_0", .id = DSC_2,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_1_1", .id = DSC_3,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_1,
+	},
+};
+
+static const struct dpu_wb_cfg sm8450_wb[] = {
+	{
+		.name = "wb_2", .id = WB_2,
+		.base = 0x65000, .len = 0x2c8,
+		.features = WB_SM8250_MASK,
+		.format_list = wb2_formats_rgb,
+		.num_formats = ARRAY_SIZE(wb2_formats_rgb),
+		.clk_ctrl = DPU_CLK_CTRL_WB2,
+		.xin_id = 6,
+		.vbif_idx = VBIF_RT,
+		.maxlinewidth = 4096,
+		.intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4),
+	},
+};
+
+static const struct dpu_intf_cfg sm8450_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x34000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x35000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	}, {
+		.name = "intf_2", .id = INTF_2,
+		.base = 0x36000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2),
+	}, {
+		.name = "intf_3", .id = INTF_3,
+		.base = 0x37000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
+	},
+};
+
+static const struct dpu_perf_cfg sm8450_perf_data = {
+	.max_bw_low = 13600000,
+	.max_bw_high = 18200000,
+	.min_core_ib = 2500000,
+	.min_llcc_ib = 0,
+	.min_dram_ib = 800000,
+	.min_prefill_lines = 35,
+	/* FIXME: lut tables */
+	.danger_lut_tbl = {0x3ffff, 0x3ffff, 0x0},
+	.safe_lut_tbl = {0xfe00, 0xfe00, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sc7180_qos_linear),
+		.entries = sc7180_qos_linear
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+		.entries = sc7180_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+		/* TODO: macrotile-qseed is different from macrotile */
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sm8450_mdss_ver = {
+	.core_major_ver = 8,
+	.core_minor_ver = 1,
+};
+
+const struct dpu_mdss_cfg dpu_sm8450_cfg = {
+	.mdss_ver = &sm8450_mdss_ver,
+	.caps = &sm8450_dpu_caps,
+	.mdp = &sm8450_mdp,
+	.ctl_count = ARRAY_SIZE(sm8450_ctl),
+	.ctl = sm8450_ctl,
+	.sspp_count = ARRAY_SIZE(sm8450_sspp),
+	.sspp = sm8450_sspp,
+	.mixer_count = ARRAY_SIZE(sm8450_lm),
+	.mixer = sm8450_lm,
+	.dspp_count = ARRAY_SIZE(sm8450_dspp),
+	.dspp = sm8450_dspp,
+	.pingpong_count = ARRAY_SIZE(sm8450_pp),
+	.pingpong = sm8450_pp,
+	.dsc_count = ARRAY_SIZE(sm8450_dsc),
+	.dsc = sm8450_dsc,
+	.merge_3d_count = ARRAY_SIZE(sm8450_merge_3d),
+	.merge_3d = sm8450_merge_3d,
+	.wb_count = ARRAY_SIZE(sm8450_wb),
+	.wb = sm8450_wb,
+	.intf_count = ARRAY_SIZE(sm8450_intf),
+	.intf = sm8450_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sm8450_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_8_4_qcs8300.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_8_4_qcs8300.h
@@ -0,0 +1,485 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_8_4_QCS8300_H
+#define _DPU_8_4_QCS8300_H
+
+static const struct dpu_caps qcs8300_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0xb,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.has_3d_merge = true,
+	.max_linewidth = 5120,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg qcs8300_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x494,
+	.features = BIT(DPU_MDP_PERIPH_0_REMOVED),
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
+		[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
+		[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
+	},
+};
+
+/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
+static const struct dpu_ctl_cfg qcs8300_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x15000, .len = 0x204,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x16000, .len = 0x204,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x17000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x18000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x19000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	}, {
+		.name = "ctl_5", .id = CTL_5,
+		.base = 0x1a000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+	},
+};
+
+static const struct dpu_sspp_cfg qcs8300_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG1,
+	}, {
+		.name = "sspp_2", .id = SSPP_VIG2,
+		.base = 0x8000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 8,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG2,
+	}, {
+		.name = "sspp_3", .id = SSPP_VIG3,
+		.base = 0xa000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 12,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG3,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x32c,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x32c,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x32c,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	}, {
+		.name = "sspp_11", .id = SSPP_DMA3,
+		.base = 0x2a000, .len = 0x32c,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 13,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA3,
+	},
+};
+
+static const struct dpu_lm_cfg qcs8300_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_3,
+		.pingpong = PINGPONG_2,
+		.dspp = DSPP_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x47000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+		.dspp = DSPP_3,
+	}, {
+		.name = "lm_4", .id = LM_4,
+		.base = 0x48000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_4,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_4,
+		.pingpong = PINGPONG_5,
+	},
+};
+
+static const struct dpu_dspp_cfg qcs8300_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_2", .id = DSPP_2,
+		.base = 0x58000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_3", .id = DSPP_3,
+		.base = 0x5a000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg qcs8300_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x69000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x6a000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x6b000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x6c000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+	}, {
+		.name = "pingpong_4", .id = PINGPONG_4,
+		.base = 0x6d000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+	}, {
+		.name = "pingpong_5", .id = PINGPONG_5,
+		.base = 0x6e000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+	}, {
+		.name = "pingpong_6", .id = PINGPONG_6,
+		.base = 0x65800, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_3,
+	}, {
+		.name = "pingpong_7", .id = PINGPONG_7,
+		.base = 0x65c00, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_3,
+	},
+};
+
+static const struct dpu_merge_3d_cfg qcs8300_merge_3d[] = {
+	{
+		.name = "merge_3d_0", .id = MERGE_3D_0,
+		.base = 0x4e000, .len = 0x8,
+	}, {
+		.name = "merge_3d_1", .id = MERGE_3D_1,
+		.base = 0x4f000, .len = 0x8,
+	}, {
+		.name = "merge_3d_2", .id = MERGE_3D_2,
+		.base = 0x50000, .len = 0x8,
+	}, {
+		.name = "merge_3d_3", .id = MERGE_3D_3,
+		.base = 0x65f00, .len = 0x8,
+	},
+};
+
+/*
+ * NOTE: Each display compression engine (DCE) contains dual hard
+ * slice DSC encoders so both share same base address but with
+ * its own different sub block address.
+ */
+static const struct dpu_dsc_cfg qcs8300_dsc[] = {
+	{
+		.name = "dce_0_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_0_1", .id = DSC_1,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_1_0", .id = DSC_2,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_1_1", .id = DSC_3,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_2_0", .id = DSC_4,
+		.base = 0x82000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_2_1", .id = DSC_5,
+		.base = 0x82000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_1,
+	},
+};
+
+static const struct dpu_wb_cfg qcs8300_wb[] = {
+	{
+		.name = "wb_2", .id = WB_2,
+		.base = 0x65000, .len = 0x2c8,
+		.features = WB_SM8250_MASK,
+		.format_list = wb2_formats_rgb_yuv,
+		.num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv),
+		.clk_ctrl = DPU_CLK_CTRL_WB2,
+		.xin_id = 6,
+		.vbif_idx = VBIF_RT,
+		.maxlinewidth = 4096,
+		.intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4),
+	},
+};
+/* TODO: INTF 3, 6, 7 and 8 are used for MST, marked as INTF_NONE for now */
+static const struct dpu_intf_cfg qcs8300_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x34000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x35000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	}, {
+		.name = "intf_2", .id = INTF_2,
+		.base = 0x36000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2),
+	}, {
+		.name = "intf_3", .id = INTF_3,
+		.base = 0x37000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,	/* pair with intf_0 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
+	}, {
+		.name = "intf_4", .id = INTF_4,
+		.base = 0x38000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 20),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 21),
+	}, {
+		.name = "intf_6", .id = INTF_6,
+		.base = 0x3A000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,	/* pair with intf_0 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 17),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 16),
+	}, {
+		.name = "intf_7", .id = INTF_7,
+		.base = 0x3b000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,	/* pair with intf_0 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 18),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 19),
+	}, {
+		.name = "intf_8", .id = INTF_8,
+		.base = 0x3c000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,	/* pair with intf_4 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
+	},
+};
+
+static const struct dpu_perf_cfg qcs8300_perf_data = {
+	.max_bw_low = 13600000,
+	.max_bw_high = 18200000,
+	.min_core_ib = 2500000,
+	.min_llcc_ib = 0,
+	.min_dram_ib = 800000,
+	.min_prefill_lines = 35,
+	/* FIXME: lut tables */
+	.danger_lut_tbl = {0x3ffff, 0x3ffff, 0x0},
+	.safe_lut_tbl = {0xfff0, 0xfff0, 0x1},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile),
+		.entries = sm6350_qos_linear_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile),
+		.entries = sm6350_qos_linear_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+		/* TODO: macrotile-qseed is different from macrotile */
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version qcs8300_mdss_ver = {
+	.core_major_ver = 8,
+	.core_minor_ver = 4,
+};
+
+const struct dpu_mdss_cfg dpu_qcs8300_cfg = {
+	.mdss_ver = &qcs8300_mdss_ver,
+	.caps = &qcs8300_dpu_caps,
+	.mdp = &qcs8300_mdp,
+	.cdm = &sc7280_cdm,
+	.ctl_count = ARRAY_SIZE(qcs8300_ctl),
+	.ctl = qcs8300_ctl,
+	.sspp_count = ARRAY_SIZE(qcs8300_sspp),
+	.sspp = qcs8300_sspp,
+	.mixer_count = ARRAY_SIZE(qcs8300_lm),
+	.mixer = qcs8300_lm,
+	.dspp_count = ARRAY_SIZE(qcs8300_dspp),
+	.dspp = qcs8300_dspp,
+	.pingpong_count = ARRAY_SIZE(qcs8300_pp),
+	.pingpong = qcs8300_pp,
+	.dsc_count = ARRAY_SIZE(qcs8300_dsc),
+	.dsc = qcs8300_dsc,
+	.merge_3d_count = ARRAY_SIZE(qcs8300_merge_3d),
+	.merge_3d = qcs8300_merge_3d,
+	.wb_count = ARRAY_SIZE(qcs8300_wb),
+	.wb = qcs8300_wb,
+	.intf_count = ARRAY_SIZE(qcs8300_intf),
+	.intf = qcs8300_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &qcs8300_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_8_4_sa8775p.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_8_4_sa8775p.h
@@ -0,0 +1,485 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_8_4_SA8775P_H
+#define _DPU_8_4_SA8775P_H
+
+static const struct dpu_caps sa8775p_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0xb,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.has_3d_merge = true,
+	.max_linewidth = 5120,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg sa8775p_mdp = {
+	.name = "top_0",
+	.base = 0x0, .len = 0x494,
+	.features = BIT(DPU_MDP_PERIPH_0_REMOVED),
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2ac, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG1] = { .reg_off = 0x2b4, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG2] = { .reg_off = 0x2bc, .bit_off = 0 },
+		[DPU_CLK_CTRL_VIG3] = { .reg_off = 0x2c4, .bit_off = 0 },
+		[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 },
+		[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 },
+		[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 },
+		[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
+	},
+};
+
+/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
+static const struct dpu_ctl_cfg sa8775p_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x15000, .len = 0x204,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x16000, .len = 0x204,
+		.features = BIT(DPU_CTL_SPLIT_DISPLAY) | CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x17000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x18000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x19000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	}, {
+		.name = "ctl_5", .id = CTL_5,
+		.base = 0x1a000, .len = 0x204,
+		.features = CTL_SC7280_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+	},
+};
+
+static const struct dpu_sspp_cfg sa8775p_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG0,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG1,
+	}, {
+		.name = "sspp_2", .id = SSPP_VIG2,
+		.base = 0x8000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 8,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG2,
+	}, {
+		.name = "sspp_3", .id = SSPP_VIG3,
+		.base = 0xa000, .len = 0x32c,
+		.features = VIG_SDM845_MASK_SDMA,
+		.sblk = &dpu_vig_sblk_qseed3_3_1,
+		.xin_id = 12,
+		.type = SSPP_TYPE_VIG,
+		.clk_ctrl = DPU_CLK_CTRL_VIG3,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x32c,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA0,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x32c,
+		.features = DMA_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA1,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x32c,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA2,
+	}, {
+		.name = "sspp_11", .id = SSPP_DMA3,
+		.base = 0x2a000, .len = 0x32c,
+		.features = DMA_CURSOR_SDM845_MASK_SDMA,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 13,
+		.type = SSPP_TYPE_DMA,
+		.clk_ctrl = DPU_CLK_CTRL_DMA3,
+	},
+};
+
+static const struct dpu_lm_cfg sa8775p_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_3,
+		.pingpong = PINGPONG_2,
+		.dspp = DSPP_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x47000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+		.dspp = DSPP_3,
+	}, {
+		.name = "lm_4", .id = LM_4,
+		.base = 0x48000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_4,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x400,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_4,
+		.pingpong = PINGPONG_5,
+	},
+};
+
+static const struct dpu_dspp_cfg sa8775p_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_2", .id = DSPP_2,
+		.base = 0x58000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_3", .id = DSPP_3,
+		.base = 0x5a000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+
+static const struct dpu_pingpong_cfg sa8775p_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x69000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x6a000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x6b000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x6c000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+	}, {
+		.name = "pingpong_4", .id = PINGPONG_4,
+		.base = 0x6d000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+	}, {
+		.name = "pingpong_5", .id = PINGPONG_5,
+		.base = 0x6e000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+	}, {
+		.name = "pingpong_6", .id = PINGPONG_6,
+		.base = 0x65800, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_3,
+	}, {
+		.name = "pingpong_7", .id = PINGPONG_7,
+		.base = 0x65c00, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_3,
+	},
+};
+
+static const struct dpu_merge_3d_cfg sa8775p_merge_3d[] = {
+	{
+		.name = "merge_3d_0", .id = MERGE_3D_0,
+		.base = 0x4e000, .len = 0x8,
+	}, {
+		.name = "merge_3d_1", .id = MERGE_3D_1,
+		.base = 0x4f000, .len = 0x8,
+	}, {
+		.name = "merge_3d_2", .id = MERGE_3D_2,
+		.base = 0x50000, .len = 0x8,
+	}, {
+		.name = "merge_3d_3", .id = MERGE_3D_3,
+		.base = 0x65f00, .len = 0x8,
+	},
+};
+
+/*
+ * NOTE: Each display compression engine (DCE) contains dual hard
+ * slice DSC encoders so both share same base address but with
+ * its own different sub block address.
+ */
+static const struct dpu_dsc_cfg sa8775p_dsc[] = {
+	{
+		.name = "dce_0_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_0_1", .id = DSC_1,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_1_0", .id = DSC_2,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_1_1", .id = DSC_3,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_2_0", .id = DSC_4,
+		.base = 0x82000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_2_1", .id = DSC_5,
+		.base = 0x82000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_1,
+	},
+};
+
+static const struct dpu_wb_cfg sa8775p_wb[] = {
+	{
+		.name = "wb_2", .id = WB_2,
+		.base = 0x65000, .len = 0x2c8,
+		.features = WB_SM8250_MASK,
+		.format_list = wb2_formats_rgb_yuv,
+		.num_formats = ARRAY_SIZE(wb2_formats_rgb_yuv),
+		.clk_ctrl = DPU_CLK_CTRL_WB2,
+		.xin_id = 6,
+		.vbif_idx = VBIF_RT,
+		.maxlinewidth = 4096,
+		.intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4),
+	},
+};
+/* TODO: INTF 3, 6, 7 and 8 are used for MST, marked as INTF_NONE for now */
+static const struct dpu_intf_cfg sa8775p_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x34000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x35000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	}, {
+		.name = "intf_2", .id = INTF_2,
+		.base = 0x36000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2),
+	}, {
+		.name = "intf_3", .id = INTF_3,
+		.base = 0x37000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,	/* pair with intf_0 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
+	}, {
+		.name = "intf_4", .id = INTF_4,
+		.base = 0x38000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 20),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 21),
+	}, {
+		.name = "intf_6", .id = INTF_6,
+		.base = 0x3A000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,	/* pair with intf_0 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 17),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 16),
+	}, {
+		.name = "intf_7", .id = INTF_7,
+		.base = 0x3b000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,	/* pair with intf_0 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 18),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 19),
+	}, {
+		.name = "intf_8", .id = INTF_8,
+		.base = 0x3c000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,	/* pair with intf_4 for DP MST */
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13),
+	},
+};
+
+static const struct dpu_perf_cfg sa8775p_perf_data = {
+	.max_bw_low = 13600000,
+	.max_bw_high = 18200000,
+	.min_core_ib = 2500000,
+	.min_llcc_ib = 0,
+	.min_dram_ib = 800000,
+	.min_prefill_lines = 35,
+	/* FIXME: lut tables */
+	.danger_lut_tbl = {0x3ffff, 0x3ffff, 0x0},
+	.safe_lut_tbl = {0xfff0, 0xfff0, 0x1},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile),
+		.entries = sm6350_qos_linear_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sm6350_qos_linear_macrotile),
+		.entries = sm6350_qos_linear_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+		/* TODO: macrotile-qseed is different from macrotile */
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sa8775p_mdss_ver = {
+	.core_major_ver = 8,
+	.core_minor_ver = 4,
+};
+
+const struct dpu_mdss_cfg dpu_sa8775p_cfg = {
+	.mdss_ver = &sa8775p_mdss_ver,
+	.caps = &sa8775p_dpu_caps,
+	.mdp = &sa8775p_mdp,
+	.cdm = &sc7280_cdm,
+	.ctl_count = ARRAY_SIZE(sa8775p_ctl),
+	.ctl = sa8775p_ctl,
+	.sspp_count = ARRAY_SIZE(sa8775p_sspp),
+	.sspp = sa8775p_sspp,
+	.mixer_count = ARRAY_SIZE(sa8775p_lm),
+	.mixer = sa8775p_lm,
+	.dspp_count = ARRAY_SIZE(sa8775p_dspp),
+	.dspp = sa8775p_dspp,
+	.pingpong_count = ARRAY_SIZE(sa8775p_pp),
+	.pingpong = sa8775p_pp,
+	.dsc_count = ARRAY_SIZE(sa8775p_dsc),
+	.dsc = sa8775p_dsc,
+	.merge_3d_count = ARRAY_SIZE(sa8775p_merge_3d),
+	.merge_3d = sa8775p_merge_3d,
+	.wb_count = ARRAY_SIZE(sa8775p_wb),
+	.wb = sa8775p_wb,
+	.intf_count = ARRAY_SIZE(sa8775p_intf),
+	.intf = sa8775p_intf,
+	.vbif_count = ARRAY_SIZE(sdm845_vbif),
+	.vbif = sdm845_vbif,
+	.perf = &sa8775p_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_9_0_sm8550.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/catalog/dpu_9_0_sm8550.h
@@ -0,0 +1,431 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_9_0_SM8550_H
+#define _DPU_9_0_SM8550_H
+
+static const struct dpu_caps sm8550_dpu_caps = {
+	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.max_mixer_blendstages = 0xb,
+	.has_src_split = true,
+	.has_dim_layer = true,
+	.has_idle_pc = true,
+	.has_3d_merge = true,
+	.max_linewidth = 5120,
+	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+};
+
+static const struct dpu_mdp_cfg sm8550_mdp = {
+	.name = "top_0",
+	.base = 0, .len = 0x494,
+	.features = BIT(DPU_MDP_PERIPH_0_REMOVED),
+	.clk_ctrls = {
+		[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 },
+	},
+};
+
+/* FIXME: get rid of DPU_CTL_SPLIT_DISPLAY in favour of proper ACTIVE_CTL support */
+static const struct dpu_ctl_cfg sm8550_ctl[] = {
+	{
+		.name = "ctl_0", .id = CTL_0,
+		.base = 0x15000, .len = 0x290,
+		.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 9),
+	}, {
+		.name = "ctl_1", .id = CTL_1,
+		.base = 0x16000, .len = 0x290,
+		.features = CTL_SM8550_MASK | BIT(DPU_CTL_SPLIT_DISPLAY),
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 10),
+	}, {
+		.name = "ctl_2", .id = CTL_2,
+		.base = 0x17000, .len = 0x290,
+		.features = CTL_SM8550_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 11),
+	}, {
+		.name = "ctl_3", .id = CTL_3,
+		.base = 0x18000, .len = 0x290,
+		.features = CTL_SM8550_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 12),
+	}, {
+		.name = "ctl_4", .id = CTL_4,
+		.base = 0x19000, .len = 0x290,
+		.features = CTL_SM8550_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 13),
+	}, {
+		.name = "ctl_5", .id = CTL_5,
+		.base = 0x1a000, .len = 0x290,
+		.features = CTL_SM8550_MASK,
+		.intr_start = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 23),
+	},
+};
+
+static const struct dpu_sspp_cfg sm8550_sspp[] = {
+	{
+		.name = "sspp_0", .id = SSPP_VIG0,
+		.base = 0x4000, .len = 0x344,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_3_2,
+		.xin_id = 0,
+		.type = SSPP_TYPE_VIG,
+	}, {
+		.name = "sspp_1", .id = SSPP_VIG1,
+		.base = 0x6000, .len = 0x344,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_3_2,
+		.xin_id = 4,
+		.type = SSPP_TYPE_VIG,
+	}, {
+		.name = "sspp_2", .id = SSPP_VIG2,
+		.base = 0x8000, .len = 0x344,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_3_2,
+		.xin_id = 8,
+		.type = SSPP_TYPE_VIG,
+	}, {
+		.name = "sspp_3", .id = SSPP_VIG3,
+		.base = 0xa000, .len = 0x344,
+		.features = VIG_SDM845_MASK,
+		.sblk = &dpu_vig_sblk_qseed3_3_2,
+		.xin_id = 12,
+		.type = SSPP_TYPE_VIG,
+	}, {
+		.name = "sspp_8", .id = SSPP_DMA0,
+		.base = 0x24000, .len = 0x344,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 1,
+		.type = SSPP_TYPE_DMA,
+	}, {
+		.name = "sspp_9", .id = SSPP_DMA1,
+		.base = 0x26000, .len = 0x344,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 5,
+		.type = SSPP_TYPE_DMA,
+	}, {
+		.name = "sspp_10", .id = SSPP_DMA2,
+		.base = 0x28000, .len = 0x344,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 9,
+		.type = SSPP_TYPE_DMA,
+	}, {
+		.name = "sspp_11", .id = SSPP_DMA3,
+		.base = 0x2a000, .len = 0x344,
+		.features = DMA_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 13,
+		.type = SSPP_TYPE_DMA,
+	}, {
+		.name = "sspp_12", .id = SSPP_DMA4,
+		.base = 0x2c000, .len = 0x344,
+		.features = DMA_CURSOR_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 14,
+		.type = SSPP_TYPE_DMA,
+	}, {
+		.name = "sspp_13", .id = SSPP_DMA5,
+		.base = 0x2e000, .len = 0x344,
+		.features = DMA_CURSOR_SDM845_MASK,
+		.sblk = &dpu_dma_sblk,
+		.xin_id = 15,
+		.type = SSPP_TYPE_DMA,
+	},
+};
+
+static const struct dpu_lm_cfg sm8550_lm[] = {
+	{
+		.name = "lm_0", .id = LM_0,
+		.base = 0x44000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_1,
+		.pingpong = PINGPONG_0,
+		.dspp = DSPP_0,
+	}, {
+		.name = "lm_1", .id = LM_1,
+		.base = 0x45000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_0,
+		.pingpong = PINGPONG_1,
+		.dspp = DSPP_1,
+	}, {
+		.name = "lm_2", .id = LM_2,
+		.base = 0x46000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_3,
+		.pingpong = PINGPONG_2,
+	}, {
+		.name = "lm_3", .id = LM_3,
+		.base = 0x47000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_2,
+		.pingpong = PINGPONG_3,
+	}, {
+		.name = "lm_4", .id = LM_4,
+		.base = 0x48000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_5,
+		.pingpong = PINGPONG_4,
+	}, {
+		.name = "lm_5", .id = LM_5,
+		.base = 0x49000, .len = 0x320,
+		.features = MIXER_SDM845_MASK,
+		.sblk = &sdm845_lm_sblk,
+		.lm_pair = LM_4,
+		.pingpong = PINGPONG_5,
+	},
+};
+
+static const struct dpu_dspp_cfg sm8550_dspp[] = {
+	{
+		.name = "dspp_0", .id = DSPP_0,
+		.base = 0x54000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_1", .id = DSPP_1,
+		.base = 0x56000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_2", .id = DSPP_2,
+		.base = 0x58000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	}, {
+		.name = "dspp_3", .id = DSPP_3,
+		.base = 0x5a000, .len = 0x1800,
+		.features = DSPP_SC7180_MASK,
+		.sblk = &sdm845_dspp_sblk,
+	},
+};
+static const struct dpu_pingpong_cfg sm8550_pp[] = {
+	{
+		.name = "pingpong_0", .id = PINGPONG_0,
+		.base = 0x69000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+	}, {
+		.name = "pingpong_1", .id = PINGPONG_1,
+		.base = 0x6a000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_0,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+	}, {
+		.name = "pingpong_2", .id = PINGPONG_2,
+		.base = 0x6b000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+	}, {
+		.name = "pingpong_3", .id = PINGPONG_3,
+		.base = 0x6c000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_1,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+	}, {
+		.name = "pingpong_4", .id = PINGPONG_4,
+		.base = 0x6d000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+	}, {
+		.name = "pingpong_5", .id = PINGPONG_5,
+		.base = 0x6e000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_2,
+		.intr_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+	}, {
+		.name = "pingpong_6", .id = PINGPONG_6,
+		.base = 0x66000, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_3,
+	}, {
+		.name = "pingpong_7", .id = PINGPONG_7,
+		.base = 0x66400, .len = 0,
+		.features = BIT(DPU_PINGPONG_DITHER),
+		.sblk = &sc7280_pp_sblk,
+		.merge_3d = MERGE_3D_3,
+	},
+};
+
+static const struct dpu_merge_3d_cfg sm8550_merge_3d[] = {
+	{
+		.name = "merge_3d_0", .id = MERGE_3D_0,
+		.base = 0x4e000, .len = 0x8,
+	}, {
+		.name = "merge_3d_1", .id = MERGE_3D_1,
+		.base = 0x4f000, .len = 0x8,
+	}, {
+		.name = "merge_3d_2", .id = MERGE_3D_2,
+		.base = 0x50000, .len = 0x8,
+	}, {
+		.name = "merge_3d_3", .id = MERGE_3D_3,
+		.base = 0x66700, .len = 0x8,
+	},
+};
+
+/*
+ * NOTE: Each display compression engine (DCE) contains dual hard
+ * slice DSC encoders so both share same base address but with
+ * its own different sub block address.
+ */
+static const struct dpu_dsc_cfg sm8550_dsc[] = {
+	{
+		.name = "dce_0_0", .id = DSC_0,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_0_1", .id = DSC_1,
+		.base = 0x80000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2),
+		.sblk = &dsc_sblk_1,
+	}, {
+		.name = "dce_1_0", .id = DSC_2,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_0,
+	}, {
+		.name = "dce_1_1", .id = DSC_3,
+		.base = 0x81000, .len = 0x4,
+		.features = BIT(DPU_DSC_HW_REV_1_2) | BIT(DPU_DSC_NATIVE_42x_EN),
+		.sblk = &dsc_sblk_1,
+	},
+};
+
+static const struct dpu_wb_cfg sm8550_wb[] = {
+	{
+		.name = "wb_2", .id = WB_2,
+		.base = 0x65000, .len = 0x2c8,
+		.features = WB_SM8250_MASK,
+		.format_list = wb2_formats_rgb,
+		.num_formats = ARRAY_SIZE(wb2_formats_rgb),
+		.xin_id = 6,
+		.vbif_idx = VBIF_RT,
+		.maxlinewidth = 4096,
+		.intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4),
+	},
+};
+
+static const struct dpu_intf_cfg sm8550_intf[] = {
+	{
+		.name = "intf_0", .id = INTF_0,
+		.base = 0x34000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 25),
+	}, {
+		.name = "intf_1", .id = INTF_1,
+		.base = 0x35000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_0,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 26),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 27),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF1_TEAR_INTR, 2),
+	}, {
+		.name = "intf_2", .id = INTF_2,
+		.base = 0x36000, .len = 0x300,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DSI,
+		.controller_id = MSM_DSI_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 28),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 29),
+		.intr_tear_rd_ptr = DPU_IRQ_IDX(MDP_INTF2_TEAR_INTR, 2),
+	}, {
+		.name = "intf_3", .id = INTF_3,
+		.base = 0x37000, .len = 0x280,
+		.features = INTF_SC7280_MASK,
+		.type = INTF_DP,
+		.controller_id = MSM_DP_CONTROLLER_1,
+		.prog_fetch_lines_worst_case = 24,
+		.intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 30),
+		.intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 31),
+	},
+};
+
+static const struct dpu_perf_cfg sm8550_perf_data = {
+	.max_bw_low = 13600000,
+	.max_bw_high = 18200000,
+	.min_core_ib = 2500000,
+	.min_llcc_ib = 0,
+	.min_dram_ib = 800000,
+	.min_prefill_lines = 35,
+	/* FIXME: lut tables */
+	.danger_lut_tbl = {0x3ffff, 0x3ffff, 0x0},
+	.safe_lut_tbl = {0xfe00, 0xfe00, 0xffff},
+	.qos_lut_tbl = {
+		{.nentry = ARRAY_SIZE(sc7180_qos_linear),
+		.entries = sc7180_qos_linear
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_macrotile),
+		.entries = sc7180_qos_macrotile
+		},
+		{.nentry = ARRAY_SIZE(sc7180_qos_nrt),
+		.entries = sc7180_qos_nrt
+		},
+		/* TODO: macrotile-qseed is different from macrotile */
+	},
+	.cdp_cfg = {
+		{.rd_enable = 1, .wr_enable = 1},
+		{.rd_enable = 1, .wr_enable = 0}
+	},
+	.clk_inefficiency_factor = 105,
+	.bw_inefficiency_factor = 120,
+};
+
+static const struct dpu_mdss_version sm8550_mdss_ver = {
+	.core_major_ver = 9,
+	.core_minor_ver = 0,
+};
+
+const struct dpu_mdss_cfg dpu_sm8550_cfg = {
+	.mdss_ver = &sm8550_mdss_ver,
+	.caps = &sm8550_dpu_caps,
+	.mdp = &sm8550_mdp,
+	.ctl_count = ARRAY_SIZE(sm8550_ctl),
+	.ctl = sm8550_ctl,
+	.sspp_count = ARRAY_SIZE(sm8550_sspp),
+	.sspp = sm8550_sspp,
+	.mixer_count = ARRAY_SIZE(sm8550_lm),
+	.mixer = sm8550_lm,
+	.dspp_count = ARRAY_SIZE(sm8550_dspp),
+	.dspp = sm8550_dspp,
+	.pingpong_count = ARRAY_SIZE(sm8550_pp),
+	.pingpong = sm8550_pp,
+	.dsc_count = ARRAY_SIZE(sm8550_dsc),
+	.dsc = sm8550_dsc,
+	.merge_3d_count = ARRAY_SIZE(sm8550_merge_3d),
+	.merge_3d = sm8550_merge_3d,
+	.wb_count = ARRAY_SIZE(sm8550_wb),
+	.wb = sm8550_wb,
+	.intf_count = ARRAY_SIZE(sm8550_intf),
+	.intf = sm8550_intf,
+	.vbif_count = ARRAY_SIZE(sm8550_vbif),
+	.vbif = sm8550_vbif,
+	.perf = &sm8550_perf_data,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_core_irq.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_core_irq.h
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __DPU_CORE_IRQ_H__
+#define __DPU_CORE_IRQ_H__
+
+#include "dpu_kms.h"
+#include "dpu_hw_interrupts.h"
+
+/**
+ * dpu_core_irq_preinstall - perform pre-installation of core IRQ handler
+ * @kms:		MSM KMS handle
+ * @return:		none
+ */
+void dpu_core_irq_preinstall(struct msm_kms *kms);
+
+/**
+ * dpu_core_irq_uninstall - uninstall core IRQ handler
+ * @kms:		MSM KMS handle
+ * @return:		none
+ */
+void dpu_core_irq_uninstall(struct msm_kms *kms);
+
+/**
+ * dpu_core_irq - core IRQ handler
+ * @kms:		MSM KMS handle
+ * @return:		interrupt handling status
+ */
+irqreturn_t dpu_core_irq(struct msm_kms *kms);
+
+/**
+ * dpu_core_irq_read - IRQ helper function for reading IRQ status
+ * @dpu_kms:		DPU handle
+ * @irq_idx:		irq index
+ * @return:		non-zero if irq detected; otherwise no irq detected
+ */
+u32 dpu_core_irq_read(
+		struct dpu_kms *dpu_kms,
+		unsigned int irq_idx);
+
+/**
+ * dpu_core_irq_register_callback - For registering callback function on IRQ
+ *                             interrupt
+ * @dpu_kms:		DPU handle
+ * @irq_idx:		irq index
+ * @irq_cb:		IRQ callback funcion.
+ * @irq_arg:		IRQ callback argument.
+ * @return:		0 for success registering callback, otherwise failure
+ *
+ * This function supports registration of multiple callbacks for each interrupt.
+ */
+int dpu_core_irq_register_callback(
+		struct dpu_kms *dpu_kms,
+		unsigned int irq_idx,
+		void (*irq_cb)(void *arg),
+		void *irq_arg);
+
+/**
+ * dpu_core_irq_unregister_callback - For unregistering callback function on IRQ
+ *                             interrupt
+ * @dpu_kms:		DPU handle
+ * @irq_idx:		irq index
+ * @return:		0 for success registering callback, otherwise failure
+ *
+ * This function supports registration of multiple callbacks for each interrupt.
+ */
+int dpu_core_irq_unregister_callback(
+		struct dpu_kms *dpu_kms,
+		unsigned int irq_idx);
+
+/**
+ * dpu_debugfs_core_irq_init - register core irq debugfs
+ * @dpu_kms: pointer to kms
+ * @parent: debugfs directory root
+ */
+void dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms,
+		struct dentry *parent);
+
+#endif /* __DPU_CORE_IRQ_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_core_perf.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_core_perf.c
@@ -0,0 +1,493 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+
+#include <linux/debugfs.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/pm_opp.h>
+#include <linux/sort.h>
+#include <linux/clk.h>
+#include <linux/bitmap.h>
+
+#include "dpu_kms.h"
+#include "dpu_trace.h"
+#include "dpu_crtc.h"
+#include "dpu_core_perf.h"
+
+/**
+ * enum dpu_perf_mode - performance tuning mode
+ * @DPU_PERF_MODE_NORMAL: performance controlled by user mode client
+ * @DPU_PERF_MODE_MINIMUM: performance bounded by minimum setting
+ * @DPU_PERF_MODE_FIXED: performance bounded by fixed setting
+ * @DPU_PERF_MODE_MAX: maximum value, used for error checking
+ */
+enum dpu_perf_mode {
+	DPU_PERF_MODE_NORMAL,
+	DPU_PERF_MODE_MINIMUM,
+	DPU_PERF_MODE_FIXED,
+	DPU_PERF_MODE_MAX
+};
+
+/**
+ * _dpu_core_perf_calc_bw() - to calculate BW per crtc
+ * @perf_cfg: performance configuration
+ * @crtc: pointer to a crtc
+ * Return: returns aggregated BW for all planes in crtc.
+ */
+static u64 _dpu_core_perf_calc_bw(const struct dpu_perf_cfg *perf_cfg,
+		struct drm_crtc *crtc)
+{
+	struct drm_plane *plane;
+	struct dpu_plane_state *pstate;
+	u64 crtc_plane_bw = 0;
+	u32 bw_factor;
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		pstate = to_dpu_plane_state(plane->state);
+		if (!pstate)
+			continue;
+
+		crtc_plane_bw += pstate->plane_fetch_bw;
+	}
+
+	bw_factor = perf_cfg->bw_inefficiency_factor;
+	if (bw_factor) {
+		crtc_plane_bw *= bw_factor;
+		do_div(crtc_plane_bw, 100);
+	}
+
+	return crtc_plane_bw;
+}
+
+/**
+ * _dpu_core_perf_calc_clk() - to calculate clock per crtc
+ * @perf_cfg: performance configuration
+ * @crtc: pointer to a crtc
+ * @state: pointer to a crtc state
+ * Return: returns max clk for all planes in crtc.
+ */
+static u64 _dpu_core_perf_calc_clk(const struct dpu_perf_cfg *perf_cfg,
+		struct drm_crtc *crtc, struct drm_crtc_state *state)
+{
+	struct drm_plane *plane;
+	struct dpu_plane_state *pstate;
+	struct drm_display_mode *mode;
+	u64 crtc_clk;
+	u32 clk_factor;
+
+	mode = &state->adjusted_mode;
+
+	crtc_clk = mode->vtotal * mode->hdisplay * drm_mode_vrefresh(mode);
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		pstate = to_dpu_plane_state(plane->state);
+		if (!pstate)
+			continue;
+
+		crtc_clk = max(pstate->plane_clk, crtc_clk);
+	}
+
+	clk_factor = perf_cfg->clk_inefficiency_factor;
+	if (clk_factor) {
+		crtc_clk *= clk_factor;
+		do_div(crtc_clk, 100);
+	}
+
+	return crtc_clk;
+}
+
+static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc)
+{
+	struct msm_drm_private *priv;
+	priv = crtc->dev->dev_private;
+	return to_dpu_kms(priv->kms);
+}
+
+static void _dpu_core_perf_calc_crtc(const struct dpu_core_perf *core_perf,
+				     struct drm_crtc *crtc,
+				     struct drm_crtc_state *state,
+				     struct dpu_core_perf_params *perf)
+{
+	const struct dpu_perf_cfg *perf_cfg = core_perf->perf_cfg;
+
+	if (!perf_cfg || !crtc || !state || !perf) {
+		DPU_ERROR("invalid parameters\n");
+		return;
+	}
+
+	memset(perf, 0, sizeof(struct dpu_core_perf_params));
+
+	if (core_perf->perf_tune.mode == DPU_PERF_MODE_MINIMUM) {
+		perf->bw_ctl = 0;
+		perf->max_per_pipe_ib = 0;
+		perf->core_clk_rate = 0;
+	} else if (core_perf->perf_tune.mode == DPU_PERF_MODE_FIXED) {
+		perf->bw_ctl = core_perf->fix_core_ab_vote;
+		perf->max_per_pipe_ib = core_perf->fix_core_ib_vote;
+		perf->core_clk_rate = core_perf->fix_core_clk_rate;
+	} else {
+		perf->bw_ctl = _dpu_core_perf_calc_bw(perf_cfg, crtc);
+		perf->max_per_pipe_ib = perf_cfg->min_dram_ib;
+		perf->core_clk_rate = _dpu_core_perf_calc_clk(perf_cfg, crtc, state);
+	}
+
+	DRM_DEBUG_ATOMIC(
+		"crtc=%d clk_rate=%llu core_ib=%llu core_ab=%llu\n",
+			crtc->base.id, perf->core_clk_rate,
+			perf->max_per_pipe_ib, perf->bw_ctl);
+}
+
+int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
+		struct drm_crtc_state *state)
+{
+	u32 bw, threshold;
+	u64 bw_sum_of_intfs = 0;
+	enum dpu_crtc_client_type curr_client_type;
+	struct dpu_crtc_state *dpu_cstate;
+	struct drm_crtc *tmp_crtc;
+	struct dpu_kms *kms;
+
+	if (!crtc || !state) {
+		DPU_ERROR("invalid crtc\n");
+		return -EINVAL;
+	}
+
+	kms = _dpu_crtc_get_kms(crtc);
+
+	/* we only need bandwidth check on real-time clients (interfaces) */
+	if (dpu_crtc_get_client_type(crtc) == NRT_CLIENT)
+		return 0;
+
+	dpu_cstate = to_dpu_crtc_state(state);
+
+	/* obtain new values */
+	_dpu_core_perf_calc_crtc(&kms->perf, crtc, state, &dpu_cstate->new_perf);
+
+	bw_sum_of_intfs = dpu_cstate->new_perf.bw_ctl;
+	curr_client_type = dpu_crtc_get_client_type(crtc);
+
+	drm_for_each_crtc(tmp_crtc, crtc->dev) {
+		if (tmp_crtc->enabled &&
+		    dpu_crtc_get_client_type(tmp_crtc) == curr_client_type &&
+		    tmp_crtc != crtc) {
+			struct dpu_crtc_state *tmp_cstate =
+				to_dpu_crtc_state(tmp_crtc->state);
+
+			DRM_DEBUG_ATOMIC("crtc:%d bw:%llu ctrl:%d\n",
+					 tmp_crtc->base.id, tmp_cstate->new_perf.bw_ctl,
+					 tmp_cstate->bw_control);
+
+			bw_sum_of_intfs += tmp_cstate->new_perf.bw_ctl;
+		}
+
+		/* convert bandwidth to kb */
+		bw = DIV_ROUND_UP_ULL(bw_sum_of_intfs, 1000);
+		DRM_DEBUG_ATOMIC("calculated bandwidth=%uk\n", bw);
+
+		threshold = kms->perf.perf_cfg->max_bw_high;
+
+		DRM_DEBUG_ATOMIC("final threshold bw limit = %d\n", threshold);
+
+		if (!threshold) {
+			DPU_ERROR("no bandwidth limits specified\n");
+			return -E2BIG;
+		} else if (bw > threshold) {
+			DPU_ERROR("exceeds bandwidth: %ukb > %ukb\n", bw,
+					threshold);
+			return -E2BIG;
+		}
+	}
+
+	return 0;
+}
+
+static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
+		struct drm_crtc *crtc)
+{
+	struct dpu_core_perf_params perf = { 0 };
+	enum dpu_crtc_client_type curr_client_type
+					= dpu_crtc_get_client_type(crtc);
+	struct drm_crtc *tmp_crtc;
+	struct dpu_crtc_state *dpu_cstate;
+	int i, ret = 0;
+	u64 avg_bw;
+
+	if (!kms->num_paths)
+		return 0;
+
+	drm_for_each_crtc(tmp_crtc, crtc->dev) {
+		if (tmp_crtc->enabled &&
+			curr_client_type ==
+				dpu_crtc_get_client_type(tmp_crtc)) {
+			dpu_cstate = to_dpu_crtc_state(tmp_crtc->state);
+
+			perf.max_per_pipe_ib = max(perf.max_per_pipe_ib,
+					dpu_cstate->new_perf.max_per_pipe_ib);
+
+			perf.bw_ctl += dpu_cstate->new_perf.bw_ctl;
+
+			DRM_DEBUG_ATOMIC("crtc=%d bw=%llu paths:%d\n",
+				  tmp_crtc->base.id,
+				  dpu_cstate->new_perf.bw_ctl, kms->num_paths);
+		}
+	}
+
+	avg_bw = perf.bw_ctl;
+	do_div(avg_bw, (kms->num_paths * 1000)); /*Bps_to_icc*/
+
+	for (i = 0; i < kms->num_paths; i++)
+		icc_set_bw(kms->path[i], avg_bw, perf.max_per_pipe_ib);
+
+	return ret;
+}
+
+/**
+ * dpu_core_perf_crtc_release_bw() - request zero bandwidth
+ * @crtc: pointer to a crtc
+ *
+ * Function checks a state variable for the crtc, if all pending commit
+ * requests are done, meaning no more bandwidth is needed, release
+ * bandwidth request.
+ */
+void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc)
+{
+	struct dpu_crtc *dpu_crtc;
+	struct dpu_kms *kms;
+
+	if (!crtc) {
+		DPU_ERROR("invalid crtc\n");
+		return;
+	}
+
+	kms = _dpu_crtc_get_kms(crtc);
+	dpu_crtc = to_dpu_crtc(crtc);
+
+	if (atomic_dec_return(&kms->bandwidth_ref) > 0)
+		return;
+
+	/* Release the bandwidth */
+	if (kms->perf.enable_bw_release) {
+		trace_dpu_cmd_release_bw(crtc->base.id);
+		DRM_DEBUG_ATOMIC("Release BW crtc=%d\n", crtc->base.id);
+		dpu_crtc->cur_perf.bw_ctl = 0;
+		_dpu_core_perf_crtc_update_bus(kms, crtc);
+	}
+}
+
+static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms)
+{
+	u64 clk_rate;
+	struct drm_crtc *crtc;
+	struct dpu_crtc_state *dpu_cstate;
+
+	if (kms->perf.perf_tune.mode == DPU_PERF_MODE_FIXED)
+		return kms->perf.fix_core_clk_rate;
+
+	if (kms->perf.perf_tune.mode == DPU_PERF_MODE_MINIMUM)
+		return kms->perf.max_core_clk_rate;
+
+	clk_rate = 0;
+	drm_for_each_crtc(crtc, kms->dev) {
+		if (crtc->enabled) {
+			dpu_cstate = to_dpu_crtc_state(crtc->state);
+			clk_rate = max(dpu_cstate->new_perf.core_clk_rate,
+							clk_rate);
+		}
+	}
+
+	return clk_rate;
+}
+
+int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
+			      int params_changed)
+{
+	struct dpu_core_perf_params *new, *old;
+	bool update_bus = false, update_clk = false;
+	u64 clk_rate = 0;
+	struct dpu_crtc *dpu_crtc;
+	struct dpu_crtc_state *dpu_cstate;
+	struct dpu_kms *kms;
+	int ret;
+
+	if (!crtc) {
+		DPU_ERROR("invalid crtc\n");
+		return -EINVAL;
+	}
+
+	kms = _dpu_crtc_get_kms(crtc);
+
+	dpu_crtc = to_dpu_crtc(crtc);
+	dpu_cstate = to_dpu_crtc_state(crtc->state);
+
+	DRM_DEBUG_ATOMIC("crtc:%d enabled:%d core_clk:%llu\n",
+			crtc->base.id, crtc->enabled, kms->perf.core_clk_rate);
+
+	old = &dpu_crtc->cur_perf;
+	new = &dpu_cstate->new_perf;
+
+	if (crtc->enabled) {
+		/*
+		 * cases for bus bandwidth update.
+		 * 1. new bandwidth vote - "ab or ib vote" is higher
+		 *    than current vote for update request.
+		 * 2. new bandwidth vote - "ab or ib vote" is lower
+		 *    than current vote at end of commit or stop.
+		 */
+		if ((params_changed && ((new->bw_ctl > old->bw_ctl) ||
+			(new->max_per_pipe_ib > old->max_per_pipe_ib)))	||
+			(!params_changed && ((new->bw_ctl < old->bw_ctl) ||
+			(new->max_per_pipe_ib < old->max_per_pipe_ib)))) {
+			DRM_DEBUG_ATOMIC("crtc=%d p=%d new_bw=%llu,old_bw=%llu\n",
+				crtc->base.id, params_changed,
+				new->bw_ctl, old->bw_ctl);
+			old->bw_ctl = new->bw_ctl;
+			old->max_per_pipe_ib = new->max_per_pipe_ib;
+			update_bus = true;
+		}
+
+		if ((params_changed && new->core_clk_rate > old->core_clk_rate) ||
+		    (!params_changed && new->core_clk_rate < old->core_clk_rate)) {
+			old->core_clk_rate = new->core_clk_rate;
+			update_clk = true;
+		}
+	} else {
+		DRM_DEBUG_ATOMIC("crtc=%d disable\n", crtc->base.id);
+		memset(old, 0, sizeof(*old));
+		update_bus = true;
+		update_clk = true;
+	}
+
+	trace_dpu_perf_crtc_update(crtc->base.id, new->bw_ctl,
+		new->core_clk_rate, !crtc->enabled, update_bus, update_clk);
+
+	if (update_bus) {
+		ret = _dpu_core_perf_crtc_update_bus(kms, crtc);
+		if (ret) {
+			DPU_ERROR("crtc-%d: failed to update bus bw vote\n",
+				  crtc->base.id);
+			return ret;
+		}
+	}
+
+	/*
+	 * Update the clock after bandwidth vote to ensure
+	 * bandwidth is available before clock rate is increased.
+	 */
+	if (update_clk) {
+		clk_rate = _dpu_core_perf_get_core_clk_rate(kms);
+
+		DRM_DEBUG_ATOMIC("clk:%llu\n", clk_rate);
+
+		trace_dpu_core_perf_update_clk(kms->dev, !crtc->enabled, clk_rate);
+
+		clk_rate = min(clk_rate, kms->perf.max_core_clk_rate);
+		ret = dev_pm_opp_set_rate(&kms->pdev->dev, clk_rate);
+		if (ret) {
+			DPU_ERROR("failed to set core clock rate %llu\n", clk_rate);
+			return ret;
+		}
+
+		kms->perf.core_clk_rate = clk_rate;
+		DRM_DEBUG_ATOMIC("update clk rate = %lld HZ\n", clk_rate);
+	}
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+static ssize_t _dpu_core_perf_mode_write(struct file *file,
+		    const char __user *user_buf, size_t count, loff_t *ppos)
+{
+	struct dpu_core_perf *perf = file->private_data;
+	u32 perf_mode = 0;
+	int ret;
+
+	ret = kstrtouint_from_user(user_buf, count, 0, &perf_mode);
+	if (ret)
+		return ret;
+
+	if (perf_mode >= DPU_PERF_MODE_MAX)
+		return -EINVAL;
+
+	if (perf_mode == DPU_PERF_MODE_FIXED) {
+		DRM_INFO("fix performance mode\n");
+	} else if (perf_mode == DPU_PERF_MODE_MINIMUM) {
+		/* run the driver with max clk and BW vote */
+		DRM_INFO("minimum performance mode\n");
+	} else if (perf_mode == DPU_PERF_MODE_NORMAL) {
+		/* reset the perf tune params to 0 */
+		DRM_INFO("normal performance mode\n");
+	}
+	perf->perf_tune.mode = perf_mode;
+
+	return count;
+}
+
+static ssize_t _dpu_core_perf_mode_read(struct file *file,
+			char __user *buff, size_t count, loff_t *ppos)
+{
+	struct dpu_core_perf *perf = file->private_data;
+	int len;
+	char buf[128];
+
+	len = scnprintf(buf, sizeof(buf),
+			"mode %d\n",
+			perf->perf_tune.mode);
+
+	return simple_read_from_buffer(buff, count, ppos, buf, len);
+}
+
+static const struct file_operations dpu_core_perf_mode_fops = {
+	.open = simple_open,
+	.read = _dpu_core_perf_mode_read,
+	.write = _dpu_core_perf_mode_write,
+};
+
+int dpu_core_perf_debugfs_init(struct dpu_kms *dpu_kms, struct dentry *parent)
+{
+	struct dpu_core_perf *perf = &dpu_kms->perf;
+	struct dentry *entry;
+
+	entry = debugfs_create_dir("core_perf", parent);
+
+	debugfs_create_u64("max_core_clk_rate", 0600, entry,
+			&perf->max_core_clk_rate);
+	debugfs_create_u64("core_clk_rate", 0600, entry,
+			&perf->core_clk_rate);
+	debugfs_create_u32("enable_bw_release", 0600, entry,
+			(u32 *)&perf->enable_bw_release);
+	debugfs_create_u32("threshold_low", 0400, entry,
+			(u32 *)&perf->perf_cfg->max_bw_low);
+	debugfs_create_u32("threshold_high", 0400, entry,
+			(u32 *)&perf->perf_cfg->max_bw_high);
+	debugfs_create_u32("min_core_ib", 0400, entry,
+			(u32 *)&perf->perf_cfg->min_core_ib);
+	debugfs_create_u32("min_llcc_ib", 0400, entry,
+			(u32 *)&perf->perf_cfg->min_llcc_ib);
+	debugfs_create_u32("min_dram_ib", 0400, entry,
+			(u32 *)&perf->perf_cfg->min_dram_ib);
+	debugfs_create_file("perf_mode", 0600, entry,
+			(u32 *)perf, &dpu_core_perf_mode_fops);
+	debugfs_create_u64("fix_core_clk_rate", 0600, entry,
+			&perf->fix_core_clk_rate);
+	debugfs_create_u64("fix_core_ib_vote", 0600, entry,
+			&perf->fix_core_ib_vote);
+	debugfs_create_u64("fix_core_ab_vote", 0600, entry,
+			&perf->fix_core_ab_vote);
+
+	return 0;
+}
+#endif
+
+int dpu_core_perf_init(struct dpu_core_perf *perf,
+		const struct dpu_perf_cfg *perf_cfg,
+		unsigned long max_core_clk_rate)
+{
+	perf->perf_cfg = perf_cfg;
+	perf->max_core_clk_rate = max_core_clk_rate;
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_core_perf.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_core_perf.h
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_CORE_PERF_H_
+#define _DPU_CORE_PERF_H_
+
+#include <linux/types.h>
+#include <linux/dcache.h>
+#include <linux/mutex.h>
+#include <drm/drm_crtc.h>
+
+#include "dpu_hw_catalog.h"
+
+/**
+ * struct dpu_core_perf_params - definition of performance parameters
+ * @max_per_pipe_ib: maximum instantaneous bandwidth request
+ * @bw_ctl: arbitrated bandwidth request
+ * @core_clk_rate: core clock rate request
+ */
+struct dpu_core_perf_params {
+	u64 max_per_pipe_ib;
+	u64 bw_ctl;
+	u64 core_clk_rate;
+};
+
+/**
+ * struct dpu_core_perf_tune - definition of performance tuning control
+ * @mode: performance mode
+ */
+struct dpu_core_perf_tune {
+	u32 mode;
+};
+
+/**
+ * struct dpu_core_perf - definition of core performance context
+ * @perf_cfg: Platform-specific performance configuration
+ * @core_clk_rate: current core clock rate
+ * @max_core_clk_rate: maximum allowable core clock rate
+ * @perf_tune: debug control for performance tuning
+ * @enable_bw_release: debug control for bandwidth release
+ * @fix_core_clk_rate: fixed core clock request in Hz used in mode 2
+ * @fix_core_ib_vote: fixed core ib vote in bps used in mode 2
+ * @fix_core_ab_vote: fixed core ab vote in bps used in mode 2
+ */
+struct dpu_core_perf {
+	const struct dpu_perf_cfg *perf_cfg;
+	u64 core_clk_rate;
+	u64 max_core_clk_rate;
+	struct dpu_core_perf_tune perf_tune;
+	u32 enable_bw_release;
+	u64 fix_core_clk_rate;
+	u64 fix_core_ib_vote;
+	u64 fix_core_ab_vote;
+};
+
+/**
+ * dpu_core_perf_crtc_check - validate performance of the given crtc state
+ * @crtc: Pointer to crtc
+ * @state: Pointer to new crtc state
+ * return: zero if success, or error code otherwise
+ */
+int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
+		struct drm_crtc_state *state);
+
+/**
+ * dpu_core_perf_crtc_update - update performance of the given crtc
+ * @crtc: Pointer to crtc
+ * @params_changed: true if crtc parameters are modified
+ * return: zero if success, or error code otherwise
+ */
+int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
+			      int params_changed);
+
+/**
+ * dpu_core_perf_crtc_release_bw - release bandwidth of the given crtc
+ * @crtc: Pointer to crtc
+ */
+void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc);
+
+/**
+ * dpu_core_perf_init - initialize the given core performance context
+ * @perf: Pointer to core performance context
+ * @perf_cfg: Pointer to platform performance configuration
+ * @max_core_clk_rate: Maximum core clock rate
+ */
+int dpu_core_perf_init(struct dpu_core_perf *perf,
+		const struct dpu_perf_cfg *perf_cfg,
+		unsigned long max_core_clk_rate);
+
+struct dpu_kms;
+
+/**
+ * dpu_core_perf_debugfs_init - initialize debugfs for core performance context
+ * @dpu_kms: Pointer to the dpu_kms struct
+ * @debugfs_parent: Pointer to parent debugfs
+ */
+int dpu_core_perf_debugfs_init(struct dpu_kms *dpu_kms, struct dentry *parent);
+
+#endif /* _DPU_CORE_PERF_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_crtc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_crtc.c
@@ -0,0 +1,1498 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+#include <linux/sort.h>
+#include <linux/debugfs.h>
+#include <linux/ktime.h>
+#include <linux/bits.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_blend.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_flip_work.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_mode.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_rect.h>
+#include <drm/drm_vblank.h>
+#include <drm/drm_self_refresh_helper.h>
+
+#include "dpu_kms.h"
+#include "dpu_hw_lm.h"
+#include "dpu_hw_ctl.h"
+#include "dpu_hw_dspp.h"
+#include "dpu_crtc.h"
+#include "dpu_plane.h"
+#include "dpu_encoder.h"
+#include "dpu_vbif.h"
+#include "dpu_core_perf.h"
+#include "dpu_trace.h"
+
+/* layer mixer index on dpu_crtc */
+#define LEFT_MIXER 0
+#define RIGHT_MIXER 1
+
+/* timeout in ms waiting for frame done */
+#define DPU_CRTC_FRAME_DONE_TIMEOUT_MS	60
+
+#define	CONVERT_S3_15(val) \
+	(((((u64)val) & ~BIT_ULL(63)) >> 17) & GENMASK_ULL(17, 0))
+
+static struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc)
+{
+	struct msm_drm_private *priv = crtc->dev->dev_private;
+
+	return to_dpu_kms(priv->kms);
+}
+
+static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_encoder *encoder;
+
+	drm_for_each_encoder(encoder, dev)
+		if (encoder->crtc == crtc)
+			return encoder;
+
+	return NULL;
+}
+
+static enum dpu_crtc_crc_source dpu_crtc_parse_crc_source(const char *src_name)
+{
+	if (!src_name ||
+	    !strcmp(src_name, "none"))
+		return DPU_CRTC_CRC_SOURCE_NONE;
+	if (!strcmp(src_name, "auto") ||
+	    !strcmp(src_name, "lm"))
+		return DPU_CRTC_CRC_SOURCE_LAYER_MIXER;
+	if (!strcmp(src_name, "encoder"))
+		return DPU_CRTC_CRC_SOURCE_ENCODER;
+
+	return DPU_CRTC_CRC_SOURCE_INVALID;
+}
+
+static int dpu_crtc_verify_crc_source(struct drm_crtc *crtc,
+		const char *src_name, size_t *values_cnt)
+{
+	enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name);
+	struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state);
+
+	if (source < 0) {
+		DRM_DEBUG_DRIVER("Invalid source %s for CRTC%d\n", src_name, crtc->index);
+		return -EINVAL;
+	}
+
+	if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER) {
+		*values_cnt = crtc_state->num_mixers;
+	} else if (source == DPU_CRTC_CRC_SOURCE_ENCODER) {
+		struct drm_encoder *drm_enc;
+
+		*values_cnt = 0;
+
+		drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask)
+			*values_cnt += dpu_encoder_get_crc_values_cnt(drm_enc);
+	}
+
+	return 0;
+}
+
+static void dpu_crtc_setup_lm_misr(struct dpu_crtc_state *crtc_state)
+{
+	struct dpu_crtc_mixer *m;
+	int i;
+
+	for (i = 0; i < crtc_state->num_mixers; ++i) {
+		m = &crtc_state->mixers[i];
+
+		if (!m->hw_lm || !m->hw_lm->ops.setup_misr)
+			continue;
+
+		/* Calculate MISR over 1 frame */
+		m->hw_lm->ops.setup_misr(m->hw_lm);
+	}
+}
+
+static void dpu_crtc_setup_encoder_misr(struct drm_crtc *crtc)
+{
+	struct drm_encoder *drm_enc;
+
+	drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask)
+		dpu_encoder_setup_misr(drm_enc);
+}
+
+static int dpu_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
+{
+	enum dpu_crtc_crc_source source = dpu_crtc_parse_crc_source(src_name);
+	enum dpu_crtc_crc_source current_source;
+	struct dpu_crtc_state *crtc_state;
+	struct drm_device *drm_dev = crtc->dev;
+
+	bool was_enabled;
+	bool enable = false;
+	int ret = 0;
+
+	if (source < 0) {
+		DRM_DEBUG_DRIVER("Invalid CRC source %s for CRTC%d\n", src_name, crtc->index);
+		return -EINVAL;
+	}
+
+	ret = drm_modeset_lock(&crtc->mutex, NULL);
+
+	if (ret)
+		return ret;
+
+	enable = (source != DPU_CRTC_CRC_SOURCE_NONE);
+	crtc_state = to_dpu_crtc_state(crtc->state);
+
+	spin_lock_irq(&drm_dev->event_lock);
+	current_source = crtc_state->crc_source;
+	spin_unlock_irq(&drm_dev->event_lock);
+
+	was_enabled = (current_source != DPU_CRTC_CRC_SOURCE_NONE);
+
+	if (!was_enabled && enable) {
+		ret = drm_crtc_vblank_get(crtc);
+
+		if (ret)
+			goto cleanup;
+
+	} else if (was_enabled && !enable) {
+		drm_crtc_vblank_put(crtc);
+	}
+
+	spin_lock_irq(&drm_dev->event_lock);
+	crtc_state->crc_source = source;
+	spin_unlock_irq(&drm_dev->event_lock);
+
+	crtc_state->crc_frame_skip_count = 0;
+
+	if (source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER)
+		dpu_crtc_setup_lm_misr(crtc_state);
+	else if (source == DPU_CRTC_CRC_SOURCE_ENCODER)
+		dpu_crtc_setup_encoder_misr(crtc);
+	else
+		ret = -EINVAL;
+
+cleanup:
+	drm_modeset_unlock(&crtc->mutex);
+
+	return ret;
+}
+
+static u32 dpu_crtc_get_vblank_counter(struct drm_crtc *crtc)
+{
+	struct drm_encoder *encoder = get_encoder_from_crtc(crtc);
+	if (!encoder) {
+		DRM_ERROR("no encoder found for crtc %d\n", crtc->index);
+		return 0;
+	}
+
+	return dpu_encoder_get_vsync_count(encoder);
+}
+
+static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc,
+		struct dpu_crtc_state *crtc_state)
+{
+	struct dpu_crtc_mixer *m;
+	u32 crcs[CRTC_DUAL_MIXERS];
+
+	int rc = 0;
+	int i;
+
+	BUILD_BUG_ON(ARRAY_SIZE(crcs) != ARRAY_SIZE(crtc_state->mixers));
+
+	for (i = 0; i < crtc_state->num_mixers; ++i) {
+
+		m = &crtc_state->mixers[i];
+
+		if (!m->hw_lm || !m->hw_lm->ops.collect_misr)
+			continue;
+
+		rc = m->hw_lm->ops.collect_misr(m->hw_lm, &crcs[i]);
+
+		if (rc) {
+			if (rc != -ENODATA)
+				DRM_DEBUG_DRIVER("MISR read failed\n");
+			return rc;
+		}
+	}
+
+	return drm_crtc_add_crc_entry(crtc, true,
+			drm_crtc_accurate_vblank_count(crtc), crcs);
+}
+
+static int dpu_crtc_get_encoder_crc(struct drm_crtc *crtc)
+{
+	struct drm_encoder *drm_enc;
+	int rc, pos = 0;
+	u32 crcs[INTF_MAX];
+
+	drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc->state->encoder_mask) {
+		rc = dpu_encoder_get_crc(drm_enc, crcs, pos);
+		if (rc < 0) {
+			if (rc != -ENODATA)
+				DRM_DEBUG_DRIVER("MISR read failed\n");
+
+			return rc;
+		}
+
+		pos += rc;
+	}
+
+	return drm_crtc_add_crc_entry(crtc, true,
+			drm_crtc_accurate_vblank_count(crtc), crcs);
+}
+
+static int dpu_crtc_get_crc(struct drm_crtc *crtc)
+{
+	struct dpu_crtc_state *crtc_state = to_dpu_crtc_state(crtc->state);
+
+	/* Skip first 2 frames in case of "uncooked" CRCs */
+	if (crtc_state->crc_frame_skip_count < 2) {
+		crtc_state->crc_frame_skip_count++;
+		return 0;
+	}
+
+	if (crtc_state->crc_source == DPU_CRTC_CRC_SOURCE_LAYER_MIXER)
+		return dpu_crtc_get_lm_crc(crtc, crtc_state);
+	else if (crtc_state->crc_source == DPU_CRTC_CRC_SOURCE_ENCODER)
+		return dpu_crtc_get_encoder_crc(crtc);
+
+	return -EINVAL;
+}
+
+static bool dpu_crtc_get_scanout_position(struct drm_crtc *crtc,
+					   bool in_vblank_irq,
+					   int *vpos, int *hpos,
+					   ktime_t *stime, ktime_t *etime,
+					   const struct drm_display_mode *mode)
+{
+	unsigned int pipe = crtc->index;
+	struct drm_encoder *encoder;
+	int line, vsw, vbp, vactive_start, vactive_end, vfp_end;
+
+	encoder = get_encoder_from_crtc(crtc);
+	if (!encoder) {
+		DRM_ERROR("no encoder found for crtc %d\n", pipe);
+		return false;
+	}
+
+	vsw = mode->crtc_vsync_end - mode->crtc_vsync_start;
+	vbp = mode->crtc_vtotal - mode->crtc_vsync_end;
+
+	/*
+	 * the line counter is 1 at the start of the VSYNC pulse and VTOTAL at
+	 * the end of VFP. Translate the porch values relative to the line
+	 * counter positions.
+	 */
+
+	vactive_start = vsw + vbp + 1;
+	vactive_end = vactive_start + mode->crtc_vdisplay;
+
+	/* last scan line before VSYNC */
+	vfp_end = mode->crtc_vtotal;
+
+	if (stime)
+		*stime = ktime_get();
+
+	line = dpu_encoder_get_linecount(encoder);
+
+	if (line < vactive_start)
+		line -= vactive_start;
+	else if (line > vactive_end)
+		line = line - vfp_end - vactive_start;
+	else
+		line -= vactive_start;
+
+	*vpos = line;
+	*hpos = 0;
+
+	if (etime)
+		*etime = ktime_get();
+
+	return true;
+}
+
+static void _dpu_crtc_setup_blend_cfg(struct dpu_crtc_mixer *mixer,
+		struct dpu_plane_state *pstate, struct dpu_format *format)
+{
+	struct dpu_hw_mixer *lm = mixer->hw_lm;
+	uint32_t blend_op;
+	uint32_t fg_alpha, bg_alpha;
+
+	fg_alpha = pstate->base.alpha >> 8;
+	bg_alpha = 0xff - fg_alpha;
+
+	/* default to opaque blending */
+	if (pstate->base.pixel_blend_mode == DRM_MODE_BLEND_PIXEL_NONE ||
+	    !format->alpha_enable) {
+		blend_op = DPU_BLEND_FG_ALPHA_FG_CONST |
+			DPU_BLEND_BG_ALPHA_BG_CONST;
+	} else if (pstate->base.pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) {
+		blend_op = DPU_BLEND_FG_ALPHA_FG_CONST |
+			DPU_BLEND_BG_ALPHA_FG_PIXEL;
+		if (fg_alpha != 0xff) {
+			bg_alpha = fg_alpha;
+			blend_op |= DPU_BLEND_BG_MOD_ALPHA |
+				    DPU_BLEND_BG_INV_MOD_ALPHA;
+		} else {
+			blend_op |= DPU_BLEND_BG_INV_ALPHA;
+		}
+	} else {
+		/* coverage blending */
+		blend_op = DPU_BLEND_FG_ALPHA_FG_PIXEL |
+			DPU_BLEND_BG_ALPHA_FG_PIXEL;
+		if (fg_alpha != 0xff) {
+			bg_alpha = fg_alpha;
+			blend_op |= DPU_BLEND_FG_MOD_ALPHA |
+				    DPU_BLEND_FG_INV_MOD_ALPHA |
+				    DPU_BLEND_BG_MOD_ALPHA |
+				    DPU_BLEND_BG_INV_MOD_ALPHA;
+		} else {
+			blend_op |= DPU_BLEND_BG_INV_ALPHA;
+		}
+	}
+
+	lm->ops.setup_blend_config(lm, pstate->stage,
+				fg_alpha, bg_alpha, blend_op);
+
+	DRM_DEBUG_ATOMIC("format:%p4cc, alpha_en:%u blend_op:0x%x\n",
+		  &format->base.pixel_format, format->alpha_enable, blend_op);
+}
+
+static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
+{
+	struct dpu_crtc_state *crtc_state;
+	int lm_idx, lm_horiz_position;
+
+	crtc_state = to_dpu_crtc_state(crtc->state);
+
+	lm_horiz_position = 0;
+	for (lm_idx = 0; lm_idx < crtc_state->num_mixers; lm_idx++) {
+		const struct drm_rect *lm_roi = &crtc_state->lm_bounds[lm_idx];
+		struct dpu_hw_mixer *hw_lm = crtc_state->mixers[lm_idx].hw_lm;
+		struct dpu_hw_mixer_cfg cfg;
+
+		if (!lm_roi || !drm_rect_visible(lm_roi))
+			continue;
+
+		cfg.out_width = drm_rect_width(lm_roi);
+		cfg.out_height = drm_rect_height(lm_roi);
+		cfg.right_mixer = lm_horiz_position++;
+		cfg.flags = 0;
+		hw_lm->ops.setup_mixer_out(hw_lm, &cfg);
+	}
+}
+
+static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
+				       struct drm_plane *plane,
+				       struct dpu_crtc_mixer *mixer,
+				       u32 num_mixers,
+				       enum dpu_stage stage,
+				       struct dpu_format *format,
+				       uint64_t modifier,
+				       struct dpu_sw_pipe *pipe,
+				       unsigned int stage_idx,
+				       struct dpu_hw_stage_cfg *stage_cfg
+				      )
+{
+	uint32_t lm_idx;
+	enum dpu_sspp sspp_idx;
+	struct drm_plane_state *state;
+
+	sspp_idx = pipe->sspp->idx;
+
+	state = plane->state;
+
+	trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
+				   state, to_dpu_plane_state(state), stage_idx,
+				   format->base.pixel_format,
+				   modifier);
+
+	DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d multirect_idx %d\n",
+			 crtc->base.id,
+			 stage,
+			 plane->base.id,
+			 sspp_idx - SSPP_NONE,
+			 state->fb ? state->fb->base.id : -1,
+			 pipe->multirect_index);
+
+	stage_cfg->stage[stage][stage_idx] = sspp_idx;
+	stage_cfg->multirect_index[stage][stage_idx] = pipe->multirect_index;
+
+	/* blend config update */
+	for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
+		mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, sspp_idx);
+}
+
+static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
+	struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer,
+	struct dpu_hw_stage_cfg *stage_cfg)
+{
+	struct drm_plane *plane;
+	struct drm_framebuffer *fb;
+	struct drm_plane_state *state;
+	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
+	struct dpu_plane_state *pstate = NULL;
+	struct dpu_format *format;
+	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
+
+	uint32_t lm_idx;
+	bool bg_alpha_enable = false;
+	DECLARE_BITMAP(fetch_active, SSPP_MAX);
+
+	memset(fetch_active, 0, sizeof(fetch_active));
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		state = plane->state;
+		if (!state)
+			continue;
+
+		if (!state->visible)
+			continue;
+
+		pstate = to_dpu_plane_state(state);
+		fb = state->fb;
+
+		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
+
+		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
+			bg_alpha_enable = true;
+
+		set_bit(pstate->pipe.sspp->idx, fetch_active);
+		_dpu_crtc_blend_setup_pipe(crtc, plane,
+					   mixer, cstate->num_mixers,
+					   pstate->stage,
+					   format, fb ? fb->modifier : 0,
+					   &pstate->pipe, 0, stage_cfg);
+
+		if (pstate->r_pipe.sspp) {
+			set_bit(pstate->r_pipe.sspp->idx, fetch_active);
+			_dpu_crtc_blend_setup_pipe(crtc, plane,
+						   mixer, cstate->num_mixers,
+						   pstate->stage,
+						   format, fb ? fb->modifier : 0,
+						   &pstate->r_pipe, 1, stage_cfg);
+		}
+
+		/* blend config update */
+		for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
+			_dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
+
+			if (bg_alpha_enable && !format->alpha_enable)
+				mixer[lm_idx].mixer_op_mode = 0;
+			else
+				mixer[lm_idx].mixer_op_mode |=
+						1 << pstate->stage;
+		}
+	}
+
+	if (ctl->ops.set_active_pipes)
+		ctl->ops.set_active_pipes(ctl, fetch_active);
+
+	_dpu_crtc_program_lm_output_roi(crtc);
+}
+
+/**
+ * _dpu_crtc_blend_setup - configure crtc mixers
+ * @crtc: Pointer to drm crtc structure
+ */
+static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
+{
+	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
+	struct dpu_crtc_mixer *mixer = cstate->mixers;
+	struct dpu_hw_ctl *ctl;
+	struct dpu_hw_mixer *lm;
+	struct dpu_hw_stage_cfg stage_cfg;
+	int i;
+
+	DRM_DEBUG_ATOMIC("%s\n", dpu_crtc->name);
+
+	for (i = 0; i < cstate->num_mixers; i++) {
+		mixer[i].mixer_op_mode = 0;
+		if (mixer[i].lm_ctl->ops.clear_all_blendstages)
+			mixer[i].lm_ctl->ops.clear_all_blendstages(
+					mixer[i].lm_ctl);
+	}
+
+	/* initialize stage cfg */
+	memset(&stage_cfg, 0, sizeof(struct dpu_hw_stage_cfg));
+
+	_dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer, &stage_cfg);
+
+	for (i = 0; i < cstate->num_mixers; i++) {
+		ctl = mixer[i].lm_ctl;
+		lm = mixer[i].hw_lm;
+
+		lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode);
+
+		/* stage config flush mask */
+		ctl->ops.update_pending_flush_mixer(ctl,
+			mixer[i].hw_lm->idx);
+
+		DRM_DEBUG_ATOMIC("lm %d, op_mode 0x%X, ctl %d\n",
+			mixer[i].hw_lm->idx - LM_0,
+			mixer[i].mixer_op_mode,
+			ctl->idx - CTL_0);
+
+		ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
+			&stage_cfg);
+	}
+}
+
+/**
+ *  _dpu_crtc_complete_flip - signal pending page_flip events
+ * Any pending vblank events are added to the vblank_event_list
+ * so that the next vblank interrupt shall signal them.
+ * However PAGE_FLIP events are not handled through the vblank_event_list.
+ * This API signals any pending PAGE_FLIP events requested through
+ * DRM_IOCTL_MODE_PAGE_FLIP and are cached in the dpu_crtc->event.
+ * @crtc: Pointer to drm crtc structure
+ */
+static void _dpu_crtc_complete_flip(struct drm_crtc *crtc)
+{
+	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	if (dpu_crtc->event) {
+		DRM_DEBUG_VBL("%s: send event: %pK\n", dpu_crtc->name,
+			      dpu_crtc->event);
+		trace_dpu_crtc_complete_flip(DRMID(crtc));
+		drm_crtc_send_vblank_event(crtc, dpu_crtc->event);
+		dpu_crtc->event = NULL;
+	}
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc)
+{
+	struct drm_encoder *encoder;
+
+	/*
+	 * TODO: This function is called from dpu debugfs and as part of atomic
+	 * check. When called from debugfs, the crtc->mutex must be held to
+	 * read crtc->state. However reading crtc->state from atomic check isn't
+	 * allowed (unless you have a good reason, a big comment, and a deep
+	 * understanding of how the atomic/modeset locks work (<- and this is
+	 * probably not possible)). So we'll keep the WARN_ON here for now, but
+	 * really we need to figure out a better way to track our operating mode
+	 */
+	WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
+
+	/* TODO: Returns the first INTF_MODE, could there be multiple values? */
+	drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
+		return dpu_encoder_get_intf_mode(encoder);
+
+	return INTF_MODE_NONE;
+}
+
+void dpu_crtc_vblank_callback(struct drm_crtc *crtc)
+{
+	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+
+	/* keep statistics on vblank callback - with auto reset via debugfs */
+	if (ktime_compare(dpu_crtc->vblank_cb_time, ktime_set(0, 0)) == 0)
+		dpu_crtc->vblank_cb_time = ktime_get();
+	else
+		dpu_crtc->vblank_cb_count++;
+
+	dpu_crtc_get_crc(crtc);
+
+	drm_crtc_handle_vblank(crtc);
+	trace_dpu_crtc_vblank_cb(DRMID(crtc));
+}
+
+static void dpu_crtc_frame_event_work(struct kthread_work *work)
+{
+	struct dpu_crtc_frame_event *fevent = container_of(work,
+			struct dpu_crtc_frame_event, work);
+	struct drm_crtc *crtc = fevent->crtc;
+	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+	unsigned long flags;
+	bool frame_done = false;
+
+	DPU_ATRACE_BEGIN("crtc_frame_event");
+
+	DRM_DEBUG_ATOMIC("crtc%d event:%u ts:%lld\n", crtc->base.id, fevent->event,
+			ktime_to_ns(fevent->ts));
+
+	if (fevent->event & (DPU_ENCODER_FRAME_EVENT_DONE
+				| DPU_ENCODER_FRAME_EVENT_ERROR
+				| DPU_ENCODER_FRAME_EVENT_PANEL_DEAD)) {
+
+		if (atomic_read(&dpu_crtc->frame_pending) < 1) {
+			/* ignore vblank when not pending */
+		} else if (atomic_dec_return(&dpu_crtc->frame_pending) == 0) {
+			/* release bandwidth and other resources */
+			trace_dpu_crtc_frame_event_done(DRMID(crtc),
+							fevent->event);
+			dpu_core_perf_crtc_release_bw(crtc);
+		} else {
+			trace_dpu_crtc_frame_event_more_pending(DRMID(crtc),
+								fevent->event);
+		}
+
+		if (fevent->event & (DPU_ENCODER_FRAME_EVENT_DONE
+					| DPU_ENCODER_FRAME_EVENT_ERROR))
+			frame_done = true;
+	}
+
+	if (fevent->event & DPU_ENCODER_FRAME_EVENT_PANEL_DEAD)
+		DPU_ERROR("crtc%d ts:%lld received panel dead event\n",
+				crtc->base.id, ktime_to_ns(fevent->ts));
+
+	if (frame_done)
+		complete_all(&dpu_crtc->frame_done_comp);
+
+	spin_lock_irqsave(&dpu_crtc->spin_lock, flags);
+	list_add_tail(&fevent->list, &dpu_crtc->frame_event_list);
+	spin_unlock_irqrestore(&dpu_crtc->spin_lock, flags);
+	DPU_ATRACE_END("crtc_frame_event");
+}
+
+/**
+ * dpu_crtc_frame_event_cb - crtc frame event callback API
+ * @crtc: Pointer to crtc
+ * @event: Event to process
+ *
+ * Encoder may call this for different events from different context - IRQ,
+ * user thread, commit_thread, etc. Each event should be carefully reviewed and
+ * should be processed in proper task context to avoid schedulin delay or
+ * properly manage the irq context's bottom half processing.
+ */
+void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event)
+{
+	struct dpu_crtc *dpu_crtc;
+	struct msm_drm_private *priv;
+	struct dpu_crtc_frame_event *fevent;
+	unsigned long flags;
+	u32 crtc_id;
+
+	/* Nothing to do on idle event */
+	if (event & DPU_ENCODER_FRAME_EVENT_IDLE)
+		return;
+
+	dpu_crtc = to_dpu_crtc(crtc);
+	priv = crtc->dev->dev_private;
+	crtc_id = drm_crtc_index(crtc);
+
+	trace_dpu_crtc_frame_event_cb(DRMID(crtc), event);
+
+	spin_lock_irqsave(&dpu_crtc->spin_lock, flags);
+	fevent = list_first_entry_or_null(&dpu_crtc->frame_event_list,
+			struct dpu_crtc_frame_event, list);
+	if (fevent)
+		list_del_init(&fevent->list);
+	spin_unlock_irqrestore(&dpu_crtc->spin_lock, flags);
+
+	if (!fevent) {
+		DRM_ERROR_RATELIMITED("crtc%d event %d overflow\n", crtc->base.id, event);
+		return;
+	}
+
+	fevent->event = event;
+	fevent->crtc = crtc;
+	fevent->ts = ktime_get();
+	kthread_queue_work(priv->event_thread[crtc_id].worker, &fevent->work);
+}
+
+void dpu_crtc_complete_commit(struct drm_crtc *crtc)
+{
+	trace_dpu_crtc_complete_commit(DRMID(crtc));
+	dpu_core_perf_crtc_update(crtc, 0);
+	_dpu_crtc_complete_flip(crtc);
+}
+
+static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc,
+		struct drm_crtc_state *state)
+{
+	struct dpu_crtc_state *cstate = to_dpu_crtc_state(state);
+	struct drm_display_mode *adj_mode = &state->adjusted_mode;
+	u32 crtc_split_width = adj_mode->hdisplay / cstate->num_mixers;
+	int i;
+
+	for (i = 0; i < cstate->num_mixers; i++) {
+		struct drm_rect *r = &cstate->lm_bounds[i];
+		r->x1 = crtc_split_width * i;
+		r->y1 = 0;
+		r->x2 = r->x1 + crtc_split_width;
+		r->y2 = adj_mode->vdisplay;
+
+		trace_dpu_crtc_setup_lm_bounds(DRMID(crtc), i, r);
+	}
+}
+
+static void _dpu_crtc_get_pcc_coeff(struct drm_crtc_state *state,
+		struct dpu_hw_pcc_cfg *cfg)
+{
+	struct drm_color_ctm *ctm;
+
+	memset(cfg, 0, sizeof(struct dpu_hw_pcc_cfg));
+
+	ctm = (struct drm_color_ctm *)state->ctm->data;
+
+	if (!ctm)
+		return;
+
+	cfg->r.r = CONVERT_S3_15(ctm->matrix[0]);
+	cfg->g.r = CONVERT_S3_15(ctm->matrix[1]);
+	cfg->b.r = CONVERT_S3_15(ctm->matrix[2]);
+
+	cfg->r.g = CONVERT_S3_15(ctm->matrix[3]);
+	cfg->g.g = CONVERT_S3_15(ctm->matrix[4]);
+	cfg->b.g = CONVERT_S3_15(ctm->matrix[5]);
+
+	cfg->r.b = CONVERT_S3_15(ctm->matrix[6]);
+	cfg->g.b = CONVERT_S3_15(ctm->matrix[7]);
+	cfg->b.b = CONVERT_S3_15(ctm->matrix[8]);
+}
+
+static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
+{
+	struct drm_crtc_state *state = crtc->state;
+	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
+	struct dpu_crtc_mixer *mixer = cstate->mixers;
+	struct dpu_hw_pcc_cfg cfg;
+	struct dpu_hw_ctl *ctl;
+	struct dpu_hw_dspp *dspp;
+	int i;
+
+
+	if (!state->color_mgmt_changed && !drm_atomic_crtc_needs_modeset(state))
+		return;
+
+	for (i = 0; i < cstate->num_mixers; i++) {
+		ctl = mixer[i].lm_ctl;
+		dspp = mixer[i].hw_dspp;
+
+		if (!dspp || !dspp->ops.setup_pcc)
+			continue;
+
+		if (!state->ctm) {
+			dspp->ops.setup_pcc(dspp, NULL);
+		} else {
+			_dpu_crtc_get_pcc_coeff(state, &cfg);
+			dspp->ops.setup_pcc(dspp, &cfg);
+		}
+
+		/* stage config flush mask */
+		ctl->ops.update_pending_flush_dspp(ctl,
+			mixer[i].hw_dspp->idx, DPU_DSPP_PCC);
+	}
+}
+
+static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
+		struct drm_atomic_state *state)
+{
+	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
+	struct drm_encoder *encoder;
+
+	if (!crtc->state->enable) {
+		DRM_DEBUG_ATOMIC("crtc%d -> enable %d, skip atomic_begin\n",
+				crtc->base.id, crtc->state->enable);
+		return;
+	}
+
+	DRM_DEBUG_ATOMIC("crtc%d\n", crtc->base.id);
+
+	_dpu_crtc_setup_lm_bounds(crtc, crtc->state);
+
+	/* encoder will trigger pending mask now */
+	drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
+		dpu_encoder_trigger_kickoff_pending(encoder);
+
+	/*
+	 * If no mixers have been allocated in dpu_crtc_atomic_check(),
+	 * it means we are trying to flush a CRTC whose state is disabled:
+	 * nothing else needs to be done.
+	 */
+	if (unlikely(!cstate->num_mixers))
+		return;
+
+	_dpu_crtc_blend_setup(crtc);
+
+	_dpu_crtc_setup_cp_blocks(crtc);
+
+	/*
+	 * PP_DONE irq is only used by command mode for now.
+	 * It is better to request pending before FLUSH and START trigger
+	 * to make sure no pp_done irq missed.
+	 * This is safe because no pp_done will happen before SW trigger
+	 * in command mode.
+	 */
+}
+
+static void dpu_crtc_atomic_flush(struct drm_crtc *crtc,
+		struct drm_atomic_state *state)
+{
+	struct dpu_crtc *dpu_crtc;
+	struct drm_device *dev;
+	struct drm_plane *plane;
+	struct msm_drm_private *priv;
+	unsigned long flags;
+	struct dpu_crtc_state *cstate;
+
+	if (!crtc->state->enable) {
+		DRM_DEBUG_ATOMIC("crtc%d -> enable %d, skip atomic_flush\n",
+				crtc->base.id, crtc->state->enable);
+		return;
+	}
+
+	DRM_DEBUG_ATOMIC("crtc%d\n", crtc->base.id);
+
+	dpu_crtc = to_dpu_crtc(crtc);
+	cstate = to_dpu_crtc_state(crtc->state);
+	dev = crtc->dev;
+	priv = dev->dev_private;
+
+	if (crtc->index >= ARRAY_SIZE(priv->event_thread)) {
+		DPU_ERROR("invalid crtc index[%d]\n", crtc->index);
+		return;
+	}
+
+	WARN_ON(dpu_crtc->event);
+	spin_lock_irqsave(&dev->event_lock, flags);
+	dpu_crtc->event = crtc->state->event;
+	crtc->state->event = NULL;
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	/*
+	 * If no mixers has been allocated in dpu_crtc_atomic_check(),
+	 * it means we are trying to flush a CRTC whose state is disabled:
+	 * nothing else needs to be done.
+	 */
+	if (unlikely(!cstate->num_mixers))
+		return;
+
+	/* update performance setting before crtc kickoff */
+	dpu_core_perf_crtc_update(crtc, 1);
+
+	/*
+	 * Final plane updates: Give each plane a chance to complete all
+	 *                      required writes/flushing before crtc's "flush
+	 *                      everything" call below.
+	 */
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		if (dpu_crtc->smmu_state.transition_error)
+			dpu_plane_set_error(plane, true);
+		dpu_plane_flush(plane);
+	}
+
+	/* Kickoff will be scheduled by outer layer */
+}
+
+/**
+ * dpu_crtc_destroy_state - state destroy hook
+ * @crtc: drm CRTC
+ * @state: CRTC state object to release
+ */
+static void dpu_crtc_destroy_state(struct drm_crtc *crtc,
+		struct drm_crtc_state *state)
+{
+	struct dpu_crtc_state *cstate = to_dpu_crtc_state(state);
+
+	DRM_DEBUG_ATOMIC("crtc%d\n", crtc->base.id);
+
+	__drm_atomic_helper_crtc_destroy_state(state);
+
+	kfree(cstate);
+}
+
+static int _dpu_crtc_wait_for_frame_done(struct drm_crtc *crtc)
+{
+	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+	int ret, rc = 0;
+
+	if (!atomic_read(&dpu_crtc->frame_pending)) {
+		DRM_DEBUG_ATOMIC("no frames pending\n");
+		return 0;
+	}
+
+	DPU_ATRACE_BEGIN("frame done completion wait");
+	ret = wait_for_completion_timeout(&dpu_crtc->frame_done_comp,
+			msecs_to_jiffies(DPU_CRTC_FRAME_DONE_TIMEOUT_MS));
+	if (!ret) {
+		DRM_ERROR("frame done wait timed out, ret:%d\n", ret);
+		rc = -ETIMEDOUT;
+	}
+	DPU_ATRACE_END("frame done completion wait");
+
+	return rc;
+}
+
+void dpu_crtc_commit_kickoff(struct drm_crtc *crtc)
+{
+	struct drm_encoder *encoder;
+	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+	struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
+	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
+
+	/*
+	 * If no mixers has been allocated in dpu_crtc_atomic_check(),
+	 * it means we are trying to start a CRTC whose state is disabled:
+	 * nothing else needs to be done.
+	 */
+	if (unlikely(!cstate->num_mixers))
+		return;
+
+	DPU_ATRACE_BEGIN("crtc_commit");
+
+	drm_for_each_encoder_mask(encoder, crtc->dev,
+			crtc->state->encoder_mask) {
+		if (!dpu_encoder_is_valid_for_commit(encoder)) {
+			DRM_DEBUG_ATOMIC("invalid FB not kicking off crtc\n");
+			goto end;
+		}
+	}
+	/*
+	 * Encoder will flush/start now, unless it has a tx pending. If so, it
+	 * may delay and flush at an irq event (e.g. ppdone)
+	 */
+	drm_for_each_encoder_mask(encoder, crtc->dev,
+				  crtc->state->encoder_mask)
+		dpu_encoder_prepare_for_kickoff(encoder);
+
+	if (atomic_inc_return(&dpu_crtc->frame_pending) == 1) {
+		/* acquire bandwidth and other resources */
+		DRM_DEBUG_ATOMIC("crtc%d first commit\n", crtc->base.id);
+	} else
+		DRM_DEBUG_ATOMIC("crtc%d commit\n", crtc->base.id);
+
+	dpu_crtc->play_count++;
+
+	dpu_vbif_clear_errors(dpu_kms);
+
+	drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
+		dpu_encoder_kickoff(encoder);
+
+	reinit_completion(&dpu_crtc->frame_done_comp);
+
+end:
+	DPU_ATRACE_END("crtc_commit");
+}
+
+static void dpu_crtc_reset(struct drm_crtc *crtc)
+{
+	struct dpu_crtc_state *cstate = kzalloc(sizeof(*cstate), GFP_KERNEL);
+
+	if (crtc->state)
+		dpu_crtc_destroy_state(crtc, crtc->state);
+
+	if (cstate)
+		__drm_atomic_helper_crtc_reset(crtc, &cstate->base);
+	else
+		__drm_atomic_helper_crtc_reset(crtc, NULL);
+}
+
+/**
+ * dpu_crtc_duplicate_state - state duplicate hook
+ * @crtc: Pointer to drm crtc structure
+ */
+static struct drm_crtc_state *dpu_crtc_duplicate_state(struct drm_crtc *crtc)
+{
+	struct dpu_crtc_state *cstate, *old_cstate = to_dpu_crtc_state(crtc->state);
+
+	cstate = kmemdup(old_cstate, sizeof(*old_cstate), GFP_KERNEL);
+	if (!cstate) {
+		DPU_ERROR("failed to allocate state\n");
+		return NULL;
+	}
+
+	/* duplicate base helper */
+	__drm_atomic_helper_crtc_duplicate_state(crtc, &cstate->base);
+
+	return &cstate->base;
+}
+
+static void dpu_crtc_atomic_print_state(struct drm_printer *p,
+					const struct drm_crtc_state *state)
+{
+	const struct dpu_crtc_state *cstate = to_dpu_crtc_state(state);
+	int i;
+
+	for (i = 0; i < cstate->num_mixers; i++) {
+		drm_printf(p, "\tlm[%d]=%d\n", i, cstate->mixers[i].hw_lm->idx - LM_0);
+		drm_printf(p, "\tctl[%d]=%d\n", i, cstate->mixers[i].lm_ctl->idx - CTL_0);
+		if (cstate->mixers[i].hw_dspp)
+			drm_printf(p, "\tdspp[%d]=%d\n", i, cstate->mixers[i].hw_dspp->idx - DSPP_0);
+	}
+}
+
+static void dpu_crtc_disable(struct drm_crtc *crtc,
+			     struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *old_crtc_state = drm_atomic_get_old_crtc_state(state,
+									      crtc);
+	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
+	struct drm_encoder *encoder;
+	unsigned long flags;
+	bool release_bandwidth = false;
+
+	DRM_DEBUG_KMS("crtc%d\n", crtc->base.id);
+
+	/* If disable is triggered while in self refresh mode,
+	 * reset the encoder software state so that in enable
+	 * it won't trigger a warn while assigning crtc.
+	 */
+	if (old_crtc_state->self_refresh_active) {
+		drm_for_each_encoder_mask(encoder, crtc->dev,
+					old_crtc_state->encoder_mask) {
+			dpu_encoder_assign_crtc(encoder, NULL);
+		}
+		return;
+	}
+
+	/* Disable/save vblank irq handling */
+	drm_crtc_vblank_off(crtc);
+
+	drm_for_each_encoder_mask(encoder, crtc->dev,
+				  old_crtc_state->encoder_mask) {
+		/* in video mode, we hold an extra bandwidth reference
+		 * as we cannot drop bandwidth at frame-done if any
+		 * crtc is being used in video mode.
+		 */
+		if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_VIDEO)
+			release_bandwidth = true;
+
+		/*
+		 * If disable is triggered during psr active(e.g: screen dim in PSR),
+		 * we will need encoder->crtc connection to process the device sleep &
+		 * preserve it during psr sequence.
+		 */
+		if (!crtc->state->self_refresh_active)
+			dpu_encoder_assign_crtc(encoder, NULL);
+	}
+
+	/* wait for frame_event_done completion */
+	if (_dpu_crtc_wait_for_frame_done(crtc))
+		DPU_ERROR("crtc%d wait for frame done failed;frame_pending%d\n",
+				crtc->base.id,
+				atomic_read(&dpu_crtc->frame_pending));
+
+	trace_dpu_crtc_disable(DRMID(crtc), false, dpu_crtc);
+	dpu_crtc->enabled = false;
+
+	if (atomic_read(&dpu_crtc->frame_pending)) {
+		trace_dpu_crtc_disable_frame_pending(DRMID(crtc),
+				     atomic_read(&dpu_crtc->frame_pending));
+		if (release_bandwidth)
+			dpu_core_perf_crtc_release_bw(crtc);
+		atomic_set(&dpu_crtc->frame_pending, 0);
+	}
+
+	dpu_core_perf_crtc_update(crtc, 0);
+
+	/* disable clk & bw control until clk & bw properties are set */
+	cstate->bw_control = false;
+	cstate->bw_split_vote = false;
+
+	if (crtc->state->event && !crtc->state->active) {
+		spin_lock_irqsave(&crtc->dev->event_lock, flags);
+		drm_crtc_send_vblank_event(crtc, crtc->state->event);
+		crtc->state->event = NULL;
+		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+	}
+
+	pm_runtime_put_sync(crtc->dev->dev);
+}
+
+static void dpu_crtc_enable(struct drm_crtc *crtc,
+		struct drm_atomic_state *state)
+{
+	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+	struct drm_encoder *encoder;
+	bool request_bandwidth = false;
+	struct drm_crtc_state *old_crtc_state;
+
+	old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
+
+	pm_runtime_get_sync(crtc->dev->dev);
+
+	DRM_DEBUG_KMS("crtc%d\n", crtc->base.id);
+
+	drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) {
+		/* in video mode, we hold an extra bandwidth reference
+		 * as we cannot drop bandwidth at frame-done if any
+		 * crtc is being used in video mode.
+		 */
+		if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_VIDEO)
+			request_bandwidth = true;
+	}
+
+	if (request_bandwidth)
+		atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
+
+	trace_dpu_crtc_enable(DRMID(crtc), true, dpu_crtc);
+	dpu_crtc->enabled = true;
+
+	if (!old_crtc_state->self_refresh_active) {
+		drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
+			dpu_encoder_assign_crtc(encoder, crtc);
+	}
+
+	/* Enable/restore vblank irq handling */
+	drm_crtc_vblank_on(crtc);
+}
+
+static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
+{
+	struct drm_crtc *crtc = cstate->crtc;
+	struct drm_encoder *encoder;
+
+	if (cstate->self_refresh_active)
+		return true;
+
+	drm_for_each_encoder_mask (encoder, crtc->dev, cstate->encoder_mask) {
+		if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_CMD) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
+		struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
+									  crtc);
+	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
+
+	const struct drm_plane_state *pstate;
+	struct drm_plane *plane;
+
+	int rc = 0;
+
+	bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
+
+	if (!crtc_state->enable || !drm_atomic_crtc_effectively_active(crtc_state)) {
+		DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n",
+				crtc->base.id, crtc_state->enable,
+				crtc_state->active);
+		memset(&cstate->new_perf, 0, sizeof(cstate->new_perf));
+		return 0;
+	}
+
+	DRM_DEBUG_ATOMIC("%s: check\n", dpu_crtc->name);
+
+	/* force a full mode set if active state changed */
+	if (crtc_state->active_changed)
+		crtc_state->mode_changed = true;
+
+	if (cstate->num_mixers)
+		_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
+
+	/* FIXME: move this to dpu_plane_atomic_check? */
+	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
+		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
+
+		if (IS_ERR_OR_NULL(pstate)) {
+			rc = PTR_ERR(pstate);
+			DPU_ERROR("%s: failed to get plane%d state, %d\n",
+					dpu_crtc->name, plane->base.id, rc);
+			return rc;
+		}
+
+		if (!pstate->visible)
+			continue;
+
+		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
+	}
+
+	atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
+
+	rc = dpu_core_perf_crtc_check(crtc, crtc_state);
+	if (rc) {
+		DPU_ERROR("crtc%d failed performance check %d\n",
+				crtc->base.id, rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+int dpu_crtc_vblank(struct drm_crtc *crtc, bool en)
+{
+	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+	struct drm_encoder *enc;
+
+	trace_dpu_crtc_vblank(DRMID(&dpu_crtc->base), en, dpu_crtc);
+
+	/*
+	 * Normally we would iterate through encoder_mask in crtc state to find
+	 * attached encoders. In this case, we might be disabling vblank _after_
+	 * encoder_mask has been cleared.
+	 *
+	 * Instead, we "assign" a crtc to the encoder in enable and clear it in
+	 * disable (which is also after encoder_mask is cleared). So instead of
+	 * using encoder mask, we'll ask the encoder to toggle itself iff it's
+	 * currently assigned to our crtc.
+	 *
+	 * Note also that this function cannot be called while crtc is disabled
+	 * since we use drm_crtc_vblank_on/off. So we don't need to worry
+	 * about the assigned crtcs being inconsistent with the current state
+	 * (which means no need to worry about modeset locks).
+	 */
+	list_for_each_entry(enc, &crtc->dev->mode_config.encoder_list, head) {
+		trace_dpu_crtc_vblank_enable(DRMID(crtc), DRMID(enc), en,
+					     dpu_crtc);
+
+		dpu_encoder_toggle_vblank_for_crtc(enc, crtc, en);
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
+{
+	struct dpu_crtc *dpu_crtc;
+	struct dpu_plane_state *pstate = NULL;
+	struct dpu_crtc_mixer *m;
+
+	struct drm_crtc *crtc;
+	struct drm_plane *plane;
+	struct drm_display_mode *mode;
+	struct drm_framebuffer *fb;
+	struct drm_plane_state *state;
+	struct dpu_crtc_state *cstate;
+
+	int i, out_width;
+
+	dpu_crtc = s->private;
+	crtc = &dpu_crtc->base;
+
+	drm_modeset_lock_all(crtc->dev);
+	cstate = to_dpu_crtc_state(crtc->state);
+
+	mode = &crtc->state->adjusted_mode;
+	out_width = mode->hdisplay / cstate->num_mixers;
+
+	seq_printf(s, "crtc:%d width:%d height:%d\n", crtc->base.id,
+				mode->hdisplay, mode->vdisplay);
+
+	seq_puts(s, "\n");
+
+	for (i = 0; i < cstate->num_mixers; ++i) {
+		m = &cstate->mixers[i];
+		seq_printf(s, "\tmixer:%d ctl:%d width:%d height:%d\n",
+			m->hw_lm->idx - LM_0, m->lm_ctl->idx - CTL_0,
+			out_width, mode->vdisplay);
+	}
+
+	seq_puts(s, "\n");
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		pstate = to_dpu_plane_state(plane->state);
+		state = plane->state;
+
+		if (!pstate || !state)
+			continue;
+
+		seq_printf(s, "\tplane:%u stage:%d\n", plane->base.id,
+			pstate->stage);
+
+		if (plane->state->fb) {
+			fb = plane->state->fb;
+
+			seq_printf(s, "\tfb:%d image format:%4.4s wxh:%ux%u ",
+				fb->base.id, (char *) &fb->format->format,
+				fb->width, fb->height);
+			for (i = 0; i < ARRAY_SIZE(fb->format->cpp); ++i)
+				seq_printf(s, "cpp[%d]:%u ",
+						i, fb->format->cpp[i]);
+			seq_puts(s, "\n\t");
+
+			seq_printf(s, "modifier:%8llu ", fb->modifier);
+			seq_puts(s, "\n");
+
+			seq_puts(s, "\t");
+			for (i = 0; i < ARRAY_SIZE(fb->pitches); i++)
+				seq_printf(s, "pitches[%d]:%8u ", i,
+							fb->pitches[i]);
+			seq_puts(s, "\n");
+
+			seq_puts(s, "\t");
+			for (i = 0; i < ARRAY_SIZE(fb->offsets); i++)
+				seq_printf(s, "offsets[%d]:%8u ", i,
+							fb->offsets[i]);
+			seq_puts(s, "\n");
+		}
+
+		seq_printf(s, "\tsrc_x:%4d src_y:%4d src_w:%4d src_h:%4d\n",
+			state->src_x, state->src_y, state->src_w, state->src_h);
+
+		seq_printf(s, "\tdst x:%4d dst_y:%4d dst_w:%4d dst_h:%4d\n",
+			state->crtc_x, state->crtc_y, state->crtc_w,
+			state->crtc_h);
+		seq_printf(s, "\tsspp[0]:%s\n",
+			   pstate->pipe.sspp->cap->name);
+		seq_printf(s, "\tmultirect[0]: mode: %d index: %d\n",
+			pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
+		if (pstate->r_pipe.sspp) {
+			seq_printf(s, "\tsspp[1]:%s\n",
+				   pstate->r_pipe.sspp->cap->name);
+			seq_printf(s, "\tmultirect[1]: mode: %d index: %d\n",
+				   pstate->r_pipe.multirect_mode, pstate->r_pipe.multirect_index);
+		}
+
+		seq_puts(s, "\n");
+	}
+	if (dpu_crtc->vblank_cb_count) {
+		ktime_t diff = ktime_sub(ktime_get(), dpu_crtc->vblank_cb_time);
+		s64 diff_ms = ktime_to_ms(diff);
+		s64 fps = diff_ms ? div_s64(
+				dpu_crtc->vblank_cb_count * 1000, diff_ms) : 0;
+
+		seq_printf(s,
+			"vblank fps:%lld count:%u total:%llums total_framecount:%llu\n",
+				fps, dpu_crtc->vblank_cb_count,
+				ktime_to_ms(diff), dpu_crtc->play_count);
+
+		/* reset time & count for next measurement */
+		dpu_crtc->vblank_cb_count = 0;
+		dpu_crtc->vblank_cb_time = ktime_set(0, 0);
+	}
+
+	drm_modeset_unlock_all(crtc->dev);
+
+	return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(_dpu_debugfs_status);
+
+static int dpu_crtc_debugfs_state_show(struct seq_file *s, void *v)
+{
+	struct drm_crtc *crtc = s->private;
+	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+
+	seq_printf(s, "client type: %d\n", dpu_crtc_get_client_type(crtc));
+	seq_printf(s, "intf_mode: %d\n", dpu_crtc_get_intf_mode(crtc));
+	seq_printf(s, "core_clk_rate: %llu\n",
+			dpu_crtc->cur_perf.core_clk_rate);
+	seq_printf(s, "bw_ctl: %llu\n", dpu_crtc->cur_perf.bw_ctl);
+	seq_printf(s, "max_per_pipe_ib: %llu\n",
+				dpu_crtc->cur_perf.max_per_pipe_ib);
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(dpu_crtc_debugfs_state);
+
+static int _dpu_crtc_init_debugfs(struct drm_crtc *crtc)
+{
+	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
+
+	debugfs_create_file("status", 0400,
+			crtc->debugfs_entry,
+			dpu_crtc, &_dpu_debugfs_status_fops);
+	debugfs_create_file("state", 0600,
+			crtc->debugfs_entry,
+			&dpu_crtc->base,
+			&dpu_crtc_debugfs_state_fops);
+
+	return 0;
+}
+#else
+static int _dpu_crtc_init_debugfs(struct drm_crtc *crtc)
+{
+	return 0;
+}
+#endif /* CONFIG_DEBUG_FS */
+
+static int dpu_crtc_late_register(struct drm_crtc *crtc)
+{
+	return _dpu_crtc_init_debugfs(crtc);
+}
+
+static const struct drm_crtc_funcs dpu_crtc_funcs = {
+	.set_config = drm_atomic_helper_set_config,
+	.page_flip = drm_atomic_helper_page_flip,
+	.reset = dpu_crtc_reset,
+	.atomic_duplicate_state = dpu_crtc_duplicate_state,
+	.atomic_destroy_state = dpu_crtc_destroy_state,
+	.atomic_print_state = dpu_crtc_atomic_print_state,
+	.late_register = dpu_crtc_late_register,
+	.verify_crc_source = dpu_crtc_verify_crc_source,
+	.set_crc_source = dpu_crtc_set_crc_source,
+	.enable_vblank  = msm_crtc_enable_vblank,
+	.disable_vblank = msm_crtc_disable_vblank,
+	.get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
+	.get_vblank_counter = dpu_crtc_get_vblank_counter,
+};
+
+static const struct drm_crtc_helper_funcs dpu_crtc_helper_funcs = {
+	.atomic_disable = dpu_crtc_disable,
+	.atomic_enable = dpu_crtc_enable,
+	.atomic_check = dpu_crtc_atomic_check,
+	.atomic_begin = dpu_crtc_atomic_begin,
+	.atomic_flush = dpu_crtc_atomic_flush,
+	.get_scanout_position = dpu_crtc_get_scanout_position,
+};
+
+/* initialize crtc */
+struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
+				struct drm_plane *cursor)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
+	struct drm_crtc *crtc = NULL;
+	struct dpu_crtc *dpu_crtc;
+	int i, ret;
+
+	dpu_crtc = drmm_crtc_alloc_with_planes(dev, struct dpu_crtc, base,
+					       plane, cursor,
+					       &dpu_crtc_funcs,
+					       NULL);
+
+	if (IS_ERR(dpu_crtc))
+		return ERR_CAST(dpu_crtc);
+
+	crtc = &dpu_crtc->base;
+	crtc->dev = dev;
+
+	spin_lock_init(&dpu_crtc->spin_lock);
+	atomic_set(&dpu_crtc->frame_pending, 0);
+
+	init_completion(&dpu_crtc->frame_done_comp);
+
+	INIT_LIST_HEAD(&dpu_crtc->frame_event_list);
+
+	for (i = 0; i < ARRAY_SIZE(dpu_crtc->frame_events); i++) {
+		INIT_LIST_HEAD(&dpu_crtc->frame_events[i].list);
+		list_add(&dpu_crtc->frame_events[i].list,
+				&dpu_crtc->frame_event_list);
+		kthread_init_work(&dpu_crtc->frame_events[i].work,
+				dpu_crtc_frame_event_work);
+	}
+
+	drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs);
+
+	if (dpu_kms->catalog->dspp_count)
+		drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
+
+	/* save user friendly CRTC name for later */
+	snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id);
+
+	/* initialize event handling */
+	spin_lock_init(&dpu_crtc->event_lock);
+
+	ret = drm_self_refresh_helper_init(crtc);
+	if (ret) {
+		DPU_ERROR("Failed to initialize %s with self-refresh helpers %d\n",
+			crtc->name, ret);
+		return ERR_PTR(ret);
+	}
+
+	DRM_DEBUG_KMS("%s: successfully initialized crtc\n", dpu_crtc->name);
+	return crtc;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_crtc.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_crtc.h
@@ -0,0 +1,305 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2021 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef _DPU_CRTC_H_
+#define _DPU_CRTC_H_
+
+#include <linux/kthread.h>
+#include <drm/drm_crtc.h>
+#include "dpu_kms.h"
+#include "dpu_core_perf.h"
+
+#define DPU_CRTC_NAME_SIZE	12
+
+/* define the maximum number of in-flight frame events */
+#define DPU_CRTC_FRAME_EVENT_SIZE	4
+
+/**
+ * enum dpu_crtc_client_type: crtc client type
+ * @RT_CLIENT:	RealTime client like video/cmd mode display
+ *              voting through apps rsc
+ * @NRT_CLIENT:	Non-RealTime client like WB display
+ *              voting through apps rsc
+ */
+enum dpu_crtc_client_type {
+	RT_CLIENT,
+	NRT_CLIENT,
+};
+
+/**
+ * enum dpu_crtc_smmu_state:	smmu state
+ * @ATTACHED:	 all the context banks are attached.
+ * @DETACHED:	 all the context banks are detached.
+ * @ATTACH_ALL_REQ:	 transient state of attaching context banks.
+ * @DETACH_ALL_REQ:	 transient state of detaching context banks.
+ */
+enum dpu_crtc_smmu_state {
+	ATTACHED = 0,
+	DETACHED,
+	ATTACH_ALL_REQ,
+	DETACH_ALL_REQ,
+};
+
+/**
+ * enum dpu_crtc_smmu_state_transition_type: state transition type
+ * @NONE: no pending state transitions
+ * @PRE_COMMIT: state transitions should be done before processing the commit
+ * @POST_COMMIT: state transitions to be done after processing the commit.
+ */
+enum dpu_crtc_smmu_state_transition_type {
+	NONE,
+	PRE_COMMIT,
+	POST_COMMIT
+};
+
+/**
+ * struct dpu_crtc_smmu_state_data: stores the smmu state and transition type
+ * @state: current state of smmu context banks
+ * @transition_type: transition request type
+ * @transition_error: whether there is error while transitioning the state
+ */
+struct dpu_crtc_smmu_state_data {
+	uint32_t state;
+	uint32_t transition_type;
+	uint32_t transition_error;
+};
+
+/**
+ * enum dpu_crtc_crc_source: CRC source
+ * @DPU_CRTC_CRC_SOURCE_NONE: no source set
+ * @DPU_CRTC_CRC_SOURCE_LAYER_MIXER: CRC in layer mixer
+ * @DPU_CRTC_CRC_SOURCE_ENCODER: CRC in encoder
+ * @DPU_CRTC_CRC_SOURCE_INVALID: Invalid source
+ */
+enum dpu_crtc_crc_source {
+	DPU_CRTC_CRC_SOURCE_NONE = 0,
+	DPU_CRTC_CRC_SOURCE_LAYER_MIXER,
+	DPU_CRTC_CRC_SOURCE_ENCODER,
+	DPU_CRTC_CRC_SOURCE_MAX,
+	DPU_CRTC_CRC_SOURCE_INVALID = -1
+};
+
+/**
+ * struct dpu_crtc_mixer: stores the map for each virtual pipeline in the CRTC
+ * @hw_lm:	LM HW Driver context
+ * @lm_ctl:	CTL Path HW driver context
+ * @lm_dspp:	DSPP HW driver context
+ * @mixer_op_mode:	mixer blending operation mode
+ * @flush_mask:	mixer flush mask for ctl, mixer and pipe
+ */
+struct dpu_crtc_mixer {
+	struct dpu_hw_mixer *hw_lm;
+	struct dpu_hw_ctl *lm_ctl;
+	struct dpu_hw_dspp *hw_dspp;
+	u32 mixer_op_mode;
+};
+
+/**
+ * struct dpu_crtc_frame_event: stores crtc frame event for crtc processing
+ * @work:	base work structure
+ * @crtc:	Pointer to crtc handling this event
+ * @list:	event list
+ * @ts:		timestamp at queue entry
+ * @event:	event identifier
+ */
+struct dpu_crtc_frame_event {
+	struct kthread_work work;
+	struct drm_crtc *crtc;
+	struct list_head list;
+	ktime_t ts;
+	u32 event;
+};
+
+/*
+ * Maximum number of free event structures to cache
+ */
+#define DPU_CRTC_MAX_EVENT_COUNT	16
+
+/**
+ * struct dpu_crtc - virtualized CRTC data structure
+ * @base          : Base drm crtc structure
+ * @name          : ASCII description of this crtc
+ * @event         : Pointer to last received drm vblank event. If there is a
+ *                  pending vblank event, this will be non-null.
+ * @vsync_count   : Running count of received vsync events
+ * @drm_requested_vblank : Whether vblanks have been enabled in the encoder
+ * @property_info : Opaque structure for generic property support
+ * @property_defaults : Array of default values for generic property support
+ * @vblank_cb_count : count of vblank callback since last reset
+ * @play_count    : frame count between crtc enable and disable
+ * @vblank_cb_time  : ktime at vblank count reset
+ * @enabled       : whether the DPU CRTC is currently enabled. updated in the
+ *                  commit-thread, not state-swap time which is earlier, so
+ *                  safe to make decisions on during VBLANK on/off work
+ * @feature_list  : list of color processing features supported on a crtc
+ * @active_list   : list of color processing features are active
+ * @dirty_list    : list of color processing features are dirty
+ * @ad_dirty: list containing ad properties that are dirty
+ * @ad_active: list containing ad properties that are active
+ * @frame_pending : Whether or not an update is pending
+ * @frame_events  : static allocation of in-flight frame events
+ * @frame_event_list : available frame event list
+ * @spin_lock     : spin lock for frame event, transaction status, etc...
+ * @frame_done_comp    : for frame_event_done synchronization
+ * @event_thread  : Pointer to event handler thread
+ * @event_worker  : Event worker queue
+ * @event_lock    : Spinlock around event handling code
+ * @phandle: Pointer to power handler
+ * @cur_perf      : current performance committed to clock/bandwidth driver
+ * @crc_source    : CRC source
+ */
+struct dpu_crtc {
+	struct drm_crtc base;
+	char name[DPU_CRTC_NAME_SIZE];
+
+	struct drm_pending_vblank_event *event;
+	u32 vsync_count;
+
+	u32 vblank_cb_count;
+	u64 play_count;
+	ktime_t vblank_cb_time;
+	bool enabled;
+
+	struct list_head feature_list;
+	struct list_head active_list;
+	struct list_head dirty_list;
+	struct list_head ad_dirty;
+	struct list_head ad_active;
+
+	atomic_t frame_pending;
+	struct dpu_crtc_frame_event frame_events[DPU_CRTC_FRAME_EVENT_SIZE];
+	struct list_head frame_event_list;
+	spinlock_t spin_lock;
+	struct completion frame_done_comp;
+
+	/* for handling internal event thread */
+	spinlock_t event_lock;
+
+	struct dpu_core_perf_params cur_perf;
+
+	struct dpu_crtc_smmu_state_data smmu_state;
+};
+
+#define to_dpu_crtc(x) container_of(x, struct dpu_crtc, base)
+
+/**
+ * struct dpu_crtc_state - dpu container for atomic crtc state
+ * @base: Base drm crtc state structure
+ * @bw_control    : true if bw/clk controlled by core bw/clk properties
+ * @bw_split_vote : true if bw controlled by llcc/dram bw properties
+ * @lm_bounds     : LM boundaries based on current mode full resolution, no ROI.
+ *                  Origin top left of CRTC.
+ * @property_state: Local storage for msm_prop properties
+ * @property_values: Current crtc property values
+ * @input_fence_timeout_ns : Cached input fence timeout, in ns
+ * @new_perf: new performance state being requested
+ * @num_mixers    : Number of mixers in use
+ * @mixers        : List of active mixers
+ * @num_ctls      : Number of ctl paths in use
+ * @hw_ctls       : List of active ctl paths
+ * @crc_source    : CRC source
+ * @crc_frame_skip_count: Number of frames skipped before getting CRC
+ */
+struct dpu_crtc_state {
+	struct drm_crtc_state base;
+
+	bool bw_control;
+	bool bw_split_vote;
+	struct drm_rect lm_bounds[CRTC_DUAL_MIXERS];
+
+	uint64_t input_fence_timeout_ns;
+
+	struct dpu_core_perf_params new_perf;
+
+	/* HW Resources reserved for the crtc */
+	u32 num_mixers;
+	struct dpu_crtc_mixer mixers[CRTC_DUAL_MIXERS];
+
+	u32 num_ctls;
+	struct dpu_hw_ctl *hw_ctls[CRTC_DUAL_MIXERS];
+
+	enum dpu_crtc_crc_source crc_source;
+	int crc_frame_skip_count;
+};
+
+#define to_dpu_crtc_state(x) \
+	container_of(x, struct dpu_crtc_state, base)
+
+/**
+ * dpu_crtc_frame_pending - retun the number of pending frames
+ * @crtc: Pointer to drm crtc object
+ */
+static inline int dpu_crtc_frame_pending(struct drm_crtc *crtc)
+{
+	return crtc ? atomic_read(&to_dpu_crtc(crtc)->frame_pending) : -EINVAL;
+}
+
+/**
+ * dpu_crtc_vblank - enable or disable vblanks for this crtc
+ * @crtc: Pointer to drm crtc object
+ * @en: true to enable vblanks, false to disable
+ */
+int dpu_crtc_vblank(struct drm_crtc *crtc, bool en);
+
+/**
+ * dpu_crtc_vblank_callback - called on vblank irq, issues completion events
+ * @crtc: Pointer to drm crtc object
+ */
+void dpu_crtc_vblank_callback(struct drm_crtc *crtc);
+
+/**
+ * dpu_crtc_commit_kickoff - trigger kickoff of the commit for this crtc
+ * @crtc: Pointer to drm crtc object
+ */
+void dpu_crtc_commit_kickoff(struct drm_crtc *crtc);
+
+/**
+ * dpu_crtc_complete_commit - callback signalling completion of current commit
+ * @crtc: Pointer to drm crtc object
+ */
+void dpu_crtc_complete_commit(struct drm_crtc *crtc);
+
+/**
+ * dpu_crtc_init - create a new crtc object
+ * @dev: dpu device
+ * @plane: base plane
+ * @cursor: cursor plane
+ * @Return: new crtc object or error
+ */
+struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
+			       struct drm_plane *cursor);
+
+/**
+ * dpu_crtc_register_custom_event - api for enabling/disabling crtc event
+ * @kms: Pointer to dpu_kms
+ * @crtc_drm: Pointer to crtc object
+ * @event: Event that client is interested
+ * @en: Flag to enable/disable the event
+ */
+int dpu_crtc_register_custom_event(struct dpu_kms *kms,
+		struct drm_crtc *crtc_drm, u32 event, bool en);
+
+/**
+ * dpu_crtc_get_intf_mode - get interface mode of the given crtc
+ * @crtc: Pointert to crtc
+ */
+enum dpu_intf_mode dpu_crtc_get_intf_mode(struct drm_crtc *crtc);
+
+/**
+ * dpu_crtc_get_client_type - check the crtc type- rt, nrt etc.
+ * @crtc: Pointer to crtc
+ */
+static inline enum dpu_crtc_client_type dpu_crtc_get_client_type(
+						struct drm_crtc *crtc)
+{
+	return crtc && crtc->state ? RT_CLIENT : NRT_CLIENT;
+}
+
+void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event);
+
+#endif /* _DPU_CRTC_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_encoder.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_encoder.c
@@ -0,0 +1,2645 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+#include <linux/debugfs.h>
+#include <linux/kthread.h>
+#include <linux/seq_file.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_file.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_framebuffer.h>
+
+#include "msm_drv.h"
+#include "dpu_kms.h"
+#include "dpu_hwio.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_intf.h"
+#include "dpu_hw_ctl.h"
+#include "dpu_hw_dspp.h"
+#include "dpu_hw_dsc.h"
+#include "dpu_hw_merge3d.h"
+#include "dpu_hw_cdm.h"
+#include "dpu_formats.h"
+#include "dpu_encoder_phys.h"
+#include "dpu_crtc.h"
+#include "dpu_trace.h"
+#include "dpu_core_irq.h"
+#include "disp/msm_disp_snapshot.h"
+
+#define DPU_DEBUG_ENC(e, fmt, ...) DRM_DEBUG_ATOMIC("enc%d " fmt,\
+		(e) ? (e)->base.base.id : -1, ##__VA_ARGS__)
+
+#define DPU_ERROR_ENC(e, fmt, ...) DPU_ERROR("enc%d " fmt,\
+		(e) ? (e)->base.base.id : -1, ##__VA_ARGS__)
+
+#define DPU_ERROR_ENC_RATELIMITED(e, fmt, ...) DPU_ERROR_RATELIMITED("enc%d " fmt,\
+		(e) ? (e)->base.base.id : -1, ##__VA_ARGS__)
+
+/*
+ * Two to anticipate panels that can do cmd/vid dynamic switching
+ * plan is to create all possible physical encoder types, and switch between
+ * them at runtime
+ */
+#define NUM_PHYS_ENCODER_TYPES 2
+
+#define MAX_PHYS_ENCODERS_PER_VIRTUAL \
+	(MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES)
+
+#define MAX_CHANNELS_PER_ENC 2
+
+#define IDLE_SHORT_TIMEOUT	1
+
+#define MAX_HDISPLAY_SPLIT 1080
+
+/* timeout in frames waiting for frame done */
+#define DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES 5
+
+/**
+ * enum dpu_enc_rc_events - events for resource control state machine
+ * @DPU_ENC_RC_EVENT_KICKOFF:
+ *	This event happens at NORMAL priority.
+ *	Event that signals the start of the transfer. When this event is
+ *	received, enable MDP/DSI core clocks. Regardless of the previous
+ *	state, the resource should be in ON state at the end of this event.
+ * @DPU_ENC_RC_EVENT_FRAME_DONE:
+ *	This event happens at INTERRUPT level.
+ *	Event signals the end of the data transfer after the PP FRAME_DONE
+ *	event. At the end of this event, a delayed work is scheduled to go to
+ *	IDLE_PC state after IDLE_TIMEOUT time.
+ * @DPU_ENC_RC_EVENT_PRE_STOP:
+ *	This event happens at NORMAL priority.
+ *	This event, when received during the ON state, leave the RC STATE
+ *	in the PRE_OFF state. It should be followed by the STOP event as
+ *	part of encoder disable.
+ *	If received during IDLE or OFF states, it will do nothing.
+ * @DPU_ENC_RC_EVENT_STOP:
+ *	This event happens at NORMAL priority.
+ *	When this event is received, disable all the MDP/DSI core clocks, and
+ *	disable IRQs. It should be called from the PRE_OFF or IDLE states.
+ *	IDLE is expected when IDLE_PC has run, and PRE_OFF did nothing.
+ *	PRE_OFF is expected when PRE_STOP was executed during the ON state.
+ *	Resource state should be in OFF at the end of the event.
+ * @DPU_ENC_RC_EVENT_ENTER_IDLE:
+ *	This event happens at NORMAL priority from a work item.
+ *	Event signals that there were no frame updates for IDLE_TIMEOUT time.
+ *	This would disable MDP/DSI core clocks and change the resource state
+ *	to IDLE.
+ */
+enum dpu_enc_rc_events {
+	DPU_ENC_RC_EVENT_KICKOFF = 1,
+	DPU_ENC_RC_EVENT_FRAME_DONE,
+	DPU_ENC_RC_EVENT_PRE_STOP,
+	DPU_ENC_RC_EVENT_STOP,
+	DPU_ENC_RC_EVENT_ENTER_IDLE
+};
+
+/*
+ * enum dpu_enc_rc_states - states that the resource control maintains
+ * @DPU_ENC_RC_STATE_OFF: Resource is in OFF state
+ * @DPU_ENC_RC_STATE_PRE_OFF: Resource is transitioning to OFF state
+ * @DPU_ENC_RC_STATE_ON: Resource is in ON state
+ * @DPU_ENC_RC_STATE_MODESET: Resource is in modeset state
+ * @DPU_ENC_RC_STATE_IDLE: Resource is in IDLE state
+ */
+enum dpu_enc_rc_states {
+	DPU_ENC_RC_STATE_OFF,
+	DPU_ENC_RC_STATE_PRE_OFF,
+	DPU_ENC_RC_STATE_ON,
+	DPU_ENC_RC_STATE_IDLE
+};
+
+/**
+ * struct dpu_encoder_virt - virtual encoder. Container of one or more physical
+ *	encoders. Virtual encoder manages one "logical" display. Physical
+ *	encoders manage one intf block, tied to a specific panel/sub-panel.
+ *	Virtual encoder defers as much as possible to the physical encoders.
+ *	Virtual encoder registers itself with the DRM Framework as the encoder.
+ * @base:		drm_encoder base class for registration with DRM
+ * @enc_spinlock:	Virtual-Encoder-Wide Spin Lock for IRQ purposes
+ * @enabled:		True if the encoder is active, protected by enc_lock
+ * @commit_done_timedout: True if there has been a timeout on commit after
+ *			enabling the encoder.
+ * @num_phys_encs:	Actual number of physical encoders contained.
+ * @phys_encs:		Container of physical encoders managed.
+ * @cur_master:		Pointer to the current master in this mode. Optimization
+ *			Only valid after enable. Cleared as disable.
+ * @cur_slave:		As above but for the slave encoder.
+ * @hw_pp:		Handle to the pingpong blocks used for the display. No.
+ *			pingpong blocks can be different than num_phys_encs.
+ * @hw_dsc:		Handle to the DSC blocks used for the display.
+ * @dsc_mask:		Bitmask of used DSC blocks.
+ * @intfs_swapped:	Whether or not the phys_enc interfaces have been swapped
+ *			for partial update right-only cases, such as pingpong
+ *			split where virtual pingpong does not generate IRQs
+ * @crtc:		Pointer to the currently assigned crtc. Normally you
+ *			would use crtc->state->encoder_mask to determine the
+ *			link between encoder/crtc. However in this case we need
+ *			to track crtc in the disable() hook which is called
+ *			_after_ encoder_mask is cleared.
+ * @connector:		If a mode is set, cached pointer to the active connector
+ * @enc_lock:			Lock around physical encoder
+ *				create/destroy/enable/disable
+ * @frame_busy_mask:		Bitmask tracking which phys_enc we are still
+ *				busy processing current command.
+ *				Bit0 = phys_encs[0] etc.
+ * @frame_done_timeout_ms:	frame done timeout in ms
+ * @frame_done_timeout_cnt:	atomic counter tracking the number of frame
+ * 				done timeouts
+ * @frame_done_timer:		watchdog timer for frame done event
+ * @disp_info:			local copy of msm_display_info struct
+ * @idle_pc_supported:		indicate if idle power collaps is supported
+ * @rc_lock:			resource control mutex lock to protect
+ *				virt encoder over various state changes
+ * @rc_state:			resource controller state
+ * @delayed_off_work:		delayed worker to schedule disabling of
+ *				clks and resources after IDLE_TIMEOUT time.
+ * @topology:                   topology of the display
+ * @idle_timeout:		idle timeout duration in milliseconds
+ * @wide_bus_en:		wide bus is enabled on this interface
+ * @dsc:			drm_dsc_config pointer, for DSC-enabled encoders
+ */
+struct dpu_encoder_virt {
+	struct drm_encoder base;
+	spinlock_t enc_spinlock;
+
+	bool enabled;
+	bool commit_done_timedout;
+
+	unsigned int num_phys_encs;
+	struct dpu_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL];
+	struct dpu_encoder_phys *cur_master;
+	struct dpu_encoder_phys *cur_slave;
+	struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
+	struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
+
+	unsigned int dsc_mask;
+
+	bool intfs_swapped;
+
+	struct drm_crtc *crtc;
+	struct drm_connector *connector;
+
+	struct mutex enc_lock;
+	DECLARE_BITMAP(frame_busy_mask, MAX_PHYS_ENCODERS_PER_VIRTUAL);
+
+	atomic_t frame_done_timeout_ms;
+	atomic_t frame_done_timeout_cnt;
+	struct timer_list frame_done_timer;
+
+	struct msm_display_info disp_info;
+
+	bool idle_pc_supported;
+	struct mutex rc_lock;
+	enum dpu_enc_rc_states rc_state;
+	struct delayed_work delayed_off_work;
+	struct msm_display_topology topology;
+
+	u32 idle_timeout;
+
+	bool wide_bus_en;
+
+	/* DSC configuration */
+	struct drm_dsc_config *dsc;
+};
+
+#define to_dpu_encoder_virt(x) container_of(x, struct dpu_encoder_virt, base)
+
+static u32 dither_matrix[DITHER_MATRIX_SZ] = {
+	15, 7, 13, 5, 3, 11, 1, 9, 12, 4, 14, 6, 0, 8, 2, 10
+};
+
+u32 dpu_encoder_get_drm_fmt(struct dpu_encoder_phys *phys_enc)
+{
+	struct drm_encoder *drm_enc;
+	struct dpu_encoder_virt *dpu_enc;
+	struct drm_display_info *info;
+	struct drm_display_mode *mode;
+
+	drm_enc = phys_enc->parent;
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	info = &dpu_enc->connector->display_info;
+	mode = &phys_enc->cached_mode;
+
+	if (drm_mode_is_420_only(info, mode))
+		return DRM_FORMAT_YUV420;
+
+	return DRM_FORMAT_RGB888;
+}
+
+bool dpu_encoder_needs_periph_flush(struct dpu_encoder_phys *phys_enc)
+{
+	struct drm_encoder *drm_enc;
+	struct dpu_encoder_virt *dpu_enc;
+	struct msm_display_info *disp_info;
+	struct msm_drm_private *priv;
+	struct drm_display_mode *mode;
+
+	drm_enc = phys_enc->parent;
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	disp_info = &dpu_enc->disp_info;
+	priv = drm_enc->dev->dev_private;
+	mode = &phys_enc->cached_mode;
+
+	return phys_enc->hw_intf->cap->type == INTF_DP &&
+	       msm_dp_needs_periph_flush(priv->dp[disp_info->h_tile_instance[0]], mode);
+}
+
+bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc)
+{
+	const struct dpu_encoder_virt *dpu_enc;
+	struct msm_drm_private *priv = drm_enc->dev->dev_private;
+	const struct msm_display_info *disp_info;
+	int index;
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	disp_info = &dpu_enc->disp_info;
+	index = disp_info->h_tile_instance[0];
+
+	if (disp_info->intf_type == INTF_DP)
+		return msm_dp_wide_bus_available(priv->dp[index]);
+	else if (disp_info->intf_type == INTF_DSI)
+		return msm_dsi_wide_bus_enabled(priv->dsi[index]);
+
+	return false;
+}
+
+bool dpu_encoder_is_dsc_enabled(const struct drm_encoder *drm_enc)
+{
+	const struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+	return dpu_enc->dsc ? true : false;
+}
+
+int dpu_encoder_get_crc_values_cnt(const struct drm_encoder *drm_enc)
+{
+	struct dpu_encoder_virt *dpu_enc;
+	int i, num_intf = 0;
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+		if (phys->hw_intf && phys->hw_intf->ops.setup_misr
+				&& phys->hw_intf->ops.collect_misr)
+			num_intf++;
+	}
+
+	return num_intf;
+}
+
+void dpu_encoder_setup_misr(const struct drm_encoder *drm_enc)
+{
+	struct dpu_encoder_virt *dpu_enc;
+
+	int i;
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+		if (!phys->hw_intf || !phys->hw_intf->ops.setup_misr)
+			continue;
+
+		phys->hw_intf->ops.setup_misr(phys->hw_intf);
+	}
+}
+
+int dpu_encoder_get_crc(const struct drm_encoder *drm_enc, u32 *crcs, int pos)
+{
+	struct dpu_encoder_virt *dpu_enc;
+
+	int i, rc = 0, entries_added = 0;
+
+	if (!drm_enc->crtc) {
+		DRM_ERROR("no crtc found for encoder %d\n", drm_enc->index);
+		return -EINVAL;
+	}
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+		if (!phys->hw_intf || !phys->hw_intf->ops.collect_misr)
+			continue;
+
+		rc = phys->hw_intf->ops.collect_misr(phys->hw_intf, &crcs[pos + entries_added]);
+		if (rc)
+			return rc;
+		entries_added++;
+	}
+
+	return entries_added;
+}
+
+static void _dpu_encoder_setup_dither(struct dpu_hw_pingpong *hw_pp, unsigned bpc)
+{
+	struct dpu_hw_dither_cfg dither_cfg = { 0 };
+
+	if (!hw_pp->ops.setup_dither)
+		return;
+
+	switch (bpc) {
+	case 6:
+		dither_cfg.c0_bitdepth = 6;
+		dither_cfg.c1_bitdepth = 6;
+		dither_cfg.c2_bitdepth = 6;
+		dither_cfg.c3_bitdepth = 6;
+		dither_cfg.temporal_en = 0;
+		break;
+	default:
+		hw_pp->ops.setup_dither(hw_pp, NULL);
+		return;
+	}
+
+	memcpy(&dither_cfg.matrix, dither_matrix,
+			sizeof(u32) * DITHER_MATRIX_SZ);
+
+	hw_pp->ops.setup_dither(hw_pp, &dither_cfg);
+}
+
+static char *dpu_encoder_helper_get_intf_type(enum dpu_intf_mode intf_mode)
+{
+	switch (intf_mode) {
+	case INTF_MODE_VIDEO:
+		return "INTF_MODE_VIDEO";
+	case INTF_MODE_CMD:
+		return "INTF_MODE_CMD";
+	case INTF_MODE_WB_BLOCK:
+		return "INTF_MODE_WB_BLOCK";
+	case INTF_MODE_WB_LINE:
+		return "INTF_MODE_WB_LINE";
+	default:
+		return "INTF_MODE_UNKNOWN";
+	}
+}
+
+void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc,
+		enum dpu_intr_idx intr_idx)
+{
+	DRM_ERROR("irq timeout id=%u, intf_mode=%s intf=%d wb=%d, pp=%d, intr=%d\n",
+			DRMID(phys_enc->parent),
+			dpu_encoder_helper_get_intf_type(phys_enc->intf_mode),
+			phys_enc->hw_intf ? phys_enc->hw_intf->idx - INTF_0 : -1,
+			phys_enc->hw_wb ? phys_enc->hw_wb->idx - WB_0 : -1,
+			phys_enc->hw_pp->idx - PINGPONG_0, intr_idx);
+
+	dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc,
+				DPU_ENCODER_FRAME_EVENT_ERROR);
+}
+
+static int dpu_encoder_helper_wait_event_timeout(int32_t drm_id,
+		u32 irq_idx, struct dpu_encoder_wait_info *info);
+
+int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
+		unsigned int irq_idx,
+		void (*func)(void *arg),
+		struct dpu_encoder_wait_info *wait_info)
+{
+	u32 irq_status;
+	int ret;
+
+	if (!wait_info) {
+		DPU_ERROR("invalid params\n");
+		return -EINVAL;
+	}
+	/* note: do master / slave checking outside */
+
+	/* return EWOULDBLOCK since we know the wait isn't necessary */
+	if (phys_enc->enable_state == DPU_ENC_DISABLED) {
+		DRM_ERROR("encoder is disabled id=%u, callback=%ps, IRQ=[%d, %d]\n",
+			  DRMID(phys_enc->parent), func,
+			  DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+		return -EWOULDBLOCK;
+	}
+
+	if (irq_idx == 0) {
+		DRM_DEBUG_KMS("skip irq wait id=%u, callback=%ps\n",
+			      DRMID(phys_enc->parent), func);
+		return 0;
+	}
+
+	DRM_DEBUG_KMS("id=%u, callback=%ps, IRQ=[%d, %d], pp=%d, pending_cnt=%d\n",
+		      DRMID(phys_enc->parent), func,
+		      DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), phys_enc->hw_pp->idx - PINGPONG_0,
+		      atomic_read(wait_info->atomic_cnt));
+
+	ret = dpu_encoder_helper_wait_event_timeout(
+			DRMID(phys_enc->parent),
+			irq_idx,
+			wait_info);
+
+	if (ret <= 0) {
+		irq_status = dpu_core_irq_read(phys_enc->dpu_kms, irq_idx);
+		if (irq_status) {
+			unsigned long flags;
+
+			DRM_DEBUG_KMS("IRQ=[%d, %d] not triggered id=%u, callback=%ps, pp=%d, atomic_cnt=%d\n",
+				      DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx),
+				      DRMID(phys_enc->parent), func,
+				      phys_enc->hw_pp->idx - PINGPONG_0,
+				      atomic_read(wait_info->atomic_cnt));
+			local_irq_save(flags);
+			func(phys_enc);
+			local_irq_restore(flags);
+			ret = 0;
+		} else {
+			ret = -ETIMEDOUT;
+			DRM_DEBUG_KMS("IRQ=[%d, %d] timeout id=%u, callback=%ps, pp=%d, atomic_cnt=%d\n",
+				      DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx),
+				      DRMID(phys_enc->parent), func,
+				      phys_enc->hw_pp->idx - PINGPONG_0,
+				      atomic_read(wait_info->atomic_cnt));
+		}
+	} else {
+		ret = 0;
+		trace_dpu_enc_irq_wait_success(DRMID(phys_enc->parent),
+			func, DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx),
+			phys_enc->hw_pp->idx - PINGPONG_0,
+			atomic_read(wait_info->atomic_cnt));
+	}
+
+	return ret;
+}
+
+int dpu_encoder_get_vsync_count(struct drm_encoder *drm_enc)
+{
+	struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
+	struct dpu_encoder_phys *phys = dpu_enc ? dpu_enc->cur_master : NULL;
+	return phys ? atomic_read(&phys->vsync_cnt) : 0;
+}
+
+int dpu_encoder_get_linecount(struct drm_encoder *drm_enc)
+{
+	struct dpu_encoder_virt *dpu_enc;
+	struct dpu_encoder_phys *phys;
+	int linecount = 0;
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	phys = dpu_enc ? dpu_enc->cur_master : NULL;
+
+	if (phys && phys->ops.get_line_count)
+		linecount = phys->ops.get_line_count(phys);
+
+	return linecount;
+}
+
+void dpu_encoder_helper_split_config(
+		struct dpu_encoder_phys *phys_enc,
+		enum dpu_intf interface)
+{
+	struct dpu_encoder_virt *dpu_enc;
+	struct split_pipe_cfg cfg = { 0 };
+	struct dpu_hw_mdp *hw_mdptop;
+	struct msm_display_info *disp_info;
+
+	if (!phys_enc->hw_mdptop || !phys_enc->parent) {
+		DPU_ERROR("invalid arg(s), encoder %d\n", phys_enc != NULL);
+		return;
+	}
+
+	dpu_enc = to_dpu_encoder_virt(phys_enc->parent);
+	hw_mdptop = phys_enc->hw_mdptop;
+	disp_info = &dpu_enc->disp_info;
+
+	if (disp_info->intf_type != INTF_DSI)
+		return;
+
+	/**
+	 * disable split modes since encoder will be operating in as the only
+	 * encoder, either for the entire use case in the case of, for example,
+	 * single DSI, or for this frame in the case of left/right only partial
+	 * update.
+	 */
+	if (phys_enc->split_role == ENC_ROLE_SOLO) {
+		if (hw_mdptop->ops.setup_split_pipe)
+			hw_mdptop->ops.setup_split_pipe(hw_mdptop, &cfg);
+		return;
+	}
+
+	cfg.en = true;
+	cfg.mode = phys_enc->intf_mode;
+	cfg.intf = interface;
+
+	if (cfg.en && phys_enc->ops.needs_single_flush &&
+			phys_enc->ops.needs_single_flush(phys_enc))
+		cfg.split_flush_en = true;
+
+	if (phys_enc->split_role == ENC_ROLE_MASTER) {
+		DPU_DEBUG_ENC(dpu_enc, "enable %d\n", cfg.en);
+
+		if (hw_mdptop->ops.setup_split_pipe)
+			hw_mdptop->ops.setup_split_pipe(hw_mdptop, &cfg);
+	}
+}
+
+bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
+{
+	struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
+	int i, intf_count = 0, num_dsc = 0;
+
+	for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
+		if (dpu_enc->phys_encs[i])
+			intf_count++;
+
+	/* See dpu_encoder_get_topology, we only support 2:2:1 topology */
+	if (dpu_enc->dsc)
+		num_dsc = 2;
+
+	return (num_dsc > 0) && (num_dsc > intf_count);
+}
+
+static struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc)
+{
+	struct msm_drm_private *priv = drm_enc->dev->dev_private;
+	struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
+	int index = dpu_enc->disp_info.h_tile_instance[0];
+
+	if (dpu_enc->disp_info.intf_type == INTF_DSI)
+		return msm_dsi_get_dsc_config(priv->dsi[index]);
+
+	return NULL;
+}
+
+static struct msm_display_topology dpu_encoder_get_topology(
+			struct dpu_encoder_virt *dpu_enc,
+			struct dpu_kms *dpu_kms,
+			struct drm_display_mode *mode,
+			struct drm_crtc_state *crtc_state,
+			struct drm_dsc_config *dsc)
+{
+	struct msm_display_topology topology = {0};
+	int i, intf_count = 0;
+
+	for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
+		if (dpu_enc->phys_encs[i])
+			intf_count++;
+
+	/* Datapath topology selection
+	 *
+	 * Dual display
+	 * 2 LM, 2 INTF ( Split display using 2 interfaces)
+	 *
+	 * Single display
+	 * 1 LM, 1 INTF
+	 * 2 LM, 1 INTF (stream merge to support high resolution interfaces)
+	 *
+	 * Add dspps to the reservation requirements if ctm is requested
+	 */
+	if (intf_count == 2)
+		topology.num_lm = 2;
+	else if (!dpu_kms->catalog->caps->has_3d_merge)
+		topology.num_lm = 1;
+	else
+		topology.num_lm = (mode->hdisplay > dpu_kms->catalog->caps->max_mixer_width) ?
+				   2 : 1;
+
+	if (crtc_state->ctm)
+		topology.num_dspp = topology.num_lm;
+
+	topology.num_intf = intf_count;
+
+	if (dsc) {
+		/*
+		 * In case of Display Stream Compression (DSC), we would use
+		 * 2 DSC encoders, 2 layer mixers and 1 interface
+		 * this is power optimal and can drive up to (including) 4k
+		 * screens
+		 */
+		topology.num_dsc = 2;
+		topology.num_lm = 2;
+		topology.num_intf = 1;
+	}
+
+	return topology;
+}
+
+static void dpu_encoder_assign_crtc_resources(struct dpu_kms *dpu_kms,
+					      struct drm_encoder *drm_enc,
+					      struct dpu_global_state *global_state,
+					      struct drm_crtc_state *crtc_state)
+{
+	struct dpu_crtc_state *cstate;
+	struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
+	struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
+	struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC];
+	int num_lm, num_ctl, num_dspp, i;
+
+	cstate = to_dpu_crtc_state(crtc_state);
+
+	memset(cstate->mixers, 0, sizeof(cstate->mixers));
+
+	num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+		drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
+	num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+		drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
+	num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+		drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
+		ARRAY_SIZE(hw_dspp));
+
+	for (i = 0; i < num_lm; i++) {
+		int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
+
+		cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
+		cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
+		cstate->mixers[i].hw_dspp = i < num_dspp ? to_dpu_hw_dspp(hw_dspp[i]) : NULL;
+	}
+
+	cstate->num_mixers = num_lm;
+}
+
+static int dpu_encoder_virt_atomic_check(
+		struct drm_encoder *drm_enc,
+		struct drm_crtc_state *crtc_state,
+		struct drm_connector_state *conn_state)
+{
+	struct dpu_encoder_virt *dpu_enc;
+	struct msm_drm_private *priv;
+	struct dpu_kms *dpu_kms;
+	struct drm_display_mode *adj_mode;
+	struct msm_display_topology topology;
+	struct msm_display_info *disp_info;
+	struct dpu_global_state *global_state;
+	struct drm_framebuffer *fb;
+	struct drm_dsc_config *dsc;
+	int i = 0;
+	int ret = 0;
+
+	if (!drm_enc || !crtc_state || !conn_state) {
+		DPU_ERROR("invalid arg(s), drm_enc %d, crtc/conn state %d/%d\n",
+				drm_enc != NULL, crtc_state != NULL, conn_state != NULL);
+		return -EINVAL;
+	}
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	DPU_DEBUG_ENC(dpu_enc, "\n");
+
+	priv = drm_enc->dev->dev_private;
+	disp_info = &dpu_enc->disp_info;
+	dpu_kms = to_dpu_kms(priv->kms);
+	adj_mode = &crtc_state->adjusted_mode;
+	global_state = dpu_kms_get_global_state(crtc_state->state);
+	if (IS_ERR(global_state))
+		return PTR_ERR(global_state);
+
+	trace_dpu_enc_atomic_check(DRMID(drm_enc));
+
+	/* perform atomic check on the first physical encoder (master) */
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+		if (phys->ops.atomic_check)
+			ret = phys->ops.atomic_check(phys, crtc_state,
+					conn_state);
+		if (ret) {
+			DPU_ERROR_ENC(dpu_enc,
+					"mode unsupported, phys idx %d\n", i);
+			return ret;
+		}
+	}
+
+	dsc = dpu_encoder_get_dsc_config(drm_enc);
+
+	topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, dsc);
+
+	/*
+	 * Use CDM only for writeback or DP at the moment as other interfaces cannot handle it.
+	 * If writeback itself cannot handle cdm for some reason it will fail in its atomic_check()
+	 * earlier.
+	 */
+	if (disp_info->intf_type == INTF_WB && conn_state->writeback_job) {
+		fb = conn_state->writeback_job->fb;
+
+		if (fb && DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(fb))))
+			topology.needs_cdm = true;
+	} else if (disp_info->intf_type == INTF_DP) {
+		if (msm_dp_is_yuv_420_enabled(priv->dp[disp_info->h_tile_instance[0]], adj_mode))
+			topology.needs_cdm = true;
+	}
+
+	if (topology.needs_cdm && !dpu_enc->cur_master->hw_cdm)
+		crtc_state->mode_changed = true;
+	else if (!topology.needs_cdm && dpu_enc->cur_master->hw_cdm)
+		crtc_state->mode_changed = true;
+	/*
+	 * Release and Allocate resources on every modeset
+	 * Dont allocate when active is false.
+	 */
+	if (drm_atomic_crtc_needs_modeset(crtc_state)) {
+		dpu_rm_release(global_state, drm_enc);
+
+		if (!crtc_state->active_changed || crtc_state->enable)
+			ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
+					drm_enc, crtc_state, topology);
+		if (!ret)
+			dpu_encoder_assign_crtc_resources(dpu_kms, drm_enc,
+							  global_state, crtc_state);
+	}
+
+	trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
+
+	return ret;
+}
+
+static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
+			struct msm_display_info *disp_info)
+{
+	struct dpu_vsync_source_cfg vsync_cfg = { 0 };
+	struct msm_drm_private *priv;
+	struct dpu_kms *dpu_kms;
+	struct dpu_hw_mdp *hw_mdptop;
+	struct drm_encoder *drm_enc;
+	struct dpu_encoder_phys *phys_enc;
+	int i;
+
+	if (!dpu_enc || !disp_info) {
+		DPU_ERROR("invalid param dpu_enc:%d or disp_info:%d\n",
+					dpu_enc != NULL, disp_info != NULL);
+		return;
+	} else if (dpu_enc->num_phys_encs > ARRAY_SIZE(dpu_enc->hw_pp)) {
+		DPU_ERROR("invalid num phys enc %d/%d\n",
+				dpu_enc->num_phys_encs,
+				(int) ARRAY_SIZE(dpu_enc->hw_pp));
+		return;
+	}
+
+	drm_enc = &dpu_enc->base;
+	/* this pointers are checked in virt_enable_helper */
+	priv = drm_enc->dev->dev_private;
+
+	dpu_kms = to_dpu_kms(priv->kms);
+	hw_mdptop = dpu_kms->hw_mdp;
+	if (!hw_mdptop) {
+		DPU_ERROR("invalid mdptop\n");
+		return;
+	}
+
+	if (hw_mdptop->ops.setup_vsync_source &&
+			disp_info->is_cmd_mode) {
+		for (i = 0; i < dpu_enc->num_phys_encs; i++)
+			vsync_cfg.ppnumber[i] = dpu_enc->hw_pp[i]->idx;
+
+		vsync_cfg.pp_count = dpu_enc->num_phys_encs;
+		vsync_cfg.frame_rate = drm_mode_vrefresh(&dpu_enc->base.crtc->state->adjusted_mode);
+
+		if (disp_info->is_te_using_watchdog_timer)
+			vsync_cfg.vsync_source = DPU_VSYNC_SOURCE_WD_TIMER_0;
+		else
+			vsync_cfg.vsync_source = DPU_VSYNC0_SOURCE_GPIO;
+
+		hw_mdptop->ops.setup_vsync_source(hw_mdptop, &vsync_cfg);
+
+		for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+			phys_enc = dpu_enc->phys_encs[i];
+
+			if (phys_enc->has_intf_te && phys_enc->hw_intf->ops.vsync_sel)
+				phys_enc->hw_intf->ops.vsync_sel(phys_enc->hw_intf,
+						vsync_cfg.vsync_source);
+		}
+	}
+}
+
+static void _dpu_encoder_irq_control(struct drm_encoder *drm_enc, bool enable)
+{
+	struct dpu_encoder_virt *dpu_enc;
+	int i;
+
+	if (!drm_enc) {
+		DPU_ERROR("invalid encoder\n");
+		return;
+	}
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+	DPU_DEBUG_ENC(dpu_enc, "enable:%d\n", enable);
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+		if (phys->ops.irq_control)
+			phys->ops.irq_control(phys, enable);
+	}
+
+}
+
+static void _dpu_encoder_resource_control_helper(struct drm_encoder *drm_enc,
+		bool enable)
+{
+	struct msm_drm_private *priv;
+	struct dpu_kms *dpu_kms;
+	struct dpu_encoder_virt *dpu_enc;
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	priv = drm_enc->dev->dev_private;
+	dpu_kms = to_dpu_kms(priv->kms);
+
+	trace_dpu_enc_rc_helper(DRMID(drm_enc), enable);
+
+	if (!dpu_enc->cur_master) {
+		DPU_ERROR("encoder master not set\n");
+		return;
+	}
+
+	if (enable) {
+		/* enable DPU core clks */
+		pm_runtime_get_sync(&dpu_kms->pdev->dev);
+
+		/* enable all the irq */
+		_dpu_encoder_irq_control(drm_enc, true);
+
+	} else {
+		/* disable all the irq */
+		_dpu_encoder_irq_control(drm_enc, false);
+
+		/* disable DPU core clks */
+		pm_runtime_put_sync(&dpu_kms->pdev->dev);
+	}
+
+}
+
+static int dpu_encoder_resource_control(struct drm_encoder *drm_enc,
+		u32 sw_event)
+{
+	struct dpu_encoder_virt *dpu_enc;
+	struct msm_drm_private *priv;
+	bool is_vid_mode = false;
+
+	if (!drm_enc || !drm_enc->dev || !drm_enc->crtc) {
+		DPU_ERROR("invalid parameters\n");
+		return -EINVAL;
+	}
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	priv = drm_enc->dev->dev_private;
+	is_vid_mode = !dpu_enc->disp_info.is_cmd_mode;
+
+	/*
+	 * when idle_pc is not supported, process only KICKOFF, STOP and MODESET
+	 * events and return early for other events (ie wb display).
+	 */
+	if (!dpu_enc->idle_pc_supported &&
+			(sw_event != DPU_ENC_RC_EVENT_KICKOFF &&
+			sw_event != DPU_ENC_RC_EVENT_STOP &&
+			sw_event != DPU_ENC_RC_EVENT_PRE_STOP))
+		return 0;
+
+	trace_dpu_enc_rc(DRMID(drm_enc), sw_event, dpu_enc->idle_pc_supported,
+			 dpu_enc->rc_state, "begin");
+
+	switch (sw_event) {
+	case DPU_ENC_RC_EVENT_KICKOFF:
+		/* cancel delayed off work, if any */
+		if (cancel_delayed_work_sync(&dpu_enc->delayed_off_work))
+			DPU_DEBUG_ENC(dpu_enc, "sw_event:%d, work cancelled\n",
+					sw_event);
+
+		mutex_lock(&dpu_enc->rc_lock);
+
+		/* return if the resource control is already in ON state */
+		if (dpu_enc->rc_state == DPU_ENC_RC_STATE_ON) {
+			DRM_DEBUG_ATOMIC("id;%u, sw_event:%d, rc in ON state\n",
+				      DRMID(drm_enc), sw_event);
+			mutex_unlock(&dpu_enc->rc_lock);
+			return 0;
+		} else if (dpu_enc->rc_state != DPU_ENC_RC_STATE_OFF &&
+				dpu_enc->rc_state != DPU_ENC_RC_STATE_IDLE) {
+			DRM_DEBUG_ATOMIC("id;%u, sw_event:%d, rc in state %d\n",
+				      DRMID(drm_enc), sw_event,
+				      dpu_enc->rc_state);
+			mutex_unlock(&dpu_enc->rc_lock);
+			return -EINVAL;
+		}
+
+		if (is_vid_mode && dpu_enc->rc_state == DPU_ENC_RC_STATE_IDLE)
+			_dpu_encoder_irq_control(drm_enc, true);
+		else
+			_dpu_encoder_resource_control_helper(drm_enc, true);
+
+		dpu_enc->rc_state = DPU_ENC_RC_STATE_ON;
+
+		trace_dpu_enc_rc(DRMID(drm_enc), sw_event,
+				 dpu_enc->idle_pc_supported, dpu_enc->rc_state,
+				 "kickoff");
+
+		mutex_unlock(&dpu_enc->rc_lock);
+		break;
+
+	case DPU_ENC_RC_EVENT_FRAME_DONE:
+		/*
+		 * mutex lock is not used as this event happens at interrupt
+		 * context. And locking is not required as, the other events
+		 * like KICKOFF and STOP does a wait-for-idle before executing
+		 * the resource_control
+		 */
+		if (dpu_enc->rc_state != DPU_ENC_RC_STATE_ON) {
+			DRM_DEBUG_KMS("id:%d, sw_event:%d,rc:%d-unexpected\n",
+				      DRMID(drm_enc), sw_event,
+				      dpu_enc->rc_state);
+			return -EINVAL;
+		}
+
+		/*
+		 * schedule off work item only when there are no
+		 * frames pending
+		 */
+		if (dpu_crtc_frame_pending(drm_enc->crtc) > 1) {
+			DRM_DEBUG_KMS("id:%d skip schedule work\n",
+				      DRMID(drm_enc));
+			return 0;
+		}
+
+		queue_delayed_work(priv->wq, &dpu_enc->delayed_off_work,
+				   msecs_to_jiffies(dpu_enc->idle_timeout));
+
+		trace_dpu_enc_rc(DRMID(drm_enc), sw_event,
+				 dpu_enc->idle_pc_supported, dpu_enc->rc_state,
+				 "frame done");
+		break;
+
+	case DPU_ENC_RC_EVENT_PRE_STOP:
+		/* cancel delayed off work, if any */
+		if (cancel_delayed_work_sync(&dpu_enc->delayed_off_work))
+			DPU_DEBUG_ENC(dpu_enc, "sw_event:%d, work cancelled\n",
+					sw_event);
+
+		mutex_lock(&dpu_enc->rc_lock);
+
+		if (is_vid_mode &&
+			  dpu_enc->rc_state == DPU_ENC_RC_STATE_IDLE) {
+			_dpu_encoder_irq_control(drm_enc, true);
+		}
+		/* skip if is already OFF or IDLE, resources are off already */
+		else if (dpu_enc->rc_state == DPU_ENC_RC_STATE_OFF ||
+				dpu_enc->rc_state == DPU_ENC_RC_STATE_IDLE) {
+			DRM_DEBUG_KMS("id:%u, sw_event:%d, rc in %d state\n",
+				      DRMID(drm_enc), sw_event,
+				      dpu_enc->rc_state);
+			mutex_unlock(&dpu_enc->rc_lock);
+			return 0;
+		}
+
+		dpu_enc->rc_state = DPU_ENC_RC_STATE_PRE_OFF;
+
+		trace_dpu_enc_rc(DRMID(drm_enc), sw_event,
+				 dpu_enc->idle_pc_supported, dpu_enc->rc_state,
+				 "pre stop");
+
+		mutex_unlock(&dpu_enc->rc_lock);
+		break;
+
+	case DPU_ENC_RC_EVENT_STOP:
+		mutex_lock(&dpu_enc->rc_lock);
+
+		/* return if the resource control is already in OFF state */
+		if (dpu_enc->rc_state == DPU_ENC_RC_STATE_OFF) {
+			DRM_DEBUG_KMS("id: %u, sw_event:%d, rc in OFF state\n",
+				      DRMID(drm_enc), sw_event);
+			mutex_unlock(&dpu_enc->rc_lock);
+			return 0;
+		} else if (dpu_enc->rc_state == DPU_ENC_RC_STATE_ON) {
+			DRM_ERROR("id: %u, sw_event:%d, rc in state %d\n",
+				  DRMID(drm_enc), sw_event, dpu_enc->rc_state);
+			mutex_unlock(&dpu_enc->rc_lock);
+			return -EINVAL;
+		}
+
+		/**
+		 * expect to arrive here only if in either idle state or pre-off
+		 * and in IDLE state the resources are already disabled
+		 */
+		if (dpu_enc->rc_state == DPU_ENC_RC_STATE_PRE_OFF)
+			_dpu_encoder_resource_control_helper(drm_enc, false);
+
+		dpu_enc->rc_state = DPU_ENC_RC_STATE_OFF;
+
+		trace_dpu_enc_rc(DRMID(drm_enc), sw_event,
+				 dpu_enc->idle_pc_supported, dpu_enc->rc_state,
+				 "stop");
+
+		mutex_unlock(&dpu_enc->rc_lock);
+		break;
+
+	case DPU_ENC_RC_EVENT_ENTER_IDLE:
+		mutex_lock(&dpu_enc->rc_lock);
+
+		if (dpu_enc->rc_state != DPU_ENC_RC_STATE_ON) {
+			DRM_ERROR("id: %u, sw_event:%d, rc:%d !ON state\n",
+				  DRMID(drm_enc), sw_event, dpu_enc->rc_state);
+			mutex_unlock(&dpu_enc->rc_lock);
+			return 0;
+		}
+
+		/*
+		 * if we are in ON but a frame was just kicked off,
+		 * ignore the IDLE event, it's probably a stale timer event
+		 */
+		if (dpu_enc->frame_busy_mask[0]) {
+			DRM_ERROR("id:%u, sw_event:%d, rc:%d frame pending\n",
+				  DRMID(drm_enc), sw_event, dpu_enc->rc_state);
+			mutex_unlock(&dpu_enc->rc_lock);
+			return 0;
+		}
+
+		if (is_vid_mode)
+			_dpu_encoder_irq_control(drm_enc, false);
+		else
+			_dpu_encoder_resource_control_helper(drm_enc, false);
+
+		dpu_enc->rc_state = DPU_ENC_RC_STATE_IDLE;
+
+		trace_dpu_enc_rc(DRMID(drm_enc), sw_event,
+				 dpu_enc->idle_pc_supported, dpu_enc->rc_state,
+				 "idle");
+
+		mutex_unlock(&dpu_enc->rc_lock);
+		break;
+
+	default:
+		DRM_ERROR("id:%u, unexpected sw_event: %d\n", DRMID(drm_enc),
+			  sw_event);
+		trace_dpu_enc_rc(DRMID(drm_enc), sw_event,
+				 dpu_enc->idle_pc_supported, dpu_enc->rc_state,
+				 "error");
+		break;
+	}
+
+	trace_dpu_enc_rc(DRMID(drm_enc), sw_event,
+			 dpu_enc->idle_pc_supported, dpu_enc->rc_state,
+			 "end");
+	return 0;
+}
+
+void dpu_encoder_prepare_wb_job(struct drm_encoder *drm_enc,
+		struct drm_writeback_job *job)
+{
+	struct dpu_encoder_virt *dpu_enc;
+	int i;
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+		if (phys->ops.prepare_wb_job)
+			phys->ops.prepare_wb_job(phys, job);
+
+	}
+}
+
+void dpu_encoder_cleanup_wb_job(struct drm_encoder *drm_enc,
+		struct drm_writeback_job *job)
+{
+	struct dpu_encoder_virt *dpu_enc;
+	int i;
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+		if (phys->ops.cleanup_wb_job)
+			phys->ops.cleanup_wb_job(phys, job);
+
+	}
+}
+
+static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc,
+					     struct drm_crtc_state *crtc_state,
+					     struct drm_connector_state *conn_state)
+{
+	struct dpu_encoder_virt *dpu_enc;
+	struct msm_drm_private *priv;
+	struct dpu_kms *dpu_kms;
+	struct dpu_global_state *global_state;
+	struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
+	struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
+	struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
+	int num_ctl, num_pp, num_dsc;
+	unsigned int dsc_mask = 0;
+	int i;
+
+	if (!drm_enc) {
+		DPU_ERROR("invalid encoder\n");
+		return;
+	}
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	DPU_DEBUG_ENC(dpu_enc, "\n");
+
+	priv = drm_enc->dev->dev_private;
+	dpu_kms = to_dpu_kms(priv->kms);
+
+	global_state = dpu_kms_get_existing_global_state(dpu_kms);
+	if (IS_ERR_OR_NULL(global_state)) {
+		DPU_ERROR("Failed to get global state");
+		return;
+	}
+
+	trace_dpu_enc_mode_set(DRMID(drm_enc));
+
+	/* Query resource that have been reserved in atomic check step. */
+	num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+		drm_enc->base.id, DPU_HW_BLK_PINGPONG, hw_pp,
+		ARRAY_SIZE(hw_pp));
+	num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+		drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
+
+	for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
+		dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
+						: NULL;
+
+	num_dsc = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+						drm_enc->base.id, DPU_HW_BLK_DSC,
+						hw_dsc, ARRAY_SIZE(hw_dsc));
+	for (i = 0; i < num_dsc; i++) {
+		dpu_enc->hw_dsc[i] = to_dpu_hw_dsc(hw_dsc[i]);
+		dsc_mask |= BIT(dpu_enc->hw_dsc[i]->idx - DSC_0);
+	}
+
+	dpu_enc->dsc_mask = dsc_mask;
+
+	if ((dpu_enc->disp_info.intf_type == INTF_WB && conn_state->writeback_job) ||
+	    dpu_enc->disp_info.intf_type == INTF_DP) {
+		struct dpu_hw_blk *hw_cdm = NULL;
+
+		dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+					      drm_enc->base.id, DPU_HW_BLK_CDM,
+					      &hw_cdm, 1);
+		dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL;
+	}
+
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+		phys->hw_pp = dpu_enc->hw_pp[i];
+		if (!phys->hw_pp) {
+			DPU_ERROR_ENC(dpu_enc,
+				"no pp block assigned at idx: %d\n", i);
+			return;
+		}
+
+		phys->hw_ctl = i < num_ctl ? to_dpu_hw_ctl(hw_ctl[i]) : NULL;
+		if (!phys->hw_ctl) {
+			DPU_ERROR_ENC(dpu_enc,
+				"no ctl block assigned at idx: %d\n", i);
+			return;
+		}
+
+		phys->cached_mode = crtc_state->adjusted_mode;
+		if (phys->ops.atomic_mode_set)
+			phys->ops.atomic_mode_set(phys, crtc_state, conn_state);
+	}
+}
+
+static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc)
+{
+	struct dpu_encoder_virt *dpu_enc = NULL;
+	int i;
+
+	if (!drm_enc || !drm_enc->dev) {
+		DPU_ERROR("invalid parameters\n");
+		return;
+	}
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	if (!dpu_enc || !dpu_enc->cur_master) {
+		DPU_ERROR("invalid dpu encoder/master\n");
+		return;
+	}
+
+
+	if (dpu_enc->disp_info.intf_type == INTF_DP &&
+		dpu_enc->cur_master->hw_mdptop &&
+		dpu_enc->cur_master->hw_mdptop->ops.intf_audio_select)
+		dpu_enc->cur_master->hw_mdptop->ops.intf_audio_select(
+			dpu_enc->cur_master->hw_mdptop);
+
+	_dpu_encoder_update_vsync_source(dpu_enc, &dpu_enc->disp_info);
+
+	if (dpu_enc->disp_info.intf_type == INTF_DSI &&
+			!WARN_ON(dpu_enc->num_phys_encs == 0)) {
+		unsigned bpc = dpu_enc->connector->display_info.bpc;
+		for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
+			if (!dpu_enc->hw_pp[i])
+				continue;
+			_dpu_encoder_setup_dither(dpu_enc->hw_pp[i], bpc);
+		}
+	}
+}
+
+void dpu_encoder_virt_runtime_resume(struct drm_encoder *drm_enc)
+{
+	struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+	mutex_lock(&dpu_enc->enc_lock);
+
+	if (!dpu_enc->enabled)
+		goto out;
+
+	if (dpu_enc->cur_slave && dpu_enc->cur_slave->ops.restore)
+		dpu_enc->cur_slave->ops.restore(dpu_enc->cur_slave);
+	if (dpu_enc->cur_master && dpu_enc->cur_master->ops.restore)
+		dpu_enc->cur_master->ops.restore(dpu_enc->cur_master);
+
+	_dpu_encoder_virt_enable_helper(drm_enc);
+
+out:
+	mutex_unlock(&dpu_enc->enc_lock);
+}
+
+static void dpu_encoder_virt_atomic_enable(struct drm_encoder *drm_enc,
+					struct drm_atomic_state *state)
+{
+	struct dpu_encoder_virt *dpu_enc = NULL;
+	int ret = 0;
+	struct drm_display_mode *cur_mode = NULL;
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	dpu_enc->dsc = dpu_encoder_get_dsc_config(drm_enc);
+
+	atomic_set(&dpu_enc->frame_done_timeout_cnt, 0);
+
+	mutex_lock(&dpu_enc->enc_lock);
+
+	dpu_enc->commit_done_timedout = false;
+
+	dpu_enc->connector = drm_atomic_get_new_connector_for_encoder(state, drm_enc);
+
+	cur_mode = &dpu_enc->base.crtc->state->adjusted_mode;
+
+	dpu_enc->wide_bus_en = dpu_encoder_is_widebus_enabled(drm_enc);
+
+	trace_dpu_enc_enable(DRMID(drm_enc), cur_mode->hdisplay,
+			     cur_mode->vdisplay);
+
+	/* always enable slave encoder before master */
+	if (dpu_enc->cur_slave && dpu_enc->cur_slave->ops.enable)
+		dpu_enc->cur_slave->ops.enable(dpu_enc->cur_slave);
+
+	if (dpu_enc->cur_master && dpu_enc->cur_master->ops.enable)
+		dpu_enc->cur_master->ops.enable(dpu_enc->cur_master);
+
+	ret = dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_KICKOFF);
+	if (ret) {
+		DPU_ERROR_ENC(dpu_enc, "dpu resource control failed: %d\n",
+				ret);
+		goto out;
+	}
+
+	_dpu_encoder_virt_enable_helper(drm_enc);
+
+	dpu_enc->enabled = true;
+
+out:
+	mutex_unlock(&dpu_enc->enc_lock);
+}
+
+static void dpu_encoder_virt_atomic_disable(struct drm_encoder *drm_enc,
+					struct drm_atomic_state *state)
+{
+	struct dpu_encoder_virt *dpu_enc = NULL;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *old_state = NULL;
+	int i = 0;
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	DPU_DEBUG_ENC(dpu_enc, "\n");
+
+	crtc = drm_atomic_get_old_crtc_for_encoder(state, drm_enc);
+	if (crtc)
+		old_state = drm_atomic_get_old_crtc_state(state, crtc);
+
+	/*
+	 * The encoder is already disabled if self refresh mode was set earlier,
+	 * in the old_state for the corresponding crtc.
+	 */
+	if (old_state && old_state->self_refresh_active)
+		return;
+
+	mutex_lock(&dpu_enc->enc_lock);
+	dpu_enc->enabled = false;
+
+	trace_dpu_enc_disable(DRMID(drm_enc));
+
+	/* wait for idle */
+	dpu_encoder_wait_for_tx_complete(drm_enc);
+
+	dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_PRE_STOP);
+
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+		if (phys->ops.disable)
+			phys->ops.disable(phys);
+	}
+
+
+	/* after phys waits for frame-done, should be no more frames pending */
+	if (atomic_xchg(&dpu_enc->frame_done_timeout_ms, 0)) {
+		DPU_ERROR("enc%d timeout pending\n", drm_enc->base.id);
+		del_timer_sync(&dpu_enc->frame_done_timer);
+	}
+
+	dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_STOP);
+
+	dpu_enc->connector = NULL;
+
+	DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n");
+
+	mutex_unlock(&dpu_enc->enc_lock);
+}
+
+static struct dpu_hw_intf *dpu_encoder_get_intf(const struct dpu_mdss_cfg *catalog,
+		struct dpu_rm *dpu_rm,
+		enum dpu_intf_type type, u32 controller_id)
+{
+	int i = 0;
+
+	if (type == INTF_WB)
+		return NULL;
+
+	for (i = 0; i < catalog->intf_count; i++) {
+		if (catalog->intf[i].type == type
+		    && catalog->intf[i].controller_id == controller_id) {
+			return dpu_rm_get_intf(dpu_rm, catalog->intf[i].id);
+		}
+	}
+
+	return NULL;
+}
+
+void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
+		struct dpu_encoder_phys *phy_enc)
+{
+	struct dpu_encoder_virt *dpu_enc = NULL;
+	unsigned long lock_flags;
+
+	if (!drm_enc || !phy_enc)
+		return;
+
+	DPU_ATRACE_BEGIN("encoder_vblank_callback");
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+	atomic_inc(&phy_enc->vsync_cnt);
+
+	spin_lock_irqsave(&dpu_enc->enc_spinlock, lock_flags);
+	if (dpu_enc->crtc)
+		dpu_crtc_vblank_callback(dpu_enc->crtc);
+	spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags);
+
+	DPU_ATRACE_END("encoder_vblank_callback");
+}
+
+void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc,
+		struct dpu_encoder_phys *phy_enc)
+{
+	if (!phy_enc)
+		return;
+
+	DPU_ATRACE_BEGIN("encoder_underrun_callback");
+	atomic_inc(&phy_enc->underrun_cnt);
+
+	/* trigger dump only on the first underrun */
+	if (atomic_read(&phy_enc->underrun_cnt) == 1)
+		msm_disp_snapshot_state(drm_enc->dev);
+
+	trace_dpu_enc_underrun_cb(DRMID(drm_enc),
+				  atomic_read(&phy_enc->underrun_cnt));
+	DPU_ATRACE_END("encoder_underrun_callback");
+}
+
+void dpu_encoder_assign_crtc(struct drm_encoder *drm_enc, struct drm_crtc *crtc)
+{
+	struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
+	unsigned long lock_flags;
+
+	spin_lock_irqsave(&dpu_enc->enc_spinlock, lock_flags);
+	/* crtc should always be cleared before re-assigning */
+	WARN_ON(crtc && dpu_enc->crtc);
+	dpu_enc->crtc = crtc;
+	spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags);
+}
+
+void dpu_encoder_toggle_vblank_for_crtc(struct drm_encoder *drm_enc,
+					struct drm_crtc *crtc, bool enable)
+{
+	struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
+	unsigned long lock_flags;
+	int i;
+
+	trace_dpu_enc_vblank_cb(DRMID(drm_enc), enable);
+
+	spin_lock_irqsave(&dpu_enc->enc_spinlock, lock_flags);
+	if (dpu_enc->crtc != crtc) {
+		spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags);
+		return;
+	}
+	spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags);
+
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+		if (phys->ops.control_vblank_irq)
+			phys->ops.control_vblank_irq(phys, enable);
+	}
+}
+
+void dpu_encoder_frame_done_callback(
+		struct drm_encoder *drm_enc,
+		struct dpu_encoder_phys *ready_phys, u32 event)
+{
+	struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
+	unsigned int i;
+
+	if (event & (DPU_ENCODER_FRAME_EVENT_DONE
+			| DPU_ENCODER_FRAME_EVENT_ERROR
+			| DPU_ENCODER_FRAME_EVENT_PANEL_DEAD)) {
+
+		if (!dpu_enc->frame_busy_mask[0]) {
+			/**
+			 * suppress frame_done without waiter,
+			 * likely autorefresh
+			 */
+			trace_dpu_enc_frame_done_cb_not_busy(DRMID(drm_enc), event,
+					dpu_encoder_helper_get_intf_type(ready_phys->intf_mode),
+					ready_phys->hw_intf ? ready_phys->hw_intf->idx : -1,
+					ready_phys->hw_wb ? ready_phys->hw_wb->idx : -1);
+			return;
+		}
+
+		/* One of the physical encoders has become idle */
+		for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+			if (dpu_enc->phys_encs[i] == ready_phys) {
+				trace_dpu_enc_frame_done_cb(DRMID(drm_enc), i,
+						dpu_enc->frame_busy_mask[0]);
+				clear_bit(i, dpu_enc->frame_busy_mask);
+			}
+		}
+
+		if (!dpu_enc->frame_busy_mask[0]) {
+			atomic_set(&dpu_enc->frame_done_timeout_ms, 0);
+			del_timer(&dpu_enc->frame_done_timer);
+
+			dpu_encoder_resource_control(drm_enc,
+					DPU_ENC_RC_EVENT_FRAME_DONE);
+
+			if (dpu_enc->crtc)
+				dpu_crtc_frame_event_cb(dpu_enc->crtc, event);
+		}
+	} else {
+		if (dpu_enc->crtc)
+			dpu_crtc_frame_event_cb(dpu_enc->crtc, event);
+	}
+}
+
+static void dpu_encoder_off_work(struct work_struct *work)
+{
+	struct dpu_encoder_virt *dpu_enc = container_of(work,
+			struct dpu_encoder_virt, delayed_off_work.work);
+
+	dpu_encoder_resource_control(&dpu_enc->base,
+						DPU_ENC_RC_EVENT_ENTER_IDLE);
+
+	dpu_encoder_frame_done_callback(&dpu_enc->base, NULL,
+				DPU_ENCODER_FRAME_EVENT_IDLE);
+}
+
+/**
+ * _dpu_encoder_trigger_flush - trigger flush for a physical encoder
+ * @drm_enc: Pointer to drm encoder structure
+ * @phys: Pointer to physical encoder structure
+ * @extra_flush_bits: Additional bit mask to include in flush trigger
+ */
+static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc,
+		struct dpu_encoder_phys *phys, uint32_t extra_flush_bits)
+{
+	struct dpu_hw_ctl *ctl;
+	int pending_kickoff_cnt;
+	u32 ret = UINT_MAX;
+
+	if (!phys->hw_pp) {
+		DPU_ERROR("invalid pingpong hw\n");
+		return;
+	}
+
+	ctl = phys->hw_ctl;
+	if (!ctl->ops.trigger_flush) {
+		DPU_ERROR("missing trigger cb\n");
+		return;
+	}
+
+	pending_kickoff_cnt = dpu_encoder_phys_inc_pending(phys);
+
+	if (extra_flush_bits && ctl->ops.update_pending_flush)
+		ctl->ops.update_pending_flush(ctl, extra_flush_bits);
+
+	ctl->ops.trigger_flush(ctl);
+
+	if (ctl->ops.get_pending_flush)
+		ret = ctl->ops.get_pending_flush(ctl);
+
+	trace_dpu_enc_trigger_flush(DRMID(drm_enc),
+			dpu_encoder_helper_get_intf_type(phys->intf_mode),
+			phys->hw_intf ? phys->hw_intf->idx : -1,
+			phys->hw_wb ? phys->hw_wb->idx : -1,
+			pending_kickoff_cnt, ctl->idx,
+			extra_flush_bits, ret);
+}
+
+/**
+ * _dpu_encoder_trigger_start - trigger start for a physical encoder
+ * @phys: Pointer to physical encoder structure
+ */
+static void _dpu_encoder_trigger_start(struct dpu_encoder_phys *phys)
+{
+	if (!phys) {
+		DPU_ERROR("invalid argument(s)\n");
+		return;
+	}
+
+	if (!phys->hw_pp) {
+		DPU_ERROR("invalid pingpong hw\n");
+		return;
+	}
+
+	if (phys->ops.trigger_start && phys->enable_state != DPU_ENC_DISABLED)
+		phys->ops.trigger_start(phys);
+}
+
+void dpu_encoder_helper_trigger_start(struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_ctl *ctl;
+
+	ctl = phys_enc->hw_ctl;
+	if (ctl->ops.trigger_start) {
+		ctl->ops.trigger_start(ctl);
+		trace_dpu_enc_trigger_start(DRMID(phys_enc->parent), ctl->idx);
+	}
+}
+
+static int dpu_encoder_helper_wait_event_timeout(
+		int32_t drm_id,
+		unsigned int irq_idx,
+		struct dpu_encoder_wait_info *info)
+{
+	int rc = 0;
+	s64 expected_time = ktime_to_ms(ktime_get()) + info->timeout_ms;
+	s64 jiffies = msecs_to_jiffies(info->timeout_ms);
+	s64 time;
+
+	do {
+		rc = wait_event_timeout(*(info->wq),
+				atomic_read(info->atomic_cnt) == 0, jiffies);
+		time = ktime_to_ms(ktime_get());
+
+		trace_dpu_enc_wait_event_timeout(drm_id,
+						 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx),
+						 rc, time,
+						 expected_time,
+						 atomic_read(info->atomic_cnt));
+	/* If we timed out, counter is valid and time is less, wait again */
+	} while (atomic_read(info->atomic_cnt) && (rc == 0) &&
+			(time < expected_time));
+
+	return rc;
+}
+
+static void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_encoder_virt *dpu_enc;
+	struct dpu_hw_ctl *ctl;
+	int rc;
+	struct drm_encoder *drm_enc;
+
+	dpu_enc = to_dpu_encoder_virt(phys_enc->parent);
+	ctl = phys_enc->hw_ctl;
+	drm_enc = phys_enc->parent;
+
+	if (!ctl->ops.reset)
+		return;
+
+	DRM_DEBUG_KMS("id:%u ctl %d reset\n", DRMID(drm_enc),
+		      ctl->idx);
+
+	rc = ctl->ops.reset(ctl);
+	if (rc) {
+		DPU_ERROR_ENC(dpu_enc, "ctl %d reset failure\n",  ctl->idx);
+		msm_disp_snapshot_state(drm_enc->dev);
+	}
+
+	phys_enc->enable_state = DPU_ENC_ENABLED;
+}
+
+/**
+ * _dpu_encoder_kickoff_phys - handle physical encoder kickoff
+ *	Iterate through the physical encoders and perform consolidated flush
+ *	and/or control start triggering as needed. This is done in the virtual
+ *	encoder rather than the individual physical ones in order to handle
+ *	use cases that require visibility into multiple physical encoders at
+ *	a time.
+ * @dpu_enc: Pointer to virtual encoder structure
+ */
+static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc)
+{
+	struct dpu_hw_ctl *ctl;
+	uint32_t i, pending_flush;
+	unsigned long lock_flags;
+
+	pending_flush = 0x0;
+
+	/* update pending counts and trigger kickoff ctl flush atomically */
+	spin_lock_irqsave(&dpu_enc->enc_spinlock, lock_flags);
+
+	/* don't perform flush/start operations for slave encoders */
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+		if (phys->enable_state == DPU_ENC_DISABLED)
+			continue;
+
+		ctl = phys->hw_ctl;
+
+		/*
+		 * This is cleared in frame_done worker, which isn't invoked
+		 * for async commits. So don't set this for async, since it'll
+		 * roll over to the next commit.
+		 */
+		if (phys->split_role != ENC_ROLE_SLAVE)
+			set_bit(i, dpu_enc->frame_busy_mask);
+
+		if (!phys->ops.needs_single_flush ||
+				!phys->ops.needs_single_flush(phys))
+			_dpu_encoder_trigger_flush(&dpu_enc->base, phys, 0x0);
+		else if (ctl->ops.get_pending_flush)
+			pending_flush |= ctl->ops.get_pending_flush(ctl);
+	}
+
+	/* for split flush, combine pending flush masks and send to master */
+	if (pending_flush && dpu_enc->cur_master) {
+		_dpu_encoder_trigger_flush(
+				&dpu_enc->base,
+				dpu_enc->cur_master,
+				pending_flush);
+	}
+
+	_dpu_encoder_trigger_start(dpu_enc->cur_master);
+
+	spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags);
+}
+
+void dpu_encoder_trigger_kickoff_pending(struct drm_encoder *drm_enc)
+{
+	struct dpu_encoder_virt *dpu_enc;
+	struct dpu_encoder_phys *phys;
+	unsigned int i;
+	struct dpu_hw_ctl *ctl;
+	struct msm_display_info *disp_info;
+
+	if (!drm_enc) {
+		DPU_ERROR("invalid encoder\n");
+		return;
+	}
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	disp_info = &dpu_enc->disp_info;
+
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		phys = dpu_enc->phys_encs[i];
+
+		ctl = phys->hw_ctl;
+		ctl->ops.clear_pending_flush(ctl);
+
+		/* update only for command mode primary ctl */
+		if ((phys == dpu_enc->cur_master) &&
+		    disp_info->is_cmd_mode
+		    && ctl->ops.trigger_pending)
+			ctl->ops.trigger_pending(ctl);
+	}
+}
+
+static u32 _dpu_encoder_calculate_linetime(struct dpu_encoder_virt *dpu_enc,
+		struct drm_display_mode *mode)
+{
+	u64 pclk_rate;
+	u32 pclk_period;
+	u32 line_time;
+
+	/*
+	 * For linetime calculation, only operate on master encoder.
+	 */
+	if (!dpu_enc->cur_master)
+		return 0;
+
+	if (!dpu_enc->cur_master->ops.get_line_count) {
+		DPU_ERROR("get_line_count function not defined\n");
+		return 0;
+	}
+
+	pclk_rate = mode->clock; /* pixel clock in kHz */
+	if (pclk_rate == 0) {
+		DPU_ERROR("pclk is 0, cannot calculate line time\n");
+		return 0;
+	}
+
+	pclk_period = DIV_ROUND_UP_ULL(1000000000ull, pclk_rate);
+	if (pclk_period == 0) {
+		DPU_ERROR("pclk period is 0\n");
+		return 0;
+	}
+
+	/*
+	 * Line time calculation based on Pixel clock and HTOTAL.
+	 * Final unit is in ns.
+	 */
+	line_time = (pclk_period * mode->htotal) / 1000;
+	if (line_time == 0) {
+		DPU_ERROR("line time calculation is 0\n");
+		return 0;
+	}
+
+	DPU_DEBUG_ENC(dpu_enc,
+			"clk_rate=%lldkHz, clk_period=%d, linetime=%dns\n",
+			pclk_rate, pclk_period, line_time);
+
+	return line_time;
+}
+
+int dpu_encoder_vsync_time(struct drm_encoder *drm_enc, ktime_t *wakeup_time)
+{
+	struct drm_display_mode *mode;
+	struct dpu_encoder_virt *dpu_enc;
+	u32 cur_line;
+	u32 line_time;
+	u32 vtotal, time_to_vsync;
+	ktime_t cur_time;
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+	if (!drm_enc->crtc || !drm_enc->crtc->state) {
+		DPU_ERROR("crtc/crtc state object is NULL\n");
+		return -EINVAL;
+	}
+	mode = &drm_enc->crtc->state->adjusted_mode;
+
+	line_time = _dpu_encoder_calculate_linetime(dpu_enc, mode);
+	if (!line_time)
+		return -EINVAL;
+
+	cur_line = dpu_enc->cur_master->ops.get_line_count(dpu_enc->cur_master);
+
+	vtotal = mode->vtotal;
+	if (cur_line >= vtotal)
+		time_to_vsync = line_time * vtotal;
+	else
+		time_to_vsync = line_time * (vtotal - cur_line);
+
+	if (time_to_vsync == 0) {
+		DPU_ERROR("time to vsync should not be zero, vtotal=%d\n",
+				vtotal);
+		return -EINVAL;
+	}
+
+	cur_time = ktime_get();
+	*wakeup_time = ktime_add_ns(cur_time, time_to_vsync);
+
+	DPU_DEBUG_ENC(dpu_enc,
+			"cur_line=%u vtotal=%u time_to_vsync=%u, cur_time=%lld, wakeup_time=%lld\n",
+			cur_line, vtotal, time_to_vsync,
+			ktime_to_ms(cur_time),
+			ktime_to_ms(*wakeup_time));
+	return 0;
+}
+
+static u32
+dpu_encoder_dsc_initial_line_calc(struct drm_dsc_config *dsc,
+				  u32 enc_ip_width)
+{
+	int ssm_delay, total_pixels, soft_slice_per_enc;
+
+	soft_slice_per_enc = enc_ip_width / dsc->slice_width;
+
+	/*
+	 * minimum number of initial line pixels is a sum of:
+	 * 1. sub-stream multiplexer delay (83 groups for 8bpc,
+	 *    91 for 10 bpc) * 3
+	 * 2. for two soft slice cases, add extra sub-stream multiplexer * 3
+	 * 3. the initial xmit delay
+	 * 4. total pipeline delay through the "lock step" of encoder (47)
+	 * 5. 6 additional pixels as the output of the rate buffer is
+	 *    48 bits wide
+	 */
+	ssm_delay = ((dsc->bits_per_component < 10) ? 84 : 92);
+	total_pixels = ssm_delay * 3 + dsc->initial_xmit_delay + 47;
+	if (soft_slice_per_enc > 1)
+		total_pixels += (ssm_delay * 3);
+	return DIV_ROUND_UP(total_pixels, dsc->slice_width);
+}
+
+static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_ctl *ctl,
+				     struct dpu_hw_dsc *hw_dsc,
+				     struct dpu_hw_pingpong *hw_pp,
+				     struct drm_dsc_config *dsc,
+				     u32 common_mode,
+				     u32 initial_lines)
+{
+	if (hw_dsc->ops.dsc_config)
+		hw_dsc->ops.dsc_config(hw_dsc, dsc, common_mode, initial_lines);
+
+	if (hw_dsc->ops.dsc_config_thresh)
+		hw_dsc->ops.dsc_config_thresh(hw_dsc, dsc);
+
+	if (hw_pp->ops.setup_dsc)
+		hw_pp->ops.setup_dsc(hw_pp);
+
+	if (hw_dsc->ops.dsc_bind_pingpong_blk)
+		hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, hw_pp->idx);
+
+	if (hw_pp->ops.enable_dsc)
+		hw_pp->ops.enable_dsc(hw_pp);
+
+	if (ctl->ops.update_pending_flush_dsc)
+		ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx);
+}
+
+static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
+				 struct drm_dsc_config *dsc)
+{
+	/* coding only for 2LM, 2enc, 1 dsc config */
+	struct dpu_encoder_phys *enc_master = dpu_enc->cur_master;
+	struct dpu_hw_ctl *ctl = enc_master->hw_ctl;
+	struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
+	struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
+	int this_frame_slices;
+	int intf_ip_w, enc_ip_w;
+	int dsc_common_mode;
+	int pic_width;
+	u32 initial_lines;
+	int i;
+
+	for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
+		hw_pp[i] = dpu_enc->hw_pp[i];
+		hw_dsc[i] = dpu_enc->hw_dsc[i];
+
+		if (!hw_pp[i] || !hw_dsc[i]) {
+			DPU_ERROR_ENC(dpu_enc, "invalid params for DSC\n");
+			return;
+		}
+	}
+
+	dsc_common_mode = 0;
+	pic_width = dsc->pic_width;
+
+	dsc_common_mode = DSC_MODE_SPLIT_PANEL;
+	if (dpu_encoder_use_dsc_merge(enc_master->parent))
+		dsc_common_mode |= DSC_MODE_MULTIPLEX;
+	if (enc_master->intf_mode == INTF_MODE_VIDEO)
+		dsc_common_mode |= DSC_MODE_VIDEO;
+
+	this_frame_slices = pic_width / dsc->slice_width;
+	intf_ip_w = this_frame_slices * dsc->slice_width;
+
+	/*
+	 * dsc merge case: when using 2 encoders for the same stream,
+	 * no. of slices need to be same on both the encoders.
+	 */
+	enc_ip_w = intf_ip_w / 2;
+	initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w);
+
+	for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
+		dpu_encoder_dsc_pipe_cfg(ctl, hw_dsc[i], hw_pp[i],
+					 dsc, dsc_common_mode, initial_lines);
+}
+
+void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc)
+{
+	struct dpu_encoder_virt *dpu_enc;
+	struct dpu_encoder_phys *phys;
+	bool needs_hw_reset = false;
+	unsigned int i;
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+	trace_dpu_enc_prepare_kickoff(DRMID(drm_enc));
+
+	/* prepare for next kickoff, may include waiting on previous kickoff */
+	DPU_ATRACE_BEGIN("enc_prepare_for_kickoff");
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		phys = dpu_enc->phys_encs[i];
+		if (phys->ops.prepare_for_kickoff)
+			phys->ops.prepare_for_kickoff(phys);
+		if (phys->enable_state == DPU_ENC_ERR_NEEDS_HW_RESET)
+			needs_hw_reset = true;
+	}
+	DPU_ATRACE_END("enc_prepare_for_kickoff");
+
+	dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_KICKOFF);
+
+	/* if any phys needs reset, reset all phys, in-order */
+	if (needs_hw_reset) {
+		trace_dpu_enc_prepare_kickoff_reset(DRMID(drm_enc));
+		for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+			dpu_encoder_helper_hw_reset(dpu_enc->phys_encs[i]);
+		}
+	}
+
+	if (dpu_enc->dsc)
+		dpu_encoder_prep_dsc(dpu_enc, dpu_enc->dsc);
+}
+
+bool dpu_encoder_is_valid_for_commit(struct drm_encoder *drm_enc)
+{
+	struct dpu_encoder_virt *dpu_enc;
+	unsigned int i;
+	struct dpu_encoder_phys *phys;
+
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+	if (drm_enc->encoder_type == DRM_MODE_ENCODER_VIRTUAL) {
+		for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+			phys = dpu_enc->phys_encs[i];
+			if (phys->ops.is_valid_for_commit && !phys->ops.is_valid_for_commit(phys)) {
+				DPU_DEBUG("invalid FB not kicking off\n");
+				return false;
+			}
+		}
+	}
+
+	return true;
+}
+
+void dpu_encoder_kickoff(struct drm_encoder *drm_enc)
+{
+	struct dpu_encoder_virt *dpu_enc;
+	struct dpu_encoder_phys *phys;
+	unsigned long timeout_ms;
+	unsigned int i;
+
+	DPU_ATRACE_BEGIN("encoder_kickoff");
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+
+	trace_dpu_enc_kickoff(DRMID(drm_enc));
+
+	timeout_ms = DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES * 1000 /
+			drm_mode_vrefresh(&drm_enc->crtc->state->adjusted_mode);
+
+	atomic_set(&dpu_enc->frame_done_timeout_ms, timeout_ms);
+	mod_timer(&dpu_enc->frame_done_timer,
+			jiffies + msecs_to_jiffies(timeout_ms));
+
+	/* All phys encs are ready to go, trigger the kickoff */
+	_dpu_encoder_kickoff_phys(dpu_enc);
+
+	/* allow phys encs to handle any post-kickoff business */
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		phys = dpu_enc->phys_encs[i];
+		if (phys->ops.handle_post_kickoff)
+			phys->ops.handle_post_kickoff(phys);
+	}
+
+	DPU_ATRACE_END("encoder_kickoff");
+}
+
+static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_mixer_cfg mixer;
+	int i, num_lm;
+	struct dpu_global_state *global_state;
+	struct dpu_hw_blk *hw_lm[2];
+	struct dpu_hw_mixer *hw_mixer[2];
+	struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
+
+	memset(&mixer, 0, sizeof(mixer));
+
+	/* reset all mixers for this encoder */
+	if (phys_enc->hw_ctl->ops.clear_all_blendstages)
+		phys_enc->hw_ctl->ops.clear_all_blendstages(phys_enc->hw_ctl);
+
+	global_state = dpu_kms_get_existing_global_state(phys_enc->dpu_kms);
+
+	num_lm = dpu_rm_get_assigned_resources(&phys_enc->dpu_kms->rm, global_state,
+		phys_enc->parent->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
+
+	for (i = 0; i < num_lm; i++) {
+		hw_mixer[i] = to_dpu_hw_mixer(hw_lm[i]);
+		if (phys_enc->hw_ctl->ops.update_pending_flush_mixer)
+			phys_enc->hw_ctl->ops.update_pending_flush_mixer(ctl, hw_mixer[i]->idx);
+
+		/* clear all blendstages */
+		if (phys_enc->hw_ctl->ops.setup_blendstage)
+			phys_enc->hw_ctl->ops.setup_blendstage(ctl, hw_mixer[i]->idx, NULL);
+	}
+}
+
+static void dpu_encoder_dsc_pipe_clr(struct dpu_hw_ctl *ctl,
+				     struct dpu_hw_dsc *hw_dsc,
+				     struct dpu_hw_pingpong *hw_pp)
+{
+	if (hw_dsc->ops.dsc_disable)
+		hw_dsc->ops.dsc_disable(hw_dsc);
+
+	if (hw_pp->ops.disable_dsc)
+		hw_pp->ops.disable_dsc(hw_pp);
+
+	if (hw_dsc->ops.dsc_bind_pingpong_blk)
+		hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, PINGPONG_NONE);
+
+	if (ctl->ops.update_pending_flush_dsc)
+		ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx);
+}
+
+static void dpu_encoder_unprep_dsc(struct dpu_encoder_virt *dpu_enc)
+{
+	/* coding only for 2LM, 2enc, 1 dsc config */
+	struct dpu_encoder_phys *enc_master = dpu_enc->cur_master;
+	struct dpu_hw_ctl *ctl = enc_master->hw_ctl;
+	struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
+	struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
+	int i;
+
+	for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
+		hw_pp[i] = dpu_enc->hw_pp[i];
+		hw_dsc[i] = dpu_enc->hw_dsc[i];
+
+		if (hw_pp[i] && hw_dsc[i])
+			dpu_encoder_dsc_pipe_clr(ctl, hw_dsc[i], hw_pp[i]);
+	}
+}
+
+void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
+	struct dpu_hw_intf_cfg intf_cfg = { 0 };
+	int i;
+	struct dpu_encoder_virt *dpu_enc;
+
+	dpu_enc = to_dpu_encoder_virt(phys_enc->parent);
+
+	phys_enc->hw_ctl->ops.reset(ctl);
+
+	dpu_encoder_helper_reset_mixers(phys_enc);
+
+	/*
+	 * TODO: move the once-only operation like CTL flush/trigger
+	 * into dpu_encoder_virt_disable() and all operations which need
+	 * to be done per phys encoder into the phys_disable() op.
+	 */
+	if (phys_enc->hw_wb) {
+		/* disable the PP block */
+		if (phys_enc->hw_wb->ops.bind_pingpong_blk)
+			phys_enc->hw_wb->ops.bind_pingpong_blk(phys_enc->hw_wb, PINGPONG_NONE);
+
+		/* mark WB flush as pending */
+		if (phys_enc->hw_ctl->ops.update_pending_flush_wb)
+			phys_enc->hw_ctl->ops.update_pending_flush_wb(ctl, phys_enc->hw_wb->idx);
+	} else {
+		for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+			if (dpu_enc->phys_encs[i] && phys_enc->hw_intf->ops.bind_pingpong_blk)
+				phys_enc->hw_intf->ops.bind_pingpong_blk(
+						dpu_enc->phys_encs[i]->hw_intf,
+						PINGPONG_NONE);
+
+			/* mark INTF flush as pending */
+			if (phys_enc->hw_ctl->ops.update_pending_flush_intf)
+				phys_enc->hw_ctl->ops.update_pending_flush_intf(phys_enc->hw_ctl,
+						dpu_enc->phys_encs[i]->hw_intf->idx);
+		}
+	}
+
+	/* reset the merge 3D HW block */
+	if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d) {
+		phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
+				BLEND_3D_NONE);
+		if (phys_enc->hw_ctl->ops.update_pending_flush_merge_3d)
+			phys_enc->hw_ctl->ops.update_pending_flush_merge_3d(ctl,
+					phys_enc->hw_pp->merge_3d->idx);
+	}
+
+	if (phys_enc->hw_cdm) {
+		if (phys_enc->hw_cdm->ops.bind_pingpong_blk && phys_enc->hw_pp)
+			phys_enc->hw_cdm->ops.bind_pingpong_blk(phys_enc->hw_cdm,
+								PINGPONG_NONE);
+		if (phys_enc->hw_ctl->ops.update_pending_flush_cdm)
+			phys_enc->hw_ctl->ops.update_pending_flush_cdm(phys_enc->hw_ctl,
+								       phys_enc->hw_cdm->idx);
+	}
+
+	if (dpu_enc->dsc) {
+		dpu_encoder_unprep_dsc(dpu_enc);
+		dpu_enc->dsc = NULL;
+	}
+
+	intf_cfg.stream_sel = 0; /* Don't care value for video mode */
+	intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
+	intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
+
+	if (phys_enc->hw_intf)
+		intf_cfg.intf = phys_enc->hw_intf->idx;
+	if (phys_enc->hw_wb)
+		intf_cfg.wb = phys_enc->hw_wb->idx;
+
+	if (phys_enc->hw_pp && phys_enc->hw_pp->merge_3d)
+		intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
+
+	if (ctl->ops.reset_intf_cfg)
+		ctl->ops.reset_intf_cfg(ctl, &intf_cfg);
+
+	ctl->ops.trigger_flush(ctl);
+	ctl->ops.trigger_start(ctl);
+	ctl->ops.clear_pending_flush(ctl);
+}
+
+void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc,
+				       const struct dpu_format *dpu_fmt,
+				       u32 output_type)
+{
+	struct dpu_hw_cdm *hw_cdm;
+	struct dpu_hw_cdm_cfg *cdm_cfg;
+	struct dpu_hw_pingpong *hw_pp;
+	int ret;
+
+	if (!phys_enc)
+		return;
+
+	cdm_cfg = &phys_enc->cdm_cfg;
+	hw_pp = phys_enc->hw_pp;
+	hw_cdm = phys_enc->hw_cdm;
+
+	if (!hw_cdm)
+		return;
+
+	if (!DPU_FORMAT_IS_YUV(dpu_fmt)) {
+		DPU_DEBUG("[enc:%d] cdm_disable fmt:%x\n", DRMID(phys_enc->parent),
+			  dpu_fmt->base.pixel_format);
+		if (hw_cdm->ops.bind_pingpong_blk)
+			hw_cdm->ops.bind_pingpong_blk(hw_cdm, PINGPONG_NONE);
+
+		return;
+	}
+
+	memset(cdm_cfg, 0, sizeof(struct dpu_hw_cdm_cfg));
+
+	cdm_cfg->output_width = phys_enc->cached_mode.hdisplay;
+	cdm_cfg->output_height = phys_enc->cached_mode.vdisplay;
+	cdm_cfg->output_fmt = dpu_fmt;
+	cdm_cfg->output_type = output_type;
+	cdm_cfg->output_bit_depth = DPU_FORMAT_IS_DX(dpu_fmt) ?
+			CDM_CDWN_OUTPUT_10BIT : CDM_CDWN_OUTPUT_8BIT;
+	cdm_cfg->csc_cfg = &dpu_csc10_rgb2yuv_601l;
+
+	/* enable 10 bit logic */
+	switch (cdm_cfg->output_fmt->chroma_sample) {
+	case DPU_CHROMA_RGB:
+		cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE;
+		cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
+		break;
+	case DPU_CHROMA_H2V1:
+		cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE;
+		cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
+		break;
+	case DPU_CHROMA_420:
+		cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE;
+		cdm_cfg->v_cdwn_type = CDM_CDWN_OFFSITE;
+		break;
+	case DPU_CHROMA_H1V2:
+	default:
+		DPU_ERROR("[enc:%d] unsupported chroma sampling type\n",
+			  DRMID(phys_enc->parent));
+		cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE;
+		cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
+		break;
+	}
+
+	DPU_DEBUG("[enc:%d] cdm_enable:%d,%d,%X,%d,%d,%d,%d]\n",
+		  DRMID(phys_enc->parent), cdm_cfg->output_width,
+		  cdm_cfg->output_height, cdm_cfg->output_fmt->base.pixel_format,
+		  cdm_cfg->output_type, cdm_cfg->output_bit_depth,
+		  cdm_cfg->h_cdwn_type, cdm_cfg->v_cdwn_type);
+
+	if (hw_cdm->ops.enable) {
+		cdm_cfg->pp_id = hw_pp->idx;
+		ret = hw_cdm->ops.enable(hw_cdm, cdm_cfg);
+		if (ret < 0) {
+			DPU_ERROR("[enc:%d] failed to enable CDM; ret:%d\n",
+				  DRMID(phys_enc->parent), ret);
+			return;
+		}
+	}
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int _dpu_encoder_status_show(struct seq_file *s, void *data)
+{
+	struct drm_encoder *drm_enc = s->private;
+	struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
+	int i;
+
+	mutex_lock(&dpu_enc->enc_lock);
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+		seq_printf(s, "intf:%d  wb:%d  vsync:%8d     underrun:%8d    frame_done_cnt:%d",
+				phys->hw_intf ? phys->hw_intf->idx - INTF_0 : -1,
+				phys->hw_wb ? phys->hw_wb->idx - WB_0 : -1,
+				atomic_read(&phys->vsync_cnt),
+				atomic_read(&phys->underrun_cnt),
+				atomic_read(&dpu_enc->frame_done_timeout_cnt));
+
+		seq_printf(s, "mode: %s\n", dpu_encoder_helper_get_intf_type(phys->intf_mode));
+	}
+	mutex_unlock(&dpu_enc->enc_lock);
+
+	return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(_dpu_encoder_status);
+
+static void dpu_encoder_debugfs_init(struct drm_encoder *drm_enc, struct dentry *root)
+{
+	/* don't error check these */
+	debugfs_create_file("status", 0600,
+			    root, drm_enc, &_dpu_encoder_status_fops);
+}
+#else
+#define dpu_encoder_debugfs_init NULL
+#endif
+
+static int dpu_encoder_virt_add_phys_encs(
+		struct drm_device *dev,
+		struct msm_display_info *disp_info,
+		struct dpu_encoder_virt *dpu_enc,
+		struct dpu_enc_phys_init_params *params)
+{
+	struct dpu_encoder_phys *enc = NULL;
+
+	DPU_DEBUG_ENC(dpu_enc, "\n");
+
+	/*
+	 * We may create up to NUM_PHYS_ENCODER_TYPES physical encoder types
+	 * in this function, check up-front.
+	 */
+	if (dpu_enc->num_phys_encs + NUM_PHYS_ENCODER_TYPES >=
+			ARRAY_SIZE(dpu_enc->phys_encs)) {
+		DPU_ERROR_ENC(dpu_enc, "too many physical encoders %d\n",
+			  dpu_enc->num_phys_encs);
+		return -EINVAL;
+	}
+
+
+	if (disp_info->intf_type == INTF_WB) {
+		enc = dpu_encoder_phys_wb_init(dev, params);
+
+		if (IS_ERR(enc)) {
+			DPU_ERROR_ENC(dpu_enc, "failed to init wb enc: %ld\n",
+				PTR_ERR(enc));
+			return PTR_ERR(enc);
+		}
+
+		dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc;
+		++dpu_enc->num_phys_encs;
+	} else if (disp_info->is_cmd_mode) {
+		enc = dpu_encoder_phys_cmd_init(dev, params);
+
+		if (IS_ERR(enc)) {
+			DPU_ERROR_ENC(dpu_enc, "failed to init cmd enc: %ld\n",
+				PTR_ERR(enc));
+			return PTR_ERR(enc);
+		}
+
+		dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc;
+		++dpu_enc->num_phys_encs;
+	} else {
+		enc = dpu_encoder_phys_vid_init(dev, params);
+
+		if (IS_ERR(enc)) {
+			DPU_ERROR_ENC(dpu_enc, "failed to init vid enc: %ld\n",
+				PTR_ERR(enc));
+			return PTR_ERR(enc);
+		}
+
+		dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc;
+		++dpu_enc->num_phys_encs;
+	}
+
+	if (params->split_role == ENC_ROLE_SLAVE)
+		dpu_enc->cur_slave = enc;
+	else
+		dpu_enc->cur_master = enc;
+
+	return 0;
+}
+
+static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc,
+				 struct dpu_kms *dpu_kms,
+				 struct msm_display_info *disp_info,
+				 int drm_enc_mode)
+{
+	int ret = 0;
+	int i = 0;
+	struct dpu_enc_phys_init_params phys_params;
+	unsigned int intf_id;
+	struct msm_drm_private *priv;
+	struct drm_encoder *drm_enc;
+
+	if (!dpu_enc) {
+		DPU_ERROR("invalid arg(s), enc %d\n", dpu_enc != NULL);
+		return -EINVAL;
+	}
+
+	drm_enc = &dpu_enc->base;
+	priv = drm_enc->dev->dev_private;
+	dpu_enc->cur_master = NULL;
+
+	memset(&phys_params, 0, sizeof(phys_params));
+	phys_params.dpu_kms = dpu_kms;
+	phys_params.parent = &dpu_enc->base;
+	phys_params.enc_spinlock = &dpu_enc->enc_spinlock;
+
+	WARN_ON(disp_info->num_of_h_tiles < 1);
+
+	DPU_DEBUG("dsi_info->num_of_h_tiles %d\n", disp_info->num_of_h_tiles);
+
+	if (disp_info->intf_type != INTF_WB)
+		dpu_enc->idle_pc_supported =
+				dpu_kms->catalog->caps->has_idle_pc;
+
+	mutex_lock(&dpu_enc->enc_lock);
+	for (i = 0; i < disp_info->num_of_h_tiles && !ret; i++) {
+		/*
+		 * Left-most tile is at index 0, content is controller id
+		 * h_tile_instance_ids[2] = {0, 1}; DSI0 = left, DSI1 = right
+		 * h_tile_instance_ids[2] = {1, 0}; DSI1 = left, DSI0 = right
+		 */
+		u32 controller_id = disp_info->h_tile_instance[i];
+
+		if (disp_info->num_of_h_tiles > 1) {
+			if (i == 0)
+				phys_params.split_role = ENC_ROLE_MASTER;
+			else
+				phys_params.split_role = ENC_ROLE_SLAVE;
+		} else {
+			phys_params.split_role = ENC_ROLE_SOLO;
+		}
+
+		DPU_DEBUG("h_tile_instance %d = %d, split_role %d\n",
+				i, controller_id, phys_params.split_role);
+
+		if (drm_enc_mode == DRM_MODE_ENCODER_DPMST) {
+			intf_id = msm_dp_get_mst_intf_id(priv->dp[controller_id],
+							 disp_info->stream_id);
+			DPU_DEBUG("intf_id %d for disp_info->stream_id = %d\n", intf_id,
+				  disp_info->stream_id);
+			phys_params.hw_intf = dpu_rm_get_intf(&dpu_kms->rm, intf_id);
+
+		} else {
+			phys_params.hw_intf = dpu_encoder_get_intf(dpu_kms->catalog, &dpu_kms->rm,
+								   disp_info->intf_type,
+								   controller_id);
+		}
+
+		if (disp_info->intf_type == INTF_WB && controller_id < WB_MAX)
+			phys_params.hw_wb = dpu_rm_get_wb(&dpu_kms->rm, controller_id);
+
+		if (!phys_params.hw_intf && !phys_params.hw_wb) {
+			DPU_ERROR_ENC(dpu_enc, "no intf or wb block assigned at idx: %d\n", i);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (phys_params.hw_intf && phys_params.hw_wb) {
+			DPU_ERROR_ENC(dpu_enc,
+					"invalid phys both intf and wb block at idx: %d\n", i);
+			ret = -EINVAL;
+			break;
+		}
+
+		ret = dpu_encoder_virt_add_phys_encs(dpu_kms->dev, disp_info,
+				dpu_enc, &phys_params);
+		if (ret) {
+			DPU_ERROR_ENC(dpu_enc, "failed to add phys encs\n");
+			break;
+		}
+	}
+
+	mutex_unlock(&dpu_enc->enc_lock);
+
+	return ret;
+}
+
+static void dpu_encoder_frame_done_timeout(struct timer_list *t)
+{
+	struct dpu_encoder_virt *dpu_enc = from_timer(dpu_enc, t,
+			frame_done_timer);
+	struct drm_encoder *drm_enc = &dpu_enc->base;
+	u32 event;
+
+	if (!drm_enc->dev) {
+		DPU_ERROR("invalid parameters\n");
+		return;
+	}
+
+	if (!dpu_enc->frame_busy_mask[0] || !dpu_enc->crtc) {
+		DRM_DEBUG_KMS("id:%u invalid timeout frame_busy_mask=%lu\n",
+			      DRMID(drm_enc), dpu_enc->frame_busy_mask[0]);
+		return;
+	} else if (!atomic_xchg(&dpu_enc->frame_done_timeout_ms, 0)) {
+		DRM_DEBUG_KMS("id:%u invalid timeout\n", DRMID(drm_enc));
+		return;
+	}
+
+	DPU_ERROR_ENC_RATELIMITED(dpu_enc, "frame done timeout\n");
+
+	if (atomic_inc_return(&dpu_enc->frame_done_timeout_cnt) == 1)
+		msm_disp_snapshot_state(drm_enc->dev);
+
+	event = DPU_ENCODER_FRAME_EVENT_ERROR;
+	trace_dpu_enc_frame_done_timeout(DRMID(drm_enc), event);
+	dpu_crtc_frame_event_cb(dpu_enc->crtc, event);
+}
+
+static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs = {
+	.atomic_mode_set = dpu_encoder_virt_atomic_mode_set,
+	.atomic_disable = dpu_encoder_virt_atomic_disable,
+	.atomic_enable = dpu_encoder_virt_atomic_enable,
+	.atomic_check = dpu_encoder_virt_atomic_check,
+};
+
+static const struct drm_encoder_funcs dpu_encoder_funcs = {
+	.debugfs_init = dpu_encoder_debugfs_init,
+};
+
+struct drm_encoder *dpu_encoder_init(struct drm_device *dev,
+		int drm_enc_mode,
+		struct msm_display_info *disp_info)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
+	struct dpu_encoder_virt *dpu_enc;
+	int ret;
+
+	dpu_enc = drmm_encoder_alloc(dev, struct dpu_encoder_virt, base,
+				     &dpu_encoder_funcs, drm_enc_mode, NULL);
+	if (IS_ERR(dpu_enc))
+		return ERR_CAST(dpu_enc);
+
+	drm_encoder_helper_add(&dpu_enc->base, &dpu_encoder_helper_funcs);
+
+	spin_lock_init(&dpu_enc->enc_spinlock);
+	dpu_enc->enabled = false;
+	mutex_init(&dpu_enc->enc_lock);
+	mutex_init(&dpu_enc->rc_lock);
+
+	ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info, drm_enc_mode);
+	if (ret) {
+		DPU_ERROR("failed to setup encoder\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	atomic_set(&dpu_enc->frame_done_timeout_ms, 0);
+	atomic_set(&dpu_enc->frame_done_timeout_cnt, 0);
+	timer_setup(&dpu_enc->frame_done_timer,
+			dpu_encoder_frame_done_timeout, 0);
+
+	INIT_DELAYED_WORK(&dpu_enc->delayed_off_work,
+			dpu_encoder_off_work);
+	dpu_enc->idle_timeout = IDLE_TIMEOUT;
+
+	memcpy(&dpu_enc->disp_info, disp_info, sizeof(*disp_info));
+
+	DPU_DEBUG_ENC(dpu_enc, "created\n");
+
+	return &dpu_enc->base;
+}
+
+/**
+ * dpu_encoder_wait_for_commit_done() - Wait for encoder to flush pending state
+ * @drm_enc:	encoder pointer
+ *
+ * Wait for hardware to have flushed the current pending changes to hardware at
+ * a vblank or CTL_START. Physical encoders will map this differently depending
+ * on the type: vid mode -> vsync_irq, cmd mode -> CTL_START.
+ *
+ * Return: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
+ */
+int dpu_encoder_wait_for_commit_done(struct drm_encoder *drm_enc)
+{
+	struct dpu_encoder_virt *dpu_enc = NULL;
+	int i, ret = 0;
+
+	if (!drm_enc) {
+		DPU_ERROR("invalid encoder\n");
+		return -EINVAL;
+	}
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	DPU_DEBUG_ENC(dpu_enc, "\n");
+
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+		if (phys->ops.wait_for_commit_done) {
+			DPU_ATRACE_BEGIN("wait_for_commit_done");
+			ret = phys->ops.wait_for_commit_done(phys);
+			DPU_ATRACE_END("wait_for_commit_done");
+			if (ret == -ETIMEDOUT && !dpu_enc->commit_done_timedout) {
+				dpu_enc->commit_done_timedout = true;
+				msm_disp_snapshot_state(drm_enc->dev);
+			}
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * dpu_encoder_wait_for_tx_complete() - Wait for encoder to transfer pixels to panel
+ * @drm_enc:	encoder pointer
+ *
+ * Wait for the hardware to transfer all the pixels to the panel. Physical
+ * encoders will map this differently depending on the type: vid mode -> vsync_irq,
+ * cmd mode -> pp_done.
+ *
+ * Return: 0 on success, -EWOULDBLOCK if already signaled, error otherwise
+ */
+int dpu_encoder_wait_for_tx_complete(struct drm_encoder *drm_enc)
+{
+	struct dpu_encoder_virt *dpu_enc = NULL;
+	int i, ret = 0;
+
+	if (!drm_enc) {
+		DPU_ERROR("invalid encoder\n");
+		return -EINVAL;
+	}
+	dpu_enc = to_dpu_encoder_virt(drm_enc);
+	DPU_DEBUG_ENC(dpu_enc, "\n");
+
+	for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+		struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
+
+		if (phys->ops.wait_for_tx_complete) {
+			DPU_ATRACE_BEGIN("wait_for_tx_complete");
+			ret = phys->ops.wait_for_tx_complete(phys);
+			DPU_ATRACE_END("wait_for_tx_complete");
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder)
+{
+	struct dpu_encoder_virt *dpu_enc = NULL;
+
+	if (!encoder) {
+		DPU_ERROR("invalid encoder\n");
+		return INTF_MODE_NONE;
+	}
+	dpu_enc = to_dpu_encoder_virt(encoder);
+
+	if (dpu_enc->cur_master)
+		return dpu_enc->cur_master->intf_mode;
+
+	if (dpu_enc->num_phys_encs)
+		return dpu_enc->phys_encs[0]->intf_mode;
+
+	return INTF_MODE_NONE;
+}
+
+unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc)
+{
+	struct drm_encoder *encoder = phys_enc->parent;
+	struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
+
+	return dpu_enc->dsc_mask;
+}
+
+void dpu_encoder_phys_init(struct dpu_encoder_phys *phys_enc,
+			  struct dpu_enc_phys_init_params *p)
+{
+	phys_enc->hw_mdptop = p->dpu_kms->hw_mdp;
+	phys_enc->hw_intf = p->hw_intf;
+	phys_enc->hw_wb = p->hw_wb;
+	phys_enc->parent = p->parent;
+	phys_enc->dpu_kms = p->dpu_kms;
+	phys_enc->split_role = p->split_role;
+	phys_enc->enc_spinlock = p->enc_spinlock;
+	phys_enc->enable_state = DPU_ENC_DISABLED;
+
+	atomic_set(&phys_enc->pending_kickoff_cnt, 0);
+	atomic_set(&phys_enc->pending_ctlstart_cnt, 0);
+
+	atomic_set(&phys_enc->vsync_cnt, 0);
+	atomic_set(&phys_enc->underrun_cnt, 0);
+
+	init_waitqueue_head(&phys_enc->pending_kickoff_wq);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_encoder.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_encoder.h
@@ -0,0 +1,197 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __DPU_ENCODER_H__
+#define __DPU_ENCODER_H__
+
+#include <drm/drm_crtc.h>
+#include "dpu_hw_mdss.h"
+
+#define DPU_ENCODER_FRAME_EVENT_DONE			BIT(0)
+#define DPU_ENCODER_FRAME_EVENT_ERROR			BIT(1)
+#define DPU_ENCODER_FRAME_EVENT_PANEL_DEAD		BIT(2)
+#define DPU_ENCODER_FRAME_EVENT_IDLE			BIT(3)
+
+#define IDLE_TIMEOUT	(66 - 16/2)
+
+/**
+ * struct msm_display_info - defines display properties
+ * @intf_type:          INTF_ type
+ * @num_of_h_tiles:     Number of horizontal tiles in case of split interface
+ * @h_tile_instance:    Controller instance used per tile. Number of elements is
+ *                      based on num_of_h_tiles
+ * @is_cmd_mode		Boolean to indicate if the CMD mode is requested
+ * @stream_id		stream id for which the interface needs to be acquired
+ * @is_te_using_watchdog_timer:  Boolean to indicate watchdog TE is
+ *				 used instead of panel TE in cmd mode panels
+ */
+struct msm_display_info {
+	enum dpu_intf_type intf_type;
+	uint32_t num_of_h_tiles;
+	uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY];
+	bool is_cmd_mode;
+	int stream_id;
+	bool is_te_using_watchdog_timer;
+};
+
+/**
+ * dpu_encoder_assign_crtc - Link the encoder to the crtc it's assigned to
+ * @encoder:	encoder pointer
+ * @crtc:	crtc pointer
+ */
+void dpu_encoder_assign_crtc(struct drm_encoder *encoder,
+			     struct drm_crtc *crtc);
+
+/**
+ * dpu_encoder_toggle_vblank_for_crtc - Toggles vblank interrupts on or off if
+ *	the encoder is assigned to the given crtc
+ * @encoder:	encoder pointer
+ * @crtc:	crtc pointer
+ * @enable:	true if vblank should be enabled
+ */
+void dpu_encoder_toggle_vblank_for_crtc(struct drm_encoder *encoder,
+					struct drm_crtc *crtc, bool enable);
+
+/**
+ * dpu_encoder_prepare_for_kickoff - schedule double buffer flip of the ctl
+ *	path (i.e. ctl flush and start) at next appropriate time.
+ *	Immediately: if no previous commit is outstanding.
+ *	Delayed: Block until next trigger can be issued.
+ * @encoder:	encoder pointer
+ */
+void dpu_encoder_prepare_for_kickoff(struct drm_encoder *encoder);
+
+/**
+ * dpu_encoder_trigger_kickoff_pending - Clear the flush bits from previous
+ *        kickoff and trigger the ctl prepare progress for command mode display.
+ * @encoder:	encoder pointer
+ */
+void dpu_encoder_trigger_kickoff_pending(struct drm_encoder *encoder);
+
+/**
+ * dpu_encoder_kickoff - trigger a double buffer flip of the ctl path
+ *	(i.e. ctl flush and start) immediately.
+ * @encoder:	encoder pointer
+ */
+void dpu_encoder_kickoff(struct drm_encoder *encoder);
+
+/**
+ * dpu_encoder_wakeup_time - get the time of the next vsync
+ */
+int dpu_encoder_vsync_time(struct drm_encoder *drm_enc, ktime_t *wakeup_time);
+
+int dpu_encoder_wait_for_commit_done(struct drm_encoder *drm_encoder);
+
+int dpu_encoder_wait_for_tx_complete(struct drm_encoder *drm_encoder);
+
+/*
+ * dpu_encoder_get_intf_mode - get interface mode of the given encoder
+ * @encoder: Pointer to drm encoder object
+ */
+enum dpu_intf_mode dpu_encoder_get_intf_mode(struct drm_encoder *encoder);
+
+/**
+ * dpu_encoder_virt_runtime_resume - pm runtime resume the encoder configs
+ * @encoder:	encoder pointer
+ */
+void dpu_encoder_virt_runtime_resume(struct drm_encoder *encoder);
+
+/**
+ * dpu_encoder_init - initialize virtual encoder object
+ * @dev:        Pointer to drm device structure
+ * @drm_enc_mode: corresponding DRM_MODE_ENCODER_* constant
+ * @disp_info:  Pointer to display information structure
+ * Returns:     Pointer to newly created drm encoder
+ */
+struct drm_encoder *dpu_encoder_init(struct drm_device *dev,
+		int drm_enc_mode,
+		struct msm_display_info *disp_info);
+
+/**
+ * dpu_encoder_set_idle_timeout - set the idle timeout for video
+ *                    and command mode encoders.
+ * @drm_enc:    Pointer to previously created drm encoder structure
+ * @idle_timeout:    idle timeout duration in milliseconds
+ */
+void dpu_encoder_set_idle_timeout(struct drm_encoder *drm_enc,
+							u32 idle_timeout);
+/**
+ * dpu_encoder_get_linecount - get interface line count for the encoder.
+ * @drm_enc:    Pointer to previously created drm encoder structure
+ */
+int dpu_encoder_get_linecount(struct drm_encoder *drm_enc);
+
+/**
+ * dpu_encoder_get_vsync_count - get vsync count for the encoder.
+ * @drm_enc:    Pointer to previously created drm encoder structure
+ */
+int dpu_encoder_get_vsync_count(struct drm_encoder *drm_enc);
+
+/**
+ * dpu_encoder_is_widebus_enabled - return bool value if widebus is enabled
+ * @drm_enc:    Pointer to previously created drm encoder structure
+ */
+bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc);
+
+/**
+ * dpu_encoder_is_dsc_enabled - indicate whether dsc is enabled
+ *				for the encoder.
+ * @drm_enc:    Pointer to previously created drm encoder structure
+ */
+bool dpu_encoder_is_dsc_enabled(const struct drm_encoder *drm_enc);
+
+/**
+ * dpu_encoder_get_crc_values_cnt - get number of physical encoders contained
+ *	in virtual encoder that can collect CRC values
+ * @drm_enc:    Pointer to previously created drm encoder structure
+ * Returns:     Number of physical encoders for given drm encoder
+ */
+int dpu_encoder_get_crc_values_cnt(const struct drm_encoder *drm_enc);
+
+/**
+ * dpu_encoder_setup_misr - enable misr calculations
+ * @drm_enc:    Pointer to previously created drm encoder structure
+ */
+void dpu_encoder_setup_misr(const struct drm_encoder *drm_encoder);
+
+/**
+ * dpu_encoder_get_crc - get the crc value from interface blocks
+ * @drm_enc:    Pointer to previously created drm encoder structure
+ * Returns:     0 on success, error otherwise
+ */
+int dpu_encoder_get_crc(const struct drm_encoder *drm_enc, u32 *crcs, int pos);
+
+/**
+ * dpu_encoder_use_dsc_merge - returns true if the encoder uses DSC merge topology.
+ * @drm_enc:    Pointer to previously created drm encoder structure
+ */
+bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc);
+
+/**
+ * dpu_encoder_prepare_wb_job - prepare writeback job for the encoder.
+ * @drm_enc:    Pointer to previously created drm encoder structure
+ * @job:        Pointer to the current drm writeback job
+ */
+void dpu_encoder_prepare_wb_job(struct drm_encoder *drm_enc,
+		struct drm_writeback_job *job);
+
+/**
+ * dpu_encoder_cleanup_wb_job - cleanup writeback job for the encoder.
+ * @drm_enc:    Pointer to previously created drm encoder structure
+ * @job:        Pointer to the current drm writeback job
+ */
+void dpu_encoder_cleanup_wb_job(struct drm_encoder *drm_enc,
+		struct drm_writeback_job *job);
+
+/**
+ * dpu_encoder_is_valid_for_commit - check if encode has valid parameters for commit.
+ * @drm_enc:    Pointer to drm encoder structure
+ */
+bool dpu_encoder_is_valid_for_commit(struct drm_encoder *drm_enc);
+
+#endif /* __DPU_ENCODER_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_encoder_phys.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_encoder_phys.h
@@ -0,0 +1,435 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __DPU_ENCODER_PHYS_H__
+#define __DPU_ENCODER_PHYS_H__
+
+#include <drm/drm_writeback.h>
+#include <linux/jiffies.h>
+
+#include "dpu_kms.h"
+#include "dpu_hw_intf.h"
+#include "dpu_hw_wb.h"
+#include "dpu_hw_pingpong.h"
+#include "dpu_hw_cdm.h"
+#include "dpu_hw_ctl.h"
+#include "dpu_hw_top.h"
+#include "dpu_hw_util.h"
+#include "dpu_encoder.h"
+#include "dpu_crtc.h"
+
+#define DPU_ENCODER_NAME_MAX	16
+
+/* wait for at most 2 vsync for lowest refresh rate (24hz) */
+#define KICKOFF_TIMEOUT_MS		84
+#define KICKOFF_TIMEOUT_JIFFIES		msecs_to_jiffies(KICKOFF_TIMEOUT_MS)
+
+/**
+ * enum dpu_enc_split_role - Role this physical encoder will play in a
+ *	split-panel configuration, where one panel is master, and others slaves.
+ *	Masters have extra responsibilities, like managing the VBLANK IRQ.
+ * @ENC_ROLE_SOLO:	This is the one and only panel. This encoder is master.
+ * @ENC_ROLE_MASTER:	This encoder is the master of a split panel config.
+ * @ENC_ROLE_SLAVE:	This encoder is not the master of a split panel config.
+ */
+enum dpu_enc_split_role {
+	ENC_ROLE_SOLO,
+	ENC_ROLE_MASTER,
+	ENC_ROLE_SLAVE,
+};
+
+/**
+ * enum dpu_enc_enable_state - current enabled state of the physical encoder
+ * @DPU_ENC_DISABLING:	Encoder transitioning to disable state
+ *			Events bounding transition are encoder type specific
+ * @DPU_ENC_DISABLED:	Encoder is disabled
+ * @DPU_ENC_ENABLING:	Encoder transitioning to enabled
+ *			Events bounding transition are encoder type specific
+ * @DPU_ENC_ENABLED:	Encoder is enabled
+ * @DPU_ENC_ERR_NEEDS_HW_RESET:	Encoder is enabled, but requires a hw_reset
+ *				to recover from a previous error
+ */
+enum dpu_enc_enable_state {
+	DPU_ENC_DISABLING,
+	DPU_ENC_DISABLED,
+	DPU_ENC_ENABLING,
+	DPU_ENC_ENABLED,
+	DPU_ENC_ERR_NEEDS_HW_RESET
+};
+
+struct dpu_encoder_phys;
+
+/**
+ * struct dpu_encoder_phys_ops - Interface the physical encoders provide to
+ *	the containing virtual encoder.
+ * @prepare_commit:		MSM Atomic Call, start of atomic commit sequence
+ * @is_master:			Whether this phys_enc is the current master
+ *				encoder. Can be switched at enable time. Based
+ *				on split_role and current mode (CMD/VID).
+ * @atomic_mode_set:		DRM Call. Set a DRM mode.
+ *				This likely caches the mode, for use at enable.
+ * @enable:			DRM Call. Enable a DRM mode.
+ * @disable:			DRM Call. Disable mode.
+ * @atomic_check:		DRM Call. Atomic check new DRM state.
+ * @control_vblank_irq		Register/Deregister for VBLANK IRQ
+ * @wait_for_commit_done:	Wait for hardware to have flushed the
+ *				current pending frames to hardware
+ * @wait_for_tx_complete:	Wait for hardware to transfer the pixels
+ *				to the panel
+ * @wait_for_vblank:		Wait for VBLANK, for sub-driver internal use
+ * @prepare_for_kickoff:	Do any work necessary prior to a kickoff
+ *				For CMD encoder, may wait for previous tx done
+ * @handle_post_kickoff:	Do any work necessary post-kickoff work
+ * @trigger_start:		Process start event on physical encoder
+ * @needs_single_flush:		Whether encoder slaves need to be flushed
+ * @irq_control:		Handler to enable/disable all the encoder IRQs
+ * @prepare_idle_pc:		phys encoder can update the vsync_enable status
+ *                              on idle power collapse prepare
+ * @restore:			Restore all the encoder configs.
+ * @get_line_count:		Obtain current vertical line count
+ */
+
+struct dpu_encoder_phys_ops {
+	void (*prepare_commit)(struct dpu_encoder_phys *encoder);
+	bool (*is_master)(struct dpu_encoder_phys *encoder);
+	void (*atomic_mode_set)(struct dpu_encoder_phys *encoder,
+			struct drm_crtc_state *crtc_state,
+			struct drm_connector_state *conn_state);
+	void (*enable)(struct dpu_encoder_phys *encoder);
+	void (*disable)(struct dpu_encoder_phys *encoder);
+	int (*atomic_check)(struct dpu_encoder_phys *encoder,
+			    struct drm_crtc_state *crtc_state,
+			    struct drm_connector_state *conn_state);
+	int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable);
+	int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc);
+	int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc);
+	void (*prepare_for_kickoff)(struct dpu_encoder_phys *phys_enc);
+	void (*handle_post_kickoff)(struct dpu_encoder_phys *phys_enc);
+	void (*trigger_start)(struct dpu_encoder_phys *phys_enc);
+	bool (*needs_single_flush)(struct dpu_encoder_phys *phys_enc);
+	void (*irq_control)(struct dpu_encoder_phys *phys, bool enable);
+	void (*prepare_idle_pc)(struct dpu_encoder_phys *phys_enc);
+	void (*restore)(struct dpu_encoder_phys *phys);
+	int (*get_line_count)(struct dpu_encoder_phys *phys);
+	int (*get_frame_count)(struct dpu_encoder_phys *phys);
+	void (*prepare_wb_job)(struct dpu_encoder_phys *phys_enc,
+			struct drm_writeback_job *job);
+	void (*cleanup_wb_job)(struct dpu_encoder_phys *phys_enc,
+			struct drm_writeback_job *job);
+	bool (*is_valid_for_commit)(struct dpu_encoder_phys *phys_enc);
+};
+
+/**
+ * enum dpu_intr_idx - dpu encoder interrupt index
+ * @INTR_IDX_VSYNC:    Vsync interrupt for video mode panel
+ * @INTR_IDX_PINGPONG: Pingpong done interrupt for cmd mode panel
+ * @INTR_IDX_UNDERRUN: Underrun interrupt for video and cmd mode panel
+ * @INTR_IDX_RDPTR:    Readpointer done interrupt for cmd mode panel
+ * @INTR_IDX_WB_DONE:  Writeback done interrupt for virtual connector
+ */
+enum dpu_intr_idx {
+	INTR_IDX_VSYNC,
+	INTR_IDX_PINGPONG,
+	INTR_IDX_UNDERRUN,
+	INTR_IDX_CTL_START,
+	INTR_IDX_RDPTR,
+	INTR_IDX_WB_DONE,
+	INTR_IDX_MAX,
+};
+
+/**
+ * struct dpu_encoder_phys - physical encoder that drives a single INTF block
+ *	tied to a specific panel / sub-panel. Abstract type, sub-classed by
+ *	phys_vid or phys_cmd for video mode or command mode encs respectively.
+ * @parent:		Pointer to the containing virtual encoder
+ * @ops:		Operations exposed to the virtual encoder
+ * @parent_ops:		Callbacks exposed by the parent to the phys_enc
+ * @hw_mdptop:		Hardware interface to the top registers
+ * @hw_ctl:		Hardware interface to the ctl registers
+ * @hw_pp:		Hardware interface to the ping pong registers
+ * @hw_intf:		Hardware interface to the intf registers
+ * @hw_wb:		Hardware interface to the wb registers
+ * @hw_cdm:		Hardware interface to the CDM registers
+ * @dpu_kms:		Pointer to the dpu_kms top level
+ * @cdm_cfg:		CDM block config needed to store WB/DP block's CDM configuration
+ * @cached_mode:	DRM mode cached at mode_set time, acted on in enable
+ * @vblank_ctl_lock:	Vblank ctl mutex lock to protect vblank_refcount
+ * @enabled:		Whether the encoder has enabled and running a mode
+ * @split_role:		Role to play in a split-panel configuration
+ * @intf_mode:		Interface mode
+ * @enc_spinlock:	Virtual-Encoder-Wide Spin Lock for IRQ purposes
+ * @enable_state:	Enable state tracking
+ * @vblank_refcount:	Reference count of vblank request
+ * @vsync_cnt:		Vsync count for the physical encoder
+ * @underrun_cnt:	Underrun count for the physical encoder
+ * @pending_kickoff_cnt:	Atomic counter tracking the number of kickoffs
+ *				vs. the number of done/vblank irqs. Should hover
+ *				between 0-2 Incremented when a new kickoff is
+ *				scheduled. Decremented in irq handler
+ * @pending_ctlstart_cnt:	Atomic counter tracking the number of ctl start
+ *                              pending.
+ * @pending_kickoff_wq:		Wait queue for blocking until kickoff completes
+ * @irq:			IRQ indices
+ * @has_intf_te:		Interface TE configuration support
+ */
+struct dpu_encoder_phys {
+	struct drm_encoder *parent;
+	struct dpu_encoder_phys_ops ops;
+	struct dpu_hw_mdp *hw_mdptop;
+	struct dpu_hw_ctl *hw_ctl;
+	struct dpu_hw_pingpong *hw_pp;
+	struct dpu_hw_intf *hw_intf;
+	struct dpu_hw_wb *hw_wb;
+	struct dpu_hw_cdm *hw_cdm;
+	struct dpu_kms *dpu_kms;
+	struct dpu_hw_cdm_cfg cdm_cfg;
+	struct drm_display_mode cached_mode;
+	struct mutex vblank_ctl_lock;
+	enum dpu_enc_split_role split_role;
+	enum dpu_intf_mode intf_mode;
+	spinlock_t *enc_spinlock;
+	enum dpu_enc_enable_state enable_state;
+	int vblank_refcount;
+	atomic_t vsync_cnt;
+	atomic_t underrun_cnt;
+	atomic_t pending_ctlstart_cnt;
+	atomic_t pending_kickoff_cnt;
+	wait_queue_head_t pending_kickoff_wq;
+	unsigned int irq[INTR_IDX_MAX];
+	bool has_intf_te;
+};
+
+static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)
+{
+	atomic_inc_return(&phys->pending_ctlstart_cnt);
+	return atomic_inc_return(&phys->pending_kickoff_cnt);
+}
+
+/**
+ * struct dpu_encoder_phys_wb - sub-class of dpu_encoder_phys to handle command
+ *	mode specific operations
+ * @base:	Baseclass physical encoder structure
+ * @wbirq_refcount:     Reference count of writeback interrupt
+ * @wb_done_timeout_cnt: number of wb done irq timeout errors
+ * @wb_cfg:  writeback block config to store fb related details
+ * @wb_conn: backpointer to writeback connector
+ * @wb_job: backpointer to current writeback job
+ * @dest:   dpu buffer layout for current writeback output buffer
+ */
+struct dpu_encoder_phys_wb {
+	struct dpu_encoder_phys base;
+	atomic_t wbirq_refcount;
+	int wb_done_timeout_cnt;
+	struct dpu_hw_wb_cfg wb_cfg;
+	struct drm_writeback_connector *wb_conn;
+	struct drm_writeback_job *wb_job;
+	struct dpu_hw_fmt_layout dest;
+};
+
+/**
+ * struct dpu_encoder_phys_cmd - sub-class of dpu_encoder_phys to handle command
+ *	mode specific operations
+ * @base:	Baseclass physical encoder structure
+ * @intf_idx:	Intf Block index used by this phys encoder
+ * @stream_sel:	Stream selection for multi-stream interfaces
+ * @serialize_wait4pp:	serialize wait4pp feature waits for pp_done interrupt
+ *			after ctl_start instead of before next frame kickoff
+ * @pp_timeout_report_cnt: number of pingpong done irq timeout errors
+ * @pending_vblank_cnt: Atomic counter tracking pending wait for VBLANK
+ * @pending_vblank_wq: Wait queue for blocking until VBLANK received
+ */
+struct dpu_encoder_phys_cmd {
+	struct dpu_encoder_phys base;
+	int stream_sel;
+	bool serialize_wait4pp;
+	int pp_timeout_report_cnt;
+	atomic_t pending_vblank_cnt;
+	wait_queue_head_t pending_vblank_wq;
+};
+
+/**
+ * struct dpu_enc_phys_init_params - initialization parameters for phys encs
+ * @dpu_kms:		Pointer to the dpu_kms top level
+ * @parent:		Pointer to the containing virtual encoder
+ * @parent_ops:		Callbacks exposed by the parent to the phys_enc
+ * @split_role:		Role to play in a split-panel configuration
+ * @hw_intf:		Hardware interface to the intf registers
+ * @hw_wb:		Hardware interface to the wb registers
+ * @enc_spinlock:	Virtual-Encoder-Wide Spin Lock for IRQ purposes
+ */
+struct dpu_enc_phys_init_params {
+	struct dpu_kms *dpu_kms;
+	struct drm_encoder *parent;
+	enum dpu_enc_split_role split_role;
+	struct dpu_hw_intf *hw_intf;
+	struct dpu_hw_wb *hw_wb;
+	spinlock_t *enc_spinlock;
+};
+
+/**
+ * dpu_encoder_wait_info - container for passing arguments to irq wait functions
+ * @wq: wait queue structure
+ * @atomic_cnt: wait until atomic_cnt equals zero
+ * @timeout_ms: timeout value in milliseconds
+ */
+struct dpu_encoder_wait_info {
+	wait_queue_head_t *wq;
+	atomic_t *atomic_cnt;
+	s64 timeout_ms;
+};
+
+/**
+ * dpu_encoder_phys_vid_init - Construct a new video mode physical encoder
+ * @p:	Pointer to init params structure
+ * Return: Error code or newly allocated encoder
+ */
+struct dpu_encoder_phys *dpu_encoder_phys_vid_init(struct drm_device *dev,
+		struct dpu_enc_phys_init_params *p);
+
+/**
+ * dpu_encoder_phys_cmd_init - Construct a new command mode physical encoder
+ * @dev:  Corresponding device for devres management
+ * @p:	Pointer to init params structure
+ * Return: Error code or newly allocated encoder
+ */
+struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(struct drm_device *dev,
+		struct dpu_enc_phys_init_params *p);
+
+/**
+ * dpu_encoder_phys_wb_init - initialize writeback encoder
+ * @dev:  Corresponding device for devres management
+ * @init:	Pointer to init info structure with initialization params
+ */
+struct dpu_encoder_phys *dpu_encoder_phys_wb_init(struct drm_device *dev,
+		struct dpu_enc_phys_init_params *p);
+
+/**
+ * dpu_encoder_helper_trigger_start - control start helper function
+ *	This helper function may be optionally specified by physical
+ *	encoders if they require ctl_start triggering.
+ * @phys_enc: Pointer to physical encoder structure
+ */
+void dpu_encoder_helper_trigger_start(struct dpu_encoder_phys *phys_enc);
+
+static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_crtc_state *dpu_cstate;
+
+	if (!phys_enc || phys_enc->enable_state == DPU_ENC_DISABLING)
+		return BLEND_3D_NONE;
+
+	dpu_cstate = to_dpu_crtc_state(phys_enc->parent->crtc->state);
+
+	/* Use merge_3d unless DSC MERGE topology is used */
+	if (phys_enc->split_role == ENC_ROLE_SOLO &&
+	    dpu_cstate->num_mixers == CRTC_DUAL_MIXERS &&
+	    !dpu_encoder_use_dsc_merge(phys_enc->parent))
+		return BLEND_3D_H_ROW_INT;
+
+	return BLEND_3D_NONE;
+}
+
+/**
+ * dpu_encoder_helper_get_dsc - get DSC blocks mask for the DPU encoder
+ *   This helper function is used by physical encoder to get DSC blocks mask
+ *   used for this encoder.
+ * @phys_enc: Pointer to physical encoder structure
+ */
+unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc);
+
+/**
+ * dpu_encoder_get_drm_fmt - return DRM fourcc format
+ * @phys_enc: Pointer to physical encoder structure
+ */
+u32 dpu_encoder_get_drm_fmt(struct dpu_encoder_phys *phys_enc);
+
+/**
+ * dpu_encoder_needs_periph_flush - return true if physical encoder requires
+ *	peripheral flush
+ * @phys_enc: Pointer to physical encoder structure
+ */
+bool dpu_encoder_needs_periph_flush(struct dpu_encoder_phys *phys_enc);
+
+/**
+ * dpu_encoder_helper_split_config - split display configuration helper function
+ *	This helper function may be used by physical encoders to configure
+ *	the split display related registers.
+ * @phys_enc: Pointer to physical encoder structure
+ * @interface: enum dpu_intf setting
+ */
+void dpu_encoder_helper_split_config(
+		struct dpu_encoder_phys *phys_enc,
+		enum dpu_intf interface);
+
+/**
+ * dpu_encoder_helper_report_irq_timeout - utility to report error that irq has
+ *	timed out, including reporting frame error event to crtc and debug dump
+ * @phys_enc: Pointer to physical encoder structure
+ * @intr_idx: Failing interrupt index
+ */
+void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc,
+		enum dpu_intr_idx intr_idx);
+
+/**
+ * dpu_encoder_helper_wait_for_irq - utility to wait on an irq.
+ *	note: will call dpu_encoder_helper_wait_for_irq on timeout
+ * @phys_enc: Pointer to physical encoder structure
+ * @irq: IRQ index
+ * @func: IRQ callback to be called in case of timeout
+ * @wait_info: wait info struct
+ * @Return: 0 or -ERROR
+ */
+int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
+		unsigned int irq,
+		void (*func)(void *arg),
+		struct dpu_encoder_wait_info *wait_info);
+
+/**
+ * dpu_encoder_helper_phys_cleanup - helper to cleanup dpu pipeline
+ * @phys_enc: Pointer to physical encoder structure
+ */
+void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc);
+
+/**
+ * dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block
+ * @phys_enc: Pointer to physical encoder
+ * @output_type: HDMI/WB
+ */
+void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc,
+				       const struct dpu_format *dpu_fmt,
+				       u32 output_type);
+
+/**
+ * dpu_encoder_vblank_callback - Notify virtual encoder of vblank IRQ reception
+ * @drm_enc:    Pointer to drm encoder structure
+ * @phys_enc:	Pointer to physical encoder
+ * Note: This is called from IRQ handler context.
+ */
+void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc,
+				 struct dpu_encoder_phys *phy_enc);
+
+/** dpu_encoder_underrun_callback - Notify virtual encoder of underrun IRQ reception
+ * @drm_enc:    Pointer to drm encoder structure
+ * @phys_enc:	Pointer to physical encoder
+ * Note: This is called from IRQ handler context.
+ */
+void dpu_encoder_underrun_callback(struct drm_encoder *drm_enc,
+				   struct dpu_encoder_phys *phy_enc);
+
+/** dpu_encoder_frame_done_callback -- Notify virtual encoder that this phys encoder completes last request frame
+ * @drm_enc:    Pointer to drm encoder structure
+ * @phys_enc:	Pointer to physical encoder
+ * @event:	Event to process
+ */
+void dpu_encoder_frame_done_callback(
+		struct drm_encoder *drm_enc,
+		struct dpu_encoder_phys *ready_phys, u32 event);
+
+void dpu_encoder_phys_init(struct dpu_encoder_phys *phys,
+			   struct dpu_enc_phys_init_params *p);
+
+#endif /* __dpu_encoder_phys_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_encoder_phys_cmd.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -0,0 +1,764 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015-2018, 2020-2021 The Linux Foundation. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+#include <linux/delay.h>
+#include "dpu_encoder_phys.h"
+#include "dpu_hw_interrupts.h"
+#include "dpu_hw_pingpong.h"
+#include "dpu_core_irq.h"
+#include "dpu_formats.h"
+#include "dpu_trace.h"
+#include "disp/msm_disp_snapshot.h"
+
+#include <drm/drm_managed.h>
+
+#define DPU_DEBUG_CMDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
+		(e) && (e)->base.parent ? \
+		(e)->base.parent->base.id : -1, \
+		(e) ? (e)->base.hw_intf->idx - INTF_0 : -1, ##__VA_ARGS__)
+
+#define DPU_ERROR_CMDENC(e, fmt, ...) DPU_ERROR("enc%d intf%d " fmt, \
+		(e) && (e)->base.parent ? \
+		(e)->base.parent->base.id : -1, \
+		(e) ? (e)->base.hw_intf->idx - INTF_0 : -1, ##__VA_ARGS__)
+
+#define to_dpu_encoder_phys_cmd(x) \
+	container_of(x, struct dpu_encoder_phys_cmd, base)
+
+#define PP_TIMEOUT_MAX_TRIALS	10
+
+/*
+ * Tearcheck sync start and continue thresholds are empirically found
+ * based on common panels In the future, may want to allow panels to override
+ * these default values
+ */
+#define DEFAULT_TEARCHECK_SYNC_THRESH_START	4
+#define DEFAULT_TEARCHECK_SYNC_THRESH_CONTINUE	4
+
+static void dpu_encoder_phys_cmd_enable_te(struct dpu_encoder_phys *phys_enc);
+
+static bool dpu_encoder_phys_cmd_is_master(struct dpu_encoder_phys *phys_enc)
+{
+	return (phys_enc->split_role != ENC_ROLE_SLAVE);
+}
+
+static void _dpu_encoder_phys_cmd_update_intf_cfg(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_encoder_phys_cmd *cmd_enc =
+			to_dpu_encoder_phys_cmd(phys_enc);
+	struct dpu_hw_ctl *ctl;
+	struct dpu_hw_intf_cfg intf_cfg = { 0 };
+	struct dpu_hw_intf_cmd_mode_cfg cmd_mode_cfg = {};
+
+	ctl = phys_enc->hw_ctl;
+	if (!ctl->ops.setup_intf_cfg)
+		return;
+
+	intf_cfg.intf = phys_enc->hw_intf->idx;
+	intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD;
+	intf_cfg.stream_sel = cmd_enc->stream_sel;
+	intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
+	intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
+	ctl->ops.setup_intf_cfg(ctl, &intf_cfg);
+
+	/* setup which pp blk will connect to this intf */
+	if (test_bit(DPU_CTL_ACTIVE_CFG, &ctl->caps->features) && phys_enc->hw_intf->ops.bind_pingpong_blk)
+		phys_enc->hw_intf->ops.bind_pingpong_blk(
+				phys_enc->hw_intf,
+				phys_enc->hw_pp->idx);
+
+	if (intf_cfg.dsc != 0)
+		cmd_mode_cfg.data_compress = true;
+
+	cmd_mode_cfg.wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent);
+
+	if (phys_enc->hw_intf->ops.program_intf_cmd_cfg)
+		phys_enc->hw_intf->ops.program_intf_cmd_cfg(phys_enc->hw_intf, &cmd_mode_cfg);
+}
+
+static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg)
+{
+	struct dpu_encoder_phys *phys_enc = arg;
+	unsigned long lock_flags;
+	int new_cnt;
+	u32 event = DPU_ENCODER_FRAME_EVENT_DONE;
+
+	if (!phys_enc->hw_pp)
+		return;
+
+	DPU_ATRACE_BEGIN("pp_done_irq");
+	/* notify all synchronous clients first, then asynchronous clients */
+	dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, event);
+
+	spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
+	new_cnt = atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
+	spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
+
+	trace_dpu_enc_phys_cmd_pp_tx_done(DRMID(phys_enc->parent),
+					  phys_enc->hw_pp->idx - PINGPONG_0,
+					  new_cnt, event);
+
+	/* Signal any waiting atomic commit thread */
+	wake_up_all(&phys_enc->pending_kickoff_wq);
+	DPU_ATRACE_END("pp_done_irq");
+}
+
+static void dpu_encoder_phys_cmd_te_rd_ptr_irq(void *arg)
+{
+	struct dpu_encoder_phys *phys_enc = arg;
+	struct dpu_encoder_phys_cmd *cmd_enc;
+
+	DPU_ATRACE_BEGIN("rd_ptr_irq");
+	cmd_enc = to_dpu_encoder_phys_cmd(phys_enc);
+
+	dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
+
+	atomic_add_unless(&cmd_enc->pending_vblank_cnt, -1, 0);
+	wake_up_all(&cmd_enc->pending_vblank_wq);
+	DPU_ATRACE_END("rd_ptr_irq");
+}
+
+static void dpu_encoder_phys_cmd_ctl_start_irq(void *arg)
+{
+	struct dpu_encoder_phys *phys_enc = arg;
+
+	DPU_ATRACE_BEGIN("ctl_start_irq");
+
+	atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0);
+
+	/* Signal any waiting ctl start interrupt */
+	wake_up_all(&phys_enc->pending_kickoff_wq);
+	DPU_ATRACE_END("ctl_start_irq");
+}
+
+static void dpu_encoder_phys_cmd_underrun_irq(void *arg)
+{
+	struct dpu_encoder_phys *phys_enc = arg;
+
+	dpu_encoder_underrun_callback(phys_enc->parent, phys_enc);
+}
+
+static void dpu_encoder_phys_cmd_atomic_mode_set(
+		struct dpu_encoder_phys *phys_enc,
+		struct drm_crtc_state *crtc_state,
+		struct drm_connector_state *conn_state)
+{
+	phys_enc->irq[INTR_IDX_CTL_START] = phys_enc->hw_ctl->caps->intr_start;
+
+	phys_enc->irq[INTR_IDX_PINGPONG] = phys_enc->hw_pp->caps->intr_done;
+
+	if (phys_enc->has_intf_te)
+		phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_intf->cap->intr_tear_rd_ptr;
+	else
+		phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr;
+
+	phys_enc->irq[INTR_IDX_UNDERRUN] = phys_enc->hw_intf->cap->intr_underrun;
+}
+
+static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_encoder_phys_cmd *cmd_enc =
+			to_dpu_encoder_phys_cmd(phys_enc);
+	u32 frame_event = DPU_ENCODER_FRAME_EVENT_ERROR;
+	bool do_log = false;
+	struct drm_encoder *drm_enc;
+
+	if (!phys_enc->hw_pp)
+		return -EINVAL;
+
+	drm_enc = phys_enc->parent;
+
+	cmd_enc->pp_timeout_report_cnt++;
+	if (cmd_enc->pp_timeout_report_cnt == PP_TIMEOUT_MAX_TRIALS) {
+		frame_event |= DPU_ENCODER_FRAME_EVENT_PANEL_DEAD;
+		do_log = true;
+	} else if (cmd_enc->pp_timeout_report_cnt == 1) {
+		do_log = true;
+	}
+
+	trace_dpu_enc_phys_cmd_pdone_timeout(DRMID(drm_enc),
+		     phys_enc->hw_pp->idx - PINGPONG_0,
+		     cmd_enc->pp_timeout_report_cnt,
+		     atomic_read(&phys_enc->pending_kickoff_cnt),
+		     frame_event);
+
+	/* to avoid flooding, only log first time, and "dead" time */
+	if (do_log) {
+		DRM_ERROR("id:%d pp:%d kickoff timeout %d cnt %d koff_cnt %d\n",
+			  DRMID(drm_enc),
+			  phys_enc->hw_pp->idx - PINGPONG_0,
+			  phys_enc->hw_ctl->idx - CTL_0,
+			  cmd_enc->pp_timeout_report_cnt,
+			  atomic_read(&phys_enc->pending_kickoff_cnt));
+		msm_disp_snapshot_state(drm_enc->dev);
+		dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
+				phys_enc->irq[INTR_IDX_RDPTR]);
+	}
+
+	atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
+
+	/* request a ctl reset before the next kickoff */
+	phys_enc->enable_state = DPU_ENC_ERR_NEEDS_HW_RESET;
+
+	dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, frame_event);
+
+	return -ETIMEDOUT;
+}
+
+static int _dpu_encoder_phys_cmd_wait_for_idle(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_encoder_phys_cmd *cmd_enc =
+			to_dpu_encoder_phys_cmd(phys_enc);
+	struct dpu_encoder_wait_info wait_info;
+	int ret;
+
+	wait_info.wq = &phys_enc->pending_kickoff_wq;
+	wait_info.atomic_cnt = &phys_enc->pending_kickoff_cnt;
+	wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
+
+	ret = dpu_encoder_helper_wait_for_irq(phys_enc,
+			phys_enc->irq[INTR_IDX_PINGPONG],
+			dpu_encoder_phys_cmd_pp_tx_done_irq,
+			&wait_info);
+	if (ret == -ETIMEDOUT)
+		_dpu_encoder_phys_cmd_handle_ppdone_timeout(phys_enc);
+	else if (!ret)
+		cmd_enc->pp_timeout_report_cnt = 0;
+
+	return ret;
+}
+
+static int dpu_encoder_phys_cmd_control_vblank_irq(
+		struct dpu_encoder_phys *phys_enc,
+		bool enable)
+{
+	int ret = 0;
+	int refcount;
+
+	if (!phys_enc->hw_pp) {
+		DPU_ERROR("invalid encoder\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&phys_enc->vblank_ctl_lock);
+	refcount = phys_enc->vblank_refcount;
+
+	/* Slave encoders don't report vblank */
+	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
+		goto end;
+
+	/* protect against negative */
+	if (!enable && refcount == 0) {
+		ret = -EINVAL;
+		goto end;
+	}
+
+	DRM_DEBUG_KMS("id:%u pp:%d enable=%s/%d\n", DRMID(phys_enc->parent),
+		      phys_enc->hw_pp->idx - PINGPONG_0,
+		      enable ? "true" : "false", refcount);
+
+	if (enable) {
+		if (phys_enc->vblank_refcount == 0)
+			ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
+					phys_enc->irq[INTR_IDX_RDPTR],
+					dpu_encoder_phys_cmd_te_rd_ptr_irq,
+					phys_enc);
+		if (!ret)
+			phys_enc->vblank_refcount++;
+	} else if (!enable) {
+		if (phys_enc->vblank_refcount == 1)
+			ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
+					phys_enc->irq[INTR_IDX_RDPTR]);
+		if (!ret)
+			phys_enc->vblank_refcount--;
+	}
+
+end:
+	mutex_unlock(&phys_enc->vblank_ctl_lock);
+	if (ret) {
+		DRM_ERROR("vblank irq err id:%u pp:%d ret:%d, enable %s/%d\n",
+			  DRMID(phys_enc->parent),
+			  phys_enc->hw_pp->idx - PINGPONG_0, ret,
+			  enable ? "true" : "false", refcount);
+	}
+
+	return ret;
+}
+
+static void dpu_encoder_phys_cmd_irq_control(struct dpu_encoder_phys *phys_enc,
+		bool enable)
+{
+	trace_dpu_enc_phys_cmd_irq_ctrl(DRMID(phys_enc->parent),
+			phys_enc->hw_pp->idx - PINGPONG_0,
+			enable, phys_enc->vblank_refcount);
+
+	if (enable) {
+		dpu_core_irq_register_callback(phys_enc->dpu_kms,
+				phys_enc->irq[INTR_IDX_PINGPONG],
+				dpu_encoder_phys_cmd_pp_tx_done_irq,
+				phys_enc);
+		dpu_core_irq_register_callback(phys_enc->dpu_kms,
+				phys_enc->irq[INTR_IDX_UNDERRUN],
+				dpu_encoder_phys_cmd_underrun_irq,
+				phys_enc);
+		dpu_encoder_phys_cmd_control_vblank_irq(phys_enc, true);
+
+		if (dpu_encoder_phys_cmd_is_master(phys_enc))
+			dpu_core_irq_register_callback(phys_enc->dpu_kms,
+					phys_enc->irq[INTR_IDX_CTL_START],
+					dpu_encoder_phys_cmd_ctl_start_irq,
+					phys_enc);
+	} else {
+		if (dpu_encoder_phys_cmd_is_master(phys_enc))
+			dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
+					phys_enc->irq[INTR_IDX_CTL_START]);
+
+		dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
+				phys_enc->irq[INTR_IDX_UNDERRUN]);
+		dpu_encoder_phys_cmd_control_vblank_irq(phys_enc, false);
+		dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
+				phys_enc->irq[INTR_IDX_PINGPONG]);
+	}
+}
+
+static void dpu_encoder_phys_cmd_tearcheck_config(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_encoder_phys_cmd *cmd_enc =
+		to_dpu_encoder_phys_cmd(phys_enc);
+	struct dpu_hw_tear_check tc_cfg = { 0 };
+	struct drm_display_mode *mode;
+	bool tc_enable = true;
+	unsigned long vsync_hz;
+	struct dpu_kms *dpu_kms;
+
+	/*
+	 * TODO: if/when resource allocation is refactored, move this to a
+	 * place where the driver can actually return an error.
+	 */
+	if (!phys_enc->has_intf_te &&
+	    (!phys_enc->hw_pp ||
+	     !phys_enc->hw_pp->ops.enable_tearcheck)) {
+		DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n");
+		return;
+	}
+
+	DPU_DEBUG_CMDENC(cmd_enc, "intf %d pp %d\n",
+			 phys_enc->hw_intf ? phys_enc->hw_intf->idx - INTF_0 : -1,
+			 phys_enc->hw_pp ? phys_enc->hw_pp->idx - PINGPONG_0 : -1);
+
+	mode = &phys_enc->cached_mode;
+
+	dpu_kms = phys_enc->dpu_kms;
+
+	/*
+	 * TE default: dsi byte clock calculated base on 70 fps;
+	 * around 14 ms to complete a kickoff cycle if te disabled;
+	 * vclk_line base on 60 fps; write is faster than read;
+	 * init == start == rdptr;
+	 *
+	 * vsync_count is ratio of MDP VSYNC clock frequency to LCD panel
+	 * frequency divided by the no. of rows (lines) in the LCDpanel.
+	 */
+	vsync_hz = dpu_kms_get_clk_rate(dpu_kms, "vsync");
+	if (!vsync_hz) {
+		DPU_DEBUG_CMDENC(cmd_enc, "invalid - no vsync clock\n");
+		return;
+	}
+
+	tc_cfg.vsync_count = vsync_hz /
+				(mode->vtotal * drm_mode_vrefresh(mode));
+
+	/*
+	 * Set the sync_cfg_height to twice vtotal so that if we lose a
+	 * TE event coming from the display TE pin we won't stall immediately
+	 */
+	tc_cfg.hw_vsync_mode = 1;
+	tc_cfg.sync_cfg_height = mode->vtotal * 2;
+	tc_cfg.vsync_init_val = mode->vdisplay;
+	tc_cfg.sync_threshold_start = DEFAULT_TEARCHECK_SYNC_THRESH_START;
+	tc_cfg.sync_threshold_continue = DEFAULT_TEARCHECK_SYNC_THRESH_CONTINUE;
+	tc_cfg.start_pos = mode->vdisplay;
+	tc_cfg.rd_ptr_irq = mode->vdisplay + 1;
+
+	DPU_DEBUG_CMDENC(cmd_enc,
+		"tc vsync_clk_speed_hz %lu vtotal %u vrefresh %u\n",
+		vsync_hz, mode->vtotal, drm_mode_vrefresh(mode));
+	DPU_DEBUG_CMDENC(cmd_enc,
+		"tc enable %u start_pos %u rd_ptr_irq %u\n",
+		tc_enable, tc_cfg.start_pos, tc_cfg.rd_ptr_irq);
+	DPU_DEBUG_CMDENC(cmd_enc,
+		"tc hw_vsync_mode %u vsync_count %u vsync_init_val %u\n",
+		tc_cfg.hw_vsync_mode, tc_cfg.vsync_count,
+		tc_cfg.vsync_init_val);
+	DPU_DEBUG_CMDENC(cmd_enc,
+		"tc cfgheight %u thresh_start %u thresh_cont %u\n",
+		tc_cfg.sync_cfg_height, tc_cfg.sync_threshold_start,
+		tc_cfg.sync_threshold_continue);
+
+	if (phys_enc->has_intf_te)
+		phys_enc->hw_intf->ops.enable_tearcheck(phys_enc->hw_intf, &tc_cfg);
+	else
+		phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, &tc_cfg);
+}
+
+static void _dpu_encoder_phys_cmd_pingpong_config(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_encoder_phys_cmd *cmd_enc =
+		to_dpu_encoder_phys_cmd(phys_enc);
+
+	if (!phys_enc->hw_pp || !phys_enc->hw_ctl->ops.setup_intf_cfg) {
+		DPU_ERROR("invalid arg(s), enc %d\n", phys_enc != NULL);
+		return;
+	}
+
+	DPU_DEBUG_CMDENC(cmd_enc, "pp %d, enabling mode:\n",
+			phys_enc->hw_pp->idx - PINGPONG_0);
+	drm_mode_debug_printmodeline(&phys_enc->cached_mode);
+
+	_dpu_encoder_phys_cmd_update_intf_cfg(phys_enc);
+	dpu_encoder_phys_cmd_tearcheck_config(phys_enc);
+}
+
+static bool dpu_encoder_phys_cmd_needs_single_flush(
+		struct dpu_encoder_phys *phys_enc)
+{
+	/**
+	 * we do separate flush for each CTL and let
+	 * CTL_START synchronize them
+	 */
+	return false;
+}
+
+static void dpu_encoder_phys_cmd_enable_helper(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_ctl *ctl;
+
+	if (!phys_enc->hw_pp) {
+		DPU_ERROR("invalid arg(s), encoder %d\n", phys_enc != NULL);
+		return;
+	}
+
+	dpu_encoder_helper_split_config(phys_enc, phys_enc->hw_intf->idx);
+
+	_dpu_encoder_phys_cmd_pingpong_config(phys_enc);
+
+	ctl = phys_enc->hw_ctl;
+	ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx);
+}
+
+static void dpu_encoder_phys_cmd_enable(struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_encoder_phys_cmd *cmd_enc =
+		to_dpu_encoder_phys_cmd(phys_enc);
+
+	if (!phys_enc->hw_pp) {
+		DPU_ERROR("invalid phys encoder\n");
+		return;
+	}
+
+	DPU_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0);
+
+	if (phys_enc->enable_state == DPU_ENC_ENABLED) {
+		DPU_ERROR("already enabled\n");
+		return;
+	}
+
+	dpu_encoder_phys_cmd_enable_helper(phys_enc);
+	phys_enc->enable_state = DPU_ENC_ENABLED;
+}
+
+static void _dpu_encoder_phys_cmd_connect_te(
+		struct dpu_encoder_phys *phys_enc, bool enable)
+{
+	if (phys_enc->has_intf_te) {
+		if (!phys_enc->hw_intf || !phys_enc->hw_intf->ops.connect_external_te)
+			return;
+
+		trace_dpu_enc_phys_cmd_connect_te(DRMID(phys_enc->parent), enable);
+		phys_enc->hw_intf->ops.connect_external_te(phys_enc->hw_intf, enable);
+	} else {
+		if (!phys_enc->hw_pp || !phys_enc->hw_pp->ops.connect_external_te)
+			return;
+
+		trace_dpu_enc_phys_cmd_connect_te(DRMID(phys_enc->parent), enable);
+		phys_enc->hw_pp->ops.connect_external_te(phys_enc->hw_pp, enable);
+	}
+}
+
+static void dpu_encoder_phys_cmd_prepare_idle_pc(
+		struct dpu_encoder_phys *phys_enc)
+{
+	_dpu_encoder_phys_cmd_connect_te(phys_enc, false);
+}
+
+static int dpu_encoder_phys_cmd_get_line_count(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_pingpong *hw_pp;
+	struct dpu_hw_intf *hw_intf;
+
+	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
+		return -EINVAL;
+
+	if (phys_enc->has_intf_te) {
+		hw_intf = phys_enc->hw_intf;
+		if (!hw_intf || !hw_intf->ops.get_line_count)
+			return -EINVAL;
+		return hw_intf->ops.get_line_count(hw_intf);
+	}
+
+	hw_pp = phys_enc->hw_pp;
+	if (!hw_pp || !hw_pp->ops.get_line_count)
+		return -EINVAL;
+	return hw_pp->ops.get_line_count(hw_pp);
+}
+
+static void dpu_encoder_phys_cmd_disable(struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_encoder_phys_cmd *cmd_enc =
+		to_dpu_encoder_phys_cmd(phys_enc);
+	struct dpu_hw_ctl *ctl;
+
+	if (phys_enc->enable_state == DPU_ENC_DISABLED) {
+		DPU_ERROR_CMDENC(cmd_enc, "already disabled\n");
+		return;
+	}
+
+	if (phys_enc->has_intf_te) {
+		DRM_DEBUG_KMS("id:%u intf:%d state:%d\n", DRMID(phys_enc->parent),
+			      phys_enc->hw_intf->idx - INTF_0,
+			      phys_enc->enable_state);
+
+		if (phys_enc->hw_intf->ops.disable_tearcheck)
+			phys_enc->hw_intf->ops.disable_tearcheck(phys_enc->hw_intf);
+	} else {
+		if (!phys_enc->hw_pp) {
+			DPU_ERROR("invalid encoder\n");
+			return;
+		}
+
+		DRM_DEBUG_KMS("id:%u pp:%d state:%d\n", DRMID(phys_enc->parent),
+			      phys_enc->hw_pp->idx - PINGPONG_0,
+			      phys_enc->enable_state);
+
+		if (phys_enc->hw_pp->ops.disable_tearcheck)
+			phys_enc->hw_pp->ops.disable_tearcheck(phys_enc->hw_pp);
+	}
+
+	if (phys_enc->hw_intf->ops.bind_pingpong_blk) {
+		phys_enc->hw_intf->ops.bind_pingpong_blk(
+				phys_enc->hw_intf,
+				PINGPONG_NONE);
+
+		ctl = phys_enc->hw_ctl;
+		ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx);
+	}
+
+	phys_enc->enable_state = DPU_ENC_DISABLED;
+}
+
+static void dpu_encoder_phys_cmd_prepare_for_kickoff(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_encoder_phys_cmd *cmd_enc =
+			to_dpu_encoder_phys_cmd(phys_enc);
+	int ret;
+
+	if (!phys_enc->hw_pp) {
+		DPU_ERROR("invalid encoder\n");
+		return;
+	}
+	DRM_DEBUG_KMS("id:%u pp:%d pending_cnt:%d\n", DRMID(phys_enc->parent),
+		      phys_enc->hw_pp->idx - PINGPONG_0,
+		      atomic_read(&phys_enc->pending_kickoff_cnt));
+
+	/*
+	 * Mark kickoff request as outstanding. If there are more than one,
+	 * outstanding, then we have to wait for the previous one to complete
+	 */
+	ret = _dpu_encoder_phys_cmd_wait_for_idle(phys_enc);
+	if (ret) {
+		/* force pending_kickoff_cnt 0 to discard failed kickoff */
+		atomic_set(&phys_enc->pending_kickoff_cnt, 0);
+		DRM_ERROR("failed wait_for_idle: id:%u ret:%d pp:%d\n",
+			  DRMID(phys_enc->parent), ret,
+			  phys_enc->hw_pp->idx - PINGPONG_0);
+	}
+
+	dpu_encoder_phys_cmd_enable_te(phys_enc);
+
+	DPU_DEBUG_CMDENC(cmd_enc, "pp:%d pending_cnt %d\n",
+			phys_enc->hw_pp->idx - PINGPONG_0,
+			atomic_read(&phys_enc->pending_kickoff_cnt));
+}
+
+static void dpu_encoder_phys_cmd_enable_te(struct dpu_encoder_phys *phys_enc)
+{
+	if (!phys_enc)
+		return;
+	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
+		return;
+
+	if (phys_enc->has_intf_te) {
+		if (!phys_enc->hw_intf->ops.disable_autorefresh)
+			return;
+
+		phys_enc->hw_intf->ops.disable_autorefresh(
+				phys_enc->hw_intf,
+				DRMID(phys_enc->parent),
+				phys_enc->cached_mode.vdisplay);
+	} else {
+		if (!phys_enc->hw_pp ||
+		    !phys_enc->hw_pp->ops.disable_autorefresh)
+			return;
+
+		phys_enc->hw_pp->ops.disable_autorefresh(
+				phys_enc->hw_pp,
+				DRMID(phys_enc->parent),
+				phys_enc->cached_mode.vdisplay);
+	}
+}
+
+static int _dpu_encoder_phys_cmd_wait_for_ctl_start(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_encoder_phys_cmd *cmd_enc =
+			to_dpu_encoder_phys_cmd(phys_enc);
+	struct dpu_encoder_wait_info wait_info;
+	int ret;
+
+	wait_info.wq = &phys_enc->pending_kickoff_wq;
+	wait_info.atomic_cnt = &phys_enc->pending_ctlstart_cnt;
+	wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
+
+	ret = dpu_encoder_helper_wait_for_irq(phys_enc,
+			phys_enc->irq[INTR_IDX_CTL_START],
+			dpu_encoder_phys_cmd_ctl_start_irq,
+			&wait_info);
+	if (ret == -ETIMEDOUT) {
+		DPU_ERROR_CMDENC(cmd_enc, "ctl start interrupt wait failed\n");
+		ret = -EINVAL;
+	} else if (!ret)
+		ret = 0;
+
+	return ret;
+}
+
+static int dpu_encoder_phys_cmd_wait_for_tx_complete(
+		struct dpu_encoder_phys *phys_enc)
+{
+	int rc;
+
+	rc = _dpu_encoder_phys_cmd_wait_for_idle(phys_enc);
+	if (rc) {
+		DRM_ERROR("failed wait_for_idle: id:%u ret:%d intf:%d\n",
+			  DRMID(phys_enc->parent), rc,
+			  phys_enc->hw_intf->idx - INTF_0);
+	}
+
+	return rc;
+}
+
+static int dpu_encoder_phys_cmd_wait_for_commit_done(
+		struct dpu_encoder_phys *phys_enc)
+{
+	/* only required for master controller */
+	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
+		return 0;
+
+	if (phys_enc->hw_ctl->ops.is_started(phys_enc->hw_ctl))
+		return dpu_encoder_phys_cmd_wait_for_tx_complete(phys_enc);
+
+	return _dpu_encoder_phys_cmd_wait_for_ctl_start(phys_enc);
+}
+
+static void dpu_encoder_phys_cmd_handle_post_kickoff(
+		struct dpu_encoder_phys *phys_enc)
+{
+	/**
+	 * re-enable external TE, either for the first time after enabling
+	 * or if disabled for Autorefresh
+	 */
+	_dpu_encoder_phys_cmd_connect_te(phys_enc, true);
+}
+
+static void dpu_encoder_phys_cmd_trigger_start(
+		struct dpu_encoder_phys *phys_enc)
+{
+	dpu_encoder_helper_trigger_start(phys_enc);
+}
+
+static void dpu_encoder_phys_cmd_init_ops(
+		struct dpu_encoder_phys_ops *ops)
+{
+	ops->is_master = dpu_encoder_phys_cmd_is_master;
+	ops->atomic_mode_set = dpu_encoder_phys_cmd_atomic_mode_set;
+	ops->enable = dpu_encoder_phys_cmd_enable;
+	ops->disable = dpu_encoder_phys_cmd_disable;
+	ops->control_vblank_irq = dpu_encoder_phys_cmd_control_vblank_irq;
+	ops->wait_for_commit_done = dpu_encoder_phys_cmd_wait_for_commit_done;
+	ops->prepare_for_kickoff = dpu_encoder_phys_cmd_prepare_for_kickoff;
+	ops->wait_for_tx_complete = dpu_encoder_phys_cmd_wait_for_tx_complete;
+	ops->trigger_start = dpu_encoder_phys_cmd_trigger_start;
+	ops->needs_single_flush = dpu_encoder_phys_cmd_needs_single_flush;
+	ops->irq_control = dpu_encoder_phys_cmd_irq_control;
+	ops->restore = dpu_encoder_phys_cmd_enable_helper;
+	ops->prepare_idle_pc = dpu_encoder_phys_cmd_prepare_idle_pc;
+	ops->handle_post_kickoff = dpu_encoder_phys_cmd_handle_post_kickoff;
+	ops->get_line_count = dpu_encoder_phys_cmd_get_line_count;
+}
+
+struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(struct drm_device *dev,
+		struct dpu_enc_phys_init_params *p)
+{
+	struct dpu_encoder_phys *phys_enc = NULL;
+	struct dpu_encoder_phys_cmd *cmd_enc = NULL;
+
+	DPU_DEBUG("intf\n");
+
+	cmd_enc = drmm_kzalloc(dev, sizeof(*cmd_enc), GFP_KERNEL);
+	if (!cmd_enc) {
+		DPU_ERROR("failed to allocate\n");
+		return ERR_PTR(-ENOMEM);
+	}
+	phys_enc = &cmd_enc->base;
+
+	dpu_encoder_phys_init(phys_enc, p);
+
+	mutex_init(&phys_enc->vblank_ctl_lock);
+	phys_enc->vblank_refcount = 0;
+
+	dpu_encoder_phys_cmd_init_ops(&phys_enc->ops);
+	phys_enc->intf_mode = INTF_MODE_CMD;
+	cmd_enc->stream_sel = 0;
+
+	if (!phys_enc->hw_intf) {
+		DPU_ERROR_CMDENC(cmd_enc, "no INTF provided\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	/* DPU before 5.0 use PINGPONG for TE handling */
+	if (phys_enc->dpu_kms->catalog->mdss_ver->core_major_ver >= 5)
+		phys_enc->has_intf_te = true;
+
+	if (phys_enc->has_intf_te && !phys_enc->hw_intf->ops.enable_tearcheck) {
+		DPU_ERROR_CMDENC(cmd_enc, "tearcheck not supported\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	atomic_set(&cmd_enc->pending_vblank_cnt, 0);
+	init_waitqueue_head(&cmd_enc->pending_vblank_wq);
+
+	DPU_DEBUG_CMDENC(cmd_enc, "created\n");
+
+	return phys_enc;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_encoder_phys_vid.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_encoder_phys_vid.c
@@ -0,0 +1,751 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2015-2018, 2020-2021 The Linux Foundation. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+#include "dpu_encoder_phys.h"
+#include "dpu_hw_interrupts.h"
+#include "dpu_hw_merge3d.h"
+#include "dpu_core_irq.h"
+#include "dpu_formats.h"
+#include "dpu_trace.h"
+#include "disp/msm_disp_snapshot.h"
+
+#include <drm/drm_managed.h>
+
+#define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
+		(e) && (e)->parent ? \
+		(e)->parent->base.id : -1, \
+		(e) && (e)->hw_intf ? \
+		(e)->hw_intf->idx - INTF_0 : -1, ##__VA_ARGS__)
+
+#define DPU_ERROR_VIDENC(e, fmt, ...) DPU_ERROR("enc%d intf%d " fmt, \
+		(e) && (e)->parent ? \
+		(e)->parent->base.id : -1, \
+		(e) && (e)->hw_intf ? \
+		(e)->hw_intf->idx - INTF_0 : -1, ##__VA_ARGS__)
+
+#define to_dpu_encoder_phys_vid(x) \
+	container_of(x, struct dpu_encoder_phys_vid, base)
+
+static bool dpu_encoder_phys_vid_is_master(
+		struct dpu_encoder_phys *phys_enc)
+{
+	bool ret = false;
+
+	if (phys_enc->split_role != ENC_ROLE_SLAVE)
+		ret = true;
+
+	return ret;
+}
+
+static void drm_mode_to_intf_timing_params(
+		const struct dpu_encoder_phys *phys_enc,
+		const struct drm_display_mode *mode,
+		struct dpu_hw_intf_timing_params *timing)
+{
+	memset(timing, 0, sizeof(*timing));
+
+	if ((mode->htotal < mode->hsync_end)
+			|| (mode->hsync_start < mode->hdisplay)
+			|| (mode->vtotal < mode->vsync_end)
+			|| (mode->vsync_start < mode->vdisplay)
+			|| (mode->hsync_end < mode->hsync_start)
+			|| (mode->vsync_end < mode->vsync_start)) {
+		DPU_ERROR(
+		    "invalid params - hstart:%d,hend:%d,htot:%d,hdisplay:%d\n",
+				mode->hsync_start, mode->hsync_end,
+				mode->htotal, mode->hdisplay);
+		DPU_ERROR("vstart:%d,vend:%d,vtot:%d,vdisplay:%d\n",
+				mode->vsync_start, mode->vsync_end,
+				mode->vtotal, mode->vdisplay);
+		return;
+	}
+
+	/*
+	 * https://www.kernel.org/doc/htmldocs/drm/ch02s05.html
+	 *  Active Region      Front Porch   Sync   Back Porch
+	 * <-----------------><------------><-----><----------->
+	 * <- [hv]display --->
+	 * <--------- [hv]sync_start ------>
+	 * <----------------- [hv]sync_end ------->
+	 * <---------------------------- [hv]total ------------->
+	 */
+	timing->width = mode->hdisplay;	/* active width */
+	timing->height = mode->vdisplay;	/* active height */
+	timing->xres = timing->width;
+	timing->yres = timing->height;
+	timing->h_back_porch = mode->htotal - mode->hsync_end;
+	timing->h_front_porch = mode->hsync_start - mode->hdisplay;
+	timing->v_back_porch = mode->vtotal - mode->vsync_end;
+	timing->v_front_porch = mode->vsync_start - mode->vdisplay;
+	timing->hsync_pulse_width = mode->hsync_end - mode->hsync_start;
+	timing->vsync_pulse_width = mode->vsync_end - mode->vsync_start;
+	timing->hsync_polarity = (mode->flags & DRM_MODE_FLAG_NHSYNC) ? 1 : 0;
+	timing->vsync_polarity = (mode->flags & DRM_MODE_FLAG_NVSYNC) ? 1 : 0;
+	timing->border_clr = 0;
+	timing->underflow_clr = 0xff;
+	timing->hsync_skew = mode->hskew;
+
+	/* DSI controller cannot handle active-low sync signals. */
+	if (phys_enc->hw_intf->cap->type == INTF_DSI) {
+		timing->hsync_polarity = 0;
+		timing->vsync_polarity = 0;
+	}
+
+	/* for DP/EDP, Shift timings to align it to bottom right */
+	if (phys_enc->hw_intf->cap->type == INTF_DP) {
+		timing->h_back_porch += timing->h_front_porch;
+		timing->h_front_porch = 0;
+		timing->v_back_porch += timing->v_front_porch;
+		timing->v_front_porch = 0;
+	}
+
+	timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent);
+	timing->compression_en = dpu_encoder_is_dsc_enabled(phys_enc->parent);
+
+	/*
+	 * for DP, divide the horizonal parameters by 2 when
+	 * widebus is enabled
+	 */
+	if (phys_enc->hw_intf->cap->type == INTF_DP && timing->wide_bus_en) {
+		timing->width = timing->width >> 1;
+		timing->xres = timing->xres >> 1;
+		timing->h_back_porch = timing->h_back_porch >> 1;
+		timing->h_front_porch = timing->h_front_porch >> 1;
+		timing->hsync_pulse_width = timing->hsync_pulse_width >> 1;
+	}
+}
+
+static u32 get_horizontal_total(const struct dpu_hw_intf_timing_params *timing)
+{
+	u32 active = timing->xres;
+	u32 inactive =
+	    timing->h_back_porch + timing->h_front_porch +
+	    timing->hsync_pulse_width;
+	return active + inactive;
+}
+
+static u32 get_vertical_total(const struct dpu_hw_intf_timing_params *timing)
+{
+	u32 active = timing->yres;
+	u32 inactive =
+	    timing->v_back_porch + timing->v_front_porch +
+	    timing->vsync_pulse_width;
+	return active + inactive;
+}
+
+/*
+ * programmable_fetch_get_num_lines:
+ *	Number of fetch lines in vertical front porch
+ * @timing: Pointer to the intf timing information for the requested mode
+ *
+ * Returns the number of fetch lines in vertical front porch at which mdp
+ * can start fetching the next frame.
+ *
+ * Number of needed prefetch lines is anything that cannot be absorbed in the
+ * start of frame time (back porch + vsync pulse width).
+ *
+ * Some panels have very large VFP, however we only need a total number of
+ * lines based on the chip worst case latencies.
+ */
+static u32 programmable_fetch_get_num_lines(
+		struct dpu_encoder_phys *phys_enc,
+		const struct dpu_hw_intf_timing_params *timing)
+{
+	u32 worst_case_needed_lines =
+	    phys_enc->hw_intf->cap->prog_fetch_lines_worst_case;
+	u32 start_of_frame_lines =
+	    timing->v_back_porch + timing->vsync_pulse_width;
+	u32 needed_vfp_lines = worst_case_needed_lines - start_of_frame_lines;
+	u32 actual_vfp_lines = 0;
+
+	/* Fetch must be outside active lines, otherwise undefined. */
+	if (start_of_frame_lines >= worst_case_needed_lines) {
+		DPU_DEBUG_VIDENC(phys_enc,
+				"prog fetch is not needed, large vbp+vsw\n");
+		actual_vfp_lines = 0;
+	} else if (timing->v_front_porch < needed_vfp_lines) {
+		/* Warn fetch needed, but not enough porch in panel config */
+		pr_warn_once
+			("low vbp+vfp may lead to perf issues in some cases\n");
+		DPU_DEBUG_VIDENC(phys_enc,
+				"less vfp than fetch req, using entire vfp\n");
+		actual_vfp_lines = timing->v_front_porch;
+	} else {
+		DPU_DEBUG_VIDENC(phys_enc, "room in vfp for needed prefetch\n");
+		actual_vfp_lines = needed_vfp_lines;
+	}
+
+	DPU_DEBUG_VIDENC(phys_enc,
+		"v_front_porch %u v_back_porch %u vsync_pulse_width %u\n",
+		timing->v_front_porch, timing->v_back_porch,
+		timing->vsync_pulse_width);
+	DPU_DEBUG_VIDENC(phys_enc,
+		"wc_lines %u needed_vfp_lines %u actual_vfp_lines %u\n",
+		worst_case_needed_lines, needed_vfp_lines, actual_vfp_lines);
+
+	return actual_vfp_lines;
+}
+
+/*
+ * programmable_fetch_config: Programs HW to prefetch lines by offsetting
+ *	the start of fetch into the vertical front porch for cases where the
+ *	vsync pulse width and vertical back porch time is insufficient
+ *
+ *	Gets # of lines to pre-fetch, then calculate VSYNC counter value.
+ *	HW layer requires VSYNC counter of first pixel of tgt VFP line.
+ *
+ * @timing: Pointer to the intf timing information for the requested mode
+ */
+static void programmable_fetch_config(struct dpu_encoder_phys *phys_enc,
+				      const struct dpu_hw_intf_timing_params *timing)
+{
+	struct dpu_hw_intf_prog_fetch f = { 0 };
+	u32 vfp_fetch_lines = 0;
+	u32 horiz_total = 0;
+	u32 vert_total = 0;
+	u32 vfp_fetch_start_vsync_counter = 0;
+	unsigned long lock_flags;
+
+	if (WARN_ON_ONCE(!phys_enc->hw_intf->ops.setup_prg_fetch))
+		return;
+
+	vfp_fetch_lines = programmable_fetch_get_num_lines(phys_enc, timing);
+	if (vfp_fetch_lines) {
+		vert_total = get_vertical_total(timing);
+		horiz_total = get_horizontal_total(timing);
+		vfp_fetch_start_vsync_counter =
+		    (vert_total - vfp_fetch_lines) * horiz_total + 1;
+		f.enable = 1;
+		f.fetch_start = vfp_fetch_start_vsync_counter;
+	}
+
+	DPU_DEBUG_VIDENC(phys_enc,
+		"vfp_fetch_lines %u vfp_fetch_start_vsync_counter %u\n",
+		vfp_fetch_lines, vfp_fetch_start_vsync_counter);
+
+	spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
+	phys_enc->hw_intf->ops.setup_prg_fetch(phys_enc->hw_intf, &f);
+	spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
+}
+
+static void dpu_encoder_phys_vid_setup_timing_engine(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct drm_display_mode mode;
+	struct dpu_hw_intf_timing_params timing_params = { 0 };
+	const struct dpu_format *fmt = NULL;
+	u32 fmt_fourcc;
+	unsigned long lock_flags;
+	struct dpu_hw_intf_cfg intf_cfg = { 0 };
+
+	drm_mode_init(&mode, &phys_enc->cached_mode);
+
+	if (!phys_enc->hw_ctl->ops.setup_intf_cfg) {
+		DPU_ERROR("invalid encoder %d\n", phys_enc != NULL);
+		return;
+	}
+
+	if (!phys_enc->hw_intf->ops.setup_timing_gen) {
+		DPU_ERROR("timing engine setup is not supported\n");
+		return;
+	}
+
+	DPU_DEBUG_VIDENC(phys_enc, "enabling mode:\n");
+	drm_mode_debug_printmodeline(&mode);
+
+	fmt_fourcc = dpu_encoder_get_drm_fmt(phys_enc);
+
+	if (phys_enc->split_role != ENC_ROLE_SOLO || fmt_fourcc == DRM_FORMAT_YUV420) {
+		mode.hdisplay >>= 1;
+		mode.htotal >>= 1;
+		mode.hsync_start >>= 1;
+		mode.hsync_end >>= 1;
+		mode.hskew >>= 1;
+
+		DPU_DEBUG_VIDENC(phys_enc,
+			"split_role %d, halve horizontal %d %d %d %d %d\n",
+			phys_enc->split_role,
+			mode.hdisplay, mode.htotal,
+			mode.hsync_start, mode.hsync_end,
+			mode.hskew);
+	}
+
+	drm_mode_to_intf_timing_params(phys_enc, &mode, &timing_params);
+
+	fmt = dpu_get_dpu_format(fmt_fourcc);
+	DPU_DEBUG_VIDENC(phys_enc, "fmt_fourcc 0x%X\n", fmt_fourcc);
+
+	if (phys_enc->hw_cdm)
+		intf_cfg.cdm = phys_enc->hw_cdm->idx;
+	intf_cfg.intf = phys_enc->hw_intf->idx;
+	intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_VID;
+	intf_cfg.stream_sel = 0; /* Don't care value for video mode */
+	intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
+	intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc);
+	if (phys_enc->hw_pp->merge_3d)
+		intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx;
+
+	spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
+	phys_enc->hw_intf->ops.setup_timing_gen(phys_enc->hw_intf,
+			&timing_params, fmt);
+	phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg);
+
+	/* setup which pp blk will connect to this intf */
+	if (phys_enc->hw_intf->ops.bind_pingpong_blk)
+		phys_enc->hw_intf->ops.bind_pingpong_blk(
+				phys_enc->hw_intf,
+				phys_enc->hw_pp->idx);
+
+	if (phys_enc->hw_pp->merge_3d)
+		phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, intf_cfg.mode_3d);
+
+	spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
+
+	programmable_fetch_config(phys_enc, &timing_params);
+}
+
+static void dpu_encoder_phys_vid_vblank_irq(void *arg)
+{
+	struct dpu_encoder_phys *phys_enc = arg;
+	struct dpu_hw_ctl *hw_ctl;
+	unsigned long lock_flags;
+	u32 flush_register = 0;
+
+	hw_ctl = phys_enc->hw_ctl;
+
+	DPU_ATRACE_BEGIN("vblank_irq");
+
+	dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
+
+	atomic_read(&phys_enc->pending_kickoff_cnt);
+
+	/*
+	 * only decrement the pending flush count if we've actually flushed
+	 * hardware. due to sw irq latency, vblank may have already happened
+	 * so we need to double-check with hw that it accepted the flush bits
+	 */
+	spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
+	if (hw_ctl->ops.get_flush_register)
+		flush_register = hw_ctl->ops.get_flush_register(hw_ctl);
+
+	if (!(flush_register & hw_ctl->ops.get_pending_flush(hw_ctl)))
+		atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
+	spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
+
+	/* Signal any waiting atomic commit thread */
+	wake_up_all(&phys_enc->pending_kickoff_wq);
+
+	dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc,
+			DPU_ENCODER_FRAME_EVENT_DONE);
+
+	DPU_ATRACE_END("vblank_irq");
+}
+
+static void dpu_encoder_phys_vid_underrun_irq(void *arg)
+{
+	struct dpu_encoder_phys *phys_enc = arg;
+
+	dpu_encoder_underrun_callback(phys_enc->parent, phys_enc);
+}
+
+static bool dpu_encoder_phys_vid_needs_single_flush(
+		struct dpu_encoder_phys *phys_enc)
+{
+	return phys_enc->split_role != ENC_ROLE_SOLO;
+}
+
+static void dpu_encoder_phys_vid_atomic_mode_set(
+		struct dpu_encoder_phys *phys_enc,
+		struct drm_crtc_state *crtc_state,
+		struct drm_connector_state *conn_state)
+{
+	phys_enc->irq[INTR_IDX_VSYNC] = phys_enc->hw_intf->cap->intr_vsync;
+
+	phys_enc->irq[INTR_IDX_UNDERRUN] = phys_enc->hw_intf->cap->intr_underrun;
+}
+
+static int dpu_encoder_phys_vid_control_vblank_irq(
+		struct dpu_encoder_phys *phys_enc,
+		bool enable)
+{
+	int ret = 0;
+	int refcount;
+
+	mutex_lock(&phys_enc->vblank_ctl_lock);
+	refcount = phys_enc->vblank_refcount;
+
+	/* Slave encoders don't report vblank */
+	if (!dpu_encoder_phys_vid_is_master(phys_enc))
+		goto end;
+
+	/* protect against negative */
+	if (!enable && refcount == 0) {
+		ret = -EINVAL;
+		goto end;
+	}
+
+	DRM_DEBUG_VBL("id:%u enable=%d/%d\n", DRMID(phys_enc->parent), enable,
+		      refcount);
+
+	if (enable) {
+		if (phys_enc->vblank_refcount == 0)
+			ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
+					phys_enc->irq[INTR_IDX_VSYNC],
+					dpu_encoder_phys_vid_vblank_irq,
+					phys_enc);
+		if (!ret)
+			phys_enc->vblank_refcount++;
+	} else if (!enable) {
+		if (phys_enc->vblank_refcount == 1)
+			ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
+					phys_enc->irq[INTR_IDX_VSYNC]);
+		if (!ret)
+			phys_enc->vblank_refcount--;
+	}
+
+end:
+	mutex_unlock(&phys_enc->vblank_ctl_lock);
+	if (ret) {
+		DRM_ERROR("failed: id:%u intf:%d ret:%d enable:%d refcnt:%d\n",
+			  DRMID(phys_enc->parent),
+			  phys_enc->hw_intf->idx - INTF_0, ret, enable,
+			  refcount);
+	}
+	return ret;
+}
+
+static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_ctl *ctl;
+	const struct dpu_format *fmt;
+	u32 fmt_fourcc;
+
+	ctl = phys_enc->hw_ctl;
+	fmt_fourcc = dpu_encoder_get_drm_fmt(phys_enc);
+	fmt = dpu_get_dpu_format(fmt_fourcc);
+
+	DPU_DEBUG_VIDENC(phys_enc, "\n");
+
+	if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing))
+		return;
+
+	dpu_encoder_helper_split_config(phys_enc, phys_enc->hw_intf->idx);
+
+	dpu_encoder_helper_phys_setup_cdm(phys_enc, fmt, CDM_CDWN_OUTPUT_HDMI);
+
+	dpu_encoder_phys_vid_setup_timing_engine(phys_enc);
+
+	/*
+	 * For single flush cases (dual-ctl or pp-split), skip setting the
+	 * flush bit for the slave intf, since both intfs use same ctl
+	 * and HW will only flush the master.
+	 */
+	if (dpu_encoder_phys_vid_needs_single_flush(phys_enc) &&
+		!dpu_encoder_phys_vid_is_master(phys_enc))
+		goto skip_flush;
+
+	ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx);
+	if (ctl->ops.update_pending_flush_merge_3d && phys_enc->hw_pp->merge_3d)
+		ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx);
+
+	if (ctl->ops.update_pending_flush_cdm && phys_enc->hw_cdm)
+		ctl->ops.update_pending_flush_cdm(ctl, phys_enc->hw_cdm->idx);
+
+	/*
+	 * Peripheral flush must be updated whenever flushing SDP packets is needed.
+	 * SDP packets are required for any YUV format (YUV420, YUV422, YUV444).
+	 */
+	if (ctl->ops.update_pending_flush_periph && dpu_encoder_needs_periph_flush(phys_enc))
+		ctl->ops.update_pending_flush_periph(ctl, phys_enc->hw_intf->idx);
+
+skip_flush:
+	DPU_DEBUG_VIDENC(phys_enc,
+		"update pending flush ctl %d intf %d\n",
+		ctl->idx - CTL_0, phys_enc->hw_intf->idx);
+
+	atomic_set(&phys_enc->underrun_cnt, 0);
+
+	/* ctl_flush & timing engine enable will be triggered by framework */
+	if (phys_enc->enable_state == DPU_ENC_DISABLED)
+		phys_enc->enable_state = DPU_ENC_ENABLING;
+}
+
+static int dpu_encoder_phys_vid_wait_for_tx_complete(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_encoder_wait_info wait_info;
+	int ret;
+
+	wait_info.wq = &phys_enc->pending_kickoff_wq;
+	wait_info.atomic_cnt = &phys_enc->pending_kickoff_cnt;
+	wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
+
+	if (!dpu_encoder_phys_vid_is_master(phys_enc)) {
+		return 0;
+	}
+
+	/* Wait for kickoff to complete */
+	ret = dpu_encoder_helper_wait_for_irq(phys_enc,
+			phys_enc->irq[INTR_IDX_VSYNC],
+			dpu_encoder_phys_vid_vblank_irq,
+			&wait_info);
+
+	if (ret == -ETIMEDOUT) {
+		dpu_encoder_helper_report_irq_timeout(phys_enc, INTR_IDX_VSYNC);
+	}
+
+	return ret;
+}
+
+static int dpu_encoder_phys_vid_wait_for_commit_done(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_ctl *hw_ctl = phys_enc->hw_ctl;
+	int ret;
+
+	if (!hw_ctl)
+		return 0;
+
+	ret = wait_event_timeout(phys_enc->pending_kickoff_wq,
+		(hw_ctl->ops.get_flush_register(hw_ctl) == 0),
+		msecs_to_jiffies(50));
+	if (ret <= 0) {
+		DPU_ERROR("vblank timeout\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
+static void dpu_encoder_phys_vid_prepare_for_kickoff(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_ctl *ctl;
+	int rc;
+	struct drm_encoder *drm_enc;
+
+	drm_enc = phys_enc->parent;
+
+	ctl = phys_enc->hw_ctl;
+	if (!ctl->ops.wait_reset_status)
+		return;
+
+	/*
+	 * hw supports hardware initiated ctl reset, so before we kickoff a new
+	 * frame, need to check and wait for hw initiated ctl reset completion
+	 */
+	rc = ctl->ops.wait_reset_status(ctl);
+	if (rc) {
+		DPU_ERROR_VIDENC(phys_enc, "ctl %d reset failure: %d\n",
+				ctl->idx, rc);
+		msm_disp_snapshot_state(drm_enc->dev);
+		dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
+				phys_enc->irq[INTR_IDX_VSYNC]);
+	}
+}
+
+static void dpu_encoder_phys_vid_disable(struct dpu_encoder_phys *phys_enc)
+{
+	unsigned long lock_flags;
+	int ret;
+	struct dpu_hw_intf_status intf_status = {0};
+
+	if (!phys_enc->parent || !phys_enc->parent->dev) {
+		DPU_ERROR("invalid encoder/device\n");
+		return;
+	}
+
+	if (!phys_enc->hw_intf) {
+		DPU_ERROR("invalid hw_intf %d hw_ctl %d\n",
+				phys_enc->hw_intf != NULL, phys_enc->hw_ctl != NULL);
+		return;
+	}
+
+	if (WARN_ON(!phys_enc->hw_intf->ops.enable_timing))
+		return;
+
+	if (phys_enc->enable_state == DPU_ENC_DISABLED) {
+		DPU_ERROR("already disabled\n");
+		return;
+	}
+
+	spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
+	phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 0);
+	if (dpu_encoder_phys_vid_is_master(phys_enc))
+		dpu_encoder_phys_inc_pending(phys_enc);
+	spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
+
+	/*
+	 * Wait for a vsync so we know the ENABLE=0 latched before
+	 * the (connector) source of the vsync's gets disabled,
+	 * otherwise we end up in a funny state if we re-enable
+	 * before the disable latches, which results that some of
+	 * the settings changes for the new modeset (like new
+	 * scanout buffer) don't latch properly..
+	 */
+	if (dpu_encoder_phys_vid_is_master(phys_enc)) {
+		ret = dpu_encoder_phys_vid_wait_for_tx_complete(phys_enc);
+		if (ret) {
+			atomic_set(&phys_enc->pending_kickoff_cnt, 0);
+			DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n",
+				  DRMID(phys_enc->parent),
+				  phys_enc->hw_intf->idx - INTF_0, ret);
+		}
+	}
+
+	if (phys_enc->hw_intf && phys_enc->hw_intf->ops.get_status)
+		phys_enc->hw_intf->ops.get_status(phys_enc->hw_intf, &intf_status);
+
+	/*
+	 * Wait for a vsync if timing en status is on after timing engine
+	 * is disabled.
+	 */
+	if (intf_status.is_en && dpu_encoder_phys_vid_is_master(phys_enc)) {
+		spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
+		dpu_encoder_phys_inc_pending(phys_enc);
+		spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
+		ret = dpu_encoder_phys_vid_wait_for_tx_complete(phys_enc);
+		if (ret) {
+			atomic_set(&phys_enc->pending_kickoff_cnt, 0);
+			DRM_ERROR("wait disable failed: id:%u intf:%d ret:%d\n",
+				  DRMID(phys_enc->parent),
+				  phys_enc->hw_intf->idx - INTF_0, ret);
+		}
+	}
+
+	dpu_encoder_helper_phys_cleanup(phys_enc);
+	phys_enc->enable_state = DPU_ENC_DISABLED;
+}
+
+static void dpu_encoder_phys_vid_handle_post_kickoff(
+		struct dpu_encoder_phys *phys_enc)
+{
+	unsigned long lock_flags;
+
+	/*
+	 * Video mode must flush CTL before enabling timing engine
+	 * Video encoders need to turn on their interfaces now
+	 */
+	if (phys_enc->enable_state == DPU_ENC_ENABLING) {
+		trace_dpu_enc_phys_vid_post_kickoff(DRMID(phys_enc->parent),
+				    phys_enc->hw_intf->idx - INTF_0);
+		spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
+		phys_enc->hw_intf->ops.enable_timing(phys_enc->hw_intf, 1);
+		spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
+		phys_enc->enable_state = DPU_ENC_ENABLED;
+	}
+}
+
+static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc,
+		bool enable)
+{
+	int ret;
+
+	trace_dpu_enc_phys_vid_irq_ctrl(DRMID(phys_enc->parent),
+			    phys_enc->hw_intf->idx - INTF_0,
+			    enable,
+			   phys_enc->vblank_refcount);
+
+	if (enable) {
+		ret = dpu_encoder_phys_vid_control_vblank_irq(phys_enc, true);
+		if (WARN_ON(ret))
+			return;
+
+		dpu_core_irq_register_callback(phys_enc->dpu_kms,
+				phys_enc->irq[INTR_IDX_UNDERRUN],
+				dpu_encoder_phys_vid_underrun_irq,
+				phys_enc);
+	} else {
+		dpu_encoder_phys_vid_control_vblank_irq(phys_enc, false);
+		dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
+				phys_enc->irq[INTR_IDX_UNDERRUN]);
+	}
+}
+
+static int dpu_encoder_phys_vid_get_line_count(
+		struct dpu_encoder_phys *phys_enc)
+{
+	if (!dpu_encoder_phys_vid_is_master(phys_enc))
+		return -EINVAL;
+
+	if (!phys_enc->hw_intf || !phys_enc->hw_intf->ops.get_line_count)
+		return -EINVAL;
+
+	return phys_enc->hw_intf->ops.get_line_count(phys_enc->hw_intf);
+}
+
+static int dpu_encoder_phys_vid_get_frame_count(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_intf_status s = {0};
+	u32 fetch_start = 0;
+	struct drm_display_mode mode;
+
+	drm_mode_init(&mode, &phys_enc->cached_mode);
+
+	if (!dpu_encoder_phys_vid_is_master(phys_enc))
+		return -EINVAL;
+
+	if (!phys_enc->hw_intf || !phys_enc->hw_intf->ops.get_status)
+		return -EINVAL;
+
+	phys_enc->hw_intf->ops.get_status(phys_enc->hw_intf, &s);
+
+	if (s.is_prog_fetch_en && s.is_en) {
+		fetch_start = mode.vtotal - (mode.vsync_start - mode.vdisplay);
+		if ((s.line_count > fetch_start) &&
+			(s.line_count <= mode.vtotal))
+			return s.frame_count + 1;
+	}
+
+	return s.frame_count;
+}
+
+static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops)
+{
+	ops->is_master = dpu_encoder_phys_vid_is_master;
+	ops->atomic_mode_set = dpu_encoder_phys_vid_atomic_mode_set;
+	ops->enable = dpu_encoder_phys_vid_enable;
+	ops->disable = dpu_encoder_phys_vid_disable;
+	ops->control_vblank_irq = dpu_encoder_phys_vid_control_vblank_irq;
+	ops->wait_for_commit_done = dpu_encoder_phys_vid_wait_for_commit_done;
+	ops->wait_for_tx_complete = dpu_encoder_phys_vid_wait_for_tx_complete;
+	ops->irq_control = dpu_encoder_phys_vid_irq_control;
+	ops->prepare_for_kickoff = dpu_encoder_phys_vid_prepare_for_kickoff;
+	ops->handle_post_kickoff = dpu_encoder_phys_vid_handle_post_kickoff;
+	ops->needs_single_flush = dpu_encoder_phys_vid_needs_single_flush;
+	ops->get_line_count = dpu_encoder_phys_vid_get_line_count;
+	ops->get_frame_count = dpu_encoder_phys_vid_get_frame_count;
+}
+
+struct dpu_encoder_phys *dpu_encoder_phys_vid_init(struct drm_device *dev,
+		struct dpu_enc_phys_init_params *p)
+{
+	struct dpu_encoder_phys *phys_enc = NULL;
+
+	if (!p) {
+		DPU_ERROR("failed to create encoder due to invalid parameter\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	phys_enc = drmm_kzalloc(dev, sizeof(*phys_enc), GFP_KERNEL);
+	if (!phys_enc) {
+		DPU_ERROR("failed to create encoder due to memory allocation error\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	DPU_DEBUG_VIDENC(phys_enc, "\n");
+
+	dpu_encoder_phys_init(phys_enc, p);
+	mutex_init(&phys_enc->vblank_ctl_lock);
+	phys_enc->vblank_refcount = 0;
+
+	dpu_encoder_phys_vid_init_ops(&phys_enc->ops);
+	phys_enc->intf_mode = INTF_MODE_VIDEO;
+
+	DPU_DEBUG_VIDENC(phys_enc, "created intf idx:%d\n", p->hw_intf->idx);
+
+	return phys_enc;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_encoder_phys_wb.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_encoder_phys_wb.c
@@ -0,0 +1,694 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+
+#include <linux/debugfs.h>
+
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_managed.h>
+
+#include "dpu_encoder_phys.h"
+#include "dpu_formats.h"
+#include "dpu_hw_top.h"
+#include "dpu_hw_wb.h"
+#include "dpu_hw_lm.h"
+#include "dpu_hw_merge3d.h"
+#include "dpu_hw_interrupts.h"
+#include "dpu_core_irq.h"
+#include "dpu_vbif.h"
+#include "dpu_crtc.h"
+#include "disp/msm_disp_snapshot.h"
+
+#define to_dpu_encoder_phys_wb(x) \
+	container_of(x, struct dpu_encoder_phys_wb, base)
+
+/**
+ * dpu_encoder_phys_wb_is_master - report wb always as master encoder
+ * @phys_enc:	Pointer to physical encoder
+ */
+static bool dpu_encoder_phys_wb_is_master(struct dpu_encoder_phys *phys_enc)
+{
+	/* there is only one physical enc for dpu_writeback */
+	return true;
+}
+
+static bool _dpu_encoder_phys_wb_clk_force_ctrl(struct dpu_hw_wb *wb,
+						struct dpu_hw_mdp *mdp,
+						bool enable, bool *forced_on)
+{
+	if (wb->ops.setup_clk_force_ctrl) {
+		*forced_on = wb->ops.setup_clk_force_ctrl(wb, enable);
+		return true;
+	}
+
+	if (mdp->ops.setup_clk_force_ctrl) {
+		*forced_on = mdp->ops.setup_clk_force_ctrl(mdp, wb->caps->clk_ctrl, enable);
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * dpu_encoder_phys_wb_set_ot_limit - set OT limit for writeback interface
+ * @phys_enc:	Pointer to physical encoder
+ */
+static void dpu_encoder_phys_wb_set_ot_limit(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_wb *hw_wb = phys_enc->hw_wb;
+	struct dpu_vbif_set_ot_params ot_params;
+	bool forced_on = false;
+
+	memset(&ot_params, 0, sizeof(ot_params));
+	ot_params.xin_id = hw_wb->caps->xin_id;
+	ot_params.num = hw_wb->idx - WB_0;
+	ot_params.width = phys_enc->cached_mode.hdisplay;
+	ot_params.height = phys_enc->cached_mode.vdisplay;
+	ot_params.is_wfd = true;
+	ot_params.frame_rate = drm_mode_vrefresh(&phys_enc->cached_mode);
+	ot_params.vbif_idx = hw_wb->caps->vbif_idx;
+	ot_params.rd = false;
+
+	if (!_dpu_encoder_phys_wb_clk_force_ctrl(hw_wb, phys_enc->dpu_kms->hw_mdp,
+						 true, &forced_on))
+		return;
+
+	dpu_vbif_set_ot_limit(phys_enc->dpu_kms, &ot_params);
+
+	if (forced_on)
+		_dpu_encoder_phys_wb_clk_force_ctrl(hw_wb, phys_enc->dpu_kms->hw_mdp,
+						    false, &forced_on);
+}
+
+/**
+ * dpu_encoder_phys_wb_set_qos_remap - set QoS remapper for writeback
+ * @phys_enc:	Pointer to physical encoder
+ */
+static void dpu_encoder_phys_wb_set_qos_remap(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_wb *hw_wb;
+	struct dpu_vbif_set_qos_params qos_params;
+	bool forced_on = false;
+
+	if (!phys_enc || !phys_enc->parent || !phys_enc->parent->crtc) {
+		DPU_ERROR("invalid arguments\n");
+		return;
+	}
+
+	if (!phys_enc->hw_wb || !phys_enc->hw_wb->caps) {
+		DPU_ERROR("invalid writeback hardware\n");
+		return;
+	}
+
+	hw_wb = phys_enc->hw_wb;
+
+	memset(&qos_params, 0, sizeof(qos_params));
+	qos_params.vbif_idx = hw_wb->caps->vbif_idx;
+	qos_params.xin_id = hw_wb->caps->xin_id;
+	qos_params.num = hw_wb->idx - WB_0;
+	qos_params.is_rt = false;
+
+	DPU_DEBUG("[qos_remap] wb:%d vbif:%d xin:%d is_rt:%d\n",
+			qos_params.num,
+			qos_params.vbif_idx,
+			qos_params.xin_id, qos_params.is_rt);
+
+	if (!_dpu_encoder_phys_wb_clk_force_ctrl(hw_wb, phys_enc->dpu_kms->hw_mdp,
+						 true, &forced_on))
+		return;
+
+	dpu_vbif_set_qos_remap(phys_enc->dpu_kms, &qos_params);
+
+	if (forced_on)
+		_dpu_encoder_phys_wb_clk_force_ctrl(hw_wb, phys_enc->dpu_kms->hw_mdp,
+						    false, &forced_on);
+}
+
+/**
+ * dpu_encoder_phys_wb_set_qos - set QoS/danger/safe LUTs for writeback
+ * @phys_enc:	Pointer to physical encoder
+ */
+static void dpu_encoder_phys_wb_set_qos(struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_wb *hw_wb;
+	struct dpu_hw_qos_cfg qos_cfg;
+	const struct dpu_mdss_cfg *catalog;
+	const struct dpu_qos_lut_tbl *qos_lut_tb;
+
+	if (!phys_enc || !phys_enc->dpu_kms || !phys_enc->dpu_kms->catalog) {
+		DPU_ERROR("invalid parameter(s)\n");
+		return;
+	}
+
+	catalog = phys_enc->dpu_kms->catalog;
+
+	hw_wb = phys_enc->hw_wb;
+
+	memset(&qos_cfg, 0, sizeof(struct dpu_hw_qos_cfg));
+	qos_cfg.danger_safe_en = true;
+	qos_cfg.danger_lut =
+		catalog->perf->danger_lut_tbl[DPU_QOS_LUT_USAGE_NRT];
+
+	qos_cfg.safe_lut = catalog->perf->safe_lut_tbl[DPU_QOS_LUT_USAGE_NRT];
+
+	qos_lut_tb = &catalog->perf->qos_lut_tbl[DPU_QOS_LUT_USAGE_NRT];
+	qos_cfg.creq_lut = _dpu_hw_get_qos_lut(qos_lut_tb, 0);
+
+	if (hw_wb->ops.setup_qos_lut)
+		hw_wb->ops.setup_qos_lut(hw_wb, &qos_cfg);
+}
+
+/**
+ * dpu_encoder_phys_wb_setup_fb - setup output framebuffer
+ * @phys_enc:	Pointer to physical encoder
+ * @fb:		Pointer to output framebuffer
+ */
+static void dpu_encoder_phys_wb_setup_fb(struct dpu_encoder_phys *phys_enc,
+		struct drm_framebuffer *fb)
+{
+	struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc);
+	struct dpu_hw_wb *hw_wb;
+	struct dpu_hw_wb_cfg *wb_cfg;
+
+	if (!phys_enc || !phys_enc->dpu_kms || !phys_enc->dpu_kms->catalog) {
+		DPU_ERROR("invalid encoder\n");
+		return;
+	}
+
+	hw_wb = phys_enc->hw_wb;
+	wb_cfg = &wb_enc->wb_cfg;
+
+	wb_cfg->intf_mode = phys_enc->intf_mode;
+	wb_cfg->roi.x1 = 0;
+	wb_cfg->roi.x2 = phys_enc->cached_mode.hdisplay;
+	wb_cfg->roi.y1 = 0;
+	wb_cfg->roi.y2 = phys_enc->cached_mode.vdisplay;
+
+	if (hw_wb->ops.setup_roi)
+		hw_wb->ops.setup_roi(hw_wb, wb_cfg);
+
+	if (hw_wb->ops.setup_outformat)
+		hw_wb->ops.setup_outformat(hw_wb, wb_cfg);
+
+	if (hw_wb->ops.setup_cdp) {
+		const struct dpu_perf_cfg *perf = phys_enc->dpu_kms->catalog->perf;
+
+		hw_wb->ops.setup_cdp(hw_wb, wb_cfg->dest.format,
+				     perf->cdp_cfg[DPU_PERF_CDP_USAGE_NRT].wr_enable);
+	}
+
+	if (hw_wb->ops.setup_outaddress)
+		hw_wb->ops.setup_outaddress(hw_wb, wb_cfg);
+}
+
+/**
+ * dpu_encoder_phys_wb_setup_ctl - setup wb pipeline for ctl path
+ * @phys_enc:Pointer to physical encoder
+ */
+static void dpu_encoder_phys_wb_setup_ctl(struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_wb *hw_wb;
+	struct dpu_hw_ctl *ctl;
+	struct dpu_hw_cdm *hw_cdm;
+
+	if (!phys_enc) {
+		DPU_ERROR("invalid encoder\n");
+		return;
+	}
+
+	hw_wb = phys_enc->hw_wb;
+	ctl = phys_enc->hw_ctl;
+	hw_cdm = phys_enc->hw_cdm;
+
+	if (test_bit(DPU_CTL_ACTIVE_CFG, &ctl->caps->features) &&
+		(phys_enc->hw_ctl &&
+		 phys_enc->hw_ctl->ops.setup_intf_cfg)) {
+		struct dpu_hw_intf_cfg intf_cfg = {0};
+		struct dpu_hw_pingpong *hw_pp = phys_enc->hw_pp;
+		enum dpu_3d_blend_mode mode_3d;
+
+		mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
+
+		intf_cfg.intf = DPU_NONE;
+		intf_cfg.wb = hw_wb->idx;
+
+		if (mode_3d && hw_pp && hw_pp->merge_3d)
+			intf_cfg.merge_3d = hw_pp->merge_3d->idx;
+
+		if (hw_cdm)
+			intf_cfg.cdm = hw_cdm->idx;
+
+		if (phys_enc->hw_pp->merge_3d && phys_enc->hw_pp->merge_3d->ops.setup_3d_mode)
+			phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d,
+					mode_3d);
+
+		/* setup which pp blk will connect to this wb */
+		if (hw_pp && phys_enc->hw_wb->ops.bind_pingpong_blk)
+			phys_enc->hw_wb->ops.bind_pingpong_blk(phys_enc->hw_wb,
+					phys_enc->hw_pp->idx);
+
+		phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg);
+	} else if (phys_enc->hw_ctl && phys_enc->hw_ctl->ops.setup_intf_cfg) {
+		struct dpu_hw_intf_cfg intf_cfg = {0};
+
+		intf_cfg.intf = DPU_NONE;
+		intf_cfg.wb = hw_wb->idx;
+		intf_cfg.mode_3d =
+			dpu_encoder_helper_get_3d_blend_mode(phys_enc);
+		phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg);
+	}
+}
+
+/**
+ * _dpu_encoder_phys_wb_update_flush - flush hardware update
+ * @phys_enc:	Pointer to physical encoder
+ */
+static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_wb *hw_wb;
+	struct dpu_hw_ctl *hw_ctl;
+	struct dpu_hw_pingpong *hw_pp;
+	struct dpu_hw_cdm *hw_cdm;
+	u32 pending_flush = 0;
+
+	if (!phys_enc)
+		return;
+
+	hw_wb = phys_enc->hw_wb;
+	hw_pp = phys_enc->hw_pp;
+	hw_ctl = phys_enc->hw_ctl;
+	hw_cdm = phys_enc->hw_cdm;
+
+	DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0);
+
+	if (!hw_ctl) {
+		DPU_DEBUG("[wb:%d] no ctl assigned\n", hw_wb->idx - WB_0);
+		return;
+	}
+
+	if (hw_ctl->ops.update_pending_flush_wb)
+		hw_ctl->ops.update_pending_flush_wb(hw_ctl, hw_wb->idx);
+
+	if (hw_ctl->ops.update_pending_flush_merge_3d && hw_pp && hw_pp->merge_3d)
+		hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl,
+				hw_pp->merge_3d->idx);
+
+	if (hw_cdm && hw_ctl->ops.update_pending_flush_cdm)
+		hw_ctl->ops.update_pending_flush_cdm(hw_ctl, hw_cdm->idx);
+
+	if (hw_ctl->ops.get_pending_flush)
+		pending_flush = hw_ctl->ops.get_pending_flush(hw_ctl);
+
+	DPU_DEBUG("Pending flush mask for CTL_%d is 0x%x, WB %d\n",
+			hw_ctl->idx - CTL_0, pending_flush,
+			hw_wb->idx - WB_0);
+}
+
+/**
+ * dpu_encoder_phys_wb_setup - setup writeback encoder
+ * @phys_enc:	Pointer to physical encoder
+ */
+static void dpu_encoder_phys_wb_setup(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_wb *hw_wb = phys_enc->hw_wb;
+	struct drm_display_mode mode = phys_enc->cached_mode;
+	struct drm_framebuffer *fb = NULL;
+	struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc);
+	struct drm_writeback_job *wb_job;
+	const struct msm_format *format;
+	const struct dpu_format *dpu_fmt;
+
+	wb_job = wb_enc->wb_job;
+	format = msm_framebuffer_format(wb_enc->wb_job->fb);
+	dpu_fmt = dpu_get_dpu_format_ext(format->pixel_format, wb_job->fb->modifier);
+
+	DPU_DEBUG("[mode_set:%d, \"%s\",%d,%d]\n",
+			hw_wb->idx - WB_0, mode.name,
+			mode.hdisplay, mode.vdisplay);
+
+	dpu_encoder_phys_wb_set_ot_limit(phys_enc);
+
+	dpu_encoder_phys_wb_set_qos_remap(phys_enc);
+
+	dpu_encoder_phys_wb_set_qos(phys_enc);
+
+	dpu_encoder_phys_wb_setup_fb(phys_enc, fb);
+
+	dpu_encoder_helper_phys_setup_cdm(phys_enc, dpu_fmt, CDM_CDWN_OUTPUT_WB);
+
+	dpu_encoder_phys_wb_setup_ctl(phys_enc);
+}
+
+/**
+ * dpu_encoder_phys_wb_done_irq - writeback interrupt handler
+ * @arg:	Pointer to writeback encoder
+ */
+static void dpu_encoder_phys_wb_done_irq(void *arg)
+{
+	struct dpu_encoder_phys *phys_enc = arg;
+	struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc);
+
+	struct dpu_hw_wb *hw_wb = phys_enc->hw_wb;
+	unsigned long lock_flags;
+	u32 event = DPU_ENCODER_FRAME_EVENT_DONE;
+
+	DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0);
+
+	dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, event);
+
+	dpu_encoder_vblank_callback(phys_enc->parent, phys_enc);
+
+	spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
+	atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
+	spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
+
+	if (wb_enc->wb_conn)
+		drm_writeback_signal_completion(wb_enc->wb_conn, 0);
+
+	/* Signal any waiting atomic commit thread */
+	wake_up_all(&phys_enc->pending_kickoff_wq);
+}
+
+/**
+ * dpu_encoder_phys_wb_irq_ctrl - irq control of WB
+ * @phys:	Pointer to physical encoder
+ * @enable:	indicates enable or disable interrupts
+ */
+static void dpu_encoder_phys_wb_irq_ctrl(
+		struct dpu_encoder_phys *phys, bool enable)
+{
+
+	struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys);
+
+	if (enable && atomic_inc_return(&wb_enc->wbirq_refcount) == 1)
+		dpu_core_irq_register_callback(phys->dpu_kms,
+				phys->irq[INTR_IDX_WB_DONE], dpu_encoder_phys_wb_done_irq, phys);
+	else if (!enable &&
+			atomic_dec_return(&wb_enc->wbirq_refcount) == 0)
+		dpu_core_irq_unregister_callback(phys->dpu_kms, phys->irq[INTR_IDX_WB_DONE]);
+}
+
+static void dpu_encoder_phys_wb_atomic_mode_set(
+		struct dpu_encoder_phys *phys_enc,
+		struct drm_crtc_state *crtc_state,
+		struct drm_connector_state *conn_state)
+{
+
+	phys_enc->irq[INTR_IDX_WB_DONE] = phys_enc->hw_wb->caps->intr_wb_done;
+}
+
+static void _dpu_encoder_phys_wb_handle_wbdone_timeout(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc);
+	u32 frame_event = DPU_ENCODER_FRAME_EVENT_ERROR;
+
+	wb_enc->wb_done_timeout_cnt++;
+
+	if (wb_enc->wb_done_timeout_cnt == 1)
+		msm_disp_snapshot_state(phys_enc->parent->dev);
+
+	atomic_add_unless(&phys_enc->pending_kickoff_cnt, -1, 0);
+
+	/* request a ctl reset before the next kickoff */
+	phys_enc->enable_state = DPU_ENC_ERR_NEEDS_HW_RESET;
+
+	if (wb_enc->wb_conn)
+		drm_writeback_signal_completion(wb_enc->wb_conn, 0);
+
+	dpu_encoder_frame_done_callback(phys_enc->parent, phys_enc, frame_event);
+}
+
+/**
+ * dpu_encoder_phys_wb_wait_for_commit_done - wait until request is committed
+ * @phys_enc:	Pointer to physical encoder
+ */
+static int dpu_encoder_phys_wb_wait_for_commit_done(
+		struct dpu_encoder_phys *phys_enc)
+{
+	unsigned long ret;
+	struct dpu_encoder_wait_info wait_info;
+	struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc);
+
+	wait_info.wq = &phys_enc->pending_kickoff_wq;
+	wait_info.atomic_cnt = &phys_enc->pending_kickoff_cnt;
+	wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
+
+	ret = dpu_encoder_helper_wait_for_irq(phys_enc,
+			phys_enc->irq[INTR_IDX_WB_DONE],
+			dpu_encoder_phys_wb_done_irq, &wait_info);
+	if (ret == -ETIMEDOUT)
+		_dpu_encoder_phys_wb_handle_wbdone_timeout(phys_enc);
+	else if (!ret)
+		wb_enc->wb_done_timeout_cnt = 0;
+
+	return ret;
+}
+
+/**
+ * dpu_encoder_phys_wb_prepare_for_kickoff - pre-kickoff processing
+ * @phys_enc:	Pointer to physical encoder
+ * Returns:	Zero on success
+ */
+static void dpu_encoder_phys_wb_prepare_for_kickoff(
+		struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc);
+	struct drm_connector *drm_conn;
+	struct drm_connector_state *state;
+
+	DPU_DEBUG("[wb:%d]\n", phys_enc->hw_wb->idx - WB_0);
+
+	if (!wb_enc->wb_conn || !wb_enc->wb_job) {
+		DPU_ERROR("invalid wb_conn or wb_job\n");
+		return;
+	}
+
+	drm_conn = &wb_enc->wb_conn->base;
+	state = drm_conn->state;
+
+	if (wb_enc->wb_conn && wb_enc->wb_job)
+		drm_writeback_queue_job(wb_enc->wb_conn, state);
+
+	dpu_encoder_phys_wb_setup(phys_enc);
+
+	_dpu_encoder_phys_wb_update_flush(phys_enc);
+}
+
+/**
+ * dpu_encoder_phys_wb_needs_single_flush - trigger flush processing
+ * @phys_enc:	Pointer to physical encoder
+ */
+static bool dpu_encoder_phys_wb_needs_single_flush(struct dpu_encoder_phys *phys_enc)
+{
+	DPU_DEBUG("[wb:%d]\n", phys_enc->hw_wb->idx - WB_0);
+	return false;
+}
+
+/**
+ * dpu_encoder_phys_wb_handle_post_kickoff - post-kickoff processing
+ * @phys_enc:	Pointer to physical encoder
+ */
+static void dpu_encoder_phys_wb_handle_post_kickoff(
+		struct dpu_encoder_phys *phys_enc)
+{
+	DPU_DEBUG("[wb:%d]\n", phys_enc->hw_wb->idx - WB_0);
+
+}
+
+/**
+ * dpu_encoder_phys_wb_enable - enable writeback encoder
+ * @phys_enc:	Pointer to physical encoder
+ */
+static void dpu_encoder_phys_wb_enable(struct dpu_encoder_phys *phys_enc)
+{
+	DPU_DEBUG("[wb:%d]\n", phys_enc->hw_wb->idx - WB_0);
+	phys_enc->enable_state = DPU_ENC_ENABLED;
+}
+/**
+ * dpu_encoder_phys_wb_disable - disable writeback encoder
+ * @phys_enc:	Pointer to physical encoder
+ */
+static void dpu_encoder_phys_wb_disable(struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_hw_wb *hw_wb = phys_enc->hw_wb;
+	struct dpu_hw_ctl *hw_ctl = phys_enc->hw_ctl;
+
+	DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0);
+
+	if (phys_enc->enable_state == DPU_ENC_DISABLED) {
+		DPU_ERROR("encoder is already disabled\n");
+		return;
+	}
+
+	/* reset h/w before final flush */
+	phys_enc->hw_ctl->ops.clear_pending_flush(phys_enc->hw_ctl);
+
+	/*
+	 * New CTL reset sequence from 5.0 MDP onwards.
+	 * If has_3d_merge_reset is not set, legacy reset
+	 * sequence is executed.
+	 *
+	 * Legacy reset sequence has not been implemented yet.
+	 * Any target earlier than SM8150 will need it and when
+	 * WB support is added to those targets will need to add
+	 * the legacy teardown sequence as well.
+	 */
+	if (hw_ctl->caps->features & BIT(DPU_CTL_ACTIVE_CFG))
+		dpu_encoder_helper_phys_cleanup(phys_enc);
+
+	phys_enc->enable_state = DPU_ENC_DISABLED;
+}
+
+static void dpu_encoder_phys_wb_prepare_wb_job(struct dpu_encoder_phys *phys_enc,
+		struct drm_writeback_job *job)
+{
+	const struct msm_format *format;
+	struct msm_gem_address_space *aspace;
+	struct dpu_hw_wb_cfg *wb_cfg;
+	int ret;
+	struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc);
+
+	if (!job->fb)
+		return;
+
+	wb_enc->wb_job = job;
+	wb_enc->wb_conn = job->connector;
+	aspace = phys_enc->dpu_kms->base.aspace;
+
+	wb_cfg = &wb_enc->wb_cfg;
+
+	memset(wb_cfg, 0, sizeof(struct dpu_hw_wb_cfg));
+
+	ret = msm_framebuffer_prepare(job->fb, aspace, false);
+	if (ret) {
+		DPU_ERROR("prep fb failed, %d\n", ret);
+		return;
+	}
+
+	format = msm_framebuffer_format(job->fb);
+
+	wb_cfg->dest.format = dpu_get_dpu_format_ext(
+			format->pixel_format, job->fb->modifier);
+	if (!wb_cfg->dest.format) {
+		/* this error should be detected during atomic_check */
+		DPU_ERROR("failed to get format %x\n", format->pixel_format);
+		return;
+	}
+
+	ret = dpu_format_populate_layout(aspace, job->fb, &wb_cfg->dest);
+	if (ret) {
+		DPU_DEBUG("failed to populate layout %d\n", ret);
+		return;
+	}
+
+	wb_cfg->dest.width = job->fb->width;
+	wb_cfg->dest.height = job->fb->height;
+	wb_cfg->dest.num_planes = wb_cfg->dest.format->num_planes;
+
+	if ((wb_cfg->dest.format->fetch_planes == DPU_PLANE_PLANAR) &&
+			(wb_cfg->dest.format->element[0] == C1_B_Cb))
+		swap(wb_cfg->dest.plane_addr[1], wb_cfg->dest.plane_addr[2]);
+
+	DPU_DEBUG("[fb_offset:%8.8x,%8.8x,%8.8x,%8.8x]\n",
+			wb_cfg->dest.plane_addr[0], wb_cfg->dest.plane_addr[1],
+			wb_cfg->dest.plane_addr[2], wb_cfg->dest.plane_addr[3]);
+
+	DPU_DEBUG("[fb_stride:%8.8x,%8.8x,%8.8x,%8.8x]\n",
+			wb_cfg->dest.plane_pitch[0], wb_cfg->dest.plane_pitch[1],
+			wb_cfg->dest.plane_pitch[2], wb_cfg->dest.plane_pitch[3]);
+}
+
+static void dpu_encoder_phys_wb_cleanup_wb_job(struct dpu_encoder_phys *phys_enc,
+		struct drm_writeback_job *job)
+{
+	struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc);
+	struct msm_gem_address_space *aspace;
+
+	if (!job->fb)
+		return;
+
+	aspace = phys_enc->dpu_kms->base.aspace;
+
+	msm_framebuffer_cleanup(job->fb, aspace, false);
+	wb_enc->wb_job = NULL;
+	wb_enc->wb_conn = NULL;
+}
+
+static bool dpu_encoder_phys_wb_is_valid_for_commit(struct dpu_encoder_phys *phys_enc)
+{
+	struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc);
+
+	if (wb_enc->wb_job)
+		return true;
+	else
+		return false;
+}
+
+/**
+ * dpu_encoder_phys_wb_init_ops - initialize writeback operations
+ * @ops:	Pointer to encoder operation table
+ */
+static void dpu_encoder_phys_wb_init_ops(struct dpu_encoder_phys_ops *ops)
+{
+	ops->is_master = dpu_encoder_phys_wb_is_master;
+	ops->atomic_mode_set = dpu_encoder_phys_wb_atomic_mode_set;
+	ops->enable = dpu_encoder_phys_wb_enable;
+	ops->disable = dpu_encoder_phys_wb_disable;
+	ops->wait_for_commit_done = dpu_encoder_phys_wb_wait_for_commit_done;
+	ops->prepare_for_kickoff = dpu_encoder_phys_wb_prepare_for_kickoff;
+	ops->handle_post_kickoff = dpu_encoder_phys_wb_handle_post_kickoff;
+	ops->needs_single_flush = dpu_encoder_phys_wb_needs_single_flush;
+	ops->trigger_start = dpu_encoder_helper_trigger_start;
+	ops->prepare_wb_job = dpu_encoder_phys_wb_prepare_wb_job;
+	ops->cleanup_wb_job = dpu_encoder_phys_wb_cleanup_wb_job;
+	ops->irq_control = dpu_encoder_phys_wb_irq_ctrl;
+	ops->is_valid_for_commit = dpu_encoder_phys_wb_is_valid_for_commit;
+
+}
+
+/**
+ * dpu_encoder_phys_wb_init - initialize writeback encoder
+ * @dev:  Corresponding device for devres management
+ * @p:	Pointer to init info structure with initialization params
+ */
+struct dpu_encoder_phys *dpu_encoder_phys_wb_init(struct drm_device *dev,
+		struct dpu_enc_phys_init_params *p)
+{
+	struct dpu_encoder_phys *phys_enc = NULL;
+	struct dpu_encoder_phys_wb *wb_enc = NULL;
+
+	DPU_DEBUG("\n");
+
+	if (!p || !p->parent) {
+		DPU_ERROR("invalid params\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	wb_enc = drmm_kzalloc(dev, sizeof(*wb_enc), GFP_KERNEL);
+	if (!wb_enc) {
+		DPU_ERROR("failed to allocate wb phys_enc enc\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	phys_enc = &wb_enc->base;
+
+	dpu_encoder_phys_init(phys_enc, p);
+
+	dpu_encoder_phys_wb_init_ops(&phys_enc->ops);
+	phys_enc->intf_mode = INTF_MODE_WB_LINE;
+
+	atomic_set(&wb_enc->wbirq_refcount, 0);
+
+	wb_enc->wb_done_timeout_cnt = 0;
+
+	DPU_DEBUG("Created dpu_encoder_phys for wb %d\n", phys_enc->hw_wb->idx);
+
+	return phys_enc;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_formats.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_formats.c
@@ -0,0 +1,1068 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+
+#include <uapi/drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
+
+#include "msm_media_info.h"
+#include "dpu_kms.h"
+#include "dpu_formats.h"
+
+#define DPU_UBWC_META_MACRO_W_H		16
+#define DPU_UBWC_META_BLOCK_SIZE	256
+#define DPU_UBWC_PLANE_SIZE_ALIGNMENT	4096
+
+#define DPU_TILE_HEIGHT_DEFAULT	1
+#define DPU_TILE_HEIGHT_TILED	4
+#define DPU_TILE_HEIGHT_UBWC	4
+#define DPU_TILE_HEIGHT_NV12	8
+
+#define DPU_MAX_IMG_WIDTH		0x3FFF
+#define DPU_MAX_IMG_HEIGHT		0x3FFF
+
+/*
+ * DPU supported format packing, bpp, and other format
+ * information.
+ * DPU currently only supports interleaved RGB formats
+ * UBWC support for a pixel format is indicated by the flag,
+ * there is additional meta data plane for such formats
+ */
+
+#define INTERLEAVED_RGB_FMT(fmt, a, r, g, b, e0, e1, e2, e3, uc, alpha,   \
+bp, flg, fm, np)                                                          \
+{                                                                         \
+	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
+	.fetch_planes = DPU_PLANE_INTERLEAVED,                            \
+	.alpha_enable = alpha,                                            \
+	.element = { (e0), (e1), (e2), (e3) },                            \
+	.bits = { g, b, r, a },                                           \
+	.chroma_sample = DPU_CHROMA_RGB,                                  \
+	.unpack_align_msb = 0,                                            \
+	.unpack_tight = 1,                                                \
+	.unpack_count = uc,                                               \
+	.bpp = bp,                                                        \
+	.fetch_mode = fm,                                                 \
+	.flag = {(flg)},                                                  \
+	.num_planes = np,                                                 \
+	.tile_height = DPU_TILE_HEIGHT_DEFAULT                            \
+}
+
+#define INTERLEAVED_RGB_FMT_TILED(fmt, a, r, g, b, e0, e1, e2, e3, uc,    \
+alpha, bp, flg, fm, np, th)                                               \
+{                                                                         \
+	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
+	.fetch_planes = DPU_PLANE_INTERLEAVED,                            \
+	.alpha_enable = alpha,                                            \
+	.element = { (e0), (e1), (e2), (e3) },                            \
+	.bits = { g, b, r, a },                                           \
+	.chroma_sample = DPU_CHROMA_RGB,                                  \
+	.unpack_align_msb = 0,                                            \
+	.unpack_tight = 1,                                                \
+	.unpack_count = uc,                                               \
+	.bpp = bp,                                                        \
+	.fetch_mode = fm,                                                 \
+	.flag = {(flg)},                                                  \
+	.num_planes = np,                                                 \
+	.tile_height = th                                                 \
+}
+
+
+#define INTERLEAVED_YUV_FMT(fmt, a, r, g, b, e0, e1, e2, e3,              \
+alpha, chroma, count, bp, flg, fm, np)                                    \
+{                                                                         \
+	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
+	.fetch_planes = DPU_PLANE_INTERLEAVED,                            \
+	.alpha_enable = alpha,                                            \
+	.element = { (e0), (e1), (e2), (e3)},                             \
+	.bits = { g, b, r, a },                                           \
+	.chroma_sample = chroma,                                          \
+	.unpack_align_msb = 0,                                            \
+	.unpack_tight = 1,                                                \
+	.unpack_count = count,                                            \
+	.bpp = bp,                                                        \
+	.fetch_mode = fm,                                                 \
+	.flag = {(flg)},                                                  \
+	.num_planes = np,                                                 \
+	.tile_height = DPU_TILE_HEIGHT_DEFAULT                            \
+}
+
+#define PSEUDO_YUV_FMT(fmt, a, r, g, b, e0, e1, chroma, flg, fm, np)      \
+{                                                                         \
+	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
+	.fetch_planes = DPU_PLANE_PSEUDO_PLANAR,                          \
+	.alpha_enable = false,                                            \
+	.element = { (e0), (e1), 0, 0 },                                  \
+	.bits = { g, b, r, a },                                           \
+	.chroma_sample = chroma,                                          \
+	.unpack_align_msb = 0,                                            \
+	.unpack_tight = 1,                                                \
+	.unpack_count = 2,                                                \
+	.bpp = 2,                                                         \
+	.fetch_mode = fm,                                                 \
+	.flag = {(flg)},                                                  \
+	.num_planes = np,                                                 \
+	.tile_height = DPU_TILE_HEIGHT_DEFAULT                            \
+}
+
+#define PSEUDO_YUV_FMT_TILED(fmt, a, r, g, b, e0, e1, chroma,             \
+flg, fm, np, th)                                                          \
+{                                                                         \
+	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
+	.fetch_planes = DPU_PLANE_PSEUDO_PLANAR,                          \
+	.alpha_enable = false,                                            \
+	.element = { (e0), (e1), 0, 0 },                                  \
+	.bits = { g, b, r, a },                                           \
+	.chroma_sample = chroma,                                          \
+	.unpack_align_msb = 0,                                            \
+	.unpack_tight = 1,                                                \
+	.unpack_count = 2,                                                \
+	.bpp = 2,                                                         \
+	.fetch_mode = fm,                                                 \
+	.flag = {(flg)},                                                  \
+	.num_planes = np,                                                 \
+	.tile_height = th                                                 \
+}
+
+#define PSEUDO_YUV_FMT_LOOSE(fmt, a, r, g, b, e0, e1, chroma, flg, fm, np)\
+{                                                                         \
+	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
+	.fetch_planes = DPU_PLANE_PSEUDO_PLANAR,                          \
+	.alpha_enable = false,                                            \
+	.element = { (e0), (e1), 0, 0 },                                  \
+	.bits = { g, b, r, a },                                           \
+	.chroma_sample = chroma,                                          \
+	.unpack_align_msb = 1,                                            \
+	.unpack_tight = 0,                                                \
+	.unpack_count = 2,                                                \
+	.bpp = 2,                                                         \
+	.fetch_mode = fm,                                                 \
+	.flag = {(flg)},                                                  \
+	.num_planes = np,                                                 \
+	.tile_height = DPU_TILE_HEIGHT_DEFAULT                            \
+}
+
+#define PSEUDO_YUV_FMT_LOOSE_TILED(fmt, a, r, g, b, e0, e1, chroma,       \
+flg, fm, np, th)                                                          \
+{                                                                         \
+	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
+	.fetch_planes = DPU_PLANE_PSEUDO_PLANAR,                          \
+	.alpha_enable = false,                                            \
+	.element = { (e0), (e1), 0, 0 },                                  \
+	.bits = { g, b, r, a },                                           \
+	.chroma_sample = chroma,                                          \
+	.unpack_align_msb = 1,                                            \
+	.unpack_tight = 0,                                                \
+	.unpack_count = 2,                                                \
+	.bpp = 2,                                                         \
+	.fetch_mode = fm,                                                 \
+	.flag = {(flg)},                                                  \
+	.num_planes = np,                                                 \
+	.tile_height = th                                                 \
+}
+
+
+#define PLANAR_YUV_FMT(fmt, a, r, g, b, e0, e1, e2, alpha, chroma, bp,    \
+flg, fm, np)                                                      \
+{                                                                         \
+	.base.pixel_format = DRM_FORMAT_ ## fmt,                          \
+	.fetch_planes = DPU_PLANE_PLANAR,                                 \
+	.alpha_enable = alpha,                                            \
+	.element = { (e0), (e1), (e2), 0 },                               \
+	.bits = { g, b, r, a },                                           \
+	.chroma_sample = chroma,                                          \
+	.unpack_align_msb = 0,                                            \
+	.unpack_tight = 1,                                                \
+	.unpack_count = 1,                                                \
+	.bpp = bp,                                                        \
+	.fetch_mode = fm,                                                 \
+	.flag = {(flg)},                                                  \
+	.num_planes = np,                                                 \
+	.tile_height = DPU_TILE_HEIGHT_DEFAULT                            \
+}
+
+/*
+ * struct dpu_media_color_map - maps drm format to media format
+ * @format: DRM base pixel format
+ * @color: Media API color related to DRM format
+ */
+struct dpu_media_color_map {
+	uint32_t format;
+	uint32_t color;
+};
+
+static const struct dpu_format dpu_format_map[] = {
+	INTERLEAVED_RGB_FMT(ARGB8888,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+		true, 4, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(ABGR8888,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		true, 4, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(XBGR8888,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		false, 4, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(RGBA8888,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+		true, 4, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(BGRA8888,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+		true, 4, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(BGRX8888,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+		false, 4, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(XRGB8888,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+		false, 4, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(RGBX8888,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+		false, 4, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(RGB888,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3,
+		false, 3, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(BGR888,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
+		false, 3, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(RGB565,
+		0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, 0, 3,
+		false, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(BGR565,
+		0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
+		false, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(ARGB1555,
+		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+		true, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(ABGR1555,
+		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		true, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(RGBA5551,
+		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
+		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+		true, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(BGRA5551,
+		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
+		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+		true, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(XRGB1555,
+		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+		false, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(XBGR1555,
+		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		false, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(RGBX5551,
+		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
+		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+		false, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(BGRX5551,
+		COLOR_ALPHA_1BIT, COLOR_5BIT, COLOR_5BIT, COLOR_5BIT,
+		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+		false, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(ARGB4444,
+		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+		true, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(ABGR4444,
+		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		true, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(RGBA4444,
+		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
+		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+		true, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(BGRA4444,
+		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
+		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+		true, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(XRGB4444,
+		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+		false, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(XBGR4444,
+		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		false, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(RGBX4444,
+		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
+		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+		false, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(BGRX4444,
+		COLOR_ALPHA_4BIT, COLOR_4BIT, COLOR_4BIT, COLOR_4BIT,
+		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+		false, 2, 0,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(BGRA1010102,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+		true, 4, DPU_FORMAT_FLAG_DX,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(RGBA1010102,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+		true, 4, DPU_FORMAT_FLAG_DX,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(ABGR2101010,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		true, 4, DPU_FORMAT_FLAG_DX,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(ARGB2101010,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+		true, 4, DPU_FORMAT_FLAG_DX,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(XRGB2101010,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, C3_ALPHA, 4,
+		false, 4, DPU_FORMAT_FLAG_DX,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(BGRX1010102,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C3_ALPHA, C2_R_Cr, C0_G_Y, C1_B_Cb, 4,
+		false, 4, DPU_FORMAT_FLAG_DX,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(XBGR2101010,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		false, 4, DPU_FORMAT_FLAG_DX,
+		DPU_FETCH_LINEAR, 1),
+
+	INTERLEAVED_RGB_FMT(RGBX1010102,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C3_ALPHA, C1_B_Cb, C0_G_Y, C2_R_Cr, 4,
+		false, 4, DPU_FORMAT_FLAG_DX,
+		DPU_FETCH_LINEAR, 1),
+
+	PSEUDO_YUV_FMT(NV12,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C1_B_Cb, C2_R_Cr,
+		DPU_CHROMA_420, DPU_FORMAT_FLAG_YUV,
+		DPU_FETCH_LINEAR, 2),
+
+	PSEUDO_YUV_FMT(NV21,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C1_B_Cb,
+		DPU_CHROMA_420, DPU_FORMAT_FLAG_YUV,
+		DPU_FETCH_LINEAR, 2),
+
+	PSEUDO_YUV_FMT(NV16,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C1_B_Cb, C2_R_Cr,
+		DPU_CHROMA_H2V1, DPU_FORMAT_FLAG_YUV,
+		DPU_FETCH_LINEAR, 2),
+
+	PSEUDO_YUV_FMT(NV61,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C1_B_Cb,
+		DPU_CHROMA_H2V1, DPU_FORMAT_FLAG_YUV,
+		DPU_FETCH_LINEAR, 2),
+
+	PSEUDO_YUV_FMT_LOOSE(P010,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C1_B_Cb, C2_R_Cr,
+		DPU_CHROMA_420, DPU_FORMAT_FLAG_DX | DPU_FORMAT_FLAG_YUV,
+		DPU_FETCH_LINEAR, 2),
+
+	INTERLEAVED_YUV_FMT(VYUY,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C0_G_Y,
+		false, DPU_CHROMA_H2V1, 4, 2, DPU_FORMAT_FLAG_YUV,
+		DPU_FETCH_LINEAR, 2),
+
+	INTERLEAVED_YUV_FMT(UYVY,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C1_B_Cb, C0_G_Y, C2_R_Cr, C0_G_Y,
+		false, DPU_CHROMA_H2V1, 4, 2, DPU_FORMAT_FLAG_YUV,
+		DPU_FETCH_LINEAR, 2),
+
+	INTERLEAVED_YUV_FMT(YUYV,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C0_G_Y, C1_B_Cb, C0_G_Y, C2_R_Cr,
+		false, DPU_CHROMA_H2V1, 4, 2, DPU_FORMAT_FLAG_YUV,
+		DPU_FETCH_LINEAR, 2),
+
+	INTERLEAVED_YUV_FMT(YVYU,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C0_G_Y, C2_R_Cr, C0_G_Y, C1_B_Cb,
+		false, DPU_CHROMA_H2V1, 4, 2, DPU_FORMAT_FLAG_YUV,
+		DPU_FETCH_LINEAR, 2),
+
+	PLANAR_YUV_FMT(YUV420,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C1_B_Cb, C0_G_Y,
+		false, DPU_CHROMA_420, 1, DPU_FORMAT_FLAG_YUV,
+		DPU_FETCH_LINEAR, 3),
+
+	PLANAR_YUV_FMT(YVU420,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C1_B_Cb, C2_R_Cr, C0_G_Y,
+		false, DPU_CHROMA_420, 1, DPU_FORMAT_FLAG_YUV,
+		DPU_FETCH_LINEAR, 3),
+};
+
+/*
+ * UBWC formats table:
+ * This table holds the UBWC formats supported.
+ * If a compression ratio needs to be used for this or any other format,
+ * the data will be passed by user-space.
+ */
+static const struct dpu_format dpu_format_map_ubwc[] = {
+	INTERLEAVED_RGB_FMT_TILED(BGR565,
+		0, COLOR_5BIT, COLOR_6BIT, COLOR_5BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, 0, 3,
+		false, 2, DPU_FORMAT_FLAG_COMPRESSED,
+		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
+
+	INTERLEAVED_RGB_FMT_TILED(ABGR8888,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		true, 4, DPU_FORMAT_FLAG_COMPRESSED,
+		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
+
+	/* ARGB8888 and ABGR8888 purposely have the same color
+	 * ordering.  The hardware only supports ABGR8888 UBWC
+	 * natively.
+	 */
+	INTERLEAVED_RGB_FMT_TILED(ARGB8888,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		true, 4, DPU_FORMAT_FLAG_COMPRESSED,
+		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
+
+	INTERLEAVED_RGB_FMT_TILED(XBGR8888,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		false, 4, DPU_FORMAT_FLAG_COMPRESSED,
+		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
+
+	INTERLEAVED_RGB_FMT_TILED(XRGB8888,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		false, 4, DPU_FORMAT_FLAG_COMPRESSED,
+		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
+
+	INTERLEAVED_RGB_FMT_TILED(ABGR2101010,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		true, 4, DPU_FORMAT_FLAG_DX | DPU_FORMAT_FLAG_COMPRESSED,
+		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
+
+	INTERLEAVED_RGB_FMT_TILED(XBGR2101010,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		true, 4, DPU_FORMAT_FLAG_DX | DPU_FORMAT_FLAG_COMPRESSED,
+		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
+
+	INTERLEAVED_RGB_FMT_TILED(XRGB2101010,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		true, 4, DPU_FORMAT_FLAG_DX | DPU_FORMAT_FLAG_COMPRESSED,
+		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
+
+	/* XRGB2101010 and ARGB2101010 purposely have the same color
+	* ordering.  The hardware only supports ARGB2101010 UBWC
+	* natively.
+	*/
+	INTERLEAVED_RGB_FMT_TILED(ARGB2101010,
+		COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
+		true, 4, DPU_FORMAT_FLAG_DX | DPU_FORMAT_FLAG_COMPRESSED,
+		DPU_FETCH_UBWC, 2, DPU_TILE_HEIGHT_UBWC),
+
+	PSEUDO_YUV_FMT_TILED(NV12,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C1_B_Cb, C2_R_Cr,
+		DPU_CHROMA_420, DPU_FORMAT_FLAG_YUV |
+				DPU_FORMAT_FLAG_COMPRESSED,
+		DPU_FETCH_UBWC, 4, DPU_TILE_HEIGHT_NV12),
+
+	PSEUDO_YUV_FMT_TILED(P010,
+		0, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
+		C1_B_Cb, C2_R_Cr,
+		DPU_CHROMA_420, DPU_FORMAT_FLAG_DX |
+				DPU_FORMAT_FLAG_YUV |
+				DPU_FORMAT_FLAG_COMPRESSED,
+		DPU_FETCH_UBWC, 4, DPU_TILE_HEIGHT_UBWC),
+};
+
+/* _dpu_get_v_h_subsample_rate - Get subsample rates for all formats we support
+ *   Note: Not using the drm_format_*_subsampling since we have formats
+ */
+static void _dpu_get_v_h_subsample_rate(
+	enum dpu_chroma_samp_type chroma_sample,
+	uint32_t *v_sample,
+	uint32_t *h_sample)
+{
+	if (!v_sample || !h_sample)
+		return;
+
+	switch (chroma_sample) {
+	case DPU_CHROMA_H2V1:
+		*v_sample = 1;
+		*h_sample = 2;
+		break;
+	case DPU_CHROMA_H1V2:
+		*v_sample = 2;
+		*h_sample = 1;
+		break;
+	case DPU_CHROMA_420:
+		*v_sample = 2;
+		*h_sample = 2;
+		break;
+	default:
+		*v_sample = 1;
+		*h_sample = 1;
+		break;
+	}
+}
+
+static int _dpu_format_get_media_color_ubwc(const struct dpu_format *fmt)
+{
+	static const struct dpu_media_color_map dpu_media_ubwc_map[] = {
+		{DRM_FORMAT_ABGR8888, COLOR_FMT_RGBA8888_UBWC},
+		{DRM_FORMAT_ARGB8888, COLOR_FMT_RGBA8888_UBWC},
+		{DRM_FORMAT_XBGR8888, COLOR_FMT_RGBA8888_UBWC},
+		{DRM_FORMAT_XRGB8888, COLOR_FMT_RGBA8888_UBWC},
+		{DRM_FORMAT_ABGR2101010, COLOR_FMT_RGBA1010102_UBWC},
+		{DRM_FORMAT_ARGB2101010, COLOR_FMT_RGBA1010102_UBWC},
+		{DRM_FORMAT_XRGB2101010, COLOR_FMT_RGBA1010102_UBWC},
+		{DRM_FORMAT_XBGR2101010, COLOR_FMT_RGBA1010102_UBWC},
+		{DRM_FORMAT_BGR565, COLOR_FMT_RGB565_UBWC},
+	};
+	int color_fmt = -1;
+	int i;
+
+	if (fmt->base.pixel_format == DRM_FORMAT_NV12 ||
+	    fmt->base.pixel_format == DRM_FORMAT_P010) {
+		if (DPU_FORMAT_IS_DX(fmt)) {
+			if (fmt->unpack_tight)
+				color_fmt = COLOR_FMT_NV12_BPP10_UBWC;
+			else
+				color_fmt = COLOR_FMT_P010_UBWC;
+		} else
+			color_fmt = COLOR_FMT_NV12_UBWC;
+		return color_fmt;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(dpu_media_ubwc_map); ++i)
+		if (fmt->base.pixel_format == dpu_media_ubwc_map[i].format) {
+			color_fmt = dpu_media_ubwc_map[i].color;
+			break;
+		}
+	return color_fmt;
+}
+
+static int _dpu_format_get_plane_sizes_ubwc(
+		const struct dpu_format *fmt,
+		const uint32_t width,
+		const uint32_t height,
+		struct dpu_hw_fmt_layout *layout)
+{
+	int i;
+	int color;
+	bool meta = DPU_FORMAT_IS_UBWC(fmt);
+
+	memset(layout, 0, sizeof(struct dpu_hw_fmt_layout));
+	layout->format = fmt;
+	layout->width = width;
+	layout->height = height;
+	layout->num_planes = fmt->num_planes;
+
+	color = _dpu_format_get_media_color_ubwc(fmt);
+	if (color < 0) {
+		DRM_ERROR("UBWC format not supported for fmt: %4.4s\n",
+			(char *)&fmt->base.pixel_format);
+		return -EINVAL;
+	}
+
+	if (DPU_FORMAT_IS_YUV(layout->format)) {
+		uint32_t y_sclines, uv_sclines;
+		uint32_t y_meta_scanlines = 0;
+		uint32_t uv_meta_scanlines = 0;
+
+		layout->num_planes = 2;
+		layout->plane_pitch[0] = VENUS_Y_STRIDE(color, width);
+		y_sclines = VENUS_Y_SCANLINES(color, height);
+		layout->plane_size[0] = MSM_MEDIA_ALIGN(layout->plane_pitch[0] *
+			y_sclines, DPU_UBWC_PLANE_SIZE_ALIGNMENT);
+
+		layout->plane_pitch[1] = VENUS_UV_STRIDE(color, width);
+		uv_sclines = VENUS_UV_SCANLINES(color, height);
+		layout->plane_size[1] = MSM_MEDIA_ALIGN(layout->plane_pitch[1] *
+			uv_sclines, DPU_UBWC_PLANE_SIZE_ALIGNMENT);
+
+		if (!meta)
+			goto done;
+
+		layout->num_planes += 2;
+		layout->plane_pitch[2] = VENUS_Y_META_STRIDE(color, width);
+		y_meta_scanlines = VENUS_Y_META_SCANLINES(color, height);
+		layout->plane_size[2] = MSM_MEDIA_ALIGN(layout->plane_pitch[2] *
+			y_meta_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT);
+
+		layout->plane_pitch[3] = VENUS_UV_META_STRIDE(color, width);
+		uv_meta_scanlines = VENUS_UV_META_SCANLINES(color, height);
+		layout->plane_size[3] = MSM_MEDIA_ALIGN(layout->plane_pitch[3] *
+			uv_meta_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT);
+
+	} else {
+		uint32_t rgb_scanlines, rgb_meta_scanlines;
+
+		layout->num_planes = 1;
+
+		layout->plane_pitch[0] = VENUS_RGB_STRIDE(color, width);
+		rgb_scanlines = VENUS_RGB_SCANLINES(color, height);
+		layout->plane_size[0] = MSM_MEDIA_ALIGN(layout->plane_pitch[0] *
+			rgb_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT);
+
+		if (!meta)
+			goto done;
+		layout->num_planes += 2;
+		layout->plane_pitch[2] = VENUS_RGB_META_STRIDE(color, width);
+		rgb_meta_scanlines = VENUS_RGB_META_SCANLINES(color, height);
+		layout->plane_size[2] = MSM_MEDIA_ALIGN(layout->plane_pitch[2] *
+			rgb_meta_scanlines, DPU_UBWC_PLANE_SIZE_ALIGNMENT);
+	}
+
+done:
+	for (i = 0; i < DPU_MAX_PLANES; i++)
+		layout->total_size += layout->plane_size[i];
+
+	return 0;
+}
+
+static int _dpu_format_get_plane_sizes_linear(
+		const struct dpu_format *fmt,
+		const uint32_t width,
+		const uint32_t height,
+		struct dpu_hw_fmt_layout *layout,
+		const uint32_t *pitches)
+{
+	int i;
+
+	memset(layout, 0, sizeof(struct dpu_hw_fmt_layout));
+	layout->format = fmt;
+	layout->width = width;
+	layout->height = height;
+	layout->num_planes = fmt->num_planes;
+
+	/* Due to memset above, only need to set planes of interest */
+	if (fmt->fetch_planes == DPU_PLANE_INTERLEAVED) {
+		layout->num_planes = 1;
+		layout->plane_size[0] = width * height * layout->format->bpp;
+		layout->plane_pitch[0] = width * layout->format->bpp;
+	} else {
+		uint32_t v_subsample, h_subsample;
+		uint32_t chroma_samp;
+		uint32_t bpp = 1;
+
+		chroma_samp = fmt->chroma_sample;
+		_dpu_get_v_h_subsample_rate(chroma_samp, &v_subsample,
+				&h_subsample);
+
+		if (width % h_subsample || height % v_subsample) {
+			DRM_ERROR("mismatch in subsample vs dimensions\n");
+			return -EINVAL;
+		}
+
+		if ((fmt->base.pixel_format == DRM_FORMAT_NV12) &&
+			(DPU_FORMAT_IS_DX(fmt)))
+			bpp = 2;
+		layout->plane_pitch[0] = width * bpp;
+		layout->plane_pitch[1] = layout->plane_pitch[0] / h_subsample;
+		layout->plane_size[0] = layout->plane_pitch[0] * height;
+		layout->plane_size[1] = layout->plane_pitch[1] *
+				(height / v_subsample);
+
+		if (fmt->fetch_planes == DPU_PLANE_PSEUDO_PLANAR) {
+			layout->num_planes = 2;
+			layout->plane_size[1] *= 2;
+			layout->plane_pitch[1] *= 2;
+		} else {
+			/* planar */
+			layout->num_planes = 3;
+			layout->plane_size[2] = layout->plane_size[1];
+			layout->plane_pitch[2] = layout->plane_pitch[1];
+		}
+	}
+
+	/*
+	 * linear format: allow user allocated pitches if they are greater than
+	 * the requirement.
+	 * ubwc format: pitch values are computed uniformly across
+	 * all the components based on ubwc specifications.
+	 */
+	for (i = 0; i < layout->num_planes && i < DPU_MAX_PLANES; ++i) {
+		if (pitches && layout->plane_pitch[i] < pitches[i])
+			layout->plane_pitch[i] = pitches[i];
+	}
+
+	for (i = 0; i < DPU_MAX_PLANES; i++)
+		layout->total_size += layout->plane_size[i];
+
+	return 0;
+}
+
+static int dpu_format_get_plane_sizes(
+		const struct dpu_format *fmt,
+		const uint32_t w,
+		const uint32_t h,
+		struct dpu_hw_fmt_layout *layout,
+		const uint32_t *pitches)
+{
+	if (!layout || !fmt) {
+		DRM_ERROR("invalid pointer\n");
+		return -EINVAL;
+	}
+
+	if ((w > DPU_MAX_IMG_WIDTH) || (h > DPU_MAX_IMG_HEIGHT)) {
+		DRM_ERROR("image dimensions outside max range\n");
+		return -ERANGE;
+	}
+
+	if (DPU_FORMAT_IS_UBWC(fmt) || DPU_FORMAT_IS_TILE(fmt))
+		return _dpu_format_get_plane_sizes_ubwc(fmt, w, h, layout);
+
+	return _dpu_format_get_plane_sizes_linear(fmt, w, h, layout, pitches);
+}
+
+static int _dpu_format_populate_addrs_ubwc(
+		struct msm_gem_address_space *aspace,
+		struct drm_framebuffer *fb,
+		struct dpu_hw_fmt_layout *layout)
+{
+	uint32_t base_addr = 0;
+	bool meta;
+
+	if (!fb || !layout) {
+		DRM_ERROR("invalid pointers\n");
+		return -EINVAL;
+	}
+
+	if (aspace)
+		base_addr = msm_framebuffer_iova(fb, aspace, 0);
+	if (!base_addr) {
+		DRM_ERROR("failed to retrieve base addr\n");
+		return -EFAULT;
+	}
+
+	meta = DPU_FORMAT_IS_UBWC(layout->format);
+
+	/* Per-format logic for verifying active planes */
+	if (DPU_FORMAT_IS_YUV(layout->format)) {
+		/************************************************/
+		/*      UBWC            **                      */
+		/*      buffer          **      DPU PLANE       */
+		/*      format          **                      */
+		/************************************************/
+		/* -------------------  ** -------------------- */
+		/* |      Y meta     |  ** |    Y bitstream   | */
+		/* |       data      |  ** |       plane      | */
+		/* -------------------  ** -------------------- */
+		/* |    Y bitstream  |  ** |  CbCr bitstream  | */
+		/* |       data      |  ** |       plane      | */
+		/* -------------------  ** -------------------- */
+		/* |   Cbcr metadata |  ** |       Y meta     | */
+		/* |       data      |  ** |       plane      | */
+		/* -------------------  ** -------------------- */
+		/* |  CbCr bitstream |  ** |     CbCr meta    | */
+		/* |       data      |  ** |       plane      | */
+		/* -------------------  ** -------------------- */
+		/************************************************/
+
+		/* configure Y bitstream plane */
+		layout->plane_addr[0] = base_addr + layout->plane_size[2];
+
+		/* configure CbCr bitstream plane */
+		layout->plane_addr[1] = base_addr + layout->plane_size[0]
+			+ layout->plane_size[2] + layout->plane_size[3];
+
+		if (!meta)
+			return 0;
+
+		/* configure Y metadata plane */
+		layout->plane_addr[2] = base_addr;
+
+		/* configure CbCr metadata plane */
+		layout->plane_addr[3] = base_addr + layout->plane_size[0]
+			+ layout->plane_size[2];
+
+	} else {
+		/************************************************/
+		/*      UBWC            **                      */
+		/*      buffer          **      DPU PLANE       */
+		/*      format          **                      */
+		/************************************************/
+		/* -------------------  ** -------------------- */
+		/* |      RGB meta   |  ** |   RGB bitstream  | */
+		/* |       data      |  ** |       plane      | */
+		/* -------------------  ** -------------------- */
+		/* |  RGB bitstream  |  ** |       NONE       | */
+		/* |       data      |  ** |                  | */
+		/* -------------------  ** -------------------- */
+		/*                      ** |     RGB meta     | */
+		/*                      ** |       plane      | */
+		/*                      ** -------------------- */
+		/************************************************/
+
+		layout->plane_addr[0] = base_addr + layout->plane_size[2];
+		layout->plane_addr[1] = 0;
+
+		if (!meta)
+			return 0;
+
+		layout->plane_addr[2] = base_addr;
+		layout->plane_addr[3] = 0;
+	}
+	return 0;
+}
+
+static int _dpu_format_populate_addrs_linear(
+		struct msm_gem_address_space *aspace,
+		struct drm_framebuffer *fb,
+		struct dpu_hw_fmt_layout *layout)
+{
+	unsigned int i;
+
+	/* Can now check the pitches given vs pitches expected */
+	for (i = 0; i < layout->num_planes; ++i) {
+		if (layout->plane_pitch[i] > fb->pitches[i]) {
+			DRM_ERROR("plane %u expected pitch %u, fb %u\n",
+				i, layout->plane_pitch[i], fb->pitches[i]);
+			return -EINVAL;
+		}
+	}
+
+	/* Populate addresses for simple formats here */
+	for (i = 0; i < layout->num_planes; ++i) {
+		if (aspace)
+			layout->plane_addr[i] =
+				msm_framebuffer_iova(fb, aspace, i);
+		if (!layout->plane_addr[i]) {
+			DRM_ERROR("failed to retrieve base addr\n");
+			return -EFAULT;
+		}
+	}
+
+	return 0;
+}
+
+int dpu_format_populate_layout(
+		struct msm_gem_address_space *aspace,
+		struct drm_framebuffer *fb,
+		struct dpu_hw_fmt_layout *layout)
+{
+	int ret;
+
+	if (!fb || !layout) {
+		DRM_ERROR("invalid arguments\n");
+		return -EINVAL;
+	}
+
+	if ((fb->width > DPU_MAX_IMG_WIDTH) ||
+			(fb->height > DPU_MAX_IMG_HEIGHT)) {
+		DRM_ERROR("image dimensions outside max range\n");
+		return -ERANGE;
+	}
+
+	layout->format = to_dpu_format(msm_framebuffer_format(fb));
+
+	/* Populate the plane sizes etc via get_format */
+	ret = dpu_format_get_plane_sizes(layout->format, fb->width, fb->height,
+			layout, fb->pitches);
+	if (ret)
+		return ret;
+
+	/* Populate the addresses given the fb */
+	if (DPU_FORMAT_IS_UBWC(layout->format) ||
+			DPU_FORMAT_IS_TILE(layout->format))
+		ret = _dpu_format_populate_addrs_ubwc(aspace, fb, layout);
+	else
+		ret = _dpu_format_populate_addrs_linear(aspace, fb, layout);
+
+	return ret;
+}
+
+int dpu_format_check_modified_format(
+		const struct msm_kms *kms,
+		const struct msm_format *msm_fmt,
+		const struct drm_mode_fb_cmd2 *cmd,
+		struct drm_gem_object **bos)
+{
+	const struct drm_format_info *info;
+	const struct dpu_format *fmt;
+	struct dpu_hw_fmt_layout layout;
+	uint32_t bos_total_size = 0;
+	int ret, i;
+
+	if (!msm_fmt || !cmd || !bos) {
+		DRM_ERROR("invalid arguments\n");
+		return -EINVAL;
+	}
+
+	fmt = to_dpu_format(msm_fmt);
+	info = drm_format_info(fmt->base.pixel_format);
+	if (!info)
+		return -EINVAL;
+
+	ret = dpu_format_get_plane_sizes(fmt, cmd->width, cmd->height,
+			&layout, cmd->pitches);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < info->num_planes; i++) {
+		if (!bos[i]) {
+			DRM_ERROR("invalid handle for plane %d\n", i);
+			return -EINVAL;
+		}
+		if ((i == 0) || (bos[i] != bos[0]))
+			bos_total_size += bos[i]->size;
+	}
+
+	if (bos_total_size < layout.total_size) {
+		DRM_ERROR("buffers total size too small %u expected %u\n",
+				bos_total_size, layout.total_size);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+const struct dpu_format *dpu_get_dpu_format_ext(
+		const uint32_t format,
+		const uint64_t modifier)
+{
+	uint32_t i = 0;
+	const struct dpu_format *fmt = NULL;
+	const struct dpu_format *map = NULL;
+	ssize_t map_size = 0;
+
+	/*
+	 * Currently only support exactly zero or one modifier.
+	 * All planes use the same modifier.
+	 */
+	DRM_DEBUG_ATOMIC("plane format modifier 0x%llX\n", modifier);
+
+	switch (modifier) {
+	case 0:
+		map = dpu_format_map;
+		map_size = ARRAY_SIZE(dpu_format_map);
+		break;
+	case DRM_FORMAT_MOD_QCOM_COMPRESSED:
+		map = dpu_format_map_ubwc;
+		map_size = ARRAY_SIZE(dpu_format_map_ubwc);
+		DRM_DEBUG_ATOMIC("found fmt: %4.4s  DRM_FORMAT_MOD_QCOM_COMPRESSED\n",
+				(char *)&format);
+		break;
+	default:
+		DPU_ERROR("unsupported format modifier %llX\n", modifier);
+		return NULL;
+	}
+
+	for (i = 0; i < map_size; i++) {
+		if (format == map[i].base.pixel_format) {
+			fmt = &map[i];
+			break;
+		}
+	}
+
+	if (fmt == NULL)
+		DPU_ERROR("unsupported fmt: %4.4s modifier 0x%llX\n",
+			(char *)&format, modifier);
+	else
+		DRM_DEBUG_ATOMIC("fmt %4.4s mod 0x%llX ubwc %d yuv %d\n",
+				(char *)&format, modifier,
+				DPU_FORMAT_IS_UBWC(fmt),
+				DPU_FORMAT_IS_YUV(fmt));
+
+	return fmt;
+}
+
+const struct msm_format *dpu_get_msm_format(
+		struct msm_kms *kms,
+		const uint32_t format,
+		const uint64_t modifiers)
+{
+	const struct dpu_format *fmt = dpu_get_dpu_format_ext(format,
+			modifiers);
+	if (fmt)
+		return &fmt->base;
+	return NULL;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_formats.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_formats.h
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_FORMATS_H
+#define _DPU_FORMATS_H
+
+#include <drm/drm_fourcc.h>
+#include "msm_gem.h"
+#include "dpu_hw_mdss.h"
+
+/**
+ * dpu_get_dpu_format_ext() - Returns dpu format structure pointer.
+ * @format:          DRM FourCC Code
+ * @modifiers:       format modifier array from client, one per plane
+ */
+const struct dpu_format *dpu_get_dpu_format_ext(
+		const uint32_t format,
+		const uint64_t modifier);
+
+#define dpu_get_dpu_format(f) dpu_get_dpu_format_ext(f, 0)
+
+/**
+ * dpu_find_format - validate if the pixel format is supported
+ * @format:		dpu format
+ * @supported_formats:	supported formats by dpu HW
+ * @num_formatss:	total number of formats
+ *
+ * Return: false if not valid format, true on success
+ */
+static inline bool dpu_find_format(u32 format, const u32 *supported_formats,
+					size_t num_formats)
+{
+	int i;
+
+	for (i = 0; i < num_formats; i++) {
+		/* check for valid formats supported */
+		if (format == supported_formats[i])
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * dpu_get_msm_format - get an dpu_format by its msm_format base
+ *                     callback function registers with the msm_kms layer
+ * @kms:             kms driver
+ * @format:          DRM FourCC Code
+ * @modifiers:       data layout modifier
+ */
+const struct msm_format *dpu_get_msm_format(
+		struct msm_kms *kms,
+		const uint32_t format,
+		const uint64_t modifiers);
+
+/**
+ * dpu_format_check_modified_format - validate format and buffers for
+ *                   dpu non-standard, i.e. modified format
+ * @kms:             kms driver
+ * @msm_fmt:         pointer to the msm_fmt base pointer of an dpu_format
+ * @cmd:             fb_cmd2 structure user request
+ * @bos:             gem buffer object list
+ *
+ * Return: error code on failure, 0 on success
+ */
+int dpu_format_check_modified_format(
+		const struct msm_kms *kms,
+		const struct msm_format *msm_fmt,
+		const struct drm_mode_fb_cmd2 *cmd,
+		struct drm_gem_object **bos);
+
+/**
+ * dpu_format_populate_layout - populate the given format layout based on
+ *                     mmu, fb, and format found in the fb
+ * @aspace:            address space pointer
+ * @fb:                framebuffer pointer
+ * @fmtl:              format layout structure to populate
+ *
+ * Return: error code on failure, -EAGAIN if success but the addresses
+ *         are the same as before or 0 if new addresses were populated
+ */
+int dpu_format_populate_layout(
+		struct msm_gem_address_space *aspace,
+		struct drm_framebuffer *fb,
+		struct dpu_hw_fmt_layout *fmtl);
+
+#endif /*_DPU_FORMATS_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_catalog.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_catalog.c
@@ -0,0 +1,702 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+#include <linux/slab.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_interrupts.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_kms.h"
+
+#define VIG_BASE_MASK \
+	(BIT(DPU_SSPP_QOS) |\
+	BIT(DPU_SSPP_CDP) |\
+	BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT))
+
+#define VIG_MASK \
+	(VIG_BASE_MASK | \
+	BIT(DPU_SSPP_CSC_10BIT))
+
+#define VIG_MSM8998_MASK \
+	(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE))
+
+#define VIG_SDM845_MASK \
+	(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3_COMPATIBLE))
+
+#define VIG_SDM845_MASK_SDMA \
+	(VIG_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+
+#define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL))
+
+#define DMA_MSM8998_MASK \
+	(BIT(DPU_SSPP_QOS) |\
+	BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
+	BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
+
+#define VIG_SC7280_MASK \
+	(VIG_SDM845_MASK | BIT(DPU_SSPP_INLINE_ROTATION))
+
+#define VIG_SC7280_MASK_SDMA \
+	(VIG_SC7280_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+
+#define DMA_SDM845_MASK \
+	(BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
+	BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
+	BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
+
+#define DMA_CURSOR_SDM845_MASK \
+	(DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR))
+
+#define DMA_SDM845_MASK_SDMA \
+	(DMA_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+
+#define DMA_CURSOR_SDM845_MASK_SDMA \
+	(DMA_CURSOR_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+
+#define DMA_CURSOR_MSM8998_MASK \
+	(DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR))
+
+#define MIXER_MSM8998_MASK \
+	(BIT(DPU_MIXER_SOURCESPLIT))
+
+#define MIXER_SDM845_MASK \
+	(BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA))
+
+#define MIXER_QCM2290_MASK \
+	(BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA))
+
+#define PINGPONG_SDM845_MASK \
+	(BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_DSC))
+
+#define PINGPONG_SDM845_TE2_MASK \
+	(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
+
+#define PINGPONG_SM8150_MASK \
+	(BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_DSC))
+
+#define CTL_SC7280_MASK \
+	(BIT(DPU_CTL_ACTIVE_CFG) | \
+	 BIT(DPU_CTL_FETCH_ACTIVE) | \
+	 BIT(DPU_CTL_VM_CFG) | \
+	 BIT(DPU_CTL_DSPP_SUB_BLOCK_FLUSH))
+
+#define CTL_SM8550_MASK \
+	(CTL_SC7280_MASK | BIT(DPU_CTL_HAS_LAYER_EXT4))
+
+#define DSPP_SC7180_MASK BIT(DPU_DSPP_PCC)
+
+#define INTF_SC7180_MASK \
+	(BIT(DPU_INTF_INPUT_CTRL) | \
+	 BIT(DPU_INTF_STATUS_SUPPORTED) | \
+	 BIT(DPU_DATA_HCTL_EN))
+
+#define INTF_SC7280_MASK (INTF_SC7180_MASK)
+
+#define WB_SM8250_MASK (BIT(DPU_WB_LINE_MODE) | \
+			 BIT(DPU_WB_UBWC) | \
+			 BIT(DPU_WB_YUV_CONFIG) | \
+			 BIT(DPU_WB_PIPE_ALPHA) | \
+			 BIT(DPU_WB_XY_ROI_OFFSET) | \
+			 BIT(DPU_WB_QOS) | \
+			 BIT(DPU_WB_QOS_8LVL) | \
+			 BIT(DPU_WB_CDP) | \
+			 BIT(DPU_WB_INPUT_CTRL))
+
+#define DEFAULT_PIXEL_RAM_SIZE		(50 * 1024)
+#define DEFAULT_DPU_LINE_WIDTH		2048
+#define DEFAULT_DPU_OUTPUT_LINE_WIDTH	2560
+
+#define MAX_HORZ_DECIMATION	4
+#define MAX_VERT_DECIMATION	4
+
+#define MAX_UPSCALE_RATIO	20
+#define MAX_DOWNSCALE_RATIO	4
+#define SSPP_UNITY_SCALE	1
+
+#define STRCAT(X, Y) (X Y)
+
+static const uint32_t plane_formats[] = {
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_RGBA8888,
+	DRM_FORMAT_BGRA8888,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_RGBX8888,
+	DRM_FORMAT_BGRX8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_ARGB2101010,
+	DRM_FORMAT_XRGB2101010,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_BGR565,
+	DRM_FORMAT_ARGB1555,
+	DRM_FORMAT_ABGR1555,
+	DRM_FORMAT_RGBA5551,
+	DRM_FORMAT_BGRA5551,
+	DRM_FORMAT_XRGB1555,
+	DRM_FORMAT_XBGR1555,
+	DRM_FORMAT_RGBX5551,
+	DRM_FORMAT_BGRX5551,
+	DRM_FORMAT_ARGB4444,
+	DRM_FORMAT_ABGR4444,
+	DRM_FORMAT_RGBA4444,
+	DRM_FORMAT_BGRA4444,
+	DRM_FORMAT_XRGB4444,
+	DRM_FORMAT_XBGR4444,
+	DRM_FORMAT_RGBX4444,
+	DRM_FORMAT_BGRX4444,
+};
+
+static const uint32_t plane_formats_yuv[] = {
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_RGBA8888,
+	DRM_FORMAT_BGRX8888,
+	DRM_FORMAT_BGRA8888,
+	DRM_FORMAT_ARGB2101010,
+	DRM_FORMAT_XRGB2101010,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_RGBX8888,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_BGR565,
+	DRM_FORMAT_ARGB1555,
+	DRM_FORMAT_ABGR1555,
+	DRM_FORMAT_RGBA5551,
+	DRM_FORMAT_BGRA5551,
+	DRM_FORMAT_XRGB1555,
+	DRM_FORMAT_XBGR1555,
+	DRM_FORMAT_RGBX5551,
+	DRM_FORMAT_BGRX5551,
+	DRM_FORMAT_ARGB4444,
+	DRM_FORMAT_ABGR4444,
+	DRM_FORMAT_RGBA4444,
+	DRM_FORMAT_BGRA4444,
+	DRM_FORMAT_XRGB4444,
+	DRM_FORMAT_XBGR4444,
+	DRM_FORMAT_RGBX4444,
+	DRM_FORMAT_BGRX4444,
+
+	DRM_FORMAT_P010,
+	DRM_FORMAT_NV12,
+	DRM_FORMAT_NV21,
+	DRM_FORMAT_NV16,
+	DRM_FORMAT_NV61,
+	DRM_FORMAT_VYUY,
+	DRM_FORMAT_UYVY,
+	DRM_FORMAT_YUYV,
+	DRM_FORMAT_YVYU,
+	DRM_FORMAT_YUV420,
+	DRM_FORMAT_YVU420,
+};
+
+static const u32 rotation_v2_formats[] = {
+	DRM_FORMAT_NV12,
+	/* TODO add formats after validation */
+};
+
+static const u32 wb2_formats_rgb[] = {
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_BGR565,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_RGBA8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_RGBX8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_ARGB1555,
+	DRM_FORMAT_RGBA5551,
+	DRM_FORMAT_XRGB1555,
+	DRM_FORMAT_RGBX5551,
+	DRM_FORMAT_ARGB4444,
+	DRM_FORMAT_RGBA4444,
+	DRM_FORMAT_RGBX4444,
+	DRM_FORMAT_XRGB4444,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_BGRA8888,
+	DRM_FORMAT_BGRX8888,
+	DRM_FORMAT_ABGR1555,
+	DRM_FORMAT_BGRA5551,
+	DRM_FORMAT_XBGR1555,
+	DRM_FORMAT_BGRX5551,
+	DRM_FORMAT_ABGR4444,
+	DRM_FORMAT_BGRA4444,
+	DRM_FORMAT_BGRX4444,
+	DRM_FORMAT_XBGR4444,
+};
+
+static const u32 wb2_formats_rgb_yuv[] = {
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_BGR565,
+	DRM_FORMAT_RGB888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_RGBA8888,
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_RGBX8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_ARGB1555,
+	DRM_FORMAT_RGBA5551,
+	DRM_FORMAT_XRGB1555,
+	DRM_FORMAT_RGBX5551,
+	DRM_FORMAT_ARGB4444,
+	DRM_FORMAT_RGBA4444,
+	DRM_FORMAT_RGBX4444,
+	DRM_FORMAT_XRGB4444,
+	DRM_FORMAT_BGR888,
+	DRM_FORMAT_BGRA8888,
+	DRM_FORMAT_BGRX8888,
+	DRM_FORMAT_ABGR1555,
+	DRM_FORMAT_BGRA5551,
+	DRM_FORMAT_XBGR1555,
+	DRM_FORMAT_BGRX5551,
+	DRM_FORMAT_ABGR4444,
+	DRM_FORMAT_BGRA4444,
+	DRM_FORMAT_BGRX4444,
+	DRM_FORMAT_XBGR4444,
+	DRM_FORMAT_NV12,
+};
+
+/*************************************************************
+ * SSPP sub blocks config
+ *************************************************************/
+
+#define SSPP_SCALER_VER(maj, min) (((maj) << 16) | (min))
+
+/* SSPP common configuration */
+#define _VIG_SBLK(scaler_ver) \
+	{ \
+	.maxdwnscale = MAX_DOWNSCALE_RATIO, \
+	.maxupscale = MAX_UPSCALE_RATIO, \
+	.scaler_blk = {.name = "scaler", \
+		.version = scaler_ver, \
+		.base = 0xa00, .len = 0xa0,}, \
+	.csc_blk = {.name = "csc", \
+		.base = 0x1a00, .len = 0x100,}, \
+	.format_list = plane_formats_yuv, \
+	.num_formats = ARRAY_SIZE(plane_formats_yuv), \
+	.virt_format_list = plane_formats, \
+	.virt_num_formats = ARRAY_SIZE(plane_formats), \
+	.rotation_cfg = NULL, \
+	}
+
+#define _VIG_SBLK_ROT(scaler_ver, rot_cfg) \
+	{ \
+	.maxdwnscale = MAX_DOWNSCALE_RATIO, \
+	.maxupscale = MAX_UPSCALE_RATIO, \
+	.scaler_blk = {.name = "scaler", \
+		.version = scaler_ver, \
+		.base = 0xa00, .len = 0xa0,}, \
+	.csc_blk = {.name = "csc", \
+		.base = 0x1a00, .len = 0x100,}, \
+	.format_list = plane_formats_yuv, \
+	.num_formats = ARRAY_SIZE(plane_formats_yuv), \
+	.virt_format_list = plane_formats, \
+	.virt_num_formats = ARRAY_SIZE(plane_formats), \
+	.rotation_cfg = rot_cfg, \
+	}
+
+#define _VIG_SBLK_NOSCALE() \
+	{ \
+	.maxdwnscale = SSPP_UNITY_SCALE, \
+	.maxupscale = SSPP_UNITY_SCALE, \
+	.format_list = plane_formats, \
+	.num_formats = ARRAY_SIZE(plane_formats), \
+	.virt_format_list = plane_formats, \
+	.virt_num_formats = ARRAY_SIZE(plane_formats), \
+	}
+
+#define _DMA_SBLK() \
+	{ \
+	.maxdwnscale = SSPP_UNITY_SCALE, \
+	.maxupscale = SSPP_UNITY_SCALE, \
+	.format_list = plane_formats, \
+	.num_formats = ARRAY_SIZE(plane_formats), \
+	.virt_format_list = plane_formats, \
+	.virt_num_formats = ARRAY_SIZE(plane_formats), \
+	}
+
+static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = {
+	.rot_maxheight = 1088,
+	.rot_num_formats = ARRAY_SIZE(rotation_v2_formats),
+	.rot_format_list = rotation_v2_formats,
+};
+
+static const struct dpu_sspp_sub_blks dpu_vig_sblk_noscale =
+				_VIG_SBLK_NOSCALE();
+
+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_2 =
+				_VIG_SBLK(SSPP_SCALER_VER(1, 2));
+
+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_3 =
+				_VIG_SBLK(SSPP_SCALER_VER(1, 3));
+
+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_1_4 =
+				_VIG_SBLK(SSPP_SCALER_VER(1, 4));
+
+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_2_4 =
+				_VIG_SBLK(SSPP_SCALER_VER(2, 4));
+
+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_0 =
+				_VIG_SBLK(SSPP_SCALER_VER(3, 0));
+
+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_0_rot_v2 =
+			_VIG_SBLK_ROT(SSPP_SCALER_VER(3, 0),
+				      &dpu_rot_sc7280_cfg_v2);
+
+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_1 =
+				_VIG_SBLK(SSPP_SCALER_VER(3, 1));
+
+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_2 =
+				_VIG_SBLK(SSPP_SCALER_VER(3, 2));
+
+static const struct dpu_sspp_sub_blks dpu_vig_sblk_qseed3_3_3 =
+				_VIG_SBLK(SSPP_SCALER_VER(3, 3));
+
+static const struct dpu_sspp_sub_blks dpu_dma_sblk = _DMA_SBLK();
+
+/*************************************************************
+ * MIXER sub blocks config
+ *************************************************************/
+
+/* MSM8998 */
+
+static const struct dpu_lm_sub_blks msm8998_lm_sblk = {
+	.maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.maxblendstages = 7, /* excluding base layer */
+	.blendstage_base = { /* offsets relative to mixer base */
+		0x20, 0x50, 0x80, 0xb0, 0x230,
+		0x260, 0x290
+	},
+};
+
+/* SDM845 */
+
+static const struct dpu_lm_sub_blks sdm845_lm_sblk = {
+	.maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.maxblendstages = 11, /* excluding base layer */
+	.blendstage_base = { /* offsets relative to mixer base */
+		0x20, 0x38, 0x50, 0x68, 0x80, 0x98,
+		0xb0, 0xc8, 0xe0, 0xf8, 0x110
+	},
+};
+
+/* SC7180 */
+
+static const struct dpu_lm_sub_blks sc7180_lm_sblk = {
+	.maxwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+	.maxblendstages = 7, /* excluding base layer */
+	.blendstage_base = { /* offsets relative to mixer base */
+		0x20, 0x38, 0x50, 0x68, 0x80, 0x98, 0xb0
+	},
+};
+
+/* QCM2290 */
+
+static const struct dpu_lm_sub_blks qcm2290_lm_sblk = {
+	.maxwidth = DEFAULT_DPU_LINE_WIDTH,
+	.maxblendstages = 4, /* excluding base layer */
+	.blendstage_base = { /* offsets relative to mixer base */
+		0x20, 0x38, 0x50, 0x68
+	},
+};
+
+/*************************************************************
+ * DSPP sub blocks config
+ *************************************************************/
+static const struct dpu_dspp_sub_blks msm8998_dspp_sblk = {
+	.pcc = {.name = "pcc", .base = 0x1700,
+		.len = 0x90, .version = 0x10007},
+};
+
+static const struct dpu_dspp_sub_blks sdm845_dspp_sblk = {
+	.pcc = {.name = "pcc", .base = 0x1700,
+		.len = 0x90, .version = 0x40000},
+};
+
+/*************************************************************
+ * PINGPONG sub blocks config
+ *************************************************************/
+static const struct dpu_pingpong_sub_blks sdm845_pp_sblk_te = {
+	.te2 = {.name = "te2", .base = 0x2000, .len = 0x0,
+		.version = 0x1},
+	.dither = {.name = "dither", .base = 0x30e0,
+		.len = 0x20, .version = 0x10000},
+};
+
+static const struct dpu_pingpong_sub_blks sdm845_pp_sblk = {
+	.dither = {.name = "dither", .base = 0x30e0,
+		.len = 0x20, .version = 0x10000},
+};
+
+static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = {
+	.dither = {.name = "dither", .base = 0xe0,
+	.len = 0x20, .version = 0x20000},
+};
+
+/*************************************************************
+ * DSC sub blocks config
+ *************************************************************/
+static const struct dpu_dsc_sub_blks dsc_sblk_0 = {
+	.enc = {.name = "enc", .base = 0x100, .len = 0x9c},
+	.ctl = {.name = "ctl", .base = 0xF00, .len = 0x10},
+};
+
+static const struct dpu_dsc_sub_blks dsc_sblk_1 = {
+	.enc = {.name = "enc", .base = 0x200, .len = 0x9c},
+	.ctl = {.name = "ctl", .base = 0xF80, .len = 0x10},
+};
+
+/*************************************************************
+ * CDM block config
+ *************************************************************/
+static const struct dpu_cdm_cfg sc7280_cdm = {
+	.name = "cdm_0",
+	.id = CDM_0,
+	.len = 0x228,
+	.base = 0x79200,
+};
+
+/*************************************************************
+ * VBIF sub blocks config
+ *************************************************************/
+/* VBIF QOS remap */
+static const u32 msm8998_rt_pri_lvl[] = {1, 2, 2, 2};
+static const u32 msm8998_nrt_pri_lvl[] = {1, 1, 1, 1};
+static const u32 sdm845_rt_pri_lvl[] = {3, 3, 4, 4, 5, 5, 6, 6};
+static const u32 sdm845_nrt_pri_lvl[] = {3, 3, 3, 3, 3, 3, 3, 3};
+static const u32 sm8650_rt_pri_lvl[] = {4, 4, 5, 5, 5, 5, 5, 6};
+
+static const struct dpu_vbif_dynamic_ot_cfg msm8998_ot_rdwr_cfg[] = {
+	{
+		.pps = 1920 * 1080 * 30,
+		.ot_limit = 2,
+	},
+	{
+		.pps = 1920 * 1080 * 60,
+		.ot_limit = 4,
+	},
+	{
+		.pps = 3840 * 2160 * 30,
+		.ot_limit = 16,
+	},
+};
+
+static const struct dpu_vbif_cfg msm8998_vbif[] = {
+	{
+	.name = "vbif_rt", .id = VBIF_RT,
+	.base = 0, .len = 0x1040,
+	.default_ot_rd_limit = 32,
+	.default_ot_wr_limit = 32,
+	.features = BIT(DPU_VBIF_QOS_REMAP) | BIT(DPU_VBIF_QOS_OTLIM),
+	.xin_halt_timeout = 0x4000,
+	.qos_rp_remap_size = 0x20,
+	.dynamic_ot_rd_tbl = {
+		.count = ARRAY_SIZE(msm8998_ot_rdwr_cfg),
+		.cfg = msm8998_ot_rdwr_cfg,
+		},
+	.dynamic_ot_wr_tbl = {
+		.count = ARRAY_SIZE(msm8998_ot_rdwr_cfg),
+		.cfg = msm8998_ot_rdwr_cfg,
+		},
+	.qos_rt_tbl = {
+		.npriority_lvl = ARRAY_SIZE(msm8998_rt_pri_lvl),
+		.priority_lvl = msm8998_rt_pri_lvl,
+		},
+	.qos_nrt_tbl = {
+		.npriority_lvl = ARRAY_SIZE(msm8998_nrt_pri_lvl),
+		.priority_lvl = msm8998_nrt_pri_lvl,
+		},
+	.memtype_count = 14,
+	.memtype = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
+	},
+};
+
+static const struct dpu_vbif_cfg sdm845_vbif[] = {
+	{
+	.name = "vbif_rt", .id = VBIF_RT,
+	.base = 0, .len = 0x1040,
+	.features = BIT(DPU_VBIF_QOS_REMAP),
+	.xin_halt_timeout = 0x4000,
+	.qos_rp_remap_size = 0x40,
+	.qos_rt_tbl = {
+		.npriority_lvl = ARRAY_SIZE(sdm845_rt_pri_lvl),
+		.priority_lvl = sdm845_rt_pri_lvl,
+		},
+	.qos_nrt_tbl = {
+		.npriority_lvl = ARRAY_SIZE(sdm845_nrt_pri_lvl),
+		.priority_lvl = sdm845_nrt_pri_lvl,
+		},
+	.memtype_count = 14,
+	.memtype = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	},
+};
+
+static const struct dpu_vbif_cfg sm8550_vbif[] = {
+	{
+	.name = "vbif_rt", .id = VBIF_RT,
+	.base = 0, .len = 0x1040,
+	.features = BIT(DPU_VBIF_QOS_REMAP),
+	.xin_halt_timeout = 0x4000,
+	.qos_rp_remap_size = 0x40,
+	.qos_rt_tbl = {
+		.npriority_lvl = ARRAY_SIZE(sdm845_rt_pri_lvl),
+		.priority_lvl = sdm845_rt_pri_lvl,
+		},
+	.qos_nrt_tbl = {
+		.npriority_lvl = ARRAY_SIZE(sdm845_nrt_pri_lvl),
+		.priority_lvl = sdm845_nrt_pri_lvl,
+		},
+	.memtype_count = 16,
+	.memtype = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	},
+};
+
+static const struct dpu_vbif_cfg sm8650_vbif[] = {
+	{
+	.name = "vbif_rt", .id = VBIF_RT,
+	.base = 0, .len = 0x1074,
+	.features = BIT(DPU_VBIF_QOS_REMAP),
+	.xin_halt_timeout = 0x4000,
+	.qos_rp_remap_size = 0x40,
+	.qos_rt_tbl = {
+		.npriority_lvl = ARRAY_SIZE(sm8650_rt_pri_lvl),
+		.priority_lvl = sm8650_rt_pri_lvl,
+		},
+	.qos_nrt_tbl = {
+		.npriority_lvl = ARRAY_SIZE(sdm845_nrt_pri_lvl),
+		.priority_lvl = sdm845_nrt_pri_lvl,
+		},
+	.memtype_count = 16,
+	.memtype = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
+	},
+};
+
+/*************************************************************
+ * PERF data config
+ *************************************************************/
+
+/* SSPP QOS LUTs */
+static const struct dpu_qos_lut_entry msm8998_qos_linear[] = {
+	{.fl = 4,  .lut = 0x1b},
+	{.fl = 5,  .lut = 0x5b},
+	{.fl = 6,  .lut = 0x15b},
+	{.fl = 7,  .lut = 0x55b},
+	{.fl = 8,  .lut = 0x155b},
+	{.fl = 9,  .lut = 0x555b},
+	{.fl = 10, .lut = 0x1555b},
+	{.fl = 11, .lut = 0x5555b},
+	{.fl = 12, .lut = 0x15555b},
+	{.fl = 0,  .lut = 0x55555b}
+};
+
+static const struct dpu_qos_lut_entry sdm845_qos_linear[] = {
+	{.fl = 4, .lut = 0x357},
+	{.fl = 5, .lut = 0x3357},
+	{.fl = 6, .lut = 0x23357},
+	{.fl = 7, .lut = 0x223357},
+	{.fl = 8, .lut = 0x2223357},
+	{.fl = 9, .lut = 0x22223357},
+	{.fl = 10, .lut = 0x222223357},
+	{.fl = 11, .lut = 0x2222223357},
+	{.fl = 12, .lut = 0x22222223357},
+	{.fl = 13, .lut = 0x222222223357},
+	{.fl = 14, .lut = 0x1222222223357},
+	{.fl = 0, .lut = 0x11222222223357}
+};
+
+static const struct dpu_qos_lut_entry msm8998_qos_macrotile[] = {
+	{.fl = 10, .lut = 0x1aaff},
+	{.fl = 11, .lut = 0x5aaff},
+	{.fl = 12, .lut = 0x15aaff},
+	{.fl = 0,  .lut = 0x55aaff},
+};
+
+static const struct dpu_qos_lut_entry sc7180_qos_linear[] = {
+	{.fl = 0, .lut = 0x0011222222335777},
+};
+
+static const struct dpu_qos_lut_entry sm6350_qos_linear_macrotile[] = {
+	{.fl = 0, .lut = 0x0011223445566777 },
+};
+
+static const struct dpu_qos_lut_entry sm8150_qos_linear[] = {
+	{.fl = 0, .lut = 0x0011222222223357 },
+};
+
+static const struct dpu_qos_lut_entry sc8180x_qos_linear[] = {
+	{.fl = 4, .lut = 0x0000000000000357 },
+};
+
+static const struct dpu_qos_lut_entry qcm2290_qos_linear[] = {
+	{.fl = 0, .lut = 0x0011222222335777},
+};
+
+static const struct dpu_qos_lut_entry sdm845_qos_macrotile[] = {
+	{.fl = 10, .lut = 0x344556677},
+	{.fl = 11, .lut = 0x3344556677},
+	{.fl = 12, .lut = 0x23344556677},
+	{.fl = 13, .lut = 0x223344556677},
+	{.fl = 14, .lut = 0x1223344556677},
+	{.fl = 0, .lut = 0x112233344556677},
+};
+
+static const struct dpu_qos_lut_entry sc7180_qos_macrotile[] = {
+	{.fl = 0, .lut = 0x0011223344556677},
+};
+
+static const struct dpu_qos_lut_entry sc8180x_qos_macrotile[] = {
+	{.fl = 10, .lut = 0x0000000344556677},
+};
+
+static const struct dpu_qos_lut_entry msm8998_qos_nrt[] = {
+	{.fl = 0, .lut = 0x0},
+};
+
+static const struct dpu_qos_lut_entry sdm845_qos_nrt[] = {
+	{.fl = 0, .lut = 0x0},
+};
+
+static const struct dpu_qos_lut_entry sc7180_qos_nrt[] = {
+	{.fl = 0, .lut = 0x0},
+};
+
+/*************************************************************
+ * Hardware catalog
+ *************************************************************/
+
+#include "catalog/dpu_3_0_msm8998.h"
+
+#include "catalog/dpu_4_0_sdm845.h"
+#include "catalog/dpu_4_1_sdm670.h"
+
+#include "catalog/dpu_5_0_sm8150.h"
+#include "catalog/dpu_5_1_sc8180x.h"
+#include "catalog/dpu_5_4_sm6125.h"
+
+#include "catalog/dpu_6_0_sm8250.h"
+#include "catalog/dpu_6_2_sc7180.h"
+#include "catalog/dpu_6_3_sm6115.h"
+#include "catalog/dpu_6_4_sm6350.h"
+#include "catalog/dpu_6_5_qcm2290.h"
+#include "catalog/dpu_6_9_sm6375.h"
+
+#include "catalog/dpu_7_0_sm8350.h"
+#include "catalog/dpu_7_2_sc7280.h"
+
+#include "catalog/dpu_8_0_sc8280xp.h"
+#include "catalog/dpu_8_1_sm8450.h"
+#include "catalog/dpu_8_4_qcs8300.h"
+#include "catalog/dpu_8_4_sa8775p.h"
+
+#include "catalog/dpu_9_0_sm8550.h"
+
+#include "catalog/dpu_10_0_sm8650.h"
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_catalog.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_catalog.h
@@ -0,0 +1,855 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_CATALOG_H
+#define _DPU_HW_CATALOG_H
+
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <linux/bitmap.h>
+#include <linux/err.h>
+
+/**
+ * Max hardware block count: For ex: max 12 SSPP pipes or
+ * 5 ctl paths. In all cases, it can have max 12 hardware blocks
+ * based on current design
+ */
+#define MAX_BLOCKS    12
+
+#define DPU_HW_BLK_NAME_LEN	16
+
+#define MAX_IMG_WIDTH 0x3fff
+#define MAX_IMG_HEIGHT 0x3fff
+
+#define CRTC_DUAL_MIXERS	2
+
+#define MAX_XIN_COUNT 16
+
+/**
+ * MDP TOP BLOCK features
+ * @DPU_MDP_PANIC_PER_PIPE Panic configuration needs to be done per pipe
+ * @DPU_MDP_10BIT_SUPPORT, Chipset supports 10 bit pixel formats
+ * @DPU_MDP_PERIPH_0_REMOVED Indicates that access to periph top0 block results
+ *			   in a failure
+ * @DPU_MDP_VSYNC_SEL      Enables vsync source selection via MDP_VSYNC_SEL register
+ *                         (moved into INTF block since DPU 5.0.0)
+ * @DPU_MDP_MAX            Maximum value
+
+ */
+enum {
+	DPU_MDP_PANIC_PER_PIPE = 0x1,
+	DPU_MDP_10BIT_SUPPORT,
+	DPU_MDP_AUDIO_SELECT,
+	DPU_MDP_PERIPH_0_REMOVED,
+	DPU_MDP_VSYNC_SEL,
+	DPU_MDP_MAX
+};
+
+/**
+ * SSPP sub-blocks/features
+ * @DPU_SSPP_SCALER_QSEED2,  QSEED2 algorithm support
+ * @DPU_SSPP_SCALER_QSEED3_COMPATIBLE,  QSEED3-compatible alogorithm support (includes QSEED3, QSEED3LITE and QSEED4)
+ * @DPU_SSPP_SCALER_RGB,     RGB Scaler, supported by RGB pipes
+ * @DPU_SSPP_CSC,            Support of Color space converion
+ * @DPU_SSPP_CSC_10BIT,      Support of 10-bit Color space conversion
+ * @DPU_SSPP_CURSOR,         SSPP can be used as a cursor layer
+ * @DPU_SSPP_QOS,            SSPP support QoS control, danger/safe/creq
+ * @DPU_SSPP_QOS_8LVL,       SSPP support 8-level QoS control
+ * @DPU_SSPP_EXCL_RECT,      SSPP supports exclusion rect
+ * @DPU_SSPP_SMART_DMA_V1,   SmartDMA 1.0 support
+ * @DPU_SSPP_SMART_DMA_V2,   SmartDMA 2.0 support
+ * @DPU_SSPP_TS_PREFILL      Supports prefill with traffic shaper
+ * @DPU_SSPP_TS_PREFILL_REC1 Supports prefill with traffic shaper multirec
+ * @DPU_SSPP_CDP             Supports client driven prefetch
+ * @DPU_SSPP_INLINE_ROTATION Support inline rotation
+ * @DPU_SSPP_MAX             maximum value
+ */
+enum {
+	DPU_SSPP_SCALER_QSEED2 = 0x1,
+	DPU_SSPP_SCALER_QSEED3_COMPATIBLE,
+	DPU_SSPP_SCALER_RGB,
+	DPU_SSPP_CSC,
+	DPU_SSPP_CSC_10BIT,
+	DPU_SSPP_CURSOR,
+	DPU_SSPP_QOS,
+	DPU_SSPP_QOS_8LVL,
+	DPU_SSPP_EXCL_RECT,
+	DPU_SSPP_SMART_DMA_V1,
+	DPU_SSPP_SMART_DMA_V2,
+	DPU_SSPP_TS_PREFILL,
+	DPU_SSPP_TS_PREFILL_REC1,
+	DPU_SSPP_CDP,
+	DPU_SSPP_INLINE_ROTATION,
+	DPU_SSPP_MAX
+};
+
+/*
+ * MIXER sub-blocks/features
+ * @DPU_MIXER_LAYER           Layer mixer layer blend configuration,
+ * @DPU_MIXER_SOURCESPLIT     Layer mixer supports source-split configuration
+ * @DPU_MIXER_GC              Gamma correction block
+ * @DPU_DIM_LAYER             Layer mixer supports dim layer
+ * @DPU_MIXER_COMBINED_ALPHA  Layer mixer has combined alpha register
+ * @DPU_MIXER_MAX             maximum value
+ */
+enum {
+	DPU_MIXER_LAYER = 0x1,
+	DPU_MIXER_SOURCESPLIT,
+	DPU_MIXER_GC,
+	DPU_DIM_LAYER,
+	DPU_MIXER_COMBINED_ALPHA,
+	DPU_MIXER_MAX
+};
+
+/**
+ * DSPP sub-blocks
+ * @DPU_DSPP_PCC             Panel color correction block
+ */
+enum {
+	DPU_DSPP_PCC = 0x1,
+	DPU_DSPP_MAX
+};
+
+/**
+ * PINGPONG sub-blocks
+ * @DPU_PINGPONG_TE2        Additional tear check block for split pipes
+ * @DPU_PINGPONG_SPLIT      PP block supports split fifo
+ * @DPU_PINGPONG_SLAVE      PP block is a suitable slave for split fifo
+ * @DPU_PINGPONG_DITHER     Dither blocks
+ * @DPU_PINGPONG_DSC        PP block supports DSC
+ * @DPU_PINGPONG_MAX
+ */
+enum {
+	DPU_PINGPONG_TE2 = 0x1,
+	DPU_PINGPONG_SPLIT,
+	DPU_PINGPONG_SLAVE,
+	DPU_PINGPONG_DITHER,
+	DPU_PINGPONG_DSC,
+	DPU_PINGPONG_MAX
+};
+
+/**
+ * CTL sub-blocks
+ * @DPU_CTL_SPLIT_DISPLAY:	CTL supports video mode split display
+ * @DPU_CTL_FETCH_ACTIVE:	Active CTL for fetch HW (SSPPs)
+ * @DPU_CTL_VM_CFG:		CTL config to support multiple VMs
+ * @DPU_CTL_HAS_LAYER_EXT4:	CTL has the CTL_LAYER_EXT4 register
+ * @DPU_CTL_DSPP_BLOCK_FLUSH:	CTL config to support dspp sub-block flush
+ * @DPU_CTL_MAX
+ */
+enum {
+	DPU_CTL_SPLIT_DISPLAY = 0x1,
+	DPU_CTL_ACTIVE_CFG,
+	DPU_CTL_FETCH_ACTIVE,
+	DPU_CTL_VM_CFG,
+	DPU_CTL_HAS_LAYER_EXT4,
+	DPU_CTL_DSPP_SUB_BLOCK_FLUSH,
+	DPU_CTL_MAX
+};
+
+/**
+ * INTF sub-blocks
+ * @DPU_INTF_INPUT_CTRL             Supports the setting of pp block from which
+ *                                  pixel data arrives to this INTF
+ * @DPU_DATA_HCTL_EN                Allows data to be transferred at different rate
+ *                                  than video timing
+ * @DPU_INTF_STATUS_SUPPORTED       INTF block has INTF_STATUS register
+ * @DPU_INTF_MAX
+ */
+enum {
+	DPU_INTF_INPUT_CTRL = 0x1,
+	DPU_DATA_HCTL_EN,
+	DPU_INTF_STATUS_SUPPORTED,
+	DPU_INTF_MAX
+};
+
+/**
+  * WB sub-blocks and features
+  * @DPU_WB_LINE_MODE        Writeback module supports line/linear mode
+  * @DPU_WB_BLOCK_MODE       Writeback module supports block mode read
+  * @DPU_WB_CHROMA_DOWN,     Writeback chroma down block,
+  * @DPU_WB_DOWNSCALE,       Writeback integer downscaler,
+  * @DPU_WB_DITHER,          Dither block
+  * @DPU_WB_TRAFFIC_SHAPER,  Writeback traffic shaper bloc
+  * @DPU_WB_UBWC,            Writeback Universal bandwidth compression
+  * @DPU_WB_YUV_CONFIG       Writeback supports output of YUV colorspace
+  * @DPU_WB_PIPE_ALPHA       Writeback supports pipe alpha
+  * @DPU_WB_XY_ROI_OFFSET    Writeback supports x/y-offset of out ROI in
+  *                          the destination image
+  * @DPU_WB_QOS,             Writeback supports QoS control, danger/safe/creq
+  * @DPU_WB_QOS_8LVL,        Writeback supports 8-level QoS control
+  * @DPU_WB_CDP              Writeback supports client driven prefetch
+  * @DPU_WB_INPUT_CTRL       Writeback supports from which pp block input pixel
+  *                          data arrives.
+  * @DPU_WB_CROP             CWB supports cropping
+  * @DPU_WB_MAX              maximum value
+  */
+enum {
+	DPU_WB_LINE_MODE = 0x1,
+	DPU_WB_BLOCK_MODE,
+	DPU_WB_UBWC,
+	DPU_WB_YUV_CONFIG,
+	DPU_WB_PIPE_ALPHA,
+	DPU_WB_XY_ROI_OFFSET,
+	DPU_WB_QOS,
+	DPU_WB_QOS_8LVL,
+	DPU_WB_CDP,
+	DPU_WB_INPUT_CTRL,
+	DPU_WB_CROP,
+	DPU_WB_MAX
+};
+
+/**
+ * VBIF sub-blocks and features
+ * @DPU_VBIF_QOS_OTLIM        VBIF supports OT Limit
+ * @DPU_VBIF_QOS_REMAP        VBIF supports QoS priority remap
+ * @DPU_VBIF_MAX              maximum value
+ */
+enum {
+	DPU_VBIF_QOS_OTLIM = 0x1,
+	DPU_VBIF_QOS_REMAP,
+	DPU_VBIF_MAX
+};
+
+/**
+ * DSC sub-blocks/features
+ * @DPU_DSC_OUTPUT_CTRL       Configure which PINGPONG block gets
+ *                            the pixel output from this DSC.
+ * @DPU_DSC_HW_REV_1_2        DSC block supports DSC 1.1 and 1.2
+ * @DPU_DSC_NATIVE_42x_EN     Supports NATIVE_422_EN and NATIVE_420_EN encoding
+ * @DPU_DSC_MAX
+ */
+enum {
+	DPU_DSC_OUTPUT_CTRL = 0x1,
+	DPU_DSC_HW_REV_1_2,
+	DPU_DSC_NATIVE_42x_EN,
+	DPU_DSC_MAX
+};
+
+/**
+ * MACRO DPU_HW_BLK_INFO - information of HW blocks inside DPU
+ * @name:              string name for debug purposes
+ * @id:                enum identifying this block
+ * @base:              register base offset to mdss
+ * @len:               length of hardware block
+ * @features           bit mask identifying sub-blocks/features
+ */
+#define DPU_HW_BLK_INFO \
+	char name[DPU_HW_BLK_NAME_LEN]; \
+	u32 id; \
+	u32 base; \
+	u32 len; \
+	unsigned long features
+
+/**
+ * struct dpu_scaler_blk: Scaler information
+ * @name: string name for debug purposes
+ * @base: offset of this sub-block relative to the block offset
+ * @len: register block length of this sub-block
+ * @version: qseed block revision, on QSEED3+ platforms this is the value of
+ *           scaler_blk.base + QSEED3_HW_VERSION registers.
+ */
+struct dpu_scaler_blk {
+	char name[DPU_HW_BLK_NAME_LEN];
+	u32 base;
+	u32 len;
+	u32 version;
+};
+
+struct dpu_csc_blk {
+	char name[DPU_HW_BLK_NAME_LEN];
+	u32 base;
+	u32 len;
+};
+
+/**
+ * struct dpu_pp_blk : Pixel processing sub-blk information
+ * @name: string name for debug purposes
+ * @base: offset of this sub-block relative to the block offset
+ * @len: register block length of this sub-block
+ * @version: HW Algorithm version
+ */
+struct dpu_pp_blk {
+	char name[DPU_HW_BLK_NAME_LEN];
+	u32 base;
+	u32 len;
+	u32 version;
+};
+
+/**
+ * struct dpu_dsc_blk - DSC Encoder sub-blk information
+ * @name: string name for debug purposes
+ * @base: offset of this sub-block relative to the block offset
+ * @len: register block length of this sub-block
+ */
+struct dpu_dsc_blk {
+	char name[DPU_HW_BLK_NAME_LEN];
+	u32 base;
+	u32 len;
+};
+
+/**
+ * enum dpu_qos_lut_usage - define QoS LUT use cases
+ */
+enum dpu_qos_lut_usage {
+	DPU_QOS_LUT_USAGE_LINEAR,
+	DPU_QOS_LUT_USAGE_MACROTILE,
+	DPU_QOS_LUT_USAGE_NRT,
+	DPU_QOS_LUT_USAGE_MAX,
+};
+
+/**
+ * struct dpu_qos_lut_entry - define QoS LUT table entry
+ * @fl: fill level, or zero on last entry to indicate default lut
+ * @lut: lut to use if equal to or less than fill level
+ */
+struct dpu_qos_lut_entry {
+	u32 fl;
+	u64 lut;
+};
+
+/**
+ * struct dpu_qos_lut_tbl - define QoS LUT table
+ * @nentry: number of entry in this table
+ * @entries: Pointer to table entries
+ */
+struct dpu_qos_lut_tbl {
+	u32 nentry;
+	const struct dpu_qos_lut_entry *entries;
+};
+
+/**
+ * struct dpu_rotation_cfg - define inline rotation config
+ * @rot_maxheight: max pre rotated height allowed for rotation
+ * @rot_num_formats: number of elements in @rot_format_list
+ * @rot_format_list: list of supported rotator formats
+ */
+struct dpu_rotation_cfg {
+	u32 rot_maxheight;
+	size_t rot_num_formats;
+	const u32 *rot_format_list;
+};
+
+/**
+ * struct dpu_caps - define DPU capabilities
+ * @max_mixer_width    max layer mixer line width support.
+ * @max_mixer_blendstages max layer mixer blend stages or
+ *                       supported z order
+ * @has_src_split      source split feature status
+ * @has_dim_layer      dim layer feature status
+ * @has_idle_pc        indicate if idle power collapse feature is supported
+ * @has_3d_merge       indicate if 3D merge is supported
+ * @max_linewidth      max linewidth for sspp
+ * @pixel_ram_size     size of latency hiding and de-tiling buffer in bytes
+ * @max_hdeci_exp      max horizontal decimation supported (max is 2^value)
+ * @max_vdeci_exp      max vertical decimation supported (max is 2^value)
+ */
+struct dpu_caps {
+	u32 max_mixer_width;
+	u32 max_mixer_blendstages;
+	bool has_src_split;
+	bool has_dim_layer;
+	bool has_idle_pc;
+	bool has_3d_merge;
+	/* SSPP limits */
+	u32 max_linewidth;
+	u32 pixel_ram_size;
+	u32 max_hdeci_exp;
+	u32 max_vdeci_exp;
+};
+
+/**
+ * struct dpu_sspp_sub_blks : SSPP sub-blocks
+ * common: Pointer to common configurations shared by sub blocks
+ * @maxdwnscale: max downscale ratio supported(without DECIMATION)
+ * @maxupscale:  maxupscale ratio supported
+ * @max_per_pipe_bw: maximum allowable bandwidth of this pipe in kBps
+ * @qseed_ver: qseed version
+ * @scaler_blk:
+ * @csc_blk:
+ * @format_list: Pointer to list of supported formats
+ * @num_formats: Number of supported formats
+ * @virt_format_list: Pointer to list of supported formats for virtual planes
+ * @virt_num_formats: Number of supported formats for virtual planes
+ * @dpu_rotation_cfg: inline rotation configuration
+ */
+struct dpu_sspp_sub_blks {
+	u32 maxdwnscale;
+	u32 maxupscale;
+	u32 max_per_pipe_bw;
+	u32 qseed_ver;
+	struct dpu_scaler_blk scaler_blk;
+	struct dpu_pp_blk csc_blk;
+
+	const u32 *format_list;
+	u32 num_formats;
+	const u32 *virt_format_list;
+	u32 virt_num_formats;
+	const struct dpu_rotation_cfg *rotation_cfg;
+};
+
+/**
+ * struct dpu_lm_sub_blks:      information of mixer block
+ * @maxwidth:               Max pixel width supported by this mixer
+ * @maxblendstages:         Max number of blend-stages supported
+ * @blendstage_base:        Blend-stage register base offset
+ */
+struct dpu_lm_sub_blks {
+	u32 maxwidth;
+	u32 maxblendstages;
+	u32 blendstage_base[MAX_BLOCKS];
+};
+
+/**
+ * struct dpu_dspp_sub_blks: Information of DSPP block
+ * @pcc: pixel color correction block
+ */
+struct dpu_dspp_sub_blks {
+	struct dpu_pp_blk pcc;
+};
+
+struct dpu_pingpong_sub_blks {
+	struct dpu_pp_blk te;
+	struct dpu_pp_blk te2;
+	struct dpu_pp_blk dither;
+};
+
+/**
+ * struct dpu_dsc_sub_blks - DSC sub-blks
+ * @enc: DSC encoder sub-block
+ * @ctl: DSC controller sub-block
+ */
+struct dpu_dsc_sub_blks {
+	struct dpu_dsc_blk enc;
+	struct dpu_dsc_blk ctl;
+};
+
+/**
+ * dpu_clk_ctrl_type - Defines top level clock control signals
+ */
+enum dpu_clk_ctrl_type {
+	DPU_CLK_CTRL_NONE,
+	DPU_CLK_CTRL_VIG0,
+	DPU_CLK_CTRL_VIG1,
+	DPU_CLK_CTRL_VIG2,
+	DPU_CLK_CTRL_VIG3,
+	DPU_CLK_CTRL_VIG4,
+	DPU_CLK_CTRL_RGB0,
+	DPU_CLK_CTRL_RGB1,
+	DPU_CLK_CTRL_RGB2,
+	DPU_CLK_CTRL_RGB3,
+	DPU_CLK_CTRL_DMA0,
+	DPU_CLK_CTRL_DMA1,
+	DPU_CLK_CTRL_DMA2,
+	DPU_CLK_CTRL_DMA3,
+	DPU_CLK_CTRL_DMA4,
+	DPU_CLK_CTRL_DMA5,
+	DPU_CLK_CTRL_CURSOR0,
+	DPU_CLK_CTRL_CURSOR1,
+	DPU_CLK_CTRL_INLINE_ROT0_SSPP,
+	DPU_CLK_CTRL_REG_DMA,
+	DPU_CLK_CTRL_WB2,
+	DPU_CLK_CTRL_MAX,
+};
+
+/* struct dpu_clk_ctrl_reg : Clock control register
+ * @reg_off:           register offset
+ * @bit_off:           bit offset
+ */
+struct dpu_clk_ctrl_reg {
+	u32 reg_off;
+	u32 bit_off;
+};
+
+/* struct dpu_mdp_cfg : MDP TOP-BLK instance info
+ * @id:                index identifying this block
+ * @base:              register base offset to mdss
+ * @features           bit mask identifying sub-blocks/features
+ * @clk_ctrls          clock control register definition
+ */
+struct dpu_mdp_cfg {
+	DPU_HW_BLK_INFO;
+	struct dpu_clk_ctrl_reg clk_ctrls[DPU_CLK_CTRL_MAX];
+};
+
+/* struct dpu_ctl_cfg : MDP CTL instance info
+ * @id:                index identifying this block
+ * @base:              register base offset to mdss
+ * @features           bit mask identifying sub-blocks/features
+ * @intr_start:        interrupt index for CTL_START
+ */
+struct dpu_ctl_cfg {
+	DPU_HW_BLK_INFO;
+	unsigned int intr_start;
+};
+
+/**
+ * struct dpu_sspp_cfg - information of source pipes
+ * @id:                index identifying this block
+ * @base               register offset of this block
+ * @features           bit mask identifying sub-blocks/features
+ * @sblk:              SSPP sub-blocks information
+ * @xin_id:            bus client identifier
+ * @clk_ctrl           clock control identifier
+ * @type               sspp type identifier
+ */
+struct dpu_sspp_cfg {
+	DPU_HW_BLK_INFO;
+	const struct dpu_sspp_sub_blks *sblk;
+	u32 xin_id;
+	enum dpu_clk_ctrl_type clk_ctrl;
+	u32 type;
+};
+
+/**
+ * struct dpu_lm_cfg - information of layer mixer blocks
+ * @id:                index identifying this block
+ * @base               register offset of this block
+ * @features           bit mask identifying sub-blocks/features
+ * @sblk:              LM Sub-blocks information
+ * @pingpong:          ID of connected PingPong, PINGPONG_NONE if unsupported
+ * @lm_pair:           ID of LM that can be controlled by same CTL
+ */
+struct dpu_lm_cfg {
+	DPU_HW_BLK_INFO;
+	const struct dpu_lm_sub_blks *sblk;
+	u32 pingpong;
+	u32 dspp;
+	unsigned long lm_pair;
+};
+
+/**
+ * struct dpu_dspp_cfg - information of DSPP blocks
+ * @id                 enum identifying this block
+ * @base               register offset of this block
+ * @features           bit mask identifying sub-blocks/features
+ *                     supported by this block
+ * @sblk               sub-blocks information
+ */
+struct dpu_dspp_cfg  {
+	DPU_HW_BLK_INFO;
+	const struct dpu_dspp_sub_blks *sblk;
+};
+
+/**
+ * struct dpu_pingpong_cfg - information of PING-PONG blocks
+ * @id                 enum identifying this block
+ * @base               register offset of this block
+ * @features           bit mask identifying sub-blocks/features
+ * @intr_done:         index for PINGPONG done interrupt
+ * @intr_rdptr:        index for PINGPONG readpointer done interrupt
+ * @sblk               sub-blocks information
+ */
+struct dpu_pingpong_cfg  {
+	DPU_HW_BLK_INFO;
+	u32 merge_3d;
+	unsigned int intr_done;
+	unsigned int intr_rdptr;
+	const struct dpu_pingpong_sub_blks *sblk;
+};
+
+/**
+ * struct dpu_merge_3d_cfg - information of DSPP blocks
+ * @id                 enum identifying this block
+ * @base               register offset of this block
+ * @features           bit mask identifying sub-blocks/features
+ *                     supported by this block
+ * @sblk               sub-blocks information
+ */
+struct dpu_merge_3d_cfg  {
+	DPU_HW_BLK_INFO;
+	const struct dpu_merge_3d_sub_blks *sblk;
+};
+
+/**
+ * struct dpu_dsc_cfg - information of DSC blocks
+ * @id                 enum identifying this block
+ * @base               register offset of this block
+ * @len:               length of hardware block
+ * @features           bit mask identifying sub-blocks/features
+ * @sblk:              sub-blocks information
+ */
+struct dpu_dsc_cfg {
+	DPU_HW_BLK_INFO;
+	const struct dpu_dsc_sub_blks *sblk;
+};
+
+/**
+ * struct dpu_intf_cfg - information of timing engine blocks
+ * @id                 enum identifying this block
+ * @base               register offset of this block
+ * @features           bit mask identifying sub-blocks/features
+ * @type:              Interface type(DSI, DP, HDMI)
+ * @controller_id:     Controller Instance ID in case of multiple of intf type
+ * @prog_fetch_lines_worst_case	Worst case latency num lines needed to prefetch
+ * @intr_underrun:	index for INTF underrun interrupt
+ * @intr_vsync:	        index for INTF VSYNC interrupt
+ * @intr_tear_rd_ptr:  Index for INTF TEAR_RD_PTR interrupt
+ */
+struct dpu_intf_cfg  {
+	DPU_HW_BLK_INFO;
+	u32 type;   /* interface type*/
+	u32 controller_id;
+	u32 prog_fetch_lines_worst_case;
+	unsigned int intr_underrun;
+	unsigned int intr_vsync;
+	unsigned int intr_tear_rd_ptr;
+};
+
+/**
+ * struct dpu_wb_cfg - information of writeback blocks
+ * @DPU_HW_BLK_INFO:    refer to the description above for DPU_HW_BLK_INFO
+ * @vbif_idx:           vbif client index
+ * @maxlinewidth:       max line width supported by writeback block
+ * @xin_id:             bus client identifier
+ * @intr_wb_done:       interrupt index for WB_DONE
+ * @format_list:	    list of formats supported by this writeback block
+ * @num_formats:	    number of formats supported by this writeback block
+ * @clk_ctrl:	        clock control identifier
+ */
+struct dpu_wb_cfg {
+	DPU_HW_BLK_INFO;
+	u8 vbif_idx;
+	u32 maxlinewidth;
+	u32 xin_id;
+	unsigned int intr_wb_done;
+	const u32 *format_list;
+	u32 num_formats;
+	enum dpu_clk_ctrl_type clk_ctrl;
+};
+
+/**
+ * struct dpu_vbif_dynamic_ot_cfg - dynamic OT setting
+ * @pps                pixel per seconds
+ * @ot_limit           OT limit to use up to specified pixel per second
+ */
+struct dpu_vbif_dynamic_ot_cfg {
+	u64 pps;
+	u32 ot_limit;
+};
+
+/**
+ * struct dpu_vbif_dynamic_ot_tbl - dynamic OT setting table
+ * @count              length of cfg
+ * @cfg                pointer to array of configuration settings with
+ *                     ascending requirements
+ */
+struct dpu_vbif_dynamic_ot_tbl {
+	u32 count;
+	const struct dpu_vbif_dynamic_ot_cfg *cfg;
+};
+
+/**
+ * struct dpu_vbif_qos_tbl - QoS priority table
+ * @npriority_lvl      num of priority level
+ * @priority_lvl       pointer to array of priority level in ascending order
+ */
+struct dpu_vbif_qos_tbl {
+	u32 npriority_lvl;
+	const u32 *priority_lvl;
+};
+
+/**
+ * struct dpu_vbif_cfg - information of VBIF blocks
+ * @id                 enum identifying this block
+ * @base               register offset of this block
+ * @features           bit mask identifying sub-blocks/features
+ * @ot_rd_limit        default OT read limit
+ * @ot_wr_limit        default OT write limit
+ * @xin_halt_timeout   maximum time (in usec) for xin to halt
+ * @qos_rp_remap_size  size of VBIF_XINL_QOS_RP_REMAP register space
+ * @dynamic_ot_rd_tbl  dynamic OT read configuration table
+ * @dynamic_ot_wr_tbl  dynamic OT write configuration table
+ * @qos_rt_tbl         real-time QoS priority table
+ * @qos_nrt_tbl        non-real-time QoS priority table
+ * @memtype_count      number of defined memtypes
+ * @memtype            array of xin memtype definitions
+ */
+struct dpu_vbif_cfg {
+	DPU_HW_BLK_INFO;
+	u32 default_ot_rd_limit;
+	u32 default_ot_wr_limit;
+	u32 xin_halt_timeout;
+	u32 qos_rp_remap_size;
+	struct dpu_vbif_dynamic_ot_tbl dynamic_ot_rd_tbl;
+	struct dpu_vbif_dynamic_ot_tbl dynamic_ot_wr_tbl;
+	struct dpu_vbif_qos_tbl qos_rt_tbl;
+	struct dpu_vbif_qos_tbl qos_nrt_tbl;
+	u32 memtype_count;
+	u32 memtype[MAX_XIN_COUNT];
+};
+
+/**
+ * struct dpu_cdm_cfg - information of chroma down blocks
+ * @name               string name for debug purposes
+ * @id                 enum identifying this block
+ * @base               register offset of this block
+ * @features           bit mask identifying sub-blocks/features
+ */
+struct dpu_cdm_cfg {
+	DPU_HW_BLK_INFO;
+};
+
+/**
+ * Define CDP use cases
+ * @DPU_PERF_CDP_UDAGE_RT: real-time use cases
+ * @DPU_PERF_CDP_USAGE_NRT: non real-time use cases such as WFD
+ */
+enum {
+	DPU_PERF_CDP_USAGE_RT,
+	DPU_PERF_CDP_USAGE_NRT,
+	DPU_PERF_CDP_USAGE_MAX
+};
+
+/**
+ * struct dpu_perf_cdp_cfg - define CDP use case configuration
+ * @rd_enable: true if read pipe CDP is enabled
+ * @wr_enable: true if write pipe CDP is enabled
+ */
+struct dpu_perf_cdp_cfg {
+	bool rd_enable;
+	bool wr_enable;
+};
+
+/**
+ * struct dpu_mdss_version - DPU's major and minor versions
+ * @core_major_ver: DPU core's major version
+ * @core_minor_ver: DPU core's minor version
+ */
+struct dpu_mdss_version {
+	u8 core_major_ver;
+	u8 core_minor_ver;
+};
+
+/**
+ * struct dpu_perf_cfg - performance control settings
+ * @max_bw_low         low threshold of maximum bandwidth (kbps)
+ * @max_bw_high        high threshold of maximum bandwidth (kbps)
+ * @min_core_ib        minimum bandwidth for core (kbps)
+ * @min_core_ib        minimum mnoc ib vote in kbps
+ * @min_llcc_ib        minimum llcc ib vote in kbps
+ * @min_dram_ib        minimum dram ib vote in kbps
+ * @undersized_prefill_lines   undersized prefill in lines
+ * @xtra_prefill_lines         extra prefill latency in lines
+ * @dest_scale_prefill_lines   destination scaler latency in lines
+ * @macrotile_perfill_lines    macrotile latency in lines
+ * @yuv_nv12_prefill_lines     yuv_nv12 latency in lines
+ * @linear_prefill_lines       linear latency in lines
+ * @downscaling_prefill_lines  downscaling latency in lines
+ * @amortizable_theshold minimum y position for traffic shaping prefill
+ * @min_prefill_lines  minimum pipeline latency in lines
+ * @clk_inefficiency_factor DPU src clock inefficiency factor
+ * @bw_inefficiency_factor DPU axi bus bw inefficiency factor
+ * @safe_lut_tbl: LUT tables for safe signals
+ * @danger_lut_tbl: LUT tables for danger signals
+ * @qos_lut_tbl: LUT tables for QoS signals
+ * @cdp_cfg            cdp use case configurations
+ */
+struct dpu_perf_cfg {
+	u32 max_bw_low;
+	u32 max_bw_high;
+	u32 min_core_ib;
+	u32 min_llcc_ib;
+	u32 min_dram_ib;
+	u32 undersized_prefill_lines;
+	u32 xtra_prefill_lines;
+	u32 dest_scale_prefill_lines;
+	u32 macrotile_prefill_lines;
+	u32 yuv_nv12_prefill_lines;
+	u32 linear_prefill_lines;
+	u32 downscaling_prefill_lines;
+	u32 amortizable_threshold;
+	u32 min_prefill_lines;
+	u32 clk_inefficiency_factor;
+	u32 bw_inefficiency_factor;
+	u32 safe_lut_tbl[DPU_QOS_LUT_USAGE_MAX];
+	u32 danger_lut_tbl[DPU_QOS_LUT_USAGE_MAX];
+	struct dpu_qos_lut_tbl qos_lut_tbl[DPU_QOS_LUT_USAGE_MAX];
+	struct dpu_perf_cdp_cfg cdp_cfg[DPU_PERF_CDP_USAGE_MAX];
+};
+
+/**
+ * struct dpu_mdss_cfg - information of MDSS HW
+ * This is the main catalog data structure representing
+ * this HW version. Contains dpu's major and minor versions,
+ * number of instances, register offsets, capabilities of the
+ * all MDSS HW sub-blocks.
+ *
+ * @dma_formats        Supported formats for dma pipe
+ * @cursor_formats     Supported formats for cursor pipe
+ * @vig_formats        Supported formats for vig pipe
+ */
+struct dpu_mdss_cfg {
+	const struct dpu_mdss_version *mdss_ver;
+
+	const struct dpu_caps *caps;
+
+	const struct dpu_mdp_cfg *mdp;
+
+	u32 ctl_count;
+	const struct dpu_ctl_cfg *ctl;
+
+	u32 sspp_count;
+	const struct dpu_sspp_cfg *sspp;
+
+	u32 mixer_count;
+	const struct dpu_lm_cfg *mixer;
+
+	u32 pingpong_count;
+	const struct dpu_pingpong_cfg *pingpong;
+
+	u32 merge_3d_count;
+	const struct dpu_merge_3d_cfg *merge_3d;
+
+	u32 dsc_count;
+	const struct dpu_dsc_cfg *dsc;
+
+	u32 intf_count;
+	const struct dpu_intf_cfg *intf;
+
+	u32 vbif_count;
+	const struct dpu_vbif_cfg *vbif;
+
+	u32 wb_count;
+	const struct dpu_wb_cfg *wb;
+
+	const struct dpu_cdm_cfg *cdm;
+
+	u32 ad_count;
+
+	u32 dspp_count;
+	const struct dpu_dspp_cfg *dspp;
+
+	/* Add additional block data structures here */
+
+	const struct dpu_perf_cfg *perf;
+	const struct dpu_format_extended *dma_formats;
+	const struct dpu_format_extended *cursor_formats;
+	const struct dpu_format_extended *vig_formats;
+};
+
+extern const struct dpu_mdss_cfg dpu_msm8998_cfg;
+extern const struct dpu_mdss_cfg dpu_sdm845_cfg;
+extern const struct dpu_mdss_cfg dpu_sdm670_cfg;
+extern const struct dpu_mdss_cfg dpu_sm8150_cfg;
+extern const struct dpu_mdss_cfg dpu_sc8180x_cfg;
+extern const struct dpu_mdss_cfg dpu_sm8250_cfg;
+extern const struct dpu_mdss_cfg dpu_sc7180_cfg;
+extern const struct dpu_mdss_cfg dpu_sm6115_cfg;
+extern const struct dpu_mdss_cfg dpu_sm6125_cfg;
+extern const struct dpu_mdss_cfg dpu_sm6350_cfg;
+extern const struct dpu_mdss_cfg dpu_qcm2290_cfg;
+extern const struct dpu_mdss_cfg dpu_sm6375_cfg;
+extern const struct dpu_mdss_cfg dpu_sm8350_cfg;
+extern const struct dpu_mdss_cfg dpu_sc7280_cfg;
+extern const struct dpu_mdss_cfg dpu_sc8280xp_cfg;
+extern const struct dpu_mdss_cfg dpu_sm8450_cfg;
+extern const struct dpu_mdss_cfg dpu_qcs8300_cfg;
+extern const struct dpu_mdss_cfg dpu_sa8775p_cfg;
+extern const struct dpu_mdss_cfg dpu_sm8550_cfg;
+extern const struct dpu_mdss_cfg dpu_sm8650_cfg;
+
+#endif /* _DPU_HW_CATALOG_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_cdm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_cdm.c
@@ -0,0 +1,247 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/bitfield.h>
+
+#include <drm/drm_managed.h>
+
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_util.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_cdm.h"
+#include "dpu_kms.h"
+
+#define CDM_CSC_10_OPMODE                  0x000
+#define CDM_CSC_10_BASE                    0x004
+
+#define CDM_CDWN2_OP_MODE                  0x100
+#define CDM_CDWN2_CLAMP_OUT                0x104
+#define CDM_CDWN2_PARAMS_3D_0              0x108
+#define CDM_CDWN2_PARAMS_3D_1              0x10C
+#define CDM_CDWN2_COEFF_COSITE_H_0         0x110
+#define CDM_CDWN2_COEFF_COSITE_H_1         0x114
+#define CDM_CDWN2_COEFF_COSITE_H_2         0x118
+#define CDM_CDWN2_COEFF_OFFSITE_H_0        0x11C
+#define CDM_CDWN2_COEFF_OFFSITE_H_1        0x120
+#define CDM_CDWN2_COEFF_OFFSITE_H_2        0x124
+#define CDM_CDWN2_COEFF_COSITE_V           0x128
+#define CDM_CDWN2_COEFF_OFFSITE_V          0x12C
+#define CDM_CDWN2_OUT_SIZE                 0x130
+
+#define CDM_HDMI_PACK_OP_MODE              0x200
+#define CDM_CSC_10_MATRIX_COEFF_0          0x004
+
+#define CDM_MUX                            0x224
+
+/* CDM CDWN2 sub-block bit definitions */
+#define CDM_CDWN2_OP_MODE_EN                  BIT(0)
+#define CDM_CDWN2_OP_MODE_ENABLE_H            BIT(1)
+#define CDM_CDWN2_OP_MODE_ENABLE_V            BIT(2)
+#define CDM_CDWN2_OP_MODE_BITS_OUT_8BIT       BIT(7)
+#define CDM_CDWN2_V_PIXEL_METHOD_MASK         GENMASK(6, 5)
+#define CDM_CDWN2_H_PIXEL_METHOD_MASK         GENMASK(4, 3)
+
+/* CDM CSC10 sub-block bit definitions */
+#define CDM_CSC10_OP_MODE_EN               BIT(0)
+#define CDM_CSC10_OP_MODE_SRC_FMT_YUV      BIT(1)
+#define CDM_CSC10_OP_MODE_DST_FMT_YUV      BIT(2)
+
+/* CDM HDMI pack sub-block bit definitions */
+#define CDM_HDMI_PACK_OP_MODE_EN           BIT(0)
+
+/*
+ * Horizontal coefficients for cosite chroma downscale
+ * s13 representation of coefficients
+ */
+static u32 cosite_h_coeff[] = {0x00000016, 0x000001cc, 0x0100009e};
+
+/*
+ * Horizontal coefficients for offsite chroma downscale
+ */
+static u32 offsite_h_coeff[] = {0x000b0005, 0x01db01eb, 0x00e40046};
+
+/*
+ * Vertical coefficients for cosite chroma downscale
+ */
+static u32 cosite_v_coeff[] = {0x00080004};
+/*
+ * Vertical coefficients for offsite chroma downscale
+ */
+static u32 offsite_v_coeff[] = {0x00060002};
+
+static int dpu_hw_cdm_setup_cdwn(struct dpu_hw_cdm *ctx, struct dpu_hw_cdm_cfg *cfg)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	u32 opmode;
+	u32 out_size;
+
+	switch (cfg->h_cdwn_type) {
+	case CDM_CDWN_DISABLE:
+		opmode = 0;
+		break;
+	case CDM_CDWN_PIXEL_DROP:
+		opmode = CDM_CDWN2_OP_MODE_ENABLE_H |
+				FIELD_PREP(CDM_CDWN2_H_PIXEL_METHOD_MASK,
+					   CDM_CDWN2_METHOD_PIXEL_DROP);
+		break;
+	case CDM_CDWN_AVG:
+		opmode = CDM_CDWN2_OP_MODE_ENABLE_H |
+				FIELD_PREP(CDM_CDWN2_H_PIXEL_METHOD_MASK,
+					   CDM_CDWN2_METHOD_AVG);
+		break;
+	case CDM_CDWN_COSITE:
+		opmode = CDM_CDWN2_OP_MODE_ENABLE_H |
+				FIELD_PREP(CDM_CDWN2_H_PIXEL_METHOD_MASK,
+					   CDM_CDWN2_METHOD_COSITE);
+		DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_0,
+			      cosite_h_coeff[0]);
+		DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_1,
+			      cosite_h_coeff[1]);
+		DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_2,
+			      cosite_h_coeff[2]);
+		break;
+	case CDM_CDWN_OFFSITE:
+		opmode = CDM_CDWN2_OP_MODE_ENABLE_H |
+				FIELD_PREP(CDM_CDWN2_H_PIXEL_METHOD_MASK, CDM_CDWN2_METHOD_OFFSITE);
+		DPU_REG_WRITE(c, CDM_CDWN2_COEFF_OFFSITE_H_0,
+			      offsite_h_coeff[0]);
+		DPU_REG_WRITE(c, CDM_CDWN2_COEFF_OFFSITE_H_1,
+			      offsite_h_coeff[1]);
+		DPU_REG_WRITE(c, CDM_CDWN2_COEFF_OFFSITE_H_2,
+			      offsite_h_coeff[2]);
+		break;
+	default:
+		DPU_ERROR("%s invalid horz down sampling type\n", __func__);
+		return -EINVAL;
+	}
+
+	switch (cfg->v_cdwn_type) {
+	case CDM_CDWN_DISABLE:
+		/* if its only Horizontal downsample, we dont need to do anything here */
+		break;
+	case CDM_CDWN_PIXEL_DROP:
+		opmode |= CDM_CDWN2_OP_MODE_ENABLE_V |
+				FIELD_PREP(CDM_CDWN2_V_PIXEL_METHOD_MASK,
+					   CDM_CDWN2_METHOD_PIXEL_DROP);
+		break;
+	case CDM_CDWN_AVG:
+		opmode |= CDM_CDWN2_OP_MODE_ENABLE_V |
+				FIELD_PREP(CDM_CDWN2_V_PIXEL_METHOD_MASK,
+					   CDM_CDWN2_METHOD_AVG);
+		break;
+	case CDM_CDWN_COSITE:
+		opmode |= CDM_CDWN2_OP_MODE_ENABLE_V |
+				FIELD_PREP(CDM_CDWN2_V_PIXEL_METHOD_MASK,
+					   CDM_CDWN2_METHOD_COSITE);
+		DPU_REG_WRITE(c,
+			      CDM_CDWN2_COEFF_COSITE_V,
+			      cosite_v_coeff[0]);
+		break;
+	case CDM_CDWN_OFFSITE:
+		opmode |= CDM_CDWN2_OP_MODE_ENABLE_V |
+				FIELD_PREP(CDM_CDWN2_V_PIXEL_METHOD_MASK,
+					   CDM_CDWN2_METHOD_OFFSITE);
+		DPU_REG_WRITE(c,
+			      CDM_CDWN2_COEFF_OFFSITE_V,
+			      offsite_v_coeff[0]);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (cfg->output_bit_depth != CDM_CDWN_OUTPUT_10BIT)
+		opmode |= CDM_CDWN2_OP_MODE_BITS_OUT_8BIT;
+
+	if (cfg->v_cdwn_type || cfg->h_cdwn_type)
+		opmode |= CDM_CDWN2_OP_MODE_EN; /* EN CDWN module */
+	else
+		opmode &= ~CDM_CDWN2_OP_MODE_EN;
+
+	out_size = (cfg->output_width & 0xFFFF) | ((cfg->output_height & 0xFFFF) << 16);
+	DPU_REG_WRITE(c, CDM_CDWN2_OUT_SIZE, out_size);
+	DPU_REG_WRITE(c, CDM_CDWN2_OP_MODE, opmode);
+	DPU_REG_WRITE(c, CDM_CDWN2_CLAMP_OUT, ((0x3FF << 16) | 0x0));
+
+	return 0;
+}
+
+static int dpu_hw_cdm_enable(struct dpu_hw_cdm *ctx, struct dpu_hw_cdm_cfg *cdm)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	const struct dpu_format *fmt;
+	u32 opmode = 0;
+	u32 csc = 0;
+
+	if (!ctx || !cdm)
+		return -EINVAL;
+
+	fmt = cdm->output_fmt;
+
+	if (!DPU_FORMAT_IS_YUV(fmt))
+		return -EINVAL;
+
+	dpu_hw_csc_setup(&ctx->hw, CDM_CSC_10_MATRIX_COEFF_0, cdm->csc_cfg, true);
+	dpu_hw_cdm_setup_cdwn(ctx, cdm);
+
+	if (cdm->output_type == CDM_CDWN_OUTPUT_HDMI) {
+		if (fmt->chroma_sample == DPU_CHROMA_H1V2)
+			return -EINVAL; /*unsupported format */
+		opmode = CDM_HDMI_PACK_OP_MODE_EN;
+		opmode |= (fmt->chroma_sample << 1);
+	}
+
+	csc |= CDM_CSC10_OP_MODE_DST_FMT_YUV;
+	csc &= ~CDM_CSC10_OP_MODE_SRC_FMT_YUV;
+	csc |= CDM_CSC10_OP_MODE_EN;
+
+	if (ctx && ctx->ops.bind_pingpong_blk)
+		ctx->ops.bind_pingpong_blk(ctx, cdm->pp_id);
+
+	DPU_REG_WRITE(c, CDM_CSC_10_OPMODE, csc);
+	DPU_REG_WRITE(c, CDM_HDMI_PACK_OP_MODE, opmode);
+	return 0;
+}
+
+static void dpu_hw_cdm_bind_pingpong_blk(struct dpu_hw_cdm *ctx, const enum dpu_pingpong pp)
+{
+	struct dpu_hw_blk_reg_map *c;
+	int mux_cfg;
+
+	c = &ctx->hw;
+
+	mux_cfg = DPU_REG_READ(c, CDM_MUX);
+	mux_cfg &= ~0xf;
+
+	if (pp)
+		mux_cfg |= (pp - PINGPONG_0) & 0x7;
+	else
+		mux_cfg |= 0xf;
+
+	DPU_REG_WRITE(c, CDM_MUX, mux_cfg);
+}
+
+struct dpu_hw_cdm *dpu_hw_cdm_init(struct drm_device *dev,
+				   const struct dpu_cdm_cfg *cfg, void __iomem *addr,
+				   const struct dpu_mdss_version *mdss_rev)
+{
+	struct dpu_hw_cdm *c;
+
+	c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
+	if (!c)
+		return ERR_PTR(-ENOMEM);
+
+	c->hw.blk_addr = addr + cfg->base;
+	c->hw.log_mask = DPU_DBG_MASK_CDM;
+
+	/* Assign ops */
+	c->idx = cfg->id;
+	c->caps = cfg;
+
+	c->ops.enable = dpu_hw_cdm_enable;
+	if (mdss_rev->core_major_ver >= 5)
+		c->ops.bind_pingpong_blk = dpu_hw_cdm_bind_pingpong_blk;
+
+	return c;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_cdm.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_cdm.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_CDM_H
+#define _DPU_HW_CDM_H
+
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_top.h"
+
+struct dpu_hw_cdm;
+
+/**
+ * struct dpu_hw_cdm_cfg : current configuration of CDM block
+ *
+ *  @output_width:         output ROI width of CDM block
+ *  @output_height:        output ROI height of CDM block
+ *  @output_bit_depth:     output bit-depth of CDM block
+ *  @h_cdwn_type:          downsample type used for horizontal pixels
+ *  @v_cdwn_type:          downsample type used for vertical pixels
+ *  @output_fmt:           handle to dpu_format of CDM block
+ *  @csc_cfg:              handle to CSC matrix programmed for CDM block
+ *  @output_type:          interface to which CDM is paired (HDMI/WB)
+ *  @pp_id:                ping-pong block to which CDM is bound to
+ */
+struct dpu_hw_cdm_cfg {
+	u32 output_width;
+	u32 output_height;
+	u32 output_bit_depth;
+	u32 h_cdwn_type;
+	u32 v_cdwn_type;
+	const struct dpu_format *output_fmt;
+	const struct dpu_csc_cfg *csc_cfg;
+	u32 output_type;
+	int pp_id;
+};
+
+/*
+ * These values are used indicate which type of downsample is used
+ * in the horizontal/vertical direction for the CDM block.
+ */
+enum dpu_hw_cdwn_type {
+	CDM_CDWN_DISABLE,
+	CDM_CDWN_PIXEL_DROP,
+	CDM_CDWN_AVG,
+	CDM_CDWN_COSITE,
+	CDM_CDWN_OFFSITE,
+};
+
+/*
+ * CDM block can be paired with WB or HDMI block. These values match
+ * the input with which the CDM block is paired.
+ */
+enum dpu_hw_cdwn_output_type {
+	CDM_CDWN_OUTPUT_HDMI,
+	CDM_CDWN_OUTPUT_WB,
+};
+
+/*
+ * CDM block can give an 8-bit or 10-bit output. These values
+ * are used to indicate the output bit depth of CDM block
+ */
+enum dpu_hw_cdwn_output_bit_depth {
+	CDM_CDWN_OUTPUT_8BIT,
+	CDM_CDWN_OUTPUT_10BIT,
+};
+
+/*
+ * CDM block can downsample using different methods. These values
+ * are used to indicate the downsample method which can be used
+ * either in the horizontal or vertical direction.
+ */
+enum dpu_hw_cdwn_op_mode_method_h_v {
+	CDM_CDWN2_METHOD_PIXEL_DROP,
+	CDM_CDWN2_METHOD_AVG,
+	CDM_CDWN2_METHOD_COSITE,
+	CDM_CDWN2_METHOD_OFFSITE
+};
+
+/**
+ * struct dpu_hw_cdm_ops : Interface to the chroma down Hw driver functions
+ *                         Assumption is these functions will be called after
+ *                         clocks are enabled
+ *  @enable:               Enables the output to interface and programs the
+ *                         output packer
+ *  @bind_pingpong_blk:    enable/disable the connection with pingpong which
+ *                         will feed pixels to this cdm
+ */
+struct dpu_hw_cdm_ops {
+	/**
+	 * Enable the CDM module
+	 * @cdm         Pointer to chroma down context
+	 */
+	int (*enable)(struct dpu_hw_cdm *cdm, struct dpu_hw_cdm_cfg *cfg);
+
+	/**
+	 * Enable/disable the connection with pingpong
+	 * @cdm         Pointer to chroma down context
+	 * @pp          pingpong block id.
+	 */
+	void (*bind_pingpong_blk)(struct dpu_hw_cdm *cdm, const enum dpu_pingpong pp);
+};
+
+/**
+ * struct dpu_hw_cdm - cdm description
+ * @base: Hardware block base structure
+ * @hw: Block hardware details
+ * @idx: CDM index
+ * @caps: Pointer to cdm_cfg
+ * @ops: handle to operations possible for this CDM
+ */
+struct dpu_hw_cdm {
+	struct dpu_hw_blk base;
+	struct dpu_hw_blk_reg_map hw;
+
+	/* chroma down */
+	const struct dpu_cdm_cfg *caps;
+	enum  dpu_cdm  idx;
+
+	/* ops */
+	struct dpu_hw_cdm_ops ops;
+};
+
+/**
+ * dpu_hw_cdm_init - initializes the cdm hw driver object.
+ * should be called once before accessing every cdm.
+ * @dev: DRM device handle
+ * @cdm: CDM catalog entry for which driver object is required
+ * @addr :   mapped register io address of MDSS
+ * @mdss_rev: mdss hw core revision
+ */
+struct dpu_hw_cdm *dpu_hw_cdm_init(struct drm_device *dev,
+				   const struct dpu_cdm_cfg *cdm, void __iomem *addr,
+				   const struct dpu_mdss_version *mdss_rev);
+
+static inline struct dpu_hw_cdm *to_dpu_hw_cdm(struct dpu_hw_blk *hw)
+{
+	return container_of(hw, struct dpu_hw_cdm, base);
+}
+
+#endif /*_DPU_HW_CDM_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_ctl.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_ctl.c
@@ -0,0 +1,761 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/delay.h>
+
+#include <drm/drm_managed.h>
+
+#include "dpu_hwio.h"
+#include "dpu_hw_ctl.h"
+#include "dpu_kms.h"
+#include "dpu_trace.h"
+
+#define   CTL_LAYER(lm)                 \
+	(((lm) == LM_5) ? (0x024) : (((lm) - LM_0) * 0x004))
+#define   CTL_LAYER_EXT(lm)             \
+	(0x40 + (((lm) - LM_0) * 0x004))
+#define   CTL_LAYER_EXT2(lm)             \
+	(0x70 + (((lm) - LM_0) * 0x004))
+#define   CTL_LAYER_EXT3(lm)             \
+	(0xA0 + (((lm) - LM_0) * 0x004))
+#define CTL_LAYER_EXT4(lm)             \
+	(0xB8 + (((lm) - LM_0) * 0x004))
+#define   CTL_TOP                       0x014
+#define   CTL_FLUSH                     0x018
+#define   CTL_START                     0x01C
+#define   CTL_PREPARE                   0x0d0
+#define   CTL_SW_RESET                  0x030
+#define   CTL_LAYER_EXTN_OFFSET         0x40
+#define   CTL_MERGE_3D_ACTIVE           0x0E4
+#define   CTL_DSC_ACTIVE                0x0E8
+#define   CTL_WB_ACTIVE                 0x0EC
+#define   CTL_INTF_ACTIVE               0x0F4
+#define   CTL_CDM_ACTIVE                0x0F8
+#define   CTL_FETCH_PIPE_ACTIVE         0x0FC
+#define   CTL_MERGE_3D_FLUSH            0x100
+#define   CTL_DSC_FLUSH                0x104
+#define   CTL_WB_FLUSH                  0x108
+#define   CTL_INTF_FLUSH                0x110
+#define   CTL_CDM_FLUSH                0x114
+#define   CTL_PERIPH_FLUSH              0x128
+#define   CTL_INTF_MASTER               0x134
+#define   CTL_DSPP_n_FLUSH(n)           ((0x13C) + ((n) * 4))
+
+#define CTL_MIXER_BORDER_OUT            BIT(24)
+#define CTL_FLUSH_MASK_CTL              BIT(17)
+
+#define DPU_REG_RESET_TIMEOUT_US        2000
+#define  MERGE_3D_IDX   23
+#define  DSC_IDX        22
+#define CDM_IDX         26
+#define  PERIPH_IDX     30
+#define  INTF_IDX       31
+#define WB_IDX          16
+#define  DSPP_IDX       29  /* From DPU hw rev 7.x.x */
+#define CTL_INVALID_BIT                 0xffff
+#define CTL_DEFAULT_GROUP_ID		0xf
+
+static const u32 fetch_tbl[SSPP_MAX] = {CTL_INVALID_BIT, 16, 17, 18, 19,
+	CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, 0,
+	1, 2, 3, 4, 5};
+
+static int _mixer_stages(const struct dpu_lm_cfg *mixer, int count,
+		enum dpu_lm lm)
+{
+	int i;
+	int stages = -EINVAL;
+
+	for (i = 0; i < count; i++) {
+		if (lm == mixer[i].id) {
+			stages = mixer[i].sblk->maxblendstages;
+			break;
+		}
+	}
+
+	return stages;
+}
+
+static inline u32 dpu_hw_ctl_get_flush_register(struct dpu_hw_ctl *ctx)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+
+	return DPU_REG_READ(c, CTL_FLUSH);
+}
+
+static inline void dpu_hw_ctl_trigger_start(struct dpu_hw_ctl *ctx)
+{
+	trace_dpu_hw_ctl_trigger_start(ctx->pending_flush_mask,
+				       dpu_hw_ctl_get_flush_register(ctx));
+	DPU_REG_WRITE(&ctx->hw, CTL_START, 0x1);
+}
+
+static inline bool dpu_hw_ctl_is_started(struct dpu_hw_ctl *ctx)
+{
+	return !!(DPU_REG_READ(&ctx->hw, CTL_START) & BIT(0));
+}
+
+static inline void dpu_hw_ctl_trigger_pending(struct dpu_hw_ctl *ctx)
+{
+	trace_dpu_hw_ctl_trigger_prepare(ctx->pending_flush_mask,
+					 dpu_hw_ctl_get_flush_register(ctx));
+	DPU_REG_WRITE(&ctx->hw, CTL_PREPARE, 0x1);
+}
+
+static inline void dpu_hw_ctl_clear_pending_flush(struct dpu_hw_ctl *ctx)
+{
+	trace_dpu_hw_ctl_clear_pending_flush(ctx->pending_flush_mask,
+				     dpu_hw_ctl_get_flush_register(ctx));
+	ctx->pending_flush_mask = 0x0;
+	ctx->pending_intf_flush_mask = 0;
+	ctx->pending_wb_flush_mask = 0;
+	ctx->pending_merge_3d_flush_mask = 0;
+	ctx->pending_dsc_flush_mask = 0;
+	ctx->pending_cdm_flush_mask = 0;
+
+	memset(ctx->pending_dspp_flush_mask, 0,
+		sizeof(ctx->pending_dspp_flush_mask));
+}
+
+static inline void dpu_hw_ctl_update_pending_flush(struct dpu_hw_ctl *ctx,
+		u32 flushbits)
+{
+	trace_dpu_hw_ctl_update_pending_flush(flushbits,
+					      ctx->pending_flush_mask);
+	ctx->pending_flush_mask |= flushbits;
+}
+
+static u32 dpu_hw_ctl_get_pending_flush(struct dpu_hw_ctl *ctx)
+{
+	return ctx->pending_flush_mask;
+}
+
+static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
+{
+	int dspp;
+
+	if (ctx->pending_flush_mask & BIT(MERGE_3D_IDX))
+		DPU_REG_WRITE(&ctx->hw, CTL_MERGE_3D_FLUSH,
+				ctx->pending_merge_3d_flush_mask);
+	if (ctx->pending_flush_mask & BIT(INTF_IDX))
+		DPU_REG_WRITE(&ctx->hw, CTL_INTF_FLUSH,
+				ctx->pending_intf_flush_mask);
+	if (ctx->pending_flush_mask & BIT(WB_IDX))
+		DPU_REG_WRITE(&ctx->hw, CTL_WB_FLUSH,
+				ctx->pending_wb_flush_mask);
+
+	if (ctx->pending_flush_mask & BIT(DSPP_IDX))
+		for (dspp = DSPP_0; dspp < DSPP_MAX; dspp++) {
+			if (ctx->pending_dspp_flush_mask[dspp - DSPP_0])
+				DPU_REG_WRITE(&ctx->hw,
+				CTL_DSPP_n_FLUSH(dspp - DSPP_0),
+				ctx->pending_dspp_flush_mask[dspp - DSPP_0]);
+		}
+
+	if (ctx->pending_flush_mask & BIT(PERIPH_IDX))
+		DPU_REG_WRITE(&ctx->hw, CTL_PERIPH_FLUSH,
+			      ctx->pending_periph_flush_mask);
+
+	if (ctx->pending_flush_mask & BIT(DSC_IDX))
+		DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH,
+			      ctx->pending_dsc_flush_mask);
+
+	if (ctx->pending_flush_mask & BIT(CDM_IDX))
+		DPU_REG_WRITE(&ctx->hw, CTL_CDM_FLUSH,
+			      ctx->pending_cdm_flush_mask);
+
+	DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
+}
+
+static inline void dpu_hw_ctl_trigger_flush(struct dpu_hw_ctl *ctx)
+{
+	trace_dpu_hw_ctl_trigger_pending_flush(ctx->pending_flush_mask,
+				     dpu_hw_ctl_get_flush_register(ctx));
+	DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
+}
+
+static void dpu_hw_ctl_update_pending_flush_sspp(struct dpu_hw_ctl *ctx,
+	enum dpu_sspp sspp)
+{
+	switch (sspp) {
+	case SSPP_VIG0:
+		ctx->pending_flush_mask |=  BIT(0);
+		break;
+	case SSPP_VIG1:
+		ctx->pending_flush_mask |= BIT(1);
+		break;
+	case SSPP_VIG2:
+		ctx->pending_flush_mask |= BIT(2);
+		break;
+	case SSPP_VIG3:
+		ctx->pending_flush_mask |= BIT(18);
+		break;
+	case SSPP_RGB0:
+		ctx->pending_flush_mask |= BIT(3);
+		break;
+	case SSPP_RGB1:
+		ctx->pending_flush_mask |= BIT(4);
+		break;
+	case SSPP_RGB2:
+		ctx->pending_flush_mask |= BIT(5);
+		break;
+	case SSPP_RGB3:
+		ctx->pending_flush_mask |= BIT(19);
+		break;
+	case SSPP_DMA0:
+		ctx->pending_flush_mask |= BIT(11);
+		break;
+	case SSPP_DMA1:
+		ctx->pending_flush_mask |= BIT(12);
+		break;
+	case SSPP_DMA2:
+		ctx->pending_flush_mask |= BIT(24);
+		break;
+	case SSPP_DMA3:
+		ctx->pending_flush_mask |= BIT(25);
+		break;
+	case SSPP_DMA4:
+		ctx->pending_flush_mask |= BIT(13);
+		break;
+	case SSPP_DMA5:
+		ctx->pending_flush_mask |= BIT(14);
+		break;
+	case SSPP_CURSOR0:
+		ctx->pending_flush_mask |= BIT(22);
+		break;
+	case SSPP_CURSOR1:
+		ctx->pending_flush_mask |= BIT(23);
+		break;
+	default:
+		break;
+	}
+}
+
+static void dpu_hw_ctl_update_pending_flush_mixer(struct dpu_hw_ctl *ctx,
+	enum dpu_lm lm)
+{
+	switch (lm) {
+	case LM_0:
+		ctx->pending_flush_mask |= BIT(6);
+		break;
+	case LM_1:
+		ctx->pending_flush_mask |= BIT(7);
+		break;
+	case LM_2:
+		ctx->pending_flush_mask |= BIT(8);
+		break;
+	case LM_3:
+		ctx->pending_flush_mask |= BIT(9);
+		break;
+	case LM_4:
+		ctx->pending_flush_mask |= BIT(10);
+		break;
+	case LM_5:
+		ctx->pending_flush_mask |= BIT(20);
+		break;
+	default:
+		break;
+	}
+
+	ctx->pending_flush_mask |= CTL_FLUSH_MASK_CTL;
+}
+
+static void dpu_hw_ctl_update_pending_flush_intf(struct dpu_hw_ctl *ctx,
+		enum dpu_intf intf)
+{
+	switch (intf) {
+	case INTF_0:
+		ctx->pending_flush_mask |= BIT(31);
+		break;
+	case INTF_1:
+		ctx->pending_flush_mask |= BIT(30);
+		break;
+	case INTF_2:
+		ctx->pending_flush_mask |= BIT(29);
+		break;
+	case INTF_3:
+		ctx->pending_flush_mask |= BIT(28);
+		break;
+	default:
+		break;
+	}
+}
+
+static void dpu_hw_ctl_update_pending_flush_wb(struct dpu_hw_ctl *ctx,
+		enum dpu_wb wb)
+{
+	switch (wb) {
+	case WB_0:
+	case WB_1:
+	case WB_2:
+		ctx->pending_flush_mask |= BIT(WB_IDX);
+		break;
+	default:
+		break;
+	}
+}
+
+static void dpu_hw_ctl_update_pending_flush_cdm(struct dpu_hw_ctl *ctx, enum dpu_cdm cdm_num)
+{
+	/* update pending flush only if CDM_0 is flushed */
+	if (cdm_num == CDM_0)
+		ctx->pending_flush_mask |= BIT(CDM_IDX);
+}
+
+static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx,
+		enum dpu_wb wb)
+{
+	ctx->pending_wb_flush_mask |= BIT(wb - WB_0);
+	ctx->pending_flush_mask |= BIT(WB_IDX);
+}
+
+static void dpu_hw_ctl_update_pending_flush_intf_v1(struct dpu_hw_ctl *ctx,
+		enum dpu_intf intf)
+{
+	ctx->pending_intf_flush_mask |= BIT(intf - INTF_0);
+	ctx->pending_flush_mask |= BIT(INTF_IDX);
+}
+
+static void dpu_hw_ctl_update_pending_flush_periph_v1(struct dpu_hw_ctl *ctx,
+						      enum dpu_intf intf)
+{
+	ctx->pending_periph_flush_mask |= BIT(intf - INTF_0);
+	ctx->pending_flush_mask |= BIT(PERIPH_IDX);
+}
+
+static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx,
+		enum dpu_merge_3d merge_3d)
+{
+	ctx->pending_merge_3d_flush_mask |= BIT(merge_3d - MERGE_3D_0);
+	ctx->pending_flush_mask |= BIT(MERGE_3D_IDX);
+}
+
+static void dpu_hw_ctl_update_pending_flush_dsc_v1(struct dpu_hw_ctl *ctx,
+						   enum dpu_dsc dsc_num)
+{
+	ctx->pending_dsc_flush_mask |= BIT(dsc_num - DSC_0);
+	ctx->pending_flush_mask |= BIT(DSC_IDX);
+}
+
+static void dpu_hw_ctl_update_pending_flush_cdm_v1(struct dpu_hw_ctl *ctx, enum dpu_cdm cdm_num)
+{
+	ctx->pending_cdm_flush_mask |= BIT(cdm_num - CDM_0);
+	ctx->pending_flush_mask |= BIT(CDM_IDX);
+}
+
+static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx,
+	enum dpu_dspp dspp, u32 dspp_sub_blk)
+{
+	switch (dspp) {
+	case DSPP_0:
+		ctx->pending_flush_mask |= BIT(13);
+		break;
+	case DSPP_1:
+		ctx->pending_flush_mask |= BIT(14);
+		break;
+	case DSPP_2:
+		ctx->pending_flush_mask |= BIT(15);
+		break;
+	case DSPP_3:
+		ctx->pending_flush_mask |= BIT(21);
+		break;
+	default:
+		break;
+	}
+}
+
+static void dpu_hw_ctl_update_pending_flush_dspp_sub_blocks(
+	struct dpu_hw_ctl *ctx,	enum dpu_dspp dspp, u32 dspp_sub_blk)
+{
+	if (dspp >= DSPP_MAX)
+		return;
+
+	switch (dspp_sub_blk) {
+	case DPU_DSPP_PCC:
+		ctx->pending_dspp_flush_mask[dspp - DSPP_0] |= BIT(4);
+		break;
+	default:
+		return;
+	}
+
+	ctx->pending_flush_mask |= BIT(DSPP_IDX);
+}
+
+static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	ktime_t timeout;
+	u32 status;
+
+	timeout = ktime_add_us(ktime_get(), timeout_us);
+
+	/*
+	 * it takes around 30us to have mdp finish resetting its ctl path
+	 * poll every 50us so that reset should be completed at 1st poll
+	 */
+	do {
+		status = DPU_REG_READ(c, CTL_SW_RESET);
+		status &= 0x1;
+		if (status)
+			usleep_range(20, 50);
+	} while (status && ktime_compare_safe(ktime_get(), timeout) < 0);
+
+	return status;
+}
+
+static int dpu_hw_ctl_reset_control(struct dpu_hw_ctl *ctx)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+
+	pr_debug("issuing hw ctl reset for ctl:%d\n", ctx->idx);
+	DPU_REG_WRITE(c, CTL_SW_RESET, 0x1);
+	if (dpu_hw_ctl_poll_reset_status(ctx, DPU_REG_RESET_TIMEOUT_US))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int dpu_hw_ctl_wait_reset_status(struct dpu_hw_ctl *ctx)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	u32 status;
+
+	status = DPU_REG_READ(c, CTL_SW_RESET);
+	status &= 0x01;
+	if (!status)
+		return 0;
+
+	pr_debug("hw ctl reset is set for ctl:%d\n", ctx->idx);
+	if (dpu_hw_ctl_poll_reset_status(ctx, DPU_REG_RESET_TIMEOUT_US)) {
+		pr_err("hw recovery is not complete for ctl:%d\n", ctx->idx);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void dpu_hw_ctl_clear_all_blendstages(struct dpu_hw_ctl *ctx)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	int i;
+
+	for (i = 0; i < ctx->mixer_count; i++) {
+		enum dpu_lm mixer_id = ctx->mixer_hw_caps[i].id;
+
+		DPU_REG_WRITE(c, CTL_LAYER(mixer_id), 0);
+		DPU_REG_WRITE(c, CTL_LAYER_EXT(mixer_id), 0);
+		DPU_REG_WRITE(c, CTL_LAYER_EXT2(mixer_id), 0);
+		DPU_REG_WRITE(c, CTL_LAYER_EXT3(mixer_id), 0);
+	}
+
+	DPU_REG_WRITE(c, CTL_FETCH_PIPE_ACTIVE, 0);
+}
+
+struct ctl_blend_config {
+	int idx, shift, ext_shift;
+};
+
+static const struct ctl_blend_config ctl_blend_config[][2] = {
+	[SSPP_NONE] = { { -1 }, { -1 } },
+	[SSPP_MAX] =  { { -1 }, { -1 } },
+	[SSPP_VIG0] = { { 0, 0,  0  }, { 3, 0 } },
+	[SSPP_VIG1] = { { 0, 3,  2  }, { 3, 4 } },
+	[SSPP_VIG2] = { { 0, 6,  4  }, { 3, 8 } },
+	[SSPP_VIG3] = { { 0, 26, 6  }, { 3, 12 } },
+	[SSPP_RGB0] = { { 0, 9,  8  }, { -1 } },
+	[SSPP_RGB1] = { { 0, 12, 10 }, { -1 } },
+	[SSPP_RGB2] = { { 0, 15, 12 }, { -1 } },
+	[SSPP_RGB3] = { { 0, 29, 14 }, { -1 } },
+	[SSPP_DMA0] = { { 0, 18, 16 }, { 2, 8 } },
+	[SSPP_DMA1] = { { 0, 21, 18 }, { 2, 12 } },
+	[SSPP_DMA2] = { { 2, 0      }, { 2, 16 } },
+	[SSPP_DMA3] = { { 2, 4      }, { 2, 20 } },
+	[SSPP_DMA4] = { { 4, 0      }, { 4, 8 } },
+	[SSPP_DMA5] = { { 4, 4      }, { 4, 12 } },
+	[SSPP_CURSOR0] =  { { 1, 20 }, { -1 } },
+	[SSPP_CURSOR1] =  { { 1, 26 }, { -1 } },
+};
+
+static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
+	enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	u32 mix, ext, mix_ext;
+	u32 mixercfg[5] = { 0 };
+	int i, j;
+	int stages;
+	int pipes_per_stage;
+
+	stages = _mixer_stages(ctx->mixer_hw_caps, ctx->mixer_count, lm);
+	if (stages < 0)
+		return;
+
+	if (test_bit(DPU_MIXER_SOURCESPLIT,
+		&ctx->mixer_hw_caps->features))
+		pipes_per_stage = PIPES_PER_STAGE;
+	else
+		pipes_per_stage = 1;
+
+	mixercfg[0] = CTL_MIXER_BORDER_OUT; /* always set BORDER_OUT */
+
+	if (!stage_cfg)
+		goto exit;
+
+	for (i = 0; i <= stages; i++) {
+		/* overflow to ext register if 'i + 1 > 7' */
+		mix = (i + 1) & 0x7;
+		ext = i >= 7;
+		mix_ext = (i + 1) & 0xf;
+
+		for (j = 0 ; j < pipes_per_stage; j++) {
+			enum dpu_sspp_multirect_index rect_index =
+				stage_cfg->multirect_index[i][j];
+			enum dpu_sspp pipe = stage_cfg->stage[i][j];
+			const struct ctl_blend_config *cfg =
+				&ctl_blend_config[pipe][rect_index == DPU_SSPP_RECT_1];
+
+			/*
+			 * CTL_LAYER has 3-bit field (and extra bits in EXT register),
+			 * all EXT registers has 4-bit fields.
+			 */
+			if (cfg->idx == -1) {
+				continue;
+			} else if (cfg->idx == 0) {
+				mixercfg[0] |= mix << cfg->shift;
+				mixercfg[1] |= ext << cfg->ext_shift;
+			} else {
+				mixercfg[cfg->idx] |= mix_ext << cfg->shift;
+			}
+		}
+	}
+
+exit:
+	DPU_REG_WRITE(c, CTL_LAYER(lm), mixercfg[0]);
+	DPU_REG_WRITE(c, CTL_LAYER_EXT(lm), mixercfg[1]);
+	DPU_REG_WRITE(c, CTL_LAYER_EXT2(lm), mixercfg[2]);
+	DPU_REG_WRITE(c, CTL_LAYER_EXT3(lm), mixercfg[3]);
+	if ((test_bit(DPU_CTL_HAS_LAYER_EXT4, &ctx->caps->features)))
+		DPU_REG_WRITE(c, CTL_LAYER_EXT4(lm), mixercfg[4]);
+}
+
+
+static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
+		struct dpu_hw_intf_cfg *cfg)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	u32 intf_active = 0;
+	u32 dsc_active = 0;
+	u32 wb_active = 0;
+	u32 mode_sel = 0;
+
+	/* CTL_TOP[31:28] carries group_id to collate CTL paths
+	 * per VM. Explicitly disable it until VM support is
+	 * added in SW. Power on reset value is not disable.
+	 */
+	if ((test_bit(DPU_CTL_VM_CFG, &ctx->caps->features)))
+		mode_sel = CTL_DEFAULT_GROUP_ID  << 28;
+
+	if (cfg->intf_mode_sel == DPU_CTL_MODE_SEL_CMD)
+		mode_sel |= BIT(17);
+
+	intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
+	wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);
+	dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE);
+
+	if (cfg->intf)
+		intf_active |= BIT(cfg->intf - INTF_0);
+
+	if (cfg->wb)
+		wb_active |= BIT(cfg->wb - WB_0);
+
+	if (cfg->dsc)
+		dsc_active |= cfg->dsc;
+
+	DPU_REG_WRITE(c, CTL_TOP, mode_sel);
+	DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
+	DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active);
+	DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active);
+
+	if (cfg->merge_3d)
+		DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE,
+			      BIT(cfg->merge_3d - MERGE_3D_0));
+
+	if (cfg->cdm)
+		DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cfg->cdm);
+}
+
+static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx,
+		struct dpu_hw_intf_cfg *cfg)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	u32 intf_cfg = 0;
+
+	intf_cfg |= (cfg->intf & 0xF) << 4;
+
+	if (cfg->mode_3d) {
+		intf_cfg |= BIT(19);
+		intf_cfg |= (cfg->mode_3d - 0x1) << 20;
+	}
+
+	if (cfg->wb)
+		intf_cfg |= (cfg->wb & 0x3) + 2;
+
+	switch (cfg->intf_mode_sel) {
+	case DPU_CTL_MODE_SEL_VID:
+		intf_cfg &= ~BIT(17);
+		intf_cfg &= ~(0x3 << 15);
+		break;
+	case DPU_CTL_MODE_SEL_CMD:
+		intf_cfg |= BIT(17);
+		intf_cfg |= ((cfg->stream_sel & 0x3) << 15);
+		break;
+	default:
+		pr_err("unknown interface type %d\n", cfg->intf_mode_sel);
+		return;
+	}
+
+	DPU_REG_WRITE(c, CTL_TOP, intf_cfg);
+}
+
+static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx,
+		struct dpu_hw_intf_cfg *cfg)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	u32 intf_active = 0;
+	u32 wb_active = 0;
+	u32 merge3d_active = 0;
+	u32 dsc_active;
+	u32 cdm_active;
+
+	/*
+	 * This API resets each portion of the CTL path namely,
+	 * clearing the sspps staged on the lm, merge_3d block,
+	 * interfaces , writeback etc to ensure clean teardown of the pipeline.
+	 * This will be used for writeback to begin with to have a
+	 * proper teardown of the writeback session but upon further
+	 * validation, this can be extended to all interfaces.
+	 */
+	if (cfg->merge_3d) {
+		merge3d_active = DPU_REG_READ(c, CTL_MERGE_3D_ACTIVE);
+		merge3d_active &= ~BIT(cfg->merge_3d - MERGE_3D_0);
+		DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE,
+				merge3d_active);
+	}
+
+	dpu_hw_ctl_clear_all_blendstages(ctx);
+
+	if (cfg->intf) {
+		intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE);
+		intf_active &= ~BIT(cfg->intf - INTF_0);
+		DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active);
+	}
+
+	if (cfg->wb) {
+		wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE);
+		wb_active &= ~BIT(cfg->wb - WB_0);
+		DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active);
+	}
+
+	if (cfg->dsc) {
+		dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE);
+		dsc_active &= ~cfg->dsc;
+		DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active);
+	}
+
+	if (cfg->cdm) {
+		cdm_active = DPU_REG_READ(c, CTL_CDM_ACTIVE);
+		cdm_active &= ~cfg->cdm;
+		DPU_REG_WRITE(c, CTL_CDM_ACTIVE, cdm_active);
+	}
+}
+
+static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx,
+	unsigned long *fetch_active)
+{
+	int i;
+	u32 val = 0;
+
+	if (fetch_active) {
+		for (i = 0; i < SSPP_MAX; i++) {
+			if (test_bit(i, fetch_active) &&
+				fetch_tbl[i] != CTL_INVALID_BIT)
+				val |= BIT(fetch_tbl[i]);
+		}
+	}
+
+	DPU_REG_WRITE(&ctx->hw, CTL_FETCH_PIPE_ACTIVE, val);
+}
+
+static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
+		unsigned long cap)
+{
+	if (cap & BIT(DPU_CTL_ACTIVE_CFG)) {
+		ops->trigger_flush = dpu_hw_ctl_trigger_flush_v1;
+		ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg_v1;
+		ops->reset_intf_cfg = dpu_hw_ctl_reset_intf_cfg_v1;
+		ops->update_pending_flush_intf =
+			dpu_hw_ctl_update_pending_flush_intf_v1;
+
+		ops->update_pending_flush_periph =
+			dpu_hw_ctl_update_pending_flush_periph_v1;
+
+		ops->update_pending_flush_merge_3d =
+			dpu_hw_ctl_update_pending_flush_merge_3d_v1;
+		ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1;
+		ops->update_pending_flush_dsc =
+			dpu_hw_ctl_update_pending_flush_dsc_v1;
+		ops->update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm_v1;
+	} else {
+		ops->trigger_flush = dpu_hw_ctl_trigger_flush;
+		ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg;
+		ops->update_pending_flush_intf =
+			dpu_hw_ctl_update_pending_flush_intf;
+		ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb;
+		ops->update_pending_flush_cdm = dpu_hw_ctl_update_pending_flush_cdm;
+	}
+	ops->clear_pending_flush = dpu_hw_ctl_clear_pending_flush;
+	ops->update_pending_flush = dpu_hw_ctl_update_pending_flush;
+	ops->get_pending_flush = dpu_hw_ctl_get_pending_flush;
+	ops->get_flush_register = dpu_hw_ctl_get_flush_register;
+	ops->trigger_start = dpu_hw_ctl_trigger_start;
+	ops->is_started = dpu_hw_ctl_is_started;
+	ops->trigger_pending = dpu_hw_ctl_trigger_pending;
+	ops->reset = dpu_hw_ctl_reset_control;
+	ops->wait_reset_status = dpu_hw_ctl_wait_reset_status;
+	ops->clear_all_blendstages = dpu_hw_ctl_clear_all_blendstages;
+	ops->setup_blendstage = dpu_hw_ctl_setup_blendstage;
+	ops->update_pending_flush_sspp = dpu_hw_ctl_update_pending_flush_sspp;
+	ops->update_pending_flush_mixer = dpu_hw_ctl_update_pending_flush_mixer;
+	if (cap & BIT(DPU_CTL_DSPP_SUB_BLOCK_FLUSH))
+		ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp_sub_blocks;
+	else
+		ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp;
+
+	if (cap & BIT(DPU_CTL_FETCH_ACTIVE))
+		ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active;
+};
+
+struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev,
+				   const struct dpu_ctl_cfg *cfg,
+				   void __iomem *addr,
+				   u32 mixer_count,
+				   const struct dpu_lm_cfg *mixer)
+{
+	struct dpu_hw_ctl *c;
+
+	c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
+	if (!c)
+		return ERR_PTR(-ENOMEM);
+
+	c->hw.blk_addr = addr + cfg->base;
+	c->hw.log_mask = DPU_DBG_MASK_CTL;
+
+	c->caps = cfg;
+	_setup_ctl_ops(&c->ops, c->caps->features);
+	c->idx = cfg->id;
+	c->mixer_count = mixer_count;
+	c->mixer_hw_caps = mixer;
+
+	return c;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_ctl.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_ctl.h
@@ -0,0 +1,312 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _DPU_HW_CTL_H
+#define _DPU_HW_CTL_H
+
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_util.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_sspp.h"
+
+/**
+ * dpu_ctl_mode_sel: Interface mode selection
+ * DPU_CTL_MODE_SEL_VID:    Video mode interface
+ * DPU_CTL_MODE_SEL_CMD:    Command mode interface
+ */
+enum dpu_ctl_mode_sel {
+	DPU_CTL_MODE_SEL_VID = 0,
+	DPU_CTL_MODE_SEL_CMD
+};
+
+struct dpu_hw_ctl;
+/**
+ * struct dpu_hw_stage_cfg - blending stage cfg
+ * @stage : SSPP_ID at each stage
+ * @multirect_index: index of the rectangle of SSPP.
+ */
+struct dpu_hw_stage_cfg {
+	enum dpu_sspp stage[DPU_STAGE_MAX][PIPES_PER_STAGE];
+	enum dpu_sspp_multirect_index multirect_index
+					[DPU_STAGE_MAX][PIPES_PER_STAGE];
+};
+
+/**
+ * struct dpu_hw_intf_cfg :Describes how the DPU writes data to output interface
+ * @intf :                 Interface id
+ * @mode_3d:               3d mux configuration
+ * @merge_3d:              3d merge block used
+ * @intf_mode_sel:         Interface mode, cmd / vid
+ * @cdm:                   CDM block used
+ * @stream_sel:            Stream selection for multi-stream interfaces
+ * @dsc:                   DSC BIT masks used
+ */
+struct dpu_hw_intf_cfg {
+	enum dpu_intf intf;
+	enum dpu_wb wb;
+	enum dpu_3d_blend_mode mode_3d;
+	enum dpu_merge_3d merge_3d;
+	enum dpu_ctl_mode_sel intf_mode_sel;
+	enum dpu_cdm cdm;
+	int stream_sel;
+	unsigned int dsc;
+};
+
+/**
+ * struct dpu_hw_ctl_ops - Interface to the wb Hw driver functions
+ * Assumption is these functions will be called after clocks are enabled
+ */
+struct dpu_hw_ctl_ops {
+	/**
+	 * kickoff hw operation for Sw controlled interfaces
+	 * DSI cmd mode and WB interface are SW controlled
+	 * @ctx       : ctl path ctx pointer
+	 */
+	void (*trigger_start)(struct dpu_hw_ctl *ctx);
+
+	/**
+	 * check if the ctl is started
+	 * @ctx       : ctl path ctx pointer
+	 * @Return: true if started, false if stopped
+	 */
+	bool (*is_started)(struct dpu_hw_ctl *ctx);
+
+	/**
+	 * kickoff prepare is in progress hw operation for sw
+	 * controlled interfaces: DSI cmd mode and WB interface
+	 * are SW controlled
+	 * @ctx       : ctl path ctx pointer
+	 */
+	void (*trigger_pending)(struct dpu_hw_ctl *ctx);
+
+	/**
+	 * Clear the value of the cached pending_flush_mask
+	 * No effect on hardware.
+	 * Required to be implemented.
+	 * @ctx       : ctl path ctx pointer
+	 */
+	void (*clear_pending_flush)(struct dpu_hw_ctl *ctx);
+
+	/**
+	 * Query the value of the cached pending_flush_mask
+	 * No effect on hardware
+	 * @ctx       : ctl path ctx pointer
+	 */
+	u32 (*get_pending_flush)(struct dpu_hw_ctl *ctx);
+
+	/**
+	 * OR in the given flushbits to the cached pending_flush_mask
+	 * No effect on hardware
+	 * @ctx       : ctl path ctx pointer
+	 * @flushbits : module flushmask
+	 */
+	void (*update_pending_flush)(struct dpu_hw_ctl *ctx,
+		u32 flushbits);
+
+	/**
+	 * OR in the given flushbits to the cached pending_(wb_)flush_mask
+	 * No effect on hardware
+	 * @ctx       : ctl path ctx pointer
+	 * @blk       : writeback block index
+	 */
+	void (*update_pending_flush_wb)(struct dpu_hw_ctl *ctx,
+		enum dpu_wb blk);
+
+	/**
+	 * OR in the given flushbits to the cached pending_(intf_)flush_mask
+	 * No effect on hardware
+	 * @ctx       : ctl path ctx pointer
+	 * @blk       : interface block index
+	 */
+	void (*update_pending_flush_intf)(struct dpu_hw_ctl *ctx,
+		enum dpu_intf blk);
+
+	/**
+	 * OR in the given flushbits to the cached pending_(periph_)flush_mask
+	 * No effect on hardware
+	 * @ctx       : ctl path ctx pointer
+	 * @blk       : interface block index
+	 */
+	void (*update_pending_flush_periph)(struct dpu_hw_ctl *ctx,
+					    enum dpu_intf blk);
+
+	/**
+	 * OR in the given flushbits to the cached pending_(merge_3d_)flush_mask
+	 * No effect on hardware
+	 * @ctx       : ctl path ctx pointer
+	 * @blk       : interface block index
+	 */
+	void (*update_pending_flush_merge_3d)(struct dpu_hw_ctl *ctx,
+		enum dpu_merge_3d blk);
+
+	/**
+	 * OR in the given flushbits to the cached pending_flush_mask
+	 * No effect on hardware
+	 * @ctx       : ctl path ctx pointer
+	 * @blk       : SSPP block index
+	 */
+	void (*update_pending_flush_sspp)(struct dpu_hw_ctl *ctx,
+		enum dpu_sspp blk);
+
+	/**
+	 * OR in the given flushbits to the cached pending_flush_mask
+	 * No effect on hardware
+	 * @ctx       : ctl path ctx pointer
+	 * @blk       : LM block index
+	 */
+	void (*update_pending_flush_mixer)(struct dpu_hw_ctl *ctx,
+		enum dpu_lm blk);
+
+	/**
+	 * OR in the given flushbits to the cached pending_flush_mask
+	 * No effect on hardware
+	 * @ctx       : ctl path ctx pointer
+	 * @blk       : DSPP block index
+	 * @dspp_sub_blk : DSPP sub-block index
+	 */
+	void (*update_pending_flush_dspp)(struct dpu_hw_ctl *ctx,
+		enum dpu_dspp blk, u32 dspp_sub_blk);
+
+	/**
+	 * OR in the given flushbits to the cached pending_(dsc_)flush_mask
+	 * No effect on hardware
+	 * @ctx: ctl path ctx pointer
+	 * @blk: interface block index
+	 */
+	void (*update_pending_flush_dsc)(struct dpu_hw_ctl *ctx,
+					 enum dpu_dsc blk);
+
+	/**
+	 * OR in the given flushbits to the cached pending_(cdm_)flush_mask
+	 * No effect on hardware
+	 * @ctx: ctl path ctx pointer
+	 * @cdm_num: idx of cdm to be flushed
+	 */
+	void (*update_pending_flush_cdm)(struct dpu_hw_ctl *ctx, enum dpu_cdm cdm_num);
+
+	/**
+	 * Write the value of the pending_flush_mask to hardware
+	 * @ctx       : ctl path ctx pointer
+	 */
+	void (*trigger_flush)(struct dpu_hw_ctl *ctx);
+
+	/**
+	 * Read the value of the flush register
+	 * @ctx       : ctl path ctx pointer
+	 * @Return: value of the ctl flush register.
+	 */
+	u32 (*get_flush_register)(struct dpu_hw_ctl *ctx);
+
+	/**
+	 * Setup ctl_path interface config
+	 * @ctx
+	 * @cfg    : interface config structure pointer
+	 */
+	void (*setup_intf_cfg)(struct dpu_hw_ctl *ctx,
+		struct dpu_hw_intf_cfg *cfg);
+
+	/**
+	 * reset ctl_path interface config
+	 * @ctx    : ctl path ctx pointer
+	 * @cfg    : interface config structure pointer
+	 */
+	void (*reset_intf_cfg)(struct dpu_hw_ctl *ctx,
+			struct dpu_hw_intf_cfg *cfg);
+
+	int (*reset)(struct dpu_hw_ctl *c);
+
+	/*
+	 * wait_reset_status - checks ctl reset status
+	 * @ctx       : ctl path ctx pointer
+	 *
+	 * This function checks the ctl reset status bit.
+	 * If the reset bit is set, it keeps polling the status till the hw
+	 * reset is complete.
+	 * Returns: 0 on success or -error if reset incomplete within interval
+	 */
+	int (*wait_reset_status)(struct dpu_hw_ctl *ctx);
+
+	/**
+	 * Set all blend stages to disabled
+	 * @ctx       : ctl path ctx pointer
+	 */
+	void (*clear_all_blendstages)(struct dpu_hw_ctl *ctx);
+
+	/**
+	 * Configure layer mixer to pipe configuration
+	 * @ctx       : ctl path ctx pointer
+	 * @lm        : layer mixer enumeration
+	 * @cfg       : blend stage configuration
+	 */
+	void (*setup_blendstage)(struct dpu_hw_ctl *ctx,
+		enum dpu_lm lm, struct dpu_hw_stage_cfg *cfg);
+
+	void (*set_active_pipes)(struct dpu_hw_ctl *ctx,
+		unsigned long *fetch_active);
+};
+
+/**
+ * struct dpu_hw_ctl : CTL PATH driver object
+ * @base: hardware block base structure
+ * @hw: block register map object
+ * @idx: control path index
+ * @caps: control path capabilities
+ * @mixer_count: number of mixers
+ * @mixer_hw_caps: mixer hardware capabilities
+ * @pending_flush_mask: storage for pending ctl_flush managed via ops
+ * @pending_intf_flush_mask: pending INTF flush
+ * @pending_wb_flush_mask: pending WB flush
+ * @pending_dsc_flush_mask: pending DSC flush
+ * @pending_cdm_flush_mask: pending CDM flush
+ * @ops: operation list
+ */
+struct dpu_hw_ctl {
+	struct dpu_hw_blk base;
+	struct dpu_hw_blk_reg_map hw;
+
+	/* ctl path */
+	int idx;
+	const struct dpu_ctl_cfg *caps;
+	int mixer_count;
+	const struct dpu_lm_cfg *mixer_hw_caps;
+	u32 pending_flush_mask;
+	u32 pending_intf_flush_mask;
+	u32 pending_wb_flush_mask;
+	u32 pending_periph_flush_mask;
+	u32 pending_merge_3d_flush_mask;
+	u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0];
+	u32 pending_dsc_flush_mask;
+	u32 pending_cdm_flush_mask;
+
+	/* ops */
+	struct dpu_hw_ctl_ops ops;
+};
+
+/**
+ * dpu_hw_ctl - convert base object dpu_hw_base to container
+ * @hw: Pointer to base hardware block
+ * return: Pointer to hardware block container
+ */
+static inline struct dpu_hw_ctl *to_dpu_hw_ctl(struct dpu_hw_blk *hw)
+{
+	return container_of(hw, struct dpu_hw_ctl, base);
+}
+
+/**
+ * dpu_hw_ctl_init() - Initializes the ctl_path hw driver object.
+ * Should be called before accessing any ctl_path register.
+ * @dev:  Corresponding device for devres management
+ * @cfg:  ctl_path catalog entry for which driver object is required
+ * @addr: mapped register io address of MDP
+ * @mixer_count: Number of mixers in @mixer
+ * @mixer: Pointer to an array of Layer Mixers defined in the catalog
+ */
+struct dpu_hw_ctl *dpu_hw_ctl_init(struct drm_device *dev,
+				   const struct dpu_ctl_cfg *cfg,
+				   void __iomem *addr,
+				   u32 mixer_count,
+				   const struct dpu_lm_cfg *mixer);
+
+#endif /*_DPU_HW_CTL_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_dsc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_dsc.c
@@ -0,0 +1,211 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020-2022, Linaro Limited
+ */
+
+#include <drm/drm_managed.h>
+
+#include <drm/display/drm_dsc_helper.h>
+
+#include "dpu_kms.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hwio.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_dsc.h"
+
+#define DSC_COMMON_MODE                 0x000
+#define DSC_ENC                         0x004
+#define DSC_PICTURE                     0x008
+#define DSC_SLICE                       0x00C
+#define DSC_CHUNK_SIZE                  0x010
+#define DSC_DELAY                       0x014
+#define DSC_SCALE_INITIAL               0x018
+#define DSC_SCALE_DEC_INTERVAL          0x01C
+#define DSC_SCALE_INC_INTERVAL          0x020
+#define DSC_FIRST_LINE_BPG_OFFSET       0x024
+#define DSC_BPG_OFFSET                  0x028
+#define DSC_DSC_OFFSET                  0x02C
+#define DSC_FLATNESS                    0x030
+#define DSC_RC_MODEL_SIZE               0x034
+#define DSC_RC                          0x038
+#define DSC_RC_BUF_THRESH               0x03C
+#define DSC_RANGE_MIN_QP                0x074
+#define DSC_RANGE_MAX_QP                0x0B0
+#define DSC_RANGE_BPG_OFFSET            0x0EC
+
+#define DSC_CTL(m) (0x1800 - 0x3FC * (m - DSC_0))
+
+static void dpu_hw_dsc_disable(struct dpu_hw_dsc *dsc)
+{
+	struct dpu_hw_blk_reg_map *c = &dsc->hw;
+
+	DPU_REG_WRITE(c, DSC_COMMON_MODE, 0);
+}
+
+static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc,
+			      struct drm_dsc_config *dsc,
+			      u32 mode,
+			      u32 initial_lines)
+{
+	struct dpu_hw_blk_reg_map *c = &hw_dsc->hw;
+	u32 data;
+	u32 slice_last_group_size;
+	u32 det_thresh_flatness;
+	bool is_cmd_mode = !(mode & DSC_MODE_VIDEO);
+
+	DPU_REG_WRITE(c, DSC_COMMON_MODE, mode);
+
+	if (is_cmd_mode)
+		initial_lines += 1;
+
+	slice_last_group_size = (dsc->slice_width + 2) % 3;
+
+	data = (initial_lines << 20);
+	data |= (slice_last_group_size << 18);
+	/* bpp is 6.4 format, 4 LSBs bits are for fractional part */
+	data |= (dsc->bits_per_pixel << 8);
+	data |= (dsc->block_pred_enable << 7);
+	data |= (dsc->line_buf_depth << 3);
+	data |= (dsc->simple_422 << 2);
+	data |= (dsc->convert_rgb << 1);
+	data |= dsc->bits_per_component;
+
+	DPU_REG_WRITE(c, DSC_ENC, data);
+
+	data = dsc->pic_width << 16;
+	data |= dsc->pic_height;
+	DPU_REG_WRITE(c, DSC_PICTURE, data);
+
+	data = dsc->slice_width << 16;
+	data |= dsc->slice_height;
+	DPU_REG_WRITE(c, DSC_SLICE, data);
+
+	data = dsc->slice_chunk_size << 16;
+	DPU_REG_WRITE(c, DSC_CHUNK_SIZE, data);
+
+	data = dsc->initial_dec_delay << 16;
+	data |= dsc->initial_xmit_delay;
+	DPU_REG_WRITE(c, DSC_DELAY, data);
+
+	data = dsc->initial_scale_value;
+	DPU_REG_WRITE(c, DSC_SCALE_INITIAL, data);
+
+	data = dsc->scale_decrement_interval;
+	DPU_REG_WRITE(c, DSC_SCALE_DEC_INTERVAL, data);
+
+	data = dsc->scale_increment_interval;
+	DPU_REG_WRITE(c, DSC_SCALE_INC_INTERVAL, data);
+
+	data = dsc->first_line_bpg_offset;
+	DPU_REG_WRITE(c, DSC_FIRST_LINE_BPG_OFFSET, data);
+
+	data = dsc->nfl_bpg_offset << 16;
+	data |= dsc->slice_bpg_offset;
+	DPU_REG_WRITE(c, DSC_BPG_OFFSET, data);
+
+	data = dsc->initial_offset << 16;
+	data |= dsc->final_offset;
+	DPU_REG_WRITE(c, DSC_DSC_OFFSET, data);
+
+	det_thresh_flatness = drm_dsc_flatness_det_thresh(dsc);
+	data = det_thresh_flatness << 10;
+	data |= dsc->flatness_max_qp << 5;
+	data |= dsc->flatness_min_qp;
+	DPU_REG_WRITE(c, DSC_FLATNESS, data);
+
+	data = dsc->rc_model_size;
+	DPU_REG_WRITE(c, DSC_RC_MODEL_SIZE, data);
+
+	data = dsc->rc_tgt_offset_low << 18;
+	data |= dsc->rc_tgt_offset_high << 14;
+	data |= dsc->rc_quant_incr_limit1 << 9;
+	data |= dsc->rc_quant_incr_limit0 << 4;
+	data |= dsc->rc_edge_factor;
+	DPU_REG_WRITE(c, DSC_RC, data);
+}
+
+static void dpu_hw_dsc_config_thresh(struct dpu_hw_dsc *hw_dsc,
+				     struct drm_dsc_config *dsc)
+{
+	struct drm_dsc_rc_range_parameters *rc = dsc->rc_range_params;
+	struct dpu_hw_blk_reg_map *c = &hw_dsc->hw;
+	u32 off;
+	int i;
+
+	off = DSC_RC_BUF_THRESH;
+	for (i = 0; i < DSC_NUM_BUF_RANGES - 1 ; i++) {
+		DPU_REG_WRITE(c, off, dsc->rc_buf_thresh[i]);
+		off += 4;
+	}
+
+	off = DSC_RANGE_MIN_QP;
+	for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
+		DPU_REG_WRITE(c, off, rc[i].range_min_qp);
+		off += 4;
+	}
+
+	off = DSC_RANGE_MAX_QP;
+	for (i = 0; i < 15; i++) {
+		DPU_REG_WRITE(c, off, rc[i].range_max_qp);
+		off += 4;
+	}
+
+	off = DSC_RANGE_BPG_OFFSET;
+	for (i = 0; i < 15; i++) {
+		DPU_REG_WRITE(c, off, rc[i].range_bpg_offset);
+		off += 4;
+	}
+}
+
+static void dpu_hw_dsc_bind_pingpong_blk(
+		struct dpu_hw_dsc *hw_dsc,
+		const enum dpu_pingpong pp)
+{
+	struct dpu_hw_blk_reg_map *c = &hw_dsc->hw;
+	int mux_cfg = 0xF;
+	u32 dsc_ctl_offset;
+
+	dsc_ctl_offset = DSC_CTL(hw_dsc->idx);
+
+	if (pp)
+		mux_cfg = (pp - PINGPONG_0) & 0x7;
+
+	if (pp)
+		DRM_DEBUG_KMS("Binding dsc:%d to pp:%d\n",
+			      hw_dsc->idx - DSC_0, pp - PINGPONG_0);
+	else
+		DRM_DEBUG_KMS("Unbinding dsc:%d from any pp\n",
+			      hw_dsc->idx - DSC_0);
+
+	DPU_REG_WRITE(c, dsc_ctl_offset, mux_cfg);
+}
+
+static void _setup_dsc_ops(struct dpu_hw_dsc_ops *ops,
+			   unsigned long cap)
+{
+	ops->dsc_disable = dpu_hw_dsc_disable;
+	ops->dsc_config = dpu_hw_dsc_config;
+	ops->dsc_config_thresh = dpu_hw_dsc_config_thresh;
+	if (cap & BIT(DPU_DSC_OUTPUT_CTRL))
+		ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk;
+};
+
+struct dpu_hw_dsc *dpu_hw_dsc_init(struct drm_device *dev,
+				   const struct dpu_dsc_cfg *cfg,
+				   void __iomem *addr)
+{
+	struct dpu_hw_dsc *c;
+
+	c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
+	if (!c)
+		return ERR_PTR(-ENOMEM);
+
+	c->hw.blk_addr = addr + cfg->base;
+	c->hw.log_mask = DPU_DBG_MASK_DSC;
+
+	c->idx = cfg->id;
+	c->caps = cfg;
+	_setup_dsc_ops(&c->ops, c->caps->features);
+
+	return c;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_dsc.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_dsc.h
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2022, Linaro Limited
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved
+ */
+
+#ifndef _DPU_HW_DSC_H
+#define _DPU_HW_DSC_H
+
+#include <drm/display/drm_dsc.h>
+
+#define DSC_MODE_SPLIT_PANEL            BIT(0)
+#define DSC_MODE_MULTIPLEX              BIT(1)
+#define DSC_MODE_VIDEO                  BIT(2)
+
+struct dpu_hw_dsc;
+
+/**
+ * struct dpu_hw_dsc_ops - interface to the dsc hardware driver functions
+ * Assumption is these functions will be called after clocks are enabled
+ */
+struct dpu_hw_dsc_ops {
+	/**
+	 * dsc_disable - disable dsc
+	 * @hw_dsc: Pointer to dsc context
+	 */
+	void (*dsc_disable)(struct dpu_hw_dsc *hw_dsc);
+
+	/**
+	 * dsc_config - configures dsc encoder
+	 * @hw_dsc: Pointer to dsc context
+	 * @dsc: panel dsc parameters
+	 * @mode: dsc topology mode to be set
+	 * @initial_lines: amount of initial lines to be used
+	 */
+	void (*dsc_config)(struct dpu_hw_dsc *hw_dsc,
+			   struct drm_dsc_config *dsc,
+			   u32 mode,
+			   u32 initial_lines);
+
+	/**
+	 * dsc_config_thresh - programs panel thresholds
+	 * @hw_dsc: Pointer to dsc context
+	 * @dsc: panel dsc parameters
+	 */
+	void (*dsc_config_thresh)(struct dpu_hw_dsc *hw_dsc,
+				  struct drm_dsc_config *dsc);
+
+	void (*dsc_bind_pingpong_blk)(struct dpu_hw_dsc *hw_dsc,
+				  enum dpu_pingpong pp);
+};
+
+struct dpu_hw_dsc {
+	struct dpu_hw_blk base;
+	struct dpu_hw_blk_reg_map hw;
+
+	/* dsc */
+	enum dpu_dsc idx;
+	const struct dpu_dsc_cfg *caps;
+
+	/* ops */
+	struct dpu_hw_dsc_ops ops;
+};
+
+/**
+ * dpu_hw_dsc_init() - Initializes the DSC hw driver object.
+ * @dev:  Corresponding device for devres management
+ * @cfg:  DSC catalog entry for which driver object is required
+ * @addr: Mapped register io address of MDP
+ * Return: Error code or allocated dpu_hw_dsc context
+ */
+struct dpu_hw_dsc *dpu_hw_dsc_init(struct drm_device *dev,
+				   const struct dpu_dsc_cfg *cfg,
+				   void __iomem *addr);
+
+/**
+ * dpu_hw_dsc_init_1_2() - initializes the v1.2 DSC hw driver object
+ * @dev:  Corresponding device for devres management
+ * @cfg:  DSC catalog entry for which driver object is required
+ * @addr: Mapped register io address of MDP
+ * Returns: Error code or allocated dpu_hw_dsc context
+ */
+struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(struct drm_device *dev,
+				       const struct dpu_dsc_cfg *cfg,
+				       void __iomem *addr);
+
+/**
+ * dpu_hw_dsc_destroy - destroys dsc driver context
+ * @dsc:   Pointer to dsc driver context returned by dpu_hw_dsc_init
+ */
+void dpu_hw_dsc_destroy(struct dpu_hw_dsc *dsc);
+
+static inline struct dpu_hw_dsc *to_dpu_hw_dsc(struct dpu_hw_blk *hw)
+{
+	return container_of(hw, struct dpu_hw_dsc, base);
+}
+
+#endif /* _DPU_HW_DSC_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_dsc_1_2.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_dsc_1_2.c
@@ -0,0 +1,390 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved
+ */
+
+#include <drm/drm_managed.h>
+
+#include <drm/display/drm_dsc_helper.h>
+
+#include "dpu_kms.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hwio.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_dsc.h"
+
+#define DSC_CMN_MAIN_CNF           0x00
+
+/* DPU_DSC_ENC register offsets */
+#define ENC_DF_CTRL                0x00
+#define ENC_GENERAL_STATUS         0x04
+#define ENC_HSLICE_STATUS          0x08
+#define ENC_OUT_STATUS             0x0C
+#define ENC_INT_STAT               0x10
+#define ENC_INT_CLR                0x14
+#define ENC_INT_MASK               0x18
+#define DSC_MAIN_CONF              0x30
+#define DSC_PICTURE_SIZE           0x34
+#define DSC_SLICE_SIZE             0x38
+#define DSC_MISC_SIZE              0x3C
+#define DSC_HRD_DELAYS             0x40
+#define DSC_RC_SCALE               0x44
+#define DSC_RC_SCALE_INC_DEC       0x48
+#define DSC_RC_OFFSETS_1           0x4C
+#define DSC_RC_OFFSETS_2           0x50
+#define DSC_RC_OFFSETS_3           0x54
+#define DSC_RC_OFFSETS_4           0x58
+#define DSC_FLATNESS_QP            0x5C
+#define DSC_RC_MODEL_SIZE          0x60
+#define DSC_RC_CONFIG              0x64
+#define DSC_RC_BUF_THRESH_0        0x68
+#define DSC_RC_BUF_THRESH_1        0x6C
+#define DSC_RC_BUF_THRESH_2        0x70
+#define DSC_RC_BUF_THRESH_3        0x74
+#define DSC_RC_MIN_QP_0            0x78
+#define DSC_RC_MIN_QP_1            0x7C
+#define DSC_RC_MIN_QP_2            0x80
+#define DSC_RC_MAX_QP_0            0x84
+#define DSC_RC_MAX_QP_1            0x88
+#define DSC_RC_MAX_QP_2            0x8C
+#define DSC_RC_RANGE_BPG_OFFSETS_0 0x90
+#define DSC_RC_RANGE_BPG_OFFSETS_1 0x94
+#define DSC_RC_RANGE_BPG_OFFSETS_2 0x98
+
+/* DPU_DSC_CTL register offsets */
+#define DSC_CTL                    0x00
+#define DSC_CFG                    0x04
+#define DSC_DATA_IN_SWAP           0x08
+#define DSC_CLK_CTRL               0x0C
+
+static int _dsc_calc_output_buf_max_addr(struct dpu_hw_dsc *hw_dsc, int num_softslice)
+{
+	int max_addr = 2400 / num_softslice;
+
+	if (hw_dsc->caps->features & BIT(DPU_DSC_NATIVE_42x_EN))
+		max_addr /= 2;
+
+	return max_addr - 1;
+};
+
+static void dpu_hw_dsc_disable_1_2(struct dpu_hw_dsc *hw_dsc)
+{
+	struct dpu_hw_blk_reg_map *hw;
+	const struct dpu_dsc_sub_blks *sblk;
+
+	if (!hw_dsc)
+		return;
+
+	hw = &hw_dsc->hw;
+	sblk = hw_dsc->caps->sblk;
+	DPU_REG_WRITE(hw, sblk->ctl.base + DSC_CFG, 0);
+
+	DPU_REG_WRITE(hw, sblk->enc.base + ENC_DF_CTRL, 0);
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_MAIN_CONF, 0);
+}
+
+static void dpu_hw_dsc_config_1_2(struct dpu_hw_dsc *hw_dsc,
+				  struct drm_dsc_config *dsc,
+				  u32 mode,
+				  u32 initial_lines)
+{
+	struct dpu_hw_blk_reg_map *hw;
+	const struct dpu_dsc_sub_blks *sblk;
+	u32 data = 0;
+	u32 det_thresh_flatness;
+	u32 num_active_slice_per_enc;
+	u32 bpp;
+
+	if (!hw_dsc || !dsc)
+		return;
+
+	hw = &hw_dsc->hw;
+
+	sblk = hw_dsc->caps->sblk;
+
+	if (mode & DSC_MODE_SPLIT_PANEL)
+		data |= BIT(0);
+
+	if (mode & DSC_MODE_MULTIPLEX)
+		data |= BIT(1);
+
+	num_active_slice_per_enc = dsc->slice_count;
+	if (mode & DSC_MODE_MULTIPLEX)
+		num_active_slice_per_enc = dsc->slice_count / 2;
+
+	data |= (num_active_slice_per_enc & 0x3) << 7;
+
+	DPU_REG_WRITE(hw, DSC_CMN_MAIN_CNF, data);
+
+	data = (initial_lines & 0xff);
+
+	if (mode & DSC_MODE_VIDEO)
+		data |= BIT(9);
+
+	data |= (_dsc_calc_output_buf_max_addr(hw_dsc, num_active_slice_per_enc) << 18);
+
+	DPU_REG_WRITE(hw, sblk->enc.base + ENC_DF_CTRL, data);
+
+	data = (dsc->dsc_version_minor & 0xf) << 28;
+	if (dsc->dsc_version_minor == 0x2) {
+		if (dsc->native_422)
+			data |= BIT(22);
+		if (dsc->native_420)
+			data |= BIT(21);
+	}
+
+	bpp = dsc->bits_per_pixel;
+	/* as per hw requirement bpp should be programmed
+	 * twice the actual value in case of 420 or 422 encoding
+	 */
+	if (dsc->native_422 || dsc->native_420)
+		bpp = 2 * bpp;
+
+	data |= bpp << 10;
+
+	if (dsc->block_pred_enable)
+		data |= BIT(20);
+
+	if (dsc->convert_rgb)
+		data |= BIT(4);
+
+	data |= (dsc->line_buf_depth & 0xf) << 6;
+	data |= dsc->bits_per_component & 0xf;
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_MAIN_CONF, data);
+
+	data = (dsc->pic_width & 0xffff) |
+		((dsc->pic_height & 0xffff) << 16);
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_PICTURE_SIZE, data);
+
+	data = (dsc->slice_width & 0xffff) |
+		((dsc->slice_height & 0xffff) << 16);
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_SLICE_SIZE, data);
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_MISC_SIZE,
+		      (dsc->slice_chunk_size) & 0xffff);
+
+	data = (dsc->initial_xmit_delay & 0xffff) |
+		((dsc->initial_dec_delay & 0xffff) << 16);
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_HRD_DELAYS, data);
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_SCALE,
+		      dsc->initial_scale_value & 0x3f);
+
+	data = (dsc->scale_increment_interval & 0xffff) |
+		((dsc->scale_decrement_interval & 0x7ff) << 16);
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_SCALE_INC_DEC, data);
+
+	data = (dsc->first_line_bpg_offset & 0x1f) |
+		((dsc->second_line_bpg_offset & 0x1f) << 5);
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_OFFSETS_1, data);
+
+	data = (dsc->nfl_bpg_offset & 0xffff) |
+		((dsc->slice_bpg_offset & 0xffff) << 16);
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_OFFSETS_2, data);
+
+	data = (dsc->initial_offset & 0xffff) |
+		((dsc->final_offset & 0xffff) << 16);
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_OFFSETS_3, data);
+
+	data = (dsc->nsl_bpg_offset & 0xffff) |
+		((dsc->second_line_offset_adj & 0xffff) << 16);
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_OFFSETS_4, data);
+
+	det_thresh_flatness = drm_dsc_flatness_det_thresh(dsc);
+	data = (dsc->flatness_min_qp & 0x1f) |
+		((dsc->flatness_max_qp & 0x1f) << 5) |
+		((det_thresh_flatness & 0xff) << 10);
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_FLATNESS_QP, data);
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MODEL_SIZE,
+		      (dsc->rc_model_size) & 0xffff);
+
+	data = dsc->rc_edge_factor & 0xf;
+	data |= (dsc->rc_quant_incr_limit0 & 0x1f) << 8;
+	data |= (dsc->rc_quant_incr_limit1 & 0x1f) << 13;
+	data |= (dsc->rc_tgt_offset_high & 0xf) << 20;
+	data |= (dsc->rc_tgt_offset_low & 0xf) << 24;
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_CONFIG, data);
+
+	/* program the dsc wrapper */
+	data = BIT(0); /* encoder enable */
+	if (dsc->native_422)
+		data |= BIT(8);
+	else if (dsc->native_420)
+		data |= BIT(9);
+	if (!dsc->convert_rgb)
+		data |= BIT(10);
+	if (dsc->bits_per_component == 8)
+		data |= BIT(11);
+	if (mode & DSC_MODE_SPLIT_PANEL)
+		data |= BIT(12);
+	if (mode & DSC_MODE_MULTIPLEX)
+		data |= BIT(13);
+	if (!(mode & DSC_MODE_VIDEO))
+		data |= BIT(17);
+
+	DPU_REG_WRITE(hw, sblk->ctl.base + DSC_CFG, data);
+}
+
+static void dpu_hw_dsc_config_thresh_1_2(struct dpu_hw_dsc *hw_dsc,
+					 struct drm_dsc_config *dsc)
+{
+	struct dpu_hw_blk_reg_map *hw;
+	const struct dpu_dsc_sub_blks *sblk;
+	struct drm_dsc_rc_range_parameters *rc;
+
+	if (!hw_dsc || !dsc)
+		return;
+
+	hw = &hw_dsc->hw;
+
+	sblk = hw_dsc->caps->sblk;
+
+	rc = dsc->rc_range_params;
+
+	/*
+	 * With BUF_THRESH -- 14 in total
+	 * each register contains 4 thresh values with the last register
+	 * containing only 2 thresh values
+	 */
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_BUF_THRESH_0,
+		      (dsc->rc_buf_thresh[0] << 0) |
+		      (dsc->rc_buf_thresh[1] << 8) |
+		      (dsc->rc_buf_thresh[2] << 16) |
+		      (dsc->rc_buf_thresh[3] << 24));
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_BUF_THRESH_1,
+		      (dsc->rc_buf_thresh[4] << 0) |
+		      (dsc->rc_buf_thresh[5] << 8) |
+		      (dsc->rc_buf_thresh[6] << 16) |
+		      (dsc->rc_buf_thresh[7] << 24));
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_BUF_THRESH_2,
+		      (dsc->rc_buf_thresh[8] << 0) |
+		      (dsc->rc_buf_thresh[9] << 8) |
+		      (dsc->rc_buf_thresh[10] << 16) |
+		      (dsc->rc_buf_thresh[11] << 24));
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_BUF_THRESH_3,
+		      (dsc->rc_buf_thresh[12] << 0) |
+		      (dsc->rc_buf_thresh[13] << 8));
+
+	/*
+	 * with min/max_QP -- 5 bits
+	 * each register contains 5 min_qp or max_qp for total of 15
+	 *
+	 * With BPG_OFFSET -- 6 bits
+	 * each register contains 5 BPG_offset for total of 15
+	 */
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MIN_QP_0,
+		      (rc[0].range_min_qp << 0) |
+		      (rc[1].range_min_qp << 5) |
+		      (rc[2].range_min_qp << 10) |
+		      (rc[3].range_min_qp << 15) |
+		      (rc[4].range_min_qp << 20));
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MAX_QP_0,
+		      (rc[0].range_max_qp << 0) |
+		      (rc[1].range_max_qp << 5) |
+		      (rc[2].range_max_qp << 10) |
+		      (rc[3].range_max_qp << 15) |
+		      (rc[4].range_max_qp << 20));
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_RANGE_BPG_OFFSETS_0,
+		      (rc[0].range_bpg_offset << 0) |
+		      (rc[1].range_bpg_offset << 6) |
+		      (rc[2].range_bpg_offset << 12) |
+		      (rc[3].range_bpg_offset << 18) |
+		      (rc[4].range_bpg_offset << 24));
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MIN_QP_1,
+		      (rc[5].range_min_qp << 0) |
+		      (rc[6].range_min_qp << 5) |
+		      (rc[7].range_min_qp << 10) |
+		      (rc[8].range_min_qp << 15) |
+		      (rc[9].range_min_qp << 20));
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MAX_QP_1,
+		      (rc[5].range_max_qp << 0) |
+		      (rc[6].range_max_qp << 5) |
+		      (rc[7].range_max_qp << 10) |
+		      (rc[8].range_max_qp << 15) |
+		      (rc[9].range_max_qp << 20));
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_RANGE_BPG_OFFSETS_1,
+		      (rc[5].range_bpg_offset << 0) |
+		      (rc[6].range_bpg_offset << 6) |
+		      (rc[7].range_bpg_offset << 12) |
+		      (rc[8].range_bpg_offset << 18) |
+		      (rc[9].range_bpg_offset << 24));
+
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MIN_QP_2,
+		      (rc[10].range_min_qp << 0) |
+		      (rc[11].range_min_qp << 5) |
+		      (rc[12].range_min_qp << 10) |
+		      (rc[13].range_min_qp << 15) |
+		      (rc[14].range_min_qp << 20));
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_MAX_QP_2,
+		      (rc[10].range_max_qp << 0) |
+		      (rc[11].range_max_qp << 5) |
+		      (rc[12].range_max_qp << 10) |
+		      (rc[13].range_max_qp << 15) |
+		      (rc[14].range_max_qp << 20));
+	DPU_REG_WRITE(hw, sblk->enc.base + DSC_RC_RANGE_BPG_OFFSETS_2,
+		      (rc[10].range_bpg_offset << 0) |
+		      (rc[11].range_bpg_offset << 6) |
+		      (rc[12].range_bpg_offset << 12) |
+		      (rc[13].range_bpg_offset << 18) |
+		      (rc[14].range_bpg_offset << 24));
+}
+
+static void dpu_hw_dsc_bind_pingpong_blk_1_2(struct dpu_hw_dsc *hw_dsc,
+					     const enum dpu_pingpong pp)
+{
+	struct dpu_hw_blk_reg_map *hw;
+	const struct dpu_dsc_sub_blks *sblk;
+	int mux_cfg = 0xf; /* Disabled */
+
+	hw = &hw_dsc->hw;
+
+	sblk = hw_dsc->caps->sblk;
+
+	if (pp)
+		mux_cfg = (pp - PINGPONG_0) & 0x7;
+
+	DPU_REG_WRITE(hw, sblk->ctl.base + DSC_CTL, mux_cfg);
+}
+
+static void _setup_dcs_ops_1_2(struct dpu_hw_dsc_ops *ops,
+			       const unsigned long features)
+{
+	ops->dsc_disable = dpu_hw_dsc_disable_1_2;
+	ops->dsc_config = dpu_hw_dsc_config_1_2;
+	ops->dsc_config_thresh = dpu_hw_dsc_config_thresh_1_2;
+	ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk_1_2;
+}
+
+struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(struct drm_device *dev,
+				       const struct dpu_dsc_cfg *cfg,
+				       void __iomem *addr)
+{
+	struct dpu_hw_dsc *c;
+
+	c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
+	if (!c)
+		return ERR_PTR(-ENOMEM);
+
+	c->hw.blk_addr = addr + cfg->base;
+	c->hw.log_mask = DPU_DBG_MASK_DSC;
+
+	c->idx = cfg->id;
+	c->caps = cfg;
+	_setup_dcs_ops_1_2(&c->ops, c->caps->features);
+
+	return c;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_dspp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_dspp.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <drm/drm_managed.h>
+
+#include "dpu_hwio.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_lm.h"
+#include "dpu_hw_dspp.h"
+#include "dpu_kms.h"
+
+
+/* DSPP_PCC */
+#define PCC_EN BIT(0)
+#define PCC_DIS 0
+#define PCC_RED_R_OFF 0x10
+#define PCC_RED_G_OFF 0x1C
+#define PCC_RED_B_OFF 0x28
+#define PCC_GREEN_R_OFF 0x14
+#define PCC_GREEN_G_OFF 0x20
+#define PCC_GREEN_B_OFF 0x2C
+#define PCC_BLUE_R_OFF 0x18
+#define PCC_BLUE_G_OFF 0x24
+#define PCC_BLUE_B_OFF 0x30
+
+static void dpu_setup_dspp_pcc(struct dpu_hw_dspp *ctx,
+		struct dpu_hw_pcc_cfg *cfg)
+{
+
+	u32 base;
+
+	if (!ctx) {
+		DRM_ERROR("invalid ctx %pK\n", ctx);
+		return;
+	}
+
+	base = ctx->cap->sblk->pcc.base;
+
+	if (!base) {
+		DRM_ERROR("invalid ctx %pK pcc base 0x%x\n", ctx, base);
+		return;
+	}
+
+	if (!cfg) {
+		DRM_DEBUG_DRIVER("disable pcc feature\n");
+		DPU_REG_WRITE(&ctx->hw, base, PCC_DIS);
+		return;
+	}
+
+	DPU_REG_WRITE(&ctx->hw, base + PCC_RED_R_OFF, cfg->r.r);
+	DPU_REG_WRITE(&ctx->hw, base + PCC_RED_G_OFF, cfg->r.g);
+	DPU_REG_WRITE(&ctx->hw, base + PCC_RED_B_OFF, cfg->r.b);
+
+	DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_R_OFF, cfg->g.r);
+	DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_G_OFF, cfg->g.g);
+	DPU_REG_WRITE(&ctx->hw, base + PCC_GREEN_B_OFF, cfg->g.b);
+
+	DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_R_OFF, cfg->b.r);
+	DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_G_OFF, cfg->b.g);
+	DPU_REG_WRITE(&ctx->hw, base + PCC_BLUE_B_OFF, cfg->b.b);
+
+	DPU_REG_WRITE(&ctx->hw, base, PCC_EN);
+}
+
+static void _setup_dspp_ops(struct dpu_hw_dspp *c,
+		unsigned long features)
+{
+	if (test_bit(DPU_DSPP_PCC, &features))
+		c->ops.setup_pcc = dpu_setup_dspp_pcc;
+}
+
+struct dpu_hw_dspp *dpu_hw_dspp_init(struct drm_device *dev,
+				     const struct dpu_dspp_cfg *cfg,
+				     void __iomem *addr)
+{
+	struct dpu_hw_dspp *c;
+
+	if (!addr)
+		return ERR_PTR(-EINVAL);
+
+	c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
+	if (!c)
+		return ERR_PTR(-ENOMEM);
+
+	c->hw.blk_addr = addr + cfg->base;
+	c->hw.log_mask = DPU_DBG_MASK_DSPP;
+
+	/* Assign ops */
+	c->idx = cfg->id;
+	c->cap = cfg;
+	_setup_dspp_ops(c, c->cap->features);
+
+	return c;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_dspp.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_dspp.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_DSPP_H
+#define _DPU_HW_DSPP_H
+
+struct dpu_hw_dspp;
+
+/**
+ * struct dpu_hw_pcc_coeff - PCC coefficient structure for each color
+ *                            component.
+ * @r: red coefficient.
+ * @g: green coefficient.
+ * @b: blue coefficient.
+ */
+
+struct dpu_hw_pcc_coeff {
+	__u32 r;
+	__u32 g;
+	__u32 b;
+};
+
+/**
+ * struct dpu_hw_pcc - pcc feature structure
+ * @r: red coefficients.
+ * @g: green coefficients.
+ * @b: blue coefficients.
+ */
+struct dpu_hw_pcc_cfg {
+	struct dpu_hw_pcc_coeff r;
+	struct dpu_hw_pcc_coeff g;
+	struct dpu_hw_pcc_coeff b;
+};
+
+/**
+ * struct dpu_hw_dspp_ops - interface to the dspp hardware driver functions
+ * Caller must call the init function to get the dspp context for each dspp
+ * Assumption is these functions will be called after clocks are enabled
+ */
+struct dpu_hw_dspp_ops {
+	/**
+	 * setup_pcc - setup dspp pcc
+	 * @ctx: Pointer to dspp context
+	 * @cfg: Pointer to configuration
+	 */
+	void (*setup_pcc)(struct dpu_hw_dspp *ctx, struct dpu_hw_pcc_cfg *cfg);
+
+};
+
+/**
+ * struct dpu_hw_dspp - dspp description
+ * @base: Hardware block base structure
+ * @hw: Block hardware details
+ * @idx: DSPP index
+ * @cap: Pointer to layer_cfg
+ * @ops: Pointer to operations possible for this DSPP
+ */
+struct dpu_hw_dspp {
+	struct dpu_hw_blk base;
+	struct dpu_hw_blk_reg_map hw;
+
+	/* dspp */
+	int idx;
+	const struct dpu_dspp_cfg *cap;
+
+	/* Ops */
+	struct dpu_hw_dspp_ops ops;
+};
+
+/**
+ * dpu_hw_dspp - convert base object dpu_hw_base to container
+ * @hw: Pointer to base hardware block
+ * return: Pointer to hardware block container
+ */
+static inline struct dpu_hw_dspp *to_dpu_hw_dspp(struct dpu_hw_blk *hw)
+{
+	return container_of(hw, struct dpu_hw_dspp, base);
+}
+
+/**
+ * dpu_hw_dspp_init() - Initializes the DSPP hw driver object.
+ * should be called once before accessing every DSPP.
+ * @dev:  Corresponding device for devres management
+ * @cfg:  DSPP catalog entry for which driver object is required
+ * @addr: Mapped register io address of MDP
+ * Return: pointer to structure or ERR_PTR
+ */
+struct dpu_hw_dspp *dpu_hw_dspp_init(struct drm_device *dev,
+				     const struct dpu_dspp_cfg *cfg,
+				     void __iomem *addr);
+
+#endif /*_DPU_HW_DSPP_H */
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_interrupts.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_interrupts.c
@@ -0,0 +1,676 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/bitops.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+
+#include <drm/drm_managed.h>
+
+#include "dpu_core_irq.h"
+#include "dpu_kms.h"
+#include "dpu_hw_interrupts.h"
+#include "dpu_hw_util.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_trace.h"
+
+/*
+ * Register offsets in MDSS register file for the interrupt registers
+ * w.r.t. the MDP base
+ */
+#define MDP_INTF_OFF(intf)				(0x6A000 + 0x800 * (intf))
+#define MDP_INTF_INTR_EN(intf)				(MDP_INTF_OFF(intf) + 0x1c0)
+#define MDP_INTF_INTR_STATUS(intf)			(MDP_INTF_OFF(intf) + 0x1c4)
+#define MDP_INTF_INTR_CLEAR(intf)			(MDP_INTF_OFF(intf) + 0x1c8)
+#define MDP_INTF_TEAR_OFF(intf)				(0x6D700 + 0x100 * (intf))
+#define MDP_INTF_INTR_TEAR_EN(intf)			(MDP_INTF_TEAR_OFF(intf) + 0x000)
+#define MDP_INTF_INTR_TEAR_STATUS(intf)			(MDP_INTF_TEAR_OFF(intf) + 0x004)
+#define MDP_INTF_INTR_TEAR_CLEAR(intf)			(MDP_INTF_TEAR_OFF(intf) + 0x008)
+#define MDP_AD4_OFF(ad4)				(0x7C000 + 0x1000 * (ad4))
+#define MDP_AD4_INTR_EN_OFF(ad4)			(MDP_AD4_OFF(ad4) + 0x41c)
+#define MDP_AD4_INTR_CLEAR_OFF(ad4)			(MDP_AD4_OFF(ad4) + 0x424)
+#define MDP_AD4_INTR_STATUS_OFF(ad4)			(MDP_AD4_OFF(ad4) + 0x420)
+#define MDP_INTF_REV_7xxx_OFF(intf)			(0x34000 + 0x1000 * (intf))
+#define MDP_INTF_REV_7xxx_INTR_EN(intf)			(MDP_INTF_REV_7xxx_OFF(intf) + 0x1c0)
+#define MDP_INTF_REV_7xxx_INTR_STATUS(intf)		(MDP_INTF_REV_7xxx_OFF(intf) + 0x1c4)
+#define MDP_INTF_REV_7xxx_INTR_CLEAR(intf)		(MDP_INTF_REV_7xxx_OFF(intf) + 0x1c8)
+#define MDP_INTF_REV_7xxx_TEAR_OFF(intf)		(0x34800 + 0x1000 * (intf))
+#define MDP_INTF_REV_7xxx_INTR_TEAR_EN(intf)		(MDP_INTF_REV_7xxx_TEAR_OFF(intf) + 0x000)
+#define MDP_INTF_REV_7xxx_INTR_TEAR_STATUS(intf)	(MDP_INTF_REV_7xxx_TEAR_OFF(intf) + 0x004)
+#define MDP_INTF_REV_7xxx_INTR_TEAR_CLEAR(intf)		(MDP_INTF_REV_7xxx_TEAR_OFF(intf) + 0x008)
+
+/**
+ * struct dpu_intr_reg - array of DPU register sets
+ * @clr_off:	offset to CLEAR reg
+ * @en_off:	offset to ENABLE reg
+ * @status_off:	offset to STATUS reg
+ */
+struct dpu_intr_reg {
+	u32 clr_off;
+	u32 en_off;
+	u32 status_off;
+};
+
+/*
+ * dpu_intr_set_legacy -  List of DPU interrupt registers for DPU <= 6.x
+ */
+static const struct dpu_intr_reg dpu_intr_set_legacy[] = {
+	[MDP_SSPP_TOP0_INTR] = {
+		INTR_CLEAR,
+		INTR_EN,
+		INTR_STATUS
+	},
+	[MDP_SSPP_TOP0_INTR2] = {
+		INTR2_CLEAR,
+		INTR2_EN,
+		INTR2_STATUS
+	},
+	[MDP_SSPP_TOP0_HIST_INTR] = {
+		HIST_INTR_CLEAR,
+		HIST_INTR_EN,
+		HIST_INTR_STATUS
+	},
+	[MDP_INTF0_INTR] = {
+		MDP_INTF_INTR_CLEAR(0),
+		MDP_INTF_INTR_EN(0),
+		MDP_INTF_INTR_STATUS(0)
+	},
+	[MDP_INTF1_INTR] = {
+		MDP_INTF_INTR_CLEAR(1),
+		MDP_INTF_INTR_EN(1),
+		MDP_INTF_INTR_STATUS(1)
+	},
+	[MDP_INTF2_INTR] = {
+		MDP_INTF_INTR_CLEAR(2),
+		MDP_INTF_INTR_EN(2),
+		MDP_INTF_INTR_STATUS(2)
+	},
+	[MDP_INTF3_INTR] = {
+		MDP_INTF_INTR_CLEAR(3),
+		MDP_INTF_INTR_EN(3),
+		MDP_INTF_INTR_STATUS(3)
+	},
+	[MDP_INTF4_INTR] = {
+		MDP_INTF_INTR_CLEAR(4),
+		MDP_INTF_INTR_EN(4),
+		MDP_INTF_INTR_STATUS(4)
+	},
+	[MDP_INTF5_INTR] = {
+		MDP_INTF_INTR_CLEAR(5),
+		MDP_INTF_INTR_EN(5),
+		MDP_INTF_INTR_STATUS(5)
+	},
+	[MDP_INTF1_TEAR_INTR] = {
+		MDP_INTF_INTR_TEAR_CLEAR(1),
+		MDP_INTF_INTR_TEAR_EN(1),
+		MDP_INTF_INTR_TEAR_STATUS(1)
+	},
+	[MDP_INTF2_TEAR_INTR] = {
+		MDP_INTF_INTR_TEAR_CLEAR(2),
+		MDP_INTF_INTR_TEAR_EN(2),
+		MDP_INTF_INTR_TEAR_STATUS(2)
+	},
+	[MDP_AD4_0_INTR] = {
+		MDP_AD4_INTR_CLEAR_OFF(0),
+		MDP_AD4_INTR_EN_OFF(0),
+		MDP_AD4_INTR_STATUS_OFF(0),
+	},
+	[MDP_AD4_1_INTR] = {
+		MDP_AD4_INTR_CLEAR_OFF(1),
+		MDP_AD4_INTR_EN_OFF(1),
+		MDP_AD4_INTR_STATUS_OFF(1),
+	},
+};
+
+/*
+ * dpu_intr_set_7xxx -  List of DPU interrupt registers for DPU >= 7.0
+ */
+static const struct dpu_intr_reg dpu_intr_set_7xxx[] = {
+	[MDP_SSPP_TOP0_INTR] = {
+		INTR_CLEAR,
+		INTR_EN,
+		INTR_STATUS
+	},
+	[MDP_SSPP_TOP0_INTR2] = {
+		INTR2_CLEAR,
+		INTR2_EN,
+		INTR2_STATUS
+	},
+	[MDP_SSPP_TOP0_HIST_INTR] = {
+		HIST_INTR_CLEAR,
+		HIST_INTR_EN,
+		HIST_INTR_STATUS
+	},
+	[MDP_INTF0_INTR] = {
+		MDP_INTF_REV_7xxx_INTR_CLEAR(0),
+		MDP_INTF_REV_7xxx_INTR_EN(0),
+		MDP_INTF_REV_7xxx_INTR_STATUS(0)
+	},
+	[MDP_INTF1_INTR] = {
+		MDP_INTF_REV_7xxx_INTR_CLEAR(1),
+		MDP_INTF_REV_7xxx_INTR_EN(1),
+		MDP_INTF_REV_7xxx_INTR_STATUS(1)
+	},
+	[MDP_INTF1_TEAR_INTR] = {
+		MDP_INTF_REV_7xxx_INTR_TEAR_CLEAR(1),
+		MDP_INTF_REV_7xxx_INTR_TEAR_EN(1),
+		MDP_INTF_REV_7xxx_INTR_TEAR_STATUS(1)
+	},
+	[MDP_INTF2_INTR] = {
+		MDP_INTF_REV_7xxx_INTR_CLEAR(2),
+		MDP_INTF_REV_7xxx_INTR_EN(2),
+		MDP_INTF_REV_7xxx_INTR_STATUS(2)
+	},
+	[MDP_INTF2_TEAR_INTR] = {
+		MDP_INTF_REV_7xxx_INTR_TEAR_CLEAR(2),
+		MDP_INTF_REV_7xxx_INTR_TEAR_EN(2),
+		MDP_INTF_REV_7xxx_INTR_TEAR_STATUS(2)
+	},
+	[MDP_INTF3_INTR] = {
+		MDP_INTF_REV_7xxx_INTR_CLEAR(3),
+		MDP_INTF_REV_7xxx_INTR_EN(3),
+		MDP_INTF_REV_7xxx_INTR_STATUS(3)
+	},
+	[MDP_INTF4_INTR] = {
+		MDP_INTF_REV_7xxx_INTR_CLEAR(4),
+		MDP_INTF_REV_7xxx_INTR_EN(4),
+		MDP_INTF_REV_7xxx_INTR_STATUS(4)
+	},
+	[MDP_INTF5_INTR] = {
+		MDP_INTF_REV_7xxx_INTR_CLEAR(5),
+		MDP_INTF_REV_7xxx_INTR_EN(5),
+		MDP_INTF_REV_7xxx_INTR_STATUS(5)
+	},
+	[MDP_INTF6_INTR] = {
+		MDP_INTF_REV_7xxx_INTR_CLEAR(6),
+		MDP_INTF_REV_7xxx_INTR_EN(6),
+		MDP_INTF_REV_7xxx_INTR_STATUS(6)
+	},
+	[MDP_INTF7_INTR] = {
+		MDP_INTF_REV_7xxx_INTR_CLEAR(7),
+		MDP_INTF_REV_7xxx_INTR_EN(7),
+		MDP_INTF_REV_7xxx_INTR_STATUS(7)
+	},
+	[MDP_INTF8_INTR] = {
+		MDP_INTF_REV_7xxx_INTR_CLEAR(8),
+		MDP_INTF_REV_7xxx_INTR_EN(8),
+		MDP_INTF_REV_7xxx_INTR_STATUS(8)
+	},
+};
+
+#define DPU_IRQ_MASK(irq_idx)	(BIT(DPU_IRQ_BIT(irq_idx)))
+
+static inline bool dpu_core_irq_is_valid(unsigned int irq_idx)
+{
+	return irq_idx && irq_idx <= DPU_NUM_IRQS;
+}
+
+static inline struct dpu_hw_intr_entry *dpu_core_irq_get_entry(struct dpu_hw_intr *intr,
+							       unsigned int irq_idx)
+{
+	return &intr->irq_tbl[irq_idx - 1];
+}
+
+/**
+ * dpu_core_irq_callback_handler - dispatch core interrupts
+ * @dpu_kms:		Pointer to DPU's KMS structure
+ * @irq_idx:		interrupt index
+ */
+static void dpu_core_irq_callback_handler(struct dpu_kms *dpu_kms, unsigned int irq_idx)
+{
+	struct dpu_hw_intr_entry *irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, irq_idx);
+
+	VERB("IRQ=[%d, %d]\n", DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+
+	if (!irq_entry->cb) {
+		DRM_ERROR("no registered cb, IRQ=[%d, %d]\n",
+			  DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+		return;
+	}
+
+	atomic_inc(&irq_entry->count);
+
+	/*
+	 * Perform registered function callback
+	 */
+	irq_entry->cb(irq_entry->arg);
+}
+
+irqreturn_t dpu_core_irq(struct msm_kms *kms)
+{
+	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
+	struct dpu_hw_intr *intr = dpu_kms->hw_intr;
+	int reg_idx;
+	unsigned int irq_idx;
+	u32 irq_status;
+	u32 enable_mask;
+	int bit;
+	unsigned long irq_flags;
+
+	if (!intr)
+		return IRQ_NONE;
+
+	spin_lock_irqsave(&intr->irq_lock, irq_flags);
+	for (reg_idx = 0; reg_idx < MDP_INTR_MAX; reg_idx++) {
+		if (!test_bit(reg_idx, &intr->irq_mask))
+			continue;
+
+		/* Read interrupt status */
+		irq_status = DPU_REG_READ(&intr->hw, intr->intr_set[reg_idx].status_off);
+
+		/* Read enable mask */
+		enable_mask = DPU_REG_READ(&intr->hw, intr->intr_set[reg_idx].en_off);
+
+		/* and clear the interrupt */
+		if (irq_status)
+			DPU_REG_WRITE(&intr->hw, intr->intr_set[reg_idx].clr_off,
+				     irq_status);
+
+		/* Finally update IRQ status based on enable mask */
+		irq_status &= enable_mask;
+
+		if (!irq_status)
+			continue;
+
+		/*
+		 * Search through matching intr status.
+		 */
+		while ((bit = ffs(irq_status)) != 0) {
+			irq_idx = DPU_IRQ_IDX(reg_idx, bit - 1);
+
+			dpu_core_irq_callback_handler(dpu_kms, irq_idx);
+
+			/*
+			 * When callback finish, clear the irq_status
+			 * with the matching mask. Once irq_status
+			 * is all cleared, the search can be stopped.
+			 */
+			irq_status &= ~BIT(bit - 1);
+		}
+	}
+
+	/* ensure register writes go through */
+	wmb();
+
+	spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
+
+	return IRQ_HANDLED;
+}
+
+static int dpu_hw_intr_enable_irq_locked(struct dpu_hw_intr *intr,
+					 unsigned int irq_idx)
+{
+	int reg_idx;
+	const struct dpu_intr_reg *reg;
+	const char *dbgstr = NULL;
+	uint32_t cache_irq_mask;
+
+	if (!intr)
+		return -EINVAL;
+
+	if (!dpu_core_irq_is_valid(irq_idx)) {
+		pr_err("invalid IRQ=[%d, %d]\n",
+		       DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+		return -EINVAL;
+	}
+
+	/*
+	 * The cache_irq_mask and hardware RMW operations needs to be done
+	 * under irq_lock and it's the caller's responsibility to ensure that's
+	 * held.
+	 */
+	assert_spin_locked(&intr->irq_lock);
+
+	reg_idx = DPU_IRQ_REG(irq_idx);
+	reg = &intr->intr_set[reg_idx];
+
+	/* Is this interrupt register supported on the platform */
+	if (WARN_ON(!reg->en_off))
+		return -EINVAL;
+
+	cache_irq_mask = intr->cache_irq_mask[reg_idx];
+	if (cache_irq_mask & DPU_IRQ_MASK(irq_idx)) {
+		dbgstr = "already ";
+	} else {
+		dbgstr = "";
+
+		cache_irq_mask |= DPU_IRQ_MASK(irq_idx);
+		/* Cleaning any pending interrupt */
+		DPU_REG_WRITE(&intr->hw, reg->clr_off, DPU_IRQ_MASK(irq_idx));
+		/* Enabling interrupts with the new mask */
+		DPU_REG_WRITE(&intr->hw, reg->en_off, cache_irq_mask);
+
+		/* ensure register write goes through */
+		wmb();
+
+		intr->cache_irq_mask[reg_idx] = cache_irq_mask;
+	}
+
+	pr_debug("DPU IRQ=[%d, %d] %senabled: MASK:0x%.8lx, CACHE-MASK:0x%.8x\n",
+		 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), dbgstr,
+			DPU_IRQ_MASK(irq_idx), cache_irq_mask);
+
+	return 0;
+}
+
+static int dpu_hw_intr_disable_irq_locked(struct dpu_hw_intr *intr,
+					  unsigned int irq_idx)
+{
+	int reg_idx;
+	const struct dpu_intr_reg *reg;
+	const char *dbgstr = NULL;
+	uint32_t cache_irq_mask;
+
+	if (!intr)
+		return -EINVAL;
+
+	if (!dpu_core_irq_is_valid(irq_idx)) {
+		pr_err("invalid IRQ=[%d, %d]\n",
+		       DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+		return -EINVAL;
+	}
+
+	/*
+	 * The cache_irq_mask and hardware RMW operations needs to be done
+	 * under irq_lock and it's the caller's responsibility to ensure that's
+	 * held.
+	 */
+	assert_spin_locked(&intr->irq_lock);
+
+	reg_idx = DPU_IRQ_REG(irq_idx);
+	reg = &intr->intr_set[reg_idx];
+
+	cache_irq_mask = intr->cache_irq_mask[reg_idx];
+	if ((cache_irq_mask & DPU_IRQ_MASK(irq_idx)) == 0) {
+		dbgstr = "already ";
+	} else {
+		dbgstr = "";
+
+		cache_irq_mask &= ~DPU_IRQ_MASK(irq_idx);
+		/* Disable interrupts based on the new mask */
+		DPU_REG_WRITE(&intr->hw, reg->en_off, cache_irq_mask);
+		/* Cleaning any pending interrupt */
+		DPU_REG_WRITE(&intr->hw, reg->clr_off, DPU_IRQ_MASK(irq_idx));
+
+		/* ensure register write goes through */
+		wmb();
+
+		intr->cache_irq_mask[reg_idx] = cache_irq_mask;
+	}
+
+	pr_debug("DPU IRQ=[%d, %d] %sdisabled: MASK:0x%.8lx, CACHE-MASK:0x%.8x\n",
+		 DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), dbgstr,
+			DPU_IRQ_MASK(irq_idx), cache_irq_mask);
+
+	return 0;
+}
+
+static void dpu_clear_irqs(struct dpu_kms *dpu_kms)
+{
+	struct dpu_hw_intr *intr = dpu_kms->hw_intr;
+	int i;
+
+	if (!intr)
+		return;
+
+	for (i = 0; i < MDP_INTR_MAX; i++) {
+		if (test_bit(i, &intr->irq_mask))
+			DPU_REG_WRITE(&intr->hw,
+					intr->intr_set[i].clr_off, 0xffffffff);
+	}
+
+	/* ensure register writes go through */
+	wmb();
+}
+
+static void dpu_disable_all_irqs(struct dpu_kms *dpu_kms)
+{
+	struct dpu_hw_intr *intr = dpu_kms->hw_intr;
+	int i;
+
+	if (!intr)
+		return;
+
+	for (i = 0; i < MDP_INTR_MAX; i++) {
+		if (test_bit(i, &intr->irq_mask))
+			DPU_REG_WRITE(&intr->hw,
+					intr->intr_set[i].en_off, 0x00000000);
+	}
+
+	/* ensure register writes go through */
+	wmb();
+}
+
+u32 dpu_core_irq_read(struct dpu_kms *dpu_kms,
+		      unsigned int irq_idx)
+{
+	struct dpu_hw_intr *intr = dpu_kms->hw_intr;
+	int reg_idx;
+	unsigned long irq_flags;
+	u32 intr_status;
+
+	if (!intr)
+		return 0;
+
+	if (!dpu_core_irq_is_valid(irq_idx)) {
+		pr_err("invalid IRQ=[%d, %d]\n", DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+		return 0;
+	}
+
+	spin_lock_irqsave(&intr->irq_lock, irq_flags);
+
+	reg_idx = DPU_IRQ_REG(irq_idx);
+	intr_status = DPU_REG_READ(&intr->hw,
+			intr->intr_set[reg_idx].status_off) &
+		DPU_IRQ_MASK(irq_idx);
+	if (intr_status)
+		DPU_REG_WRITE(&intr->hw, intr->intr_set[reg_idx].clr_off,
+				intr_status);
+
+	/* ensure register writes go through */
+	wmb();
+
+	spin_unlock_irqrestore(&intr->irq_lock, irq_flags);
+
+	return intr_status;
+}
+
+struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev,
+				     void __iomem *addr,
+				     const struct dpu_mdss_cfg *m)
+{
+	struct dpu_hw_intr *intr;
+	unsigned int i;
+
+	if (!addr || !m)
+		return ERR_PTR(-EINVAL);
+
+	intr = drmm_kzalloc(dev, sizeof(*intr), GFP_KERNEL);
+	if (!intr)
+		return ERR_PTR(-ENOMEM);
+
+	if (m->mdss_ver->core_major_ver >= 7)
+		intr->intr_set = dpu_intr_set_7xxx;
+	else
+		intr->intr_set = dpu_intr_set_legacy;
+
+	intr->hw.blk_addr = addr + m->mdp[0].base;
+
+	intr->irq_mask = BIT(MDP_SSPP_TOP0_INTR) |
+			 BIT(MDP_SSPP_TOP0_INTR2) |
+			 BIT(MDP_SSPP_TOP0_HIST_INTR);
+	for (i = 0; i < m->intf_count; i++) {
+		const struct dpu_intf_cfg *intf = &m->intf[i];
+
+		if (intf->type == INTF_NONE)
+			continue;
+
+		intr->irq_mask |= BIT(MDP_INTFn_INTR(intf->id));
+
+		if (intf->intr_tear_rd_ptr)
+			intr->irq_mask |= BIT(DPU_IRQ_REG(intf->intr_tear_rd_ptr));
+	}
+
+	spin_lock_init(&intr->irq_lock);
+
+	return intr;
+}
+
+int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms,
+				   unsigned int irq_idx,
+				   void (*irq_cb)(void *arg),
+				   void *irq_arg)
+{
+	struct dpu_hw_intr_entry *irq_entry;
+	unsigned long irq_flags;
+	int ret;
+
+	if (!irq_cb) {
+		DPU_ERROR("IRQ=[%d, %d] NULL callback\n",
+			  DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+		return -EINVAL;
+	}
+
+	if (!dpu_core_irq_is_valid(irq_idx)) {
+		DPU_ERROR("invalid IRQ=[%d, %d] irq_cb:%ps\n",
+			  DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), irq_cb);
+		return -EINVAL;
+	}
+
+	VERB("[%pS] IRQ=[%d, %d]\n", __builtin_return_address(0),
+	     DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+
+	spin_lock_irqsave(&dpu_kms->hw_intr->irq_lock, irq_flags);
+
+	irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, irq_idx);
+	if (unlikely(WARN_ON(irq_entry->cb))) {
+		spin_unlock_irqrestore(&dpu_kms->hw_intr->irq_lock, irq_flags);
+
+		return -EBUSY;
+	}
+
+	trace_dpu_core_irq_register_callback(DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), irq_cb);
+	irq_entry->arg = irq_arg;
+	irq_entry->cb = irq_cb;
+
+	ret = dpu_hw_intr_enable_irq_locked(
+				dpu_kms->hw_intr,
+				irq_idx);
+	if (ret)
+		DPU_ERROR("Failed/ to enable IRQ=[%d, %d]\n",
+			  DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+	spin_unlock_irqrestore(&dpu_kms->hw_intr->irq_lock, irq_flags);
+
+	trace_dpu_irq_register_success(DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+
+	return 0;
+}
+
+int dpu_core_irq_unregister_callback(struct dpu_kms *dpu_kms,
+				     unsigned int irq_idx)
+{
+	struct dpu_hw_intr_entry *irq_entry;
+	unsigned long irq_flags;
+	int ret;
+
+	if (!dpu_core_irq_is_valid(irq_idx)) {
+		DPU_ERROR("invalid IRQ=[%d, %d]\n",
+			  DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+		return -EINVAL;
+	}
+
+	VERB("[%pS] IRQ=[%d, %d]\n", __builtin_return_address(0),
+	     DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+
+	spin_lock_irqsave(&dpu_kms->hw_intr->irq_lock, irq_flags);
+	trace_dpu_core_irq_unregister_callback(DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+
+	ret = dpu_hw_intr_disable_irq_locked(dpu_kms->hw_intr, irq_idx);
+	if (ret)
+		DPU_ERROR("Failed to disable IRQ=[%d, %d]: %d\n",
+			  DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx), ret);
+
+	irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, irq_idx);
+	irq_entry->cb = NULL;
+	irq_entry->arg = NULL;
+
+	spin_unlock_irqrestore(&dpu_kms->hw_intr->irq_lock, irq_flags);
+
+	trace_dpu_irq_unregister_success(DPU_IRQ_REG(irq_idx), DPU_IRQ_BIT(irq_idx));
+
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int dpu_debugfs_core_irq_show(struct seq_file *s, void *v)
+{
+	struct dpu_kms *dpu_kms = s->private;
+	struct dpu_hw_intr_entry *irq_entry;
+	unsigned long irq_flags;
+	int i, irq_count;
+	void *cb;
+
+	for (i = 1; i <= DPU_NUM_IRQS; i++) {
+		spin_lock_irqsave(&dpu_kms->hw_intr->irq_lock, irq_flags);
+		irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, i);
+		irq_count = atomic_read(&irq_entry->count);
+		cb = irq_entry->cb;
+		spin_unlock_irqrestore(&dpu_kms->hw_intr->irq_lock, irq_flags);
+
+		if (irq_count || cb)
+			seq_printf(s, "IRQ=[%d, %d] count:%d cb:%ps\n",
+				   DPU_IRQ_REG(i), DPU_IRQ_BIT(i), irq_count, cb);
+	}
+
+	return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(dpu_debugfs_core_irq);
+
+void dpu_debugfs_core_irq_init(struct dpu_kms *dpu_kms,
+		struct dentry *parent)
+{
+	debugfs_create_file("core_irq", 0600, parent, dpu_kms,
+		&dpu_debugfs_core_irq_fops);
+}
+#endif
+
+void dpu_core_irq_preinstall(struct msm_kms *kms)
+{
+	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
+	struct dpu_hw_intr_entry *irq_entry;
+	int i;
+
+	pm_runtime_get_sync(&dpu_kms->pdev->dev);
+	dpu_clear_irqs(dpu_kms);
+	dpu_disable_all_irqs(dpu_kms);
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
+
+	for (i = 1; i <= DPU_NUM_IRQS; i++) {
+		irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, i);
+		atomic_set(&irq_entry->count, 0);
+	}
+}
+
+void dpu_core_irq_uninstall(struct msm_kms *kms)
+{
+	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
+	struct dpu_hw_intr_entry *irq_entry;
+	int i;
+
+	if (!dpu_kms->hw_intr)
+		return;
+
+	pm_runtime_get_sync(&dpu_kms->pdev->dev);
+	for (i = 1; i <= DPU_NUM_IRQS; i++) {
+		irq_entry = dpu_core_irq_get_entry(dpu_kms->hw_intr, i);
+		if (irq_entry->cb)
+			DPU_ERROR("IRQ=[%d, %d] still enabled/registered\n",
+				  DPU_IRQ_REG(i), DPU_IRQ_BIT(i));
+	}
+
+	dpu_clear_irqs(dpu_kms);
+	dpu_disable_all_irqs(dpu_kms);
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_interrupts.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_interrupts.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_INTERRUPTS_H
+#define _DPU_HW_INTERRUPTS_H
+
+#include <linux/types.h>
+
+#include "dpu_hwio.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_util.h"
+#include "dpu_hw_mdss.h"
+
+/* When making changes be sure to sync with dpu_intr_set */
+enum dpu_hw_intr_reg {
+	MDP_SSPP_TOP0_INTR,
+	MDP_SSPP_TOP0_INTR2,
+	MDP_SSPP_TOP0_HIST_INTR,
+	/* All MDP_INTFn_INTR should come sequentially */
+	MDP_INTF0_INTR,
+	MDP_INTF1_INTR,
+	MDP_INTF2_INTR,
+	MDP_INTF3_INTR,
+	MDP_INTF4_INTR,
+	MDP_INTF5_INTR,
+	MDP_INTF6_INTR,
+	MDP_INTF7_INTR,
+	MDP_INTF8_INTR,
+	MDP_INTF1_TEAR_INTR,
+	MDP_INTF2_TEAR_INTR,
+	MDP_AD4_0_INTR,
+	MDP_AD4_1_INTR,
+	MDP_INTR_MAX,
+};
+
+#define MDP_INTFn_INTR(intf)	(MDP_INTF0_INTR + (intf - INTF_0))
+
+#define DPU_IRQ_IDX(reg_idx, offset)	(1 + reg_idx * 32 + offset)
+#define DPU_IRQ_REG(irq_idx)	((irq_idx - 1) / 32)
+#define DPU_IRQ_BIT(irq_idx)	((irq_idx - 1) % 32)
+
+#define DPU_NUM_IRQS		(MDP_INTR_MAX * 32)
+
+struct dpu_hw_intr_entry {
+	void (*cb)(void *arg);
+	void *arg;
+	atomic_t count;
+};
+
+/**
+ * struct dpu_hw_intr: hw interrupts handling data structure
+ * @hw:               virtual address mapping
+ * @ops:              function pointer mapping for IRQ handling
+ * @cache_irq_mask:   array of IRQ enable masks reg storage created during init
+ * @save_irq_status:  array of IRQ status reg storage created during init
+ * @irq_lock:         spinlock for accessing IRQ resources
+ * @irq_cb_tbl:       array of IRQ callbacks
+ */
+struct dpu_hw_intr {
+	struct dpu_hw_blk_reg_map hw;
+	u32 cache_irq_mask[MDP_INTR_MAX];
+	u32 *save_irq_status;
+	spinlock_t irq_lock;
+	unsigned long irq_mask;
+	const struct dpu_intr_reg *intr_set;
+
+	struct dpu_hw_intr_entry irq_tbl[DPU_NUM_IRQS];
+};
+
+/**
+ * dpu_hw_intr_init(): Initializes the interrupts hw object
+ * @dev:  Corresponding device for devres management
+ * @addr: mapped register io address of MDP
+ * @m:    pointer to MDSS catalog data
+ */
+struct dpu_hw_intr *dpu_hw_intr_init(struct drm_device *dev,
+				     void __iomem *addr,
+				     const struct dpu_mdss_cfg *m);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_intf.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_intf.c
@@ -0,0 +1,590 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#include "dpu_hwio.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_intf.h"
+#include "dpu_kms.h"
+#include "dpu_trace.h"
+
+#include <linux/iopoll.h>
+
+#include <drm/drm_managed.h>
+
+#define INTF_TIMING_ENGINE_EN           0x000
+#define INTF_CONFIG                     0x004
+#define INTF_HSYNC_CTL                  0x008
+#define INTF_VSYNC_PERIOD_F0            0x00C
+#define INTF_VSYNC_PERIOD_F1            0x010
+#define INTF_VSYNC_PULSE_WIDTH_F0       0x014
+#define INTF_VSYNC_PULSE_WIDTH_F1       0x018
+#define INTF_DISPLAY_V_START_F0         0x01C
+#define INTF_DISPLAY_V_START_F1         0x020
+#define INTF_DISPLAY_V_END_F0           0x024
+#define INTF_DISPLAY_V_END_F1           0x028
+#define INTF_ACTIVE_V_START_F0          0x02C
+#define INTF_ACTIVE_V_START_F1          0x030
+#define INTF_ACTIVE_V_END_F0            0x034
+#define INTF_ACTIVE_V_END_F1            0x038
+#define INTF_DISPLAY_HCTL               0x03C
+#define INTF_ACTIVE_HCTL                0x040
+#define INTF_BORDER_COLOR               0x044
+#define INTF_UNDERFLOW_COLOR            0x048
+#define INTF_HSYNC_SKEW                 0x04C
+#define INTF_POLARITY_CTL               0x050
+#define INTF_TEST_CTL                   0x054
+#define INTF_TP_COLOR0                  0x058
+#define INTF_TP_COLOR1                  0x05C
+#define INTF_CONFIG2                    0x060
+#define INTF_DISPLAY_DATA_HCTL          0x064
+#define INTF_ACTIVE_DATA_HCTL           0x068
+
+#define INTF_DSI_CMD_MODE_TRIGGER_EN    0x084
+#define INTF_PANEL_FORMAT               0x090
+
+#define INTF_FRAME_LINE_COUNT_EN        0x0A8
+#define INTF_FRAME_COUNT                0x0AC
+#define INTF_LINE_COUNT                 0x0B0
+
+#define INTF_DEFLICKER_CONFIG           0x0F0
+#define INTF_DEFLICKER_STRNG_COEFF      0x0F4
+#define INTF_DEFLICKER_WEAK_COEFF       0x0F8
+
+#define INTF_TPG_ENABLE                 0x100
+#define INTF_TPG_MAIN_CONTROL           0x104
+#define INTF_TPG_VIDEO_CONFIG           0x108
+#define INTF_TPG_COMPONENT_LIMITS       0x10C
+#define INTF_TPG_RECTANGLE              0x110
+#define INTF_TPG_INITIAL_VALUE          0x114
+#define INTF_TPG_BLK_WHITE_PATTERN_FRAMES 0x118
+#define INTF_TPG_RGB_MAPPING            0x11C
+#define INTF_PROG_FETCH_START           0x170
+#define INTF_PROG_ROT_START             0x174
+
+#define INTF_MISR_CTRL                  0x180
+#define INTF_MISR_SIGNATURE             0x184
+
+#define INTF_MUX                        0x25C
+#define INTF_STATUS                     0x26C
+#define INTF_AVR_CONTROL                0x270
+#define INTF_AVR_MODE                   0x274
+#define INTF_AVR_TRIGGER                0x278
+#define INTF_AVR_VTOTAL                 0x27C
+#define INTF_TEAR_MDP_VSYNC_SEL         0x280
+#define INTF_TEAR_TEAR_CHECK_EN         0x284
+#define INTF_TEAR_SYNC_CONFIG_VSYNC     0x288
+#define INTF_TEAR_SYNC_CONFIG_HEIGHT    0x28C
+#define INTF_TEAR_SYNC_WRCOUNT          0x290
+#define INTF_TEAR_VSYNC_INIT_VAL        0x294
+#define INTF_TEAR_INT_COUNT_VAL         0x298
+#define INTF_TEAR_SYNC_THRESH           0x29C
+#define INTF_TEAR_START_POS             0x2A0
+#define INTF_TEAR_RD_PTR_IRQ            0x2A4
+#define INTF_TEAR_WR_PTR_IRQ            0x2A8
+#define INTF_TEAR_OUT_LINE_COUNT        0x2AC
+#define INTF_TEAR_LINE_COUNT            0x2B0
+#define INTF_TEAR_AUTOREFRESH_CONFIG    0x2B4
+
+#define INTF_CFG_ACTIVE_H_EN	BIT(29)
+#define INTF_CFG_ACTIVE_V_EN	BIT(30)
+
+#define INTF_CFG2_DATABUS_WIDEN	BIT(0)
+#define INTF_CFG2_DATA_HCTL_EN	BIT(4)
+#define INTF_CFG2_DCE_DATA_COMPRESS     BIT(12)
+
+
+static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *ctx,
+		const struct dpu_hw_intf_timing_params *p,
+		const struct dpu_format *fmt)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	u32 hsync_period, vsync_period;
+	u32 display_v_start, display_v_end;
+	u32 hsync_start_x, hsync_end_x;
+	u32 hsync_data_start_x, hsync_data_end_x;
+	u32 active_h_start, active_h_end;
+	u32 active_v_start, active_v_end;
+	u32 active_hctl, display_hctl, hsync_ctl;
+	u32 polarity_ctl, den_polarity;
+	u32 panel_format;
+	u32 intf_cfg, intf_cfg2 = 0;
+	u32 display_data_hctl = 0, active_data_hctl = 0;
+	u32 data_width;
+	bool dp_intf = false;
+
+	/* read interface_cfg */
+	intf_cfg = DPU_REG_READ(c, INTF_CONFIG);
+
+	if (ctx->cap->type == INTF_DP)
+		dp_intf = true;
+
+	hsync_period = p->hsync_pulse_width + p->h_back_porch + p->width +
+	p->h_front_porch;
+	vsync_period = p->vsync_pulse_width + p->v_back_porch + p->height +
+	p->v_front_porch;
+
+	display_v_start = ((p->vsync_pulse_width + p->v_back_porch) *
+	hsync_period) + p->hsync_skew;
+	display_v_end = ((vsync_period - p->v_front_porch) * hsync_period) +
+	p->hsync_skew - 1;
+
+	hsync_start_x = p->h_back_porch + p->hsync_pulse_width;
+	hsync_end_x = hsync_period - p->h_front_porch - 1;
+
+	if (p->width != p->xres) { /* border fill added */
+		active_h_start = hsync_start_x;
+		active_h_end = active_h_start + p->xres - 1;
+	} else {
+		active_h_start = 0;
+		active_h_end = 0;
+	}
+
+	if (p->height != p->yres) { /* border fill added */
+		active_v_start = display_v_start;
+		active_v_end = active_v_start + (p->yres * hsync_period) - 1;
+	} else {
+		active_v_start = 0;
+		active_v_end = 0;
+	}
+
+	if (active_h_end) {
+		active_hctl = (active_h_end << 16) | active_h_start;
+		intf_cfg |= INTF_CFG_ACTIVE_H_EN;
+	} else {
+		active_hctl = 0;
+	}
+
+	if (active_v_end)
+		intf_cfg |= INTF_CFG_ACTIVE_V_EN;
+
+	hsync_ctl = (hsync_period << 16) | p->hsync_pulse_width;
+	display_hctl = (hsync_end_x << 16) | hsync_start_x;
+
+	if (p->wide_bus_en)
+		intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN;
+
+	data_width = p->width;
+
+	hsync_data_start_x = hsync_start_x;
+	hsync_data_end_x =  hsync_start_x + data_width - 1;
+
+	display_data_hctl = (hsync_data_end_x << 16) | hsync_data_start_x;
+
+	if (dp_intf) {
+		/* DP timing adjustment */
+		display_v_start += p->hsync_pulse_width + p->h_back_porch;
+		display_v_end   -= p->h_front_porch;
+
+		active_h_start = hsync_start_x;
+		active_h_end = active_h_start + p->xres - 1;
+		active_v_start = display_v_start;
+		active_v_end = active_v_start + (p->yres * hsync_period) - 1;
+
+		active_hctl = (active_h_end << 16) | active_h_start;
+		display_hctl = active_hctl;
+
+		intf_cfg |= INTF_CFG_ACTIVE_H_EN | INTF_CFG_ACTIVE_V_EN;
+	}
+
+	den_polarity = 0;
+	polarity_ctl = (den_polarity << 2) | /*  DEN Polarity  */
+		(p->vsync_polarity << 1) | /* VSYNC Polarity */
+		(p->hsync_polarity << 0);  /* HSYNC Polarity */
+
+	if (!DPU_FORMAT_IS_YUV(fmt))
+		panel_format = (fmt->bits[C0_G_Y] |
+				(fmt->bits[C1_B_Cb] << 2) |
+				(fmt->bits[C2_R_Cr] << 4) |
+				(0x21 << 8));
+	else
+		/* Interface treats all the pixel data in RGB888 format */
+		panel_format = (COLOR_8BIT |
+				(COLOR_8BIT << 2) |
+				(COLOR_8BIT << 4) |
+				(0x21 << 8));
+
+	DPU_REG_WRITE(c, INTF_HSYNC_CTL, hsync_ctl);
+	DPU_REG_WRITE(c, INTF_VSYNC_PERIOD_F0, vsync_period * hsync_period);
+	DPU_REG_WRITE(c, INTF_VSYNC_PULSE_WIDTH_F0,
+			p->vsync_pulse_width * hsync_period);
+	DPU_REG_WRITE(c, INTF_DISPLAY_HCTL, display_hctl);
+	DPU_REG_WRITE(c, INTF_DISPLAY_V_START_F0, display_v_start);
+	DPU_REG_WRITE(c, INTF_DISPLAY_V_END_F0, display_v_end);
+	DPU_REG_WRITE(c, INTF_ACTIVE_HCTL,  active_hctl);
+	DPU_REG_WRITE(c, INTF_ACTIVE_V_START_F0, active_v_start);
+	DPU_REG_WRITE(c, INTF_ACTIVE_V_END_F0, active_v_end);
+	DPU_REG_WRITE(c, INTF_BORDER_COLOR, p->border_clr);
+	DPU_REG_WRITE(c, INTF_UNDERFLOW_COLOR, p->underflow_clr);
+	DPU_REG_WRITE(c, INTF_HSYNC_SKEW, p->hsync_skew);
+	DPU_REG_WRITE(c, INTF_POLARITY_CTL, polarity_ctl);
+	DPU_REG_WRITE(c, INTF_FRAME_LINE_COUNT_EN, 0x3);
+	DPU_REG_WRITE(c, INTF_CONFIG, intf_cfg);
+	DPU_REG_WRITE(c, INTF_PANEL_FORMAT, panel_format);
+	if (ctx->cap->features & BIT(DPU_DATA_HCTL_EN)) {
+		/*
+		 * DATA_HCTL_EN controls data timing which can be different from
+		 * video timing. It is recommended to enable it for all cases, except
+		 * if compression is enabled in 1 pixel per clock mode
+		 */
+		if (!(p->compression_en && !p->wide_bus_en))
+			intf_cfg2 |= INTF_CFG2_DATA_HCTL_EN;
+
+		DPU_REG_WRITE(c, INTF_CONFIG2, intf_cfg2);
+		DPU_REG_WRITE(c, INTF_DISPLAY_DATA_HCTL, display_data_hctl);
+		DPU_REG_WRITE(c, INTF_ACTIVE_DATA_HCTL, active_data_hctl);
+	}
+}
+
+static void dpu_hw_intf_enable_timing_engine(
+		struct dpu_hw_intf *intf,
+		u8 enable)
+{
+	struct dpu_hw_blk_reg_map *c = &intf->hw;
+	/* Note: Display interface select is handled in top block hw layer */
+	DPU_REG_WRITE(c, INTF_TIMING_ENGINE_EN, enable != 0);
+}
+
+static void dpu_hw_intf_setup_prg_fetch(
+		struct dpu_hw_intf *intf,
+		const struct dpu_hw_intf_prog_fetch *fetch)
+{
+	struct dpu_hw_blk_reg_map *c = &intf->hw;
+	int fetch_enable;
+
+	/*
+	 * Fetch should always be outside the active lines. If the fetching
+	 * is programmed within active region, hardware behavior is unknown.
+	 */
+
+	fetch_enable = DPU_REG_READ(c, INTF_CONFIG);
+	if (fetch->enable) {
+		fetch_enable |= BIT(31);
+		DPU_REG_WRITE(c, INTF_PROG_FETCH_START,
+				fetch->fetch_start);
+	} else {
+		fetch_enable &= ~BIT(31);
+	}
+
+	DPU_REG_WRITE(c, INTF_CONFIG, fetch_enable);
+}
+
+static void dpu_hw_intf_bind_pingpong_blk(
+		struct dpu_hw_intf *intf,
+		const enum dpu_pingpong pp)
+{
+	struct dpu_hw_blk_reg_map *c = &intf->hw;
+	u32 mux_cfg;
+
+	mux_cfg = DPU_REG_READ(c, INTF_MUX);
+	mux_cfg &= ~0xf;
+
+	if (pp)
+		mux_cfg |= (pp - PINGPONG_0) & 0x7;
+	else
+		mux_cfg |= 0xf;
+
+	DPU_REG_WRITE(c, INTF_MUX, mux_cfg);
+}
+
+static void dpu_hw_intf_get_status(
+		struct dpu_hw_intf *intf,
+		struct dpu_hw_intf_status *s)
+{
+	struct dpu_hw_blk_reg_map *c = &intf->hw;
+	unsigned long cap = intf->cap->features;
+
+	if (cap & BIT(DPU_INTF_STATUS_SUPPORTED))
+		s->is_en = DPU_REG_READ(c, INTF_STATUS) & BIT(0);
+	else
+		s->is_en = DPU_REG_READ(c, INTF_TIMING_ENGINE_EN);
+
+	s->is_prog_fetch_en = !!(DPU_REG_READ(c, INTF_CONFIG) & BIT(31));
+	if (s->is_en) {
+		s->frame_count = DPU_REG_READ(c, INTF_FRAME_COUNT);
+		s->line_count = DPU_REG_READ(c, INTF_LINE_COUNT);
+	} else {
+		s->line_count = 0;
+		s->frame_count = 0;
+	}
+}
+
+static u32 dpu_hw_intf_get_line_count(struct dpu_hw_intf *intf)
+{
+	struct dpu_hw_blk_reg_map *c;
+
+	if (!intf)
+		return 0;
+
+	c = &intf->hw;
+
+	return DPU_REG_READ(c, INTF_LINE_COUNT);
+}
+
+static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf)
+{
+	dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, 0x1);
+}
+
+static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 *misr_value)
+{
+	return dpu_hw_collect_misr(&intf->hw, INTF_MISR_CTRL, INTF_MISR_SIGNATURE, misr_value);
+}
+
+static int dpu_hw_intf_enable_te(struct dpu_hw_intf *intf,
+		struct dpu_hw_tear_check *te)
+{
+	struct dpu_hw_blk_reg_map *c;
+	int cfg;
+
+	if (!intf)
+		return -EINVAL;
+
+	c = &intf->hw;
+
+	cfg = BIT(19); /* VSYNC_COUNTER_EN */
+	if (te->hw_vsync_mode)
+		cfg |= BIT(20);
+
+	cfg |= te->vsync_count;
+
+	DPU_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg);
+	DPU_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_HEIGHT, te->sync_cfg_height);
+	DPU_REG_WRITE(c, INTF_TEAR_VSYNC_INIT_VAL, te->vsync_init_val);
+	DPU_REG_WRITE(c, INTF_TEAR_RD_PTR_IRQ, te->rd_ptr_irq);
+	DPU_REG_WRITE(c, INTF_TEAR_START_POS, te->start_pos);
+	DPU_REG_WRITE(c, INTF_TEAR_SYNC_THRESH,
+			((te->sync_threshold_continue << 16) |
+			 te->sync_threshold_start));
+	DPU_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT,
+			(te->start_pos + te->sync_threshold_start + 1));
+
+	DPU_REG_WRITE(c, INTF_TEAR_TEAR_CHECK_EN, 1);
+
+	return 0;
+}
+
+static void dpu_hw_intf_setup_autorefresh_config(struct dpu_hw_intf *intf,
+		u32 frame_count, bool enable)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 refresh_cfg;
+
+	c = &intf->hw;
+	refresh_cfg = DPU_REG_READ(c, INTF_TEAR_AUTOREFRESH_CONFIG);
+	if (enable)
+		refresh_cfg = BIT(31) | frame_count;
+	else
+		refresh_cfg &= ~BIT(31);
+
+	DPU_REG_WRITE(c, INTF_TEAR_AUTOREFRESH_CONFIG, refresh_cfg);
+}
+
+/*
+ * dpu_hw_intf_get_autorefresh_config - Get autorefresh config from HW
+ * @intf:        DPU intf structure
+ * @frame_count: Used to return the current frame count from hw
+ *
+ * Returns: True if autorefresh enabled, false if disabled.
+ */
+static bool dpu_hw_intf_get_autorefresh_config(struct dpu_hw_intf *intf,
+		u32 *frame_count)
+{
+	u32 val = DPU_REG_READ(&intf->hw, INTF_TEAR_AUTOREFRESH_CONFIG);
+
+	if (frame_count != NULL)
+		*frame_count = val & 0xffff;
+	return !!((val & BIT(31)) >> 31);
+}
+
+static int dpu_hw_intf_disable_te(struct dpu_hw_intf *intf)
+{
+	struct dpu_hw_blk_reg_map *c;
+
+	if (!intf)
+		return -EINVAL;
+
+	c = &intf->hw;
+	DPU_REG_WRITE(c, INTF_TEAR_TEAR_CHECK_EN, 0);
+	return 0;
+}
+
+static int dpu_hw_intf_connect_external_te(struct dpu_hw_intf *intf,
+		bool enable_external_te)
+{
+	struct dpu_hw_blk_reg_map *c = &intf->hw;
+	u32 cfg;
+	int orig;
+
+	if (!intf)
+		return -EINVAL;
+
+	c = &intf->hw;
+	cfg = DPU_REG_READ(c, INTF_TEAR_SYNC_CONFIG_VSYNC);
+	orig = (bool)(cfg & BIT(20));
+	if (enable_external_te)
+		cfg |= BIT(20);
+	else
+		cfg &= ~BIT(20);
+	DPU_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg);
+	trace_dpu_intf_connect_ext_te(intf->idx - INTF_0, cfg);
+
+	return orig;
+}
+
+static int dpu_hw_intf_get_vsync_info(struct dpu_hw_intf *intf,
+		struct dpu_hw_pp_vsync_info *info)
+{
+	struct dpu_hw_blk_reg_map *c = &intf->hw;
+	u32 val;
+
+	if (!intf || !info)
+		return -EINVAL;
+
+	c = &intf->hw;
+
+	val = DPU_REG_READ(c, INTF_TEAR_VSYNC_INIT_VAL);
+	info->rd_ptr_init_val = val & 0xffff;
+
+	val = DPU_REG_READ(c, INTF_TEAR_INT_COUNT_VAL);
+	info->rd_ptr_frame_count = (val & 0xffff0000) >> 16;
+	info->rd_ptr_line_count = val & 0xffff;
+
+	val = DPU_REG_READ(c, INTF_TEAR_LINE_COUNT);
+	info->wr_ptr_line_count = val & 0xffff;
+
+	val = DPU_REG_READ(c, INTF_FRAME_COUNT);
+	info->intf_frame_count = val;
+
+	return 0;
+}
+
+static void dpu_hw_intf_vsync_sel(struct dpu_hw_intf *intf,
+		u32 vsync_source)
+{
+	struct dpu_hw_blk_reg_map *c;
+
+	if (!intf)
+		return;
+
+	c = &intf->hw;
+
+	DPU_REG_WRITE(c, INTF_TEAR_MDP_VSYNC_SEL, (vsync_source & 0xf));
+}
+
+static void dpu_hw_intf_disable_autorefresh(struct dpu_hw_intf *intf,
+					    uint32_t encoder_id, u16 vdisplay)
+{
+	struct dpu_hw_pp_vsync_info info;
+	int trial = 0;
+
+	/* If autorefresh is already disabled, we have nothing to do */
+	if (!dpu_hw_intf_get_autorefresh_config(intf, NULL))
+		return;
+
+	/*
+	 * If autorefresh is enabled, disable it and make sure it is safe to
+	 * proceed with current frame commit/push. Sequence followed is,
+	 * 1. Disable TE
+	 * 2. Disable autorefresh config
+	 * 4. Poll for frame transfer ongoing to be false
+	 * 5. Enable TE back
+	 */
+
+	dpu_hw_intf_connect_external_te(intf, false);
+	dpu_hw_intf_setup_autorefresh_config(intf, 0, false);
+
+	do {
+		udelay(DPU_ENC_MAX_POLL_TIMEOUT_US);
+		if ((trial * DPU_ENC_MAX_POLL_TIMEOUT_US)
+				> (KICKOFF_TIMEOUT_MS * USEC_PER_MSEC)) {
+			DPU_ERROR("enc%d intf%d disable autorefresh failed\n",
+				  encoder_id, intf->idx - INTF_0);
+			break;
+		}
+
+		trial++;
+
+		dpu_hw_intf_get_vsync_info(intf, &info);
+	} while (info.wr_ptr_line_count > 0 &&
+		 info.wr_ptr_line_count < vdisplay);
+
+	dpu_hw_intf_connect_external_te(intf, true);
+
+	DPU_DEBUG("enc%d intf%d disabled autorefresh\n",
+		  encoder_id, intf->idx - INTF_0);
+
+}
+
+static void dpu_hw_intf_program_intf_cmd_cfg(struct dpu_hw_intf *ctx,
+					     struct dpu_hw_intf_cmd_mode_cfg *cmd_mode_cfg)
+{
+	u32 intf_cfg2 = DPU_REG_READ(&ctx->hw, INTF_CONFIG2);
+
+	if (cmd_mode_cfg->data_compress)
+		intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS;
+
+	if (cmd_mode_cfg->wide_bus_en)
+		intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN;
+
+	DPU_REG_WRITE(&ctx->hw, INTF_CONFIG2, intf_cfg2);
+}
+
+struct dpu_hw_intf *dpu_hw_intf_init(struct drm_device *dev,
+				     const struct dpu_intf_cfg *cfg,
+				     void __iomem *addr,
+				     const struct dpu_mdss_version *mdss_rev)
+{
+	struct dpu_hw_intf *c;
+
+	if (cfg->type == INTF_NONE) {
+		DPU_DEBUG("Skip intf %d with type NONE\n", cfg->id - INTF_0);
+		return NULL;
+	}
+
+	c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
+	if (!c)
+		return ERR_PTR(-ENOMEM);
+
+	c->hw.blk_addr = addr + cfg->base;
+	c->hw.log_mask = DPU_DBG_MASK_INTF;
+
+	/*
+	 * Assign ops
+	 */
+	c->idx = cfg->id;
+	c->cap = cfg;
+
+	c->ops.setup_timing_gen = dpu_hw_intf_setup_timing_engine;
+	c->ops.setup_prg_fetch  = dpu_hw_intf_setup_prg_fetch;
+	c->ops.get_status = dpu_hw_intf_get_status;
+	c->ops.enable_timing = dpu_hw_intf_enable_timing_engine;
+	c->ops.get_line_count = dpu_hw_intf_get_line_count;
+	c->ops.setup_misr = dpu_hw_intf_setup_misr;
+	c->ops.collect_misr = dpu_hw_intf_collect_misr;
+
+	if (cfg->features & BIT(DPU_INTF_INPUT_CTRL))
+		c->ops.bind_pingpong_blk = dpu_hw_intf_bind_pingpong_blk;
+
+	/* INTF TE is only for DSI interfaces */
+	if (mdss_rev->core_major_ver >= 5 && cfg->type == INTF_DSI) {
+		WARN_ON(!cfg->intr_tear_rd_ptr);
+
+		c->ops.enable_tearcheck = dpu_hw_intf_enable_te;
+		c->ops.disable_tearcheck = dpu_hw_intf_disable_te;
+		c->ops.connect_external_te = dpu_hw_intf_connect_external_te;
+		c->ops.vsync_sel = dpu_hw_intf_vsync_sel;
+		c->ops.disable_autorefresh = dpu_hw_intf_disable_autorefresh;
+	}
+
+	/* Technically, INTF_CONFIG2 is present for DPU 5.0+, but
+	 * we can configure it for DPU 7.0+ since the wide bus and DSC flags
+	 * would not be set for DPU < 7.0 anyways
+	 */
+	if (mdss_rev->core_major_ver >= 7)
+		c->ops.program_intf_cmd_cfg = dpu_hw_intf_program_intf_cmd_cfg;
+
+	return c;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_intf.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_intf.h
@@ -0,0 +1,145 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_INTF_H
+#define _DPU_HW_INTF_H
+
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_util.h"
+
+struct dpu_hw_intf;
+
+/* intf timing settings */
+struct dpu_hw_intf_timing_params {
+	u32 width;		/* active width */
+	u32 height;		/* active height */
+	u32 xres;		/* Display panel width */
+	u32 yres;		/* Display panel height */
+
+	u32 h_back_porch;
+	u32 h_front_porch;
+	u32 v_back_porch;
+	u32 v_front_porch;
+	u32 hsync_pulse_width;
+	u32 vsync_pulse_width;
+	u32 hsync_polarity;
+	u32 vsync_polarity;
+	u32 border_clr;
+	u32 underflow_clr;
+	u32 hsync_skew;
+
+	bool wide_bus_en;
+	bool compression_en;
+};
+
+struct dpu_hw_intf_prog_fetch {
+	u8 enable;
+	/* vsync counter for the front porch pixel line */
+	u32 fetch_start;
+};
+
+struct dpu_hw_intf_status {
+	u8 is_en;		/* interface timing engine is enabled or not */
+	u8 is_prog_fetch_en;	/* interface prog fetch counter is enabled or not */
+	u32 frame_count;	/* frame count since timing engine enabled */
+	u32 line_count;		/* current line count including blanking */
+};
+
+struct dpu_hw_intf_cmd_mode_cfg {
+	u8 data_compress;	/* enable data compress between dpu and dsi */
+	u8 wide_bus_en;		/* enable databus widen mode */
+};
+
+/**
+ * struct dpu_hw_intf_ops : Interface to the interface Hw driver functions
+ *  Assumption is these functions will be called after clocks are enabled
+ * @ setup_timing_gen : programs the timing engine
+ * @ setup_prog_fetch : enables/disables the programmable fetch logic
+ * @ enable_timing: enable/disable timing engine
+ * @ get_status: returns if timing engine is enabled or not
+ * @ get_line_count: reads current vertical line counter
+ * @bind_pingpong_blk: enable/disable the connection with pingpong which will
+ *                     feed pixels to this interface
+ * @setup_misr: enable/disable MISR
+ * @collect_misr: read MISR signature
+ * @enable_tearcheck:           Enables vsync generation and sets up init value of read
+ *                              pointer and programs the tear check configuration
+ * @disable_tearcheck:          Disables tearcheck block
+ * @connect_external_te:        Read, modify, write to either set or clear listening to external TE
+ *                              Return: 1 if TE was originally connected, 0 if not, or -ERROR
+ * @get_vsync_info:             Provides the programmed and current line_count
+ * @setup_autorefresh:          Configure and enable the autorefresh config
+ * @get_autorefresh:            Retrieve autorefresh config from hardware
+ *                              Return: 0 on success, -ETIMEDOUT on timeout
+ * @vsync_sel:                  Select vsync signal for tear-effect configuration
+ * @program_intf_cmd_cfg:       Program the DPU to interface datapath for command mode
+ */
+struct dpu_hw_intf_ops {
+	void (*setup_timing_gen)(struct dpu_hw_intf *intf,
+			const struct dpu_hw_intf_timing_params *p,
+			const struct dpu_format *fmt);
+
+	void (*setup_prg_fetch)(struct dpu_hw_intf *intf,
+			const struct dpu_hw_intf_prog_fetch *fetch);
+
+	void (*enable_timing)(struct dpu_hw_intf *intf,
+			u8 enable);
+
+	void (*get_status)(struct dpu_hw_intf *intf,
+			struct dpu_hw_intf_status *status);
+
+	u32 (*get_line_count)(struct dpu_hw_intf *intf);
+
+	void (*bind_pingpong_blk)(struct dpu_hw_intf *intf,
+			const enum dpu_pingpong pp);
+	void (*setup_misr)(struct dpu_hw_intf *intf);
+	int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value);
+
+	// Tearcheck on INTF since DPU 5.0.0
+
+	int (*enable_tearcheck)(struct dpu_hw_intf *intf, struct dpu_hw_tear_check *cfg);
+
+	int (*disable_tearcheck)(struct dpu_hw_intf *intf);
+
+	int (*connect_external_te)(struct dpu_hw_intf *intf, bool enable_external_te);
+
+	void (*vsync_sel)(struct dpu_hw_intf *intf, u32 vsync_source);
+
+	/**
+	 * Disable autorefresh if enabled
+	 */
+	void (*disable_autorefresh)(struct dpu_hw_intf *intf, uint32_t encoder_id, u16 vdisplay);
+
+	void (*program_intf_cmd_cfg)(struct dpu_hw_intf *intf,
+				     struct dpu_hw_intf_cmd_mode_cfg *cmd_mode_cfg);
+};
+
+struct dpu_hw_intf {
+	struct dpu_hw_blk_reg_map hw;
+
+	/* intf */
+	enum dpu_intf idx;
+	const struct dpu_intf_cfg *cap;
+
+	/* ops */
+	struct dpu_hw_intf_ops ops;
+};
+
+/**
+ * dpu_hw_intf_init() - Initializes the INTF driver for the passed
+ * interface catalog entry.
+ * @dev:  Corresponding device for devres management
+ * @cfg:  interface catalog entry for which driver object is required
+ * @addr: mapped register io address of MDP
+ * @mdss_rev: dpu core's major and minor versions
+ */
+struct dpu_hw_intf *dpu_hw_intf_init(struct drm_device *dev,
+				     const struct dpu_intf_cfg *cfg,
+				     void __iomem *addr,
+				     const struct dpu_mdss_version *mdss_rev);
+
+#endif /*_DPU_HW_INTF_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_lm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_lm.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
+ */
+
+#include <drm/drm_managed.h>
+
+#include "dpu_kms.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hwio.h"
+#include "dpu_hw_lm.h"
+#include "dpu_hw_mdss.h"
+
+#define LM_OP_MODE                        0x00
+#define LM_OUT_SIZE                       0x04
+#define LM_BORDER_COLOR_0                 0x08
+#define LM_BORDER_COLOR_1                 0x010
+
+/* These register are offset to mixer base + stage base */
+#define LM_BLEND0_OP                     0x00
+#define LM_BLEND0_CONST_ALPHA            0x04
+#define LM_FG_COLOR_FILL_COLOR_0         0x08
+#define LM_FG_COLOR_FILL_COLOR_1         0x0C
+#define LM_FG_COLOR_FILL_SIZE            0x10
+#define LM_FG_COLOR_FILL_XY              0x14
+
+#define LM_BLEND0_FG_ALPHA               0x04
+#define LM_BLEND0_BG_ALPHA               0x08
+
+#define LM_MISR_CTRL                     0x310
+#define LM_MISR_SIGNATURE                0x314
+
+
+/**
+ * _stage_offset(): returns the relative offset of the blend registers
+ * for the stage to be setup
+ * @ctx:     mixer ctx contains the mixer to be programmed
+ * @stage: stage index to setup
+ */
+static inline int _stage_offset(struct dpu_hw_mixer *ctx, enum dpu_stage stage)
+{
+	const struct dpu_lm_sub_blks *sblk = ctx->cap->sblk;
+	if (stage != DPU_STAGE_BASE && stage <= sblk->maxblendstages)
+		return sblk->blendstage_base[stage - DPU_STAGE_0];
+
+	return -EINVAL;
+}
+
+static void dpu_hw_lm_setup_out(struct dpu_hw_mixer *ctx,
+		struct dpu_hw_mixer_cfg *mixer)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	u32 outsize;
+	u32 op_mode;
+
+	op_mode = DPU_REG_READ(c, LM_OP_MODE);
+
+	outsize = mixer->out_height << 16 | mixer->out_width;
+	DPU_REG_WRITE(c, LM_OUT_SIZE, outsize);
+
+	/* SPLIT_LEFT_RIGHT */
+	if (mixer->right_mixer)
+		op_mode |= BIT(31);
+	else
+		op_mode &= ~BIT(31);
+	DPU_REG_WRITE(c, LM_OP_MODE, op_mode);
+}
+
+static void dpu_hw_lm_setup_border_color(struct dpu_hw_mixer *ctx,
+		struct dpu_mdss_color *color,
+		u8 border_en)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+
+	if (border_en) {
+		DPU_REG_WRITE(c, LM_BORDER_COLOR_0,
+			(color->color_0 & 0xFFF) |
+			((color->color_1 & 0xFFF) << 0x10));
+		DPU_REG_WRITE(c, LM_BORDER_COLOR_1,
+			(color->color_2 & 0xFFF) |
+			((color->color_3 & 0xFFF) << 0x10));
+	}
+}
+
+static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx)
+{
+	dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, 0x0);
+}
+
+static int dpu_hw_lm_collect_misr(struct dpu_hw_mixer *ctx, u32 *misr_value)
+{
+	return dpu_hw_collect_misr(&ctx->hw, LM_MISR_CTRL, LM_MISR_SIGNATURE, misr_value);
+}
+
+static void dpu_hw_lm_setup_blend_config_combined_alpha(struct dpu_hw_mixer *ctx,
+	u32 stage, u32 fg_alpha, u32 bg_alpha, u32 blend_op)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	int stage_off;
+	u32 const_alpha;
+
+	if (stage == DPU_STAGE_BASE)
+		return;
+
+	stage_off = _stage_offset(ctx, stage);
+	if (WARN_ON(stage_off < 0))
+		return;
+
+	const_alpha = (bg_alpha & 0xFF) | ((fg_alpha & 0xFF) << 16);
+	DPU_REG_WRITE(c, LM_BLEND0_CONST_ALPHA + stage_off, const_alpha);
+	DPU_REG_WRITE(c, LM_BLEND0_OP + stage_off, blend_op);
+}
+
+static void dpu_hw_lm_setup_blend_config(struct dpu_hw_mixer *ctx,
+	u32 stage, u32 fg_alpha, u32 bg_alpha, u32 blend_op)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	int stage_off;
+
+	if (stage == DPU_STAGE_BASE)
+		return;
+
+	stage_off = _stage_offset(ctx, stage);
+	if (WARN_ON(stage_off < 0))
+		return;
+
+	DPU_REG_WRITE(c, LM_BLEND0_FG_ALPHA + stage_off, fg_alpha);
+	DPU_REG_WRITE(c, LM_BLEND0_BG_ALPHA + stage_off, bg_alpha);
+	DPU_REG_WRITE(c, LM_BLEND0_OP + stage_off, blend_op);
+}
+
+static void dpu_hw_lm_setup_color3(struct dpu_hw_mixer *ctx,
+	uint32_t mixer_op_mode)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	int op_mode;
+
+	/* read the existing op_mode configuration */
+	op_mode = DPU_REG_READ(c, LM_OP_MODE);
+
+	op_mode = (op_mode & (BIT(31) | BIT(30))) | mixer_op_mode;
+
+	DPU_REG_WRITE(c, LM_OP_MODE, op_mode);
+}
+
+static void _setup_mixer_ops(struct dpu_hw_lm_ops *ops,
+		unsigned long features)
+{
+	ops->setup_mixer_out = dpu_hw_lm_setup_out;
+	if (test_bit(DPU_MIXER_COMBINED_ALPHA, &features))
+		ops->setup_blend_config = dpu_hw_lm_setup_blend_config_combined_alpha;
+	else
+		ops->setup_blend_config = dpu_hw_lm_setup_blend_config;
+	ops->setup_alpha_out = dpu_hw_lm_setup_color3;
+	ops->setup_border_color = dpu_hw_lm_setup_border_color;
+	ops->setup_misr = dpu_hw_lm_setup_misr;
+	ops->collect_misr = dpu_hw_lm_collect_misr;
+}
+
+struct dpu_hw_mixer *dpu_hw_lm_init(struct drm_device *dev,
+				    const struct dpu_lm_cfg *cfg,
+				    void __iomem *addr)
+{
+	struct dpu_hw_mixer *c;
+
+	if (cfg->pingpong == PINGPONG_NONE) {
+		DPU_DEBUG("skip mixer %d without pingpong\n", cfg->id);
+		return NULL;
+	}
+
+	c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
+	if (!c)
+		return ERR_PTR(-ENOMEM);
+
+	c->hw.blk_addr = addr + cfg->base;
+	c->hw.log_mask = DPU_DBG_MASK_LM;
+
+	/* Assign ops */
+	c->idx = cfg->id;
+	c->cap = cfg;
+	_setup_mixer_ops(&c->ops, c->cap->features);
+
+	return c;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_lm.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_lm.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_LM_H
+#define _DPU_HW_LM_H
+
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_util.h"
+
+struct dpu_hw_mixer;
+
+struct dpu_hw_mixer_cfg {
+	u32 out_width;
+	u32 out_height;
+	bool right_mixer;
+	int flags;
+};
+
+struct dpu_hw_color3_cfg {
+	u8 keep_fg[DPU_STAGE_MAX];
+};
+
+/**
+ *
+ * struct dpu_hw_lm_ops : Interface to the mixer Hw driver functions
+ *  Assumption is these functions will be called after clocks are enabled
+ */
+struct dpu_hw_lm_ops {
+	/*
+	 * Sets up mixer output width and height
+	 * and border color if enabled
+	 */
+	void (*setup_mixer_out)(struct dpu_hw_mixer *ctx,
+		struct dpu_hw_mixer_cfg *cfg);
+
+	/*
+	 * Alpha blending configuration
+	 * for the specified stage
+	 */
+	void (*setup_blend_config)(struct dpu_hw_mixer *ctx, uint32_t stage,
+		uint32_t fg_alpha, uint32_t bg_alpha, uint32_t blend_op);
+
+	/*
+	 * Alpha color component selection from either fg or bg
+	 */
+	void (*setup_alpha_out)(struct dpu_hw_mixer *ctx, uint32_t mixer_op);
+
+	/**
+	 * setup_border_color : enable/disable border color
+	 */
+	void (*setup_border_color)(struct dpu_hw_mixer *ctx,
+		struct dpu_mdss_color *color,
+		u8 border_en);
+
+	/**
+	 * setup_misr: Enable/disable MISR
+	 */
+	void (*setup_misr)(struct dpu_hw_mixer *ctx);
+
+	/**
+	 * collect_misr: Read MISR signature
+	 */
+	int (*collect_misr)(struct dpu_hw_mixer *ctx, u32 *misr_value);
+};
+
+struct dpu_hw_mixer {
+	struct dpu_hw_blk base;
+	struct dpu_hw_blk_reg_map hw;
+
+	/* lm */
+	enum dpu_lm  idx;
+	const struct dpu_lm_cfg   *cap;
+	const struct dpu_mdp_cfg  *mdp;
+	const struct dpu_ctl_cfg  *ctl;
+
+	/* ops */
+	struct dpu_hw_lm_ops ops;
+
+	/* store mixer info specific to display */
+	struct dpu_hw_mixer_cfg cfg;
+};
+
+/**
+ * to_dpu_hw_mixer - convert base object dpu_hw_base to container
+ * @hw: Pointer to base hardware block
+ * return: Pointer to hardware block container
+ */
+static inline struct dpu_hw_mixer *to_dpu_hw_mixer(struct dpu_hw_blk *hw)
+{
+	return container_of(hw, struct dpu_hw_mixer, base);
+}
+
+/**
+ * dpu_hw_lm_init() - Initializes the mixer hw driver object.
+ * should be called once before accessing every mixer.
+ * @dev:  Corresponding device for devres management
+ * @cfg:  mixer catalog entry for which driver object is required
+ * @addr: mapped register io address of MDP
+ */
+struct dpu_hw_mixer *dpu_hw_lm_init(struct drm_device *dev,
+				    const struct dpu_lm_cfg *cfg,
+				    void __iomem *addr);
+
+#endif /*_DPU_HW_LM_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_mdss.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_mdss.h
@@ -0,0 +1,520 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_MDSS_H
+#define _DPU_HW_MDSS_H
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+
+#include "msm_drv.h"
+
+#define DPU_DBG_NAME			"dpu"
+
+#define DPU_NONE                        0
+
+#ifndef DPU_CSC_MATRIX_COEFF_SIZE
+#define DPU_CSC_MATRIX_COEFF_SIZE	9
+#endif
+
+#ifndef DPU_CSC_CLAMP_SIZE
+#define DPU_CSC_CLAMP_SIZE		6
+#endif
+
+#ifndef DPU_CSC_BIAS_SIZE
+#define DPU_CSC_BIAS_SIZE		3
+#endif
+
+#ifndef DPU_MAX_PLANES
+#define DPU_MAX_PLANES			4
+#endif
+
+#define PIPES_PER_STAGE			2
+#ifndef DPU_MAX_DE_CURVES
+#define DPU_MAX_DE_CURVES		3
+#endif
+
+enum dpu_format_flags {
+	DPU_FORMAT_FLAG_YUV_BIT,
+	DPU_FORMAT_FLAG_DX_BIT,
+	DPU_FORMAT_FLAG_COMPRESSED_BIT,
+	DPU_FORMAT_FLAG_BIT_MAX,
+};
+
+#define DPU_FORMAT_FLAG_YUV		BIT(DPU_FORMAT_FLAG_YUV_BIT)
+#define DPU_FORMAT_FLAG_DX		BIT(DPU_FORMAT_FLAG_DX_BIT)
+#define DPU_FORMAT_FLAG_COMPRESSED	BIT(DPU_FORMAT_FLAG_COMPRESSED_BIT)
+#define DPU_FORMAT_IS_YUV(X)		\
+	(test_bit(DPU_FORMAT_FLAG_YUV_BIT, (X)->flag))
+#define DPU_FORMAT_IS_DX(X)		\
+	(test_bit(DPU_FORMAT_FLAG_DX_BIT, (X)->flag))
+#define DPU_FORMAT_IS_LINEAR(X)		((X)->fetch_mode == DPU_FETCH_LINEAR)
+#define DPU_FORMAT_IS_TILE(X) \
+	(((X)->fetch_mode == DPU_FETCH_UBWC) && \
+			!test_bit(DPU_FORMAT_FLAG_COMPRESSED_BIT, (X)->flag))
+#define DPU_FORMAT_IS_UBWC(X) \
+	(((X)->fetch_mode == DPU_FETCH_UBWC) && \
+			test_bit(DPU_FORMAT_FLAG_COMPRESSED_BIT, (X)->flag))
+
+#define DPU_BLEND_FG_ALPHA_FG_CONST	(0 << 0)
+#define DPU_BLEND_FG_ALPHA_BG_CONST	(1 << 0)
+#define DPU_BLEND_FG_ALPHA_FG_PIXEL	(2 << 0)
+#define DPU_BLEND_FG_ALPHA_BG_PIXEL	(3 << 0)
+#define DPU_BLEND_FG_INV_ALPHA		(1 << 2)
+#define DPU_BLEND_FG_MOD_ALPHA		(1 << 3)
+#define DPU_BLEND_FG_INV_MOD_ALPHA	(1 << 4)
+#define DPU_BLEND_FG_TRANSP_EN		(1 << 5)
+#define DPU_BLEND_BG_ALPHA_FG_CONST	(0 << 8)
+#define DPU_BLEND_BG_ALPHA_BG_CONST	(1 << 8)
+#define DPU_BLEND_BG_ALPHA_FG_PIXEL	(2 << 8)
+#define DPU_BLEND_BG_ALPHA_BG_PIXEL	(3 << 8)
+#define DPU_BLEND_BG_INV_ALPHA		(1 << 10)
+#define DPU_BLEND_BG_MOD_ALPHA		(1 << 11)
+#define DPU_BLEND_BG_INV_MOD_ALPHA	(1 << 12)
+#define DPU_BLEND_BG_TRANSP_EN		(1 << 13)
+
+#define DPU_VSYNC0_SOURCE_GPIO		0
+#define DPU_VSYNC1_SOURCE_GPIO		1
+#define DPU_VSYNC2_SOURCE_GPIO		2
+#define DPU_VSYNC_SOURCE_INTF_0		3
+#define DPU_VSYNC_SOURCE_INTF_1		4
+#define DPU_VSYNC_SOURCE_INTF_2		5
+#define DPU_VSYNC_SOURCE_INTF_3		6
+#define DPU_VSYNC_SOURCE_WD_TIMER_4	11
+#define DPU_VSYNC_SOURCE_WD_TIMER_3	12
+#define DPU_VSYNC_SOURCE_WD_TIMER_2	13
+#define DPU_VSYNC_SOURCE_WD_TIMER_1	14
+#define DPU_VSYNC_SOURCE_WD_TIMER_0	15
+
+enum dpu_hw_blk_type {
+	DPU_HW_BLK_TOP = 0,
+	DPU_HW_BLK_SSPP,
+	DPU_HW_BLK_LM,
+	DPU_HW_BLK_CTL,
+	DPU_HW_BLK_PINGPONG,
+	DPU_HW_BLK_INTF,
+	DPU_HW_BLK_WB,
+	DPU_HW_BLK_DSPP,
+	DPU_HW_BLK_MERGE_3D,
+	DPU_HW_BLK_DSC,
+	DPU_HW_BLK_CDM,
+	DPU_HW_BLK_MAX,
+};
+
+enum dpu_sspp {
+	SSPP_NONE,
+	SSPP_VIG0,
+	SSPP_VIG1,
+	SSPP_VIG2,
+	SSPP_VIG3,
+	SSPP_RGB0,
+	SSPP_RGB1,
+	SSPP_RGB2,
+	SSPP_RGB3,
+	SSPP_DMA0,
+	SSPP_DMA1,
+	SSPP_DMA2,
+	SSPP_DMA3,
+	SSPP_DMA4,
+	SSPP_DMA5,
+	SSPP_CURSOR0,
+	SSPP_CURSOR1,
+	SSPP_MAX
+};
+
+enum dpu_sspp_type {
+	SSPP_TYPE_VIG,
+	SSPP_TYPE_RGB,
+	SSPP_TYPE_DMA,
+	SSPP_TYPE_CURSOR,
+	SSPP_TYPE_MAX
+};
+
+enum dpu_lm {
+	LM_0 = 1,
+	LM_1,
+	LM_2,
+	LM_3,
+	LM_4,
+	LM_5,
+	LM_6,
+	LM_MAX
+};
+
+enum dpu_stage {
+	DPU_STAGE_BASE = 0,
+	DPU_STAGE_0,
+	DPU_STAGE_1,
+	DPU_STAGE_2,
+	DPU_STAGE_3,
+	DPU_STAGE_4,
+	DPU_STAGE_5,
+	DPU_STAGE_6,
+	DPU_STAGE_7,
+	DPU_STAGE_8,
+	DPU_STAGE_9,
+	DPU_STAGE_10,
+	DPU_STAGE_MAX
+};
+enum dpu_dspp {
+	DSPP_0 = 1,
+	DSPP_1,
+	DSPP_2,
+	DSPP_3,
+	DSPP_MAX
+};
+
+enum dpu_ctl {
+	CTL_0 = 1,
+	CTL_1,
+	CTL_2,
+	CTL_3,
+	CTL_4,
+	CTL_5,
+	CTL_MAX
+};
+
+enum dpu_dsc {
+	DSC_NONE = 0,
+	DSC_0,
+	DSC_1,
+	DSC_2,
+	DSC_3,
+	DSC_4,
+	DSC_5,
+	DSC_MAX
+};
+
+enum dpu_cdm {
+	CDM_0 = 1,
+	CDM_MAX
+};
+
+enum dpu_pingpong {
+	PINGPONG_NONE,
+	PINGPONG_0,
+	PINGPONG_1,
+	PINGPONG_2,
+	PINGPONG_3,
+	PINGPONG_4,
+	PINGPONG_5,
+	PINGPONG_6,
+	PINGPONG_7,
+	PINGPONG_8,
+	PINGPONG_9,
+	PINGPONG_S0,
+	PINGPONG_MAX
+};
+
+enum dpu_merge_3d {
+	MERGE_3D_0 = 1,
+	MERGE_3D_1,
+	MERGE_3D_2,
+	MERGE_3D_3,
+	MERGE_3D_4,
+	MERGE_3D_MAX
+};
+
+enum dpu_intf {
+	INTF_0 = 1,
+	INTF_1,
+	INTF_2,
+	INTF_3,
+	INTF_4,
+	INTF_5,
+	INTF_6,
+	INTF_7,
+	INTF_8,
+	INTF_MAX
+};
+
+/*
+ * Historically these values correspond to the values written to the
+ * DISP_INTF_SEL register, which had to programmed manually. On newer MDP
+ * generations this register is NOP, but we keep the values for historical
+ * reasons.
+ */
+enum dpu_intf_type {
+	INTF_NONE = 0x0,
+	INTF_DSI = 0x1,
+	INTF_HDMI = 0x3,
+	INTF_LCDC = 0x5,
+	/* old eDP found on 8x74 and 8x84 */
+	INTF_EDP = 0x9,
+	/* both DP and eDP,  handled by the new DP driver */
+	INTF_DP = 0xa,
+
+	/* virtual interfaces */
+	INTF_WB = 0x100,
+};
+
+enum dpu_intf_mode {
+	INTF_MODE_NONE = 0,
+	INTF_MODE_CMD,
+	INTF_MODE_VIDEO,
+	INTF_MODE_WB_BLOCK,
+	INTF_MODE_WB_LINE,
+	INTF_MODE_MAX
+};
+
+enum dpu_wb {
+	WB_0 = 1,
+	WB_1,
+	WB_2,
+	WB_3,
+	WB_MAX
+};
+
+enum dpu_cwb {
+	CWB_0 = 0x1,
+	CWB_1,
+	CWB_2,
+	CWB_3,
+	CWB_MAX
+};
+
+enum dpu_wd_timer {
+	WD_TIMER_0 = 0x1,
+	WD_TIMER_1,
+	WD_TIMER_2,
+	WD_TIMER_3,
+	WD_TIMER_4,
+	WD_TIMER_5,
+	WD_TIMER_MAX
+};
+
+enum dpu_vbif {
+	VBIF_RT,
+	VBIF_NRT,
+	VBIF_MAX,
+};
+
+/**
+ * DPU HW,Component order color map
+ */
+enum {
+	C0_G_Y = 0,
+	C1_B_Cb = 1,
+	C2_R_Cr = 2,
+	C3_ALPHA = 3
+};
+
+/**
+ * enum dpu_plane_type - defines how the color component pixel packing
+ * @DPU_PLANE_INTERLEAVED   : Color components in single plane
+ * @DPU_PLANE_PLANAR        : Color component in separate planes
+ * @DPU_PLANE_PSEUDO_PLANAR : Chroma components interleaved in separate plane
+ */
+enum dpu_plane_type {
+	DPU_PLANE_INTERLEAVED,
+	DPU_PLANE_PLANAR,
+	DPU_PLANE_PSEUDO_PLANAR,
+};
+
+/**
+ * enum dpu_chroma_samp_type - chroma sub-samplng type
+ * @DPU_CHROMA_RGB   : No chroma subsampling
+ * @DPU_CHROMA_H2V1  : Chroma pixels are horizontally subsampled
+ * @DPU_CHROMA_H1V2  : Chroma pixels are vertically subsampled
+ * @DPU_CHROMA_420   : 420 subsampling
+ */
+enum dpu_chroma_samp_type {
+	DPU_CHROMA_RGB,
+	DPU_CHROMA_H2V1,
+	DPU_CHROMA_H1V2,
+	DPU_CHROMA_420
+};
+
+/**
+ * dpu_fetch_type - Defines How DPU HW fetches data
+ * @DPU_FETCH_LINEAR   : fetch is line by line
+ * @DPU_FETCH_TILE     : fetches data in Z order from a tile
+ * @DPU_FETCH_UBWC     : fetch and decompress data
+ */
+enum dpu_fetch_type {
+	DPU_FETCH_LINEAR,
+	DPU_FETCH_TILE,
+	DPU_FETCH_UBWC
+};
+
+/**
+ * Value of enum chosen to fit the number of bits
+ * expected by the HW programming.
+ */
+enum {
+	COLOR_ALPHA_1BIT = 0,
+	COLOR_ALPHA_4BIT = 1,
+	COLOR_4BIT = 0,
+	COLOR_5BIT = 1, /* No 5-bit Alpha */
+	COLOR_6BIT = 2, /* 6-Bit Alpha also = 2 */
+	COLOR_8BIT = 3, /* 8-Bit Alpha also = 3 */
+};
+
+/**
+ * enum dpu_3d_blend_mode
+ * Desribes how the 3d data is blended
+ * @BLEND_3D_NONE      : 3d blending not enabled
+ * @BLEND_3D_FRAME_INT : Frame interleaving
+ * @BLEND_3D_H_ROW_INT : Horizontal row interleaving
+ * @BLEND_3D_V_ROW_INT : vertical row interleaving
+ * @BLEND_3D_COL_INT   : column interleaving
+ * @BLEND_3D_MAX       :
+ */
+enum dpu_3d_blend_mode {
+	BLEND_3D_NONE = 0,
+	BLEND_3D_FRAME_INT,
+	BLEND_3D_H_ROW_INT,
+	BLEND_3D_V_ROW_INT,
+	BLEND_3D_COL_INT,
+	BLEND_3D_MAX
+};
+
+/** struct dpu_format - defines the format configuration which
+ * allows DPU HW to correctly fetch and decode the format
+ * @base: base msm_format structure containing fourcc code
+ * @fetch_planes: how the color components are packed in pixel format
+ * @element: element color ordering
+ * @bits: element bit widths
+ * @chroma_sample: chroma sub-samplng type
+ * @unpack_align_msb: unpack aligned, 0 to LSB, 1 to MSB
+ * @unpack_tight: 0 for loose, 1 for tight
+ * @unpack_count: 0 = 1 component, 1 = 2 component
+ * @bpp: bytes per pixel
+ * @alpha_enable: whether the format has an alpha channel
+ * @num_planes: number of planes (including meta data planes)
+ * @fetch_mode: linear, tiled, or ubwc hw fetch behavior
+ * @flag: usage bit flags
+ * @tile_width: format tile width
+ * @tile_height: format tile height
+ */
+struct dpu_format {
+	struct msm_format base;
+	enum dpu_plane_type fetch_planes;
+	u8 element[DPU_MAX_PLANES];
+	u8 bits[DPU_MAX_PLANES];
+	enum dpu_chroma_samp_type chroma_sample;
+	u8 unpack_align_msb;
+	u8 unpack_tight;
+	u8 unpack_count;
+	u8 bpp;
+	u8 alpha_enable;
+	u8 num_planes;
+	enum dpu_fetch_type fetch_mode;
+	DECLARE_BITMAP(flag, DPU_FORMAT_FLAG_BIT_MAX);
+	u16 tile_width;
+	u16 tile_height;
+};
+#define to_dpu_format(x) container_of(x, struct dpu_format, base)
+
+/**
+ * struct dpu_hw_fmt_layout - format information of the source pixel data
+ * @format: pixel format parameters
+ * @num_planes: number of planes (including meta data planes)
+ * @width: image width
+ * @height: image height
+ * @total_size: total size in bytes
+ * @plane_addr: address of each plane
+ * @plane_size: length of each plane
+ * @plane_pitch: pitch of each plane
+ */
+struct dpu_hw_fmt_layout {
+	const struct dpu_format *format;
+	uint32_t num_planes;
+	uint32_t width;
+	uint32_t height;
+	uint32_t total_size;
+	uint32_t plane_addr[DPU_MAX_PLANES];
+	uint32_t plane_size[DPU_MAX_PLANES];
+	uint32_t plane_pitch[DPU_MAX_PLANES];
+};
+
+struct dpu_csc_cfg {
+	/* matrix coefficients in S15.16 format */
+	uint32_t csc_mv[DPU_CSC_MATRIX_COEFF_SIZE];
+	uint32_t csc_pre_bv[DPU_CSC_BIAS_SIZE];
+	uint32_t csc_post_bv[DPU_CSC_BIAS_SIZE];
+	uint32_t csc_pre_lv[DPU_CSC_CLAMP_SIZE];
+	uint32_t csc_post_lv[DPU_CSC_CLAMP_SIZE];
+};
+
+/**
+ * struct dpu_mdss_color - mdss color description
+ * color 0 : green
+ * color 1 : blue
+ * color 2 : red
+ * color 3 : alpha
+ */
+struct dpu_mdss_color {
+	u32 color_0;
+	u32 color_1;
+	u32 color_2;
+	u32 color_3;
+};
+
+/*
+ * Define bit masks for h/w logging.
+ */
+#define DPU_DBG_MASK_NONE     (1 << 0)
+#define DPU_DBG_MASK_INTF     (1 << 1)
+#define DPU_DBG_MASK_LM       (1 << 2)
+#define DPU_DBG_MASK_CTL      (1 << 3)
+#define DPU_DBG_MASK_PINGPONG (1 << 4)
+#define DPU_DBG_MASK_SSPP     (1 << 5)
+#define DPU_DBG_MASK_WB       (1 << 6)
+#define DPU_DBG_MASK_TOP      (1 << 7)
+#define DPU_DBG_MASK_VBIF     (1 << 8)
+#define DPU_DBG_MASK_ROT      (1 << 9)
+#define DPU_DBG_MASK_DSPP     (1 << 10)
+#define DPU_DBG_MASK_DSC      (1 << 11)
+#define DPU_DBG_MASK_CDM      (1 << 12)
+
+/**
+ * struct dpu_hw_tear_check - Struct contains parameters to configure
+ * tear-effect module. This structure is used to configure tear-check
+ * logic present either in ping-pong or in interface module.
+ * @vsync_count:        Ratio of MDP VSYNC clk freq(Hz) to refresh rate divided
+ *                      by no of lines
+ * @sync_cfg_height:    Total vertical lines (display height - 1)
+ * @vsync_init_val:     Init value to which the read pointer gets loaded at
+ *                      vsync edge
+ * @sync_threshold_start:    Read pointer threshold start ROI for write operation
+ * @sync_threshold_continue: The minimum number of lines the write pointer
+ *                           needs to be above the read pointer
+ * @start_pos:          The position from which the start_threshold value is added
+ * @rd_ptr_irq:         The read pointer line at which interrupt has to be generated
+ * @hw_vsync_mode:      Sync with external frame sync input
+ */
+struct dpu_hw_tear_check {
+	/*
+	 * This is ratio of MDP VSYNC clk freq(Hz) to
+	 * refresh rate divided by no of lines
+	 */
+	u32 vsync_count;
+	u32 sync_cfg_height;
+	u32 vsync_init_val;
+	u32 sync_threshold_start;
+	u32 sync_threshold_continue;
+	u32 start_pos;
+	u32 rd_ptr_irq;
+	u8 hw_vsync_mode;
+};
+
+/**
+ * struct dpu_hw_pp_vsync_info - Struct contains parameters to configure
+ * read and write pointers for command mode panels
+ * @rd_ptr_init_val:    Value of rd pointer at vsync edge
+ * @rd_ptr_frame_count: Num frames sent since enabling interface
+ * @rd_ptr_line_count:  Current line on panel (rd ptr)
+ * @wr_ptr_line_count:  Current line within pp fifo (wr ptr)
+ * @intf_frame_count:   Frames read from intf
+ */
+struct dpu_hw_pp_vsync_info {
+	u32 rd_ptr_init_val;
+	u32 rd_ptr_frame_count;
+	u32 rd_ptr_line_count;
+	u32 wr_ptr_line_count;
+	u32 intf_frame_count;
+};
+
+#endif  /* _DPU_HW_MDSS_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_merge3d.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_merge3d.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/iopoll.h>
+
+#include <drm/drm_managed.h>
+
+#include "dpu_hw_mdss.h"
+#include "dpu_hwio.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_merge3d.h"
+#include "dpu_kms.h"
+#include "dpu_trace.h"
+
+#define MERGE_3D_MUX  0x000
+#define MERGE_3D_MODE 0x004
+
+static void dpu_hw_merge_3d_setup_3d_mode(struct dpu_hw_merge_3d *merge_3d,
+			enum dpu_3d_blend_mode mode_3d)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 data;
+
+
+	c = &merge_3d->hw;
+	if (mode_3d == BLEND_3D_NONE) {
+		DPU_REG_WRITE(c, MERGE_3D_MODE, 0);
+		DPU_REG_WRITE(c, MERGE_3D_MUX, 0);
+	} else {
+		data = BIT(0) | ((mode_3d - 1) << 1);
+		DPU_REG_WRITE(c, MERGE_3D_MODE, data);
+	}
+}
+
+static void _setup_merge_3d_ops(struct dpu_hw_merge_3d *c,
+				unsigned long features)
+{
+	c->ops.setup_3d_mode = dpu_hw_merge_3d_setup_3d_mode;
+};
+
+struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(struct drm_device *dev,
+					     const struct dpu_merge_3d_cfg *cfg,
+					     void __iomem *addr)
+{
+	struct dpu_hw_merge_3d *c;
+
+	c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
+	if (!c)
+		return ERR_PTR(-ENOMEM);
+
+	c->hw.blk_addr = addr + cfg->base;
+	c->hw.log_mask = DPU_DBG_MASK_PINGPONG;
+
+	c->idx = cfg->id;
+	c->caps = cfg;
+	_setup_merge_3d_ops(c, c->caps->features);
+
+	return c;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_merge3d.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_merge3d.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_MERGE3D_H
+#define _DPU_HW_MERGE3D_H
+
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_util.h"
+
+struct dpu_hw_merge_3d;
+
+/**
+ *
+ * struct dpu_hw_merge_3d_ops : Interface to the merge_3d Hw driver functions
+ *  Assumption is these functions will be called after clocks are enabled
+ *  @setup_3d_mode : enable 3D merge
+ */
+struct dpu_hw_merge_3d_ops {
+	void (*setup_3d_mode)(struct dpu_hw_merge_3d *merge_3d,
+			enum dpu_3d_blend_mode mode_3d);
+
+};
+
+struct dpu_hw_merge_3d {
+	struct dpu_hw_blk base;
+	struct dpu_hw_blk_reg_map hw;
+
+	/* merge_3d */
+	enum dpu_merge_3d idx;
+	const struct dpu_merge_3d_cfg *caps;
+
+	/* ops */
+	struct dpu_hw_merge_3d_ops ops;
+};
+
+/**
+ * to_dpu_hw_merge_3d - convert base object dpu_hw_base to container
+ * @hw: Pointer to base hardware block
+ * return: Pointer to hardware block container
+ */
+static inline struct dpu_hw_merge_3d *to_dpu_hw_merge_3d(struct dpu_hw_blk *hw)
+{
+	return container_of(hw, struct dpu_hw_merge_3d, base);
+}
+
+/**
+ * dpu_hw_merge_3d_init() - Initializes the merge_3d driver for the passed
+ * merge3d catalog entry.
+ * @dev:  Corresponding device for devres management
+ * @cfg:  Pingpong catalog entry for which driver object is required
+ * @addr: Mapped register io address of MDP
+ * Return: Error code or allocated dpu_hw_merge_3d context
+ */
+struct dpu_hw_merge_3d *dpu_hw_merge_3d_init(struct drm_device *dev,
+					     const struct dpu_merge_3d_cfg *cfg,
+					     void __iomem *addr);
+
+#endif /*_DPU_HW_MERGE3D_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_pingpong.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_pingpong.c
@@ -0,0 +1,323 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/iopoll.h>
+
+#include <drm/drm_managed.h>
+
+#include "dpu_hw_mdss.h"
+#include "dpu_hwio.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_pingpong.h"
+#include "dpu_kms.h"
+#include "dpu_trace.h"
+
+#define PP_TEAR_CHECK_EN                0x000
+#define PP_SYNC_CONFIG_VSYNC            0x004
+#define PP_SYNC_CONFIG_HEIGHT           0x008
+#define PP_SYNC_WRCOUNT                 0x00C
+#define PP_VSYNC_INIT_VAL               0x010
+#define PP_INT_COUNT_VAL                0x014
+#define PP_SYNC_THRESH                  0x018
+#define PP_START_POS                    0x01C
+#define PP_RD_PTR_IRQ                   0x020
+#define PP_WR_PTR_IRQ                   0x024
+#define PP_OUT_LINE_COUNT               0x028
+#define PP_LINE_COUNT                   0x02C
+#define PP_AUTOREFRESH_CONFIG           0x030
+
+#define PP_FBC_MODE                     0x034
+#define PP_FBC_BUDGET_CTL               0x038
+#define PP_FBC_LOSSY_MODE               0x03C
+#define PP_DSC_MODE                     0x0a0
+#define PP_DCE_DATA_IN_SWAP             0x0ac
+#define PP_DCE_DATA_OUT_SWAP            0x0c8
+
+#define PP_DITHER_EN			0x000
+#define PP_DITHER_BITDEPTH		0x004
+#define PP_DITHER_MATRIX		0x008
+
+#define DITHER_DEPTH_MAP_INDEX 9
+
+static u32 dither_depth_map[DITHER_DEPTH_MAP_INDEX] = {
+	0, 0, 0, 0, 0, 0, 0, 1, 2
+};
+
+static void dpu_hw_pp_setup_dither(struct dpu_hw_pingpong *pp,
+				    struct dpu_hw_dither_cfg *cfg)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 i, base, data = 0;
+
+	c = &pp->hw;
+	base = pp->caps->sblk->dither.base;
+	if (!cfg) {
+		DPU_REG_WRITE(c, base + PP_DITHER_EN, 0);
+		return;
+	}
+
+	data = dither_depth_map[cfg->c0_bitdepth] & REG_MASK(2);
+	data |= (dither_depth_map[cfg->c1_bitdepth] & REG_MASK(2)) << 2;
+	data |= (dither_depth_map[cfg->c2_bitdepth] & REG_MASK(2)) << 4;
+	data |= (dither_depth_map[cfg->c3_bitdepth] & REG_MASK(2)) << 6;
+	data |= (cfg->temporal_en) ? (1 << 8) : 0;
+
+	DPU_REG_WRITE(c, base + PP_DITHER_BITDEPTH, data);
+
+	for (i = 0; i < DITHER_MATRIX_SZ - 3; i += 4) {
+		data = (cfg->matrix[i] & REG_MASK(4)) |
+			((cfg->matrix[i + 1] & REG_MASK(4)) << 4) |
+			((cfg->matrix[i + 2] & REG_MASK(4)) << 8) |
+			((cfg->matrix[i + 3] & REG_MASK(4)) << 12);
+		DPU_REG_WRITE(c, base + PP_DITHER_MATRIX + i, data);
+	}
+	DPU_REG_WRITE(c, base + PP_DITHER_EN, 1);
+}
+
+static int dpu_hw_pp_enable_te(struct dpu_hw_pingpong *pp,
+		struct dpu_hw_tear_check *te)
+{
+	struct dpu_hw_blk_reg_map *c;
+	int cfg;
+
+	if (!pp || !te)
+		return -EINVAL;
+	c = &pp->hw;
+
+	cfg = BIT(19); /*VSYNC_COUNTER_EN */
+	if (te->hw_vsync_mode)
+		cfg |= BIT(20);
+
+	cfg |= te->vsync_count;
+
+	DPU_REG_WRITE(c, PP_SYNC_CONFIG_VSYNC, cfg);
+	DPU_REG_WRITE(c, PP_SYNC_CONFIG_HEIGHT, te->sync_cfg_height);
+	DPU_REG_WRITE(c, PP_VSYNC_INIT_VAL, te->vsync_init_val);
+	DPU_REG_WRITE(c, PP_RD_PTR_IRQ, te->rd_ptr_irq);
+	DPU_REG_WRITE(c, PP_START_POS, te->start_pos);
+	DPU_REG_WRITE(c, PP_SYNC_THRESH,
+			((te->sync_threshold_continue << 16) |
+			 te->sync_threshold_start));
+	DPU_REG_WRITE(c, PP_SYNC_WRCOUNT,
+			(te->start_pos + te->sync_threshold_start + 1));
+
+	DPU_REG_WRITE(c, PP_TEAR_CHECK_EN, 1);
+
+	return 0;
+}
+
+static void dpu_hw_pp_setup_autorefresh_config(struct dpu_hw_pingpong *pp,
+					       u32 frame_count, bool enable)
+{
+	DPU_REG_WRITE(&pp->hw, PP_AUTOREFRESH_CONFIG,
+		      enable ? (BIT(31) | frame_count) : 0);
+}
+
+/*
+ * dpu_hw_pp_get_autorefresh_config - Get autorefresh config from HW
+ * @pp:          DPU pingpong structure
+ * @frame_count: Used to return the current frame count from hw
+ *
+ * Returns: True if autorefresh enabled, false if disabled.
+ */
+static bool dpu_hw_pp_get_autorefresh_config(struct dpu_hw_pingpong *pp,
+					     u32 *frame_count)
+{
+	u32 val = DPU_REG_READ(&pp->hw, PP_AUTOREFRESH_CONFIG);
+	if (frame_count != NULL)
+		*frame_count = val & 0xffff;
+	return !!((val & BIT(31)) >> 31);
+}
+
+static int dpu_hw_pp_disable_te(struct dpu_hw_pingpong *pp)
+{
+	struct dpu_hw_blk_reg_map *c;
+
+	if (!pp)
+		return -EINVAL;
+	c = &pp->hw;
+
+	DPU_REG_WRITE(c, PP_TEAR_CHECK_EN, 0);
+	return 0;
+}
+
+static int dpu_hw_pp_connect_external_te(struct dpu_hw_pingpong *pp,
+		bool enable_external_te)
+{
+	struct dpu_hw_blk_reg_map *c = &pp->hw;
+	u32 cfg;
+	int orig;
+
+	if (!pp)
+		return -EINVAL;
+
+	c = &pp->hw;
+	cfg = DPU_REG_READ(c, PP_SYNC_CONFIG_VSYNC);
+	orig = (bool)(cfg & BIT(20));
+	if (enable_external_te)
+		cfg |= BIT(20);
+	else
+		cfg &= ~BIT(20);
+	DPU_REG_WRITE(c, PP_SYNC_CONFIG_VSYNC, cfg);
+	trace_dpu_pp_connect_ext_te(pp->idx - PINGPONG_0, cfg);
+
+	return orig;
+}
+
+static int dpu_hw_pp_get_vsync_info(struct dpu_hw_pingpong *pp,
+		struct dpu_hw_pp_vsync_info *info)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 val;
+
+	if (!pp || !info)
+		return -EINVAL;
+	c = &pp->hw;
+
+	val = DPU_REG_READ(c, PP_VSYNC_INIT_VAL);
+	info->rd_ptr_init_val = val & 0xffff;
+
+	val = DPU_REG_READ(c, PP_INT_COUNT_VAL);
+	info->rd_ptr_frame_count = (val & 0xffff0000) >> 16;
+	info->rd_ptr_line_count = val & 0xffff;
+
+	val = DPU_REG_READ(c, PP_LINE_COUNT);
+	info->wr_ptr_line_count = val & 0xffff;
+
+	return 0;
+}
+
+static u32 dpu_hw_pp_get_line_count(struct dpu_hw_pingpong *pp)
+{
+	struct dpu_hw_blk_reg_map *c = &pp->hw;
+	u32 height, init;
+	u32 line = 0xFFFF;
+
+	if (!pp)
+		return 0;
+	c = &pp->hw;
+
+	init = DPU_REG_READ(c, PP_VSYNC_INIT_VAL) & 0xFFFF;
+	height = DPU_REG_READ(c, PP_SYNC_CONFIG_HEIGHT) & 0xFFFF;
+
+	if (height < init)
+		return line;
+
+	line = DPU_REG_READ(c, PP_INT_COUNT_VAL) & 0xFFFF;
+
+	if (line < init)
+		line += (0xFFFF - init);
+	else
+		line -= init;
+
+	return line;
+}
+
+static void dpu_hw_pp_disable_autorefresh(struct dpu_hw_pingpong *pp,
+					  uint32_t encoder_id, u16 vdisplay)
+{
+	struct dpu_hw_pp_vsync_info info;
+	int trial = 0;
+
+	/* If autorefresh is already disabled, we have nothing to do */
+	if (!dpu_hw_pp_get_autorefresh_config(pp, NULL))
+		return;
+
+	/*
+	 * If autorefresh is enabled, disable it and make sure it is safe to
+	 * proceed with current frame commit/push. Sequence followed is,
+	 * 1. Disable TE
+	 * 2. Disable autorefresh config
+	 * 4. Poll for frame transfer ongoing to be false
+	 * 5. Enable TE back
+	 */
+
+	dpu_hw_pp_connect_external_te(pp, false);
+	dpu_hw_pp_setup_autorefresh_config(pp, 0, false);
+
+	do {
+		udelay(DPU_ENC_MAX_POLL_TIMEOUT_US);
+		if ((trial * DPU_ENC_MAX_POLL_TIMEOUT_US)
+				> (KICKOFF_TIMEOUT_MS * USEC_PER_MSEC)) {
+			DPU_ERROR("enc%d pp%d disable autorefresh failed\n",
+				  encoder_id, pp->idx - PINGPONG_0);
+			break;
+		}
+
+		trial++;
+
+		dpu_hw_pp_get_vsync_info(pp, &info);
+	} while (info.wr_ptr_line_count > 0 &&
+		 info.wr_ptr_line_count < vdisplay);
+
+	dpu_hw_pp_connect_external_te(pp, true);
+
+	DPU_DEBUG("enc%d pp%d disabled autorefresh\n",
+		  encoder_id, pp->idx - PINGPONG_0);
+}
+
+static int dpu_hw_pp_dsc_enable(struct dpu_hw_pingpong *pp)
+{
+	struct dpu_hw_blk_reg_map *c = &pp->hw;
+
+	DPU_REG_WRITE(c, PP_DSC_MODE, 1);
+	return 0;
+}
+
+static void dpu_hw_pp_dsc_disable(struct dpu_hw_pingpong *pp)
+{
+	struct dpu_hw_blk_reg_map *c = &pp->hw;
+
+	DPU_REG_WRITE(c, PP_DSC_MODE, 0);
+}
+
+static int dpu_hw_pp_setup_dsc(struct dpu_hw_pingpong *pp)
+{
+	struct dpu_hw_blk_reg_map *pp_c = &pp->hw;
+	int data;
+
+	data = DPU_REG_READ(pp_c, PP_DCE_DATA_OUT_SWAP);
+	data |= BIT(18); /* endian flip */
+	DPU_REG_WRITE(pp_c, PP_DCE_DATA_OUT_SWAP, data);
+	return 0;
+}
+
+struct dpu_hw_pingpong *dpu_hw_pingpong_init(struct drm_device *dev,
+					     const struct dpu_pingpong_cfg *cfg,
+					     void __iomem *addr,
+					     const struct dpu_mdss_version *mdss_rev)
+{
+	struct dpu_hw_pingpong *c;
+
+	c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
+	if (!c)
+		return ERR_PTR(-ENOMEM);
+
+	c->hw.blk_addr = addr + cfg->base;
+	c->hw.log_mask = DPU_DBG_MASK_PINGPONG;
+
+	c->idx = cfg->id;
+	c->caps = cfg;
+
+	if (mdss_rev->core_major_ver < 5) {
+		WARN_ON(!cfg->intr_rdptr);
+
+		c->ops.enable_tearcheck = dpu_hw_pp_enable_te;
+		c->ops.disable_tearcheck = dpu_hw_pp_disable_te;
+		c->ops.connect_external_te = dpu_hw_pp_connect_external_te;
+		c->ops.get_line_count = dpu_hw_pp_get_line_count;
+		c->ops.disable_autorefresh = dpu_hw_pp_disable_autorefresh;
+	}
+
+	if (test_bit(DPU_PINGPONG_DSC, &cfg->features)) {
+		c->ops.setup_dsc = dpu_hw_pp_setup_dsc;
+		c->ops.enable_dsc = dpu_hw_pp_dsc_enable;
+		c->ops.disable_dsc = dpu_hw_pp_dsc_disable;
+	}
+
+	if (test_bit(DPU_PINGPONG_DITHER, &cfg->features))
+		c->ops.setup_dither = dpu_hw_pp_setup_dither;
+
+	return c;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_pingpong.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_pingpong.h
@@ -0,0 +1,135 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_PINGPONG_H
+#define _DPU_HW_PINGPONG_H
+
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_util.h"
+
+#define DITHER_MATRIX_SZ 16
+
+struct dpu_hw_pingpong;
+
+/**
+ * struct dpu_hw_dither_cfg - dither feature structure
+ * @flags: for customizing operations
+ * @temporal_en: temperal dither enable
+ * @c0_bitdepth: c0 component bit depth
+ * @c1_bitdepth: c1 component bit depth
+ * @c2_bitdepth: c2 component bit depth
+ * @c3_bitdepth: c2 component bit depth
+ * @matrix: dither strength matrix
+ */
+struct dpu_hw_dither_cfg {
+	u64 flags;
+	u32 temporal_en;
+	u32 c0_bitdepth;
+	u32 c1_bitdepth;
+	u32 c2_bitdepth;
+	u32 c3_bitdepth;
+	u32 matrix[DITHER_MATRIX_SZ];
+};
+
+/**
+ *
+ * struct dpu_hw_pingpong_ops : Interface to the pingpong Hw driver functions
+ *  Assumption is these functions will be called after clocks are enabled
+ *  @enable_tearcheck: program and enable tear check block
+ *  @disable_tearcheck: disable able tear check block
+ *  @setup_dither : function to program the dither hw block
+ *  @get_line_count: obtain current vertical line counter
+ */
+struct dpu_hw_pingpong_ops {
+	/**
+	 * enables vysnc generation and sets up init value of
+	 * read pointer and programs the tear check cofiguration
+	 */
+	int (*enable_tearcheck)(struct dpu_hw_pingpong *pp,
+			struct dpu_hw_tear_check *cfg);
+
+	/**
+	 * disables tear check block
+	 */
+	int (*disable_tearcheck)(struct dpu_hw_pingpong *pp);
+
+	/**
+	 * read, modify, write to either set or clear listening to external TE
+	 * @Return: 1 if TE was originally connected, 0 if not, or -ERROR
+	 */
+	int (*connect_external_te)(struct dpu_hw_pingpong *pp,
+			bool enable_external_te);
+
+	/**
+	 * Obtain current vertical line counter
+	 */
+	u32 (*get_line_count)(struct dpu_hw_pingpong *pp);
+
+	/**
+	 * Disable autorefresh if enabled
+	 */
+	void (*disable_autorefresh)(struct dpu_hw_pingpong *pp, uint32_t encoder_id, u16 vdisplay);
+
+	/**
+	 * Setup dither matix for pingpong block
+	 */
+	void (*setup_dither)(struct dpu_hw_pingpong *pp,
+			struct dpu_hw_dither_cfg *cfg);
+	/**
+	 * Enable DSC
+	 */
+	int (*enable_dsc)(struct dpu_hw_pingpong *pp);
+
+	/**
+	 * Disable DSC
+	 */
+	void (*disable_dsc)(struct dpu_hw_pingpong *pp);
+
+	/**
+	 * Setup DSC
+	 */
+	int (*setup_dsc)(struct dpu_hw_pingpong *pp);
+};
+
+struct dpu_hw_merge_3d;
+
+struct dpu_hw_pingpong {
+	struct dpu_hw_blk base;
+	struct dpu_hw_blk_reg_map hw;
+
+	/* pingpong */
+	enum dpu_pingpong idx;
+	const struct dpu_pingpong_cfg *caps;
+	struct dpu_hw_merge_3d *merge_3d;
+
+	/* ops */
+	struct dpu_hw_pingpong_ops ops;
+};
+
+/**
+ * to_dpu_hw_pingpong - convert base object dpu_hw_base to container
+ * @hw: Pointer to base hardware block
+ * return: Pointer to hardware block container
+ */
+static inline struct dpu_hw_pingpong *to_dpu_hw_pingpong(struct dpu_hw_blk *hw)
+{
+	return container_of(hw, struct dpu_hw_pingpong, base);
+}
+
+/**
+ * dpu_hw_pingpong_init() - initializes the pingpong driver for the passed
+ * pingpong catalog entry.
+ * @dev:  Corresponding device for devres management
+ * @cfg:  Pingpong catalog entry for which driver object is required
+ * @addr: Mapped register io address of MDP
+ * @mdss_rev: dpu core's major and minor versions
+ * Return: Error code or allocated dpu_hw_pingpong context
+ */
+struct dpu_hw_pingpong *dpu_hw_pingpong_init(struct drm_device *dev,
+					     const struct dpu_pingpong_cfg *cfg,
+					     void __iomem *addr,
+					     const struct dpu_mdss_version *mdss_rev);
+
+#endif /*_DPU_HW_PINGPONG_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_sspp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_sspp.c
@@ -0,0 +1,698 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#include "dpu_hwio.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_lm.h"
+#include "dpu_hw_sspp.h"
+#include "dpu_kms.h"
+
+#include "msm_mdss.h"
+
+#include <drm/drm_file.h>
+#include <drm/drm_managed.h>
+
+#define DPU_FETCH_CONFIG_RESET_VALUE   0x00000087
+
+/* SSPP registers */
+#define SSPP_SRC_SIZE                      0x00
+#define SSPP_SRC_XY                        0x08
+#define SSPP_OUT_SIZE                      0x0c
+#define SSPP_OUT_XY                        0x10
+#define SSPP_SRC0_ADDR                     0x14
+#define SSPP_SRC1_ADDR                     0x18
+#define SSPP_SRC2_ADDR                     0x1C
+#define SSPP_SRC3_ADDR                     0x20
+#define SSPP_SRC_YSTRIDE0                  0x24
+#define SSPP_SRC_YSTRIDE1                  0x28
+#define SSPP_SRC_FORMAT                    0x30
+#define SSPP_SRC_UNPACK_PATTERN            0x34
+#define SSPP_SRC_OP_MODE                   0x38
+#define SSPP_SRC_CONSTANT_COLOR            0x3c
+#define SSPP_EXCL_REC_CTL                  0x40
+#define SSPP_UBWC_STATIC_CTRL              0x44
+#define SSPP_FETCH_CONFIG                  0x48
+#define SSPP_DANGER_LUT                    0x60
+#define SSPP_SAFE_LUT                      0x64
+#define SSPP_CREQ_LUT                      0x68
+#define SSPP_QOS_CTRL                      0x6C
+#define SSPP_SRC_ADDR_SW_STATUS            0x70
+#define SSPP_CREQ_LUT_0                    0x74
+#define SSPP_CREQ_LUT_1                    0x78
+#define SSPP_DECIMATION_CONFIG             0xB4
+#define SSPP_SW_PIX_EXT_C0_LR              0x100
+#define SSPP_SW_PIX_EXT_C0_TB              0x104
+#define SSPP_SW_PIX_EXT_C0_REQ_PIXELS      0x108
+#define SSPP_SW_PIX_EXT_C1C2_LR            0x110
+#define SSPP_SW_PIX_EXT_C1C2_TB            0x114
+#define SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS    0x118
+#define SSPP_SW_PIX_EXT_C3_LR              0x120
+#define SSPP_SW_PIX_EXT_C3_TB              0x124
+#define SSPP_SW_PIX_EXT_C3_REQ_PIXELS      0x128
+#define SSPP_TRAFFIC_SHAPER                0x130
+#define SSPP_CDP_CNTL                      0x134
+#define SSPP_UBWC_ERROR_STATUS             0x138
+#define SSPP_CDP_CNTL_REC1                 0x13c
+#define SSPP_TRAFFIC_SHAPER_PREFILL        0x150
+#define SSPP_TRAFFIC_SHAPER_REC1_PREFILL   0x154
+#define SSPP_TRAFFIC_SHAPER_REC1           0x158
+#define SSPP_OUT_SIZE_REC1                 0x160
+#define SSPP_OUT_XY_REC1                   0x164
+#define SSPP_SRC_XY_REC1                   0x168
+#define SSPP_SRC_SIZE_REC1                 0x16C
+#define SSPP_MULTIRECT_OPMODE              0x170
+#define SSPP_SRC_FORMAT_REC1               0x174
+#define SSPP_SRC_UNPACK_PATTERN_REC1       0x178
+#define SSPP_SRC_OP_MODE_REC1              0x17C
+#define SSPP_SRC_CONSTANT_COLOR_REC1       0x180
+#define SSPP_EXCL_REC_SIZE_REC1            0x184
+#define SSPP_EXCL_REC_XY_REC1              0x188
+#define SSPP_EXCL_REC_SIZE                 0x1B4
+#define SSPP_EXCL_REC_XY                   0x1B8
+#define SSPP_CLK_CTRL                      0x330
+
+/* SSPP_SRC_OP_MODE & OP_MODE_REC1 */
+#define MDSS_MDP_OP_DEINTERLACE            BIT(22)
+#define MDSS_MDP_OP_DEINTERLACE_ODD        BIT(23)
+#define MDSS_MDP_OP_IGC_ROM_1              BIT(18)
+#define MDSS_MDP_OP_IGC_ROM_0              BIT(17)
+#define MDSS_MDP_OP_IGC_EN                 BIT(16)
+#define MDSS_MDP_OP_FLIP_UD                BIT(14)
+#define MDSS_MDP_OP_FLIP_LR                BIT(13)
+#define MDSS_MDP_OP_BWC_EN                 BIT(0)
+#define MDSS_MDP_OP_PE_OVERRIDE            BIT(31)
+#define MDSS_MDP_OP_BWC_LOSSLESS           (0 << 1)
+#define MDSS_MDP_OP_BWC_Q_HIGH             (1 << 1)
+#define MDSS_MDP_OP_BWC_Q_MED              (2 << 1)
+
+/* SSPP_QOS_CTRL */
+#define SSPP_QOS_CTRL_VBLANK_EN            BIT(16)
+#define SSPP_QOS_CTRL_DANGER_SAFE_EN       BIT(0)
+#define SSPP_QOS_CTRL_DANGER_VBLANK_MASK   0x3
+#define SSPP_QOS_CTRL_DANGER_VBLANK_OFF    4
+#define SSPP_QOS_CTRL_CREQ_VBLANK_MASK     0x3
+#define SSPP_QOS_CTRL_CREQ_VBLANK_OFF      20
+
+/* DPU_SSPP_SCALER_QSEED2 */
+#define SSPP_VIG_OP_MODE                   0x0
+#define SCALE_CONFIG                       0x04
+#define COMP0_3_PHASE_STEP_X               0x10
+#define COMP0_3_PHASE_STEP_Y               0x14
+#define COMP1_2_PHASE_STEP_X               0x18
+#define COMP1_2_PHASE_STEP_Y               0x1c
+#define COMP0_3_INIT_PHASE_X               0x20
+#define COMP0_3_INIT_PHASE_Y               0x24
+#define COMP1_2_INIT_PHASE_X               0x28
+#define COMP1_2_INIT_PHASE_Y               0x2C
+#define VIG_0_QSEED2_SHARP                 0x30
+
+/* SSPP_TRAFFIC_SHAPER and _REC1 */
+#define SSPP_TRAFFIC_SHAPER_BPC_MAX        0xFF
+
+/*
+ * Definitions for ViG op modes
+ */
+#define VIG_OP_CSC_DST_DATAFMT BIT(19)
+#define VIG_OP_CSC_SRC_DATAFMT BIT(18)
+#define VIG_OP_CSC_EN          BIT(17)
+#define VIG_OP_MEM_PROT_CONT   BIT(15)
+#define VIG_OP_MEM_PROT_VAL    BIT(14)
+#define VIG_OP_MEM_PROT_SAT    BIT(13)
+#define VIG_OP_MEM_PROT_HUE    BIT(12)
+#define VIG_OP_HIST            BIT(8)
+#define VIG_OP_SKY_COL         BIT(7)
+#define VIG_OP_FOIL            BIT(6)
+#define VIG_OP_SKIN_COL        BIT(5)
+#define VIG_OP_PA_EN           BIT(4)
+#define VIG_OP_PA_SAT_ZERO_EXP BIT(2)
+#define VIG_OP_MEM_PROT_BLEND  BIT(1)
+
+/*
+ * Definitions for CSC 10 op modes
+ */
+#define SSPP_VIG_CSC_10_OP_MODE            0x0
+#define VIG_CSC_10_SRC_DATAFMT BIT(1)
+#define VIG_CSC_10_EN          BIT(0)
+#define CSC_10BIT_OFFSET       4
+
+/* traffic shaper clock in Hz */
+#define TS_CLK			19200000
+
+
+static void dpu_hw_sspp_setup_multirect(struct dpu_sw_pipe *pipe)
+{
+	struct dpu_hw_sspp *ctx = pipe->sspp;
+	u32 mode_mask;
+
+	if (!ctx)
+		return;
+
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
+		/**
+		 * if rect index is RECT_SOLO, we cannot expect a
+		 * virtual plane sharing the same SSPP id. So we go
+		 * and disable multirect
+		 */
+		mode_mask = 0;
+	} else {
+		mode_mask = DPU_REG_READ(&ctx->hw, SSPP_MULTIRECT_OPMODE);
+		mode_mask |= pipe->multirect_index;
+		if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_TIME_MX)
+			mode_mask |= BIT(2);
+		else
+			mode_mask &= ~BIT(2);
+	}
+
+	DPU_REG_WRITE(&ctx->hw, SSPP_MULTIRECT_OPMODE, mode_mask);
+}
+
+static void _sspp_setup_opmode(struct dpu_hw_sspp *ctx,
+		u32 mask, u8 en)
+{
+	const struct dpu_sspp_sub_blks *sblk = ctx->cap->sblk;
+	u32 opmode;
+
+	if (!test_bit(DPU_SSPP_SCALER_QSEED2, &ctx->cap->features) ||
+		!test_bit(DPU_SSPP_CSC, &ctx->cap->features))
+		return;
+
+	opmode = DPU_REG_READ(&ctx->hw, sblk->scaler_blk.base + SSPP_VIG_OP_MODE);
+
+	if (en)
+		opmode |= mask;
+	else
+		opmode &= ~mask;
+
+	DPU_REG_WRITE(&ctx->hw, sblk->scaler_blk.base + SSPP_VIG_OP_MODE, opmode);
+}
+
+static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp *ctx,
+		u32 mask, u8 en)
+{
+	const struct dpu_sspp_sub_blks *sblk = ctx->cap->sblk;
+	u32 opmode;
+
+	opmode = DPU_REG_READ(&ctx->hw, sblk->csc_blk.base + SSPP_VIG_CSC_10_OP_MODE);
+	if (en)
+		opmode |= mask;
+	else
+		opmode &= ~mask;
+
+	DPU_REG_WRITE(&ctx->hw, sblk->csc_blk.base + SSPP_VIG_CSC_10_OP_MODE, opmode);
+}
+
+/*
+ * Setup source pixel format, flip,
+ */
+static void dpu_hw_sspp_setup_format(struct dpu_sw_pipe *pipe,
+		const struct dpu_format *fmt, u32 flags)
+{
+	struct dpu_hw_sspp *ctx = pipe->sspp;
+	struct dpu_hw_blk_reg_map *c;
+	u32 chroma_samp, unpack, src_format;
+	u32 opmode = 0;
+	u32 fast_clear = 0;
+	u32 op_mode_off, unpack_pat_off, format_off;
+
+	if (!ctx || !fmt)
+		return;
+
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+	    pipe->multirect_index == DPU_SSPP_RECT_0) {
+		op_mode_off = SSPP_SRC_OP_MODE;
+		unpack_pat_off = SSPP_SRC_UNPACK_PATTERN;
+		format_off = SSPP_SRC_FORMAT;
+	} else {
+		op_mode_off = SSPP_SRC_OP_MODE_REC1;
+		unpack_pat_off = SSPP_SRC_UNPACK_PATTERN_REC1;
+		format_off = SSPP_SRC_FORMAT_REC1;
+	}
+
+	c = &ctx->hw;
+	opmode = DPU_REG_READ(c, op_mode_off);
+	opmode &= ~(MDSS_MDP_OP_FLIP_LR | MDSS_MDP_OP_FLIP_UD |
+			MDSS_MDP_OP_BWC_EN | MDSS_MDP_OP_PE_OVERRIDE);
+
+	if (flags & DPU_SSPP_FLIP_LR)
+		opmode |= MDSS_MDP_OP_FLIP_LR;
+	if (flags & DPU_SSPP_FLIP_UD)
+		opmode |= MDSS_MDP_OP_FLIP_UD;
+
+	chroma_samp = fmt->chroma_sample;
+	if (flags & DPU_SSPP_SOURCE_ROTATED_90) {
+		if (chroma_samp == DPU_CHROMA_H2V1)
+			chroma_samp = DPU_CHROMA_H1V2;
+		else if (chroma_samp == DPU_CHROMA_H1V2)
+			chroma_samp = DPU_CHROMA_H2V1;
+	}
+
+	src_format = (chroma_samp << 23) | (fmt->fetch_planes << 19) |
+		(fmt->bits[C3_ALPHA] << 6) | (fmt->bits[C2_R_Cr] << 4) |
+		(fmt->bits[C1_B_Cb] << 2) | (fmt->bits[C0_G_Y] << 0);
+
+	if (flags & DPU_SSPP_ROT_90)
+		src_format |= BIT(11); /* ROT90 */
+
+	if (fmt->alpha_enable && fmt->fetch_planes == DPU_PLANE_INTERLEAVED)
+		src_format |= BIT(8); /* SRCC3_EN */
+
+	if (flags & DPU_SSPP_SOLID_FILL)
+		src_format |= BIT(22);
+
+	unpack = (fmt->element[3] << 24) | (fmt->element[2] << 16) |
+		(fmt->element[1] << 8) | (fmt->element[0] << 0);
+	src_format |= ((fmt->unpack_count - 1) << 12) |
+		(fmt->unpack_tight << 17) |
+		(fmt->unpack_align_msb << 18) |
+		((fmt->bpp - 1) << 9);
+
+	if (fmt->fetch_mode != DPU_FETCH_LINEAR) {
+		if (DPU_FORMAT_IS_UBWC(fmt))
+			opmode |= MDSS_MDP_OP_BWC_EN;
+		src_format |= (fmt->fetch_mode & 3) << 30; /*FRAME_FORMAT */
+		DPU_REG_WRITE(c, SSPP_FETCH_CONFIG,
+			DPU_FETCH_CONFIG_RESET_VALUE |
+			ctx->ubwc->highest_bank_bit << 18);
+		switch (ctx->ubwc->ubwc_enc_version) {
+		case UBWC_1_0:
+			fast_clear = fmt->alpha_enable ? BIT(31) : 0;
+			DPU_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL,
+					fast_clear | (ctx->ubwc->ubwc_swizzle & 0x1) |
+					BIT(8) |
+					(ctx->ubwc->highest_bank_bit << 4));
+			break;
+		case UBWC_2_0:
+			fast_clear = fmt->alpha_enable ? BIT(31) : 0;
+			DPU_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL,
+					fast_clear | (ctx->ubwc->ubwc_swizzle) |
+					(ctx->ubwc->highest_bank_bit << 4));
+			break;
+		case UBWC_3_0:
+			DPU_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL,
+					BIT(30) | (ctx->ubwc->ubwc_swizzle) |
+					(ctx->ubwc->highest_bank_bit << 4));
+			break;
+		case UBWC_4_0:
+			DPU_REG_WRITE(c, SSPP_UBWC_STATIC_CTRL,
+					DPU_FORMAT_IS_YUV(fmt) ? 0 : BIT(30));
+			break;
+		}
+	}
+
+	opmode |= MDSS_MDP_OP_PE_OVERRIDE;
+
+	/* if this is YUV pixel format, enable CSC */
+	if (DPU_FORMAT_IS_YUV(fmt))
+		src_format |= BIT(15);
+
+	if (DPU_FORMAT_IS_DX(fmt))
+		src_format |= BIT(14);
+
+	/* update scaler opmode, if appropriate */
+	if (test_bit(DPU_SSPP_CSC, &ctx->cap->features))
+		_sspp_setup_opmode(ctx, VIG_OP_CSC_EN | VIG_OP_CSC_SRC_DATAFMT,
+			DPU_FORMAT_IS_YUV(fmt));
+	else if (test_bit(DPU_SSPP_CSC_10BIT, &ctx->cap->features))
+		_sspp_setup_csc10_opmode(ctx,
+			VIG_CSC_10_EN | VIG_CSC_10_SRC_DATAFMT,
+			DPU_FORMAT_IS_YUV(fmt));
+
+	DPU_REG_WRITE(c, format_off, src_format);
+	DPU_REG_WRITE(c, unpack_pat_off, unpack);
+	DPU_REG_WRITE(c, op_mode_off, opmode);
+
+	/* clear previous UBWC error */
+	DPU_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS, BIT(31));
+}
+
+static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx,
+		struct dpu_hw_pixel_ext *pe_ext)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u8 color;
+	u32 lr_pe[4], tb_pe[4], tot_req_pixels[4];
+	const u32 bytemask = 0xff;
+	const u32 shortmask = 0xffff;
+
+	if (!ctx || !pe_ext)
+		return;
+
+	c = &ctx->hw;
+
+	/* program SW pixel extension override for all pipes*/
+	for (color = 0; color < DPU_MAX_PLANES; color++) {
+		/* color 2 has the same set of registers as color 1 */
+		if (color == 2)
+			continue;
+
+		lr_pe[color] = ((pe_ext->right_ftch[color] & bytemask) << 24)|
+			((pe_ext->right_rpt[color] & bytemask) << 16)|
+			((pe_ext->left_ftch[color] & bytemask) << 8)|
+			(pe_ext->left_rpt[color] & bytemask);
+
+		tb_pe[color] = ((pe_ext->btm_ftch[color] & bytemask) << 24)|
+			((pe_ext->btm_rpt[color] & bytemask) << 16)|
+			((pe_ext->top_ftch[color] & bytemask) << 8)|
+			(pe_ext->top_rpt[color] & bytemask);
+
+		tot_req_pixels[color] = (((pe_ext->roi_h[color] +
+			pe_ext->num_ext_pxls_top[color] +
+			pe_ext->num_ext_pxls_btm[color]) & shortmask) << 16) |
+			((pe_ext->roi_w[color] +
+			pe_ext->num_ext_pxls_left[color] +
+			pe_ext->num_ext_pxls_right[color]) & shortmask);
+	}
+
+	/* color 0 */
+	DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_LR, lr_pe[0]);
+	DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_TB, tb_pe[0]);
+	DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C0_REQ_PIXELS,
+			tot_req_pixels[0]);
+
+	/* color 1 and color 2 */
+	DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_LR, lr_pe[1]);
+	DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_TB, tb_pe[1]);
+	DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C1C2_REQ_PIXELS,
+			tot_req_pixels[1]);
+
+	/* color 3 */
+	DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_LR, lr_pe[3]);
+	DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_TB, lr_pe[3]);
+	DPU_REG_WRITE(c, SSPP_SW_PIX_EXT_C3_REQ_PIXELS,
+			tot_req_pixels[3]);
+}
+
+static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
+		struct dpu_hw_scaler3_cfg *scaler3_cfg,
+		const struct dpu_format *format)
+{
+	if (!ctx || !scaler3_cfg)
+		return;
+
+	dpu_hw_setup_scaler3(&ctx->hw, scaler3_cfg,
+			ctx->cap->sblk->scaler_blk.base,
+			ctx->cap->sblk->scaler_blk.version,
+			format);
+}
+
+/*
+ * dpu_hw_sspp_setup_rects()
+ */
+static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
+		struct dpu_sw_pipe_cfg *cfg)
+{
+	struct dpu_hw_sspp *ctx = pipe->sspp;
+	struct dpu_hw_blk_reg_map *c;
+	u32 src_size, src_xy, dst_size, dst_xy;
+	u32 src_size_off, src_xy_off, out_size_off, out_xy_off;
+
+	if (!ctx || !cfg)
+		return;
+
+	c = &ctx->hw;
+
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+	    pipe->multirect_index == DPU_SSPP_RECT_0) {
+		src_size_off = SSPP_SRC_SIZE;
+		src_xy_off = SSPP_SRC_XY;
+		out_size_off = SSPP_OUT_SIZE;
+		out_xy_off = SSPP_OUT_XY;
+	} else {
+		src_size_off = SSPP_SRC_SIZE_REC1;
+		src_xy_off = SSPP_SRC_XY_REC1;
+		out_size_off = SSPP_OUT_SIZE_REC1;
+		out_xy_off = SSPP_OUT_XY_REC1;
+	}
+
+
+	/* src and dest rect programming */
+	src_xy = (cfg->src_rect.y1 << 16) | cfg->src_rect.x1;
+	src_size = (drm_rect_height(&cfg->src_rect) << 16) |
+		   drm_rect_width(&cfg->src_rect);
+	dst_xy = (cfg->dst_rect.y1 << 16) | cfg->dst_rect.x1;
+	dst_size = (drm_rect_height(&cfg->dst_rect) << 16) |
+		drm_rect_width(&cfg->dst_rect);
+
+	/* rectangle register programming */
+	DPU_REG_WRITE(c, src_size_off, src_size);
+	DPU_REG_WRITE(c, src_xy_off, src_xy);
+	DPU_REG_WRITE(c, out_size_off, dst_size);
+	DPU_REG_WRITE(c, out_xy_off, dst_xy);
+}
+
+static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
+		struct dpu_hw_fmt_layout *layout)
+{
+	struct dpu_hw_sspp *ctx = pipe->sspp;
+	u32 ystride0, ystride1;
+	int i;
+
+	if (!ctx)
+		return;
+
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
+		for (i = 0; i < ARRAY_SIZE(layout->plane_addr); i++)
+			DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + i * 0x4,
+					layout->plane_addr[i]);
+	} else if (pipe->multirect_index == DPU_SSPP_RECT_0) {
+		DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR,
+				layout->plane_addr[0]);
+		DPU_REG_WRITE(&ctx->hw, SSPP_SRC2_ADDR,
+				layout->plane_addr[2]);
+	} else {
+		DPU_REG_WRITE(&ctx->hw, SSPP_SRC1_ADDR,
+				layout->plane_addr[0]);
+		DPU_REG_WRITE(&ctx->hw, SSPP_SRC3_ADDR,
+				layout->plane_addr[2]);
+	}
+
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
+		ystride0 = (layout->plane_pitch[0]) |
+			(layout->plane_pitch[1] << 16);
+		ystride1 = (layout->plane_pitch[2]) |
+			(layout->plane_pitch[3] << 16);
+	} else {
+		ystride0 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE0);
+		ystride1 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE1);
+
+		if (pipe->multirect_index == DPU_SSPP_RECT_0) {
+			ystride0 = (ystride0 & 0xFFFF0000) |
+				(layout->plane_pitch[0] & 0x0000FFFF);
+			ystride1 = (ystride1 & 0xFFFF0000)|
+				(layout->plane_pitch[2] & 0x0000FFFF);
+		} else {
+			ystride0 = (ystride0 & 0x0000FFFF) |
+				((layout->plane_pitch[0] << 16) &
+				 0xFFFF0000);
+			ystride1 = (ystride1 & 0x0000FFFF) |
+				((layout->plane_pitch[2] << 16) &
+				 0xFFFF0000);
+		}
+	}
+
+	DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE0, ystride0);
+	DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE1, ystride1);
+}
+
+static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
+		const struct dpu_csc_cfg *data)
+{
+	u32 offset;
+	bool csc10 = false;
+
+	if (!ctx || !data)
+		return;
+
+	offset = ctx->cap->sblk->csc_blk.base;
+
+	if (test_bit(DPU_SSPP_CSC_10BIT, &ctx->cap->features)) {
+		offset += CSC_10BIT_OFFSET;
+		csc10 = true;
+	}
+
+	dpu_hw_csc_setup(&ctx->hw, offset, data, csc10);
+}
+
+static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color)
+{
+	struct dpu_hw_sspp *ctx = pipe->sspp;
+	struct dpu_hw_fmt_layout cfg;
+
+	if (!ctx)
+		return;
+
+	/* cleanup source addresses */
+	memset(&cfg, 0, sizeof(cfg));
+	ctx->ops.setup_sourceaddress(pipe, &cfg);
+
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+	    pipe->multirect_index == DPU_SSPP_RECT_0)
+		DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR, color);
+	else
+		DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR_REC1,
+				color);
+}
+
+static void dpu_hw_sspp_setup_qos_lut(struct dpu_hw_sspp *ctx,
+				      struct dpu_hw_qos_cfg *cfg)
+{
+	if (!ctx || !cfg)
+		return;
+
+	_dpu_hw_setup_qos_lut(&ctx->hw, SSPP_DANGER_LUT,
+			      test_bit(DPU_SSPP_QOS_8LVL, &ctx->cap->features),
+			      cfg);
+}
+
+static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx,
+				       bool danger_safe_en)
+{
+	if (!ctx)
+		return;
+
+	DPU_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL,
+		      danger_safe_en ? SSPP_QOS_CTRL_DANGER_SAFE_EN : 0);
+}
+
+static void dpu_hw_sspp_setup_cdp(struct dpu_sw_pipe *pipe,
+				  const struct dpu_format *fmt,
+				  bool enable)
+{
+	struct dpu_hw_sspp *ctx = pipe->sspp;
+	u32 cdp_cntl_offset = 0;
+
+	if (!ctx)
+		return;
+
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+	    pipe->multirect_index == DPU_SSPP_RECT_0)
+		cdp_cntl_offset = SSPP_CDP_CNTL;
+	else
+		cdp_cntl_offset = SSPP_CDP_CNTL_REC1;
+
+	dpu_setup_cdp(&ctx->hw, cdp_cntl_offset, fmt, enable);
+}
+
+static bool dpu_hw_sspp_setup_clk_force_ctrl(struct dpu_hw_sspp *ctx, bool enable)
+{
+	static const struct dpu_clk_ctrl_reg sspp_clk_ctrl = {
+		.reg_off = SSPP_CLK_CTRL,
+		.bit_off = 0
+	};
+
+	return dpu_hw_clk_force_ctrl(&ctx->hw, &sspp_clk_ctrl, enable);
+}
+
+static void _setup_layer_ops(struct dpu_hw_sspp *c,
+		unsigned long features, const struct dpu_mdss_version *mdss_rev)
+{
+	c->ops.setup_format = dpu_hw_sspp_setup_format;
+	c->ops.setup_rects = dpu_hw_sspp_setup_rects;
+	c->ops.setup_sourceaddress = dpu_hw_sspp_setup_sourceaddress;
+	c->ops.setup_solidfill = dpu_hw_sspp_setup_solidfill;
+	c->ops.setup_pe = dpu_hw_sspp_setup_pe_config;
+
+	if (test_bit(DPU_SSPP_QOS, &features)) {
+		c->ops.setup_qos_lut = dpu_hw_sspp_setup_qos_lut;
+		c->ops.setup_qos_ctrl = dpu_hw_sspp_setup_qos_ctrl;
+	}
+
+	if (test_bit(DPU_SSPP_CSC, &features) ||
+		test_bit(DPU_SSPP_CSC_10BIT, &features))
+		c->ops.setup_csc = dpu_hw_sspp_setup_csc;
+
+	if (test_bit(DPU_SSPP_SMART_DMA_V1, &c->cap->features) ||
+		test_bit(DPU_SSPP_SMART_DMA_V2, &c->cap->features))
+		c->ops.setup_multirect = dpu_hw_sspp_setup_multirect;
+
+	if (test_bit(DPU_SSPP_SCALER_QSEED3_COMPATIBLE, &features))
+		c->ops.setup_scaler = _dpu_hw_sspp_setup_scaler3;
+
+	if (test_bit(DPU_SSPP_CDP, &features))
+		c->ops.setup_cdp = dpu_hw_sspp_setup_cdp;
+
+	if (mdss_rev->core_major_ver >= 9)
+		c->ops.setup_clk_force_ctrl = dpu_hw_sspp_setup_clk_force_ctrl;
+}
+
+#ifdef CONFIG_DEBUG_FS
+int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms,
+			      struct dentry *entry)
+{
+	const struct dpu_sspp_cfg *cfg = hw_pipe->cap;
+	const struct dpu_sspp_sub_blks *sblk = cfg->sblk;
+	struct dentry *debugfs_root;
+	char sspp_name[32];
+
+	snprintf(sspp_name, sizeof(sspp_name), "%d", hw_pipe->idx);
+
+	/* create overall sub-directory for the pipe */
+	debugfs_root =
+		debugfs_create_dir(sspp_name, entry);
+
+	/* don't error check these */
+	debugfs_create_xul("features", 0600,
+			debugfs_root, (unsigned long *)&hw_pipe->cap->features);
+
+	/* add register dump support */
+	dpu_debugfs_create_regset32("src_blk", 0400,
+			debugfs_root,
+			cfg->base,
+			cfg->len,
+			kms);
+
+	if (sblk->scaler_blk.len)
+		dpu_debugfs_create_regset32("scaler_blk", 0400,
+				debugfs_root,
+				sblk->scaler_blk.base + cfg->base,
+				sblk->scaler_blk.len,
+				kms);
+
+	if (cfg->features & BIT(DPU_SSPP_CSC) ||
+			cfg->features & BIT(DPU_SSPP_CSC_10BIT))
+		dpu_debugfs_create_regset32("csc_blk", 0400,
+				debugfs_root,
+				sblk->csc_blk.base + cfg->base,
+				sblk->csc_blk.len,
+				kms);
+
+	debugfs_create_u32("xin_id",
+			0400,
+			debugfs_root,
+			(u32 *) &cfg->xin_id);
+	debugfs_create_u32("clk_ctrl",
+			0400,
+			debugfs_root,
+			(u32 *) &cfg->clk_ctrl);
+
+	return 0;
+}
+#endif
+
+struct dpu_hw_sspp *dpu_hw_sspp_init(struct drm_device *dev,
+				     const struct dpu_sspp_cfg *cfg,
+				     void __iomem *addr,
+				     const struct msm_mdss_data *mdss_data,
+				     const struct dpu_mdss_version *mdss_rev)
+{
+	struct dpu_hw_sspp *hw_pipe;
+
+	if (!addr)
+		return ERR_PTR(-EINVAL);
+
+	hw_pipe = drmm_kzalloc(dev, sizeof(*hw_pipe), GFP_KERNEL);
+	if (!hw_pipe)
+		return ERR_PTR(-ENOMEM);
+
+	hw_pipe->hw.blk_addr = addr + cfg->base;
+	hw_pipe->hw.log_mask = DPU_DBG_MASK_SSPP;
+
+	/* Assign ops */
+	hw_pipe->ubwc = mdss_data;
+	hw_pipe->idx = cfg->id;
+	hw_pipe->cap = cfg;
+	_setup_layer_ops(hw_pipe, hw_pipe->cap->features, mdss_rev);
+
+	return hw_pipe;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_sspp.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_sspp.h
@@ -0,0 +1,337 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_SSPP_H
+#define _DPU_HW_SSPP_H
+
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_util.h"
+#include "dpu_formats.h"
+
+struct dpu_hw_sspp;
+
+/**
+ * Flags
+ */
+#define DPU_SSPP_FLIP_LR		BIT(0)
+#define DPU_SSPP_FLIP_UD		BIT(1)
+#define DPU_SSPP_SOURCE_ROTATED_90	BIT(2)
+#define DPU_SSPP_ROT_90			BIT(3)
+#define DPU_SSPP_SOLID_FILL		BIT(4)
+
+/**
+ * Component indices
+ */
+enum {
+	DPU_SSPP_COMP_0,
+	DPU_SSPP_COMP_1_2,
+	DPU_SSPP_COMP_2,
+	DPU_SSPP_COMP_3,
+
+	DPU_SSPP_COMP_MAX
+};
+
+/**
+ * DPU_SSPP_RECT_SOLO - multirect disabled
+ * DPU_SSPP_RECT_0 - rect0 of a multirect pipe
+ * DPU_SSPP_RECT_1 - rect1 of a multirect pipe
+ *
+ * Note: HW supports multirect with either RECT0 or
+ * RECT1. Considering no benefit of such configs over
+ * SOLO mode and to keep the plane management simple,
+ * we dont support single rect multirect configs.
+ */
+enum dpu_sspp_multirect_index {
+	DPU_SSPP_RECT_SOLO = 0,
+	DPU_SSPP_RECT_0,
+	DPU_SSPP_RECT_1,
+};
+
+enum dpu_sspp_multirect_mode {
+	DPU_SSPP_MULTIRECT_NONE = 0,
+	DPU_SSPP_MULTIRECT_PARALLEL,
+	DPU_SSPP_MULTIRECT_TIME_MX,
+};
+
+enum {
+	DPU_FRAME_LINEAR,
+	DPU_FRAME_TILE_A4X,
+	DPU_FRAME_TILE_A5X,
+};
+
+enum dpu_hw_filter {
+	DPU_SCALE_FILTER_NEAREST = 0,
+	DPU_SCALE_FILTER_BIL,
+	DPU_SCALE_FILTER_PCMN,
+	DPU_SCALE_FILTER_CA,
+	DPU_SCALE_FILTER_MAX
+};
+
+enum dpu_hw_filter_alpa {
+	DPU_SCALE_ALPHA_PIXEL_REP,
+	DPU_SCALE_ALPHA_BIL
+};
+
+enum dpu_hw_filter_yuv {
+	DPU_SCALE_2D_4X4,
+	DPU_SCALE_2D_CIR,
+	DPU_SCALE_1D_SEP,
+	DPU_SCALE_BIL
+};
+
+struct dpu_hw_sharp_cfg {
+	u32 strength;
+	u32 edge_thr;
+	u32 smooth_thr;
+	u32 noise_thr;
+};
+
+struct dpu_hw_pixel_ext {
+	/* scaling factors are enabled for this input layer */
+	uint8_t enable_pxl_ext;
+
+	int init_phase_x[DPU_MAX_PLANES];
+	int phase_step_x[DPU_MAX_PLANES];
+	int init_phase_y[DPU_MAX_PLANES];
+	int phase_step_y[DPU_MAX_PLANES];
+
+	/*
+	 * Number of pixels extension in left, right, top and bottom direction
+	 * for all color components. This pixel value for each color component
+	 * should be sum of fetch + repeat pixels.
+	 */
+	int num_ext_pxls_left[DPU_MAX_PLANES];
+	int num_ext_pxls_right[DPU_MAX_PLANES];
+	int num_ext_pxls_top[DPU_MAX_PLANES];
+	int num_ext_pxls_btm[DPU_MAX_PLANES];
+
+	/*
+	 * Number of pixels needs to be overfetched in left, right, top and
+	 * bottom directions from source image for scaling.
+	 */
+	int left_ftch[DPU_MAX_PLANES];
+	int right_ftch[DPU_MAX_PLANES];
+	int top_ftch[DPU_MAX_PLANES];
+	int btm_ftch[DPU_MAX_PLANES];
+
+	/*
+	 * Number of pixels needs to be repeated in left, right, top and
+	 * bottom directions for scaling.
+	 */
+	int left_rpt[DPU_MAX_PLANES];
+	int right_rpt[DPU_MAX_PLANES];
+	int top_rpt[DPU_MAX_PLANES];
+	int btm_rpt[DPU_MAX_PLANES];
+
+	uint32_t roi_w[DPU_MAX_PLANES];
+	uint32_t roi_h[DPU_MAX_PLANES];
+
+	/*
+	 * Filter type to be used for scaling in horizontal and vertical
+	 * directions
+	 */
+	enum dpu_hw_filter horz_filter[DPU_MAX_PLANES];
+	enum dpu_hw_filter vert_filter[DPU_MAX_PLANES];
+
+};
+
+/**
+ * struct dpu_sw_pipe_cfg : software pipe configuration
+ * @src_rect:  src ROI, caller takes into account the different operations
+ *             such as decimation, flip etc to program this field
+ * @dest_rect: destination ROI.
+ */
+struct dpu_sw_pipe_cfg {
+	struct drm_rect src_rect;
+	struct drm_rect dst_rect;
+};
+
+/**
+ * struct dpu_hw_pipe_ts_cfg - traffic shaper configuration
+ * @size: size to prefill in bytes, or zero to disable
+ * @time: time to prefill in usec, or zero to disable
+ */
+struct dpu_hw_pipe_ts_cfg {
+	u64 size;
+	u64 time;
+};
+
+/**
+ * struct dpu_sw_pipe - software pipe description
+ * @sspp:      backing SSPP pipe
+ * @index:     index of the rectangle of SSPP
+ * @mode:      parallel or time multiplex multirect mode
+ */
+struct dpu_sw_pipe {
+	struct dpu_hw_sspp *sspp;
+	enum dpu_sspp_multirect_index multirect_index;
+	enum dpu_sspp_multirect_mode multirect_mode;
+};
+
+/**
+ * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions
+ * Caller must call the init function to get the pipe context for each pipe
+ * Assumption is these functions will be called after clocks are enabled
+ */
+struct dpu_hw_sspp_ops {
+	/**
+	 * setup_format - setup pixel format cropping rectangle, flip
+	 * @pipe: Pointer to software pipe context
+	 * @cfg: Pointer to pipe config structure
+	 * @flags: Extra flags for format config
+	 */
+	void (*setup_format)(struct dpu_sw_pipe *pipe,
+			     const struct dpu_format *fmt, u32 flags);
+
+	/**
+	 * setup_rects - setup pipe ROI rectangles
+	 * @pipe: Pointer to software pipe context
+	 * @cfg: Pointer to pipe config structure
+	 */
+	void (*setup_rects)(struct dpu_sw_pipe *pipe,
+			    struct dpu_sw_pipe_cfg *cfg);
+
+	/**
+	 * setup_pe - setup pipe pixel extension
+	 * @ctx: Pointer to pipe context
+	 * @pe_ext: Pointer to pixel ext settings
+	 */
+	void (*setup_pe)(struct dpu_hw_sspp *ctx,
+			struct dpu_hw_pixel_ext *pe_ext);
+
+	/**
+	 * setup_sourceaddress - setup pipe source addresses
+	 * @pipe: Pointer to software pipe context
+	 * @layout: format layout information for programming buffer to hardware
+	 */
+	void (*setup_sourceaddress)(struct dpu_sw_pipe *ctx,
+				    struct dpu_hw_fmt_layout *layout);
+
+	/**
+	 * setup_csc - setup color space coversion
+	 * @ctx: Pointer to pipe context
+	 * @data: Pointer to config structure
+	 */
+	void (*setup_csc)(struct dpu_hw_sspp *ctx, const struct dpu_csc_cfg *data);
+
+	/**
+	 * setup_solidfill - enable/disable colorfill
+	 * @pipe: Pointer to software pipe context
+	 * @const_color: Fill color value
+	 * @flags: Pipe flags
+	 */
+	void (*setup_solidfill)(struct dpu_sw_pipe *pipe, u32 color);
+
+	/**
+	 * setup_multirect - setup multirect configuration
+	 * @pipe: Pointer to software pipe context
+	 */
+
+	void (*setup_multirect)(struct dpu_sw_pipe *pipe);
+
+	/**
+	 * setup_sharpening - setup sharpening
+	 * @ctx: Pointer to pipe context
+	 * @cfg: Pointer to config structure
+	 */
+	void (*setup_sharpening)(struct dpu_hw_sspp *ctx,
+			struct dpu_hw_sharp_cfg *cfg);
+
+
+	/**
+	 * setup_qos_lut - setup QoS LUTs
+	 * @ctx: Pointer to pipe context
+	 * @cfg: LUT configuration
+	 */
+	void (*setup_qos_lut)(struct dpu_hw_sspp *ctx,
+			struct dpu_hw_qos_cfg *cfg);
+
+	/**
+	 * setup_qos_ctrl - setup QoS control
+	 * @ctx: Pointer to pipe context
+	 * @danger_safe_en: flags controlling enabling of danger/safe QoS/LUT
+	 */
+	void (*setup_qos_ctrl)(struct dpu_hw_sspp *ctx,
+			       bool danger_safe_en);
+
+	/**
+	 * setup_clk_force_ctrl - setup clock force control
+	 * @ctx: Pointer to pipe context
+	 * @enable: enable clock force if true
+	 */
+	bool (*setup_clk_force_ctrl)(struct dpu_hw_sspp *ctx,
+				     bool enable);
+
+	/**
+	 * setup_histogram - setup histograms
+	 * @ctx: Pointer to pipe context
+	 * @cfg: Pointer to histogram configuration
+	 */
+	void (*setup_histogram)(struct dpu_hw_sspp *ctx,
+			void *cfg);
+
+	/**
+	 * setup_scaler - setup scaler
+	 * @scaler3_cfg: Pointer to scaler configuration
+	 * @format: pixel format parameters
+	 */
+	void (*setup_scaler)(struct dpu_hw_sspp *ctx,
+		struct dpu_hw_scaler3_cfg *scaler3_cfg,
+		const struct dpu_format *format);
+
+	/**
+	 * setup_cdp - setup client driven prefetch
+	 * @pipe: Pointer to software pipe context
+	 * @fmt: format used by the sw pipe
+	 * @enable: whether the CDP should be enabled for this pipe
+	 */
+	void (*setup_cdp)(struct dpu_sw_pipe *pipe,
+			  const struct dpu_format *fmt,
+			  bool enable);
+};
+
+/**
+ * struct dpu_hw_sspp - pipe description
+ * @base: hardware block base structure
+ * @hw: block hardware details
+ * @ubwc: UBWC configuration data
+ * @idx: pipe index
+ * @cap: pointer to layer_cfg
+ * @ops: pointer to operations possible for this pipe
+ */
+struct dpu_hw_sspp {
+	struct dpu_hw_blk base;
+	struct dpu_hw_blk_reg_map hw;
+	const struct msm_mdss_data *ubwc;
+
+	/* Pipe */
+	enum dpu_sspp idx;
+	const struct dpu_sspp_cfg *cap;
+
+	/* Ops */
+	struct dpu_hw_sspp_ops ops;
+};
+
+struct dpu_kms;
+/**
+ * dpu_hw_sspp_init() - Initializes the sspp hw driver object.
+ * Should be called once before accessing every pipe.
+ * @dev:  Corresponding device for devres management
+ * @cfg:  Pipe catalog entry for which driver object is required
+ * @addr: Mapped register io address of MDP
+ * @mdss_data: UBWC / MDSS configuration data
+ * @mdss_rev: dpu core's major and minor versions
+ */
+struct dpu_hw_sspp *dpu_hw_sspp_init(struct drm_device *dev,
+				     const struct dpu_sspp_cfg *cfg,
+				     void __iomem *addr,
+				     const struct msm_mdss_data *mdss_data,
+				     const struct dpu_mdss_version *mdss_rev);
+
+int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms,
+			      struct dentry *entry);
+
+#endif /*_DPU_HW_SSPP_H */
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_top.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_top.c
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <drm/drm_managed.h>
+
+#include "dpu_hwio.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_top.h"
+#include "dpu_kms.h"
+
+#define FLD_SPLIT_DISPLAY_CMD             BIT(1)
+#define FLD_SMART_PANEL_FREE_RUN          BIT(2)
+#define FLD_INTF_1_SW_TRG_MUX             BIT(4)
+#define FLD_INTF_2_SW_TRG_MUX             BIT(8)
+#define FLD_TE_LINE_INTER_WATERLEVEL_MASK 0xFFFF
+
+#define TRAFFIC_SHAPER_EN                 BIT(31)
+#define TRAFFIC_SHAPER_RD_CLIENT(num)     (0x030 + (num * 4))
+#define TRAFFIC_SHAPER_WR_CLIENT(num)     (0x060 + (num * 4))
+#define TRAFFIC_SHAPER_FIXPOINT_FACTOR    4
+
+#define MDP_TICK_COUNT                    16
+#define XO_CLK_RATE                       19200
+#define MS_TICKS_IN_SEC                   1000
+
+#define CALCULATE_WD_LOAD_VALUE(fps) \
+	((uint32_t)((MS_TICKS_IN_SEC * XO_CLK_RATE)/(MDP_TICK_COUNT * fps)))
+
+static void dpu_hw_setup_split_pipe(struct dpu_hw_mdp *mdp,
+		struct split_pipe_cfg *cfg)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 upper_pipe = 0;
+	u32 lower_pipe = 0;
+
+	if (!mdp || !cfg)
+		return;
+
+	c = &mdp->hw;
+
+	if (cfg->en) {
+		if (cfg->mode == INTF_MODE_CMD) {
+			lower_pipe = FLD_SPLIT_DISPLAY_CMD;
+			/* interface controlling sw trigger */
+			if (cfg->intf == INTF_2)
+				lower_pipe |= FLD_INTF_1_SW_TRG_MUX;
+			else
+				lower_pipe |= FLD_INTF_2_SW_TRG_MUX;
+			upper_pipe = lower_pipe;
+		} else {
+			if (cfg->intf == INTF_2) {
+				lower_pipe = FLD_INTF_1_SW_TRG_MUX;
+				upper_pipe = FLD_INTF_2_SW_TRG_MUX;
+			} else {
+				lower_pipe = FLD_INTF_2_SW_TRG_MUX;
+				upper_pipe = FLD_INTF_1_SW_TRG_MUX;
+			}
+		}
+	}
+
+	DPU_REG_WRITE(c, SSPP_SPARE, cfg->split_flush_en ? 0x1 : 0x0);
+	DPU_REG_WRITE(c, SPLIT_DISPLAY_LOWER_PIPE_CTRL, lower_pipe);
+	DPU_REG_WRITE(c, SPLIT_DISPLAY_UPPER_PIPE_CTRL, upper_pipe);
+	DPU_REG_WRITE(c, SPLIT_DISPLAY_EN, cfg->en & 0x1);
+}
+
+static bool dpu_hw_setup_clk_force_ctrl(struct dpu_hw_mdp *mdp,
+		enum dpu_clk_ctrl_type clk_ctrl, bool enable)
+{
+	if (!mdp)
+		return false;
+
+	if (clk_ctrl <= DPU_CLK_CTRL_NONE || clk_ctrl >= DPU_CLK_CTRL_MAX)
+		return false;
+
+	return dpu_hw_clk_force_ctrl(&mdp->hw, &mdp->caps->clk_ctrls[clk_ctrl], enable);
+}
+
+
+static void dpu_hw_get_danger_status(struct dpu_hw_mdp *mdp,
+		struct dpu_danger_safe_status *status)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 value;
+
+	if (!mdp || !status)
+		return;
+
+	c = &mdp->hw;
+
+	value = DPU_REG_READ(c, DANGER_STATUS);
+	status->mdp = (value >> 0) & 0x3;
+	status->sspp[SSPP_VIG0] = (value >> 4) & 0x3;
+	status->sspp[SSPP_VIG1] = (value >> 6) & 0x3;
+	status->sspp[SSPP_VIG2] = (value >> 8) & 0x3;
+	status->sspp[SSPP_VIG3] = (value >> 10) & 0x3;
+	status->sspp[SSPP_RGB0] = (value >> 12) & 0x3;
+	status->sspp[SSPP_RGB1] = (value >> 14) & 0x3;
+	status->sspp[SSPP_RGB2] = (value >> 16) & 0x3;
+	status->sspp[SSPP_RGB3] = (value >> 18) & 0x3;
+	status->sspp[SSPP_DMA0] = (value >> 20) & 0x3;
+	status->sspp[SSPP_DMA1] = (value >> 22) & 0x3;
+	status->sspp[SSPP_DMA2] = (value >> 28) & 0x3;
+	status->sspp[SSPP_DMA3] = (value >> 30) & 0x3;
+	status->sspp[SSPP_CURSOR0] = (value >> 24) & 0x3;
+	status->sspp[SSPP_CURSOR1] = (value >> 26) & 0x3;
+}
+
+static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp,
+		struct dpu_vsync_source_cfg *cfg)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 reg, wd_load_value, wd_ctl, wd_ctl2;
+
+	if (!mdp || !cfg)
+		return;
+
+	c = &mdp->hw;
+
+	if (cfg->vsync_source >= DPU_VSYNC_SOURCE_WD_TIMER_4 &&
+			cfg->vsync_source <= DPU_VSYNC_SOURCE_WD_TIMER_0) {
+		switch (cfg->vsync_source) {
+		case DPU_VSYNC_SOURCE_WD_TIMER_4:
+			wd_load_value = MDP_WD_TIMER_4_LOAD_VALUE;
+			wd_ctl = MDP_WD_TIMER_4_CTL;
+			wd_ctl2 = MDP_WD_TIMER_4_CTL2;
+			break;
+		case DPU_VSYNC_SOURCE_WD_TIMER_3:
+			wd_load_value = MDP_WD_TIMER_3_LOAD_VALUE;
+			wd_ctl = MDP_WD_TIMER_3_CTL;
+			wd_ctl2 = MDP_WD_TIMER_3_CTL2;
+			break;
+		case DPU_VSYNC_SOURCE_WD_TIMER_2:
+			wd_load_value = MDP_WD_TIMER_2_LOAD_VALUE;
+			wd_ctl = MDP_WD_TIMER_2_CTL;
+			wd_ctl2 = MDP_WD_TIMER_2_CTL2;
+			break;
+		case DPU_VSYNC_SOURCE_WD_TIMER_1:
+			wd_load_value = MDP_WD_TIMER_1_LOAD_VALUE;
+			wd_ctl = MDP_WD_TIMER_1_CTL;
+			wd_ctl2 = MDP_WD_TIMER_1_CTL2;
+			break;
+		case DPU_VSYNC_SOURCE_WD_TIMER_0:
+		default:
+			wd_load_value = MDP_WD_TIMER_0_LOAD_VALUE;
+			wd_ctl = MDP_WD_TIMER_0_CTL;
+			wd_ctl2 = MDP_WD_TIMER_0_CTL2;
+			break;
+		}
+
+		DPU_REG_WRITE(c, wd_load_value,
+			CALCULATE_WD_LOAD_VALUE(cfg->frame_rate));
+
+		DPU_REG_WRITE(c, wd_ctl, BIT(0)); /* clear timer */
+		reg = DPU_REG_READ(c, wd_ctl2);
+		reg |= BIT(8);		/* enable heartbeat timer */
+		reg |= BIT(0);		/* enable WD timer */
+		DPU_REG_WRITE(c, wd_ctl2, reg);
+
+		/* make sure that timers are enabled/disabled for vsync state */
+		wmb();
+	}
+}
+
+static void dpu_hw_setup_vsync_source_and_vsync_sel(struct dpu_hw_mdp *mdp,
+		struct dpu_vsync_source_cfg *cfg)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 reg, i;
+	static const u32 pp_offset[PINGPONG_MAX] = {0xC, 0x8, 0x4, 0x13, 0x18};
+
+	if (!mdp || !cfg || (cfg->pp_count > ARRAY_SIZE(cfg->ppnumber)))
+		return;
+
+	c = &mdp->hw;
+
+	reg = DPU_REG_READ(c, MDP_VSYNC_SEL);
+	for (i = 0; i < cfg->pp_count; i++) {
+		int pp_idx = cfg->ppnumber[i] - PINGPONG_0;
+
+		if (pp_idx >= ARRAY_SIZE(pp_offset))
+			continue;
+
+		reg &= ~(0xf << pp_offset[pp_idx]);
+		reg |= (cfg->vsync_source & 0xf) << pp_offset[pp_idx];
+	}
+	DPU_REG_WRITE(c, MDP_VSYNC_SEL, reg);
+
+	dpu_hw_setup_vsync_source(mdp, cfg);
+}
+
+static void dpu_hw_get_safe_status(struct dpu_hw_mdp *mdp,
+		struct dpu_danger_safe_status *status)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 value;
+
+	if (!mdp || !status)
+		return;
+
+	c = &mdp->hw;
+
+	value = DPU_REG_READ(c, SAFE_STATUS);
+	status->mdp = (value >> 0) & 0x1;
+	status->sspp[SSPP_VIG0] = (value >> 4) & 0x1;
+	status->sspp[SSPP_VIG1] = (value >> 6) & 0x1;
+	status->sspp[SSPP_VIG2] = (value >> 8) & 0x1;
+	status->sspp[SSPP_VIG3] = (value >> 10) & 0x1;
+	status->sspp[SSPP_RGB0] = (value >> 12) & 0x1;
+	status->sspp[SSPP_RGB1] = (value >> 14) & 0x1;
+	status->sspp[SSPP_RGB2] = (value >> 16) & 0x1;
+	status->sspp[SSPP_RGB3] = (value >> 18) & 0x1;
+	status->sspp[SSPP_DMA0] = (value >> 20) & 0x1;
+	status->sspp[SSPP_DMA1] = (value >> 22) & 0x1;
+	status->sspp[SSPP_DMA2] = (value >> 28) & 0x1;
+	status->sspp[SSPP_DMA3] = (value >> 30) & 0x1;
+	status->sspp[SSPP_CURSOR0] = (value >> 24) & 0x1;
+	status->sspp[SSPP_CURSOR1] = (value >> 26) & 0x1;
+}
+
+static void dpu_hw_intf_audio_select(struct dpu_hw_mdp *mdp)
+{
+	struct dpu_hw_blk_reg_map *c;
+
+	if (!mdp)
+		return;
+
+	c = &mdp->hw;
+
+	DPU_REG_WRITE(c, HDMI_DP_CORE_SELECT, 0x1);
+}
+
+static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
+		unsigned long cap)
+{
+	ops->setup_split_pipe = dpu_hw_setup_split_pipe;
+	ops->setup_clk_force_ctrl = dpu_hw_setup_clk_force_ctrl;
+	ops->get_danger_status = dpu_hw_get_danger_status;
+
+	if (cap & BIT(DPU_MDP_VSYNC_SEL))
+		ops->setup_vsync_source = dpu_hw_setup_vsync_source_and_vsync_sel;
+	else
+		ops->setup_vsync_source = dpu_hw_setup_vsync_source;
+
+	ops->get_safe_status = dpu_hw_get_safe_status;
+
+	if (cap & BIT(DPU_MDP_AUDIO_SELECT))
+		ops->intf_audio_select = dpu_hw_intf_audio_select;
+}
+
+struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev,
+				      const struct dpu_mdp_cfg *cfg,
+				      void __iomem *addr,
+				      const struct dpu_mdss_cfg *m)
+{
+	struct dpu_hw_mdp *mdp;
+
+	if (!addr)
+		return ERR_PTR(-EINVAL);
+
+	mdp = drmm_kzalloc(dev, sizeof(*mdp), GFP_KERNEL);
+	if (!mdp)
+		return ERR_PTR(-ENOMEM);
+
+	mdp->hw.blk_addr = addr + cfg->base;
+	mdp->hw.log_mask = DPU_DBG_MASK_TOP;
+
+	/*
+	 * Assign ops
+	 */
+	mdp->caps = cfg;
+	_setup_mdp_ops(&mdp->ops, mdp->caps->features);
+
+	return mdp;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_top.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_top.h
@@ -0,0 +1,160 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_TOP_H
+#define _DPU_HW_TOP_H
+
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_util.h"
+
+struct dpu_hw_mdp;
+
+/**
+ * struct traffic_shaper_cfg: traffic shaper configuration
+ * @en        : enable/disable traffic shaper
+ * @rd_client : true if read client; false if write client
+ * @client_id : client identifier
+ * @bpc_denom : denominator of byte per clk
+ * @bpc_numer : numerator of byte per clk
+ */
+struct traffic_shaper_cfg {
+	bool en;
+	bool rd_client;
+	u32 client_id;
+	u32 bpc_denom;
+	u64 bpc_numer;
+};
+
+/**
+ * struct split_pipe_cfg - pipe configuration for dual display panels
+ * @en        : Enable/disable dual pipe configuration
+ * @mode      : Panel interface mode
+ * @intf      : Interface id for main control path
+ * @split_flush_en: Allows both the paths to be flushed when master path is
+ *              flushed
+ */
+struct split_pipe_cfg {
+	bool en;
+	enum dpu_intf_mode mode;
+	enum dpu_intf intf;
+	bool split_flush_en;
+};
+
+/**
+ * struct dpu_danger_safe_status: danger and safe status signals
+ * @mdp: top level status
+ * @sspp: source pipe status
+ */
+struct dpu_danger_safe_status {
+	u8 mdp;
+	u8 sspp[SSPP_MAX];
+};
+
+/**
+ * struct dpu_vsync_source_cfg - configure vsync source and configure the
+ *                                    watchdog timers if required.
+ * @pp_count: number of ping pongs active
+ * @frame_rate: Display frame rate
+ * @ppnumber: ping pong index array
+ * @vsync_source: vsync source selection
+ */
+struct dpu_vsync_source_cfg {
+	u32 pp_count;
+	u32 frame_rate;
+	u32 ppnumber[PINGPONG_MAX];
+	u32 vsync_source;
+};
+
+/**
+ * struct dpu_hw_mdp_ops - interface to the MDP TOP Hw driver functions
+ * Assumption is these functions will be called after clocks are enabled.
+ * @setup_split_pipe : Programs the pipe control registers
+ * @setup_pp_split : Programs the pp split control registers
+ * @setup_traffic_shaper : programs traffic shaper control
+ */
+struct dpu_hw_mdp_ops {
+	/** setup_split_pipe() : Registers are not double buffered, thisk
+	 * function should be called before timing control enable
+	 * @mdp  : mdp top context driver
+	 * @cfg  : upper and lower part of pipe configuration
+	 */
+	void (*setup_split_pipe)(struct dpu_hw_mdp *mdp,
+			struct split_pipe_cfg *p);
+
+	/**
+	 * setup_traffic_shaper() : Setup traffic shaper control
+	 * @mdp  : mdp top context driver
+	 * @cfg  : traffic shaper configuration
+	 */
+	void (*setup_traffic_shaper)(struct dpu_hw_mdp *mdp,
+			struct traffic_shaper_cfg *cfg);
+
+	/**
+	 * setup_clk_force_ctrl - set clock force control
+	 * @mdp: mdp top context driver
+	 * @clk_ctrl: clock to be controlled
+	 * @enable: force on enable
+	 * @return: if the clock is forced-on by this function
+	 */
+	bool (*setup_clk_force_ctrl)(struct dpu_hw_mdp *mdp,
+			enum dpu_clk_ctrl_type clk_ctrl, bool enable);
+
+	/**
+	 * get_danger_status - get danger status
+	 * @mdp: mdp top context driver
+	 * @status: Pointer to danger safe status
+	 */
+	void (*get_danger_status)(struct dpu_hw_mdp *mdp,
+			struct dpu_danger_safe_status *status);
+
+	/**
+	 * setup_vsync_source - setup vsync source configuration details
+	 * @mdp: mdp top context driver
+	 * @cfg: vsync source selection configuration
+	 */
+	void (*setup_vsync_source)(struct dpu_hw_mdp *mdp,
+				struct dpu_vsync_source_cfg *cfg);
+
+	/**
+	 * get_safe_status - get safe status
+	 * @mdp: mdp top context driver
+	 * @status: Pointer to danger safe status
+	 */
+	void (*get_safe_status)(struct dpu_hw_mdp *mdp,
+			struct dpu_danger_safe_status *status);
+
+	/**
+	 * intf_audio_select - select the external interface for audio
+	 * @mdp: mdp top context driver
+	 */
+	void (*intf_audio_select)(struct dpu_hw_mdp *mdp);
+};
+
+struct dpu_hw_mdp {
+	struct dpu_hw_blk base;
+	struct dpu_hw_blk_reg_map hw;
+
+	/* top */
+	const struct dpu_mdp_cfg *caps;
+
+	/* ops */
+	struct dpu_hw_mdp_ops ops;
+};
+
+/**
+ * dpu_hw_mdptop_init - initializes the top driver for the passed config
+ * @dev:  Corresponding device for devres management
+ * @cfg:  MDP TOP configuration from catalog
+ * @addr: Mapped register io address of MDP
+ * @m:    Pointer to mdss catalog data
+ */
+struct dpu_hw_mdp *dpu_hw_mdptop_init(struct drm_device *dev,
+				      const struct dpu_mdp_cfg *cfg,
+				      void __iomem *addr,
+				      const struct dpu_mdss_cfg *m);
+
+void dpu_hw_mdp_destroy(struct dpu_hw_mdp *mdp);
+
+#endif /*_DPU_HW_TOP_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_util.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_util.c
@@ -0,0 +1,603 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+
+#include "msm_drv.h"
+#include "dpu_kms.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_util.h"
+
+/* using a file static variables for debugfs access */
+static u32 dpu_hw_util_log_mask = DPU_DBG_MASK_NONE;
+
+/* DPU_SCALER_QSEED3 */
+#define QSEED3_HW_VERSION                  0x00
+#define QSEED3_OP_MODE                     0x04
+#define QSEED3_RGB2Y_COEFF                 0x08
+#define QSEED3_PHASE_INIT                  0x0C
+#define QSEED3_PHASE_STEP_Y_H              0x10
+#define QSEED3_PHASE_STEP_Y_V              0x14
+#define QSEED3_PHASE_STEP_UV_H             0x18
+#define QSEED3_PHASE_STEP_UV_V             0x1C
+#define QSEED3_PRELOAD                     0x20
+#define QSEED3_DE_SHARPEN                  0x24
+#define QSEED3_DE_SHARPEN_CTL              0x28
+#define QSEED3_DE_SHAPE_CTL                0x2C
+#define QSEED3_DE_THRESHOLD                0x30
+#define QSEED3_DE_ADJUST_DATA_0            0x34
+#define QSEED3_DE_ADJUST_DATA_1            0x38
+#define QSEED3_DE_ADJUST_DATA_2            0x3C
+#define QSEED3_SRC_SIZE_Y_RGB_A            0x40
+#define QSEED3_SRC_SIZE_UV                 0x44
+#define QSEED3_DST_SIZE                    0x48
+#define QSEED3_COEF_LUT_CTRL               0x4C
+#define QSEED3_COEF_LUT_SWAP_BIT           0
+#define QSEED3_COEF_LUT_DIR_BIT            1
+#define QSEED3_COEF_LUT_Y_CIR_BIT          2
+#define QSEED3_COEF_LUT_UV_CIR_BIT         3
+#define QSEED3_COEF_LUT_Y_SEP_BIT          4
+#define QSEED3_COEF_LUT_UV_SEP_BIT         5
+#define QSEED3_BUFFER_CTRL                 0x50
+#define QSEED3_CLK_CTRL0                   0x54
+#define QSEED3_CLK_CTRL1                   0x58
+#define QSEED3_CLK_STATUS                  0x5C
+#define QSEED3_PHASE_INIT_Y_H              0x90
+#define QSEED3_PHASE_INIT_Y_V              0x94
+#define QSEED3_PHASE_INIT_UV_H             0x98
+#define QSEED3_PHASE_INIT_UV_V             0x9C
+#define QSEED3_COEF_LUT                    0x100
+#define QSEED3_FILTERS                     5
+#define QSEED3_LUT_REGIONS                 4
+#define QSEED3_CIRCULAR_LUTS               9
+#define QSEED3_SEPARABLE_LUTS              10
+#define QSEED3_LUT_SIZE                    60
+#define QSEED3_ENABLE                      2
+#define QSEED3_DIR_LUT_SIZE                (200 * sizeof(u32))
+#define QSEED3_CIR_LUT_SIZE \
+	(QSEED3_LUT_SIZE * QSEED3_CIRCULAR_LUTS * sizeof(u32))
+#define QSEED3_SEP_LUT_SIZE \
+	(QSEED3_LUT_SIZE * QSEED3_SEPARABLE_LUTS * sizeof(u32))
+
+/* DPU_SCALER_QSEED3LITE */
+#define QSEED3LITE_COEF_LUT_Y_SEP_BIT         4
+#define QSEED3LITE_COEF_LUT_UV_SEP_BIT        5
+#define QSEED3LITE_COEF_LUT_CTRL              0x4C
+#define QSEED3LITE_COEF_LUT_SWAP_BIT          0
+#define QSEED3LITE_DIR_FILTER_WEIGHT          0x60
+#define QSEED3LITE_FILTERS                 2
+#define QSEED3LITE_SEPARABLE_LUTS             10
+#define QSEED3LITE_LUT_SIZE                   33
+#define QSEED3LITE_SEP_LUT_SIZE \
+	        (QSEED3LITE_LUT_SIZE * QSEED3LITE_SEPARABLE_LUTS * sizeof(u32))
+
+/* QOS_LUT */
+#define QOS_DANGER_LUT                    0x00
+#define QOS_SAFE_LUT                      0x04
+#define QOS_CREQ_LUT                      0x08
+#define QOS_QOS_CTRL                      0x0C
+#define QOS_CREQ_LUT_0                    0x14
+#define QOS_CREQ_LUT_1                    0x18
+
+/* QOS_QOS_CTRL */
+#define QOS_QOS_CTRL_DANGER_SAFE_EN       BIT(0)
+#define QOS_QOS_CTRL_DANGER_VBLANK_MASK   GENMASK(5, 4)
+#define QOS_QOS_CTRL_VBLANK_EN            BIT(16)
+#define QOS_QOS_CTRL_CREQ_VBLANK_MASK     GENMASK(21, 20)
+
+void dpu_reg_write(struct dpu_hw_blk_reg_map *c,
+		u32 reg_off,
+		u32 val,
+		const char *name)
+{
+	/* don't need to mutex protect this */
+	if (c->log_mask & dpu_hw_util_log_mask)
+		DPU_DEBUG_DRIVER("[%s:0x%X] <= 0x%X\n",
+				name, reg_off, val);
+	writel_relaxed(val, c->blk_addr + reg_off);
+}
+
+int dpu_reg_read(struct dpu_hw_blk_reg_map *c, u32 reg_off)
+{
+	return readl_relaxed(c->blk_addr + reg_off);
+}
+
+u32 *dpu_hw_util_get_log_mask_ptr(void)
+{
+	return &dpu_hw_util_log_mask;
+}
+
+static void _dpu_hw_setup_scaler3_lut(struct dpu_hw_blk_reg_map *c,
+		struct dpu_hw_scaler3_cfg *scaler3_cfg, u32 offset)
+{
+	int i, j, filter;
+	int config_lut = 0x0;
+	unsigned long lut_flags;
+	u32 lut_addr, lut_offset, lut_len;
+	u32 *lut[QSEED3_FILTERS] = {NULL, NULL, NULL, NULL, NULL};
+	static const uint32_t off_tbl[QSEED3_FILTERS][QSEED3_LUT_REGIONS][2] = {
+		{{18, 0x000}, {12, 0x120}, {12, 0x1E0}, {8, 0x2A0} },
+		{{6, 0x320}, {3, 0x3E0}, {3, 0x440}, {3, 0x4A0} },
+		{{6, 0x500}, {3, 0x5c0}, {3, 0x620}, {3, 0x680} },
+		{{6, 0x380}, {3, 0x410}, {3, 0x470}, {3, 0x4d0} },
+		{{6, 0x560}, {3, 0x5f0}, {3, 0x650}, {3, 0x6b0} },
+	};
+
+	lut_flags = (unsigned long) scaler3_cfg->lut_flag;
+	if (test_bit(QSEED3_COEF_LUT_DIR_BIT, &lut_flags) &&
+		(scaler3_cfg->dir_len == QSEED3_DIR_LUT_SIZE)) {
+		lut[0] = scaler3_cfg->dir_lut;
+		config_lut = 1;
+	}
+	if (test_bit(QSEED3_COEF_LUT_Y_CIR_BIT, &lut_flags) &&
+		(scaler3_cfg->y_rgb_cir_lut_idx < QSEED3_CIRCULAR_LUTS) &&
+		(scaler3_cfg->cir_len == QSEED3_CIR_LUT_SIZE)) {
+		lut[1] = scaler3_cfg->cir_lut +
+			scaler3_cfg->y_rgb_cir_lut_idx * QSEED3_LUT_SIZE;
+		config_lut = 1;
+	}
+	if (test_bit(QSEED3_COEF_LUT_UV_CIR_BIT, &lut_flags) &&
+		(scaler3_cfg->uv_cir_lut_idx < QSEED3_CIRCULAR_LUTS) &&
+		(scaler3_cfg->cir_len == QSEED3_CIR_LUT_SIZE)) {
+		lut[2] = scaler3_cfg->cir_lut +
+			scaler3_cfg->uv_cir_lut_idx * QSEED3_LUT_SIZE;
+		config_lut = 1;
+	}
+	if (test_bit(QSEED3_COEF_LUT_Y_SEP_BIT, &lut_flags) &&
+		(scaler3_cfg->y_rgb_sep_lut_idx < QSEED3_SEPARABLE_LUTS) &&
+		(scaler3_cfg->sep_len == QSEED3_SEP_LUT_SIZE)) {
+		lut[3] = scaler3_cfg->sep_lut +
+			scaler3_cfg->y_rgb_sep_lut_idx * QSEED3_LUT_SIZE;
+		config_lut = 1;
+	}
+	if (test_bit(QSEED3_COEF_LUT_UV_SEP_BIT, &lut_flags) &&
+		(scaler3_cfg->uv_sep_lut_idx < QSEED3_SEPARABLE_LUTS) &&
+		(scaler3_cfg->sep_len == QSEED3_SEP_LUT_SIZE)) {
+		lut[4] = scaler3_cfg->sep_lut +
+			scaler3_cfg->uv_sep_lut_idx * QSEED3_LUT_SIZE;
+		config_lut = 1;
+	}
+
+	if (config_lut) {
+		for (filter = 0; filter < QSEED3_FILTERS; filter++) {
+			if (!lut[filter])
+				continue;
+			lut_offset = 0;
+			for (i = 0; i < QSEED3_LUT_REGIONS; i++) {
+				lut_addr = QSEED3_COEF_LUT + offset
+					+ off_tbl[filter][i][1];
+				lut_len = off_tbl[filter][i][0] << 2;
+				for (j = 0; j < lut_len; j++) {
+					DPU_REG_WRITE(c,
+						lut_addr,
+						(lut[filter])[lut_offset++]);
+					lut_addr += 4;
+				}
+			}
+		}
+	}
+
+	if (test_bit(QSEED3_COEF_LUT_SWAP_BIT, &lut_flags))
+		DPU_REG_WRITE(c, QSEED3_COEF_LUT_CTRL + offset, BIT(0));
+
+}
+
+static void _dpu_hw_setup_scaler3lite_lut(struct dpu_hw_blk_reg_map *c,
+		struct dpu_hw_scaler3_cfg *scaler3_cfg, u32 offset)
+{
+	int j, filter;
+	int config_lut = 0x0;
+	unsigned long lut_flags;
+	u32 lut_addr, lut_offset;
+	u32 *lut[QSEED3LITE_FILTERS] = {NULL, NULL};
+	static const uint32_t off_tbl[QSEED3_FILTERS] = { 0x000, 0x200 };
+
+	DPU_REG_WRITE(c, QSEED3LITE_DIR_FILTER_WEIGHT + offset, scaler3_cfg->dir_weight);
+
+	if (!scaler3_cfg->sep_lut)
+		return;
+
+	lut_flags = (unsigned long) scaler3_cfg->lut_flag;
+	if (test_bit(QSEED3_COEF_LUT_Y_SEP_BIT, &lut_flags) &&
+		(scaler3_cfg->y_rgb_sep_lut_idx < QSEED3LITE_SEPARABLE_LUTS) &&
+		(scaler3_cfg->sep_len == QSEED3LITE_SEP_LUT_SIZE)) {
+		lut[0] = scaler3_cfg->sep_lut +
+			scaler3_cfg->y_rgb_sep_lut_idx * QSEED3LITE_LUT_SIZE;
+		config_lut = 1;
+	}
+	if (test_bit(QSEED3_COEF_LUT_UV_SEP_BIT, &lut_flags) &&
+		(scaler3_cfg->uv_sep_lut_idx < QSEED3LITE_SEPARABLE_LUTS) &&
+		(scaler3_cfg->sep_len == QSEED3LITE_SEP_LUT_SIZE)) {
+		lut[1] = scaler3_cfg->sep_lut +
+			scaler3_cfg->uv_sep_lut_idx * QSEED3LITE_LUT_SIZE;
+		config_lut = 1;
+	}
+
+	if (config_lut) {
+		for (filter = 0; filter < QSEED3LITE_FILTERS; filter++) {
+			if (!lut[filter])
+				continue;
+			lut_offset = 0;
+			lut_addr = QSEED3_COEF_LUT + offset + off_tbl[filter];
+			for (j = 0; j < QSEED3LITE_LUT_SIZE; j++) {
+				DPU_REG_WRITE(c,
+					lut_addr,
+					(lut[filter])[lut_offset++]);
+				lut_addr += 4;
+			}
+		}
+	}
+
+	if (test_bit(QSEED3_COEF_LUT_SWAP_BIT, &lut_flags))
+		DPU_REG_WRITE(c, QSEED3_COEF_LUT_CTRL + offset, BIT(0));
+
+}
+
+static void _dpu_hw_setup_scaler3_de(struct dpu_hw_blk_reg_map *c,
+		struct dpu_hw_scaler3_de_cfg *de_cfg, u32 offset)
+{
+	u32 sharp_lvl, sharp_ctl, shape_ctl, de_thr;
+	u32 adjust_a, adjust_b, adjust_c;
+
+	if (!de_cfg->enable)
+		return;
+
+	sharp_lvl = (de_cfg->sharpen_level1 & 0x1FF) |
+		((de_cfg->sharpen_level2 & 0x1FF) << 16);
+
+	sharp_ctl = ((de_cfg->limit & 0xF) << 9) |
+		((de_cfg->prec_shift & 0x7) << 13) |
+		((de_cfg->clip & 0x7) << 16);
+
+	shape_ctl = (de_cfg->thr_quiet & 0xFF) |
+		((de_cfg->thr_dieout & 0x3FF) << 16);
+
+	de_thr = (de_cfg->thr_low & 0x3FF) |
+		((de_cfg->thr_high & 0x3FF) << 16);
+
+	adjust_a = (de_cfg->adjust_a[0] & 0x3FF) |
+		((de_cfg->adjust_a[1] & 0x3FF) << 10) |
+		((de_cfg->adjust_a[2] & 0x3FF) << 20);
+
+	adjust_b = (de_cfg->adjust_b[0] & 0x3FF) |
+		((de_cfg->adjust_b[1] & 0x3FF) << 10) |
+		((de_cfg->adjust_b[2] & 0x3FF) << 20);
+
+	adjust_c = (de_cfg->adjust_c[0] & 0x3FF) |
+		((de_cfg->adjust_c[1] & 0x3FF) << 10) |
+		((de_cfg->adjust_c[2] & 0x3FF) << 20);
+
+	DPU_REG_WRITE(c, QSEED3_DE_SHARPEN + offset, sharp_lvl);
+	DPU_REG_WRITE(c, QSEED3_DE_SHARPEN_CTL + offset, sharp_ctl);
+	DPU_REG_WRITE(c, QSEED3_DE_SHAPE_CTL + offset, shape_ctl);
+	DPU_REG_WRITE(c, QSEED3_DE_THRESHOLD + offset, de_thr);
+	DPU_REG_WRITE(c, QSEED3_DE_ADJUST_DATA_0 + offset, adjust_a);
+	DPU_REG_WRITE(c, QSEED3_DE_ADJUST_DATA_1 + offset, adjust_b);
+	DPU_REG_WRITE(c, QSEED3_DE_ADJUST_DATA_2 + offset, adjust_c);
+
+}
+
+void dpu_hw_setup_scaler3(struct dpu_hw_blk_reg_map *c,
+		struct dpu_hw_scaler3_cfg *scaler3_cfg,
+		u32 scaler_offset, u32 scaler_version,
+		const struct dpu_format *format)
+{
+	u32 op_mode = 0;
+	u32 phase_init, preload, src_y_rgb, src_uv, dst;
+
+	if (!scaler3_cfg->enable)
+		goto end;
+
+	op_mode |= BIT(0);
+	op_mode |= (scaler3_cfg->y_rgb_filter_cfg & 0x3) << 16;
+
+	if (format && DPU_FORMAT_IS_YUV(format)) {
+		op_mode |= BIT(12);
+		op_mode |= (scaler3_cfg->uv_filter_cfg & 0x3) << 24;
+	}
+
+	op_mode |= (scaler3_cfg->blend_cfg & 1) << 31;
+	op_mode |= (scaler3_cfg->dir_en) ? BIT(4) : 0;
+
+	preload =
+		((scaler3_cfg->preload_x[0] & 0x7F) << 0) |
+		((scaler3_cfg->preload_y[0] & 0x7F) << 8) |
+		((scaler3_cfg->preload_x[1] & 0x7F) << 16) |
+		((scaler3_cfg->preload_y[1] & 0x7F) << 24);
+
+	src_y_rgb = (scaler3_cfg->src_width[0] & 0x1FFFF) |
+		((scaler3_cfg->src_height[0] & 0x1FFFF) << 16);
+
+	src_uv = (scaler3_cfg->src_width[1] & 0x1FFFF) |
+		((scaler3_cfg->src_height[1] & 0x1FFFF) << 16);
+
+	dst = (scaler3_cfg->dst_width & 0x1FFFF) |
+		((scaler3_cfg->dst_height & 0x1FFFF) << 16);
+
+	if (scaler3_cfg->de.enable) {
+		_dpu_hw_setup_scaler3_de(c, &scaler3_cfg->de, scaler_offset);
+		op_mode |= BIT(8);
+	}
+
+	if (scaler3_cfg->lut_flag) {
+		if (scaler_version < 0x2004)
+			_dpu_hw_setup_scaler3_lut(c, scaler3_cfg, scaler_offset);
+		else
+			_dpu_hw_setup_scaler3lite_lut(c, scaler3_cfg, scaler_offset);
+	}
+
+	if (scaler_version == 0x1002) {
+		phase_init =
+			((scaler3_cfg->init_phase_x[0] & 0x3F) << 0) |
+			((scaler3_cfg->init_phase_y[0] & 0x3F) << 8) |
+			((scaler3_cfg->init_phase_x[1] & 0x3F) << 16) |
+			((scaler3_cfg->init_phase_y[1] & 0x3F) << 24);
+		DPU_REG_WRITE(c, QSEED3_PHASE_INIT + scaler_offset, phase_init);
+	} else {
+		DPU_REG_WRITE(c, QSEED3_PHASE_INIT_Y_H + scaler_offset,
+			scaler3_cfg->init_phase_x[0] & 0x1FFFFF);
+		DPU_REG_WRITE(c, QSEED3_PHASE_INIT_Y_V + scaler_offset,
+			scaler3_cfg->init_phase_y[0] & 0x1FFFFF);
+		DPU_REG_WRITE(c, QSEED3_PHASE_INIT_UV_H + scaler_offset,
+			scaler3_cfg->init_phase_x[1] & 0x1FFFFF);
+		DPU_REG_WRITE(c, QSEED3_PHASE_INIT_UV_V + scaler_offset,
+			scaler3_cfg->init_phase_y[1] & 0x1FFFFF);
+	}
+
+	DPU_REG_WRITE(c, QSEED3_PHASE_STEP_Y_H + scaler_offset,
+		scaler3_cfg->phase_step_x[0] & 0xFFFFFF);
+
+	DPU_REG_WRITE(c, QSEED3_PHASE_STEP_Y_V + scaler_offset,
+		scaler3_cfg->phase_step_y[0] & 0xFFFFFF);
+
+	DPU_REG_WRITE(c, QSEED3_PHASE_STEP_UV_H + scaler_offset,
+		scaler3_cfg->phase_step_x[1] & 0xFFFFFF);
+
+	DPU_REG_WRITE(c, QSEED3_PHASE_STEP_UV_V + scaler_offset,
+		scaler3_cfg->phase_step_y[1] & 0xFFFFFF);
+
+	DPU_REG_WRITE(c, QSEED3_PRELOAD + scaler_offset, preload);
+
+	DPU_REG_WRITE(c, QSEED3_SRC_SIZE_Y_RGB_A + scaler_offset, src_y_rgb);
+
+	DPU_REG_WRITE(c, QSEED3_SRC_SIZE_UV + scaler_offset, src_uv);
+
+	DPU_REG_WRITE(c, QSEED3_DST_SIZE + scaler_offset, dst);
+
+end:
+	if (format && !DPU_FORMAT_IS_DX(format))
+		op_mode |= BIT(14);
+
+	if (format && format->alpha_enable) {
+		op_mode |= BIT(10);
+		if (scaler_version == 0x1002)
+			op_mode |= (scaler3_cfg->alpha_filter_cfg & 0x1) << 30;
+		else
+			op_mode |= (scaler3_cfg->alpha_filter_cfg & 0x3) << 29;
+	}
+
+	DPU_REG_WRITE(c, QSEED3_OP_MODE + scaler_offset, op_mode);
+}
+
+void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c,
+		u32 csc_reg_off,
+		const struct dpu_csc_cfg *data, bool csc10)
+{
+	static const u32 matrix_shift = 7;
+	u32 clamp_shift = csc10 ? 16 : 8;
+	u32 val;
+
+	/* matrix coeff - convert S15.16 to S4.9 */
+	val = ((data->csc_mv[0] >> matrix_shift) & 0x1FFF) |
+		(((data->csc_mv[1] >> matrix_shift) & 0x1FFF) << 16);
+	DPU_REG_WRITE(c, csc_reg_off, val);
+	val = ((data->csc_mv[2] >> matrix_shift) & 0x1FFF) |
+		(((data->csc_mv[3] >> matrix_shift) & 0x1FFF) << 16);
+	DPU_REG_WRITE(c, csc_reg_off + 0x4, val);
+	val = ((data->csc_mv[4] >> matrix_shift) & 0x1FFF) |
+		(((data->csc_mv[5] >> matrix_shift) & 0x1FFF) << 16);
+	DPU_REG_WRITE(c, csc_reg_off + 0x8, val);
+	val = ((data->csc_mv[6] >> matrix_shift) & 0x1FFF) |
+		(((data->csc_mv[7] >> matrix_shift) & 0x1FFF) << 16);
+	DPU_REG_WRITE(c, csc_reg_off + 0xc, val);
+	val = (data->csc_mv[8] >> matrix_shift) & 0x1FFF;
+	DPU_REG_WRITE(c, csc_reg_off + 0x10, val);
+
+	/* Pre clamp */
+	val = (data->csc_pre_lv[0] << clamp_shift) | data->csc_pre_lv[1];
+	DPU_REG_WRITE(c, csc_reg_off + 0x14, val);
+	val = (data->csc_pre_lv[2] << clamp_shift) | data->csc_pre_lv[3];
+	DPU_REG_WRITE(c, csc_reg_off + 0x18, val);
+	val = (data->csc_pre_lv[4] << clamp_shift) | data->csc_pre_lv[5];
+	DPU_REG_WRITE(c, csc_reg_off + 0x1c, val);
+
+	/* Post clamp */
+	val = (data->csc_post_lv[0] << clamp_shift) | data->csc_post_lv[1];
+	DPU_REG_WRITE(c, csc_reg_off + 0x20, val);
+	val = (data->csc_post_lv[2] << clamp_shift) | data->csc_post_lv[3];
+	DPU_REG_WRITE(c, csc_reg_off + 0x24, val);
+	val = (data->csc_post_lv[4] << clamp_shift) | data->csc_post_lv[5];
+	DPU_REG_WRITE(c, csc_reg_off + 0x28, val);
+
+	/* Pre-Bias */
+	DPU_REG_WRITE(c, csc_reg_off + 0x2c, data->csc_pre_bv[0]);
+	DPU_REG_WRITE(c, csc_reg_off + 0x30, data->csc_pre_bv[1]);
+	DPU_REG_WRITE(c, csc_reg_off + 0x34, data->csc_pre_bv[2]);
+
+	/* Post-Bias */
+	DPU_REG_WRITE(c, csc_reg_off + 0x38, data->csc_post_bv[0]);
+	DPU_REG_WRITE(c, csc_reg_off + 0x3c, data->csc_post_bv[1]);
+	DPU_REG_WRITE(c, csc_reg_off + 0x40, data->csc_post_bv[2]);
+}
+
+/**
+ * _dpu_hw_get_qos_lut - get LUT mapping based on fill level
+ * @tbl:		Pointer to LUT table
+ * @total_fl:		fill level
+ * Return: LUT setting corresponding to the fill level
+ */
+u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl,
+		u32 total_fl)
+{
+	int i;
+
+	if (!tbl || !tbl->nentry || !tbl->entries)
+		return 0;
+
+	for (i = 0; i < tbl->nentry; i++)
+		if (total_fl <= tbl->entries[i].fl)
+			return tbl->entries[i].lut;
+
+	/* if last fl is zero, use as default */
+	if (!tbl->entries[i-1].fl)
+		return tbl->entries[i-1].lut;
+
+	return 0;
+}
+
+void _dpu_hw_setup_qos_lut(struct dpu_hw_blk_reg_map *c, u32 offset,
+			   bool qos_8lvl,
+			   const struct dpu_hw_qos_cfg *cfg)
+{
+	DPU_REG_WRITE(c, offset + QOS_DANGER_LUT, cfg->danger_lut);
+	DPU_REG_WRITE(c, offset + QOS_SAFE_LUT, cfg->safe_lut);
+
+	if (qos_8lvl) {
+		DPU_REG_WRITE(c, offset + QOS_CREQ_LUT_0, cfg->creq_lut);
+		DPU_REG_WRITE(c, offset + QOS_CREQ_LUT_1, cfg->creq_lut >> 32);
+	} else {
+		DPU_REG_WRITE(c, offset + QOS_CREQ_LUT, cfg->creq_lut);
+	}
+
+	DPU_REG_WRITE(c, offset + QOS_QOS_CTRL,
+		      cfg->danger_safe_en ? QOS_QOS_CTRL_DANGER_SAFE_EN : 0);
+}
+
+/*
+ * note: Aside from encoders, input_sel should be set to 0x0 by default
+ */
+void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c,
+		u32 misr_ctrl_offset, u8 input_sel)
+{
+	u32 config = 0;
+
+	DPU_REG_WRITE(c, misr_ctrl_offset, MISR_CTRL_STATUS_CLEAR);
+
+	/* Clear old MISR value (in case it's read before a new value is calculated)*/
+	wmb();
+
+	config = MISR_FRAME_COUNT | MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK |
+		((input_sel & 0xF) << 24);
+	DPU_REG_WRITE(c, misr_ctrl_offset, config);
+}
+
+int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c,
+		u32 misr_ctrl_offset,
+		u32 misr_signature_offset,
+		u32 *misr_value)
+{
+	u32 ctrl = 0;
+
+	if (!misr_value)
+		return -EINVAL;
+
+	ctrl = DPU_REG_READ(c, misr_ctrl_offset);
+
+	if (!(ctrl & MISR_CTRL_ENABLE))
+		return -ENODATA;
+
+	if (!(ctrl & MISR_CTRL_STATUS))
+		return -EINVAL;
+
+	*misr_value = DPU_REG_READ(c, misr_signature_offset);
+
+	return 0;
+}
+
+#define CDP_ENABLE		BIT(0)
+#define CDP_UBWC_META_ENABLE	BIT(1)
+#define CDP_TILE_AMORTIZE_ENABLE BIT(2)
+#define CDP_PRELOAD_AHEAD_64	BIT(3)
+
+void dpu_setup_cdp(struct dpu_hw_blk_reg_map *c, u32 offset,
+		   const struct dpu_format *fmt, bool enable)
+{
+	u32 cdp_cntl = CDP_PRELOAD_AHEAD_64;
+
+	if (enable)
+		cdp_cntl |= CDP_ENABLE;
+	if (DPU_FORMAT_IS_UBWC(fmt))
+		cdp_cntl |= CDP_UBWC_META_ENABLE;
+	if (DPU_FORMAT_IS_UBWC(fmt) ||
+	    DPU_FORMAT_IS_TILE(fmt))
+		cdp_cntl |= CDP_TILE_AMORTIZE_ENABLE;
+
+	DPU_REG_WRITE(c, offset, cdp_cntl);
+}
+
+bool dpu_hw_clk_force_ctrl(struct dpu_hw_blk_reg_map *c,
+			   const struct dpu_clk_ctrl_reg *clk_ctrl_reg,
+			   bool enable)
+{
+	u32 reg_val, new_val;
+	bool clk_forced_on;
+
+	reg_val = DPU_REG_READ(c, clk_ctrl_reg->reg_off);
+
+	if (enable)
+		new_val = reg_val | BIT(clk_ctrl_reg->bit_off);
+	else
+		new_val = reg_val & ~BIT(clk_ctrl_reg->bit_off);
+
+	DPU_REG_WRITE(c, clk_ctrl_reg->reg_off, new_val);
+
+	clk_forced_on = !(reg_val & BIT(clk_ctrl_reg->bit_off));
+
+	return clk_forced_on;
+}
+
+#define TO_S15D16(_x_)((_x_) << 7)
+
+const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = {
+	{
+		/* S15.16 format */
+		0x00012A00, 0x00000000, 0x00019880,
+		0x00012A00, 0xFFFF9B80, 0xFFFF3000,
+		0x00012A00, 0x00020480, 0x00000000,
+	},
+	/* signed bias */
+	{ 0xfff0, 0xff80, 0xff80,},
+	{ 0x0, 0x0, 0x0,},
+	/* unsigned clamp */
+	{ 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0,},
+	{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,},
+};
+
+const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
+	{
+		/* S15.16 format */
+		0x00012A00, 0x00000000, 0x00019880,
+		0x00012A00, 0xFFFF9B80, 0xFFFF3000,
+		0x00012A00, 0x00020480, 0x00000000,
+	},
+	/* signed bias */
+	{ 0xffc0, 0xfe00, 0xfe00,},
+	{ 0x0, 0x0, 0x0,},
+	/* unsigned clamp */
+	{ 0x40, 0x3ac, 0x40, 0x3c0, 0x40, 0x3c0,},
+	{ 0x00, 0x3ff, 0x00, 0x3ff, 0x00, 0x3ff,},
+};
+
+const struct dpu_csc_cfg dpu_csc10_rgb2yuv_601l = {
+	{
+		TO_S15D16(0x0083), TO_S15D16(0x0102), TO_S15D16(0x0032),
+		TO_S15D16(0x1fb5), TO_S15D16(0x1f6c), TO_S15D16(0x00e1),
+		TO_S15D16(0x00e1), TO_S15D16(0x1f45), TO_S15D16(0x1fdc)
+	},
+	{ 0x00, 0x00, 0x00 },
+	{ 0x0040, 0x0200, 0x0200 },
+	{ 0x000, 0x3ff, 0x000, 0x3ff, 0x000, 0x3ff },
+	{ 0x040, 0x3ac, 0x040, 0x3c0, 0x040, 0x3c0 },
+};
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_util.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_util.h
@@ -0,0 +1,375 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_UTIL_H
+#define _DPU_HW_UTIL_H
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_catalog.h"
+
+#define REG_MASK(n)                     ((BIT(n)) - 1)
+#define MISR_FRAME_COUNT                0x1
+#define MISR_CTRL_ENABLE                BIT(8)
+#define MISR_CTRL_STATUS                BIT(9)
+#define MISR_CTRL_STATUS_CLEAR          BIT(10)
+#define MISR_CTRL_FREE_RUN_MASK         BIT(31)
+
+#define TO_S15D16(_x_)((_x_) << 7)
+
+extern const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L;
+extern const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L;
+extern const struct dpu_csc_cfg dpu_csc10_rgb2yuv_601l;
+
+/*
+ * This is the common struct maintained by each sub block
+ * for mapping the register offsets in this block to the
+ * absoulute IO address
+ * @blk_addr:     hw block register mapped address
+ * @log_mask:     log mask for this block
+ */
+struct dpu_hw_blk_reg_map {
+	void __iomem *blk_addr;
+	u32 log_mask;
+};
+
+/**
+ * struct dpu_hw_blk - opaque hardware block object
+ */
+struct dpu_hw_blk {
+	/* opaque */
+};
+
+/**
+ * struct dpu_hw_scaler3_de_cfg : QSEEDv3 detail enhancer configuration
+ * @enable:         detail enhancer enable/disable
+ * @sharpen_level1: sharpening strength for noise
+ * @sharpen_level2: sharpening strength for signal
+ * @ clip:          clip shift
+ * @ limit:         limit value
+ * @ thr_quiet:     quiet threshold
+ * @ thr_dieout:    dieout threshold
+ * @ thr_high:      low threshold
+ * @ thr_high:      high threshold
+ * @ prec_shift:    precision shift
+ * @ adjust_a:      A-coefficients for mapping curve
+ * @ adjust_b:      B-coefficients for mapping curve
+ * @ adjust_c:      C-coefficients for mapping curve
+ */
+struct dpu_hw_scaler3_de_cfg {
+	u32 enable;
+	int16_t sharpen_level1;
+	int16_t sharpen_level2;
+	uint16_t clip;
+	uint16_t limit;
+	uint16_t thr_quiet;
+	uint16_t thr_dieout;
+	uint16_t thr_low;
+	uint16_t thr_high;
+	uint16_t prec_shift;
+	int16_t adjust_a[DPU_MAX_DE_CURVES];
+	int16_t adjust_b[DPU_MAX_DE_CURVES];
+	int16_t adjust_c[DPU_MAX_DE_CURVES];
+};
+
+
+/**
+ * struct dpu_hw_scaler3_cfg : QSEEDv3 configuration
+ * @enable:        scaler enable
+ * @dir_en:        direction detection block enable
+ * @ init_phase_x: horizontal initial phase
+ * @ phase_step_x: horizontal phase step
+ * @ init_phase_y: vertical initial phase
+ * @ phase_step_y: vertical phase step
+ * @ preload_x:    horizontal preload value
+ * @ preload_y:    vertical preload value
+ * @ src_width:    source width
+ * @ src_height:   source height
+ * @ dst_width:    destination width
+ * @ dst_height:   destination height
+ * @ y_rgb_filter_cfg: y/rgb plane filter configuration
+ * @ uv_filter_cfg: uv plane filter configuration
+ * @ alpha_filter_cfg: alpha filter configuration
+ * @ blend_cfg:    blend coefficients configuration
+ * @ lut_flag:     scaler LUT update flags
+ *                 0x1 swap LUT bank
+ *                 0x2 update 2D filter LUT
+ *                 0x4 update y circular filter LUT
+ *                 0x8 update uv circular filter LUT
+ *                 0x10 update y separable filter LUT
+ *                 0x20 update uv separable filter LUT
+ * @ dir_lut_idx:  2D filter LUT index
+ * @ y_rgb_cir_lut_idx: y circular filter LUT index
+ * @ uv_cir_lut_idx: uv circular filter LUT index
+ * @ y_rgb_sep_lut_idx: y circular filter LUT index
+ * @ uv_sep_lut_idx: uv separable filter LUT index
+ * @ dir_lut:      pointer to 2D LUT
+ * @ cir_lut:      pointer to circular filter LUT
+ * @ sep_lut:      pointer to separable filter LUT
+ * @ de: detail enhancer configuration
+ * @ dir_weight:   Directional weight
+ */
+struct dpu_hw_scaler3_cfg {
+	u32 enable;
+	u32 dir_en;
+	int32_t init_phase_x[DPU_MAX_PLANES];
+	int32_t phase_step_x[DPU_MAX_PLANES];
+	int32_t init_phase_y[DPU_MAX_PLANES];
+	int32_t phase_step_y[DPU_MAX_PLANES];
+
+	u32 preload_x[DPU_MAX_PLANES];
+	u32 preload_y[DPU_MAX_PLANES];
+	u32 src_width[DPU_MAX_PLANES];
+	u32 src_height[DPU_MAX_PLANES];
+
+	u32 dst_width;
+	u32 dst_height;
+
+	u32 y_rgb_filter_cfg;
+	u32 uv_filter_cfg;
+	u32 alpha_filter_cfg;
+	u32 blend_cfg;
+
+	u32 lut_flag;
+	u32 dir_lut_idx;
+
+	u32 y_rgb_cir_lut_idx;
+	u32 uv_cir_lut_idx;
+	u32 y_rgb_sep_lut_idx;
+	u32 uv_sep_lut_idx;
+	u32 *dir_lut;
+	size_t dir_len;
+	u32 *cir_lut;
+	size_t cir_len;
+	u32 *sep_lut;
+	size_t sep_len;
+
+	/*
+	 * Detail enhancer settings
+	 */
+	struct dpu_hw_scaler3_de_cfg de;
+
+	u32 dir_weight;
+};
+
+/**
+ * struct dpu_drm_pix_ext_v1 - version 1 of pixel ext structure
+ * @num_ext_pxls_lr: Number of total horizontal pixels
+ * @num_ext_pxls_tb: Number of total vertical lines
+ * @left_ftch:       Number of extra pixels to overfetch from left
+ * @right_ftch:      Number of extra pixels to overfetch from right
+ * @top_ftch:        Number of extra lines to overfetch from top
+ * @btm_ftch:        Number of extra lines to overfetch from bottom
+ * @left_rpt:        Number of extra pixels to repeat from left
+ * @right_rpt:       Number of extra pixels to repeat from right
+ * @top_rpt:         Number of extra lines to repeat from top
+ * @btm_rpt:         Number of extra lines to repeat from bottom
+ */
+struct dpu_drm_pix_ext_v1 {
+	/*
+	 * Number of pixels ext in left, right, top and bottom direction
+	 * for all color components.
+	 */
+	int32_t num_ext_pxls_lr[DPU_MAX_PLANES];
+	int32_t num_ext_pxls_tb[DPU_MAX_PLANES];
+
+	/*
+	 * Number of pixels needs to be overfetched in left, right, top
+	 * and bottom directions from source image for scaling.
+	 */
+	int32_t left_ftch[DPU_MAX_PLANES];
+	int32_t right_ftch[DPU_MAX_PLANES];
+	int32_t top_ftch[DPU_MAX_PLANES];
+	int32_t btm_ftch[DPU_MAX_PLANES];
+	/*
+	 * Number of pixels needs to be repeated in left, right, top and
+	 * bottom directions for scaling.
+	 */
+	int32_t left_rpt[DPU_MAX_PLANES];
+	int32_t right_rpt[DPU_MAX_PLANES];
+	int32_t top_rpt[DPU_MAX_PLANES];
+	int32_t btm_rpt[DPU_MAX_PLANES];
+
+};
+
+/**
+ * struct dpu_drm_de_v1 - version 1 of detail enhancer structure
+ * @enable:         Enables/disables detail enhancer
+ * @sharpen_level1: Sharpening strength for noise
+ * @sharpen_level2: Sharpening strength for context
+ * @clip:           Clip coefficient
+ * @limit:          Detail enhancer limit factor
+ * @thr_quiet:      Quite zone threshold
+ * @thr_dieout:     Die-out zone threshold
+ * @thr_low:        Linear zone left threshold
+ * @thr_high:       Linear zone right threshold
+ * @prec_shift:     Detail enhancer precision
+ * @adjust_a:       Mapping curves A coefficients
+ * @adjust_b:       Mapping curves B coefficients
+ * @adjust_c:       Mapping curves C coefficients
+ */
+struct dpu_drm_de_v1 {
+	uint32_t enable;
+	int16_t sharpen_level1;
+	int16_t sharpen_level2;
+	uint16_t clip;
+	uint16_t limit;
+	uint16_t thr_quiet;
+	uint16_t thr_dieout;
+	uint16_t thr_low;
+	uint16_t thr_high;
+	uint16_t prec_shift;
+	int16_t adjust_a[DPU_MAX_DE_CURVES];
+	int16_t adjust_b[DPU_MAX_DE_CURVES];
+	int16_t adjust_c[DPU_MAX_DE_CURVES];
+};
+
+/**
+ * struct dpu_drm_scaler_v2 - version 2 of struct dpu_drm_scaler
+ * @enable:            Scaler enable
+ * @dir_en:            Detail enhancer enable
+ * @pe:                Pixel extension settings
+ * @horz_decimate:     Horizontal decimation factor
+ * @vert_decimate:     Vertical decimation factor
+ * @init_phase_x:      Initial scaler phase values for x
+ * @phase_step_x:      Phase step values for x
+ * @init_phase_y:      Initial scaler phase values for y
+ * @phase_step_y:      Phase step values for y
+ * @preload_x:         Horizontal preload value
+ * @preload_y:         Vertical preload value
+ * @src_width:         Source width
+ * @src_height:        Source height
+ * @dst_width:         Destination width
+ * @dst_height:        Destination height
+ * @y_rgb_filter_cfg:  Y/RGB plane filter configuration
+ * @uv_filter_cfg:     UV plane filter configuration
+ * @alpha_filter_cfg:  Alpha filter configuration
+ * @blend_cfg:         Selection of blend coefficients
+ * @lut_flag:          LUT configuration flags
+ * @dir_lut_idx:       2d 4x4 LUT index
+ * @y_rgb_cir_lut_idx: Y/RGB circular LUT index
+ * @uv_cir_lut_idx:    UV circular LUT index
+ * @y_rgb_sep_lut_idx: Y/RGB separable LUT index
+ * @uv_sep_lut_idx:    UV separable LUT index
+ * @de:                Detail enhancer settings
+ */
+struct dpu_drm_scaler_v2 {
+	/*
+	 * General definitions
+	 */
+	uint32_t enable;
+	uint32_t dir_en;
+
+	/*
+	 * Pix ext settings
+	 */
+	struct dpu_drm_pix_ext_v1 pe;
+
+	/*
+	 * Decimation settings
+	 */
+	uint32_t horz_decimate;
+	uint32_t vert_decimate;
+
+	/*
+	 * Phase settings
+	 */
+	int32_t init_phase_x[DPU_MAX_PLANES];
+	int32_t phase_step_x[DPU_MAX_PLANES];
+	int32_t init_phase_y[DPU_MAX_PLANES];
+	int32_t phase_step_y[DPU_MAX_PLANES];
+
+	uint32_t preload_x[DPU_MAX_PLANES];
+	uint32_t preload_y[DPU_MAX_PLANES];
+	uint32_t src_width[DPU_MAX_PLANES];
+	uint32_t src_height[DPU_MAX_PLANES];
+
+	uint32_t dst_width;
+	uint32_t dst_height;
+
+	uint32_t y_rgb_filter_cfg;
+	uint32_t uv_filter_cfg;
+	uint32_t alpha_filter_cfg;
+	uint32_t blend_cfg;
+
+	uint32_t lut_flag;
+	uint32_t dir_lut_idx;
+
+	/* for Y(RGB) and UV planes*/
+	uint32_t y_rgb_cir_lut_idx;
+	uint32_t uv_cir_lut_idx;
+	uint32_t y_rgb_sep_lut_idx;
+	uint32_t uv_sep_lut_idx;
+
+	/*
+	 * Detail enhancer settings
+	 */
+	struct dpu_drm_de_v1 de;
+};
+
+/**
+ * struct dpu_hw_qos_cfg: pipe QoS configuration
+ * @danger_lut: LUT for generate danger level based on fill level
+ * @safe_lut: LUT for generate safe level based on fill level
+ * @creq_lut: LUT for generate creq level based on fill level
+ * @creq_vblank: creq value generated to vbif during vertical blanking
+ * @danger_vblank: danger value generated during vertical blanking
+ * @vblank_en: enable creq_vblank and danger_vblank during vblank
+ * @danger_safe_en: enable danger safe generation
+ */
+struct dpu_hw_qos_cfg {
+	u32 danger_lut;
+	u32 safe_lut;
+	u64 creq_lut;
+	bool danger_safe_en;
+};
+
+u32 *dpu_hw_util_get_log_mask_ptr(void);
+
+void dpu_reg_write(struct dpu_hw_blk_reg_map *c,
+		u32 reg_off,
+		u32 val,
+		const char *name);
+int dpu_reg_read(struct dpu_hw_blk_reg_map *c, u32 reg_off);
+
+#define DPU_REG_WRITE(c, off, val) dpu_reg_write(c, off, val, #off)
+#define DPU_REG_READ(c, off) dpu_reg_read(c, off)
+
+void *dpu_hw_util_get_dir(void);
+
+void dpu_hw_setup_scaler3(struct dpu_hw_blk_reg_map *c,
+		struct dpu_hw_scaler3_cfg *scaler3_cfg,
+		u32 scaler_offset, u32 scaler_version,
+		const struct dpu_format *format);
+
+void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map  *c,
+		u32 csc_reg_off,
+		const struct dpu_csc_cfg *data, bool csc10);
+
+void dpu_setup_cdp(struct dpu_hw_blk_reg_map *c, u32 offset,
+		   const struct dpu_format *fmt, bool enable);
+
+u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl,
+		u32 total_fl);
+
+void _dpu_hw_setup_qos_lut(struct dpu_hw_blk_reg_map *c, u32 offset,
+			   bool qos_8lvl,
+			   const struct dpu_hw_qos_cfg *cfg);
+
+void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c,
+		u32 misr_ctrl_offset, u8 input_sel);
+
+int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c,
+		u32 misr_ctrl_offset,
+		u32 misr_signature_offset,
+		u32 *misr_value);
+
+bool dpu_hw_clk_force_ctrl(struct dpu_hw_blk_reg_map *c,
+			   const struct dpu_clk_ctrl_reg *clk_ctrl_reg,
+			   bool enable);
+
+#endif /* _DPU_HW_UTIL_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_vbif.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_vbif.c
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <drm/drm_managed.h>
+
+#include "dpu_hwio.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_vbif.h"
+
+#define VBIF_VERSION			0x0000
+#define VBIF_CLK_FORCE_CTRL0		0x0008
+#define VBIF_CLK_FORCE_CTRL1		0x000C
+#define VBIF_QOS_REMAP_00		0x0020
+#define VBIF_QOS_REMAP_01		0x0024
+#define VBIF_QOS_REMAP_10		0x0028
+#define VBIF_QOS_REMAP_11		0x002C
+#define VBIF_WRITE_GATHER_EN		0x00AC
+#define VBIF_IN_RD_LIM_CONF0		0x00B0
+#define VBIF_IN_RD_LIM_CONF1		0x00B4
+#define VBIF_IN_RD_LIM_CONF2		0x00B8
+#define VBIF_IN_WR_LIM_CONF0		0x00C0
+#define VBIF_IN_WR_LIM_CONF1		0x00C4
+#define VBIF_IN_WR_LIM_CONF2		0x00C8
+#define VBIF_OUT_RD_LIM_CONF0		0x00D0
+#define VBIF_OUT_WR_LIM_CONF0		0x00D4
+#define VBIF_OUT_AXI_AMEMTYPE_CONF0	0x0160
+#define VBIF_OUT_AXI_AMEMTYPE_CONF1	0x0164
+#define VBIF_XIN_PND_ERR		0x0190
+#define VBIF_XIN_SRC_ERR		0x0194
+#define VBIF_XIN_CLR_ERR		0x019C
+#define VBIF_XIN_HALT_CTRL0		0x0200
+#define VBIF_XIN_HALT_CTRL1		0x0204
+#define VBIF_XINL_QOS_RP_REMAP_000	0x0550
+#define VBIF_XINL_QOS_LVL_REMAP_000(vbif)	(VBIF_XINL_QOS_RP_REMAP_000 + (vbif)->cap->qos_rp_remap_size)
+
+static void dpu_hw_clear_errors(struct dpu_hw_vbif *vbif,
+		u32 *pnd_errors, u32 *src_errors)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 pnd, src;
+
+	if (!vbif)
+		return;
+	c = &vbif->hw;
+	pnd = DPU_REG_READ(c, VBIF_XIN_PND_ERR);
+	src = DPU_REG_READ(c, VBIF_XIN_SRC_ERR);
+
+	if (pnd_errors)
+		*pnd_errors = pnd;
+	if (src_errors)
+		*src_errors = src;
+
+	DPU_REG_WRITE(c, VBIF_XIN_CLR_ERR, pnd | src);
+}
+
+static void dpu_hw_set_mem_type(struct dpu_hw_vbif *vbif,
+		u32 xin_id, u32 value)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 reg_off;
+	u32 bit_off;
+	u32 reg_val;
+
+	/*
+	 * Assume 4 bits per bit field, 8 fields per 32-bit register so
+	 * 16 bit fields maximum across two registers
+	 */
+	if (!vbif || xin_id >= MAX_XIN_COUNT || xin_id >= 16)
+		return;
+
+	c = &vbif->hw;
+
+	if (xin_id >= 8) {
+		xin_id -= 8;
+		reg_off = VBIF_OUT_AXI_AMEMTYPE_CONF1;
+	} else {
+		reg_off = VBIF_OUT_AXI_AMEMTYPE_CONF0;
+	}
+	bit_off = (xin_id & 0x7) * 4;
+	reg_val = DPU_REG_READ(c, reg_off);
+	reg_val &= ~(0x7 << bit_off);
+	reg_val |= (value & 0x7) << bit_off;
+	DPU_REG_WRITE(c, reg_off, reg_val);
+}
+
+static void dpu_hw_set_limit_conf(struct dpu_hw_vbif *vbif,
+		u32 xin_id, bool rd, u32 limit)
+{
+	struct dpu_hw_blk_reg_map *c = &vbif->hw;
+	u32 reg_val;
+	u32 reg_off;
+	u32 bit_off;
+
+	if (rd)
+		reg_off = VBIF_IN_RD_LIM_CONF0;
+	else
+		reg_off = VBIF_IN_WR_LIM_CONF0;
+
+	reg_off += (xin_id / 4) * 4;
+	bit_off = (xin_id % 4) * 8;
+	reg_val = DPU_REG_READ(c, reg_off);
+	reg_val &= ~(0xFF << bit_off);
+	reg_val |= (limit) << bit_off;
+	DPU_REG_WRITE(c, reg_off, reg_val);
+}
+
+static u32 dpu_hw_get_limit_conf(struct dpu_hw_vbif *vbif,
+		u32 xin_id, bool rd)
+{
+	struct dpu_hw_blk_reg_map *c = &vbif->hw;
+	u32 reg_val;
+	u32 reg_off;
+	u32 bit_off;
+	u32 limit;
+
+	if (rd)
+		reg_off = VBIF_IN_RD_LIM_CONF0;
+	else
+		reg_off = VBIF_IN_WR_LIM_CONF0;
+
+	reg_off += (xin_id / 4) * 4;
+	bit_off = (xin_id % 4) * 8;
+	reg_val = DPU_REG_READ(c, reg_off);
+	limit = (reg_val >> bit_off) & 0xFF;
+
+	return limit;
+}
+
+static void dpu_hw_set_halt_ctrl(struct dpu_hw_vbif *vbif,
+		u32 xin_id, bool enable)
+{
+	struct dpu_hw_blk_reg_map *c = &vbif->hw;
+	u32 reg_val;
+
+	reg_val = DPU_REG_READ(c, VBIF_XIN_HALT_CTRL0);
+
+	if (enable)
+		reg_val |= BIT(xin_id);
+	else
+		reg_val &= ~BIT(xin_id);
+
+	DPU_REG_WRITE(c, VBIF_XIN_HALT_CTRL0, reg_val);
+}
+
+static bool dpu_hw_get_halt_ctrl(struct dpu_hw_vbif *vbif,
+		u32 xin_id)
+{
+	struct dpu_hw_blk_reg_map *c = &vbif->hw;
+	u32 reg_val;
+
+	reg_val = DPU_REG_READ(c, VBIF_XIN_HALT_CTRL1);
+
+	return (reg_val & BIT(xin_id)) ? true : false;
+}
+
+static void dpu_hw_set_qos_remap(struct dpu_hw_vbif *vbif,
+		u32 xin_id, u32 level, u32 remap_level)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 reg_lvl, reg_val, reg_val_lvl, mask, reg_high, reg_shift;
+
+	if (!vbif)
+		return;
+
+	c = &vbif->hw;
+
+	reg_lvl = VBIF_XINL_QOS_LVL_REMAP_000(vbif);
+	reg_high = ((xin_id & 0x8) >> 3) * 4 + (level * 8);
+	reg_shift = (xin_id & 0x7) * 4;
+
+	reg_val = DPU_REG_READ(c, VBIF_XINL_QOS_RP_REMAP_000 + reg_high);
+	reg_val_lvl = DPU_REG_READ(c, reg_lvl + reg_high);
+
+	mask = 0x7 << reg_shift;
+
+	reg_val &= ~mask;
+	reg_val |= (remap_level << reg_shift) & mask;
+
+	reg_val_lvl &= ~mask;
+	reg_val_lvl |= (remap_level << reg_shift) & mask;
+
+	DPU_REG_WRITE(c, VBIF_XINL_QOS_RP_REMAP_000 + reg_high, reg_val);
+	DPU_REG_WRITE(c, reg_lvl + reg_high, reg_val_lvl);
+}
+
+static void dpu_hw_set_write_gather_en(struct dpu_hw_vbif *vbif, u32 xin_id)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 reg_val;
+
+	if (!vbif || xin_id >= MAX_XIN_COUNT)
+		return;
+
+	c = &vbif->hw;
+
+	reg_val = DPU_REG_READ(c, VBIF_WRITE_GATHER_EN);
+	reg_val |= BIT(xin_id);
+	DPU_REG_WRITE(c, VBIF_WRITE_GATHER_EN, reg_val);
+}
+
+static void _setup_vbif_ops(struct dpu_hw_vbif_ops *ops,
+		unsigned long cap)
+{
+	ops->set_limit_conf = dpu_hw_set_limit_conf;
+	ops->get_limit_conf = dpu_hw_get_limit_conf;
+	ops->set_halt_ctrl = dpu_hw_set_halt_ctrl;
+	ops->get_halt_ctrl = dpu_hw_get_halt_ctrl;
+	if (test_bit(DPU_VBIF_QOS_REMAP, &cap))
+		ops->set_qos_remap = dpu_hw_set_qos_remap;
+	ops->set_mem_type = dpu_hw_set_mem_type;
+	ops->clear_errors = dpu_hw_clear_errors;
+	ops->set_write_gather_en = dpu_hw_set_write_gather_en;
+}
+
+struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev,
+				     const struct dpu_vbif_cfg *cfg,
+				     void __iomem *addr)
+{
+	struct dpu_hw_vbif *c;
+
+	c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
+	if (!c)
+		return ERR_PTR(-ENOMEM);
+
+	c->hw.blk_addr = addr + cfg->base;
+	c->hw.log_mask = DPU_DBG_MASK_VBIF;
+
+	/*
+	 * Assign ops
+	 */
+	c->idx = cfg->id;
+	c->cap = cfg;
+	_setup_vbif_ops(&c->ops, c->cap->features);
+
+	/* no need to register sub-range in dpu dbg, dump entire vbif io base */
+
+	return c;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_vbif.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_vbif.h
@@ -0,0 +1,119 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HW_VBIF_H
+#define _DPU_HW_VBIF_H
+
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_util.h"
+
+struct dpu_hw_vbif;
+
+/**
+ * struct dpu_hw_vbif_ops : Interface to the VBIF hardware driver functions
+ *  Assumption is these functions will be called after clocks are enabled
+ */
+struct dpu_hw_vbif_ops {
+	/**
+	 * set_limit_conf - set transaction limit config
+	 * @vbif: vbif context driver
+	 * @xin_id: client interface identifier
+	 * @rd: true for read limit; false for write limit
+	 * @limit: outstanding transaction limit
+	 */
+	void (*set_limit_conf)(struct dpu_hw_vbif *vbif,
+			u32 xin_id, bool rd, u32 limit);
+
+	/**
+	 * get_limit_conf - get transaction limit config
+	 * @vbif: vbif context driver
+	 * @xin_id: client interface identifier
+	 * @rd: true for read limit; false for write limit
+	 * @return: outstanding transaction limit
+	 */
+	u32 (*get_limit_conf)(struct dpu_hw_vbif *vbif,
+			u32 xin_id, bool rd);
+
+	/**
+	 * set_halt_ctrl - set halt control
+	 * @vbif: vbif context driver
+	 * @xin_id: client interface identifier
+	 * @enable: halt control enable
+	 */
+	void (*set_halt_ctrl)(struct dpu_hw_vbif *vbif,
+			u32 xin_id, bool enable);
+
+	/**
+	 * get_halt_ctrl - get halt control
+	 * @vbif: vbif context driver
+	 * @xin_id: client interface identifier
+	 * @return: halt control enable
+	 */
+	bool (*get_halt_ctrl)(struct dpu_hw_vbif *vbif,
+			u32 xin_id);
+
+	/**
+	 * set_qos_remap - set QoS priority remap
+	 * @vbif: vbif context driver
+	 * @xin_id: client interface identifier
+	 * @level: priority level
+	 * @remap_level: remapped level
+	 */
+	void (*set_qos_remap)(struct dpu_hw_vbif *vbif,
+			u32 xin_id, u32 level, u32 remap_level);
+
+	/**
+	 * set_mem_type - set memory type
+	 * @vbif: vbif context driver
+	 * @xin_id: client interface identifier
+	 * @value: memory type value
+	 */
+	void (*set_mem_type)(struct dpu_hw_vbif *vbif,
+			u32 xin_id, u32 value);
+
+	/**
+	 * clear_errors - clear any vbif errors
+	 *	This function clears any detected pending/source errors
+	 *	on the VBIF interface, and optionally returns the detected
+	 *	error mask(s).
+	 * @vbif: vbif context driver
+	 * @pnd_errors: pointer to pending error reporting variable
+	 * @src_errors: pointer to source error reporting variable
+	 */
+	void (*clear_errors)(struct dpu_hw_vbif *vbif,
+		u32 *pnd_errors, u32 *src_errors);
+
+	/**
+	 * set_write_gather_en - set write_gather enable
+	 * @vbif: vbif context driver
+	 * @xin_id: client interface identifier
+	 */
+	void (*set_write_gather_en)(struct dpu_hw_vbif *vbif, u32 xin_id);
+};
+
+struct dpu_hw_vbif {
+	/* base */
+	struct dpu_hw_blk_reg_map hw;
+
+	/* vbif */
+	enum dpu_vbif idx;
+	const struct dpu_vbif_cfg *cap;
+
+	/* ops */
+	struct dpu_hw_vbif_ops ops;
+};
+
+/**
+ * dpu_hw_vbif_init() - Initializes the VBIF driver for the passed
+ * VBIF catalog entry.
+ * @dev:  Corresponding device for devres management
+ * @cfg:  VBIF catalog entry for which driver object is required
+ * @addr: Mapped register io address of MDSS
+ */
+struct dpu_hw_vbif *dpu_hw_vbif_init(struct drm_device *dev,
+				     const struct dpu_vbif_cfg *cfg,
+				     void __iomem *addr);
+
+#endif /*_DPU_HW_VBIF_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_wb.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_wb.c
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0-only
+ /*
+  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved
+  */
+
+#include <drm/drm_managed.h>
+
+#include "dpu_hw_mdss.h"
+#include "dpu_hwio.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_wb.h"
+#include "dpu_formats.h"
+#include "dpu_kms.h"
+
+#define WB_DST_FORMAT                         0x000
+#define WB_DST_OP_MODE                        0x004
+#define WB_DST_PACK_PATTERN                   0x008
+#define WB_DST0_ADDR                          0x00C
+#define WB_DST1_ADDR                          0x010
+#define WB_DST2_ADDR                          0x014
+#define WB_DST3_ADDR                          0x018
+#define WB_DST_YSTRIDE0                       0x01C
+#define WB_DST_YSTRIDE1                       0x020
+#define WB_DST_YSTRIDE1                       0x020
+#define WB_DST_DITHER_BITDEPTH                0x024
+#define WB_DST_MATRIX_ROW0                    0x030
+#define WB_DST_MATRIX_ROW1                    0x034
+#define WB_DST_MATRIX_ROW2                    0x038
+#define WB_DST_MATRIX_ROW3                    0x03C
+#define WB_DST_WRITE_CONFIG                   0x048
+#define WB_ROTATION_DNSCALER                  0x050
+#define WB_ROTATOR_PIPE_DOWNSCALER            0x054
+#define WB_N16_INIT_PHASE_X_C03               0x060
+#define WB_N16_INIT_PHASE_X_C12               0x064
+#define WB_N16_INIT_PHASE_Y_C03               0x068
+#define WB_N16_INIT_PHASE_Y_C12               0x06C
+#define WB_OUT_SIZE                           0x074
+#define WB_ALPHA_X_VALUE                      0x078
+#define WB_DANGER_LUT                         0x084
+#define WB_SAFE_LUT                           0x088
+#define WB_QOS_CTRL                           0x090
+#define WB_CREQ_LUT_0                         0x098
+#define WB_CREQ_LUT_1                         0x09C
+#define WB_UBWC_STATIC_CTRL                   0x144
+#define WB_MUX                                0x150
+#define WB_CROP_CTRL                          0x154
+#define WB_CROP_OFFSET                        0x158
+#define WB_CLK_CTRL                           0x178
+#define WB_CSC_BASE                           0x260
+#define WB_DST_ADDR_SW_STATUS                 0x2B0
+#define WB_CDP_CNTL                           0x2B4
+#define WB_OUT_IMAGE_SIZE                     0x2C0
+#define WB_OUT_XY                             0x2C4
+
+static void dpu_hw_wb_setup_outaddress(struct dpu_hw_wb *ctx,
+		struct dpu_hw_wb_cfg *data)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+
+	DPU_REG_WRITE(c, WB_DST0_ADDR, data->dest.plane_addr[0]);
+	DPU_REG_WRITE(c, WB_DST1_ADDR, data->dest.plane_addr[1]);
+	DPU_REG_WRITE(c, WB_DST2_ADDR, data->dest.plane_addr[2]);
+	DPU_REG_WRITE(c, WB_DST3_ADDR, data->dest.plane_addr[3]);
+}
+
+static void dpu_hw_wb_setup_format(struct dpu_hw_wb *ctx,
+		struct dpu_hw_wb_cfg *data)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	const struct dpu_format *fmt = data->dest.format;
+	u32 dst_format, pattern, ystride0, ystride1, outsize, chroma_samp;
+	u32 write_config = 0;
+	u32 opmode = 0;
+	u32 dst_addr_sw = 0;
+
+	chroma_samp = fmt->chroma_sample;
+
+	dst_format = (chroma_samp << 23) |
+		(fmt->fetch_planes << 19) |
+		(fmt->bits[C3_ALPHA] << 6) |
+		(fmt->bits[C2_R_Cr] << 4) |
+		(fmt->bits[C1_B_Cb] << 2) |
+		(fmt->bits[C0_G_Y] << 0);
+
+	if (fmt->bits[C3_ALPHA] || fmt->alpha_enable) {
+		dst_format |= BIT(8); /* DSTC3_EN */
+		if (!fmt->alpha_enable ||
+			!(ctx->caps->features & BIT(DPU_WB_PIPE_ALPHA)))
+			dst_format |= BIT(14); /* DST_ALPHA_X */
+	}
+
+	if (DPU_FORMAT_IS_YUV(fmt))
+		dst_format |= BIT(15);
+
+	pattern = (fmt->element[3] << 24) |
+		(fmt->element[2] << 16) |
+		(fmt->element[1] << 8)  |
+		(fmt->element[0] << 0);
+
+	dst_format |= (fmt->unpack_align_msb << 18) |
+		(fmt->unpack_tight << 17) |
+		((fmt->unpack_count - 1) << 12) |
+		((fmt->bpp - 1) << 9);
+
+	ystride0 = data->dest.plane_pitch[0] |
+		(data->dest.plane_pitch[1] << 16);
+	ystride1 = data->dest.plane_pitch[2] |
+	(data->dest.plane_pitch[3] << 16);
+
+	if (drm_rect_height(&data->roi) && drm_rect_width(&data->roi))
+		outsize = (drm_rect_height(&data->roi) << 16) | drm_rect_width(&data->roi);
+	else
+		outsize = (data->dest.height << 16) | data->dest.width;
+
+	DPU_REG_WRITE(c, WB_ALPHA_X_VALUE, 0xFF);
+	DPU_REG_WRITE(c, WB_DST_FORMAT, dst_format);
+	DPU_REG_WRITE(c, WB_DST_OP_MODE, opmode);
+	DPU_REG_WRITE(c, WB_DST_PACK_PATTERN, pattern);
+	DPU_REG_WRITE(c, WB_DST_YSTRIDE0, ystride0);
+	DPU_REG_WRITE(c, WB_DST_YSTRIDE1, ystride1);
+	DPU_REG_WRITE(c, WB_OUT_SIZE, outsize);
+	DPU_REG_WRITE(c, WB_DST_WRITE_CONFIG, write_config);
+	DPU_REG_WRITE(c, WB_DST_ADDR_SW_STATUS, dst_addr_sw);
+}
+
+static void dpu_hw_wb_roi(struct dpu_hw_wb *ctx, struct dpu_hw_wb_cfg *wb)
+{
+	struct dpu_hw_blk_reg_map *c = &ctx->hw;
+	u32 image_size, out_size, out_xy;
+
+	image_size = (wb->dest.height << 16) | wb->dest.width;
+	out_xy = 0;
+	out_size = (drm_rect_height(&wb->roi) << 16) | drm_rect_width(&wb->roi);
+
+	DPU_REG_WRITE(c, WB_OUT_IMAGE_SIZE, image_size);
+	DPU_REG_WRITE(c, WB_OUT_XY, out_xy);
+	DPU_REG_WRITE(c, WB_OUT_SIZE, out_size);
+}
+
+static void dpu_hw_wb_setup_qos_lut(struct dpu_hw_wb *ctx,
+		struct dpu_hw_qos_cfg *cfg)
+{
+	if (!ctx || !cfg)
+		return;
+
+	_dpu_hw_setup_qos_lut(&ctx->hw, WB_DANGER_LUT,
+			      test_bit(DPU_WB_QOS_8LVL, &ctx->caps->features),
+			      cfg);
+}
+
+static void dpu_hw_wb_setup_cdp(struct dpu_hw_wb *ctx,
+				const struct dpu_format *fmt,
+				bool enable)
+{
+	if (!ctx)
+		return;
+
+	dpu_setup_cdp(&ctx->hw, WB_CDP_CNTL, fmt, enable);
+}
+
+static void dpu_hw_wb_bind_pingpong_blk(
+		struct dpu_hw_wb *ctx,
+		const enum dpu_pingpong pp)
+{
+	struct dpu_hw_blk_reg_map *c;
+	int mux_cfg;
+
+	if (!ctx)
+		return;
+
+	c = &ctx->hw;
+
+	mux_cfg = DPU_REG_READ(c, WB_MUX);
+	mux_cfg &= ~0xf;
+
+	if (pp)
+		mux_cfg |= (pp - PINGPONG_0) & 0x7;
+	else
+		mux_cfg |= 0xf;
+
+	DPU_REG_WRITE(c, WB_MUX, mux_cfg);
+}
+
+static bool dpu_hw_wb_setup_clk_force_ctrl(struct dpu_hw_wb *ctx, bool enable)
+{
+	static const struct dpu_clk_ctrl_reg wb_clk_ctrl = {
+		.reg_off = WB_CLK_CTRL,
+		.bit_off = 0
+	};
+
+	return dpu_hw_clk_force_ctrl(&ctx->hw, &wb_clk_ctrl, enable);
+}
+
+static void _setup_wb_ops(struct dpu_hw_wb_ops *ops,
+		unsigned long features, const struct dpu_mdss_version *mdss_rev)
+{
+	ops->setup_outaddress = dpu_hw_wb_setup_outaddress;
+	ops->setup_outformat = dpu_hw_wb_setup_format;
+
+	if (test_bit(DPU_WB_XY_ROI_OFFSET, &features))
+		ops->setup_roi = dpu_hw_wb_roi;
+
+	if (test_bit(DPU_WB_QOS, &features))
+		ops->setup_qos_lut = dpu_hw_wb_setup_qos_lut;
+
+	if (test_bit(DPU_WB_CDP, &features))
+		ops->setup_cdp = dpu_hw_wb_setup_cdp;
+
+	if (test_bit(DPU_WB_INPUT_CTRL, &features))
+		ops->bind_pingpong_blk = dpu_hw_wb_bind_pingpong_blk;
+
+	if (mdss_rev->core_major_ver >= 9)
+		ops->setup_clk_force_ctrl = dpu_hw_wb_setup_clk_force_ctrl;
+}
+
+struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev,
+				 const struct dpu_wb_cfg *cfg,
+				 void __iomem *addr,
+				 const struct dpu_mdss_version *mdss_rev)
+{
+	struct dpu_hw_wb *c;
+
+	if (!addr)
+		return ERR_PTR(-EINVAL);
+
+	c = drmm_kzalloc(dev, sizeof(*c), GFP_KERNEL);
+	if (!c)
+		return ERR_PTR(-ENOMEM);
+
+	c->hw.blk_addr = addr + cfg->base;
+	c->hw.log_mask = DPU_DBG_MASK_WB;
+
+	/* Assign ops */
+	c->idx = cfg->id;
+	c->caps = cfg;
+	_setup_wb_ops(&c->ops, c->caps->features, mdss_rev);
+
+	return c;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_wb.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hw_wb.h
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved
+ */
+
+#ifndef _DPU_HW_WB_H
+#define _DPU_HW_WB_H
+
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_top.h"
+#include "dpu_hw_util.h"
+#include "dpu_hw_pingpong.h"
+
+struct dpu_hw_wb;
+
+struct dpu_hw_wb_cfg {
+	struct dpu_hw_fmt_layout dest;
+	enum dpu_intf_mode intf_mode;
+	struct drm_rect roi;
+	struct drm_rect crop;
+};
+
+/**
+ *
+ * struct dpu_hw_wb_ops : Interface to the wb hw driver functions
+ *  Assumption is these functions will be called after clocks are enabled
+ *  @setup_outaddress: setup output address from the writeback job
+ *  @setup_outformat: setup output format of writeback block from writeback job
+ *  @setup_qos_lut:   setup qos LUT for writeback block based on input
+ *  @setup_cdp:       setup chroma down prefetch block for writeback block
+ *  @setup_clk_force_ctrl: setup clock force control
+ *  @bind_pingpong_blk: enable/disable the connection with ping-pong block
+ */
+struct dpu_hw_wb_ops {
+	void (*setup_outaddress)(struct dpu_hw_wb *ctx,
+			struct dpu_hw_wb_cfg *wb);
+
+	void (*setup_outformat)(struct dpu_hw_wb *ctx,
+			struct dpu_hw_wb_cfg *wb);
+
+	void (*setup_roi)(struct dpu_hw_wb *ctx,
+			struct dpu_hw_wb_cfg *wb);
+
+	void (*setup_qos_lut)(struct dpu_hw_wb *ctx,
+			struct dpu_hw_qos_cfg *cfg);
+
+	void (*setup_cdp)(struct dpu_hw_wb *ctx,
+			  const struct dpu_format *fmt,
+			  bool enable);
+
+	bool (*setup_clk_force_ctrl)(struct dpu_hw_wb *ctx,
+				     bool enable);
+
+	void (*bind_pingpong_blk)(struct dpu_hw_wb *ctx,
+				  const enum dpu_pingpong pp);
+};
+
+/**
+ * struct dpu_hw_wb : WB driver object
+ * @hw: block hardware details
+ * @idx: hardware index number within type
+ * @wb_hw_caps: hardware capabilities
+ * @ops: function pointers
+ */
+struct dpu_hw_wb {
+	struct dpu_hw_blk_reg_map hw;
+
+	/* wb path */
+	int idx;
+	const struct dpu_wb_cfg *caps;
+
+	/* ops */
+	struct dpu_hw_wb_ops ops;
+};
+
+/**
+ * dpu_hw_wb_init() - Initializes the writeback hw driver object.
+ * @dev:  Corresponding device for devres management
+ * @cfg:  wb_path catalog entry for which driver object is required
+ * @addr: mapped register io address of MDP
+ * @mdss_rev: dpu core's major and minor versions
+ * Return: Error code or allocated dpu_hw_wb context
+ */
+struct dpu_hw_wb *dpu_hw_wb_init(struct drm_device *dev,
+				 const struct dpu_wb_cfg *cfg,
+				 void __iomem *addr,
+				 const struct dpu_mdss_version *mdss_rev);
+
+#endif /*_DPU_HW_WB_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hwio.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_hwio.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DPU_HWIO_H
+#define _DPU_HWIO_H
+
+#include "dpu_hw_util.h"
+
+/**
+ * MDP TOP block Register and bit fields and defines
+ */
+#define DISP_INTF_SEL                   0x004
+#define INTR_EN                         0x010
+#define INTR_STATUS                     0x014
+#define INTR_CLEAR                      0x018
+#define INTR2_EN                        0x008
+#define INTR2_STATUS                    0x00c
+#define SSPP_SPARE                      0x028
+#define INTR2_CLEAR                     0x02c
+#define HIST_INTR_EN                    0x01c
+#define HIST_INTR_STATUS                0x020
+#define HIST_INTR_CLEAR                 0x024
+#define SPLIT_DISPLAY_EN                0x2F4
+#define SPLIT_DISPLAY_UPPER_PIPE_CTRL   0x2F8
+#define DSPP_IGC_COLOR0_RAM_LUTN        0x300
+#define DSPP_IGC_COLOR1_RAM_LUTN        0x304
+#define DSPP_IGC_COLOR2_RAM_LUTN        0x308
+#define DANGER_STATUS                   0x360
+#define SAFE_STATUS                     0x364
+#define HW_EVENTS_CTL                   0x37C
+#define MDP_WD_TIMER_0_CTL              0x380
+#define MDP_WD_TIMER_0_CTL2             0x384
+#define MDP_WD_TIMER_0_LOAD_VALUE       0x388
+#define MDP_WD_TIMER_1_CTL              0x390
+#define MDP_WD_TIMER_1_CTL2             0x394
+#define MDP_WD_TIMER_1_LOAD_VALUE       0x398
+#define CLK_CTRL3                       0x3A8
+#define CLK_STATUS3                     0x3AC
+#define CLK_CTRL4                       0x3B0
+#define CLK_STATUS4                     0x3B4
+#define CLK_CTRL5                       0x3B8
+#define CLK_STATUS5                     0x3BC
+#define CLK_CTRL7                       0x3D0
+#define CLK_STATUS7                     0x3D4
+#define SPLIT_DISPLAY_LOWER_PIPE_CTRL   0x3F0
+#define SPLIT_DISPLAY_TE_LINE_INTERVAL  0x3F4
+#define INTF_SW_RESET_MASK              0x3FC
+#define HDMI_DP_CORE_SELECT             0x408
+#define MDP_OUT_CTL_0                   0x410
+#define MDP_VSYNC_SEL                   0x414
+#define MDP_WD_TIMER_2_CTL              0x420
+#define MDP_WD_TIMER_2_CTL2             0x424
+#define MDP_WD_TIMER_2_LOAD_VALUE       0x428
+#define MDP_WD_TIMER_3_CTL              0x430
+#define MDP_WD_TIMER_3_CTL2             0x434
+#define MDP_WD_TIMER_3_LOAD_VALUE       0x438
+#define MDP_WD_TIMER_4_CTL              0x440
+#define MDP_WD_TIMER_4_CTL2             0x444
+#define MDP_WD_TIMER_4_LOAD_VALUE       0x448
+#define DCE_SEL                         0x450
+
+#define MDP_PERIPH_TOP0			MDP_WD_TIMER_0_CTL
+#define MDP_PERIPH_TOP0_END		CLK_CTRL3
+
+#endif /*_DPU_HWIO_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_kms.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_kms.c
@@ -0,0 +1,1402 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+
+#include <linux/debugfs.h>
+#include <linux/dma-buf.h>
+#include <linux/of_irq.h>
+#include <linux/pm_opp.h>
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_file.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_vblank.h>
+#include <drm/drm_writeback.h>
+
+#include "msm_drv.h"
+#include "msm_mmu.h"
+#include "msm_mdss.h"
+#include "msm_gem.h"
+#include "disp/msm_disp_snapshot.h"
+
+#include "dpu_core_irq.h"
+#include "dpu_crtc.h"
+#include "dpu_encoder.h"
+#include "dpu_formats.h"
+#include "dpu_hw_vbif.h"
+#include "dpu_kms.h"
+#include "dpu_plane.h"
+#include "dpu_vbif.h"
+#include "dpu_writeback.h"
+
+#define CREATE_TRACE_POINTS
+#include "dpu_trace.h"
+
+/*
+ * To enable overall DRM driver logging
+ * # echo 0x2 > /sys/module/drm/parameters/debug
+ *
+ * To enable DRM driver h/w logging
+ * # echo <mask> > /sys/kernel/debug/dri/0/debug/hw_log_mask
+ *
+ * See dpu_hw_mdss.h for h/w logging mask definitions (search for DPU_DBG_MASK_)
+ */
+#define DPU_DEBUGFS_DIR "msm_dpu"
+#define DPU_DEBUGFS_HWMASKNAME "hw_log_mask"
+
+static int dpu_kms_hw_init(struct msm_kms *kms);
+static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms);
+
+#ifdef CONFIG_DEBUG_FS
+static int _dpu_danger_signal_status(struct seq_file *s,
+		bool danger_status)
+{
+	struct dpu_danger_safe_status status;
+	struct dpu_kms *kms = s->private;
+	int i;
+
+	if (!kms->hw_mdp) {
+		DPU_ERROR("invalid arg(s)\n");
+		return 0;
+	}
+
+	memset(&status, 0, sizeof(struct dpu_danger_safe_status));
+
+	pm_runtime_get_sync(&kms->pdev->dev);
+	if (danger_status) {
+		seq_puts(s, "\nDanger signal status:\n");
+		if (kms->hw_mdp->ops.get_danger_status)
+			kms->hw_mdp->ops.get_danger_status(kms->hw_mdp,
+					&status);
+	} else {
+		seq_puts(s, "\nSafe signal status:\n");
+		if (kms->hw_mdp->ops.get_safe_status)
+			kms->hw_mdp->ops.get_safe_status(kms->hw_mdp,
+					&status);
+	}
+	pm_runtime_put_sync(&kms->pdev->dev);
+
+	seq_printf(s, "MDP     :  0x%x\n", status.mdp);
+
+	for (i = SSPP_VIG0; i < SSPP_MAX; i++)
+		seq_printf(s, "SSPP%d   :  0x%x  \n", i - SSPP_VIG0,
+				status.sspp[i]);
+	seq_puts(s, "\n");
+
+	return 0;
+}
+
+static int dpu_debugfs_danger_stats_show(struct seq_file *s, void *v)
+{
+	return _dpu_danger_signal_status(s, true);
+}
+DEFINE_SHOW_ATTRIBUTE(dpu_debugfs_danger_stats);
+
+static int dpu_debugfs_safe_stats_show(struct seq_file *s, void *v)
+{
+	return _dpu_danger_signal_status(s, false);
+}
+DEFINE_SHOW_ATTRIBUTE(dpu_debugfs_safe_stats);
+
+static ssize_t _dpu_plane_danger_read(struct file *file,
+			char __user *buff, size_t count, loff_t *ppos)
+{
+	struct dpu_kms *kms = file->private_data;
+	int len;
+	char buf[40];
+
+	len = scnprintf(buf, sizeof(buf), "%d\n", !kms->has_danger_ctrl);
+
+	return simple_read_from_buffer(buff, count, ppos, buf, len);
+}
+
+static void _dpu_plane_set_danger_state(struct dpu_kms *kms, bool enable)
+{
+	struct drm_plane *plane;
+
+	drm_for_each_plane(plane, kms->dev) {
+		if (plane->fb && plane->state) {
+			dpu_plane_danger_signal_ctrl(plane, enable);
+			DPU_DEBUG("plane:%d img:%dx%d ",
+				plane->base.id, plane->fb->width,
+				plane->fb->height);
+			DPU_DEBUG("src[%d,%d,%d,%d] dst[%d,%d,%d,%d]\n",
+				plane->state->src_x >> 16,
+				plane->state->src_y >> 16,
+				plane->state->src_w >> 16,
+				plane->state->src_h >> 16,
+				plane->state->crtc_x, plane->state->crtc_y,
+				plane->state->crtc_w, plane->state->crtc_h);
+		} else {
+			DPU_DEBUG("Inactive plane:%d\n", plane->base.id);
+		}
+	}
+}
+
+static ssize_t _dpu_plane_danger_write(struct file *file,
+		    const char __user *user_buf, size_t count, loff_t *ppos)
+{
+	struct dpu_kms *kms = file->private_data;
+	int disable_panic;
+	int ret;
+
+	ret = kstrtouint_from_user(user_buf, count, 0, &disable_panic);
+	if (ret)
+		return ret;
+
+	if (disable_panic) {
+		/* Disable panic signal for all active pipes */
+		DPU_DEBUG("Disabling danger:\n");
+		_dpu_plane_set_danger_state(kms, false);
+		kms->has_danger_ctrl = false;
+	} else {
+		/* Enable panic signal for all active pipes */
+		DPU_DEBUG("Enabling danger:\n");
+		kms->has_danger_ctrl = true;
+		_dpu_plane_set_danger_state(kms, true);
+	}
+
+	return count;
+}
+
+static const struct file_operations dpu_plane_danger_enable = {
+	.open = simple_open,
+	.read = _dpu_plane_danger_read,
+	.write = _dpu_plane_danger_write,
+};
+
+static void dpu_debugfs_danger_init(struct dpu_kms *dpu_kms,
+		struct dentry *parent)
+{
+	struct dentry *entry = debugfs_create_dir("danger", parent);
+
+	debugfs_create_file("danger_status", 0600, entry,
+			dpu_kms, &dpu_debugfs_danger_stats_fops);
+	debugfs_create_file("safe_status", 0600, entry,
+			dpu_kms, &dpu_debugfs_safe_stats_fops);
+	debugfs_create_file("disable_danger", 0600, entry,
+			dpu_kms, &dpu_plane_danger_enable);
+
+}
+
+/*
+ * Companion structure for dpu_debugfs_create_regset32.
+ */
+struct dpu_debugfs_regset32 {
+	uint32_t offset;
+	uint32_t blk_len;
+	struct dpu_kms *dpu_kms;
+};
+
+static int dpu_regset32_show(struct seq_file *s, void *data)
+{
+	struct dpu_debugfs_regset32 *regset = s->private;
+	struct dpu_kms *dpu_kms = regset->dpu_kms;
+	void __iomem *base;
+	uint32_t i, addr;
+
+	if (!dpu_kms->mmio)
+		return 0;
+
+	base = dpu_kms->mmio + regset->offset;
+
+	/* insert padding spaces, if needed */
+	if (regset->offset & 0xF) {
+		seq_printf(s, "[%x]", regset->offset & ~0xF);
+		for (i = 0; i < (regset->offset & 0xF); i += 4)
+			seq_puts(s, "         ");
+	}
+
+	pm_runtime_get_sync(&dpu_kms->pdev->dev);
+
+	/* main register output */
+	for (i = 0; i < regset->blk_len; i += 4) {
+		addr = regset->offset + i;
+		if ((addr & 0xF) == 0x0)
+			seq_printf(s, i ? "\n[%x]" : "[%x]", addr);
+		seq_printf(s, " %08x", readl_relaxed(base + i));
+	}
+	seq_puts(s, "\n");
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(dpu_regset32);
+
+void dpu_debugfs_create_regset32(const char *name, umode_t mode,
+		void *parent,
+		uint32_t offset, uint32_t length, struct dpu_kms *dpu_kms)
+{
+	struct dpu_debugfs_regset32 *regset;
+
+	if (WARN_ON(!name || !dpu_kms || !length))
+		return;
+
+	regset = devm_kzalloc(&dpu_kms->pdev->dev, sizeof(*regset), GFP_KERNEL);
+	if (!regset)
+		return;
+
+	/* make sure offset is a multiple of 4 */
+	regset->offset = round_down(offset, 4);
+	regset->blk_len = length;
+	regset->dpu_kms = dpu_kms;
+
+	debugfs_create_file(name, mode, parent, regset, &dpu_regset32_fops);
+}
+
+static void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root)
+{
+	struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
+	int i;
+
+	if (IS_ERR(entry))
+		return;
+
+	for (i = SSPP_NONE; i < SSPP_MAX; i++) {
+		struct dpu_hw_sspp *hw = dpu_rm_get_sspp(&dpu_kms->rm, i);
+
+		if (!hw)
+			continue;
+
+		_dpu_hw_sspp_init_debugfs(hw, dpu_kms, entry);
+	}
+}
+
+static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
+{
+	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
+	void *p = dpu_hw_util_get_log_mask_ptr();
+	struct dentry *entry;
+
+	if (!p)
+		return -EINVAL;
+
+	/* Only create a set of debugfs for the primary node, ignore render nodes */
+	if (minor->type != DRM_MINOR_PRIMARY)
+		return 0;
+
+	entry = debugfs_create_dir("debug", minor->debugfs_root);
+
+	debugfs_create_x32(DPU_DEBUGFS_HWMASKNAME, 0600, entry, p);
+
+	dpu_debugfs_danger_init(dpu_kms, entry);
+	dpu_debugfs_vbif_init(dpu_kms, entry);
+	dpu_debugfs_core_irq_init(dpu_kms, entry);
+	dpu_debugfs_sspp_init(dpu_kms, entry);
+
+	return dpu_core_perf_debugfs_init(dpu_kms, entry);
+}
+#endif
+
+/* Global/shared object state funcs */
+
+/*
+ * This is a helper that returns the private state currently in operation.
+ * Note that this would return the "old_state" if called in the atomic check
+ * path, and the "new_state" after the atomic swap has been done.
+ */
+struct dpu_global_state *
+dpu_kms_get_existing_global_state(struct dpu_kms *dpu_kms)
+{
+	return to_dpu_global_state(dpu_kms->global_state.state);
+}
+
+/*
+ * This acquires the modeset lock set aside for global state, creates
+ * a new duplicated private object state.
+ */
+struct dpu_global_state *dpu_kms_get_global_state(struct drm_atomic_state *s)
+{
+	struct msm_drm_private *priv = s->dev->dev_private;
+	struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
+	struct drm_private_state *priv_state;
+	int ret;
+
+	ret = drm_modeset_lock(&dpu_kms->global_state_lock, s->acquire_ctx);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv_state = drm_atomic_get_private_obj_state(s,
+						&dpu_kms->global_state);
+	if (IS_ERR(priv_state))
+		return ERR_CAST(priv_state);
+
+	return to_dpu_global_state(priv_state);
+}
+
+static struct drm_private_state *
+dpu_kms_global_duplicate_state(struct drm_private_obj *obj)
+{
+	struct dpu_global_state *state;
+
+	state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return NULL;
+
+	__drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
+
+	return &state->base;
+}
+
+static void dpu_kms_global_destroy_state(struct drm_private_obj *obj,
+				      struct drm_private_state *state)
+{
+	struct dpu_global_state *dpu_state = to_dpu_global_state(state);
+
+	kfree(dpu_state);
+}
+
+static const struct drm_private_state_funcs dpu_kms_global_state_funcs = {
+	.atomic_duplicate_state = dpu_kms_global_duplicate_state,
+	.atomic_destroy_state = dpu_kms_global_destroy_state,
+};
+
+static int dpu_kms_global_obj_init(struct dpu_kms *dpu_kms)
+{
+	struct dpu_global_state *state;
+
+	drm_modeset_lock_init(&dpu_kms->global_state_lock);
+
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return -ENOMEM;
+
+	drm_atomic_private_obj_init(dpu_kms->dev, &dpu_kms->global_state,
+				    &state->base,
+				    &dpu_kms_global_state_funcs);
+	return 0;
+}
+
+static void dpu_kms_global_obj_fini(struct dpu_kms *dpu_kms)
+{
+	drm_atomic_private_obj_fini(&dpu_kms->global_state);
+	drm_modeset_lock_fini(&dpu_kms->global_state_lock);
+}
+
+static int dpu_kms_parse_data_bus_icc_path(struct dpu_kms *dpu_kms)
+{
+	struct icc_path *path0;
+	struct icc_path *path1;
+	struct device *dpu_dev = &dpu_kms->pdev->dev;
+
+	path0 = msm_icc_get(dpu_dev, "mdp0-mem");
+	path1 = msm_icc_get(dpu_dev, "mdp1-mem");
+
+	if (IS_ERR_OR_NULL(path0))
+		return PTR_ERR_OR_ZERO(path0);
+
+	dpu_kms->path[0] = path0;
+	dpu_kms->num_paths = 1;
+
+	if (!IS_ERR_OR_NULL(path1)) {
+		dpu_kms->path[1] = path1;
+		dpu_kms->num_paths++;
+	}
+	return 0;
+}
+
+static int dpu_kms_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
+{
+	return dpu_crtc_vblank(crtc, true);
+}
+
+static void dpu_kms_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
+{
+	dpu_crtc_vblank(crtc, false);
+}
+
+static void dpu_kms_enable_commit(struct msm_kms *kms)
+{
+	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
+	pm_runtime_get_sync(&dpu_kms->pdev->dev);
+}
+
+static void dpu_kms_disable_commit(struct msm_kms *kms)
+{
+	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
+}
+
+static void dpu_kms_flush_commit(struct msm_kms *kms, unsigned crtc_mask)
+{
+	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
+	struct drm_crtc *crtc;
+
+	for_each_crtc_mask(dpu_kms->dev, crtc, crtc_mask) {
+		if (!crtc->state->active)
+			continue;
+
+		trace_dpu_kms_commit(DRMID(crtc));
+		dpu_crtc_commit_kickoff(crtc);
+	}
+}
+
+static void dpu_kms_complete_commit(struct msm_kms *kms, unsigned crtc_mask)
+{
+	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
+	struct drm_crtc *crtc;
+
+	DPU_ATRACE_BEGIN("kms_complete_commit");
+
+	for_each_crtc_mask(dpu_kms->dev, crtc, crtc_mask)
+		dpu_crtc_complete_commit(crtc);
+
+	DPU_ATRACE_END("kms_complete_commit");
+}
+
+static void dpu_kms_wait_for_commit_done(struct msm_kms *kms,
+		struct drm_crtc *crtc)
+{
+	struct drm_encoder *encoder;
+	struct drm_device *dev;
+	int ret;
+
+	if (!kms || !crtc || !crtc->state) {
+		DPU_ERROR("invalid params\n");
+		return;
+	}
+
+	dev = crtc->dev;
+
+	if (!crtc->state->enable) {
+		DPU_DEBUG("[crtc:%d] not enable\n", crtc->base.id);
+		return;
+	}
+
+	if (!drm_atomic_crtc_effectively_active(crtc->state)) {
+		DPU_DEBUG("[crtc:%d] not active\n", crtc->base.id);
+		return;
+	}
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		if (encoder->crtc != crtc)
+			continue;
+		/*
+		 * Wait for post-flush if necessary to delay before
+		 * plane_cleanup. For example, wait for vsync in case of video
+		 * mode panels. This may be a no-op for command mode panels.
+		 */
+		trace_dpu_kms_wait_for_commit_done(DRMID(crtc));
+		ret = dpu_encoder_wait_for_commit_done(encoder);
+		if (ret && ret != -EWOULDBLOCK) {
+			DPU_ERROR("wait for commit done returned %d\n", ret);
+			break;
+		}
+	}
+}
+
+static void dpu_kms_wait_flush(struct msm_kms *kms, unsigned crtc_mask)
+{
+	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
+	struct drm_crtc *crtc;
+
+	for_each_crtc_mask(dpu_kms->dev, crtc, crtc_mask)
+		dpu_kms_wait_for_commit_done(kms, crtc);
+}
+
+static int _dpu_kms_initialize_dsi(struct drm_device *dev,
+				    struct msm_drm_private *priv,
+				    struct dpu_kms *dpu_kms)
+{
+	struct drm_encoder *encoder = NULL;
+	struct msm_display_info info;
+	int i, rc = 0;
+
+	if (!(priv->dsi[0] || priv->dsi[1]))
+		return rc;
+
+	/*
+	 * We support following confiurations:
+	 * - Single DSI host (dsi0 or dsi1)
+	 * - Two independent DSI hosts
+	 * - Bonded DSI0 and DSI1 hosts
+	 *
+	 * TODO: Support swapping DSI0 and DSI1 in the bonded setup.
+	 */
+	for (i = 0; i < ARRAY_SIZE(priv->dsi); i++) {
+		int other = (i + 1) % 2;
+
+		if (!priv->dsi[i])
+			continue;
+
+		if (msm_dsi_is_bonded_dsi(priv->dsi[i]) &&
+		    !msm_dsi_is_master_dsi(priv->dsi[i]))
+			continue;
+
+		memset(&info, 0, sizeof(info));
+		info.intf_type = INTF_DSI;
+
+		info.h_tile_instance[info.num_of_h_tiles++] = i;
+		if (msm_dsi_is_bonded_dsi(priv->dsi[i]))
+			info.h_tile_instance[info.num_of_h_tiles++] = other;
+
+		info.is_cmd_mode = msm_dsi_is_cmd_mode(priv->dsi[i]);
+
+		encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_DSI, &info);
+		if (IS_ERR(encoder)) {
+			DPU_ERROR("encoder init failed for dsi display\n");
+			return PTR_ERR(encoder);
+		}
+
+		rc = msm_dsi_modeset_init(priv->dsi[i], dev, encoder);
+		if (rc) {
+			DPU_ERROR("modeset_init failed for dsi[%d], rc = %d\n",
+				i, rc);
+			break;
+		}
+
+		if (msm_dsi_is_bonded_dsi(priv->dsi[i]) && priv->dsi[other]) {
+			rc = msm_dsi_modeset_init(priv->dsi[other], dev, encoder);
+			if (rc) {
+				DPU_ERROR("modeset_init failed for dsi[%d], rc = %d\n",
+					other, rc);
+				break;
+			}
+		}
+	}
+
+	return rc;
+}
+
+static int _dpu_kms_initialize_displayport(struct drm_device *dev,
+					    struct msm_drm_private *priv,
+					    struct dpu_kms *dpu_kms)
+{
+	struct drm_encoder *encoder = NULL;
+	struct msm_display_info info;
+	bool yuv_supported;
+	int rc;
+	int i, stream_id;
+	int stream_cnt;
+
+	for (i = 0; i < ARRAY_SIZE(priv->dp); i++) {
+		if (!priv->dp[i])
+			continue;
+
+		memset(&info, 0, sizeof(info));
+		info.num_of_h_tiles = 1;
+		info.h_tile_instance[0] = i;
+		info.intf_type = INTF_DP;
+
+		encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS, &info);
+		if (IS_ERR(encoder)) {
+			DPU_ERROR("encoder init failed for dsi display\n");
+			return PTR_ERR(encoder);
+		}
+
+		yuv_supported = !!dpu_kms->catalog->cdm;
+		rc = msm_dp_modeset_init(priv->dp[i], dev, encoder, yuv_supported);
+		if (rc) {
+			DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
+			return rc;
+		}
+
+		stream_cnt = msm_dp_get_mst_max_stream(priv->dp[i]);
+
+		if (stream_cnt > 1) {
+			rc = msm_dp_mst_register(priv->dp[i]);
+			if (rc) {
+				DPU_ERROR("dp_mst_init failed for DP, rc = %d\n", rc);
+				return rc;
+			}
+
+			for (stream_id = 0; stream_id < stream_cnt; stream_id++) {
+				info.stream_id = stream_id;
+				encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_DPMST, &info);
+				if (IS_ERR(encoder)) {
+					DPU_ERROR("encoder init failed for dp mst display\n");
+					return PTR_ERR(encoder);
+				}
+
+				rc = msm_dp_mst_bridge_init(priv->dp[i], encoder);
+				if (rc) {
+					DPU_ERROR("dp mst bridge %d init failed, %d\n",
+						  stream_id, rc);
+					continue;
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int _dpu_kms_initialize_hdmi(struct drm_device *dev,
+				    struct msm_drm_private *priv,
+				    struct dpu_kms *dpu_kms)
+{
+	struct drm_encoder *encoder = NULL;
+	struct msm_display_info info;
+	int rc;
+
+	if (!priv->hdmi)
+		return 0;
+
+	memset(&info, 0, sizeof(info));
+	info.num_of_h_tiles = 1;
+	info.h_tile_instance[0] = 0;
+	info.intf_type = INTF_HDMI;
+
+	encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS, &info);
+	if (IS_ERR(encoder)) {
+		DPU_ERROR("encoder init failed for HDMI display\n");
+		return PTR_ERR(encoder);
+	}
+
+	rc = msm_hdmi_modeset_init(priv->hdmi, dev, encoder);
+	if (rc) {
+		DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+static int _dpu_kms_initialize_writeback(struct drm_device *dev,
+		struct msm_drm_private *priv, struct dpu_kms *dpu_kms,
+		const u32 *wb_formats, int n_formats)
+{
+	struct drm_encoder *encoder = NULL;
+	struct msm_display_info info;
+	const enum dpu_wb wb_idx = WB_2;
+	u32 maxlinewidth;
+	int rc;
+
+	memset(&info, 0, sizeof(info));
+
+	info.num_of_h_tiles = 1;
+	/* use only WB idx 2 instance for DPU */
+	info.h_tile_instance[0] = wb_idx;
+	info.intf_type = INTF_WB;
+
+	maxlinewidth = dpu_rm_get_wb(&dpu_kms->rm, info.h_tile_instance[0])->caps->maxlinewidth;
+
+	encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_VIRTUAL, &info);
+	if (IS_ERR(encoder)) {
+		DPU_ERROR("encoder init failed for dsi display\n");
+		return PTR_ERR(encoder);
+	}
+
+	rc = dpu_writeback_init(dev, encoder, wb_formats, n_formats, maxlinewidth);
+	if (rc) {
+		DPU_ERROR("dpu_writeback_init, rc = %d\n", rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+/**
+ * _dpu_kms_setup_displays - create encoders, bridges and connectors
+ *                           for underlying displays
+ * @dev:        Pointer to drm device structure
+ * @priv:       Pointer to private drm device data
+ * @dpu_kms:    Pointer to dpu kms structure
+ * Returns:     Zero on success
+ */
+static int _dpu_kms_setup_displays(struct drm_device *dev,
+				    struct msm_drm_private *priv,
+				    struct dpu_kms *dpu_kms)
+{
+	int rc = 0;
+	int i;
+
+	rc = _dpu_kms_initialize_dsi(dev, priv, dpu_kms);
+	if (rc) {
+		DPU_ERROR("initialize_dsi failed, rc = %d\n", rc);
+		return rc;
+	}
+
+	rc = _dpu_kms_initialize_displayport(dev, priv, dpu_kms);
+	if (rc) {
+		DPU_ERROR("initialize_DP failed, rc = %d\n", rc);
+		return rc;
+	}
+
+	rc = _dpu_kms_initialize_hdmi(dev, priv, dpu_kms);
+	if (rc) {
+		DPU_ERROR("initialize HDMI failed, rc = %d\n", rc);
+		return rc;
+	}
+
+	/* Since WB isn't a driver check the catalog before initializing */
+	if (dpu_kms->catalog->wb_count) {
+		for (i = 0; i < dpu_kms->catalog->wb_count; i++) {
+			if (dpu_kms->catalog->wb[i].id == WB_2) {
+				rc = _dpu_kms_initialize_writeback(dev, priv, dpu_kms,
+						dpu_kms->catalog->wb[i].format_list,
+						dpu_kms->catalog->wb[i].num_formats);
+				if (rc) {
+					DPU_ERROR("initialize_WB failed, rc = %d\n", rc);
+					return rc;
+				}
+			}
+		}
+	}
+
+	return rc;
+}
+
+#define MAX_PLANES 20
+static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
+{
+	struct drm_device *dev;
+	struct drm_plane *primary_planes[MAX_PLANES], *plane;
+	struct drm_plane *cursor_planes[MAX_PLANES] = { NULL };
+	struct drm_crtc *crtc;
+	struct drm_encoder *encoder;
+	unsigned int num_encoders;
+
+	struct msm_drm_private *priv;
+	const struct dpu_mdss_cfg *catalog;
+
+	int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret;
+	int max_crtc_count;
+	dev = dpu_kms->dev;
+	priv = dev->dev_private;
+	catalog = dpu_kms->catalog;
+
+	/*
+	 * Create encoder and query display drivers to create
+	 * bridges and connectors
+	 */
+	ret = _dpu_kms_setup_displays(dev, priv, dpu_kms);
+	if (ret)
+		return ret;
+
+	num_encoders = 0;
+	drm_for_each_encoder(encoder, dev)
+		num_encoders++;
+
+	max_crtc_count = min(catalog->mixer_count, num_encoders);
+
+	/* Create the planes, keeping track of one primary/cursor per crtc */
+	for (i = 0; i < catalog->sspp_count; i++) {
+		enum drm_plane_type type;
+
+		if ((catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR))
+			&& cursor_planes_idx < max_crtc_count)
+			type = DRM_PLANE_TYPE_CURSOR;
+		else if (primary_planes_idx < max_crtc_count)
+			type = DRM_PLANE_TYPE_PRIMARY;
+		else
+			type = DRM_PLANE_TYPE_OVERLAY;
+
+		DPU_DEBUG("Create plane type %d with features %lx (cur %lx)\n",
+			  type, catalog->sspp[i].features,
+			  catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR));
+
+		plane = dpu_plane_init(dev, catalog->sspp[i].id, type,
+				       (1UL << max_crtc_count) - 1);
+		if (IS_ERR(plane)) {
+			DPU_ERROR("dpu_plane_init failed\n");
+			ret = PTR_ERR(plane);
+			return ret;
+		}
+
+		if (type == DRM_PLANE_TYPE_CURSOR)
+			cursor_planes[cursor_planes_idx++] = plane;
+		else if (type == DRM_PLANE_TYPE_PRIMARY)
+			primary_planes[primary_planes_idx++] = plane;
+	}
+
+	max_crtc_count = min(max_crtc_count, primary_planes_idx);
+
+	/* Create one CRTC per encoder */
+	for (i = 0; i < max_crtc_count; i++) {
+		crtc = dpu_crtc_init(dev, primary_planes[i], cursor_planes[i]);
+		if (IS_ERR(crtc)) {
+			ret = PTR_ERR(crtc);
+			return ret;
+		}
+		priv->num_crtcs++;
+	}
+
+	/* All CRTCs are compatible with all encoders */
+	drm_for_each_encoder(encoder, dev)
+		encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
+
+	return 0;
+}
+
+static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
+{
+	int i;
+
+	dpu_kms->hw_intr = NULL;
+
+	/* safe to call these more than once during shutdown */
+	_dpu_kms_mmu_destroy(dpu_kms);
+
+	for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
+		dpu_kms->hw_vbif[i] = NULL;
+	}
+
+	dpu_kms_global_obj_fini(dpu_kms);
+
+	dpu_kms->catalog = NULL;
+
+	dpu_kms->hw_mdp = NULL;
+}
+
+static void dpu_kms_destroy(struct msm_kms *kms)
+{
+	struct dpu_kms *dpu_kms;
+
+	if (!kms) {
+		DPU_ERROR("invalid kms\n");
+		return;
+	}
+
+	dpu_kms = to_dpu_kms(kms);
+
+	_dpu_kms_hw_destroy(dpu_kms);
+
+	msm_kms_destroy(&dpu_kms->base);
+
+	if (dpu_kms->rpm_enabled)
+		pm_runtime_disable(&dpu_kms->pdev->dev);
+}
+
+static int dpu_irq_postinstall(struct msm_kms *kms)
+{
+	struct msm_drm_private *priv;
+	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
+
+	if (!dpu_kms || !dpu_kms->dev)
+		return -EINVAL;
+
+	priv = dpu_kms->dev->dev_private;
+	if (!priv)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state, struct msm_kms *kms)
+{
+	int i;
+	struct dpu_kms *dpu_kms;
+	const struct dpu_mdss_cfg *cat;
+	void __iomem *base;
+
+	dpu_kms = to_dpu_kms(kms);
+
+	cat = dpu_kms->catalog;
+
+	pm_runtime_get_sync(&dpu_kms->pdev->dev);
+
+	/* dump CTL sub-blocks HW regs info */
+	for (i = 0; i < cat->ctl_count; i++)
+		msm_disp_snapshot_add_block(disp_state, cat->ctl[i].len,
+				dpu_kms->mmio + cat->ctl[i].base, cat->ctl[i].name);
+
+	/* dump DSPP sub-blocks HW regs info */
+	for (i = 0; i < cat->dspp_count; i++) {
+		base = dpu_kms->mmio + cat->dspp[i].base;
+		msm_disp_snapshot_add_block(disp_state, cat->dspp[i].len, base, cat->dspp[i].name);
+
+		if (cat->dspp[i].sblk && cat->dspp[i].sblk->pcc.len > 0)
+			msm_disp_snapshot_add_block(disp_state, cat->dspp[i].sblk->pcc.len,
+						    base + cat->dspp[i].sblk->pcc.base, "%s_%s",
+						    cat->dspp[i].name,
+						    cat->dspp[i].sblk->pcc.name);
+	}
+
+	/* dump INTF sub-blocks HW regs info */
+	for (i = 0; i < cat->intf_count; i++)
+		msm_disp_snapshot_add_block(disp_state, cat->intf[i].len,
+				dpu_kms->mmio + cat->intf[i].base, cat->intf[i].name);
+
+	/* dump PP sub-blocks HW regs info */
+	for (i = 0; i < cat->pingpong_count; i++) {
+		base = dpu_kms->mmio + cat->pingpong[i].base;
+		msm_disp_snapshot_add_block(disp_state, cat->pingpong[i].len, base,
+					    cat->pingpong[i].name);
+
+		/* TE2 sub-block has length of 0, so will not print it */
+
+		if (cat->pingpong[i].sblk && cat->pingpong[i].sblk->dither.len > 0)
+			msm_disp_snapshot_add_block(disp_state, cat->pingpong[i].sblk->dither.len,
+						    base + cat->pingpong[i].sblk->dither.base,
+						    "%s_%s", cat->pingpong[i].name,
+						    cat->pingpong[i].sblk->dither.name);
+	}
+
+	/* dump SSPP sub-blocks HW regs info */
+	for (i = 0; i < cat->sspp_count; i++) {
+		base = dpu_kms->mmio + cat->sspp[i].base;
+		msm_disp_snapshot_add_block(disp_state, cat->sspp[i].len, base, cat->sspp[i].name);
+
+		if (cat->sspp[i].sblk && cat->sspp[i].sblk->scaler_blk.len > 0)
+			msm_disp_snapshot_add_block(disp_state, cat->sspp[i].sblk->scaler_blk.len,
+						    base + cat->sspp[i].sblk->scaler_blk.base,
+						    "%s_%s", cat->sspp[i].name,
+						    cat->sspp[i].sblk->scaler_blk.name);
+
+		if (cat->sspp[i].sblk && cat->sspp[i].sblk->csc_blk.len > 0)
+			msm_disp_snapshot_add_block(disp_state, cat->sspp[i].sblk->csc_blk.len,
+						    base + cat->sspp[i].sblk->csc_blk.base,
+						    "%s_%s", cat->sspp[i].name,
+						    cat->sspp[i].sblk->csc_blk.name);
+	}
+
+	/* dump LM sub-blocks HW regs info */
+	for (i = 0; i < cat->mixer_count; i++)
+		msm_disp_snapshot_add_block(disp_state, cat->mixer[i].len,
+				dpu_kms->mmio + cat->mixer[i].base, cat->mixer[i].name);
+
+	/* dump WB sub-blocks HW regs info */
+	for (i = 0; i < cat->wb_count; i++)
+		msm_disp_snapshot_add_block(disp_state, cat->wb[i].len,
+				dpu_kms->mmio + cat->wb[i].base, cat->wb[i].name);
+
+	if (cat->mdp[0].features & BIT(DPU_MDP_PERIPH_0_REMOVED)) {
+		msm_disp_snapshot_add_block(disp_state, MDP_PERIPH_TOP0,
+				dpu_kms->mmio + cat->mdp[0].base, "top");
+		msm_disp_snapshot_add_block(disp_state, cat->mdp[0].len - MDP_PERIPH_TOP0_END,
+				dpu_kms->mmio + cat->mdp[0].base + MDP_PERIPH_TOP0_END, "top_2");
+	} else {
+		msm_disp_snapshot_add_block(disp_state, cat->mdp[0].len,
+				dpu_kms->mmio + cat->mdp[0].base, "top");
+	}
+
+	/* dump DSC sub-blocks HW regs info */
+	for (i = 0; i < cat->dsc_count; i++) {
+		base = dpu_kms->mmio + cat->dsc[i].base;
+		msm_disp_snapshot_add_block(disp_state, cat->dsc[i].len, base, cat->dsc[i].name);
+
+		if (cat->dsc[i].features & BIT(DPU_DSC_HW_REV_1_2)) {
+			struct dpu_dsc_blk enc = cat->dsc[i].sblk->enc;
+			struct dpu_dsc_blk ctl = cat->dsc[i].sblk->ctl;
+
+			msm_disp_snapshot_add_block(disp_state, enc.len, base + enc.base, "%s_%s",
+						    cat->dsc[i].name, enc.name);
+			msm_disp_snapshot_add_block(disp_state, ctl.len, base + ctl.base, "%s_%s",
+						    cat->dsc[i].name, ctl.name);
+		}
+	}
+
+	if (cat->cdm)
+		msm_disp_snapshot_add_block(disp_state, cat->cdm->len,
+					    dpu_kms->mmio + cat->cdm->base, cat->cdm->name);
+
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
+}
+
+static const struct msm_kms_funcs kms_funcs = {
+	.hw_init         = dpu_kms_hw_init,
+	.irq_preinstall  = dpu_core_irq_preinstall,
+	.irq_postinstall = dpu_irq_postinstall,
+	.irq_uninstall   = dpu_core_irq_uninstall,
+	.irq             = dpu_core_irq,
+	.enable_commit   = dpu_kms_enable_commit,
+	.disable_commit  = dpu_kms_disable_commit,
+	.flush_commit    = dpu_kms_flush_commit,
+	.wait_flush      = dpu_kms_wait_flush,
+	.complete_commit = dpu_kms_complete_commit,
+	.enable_vblank   = dpu_kms_enable_vblank,
+	.disable_vblank  = dpu_kms_disable_vblank,
+	.check_modified_format = dpu_format_check_modified_format,
+	.get_format      = dpu_get_msm_format,
+	.destroy         = dpu_kms_destroy,
+	.snapshot        = dpu_kms_mdp_snapshot,
+#ifdef CONFIG_DEBUG_FS
+	.debugfs_init    = dpu_kms_debugfs_init,
+#endif
+};
+
+static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms)
+{
+	struct msm_mmu *mmu;
+
+	if (!dpu_kms->base.aspace)
+		return;
+
+	mmu = dpu_kms->base.aspace->mmu;
+
+	mmu->funcs->detach(mmu);
+	msm_gem_address_space_put(dpu_kms->base.aspace);
+
+	dpu_kms->base.aspace = NULL;
+}
+
+static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms)
+{
+	struct msm_gem_address_space *aspace;
+
+	aspace = msm_kms_init_aspace(dpu_kms->dev);
+	if (IS_ERR(aspace))
+		return PTR_ERR(aspace);
+
+	dpu_kms->base.aspace = aspace;
+
+	return 0;
+}
+
+unsigned long dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name)
+{
+	struct clk *clk;
+
+	clk = msm_clk_bulk_get_clock(dpu_kms->clocks, dpu_kms->num_clocks, clock_name);
+	if (!clk)
+		return 0;
+
+	return clk_get_rate(clk);
+}
+
+#define	DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE	412500000
+
+static int dpu_kms_hw_init(struct msm_kms *kms)
+{
+	struct dpu_kms *dpu_kms;
+	struct drm_device *dev;
+	int i, rc = -EINVAL;
+	unsigned long max_core_clk_rate;
+	u32 core_rev;
+
+	if (!kms) {
+		DPU_ERROR("invalid kms\n");
+		return rc;
+	}
+
+	dpu_kms = to_dpu_kms(kms);
+	dev = dpu_kms->dev;
+
+	dev->mode_config.cursor_width = 512;
+	dev->mode_config.cursor_height = 512;
+
+	rc = dpu_kms_global_obj_init(dpu_kms);
+	if (rc)
+		return rc;
+
+	atomic_set(&dpu_kms->bandwidth_ref, 0);
+
+	rc = pm_runtime_resume_and_get(&dpu_kms->pdev->dev);
+	if (rc < 0)
+		goto error;
+
+	core_rev = readl_relaxed(dpu_kms->mmio + 0x0);
+
+	pr_info("dpu hardware revision:0x%x\n", core_rev);
+
+	dpu_kms->catalog = of_device_get_match_data(dev->dev);
+	if (!dpu_kms->catalog) {
+		DPU_ERROR("device config not known!\n");
+		rc = -EINVAL;
+		goto err_pm_put;
+	}
+
+	/*
+	 * Now we need to read the HW catalog and initialize resources such as
+	 * clocks, regulators, GDSC/MMAGIC, ioremap the register ranges etc
+	 */
+	rc = _dpu_kms_mmu_init(dpu_kms);
+	if (rc) {
+		DPU_ERROR("dpu_kms_mmu_init failed: %d\n", rc);
+		goto err_pm_put;
+	}
+
+	dpu_kms->mdss = msm_mdss_get_mdss_data(dpu_kms->pdev->dev.parent);
+	if (IS_ERR(dpu_kms->mdss)) {
+		rc = PTR_ERR(dpu_kms->mdss);
+		DPU_ERROR("failed to get MDSS data: %d\n", rc);
+		goto err_pm_put;
+	}
+
+	if (!dpu_kms->mdss) {
+		rc = -EINVAL;
+		DPU_ERROR("NULL MDSS data\n");
+		goto err_pm_put;
+	}
+
+	rc = dpu_rm_init(dev, &dpu_kms->rm, dpu_kms->catalog, dpu_kms->mdss, dpu_kms->mmio);
+	if (rc) {
+		DPU_ERROR("rm init failed: %d\n", rc);
+		goto err_pm_put;
+	}
+
+	dpu_kms->hw_mdp = dpu_hw_mdptop_init(dev,
+					     dpu_kms->catalog->mdp,
+					     dpu_kms->mmio,
+					     dpu_kms->catalog);
+	if (IS_ERR(dpu_kms->hw_mdp)) {
+		rc = PTR_ERR(dpu_kms->hw_mdp);
+		DPU_ERROR("failed to get hw_mdp: %d\n", rc);
+		dpu_kms->hw_mdp = NULL;
+		goto err_pm_put;
+	}
+
+	for (i = 0; i < dpu_kms->catalog->vbif_count; i++) {
+		struct dpu_hw_vbif *hw;
+		const struct dpu_vbif_cfg *vbif = &dpu_kms->catalog->vbif[i];
+
+		hw = dpu_hw_vbif_init(dev, vbif, dpu_kms->vbif[vbif->id]);
+		if (IS_ERR(hw)) {
+			rc = PTR_ERR(hw);
+			DPU_ERROR("failed to init vbif %d: %d\n", vbif->id, rc);
+			goto err_pm_put;
+		}
+
+		dpu_kms->hw_vbif[vbif->id] = hw;
+	}
+
+	/* TODO: use the same max_freq as in dpu_kms_hw_init */
+	max_core_clk_rate = dpu_kms_get_clk_rate(dpu_kms, "core");
+	if (!max_core_clk_rate) {
+		DPU_DEBUG("max core clk rate not determined, using default\n");
+		max_core_clk_rate = DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE;
+	}
+
+	rc = dpu_core_perf_init(&dpu_kms->perf, dpu_kms->catalog->perf, max_core_clk_rate);
+	if (rc) {
+		DPU_ERROR("failed to init perf %d\n", rc);
+		goto err_pm_put;
+	}
+
+	dpu_kms->hw_intr = dpu_hw_intr_init(dev, dpu_kms->mmio, dpu_kms->catalog);
+	if (IS_ERR(dpu_kms->hw_intr)) {
+		rc = PTR_ERR(dpu_kms->hw_intr);
+		DPU_ERROR("hw_intr init failed: %d\n", rc);
+		dpu_kms->hw_intr = NULL;
+		goto err_pm_put;
+	}
+
+	dev->mode_config.min_width = 0;
+	dev->mode_config.min_height = 0;
+
+	/*
+	 * max crtc width is equal to the max mixer width * 2 and max height is
+	 * is 4K
+	 */
+	dev->mode_config.max_width =
+			dpu_kms->catalog->caps->max_mixer_width * 2;
+	dev->mode_config.max_height = 4096;
+
+	dev->max_vblank_count = 0xffffffff;
+	/* Disable vblank irqs aggressively for power-saving */
+	dev->vblank_disable_immediate = true;
+
+	/*
+	 * _dpu_kms_drm_obj_init should create the DRM related objects
+	 * i.e. CRTCs, planes, encoders, connectors and so forth
+	 */
+	rc = _dpu_kms_drm_obj_init(dpu_kms);
+	if (rc) {
+		DPU_ERROR("modeset init failed: %d\n", rc);
+		goto err_pm_put;
+	}
+
+	dpu_vbif_init_memtypes(dpu_kms);
+
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
+
+	return 0;
+
+err_pm_put:
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
+error:
+	_dpu_kms_hw_destroy(dpu_kms);
+
+	return rc;
+}
+
+static int dpu_kms_init(struct drm_device *ddev)
+{
+	struct msm_drm_private *priv = ddev->dev_private;
+	struct device *dev = ddev->dev;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
+	struct dev_pm_opp *opp;
+	int ret = 0;
+	unsigned long max_freq = ULONG_MAX;
+
+	opp = dev_pm_opp_find_freq_floor(dev, &max_freq);
+	if (!IS_ERR(opp))
+		dev_pm_opp_put(opp);
+
+	dev_pm_opp_set_rate(dev, max_freq);
+
+	ret = msm_kms_init(&dpu_kms->base, &kms_funcs);
+	if (ret) {
+		DPU_ERROR("failed to init kms, ret=%d\n", ret);
+		return ret;
+	}
+	dpu_kms->dev = ddev;
+
+	pm_runtime_enable(&pdev->dev);
+	dpu_kms->rpm_enabled = true;
+
+	return 0;
+}
+
+static int dpu_dev_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct dpu_kms *dpu_kms;
+	int irq;
+	int ret = 0;
+
+	dpu_kms = devm_kzalloc(dev, sizeof(*dpu_kms), GFP_KERNEL);
+	if (!dpu_kms)
+		return -ENOMEM;
+
+	dpu_kms->pdev = pdev;
+
+	ret = devm_pm_opp_set_clkname(dev, "core");
+	if (ret)
+		return ret;
+	/* OPP table is optional */
+	ret = devm_pm_opp_of_add_table(dev);
+	if (ret && ret != -ENODEV)
+		return dev_err_probe(dev, ret, "invalid OPP table in device tree\n");
+
+	ret = devm_clk_bulk_get_all(&pdev->dev, &dpu_kms->clocks);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "failed to parse clocks\n");
+
+	dpu_kms->num_clocks = ret;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return dev_err_probe(dev, irq, "failed to get irq\n");
+
+	dpu_kms->base.irq = irq;
+
+	dpu_kms->mmio = msm_ioremap(pdev, "mdp");
+	if (IS_ERR(dpu_kms->mmio)) {
+		ret = PTR_ERR(dpu_kms->mmio);
+		DPU_ERROR("mdp register memory map failed: %d\n", ret);
+		dpu_kms->mmio = NULL;
+		return ret;
+	}
+	DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
+
+	dpu_kms->vbif[VBIF_RT] = msm_ioremap(pdev, "vbif");
+	if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
+		ret = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
+		DPU_ERROR("vbif register memory map failed: %d\n", ret);
+		dpu_kms->vbif[VBIF_RT] = NULL;
+		return ret;
+	}
+
+	dpu_kms->vbif[VBIF_NRT] = msm_ioremap_quiet(pdev, "vbif_nrt");
+	if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) {
+		dpu_kms->vbif[VBIF_NRT] = NULL;
+		DPU_DEBUG("VBIF NRT is not defined");
+	}
+
+	ret = dpu_kms_parse_data_bus_icc_path(dpu_kms);
+	if (ret)
+		return ret;
+
+	return msm_drv_probe(&pdev->dev, dpu_kms_init, &dpu_kms->base);
+}
+
+static void dpu_dev_remove(struct platform_device *pdev)
+{
+	component_master_del(&pdev->dev, &msm_drm_ops);
+}
+
+static int __maybe_unused dpu_runtime_suspend(struct device *dev)
+{
+	int i;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct msm_drm_private *priv = platform_get_drvdata(pdev);
+	struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
+
+	/* Drop the performance state vote */
+	dev_pm_opp_set_rate(dev, 0);
+	clk_bulk_disable_unprepare(dpu_kms->num_clocks, dpu_kms->clocks);
+
+	for (i = 0; i < dpu_kms->num_paths; i++)
+		icc_set_bw(dpu_kms->path[i], 0, 0);
+
+	return 0;
+}
+
+static int __maybe_unused dpu_runtime_resume(struct device *dev)
+{
+	int rc = -1;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct msm_drm_private *priv = platform_get_drvdata(pdev);
+	struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
+	struct drm_encoder *encoder;
+	struct drm_device *ddev;
+
+	ddev = dpu_kms->dev;
+
+	rc = clk_bulk_prepare_enable(dpu_kms->num_clocks, dpu_kms->clocks);
+	if (rc) {
+		DPU_ERROR("clock enable failed rc:%d\n", rc);
+		return rc;
+	}
+
+	dpu_vbif_init_memtypes(dpu_kms);
+
+	drm_for_each_encoder(encoder, ddev)
+		dpu_encoder_virt_runtime_resume(encoder);
+
+	return rc;
+}
+
+static const struct dev_pm_ops dpu_pm_ops = {
+	SET_RUNTIME_PM_OPS(dpu_runtime_suspend, dpu_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+	.prepare = msm_kms_pm_prepare,
+	.complete = msm_kms_pm_complete,
+};
+
+static const struct of_device_id dpu_dt_match[] = {
+	{ .compatible = "qcom,msm8998-dpu", .data = &dpu_msm8998_cfg, },
+	{ .compatible = "qcom,qcm2290-dpu", .data = &dpu_qcm2290_cfg, },
+	{ .compatible = "qcom,sdm670-dpu", .data = &dpu_sdm670_cfg, },
+	{ .compatible = "qcom,sdm845-dpu", .data = &dpu_sdm845_cfg, },
+	{ .compatible = "qcom,sc7180-dpu", .data = &dpu_sc7180_cfg, },
+	{ .compatible = "qcom,sc7280-dpu", .data = &dpu_sc7280_cfg, },
+	{ .compatible = "qcom,sc8180x-dpu", .data = &dpu_sc8180x_cfg, },
+	{ .compatible = "qcom,sc8280xp-dpu", .data = &dpu_sc8280xp_cfg, },
+	{ .compatible = "qcom,sm6115-dpu", .data = &dpu_sm6115_cfg, },
+	{ .compatible = "qcom,sm6125-dpu", .data = &dpu_sm6125_cfg, },
+	{ .compatible = "qcom,sm6350-dpu", .data = &dpu_sm6350_cfg, },
+	{ .compatible = "qcom,sm6375-dpu", .data = &dpu_sm6375_cfg, },
+	{ .compatible = "qcom,sm8150-dpu", .data = &dpu_sm8150_cfg, },
+	{ .compatible = "qcom,sm8250-dpu", .data = &dpu_sm8250_cfg, },
+	{ .compatible = "qcom,sm8350-dpu", .data = &dpu_sm8350_cfg, },
+	{ .compatible = "qcom,sm8450-dpu", .data = &dpu_sm8450_cfg, },
+	{ .compatible = "qcom,qcs8300-dpu", .data = &dpu_qcs8300_cfg, },
+	{ .compatible = "qcom,sa8775p-dpu", .data = &dpu_sa8775p_cfg, },
+	{ .compatible = "qcom,sm8550-dpu", .data = &dpu_sm8550_cfg, },
+	{ .compatible = "qcom,sm8650-dpu", .data = &dpu_sm8650_cfg, },
+	{}
+};
+MODULE_DEVICE_TABLE(of, dpu_dt_match);
+
+static struct platform_driver dpu_driver = {
+	.probe = dpu_dev_probe,
+	.remove_new = dpu_dev_remove,
+	.shutdown = msm_kms_shutdown,
+	.driver = {
+		.name = "msm_dpu",
+		.of_match_table = dpu_dt_match,
+		.pm = &dpu_pm_ops,
+	},
+};
+
+void __init msm_dpu_register(void)
+{
+	platform_driver_register(&dpu_driver);
+}
+
+void __exit msm_dpu_unregister(void)
+{
+	platform_driver_unregister(&dpu_driver);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_kms.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_kms.h
@@ -0,0 +1,200 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __DPU_KMS_H__
+#define __DPU_KMS_H__
+
+#include <linux/interconnect.h>
+
+#include <drm/drm_drv.h>
+
+#include "msm_drv.h"
+#include "msm_kms.h"
+#include "msm_mmu.h"
+#include "msm_gem.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hw_ctl.h"
+#include "dpu_hw_lm.h"
+#include "dpu_hw_interrupts.h"
+#include "dpu_hw_top.h"
+#include "dpu_rm.h"
+#include "dpu_core_perf.h"
+
+#define DRMID(x) ((x) ? (x)->base.id : -1)
+
+/**
+ * DPU_DEBUG - macro for kms/plane/crtc/encoder/connector logs
+ * @fmt: Pointer to format string
+ */
+#define DPU_DEBUG(fmt, ...)                                                \
+	DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__)
+
+/**
+ * DPU_DEBUG_DRIVER - macro for hardware driver logging
+ * @fmt: Pointer to format string
+ */
+#define DPU_DEBUG_DRIVER(fmt, ...)                                         \
+	DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__)
+
+#define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__)
+#define DPU_ERROR_RATELIMITED(fmt, ...) pr_err_ratelimited("[dpu error]" fmt, ##__VA_ARGS__)
+
+/**
+ * ktime_compare_safe - compare two ktime structures
+ *	This macro is similar to the standard ktime_compare() function, but
+ *	attempts to also handle ktime overflows.
+ * @A: First ktime value
+ * @B: Second ktime value
+ * Returns: -1 if A < B, 0 if A == B, 1 if A > B
+ */
+#define ktime_compare_safe(A, B) \
+	ktime_compare(ktime_sub((A), (B)), ktime_set(0, 0))
+
+struct dpu_kms {
+	struct msm_kms base;
+	struct drm_device *dev;
+	const struct dpu_mdss_cfg *catalog;
+	const struct msm_mdss_data *mdss;
+
+	/* io/register spaces: */
+	void __iomem *mmio, *vbif[VBIF_MAX];
+
+	struct regulator *vdd;
+	struct regulator *mmagic;
+	struct regulator *venus;
+
+	struct dpu_hw_intr *hw_intr;
+
+	struct dpu_core_perf perf;
+
+	/*
+	 * Global private object state, Do not access directly, use
+	 * dpu_kms_global_get_state()
+	 */
+	struct drm_modeset_lock global_state_lock;
+	struct drm_private_obj global_state;
+
+	struct dpu_rm rm;
+
+	struct dpu_hw_vbif *hw_vbif[VBIF_MAX];
+	struct dpu_hw_mdp *hw_mdp;
+
+	bool has_danger_ctrl;
+
+	struct platform_device *pdev;
+	bool rpm_enabled;
+
+	struct clk_bulk_data *clocks;
+	size_t num_clocks;
+
+	/* reference count bandwidth requests, so we know when we can
+	 * release bandwidth.  Each atomic update increments, and frame-
+	 * done event decrements.  Additionally, for video mode, the
+	 * reference is incremented when crtc is enabled, and decremented
+	 * when disabled.
+	 */
+	atomic_t bandwidth_ref;
+	struct icc_path *path[2];
+	u32 num_paths;
+};
+
+struct vsync_info {
+	u32 frame_count;
+	u32 line_count;
+};
+
+#define DPU_ENC_WR_PTR_START_TIMEOUT_US 20000
+
+#define DPU_ENC_MAX_POLL_TIMEOUT_US	2000
+
+#define to_dpu_kms(x) container_of(x, struct dpu_kms, base)
+
+#define to_dpu_global_state(x) container_of(x, struct dpu_global_state, base)
+
+/* Global private object state for tracking resources that are shared across
+ * multiple kms objects (planes/crtcs/etc).
+ */
+struct dpu_global_state {
+	struct drm_private_state base;
+
+	uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0];
+	uint32_t mixer_to_enc_id[LM_MAX - LM_0];
+	uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
+	uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
+	uint32_t dsc_to_enc_id[DSC_MAX - DSC_0];
+	uint32_t cdm_to_enc_id;
+};
+
+struct dpu_global_state
+	*dpu_kms_get_existing_global_state(struct dpu_kms *dpu_kms);
+struct dpu_global_state
+	*__must_check dpu_kms_get_global_state(struct drm_atomic_state *s);
+
+/**
+ * Debugfs functions - extra helper functions for debugfs support
+ *
+ * Main debugfs documentation is located at,
+ *
+ * Documentation/filesystems/debugfs.rst
+ *
+ * @dpu_debugfs_create_regset32: Create 32-bit register dump file
+ */
+
+/**
+ * dpu_debugfs_create_regset32 - Create register read back file for debugfs
+ *
+ * This function is almost identical to the standard debugfs_create_regset32()
+ * function, with the main difference being that a list of register
+ * names/offsets do not need to be provided. The 'read' function simply outputs
+ * sequential register values over a specified range.
+ *
+ * @name:   File name within debugfs
+ * @mode:   File mode within debugfs
+ * @parent: Parent directory entry within debugfs, can be NULL
+ * @offset: sub-block offset
+ * @length: sub-block length, in bytes
+ * @dpu_kms: pointer to dpu kms structure
+ */
+void dpu_debugfs_create_regset32(const char *name, umode_t mode,
+		void *parent,
+		uint32_t offset, uint32_t length, struct dpu_kms *dpu_kms);
+
+/**
+ * dpu_debugfs_get_root - Return root directory entry for KMS's debugfs
+ *
+ * The return value should be passed as the 'parent' argument to subsequent
+ * debugfs create calls.
+ *
+ * @dpu_kms: Pointer to DPU's KMS structure
+ *
+ * Return: dentry pointer for DPU's debugfs location
+ */
+void *dpu_debugfs_get_root(struct dpu_kms *dpu_kms);
+
+/**
+ * DPU info management functions
+ * These functions/definitions allow for building up a 'dpu_info' structure
+ * containing one or more "key=value\n" entries.
+ */
+#define DPU_KMS_INFO_MAX_SIZE	4096
+
+/**
+ * Vblank enable/disable functions
+ */
+int dpu_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
+void dpu_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
+
+/**
+ * dpu_kms_get_clk_rate() - get the clock rate
+ * @dpu_kms:  pointer to dpu_kms structure
+ * @clock_name: clock name to get the rate
+ *
+ * Return: current clock rate
+ */
+unsigned long dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name);
+
+#endif /* __dpu_kms_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_plane.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_plane.c
@@ -0,0 +1,1449 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2014-2018 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+
+#include <linux/debugfs.h>
+#include <linux/dma-buf.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_uapi.h>
+#include <drm/drm_blend.h>
+#include <drm/drm_damage_helper.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_atomic_helper.h>
+
+#include "msm_drv.h"
+#include "dpu_kms.h"
+#include "dpu_formats.h"
+#include "dpu_hw_sspp.h"
+#include "dpu_hw_util.h"
+#include "dpu_trace.h"
+#include "dpu_crtc.h"
+#include "dpu_vbif.h"
+#include "dpu_plane.h"
+
+#define DPU_DEBUG_PLANE(pl, fmt, ...) DRM_DEBUG_ATOMIC("plane%d " fmt,\
+		(pl) ? (pl)->base.base.id : -1, ##__VA_ARGS__)
+
+#define DPU_ERROR_PLANE(pl, fmt, ...) DPU_ERROR("plane%d " fmt,\
+		(pl) ? (pl)->base.base.id : -1, ##__VA_ARGS__)
+
+#define DECIMATED_DIMENSION(dim, deci) (((dim) + ((1 << (deci)) - 1)) >> (deci))
+#define PHASE_STEP_SHIFT	21
+#define PHASE_STEP_UNIT_SCALE   ((int) (1 << PHASE_STEP_SHIFT))
+#define PHASE_RESIDUAL		15
+
+#define SHARP_STRENGTH_DEFAULT	32
+#define SHARP_EDGE_THR_DEFAULT	112
+#define SHARP_SMOOTH_THR_DEFAULT	8
+#define SHARP_NOISE_THR_DEFAULT	2
+
+#define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
+#define DPU_ZPOS_MAX 255
+
+/*
+ * Default Preload Values
+ */
+#define DPU_QSEED3_DEFAULT_PRELOAD_H 0x4
+#define DPU_QSEED3_DEFAULT_PRELOAD_V 0x3
+#define DPU_QSEED4_DEFAULT_PRELOAD_V 0x2
+#define DPU_QSEED4_DEFAULT_PRELOAD_H 0x4
+
+#define DEFAULT_REFRESH_RATE	60
+
+static const uint32_t qcom_compressed_supported_formats[] = {
+	DRM_FORMAT_ABGR8888,
+	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_XBGR8888,
+	DRM_FORMAT_XRGB8888,
+	DRM_FORMAT_ARGB2101010,
+	DRM_FORMAT_XRGB2101010,
+	DRM_FORMAT_BGR565,
+
+	DRM_FORMAT_NV12,
+	DRM_FORMAT_P010,
+};
+
+/*
+ * struct dpu_plane - local dpu plane structure
+ * @aspace: address space pointer
+ * @csc_ptr: Points to dpu_csc_cfg structure to use for current
+ * @catalog: Points to dpu catalog structure
+ * @revalidate: force revalidation of all the plane properties
+ */
+struct dpu_plane {
+	struct drm_plane base;
+
+	enum dpu_sspp pipe;
+
+	uint32_t color_fill;
+	bool is_error;
+	bool is_rt_pipe;
+	const struct dpu_mdss_cfg *catalog;
+};
+
+static const uint64_t supported_format_modifiers[] = {
+	DRM_FORMAT_MOD_QCOM_COMPRESSED,
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_INVALID
+};
+
+#define to_dpu_plane(x) container_of(x, struct dpu_plane, base)
+
+static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane)
+{
+	struct msm_drm_private *priv = plane->dev->dev_private;
+
+	return to_dpu_kms(priv->kms);
+}
+
+/**
+ * _dpu_plane_calc_bw - calculate bandwidth required for a plane
+ * @catalog: Points to dpu catalog structure
+ * @fmt: Pointer to source buffer format
+ * @mode: Pointer to drm display mode
+ * @pipe_cfg: Pointer to pipe configuration
+ * Result: Updates calculated bandwidth in the plane state.
+ * BW Equation: src_w * src_h * bpp * fps * (v_total / v_dest)
+ * Prefill BW Equation: line src bytes * line_time
+ */
+static u64 _dpu_plane_calc_bw(const struct dpu_mdss_cfg *catalog,
+	const struct dpu_format *fmt,
+	const struct drm_display_mode *mode,
+	struct dpu_sw_pipe_cfg *pipe_cfg)
+{
+	int src_width, src_height, dst_height, fps;
+	u64 plane_pixel_rate, plane_bit_rate;
+	u64 plane_prefill_bw;
+	u64 plane_bw;
+	u32 hw_latency_lines;
+	u64 scale_factor;
+	int vbp, vpw, vfp;
+
+	src_width = drm_rect_width(&pipe_cfg->src_rect);
+	src_height = drm_rect_height(&pipe_cfg->src_rect);
+	dst_height = drm_rect_height(&pipe_cfg->dst_rect);
+	fps = drm_mode_vrefresh(mode);
+	vbp = mode->vtotal - mode->vsync_end;
+	vpw = mode->vsync_end - mode->vsync_start;
+	vfp = mode->vsync_start - mode->vdisplay;
+	hw_latency_lines =  catalog->perf->min_prefill_lines;
+	scale_factor = src_height > dst_height ?
+		mult_frac(src_height, 1, dst_height) : 1;
+
+	plane_pixel_rate = src_width * mode->vtotal * fps;
+	plane_bit_rate = plane_pixel_rate * fmt->bpp;
+
+	plane_bw = plane_bit_rate * scale_factor;
+
+	plane_prefill_bw = plane_bw * hw_latency_lines;
+
+	if ((vbp+vpw) > hw_latency_lines)
+		do_div(plane_prefill_bw, (vbp+vpw));
+	else if ((vbp+vpw+vfp) < hw_latency_lines)
+		do_div(plane_prefill_bw, (vbp+vpw+vfp));
+	else
+		do_div(plane_prefill_bw, hw_latency_lines);
+
+
+	return max(plane_bw, plane_prefill_bw);
+}
+
+/**
+ * _dpu_plane_calc_clk - calculate clock required for a plane
+ * @mode: Pointer to drm display mode
+ * @pipe_cfg: Pointer to pipe configuration
+ * Result: Updates calculated clock in the plane state.
+ * Clock equation: dst_w * v_total * fps * (src_h / dst_h)
+ */
+static u64 _dpu_plane_calc_clk(const struct drm_display_mode *mode,
+		struct dpu_sw_pipe_cfg *pipe_cfg)
+{
+	int dst_width, src_height, dst_height, fps;
+	u64 plane_clk;
+
+	src_height = drm_rect_height(&pipe_cfg->src_rect);
+	dst_width = drm_rect_width(&pipe_cfg->dst_rect);
+	dst_height = drm_rect_height(&pipe_cfg->dst_rect);
+	fps = drm_mode_vrefresh(mode);
+
+	plane_clk =
+		dst_width * mode->vtotal * fps;
+
+	if (src_height > dst_height) {
+		plane_clk *= src_height;
+		do_div(plane_clk, dst_height);
+	}
+
+	return plane_clk;
+}
+
+/**
+ * _dpu_plane_calc_fill_level - calculate fill level of the given source format
+ * @plane:		Pointer to drm plane
+ * @pipe:		Pointer to software pipe
+ * @lut_usage:		LUT usecase
+ * @fmt:		Pointer to source buffer format
+ * @src_width:		width of source buffer
+ * Return: fill level corresponding to the source buffer/format or 0 if error
+ */
+static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
+		struct dpu_sw_pipe *pipe,
+		enum dpu_qos_lut_usage lut_usage,
+		const struct dpu_format *fmt, u32 src_width)
+{
+	struct dpu_plane *pdpu;
+	u32 fixed_buff_size;
+	u32 total_fl;
+
+	if (!fmt || !pipe || !src_width || !fmt->bpp) {
+		DPU_ERROR("invalid arguments\n");
+		return 0;
+	}
+
+	if (lut_usage == DPU_QOS_LUT_USAGE_NRT)
+		return 0;
+
+	pdpu = to_dpu_plane(plane);
+	fixed_buff_size = pdpu->catalog->caps->pixel_ram_size;
+
+	/* FIXME: in multirect case account for the src_width of all the planes */
+
+	if (fmt->fetch_planes == DPU_PLANE_PSEUDO_PLANAR) {
+		if (fmt->chroma_sample == DPU_CHROMA_420) {
+			/* NV12 */
+			total_fl = (fixed_buff_size / 2) /
+				((src_width + 32) * fmt->bpp);
+		} else {
+			/* non NV12 */
+			total_fl = (fixed_buff_size / 2) * 2 /
+				((src_width + 32) * fmt->bpp);
+		}
+	} else {
+		if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
+			total_fl = (fixed_buff_size / 2) * 2 /
+				((src_width + 32) * fmt->bpp);
+		} else {
+			total_fl = (fixed_buff_size) * 2 /
+				((src_width + 32) * fmt->bpp);
+		}
+	}
+
+	DPU_DEBUG_PLANE(pdpu, "pnum:%d fmt: %4.4s w:%u fl:%u\n",
+			pipe->sspp->idx - SSPP_VIG0,
+			(char *)&fmt->base.pixel_format,
+			src_width, total_fl);
+
+	return total_fl;
+}
+
+/**
+ * _dpu_plane_set_qos_lut - set QoS LUT of the given plane
+ * @plane:		Pointer to drm plane
+ * @pipe:		Pointer to software pipe
+ * @fmt:		Pointer to source buffer format
+ * @pipe_cfg:		Pointer to pipe configuration
+ */
+static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
+		struct dpu_sw_pipe *pipe,
+		const struct dpu_format *fmt, struct dpu_sw_pipe_cfg *pipe_cfg)
+{
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_hw_qos_cfg cfg;
+	u32 total_fl, lut_usage;
+
+	if (!pdpu->is_rt_pipe) {
+		lut_usage = DPU_QOS_LUT_USAGE_NRT;
+	} else {
+		if (fmt && DPU_FORMAT_IS_LINEAR(fmt))
+			lut_usage = DPU_QOS_LUT_USAGE_LINEAR;
+		else
+			lut_usage = DPU_QOS_LUT_USAGE_MACROTILE;
+	}
+
+	total_fl = _dpu_plane_calc_fill_level(plane, pipe, lut_usage, fmt,
+				drm_rect_width(&pipe_cfg->src_rect));
+
+	cfg.creq_lut = _dpu_hw_get_qos_lut(&pdpu->catalog->perf->qos_lut_tbl[lut_usage], total_fl);
+	cfg.danger_lut = pdpu->catalog->perf->danger_lut_tbl[lut_usage];
+	cfg.safe_lut = pdpu->catalog->perf->safe_lut_tbl[lut_usage];
+
+	if (pipe->sspp->idx != SSPP_CURSOR0 &&
+	    pipe->sspp->idx != SSPP_CURSOR1 &&
+	    pdpu->is_rt_pipe)
+		cfg.danger_safe_en = true;
+
+	DPU_DEBUG_PLANE(pdpu, "pnum:%d ds:%d is_rt:%d\n",
+		pdpu->pipe - SSPP_VIG0,
+		cfg.danger_safe_en,
+		pdpu->is_rt_pipe);
+
+	trace_dpu_perf_set_qos_luts(pipe->sspp->idx - SSPP_VIG0,
+			(fmt) ? fmt->base.pixel_format : 0,
+			pdpu->is_rt_pipe, total_fl, cfg.creq_lut, lut_usage);
+
+	DPU_DEBUG_PLANE(pdpu, "pnum:%d fmt: %4.4s rt:%d fl:%u lut:0x%llx\n",
+			pdpu->pipe - SSPP_VIG0,
+			fmt ? (char *)&fmt->base.pixel_format : NULL,
+			pdpu->is_rt_pipe, total_fl, cfg.creq_lut);
+
+	trace_dpu_perf_set_danger_luts(pdpu->pipe - SSPP_VIG0,
+			(fmt) ? fmt->base.pixel_format : 0,
+			(fmt) ? fmt->fetch_mode : 0,
+			cfg.danger_lut,
+			cfg.safe_lut);
+
+	DPU_DEBUG_PLANE(pdpu, "pnum:%d fmt: %4.4s mode:%d luts[0x%x, 0x%x]\n",
+		pdpu->pipe - SSPP_VIG0,
+		fmt ? (char *)&fmt->base.pixel_format : NULL,
+		fmt ? fmt->fetch_mode : -1,
+		cfg.danger_lut,
+		cfg.safe_lut);
+
+	pipe->sspp->ops.setup_qos_lut(pipe->sspp, &cfg);
+}
+
+/**
+ * _dpu_plane_set_qos_ctrl - set QoS control of the given plane
+ * @plane:		Pointer to drm plane
+ * @pipe:		Pointer to software pipe
+ * @enable:		true to enable QoS control
+ */
+static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
+	struct dpu_sw_pipe *pipe,
+	bool enable)
+{
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+
+	if (!pdpu->is_rt_pipe)
+		enable = false;
+
+	DPU_DEBUG_PLANE(pdpu, "pnum:%d ds:%d is_rt:%d\n",
+		pdpu->pipe - SSPP_VIG0,
+		enable,
+		pdpu->is_rt_pipe);
+
+	pipe->sspp->ops.setup_qos_ctrl(pipe->sspp,
+				       enable);
+}
+
+static bool _dpu_plane_sspp_clk_force_ctrl(struct dpu_hw_sspp *sspp,
+					   struct dpu_hw_mdp *mdp,
+					   bool enable, bool *forced_on)
+{
+	if (sspp->ops.setup_clk_force_ctrl) {
+		*forced_on = sspp->ops.setup_clk_force_ctrl(sspp, enable);
+		return true;
+	}
+
+	if (mdp->ops.setup_clk_force_ctrl) {
+		*forced_on = mdp->ops.setup_clk_force_ctrl(mdp, sspp->cap->clk_ctrl, enable);
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * _dpu_plane_set_ot_limit - set OT limit for the given plane
+ * @plane:		Pointer to drm plane
+ * @pipe:		Pointer to software pipe
+ * @pipe_cfg:		Pointer to pipe configuration
+ * @frame_rate:		CRTC's frame rate
+ */
+static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
+		struct dpu_sw_pipe *pipe,
+		struct dpu_sw_pipe_cfg *pipe_cfg,
+		int frame_rate)
+{
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_vbif_set_ot_params ot_params;
+	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
+	bool forced_on = false;
+
+	memset(&ot_params, 0, sizeof(ot_params));
+	ot_params.xin_id = pipe->sspp->cap->xin_id;
+	ot_params.num = pipe->sspp->idx - SSPP_NONE;
+	ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
+	ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
+	ot_params.is_wfd = !pdpu->is_rt_pipe;
+	ot_params.frame_rate = frame_rate;
+	ot_params.vbif_idx = VBIF_RT;
+	ot_params.rd = true;
+
+	if (!_dpu_plane_sspp_clk_force_ctrl(pipe->sspp, dpu_kms->hw_mdp,
+					    true, &forced_on))
+		return;
+
+	dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
+
+	if (forced_on)
+		_dpu_plane_sspp_clk_force_ctrl(pipe->sspp, dpu_kms->hw_mdp,
+					       false, &forced_on);
+}
+
+/**
+ * _dpu_plane_set_qos_remap - set vbif QoS for the given plane
+ * @plane:		Pointer to drm plane
+ * @pipe:		Pointer to software pipe
+ */
+static void _dpu_plane_set_qos_remap(struct drm_plane *plane,
+		struct dpu_sw_pipe *pipe)
+{
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_vbif_set_qos_params qos_params;
+	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
+	bool forced_on = false;
+
+	memset(&qos_params, 0, sizeof(qos_params));
+	qos_params.vbif_idx = VBIF_RT;
+	qos_params.xin_id = pipe->sspp->cap->xin_id;
+	qos_params.num = pipe->sspp->idx - SSPP_VIG0;
+	qos_params.is_rt = pdpu->is_rt_pipe;
+
+	DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d\n",
+			qos_params.num,
+			qos_params.vbif_idx,
+			qos_params.xin_id, qos_params.is_rt);
+
+	if (!_dpu_plane_sspp_clk_force_ctrl(pipe->sspp, dpu_kms->hw_mdp,
+					    true, &forced_on))
+		return;
+
+	dpu_vbif_set_qos_remap(dpu_kms, &qos_params);
+
+	if (forced_on)
+		_dpu_plane_sspp_clk_force_ctrl(pipe->sspp, dpu_kms->hw_mdp,
+					       false, &forced_on);
+}
+
+static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *pipe_hw,
+		uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h,
+		struct dpu_hw_scaler3_cfg *scale_cfg,
+		const struct dpu_format *fmt,
+		uint32_t chroma_subsmpl_h, uint32_t chroma_subsmpl_v,
+		unsigned int rotation)
+{
+	uint32_t i;
+	bool inline_rotation = rotation & DRM_MODE_ROTATE_90;
+
+	/*
+	 * For inline rotation cases, scaler config is post-rotation,
+	 * so swap the dimensions here. However, pixel extension will
+	 * need pre-rotation settings.
+	 */
+	if (inline_rotation)
+		swap(src_w, src_h);
+
+	scale_cfg->phase_step_x[DPU_SSPP_COMP_0] =
+		mult_frac((1 << PHASE_STEP_SHIFT), src_w, dst_w);
+	scale_cfg->phase_step_y[DPU_SSPP_COMP_0] =
+		mult_frac((1 << PHASE_STEP_SHIFT), src_h, dst_h);
+
+
+	scale_cfg->phase_step_y[DPU_SSPP_COMP_1_2] =
+		scale_cfg->phase_step_y[DPU_SSPP_COMP_0] / chroma_subsmpl_v;
+	scale_cfg->phase_step_x[DPU_SSPP_COMP_1_2] =
+		scale_cfg->phase_step_x[DPU_SSPP_COMP_0] / chroma_subsmpl_h;
+
+	scale_cfg->phase_step_x[DPU_SSPP_COMP_2] =
+		scale_cfg->phase_step_x[DPU_SSPP_COMP_1_2];
+	scale_cfg->phase_step_y[DPU_SSPP_COMP_2] =
+		scale_cfg->phase_step_y[DPU_SSPP_COMP_1_2];
+
+	scale_cfg->phase_step_x[DPU_SSPP_COMP_3] =
+		scale_cfg->phase_step_x[DPU_SSPP_COMP_0];
+	scale_cfg->phase_step_y[DPU_SSPP_COMP_3] =
+		scale_cfg->phase_step_y[DPU_SSPP_COMP_0];
+
+	for (i = 0; i < DPU_MAX_PLANES; i++) {
+		scale_cfg->src_width[i] = src_w;
+		scale_cfg->src_height[i] = src_h;
+		if (i == DPU_SSPP_COMP_1_2 || i == DPU_SSPP_COMP_2) {
+			scale_cfg->src_width[i] /= chroma_subsmpl_h;
+			scale_cfg->src_height[i] /= chroma_subsmpl_v;
+		}
+
+		if (pipe_hw->cap->sblk->scaler_blk.version >= 0x3000) {
+			scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
+			scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
+		} else {
+			scale_cfg->preload_x[i] = DPU_QSEED3_DEFAULT_PRELOAD_H;
+			scale_cfg->preload_y[i] = DPU_QSEED3_DEFAULT_PRELOAD_V;
+		}
+	}
+	if (!(DPU_FORMAT_IS_YUV(fmt)) && (src_h == dst_h)
+		&& (src_w == dst_w))
+		return;
+
+	scale_cfg->dst_width = dst_w;
+	scale_cfg->dst_height = dst_h;
+	scale_cfg->y_rgb_filter_cfg = DPU_SCALE_BIL;
+	scale_cfg->uv_filter_cfg = DPU_SCALE_BIL;
+	scale_cfg->alpha_filter_cfg = DPU_SCALE_ALPHA_BIL;
+	scale_cfg->lut_flag = 0;
+	scale_cfg->blend_cfg = 1;
+	scale_cfg->enable = 1;
+}
+
+static void _dpu_plane_setup_pixel_ext(struct dpu_hw_scaler3_cfg *scale_cfg,
+				struct dpu_hw_pixel_ext *pixel_ext,
+				uint32_t src_w, uint32_t src_h,
+				uint32_t chroma_subsmpl_h, uint32_t chroma_subsmpl_v)
+{
+	int i;
+
+	for (i = 0; i < DPU_MAX_PLANES; i++) {
+		if (i == DPU_SSPP_COMP_1_2 || i == DPU_SSPP_COMP_2) {
+			src_w /= chroma_subsmpl_h;
+			src_h /= chroma_subsmpl_v;
+		}
+
+		pixel_ext->num_ext_pxls_top[i] = src_h;
+		pixel_ext->num_ext_pxls_left[i] = src_w;
+	}
+}
+
+static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_sw_pipe *pipe,
+						    const struct dpu_format *fmt)
+{
+	const struct dpu_csc_cfg *csc_ptr;
+
+	if (!DPU_FORMAT_IS_YUV(fmt))
+		return NULL;
+
+	if (BIT(DPU_SSPP_CSC_10BIT) & pipe->sspp->cap->features)
+		csc_ptr = &dpu_csc10_YUV2RGB_601L;
+	else
+		csc_ptr = &dpu_csc_YUV2RGB_601L;
+
+	return csc_ptr;
+}
+
+static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe,
+		const struct dpu_format *fmt, bool color_fill,
+		struct dpu_sw_pipe_cfg *pipe_cfg,
+		unsigned int rotation)
+{
+	struct dpu_hw_sspp *pipe_hw = pipe->sspp;
+	const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format);
+	struct dpu_hw_scaler3_cfg scaler3_cfg;
+	struct dpu_hw_pixel_ext pixel_ext;
+	u32 src_width = drm_rect_width(&pipe_cfg->src_rect);
+	u32 src_height = drm_rect_height(&pipe_cfg->src_rect);
+	u32 dst_width = drm_rect_width(&pipe_cfg->dst_rect);
+	u32 dst_height = drm_rect_height(&pipe_cfg->dst_rect);
+
+	memset(&scaler3_cfg, 0, sizeof(scaler3_cfg));
+	memset(&pixel_ext, 0, sizeof(pixel_ext));
+
+	/* don't chroma subsample if decimating */
+	/* update scaler. calculate default config for QSEED3 */
+	_dpu_plane_setup_scaler3(pipe_hw,
+			src_width,
+			src_height,
+			dst_width,
+			dst_height,
+			&scaler3_cfg, fmt,
+			info->hsub, info->vsub,
+			rotation);
+
+	/* configure pixel extension based on scalar config */
+	_dpu_plane_setup_pixel_ext(&scaler3_cfg, &pixel_ext,
+			src_width, src_height, info->hsub, info->vsub);
+
+	if (pipe_hw->ops.setup_pe)
+		pipe_hw->ops.setup_pe(pipe_hw,
+				&pixel_ext);
+
+	/**
+	 * when programmed in multirect mode, scalar block will be
+	 * bypassed. Still we need to update alpha and bitwidth
+	 * ONLY for RECT0
+	 */
+	if (pipe_hw->ops.setup_scaler &&
+			pipe->multirect_index != DPU_SSPP_RECT_1)
+		pipe_hw->ops.setup_scaler(pipe_hw,
+				&scaler3_cfg,
+				fmt);
+}
+
+static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
+				       struct dpu_sw_pipe *pipe,
+				       struct drm_rect *dst_rect,
+				       u32 fill_color,
+				       const struct dpu_format *fmt)
+{
+	struct dpu_sw_pipe_cfg pipe_cfg;
+
+	/* update sspp */
+	if (!pipe->sspp->ops.setup_solidfill)
+		return;
+
+	pipe->sspp->ops.setup_solidfill(pipe, fill_color);
+
+	/* override scaler/decimation if solid fill */
+	pipe_cfg.dst_rect = *dst_rect;
+
+	pipe_cfg.src_rect.x1 = 0;
+	pipe_cfg.src_rect.y1 = 0;
+	pipe_cfg.src_rect.x2 =
+		drm_rect_width(&pipe_cfg.dst_rect);
+	pipe_cfg.src_rect.y2 =
+		drm_rect_height(&pipe_cfg.dst_rect);
+
+	if (pipe->sspp->ops.setup_format)
+		pipe->sspp->ops.setup_format(pipe, fmt, DPU_SSPP_SOLID_FILL);
+
+	if (pipe->sspp->ops.setup_rects)
+		pipe->sspp->ops.setup_rects(pipe, &pipe_cfg);
+
+	_dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation);
+}
+
+/**
+ * _dpu_plane_color_fill - enables color fill on plane
+ * @pdpu:   Pointer to DPU plane object
+ * @color:  RGB fill color value, [23..16] Blue, [15..8] Green, [7..0] Red
+ * @alpha:  8-bit fill alpha value, 255 selects 100% alpha
+ */
+static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
+		uint32_t color, uint32_t alpha)
+{
+	const struct dpu_format *fmt;
+	const struct drm_plane *plane = &pdpu->base;
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
+	u32 fill_color = (color & 0xFFFFFF) | ((alpha & 0xFF) << 24);
+
+	DPU_DEBUG_PLANE(pdpu, "\n");
+
+	/*
+	 * select fill format to match user property expectation,
+	 * h/w only supports RGB variants
+	 */
+	fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
+	/* should not happen ever */
+	if (!fmt)
+		return;
+
+	/* update sspp */
+	_dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg.dst_rect,
+				   fill_color, fmt);
+
+	if (pstate->r_pipe.sspp)
+		_dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg.dst_rect,
+					   fill_color, fmt);
+}
+
+static int dpu_plane_prepare_fb(struct drm_plane *plane,
+		struct drm_plane_state *new_state)
+{
+	struct drm_framebuffer *fb = new_state->fb;
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(new_state);
+	struct dpu_hw_fmt_layout layout;
+	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
+	int ret;
+
+	if (!new_state->fb)
+		return 0;
+
+	DPU_DEBUG_PLANE(pdpu, "FB[%u]\n", fb->base.id);
+
+	/* cache aspace */
+	pstate->aspace = kms->base.aspace;
+
+	/*
+	 * TODO: Need to sort out the msm_framebuffer_prepare() call below so
+	 *       we can use msm_atomic_prepare_fb() instead of doing the
+	 *       implicit fence and fb prepare by hand here.
+	 */
+	drm_gem_plane_helper_prepare_fb(plane, new_state);
+
+	if (pstate->aspace) {
+		ret = msm_framebuffer_prepare(new_state->fb,
+				pstate->aspace, pstate->needs_dirtyfb);
+		if (ret) {
+			DPU_ERROR("failed to prepare framebuffer\n");
+			return ret;
+		}
+	}
+
+	/* validate framebuffer layout before commit */
+	ret = dpu_format_populate_layout(pstate->aspace,
+			new_state->fb, &layout);
+	if (ret) {
+		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
+		if (pstate->aspace)
+			msm_framebuffer_cleanup(new_state->fb, pstate->aspace,
+						pstate->needs_dirtyfb);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void dpu_plane_cleanup_fb(struct drm_plane *plane,
+		struct drm_plane_state *old_state)
+{
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *old_pstate;
+
+	if (!old_state || !old_state->fb)
+		return;
+
+	old_pstate = to_dpu_plane_state(old_state);
+
+	DPU_DEBUG_PLANE(pdpu, "FB[%u]\n", old_state->fb->base.id);
+
+	msm_framebuffer_cleanup(old_state->fb, old_pstate->aspace,
+				old_pstate->needs_dirtyfb);
+}
+
+static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
+						const struct dpu_sspp_sub_blks *sblk,
+						struct drm_rect src, const struct dpu_format *fmt)
+{
+	size_t num_formats;
+	const u32 *supported_formats;
+
+	if (!sblk->rotation_cfg) {
+		DPU_ERROR("invalid rotation cfg\n");
+		return -EINVAL;
+	}
+
+	if (drm_rect_width(&src) > sblk->rotation_cfg->rot_maxheight) {
+		DPU_DEBUG_PLANE(pdpu, "invalid height for inline rot:%d max:%d\n",
+				src.y2, sblk->rotation_cfg->rot_maxheight);
+		return -EINVAL;
+	}
+
+	supported_formats = sblk->rotation_cfg->rot_format_list;
+	num_formats = sblk->rotation_cfg->rot_num_formats;
+
+	if (!DPU_FORMAT_IS_UBWC(fmt) ||
+		!dpu_find_format(fmt->base.pixel_format, supported_formats, num_formats))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
+		struct dpu_sw_pipe *pipe,
+		struct dpu_sw_pipe_cfg *pipe_cfg,
+		const struct dpu_format *fmt,
+		const struct drm_display_mode *mode)
+{
+	uint32_t min_src_size;
+	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
+
+	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
+
+	if (DPU_FORMAT_IS_YUV(fmt) &&
+	    !pipe->sspp->cap->sblk->csc_blk.len) {
+		DPU_DEBUG_PLANE(pdpu,
+				"plane doesn't have csc for yuv\n");
+		return -EINVAL;
+	}
+
+	/* check src bounds */
+	if (drm_rect_width(&pipe_cfg->src_rect) < min_src_size ||
+	    drm_rect_height(&pipe_cfg->src_rect) < min_src_size) {
+		DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
+				DRM_RECT_ARG(&pipe_cfg->src_rect));
+		return -E2BIG;
+	}
+
+	/* valid yuv image */
+	if (DPU_FORMAT_IS_YUV(fmt) &&
+	    (pipe_cfg->src_rect.x1 & 0x1 ||
+	     pipe_cfg->src_rect.y1 & 0x1 ||
+	     drm_rect_width(&pipe_cfg->src_rect) & 0x1 ||
+	     drm_rect_height(&pipe_cfg->src_rect) & 0x1)) {
+		DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
+				DRM_RECT_ARG(&pipe_cfg->src_rect));
+		return -EINVAL;
+	}
+
+	/* min dst support */
+	if (drm_rect_width(&pipe_cfg->dst_rect) < 0x1 ||
+	    drm_rect_height(&pipe_cfg->dst_rect) < 0x1) {
+		DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
+				DRM_RECT_ARG(&pipe_cfg->dst_rect));
+		return -EINVAL;
+	}
+
+	/* max clk check */
+	if (_dpu_plane_calc_clk(mode, pipe_cfg) > kms->perf.max_core_clk_rate) {
+		DPU_DEBUG_PLANE(pdpu, "plane exceeds max mdp core clk limits\n");
+		return -E2BIG;
+	}
+
+	return 0;
+}
+
+static int dpu_plane_atomic_check(struct drm_plane *plane,
+				  struct drm_atomic_state *state)
+{
+	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
+										 plane);
+	int ret = 0, min_scale;
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
+	u64 max_mdp_clk_rate = kms->perf.max_core_clk_rate;
+	struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
+	struct dpu_sw_pipe *pipe = &pstate->pipe;
+	struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
+	const struct drm_crtc_state *crtc_state = NULL;
+	const struct dpu_format *fmt;
+	struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+	struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
+	struct drm_rect fb_rect = { 0 };
+	uint32_t max_linewidth;
+	unsigned int rotation;
+	uint32_t supported_rotations;
+	const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
+	const struct dpu_sspp_sub_blks *sblk = pstate->pipe.sspp->cap->sblk;
+
+	if (new_plane_state->crtc)
+		crtc_state = drm_atomic_get_new_crtc_state(state,
+							   new_plane_state->crtc);
+
+	min_scale = FRAC_16_16(1, sblk->maxupscale);
+	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
+						  min_scale,
+						  sblk->maxdwnscale << 16,
+						  true, true);
+	if (ret) {
+		DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
+		return ret;
+	}
+	if (!new_plane_state->visible)
+		return 0;
+
+	pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+	pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+	r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+	r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+	r_pipe->sspp = NULL;
+
+	pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
+	if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
+		DPU_ERROR("> %d plane stages assigned\n",
+			  pdpu->catalog->caps->max_mixer_blendstages - DPU_STAGE_0);
+		return -EINVAL;
+	}
+
+	pipe_cfg->src_rect = new_plane_state->src;
+
+	/* state->src is 16.16, src_rect is not */
+	pipe_cfg->src_rect.x1 >>= 16;
+	pipe_cfg->src_rect.x2 >>= 16;
+	pipe_cfg->src_rect.y1 >>= 16;
+	pipe_cfg->src_rect.y2 >>= 16;
+
+	pipe_cfg->dst_rect = new_plane_state->dst;
+
+	fb_rect.x2 = new_plane_state->fb->width;
+	fb_rect.y2 = new_plane_state->fb->height;
+
+	/* Ensure fb size is supported */
+	if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH ||
+	    drm_rect_height(&fb_rect) > MAX_IMG_HEIGHT) {
+		DPU_DEBUG_PLANE(pdpu, "invalid framebuffer " DRM_RECT_FMT "\n",
+				DRM_RECT_ARG(&fb_rect));
+		return -E2BIG;
+	}
+
+	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
+
+	max_linewidth = pdpu->catalog->caps->max_linewidth;
+
+	drm_rect_rotate(&pipe_cfg->src_rect,
+			new_plane_state->fb->width, new_plane_state->fb->height,
+			new_plane_state->rotation);
+
+	if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) ||
+	     _dpu_plane_calc_clk(&crtc_state->adjusted_mode, pipe_cfg) > max_mdp_clk_rate) {
+		/*
+		 * In parallel multirect case only the half of the usual width
+		 * is supported for tiled formats. If we are here, we know that
+		 * full width is more than max_linewidth, thus each rect is
+		 * wider than allowed.
+		 */
+		if (DPU_FORMAT_IS_UBWC(fmt) &&
+		    drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
+			DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, tiled format\n",
+					DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
+			return -E2BIG;
+		}
+
+		if (drm_rect_width(&pipe_cfg->src_rect) > 2 * max_linewidth) {
+			DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
+					DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
+			return -E2BIG;
+		}
+
+		if (drm_rect_width(&pipe_cfg->src_rect) != drm_rect_width(&pipe_cfg->dst_rect) ||
+		    drm_rect_height(&pipe_cfg->src_rect) != drm_rect_height(&pipe_cfg->dst_rect) ||
+		    (!test_bit(DPU_SSPP_SMART_DMA_V1, &pipe->sspp->cap->features) &&
+		     !test_bit(DPU_SSPP_SMART_DMA_V2, &pipe->sspp->cap->features)) ||
+		    DPU_FORMAT_IS_YUV(fmt)) {
+			DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, can't use split source\n",
+					DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
+			return -E2BIG;
+		}
+
+		/*
+		 * Use multirect for wide plane. We do not support dynamic
+		 * assignment of SSPPs, so we know the configuration.
+		 */
+		pipe->multirect_index = DPU_SSPP_RECT_0;
+		pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
+
+		r_pipe->sspp = pipe->sspp;
+		r_pipe->multirect_index = DPU_SSPP_RECT_1;
+		r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
+
+		*r_pipe_cfg = *pipe_cfg;
+		pipe_cfg->src_rect.x2 = (pipe_cfg->src_rect.x1 + pipe_cfg->src_rect.x2) >> 1;
+		pipe_cfg->dst_rect.x2 = (pipe_cfg->dst_rect.x1 + pipe_cfg->dst_rect.x2) >> 1;
+		r_pipe_cfg->src_rect.x1 = pipe_cfg->src_rect.x2;
+		r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2;
+	}
+
+	drm_rect_rotate_inv(&pipe_cfg->src_rect,
+			    new_plane_state->fb->width, new_plane_state->fb->height,
+			    new_plane_state->rotation);
+	if (r_pipe->sspp)
+		drm_rect_rotate_inv(&r_pipe_cfg->src_rect,
+				    new_plane_state->fb->width, new_plane_state->fb->height,
+				    new_plane_state->rotation);
+
+	ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt, &crtc_state->adjusted_mode);
+	if (ret)
+		return ret;
+
+	if (r_pipe->sspp) {
+		ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt,
+						  &crtc_state->adjusted_mode);
+		if (ret)
+			return ret;
+	}
+
+	supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
+
+	if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
+		supported_rotations |= DRM_MODE_ROTATE_90;
+
+	rotation = drm_rotation_simplify(new_plane_state->rotation,
+					supported_rotations);
+
+	if ((pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) &&
+		(rotation & DRM_MODE_ROTATE_90)) {
+		ret = dpu_plane_check_inline_rotation(pdpu, sblk, pipe_cfg->src_rect, fmt);
+		if (ret)
+			return ret;
+	}
+
+	pstate->rotation = rotation;
+	pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state);
+
+	return 0;
+}
+
+static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe)
+{
+	const struct dpu_format *format =
+		to_dpu_format(msm_framebuffer_format(pdpu->base.state->fb));
+	const struct dpu_csc_cfg *csc_ptr;
+
+	if (!pipe->sspp || !pipe->sspp->ops.setup_csc)
+		return;
+
+	csc_ptr = _dpu_plane_get_csc(pipe, format);
+	if (!csc_ptr)
+		return;
+
+	DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
+			csc_ptr->csc_mv[0],
+			csc_ptr->csc_mv[1],
+			csc_ptr->csc_mv[2]);
+
+	pipe->sspp->ops.setup_csc(pipe->sspp, csc_ptr);
+
+}
+
+void dpu_plane_flush(struct drm_plane *plane)
+{
+	struct dpu_plane *pdpu;
+	struct dpu_plane_state *pstate;
+
+	if (!plane || !plane->state) {
+		DPU_ERROR("invalid plane\n");
+		return;
+	}
+
+	pdpu = to_dpu_plane(plane);
+	pstate = to_dpu_plane_state(plane->state);
+
+	/*
+	 * These updates have to be done immediately before the plane flush
+	 * timing, and may not be moved to the atomic_update/mode_set functions.
+	 */
+	if (pdpu->is_error)
+		/* force white frame with 100% alpha pipe output on error */
+		_dpu_plane_color_fill(pdpu, 0xFFFFFF, 0xFF);
+	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
+		/* force 100% alpha */
+		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
+	else {
+		dpu_plane_flush_csc(pdpu, &pstate->pipe);
+		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
+	}
+
+	/* flag h/w flush complete */
+	if (plane->state)
+		pstate->pending = false;
+}
+
+/**
+ * dpu_plane_set_error: enable/disable error condition
+ * @plane: pointer to drm_plane structure
+ * @error: error value to set
+ */
+void dpu_plane_set_error(struct drm_plane *plane, bool error)
+{
+	struct dpu_plane *pdpu;
+
+	if (!plane)
+		return;
+
+	pdpu = to_dpu_plane(plane);
+	pdpu->is_error = error;
+}
+
+static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
+				       struct dpu_sw_pipe *pipe,
+				       struct dpu_sw_pipe_cfg *pipe_cfg,
+				       const struct dpu_format *fmt,
+				       int frame_rate,
+				       struct dpu_hw_fmt_layout *layout)
+{
+	uint32_t src_flags;
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct drm_plane_state *state = plane->state;
+	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
+
+	if (layout && pipe->sspp->ops.setup_sourceaddress) {
+		trace_dpu_plane_set_scanout(pipe, layout);
+		pipe->sspp->ops.setup_sourceaddress(pipe, layout);
+	}
+
+	/* override for color fill */
+	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
+		_dpu_plane_set_qos_ctrl(plane, pipe, false);
+
+		/* skip remaining processing on color fill */
+		return;
+	}
+
+	if (pipe->sspp->ops.setup_rects) {
+		pipe->sspp->ops.setup_rects(pipe,
+				pipe_cfg);
+	}
+
+	_dpu_plane_setup_scaler(pipe, fmt, false, pipe_cfg, pstate->rotation);
+
+	if (pipe->sspp->ops.setup_multirect)
+		pipe->sspp->ops.setup_multirect(
+				pipe);
+
+	if (pipe->sspp->ops.setup_format) {
+		unsigned int rotation = pstate->rotation;
+
+		src_flags = 0x0;
+
+		if (rotation & DRM_MODE_REFLECT_X)
+			src_flags |= DPU_SSPP_FLIP_LR;
+
+		if (rotation & DRM_MODE_REFLECT_Y)
+			src_flags |= DPU_SSPP_FLIP_UD;
+
+		if (rotation & DRM_MODE_ROTATE_90)
+			src_flags |= DPU_SSPP_ROT_90;
+
+		/* update format */
+		pipe->sspp->ops.setup_format(pipe, fmt, src_flags);
+
+		if (pipe->sspp->ops.setup_cdp) {
+			const struct dpu_perf_cfg *perf = pdpu->catalog->perf;
+
+			pipe->sspp->ops.setup_cdp(pipe, fmt,
+						  perf->cdp_cfg[DPU_PERF_CDP_USAGE_RT].rd_enable);
+		}
+	}
+
+	_dpu_plane_set_qos_lut(plane, pipe, fmt, pipe_cfg);
+
+	if (pipe->sspp->idx != SSPP_CURSOR0 &&
+	    pipe->sspp->idx != SSPP_CURSOR1)
+		_dpu_plane_set_ot_limit(plane, pipe, pipe_cfg, frame_rate);
+
+	if (pstate->needs_qos_remap)
+		_dpu_plane_set_qos_remap(plane, pipe);
+}
+
+static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
+{
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct drm_plane_state *state = plane->state;
+	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
+	struct dpu_sw_pipe *pipe = &pstate->pipe;
+	struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
+	struct drm_crtc *crtc = state->crtc;
+	struct drm_framebuffer *fb = state->fb;
+	bool is_rt_pipe;
+	const struct dpu_format *fmt =
+		to_dpu_format(msm_framebuffer_format(fb));
+	struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+	struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
+	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
+	struct msm_gem_address_space *aspace = kms->base.aspace;
+	struct dpu_hw_fmt_layout layout;
+	bool layout_valid = false;
+	int ret;
+
+	ret = dpu_format_populate_layout(aspace, fb, &layout);
+	if (ret)
+		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
+	else
+		layout_valid = true;
+
+	pstate->pending = true;
+
+	is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
+	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
+	pdpu->is_rt_pipe = is_rt_pipe;
+
+	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
+			", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
+			crtc->base.id, DRM_RECT_ARG(&state->dst),
+			(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
+
+	dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
+				   drm_mode_vrefresh(&crtc->mode),
+				   layout_valid ? &layout : NULL);
+
+	if (r_pipe->sspp) {
+		dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
+					   drm_mode_vrefresh(&crtc->mode),
+					   layout_valid ? &layout : NULL);
+	}
+
+	if (pstate->needs_qos_remap)
+		pstate->needs_qos_remap = false;
+
+	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt,
+						    &crtc->mode, pipe_cfg);
+
+	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, pipe_cfg);
+
+	if (r_pipe->sspp) {
+		pstate->plane_fetch_bw += _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, r_pipe_cfg);
+
+		pstate->plane_clk = max(pstate->plane_clk, _dpu_plane_calc_clk(&crtc->mode, r_pipe_cfg));
+	}
+}
+
+static void _dpu_plane_atomic_disable(struct drm_plane *plane)
+{
+	struct drm_plane_state *state = plane->state;
+	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
+	struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
+
+	trace_dpu_plane_disable(DRMID(plane), false,
+				pstate->pipe.multirect_mode);
+
+	if (r_pipe->sspp) {
+		r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+		r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+
+		if (r_pipe->sspp->ops.setup_multirect)
+			r_pipe->sspp->ops.setup_multirect(r_pipe);
+	}
+
+	pstate->pending = true;
+}
+
+static void dpu_plane_atomic_update(struct drm_plane *plane,
+				struct drm_atomic_state *state)
+{
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
+									   plane);
+
+	pdpu->is_error = false;
+
+	DPU_DEBUG_PLANE(pdpu, "\n");
+
+	if (!new_state->visible) {
+		_dpu_plane_atomic_disable(plane);
+	} else {
+		dpu_plane_sspp_atomic_update(plane);
+	}
+}
+
+static void dpu_plane_destroy_state(struct drm_plane *plane,
+		struct drm_plane_state *state)
+{
+	__drm_atomic_helper_plane_destroy_state(state);
+	kfree(to_dpu_plane_state(state));
+}
+
+static struct drm_plane_state *
+dpu_plane_duplicate_state(struct drm_plane *plane)
+{
+	struct dpu_plane *pdpu;
+	struct dpu_plane_state *pstate;
+	struct dpu_plane_state *old_state;
+
+	if (!plane) {
+		DPU_ERROR("invalid plane\n");
+		return NULL;
+	} else if (!plane->state) {
+		DPU_ERROR("invalid plane state\n");
+		return NULL;
+	}
+
+	old_state = to_dpu_plane_state(plane->state);
+	pdpu = to_dpu_plane(plane);
+	pstate = kmemdup(old_state, sizeof(*old_state), GFP_KERNEL);
+	if (!pstate) {
+		DPU_ERROR_PLANE(pdpu, "failed to allocate state\n");
+		return NULL;
+	}
+
+	DPU_DEBUG_PLANE(pdpu, "\n");
+
+	pstate->pending = false;
+
+	__drm_atomic_helper_plane_duplicate_state(plane, &pstate->base);
+
+	return &pstate->base;
+}
+
+static const char * const multirect_mode_name[] = {
+	[DPU_SSPP_MULTIRECT_NONE] = "none",
+	[DPU_SSPP_MULTIRECT_PARALLEL] = "parallel",
+	[DPU_SSPP_MULTIRECT_TIME_MX] = "time_mx",
+};
+
+static const char * const multirect_index_name[] = {
+	[DPU_SSPP_RECT_SOLO] = "solo",
+	[DPU_SSPP_RECT_0] = "rect_0",
+	[DPU_SSPP_RECT_1] = "rect_1",
+};
+
+static const char *dpu_get_multirect_mode(enum dpu_sspp_multirect_mode mode)
+{
+	if (WARN_ON(mode >= ARRAY_SIZE(multirect_mode_name)))
+		return "unknown";
+
+	return multirect_mode_name[mode];
+}
+
+static const char *dpu_get_multirect_index(enum dpu_sspp_multirect_index index)
+{
+	if (WARN_ON(index >= ARRAY_SIZE(multirect_index_name)))
+		return "unknown";
+
+	return multirect_index_name[index];
+}
+
+static void dpu_plane_atomic_print_state(struct drm_printer *p,
+		const struct drm_plane_state *state)
+{
+	const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
+	const struct dpu_sw_pipe *pipe = &pstate->pipe;
+	const struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+	const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
+	const struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
+
+	drm_printf(p, "\tstage=%d\n", pstate->stage);
+
+	drm_printf(p, "\tsspp[0]=%s\n", pipe->sspp->cap->name);
+	drm_printf(p, "\tmultirect_mode[0]=%s\n", dpu_get_multirect_mode(pipe->multirect_mode));
+	drm_printf(p, "\tmultirect_index[0]=%s\n",
+		   dpu_get_multirect_index(pipe->multirect_index));
+	drm_printf(p, "\tsrc[0]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->src_rect));
+	drm_printf(p, "\tdst[0]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->dst_rect));
+
+	if (r_pipe->sspp) {
+		drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
+		drm_printf(p, "\tmultirect_mode[1]=%s\n",
+			   dpu_get_multirect_mode(r_pipe->multirect_mode));
+		drm_printf(p, "\tmultirect_index[1]=%s\n",
+			   dpu_get_multirect_index(r_pipe->multirect_index));
+		drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
+		drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
+	}
+}
+
+static void dpu_plane_reset(struct drm_plane *plane)
+{
+	struct dpu_plane *pdpu;
+	struct dpu_plane_state *pstate;
+	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
+
+	if (!plane) {
+		DPU_ERROR("invalid plane\n");
+		return;
+	}
+
+	pdpu = to_dpu_plane(plane);
+	DPU_DEBUG_PLANE(pdpu, "\n");
+
+	/* remove previous state, if present */
+	if (plane->state) {
+		dpu_plane_destroy_state(plane, plane->state);
+		plane->state = NULL;
+	}
+
+	pstate = kzalloc(sizeof(*pstate), GFP_KERNEL);
+	if (!pstate) {
+		DPU_ERROR_PLANE(pdpu, "failed to allocate state\n");
+		return;
+	}
+
+	/*
+	 * Set the SSPP here until we have proper virtualized DPU planes.
+	 * This is the place where the state is allocated, so fill it fully.
+	 */
+	pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
+	pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
+	pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+
+	pstate->r_pipe.sspp = NULL;
+
+	__drm_atomic_helper_plane_reset(plane, &pstate->base);
+}
+
+#ifdef CONFIG_DEBUG_FS
+void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
+{
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
+	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
+
+	if (!pdpu->is_rt_pipe)
+		return;
+
+	pm_runtime_get_sync(&dpu_kms->pdev->dev);
+	_dpu_plane_set_qos_ctrl(plane, &pstate->pipe, enable);
+	if (pstate->r_pipe.sspp)
+		_dpu_plane_set_qos_ctrl(plane, &pstate->r_pipe, enable);
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
+}
+#endif
+
+static bool dpu_plane_format_mod_supported(struct drm_plane *plane,
+		uint32_t format, uint64_t modifier)
+{
+	if (modifier == DRM_FORMAT_MOD_LINEAR)
+		return true;
+
+	if (modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED)
+		return dpu_find_format(format, qcom_compressed_supported_formats,
+				ARRAY_SIZE(qcom_compressed_supported_formats));
+
+	return false;
+}
+
+static const struct drm_plane_funcs dpu_plane_funcs = {
+		.update_plane = drm_atomic_helper_update_plane,
+		.disable_plane = drm_atomic_helper_disable_plane,
+		.reset = dpu_plane_reset,
+		.atomic_duplicate_state = dpu_plane_duplicate_state,
+		.atomic_destroy_state = dpu_plane_destroy_state,
+		.atomic_print_state = dpu_plane_atomic_print_state,
+		.format_mod_supported = dpu_plane_format_mod_supported,
+};
+
+static const struct drm_plane_helper_funcs dpu_plane_helper_funcs = {
+		.prepare_fb = dpu_plane_prepare_fb,
+		.cleanup_fb = dpu_plane_cleanup_fb,
+		.atomic_check = dpu_plane_atomic_check,
+		.atomic_update = dpu_plane_atomic_update,
+};
+
+/* initialize plane */
+struct drm_plane *dpu_plane_init(struct drm_device *dev,
+		uint32_t pipe, enum drm_plane_type type,
+		unsigned long possible_crtcs)
+{
+	struct drm_plane *plane = NULL;
+	const uint32_t *format_list;
+	struct dpu_plane *pdpu;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct dpu_kms *kms = to_dpu_kms(priv->kms);
+	struct dpu_hw_sspp *pipe_hw;
+	uint32_t num_formats;
+	uint32_t supported_rotations;
+	int ret;
+
+	/* initialize underlying h/w driver */
+	pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe);
+	if (!pipe_hw || !pipe_hw->cap || !pipe_hw->cap->sblk) {
+		DPU_ERROR("[%u]SSPP is invalid\n", pipe);
+		return ERR_PTR(-EINVAL);
+	}
+
+	format_list = pipe_hw->cap->sblk->format_list;
+	num_formats = pipe_hw->cap->sblk->num_formats;
+
+	pdpu = drmm_universal_plane_alloc(dev, struct dpu_plane, base,
+				0xff, &dpu_plane_funcs,
+				format_list, num_formats,
+				supported_format_modifiers, type, NULL);
+	if (IS_ERR(pdpu))
+		return ERR_CAST(pdpu);
+
+	/* cache local stuff for later */
+	plane = &pdpu->base;
+	pdpu->pipe = pipe;
+
+	pdpu->catalog = kms->catalog;
+
+	ret = drm_plane_create_zpos_property(plane, 0, 0, DPU_ZPOS_MAX);
+	if (ret)
+		DPU_ERROR("failed to install zpos property, rc = %d\n", ret);
+
+	drm_plane_create_alpha_property(plane);
+	drm_plane_create_blend_mode_property(plane,
+			BIT(DRM_MODE_BLEND_PIXEL_NONE) |
+			BIT(DRM_MODE_BLEND_PREMULTI) |
+			BIT(DRM_MODE_BLEND_COVERAGE));
+
+	supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
+
+	if (pipe_hw->cap->features & BIT(DPU_SSPP_INLINE_ROTATION))
+		supported_rotations |= DRM_MODE_ROTATE_MASK;
+
+	drm_plane_create_rotation_property(plane,
+		    DRM_MODE_ROTATE_0, supported_rotations);
+
+	drm_plane_enable_fb_damage_clips(plane);
+
+	/* success! finalize initialization */
+	drm_plane_helper_add(plane, &dpu_plane_helper_funcs);
+
+	DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name,
+					pipe, plane->base.id);
+	return plane;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_plane.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_plane.h
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef _DPU_PLANE_H_
+#define _DPU_PLANE_H_
+
+#include <drm/drm_crtc.h>
+
+#include "dpu_kms.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_sspp.h"
+
+/**
+ * struct dpu_plane_state: Define dpu extension of drm plane state object
+ * @base:	base drm plane state object
+ * @aspace:	pointer to address space for input/output buffers
+ * @pipe:	software pipe description
+ * @r_pipe:	software pipe description of the second pipe
+ * @pipe_cfg:	software pipe configuration
+ * @r_pipe_cfg:	software pipe configuration for the second pipe
+ * @stage:	assigned by crtc blender
+ * @needs_qos_remap: qos remap settings need to be updated
+ * @multirect_index: index of the rectangle of SSPP
+ * @multirect_mode: parallel or time multiplex multirect mode
+ * @pending:	whether the current update is still pending
+ * @plane_fetch_bw: calculated BW per plane
+ * @plane_clk: calculated clk per plane
+ * @needs_dirtyfb: whether attached CRTC needs pixel data explicitly flushed
+ * @rotation: simplified drm rotation hint
+ */
+struct dpu_plane_state {
+	struct drm_plane_state base;
+	struct msm_gem_address_space *aspace;
+	struct dpu_sw_pipe pipe;
+	struct dpu_sw_pipe r_pipe;
+	struct dpu_sw_pipe_cfg pipe_cfg;
+	struct dpu_sw_pipe_cfg r_pipe_cfg;
+	enum dpu_stage stage;
+	bool needs_qos_remap;
+	bool pending;
+
+	u64 plane_fetch_bw;
+	u64 plane_clk;
+
+	bool needs_dirtyfb;
+	unsigned int rotation;
+};
+
+#define to_dpu_plane_state(x) \
+	container_of(x, struct dpu_plane_state, base)
+
+/**
+ * dpu_plane_flush - final plane operations before commit flush
+ * @plane: Pointer to drm plane structure
+ */
+void dpu_plane_flush(struct drm_plane *plane);
+
+/**
+ * dpu_plane_set_error: enable/disable error condition
+ * @plane: pointer to drm_plane structure
+ */
+void dpu_plane_set_error(struct drm_plane *plane, bool error);
+
+/**
+ * dpu_plane_init - create new dpu plane for the given pipe
+ * @dev:   Pointer to DRM device
+ * @pipe:  dpu hardware pipe identifier
+ * @type:  Plane type - PRIMARY/OVERLAY/CURSOR
+ * @possible_crtcs: bitmask of crtc that can be attached to the given pipe
+ *
+ */
+struct drm_plane *dpu_plane_init(struct drm_device *dev,
+		uint32_t pipe, enum drm_plane_type type,
+		unsigned long possible_crtcs);
+
+/**
+ * dpu_plane_color_fill - enables color fill on plane
+ * @plane:  Pointer to DRM plane object
+ * @color:  RGB fill color value, [23..16] Blue, [15..8] Green, [7..0] Red
+ * @alpha:  8-bit fill alpha value, 255 selects 100% alpha
+ * Returns: 0 on success
+ */
+int dpu_plane_color_fill(struct drm_plane *plane,
+		uint32_t color, uint32_t alpha);
+
+#ifdef CONFIG_DEBUG_FS
+void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable);
+#else
+static inline void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) {}
+#endif
+
+#endif /* _DPU_PLANE_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_rm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_rm.c
@@ -0,0 +1,636 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm:%s] " fmt, __func__
+#include "dpu_kms.h"
+#include "dpu_hw_lm.h"
+#include "dpu_hw_ctl.h"
+#include "dpu_hw_cdm.h"
+#include "dpu_hw_pingpong.h"
+#include "dpu_hw_sspp.h"
+#include "dpu_hw_intf.h"
+#include "dpu_hw_wb.h"
+#include "dpu_hw_dspp.h"
+#include "dpu_hw_merge3d.h"
+#include "dpu_hw_dsc.h"
+#include "dpu_encoder.h"
+#include "dpu_trace.h"
+
+
+static inline bool reserved_by_other(uint32_t *res_map, int idx,
+				     uint32_t enc_id)
+{
+	return res_map[idx] && res_map[idx] != enc_id;
+}
+
+/**
+ * struct dpu_rm_requirements - Reservation requirements parameter bundle
+ * @topology:  selected topology for the display
+ */
+struct dpu_rm_requirements {
+	struct msm_display_topology topology;
+};
+
+int dpu_rm_init(struct drm_device *dev,
+		struct dpu_rm *rm,
+		const struct dpu_mdss_cfg *cat,
+		const struct msm_mdss_data *mdss_data,
+		void __iomem *mmio)
+{
+	int rc, i;
+
+	if (!rm || !cat || !mmio) {
+		DPU_ERROR("invalid kms\n");
+		return -EINVAL;
+	}
+
+	/* Clear, setup lists */
+	memset(rm, 0, sizeof(*rm));
+
+	/* Interrogate HW catalog and create tracking items for hw blocks */
+	for (i = 0; i < cat->mixer_count; i++) {
+		struct dpu_hw_mixer *hw;
+		const struct dpu_lm_cfg *lm = &cat->mixer[i];
+
+		hw = dpu_hw_lm_init(dev, lm, mmio);
+		if (IS_ERR(hw)) {
+			rc = PTR_ERR(hw);
+			DPU_ERROR("failed lm object creation: err %d\n", rc);
+			goto fail;
+		}
+		rm->mixer_blks[lm->id - LM_0] = &hw->base;
+	}
+
+	for (i = 0; i < cat->merge_3d_count; i++) {
+		struct dpu_hw_merge_3d *hw;
+		const struct dpu_merge_3d_cfg *merge_3d = &cat->merge_3d[i];
+
+		hw = dpu_hw_merge_3d_init(dev, merge_3d, mmio);
+		if (IS_ERR(hw)) {
+			rc = PTR_ERR(hw);
+			DPU_ERROR("failed merge_3d object creation: err %d\n",
+				rc);
+			goto fail;
+		}
+		rm->merge_3d_blks[merge_3d->id - MERGE_3D_0] = &hw->base;
+	}
+
+	for (i = 0; i < cat->pingpong_count; i++) {
+		struct dpu_hw_pingpong *hw;
+		const struct dpu_pingpong_cfg *pp = &cat->pingpong[i];
+
+		hw = dpu_hw_pingpong_init(dev, pp, mmio, cat->mdss_ver);
+		if (IS_ERR(hw)) {
+			rc = PTR_ERR(hw);
+			DPU_ERROR("failed pingpong object creation: err %d\n",
+				rc);
+			goto fail;
+		}
+		if (pp->merge_3d && pp->merge_3d < MERGE_3D_MAX)
+			hw->merge_3d = to_dpu_hw_merge_3d(rm->merge_3d_blks[pp->merge_3d - MERGE_3D_0]);
+		rm->pingpong_blks[pp->id - PINGPONG_0] = &hw->base;
+	}
+
+	for (i = 0; i < cat->intf_count; i++) {
+		struct dpu_hw_intf *hw;
+		const struct dpu_intf_cfg *intf = &cat->intf[i];
+
+		hw = dpu_hw_intf_init(dev, intf, mmio, cat->mdss_ver);
+		if (IS_ERR(hw)) {
+			rc = PTR_ERR(hw);
+			DPU_ERROR("failed intf object creation: err %d\n", rc);
+			goto fail;
+		}
+		rm->hw_intf[intf->id - INTF_0] = hw;
+	}
+
+	for (i = 0; i < cat->wb_count; i++) {
+		struct dpu_hw_wb *hw;
+		const struct dpu_wb_cfg *wb = &cat->wb[i];
+
+		hw = dpu_hw_wb_init(dev, wb, mmio, cat->mdss_ver);
+		if (IS_ERR(hw)) {
+			rc = PTR_ERR(hw);
+			DPU_ERROR("failed wb object creation: err %d\n", rc);
+			goto fail;
+		}
+		rm->hw_wb[wb->id - WB_0] = hw;
+	}
+
+	for (i = 0; i < cat->ctl_count; i++) {
+		struct dpu_hw_ctl *hw;
+		const struct dpu_ctl_cfg *ctl = &cat->ctl[i];
+
+		hw = dpu_hw_ctl_init(dev, ctl, mmio, cat->mixer_count, cat->mixer);
+		if (IS_ERR(hw)) {
+			rc = PTR_ERR(hw);
+			DPU_ERROR("failed ctl object creation: err %d\n", rc);
+			goto fail;
+		}
+		rm->ctl_blks[ctl->id - CTL_0] = &hw->base;
+	}
+
+	for (i = 0; i < cat->dspp_count; i++) {
+		struct dpu_hw_dspp *hw;
+		const struct dpu_dspp_cfg *dspp = &cat->dspp[i];
+
+		hw = dpu_hw_dspp_init(dev, dspp, mmio);
+		if (IS_ERR(hw)) {
+			rc = PTR_ERR(hw);
+			DPU_ERROR("failed dspp object creation: err %d\n", rc);
+			goto fail;
+		}
+		rm->dspp_blks[dspp->id - DSPP_0] = &hw->base;
+	}
+
+	for (i = 0; i < cat->dsc_count; i++) {
+		struct dpu_hw_dsc *hw;
+		const struct dpu_dsc_cfg *dsc = &cat->dsc[i];
+
+		if (test_bit(DPU_DSC_HW_REV_1_2, &dsc->features))
+			hw = dpu_hw_dsc_init_1_2(dev, dsc, mmio);
+		else
+			hw = dpu_hw_dsc_init(dev, dsc, mmio);
+
+		if (IS_ERR(hw)) {
+			rc = PTR_ERR(hw);
+			DPU_ERROR("failed dsc object creation: err %d\n", rc);
+			goto fail;
+		}
+		rm->dsc_blks[dsc->id - DSC_0] = &hw->base;
+	}
+
+	for (i = 0; i < cat->sspp_count; i++) {
+		struct dpu_hw_sspp *hw;
+		const struct dpu_sspp_cfg *sspp = &cat->sspp[i];
+
+		hw = dpu_hw_sspp_init(dev, sspp, mmio, mdss_data, cat->mdss_ver);
+		if (IS_ERR(hw)) {
+			rc = PTR_ERR(hw);
+			DPU_ERROR("failed sspp object creation: err %d\n", rc);
+			goto fail;
+		}
+		rm->hw_sspp[sspp->id - SSPP_NONE] = hw;
+	}
+
+	if (cat->cdm) {
+		struct dpu_hw_cdm *hw;
+
+		hw = dpu_hw_cdm_init(dev, cat->cdm, mmio, cat->mdss_ver);
+		if (IS_ERR(hw)) {
+			rc = PTR_ERR(hw);
+			DPU_ERROR("failed cdm object creation: err %d\n", rc);
+			goto fail;
+		}
+		rm->cdm_blk = &hw->base;
+	}
+
+	return 0;
+
+fail:
+	return rc ? rc : -EFAULT;
+}
+
+static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top)
+{
+	return top->num_intf > 1;
+}
+
+/**
+ * _dpu_rm_get_lm_peer - get the id of a mixer which is a peer of the primary
+ * @rm: dpu resource manager handle
+ * @primary_idx: index of primary mixer in rm->mixer_blks[]
+ *
+ * Returns: lm peer mixed id on success or %-EINVAL on error
+ */
+static int _dpu_rm_get_lm_peer(struct dpu_rm *rm, int primary_idx)
+{
+	const struct dpu_lm_cfg *prim_lm_cfg;
+
+	prim_lm_cfg = to_dpu_hw_mixer(rm->mixer_blks[primary_idx])->cap;
+
+	if (prim_lm_cfg->lm_pair >= LM_0 && prim_lm_cfg->lm_pair < LM_MAX)
+		return prim_lm_cfg->lm_pair - LM_0;
+	return -EINVAL;
+}
+
+/**
+ * _dpu_rm_check_lm_and_get_connected_blks - check if proposed layer mixer meets
+ *	proposed use case requirements, incl. hardwired dependent blocks like
+ *	pingpong
+ * @rm: dpu resource manager handle
+ * @global_state: resources shared across multiple kms objects
+ * @enc_id: encoder id requesting for allocation
+ * @lm_idx: index of proposed layer mixer in rm->mixer_blks[], function checks
+ *      if lm, and all other hardwired blocks connected to the lm (pp) is
+ *      available and appropriate
+ * @pp_idx: output parameter, index of pingpong block attached to the layer
+ *      mixer in rm->pingpong_blks[].
+ * @dspp_idx: output parameter, index of dspp block attached to the layer
+ *      mixer in rm->dspp_blks[].
+ * @reqs: input parameter, rm requirements for HW blocks needed in the
+ *      datapath.
+ * Return: true if lm matches all requirements, false otherwise
+ */
+static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
+		struct dpu_global_state *global_state,
+		uint32_t enc_id, int lm_idx, int *pp_idx, int *dspp_idx,
+		struct dpu_rm_requirements *reqs)
+{
+	const struct dpu_lm_cfg *lm_cfg;
+	int idx;
+
+	/* Already reserved? */
+	if (reserved_by_other(global_state->mixer_to_enc_id, lm_idx, enc_id)) {
+		DPU_DEBUG("lm %d already reserved\n", lm_idx + LM_0);
+		return false;
+	}
+
+	lm_cfg = to_dpu_hw_mixer(rm->mixer_blks[lm_idx])->cap;
+	idx = lm_cfg->pingpong - PINGPONG_0;
+	if (idx < 0 || idx >= ARRAY_SIZE(rm->pingpong_blks)) {
+		DPU_ERROR("failed to get pp on lm %d\n", lm_cfg->pingpong);
+		return false;
+	}
+
+	if (reserved_by_other(global_state->pingpong_to_enc_id, idx, enc_id)) {
+		DPU_DEBUG("lm %d pp %d already reserved\n", lm_cfg->id,
+				lm_cfg->pingpong);
+		return false;
+	}
+	*pp_idx = idx;
+
+	if (!reqs->topology.num_dspp)
+		return true;
+
+	idx = lm_cfg->dspp - DSPP_0;
+	if (idx < 0 || idx >= ARRAY_SIZE(rm->dspp_blks)) {
+		DPU_ERROR("failed to get dspp on lm %d\n", lm_cfg->dspp);
+		return false;
+	}
+
+	if (reserved_by_other(global_state->dspp_to_enc_id, idx, enc_id)) {
+		DPU_DEBUG("lm %d dspp %d already reserved\n", lm_cfg->id,
+				lm_cfg->dspp);
+		return false;
+	}
+	*dspp_idx = idx;
+
+	return true;
+}
+
+static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
+			       struct dpu_global_state *global_state,
+			       uint32_t enc_id,
+			       struct dpu_rm_requirements *reqs)
+
+{
+	int lm_idx[MAX_BLOCKS];
+	int pp_idx[MAX_BLOCKS];
+	int dspp_idx[MAX_BLOCKS] = {0};
+	int i, lm_count = 0;
+
+	if (!reqs->topology.num_lm) {
+		DPU_ERROR("invalid number of lm: %d\n", reqs->topology.num_lm);
+		return -EINVAL;
+	}
+
+	/* Find a primary mixer */
+	for (i = 0; i < ARRAY_SIZE(rm->mixer_blks) &&
+			lm_count < reqs->topology.num_lm; i++) {
+		if (!rm->mixer_blks[i])
+			continue;
+
+		lm_count = 0;
+		lm_idx[lm_count] = i;
+
+		if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state,
+				enc_id, i, &pp_idx[lm_count],
+				&dspp_idx[lm_count], reqs)) {
+			continue;
+		}
+
+		++lm_count;
+
+		/* Valid primary mixer found, find matching peers */
+		if (lm_count < reqs->topology.num_lm) {
+			int j = _dpu_rm_get_lm_peer(rm, i);
+
+			/* ignore the peer if there is an error or if the peer was already processed */
+			if (j < 0 || j < i)
+				continue;
+
+			if (!rm->mixer_blks[j])
+				continue;
+
+			if (!_dpu_rm_check_lm_and_get_connected_blks(rm,
+					global_state, enc_id, j,
+					&pp_idx[lm_count], &dspp_idx[lm_count],
+					reqs)) {
+				continue;
+			}
+
+			lm_idx[lm_count] = j;
+			++lm_count;
+		}
+	}
+
+	if (lm_count != reqs->topology.num_lm) {
+		DPU_DEBUG("unable to find appropriate mixers\n");
+		return -ENAVAIL;
+	}
+
+	for (i = 0; i < lm_count; i++) {
+		global_state->mixer_to_enc_id[lm_idx[i]] = enc_id;
+		global_state->pingpong_to_enc_id[pp_idx[i]] = enc_id;
+		global_state->dspp_to_enc_id[dspp_idx[i]] =
+			reqs->topology.num_dspp ? enc_id : 0;
+
+		trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, enc_id,
+					 pp_idx[i] + PINGPONG_0);
+	}
+
+	return 0;
+}
+
+static int _dpu_rm_reserve_ctls(
+		struct dpu_rm *rm,
+		struct dpu_global_state *global_state,
+		uint32_t enc_id,
+		const struct msm_display_topology *top)
+{
+	int ctl_idx[MAX_BLOCKS];
+	int i = 0, j, num_ctls;
+	bool needs_split_display;
+
+	/* each hw_intf needs its own hw_ctrl to program its control path */
+	num_ctls = top->num_intf;
+
+	needs_split_display = _dpu_rm_needs_split_display(top);
+
+	for (j = 0; j < ARRAY_SIZE(rm->ctl_blks); j++) {
+		const struct dpu_hw_ctl *ctl;
+		unsigned long features;
+		bool has_split_display;
+
+		if (!rm->ctl_blks[j])
+			continue;
+		if (reserved_by_other(global_state->ctl_to_enc_id, j, enc_id))
+			continue;
+
+		ctl = to_dpu_hw_ctl(rm->ctl_blks[j]);
+		features = ctl->caps->features;
+		has_split_display = BIT(DPU_CTL_SPLIT_DISPLAY) & features;
+
+		DPU_DEBUG("ctl %d caps 0x%lX\n", j + CTL_0, features);
+
+		if (needs_split_display != has_split_display)
+			continue;
+
+		ctl_idx[i] = j;
+		DPU_DEBUG("ctl %d match\n", j + CTL_0);
+
+		if (++i == num_ctls)
+			break;
+
+	}
+
+	if (i != num_ctls)
+		return -ENAVAIL;
+
+	for (i = 0; i < ARRAY_SIZE(ctl_idx) && i < num_ctls; i++) {
+		global_state->ctl_to_enc_id[ctl_idx[i]] = enc_id;
+		trace_dpu_rm_reserve_ctls(i + CTL_0, enc_id);
+	}
+
+	return 0;
+}
+
+static int _dpu_rm_reserve_dsc(struct dpu_rm *rm,
+			       struct dpu_global_state *global_state,
+			       struct drm_encoder *enc,
+			       const struct msm_display_topology *top)
+{
+	int num_dsc = top->num_dsc;
+	int i;
+
+	/* check if DSC required are allocated or not */
+	for (i = 0; i < num_dsc; i++) {
+		if (!rm->dsc_blks[i]) {
+			DPU_ERROR("DSC %d does not exist\n", i);
+			return -EIO;
+		}
+
+		if (global_state->dsc_to_enc_id[i]) {
+			DPU_ERROR("DSC %d is already allocated\n", i);
+			return -EIO;
+		}
+	}
+
+	for (i = 0; i < num_dsc; i++)
+		global_state->dsc_to_enc_id[i] = enc->base.id;
+
+	return 0;
+}
+
+static int _dpu_rm_reserve_cdm(struct dpu_rm *rm,
+			       struct dpu_global_state *global_state,
+			       struct drm_encoder *enc)
+{
+	/* try allocating only one CDM block */
+	if (!rm->cdm_blk) {
+		DPU_ERROR("CDM block does not exist\n");
+		return -EIO;
+	}
+
+	if (global_state->cdm_to_enc_id) {
+		DPU_ERROR("CDM_0 is already allocated\n");
+		return -EIO;
+	}
+
+	global_state->cdm_to_enc_id = enc->base.id;
+
+	return 0;
+}
+
+static int _dpu_rm_make_reservation(
+		struct dpu_rm *rm,
+		struct dpu_global_state *global_state,
+		struct drm_encoder *enc,
+		struct dpu_rm_requirements *reqs)
+{
+	int ret;
+
+	ret = _dpu_rm_reserve_lms(rm, global_state, enc->base.id, reqs);
+	if (ret) {
+		DPU_ERROR("unable to find appropriate mixers\n");
+		return ret;
+	}
+
+	ret = _dpu_rm_reserve_ctls(rm, global_state, enc->base.id,
+				&reqs->topology);
+	if (ret) {
+		DPU_ERROR("unable to find appropriate CTL\n");
+		return ret;
+	}
+
+	ret  = _dpu_rm_reserve_dsc(rm, global_state, enc, &reqs->topology);
+	if (ret)
+		return ret;
+
+	if (reqs->topology.needs_cdm) {
+		ret = _dpu_rm_reserve_cdm(rm, global_state, enc);
+		if (ret) {
+			DPU_ERROR("unable to find CDM blk\n");
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+static int _dpu_rm_populate_requirements(
+		struct drm_encoder *enc,
+		struct dpu_rm_requirements *reqs,
+		struct msm_display_topology req_topology)
+{
+	reqs->topology = req_topology;
+
+	DRM_DEBUG_KMS("num_lm: %d num_dsc: %d num_intf: %d cdm: %d\n",
+		      reqs->topology.num_lm, reqs->topology.num_dsc,
+		      reqs->topology.num_intf, reqs->topology.needs_cdm);
+
+	return 0;
+}
+
+static void _dpu_rm_clear_mapping(uint32_t *res_mapping, int cnt,
+				  uint32_t enc_id)
+{
+	int i;
+
+	for (i = 0; i < cnt; i++) {
+		if (res_mapping[i] == enc_id)
+			res_mapping[i] = 0;
+	}
+}
+
+void dpu_rm_release(struct dpu_global_state *global_state,
+		    struct drm_encoder *enc)
+{
+	_dpu_rm_clear_mapping(global_state->pingpong_to_enc_id,
+		ARRAY_SIZE(global_state->pingpong_to_enc_id), enc->base.id);
+	_dpu_rm_clear_mapping(global_state->mixer_to_enc_id,
+		ARRAY_SIZE(global_state->mixer_to_enc_id), enc->base.id);
+	_dpu_rm_clear_mapping(global_state->ctl_to_enc_id,
+		ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id);
+	_dpu_rm_clear_mapping(global_state->dsc_to_enc_id,
+		ARRAY_SIZE(global_state->dsc_to_enc_id), enc->base.id);
+	_dpu_rm_clear_mapping(global_state->dspp_to_enc_id,
+		ARRAY_SIZE(global_state->dspp_to_enc_id), enc->base.id);
+	_dpu_rm_clear_mapping(&global_state->cdm_to_enc_id, 1, enc->base.id);
+}
+
+int dpu_rm_reserve(
+		struct dpu_rm *rm,
+		struct dpu_global_state *global_state,
+		struct drm_encoder *enc,
+		struct drm_crtc_state *crtc_state,
+		struct msm_display_topology topology)
+{
+	struct dpu_rm_requirements reqs;
+	int ret;
+
+	/* Check if this is just a page-flip */
+	if (!drm_atomic_crtc_needs_modeset(crtc_state))
+		return 0;
+
+	if (IS_ERR(global_state)) {
+		DPU_ERROR("failed to global state\n");
+		return PTR_ERR(global_state);
+	}
+
+	DRM_DEBUG_KMS("reserving hw for enc %d crtc %d\n",
+		      enc->base.id, crtc_state->crtc->base.id);
+
+	ret = _dpu_rm_populate_requirements(enc, &reqs, topology);
+	if (ret) {
+		DPU_ERROR("failed to populate hw requirements\n");
+		return ret;
+	}
+
+	ret = _dpu_rm_make_reservation(rm, global_state, enc, &reqs);
+	if (ret)
+		DPU_ERROR("failed to reserve hw resources: %d\n", ret);
+
+
+
+	return ret;
+}
+
+int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
+	struct dpu_global_state *global_state, uint32_t enc_id,
+	enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size)
+{
+	struct dpu_hw_blk **hw_blks;
+	uint32_t *hw_to_enc_id;
+	int i, num_blks, max_blks;
+
+	switch (type) {
+	case DPU_HW_BLK_PINGPONG:
+		hw_blks = rm->pingpong_blks;
+		hw_to_enc_id = global_state->pingpong_to_enc_id;
+		max_blks = ARRAY_SIZE(rm->pingpong_blks);
+		break;
+	case DPU_HW_BLK_LM:
+		hw_blks = rm->mixer_blks;
+		hw_to_enc_id = global_state->mixer_to_enc_id;
+		max_blks = ARRAY_SIZE(rm->mixer_blks);
+		break;
+	case DPU_HW_BLK_CTL:
+		hw_blks = rm->ctl_blks;
+		hw_to_enc_id = global_state->ctl_to_enc_id;
+		max_blks = ARRAY_SIZE(rm->ctl_blks);
+		break;
+	case DPU_HW_BLK_DSPP:
+		hw_blks = rm->dspp_blks;
+		hw_to_enc_id = global_state->dspp_to_enc_id;
+		max_blks = ARRAY_SIZE(rm->dspp_blks);
+		break;
+	case DPU_HW_BLK_DSC:
+		hw_blks = rm->dsc_blks;
+		hw_to_enc_id = global_state->dsc_to_enc_id;
+		max_blks = ARRAY_SIZE(rm->dsc_blks);
+		break;
+	case DPU_HW_BLK_CDM:
+		hw_blks = &rm->cdm_blk;
+		hw_to_enc_id = &global_state->cdm_to_enc_id;
+		max_blks = 1;
+		break;
+	default:
+		DPU_ERROR("blk type %d not managed by rm\n", type);
+		return 0;
+	}
+
+	num_blks = 0;
+	for (i = 0; i < max_blks; i++) {
+		if (hw_to_enc_id[i] != enc_id)
+			continue;
+
+		if (num_blks == blks_size) {
+			DPU_ERROR("More than %d resources assigned to enc %d\n",
+				  blks_size, enc_id);
+			break;
+		}
+		if (!hw_blks[i]) {
+			DPU_ERROR("Allocated resource %d unavailable to assign to enc %d\n",
+				  type, enc_id);
+			break;
+		}
+		blks[num_blks++] = hw_blks[i];
+	}
+
+	return num_blks;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_rm.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_rm.h
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __DPU_RM_H__
+#define __DPU_RM_H__
+
+#include <linux/list.h>
+
+#include "msm_kms.h"
+#include "dpu_hw_top.h"
+
+struct dpu_global_state;
+
+/**
+ * struct dpu_rm - DPU dynamic hardware resource manager
+ * @pingpong_blks: array of pingpong hardware resources
+ * @mixer_blks: array of layer mixer hardware resources
+ * @ctl_blks: array of ctl hardware resources
+ * @hw_intf: array of intf hardware resources
+ * @hw_wb: array of wb hardware resources
+ * @dspp_blks: array of dspp hardware resources
+ * @hw_sspp: array of sspp hardware resources
+ * @cdm_blk: cdm hardware resource
+ */
+struct dpu_rm {
+	struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
+	struct dpu_hw_blk *mixer_blks[LM_MAX - LM_0];
+	struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0];
+	struct dpu_hw_intf *hw_intf[INTF_MAX - INTF_0];
+	struct dpu_hw_wb *hw_wb[WB_MAX - WB_0];
+	struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0];
+	struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0];
+	struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0];
+	struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE];
+	struct dpu_hw_blk *cdm_blk;
+};
+
+/**
+ * dpu_rm_init - Read hardware catalog and create reservation tracking objects
+ *	for all HW blocks.
+ * @dev:  Corresponding device for devres management
+ * @rm: DPU Resource Manager handle
+ * @cat: Pointer to hardware catalog
+ * @mdss_data: Pointer to MDSS / UBWC configuration
+ * @mmio: mapped register io address of MDP
+ * @Return: 0 on Success otherwise -ERROR
+ */
+int dpu_rm_init(struct drm_device *dev,
+		struct dpu_rm *rm,
+		const struct dpu_mdss_cfg *cat,
+		const struct msm_mdss_data *mdss_data,
+		void __iomem *mmio);
+
+/**
+ * dpu_rm_reserve - Given a CRTC->Encoder->Connector display chain, analyze
+ *	the use connections and user requirements, specified through related
+ *	topology control properties, and reserve hardware blocks to that
+ *	display chain.
+ *	HW blocks can then be accessed through dpu_rm_get_* functions.
+ *	HW Reservations should be released via dpu_rm_release_hw.
+ * @rm: DPU Resource Manager handle
+ * @drm_enc: DRM Encoder handle
+ * @crtc_state: Proposed Atomic DRM CRTC State handle
+ * @topology: Pointer to topology info for the display
+ * @Return: 0 on Success otherwise -ERROR
+ */
+int dpu_rm_reserve(struct dpu_rm *rm,
+		struct dpu_global_state *global_state,
+		struct drm_encoder *drm_enc,
+		struct drm_crtc_state *crtc_state,
+		struct msm_display_topology topology);
+
+/**
+ * dpu_rm_reserve - Given the encoder for the display chain, release any
+ *	HW blocks previously reserved for that use case.
+ * @rm: DPU Resource Manager handle
+ * @enc: DRM Encoder handle
+ * @Return: 0 on Success otherwise -ERROR
+ */
+void dpu_rm_release(struct dpu_global_state *global_state,
+		struct drm_encoder *enc);
+
+/**
+ * Get hw resources of the given type that are assigned to this encoder.
+ */
+int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
+	struct dpu_global_state *global_state, uint32_t enc_id,
+	enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size);
+
+/**
+ * dpu_rm_get_intf - Return a struct dpu_hw_intf instance given it's index.
+ * @rm: DPU Resource Manager handle
+ * @intf_idx: INTF's index
+ */
+static inline struct dpu_hw_intf *dpu_rm_get_intf(struct dpu_rm *rm, enum dpu_intf intf_idx)
+{
+	return rm->hw_intf[intf_idx - INTF_0];
+}
+
+/**
+ * dpu_rm_get_wb - Return a struct dpu_hw_wb instance given it's index.
+ * @rm: DPU Resource Manager handle
+ * @wb_idx: WB index
+ */
+static inline struct dpu_hw_wb *dpu_rm_get_wb(struct dpu_rm *rm, enum dpu_wb wb_idx)
+{
+	return rm->hw_wb[wb_idx - WB_0];
+}
+
+/**
+ * dpu_rm_get_sspp - Return a struct dpu_hw_sspp instance given it's index.
+ * @rm: DPU Resource Manager handle
+ * @sspp_idx: SSPP index
+ */
+static inline struct dpu_hw_sspp *dpu_rm_get_sspp(struct dpu_rm *rm, enum dpu_sspp sspp_idx)
+{
+	return rm->hw_sspp[sspp_idx - SSPP_NONE];
+}
+
+#endif /* __DPU_RM_H__ */
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_trace.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_trace.h
@@ -0,0 +1,974 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ */
+
+#if !defined(_DPU_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
+#define _DPU_TRACE_H_
+
+#include <linux/stringify.h>
+#include <linux/types.h>
+#include <linux/tracepoint.h>
+
+#include <drm/drm_rect.h>
+#include "dpu_crtc.h"
+#include "dpu_encoder_phys.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_vbif.h"
+#include "dpu_plane.h"
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM dpu
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE dpu_trace
+
+TRACE_EVENT(dpu_perf_set_qos_luts,
+	TP_PROTO(u32 pnum, u32 fmt, bool rt, u32 fl,
+		u32 lut, u32 lut_usage),
+	TP_ARGS(pnum, fmt, rt, fl, lut, lut_usage),
+	TP_STRUCT__entry(
+			__field(u32, pnum)
+			__field(u32, fmt)
+			__field(bool, rt)
+			__field(u32, fl)
+			__field(u64, lut)
+			__field(u32, lut_usage)
+	),
+	TP_fast_assign(
+			__entry->pnum = pnum;
+			__entry->fmt = fmt;
+			__entry->rt = rt;
+			__entry->fl = fl;
+			__entry->lut = lut;
+			__entry->lut_usage = lut_usage;
+	),
+	TP_printk("pnum=%d fmt=%x rt=%d fl=%d lut=0x%llx lut_usage=%d",
+			__entry->pnum, __entry->fmt,
+			__entry->rt, __entry->fl,
+			__entry->lut, __entry->lut_usage)
+);
+
+TRACE_EVENT(dpu_perf_set_danger_luts,
+	TP_PROTO(u32 pnum, u32 fmt, u32 mode, u32 danger_lut,
+		u32 safe_lut),
+	TP_ARGS(pnum, fmt, mode, danger_lut, safe_lut),
+	TP_STRUCT__entry(
+			__field(u32, pnum)
+			__field(u32, fmt)
+			__field(u32, mode)
+			__field(u32, danger_lut)
+			__field(u32, safe_lut)
+	),
+	TP_fast_assign(
+			__entry->pnum = pnum;
+			__entry->fmt = fmt;
+			__entry->mode = mode;
+			__entry->danger_lut = danger_lut;
+			__entry->safe_lut = safe_lut;
+	),
+	TP_printk("pnum=%d fmt=%x mode=%d luts[0x%x, 0x%x]",
+			__entry->pnum, __entry->fmt,
+			__entry->mode, __entry->danger_lut,
+			__entry->safe_lut)
+);
+
+TRACE_EVENT(dpu_perf_set_ot,
+	TP_PROTO(u32 pnum, u32 xin_id, u32 rd_lim, u32 vbif_idx),
+	TP_ARGS(pnum, xin_id, rd_lim, vbif_idx),
+	TP_STRUCT__entry(
+			__field(u32, pnum)
+			__field(u32, xin_id)
+			__field(u32, rd_lim)
+			__field(u32, vbif_idx)
+	),
+	TP_fast_assign(
+			__entry->pnum = pnum;
+			__entry->xin_id = xin_id;
+			__entry->rd_lim = rd_lim;
+			__entry->vbif_idx = vbif_idx;
+	),
+	TP_printk("pnum:%d xin_id:%d ot:%d vbif:%d",
+			__entry->pnum, __entry->xin_id, __entry->rd_lim,
+			__entry->vbif_idx)
+)
+
+TRACE_EVENT(dpu_cmd_release_bw,
+	TP_PROTO(u32 crtc_id),
+	TP_ARGS(crtc_id),
+	TP_STRUCT__entry(
+			__field(u32, crtc_id)
+	),
+	TP_fast_assign(
+			__entry->crtc_id = crtc_id;
+	),
+	TP_printk("crtc:%d", __entry->crtc_id)
+);
+
+TRACE_EVENT(tracing_mark_write,
+	TP_PROTO(int pid, const char *name, bool trace_begin),
+	TP_ARGS(pid, name, trace_begin),
+	TP_STRUCT__entry(
+			__field(int, pid)
+			__string(trace_name, name)
+			__field(bool, trace_begin)
+	),
+	TP_fast_assign(
+			__entry->pid = pid;
+			__assign_str(trace_name, name);
+			__entry->trace_begin = trace_begin;
+	),
+	TP_printk("%s|%d|%s", __entry->trace_begin ? "B" : "E",
+		__entry->pid, __get_str(trace_name))
+)
+
+TRACE_EVENT(dpu_trace_counter,
+	TP_PROTO(int pid, char *name, int value),
+	TP_ARGS(pid, name, value),
+	TP_STRUCT__entry(
+			__field(int, pid)
+			__string(counter_name, name)
+			__field(int, value)
+	),
+	TP_fast_assign(
+			__entry->pid = current->tgid;
+			__assign_str(counter_name, name);
+			__entry->value = value;
+	),
+	TP_printk("%d|%s|%d", __entry->pid,
+			__get_str(counter_name), __entry->value)
+)
+
+TRACE_EVENT(dpu_perf_crtc_update,
+	TP_PROTO(u32 crtc, u64 bw_ctl, u32 core_clk_rate,
+			bool stop_req, bool update_bus, bool update_clk),
+	TP_ARGS(crtc, bw_ctl, core_clk_rate, stop_req, update_bus, update_clk),
+	TP_STRUCT__entry(
+			__field(u32, crtc)
+			__field(u64, bw_ctl)
+			__field(u32, core_clk_rate)
+			__field(bool, stop_req)
+			__field(u32, update_bus)
+			__field(u32, update_clk)
+	),
+	TP_fast_assign(
+			__entry->crtc = crtc;
+			__entry->bw_ctl = bw_ctl;
+			__entry->core_clk_rate = core_clk_rate;
+			__entry->stop_req = stop_req;
+			__entry->update_bus = update_bus;
+			__entry->update_clk = update_clk;
+	),
+	 TP_printk(
+		"crtc=%d bw_ctl=%llu clk_rate=%u stop_req=%d u_bus=%d u_clk=%d",
+			__entry->crtc,
+			__entry->bw_ctl,
+			__entry->core_clk_rate,
+			__entry->stop_req,
+			__entry->update_bus,
+			__entry->update_clk)
+);
+
+DECLARE_EVENT_CLASS(dpu_irq_template,
+	TP_PROTO(unsigned int irq_reg, unsigned int irq_bit),
+	TP_ARGS(irq_reg, irq_bit),
+	TP_STRUCT__entry(
+		__field(	unsigned int,		irq_reg		)
+		__field(	unsigned int,		irq_bit		)
+	),
+	TP_fast_assign(
+		__entry->irq_reg = irq_reg;
+		__entry->irq_bit = irq_bit;
+	),
+	TP_printk("IRQ=[%d, %d]", __entry->irq_reg, __entry->irq_bit)
+);
+DEFINE_EVENT(dpu_irq_template, dpu_irq_register_success,
+	TP_PROTO(unsigned int irq_reg, unsigned int irq_bit),
+	TP_ARGS(irq_reg, irq_bit)
+);
+DEFINE_EVENT(dpu_irq_template, dpu_irq_unregister_success,
+	TP_PROTO(unsigned int irq_reg, unsigned int irq_bit),
+	TP_ARGS(irq_reg, irq_bit)
+);
+
+TRACE_EVENT(dpu_enc_irq_wait_success,
+	TP_PROTO(uint32_t drm_id, void *func,
+		 unsigned int irq_reg, unsigned int irq_bit, enum dpu_pingpong pp_idx, int atomic_cnt),
+	TP_ARGS(drm_id, func, irq_reg, irq_bit, pp_idx, atomic_cnt),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		drm_id		)
+		__field(	void *,			func		)
+		__field(	unsigned int,		irq_reg		)
+		__field(	unsigned int,		irq_bit		)
+		__field(	enum dpu_pingpong,	pp_idx		)
+		__field(	int,			atomic_cnt	)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->func = func;
+		__entry->irq_reg = irq_reg;
+		__entry->irq_bit = irq_bit;
+		__entry->pp_idx = pp_idx;
+		__entry->atomic_cnt = atomic_cnt;
+	),
+	TP_printk("id=%u, callback=%ps, IRQ=[%d, %d], pp=%d, atomic_cnt=%d",
+		  __entry->drm_id, __entry->func,
+		  __entry->irq_reg, __entry->irq_bit, __entry->pp_idx, __entry->atomic_cnt)
+);
+
+DECLARE_EVENT_CLASS(dpu_drm_obj_template,
+	TP_PROTO(uint32_t drm_id),
+	TP_ARGS(drm_id),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		drm_id		)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+	),
+	TP_printk("id=%u", __entry->drm_id)
+);
+DEFINE_EVENT(dpu_drm_obj_template, dpu_enc_atomic_check,
+	TP_PROTO(uint32_t drm_id),
+	TP_ARGS(drm_id)
+);
+DEFINE_EVENT(dpu_drm_obj_template, dpu_enc_mode_set,
+	TP_PROTO(uint32_t drm_id),
+	TP_ARGS(drm_id)
+);
+DEFINE_EVENT(dpu_drm_obj_template, dpu_enc_disable,
+	TP_PROTO(uint32_t drm_id),
+	TP_ARGS(drm_id)
+);
+DEFINE_EVENT(dpu_drm_obj_template, dpu_enc_kickoff,
+	TP_PROTO(uint32_t drm_id),
+	TP_ARGS(drm_id)
+);
+DEFINE_EVENT(dpu_drm_obj_template, dpu_enc_prepare_kickoff,
+	TP_PROTO(uint32_t drm_id),
+	TP_ARGS(drm_id)
+);
+DEFINE_EVENT(dpu_drm_obj_template, dpu_enc_prepare_kickoff_reset,
+	TP_PROTO(uint32_t drm_id),
+	TP_ARGS(drm_id)
+);
+DEFINE_EVENT(dpu_drm_obj_template, dpu_crtc_complete_flip,
+	TP_PROTO(uint32_t drm_id),
+	TP_ARGS(drm_id)
+);
+DEFINE_EVENT(dpu_drm_obj_template, dpu_crtc_vblank_cb,
+	TP_PROTO(uint32_t drm_id),
+	TP_ARGS(drm_id)
+);
+DEFINE_EVENT(dpu_drm_obj_template, dpu_crtc_complete_commit,
+	TP_PROTO(uint32_t drm_id),
+	TP_ARGS(drm_id)
+);
+DEFINE_EVENT(dpu_drm_obj_template, dpu_kms_commit,
+	TP_PROTO(uint32_t drm_id),
+	TP_ARGS(drm_id)
+);
+DEFINE_EVENT(dpu_drm_obj_template, dpu_kms_wait_for_commit_done,
+	TP_PROTO(uint32_t drm_id),
+	TP_ARGS(drm_id)
+);
+DEFINE_EVENT(dpu_drm_obj_template, dpu_crtc_runtime_resume,
+	TP_PROTO(uint32_t drm_id),
+	TP_ARGS(drm_id)
+);
+
+TRACE_EVENT(dpu_enc_enable,
+	TP_PROTO(uint32_t drm_id, int hdisplay, int vdisplay),
+	TP_ARGS(drm_id, hdisplay, vdisplay),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		drm_id		)
+		__field(	int,			hdisplay	)
+		__field(	int,			vdisplay	)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->hdisplay = hdisplay;
+		__entry->vdisplay = vdisplay;
+	),
+	TP_printk("id=%u, mode=%dx%d",
+		  __entry->drm_id, __entry->hdisplay, __entry->vdisplay)
+);
+
+DECLARE_EVENT_CLASS(dpu_enc_keyval_template,
+	TP_PROTO(uint32_t drm_id, int val),
+	TP_ARGS(drm_id, val),
+	TP_STRUCT__entry(
+		__field(	uint32_t,	drm_id	)
+		__field(	int,		val	)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->val = val;
+	),
+	TP_printk("id=%u, val=%d", __entry->drm_id, __entry->val)
+);
+DEFINE_EVENT(dpu_enc_keyval_template, dpu_enc_underrun_cb,
+	TP_PROTO(uint32_t drm_id, int count),
+	TP_ARGS(drm_id, count)
+);
+DEFINE_EVENT(dpu_enc_keyval_template, dpu_enc_trigger_start,
+	TP_PROTO(uint32_t drm_id, int ctl_idx),
+	TP_ARGS(drm_id, ctl_idx)
+);
+
+TRACE_EVENT(dpu_enc_atomic_check_flags,
+	TP_PROTO(uint32_t drm_id, unsigned int flags),
+	TP_ARGS(drm_id, flags),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		drm_id		)
+		__field(	unsigned int,		flags		)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->flags = flags;
+	),
+	TP_printk("id=%u, flags=%u",
+		  __entry->drm_id, __entry->flags)
+);
+
+DECLARE_EVENT_CLASS(dpu_enc_id_enable_template,
+	TP_PROTO(uint32_t drm_id, bool enable),
+	TP_ARGS(drm_id, enable),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		drm_id		)
+		__field(	bool,			enable		)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->enable = enable;
+	),
+	TP_printk("id=%u, enable=%s",
+		  __entry->drm_id, __entry->enable ? "true" : "false")
+);
+DEFINE_EVENT(dpu_enc_id_enable_template, dpu_enc_rc_helper,
+	TP_PROTO(uint32_t drm_id, bool enable),
+	TP_ARGS(drm_id, enable)
+);
+DEFINE_EVENT(dpu_enc_id_enable_template, dpu_enc_vblank_cb,
+	TP_PROTO(uint32_t drm_id, bool enable),
+	TP_ARGS(drm_id, enable)
+);
+DEFINE_EVENT(dpu_enc_id_enable_template, dpu_enc_phys_cmd_connect_te,
+	TP_PROTO(uint32_t drm_id, bool enable),
+	TP_ARGS(drm_id, enable)
+);
+
+TRACE_EVENT(dpu_enc_rc,
+	TP_PROTO(uint32_t drm_id, u32 sw_event, bool idle_pc_supported,
+		 int rc_state, const char *stage),
+	TP_ARGS(drm_id, sw_event, idle_pc_supported, rc_state, stage),
+	TP_STRUCT__entry(
+		__field(	uint32_t,	drm_id			)
+		__field(	u32,		sw_event		)
+		__field(	bool,		idle_pc_supported	)
+		__field(	int,		rc_state		)
+		__string(	stage_str,	stage			)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->sw_event = sw_event;
+		__entry->idle_pc_supported = idle_pc_supported;
+		__entry->rc_state = rc_state;
+		__assign_str(stage_str, stage);
+	),
+	TP_printk("%s: id:%u, sw_event:%d, idle_pc_supported:%s, rc_state:%d",
+		  __get_str(stage_str), __entry->drm_id, __entry->sw_event,
+		  __entry->idle_pc_supported ? "true" : "false",
+		  __entry->rc_state)
+);
+
+TRACE_EVENT(dpu_enc_frame_done_cb_not_busy,
+	TP_PROTO(uint32_t drm_id, u32 event, char *intf_mode, enum dpu_intf intf_idx,
+			enum dpu_wb wb_idx),
+	TP_ARGS(drm_id, event, intf_mode, intf_idx, wb_idx),
+	TP_STRUCT__entry(
+		__field(	uint32_t,	drm_id		)
+		__field(	u32,		event		)
+		__string(	intf_mode_str,	intf_mode	)
+		__field(	enum dpu_intf,	intf_idx	)
+		__field(	enum dpu_wb,	wb_idx		)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->event = event;
+		__assign_str(intf_mode_str, intf_mode);
+		__entry->intf_idx = intf_idx;
+		__entry->wb_idx = wb_idx;
+	),
+	TP_printk("id=%u, event=%u, intf_mode=%s intf=%d wb=%d", __entry->drm_id,
+			__entry->event, __get_str(intf_mode_str),
+			__entry->intf_idx, __entry->wb_idx)
+);
+
+TRACE_EVENT(dpu_enc_frame_done_cb,
+	TP_PROTO(uint32_t drm_id, unsigned int idx,
+		 unsigned long frame_busy_mask),
+	TP_ARGS(drm_id, idx, frame_busy_mask),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		drm_id		)
+		__field(	unsigned int,		idx		)
+		__field(	unsigned long,		frame_busy_mask	)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->idx = idx;
+		__entry->frame_busy_mask = frame_busy_mask;
+	),
+	TP_printk("id=%u, idx=%u, frame_busy_mask=%lx", __entry->drm_id,
+		  __entry->idx, __entry->frame_busy_mask)
+);
+
+TRACE_EVENT(dpu_enc_trigger_flush,
+	TP_PROTO(uint32_t drm_id, char *intf_mode, enum dpu_intf intf_idx, enum dpu_wb wb_idx,
+		 int pending_kickoff_cnt, int ctl_idx, u32 extra_flush_bits,
+		 u32 pending_flush_ret),
+	TP_ARGS(drm_id, intf_mode, intf_idx, wb_idx, pending_kickoff_cnt, ctl_idx,
+		extra_flush_bits, pending_flush_ret),
+	TP_STRUCT__entry(
+		__field(	uint32_t,	drm_id			)
+		__string(	intf_mode_str,	intf_mode		)
+		__field(	enum dpu_intf,	intf_idx		)
+		__field(	enum dpu_wb,	wb_idx			)
+		__field(	int,		pending_kickoff_cnt	)
+		__field(	int,		ctl_idx			)
+		__field(	u32,		extra_flush_bits	)
+		__field(	u32,		pending_flush_ret	)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__assign_str(intf_mode_str, intf_mode);
+		__entry->intf_idx = intf_idx;
+		__entry->wb_idx = wb_idx;
+		__entry->pending_kickoff_cnt = pending_kickoff_cnt;
+		__entry->ctl_idx = ctl_idx;
+		__entry->extra_flush_bits = extra_flush_bits;
+		__entry->pending_flush_ret = pending_flush_ret;
+	),
+	TP_printk("id=%u, intf_mode=%s, intf_idx=%d, wb_idx=%d, pending_kickoff_cnt=%d ctl_idx=%d "
+		  "extra_flush_bits=0x%x pending_flush_ret=0x%x",
+		  __entry->drm_id, __get_str(intf_mode_str), __entry->intf_idx, __entry->wb_idx,
+		  __entry->pending_kickoff_cnt, __entry->ctl_idx,
+		  __entry->extra_flush_bits, __entry->pending_flush_ret)
+);
+
+DECLARE_EVENT_CLASS(dpu_id_event_template,
+	TP_PROTO(uint32_t drm_id, u32 event),
+	TP_ARGS(drm_id, event),
+	TP_STRUCT__entry(
+		__field(	uint32_t,	drm_id	)
+		__field(	u32,		event	)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->event = event;
+	),
+	TP_printk("id=%u, event=%u", __entry->drm_id, __entry->event)
+);
+DEFINE_EVENT(dpu_id_event_template, dpu_enc_frame_done_timeout,
+	TP_PROTO(uint32_t drm_id, u32 event),
+	TP_ARGS(drm_id, event)
+);
+DEFINE_EVENT(dpu_id_event_template, dpu_crtc_frame_event_cb,
+	TP_PROTO(uint32_t drm_id, u32 event),
+	TP_ARGS(drm_id, event)
+);
+DEFINE_EVENT(dpu_id_event_template, dpu_crtc_frame_event_done,
+	TP_PROTO(uint32_t drm_id, u32 event),
+	TP_ARGS(drm_id, event)
+);
+DEFINE_EVENT(dpu_id_event_template, dpu_crtc_frame_event_more_pending,
+	TP_PROTO(uint32_t drm_id, u32 event),
+	TP_ARGS(drm_id, event)
+);
+
+TRACE_EVENT(dpu_enc_wait_event_timeout,
+	TP_PROTO(uint32_t drm_id, unsigned int irq_reg, unsigned int irq_bit, int rc, s64 time,
+		 s64 expected_time, int atomic_cnt),
+	TP_ARGS(drm_id, irq_reg, irq_bit, rc, time, expected_time, atomic_cnt),
+	TP_STRUCT__entry(
+		__field(	uint32_t,	drm_id		)
+		__field(	unsigned int,	irq_reg		)
+		__field(	unsigned int,	irq_bit		)
+		__field(	int,		rc		)
+		__field(	s64,		time		)
+		__field(	s64,		expected_time	)
+		__field(	int,		atomic_cnt	)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->irq_reg = irq_reg;
+		__entry->irq_bit = irq_bit;
+		__entry->rc = rc;
+		__entry->time = time;
+		__entry->expected_time = expected_time;
+		__entry->atomic_cnt = atomic_cnt;
+	),
+	TP_printk("id=%u, IRQ=[%d, %d], rc=%d, time=%lld, expected=%lld cnt=%d",
+		  __entry->drm_id, __entry->irq_reg, __entry->irq_bit, __entry->rc, __entry->time,
+		  __entry->expected_time, __entry->atomic_cnt)
+);
+
+TRACE_EVENT(dpu_enc_phys_cmd_irq_ctrl,
+	TP_PROTO(uint32_t drm_id, enum dpu_pingpong pp, bool enable,
+		 int refcnt),
+	TP_ARGS(drm_id, pp, enable, refcnt),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		drm_id	)
+		__field(	enum dpu_pingpong,	pp	)
+		__field(	bool,			enable	)
+		__field(	int,			refcnt	)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->pp = pp;
+		__entry->enable = enable;
+		__entry->refcnt = refcnt;
+	),
+	TP_printk("id=%u, pp=%d, enable=%s, refcnt=%d", __entry->drm_id,
+		  __entry->pp, __entry->enable ? "true" : "false",
+		  __entry->refcnt)
+);
+
+TRACE_EVENT(dpu_enc_phys_cmd_pp_tx_done,
+	TP_PROTO(uint32_t drm_id, enum dpu_pingpong pp, int new_count,
+		 u32 event),
+	TP_ARGS(drm_id, pp, new_count, event),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		drm_id		)
+		__field(	enum dpu_pingpong,	pp		)
+		__field(	int,			new_count	)
+		__field(	u32,			event		)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->pp = pp;
+		__entry->new_count = new_count;
+		__entry->event = event;
+	),
+	TP_printk("id=%u, pp=%d, new_count=%d, event=%u", __entry->drm_id,
+		  __entry->pp, __entry->new_count, __entry->event)
+);
+
+TRACE_EVENT(dpu_enc_phys_cmd_pdone_timeout,
+	TP_PROTO(uint32_t drm_id, enum dpu_pingpong pp, int timeout_count,
+		 int kickoff_count, u32 event),
+	TP_ARGS(drm_id, pp, timeout_count, kickoff_count, event),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		drm_id		)
+		__field(	enum dpu_pingpong,	pp		)
+		__field(	int,			timeout_count	)
+		__field(	int,			kickoff_count	)
+		__field(	u32,			event		)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->pp = pp;
+		__entry->timeout_count = timeout_count;
+		__entry->kickoff_count = kickoff_count;
+		__entry->event = event;
+	),
+	TP_printk("id=%u, pp=%d, timeout_count=%d, kickoff_count=%d, event=%u",
+		  __entry->drm_id, __entry->pp, __entry->timeout_count,
+		  __entry->kickoff_count, __entry->event)
+);
+
+TRACE_EVENT(dpu_enc_phys_vid_post_kickoff,
+	TP_PROTO(uint32_t drm_id, enum dpu_intf intf_idx),
+	TP_ARGS(drm_id, intf_idx),
+	TP_STRUCT__entry(
+		__field(	uint32_t,	drm_id			)
+		__field(	enum dpu_intf,	intf_idx		)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->intf_idx = intf_idx;
+	),
+	TP_printk("id=%u, intf_idx=%d", __entry->drm_id, __entry->intf_idx)
+);
+
+TRACE_EVENT(dpu_enc_phys_vid_irq_ctrl,
+	TP_PROTO(uint32_t drm_id, enum dpu_intf intf_idx, bool enable,
+		 int refcnt),
+	TP_ARGS(drm_id, intf_idx, enable, refcnt),
+	TP_STRUCT__entry(
+		__field(	uint32_t,	drm_id		)
+		__field(	enum dpu_intf,	intf_idx	)
+		__field(	bool,		enable		)
+		__field(	int,		refcnt		)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->intf_idx = intf_idx;
+		__entry->enable = enable;
+		__entry->refcnt = refcnt;
+	),
+	TP_printk("id=%u, intf_idx=%d enable=%s refcnt=%d", __entry->drm_id,
+		  __entry->intf_idx, __entry->enable ? "true" : "false",
+		  __entry->drm_id)
+);
+
+TRACE_EVENT(dpu_crtc_setup_mixer,
+	TP_PROTO(uint32_t crtc_id, uint32_t plane_id,
+		 struct drm_plane_state *state, struct dpu_plane_state *pstate,
+		 uint32_t stage_idx, uint32_t pixel_format,
+		 uint64_t modifier),
+	TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
+		pixel_format, modifier),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		crtc_id		)
+		__field(	uint32_t,		plane_id	)
+		__field(	uint32_t,		fb_id		)
+		__field_struct(	struct drm_rect,	src_rect	)
+		__field_struct(	struct drm_rect,	dst_rect	)
+		__field(	uint32_t,		stage_idx	)
+		__field(	enum dpu_stage,		stage		)
+		__field(	enum dpu_sspp,		sspp		)
+		__field(	uint32_t,		multirect_idx	)
+		__field(	uint32_t,		multirect_mode	)
+		__field(	uint32_t,		pixel_format	)
+		__field(	uint64_t,		modifier	)
+	),
+	TP_fast_assign(
+		__entry->crtc_id = crtc_id;
+		__entry->plane_id = plane_id;
+		__entry->fb_id = state ? state->fb->base.id : 0;
+		__entry->src_rect = drm_plane_state_src(state);
+		__entry->dst_rect = drm_plane_state_dest(state);
+		__entry->stage_idx = stage_idx;
+		__entry->stage = pstate->stage;
+		__entry->sspp = pstate->pipe.sspp->idx;
+		__entry->multirect_idx = pstate->pipe.multirect_index;
+		__entry->multirect_mode = pstate->pipe.multirect_mode;
+		__entry->pixel_format = pixel_format;
+		__entry->modifier = modifier;
+	),
+	TP_printk("crtc_id:%u plane_id:%u fb_id:%u src:" DRM_RECT_FP_FMT
+		  " dst:" DRM_RECT_FMT " stage_idx:%u stage:%d, sspp:%d "
+		  "multirect_index:%d multirect_mode:%u pix_format:%u "
+		  "modifier:%llu",
+		  __entry->crtc_id, __entry->plane_id, __entry->fb_id,
+		  DRM_RECT_FP_ARG(&__entry->src_rect),
+		  DRM_RECT_ARG(&__entry->dst_rect),
+		  __entry->stage_idx, __entry->stage, __entry->sspp,
+		  __entry->multirect_idx, __entry->multirect_mode,
+		  __entry->pixel_format, __entry->modifier)
+);
+
+TRACE_EVENT(dpu_crtc_setup_lm_bounds,
+	TP_PROTO(uint32_t drm_id, int mixer, struct drm_rect *bounds),
+	TP_ARGS(drm_id, mixer, bounds),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		drm_id	)
+		__field(	int,			mixer	)
+		__field_struct(	struct drm_rect,	bounds	)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->mixer = mixer;
+		__entry->bounds = *bounds;
+	),
+	TP_printk("id:%u mixer:%d bounds:" DRM_RECT_FMT, __entry->drm_id,
+		  __entry->mixer, DRM_RECT_ARG(&__entry->bounds))
+);
+
+TRACE_EVENT(dpu_crtc_vblank_enable,
+	TP_PROTO(uint32_t drm_id, uint32_t enc_id, bool enable,
+		 struct dpu_crtc *crtc),
+	TP_ARGS(drm_id, enc_id, enable, crtc),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		drm_id	)
+		__field(	uint32_t,		enc_id	)
+		__field(	bool,			enable	)
+		__field(	bool,			enabled )
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->enc_id = enc_id;
+		__entry->enable = enable;
+		__entry->enabled = crtc->enabled;
+	),
+	TP_printk("id:%u encoder:%u enable:%s state{enabled:%s}",
+		  __entry->drm_id, __entry->enc_id,
+		  __entry->enable ? "true" : "false",
+		  __entry->enabled ? "true" : "false")
+);
+
+DECLARE_EVENT_CLASS(dpu_crtc_enable_template,
+	TP_PROTO(uint32_t drm_id, bool enable, struct dpu_crtc *crtc),
+	TP_ARGS(drm_id, enable, crtc),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		drm_id	)
+		__field(	bool,			enable	)
+		__field(	bool,			enabled )
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->enable = enable;
+		__entry->enabled = crtc->enabled;
+	),
+	TP_printk("id:%u enable:%s state{enabled:%s}",
+		  __entry->drm_id, __entry->enable ? "true" : "false",
+		  __entry->enabled ? "true" : "false")
+);
+DEFINE_EVENT(dpu_crtc_enable_template, dpu_crtc_enable,
+	TP_PROTO(uint32_t drm_id, bool enable, struct dpu_crtc *crtc),
+	TP_ARGS(drm_id, enable, crtc)
+);
+DEFINE_EVENT(dpu_crtc_enable_template, dpu_crtc_disable,
+	TP_PROTO(uint32_t drm_id, bool enable, struct dpu_crtc *crtc),
+	TP_ARGS(drm_id, enable, crtc)
+);
+DEFINE_EVENT(dpu_crtc_enable_template, dpu_crtc_vblank,
+	TP_PROTO(uint32_t drm_id, bool enable, struct dpu_crtc *crtc),
+	TP_ARGS(drm_id, enable, crtc)
+);
+
+TRACE_EVENT(dpu_crtc_disable_frame_pending,
+	TP_PROTO(uint32_t drm_id, int frame_pending),
+	TP_ARGS(drm_id, frame_pending),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		drm_id		)
+		__field(	int,			frame_pending	)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->frame_pending = frame_pending;
+	),
+	TP_printk("id:%u frame_pending:%d", __entry->drm_id,
+		  __entry->frame_pending)
+);
+
+TRACE_EVENT(dpu_plane_set_scanout,
+	TP_PROTO(struct dpu_sw_pipe *pipe, struct dpu_hw_fmt_layout *layout),
+	TP_ARGS(pipe, layout),
+	TP_STRUCT__entry(
+		__field(	enum dpu_sspp,			index	)
+		__field_struct(	struct dpu_hw_fmt_layout,	layout	)
+		__field(	enum dpu_sspp_multirect_index,	multirect_index)
+	),
+	TP_fast_assign(
+		__entry->index = pipe->sspp->idx;
+		__entry->layout = *layout;
+		__entry->multirect_index = pipe->multirect_index;
+	),
+	TP_printk("index:%d layout:{%ux%u @ [%u/%u, %u/%u, %u/%u, %u/%u]} "
+		  "multirect_index:%d", __entry->index, __entry->layout.width,
+		  __entry->layout.height, __entry->layout.plane_addr[0],
+		  __entry->layout.plane_size[0],
+		  __entry->layout.plane_addr[1],
+		  __entry->layout.plane_size[1],
+		  __entry->layout.plane_addr[2],
+		  __entry->layout.plane_size[2],
+		  __entry->layout.plane_addr[3],
+		  __entry->layout.plane_size[3], __entry->multirect_index)
+);
+
+TRACE_EVENT(dpu_plane_disable,
+	TP_PROTO(uint32_t drm_id, bool is_virtual, uint32_t multirect_mode),
+	TP_ARGS(drm_id, is_virtual, multirect_mode),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		drm_id		)
+		__field(	bool,			is_virtual	)
+		__field(	uint32_t,		multirect_mode	)
+	),
+	TP_fast_assign(
+		__entry->drm_id = drm_id;
+		__entry->is_virtual = is_virtual;
+		__entry->multirect_mode = multirect_mode;
+	),
+	TP_printk("id:%u is_virtual:%s multirect_mode:%u", __entry->drm_id,
+		  __entry->is_virtual ? "true" : "false",
+		  __entry->multirect_mode)
+);
+
+DECLARE_EVENT_CLASS(dpu_rm_iter_template,
+	TP_PROTO(uint32_t id, uint32_t enc_id),
+	TP_ARGS(id, enc_id),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		id	)
+		__field(	uint32_t,		enc_id	)
+	),
+	TP_fast_assign(
+		__entry->id = id;
+		__entry->enc_id = enc_id;
+	),
+	TP_printk("id:%d enc_id:%u", __entry->id, __entry->enc_id)
+);
+DEFINE_EVENT(dpu_rm_iter_template, dpu_rm_reserve_intf,
+	TP_PROTO(uint32_t id, uint32_t enc_id),
+	TP_ARGS(id, enc_id)
+);
+DEFINE_EVENT(dpu_rm_iter_template, dpu_rm_reserve_ctls,
+	TP_PROTO(uint32_t id, uint32_t enc_id),
+	TP_ARGS(id, enc_id)
+);
+
+TRACE_EVENT(dpu_rm_reserve_lms,
+	TP_PROTO(uint32_t id, uint32_t enc_id, uint32_t pp_id),
+	TP_ARGS(id, enc_id, pp_id),
+	TP_STRUCT__entry(
+		__field(	uint32_t,		id	)
+		__field(	uint32_t,		enc_id	)
+		__field(	uint32_t,		pp_id	)
+	),
+	TP_fast_assign(
+		__entry->id = id;
+		__entry->enc_id = enc_id;
+		__entry->pp_id = pp_id;
+	),
+	TP_printk("id:%d enc_id:%u pp_id:%u", __entry->id,
+		  __entry->enc_id, __entry->pp_id)
+);
+
+TRACE_EVENT(dpu_vbif_wait_xin_halt_fail,
+	TP_PROTO(enum dpu_vbif index, u32 xin_id),
+	TP_ARGS(index, xin_id),
+	TP_STRUCT__entry(
+		__field(	enum dpu_vbif,	index	)
+		__field(	u32,		xin_id	)
+	),
+	TP_fast_assign(
+		__entry->index = index;
+		__entry->xin_id = xin_id;
+	),
+	TP_printk("index:%d xin_id:%u", __entry->index, __entry->xin_id)
+);
+
+TRACE_EVENT(dpu_pp_connect_ext_te,
+	TP_PROTO(enum dpu_pingpong pp, u32 cfg),
+	TP_ARGS(pp, cfg),
+	TP_STRUCT__entry(
+		__field(	enum dpu_pingpong,	pp	)
+		__field(	u32,			cfg	)
+	),
+	TP_fast_assign(
+		__entry->pp = pp;
+		__entry->cfg = cfg;
+	),
+	TP_printk("pp:%d cfg:%u", __entry->pp, __entry->cfg)
+);
+
+TRACE_EVENT(dpu_intf_connect_ext_te,
+	TP_PROTO(enum dpu_intf intf, u32 cfg),
+	TP_ARGS(intf, cfg),
+	TP_STRUCT__entry(
+		__field(	enum dpu_intf,	intf	)
+		__field(	u32,			cfg	)
+	),
+	TP_fast_assign(
+		__entry->intf = intf;
+		__entry->cfg = cfg;
+	),
+	TP_printk("intf:%d cfg:%u", __entry->intf, __entry->cfg)
+);
+
+TRACE_EVENT(dpu_core_irq_register_callback,
+	TP_PROTO(unsigned int irq_reg, unsigned int irq_bit, void *callback),
+	TP_ARGS(irq_reg, irq_bit, callback),
+	TP_STRUCT__entry(
+		__field(	unsigned int,			irq_reg	)
+		__field(	unsigned int,			irq_bit	)
+		__field(	void *,				callback)
+	),
+	TP_fast_assign(
+		__entry->irq_reg = irq_reg;
+		__entry->irq_bit = irq_bit;
+		__entry->callback = callback;
+	),
+	TP_printk("IRQ=[%d, %d] callback:%ps", __entry->irq_reg, __entry->irq_bit,
+		  __entry->callback)
+);
+
+TRACE_EVENT(dpu_core_irq_unregister_callback,
+	TP_PROTO(unsigned int irq_reg, unsigned int irq_bit),
+	TP_ARGS(irq_reg, irq_bit),
+	TP_STRUCT__entry(
+		__field(	unsigned int,			irq_reg	)
+		__field(	unsigned int,			irq_bit	)
+	),
+	TP_fast_assign(
+		__entry->irq_reg = irq_reg;
+		__entry->irq_bit = irq_bit;
+	),
+	TP_printk("IRQ=[%d, %d]", __entry->irq_reg, __entry->irq_bit)
+);
+
+TRACE_EVENT(dpu_core_perf_update_clk,
+	TP_PROTO(struct drm_device *dev, bool stop_req, u64 clk_rate),
+	TP_ARGS(dev, stop_req, clk_rate),
+	TP_STRUCT__entry(
+		__string(	dev_name,		dev->unique	)
+		__field(	bool,			stop_req	)
+		__field(	u64,			clk_rate	)
+	),
+	TP_fast_assign(
+		__assign_str(dev_name, dev->unique);
+		__entry->stop_req = stop_req;
+		__entry->clk_rate = clk_rate;
+	),
+	TP_printk("dev:%s stop_req:%s clk_rate:%llu", __get_str(dev_name),
+		  __entry->stop_req ? "true" : "false", __entry->clk_rate)
+);
+
+TRACE_EVENT(dpu_hw_ctl_update_pending_flush,
+	TP_PROTO(u32 new_bits, u32 pending_mask),
+	TP_ARGS(new_bits, pending_mask),
+	TP_STRUCT__entry(
+		__field(	u32,			new_bits	)
+		__field(	u32,			pending_mask	)
+	),
+	TP_fast_assign(
+		__entry->new_bits = new_bits;
+		__entry->pending_mask = pending_mask;
+	),
+	TP_printk("new=%x existing=%x", __entry->new_bits,
+		  __entry->pending_mask)
+);
+
+DECLARE_EVENT_CLASS(dpu_hw_ctl_pending_flush_template,
+	TP_PROTO(u32 pending_mask, u32 ctl_flush),
+	TP_ARGS(pending_mask, ctl_flush),
+	TP_STRUCT__entry(
+		__field(	u32,			pending_mask	)
+		__field(	u32,			ctl_flush	)
+	),
+	TP_fast_assign(
+		__entry->pending_mask = pending_mask;
+		__entry->ctl_flush = ctl_flush;
+	),
+	TP_printk("pending_mask=%x CTL_FLUSH=%x", __entry->pending_mask,
+		  __entry->ctl_flush)
+);
+DEFINE_EVENT(dpu_hw_ctl_pending_flush_template, dpu_hw_ctl_clear_pending_flush,
+	TP_PROTO(u32 pending_mask, u32 ctl_flush),
+	TP_ARGS(pending_mask, ctl_flush)
+);
+DEFINE_EVENT(dpu_hw_ctl_pending_flush_template,
+	     dpu_hw_ctl_trigger_pending_flush,
+	TP_PROTO(u32 pending_mask, u32 ctl_flush),
+	TP_ARGS(pending_mask, ctl_flush)
+);
+DEFINE_EVENT(dpu_hw_ctl_pending_flush_template, dpu_hw_ctl_trigger_prepare,
+	TP_PROTO(u32 pending_mask, u32 ctl_flush),
+	TP_ARGS(pending_mask, ctl_flush)
+);
+DEFINE_EVENT(dpu_hw_ctl_pending_flush_template, dpu_hw_ctl_trigger_start,
+	TP_PROTO(u32 pending_mask, u32 ctl_flush),
+	TP_ARGS(pending_mask, ctl_flush)
+);
+
+#define DPU_ATRACE_END(name) trace_tracing_mark_write(current->tgid, name, 0)
+#define DPU_ATRACE_BEGIN(name) trace_tracing_mark_write(current->tgid, name, 1)
+#define DPU_ATRACE_FUNC() DPU_ATRACE_BEGIN(__func__)
+
+#define DPU_ATRACE_INT(name, value) \
+	trace_dpu_trace_counter(current->tgid, name, value)
+
+#endif /* _DPU_TRACE_H_ */
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#include <trace/define_trace.h>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_vbif.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_vbif.c
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+
+#include "dpu_vbif.h"
+#include "dpu_hw_vbif.h"
+#include "dpu_trace.h"
+
+static struct dpu_hw_vbif *dpu_get_vbif(struct dpu_kms *dpu_kms, enum dpu_vbif vbif_idx)
+{
+	if (vbif_idx < ARRAY_SIZE(dpu_kms->hw_vbif))
+		return dpu_kms->hw_vbif[vbif_idx];
+
+	return NULL;
+}
+
+static const char *dpu_vbif_name(enum dpu_vbif idx)
+{
+	switch (idx) {
+	case VBIF_RT:
+		return "VBIF_RT";
+	case VBIF_NRT:
+		return "VBIF_NRT";
+	default:
+		return "??";
+	}
+}
+
+/**
+ * _dpu_vbif_wait_for_xin_halt - wait for the xin to halt
+ * @vbif:	Pointer to hardware vbif driver
+ * @xin_id:	Client interface identifier
+ * @return:	0 if success; error code otherwise
+ */
+static int _dpu_vbif_wait_for_xin_halt(struct dpu_hw_vbif *vbif, u32 xin_id)
+{
+	ktime_t timeout;
+	bool status;
+	int rc;
+
+	if (!vbif || !vbif->cap || !vbif->ops.get_halt_ctrl) {
+		DPU_ERROR("invalid arguments vbif %d\n", vbif != NULL);
+		return -EINVAL;
+	}
+
+	timeout = ktime_add_us(ktime_get(), vbif->cap->xin_halt_timeout);
+	for (;;) {
+		status = vbif->ops.get_halt_ctrl(vbif, xin_id);
+		if (status)
+			break;
+		if (ktime_compare_safe(ktime_get(), timeout) > 0) {
+			status = vbif->ops.get_halt_ctrl(vbif, xin_id);
+			break;
+		}
+		usleep_range(501, 1000);
+	}
+
+	if (!status) {
+		rc = -ETIMEDOUT;
+		DPU_ERROR("%s client %d not halting. TIMEDOUT.\n",
+				dpu_vbif_name(vbif->idx), xin_id);
+	} else {
+		rc = 0;
+		DRM_DEBUG_ATOMIC("%s client %d is halted\n",
+				dpu_vbif_name(vbif->idx), xin_id);
+	}
+
+	return rc;
+}
+
+/**
+ * _dpu_vbif_apply_dynamic_ot_limit - determine OT based on usecase parameters
+ * @vbif:	Pointer to hardware vbif driver
+ * @ot_lim:	Pointer to OT limit to be modified
+ * @params:	Pointer to usecase parameters
+ */
+static void _dpu_vbif_apply_dynamic_ot_limit(struct dpu_hw_vbif *vbif,
+		u32 *ot_lim, struct dpu_vbif_set_ot_params *params)
+{
+	u64 pps;
+	const struct dpu_vbif_dynamic_ot_tbl *tbl;
+	u32 i;
+
+	if (!vbif || !(vbif->cap->features & BIT(DPU_VBIF_QOS_OTLIM)))
+		return;
+
+	/* Dynamic OT setting done only for WFD */
+	if (!params->is_wfd)
+		return;
+
+	pps = params->frame_rate;
+	pps *= params->width;
+	pps *= params->height;
+
+	tbl = params->rd ? &vbif->cap->dynamic_ot_rd_tbl :
+			&vbif->cap->dynamic_ot_wr_tbl;
+
+	for (i = 0; i < tbl->count; i++) {
+		if (pps <= tbl->cfg[i].pps) {
+			*ot_lim = tbl->cfg[i].ot_limit;
+			break;
+		}
+	}
+
+	DRM_DEBUG_ATOMIC("%s xin:%d w:%d h:%d fps:%d pps:%llu ot:%u\n",
+			dpu_vbif_name(vbif->idx), params->xin_id,
+			params->width, params->height, params->frame_rate,
+			pps, *ot_lim);
+}
+
+/**
+ * _dpu_vbif_get_ot_limit - get OT based on usecase & configuration parameters
+ * @vbif:	Pointer to hardware vbif driver
+ * @params:	Pointer to usecase parameters
+ * @return:	OT limit
+ */
+static u32 _dpu_vbif_get_ot_limit(struct dpu_hw_vbif *vbif,
+	struct dpu_vbif_set_ot_params *params)
+{
+	u32 ot_lim = 0;
+	u32 val;
+
+	if (!vbif || !vbif->cap) {
+		DPU_ERROR("invalid arguments vbif %d\n", vbif != NULL);
+		return -EINVAL;
+	}
+
+	if (vbif->cap->default_ot_wr_limit && !params->rd)
+		ot_lim = vbif->cap->default_ot_wr_limit;
+	else if (vbif->cap->default_ot_rd_limit && params->rd)
+		ot_lim = vbif->cap->default_ot_rd_limit;
+
+	/*
+	 * If default ot is not set from dt/catalog,
+	 * then do not configure it.
+	 */
+	if (ot_lim == 0)
+		goto exit;
+
+	/* Modify the limits if the target and the use case requires it */
+	_dpu_vbif_apply_dynamic_ot_limit(vbif, &ot_lim, params);
+
+	if (vbif && vbif->ops.get_limit_conf) {
+		val = vbif->ops.get_limit_conf(vbif,
+				params->xin_id, params->rd);
+		if (val == ot_lim)
+			ot_lim = 0;
+	}
+
+exit:
+	DRM_DEBUG_ATOMIC("%s xin:%d ot_lim:%d\n",
+			dpu_vbif_name(vbif->idx), params->xin_id, ot_lim);
+	return ot_lim;
+}
+
+/**
+ * dpu_vbif_set_ot_limit - set OT based on usecase & configuration parameters
+ * @dpu_kms:	DPU handler
+ * @params:	Pointer to usecase parameters
+ *
+ * Note this function would block waiting for bus halt.
+ */
+void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,
+		struct dpu_vbif_set_ot_params *params)
+{
+	struct dpu_hw_vbif *vbif;
+	u32 ot_lim;
+	int ret;
+
+	vbif = dpu_get_vbif(dpu_kms, params->vbif_idx);
+	if (!vbif) {
+		DRM_DEBUG_ATOMIC("invalid arguments vbif %d\n", vbif != NULL);
+		return;
+	}
+
+	if (!vbif->ops.set_limit_conf || !vbif->ops.set_halt_ctrl)
+		return;
+
+	/* set write_gather_en for all write clients */
+	if (vbif->ops.set_write_gather_en && !params->rd)
+		vbif->ops.set_write_gather_en(vbif, params->xin_id);
+
+	ot_lim = _dpu_vbif_get_ot_limit(vbif, params) & 0xFF;
+
+	if (ot_lim == 0)
+		return;
+
+	trace_dpu_perf_set_ot(params->num, params->xin_id, ot_lim,
+		params->vbif_idx);
+
+	vbif->ops.set_limit_conf(vbif, params->xin_id, params->rd, ot_lim);
+
+	vbif->ops.set_halt_ctrl(vbif, params->xin_id, true);
+
+	ret = _dpu_vbif_wait_for_xin_halt(vbif, params->xin_id);
+	if (ret)
+		trace_dpu_vbif_wait_xin_halt_fail(vbif->idx, params->xin_id);
+
+	vbif->ops.set_halt_ctrl(vbif, params->xin_id, false);
+}
+
+void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms,
+		struct dpu_vbif_set_qos_params *params)
+{
+	struct dpu_hw_vbif *vbif;
+	const struct dpu_vbif_qos_tbl *qos_tbl;
+	int i;
+
+	if (!params) {
+		DPU_ERROR("invalid arguments\n");
+		return;
+	}
+
+	vbif = dpu_get_vbif(dpu_kms, params->vbif_idx);
+
+	if (!vbif || !vbif->cap) {
+		DPU_ERROR("invalid vbif %d\n", params->vbif_idx);
+		return;
+	}
+
+	if (!vbif->ops.set_qos_remap) {
+		DRM_DEBUG_ATOMIC("qos remap not supported\n");
+		return;
+	}
+
+	qos_tbl = params->is_rt ? &vbif->cap->qos_rt_tbl :
+			&vbif->cap->qos_nrt_tbl;
+
+	if (!qos_tbl->npriority_lvl || !qos_tbl->priority_lvl) {
+		DRM_DEBUG_ATOMIC("qos tbl not defined\n");
+		return;
+	}
+
+	for (i = 0; i < qos_tbl->npriority_lvl; i++) {
+		DRM_DEBUG_ATOMIC("%s xin:%d lvl:%d/%d\n",
+				dpu_vbif_name(params->vbif_idx), params->xin_id, i,
+				qos_tbl->priority_lvl[i]);
+		vbif->ops.set_qos_remap(vbif, params->xin_id, i,
+				qos_tbl->priority_lvl[i]);
+	}
+}
+
+void dpu_vbif_clear_errors(struct dpu_kms *dpu_kms)
+{
+	struct dpu_hw_vbif *vbif;
+	u32 i, pnd, src;
+
+	for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
+		vbif = dpu_kms->hw_vbif[i];
+		if (vbif && vbif->ops.clear_errors) {
+			vbif->ops.clear_errors(vbif, &pnd, &src);
+			if (pnd || src) {
+				DRM_DEBUG_KMS("%s: pnd 0x%X, src 0x%X\n",
+					      dpu_vbif_name(vbif->idx), pnd, src);
+			}
+		}
+	}
+}
+
+void dpu_vbif_init_memtypes(struct dpu_kms *dpu_kms)
+{
+	struct dpu_hw_vbif *vbif;
+	int i, j;
+
+	for (i = 0; i < ARRAY_SIZE(dpu_kms->hw_vbif); i++) {
+		vbif = dpu_kms->hw_vbif[i];
+		if (vbif && vbif->cap && vbif->ops.set_mem_type) {
+			for (j = 0; j < vbif->cap->memtype_count; j++)
+				vbif->ops.set_mem_type(
+						vbif, j, vbif->cap->memtype[j]);
+		}
+	}
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+void dpu_debugfs_vbif_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root)
+{
+	char vbif_name[32];
+	struct dentry *entry, *debugfs_vbif;
+	int i, j;
+
+	entry = debugfs_create_dir("vbif", debugfs_root);
+
+	for (i = 0; i < dpu_kms->catalog->vbif_count; i++) {
+		const struct dpu_vbif_cfg *vbif = &dpu_kms->catalog->vbif[i];
+
+		snprintf(vbif_name, sizeof(vbif_name), "%d", vbif->id);
+
+		debugfs_vbif = debugfs_create_dir(vbif_name, entry);
+
+		debugfs_create_u32("features", 0600, debugfs_vbif,
+			(u32 *)&vbif->features);
+
+		debugfs_create_u32("xin_halt_timeout", 0400, debugfs_vbif,
+			(u32 *)&vbif->xin_halt_timeout);
+
+		debugfs_create_u32("default_rd_ot_limit", 0400, debugfs_vbif,
+			(u32 *)&vbif->default_ot_rd_limit);
+
+		debugfs_create_u32("default_wr_ot_limit", 0400, debugfs_vbif,
+			(u32 *)&vbif->default_ot_wr_limit);
+
+		for (j = 0; j < vbif->dynamic_ot_rd_tbl.count; j++) {
+			const struct dpu_vbif_dynamic_ot_cfg *cfg =
+					&vbif->dynamic_ot_rd_tbl.cfg[j];
+
+			snprintf(vbif_name, sizeof(vbif_name),
+					"dynamic_ot_rd_%d_pps", j);
+			debugfs_create_u64(vbif_name, 0400, debugfs_vbif,
+					(u64 *)&cfg->pps);
+			snprintf(vbif_name, sizeof(vbif_name),
+					"dynamic_ot_rd_%d_ot_limit", j);
+			debugfs_create_u32(vbif_name, 0400, debugfs_vbif,
+					(u32 *)&cfg->ot_limit);
+		}
+
+		for (j = 0; j < vbif->dynamic_ot_wr_tbl.count; j++) {
+			const struct dpu_vbif_dynamic_ot_cfg *cfg =
+					&vbif->dynamic_ot_wr_tbl.cfg[j];
+
+			snprintf(vbif_name, sizeof(vbif_name),
+					"dynamic_ot_wr_%d_pps", j);
+			debugfs_create_u64(vbif_name, 0400, debugfs_vbif,
+					(u64 *)&cfg->pps);
+			snprintf(vbif_name, sizeof(vbif_name),
+					"dynamic_ot_wr_%d_ot_limit", j);
+			debugfs_create_u32(vbif_name, 0400, debugfs_vbif,
+					(u32 *)&cfg->ot_limit);
+		}
+	}
+}
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_vbif.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_vbif.h
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __DPU_VBIF_H__
+#define __DPU_VBIF_H__
+
+#include "dpu_kms.h"
+
+struct dpu_vbif_set_ot_params {
+	u32 xin_id;
+	u32 num;
+	u32 width;
+	u32 height;
+	u32 frame_rate;
+	bool rd;
+	bool is_wfd;
+	u32 vbif_idx;
+};
+
+struct dpu_vbif_set_memtype_params {
+	u32 xin_id;
+	u32 vbif_idx;
+	bool is_cacheable;
+};
+
+/**
+ * struct dpu_vbif_set_qos_params - QoS remapper parameter
+ * @vbif_idx: vbif identifier
+ * @xin_id: client interface identifier
+ * @num: pipe identifier (debug only)
+ * @is_rt: true if pipe is used in real-time use case
+ */
+struct dpu_vbif_set_qos_params {
+	u32 vbif_idx;
+	u32 xin_id;
+	u32 num;
+	bool is_rt;
+};
+
+/**
+ * dpu_vbif_set_ot_limit - set OT limit for vbif client
+ * @dpu_kms:	DPU handler
+ * @params:	Pointer to OT configuration parameters
+ */
+void dpu_vbif_set_ot_limit(struct dpu_kms *dpu_kms,
+		struct dpu_vbif_set_ot_params *params);
+
+/**
+ * dpu_vbif_set_qos_remap - set QoS priority level remap
+ * @dpu_kms:	DPU handler
+ * @params:	Pointer to QoS configuration parameters
+ */
+void dpu_vbif_set_qos_remap(struct dpu_kms *dpu_kms,
+		struct dpu_vbif_set_qos_params *params);
+
+/**
+ * dpu_vbif_clear_errors - clear any vbif errors
+ * @dpu_kms:	DPU handler
+ */
+void dpu_vbif_clear_errors(struct dpu_kms *dpu_kms);
+
+/**
+ * dpu_vbif_init_memtypes - initialize xin memory types for vbif
+ * @dpu_kms:	DPU handler
+ */
+void dpu_vbif_init_memtypes(struct dpu_kms *dpu_kms);
+
+void dpu_debugfs_vbif_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root);
+
+#endif /* __DPU_VBIF_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_writeback.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_writeback.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <drm/drm_edid.h>
+#include <drm/drm_framebuffer.h>
+
+#include "dpu_writeback.h"
+
+static int dpu_wb_conn_get_modes(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms);
+
+	/*
+	 * We should ideally be limiting the modes only to the maxlinewidth but
+	 * on some chipsets this will allow even 4k modes to be added which will
+	 * fail the per SSPP bandwidth checks. So, till we have dual-SSPP support
+	 * and source split support added lets limit the modes based on max_mixer_width
+	 * as 4K modes can then be supported.
+	 */
+	return drm_add_modes_noedid(connector, dpu_kms->catalog->caps->max_mixer_width,
+			dev->mode_config.max_height);
+}
+
+static int dpu_wb_conn_atomic_check(struct drm_connector *connector,
+				    struct drm_atomic_state *state)
+{
+	struct drm_writeback_connector *wb_conn = drm_connector_to_writeback(connector);
+	struct dpu_wb_connector *dpu_wb_conn = to_dpu_wb_conn(wb_conn);
+	struct drm_connector_state *conn_state =
+		drm_atomic_get_new_connector_state(state, connector);
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+	const struct drm_display_mode *mode;
+	struct drm_framebuffer *fb;
+
+	DPU_DEBUG("[atomic_check:%d]\n", connector->base.id);
+
+	if (!conn_state || !conn_state->connector) {
+		DPU_ERROR("invalid connector state\n");
+		return -EINVAL;
+	} else if (conn_state->connector->status != connector_status_connected) {
+		DPU_ERROR("connector not connected %d\n", conn_state->connector->status);
+		return -EINVAL;
+	}
+
+	crtc = conn_state->crtc;
+	if (!crtc)
+		return 0;
+
+	if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
+		return 0;
+
+	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	if (IS_ERR(crtc_state))
+		return PTR_ERR(crtc_state);
+
+	mode = &crtc_state->mode;
+
+	fb = conn_state->writeback_job->fb;
+
+	DPU_DEBUG("[fb_id:%u][fb:%u,%u][mode:\"%s\":%ux%u]\n", fb->base.id, fb->width, fb->height,
+		  mode->name, mode->hdisplay, mode->vdisplay);
+
+	if (fb->width != mode->hdisplay) {
+		DPU_ERROR("invalid fb w=%d, mode w=%d\n", fb->width, mode->hdisplay);
+		return -EINVAL;
+	} else if (fb->height != mode->vdisplay) {
+		DPU_ERROR("invalid fb h=%d, mode h=%d\n", fb->height, mode->vdisplay);
+		return -EINVAL;
+	} else if (fb->width > dpu_wb_conn->maxlinewidth) {
+		DPU_ERROR("invalid fb w=%d, maxlinewidth=%u\n",
+			  fb->width, dpu_wb_conn->maxlinewidth);
+		return -EINVAL;
+	}
+
+	return drm_atomic_helper_check_wb_connector_state(conn_state->connector, conn_state->state);
+}
+
+static const struct drm_connector_funcs dpu_wb_conn_funcs = {
+	.reset = drm_atomic_helper_connector_reset,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = drm_connector_cleanup,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int dpu_wb_conn_prepare_job(struct drm_writeback_connector *connector,
+		struct drm_writeback_job *job)
+{
+
+	struct dpu_wb_connector *dpu_wb_conn = to_dpu_wb_conn(connector);
+
+	if (!job->fb)
+		return 0;
+
+	dpu_encoder_prepare_wb_job(dpu_wb_conn->wb_enc, job);
+
+	return 0;
+}
+
+static void dpu_wb_conn_cleanup_job(struct drm_writeback_connector *connector,
+		struct drm_writeback_job *job)
+{
+	struct dpu_wb_connector *dpu_wb_conn = to_dpu_wb_conn(connector);
+
+	if (!job->fb)
+		return;
+
+	dpu_encoder_cleanup_wb_job(dpu_wb_conn->wb_enc, job);
+}
+
+static const struct drm_connector_helper_funcs dpu_wb_conn_helper_funcs = {
+	.get_modes = dpu_wb_conn_get_modes,
+	.atomic_check = dpu_wb_conn_atomic_check,
+	.prepare_writeback_job = dpu_wb_conn_prepare_job,
+	.cleanup_writeback_job = dpu_wb_conn_cleanup_job,
+};
+
+int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
+		const u32 *format_list, u32 num_formats, u32 maxlinewidth)
+{
+	struct dpu_wb_connector *dpu_wb_conn;
+	int rc = 0;
+
+	dpu_wb_conn = devm_kzalloc(dev->dev, sizeof(*dpu_wb_conn), GFP_KERNEL);
+	if (!dpu_wb_conn)
+		return -ENOMEM;
+
+	dpu_wb_conn->maxlinewidth = maxlinewidth;
+
+	drm_connector_helper_add(&dpu_wb_conn->base.base, &dpu_wb_conn_helper_funcs);
+
+	/* DPU initializes the encoder and sets it up completely for writeback
+	 * cases and hence should use the new API drm_writeback_connector_init_with_encoder
+	 * to initialize the writeback connector
+	 */
+	rc = drm_writeback_connector_init_with_encoder(dev, &dpu_wb_conn->base, enc,
+			&dpu_wb_conn_funcs, format_list, num_formats);
+
+	if (!rc)
+		dpu_wb_conn->wb_enc = enc;
+
+	return rc;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/dpu_writeback.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/dpu_writeback.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _DPU_WRITEBACK_H
+#define _DPU_WRITEBACK_H
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_file.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_writeback.h>
+
+#include "msm_drv.h"
+#include "dpu_kms.h"
+#include "dpu_encoder_phys.h"
+
+struct dpu_wb_connector {
+	struct drm_writeback_connector base;
+	struct drm_encoder *wb_enc;
+	u32 maxlinewidth;
+};
+
+static inline struct dpu_wb_connector *to_dpu_wb_conn(struct drm_writeback_connector *conn)
+{
+	return container_of(conn, struct dpu_wb_connector, base);
+}
+
+int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc,
+		const u32 *format_list, u32 num_formats, u32 maxlinewidth);
+
+#endif /*_DPU_WRITEBACK_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/dpu1/msm_media_info.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/dpu1/msm_media_info.h
@@ -0,0 +1,1155 @@
+#ifndef __MEDIA_INFO_H__
+#define __MEDIA_INFO_H__
+
+#ifndef MSM_MEDIA_ALIGN
+#define MSM_MEDIA_ALIGN(__sz, __align) (((__align) & ((__align) - 1)) ?\
+	((((__sz) + (__align) - 1) / (__align)) * (__align)) :\
+	(((__sz) + (__align) - 1) & (~((__align) - 1))))
+#endif
+
+#ifndef MSM_MEDIA_ROUNDUP
+#define MSM_MEDIA_ROUNDUP(__sz, __r) (((__sz) + ((__r) - 1)) / (__r))
+#endif
+
+#ifndef MSM_MEDIA_MAX
+#define MSM_MEDIA_MAX(__a, __b) ((__a) > (__b)?(__a):(__b))
+#endif
+
+enum color_fmts {
+	/* Venus NV12:
+	 * YUV 4:2:0 image with a plane of 8 bit Y samples followed
+	 * by an interleaved U/V plane containing 8 bit 2x2 subsampled
+	 * colour difference samples.
+	 *
+	 * <-------- Y/UV_Stride -------->
+	 * <------- Width ------->
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  ^           ^
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  Height      |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |          Y_Scanlines
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  V           |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              V
+	 * U V U V U V U V U V U V . . . .  ^
+	 * U V U V U V U V U V U V . . . .  |
+	 * U V U V U V U V U V U V . . . .  |
+	 * U V U V U V U V U V U V . . . .  UV_Scanlines
+	 * . . . . . . . . . . . . . . . .  |
+	 * . . . . . . . . . . . . . . . .  V
+	 * . . . . . . . . . . . . . . . .  --> Buffer size alignment
+	 *
+	 * Y_Stride : Width aligned to 128
+	 * UV_Stride : Width aligned to 128
+	 * Y_Scanlines: Height aligned to 32
+	 * UV_Scanlines: Height/2 aligned to 16
+	 * Extradata: Arbitrary (software-imposed) padding
+	 * Total size = align((Y_Stride * Y_Scanlines
+	 *          + UV_Stride * UV_Scanlines
+	 *          + max(Extradata, Y_Stride * 8), 4096)
+	 */
+	COLOR_FMT_NV12,
+
+	/* Venus NV21:
+	 * YUV 4:2:0 image with a plane of 8 bit Y samples followed
+	 * by an interleaved V/U plane containing 8 bit 2x2 subsampled
+	 * colour difference samples.
+	 *
+	 * <-------- Y/UV_Stride -------->
+	 * <------- Width ------->
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  ^           ^
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  Height      |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |          Y_Scanlines
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  V           |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              V
+	 * V U V U V U V U V U V U . . . .  ^
+	 * V U V U V U V U V U V U . . . .  |
+	 * V U V U V U V U V U V U . . . .  |
+	 * V U V U V U V U V U V U . . . .  UV_Scanlines
+	 * . . . . . . . . . . . . . . . .  |
+	 * . . . . . . . . . . . . . . . .  V
+	 * . . . . . . . . . . . . . . . .  --> Padding & Buffer size alignment
+	 *
+	 * Y_Stride : Width aligned to 128
+	 * UV_Stride : Width aligned to 128
+	 * Y_Scanlines: Height aligned to 32
+	 * UV_Scanlines: Height/2 aligned to 16
+	 * Extradata: Arbitrary (software-imposed) padding
+	 * Total size = align((Y_Stride * Y_Scanlines
+	 *          + UV_Stride * UV_Scanlines
+	 *          + max(Extradata, Y_Stride * 8), 4096)
+	 */
+	COLOR_FMT_NV21,
+	/* Venus NV12_MVTB:
+	 * Two YUV 4:2:0 images/views one after the other
+	 * in a top-bottom layout, same as NV12
+	 * with a plane of 8 bit Y samples followed
+	 * by an interleaved U/V plane containing 8 bit 2x2 subsampled
+	 * colour difference samples.
+	 *
+	 *
+	 * <-------- Y/UV_Stride -------->
+	 * <------- Width ------->
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  ^           ^               ^
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |               |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  Height      |               |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |          Y_Scanlines      |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |               |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |               |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |               |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  V           |               |
+	 * . . . . . . . . . . . . . . . .              |             View_1
+	 * . . . . . . . . . . . . . . . .              |               |
+	 * . . . . . . . . . . . . . . . .              |               |
+	 * . . . . . . . . . . . . . . . .              V               |
+	 * U V U V U V U V U V U V . . . .  ^                           |
+	 * U V U V U V U V U V U V . . . .  |                           |
+	 * U V U V U V U V U V U V . . . .  |                           |
+	 * U V U V U V U V U V U V . . . .  UV_Scanlines                |
+	 * . . . . . . . . . . . . . . . .  |                           |
+	 * . . . . . . . . . . . . . . . .  V                           V
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  ^           ^               ^
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |               |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  Height      |               |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |          Y_Scanlines      |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |               |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |               |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |               |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  V           |               |
+	 * . . . . . . . . . . . . . . . .              |             View_2
+	 * . . . . . . . . . . . . . . . .              |               |
+	 * . . . . . . . . . . . . . . . .              |               |
+	 * . . . . . . . . . . . . . . . .              V               |
+	 * U V U V U V U V U V U V . . . .  ^                           |
+	 * U V U V U V U V U V U V . . . .  |                           |
+	 * U V U V U V U V U V U V . . . .  |                           |
+	 * U V U V U V U V U V U V . . . .  UV_Scanlines                |
+	 * . . . . . . . . . . . . . . . .  |                           |
+	 * . . . . . . . . . . . . . . . .  V                           V
+	 * . . . . . . . . . . . . . . . .  --> Buffer size alignment
+	 *
+	 * Y_Stride : Width aligned to 128
+	 * UV_Stride : Width aligned to 128
+	 * Y_Scanlines: Height aligned to 32
+	 * UV_Scanlines: Height/2 aligned to 16
+	 * View_1 begin at: 0 (zero)
+	 * View_2 begin at: Y_Stride * Y_Scanlines + UV_Stride * UV_Scanlines
+	 * Extradata: Arbitrary (software-imposed) padding
+	 * Total size = align((2*(Y_Stride * Y_Scanlines)
+	 *          + 2*(UV_Stride * UV_Scanlines) + Extradata), 4096)
+	 */
+	COLOR_FMT_NV12_MVTB,
+	/*
+	 * The buffer can be of 2 types:
+	 * (1) Venus NV12 UBWC Progressive
+	 * (2) Venus NV12 UBWC Interlaced
+	 *
+	 * (1) Venus NV12 UBWC Progressive Buffer Format:
+	 * Compressed Macro-tile format for NV12.
+	 * Contains 4 planes in the following order -
+	 * (A) Y_Meta_Plane
+	 * (B) Y_UBWC_Plane
+	 * (C) UV_Meta_Plane
+	 * (D) UV_UBWC_Plane
+	 *
+	 * Y_Meta_Plane consists of meta information to decode compressed
+	 * tile data in Y_UBWC_Plane.
+	 * Y_UBWC_Plane consists of Y data in compressed macro-tile format.
+	 * UBWC decoder block will use the Y_Meta_Plane data together with
+	 * Y_UBWC_Plane data to produce loss-less uncompressed 8 bit Y samples.
+	 *
+	 * UV_Meta_Plane consists of meta information to decode compressed
+	 * tile data in UV_UBWC_Plane.
+	 * UV_UBWC_Plane consists of UV data in compressed macro-tile format.
+	 * UBWC decoder block will use UV_Meta_Plane data together with
+	 * UV_UBWC_Plane data to produce loss-less uncompressed 8 bit 2x2
+	 * subsampled color difference samples.
+	 *
+	 * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable
+	 * and randomly accessible. There is no dependency between tiles.
+	 *
+	 * <----- Y_Meta_Stride ---->
+	 * <-------- Width ------>
+	 * M M M M M M M M M M M M . .      ^           ^
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      Height      |
+	 * M M M M M M M M M M M M . .      |         Meta_Y_Scanlines
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      V           |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . .                  V
+	 * <--Compressed tile Y Stride--->
+	 * <------- Width ------->
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  ^           ^
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  Height      |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |        Macro_tile_Y_Scanlines
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  V           |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . . . .              V
+	 * <----- UV_Meta_Stride ---->
+	 * M M M M M M M M M M M M . .      ^
+	 * M M M M M M M M M M M M . .      |
+	 * M M M M M M M M M M M M . .      |
+	 * M M M M M M M M M M M M . .      M_UV_Scanlines
+	 * . . . . . . . . . . . . . .      |
+	 * . . . . . . . . . . . . . .      V
+	 * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+	 * <--Compressed tile UV Stride--->
+	 * U* V* U* V* U* V* U* V* . . . .  ^
+	 * U* V* U* V* U* V* U* V* . . . .  |
+	 * U* V* U* V* U* V* U* V* . . . .  |
+	 * U* V* U* V* U* V* U* V* . . . .  UV_Scanlines
+	 * . . . . . . . . . . . . . . . .  |
+	 * . . . . . . . . . . . . . . . .  V
+	 * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
+	 *
+	 * Y_Stride = align(Width, 128)
+	 * UV_Stride = align(Width, 128)
+	 * Y_Scanlines = align(Height, 32)
+	 * UV_Scanlines = align(Height/2, 16)
+	 * Y_UBWC_Plane_size = align(Y_Stride * Y_Scanlines, 4096)
+	 * UV_UBWC_Plane_size = align(UV_Stride * UV_Scanlines, 4096)
+	 * Y_Meta_Stride = align(roundup(Width, Y_TileWidth), 64)
+	 * Y_Meta_Scanlines = align(roundup(Height, Y_TileHeight), 16)
+	 * Y_Meta_Plane_size = align(Y_Meta_Stride * Y_Meta_Scanlines, 4096)
+	 * UV_Meta_Stride = align(roundup(Width, UV_TileWidth), 64)
+	 * UV_Meta_Scanlines = align(roundup(Height, UV_TileHeight), 16)
+	 * UV_Meta_Plane_size = align(UV_Meta_Stride * UV_Meta_Scanlines, 4096)
+	 * Extradata = 8k
+	 *
+	 * Total size = align( Y_UBWC_Plane_size + UV_UBWC_Plane_size +
+	 *           Y_Meta_Plane_size + UV_Meta_Plane_size
+	 *           + max(Extradata, Y_Stride * 48), 4096)
+	 *
+	 *
+	 * (2) Venus NV12 UBWC Interlaced Buffer Format:
+	 * Compressed Macro-tile format for NV12 interlaced.
+	 * Contains 8 planes in the following order -
+	 * (A) Y_Meta_Top_Field_Plane
+	 * (B) Y_UBWC_Top_Field_Plane
+	 * (C) UV_Meta_Top_Field_Plane
+	 * (D) UV_UBWC_Top_Field_Plane
+	 * (E) Y_Meta_Bottom_Field_Plane
+	 * (F) Y_UBWC_Bottom_Field_Plane
+	 * (G) UV_Meta_Bottom_Field_Plane
+	 * (H) UV_UBWC_Bottom_Field_Plane
+	 * Y_Meta_Top_Field_Plane consists of meta information to decode
+	 * compressed tile data for Y_UBWC_Top_Field_Plane.
+	 * Y_UBWC_Top_Field_Plane consists of Y data in compressed macro-tile
+	 * format for top field of an interlaced frame.
+	 * UBWC decoder block will use the Y_Meta_Top_Field_Plane data together
+	 * with Y_UBWC_Top_Field_Plane data to produce loss-less uncompressed
+	 * 8 bit Y samples for top field of an interlaced frame.
+	 *
+	 * UV_Meta_Top_Field_Plane consists of meta information to decode
+	 * compressed tile data in UV_UBWC_Top_Field_Plane.
+	 * UV_UBWC_Top_Field_Plane consists of UV data in compressed macro-tile
+	 * format for top field of an interlaced frame.
+	 * UBWC decoder block will use UV_Meta_Top_Field_Plane data together
+	 * with UV_UBWC_Top_Field_Plane data to produce loss-less uncompressed
+	 * 8 bit subsampled color difference samples for top field of an
+	 * interlaced frame.
+	 *
+	 * Each tile in Y_UBWC_Top_Field_Plane/UV_UBWC_Top_Field_Plane is
+	 * independently decodable and randomly accessible. There is no
+	 * dependency between tiles.
+	 *
+	 * Y_Meta_Bottom_Field_Plane consists of meta information to decode
+	 * compressed tile data for Y_UBWC_Bottom_Field_Plane.
+	 * Y_UBWC_Bottom_Field_Plane consists of Y data in compressed macro-tile
+	 * format for bottom field of an interlaced frame.
+	 * UBWC decoder block will use the Y_Meta_Bottom_Field_Plane data
+	 * together with Y_UBWC_Bottom_Field_Plane data to produce loss-less
+	 * uncompressed 8 bit Y samples for bottom field of an interlaced frame.
+	 *
+	 * UV_Meta_Bottom_Field_Plane consists of meta information to decode
+	 * compressed tile data in UV_UBWC_Bottom_Field_Plane.
+	 * UV_UBWC_Bottom_Field_Plane consists of UV data in compressed
+	 * macro-tile format for bottom field of an interlaced frame.
+	 * UBWC decoder block will use UV_Meta_Bottom_Field_Plane data together
+	 * with UV_UBWC_Bottom_Field_Plane data to produce loss-less
+	 * uncompressed 8 bit subsampled color difference samples for bottom
+	 * field of an interlaced frame.
+	 *
+	 * Each tile in Y_UBWC_Bottom_Field_Plane/UV_UBWC_Bottom_Field_Plane is
+	 * independently decodable and randomly accessible. There is no
+	 * dependency between tiles.
+	 *
+	 * <-----Y_TF_Meta_Stride---->
+	 * <-------- Width ------>
+	 * M M M M M M M M M M M M . .      ^           ^
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . . Half_height      |
+	 * M M M M M M M M M M M M . .      |         Meta_Y_TF_Scanlines
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      V           |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . .                  V
+	 * <-Compressed tile Y_TF Stride->
+	 * <------- Width ------->
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  ^           ^
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Half_height  |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |        Macro_tile_Y_TF_Scanlines
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  V           |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . . . .              V
+	 * <----UV_TF_Meta_Stride---->
+	 * M M M M M M M M M M M M . .      ^
+	 * M M M M M M M M M M M M . .      |
+	 * M M M M M M M M M M M M . .      |
+	 * M M M M M M M M M M M M . .      M_UV_TF_Scanlines
+	 * . . . . . . . . . . . . . .      |
+	 * . . . . . . . . . . . . . .      V
+	 * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+	 * <-Compressed tile UV_TF Stride->
+	 * U* V* U* V* U* V* U* V* . . . .  ^
+	 * U* V* U* V* U* V* U* V* . . . .  |
+	 * U* V* U* V* U* V* U* V* . . . .  |
+	 * U* V* U* V* U* V* U* V* . . . .  UV_TF_Scanlines
+	 * . . . . . . . . . . . . . . . .  |
+	 * . . . . . . . . . . . . . . . .  V
+	 * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
+	 * <-----Y_BF_Meta_Stride---->
+	 * <-------- Width ------>
+	 * M M M M M M M M M M M M . .      ^           ^
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . . Half_height      |
+	 * M M M M M M M M M M M M . .      |         Meta_Y_BF_Scanlines
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      V           |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . .                  V
+	 * <-Compressed tile Y_BF Stride->
+	 * <------- Width ------->
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  ^           ^
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Half_height  |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |        Macro_tile_Y_BF_Scanlines
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  V           |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . . . .              V
+	 * <----UV_BF_Meta_Stride---->
+	 * M M M M M M M M M M M M . .      ^
+	 * M M M M M M M M M M M M . .      |
+	 * M M M M M M M M M M M M . .      |
+	 * M M M M M M M M M M M M . .      M_UV_BF_Scanlines
+	 * . . . . . . . . . . . . . .      |
+	 * . . . . . . . . . . . . . .      V
+	 * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+	 * <-Compressed tile UV_BF Stride->
+	 * U* V* U* V* U* V* U* V* . . . .  ^
+	 * U* V* U* V* U* V* U* V* . . . .  |
+	 * U* V* U* V* U* V* U* V* . . . .  |
+	 * U* V* U* V* U* V* U* V* . . . .  UV_BF_Scanlines
+	 * . . . . . . . . . . . . . . . .  |
+	 * . . . . . . . . . . . . . . . .  V
+	 * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
+	 *
+	 * Half_height = (Height+1)>>1
+	 * Y_TF_Stride = align(Width, 128)
+	 * UV_TF_Stride = align(Width, 128)
+	 * Y_TF_Scanlines = align(Half_height, 32)
+	 * UV_TF_Scanlines = align((Half_height+1)/2, 32)
+	 * Y_UBWC_TF_Plane_size = align(Y_TF_Stride * Y_TF_Scanlines, 4096)
+	 * UV_UBWC_TF_Plane_size = align(UV_TF_Stride * UV_TF_Scanlines, 4096)
+	 * Y_TF_Meta_Stride = align(roundup(Width, Y_TileWidth), 64)
+	 * Y_TF_Meta_Scanlines = align(roundup(Half_height, Y_TileHeight), 16)
+	 * Y_TF_Meta_Plane_size =
+	 *     align(Y_TF_Meta_Stride * Y_TF_Meta_Scanlines, 4096)
+	 * UV_TF_Meta_Stride = align(roundup(Width, UV_TileWidth), 64)
+	 * UV_TF_Meta_Scanlines = align(roundup(Half_height, UV_TileHeight), 16)
+	 * UV_TF_Meta_Plane_size =
+	 *     align(UV_TF_Meta_Stride * UV_TF_Meta_Scanlines, 4096)
+	 * Y_BF_Stride = align(Width, 128)
+	 * UV_BF_Stride = align(Width, 128)
+	 * Y_BF_Scanlines = align(Half_height, 32)
+	 * UV_BF_Scanlines = align((Half_height+1)/2, 32)
+	 * Y_UBWC_BF_Plane_size = align(Y_BF_Stride * Y_BF_Scanlines, 4096)
+	 * UV_UBWC_BF_Plane_size = align(UV_BF_Stride * UV_BF_Scanlines, 4096)
+	 * Y_BF_Meta_Stride = align(roundup(Width, Y_TileWidth), 64)
+	 * Y_BF_Meta_Scanlines = align(roundup(Half_height, Y_TileHeight), 16)
+	 * Y_BF_Meta_Plane_size =
+	 *     align(Y_BF_Meta_Stride * Y_BF_Meta_Scanlines, 4096)
+	 * UV_BF_Meta_Stride = align(roundup(Width, UV_TileWidth), 64)
+	 * UV_BF_Meta_Scanlines = align(roundup(Half_height, UV_TileHeight), 16)
+	 * UV_BF_Meta_Plane_size =
+	 *     align(UV_BF_Meta_Stride * UV_BF_Meta_Scanlines, 4096)
+	 * Extradata = 8k
+	 *
+	 * Total size = align( Y_UBWC_TF_Plane_size + UV_UBWC_TF_Plane_size +
+	 *           Y_TF_Meta_Plane_size + UV_TF_Meta_Plane_size +
+	 *			 Y_UBWC_BF_Plane_size + UV_UBWC_BF_Plane_size +
+	 *           Y_BF_Meta_Plane_size + UV_BF_Meta_Plane_size +
+	 *           + max(Extradata, Y_TF_Stride * 48), 4096)
+	 */
+	COLOR_FMT_NV12_UBWC,
+	/* Venus NV12 10-bit UBWC:
+	 * Compressed Macro-tile format for NV12.
+	 * Contains 4 planes in the following order -
+	 * (A) Y_Meta_Plane
+	 * (B) Y_UBWC_Plane
+	 * (C) UV_Meta_Plane
+	 * (D) UV_UBWC_Plane
+	 *
+	 * Y_Meta_Plane consists of meta information to decode compressed
+	 * tile data in Y_UBWC_Plane.
+	 * Y_UBWC_Plane consists of Y data in compressed macro-tile format.
+	 * UBWC decoder block will use the Y_Meta_Plane data together with
+	 * Y_UBWC_Plane data to produce loss-less uncompressed 10 bit Y samples.
+	 *
+	 * UV_Meta_Plane consists of meta information to decode compressed
+	 * tile data in UV_UBWC_Plane.
+	 * UV_UBWC_Plane consists of UV data in compressed macro-tile format.
+	 * UBWC decoder block will use UV_Meta_Plane data together with
+	 * UV_UBWC_Plane data to produce loss-less uncompressed 10 bit 2x2
+	 * subsampled color difference samples.
+	 *
+	 * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable
+	 * and randomly accessible. There is no dependency between tiles.
+	 *
+	 * <----- Y_Meta_Stride ----->
+	 * <-------- Width ------>
+	 * M M M M M M M M M M M M . .      ^           ^
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      Height      |
+	 * M M M M M M M M M M M M . .      |         Meta_Y_Scanlines
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      V           |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . .                  V
+	 * <--Compressed tile Y Stride--->
+	 * <------- Width ------->
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  ^           ^
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  Height      |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |        Macro_tile_Y_Scanlines
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  V           |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . . . .              V
+	 * <----- UV_Meta_Stride ---->
+	 * M M M M M M M M M M M M . .      ^
+	 * M M M M M M M M M M M M . .      |
+	 * M M M M M M M M M M M M . .      |
+	 * M M M M M M M M M M M M . .      M_UV_Scanlines
+	 * . . . . . . . . . . . . . .      |
+	 * . . . . . . . . . . . . . .      V
+	 * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+	 * <--Compressed tile UV Stride--->
+	 * U* V* U* V* U* V* U* V* . . . .  ^
+	 * U* V* U* V* U* V* U* V* . . . .  |
+	 * U* V* U* V* U* V* U* V* . . . .  |
+	 * U* V* U* V* U* V* U* V* . . . .  UV_Scanlines
+	 * . . . . . . . . . . . . . . . .  |
+	 * . . . . . . . . . . . . . . . .  V
+	 * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
+	 *
+	 *
+	 * Y_Stride = align(Width * 4/3, 128)
+	 * UV_Stride = align(Width * 4/3, 128)
+	 * Y_Scanlines = align(Height, 32)
+	 * UV_Scanlines = align(Height/2, 16)
+	 * Y_UBWC_Plane_Size = align(Y_Stride * Y_Scanlines, 4096)
+	 * UV_UBWC_Plane_Size = align(UV_Stride * UV_Scanlines, 4096)
+	 * Y_Meta_Stride = align(roundup(Width, Y_TileWidth), 64)
+	 * Y_Meta_Scanlines = align(roundup(Height, Y_TileHeight), 16)
+	 * Y_Meta_Plane_size = align(Y_Meta_Stride * Y_Meta_Scanlines, 4096)
+	 * UV_Meta_Stride = align(roundup(Width, UV_TileWidth), 64)
+	 * UV_Meta_Scanlines = align(roundup(Height, UV_TileHeight), 16)
+	 * UV_Meta_Plane_size = align(UV_Meta_Stride * UV_Meta_Scanlines, 4096)
+	 * Extradata = 8k
+	 *
+	 * Total size = align(Y_UBWC_Plane_size + UV_UBWC_Plane_size +
+	 *           Y_Meta_Plane_size + UV_Meta_Plane_size
+	 *           + max(Extradata, Y_Stride * 48), 4096)
+	 */
+	COLOR_FMT_NV12_BPP10_UBWC,
+	/* Venus RGBA8888 format:
+	 * Contains 1 plane in the following order -
+	 * (A) RGBA plane
+	 *
+	 * <-------- RGB_Stride -------->
+	 * <------- Width ------->
+	 * R R R R R R R R R R R R . . . .  ^           ^
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  Height      |
+	 * R R R R R R R R R R R R . . . .  |       RGB_Scanlines
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  V           |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              V
+	 *
+	 * RGB_Stride = align(Width * 4, 128)
+	 * RGB_Scanlines = align(Height, 32)
+	 * RGB_Plane_size = align(RGB_Stride * RGB_Scanlines, 4096)
+	 * Extradata = 8k
+	 *
+	 * Total size = align(RGB_Plane_size + Extradata, 4096)
+	 */
+	COLOR_FMT_RGBA8888,
+	/* Venus RGBA8888 UBWC format:
+	 * Contains 2 planes in the following order -
+	 * (A) Meta plane
+	 * (B) RGBA plane
+	 *
+	 * <--- RGB_Meta_Stride ---->
+	 * <-------- Width ------>
+	 * M M M M M M M M M M M M . .      ^           ^
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      Height      |
+	 * M M M M M M M M M M M M . .      |       Meta_RGB_Scanlines
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      V           |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . .                  V
+	 * <-------- RGB_Stride -------->
+	 * <------- Width ------->
+	 * R R R R R R R R R R R R . . . .  ^           ^
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  Height      |
+	 * R R R R R R R R R R R R . . . .  |       RGB_Scanlines
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  V           |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .    -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . . . .              V
+	 *
+	 * RGB_Stride = align(Width * 4, 128)
+	 * RGB_Scanlines = align(Height, 32)
+	 * RGB_Plane_size = align(RGB_Stride * RGB_Scanlines, 4096)
+	 * RGB_Meta_Stride = align(roundup(Width, RGB_TileWidth), 64)
+	 * RGB_Meta_Scanline = align(roundup(Height, RGB_TileHeight), 16)
+	 * RGB_Meta_Plane_size = align(RGB_Meta_Stride *
+	 *		RGB_Meta_Scanlines, 4096)
+	 * Extradata = 8k
+	 *
+	 * Total size = align(RGB_Meta_Plane_size + RGB_Plane_size +
+	 *		Extradata, 4096)
+	 */
+	COLOR_FMT_RGBA8888_UBWC,
+	/* Venus RGBA1010102 UBWC format:
+	 * Contains 2 planes in the following order -
+	 * (A) Meta plane
+	 * (B) RGBA plane
+	 *
+	 * <--- RGB_Meta_Stride ---->
+	 * <-------- Width ------>
+	 * M M M M M M M M M M M M . .      ^           ^
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      Height      |
+	 * M M M M M M M M M M M M . .      |       Meta_RGB_Scanlines
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      V           |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . .                  V
+	 * <-------- RGB_Stride -------->
+	 * <------- Width ------->
+	 * R R R R R R R R R R R R . . . .  ^           ^
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  Height      |
+	 * R R R R R R R R R R R R . . . .  |       RGB_Scanlines
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  V           |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .    -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . . . .              V
+	 *
+	 * RGB_Stride = align(Width * 4, 256)
+	 * RGB_Scanlines = align(Height, 16)
+	 * RGB_Plane_size = align(RGB_Stride * RGB_Scanlines, 4096)
+	 * RGB_Meta_Stride = align(roundup(Width, RGB_TileWidth), 64)
+	 * RGB_Meta_Scanline = align(roundup(Height, RGB_TileHeight), 16)
+	 * RGB_Meta_Plane_size = align(RGB_Meta_Stride *
+	 *		RGB_Meta_Scanlines, 4096)
+	 * Extradata = 8k
+	 *
+	 * Total size = align(RGB_Meta_Plane_size + RGB_Plane_size +
+	 *		Extradata, 4096)
+	 */
+	COLOR_FMT_RGBA1010102_UBWC,
+	/* Venus RGB565 UBWC format:
+	 * Contains 2 planes in the following order -
+	 * (A) Meta plane
+	 * (B) RGB plane
+	 *
+	 * <--- RGB_Meta_Stride ---->
+	 * <-------- Width ------>
+	 * M M M M M M M M M M M M . .      ^           ^
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      Height      |
+	 * M M M M M M M M M M M M . .      |       Meta_RGB_Scanlines
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      V           |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . .                  V
+	 * <-------- RGB_Stride -------->
+	 * <------- Width ------->
+	 * R R R R R R R R R R R R . . . .  ^           ^
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  Height      |
+	 * R R R R R R R R R R R R . . . .  |       RGB_Scanlines
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  |           |
+	 * R R R R R R R R R R R R . . . .  V           |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .    -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . . . .              V
+	 *
+	 * RGB_Stride = align(Width * 2, 128)
+	 * RGB_Scanlines = align(Height, 16)
+	 * RGB_Plane_size = align(RGB_Stride * RGB_Scanlines, 4096)
+	 * RGB_Meta_Stride = align(roundup(Width, RGB_TileWidth), 64)
+	 * RGB_Meta_Scanline = align(roundup(Height, RGB_TileHeight), 16)
+	 * RGB_Meta_Plane_size = align(RGB_Meta_Stride *
+	 *		RGB_Meta_Scanlines, 4096)
+	 * Extradata = 8k
+	 *
+	 * Total size = align(RGB_Meta_Plane_size + RGB_Plane_size +
+	 *		Extradata, 4096)
+	 */
+	COLOR_FMT_RGB565_UBWC,
+	/* P010 UBWC:
+	 * Compressed Macro-tile format for NV12.
+	 * Contains 4 planes in the following order -
+	 * (A) Y_Meta_Plane
+	 * (B) Y_UBWC_Plane
+	 * (C) UV_Meta_Plane
+	 * (D) UV_UBWC_Plane
+	 *
+	 * Y_Meta_Plane consists of meta information to decode compressed
+	 * tile data in Y_UBWC_Plane.
+	 * Y_UBWC_Plane consists of Y data in compressed macro-tile format.
+	 * UBWC decoder block will use the Y_Meta_Plane data together with
+	 * Y_UBWC_Plane data to produce loss-less uncompressed 10 bit Y samples.
+	 *
+	 * UV_Meta_Plane consists of meta information to decode compressed
+	 * tile data in UV_UBWC_Plane.
+	 * UV_UBWC_Plane consists of UV data in compressed macro-tile format.
+	 * UBWC decoder block will use UV_Meta_Plane data together with
+	 * UV_UBWC_Plane data to produce loss-less uncompressed 10 bit 2x2
+	 * subsampled color difference samples.
+	 *
+	 * Each tile in Y_UBWC_Plane/UV_UBWC_Plane is independently decodable
+	 * and randomly accessible. There is no dependency between tiles.
+	 *
+	 * <----- Y_Meta_Stride ----->
+	 * <-------- Width ------>
+	 * M M M M M M M M M M M M . .      ^           ^
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      Height      |
+	 * M M M M M M M M M M M M . .      |         Meta_Y_Scanlines
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      |           |
+	 * M M M M M M M M M M M M . .      V           |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .                  |
+	 * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . .                  V
+	 * <--Compressed tile Y Stride--->
+	 * <------- Width ------->
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  ^           ^
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  Height      |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |        Macro_tile_Y_Scanlines
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  |           |
+	 * Y* Y* Y* Y* Y* Y* Y* Y* . . . .  V           |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
+	 * . . . . . . . . . . . . . . . .              V
+	 * <----- UV_Meta_Stride ---->
+	 * M M M M M M M M M M M M . .      ^
+	 * M M M M M M M M M M M M . .      |
+	 * M M M M M M M M M M M M . .      |
+	 * M M M M M M M M M M M M . .      M_UV_Scanlines
+	 * . . . . . . . . . . . . . .      |
+	 * . . . . . . . . . . . . . .      V
+	 * . . . . . . . . . . . . . .      -------> Buffer size aligned to 4k
+	 * <--Compressed tile UV Stride--->
+	 * U* V* U* V* U* V* U* V* . . . .  ^
+	 * U* V* U* V* U* V* U* V* . . . .  |
+	 * U* V* U* V* U* V* U* V* . . . .  |
+	 * U* V* U* V* U* V* U* V* . . . .  UV_Scanlines
+	 * . . . . . . . . . . . . . . . .  |
+	 * . . . . . . . . . . . . . . . .  V
+	 * . . . . . . . . . . . . . . . .  -------> Buffer size aligned to 4k
+	 *
+	 *
+	 * Y_Stride = align(Width * 2, 256)
+	 * UV_Stride = align(Width * 2, 256)
+	 * Y_Scanlines = align(Height, 16)
+	 * UV_Scanlines = align(Height/2, 16)
+	 * Y_UBWC_Plane_Size = align(Y_Stride * Y_Scanlines, 4096)
+	 * UV_UBWC_Plane_Size = align(UV_Stride * UV_Scanlines, 4096)
+	 * Y_Meta_Stride = align(roundup(Width, Y_TileWidth), 64)
+	 * Y_Meta_Scanlines = align(roundup(Height, Y_TileHeight), 16)
+	 * Y_Meta_Plane_size = align(Y_Meta_Stride * Y_Meta_Scanlines, 4096)
+	 * UV_Meta_Stride = align(roundup(Width, UV_TileWidth), 64)
+	 * UV_Meta_Scanlines = align(roundup(Height, UV_TileHeight), 16)
+	 * UV_Meta_Plane_size = align(UV_Meta_Stride * UV_Meta_Scanlines, 4096)
+	 * Extradata = 8k
+	 *
+	 * Total size = align(Y_UBWC_Plane_size + UV_UBWC_Plane_size +
+	 *           Y_Meta_Plane_size + UV_Meta_Plane_size
+	 *           + max(Extradata, Y_Stride * 48), 4096)
+	 */
+	COLOR_FMT_P010_UBWC,
+	/* Venus P010:
+	 * YUV 4:2:0 image with a plane of 10 bit Y samples followed
+	 * by an interleaved U/V plane containing 10 bit 2x2 subsampled
+	 * colour difference samples.
+	 *
+	 * <-------- Y/UV_Stride -------->
+	 * <------- Width ------->
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  ^           ^
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  Height      |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |          Y_Scanlines
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  |           |
+	 * Y Y Y Y Y Y Y Y Y Y Y Y . . . .  V           |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              |
+	 * . . . . . . . . . . . . . . . .              V
+	 * U V U V U V U V U V U V . . . .  ^
+	 * U V U V U V U V U V U V . . . .  |
+	 * U V U V U V U V U V U V . . . .  |
+	 * U V U V U V U V U V U V . . . .  UV_Scanlines
+	 * . . . . . . . . . . . . . . . .  |
+	 * . . . . . . . . . . . . . . . .  V
+	 * . . . . . . . . . . . . . . . .  --> Buffer size alignment
+	 *
+	 * Y_Stride : Width * 2 aligned to 128
+	 * UV_Stride : Width * 2 aligned to 128
+	 * Y_Scanlines: Height aligned to 32
+	 * UV_Scanlines: Height/2 aligned to 16
+	 * Extradata: Arbitrary (software-imposed) padding
+	 * Total size = align((Y_Stride * Y_Scanlines
+	 *          + UV_Stride * UV_Scanlines
+	 *          + max(Extradata, Y_Stride * 8), 4096)
+	 */
+	COLOR_FMT_P010,
+};
+
+#define COLOR_FMT_RGBA1010102_UBWC	COLOR_FMT_RGBA1010102_UBWC
+#define COLOR_FMT_RGB565_UBWC		COLOR_FMT_RGB565_UBWC
+#define COLOR_FMT_P010_UBWC		COLOR_FMT_P010_UBWC
+#define COLOR_FMT_P010		COLOR_FMT_P010
+
+/*
+ * Function arguments:
+ * @color_fmt
+ * @width
+ * Progressive: width
+ * Interlaced: width
+ */
+static unsigned int VENUS_Y_STRIDE(int color_fmt, int width)
+{
+	unsigned int stride = 0;
+
+	if (!width)
+		return 0;
+
+	switch (color_fmt) {
+	case COLOR_FMT_NV21:
+	case COLOR_FMT_NV12:
+	case COLOR_FMT_NV12_MVTB:
+	case COLOR_FMT_NV12_UBWC:
+		stride = MSM_MEDIA_ALIGN(width, 128);
+		break;
+	case COLOR_FMT_NV12_BPP10_UBWC:
+		stride = MSM_MEDIA_ALIGN(width, 192);
+		stride = MSM_MEDIA_ALIGN(stride * 4 / 3, 256);
+		break;
+	case COLOR_FMT_P010_UBWC:
+		stride = MSM_MEDIA_ALIGN(width * 2, 256);
+		break;
+	case COLOR_FMT_P010:
+		stride = MSM_MEDIA_ALIGN(width * 2, 128);
+		break;
+	}
+
+	return stride;
+}
+
+/*
+ * Function arguments:
+ * @color_fmt
+ * @width
+ * Progressive: width
+ * Interlaced: width
+ */
+static unsigned int VENUS_UV_STRIDE(int color_fmt, int width)
+{
+	unsigned int stride = 0;
+
+	if (!width)
+		return 0;
+
+	switch (color_fmt) {
+	case COLOR_FMT_NV21:
+	case COLOR_FMT_NV12:
+	case COLOR_FMT_NV12_MVTB:
+	case COLOR_FMT_NV12_UBWC:
+		stride = MSM_MEDIA_ALIGN(width, 128);
+		break;
+	case COLOR_FMT_NV12_BPP10_UBWC:
+		stride = MSM_MEDIA_ALIGN(width, 192);
+		stride = MSM_MEDIA_ALIGN(stride * 4 / 3, 256);
+		break;
+	case COLOR_FMT_P010_UBWC:
+		stride = MSM_MEDIA_ALIGN(width * 2, 256);
+		break;
+	case COLOR_FMT_P010:
+		stride = MSM_MEDIA_ALIGN(width * 2, 128);
+		break;
+	}
+
+	return stride;
+}
+
+/*
+ * Function arguments:
+ * @color_fmt
+ * @height
+ * Progressive: height
+ * Interlaced: (height+1)>>1
+ */
+static unsigned int VENUS_Y_SCANLINES(int color_fmt, int height)
+{
+	unsigned int sclines = 0;
+
+	if (!height)
+		return 0;
+
+	switch (color_fmt) {
+	case COLOR_FMT_NV21:
+	case COLOR_FMT_NV12:
+	case COLOR_FMT_NV12_MVTB:
+	case COLOR_FMT_NV12_UBWC:
+	case COLOR_FMT_P010:
+		sclines = MSM_MEDIA_ALIGN(height, 32);
+		break;
+	case COLOR_FMT_NV12_BPP10_UBWC:
+	case COLOR_FMT_P010_UBWC:
+		sclines = MSM_MEDIA_ALIGN(height, 16);
+		break;
+	}
+
+	return sclines;
+}
+
+/*
+ * Function arguments:
+ * @color_fmt
+ * @height
+ * Progressive: height
+ * Interlaced: (height+1)>>1
+ */
+static unsigned int VENUS_UV_SCANLINES(int color_fmt, int height)
+{
+	unsigned int sclines = 0;
+
+	if (!height)
+		return 0;
+
+	switch (color_fmt) {
+	case COLOR_FMT_NV21:
+	case COLOR_FMT_NV12:
+	case COLOR_FMT_NV12_MVTB:
+	case COLOR_FMT_NV12_BPP10_UBWC:
+	case COLOR_FMT_P010_UBWC:
+	case COLOR_FMT_P010:
+		sclines = MSM_MEDIA_ALIGN((height + 1) >> 1, 16);
+		break;
+	case COLOR_FMT_NV12_UBWC:
+		sclines = MSM_MEDIA_ALIGN((height + 1) >> 1, 32);
+		break;
+	}
+
+	return sclines;
+}
+
+/*
+ * Function arguments:
+ * @color_fmt
+ * @width
+ * Progressive: width
+ * Interlaced: width
+ */
+static unsigned int VENUS_Y_META_STRIDE(int color_fmt, int width)
+{
+	int y_tile_width = 0, y_meta_stride;
+
+	if (!width)
+		return 0;
+
+	switch (color_fmt) {
+	case COLOR_FMT_NV12_UBWC:
+	case COLOR_FMT_P010_UBWC:
+		y_tile_width = 32;
+		break;
+	case COLOR_FMT_NV12_BPP10_UBWC:
+		y_tile_width = 48;
+		break;
+	default:
+		return 0;
+	}
+
+	y_meta_stride = MSM_MEDIA_ROUNDUP(width, y_tile_width);
+	return MSM_MEDIA_ALIGN(y_meta_stride, 64);
+}
+
+/*
+ * Function arguments:
+ * @color_fmt
+ * @height
+ * Progressive: height
+ * Interlaced: (height+1)>>1
+ */
+static unsigned int VENUS_Y_META_SCANLINES(int color_fmt, int height)
+{
+	int y_tile_height = 0, y_meta_scanlines;
+
+	if (!height)
+		return 0;
+
+	switch (color_fmt) {
+	case COLOR_FMT_NV12_UBWC:
+		y_tile_height = 8;
+		break;
+	case COLOR_FMT_NV12_BPP10_UBWC:
+	case COLOR_FMT_P010_UBWC:
+		y_tile_height = 4;
+		break;
+	default:
+		return 0;
+	}
+
+	y_meta_scanlines = MSM_MEDIA_ROUNDUP(height, y_tile_height);
+	return MSM_MEDIA_ALIGN(y_meta_scanlines, 16);
+}
+
+/*
+ * Function arguments:
+ * @color_fmt
+ * @width
+ * Progressive: width
+ * Interlaced: width
+ */
+static unsigned int VENUS_UV_META_STRIDE(int color_fmt, int width)
+{
+	int uv_tile_width = 0, uv_meta_stride;
+
+	if (!width)
+		return 0;
+
+	switch (color_fmt) {
+	case COLOR_FMT_NV12_UBWC:
+	case COLOR_FMT_P010_UBWC:
+		uv_tile_width = 16;
+		break;
+	case COLOR_FMT_NV12_BPP10_UBWC:
+		uv_tile_width = 24;
+		break;
+	default:
+		return 0;
+	}
+
+	uv_meta_stride = MSM_MEDIA_ROUNDUP((width+1)>>1, uv_tile_width);
+	return MSM_MEDIA_ALIGN(uv_meta_stride, 64);
+}
+
+/*
+ * Function arguments:
+ * @color_fmt
+ * @height
+ * Progressive: height
+ * Interlaced: (height+1)>>1
+ */
+static unsigned int VENUS_UV_META_SCANLINES(int color_fmt, int height)
+{
+	int uv_tile_height = 0, uv_meta_scanlines;
+
+	if (!height)
+		return 0;
+
+	switch (color_fmt) {
+	case COLOR_FMT_NV12_UBWC:
+		uv_tile_height = 8;
+		break;
+	case COLOR_FMT_NV12_BPP10_UBWC:
+	case COLOR_FMT_P010_UBWC:
+		uv_tile_height = 4;
+		break;
+	default:
+		return 0;
+	}
+
+	uv_meta_scanlines = MSM_MEDIA_ROUNDUP((height+1)>>1, uv_tile_height);
+	return MSM_MEDIA_ALIGN(uv_meta_scanlines, 16);
+}
+
+static unsigned int VENUS_RGB_STRIDE(int color_fmt, int width)
+{
+	unsigned int alignment = 0, bpp = 4;
+
+	if (!width)
+		return 0;
+
+	switch (color_fmt) {
+	case COLOR_FMT_RGBA8888:
+		alignment = 128;
+		break;
+	case COLOR_FMT_RGB565_UBWC:
+		alignment = 256;
+		bpp = 2;
+		break;
+	case COLOR_FMT_RGBA8888_UBWC:
+	case COLOR_FMT_RGBA1010102_UBWC:
+		alignment = 256;
+		break;
+	default:
+		return 0;
+	}
+
+	return MSM_MEDIA_ALIGN(width * bpp, alignment);
+}
+
+static unsigned int VENUS_RGB_SCANLINES(int color_fmt, int height)
+{
+	unsigned int alignment = 0;
+
+	if (!height)
+		return 0;
+
+	switch (color_fmt) {
+	case COLOR_FMT_RGBA8888:
+		alignment = 32;
+		break;
+	case COLOR_FMT_RGBA8888_UBWC:
+	case COLOR_FMT_RGBA1010102_UBWC:
+	case COLOR_FMT_RGB565_UBWC:
+		alignment = 16;
+		break;
+	default:
+		return 0;
+	}
+
+	return MSM_MEDIA_ALIGN(height, alignment);
+}
+
+static unsigned int VENUS_RGB_META_STRIDE(int color_fmt, int width)
+{
+	int rgb_meta_stride;
+
+	if (!width)
+		return 0;
+
+	switch (color_fmt) {
+	case COLOR_FMT_RGBA8888_UBWC:
+	case COLOR_FMT_RGBA1010102_UBWC:
+	case COLOR_FMT_RGB565_UBWC:
+		rgb_meta_stride = MSM_MEDIA_ROUNDUP(width, 16);
+		return MSM_MEDIA_ALIGN(rgb_meta_stride, 64);
+	}
+
+	return 0;
+}
+
+static unsigned int VENUS_RGB_META_SCANLINES(int color_fmt, int height)
+{
+	int rgb_meta_scanlines;
+
+	if (!height)
+		return 0;
+
+	switch (color_fmt) {
+	case COLOR_FMT_RGBA8888_UBWC:
+	case COLOR_FMT_RGBA1010102_UBWC:
+	case COLOR_FMT_RGB565_UBWC:
+		rgb_meta_scanlines = MSM_MEDIA_ROUNDUP(height, 4);
+		return MSM_MEDIA_ALIGN(rgb_meta_scanlines, 16);
+	}
+
+	return 0;
+}
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_crtc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_crtc.c
@@ -0,0 +1,667 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_flip_work.h>
+#include <drm/drm_managed.h>
+#include <drm/drm_mode.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_vblank.h>
+
+#include "mdp4_kms.h"
+#include "msm_gem.h"
+
+struct mdp4_crtc {
+	struct drm_crtc base;
+	char name[8];
+	int id;
+	int ovlp;
+	enum mdp4_dma dma;
+	bool enabled;
+
+	/* which mixer/encoder we route output to: */
+	int mixer;
+
+	struct {
+		spinlock_t lock;
+		bool stale;
+		uint32_t width, height;
+		uint32_t x, y;
+
+		/* next cursor to scan-out: */
+		uint32_t next_iova;
+		struct drm_gem_object *next_bo;
+
+		/* current cursor being scanned out: */
+		struct drm_gem_object *scanout_bo;
+	} cursor;
+
+
+	/* if there is a pending flip, these will be non-null: */
+	struct drm_pending_vblank_event *event;
+
+	/* Bits have been flushed at the last commit,
+	 * used to decide if a vsync has happened since last commit.
+	 */
+	u32 flushed_mask;
+
+#define PENDING_CURSOR 0x1
+#define PENDING_FLIP   0x2
+	atomic_t pending;
+
+	/* for unref'ing cursor bo's after scanout completes: */
+	struct drm_flip_work unref_cursor_work;
+
+	struct mdp_irq vblank;
+	struct mdp_irq err;
+};
+#define to_mdp4_crtc(x) container_of(x, struct mdp4_crtc, base)
+
+static struct mdp4_kms *get_kms(struct drm_crtc *crtc)
+{
+	struct msm_drm_private *priv = crtc->dev->dev_private;
+	return to_mdp4_kms(to_mdp_kms(priv->kms));
+}
+
+static void request_pending(struct drm_crtc *crtc, uint32_t pending)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+
+	atomic_or(pending, &mdp4_crtc->pending);
+	mdp_irq_register(&get_kms(crtc)->base, &mdp4_crtc->vblank);
+}
+
+static void crtc_flush(struct drm_crtc *crtc)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	struct mdp4_kms *mdp4_kms = get_kms(crtc);
+	struct drm_plane *plane;
+	uint32_t flush = 0;
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane);
+		flush |= pipe2flush(pipe_id);
+	}
+
+	flush |= ovlp2flush(mdp4_crtc->ovlp);
+
+	DBG("%s: flush=%08x", mdp4_crtc->name, flush);
+
+	mdp4_crtc->flushed_mask = flush;
+
+	mdp4_write(mdp4_kms, REG_MDP4_OVERLAY_FLUSH, flush);
+}
+
+/* if file!=NULL, this is preclose potential cancel-flip path */
+static void complete_flip(struct drm_crtc *crtc, struct drm_file *file)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	struct drm_pending_vblank_event *event;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	event = mdp4_crtc->event;
+	if (event) {
+		mdp4_crtc->event = NULL;
+		DBG("%s: send event: %p", mdp4_crtc->name, event);
+		drm_crtc_send_vblank_event(crtc, event);
+	}
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+static void unref_cursor_worker(struct drm_flip_work *work, void *val)
+{
+	struct mdp4_crtc *mdp4_crtc =
+		container_of(work, struct mdp4_crtc, unref_cursor_work);
+	struct mdp4_kms *mdp4_kms = get_kms(&mdp4_crtc->base);
+	struct msm_kms *kms = &mdp4_kms->base.base;
+
+	msm_gem_unpin_iova(val, kms->aspace);
+	drm_gem_object_put(val);
+}
+
+/* statically (for now) map planes to mixer stage (z-order): */
+static const int idxs[] = {
+		[VG1]  = 1,
+		[VG2]  = 2,
+		[RGB1] = 0,
+		[RGB2] = 0,
+		[RGB3] = 0,
+		[VG3]  = 3,
+		[VG4]  = 4,
+
+};
+
+/* setup mixer config, for which we need to consider all crtc's and
+ * the planes attached to them
+ *
+ * TODO may possibly need some extra locking here
+ */
+static void setup_mixer(struct mdp4_kms *mdp4_kms)
+{
+	struct drm_mode_config *config = &mdp4_kms->dev->mode_config;
+	struct drm_crtc *crtc;
+	uint32_t mixer_cfg = 0;
+	static const enum mdp_mixer_stage_id stages[] = {
+			STAGE_BASE, STAGE0, STAGE1, STAGE2, STAGE3,
+	};
+
+	list_for_each_entry(crtc, &config->crtc_list, head) {
+		struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+		struct drm_plane *plane;
+
+		drm_atomic_crtc_for_each_plane(plane, crtc) {
+			enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane);
+			int idx = idxs[pipe_id];
+			mixer_cfg = mixercfg(mixer_cfg, mdp4_crtc->mixer,
+					pipe_id, stages[idx]);
+		}
+	}
+
+	mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg);
+}
+
+static void blend_setup(struct drm_crtc *crtc)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	struct mdp4_kms *mdp4_kms = get_kms(crtc);
+	struct drm_plane *plane;
+	int i, ovlp = mdp4_crtc->ovlp;
+	bool alpha[4]= { false, false, false, false };
+
+	mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0);
+	mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0);
+	mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH0(ovlp), 0);
+	mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH1(ovlp), 0);
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		enum mdp4_pipe pipe_id = mdp4_plane_pipe(plane);
+		int idx = idxs[pipe_id];
+		if (idx > 0) {
+			const struct mdp_format *format =
+					to_mdp_format(msm_framebuffer_format(plane->state->fb));
+			alpha[idx-1] = format->alpha_enable;
+		}
+	}
+
+	for (i = 0; i < 4; i++) {
+		uint32_t op;
+
+		if (alpha[i]) {
+			op = MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_PIXEL) |
+					MDP4_OVLP_STAGE_OP_BG_ALPHA(FG_PIXEL) |
+					MDP4_OVLP_STAGE_OP_BG_INV_ALPHA;
+		} else {
+			op = MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_CONST) |
+					MDP4_OVLP_STAGE_OP_BG_ALPHA(BG_CONST);
+		}
+
+		mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_FG_ALPHA(ovlp, i), 0xff);
+		mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_BG_ALPHA(ovlp, i), 0x00);
+		mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_OP(ovlp, i), op);
+		mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_CO3(ovlp, i), 1);
+		mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW0(ovlp, i), 0);
+		mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW1(ovlp, i), 0);
+		mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH0(ovlp, i), 0);
+		mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0);
+	}
+
+	setup_mixer(mdp4_kms);
+}
+
+static void mdp4_crtc_mode_set_nofb(struct drm_crtc *crtc)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	struct mdp4_kms *mdp4_kms = get_kms(crtc);
+	enum mdp4_dma dma = mdp4_crtc->dma;
+	int ovlp = mdp4_crtc->ovlp;
+	struct drm_display_mode *mode;
+
+	if (WARN_ON(!crtc->state))
+		return;
+
+	mode = &crtc->state->adjusted_mode;
+
+	DBG("%s: set mode: " DRM_MODE_FMT,
+			mdp4_crtc->name, DRM_MODE_ARG(mode));
+
+	mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_SIZE(dma),
+			MDP4_DMA_SRC_SIZE_WIDTH(mode->hdisplay) |
+			MDP4_DMA_SRC_SIZE_HEIGHT(mode->vdisplay));
+
+	/* take data from pipe: */
+	mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_BASE(dma), 0);
+	mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_STRIDE(dma), 0);
+	mdp4_write(mdp4_kms, REG_MDP4_DMA_DST_SIZE(dma),
+			MDP4_DMA_DST_SIZE_WIDTH(0) |
+			MDP4_DMA_DST_SIZE_HEIGHT(0));
+
+	mdp4_write(mdp4_kms, REG_MDP4_OVLP_BASE(ovlp), 0);
+	mdp4_write(mdp4_kms, REG_MDP4_OVLP_SIZE(ovlp),
+			MDP4_OVLP_SIZE_WIDTH(mode->hdisplay) |
+			MDP4_OVLP_SIZE_HEIGHT(mode->vdisplay));
+	mdp4_write(mdp4_kms, REG_MDP4_OVLP_STRIDE(ovlp), 0);
+
+	mdp4_write(mdp4_kms, REG_MDP4_OVLP_CFG(ovlp), 1);
+
+	if (dma == DMA_E) {
+		mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(0), 0x00ff0000);
+		mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(1), 0x00ff0000);
+		mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(2), 0x00ff0000);
+	}
+}
+
+static void mdp4_crtc_atomic_disable(struct drm_crtc *crtc,
+				     struct drm_atomic_state *state)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	struct mdp4_kms *mdp4_kms = get_kms(crtc);
+	unsigned long flags;
+
+	DBG("%s", mdp4_crtc->name);
+
+	if (WARN_ON(!mdp4_crtc->enabled))
+		return;
+
+	/* Disable/save vblank irq handling before power is disabled */
+	drm_crtc_vblank_off(crtc);
+
+	mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err);
+	mdp4_disable(mdp4_kms);
+
+	if (crtc->state->event && !crtc->state->active) {
+		WARN_ON(mdp4_crtc->event);
+		spin_lock_irqsave(&mdp4_kms->dev->event_lock, flags);
+		drm_crtc_send_vblank_event(crtc, crtc->state->event);
+		crtc->state->event = NULL;
+		spin_unlock_irqrestore(&mdp4_kms->dev->event_lock, flags);
+	}
+
+	mdp4_crtc->enabled = false;
+}
+
+static void mdp4_crtc_atomic_enable(struct drm_crtc *crtc,
+				    struct drm_atomic_state *state)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	struct mdp4_kms *mdp4_kms = get_kms(crtc);
+
+	DBG("%s", mdp4_crtc->name);
+
+	if (WARN_ON(mdp4_crtc->enabled))
+		return;
+
+	mdp4_enable(mdp4_kms);
+
+	/* Restore vblank irq handling after power is enabled */
+	drm_crtc_vblank_on(crtc);
+
+	mdp_irq_register(&mdp4_kms->base, &mdp4_crtc->err);
+
+	crtc_flush(crtc);
+
+	mdp4_crtc->enabled = true;
+}
+
+static int mdp4_crtc_atomic_check(struct drm_crtc *crtc,
+		struct drm_atomic_state *state)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	DBG("%s: check", mdp4_crtc->name);
+	// TODO anything else to check?
+	return 0;
+}
+
+static void mdp4_crtc_atomic_begin(struct drm_crtc *crtc,
+				   struct drm_atomic_state *state)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	DBG("%s: begin", mdp4_crtc->name);
+}
+
+static void mdp4_crtc_atomic_flush(struct drm_crtc *crtc,
+				   struct drm_atomic_state *state)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	struct drm_device *dev = crtc->dev;
+	unsigned long flags;
+
+	DBG("%s: event: %p", mdp4_crtc->name, crtc->state->event);
+
+	WARN_ON(mdp4_crtc->event);
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	mdp4_crtc->event = crtc->state->event;
+	crtc->state->event = NULL;
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	blend_setup(crtc);
+	crtc_flush(crtc);
+	request_pending(crtc, PENDING_FLIP);
+}
+
+#define CURSOR_WIDTH 64
+#define CURSOR_HEIGHT 64
+
+/* called from IRQ to update cursor related registers (if needed).  The
+ * cursor registers, other than x/y position, appear not to be double
+ * buffered, and changing them other than from vblank seems to trigger
+ * underflow.
+ */
+static void update_cursor(struct drm_crtc *crtc)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	struct mdp4_kms *mdp4_kms = get_kms(crtc);
+	struct msm_kms *kms = &mdp4_kms->base.base;
+	enum mdp4_dma dma = mdp4_crtc->dma;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags);
+	if (mdp4_crtc->cursor.stale) {
+		struct drm_gem_object *next_bo = mdp4_crtc->cursor.next_bo;
+		struct drm_gem_object *prev_bo = mdp4_crtc->cursor.scanout_bo;
+		uint64_t iova = mdp4_crtc->cursor.next_iova;
+
+		if (next_bo) {
+			/* take a obj ref + iova ref when we start scanning out: */
+			drm_gem_object_get(next_bo);
+			msm_gem_get_and_pin_iova(next_bo, kms->aspace, &iova);
+
+			/* enable cursor: */
+			mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_SIZE(dma),
+					MDP4_DMA_CURSOR_SIZE_WIDTH(mdp4_crtc->cursor.width) |
+					MDP4_DMA_CURSOR_SIZE_HEIGHT(mdp4_crtc->cursor.height));
+			mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BASE(dma), iova);
+			mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BLEND_CONFIG(dma),
+					MDP4_DMA_CURSOR_BLEND_CONFIG_FORMAT(CURSOR_ARGB) |
+					MDP4_DMA_CURSOR_BLEND_CONFIG_CURSOR_EN);
+		} else {
+			/* disable cursor: */
+			mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BASE(dma),
+					mdp4_kms->blank_cursor_iova);
+		}
+
+		/* and drop the iova ref + obj rev when done scanning out: */
+		if (prev_bo)
+			drm_flip_work_queue(&mdp4_crtc->unref_cursor_work, prev_bo);
+
+		mdp4_crtc->cursor.scanout_bo = next_bo;
+		mdp4_crtc->cursor.stale = false;
+	}
+
+	mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_POS(dma),
+			MDP4_DMA_CURSOR_POS_X(mdp4_crtc->cursor.x) |
+			MDP4_DMA_CURSOR_POS_Y(mdp4_crtc->cursor.y));
+
+	spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags);
+}
+
+static int mdp4_crtc_cursor_set(struct drm_crtc *crtc,
+		struct drm_file *file_priv, uint32_t handle,
+		uint32_t width, uint32_t height)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	struct mdp4_kms *mdp4_kms = get_kms(crtc);
+	struct msm_kms *kms = &mdp4_kms->base.base;
+	struct drm_device *dev = crtc->dev;
+	struct drm_gem_object *cursor_bo, *old_bo;
+	unsigned long flags;
+	uint64_t iova;
+	int ret;
+
+	if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
+		DRM_DEV_ERROR(dev->dev, "bad cursor size: %dx%d\n", width, height);
+		return -EINVAL;
+	}
+
+	if (handle) {
+		cursor_bo = drm_gem_object_lookup(file_priv, handle);
+		if (!cursor_bo)
+			return -ENOENT;
+	} else {
+		cursor_bo = NULL;
+	}
+
+	if (cursor_bo) {
+		ret = msm_gem_get_and_pin_iova(cursor_bo, kms->aspace, &iova);
+		if (ret)
+			goto fail;
+	} else {
+		iova = 0;
+	}
+
+	spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags);
+	old_bo = mdp4_crtc->cursor.next_bo;
+	mdp4_crtc->cursor.next_bo   = cursor_bo;
+	mdp4_crtc->cursor.next_iova = iova;
+	mdp4_crtc->cursor.width     = width;
+	mdp4_crtc->cursor.height    = height;
+	mdp4_crtc->cursor.stale     = true;
+	spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags);
+
+	if (old_bo) {
+		/* drop our previous reference: */
+		drm_flip_work_queue(&mdp4_crtc->unref_cursor_work, old_bo);
+	}
+
+	request_pending(crtc, PENDING_CURSOR);
+
+	return 0;
+
+fail:
+	drm_gem_object_put(cursor_bo);
+	return ret;
+}
+
+static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags);
+	mdp4_crtc->cursor.x = x;
+	mdp4_crtc->cursor.y = y;
+	spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags);
+
+	crtc_flush(crtc);
+	request_pending(crtc, PENDING_CURSOR);
+
+	return 0;
+}
+
+static const struct drm_crtc_funcs mdp4_crtc_funcs = {
+	.set_config = drm_atomic_helper_set_config,
+	.page_flip = drm_atomic_helper_page_flip,
+	.cursor_set = mdp4_crtc_cursor_set,
+	.cursor_move = mdp4_crtc_cursor_move,
+	.reset = drm_atomic_helper_crtc_reset,
+	.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+	.enable_vblank  = msm_crtc_enable_vblank,
+	.disable_vblank = msm_crtc_disable_vblank,
+};
+
+static const struct drm_crtc_helper_funcs mdp4_crtc_helper_funcs = {
+	.mode_set_nofb = mdp4_crtc_mode_set_nofb,
+	.atomic_check = mdp4_crtc_atomic_check,
+	.atomic_begin = mdp4_crtc_atomic_begin,
+	.atomic_flush = mdp4_crtc_atomic_flush,
+	.atomic_enable = mdp4_crtc_atomic_enable,
+	.atomic_disable = mdp4_crtc_atomic_disable,
+};
+
+static void mdp4_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus)
+{
+	struct mdp4_crtc *mdp4_crtc = container_of(irq, struct mdp4_crtc, vblank);
+	struct drm_crtc *crtc = &mdp4_crtc->base;
+	struct msm_drm_private *priv = crtc->dev->dev_private;
+	unsigned pending;
+
+	mdp_irq_unregister(&get_kms(crtc)->base, &mdp4_crtc->vblank);
+
+	pending = atomic_xchg(&mdp4_crtc->pending, 0);
+
+	if (pending & PENDING_FLIP) {
+		complete_flip(crtc, NULL);
+	}
+
+	if (pending & PENDING_CURSOR) {
+		update_cursor(crtc);
+		drm_flip_work_commit(&mdp4_crtc->unref_cursor_work, priv->wq);
+	}
+}
+
+static void mdp4_crtc_err_irq(struct mdp_irq *irq, uint32_t irqstatus)
+{
+	struct mdp4_crtc *mdp4_crtc = container_of(irq, struct mdp4_crtc, err);
+	struct drm_crtc *crtc = &mdp4_crtc->base;
+	DBG("%s: error: %08x", mdp4_crtc->name, irqstatus);
+	crtc_flush(crtc);
+}
+
+static void mdp4_crtc_wait_for_flush_done(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	struct mdp4_kms *mdp4_kms = get_kms(crtc);
+	int ret;
+
+	ret = drm_crtc_vblank_get(crtc);
+	if (ret)
+		return;
+
+	ret = wait_event_timeout(dev->vblank[drm_crtc_index(crtc)].queue,
+		!(mdp4_read(mdp4_kms, REG_MDP4_OVERLAY_FLUSH) &
+			mdp4_crtc->flushed_mask),
+		msecs_to_jiffies(50));
+	if (ret <= 0)
+		dev_warn(dev->dev, "vblank time out, crtc=%d\n", mdp4_crtc->id);
+
+	mdp4_crtc->flushed_mask = 0;
+
+	drm_crtc_vblank_put(crtc);
+}
+
+uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	return mdp4_crtc->vblank.irqmask;
+}
+
+/* set dma config, ie. the format the encoder wants. */
+void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	struct mdp4_kms *mdp4_kms = get_kms(crtc);
+
+	mdp4_write(mdp4_kms, REG_MDP4_DMA_CONFIG(mdp4_crtc->dma), config);
+}
+
+/* set interface for routing crtc->encoder: */
+void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf, int mixer)
+{
+	struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+	struct mdp4_kms *mdp4_kms = get_kms(crtc);
+	uint32_t intf_sel;
+
+	intf_sel = mdp4_read(mdp4_kms, REG_MDP4_DISP_INTF_SEL);
+
+	switch (mdp4_crtc->dma) {
+	case DMA_P:
+		intf_sel &= ~MDP4_DISP_INTF_SEL_PRIM__MASK;
+		intf_sel |= MDP4_DISP_INTF_SEL_PRIM(intf);
+		break;
+	case DMA_S:
+		intf_sel &= ~MDP4_DISP_INTF_SEL_SEC__MASK;
+		intf_sel |= MDP4_DISP_INTF_SEL_SEC(intf);
+		break;
+	case DMA_E:
+		intf_sel &= ~MDP4_DISP_INTF_SEL_EXT__MASK;
+		intf_sel |= MDP4_DISP_INTF_SEL_EXT(intf);
+		break;
+	}
+
+	if (intf == INTF_DSI_VIDEO) {
+		intf_sel &= ~MDP4_DISP_INTF_SEL_DSI_CMD;
+		intf_sel |= MDP4_DISP_INTF_SEL_DSI_VIDEO;
+	} else if (intf == INTF_DSI_CMD) {
+		intf_sel &= ~MDP4_DISP_INTF_SEL_DSI_VIDEO;
+		intf_sel |= MDP4_DISP_INTF_SEL_DSI_CMD;
+	}
+
+	mdp4_crtc->mixer = mixer;
+
+	blend_setup(crtc);
+
+	DBG("%s: intf_sel=%08x", mdp4_crtc->name, intf_sel);
+
+	mdp4_write(mdp4_kms, REG_MDP4_DISP_INTF_SEL, intf_sel);
+}
+
+void mdp4_crtc_wait_for_commit_done(struct drm_crtc *crtc)
+{
+	/* wait_for_flush_done is the only case for now.
+	 * Later we will have command mode CRTC to wait for
+	 * other event.
+	 */
+	mdp4_crtc_wait_for_flush_done(crtc);
+}
+
+static const char *dma_names[] = {
+		"DMA_P", "DMA_S", "DMA_E",
+};
+
+static void mdp4_crtc_flip_cleanup(struct drm_device *dev, void *ptr)
+{
+	struct mdp4_crtc *mdp4_crtc = ptr;
+
+	drm_flip_work_cleanup(&mdp4_crtc->unref_cursor_work);
+}
+
+/* initialize crtc */
+struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
+		struct drm_plane *plane, int id, int ovlp_id,
+		enum mdp4_dma dma_id)
+{
+	struct drm_crtc *crtc = NULL;
+	struct mdp4_crtc *mdp4_crtc;
+	int ret;
+
+	mdp4_crtc = drmm_crtc_alloc_with_planes(dev, struct mdp4_crtc, base,
+						plane, NULL,
+						&mdp4_crtc_funcs, NULL);
+	if (IS_ERR(mdp4_crtc))
+		return ERR_CAST(mdp4_crtc);
+
+	crtc = &mdp4_crtc->base;
+
+	mdp4_crtc->id = id;
+
+	mdp4_crtc->ovlp = ovlp_id;
+	mdp4_crtc->dma = dma_id;
+
+	mdp4_crtc->vblank.irqmask = dma2irq(mdp4_crtc->dma);
+	mdp4_crtc->vblank.irq = mdp4_crtc_vblank_irq;
+
+	mdp4_crtc->err.irqmask = dma2err(mdp4_crtc->dma);
+	mdp4_crtc->err.irq = mdp4_crtc_err_irq;
+
+	snprintf(mdp4_crtc->name, sizeof(mdp4_crtc->name), "%s:%d",
+			dma_names[dma_id], ovlp_id);
+
+	spin_lock_init(&mdp4_crtc->cursor.lock);
+
+	drm_flip_work_init(&mdp4_crtc->unref_cursor_work,
+			"unref cursor", unref_cursor_worker);
+	ret = drmm_add_action_or_reset(dev, mdp4_crtc_flip_cleanup, mdp4_crtc);
+	if (ret)
+		return ERR_PTR(ret);
+
+	drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs);
+
+	return crtc;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_dsi_encoder.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_dsi_encoder.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, Inforce Computing. All rights reserved.
+ *
+ * Author: Vinay Simha <vinaysimha@inforcecomputing.com>
+ */
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_probe_helper.h>
+
+#include "mdp4_kms.h"
+
+#ifdef CONFIG_DRM_MSM_DSI
+
+struct mdp4_dsi_encoder {
+	struct drm_encoder base;
+	struct drm_panel *panel;
+	bool enabled;
+};
+#define to_mdp4_dsi_encoder(x) container_of(x, struct mdp4_dsi_encoder, base)
+
+static struct mdp4_kms *get_kms(struct drm_encoder *encoder)
+{
+	struct msm_drm_private *priv = encoder->dev->dev_private;
+	return to_mdp4_kms(to_mdp_kms(priv->kms));
+}
+
+static void mdp4_dsi_encoder_mode_set(struct drm_encoder *encoder,
+				      struct drm_display_mode *mode,
+				      struct drm_display_mode *adjusted_mode)
+{
+	struct mdp4_kms *mdp4_kms = get_kms(encoder);
+	uint32_t dsi_hsync_skew, vsync_period, vsync_len, ctrl_pol;
+	uint32_t display_v_start, display_v_end;
+	uint32_t hsync_start_x, hsync_end_x;
+
+	mode = adjusted_mode;
+
+	DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
+
+	ctrl_pol = 0;
+	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+		ctrl_pol |= MDP4_DSI_CTRL_POLARITY_HSYNC_LOW;
+	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+		ctrl_pol |= MDP4_DSI_CTRL_POLARITY_VSYNC_LOW;
+	/* probably need to get DATA_EN polarity from panel.. */
+
+	dsi_hsync_skew = 0;  /* get this from panel? */
+
+	hsync_start_x = (mode->htotal - mode->hsync_start);
+	hsync_end_x = mode->htotal - (mode->hsync_start - mode->hdisplay) - 1;
+
+	vsync_period = mode->vtotal * mode->htotal;
+	vsync_len = (mode->vsync_end - mode->vsync_start) * mode->htotal;
+	display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + dsi_hsync_skew;
+	display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + dsi_hsync_skew - 1;
+
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_HSYNC_CTRL,
+			MDP4_DSI_HSYNC_CTRL_PULSEW(mode->hsync_end - mode->hsync_start) |
+			MDP4_DSI_HSYNC_CTRL_PERIOD(mode->htotal));
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_VSYNC_PERIOD, vsync_period);
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_VSYNC_LEN, vsync_len);
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_DISPLAY_HCTRL,
+			MDP4_DSI_DISPLAY_HCTRL_START(hsync_start_x) |
+			MDP4_DSI_DISPLAY_HCTRL_END(hsync_end_x));
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_DISPLAY_VSTART, display_v_start);
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_DISPLAY_VEND, display_v_end);
+
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_CTRL_POLARITY, ctrl_pol);
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_UNDERFLOW_CLR,
+			MDP4_DSI_UNDERFLOW_CLR_ENABLE_RECOVERY |
+			MDP4_DSI_UNDERFLOW_CLR_COLOR(0xff));
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_ACTIVE_HCTL,
+			MDP4_DSI_ACTIVE_HCTL_START(0) |
+			MDP4_DSI_ACTIVE_HCTL_END(0));
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_HSYNC_SKEW, dsi_hsync_skew);
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_BORDER_CLR, 0);
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_ACTIVE_VSTART, 0);
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_ACTIVE_VEND, 0);
+}
+
+static void mdp4_dsi_encoder_disable(struct drm_encoder *encoder)
+{
+	struct mdp4_dsi_encoder *mdp4_dsi_encoder = to_mdp4_dsi_encoder(encoder);
+	struct mdp4_kms *mdp4_kms = get_kms(encoder);
+
+	if (!mdp4_dsi_encoder->enabled)
+		return;
+
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_ENABLE, 0);
+
+	/*
+	 * Wait for a vsync so we know the ENABLE=0 latched before
+	 * the (connector) source of the vsync's gets disabled,
+	 * otherwise we end up in a funny state if we re-enable
+	 * before the disable latches, which results that some of
+	 * the settings changes for the new modeset (like new
+	 * scanout buffer) don't latch properly..
+	 */
+	mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_PRIMARY_VSYNC);
+
+	mdp4_dsi_encoder->enabled = false;
+}
+
+static void mdp4_dsi_encoder_enable(struct drm_encoder *encoder)
+{
+	struct mdp4_dsi_encoder *mdp4_dsi_encoder = to_mdp4_dsi_encoder(encoder);
+	struct mdp4_kms *mdp4_kms = get_kms(encoder);
+
+	if (mdp4_dsi_encoder->enabled)
+		return;
+
+	mdp4_crtc_set_config(encoder->crtc,
+			MDP4_DMA_CONFIG_PACK_ALIGN_MSB |
+			MDP4_DMA_CONFIG_DEFLKR_EN |
+			MDP4_DMA_CONFIG_DITHER_EN |
+			MDP4_DMA_CONFIG_R_BPC(BPC8) |
+			MDP4_DMA_CONFIG_G_BPC(BPC8) |
+			MDP4_DMA_CONFIG_B_BPC(BPC8) |
+			MDP4_DMA_CONFIG_PACK(0x21));
+
+	mdp4_crtc_set_intf(encoder->crtc, INTF_DSI_VIDEO, 0);
+
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_ENABLE, 1);
+
+	mdp4_dsi_encoder->enabled = true;
+}
+
+static const struct drm_encoder_helper_funcs mdp4_dsi_encoder_helper_funcs = {
+	.mode_set = mdp4_dsi_encoder_mode_set,
+	.disable = mdp4_dsi_encoder_disable,
+	.enable = mdp4_dsi_encoder_enable,
+};
+
+/* initialize encoder */
+struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev)
+{
+	struct drm_encoder *encoder;
+	struct mdp4_dsi_encoder *mdp4_dsi_encoder;
+
+	mdp4_dsi_encoder = drmm_encoder_alloc(dev, struct mdp4_dsi_encoder, base,
+					      NULL, DRM_MODE_ENCODER_DSI, NULL);
+	if (IS_ERR(mdp4_dsi_encoder))
+		return ERR_CAST(mdp4_dsi_encoder);
+
+	encoder = &mdp4_dsi_encoder->base;
+
+	drm_encoder_helper_add(encoder, &mdp4_dsi_encoder_helper_funcs);
+
+	return encoder;
+}
+#endif /* CONFIG_DRM_MSM_DSI */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_dtv_encoder.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_dtv_encoder.c
@@ -0,0 +1,190 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_probe_helper.h>
+
+#include "mdp4_kms.h"
+
+struct mdp4_dtv_encoder {
+	struct drm_encoder base;
+	struct clk *hdmi_clk;
+	struct clk *mdp_clk;
+	unsigned long int pixclock;
+	bool enabled;
+	uint32_t bsc;
+};
+#define to_mdp4_dtv_encoder(x) container_of(x, struct mdp4_dtv_encoder, base)
+
+static struct mdp4_kms *get_kms(struct drm_encoder *encoder)
+{
+	struct msm_drm_private *priv = encoder->dev->dev_private;
+	return to_mdp4_kms(to_mdp_kms(priv->kms));
+}
+
+static void mdp4_dtv_encoder_mode_set(struct drm_encoder *encoder,
+		struct drm_display_mode *mode,
+		struct drm_display_mode *adjusted_mode)
+{
+	struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
+	struct mdp4_kms *mdp4_kms = get_kms(encoder);
+	uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol;
+	uint32_t display_v_start, display_v_end;
+	uint32_t hsync_start_x, hsync_end_x;
+
+	mode = adjusted_mode;
+
+	DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
+
+	mdp4_dtv_encoder->pixclock = mode->clock * 1000;
+
+	DBG("pixclock=%lu", mdp4_dtv_encoder->pixclock);
+
+	ctrl_pol = 0;
+	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+		ctrl_pol |= MDP4_DTV_CTRL_POLARITY_HSYNC_LOW;
+	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+		ctrl_pol |= MDP4_DTV_CTRL_POLARITY_VSYNC_LOW;
+	/* probably need to get DATA_EN polarity from panel.. */
+
+	dtv_hsync_skew = 0;  /* get this from panel? */
+
+	hsync_start_x = (mode->htotal - mode->hsync_start);
+	hsync_end_x = mode->htotal - (mode->hsync_start - mode->hdisplay) - 1;
+
+	vsync_period = mode->vtotal * mode->htotal;
+	vsync_len = (mode->vsync_end - mode->vsync_start) * mode->htotal;
+	display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + dtv_hsync_skew;
+	display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + dtv_hsync_skew - 1;
+
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_HSYNC_CTRL,
+			MDP4_DTV_HSYNC_CTRL_PULSEW(mode->hsync_end - mode->hsync_start) |
+			MDP4_DTV_HSYNC_CTRL_PERIOD(mode->htotal));
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_VSYNC_PERIOD, vsync_period);
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_VSYNC_LEN, vsync_len);
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_DISPLAY_HCTRL,
+			MDP4_DTV_DISPLAY_HCTRL_START(hsync_start_x) |
+			MDP4_DTV_DISPLAY_HCTRL_END(hsync_end_x));
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_DISPLAY_VSTART, display_v_start);
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_DISPLAY_VEND, display_v_end);
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_BORDER_CLR, 0);
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_UNDERFLOW_CLR,
+			MDP4_DTV_UNDERFLOW_CLR_ENABLE_RECOVERY |
+			MDP4_DTV_UNDERFLOW_CLR_COLOR(0xff));
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_HSYNC_SKEW, dtv_hsync_skew);
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_CTRL_POLARITY, ctrl_pol);
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_HCTL,
+			MDP4_DTV_ACTIVE_HCTL_START(0) |
+			MDP4_DTV_ACTIVE_HCTL_END(0));
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_VSTART, 0);
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_VEND, 0);
+}
+
+static void mdp4_dtv_encoder_disable(struct drm_encoder *encoder)
+{
+	struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
+	struct mdp4_kms *mdp4_kms = get_kms(encoder);
+
+	if (WARN_ON(!mdp4_dtv_encoder->enabled))
+		return;
+
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 0);
+
+	/*
+	 * Wait for a vsync so we know the ENABLE=0 latched before
+	 * the (connector) source of the vsync's gets disabled,
+	 * otherwise we end up in a funny state if we re-enable
+	 * before the disable latches, which results that some of
+	 * the settings changes for the new modeset (like new
+	 * scanout buffer) don't latch properly..
+	 */
+	mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_EXTERNAL_VSYNC);
+
+	clk_disable_unprepare(mdp4_dtv_encoder->hdmi_clk);
+	clk_disable_unprepare(mdp4_dtv_encoder->mdp_clk);
+
+	mdp4_dtv_encoder->enabled = false;
+}
+
+static void mdp4_dtv_encoder_enable(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
+	struct mdp4_kms *mdp4_kms = get_kms(encoder);
+	unsigned long pc = mdp4_dtv_encoder->pixclock;
+	int ret;
+
+	if (WARN_ON(mdp4_dtv_encoder->enabled))
+		return;
+
+	mdp4_crtc_set_config(encoder->crtc,
+			MDP4_DMA_CONFIG_R_BPC(BPC8) |
+			MDP4_DMA_CONFIG_G_BPC(BPC8) |
+			MDP4_DMA_CONFIG_B_BPC(BPC8) |
+			MDP4_DMA_CONFIG_PACK(0x21));
+	mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 1);
+
+	DBG("setting mdp_clk=%lu", pc);
+
+	ret = clk_set_rate(mdp4_dtv_encoder->mdp_clk, pc);
+	if (ret)
+		DRM_DEV_ERROR(dev->dev, "failed to set mdp_clk to %lu: %d\n",
+			pc, ret);
+
+	ret = clk_prepare_enable(mdp4_dtv_encoder->mdp_clk);
+	if (ret)
+		DRM_DEV_ERROR(dev->dev, "failed to enabled mdp_clk: %d\n", ret);
+
+	ret = clk_prepare_enable(mdp4_dtv_encoder->hdmi_clk);
+	if (ret)
+		DRM_DEV_ERROR(dev->dev, "failed to enable hdmi_clk: %d\n", ret);
+
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 1);
+
+	mdp4_dtv_encoder->enabled = true;
+}
+
+static const struct drm_encoder_helper_funcs mdp4_dtv_encoder_helper_funcs = {
+	.mode_set = mdp4_dtv_encoder_mode_set,
+	.enable = mdp4_dtv_encoder_enable,
+	.disable = mdp4_dtv_encoder_disable,
+};
+
+long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate)
+{
+	struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
+	return clk_round_rate(mdp4_dtv_encoder->mdp_clk, rate);
+}
+
+/* initialize encoder */
+struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev)
+{
+	struct drm_encoder *encoder;
+	struct mdp4_dtv_encoder *mdp4_dtv_encoder;
+
+	mdp4_dtv_encoder = drmm_encoder_alloc(dev, struct mdp4_dtv_encoder, base,
+					      NULL, DRM_MODE_ENCODER_TMDS, NULL);
+	if (IS_ERR(mdp4_dtv_encoder))
+		return ERR_CAST(mdp4_dtv_encoder);
+
+	encoder = &mdp4_dtv_encoder->base;
+
+	drm_encoder_helper_add(encoder, &mdp4_dtv_encoder_helper_funcs);
+
+	mdp4_dtv_encoder->hdmi_clk = devm_clk_get(dev->dev, "hdmi_clk");
+	if (IS_ERR(mdp4_dtv_encoder->hdmi_clk)) {
+		DRM_DEV_ERROR(dev->dev, "failed to get hdmi_clk\n");
+		return ERR_CAST(mdp4_dtv_encoder->hdmi_clk);
+	}
+
+	mdp4_dtv_encoder->mdp_clk = devm_clk_get(dev->dev, "tv_clk");
+	if (IS_ERR(mdp4_dtv_encoder->mdp_clk)) {
+		DRM_DEV_ERROR(dev->dev, "failed to get tv_clk\n");
+		return ERR_CAST(mdp4_dtv_encoder->mdp_clk);
+	}
+
+	return encoder;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_irq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_irq.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <drm/drm_print.h>
+#include <drm/drm_vblank.h>
+
+#include "msm_drv.h"
+#include "mdp4_kms.h"
+
+void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
+		uint32_t old_irqmask)
+{
+	mdp4_write(to_mdp4_kms(mdp_kms), REG_MDP4_INTR_CLEAR,
+		irqmask ^ (irqmask & old_irqmask));
+	mdp4_write(to_mdp4_kms(mdp_kms), REG_MDP4_INTR_ENABLE, irqmask);
+}
+
+static void mdp4_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus)
+{
+	struct mdp4_kms *mdp4_kms = container_of(irq, struct mdp4_kms, error_handler);
+	static DEFINE_RATELIMIT_STATE(rs, 5*HZ, 1);
+	extern bool dumpstate;
+
+	DRM_ERROR_RATELIMITED("errors: %08x\n", irqstatus);
+
+	if (dumpstate && __ratelimit(&rs)) {
+		struct drm_printer p = drm_info_printer(mdp4_kms->dev->dev);
+		drm_state_dump(mdp4_kms->dev, &p);
+	}
+}
+
+void mdp4_irq_preinstall(struct msm_kms *kms)
+{
+	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+	mdp4_enable(mdp4_kms);
+	mdp4_write(mdp4_kms, REG_MDP4_INTR_CLEAR, 0xffffffff);
+	mdp4_write(mdp4_kms, REG_MDP4_INTR_ENABLE, 0x00000000);
+	mdp4_disable(mdp4_kms);
+}
+
+int mdp4_irq_postinstall(struct msm_kms *kms)
+{
+	struct mdp_kms *mdp_kms = to_mdp_kms(kms);
+	struct mdp4_kms *mdp4_kms = to_mdp4_kms(mdp_kms);
+	struct mdp_irq *error_handler = &mdp4_kms->error_handler;
+
+	error_handler->irq = mdp4_irq_error_handler;
+	error_handler->irqmask = MDP4_IRQ_PRIMARY_INTF_UDERRUN |
+			MDP4_IRQ_EXTERNAL_INTF_UDERRUN;
+
+	mdp_irq_register(mdp_kms, error_handler);
+
+	return 0;
+}
+
+void mdp4_irq_uninstall(struct msm_kms *kms)
+{
+	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+	mdp4_enable(mdp4_kms);
+	mdp4_write(mdp4_kms, REG_MDP4_INTR_ENABLE, 0x00000000);
+	mdp4_disable(mdp4_kms);
+}
+
+irqreturn_t mdp4_irq(struct msm_kms *kms)
+{
+	struct mdp_kms *mdp_kms = to_mdp_kms(kms);
+	struct mdp4_kms *mdp4_kms = to_mdp4_kms(mdp_kms);
+	struct drm_device *dev = mdp4_kms->dev;
+	struct drm_crtc *crtc;
+	uint32_t status, enable;
+
+	enable = mdp4_read(mdp4_kms, REG_MDP4_INTR_ENABLE);
+	status = mdp4_read(mdp4_kms, REG_MDP4_INTR_STATUS) & enable;
+	mdp4_write(mdp4_kms, REG_MDP4_INTR_CLEAR, status);
+
+	VERB("status=%08x", status);
+
+	mdp_dispatch_irqs(mdp_kms, status);
+
+	drm_for_each_crtc(crtc, dev)
+		if (status & mdp4_crtc_vblank(crtc))
+			drm_crtc_handle_vblank(crtc);
+
+	return IRQ_HANDLED;
+}
+
+int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
+{
+	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+
+	mdp4_enable(mdp4_kms);
+	mdp_update_vblank_mask(to_mdp_kms(kms),
+			mdp4_crtc_vblank(crtc), true);
+	mdp4_disable(mdp4_kms);
+
+	return 0;
+}
+
+void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
+{
+	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+
+	mdp4_enable(mdp4_kms);
+	mdp_update_vblank_mask(to_mdp_kms(kms),
+			mdp4_crtc_vblank(crtc), false);
+	mdp4_disable(mdp4_kms);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_kms.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_kms.c
@@ -0,0 +1,589 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/delay.h>
+
+#include <drm/drm_vblank.h>
+
+#include "msm_drv.h"
+#include "msm_gem.h"
+#include "msm_mmu.h"
+#include "mdp4_kms.h"
+
+static int mdp4_hw_init(struct msm_kms *kms)
+{
+	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+	struct drm_device *dev = mdp4_kms->dev;
+	u32 dmap_cfg, vg_cfg;
+	unsigned long clk;
+
+	pm_runtime_get_sync(dev->dev);
+
+	if (mdp4_kms->rev > 1) {
+		mdp4_write(mdp4_kms, REG_MDP4_CS_CONTROLLER0, 0x0707ffff);
+		mdp4_write(mdp4_kms, REG_MDP4_CS_CONTROLLER1, 0x03073f3f);
+	}
+
+	mdp4_write(mdp4_kms, REG_MDP4_PORTMAP_MODE, 0x3);
+
+	/* max read pending cmd config, 3 pending requests: */
+	mdp4_write(mdp4_kms, REG_MDP4_READ_CNFG, 0x02222);
+
+	clk = clk_get_rate(mdp4_kms->clk);
+
+	if ((mdp4_kms->rev >= 1) || (clk >= 90000000)) {
+		dmap_cfg = 0x47;     /* 16 bytes-burst x 8 req */
+		vg_cfg = 0x47;       /* 16 bytes-burs x 8 req */
+	} else {
+		dmap_cfg = 0x27;     /* 8 bytes-burst x 8 req */
+		vg_cfg = 0x43;       /* 16 bytes-burst x 4 req */
+	}
+
+	DBG("fetch config: dmap=%02x, vg=%02x", dmap_cfg, vg_cfg);
+
+	mdp4_write(mdp4_kms, REG_MDP4_DMA_FETCH_CONFIG(DMA_P), dmap_cfg);
+	mdp4_write(mdp4_kms, REG_MDP4_DMA_FETCH_CONFIG(DMA_E), dmap_cfg);
+
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_FETCH_CONFIG(VG1), vg_cfg);
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_FETCH_CONFIG(VG2), vg_cfg);
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_FETCH_CONFIG(RGB1), vg_cfg);
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_FETCH_CONFIG(RGB2), vg_cfg);
+
+	if (mdp4_kms->rev >= 2)
+		mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG_UPDATE_METHOD, 1);
+	mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, 0);
+
+	/* disable CSC matrix / YUV by default: */
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(VG1), 0);
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(VG2), 0);
+	mdp4_write(mdp4_kms, REG_MDP4_DMA_P_OP_MODE, 0);
+	mdp4_write(mdp4_kms, REG_MDP4_DMA_S_OP_MODE, 0);
+	mdp4_write(mdp4_kms, REG_MDP4_OVLP_CSC_CONFIG(1), 0);
+	mdp4_write(mdp4_kms, REG_MDP4_OVLP_CSC_CONFIG(2), 0);
+
+	if (mdp4_kms->rev > 1)
+		mdp4_write(mdp4_kms, REG_MDP4_RESET_STATUS, 1);
+
+	pm_runtime_put_sync(dev->dev);
+
+	return 0;
+}
+
+static void mdp4_enable_commit(struct msm_kms *kms)
+{
+	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+	mdp4_enable(mdp4_kms);
+}
+
+static void mdp4_disable_commit(struct msm_kms *kms)
+{
+	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+	mdp4_disable(mdp4_kms);
+}
+
+static void mdp4_flush_commit(struct msm_kms *kms, unsigned crtc_mask)
+{
+	/* TODO */
+}
+
+static void mdp4_wait_flush(struct msm_kms *kms, unsigned crtc_mask)
+{
+	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+	struct drm_crtc *crtc;
+
+	for_each_crtc_mask(mdp4_kms->dev, crtc, crtc_mask)
+		mdp4_crtc_wait_for_commit_done(crtc);
+}
+
+static void mdp4_complete_commit(struct msm_kms *kms, unsigned crtc_mask)
+{
+}
+
+static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate,
+		struct drm_encoder *encoder)
+{
+	/* if we had >1 encoder, we'd need something more clever: */
+	switch (encoder->encoder_type) {
+	case DRM_MODE_ENCODER_TMDS:
+		return mdp4_dtv_round_pixclk(encoder, rate);
+	case DRM_MODE_ENCODER_LVDS:
+	case DRM_MODE_ENCODER_DSI:
+	default:
+		return rate;
+	}
+}
+
+static void mdp4_destroy(struct msm_kms *kms)
+{
+	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
+	struct device *dev = mdp4_kms->dev->dev;
+	struct msm_gem_address_space *aspace = kms->aspace;
+
+	if (mdp4_kms->blank_cursor_iova)
+		msm_gem_unpin_iova(mdp4_kms->blank_cursor_bo, kms->aspace);
+	drm_gem_object_put(mdp4_kms->blank_cursor_bo);
+
+	if (aspace) {
+		aspace->mmu->funcs->detach(aspace->mmu);
+		msm_gem_address_space_put(aspace);
+	}
+
+	if (mdp4_kms->rpm_enabled)
+		pm_runtime_disable(dev);
+
+	mdp_kms_destroy(&mdp4_kms->base);
+}
+
+static const struct mdp_kms_funcs kms_funcs = {
+	.base = {
+		.hw_init         = mdp4_hw_init,
+		.irq_preinstall  = mdp4_irq_preinstall,
+		.irq_postinstall = mdp4_irq_postinstall,
+		.irq_uninstall   = mdp4_irq_uninstall,
+		.irq             = mdp4_irq,
+		.enable_vblank   = mdp4_enable_vblank,
+		.disable_vblank  = mdp4_disable_vblank,
+		.enable_commit   = mdp4_enable_commit,
+		.disable_commit  = mdp4_disable_commit,
+		.flush_commit    = mdp4_flush_commit,
+		.wait_flush      = mdp4_wait_flush,
+		.complete_commit = mdp4_complete_commit,
+		.get_format      = mdp_get_format,
+		.round_pixclk    = mdp4_round_pixclk,
+		.destroy         = mdp4_destroy,
+	},
+	.set_irqmask         = mdp4_set_irqmask,
+};
+
+int mdp4_disable(struct mdp4_kms *mdp4_kms)
+{
+	DBG("");
+
+	clk_disable_unprepare(mdp4_kms->clk);
+	clk_disable_unprepare(mdp4_kms->pclk);
+	clk_disable_unprepare(mdp4_kms->lut_clk);
+	clk_disable_unprepare(mdp4_kms->axi_clk);
+
+	return 0;
+}
+
+int mdp4_enable(struct mdp4_kms *mdp4_kms)
+{
+	DBG("");
+
+	clk_prepare_enable(mdp4_kms->clk);
+	clk_prepare_enable(mdp4_kms->pclk);
+	clk_prepare_enable(mdp4_kms->lut_clk);
+	clk_prepare_enable(mdp4_kms->axi_clk);
+
+	return 0;
+}
+
+
+static int mdp4_modeset_init_intf(struct mdp4_kms *mdp4_kms,
+				  int intf_type)
+{
+	struct drm_device *dev = mdp4_kms->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct drm_encoder *encoder;
+	struct drm_connector *connector;
+	struct device_node *panel_node;
+	int dsi_id;
+	int ret;
+
+	switch (intf_type) {
+	case DRM_MODE_ENCODER_LVDS:
+		/*
+		 * bail out early if there is no panel node (no need to
+		 * initialize LCDC encoder and LVDS connector)
+		 */
+		panel_node = of_graph_get_remote_node(dev->dev->of_node, 0, 0);
+		if (!panel_node)
+			return 0;
+
+		encoder = mdp4_lcdc_encoder_init(dev, panel_node);
+		if (IS_ERR(encoder)) {
+			DRM_DEV_ERROR(dev->dev, "failed to construct LCDC encoder\n");
+			of_node_put(panel_node);
+			return PTR_ERR(encoder);
+		}
+
+		/* LCDC can be hooked to DMA_P (TODO: Add DMA_S later?) */
+		encoder->possible_crtcs = 1 << DMA_P;
+
+		connector = mdp4_lvds_connector_init(dev, panel_node, encoder);
+		if (IS_ERR(connector)) {
+			DRM_DEV_ERROR(dev->dev, "failed to initialize LVDS connector\n");
+			of_node_put(panel_node);
+			return PTR_ERR(connector);
+		}
+
+		break;
+	case DRM_MODE_ENCODER_TMDS:
+		encoder = mdp4_dtv_encoder_init(dev);
+		if (IS_ERR(encoder)) {
+			DRM_DEV_ERROR(dev->dev, "failed to construct DTV encoder\n");
+			return PTR_ERR(encoder);
+		}
+
+		/* DTV can be hooked to DMA_E: */
+		encoder->possible_crtcs = 1 << 1;
+
+		if (priv->hdmi) {
+			/* Construct bridge/connector for HDMI: */
+			ret = msm_hdmi_modeset_init(priv->hdmi, dev, encoder);
+			if (ret) {
+				DRM_DEV_ERROR(dev->dev, "failed to initialize HDMI: %d\n", ret);
+				return ret;
+			}
+		}
+
+		break;
+	case DRM_MODE_ENCODER_DSI:
+		/* only DSI1 supported for now */
+		dsi_id = 0;
+
+		if (!priv->dsi[dsi_id])
+			break;
+
+		encoder = mdp4_dsi_encoder_init(dev);
+		if (IS_ERR(encoder)) {
+			ret = PTR_ERR(encoder);
+			DRM_DEV_ERROR(dev->dev,
+				"failed to construct DSI encoder: %d\n", ret);
+			return ret;
+		}
+
+		/* TODO: Add DMA_S later? */
+		encoder->possible_crtcs = 1 << DMA_P;
+
+		ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, encoder);
+		if (ret) {
+			DRM_DEV_ERROR(dev->dev, "failed to initialize DSI: %d\n",
+				ret);
+			return ret;
+		}
+
+		break;
+	default:
+		DRM_DEV_ERROR(dev->dev, "Invalid or unsupported interface\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int modeset_init(struct mdp4_kms *mdp4_kms)
+{
+	struct drm_device *dev = mdp4_kms->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct drm_plane *plane;
+	struct drm_crtc *crtc;
+	int i, ret;
+	static const enum mdp4_pipe rgb_planes[] = {
+		RGB1, RGB2,
+	};
+	static const enum mdp4_pipe vg_planes[] = {
+		VG1, VG2,
+	};
+	static const enum mdp4_dma mdp4_crtcs[] = {
+		DMA_P, DMA_E,
+	};
+	static const char * const mdp4_crtc_names[] = {
+		"DMA_P", "DMA_E",
+	};
+	static const int mdp4_intfs[] = {
+		DRM_MODE_ENCODER_LVDS,
+		DRM_MODE_ENCODER_DSI,
+		DRM_MODE_ENCODER_TMDS,
+	};
+
+	/* construct non-private planes: */
+	for (i = 0; i < ARRAY_SIZE(vg_planes); i++) {
+		plane = mdp4_plane_init(dev, vg_planes[i], false);
+		if (IS_ERR(plane)) {
+			DRM_DEV_ERROR(dev->dev,
+				"failed to construct plane for VG%d\n", i + 1);
+			ret = PTR_ERR(plane);
+			goto fail;
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(mdp4_crtcs); i++) {
+		plane = mdp4_plane_init(dev, rgb_planes[i], true);
+		if (IS_ERR(plane)) {
+			DRM_DEV_ERROR(dev->dev,
+				"failed to construct plane for RGB%d\n", i + 1);
+			ret = PTR_ERR(plane);
+			goto fail;
+		}
+
+		crtc  = mdp4_crtc_init(dev, plane, priv->num_crtcs, i,
+				mdp4_crtcs[i]);
+		if (IS_ERR(crtc)) {
+			DRM_DEV_ERROR(dev->dev, "failed to construct crtc for %s\n",
+				mdp4_crtc_names[i]);
+			ret = PTR_ERR(crtc);
+			goto fail;
+		}
+
+		priv->num_crtcs++;
+	}
+
+	/*
+	 * we currently set up two relatively fixed paths:
+	 *
+	 * LCDC/LVDS path: RGB1 -> DMA_P -> LCDC -> LVDS
+	 *			or
+	 * DSI path: RGB1 -> DMA_P -> DSI1 -> DSI Panel
+	 *
+	 * DTV/HDMI path: RGB2 -> DMA_E -> DTV -> HDMI
+	 */
+
+	for (i = 0; i < ARRAY_SIZE(mdp4_intfs); i++) {
+		ret = mdp4_modeset_init_intf(mdp4_kms, mdp4_intfs[i]);
+		if (ret) {
+			DRM_DEV_ERROR(dev->dev, "failed to initialize intf: %d, %d\n",
+				i, ret);
+			goto fail;
+		}
+	}
+
+	return 0;
+
+fail:
+	return ret;
+}
+
+static void read_mdp_hw_revision(struct mdp4_kms *mdp4_kms,
+				 u32 *major, u32 *minor)
+{
+	struct drm_device *dev = mdp4_kms->dev;
+	u32 version;
+
+	mdp4_enable(mdp4_kms);
+	version = mdp4_read(mdp4_kms, REG_MDP4_VERSION);
+	mdp4_disable(mdp4_kms);
+
+	*major = FIELD(version, MDP4_VERSION_MAJOR);
+	*minor = FIELD(version, MDP4_VERSION_MINOR);
+
+	DRM_DEV_INFO(dev->dev, "MDP4 version v%d.%d", *major, *minor);
+}
+
+static int mdp4_kms_init(struct drm_device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev->dev);
+	struct msm_drm_private *priv = dev->dev_private;
+	struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(priv->kms));
+	struct msm_kms *kms = NULL;
+	struct msm_mmu *mmu;
+	struct msm_gem_address_space *aspace;
+	int ret;
+	u32 major, minor;
+	unsigned long max_clk;
+
+	/* TODO: Chips that aren't apq8064 have a 200 Mhz max_clk */
+	max_clk = 266667000;
+
+	ret = mdp_kms_init(&mdp4_kms->base, &kms_funcs);
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev, "failed to init kms\n");
+		goto fail;
+	}
+
+	kms = priv->kms;
+
+	mdp4_kms->dev = dev;
+
+	if (mdp4_kms->vdd) {
+		ret = regulator_enable(mdp4_kms->vdd);
+		if (ret) {
+			DRM_DEV_ERROR(dev->dev, "failed to enable regulator vdd: %d\n", ret);
+			goto fail;
+		}
+	}
+
+	clk_set_rate(mdp4_kms->clk, max_clk);
+
+	read_mdp_hw_revision(mdp4_kms, &major, &minor);
+
+	if (major != 4) {
+		DRM_DEV_ERROR(dev->dev, "unexpected MDP version: v%d.%d\n",
+			      major, minor);
+		ret = -ENXIO;
+		goto fail;
+	}
+
+	mdp4_kms->rev = minor;
+
+	if (mdp4_kms->rev >= 2) {
+		if (!mdp4_kms->lut_clk) {
+			DRM_DEV_ERROR(dev->dev, "failed to get lut_clk\n");
+			ret = -ENODEV;
+			goto fail;
+		}
+		clk_set_rate(mdp4_kms->lut_clk, max_clk);
+	}
+
+	pm_runtime_enable(dev->dev);
+	mdp4_kms->rpm_enabled = true;
+
+	/* make sure things are off before attaching iommu (bootloader could
+	 * have left things on, in which case we'll start getting faults if
+	 * we don't disable):
+	 */
+	mdp4_enable(mdp4_kms);
+	mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 0);
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0);
+	mdp4_write(mdp4_kms, REG_MDP4_DSI_ENABLE, 0);
+	mdp4_disable(mdp4_kms);
+	mdelay(16);
+
+	mmu = msm_iommu_new(&pdev->dev, 0);
+	if (IS_ERR(mmu)) {
+		ret = PTR_ERR(mmu);
+		goto fail;
+	} else if (!mmu) {
+		DRM_DEV_INFO(dev->dev, "no iommu, fallback to phys "
+				"contig buffers for scanout\n");
+		aspace = NULL;
+	} else {
+		aspace  = msm_gem_address_space_create(mmu,
+			"mdp4", 0x1000, 0x100000000 - 0x1000);
+
+		if (IS_ERR(aspace)) {
+			if (!IS_ERR(mmu))
+				mmu->funcs->destroy(mmu);
+			ret = PTR_ERR(aspace);
+			goto fail;
+		}
+
+		kms->aspace = aspace;
+	}
+
+	ret = modeset_init(mdp4_kms);
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev, "modeset_init failed: %d\n", ret);
+		goto fail;
+	}
+
+	mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC | MSM_BO_SCANOUT);
+	if (IS_ERR(mdp4_kms->blank_cursor_bo)) {
+		ret = PTR_ERR(mdp4_kms->blank_cursor_bo);
+		DRM_DEV_ERROR(dev->dev, "could not allocate blank-cursor bo: %d\n", ret);
+		mdp4_kms->blank_cursor_bo = NULL;
+		goto fail;
+	}
+
+	ret = msm_gem_get_and_pin_iova(mdp4_kms->blank_cursor_bo, kms->aspace,
+			&mdp4_kms->blank_cursor_iova);
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev, "could not pin blank-cursor bo: %d\n", ret);
+		goto fail;
+	}
+
+	dev->mode_config.min_width = 0;
+	dev->mode_config.min_height = 0;
+	dev->mode_config.max_width = 2048;
+	dev->mode_config.max_height = 2048;
+
+	return 0;
+
+fail:
+	if (kms)
+		mdp4_destroy(kms);
+
+	return ret;
+}
+
+static const struct dev_pm_ops mdp4_pm_ops = {
+	.prepare = msm_kms_pm_prepare,
+	.complete = msm_kms_pm_complete,
+};
+
+static int mdp4_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mdp4_kms *mdp4_kms;
+	int irq;
+
+	mdp4_kms = devm_kzalloc(dev, sizeof(*mdp4_kms), GFP_KERNEL);
+	if (!mdp4_kms)
+		return dev_err_probe(dev, -ENOMEM, "failed to allocate kms\n");
+
+	mdp4_kms->mmio = msm_ioremap(pdev, NULL);
+	if (IS_ERR(mdp4_kms->mmio))
+		return PTR_ERR(mdp4_kms->mmio);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return dev_err_probe(dev, irq, "failed to get irq\n");
+
+	mdp4_kms->base.base.irq = irq;
+
+	/* NOTE: driver for this regulator still missing upstream.. use
+	 * _get_exclusive() and ignore the error if it does not exist
+	 * (and hope that the bootloader left it on for us)
+	 */
+	mdp4_kms->vdd = devm_regulator_get_exclusive(&pdev->dev, "vdd");
+	if (IS_ERR(mdp4_kms->vdd))
+		mdp4_kms->vdd = NULL;
+
+	mdp4_kms->clk = devm_clk_get(&pdev->dev, "core_clk");
+	if (IS_ERR(mdp4_kms->clk))
+		return dev_err_probe(dev, PTR_ERR(mdp4_kms->clk), "failed to get core_clk\n");
+
+	mdp4_kms->pclk = devm_clk_get(&pdev->dev, "iface_clk");
+	if (IS_ERR(mdp4_kms->pclk))
+		mdp4_kms->pclk = NULL;
+
+	mdp4_kms->axi_clk = devm_clk_get(&pdev->dev, "bus_clk");
+	if (IS_ERR(mdp4_kms->axi_clk))
+		return dev_err_probe(dev, PTR_ERR(mdp4_kms->axi_clk), "failed to get axi_clk\n");
+
+	/*
+	 * This is required for revn >= 2. Handle errors here and let the kms
+	 * init bail out if the clock is not provided.
+	 */
+	mdp4_kms->lut_clk = devm_clk_get_optional(&pdev->dev, "lut_clk");
+	if (IS_ERR(mdp4_kms->lut_clk))
+		return dev_err_probe(dev, PTR_ERR(mdp4_kms->lut_clk), "failed to get lut_clk\n");
+
+	return msm_drv_probe(&pdev->dev, mdp4_kms_init, &mdp4_kms->base.base);
+}
+
+static void mdp4_remove(struct platform_device *pdev)
+{
+	component_master_del(&pdev->dev, &msm_drm_ops);
+}
+
+static const struct of_device_id mdp4_dt_match[] = {
+	{ .compatible = "qcom,mdp4" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mdp4_dt_match);
+
+static struct platform_driver mdp4_platform_driver = {
+	.probe      = mdp4_probe,
+	.remove_new = mdp4_remove,
+	.shutdown   = msm_kms_shutdown,
+	.driver     = {
+		.name   = "mdp4",
+		.of_match_table = mdp4_dt_match,
+		.pm     = &mdp4_pm_ops,
+	},
+};
+
+void __init msm_mdp4_register(void)
+{
+	platform_driver_register(&mdp4_platform_driver);
+}
+
+void __exit msm_mdp4_unregister(void)
+{
+	platform_driver_unregister(&mdp4_platform_driver);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_kms.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_kms.h
@@ -0,0 +1,219 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __MDP4_KMS_H__
+#define __MDP4_KMS_H__
+
+#include <drm/drm_panel.h>
+
+#include "msm_drv.h"
+#include "msm_kms.h"
+#include "disp/mdp_kms.h"
+#include "mdp4.xml.h"
+
+struct device_node;
+
+struct mdp4_kms {
+	struct mdp_kms base;
+
+	struct drm_device *dev;
+
+	int rev;
+
+	void __iomem *mmio;
+
+	struct regulator *vdd;
+
+	struct clk *clk;
+	struct clk *pclk;
+	struct clk *lut_clk;
+	struct clk *axi_clk;
+
+	struct mdp_irq error_handler;
+
+	bool rpm_enabled;
+
+	/* empty/blank cursor bo to use when cursor is "disabled" */
+	struct drm_gem_object *blank_cursor_bo;
+	uint64_t blank_cursor_iova;
+};
+#define to_mdp4_kms(x) container_of(x, struct mdp4_kms, base)
+
+static inline void mdp4_write(struct mdp4_kms *mdp4_kms, u32 reg, u32 data)
+{
+	msm_writel(data, mdp4_kms->mmio + reg);
+}
+
+static inline u32 mdp4_read(struct mdp4_kms *mdp4_kms, u32 reg)
+{
+	return msm_readl(mdp4_kms->mmio + reg);
+}
+
+static inline uint32_t pipe2flush(enum mdp4_pipe pipe)
+{
+	switch (pipe) {
+	case VG1:      return MDP4_OVERLAY_FLUSH_VG1;
+	case VG2:      return MDP4_OVERLAY_FLUSH_VG2;
+	case RGB1:     return MDP4_OVERLAY_FLUSH_RGB1;
+	case RGB2:     return MDP4_OVERLAY_FLUSH_RGB2;
+	default:       return 0;
+	}
+}
+
+static inline uint32_t ovlp2flush(int ovlp)
+{
+	switch (ovlp) {
+	case 0:        return MDP4_OVERLAY_FLUSH_OVLP0;
+	case 1:        return MDP4_OVERLAY_FLUSH_OVLP1;
+	default:       return 0;
+	}
+}
+
+static inline uint32_t dma2irq(enum mdp4_dma dma)
+{
+	switch (dma) {
+	case DMA_P:    return MDP4_IRQ_DMA_P_DONE;
+	case DMA_S:    return MDP4_IRQ_DMA_S_DONE;
+	case DMA_E:    return MDP4_IRQ_DMA_E_DONE;
+	default:       return 0;
+	}
+}
+
+static inline uint32_t dma2err(enum mdp4_dma dma)
+{
+	switch (dma) {
+	case DMA_P:    return MDP4_IRQ_PRIMARY_INTF_UDERRUN;
+	case DMA_S:    return 0;  // ???
+	case DMA_E:    return MDP4_IRQ_EXTERNAL_INTF_UDERRUN;
+	default:       return 0;
+	}
+}
+
+static inline uint32_t mixercfg(uint32_t mixer_cfg, int mixer,
+		enum mdp4_pipe pipe, enum mdp_mixer_stage_id stage)
+{
+	switch (pipe) {
+	case VG1:
+		mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE0__MASK |
+				MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
+		mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE0(stage) |
+			COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
+		break;
+	case VG2:
+		mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE1__MASK |
+				MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
+		mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE1(stage) |
+			COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
+		break;
+	case RGB1:
+		mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE2__MASK |
+				MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
+		mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE2(stage) |
+			COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
+		break;
+	case RGB2:
+		mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE3__MASK |
+				MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
+		mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE3(stage) |
+			COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
+		break;
+	case RGB3:
+		mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE4__MASK |
+				MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
+		mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE4(stage) |
+			COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
+		break;
+	case VG3:
+		mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE5__MASK |
+				MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
+		mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE5(stage) |
+			COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
+		break;
+	case VG4:
+		mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE6__MASK |
+				MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
+		mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE6(stage) |
+			COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
+		break;
+	default:
+		WARN(1, "invalid pipe");
+		break;
+	}
+
+	return mixer_cfg;
+}
+
+int mdp4_disable(struct mdp4_kms *mdp4_kms);
+int mdp4_enable(struct mdp4_kms *mdp4_kms);
+
+void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
+		uint32_t old_irqmask);
+void mdp4_irq_preinstall(struct msm_kms *kms);
+int mdp4_irq_postinstall(struct msm_kms *kms);
+void mdp4_irq_uninstall(struct msm_kms *kms);
+irqreturn_t mdp4_irq(struct msm_kms *kms);
+int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
+void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
+
+static inline uint32_t mdp4_pipe_caps(enum mdp4_pipe pipe)
+{
+	switch (pipe) {
+	case VG1:
+	case VG2:
+	case VG3:
+	case VG4:
+		return MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
+				MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC;
+	case RGB1:
+	case RGB2:
+	case RGB3:
+		return MDP_PIPE_CAP_SCALE;
+	default:
+		return 0;
+	}
+}
+
+enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane);
+struct drm_plane *mdp4_plane_init(struct drm_device *dev,
+		enum mdp4_pipe pipe_id, bool private_plane);
+
+uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc);
+void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config);
+void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf, int mixer);
+void mdp4_crtc_wait_for_commit_done(struct drm_crtc *crtc);
+struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
+		struct drm_plane *plane, int id, int ovlp_id,
+		enum mdp4_dma dma_id);
+
+long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate);
+struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev);
+
+long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate);
+struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev,
+		struct device_node *panel_node);
+
+struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev,
+		struct device_node *panel_node, struct drm_encoder *encoder);
+
+#ifdef CONFIG_DRM_MSM_DSI
+struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev);
+#else
+static inline struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev)
+{
+	return ERR_PTR(-ENODEV);
+}
+#endif
+
+#ifdef CONFIG_COMMON_CLK
+struct clk *mpd4_lvds_pll_init(struct drm_device *dev);
+#else
+static inline struct clk *mpd4_lvds_pll_init(struct drm_device *dev)
+{
+	return ERR_PTR(-ENODEV);
+}
+#endif
+
+#endif /* __MDP4_KMS_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_lcdc_encoder.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_lcdc_encoder.c
@@ -0,0 +1,402 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ * Author: Vinay Simha <vinaysimha@inforcecomputing.com>
+ */
+
+#include <linux/delay.h>
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_probe_helper.h>
+
+#include "mdp4_kms.h"
+
+struct mdp4_lcdc_encoder {
+	struct drm_encoder base;
+	struct device_node *panel_node;
+	struct drm_panel *panel;
+	struct clk *lcdc_clk;
+	unsigned long int pixclock;
+	struct regulator_bulk_data regs[3];
+	bool enabled;
+	uint32_t bsc;
+};
+#define to_mdp4_lcdc_encoder(x) container_of(x, struct mdp4_lcdc_encoder, base)
+
+static struct mdp4_kms *get_kms(struct drm_encoder *encoder)
+{
+	struct msm_drm_private *priv = encoder->dev->dev_private;
+	return to_mdp4_kms(to_mdp_kms(priv->kms));
+}
+
+/* this should probably be a helper: */
+static struct drm_connector *get_connector(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_connector *connector;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+		if (connector->encoder == encoder)
+			return connector;
+
+	return NULL;
+}
+
+static void setup_phy(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct drm_connector *connector = get_connector(encoder);
+	struct mdp4_kms *mdp4_kms = get_kms(encoder);
+	uint32_t lvds_intf = 0, lvds_phy_cfg0 = 0;
+	int bpp, nchan, swap;
+
+	if (!connector)
+		return;
+
+	bpp = 3 * connector->display_info.bpc;
+
+	if (!bpp)
+		bpp = 18;
+
+	/* TODO, these should come from panel somehow: */
+	nchan = 1;
+	swap = 0;
+
+	switch (bpp) {
+	case 24:
+		mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(0),
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x08) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x05) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x04) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x03));
+		mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(0),
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x02) |
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x01) |
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x00));
+		mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(1),
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x11) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x10) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x0d) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x0c));
+		mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(1),
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x0b) |
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x0a) |
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x09));
+		mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(2),
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x1a) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x19) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x18) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x15));
+		mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(2),
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x14) |
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x13) |
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x12));
+		mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(3),
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x1b) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x17) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x16) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x0f));
+		mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(3),
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x0e) |
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x07) |
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x06));
+		if (nchan == 2) {
+			lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE3_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE2_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE1_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE0_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE3_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE2_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE1_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE0_EN;
+		} else {
+			lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE3_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE2_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE1_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE0_EN;
+		}
+		break;
+
+	case 18:
+		mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(0),
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x0a) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x07) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x06) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x05));
+		mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(0),
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x04) |
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x03) |
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x02));
+		mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(1),
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x13) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x12) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x0f) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x0e));
+		mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(1),
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x0d) |
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x0c) |
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x0b));
+		mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_3_TO_0(2),
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT0(0x1a) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT1(0x19) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT2(0x18) |
+				MDP4_LCDC_LVDS_MUX_CTL_3_TO_0_BIT3(0x17));
+		mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_MUX_CTL_6_TO_4(2),
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT4(0x16) |
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT5(0x15) |
+				MDP4_LCDC_LVDS_MUX_CTL_6_TO_4_BIT6(0x14));
+		if (nchan == 2) {
+			lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE2_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE1_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH2_DATA_LANE0_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE2_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE1_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE0_EN;
+		} else {
+			lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE2_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE1_EN |
+					MDP4_LCDC_LVDS_INTF_CTL_CH1_DATA_LANE0_EN;
+		}
+		lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_RGB_OUT;
+		break;
+
+	default:
+		DRM_DEV_ERROR(dev->dev, "unknown bpp: %d\n", bpp);
+		return;
+	}
+
+	switch (nchan) {
+	case 1:
+		lvds_phy_cfg0 = MDP4_LVDS_PHY_CFG0_CHANNEL0;
+		lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH1_CLK_LANE_EN |
+				MDP4_LCDC_LVDS_INTF_CTL_MODE_SEL;
+		break;
+	case 2:
+		lvds_phy_cfg0 = MDP4_LVDS_PHY_CFG0_CHANNEL0 |
+				MDP4_LVDS_PHY_CFG0_CHANNEL1;
+		lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH2_CLK_LANE_EN |
+				MDP4_LCDC_LVDS_INTF_CTL_CH1_CLK_LANE_EN;
+		break;
+	default:
+		DRM_DEV_ERROR(dev->dev, "unknown # of channels: %d\n", nchan);
+		return;
+	}
+
+	if (swap)
+		lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_CH_SWAP;
+
+	lvds_intf |= MDP4_LCDC_LVDS_INTF_CTL_ENABLE;
+
+	mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG0, lvds_phy_cfg0);
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_INTF_CTL, lvds_intf);
+	mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG2, 0x30);
+
+	mb();
+	udelay(1);
+	lvds_phy_cfg0 |= MDP4_LVDS_PHY_CFG0_SERIALIZATION_ENBLE;
+	mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG0, lvds_phy_cfg0);
+}
+
+static void mdp4_lcdc_encoder_mode_set(struct drm_encoder *encoder,
+		struct drm_display_mode *mode,
+		struct drm_display_mode *adjusted_mode)
+{
+	struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
+			to_mdp4_lcdc_encoder(encoder);
+	struct mdp4_kms *mdp4_kms = get_kms(encoder);
+	uint32_t lcdc_hsync_skew, vsync_period, vsync_len, ctrl_pol;
+	uint32_t display_v_start, display_v_end;
+	uint32_t hsync_start_x, hsync_end_x;
+
+	mode = adjusted_mode;
+
+	DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
+
+	mdp4_lcdc_encoder->pixclock = mode->clock * 1000;
+
+	DBG("pixclock=%lu", mdp4_lcdc_encoder->pixclock);
+
+	ctrl_pol = 0;
+	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+		ctrl_pol |= MDP4_LCDC_CTRL_POLARITY_HSYNC_LOW;
+	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+		ctrl_pol |= MDP4_LCDC_CTRL_POLARITY_VSYNC_LOW;
+	/* probably need to get DATA_EN polarity from panel.. */
+
+	lcdc_hsync_skew = 0;  /* get this from panel? */
+
+	hsync_start_x = (mode->htotal - mode->hsync_start);
+	hsync_end_x = mode->htotal - (mode->hsync_start - mode->hdisplay) - 1;
+
+	vsync_period = mode->vtotal * mode->htotal;
+	vsync_len = (mode->vsync_end - mode->vsync_start) * mode->htotal;
+	display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + lcdc_hsync_skew;
+	display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + lcdc_hsync_skew - 1;
+
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_HSYNC_CTRL,
+			MDP4_LCDC_HSYNC_CTRL_PULSEW(mode->hsync_end - mode->hsync_start) |
+			MDP4_LCDC_HSYNC_CTRL_PERIOD(mode->htotal));
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_VSYNC_PERIOD, vsync_period);
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_VSYNC_LEN, vsync_len);
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_DISPLAY_HCTRL,
+			MDP4_LCDC_DISPLAY_HCTRL_START(hsync_start_x) |
+			MDP4_LCDC_DISPLAY_HCTRL_END(hsync_end_x));
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_DISPLAY_VSTART, display_v_start);
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_DISPLAY_VEND, display_v_end);
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_BORDER_CLR, 0);
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_UNDERFLOW_CLR,
+			MDP4_LCDC_UNDERFLOW_CLR_ENABLE_RECOVERY |
+			MDP4_LCDC_UNDERFLOW_CLR_COLOR(0xff));
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_HSYNC_SKEW, lcdc_hsync_skew);
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_CTRL_POLARITY, ctrl_pol);
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_ACTIVE_HCTL,
+			MDP4_LCDC_ACTIVE_HCTL_START(0) |
+			MDP4_LCDC_ACTIVE_HCTL_END(0));
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_ACTIVE_VSTART, 0);
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_ACTIVE_VEND, 0);
+}
+
+static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder)
+{
+	struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
+			to_mdp4_lcdc_encoder(encoder);
+	struct mdp4_kms *mdp4_kms = get_kms(encoder);
+	struct drm_panel *panel;
+
+	if (WARN_ON(!mdp4_lcdc_encoder->enabled))
+		return;
+
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0);
+
+	panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node);
+	if (!IS_ERR(panel)) {
+		drm_panel_disable(panel);
+		drm_panel_unprepare(panel);
+	}
+
+	/*
+	 * Wait for a vsync so we know the ENABLE=0 latched before
+	 * the (connector) source of the vsync's gets disabled,
+	 * otherwise we end up in a funny state if we re-enable
+	 * before the disable latches, which results that some of
+	 * the settings changes for the new modeset (like new
+	 * scanout buffer) don't latch properly..
+	 */
+	mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_PRIMARY_VSYNC);
+
+	clk_disable_unprepare(mdp4_lcdc_encoder->lcdc_clk);
+
+	regulator_bulk_disable(ARRAY_SIZE(mdp4_lcdc_encoder->regs),
+			       mdp4_lcdc_encoder->regs);
+
+	mdp4_lcdc_encoder->enabled = false;
+}
+
+static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
+			to_mdp4_lcdc_encoder(encoder);
+	unsigned long pc = mdp4_lcdc_encoder->pixclock;
+	struct mdp4_kms *mdp4_kms = get_kms(encoder);
+	struct drm_panel *panel;
+	uint32_t config;
+	int ret;
+
+	if (WARN_ON(mdp4_lcdc_encoder->enabled))
+		return;
+
+	/* TODO: hard-coded for 18bpp: */
+	config =
+		MDP4_DMA_CONFIG_R_BPC(BPC6) |
+		MDP4_DMA_CONFIG_G_BPC(BPC6) |
+		MDP4_DMA_CONFIG_B_BPC(BPC6) |
+		MDP4_DMA_CONFIG_PACK(0x21) |
+		MDP4_DMA_CONFIG_DEFLKR_EN |
+		MDP4_DMA_CONFIG_DITHER_EN;
+
+	if (!of_property_read_bool(dev->dev->of_node, "qcom,lcdc-align-lsb"))
+		config |= MDP4_DMA_CONFIG_PACK_ALIGN_MSB;
+
+	mdp4_crtc_set_config(encoder->crtc, config);
+	mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0);
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(mdp4_lcdc_encoder->regs),
+				    mdp4_lcdc_encoder->regs);
+	if (ret)
+		DRM_DEV_ERROR(dev->dev, "failed to enable regulators: %d\n", ret);
+
+	DBG("setting lcdc_clk=%lu", pc);
+	ret = clk_set_rate(mdp4_lcdc_encoder->lcdc_clk, pc);
+	if (ret)
+		DRM_DEV_ERROR(dev->dev, "failed to configure lcdc_clk: %d\n", ret);
+	ret = clk_prepare_enable(mdp4_lcdc_encoder->lcdc_clk);
+	if (ret)
+		DRM_DEV_ERROR(dev->dev, "failed to enable lcdc_clk: %d\n", ret);
+
+	panel = of_drm_find_panel(mdp4_lcdc_encoder->panel_node);
+	if (!IS_ERR(panel)) {
+		drm_panel_prepare(panel);
+		drm_panel_enable(panel);
+	}
+
+	setup_phy(encoder);
+
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 1);
+
+	mdp4_lcdc_encoder->enabled = true;
+}
+
+static const struct drm_encoder_helper_funcs mdp4_lcdc_encoder_helper_funcs = {
+	.mode_set = mdp4_lcdc_encoder_mode_set,
+	.disable = mdp4_lcdc_encoder_disable,
+	.enable = mdp4_lcdc_encoder_enable,
+};
+
+long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate)
+{
+	struct mdp4_lcdc_encoder *mdp4_lcdc_encoder =
+			to_mdp4_lcdc_encoder(encoder);
+	return clk_round_rate(mdp4_lcdc_encoder->lcdc_clk, rate);
+}
+
+/* initialize encoder */
+struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev,
+		struct device_node *panel_node)
+{
+	struct drm_encoder *encoder;
+	struct mdp4_lcdc_encoder *mdp4_lcdc_encoder;
+	int ret;
+
+	mdp4_lcdc_encoder = drmm_encoder_alloc(dev, struct mdp4_lcdc_encoder, base,
+					       NULL, DRM_MODE_ENCODER_LVDS, NULL);
+	if (IS_ERR(mdp4_lcdc_encoder))
+		return ERR_CAST(mdp4_lcdc_encoder);
+
+	mdp4_lcdc_encoder->panel_node = panel_node;
+
+	encoder = &mdp4_lcdc_encoder->base;
+
+	drm_encoder_helper_add(encoder, &mdp4_lcdc_encoder_helper_funcs);
+
+	/* TODO: do we need different pll in other cases? */
+	mdp4_lcdc_encoder->lcdc_clk = mpd4_lvds_pll_init(dev);
+	if (IS_ERR(mdp4_lcdc_encoder->lcdc_clk)) {
+		DRM_DEV_ERROR(dev->dev, "failed to get lvds_clk\n");
+		return ERR_CAST(mdp4_lcdc_encoder->lcdc_clk);
+	}
+
+	/* TODO: different regulators in other cases? */
+	mdp4_lcdc_encoder->regs[0].supply = "lvds-vccs-3p3v";
+	mdp4_lcdc_encoder->regs[1].supply = "lvds-vccs-3p3v";
+	mdp4_lcdc_encoder->regs[2].supply = "lvds-vdda";
+
+	ret = devm_regulator_bulk_get(dev->dev,
+				      ARRAY_SIZE(mdp4_lcdc_encoder->regs),
+				      mdp4_lcdc_encoder->regs);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return encoder;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_lvds_connector.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_lvds_connector.c
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ * Author: Vinay Simha <vinaysimha@inforcecomputing.com>
+ */
+
+#include "mdp4_kms.h"
+
+struct mdp4_lvds_connector {
+	struct drm_connector base;
+	struct drm_encoder *encoder;
+	struct device_node *panel_node;
+	struct drm_panel *panel;
+};
+#define to_mdp4_lvds_connector(x) container_of(x, struct mdp4_lvds_connector, base)
+
+static enum drm_connector_status mdp4_lvds_connector_detect(
+		struct drm_connector *connector, bool force)
+{
+	struct mdp4_lvds_connector *mdp4_lvds_connector =
+			to_mdp4_lvds_connector(connector);
+
+	if (!mdp4_lvds_connector->panel) {
+		mdp4_lvds_connector->panel =
+			of_drm_find_panel(mdp4_lvds_connector->panel_node);
+		if (IS_ERR(mdp4_lvds_connector->panel))
+			mdp4_lvds_connector->panel = NULL;
+	}
+
+	return mdp4_lvds_connector->panel ?
+			connector_status_connected :
+			connector_status_disconnected;
+}
+
+static void mdp4_lvds_connector_destroy(struct drm_connector *connector)
+{
+	struct mdp4_lvds_connector *mdp4_lvds_connector =
+			to_mdp4_lvds_connector(connector);
+
+	drm_connector_cleanup(connector);
+
+	kfree(mdp4_lvds_connector);
+}
+
+static int mdp4_lvds_connector_get_modes(struct drm_connector *connector)
+{
+	struct mdp4_lvds_connector *mdp4_lvds_connector =
+			to_mdp4_lvds_connector(connector);
+	struct drm_panel *panel = mdp4_lvds_connector->panel;
+	int ret = 0;
+
+	if (panel)
+		ret = drm_panel_get_modes(panel, connector);
+
+	return ret;
+}
+
+static enum drm_mode_status
+mdp4_lvds_connector_mode_valid(struct drm_connector *connector,
+			       struct drm_display_mode *mode)
+{
+	struct mdp4_lvds_connector *mdp4_lvds_connector =
+			to_mdp4_lvds_connector(connector);
+	struct drm_encoder *encoder = mdp4_lvds_connector->encoder;
+	long actual, requested;
+
+	requested = 1000 * mode->clock;
+	actual = mdp4_lcdc_round_pixclk(encoder, requested);
+
+	DBG("requested=%ld, actual=%ld", requested, actual);
+
+	if (actual != requested)
+		return MODE_CLOCK_RANGE;
+
+	return MODE_OK;
+}
+
+static const struct drm_connector_funcs mdp4_lvds_connector_funcs = {
+	.detect = mdp4_lvds_connector_detect,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.destroy = mdp4_lvds_connector_destroy,
+	.reset = drm_atomic_helper_connector_reset,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static const struct drm_connector_helper_funcs mdp4_lvds_connector_helper_funcs = {
+	.get_modes = mdp4_lvds_connector_get_modes,
+	.mode_valid = mdp4_lvds_connector_mode_valid,
+};
+
+/* initialize connector */
+struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev,
+		struct device_node *panel_node, struct drm_encoder *encoder)
+{
+	struct drm_connector *connector = NULL;
+	struct mdp4_lvds_connector *mdp4_lvds_connector;
+
+	mdp4_lvds_connector = kzalloc(sizeof(*mdp4_lvds_connector), GFP_KERNEL);
+	if (!mdp4_lvds_connector)
+		return ERR_PTR(-ENOMEM);
+
+	mdp4_lvds_connector->encoder = encoder;
+	mdp4_lvds_connector->panel_node = panel_node;
+
+	connector = &mdp4_lvds_connector->base;
+
+	drm_connector_init(dev, connector, &mdp4_lvds_connector_funcs,
+			DRM_MODE_CONNECTOR_LVDS);
+	drm_connector_helper_add(connector, &mdp4_lvds_connector_helper_funcs);
+
+	connector->polled = 0;
+
+	connector->interlace_allowed = 0;
+	connector->doublescan_allowed = 0;
+
+	drm_connector_attach_encoder(connector, encoder);
+
+	return connector;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_lvds_pll.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_lvds_pll.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+
+#include "mdp4_kms.h"
+
+struct mdp4_lvds_pll {
+	struct clk_hw pll_hw;
+	struct drm_device *dev;
+	unsigned long pixclk;
+};
+#define to_mdp4_lvds_pll(x) container_of(x, struct mdp4_lvds_pll, pll_hw)
+
+static struct mdp4_kms *get_kms(struct mdp4_lvds_pll *lvds_pll)
+{
+	struct msm_drm_private *priv = lvds_pll->dev->dev_private;
+	return to_mdp4_kms(to_mdp_kms(priv->kms));
+}
+
+struct pll_rate {
+	unsigned long rate;
+	struct {
+		uint32_t val;
+		uint32_t reg;
+	} conf[32];
+};
+
+/* NOTE: keep sorted highest freq to lowest: */
+static const struct pll_rate freqtbl[] = {
+	{ 72000000, {
+		{ 0x8f, REG_MDP4_LVDS_PHY_PLL_CTRL_1 },
+		{ 0x30, REG_MDP4_LVDS_PHY_PLL_CTRL_2 },
+		{ 0xc6, REG_MDP4_LVDS_PHY_PLL_CTRL_3 },
+		{ 0x10, REG_MDP4_LVDS_PHY_PLL_CTRL_5 },
+		{ 0x07, REG_MDP4_LVDS_PHY_PLL_CTRL_6 },
+		{ 0x62, REG_MDP4_LVDS_PHY_PLL_CTRL_7 },
+		{ 0x41, REG_MDP4_LVDS_PHY_PLL_CTRL_8 },
+		{ 0x0d, REG_MDP4_LVDS_PHY_PLL_CTRL_9 },
+		{ 0, 0 } }
+	},
+};
+
+static const struct pll_rate *find_rate(unsigned long rate)
+{
+	int i;
+	for (i = 1; i < ARRAY_SIZE(freqtbl); i++)
+		if (rate > freqtbl[i].rate)
+			return &freqtbl[i-1];
+	return &freqtbl[i-1];
+}
+
+static int mpd4_lvds_pll_enable(struct clk_hw *hw)
+{
+	struct mdp4_lvds_pll *lvds_pll = to_mdp4_lvds_pll(hw);
+	struct mdp4_kms *mdp4_kms = get_kms(lvds_pll);
+	const struct pll_rate *pll_rate = find_rate(lvds_pll->pixclk);
+	int i;
+
+	DBG("pixclk=%lu (%lu)", lvds_pll->pixclk, pll_rate->rate);
+
+	if (WARN_ON(!pll_rate))
+		return -EINVAL;
+
+	mdp4_write(mdp4_kms, REG_MDP4_LCDC_LVDS_PHY_RESET, 0x33);
+
+	for (i = 0; pll_rate->conf[i].reg; i++)
+		mdp4_write(mdp4_kms, pll_rate->conf[i].reg, pll_rate->conf[i].val);
+
+	mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_PLL_CTRL_0, 0x01);
+
+	/* Wait until LVDS PLL is locked and ready */
+	while (!mdp4_read(mdp4_kms, REG_MDP4_LVDS_PHY_PLL_LOCKED))
+		cpu_relax();
+
+	return 0;
+}
+
+static void mpd4_lvds_pll_disable(struct clk_hw *hw)
+{
+	struct mdp4_lvds_pll *lvds_pll = to_mdp4_lvds_pll(hw);
+	struct mdp4_kms *mdp4_kms = get_kms(lvds_pll);
+
+	DBG("");
+
+	mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG0, 0x0);
+	mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_PLL_CTRL_0, 0x0);
+}
+
+static unsigned long mpd4_lvds_pll_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct mdp4_lvds_pll *lvds_pll = to_mdp4_lvds_pll(hw);
+	return lvds_pll->pixclk;
+}
+
+static long mpd4_lvds_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long *parent_rate)
+{
+	const struct pll_rate *pll_rate = find_rate(rate);
+	return pll_rate->rate;
+}
+
+static int mpd4_lvds_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long parent_rate)
+{
+	struct mdp4_lvds_pll *lvds_pll = to_mdp4_lvds_pll(hw);
+	lvds_pll->pixclk = rate;
+	return 0;
+}
+
+
+static const struct clk_ops mpd4_lvds_pll_ops = {
+	.enable = mpd4_lvds_pll_enable,
+	.disable = mpd4_lvds_pll_disable,
+	.recalc_rate = mpd4_lvds_pll_recalc_rate,
+	.round_rate = mpd4_lvds_pll_round_rate,
+	.set_rate = mpd4_lvds_pll_set_rate,
+};
+
+static const char *mpd4_lvds_pll_parents[] = {
+	"pxo",
+};
+
+static struct clk_init_data pll_init = {
+	.name = "mpd4_lvds_pll",
+	.ops = &mpd4_lvds_pll_ops,
+	.parent_names = mpd4_lvds_pll_parents,
+	.num_parents = ARRAY_SIZE(mpd4_lvds_pll_parents),
+};
+
+struct clk *mpd4_lvds_pll_init(struct drm_device *dev)
+{
+	struct mdp4_lvds_pll *lvds_pll;
+	struct clk *clk;
+	int ret;
+
+	lvds_pll = devm_kzalloc(dev->dev, sizeof(*lvds_pll), GFP_KERNEL);
+	if (!lvds_pll) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	lvds_pll->dev = dev;
+
+	lvds_pll->pll_hw.init = &pll_init;
+	clk = devm_clk_register(dev->dev, &lvds_pll->pll_hw);
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		goto fail;
+	}
+
+	return clk;
+
+fail:
+	return ERR_PTR(ret);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_plane.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp4/mdp4_plane.c
@@ -0,0 +1,419 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_damage_helper.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_atomic_helper.h>
+
+#include "mdp4_kms.h"
+
+#define DOWN_SCALE_MAX	8
+#define UP_SCALE_MAX	8
+
+struct mdp4_plane {
+	struct drm_plane base;
+	const char *name;
+
+	enum mdp4_pipe pipe;
+
+	uint32_t caps;
+	uint32_t nformats;
+	uint32_t formats[32];
+
+	bool enabled;
+};
+#define to_mdp4_plane(x) container_of(x, struct mdp4_plane, base)
+
+/* MDP format helper functions */
+static inline
+enum mdp4_frame_format mdp4_get_frame_format(struct drm_framebuffer *fb)
+{
+	bool is_tile = false;
+
+	if (fb->modifier == DRM_FORMAT_MOD_SAMSUNG_64_32_TILE)
+		is_tile = true;
+
+	if (fb->format->format == DRM_FORMAT_NV12 && is_tile)
+		return FRAME_TILE_YCBCR_420;
+
+	return FRAME_LINEAR;
+}
+
+static void mdp4_plane_set_scanout(struct drm_plane *plane,
+		struct drm_framebuffer *fb);
+static int mdp4_plane_mode_set(struct drm_plane *plane,
+		struct drm_crtc *crtc, struct drm_framebuffer *fb,
+		int crtc_x, int crtc_y,
+		unsigned int crtc_w, unsigned int crtc_h,
+		uint32_t src_x, uint32_t src_y,
+		uint32_t src_w, uint32_t src_h);
+
+static struct mdp4_kms *get_kms(struct drm_plane *plane)
+{
+	struct msm_drm_private *priv = plane->dev->dev_private;
+	return to_mdp4_kms(to_mdp_kms(priv->kms));
+}
+
+static void mdp4_plane_destroy(struct drm_plane *plane)
+{
+	struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
+
+	drm_plane_cleanup(plane);
+
+	kfree(mdp4_plane);
+}
+
+/* helper to install properties which are common to planes and crtcs */
+static void mdp4_plane_install_properties(struct drm_plane *plane,
+		struct drm_mode_object *obj)
+{
+	// XXX
+}
+
+static int mdp4_plane_set_property(struct drm_plane *plane,
+		struct drm_property *property, uint64_t val)
+{
+	// XXX
+	return -EINVAL;
+}
+
+static const struct drm_plane_funcs mdp4_plane_funcs = {
+		.update_plane = drm_atomic_helper_update_plane,
+		.disable_plane = drm_atomic_helper_disable_plane,
+		.destroy = mdp4_plane_destroy,
+		.set_property = mdp4_plane_set_property,
+		.reset = drm_atomic_helper_plane_reset,
+		.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+		.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+};
+
+static int mdp4_plane_prepare_fb(struct drm_plane *plane,
+				 struct drm_plane_state *new_state)
+{
+	struct msm_drm_private *priv = plane->dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+
+	if (!new_state->fb)
+		return 0;
+
+	drm_gem_plane_helper_prepare_fb(plane, new_state);
+
+	return msm_framebuffer_prepare(new_state->fb, kms->aspace, false);
+}
+
+static void mdp4_plane_cleanup_fb(struct drm_plane *plane,
+				  struct drm_plane_state *old_state)
+{
+	struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
+	struct mdp4_kms *mdp4_kms = get_kms(plane);
+	struct msm_kms *kms = &mdp4_kms->base.base;
+	struct drm_framebuffer *fb = old_state->fb;
+
+	if (!fb)
+		return;
+
+	DBG("%s: cleanup: FB[%u]", mdp4_plane->name, fb->base.id);
+	msm_framebuffer_cleanup(fb, kms->aspace, false);
+}
+
+
+static int mdp4_plane_atomic_check(struct drm_plane *plane,
+		struct drm_atomic_state *state)
+{
+	return 0;
+}
+
+static void mdp4_plane_atomic_update(struct drm_plane *plane,
+				     struct drm_atomic_state *state)
+{
+	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
+									   plane);
+	int ret;
+
+	ret = mdp4_plane_mode_set(plane,
+			new_state->crtc, new_state->fb,
+			new_state->crtc_x, new_state->crtc_y,
+			new_state->crtc_w, new_state->crtc_h,
+			new_state->src_x,  new_state->src_y,
+			new_state->src_w, new_state->src_h);
+	/* atomic_check should have ensured that this doesn't fail */
+	WARN_ON(ret < 0);
+}
+
+static const struct drm_plane_helper_funcs mdp4_plane_helper_funcs = {
+		.prepare_fb = mdp4_plane_prepare_fb,
+		.cleanup_fb = mdp4_plane_cleanup_fb,
+		.atomic_check = mdp4_plane_atomic_check,
+		.atomic_update = mdp4_plane_atomic_update,
+};
+
+static void mdp4_plane_set_scanout(struct drm_plane *plane,
+		struct drm_framebuffer *fb)
+{
+	struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
+	struct mdp4_kms *mdp4_kms = get_kms(plane);
+	struct msm_kms *kms = &mdp4_kms->base.base;
+	enum mdp4_pipe pipe = mdp4_plane->pipe;
+
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_STRIDE_A(pipe),
+			MDP4_PIPE_SRC_STRIDE_A_P0(fb->pitches[0]) |
+			MDP4_PIPE_SRC_STRIDE_A_P1(fb->pitches[1]));
+
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_STRIDE_B(pipe),
+			MDP4_PIPE_SRC_STRIDE_B_P2(fb->pitches[2]) |
+			MDP4_PIPE_SRC_STRIDE_B_P3(fb->pitches[3]));
+
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP0_BASE(pipe),
+			msm_framebuffer_iova(fb, kms->aspace, 0));
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP1_BASE(pipe),
+			msm_framebuffer_iova(fb, kms->aspace, 1));
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP2_BASE(pipe),
+			msm_framebuffer_iova(fb, kms->aspace, 2));
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP3_BASE(pipe),
+			msm_framebuffer_iova(fb, kms->aspace, 3));
+}
+
+static void mdp4_write_csc_config(struct mdp4_kms *mdp4_kms,
+		enum mdp4_pipe pipe, struct csc_cfg *csc)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(csc->matrix); i++) {
+		mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_MV(pipe, i),
+				csc->matrix[i]);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(csc->post_bias) ; i++) {
+		mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_PRE_BV(pipe, i),
+				csc->pre_bias[i]);
+
+		mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_POST_BV(pipe, i),
+				csc->post_bias[i]);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(csc->post_clamp) ; i++) {
+		mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_PRE_LV(pipe, i),
+				csc->pre_clamp[i]);
+
+		mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_POST_LV(pipe, i),
+				csc->post_clamp[i]);
+	}
+}
+
+#define MDP4_VG_PHASE_STEP_DEFAULT	0x20000000
+
+static int mdp4_plane_mode_set(struct drm_plane *plane,
+		struct drm_crtc *crtc, struct drm_framebuffer *fb,
+		int crtc_x, int crtc_y,
+		unsigned int crtc_w, unsigned int crtc_h,
+		uint32_t src_x, uint32_t src_y,
+		uint32_t src_w, uint32_t src_h)
+{
+	struct drm_device *dev = plane->dev;
+	struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
+	struct mdp4_kms *mdp4_kms = get_kms(plane);
+	enum mdp4_pipe pipe = mdp4_plane->pipe;
+	const struct mdp_format *format;
+	uint32_t op_mode = 0;
+	uint32_t phasex_step = MDP4_VG_PHASE_STEP_DEFAULT;
+	uint32_t phasey_step = MDP4_VG_PHASE_STEP_DEFAULT;
+	enum mdp4_frame_format frame_type;
+
+	if (!(crtc && fb)) {
+		DBG("%s: disabled!", mdp4_plane->name);
+		return 0;
+	}
+
+	frame_type = mdp4_get_frame_format(fb);
+
+	/* src values are in Q16 fixed point, convert to integer: */
+	src_x = src_x >> 16;
+	src_y = src_y >> 16;
+	src_w = src_w >> 16;
+	src_h = src_h >> 16;
+
+	DBG("%s: FB[%u] %u,%u,%u,%u -> CRTC[%u] %d,%d,%u,%u", mdp4_plane->name,
+			fb->base.id, src_x, src_y, src_w, src_h,
+			crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h);
+
+	format = to_mdp_format(msm_framebuffer_format(fb));
+
+	if (src_w > (crtc_w * DOWN_SCALE_MAX)) {
+		DRM_DEV_ERROR(dev->dev, "Width down scaling exceeds limits!\n");
+		return -ERANGE;
+	}
+
+	if (src_h > (crtc_h * DOWN_SCALE_MAX)) {
+		DRM_DEV_ERROR(dev->dev, "Height down scaling exceeds limits!\n");
+		return -ERANGE;
+	}
+
+	if (crtc_w > (src_w * UP_SCALE_MAX)) {
+		DRM_DEV_ERROR(dev->dev, "Width up scaling exceeds limits!\n");
+		return -ERANGE;
+	}
+
+	if (crtc_h > (src_h * UP_SCALE_MAX)) {
+		DRM_DEV_ERROR(dev->dev, "Height up scaling exceeds limits!\n");
+		return -ERANGE;
+	}
+
+	if (src_w != crtc_w) {
+		uint32_t sel_unit = SCALE_FIR;
+		op_mode |= MDP4_PIPE_OP_MODE_SCALEX_EN;
+
+		if (MDP_FORMAT_IS_YUV(format)) {
+			if (crtc_w > src_w)
+				sel_unit = SCALE_PIXEL_RPT;
+			else if (crtc_w <= (src_w / 4))
+				sel_unit = SCALE_MN_PHASE;
+
+			op_mode |= MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL(sel_unit);
+			phasex_step = mult_frac(MDP4_VG_PHASE_STEP_DEFAULT,
+					src_w, crtc_w);
+		}
+	}
+
+	if (src_h != crtc_h) {
+		uint32_t sel_unit = SCALE_FIR;
+		op_mode |= MDP4_PIPE_OP_MODE_SCALEY_EN;
+
+		if (MDP_FORMAT_IS_YUV(format)) {
+
+			if (crtc_h > src_h)
+				sel_unit = SCALE_PIXEL_RPT;
+			else if (crtc_h <= (src_h / 4))
+				sel_unit = SCALE_MN_PHASE;
+
+			op_mode |= MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL(sel_unit);
+			phasey_step = mult_frac(MDP4_VG_PHASE_STEP_DEFAULT,
+					src_h, crtc_h);
+		}
+	}
+
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_SIZE(pipe),
+			MDP4_PIPE_SRC_SIZE_WIDTH(src_w) |
+			MDP4_PIPE_SRC_SIZE_HEIGHT(src_h));
+
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_XY(pipe),
+			MDP4_PIPE_SRC_XY_X(src_x) |
+			MDP4_PIPE_SRC_XY_Y(src_y));
+
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_DST_SIZE(pipe),
+			MDP4_PIPE_DST_SIZE_WIDTH(crtc_w) |
+			MDP4_PIPE_DST_SIZE_HEIGHT(crtc_h));
+
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_DST_XY(pipe),
+			MDP4_PIPE_DST_XY_X(crtc_x) |
+			MDP4_PIPE_DST_XY_Y(crtc_y));
+
+	mdp4_plane_set_scanout(plane, fb);
+
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_FORMAT(pipe),
+			MDP4_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) |
+			MDP4_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) |
+			MDP4_PIPE_SRC_FORMAT_G_BPC(format->bpc_g) |
+			MDP4_PIPE_SRC_FORMAT_B_BPC(format->bpc_b) |
+			COND(format->alpha_enable, MDP4_PIPE_SRC_FORMAT_ALPHA_ENABLE) |
+			MDP4_PIPE_SRC_FORMAT_CPP(format->cpp - 1) |
+			MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT(format->unpack_count - 1) |
+			MDP4_PIPE_SRC_FORMAT_FETCH_PLANES(format->fetch_type) |
+			MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP(format->chroma_sample) |
+			MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT(frame_type) |
+			COND(format->unpack_tight, MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT));
+
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_UNPACK(pipe),
+			MDP4_PIPE_SRC_UNPACK_ELEM0(format->unpack[0]) |
+			MDP4_PIPE_SRC_UNPACK_ELEM1(format->unpack[1]) |
+			MDP4_PIPE_SRC_UNPACK_ELEM2(format->unpack[2]) |
+			MDP4_PIPE_SRC_UNPACK_ELEM3(format->unpack[3]));
+
+	if (MDP_FORMAT_IS_YUV(format)) {
+		struct csc_cfg *csc = mdp_get_default_csc_cfg(CSC_YUV2RGB);
+
+		op_mode |= MDP4_PIPE_OP_MODE_SRC_YCBCR;
+		op_mode |= MDP4_PIPE_OP_MODE_CSC_EN;
+		mdp4_write_csc_config(mdp4_kms, pipe, csc);
+	}
+
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(pipe), op_mode);
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEX_STEP(pipe), phasex_step);
+	mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEY_STEP(pipe), phasey_step);
+
+	if (frame_type != FRAME_LINEAR)
+		mdp4_write(mdp4_kms, REG_MDP4_PIPE_SSTILE_FRAME_SIZE(pipe),
+				MDP4_PIPE_SSTILE_FRAME_SIZE_WIDTH(src_w) |
+				MDP4_PIPE_SSTILE_FRAME_SIZE_HEIGHT(src_h));
+
+	return 0;
+}
+
+static const char *pipe_names[] = {
+		"VG1", "VG2",
+		"RGB1", "RGB2", "RGB3",
+		"VG3", "VG4",
+};
+
+enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane)
+{
+	struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
+	return mdp4_plane->pipe;
+}
+
+static const uint64_t supported_format_modifiers[] = {
+	DRM_FORMAT_MOD_SAMSUNG_64_32_TILE,
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_INVALID
+};
+
+/* initialize plane */
+struct drm_plane *mdp4_plane_init(struct drm_device *dev,
+		enum mdp4_pipe pipe_id, bool private_plane)
+{
+	struct drm_plane *plane = NULL;
+	struct mdp4_plane *mdp4_plane;
+	int ret;
+	enum drm_plane_type type;
+
+	mdp4_plane = kzalloc(sizeof(*mdp4_plane), GFP_KERNEL);
+	if (!mdp4_plane) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	plane = &mdp4_plane->base;
+
+	mdp4_plane->pipe = pipe_id;
+	mdp4_plane->name = pipe_names[pipe_id];
+	mdp4_plane->caps = mdp4_pipe_caps(pipe_id);
+
+	mdp4_plane->nformats = mdp_get_formats(mdp4_plane->formats,
+			ARRAY_SIZE(mdp4_plane->formats),
+			!pipe_supports_yuv(mdp4_plane->caps));
+
+	type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
+	ret = drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs,
+				 mdp4_plane->formats, mdp4_plane->nformats,
+				 supported_format_modifiers, type, NULL);
+	if (ret)
+		goto fail;
+
+	drm_plane_helper_add(plane, &mdp4_plane_helper_funcs);
+
+	mdp4_plane_install_properties(plane, &plane->base);
+
+	drm_plane_enable_fb_damage_clips(plane);
+
+	return plane;
+
+fail:
+	if (plane)
+		mdp4_plane_destroy(plane);
+
+	return ERR_PTR(ret);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_cfg.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_cfg.c
@@ -0,0 +1,1401 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ */
+
+#include "mdp5_kms.h"
+#include "mdp5_cfg.h"
+
+struct mdp5_cfg_handler {
+	int revision;
+	struct mdp5_cfg config;
+};
+
+/* mdp5_cfg must be exposed (used in mdp5.xml.h) */
+const struct mdp5_cfg_hw *mdp5_cfg = NULL;
+
+static const struct mdp5_cfg_hw msm8x74v1_config = {
+	.name = "msm8x74v1",
+	.mdp = {
+		.count = 1,
+		.caps = MDP_CAP_SMP |
+			0,
+	},
+	.smp = {
+		.mmb_count = 22,
+		.mmb_size = 4096,
+		.clients = {
+			[SSPP_VIG0] =  1, [SSPP_VIG1] =  4, [SSPP_VIG2] =  7,
+			[SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
+			[SSPP_RGB0] = 16, [SSPP_RGB1] = 17, [SSPP_RGB2] = 18,
+		},
+	},
+	.ctl = {
+		.count = 5,
+		.base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
+		.flush_hw_mask = 0x0003ffff,
+	},
+	.pipe_vig = {
+		.count = 3,
+		.base = { 0x01100, 0x01500, 0x01900 },
+		.caps = MDP_PIPE_CAP_HFLIP |
+			MDP_PIPE_CAP_VFLIP |
+			MDP_PIPE_CAP_SCALE |
+			MDP_PIPE_CAP_CSC   |
+			0,
+	},
+	.pipe_rgb = {
+		.count = 3,
+		.base = { 0x01d00, 0x02100, 0x02500 },
+		.caps = MDP_PIPE_CAP_HFLIP |
+			MDP_PIPE_CAP_VFLIP |
+			MDP_PIPE_CAP_SCALE |
+			0,
+	},
+	.pipe_dma = {
+		.count = 2,
+		.base = { 0x02900, 0x02d00 },
+		.caps = MDP_PIPE_CAP_HFLIP |
+			MDP_PIPE_CAP_VFLIP |
+			0,
+	},
+	.lm = {
+		.count = 5,
+		.base = { 0x03100, 0x03500, 0x03900, 0x03d00, 0x04100 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 1, .pp = 1, .dspp = 1,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 2, .pp = 2, .dspp = 2,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 3, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB },
+				{ .id = 4, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB },
+			     },
+		.nb_stages = 5,
+		.max_width = 2048,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 3,
+		.base = { 0x04500, 0x04900, 0x04d00 },
+	},
+	.pp = {
+		.count = 3,
+		.base = { 0x21a00, 0x21b00, 0x21c00 },
+	},
+	.intf = {
+		.base = { 0x21000, 0x21200, 0x21400, 0x21600 },
+		.connect = {
+			[0] = INTF_eDP,
+			[1] = INTF_DSI,
+			[2] = INTF_DSI,
+			[3] = INTF_HDMI,
+		},
+	},
+	.perf = {
+		.ab_inefficiency = 200,
+		.ib_inefficiency = 120,
+		.clk_inefficiency = 125
+	},
+	.max_clk = 200000000,
+};
+
+static const struct mdp5_cfg_hw msm8x26_config = {
+	.name = "msm8x26",
+	.mdp = {
+		.count = 1,
+		.caps = MDP_CAP_SMP |
+			0,
+	},
+	.smp = {
+		.mmb_count = 7,
+		.mmb_size = 4096,
+		.clients = {
+			[SSPP_VIG0] =  1,
+			[SSPP_DMA0] = 4,
+			[SSPP_RGB0] = 7,
+		},
+	},
+	.ctl = {
+		.count = 2,
+		.base = { 0x00500, 0x00600 },
+		.flush_hw_mask = 0x0003ffff,
+	},
+	.pipe_vig = {
+		.count = 1,
+		.base = { 0x01100 },
+		.caps = MDP_PIPE_CAP_HFLIP |
+			MDP_PIPE_CAP_VFLIP |
+			MDP_PIPE_CAP_SCALE |
+			MDP_PIPE_CAP_CSC   |
+			0,
+	},
+	.pipe_rgb = {
+		.count = 1,
+		.base = { 0x01d00 },
+		.caps = MDP_PIPE_CAP_HFLIP |
+			MDP_PIPE_CAP_VFLIP |
+			MDP_PIPE_CAP_SCALE |
+			0,
+	},
+	.pipe_dma = {
+		.count = 1,
+		.base = { 0x02900 },
+		.caps = MDP_PIPE_CAP_HFLIP |
+			MDP_PIPE_CAP_VFLIP |
+			0,
+	},
+	.lm = {
+		.count = 2,
+		.base = { 0x03100, 0x03d00 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 1, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB },
+			     },
+		.nb_stages = 2,
+		.max_width = 2048,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 1,
+		.base = { 0x04500 },
+	},
+	.pp = {
+		.count = 1,
+		.base = { 0x21a00 },
+	},
+	.intf = {
+		.base = { 0x00000, 0x21200 },
+		.connect = {
+			[0] = INTF_DISABLED,
+			[1] = INTF_DSI,
+		},
+	},
+	.perf = {
+		.ab_inefficiency = 100,
+		.ib_inefficiency = 200,
+		.clk_inefficiency = 125
+	},
+	.max_clk = 200000000,
+};
+
+static const struct mdp5_cfg_hw msm8x74v2_config = {
+	.name = "msm8x74",
+	.mdp = {
+		.count = 1,
+		.caps = MDP_CAP_SMP |
+			0,
+	},
+	.smp = {
+		.mmb_count = 22,
+		.mmb_size = 4096,
+		.clients = {
+			[SSPP_VIG0] =  1, [SSPP_VIG1] =  4, [SSPP_VIG2] =  7,
+			[SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
+			[SSPP_RGB0] = 16, [SSPP_RGB1] = 17, [SSPP_RGB2] = 18,
+		},
+	},
+	.ctl = {
+		.count = 5,
+		.base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
+		.flush_hw_mask = 0x0003ffff,
+	},
+	.pipe_vig = {
+		.count = 3,
+		.base = { 0x01100, 0x01500, 0x01900 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
+				MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
+				MDP_PIPE_CAP_DECIMATION,
+	},
+	.pipe_rgb = {
+		.count = 3,
+		.base = { 0x01d00, 0x02100, 0x02500 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
+				MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
+	},
+	.pipe_dma = {
+		.count = 2,
+		.base = { 0x02900, 0x02d00 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
+	},
+	.lm = {
+		.count = 5,
+		.base = { 0x03100, 0x03500, 0x03900, 0x03d00, 0x04100 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 1, .pp = 1, .dspp = 1,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 2, .pp = 2, .dspp = 2,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 3, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB, },
+				{ .id = 4, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB, },
+			     },
+		.nb_stages = 5,
+		.max_width = 2048,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 3,
+		.base = { 0x04500, 0x04900, 0x04d00 },
+	},
+	.ad = {
+		.count = 2,
+		.base = { 0x13000, 0x13200 },
+	},
+	.pp = {
+		.count = 3,
+		.base = { 0x12c00, 0x12d00, 0x12e00 },
+	},
+	.intf = {
+		.base = { 0x12400, 0x12600, 0x12800, 0x12a00 },
+		.connect = {
+			[0] = INTF_eDP,
+			[1] = INTF_DSI,
+			[2] = INTF_DSI,
+			[3] = INTF_HDMI,
+		},
+	},
+	.perf = {
+		.ab_inefficiency = 200,
+		.ib_inefficiency = 120,
+		.clk_inefficiency = 125
+	},
+	.max_clk = 320000000,
+};
+
+static const struct mdp5_cfg_hw apq8084_config = {
+	.name = "apq8084",
+	.mdp = {
+		.count = 1,
+		.caps = MDP_CAP_SMP |
+			MDP_CAP_SRC_SPLIT |
+			0,
+	},
+	.smp = {
+		.mmb_count = 44,
+		.mmb_size = 8192,
+		.clients = {
+			[SSPP_VIG0] =  1, [SSPP_VIG1] =  4,
+			[SSPP_VIG2] =  7, [SSPP_VIG3] = 19,
+			[SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
+			[SSPP_RGB0] = 16, [SSPP_RGB1] = 17,
+			[SSPP_RGB2] = 18, [SSPP_RGB3] = 22,
+		},
+		.reserved_state[0] = GENMASK(7, 0),	/* first 8 MMBs */
+		.reserved = {
+			/* Two SMP blocks are statically tied to RGB pipes: */
+			[16] = 2, [17] = 2, [18] = 2, [22] = 2,
+		},
+	},
+	.ctl = {
+		.count = 5,
+		.base = { 0x00500, 0x00600, 0x00700, 0x00800, 0x00900 },
+		.flush_hw_mask = 0x003fffff,
+	},
+	.pipe_vig = {
+		.count = 4,
+		.base = { 0x01100, 0x01500, 0x01900, 0x01d00 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
+				MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
+				MDP_PIPE_CAP_DECIMATION,
+	},
+	.pipe_rgb = {
+		.count = 4,
+		.base = { 0x02100, 0x02500, 0x02900, 0x02d00 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
+				MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
+	},
+	.pipe_dma = {
+		.count = 2,
+		.base = { 0x03100, 0x03500 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
+	},
+	.lm = {
+		.count = 6,
+		.base = { 0x03900, 0x03d00, 0x04100, 0x04500, 0x04900, 0x04d00 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY |
+					  MDP_LM_CAP_PAIR, },
+				{ .id = 1, .pp = 1, .dspp = 1,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 2, .pp = 2, .dspp = 2,
+				  .caps = MDP_LM_CAP_DISPLAY |
+					  MDP_LM_CAP_PAIR, },
+				{ .id = 3, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB, },
+				{ .id = 4, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB, },
+				{ .id = 5, .pp = 3, .dspp = 3,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+			     },
+		.nb_stages = 5,
+		.max_width = 2048,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 4,
+		.base = { 0x05100, 0x05500, 0x05900, 0x05d00 },
+
+	},
+	.ad = {
+		.count = 3,
+		.base = { 0x13400, 0x13600, 0x13800 },
+	},
+	.pp = {
+		.count = 4,
+		.base = { 0x12e00, 0x12f00, 0x13000, 0x13100 },
+	},
+	.intf = {
+		.base = { 0x12400, 0x12600, 0x12800, 0x12a00, 0x12c00 },
+		.connect = {
+			[0] = INTF_eDP,
+			[1] = INTF_DSI,
+			[2] = INTF_DSI,
+			[3] = INTF_HDMI,
+		},
+	},
+	.perf = {
+		.ab_inefficiency = 200,
+		.ib_inefficiency = 120,
+		.clk_inefficiency = 105
+	},
+	.max_clk = 320000000,
+};
+
+static const struct mdp5_cfg_hw msm8x16_config = {
+	.name = "msm8x16",
+	.mdp = {
+		.count = 1,
+		.base = { 0x0 },
+		.caps = MDP_CAP_SMP |
+			0,
+	},
+	.smp = {
+		.mmb_count = 8,
+		.mmb_size = 8192,
+		.clients = {
+			[SSPP_VIG0] = 1, [SSPP_DMA0] = 4,
+			[SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
+		},
+	},
+	.ctl = {
+		.count = 5,
+		.base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
+		.flush_hw_mask = 0x4003ffff,
+	},
+	.pipe_vig = {
+		.count = 1,
+		.base = { 0x04000 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
+				MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
+				MDP_PIPE_CAP_DECIMATION,
+	},
+	.pipe_rgb = {
+		.count = 2,
+		.base = { 0x14000, 0x16000 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
+				MDP_PIPE_CAP_DECIMATION,
+	},
+	.pipe_dma = {
+		.count = 1,
+		.base = { 0x24000 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
+	},
+	.lm = {
+		.count = 2, /* LM0 and LM3 */
+		.base = { 0x44000, 0x47000 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 3, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB },
+			     },
+		.nb_stages = 8,
+		.max_width = 2048,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 1,
+		.base = { 0x54000 },
+
+	},
+	.intf = {
+		.base = { 0x00000, 0x6a800 },
+		.connect = {
+			[0] = INTF_DISABLED,
+			[1] = INTF_DSI,
+		},
+	},
+	.perf = {
+		.ab_inefficiency = 100,
+		.ib_inefficiency = 200,
+		.clk_inefficiency = 105
+	},
+	.max_clk = 320000000,
+};
+
+static const struct mdp5_cfg_hw msm8x36_config = {
+	.name = "msm8x36",
+	.mdp = {
+		.count = 1,
+		.base = { 0x0 },
+		.caps = MDP_CAP_SMP |
+			0,
+	},
+	.smp = {
+		.mmb_count = 8,
+		.mmb_size = 10240,
+		.clients = {
+			[SSPP_VIG0] = 1, [SSPP_DMA0] = 4,
+			[SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
+		},
+	},
+	.ctl = {
+		.count = 3,
+		.base = { 0x01000, 0x01200, 0x01400 },
+		.flush_hw_mask = 0x4003ffff,
+	},
+	.pipe_vig = {
+		.count = 1,
+		.base = { 0x04000 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
+				MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
+				MDP_PIPE_CAP_DECIMATION,
+	},
+	.pipe_rgb = {
+		.count = 2,
+		.base = { 0x14000, 0x16000 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
+				MDP_PIPE_CAP_DECIMATION,
+	},
+	.pipe_dma = {
+		.count = 1,
+		.base = { 0x24000 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
+	},
+	.lm = {
+		.count = 2,
+		.base = { 0x44000, 0x47000 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 1, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB, },
+				},
+		.nb_stages = 8,
+		.max_width = 2560,
+		.max_height = 0xFFFF,
+	},
+	.pp = {
+		.count = 1,
+		.base = { 0x70000 },
+	},
+	.ad = {
+		.count = 1,
+		.base = { 0x78000 },
+	},
+	.dspp = {
+		.count = 1,
+		.base = { 0x54000 },
+	},
+	.intf = {
+		.base = { 0x00000, 0x6a800, 0x6b000 },
+		.connect = {
+			[0] = INTF_DISABLED,
+			[1] = INTF_DSI,
+			[2] = INTF_DSI,
+		},
+	},
+	.perf = {
+		.ab_inefficiency = 100,
+		.ib_inefficiency = 200,
+		.clk_inefficiency = 105
+	},
+	.max_clk = 366670000,
+};
+
+static const struct mdp5_cfg_hw msm8x94_config = {
+	.name = "msm8x94",
+	.mdp = {
+		.count = 1,
+		.caps = MDP_CAP_SMP |
+			MDP_CAP_SRC_SPLIT |
+			0,
+	},
+	.smp = {
+		.mmb_count = 44,
+		.mmb_size = 8192,
+		.clients = {
+			[SSPP_VIG0] =  1, [SSPP_VIG1] =  4,
+			[SSPP_VIG2] =  7, [SSPP_VIG3] = 19,
+			[SSPP_DMA0] = 10, [SSPP_DMA1] = 13,
+			[SSPP_RGB0] = 16, [SSPP_RGB1] = 17,
+			[SSPP_RGB2] = 18, [SSPP_RGB3] = 22,
+		},
+		.reserved_state[0] = GENMASK(23, 0),	/* first 24 MMBs */
+		.reserved = {
+			 [1] = 1,  [4] = 1,  [7] = 1, [19] = 1,
+			[16] = 5, [17] = 5, [18] = 5, [22] = 5,
+		},
+	},
+	.ctl = {
+		.count = 5,
+		.base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
+		.flush_hw_mask = 0xf0ffffff,
+	},
+	.pipe_vig = {
+		.count = 4,
+		.base = { 0x04000, 0x06000, 0x08000, 0x0a000 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
+				MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC |
+				MDP_PIPE_CAP_DECIMATION,
+	},
+	.pipe_rgb = {
+		.count = 4,
+		.base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
+				MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_DECIMATION,
+	},
+	.pipe_dma = {
+		.count = 2,
+		.base = { 0x24000, 0x26000 },
+		.caps = MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP,
+	},
+	.lm = {
+		.count = 6,
+		.base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY |
+					  MDP_LM_CAP_PAIR, },
+				{ .id = 1, .pp = 1, .dspp = 1,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 2, .pp = 2, .dspp = 2,
+				  .caps = MDP_LM_CAP_DISPLAY |
+					  MDP_LM_CAP_PAIR, },
+				{ .id = 3, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB, },
+				{ .id = 4, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB, },
+				{ .id = 5, .pp = 3, .dspp = 3,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+			     },
+		.nb_stages = 8,
+		.max_width = 2048,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 4,
+		.base = { 0x54000, 0x56000, 0x58000, 0x5a000 },
+
+	},
+	.ad = {
+		.count = 3,
+		.base = { 0x78000, 0x78800, 0x79000 },
+	},
+	.pp = {
+		.count = 4,
+		.base = { 0x70000, 0x70800, 0x71000, 0x71800 },
+	},
+	.intf = {
+		.base = { 0x6a000, 0x6a800, 0x6b000, 0x6b800, 0x6c000 },
+		.connect = {
+			[0] = INTF_DISABLED,
+			[1] = INTF_DSI,
+			[2] = INTF_DSI,
+			[3] = INTF_HDMI,
+		},
+	},
+	.perf = {
+		.ab_inefficiency = 100,
+		.ib_inefficiency = 100,
+		.clk_inefficiency = 105
+	},
+	.max_clk = 400000000,
+};
+
+static const struct mdp5_cfg_hw msm8x96_config = {
+	.name = "msm8x96",
+	.mdp = {
+		.count = 1,
+		.caps = MDP_CAP_DSC |
+			MDP_CAP_CDM |
+			MDP_CAP_SRC_SPLIT |
+			0,
+	},
+	.ctl = {
+		.count = 5,
+		.base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
+		.flush_hw_mask = 0xf4ffffff,
+	},
+	.pipe_vig = {
+		.count = 4,
+		.base = { 0x04000, 0x06000, 0x08000, 0x0a000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SCALE	|
+			MDP_PIPE_CAP_CSC	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_rgb = {
+		.count = 4,
+		.base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SCALE	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_dma = {
+		.count = 2,
+		.base = { 0x24000, 0x26000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_cursor = {
+		.count = 2,
+		.base = { 0x34000, 0x36000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			MDP_PIPE_CAP_CURSOR	|
+			0,
+	},
+
+	.lm = {
+		.count = 6,
+		.base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY |
+					  MDP_LM_CAP_PAIR, },
+				{ .id = 1, .pp = 1, .dspp = 1,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 2, .pp = 2, .dspp = -1,
+				  .caps = MDP_LM_CAP_DISPLAY |
+					  MDP_LM_CAP_PAIR, },
+				{ .id = 3, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB, },
+				{ .id = 4, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB, },
+				{ .id = 5, .pp = 3, .dspp = -1,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+			     },
+		.nb_stages = 8,
+		.max_width = 2560,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 2,
+		.base = { 0x54000, 0x56000 },
+	},
+	.ad = {
+		.count = 3,
+		.base = { 0x78000, 0x78800, 0x79000 },
+	},
+	.pp = {
+		.count = 4,
+		.base = { 0x70000, 0x70800, 0x71000, 0x71800 },
+	},
+	.cdm = {
+		.count = 1,
+		.base = { 0x79200 },
+	},
+	.dsc = {
+		.count = 2,
+		.base = { 0x80000, 0x80400 },
+	},
+	.intf = {
+		.base = { 0x6a000, 0x6a800, 0x6b000, 0x6b800, 0x6c000 },
+		.connect = {
+			[0] = INTF_DISABLED,
+			[1] = INTF_DSI,
+			[2] = INTF_DSI,
+			[3] = INTF_HDMI,
+		},
+	},
+	.perf = {
+		.ab_inefficiency = 100,
+		.ib_inefficiency = 200,
+		.clk_inefficiency = 105
+	},
+	.max_clk = 412500000,
+};
+
+static const struct mdp5_cfg_hw msm8x76_config = {
+	.name = "msm8x76",
+	.mdp = {
+		.count = 1,
+		.caps = MDP_CAP_SMP |
+			MDP_CAP_DSC |
+			MDP_CAP_SRC_SPLIT |
+			0,
+	},
+	.ctl = {
+		.count = 3,
+		.base = { 0x01000, 0x01200, 0x01400 },
+		.flush_hw_mask = 0xffffffff,
+	},
+	.smp = {
+		.mmb_count = 10,
+		.mmb_size = 10240,
+		.clients = {
+			[SSPP_VIG0] = 1, [SSPP_VIG1] = 9,
+			[SSPP_DMA0] = 4,
+			[SSPP_RGB0] = 7, [SSPP_RGB1] = 8,
+		},
+	},
+	.pipe_vig = {
+		.count = 2,
+		.base = { 0x04000, 0x06000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SCALE	|
+			MDP_PIPE_CAP_CSC	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_rgb = {
+		.count = 2,
+		.base = { 0x14000, 0x16000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_dma = {
+		.count = 1,
+		.base = { 0x24000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_cursor = {
+		.count = 1,
+		.base = { 0x440DC },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			MDP_PIPE_CAP_CURSOR	|
+			0,
+	},
+	.lm = {
+		.count = 2,
+		.base = { 0x44000, 0x45000 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 1, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB },
+			     },
+		.nb_stages = 8,
+		.max_width = 2560,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 1,
+		.base = { 0x54000 },
+
+	},
+	.pp = {
+		.count = 3,
+		.base = { 0x70000, 0x70800, 0x72000 },
+	},
+	.dsc = {
+		.count = 2,
+		.base = { 0x80000, 0x80400 },
+	},
+	.intf = {
+		.base = { 0x6a000, 0x6a800, 0x6b000 },
+		.connect = {
+			[0] = INTF_DISABLED,
+			[1] = INTF_DSI,
+			[2] = INTF_DSI,
+		},
+	},
+	.max_clk = 360000000,
+};
+
+static const struct mdp5_cfg_hw msm8x53_config = {
+	.name = "msm8x53",
+	.mdp = {
+		.count = 1,
+		.caps = MDP_CAP_CDM |
+			MDP_CAP_SRC_SPLIT,
+	},
+	.ctl = {
+		.count = 3,
+		.base = { 0x01000, 0x01200, 0x01400 },
+		.flush_hw_mask = 0xffffffff,
+	},
+	.pipe_vig = {
+		.count = 1,
+		.base = { 0x04000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SCALE	|
+			MDP_PIPE_CAP_CSC	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_rgb = {
+		.count = 2,
+		.base = { 0x14000, 0x16000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_dma = {
+		.count = 1,
+		.base = { 0x24000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_cursor = {
+		.count = 1,
+		.base = { 0x34000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			MDP_PIPE_CAP_CURSOR	|
+			0,
+	},
+
+	.lm = {
+		.count = 3,
+		.base = { 0x44000, 0x45000 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY |
+					  MDP_LM_CAP_PAIR },
+				{ .id = 1, .pp = 1, .dspp = -1,
+				  .caps = MDP_LM_CAP_DISPLAY },
+			     },
+		.nb_stages = 5,
+		.max_width = 2048,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 1,
+		.base = { 0x54000 },
+
+	},
+	.pp = {
+		.count = 2,
+		.base = { 0x70000, 0x70800 },
+	},
+	.cdm = {
+		.count = 1,
+		.base = { 0x79200 },
+	},
+	.intf = {
+		.base = { 0x6a000, 0x6a800, 0x6b000 },
+		.connect = {
+			[0] = INTF_DISABLED,
+			[1] = INTF_DSI,
+			[2] = INTF_DSI,
+		},
+	},
+	.perf = {
+		.ab_inefficiency = 100,
+		.ib_inefficiency = 200,
+		.clk_inefficiency = 105
+	},
+	.max_clk = 400000000,
+};
+
+static const struct mdp5_cfg_hw msm8917_config = {
+	.name = "msm8917",
+	.mdp = {
+		.count = 1,
+		.caps = MDP_CAP_CDM,
+	},
+	.ctl = {
+		.count = 3,
+		.base = { 0x01000, 0x01200, 0x01400 },
+		.flush_hw_mask = 0xffffffff,
+	},
+	.pipe_vig = {
+		.count = 1,
+		.base = { 0x04000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SCALE	|
+			MDP_PIPE_CAP_CSC	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_rgb = {
+		.count = 2,
+		.base = { 0x14000, 0x16000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_dma = {
+		.count = 1,
+		.base = { 0x24000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_cursor = {
+		.count = 1,
+		.base = { 0x34000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			MDP_PIPE_CAP_CURSOR	|
+			0,
+	},
+
+	.lm = {
+		.count = 2,
+		.base = { 0x44000, 0x45000 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 1, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB },
+			     },
+		.nb_stages = 8,
+		.max_width = 2048,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 1,
+		.base = { 0x54000 },
+
+	},
+	.pp = {
+		.count = 1,
+		.base = { 0x70000 },
+	},
+	.cdm = {
+		.count = 1,
+		.base = { 0x79200 },
+	},
+	.intf = {
+		.base = { 0x6a000, 0x6a800 },
+		.connect = {
+			[0] = INTF_DISABLED,
+			[1] = INTF_DSI,
+		},
+	},
+	.max_clk = 320000000,
+};
+
+static const struct mdp5_cfg_hw msm8998_config = {
+	.name = "msm8998",
+	.mdp = {
+		.count = 1,
+		.caps = MDP_CAP_DSC |
+			MDP_CAP_CDM |
+			MDP_CAP_SRC_SPLIT |
+			0,
+	},
+	.ctl = {
+		.count = 5,
+		.base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
+		.flush_hw_mask = 0xf7ffffff,
+	},
+	.pipe_vig = {
+		.count = 4,
+		.base = { 0x04000, 0x06000, 0x08000, 0x0a000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SCALE	|
+			MDP_PIPE_CAP_CSC	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_rgb = {
+		.count = 4,
+		.base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SCALE	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_dma = {
+		.count = 2, /* driver supports max of 2 currently */
+		.base = { 0x24000, 0x26000, 0x28000, 0x2a000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_cursor = {
+		.count = 2,
+		.base = { 0x34000, 0x36000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			MDP_PIPE_CAP_CURSOR	|
+			0,
+	},
+
+	.lm = {
+		.count = 6,
+		.base = { 0x44000, 0x45000, 0x46000, 0x47000, 0x48000, 0x49000 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY |
+					  MDP_LM_CAP_PAIR, },
+				{ .id = 1, .pp = 1, .dspp = 1,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 2, .pp = 2, .dspp = -1,
+				  .caps = MDP_LM_CAP_DISPLAY |
+					  MDP_LM_CAP_PAIR, },
+				{ .id = 3, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB, },
+				{ .id = 4, .pp = -1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB, },
+				{ .id = 5, .pp = 3, .dspp = -1,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+			     },
+		.nb_stages = 8,
+		.max_width = 2560,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 2,
+		.base = { 0x54000, 0x56000 },
+	},
+	.ad = {
+		.count = 3,
+		.base = { 0x78000, 0x78800, 0x79000 },
+	},
+	.pp = {
+		.count = 4,
+		.base = { 0x70000, 0x70800, 0x71000, 0x71800 },
+	},
+	.cdm = {
+		.count = 1,
+		.base = { 0x79200 },
+	},
+	.dsc = {
+		.count = 2,
+		.base = { 0x80000, 0x80400 },
+	},
+	.intf = {
+		.base = { 0x6a000, 0x6a800, 0x6b000, 0x6b800, 0x6c000 },
+		.connect = {
+			[0] = INTF_eDP,
+			[1] = INTF_DSI,
+			[2] = INTF_DSI,
+			[3] = INTF_HDMI,
+		},
+	},
+	.max_clk = 412500000,
+};
+
+static const struct mdp5_cfg_hw sdm630_config = {
+	.name = "sdm630",
+	.mdp = {
+		.count = 1,
+		.caps = MDP_CAP_CDM |
+			MDP_CAP_SRC_SPLIT |
+			0,
+	},
+	.ctl = {
+		.count = 5,
+		.base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
+		.flush_hw_mask = 0xf4ffffff,
+	},
+	.pipe_vig = {
+		.count = 1,
+		.base = { 0x04000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SCALE	|
+			MDP_PIPE_CAP_CSC	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_rgb = {
+		.count = 4,
+		.base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SCALE	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_dma = {
+		.count = 2, /* driver supports max of 2 currently */
+		.base = { 0x24000, 0x26000, 0x28000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_cursor = {
+		.count = 1,
+		.base = { 0x34000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			MDP_PIPE_CAP_CURSOR	|
+			0,
+	},
+
+	.lm = {
+		.count = 2,
+		.base = { 0x44000, 0x46000 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY |
+					  MDP_LM_CAP_PAIR, },
+				{ .id = 1, .pp = 1, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB, },
+				},
+		.nb_stages = 8,
+		.max_width = 2048,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 1,
+		.base = { 0x54000 },
+	},
+	.ad = {
+		.count = 2,
+		.base = { 0x78000, 0x78800 },
+	},
+	.pp = {
+		.count = 3,
+		.base = { 0x70000, 0x71000, 0x72000 },
+	},
+	.cdm = {
+		.count = 1,
+		.base = { 0x79200 },
+	},
+	.intf = {
+		.base = { 0x6a000, 0x6a800 },
+		.connect = {
+			[0] = INTF_DISABLED,
+			[1] = INTF_DSI,
+		},
+	},
+	.max_clk = 412500000,
+};
+
+static const struct mdp5_cfg_hw sdm660_config = {
+	.name = "sdm660",
+	.mdp = {
+		.count = 1,
+		.caps = MDP_CAP_DSC |
+			MDP_CAP_CDM |
+			MDP_CAP_SRC_SPLIT |
+			0,
+	},
+	.ctl = {
+		.count = 5,
+		.base = { 0x01000, 0x01200, 0x01400, 0x01600, 0x01800 },
+		.flush_hw_mask = 0xf4ffffff,
+	},
+	.pipe_vig = {
+		.count = 2,
+		.base = { 0x04000, 0x6000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SCALE	|
+			MDP_PIPE_CAP_CSC	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_rgb = {
+		.count = 4,
+		.base = { 0x14000, 0x16000, 0x18000, 0x1a000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SCALE	|
+			MDP_PIPE_CAP_DECIMATION	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_dma = {
+		.count = 2, /* driver supports max of 2 currently */
+		.base = { 0x24000, 0x26000, 0x28000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			0,
+	},
+	.pipe_cursor = {
+		.count = 1,
+		.base = { 0x34000 },
+		.caps = MDP_PIPE_CAP_HFLIP	|
+			MDP_PIPE_CAP_VFLIP	|
+			MDP_PIPE_CAP_SW_PIX_EXT	|
+			MDP_PIPE_CAP_CURSOR	|
+			0,
+	},
+
+	.lm = {
+		.count = 4,
+		.base = { 0x44000, 0x45000, 0x46000, 0x49000 },
+		.instances = {
+				{ .id = 0, .pp = 0, .dspp = 0,
+				  .caps = MDP_LM_CAP_DISPLAY |
+					  MDP_LM_CAP_PAIR, },
+				{ .id = 1, .pp = 1, .dspp = 1,
+				  .caps = MDP_LM_CAP_DISPLAY, },
+				{ .id = 2, .pp = 2, .dspp = -1,
+				  .caps = MDP_LM_CAP_DISPLAY |
+					  MDP_LM_CAP_PAIR, },
+				{ .id = 3, .pp = 3, .dspp = -1,
+				  .caps = MDP_LM_CAP_WB, },
+				},
+		.nb_stages = 8,
+		.max_width = 2560,
+		.max_height = 0xFFFF,
+	},
+	.dspp = {
+		.count = 2,
+		.base = { 0x54000, 0x56000 },
+	},
+	.ad = {
+		.count = 2,
+		.base = { 0x78000, 0x78800 },
+	},
+	.pp = {
+		.count = 5,
+		.base = { 0x70000, 0x70800, 0x71000, 0x71800, 0x72000 },
+	},
+	.cdm = {
+		.count = 1,
+		.base = { 0x79200 },
+	},
+	.dsc = {
+		.count = 2,
+		.base = { 0x80000, 0x80400 },
+	},
+	.intf = {
+		.base = { 0x6a000, 0x6a800, 0x6b000, 0x6b800 },
+		.connect = {
+			[0] = INTF_DISABLED,
+			[1] = INTF_DSI,
+			[2] = INTF_DSI,
+			[3] = INTF_HDMI,
+		},
+	},
+	.max_clk = 412500000,
+};
+
+static const struct mdp5_cfg_handler cfg_handlers_v1[] = {
+	{ .revision = 0, .config = { .hw = &msm8x74v1_config } },
+	{ .revision = 1, .config = { .hw = &msm8x26_config } },
+	{ .revision = 2, .config = { .hw = &msm8x74v2_config } },
+	{ .revision = 3, .config = { .hw = &apq8084_config } },
+	{ .revision = 6, .config = { .hw = &msm8x16_config } },
+	{ .revision = 8, .config = { .hw = &msm8x36_config } },
+	{ .revision = 9, .config = { .hw = &msm8x94_config } },
+	{ .revision = 7, .config = { .hw = &msm8x96_config } },
+	{ .revision = 11, .config = { .hw = &msm8x76_config } },
+	{ .revision = 15, .config = { .hw = &msm8917_config } },
+	{ .revision = 16, .config = { .hw = &msm8x53_config } },
+};
+
+static const struct mdp5_cfg_handler cfg_handlers_v3[] = {
+	{ .revision = 0, .config = { .hw = &msm8998_config } },
+	{ .revision = 2, .config = { .hw = &sdm660_config } },
+	{ .revision = 3, .config = { .hw = &sdm630_config } },
+};
+
+const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(struct mdp5_cfg_handler *cfg_handler)
+{
+	return cfg_handler->config.hw;
+}
+
+struct mdp5_cfg *mdp5_cfg_get_config(struct mdp5_cfg_handler *cfg_handler)
+{
+	return &cfg_handler->config;
+}
+
+int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_handler)
+{
+	return cfg_handler->revision;
+}
+
+struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms,
+		uint32_t major, uint32_t minor)
+{
+	struct drm_device *dev = mdp5_kms->dev;
+	struct mdp5_cfg_handler *cfg_handler;
+	const struct mdp5_cfg_handler *cfg_handlers;
+	int i, num_handlers;
+
+	cfg_handler = devm_kzalloc(dev->dev, sizeof(*cfg_handler), GFP_KERNEL);
+	if (unlikely(!cfg_handler)) {
+		return ERR_PTR(-ENOMEM);
+	}
+
+	switch (major) {
+	case 1:
+		cfg_handlers = cfg_handlers_v1;
+		num_handlers = ARRAY_SIZE(cfg_handlers_v1);
+		break;
+	case 3:
+		cfg_handlers = cfg_handlers_v3;
+		num_handlers = ARRAY_SIZE(cfg_handlers_v3);
+		break;
+	default:
+		DRM_DEV_ERROR(dev->dev, "unexpected MDP major version: v%d.%d\n",
+				major, minor);
+		return ERR_PTR(-ENXIO);
+	}
+
+	/* only after mdp5_cfg global pointer's init can we access the hw */
+	for (i = 0; i < num_handlers; i++) {
+		if (cfg_handlers[i].revision != minor)
+			continue;
+		mdp5_cfg = cfg_handlers[i].config.hw;
+
+		break;
+	}
+	if (unlikely(!mdp5_cfg)) {
+		DRM_DEV_ERROR(dev->dev, "unexpected MDP minor revision: v%d.%d\n",
+				major, minor);
+		return ERR_PTR(-ENXIO);
+	}
+
+	cfg_handler->revision = minor;
+	cfg_handler->config.hw = mdp5_cfg;
+
+	DBG("MDP5: %s hw config selected", mdp5_cfg->name);
+
+	return cfg_handler;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_cfg.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_cfg.h
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __MDP5_CFG_H__
+#define __MDP5_CFG_H__
+
+#include "msm_drv.h"
+
+/*
+ * mdp5_cfg
+ *
+ * This module configures the dynamic offsets used by mdp5.xml.h
+ * (initialized in mdp5_cfg.c)
+ */
+extern const struct mdp5_cfg_hw *mdp5_cfg;
+
+#define MAX_CTL			8
+#define MAX_BASES		8
+#define MAX_SMP_BLOCKS		44
+#define MAX_CLIENTS		32
+
+typedef DECLARE_BITMAP(mdp5_smp_state_t, MAX_SMP_BLOCKS);
+
+#define MDP5_SUB_BLOCK_DEFINITION \
+	unsigned int count; \
+	uint32_t base[MAX_BASES]
+
+struct mdp5_sub_block {
+	MDP5_SUB_BLOCK_DEFINITION;
+};
+
+struct mdp5_lm_instance {
+	int id;
+	int pp;
+	int dspp;
+	uint32_t caps;
+};
+
+struct mdp5_lm_block {
+	MDP5_SUB_BLOCK_DEFINITION;
+	struct mdp5_lm_instance instances[MAX_BASES];
+	uint32_t nb_stages;		/* number of stages per blender */
+	uint32_t max_width;		/* Maximum output resolution */
+	uint32_t max_height;
+};
+
+struct mdp5_pipe_block {
+	MDP5_SUB_BLOCK_DEFINITION;
+	uint32_t caps;			/* pipe capabilities */
+};
+
+struct mdp5_ctl_block {
+	MDP5_SUB_BLOCK_DEFINITION;
+	uint32_t flush_hw_mask;		/* FLUSH register's hardware mask */
+};
+
+struct mdp5_smp_block {
+	int mmb_count;			/* number of SMP MMBs */
+	int mmb_size;			/* MMB: size in bytes */
+	uint32_t clients[MAX_CLIENTS];	/* SMP port allocation /pipe */
+	mdp5_smp_state_t reserved_state;/* SMP MMBs statically allocated */
+	uint8_t reserved[MAX_CLIENTS];	/* # of MMBs allocated per client */
+};
+
+struct mdp5_mdp_block {
+	MDP5_SUB_BLOCK_DEFINITION;
+	uint32_t caps;			/* MDP capabilities: MDP_CAP_xxx bits */
+};
+
+struct mdp5_wb_instance {
+	int id;
+	int lm;
+};
+
+struct mdp5_wb_block {
+	MDP5_SUB_BLOCK_DEFINITION;
+	struct mdp5_wb_instance instances[MAX_BASES];
+};
+
+#define MDP5_INTF_NUM_MAX	5
+
+struct mdp5_intf_block {
+	uint32_t base[MAX_BASES];
+	u32 connect[MDP5_INTF_NUM_MAX]; /* array of enum mdp5_intf_type */
+};
+
+struct mdp5_perf_block {
+	u32 ab_inefficiency;
+	u32 ib_inefficiency;
+	u32 clk_inefficiency;
+};
+
+struct mdp5_cfg_hw {
+	char  *name;
+
+	struct mdp5_mdp_block mdp;
+	struct mdp5_smp_block smp;
+	struct mdp5_ctl_block ctl;
+	struct mdp5_pipe_block pipe_vig;
+	struct mdp5_pipe_block pipe_rgb;
+	struct mdp5_pipe_block pipe_dma;
+	struct mdp5_pipe_block pipe_cursor;
+	struct mdp5_lm_block  lm;
+	struct mdp5_sub_block dspp;
+	struct mdp5_sub_block ad;
+	struct mdp5_sub_block pp;
+	struct mdp5_sub_block dsc;
+	struct mdp5_sub_block cdm;
+	struct mdp5_wb_block wb;
+	struct mdp5_intf_block intf;
+	struct mdp5_perf_block perf;
+
+	uint32_t max_clk;
+};
+
+struct mdp5_cfg {
+	const struct mdp5_cfg_hw *hw;
+};
+
+struct mdp5_kms;
+struct mdp5_cfg_handler;
+
+const struct mdp5_cfg_hw *mdp5_cfg_get_hw_config(struct mdp5_cfg_handler *cfg_hnd);
+struct mdp5_cfg *mdp5_cfg_get_config(struct mdp5_cfg_handler *cfg_hnd);
+int mdp5_cfg_get_hw_rev(struct mdp5_cfg_handler *cfg_hnd);
+
+#define mdp5_cfg_intf_is_virtual(intf_type) ({	\
+	typeof(intf_type) __val = (intf_type);	\
+	(__val) >= INTF_VIRTUAL ? true : false; })
+
+struct mdp5_cfg_handler *mdp5_cfg_init(struct mdp5_kms *mdp5_kms,
+		uint32_t major, uint32_t minor);
+
+#endif /* __MDP5_CFG_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_cmd_encoder.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_cmd_encoder.c
@@ -0,0 +1,203 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ */
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_probe_helper.h>
+
+#include "mdp5_kms.h"
+
+#ifdef CONFIG_DRM_MSM_DSI
+
+static struct mdp5_kms *get_kms(struct drm_encoder *encoder)
+{
+	struct msm_drm_private *priv = encoder->dev->dev_private;
+	return to_mdp5_kms(to_mdp_kms(priv->kms));
+}
+
+#define VSYNC_CLK_RATE 19200000
+static int pingpong_tearcheck_setup(struct drm_encoder *encoder,
+				    struct drm_display_mode *mode)
+{
+	struct mdp5_kms *mdp5_kms = get_kms(encoder);
+	struct device *dev = encoder->dev->dev;
+	u32 total_lines, vclks_line, cfg;
+	long vsync_clk_speed;
+	struct mdp5_hw_mixer *mixer = mdp5_crtc_get_mixer(encoder->crtc);
+	int pp_id = mixer->pp;
+
+	if (IS_ERR_OR_NULL(mdp5_kms->vsync_clk)) {
+		DRM_DEV_ERROR(dev, "vsync_clk is not initialized\n");
+		return -EINVAL;
+	}
+
+	total_lines = mode->vtotal * drm_mode_vrefresh(mode);
+	if (!total_lines) {
+		DRM_DEV_ERROR(dev, "%s: vtotal(%d) or vrefresh(%d) is 0\n",
+			      __func__, mode->vtotal, drm_mode_vrefresh(mode));
+		return -EINVAL;
+	}
+
+	vsync_clk_speed = clk_round_rate(mdp5_kms->vsync_clk, VSYNC_CLK_RATE);
+	if (vsync_clk_speed <= 0) {
+		DRM_DEV_ERROR(dev, "vsync_clk round rate failed %ld\n",
+							vsync_clk_speed);
+		return -EINVAL;
+	}
+	vclks_line = vsync_clk_speed / total_lines;
+
+	cfg = MDP5_PP_SYNC_CONFIG_VSYNC_COUNTER_EN
+		| MDP5_PP_SYNC_CONFIG_VSYNC_IN_EN;
+	cfg |= MDP5_PP_SYNC_CONFIG_VSYNC_COUNT(vclks_line);
+
+	/*
+	 * Tearcheck emits a blanking signal every vclks_line * vtotal * 2 ticks on
+	 * the vsync_clk equating to roughly half the desired panel refresh rate.
+	 * This is only necessary as stability fallback if interrupts from the
+	 * panel arrive too late or not at all, but is currently used by default
+	 * because these panel interrupts are not wired up yet.
+	 */
+	mdp5_write(mdp5_kms, REG_MDP5_PP_SYNC_CONFIG_VSYNC(pp_id), cfg);
+	mdp5_write(mdp5_kms,
+		REG_MDP5_PP_SYNC_CONFIG_HEIGHT(pp_id), (2 * mode->vtotal));
+
+	mdp5_write(mdp5_kms,
+		REG_MDP5_PP_VSYNC_INIT_VAL(pp_id), mode->vdisplay);
+	mdp5_write(mdp5_kms, REG_MDP5_PP_RD_PTR_IRQ(pp_id), mode->vdisplay + 1);
+	mdp5_write(mdp5_kms, REG_MDP5_PP_START_POS(pp_id), mode->vdisplay);
+	mdp5_write(mdp5_kms, REG_MDP5_PP_SYNC_THRESH(pp_id),
+			MDP5_PP_SYNC_THRESH_START(4) |
+			MDP5_PP_SYNC_THRESH_CONTINUE(4));
+	mdp5_write(mdp5_kms, REG_MDP5_PP_AUTOREFRESH_CONFIG(pp_id), 0x0);
+
+	return 0;
+}
+
+static int pingpong_tearcheck_enable(struct drm_encoder *encoder)
+{
+	struct mdp5_kms *mdp5_kms = get_kms(encoder);
+	struct mdp5_hw_mixer *mixer = mdp5_crtc_get_mixer(encoder->crtc);
+	int pp_id = mixer->pp;
+	int ret;
+
+	ret = clk_set_rate(mdp5_kms->vsync_clk,
+		clk_round_rate(mdp5_kms->vsync_clk, VSYNC_CLK_RATE));
+	if (ret) {
+		DRM_DEV_ERROR(encoder->dev->dev,
+			"vsync_clk clk_set_rate failed, %d\n", ret);
+		return ret;
+	}
+	ret = clk_prepare_enable(mdp5_kms->vsync_clk);
+	if (ret) {
+		DRM_DEV_ERROR(encoder->dev->dev,
+			"vsync_clk clk_prepare_enable failed, %d\n", ret);
+		return ret;
+	}
+
+	mdp5_write(mdp5_kms, REG_MDP5_PP_TEAR_CHECK_EN(pp_id), 1);
+
+	return 0;
+}
+
+static void pingpong_tearcheck_disable(struct drm_encoder *encoder)
+{
+	struct mdp5_kms *mdp5_kms = get_kms(encoder);
+	struct mdp5_hw_mixer *mixer = mdp5_crtc_get_mixer(encoder->crtc);
+	int pp_id = mixer->pp;
+
+	mdp5_write(mdp5_kms, REG_MDP5_PP_TEAR_CHECK_EN(pp_id), 0);
+	clk_disable_unprepare(mdp5_kms->vsync_clk);
+}
+
+void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode)
+{
+	mode = adjusted_mode;
+
+	DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
+	pingpong_tearcheck_setup(encoder, mode);
+	mdp5_crtc_set_pipeline(encoder->crtc);
+}
+
+void mdp5_cmd_encoder_disable(struct drm_encoder *encoder)
+{
+	struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
+	struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl;
+	struct mdp5_interface *intf = mdp5_cmd_enc->intf;
+	struct mdp5_pipeline *pipeline = mdp5_crtc_get_pipeline(encoder->crtc);
+
+	if (WARN_ON(!mdp5_cmd_enc->enabled))
+		return;
+
+	pingpong_tearcheck_disable(encoder);
+
+	mdp5_ctl_set_encoder_state(ctl, pipeline, false);
+	mdp5_ctl_commit(ctl, pipeline, mdp_ctl_flush_mask_encoder(intf), true);
+
+	mdp5_cmd_enc->enabled = false;
+}
+
+void mdp5_cmd_encoder_enable(struct drm_encoder *encoder)
+{
+	struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
+	struct mdp5_ctl *ctl = mdp5_cmd_enc->ctl;
+	struct mdp5_interface *intf = mdp5_cmd_enc->intf;
+	struct mdp5_pipeline *pipeline = mdp5_crtc_get_pipeline(encoder->crtc);
+
+	if (WARN_ON(mdp5_cmd_enc->enabled))
+		return;
+
+	if (pingpong_tearcheck_enable(encoder))
+		return;
+
+	mdp5_ctl_commit(ctl, pipeline, mdp_ctl_flush_mask_encoder(intf), true);
+
+	mdp5_ctl_set_encoder_state(ctl, pipeline, true);
+
+	mdp5_cmd_enc->enabled = true;
+}
+
+int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
+				       struct drm_encoder *slave_encoder)
+{
+	struct mdp5_encoder *mdp5_cmd_enc = to_mdp5_encoder(encoder);
+	struct mdp5_kms *mdp5_kms;
+	struct device *dev;
+	int intf_num;
+	u32 data = 0;
+
+	if (!encoder || !slave_encoder)
+		return -EINVAL;
+
+	mdp5_kms = get_kms(encoder);
+	intf_num = mdp5_cmd_enc->intf->num;
+
+	/* Switch slave encoder's trigger MUX, to use the master's
+	 * start signal for the slave encoder
+	 */
+	if (intf_num == 1)
+		data |= MDP5_SPLIT_DPL_UPPER_INTF2_SW_TRG_MUX;
+	else if (intf_num == 2)
+		data |= MDP5_SPLIT_DPL_UPPER_INTF1_SW_TRG_MUX;
+	else
+		return -EINVAL;
+
+	/* Smart Panel, Sync mode */
+	data |= MDP5_SPLIT_DPL_UPPER_SMART_PANEL;
+
+	dev = &mdp5_kms->pdev->dev;
+
+	/* Make sure clocks are on when connectors calling this function. */
+	pm_runtime_get_sync(dev);
+	mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_UPPER, data);
+
+	mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_LOWER,
+		   MDP5_SPLIT_DPL_LOWER_SMART_PANEL);
+	mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_EN, 1);
+	pm_runtime_put_sync(dev);
+
+	return 0;
+}
+#endif /* CONFIG_DRM_MSM_DSI */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_crtc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_crtc.c
@@ -0,0 +1,1360 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/sort.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_blend.h>
+#include <drm/drm_mode.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_flip_work.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_managed.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_vblank.h>
+
+#include "mdp5_kms.h"
+#include "msm_gem.h"
+
+#define CURSOR_WIDTH	64
+#define CURSOR_HEIGHT	64
+
+struct mdp5_crtc {
+	struct drm_crtc base;
+	int id;
+	bool enabled;
+
+	spinlock_t lm_lock;     /* protect REG_MDP5_LM_* registers */
+
+	/* if there is a pending flip, these will be non-null: */
+	struct drm_pending_vblank_event *event;
+
+	/* Bits have been flushed at the last commit,
+	 * used to decide if a vsync has happened since last commit.
+	 */
+	u32 flushed_mask;
+
+#define PENDING_CURSOR 0x1
+#define PENDING_FLIP   0x2
+	atomic_t pending;
+
+	/* for unref'ing cursor bo's after scanout completes: */
+	struct drm_flip_work unref_cursor_work;
+
+	struct mdp_irq vblank;
+	struct mdp_irq err;
+	struct mdp_irq pp_done;
+
+	struct completion pp_completion;
+
+	bool lm_cursor_enabled;
+
+	struct {
+		/* protect REG_MDP5_LM_CURSOR* registers and cursor scanout_bo*/
+		spinlock_t lock;
+
+		/* current cursor being scanned out: */
+		struct drm_gem_object *scanout_bo;
+		uint64_t iova;
+		uint32_t width, height;
+		int x, y;
+	} cursor;
+};
+#define to_mdp5_crtc(x) container_of(x, struct mdp5_crtc, base)
+
+static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc);
+
+static struct mdp5_kms *get_kms(struct drm_crtc *crtc)
+{
+	struct msm_drm_private *priv = crtc->dev->dev_private;
+	return to_mdp5_kms(to_mdp_kms(priv->kms));
+}
+
+static void request_pending(struct drm_crtc *crtc, uint32_t pending)
+{
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+
+	atomic_or(pending, &mdp5_crtc->pending);
+	mdp_irq_register(&get_kms(crtc)->base, &mdp5_crtc->vblank);
+}
+
+static void request_pp_done_pending(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	reinit_completion(&mdp5_crtc->pp_completion);
+}
+
+static u32 crtc_flush(struct drm_crtc *crtc, u32 flush_mask)
+{
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct mdp5_ctl *ctl = mdp5_cstate->ctl;
+	struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline;
+	bool start = !mdp5_cstate->defer_start;
+
+	mdp5_cstate->defer_start = false;
+
+	DBG("%s: flush=%08x", crtc->name, flush_mask);
+
+	return mdp5_ctl_commit(ctl, pipeline, flush_mask, start);
+}
+
+/*
+ * flush updates, to make sure hw is updated to new scanout fb,
+ * so that we can safely queue unref to current fb (ie. next
+ * vblank we know hw is done w/ previous scanout_fb).
+ */
+static u32 crtc_flush_all(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct mdp5_hw_mixer *mixer, *r_mixer;
+	struct drm_plane *plane;
+	uint32_t flush_mask = 0;
+
+	/* this should not happen: */
+	if (WARN_ON(!mdp5_cstate->ctl))
+		return 0;
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		if (!plane->state->visible)
+			continue;
+		flush_mask |= mdp5_plane_get_flush(plane);
+	}
+
+	mixer = mdp5_cstate->pipeline.mixer;
+	flush_mask |= mdp_ctl_flush_mask_lm(mixer->lm);
+
+	r_mixer = mdp5_cstate->pipeline.r_mixer;
+	if (r_mixer)
+		flush_mask |= mdp_ctl_flush_mask_lm(r_mixer->lm);
+
+	return crtc_flush(crtc, flush_mask);
+}
+
+/* if file!=NULL, this is preclose potential cancel-flip path */
+static void complete_flip(struct drm_crtc *crtc, struct drm_file *file)
+{
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline;
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	struct mdp5_ctl *ctl = mdp5_cstate->ctl;
+	struct drm_device *dev = crtc->dev;
+	struct drm_pending_vblank_event *event;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	event = mdp5_crtc->event;
+	if (event) {
+		mdp5_crtc->event = NULL;
+		DBG("%s: send event: %p", crtc->name, event);
+		drm_crtc_send_vblank_event(crtc, event);
+	}
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	if (ctl && !crtc->state->enable) {
+		/* set STAGE_UNUSED for all layers */
+		mdp5_ctl_blend(ctl, pipeline, NULL, NULL, 0, 0);
+		/* XXX: What to do here? */
+		/* mdp5_crtc->ctl = NULL; */
+	}
+}
+
+static void unref_cursor_worker(struct drm_flip_work *work, void *val)
+{
+	struct mdp5_crtc *mdp5_crtc =
+		container_of(work, struct mdp5_crtc, unref_cursor_work);
+	struct mdp5_kms *mdp5_kms = get_kms(&mdp5_crtc->base);
+	struct msm_kms *kms = &mdp5_kms->base.base;
+
+	msm_gem_unpin_iova(val, kms->aspace);
+	drm_gem_object_put(val);
+}
+
+static void mdp5_crtc_flip_cleanup(struct drm_device *dev, void *ptr)
+{
+	struct mdp5_crtc *mdp5_crtc = ptr;
+
+	drm_flip_work_cleanup(&mdp5_crtc->unref_cursor_work);
+}
+
+static inline u32 mdp5_lm_use_fg_alpha_mask(enum mdp_mixer_stage_id stage)
+{
+	switch (stage) {
+	case STAGE0: return MDP5_LM_BLEND_COLOR_OUT_STAGE0_FG_ALPHA;
+	case STAGE1: return MDP5_LM_BLEND_COLOR_OUT_STAGE1_FG_ALPHA;
+	case STAGE2: return MDP5_LM_BLEND_COLOR_OUT_STAGE2_FG_ALPHA;
+	case STAGE3: return MDP5_LM_BLEND_COLOR_OUT_STAGE3_FG_ALPHA;
+	case STAGE4: return MDP5_LM_BLEND_COLOR_OUT_STAGE4_FG_ALPHA;
+	case STAGE5: return MDP5_LM_BLEND_COLOR_OUT_STAGE5_FG_ALPHA;
+	case STAGE6: return MDP5_LM_BLEND_COLOR_OUT_STAGE6_FG_ALPHA;
+	default:
+		return 0;
+	}
+}
+
+/*
+ * left/right pipe offsets for the stage array used in blend_setup()
+ */
+#define PIPE_LEFT	0
+#define PIPE_RIGHT	1
+
+/*
+ * blend_setup() - blend all the planes of a CRTC
+ *
+ * If no base layer is available, border will be enabled as the base layer.
+ * Otherwise all layers will be blended based on their stage calculated
+ * in mdp5_crtc_atomic_check.
+ */
+static void blend_setup(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline;
+	struct mdp5_kms *mdp5_kms = get_kms(crtc);
+	struct drm_plane *plane;
+	struct mdp5_plane_state *pstate, *pstates[STAGE_MAX + 1] = {NULL};
+	const struct mdp_format *format;
+	struct mdp5_hw_mixer *mixer = pipeline->mixer;
+	uint32_t lm = mixer->lm;
+	struct mdp5_hw_mixer *r_mixer = pipeline->r_mixer;
+	uint32_t r_lm = r_mixer ? r_mixer->lm : 0;
+	struct mdp5_ctl *ctl = mdp5_cstate->ctl;
+	uint32_t blend_op, fg_alpha, bg_alpha, ctl_blend_flags = 0;
+	unsigned long flags;
+	enum mdp5_pipe stage[STAGE_MAX + 1][MAX_PIPE_STAGE] = { { SSPP_NONE } };
+	enum mdp5_pipe r_stage[STAGE_MAX + 1][MAX_PIPE_STAGE] = { { SSPP_NONE } };
+	int i, plane_cnt = 0;
+	bool bg_alpha_enabled = false;
+	u32 mixer_op_mode = 0;
+	u32 val;
+#define blender(stage)	((stage) - STAGE0)
+
+	spin_lock_irqsave(&mdp5_crtc->lm_lock, flags);
+
+	/* ctl could be released already when we are shutting down: */
+	/* XXX: Can this happen now? */
+	if (!ctl)
+		goto out;
+
+	/* Collect all plane information */
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		enum mdp5_pipe right_pipe;
+
+		if (!plane->state->visible)
+			continue;
+
+		pstate = to_mdp5_plane_state(plane->state);
+		pstates[pstate->stage] = pstate;
+		stage[pstate->stage][PIPE_LEFT] = mdp5_plane_pipe(plane);
+		/*
+		 * if we have a right mixer, stage the same pipe as we
+		 * have on the left mixer
+		 */
+		if (r_mixer)
+			r_stage[pstate->stage][PIPE_LEFT] =
+						mdp5_plane_pipe(plane);
+		/*
+		 * if we have a right pipe (i.e, the plane comprises of 2
+		 * hwpipes, then stage the right pipe on the right side of both
+		 * the layer mixers
+		 */
+		right_pipe = mdp5_plane_right_pipe(plane);
+		if (right_pipe) {
+			stage[pstate->stage][PIPE_RIGHT] = right_pipe;
+			r_stage[pstate->stage][PIPE_RIGHT] = right_pipe;
+		}
+
+		plane_cnt++;
+	}
+
+	if (!pstates[STAGE_BASE]) {
+		ctl_blend_flags |= MDP5_CTL_BLEND_OP_FLAG_BORDER_OUT;
+		DBG("Border Color is enabled");
+	} else if (plane_cnt) {
+		format = to_mdp_format(msm_framebuffer_format(pstates[STAGE_BASE]->base.fb));
+
+		if (format->alpha_enable)
+			bg_alpha_enabled = true;
+	}
+
+	/* The reset for blending */
+	for (i = STAGE0; i <= STAGE_MAX; i++) {
+		if (!pstates[i])
+			continue;
+
+		format = to_mdp_format(
+			msm_framebuffer_format(pstates[i]->base.fb));
+		plane = pstates[i]->base.plane;
+		blend_op = MDP5_LM_BLEND_OP_MODE_FG_ALPHA(FG_CONST) |
+			MDP5_LM_BLEND_OP_MODE_BG_ALPHA(BG_CONST);
+		fg_alpha = pstates[i]->base.alpha >> 8;
+		bg_alpha = 0xFF - fg_alpha;
+
+		if (!format->alpha_enable && bg_alpha_enabled)
+			mixer_op_mode = 0;
+		else
+			mixer_op_mode |= mdp5_lm_use_fg_alpha_mask(i);
+
+		DBG("Stage %d fg_alpha %x bg_alpha %x", i, fg_alpha, bg_alpha);
+
+		if (format->alpha_enable &&
+		    pstates[i]->base.pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) {
+			blend_op = MDP5_LM_BLEND_OP_MODE_FG_ALPHA(FG_CONST) |
+				MDP5_LM_BLEND_OP_MODE_BG_ALPHA(FG_PIXEL);
+			if (fg_alpha != 0xff) {
+				bg_alpha = fg_alpha;
+				blend_op |=
+					MDP5_LM_BLEND_OP_MODE_BG_MOD_ALPHA |
+					MDP5_LM_BLEND_OP_MODE_BG_INV_MOD_ALPHA;
+			} else {
+				blend_op |= MDP5_LM_BLEND_OP_MODE_BG_INV_ALPHA;
+			}
+		} else if (format->alpha_enable &&
+			   pstates[i]->base.pixel_blend_mode == DRM_MODE_BLEND_COVERAGE) {
+			blend_op = MDP5_LM_BLEND_OP_MODE_FG_ALPHA(FG_PIXEL) |
+				MDP5_LM_BLEND_OP_MODE_BG_ALPHA(FG_PIXEL);
+			if (fg_alpha != 0xff) {
+				bg_alpha = fg_alpha;
+				blend_op |=
+				       MDP5_LM_BLEND_OP_MODE_FG_MOD_ALPHA |
+				       MDP5_LM_BLEND_OP_MODE_FG_INV_MOD_ALPHA |
+				       MDP5_LM_BLEND_OP_MODE_BG_MOD_ALPHA |
+				       MDP5_LM_BLEND_OP_MODE_BG_INV_MOD_ALPHA;
+			} else {
+				blend_op |= MDP5_LM_BLEND_OP_MODE_BG_INV_ALPHA;
+			}
+		}
+
+		mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_OP_MODE(lm,
+				blender(i)), blend_op);
+		mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_FG_ALPHA(lm,
+				blender(i)), fg_alpha);
+		mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_BG_ALPHA(lm,
+				blender(i)), bg_alpha);
+		if (r_mixer) {
+			mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_OP_MODE(r_lm,
+					blender(i)), blend_op);
+			mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_FG_ALPHA(r_lm,
+					blender(i)), fg_alpha);
+			mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_BG_ALPHA(r_lm,
+					blender(i)), bg_alpha);
+		}
+	}
+
+	val = mdp5_read(mdp5_kms, REG_MDP5_LM_BLEND_COLOR_OUT(lm));
+	mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_COLOR_OUT(lm),
+		   val | mixer_op_mode);
+	if (r_mixer) {
+		val = mdp5_read(mdp5_kms, REG_MDP5_LM_BLEND_COLOR_OUT(r_lm));
+		mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_COLOR_OUT(r_lm),
+			   val | mixer_op_mode);
+	}
+
+	mdp5_ctl_blend(ctl, pipeline, stage, r_stage, plane_cnt,
+		       ctl_blend_flags);
+out:
+	spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags);
+}
+
+static void mdp5_crtc_mode_set_nofb(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct mdp5_kms *mdp5_kms = get_kms(crtc);
+	struct mdp5_hw_mixer *mixer = mdp5_cstate->pipeline.mixer;
+	struct mdp5_hw_mixer *r_mixer = mdp5_cstate->pipeline.r_mixer;
+	uint32_t lm = mixer->lm;
+	u32 mixer_width, val;
+	unsigned long flags;
+	struct drm_display_mode *mode;
+
+	if (WARN_ON(!crtc->state))
+		return;
+
+	mode = &crtc->state->adjusted_mode;
+
+	DBG("%s: set mode: " DRM_MODE_FMT, crtc->name, DRM_MODE_ARG(mode));
+
+	mixer_width = mode->hdisplay;
+	if (r_mixer)
+		mixer_width /= 2;
+
+	spin_lock_irqsave(&mdp5_crtc->lm_lock, flags);
+	mdp5_write(mdp5_kms, REG_MDP5_LM_OUT_SIZE(lm),
+			MDP5_LM_OUT_SIZE_WIDTH(mixer_width) |
+			MDP5_LM_OUT_SIZE_HEIGHT(mode->vdisplay));
+
+	/* Assign mixer to LEFT side in source split mode */
+	val = mdp5_read(mdp5_kms, REG_MDP5_LM_BLEND_COLOR_OUT(lm));
+	val &= ~MDP5_LM_BLEND_COLOR_OUT_SPLIT_LEFT_RIGHT;
+	mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_COLOR_OUT(lm), val);
+
+	if (r_mixer) {
+		u32 r_lm = r_mixer->lm;
+
+		mdp5_write(mdp5_kms, REG_MDP5_LM_OUT_SIZE(r_lm),
+			   MDP5_LM_OUT_SIZE_WIDTH(mixer_width) |
+			   MDP5_LM_OUT_SIZE_HEIGHT(mode->vdisplay));
+
+		/* Assign mixer to RIGHT side in source split mode */
+		val = mdp5_read(mdp5_kms, REG_MDP5_LM_BLEND_COLOR_OUT(r_lm));
+		val |= MDP5_LM_BLEND_COLOR_OUT_SPLIT_LEFT_RIGHT;
+		mdp5_write(mdp5_kms, REG_MDP5_LM_BLEND_COLOR_OUT(r_lm), val);
+	}
+
+	spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags);
+}
+
+static struct drm_encoder *get_encoder_from_crtc(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_encoder *encoder;
+
+	drm_for_each_encoder(encoder, dev)
+		if (encoder->crtc == crtc)
+			return encoder;
+
+	return NULL;
+}
+
+static bool mdp5_crtc_get_scanout_position(struct drm_crtc *crtc,
+					   bool in_vblank_irq,
+					   int *vpos, int *hpos,
+					   ktime_t *stime, ktime_t *etime,
+					   const struct drm_display_mode *mode)
+{
+	unsigned int pipe = crtc->index;
+	struct drm_encoder *encoder;
+	int line, vsw, vbp, vactive_start, vactive_end, vfp_end;
+
+
+	encoder = get_encoder_from_crtc(crtc);
+	if (!encoder) {
+		DRM_ERROR("no encoder found for crtc %d\n", pipe);
+		return false;
+	}
+
+	vsw = mode->crtc_vsync_end - mode->crtc_vsync_start;
+	vbp = mode->crtc_vtotal - mode->crtc_vsync_end;
+
+	/*
+	 * the line counter is 1 at the start of the VSYNC pulse and VTOTAL at
+	 * the end of VFP. Translate the porch values relative to the line
+	 * counter positions.
+	 */
+
+	vactive_start = vsw + vbp + 1;
+
+	vactive_end = vactive_start + mode->crtc_vdisplay;
+
+	/* last scan line before VSYNC */
+	vfp_end = mode->crtc_vtotal;
+
+	if (stime)
+		*stime = ktime_get();
+
+	line = mdp5_encoder_get_linecount(encoder);
+
+	if (line < vactive_start)
+		line -= vactive_start;
+	else if (line > vactive_end)
+		line = line - vfp_end - vactive_start;
+	else
+		line -= vactive_start;
+
+	*vpos = line;
+	*hpos = 0;
+
+	if (etime)
+		*etime = ktime_get();
+
+	return true;
+}
+
+static u32 mdp5_crtc_get_vblank_counter(struct drm_crtc *crtc)
+{
+	struct drm_encoder *encoder;
+
+	encoder = get_encoder_from_crtc(crtc);
+	if (!encoder)
+		return 0;
+
+	return mdp5_encoder_get_framecount(encoder);
+}
+
+static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc,
+				     struct drm_atomic_state *state)
+{
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct mdp5_kms *mdp5_kms = get_kms(crtc);
+	struct device *dev = &mdp5_kms->pdev->dev;
+	unsigned long flags;
+
+	DBG("%s", crtc->name);
+
+	if (WARN_ON(!mdp5_crtc->enabled))
+		return;
+
+	/* Disable/save vblank irq handling before power is disabled */
+	drm_crtc_vblank_off(crtc);
+
+	if (mdp5_cstate->cmd_mode)
+		mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->pp_done);
+
+	mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->err);
+	pm_runtime_put_sync(dev);
+
+	if (crtc->state->event && !crtc->state->active) {
+		WARN_ON(mdp5_crtc->event);
+		spin_lock_irqsave(&mdp5_kms->dev->event_lock, flags);
+		drm_crtc_send_vblank_event(crtc, crtc->state->event);
+		crtc->state->event = NULL;
+		spin_unlock_irqrestore(&mdp5_kms->dev->event_lock, flags);
+	}
+
+	mdp5_crtc->enabled = false;
+}
+
+static void mdp5_crtc_vblank_on(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct mdp5_interface *intf = mdp5_cstate->pipeline.intf;
+	u32 count;
+
+	count = intf->mode == MDP5_INTF_DSI_MODE_COMMAND ? 0 : 0xffffffff;
+	drm_crtc_set_max_vblank_count(crtc, count);
+
+	drm_crtc_vblank_on(crtc);
+}
+
+static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc,
+				    struct drm_atomic_state *state)
+{
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct mdp5_kms *mdp5_kms = get_kms(crtc);
+	struct device *dev = &mdp5_kms->pdev->dev;
+
+	DBG("%s", crtc->name);
+
+	if (WARN_ON(mdp5_crtc->enabled))
+		return;
+
+	pm_runtime_get_sync(dev);
+
+	if (mdp5_crtc->lm_cursor_enabled) {
+		/*
+		 * Restore LM cursor state, as it might have been lost
+		 * with suspend:
+		 */
+		if (mdp5_crtc->cursor.iova) {
+			unsigned long flags;
+
+			spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags);
+			mdp5_crtc_restore_cursor(crtc);
+			spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags);
+
+			mdp5_ctl_set_cursor(mdp5_cstate->ctl,
+					    &mdp5_cstate->pipeline, 0, true);
+		} else {
+			mdp5_ctl_set_cursor(mdp5_cstate->ctl,
+					    &mdp5_cstate->pipeline, 0, false);
+		}
+	}
+
+	/* Restore vblank irq handling after power is enabled */
+	mdp5_crtc_vblank_on(crtc);
+
+	mdp5_crtc_mode_set_nofb(crtc);
+
+	mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err);
+
+	if (mdp5_cstate->cmd_mode)
+		mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->pp_done);
+
+	mdp5_crtc->enabled = true;
+}
+
+static int mdp5_crtc_setup_pipeline(struct drm_crtc *crtc,
+				    struct drm_crtc_state *new_crtc_state,
+				    bool need_right_mixer)
+{
+	struct mdp5_crtc_state *mdp5_cstate =
+			to_mdp5_crtc_state(new_crtc_state);
+	struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline;
+	struct mdp5_interface *intf;
+	bool new_mixer = false;
+
+	new_mixer = !pipeline->mixer;
+
+	if ((need_right_mixer && !pipeline->r_mixer) ||
+	    (!need_right_mixer && pipeline->r_mixer))
+		new_mixer = true;
+
+	if (new_mixer) {
+		struct mdp5_hw_mixer *old_mixer = pipeline->mixer;
+		struct mdp5_hw_mixer *old_r_mixer = pipeline->r_mixer;
+		u32 caps;
+		int ret;
+
+		caps = MDP_LM_CAP_DISPLAY;
+		if (need_right_mixer)
+			caps |= MDP_LM_CAP_PAIR;
+
+		ret = mdp5_mixer_assign(new_crtc_state->state, crtc, caps,
+					&pipeline->mixer, need_right_mixer ?
+					&pipeline->r_mixer : NULL);
+		if (ret)
+			return ret;
+
+		ret = mdp5_mixer_release(new_crtc_state->state, old_mixer);
+		if (ret)
+			return ret;
+
+		if (old_r_mixer) {
+			ret = mdp5_mixer_release(new_crtc_state->state, old_r_mixer);
+			if (ret)
+				return ret;
+
+			if (!need_right_mixer)
+				pipeline->r_mixer = NULL;
+		}
+	}
+
+	/*
+	 * these should have been already set up in the encoder's atomic
+	 * check (called by drm_atomic_helper_check_modeset)
+	 */
+	intf = pipeline->intf;
+
+	mdp5_cstate->err_irqmask = intf2err(intf->num);
+	mdp5_cstate->vblank_irqmask = intf2vblank(pipeline->mixer, intf);
+
+	if ((intf->type == INTF_DSI) &&
+	    (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)) {
+		mdp5_cstate->pp_done_irqmask = lm2ppdone(pipeline->mixer);
+		mdp5_cstate->cmd_mode = true;
+	} else {
+		mdp5_cstate->pp_done_irqmask = 0;
+		mdp5_cstate->cmd_mode = false;
+	}
+
+	return 0;
+}
+
+struct plane_state {
+	struct drm_plane *plane;
+	struct mdp5_plane_state *state;
+};
+
+static int pstate_cmp(const void *a, const void *b)
+{
+	struct plane_state *pa = (struct plane_state *)a;
+	struct plane_state *pb = (struct plane_state *)b;
+	return pa->state->base.normalized_zpos - pb->state->base.normalized_zpos;
+}
+
+/* is there a helper for this? */
+static bool is_fullscreen(struct drm_crtc_state *cstate,
+		struct drm_plane_state *pstate)
+{
+	return (pstate->crtc_x <= 0) && (pstate->crtc_y <= 0) &&
+		((pstate->crtc_x + pstate->crtc_w) >= cstate->mode.hdisplay) &&
+		((pstate->crtc_y + pstate->crtc_h) >= cstate->mode.vdisplay);
+}
+
+static enum mdp_mixer_stage_id get_start_stage(struct drm_crtc *crtc,
+					struct drm_crtc_state *new_crtc_state,
+					struct drm_plane_state *bpstate)
+{
+	struct mdp5_crtc_state *mdp5_cstate =
+			to_mdp5_crtc_state(new_crtc_state);
+
+	/*
+	 * if we're in source split mode, it's mandatory to have
+	 * border out on the base stage
+	 */
+	if (mdp5_cstate->pipeline.r_mixer)
+		return STAGE0;
+
+	/* if the bottom-most layer is not fullscreen, we need to use
+	 * it for solid-color:
+	 */
+	if (!is_fullscreen(new_crtc_state, bpstate))
+		return STAGE0;
+
+	return STAGE_BASE;
+}
+
+static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
+		struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state,
+									  crtc);
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc_state);
+	struct mdp5_interface *intf = mdp5_cstate->pipeline.intf;
+	struct mdp5_kms *mdp5_kms = get_kms(crtc);
+	struct drm_plane *plane;
+	struct drm_device *dev = crtc->dev;
+	struct plane_state pstates[STAGE_MAX + 1];
+	const struct mdp5_cfg_hw *hw_cfg;
+	const struct drm_plane_state *pstate;
+	const struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+	bool cursor_plane = false;
+	bool need_right_mixer = false;
+	int cnt = 0, i;
+	int ret;
+	enum mdp_mixer_stage_id start;
+
+	DBG("%s: check", crtc->name);
+
+	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
+		struct mdp5_plane_state *mdp5_pstate =
+				to_mdp5_plane_state(pstate);
+
+		if (!pstate->visible)
+			continue;
+
+		pstates[cnt].plane = plane;
+		pstates[cnt].state = to_mdp5_plane_state(pstate);
+
+		mdp5_pstate->needs_dirtyfb =
+			intf->mode == MDP5_INTF_DSI_MODE_COMMAND;
+
+		/*
+		 * if any plane on this crtc uses 2 hwpipes, then we need
+		 * the crtc to have a right hwmixer.
+		 */
+		if (pstates[cnt].state->r_hwpipe)
+			need_right_mixer = true;
+		cnt++;
+
+		if (plane->type == DRM_PLANE_TYPE_CURSOR)
+			cursor_plane = true;
+	}
+
+	/* bail out early if there aren't any planes */
+	if (!cnt)
+		return 0;
+
+	hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
+
+	/*
+	 * we need a right hwmixer if the mode's width is greater than a single
+	 * LM's max width
+	 */
+	if (mode->hdisplay > hw_cfg->lm.max_width)
+		need_right_mixer = true;
+
+	ret = mdp5_crtc_setup_pipeline(crtc, crtc_state, need_right_mixer);
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev, "couldn't assign mixers %d\n", ret);
+		return ret;
+	}
+
+	/* assign a stage based on sorted zpos property */
+	sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL);
+
+	/* trigger a warning if cursor isn't the highest zorder */
+	WARN_ON(cursor_plane &&
+		(pstates[cnt - 1].plane->type != DRM_PLANE_TYPE_CURSOR));
+
+	start = get_start_stage(crtc, crtc_state, &pstates[0].state->base);
+
+	/* verify that there are not too many planes attached to crtc
+	 * and that we don't have conflicting mixer stages:
+	 */
+	if ((cnt + start - 1) >= hw_cfg->lm.nb_stages) {
+		DRM_DEV_ERROR(dev->dev, "too many planes! cnt=%d, start stage=%d\n",
+			cnt, start);
+		return -EINVAL;
+	}
+
+	for (i = 0; i < cnt; i++) {
+		if (cursor_plane && (i == (cnt - 1)))
+			pstates[i].state->stage = hw_cfg->lm.nb_stages;
+		else
+			pstates[i].state->stage = start + i;
+		DBG("%s: assign pipe %s on stage=%d", crtc->name,
+				pstates[i].plane->name,
+				pstates[i].state->stage);
+	}
+
+	return 0;
+}
+
+static void mdp5_crtc_atomic_begin(struct drm_crtc *crtc,
+				   struct drm_atomic_state *state)
+{
+	DBG("%s: begin", crtc->name);
+}
+
+static void mdp5_crtc_atomic_flush(struct drm_crtc *crtc,
+				   struct drm_atomic_state *state)
+{
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct drm_device *dev = crtc->dev;
+	unsigned long flags;
+
+	DBG("%s: event: %p", crtc->name, crtc->state->event);
+
+	WARN_ON(mdp5_crtc->event);
+
+	spin_lock_irqsave(&dev->event_lock, flags);
+	mdp5_crtc->event = crtc->state->event;
+	crtc->state->event = NULL;
+	spin_unlock_irqrestore(&dev->event_lock, flags);
+
+	/*
+	 * If no CTL has been allocated in mdp5_crtc_atomic_check(),
+	 * it means we are trying to flush a CRTC whose state is disabled:
+	 * nothing else needs to be done.
+	 */
+	/* XXX: Can this happen now ? */
+	if (unlikely(!mdp5_cstate->ctl))
+		return;
+
+	blend_setup(crtc);
+
+	/* PP_DONE irq is only used by command mode for now.
+	 * It is better to request pending before FLUSH and START trigger
+	 * to make sure no pp_done irq missed.
+	 * This is safe because no pp_done will happen before SW trigger
+	 * in command mode.
+	 */
+	if (mdp5_cstate->cmd_mode)
+		request_pp_done_pending(crtc);
+
+	mdp5_crtc->flushed_mask = crtc_flush_all(crtc);
+
+	/* XXX are we leaking out state here? */
+	mdp5_crtc->vblank.irqmask = mdp5_cstate->vblank_irqmask;
+	mdp5_crtc->err.irqmask = mdp5_cstate->err_irqmask;
+	mdp5_crtc->pp_done.irqmask = mdp5_cstate->pp_done_irqmask;
+
+	request_pending(crtc, PENDING_FLIP);
+}
+
+static void get_roi(struct drm_crtc *crtc, uint32_t *roi_w, uint32_t *roi_h)
+{
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	uint32_t xres = crtc->mode.hdisplay;
+	uint32_t yres = crtc->mode.vdisplay;
+
+	/*
+	 * Cursor Region Of Interest (ROI) is a plane read from cursor
+	 * buffer to render. The ROI region is determined by the visibility of
+	 * the cursor point. In the default Cursor image the cursor point will
+	 * be at the top left of the cursor image.
+	 *
+	 * Without rotation:
+	 * If the cursor point reaches the right (xres - x < cursor.width) or
+	 * bottom (yres - y < cursor.height) boundary of the screen, then ROI
+	 * width and ROI height need to be evaluated to crop the cursor image
+	 * accordingly.
+	 * (xres-x) will be new cursor width when x > (xres - cursor.width)
+	 * (yres-y) will be new cursor height when y > (yres - cursor.height)
+	 *
+	 * With rotation:
+	 * We get negative x and/or y coordinates.
+	 * (cursor.width - abs(x)) will be new cursor width when x < 0
+	 * (cursor.height - abs(y)) will be new cursor width when y < 0
+	 */
+	if (mdp5_crtc->cursor.x >= 0)
+		*roi_w = min(mdp5_crtc->cursor.width, xres -
+			mdp5_crtc->cursor.x);
+	else
+		*roi_w = mdp5_crtc->cursor.width - abs(mdp5_crtc->cursor.x);
+	if (mdp5_crtc->cursor.y >= 0)
+		*roi_h = min(mdp5_crtc->cursor.height, yres -
+			mdp5_crtc->cursor.y);
+	else
+		*roi_h = mdp5_crtc->cursor.height - abs(mdp5_crtc->cursor.y);
+}
+
+static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc)
+{
+	const struct drm_format_info *info = drm_format_info(DRM_FORMAT_ARGB8888);
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	struct mdp5_kms *mdp5_kms = get_kms(crtc);
+	const enum mdp5_cursor_alpha cur_alpha = CURSOR_ALPHA_PER_PIXEL;
+	uint32_t blendcfg, stride;
+	uint32_t x, y, src_x, src_y, width, height;
+	uint32_t roi_w, roi_h;
+	int lm;
+
+	assert_spin_locked(&mdp5_crtc->cursor.lock);
+
+	lm = mdp5_cstate->pipeline.mixer->lm;
+
+	x = mdp5_crtc->cursor.x;
+	y = mdp5_crtc->cursor.y;
+	width = mdp5_crtc->cursor.width;
+	height = mdp5_crtc->cursor.height;
+
+	stride = width * info->cpp[0];
+
+	get_roi(crtc, &roi_w, &roi_h);
+
+	/* If cusror buffer overlaps due to rotation on the
+	 * upper or left screen border the pixel offset inside
+	 * the cursor buffer of the ROI is the positive overlap
+	 * distance.
+	 */
+	if (mdp5_crtc->cursor.x < 0) {
+		src_x = abs(mdp5_crtc->cursor.x);
+		x = 0;
+	} else {
+		src_x = 0;
+	}
+	if (mdp5_crtc->cursor.y < 0) {
+		src_y = abs(mdp5_crtc->cursor.y);
+		y = 0;
+	} else {
+		src_y = 0;
+	}
+	DBG("%s: x=%d, y=%d roi_w=%d roi_h=%d src_x=%d src_y=%d",
+		crtc->name, x, y, roi_w, roi_h, src_x, src_y);
+
+	mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride);
+	mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm),
+			MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888));
+	mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_IMG_SIZE(lm),
+			MDP5_LM_CURSOR_IMG_SIZE_SRC_H(height) |
+			MDP5_LM_CURSOR_IMG_SIZE_SRC_W(width));
+	mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm),
+			MDP5_LM_CURSOR_SIZE_ROI_H(roi_h) |
+			MDP5_LM_CURSOR_SIZE_ROI_W(roi_w));
+	mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_START_XY(lm),
+			MDP5_LM_CURSOR_START_XY_Y_START(y) |
+			MDP5_LM_CURSOR_START_XY_X_START(x));
+	mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_XY(lm),
+			MDP5_LM_CURSOR_XY_SRC_Y(src_y) |
+			MDP5_LM_CURSOR_XY_SRC_X(src_x));
+	mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BASE_ADDR(lm),
+			mdp5_crtc->cursor.iova);
+
+	blendcfg = MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_EN;
+	blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL(cur_alpha);
+	mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BLEND_CONFIG(lm), blendcfg);
+}
+
+static int mdp5_crtc_cursor_set(struct drm_crtc *crtc,
+		struct drm_file *file, uint32_t handle,
+		uint32_t width, uint32_t height)
+{
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline;
+	struct drm_device *dev = crtc->dev;
+	struct mdp5_kms *mdp5_kms = get_kms(crtc);
+	struct platform_device *pdev = mdp5_kms->pdev;
+	struct msm_kms *kms = &mdp5_kms->base.base;
+	struct drm_gem_object *cursor_bo, *old_bo = NULL;
+	struct mdp5_ctl *ctl;
+	int ret;
+	uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0);
+	bool cursor_enable = true;
+	unsigned long flags;
+
+	if (!mdp5_crtc->lm_cursor_enabled) {
+		dev_warn(dev->dev,
+			 "cursor_set is deprecated with cursor planes\n");
+		return -EINVAL;
+	}
+
+	if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
+		DRM_DEV_ERROR(dev->dev, "bad cursor size: %dx%d\n", width, height);
+		return -EINVAL;
+	}
+
+	ctl = mdp5_cstate->ctl;
+	if (!ctl)
+		return -EINVAL;
+
+	/* don't support LM cursors when we have source split enabled */
+	if (mdp5_cstate->pipeline.r_mixer)
+		return -EINVAL;
+
+	if (!handle) {
+		DBG("Cursor off");
+		cursor_enable = false;
+		mdp5_crtc->cursor.iova = 0;
+		pm_runtime_get_sync(&pdev->dev);
+		goto set_cursor;
+	}
+
+	cursor_bo = drm_gem_object_lookup(file, handle);
+	if (!cursor_bo)
+		return -ENOENT;
+
+	ret = msm_gem_get_and_pin_iova(cursor_bo, kms->aspace,
+			&mdp5_crtc->cursor.iova);
+	if (ret) {
+		drm_gem_object_put(cursor_bo);
+		return -EINVAL;
+	}
+
+	pm_runtime_get_sync(&pdev->dev);
+
+	spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags);
+	old_bo = mdp5_crtc->cursor.scanout_bo;
+
+	mdp5_crtc->cursor.scanout_bo = cursor_bo;
+	mdp5_crtc->cursor.width = width;
+	mdp5_crtc->cursor.height = height;
+
+	mdp5_crtc_restore_cursor(crtc);
+
+	spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags);
+
+set_cursor:
+	ret = mdp5_ctl_set_cursor(ctl, pipeline, 0, cursor_enable);
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev, "failed to %sable cursor: %d\n",
+				cursor_enable ? "en" : "dis", ret);
+		goto end;
+	}
+
+	crtc_flush(crtc, flush_mask);
+
+end:
+	pm_runtime_put_sync(&pdev->dev);
+	if (old_bo) {
+		drm_flip_work_queue(&mdp5_crtc->unref_cursor_work, old_bo);
+		/* enable vblank to complete cursor work: */
+		request_pending(crtc, PENDING_CURSOR);
+	}
+	return ret;
+}
+
+static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+	struct mdp5_kms *mdp5_kms = get_kms(crtc);
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0);
+	struct drm_device *dev = crtc->dev;
+	uint32_t roi_w;
+	uint32_t roi_h;
+	unsigned long flags;
+
+	if (!mdp5_crtc->lm_cursor_enabled) {
+		dev_warn(dev->dev,
+			 "cursor_move is deprecated with cursor planes\n");
+		return -EINVAL;
+	}
+
+	/* don't support LM cursors when we have source split enabled */
+	if (mdp5_cstate->pipeline.r_mixer)
+		return -EINVAL;
+
+	/* In case the CRTC is disabled, just drop the cursor update */
+	if (unlikely(!crtc->state->enable))
+		return 0;
+
+	/* accept negative x/y coordinates up to maximum cursor overlap */
+	mdp5_crtc->cursor.x = x = max(x, -(int)mdp5_crtc->cursor.width);
+	mdp5_crtc->cursor.y = y = max(y, -(int)mdp5_crtc->cursor.height);
+
+	get_roi(crtc, &roi_w, &roi_h);
+
+	pm_runtime_get_sync(&mdp5_kms->pdev->dev);
+
+	spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags);
+	mdp5_crtc_restore_cursor(crtc);
+	spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags);
+
+	crtc_flush(crtc, flush_mask);
+
+	pm_runtime_put_sync(&mdp5_kms->pdev->dev);
+
+	return 0;
+}
+
+static void
+mdp5_crtc_atomic_print_state(struct drm_printer *p,
+			     const struct drm_crtc_state *state)
+{
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(state);
+	struct mdp5_pipeline *pipeline = &mdp5_cstate->pipeline;
+	struct mdp5_kms *mdp5_kms = get_kms(state->crtc);
+
+	if (WARN_ON(!pipeline))
+		return;
+
+	if (mdp5_cstate->ctl)
+		drm_printf(p, "\tctl=%d\n", mdp5_ctl_get_ctl_id(mdp5_cstate->ctl));
+
+	drm_printf(p, "\thwmixer=%s\n", pipeline->mixer ?
+			pipeline->mixer->name : "(null)");
+
+	if (mdp5_kms->caps & MDP_CAP_SRC_SPLIT)
+		drm_printf(p, "\tright hwmixer=%s\n", pipeline->r_mixer ?
+			   pipeline->r_mixer->name : "(null)");
+
+	drm_printf(p, "\tcmd_mode=%d\n", mdp5_cstate->cmd_mode);
+}
+
+static struct drm_crtc_state *
+mdp5_crtc_duplicate_state(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc_state *mdp5_cstate;
+
+	if (WARN_ON(!crtc->state))
+		return NULL;
+
+	mdp5_cstate = kmemdup(to_mdp5_crtc_state(crtc->state),
+			      sizeof(*mdp5_cstate), GFP_KERNEL);
+	if (!mdp5_cstate)
+		return NULL;
+
+	__drm_atomic_helper_crtc_duplicate_state(crtc, &mdp5_cstate->base);
+
+	return &mdp5_cstate->base;
+}
+
+static void mdp5_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *state)
+{
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(state);
+
+	__drm_atomic_helper_crtc_destroy_state(state);
+
+	kfree(mdp5_cstate);
+}
+
+static void mdp5_crtc_reset(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc_state *mdp5_cstate =
+		kzalloc(sizeof(*mdp5_cstate), GFP_KERNEL);
+
+	if (crtc->state)
+		mdp5_crtc_destroy_state(crtc, crtc->state);
+
+	if (mdp5_cstate)
+		__drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base);
+	else
+		__drm_atomic_helper_crtc_reset(crtc, NULL);
+}
+
+static const struct drm_crtc_funcs mdp5_crtc_no_lm_cursor_funcs = {
+	.set_config = drm_atomic_helper_set_config,
+	.page_flip = drm_atomic_helper_page_flip,
+	.reset = mdp5_crtc_reset,
+	.atomic_duplicate_state = mdp5_crtc_duplicate_state,
+	.atomic_destroy_state = mdp5_crtc_destroy_state,
+	.atomic_print_state = mdp5_crtc_atomic_print_state,
+	.get_vblank_counter = mdp5_crtc_get_vblank_counter,
+	.enable_vblank  = msm_crtc_enable_vblank,
+	.disable_vblank = msm_crtc_disable_vblank,
+	.get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
+};
+
+static const struct drm_crtc_funcs mdp5_crtc_funcs = {
+	.set_config = drm_atomic_helper_set_config,
+	.page_flip = drm_atomic_helper_page_flip,
+	.reset = mdp5_crtc_reset,
+	.atomic_duplicate_state = mdp5_crtc_duplicate_state,
+	.atomic_destroy_state = mdp5_crtc_destroy_state,
+	.cursor_set = mdp5_crtc_cursor_set,
+	.cursor_move = mdp5_crtc_cursor_move,
+	.atomic_print_state = mdp5_crtc_atomic_print_state,
+	.get_vblank_counter = mdp5_crtc_get_vblank_counter,
+	.enable_vblank  = msm_crtc_enable_vblank,
+	.disable_vblank = msm_crtc_disable_vblank,
+	.get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp,
+};
+
+static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = {
+	.mode_set_nofb = mdp5_crtc_mode_set_nofb,
+	.atomic_check = mdp5_crtc_atomic_check,
+	.atomic_begin = mdp5_crtc_atomic_begin,
+	.atomic_flush = mdp5_crtc_atomic_flush,
+	.atomic_enable = mdp5_crtc_atomic_enable,
+	.atomic_disable = mdp5_crtc_atomic_disable,
+	.get_scanout_position = mdp5_crtc_get_scanout_position,
+};
+
+static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus)
+{
+	struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc, vblank);
+	struct drm_crtc *crtc = &mdp5_crtc->base;
+	struct msm_drm_private *priv = crtc->dev->dev_private;
+	unsigned pending;
+
+	mdp_irq_unregister(&get_kms(crtc)->base, &mdp5_crtc->vblank);
+
+	pending = atomic_xchg(&mdp5_crtc->pending, 0);
+
+	if (pending & PENDING_FLIP) {
+		complete_flip(crtc, NULL);
+	}
+
+	if (pending & PENDING_CURSOR)
+		drm_flip_work_commit(&mdp5_crtc->unref_cursor_work, priv->wq);
+}
+
+static void mdp5_crtc_err_irq(struct mdp_irq *irq, uint32_t irqstatus)
+{
+	struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc, err);
+
+	DBG("%s: error: %08x", mdp5_crtc->base.name, irqstatus);
+}
+
+static void mdp5_crtc_pp_done_irq(struct mdp_irq *irq, uint32_t irqstatus)
+{
+	struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc,
+								pp_done);
+
+	complete_all(&mdp5_crtc->pp_completion);
+}
+
+static void mdp5_crtc_wait_for_pp_done(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	int ret;
+
+	ret = wait_for_completion_timeout(&mdp5_crtc->pp_completion,
+						msecs_to_jiffies(50));
+	if (ret == 0)
+		dev_warn_ratelimited(dev->dev, "pp done time out, lm=%d\n",
+				     mdp5_cstate->pipeline.mixer->lm);
+}
+
+static void mdp5_crtc_wait_for_flush_done(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct mdp5_ctl *ctl = mdp5_cstate->ctl;
+	int ret;
+
+	/* Should not call this function if crtc is disabled. */
+	if (!ctl)
+		return;
+
+	ret = drm_crtc_vblank_get(crtc);
+	if (ret)
+		return;
+
+	ret = wait_event_timeout(dev->vblank[drm_crtc_index(crtc)].queue,
+		((mdp5_ctl_get_commit_status(ctl) &
+		mdp5_crtc->flushed_mask) == 0),
+		msecs_to_jiffies(50));
+	if (ret <= 0)
+		dev_warn(dev->dev, "vblank time out, crtc=%d\n", mdp5_crtc->id);
+
+	mdp5_crtc->flushed_mask = 0;
+
+	drm_crtc_vblank_put(crtc);
+}
+
+uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
+	return mdp5_crtc->vblank.irqmask;
+}
+
+void mdp5_crtc_set_pipeline(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+	struct mdp5_kms *mdp5_kms = get_kms(crtc);
+
+	/* should this be done elsewhere ? */
+	mdp_irq_update(&mdp5_kms->base);
+
+	mdp5_ctl_set_pipeline(mdp5_cstate->ctl, &mdp5_cstate->pipeline);
+}
+
+struct mdp5_ctl *mdp5_crtc_get_ctl(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+
+	return mdp5_cstate->ctl;
+}
+
+struct mdp5_hw_mixer *mdp5_crtc_get_mixer(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc_state *mdp5_cstate;
+
+	if (WARN_ON(!crtc))
+		return ERR_PTR(-EINVAL);
+
+	mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+
+	return WARN_ON(!mdp5_cstate->pipeline.mixer) ?
+		ERR_PTR(-EINVAL) : mdp5_cstate->pipeline.mixer;
+}
+
+struct mdp5_pipeline *mdp5_crtc_get_pipeline(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc_state *mdp5_cstate;
+
+	if (WARN_ON(!crtc))
+		return ERR_PTR(-EINVAL);
+
+	mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+
+	return &mdp5_cstate->pipeline;
+}
+
+void mdp5_crtc_wait_for_commit_done(struct drm_crtc *crtc)
+{
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
+
+	if (mdp5_cstate->cmd_mode)
+		mdp5_crtc_wait_for_pp_done(crtc);
+	else
+		mdp5_crtc_wait_for_flush_done(crtc);
+}
+
+/* initialize crtc */
+struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
+				struct drm_plane *plane,
+				struct drm_plane *cursor_plane, int id)
+{
+	struct drm_crtc *crtc = NULL;
+	struct mdp5_crtc *mdp5_crtc;
+	int ret;
+
+	mdp5_crtc = drmm_crtc_alloc_with_planes(dev, struct mdp5_crtc, base,
+						plane, cursor_plane,
+						cursor_plane ?
+						&mdp5_crtc_no_lm_cursor_funcs :
+						&mdp5_crtc_funcs,
+						NULL);
+	if (IS_ERR(mdp5_crtc))
+		return ERR_CAST(mdp5_crtc);
+
+	crtc = &mdp5_crtc->base;
+
+	mdp5_crtc->id = id;
+
+	spin_lock_init(&mdp5_crtc->lm_lock);
+	spin_lock_init(&mdp5_crtc->cursor.lock);
+	init_completion(&mdp5_crtc->pp_completion);
+
+	mdp5_crtc->vblank.irq = mdp5_crtc_vblank_irq;
+	mdp5_crtc->err.irq = mdp5_crtc_err_irq;
+	mdp5_crtc->pp_done.irq = mdp5_crtc_pp_done_irq;
+
+	mdp5_crtc->lm_cursor_enabled = cursor_plane ? false : true;
+
+	drm_flip_work_init(&mdp5_crtc->unref_cursor_work,
+			"unref cursor", unref_cursor_worker);
+	ret = drmm_add_action_or_reset(dev, mdp5_crtc_flip_cleanup, mdp5_crtc);
+	if (ret)
+		return ERR_PTR(ret);
+
+	drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs);
+
+	return crtc;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_ctl.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_ctl.c
@@ -0,0 +1,751 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
+ */
+
+#include "mdp5_kms.h"
+#include "mdp5_ctl.h"
+
+/*
+ * CTL - MDP Control Pool Manager
+ *
+ * Controls are shared between all display interfaces.
+ *
+ * They are intended to be used for data path configuration.
+ * The top level register programming describes the complete data path for
+ * a specific data path ID - REG_MDP5_CTL_*(<id>, ...)
+ *
+ * Hardware capabilities determine the number of concurrent data paths
+ *
+ * In certain use cases (high-resolution dual pipe), one single CTL can be
+ * shared across multiple CRTCs.
+ */
+
+#define CTL_STAT_BUSY		0x1
+#define CTL_STAT_BOOKED	0x2
+
+struct mdp5_ctl {
+	struct mdp5_ctl_manager *ctlm;
+
+	u32 id;
+
+	/* CTL status bitmask */
+	u32 status;
+
+	bool encoder_enabled;
+
+	/* pending flush_mask bits */
+	u32 flush_mask;
+
+	/* REG_MDP5_CTL_*(<id>) registers access info + lock: */
+	spinlock_t hw_lock;
+	u32 reg_offset;
+
+	/* when do CTL registers need to be flushed? (mask of trigger bits) */
+	u32 pending_ctl_trigger;
+
+	bool cursor_on;
+
+	/* True if the current CTL has FLUSH bits pending for single FLUSH. */
+	bool flush_pending;
+
+	struct mdp5_ctl *pair; /* Paired CTL to be flushed together */
+};
+
+struct mdp5_ctl_manager {
+	struct drm_device *dev;
+
+	/* number of CTL / Layer Mixers in this hw config: */
+	u32 nlm;
+	u32 nctl;
+
+	/* to filter out non-present bits in the current hardware config */
+	u32 flush_hw_mask;
+
+	/* status for single FLUSH */
+	bool single_flush_supported;
+	u32 single_flush_pending_mask;
+
+	/* pool of CTLs + lock to protect resource allocation (ctls[i].busy) */
+	spinlock_t pool_lock;
+	struct mdp5_ctl ctls[MAX_CTL];
+};
+
+static inline
+struct mdp5_kms *get_kms(struct mdp5_ctl_manager *ctl_mgr)
+{
+	struct msm_drm_private *priv = ctl_mgr->dev->dev_private;
+
+	return to_mdp5_kms(to_mdp_kms(priv->kms));
+}
+
+static inline
+void ctl_write(struct mdp5_ctl *ctl, u32 reg, u32 data)
+{
+	struct mdp5_kms *mdp5_kms = get_kms(ctl->ctlm);
+
+	(void)ctl->reg_offset; /* TODO use this instead of mdp5_write */
+	mdp5_write(mdp5_kms, reg, data);
+}
+
+static inline
+u32 ctl_read(struct mdp5_ctl *ctl, u32 reg)
+{
+	struct mdp5_kms *mdp5_kms = get_kms(ctl->ctlm);
+
+	(void)ctl->reg_offset; /* TODO use this instead of mdp5_write */
+	return mdp5_read(mdp5_kms, reg);
+}
+
+static void set_display_intf(struct mdp5_kms *mdp5_kms,
+		struct mdp5_interface *intf)
+{
+	unsigned long flags;
+	u32 intf_sel;
+
+	spin_lock_irqsave(&mdp5_kms->resource_lock, flags);
+	intf_sel = mdp5_read(mdp5_kms, REG_MDP5_DISP_INTF_SEL);
+
+	switch (intf->num) {
+	case 0:
+		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF0__MASK;
+		intf_sel |= MDP5_DISP_INTF_SEL_INTF0(intf->type);
+		break;
+	case 1:
+		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF1__MASK;
+		intf_sel |= MDP5_DISP_INTF_SEL_INTF1(intf->type);
+		break;
+	case 2:
+		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF2__MASK;
+		intf_sel |= MDP5_DISP_INTF_SEL_INTF2(intf->type);
+		break;
+	case 3:
+		intf_sel &= ~MDP5_DISP_INTF_SEL_INTF3__MASK;
+		intf_sel |= MDP5_DISP_INTF_SEL_INTF3(intf->type);
+		break;
+	default:
+		BUG();
+		break;
+	}
+
+	mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, intf_sel);
+	spin_unlock_irqrestore(&mdp5_kms->resource_lock, flags);
+}
+
+static void set_ctl_op(struct mdp5_ctl *ctl, struct mdp5_pipeline *pipeline)
+{
+	unsigned long flags;
+	struct mdp5_interface *intf = pipeline->intf;
+	u32 ctl_op = 0;
+
+	if (!mdp5_cfg_intf_is_virtual(intf->type))
+		ctl_op |= MDP5_CTL_OP_INTF_NUM(INTF0 + intf->num);
+
+	switch (intf->type) {
+	case INTF_DSI:
+		if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
+			ctl_op |= MDP5_CTL_OP_CMD_MODE;
+		break;
+
+	case INTF_WB:
+		if (intf->mode == MDP5_INTF_WB_MODE_LINE)
+			ctl_op |= MDP5_CTL_OP_MODE(MODE_WB_2_LINE);
+		break;
+
+	default:
+		break;
+	}
+
+	if (pipeline->r_mixer)
+		ctl_op |= MDP5_CTL_OP_PACK_3D_ENABLE |
+			  MDP5_CTL_OP_PACK_3D(1);
+
+	spin_lock_irqsave(&ctl->hw_lock, flags);
+	ctl_write(ctl, REG_MDP5_CTL_OP(ctl->id), ctl_op);
+	spin_unlock_irqrestore(&ctl->hw_lock, flags);
+}
+
+int mdp5_ctl_set_pipeline(struct mdp5_ctl *ctl, struct mdp5_pipeline *pipeline)
+{
+	struct mdp5_kms *mdp5_kms = get_kms(ctl->ctlm);
+	struct mdp5_interface *intf = pipeline->intf;
+
+	/* Virtual interfaces need not set a display intf (e.g.: Writeback) */
+	if (!mdp5_cfg_intf_is_virtual(intf->type))
+		set_display_intf(mdp5_kms, intf);
+
+	set_ctl_op(ctl, pipeline);
+
+	return 0;
+}
+
+static bool start_signal_needed(struct mdp5_ctl *ctl,
+				struct mdp5_pipeline *pipeline)
+{
+	struct mdp5_interface *intf = pipeline->intf;
+
+	if (!ctl->encoder_enabled)
+		return false;
+
+	switch (intf->type) {
+	case INTF_WB:
+		return true;
+	case INTF_DSI:
+		return intf->mode == MDP5_INTF_DSI_MODE_COMMAND;
+	default:
+		return false;
+	}
+}
+
+/*
+ * send_start_signal() - Overlay Processor Start Signal
+ *
+ * For a given control operation (display pipeline), a START signal needs to be
+ * executed in order to kick off operation and activate all layers.
+ * e.g.: DSI command mode, Writeback
+ */
+static void send_start_signal(struct mdp5_ctl *ctl)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ctl->hw_lock, flags);
+	ctl_write(ctl, REG_MDP5_CTL_START(ctl->id), 1);
+	spin_unlock_irqrestore(&ctl->hw_lock, flags);
+}
+
+/**
+ * mdp5_ctl_set_encoder_state() - set the encoder state
+ *
+ * @ctl:      the CTL instance
+ * @pipeline: the encoder's INTF + MIXER configuration
+ * @enabled:  true, when encoder is ready for data streaming; false, otherwise.
+ *
+ * Note:
+ * This encoder state is needed to trigger START signal (data path kickoff).
+ */
+int mdp5_ctl_set_encoder_state(struct mdp5_ctl *ctl,
+			       struct mdp5_pipeline *pipeline,
+			       bool enabled)
+{
+	struct mdp5_interface *intf = pipeline->intf;
+
+	if (WARN_ON(!ctl))
+		return -EINVAL;
+
+	ctl->encoder_enabled = enabled;
+	DBG("intf_%d: %s", intf->num, enabled ? "on" : "off");
+
+	if (start_signal_needed(ctl, pipeline)) {
+		send_start_signal(ctl);
+	}
+
+	return 0;
+}
+
+/*
+ * Note:
+ * CTL registers need to be flushed after calling this function
+ * (call mdp5_ctl_commit() with mdp_ctl_flush_mask_ctl() mask)
+ */
+int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, struct mdp5_pipeline *pipeline,
+			int cursor_id, bool enable)
+{
+	struct mdp5_ctl_manager *ctl_mgr = ctl->ctlm;
+	unsigned long flags;
+	u32 blend_cfg;
+	struct mdp5_hw_mixer *mixer = pipeline->mixer;
+
+	if (WARN_ON(!mixer)) {
+		DRM_DEV_ERROR(ctl_mgr->dev->dev, "CTL %d cannot find LM",
+			ctl->id);
+		return -EINVAL;
+	}
+
+	if (pipeline->r_mixer) {
+		DRM_DEV_ERROR(ctl_mgr->dev->dev, "unsupported configuration");
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&ctl->hw_lock, flags);
+
+	blend_cfg = ctl_read(ctl, REG_MDP5_CTL_LAYER_REG(ctl->id, mixer->lm));
+
+	if (enable)
+		blend_cfg |=  MDP5_CTL_LAYER_REG_CURSOR_OUT;
+	else
+		blend_cfg &= ~MDP5_CTL_LAYER_REG_CURSOR_OUT;
+
+	ctl_write(ctl, REG_MDP5_CTL_LAYER_REG(ctl->id, mixer->lm), blend_cfg);
+	ctl->cursor_on = enable;
+
+	spin_unlock_irqrestore(&ctl->hw_lock, flags);
+
+	ctl->pending_ctl_trigger = mdp_ctl_flush_mask_cursor(cursor_id);
+
+	return 0;
+}
+
+static u32 mdp_ctl_blend_mask(enum mdp5_pipe pipe,
+		enum mdp_mixer_stage_id stage)
+{
+	switch (pipe) {
+	case SSPP_VIG0: return MDP5_CTL_LAYER_REG_VIG0(stage);
+	case SSPP_VIG1: return MDP5_CTL_LAYER_REG_VIG1(stage);
+	case SSPP_VIG2: return MDP5_CTL_LAYER_REG_VIG2(stage);
+	case SSPP_RGB0: return MDP5_CTL_LAYER_REG_RGB0(stage);
+	case SSPP_RGB1: return MDP5_CTL_LAYER_REG_RGB1(stage);
+	case SSPP_RGB2: return MDP5_CTL_LAYER_REG_RGB2(stage);
+	case SSPP_DMA0: return MDP5_CTL_LAYER_REG_DMA0(stage);
+	case SSPP_DMA1: return MDP5_CTL_LAYER_REG_DMA1(stage);
+	case SSPP_VIG3: return MDP5_CTL_LAYER_REG_VIG3(stage);
+	case SSPP_RGB3: return MDP5_CTL_LAYER_REG_RGB3(stage);
+	case SSPP_CURSOR0:
+	case SSPP_CURSOR1:
+	default:	return 0;
+	}
+}
+
+static u32 mdp_ctl_blend_ext_mask(enum mdp5_pipe pipe,
+		enum mdp_mixer_stage_id stage)
+{
+	if (stage < STAGE6 && (pipe != SSPP_CURSOR0 && pipe != SSPP_CURSOR1))
+		return 0;
+
+	switch (pipe) {
+	case SSPP_VIG0: return MDP5_CTL_LAYER_EXT_REG_VIG0_BIT3;
+	case SSPP_VIG1: return MDP5_CTL_LAYER_EXT_REG_VIG1_BIT3;
+	case SSPP_VIG2: return MDP5_CTL_LAYER_EXT_REG_VIG2_BIT3;
+	case SSPP_RGB0: return MDP5_CTL_LAYER_EXT_REG_RGB0_BIT3;
+	case SSPP_RGB1: return MDP5_CTL_LAYER_EXT_REG_RGB1_BIT3;
+	case SSPP_RGB2: return MDP5_CTL_LAYER_EXT_REG_RGB2_BIT3;
+	case SSPP_DMA0: return MDP5_CTL_LAYER_EXT_REG_DMA0_BIT3;
+	case SSPP_DMA1: return MDP5_CTL_LAYER_EXT_REG_DMA1_BIT3;
+	case SSPP_VIG3: return MDP5_CTL_LAYER_EXT_REG_VIG3_BIT3;
+	case SSPP_RGB3: return MDP5_CTL_LAYER_EXT_REG_RGB3_BIT3;
+	case SSPP_CURSOR0: return MDP5_CTL_LAYER_EXT_REG_CURSOR0(stage);
+	case SSPP_CURSOR1: return MDP5_CTL_LAYER_EXT_REG_CURSOR1(stage);
+	default:	return 0;
+	}
+}
+
+static void mdp5_ctl_reset_blend_regs(struct mdp5_ctl *ctl)
+{
+	unsigned long flags;
+	struct mdp5_ctl_manager *ctl_mgr = ctl->ctlm;
+	int i;
+
+	spin_lock_irqsave(&ctl->hw_lock, flags);
+
+	for (i = 0; i < ctl_mgr->nlm; i++) {
+		ctl_write(ctl, REG_MDP5_CTL_LAYER_REG(ctl->id, i), 0x0);
+		ctl_write(ctl, REG_MDP5_CTL_LAYER_EXT_REG(ctl->id, i), 0x0);
+	}
+
+	spin_unlock_irqrestore(&ctl->hw_lock, flags);
+}
+
+#define PIPE_LEFT	0
+#define PIPE_RIGHT	1
+int mdp5_ctl_blend(struct mdp5_ctl *ctl, struct mdp5_pipeline *pipeline,
+		   enum mdp5_pipe stage[][MAX_PIPE_STAGE],
+		   enum mdp5_pipe r_stage[][MAX_PIPE_STAGE],
+		   u32 stage_cnt, u32 ctl_blend_op_flags)
+{
+	struct mdp5_hw_mixer *mixer = pipeline->mixer;
+	struct mdp5_hw_mixer *r_mixer = pipeline->r_mixer;
+	unsigned long flags;
+	u32 blend_cfg = 0, blend_ext_cfg = 0;
+	u32 r_blend_cfg = 0, r_blend_ext_cfg = 0;
+	int i, start_stage;
+
+	mdp5_ctl_reset_blend_regs(ctl);
+
+	if (ctl_blend_op_flags & MDP5_CTL_BLEND_OP_FLAG_BORDER_OUT) {
+		start_stage = STAGE0;
+		blend_cfg |= MDP5_CTL_LAYER_REG_BORDER_COLOR;
+		if (r_mixer)
+			r_blend_cfg |= MDP5_CTL_LAYER_REG_BORDER_COLOR;
+	} else {
+		start_stage = STAGE_BASE;
+	}
+
+	for (i = start_stage; stage_cnt && i <= STAGE_MAX; i++) {
+		blend_cfg |=
+			mdp_ctl_blend_mask(stage[i][PIPE_LEFT], i) |
+			mdp_ctl_blend_mask(stage[i][PIPE_RIGHT], i);
+		blend_ext_cfg |=
+			mdp_ctl_blend_ext_mask(stage[i][PIPE_LEFT], i) |
+			mdp_ctl_blend_ext_mask(stage[i][PIPE_RIGHT], i);
+		if (r_mixer) {
+			r_blend_cfg |=
+				mdp_ctl_blend_mask(r_stage[i][PIPE_LEFT], i) |
+				mdp_ctl_blend_mask(r_stage[i][PIPE_RIGHT], i);
+			r_blend_ext_cfg |=
+			     mdp_ctl_blend_ext_mask(r_stage[i][PIPE_LEFT], i) |
+			     mdp_ctl_blend_ext_mask(r_stage[i][PIPE_RIGHT], i);
+		}
+	}
+
+	spin_lock_irqsave(&ctl->hw_lock, flags);
+	if (ctl->cursor_on)
+		blend_cfg |=  MDP5_CTL_LAYER_REG_CURSOR_OUT;
+
+	ctl_write(ctl, REG_MDP5_CTL_LAYER_REG(ctl->id, mixer->lm), blend_cfg);
+	ctl_write(ctl, REG_MDP5_CTL_LAYER_EXT_REG(ctl->id, mixer->lm),
+		  blend_ext_cfg);
+	if (r_mixer) {
+		ctl_write(ctl, REG_MDP5_CTL_LAYER_REG(ctl->id, r_mixer->lm),
+			  r_blend_cfg);
+		ctl_write(ctl, REG_MDP5_CTL_LAYER_EXT_REG(ctl->id, r_mixer->lm),
+			  r_blend_ext_cfg);
+	}
+	spin_unlock_irqrestore(&ctl->hw_lock, flags);
+
+	ctl->pending_ctl_trigger = mdp_ctl_flush_mask_lm(mixer->lm);
+	if (r_mixer)
+		ctl->pending_ctl_trigger |= mdp_ctl_flush_mask_lm(r_mixer->lm);
+
+	DBG("lm%d: blend config = 0x%08x. ext_cfg = 0x%08x", mixer->lm,
+		blend_cfg, blend_ext_cfg);
+	if (r_mixer)
+		DBG("lm%d: blend config = 0x%08x. ext_cfg = 0x%08x",
+		    r_mixer->lm, r_blend_cfg, r_blend_ext_cfg);
+
+	return 0;
+}
+
+u32 mdp_ctl_flush_mask_encoder(struct mdp5_interface *intf)
+{
+	if (intf->type == INTF_WB)
+		return MDP5_CTL_FLUSH_WB;
+
+	switch (intf->num) {
+	case 0: return MDP5_CTL_FLUSH_TIMING_0;
+	case 1: return MDP5_CTL_FLUSH_TIMING_1;
+	case 2: return MDP5_CTL_FLUSH_TIMING_2;
+	case 3: return MDP5_CTL_FLUSH_TIMING_3;
+	default: return 0;
+	}
+}
+
+u32 mdp_ctl_flush_mask_cursor(int cursor_id)
+{
+	switch (cursor_id) {
+	case 0: return MDP5_CTL_FLUSH_CURSOR_0;
+	case 1: return MDP5_CTL_FLUSH_CURSOR_1;
+	default: return 0;
+	}
+}
+
+u32 mdp_ctl_flush_mask_pipe(enum mdp5_pipe pipe)
+{
+	switch (pipe) {
+	case SSPP_VIG0: return MDP5_CTL_FLUSH_VIG0;
+	case SSPP_VIG1: return MDP5_CTL_FLUSH_VIG1;
+	case SSPP_VIG2: return MDP5_CTL_FLUSH_VIG2;
+	case SSPP_RGB0: return MDP5_CTL_FLUSH_RGB0;
+	case SSPP_RGB1: return MDP5_CTL_FLUSH_RGB1;
+	case SSPP_RGB2: return MDP5_CTL_FLUSH_RGB2;
+	case SSPP_DMA0: return MDP5_CTL_FLUSH_DMA0;
+	case SSPP_DMA1: return MDP5_CTL_FLUSH_DMA1;
+	case SSPP_VIG3: return MDP5_CTL_FLUSH_VIG3;
+	case SSPP_RGB3: return MDP5_CTL_FLUSH_RGB3;
+	case SSPP_CURSOR0: return MDP5_CTL_FLUSH_CURSOR_0;
+	case SSPP_CURSOR1: return MDP5_CTL_FLUSH_CURSOR_1;
+	default:        return 0;
+	}
+}
+
+u32 mdp_ctl_flush_mask_lm(int lm)
+{
+	switch (lm) {
+	case 0:  return MDP5_CTL_FLUSH_LM0;
+	case 1:  return MDP5_CTL_FLUSH_LM1;
+	case 2:  return MDP5_CTL_FLUSH_LM2;
+	case 3:  return MDP5_CTL_FLUSH_LM3;
+	case 4:  return MDP5_CTL_FLUSH_LM4;
+	case 5:  return MDP5_CTL_FLUSH_LM5;
+	default: return 0;
+	}
+}
+
+static u32 fix_sw_flush(struct mdp5_ctl *ctl, struct mdp5_pipeline *pipeline,
+			u32 flush_mask)
+{
+	struct mdp5_ctl_manager *ctl_mgr = ctl->ctlm;
+	u32 sw_mask = 0;
+#define BIT_NEEDS_SW_FIX(bit) \
+	(!(ctl_mgr->flush_hw_mask & bit) && (flush_mask & bit))
+
+	/* for some targets, cursor bit is the same as LM bit */
+	if (BIT_NEEDS_SW_FIX(MDP5_CTL_FLUSH_CURSOR_0))
+		sw_mask |= mdp_ctl_flush_mask_lm(pipeline->mixer->lm);
+
+	return sw_mask;
+}
+
+static void fix_for_single_flush(struct mdp5_ctl *ctl, u32 *flush_mask,
+		u32 *flush_id)
+{
+	struct mdp5_ctl_manager *ctl_mgr = ctl->ctlm;
+
+	if (ctl->pair) {
+		DBG("CTL %d FLUSH pending mask %x", ctl->id, *flush_mask);
+		ctl->flush_pending = true;
+		ctl_mgr->single_flush_pending_mask |= (*flush_mask);
+		*flush_mask = 0;
+
+		if (ctl->pair->flush_pending) {
+			*flush_id = min_t(u32, ctl->id, ctl->pair->id);
+			*flush_mask = ctl_mgr->single_flush_pending_mask;
+
+			ctl->flush_pending = false;
+			ctl->pair->flush_pending = false;
+			ctl_mgr->single_flush_pending_mask = 0;
+
+			DBG("Single FLUSH mask %x,ID %d", *flush_mask,
+				*flush_id);
+		}
+	}
+}
+
+/**
+ * mdp5_ctl_commit() - Register Flush
+ *
+ * @ctl:        the CTL instance
+ * @pipeline:   the encoder's INTF + MIXER configuration
+ * @flush_mask: bitmask of display controller hw blocks to flush
+ * @start:      if true, immediately update flush registers and set START
+ *              bit, otherwise accumulate flush_mask bits until we are
+ *              ready to START
+ *
+ * The flush register is used to indicate several registers are all
+ * programmed, and are safe to update to the back copy of the double
+ * buffered registers.
+ *
+ * Some registers FLUSH bits are shared when the hardware does not have
+ * dedicated bits for them; handling these is the job of fix_sw_flush().
+ *
+ * CTL registers need to be flushed in some circumstances; if that is the
+ * case, some trigger bits will be present in both flush mask and
+ * ctl->pending_ctl_trigger.
+ *
+ * Return H/W flushed bit mask.
+ */
+u32 mdp5_ctl_commit(struct mdp5_ctl *ctl,
+		    struct mdp5_pipeline *pipeline,
+		    u32 flush_mask, bool start)
+{
+	struct mdp5_ctl_manager *ctl_mgr = ctl->ctlm;
+	unsigned long flags;
+	u32 flush_id = ctl->id;
+	u32 curr_ctl_flush_mask;
+
+	VERB("flush_mask=%x, trigger=%x", flush_mask, ctl->pending_ctl_trigger);
+
+	if (ctl->pending_ctl_trigger & flush_mask) {
+		flush_mask |= MDP5_CTL_FLUSH_CTL;
+		ctl->pending_ctl_trigger = 0;
+	}
+
+	flush_mask |= fix_sw_flush(ctl, pipeline, flush_mask);
+
+	flush_mask &= ctl_mgr->flush_hw_mask;
+
+	curr_ctl_flush_mask = flush_mask;
+
+	fix_for_single_flush(ctl, &flush_mask, &flush_id);
+
+	if (!start) {
+		ctl->flush_mask |= flush_mask;
+		return curr_ctl_flush_mask;
+	} else {
+		flush_mask |= ctl->flush_mask;
+		ctl->flush_mask = 0;
+	}
+
+	if (flush_mask) {
+		spin_lock_irqsave(&ctl->hw_lock, flags);
+		ctl_write(ctl, REG_MDP5_CTL_FLUSH(flush_id), flush_mask);
+		spin_unlock_irqrestore(&ctl->hw_lock, flags);
+	}
+
+	if (start_signal_needed(ctl, pipeline)) {
+		send_start_signal(ctl);
+	}
+
+	return curr_ctl_flush_mask;
+}
+
+u32 mdp5_ctl_get_commit_status(struct mdp5_ctl *ctl)
+{
+	return ctl_read(ctl, REG_MDP5_CTL_FLUSH(ctl->id));
+}
+
+int mdp5_ctl_get_ctl_id(struct mdp5_ctl *ctl)
+{
+	return WARN_ON(!ctl) ? -EINVAL : ctl->id;
+}
+
+/*
+ * mdp5_ctl_pair() - Associate 2 booked CTLs for single FLUSH
+ */
+int mdp5_ctl_pair(struct mdp5_ctl *ctlx, struct mdp5_ctl *ctly, bool enable)
+{
+	struct mdp5_ctl_manager *ctl_mgr = ctlx->ctlm;
+	struct mdp5_kms *mdp5_kms = get_kms(ctl_mgr);
+
+	/* do nothing silently if hw doesn't support */
+	if (!ctl_mgr->single_flush_supported)
+		return 0;
+
+	if (!enable) {
+		ctlx->pair = NULL;
+		ctly->pair = NULL;
+		mdp5_write(mdp5_kms, REG_MDP5_SPARE_0, 0);
+		return 0;
+	} else if ((ctlx->pair != NULL) || (ctly->pair != NULL)) {
+		DRM_DEV_ERROR(ctl_mgr->dev->dev, "CTLs already paired\n");
+		return -EINVAL;
+	} else if (!(ctlx->status & ctly->status & CTL_STAT_BOOKED)) {
+		DRM_DEV_ERROR(ctl_mgr->dev->dev, "Only pair booked CTLs\n");
+		return -EINVAL;
+	}
+
+	ctlx->pair = ctly;
+	ctly->pair = ctlx;
+
+	mdp5_write(mdp5_kms, REG_MDP5_SPARE_0,
+		   MDP5_SPARE_0_SPLIT_DPL_SINGLE_FLUSH_EN);
+
+	return 0;
+}
+
+/*
+ * mdp5_ctl_request() - CTL allocation
+ *
+ * Try to return booked CTL for @intf_num is 1 or 2, unbooked for other INTFs.
+ * If no CTL is available in preferred category, allocate from the other one.
+ *
+ * @return fail if no CTL is available.
+ */
+struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctl_mgr,
+		int intf_num)
+{
+	struct mdp5_ctl *ctl = NULL;
+	const u32 checkm = CTL_STAT_BUSY | CTL_STAT_BOOKED;
+	u32 match = ((intf_num == 1) || (intf_num == 2)) ? CTL_STAT_BOOKED : 0;
+	unsigned long flags;
+	int c;
+
+	spin_lock_irqsave(&ctl_mgr->pool_lock, flags);
+
+	/* search the preferred */
+	for (c = 0; c < ctl_mgr->nctl; c++)
+		if ((ctl_mgr->ctls[c].status & checkm) == match)
+			goto found;
+
+	dev_warn(ctl_mgr->dev->dev,
+		"fall back to the other CTL category for INTF %d!\n", intf_num);
+
+	match ^= CTL_STAT_BOOKED;
+	for (c = 0; c < ctl_mgr->nctl; c++)
+		if ((ctl_mgr->ctls[c].status & checkm) == match)
+			goto found;
+
+	DRM_DEV_ERROR(ctl_mgr->dev->dev, "No more CTL available!");
+	goto unlock;
+
+found:
+	ctl = &ctl_mgr->ctls[c];
+	ctl->status |= CTL_STAT_BUSY;
+	ctl->pending_ctl_trigger = 0;
+	DBG("CTL %d allocated", ctl->id);
+
+unlock:
+	spin_unlock_irqrestore(&ctl_mgr->pool_lock, flags);
+	return ctl;
+}
+
+void mdp5_ctlm_hw_reset(struct mdp5_ctl_manager *ctl_mgr)
+{
+	unsigned long flags;
+	int c;
+
+	for (c = 0; c < ctl_mgr->nctl; c++) {
+		struct mdp5_ctl *ctl = &ctl_mgr->ctls[c];
+
+		spin_lock_irqsave(&ctl->hw_lock, flags);
+		ctl_write(ctl, REG_MDP5_CTL_OP(ctl->id), 0);
+		spin_unlock_irqrestore(&ctl->hw_lock, flags);
+	}
+}
+
+struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev,
+		void __iomem *mmio_base, struct mdp5_cfg_handler *cfg_hnd)
+{
+	struct mdp5_ctl_manager *ctl_mgr;
+	const struct mdp5_cfg_hw *hw_cfg = mdp5_cfg_get_hw_config(cfg_hnd);
+	int rev = mdp5_cfg_get_hw_rev(cfg_hnd);
+	unsigned dsi_cnt = 0;
+	const struct mdp5_ctl_block *ctl_cfg = &hw_cfg->ctl;
+	unsigned long flags;
+	int c, ret;
+
+	ctl_mgr = devm_kzalloc(dev->dev, sizeof(*ctl_mgr), GFP_KERNEL);
+	if (!ctl_mgr) {
+		DRM_DEV_ERROR(dev->dev, "failed to allocate CTL manager\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	if (WARN_ON(ctl_cfg->count > MAX_CTL)) {
+		DRM_DEV_ERROR(dev->dev, "Increase static pool size to at least %d\n",
+				ctl_cfg->count);
+		return ERR_PTR(-ENOSPC);
+	}
+
+	/* initialize the CTL manager: */
+	ctl_mgr->dev = dev;
+	ctl_mgr->nlm = hw_cfg->lm.count;
+	ctl_mgr->nctl = ctl_cfg->count;
+	ctl_mgr->flush_hw_mask = ctl_cfg->flush_hw_mask;
+	spin_lock_init(&ctl_mgr->pool_lock);
+
+	/* initialize each CTL of the pool: */
+	spin_lock_irqsave(&ctl_mgr->pool_lock, flags);
+	for (c = 0; c < ctl_mgr->nctl; c++) {
+		struct mdp5_ctl *ctl = &ctl_mgr->ctls[c];
+
+		if (WARN_ON(!ctl_cfg->base[c])) {
+			DRM_DEV_ERROR(dev->dev, "CTL_%d: base is null!\n", c);
+			ret = -EINVAL;
+			spin_unlock_irqrestore(&ctl_mgr->pool_lock, flags);
+			return ERR_PTR(ret);
+		}
+		ctl->ctlm = ctl_mgr;
+		ctl->id = c;
+		ctl->reg_offset = ctl_cfg->base[c];
+		ctl->status = 0;
+		spin_lock_init(&ctl->hw_lock);
+	}
+
+	/*
+	 * In bonded DSI case, CTL0 and CTL1 are always assigned to two DSI
+	 * interfaces to support single FLUSH feature (Flush CTL0 and CTL1 when
+	 * only write into CTL0's FLUSH register) to keep two DSI pipes in sync.
+	 * Single FLUSH is supported from hw rev v3.0.
+	 */
+	for (c = 0; c < ARRAY_SIZE(hw_cfg->intf.connect); c++)
+		if (hw_cfg->intf.connect[c] == INTF_DSI)
+			dsi_cnt++;
+	if ((rev >= 3) && (dsi_cnt > 1)) {
+		ctl_mgr->single_flush_supported = true;
+		/* Reserve CTL0/1 for INTF1/2 */
+		ctl_mgr->ctls[0].status |= CTL_STAT_BOOKED;
+		ctl_mgr->ctls[1].status |= CTL_STAT_BOOKED;
+	}
+	spin_unlock_irqrestore(&ctl_mgr->pool_lock, flags);
+	DBG("Pool of %d CTLs created.", ctl_mgr->nctl);
+
+	return ctl_mgr;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_ctl.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_ctl.h
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __MDP5_CTL_H__
+#define __MDP5_CTL_H__
+
+#include "msm_drv.h"
+
+/*
+ * CTL Manager prototypes:
+ * mdp5_ctlm_init() returns a ctlm (CTL Manager) handler,
+ * which is then used to call the other mdp5_ctlm_*(ctlm, ...) functions.
+ */
+struct mdp5_ctl_manager;
+struct mdp5_ctl_manager *mdp5_ctlm_init(struct drm_device *dev,
+		void __iomem *mmio_base, struct mdp5_cfg_handler *cfg_hnd);
+void mdp5_ctlm_hw_reset(struct mdp5_ctl_manager *ctlm);
+
+/*
+ * CTL prototypes:
+ * mdp5_ctl_request(ctlm, ...) returns a ctl (CTL resource) handler,
+ * which is then used to call the other mdp5_ctl_*(ctl, ...) functions.
+ */
+struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctlm, int intf_num);
+
+int mdp5_ctl_get_ctl_id(struct mdp5_ctl *ctl);
+
+struct mdp5_interface;
+struct mdp5_pipeline;
+int mdp5_ctl_set_pipeline(struct mdp5_ctl *ctl, struct mdp5_pipeline *p);
+int mdp5_ctl_set_encoder_state(struct mdp5_ctl *ctl, struct mdp5_pipeline *p,
+			       bool enabled);
+
+int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, struct mdp5_pipeline *pipeline,
+			int cursor_id, bool enable);
+int mdp5_ctl_pair(struct mdp5_ctl *ctlx, struct mdp5_ctl *ctly, bool enable);
+
+#define MAX_PIPE_STAGE		2
+
+/*
+ * mdp5_ctl_blend() - Blend multiple layers on a Layer Mixer (LM)
+ *
+ * @stage: array to contain the pipe num for each stage
+ * @stage_cnt: valid stage number in stage array
+ * @ctl_blend_op_flags: blender operation mode flags
+ *
+ * Note:
+ * CTL registers need to be flushed after calling this function
+ * (call mdp5_ctl_commit() with mdp_ctl_flush_mask_ctl() mask)
+ */
+#define MDP5_CTL_BLEND_OP_FLAG_BORDER_OUT	BIT(0)
+int mdp5_ctl_blend(struct mdp5_ctl *ctl, struct mdp5_pipeline *pipeline,
+		   enum mdp5_pipe stage[][MAX_PIPE_STAGE],
+		   enum mdp5_pipe r_stage[][MAX_PIPE_STAGE],
+		   u32 stage_cnt, u32 ctl_blend_op_flags);
+
+/**
+ * mdp_ctl_flush_mask...() - Register FLUSH masks
+ *
+ * These masks are used to specify which block(s) need to be flushed
+ * through @flush_mask parameter in mdp5_ctl_commit(.., flush_mask).
+ */
+u32 mdp_ctl_flush_mask_lm(int lm);
+u32 mdp_ctl_flush_mask_pipe(enum mdp5_pipe pipe);
+u32 mdp_ctl_flush_mask_cursor(int cursor_id);
+u32 mdp_ctl_flush_mask_encoder(struct mdp5_interface *intf);
+
+/* @flush_mask: see CTL flush masks definitions below */
+u32 mdp5_ctl_commit(struct mdp5_ctl *ctl, struct mdp5_pipeline *pipeline,
+		    u32 flush_mask, bool start);
+u32 mdp5_ctl_get_commit_status(struct mdp5_ctl *ctl);
+
+
+
+#endif /* __MDP5_CTL_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_encoder.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_encoder.c
@@ -0,0 +1,349 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_probe_helper.h>
+
+#include "mdp5_kms.h"
+
+static struct mdp5_kms *get_kms(struct drm_encoder *encoder)
+{
+	struct msm_drm_private *priv = encoder->dev->dev_private;
+	return to_mdp5_kms(to_mdp_kms(priv->kms));
+}
+
+static void mdp5_vid_encoder_mode_set(struct drm_encoder *encoder,
+				      struct drm_display_mode *mode,
+				      struct drm_display_mode *adjusted_mode)
+{
+	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
+	struct mdp5_kms *mdp5_kms = get_kms(encoder);
+	struct drm_device *dev = encoder->dev;
+	struct drm_connector *connector;
+	int intf = mdp5_encoder->intf->num;
+	uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol;
+	uint32_t display_v_start, display_v_end;
+	uint32_t hsync_start_x, hsync_end_x;
+	uint32_t format = 0x2100;
+	unsigned long flags;
+
+	mode = adjusted_mode;
+
+	DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
+
+	ctrl_pol = 0;
+
+	/* DSI controller cannot handle active-low sync signals. */
+	if (mdp5_encoder->intf->type != INTF_DSI) {
+		if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+			ctrl_pol |= MDP5_INTF_POLARITY_CTL_HSYNC_LOW;
+		if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+			ctrl_pol |= MDP5_INTF_POLARITY_CTL_VSYNC_LOW;
+	}
+	/* probably need to get DATA_EN polarity from panel.. */
+
+	dtv_hsync_skew = 0;  /* get this from panel? */
+
+	/* Get color format from panel, default is 8bpc */
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		if (connector->encoder == encoder) {
+			switch (connector->display_info.bpc) {
+			case 4:
+				format |= 0;
+				break;
+			case 5:
+				format |= 0x15;
+				break;
+			case 6:
+				format |= 0x2A;
+				break;
+			case 8:
+			default:
+				format |= 0x3F;
+				break;
+			}
+			break;
+		}
+	}
+
+	hsync_start_x = (mode->htotal - mode->hsync_start);
+	hsync_end_x = mode->htotal - (mode->hsync_start - mode->hdisplay) - 1;
+
+	vsync_period = mode->vtotal * mode->htotal;
+	vsync_len = (mode->vsync_end - mode->vsync_start) * mode->htotal;
+	display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + dtv_hsync_skew;
+	display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + dtv_hsync_skew - 1;
+
+	/*
+	 * For edp only:
+	 * DISPLAY_V_START = (VBP * HCYCLE) + HBP
+	 * DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP
+	 */
+	if (mdp5_encoder->intf->type == INTF_eDP) {
+		display_v_start += mode->htotal - mode->hsync_start;
+		display_v_end -= mode->hsync_start - mode->hdisplay;
+	}
+
+	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
+
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_HSYNC_CTL(intf),
+			MDP5_INTF_HSYNC_CTL_PULSEW(mode->hsync_end - mode->hsync_start) |
+			MDP5_INTF_HSYNC_CTL_PERIOD(mode->htotal));
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_VSYNC_PERIOD_F0(intf), vsync_period);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_VSYNC_LEN_F0(intf), vsync_len);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_DISPLAY_HCTL(intf),
+			MDP5_INTF_DISPLAY_HCTL_START(hsync_start_x) |
+			MDP5_INTF_DISPLAY_HCTL_END(hsync_end_x));
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_DISPLAY_VSTART_F0(intf), display_v_start);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_DISPLAY_VEND_F0(intf), display_v_end);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_BORDER_COLOR(intf), 0);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_UNDERFLOW_COLOR(intf), 0xff);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_HSYNC_SKEW(intf), dtv_hsync_skew);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_POLARITY_CTL(intf), ctrl_pol);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_ACTIVE_HCTL(intf),
+			MDP5_INTF_ACTIVE_HCTL_START(0) |
+			MDP5_INTF_ACTIVE_HCTL_END(0));
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_ACTIVE_VSTART_F0(intf), 0);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_ACTIVE_VEND_F0(intf), 0);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_PANEL_FORMAT(intf), format);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(intf), 0x3);  /* frame+line? */
+
+	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
+
+	mdp5_crtc_set_pipeline(encoder->crtc);
+}
+
+static void mdp5_vid_encoder_disable(struct drm_encoder *encoder)
+{
+	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
+	struct mdp5_kms *mdp5_kms = get_kms(encoder);
+	struct mdp5_ctl *ctl = mdp5_encoder->ctl;
+	struct mdp5_pipeline *pipeline = mdp5_crtc_get_pipeline(encoder->crtc);
+	struct mdp5_hw_mixer *mixer = mdp5_crtc_get_mixer(encoder->crtc);
+	struct mdp5_interface *intf = mdp5_encoder->intf;
+	int intfn = mdp5_encoder->intf->num;
+	unsigned long flags;
+
+	if (WARN_ON(!mdp5_encoder->enabled))
+		return;
+
+	mdp5_ctl_set_encoder_state(ctl, pipeline, false);
+
+	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 0);
+	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
+	mdp5_ctl_commit(ctl, pipeline, mdp_ctl_flush_mask_encoder(intf), true);
+
+	/*
+	 * Wait for a vsync so we know the ENABLE=0 latched before
+	 * the (connector) source of the vsync's gets disabled,
+	 * otherwise we end up in a funny state if we re-enable
+	 * before the disable latches, which results that some of
+	 * the settings changes for the new modeset (like new
+	 * scanout buffer) don't latch properly..
+	 */
+	mdp_irq_wait(&mdp5_kms->base, intf2vblank(mixer, intf));
+
+	mdp5_encoder->enabled = false;
+}
+
+static void mdp5_vid_encoder_enable(struct drm_encoder *encoder)
+{
+	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
+	struct mdp5_kms *mdp5_kms = get_kms(encoder);
+	struct mdp5_ctl *ctl = mdp5_encoder->ctl;
+	struct mdp5_interface *intf = mdp5_encoder->intf;
+	struct mdp5_pipeline *pipeline = mdp5_crtc_get_pipeline(encoder->crtc);
+	int intfn = intf->num;
+	unsigned long flags;
+
+	if (WARN_ON(mdp5_encoder->enabled))
+		return;
+
+	spin_lock_irqsave(&mdp5_encoder->intf_lock, flags);
+	mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intfn), 1);
+	spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags);
+	mdp5_ctl_commit(ctl, pipeline, mdp_ctl_flush_mask_encoder(intf), true);
+
+	mdp5_ctl_set_encoder_state(ctl, pipeline, true);
+
+	mdp5_encoder->enabled = true;
+}
+
+static void mdp5_encoder_mode_set(struct drm_encoder *encoder,
+				  struct drm_display_mode *mode,
+				  struct drm_display_mode *adjusted_mode)
+{
+	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
+	struct mdp5_interface *intf = mdp5_encoder->intf;
+
+	if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
+		mdp5_cmd_encoder_mode_set(encoder, mode, adjusted_mode);
+	else
+		mdp5_vid_encoder_mode_set(encoder, mode, adjusted_mode);
+}
+
+static void mdp5_encoder_disable(struct drm_encoder *encoder)
+{
+	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
+	struct mdp5_interface *intf = mdp5_encoder->intf;
+
+	if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
+		mdp5_cmd_encoder_disable(encoder);
+	else
+		mdp5_vid_encoder_disable(encoder);
+}
+
+static void mdp5_encoder_enable(struct drm_encoder *encoder)
+{
+	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
+	struct mdp5_interface *intf = mdp5_encoder->intf;
+	/* this isn't right I think */
+	struct drm_crtc_state *cstate = encoder->crtc->state;
+
+	mdp5_encoder_mode_set(encoder, &cstate->mode, &cstate->adjusted_mode);
+
+	if (intf->mode == MDP5_INTF_DSI_MODE_COMMAND)
+		mdp5_cmd_encoder_enable(encoder);
+	else
+		mdp5_vid_encoder_enable(encoder);
+}
+
+static int mdp5_encoder_atomic_check(struct drm_encoder *encoder,
+				     struct drm_crtc_state *crtc_state,
+				     struct drm_connector_state *conn_state)
+{
+	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
+	struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc_state);
+	struct mdp5_interface *intf = mdp5_encoder->intf;
+	struct mdp5_ctl *ctl = mdp5_encoder->ctl;
+
+	mdp5_cstate->ctl = ctl;
+	mdp5_cstate->pipeline.intf = intf;
+
+	/*
+	 * This is a bit awkward, but we want to flush the CTL and hit the
+	 * START bit at most once for an atomic update.  In the non-full-
+	 * modeset case, this is done from crtc->atomic_flush(), but that
+	 * is too early in the case of full modeset, in which case we
+	 * defer to encoder->enable().  But we need to *know* whether
+	 * encoder->enable() will be called to do this:
+	 */
+	if (drm_atomic_crtc_needs_modeset(crtc_state))
+		mdp5_cstate->defer_start = true;
+
+	return 0;
+}
+
+static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = {
+	.disable = mdp5_encoder_disable,
+	.enable = mdp5_encoder_enable,
+	.atomic_check = mdp5_encoder_atomic_check,
+};
+
+int mdp5_encoder_get_linecount(struct drm_encoder *encoder)
+{
+	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
+	struct mdp5_kms *mdp5_kms = get_kms(encoder);
+	int intf = mdp5_encoder->intf->num;
+
+	return mdp5_read(mdp5_kms, REG_MDP5_INTF_LINE_COUNT(intf));
+}
+
+u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder)
+{
+	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
+	struct mdp5_kms *mdp5_kms = get_kms(encoder);
+	int intf = mdp5_encoder->intf->num;
+
+	return mdp5_read(mdp5_kms, REG_MDP5_INTF_FRAME_COUNT(intf));
+}
+
+int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
+				       struct drm_encoder *slave_encoder)
+{
+	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
+	struct mdp5_encoder *mdp5_slave_enc = to_mdp5_encoder(slave_encoder);
+	struct mdp5_kms *mdp5_kms;
+	struct device *dev;
+	int intf_num;
+	u32 data = 0;
+
+	if (!encoder || !slave_encoder)
+		return -EINVAL;
+
+	mdp5_kms = get_kms(encoder);
+	intf_num = mdp5_encoder->intf->num;
+
+	/* Switch slave encoder's TimingGen Sync mode,
+	 * to use the master's enable signal for the slave encoder.
+	 */
+	if (intf_num == 1)
+		data |= MDP5_SPLIT_DPL_LOWER_INTF2_TG_SYNC;
+	else if (intf_num == 2)
+		data |= MDP5_SPLIT_DPL_LOWER_INTF1_TG_SYNC;
+	else
+		return -EINVAL;
+
+	dev = &mdp5_kms->pdev->dev;
+	/* Make sure clocks are on when connectors calling this function. */
+	pm_runtime_get_sync(dev);
+
+	/* Dumb Panel, Sync mode */
+	mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_UPPER, 0);
+	mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_LOWER, data);
+	mdp5_write(mdp5_kms, REG_MDP5_SPLIT_DPL_EN, 1);
+
+	mdp5_ctl_pair(mdp5_encoder->ctl, mdp5_slave_enc->ctl, true);
+
+	pm_runtime_put_sync(dev);
+
+	return 0;
+}
+
+void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode)
+{
+	struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder);
+	struct mdp5_interface *intf = mdp5_encoder->intf;
+
+	/* TODO: Expand this to set writeback modes too */
+	if (cmd_mode) {
+		WARN_ON(intf->type != INTF_DSI);
+		intf->mode = MDP5_INTF_DSI_MODE_COMMAND;
+	} else {
+		if (intf->type == INTF_DSI)
+			intf->mode = MDP5_INTF_DSI_MODE_VIDEO;
+		else
+			intf->mode = MDP5_INTF_MODE_NONE;
+	}
+}
+
+/* initialize encoder */
+struct drm_encoder *mdp5_encoder_init(struct drm_device *dev,
+				      struct mdp5_interface *intf,
+				      struct mdp5_ctl *ctl)
+{
+	struct drm_encoder *encoder = NULL;
+	struct mdp5_encoder *mdp5_encoder;
+	int enc_type = (intf->type == INTF_DSI) ?
+		DRM_MODE_ENCODER_DSI : DRM_MODE_ENCODER_TMDS;
+
+	mdp5_encoder = drmm_encoder_alloc(dev, struct mdp5_encoder, base,
+					  NULL, enc_type, NULL);
+	if (IS_ERR(mdp5_encoder))
+		return ERR_CAST(mdp5_encoder);
+
+	encoder = &mdp5_encoder->base;
+	mdp5_encoder->ctl = ctl;
+	mdp5_encoder->intf = intf;
+
+	spin_lock_init(&mdp5_encoder->intf_lock);
+
+	drm_encoder_helper_add(encoder, &mdp5_encoder_helper_funcs);
+
+	return encoder;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_irq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_irq.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/irq.h>
+
+#include <drm/drm_print.h>
+#include <drm/drm_vblank.h>
+
+#include "msm_drv.h"
+#include "mdp5_kms.h"
+
+void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
+		uint32_t old_irqmask)
+{
+	mdp5_write(to_mdp5_kms(mdp_kms), REG_MDP5_INTR_CLEAR,
+		   irqmask ^ (irqmask & old_irqmask));
+	mdp5_write(to_mdp5_kms(mdp_kms), REG_MDP5_INTR_EN, irqmask);
+}
+
+static void mdp5_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus)
+{
+	struct mdp5_kms *mdp5_kms = container_of(irq, struct mdp5_kms, error_handler);
+	static DEFINE_RATELIMIT_STATE(rs, 5*HZ, 1);
+	extern bool dumpstate;
+
+	DRM_ERROR_RATELIMITED("errors: %08x\n", irqstatus);
+
+	if (dumpstate && __ratelimit(&rs)) {
+		struct drm_printer p = drm_info_printer(mdp5_kms->dev->dev);
+		drm_state_dump(mdp5_kms->dev, &p);
+		if (mdp5_kms->smp)
+			mdp5_smp_dump(mdp5_kms->smp, &p);
+	}
+}
+
+void mdp5_irq_preinstall(struct msm_kms *kms)
+{
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+	struct device *dev = &mdp5_kms->pdev->dev;
+
+	pm_runtime_get_sync(dev);
+	mdp5_write(mdp5_kms, REG_MDP5_INTR_CLEAR, 0xffffffff);
+	mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000);
+	pm_runtime_put_sync(dev);
+}
+
+int mdp5_irq_postinstall(struct msm_kms *kms)
+{
+	struct mdp_kms *mdp_kms = to_mdp_kms(kms);
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
+	struct device *dev = &mdp5_kms->pdev->dev;
+	struct mdp_irq *error_handler = &mdp5_kms->error_handler;
+
+	error_handler->irq = mdp5_irq_error_handler;
+	error_handler->irqmask = MDP5_IRQ_INTF0_UNDER_RUN |
+			MDP5_IRQ_INTF1_UNDER_RUN |
+			MDP5_IRQ_INTF2_UNDER_RUN |
+			MDP5_IRQ_INTF3_UNDER_RUN;
+
+	pm_runtime_get_sync(dev);
+	mdp_irq_register(mdp_kms, error_handler);
+	pm_runtime_put_sync(dev);
+
+	return 0;
+}
+
+void mdp5_irq_uninstall(struct msm_kms *kms)
+{
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+	struct device *dev = &mdp5_kms->pdev->dev;
+
+	pm_runtime_get_sync(dev);
+	mdp5_write(mdp5_kms, REG_MDP5_INTR_EN, 0x00000000);
+	pm_runtime_put_sync(dev);
+}
+
+irqreturn_t mdp5_irq(struct msm_kms *kms)
+{
+	struct mdp_kms *mdp_kms = to_mdp_kms(kms);
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(mdp_kms);
+	struct drm_device *dev = mdp5_kms->dev;
+	struct drm_crtc *crtc;
+	uint32_t status, enable;
+
+	enable = mdp5_read(mdp5_kms, REG_MDP5_INTR_EN);
+	status = mdp5_read(mdp5_kms, REG_MDP5_INTR_STATUS) & enable;
+	mdp5_write(mdp5_kms, REG_MDP5_INTR_CLEAR, status);
+
+	VERB("status=%08x", status);
+
+	mdp_dispatch_irqs(mdp_kms, status);
+
+	drm_for_each_crtc(crtc, dev)
+		if (status & mdp5_crtc_vblank(crtc))
+			drm_crtc_handle_vblank(crtc);
+
+	return IRQ_HANDLED;
+}
+
+int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
+{
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+	struct device *dev = &mdp5_kms->pdev->dev;
+
+	pm_runtime_get_sync(dev);
+	mdp_update_vblank_mask(to_mdp_kms(kms),
+			mdp5_crtc_vblank(crtc), true);
+	pm_runtime_put_sync(dev);
+
+	return 0;
+}
+
+void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
+{
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+	struct device *dev = &mdp5_kms->pdev->dev;
+
+	pm_runtime_get_sync(dev);
+	mdp_update_vblank_mask(to_mdp_kms(kms),
+			mdp5_crtc_vblank(crtc), false);
+	pm_runtime_put_sync(dev);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_kms.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_kms.c
@@ -0,0 +1,976 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/interconnect.h>
+#include <linux/of_irq.h>
+
+#include <drm/drm_debugfs.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_file.h>
+#include <drm/drm_vblank.h>
+
+#include "msm_drv.h"
+#include "msm_gem.h"
+#include "msm_mmu.h"
+#include "mdp5_kms.h"
+
+static int mdp5_hw_init(struct msm_kms *kms)
+{
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+	struct device *dev = &mdp5_kms->pdev->dev;
+	unsigned long flags;
+
+	pm_runtime_get_sync(dev);
+
+	/* Magic unknown register writes:
+	 *
+	 *    W VBIF:0x004 00000001      (mdss_mdp.c:839)
+	 *    W MDP5:0x2e0 0xe9          (mdss_mdp.c:839)
+	 *    W MDP5:0x2e4 0x55          (mdss_mdp.c:839)
+	 *    W MDP5:0x3ac 0xc0000ccc    (mdss_mdp.c:839)
+	 *    W MDP5:0x3b4 0xc0000ccc    (mdss_mdp.c:839)
+	 *    W MDP5:0x3bc 0xcccccc      (mdss_mdp.c:839)
+	 *    W MDP5:0x4a8 0xcccc0c0     (mdss_mdp.c:839)
+	 *    W MDP5:0x4b0 0xccccc0c0    (mdss_mdp.c:839)
+	 *    W MDP5:0x4b8 0xccccc000    (mdss_mdp.c:839)
+	 *
+	 * Downstream fbdev driver gets these register offsets/values
+	 * from DT.. not really sure what these registers are or if
+	 * different values for different boards/SoC's, etc.  I guess
+	 * they are the golden registers.
+	 *
+	 * Not setting these does not seem to cause any problem.  But
+	 * we may be getting lucky with the bootloader initializing
+	 * them for us.  OTOH, if we can always count on the bootloader
+	 * setting the golden registers, then perhaps we don't need to
+	 * care.
+	 */
+
+	spin_lock_irqsave(&mdp5_kms->resource_lock, flags);
+	mdp5_write(mdp5_kms, REG_MDP5_DISP_INTF_SEL, 0);
+	spin_unlock_irqrestore(&mdp5_kms->resource_lock, flags);
+
+	mdp5_ctlm_hw_reset(mdp5_kms->ctlm);
+
+	pm_runtime_put_sync(dev);
+
+	return 0;
+}
+
+/* Global/shared object state funcs */
+
+/*
+ * This is a helper that returns the private state currently in operation.
+ * Note that this would return the "old_state" if called in the atomic check
+ * path, and the "new_state" after the atomic swap has been done.
+ */
+struct mdp5_global_state *
+mdp5_get_existing_global_state(struct mdp5_kms *mdp5_kms)
+{
+	return to_mdp5_global_state(mdp5_kms->glob_state.state);
+}
+
+/*
+ * This acquires the modeset lock set aside for global state, creates
+ * a new duplicated private object state.
+ */
+struct mdp5_global_state *mdp5_get_global_state(struct drm_atomic_state *s)
+{
+	struct msm_drm_private *priv = s->dev->dev_private;
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+	struct drm_private_state *priv_state;
+	int ret;
+
+	ret = drm_modeset_lock(&mdp5_kms->glob_state_lock, s->acquire_ctx);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv_state = drm_atomic_get_private_obj_state(s, &mdp5_kms->glob_state);
+	if (IS_ERR(priv_state))
+		return ERR_CAST(priv_state);
+
+	return to_mdp5_global_state(priv_state);
+}
+
+static struct drm_private_state *
+mdp5_global_duplicate_state(struct drm_private_obj *obj)
+{
+	struct mdp5_global_state *state;
+
+	state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return NULL;
+
+	__drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
+
+	return &state->base;
+}
+
+static void mdp5_global_destroy_state(struct drm_private_obj *obj,
+				      struct drm_private_state *state)
+{
+	struct mdp5_global_state *mdp5_state = to_mdp5_global_state(state);
+
+	kfree(mdp5_state);
+}
+
+static const struct drm_private_state_funcs mdp5_global_state_funcs = {
+	.atomic_duplicate_state = mdp5_global_duplicate_state,
+	.atomic_destroy_state = mdp5_global_destroy_state,
+};
+
+static int mdp5_global_obj_init(struct mdp5_kms *mdp5_kms)
+{
+	struct mdp5_global_state *state;
+
+	drm_modeset_lock_init(&mdp5_kms->glob_state_lock);
+
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return -ENOMEM;
+
+	state->mdp5_kms = mdp5_kms;
+
+	drm_atomic_private_obj_init(mdp5_kms->dev, &mdp5_kms->glob_state,
+				    &state->base,
+				    &mdp5_global_state_funcs);
+	return 0;
+}
+
+static void mdp5_enable_commit(struct msm_kms *kms)
+{
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+	pm_runtime_get_sync(&mdp5_kms->pdev->dev);
+}
+
+static void mdp5_disable_commit(struct msm_kms *kms)
+{
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+	pm_runtime_put_sync(&mdp5_kms->pdev->dev);
+}
+
+static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
+{
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+	struct mdp5_global_state *global_state;
+
+	global_state = mdp5_get_existing_global_state(mdp5_kms);
+
+	if (mdp5_kms->smp)
+		mdp5_smp_prepare_commit(mdp5_kms->smp, &global_state->smp);
+}
+
+static void mdp5_flush_commit(struct msm_kms *kms, unsigned crtc_mask)
+{
+	/* TODO */
+}
+
+static void mdp5_wait_flush(struct msm_kms *kms, unsigned crtc_mask)
+{
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+	struct drm_crtc *crtc;
+
+	for_each_crtc_mask(mdp5_kms->dev, crtc, crtc_mask)
+		mdp5_crtc_wait_for_commit_done(crtc);
+}
+
+static void mdp5_complete_commit(struct msm_kms *kms, unsigned crtc_mask)
+{
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+	struct mdp5_global_state *global_state;
+
+	global_state = mdp5_get_existing_global_state(mdp5_kms);
+
+	if (mdp5_kms->smp)
+		mdp5_smp_complete_commit(mdp5_kms->smp, &global_state->smp);
+}
+
+static int mdp5_set_split_display(struct msm_kms *kms,
+		struct drm_encoder *encoder,
+		struct drm_encoder *slave_encoder,
+		bool is_cmd_mode)
+{
+	if (is_cmd_mode)
+		return mdp5_cmd_encoder_set_split_display(encoder,
+							slave_encoder);
+	else
+		return mdp5_vid_encoder_set_split_display(encoder,
+							  slave_encoder);
+}
+
+static void mdp5_destroy(struct mdp5_kms *mdp5_kms);
+
+static void mdp5_kms_destroy(struct msm_kms *kms)
+{
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+	struct msm_gem_address_space *aspace = kms->aspace;
+
+	if (aspace) {
+		aspace->mmu->funcs->detach(aspace->mmu);
+		msm_gem_address_space_put(aspace);
+	}
+
+	mdp_kms_destroy(&mdp5_kms->base);
+	mdp5_destroy(mdp5_kms);
+}
+
+#ifdef CONFIG_DEBUG_FS
+static int smp_show(struct seq_file *m, void *arg)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+	struct drm_printer p = drm_seq_file_printer(m);
+
+	if (!mdp5_kms->smp) {
+		drm_printf(&p, "no SMP pool\n");
+		return 0;
+	}
+
+	mdp5_smp_dump(mdp5_kms->smp, &p);
+
+	return 0;
+}
+
+static struct drm_info_list mdp5_debugfs_list[] = {
+		{"smp", smp_show },
+};
+
+static int mdp5_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
+{
+	drm_debugfs_create_files(mdp5_debugfs_list,
+				 ARRAY_SIZE(mdp5_debugfs_list),
+				 minor->debugfs_root, minor);
+
+	return 0;
+}
+#endif
+
+static const struct mdp_kms_funcs kms_funcs = {
+	.base = {
+		.hw_init         = mdp5_hw_init,
+		.irq_preinstall  = mdp5_irq_preinstall,
+		.irq_postinstall = mdp5_irq_postinstall,
+		.irq_uninstall   = mdp5_irq_uninstall,
+		.irq             = mdp5_irq,
+		.enable_vblank   = mdp5_enable_vblank,
+		.disable_vblank  = mdp5_disable_vblank,
+		.flush_commit    = mdp5_flush_commit,
+		.enable_commit   = mdp5_enable_commit,
+		.disable_commit  = mdp5_disable_commit,
+		.prepare_commit  = mdp5_prepare_commit,
+		.wait_flush      = mdp5_wait_flush,
+		.complete_commit = mdp5_complete_commit,
+		.get_format      = mdp_get_format,
+		.set_split_display = mdp5_set_split_display,
+		.destroy         = mdp5_kms_destroy,
+#ifdef CONFIG_DEBUG_FS
+		.debugfs_init    = mdp5_kms_debugfs_init,
+#endif
+	},
+	.set_irqmask         = mdp5_set_irqmask,
+};
+
+static int mdp5_disable(struct mdp5_kms *mdp5_kms)
+{
+	DBG("");
+
+	mdp5_kms->enable_count--;
+	WARN_ON(mdp5_kms->enable_count < 0);
+
+	clk_disable_unprepare(mdp5_kms->tbu_rt_clk);
+	clk_disable_unprepare(mdp5_kms->tbu_clk);
+	clk_disable_unprepare(mdp5_kms->ahb_clk);
+	clk_disable_unprepare(mdp5_kms->axi_clk);
+	clk_disable_unprepare(mdp5_kms->core_clk);
+	clk_disable_unprepare(mdp5_kms->lut_clk);
+
+	return 0;
+}
+
+static int mdp5_enable(struct mdp5_kms *mdp5_kms)
+{
+	DBG("");
+
+	mdp5_kms->enable_count++;
+
+	clk_prepare_enable(mdp5_kms->ahb_clk);
+	clk_prepare_enable(mdp5_kms->axi_clk);
+	clk_prepare_enable(mdp5_kms->core_clk);
+	clk_prepare_enable(mdp5_kms->lut_clk);
+	clk_prepare_enable(mdp5_kms->tbu_clk);
+	clk_prepare_enable(mdp5_kms->tbu_rt_clk);
+
+	return 0;
+}
+
+static struct drm_encoder *construct_encoder(struct mdp5_kms *mdp5_kms,
+					     struct mdp5_interface *intf,
+					     struct mdp5_ctl *ctl)
+{
+	struct drm_device *dev = mdp5_kms->dev;
+	struct drm_encoder *encoder;
+
+	encoder = mdp5_encoder_init(dev, intf, ctl);
+	if (IS_ERR(encoder)) {
+		DRM_DEV_ERROR(dev->dev, "failed to construct encoder\n");
+		return encoder;
+	}
+
+	return encoder;
+}
+
+static int get_dsi_id_from_intf(const struct mdp5_cfg_hw *hw_cfg, int intf_num)
+{
+	const enum mdp5_intf_type *intfs = hw_cfg->intf.connect;
+	const int intf_cnt = ARRAY_SIZE(hw_cfg->intf.connect);
+	int id = 0, i;
+
+	for (i = 0; i < intf_cnt; i++) {
+		if (intfs[i] == INTF_DSI) {
+			if (intf_num == i)
+				return id;
+
+			id++;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int modeset_init_intf(struct mdp5_kms *mdp5_kms,
+			     struct mdp5_interface *intf)
+{
+	struct drm_device *dev = mdp5_kms->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct mdp5_ctl_manager *ctlm = mdp5_kms->ctlm;
+	struct mdp5_ctl *ctl;
+	struct drm_encoder *encoder;
+	int ret = 0;
+
+	switch (intf->type) {
+	case INTF_eDP:
+		DRM_DEV_INFO(dev->dev, "Skipping eDP interface %d\n", intf->num);
+		break;
+	case INTF_HDMI:
+		if (!priv->hdmi)
+			break;
+
+		ctl = mdp5_ctlm_request(ctlm, intf->num);
+		if (!ctl) {
+			ret = -EINVAL;
+			break;
+		}
+
+		encoder = construct_encoder(mdp5_kms, intf, ctl);
+		if (IS_ERR(encoder)) {
+			ret = PTR_ERR(encoder);
+			break;
+		}
+
+		ret = msm_hdmi_modeset_init(priv->hdmi, dev, encoder);
+		break;
+	case INTF_DSI:
+	{
+		const struct mdp5_cfg_hw *hw_cfg =
+					mdp5_cfg_get_hw_config(mdp5_kms->cfg);
+		int dsi_id = get_dsi_id_from_intf(hw_cfg, intf->num);
+
+		if ((dsi_id >= ARRAY_SIZE(priv->dsi)) || (dsi_id < 0)) {
+			DRM_DEV_ERROR(dev->dev, "failed to find dsi from intf %d\n",
+				intf->num);
+			ret = -EINVAL;
+			break;
+		}
+
+		if (!priv->dsi[dsi_id])
+			break;
+
+		ctl = mdp5_ctlm_request(ctlm, intf->num);
+		if (!ctl) {
+			ret = -EINVAL;
+			break;
+		}
+
+		encoder = construct_encoder(mdp5_kms, intf, ctl);
+		if (IS_ERR(encoder)) {
+			ret = PTR_ERR(encoder);
+			break;
+		}
+
+		ret = msm_dsi_modeset_init(priv->dsi[dsi_id], dev, encoder);
+		if (!ret)
+			mdp5_encoder_set_intf_mode(encoder, msm_dsi_is_cmd_mode(priv->dsi[dsi_id]));
+
+		break;
+	}
+	default:
+		DRM_DEV_ERROR(dev->dev, "unknown intf: %d\n", intf->type);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static int modeset_init(struct mdp5_kms *mdp5_kms)
+{
+	struct drm_device *dev = mdp5_kms->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	unsigned int num_crtcs;
+	int i, ret, pi = 0, ci = 0;
+	struct drm_plane *primary[MAX_BASES] = { NULL };
+	struct drm_plane *cursor[MAX_BASES] = { NULL };
+	struct drm_encoder *encoder;
+	unsigned int num_encoders;
+
+	/*
+	 * Construct encoders and modeset initialize connector devices
+	 * for each external display interface.
+	 */
+	for (i = 0; i < mdp5_kms->num_intfs; i++) {
+		ret = modeset_init_intf(mdp5_kms, mdp5_kms->intfs[i]);
+		if (ret)
+			goto fail;
+	}
+
+	num_encoders = 0;
+	drm_for_each_encoder(encoder, dev)
+		num_encoders++;
+
+	/*
+	 * We should ideally have less number of encoders (set up by parsing
+	 * the MDP5 interfaces) than the number of layer mixers present in HW,
+	 * but let's be safe here anyway
+	 */
+	num_crtcs = min(num_encoders, mdp5_kms->num_hwmixers);
+
+	/*
+	 * Construct planes equaling the number of hw pipes, and CRTCs for the
+	 * N encoders set up by the driver. The first N planes become primary
+	 * planes for the CRTCs, with the remainder as overlay planes:
+	 */
+	for (i = 0; i < mdp5_kms->num_hwpipes; i++) {
+		struct mdp5_hw_pipe *hwpipe = mdp5_kms->hwpipes[i];
+		struct drm_plane *plane;
+		enum drm_plane_type type;
+
+		if (i < num_crtcs)
+			type = DRM_PLANE_TYPE_PRIMARY;
+		else if (hwpipe->caps & MDP_PIPE_CAP_CURSOR)
+			type = DRM_PLANE_TYPE_CURSOR;
+		else
+			type = DRM_PLANE_TYPE_OVERLAY;
+
+		plane = mdp5_plane_init(dev, type);
+		if (IS_ERR(plane)) {
+			ret = PTR_ERR(plane);
+			DRM_DEV_ERROR(dev->dev, "failed to construct plane %d (%d)\n", i, ret);
+			goto fail;
+		}
+
+		if (type == DRM_PLANE_TYPE_PRIMARY)
+			primary[pi++] = plane;
+		if (type == DRM_PLANE_TYPE_CURSOR)
+			cursor[ci++] = plane;
+	}
+
+	for (i = 0; i < num_crtcs; i++) {
+		struct drm_crtc *crtc;
+
+		crtc  = mdp5_crtc_init(dev, primary[i], cursor[i], i);
+		if (IS_ERR(crtc)) {
+			ret = PTR_ERR(crtc);
+			DRM_DEV_ERROR(dev->dev, "failed to construct crtc %d (%d)\n", i, ret);
+			goto fail;
+		}
+		priv->num_crtcs++;
+	}
+
+	/*
+	 * Now that we know the number of crtcs we've created, set the possible
+	 * crtcs for the encoders
+	 */
+	drm_for_each_encoder(encoder, dev)
+		encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;
+
+	return 0;
+
+fail:
+	return ret;
+}
+
+static void read_mdp_hw_revision(struct mdp5_kms *mdp5_kms,
+				 u32 *major, u32 *minor)
+{
+	struct device *dev = &mdp5_kms->pdev->dev;
+	u32 version;
+
+	pm_runtime_get_sync(dev);
+	version = mdp5_read(mdp5_kms, REG_MDP5_HW_VERSION);
+	pm_runtime_put_sync(dev);
+
+	*major = FIELD(version, MDP5_HW_VERSION_MAJOR);
+	*minor = FIELD(version, MDP5_HW_VERSION_MINOR);
+
+	DRM_DEV_INFO(dev, "MDP5 version v%d.%d", *major, *minor);
+}
+
+static int get_clk(struct platform_device *pdev, struct clk **clkp,
+		const char *name, bool mandatory)
+{
+	struct device *dev = &pdev->dev;
+	struct clk *clk = msm_clk_get(pdev, name);
+	if (IS_ERR(clk) && mandatory) {
+		DRM_DEV_ERROR(dev, "failed to get %s (%ld)\n", name, PTR_ERR(clk));
+		return PTR_ERR(clk);
+	}
+	if (IS_ERR(clk))
+		DBG("skipping %s", name);
+	else
+		*clkp = clk;
+
+	return 0;
+}
+
+static int mdp5_init(struct platform_device *pdev, struct drm_device *dev);
+
+static int mdp5_kms_init(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct platform_device *pdev;
+	struct mdp5_kms *mdp5_kms;
+	struct mdp5_cfg *config;
+	struct msm_kms *kms = priv->kms;
+	struct msm_gem_address_space *aspace;
+	int i, ret;
+
+	ret = mdp5_init(to_platform_device(dev->dev), dev);
+	if (ret)
+		return ret;
+
+	mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
+
+	pdev = mdp5_kms->pdev;
+
+	ret = mdp_kms_init(&mdp5_kms->base, &kms_funcs);
+	if (ret) {
+		DRM_DEV_ERROR(&pdev->dev, "failed to init kms\n");
+		goto fail;
+	}
+
+	config = mdp5_cfg_get_config(mdp5_kms->cfg);
+
+	/* make sure things are off before attaching iommu (bootloader could
+	 * have left things on, in which case we'll start getting faults if
+	 * we don't disable):
+	 */
+	pm_runtime_get_sync(&pdev->dev);
+	for (i = 0; i < MDP5_INTF_NUM_MAX; i++) {
+		if (mdp5_cfg_intf_is_virtual(config->hw->intf.connect[i]) ||
+		    !config->hw->intf.base[i])
+			continue;
+		mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(i), 0);
+
+		mdp5_write(mdp5_kms, REG_MDP5_INTF_FRAME_LINE_COUNT_EN(i), 0x3);
+	}
+	mdelay(16);
+
+	aspace = msm_kms_init_aspace(mdp5_kms->dev);
+	if (IS_ERR(aspace)) {
+		ret = PTR_ERR(aspace);
+		goto fail;
+	}
+
+	kms->aspace = aspace;
+
+	pm_runtime_put_sync(&pdev->dev);
+
+	ret = modeset_init(mdp5_kms);
+	if (ret) {
+		DRM_DEV_ERROR(&pdev->dev, "modeset_init failed: %d\n", ret);
+		goto fail;
+	}
+
+	dev->mode_config.min_width = 0;
+	dev->mode_config.min_height = 0;
+	dev->mode_config.max_width = 0xffff;
+	dev->mode_config.max_height = 0xffff;
+
+	dev->max_vblank_count = 0; /* max_vblank_count is set on each CRTC */
+	dev->vblank_disable_immediate = true;
+
+	return 0;
+fail:
+	if (kms)
+		mdp5_kms_destroy(kms);
+
+	return ret;
+}
+
+static void mdp5_destroy(struct mdp5_kms *mdp5_kms)
+{
+	if (mdp5_kms->rpm_enabled)
+		pm_runtime_disable(&mdp5_kms->pdev->dev);
+
+	drm_atomic_private_obj_fini(&mdp5_kms->glob_state);
+	drm_modeset_lock_fini(&mdp5_kms->glob_state_lock);
+}
+
+static int construct_pipes(struct mdp5_kms *mdp5_kms, int cnt,
+		const enum mdp5_pipe *pipes, const uint32_t *offsets,
+		uint32_t caps)
+{
+	struct drm_device *dev = mdp5_kms->dev;
+	int i, ret;
+
+	for (i = 0; i < cnt; i++) {
+		struct mdp5_hw_pipe *hwpipe;
+
+		hwpipe = mdp5_pipe_init(dev, pipes[i], offsets[i], caps);
+		if (IS_ERR(hwpipe)) {
+			ret = PTR_ERR(hwpipe);
+			DRM_DEV_ERROR(dev->dev, "failed to construct pipe for %s (%d)\n",
+					pipe2name(pipes[i]), ret);
+			return ret;
+		}
+		hwpipe->idx = mdp5_kms->num_hwpipes;
+		mdp5_kms->hwpipes[mdp5_kms->num_hwpipes++] = hwpipe;
+	}
+
+	return 0;
+}
+
+static int hwpipe_init(struct mdp5_kms *mdp5_kms)
+{
+	static const enum mdp5_pipe rgb_planes[] = {
+			SSPP_RGB0, SSPP_RGB1, SSPP_RGB2, SSPP_RGB3,
+	};
+	static const enum mdp5_pipe vig_planes[] = {
+			SSPP_VIG0, SSPP_VIG1, SSPP_VIG2, SSPP_VIG3,
+	};
+	static const enum mdp5_pipe dma_planes[] = {
+			SSPP_DMA0, SSPP_DMA1,
+	};
+	static const enum mdp5_pipe cursor_planes[] = {
+			SSPP_CURSOR0, SSPP_CURSOR1,
+	};
+	const struct mdp5_cfg_hw *hw_cfg;
+	int ret;
+
+	hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
+
+	/* Construct RGB pipes: */
+	ret = construct_pipes(mdp5_kms, hw_cfg->pipe_rgb.count, rgb_planes,
+			hw_cfg->pipe_rgb.base, hw_cfg->pipe_rgb.caps);
+	if (ret)
+		return ret;
+
+	/* Construct video (VIG) pipes: */
+	ret = construct_pipes(mdp5_kms, hw_cfg->pipe_vig.count, vig_planes,
+			hw_cfg->pipe_vig.base, hw_cfg->pipe_vig.caps);
+	if (ret)
+		return ret;
+
+	/* Construct DMA pipes: */
+	ret = construct_pipes(mdp5_kms, hw_cfg->pipe_dma.count, dma_planes,
+			hw_cfg->pipe_dma.base, hw_cfg->pipe_dma.caps);
+	if (ret)
+		return ret;
+
+	/* Construct cursor pipes: */
+	ret = construct_pipes(mdp5_kms, hw_cfg->pipe_cursor.count,
+			cursor_planes, hw_cfg->pipe_cursor.base,
+			hw_cfg->pipe_cursor.caps);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static int hwmixer_init(struct mdp5_kms *mdp5_kms)
+{
+	struct drm_device *dev = mdp5_kms->dev;
+	const struct mdp5_cfg_hw *hw_cfg;
+	int i, ret;
+
+	hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
+
+	for (i = 0; i < hw_cfg->lm.count; i++) {
+		struct mdp5_hw_mixer *mixer;
+
+		mixer = mdp5_mixer_init(dev, &hw_cfg->lm.instances[i]);
+		if (IS_ERR(mixer)) {
+			ret = PTR_ERR(mixer);
+			DRM_DEV_ERROR(dev->dev, "failed to construct LM%d (%d)\n",
+				i, ret);
+			return ret;
+		}
+
+		mixer->idx = mdp5_kms->num_hwmixers;
+		mdp5_kms->hwmixers[mdp5_kms->num_hwmixers++] = mixer;
+	}
+
+	return 0;
+}
+
+static int interface_init(struct mdp5_kms *mdp5_kms)
+{
+	struct drm_device *dev = mdp5_kms->dev;
+	const struct mdp5_cfg_hw *hw_cfg;
+	const enum mdp5_intf_type *intf_types;
+	int i;
+
+	hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
+	intf_types = hw_cfg->intf.connect;
+
+	for (i = 0; i < ARRAY_SIZE(hw_cfg->intf.connect); i++) {
+		struct mdp5_interface *intf;
+
+		if (intf_types[i] == INTF_DISABLED)
+			continue;
+
+		intf = devm_kzalloc(dev->dev, sizeof(*intf), GFP_KERNEL);
+		if (!intf) {
+			DRM_DEV_ERROR(dev->dev, "failed to construct INTF%d\n", i);
+			return -ENOMEM;
+		}
+
+		intf->num = i;
+		intf->type = intf_types[i];
+		intf->mode = MDP5_INTF_MODE_NONE;
+		intf->idx = mdp5_kms->num_intfs;
+		mdp5_kms->intfs[mdp5_kms->num_intfs++] = intf;
+	}
+
+	return 0;
+}
+
+static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+	struct mdp5_cfg *config;
+	u32 major, minor;
+	int ret;
+
+	mdp5_kms->dev = dev;
+
+	ret = mdp5_global_obj_init(mdp5_kms);
+	if (ret)
+		goto fail;
+
+	/* we need to set a default rate before enabling.  Set a safe
+	 * rate first, then figure out hw revision, and then set a
+	 * more optimal rate:
+	 */
+	clk_set_rate(mdp5_kms->core_clk, 200000000);
+
+	pm_runtime_enable(&pdev->dev);
+	mdp5_kms->rpm_enabled = true;
+
+	read_mdp_hw_revision(mdp5_kms, &major, &minor);
+
+	mdp5_kms->cfg = mdp5_cfg_init(mdp5_kms, major, minor);
+	if (IS_ERR(mdp5_kms->cfg)) {
+		ret = PTR_ERR(mdp5_kms->cfg);
+		mdp5_kms->cfg = NULL;
+		goto fail;
+	}
+
+	config = mdp5_cfg_get_config(mdp5_kms->cfg);
+	mdp5_kms->caps = config->hw->mdp.caps;
+
+	/* TODO: compute core clock rate at runtime */
+	clk_set_rate(mdp5_kms->core_clk, config->hw->max_clk);
+
+	/*
+	 * Some chipsets have a Shared Memory Pool (SMP), while others
+	 * have dedicated latency buffering per source pipe instead;
+	 * this section initializes the SMP:
+	 */
+	if (mdp5_kms->caps & MDP_CAP_SMP) {
+		mdp5_kms->smp = mdp5_smp_init(mdp5_kms, &config->hw->smp);
+		if (IS_ERR(mdp5_kms->smp)) {
+			ret = PTR_ERR(mdp5_kms->smp);
+			mdp5_kms->smp = NULL;
+			goto fail;
+		}
+	}
+
+	mdp5_kms->ctlm = mdp5_ctlm_init(dev, mdp5_kms->mmio, mdp5_kms->cfg);
+	if (IS_ERR(mdp5_kms->ctlm)) {
+		ret = PTR_ERR(mdp5_kms->ctlm);
+		mdp5_kms->ctlm = NULL;
+		goto fail;
+	}
+
+	ret = hwpipe_init(mdp5_kms);
+	if (ret)
+		goto fail;
+
+	ret = hwmixer_init(mdp5_kms);
+	if (ret)
+		goto fail;
+
+	ret = interface_init(mdp5_kms);
+	if (ret)
+		goto fail;
+
+	return 0;
+fail:
+	mdp5_destroy(mdp5_kms);
+	return ret;
+}
+
+static int mdp5_setup_interconnect(struct platform_device *pdev)
+{
+	struct icc_path *path0 = msm_icc_get(&pdev->dev, "mdp0-mem");
+	struct icc_path *path1 = msm_icc_get(&pdev->dev, "mdp1-mem");
+	struct icc_path *path_rot = msm_icc_get(&pdev->dev, "rotator-mem");
+
+	if (IS_ERR(path0))
+		return PTR_ERR(path0);
+
+	if (!path0) {
+		/* no interconnect support is not necessarily a fatal
+		 * condition, the platform may simply not have an
+		 * interconnect driver yet.  But warn about it in case
+		 * bootloader didn't setup bus clocks high enough for
+		 * scanout.
+		 */
+		dev_warn(&pdev->dev, "No interconnect support may cause display underflows!\n");
+		return 0;
+	}
+
+	icc_set_bw(path0, 0, MBps_to_icc(6400));
+
+	if (!IS_ERR_OR_NULL(path1))
+		icc_set_bw(path1, 0, MBps_to_icc(6400));
+	if (!IS_ERR_OR_NULL(path_rot))
+		icc_set_bw(path_rot, 0, MBps_to_icc(6400));
+
+	return 0;
+}
+
+static int mdp5_dev_probe(struct platform_device *pdev)
+{
+	struct mdp5_kms *mdp5_kms;
+	int ret, irq;
+
+	DBG("");
+
+	mdp5_kms = devm_kzalloc(&pdev->dev, sizeof(*mdp5_kms), GFP_KERNEL);
+	if (!mdp5_kms)
+		return -ENOMEM;
+
+	ret = mdp5_setup_interconnect(pdev);
+	if (ret)
+		return ret;
+
+	mdp5_kms->pdev = pdev;
+
+	spin_lock_init(&mdp5_kms->resource_lock);
+
+	mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys");
+	if (IS_ERR(mdp5_kms->mmio))
+		return PTR_ERR(mdp5_kms->mmio);
+
+	/* mandatory clocks: */
+	ret = get_clk(pdev, &mdp5_kms->axi_clk, "bus", true);
+	if (ret)
+		return ret;
+	ret = get_clk(pdev, &mdp5_kms->ahb_clk, "iface", true);
+	if (ret)
+		return ret;
+	ret = get_clk(pdev, &mdp5_kms->core_clk, "core", true);
+	if (ret)
+		return ret;
+	ret = get_clk(pdev, &mdp5_kms->vsync_clk, "vsync", true);
+	if (ret)
+		return ret;
+
+	/* optional clocks: */
+	get_clk(pdev, &mdp5_kms->lut_clk, "lut", false);
+	get_clk(pdev, &mdp5_kms->tbu_clk, "tbu", false);
+	get_clk(pdev, &mdp5_kms->tbu_rt_clk, "tbu_rt", false);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return dev_err_probe(&pdev->dev, irq, "failed to get irq\n");
+
+	mdp5_kms->base.base.irq = irq;
+
+	return msm_drv_probe(&pdev->dev, mdp5_kms_init, &mdp5_kms->base.base);
+}
+
+static void mdp5_dev_remove(struct platform_device *pdev)
+{
+	DBG("");
+	component_master_del(&pdev->dev, &msm_drm_ops);
+}
+
+static __maybe_unused int mdp5_runtime_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct msm_drm_private *priv = platform_get_drvdata(pdev);
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+
+	DBG("");
+
+	return mdp5_disable(mdp5_kms);
+}
+
+static __maybe_unused int mdp5_runtime_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct msm_drm_private *priv = platform_get_drvdata(pdev);
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+
+	DBG("");
+
+	return mdp5_enable(mdp5_kms);
+}
+
+static const struct dev_pm_ops mdp5_pm_ops = {
+	SET_RUNTIME_PM_OPS(mdp5_runtime_suspend, mdp5_runtime_resume, NULL)
+	.prepare = msm_kms_pm_prepare,
+	.complete = msm_kms_pm_complete,
+};
+
+static const struct of_device_id mdp5_dt_match[] = {
+	{ .compatible = "qcom,mdp5", },
+	/* to support downstream DT files */
+	{ .compatible = "qcom,mdss_mdp", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, mdp5_dt_match);
+
+static struct platform_driver mdp5_driver = {
+	.probe = mdp5_dev_probe,
+	.remove_new = mdp5_dev_remove,
+	.shutdown = msm_kms_shutdown,
+	.driver = {
+		.name = "msm_mdp",
+		.of_match_table = mdp5_dt_match,
+		.pm = &mdp5_pm_ops,
+	},
+};
+
+void __init msm_mdp_register(void)
+{
+	DBG("");
+	platform_driver_register(&mdp5_driver);
+}
+
+void __exit msm_mdp_unregister(void)
+{
+	DBG("");
+	platform_driver_unregister(&mdp5_driver);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_kms.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_kms.h
@@ -0,0 +1,327 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __MDP5_KMS_H__
+#define __MDP5_KMS_H__
+
+#include "msm_drv.h"
+#include "msm_kms.h"
+#include "disp/mdp_kms.h"
+#include "mdp5_cfg.h"	/* must be included before mdp5.xml.h */
+#include "mdp5.xml.h"
+#include "mdp5_pipe.h"
+#include "mdp5_mixer.h"
+#include "mdp5_ctl.h"
+#include "mdp5_smp.h"
+
+struct mdp5_kms {
+	struct mdp_kms base;
+
+	struct drm_device *dev;
+
+	struct platform_device *pdev;
+
+	unsigned num_hwpipes;
+	struct mdp5_hw_pipe *hwpipes[SSPP_MAX];
+
+	unsigned num_hwmixers;
+	struct mdp5_hw_mixer *hwmixers[8];
+
+	unsigned num_intfs;
+	struct mdp5_interface *intfs[5];
+
+	struct mdp5_cfg_handler *cfg;
+	uint32_t caps;	/* MDP capabilities (MDP_CAP_XXX bits) */
+
+	/*
+	 * Global private object state, Do not access directly, use
+	 * mdp5_global_get_state()
+	 */
+	struct drm_modeset_lock glob_state_lock;
+	struct drm_private_obj glob_state;
+
+	struct mdp5_smp *smp;
+	struct mdp5_ctl_manager *ctlm;
+
+	/* io/register spaces: */
+	void __iomem *mmio;
+
+	struct clk *axi_clk;
+	struct clk *ahb_clk;
+	struct clk *core_clk;
+	struct clk *lut_clk;
+	struct clk *tbu_clk;
+	struct clk *tbu_rt_clk;
+	struct clk *vsync_clk;
+
+	/*
+	 * lock to protect access to global resources: ie., following register:
+	 *	- REG_MDP5_DISP_INTF_SEL
+	 */
+	spinlock_t resource_lock;
+
+	bool rpm_enabled;
+
+	struct mdp_irq error_handler;
+
+	int enable_count;
+};
+#define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base)
+
+/* Global private object state for tracking resources that are shared across
+ * multiple kms objects (planes/crtcs/etc).
+ */
+#define to_mdp5_global_state(x) container_of(x, struct mdp5_global_state, base)
+struct mdp5_global_state {
+	struct drm_private_state base;
+
+	struct drm_atomic_state *state;
+	struct mdp5_kms *mdp5_kms;
+
+	struct mdp5_hw_pipe_state hwpipe;
+	struct mdp5_hw_mixer_state hwmixer;
+	struct mdp5_smp_state smp;
+};
+
+struct mdp5_global_state * mdp5_get_existing_global_state(struct mdp5_kms *mdp5_kms);
+struct mdp5_global_state *__must_check mdp5_get_global_state(struct drm_atomic_state *s);
+
+/* Atomic plane state.  Subclasses the base drm_plane_state in order to
+ * track assigned hwpipe and hw specific state.
+ */
+struct mdp5_plane_state {
+	struct drm_plane_state base;
+
+	struct mdp5_hw_pipe *hwpipe;
+	struct mdp5_hw_pipe *r_hwpipe;	/* right hwpipe */
+
+	/* assigned by crtc blender */
+	enum mdp_mixer_stage_id stage;
+
+	/* whether attached CRTC needs pixel data explicitly flushed to
+	 * display (ex. DSI command mode display)
+	 */
+	bool needs_dirtyfb;
+};
+#define to_mdp5_plane_state(x) \
+		container_of(x, struct mdp5_plane_state, base)
+
+struct mdp5_pipeline {
+	struct mdp5_interface *intf;
+	struct mdp5_hw_mixer *mixer;
+	struct mdp5_hw_mixer *r_mixer;	/* right mixer */
+};
+
+struct mdp5_crtc_state {
+	struct drm_crtc_state base;
+
+	struct mdp5_ctl *ctl;
+	struct mdp5_pipeline pipeline;
+
+	/* these are derivatives of intf/mixer state in mdp5_pipeline */
+	u32 vblank_irqmask;
+	u32 err_irqmask;
+	u32 pp_done_irqmask;
+
+	bool cmd_mode;
+
+	/* should we not write CTL[n].START register on flush?  If the
+	 * encoder has changed this is set to true, since encoder->enable()
+	 * is called after crtc state is committed, but we only want to
+	 * write the CTL[n].START register once.  This lets us defer
+	 * writing CTL[n].START until encoder->enable()
+	 */
+	bool defer_start;
+};
+#define to_mdp5_crtc_state(x) \
+		container_of(x, struct mdp5_crtc_state, base)
+
+enum mdp5_intf_mode {
+	MDP5_INTF_MODE_NONE = 0,
+
+	/* Modes used for DSI interface (INTF_DSI type): */
+	MDP5_INTF_DSI_MODE_VIDEO,
+	MDP5_INTF_DSI_MODE_COMMAND,
+
+	/* Modes used for WB interface (INTF_WB type):  */
+	MDP5_INTF_WB_MODE_BLOCK,
+	MDP5_INTF_WB_MODE_LINE,
+};
+
+struct mdp5_interface {
+	int idx;
+	int num; /* display interface number */
+	enum mdp5_intf_type type;
+	enum mdp5_intf_mode mode;
+};
+
+struct mdp5_encoder {
+	struct drm_encoder base;
+	spinlock_t intf_lock;	/* protect REG_MDP5_INTF_* registers */
+	bool enabled;
+	uint32_t bsc;
+
+	struct mdp5_interface *intf;
+	struct mdp5_ctl *ctl;
+};
+#define to_mdp5_encoder(x) container_of(x, struct mdp5_encoder, base)
+
+static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data)
+{
+	WARN_ON(mdp5_kms->enable_count <= 0);
+	msm_writel(data, mdp5_kms->mmio + reg);
+}
+
+static inline u32 mdp5_read(struct mdp5_kms *mdp5_kms, u32 reg)
+{
+	WARN_ON(mdp5_kms->enable_count <= 0);
+	return msm_readl(mdp5_kms->mmio + reg);
+}
+
+static inline const char *stage2name(enum mdp_mixer_stage_id stage)
+{
+	static const char *names[] = {
+#define NAME(n) [n] = #n
+		NAME(STAGE_UNUSED), NAME(STAGE_BASE),
+		NAME(STAGE0), NAME(STAGE1), NAME(STAGE2),
+		NAME(STAGE3), NAME(STAGE4), NAME(STAGE6),
+#undef NAME
+	};
+	return names[stage];
+}
+
+static inline const char *pipe2name(enum mdp5_pipe pipe)
+{
+	static const char *names[] = {
+#define NAME(n) [SSPP_ ## n] = #n
+		NAME(VIG0), NAME(VIG1), NAME(VIG2),
+		NAME(RGB0), NAME(RGB1), NAME(RGB2),
+		NAME(DMA0), NAME(DMA1),
+		NAME(VIG3), NAME(RGB3),
+		NAME(CURSOR0), NAME(CURSOR1),
+#undef NAME
+	};
+	return names[pipe];
+}
+
+static inline int pipe2nclients(enum mdp5_pipe pipe)
+{
+	switch (pipe) {
+	case SSPP_RGB0:
+	case SSPP_RGB1:
+	case SSPP_RGB2:
+	case SSPP_RGB3:
+		return 1;
+	default:
+		return 3;
+	}
+}
+
+static inline uint32_t intf2err(int intf_num)
+{
+	switch (intf_num) {
+	case 0:  return MDP5_IRQ_INTF0_UNDER_RUN;
+	case 1:  return MDP5_IRQ_INTF1_UNDER_RUN;
+	case 2:  return MDP5_IRQ_INTF2_UNDER_RUN;
+	case 3:  return MDP5_IRQ_INTF3_UNDER_RUN;
+	default: return 0;
+	}
+}
+
+static inline uint32_t intf2vblank(struct mdp5_hw_mixer *mixer,
+				   struct mdp5_interface *intf)
+{
+	/*
+	 * In case of DSI Command Mode, the Ping Pong's read pointer IRQ
+	 * acts as a Vblank signal. The Ping Pong buffer used is bound to
+	 * layer mixer.
+	 */
+
+	if ((intf->type == INTF_DSI) &&
+			(intf->mode == MDP5_INTF_DSI_MODE_COMMAND))
+		return MDP5_IRQ_PING_PONG_0_RD_PTR << mixer->pp;
+
+	if (intf->type == INTF_WB)
+		return MDP5_IRQ_WB_2_DONE;
+
+	switch (intf->num) {
+	case 0:  return MDP5_IRQ_INTF0_VSYNC;
+	case 1:  return MDP5_IRQ_INTF1_VSYNC;
+	case 2:  return MDP5_IRQ_INTF2_VSYNC;
+	case 3:  return MDP5_IRQ_INTF3_VSYNC;
+	default: return 0;
+	}
+}
+
+static inline uint32_t lm2ppdone(struct mdp5_hw_mixer *mixer)
+{
+	return MDP5_IRQ_PING_PONG_0_DONE << mixer->pp;
+}
+
+void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
+		uint32_t old_irqmask);
+void mdp5_irq_preinstall(struct msm_kms *kms);
+int mdp5_irq_postinstall(struct msm_kms *kms);
+void mdp5_irq_uninstall(struct msm_kms *kms);
+irqreturn_t mdp5_irq(struct msm_kms *kms);
+int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
+void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
+int mdp5_irq_domain_init(struct mdp5_kms *mdp5_kms);
+void mdp5_irq_domain_fini(struct mdp5_kms *mdp5_kms);
+
+uint32_t mdp5_plane_get_flush(struct drm_plane *plane);
+enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane);
+enum mdp5_pipe mdp5_plane_right_pipe(struct drm_plane *plane);
+struct drm_plane *mdp5_plane_init(struct drm_device *dev,
+				  enum drm_plane_type type);
+
+struct mdp5_ctl *mdp5_crtc_get_ctl(struct drm_crtc *crtc);
+uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc);
+
+struct mdp5_hw_mixer *mdp5_crtc_get_mixer(struct drm_crtc *crtc);
+struct mdp5_pipeline *mdp5_crtc_get_pipeline(struct drm_crtc *crtc);
+void mdp5_crtc_set_pipeline(struct drm_crtc *crtc);
+void mdp5_crtc_wait_for_commit_done(struct drm_crtc *crtc);
+struct drm_crtc *mdp5_crtc_init(struct drm_device *dev,
+				struct drm_plane *plane,
+				struct drm_plane *cursor_plane, int id);
+
+struct drm_encoder *mdp5_encoder_init(struct drm_device *dev,
+		struct mdp5_interface *intf, struct mdp5_ctl *ctl);
+int mdp5_vid_encoder_set_split_display(struct drm_encoder *encoder,
+				       struct drm_encoder *slave_encoder);
+void mdp5_encoder_set_intf_mode(struct drm_encoder *encoder, bool cmd_mode);
+int mdp5_encoder_get_linecount(struct drm_encoder *encoder);
+u32 mdp5_encoder_get_framecount(struct drm_encoder *encoder);
+
+#ifdef CONFIG_DRM_MSM_DSI
+void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode);
+void mdp5_cmd_encoder_disable(struct drm_encoder *encoder);
+void mdp5_cmd_encoder_enable(struct drm_encoder *encoder);
+int mdp5_cmd_encoder_set_split_display(struct drm_encoder *encoder,
+				       struct drm_encoder *slave_encoder);
+#else
+static inline void mdp5_cmd_encoder_mode_set(struct drm_encoder *encoder,
+					     struct drm_display_mode *mode,
+					     struct drm_display_mode *adjusted_mode)
+{
+}
+static inline void mdp5_cmd_encoder_disable(struct drm_encoder *encoder)
+{
+}
+static inline void mdp5_cmd_encoder_enable(struct drm_encoder *encoder)
+{
+}
+static inline int mdp5_cmd_encoder_set_split_display(
+	struct drm_encoder *encoder, struct drm_encoder *slave_encoder)
+{
+	return -EINVAL;
+}
+#endif
+
+#endif /* __MDP5_KMS_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_mixer.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_mixer.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2017 The Linux Foundation. All rights reserved.
+ */
+
+#include "mdp5_kms.h"
+
+/*
+ * As of now, there are only 2 combinations possible for source split:
+ *
+ * Left | Right
+ * -----|------
+ *  LM0 | LM1
+ *  LM2 | LM5
+ *
+ */
+static int lm_right_pair[] = { 1, -1, 5, -1, -1, -1 };
+
+static int get_right_pair_idx(struct mdp5_kms *mdp5_kms, int lm)
+{
+	int i;
+	int pair_lm;
+
+	pair_lm = lm_right_pair[lm];
+	if (pair_lm < 0)
+		return -EINVAL;
+
+	for (i = 0; i < mdp5_kms->num_hwmixers; i++) {
+		struct mdp5_hw_mixer *mixer = mdp5_kms->hwmixers[i];
+
+		if (mixer->lm == pair_lm)
+			return mixer->idx;
+	}
+
+	return -1;
+}
+
+int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc,
+		      uint32_t caps, struct mdp5_hw_mixer **mixer,
+		      struct mdp5_hw_mixer **r_mixer)
+{
+	struct msm_drm_private *priv = s->dev->dev_private;
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+	struct mdp5_global_state *global_state = mdp5_get_global_state(s);
+	struct mdp5_hw_mixer_state *new_state;
+	int i;
+
+	if (IS_ERR(global_state))
+		return PTR_ERR(global_state);
+
+	new_state = &global_state->hwmixer;
+
+	for (i = 0; i < mdp5_kms->num_hwmixers; i++) {
+		struct mdp5_hw_mixer *cur = mdp5_kms->hwmixers[i];
+
+		/*
+		 * skip if already in-use by a different CRTC. If there is a
+		 * mixer already assigned to this CRTC, it means this call is
+		 * a request to get an additional right mixer. Assume that the
+		 * existing mixer is the 'left' one, and try to see if we can
+		 * get its corresponding 'right' pair.
+		 */
+		if (new_state->hwmixer_to_crtc[cur->idx] &&
+		    new_state->hwmixer_to_crtc[cur->idx] != crtc)
+			continue;
+
+		/* skip if doesn't support some required caps: */
+		if (caps & ~cur->caps)
+			continue;
+
+		if (r_mixer) {
+			int pair_idx;
+
+			pair_idx = get_right_pair_idx(mdp5_kms, cur->lm);
+			if (pair_idx < 0)
+				return -EINVAL;
+
+			if (new_state->hwmixer_to_crtc[pair_idx])
+				continue;
+
+			*r_mixer = mdp5_kms->hwmixers[pair_idx];
+		}
+
+		/*
+		 * prefer a pair-able LM over an unpairable one. We can
+		 * switch the CRTC from Normal mode to Source Split mode
+		 * without requiring a full modeset if we had already
+		 * assigned this CRTC a pair-able LM.
+		 *
+		 * TODO: There will be assignment sequences which would
+		 * result in the CRTC requiring a full modeset, even
+		 * if we have the LM resources to prevent it. For a platform
+		 * with a few displays, we don't run out of pair-able LMs
+		 * so easily. For now, ignore the possibility of requiring
+		 * a full modeset.
+		 */
+		if (!(*mixer) || cur->caps & MDP_LM_CAP_PAIR)
+			*mixer = cur;
+	}
+
+	if (!(*mixer))
+		return -ENOMEM;
+
+	if (r_mixer && !(*r_mixer))
+		return -ENOMEM;
+
+	DBG("assigning Layer Mixer %d to crtc %s", (*mixer)->lm, crtc->name);
+
+	new_state->hwmixer_to_crtc[(*mixer)->idx] = crtc;
+	if (r_mixer) {
+		DBG("assigning Right Layer Mixer %d to crtc %s", (*r_mixer)->lm,
+		    crtc->name);
+		new_state->hwmixer_to_crtc[(*r_mixer)->idx] = crtc;
+	}
+
+	return 0;
+}
+
+int mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer *mixer)
+{
+	struct mdp5_global_state *global_state = mdp5_get_global_state(s);
+	struct mdp5_hw_mixer_state *new_state;
+
+	if (!mixer)
+		return 0;
+
+	if (IS_ERR(global_state))
+		return PTR_ERR(global_state);
+
+	new_state = &global_state->hwmixer;
+
+	if (WARN_ON(!new_state->hwmixer_to_crtc[mixer->idx]))
+		return -EINVAL;
+
+	DBG("%s: release from crtc %s", mixer->name,
+	    new_state->hwmixer_to_crtc[mixer->idx]->name);
+
+	new_state->hwmixer_to_crtc[mixer->idx] = NULL;
+
+	return 0;
+}
+
+static const char * const mixer_names[] = {
+	"LM0", "LM1", "LM2", "LM3", "LM4", "LM5",
+};
+
+struct mdp5_hw_mixer *mdp5_mixer_init(struct drm_device *dev,
+				      const struct mdp5_lm_instance *lm)
+{
+	struct mdp5_hw_mixer *mixer;
+
+	mixer = devm_kzalloc(dev->dev, sizeof(*mixer), GFP_KERNEL);
+	if (!mixer)
+		return ERR_PTR(-ENOMEM);
+
+	mixer->name = mixer_names[lm->id];
+	mixer->lm = lm->id;
+	mixer->caps = lm->caps;
+	mixer->pp = lm->pp;
+	mixer->dspp = lm->dspp;
+	mixer->flush_mask = mdp_ctl_flush_mask_lm(lm->id);
+
+	return mixer;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_mixer.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_mixer.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2017 The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __MDP5_LM_H__
+#define __MDP5_LM_H__
+
+/* represents a hw Layer Mixer, one (or more) is dynamically assigned to a crtc */
+struct mdp5_hw_mixer {
+	int idx;
+
+	const char *name;
+
+	int lm;			/* the LM instance # */
+	uint32_t caps;
+	int pp;
+	int dspp;
+
+	uint32_t flush_mask;      /* used to commit LM registers */
+};
+
+/* global atomic state of assignment between CRTCs and Layer Mixers: */
+struct mdp5_hw_mixer_state {
+	struct drm_crtc *hwmixer_to_crtc[8];
+};
+
+struct mdp5_hw_mixer *mdp5_mixer_init(struct drm_device *dev,
+				      const struct mdp5_lm_instance *lm);
+int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc,
+		      uint32_t caps, struct mdp5_hw_mixer **mixer,
+		      struct mdp5_hw_mixer **r_mixer);
+int mdp5_mixer_release(struct drm_atomic_state *s,
+		       struct mdp5_hw_mixer *mixer);
+
+#endif /* __MDP5_LM_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_pipe.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_pipe.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2016 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include "mdp5_kms.h"
+
+int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane,
+		     uint32_t caps, uint32_t blkcfg,
+		     struct mdp5_hw_pipe **hwpipe,
+		     struct mdp5_hw_pipe **r_hwpipe)
+{
+	struct msm_drm_private *priv = s->dev->dev_private;
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+	struct mdp5_global_state *new_global_state, *old_global_state;
+	struct mdp5_hw_pipe_state *old_state, *new_state;
+	int i, j;
+
+	new_global_state = mdp5_get_global_state(s);
+	if (IS_ERR(new_global_state))
+		return PTR_ERR(new_global_state);
+
+	/* grab old_state after mdp5_get_global_state(), since now we hold lock: */
+	old_global_state = mdp5_get_existing_global_state(mdp5_kms);
+
+	old_state = &old_global_state->hwpipe;
+	new_state = &new_global_state->hwpipe;
+
+	for (i = 0; i < mdp5_kms->num_hwpipes; i++) {
+		struct mdp5_hw_pipe *cur = mdp5_kms->hwpipes[i];
+
+		/* skip if already in-use.. check both new and old state,
+		 * since we cannot immediately re-use a pipe that is
+		 * released in the current update in some cases:
+		 *  (1) mdp5 can have SMP (non-double-buffered)
+		 *  (2) hw pipe previously assigned to different CRTC
+		 *      (vblanks might not be aligned)
+		 */
+		if (new_state->hwpipe_to_plane[cur->idx] ||
+				old_state->hwpipe_to_plane[cur->idx])
+			continue;
+
+		/* skip if doesn't support some required caps: */
+		if (caps & ~cur->caps)
+			continue;
+
+		/*
+		 * don't assign a cursor pipe to a plane that isn't going to
+		 * be used as a cursor
+		 */
+		if (cur->caps & MDP_PIPE_CAP_CURSOR &&
+				plane->type != DRM_PLANE_TYPE_CURSOR)
+			continue;
+
+		/* possible candidate, take the one with the
+		 * fewest unneeded caps bits set:
+		 */
+		if (!(*hwpipe) || (hweight_long(cur->caps & ~caps) <
+				   hweight_long((*hwpipe)->caps & ~caps))) {
+			bool r_found = false;
+
+			if (r_hwpipe) {
+				for (j = i + 1; j < mdp5_kms->num_hwpipes;
+				     j++) {
+					struct mdp5_hw_pipe *r_cur =
+							mdp5_kms->hwpipes[j];
+
+					/* reject different types of hwpipes */
+					if (r_cur->caps != cur->caps)
+						continue;
+
+					/* respect priority, eg. VIG0 > VIG1 */
+					if (cur->pipe > r_cur->pipe)
+						continue;
+
+					*r_hwpipe = r_cur;
+					r_found = true;
+					break;
+				}
+			}
+
+			if (!r_hwpipe || r_found)
+				*hwpipe = cur;
+		}
+	}
+
+	if (!(*hwpipe))
+		return -ENOMEM;
+
+	if (r_hwpipe && !(*r_hwpipe))
+		return -ENOMEM;
+
+	if (mdp5_kms->smp) {
+		int ret;
+
+		/* We don't support SMP and 2 hwpipes/plane together */
+		WARN_ON(r_hwpipe);
+
+		DBG("%s: alloc SMP blocks", (*hwpipe)->name);
+		ret = mdp5_smp_assign(mdp5_kms->smp, &new_global_state->smp,
+				(*hwpipe)->pipe, blkcfg);
+		if (ret)
+			return -ENOMEM;
+
+		(*hwpipe)->blkcfg = blkcfg;
+	}
+
+	DBG("%s: assign to plane %s for caps %x",
+			(*hwpipe)->name, plane->name, caps);
+	new_state->hwpipe_to_plane[(*hwpipe)->idx] = plane;
+
+	if (r_hwpipe) {
+		DBG("%s: assign to right of plane %s for caps %x",
+		    (*r_hwpipe)->name, plane->name, caps);
+		new_state->hwpipe_to_plane[(*r_hwpipe)->idx] = plane;
+	}
+
+	return 0;
+}
+
+int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe)
+{
+	struct msm_drm_private *priv = s->dev->dev_private;
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+	struct mdp5_global_state *state;
+	struct mdp5_hw_pipe_state *new_state;
+
+	if (!hwpipe)
+		return 0;
+
+	state = mdp5_get_global_state(s);
+	if (IS_ERR(state))
+		return PTR_ERR(state);
+
+	new_state = &state->hwpipe;
+
+	if (WARN_ON(!new_state->hwpipe_to_plane[hwpipe->idx]))
+		return -EINVAL;
+
+	DBG("%s: release from plane %s", hwpipe->name,
+		new_state->hwpipe_to_plane[hwpipe->idx]->name);
+
+	if (mdp5_kms->smp) {
+		DBG("%s: free SMP blocks", hwpipe->name);
+		mdp5_smp_release(mdp5_kms->smp, &state->smp, hwpipe->pipe);
+	}
+
+	new_state->hwpipe_to_plane[hwpipe->idx] = NULL;
+
+	return 0;
+}
+
+struct mdp5_hw_pipe *mdp5_pipe_init(struct drm_device *dev,
+		enum mdp5_pipe pipe,
+		uint32_t reg_offset, uint32_t caps)
+{
+	struct mdp5_hw_pipe *hwpipe;
+
+	hwpipe = devm_kzalloc(dev->dev, sizeof(*hwpipe), GFP_KERNEL);
+	if (!hwpipe)
+		return ERR_PTR(-ENOMEM);
+
+	hwpipe->name = pipe2name(pipe);
+	hwpipe->pipe = pipe;
+	hwpipe->reg_offset = reg_offset;
+	hwpipe->caps = caps;
+	hwpipe->flush_mask = mdp_ctl_flush_mask_pipe(pipe);
+
+	return hwpipe;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_pipe.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_pipe.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2016 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __MDP5_PIPE_H__
+#define __MDP5_PIPE_H__
+
+/* TODO: Add SSPP_MAX in mdp5.xml.h */
+#define SSPP_MAX	(SSPP_CURSOR1 + 1)
+
+/* represents a hw pipe, which is dynamically assigned to a plane */
+struct mdp5_hw_pipe {
+	int idx;
+
+	const char *name;
+	enum mdp5_pipe pipe;
+
+	uint32_t reg_offset;
+	uint32_t caps;
+
+	uint32_t flush_mask;      /* used to commit pipe registers */
+
+	/* number of smp blocks per plane, ie:
+	 *   nblks_y | (nblks_u << 8) | (nblks_v << 16)
+	 */
+	uint32_t blkcfg;
+};
+
+/* global atomic state of assignment between pipes and planes: */
+struct mdp5_hw_pipe_state {
+	struct drm_plane *hwpipe_to_plane[SSPP_MAX];
+};
+
+int mdp5_pipe_assign(struct drm_atomic_state *s, struct drm_plane *plane,
+		     uint32_t caps, uint32_t blkcfg,
+		     struct mdp5_hw_pipe **hwpipe,
+		     struct mdp5_hw_pipe **r_hwpipe);
+int mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe);
+
+struct mdp5_hw_pipe *mdp5_pipe_init(struct drm_device *dev,
+		enum mdp5_pipe pipe,
+		uint32_t reg_offset, uint32_t caps);
+
+#endif /* __MDP5_PIPE_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_plane.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_plane.c
@@ -0,0 +1,1048 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2014-2015 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_blend.h>
+#include <drm/drm_damage_helper.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_atomic_helper.h>
+#include <drm/drm_print.h>
+
+#include "mdp5_kms.h"
+
+struct mdp5_plane {
+	struct drm_plane base;
+
+	uint32_t nformats;
+	uint32_t formats[32];
+};
+#define to_mdp5_plane(x) container_of(x, struct mdp5_plane, base)
+
+static int mdp5_plane_mode_set(struct drm_plane *plane,
+		struct drm_crtc *crtc, struct drm_framebuffer *fb,
+		struct drm_rect *src, struct drm_rect *dest);
+
+static struct mdp5_kms *get_kms(struct drm_plane *plane)
+{
+	struct msm_drm_private *priv = plane->dev->dev_private;
+	return to_mdp5_kms(to_mdp_kms(priv->kms));
+}
+
+static bool plane_enabled(struct drm_plane_state *state)
+{
+	return state->visible;
+}
+
+static void mdp5_plane_destroy(struct drm_plane *plane)
+{
+	struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane);
+
+	drm_plane_cleanup(plane);
+
+	kfree(mdp5_plane);
+}
+
+/* helper to install properties which are common to planes and crtcs */
+static void mdp5_plane_install_properties(struct drm_plane *plane,
+		struct drm_mode_object *obj)
+{
+	unsigned int zpos;
+
+	drm_plane_create_rotation_property(plane,
+					   DRM_MODE_ROTATE_0,
+					   DRM_MODE_ROTATE_0 |
+					   DRM_MODE_ROTATE_180 |
+					   DRM_MODE_REFLECT_X |
+					   DRM_MODE_REFLECT_Y);
+	drm_plane_create_alpha_property(plane);
+	drm_plane_create_blend_mode_property(plane,
+			BIT(DRM_MODE_BLEND_PIXEL_NONE) |
+			BIT(DRM_MODE_BLEND_PREMULTI) |
+			BIT(DRM_MODE_BLEND_COVERAGE));
+
+	if (plane->type == DRM_PLANE_TYPE_PRIMARY)
+		zpos = STAGE_BASE;
+	else
+		zpos = STAGE0 + drm_plane_index(plane);
+	drm_plane_create_zpos_property(plane, zpos, 1, 255);
+}
+
+static void
+mdp5_plane_atomic_print_state(struct drm_printer *p,
+		const struct drm_plane_state *state)
+{
+	struct mdp5_plane_state *pstate = to_mdp5_plane_state(state);
+	struct mdp5_kms *mdp5_kms = get_kms(state->plane);
+
+	drm_printf(p, "\thwpipe=%s\n", pstate->hwpipe ?
+			pstate->hwpipe->name : "(null)");
+	if (mdp5_kms->caps & MDP_CAP_SRC_SPLIT)
+		drm_printf(p, "\tright-hwpipe=%s\n",
+			   pstate->r_hwpipe ? pstate->r_hwpipe->name :
+					      "(null)");
+	drm_printf(p, "\tblend_mode=%u\n", pstate->base.pixel_blend_mode);
+	drm_printf(p, "\tzpos=%u\n", pstate->base.zpos);
+	drm_printf(p, "\tnormalized_zpos=%u\n", pstate->base.normalized_zpos);
+	drm_printf(p, "\talpha=%u\n", pstate->base.alpha);
+	drm_printf(p, "\tstage=%s\n", stage2name(pstate->stage));
+}
+
+static void mdp5_plane_reset(struct drm_plane *plane)
+{
+	struct mdp5_plane_state *mdp5_state;
+
+	if (plane->state)
+		__drm_atomic_helper_plane_destroy_state(plane->state);
+
+	kfree(to_mdp5_plane_state(plane->state));
+	plane->state = NULL;
+	mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL);
+	if (!mdp5_state)
+		return;
+	__drm_atomic_helper_plane_reset(plane, &mdp5_state->base);
+}
+
+static struct drm_plane_state *
+mdp5_plane_duplicate_state(struct drm_plane *plane)
+{
+	struct mdp5_plane_state *mdp5_state;
+
+	if (WARN_ON(!plane->state))
+		return NULL;
+
+	mdp5_state = kmemdup(to_mdp5_plane_state(plane->state),
+			sizeof(*mdp5_state), GFP_KERNEL);
+	if (!mdp5_state)
+		return NULL;
+
+	__drm_atomic_helper_plane_duplicate_state(plane, &mdp5_state->base);
+
+	return &mdp5_state->base;
+}
+
+static void mdp5_plane_destroy_state(struct drm_plane *plane,
+		struct drm_plane_state *state)
+{
+	struct mdp5_plane_state *pstate = to_mdp5_plane_state(state);
+
+	__drm_atomic_helper_plane_destroy_state(state);
+
+	kfree(pstate);
+}
+
+static const struct drm_plane_funcs mdp5_plane_funcs = {
+		.update_plane = drm_atomic_helper_update_plane,
+		.disable_plane = drm_atomic_helper_disable_plane,
+		.destroy = mdp5_plane_destroy,
+		.reset = mdp5_plane_reset,
+		.atomic_duplicate_state = mdp5_plane_duplicate_state,
+		.atomic_destroy_state = mdp5_plane_destroy_state,
+		.atomic_print_state = mdp5_plane_atomic_print_state,
+};
+
+static int mdp5_plane_prepare_fb(struct drm_plane *plane,
+				 struct drm_plane_state *new_state)
+{
+	struct msm_drm_private *priv = plane->dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+	bool needs_dirtyfb = to_mdp5_plane_state(new_state)->needs_dirtyfb;
+
+	if (!new_state->fb)
+		return 0;
+
+	drm_gem_plane_helper_prepare_fb(plane, new_state);
+
+	return msm_framebuffer_prepare(new_state->fb, kms->aspace, needs_dirtyfb);
+}
+
+static void mdp5_plane_cleanup_fb(struct drm_plane *plane,
+				  struct drm_plane_state *old_state)
+{
+	struct mdp5_kms *mdp5_kms = get_kms(plane);
+	struct msm_kms *kms = &mdp5_kms->base.base;
+	struct drm_framebuffer *fb = old_state->fb;
+	bool needed_dirtyfb = to_mdp5_plane_state(old_state)->needs_dirtyfb;
+
+	if (!fb)
+		return;
+
+	DBG("%s: cleanup: FB[%u]", plane->name, fb->base.id);
+	msm_framebuffer_cleanup(fb, kms->aspace, needed_dirtyfb);
+}
+
+static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state,
+					      struct drm_plane_state *state)
+{
+	struct mdp5_plane_state *mdp5_state = to_mdp5_plane_state(state);
+	struct drm_plane *plane = state->plane;
+	struct drm_plane_state *old_state = plane->state;
+	struct mdp5_cfg *config = mdp5_cfg_get_config(get_kms(plane)->cfg);
+	bool new_hwpipe = false;
+	bool need_right_hwpipe = false;
+	uint32_t max_width, max_height;
+	bool out_of_bounds = false;
+	uint32_t caps = 0;
+	int min_scale, max_scale;
+	int ret;
+
+	DBG("%s: check (%d -> %d)", plane->name,
+			plane_enabled(old_state), plane_enabled(state));
+
+	max_width = config->hw->lm.max_width << 16;
+	max_height = config->hw->lm.max_height << 16;
+
+	/* Make sure source dimensions are within bounds. */
+	if (state->src_h > max_height)
+		out_of_bounds = true;
+
+	if (state->src_w > max_width) {
+		/* If source split is supported, we can go up to 2x
+		 * the max LM width, but we'd need to stage another
+		 * hwpipe to the right LM. So, the drm_plane would
+		 * consist of 2 hwpipes.
+		 */
+		if (config->hw->mdp.caps & MDP_CAP_SRC_SPLIT &&
+		    (state->src_w <= 2 * max_width))
+			need_right_hwpipe = true;
+		else
+			out_of_bounds = true;
+	}
+
+	if (out_of_bounds) {
+		struct drm_rect src = drm_plane_state_src(state);
+		DBG("Invalid source size "DRM_RECT_FP_FMT,
+				DRM_RECT_FP_ARG(&src));
+		return -ERANGE;
+	}
+
+	min_scale = FRAC_16_16(1, 8);
+	max_scale = FRAC_16_16(8, 1);
+
+	ret = drm_atomic_helper_check_plane_state(state, crtc_state,
+						  min_scale, max_scale,
+						  true, true);
+	if (ret)
+		return ret;
+
+	if (plane_enabled(state)) {
+		unsigned int rotation;
+		const struct mdp_format *format;
+		struct mdp5_kms *mdp5_kms = get_kms(plane);
+		uint32_t blkcfg = 0;
+
+		format = to_mdp_format(msm_framebuffer_format(state->fb));
+		if (MDP_FORMAT_IS_YUV(format))
+			caps |= MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC;
+
+		if (((state->src_w >> 16) != state->crtc_w) ||
+				((state->src_h >> 16) != state->crtc_h))
+			caps |= MDP_PIPE_CAP_SCALE;
+
+		rotation = drm_rotation_simplify(state->rotation,
+						 DRM_MODE_ROTATE_0 |
+						 DRM_MODE_REFLECT_X |
+						 DRM_MODE_REFLECT_Y);
+
+		if (rotation & DRM_MODE_REFLECT_X)
+			caps |= MDP_PIPE_CAP_HFLIP;
+
+		if (rotation & DRM_MODE_REFLECT_Y)
+			caps |= MDP_PIPE_CAP_VFLIP;
+
+		if (plane->type == DRM_PLANE_TYPE_CURSOR)
+			caps |= MDP_PIPE_CAP_CURSOR;
+
+		/* (re)allocate hw pipe if we don't have one or caps-mismatch: */
+		if (!mdp5_state->hwpipe || (caps & ~mdp5_state->hwpipe->caps))
+			new_hwpipe = true;
+
+		/*
+		 * (re)allocte hw pipe if we're either requesting for 2 hw pipes
+		 * or we're switching from 2 hw pipes to 1 hw pipe because the
+		 * new src_w can be supported by 1 hw pipe itself.
+		 */
+		if ((need_right_hwpipe && !mdp5_state->r_hwpipe) ||
+		    (!need_right_hwpipe && mdp5_state->r_hwpipe))
+			new_hwpipe = true;
+
+		if (mdp5_kms->smp) {
+			const struct mdp_format *format =
+				to_mdp_format(msm_framebuffer_format(state->fb));
+
+			blkcfg = mdp5_smp_calculate(mdp5_kms->smp, format,
+					state->src_w >> 16, false);
+
+			if (mdp5_state->hwpipe && (mdp5_state->hwpipe->blkcfg != blkcfg))
+				new_hwpipe = true;
+		}
+
+		/* (re)assign hwpipe if needed, otherwise keep old one: */
+		if (new_hwpipe) {
+			/* TODO maybe we want to re-assign hwpipe sometimes
+			 * in cases when we no-longer need some caps to make
+			 * it available for other planes?
+			 */
+			struct mdp5_hw_pipe *old_hwpipe = mdp5_state->hwpipe;
+			struct mdp5_hw_pipe *old_right_hwpipe =
+							  mdp5_state->r_hwpipe;
+			struct mdp5_hw_pipe *new_hwpipe = NULL;
+			struct mdp5_hw_pipe *new_right_hwpipe = NULL;
+
+			ret = mdp5_pipe_assign(state->state, plane, caps,
+					       blkcfg, &new_hwpipe,
+					       need_right_hwpipe ?
+					       &new_right_hwpipe : NULL);
+			if (ret) {
+				DBG("%s: failed to assign hwpipe(s)!",
+				    plane->name);
+				return ret;
+			}
+
+			mdp5_state->hwpipe = new_hwpipe;
+			if (need_right_hwpipe)
+				mdp5_state->r_hwpipe = new_right_hwpipe;
+			else
+				/*
+				 * set it to NULL so that the driver knows we
+				 * don't have a right hwpipe when committing a
+				 * new state
+				 */
+				mdp5_state->r_hwpipe = NULL;
+
+
+			ret = mdp5_pipe_release(state->state, old_hwpipe);
+			if (ret)
+				return ret;
+
+			ret = mdp5_pipe_release(state->state, old_right_hwpipe);
+			if (ret)
+				return ret;
+
+		}
+	} else {
+		ret = mdp5_pipe_release(state->state, mdp5_state->hwpipe);
+		if (ret)
+			return ret;
+
+		ret = mdp5_pipe_release(state->state, mdp5_state->r_hwpipe);
+		if (ret)
+			return ret;
+
+		mdp5_state->hwpipe = mdp5_state->r_hwpipe = NULL;
+	}
+
+	return 0;
+}
+
+static int mdp5_plane_atomic_check(struct drm_plane *plane,
+				   struct drm_atomic_state *state)
+{
+	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state,
+										 plane);
+	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
+										 plane);
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *crtc_state;
+
+	crtc = new_plane_state->crtc ? new_plane_state->crtc : old_plane_state->crtc;
+	if (!crtc)
+		return 0;
+
+	crtc_state = drm_atomic_get_existing_crtc_state(state,
+							crtc);
+	if (WARN_ON(!crtc_state))
+		return -EINVAL;
+
+	return mdp5_plane_atomic_check_with_state(crtc_state, new_plane_state);
+}
+
+static void mdp5_plane_atomic_update(struct drm_plane *plane,
+				     struct drm_atomic_state *state)
+{
+	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
+									   plane);
+
+	DBG("%s: update", plane->name);
+
+	if (plane_enabled(new_state)) {
+		int ret;
+
+		ret = mdp5_plane_mode_set(plane,
+				new_state->crtc, new_state->fb,
+				&new_state->src, &new_state->dst);
+		/* atomic_check should have ensured that this doesn't fail */
+		WARN_ON(ret < 0);
+	}
+}
+
+static int mdp5_plane_atomic_async_check(struct drm_plane *plane,
+					 struct drm_atomic_state *state)
+{
+	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
+										 plane);
+	struct mdp5_plane_state *mdp5_state = to_mdp5_plane_state(new_plane_state);
+	struct drm_crtc_state *crtc_state;
+	int min_scale, max_scale;
+	int ret;
+
+	crtc_state = drm_atomic_get_existing_crtc_state(state,
+							new_plane_state->crtc);
+	if (WARN_ON(!crtc_state))
+		return -EINVAL;
+
+	if (!crtc_state->active)
+		return -EINVAL;
+
+	/* don't use fast path if we don't have a hwpipe allocated yet */
+	if (!mdp5_state->hwpipe)
+		return -EINVAL;
+
+	/* only allow changing of position(crtc x/y or src x/y) in fast path */
+	if (plane->state->crtc != new_plane_state->crtc ||
+	    plane->state->src_w != new_plane_state->src_w ||
+	    plane->state->src_h != new_plane_state->src_h ||
+	    plane->state->crtc_w != new_plane_state->crtc_w ||
+	    plane->state->crtc_h != new_plane_state->crtc_h ||
+	    !plane->state->fb ||
+	    plane->state->fb != new_plane_state->fb)
+		return -EINVAL;
+
+	min_scale = FRAC_16_16(1, 8);
+	max_scale = FRAC_16_16(8, 1);
+
+	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
+						  min_scale, max_scale,
+						  true, true);
+	if (ret)
+		return ret;
+
+	/*
+	 * if the visibility of the plane changes (i.e, if the cursor is
+	 * clipped out completely, we can't take the async path because
+	 * we need to stage/unstage the plane from the Layer Mixer(s). We
+	 * also assign/unassign the hwpipe(s) tied to the plane. We avoid
+	 * taking the fast path for both these reasons.
+	 */
+	if (new_plane_state->visible != plane->state->visible)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void mdp5_plane_atomic_async_update(struct drm_plane *plane,
+					   struct drm_atomic_state *state)
+{
+	struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
+									   plane);
+	struct drm_framebuffer *old_fb = plane->state->fb;
+
+	plane->state->src_x = new_state->src_x;
+	plane->state->src_y = new_state->src_y;
+	plane->state->crtc_x = new_state->crtc_x;
+	plane->state->crtc_y = new_state->crtc_y;
+
+	if (plane_enabled(new_state)) {
+		struct mdp5_ctl *ctl;
+		struct mdp5_pipeline *pipeline =
+					mdp5_crtc_get_pipeline(new_state->crtc);
+		int ret;
+
+		ret = mdp5_plane_mode_set(plane, new_state->crtc, new_state->fb,
+				&new_state->src, &new_state->dst);
+		WARN_ON(ret < 0);
+
+		ctl = mdp5_crtc_get_ctl(new_state->crtc);
+
+		mdp5_ctl_commit(ctl, pipeline, mdp5_plane_get_flush(plane), true);
+	}
+
+	*to_mdp5_plane_state(plane->state) =
+		*to_mdp5_plane_state(new_state);
+
+	new_state->fb = old_fb;
+}
+
+static const struct drm_plane_helper_funcs mdp5_plane_helper_funcs = {
+		.prepare_fb = mdp5_plane_prepare_fb,
+		.cleanup_fb = mdp5_plane_cleanup_fb,
+		.atomic_check = mdp5_plane_atomic_check,
+		.atomic_update = mdp5_plane_atomic_update,
+		.atomic_async_check = mdp5_plane_atomic_async_check,
+		.atomic_async_update = mdp5_plane_atomic_async_update,
+};
+
+static void set_scanout_locked(struct mdp5_kms *mdp5_kms,
+			       enum mdp5_pipe pipe,
+			       struct drm_framebuffer *fb)
+{
+	struct msm_kms *kms = &mdp5_kms->base.base;
+
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_STRIDE_A(pipe),
+			MDP5_PIPE_SRC_STRIDE_A_P0(fb->pitches[0]) |
+			MDP5_PIPE_SRC_STRIDE_A_P1(fb->pitches[1]));
+
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_STRIDE_B(pipe),
+			MDP5_PIPE_SRC_STRIDE_B_P2(fb->pitches[2]) |
+			MDP5_PIPE_SRC_STRIDE_B_P3(fb->pitches[3]));
+
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC0_ADDR(pipe),
+			msm_framebuffer_iova(fb, kms->aspace, 0));
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC1_ADDR(pipe),
+			msm_framebuffer_iova(fb, kms->aspace, 1));
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC2_ADDR(pipe),
+			msm_framebuffer_iova(fb, kms->aspace, 2));
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC3_ADDR(pipe),
+			msm_framebuffer_iova(fb, kms->aspace, 3));
+}
+
+/* Note: mdp5_plane->pipe_lock must be locked */
+static void csc_disable(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe)
+{
+	uint32_t value = mdp5_read(mdp5_kms, REG_MDP5_PIPE_OP_MODE(pipe)) &
+			 ~MDP5_PIPE_OP_MODE_CSC_1_EN;
+
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_OP_MODE(pipe), value);
+}
+
+/* Note: mdp5_plane->pipe_lock must be locked */
+static void csc_enable(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe,
+		struct csc_cfg *csc)
+{
+	uint32_t  i, mode = 0; /* RGB, no CSC */
+	uint32_t *matrix;
+
+	if (unlikely(!csc))
+		return;
+
+	if ((csc->type == CSC_YUV2RGB) || (CSC_YUV2YUV == csc->type))
+		mode |= MDP5_PIPE_OP_MODE_CSC_SRC_DATA_FORMAT(DATA_FORMAT_YUV);
+	if ((csc->type == CSC_RGB2YUV) || (CSC_YUV2YUV == csc->type))
+		mode |= MDP5_PIPE_OP_MODE_CSC_DST_DATA_FORMAT(DATA_FORMAT_YUV);
+	mode |= MDP5_PIPE_OP_MODE_CSC_1_EN;
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_OP_MODE(pipe), mode);
+
+	matrix = csc->matrix;
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_0(pipe),
+			MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_11(matrix[0]) |
+			MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_12(matrix[1]));
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_1(pipe),
+			MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_13(matrix[2]) |
+			MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_21(matrix[3]));
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_2(pipe),
+			MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_22(matrix[4]) |
+			MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_23(matrix[5]));
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_3(pipe),
+			MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_31(matrix[6]) |
+			MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_32(matrix[7]));
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_4(pipe),
+			MDP5_PIPE_CSC_1_MATRIX_COEFF_4_COEFF_33(matrix[8]));
+
+	for (i = 0; i < ARRAY_SIZE(csc->pre_bias); i++) {
+		uint32_t *pre_clamp = csc->pre_clamp;
+		uint32_t *post_clamp = csc->post_clamp;
+
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_PRE_CLAMP(pipe, i),
+			MDP5_PIPE_CSC_1_PRE_CLAMP_REG_HIGH(pre_clamp[2*i+1]) |
+			MDP5_PIPE_CSC_1_PRE_CLAMP_REG_LOW(pre_clamp[2*i]));
+
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_POST_CLAMP(pipe, i),
+			MDP5_PIPE_CSC_1_POST_CLAMP_REG_HIGH(post_clamp[2*i+1]) |
+			MDP5_PIPE_CSC_1_POST_CLAMP_REG_LOW(post_clamp[2*i]));
+
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_PRE_BIAS(pipe, i),
+			MDP5_PIPE_CSC_1_PRE_BIAS_REG_VALUE(csc->pre_bias[i]));
+
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_POST_BIAS(pipe, i),
+			MDP5_PIPE_CSC_1_POST_BIAS_REG_VALUE(csc->post_bias[i]));
+	}
+}
+
+#define PHASE_STEP_SHIFT	21
+#define DOWN_SCALE_RATIO_MAX	32	/* 2^(26-21) */
+
+static int calc_phase_step(uint32_t src, uint32_t dst, uint32_t *out_phase)
+{
+	uint32_t unit;
+
+	if (src == 0 || dst == 0)
+		return -EINVAL;
+
+	/*
+	 * PHASE_STEP_X/Y is coded on 26 bits (25:0),
+	 * where 2^21 represents the unity "1" in fixed-point hardware design.
+	 * This leaves 5 bits for the integer part (downscale case):
+	 *	-> maximum downscale ratio = 0b1_1111 = 31
+	 */
+	if (src > (dst * DOWN_SCALE_RATIO_MAX))
+		return -EOVERFLOW;
+
+	unit = 1 << PHASE_STEP_SHIFT;
+	*out_phase = mult_frac(unit, src, dst);
+
+	return 0;
+}
+
+static int calc_scalex_steps(struct drm_plane *plane,
+		uint32_t pixel_format, uint32_t src, uint32_t dest,
+		uint32_t phasex_steps[COMP_MAX])
+{
+	const struct drm_format_info *info = drm_format_info(pixel_format);
+	struct mdp5_kms *mdp5_kms = get_kms(plane);
+	struct device *dev = mdp5_kms->dev->dev;
+	uint32_t phasex_step;
+	int ret;
+
+	ret = calc_phase_step(src, dest, &phasex_step);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "X scaling (%d->%d) failed: %d\n", src, dest, ret);
+		return ret;
+	}
+
+	phasex_steps[COMP_0]   = phasex_step;
+	phasex_steps[COMP_3]   = phasex_step;
+	phasex_steps[COMP_1_2] = phasex_step / info->hsub;
+
+	return 0;
+}
+
+static int calc_scaley_steps(struct drm_plane *plane,
+		uint32_t pixel_format, uint32_t src, uint32_t dest,
+		uint32_t phasey_steps[COMP_MAX])
+{
+	const struct drm_format_info *info = drm_format_info(pixel_format);
+	struct mdp5_kms *mdp5_kms = get_kms(plane);
+	struct device *dev = mdp5_kms->dev->dev;
+	uint32_t phasey_step;
+	int ret;
+
+	ret = calc_phase_step(src, dest, &phasey_step);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "Y scaling (%d->%d) failed: %d\n", src, dest, ret);
+		return ret;
+	}
+
+	phasey_steps[COMP_0]   = phasey_step;
+	phasey_steps[COMP_3]   = phasey_step;
+	phasey_steps[COMP_1_2] = phasey_step / info->vsub;
+
+	return 0;
+}
+
+static uint32_t get_scale_config(const struct mdp_format *format,
+		uint32_t src, uint32_t dst, bool horz)
+{
+	const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
+	bool scaling = format->is_yuv ? true : (src != dst);
+	uint32_t sub;
+	uint32_t ya_filter, uv_filter;
+	bool yuv = format->is_yuv;
+
+	if (!scaling)
+		return 0;
+
+	if (yuv) {
+		sub = horz ? info->hsub : info->vsub;
+		uv_filter = ((src / sub) <= dst) ?
+				   SCALE_FILTER_BIL : SCALE_FILTER_PCMN;
+	}
+	ya_filter = (src <= dst) ? SCALE_FILTER_BIL : SCALE_FILTER_PCMN;
+
+	if (horz)
+		return  MDP5_PIPE_SCALE_CONFIG_SCALEX_EN |
+			MDP5_PIPE_SCALE_CONFIG_SCALEX_FILTER_COMP_0(ya_filter) |
+			MDP5_PIPE_SCALE_CONFIG_SCALEX_FILTER_COMP_3(ya_filter) |
+			COND(yuv, MDP5_PIPE_SCALE_CONFIG_SCALEX_FILTER_COMP_1_2(uv_filter));
+	else
+		return  MDP5_PIPE_SCALE_CONFIG_SCALEY_EN |
+			MDP5_PIPE_SCALE_CONFIG_SCALEY_FILTER_COMP_0(ya_filter) |
+			MDP5_PIPE_SCALE_CONFIG_SCALEY_FILTER_COMP_3(ya_filter) |
+			COND(yuv, MDP5_PIPE_SCALE_CONFIG_SCALEY_FILTER_COMP_1_2(uv_filter));
+}
+
+static void calc_pixel_ext(const struct mdp_format *format,
+		uint32_t src, uint32_t dst, uint32_t phase_step[2],
+		int pix_ext_edge1[COMP_MAX], int pix_ext_edge2[COMP_MAX],
+		bool horz)
+{
+	bool scaling = format->is_yuv ? true : (src != dst);
+	int i;
+
+	/*
+	 * Note:
+	 * We assume here that:
+	 *     1. PCMN filter is used for downscale
+	 *     2. bilinear filter is used for upscale
+	 *     3. we are in a single pipe configuration
+	 */
+
+	for (i = 0; i < COMP_MAX; i++) {
+		pix_ext_edge1[i] = 0;
+		pix_ext_edge2[i] = scaling ? 1 : 0;
+	}
+}
+
+static void mdp5_write_pixel_ext(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe,
+	const struct mdp_format *format,
+	uint32_t src_w, int pe_left[COMP_MAX], int pe_right[COMP_MAX],
+	uint32_t src_h, int pe_top[COMP_MAX], int pe_bottom[COMP_MAX])
+{
+	const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
+	uint32_t lr, tb, req;
+	int i;
+
+	for (i = 0; i < COMP_MAX; i++) {
+		uint32_t roi_w = src_w;
+		uint32_t roi_h = src_h;
+
+		if (format->is_yuv && i == COMP_1_2) {
+			roi_w /= info->hsub;
+			roi_h /= info->vsub;
+		}
+
+		lr  = (pe_left[i] >= 0) ?
+			MDP5_PIPE_SW_PIX_EXT_LR_LEFT_RPT(pe_left[i]) :
+			MDP5_PIPE_SW_PIX_EXT_LR_LEFT_OVF(pe_left[i]);
+
+		lr |= (pe_right[i] >= 0) ?
+			MDP5_PIPE_SW_PIX_EXT_LR_RIGHT_RPT(pe_right[i]) :
+			MDP5_PIPE_SW_PIX_EXT_LR_RIGHT_OVF(pe_right[i]);
+
+		tb  = (pe_top[i] >= 0) ?
+			MDP5_PIPE_SW_PIX_EXT_TB_TOP_RPT(pe_top[i]) :
+			MDP5_PIPE_SW_PIX_EXT_TB_TOP_OVF(pe_top[i]);
+
+		tb |= (pe_bottom[i] >= 0) ?
+			MDP5_PIPE_SW_PIX_EXT_TB_BOTTOM_RPT(pe_bottom[i]) :
+			MDP5_PIPE_SW_PIX_EXT_TB_BOTTOM_OVF(pe_bottom[i]);
+
+		req  = MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS_LEFT_RIGHT(roi_w +
+				pe_left[i] + pe_right[i]);
+
+		req |= MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS_TOP_BOTTOM(roi_h +
+				pe_top[i] + pe_bottom[i]);
+
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_SW_PIX_EXT_LR(pipe, i), lr);
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_SW_PIX_EXT_TB(pipe, i), tb);
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS(pipe, i), req);
+
+		DBG("comp-%d (L/R): rpt=%d/%d, ovf=%d/%d, req=%d", i,
+			FIELD(lr,  MDP5_PIPE_SW_PIX_EXT_LR_LEFT_RPT),
+			FIELD(lr,  MDP5_PIPE_SW_PIX_EXT_LR_RIGHT_RPT),
+			FIELD(lr,  MDP5_PIPE_SW_PIX_EXT_LR_LEFT_OVF),
+			FIELD(lr,  MDP5_PIPE_SW_PIX_EXT_LR_RIGHT_OVF),
+			FIELD(req, MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS_LEFT_RIGHT));
+
+		DBG("comp-%d (T/B): rpt=%d/%d, ovf=%d/%d, req=%d", i,
+			FIELD(tb,  MDP5_PIPE_SW_PIX_EXT_TB_TOP_RPT),
+			FIELD(tb,  MDP5_PIPE_SW_PIX_EXT_TB_BOTTOM_RPT),
+			FIELD(tb,  MDP5_PIPE_SW_PIX_EXT_TB_TOP_OVF),
+			FIELD(tb,  MDP5_PIPE_SW_PIX_EXT_TB_BOTTOM_OVF),
+			FIELD(req, MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS_TOP_BOTTOM));
+	}
+}
+
+struct pixel_ext {
+	int left[COMP_MAX];
+	int right[COMP_MAX];
+	int top[COMP_MAX];
+	int bottom[COMP_MAX];
+};
+
+struct phase_step {
+	u32 x[COMP_MAX];
+	u32 y[COMP_MAX];
+};
+
+static void mdp5_hwpipe_mode_set(struct mdp5_kms *mdp5_kms,
+				 struct mdp5_hw_pipe *hwpipe,
+				 struct drm_framebuffer *fb,
+				 struct phase_step *step,
+				 struct pixel_ext *pe,
+				 u32 scale_config, u32 hdecm, u32 vdecm,
+				 bool hflip, bool vflip,
+				 int crtc_x, int crtc_y,
+				 unsigned int crtc_w, unsigned int crtc_h,
+				 u32 src_img_w, u32 src_img_h,
+				 u32 src_x, u32 src_y,
+				 u32 src_w, u32 src_h)
+{
+	enum mdp5_pipe pipe = hwpipe->pipe;
+	bool has_pe = hwpipe->caps & MDP_PIPE_CAP_SW_PIX_EXT;
+	const struct mdp_format *format =
+			to_mdp_format(msm_framebuffer_format(fb));
+
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_IMG_SIZE(pipe),
+			MDP5_PIPE_SRC_IMG_SIZE_WIDTH(src_img_w) |
+			MDP5_PIPE_SRC_IMG_SIZE_HEIGHT(src_img_h));
+
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_SIZE(pipe),
+			MDP5_PIPE_SRC_SIZE_WIDTH(src_w) |
+			MDP5_PIPE_SRC_SIZE_HEIGHT(src_h));
+
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_XY(pipe),
+			MDP5_PIPE_SRC_XY_X(src_x) |
+			MDP5_PIPE_SRC_XY_Y(src_y));
+
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_OUT_SIZE(pipe),
+			MDP5_PIPE_OUT_SIZE_WIDTH(crtc_w) |
+			MDP5_PIPE_OUT_SIZE_HEIGHT(crtc_h));
+
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_OUT_XY(pipe),
+			MDP5_PIPE_OUT_XY_X(crtc_x) |
+			MDP5_PIPE_OUT_XY_Y(crtc_y));
+
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_FORMAT(pipe),
+			MDP5_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) |
+			MDP5_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) |
+			MDP5_PIPE_SRC_FORMAT_G_BPC(format->bpc_g) |
+			MDP5_PIPE_SRC_FORMAT_B_BPC(format->bpc_b) |
+			COND(format->alpha_enable, MDP5_PIPE_SRC_FORMAT_ALPHA_ENABLE) |
+			MDP5_PIPE_SRC_FORMAT_CPP(format->cpp - 1) |
+			MDP5_PIPE_SRC_FORMAT_UNPACK_COUNT(format->unpack_count - 1) |
+			COND(format->unpack_tight, MDP5_PIPE_SRC_FORMAT_UNPACK_TIGHT) |
+			MDP5_PIPE_SRC_FORMAT_FETCH_TYPE(format->fetch_type) |
+			MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP(format->chroma_sample));
+
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_UNPACK(pipe),
+			MDP5_PIPE_SRC_UNPACK_ELEM0(format->unpack[0]) |
+			MDP5_PIPE_SRC_UNPACK_ELEM1(format->unpack[1]) |
+			MDP5_PIPE_SRC_UNPACK_ELEM2(format->unpack[2]) |
+			MDP5_PIPE_SRC_UNPACK_ELEM3(format->unpack[3]));
+
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_OP_MODE(pipe),
+			(hflip ? MDP5_PIPE_SRC_OP_MODE_FLIP_LR : 0) |
+			(vflip ? MDP5_PIPE_SRC_OP_MODE_FLIP_UD : 0) |
+			COND(has_pe, MDP5_PIPE_SRC_OP_MODE_SW_PIX_EXT_OVERRIDE) |
+			MDP5_PIPE_SRC_OP_MODE_BWC(BWC_LOSSLESS));
+
+	/* not using secure mode: */
+	mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_ADDR_SW_STATUS(pipe), 0);
+
+	if (hwpipe->caps & MDP_PIPE_CAP_SW_PIX_EXT)
+		mdp5_write_pixel_ext(mdp5_kms, pipe, format,
+				src_w, pe->left, pe->right,
+				src_h, pe->top, pe->bottom);
+
+	if (hwpipe->caps & MDP_PIPE_CAP_SCALE) {
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_PHASE_STEP_X(pipe),
+				step->x[COMP_0]);
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_PHASE_STEP_Y(pipe),
+				step->y[COMP_0]);
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_CR_PHASE_STEP_X(pipe),
+				step->x[COMP_1_2]);
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_CR_PHASE_STEP_Y(pipe),
+				step->y[COMP_1_2]);
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_DECIMATION(pipe),
+				MDP5_PIPE_DECIMATION_VERT(vdecm) |
+				MDP5_PIPE_DECIMATION_HORZ(hdecm));
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_CONFIG(pipe),
+			   scale_config);
+	}
+
+	if (hwpipe->caps & MDP_PIPE_CAP_CSC) {
+		if (MDP_FORMAT_IS_YUV(format))
+			csc_enable(mdp5_kms, pipe,
+					mdp_get_default_csc_cfg(CSC_YUV2RGB));
+		else
+			csc_disable(mdp5_kms, pipe);
+	}
+
+	set_scanout_locked(mdp5_kms, pipe, fb);
+}
+
+static int mdp5_plane_mode_set(struct drm_plane *plane,
+		struct drm_crtc *crtc, struct drm_framebuffer *fb,
+		struct drm_rect *src, struct drm_rect *dest)
+{
+	struct drm_plane_state *pstate = plane->state;
+	struct mdp5_hw_pipe *hwpipe = to_mdp5_plane_state(pstate)->hwpipe;
+	struct mdp5_kms *mdp5_kms = get_kms(plane);
+	enum mdp5_pipe pipe = hwpipe->pipe;
+	struct mdp5_hw_pipe *right_hwpipe;
+	const struct mdp_format *format;
+	uint32_t nplanes, config = 0;
+	struct phase_step step = { { 0 } };
+	struct pixel_ext pe = { { 0 } };
+	uint32_t hdecm = 0, vdecm = 0;
+	uint32_t pix_format;
+	unsigned int rotation;
+	bool vflip, hflip;
+	int crtc_x, crtc_y;
+	unsigned int crtc_w, crtc_h;
+	uint32_t src_x, src_y;
+	uint32_t src_w, src_h;
+	uint32_t src_img_w, src_img_h;
+	int ret;
+
+	nplanes = fb->format->num_planes;
+
+	/* bad formats should already be rejected: */
+	if (WARN_ON(nplanes > pipe2nclients(pipe)))
+		return -EINVAL;
+
+	format = to_mdp_format(msm_framebuffer_format(fb));
+	pix_format = format->base.pixel_format;
+
+	src_x = src->x1;
+	src_y = src->y1;
+	src_w = drm_rect_width(src);
+	src_h = drm_rect_height(src);
+
+	crtc_x = dest->x1;
+	crtc_y = dest->y1;
+	crtc_w = drm_rect_width(dest);
+	crtc_h = drm_rect_height(dest);
+
+	/* src values are in Q16 fixed point, convert to integer: */
+	src_x = src_x >> 16;
+	src_y = src_y >> 16;
+	src_w = src_w >> 16;
+	src_h = src_h >> 16;
+
+	src_img_w = min(fb->width, src_w);
+	src_img_h = min(fb->height, src_h);
+
+	DBG("%s: FB[%u] %u,%u,%u,%u -> CRTC[%u] %d,%d,%u,%u", plane->name,
+			fb->base.id, src_x, src_y, src_w, src_h,
+			crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h);
+
+	right_hwpipe = to_mdp5_plane_state(pstate)->r_hwpipe;
+	if (right_hwpipe) {
+		/*
+		 * if the plane comprises of 2 hw pipes, assume that the width
+		 * is split equally across them. The only parameters that varies
+		 * between the 2 pipes are src_x and crtc_x
+		 */
+		crtc_w /= 2;
+		src_w /= 2;
+		src_img_w /= 2;
+	}
+
+	ret = calc_scalex_steps(plane, pix_format, src_w, crtc_w, step.x);
+	if (ret)
+		return ret;
+
+	ret = calc_scaley_steps(plane, pix_format, src_h, crtc_h, step.y);
+	if (ret)
+		return ret;
+
+	if (hwpipe->caps & MDP_PIPE_CAP_SW_PIX_EXT) {
+		calc_pixel_ext(format, src_w, crtc_w, step.x,
+			       pe.left, pe.right, true);
+		calc_pixel_ext(format, src_h, crtc_h, step.y,
+			       pe.top, pe.bottom, false);
+	}
+
+	/* TODO calc hdecm, vdecm */
+
+	/* SCALE is used to both scale and up-sample chroma components */
+	config |= get_scale_config(format, src_w, crtc_w, true);
+	config |= get_scale_config(format, src_h, crtc_h, false);
+	DBG("scale config = %x", config);
+
+	rotation = drm_rotation_simplify(pstate->rotation,
+					 DRM_MODE_ROTATE_0 |
+					 DRM_MODE_REFLECT_X |
+					 DRM_MODE_REFLECT_Y);
+	hflip = !!(rotation & DRM_MODE_REFLECT_X);
+	vflip = !!(rotation & DRM_MODE_REFLECT_Y);
+
+	mdp5_hwpipe_mode_set(mdp5_kms, hwpipe, fb, &step, &pe,
+			     config, hdecm, vdecm, hflip, vflip,
+			     crtc_x, crtc_y, crtc_w, crtc_h,
+			     src_img_w, src_img_h,
+			     src_x, src_y, src_w, src_h);
+	if (right_hwpipe)
+		mdp5_hwpipe_mode_set(mdp5_kms, right_hwpipe, fb, &step, &pe,
+				     config, hdecm, vdecm, hflip, vflip,
+				     crtc_x + crtc_w, crtc_y, crtc_w, crtc_h,
+				     src_img_w, src_img_h,
+				     src_x + src_w, src_y, src_w, src_h);
+
+	return ret;
+}
+
+/*
+ * Use this func and the one below only after the atomic state has been
+ * successfully swapped
+ */
+enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane)
+{
+	struct mdp5_plane_state *pstate = to_mdp5_plane_state(plane->state);
+
+	if (WARN_ON(!pstate->hwpipe))
+		return SSPP_NONE;
+
+	return pstate->hwpipe->pipe;
+}
+
+enum mdp5_pipe mdp5_plane_right_pipe(struct drm_plane *plane)
+{
+	struct mdp5_plane_state *pstate = to_mdp5_plane_state(plane->state);
+
+	if (!pstate->r_hwpipe)
+		return SSPP_NONE;
+
+	return pstate->r_hwpipe->pipe;
+}
+
+uint32_t mdp5_plane_get_flush(struct drm_plane *plane)
+{
+	struct mdp5_plane_state *pstate = to_mdp5_plane_state(plane->state);
+	u32 mask;
+
+	if (WARN_ON(!pstate->hwpipe))
+		return 0;
+
+	mask = pstate->hwpipe->flush_mask;
+
+	if (pstate->r_hwpipe)
+		mask |= pstate->r_hwpipe->flush_mask;
+
+	return mask;
+}
+
+/* initialize plane */
+struct drm_plane *mdp5_plane_init(struct drm_device *dev,
+				  enum drm_plane_type type)
+{
+	struct drm_plane *plane = NULL;
+	struct mdp5_plane *mdp5_plane;
+	int ret;
+
+	mdp5_plane = kzalloc(sizeof(*mdp5_plane), GFP_KERNEL);
+	if (!mdp5_plane) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	plane = &mdp5_plane->base;
+
+	mdp5_plane->nformats = mdp_get_formats(mdp5_plane->formats,
+		ARRAY_SIZE(mdp5_plane->formats), false);
+
+	ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs,
+			mdp5_plane->formats, mdp5_plane->nformats,
+			NULL, type, NULL);
+	if (ret)
+		goto fail;
+
+	drm_plane_helper_add(plane, &mdp5_plane_helper_funcs);
+
+	mdp5_plane_install_properties(plane, &plane->base);
+
+	drm_plane_enable_fb_damage_clips(plane);
+
+	return plane;
+
+fail:
+	if (plane)
+		mdp5_plane_destroy(plane);
+
+	return ERR_PTR(ret);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_smp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_smp.c
@@ -0,0 +1,397 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <drm/drm_fourcc.h>
+#include <drm/drm_util.h>
+
+#include "mdp5_kms.h"
+#include "mdp5_smp.h"
+
+
+struct mdp5_smp {
+	struct drm_device *dev;
+
+	uint8_t reserved[MAX_CLIENTS]; /* fixed MMBs allocation per client */
+
+	int blk_cnt;
+	int blk_size;
+
+	/* register cache */
+	u32 alloc_w[22];
+	u32 alloc_r[22];
+	u32 pipe_reqprio_fifo_wm0[SSPP_MAX];
+	u32 pipe_reqprio_fifo_wm1[SSPP_MAX];
+	u32 pipe_reqprio_fifo_wm2[SSPP_MAX];
+};
+
+static inline
+struct mdp5_kms *get_kms(struct mdp5_smp *smp)
+{
+	struct msm_drm_private *priv = smp->dev->dev_private;
+
+	return to_mdp5_kms(to_mdp_kms(priv->kms));
+}
+
+static inline u32 pipe2client(enum mdp5_pipe pipe, int plane)
+{
+#define CID_UNUSED	0
+
+	if (WARN_ON(plane >= pipe2nclients(pipe)))
+		return CID_UNUSED;
+
+	/*
+	 * Note on SMP clients:
+	 * For ViG pipes, fetch Y/Cr/Cb-components clients are always
+	 * consecutive, and in that order.
+	 *
+	 * e.g.:
+	 * if mdp5_cfg->smp.clients[SSPP_VIG0] = N,
+	 *	Y  plane's client ID is N
+	 *	Cr plane's client ID is N + 1
+	 *	Cb plane's client ID is N + 2
+	 */
+
+	return mdp5_cfg->smp.clients[pipe] + plane;
+}
+
+/* allocate blocks for the specified request: */
+static int smp_request_block(struct mdp5_smp *smp,
+		struct mdp5_smp_state *state,
+		u32 cid, int nblks)
+{
+	void *cs = state->client_state[cid];
+	int i, avail, cnt = smp->blk_cnt;
+	uint8_t reserved;
+
+	/* we shouldn't be requesting blocks for an in-use client: */
+	WARN_ON(!bitmap_empty(cs, cnt));
+
+	reserved = smp->reserved[cid];
+
+	if (reserved) {
+		nblks = max(0, nblks - reserved);
+		DBG("%d MMBs allocated (%d reserved)", nblks, reserved);
+	}
+
+	avail = cnt - bitmap_weight(state->state, cnt);
+	if (nblks > avail) {
+		DRM_DEV_ERROR(smp->dev->dev, "out of blks (req=%d > avail=%d)\n",
+				nblks, avail);
+		return -ENOSPC;
+	}
+
+	for (i = 0; i < nblks; i++) {
+		int blk = find_first_zero_bit(state->state, cnt);
+		set_bit(blk, cs);
+		set_bit(blk, state->state);
+	}
+
+	return 0;
+}
+
+static void set_fifo_thresholds(struct mdp5_smp *smp,
+		enum mdp5_pipe pipe, int nblks)
+{
+	u32 smp_entries_per_blk = smp->blk_size / (128 / BITS_PER_BYTE);
+	u32 val;
+
+	/* 1/4 of SMP pool that is being fetched */
+	val = (nblks * smp_entries_per_blk) / 4;
+
+	smp->pipe_reqprio_fifo_wm0[pipe] = val * 1;
+	smp->pipe_reqprio_fifo_wm1[pipe] = val * 2;
+	smp->pipe_reqprio_fifo_wm2[pipe] = val * 3;
+}
+
+/*
+ * NOTE: looks like if horizontal decimation is used (if we supported that)
+ * then the width used to calculate SMP block requirements is the post-
+ * decimated width.  Ie. SMP buffering sits downstream of decimation (which
+ * presumably happens during the dma from scanout buffer).
+ */
+uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
+		const struct mdp_format *format,
+		u32 width, bool hdecim)
+{
+	const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
+	struct mdp5_kms *mdp5_kms = get_kms(smp);
+	int rev = mdp5_cfg_get_hw_rev(mdp5_kms->cfg);
+	int i, hsub, nplanes, nlines;
+	uint32_t blkcfg = 0;
+
+	nplanes = info->num_planes;
+	hsub = info->hsub;
+
+	/* different if BWC (compressed framebuffer?) enabled: */
+	nlines = 2;
+
+	/* Newer MDPs have split/packing logic, which fetches sub-sampled
+	 * U and V components (splits them from Y if necessary) and packs
+	 * them together, writes to SMP using a single client.
+	 */
+	if ((rev > 0) && (format->chroma_sample > CHROMA_FULL)) {
+		nplanes = 2;
+
+		/* if decimation is enabled, HW decimates less on the
+		 * sub sampled chroma components
+		 */
+		if (hdecim && (hsub > 1))
+			hsub = 1;
+	}
+
+	for (i = 0; i < nplanes; i++) {
+		int n, fetch_stride, cpp;
+
+		cpp = info->cpp[i];
+		fetch_stride = width * cpp / (i ? hsub : 1);
+
+		n = DIV_ROUND_UP(fetch_stride * nlines, smp->blk_size);
+
+		/* for hw rev v1.00 */
+		if (rev == 0)
+			n = roundup_pow_of_two(n);
+
+		blkcfg |= (n << (8 * i));
+	}
+
+	return blkcfg;
+}
+
+int mdp5_smp_assign(struct mdp5_smp *smp, struct mdp5_smp_state *state,
+		enum mdp5_pipe pipe, uint32_t blkcfg)
+{
+	struct mdp5_kms *mdp5_kms = get_kms(smp);
+	struct drm_device *dev = mdp5_kms->dev;
+	int i, ret;
+
+	for (i = 0; i < pipe2nclients(pipe); i++) {
+		u32 cid = pipe2client(pipe, i);
+		int n = blkcfg & 0xff;
+
+		if (!n)
+			continue;
+
+		DBG("%s[%d]: request %d SMP blocks", pipe2name(pipe), i, n);
+		ret = smp_request_block(smp, state, cid, n);
+		if (ret) {
+			DRM_DEV_ERROR(dev->dev, "Cannot allocate %d SMP blocks: %d\n",
+					n, ret);
+			return ret;
+		}
+
+		blkcfg >>= 8;
+	}
+
+	state->assigned |= (1 << pipe);
+
+	return 0;
+}
+
+/* Release SMP blocks for all clients of the pipe */
+void mdp5_smp_release(struct mdp5_smp *smp, struct mdp5_smp_state *state,
+		enum mdp5_pipe pipe)
+{
+	int i;
+	int cnt = smp->blk_cnt;
+
+	for (i = 0; i < pipe2nclients(pipe); i++) {
+		u32 cid = pipe2client(pipe, i);
+		void *cs = state->client_state[cid];
+
+		/* update global state: */
+		bitmap_andnot(state->state, state->state, cs, cnt);
+
+		/* clear client's state */
+		bitmap_zero(cs, cnt);
+	}
+
+	state->released |= (1 << pipe);
+}
+
+/* NOTE: SMP_ALLOC_* regs are *not* double buffered, so release has to
+ * happen after scanout completes.
+ */
+static unsigned update_smp_state(struct mdp5_smp *smp,
+		u32 cid, mdp5_smp_state_t *assigned)
+{
+	int cnt = smp->blk_cnt;
+	unsigned nblks = 0;
+	u32 blk, val;
+
+	for_each_set_bit(blk, *assigned, cnt) {
+		int idx = blk / 3;
+		int fld = blk % 3;
+
+		val = smp->alloc_w[idx];
+
+		switch (fld) {
+		case 0:
+			val &= ~MDP5_SMP_ALLOC_W_REG_CLIENT0__MASK;
+			val |= MDP5_SMP_ALLOC_W_REG_CLIENT0(cid);
+			break;
+		case 1:
+			val &= ~MDP5_SMP_ALLOC_W_REG_CLIENT1__MASK;
+			val |= MDP5_SMP_ALLOC_W_REG_CLIENT1(cid);
+			break;
+		case 2:
+			val &= ~MDP5_SMP_ALLOC_W_REG_CLIENT2__MASK;
+			val |= MDP5_SMP_ALLOC_W_REG_CLIENT2(cid);
+			break;
+		}
+
+		smp->alloc_w[idx] = val;
+		smp->alloc_r[idx] = val;
+
+		nblks++;
+	}
+
+	return nblks;
+}
+
+static void write_smp_alloc_regs(struct mdp5_smp *smp)
+{
+	struct mdp5_kms *mdp5_kms = get_kms(smp);
+	int i, num_regs;
+
+	num_regs = smp->blk_cnt / 3 + 1;
+
+	for (i = 0; i < num_regs; i++) {
+		mdp5_write(mdp5_kms, REG_MDP5_SMP_ALLOC_W_REG(i),
+			   smp->alloc_w[i]);
+		mdp5_write(mdp5_kms, REG_MDP5_SMP_ALLOC_R_REG(i),
+			   smp->alloc_r[i]);
+	}
+}
+
+static void write_smp_fifo_regs(struct mdp5_smp *smp)
+{
+	struct mdp5_kms *mdp5_kms = get_kms(smp);
+	int i;
+
+	for (i = 0; i < mdp5_kms->num_hwpipes; i++) {
+		struct mdp5_hw_pipe *hwpipe = mdp5_kms->hwpipes[i];
+		enum mdp5_pipe pipe = hwpipe->pipe;
+
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_0(pipe),
+			   smp->pipe_reqprio_fifo_wm0[pipe]);
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_1(pipe),
+			   smp->pipe_reqprio_fifo_wm1[pipe]);
+		mdp5_write(mdp5_kms, REG_MDP5_PIPE_REQPRIO_FIFO_WM_2(pipe),
+			   smp->pipe_reqprio_fifo_wm2[pipe]);
+	}
+}
+
+void mdp5_smp_prepare_commit(struct mdp5_smp *smp, struct mdp5_smp_state *state)
+{
+	enum mdp5_pipe pipe;
+
+	for_each_set_bit(pipe, &state->assigned, sizeof(state->assigned) * 8) {
+		unsigned i, nblks = 0;
+
+		for (i = 0; i < pipe2nclients(pipe); i++) {
+			u32 cid = pipe2client(pipe, i);
+			void *cs = state->client_state[cid];
+
+			nblks += update_smp_state(smp, cid, cs);
+
+			DBG("assign %s:%u, %u blks",
+				pipe2name(pipe), i, nblks);
+		}
+
+		set_fifo_thresholds(smp, pipe, nblks);
+	}
+
+	write_smp_alloc_regs(smp);
+	write_smp_fifo_regs(smp);
+
+	state->assigned = 0;
+}
+
+void mdp5_smp_complete_commit(struct mdp5_smp *smp, struct mdp5_smp_state *state)
+{
+	enum mdp5_pipe pipe;
+
+	for_each_set_bit(pipe, &state->released, sizeof(state->released) * 8) {
+		DBG("release %s", pipe2name(pipe));
+		set_fifo_thresholds(smp, pipe, 0);
+	}
+
+	write_smp_fifo_regs(smp);
+
+	state->released = 0;
+}
+
+void mdp5_smp_dump(struct mdp5_smp *smp, struct drm_printer *p)
+{
+	struct mdp5_kms *mdp5_kms = get_kms(smp);
+	struct mdp5_hw_pipe_state *hwpstate;
+	struct mdp5_smp_state *state;
+	struct mdp5_global_state *global_state;
+	int total = 0, i, j;
+
+	drm_printf(p, "name\tinuse\tplane\n");
+	drm_printf(p, "----\t-----\t-----\n");
+
+	if (drm_can_sleep())
+		drm_modeset_lock(&mdp5_kms->glob_state_lock, NULL);
+
+	global_state = mdp5_get_existing_global_state(mdp5_kms);
+
+	/* grab these *after* we hold the state_lock */
+	hwpstate = &global_state->hwpipe;
+	state = &global_state->smp;
+
+	for (i = 0; i < mdp5_kms->num_hwpipes; i++) {
+		struct mdp5_hw_pipe *hwpipe = mdp5_kms->hwpipes[i];
+		struct drm_plane *plane = hwpstate->hwpipe_to_plane[hwpipe->idx];
+		enum mdp5_pipe pipe = hwpipe->pipe;
+		for (j = 0; j < pipe2nclients(pipe); j++) {
+			u32 cid = pipe2client(pipe, j);
+			void *cs = state->client_state[cid];
+			int inuse = bitmap_weight(cs, smp->blk_cnt);
+
+			drm_printf(p, "%s:%d\t%d\t%s\n",
+				pipe2name(pipe), j, inuse,
+				plane ? plane->name : "(null)");
+
+			total += inuse;
+		}
+	}
+
+	drm_printf(p, "TOTAL:\t%d\t(of %d)\n", total, smp->blk_cnt);
+	drm_printf(p, "AVAIL:\t%d\n", smp->blk_cnt -
+			bitmap_weight(state->state, smp->blk_cnt));
+
+	if (drm_can_sleep())
+		drm_modeset_unlock(&mdp5_kms->glob_state_lock);
+}
+
+
+struct mdp5_smp *mdp5_smp_init(struct mdp5_kms *mdp5_kms, const struct mdp5_smp_block *cfg)
+{
+	struct drm_device *dev = mdp5_kms->dev;
+	struct mdp5_smp_state *state;
+	struct mdp5_global_state *global_state;
+	struct mdp5_smp *smp;
+
+	smp = devm_kzalloc(dev->dev, sizeof(*smp), GFP_KERNEL);
+	if (unlikely(!smp))
+		return ERR_PTR(-ENOMEM);
+
+	smp->dev = mdp5_kms->dev;
+	smp->blk_cnt = cfg->mmb_count;
+	smp->blk_size = cfg->mmb_size;
+
+	global_state = mdp5_get_existing_global_state(mdp5_kms);
+	state = &global_state->smp;
+
+	/* statically tied MMBs cannot be re-allocated: */
+	bitmap_copy(state->state, cfg->reserved_state, smp->blk_cnt);
+	memcpy(smp->reserved, cfg->reserved, sizeof(smp->reserved));
+
+	return smp;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_smp.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp5/mdp5_smp.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __MDP5_SMP_H__
+#define __MDP5_SMP_H__
+
+#include <drm/drm_print.h>
+
+#include "msm_drv.h"
+
+/*
+ * SMP - Shared Memory Pool:
+ *
+ * SMP blocks are shared between all the clients, where each plane in
+ * a scanout buffer is a SMP client.  Ie. scanout of 3 plane I420 on
+ * pipe VIG0 => 3 clients: VIG0_Y, VIG0_CB, VIG0_CR.
+ *
+ * Based on the size of the attached scanout buffer, a certain # of
+ * blocks must be allocated to that client out of the shared pool.
+ *
+ * In some hw, some blocks are statically allocated for certain pipes
+ * and CANNOT be re-allocated (eg: MMB0 and MMB1 both tied to RGB0).
+ *
+ *
+ * Atomic SMP State:
+ *
+ * On atomic updates that modify SMP configuration, the state is cloned
+ * (copied) and modified.  For test-only, or in cases where atomic
+ * update fails (or if we hit ww_mutex deadlock/backoff condition) the
+ * new state is simply thrown away.
+ *
+ * Because the SMP registers are not double buffered, updates are a
+ * two step process:
+ *
+ * 1) in _prepare_commit() we configure things (via read-modify-write)
+ *    for the newly assigned pipes, so we don't take away blocks
+ *    assigned to pipes that are still scanning out
+ * 2) in _complete_commit(), after vblank/etc, we clear things for the
+ *    released clients, since at that point old pipes are no longer
+ *    scanning out.
+ */
+struct mdp5_smp_state {
+	/* global state of what blocks are in use: */
+	mdp5_smp_state_t state;
+
+	/* per client state of what blocks they are using: */
+	mdp5_smp_state_t client_state[MAX_CLIENTS];
+
+	/* assigned pipes (hw updated at _prepare_commit()): */
+	unsigned long assigned;
+
+	/* released pipes (hw updated at _complete_commit()): */
+	unsigned long released;
+};
+
+struct mdp5_kms;
+struct mdp5_smp;
+
+/*
+ * SMP module prototypes:
+ * mdp5_smp_init() returns a SMP @handler,
+ * which is then used to call the other mdp5_smp_*(handler, ...) functions.
+ */
+
+struct mdp5_smp *mdp5_smp_init(struct mdp5_kms *mdp5_kms,
+		const struct mdp5_smp_block *cfg);
+
+void mdp5_smp_dump(struct mdp5_smp *smp, struct drm_printer *p);
+
+uint32_t mdp5_smp_calculate(struct mdp5_smp *smp,
+		const struct mdp_format *format,
+		u32 width, bool hdecim);
+
+int mdp5_smp_assign(struct mdp5_smp *smp, struct mdp5_smp_state *state,
+		enum mdp5_pipe pipe, uint32_t blkcfg);
+void mdp5_smp_release(struct mdp5_smp *smp, struct mdp5_smp_state *state,
+		enum mdp5_pipe pipe);
+
+void mdp5_smp_prepare_commit(struct mdp5_smp *smp, struct mdp5_smp_state *state);
+void mdp5_smp_complete_commit(struct mdp5_smp *smp, struct mdp5_smp_state *state);
+
+#endif /* __MDP5_SMP_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp_format.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp_format.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
+
+#include "msm_drv.h"
+#include "mdp_kms.h"
+
+static struct csc_cfg csc_convert[CSC_MAX] = {
+	[CSC_RGB2RGB] = {
+		.type = CSC_RGB2RGB,
+		.matrix = {
+			0x0200, 0x0000, 0x0000,
+			0x0000, 0x0200, 0x0000,
+			0x0000, 0x0000, 0x0200
+		},
+		.pre_bias =	{ 0x0, 0x0, 0x0 },
+		.post_bias =	{ 0x0, 0x0, 0x0 },
+		.pre_clamp =	{ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff },
+		.post_clamp =	{ 0x0, 0xff, 0x0, 0xff, 0x0, 0xff },
+	},
+	[CSC_YUV2RGB] = {
+		.type = CSC_YUV2RGB,
+		.matrix = {
+			0x0254, 0x0000, 0x0331,
+			0x0254, 0xff37, 0xfe60,
+			0x0254, 0x0409, 0x0000
+		},
+		.pre_bias =	{ 0xfff0, 0xff80, 0xff80 },
+		.post_bias =	{ 0x00, 0x00, 0x00 },
+		.pre_clamp =	{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
+		.post_clamp =	{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
+	},
+	[CSC_RGB2YUV] = {
+		.type = CSC_RGB2YUV,
+		.matrix = {
+			0x0083, 0x0102, 0x0032,
+			0x1fb5, 0x1f6c, 0x00e1,
+			0x00e1, 0x1f45, 0x1fdc
+		},
+		.pre_bias =	{ 0x00, 0x00, 0x00 },
+		.post_bias =	{ 0x10, 0x80, 0x80 },
+		.pre_clamp =	{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
+		.post_clamp =	{ 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0 },
+	},
+	[CSC_YUV2YUV] = {
+		.type = CSC_YUV2YUV,
+		.matrix = {
+			0x0200, 0x0000, 0x0000,
+			0x0000, 0x0200, 0x0000,
+			0x0000, 0x0000, 0x0200
+		},
+		.pre_bias =	{ 0x00, 0x00, 0x00 },
+		.post_bias =	{ 0x00, 0x00, 0x00 },
+		.pre_clamp =	{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
+		.post_clamp =	{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff },
+	},
+};
+
+#define FMT(name, a, r, g, b, e0, e1, e2, e3, alpha, tight, c, cnt, fp, cs, yuv) { \
+		.base = { .pixel_format = DRM_FORMAT_ ## name }, \
+		.bpc_a = BPC ## a ## A,                          \
+		.bpc_r = BPC ## r,                               \
+		.bpc_g = BPC ## g,                               \
+		.bpc_b = BPC ## b,                               \
+		.unpack = { e0, e1, e2, e3 },                    \
+		.alpha_enable = alpha,                           \
+		.unpack_tight = tight,                           \
+		.cpp = c,                                        \
+		.unpack_count = cnt,                             \
+		.fetch_type = fp,                                \
+		.chroma_sample = cs,                             \
+		.is_yuv = yuv,                                   \
+}
+
+#define BPC0A 0
+
+/*
+ * Note: Keep RGB formats 1st, followed by YUV formats to avoid breaking
+ * mdp_get_rgb_formats()'s implementation.
+ */
+static const struct mdp_format formats[] = {
+	/*  name      a  r  g  b   e0 e1 e2 e3  alpha   tight  cpp cnt ... */
+	FMT(ARGB8888, 8, 8, 8, 8,  1, 0, 2, 3,  true,   true,  4,  4,
+			MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
+	FMT(ABGR8888, 8, 8, 8, 8,  2, 0, 1, 3,  true,   true,  4,  4,
+			MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
+	FMT(RGBA8888, 8, 8, 8, 8,  3, 1, 0, 2,  true,   true,  4,  4,
+			MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
+	FMT(BGRA8888, 8, 8, 8, 8,  3, 2, 0, 1,  true,   true,  4,  4,
+			MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
+	FMT(XRGB8888, 8, 8, 8, 8,  1, 0, 2, 3,  false,  true,  4,  4,
+			MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
+	FMT(XBGR8888, 8, 8, 8, 8,  2, 0, 1, 3,  false,   true,  4,  4,
+			MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
+	FMT(RGBX8888, 8, 8, 8, 8,  3, 1, 0, 2,  false,   true,  4,  4,
+			MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
+	FMT(BGRX8888, 8, 8, 8, 8,  3, 2, 0, 1,  false,   true,  4,  4,
+			MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
+	FMT(RGB888,   0, 8, 8, 8,  1, 0, 2, 0,  false,  true,  3,  3,
+			MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
+	FMT(BGR888,   0, 8, 8, 8,  2, 0, 1, 0,  false,  true,  3,  3,
+			MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
+	FMT(RGB565,   0, 5, 6, 5,  1, 0, 2, 0,  false,  true,  2,  3,
+			MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
+	FMT(BGR565,   0, 5, 6, 5,  2, 0, 1, 0,  false,  true,  2,  3,
+			MDP_PLANE_INTERLEAVED, CHROMA_FULL, false),
+
+	/* --- RGB formats above / YUV formats below this line --- */
+
+	/* 2 plane YUV */
+	FMT(NV12,     0, 8, 8, 8,  1, 2, 0, 0,  false,  true,  2, 2,
+			MDP_PLANE_PSEUDO_PLANAR, CHROMA_420, true),
+	FMT(NV21,     0, 8, 8, 8,  2, 1, 0, 0,  false,  true,  2, 2,
+			MDP_PLANE_PSEUDO_PLANAR, CHROMA_420, true),
+	FMT(NV16,     0, 8, 8, 8,  1, 2, 0, 0,  false,  true,  2, 2,
+			MDP_PLANE_PSEUDO_PLANAR, CHROMA_H2V1, true),
+	FMT(NV61,     0, 8, 8, 8,  2, 1, 0, 0,  false,  true,  2, 2,
+			MDP_PLANE_PSEUDO_PLANAR, CHROMA_H2V1, true),
+	/* 1 plane YUV */
+	FMT(VYUY,     0, 8, 8, 8,  2, 0, 1, 0,  false,  true,  2, 4,
+			MDP_PLANE_INTERLEAVED, CHROMA_H2V1, true),
+	FMT(UYVY,     0, 8, 8, 8,  1, 0, 2, 0,  false,  true,  2, 4,
+			MDP_PLANE_INTERLEAVED, CHROMA_H2V1, true),
+	FMT(YUYV,     0, 8, 8, 8,  0, 1, 0, 2,  false,  true,  2, 4,
+			MDP_PLANE_INTERLEAVED, CHROMA_H2V1, true),
+	FMT(YVYU,     0, 8, 8, 8,  0, 2, 0, 1,  false,  true,  2, 4,
+			MDP_PLANE_INTERLEAVED, CHROMA_H2V1, true),
+	/* 3 plane YUV */
+	FMT(YUV420,   0, 8, 8, 8,  2, 1, 0, 0,  false,  true,  1, 1,
+			MDP_PLANE_PLANAR, CHROMA_420, true),
+	FMT(YVU420,   0, 8, 8, 8,  1, 2, 0, 0,  false,  true,  1, 1,
+			MDP_PLANE_PLANAR, CHROMA_420, true),
+};
+
+/*
+ * Note:
+ * @rgb_only must be set to true, when requesting
+ * supported formats for RGB pipes.
+ */
+uint32_t mdp_get_formats(uint32_t *pixel_formats, uint32_t max_formats,
+		bool rgb_only)
+{
+	uint32_t i;
+	for (i = 0; i < ARRAY_SIZE(formats); i++) {
+		const struct mdp_format *f = &formats[i];
+
+		if (i == max_formats)
+			break;
+
+		if (rgb_only && MDP_FORMAT_IS_YUV(f))
+			break;
+
+		pixel_formats[i] = f->base.pixel_format;
+	}
+
+	return i;
+}
+
+const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format,
+		uint64_t modifier)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(formats); i++) {
+		const struct mdp_format *f = &formats[i];
+		if (f->base.pixel_format == format)
+			return &f->base;
+	}
+	return NULL;
+}
+
+struct csc_cfg *mdp_get_default_csc_cfg(enum csc_type type)
+{
+	if (WARN_ON(type >= CSC_MAX))
+		return NULL;
+
+	return &csc_convert[type];
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp_kms.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp_kms.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+
+#include "msm_drv.h"
+#include "mdp_kms.h"
+
+
+struct mdp_irq_wait {
+	struct mdp_irq irq;
+	int count;
+};
+
+static DECLARE_WAIT_QUEUE_HEAD(wait_event);
+
+static DEFINE_SPINLOCK(list_lock);
+
+static void update_irq(struct mdp_kms *mdp_kms)
+{
+	struct mdp_irq *irq;
+	uint32_t irqmask = mdp_kms->vblank_mask;
+
+	assert_spin_locked(&list_lock);
+
+	list_for_each_entry(irq, &mdp_kms->irq_list, node)
+		irqmask |= irq->irqmask;
+
+	mdp_kms->funcs->set_irqmask(mdp_kms, irqmask, mdp_kms->cur_irq_mask);
+	mdp_kms->cur_irq_mask = irqmask;
+}
+
+/* if an mdp_irq's irqmask has changed, such as when mdp5 crtc<->encoder
+ * link changes, this must be called to figure out the new global irqmask
+ */
+void mdp_irq_update(struct mdp_kms *mdp_kms)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&list_lock, flags);
+	update_irq(mdp_kms);
+	spin_unlock_irqrestore(&list_lock, flags);
+}
+
+void mdp_dispatch_irqs(struct mdp_kms *mdp_kms, uint32_t status)
+{
+	struct mdp_irq *handler, *n;
+	unsigned long flags;
+
+	spin_lock_irqsave(&list_lock, flags);
+	mdp_kms->in_irq = true;
+	list_for_each_entry_safe(handler, n, &mdp_kms->irq_list, node) {
+		if (handler->irqmask & status) {
+			spin_unlock_irqrestore(&list_lock, flags);
+			handler->irq(handler, handler->irqmask & status);
+			spin_lock_irqsave(&list_lock, flags);
+		}
+	}
+	mdp_kms->in_irq = false;
+	update_irq(mdp_kms);
+	spin_unlock_irqrestore(&list_lock, flags);
+
+}
+
+void mdp_update_vblank_mask(struct mdp_kms *mdp_kms, uint32_t mask, bool enable)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&list_lock, flags);
+	if (enable)
+		mdp_kms->vblank_mask |= mask;
+	else
+		mdp_kms->vblank_mask &= ~mask;
+	update_irq(mdp_kms);
+	spin_unlock_irqrestore(&list_lock, flags);
+}
+
+static void wait_irq(struct mdp_irq *irq, uint32_t irqstatus)
+{
+	struct mdp_irq_wait *wait =
+			container_of(irq, struct mdp_irq_wait, irq);
+	wait->count--;
+	wake_up_all(&wait_event);
+}
+
+void mdp_irq_wait(struct mdp_kms *mdp_kms, uint32_t irqmask)
+{
+	struct mdp_irq_wait wait = {
+		.irq = {
+			.irq = wait_irq,
+			.irqmask = irqmask,
+		},
+		.count = 1,
+	};
+	mdp_irq_register(mdp_kms, &wait.irq);
+	wait_event_timeout(wait_event, (wait.count <= 0),
+			msecs_to_jiffies(100));
+	mdp_irq_unregister(mdp_kms, &wait.irq);
+}
+
+void mdp_irq_register(struct mdp_kms *mdp_kms, struct mdp_irq *irq)
+{
+	unsigned long flags;
+	bool needs_update = false;
+
+	spin_lock_irqsave(&list_lock, flags);
+
+	if (!irq->registered) {
+		irq->registered = true;
+		list_add(&irq->node, &mdp_kms->irq_list);
+		needs_update = !mdp_kms->in_irq;
+	}
+
+	spin_unlock_irqrestore(&list_lock, flags);
+
+	if (needs_update)
+		mdp_irq_update(mdp_kms);
+}
+
+void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq)
+{
+	unsigned long flags;
+	bool needs_update = false;
+
+	spin_lock_irqsave(&list_lock, flags);
+
+	if (irq->registered) {
+		irq->registered = false;
+		list_del(&irq->node);
+		needs_update = !mdp_kms->in_irq;
+	}
+
+	spin_unlock_irqrestore(&list_lock, flags);
+
+	if (needs_update)
+		mdp_irq_update(mdp_kms);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/mdp_kms.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/mdp_kms.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __MDP_KMS_H__
+#define __MDP_KMS_H__
+
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#include "msm_drv.h"
+#include "msm_kms.h"
+#include "mdp_common.xml.h"
+
+struct mdp_kms;
+
+struct mdp_kms_funcs {
+	struct msm_kms_funcs base;
+	void (*set_irqmask)(struct mdp_kms *mdp_kms, uint32_t irqmask,
+		uint32_t old_irqmask);
+};
+
+struct mdp_kms {
+	struct msm_kms base;
+
+	const struct mdp_kms_funcs *funcs;
+
+	/* irq handling: */
+	bool in_irq;
+	struct list_head irq_list;    /* list of mdp4_irq */
+	uint32_t vblank_mask;         /* irq bits set for userspace vblank */
+	uint32_t cur_irq_mask;        /* current irq mask */
+};
+#define to_mdp_kms(x) container_of(x, struct mdp_kms, base)
+
+static inline int mdp_kms_init(struct mdp_kms *mdp_kms,
+		const struct mdp_kms_funcs *funcs)
+{
+	mdp_kms->funcs = funcs;
+	INIT_LIST_HEAD(&mdp_kms->irq_list);
+	return msm_kms_init(&mdp_kms->base, &funcs->base);
+}
+
+static inline void mdp_kms_destroy(struct mdp_kms *mdp_kms)
+{
+	msm_kms_destroy(&mdp_kms->base);
+}
+
+/*
+ * irq helpers:
+ */
+
+/* For transiently registering for different MDP irqs that various parts
+ * of the KMS code need during setup/configuration.  These are not
+ * necessarily the same as what drm_vblank_get/put() are requesting, and
+ * the hysteresis in drm_vblank_put() is not necessarily desirable for
+ * internal housekeeping related irq usage.
+ */
+struct mdp_irq {
+	struct list_head node;
+	uint32_t irqmask;
+	bool registered;
+	void (*irq)(struct mdp_irq *irq, uint32_t irqstatus);
+};
+
+void mdp_dispatch_irqs(struct mdp_kms *mdp_kms, uint32_t status);
+void mdp_update_vblank_mask(struct mdp_kms *mdp_kms, uint32_t mask, bool enable);
+void mdp_irq_wait(struct mdp_kms *mdp_kms, uint32_t irqmask);
+void mdp_irq_register(struct mdp_kms *mdp_kms, struct mdp_irq *irq);
+void mdp_irq_unregister(struct mdp_kms *mdp_kms, struct mdp_irq *irq);
+void mdp_irq_update(struct mdp_kms *mdp_kms);
+
+/*
+ * pixel format helpers:
+ */
+
+struct mdp_format {
+	struct msm_format base;
+	enum mdp_bpc bpc_r, bpc_g, bpc_b;
+	enum mdp_bpc_alpha bpc_a;
+	uint8_t unpack[4];
+	bool alpha_enable, unpack_tight;
+	uint8_t cpp, unpack_count;
+	enum mdp_fetch_type fetch_type;
+	enum mdp_chroma_samp_type chroma_sample;
+	bool is_yuv;
+};
+#define to_mdp_format(x) container_of(x, struct mdp_format, base)
+#define MDP_FORMAT_IS_YUV(mdp_format) ((mdp_format)->is_yuv)
+
+uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats, bool rgb_only);
+const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format, uint64_t modifier);
+
+/* MDP capabilities */
+#define MDP_CAP_SMP		BIT(0)	/* Shared Memory Pool                 */
+#define MDP_CAP_DSC		BIT(1)	/* VESA Display Stream Compression    */
+#define MDP_CAP_CDM		BIT(2)	/* Chroma Down Module (HDMI 2.0 YUV)  */
+#define MDP_CAP_SRC_SPLIT	BIT(3)	/* Source Split of SSPPs */
+
+/* MDP pipe capabilities */
+#define MDP_PIPE_CAP_HFLIP			BIT(0)
+#define MDP_PIPE_CAP_VFLIP			BIT(1)
+#define MDP_PIPE_CAP_SCALE			BIT(2)
+#define MDP_PIPE_CAP_CSC			BIT(3)
+#define MDP_PIPE_CAP_DECIMATION			BIT(4)
+#define MDP_PIPE_CAP_SW_PIX_EXT			BIT(5)
+#define MDP_PIPE_CAP_CURSOR			BIT(6)
+
+/* MDP layer mixer caps */
+#define MDP_LM_CAP_DISPLAY			BIT(0)
+#define MDP_LM_CAP_WB				BIT(1)
+#define MDP_LM_CAP_PAIR				BIT(2)
+
+static inline bool pipe_supports_yuv(uint32_t pipe_caps)
+{
+	return (pipe_caps & MDP_PIPE_CAP_SCALE) &&
+		(pipe_caps & MDP_PIPE_CAP_CSC);
+}
+
+enum csc_type {
+	CSC_RGB2RGB = 0,
+	CSC_YUV2RGB,
+	CSC_RGB2YUV,
+	CSC_YUV2YUV,
+	CSC_MAX
+};
+
+struct csc_cfg {
+	enum csc_type type;
+	uint32_t matrix[9];
+	uint32_t pre_bias[3];
+	uint32_t post_bias[3];
+	uint32_t pre_clamp[6];
+	uint32_t post_clamp[6];
+};
+
+struct csc_cfg *mdp_get_default_csc_cfg(enum csc_type);
+
+#endif /* __MDP_KMS_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/msm_disp_snapshot.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/msm_disp_snapshot.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+
+#include "msm_disp_snapshot.h"
+
+static ssize_t __maybe_unused disp_devcoredump_read(char *buffer, loff_t offset,
+		size_t count, void *data, size_t datalen)
+{
+	struct drm_print_iterator iter;
+	struct drm_printer p;
+	struct msm_disp_state *disp_state;
+
+	disp_state = data;
+
+	iter.data = buffer;
+	iter.offset = 0;
+	iter.start = offset;
+	iter.remain = count;
+
+	p = drm_coredump_printer(&iter);
+
+	msm_disp_state_print(disp_state, &p);
+
+	return count - iter.remain;
+}
+
+struct msm_disp_state *
+msm_disp_snapshot_state_sync(struct msm_kms *kms)
+{
+	struct drm_device *drm_dev = kms->dev;
+	struct msm_disp_state *disp_state;
+
+	WARN_ON(!mutex_is_locked(&kms->dump_mutex));
+
+	disp_state = kzalloc(sizeof(struct msm_disp_state), GFP_KERNEL);
+	if (!disp_state)
+		return ERR_PTR(-ENOMEM);
+
+	disp_state->dev = drm_dev->dev;
+	disp_state->drm_dev = drm_dev;
+
+	INIT_LIST_HEAD(&disp_state->blocks);
+
+	msm_disp_snapshot_capture_state(disp_state);
+
+	return disp_state;
+}
+
+static void _msm_disp_snapshot_work(struct kthread_work *work)
+{
+	struct msm_kms *kms = container_of(work, struct msm_kms, dump_work);
+	struct msm_disp_state *disp_state;
+	struct drm_printer p;
+
+	/* Serialize dumping here */
+	mutex_lock(&kms->dump_mutex);
+	disp_state = msm_disp_snapshot_state_sync(kms);
+	mutex_unlock(&kms->dump_mutex);
+
+	if (IS_ERR(disp_state))
+		return;
+
+	if (MSM_DISP_SNAPSHOT_DUMP_IN_CONSOLE) {
+		p = drm_info_printer(disp_state->drm_dev->dev);
+		msm_disp_state_print(disp_state, &p);
+	}
+
+	/*
+	 * If COREDUMP is disabled, the stub will call the free function.
+	 * If there is a codedump pending for the device, the dev_coredumpm()
+	 * will also free new coredump state.
+	 */
+	dev_coredumpm(disp_state->dev, THIS_MODULE, disp_state, 0, GFP_KERNEL,
+			disp_devcoredump_read, msm_disp_state_free);
+}
+
+void msm_disp_snapshot_state(struct drm_device *drm_dev)
+{
+	struct msm_drm_private *priv;
+	struct msm_kms *kms;
+
+	if (!drm_dev) {
+		DRM_ERROR("invalid params\n");
+		return;
+	}
+
+	priv = drm_dev->dev_private;
+	kms = priv->kms;
+
+	kthread_queue_work(kms->dump_worker, &kms->dump_work);
+}
+
+int msm_disp_snapshot_init(struct drm_device *drm_dev)
+{
+	struct msm_drm_private *priv;
+	struct msm_kms *kms;
+
+	if (!drm_dev) {
+		DRM_ERROR("invalid params\n");
+		return -EINVAL;
+	}
+
+	priv = drm_dev->dev_private;
+	kms = priv->kms;
+
+	mutex_init(&kms->dump_mutex);
+
+	kms->dump_worker = kthread_create_worker(0, "%s", "disp_snapshot");
+	if (IS_ERR(kms->dump_worker))
+		DRM_ERROR("failed to create disp state task\n");
+
+	kthread_init_work(&kms->dump_work, _msm_disp_snapshot_work);
+
+	return 0;
+}
+
+void msm_disp_snapshot_destroy(struct drm_device *drm_dev)
+{
+	struct msm_kms *kms;
+	struct msm_drm_private *priv;
+
+	if (!drm_dev) {
+		DRM_ERROR("invalid params\n");
+		return;
+	}
+
+	priv = drm_dev->dev_private;
+	kms = priv->kms;
+
+	if (kms->dump_worker)
+		kthread_destroy_worker(kms->dump_worker);
+
+	mutex_destroy(&kms->dump_mutex);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/msm_disp_snapshot.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/msm_disp_snapshot.h
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef MSM_DISP_SNAPSHOT_H_
+#define MSM_DISP_SNAPSHOT_H_
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_device.h>
+#include "../../../drm_crtc_internal.h"
+#include <drm/drm_print.h>
+#include <drm/drm_atomic.h>
+#include <linux/debugfs.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/ktime.h>
+#include <linux/uaccess.h>
+#include <linux/dma-buf.h>
+#include <linux/slab.h>
+#include <linux/list_sort.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/kthread.h>
+#include <linux/devcoredump.h>
+#include "msm_kms.h"
+
+#define MSM_DISP_SNAPSHOT_MAX_BLKS		10
+
+/* debug option to print the registers in logs */
+#define MSM_DISP_SNAPSHOT_DUMP_IN_CONSOLE 0
+
+/* print debug ranges in groups of 4 u32s */
+#define REG_DUMP_ALIGN		16
+
+/**
+ * struct msm_disp_state - structure to store current dpu state
+ * @dev: device pointer
+ * @drm_dev: drm device pointer
+ * @atomic_state: atomic state duplicated at the time of the error
+ * @time: timestamp at which the coredump was captured
+ */
+struct msm_disp_state {
+	struct device *dev;
+	struct drm_device *drm_dev;
+
+	struct list_head blocks;
+
+	struct drm_atomic_state *atomic_state;
+
+	struct timespec64 time;
+};
+
+/**
+ * struct msm_disp_state_block - structure to store each hardware block state
+ * @name: name of the block
+ * @drm_dev: handle to the linked list head
+ * @size: size of the register space of this hardware block
+ * @state: array holding the register dump of this hardware block
+ * @base_addr: starting address of this hardware block's register space
+ */
+struct msm_disp_state_block {
+	char name[SZ_128];
+	struct list_head node;
+	unsigned int size;
+	u32 *state;
+	void __iomem *base_addr;
+};
+
+/**
+ * msm_disp_snapshot_init - initialize display snapshot
+ * @drm_dev:	drm device handle
+ *
+ * Returns:		0 or -ERROR
+ */
+int msm_disp_snapshot_init(struct drm_device *drm_dev);
+
+/**
+ * msm_disp_snapshot_destroy - destroy the display snapshot
+ * @drm_dev:    drm device handle
+ *
+ * Returns:	none
+ */
+void msm_disp_snapshot_destroy(struct drm_device *drm_dev);
+
+/**
+ * msm_disp_snapshot_state_sync - synchronously snapshot display state
+ * @kms:  the kms object
+ *
+ * Returns state or error
+ *
+ * Must be called with &kms->dump_mutex held
+ */
+struct msm_disp_state *msm_disp_snapshot_state_sync(struct msm_kms *kms);
+
+/**
+ * msm_disp_snapshot_state - trigger to dump the display snapshot
+ * @drm_dev:	handle to drm device
+
+ * Returns:	none
+ */
+void msm_disp_snapshot_state(struct drm_device *drm_dev);
+
+/**
+ * msm_disp_state_print - print out the current dpu state
+ * @disp_state:	    handle to drm device
+ * @p:	    handle to drm printer
+ *
+ * Returns:	none
+ */
+void msm_disp_state_print(struct msm_disp_state *disp_state, struct drm_printer *p);
+
+/**
+ * msm_disp_snapshot_capture_state - utility to capture atomic state and hw registers
+ * @disp_state:	    handle to msm_disp_state struct
+
+ * Returns:	none
+ */
+void msm_disp_snapshot_capture_state(struct msm_disp_state *disp_state);
+
+/**
+ * msm_disp_state_free - free the memory after the coredump has been read
+ * @data:	    handle to struct msm_disp_state
+
+ * Returns: none
+ */
+void msm_disp_state_free(void *data);
+
+/**
+ * msm_disp_snapshot_add_block - add a hardware block with its register dump
+ * @disp_state:	    handle to struct msm_disp_state
+ * @name:           name of the hardware block
+ * @len:            size of the register space of the hardware block
+ * @base_addr:      starting address of the register space of the hardware block
+ * @fmt:            format in which the block names need to be printed
+ *
+ * Returns: none
+ */
+__printf(4, 5)
+void msm_disp_snapshot_add_block(struct msm_disp_state *disp_state, u32 len,
+		void __iomem *base_addr, const char *fmt, ...);
+
+#endif /* MSM_DISP_SNAPSHOT_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/disp/msm_disp_snapshot_util.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/disp/msm_disp_snapshot_util.c
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
+
+#include <generated/utsrelease.h>
+
+#include "msm_disp_snapshot.h"
+
+static void msm_disp_state_dump_regs(u32 **reg, u32 aligned_len, void __iomem *base_addr)
+{
+	u32 len_padded;
+	u32 num_rows;
+	u32 x0, x4, x8, xc;
+	void __iomem *addr;
+	u32 *dump_addr = NULL;
+	void __iomem *end_addr;
+	int i;
+
+	len_padded = aligned_len * REG_DUMP_ALIGN;
+	num_rows = aligned_len / REG_DUMP_ALIGN;
+
+	addr = base_addr;
+	end_addr = base_addr + aligned_len;
+
+	if (!(*reg))
+		*reg = kzalloc(len_padded, GFP_KERNEL);
+
+	if (*reg)
+		dump_addr = *reg;
+
+	for (i = 0; i < num_rows; i++) {
+		x0 = (addr < end_addr) ? readl_relaxed(addr + 0x0) : 0;
+		x4 = (addr + 0x4 < end_addr) ? readl_relaxed(addr + 0x4) : 0;
+		x8 = (addr + 0x8 < end_addr) ? readl_relaxed(addr + 0x8) : 0;
+		xc = (addr + 0xc < end_addr) ? readl_relaxed(addr + 0xc) : 0;
+
+		if (dump_addr) {
+			dump_addr[i * 4] = x0;
+			dump_addr[i * 4 + 1] = x4;
+			dump_addr[i * 4 + 2] = x8;
+			dump_addr[i * 4 + 3] = xc;
+		}
+
+		addr += REG_DUMP_ALIGN;
+	}
+}
+
+static void msm_disp_state_print_regs(u32 **reg, u32 len, void __iomem *base_addr,
+		struct drm_printer *p)
+{
+	int i;
+	u32 *dump_addr = NULL;
+	void __iomem *addr;
+	u32 num_rows;
+
+	addr = base_addr;
+	num_rows = len / REG_DUMP_ALIGN;
+
+	if (*reg)
+		dump_addr = *reg;
+
+	for (i = 0; i < num_rows; i++) {
+		drm_printf(p, "0x%lx : %08x %08x %08x %08x\n",
+				(unsigned long)(addr - base_addr),
+				dump_addr[i * 4], dump_addr[i * 4 + 1],
+				dump_addr[i * 4 + 2], dump_addr[i * 4 + 3]);
+		addr += REG_DUMP_ALIGN;
+	}
+}
+
+void msm_disp_state_print(struct msm_disp_state *state, struct drm_printer *p)
+{
+	struct msm_disp_state_block *block, *tmp;
+
+	if (!p) {
+		DRM_ERROR("invalid drm printer\n");
+		return;
+	}
+
+	drm_printf(p, "---\n");
+	drm_printf(p, "kernel: " UTS_RELEASE "\n");
+	drm_printf(p, "module: " KBUILD_MODNAME "\n");
+	drm_printf(p, "dpu devcoredump\n");
+	drm_printf(p, "time: %lld.%09ld\n",
+		state->time.tv_sec, state->time.tv_nsec);
+
+	list_for_each_entry_safe(block, tmp, &state->blocks, node) {
+		drm_printf(p, "====================%s================\n", block->name);
+		msm_disp_state_print_regs(&block->state, block->size, block->base_addr, p);
+	}
+
+	drm_printf(p, "===================dpu drm state================\n");
+
+	if (state->atomic_state)
+		drm_atomic_print_new_state(state->atomic_state, p);
+}
+
+static void msm_disp_capture_atomic_state(struct msm_disp_state *disp_state)
+{
+	struct drm_device *ddev;
+	struct drm_modeset_acquire_ctx ctx;
+
+	ktime_get_real_ts64(&disp_state->time);
+
+	ddev = disp_state->drm_dev;
+
+	drm_modeset_acquire_init(&ctx, 0);
+
+	while (drm_modeset_lock_all_ctx(ddev, &ctx) != 0)
+		drm_modeset_backoff(&ctx);
+
+	disp_state->atomic_state = drm_atomic_helper_duplicate_state(ddev,
+			&ctx);
+	drm_modeset_drop_locks(&ctx);
+	drm_modeset_acquire_fini(&ctx);
+}
+
+void msm_disp_snapshot_capture_state(struct msm_disp_state *disp_state)
+{
+	struct msm_drm_private *priv;
+	struct drm_device *drm_dev;
+	struct msm_kms *kms;
+	int i;
+
+	drm_dev = disp_state->drm_dev;
+	priv = drm_dev->dev_private;
+	kms = priv->kms;
+
+	for (i = 0; i < ARRAY_SIZE(priv->dp); i++) {
+		if (!priv->dp[i])
+			continue;
+
+		msm_dp_snapshot(disp_state, priv->dp[i]);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(priv->dsi); i++) {
+		if (!priv->dsi[i])
+			continue;
+
+		msm_dsi_snapshot(disp_state, priv->dsi[i]);
+	}
+
+	if (kms->funcs->snapshot)
+		kms->funcs->snapshot(disp_state, kms);
+
+	msm_disp_capture_atomic_state(disp_state);
+}
+
+void msm_disp_state_free(void *data)
+{
+	struct msm_disp_state *disp_state = data;
+	struct msm_disp_state_block *block, *tmp;
+
+	if (disp_state->atomic_state) {
+		drm_atomic_state_put(disp_state->atomic_state);
+		disp_state->atomic_state = NULL;
+	}
+
+	list_for_each_entry_safe(block, tmp, &disp_state->blocks, node) {
+		list_del(&block->node);
+		kfree(block->state);
+		kfree(block);
+	}
+
+	kfree(disp_state);
+}
+
+void msm_disp_snapshot_add_block(struct msm_disp_state *disp_state, u32 len,
+		void __iomem *base_addr, const char *fmt, ...)
+{
+	struct msm_disp_state_block *new_blk;
+	struct va_format vaf;
+	va_list va;
+
+	new_blk = kzalloc(sizeof(struct msm_disp_state_block), GFP_KERNEL);
+	if (!new_blk)
+		return;
+
+	va_start(va, fmt);
+
+	vaf.fmt = fmt;
+	vaf.va = &va;
+	snprintf(new_blk->name, sizeof(new_blk->name), "%pV", &vaf);
+
+	va_end(va);
+
+	INIT_LIST_HEAD(&new_blk->node);
+	new_blk->size = ALIGN(len, REG_DUMP_ALIGN);
+	new_blk->base_addr = base_addr;
+
+	msm_disp_state_dump_regs(&new_blk->state, new_blk->size, base_addr);
+	list_add_tail(&new_blk->node, &disp_state->blocks);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_audio.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_audio.c
@@ -0,0 +1,581 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ */
+
+
+#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
+
+#include <linux/platform_device.h>
+
+#include <drm/display/drm_dp_helper.h>
+#include <drm/drm_edid.h>
+
+#include "dp_catalog.h"
+#include "dp_audio.h"
+#include "dp_panel.h"
+#include "dp_display.h"
+#include "dp_utils.h"
+
+struct msm_dp_audio_private {
+	struct platform_device *audio_pdev;
+	struct platform_device *pdev;
+	struct drm_device *drm_dev;
+	struct msm_dp_catalog *catalog;
+
+	u32 channels;
+
+	struct msm_dp_audio msm_dp_audio;
+};
+
+static u32 msm_dp_audio_get_header(struct msm_dp_catalog *catalog,
+		enum msm_dp_catalog_audio_sdp_type sdp,
+		enum msm_dp_catalog_audio_header_type header)
+{
+	return msm_dp_catalog_audio_get_header(catalog, sdp, header);
+}
+
+static void msm_dp_audio_set_header(struct msm_dp_catalog *catalog,
+		u32 data,
+		enum msm_dp_catalog_audio_sdp_type sdp,
+		enum msm_dp_catalog_audio_header_type header)
+{
+	msm_dp_catalog_audio_set_header(catalog, sdp, header, data);
+}
+
+static void msm_dp_audio_stream_sdp(struct msm_dp_audio_private *audio)
+{
+	struct msm_dp_catalog *catalog = audio->catalog;
+	u32 value, new_value;
+	u8 parity_byte;
+
+	/* Config header and parity byte 1 */
+	value = msm_dp_audio_get_header(catalog,
+			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
+
+	new_value = 0x02;
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
+	value |= ((new_value << HEADER_BYTE_1_BIT)
+			| (parity_byte << PARITY_BYTE_1_BIT));
+	drm_dbg_dp(audio->drm_dev,
+			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
+			value, parity_byte);
+	msm_dp_audio_set_header(catalog, value,
+		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_1);
+
+	/* Config header and parity byte 2 */
+	value = msm_dp_audio_get_header(catalog,
+			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
+	new_value = value;
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
+	value |= ((new_value << HEADER_BYTE_2_BIT)
+			| (parity_byte << PARITY_BYTE_2_BIT));
+	drm_dbg_dp(audio->drm_dev,
+			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
+			value, parity_byte);
+
+	msm_dp_audio_set_header(catalog, value,
+		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_2);
+
+	/* Config header and parity byte 3 */
+	value = msm_dp_audio_get_header(catalog,
+			DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
+
+	new_value = audio->channels - 1;
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
+	value |= ((new_value << HEADER_BYTE_3_BIT)
+			| (parity_byte << PARITY_BYTE_3_BIT));
+	drm_dbg_dp(audio->drm_dev,
+			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
+		value, parity_byte);
+
+	msm_dp_audio_set_header(catalog, value,
+		DP_AUDIO_SDP_STREAM, DP_AUDIO_SDP_HEADER_3);
+}
+
+static void msm_dp_audio_timestamp_sdp(struct msm_dp_audio_private *audio)
+{
+	struct msm_dp_catalog *catalog = audio->catalog;
+	u32 value, new_value;
+	u8 parity_byte;
+
+	/* Config header and parity byte 1 */
+	value = msm_dp_audio_get_header(catalog,
+			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
+
+	new_value = 0x1;
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
+	value |= ((new_value << HEADER_BYTE_1_BIT)
+			| (parity_byte << PARITY_BYTE_1_BIT));
+	drm_dbg_dp(audio->drm_dev,
+			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
+			value, parity_byte);
+	msm_dp_audio_set_header(catalog, value,
+		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_1);
+
+	/* Config header and parity byte 2 */
+	value = msm_dp_audio_get_header(catalog,
+			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
+
+	new_value = 0x17;
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
+	value |= ((new_value << HEADER_BYTE_2_BIT)
+			| (parity_byte << PARITY_BYTE_2_BIT));
+	drm_dbg_dp(audio->drm_dev,
+			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
+			value, parity_byte);
+	msm_dp_audio_set_header(catalog, value,
+		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_2);
+
+	/* Config header and parity byte 3 */
+	value = msm_dp_audio_get_header(catalog,
+			DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
+
+	new_value = (0x0 | (0x11 << 2));
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
+	value |= ((new_value << HEADER_BYTE_3_BIT)
+			| (parity_byte << PARITY_BYTE_3_BIT));
+	drm_dbg_dp(audio->drm_dev,
+			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
+			value, parity_byte);
+	msm_dp_audio_set_header(catalog, value,
+		DP_AUDIO_SDP_TIMESTAMP, DP_AUDIO_SDP_HEADER_3);
+}
+
+static void msm_dp_audio_infoframe_sdp(struct msm_dp_audio_private *audio)
+{
+	struct msm_dp_catalog *catalog = audio->catalog;
+	u32 value, new_value;
+	u8 parity_byte;
+
+	/* Config header and parity byte 1 */
+	value = msm_dp_audio_get_header(catalog,
+			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
+
+	new_value = 0x84;
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
+	value |= ((new_value << HEADER_BYTE_1_BIT)
+			| (parity_byte << PARITY_BYTE_1_BIT));
+	drm_dbg_dp(audio->drm_dev,
+			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
+			value, parity_byte);
+	msm_dp_audio_set_header(catalog, value,
+		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_1);
+
+	/* Config header and parity byte 2 */
+	value = msm_dp_audio_get_header(catalog,
+			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
+
+	new_value = 0x1b;
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
+	value |= ((new_value << HEADER_BYTE_2_BIT)
+			| (parity_byte << PARITY_BYTE_2_BIT));
+	drm_dbg_dp(audio->drm_dev,
+			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
+			value, parity_byte);
+	msm_dp_audio_set_header(catalog, value,
+		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_2);
+
+	/* Config header and parity byte 3 */
+	value = msm_dp_audio_get_header(catalog,
+			DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
+
+	new_value = (0x0 | (0x11 << 2));
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
+	value |= ((new_value << HEADER_BYTE_3_BIT)
+			| (parity_byte << PARITY_BYTE_3_BIT));
+	drm_dbg_dp(audio->drm_dev,
+			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
+			new_value, parity_byte);
+	msm_dp_audio_set_header(catalog, value,
+		DP_AUDIO_SDP_INFOFRAME, DP_AUDIO_SDP_HEADER_3);
+}
+
+static void msm_dp_audio_copy_management_sdp(struct msm_dp_audio_private *audio)
+{
+	struct msm_dp_catalog *catalog = audio->catalog;
+	u32 value, new_value;
+	u8 parity_byte;
+
+	/* Config header and parity byte 1 */
+	value = msm_dp_audio_get_header(catalog,
+			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
+
+	new_value = 0x05;
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
+	value |= ((new_value << HEADER_BYTE_1_BIT)
+			| (parity_byte << PARITY_BYTE_1_BIT));
+	drm_dbg_dp(audio->drm_dev,
+			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
+			value, parity_byte);
+	msm_dp_audio_set_header(catalog, value,
+		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_1);
+
+	/* Config header and parity byte 2 */
+	value = msm_dp_audio_get_header(catalog,
+			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
+
+	new_value = 0x0F;
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
+	value |= ((new_value << HEADER_BYTE_2_BIT)
+			| (parity_byte << PARITY_BYTE_2_BIT));
+	drm_dbg_dp(audio->drm_dev,
+			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
+			value, parity_byte);
+	msm_dp_audio_set_header(catalog, value,
+		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_2);
+
+	/* Config header and parity byte 3 */
+	value = msm_dp_audio_get_header(catalog,
+			DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
+
+	new_value = 0x0;
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
+	value |= ((new_value << HEADER_BYTE_3_BIT)
+			| (parity_byte << PARITY_BYTE_3_BIT));
+	drm_dbg_dp(audio->drm_dev,
+			"Header Byte 3: value = 0x%x, parity_byte = 0x%x\n",
+			value, parity_byte);
+	msm_dp_audio_set_header(catalog, value,
+		DP_AUDIO_SDP_COPYMANAGEMENT, DP_AUDIO_SDP_HEADER_3);
+}
+
+static void msm_dp_audio_isrc_sdp(struct msm_dp_audio_private *audio)
+{
+	struct msm_dp_catalog *catalog = audio->catalog;
+	u32 value, new_value;
+	u8 parity_byte;
+
+	/* Config header and parity byte 1 */
+	value = msm_dp_audio_get_header(catalog,
+			DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
+
+	new_value = 0x06;
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
+	value |= ((new_value << HEADER_BYTE_1_BIT)
+			| (parity_byte << PARITY_BYTE_1_BIT));
+	drm_dbg_dp(audio->drm_dev,
+			"Header Byte 1: value = 0x%x, parity_byte = 0x%x\n",
+			value, parity_byte);
+	msm_dp_audio_set_header(catalog, value,
+		DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_1);
+
+	/* Config header and parity byte 2 */
+	value = msm_dp_audio_get_header(catalog,
+			DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
+
+	new_value = 0x0F;
+	parity_byte = msm_dp_utils_calculate_parity(new_value);
+	value |= ((new_value << HEADER_BYTE_2_BIT)
+			| (parity_byte << PARITY_BYTE_2_BIT));
+	drm_dbg_dp(audio->drm_dev,
+			"Header Byte 2: value = 0x%x, parity_byte = 0x%x\n",
+			value, parity_byte);
+	msm_dp_audio_set_header(catalog, value,
+		DP_AUDIO_SDP_ISRC, DP_AUDIO_SDP_HEADER_2);
+}
+
+static void msm_dp_audio_setup_sdp(struct msm_dp_audio_private *audio)
+{
+	msm_dp_catalog_audio_config_sdp(audio->catalog);
+
+	msm_dp_audio_stream_sdp(audio);
+	msm_dp_audio_timestamp_sdp(audio);
+	msm_dp_audio_infoframe_sdp(audio);
+	msm_dp_audio_copy_management_sdp(audio);
+	msm_dp_audio_isrc_sdp(audio);
+}
+
+static void msm_dp_audio_setup_acr(struct msm_dp_audio_private *audio)
+{
+	u32 select = 0;
+	struct msm_dp_catalog *catalog = audio->catalog;
+
+	switch (audio->msm_dp_audio.bw_code) {
+	case DP_LINK_BW_1_62:
+		select = 0;
+		break;
+	case DP_LINK_BW_2_7:
+		select = 1;
+		break;
+	case DP_LINK_BW_5_4:
+		select = 2;
+		break;
+	case DP_LINK_BW_8_1:
+		select = 3;
+		break;
+	default:
+		drm_dbg_dp(audio->drm_dev, "Unknown link rate\n");
+		select = 0;
+		break;
+	}
+
+	msm_dp_catalog_audio_config_acr(catalog, select);
+}
+
+static void msm_dp_audio_safe_to_exit_level(struct msm_dp_audio_private *audio)
+{
+	struct msm_dp_catalog *catalog = audio->catalog;
+	u32 safe_to_exit_level = 0;
+
+	switch (audio->msm_dp_audio.lane_count) {
+	case 1:
+		safe_to_exit_level = 14;
+		break;
+	case 2:
+		safe_to_exit_level = 8;
+		break;
+	case 4:
+		safe_to_exit_level = 5;
+		break;
+	default:
+		drm_dbg_dp(audio->drm_dev,
+				"setting the default safe_to_exit_level = %u\n",
+				safe_to_exit_level);
+		safe_to_exit_level = 14;
+		break;
+	}
+
+	msm_dp_catalog_audio_sfe_level(catalog, safe_to_exit_level);
+}
+
+static void msm_dp_audio_enable(struct msm_dp_audio_private *audio, bool enable)
+{
+	struct msm_dp_catalog *catalog = audio->catalog;
+
+	msm_dp_catalog_audio_enable(catalog, enable);
+}
+
+static struct msm_dp_audio_private *msm_dp_audio_get_data(struct platform_device *pdev)
+{
+	struct msm_dp_audio *msm_dp_audio;
+	struct msm_dp *msm_dp_display;
+
+	if (!pdev) {
+		DRM_ERROR("invalid input\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	msm_dp_display = platform_get_drvdata(pdev);
+	if (!msm_dp_display) {
+		DRM_ERROR("invalid input\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	msm_dp_audio = msm_dp_display->msm_dp_audio;
+
+	if (!msm_dp_audio) {
+		DRM_ERROR("invalid msm_dp_audio data\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	return container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio);
+}
+
+static int msm_dp_audio_hook_plugged_cb(struct device *dev, void *data,
+		hdmi_codec_plugged_cb fn,
+		struct device *codec_dev)
+{
+
+	struct platform_device *pdev;
+	struct msm_dp *msm_dp_display;
+
+	pdev = to_platform_device(dev);
+	if (!pdev) {
+		pr_err("invalid input\n");
+		return -ENODEV;
+	}
+
+	msm_dp_display = platform_get_drvdata(pdev);
+	if (!msm_dp_display) {
+		pr_err("invalid input\n");
+		return -ENODEV;
+	}
+
+	return msm_dp_display_set_plugged_cb(msm_dp_display, fn, codec_dev);
+}
+
+static int msm_dp_audio_get_eld(struct device *dev,
+	void *data, uint8_t *buf, size_t len)
+{
+	struct platform_device *pdev;
+	struct msm_dp *msm_dp_display;
+
+	pdev = to_platform_device(dev);
+
+	if (!pdev) {
+		DRM_ERROR("invalid input\n");
+		return -ENODEV;
+	}
+
+	msm_dp_display = platform_get_drvdata(pdev);
+	if (!msm_dp_display) {
+		DRM_ERROR("invalid input\n");
+		return -ENODEV;
+	}
+
+	memcpy(buf, msm_dp_display->connector->eld,
+		min(sizeof(msm_dp_display->connector->eld), len));
+
+	return 0;
+}
+
+int msm_dp_audio_hw_params(struct device *dev,
+	void *data,
+	struct hdmi_codec_daifmt *daifmt,
+	struct hdmi_codec_params *params)
+{
+	int rc = 0;
+	struct msm_dp_audio_private *audio;
+	struct platform_device *pdev;
+	struct msm_dp *msm_dp_display;
+
+	pdev = to_platform_device(dev);
+	msm_dp_display = platform_get_drvdata(pdev);
+
+	/*
+	 * there could be cases where sound card can be opened even
+	 * before OR even when DP is not connected . This can cause
+	 * unclocked access as the audio subsystem relies on the DP
+	 * driver to maintain the correct state of clocks. To protect
+	 * such cases check for connection status and bail out if not
+	 * connected.
+	 */
+	if (!msm_dp_display_get_active_stream_cnt(msm_dp_display)) {
+		rc = -EINVAL;
+		goto end;
+	}
+
+	audio = msm_dp_audio_get_data(pdev);
+	if (IS_ERR(audio)) {
+		rc = PTR_ERR(audio);
+		goto end;
+	}
+
+	audio->channels = params->channels;
+
+	msm_dp_audio_setup_sdp(audio);
+	msm_dp_audio_setup_acr(audio);
+	msm_dp_audio_safe_to_exit_level(audio);
+	msm_dp_audio_enable(audio, true);
+	msm_dp_display_signal_audio_start(msm_dp_display);
+	msm_dp_display->audio_enabled = true;
+
+end:
+	return rc;
+}
+
+static void msm_dp_audio_shutdown(struct device *dev, void *data)
+{
+	struct msm_dp_audio_private *audio;
+	struct platform_device *pdev;
+	struct msm_dp *msm_dp_display;
+
+	pdev = to_platform_device(dev);
+	msm_dp_display = platform_get_drvdata(pdev);
+	audio = msm_dp_audio_get_data(pdev);
+	if (IS_ERR(audio)) {
+		DRM_ERROR("failed to get audio data\n");
+		return;
+	}
+
+	/*
+	 * if audio was not enabled there is no need
+	 * to execute the shutdown and we can bail out early.
+	 * This also makes sure that we dont cause an unclocked
+	 * access when audio subsystem calls this without DP being
+	 * connected. is_connected cannot be used here as its set
+	 * to false earlier than this call
+	 */
+	if (!msm_dp_display->audio_enabled)
+		return;
+
+	msm_dp_audio_enable(audio, false);
+	/* signal the dp display to safely shutdown clocks */
+	msm_dp_display_signal_audio_complete(msm_dp_display);
+}
+
+static const struct hdmi_codec_ops msm_dp_audio_codec_ops = {
+	.hw_params = msm_dp_audio_hw_params,
+	.audio_shutdown = msm_dp_audio_shutdown,
+	.get_eld = msm_dp_audio_get_eld,
+	.hook_plugged_cb = msm_dp_audio_hook_plugged_cb,
+};
+
+static struct hdmi_codec_pdata codec_data = {
+	.ops = &msm_dp_audio_codec_ops,
+	.max_i2s_channels = 8,
+	.i2s = 1,
+};
+
+void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm_dp_audio)
+{
+	struct msm_dp_audio_private *audio_priv;
+
+	audio_priv = container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio);
+
+	if (audio_priv->audio_pdev) {
+		platform_device_unregister(audio_priv->audio_pdev);
+		audio_priv->audio_pdev = NULL;
+	}
+}
+
+int msm_dp_register_audio_driver(struct device *dev,
+		struct msm_dp_audio *msm_dp_audio)
+{
+	struct msm_dp_audio_private *audio_priv;
+
+	audio_priv = container_of(msm_dp_audio,
+			struct msm_dp_audio_private, msm_dp_audio);
+
+	audio_priv->audio_pdev = platform_device_register_data(dev,
+						HDMI_CODEC_DRV_NAME,
+						PLATFORM_DEVID_AUTO,
+						&codec_data,
+						sizeof(codec_data));
+	return PTR_ERR_OR_ZERO(audio_priv->audio_pdev);
+}
+
+struct msm_dp_audio *msm_dp_audio_get(struct platform_device *pdev,
+			struct msm_dp_panel *panel,
+			struct msm_dp_catalog *catalog)
+{
+	int rc = 0;
+	struct msm_dp_audio_private *audio;
+	struct msm_dp_audio *msm_dp_audio;
+
+	if (!pdev || !panel || !catalog) {
+		DRM_ERROR("invalid input\n");
+		rc = -EINVAL;
+		goto error;
+	}
+
+	audio = devm_kzalloc(&pdev->dev, sizeof(*audio), GFP_KERNEL);
+	if (!audio) {
+		rc = -ENOMEM;
+		goto error;
+	}
+
+	audio->pdev = pdev;
+	audio->catalog = catalog;
+
+	msm_dp_audio = &audio->msm_dp_audio;
+
+	msm_dp_catalog_audio_init(catalog);
+
+	return msm_dp_audio;
+error:
+	return ERR_PTR(rc);
+}
+
+void msm_dp_audio_put(struct msm_dp_audio *msm_dp_audio)
+{
+	struct msm_dp_audio_private *audio;
+
+	if (!msm_dp_audio)
+		return;
+
+	audio = container_of(msm_dp_audio, struct msm_dp_audio_private, msm_dp_audio);
+
+	devm_kfree(&audio->pdev->dev, audio);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_audio.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_audio.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DP_AUDIO_H_
+#define _DP_AUDIO_H_
+
+#include <linux/platform_device.h>
+
+#include "dp_panel.h"
+#include "dp_catalog.h"
+#include <sound/hdmi-codec.h>
+
+/**
+ * struct msm_dp_audio
+ * @lane_count: number of lanes configured in current session
+ * @bw_code: link rate's bandwidth code for current session
+ */
+struct msm_dp_audio {
+	u32 lane_count;
+	u32 bw_code;
+};
+
+/**
+ * msm_dp_audio_get()
+ *
+ * Creates and instance of dp audio.
+ *
+ * @pdev: caller's platform device instance.
+ * @panel: an instance of msm_dp_panel module.
+ * @catalog: an instance of msm_dp_catalog module.
+ *
+ * Returns the error code in case of failure, otherwize
+ * an instance of newly created msm_dp_module.
+ */
+struct msm_dp_audio *msm_dp_audio_get(struct platform_device *pdev,
+			struct msm_dp_panel *panel,
+			struct msm_dp_catalog *catalog);
+
+/**
+ * msm_dp_register_audio_driver()
+ *
+ * Registers DP device with hdmi_codec interface.
+ *
+ * @dev: DP device instance.
+ * @msm_dp_audio: an instance of msm_dp_audio module.
+ *
+ *
+ * Returns the error code in case of failure, otherwise
+ * zero on success.
+ */
+int msm_dp_register_audio_driver(struct device *dev,
+		struct msm_dp_audio *msm_dp_audio);
+
+void msm_dp_unregister_audio_driver(struct device *dev, struct msm_dp_audio *msm_dp_audio);
+
+/**
+ * msm_dp_audio_put()
+ *
+ * Cleans the msm_dp_audio instance.
+ *
+ * @msm_dp_audio: an instance of msm_dp_audio.
+ */
+void msm_dp_audio_put(struct msm_dp_audio *msm_dp_audio);
+
+int msm_dp_audio_hw_params(struct device *dev,
+	void *data,
+	struct hdmi_codec_daifmt *daifmt,
+	struct hdmi_codec_params *params);
+
+#endif /* _DP_AUDIO_H_ */
+
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_aux.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_aux.c
@@ -0,0 +1,578 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/delay.h>
+#include <linux/phy/phy.h>
+#include <drm/drm_print.h>
+
+#include "dp_reg.h"
+#include "dp_aux.h"
+
+enum msm_dp_aux_err {
+	DP_AUX_ERR_NONE,
+	DP_AUX_ERR_ADDR,
+	DP_AUX_ERR_TOUT,
+	DP_AUX_ERR_NACK,
+	DP_AUX_ERR_DEFER,
+	DP_AUX_ERR_NACK_DEFER,
+	DP_AUX_ERR_PHY,
+};
+
+struct msm_dp_aux_private {
+	struct device *dev;
+	struct msm_dp_catalog *catalog;
+
+	struct phy *phy;
+
+	struct mutex mutex;
+	struct completion comp;
+
+	enum msm_dp_aux_err aux_error_num;
+	u32 retry_cnt;
+	bool cmd_busy;
+	bool native;
+	bool read;
+	bool no_send_addr;
+	bool no_send_stop;
+	bool initted;
+	bool is_edp;
+	bool enable_xfers;
+	u32 offset;
+	u32 segment;
+
+	struct drm_dp_aux msm_dp_aux;
+};
+
+#define MAX_AUX_RETRIES			5
+
+static ssize_t msm_dp_aux_write(struct msm_dp_aux_private *aux,
+			struct drm_dp_aux_msg *msg)
+{
+	u8 data[4];
+	u32 reg;
+	ssize_t len;
+	u8 *msgdata = msg->buffer;
+	int const AUX_CMD_FIFO_LEN = 128;
+	int i = 0;
+
+	if (aux->read)
+		len = 0;
+	else
+		len = msg->size;
+
+	/*
+	 * cmd fifo only has depth of 144 bytes
+	 * limit buf length to 128 bytes here
+	 */
+	if (len > AUX_CMD_FIFO_LEN - 4) {
+		DRM_ERROR("buf size greater than allowed size of 128 bytes\n");
+		return -EINVAL;
+	}
+
+	/* Pack cmd and write to HW */
+	data[0] = (msg->address >> 16) & 0xf;	/* addr[19:16] */
+	if (aux->read)
+		data[0] |=  BIT(4);		/* R/W */
+
+	data[1] = msg->address >> 8;		/* addr[15:8] */
+	data[2] = msg->address;			/* addr[7:0] */
+	data[3] = msg->size - 1;		/* len[7:0] */
+
+	for (i = 0; i < len + 4; i++) {
+		reg = (i < 4) ? data[i] : msgdata[i - 4];
+		reg <<= DP_AUX_DATA_OFFSET;
+		reg &= DP_AUX_DATA_MASK;
+		reg |= DP_AUX_DATA_WRITE;
+		/* index = 0, write */
+		if (i == 0)
+			reg |= DP_AUX_DATA_INDEX_WRITE;
+		msm_dp_catalog_aux_write_data(aux->catalog, reg);
+	}
+
+	msm_dp_catalog_aux_clear_trans(aux->catalog, false);
+	msm_dp_catalog_aux_clear_hw_interrupts(aux->catalog);
+
+	reg = 0; /* Transaction number == 1 */
+	if (!aux->native) { /* i2c */
+		reg |= DP_AUX_TRANS_CTRL_I2C;
+
+		if (aux->no_send_addr)
+			reg |= DP_AUX_TRANS_CTRL_NO_SEND_ADDR;
+
+		if (aux->no_send_stop)
+			reg |= DP_AUX_TRANS_CTRL_NO_SEND_STOP;
+	}
+
+	reg |= DP_AUX_TRANS_CTRL_GO;
+	msm_dp_catalog_aux_write_trans(aux->catalog, reg);
+
+	return len;
+}
+
+static ssize_t msm_dp_aux_cmd_fifo_tx(struct msm_dp_aux_private *aux,
+			      struct drm_dp_aux_msg *msg)
+{
+	ssize_t ret;
+	unsigned long time_left;
+
+	reinit_completion(&aux->comp);
+
+	ret = msm_dp_aux_write(aux, msg);
+	if (ret < 0)
+		return ret;
+
+	time_left = wait_for_completion_timeout(&aux->comp,
+						msecs_to_jiffies(250));
+	if (!time_left)
+		return -ETIMEDOUT;
+
+	return ret;
+}
+
+static ssize_t msm_dp_aux_cmd_fifo_rx(struct msm_dp_aux_private *aux,
+		struct drm_dp_aux_msg *msg)
+{
+	u32 data;
+	u8 *dp;
+	u32 i, actual_i;
+	u32 len = msg->size;
+
+	msm_dp_catalog_aux_clear_trans(aux->catalog, true);
+
+	data = DP_AUX_DATA_INDEX_WRITE; /* INDEX_WRITE */
+	data |= DP_AUX_DATA_READ;  /* read */
+
+	msm_dp_catalog_aux_write_data(aux->catalog, data);
+
+	dp = msg->buffer;
+
+	/* discard first byte */
+	data = msm_dp_catalog_aux_read_data(aux->catalog);
+
+	for (i = 0; i < len; i++) {
+		data = msm_dp_catalog_aux_read_data(aux->catalog);
+		*dp++ = (u8)((data >> DP_AUX_DATA_OFFSET) & 0xff);
+
+		actual_i = (data >> DP_AUX_DATA_INDEX_OFFSET) & 0xFF;
+		if (i != actual_i)
+			break;
+	}
+
+	return i;
+}
+
+static void msm_dp_aux_update_offset_and_segment(struct msm_dp_aux_private *aux,
+					     struct drm_dp_aux_msg *input_msg)
+{
+	u32 edid_address = 0x50;
+	u32 segment_address = 0x30;
+	bool i2c_read = input_msg->request &
+		(DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
+	u8 *data;
+
+	if (aux->native || i2c_read || ((input_msg->address != edid_address) &&
+		(input_msg->address != segment_address)))
+		return;
+
+
+	data = input_msg->buffer;
+	if (input_msg->address == segment_address)
+		aux->segment = *data;
+	else
+		aux->offset = *data;
+}
+
+/**
+ * msm_dp_aux_transfer_helper() - helper function for EDID read transactions
+ *
+ * @aux: DP AUX private structure
+ * @input_msg: input message from DRM upstream APIs
+ * @send_seg: send the segment to sink
+ *
+ * return: void
+ *
+ * This helper function is used to fix EDID reads for non-compliant
+ * sinks that do not handle the i2c middle-of-transaction flag correctly.
+ */
+static void msm_dp_aux_transfer_helper(struct msm_dp_aux_private *aux,
+				   struct drm_dp_aux_msg *input_msg,
+				   bool send_seg)
+{
+	struct drm_dp_aux_msg helper_msg;
+	u32 message_size = 0x10;
+	u32 segment_address = 0x30;
+	u32 const edid_block_length = 0x80;
+	bool i2c_mot = input_msg->request & DP_AUX_I2C_MOT;
+	bool i2c_read = input_msg->request &
+		(DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
+
+	if (!i2c_mot || !i2c_read || (input_msg->size == 0))
+		return;
+
+	/*
+	 * Sending the segment value and EDID offset will be performed
+	 * from the DRM upstream EDID driver for each block. Avoid
+	 * duplicate AUX transactions related to this while reading the
+	 * first 16 bytes of each block.
+	 */
+	if (!(aux->offset % edid_block_length) || !send_seg)
+		goto end;
+
+	aux->read = false;
+	aux->cmd_busy = true;
+	aux->no_send_addr = true;
+	aux->no_send_stop = true;
+
+	/*
+	 * Send the segment address for every i2c read in which the
+	 * middle-of-tranaction flag is set. This is required to support EDID
+	 * reads of more than 2 blocks as the segment address is reset to 0
+	 * since we are overriding the middle-of-transaction flag for read
+	 * transactions.
+	 */
+
+	if (aux->segment) {
+		memset(&helper_msg, 0, sizeof(helper_msg));
+		helper_msg.address = segment_address;
+		helper_msg.buffer = &aux->segment;
+		helper_msg.size = 1;
+		msm_dp_aux_cmd_fifo_tx(aux, &helper_msg);
+	}
+
+	/*
+	 * Send the offset address for every i2c read in which the
+	 * middle-of-transaction flag is set. This will ensure that the sink
+	 * will update its read pointer and return the correct portion of the
+	 * EDID buffer in the subsequent i2c read trasntion triggered in the
+	 * native AUX transfer function.
+	 */
+	memset(&helper_msg, 0, sizeof(helper_msg));
+	helper_msg.address = input_msg->address;
+	helper_msg.buffer = &aux->offset;
+	helper_msg.size = 1;
+	msm_dp_aux_cmd_fifo_tx(aux, &helper_msg);
+
+end:
+	aux->offset += message_size;
+	if (aux->offset == 0x80 || aux->offset == 0x100)
+		aux->segment = 0x0; /* reset segment at end of block */
+}
+
+/*
+ * This function does the real job to process an AUX transaction.
+ * It will call aux_reset() function to reset the AUX channel,
+ * if the waiting is timeout.
+ */
+static ssize_t msm_dp_aux_transfer(struct drm_dp_aux *msm_dp_aux,
+			       struct drm_dp_aux_msg *msg)
+{
+	ssize_t ret;
+	int const aux_cmd_native_max = 16;
+	int const aux_cmd_i2c_max = 128;
+	struct msm_dp_aux_private *aux;
+
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+
+	aux->native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
+
+	/* Ignore address only message */
+	if (msg->size == 0 || !msg->buffer) {
+		msg->reply = aux->native ?
+			DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
+		return msg->size;
+	}
+
+	/* msg sanity check */
+	if ((aux->native && msg->size > aux_cmd_native_max) ||
+	    msg->size > aux_cmd_i2c_max) {
+		DRM_ERROR("%s: invalid msg: size(%zu), request(%x)\n",
+			__func__, msg->size, msg->request);
+		return -EINVAL;
+	}
+
+	ret = pm_runtime_resume_and_get(msm_dp_aux->dev);
+	if (ret)
+		return  ret;
+
+	mutex_lock(&aux->mutex);
+	if (!aux->initted) {
+		ret = -EIO;
+		goto exit;
+	}
+
+	/*
+	 * If we're using DP and an external display isn't connected then the
+	 * transfer won't succeed. Return right away. If we don't do this we
+	 * can end up with long timeouts if someone tries to access the DP AUX
+	 * character device when no DP device is connected.
+	 */
+	if (!aux->is_edp && !aux->enable_xfers) {
+		ret = -ENXIO;
+		goto exit;
+	}
+
+	msm_dp_aux_update_offset_and_segment(aux, msg);
+	msm_dp_aux_transfer_helper(aux, msg, true);
+
+	aux->read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
+	aux->cmd_busy = true;
+
+	if (aux->read) {
+		aux->no_send_addr = true;
+		aux->no_send_stop = false;
+	} else {
+		aux->no_send_addr = true;
+		aux->no_send_stop = true;
+	}
+
+	ret = msm_dp_aux_cmd_fifo_tx(aux, msg);
+	if (ret < 0) {
+		if (aux->native) {
+			aux->retry_cnt++;
+			if (!(aux->retry_cnt % MAX_AUX_RETRIES))
+				phy_calibrate(aux->phy);
+		}
+		/* reset aux if link is in connected state */
+		if (msm_dp_catalog_link_is_connected(aux->catalog))
+			msm_dp_catalog_aux_reset(aux->catalog);
+	} else {
+		aux->retry_cnt = 0;
+		switch (aux->aux_error_num) {
+		case DP_AUX_ERR_NONE:
+			if (aux->read)
+				ret = msm_dp_aux_cmd_fifo_rx(aux, msg);
+			msg->reply = aux->native ? DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
+			break;
+		case DP_AUX_ERR_DEFER:
+			msg->reply = aux->native ? DP_AUX_NATIVE_REPLY_DEFER : DP_AUX_I2C_REPLY_DEFER;
+			break;
+		case DP_AUX_ERR_PHY:
+		case DP_AUX_ERR_ADDR:
+		case DP_AUX_ERR_NACK:
+		case DP_AUX_ERR_NACK_DEFER:
+			msg->reply = aux->native ? DP_AUX_NATIVE_REPLY_NACK : DP_AUX_I2C_REPLY_NACK;
+			break;
+		case DP_AUX_ERR_TOUT:
+			ret = -ETIMEDOUT;
+			break;
+		}
+	}
+
+	aux->cmd_busy = false;
+
+exit:
+	mutex_unlock(&aux->mutex);
+	pm_runtime_put_sync(msm_dp_aux->dev);
+
+	return ret;
+}
+
+irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux)
+{
+	u32 isr;
+	struct msm_dp_aux_private *aux;
+
+	if (!msm_dp_aux) {
+		DRM_ERROR("invalid input\n");
+		return IRQ_NONE;
+	}
+
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+
+	isr = msm_dp_catalog_aux_get_irq(aux->catalog);
+
+	/* no interrupts pending, return immediately */
+	if (!isr)
+		return IRQ_NONE;
+
+	if (!aux->cmd_busy) {
+		DRM_ERROR("Unexpected DP AUX IRQ %#010x when not busy\n", isr);
+		return IRQ_NONE;
+	}
+
+	/*
+	 * The logic below assumes only one error bit is set (other than "done"
+	 * which can apparently be set at the same time as some of the other
+	 * bits). Warn if more than one get set so we know we need to improve
+	 * the logic.
+	 */
+	if (hweight32(isr & ~DP_INTR_AUX_XFER_DONE) > 1)
+		DRM_WARN("Some DP AUX interrupts unhandled: %#010x\n", isr);
+
+	if (isr & DP_INTR_AUX_ERROR) {
+		aux->aux_error_num = DP_AUX_ERR_PHY;
+		msm_dp_catalog_aux_clear_hw_interrupts(aux->catalog);
+	} else if (isr & DP_INTR_NACK_DEFER) {
+		aux->aux_error_num = DP_AUX_ERR_NACK_DEFER;
+	} else if (isr & DP_INTR_WRONG_ADDR) {
+		aux->aux_error_num = DP_AUX_ERR_ADDR;
+	} else if (isr & DP_INTR_TIMEOUT) {
+		aux->aux_error_num = DP_AUX_ERR_TOUT;
+	} else if (!aux->native && (isr & DP_INTR_I2C_NACK)) {
+		aux->aux_error_num = DP_AUX_ERR_NACK;
+	} else if (!aux->native && (isr & DP_INTR_I2C_DEFER)) {
+		if (isr & DP_INTR_AUX_XFER_DONE)
+			aux->aux_error_num = DP_AUX_ERR_NACK;
+		else
+			aux->aux_error_num = DP_AUX_ERR_DEFER;
+	} else if (isr & DP_INTR_AUX_XFER_DONE) {
+		aux->aux_error_num = DP_AUX_ERR_NONE;
+	} else {
+		DRM_WARN("Unexpected interrupt: %#010x\n", isr);
+		return IRQ_NONE;
+	}
+
+	complete(&aux->comp);
+
+	return IRQ_HANDLED;
+}
+
+void msm_dp_aux_enable_xfers(struct drm_dp_aux *msm_dp_aux, bool enabled)
+{
+	struct msm_dp_aux_private *aux;
+
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+	aux->enable_xfers = enabled;
+}
+
+void msm_dp_aux_reconfig(struct drm_dp_aux *msm_dp_aux)
+{
+	struct msm_dp_aux_private *aux;
+
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+
+	phy_calibrate(aux->phy);
+	msm_dp_catalog_aux_reset(aux->catalog);
+}
+
+void msm_dp_aux_init(struct drm_dp_aux *msm_dp_aux)
+{
+	struct msm_dp_aux_private *aux;
+
+	if (!msm_dp_aux) {
+		DRM_ERROR("invalid input\n");
+		return;
+	}
+
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+
+	mutex_lock(&aux->mutex);
+
+	msm_dp_catalog_aux_enable(aux->catalog, true);
+	aux->retry_cnt = 0;
+	aux->initted = true;
+
+	mutex_unlock(&aux->mutex);
+}
+
+void msm_dp_aux_deinit(struct drm_dp_aux *msm_dp_aux)
+{
+	struct msm_dp_aux_private *aux;
+
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+
+	mutex_lock(&aux->mutex);
+
+	aux->initted = false;
+	msm_dp_catalog_aux_enable(aux->catalog, false);
+
+	mutex_unlock(&aux->mutex);
+}
+
+int msm_dp_aux_register(struct drm_dp_aux *msm_dp_aux)
+{
+	int ret;
+
+	if (!msm_dp_aux) {
+		DRM_ERROR("invalid input\n");
+		return -EINVAL;
+	}
+
+	ret = drm_dp_aux_register(msm_dp_aux);
+	if (ret) {
+		DRM_ERROR("%s: failed to register drm aux: %d\n", __func__,
+				ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+void msm_dp_aux_unregister(struct drm_dp_aux *msm_dp_aux)
+{
+	drm_dp_aux_unregister(msm_dp_aux);
+}
+
+static int msm_dp_wait_hpd_asserted(struct drm_dp_aux *msm_dp_aux,
+				 unsigned long wait_us)
+{
+	int ret;
+	struct msm_dp_aux_private *aux;
+
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+
+	pm_runtime_get_sync(aux->dev);
+	ret = pm_runtime_resume_and_get(aux->dev);
+	if (ret)
+		return ret;
+
+	ret = msm_dp_catalog_aux_wait_for_hpd_connect_state(aux->catalog, wait_us);
+	pm_runtime_put_sync(aux->dev);
+
+	return ret;
+}
+
+struct drm_dp_aux *msm_dp_aux_get(struct device *dev, struct msm_dp_catalog *catalog,
+			      struct phy *phy,
+			      bool is_edp)
+{
+	struct msm_dp_aux_private *aux;
+
+	if (!catalog) {
+		DRM_ERROR("invalid input\n");
+		return ERR_PTR(-ENODEV);
+	}
+
+	aux = devm_kzalloc(dev, sizeof(*aux), GFP_KERNEL);
+	if (!aux)
+		return ERR_PTR(-ENOMEM);
+
+	init_completion(&aux->comp);
+	aux->cmd_busy = false;
+	aux->is_edp = is_edp;
+	mutex_init(&aux->mutex);
+
+	aux->dev = dev;
+	aux->catalog = catalog;
+	aux->phy = phy;
+	aux->retry_cnt = 0;
+
+	/*
+	 * Use the drm_dp_aux_init() to use the aux adapter
+	 * before registering AUX with the DRM device so that
+	 * msm eDP panel can be detected by generic_dep_panel_probe().
+	 */
+	aux->msm_dp_aux.name = "dpu_dp_aux";
+	aux->msm_dp_aux.dev = dev;
+	aux->msm_dp_aux.transfer = msm_dp_aux_transfer;
+	aux->msm_dp_aux.wait_hpd_asserted = msm_dp_wait_hpd_asserted;
+	drm_dp_aux_init(&aux->msm_dp_aux);
+
+	return &aux->msm_dp_aux;
+}
+
+void msm_dp_aux_put(struct drm_dp_aux *msm_dp_aux)
+{
+	struct msm_dp_aux_private *aux;
+
+	if (!msm_dp_aux)
+		return;
+
+	aux = container_of(msm_dp_aux, struct msm_dp_aux_private, msm_dp_aux);
+
+	mutex_destroy(&aux->mutex);
+
+	devm_kfree(aux->dev, aux);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_aux.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_aux.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DP_AUX_H_
+#define _DP_AUX_H_
+
+#include "dp_catalog.h"
+#include <drm/display/drm_dp_helper.h>
+#include <drm/display/drm_dp_mst_helper.h>
+
+int msm_dp_aux_register(struct drm_dp_aux *msm_dp_aux);
+void msm_dp_aux_unregister(struct drm_dp_aux *msm_dp_aux);
+irqreturn_t msm_dp_aux_isr(struct drm_dp_aux *msm_dp_aux);
+void msm_dp_aux_enable_xfers(struct drm_dp_aux *msm_dp_aux, bool enabled);
+void msm_dp_aux_init(struct drm_dp_aux *msm_dp_aux);
+void msm_dp_aux_deinit(struct drm_dp_aux *msm_dp_aux);
+void msm_dp_aux_reconfig(struct drm_dp_aux *msm_dp_aux);
+
+struct phy;
+struct drm_dp_aux *msm_dp_aux_get(struct device *dev, struct msm_dp_catalog *catalog,
+			      struct phy *phy,
+			      bool is_edp);
+void msm_dp_aux_put(struct drm_dp_aux *aux);
+
+#endif /*__DP_AUX_H_*/
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_catalog.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_catalog.c
@@ -0,0 +1,1588 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
+
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+#include <linux/platform_device.h>
+#include <linux/rational.h>
+#include <drm/display/drm_dp_helper.h>
+#include <drm/drm_print.h>
+
+#include "dp_catalog.h"
+#include "dp_reg.h"
+
+#define POLLING_SLEEP_US			1000
+#define POLLING_TIMEOUT_US			10000
+
+#define SCRAMBLER_RESET_COUNT_VALUE		0xFC
+
+#define DP_INTERRUPT_STATUS_ACK_SHIFT	1
+#define DP_INTERRUPT_STATUS_MASK_SHIFT	2
+
+#define DP_INTF_CONFIG_DATABUS_WIDEN     BIT(4)
+
+#define DP_INTERRUPT_STATUS1 \
+	(DP_INTR_AUX_XFER_DONE| \
+	DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
+	DP_INTR_NACK_DEFER | DP_INTR_WRONG_DATA_CNT | \
+	DP_INTR_I2C_NACK | DP_INTR_I2C_DEFER | \
+	DP_INTR_PLL_UNLOCKED | DP_INTR_AUX_ERROR)
+
+#define DP_INTERRUPT_STATUS1_ACK \
+	(DP_INTERRUPT_STATUS1 << DP_INTERRUPT_STATUS_ACK_SHIFT)
+#define DP_INTERRUPT_STATUS1_MASK \
+	(DP_INTERRUPT_STATUS1 << DP_INTERRUPT_STATUS_MASK_SHIFT)
+
+#define DP_INTERRUPT_STATUS2 \
+	(DP_INTR_READY_FOR_VIDEO | DP_INTR_IDLE_PATTERN_SENT | \
+	DP_INTR_FRAME_END | DP_INTR_CRC_UPDATED)
+
+#define DP_INTERRUPT_STATUS2_ACK \
+	(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_ACK_SHIFT)
+#define DP_INTERRUPT_STATUS2_MASK \
+	(DP_INTERRUPT_STATUS2 << DP_INTERRUPT_STATUS_MASK_SHIFT)
+
+#define DP_INTERRUPT_STATUS4 \
+	(PSR_UPDATE_INT | PSR_CAPTURE_INT | PSR_EXIT_INT | \
+	PSR_UPDATE_ERROR_INT | PSR_WAKE_ERROR_INT)
+
+#define DP_INTERRUPT_STATUS5 \
+	(DP_INTR_DP0_VCPF_SENT | DP_INTR_DP1_VCPF_SENT)
+#define DP_INTERRUPT_STATUS5_MASK \
+	(DP_INTERRUPT_STATUS5 << DP_INTERRUPT_STATUS_MASK_SHIFT)
+
+#define DP_INTERRUPT_MASK4 \
+	(PSR_UPDATE_MASK | PSR_CAPTURE_MASK | PSR_EXIT_MASK | \
+	PSR_UPDATE_ERROR_MASK | PSR_WAKE_ERROR_MASK)
+
+#define DP_DEFAULT_AHB_OFFSET	0x0000
+#define DP_DEFAULT_AHB_SIZE	0x0200
+#define DP_DEFAULT_AUX_OFFSET	0x0200
+#define DP_DEFAULT_AUX_SIZE	0x0200
+#define DP_DEFAULT_LINK_OFFSET	0x0400
+#define DP_DEFAULT_LINK_SIZE	0x0C00
+#define DP_DEFAULT_P0_OFFSET	0x1000
+#define DP_DEFAULT_P0_SIZE	0x0400
+
+struct dss_io_region {
+	size_t len;
+	void __iomem *base;
+};
+
+struct dss_io_data {
+	struct dss_io_region ahb;
+	struct dss_io_region aux;
+	struct dss_io_region link;
+	struct dss_io_region p0;
+	struct dss_io_region p1;
+};
+
+struct msm_dp_catalog_private {
+	struct device *dev;
+	struct drm_device *drm_dev;
+	struct dss_io_data io;
+	u32 (*audio_map)[DP_AUDIO_SDP_HEADER_MAX];
+	struct msm_dp_catalog msm_dp_catalog;
+};
+
+void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_disp_state *disp_state)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+			struct msm_dp_catalog_private, msm_dp_catalog);
+	struct dss_io_data *dss = &catalog->io;
+
+	msm_disp_snapshot_add_block(disp_state, dss->ahb.len, dss->ahb.base, "dp_ahb");
+	msm_disp_snapshot_add_block(disp_state, dss->aux.len, dss->aux.base, "dp_aux");
+	msm_disp_snapshot_add_block(disp_state, dss->link.len, dss->link.base, "dp_link");
+	msm_disp_snapshot_add_block(disp_state, dss->p0.len, dss->p0.base, "dp_p0");
+	msm_disp_snapshot_add_block(disp_state, dss->p1.len, dss->p0.base, "dp_p1");
+}
+
+static inline u32 msm_dp_read_aux(struct msm_dp_catalog_private *catalog, u32 offset)
+{
+	return readl_relaxed(catalog->io.aux.base + offset);
+}
+
+static inline void msm_dp_write_aux(struct msm_dp_catalog_private *catalog,
+			       u32 offset, u32 data)
+{
+	/*
+	 * To make sure aux reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	writel(data, catalog->io.aux.base + offset);
+}
+
+static inline u32 msm_dp_read_ahb(const struct msm_dp_catalog_private *catalog, u32 offset)
+{
+	return readl_relaxed(catalog->io.ahb.base + offset);
+}
+
+static inline void msm_dp_write_ahb(struct msm_dp_catalog_private *catalog,
+			       u32 offset, u32 data)
+{
+	/*
+	 * To make sure phy reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	writel(data, catalog->io.ahb.base + offset);
+}
+
+static inline void msm_dp_write_p0(struct msm_dp_catalog_private *catalog,
+			       u32 offset, u32 data)
+{
+	/*
+	 * To make sure interface reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	writel(data, catalog->io.p0.base + offset);
+}
+
+static inline u32 msm_dp_read_p0(struct msm_dp_catalog_private *catalog,
+			       u32 offset)
+{
+	/*
+	 * To make sure interface reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	return readl_relaxed(catalog->io.p0.base + offset);
+}
+
+static inline void msm_dp_write_p1(struct msm_dp_catalog_private *catalog,
+				   u32 offset, u32 data)
+{
+	/*
+	 * To make sure interface reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	writel(data, catalog->io.p1.base + offset);
+}
+
+static inline u32 msm_dp_read_p1(struct msm_dp_catalog_private *catalog,
+				 u32 offset)
+{
+	/*
+	 * To make sure interface reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	return readl_relaxed(catalog->io.p1.base + offset);
+}
+
+static inline u32 msm_dp_read_link(struct msm_dp_catalog_private *catalog, u32 offset)
+{
+	return readl_relaxed(catalog->io.link.base + offset);
+}
+
+static inline void msm_dp_write_link(struct msm_dp_catalog_private *catalog,
+			       u32 offset, u32 data)
+{
+	/*
+	 * To make sure link reg writes happens before any other operation,
+	 * this function uses writel() instread of writel_relaxed()
+	 */
+	writel(data, catalog->io.link.base + offset);
+}
+
+/* aux related catalog functions */
+u32 msm_dp_catalog_aux_read_data(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	return msm_dp_read_aux(catalog, REG_DP_AUX_DATA);
+}
+
+int msm_dp_catalog_aux_write_data(struct msm_dp_catalog *msm_dp_catalog, u32 data)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	msm_dp_write_aux(catalog, REG_DP_AUX_DATA, data);
+	return 0;
+}
+
+int msm_dp_catalog_aux_write_trans(struct msm_dp_catalog *msm_dp_catalog, u32 data)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	msm_dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, data);
+	return 0;
+}
+
+int msm_dp_catalog_aux_clear_trans(struct msm_dp_catalog *msm_dp_catalog, bool read)
+{
+	u32 data;
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	if (read) {
+		data = msm_dp_read_aux(catalog, REG_DP_AUX_TRANS_CTRL);
+		data &= ~DP_AUX_TRANS_CTRL_GO;
+		msm_dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, data);
+	} else {
+		msm_dp_write_aux(catalog, REG_DP_AUX_TRANS_CTRL, 0);
+	}
+	return 0;
+}
+
+int msm_dp_catalog_aux_clear_hw_interrupts(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	msm_dp_read_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_STATUS);
+	msm_dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x1f);
+	msm_dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0x9f);
+	msm_dp_write_aux(catalog, REG_DP_PHY_AUX_INTERRUPT_CLEAR, 0);
+	return 0;
+}
+
+/**
+ * msm_dp_catalog_aux_reset() - reset AUX controller
+ *
+ * @msm_dp_catalog: DP catalog structure
+ *
+ * return: void
+ *
+ * This function reset AUX controller
+ *
+ * NOTE: reset AUX controller will also clear any pending HPD related interrupts
+ * 
+ */
+void msm_dp_catalog_aux_reset(struct msm_dp_catalog *msm_dp_catalog)
+{
+	u32 aux_ctrl;
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	aux_ctrl = msm_dp_read_aux(catalog, REG_DP_AUX_CTRL);
+
+	aux_ctrl |= DP_AUX_CTRL_RESET;
+	msm_dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
+	usleep_range(1000, 1100); /* h/w recommended delay */
+
+	aux_ctrl &= ~DP_AUX_CTRL_RESET;
+	msm_dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
+}
+
+void msm_dp_catalog_aux_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable)
+{
+	u32 aux_ctrl;
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	aux_ctrl = msm_dp_read_aux(catalog, REG_DP_AUX_CTRL);
+
+	if (enable) {
+		msm_dp_write_aux(catalog, REG_DP_TIMEOUT_COUNT, 0xffff);
+		msm_dp_write_aux(catalog, REG_DP_AUX_LIMITS, 0xffff);
+		aux_ctrl |= DP_AUX_CTRL_ENABLE;
+	} else {
+		aux_ctrl &= ~DP_AUX_CTRL_ENABLE;
+	}
+
+	msm_dp_write_aux(catalog, REG_DP_AUX_CTRL, aux_ctrl);
+}
+
+int msm_dp_catalog_aux_wait_for_hpd_connect_state(struct msm_dp_catalog *msm_dp_catalog,
+					      unsigned long wait_us)
+{
+	u32 state;
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	/* poll for hpd connected status every 2ms and timeout after wait_us */
+	return readl_poll_timeout(catalog->io.aux.base +
+				REG_DP_DP_HPD_INT_STATUS,
+				state, state & DP_DP_HPD_STATE_STATUS_CONNECTED,
+				min(wait_us, 2000), wait_us);
+}
+
+static void dump_regs(void __iomem *base, int len)
+{
+	int i;
+	u32 x0, x4, x8, xc;
+	u32 addr_off = 0;
+
+	len = DIV_ROUND_UP(len, 16);
+	for (i = 0; i < len; i++) {
+		x0 = readl_relaxed(base + addr_off);
+		x4 = readl_relaxed(base + addr_off + 0x04);
+		x8 = readl_relaxed(base + addr_off + 0x08);
+		xc = readl_relaxed(base + addr_off + 0x0c);
+
+		pr_info("%08x: %08x %08x %08x %08x", addr_off, x0, x4, x8, xc);
+		addr_off += 16;
+	}
+}
+
+void msm_dp_catalog_dump_regs(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
+	struct dss_io_data *io = &catalog->io;
+
+	pr_info("AHB regs\n");
+	dump_regs(io->ahb.base, io->ahb.len);
+
+	pr_info("AUXCLK regs\n");
+	dump_regs(io->aux.base, io->aux.len);
+
+	pr_info("LCLK regs\n");
+	dump_regs(io->link.base, io->link.len);
+
+	pr_info("P0CLK regs\n");
+	dump_regs(io->p0.base, io->p0.len);
+}
+
+u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+	u32 intr, intr_ack;
+
+	intr = msm_dp_read_ahb(catalog, REG_DP_INTR_STATUS);
+	intr &= ~DP_INTERRUPT_STATUS1_MASK;
+	intr_ack = (intr & DP_INTERRUPT_STATUS1)
+			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
+	msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS, intr_ack |
+			DP_INTERRUPT_STATUS1_MASK);
+
+	return intr;
+
+}
+
+/* controller related catalog functions */
+void msm_dp_catalog_ctrl_update_transfer_unit(struct msm_dp_catalog *msm_dp_catalog,
+				u32 msm_dp_tu, u32 valid_boundary,
+				u32 valid_boundary2)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	msm_dp_write_link(catalog, REG_DP_VALID_BOUNDARY, valid_boundary);
+	msm_dp_write_link(catalog, REG_DP_TU, msm_dp_tu);
+	msm_dp_write_link(catalog, REG_DP_VALID_BOUNDARY_2, valid_boundary2);
+}
+
+void msm_dp_catalog_ctrl_state_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 state)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	msm_dp_write_link(catalog, REG_DP_STATE_CTRL, state);
+}
+
+void msm_dp_catalog_ctrl_config_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 cfg)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	drm_dbg_dp(catalog->drm_dev, "DP_CONFIGURATION_CTRL=0x%x\n", cfg);
+
+	msm_dp_write_link(catalog, REG_DP_CONFIGURATION_CTRL, cfg);
+}
+
+void msm_dp_catalog_ctrl_lane_mapping(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+	u32 ln_0 = 0, ln_1 = 1, ln_2 = 2, ln_3 = 3; /* One-to-One mapping */
+	u32 ln_mapping;
+
+	ln_mapping = ln_0 << LANE0_MAPPING_SHIFT;
+	ln_mapping |= ln_1 << LANE1_MAPPING_SHIFT;
+	ln_mapping |= ln_2 << LANE2_MAPPING_SHIFT;
+	ln_mapping |= ln_3 << LANE3_MAPPING_SHIFT;
+
+	msm_dp_write_link(catalog, REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING,
+			ln_mapping);
+}
+
+void msm_dp_catalog_ctrl_psr_mainlink_enable(struct msm_dp_catalog *msm_dp_catalog,
+						bool enable)
+{
+	u32 val;
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	val = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+
+	if (enable)
+		val |= DP_MAINLINK_CTRL_ENABLE;
+	else
+		val &= ~DP_MAINLINK_CTRL_ENABLE;
+
+	msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, val);
+}
+
+void msm_dp_catalog_mst_config(struct msm_dp_catalog *msm_dp_catalog, bool enable)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+							      struct msm_dp_catalog_private,
+							      msm_dp_catalog);
+
+	u32 mainlink_ctrl;
+
+	mainlink_ctrl = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+	if (enable)
+		mainlink_ctrl |= (0x04000100);
+	else
+		mainlink_ctrl &= ~(0x04000100);
+
+	msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+}
+
+void msm_dp_catalog_ctrl_mainlink_ctrl(struct msm_dp_catalog *msm_dp_catalog,
+				       bool enable)
+{
+	u32 mainlink_ctrl;
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	drm_dbg_dp(catalog->drm_dev, "enable=%d\n", enable);
+	if (enable) {
+		/*
+		 * To make sure link reg writes happens before other operation,
+		 * msm_dp_write_link() function uses writel()
+		 */
+		mainlink_ctrl = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+
+		mainlink_ctrl &= ~(DP_MAINLINK_CTRL_RESET |
+						DP_MAINLINK_CTRL_ENABLE);
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+
+		mainlink_ctrl |= DP_MAINLINK_CTRL_RESET;
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+
+		mainlink_ctrl &= ~DP_MAINLINK_CTRL_RESET;
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+
+		mainlink_ctrl |= (DP_MAINLINK_CTRL_ENABLE |
+					DP_MAINLINK_FB_BOUNDARY_SEL);
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+	} else {
+		mainlink_ctrl = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+		mainlink_ctrl &= ~DP_MAINLINK_CTRL_ENABLE;
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+	}
+}
+
+void msm_dp_catalog_ctrl_config_misc(struct msm_dp_catalog *msm_dp_catalog,
+					u32 colorimetry_cfg,
+					u32 test_bits_depth)
+{
+	u32 misc_val;
+	u32 reg_offset = 0;
+
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	if (msm_dp_catalog->stream_id >= DP_STREAM_MAX) {
+		DRM_ERROR("invalid stream_id:%d\n", msm_dp_catalog->stream_id);
+		return;
+	}
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_1)
+		reg_offset = REG_DP1_MISC1_MISC0 - REG_DP_MISC1_MISC0;
+
+	misc_val = msm_dp_read_link(catalog, REG_DP_MISC1_MISC0 + reg_offset);
+
+	/* clear bpp bits */
+	misc_val &= ~(0x07 << DP_MISC0_TEST_BITS_DEPTH_SHIFT);
+	misc_val |= colorimetry_cfg << DP_MISC0_COLORIMETRY_CFG_SHIFT;
+	misc_val |= test_bits_depth << DP_MISC0_TEST_BITS_DEPTH_SHIFT;
+	/* Configure clock to synchronous mode */
+	misc_val |= DP_MISC0_SYNCHRONOUS_CLK;
+
+	drm_dbg_dp(catalog->drm_dev, "misc settings = 0x%x\n", misc_val);
+	msm_dp_write_link(catalog, REG_DP_MISC1_MISC0 + reg_offset, misc_val);
+}
+
+void msm_dp_catalog_setup_peripheral_flush(struct msm_dp_catalog *msm_dp_catalog)
+{
+	u32 mainlink_ctrl, hw_revision;
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	mainlink_ctrl = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+
+	hw_revision = msm_dp_catalog_hw_revision(msm_dp_catalog);
+	if (hw_revision >= DP_HW_VERSION_1_2)
+		mainlink_ctrl |= DP_MAINLINK_FLUSH_MODE_SDE_PERIPH_UPDATE;
+	else
+		mainlink_ctrl |= DP_MAINLINK_FLUSH_MODE_UPDATE_SDP;
+
+	msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, mainlink_ctrl);
+}
+
+void msm_dp_catalog_ctrl_config_msa(struct msm_dp_catalog *msm_dp_catalog,
+					u32 rate, u32 stream_rate_khz,
+					bool is_ycbcr_420)
+{
+	u32 pixel_m, pixel_n;
+	u32 mvid, nvid, pixel_div = 0, dispcc_input_rate;
+	u32 const nvid_fixed = DP_LINK_CONSTANT_N_VALUE;
+	u32 const link_rate_hbr2 = 540000;
+	u32 const link_rate_hbr3 = 810000;
+	unsigned long den, num;
+	u32 mvid_reg_off = 0, nvid_reg_off = 0;
+
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	if (msm_dp_catalog->stream_id >= DP_STREAM_MAX) {
+		DRM_ERROR("invalid stream_id:%d\n", msm_dp_catalog->stream_id);
+		return;
+	}
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_1) {
+		mvid_reg_off = REG_DP1_SOFTWARE_MVID - REG_DP_SOFTWARE_MVID;
+		nvid_reg_off = REG_DP1_SOFTWARE_NVID - REG_DP_SOFTWARE_NVID;
+	}
+
+	if (rate == link_rate_hbr3)
+		pixel_div = 6;
+	else if (rate == 162000 || rate == 270000)
+		pixel_div = 2;
+	else if (rate == link_rate_hbr2)
+		pixel_div = 4;
+	else
+		DRM_ERROR("Invalid pixel mux divider\n");
+
+	dispcc_input_rate = (rate * 10) / pixel_div;
+
+	rational_best_approximation(dispcc_input_rate, stream_rate_khz,
+			(unsigned long)(1 << 16) - 1,
+			(unsigned long)(1 << 16) - 1, &den, &num);
+
+	den = ~(den - num);
+	den = den & 0xFFFF;
+	pixel_m = num;
+	pixel_n = den;
+
+	mvid = (pixel_m & 0xFFFF) * 5;
+	nvid = (0xFFFF & (~pixel_n)) + (pixel_m & 0xFFFF);
+
+	if (nvid < nvid_fixed) {
+		u32 temp;
+
+		temp = (nvid_fixed / nvid) * nvid;
+		mvid = (nvid_fixed / nvid) * mvid;
+		nvid = temp;
+	}
+
+	if (is_ycbcr_420)
+		mvid /= 2;
+
+	if (link_rate_hbr2 == rate)
+		nvid *= 2;
+
+	if (link_rate_hbr3 == rate)
+		nvid *= 3;
+
+	drm_dbg_dp(catalog->drm_dev, "mvid=0x%x, nvid=0x%x\n", mvid, nvid);
+
+	msm_dp_write_link(catalog, REG_DP_SOFTWARE_MVID + mvid_reg_off, mvid);
+	msm_dp_write_link(catalog, REG_DP_SOFTWARE_NVID + nvid_reg_off, nvid);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_0)
+		msm_dp_write_p0(catalog, MMSS_DP_DSC_DTO, 0x0);
+	else
+		msm_dp_write_p1(catalog, MMSS_DP_DSC_DTO, 0x0);
+}
+
+int msm_dp_catalog_ctrl_set_pattern_state_bit(struct msm_dp_catalog *msm_dp_catalog,
+					u32 state_bit)
+{
+	int bit, ret;
+	u32 data;
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	bit = BIT(state_bit - 1);
+	drm_dbg_dp(catalog->drm_dev, "hw: bit=%d train=%d\n", bit, state_bit);
+	msm_dp_catalog_ctrl_state_ctrl(msm_dp_catalog, bit);
+
+	bit = BIT(state_bit - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT;
+
+	/* Poll for mainlink ready status */
+	ret = readx_poll_timeout(readl, catalog->io.link.base +
+					REG_DP_MAINLINK_READY,
+					data, data & bit,
+					POLLING_SLEEP_US, POLLING_TIMEOUT_US);
+	if (ret < 0) {
+		DRM_ERROR("set state_bit for link_train=%d failed\n", state_bit);
+		return ret;
+	}
+	return 0;
+}
+
+/**
+ * msm_dp_catalog_hw_revision() - retrieve DP hw revision
+ *
+ * @msm_dp_catalog: DP catalog structure
+ *
+ * Return: DP controller hw revision
+ *
+ */
+u32 msm_dp_catalog_hw_revision(const struct msm_dp_catalog *msm_dp_catalog)
+{
+	const struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	return msm_dp_read_ahb(catalog, REG_DP_HW_VERSION);
+}
+
+/**
+ * msm_dp_catalog_ctrl_reset() - reset DP controller
+ *
+ * @msm_dp_catalog: DP catalog structure
+ *
+ * return: void
+ *
+ * This function reset the DP controller
+ *
+ * NOTE: reset DP controller will also clear any pending HPD related interrupts
+ * 
+ */
+void msm_dp_catalog_ctrl_reset(struct msm_dp_catalog *msm_dp_catalog)
+{
+	u32 sw_reset;
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	sw_reset = msm_dp_read_ahb(catalog, REG_DP_SW_RESET);
+
+	sw_reset |= DP_SW_RESET;
+	msm_dp_write_ahb(catalog, REG_DP_SW_RESET, sw_reset);
+	usleep_range(1000, 1100); /* h/w recommended delay */
+
+	sw_reset &= ~DP_SW_RESET;
+	msm_dp_write_ahb(catalog, REG_DP_SW_RESET, sw_reset);
+}
+
+bool msm_dp_catalog_ctrl_mainlink_ready(struct msm_dp_catalog *msm_dp_catalog)
+{
+	u32 data;
+	int ret;
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	/* Poll for mainlink ready status */
+	ret = readl_poll_timeout(catalog->io.link.base +
+				REG_DP_MAINLINK_READY,
+				data, data & DP_MAINLINK_READY_FOR_VIDEO,
+				POLLING_SLEEP_US, POLLING_TIMEOUT_US);
+	if (ret < 0) {
+		DRM_ERROR("mainlink not ready\n");
+		return false;
+	}
+
+	return true;
+}
+
+void msm_dp_catalog_ctrl_enable_irq(struct msm_dp_catalog *msm_dp_catalog,
+						bool enable)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	if (enable) {
+		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS,
+				DP_INTERRUPT_STATUS1_MASK);
+		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS2,
+				DP_INTERRUPT_STATUS2_MASK);
+		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS5,
+				 DP_INTERRUPT_STATUS5_MASK);
+	} else {
+		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS, 0x00);
+		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS2, 0x00);
+		msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS5, 0x00);
+	}
+}
+
+void msm_dp_catalog_hpd_config_intr(struct msm_dp_catalog *msm_dp_catalog,
+			u32 intr_mask, bool en)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	u32 config = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_MASK);
+
+	config = (en ? config | intr_mask : config & ~intr_mask);
+
+	drm_dbg_dp(catalog->drm_dev, "intr_mask=%#x config=%#x\n",
+					intr_mask, config);
+	msm_dp_write_aux(catalog, REG_DP_DP_HPD_INT_MASK,
+				config & DP_DP_HPD_INT_MASK);
+}
+
+void msm_dp_catalog_ctrl_hpd_enable(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	u32 reftimer = msm_dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER);
+
+	/* Configure REFTIMER and enable it */
+	reftimer |= DP_DP_HPD_REFTIMER_ENABLE;
+	msm_dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
+
+	/* Enable HPD */
+	msm_dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN);
+}
+
+void msm_dp_catalog_ctrl_hpd_disable(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	u32 reftimer = msm_dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER);
+
+	reftimer &= ~DP_DP_HPD_REFTIMER_ENABLE;
+	msm_dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer);
+
+	msm_dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, 0);
+}
+
+static void msm_dp_catalog_enable_sdp(struct msm_dp_catalog_private *catalog)
+{
+	/* trigger sdp */
+	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3, UPDATE_SDP);
+	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3, 0x0);
+}
+
+void msm_dp_catalog_ctrl_config_psr(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+	u32 config;
+
+	/* enable PSR1 function */
+	config = msm_dp_read_link(catalog, REG_PSR_CONFIG);
+	config |= PSR1_SUPPORTED;
+	msm_dp_write_link(catalog, REG_PSR_CONFIG, config);
+
+	msm_dp_write_ahb(catalog, REG_DP_INTR_MASK4, DP_INTERRUPT_MASK4);
+	msm_dp_catalog_enable_sdp(catalog);
+}
+
+void msm_dp_catalog_ctrl_set_psr(struct msm_dp_catalog *msm_dp_catalog, bool enter)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+			struct msm_dp_catalog_private, msm_dp_catalog);
+	u32 cmd;
+
+	cmd = msm_dp_read_link(catalog, REG_PSR_CMD);
+
+	cmd &= ~(PSR_ENTER | PSR_EXIT);
+
+	if (enter)
+		cmd |= PSR_ENTER;
+	else
+		cmd |= PSR_EXIT;
+
+	msm_dp_catalog_enable_sdp(catalog);
+	msm_dp_write_link(catalog, REG_PSR_CMD, cmd);
+}
+
+u32 msm_dp_catalog_link_is_connected(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+	u32 status;
+
+	status = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS);
+	drm_dbg_dp(catalog->drm_dev, "aux status: %#x\n", status);
+	status >>= DP_DP_HPD_STATE_STATUS_BITS_SHIFT;
+	status &= DP_DP_HPD_STATE_STATUS_BITS_MASK;
+
+	return status;
+}
+
+u32 msm_dp_catalog_hpd_get_intr_status(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+	int isr, mask;
+
+	isr = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS);
+	msm_dp_write_aux(catalog, REG_DP_DP_HPD_INT_ACK,
+				 (isr & DP_DP_HPD_INT_MASK));
+	mask = msm_dp_read_aux(catalog, REG_DP_DP_HPD_INT_MASK);
+
+	/*
+	 * We only want to return interrupts that are unmasked to the caller.
+	 * However, the interrupt status field also contains other
+	 * informational bits about the HPD state status, so we only mask
+	 * out the part of the register that tells us about which interrupts
+	 * are pending.
+	 */
+	return isr & (mask | ~DP_DP_HPD_INT_MASK);
+}
+
+u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+	u32 intr, intr_ack;
+
+	intr = msm_dp_read_ahb(catalog, REG_DP_INTR_STATUS4);
+	intr_ack = (intr & DP_INTERRUPT_STATUS4)
+			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
+	msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS4, intr_ack);
+
+	return intr;
+}
+
+int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+	u32 intr, intr_ack;
+
+	intr = msm_dp_read_ahb(catalog, REG_DP_INTR_STATUS2);
+	intr &= ~DP_INTERRUPT_STATUS2_MASK;
+	intr_ack = (intr & DP_INTERRUPT_STATUS2)
+			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
+	msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS2,
+			intr_ack | DP_INTERRUPT_STATUS2_MASK);
+
+	return intr;
+}
+
+int msm_dp_catalog_ctrl_get_interrupt_5(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+							      struct msm_dp_catalog_private,
+							      msm_dp_catalog);
+	u32 intr, intr_ack;
+
+	intr = msm_dp_read_ahb(catalog, REG_DP_INTR_STATUS5);
+	intr &= ~DP_INTERRUPT_STATUS5_MASK;
+	intr_ack = (intr & DP_INTERRUPT_STATUS5)
+			<< DP_INTERRUPT_STATUS_ACK_SHIFT;
+	msm_dp_write_ahb(catalog, REG_DP_INTR_STATUS5,
+			 intr_ack | DP_INTERRUPT_STATUS5_MASK);
+
+	return intr;
+}
+
+void msm_dp_catalog_ctrl_phy_reset(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	msm_dp_write_ahb(catalog, REG_DP_PHY_CTRL,
+			DP_PHY_CTRL_SW_RESET | DP_PHY_CTRL_SW_RESET_PLL);
+	usleep_range(1000, 1100); /* h/w recommended delay */
+	msm_dp_write_ahb(catalog, REG_DP_PHY_CTRL, 0x0);
+}
+
+void msm_dp_catalog_ctrl_send_phy_pattern(struct msm_dp_catalog *msm_dp_catalog,
+			u32 pattern)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+	u32 value = 0x0;
+
+	/* Make sure to clear the current pattern before starting a new one */
+	msm_dp_write_link(catalog, REG_DP_STATE_CTRL, 0x0);
+
+	drm_dbg_dp(catalog->drm_dev, "pattern: %#x\n", pattern);
+	switch (pattern) {
+	case DP_PHY_TEST_PATTERN_D10_2:
+		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
+				DP_STATE_CTRL_LINK_TRAINING_PATTERN1);
+		break;
+	case DP_PHY_TEST_PATTERN_ERROR_COUNT:
+		value &= ~(1 << 16);
+		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+					value);
+		value |= SCRAMBLER_RESET_COUNT_VALUE;
+		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+					value);
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_LEVELS,
+					DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2);
+		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
+					DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE);
+		break;
+	case DP_PHY_TEST_PATTERN_PRBS7:
+		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
+				DP_STATE_CTRL_LINK_PRBS7);
+		break;
+	case DP_PHY_TEST_PATTERN_80BIT_CUSTOM:
+		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
+				DP_STATE_CTRL_LINK_TEST_CUSTOM_PATTERN);
+		/* 00111110000011111000001111100000 */
+		msm_dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG0,
+				0x3E0F83E0);
+		/* 00001111100000111110000011111000 */
+		msm_dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG1,
+				0x0F83E0F8);
+		/* 1111100000111110 */
+		msm_dp_write_link(catalog, REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG2,
+				0x0000F83E);
+		break;
+	case DP_PHY_TEST_PATTERN_CP2520:
+		value = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+		value &= ~DP_MAINLINK_CTRL_SW_BYPASS_SCRAMBLER;
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, value);
+
+		value = DP_HBR2_ERM_PATTERN;
+		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+				value);
+		value |= SCRAMBLER_RESET_COUNT_VALUE;
+		msm_dp_write_link(catalog, REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET,
+					value);
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_LEVELS,
+					DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2);
+		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
+					DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE);
+		value = msm_dp_read_link(catalog, REG_DP_MAINLINK_CTRL);
+		value |= DP_MAINLINK_CTRL_ENABLE;
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL, value);
+		break;
+	case DP_PHY_TEST_PATTERN_SEL_MASK:
+		msm_dp_write_link(catalog, REG_DP_MAINLINK_CTRL,
+				DP_MAINLINK_CTRL_ENABLE);
+		msm_dp_write_link(catalog, REG_DP_STATE_CTRL,
+				DP_STATE_CTRL_LINK_TRAINING_PATTERN4);
+		break;
+	default:
+		drm_dbg_dp(catalog->drm_dev,
+				"No valid test pattern requested: %#x\n", pattern);
+		break;
+	}
+}
+
+u32 msm_dp_catalog_ctrl_read_phy_pattern(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	return msm_dp_read_link(catalog, REG_DP_MAINLINK_READY);
+}
+
+/* panel related catalog functions */
+int msm_dp_catalog_panel_timing_cfg(struct msm_dp_catalog *msm_dp_catalog, u32 total,
+				u32 sync_start, u32 width_blanking, u32 msm_dp_active)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+	u32 reg;
+	u32 offset = 0;
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_1)
+		offset = REG_DP1_TOTAL_HOR_VER - REG_DP_TOTAL_HOR_VER;
+
+	msm_dp_write_link(catalog, REG_DP_TOTAL_HOR_VER + offset, total);
+	msm_dp_write_link(catalog, REG_DP_START_HOR_VER_FROM_SYNC + offset, sync_start);
+	msm_dp_write_link(catalog, REG_DP_HSYNC_VSYNC_WIDTH_POLARITY + offset, width_blanking);
+	msm_dp_write_link(catalog, REG_DP_ACTIVE_HOR_VER + offset, msm_dp_active);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_0)
+		reg = msm_dp_read_p0(catalog, MMSS_DP_INTF_CONFIG);
+	else
+		reg = msm_dp_read_p1(catalog, MMSS_DP_INTF_CONFIG);
+
+	if (msm_dp_catalog->wide_bus_en)
+		reg |= DP_INTF_CONFIG_DATABUS_WIDEN;
+	else
+		reg &= ~DP_INTF_CONFIG_DATABUS_WIDEN;
+
+
+	DRM_DEBUG_DP("wide_bus_en=%d reg=%#x\n", msm_dp_catalog->wide_bus_en, reg);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_0)
+		msm_dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, reg);
+	else
+		msm_dp_write_p1(catalog, MMSS_DP_INTF_CONFIG, reg);
+
+	return 0;
+}
+
+int msm_dp_catalog_mst_async_fifo(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+							      struct msm_dp_catalog_private,
+							      msm_dp_catalog);
+
+	u32 reg;
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_0)
+		reg = msm_dp_read_p0(catalog, MMSS_DP_ASYNC_FIFO_CONFIG);
+	else
+		reg = msm_dp_read_p1(catalog, MMSS_DP_ASYNC_FIFO_CONFIG);
+
+	/* enable MST_FIFO_CONSTANT_FILL */
+	reg |= BIT(0);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_0)
+		msm_dp_write_p0(catalog, MMSS_DP_ASYNC_FIFO_CONFIG, reg);
+	else
+		msm_dp_write_p1(catalog, MMSS_DP_ASYNC_FIFO_CONFIG, reg);
+
+	return 0;
+}
+
+static void msm_dp_catalog_panel_send_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog, struct dp_sdp *vsc_sdp)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 header[2];
+	u32 val;
+	int i;
+	u32 msm_dp_generic_offset = 0;
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_1)
+		msm_dp_generic_offset = MMSS_DP1_GENERIC0_0 - MMSS_DP_GENERIC0_0;
+
+	msm_dp_utils_pack_sdp_header(&vsc_sdp->sdp_header, header);
+
+	msm_dp_write_link(catalog, MMSS_DP_GENERIC0_0 + msm_dp_generic_offset, header[0]);
+	msm_dp_write_link(catalog, MMSS_DP_GENERIC0_1 + msm_dp_generic_offset, header[1]);
+
+	for (i = 0; i < sizeof(vsc_sdp->db); i += 4) {
+		val = ((vsc_sdp->db[i]) | (vsc_sdp->db[i + 1] << 8) | (vsc_sdp->db[i + 2] << 16) |
+		       (vsc_sdp->db[i + 3] << 24));
+		msm_dp_write_link(catalog, MMSS_DP_GENERIC0_2 + i + msm_dp_generic_offset, val);
+	}
+}
+
+static void msm_dp_catalog_panel_update_sdp(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 hw_revision;
+	u32 sdp_cfg3_offset = 0;
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_1)
+		sdp_cfg3_offset = MMSS_DP1_SDP_CFG3 - MMSS_DP_SDP_CFG3;
+
+	hw_revision = msm_dp_catalog_hw_revision(msm_dp_catalog);
+	if (hw_revision < DP_HW_VERSION_1_2 && hw_revision >= DP_HW_VERSION_1_0) {
+		msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3 + sdp_cfg3_offset, 0x01);
+		msm_dp_write_link(catalog, MMSS_DP_SDP_CFG3 + sdp_cfg3_offset, 0x00);
+	}
+}
+
+void msm_dp_catalog_panel_enable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog, struct dp_sdp *vsc_sdp)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 cfg, cfg2, misc;
+	u32 misc_reg_offset = 0;
+	u32 sdp_cfg_offset = 0;
+	u32 sdp_cfg2_offset = 0;
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	if (msm_dp_catalog->stream_id == DP_STREAM_1) {
+		misc_reg_offset = REG_DP1_MISC1_MISC0 - REG_DP_MISC1_MISC0;
+		sdp_cfg_offset = MMSS_DP1_SDP_CFG - MMSS_DP_SDP_CFG;
+		sdp_cfg2_offset = MMSS_DP1_SDP_CFG2 - MMSS_DP_SDP_CFG2;
+	}
+
+	cfg = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG + sdp_cfg_offset);
+	cfg2 = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG2 + sdp_cfg2_offset);
+	misc = msm_dp_read_link(catalog, REG_DP_MISC1_MISC0 + misc_reg_offset);
+
+	cfg |= GEN0_SDP_EN;
+	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG + sdp_cfg_offset, cfg);
+
+	cfg2 |= GENERIC0_SDPSIZE_VALID;
+	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG2 + sdp_cfg2_offset, cfg2);
+
+	msm_dp_catalog_panel_send_vsc_sdp(msm_dp_catalog, vsc_sdp);
+
+	/* indicates presence of VSC (BIT(6) of MISC1) */
+	misc |= DP_MISC1_VSC_SDP;
+
+	drm_dbg_dp(catalog->drm_dev, "vsc sdp enable=1\n");
+
+	pr_debug("misc settings = 0x%x\n", misc);
+
+	msm_dp_write_link(catalog, REG_DP_MISC1_MISC0 + misc_reg_offset, misc);
+
+	msm_dp_catalog_panel_update_sdp(msm_dp_catalog);
+}
+
+void msm_dp_catalog_panel_disable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 cfg, cfg2, misc;
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	cfg = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG);
+	cfg2 = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG2);
+	misc = msm_dp_read_link(catalog, REG_DP_MISC1_MISC0);
+
+	cfg &= ~GEN0_SDP_EN;
+	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG, cfg);
+
+	cfg2 &= ~GENERIC0_SDPSIZE_VALID;
+	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG2, cfg2);
+
+	/* switch back to MSA */
+	misc &= ~DP_MISC1_VSC_SDP;
+
+	drm_dbg_dp(catalog->drm_dev, "vsc sdp enable=0\n");
+
+	pr_debug("misc settings = 0x%x\n", misc);
+	msm_dp_write_link(catalog, REG_DP_MISC1_MISC0, misc);
+
+	msm_dp_catalog_panel_update_sdp(msm_dp_catalog);
+}
+
+void msm_dp_catalog_trigger_act(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog;
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	msm_dp_write_link(catalog, REG_DP_MST_ACT, 0x1);
+
+	/* make sure ACT signal is performed */
+	wmb();
+}
+
+bool msm_dp_catalog_read_act_complete_sts(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog;
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	return msm_dp_read_link(catalog, REG_DP_MST_ACT);
+}
+
+void msm_dp_catalog_mst_channel_alloc(struct msm_dp_catalog *msm_dp_catalog,
+				      u32 ch, u32 ch_start_slot, u32 tot_slot_cnt)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 i, slot_reg_1, slot_reg_2, slot;
+	u32 reg_off = 0;
+	int const num_slots_per_reg = 32;
+
+	if (!msm_dp_catalog || ch >= DP_STREAM_MAX) {
+		DRM_ERROR("invalid input. ch %d\n", ch);
+		return;
+	}
+
+	if (ch_start_slot > DP_MAX_TIME_SLOTS ||
+	    (ch_start_slot + tot_slot_cnt > DP_MAX_TIME_SLOTS)) {
+		DRM_ERROR("invalid slots start %d, tot %d\n",
+			  ch_start_slot, tot_slot_cnt);
+		return;
+	}
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	drm_dbg_dp(catalog->drm_dev, "ch %d, start_slot %d, tot_slot %d\n",
+		   ch, ch_start_slot, tot_slot_cnt);
+
+	if (ch == DP_STREAM_1)
+		reg_off = REG_DP_DP1_TIMESLOT_1_32 - REG_DP_DP0_TIMESLOT_1_32;
+
+	slot_reg_1 = 0;
+	slot_reg_2 = 0;
+
+	if (ch_start_slot && tot_slot_cnt) {
+		ch_start_slot--;
+		for (i = 0; i < tot_slot_cnt; i++) {
+			if (ch_start_slot < num_slots_per_reg) {
+				slot_reg_1 |= BIT(ch_start_slot);
+			} else {
+				slot = ch_start_slot - num_slots_per_reg;
+				slot_reg_2 |= BIT(slot);
+			}
+			ch_start_slot++;
+		}
+	}
+
+	drm_dbg_dp(catalog->drm_dev, "ch:%d slot_reg_1:%d, slot_reg_2:%d\n", ch,
+		   slot_reg_1, slot_reg_2);
+
+	msm_dp_write_link(catalog, REG_DP_DP0_TIMESLOT_1_32 + reg_off, slot_reg_1);
+	msm_dp_write_link(catalog, REG_DP_DP0_TIMESLOT_33_63 + reg_off, slot_reg_2);
+}
+
+void msm_dp_catalog_ctrl_update_rg(struct msm_dp_catalog *msm_dp_catalog, u32 stream,
+				   u32 x_int, u32 y_frac_enum)
+{
+	struct msm_dp_catalog_private *catalog;
+
+	u32 rg, reg_off = 0;
+
+	if (!msm_dp_catalog || stream >= DP_STREAM_MAX) {
+		DRM_ERROR("invalid input. stream %d\n", stream);
+		return;
+	}
+
+	catalog = container_of(msm_dp_catalog, struct msm_dp_catalog_private, msm_dp_catalog);
+
+	rg = y_frac_enum;
+	rg |= (x_int << 16);
+
+	drm_dbg_dp(catalog->drm_dev, "stream: %d x_int:%d y_frac_enum:%d rg:%d\n",
+		   stream, x_int, y_frac_enum, rg);
+
+	if (stream == DP_STREAM_1)
+		reg_off = REG_DP_DP1_RG - REG_DP_DP0_RG;
+
+	msm_dp_write_link(catalog, REG_DP_DP0_RG + reg_off, rg);
+}
+
+void msm_dp_catalog_panel_tpg_enable(struct msm_dp_catalog *msm_dp_catalog,
+				struct drm_display_mode *drm_mode)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+	u32 hsync_period, vsync_period;
+	u32 display_v_start, display_v_end;
+	u32 hsync_start_x, hsync_end_x;
+	u32 v_sync_width;
+	u32 hsync_ctl;
+	u32 display_hctl;
+
+	/* TPG config parameters*/
+	hsync_period = drm_mode->htotal;
+	vsync_period = drm_mode->vtotal;
+
+	display_v_start = ((drm_mode->vtotal - drm_mode->vsync_start) *
+					hsync_period);
+	display_v_end = ((vsync_period - (drm_mode->vsync_start -
+					drm_mode->vdisplay))
+					* hsync_period) - 1;
+
+	display_v_start += drm_mode->htotal - drm_mode->hsync_start;
+	display_v_end -= (drm_mode->hsync_start - drm_mode->hdisplay);
+
+	hsync_start_x = drm_mode->htotal - drm_mode->hsync_start;
+	hsync_end_x = hsync_period - (drm_mode->hsync_start -
+					drm_mode->hdisplay) - 1;
+
+	v_sync_width = drm_mode->vsync_end - drm_mode->vsync_start;
+
+	hsync_ctl = (hsync_period << 16) |
+			(drm_mode->hsync_end - drm_mode->hsync_start);
+	display_hctl = (hsync_end_x << 16) | hsync_start_x;
+
+
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_CONFIG, 0x0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_HSYNC_CTL, hsync_ctl);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PERIOD_F0, vsync_period *
+			hsync_period);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F0, v_sync_width *
+			hsync_period);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PERIOD_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_HCTL, display_hctl);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_HCTL, 0);
+	msm_dp_write_p0(catalog, MMSS_INTF_DISPLAY_V_START_F0, display_v_start);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_V_END_F0, display_v_end);
+	msm_dp_write_p0(catalog, MMSS_INTF_DISPLAY_V_START_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_DISPLAY_V_END_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_START_F0, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_END_F0, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_START_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_ACTIVE_V_END_F1, 0);
+	msm_dp_write_p0(catalog, MMSS_DP_INTF_POLARITY_CTL, 0);
+
+	msm_dp_write_p0(catalog, MMSS_DP_TPG_MAIN_CONTROL,
+				DP_TPG_CHECKERED_RECT_PATTERN);
+	msm_dp_write_p0(catalog, MMSS_DP_TPG_VIDEO_CONFIG,
+				DP_TPG_VIDEO_CONFIG_BPP_8BIT |
+				DP_TPG_VIDEO_CONFIG_RGB);
+	msm_dp_write_p0(catalog, MMSS_DP_BIST_ENABLE,
+				DP_BIST_ENABLE_DPBIST_EN);
+	msm_dp_write_p0(catalog, MMSS_DP_TIMING_ENGINE_EN,
+				DP_TIMING_ENGINE_EN_EN);
+	drm_dbg_dp(catalog->drm_dev, "%s: enabled tpg\n", __func__);
+}
+
+void msm_dp_catalog_panel_tpg_disable(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog = container_of(msm_dp_catalog,
+				struct msm_dp_catalog_private, msm_dp_catalog);
+
+	msm_dp_write_p0(catalog, MMSS_DP_TPG_MAIN_CONTROL, 0x0);
+	msm_dp_write_p0(catalog, MMSS_DP_BIST_ENABLE, 0x0);
+	msm_dp_write_p0(catalog, MMSS_DP_TIMING_ENGINE_EN, 0x0);
+}
+
+static void __iomem *msm_dp_ioremap(struct platform_device *pdev, int idx, size_t *len)
+{
+	struct resource *res;
+	void __iomem *base;
+
+	base = devm_platform_get_and_ioremap_resource(pdev, idx, &res);
+	if (!IS_ERR(base))
+		*len = resource_size(res);
+
+	return base;
+}
+
+static int msm_dp_catalog_get_io(struct msm_dp_catalog_private *catalog)
+{
+	struct platform_device *pdev = to_platform_device(catalog->dev);
+	struct dss_io_data *dss = &catalog->io;
+
+	dss->ahb.base = msm_dp_ioremap(pdev, 0, &dss->ahb.len);
+	if (IS_ERR(dss->ahb.base))
+		return PTR_ERR(dss->ahb.base);
+
+	dss->aux.base = msm_dp_ioremap(pdev, 1, &dss->aux.len);
+	if (IS_ERR(dss->aux.base)) {
+		/*
+		 * The initial binding had a single reg, but in order to
+		 * support variation in the sub-region sizes this was split.
+		 * msm_dp_ioremap() will fail with -EINVAL here if only a single
+		 * reg is specified, so fill in the sub-region offsets and
+		 * lengths based on this single region.
+		 */
+		if (PTR_ERR(dss->aux.base) == -EINVAL) {
+			if (dss->ahb.len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) {
+				DRM_ERROR("legacy memory region not large enough\n");
+				return -EINVAL;
+			}
+
+			dss->ahb.len = DP_DEFAULT_AHB_SIZE;
+			dss->aux.base = dss->ahb.base + DP_DEFAULT_AUX_OFFSET;
+			dss->aux.len = DP_DEFAULT_AUX_SIZE;
+			dss->link.base = dss->ahb.base + DP_DEFAULT_LINK_OFFSET;
+			dss->link.len = DP_DEFAULT_LINK_SIZE;
+			dss->p0.base = dss->ahb.base + DP_DEFAULT_P0_OFFSET;
+			dss->p0.len = DP_DEFAULT_P0_SIZE;
+		} else {
+			DRM_ERROR("unable to remap aux region: %pe\n", dss->aux.base);
+			return PTR_ERR(dss->aux.base);
+		}
+	} else {
+		dss->link.base = msm_dp_ioremap(pdev, 2, &dss->link.len);
+		if (IS_ERR(dss->link.base)) {
+			DRM_ERROR("unable to remap link region: %pe\n", dss->link.base);
+			return PTR_ERR(dss->link.base);
+		}
+
+		dss->p0.base = msm_dp_ioremap(pdev, 3, &dss->p0.len);
+		if (IS_ERR(dss->p0.base)) {
+			DRM_ERROR("unable to remap p0 region: %pe\n", dss->p0.base);
+			return PTR_ERR(dss->p0.base);
+		}
+
+		dss->p1.base = msm_dp_ioremap(pdev, 4, &dss->p1.len);
+		if (IS_ERR(dss->p1.base)) {
+			DRM_ERROR("unable to remap p1 region: %pe\n", dss->p1.base);
+			return PTR_ERR(dss->p1.base);
+		}
+	}
+
+	return 0;
+}
+
+struct msm_dp_catalog *msm_dp_catalog_get(struct device *dev)
+{
+	struct msm_dp_catalog_private *catalog;
+	int ret;
+
+	catalog  = devm_kzalloc(dev, sizeof(*catalog), GFP_KERNEL);
+	if (!catalog)
+		return ERR_PTR(-ENOMEM);
+
+	catalog->dev = dev;
+
+	ret = msm_dp_catalog_get_io(catalog);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &catalog->msm_dp_catalog;
+}
+
+u32 msm_dp_catalog_audio_get_header(struct msm_dp_catalog *msm_dp_catalog,
+				enum msm_dp_catalog_audio_sdp_type sdp,
+				enum msm_dp_catalog_audio_header_type header)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 (*sdp_map)[DP_AUDIO_SDP_HEADER_MAX];
+
+	catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
+
+	sdp_map = catalog->audio_map;
+
+	return msm_dp_read_link(catalog, sdp_map[sdp][header]);
+}
+
+void msm_dp_catalog_audio_set_header(struct msm_dp_catalog *msm_dp_catalog,
+				 enum msm_dp_catalog_audio_sdp_type sdp,
+				 enum msm_dp_catalog_audio_header_type header,
+				 u32 data)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 (*sdp_map)[DP_AUDIO_SDP_HEADER_MAX];
+
+	if (!msm_dp_catalog)
+		return;
+
+	catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
+
+	sdp_map = catalog->audio_map;
+
+	msm_dp_write_link(catalog, sdp_map[sdp][header], data);
+}
+
+void msm_dp_catalog_audio_config_acr(struct msm_dp_catalog *msm_dp_catalog, u32 select)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 acr_ctrl;
+
+	if (!msm_dp_catalog)
+		return;
+
+	catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
+
+	acr_ctrl = select << 4 | BIT(31) | BIT(8) | BIT(14);
+
+	drm_dbg_dp(catalog->drm_dev, "select: %#x, acr_ctrl: %#x\n",
+					select, acr_ctrl);
+
+	msm_dp_write_link(catalog, MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl);
+}
+
+void msm_dp_catalog_audio_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 audio_ctrl;
+
+	if (!msm_dp_catalog)
+		return;
+
+	catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
+
+	audio_ctrl = msm_dp_read_link(catalog, MMSS_DP_AUDIO_CFG);
+
+	if (enable)
+		audio_ctrl |= BIT(0);
+	else
+		audio_ctrl &= ~BIT(0);
+
+	drm_dbg_dp(catalog->drm_dev, "dp_audio_cfg = 0x%x\n", audio_ctrl);
+
+	msm_dp_write_link(catalog, MMSS_DP_AUDIO_CFG, audio_ctrl);
+	/* make sure audio engine is disabled */
+	wmb();
+}
+
+void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 sdp_cfg = 0;
+	u32 sdp_cfg2 = 0;
+
+	if (!msm_dp_catalog)
+		return;
+
+	catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
+
+	sdp_cfg = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG);
+	/* AUDIO_TIMESTAMP_SDP_EN */
+	sdp_cfg |= BIT(1);
+	/* AUDIO_STREAM_SDP_EN */
+	sdp_cfg |= BIT(2);
+	/* AUDIO_COPY_MANAGEMENT_SDP_EN */
+	sdp_cfg |= BIT(5);
+	/* AUDIO_ISRC_SDP_EN  */
+	sdp_cfg |= BIT(6);
+	/* AUDIO_INFOFRAME_SDP_EN  */
+	sdp_cfg |= BIT(20);
+
+	drm_dbg_dp(catalog->drm_dev, "sdp_cfg = 0x%x\n", sdp_cfg);
+
+	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG, sdp_cfg);
+
+	sdp_cfg2 = msm_dp_read_link(catalog, MMSS_DP_SDP_CFG2);
+	/* IFRM_REGSRC -> Do not use reg values */
+	sdp_cfg2 &= ~BIT(0);
+	/* AUDIO_STREAM_HB3_REGSRC-> Do not use reg values */
+	sdp_cfg2 &= ~BIT(1);
+
+	drm_dbg_dp(catalog->drm_dev, "sdp_cfg2 = 0x%x\n", sdp_cfg2);
+
+	msm_dp_write_link(catalog, MMSS_DP_SDP_CFG2, sdp_cfg2);
+}
+
+void msm_dp_catalog_audio_init(struct msm_dp_catalog *msm_dp_catalog)
+{
+	struct msm_dp_catalog_private *catalog;
+
+	static u32 sdp_map[][DP_AUDIO_SDP_HEADER_MAX] = {
+		{
+			MMSS_DP_AUDIO_STREAM_0,
+			MMSS_DP_AUDIO_STREAM_1,
+			MMSS_DP_AUDIO_STREAM_1,
+		},
+		{
+			MMSS_DP_AUDIO_TIMESTAMP_0,
+			MMSS_DP_AUDIO_TIMESTAMP_1,
+			MMSS_DP_AUDIO_TIMESTAMP_1,
+		},
+		{
+			MMSS_DP_AUDIO_INFOFRAME_0,
+			MMSS_DP_AUDIO_INFOFRAME_1,
+			MMSS_DP_AUDIO_INFOFRAME_1,
+		},
+		{
+			MMSS_DP_AUDIO_COPYMANAGEMENT_0,
+			MMSS_DP_AUDIO_COPYMANAGEMENT_1,
+			MMSS_DP_AUDIO_COPYMANAGEMENT_1,
+		},
+		{
+			MMSS_DP_AUDIO_ISRC_0,
+			MMSS_DP_AUDIO_ISRC_1,
+			MMSS_DP_AUDIO_ISRC_1,
+		},
+	};
+
+	if (!msm_dp_catalog)
+		return;
+
+	catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
+
+	catalog->audio_map = sdp_map;
+}
+
+void msm_dp_catalog_audio_sfe_level(struct msm_dp_catalog *msm_dp_catalog, u32 safe_to_exit_level)
+{
+	struct msm_dp_catalog_private *catalog;
+	u32 mainlink_levels;
+
+	if (!msm_dp_catalog)
+		return;
+
+	catalog = container_of(msm_dp_catalog,
+		struct msm_dp_catalog_private, msm_dp_catalog);
+
+	mainlink_levels = msm_dp_read_link(catalog, REG_DP_MAINLINK_LEVELS);
+	mainlink_levels &= 0xFE0;
+	mainlink_levels |= safe_to_exit_level;
+
+	drm_dbg_dp(catalog->drm_dev,
+			"mainlink_level = 0x%x, safe_to_exit_level = 0x%x\n",
+			 mainlink_levels, safe_to_exit_level);
+
+	msm_dp_write_link(catalog, REG_DP_MAINLINK_LEVELS, mainlink_levels);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_catalog.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_catalog.h
@@ -0,0 +1,154 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DP_CATALOG_H_
+#define _DP_CATALOG_H_
+
+#include <drm/drm_modes.h>
+
+#include "dp_utils.h"
+#include "disp/msm_disp_snapshot.h"
+
+/* interrupts */
+#define DP_INTR_HPD		BIT(0)
+#define DP_INTR_AUX_XFER_DONE	BIT(3)
+#define DP_INTR_WRONG_ADDR	BIT(6)
+#define DP_INTR_TIMEOUT		BIT(9)
+#define DP_INTR_NACK_DEFER	BIT(12)
+#define DP_INTR_WRONG_DATA_CNT	BIT(15)
+#define DP_INTR_I2C_NACK	BIT(18)
+#define DP_INTR_I2C_DEFER	BIT(21)
+#define DP_INTR_PLL_UNLOCKED	BIT(24)
+#define DP_INTR_AUX_ERROR	BIT(27)
+
+#define DP_INTR_READY_FOR_VIDEO		BIT(0)
+#define DP_INTR_IDLE_PATTERN_SENT	BIT(3)
+#define DP_INTR_FRAME_END		BIT(6)
+#define DP_INTR_CRC_UPDATED		BIT(9)
+
+#define DP_INTR_DP0_VCPF_SENT		BIT(0)
+#define DP_INTR_DP1_VCPF_SENT		BIT(3)
+
+#define DP_HW_VERSION_1_0	0x10000000
+#define DP_HW_VERSION_1_2	0x10020000
+
+#define DP_MAX_TIME_SLOTS 64
+
+enum msm_dp_catalog_audio_sdp_type {
+	DP_AUDIO_SDP_STREAM,
+	DP_AUDIO_SDP_TIMESTAMP,
+	DP_AUDIO_SDP_INFOFRAME,
+	DP_AUDIO_SDP_COPYMANAGEMENT,
+	DP_AUDIO_SDP_ISRC,
+	DP_AUDIO_SDP_MAX,
+};
+
+enum msm_dp_catalog_audio_header_type {
+	DP_AUDIO_SDP_HEADER_1,
+	DP_AUDIO_SDP_HEADER_2,
+	DP_AUDIO_SDP_HEADER_3,
+	DP_AUDIO_SDP_HEADER_MAX,
+};
+
+/* stream id */
+enum msm_dp_stream_id {
+	DP_STREAM_0,
+	DP_STREAM_1,
+	DP_STREAM_2,
+	DP_STREAM_3,
+	DP_STREAM_MAX,
+};
+
+struct msm_dp_catalog {
+	bool wide_bus_en;
+	enum msm_dp_stream_id stream_id;
+};
+
+/* Debug module */
+void msm_dp_catalog_snapshot(struct msm_dp_catalog *msm_dp_catalog, struct msm_disp_state *disp_state);
+
+/* AUX APIs */
+u32 msm_dp_catalog_aux_read_data(struct msm_dp_catalog *msm_dp_catalog);
+int msm_dp_catalog_aux_write_data(struct msm_dp_catalog *msm_dp_catalog, u32 data);
+int msm_dp_catalog_aux_write_trans(struct msm_dp_catalog *msm_dp_catalog, u32 data);
+int msm_dp_catalog_aux_clear_trans(struct msm_dp_catalog *msm_dp_catalog, bool read);
+int msm_dp_catalog_aux_clear_hw_interrupts(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_aux_reset(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_aux_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable);
+int msm_dp_catalog_aux_wait_for_hpd_connect_state(struct msm_dp_catalog *msm_dp_catalog,
+					      unsigned long wait_us);
+u32 msm_dp_catalog_aux_get_irq(struct msm_dp_catalog *msm_dp_catalog);
+
+/* DP Controller APIs */
+void msm_dp_catalog_ctrl_state_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 state);
+void msm_dp_catalog_ctrl_config_ctrl(struct msm_dp_catalog *msm_dp_catalog, u32 config);
+void msm_dp_catalog_ctrl_lane_mapping(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_mainlink_ctrl(struct msm_dp_catalog *msm_dp_catalog, bool enable);
+void msm_dp_catalog_ctrl_psr_mainlink_enable(struct msm_dp_catalog *msm_dp_catalog, bool enable);
+void msm_dp_catalog_setup_peripheral_flush(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_config_misc(struct msm_dp_catalog *msm_dp_catalog, u32 cc, u32 tb);
+void msm_dp_catalog_ctrl_config_msa(struct msm_dp_catalog *msm_dp_catalog, u32 rate,
+				u32 stream_rate_khz, bool is_ycbcr_420);
+int msm_dp_catalog_ctrl_set_pattern_state_bit(struct msm_dp_catalog *msm_dp_catalog, u32 pattern);
+u32 msm_dp_catalog_hw_revision(const struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_reset(struct msm_dp_catalog *msm_dp_catalog);
+bool msm_dp_catalog_ctrl_mainlink_ready(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_enable_irq(struct msm_dp_catalog *msm_dp_catalog, bool enable);
+void msm_dp_catalog_hpd_config_intr(struct msm_dp_catalog *msm_dp_catalog,
+			u32 intr_mask, bool en);
+void msm_dp_catalog_ctrl_hpd_enable(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_hpd_disable(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_config_psr(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_set_psr(struct msm_dp_catalog *msm_dp_catalog, bool enter);
+u32 msm_dp_catalog_link_is_connected(struct msm_dp_catalog *msm_dp_catalog);
+u32 msm_dp_catalog_hpd_get_intr_status(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_phy_reset(struct msm_dp_catalog *msm_dp_catalog);
+int msm_dp_catalog_ctrl_get_interrupt(struct msm_dp_catalog *msm_dp_catalog);
+int msm_dp_catalog_ctrl_get_interrupt_5(struct msm_dp_catalog *msm_dp_catalog);
+u32 msm_dp_catalog_ctrl_read_psr_interrupt_status(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_ctrl_update_transfer_unit(struct msm_dp_catalog *msm_dp_catalog,
+				u32 msm_dp_tu, u32 valid_boundary,
+				u32 valid_boundary2);
+void msm_dp_catalog_ctrl_send_phy_pattern(struct msm_dp_catalog *msm_dp_catalog,
+				u32 pattern);
+u32 msm_dp_catalog_ctrl_read_phy_pattern(struct msm_dp_catalog *msm_dp_catalog);
+
+/* DP Panel APIs */
+int msm_dp_catalog_panel_timing_cfg(struct msm_dp_catalog *msm_dp_catalog, u32 total,
+				u32 sync_start, u32 width_blanking, u32 msm_dp_active);
+void msm_dp_catalog_panel_enable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog, struct dp_sdp *vsc_sdp);
+void msm_dp_catalog_panel_disable_vsc_sdp(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_dump_regs(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_panel_tpg_enable(struct msm_dp_catalog *msm_dp_catalog,
+				struct drm_display_mode *drm_mode);
+void msm_dp_catalog_panel_tpg_disable(struct msm_dp_catalog *msm_dp_catalog);
+
+struct msm_dp_catalog *msm_dp_catalog_get(struct device *dev);
+
+/* DP Audio APIs */
+u32 msm_dp_catalog_audio_get_header(struct msm_dp_catalog *msm_dp_catalog,
+				enum msm_dp_catalog_audio_sdp_type sdp,
+				enum msm_dp_catalog_audio_header_type header);
+void msm_dp_catalog_audio_set_header(struct msm_dp_catalog *msm_dp_catalog,
+				 enum msm_dp_catalog_audio_sdp_type sdp,
+				 enum msm_dp_catalog_audio_header_type header,
+				 u32 data);
+void msm_dp_catalog_audio_config_acr(struct msm_dp_catalog *catalog, u32 select);
+void msm_dp_catalog_audio_enable(struct msm_dp_catalog *catalog, bool enable);
+void msm_dp_catalog_audio_config_sdp(struct msm_dp_catalog *catalog);
+void msm_dp_catalog_audio_init(struct msm_dp_catalog *catalog);
+void msm_dp_catalog_audio_sfe_level(struct msm_dp_catalog *catalog, u32 safe_to_exit_level);
+
+/* DP MST APIs */
+void msm_dp_catalog_trigger_act(struct msm_dp_catalog *msm_dp_catalog);
+bool msm_dp_catalog_read_act_complete_sts(struct msm_dp_catalog *msm_dp_catalog);
+void msm_dp_catalog_mst_config(struct msm_dp_catalog *msm_dp_catalog, bool enable);
+void msm_dp_catalog_mst_channel_alloc(struct msm_dp_catalog *msm_dp_catalog,
+				      u32 ch, u32 ch_start_slot, u32 tot_slot_cnt);
+void msm_dp_catalog_ctrl_update_rg(struct msm_dp_catalog *msm_dp_catalog, u32 stream,
+				   u32 x_int, u32 y_frac_enum);
+int msm_dp_catalog_mst_async_fifo(struct msm_dp_catalog *msm_dp_catalog);
+
+#endif /* _DP_CATALOG_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_ctrl.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_ctrl.c
@@ -0,0 +1,2484 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
+
+#include <linux/types.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/phy/phy.h>
+#include <linux/phy/phy-dp.h>
+#include <linux/pm_opp.h>
+
+#include <drm/display/drm_dp_helper.h>
+#include <drm/drm_fixed.h>
+#include <drm/drm_print.h>
+
+#include "dp_reg.h"
+#include "dp_ctrl.h"
+#include "dp_link.h"
+
+#define DP_KHZ_TO_HZ 1000
+#define IDLE_PATTERN_COMPLETION_TIMEOUT_JIFFIES	(30 * HZ / 1000) /* 30 ms */
+#define PSR_OPERATION_COMPLETION_TIMEOUT_JIFFIES       (300 * HZ / 1000) /* 300 ms */
+#define WAIT_FOR_VIDEO_READY_TIMEOUT_JIFFIES (HZ / 2)
+
+#define DP_CTRL_INTR_READY_FOR_VIDEO     BIT(0)
+#define DP_CTRL_INTR_IDLE_PATTERN_SENT  BIT(3)
+#define DP_CTRL_INTR_DP0_VCPF_SENT       BIT(0)
+#define DP_CTRL_INTR_DP1_VCPF_SENT       BIT(3)
+
+#define MST_DP0_PUSH_VCPF		BIT(12)
+#define MST_DP1_PUSH_VCPF		BIT(14)
+
+#define MR_LINK_TRAINING1  0x8
+#define MR_LINK_SYMBOL_ERM 0x80
+#define MR_LINK_PRBS7 0x100
+#define MR_LINK_CUSTOM80 0x200
+#define MR_LINK_TRAINING4  0x40
+
+enum {
+	DP_TRAINING_NONE,
+	DP_TRAINING_1,
+	DP_TRAINING_2,
+};
+
+struct msm_dp_tu_calc_input {
+	u64 lclk;        /* 162, 270, 540 and 810 */
+	u64 pclk_khz;    /* in KHz */
+	u64 hactive;     /* active h-width */
+	u64 hporch;      /* bp + fp + pulse */
+	int nlanes;      /* no.of.lanes */
+	int bpp;         /* bits */
+	int pixel_enc;   /* 444, 420, 422 */
+	int dsc_en;     /* dsc on/off */
+	int async_en;   /* async mode */
+	int fec_en;     /* fec */
+	int compress_ratio; /* 2:1 = 200, 3:1 = 300, 3.75:1 = 375 */
+	int num_of_dsc_slices; /* number of slices per line */
+};
+
+struct msm_dp_vc_tu_mapping_table {
+	u32 vic;
+	u8 lanes;
+	u8 lrate; /* DP_LINK_RATE -> 162(6), 270(10), 540(20), 810 (30) */
+	u8 bpp;
+	u8 valid_boundary_link;
+	u16 delay_start_link;
+	bool boundary_moderation_en;
+	u8 valid_lower_boundary_link;
+	u8 upper_boundary_count;
+	u8 lower_boundary_count;
+	u8 tu_size_minus1;
+};
+
+struct msm_dp_mst_ch_slot_info {
+	u32 start_slot;
+	u32 tot_slots;
+};
+
+struct msm_dp_ctrl_private {
+	struct msm_dp_ctrl msm_dp_ctrl;
+	struct drm_device *drm_dev;
+	struct device *dev;
+	struct drm_dp_aux *aux;
+	struct msm_dp_panel *panel;
+	struct msm_dp_link *link;
+	struct msm_dp_catalog *catalog;
+
+	struct phy *phy;
+
+	unsigned int num_core_clks;
+	struct clk_bulk_data *core_clks;
+
+	unsigned int num_link_clks;
+	struct clk_bulk_data *link_clks;
+
+	struct clk *pixel_clk[DP_STREAM_MAX];
+
+	union phy_configure_opts phy_opts;
+
+	struct completion idle_comp;
+	struct completion psr_op_comp;
+	struct completion video_comp;
+
+	bool core_clks_on;
+	bool link_clks_on;
+	bool mst_active;
+	bool stream_clks_on[DP_STREAM_MAX];
+
+	struct msm_dp_mst_ch_slot_info mst_ch_info[DP_STREAM_MAX];
+};
+
+static int msm_dp_aux_link_configure(struct drm_dp_aux *aux,
+					struct msm_dp_link_info *link)
+{
+	u8 values[2];
+	int err;
+
+	values[0] = drm_dp_link_rate_to_bw_code(link->rate);
+	values[1] = link->num_lanes;
+
+	if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING)
+		values[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+
+	err = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, values, sizeof(values));
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	reinit_completion(&ctrl->idle_comp);
+	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_PUSH_IDLE);
+
+	if (!wait_for_completion_timeout(&ctrl->idle_comp,
+			IDLE_PATTERN_COMPLETION_TIMEOUT_JIFFIES))
+		pr_warn("PUSH_IDLE pattern timedout\n");
+
+	drm_dbg_dp(ctrl->drm_dev, "mainlink off\n");
+}
+
+void msm_dp_ctrl_push_vcpf(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *msm_dp_panel)
+{
+	u32 state = 0x0;
+	struct msm_dp_ctrl_private *ctrl;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	if (msm_dp_panel->stream_id >= DP_STREAM_MAX) {
+		DRM_ERROR("invalid input\n");
+		return;
+	}
+
+	if (msm_dp_panel->stream_id == DP_STREAM_0)
+		state |= MST_DP0_PUSH_VCPF;
+	else
+		state |= MST_DP1_PUSH_VCPF;
+
+	reinit_completion(&ctrl->idle_comp);
+
+	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, state);
+
+	if (!wait_for_completion_timeout(&ctrl->idle_comp,
+					 IDLE_PATTERN_COMPLETION_TIMEOUT_JIFFIES))
+		pr_warn("PUSH_VCPF pattern timedout\n");
+
+	drm_dbg_dp(ctrl->drm_dev, "mainlink off\n");
+}
+
+static void msm_dp_ctrl_config_ctrl(struct msm_dp_ctrl_private *ctrl,
+		struct msm_dp_panel *msm_dp_panel)
+{
+	u32 config = 0, tbd;
+	const u8 *dpcd = ctrl->panel->dpcd;
+
+	/* Default-> LSCLK DIV: 1/4 LCLK  */
+	config |= (2 << DP_CONFIGURATION_CTRL_LSCLK_DIV_SHIFT);
+
+	if (msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420)
+		config |= DP_CONFIGURATION_CTRL_RGB_YUV; /* YUV420 */
+
+	/* Scrambler reset enable */
+	if (drm_dp_alternate_scrambler_reset_cap(dpcd))
+		config |= DP_CONFIGURATION_CTRL_ASSR;
+
+	tbd = msm_dp_link_get_test_bits_depth(ctrl->link,
+		msm_dp_panel->msm_dp_mode.bpp);
+
+	config |= tbd << DP_CONFIGURATION_CTRL_BPC_SHIFT;
+
+	/* Num of Lanes */
+	config |= ((ctrl->link->link_params.num_lanes - 1)
+			<< DP_CONFIGURATION_CTRL_NUM_OF_LANES_SHIFT);
+
+	if (drm_dp_enhanced_frame_cap(dpcd))
+		config |= DP_CONFIGURATION_CTRL_ENHANCED_FRAMING;
+
+	config |= DP_CONFIGURATION_CTRL_P_INTERLACED; /* progressive video */
+
+	/* sync clock & static Mvid */
+	config |= DP_CONFIGURATION_CTRL_STATIC_DYNAMIC_CN;
+	config |= DP_CONFIGURATION_CTRL_SYNC_ASYNC_CLK;
+
+	if (ctrl->panel->psr_cap.version)
+		config |= DP_CONFIGURATION_CTRL_SEND_VSC;
+
+	msm_dp_catalog_ctrl_config_ctrl(ctrl->catalog, config);
+}
+
+static void msm_dp_ctrl_configure_source_params(struct msm_dp_ctrl_private *ctrl,
+		struct msm_dp_panel *msm_dp_panel)
+{
+	u32 cc, tb;
+	ctrl->catalog->stream_id = msm_dp_panel->stream_id;
+
+	msm_dp_catalog_ctrl_lane_mapping(ctrl->catalog);
+	msm_dp_catalog_setup_peripheral_flush(ctrl->catalog);
+
+	if (ctrl->mst_active)
+		msm_dp_catalog_mst_config(ctrl->catalog, true);
+
+	msm_dp_ctrl_config_ctrl(ctrl, msm_dp_panel);
+
+	tb = msm_dp_link_get_test_bits_depth(ctrl->link,
+		msm_dp_panel->msm_dp_mode.bpp);
+	cc = msm_dp_link_get_colorimetry_config(ctrl->link);
+	msm_dp_catalog_ctrl_config_misc(ctrl->catalog, cc, tb);
+	msm_dp_panel_timing_cfg(msm_dp_panel);
+
+	if (ctrl->mst_active)
+		msm_dp_catalog_mst_async_fifo(ctrl->catalog);
+}
+
+/*
+ * The structure and few functions present below are IP/Hardware
+ * specific implementation. Most of the implementation will not
+ * have coding comments
+ */
+struct tu_algo_data {
+	s64 lclk_fp;
+	s64 pclk_fp;
+	s64 lwidth;
+	s64 lwidth_fp;
+	s64 hbp_relative_to_pclk;
+	s64 hbp_relative_to_pclk_fp;
+	int nlanes;
+	int bpp;
+	int pixelEnc;
+	int dsc_en;
+	int async_en;
+	int bpc;
+
+	uint delay_start_link_extra_pixclk;
+	int extra_buffer_margin;
+	s64 ratio_fp;
+	s64 original_ratio_fp;
+
+	s64 err_fp;
+	s64 n_err_fp;
+	s64 n_n_err_fp;
+	int tu_size;
+	int tu_size_desired;
+	int tu_size_minus1;
+
+	int valid_boundary_link;
+	s64 resulting_valid_fp;
+	s64 total_valid_fp;
+	s64 effective_valid_fp;
+	s64 effective_valid_recorded_fp;
+	int n_tus;
+	int n_tus_per_lane;
+	int paired_tus;
+	int remainder_tus;
+	int remainder_tus_upper;
+	int remainder_tus_lower;
+	int extra_bytes;
+	int filler_size;
+	int delay_start_link;
+
+	int extra_pclk_cycles;
+	int extra_pclk_cycles_in_link_clk;
+	s64 ratio_by_tu_fp;
+	s64 average_valid2_fp;
+	int new_valid_boundary_link;
+	int remainder_symbols_exist;
+	int n_symbols;
+	s64 n_remainder_symbols_per_lane_fp;
+	s64 last_partial_tu_fp;
+	s64 TU_ratio_err_fp;
+
+	int n_tus_incl_last_incomplete_tu;
+	int extra_pclk_cycles_tmp;
+	int extra_pclk_cycles_in_link_clk_tmp;
+	int extra_required_bytes_new_tmp;
+	int filler_size_tmp;
+	int lower_filler_size_tmp;
+	int delay_start_link_tmp;
+
+	bool boundary_moderation_en;
+	int boundary_mod_lower_err;
+	int upper_boundary_count;
+	int lower_boundary_count;
+	int i_upper_boundary_count;
+	int i_lower_boundary_count;
+	int valid_lower_boundary_link;
+	int even_distribution_BF;
+	int even_distribution_legacy;
+	int even_distribution;
+	int min_hblank_violated;
+	s64 delay_start_time_fp;
+	s64 hbp_time_fp;
+	s64 hactive_time_fp;
+	s64 diff_abs_fp;
+
+	s64 ratio;
+};
+
+static int _tu_param_compare(s64 a, s64 b)
+{
+	u32 a_sign;
+	u32 b_sign;
+	s64 a_temp, b_temp, minus_1;
+
+	if (a == b)
+		return 0;
+
+	minus_1 = drm_fixp_from_fraction(-1, 1);
+
+	a_sign = (a >> 32) & 0x80000000 ? 1 : 0;
+
+	b_sign = (b >> 32) & 0x80000000 ? 1 : 0;
+
+	if (a_sign > b_sign)
+		return 2;
+	else if (b_sign > a_sign)
+		return 1;
+
+	if (!a_sign && !b_sign) { /* positive */
+		if (a > b)
+			return 1;
+		else
+			return 2;
+	} else { /* negative */
+		a_temp = drm_fixp_mul(a, minus_1);
+		b_temp = drm_fixp_mul(b, minus_1);
+
+		if (a_temp > b_temp)
+			return 2;
+		else
+			return 1;
+	}
+}
+
+static void msm_dp_panel_update_tu_timings(struct msm_dp_tu_calc_input *in,
+					struct tu_algo_data *tu)
+{
+	int nlanes = in->nlanes;
+	int dsc_num_slices = in->num_of_dsc_slices;
+	int dsc_num_bytes  = 0;
+	int numerator;
+	s64 pclk_dsc_fp;
+	s64 dwidth_dsc_fp;
+	s64 hbp_dsc_fp;
+
+	int tot_num_eoc_symbols = 0;
+	int tot_num_hor_bytes   = 0;
+	int tot_num_dummy_bytes = 0;
+	int dwidth_dsc_bytes    = 0;
+	int  eoc_bytes           = 0;
+
+	s64 temp1_fp, temp2_fp, temp3_fp;
+
+	tu->lclk_fp              = drm_fixp_from_fraction(in->lclk, 1);
+	tu->pclk_fp              = drm_fixp_from_fraction(in->pclk_khz, 1000);
+	tu->lwidth               = in->hactive;
+	tu->hbp_relative_to_pclk = in->hporch;
+	tu->nlanes               = in->nlanes;
+	tu->bpp                  = in->bpp;
+	tu->pixelEnc             = in->pixel_enc;
+	tu->dsc_en               = in->dsc_en;
+	tu->async_en             = in->async_en;
+	tu->lwidth_fp            = drm_fixp_from_fraction(in->hactive, 1);
+	tu->hbp_relative_to_pclk_fp = drm_fixp_from_fraction(in->hporch, 1);
+
+	if (tu->pixelEnc == 420) {
+		temp1_fp = drm_fixp_from_fraction(2, 1);
+		tu->pclk_fp = drm_fixp_div(tu->pclk_fp, temp1_fp);
+		tu->lwidth_fp = drm_fixp_div(tu->lwidth_fp, temp1_fp);
+		tu->hbp_relative_to_pclk_fp =
+				drm_fixp_div(tu->hbp_relative_to_pclk_fp, 2);
+	}
+
+	if (tu->pixelEnc == 422) {
+		switch (tu->bpp) {
+		case 24:
+			tu->bpp = 16;
+			tu->bpc = 8;
+			break;
+		case 30:
+			tu->bpp = 20;
+			tu->bpc = 10;
+			break;
+		default:
+			tu->bpp = 16;
+			tu->bpc = 8;
+			break;
+		}
+	} else {
+		tu->bpc = tu->bpp/3;
+	}
+
+	if (!in->dsc_en)
+		goto fec_check;
+
+	temp1_fp = drm_fixp_from_fraction(in->compress_ratio, 100);
+	temp2_fp = drm_fixp_from_fraction(in->bpp, 1);
+	temp3_fp = drm_fixp_div(temp2_fp, temp1_fp);
+	temp2_fp = drm_fixp_mul(tu->lwidth_fp, temp3_fp);
+
+	temp1_fp = drm_fixp_from_fraction(8, 1);
+	temp3_fp = drm_fixp_div(temp2_fp, temp1_fp);
+
+	numerator = drm_fixp2int(temp3_fp);
+
+	dsc_num_bytes  = numerator / dsc_num_slices;
+	eoc_bytes           = dsc_num_bytes % nlanes;
+	tot_num_eoc_symbols = nlanes * dsc_num_slices;
+	tot_num_hor_bytes   = dsc_num_bytes * dsc_num_slices;
+	tot_num_dummy_bytes = (nlanes - eoc_bytes) * dsc_num_slices;
+
+	if (dsc_num_bytes == 0)
+		pr_info("incorrect no of bytes per slice=%d\n", dsc_num_bytes);
+
+	dwidth_dsc_bytes = (tot_num_hor_bytes +
+				tot_num_eoc_symbols +
+				(eoc_bytes == 0 ? 0 : tot_num_dummy_bytes));
+
+	dwidth_dsc_fp = drm_fixp_from_fraction(dwidth_dsc_bytes, 3);
+
+	temp2_fp = drm_fixp_mul(tu->pclk_fp, dwidth_dsc_fp);
+	temp1_fp = drm_fixp_div(temp2_fp, tu->lwidth_fp);
+	pclk_dsc_fp = temp1_fp;
+
+	temp1_fp = drm_fixp_div(pclk_dsc_fp, tu->pclk_fp);
+	temp2_fp = drm_fixp_mul(tu->hbp_relative_to_pclk_fp, temp1_fp);
+	hbp_dsc_fp = temp2_fp;
+
+	/* output */
+	tu->pclk_fp = pclk_dsc_fp;
+	tu->lwidth_fp = dwidth_dsc_fp;
+	tu->hbp_relative_to_pclk_fp = hbp_dsc_fp;
+
+fec_check:
+	if (in->fec_en) {
+		temp1_fp = drm_fixp_from_fraction(976, 1000); /* 0.976 */
+		tu->lclk_fp = drm_fixp_mul(tu->lclk_fp, temp1_fp);
+	}
+}
+
+static void _tu_valid_boundary_calc(struct tu_algo_data *tu)
+{
+	s64 temp1_fp, temp2_fp, temp, temp1, temp2;
+	int compare_result_1, compare_result_2, compare_result_3;
+
+	temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
+	temp2_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
+
+	tu->new_valid_boundary_link = drm_fixp2int_ceil(temp2_fp);
+
+	temp = (tu->i_upper_boundary_count *
+				tu->new_valid_boundary_link +
+				tu->i_lower_boundary_count *
+				(tu->new_valid_boundary_link-1));
+	tu->average_valid2_fp = drm_fixp_from_fraction(temp,
+					(tu->i_upper_boundary_count +
+					tu->i_lower_boundary_count));
+
+	temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
+	temp2_fp = tu->lwidth_fp;
+	temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
+	temp2_fp = drm_fixp_div(temp1_fp, tu->average_valid2_fp);
+	tu->n_tus = drm_fixp2int(temp2_fp);
+	if ((temp2_fp & 0xFFFFFFFF) > 0xFFFFF000)
+		tu->n_tus += 1;
+
+	temp1_fp = drm_fixp_from_fraction(tu->n_tus, 1);
+	temp2_fp = drm_fixp_mul(temp1_fp, tu->average_valid2_fp);
+	temp1_fp = drm_fixp_from_fraction(tu->n_symbols, 1);
+	temp2_fp = temp1_fp - temp2_fp;
+	temp1_fp = drm_fixp_from_fraction(tu->nlanes, 1);
+	temp2_fp = drm_fixp_div(temp2_fp, temp1_fp);
+	tu->n_remainder_symbols_per_lane_fp = temp2_fp;
+
+	temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
+	tu->last_partial_tu_fp =
+			drm_fixp_div(tu->n_remainder_symbols_per_lane_fp,
+					temp1_fp);
+
+	if (tu->n_remainder_symbols_per_lane_fp != 0)
+		tu->remainder_symbols_exist = 1;
+	else
+		tu->remainder_symbols_exist = 0;
+
+	temp1_fp = drm_fixp_from_fraction(tu->n_tus, tu->nlanes);
+	tu->n_tus_per_lane = drm_fixp2int(temp1_fp);
+
+	tu->paired_tus = (int)((tu->n_tus_per_lane) /
+					(tu->i_upper_boundary_count +
+					 tu->i_lower_boundary_count));
+
+	tu->remainder_tus = tu->n_tus_per_lane - tu->paired_tus *
+						(tu->i_upper_boundary_count +
+						tu->i_lower_boundary_count);
+
+	if ((tu->remainder_tus - tu->i_upper_boundary_count) > 0) {
+		tu->remainder_tus_upper = tu->i_upper_boundary_count;
+		tu->remainder_tus_lower = tu->remainder_tus -
+						tu->i_upper_boundary_count;
+	} else {
+		tu->remainder_tus_upper = tu->remainder_tus;
+		tu->remainder_tus_lower = 0;
+	}
+
+	temp = tu->paired_tus * (tu->i_upper_boundary_count *
+				tu->new_valid_boundary_link +
+				tu->i_lower_boundary_count *
+				(tu->new_valid_boundary_link - 1)) +
+				(tu->remainder_tus_upper *
+				 tu->new_valid_boundary_link) +
+				(tu->remainder_tus_lower *
+				(tu->new_valid_boundary_link - 1));
+	tu->total_valid_fp = drm_fixp_from_fraction(temp, 1);
+
+	if (tu->remainder_symbols_exist) {
+		temp1_fp = tu->total_valid_fp +
+				tu->n_remainder_symbols_per_lane_fp;
+		temp2_fp = drm_fixp_from_fraction(tu->n_tus_per_lane, 1);
+		temp2_fp = temp2_fp + tu->last_partial_tu_fp;
+		temp1_fp = drm_fixp_div(temp1_fp, temp2_fp);
+	} else {
+		temp2_fp = drm_fixp_from_fraction(tu->n_tus_per_lane, 1);
+		temp1_fp = drm_fixp_div(tu->total_valid_fp, temp2_fp);
+	}
+	tu->effective_valid_fp = temp1_fp;
+
+	temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
+	temp2_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
+	tu->n_n_err_fp = tu->effective_valid_fp - temp2_fp;
+
+	temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
+	temp2_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
+	tu->n_err_fp = tu->average_valid2_fp - temp2_fp;
+
+	tu->even_distribution = tu->n_tus % tu->nlanes == 0 ? 1 : 0;
+
+	temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
+	temp2_fp = tu->lwidth_fp;
+	temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
+	temp2_fp = drm_fixp_div(temp1_fp, tu->average_valid2_fp);
+
+	if (temp2_fp)
+		tu->n_tus_incl_last_incomplete_tu = drm_fixp2int_ceil(temp2_fp);
+	else
+		tu->n_tus_incl_last_incomplete_tu = 0;
+
+	temp1 = 0;
+	temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
+	temp2_fp = drm_fixp_mul(tu->original_ratio_fp, temp1_fp);
+	temp1_fp = tu->average_valid2_fp - temp2_fp;
+	temp2_fp = drm_fixp_from_fraction(tu->n_tus_incl_last_incomplete_tu, 1);
+	temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
+
+	if (temp1_fp)
+		temp1 = drm_fixp2int_ceil(temp1_fp);
+
+	temp = tu->i_upper_boundary_count * tu->nlanes;
+	temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
+	temp2_fp = drm_fixp_mul(tu->original_ratio_fp, temp1_fp);
+	temp1_fp = drm_fixp_from_fraction(tu->new_valid_boundary_link, 1);
+	temp2_fp = temp1_fp - temp2_fp;
+	temp1_fp = drm_fixp_from_fraction(temp, 1);
+	temp2_fp = drm_fixp_mul(temp1_fp, temp2_fp);
+
+	if (temp2_fp)
+		temp2 = drm_fixp2int_ceil(temp2_fp);
+	else
+		temp2 = 0;
+	tu->extra_required_bytes_new_tmp = (int)(temp1 + temp2);
+
+	temp1_fp = drm_fixp_from_fraction(8, tu->bpp);
+	temp2_fp = drm_fixp_from_fraction(
+	tu->extra_required_bytes_new_tmp, 1);
+	temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
+
+	if (temp1_fp)
+		tu->extra_pclk_cycles_tmp = drm_fixp2int_ceil(temp1_fp);
+	else
+		tu->extra_pclk_cycles_tmp = 0;
+
+	temp1_fp = drm_fixp_from_fraction(tu->extra_pclk_cycles_tmp, 1);
+	temp2_fp = drm_fixp_div(tu->lclk_fp, tu->pclk_fp);
+	temp1_fp = drm_fixp_mul(temp1_fp, temp2_fp);
+
+	if (temp1_fp)
+		tu->extra_pclk_cycles_in_link_clk_tmp =
+						drm_fixp2int_ceil(temp1_fp);
+	else
+		tu->extra_pclk_cycles_in_link_clk_tmp = 0;
+
+	tu->filler_size_tmp = tu->tu_size - tu->new_valid_boundary_link;
+
+	tu->lower_filler_size_tmp = tu->filler_size_tmp + 1;
+
+	tu->delay_start_link_tmp = tu->extra_pclk_cycles_in_link_clk_tmp +
+					tu->lower_filler_size_tmp +
+					tu->extra_buffer_margin;
+
+	temp1_fp = drm_fixp_from_fraction(tu->delay_start_link_tmp, 1);
+	tu->delay_start_time_fp = drm_fixp_div(temp1_fp, tu->lclk_fp);
+
+	compare_result_1 = _tu_param_compare(tu->n_n_err_fp, tu->diff_abs_fp);
+	if (compare_result_1 == 2)
+		compare_result_1 = 1;
+	else
+		compare_result_1 = 0;
+
+	compare_result_2 = _tu_param_compare(tu->n_n_err_fp, tu->err_fp);
+	if (compare_result_2 == 2)
+		compare_result_2 = 1;
+	else
+		compare_result_2 = 0;
+
+	compare_result_3 = _tu_param_compare(tu->hbp_time_fp,
+					tu->delay_start_time_fp);
+	if (compare_result_3 == 2)
+		compare_result_3 = 0;
+	else
+		compare_result_3 = 1;
+
+	if (((tu->even_distribution == 1) ||
+			((tu->even_distribution_BF == 0) &&
+			(tu->even_distribution_legacy == 0))) &&
+			tu->n_err_fp >= 0 && tu->n_n_err_fp >= 0 &&
+			compare_result_2 &&
+			(compare_result_1 || (tu->min_hblank_violated == 1)) &&
+			(tu->new_valid_boundary_link - 1) > 0 &&
+			compare_result_3 &&
+			(tu->delay_start_link_tmp <= 1023)) {
+		tu->upper_boundary_count = tu->i_upper_boundary_count;
+		tu->lower_boundary_count = tu->i_lower_boundary_count;
+		tu->err_fp = tu->n_n_err_fp;
+		tu->boundary_moderation_en = true;
+		tu->tu_size_desired = tu->tu_size;
+		tu->valid_boundary_link = tu->new_valid_boundary_link;
+		tu->effective_valid_recorded_fp = tu->effective_valid_fp;
+		tu->even_distribution_BF = 1;
+		tu->delay_start_link = tu->delay_start_link_tmp;
+	} else if (tu->boundary_mod_lower_err == 0) {
+		compare_result_1 = _tu_param_compare(tu->n_n_err_fp,
+							tu->diff_abs_fp);
+		if (compare_result_1 == 2)
+			tu->boundary_mod_lower_err = 1;
+	}
+}
+
+static void _dp_ctrl_calc_tu(struct msm_dp_ctrl_private *ctrl,
+				struct msm_dp_tu_calc_input *in,
+				struct msm_dp_vc_tu_mapping_table *tu_table)
+{
+	struct tu_algo_data *tu;
+	int compare_result_1, compare_result_2;
+	u64 temp = 0;
+	s64 temp_fp = 0, temp1_fp = 0, temp2_fp = 0;
+
+	s64 LCLK_FAST_SKEW_fp = drm_fixp_from_fraction(6, 10000); /* 0.0006 */
+	s64 const_p49_fp = drm_fixp_from_fraction(49, 100); /* 0.49 */
+	s64 const_p56_fp = drm_fixp_from_fraction(56, 100); /* 0.56 */
+	s64 RATIO_SCALE_fp = drm_fixp_from_fraction(1001, 1000);
+
+	u8 DP_BRUTE_FORCE = 1;
+	s64 BRUTE_FORCE_THRESHOLD_fp = drm_fixp_from_fraction(1, 10); /* 0.1 */
+	uint EXTRA_PIXCLK_CYCLE_DELAY = 4;
+	uint HBLANK_MARGIN = 4;
+
+	tu = kzalloc(sizeof(*tu), GFP_KERNEL);
+	if (!tu)
+		return;
+
+	msm_dp_panel_update_tu_timings(in, tu);
+
+	tu->err_fp = drm_fixp_from_fraction(1000, 1); /* 1000 */
+
+	temp1_fp = drm_fixp_from_fraction(4, 1);
+	temp2_fp = drm_fixp_mul(temp1_fp, tu->lclk_fp);
+	temp_fp = drm_fixp_div(temp2_fp, tu->pclk_fp);
+	tu->extra_buffer_margin = drm_fixp2int_ceil(temp_fp);
+
+	temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
+	temp2_fp = drm_fixp_mul(tu->pclk_fp, temp1_fp);
+	temp1_fp = drm_fixp_from_fraction(tu->nlanes, 1);
+	temp2_fp = drm_fixp_div(temp2_fp, temp1_fp);
+	tu->ratio_fp = drm_fixp_div(temp2_fp, tu->lclk_fp);
+
+	tu->original_ratio_fp = tu->ratio_fp;
+	tu->boundary_moderation_en = false;
+	tu->upper_boundary_count = 0;
+	tu->lower_boundary_count = 0;
+	tu->i_upper_boundary_count = 0;
+	tu->i_lower_boundary_count = 0;
+	tu->valid_lower_boundary_link = 0;
+	tu->even_distribution_BF = 0;
+	tu->even_distribution_legacy = 0;
+	tu->even_distribution = 0;
+	tu->delay_start_time_fp = 0;
+
+	tu->err_fp = drm_fixp_from_fraction(1000, 1);
+	tu->n_err_fp = 0;
+	tu->n_n_err_fp = 0;
+
+	tu->ratio = drm_fixp2int(tu->ratio_fp);
+	temp1_fp = drm_fixp_from_fraction(tu->nlanes, 1);
+	div64_u64_rem(tu->lwidth_fp, temp1_fp, &temp2_fp);
+	if (temp2_fp != 0 &&
+			!tu->ratio && tu->dsc_en == 0) {
+		tu->ratio_fp = drm_fixp_mul(tu->ratio_fp, RATIO_SCALE_fp);
+		tu->ratio = drm_fixp2int(tu->ratio_fp);
+		if (tu->ratio)
+			tu->ratio_fp = drm_fixp_from_fraction(1, 1);
+	}
+
+	if (tu->ratio > 1)
+		tu->ratio = 1;
+
+	if (tu->ratio == 1)
+		goto tu_size_calc;
+
+	compare_result_1 = _tu_param_compare(tu->ratio_fp, const_p49_fp);
+	if (!compare_result_1 || compare_result_1 == 1)
+		compare_result_1 = 1;
+	else
+		compare_result_1 = 0;
+
+	compare_result_2 = _tu_param_compare(tu->ratio_fp, const_p56_fp);
+	if (!compare_result_2 || compare_result_2 == 2)
+		compare_result_2 = 1;
+	else
+		compare_result_2 = 0;
+
+	if (tu->dsc_en && compare_result_1 && compare_result_2) {
+		HBLANK_MARGIN += 4;
+		drm_dbg_dp(ctrl->drm_dev,
+			"increase HBLANK_MARGIN to %d\n", HBLANK_MARGIN);
+	}
+
+tu_size_calc:
+	for (tu->tu_size = 32; tu->tu_size <= 64; tu->tu_size++) {
+		temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
+		temp2_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
+		temp = drm_fixp2int_ceil(temp2_fp);
+		temp1_fp = drm_fixp_from_fraction(temp, 1);
+		tu->n_err_fp = temp1_fp - temp2_fp;
+
+		if (tu->n_err_fp < tu->err_fp) {
+			tu->err_fp = tu->n_err_fp;
+			tu->tu_size_desired = tu->tu_size;
+		}
+	}
+
+	tu->tu_size_minus1 = tu->tu_size_desired - 1;
+
+	temp1_fp = drm_fixp_from_fraction(tu->tu_size_desired, 1);
+	temp2_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
+	tu->valid_boundary_link = drm_fixp2int_ceil(temp2_fp);
+
+	temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
+	temp2_fp = tu->lwidth_fp;
+	temp2_fp = drm_fixp_mul(temp2_fp, temp1_fp);
+
+	temp1_fp = drm_fixp_from_fraction(tu->valid_boundary_link, 1);
+	temp2_fp = drm_fixp_div(temp2_fp, temp1_fp);
+	tu->n_tus = drm_fixp2int(temp2_fp);
+	if ((temp2_fp & 0xFFFFFFFF) > 0xFFFFF000)
+		tu->n_tus += 1;
+
+	tu->even_distribution_legacy = tu->n_tus % tu->nlanes == 0 ? 1 : 0;
+
+	drm_dbg_dp(ctrl->drm_dev,
+			"n_sym = %d, num_of_tus = %d\n",
+			tu->valid_boundary_link, tu->n_tus);
+
+	temp1_fp = drm_fixp_from_fraction(tu->tu_size_desired, 1);
+	temp2_fp = drm_fixp_mul(tu->original_ratio_fp, temp1_fp);
+	temp1_fp = drm_fixp_from_fraction(tu->valid_boundary_link, 1);
+	temp2_fp = temp1_fp - temp2_fp;
+	temp1_fp = drm_fixp_from_fraction(tu->n_tus + 1, 1);
+	temp2_fp = drm_fixp_mul(temp1_fp, temp2_fp);
+
+	temp = drm_fixp2int(temp2_fp);
+	if (temp && temp2_fp)
+		tu->extra_bytes = drm_fixp2int_ceil(temp2_fp);
+	else
+		tu->extra_bytes = 0;
+
+	temp1_fp = drm_fixp_from_fraction(tu->extra_bytes, 1);
+	temp2_fp = drm_fixp_from_fraction(8, tu->bpp);
+	temp1_fp = drm_fixp_mul(temp1_fp, temp2_fp);
+
+	if (temp && temp1_fp)
+		tu->extra_pclk_cycles = drm_fixp2int_ceil(temp1_fp);
+	else
+		tu->extra_pclk_cycles = drm_fixp2int(temp1_fp);
+
+	temp1_fp = drm_fixp_div(tu->lclk_fp, tu->pclk_fp);
+	temp2_fp = drm_fixp_from_fraction(tu->extra_pclk_cycles, 1);
+	temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
+
+	if (temp1_fp)
+		tu->extra_pclk_cycles_in_link_clk = drm_fixp2int_ceil(temp1_fp);
+	else
+		tu->extra_pclk_cycles_in_link_clk = drm_fixp2int(temp1_fp);
+
+	tu->filler_size = tu->tu_size_desired - tu->valid_boundary_link;
+
+	temp1_fp = drm_fixp_from_fraction(tu->tu_size_desired, 1);
+	tu->ratio_by_tu_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
+
+	tu->delay_start_link = tu->extra_pclk_cycles_in_link_clk +
+				tu->filler_size + tu->extra_buffer_margin;
+
+	tu->resulting_valid_fp =
+			drm_fixp_from_fraction(tu->valid_boundary_link, 1);
+
+	temp1_fp = drm_fixp_from_fraction(tu->tu_size_desired, 1);
+	temp2_fp = drm_fixp_div(tu->resulting_valid_fp, temp1_fp);
+	tu->TU_ratio_err_fp = temp2_fp - tu->original_ratio_fp;
+
+	temp1_fp = drm_fixp_from_fraction(HBLANK_MARGIN, 1);
+	temp1_fp = tu->hbp_relative_to_pclk_fp - temp1_fp;
+	tu->hbp_time_fp = drm_fixp_div(temp1_fp, tu->pclk_fp);
+
+	temp1_fp = drm_fixp_from_fraction(tu->delay_start_link, 1);
+	tu->delay_start_time_fp = drm_fixp_div(temp1_fp, tu->lclk_fp);
+
+	compare_result_1 = _tu_param_compare(tu->hbp_time_fp,
+					tu->delay_start_time_fp);
+	if (compare_result_1 == 2) /* if (hbp_time_fp < delay_start_time_fp) */
+		tu->min_hblank_violated = 1;
+
+	tu->hactive_time_fp = drm_fixp_div(tu->lwidth_fp, tu->pclk_fp);
+
+	compare_result_2 = _tu_param_compare(tu->hactive_time_fp,
+						tu->delay_start_time_fp);
+	if (compare_result_2 == 2)
+		tu->min_hblank_violated = 1;
+
+	tu->delay_start_time_fp = 0;
+
+	/* brute force */
+
+	tu->delay_start_link_extra_pixclk = EXTRA_PIXCLK_CYCLE_DELAY;
+	tu->diff_abs_fp = tu->resulting_valid_fp - tu->ratio_by_tu_fp;
+
+	temp = drm_fixp2int(tu->diff_abs_fp);
+	if (!temp && tu->diff_abs_fp <= 0xffff)
+		tu->diff_abs_fp = 0;
+
+	/* if(diff_abs < 0) diff_abs *= -1 */
+	if (tu->diff_abs_fp < 0)
+		tu->diff_abs_fp = drm_fixp_mul(tu->diff_abs_fp, -1);
+
+	tu->boundary_mod_lower_err = 0;
+	if ((tu->diff_abs_fp != 0 &&
+			((tu->diff_abs_fp > BRUTE_FORCE_THRESHOLD_fp) ||
+			 (tu->even_distribution_legacy == 0) ||
+			 (DP_BRUTE_FORCE == 1))) ||
+			(tu->min_hblank_violated == 1)) {
+		do {
+			tu->err_fp = drm_fixp_from_fraction(1000, 1);
+
+			temp1_fp = drm_fixp_div(tu->lclk_fp, tu->pclk_fp);
+			temp2_fp = drm_fixp_from_fraction(
+					tu->delay_start_link_extra_pixclk, 1);
+			temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
+
+			if (temp1_fp)
+				tu->extra_buffer_margin =
+					drm_fixp2int_ceil(temp1_fp);
+			else
+				tu->extra_buffer_margin = 0;
+
+			temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
+			temp1_fp = drm_fixp_mul(tu->lwidth_fp, temp1_fp);
+
+			if (temp1_fp)
+				tu->n_symbols = drm_fixp2int_ceil(temp1_fp);
+			else
+				tu->n_symbols = 0;
+
+			for (tu->tu_size = 32; tu->tu_size <= 64; tu->tu_size++) {
+				for (tu->i_upper_boundary_count = 1;
+					tu->i_upper_boundary_count <= 15;
+					tu->i_upper_boundary_count++) {
+					for (tu->i_lower_boundary_count = 1;
+						tu->i_lower_boundary_count <= 15;
+						tu->i_lower_boundary_count++) {
+						_tu_valid_boundary_calc(tu);
+					}
+				}
+			}
+			tu->delay_start_link_extra_pixclk--;
+		} while (tu->boundary_moderation_en != true &&
+			tu->boundary_mod_lower_err == 1 &&
+			tu->delay_start_link_extra_pixclk != 0);
+
+		if (tu->boundary_moderation_en == true) {
+			temp1_fp = drm_fixp_from_fraction(
+					(tu->upper_boundary_count *
+					tu->valid_boundary_link +
+					tu->lower_boundary_count *
+					(tu->valid_boundary_link - 1)), 1);
+			temp2_fp = drm_fixp_from_fraction(
+					(tu->upper_boundary_count +
+					tu->lower_boundary_count), 1);
+			tu->resulting_valid_fp =
+					drm_fixp_div(temp1_fp, temp2_fp);
+
+			temp1_fp = drm_fixp_from_fraction(
+					tu->tu_size_desired, 1);
+			tu->ratio_by_tu_fp =
+				drm_fixp_mul(tu->original_ratio_fp, temp1_fp);
+
+			tu->valid_lower_boundary_link =
+				tu->valid_boundary_link - 1;
+
+			temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
+			temp1_fp = drm_fixp_mul(tu->lwidth_fp, temp1_fp);
+			temp2_fp = drm_fixp_div(temp1_fp,
+						tu->resulting_valid_fp);
+			tu->n_tus = drm_fixp2int(temp2_fp);
+
+			tu->tu_size_minus1 = tu->tu_size_desired - 1;
+			tu->even_distribution_BF = 1;
+
+			temp1_fp =
+				drm_fixp_from_fraction(tu->tu_size_desired, 1);
+			temp2_fp =
+				drm_fixp_div(tu->resulting_valid_fp, temp1_fp);
+			tu->TU_ratio_err_fp = temp2_fp - tu->original_ratio_fp;
+		}
+	}
+
+	temp2_fp = drm_fixp_mul(LCLK_FAST_SKEW_fp, tu->lwidth_fp);
+
+	if (temp2_fp)
+		temp = drm_fixp2int_ceil(temp2_fp);
+	else
+		temp = 0;
+
+	temp1_fp = drm_fixp_from_fraction(tu->nlanes, 1);
+	temp2_fp = drm_fixp_mul(tu->original_ratio_fp, temp1_fp);
+	temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
+	temp2_fp = drm_fixp_div(temp1_fp, temp2_fp);
+	temp1_fp = drm_fixp_from_fraction(temp, 1);
+	temp2_fp = drm_fixp_mul(temp1_fp, temp2_fp);
+	temp = drm_fixp2int(temp2_fp);
+
+	if (tu->async_en)
+		tu->delay_start_link += (int)temp;
+
+	temp1_fp = drm_fixp_from_fraction(tu->delay_start_link, 1);
+	tu->delay_start_time_fp = drm_fixp_div(temp1_fp, tu->lclk_fp);
+
+	/* OUTPUTS */
+	tu_table->valid_boundary_link       = tu->valid_boundary_link;
+	tu_table->delay_start_link          = tu->delay_start_link;
+	tu_table->boundary_moderation_en    = tu->boundary_moderation_en;
+	tu_table->valid_lower_boundary_link = tu->valid_lower_boundary_link;
+	tu_table->upper_boundary_count      = tu->upper_boundary_count;
+	tu_table->lower_boundary_count      = tu->lower_boundary_count;
+	tu_table->tu_size_minus1            = tu->tu_size_minus1;
+
+	drm_dbg_dp(ctrl->drm_dev, "TU: valid_boundary_link: %d\n",
+				tu_table->valid_boundary_link);
+	drm_dbg_dp(ctrl->drm_dev, "TU: delay_start_link: %d\n",
+				tu_table->delay_start_link);
+	drm_dbg_dp(ctrl->drm_dev, "TU: boundary_moderation_en: %d\n",
+			tu_table->boundary_moderation_en);
+	drm_dbg_dp(ctrl->drm_dev, "TU: valid_lower_boundary_link: %d\n",
+			tu_table->valid_lower_boundary_link);
+	drm_dbg_dp(ctrl->drm_dev, "TU: upper_boundary_count: %d\n",
+			tu_table->upper_boundary_count);
+	drm_dbg_dp(ctrl->drm_dev, "TU: lower_boundary_count: %d\n",
+			tu_table->lower_boundary_count);
+	drm_dbg_dp(ctrl->drm_dev, "TU: tu_size_minus1: %d\n",
+			tu_table->tu_size_minus1);
+
+	kfree(tu);
+}
+
+static void msm_dp_ctrl_calc_tu_parameters(struct msm_dp_ctrl_private *ctrl,
+		struct msm_dp_vc_tu_mapping_table *tu_table)
+{
+	struct msm_dp_tu_calc_input in;
+	struct drm_display_mode *drm_mode;
+
+	drm_mode = &ctrl->panel->msm_dp_mode.drm_mode;
+
+	in.lclk = ctrl->link->link_params.rate / 1000;
+	in.pclk_khz = drm_mode->clock;
+	in.hactive = drm_mode->hdisplay;
+	in.hporch = drm_mode->htotal - drm_mode->hdisplay;
+	in.nlanes = ctrl->link->link_params.num_lanes;
+	in.bpp = ctrl->panel->msm_dp_mode.bpp;
+	in.pixel_enc = ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420 ? 420 : 444;
+	in.dsc_en = 0;
+	in.async_en = 0;
+	in.fec_en = 0;
+	in.num_of_dsc_slices = 0;
+	in.compress_ratio = 100;
+
+	_dp_ctrl_calc_tu(ctrl, &in, tu_table);
+}
+
+static void msm_dp_ctrl_setup_tr_unit(struct msm_dp_ctrl_private *ctrl)
+{
+	u32 msm_dp_tu = 0x0;
+	u32 valid_boundary = 0x0;
+	u32 valid_boundary2 = 0x0;
+	struct msm_dp_vc_tu_mapping_table tu_calc_table;
+
+	msm_dp_ctrl_calc_tu_parameters(ctrl, &tu_calc_table);
+
+	msm_dp_tu |= tu_calc_table.tu_size_minus1;
+	valid_boundary |= tu_calc_table.valid_boundary_link;
+	valid_boundary |= (tu_calc_table.delay_start_link << 16);
+
+	valid_boundary2 |= (tu_calc_table.valid_lower_boundary_link << 1);
+	valid_boundary2 |= (tu_calc_table.upper_boundary_count << 16);
+	valid_boundary2 |= (tu_calc_table.lower_boundary_count << 20);
+
+	if (tu_calc_table.boundary_moderation_en)
+		valid_boundary2 |= BIT(0);
+
+	pr_debug("dp_tu=0x%x, valid_boundary=0x%x, valid_boundary2=0x%x\n",
+			msm_dp_tu, valid_boundary, valid_boundary2);
+
+	msm_dp_catalog_ctrl_update_transfer_unit(ctrl->catalog,
+				msm_dp_tu, valid_boundary, valid_boundary2);
+}
+
+static int msm_dp_ctrl_wait4video_ready(struct msm_dp_ctrl_private *ctrl)
+{
+	int ret = 0;
+
+	if (!wait_for_completion_timeout(&ctrl->video_comp,
+				WAIT_FOR_VIDEO_READY_TIMEOUT_JIFFIES)) {
+		DRM_ERROR("wait4video timedout\n");
+		ret = -ETIMEDOUT;
+	}
+	return ret;
+}
+
+static int msm_dp_ctrl_set_vx_px(struct msm_dp_ctrl_private *ctrl,
+			     u8 v_level, u8 p_level)
+{
+	union phy_configure_opts *phy_opts = &ctrl->phy_opts;
+
+	/* TODO: Update for all lanes instead of just first one */
+	phy_opts->dp.voltage[0] = v_level;
+	phy_opts->dp.pre[0] = p_level;
+	phy_opts->dp.set_voltages = 1;
+	phy_configure(ctrl->phy, phy_opts);
+	phy_opts->dp.set_voltages = 0;
+
+	return 0;
+}
+
+static int msm_dp_ctrl_update_vx_px(struct msm_dp_ctrl_private *ctrl)
+{
+	struct msm_dp_link *link = ctrl->link;
+	int ret = 0, lane, lane_cnt;
+	u8 buf[4];
+	u32 max_level_reached = 0;
+	u32 voltage_swing_level = link->phy_params.v_level;
+	u32 pre_emphasis_level = link->phy_params.p_level;
+
+	drm_dbg_dp(ctrl->drm_dev,
+		"voltage level: %d emphasis level: %d\n",
+			voltage_swing_level, pre_emphasis_level);
+	ret = msm_dp_ctrl_set_vx_px(ctrl,
+		voltage_swing_level, pre_emphasis_level);
+
+	if (ret)
+		return ret;
+
+	if (voltage_swing_level >= DP_TRAIN_LEVEL_MAX) {
+		drm_dbg_dp(ctrl->drm_dev,
+				"max. voltage swing level reached %d\n",
+				voltage_swing_level);
+		max_level_reached |= DP_TRAIN_MAX_SWING_REACHED;
+	}
+
+	if (pre_emphasis_level >= DP_TRAIN_LEVEL_MAX) {
+		drm_dbg_dp(ctrl->drm_dev,
+				"max. pre-emphasis level reached %d\n",
+				pre_emphasis_level);
+		max_level_reached  |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+	}
+
+	pre_emphasis_level <<= DP_TRAIN_PRE_EMPHASIS_SHIFT;
+
+	lane_cnt = ctrl->link->link_params.num_lanes;
+	for (lane = 0; lane < lane_cnt; lane++)
+		buf[lane] = voltage_swing_level | pre_emphasis_level
+				| max_level_reached;
+
+	drm_dbg_dp(ctrl->drm_dev, "sink: p|v=0x%x\n",
+			voltage_swing_level | pre_emphasis_level);
+	ret = drm_dp_dpcd_write(ctrl->aux, DP_TRAINING_LANE0_SET,
+					buf, lane_cnt);
+	if (ret == lane_cnt)
+		ret = 0;
+
+	return ret;
+}
+
+static bool msm_dp_ctrl_train_pattern_set(struct msm_dp_ctrl_private *ctrl,
+		u8 pattern)
+{
+	u8 buf;
+	int ret = 0;
+
+	drm_dbg_dp(ctrl->drm_dev, "sink: pattern=%x\n", pattern);
+
+	buf = pattern;
+
+	if (pattern && pattern != DP_TRAINING_PATTERN_4)
+		buf |= DP_LINK_SCRAMBLING_DISABLE;
+
+	ret = drm_dp_dpcd_writeb(ctrl->aux, DP_TRAINING_PATTERN_SET, buf);
+	return ret == 1;
+}
+
+static int msm_dp_ctrl_read_link_status(struct msm_dp_ctrl_private *ctrl,
+				    u8 *link_status)
+{
+	int ret = 0, len;
+
+	len = drm_dp_dpcd_read_link_status(ctrl->aux, link_status);
+	if (len != DP_LINK_STATUS_SIZE) {
+		DRM_ERROR("DP link status read failed, err: %d\n", len);
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int msm_dp_ctrl_link_train_1(struct msm_dp_ctrl_private *ctrl,
+			int *training_step)
+{
+	int tries, old_v_level, ret = 0;
+	u8 link_status[DP_LINK_STATUS_SIZE];
+	int const maximum_retries = 4;
+
+	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+
+	*training_step = DP_TRAINING_1;
+
+	ret = msm_dp_catalog_ctrl_set_pattern_state_bit(ctrl->catalog, 1);
+	if (ret)
+		return ret;
+	msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_1 |
+		DP_LINK_SCRAMBLING_DISABLE);
+
+	ret = msm_dp_ctrl_update_vx_px(ctrl);
+	if (ret)
+		return ret;
+
+	tries = 0;
+	old_v_level = ctrl->link->phy_params.v_level;
+	for (tries = 0; tries < maximum_retries; tries++) {
+		drm_dp_link_train_clock_recovery_delay(ctrl->aux, ctrl->panel->dpcd);
+
+		ret = msm_dp_ctrl_read_link_status(ctrl, link_status);
+		if (ret)
+			return ret;
+
+		if (drm_dp_clock_recovery_ok(link_status,
+			ctrl->link->link_params.num_lanes)) {
+			return 0;
+		}
+
+		if (ctrl->link->phy_params.v_level >=
+			DP_TRAIN_LEVEL_MAX) {
+			DRM_ERROR_RATELIMITED("max v_level reached\n");
+			return -EAGAIN;
+		}
+
+		if (old_v_level != ctrl->link->phy_params.v_level) {
+			tries = 0;
+			old_v_level = ctrl->link->phy_params.v_level;
+		}
+
+		msm_dp_link_adjust_levels(ctrl->link, link_status);
+		ret = msm_dp_ctrl_update_vx_px(ctrl);
+		if (ret)
+			return ret;
+	}
+
+	DRM_ERROR("max tries reached\n");
+	return -ETIMEDOUT;
+}
+
+static int msm_dp_ctrl_link_rate_down_shift(struct msm_dp_ctrl_private *ctrl)
+{
+	int ret = 0;
+
+	switch (ctrl->link->link_params.rate) {
+	case 810000:
+		ctrl->link->link_params.rate = 540000;
+		break;
+	case 540000:
+		ctrl->link->link_params.rate = 270000;
+		break;
+	case 270000:
+		ctrl->link->link_params.rate = 162000;
+		break;
+	case 162000:
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	if (!ret) {
+		drm_dbg_dp(ctrl->drm_dev, "new rate=0x%x\n",
+				ctrl->link->link_params.rate);
+	}
+
+	return ret;
+}
+
+static int msm_dp_ctrl_link_lane_down_shift(struct msm_dp_ctrl_private *ctrl)
+{
+
+	if (ctrl->link->link_params.num_lanes == 1)
+		return -1;
+
+	ctrl->link->link_params.num_lanes /= 2;
+	ctrl->link->link_params.rate = ctrl->panel->link_info.rate;
+
+	ctrl->link->phy_params.p_level = 0;
+	ctrl->link->phy_params.v_level = 0;
+
+	return 0;
+}
+
+static void msm_dp_ctrl_clear_training_pattern(struct msm_dp_ctrl_private *ctrl)
+{
+	msm_dp_ctrl_train_pattern_set(ctrl, DP_TRAINING_PATTERN_DISABLE);
+	drm_dp_link_train_channel_eq_delay(ctrl->aux, ctrl->panel->dpcd);
+}
+
+static int msm_dp_ctrl_link_train_2(struct msm_dp_ctrl_private *ctrl,
+			int *training_step)
+{
+	int tries = 0, ret = 0;
+	u8 pattern;
+	u32 state_ctrl_bit;
+	int const maximum_retries = 5;
+	u8 link_status[DP_LINK_STATUS_SIZE];
+
+	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+
+	*training_step = DP_TRAINING_2;
+
+	if (drm_dp_tps4_supported(ctrl->panel->dpcd)) {
+		pattern = DP_TRAINING_PATTERN_4;
+		state_ctrl_bit = 4;
+	} else if (drm_dp_tps3_supported(ctrl->panel->dpcd)) {
+		pattern = DP_TRAINING_PATTERN_3;
+		state_ctrl_bit = 3;
+	} else {
+		pattern = DP_TRAINING_PATTERN_2;
+		state_ctrl_bit = 2;
+	}
+
+	ret = msm_dp_catalog_ctrl_set_pattern_state_bit(ctrl->catalog, state_ctrl_bit);
+	if (ret)
+		return ret;
+
+	msm_dp_ctrl_train_pattern_set(ctrl, pattern);
+
+	for (tries = 0; tries <= maximum_retries; tries++) {
+		drm_dp_link_train_channel_eq_delay(ctrl->aux, ctrl->panel->dpcd);
+
+		ret = msm_dp_ctrl_read_link_status(ctrl, link_status);
+		if (ret)
+			return ret;
+
+		if (drm_dp_channel_eq_ok(link_status,
+			ctrl->link->link_params.num_lanes)) {
+			return 0;
+		}
+
+		msm_dp_link_adjust_levels(ctrl->link, link_status);
+		ret = msm_dp_ctrl_update_vx_px(ctrl);
+		if (ret)
+			return ret;
+
+	}
+
+	return -ETIMEDOUT;
+}
+
+static int msm_dp_ctrl_link_train(struct msm_dp_ctrl_private *ctrl,
+			int *training_step)
+{
+	int ret = 0;
+	const u8 *dpcd = ctrl->panel->dpcd;
+	u8 encoding[] = { 0, DP_SET_ANSI_8B10B };
+	u8 assr;
+	struct msm_dp_link_info link_info = {0};
+
+	msm_dp_ctrl_config_ctrl(ctrl, ctrl->panel);
+
+	link_info.num_lanes = ctrl->link->link_params.num_lanes;
+	link_info.rate = ctrl->link->link_params.rate;
+	link_info.capabilities = DP_LINK_CAP_ENHANCED_FRAMING;
+
+	msm_dp_link_reset_phy_params_vx_px(ctrl->link);
+
+	msm_dp_aux_link_configure(ctrl->aux, &link_info);
+
+	if (drm_dp_max_downspread(dpcd))
+		encoding[0] |= DP_SPREAD_AMP_0_5;
+
+	/* config DOWNSPREAD_CTRL and MAIN_LINK_CHANNEL_CODING_SET */
+	drm_dp_dpcd_write(ctrl->aux, DP_DOWNSPREAD_CTRL, encoding, 2);
+
+	if (drm_dp_alternate_scrambler_reset_cap(dpcd)) {
+		assr = DP_ALTERNATE_SCRAMBLER_RESET_ENABLE;
+		drm_dp_dpcd_write(ctrl->aux, DP_EDP_CONFIGURATION_SET,
+				&assr, 1);
+	}
+
+	ret = msm_dp_ctrl_link_train_1(ctrl, training_step);
+	if (ret) {
+		DRM_ERROR("link training #1 failed. ret=%d\n", ret);
+		goto end;
+	}
+
+	/* print success info as this is a result of user initiated action */
+	drm_dbg_dp(ctrl->drm_dev, "link training #1 successful\n");
+
+	ret = msm_dp_ctrl_link_train_2(ctrl, training_step);
+	if (ret) {
+		DRM_ERROR("link training #2 failed. ret=%d\n", ret);
+		goto end;
+	}
+
+	/* print success info as this is a result of user initiated action */
+	drm_dbg_dp(ctrl->drm_dev, "link training #2 successful\n");
+
+end:
+	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+
+	return ret;
+}
+
+static int msm_dp_ctrl_setup_main_link(struct msm_dp_ctrl_private *ctrl,
+			int *training_step)
+{
+	int ret = 0;
+
+	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, true);
+
+	if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN)
+		return ret;
+
+	/*
+	 * As part of previous calls, DP controller state might have
+	 * transitioned to PUSH_IDLE. In order to start transmitting
+	 * a link training pattern, we have to first do soft reset.
+	 */
+
+	ret = msm_dp_ctrl_link_train(ctrl, training_step);
+
+	return ret;
+}
+
+int msm_dp_ctrl_core_clk_enable(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	int ret = 0;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	if (ctrl->core_clks_on) {
+		drm_dbg_dp(ctrl->drm_dev, "core clks already enabled\n");
+		return 0;
+	}
+
+	ret = clk_bulk_prepare_enable(ctrl->num_core_clks, ctrl->core_clks);
+	if (ret)
+		return ret;
+
+	ctrl->core_clks_on = true;
+
+	drm_dbg_dp(ctrl->drm_dev, "enable core clocks \n");
+	drm_dbg_dp(ctrl->drm_dev, "stream_clks:%s link_clks:%s core_clks:%s\n",
+		   ctrl->stream_clks_on ? "on" : "off",
+		   ctrl->link_clks_on ? "on" : "off",
+		   ctrl->core_clks_on ? "on" : "off");
+
+	return 0;
+}
+
+void msm_dp_ctrl_core_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	clk_bulk_disable_unprepare(ctrl->num_core_clks, ctrl->core_clks);
+
+	ctrl->core_clks_on = false;
+
+	drm_dbg_dp(ctrl->drm_dev, "disable core clocks \n");
+	drm_dbg_dp(ctrl->drm_dev, "stream_clks:%s link_clks:%s core_clks:%s\n",
+		   ctrl->stream_clks_on ? "on" : "off",
+		   ctrl->link_clks_on ? "on" : "off",
+		   ctrl->core_clks_on ? "on" : "off");
+}
+
+static int msm_dp_ctrl_link_clk_enable(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	int ret = 0;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	if (ctrl->link_clks_on) {
+		drm_dbg_dp(ctrl->drm_dev, "links clks already enabled\n");
+		return 0;
+	}
+
+	if (!ctrl->core_clks_on) {
+		drm_dbg_dp(ctrl->drm_dev, "Enable core clks before link clks\n");
+
+		msm_dp_ctrl_core_clk_enable(msm_dp_ctrl);
+	}
+
+	ret = clk_bulk_prepare_enable(ctrl->num_link_clks, ctrl->link_clks);
+	if (ret)
+		return ret;
+
+	ctrl->link_clks_on = true;
+
+	drm_dbg_dp(ctrl->drm_dev, "enable link clocks\n");
+	drm_dbg_dp(ctrl->drm_dev, "stream_clks:%s link_clks:%s core_clks:%s\n",
+		   ctrl->stream_clks_on ? "on" : "off",
+		   ctrl->link_clks_on ? "on" : "off",
+		   ctrl->core_clks_on ? "on" : "off");
+
+	return 0;
+}
+
+static void msm_dp_ctrl_link_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	clk_bulk_disable_unprepare(ctrl->num_link_clks, ctrl->link_clks);
+
+	ctrl->link_clks_on = false;
+
+	drm_dbg_dp(ctrl->drm_dev, "disabled link clocks\n");
+	drm_dbg_dp(ctrl->drm_dev, "stream_clks:%s link_clks:%s core_clks:%s\n",
+		   ctrl->stream_clks_on ? "on" : "off",
+		   ctrl->link_clks_on ? "on" : "off",
+		   ctrl->core_clks_on ? "on" : "off");
+}
+
+static int msm_dp_ctrl_enable_mainlink_clocks(struct msm_dp_ctrl_private *ctrl)
+{
+	int ret = 0;
+	struct phy *phy = ctrl->phy;
+	const u8 *dpcd = ctrl->panel->dpcd;
+
+	ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;
+	ctrl->phy_opts.dp.link_rate = ctrl->link->link_params.rate / 100;
+	ctrl->phy_opts.dp.ssc = drm_dp_max_downspread(dpcd);
+
+	phy_configure(phy, &ctrl->phy_opts);
+	phy_power_on(phy);
+
+	dev_pm_opp_set_rate(ctrl->dev, ctrl->link->link_params.rate * 1000);
+	ret = msm_dp_ctrl_link_clk_enable(&ctrl->msm_dp_ctrl);
+	if (ret)
+		DRM_ERROR("Unable to start link clocks. ret=%d\n", ret);
+
+	drm_dbg_dp(ctrl->drm_dev, "link rate=%d\n", ctrl->link->link_params.rate);
+
+	return ret;
+}
+
+void msm_dp_ctrl_reset_irq_ctrl(struct msm_dp_ctrl *msm_dp_ctrl, bool enable)
+{
+	struct msm_dp_ctrl_private *ctrl;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	msm_dp_catalog_ctrl_reset(ctrl->catalog);
+
+	/*
+	 * all dp controller programmable registers will not
+	 * be reset to default value after DP_SW_RESET
+	 * therefore interrupt mask bits have to be updated
+	 * to enable/disable interrupts
+	 */
+	msm_dp_catalog_ctrl_enable_irq(ctrl->catalog, enable);
+}
+
+void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	u8 cfg;
+	struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,
+			struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	if (!ctrl->panel->psr_cap.version)
+		return;
+
+	msm_dp_catalog_ctrl_config_psr(ctrl->catalog);
+
+	cfg = DP_PSR_ENABLE;
+	drm_dp_dpcd_write(ctrl->aux, DP_PSR_EN_CFG, &cfg, 1);
+}
+
+void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl, bool enter)
+{
+	struct msm_dp_ctrl_private *ctrl = container_of(msm_dp_ctrl,
+			struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	if (!ctrl->panel->psr_cap.version)
+		return;
+
+	/*
+	 * When entering PSR,
+	 * 1. Send PSR enter SDP and wait for the PSR_UPDATE_INT
+	 * 2. Turn off video
+	 * 3. Disable the mainlink
+	 *
+	 * When exiting PSR,
+	 * 1. Enable the mainlink
+	 * 2. Send the PSR exit SDP
+	 */
+	if (enter) {
+		reinit_completion(&ctrl->psr_op_comp);
+		msm_dp_catalog_ctrl_set_psr(ctrl->catalog, true);
+
+		if (!wait_for_completion_timeout(&ctrl->psr_op_comp,
+			PSR_OPERATION_COMPLETION_TIMEOUT_JIFFIES)) {
+			DRM_ERROR("PSR_ENTRY timedout\n");
+			msm_dp_catalog_ctrl_set_psr(ctrl->catalog, false);
+			return;
+		}
+
+		msm_dp_ctrl_push_idle(msm_dp_ctrl);
+		msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+
+		msm_dp_catalog_ctrl_psr_mainlink_enable(ctrl->catalog, false);
+	} else {
+		msm_dp_catalog_ctrl_psr_mainlink_enable(ctrl->catalog, true);
+
+		msm_dp_catalog_ctrl_set_psr(ctrl->catalog, false);
+		msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
+		msm_dp_ctrl_wait4video_ready(ctrl);
+		msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, 0);
+	}
+}
+
+void msm_dp_ctrl_phy_init(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	struct phy *phy;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	phy = ctrl->phy;
+
+	msm_dp_catalog_ctrl_phy_reset(ctrl->catalog);
+	phy_init(phy);
+
+	drm_dbg_dp(ctrl->drm_dev, "phy=%p init=%d power_on=%d\n",
+			phy, phy->init_count, phy->power_count);
+}
+
+void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	struct phy *phy;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	phy = ctrl->phy;
+
+	msm_dp_catalog_ctrl_phy_reset(ctrl->catalog);
+	phy_exit(phy);
+	drm_dbg_dp(ctrl->drm_dev, "phy=%p init=%d power_on=%d\n",
+			phy, phy->init_count, phy->power_count);
+}
+
+static int msm_dp_ctrl_reinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
+{
+	struct phy *phy = ctrl->phy;
+	int ret = 0;
+
+	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
+	ctrl->phy_opts.dp.lanes = ctrl->link->link_params.num_lanes;
+	phy_configure(phy, &ctrl->phy_opts);
+	/*
+	 * Disable and re-enable the mainlink clock since the
+	 * link clock might have been adjusted as part of the
+	 * link maintenance.
+	 */
+	dev_pm_opp_set_rate(ctrl->dev, 0);
+
+	msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
+
+	phy_power_off(phy);
+	/* hw recommended delay before re-enabling clocks */
+	msleep(20);
+
+	ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl);
+	if (ret) {
+		DRM_ERROR("Failed to enable mainlink clks. ret=%d\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int msm_dp_ctrl_deinitialize_mainlink(struct msm_dp_ctrl_private *ctrl)
+{
+	struct phy *phy;
+
+	phy = ctrl->phy;
+
+	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
+
+	msm_dp_catalog_ctrl_reset(ctrl->catalog);
+
+	dev_pm_opp_set_rate(ctrl->dev, 0);
+	msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
+
+	phy_power_off(phy);
+
+	/* aux channel down, reinit phy */
+	phy_exit(phy);
+	phy_init(phy);
+
+	drm_dbg_dp(ctrl->drm_dev, "phy=%p init=%d power_on=%d\n",
+			phy, phy->init_count, phy->power_count);
+	return 0;
+}
+
+int msm_dp_ctrl_mst_send_act(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	bool act_complete;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	msm_dp_catalog_trigger_act(ctrl->catalog);
+	msleep(20); /* needs 1 frame time */
+
+	act_complete = msm_dp_catalog_read_act_complete_sts(ctrl->catalog);
+
+	if (!act_complete)
+		drm_dbg_dp(ctrl->drm_dev, "mst ACT trigger complete SUCCESS\n");
+	else
+		DRM_ERROR("mst ACT trigger complete failed\n");
+
+	return 0;
+}
+
+static int msm_dp_ctrl_link_maintenance(struct msm_dp_ctrl_private *ctrl)
+{
+	int ret = 0;
+	int training_step = DP_TRAINING_NONE;
+
+	msm_dp_ctrl_push_idle(&ctrl->msm_dp_ctrl);
+
+	ctrl->link->phy_params.p_level = 0;
+	ctrl->link->phy_params.v_level = 0;
+
+	ret = msm_dp_ctrl_setup_main_link(ctrl, &training_step);
+	if (ret)
+		goto end;
+
+	msm_dp_ctrl_clear_training_pattern(ctrl);
+
+	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
+
+	if (ctrl->mst_active)
+		msm_dp_ctrl_mst_send_act(&ctrl->msm_dp_ctrl);
+
+	ret = msm_dp_ctrl_wait4video_ready(ctrl);
+end:
+	return ret;
+}
+
+static bool msm_dp_ctrl_send_phy_test_pattern(struct msm_dp_ctrl_private *ctrl)
+{
+	bool success = false;
+	u32 pattern_sent = 0x0;
+	u32 pattern_requested = ctrl->link->phy_params.phy_test_pattern_sel;
+
+	drm_dbg_dp(ctrl->drm_dev, "request: 0x%x\n", pattern_requested);
+
+	if (msm_dp_ctrl_set_vx_px(ctrl,
+			ctrl->link->phy_params.v_level,
+			ctrl->link->phy_params.p_level)) {
+		DRM_ERROR("Failed to set v/p levels\n");
+		return false;
+	}
+	msm_dp_catalog_ctrl_send_phy_pattern(ctrl->catalog, pattern_requested);
+	msm_dp_ctrl_update_vx_px(ctrl);
+	msm_dp_link_send_test_response(ctrl->link);
+
+	pattern_sent = msm_dp_catalog_ctrl_read_phy_pattern(ctrl->catalog);
+
+	switch (pattern_sent) {
+	case MR_LINK_TRAINING1:
+		success = (pattern_requested ==
+				DP_PHY_TEST_PATTERN_D10_2);
+		break;
+	case MR_LINK_SYMBOL_ERM:
+		success = ((pattern_requested ==
+			DP_PHY_TEST_PATTERN_ERROR_COUNT) ||
+				(pattern_requested ==
+				DP_PHY_TEST_PATTERN_CP2520));
+		break;
+	case MR_LINK_PRBS7:
+		success = (pattern_requested ==
+				DP_PHY_TEST_PATTERN_PRBS7);
+		break;
+	case MR_LINK_CUSTOM80:
+		success = (pattern_requested ==
+				DP_PHY_TEST_PATTERN_80BIT_CUSTOM);
+		break;
+	case MR_LINK_TRAINING4:
+		success = (pattern_requested ==
+				DP_PHY_TEST_PATTERN_SEL_MASK);
+		break;
+	default:
+		success = false;
+	}
+
+	drm_dbg_dp(ctrl->drm_dev, "%s: test->0x%x\n",
+		success ? "success" : "failed", pattern_requested);
+	return success;
+}
+
+static int msm_dp_ctrl_stream_clk_on(struct msm_dp_ctrl_private *ctrl, unsigned long pixel_rate,
+				     enum msm_dp_stream_id stream_id)
+{
+	int ret;
+
+	ret = clk_set_rate(ctrl->pixel_clk[stream_id], pixel_rate * 1000);
+	if (ret) {
+		DRM_ERROR("Failed to set stream clk rate. ret=%d\n", ret);
+		return ret;
+	}
+
+	if (ctrl->stream_clks_on[stream_id]) {
+		drm_dbg_dp(ctrl->drm_dev, "stream clks already enabled\n");
+	} else {
+		ret = clk_prepare_enable(ctrl->pixel_clk[stream_id]);
+		if (ret) {
+			DRM_ERROR("Failed to start stream clks. ret=%d\n", ret);
+			return ret;
+		}
+		ctrl->stream_clks_on[stream_id] = true;
+	}
+
+	return ret;
+}
+
+static int msm_dp_ctrl_process_phy_test_request(struct msm_dp_ctrl_private *ctrl,
+		struct msm_dp_panel *msm_dp_panel)
+{
+	int ret;
+	unsigned long pixel_rate;
+
+	if (!ctrl->link->phy_params.phy_test_pattern_sel) {
+		drm_dbg_dp(ctrl->drm_dev,
+			"no test pattern selected by sink\n");
+		return 0;
+	}
+
+	/*
+	 * The global reset will need DP link related clocks to be
+	 * running. Add the global reset just before disabling the
+	 * link clocks and core clocks.
+	 */
+	msm_dp_ctrl_stream_clk_off(&ctrl->msm_dp_ctrl, msm_dp_panel);
+	msm_dp_ctrl_off_link(&ctrl->msm_dp_ctrl);
+
+	ret = msm_dp_ctrl_on_link(&ctrl->msm_dp_ctrl, ctrl->mst_active);
+	if (ret) {
+		DRM_ERROR("failed to enable DP link controller\n");
+		return ret;
+	}
+
+	pixel_rate = msm_dp_panel->msm_dp_mode.drm_mode.clock;
+	ret = msm_dp_ctrl_stream_clk_on(ctrl, pixel_rate, msm_dp_panel->stream_id);
+
+	msm_dp_ctrl_send_phy_test_pattern(ctrl);
+
+	return 0;
+}
+
+void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	u32 sink_request = 0x0;
+
+	if (!msm_dp_ctrl) {
+		DRM_ERROR("invalid input\n");
+		return;
+	}
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	sink_request = ctrl->link->sink_request;
+
+	if (sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
+		drm_dbg_dp(ctrl->drm_dev, "PHY_TEST_PATTERN request\n");
+		if (msm_dp_ctrl_process_phy_test_request(ctrl, ctrl->panel)) {
+			DRM_ERROR("process phy_test_req failed\n");
+			return;
+		}
+	}
+
+	if (sink_request & DP_LINK_STATUS_UPDATED) {
+		if (msm_dp_ctrl_link_maintenance(ctrl)) {
+			DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");
+			return;
+		}
+	}
+
+	if (sink_request & DP_TEST_LINK_TRAINING) {
+		msm_dp_link_send_test_response(ctrl->link);
+		if (msm_dp_ctrl_link_maintenance(ctrl)) {
+			DRM_ERROR("LM failed: TEST_LINK_TRAINING\n");
+			return;
+		}
+	}
+}
+
+static bool msm_dp_ctrl_clock_recovery_any_ok(
+			const u8 link_status[DP_LINK_STATUS_SIZE],
+			int lane_count)
+{
+	int reduced_cnt;
+
+	if (lane_count <= 1)
+		return false;
+
+	/*
+	 * only interested in the lane number after reduced
+	 * lane_count = 4, then only interested in 2 lanes
+	 * lane_count = 2, then only interested in 1 lane
+	 */
+	reduced_cnt = lane_count >> 1;
+
+	return drm_dp_clock_recovery_ok(link_status, reduced_cnt);
+}
+
+static bool msm_dp_ctrl_channel_eq_ok(struct msm_dp_ctrl_private *ctrl)
+{
+	u8 link_status[DP_LINK_STATUS_SIZE];
+	int num_lanes = ctrl->link->link_params.num_lanes;
+
+	msm_dp_ctrl_read_link_status(ctrl, link_status);
+
+	return drm_dp_channel_eq_ok(link_status, num_lanes);
+}
+
+int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl, bool mst_active)
+{
+	int rc = 0;
+	struct msm_dp_ctrl_private *ctrl;
+	u32 rate;
+	int link_train_max_retries = 5;
+	u32 const phy_cts_pixel_clk_khz = 148500;
+	u8 link_status[DP_LINK_STATUS_SIZE];
+	unsigned int training_step;
+	unsigned long pixel_rate;
+
+	if (!msm_dp_ctrl)
+		return -EINVAL;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	rate = ctrl->panel->link_info.rate;
+	pixel_rate = ctrl->panel->msm_dp_mode.drm_mode.clock;
+
+	ctrl->mst_active = mst_active;
+	msm_dp_ctrl_core_clk_enable(&ctrl->msm_dp_ctrl);
+
+	if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN) {
+		drm_dbg_dp(ctrl->drm_dev,
+				"using phy test link parameters\n");
+		if (!pixel_rate)
+			pixel_rate = phy_cts_pixel_clk_khz;
+	} else {
+		ctrl->link->link_params.rate = rate;
+		ctrl->link->link_params.num_lanes =
+			ctrl->panel->link_info.num_lanes;
+		if (ctrl->panel->msm_dp_mode.out_fmt_is_yuv_420)
+			pixel_rate >>= 1;
+	}
+
+	drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d, pixel_rate=%lu\n",
+		ctrl->link->link_params.rate, ctrl->link->link_params.num_lanes,
+		pixel_rate);
+
+	rc = msm_dp_ctrl_enable_mainlink_clocks(ctrl);
+	if (rc)
+		return rc;
+
+	while (--link_train_max_retries) {
+		training_step = DP_TRAINING_NONE;
+		rc = msm_dp_ctrl_setup_main_link(ctrl, &training_step);
+		if (rc == 0) {
+			/* training completed successfully */
+			break;
+		} else if (training_step == DP_TRAINING_1) {
+			/* link train_1 failed */
+			if (!msm_dp_catalog_link_is_connected(ctrl->catalog))
+				break;
+
+			msm_dp_ctrl_read_link_status(ctrl, link_status);
+
+			rc = msm_dp_ctrl_link_rate_down_shift(ctrl);
+			if (rc < 0) { /* already in RBR = 1.6G */
+				if (msm_dp_ctrl_clock_recovery_any_ok(link_status,
+					ctrl->link->link_params.num_lanes)) {
+					/*
+					 * some lanes are ready,
+					 * reduce lane number
+					 */
+					rc = msm_dp_ctrl_link_lane_down_shift(ctrl);
+					if (rc < 0) { /* lane == 1 already */
+						/* end with failure */
+						break;
+					}
+				} else {
+					/* end with failure */
+					break; /* lane == 1 already */
+				}
+			}
+		} else if (training_step == DP_TRAINING_2) {
+			/* link train_2 failed */
+			if (!msm_dp_catalog_link_is_connected(ctrl->catalog))
+				break;
+
+			msm_dp_ctrl_read_link_status(ctrl, link_status);
+
+			if (!drm_dp_clock_recovery_ok(link_status,
+					ctrl->link->link_params.num_lanes))
+				rc = msm_dp_ctrl_link_rate_down_shift(ctrl);
+			else
+				rc = msm_dp_ctrl_link_lane_down_shift(ctrl);
+
+			if (rc < 0) {
+				/* end with failure */
+				break; /* lane == 1 already */
+			}
+
+			/* stop link training before start re training  */
+			msm_dp_ctrl_clear_training_pattern(ctrl);
+		}
+
+		rc = msm_dp_ctrl_reinitialize_mainlink(ctrl);
+		if (rc) {
+			DRM_ERROR("Failed to reinitialize mainlink. rc=%d\n", rc);
+			break;
+		}
+	}
+
+	if (ctrl->link->sink_request & DP_TEST_LINK_PHY_TEST_PATTERN)
+		return rc;
+
+	if (rc == 0) {  /* link train successfully */
+		/*
+		 * do not stop train pattern here
+		 * stop link training at on_stream
+		 * to pass compliance test
+		 */
+	} else  {
+		/*
+		 * link training failed
+		 * end txing train pattern here
+		 */
+		msm_dp_ctrl_clear_training_pattern(ctrl);
+
+		msm_dp_ctrl_deinitialize_mainlink(ctrl);
+		rc = -ECONNRESET;
+	}
+
+	return rc;
+}
+
+static int msm_dp_ctrl_link_retrain(struct msm_dp_ctrl_private *ctrl)
+{
+	int training_step = DP_TRAINING_NONE;
+
+	return msm_dp_ctrl_setup_main_link(ctrl, &training_step);
+}
+
+int msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train)
+{
+	int ret = 0;
+	struct msm_dp_ctrl_private *ctrl;
+
+	if (!msm_dp_ctrl)
+		return -EINVAL;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	drm_dbg_dp(ctrl->drm_dev, "rate=%d, num_lanes=%d\n",
+		ctrl->link->link_params.rate,
+		ctrl->link->link_params.num_lanes);
+
+	drm_dbg_dp(ctrl->drm_dev,
+		"core_clk_on=%d link_clk_on=%d\n",
+		ctrl->core_clks_on, ctrl->link_clks_on);
+
+	if (!ctrl->link_clks_on) { /* link clk is off */
+		ret = msm_dp_ctrl_enable_mainlink_clocks(ctrl);
+		if (ret) {
+			DRM_ERROR("Failed to start link clocks. ret=%d\n", ret);
+			return ret;
+		}
+	}
+
+	if (force_link_train || !msm_dp_ctrl_channel_eq_ok(ctrl))
+		msm_dp_ctrl_link_retrain(ctrl);
+
+	/* stop txing train pattern to end link training */
+	msm_dp_ctrl_clear_training_pattern(ctrl);
+
+	return ret;
+}
+
+static void msm_dp_ctrl_mst_calculate_rg(struct msm_dp_ctrl_private *ctrl,
+					 struct msm_dp_panel *panel,
+					 u32 *p_x_int, u32 *p_y_frac_enum)
+{
+	u64 min_slot_cnt, max_slot_cnt;
+	u64 raw_target_sc, target_sc_fixp;
+	u64 ts_denom, ts_enum, ts_int;
+	u64 pclk = panel->msm_dp_mode.drm_mode.clock;
+	u64 lclk = 0;
+	u64 lanes = ctrl->link->link_params.num_lanes;
+	u64 bpp = panel->msm_dp_mode.bpp;
+	u64 pbn = panel->mst_caps.pbn;
+	u64 numerator, denominator, temp, temp1, temp2;
+	u32 x_int = 0, y_frac_enum = 0;
+	u64 target_strm_sym, ts_int_fixp, ts_frac_fixp, y_frac_enum_fixp;
+
+	lclk = ctrl->link->link_params.rate;
+
+	/* min_slot_cnt */
+	numerator = pclk * bpp * 64 * 1000;
+	denominator = lclk * lanes * 8 * 1000;
+	min_slot_cnt = drm_fixp_from_fraction(numerator, denominator);
+
+	/* max_slot_cnt */
+	numerator = pbn * 54 * 1000;
+	denominator = lclk * lanes;
+	max_slot_cnt = drm_fixp_from_fraction(numerator, denominator);
+
+	/* raw_target_sc */
+	numerator = max_slot_cnt + min_slot_cnt;
+	denominator = drm_fixp_from_fraction(2, 1);
+	raw_target_sc = drm_fixp_div(numerator, denominator);
+
+	/* target_sc */
+	temp = drm_fixp_from_fraction(256 * lanes, 1);
+	numerator = drm_fixp_mul(raw_target_sc, temp);
+	denominator = drm_fixp_from_fraction(256 * lanes, 1);
+	target_sc_fixp = drm_fixp_div(numerator, denominator);
+
+	ts_enum = 256 * lanes;
+	ts_denom = drm_fixp_from_fraction(256 * lanes, 1);
+	ts_int = drm_fixp2int(target_sc_fixp);
+
+	temp = drm_fixp2int_ceil(raw_target_sc);
+	if (temp != ts_int) {
+		temp = drm_fixp_from_fraction(ts_int, 1);
+		temp1 = raw_target_sc - temp;
+		temp2 = drm_fixp_mul(temp1, ts_denom);
+		ts_enum = drm_fixp2int(temp2);
+	}
+
+	/* target_strm_sym */
+	ts_int_fixp = drm_fixp_from_fraction(ts_int, 1);
+	ts_frac_fixp = drm_fixp_from_fraction(ts_enum, drm_fixp2int(ts_denom));
+	temp = ts_int_fixp + ts_frac_fixp;
+	temp1 = drm_fixp_from_fraction(lanes, 1);
+	target_strm_sym = drm_fixp_mul(temp, temp1);
+
+	/* x_int */
+	x_int = drm_fixp2int(target_strm_sym);
+
+	/* y_enum_frac */
+	temp = drm_fixp_from_fraction(x_int, 1);
+	temp1 = target_strm_sym - temp;
+	temp2 = drm_fixp_from_fraction(256, 1);
+	y_frac_enum_fixp = drm_fixp_mul(temp1, temp2);
+
+	temp1 = drm_fixp2int(y_frac_enum_fixp);
+	temp2 = drm_fixp2int_ceil(y_frac_enum_fixp);
+
+	y_frac_enum = (u32)((temp1 == temp2) ? temp1 : temp1 + 1);
+
+	*p_x_int = x_int;
+	*p_y_frac_enum = y_frac_enum;
+
+	drm_dbg_dp(ctrl->drm_dev, "mst lane_cnt:%llu, rate:%llu x_int:%d, y_frac:%d\n",
+		   lanes, lclk, x_int, y_frac_enum);
+}
+
+static void msm_dp_ctrl_mst_stream_setup(struct msm_dp_ctrl_private *ctrl,
+					 struct msm_dp_panel *panel,
+					 u32 max_streams)
+{
+	u32 x_int, y_frac_enum;
+
+	drm_dbg_dp(ctrl->drm_dev, "mst stream channel allocation\n");
+
+	msm_dp_ctrl_mst_stream_channel_slot_setup(&ctrl->msm_dp_ctrl, max_streams);
+
+	msm_dp_ctrl_mst_calculate_rg(ctrl, panel, &x_int, &y_frac_enum);
+
+	msm_dp_catalog_ctrl_update_rg(ctrl->catalog, panel->stream_id,
+				      x_int, y_frac_enum);
+}
+
+int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl,
+			  struct msm_dp_panel *msm_dp_panel, u32 max_streams)
+{
+	int ret = 0;
+	bool mainlink_ready = false;
+	struct msm_dp_ctrl_private *ctrl;
+	unsigned long pixel_rate;
+	unsigned long pixel_rate_orig;
+
+	if (!msm_dp_ctrl)
+		return -EINVAL;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	pixel_rate = pixel_rate_orig = msm_dp_panel->msm_dp_mode.drm_mode.clock;
+
+	if (msm_dp_ctrl->wide_bus_en || msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420)
+		pixel_rate >>= 1;
+
+	drm_dbg_dp(ctrl->drm_dev, "pixel_rate=%lu\n", pixel_rate);
+
+	ret = msm_dp_ctrl_stream_clk_on(ctrl, pixel_rate, msm_dp_panel->stream_id);
+	if (ret) {
+		DRM_ERROR("failed to enable stream pixel clk\n");
+		return ret;
+	}
+
+	/*
+	 * Set up transfer unit values and set controller state to send
+	 * video.
+	 */
+	reinit_completion(&ctrl->video_comp);
+
+	msm_dp_ctrl_configure_source_params(ctrl, msm_dp_panel);
+
+	msm_dp_catalog_ctrl_config_msa(ctrl->catalog,
+		ctrl->link->link_params.rate,
+		pixel_rate_orig,
+		msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420);
+
+	if (!ctrl->mst_active)
+		msm_dp_ctrl_setup_tr_unit(ctrl);
+
+	if (ctrl->mst_active)
+		msm_dp_ctrl_mst_stream_setup(ctrl, msm_dp_panel, max_streams);
+
+	msm_dp_catalog_ctrl_state_ctrl(ctrl->catalog, DP_STATE_CTRL_SEND_VIDEO);
+
+	if (ctrl->mst_active)
+		msm_dp_ctrl_mst_send_act(msm_dp_ctrl);
+
+	ret = msm_dp_ctrl_wait4video_ready(ctrl);
+	if (ret)
+		return ret;
+
+	mainlink_ready = msm_dp_catalog_ctrl_mainlink_ready(ctrl->catalog);
+	drm_dbg_dp(ctrl->drm_dev,
+		"mainlink %s\n", mainlink_ready ? "READY" : "NOT READY");
+
+	return ret;
+}
+
+void msm_dp_ctrl_stream_clk_off(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_ctrl_private *ctrl;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	if (ctrl->stream_clks_on[msm_dp_panel->stream_id]) {
+		clk_disable_unprepare(ctrl->pixel_clk[msm_dp_panel->stream_id]);
+		ctrl->stream_clks_on[msm_dp_panel->stream_id] = false;
+	}
+}
+
+void msm_dp_ctrl_clear_vsc_sdp_pkt(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *dp_panel)
+{
+	struct msm_dp_ctrl_private *ctrl;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	ctrl->catalog->stream_id = dp_panel->stream_id;
+	msm_dp_catalog_panel_disable_vsc_sdp(ctrl->catalog);
+}
+
+void msm_dp_ctrl_psm_config(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	/* set dongle to D3 (power off) mode */
+	msm_dp_link_psm_config(ctrl->link, &ctrl->panel->link_info, true);
+}
+
+void msm_dp_ctrl_reinit_phy(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	struct phy *phy;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	phy = ctrl->phy;
+
+	/* aux channel down, reinit phy */
+	phy_exit(phy);
+	phy_init(phy);
+
+	drm_dbg_dp(ctrl->drm_dev, "phy=%p init=%d power_on=%d\n",
+			phy, phy->init_count, phy->power_count);
+}
+
+void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	struct phy *phy;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	phy = ctrl->phy;
+
+	msm_dp_catalog_ctrl_mainlink_ctrl(ctrl->catalog, false);
+	msm_dp_catalog_mst_config(ctrl->catalog, false);
+
+	ctrl->mst_active = false;
+
+	dev_pm_opp_set_rate(ctrl->dev, 0);
+	msm_dp_ctrl_link_clk_disable(&ctrl->msm_dp_ctrl);
+
+	drm_dbg_dp(ctrl->drm_dev, "Before, phy=%p init_count=%d power_on=%d\n",
+		   phy, phy->init_count, phy->power_count);
+
+	phy_power_off(phy);
+
+	drm_dbg_dp(ctrl->drm_dev, "After, phy=%p init_count=%d power_on=%d\n",
+		   phy, phy->init_count, phy->power_count);
+}
+
+void msm_dp_ctrl_set_mst_channel_info(struct msm_dp_ctrl *msm_dp_ctrl,
+				      enum msm_dp_stream_id strm,
+				      u32 start_slot, u32 tot_slots)
+{
+	struct msm_dp_ctrl_private *ctrl;
+
+	if (!msm_dp_ctrl || strm >= DP_STREAM_MAX) {
+		DRM_ERROR("invalid input\n");
+		return;
+	}
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	ctrl->mst_ch_info[strm].start_slot = start_slot;
+	ctrl->mst_ch_info[strm].tot_slots = tot_slots;
+}
+
+// TO-DO : Check if we can do a dealloc instead of this one during teardown
+void msm_dp_ctrl_mst_stream_channel_slot_setup(struct msm_dp_ctrl *msm_dp_ctrl, u32 max_streams)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	int i;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	for (i = DP_STREAM_0; i < max_streams; i++) {
+		msm_dp_catalog_mst_channel_alloc(ctrl->catalog,
+						 i, ctrl->mst_ch_info[i].start_slot,
+						 ctrl->mst_ch_info[i].tot_slots);
+	}
+}
+
+irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	u32 isr;
+	irqreturn_t ret = IRQ_NONE;
+
+	if (!msm_dp_ctrl)
+		return IRQ_NONE;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+
+	if (ctrl->panel->psr_cap.version) {
+		isr = msm_dp_catalog_ctrl_read_psr_interrupt_status(ctrl->catalog);
+
+		if (isr)
+			complete(&ctrl->psr_op_comp);
+
+		if (isr & PSR_EXIT_INT)
+			drm_dbg_dp(ctrl->drm_dev, "PSR exit done\n");
+
+		if (isr & PSR_UPDATE_INT)
+			drm_dbg_dp(ctrl->drm_dev, "PSR frame update done\n");
+
+		if (isr & PSR_CAPTURE_INT)
+			drm_dbg_dp(ctrl->drm_dev, "PSR frame capture done\n");
+	}
+
+	isr = msm_dp_catalog_ctrl_get_interrupt(ctrl->catalog);
+
+
+	if (isr & DP_CTRL_INTR_READY_FOR_VIDEO) {
+		drm_dbg_dp(ctrl->drm_dev, "dp_video_ready\n");
+		complete(&ctrl->video_comp);
+		ret = IRQ_HANDLED;
+	}
+
+	if (isr & DP_CTRL_INTR_IDLE_PATTERN_SENT) {
+		drm_dbg_dp(ctrl->drm_dev, "idle_patterns_sent\n");
+		complete(&ctrl->idle_comp);
+		ret = IRQ_HANDLED;
+	}
+
+	isr = msm_dp_catalog_ctrl_get_interrupt_5(ctrl->catalog);
+	if (isr & (DP_INTR_DP0_VCPF_SENT | DP_INTR_DP1_VCPF_SENT)) {
+		drm_dbg_dp(ctrl->drm_dev, "vcpf sent\n");
+		complete(&ctrl->idle_comp);
+		ret = IRQ_HANDLED;
+	}
+
+	return ret;
+}
+
+static const char *core_clks[] = {
+	"core_iface",
+	"core_aux",
+};
+
+static const char *ctrl_clks[] = {
+	"ctrl_link",
+	"ctrl_link_iface",
+};
+
+static int msm_dp_ctrl_clk_init(struct msm_dp_ctrl *msm_dp_ctrl)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	struct device *dev;
+	int i, rc;
+
+	ctrl = container_of(msm_dp_ctrl, struct msm_dp_ctrl_private, msm_dp_ctrl);
+	dev = ctrl->dev;
+
+	ctrl->num_core_clks = ARRAY_SIZE(core_clks);
+	ctrl->core_clks = devm_kcalloc(dev, ctrl->num_core_clks, sizeof(*ctrl->core_clks), GFP_KERNEL);
+	if (!ctrl->core_clks)
+		return -ENOMEM;
+
+	for (i = 0; i < ctrl->num_core_clks; i++)
+		ctrl->core_clks[i].id = core_clks[i];
+
+	rc = devm_clk_bulk_get(dev, ctrl->num_core_clks, ctrl->core_clks);
+	if (rc)
+		return rc;
+
+	ctrl->num_link_clks = ARRAY_SIZE(ctrl_clks);
+	ctrl->link_clks = devm_kcalloc(dev, ctrl->num_link_clks, sizeof(*ctrl->link_clks), GFP_KERNEL);
+	if (!ctrl->link_clks)
+		return -ENOMEM;
+
+	for (i = 0; i < ctrl->num_link_clks; i++)
+		ctrl->link_clks[i].id = ctrl_clks[i];
+
+	rc = devm_clk_bulk_get(dev, ctrl->num_link_clks, ctrl->link_clks);
+	if (rc)
+		return rc;
+
+	ctrl->pixel_clk[DP_STREAM_0] = devm_clk_get(dev, "stream_pixel");
+	if (IS_ERR(ctrl->pixel_clk[DP_STREAM_0]))
+		return PTR_ERR(ctrl->pixel_clk[DP_STREAM_0]);
+
+	ctrl->pixel_clk[DP_STREAM_1] = devm_clk_get(dev, "stream_1_pixel");
+	if (IS_ERR(ctrl->pixel_clk[DP_STREAM_1]))
+		DRM_ERROR("failed to get stream_pixel_2");
+
+	return 0;
+}
+
+struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link,
+			struct msm_dp_panel *panel,	struct drm_dp_aux *aux,
+			struct msm_dp_catalog *catalog,
+			struct phy *phy)
+{
+	struct msm_dp_ctrl_private *ctrl;
+	int ret;
+
+	if (!dev || !panel || !aux ||
+	    !link || !catalog) {
+		DRM_ERROR("invalid input\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
+	if (!ctrl) {
+		DRM_ERROR("Mem allocation failure\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	ret = devm_pm_opp_set_clkname(dev, "ctrl_link");
+	if (ret) {
+		dev_err(dev, "invalid DP OPP table in device tree\n");
+		/* caller do PTR_ERR(opp_table) */
+		return (struct msm_dp_ctrl *)ERR_PTR(ret);
+	}
+
+	/* OPP table is optional */
+	ret = devm_pm_opp_of_add_table(dev);
+	if (ret)
+		dev_err(dev, "failed to add DP OPP table\n");
+
+	init_completion(&ctrl->idle_comp);
+	init_completion(&ctrl->psr_op_comp);
+	init_completion(&ctrl->video_comp);
+
+	/* in parameters */
+	ctrl->panel    = panel;
+	ctrl->aux      = aux;
+	ctrl->link     = link;
+	ctrl->catalog  = catalog;
+	ctrl->dev      = dev;
+	ctrl->phy      = phy;
+	ctrl->mst_active = false;
+
+	ret = msm_dp_ctrl_clk_init(&ctrl->msm_dp_ctrl);
+	if (ret) {
+		dev_err(dev, "failed to init clocks\n");
+		return ERR_PTR(ret);
+	}
+
+	return &ctrl->msm_dp_ctrl;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_ctrl.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_ctrl.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DP_CTRL_H_
+#define _DP_CTRL_H_
+
+#include "dp_aux.h"
+#include "dp_panel.h"
+#include "dp_link.h"
+#include "dp_catalog.h"
+
+struct msm_dp_ctrl {
+	bool wide_bus_en;
+};
+
+struct phy;
+
+int msm_dp_ctrl_on_link(struct msm_dp_ctrl *msm_dp_ctrl, bool mst_active);
+int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl,
+			  struct msm_dp_panel *msm_dp_panel, u32 max_streams);
+int msm_dp_ctrl_prepare_stream_on(struct msm_dp_ctrl *msm_dp_ctrl, bool force_link_train);
+void msm_dp_ctrl_off_link_stream(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_off_link(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_stream_clk_off(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *msm_dp_panel);
+void msm_dp_ctrl_push_idle(struct msm_dp_ctrl *msm_dp_ctrl);
+irqreturn_t msm_dp_ctrl_isr(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_handle_sink_request(struct msm_dp_ctrl *msm_dp_ctrl);
+struct msm_dp_ctrl *msm_dp_ctrl_get(struct device *dev, struct msm_dp_link *link,
+			struct msm_dp_panel *panel,	struct drm_dp_aux *aux,
+			struct msm_dp_catalog *catalog,
+			struct phy *phy);
+
+void msm_dp_ctrl_reset_irq_ctrl(struct msm_dp_ctrl *msm_dp_ctrl, bool enable);
+void msm_dp_ctrl_phy_init(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_irq_phy_exit(struct msm_dp_ctrl *msm_dp_ctrl);
+
+void msm_dp_ctrl_set_psr(struct msm_dp_ctrl *msm_dp_ctrl, bool enable);
+void msm_dp_ctrl_config_psr(struct msm_dp_ctrl *msm_dp_ctrl);
+
+int msm_dp_ctrl_core_clk_enable(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_core_clk_disable(struct msm_dp_ctrl *msm_dp_ctrl);
+
+void msm_dp_ctrl_clear_vsc_sdp_pkt(struct msm_dp_ctrl *msm_dp_ctrl,
+		struct msm_dp_panel *msm_dp_panel);
+void msm_dp_ctrl_psm_config(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_reinit_phy(struct msm_dp_ctrl *msm_dp_ctrl);
+int msm_dp_ctrl_mst_send_act(struct msm_dp_ctrl *msm_dp_ctrl);
+void msm_dp_ctrl_mst_stream_channel_slot_setup(struct msm_dp_ctrl *msm_dp_ctrl, u32 max_streams);
+void msm_dp_ctrl_set_mst_channel_info(struct msm_dp_ctrl *msm_dp_ctrl,
+				      enum msm_dp_stream_id strm,
+				      u32 start_slot, u32 tot_slots);
+void msm_dp_ctrl_push_vcpf(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel *msm_dp_panel);
+#endif /* _DP_CTRL_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_debug.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_debug.c
@@ -0,0 +1,237 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ */
+
+#define pr_fmt(fmt)"[drm-dp] %s: " fmt, __func__
+
+#include <linux/debugfs.h>
+#include <drm/drm_connector.h>
+#include <drm/drm_file.h>
+
+#include "dp_catalog.h"
+#include "dp_aux.h"
+#include "dp_ctrl.h"
+#include "dp_debug.h"
+#include "dp_display.h"
+
+#define DEBUG_NAME "msm_dp"
+
+struct msm_dp_debug_private {
+	struct msm_dp_link *link;
+	struct msm_dp_panel *panel;
+	struct drm_connector *connector;
+};
+
+static int msm_dp_debug_show(struct seq_file *seq, void *p)
+{
+	struct msm_dp_debug_private *debug = seq->private;
+	u64 lclk = 0;
+	u32 link_params_rate;
+	const struct drm_display_mode *drm_mode;
+
+	if (!debug)
+		return -ENODEV;
+
+	drm_mode = &debug->panel->msm_dp_mode.drm_mode;
+
+	seq_printf(seq, "\tname = %s\n", DEBUG_NAME);
+	seq_printf(seq, "\tdrm_dp_link\n\t\trate = %u\n",
+			debug->panel->link_info.rate);
+	seq_printf(seq, "\t\tnum_lanes = %u\n",
+			debug->panel->link_info.num_lanes);
+	seq_printf(seq, "\t\tcapabilities = %lu\n",
+			debug->panel->link_info.capabilities);
+	seq_printf(seq, "\tdp_panel_info:\n\t\tactive = %dx%d\n",
+			drm_mode->hdisplay,
+			drm_mode->vdisplay);
+	seq_printf(seq, "\t\tback_porch = %dx%d\n",
+			drm_mode->htotal - drm_mode->hsync_end,
+			drm_mode->vtotal - drm_mode->vsync_end);
+	seq_printf(seq, "\t\tfront_porch = %dx%d\n",
+			drm_mode->hsync_start - drm_mode->hdisplay,
+			drm_mode->vsync_start - drm_mode->vdisplay);
+	seq_printf(seq, "\t\tsync_width = %dx%d\n",
+			drm_mode->hsync_end - drm_mode->hsync_start,
+			drm_mode->vsync_end - drm_mode->vsync_start);
+	seq_printf(seq, "\t\tactive_low = %dx%d\n",
+			debug->panel->msm_dp_mode.h_active_low,
+			debug->panel->msm_dp_mode.v_active_low);
+	seq_printf(seq, "\t\th_skew = %d\n",
+			drm_mode->hskew);
+	seq_printf(seq, "\t\trefresh rate = %d\n",
+			drm_mode_vrefresh(drm_mode));
+	seq_printf(seq, "\t\tpixel clock khz = %d\n",
+			drm_mode->clock);
+	seq_printf(seq, "\t\tbpp = %d\n",
+			debug->panel->msm_dp_mode.bpp);
+
+	/* Link Information */
+	seq_printf(seq, "\tdp_link:\n\t\ttest_requested = %d\n",
+			debug->link->sink_request);
+	seq_printf(seq, "\t\tnum_lanes = %d\n",
+			debug->link->link_params.num_lanes);
+	link_params_rate = debug->link->link_params.rate;
+	seq_printf(seq, "\t\tbw_code = %d\n",
+			drm_dp_link_rate_to_bw_code(link_params_rate));
+	lclk = debug->link->link_params.rate * 1000;
+	seq_printf(seq, "\t\tlclk = %lld\n", lclk);
+	seq_printf(seq, "\t\tv_level = %d\n",
+			debug->link->phy_params.v_level);
+	seq_printf(seq, "\t\tp_level = %d\n",
+			debug->link->phy_params.p_level);
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(msm_dp_debug);
+
+static int msm_dp_test_data_show(struct seq_file *m, void *data)
+{
+	const struct msm_dp_debug_private *debug = m->private;
+	const struct drm_connector *connector = debug->connector;
+	u32 bpc;
+
+	if (connector->status == connector_status_connected) {
+		bpc = debug->link->test_video.test_bit_depth;
+		seq_printf(m, "hdisplay: %d\n",
+				debug->link->test_video.test_h_width);
+		seq_printf(m, "vdisplay: %d\n",
+				debug->link->test_video.test_v_height);
+		seq_printf(m, "bpc: %u\n",
+				msm_dp_link_bit_depth_to_bpp(bpc) / 3);
+	} else {
+		seq_puts(m, "0");
+	}
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(msm_dp_test_data);
+
+static int msm_dp_test_type_show(struct seq_file *m, void *data)
+{
+	const struct msm_dp_debug_private *debug = m->private;
+	const struct drm_connector *connector = debug->connector;
+
+	if (connector->status == connector_status_connected)
+		seq_printf(m, "%02x", DP_TEST_LINK_VIDEO_PATTERN);
+	else
+		seq_puts(m, "0");
+
+	return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(msm_dp_test_type);
+
+static ssize_t msm_dp_test_active_write(struct file *file,
+		const char __user *ubuf,
+		size_t len, loff_t *offp)
+{
+	char *input_buffer;
+	int status = 0;
+	const struct msm_dp_debug_private *debug;
+	const struct drm_connector *connector;
+	int val = 0;
+
+	debug = ((struct seq_file *)file->private_data)->private;
+	connector = debug->connector;
+
+	if (len == 0)
+		return 0;
+
+	input_buffer = memdup_user_nul(ubuf, len);
+	if (IS_ERR(input_buffer))
+		return PTR_ERR(input_buffer);
+
+	DRM_DEBUG_DRIVER("Copied %d bytes from user\n", (unsigned int)len);
+
+	if (connector->status == connector_status_connected) {
+		status = kstrtoint(input_buffer, 10, &val);
+		if (status < 0) {
+			kfree(input_buffer);
+			return status;
+		}
+		DRM_DEBUG_DRIVER("Got %d for test active\n", val);
+		/* To prevent erroneous activation of the compliance
+		 * testing code, only accept an actual value of 1 here
+		 */
+		if (val == 1)
+			debug->panel->video_test = true;
+		else
+			debug->panel->video_test = false;
+	}
+	kfree(input_buffer);
+
+	*offp += len;
+	return len;
+}
+
+static int msm_dp_test_active_show(struct seq_file *m, void *data)
+{
+	struct msm_dp_debug_private *debug = m->private;
+	struct drm_connector *connector = debug->connector;
+
+	if (connector->status == connector_status_connected) {
+		if (debug->panel->video_test)
+			seq_puts(m, "1");
+		else
+			seq_puts(m, "0");
+	} else {
+		seq_puts(m, "0");
+	}
+
+	return 0;
+}
+
+static int msm_dp_test_active_open(struct inode *inode,
+		struct file *file)
+{
+	return single_open(file, msm_dp_test_active_show,
+			inode->i_private);
+}
+
+static const struct file_operations test_active_fops = {
+	.owner = THIS_MODULE,
+	.open = msm_dp_test_active_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+	.write = msm_dp_test_active_write
+};
+
+int msm_dp_debug_init(struct device *dev, struct msm_dp_panel *panel,
+		  struct msm_dp_link *link,
+		  struct drm_connector *connector,
+		  struct dentry *root, bool is_edp)
+{
+	struct msm_dp_debug_private *debug;
+
+	if (!dev || !panel || !link) {
+		DRM_ERROR("invalid input\n");
+		return -EINVAL;
+	}
+
+	debug = devm_kzalloc(dev, sizeof(*debug), GFP_KERNEL);
+	if (!debug)
+		return -ENOMEM;
+
+	debug->link = link;
+	debug->panel = panel;
+
+	debugfs_create_file("dp_debug", 0444, root,
+			debug, &msm_dp_debug_fops);
+
+	if (!is_edp) {
+		debugfs_create_file("dp_test_active", 0444,
+				    root,
+				    debug, &test_active_fops);
+
+		debugfs_create_file("dp_test_data", 0444,
+				    root,
+				    debug, &msm_dp_test_data_fops);
+
+		debugfs_create_file("dp_test_type", 0444,
+				    root,
+				    debug, &msm_dp_test_type_fops);
+	}
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_debug.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_debug.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DP_DEBUG_H_
+#define _DP_DEBUG_H_
+
+#include "dp_panel.h"
+#include "dp_link.h"
+
+#if defined(CONFIG_DEBUG_FS)
+
+/**
+ * msm_dp_debug_get() - configure and get the DisplayPlot debug module data
+ *
+ * @dev: device instance of the caller
+ * @panel: instance of panel module
+ * @link: instance of link module
+ * @connector: double pointer to display connector
+ * @root: connector's debugfs root
+ * @is_edp: set for eDP connectors / panels
+ * return: pointer to allocated debug module data
+ *
+ * This function sets up the debug module and provides a way
+ * for debugfs input to be communicated with existing modules
+ */
+int msm_dp_debug_init(struct device *dev, struct msm_dp_panel *panel,
+		  struct msm_dp_link *link,
+		  struct drm_connector *connector,
+		  struct dentry *root,
+		  bool is_edp);
+
+#else
+
+static inline
+int msm_dp_debug_init(struct device *dev, struct msm_dp_panel *panel,
+		  struct msm_dp_link *link,
+		  struct drm_connector *connector,
+		  struct dentry *root,
+		  bool is_edp)
+{
+	return -EINVAL;
+}
+
+#endif /* defined(CONFIG_DEBUG_FS) */
+
+#endif /* _DP_DEBUG_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_display.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_display.c
@@ -0,0 +1,2022 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+#include <linux/component.h>
+#include <linux/of_irq.h>
+#include <linux/phy/phy.h>
+#include <linux/delay.h>
+#include <drm/display/drm_dp_aux_bus.h>
+
+#include "msm_drv.h"
+#include "msm_kms.h"
+#include "dp_ctrl.h"
+#include "dp_catalog.h"
+#include "dp_aux.h"
+#include "dp_reg.h"
+#include "dp_link.h"
+#include "dp_panel.h"
+#include "dp_display.h"
+#include "dp_drm.h"
+#include "dp_audio.h"
+#include "dp_debug.h"
+#include "dp_mst_drm.h"
+
+static bool psr_enabled = false;
+module_param(psr_enabled, bool, 0);
+MODULE_PARM_DESC(psr_enabled, "enable PSR for eDP and DP displays");
+
+#define HPD_STRING_SIZE 30
+
+#define DEFAULT_STREAM_COUNT 1
+
+enum {
+	ISR_DISCONNECTED,
+	ISR_CONNECT_PENDING,
+	ISR_CONNECTED,
+	ISR_HPD_REPLUG_COUNT,
+	ISR_IRQ_HPD_PULSE_COUNT,
+	ISR_HPD_LO_GLITH_COUNT,
+};
+
+/* event thread connection state */
+enum {
+	ST_DISCONNECTED,
+	ST_MAINLINK_READY,
+	ST_CONNECTED,
+	ST_DISCONNECT_PENDING,
+	ST_DISPLAY_OFF,
+};
+
+enum {
+	EV_NO_EVENT,
+	/* hpd events */
+	EV_HPD_PLUG_INT,
+	EV_IRQ_HPD_INT,
+	EV_HPD_UNPLUG_INT,
+	EV_USER_NOTIFICATION,
+};
+
+#define EVENT_TIMEOUT	(HZ/10)	/* 100ms */
+#define DP_EVENT_Q_MAX	8
+
+#define DP_TIMEOUT_NONE		0
+
+#define WAIT_FOR_RESUME_TIMEOUT_JIFFIES (HZ / 2)
+
+#define MAX_DPCD_TRANSACTION_BYTES 16
+
+struct msm_dp_event {
+	u32 event_id;
+	u32 data;
+	u32 delay;
+};
+
+struct msm_dp_display_private {
+	int irq;
+
+	unsigned int id;
+
+	/* state variables */
+	bool core_initialized;
+	bool phy_initialized;
+	bool audio_supported;
+
+	struct drm_device *drm_dev;
+
+	struct msm_dp_catalog *catalog;
+	struct drm_dp_aux *aux;
+	struct msm_dp_link    *link;
+	struct msm_dp_panel   *panel;
+	struct msm_dp_ctrl    *ctrl;
+
+	struct msm_dp msm_dp_display;
+
+	/* wait for audio signaling */
+	struct completion audio_comp;
+
+	unsigned int max_stream;
+
+	/* event related only access by event thread */
+	struct mutex event_mutex;
+	wait_queue_head_t event_q;
+	u32 hpd_state;
+	u32 event_pndx;
+	u32 event_gndx;
+	struct task_struct *ev_tsk;
+	struct msm_dp_event event_list[DP_EVENT_Q_MAX];
+	spinlock_t event_lock;
+
+	bool wide_bus_supported;
+
+	u32 active_stream_cnt;
+
+	const unsigned int *intf_map;
+
+	struct msm_dp_audio *audio;
+};
+
+struct msm_dp_desc {
+	phys_addr_t io_start;
+	unsigned int id;
+	bool wide_bus_supported;
+	const unsigned int *intf_map;
+	unsigned int max_streams;
+};
+
+/* to be kept in sync with enum dpu_intf of dpu_hw_mdss.h */
+enum dp_mst_intf {
+	INTF_0 = 1,
+	INTF_1,
+	INTF_2,
+	INTF_3,
+	INTF_4,
+	INTF_5,
+	INTF_6,
+	INTF_7,
+	INTF_8,
+	INTF_MAX
+};
+
+static const unsigned int stream_intf_map_sa_8775p[][DP_STREAM_MAX] = {
+	{INTF_0, INTF_3},
+	{INTF_4, INTF_8},
+	{}
+};
+
+static const struct msm_dp_desc msm_dp_desc_qcs8300[] = {
+	{ .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true,
+	  .max_streams = 2, .intf_map = stream_intf_map_sa_8775p[MSM_DP_CONTROLLER_0],
+	},
+	{}
+};
+
+static const struct msm_dp_desc msm_dp_desc_sa8775p[] = {
+	{ .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true,
+	  .max_streams = 2, .intf_map = stream_intf_map_sa_8775p[MSM_DP_CONTROLLER_0],
+	},
+	{ .io_start = 0x0af5c000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true,
+	  .max_streams = 2, .intf_map = stream_intf_map_sa_8775p[MSM_DP_CONTROLLER_1],
+	},
+	{ .io_start = 0x22154000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },
+	{ .io_start = 0x2215c000, .id = MSM_DP_CONTROLLER_3, .wide_bus_supported = true },
+	{}
+};
+
+static const struct msm_dp_desc msm_dp_desc_sc7180[] = {
+	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{}
+};
+
+static const struct msm_dp_desc msm_dp_desc_sc7280[] = {
+	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
+	{}
+};
+
+static const struct msm_dp_desc msm_dp_desc_sc8180x[] = {
+	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{ .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
+	{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },
+	{}
+};
+
+static const struct msm_dp_desc msm_dp_desc_sc8280xp[] = {
+	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{ .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
+	{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },
+	{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .wide_bus_supported = true },
+	{ .io_start = 0x22090000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{ .io_start = 0x22098000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
+	{ .io_start = 0x2209a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },
+	{ .io_start = 0x220a0000, .id = MSM_DP_CONTROLLER_3, .wide_bus_supported = true },
+	{}
+};
+
+static const struct msm_dp_desc msm_dp_desc_sm8650[] = {
+	{ .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{}
+};
+
+static const struct msm_dp_desc msm_dp_desc_x1e80100[] = {
+	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },
+	{ .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },
+	{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },
+	{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .wide_bus_supported = true },
+	{}
+};
+
+static const struct of_device_id msm_dp_dt_match[] = {
+	{ .compatible = "qcom,qcs8300-dp", .data = &msm_dp_desc_qcs8300 },
+	{ .compatible = "qcom,sa8775p-dp", .data = &msm_dp_desc_sa8775p },
+	{ .compatible = "qcom,sc7180-dp", .data = &msm_dp_desc_sc7180 },
+	{ .compatible = "qcom,sc7280-dp", .data = &msm_dp_desc_sc7280 },
+	{ .compatible = "qcom,sc7280-edp", .data = &msm_dp_desc_sc7280 },
+	{ .compatible = "qcom,sc8180x-dp", .data = &msm_dp_desc_sc8180x },
+	{ .compatible = "qcom,sc8180x-edp", .data = &msm_dp_desc_sc8180x },
+	{ .compatible = "qcom,sc8280xp-dp", .data = &msm_dp_desc_sc8280xp },
+	{ .compatible = "qcom,sc8280xp-edp", .data = &msm_dp_desc_sc8280xp },
+	{ .compatible = "qcom,sdm845-dp", .data = &msm_dp_desc_sc7180 },
+	{ .compatible = "qcom,sm8350-dp", .data = &msm_dp_desc_sc7180 },
+	{ .compatible = "qcom,sm8650-dp", .data = &msm_dp_desc_sm8650 },
+	{ .compatible = "qcom,x1e80100-dp", .data = &msm_dp_desc_x1e80100 },
+	{}
+};
+
+int msm_dp_display_get_active_stream_cnt(struct msm_dp *msm_dp)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(msm_dp, struct msm_dp_display_private, msm_dp_display);
+
+	return msm_dp_display->active_stream_cnt;
+}
+
+static struct msm_dp_display_private *dev_get_dp_display_private(struct device *dev)
+{
+	struct msm_dp *dp = dev_get_drvdata(dev);
+
+	return container_of(dp, struct msm_dp_display_private, msm_dp_display);
+}
+
+static int msm_dp_add_event(struct msm_dp_display_private *msm_dp_priv, u32 event,
+						u32 data, u32 delay)
+{
+	unsigned long flag;
+	struct msm_dp_event *todo;
+	int pndx;
+
+	spin_lock_irqsave(&msm_dp_priv->event_lock, flag);
+	pndx = msm_dp_priv->event_pndx + 1;
+	pndx %= DP_EVENT_Q_MAX;
+	if (pndx == msm_dp_priv->event_gndx) {
+		pr_err("event_q is full: pndx=%d gndx=%d\n",
+			msm_dp_priv->event_pndx, msm_dp_priv->event_gndx);
+		spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
+		return -EPERM;
+	}
+	todo = &msm_dp_priv->event_list[msm_dp_priv->event_pndx++];
+	msm_dp_priv->event_pndx %= DP_EVENT_Q_MAX;
+	todo->event_id = event;
+	todo->data = data;
+	todo->delay = delay;
+	wake_up(&msm_dp_priv->event_q);
+	spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
+
+	return 0;
+}
+
+static int msm_dp_del_event(struct msm_dp_display_private *msm_dp_priv, u32 event)
+{
+	unsigned long flag;
+	struct msm_dp_event *todo;
+	u32	gndx;
+
+	spin_lock_irqsave(&msm_dp_priv->event_lock, flag);
+	if (msm_dp_priv->event_pndx == msm_dp_priv->event_gndx) {
+		spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
+		return -ENOENT;
+	}
+
+	gndx = msm_dp_priv->event_gndx;
+	while (msm_dp_priv->event_pndx != gndx) {
+		todo = &msm_dp_priv->event_list[gndx];
+		if (todo->event_id == event) {
+			todo->event_id = EV_NO_EVENT;	/* deleted */
+			todo->delay = 0;
+		}
+		gndx++;
+		gndx %= DP_EVENT_Q_MAX;
+	}
+	spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
+
+	return 0;
+}
+
+void msm_dp_display_signal_audio_start(struct msm_dp *msm_dp_display)
+{
+	struct msm_dp_display_private *dp;
+
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	reinit_completion(&dp->audio_comp);
+}
+
+void msm_dp_display_signal_audio_complete(struct msm_dp *msm_dp_display)
+{
+	struct msm_dp_display_private *dp;
+
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	complete_all(&dp->audio_comp);
+}
+
+static int msm_dp_hpd_event_thread_start(struct msm_dp_display_private *msm_dp_priv);
+
+static int msm_dp_display_bind(struct device *dev, struct device *master,
+			   void *data)
+{
+	int rc = 0;
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
+	struct msm_drm_private *priv = dev_get_drvdata(master);
+	struct drm_device *drm = priv->dev;
+
+	dp->msm_dp_display.drm_dev = drm;
+	priv->dp[dp->id] = &dp->msm_dp_display;
+
+
+
+	dp->drm_dev = drm;
+	dp->aux->drm_dev = drm;
+	rc = msm_dp_aux_register(dp->aux);
+	if (rc) {
+		DRM_ERROR("DRM DP AUX register failed\n");
+		goto end;
+	}
+
+
+	rc = msm_dp_register_audio_driver(dev, dp->audio);
+	if (rc) {
+		DRM_ERROR("Audio registration Dp failed\n");
+		goto end;
+	}
+
+	rc = msm_dp_hpd_event_thread_start(dp);
+	if (rc) {
+		DRM_ERROR("Event thread create failed\n");
+		goto end;
+	}
+
+	return 0;
+end:
+	return rc;
+}
+
+static void msm_dp_display_unbind(struct device *dev, struct device *master,
+			      void *data)
+{
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
+	struct msm_drm_private *priv = dev_get_drvdata(master);
+
+	kthread_stop(dp->ev_tsk);
+
+	of_dp_aux_depopulate_bus(dp->aux);
+
+	msm_dp_unregister_audio_driver(dev, dp->audio);
+	msm_dp_aux_unregister(dp->aux);
+	dp->drm_dev = NULL;
+	dp->aux->drm_dev = NULL;
+	priv->dp[dp->id] = NULL;
+}
+
+static const struct component_ops msm_dp_display_comp_ops = {
+	.bind = msm_dp_display_bind,
+	.unbind = msm_dp_display_unbind,
+};
+
+static void msm_dp_display_send_hpd_event(struct msm_dp *msm_dp_display)
+{
+	struct msm_dp_display_private *dp;
+	struct drm_connector *connector;
+
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	connector = dp->msm_dp_display.connector;
+	drm_helper_hpd_irq_event(connector->dev);
+}
+
+static int msm_dp_display_send_hpd_notification(struct msm_dp_display_private *dp,
+					    bool hpd)
+{
+	if ((hpd && dp->msm_dp_display.link_ready) ||
+			(!hpd && !dp->msm_dp_display.link_ready)) {
+		drm_dbg_dp(dp->drm_dev, "HPD already %s\n",
+				(hpd ? "on" : "off"));
+		return 0;
+	}
+
+	/* reset video pattern flag on disconnect */
+	if (!hpd) {
+		dp->panel->video_test = false;
+		if (!dp->msm_dp_display.is_edp)
+			drm_dp_set_subconnector_property(dp->msm_dp_display.connector,
+							 connector_status_disconnected,
+							 dp->panel->dpcd,
+							 dp->panel->downstream_ports);
+	}
+
+	dp->msm_dp_display.link_ready = hpd;
+
+	drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n",
+			dp->msm_dp_display.connector_type, hpd);
+	msm_dp_display_send_hpd_event(&dp->msm_dp_display);
+
+	return 0;
+}
+
+static void msm_dp_display_mst_init(struct msm_dp_display_private *dp)
+{
+	const unsigned long clear_mstm_ctrl_timeout_us = 100000;
+	u8 old_mstm_ctrl;
+	struct msm_dp *msm_dp = &dp->msm_dp_display;
+	int ret;
+
+	/* clear sink mst state */
+	drm_dp_dpcd_readb(dp->aux, DP_MSTM_CTRL, &old_mstm_ctrl);
+	drm_dp_dpcd_writeb(dp->aux, DP_MSTM_CTRL, 0);
+
+	/* add extra delay if MST state is not cleared */
+	if (old_mstm_ctrl) {
+		drm_dbg_dp(dp->drm_dev, "MSTM_CTRL is not cleared, wait %luus\n",
+			   clear_mstm_ctrl_timeout_us);
+		usleep_range(clear_mstm_ctrl_timeout_us,
+			     clear_mstm_ctrl_timeout_us + 1000);
+	}
+
+	ret = drm_dp_dpcd_writeb(dp->aux, DP_MSTM_CTRL,
+				 DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC);
+	if (ret < 0) {
+		DRM_ERROR("sink mst enablement failed\n");
+		return;
+	}
+
+	msm_dp->mst_active = true;
+}
+
+static void msm_dp_display_set_mst_mgr_state(struct msm_dp_display_private *dp,
+					     bool state)
+{
+	if (!dp->msm_dp_display.mst_active)
+		return;
+
+	msm_dp_mst_display_set_mgr_state(&dp->msm_dp_display, state);
+
+	drm_dbg_dp(dp->drm_dev, "mst_mgr_state: %d\n", state);
+}
+
+static int msm_dp_display_process_hpd_high(struct msm_dp_display_private *dp)
+{
+	struct drm_connector *connector = dp->msm_dp_display.connector;
+	const struct drm_display_info *info = &connector->display_info;
+	int rc = 0;
+	struct msm_dp *dp_display = &dp->msm_dp_display;
+
+	rc = msm_dp_panel_read_link_caps(dp->panel, connector);
+	if (rc)
+		goto end;
+
+	if (dp->max_stream <= DEFAULT_STREAM_COUNT || !msm_dp_panel_read_mst_cap(dp->panel)) {
+		rc = msm_dp_panel_read_edid(dp->panel, connector);
+		if (rc)
+			goto end;
+	}
+
+	msm_dp_link_process_request(dp->link);
+
+	if (!dp->msm_dp_display.is_edp)
+		drm_dp_set_subconnector_property(connector,
+						 connector_status_connected,
+						 dp->panel->dpcd,
+						 dp->panel->downstream_ports);
+
+	dp->msm_dp_display.psr_supported = dp->panel->psr_cap.version && psr_enabled;
+
+	dp->audio_supported = info->has_audio;
+	msm_dp_panel_handle_sink_request(dp->panel);
+
+	/*
+	 * set sink to normal operation mode -- D0
+	 * before dpcd read
+	 */
+	msm_dp_link_psm_config(dp->link, &dp->panel->link_info, false);
+
+	if (dp->max_stream > DEFAULT_STREAM_COUNT && msm_dp_panel_read_mst_cap(dp->panel))
+		msm_dp_display_mst_init(dp);
+
+	msm_dp_link_reset_phy_params_vx_px(dp->link);
+	rc = msm_dp_ctrl_on_link(dp->ctrl, dp_display->mst_active);
+	if (rc) {
+		DRM_ERROR("failed to complete DP link training\n");
+		goto end;
+	}
+
+	msm_dp_display_set_mst_mgr_state(dp, true);
+
+	msm_dp_add_event(dp, EV_USER_NOTIFICATION, true, 0);
+
+end:
+	return rc;
+}
+
+static void msm_dp_display_host_phy_init(struct msm_dp_display_private *dp)
+{
+	drm_dbg_dp(dp->drm_dev, "type=%d core_init=%d phy_init=%d\n",
+		dp->msm_dp_display.connector_type, dp->core_initialized,
+		dp->phy_initialized);
+
+	if (!dp->phy_initialized) {
+		msm_dp_ctrl_phy_init(dp->ctrl);
+		dp->phy_initialized = true;
+	}
+}
+
+static void msm_dp_display_host_phy_exit(struct msm_dp_display_private *dp)
+{
+	drm_dbg_dp(dp->drm_dev, "type=%d core_init=%d phy_init=%d\n",
+		dp->msm_dp_display.connector_type, dp->core_initialized,
+		dp->phy_initialized);
+
+	if (dp->phy_initialized) {
+		msm_dp_ctrl_phy_exit(dp->ctrl);
+		dp->phy_initialized = false;
+	}
+}
+
+static void msm_dp_display_host_init(struct msm_dp_display_private *dp)
+{
+	drm_dbg_dp(dp->drm_dev, "type=%d core_init=%d phy_init=%d\n",
+		dp->msm_dp_display.connector_type, dp->core_initialized,
+		dp->phy_initialized);
+
+	msm_dp_ctrl_core_clk_enable(dp->ctrl);
+	msm_dp_ctrl_reset_irq_ctrl(dp->ctrl, true);
+	msm_dp_aux_init(dp->aux);
+	dp->core_initialized = true;
+}
+
+static void msm_dp_display_host_deinit(struct msm_dp_display_private *dp)
+{
+	drm_dbg_dp(dp->drm_dev, "type=%d core_init=%d phy_init=%d\n",
+		dp->msm_dp_display.connector_type, dp->core_initialized,
+		dp->phy_initialized);
+
+	msm_dp_ctrl_reset_irq_ctrl(dp->ctrl, false);
+	msm_dp_aux_deinit(dp->aux);
+	msm_dp_ctrl_core_clk_disable(dp->ctrl);
+	dp->core_initialized = false;
+}
+
+static int msm_dp_display_usbpd_configure_cb(struct device *dev)
+{
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
+
+	msm_dp_display_host_phy_init(dp);
+
+	return msm_dp_display_process_hpd_high(dp);
+}
+
+static int msm_dp_display_notify_disconnect(struct device *dev)
+{
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
+	struct msm_dp *dp_display = &dp->msm_dp_display;
+
+	if (dp_display->mst_active) {
+		msm_dp_mst_display_set_mgr_state(&dp->msm_dp_display, false);
+		dp_display->mst_active = false;
+	}
+
+	msm_dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);
+
+	return 0;
+}
+
+static void msm_dp_display_handle_video_request(struct msm_dp_display_private *dp)
+{
+	if (dp->link->sink_request & DP_TEST_LINK_VIDEO_PATTERN) {
+		dp->panel->video_test = true;
+		msm_dp_link_send_test_response(dp->link);
+	}
+}
+
+static int msm_dp_display_handle_port_status_changed(struct msm_dp_display_private *dp)
+{
+	int rc = 0;
+
+	if (drm_dp_is_branch(dp->panel->dpcd) && dp->link->sink_count == 0) {
+		drm_dbg_dp(dp->drm_dev, "sink count is zero, nothing to do\n");
+		if (dp->hpd_state != ST_DISCONNECTED) {
+			dp->hpd_state = ST_DISCONNECT_PENDING;
+			msm_dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);
+		}
+	} else {
+		if (dp->hpd_state == ST_DISCONNECTED) {
+			dp->hpd_state = ST_MAINLINK_READY;
+			rc = msm_dp_display_process_hpd_high(dp);
+			if (rc)
+				dp->hpd_state = ST_DISCONNECTED;
+		}
+	}
+
+	return rc;
+}
+
+static int msm_dp_display_handle_irq_hpd(struct msm_dp_display_private *dp)
+{
+	u32 sink_request = dp->link->sink_request;
+
+	drm_dbg_dp(dp->drm_dev, "%d\n", sink_request);
+	if (dp->hpd_state == ST_DISCONNECTED) {
+		if (sink_request & DP_LINK_STATUS_UPDATED) {
+			drm_dbg_dp(dp->drm_dev, "Disconnected sink_request: %d\n",
+							sink_request);
+			DRM_ERROR("Disconnected, no DP_LINK_STATUS_UPDATED\n");
+			return -EINVAL;
+		}
+	}
+
+	msm_dp_ctrl_handle_sink_request(dp->ctrl);
+
+	if (sink_request & DP_TEST_LINK_VIDEO_PATTERN)
+		msm_dp_display_handle_video_request(dp);
+
+	return 0;
+}
+
+static int msm_dp_display_usbpd_attention_cb(struct device *dev)
+{
+	int rc = 0;
+	u32 sink_request;
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
+	struct msm_dp *msm_dp_display = &dp->msm_dp_display;
+
+	/* check for any test request issued by sink */
+	rc = msm_dp_link_process_request(dp->link);
+	if (!rc) {
+		sink_request = dp->link->sink_request;
+		drm_dbg_dp(dp->drm_dev, "hpd_state=%d sink_request=%d\n",
+					dp->hpd_state, sink_request);
+		if (sink_request & DS_PORT_STATUS_CHANGED) {
+			if (!msm_dp_display->mst_active)
+				rc = msm_dp_display_handle_port_status_changed(dp);
+		} else {
+			rc = msm_dp_display_handle_irq_hpd(dp);
+		}
+	}
+
+	msm_dp_mst_display_hpd_irq(&dp->msm_dp_display);
+	return rc;
+}
+
+static int msm_dp_hpd_plug_handle(struct msm_dp_display_private *dp, u32 data)
+{
+	u32 state;
+	int ret;
+	struct platform_device *pdev = dp->msm_dp_display.pdev;
+
+	msm_dp_aux_enable_xfers(dp->aux, true);
+
+	mutex_lock(&dp->event_mutex);
+
+	state =  dp->hpd_state;
+	drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
+			dp->msm_dp_display.connector_type, state);
+
+	if (state == ST_DISPLAY_OFF) {
+		mutex_unlock(&dp->event_mutex);
+		return 0;
+	}
+
+	if (state == ST_MAINLINK_READY || state == ST_CONNECTED) {
+		mutex_unlock(&dp->event_mutex);
+		return 0;
+	}
+
+	if (state == ST_DISCONNECT_PENDING) {
+		/* wait until ST_DISCONNECTED */
+		msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0, 1); /* delay = 1 */
+		mutex_unlock(&dp->event_mutex);
+		return 0;
+	}
+
+	ret = pm_runtime_resume_and_get(&pdev->dev);
+	if (ret) {
+		DRM_ERROR("failed to pm_runtime_resume\n");
+		mutex_unlock(&dp->event_mutex);
+		return ret;
+	}
+
+	ret = msm_dp_display_usbpd_configure_cb(&pdev->dev);
+	if (ret) {	/* link train failed */
+		dp->hpd_state = ST_DISCONNECTED;
+		pm_runtime_put_sync(&pdev->dev);
+	} else {
+		dp->hpd_state = ST_MAINLINK_READY;
+	}
+
+	drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
+			dp->msm_dp_display.connector_type, state);
+	mutex_unlock(&dp->event_mutex);
+
+	/* uevent will complete connection part */
+	return 0;
+};
+
+static void msm_dp_display_handle_plugged_change(struct msm_dp *msm_dp_display,
+		bool plugged)
+{
+	struct msm_dp_display_private *dp;
+
+	dp = container_of(msm_dp_display,
+			struct msm_dp_display_private, msm_dp_display);
+
+	/* notify audio subsystem only if sink supports audio */
+	if (msm_dp_display->plugged_cb && msm_dp_display->codec_dev &&
+			dp->audio_supported)
+		msm_dp_display->plugged_cb(msm_dp_display->codec_dev, plugged);
+}
+
+static int msm_dp_hpd_unplug_handle(struct msm_dp_display_private *dp, u32 data)
+{
+	u32 state;
+	struct platform_device *pdev = dp->msm_dp_display.pdev;
+
+	msm_dp_aux_enable_xfers(dp->aux, false);
+
+	mutex_lock(&dp->event_mutex);
+
+	state = dp->hpd_state;
+
+	drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
+			dp->msm_dp_display.connector_type, state);
+
+	/* unplugged, no more irq_hpd handle */
+	msm_dp_del_event(dp, EV_IRQ_HPD_INT);
+
+	if (state == ST_DISCONNECTED) {
+		/* triggered by irq_hdp with sink_count = 0 */
+		if (dp->link->sink_count == 0) {
+			msm_dp_display_host_phy_exit(dp);
+		}
+		msm_dp_display_notify_disconnect(&dp->msm_dp_display.pdev->dev);
+		mutex_unlock(&dp->event_mutex);
+		return 0;
+	} else if (state == ST_DISCONNECT_PENDING) {
+		mutex_unlock(&dp->event_mutex);
+		return 0;
+	} else if (state == ST_MAINLINK_READY) {
+		msm_dp_ctrl_off_link(dp->ctrl);
+		msm_dp_display_host_phy_exit(dp);
+		dp->hpd_state = ST_DISCONNECTED;
+		msm_dp_display_notify_disconnect(&dp->msm_dp_display.pdev->dev);
+		pm_runtime_put_sync(&pdev->dev);
+		mutex_unlock(&dp->event_mutex);
+		return 0;
+	}
+
+	/*
+	 * We don't need separate work for disconnect as
+	 * connect/attention interrupts are disabled
+	 */
+	msm_dp_display_notify_disconnect(&dp->msm_dp_display.pdev->dev);
+
+	if (state == ST_DISPLAY_OFF) {
+		dp->hpd_state = ST_DISCONNECTED;
+	} else {
+		dp->hpd_state = ST_DISCONNECT_PENDING;
+	}
+
+	/* signal the disconnect event early to ensure proper teardown */
+	msm_dp_display_handle_plugged_change(&dp->msm_dp_display, false);
+
+	drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
+			dp->msm_dp_display.connector_type, state);
+
+	/* uevent will complete disconnection part */
+	pm_runtime_put_sync(&pdev->dev);
+	mutex_unlock(&dp->event_mutex);
+	return 0;
+}
+
+static int msm_dp_irq_hpd_handle(struct msm_dp_display_private *dp, u32 data)
+{
+	u32 state;
+
+	mutex_lock(&dp->event_mutex);
+
+	/* irq_hpd can happen at either connected or disconnected state */
+	state =  dp->hpd_state;
+	drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
+			dp->msm_dp_display.connector_type, state);
+
+	/* irq hpd to indicate monitor disconnect/connect can happen even
+	 * after stream is disabled not necessarily due to hotplug disconnect
+	 */
+	if (state == ST_DISPLAY_OFF && !dp->msm_dp_display.mst_active) {
+		mutex_unlock(&dp->event_mutex);
+		return 0;
+	}
+
+	if ((state == ST_MAINLINK_READY || state == ST_DISCONNECT_PENDING) &&
+			!dp->msm_dp_display.mst_active) {
+		/* wait until ST_CONNECTED */
+		msm_dp_add_event(dp, EV_IRQ_HPD_INT, 0, 1); /* delay = 1 */
+		mutex_unlock(&dp->event_mutex);
+		return 0;
+	}
+
+	msm_dp_display_usbpd_attention_cb(&dp->msm_dp_display.pdev->dev);
+
+	drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",
+			dp->msm_dp_display.connector_type, state);
+
+	mutex_unlock(&dp->event_mutex);
+
+	return 0;
+}
+
+struct msm_dp_panel *msm_dp_display_get_panel(struct msm_dp *dp_display)
+{
+	struct msm_dp_display_private *dp;
+	struct msm_dp_panel *dp_panel;
+
+	struct msm_dp_panel_in panel_in;
+
+	dp = container_of(dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	panel_in.dev = &dp_display->pdev->dev;
+	panel_in.aux = dp->aux;
+	panel_in.catalog = dp->catalog;
+	panel_in.link = dp->link;
+
+	dp_panel = msm_dp_panel_get(&panel_in);
+
+	if (IS_ERR(dp->panel)) {
+		DRM_ERROR("failed to initialize panel\n");
+		return NULL;
+	}
+
+	memcpy(dp_panel->dpcd, dp->panel->dpcd, DP_RECEIVER_CAP_SIZE + 1);
+	memcpy(&dp_panel->link_info, &dp->panel->link_info,
+	       sizeof(dp->panel->link_info));
+
+	return dp_panel;
+}
+
+static void msm_dp_display_deinit_sub_modules(struct msm_dp_display_private *dp)
+{
+	msm_dp_audio_put(dp->audio);
+	msm_dp_panel_put(dp->panel);
+	msm_dp_aux_put(dp->aux);
+}
+
+static int msm_dp_init_sub_modules(struct msm_dp_display_private *dp)
+{
+	int rc = 0;
+	struct device *dev = &dp->msm_dp_display.pdev->dev;
+	struct msm_dp_panel_in panel_in = {
+		.dev = dev,
+	};
+	struct phy *phy;
+
+	phy = devm_phy_get(dev, "dp");
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	rc = phy_set_mode_ext(phy, PHY_MODE_DP,
+			      dp->msm_dp_display.is_edp ? PHY_SUBMODE_EDP : PHY_SUBMODE_DP);
+	if (rc) {
+		DRM_ERROR("failed to set phy submode, rc = %d\n", rc);
+		dp->catalog = NULL;
+		goto error;
+	}
+
+	dp->catalog = msm_dp_catalog_get(dev);
+	if (IS_ERR(dp->catalog)) {
+		rc = PTR_ERR(dp->catalog);
+		DRM_ERROR("failed to initialize catalog, rc = %d\n", rc);
+		dp->catalog = NULL;
+		goto error;
+	}
+
+	dp->aux = msm_dp_aux_get(dev, dp->catalog,
+			     phy,
+			     dp->msm_dp_display.is_edp);
+	if (IS_ERR(dp->aux)) {
+		rc = PTR_ERR(dp->aux);
+		DRM_ERROR("failed to initialize aux, rc = %d\n", rc);
+		dp->aux = NULL;
+		goto error;
+	}
+
+	dp->link = msm_dp_link_get(dev, dp->aux);
+	if (IS_ERR(dp->link)) {
+		rc = PTR_ERR(dp->link);
+		DRM_ERROR("failed to initialize link, rc = %d\n", rc);
+		dp->link = NULL;
+		goto error_link;
+	}
+
+	panel_in.aux = dp->aux;
+	panel_in.catalog = dp->catalog;
+	panel_in.link = dp->link;
+
+	dp->panel = msm_dp_panel_get(&panel_in);
+	if (IS_ERR(dp->panel)) {
+		rc = PTR_ERR(dp->panel);
+		DRM_ERROR("failed to initialize panel, rc = %d\n", rc);
+		dp->panel = NULL;
+		goto error_link;
+	}
+
+	dp->ctrl = msm_dp_ctrl_get(dev, dp->link, dp->panel, dp->aux,
+			       dp->catalog,
+			       phy);
+	if (IS_ERR(dp->ctrl)) {
+		rc = PTR_ERR(dp->ctrl);
+		DRM_ERROR("failed to initialize ctrl, rc = %d\n", rc);
+		dp->ctrl = NULL;
+		goto error_ctrl;
+	}
+
+	dp->audio = msm_dp_audio_get(dp->msm_dp_display.pdev, dp->panel, dp->catalog);
+	if (IS_ERR(dp->audio)) {
+		rc = PTR_ERR(dp->audio);
+		pr_err("failed to initialize audio, rc = %d\n", rc);
+		dp->audio = NULL;
+		goto error_ctrl;
+	}
+
+	return rc;
+
+error_ctrl:
+	msm_dp_panel_put(dp->panel);
+error_link:
+	msm_dp_aux_put(dp->aux);
+error:
+	return rc;
+}
+
+static int msm_dp_display_set_mode(struct msm_dp *msm_dp_display,
+				   const struct drm_display_mode *adjusted_mode,
+				   struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_display_mode msm_dp_mode;
+
+	memset(&msm_dp_mode, 0x0, sizeof(struct msm_dp_display_mode));
+
+	if (msm_dp_display_check_video_test(msm_dp_display))
+		msm_dp_mode.bpp = msm_dp_display_get_test_bpp(msm_dp_display);
+	else /* Default num_components per px = 3 */
+		msm_dp_mode.bpp = msm_dp_panel->connector->display_info.bpc * 3;
+
+	if (!msm_dp_mode.bpp)
+		msm_dp_mode.bpp = 24; /* Default bpp */
+
+	drm_mode_copy(&msm_dp_mode.drm_mode, adjusted_mode);
+
+	msm_dp_mode.v_active_low =
+		!!(msm_dp_mode.drm_mode.flags & DRM_MODE_FLAG_NVSYNC);
+
+	msm_dp_mode.h_active_low =
+		!!(msm_dp_mode.drm_mode.flags & DRM_MODE_FLAG_NHSYNC);
+
+	msm_dp_mode.out_fmt_is_yuv_420 =
+		drm_mode_is_420_only(&msm_dp_display->connector->display_info, adjusted_mode) &&
+		msm_dp_panel->vsc_sdp_supported;
+
+	drm_mode_copy(&msm_dp_panel->msm_dp_mode.drm_mode, &msm_dp_mode.drm_mode);
+	msm_dp_panel->msm_dp_mode.bpp = msm_dp_mode.bpp;
+	msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420 = msm_dp_mode.out_fmt_is_yuv_420;
+	msm_dp_panel->msm_dp_mode.v_active_low = msm_dp_mode.v_active_low;
+	msm_dp_panel->msm_dp_mode.h_active_low = msm_dp_mode.h_active_low;
+	msm_dp_panel_init_panel_info(msm_dp_panel);
+
+	return 0;
+}
+
+static int msm_dp_display_prepare(struct msm_dp_display_private *dp)
+{
+	int rc = 0;
+	struct msm_dp *msm_dp_display = &dp->msm_dp_display;
+	bool force_link_train = false;
+	u32 state;
+
+	drm_dbg_dp(dp->drm_dev, "sink_count=%d\n", dp->link->sink_count);
+	if (msm_dp_display->prepared) {
+		drm_dbg_dp(dp->drm_dev, "Link already setup, return\n");
+		return 0;
+	}
+
+	state = dp->hpd_state;
+	if (state != ST_DISPLAY_OFF && state != ST_MAINLINK_READY)
+		return -EINVAL;
+
+	rc = pm_runtime_resume_and_get(&msm_dp_display->pdev->dev);
+	if (rc) {
+		DRM_ERROR("failed to pm_runtime_resume\n");
+		return rc;
+	}
+
+	if (dp->hpd_state == ST_DISPLAY_OFF) {
+		msm_dp_display_host_phy_init(dp);
+		force_link_train = true;
+	}
+
+	rc = msm_dp_ctrl_prepare_stream_on(dp->ctrl, force_link_train);
+	if (!rc)
+		msm_dp_display->prepared = true;
+
+	return rc;
+}
+
+static int msm_dp_display_enable(struct msm_dp_display_private *dp,
+				 struct msm_dp_panel *msm_dp_panel)
+{
+	int rc = 0;
+
+	drm_dbg_dp(dp->drm_dev, "sink_count=%d\n", dp->link->sink_count);
+
+	rc = msm_dp_ctrl_on_stream(dp->ctrl, msm_dp_panel, dp->max_stream);
+
+	return rc;
+}
+
+static int msm_dp_display_post_enable(struct msm_dp *msm_dp_display)
+{
+	struct msm_dp_display_private *dp;
+	u32 rate;
+
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	rate = dp->link->link_params.rate;
+
+	if (dp->audio_supported) {
+		dp->audio->bw_code = drm_dp_link_rate_to_bw_code(rate);
+		dp->audio->lane_count = dp->link->link_params.num_lanes;
+	}
+
+	/* signal the connect event late to synchronize video and display */
+	msm_dp_display_handle_plugged_change(msm_dp_display, true);
+
+	if (msm_dp_display->psr_supported)
+		msm_dp_ctrl_config_psr(dp->ctrl);
+
+	return 0;
+}
+
+static void msm_dp_display_audio_notify_disable(struct msm_dp_display_private *dp)
+{
+	struct msm_dp *msm_dp_display = &dp->msm_dp_display;
+
+	/* wait only if audio was enabled */
+	if (msm_dp_display->audio_enabled) {
+		/* signal the disconnect event */
+		msm_dp_display_handle_plugged_change(msm_dp_display, false);
+		if (!wait_for_completion_timeout(&dp->audio_comp,
+				HZ * 5))
+			DRM_ERROR("audio comp timeout\n");
+	}
+
+	msm_dp_display->audio_enabled = false;
+}
+
+static int msm_dp_display_disable(struct msm_dp_display_private *dp,
+				  struct msm_dp_panel *msm_dp_panel)
+{
+	if (!dp->active_stream_cnt)
+		return 0;
+
+	msm_dp_ctrl_clear_vsc_sdp_pkt(dp->ctrl, msm_dp_panel);
+
+	msm_dp_ctrl_stream_clk_off(dp->ctrl, msm_dp_panel);
+
+	dp->active_stream_cnt--;
+
+	drm_dbg_dp(dp->drm_dev, "sink count: %d\n", dp->link->sink_count);
+	return 0;
+}
+
+int msm_dp_display_set_plugged_cb(struct msm_dp *msm_dp_display,
+		hdmi_codec_plugged_cb fn, struct device *codec_dev)
+{
+	bool plugged;
+
+	msm_dp_display->plugged_cb = fn;
+	msm_dp_display->codec_dev = codec_dev;
+	plugged = msm_dp_display->link_ready;
+	msm_dp_display_handle_plugged_change(msm_dp_display, plugged);
+
+	return 0;
+}
+
+int msm_dp_display_set_stream_info(struct msm_dp *dp,
+				   struct msm_dp_panel *panel, u32 strm_id, u32 start_slot,
+				   u32 num_slots, u32 pbn, int vcpi)
+{
+	struct msm_dp_display_private *msm_dp_display;
+	const int max_slots = 64;
+
+
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+	if (!msm_dp_display) {
+		DRM_ERROR("invalid input\n");
+		return -EINVAL;
+	}
+
+	if (strm_id >= DP_STREAM_MAX) {
+		DRM_ERROR("invalid stream id:%d\n", strm_id);
+		return -EINVAL;
+	}
+
+	if (start_slot + num_slots > max_slots) {
+		DRM_ERROR("invalid channel info received. start:%d, slots:%d\n",
+			  start_slot, num_slots);
+		return -EINVAL;
+	}
+
+	msm_dp_ctrl_set_mst_channel_info(msm_dp_display->ctrl, strm_id, start_slot, num_slots);
+
+	if (panel) {
+		panel->stream_id = strm_id;
+		panel->mst_caps.pbn = pbn;
+	}
+
+	return 0;
+}
+
+/**
+ * msm_dp_bridge_mode_valid - callback to determine if specified mode is valid
+ * @dp: Pointer to dp display structure
+ * @info: display info
+ * @mode: Pointer to drm mode structure
+ * Returns: Validity status for specified mode
+ */
+enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
+					       const struct drm_display_info *info,
+					       const struct drm_display_mode *mode)
+{
+	const u32 num_components = 3, default_bpp = 24;
+	struct msm_dp_display_private *msm_dp_display;
+	struct msm_dp_link_info *link_info;
+	u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;
+	int mode_pclk_khz = mode->clock;
+
+	if (!dp || !mode_pclk_khz || !dp->connector) {
+		DRM_ERROR("invalid params\n");
+		return -EINVAL;
+	}
+
+	if (mode->clock > DP_MAX_PIXEL_CLK_KHZ)
+		return MODE_CLOCK_HIGH;
+
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+	link_info = &msm_dp_display->panel->link_info;
+
+	if (drm_mode_is_420_only(&dp->connector->display_info, mode) &&
+	    msm_dp_display->panel->vsc_sdp_supported)
+		mode_pclk_khz /= 2;
+
+	mode_bpp = dp->connector->display_info.bpc * num_components;
+	if (!mode_bpp)
+		mode_bpp = default_bpp;
+
+	mode_bpp = msm_dp_panel_get_mode_bpp(msm_dp_display->panel,
+			mode_bpp, mode_pclk_khz);
+
+	mode_rate_khz = mode_pclk_khz * mode_bpp;
+	supported_rate_khz = link_info->num_lanes * link_info->rate * 8;
+
+	if (mode_rate_khz > supported_rate_khz)
+		return MODE_BAD;
+
+	return MODE_OK;
+}
+
+int msm_dp_display_get_modes(struct msm_dp *dp)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	if (!dp) {
+		DRM_ERROR("invalid params\n");
+		return 0;
+	}
+
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+	return msm_dp_panel_get_modes(msm_dp_display->panel,
+		dp->connector);
+}
+
+bool msm_dp_display_check_video_test(struct msm_dp *dp)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+	return msm_dp_display->panel->video_test;
+}
+
+int msm_dp_display_get_test_bpp(struct msm_dp *dp)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	if (!dp) {
+		DRM_ERROR("invalid params\n");
+		return 0;
+	}
+
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+	return msm_dp_link_bit_depth_to_bpp(
+		msm_dp_display->link->test_video.test_bit_depth);
+}
+
+void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+	/*
+	 * if we are reading registers we need the link clocks to be on
+	 * however till DP cable is connected this will not happen as we
+	 * do not know the resolution to power up with. Hence check the
+	 * power_on status before dumping DP registers to avoid crash due
+	 * to unclocked access
+	 */
+	mutex_lock(&msm_dp_display->event_mutex);
+
+	if (!msm_dp_display->active_stream_cnt) {
+		mutex_unlock(&msm_dp_display->event_mutex);
+		return;
+	}
+
+	msm_dp_catalog_snapshot(msm_dp_display->catalog, disp_state);
+
+	mutex_unlock(&msm_dp_display->event_mutex);
+}
+
+void msm_dp_display_set_psr(struct msm_dp *msm_dp_display, bool enter)
+{
+	struct msm_dp_display_private *dp;
+
+	if (!msm_dp_display) {
+		DRM_ERROR("invalid params\n");
+		return;
+	}
+
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+	msm_dp_ctrl_set_psr(dp->ctrl, enter);
+}
+
+static int hpd_event_thread(void *data)
+{
+	struct msm_dp_display_private *msm_dp_priv;
+	unsigned long flag;
+	struct msm_dp_event *todo;
+	int timeout_mode = 0;
+
+	msm_dp_priv = (struct msm_dp_display_private *)data;
+
+	while (1) {
+		if (timeout_mode) {
+			wait_event_timeout(msm_dp_priv->event_q,
+				(msm_dp_priv->event_pndx == msm_dp_priv->event_gndx) ||
+					kthread_should_stop(), EVENT_TIMEOUT);
+		} else {
+			wait_event_interruptible(msm_dp_priv->event_q,
+				(msm_dp_priv->event_pndx != msm_dp_priv->event_gndx) ||
+					kthread_should_stop());
+		}
+
+		if (kthread_should_stop())
+			break;
+
+		spin_lock_irqsave(&msm_dp_priv->event_lock, flag);
+		todo = &msm_dp_priv->event_list[msm_dp_priv->event_gndx];
+		if (todo->delay) {
+			struct msm_dp_event *todo_next;
+
+			msm_dp_priv->event_gndx++;
+			msm_dp_priv->event_gndx %= DP_EVENT_Q_MAX;
+
+			/* re enter delay event into q */
+			todo_next = &msm_dp_priv->event_list[msm_dp_priv->event_pndx++];
+			msm_dp_priv->event_pndx %= DP_EVENT_Q_MAX;
+			todo_next->event_id = todo->event_id;
+			todo_next->data = todo->data;
+			todo_next->delay = todo->delay - 1;
+
+			/* clean up older event */
+			todo->event_id = EV_NO_EVENT;
+			todo->delay = 0;
+
+			/* switch to timeout mode */
+			timeout_mode = 1;
+			spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
+			continue;
+		}
+
+		/* timeout with no events in q */
+		if (msm_dp_priv->event_pndx == msm_dp_priv->event_gndx) {
+			spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
+			continue;
+		}
+
+		msm_dp_priv->event_gndx++;
+		msm_dp_priv->event_gndx %= DP_EVENT_Q_MAX;
+		timeout_mode = 0;
+		spin_unlock_irqrestore(&msm_dp_priv->event_lock, flag);
+
+		switch (todo->event_id) {
+		case EV_HPD_PLUG_INT:
+			msm_dp_hpd_plug_handle(msm_dp_priv, todo->data);
+			break;
+		case EV_HPD_UNPLUG_INT:
+			msm_dp_hpd_unplug_handle(msm_dp_priv, todo->data);
+			break;
+		case EV_IRQ_HPD_INT:
+			msm_dp_irq_hpd_handle(msm_dp_priv, todo->data);
+			break;
+		case EV_USER_NOTIFICATION:
+			msm_dp_display_send_hpd_notification(msm_dp_priv,
+						todo->data);
+			break;
+		default:
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int msm_dp_hpd_event_thread_start(struct msm_dp_display_private *msm_dp_priv)
+{
+	/* set event q to empty */
+	msm_dp_priv->event_gndx = 0;
+	msm_dp_priv->event_pndx = 0;
+
+	msm_dp_priv->ev_tsk = kthread_run(hpd_event_thread, msm_dp_priv, "dp_hpd_handler");
+	if (IS_ERR(msm_dp_priv->ev_tsk))
+		return PTR_ERR(msm_dp_priv->ev_tsk);
+
+	return 0;
+}
+
+static irqreturn_t msm_dp_display_irq_handler(int irq, void *dev_id)
+{
+	struct msm_dp_display_private *dp = dev_id;
+	irqreturn_t ret = IRQ_NONE;
+	u32 hpd_isr_status;
+
+	if (!dp) {
+		DRM_ERROR("invalid data\n");
+		return IRQ_NONE;
+	}
+
+	hpd_isr_status = msm_dp_catalog_hpd_get_intr_status(dp->catalog);
+
+	if (hpd_isr_status & 0x0F) {
+		drm_dbg_dp(dp->drm_dev, "type=%d isr=0x%x\n",
+			dp->msm_dp_display.connector_type, hpd_isr_status);
+		/* hpd related interrupts */
+		if (hpd_isr_status & DP_DP_HPD_PLUG_INT_MASK)
+			msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
+
+		if (hpd_isr_status & DP_DP_IRQ_HPD_INT_MASK) {
+			msm_dp_add_event(dp, EV_IRQ_HPD_INT, 0, 0);
+		}
+
+		if (hpd_isr_status & DP_DP_HPD_REPLUG_INT_MASK) {
+			msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
+			msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0, 3);
+		}
+
+		if (hpd_isr_status & DP_DP_HPD_UNPLUG_INT_MASK)
+			msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
+
+		ret = IRQ_HANDLED;
+	}
+
+	/* DP controller isr */
+	ret |= msm_dp_ctrl_isr(dp->ctrl);
+
+	/* DP aux isr */
+	ret |= msm_dp_aux_isr(dp->aux);
+
+	return ret;
+}
+
+static int msm_dp_display_request_irq(struct msm_dp_display_private *dp)
+{
+	int rc = 0;
+	struct platform_device *pdev = dp->msm_dp_display.pdev;
+
+	dp->irq = platform_get_irq(pdev, 0);
+	if (dp->irq < 0) {
+		DRM_ERROR("failed to get irq\n");
+		return dp->irq;
+	}
+
+	rc = devm_request_irq(&pdev->dev, dp->irq, msm_dp_display_irq_handler,
+			      IRQF_TRIGGER_HIGH|IRQF_NO_AUTOEN,
+			      "dp_display_isr", dp);
+
+	if (rc < 0) {
+		DRM_ERROR("failed to request IRQ%u: %d\n",
+				dp->irq, rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+static const struct msm_dp_desc *msm_dp_display_get_desc(struct platform_device *pdev)
+{
+	const struct msm_dp_desc *descs = of_device_get_match_data(&pdev->dev);
+	struct resource *res;
+	int i;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return NULL;
+
+	for (i = 0; i < descs[i].io_start; i++) {
+		if (descs[i].io_start == res->start)
+			return &descs[i];
+	}
+
+	dev_err(&pdev->dev, "unknown displayport instance\n");
+	return NULL;
+}
+
+static int msm_dp_display_probe_tail(struct device *dev)
+{
+	struct msm_dp *dp = dev_get_drvdata(dev);
+	int ret;
+
+	/*
+	 * External bridges are mandatory for eDP interfaces: one has to
+	 * provide at least an eDP panel (which gets wrapped into panel-bridge).
+	 *
+	 * For DisplayPort interfaces external bridges are optional, so
+	 * silently ignore an error if one is not present (-ENODEV).
+	 */
+	dp->next_bridge = devm_drm_of_get_bridge(&dp->pdev->dev, dp->pdev->dev.of_node, 1, 0);
+	if (IS_ERR(dp->next_bridge)) {
+		ret = PTR_ERR(dp->next_bridge);
+		dp->next_bridge = NULL;
+		if (dp->is_edp || ret != -ENODEV)
+			return ret;
+	}
+
+	ret = component_add(dev, &msm_dp_display_comp_ops);
+	if (ret)
+		DRM_ERROR("component add failed, rc=%d\n", ret);
+
+	return ret;
+}
+
+static int msm_dp_auxbus_done_probe(struct drm_dp_aux *aux)
+{
+	return msm_dp_display_probe_tail(aux->dev);
+}
+
+static int msm_dp_display_get_connector_type(struct platform_device *pdev,
+					 const struct msm_dp_desc *desc)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *aux_bus = of_get_child_by_name(node, "aux-bus");
+	struct device_node *panel = of_get_child_by_name(aux_bus, "panel");
+	int connector_type;
+
+	if (panel)
+		connector_type = DRM_MODE_CONNECTOR_eDP;
+	else
+		connector_type = DRM_MODE_SUBCONNECTOR_DisplayPort;
+
+	of_node_put(panel);
+	of_node_put(aux_bus);
+
+	return connector_type;
+}
+
+int msm_dp_get_mst_max_stream(const struct msm_dp *dp_display)
+{
+	struct msm_dp_display_private *dp_priv;
+
+	dp_priv = container_of(dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	return dp_priv->max_stream;
+}
+
+int msm_dp_mst_bridge_init(struct msm_dp *dp_display, struct drm_encoder *encoder)
+{
+	return msm_dp_mst_drm_bridge_init(dp_display, encoder);
+}
+
+static int msm_dp_display_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	struct msm_dp_display_private *dp;
+	const struct msm_dp_desc *desc;
+
+	if (!pdev || !pdev->dev.of_node) {
+		DRM_ERROR("pdev not found\n");
+		return -ENODEV;
+	}
+
+	dp = devm_kzalloc(&pdev->dev, sizeof(*dp), GFP_KERNEL);
+	if (!dp)
+		return -ENOMEM;
+
+	desc = msm_dp_display_get_desc(pdev);
+	if (!desc)
+		return -EINVAL;
+
+	dp->msm_dp_display.pdev = pdev;
+	dp->id = desc->id;
+	dp->msm_dp_display.connector_type = msm_dp_display_get_connector_type(pdev, desc);
+	dp->wide_bus_supported = desc->wide_bus_supported;
+	dp->msm_dp_display.is_edp =
+		(dp->msm_dp_display.connector_type == DRM_MODE_CONNECTOR_eDP);
+
+	dp->max_stream = (desc->max_streams > DEFAULT_STREAM_COUNT) ?
+			  desc->max_streams : DEFAULT_STREAM_COUNT;
+
+	dp->intf_map = desc->intf_map;
+
+	rc = msm_dp_init_sub_modules(dp);
+	if (rc) {
+		DRM_ERROR("init sub module failed\n");
+		return -EPROBE_DEFER;
+	}
+
+	/* setup event q */
+	mutex_init(&dp->event_mutex);
+	init_waitqueue_head(&dp->event_q);
+	spin_lock_init(&dp->event_lock);
+
+	/* Store DP audio handle inside DP display */
+	dp->msm_dp_display.msm_dp_audio = dp->audio;
+
+	init_completion(&dp->audio_comp);
+
+	platform_set_drvdata(pdev, &dp->msm_dp_display);
+
+	rc = devm_pm_runtime_enable(&pdev->dev);
+	if (rc)
+		goto err;
+
+	rc = msm_dp_display_request_irq(dp);
+	if (rc)
+		goto err;
+
+	if (dp->msm_dp_display.is_edp) {
+		rc = devm_of_dp_aux_populate_bus(dp->aux, msm_dp_auxbus_done_probe);
+		if (rc) {
+			DRM_ERROR("eDP auxbus population failed, rc=%d\n", rc);
+			goto err;
+		}
+	} else {
+		rc = msm_dp_display_probe_tail(&pdev->dev);
+		if (rc)
+			goto err;
+	}
+
+	return rc;
+
+err:
+	msm_dp_display_deinit_sub_modules(dp);
+	return rc;
+}
+
+static void msm_dp_display_remove(struct platform_device *pdev)
+{
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(&pdev->dev);
+
+	component_del(&pdev->dev, &msm_dp_display_comp_ops);
+	msm_dp_display_deinit_sub_modules(dp);
+	platform_set_drvdata(pdev, NULL);
+}
+
+static int msm_dp_pm_runtime_suspend(struct device *dev)
+{
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
+
+	disable_irq(dp->irq);
+
+	if (dp->msm_dp_display.is_edp) {
+		msm_dp_display_host_phy_exit(dp);
+		msm_dp_catalog_ctrl_hpd_disable(dp->catalog);
+	}
+	msm_dp_display_host_deinit(dp);
+
+	return 0;
+}
+
+static int msm_dp_pm_runtime_resume(struct device *dev)
+{
+	struct msm_dp_display_private *dp = dev_get_dp_display_private(dev);
+
+	/*
+	 * for eDP, host cotroller, HPD block and PHY are enabled here
+	 * but with HPD irq disabled
+	 *
+	 * for DP, only host controller is enabled here.
+	 * HPD block is enabled at msm_dp_bridge_hpd_enable()
+	 * PHY will be enabled at plugin handler later
+	 */
+	msm_dp_display_host_init(dp);
+	if (dp->msm_dp_display.is_edp) {
+		msm_dp_catalog_ctrl_hpd_enable(dp->catalog);
+		msm_dp_display_host_phy_init(dp);
+	}
+
+	enable_irq(dp->irq);
+	return 0;
+}
+
+static const struct dev_pm_ops msm_dp_pm_ops = {
+	SET_RUNTIME_PM_OPS(msm_dp_pm_runtime_suspend, msm_dp_pm_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+};
+
+static struct platform_driver msm_dp_display_driver = {
+	.probe  = msm_dp_display_probe,
+	.remove_new = msm_dp_display_remove,
+	.driver = {
+		.name = "msm-dp-display",
+		.of_match_table = msm_dp_dt_match,
+		.suppress_bind_attrs = true,
+		.pm = &msm_dp_pm_ops,
+	},
+};
+
+int __init msm_dp_register(void)
+{
+	int ret;
+
+	ret = platform_driver_register(&msm_dp_display_driver);
+	if (ret)
+		DRM_ERROR("Dp display driver register failed");
+
+	return ret;
+}
+
+void __exit msm_dp_unregister(void)
+{
+	platform_driver_unregister(&msm_dp_display_driver);
+}
+
+bool msm_dp_is_yuv_420_enabled(const struct msm_dp *msm_dp_display,
+			       const struct drm_display_mode *mode)
+{
+	struct msm_dp_display_private *dp;
+	const struct drm_display_info *info;
+
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+	info = &msm_dp_display->connector->display_info;
+
+	return dp->panel->vsc_sdp_supported && drm_mode_is_420_only(info, mode);
+}
+
+bool msm_dp_needs_periph_flush(const struct msm_dp *msm_dp_display,
+			       const struct drm_display_mode *mode)
+{
+	return msm_dp_is_yuv_420_enabled(msm_dp_display, mode);
+}
+
+bool msm_dp_wide_bus_available(const struct msm_dp *msm_dp_display)
+{
+	struct msm_dp_display_private *dp;
+
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	if (dp->panel->msm_dp_mode.out_fmt_is_yuv_420)
+		return false;
+
+	return dp->wide_bus_supported;
+}
+
+int msm_dp_get_mst_intf_id(struct msm_dp *dp_display, int stream_id)
+{
+	struct msm_dp_display_private *dp;
+
+	dp = container_of(dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	if (dp->intf_map)
+		return dp->intf_map[stream_id];
+
+	return 0;
+}
+
+void msm_dp_display_debugfs_init(struct msm_dp *msm_dp_display, struct dentry *root, bool is_edp)
+{
+	struct msm_dp_display_private *dp;
+	struct device *dev;
+	int rc;
+
+	dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+	dev = &dp->msm_dp_display.pdev->dev;
+
+	rc = msm_dp_debug_init(dev, dp->panel, dp->link, dp->msm_dp_display.connector, root, is_edp);
+	if (rc)
+		DRM_ERROR("failed to initialize debug, rc = %d\n", rc);
+}
+
+int msm_dp_modeset_init(struct msm_dp *msm_dp_display, struct drm_device *dev,
+			struct drm_encoder *encoder, bool yuv_supported)
+{
+	struct msm_dp_display_private *msm_dp_priv;
+	int ret;
+
+	msm_dp_display->drm_dev = dev;
+
+	msm_dp_priv = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	ret = msm_dp_bridge_init(msm_dp_display, dev, encoder, yuv_supported);
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev,
+			"failed to create dp bridge: %d\n", ret);
+		return ret;
+	}
+
+	msm_dp_display->connector = msm_dp_drm_connector_init(msm_dp_display, encoder);
+	if (IS_ERR(msm_dp_display->connector)) {
+		ret = PTR_ERR(msm_dp_display->connector);
+		DRM_DEV_ERROR(dev->dev,
+			"failed to create dp connector: %d\n", ret);
+		msm_dp_display->connector = NULL;
+		return ret;
+	}
+
+	msm_dp_priv->panel->connector = msm_dp_display->connector;
+
+	return 0;
+}
+
+int msm_dp_mst_register(struct msm_dp *dp)
+{
+	struct msm_dp_display_private *dp_display;
+
+	dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+	return msm_dp_mst_init(dp, dp_display->max_stream,
+			   MAX_DPCD_TRANSACTION_BYTES, dp_display->aux);
+}
+
+void msm_dp_display_atomic_prepare(struct msm_dp *dp)
+{
+	int rc = 0;
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+	mutex_lock(&msm_dp_display->event_mutex);
+
+	rc = msm_dp_display_prepare(msm_dp_display);
+	if (rc) {
+		DRM_ERROR("DP display prepare failed, rc=%d\n", rc);
+	}
+
+	mutex_unlock(&msm_dp_display->event_mutex);
+}
+
+void msm_dp_display_enable_helper(struct msm_dp *dp, struct msm_dp_panel *msm_dp_panel)
+{
+	int rc = 0;
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+	if (dp->is_edp)
+		msm_dp_hpd_plug_handle(msm_dp_display, 0);
+
+	mutex_lock(&msm_dp_display->event_mutex);
+
+	rc = msm_dp_display_enable(msm_dp_display, msm_dp_panel);
+	if (rc)
+		DRM_ERROR("DP display enable failed, rc=%d\n", rc);
+
+	rc = msm_dp_display_post_enable(dp);
+	if (rc) {
+		DRM_ERROR("DP display post enable failed, rc=%d\n", rc);
+		msm_dp_display_disable(msm_dp_display, msm_dp_panel);
+	}
+
+	msm_dp_display->active_stream_cnt++;
+
+	/* completed connection */
+	msm_dp_display->hpd_state = ST_CONNECTED;
+
+	drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
+	mutex_unlock(&msm_dp_display->event_mutex);
+}
+
+void msm_dp_display_atomic_enable(struct msm_dp *msm_dp)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(msm_dp, struct msm_dp_display_private, msm_dp_display);
+
+	// move this to a different commit
+	msm_dp_display_set_stream_info(msm_dp, msm_dp_display->panel, 0, 0, 0, 0, 0);
+
+	msm_dp_display_enable_helper(msm_dp, msm_dp_display->panel);
+}
+
+void msm_dp_display_disable_helper(struct msm_dp *dp, struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+	if (!msm_dp_display->active_stream_cnt) {
+		drm_dbg_dp(dp->drm_dev, "no active streams\n");
+		return;
+	}
+
+	msm_dp_ctrl_push_vcpf(msm_dp_display->ctrl, msm_dp_panel);
+	msm_dp_ctrl_mst_stream_channel_slot_setup(msm_dp_display->ctrl, msm_dp_display->max_stream);
+	msm_dp_ctrl_mst_send_act(msm_dp_display->ctrl);
+}
+
+void msm_dp_display_atomic_disable(struct msm_dp *msm_dp)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(msm_dp, struct msm_dp_display_private, msm_dp_display);
+
+	msm_dp_ctrl_push_idle(msm_dp_display->ctrl);
+}
+
+void msm_dp_display_unprepare(struct msm_dp *msm_dp)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(msm_dp, struct msm_dp_display_private, msm_dp_display);
+	if (!msm_dp->prepared) {
+		drm_dbg_dp(msm_dp->drm_dev, "Link already unprepare, return\n");
+		return;
+	}
+
+	if (msm_dp_display->active_stream_cnt) {
+		drm_dbg_dp(msm_dp->drm_dev, "stream still active, return\n");
+		return;
+	}
+
+	/* dongle is still connected but sinks are disconnected */
+	if (msm_dp_display->link->sink_count == 0)
+		msm_dp_ctrl_psm_config(msm_dp_display->ctrl);
+
+	msm_dp_ctrl_off_link(msm_dp_display->ctrl);
+
+	/* re-init the PHY so that we can listen to Dongle disconnect */
+	if (msm_dp_display->link->sink_count == 0)
+		msm_dp_ctrl_reinit_phy(msm_dp_display->ctrl);
+	else
+		msm_dp_display_host_phy_exit(msm_dp_display);
+
+	pm_runtime_put_sync(&msm_dp->pdev->dev);
+
+	msm_dp->prepared = false;
+}
+
+void msm_dp_display_atomic_post_disable_helper(struct msm_dp *dp, struct msm_dp_panel *msm_dp_panel)
+{
+	u32 state;
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(dp, struct msm_dp_display_private, msm_dp_display);
+
+	if (dp->is_edp)
+		msm_dp_hpd_unplug_handle(msm_dp_display, 0);
+
+	mutex_lock(&msm_dp_display->event_mutex);
+
+	state = msm_dp_display->hpd_state;
+	if (state != ST_DISCONNECT_PENDING && state != ST_CONNECTED)
+		drm_dbg_dp(dp->drm_dev, "type=%d wrong hpd_state=%d\n",
+			   dp->connector_type, state);
+
+	msm_dp_display_audio_notify_disable(msm_dp_display);
+
+	msm_dp_display_disable(msm_dp_display, msm_dp_panel);
+
+	state =  msm_dp_display->hpd_state;
+	if (state == ST_DISCONNECT_PENDING && !msm_dp_display->active_stream_cnt) {
+		/* completed disconnection */
+		msm_dp_display->hpd_state = ST_DISCONNECTED;
+	} else if (state != ST_DISCONNECT_PENDING && state != ST_DISCONNECTED) {
+		/* stay at pending till both streams are disabled, otherwise OFF */
+		msm_dp_display->hpd_state = ST_DISPLAY_OFF;
+	}
+
+	drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
+
+	mutex_unlock(&msm_dp_display->event_mutex);
+}
+
+void msm_dp_display_atomic_post_disable(struct msm_dp *msm_dp)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(msm_dp, struct msm_dp_display_private, msm_dp_display);
+
+	msm_dp_display_atomic_post_disable_helper(msm_dp, msm_dp_display->panel);
+
+	msm_dp_display_unprepare(msm_dp);
+}
+
+void msm_dp_display_mode_set_helper(struct msm_dp *msm_dp,
+				    const struct drm_display_mode *mode,
+				    const struct drm_display_mode *adjusted_mode,
+				    struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(msm_dp, struct msm_dp_display_private, msm_dp_display);
+
+	msm_dp_display_set_mode(msm_dp, adjusted_mode, msm_dp_panel);
+
+	/* populate wide_bus_support to different layers */
+	msm_dp_display->ctrl->wide_bus_en =
+		msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420 ?
+		false : msm_dp_display->wide_bus_supported;
+	msm_dp_display->catalog->wide_bus_en =
+		msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420 ?
+		false : msm_dp_display->wide_bus_supported;
+}
+
+void msm_dp_display_mode_set(struct msm_dp *msm_dp,
+			     const struct drm_display_mode *mode,
+			     const struct drm_display_mode *adjusted_mode)
+{
+	struct msm_dp_display_private *msm_dp_display;
+
+	msm_dp_display = container_of(msm_dp, struct msm_dp_display_private, msm_dp_display);
+
+	msm_dp_display_mode_set_helper(msm_dp, mode, adjusted_mode, msm_dp_display->panel);
+}
+
+void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge)
+{
+	struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(bridge);
+	struct msm_dp *msm_dp_display = msm_dp_bridge->msm_dp_display;
+	struct msm_dp_display_private *dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	/*
+	 * this is for external DP with hpd irq enabled case,
+	 * step-1: msm_dp_pm_runtime_resume() enable dp host only
+	 * step-2: enable hdp block and have hpd irq enabled here
+	 * step-3: waiting for plugin irq while phy is not initialized
+	 * step-4: DP PHY is initialized at plugin handler before link training
+	 *
+	 */
+	mutex_lock(&dp->event_mutex);
+	if (pm_runtime_resume_and_get(&msm_dp_display->pdev->dev)) {
+		DRM_ERROR("failed to resume power\n");
+		mutex_unlock(&dp->event_mutex);
+		return;
+	}
+
+	msm_dp_catalog_ctrl_hpd_enable(dp->catalog);
+
+	/* enable HDP interrupts */
+	msm_dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, true);
+
+	msm_dp_display->internal_hpd = true;
+	mutex_unlock(&dp->event_mutex);
+}
+
+void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge)
+{
+	struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(bridge);
+	struct msm_dp *msm_dp_display = msm_dp_bridge->msm_dp_display;
+	struct msm_dp_display_private *dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	mutex_lock(&dp->event_mutex);
+	/* disable HDP interrupts */
+	msm_dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
+	msm_dp_catalog_ctrl_hpd_disable(dp->catalog);
+
+	msm_dp_display->internal_hpd = false;
+
+	pm_runtime_put_sync(&msm_dp_display->pdev->dev);
+	mutex_unlock(&dp->event_mutex);
+}
+
+void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
+			  enum drm_connector_status status)
+{
+	struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(bridge);
+	struct msm_dp *msm_dp_display = msm_dp_bridge->msm_dp_display;
+	struct msm_dp_display_private *dp = container_of(msm_dp_display, struct msm_dp_display_private, msm_dp_display);
+
+	/* Without next_bridge interrupts are handled by the DP core directly */
+	if (msm_dp_display->internal_hpd)
+		return;
+
+	if (!msm_dp_display->link_ready && status == connector_status_connected)
+		msm_dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
+	else if (msm_dp_display->link_ready && status == connector_status_disconnected)
+		msm_dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_display.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_display.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DP_DISPLAY_H_
+#define _DP_DISPLAY_H_
+
+#include "dp_panel.h"
+#include "dp_mst_drm.h"
+#include <sound/hdmi-codec.h>
+#include "disp/msm_disp_snapshot.h"
+
+#define DP_MAX_PIXEL_CLK_KHZ	675000
+
+struct msm_dp {
+	struct drm_device *drm_dev;
+	struct platform_device *pdev;
+	struct device *codec_dev;
+	struct drm_connector *connector;
+	struct drm_bridge *next_bridge;
+	bool link_ready;
+	bool audio_enabled;
+	bool prepared;
+	bool mst_active;
+	unsigned int connector_type;
+	bool is_edp;
+	bool internal_hpd;
+
+	struct msm_dp_mst *msm_dp_mst;
+	hdmi_codec_plugged_cb plugged_cb;
+
+	struct msm_dp_audio *msm_dp_audio;
+	bool psr_supported;
+};
+
+int msm_dp_display_set_plugged_cb(struct msm_dp *msm_dp_display,
+		hdmi_codec_plugged_cb fn, struct device *codec_dev);
+int msm_dp_display_get_modes(struct msm_dp *msm_dp_display);
+bool msm_dp_display_check_video_test(struct msm_dp *msm_dp_display);
+int msm_dp_display_get_test_bpp(struct msm_dp *msm_dp_display);
+void msm_dp_display_signal_audio_start(struct msm_dp *msm_dp_display);
+void msm_dp_display_signal_audio_complete(struct msm_dp *msm_dp_display);
+void msm_dp_display_set_psr(struct msm_dp *dp, bool enter);
+void msm_dp_display_debugfs_init(struct msm_dp *msm_dp_display, struct dentry *dentry, bool is_edp);
+void msm_dp_display_atomic_post_disable(struct msm_dp *dp_display);
+void msm_dp_display_atomic_disable(struct msm_dp *dp_display);
+void msm_dp_display_atomic_enable(struct msm_dp *dp_display);
+void msm_dp_display_atomic_prepare(struct msm_dp *dp);
+void msm_dp_display_mode_set(struct msm_dp *dp,
+			     const struct drm_display_mode *mode,
+			     const struct drm_display_mode *adjusted_mode);
+enum drm_mode_status msm_dp_display_mode_valid(struct msm_dp *dp,
+					       const struct drm_display_info *info,
+					       const struct drm_display_mode *mode);
+int msm_dp_display_set_stream_info(struct msm_dp *dp,
+				   struct msm_dp_panel *panel, u32 strm_id,
+				   u32 start_slot, u32 num_slots, u32 pbn, int vcpi);
+void msm_dp_display_enable_helper(struct msm_dp *msm_dp, struct msm_dp_panel *msm_dp_panel);
+void msm_dp_display_disable_helper(struct msm_dp *msm_dp, struct msm_dp_panel *msm_dp_panel);
+void msm_dp_display_mode_set_helper(struct msm_dp *msm_dp,
+				    const struct drm_display_mode *mode,
+				    const struct drm_display_mode *adjusted_mode,
+				    struct msm_dp_panel *msm_dp_panel);
+void msm_dp_display_atomic_post_disable_helper(struct msm_dp *msm_dp,
+					       struct msm_dp_panel *msm_dp_panel);
+
+void msm_dp_display_unprepare(struct msm_dp *dp);
+
+int msm_dp_display_get_active_stream_cnt(struct msm_dp *msm_dp);
+
+struct msm_dp_panel *msm_dp_display_get_panel(struct msm_dp *dp_display);
+
+#endif /* _DP_DISPLAY_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_drm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_drm.c
@@ -0,0 +1,419 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_bridge_connector.h>
+#include <drm/drm_crtc.h>
+
+#include "msm_drv.h"
+#include "msm_kms.h"
+#include "dp_drm.h"
+
+/**
+ * msm_dp_bridge_detect - callback to determine if connector is connected
+ * @bridge: Pointer to drm bridge structure
+ * Returns: Bridge's 'is connected' status
+ */
+static enum drm_connector_status msm_dp_bridge_detect(struct drm_bridge *bridge)
+{
+	struct msm_dp *dp;
+
+	dp = to_dp_bridge(bridge)->msm_dp_display;
+
+	drm_dbg_dp(dp->drm_dev, "link_ready = %s\n",
+		(dp->link_ready) ? "true" : "false");
+
+	return (dp->link_ready && !dp->mst_active) ? connector_status_connected :
+					connector_status_disconnected;
+}
+
+static int msm_dp_bridge_atomic_check(struct drm_bridge *bridge,
+			    struct drm_bridge_state *bridge_state,
+			    struct drm_crtc_state *crtc_state,
+			    struct drm_connector_state *conn_state)
+{
+	struct msm_dp *dp;
+
+	dp = to_dp_bridge(bridge)->msm_dp_display;
+
+	drm_dbg_dp(dp->drm_dev, "link_ready = %s\n",
+		(dp->link_ready) ? "true" : "false");
+
+	/*
+	 * There is no protection in the DRM framework to check if the display
+	 * pipeline has been already disabled before trying to disable it again.
+	 * Hence if the sink is unplugged, the pipeline gets disabled, but the
+	 * crtc->active is still true. Any attempt to set the mode or manually
+	 * disable this encoder will result in the crash.
+	 *
+	 * TODO: add support for telling the DRM subsystem that the pipeline is
+	 * disabled by the hardware and thus all access to it should be forbidden.
+	 * After that this piece of code can be removed.
+	 */
+	if (bridge->ops & DRM_BRIDGE_OP_HPD)
+		return (dp->link_ready) ? 0 : -ENOTCONN;
+
+	return 0;
+}
+
+
+/**
+ * msm_dp_bridge_get_modes - callback to add drm modes via drm_mode_probed_add()
+ * @bridge: Poiner to drm bridge
+ * @connector: Pointer to drm connector structure
+ * Returns: Number of modes added
+ */
+static int msm_dp_bridge_get_modes(struct drm_bridge *bridge, struct drm_connector *connector)
+{
+	int rc = 0;
+	struct msm_dp *dp;
+
+	if (!connector)
+		return 0;
+
+	dp = to_dp_bridge(bridge)->msm_dp_display;
+
+	/* pluggable case assumes EDID is read when HPD */
+	if (dp->link_ready) {
+		rc = msm_dp_display_get_modes(dp);
+		if (rc <= 0) {
+			DRM_ERROR("failed to get DP sink modes, rc=%d\n", rc);
+			return rc;
+		}
+	} else {
+		drm_dbg_dp(connector->dev, "No sink connected\n");
+	}
+	return rc;
+}
+
+static void msm_dp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry *root)
+{
+	struct msm_dp *dp = to_dp_bridge(bridge)->msm_dp_display;
+
+	msm_dp_display_debugfs_init(dp, root, false);
+}
+
+static void msm_dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
+					struct drm_bridge_state *old_bridge_state)
+{
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+	msm_dp_display_atomic_prepare(dp);
+	msm_dp_display_atomic_enable(dp);
+}
+
+static void msm_dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
+					 struct drm_bridge_state *old_bridge_state)
+{
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+	msm_dp_display_atomic_disable(dp);
+}
+
+static void msm_dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
+					      struct drm_bridge_state *old_bridge_state)
+{
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+	msm_dp_display_atomic_post_disable(dp);
+}
+
+static void msm_dp_bridge_mode_set(struct drm_bridge *drm_bridge,
+				   const struct drm_display_mode *mode,
+				   const struct drm_display_mode *adjusted_mode)
+{
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+	msm_dp_display_mode_set(dp, mode, adjusted_mode);
+}
+
+static enum drm_mode_status msm_dp_bridge_mode_valid(struct drm_bridge *drm_bridge,
+						     const struct drm_display_info *info,
+						     const struct drm_display_mode *mode)
+{
+	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = dp_bridge->msm_dp_display;
+
+	return msm_dp_display_mode_valid(dp, info, mode);
+}
+
+static const struct drm_bridge_funcs msm_dp_bridge_ops = {
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state   = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset           = drm_atomic_helper_bridge_reset,
+	.atomic_enable          = msm_dp_bridge_atomic_enable,
+	.atomic_disable         = msm_dp_bridge_atomic_disable,
+	.atomic_post_disable    = msm_dp_bridge_atomic_post_disable,
+	.mode_set     = msm_dp_bridge_mode_set,
+	.mode_valid   = msm_dp_bridge_mode_valid,
+	.get_modes    = msm_dp_bridge_get_modes,
+	.detect       = msm_dp_bridge_detect,
+	.atomic_check = msm_dp_bridge_atomic_check,
+	.hpd_enable   = msm_dp_bridge_hpd_enable,
+	.hpd_disable  = msm_dp_bridge_hpd_disable,
+	.hpd_notify   = msm_dp_bridge_hpd_notify,
+	.debugfs_init = msm_dp_bridge_debugfs_init,
+};
+
+static int msm_edp_bridge_atomic_check(struct drm_bridge *drm_bridge,
+				   struct drm_bridge_state *bridge_state,
+				   struct drm_crtc_state *crtc_state,
+				   struct drm_connector_state *conn_state)
+{
+	struct msm_dp *dp = to_dp_bridge(drm_bridge)->msm_dp_display;
+
+	if (WARN_ON(!conn_state))
+		return -ENODEV;
+
+	conn_state->self_refresh_aware = dp->psr_supported;
+
+	if (!conn_state->crtc || !crtc_state)
+		return 0;
+
+	if (crtc_state->self_refresh_active && !dp->psr_supported)
+		return -EINVAL;
+
+	return 0;
+}
+
+static void msm_edp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
+				     struct drm_bridge_state *old_bridge_state)
+{
+	struct drm_atomic_state *atomic_state = old_bridge_state->base.state;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *old_crtc_state;
+	struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
+
+	/*
+	 * Check the old state of the crtc to determine if the panel
+	 * was put into psr state previously by the msm_edp_bridge_atomic_disable.
+	 * If the panel is in psr, just exit psr state and skip the full
+	 * bridge enable sequence.
+	 */
+	crtc = drm_atomic_get_new_crtc_for_encoder(atomic_state,
+						   drm_bridge->encoder);
+	if (!crtc)
+		return;
+
+	old_crtc_state = drm_atomic_get_old_crtc_state(atomic_state, crtc);
+
+	if (old_crtc_state && old_crtc_state->self_refresh_active) {
+		msm_dp_display_set_psr(dp, false);
+		return;
+	}
+
+	msm_dp_display_atomic_prepare(dp);
+	msm_dp_display_atomic_enable(dp);
+}
+
+static void msm_edp_bridge_atomic_disable(struct drm_bridge *drm_bridge,
+				      struct drm_bridge_state *old_bridge_state)
+{
+	struct drm_atomic_state *atomic_state = old_bridge_state->base.state;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *new_crtc_state = NULL, *old_crtc_state = NULL;
+	struct msm_dp_bridge *msm_dp_bridge = to_dp_bridge(drm_bridge);
+	struct msm_dp *dp = msm_dp_bridge->msm_dp_display;
+
+	crtc = drm_atomic_get_old_crtc_for_encoder(atomic_state,
+						   drm_bridge->encoder);
+	if (!crtc)
+		goto out;
+
+	new_crtc_state = drm_atomic_get_new_crtc_state(atomic_state, crtc);
+	if (!new_crtc_state)
+		goto out;
+
+	old_crtc_state = drm_atomic_get_old_crtc_state(atomic_state, crtc);
+	if (!old_crtc_state)
+		goto out;
+
+	/*
+	 * Set self refresh mode if current crtc state is active.
+	 *
+	 * If old crtc state is active, then this is a display disable
+	 * call while the sink is in psr state. So, exit psr here.
+	 * The eDP controller will be disabled in the
+	 * msm_edp_bridge_atomic_post_disable function.
+	 *
+	 * We observed sink is stuck in self refresh if psr exit is skipped
+	 * when display disable occurs while the sink is in psr state.
+	 */
+	if (new_crtc_state->self_refresh_active) {
+		msm_dp_display_set_psr(dp, true);
+		return;
+	} else if (old_crtc_state->self_refresh_active) {
+		msm_dp_display_set_psr(dp, false);
+		return;
+	}
+
+out:
+	msm_dp_bridge_atomic_disable(drm_bridge, old_bridge_state);
+}
+
+static void msm_edp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
+				struct drm_bridge_state *old_bridge_state)
+{
+	struct drm_atomic_state *atomic_state = old_bridge_state->base.state;
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *new_crtc_state = NULL;
+
+	crtc = drm_atomic_get_old_crtc_for_encoder(atomic_state,
+						   drm_bridge->encoder);
+	if (!crtc)
+		return;
+
+	new_crtc_state = drm_atomic_get_new_crtc_state(atomic_state, crtc);
+	if (!new_crtc_state)
+		return;
+
+	/*
+	 * Self refresh mode is already set in msm_edp_bridge_atomic_disable.
+	 */
+	if (new_crtc_state->self_refresh_active)
+		return;
+
+	msm_dp_bridge_atomic_post_disable(drm_bridge, old_bridge_state);
+}
+
+/**
+ * msm_edp_bridge_mode_valid - callback to determine if specified mode is valid
+ * @bridge: Pointer to drm bridge structure
+ * @info: display info
+ * @mode: Pointer to drm mode structure
+ * Returns: Validity status for specified mode
+ */
+static enum drm_mode_status msm_edp_bridge_mode_valid(struct drm_bridge *bridge,
+					  const struct drm_display_info *info,
+					  const struct drm_display_mode *mode)
+{
+	struct msm_dp *dp;
+	int mode_pclk_khz = mode->clock;
+
+	dp = to_dp_bridge(bridge)->msm_dp_display;
+
+	if (!dp || !mode_pclk_khz || !dp->connector) {
+		DRM_ERROR("invalid params\n");
+		return -EINVAL;
+	}
+
+	if (mode->clock > DP_MAX_PIXEL_CLK_KHZ)
+		return MODE_CLOCK_HIGH;
+
+	/*
+	 * The eDP controller currently does not have a reliable way of
+	 * enabling panel power to read sink capabilities. So, we rely
+	 * on the panel driver to populate only supported modes for now.
+	 */
+	return MODE_OK;
+}
+
+static void msm_edp_bridge_debugfs_init(struct drm_bridge *bridge, struct dentry *root)
+{
+	struct msm_dp *dp = to_dp_bridge(bridge)->msm_dp_display;
+
+	msm_dp_display_debugfs_init(dp, root, true);
+}
+
+static const struct drm_bridge_funcs msm_edp_bridge_ops = {
+	.atomic_enable = msm_edp_bridge_atomic_enable,
+	.atomic_disable = msm_edp_bridge_atomic_disable,
+	.atomic_post_disable = msm_edp_bridge_atomic_post_disable,
+	.mode_set = msm_dp_bridge_mode_set,
+	.mode_valid = msm_edp_bridge_mode_valid,
+	.atomic_reset = drm_atomic_helper_bridge_reset,
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+	.atomic_check = msm_edp_bridge_atomic_check,
+	.debugfs_init = msm_edp_bridge_debugfs_init,
+};
+
+int msm_dp_bridge_init(struct msm_dp *msm_dp_display, struct drm_device *dev,
+		   struct drm_encoder *encoder, bool yuv_supported)
+{
+	int rc;
+	struct msm_dp_bridge *msm_dp_bridge;
+	struct drm_bridge *bridge;
+
+	msm_dp_bridge = devm_kzalloc(dev->dev, sizeof(*msm_dp_bridge), GFP_KERNEL);
+	if (!msm_dp_bridge)
+		return -ENOMEM;
+
+	msm_dp_bridge->msm_dp_display = msm_dp_display;
+
+	bridge = &msm_dp_bridge->bridge;
+	bridge->funcs = msm_dp_display->is_edp ? &msm_edp_bridge_ops : &msm_dp_bridge_ops;
+	bridge->type = msm_dp_display->connector_type;
+	bridge->ycbcr_420_allowed = yuv_supported;
+
+	/*
+	 * Many ops only make sense for DP. Why?
+	 * - Detect/HPD are used by DRM to know if a display is _physically_
+	 *   there, not whether the display is powered on / finished initting.
+	 *   On eDP we assume the display is always there because you can't
+	 *   know until power is applied. If we don't implement the ops DRM will
+	 *   assume our display is always there.
+	 * - Currently eDP mode reading is driven by the panel driver. This
+	 *   allows the panel driver to properly power itself on to read the
+	 *   modes.
+	 */
+	if (!msm_dp_display->is_edp) {
+		bridge->ops =
+			DRM_BRIDGE_OP_DETECT |
+			DRM_BRIDGE_OP_HPD |
+			DRM_BRIDGE_OP_MODES;
+	}
+
+	rc = devm_drm_bridge_add(dev->dev, bridge);
+	if (rc) {
+		DRM_ERROR("failed to add bridge, rc=%d\n", rc);
+
+		return rc;
+	}
+
+	rc = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+	if (rc) {
+		DRM_ERROR("failed to attach bridge, rc=%d\n", rc);
+
+		return rc;
+	}
+
+	if (msm_dp_display->next_bridge) {
+		rc = drm_bridge_attach(encoder,
+					msm_dp_display->next_bridge, bridge,
+					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+		if (rc < 0) {
+			DRM_ERROR("failed to attach panel bridge: %d\n", rc);
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
+/* connector initialization */
+struct drm_connector *msm_dp_drm_connector_init(struct msm_dp *msm_dp_display,
+					    struct drm_encoder *encoder)
+{
+	struct drm_connector *connector = NULL;
+
+	connector = drm_bridge_connector_init(msm_dp_display->drm_dev, encoder);
+	if (IS_ERR(connector))
+		return connector;
+
+	if (!msm_dp_display->is_edp)
+		drm_connector_attach_dp_subconnector_property(connector);
+
+	drm_connector_attach_encoder(connector, encoder);
+
+	return connector;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_drm.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_drm.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DP_DRM_H_
+#define _DP_DRM_H_
+
+#include <linux/types.h>
+#include <drm/drm_bridge.h>
+
+#include "msm_drv.h"
+#include "dp_display.h"
+
+struct msm_dp_bridge {
+	struct drm_bridge bridge;
+	struct msm_dp *msm_dp_display;
+};
+
+#define to_dp_bridge(x)     container_of((x), struct msm_dp_bridge, bridge)
+
+struct drm_connector *msm_dp_drm_connector_init(struct msm_dp *msm_dp_display,
+					    struct drm_encoder *encoder);
+int msm_dp_bridge_init(struct msm_dp *msm_dp_display, struct drm_device *dev,
+		   struct drm_encoder *encoder,
+		   bool yuv_supported);
+
+void msm_dp_bridge_hpd_enable(struct drm_bridge *bridge);
+void msm_dp_bridge_hpd_disable(struct drm_bridge *bridge);
+void msm_dp_bridge_hpd_notify(struct drm_bridge *bridge,
+			  enum drm_connector_status status);
+
+#endif /* _DP_DRM_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_link.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_link.c
@@ -0,0 +1,1232 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ */
+
+#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
+
+#include <drm/drm_print.h>
+
+#include "dp_reg.h"
+#include "dp_link.h"
+#include "dp_panel.h"
+
+#define DP_TEST_REQUEST_MASK		0x7F
+
+enum audio_sample_rate {
+	AUDIO_SAMPLE_RATE_32_KHZ	= 0x00,
+	AUDIO_SAMPLE_RATE_44_1_KHZ	= 0x01,
+	AUDIO_SAMPLE_RATE_48_KHZ	= 0x02,
+	AUDIO_SAMPLE_RATE_88_2_KHZ	= 0x03,
+	AUDIO_SAMPLE_RATE_96_KHZ	= 0x04,
+	AUDIO_SAMPLE_RATE_176_4_KHZ	= 0x05,
+	AUDIO_SAMPLE_RATE_192_KHZ	= 0x06,
+};
+
+enum audio_pattern_type {
+	AUDIO_TEST_PATTERN_OPERATOR_DEFINED	= 0x00,
+	AUDIO_TEST_PATTERN_SAWTOOTH		= 0x01,
+};
+
+struct msm_dp_link_request {
+	u32 test_requested;
+	u32 test_link_rate;
+	u32 test_lane_count;
+};
+
+struct msm_dp_link_private {
+	u32 prev_sink_count;
+	struct drm_device *drm_dev;
+	struct drm_dp_aux *aux;
+	struct msm_dp_link msm_dp_link;
+
+	struct msm_dp_link_request request;
+	struct mutex psm_mutex;
+	u8 link_status[DP_LINK_STATUS_SIZE];
+};
+
+static int msm_dp_aux_link_power_up(struct drm_dp_aux *aux,
+					struct msm_dp_link_info *link)
+{
+	u8 value;
+	ssize_t len;
+	int i;
+
+	if (link->revision < 0x11)
+		return 0;
+
+	len = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
+	if (len < 0)
+		return len;
+
+	value &= ~DP_SET_POWER_MASK;
+	value |= DP_SET_POWER_D0;
+
+	/* retry for 1ms to give the sink time to wake up */
+	for (i = 0; i < 3; i++) {
+		len = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
+		usleep_range(1000, 2000);
+		if (len == 1)
+			break;
+	}
+
+	return 0;
+}
+
+static int msm_dp_aux_link_power_down(struct drm_dp_aux *aux,
+					struct msm_dp_link_info *link)
+{
+	u8 value;
+	int err;
+
+	if (link->revision < 0x11)
+		return 0;
+
+	err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
+	if (err < 0)
+		return err;
+
+	value &= ~DP_SET_POWER_MASK;
+	value |= DP_SET_POWER_D3;
+
+	err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+static int msm_dp_link_get_period(struct msm_dp_link_private *link, int const addr)
+{
+	int ret = 0;
+	u8 data;
+	u32 const max_audio_period = 0xA;
+
+	/* TEST_AUDIO_PERIOD_CH_XX */
+	if (drm_dp_dpcd_readb(link->aux, addr, &data) < 0) {
+		DRM_ERROR("failed to read test_audio_period (0x%x)\n", addr);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Period - Bits 3:0 */
+	data = data & 0xF;
+	if ((int)data > max_audio_period) {
+		DRM_ERROR("invalid test_audio_period_ch_1 = 0x%x\n", data);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	ret = data;
+exit:
+	return ret;
+}
+
+static int msm_dp_link_parse_audio_channel_period(struct msm_dp_link_private *link)
+{
+	int ret = 0;
+	struct msm_dp_link_test_audio *req = &link->msm_dp_link.test_audio;
+
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH1);
+	if (ret == -EINVAL)
+		goto exit;
+
+	req->test_audio_period_ch_1 = ret;
+	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_1 = 0x%x\n", ret);
+
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH2);
+	if (ret == -EINVAL)
+		goto exit;
+
+	req->test_audio_period_ch_2 = ret;
+	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_2 = 0x%x\n", ret);
+
+	/* TEST_AUDIO_PERIOD_CH_3 (Byte 0x275) */
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH3);
+	if (ret == -EINVAL)
+		goto exit;
+
+	req->test_audio_period_ch_3 = ret;
+	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_3 = 0x%x\n", ret);
+
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH4);
+	if (ret == -EINVAL)
+		goto exit;
+
+	req->test_audio_period_ch_4 = ret;
+	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_4 = 0x%x\n", ret);
+
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH5);
+	if (ret == -EINVAL)
+		goto exit;
+
+	req->test_audio_period_ch_5 = ret;
+	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_5 = 0x%x\n", ret);
+
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH6);
+	if (ret == -EINVAL)
+		goto exit;
+
+	req->test_audio_period_ch_6 = ret;
+	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_6 = 0x%x\n", ret);
+
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH7);
+	if (ret == -EINVAL)
+		goto exit;
+
+	req->test_audio_period_ch_7 = ret;
+	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_7 = 0x%x\n", ret);
+
+	ret = msm_dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH8);
+	if (ret == -EINVAL)
+		goto exit;
+
+	req->test_audio_period_ch_8 = ret;
+	drm_dbg_dp(link->drm_dev, "test_audio_period_ch_8 = 0x%x\n", ret);
+exit:
+	return ret;
+}
+
+static int msm_dp_link_parse_audio_pattern_type(struct msm_dp_link_private *link)
+{
+	int ret = 0;
+	u8 data;
+	ssize_t rlen;
+	int const max_audio_pattern_type = 0x1;
+
+	rlen = drm_dp_dpcd_readb(link->aux,
+				DP_TEST_AUDIO_PATTERN_TYPE, &data);
+	if (rlen < 0) {
+		DRM_ERROR("failed to read link audio mode. rlen=%zd\n", rlen);
+		return rlen;
+	}
+
+	/* Audio Pattern Type - Bits 7:0 */
+	if ((int)data > max_audio_pattern_type) {
+		DRM_ERROR("invalid audio pattern type = 0x%x\n", data);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	link->msm_dp_link.test_audio.test_audio_pattern_type = data;
+	drm_dbg_dp(link->drm_dev, "audio pattern type = 0x%x\n", data);
+exit:
+	return ret;
+}
+
+static int msm_dp_link_parse_audio_mode(struct msm_dp_link_private *link)
+{
+	int ret = 0;
+	u8 data;
+	ssize_t rlen;
+	int const max_audio_sampling_rate = 0x6;
+	int const max_audio_channel_count = 0x8;
+	int sampling_rate = 0x0;
+	int channel_count = 0x0;
+
+	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_AUDIO_MODE, &data);
+	if (rlen < 0) {
+		DRM_ERROR("failed to read link audio mode. rlen=%zd\n", rlen);
+		return rlen;
+	}
+
+	/* Sampling Rate - Bits 3:0 */
+	sampling_rate = data & 0xF;
+	if (sampling_rate > max_audio_sampling_rate) {
+		DRM_ERROR("sampling rate (0x%x) greater than max (0x%x)\n",
+				sampling_rate, max_audio_sampling_rate);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	/* Channel Count - Bits 7:4 */
+	channel_count = ((data & 0xF0) >> 4) + 1;
+	if (channel_count > max_audio_channel_count) {
+		DRM_ERROR("channel_count (0x%x) greater than max (0x%x)\n",
+				channel_count, max_audio_channel_count);
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	link->msm_dp_link.test_audio.test_audio_sampling_rate = sampling_rate;
+	link->msm_dp_link.test_audio.test_audio_channel_count = channel_count;
+	drm_dbg_dp(link->drm_dev,
+			"sampling_rate = 0x%x, channel_count = 0x%x\n",
+			sampling_rate, channel_count);
+exit:
+	return ret;
+}
+
+static int msm_dp_link_parse_audio_pattern_params(struct msm_dp_link_private *link)
+{
+	int ret = 0;
+
+	ret = msm_dp_link_parse_audio_mode(link);
+	if (ret)
+		goto exit;
+
+	ret = msm_dp_link_parse_audio_pattern_type(link);
+	if (ret)
+		goto exit;
+
+	ret = msm_dp_link_parse_audio_channel_period(link);
+
+exit:
+	return ret;
+}
+
+static bool msm_dp_link_is_video_pattern_valid(u32 pattern)
+{
+	switch (pattern) {
+	case DP_NO_TEST_PATTERN:
+	case DP_COLOR_RAMP:
+	case DP_BLACK_AND_WHITE_VERTICAL_LINES:
+	case DP_COLOR_SQUARE:
+		return true;
+	default:
+		return false;
+	}
+}
+
+/**
+ * msm_dp_link_is_bit_depth_valid() - validates the bit depth requested
+ * @tbd: bit depth requested by the sink
+ *
+ * Returns true if the requested bit depth is supported.
+ */
+static bool msm_dp_link_is_bit_depth_valid(u32 tbd)
+{
+	/* DP_TEST_VIDEO_PATTERN_NONE is treated as invalid */
+	switch (tbd) {
+	case DP_TEST_BIT_DEPTH_6:
+	case DP_TEST_BIT_DEPTH_8:
+	case DP_TEST_BIT_DEPTH_10:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static int msm_dp_link_parse_timing_params1(struct msm_dp_link_private *link,
+					int addr, int len, u32 *val)
+{
+	u8 bp[2];
+	int rlen;
+
+	if (len != 2)
+		return -EINVAL;
+
+	/* Read the requested video link pattern (Byte 0x221). */
+	rlen = drm_dp_dpcd_read(link->aux, addr, bp, len);
+	if (rlen < len) {
+		DRM_ERROR("failed to read 0x%x\n", addr);
+		return -EINVAL;
+	}
+
+	*val = bp[1] | (bp[0] << 8);
+
+	return 0;
+}
+
+static int msm_dp_link_parse_timing_params2(struct msm_dp_link_private *link,
+					int addr, int len,
+					u32 *val1, u32 *val2)
+{
+	u8 bp[2];
+	int rlen;
+
+	if (len != 2)
+		return -EINVAL;
+
+	/* Read the requested video link pattern (Byte 0x221). */
+	rlen = drm_dp_dpcd_read(link->aux, addr, bp, len);
+	if (rlen < len) {
+		DRM_ERROR("failed to read 0x%x\n", addr);
+		return -EINVAL;
+	}
+
+	*val1 = (bp[0] & BIT(7)) >> 7;
+	*val2 = bp[1] | ((bp[0] & 0x7F) << 8);
+
+	return 0;
+}
+
+static int msm_dp_link_parse_timing_params3(struct msm_dp_link_private *link,
+					int addr, u32 *val)
+{
+	u8 bp;
+	u32 len = 1;
+	int rlen;
+
+	rlen = drm_dp_dpcd_read(link->aux, addr, &bp, len);
+	if (rlen < 1) {
+		DRM_ERROR("failed to read 0x%x\n", addr);
+		return -EINVAL;
+	}
+	*val = bp;
+
+	return 0;
+}
+
+/**
+ * msm_dp_link_parse_video_pattern_params() - parses video pattern parameters from DPCD
+ * @link: Display Port Driver data
+ *
+ * Returns 0 if it successfully parses the video link pattern and the link
+ * bit depth requested by the sink and, and if the values parsed are valid.
+ */
+static int msm_dp_link_parse_video_pattern_params(struct msm_dp_link_private *link)
+{
+	int ret = 0;
+	ssize_t rlen;
+	u8 bp;
+
+	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_PATTERN, &bp);
+	if (rlen < 0) {
+		DRM_ERROR("failed to read link video pattern. rlen=%zd\n",
+			rlen);
+		return rlen;
+	}
+
+	if (!msm_dp_link_is_video_pattern_valid(bp)) {
+		DRM_ERROR("invalid link video pattern = 0x%x\n", bp);
+		ret = -EINVAL;
+		return ret;
+	}
+
+	link->msm_dp_link.test_video.test_video_pattern = bp;
+
+	/* Read the requested color bit depth and dynamic range (Byte 0x232) */
+	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_MISC0, &bp);
+	if (rlen < 0) {
+		DRM_ERROR("failed to read link bit depth. rlen=%zd\n", rlen);
+		return rlen;
+	}
+
+	/* Dynamic Range */
+	link->msm_dp_link.test_video.test_dyn_range =
+			(bp & DP_TEST_DYNAMIC_RANGE_CEA);
+
+	/* Color bit depth */
+	bp &= DP_TEST_BIT_DEPTH_MASK;
+	if (!msm_dp_link_is_bit_depth_valid(bp)) {
+		DRM_ERROR("invalid link bit depth = 0x%x\n", bp);
+		ret = -EINVAL;
+		return ret;
+	}
+
+	link->msm_dp_link.test_video.test_bit_depth = bp;
+
+	/* resolution timing params */
+	ret = msm_dp_link_parse_timing_params1(link, DP_TEST_H_TOTAL_HI, 2,
+			&link->msm_dp_link.test_video.test_h_total);
+	if (ret) {
+		DRM_ERROR("failed to parse test_htotal(DP_TEST_H_TOTAL_HI)\n");
+		return ret;
+	}
+
+	ret = msm_dp_link_parse_timing_params1(link, DP_TEST_V_TOTAL_HI, 2,
+			&link->msm_dp_link.test_video.test_v_total);
+	if (ret) {
+		DRM_ERROR("failed to parse test_v_total(DP_TEST_V_TOTAL_HI)\n");
+		return ret;
+	}
+
+	ret = msm_dp_link_parse_timing_params1(link, DP_TEST_H_START_HI, 2,
+			&link->msm_dp_link.test_video.test_h_start);
+	if (ret) {
+		DRM_ERROR("failed to parse test_h_start(DP_TEST_H_START_HI)\n");
+		return ret;
+	}
+
+	ret = msm_dp_link_parse_timing_params1(link, DP_TEST_V_START_HI, 2,
+			&link->msm_dp_link.test_video.test_v_start);
+	if (ret) {
+		DRM_ERROR("failed to parse test_v_start(DP_TEST_V_START_HI)\n");
+		return ret;
+	}
+
+	ret = msm_dp_link_parse_timing_params2(link, DP_TEST_HSYNC_HI, 2,
+			&link->msm_dp_link.test_video.test_hsync_pol,
+			&link->msm_dp_link.test_video.test_hsync_width);
+	if (ret) {
+		DRM_ERROR("failed to parse (DP_TEST_HSYNC_HI)\n");
+		return ret;
+	}
+
+	ret = msm_dp_link_parse_timing_params2(link, DP_TEST_VSYNC_HI, 2,
+			&link->msm_dp_link.test_video.test_vsync_pol,
+			&link->msm_dp_link.test_video.test_vsync_width);
+	if (ret) {
+		DRM_ERROR("failed to parse (DP_TEST_VSYNC_HI)\n");
+		return ret;
+	}
+
+	ret = msm_dp_link_parse_timing_params1(link, DP_TEST_H_WIDTH_HI, 2,
+			&link->msm_dp_link.test_video.test_h_width);
+	if (ret) {
+		DRM_ERROR("failed to parse test_h_width(DP_TEST_H_WIDTH_HI)\n");
+		return ret;
+	}
+
+	ret = msm_dp_link_parse_timing_params1(link, DP_TEST_V_HEIGHT_HI, 2,
+			&link->msm_dp_link.test_video.test_v_height);
+	if (ret) {
+		DRM_ERROR("failed to parse test_v_height\n");
+		return ret;
+	}
+
+	ret = msm_dp_link_parse_timing_params3(link, DP_TEST_MISC1,
+		&link->msm_dp_link.test_video.test_rr_d);
+	link->msm_dp_link.test_video.test_rr_d &= DP_TEST_REFRESH_DENOMINATOR;
+	if (ret) {
+		DRM_ERROR("failed to parse test_rr_d (DP_TEST_MISC1)\n");
+		return ret;
+	}
+
+	ret = msm_dp_link_parse_timing_params3(link, DP_TEST_REFRESH_RATE_NUMERATOR,
+		&link->msm_dp_link.test_video.test_rr_n);
+	if (ret) {
+		DRM_ERROR("failed to parse test_rr_n\n");
+		return ret;
+	}
+
+	drm_dbg_dp(link->drm_dev,
+		"link video pattern = 0x%x\n"
+		"link dynamic range = 0x%x\n"
+		"link bit depth = 0x%x\n"
+		"TEST_H_TOTAL = %d, TEST_V_TOTAL = %d\n"
+		"TEST_H_START = %d, TEST_V_START = %d\n"
+		"TEST_HSYNC_POL = %d\n"
+		"TEST_HSYNC_WIDTH = %d\n"
+		"TEST_VSYNC_POL = %d\n"
+		"TEST_VSYNC_WIDTH = %d\n"
+		"TEST_H_WIDTH = %d\n"
+		"TEST_V_HEIGHT = %d\n"
+		"TEST_REFRESH_DENOMINATOR = %d\n"
+		 "TEST_REFRESH_NUMERATOR = %d\n",
+		link->msm_dp_link.test_video.test_video_pattern,
+		link->msm_dp_link.test_video.test_dyn_range,
+		link->msm_dp_link.test_video.test_bit_depth,
+		link->msm_dp_link.test_video.test_h_total,
+		link->msm_dp_link.test_video.test_v_total,
+		link->msm_dp_link.test_video.test_h_start,
+		link->msm_dp_link.test_video.test_v_start,
+		link->msm_dp_link.test_video.test_hsync_pol,
+		link->msm_dp_link.test_video.test_hsync_width,
+		link->msm_dp_link.test_video.test_vsync_pol,
+		link->msm_dp_link.test_video.test_vsync_width,
+		link->msm_dp_link.test_video.test_h_width,
+		link->msm_dp_link.test_video.test_v_height,
+		link->msm_dp_link.test_video.test_rr_d,
+		link->msm_dp_link.test_video.test_rr_n);
+
+	return ret;
+}
+
+/**
+ * msm_dp_link_parse_link_training_params() - parses link training parameters from
+ * DPCD
+ * @link: Display Port Driver data
+ *
+ * Returns 0 if it successfully parses the link rate (Byte 0x219) and lane
+ * count (Byte 0x220), and if these values parse are valid.
+ */
+static int msm_dp_link_parse_link_training_params(struct msm_dp_link_private *link)
+{
+	u8 bp;
+	ssize_t rlen;
+
+	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_LINK_RATE,	&bp);
+	if (rlen < 0) {
+		DRM_ERROR("failed to read link rate. rlen=%zd\n", rlen);
+		return rlen;
+	}
+
+	if (!is_link_rate_valid(bp)) {
+		DRM_ERROR("invalid link rate = 0x%x\n", bp);
+		return -EINVAL;
+	}
+
+	link->request.test_link_rate = bp;
+	drm_dbg_dp(link->drm_dev, "link rate = 0x%x\n",
+				link->request.test_link_rate);
+
+	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_LANE_COUNT, &bp);
+	if (rlen < 0) {
+		DRM_ERROR("failed to read lane count. rlen=%zd\n", rlen);
+		return rlen;
+	}
+	bp &= DP_MAX_LANE_COUNT_MASK;
+
+	if (!is_lane_count_valid(bp)) {
+		DRM_ERROR("invalid lane count = 0x%x\n", bp);
+		return -EINVAL;
+	}
+
+	link->request.test_lane_count = bp;
+	drm_dbg_dp(link->drm_dev, "lane count = 0x%x\n",
+				link->request.test_lane_count);
+	return 0;
+}
+
+/**
+ * msm_dp_link_parse_phy_test_params() - parses the phy link parameters
+ * @link: Display Port Driver data
+ *
+ * Parses the DPCD (Byte 0x248) for the DP PHY link pattern that is being
+ * requested.
+ */
+static int msm_dp_link_parse_phy_test_params(struct msm_dp_link_private *link)
+{
+	u8 data;
+	ssize_t rlen;
+
+	rlen = drm_dp_dpcd_readb(link->aux, DP_PHY_TEST_PATTERN,
+					&data);
+	if (rlen < 0) {
+		DRM_ERROR("failed to read phy link pattern. rlen=%zd\n", rlen);
+		return rlen;
+	}
+
+	link->msm_dp_link.phy_params.phy_test_pattern_sel = data & 0x07;
+
+	drm_dbg_dp(link->drm_dev, "phy_test_pattern_sel = 0x%x\n", data);
+
+	switch (data) {
+	case DP_PHY_TEST_PATTERN_SEL_MASK:
+	case DP_PHY_TEST_PATTERN_NONE:
+	case DP_PHY_TEST_PATTERN_D10_2:
+	case DP_PHY_TEST_PATTERN_ERROR_COUNT:
+	case DP_PHY_TEST_PATTERN_PRBS7:
+	case DP_PHY_TEST_PATTERN_80BIT_CUSTOM:
+	case DP_PHY_TEST_PATTERN_CP2520:
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+/**
+ * msm_dp_link_is_video_audio_test_requested() - checks for audio/video link request
+ * @link: link requested by the sink
+ *
+ * Returns true if the requested link is a permitted audio/video link.
+ */
+static bool msm_dp_link_is_video_audio_test_requested(u32 link)
+{
+	u8 video_audio_test = (DP_TEST_LINK_VIDEO_PATTERN |
+				DP_TEST_LINK_AUDIO_PATTERN |
+				DP_TEST_LINK_AUDIO_DISABLED_VIDEO);
+
+	return ((link & video_audio_test) &&
+		!(link & ~video_audio_test));
+}
+
+/**
+ * msm_dp_link_parse_request() - parses link request parameters from sink
+ * @link: Display Port Driver data
+ *
+ * Parses the DPCD to check if an automated link is requested (Byte 0x201),
+ * and what type of link automation is being requested (Byte 0x218).
+ */
+static int msm_dp_link_parse_request(struct msm_dp_link_private *link)
+{
+	int ret = 0;
+	u8 data;
+	ssize_t rlen;
+
+	/**
+	 * Read the device service IRQ vector (Byte 0x201) to determine
+	 * whether an automated link has been requested by the sink.
+	 */
+	rlen = drm_dp_dpcd_readb(link->aux,
+				DP_DEVICE_SERVICE_IRQ_VECTOR, &data);
+	if (rlen < 0) {
+		DRM_ERROR("aux read failed. rlen=%zd\n", rlen);
+		return rlen;
+	}
+
+	drm_dbg_dp(link->drm_dev, "device service irq vector = 0x%x\n", data);
+
+	if (!(data & DP_AUTOMATED_TEST_REQUEST)) {
+		drm_dbg_dp(link->drm_dev, "no test requested\n");
+		return 0;
+	}
+
+	/**
+	 * Read the link request byte (Byte 0x218) to determine what type
+	 * of automated link has been requested by the sink.
+	 */
+	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_REQUEST, &data);
+	if (rlen < 0) {
+		DRM_ERROR("aux read failed. rlen=%zd\n", rlen);
+		return rlen;
+	}
+
+	if (!data || (data == DP_TEST_LINK_FAUX_PATTERN)) {
+		drm_dbg_dp(link->drm_dev, "link 0x%x not supported\n", data);
+		goto end;
+	}
+
+	drm_dbg_dp(link->drm_dev, "Test:(0x%x) requested\n", data);
+	link->request.test_requested = data;
+	if (link->request.test_requested == DP_TEST_LINK_PHY_TEST_PATTERN) {
+		ret = msm_dp_link_parse_phy_test_params(link);
+		if (ret)
+			goto end;
+		ret = msm_dp_link_parse_link_training_params(link);
+		if (ret)
+			goto end;
+	}
+
+	if (link->request.test_requested == DP_TEST_LINK_TRAINING) {
+		ret = msm_dp_link_parse_link_training_params(link);
+		if (ret)
+			goto end;
+	}
+
+	if (msm_dp_link_is_video_audio_test_requested(
+			link->request.test_requested)) {
+		ret = msm_dp_link_parse_video_pattern_params(link);
+		if (ret)
+			goto end;
+
+		ret = msm_dp_link_parse_audio_pattern_params(link);
+	}
+end:
+	/*
+	 * Send a DP_TEST_ACK if all link parameters are valid, otherwise send
+	 * a DP_TEST_NAK.
+	 */
+	if (ret) {
+		link->msm_dp_link.test_response = DP_TEST_NAK;
+	} else {
+		if (link->request.test_requested != DP_TEST_LINK_EDID_READ)
+			link->msm_dp_link.test_response = DP_TEST_ACK;
+		else
+			link->msm_dp_link.test_response =
+				DP_TEST_EDID_CHECKSUM_WRITE;
+	}
+
+	return ret;
+}
+
+static int msm_dp_link_parse_sink_status_field(struct msm_dp_link_private *link)
+{
+	int len;
+
+	link->prev_sink_count = link->msm_dp_link.sink_count;
+	len = drm_dp_read_sink_count(link->aux);
+	if (len < 0) {
+		DRM_ERROR("DP parse sink count failed\n");
+		return len;
+	}
+	link->msm_dp_link.sink_count = len;
+
+	len = drm_dp_dpcd_read_link_status(link->aux,
+		link->link_status);
+	if (len < DP_LINK_STATUS_SIZE) {
+		DRM_ERROR("DP link status read failed\n");
+		return len;
+	}
+
+	return msm_dp_link_parse_request(link);
+}
+
+/**
+ * msm_dp_link_process_link_training_request() - processes new training requests
+ * @link: Display Port link data
+ *
+ * This function will handle new link training requests that are initiated by
+ * the sink. In particular, it will update the requested lane count and link
+ * rate, and then trigger the link retraining procedure.
+ *
+ * The function will return 0 if a link training request has been processed,
+ * otherwise it will return -EINVAL.
+ */
+static int msm_dp_link_process_link_training_request(struct msm_dp_link_private *link)
+{
+	if (link->request.test_requested != DP_TEST_LINK_TRAINING)
+		return -EINVAL;
+
+	drm_dbg_dp(link->drm_dev,
+			"Test:0x%x link rate = 0x%x, lane count = 0x%x\n",
+			DP_TEST_LINK_TRAINING,
+			link->request.test_link_rate,
+			link->request.test_lane_count);
+
+	link->msm_dp_link.link_params.num_lanes = link->request.test_lane_count;
+	link->msm_dp_link.link_params.rate =
+		drm_dp_bw_code_to_link_rate(link->request.test_link_rate);
+
+	return 0;
+}
+
+bool msm_dp_link_send_test_response(struct msm_dp_link *msm_dp_link)
+{
+	struct msm_dp_link_private *link = NULL;
+	int ret = 0;
+
+	if (!msm_dp_link) {
+		DRM_ERROR("invalid input\n");
+		return false;
+	}
+
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
+
+	ret = drm_dp_dpcd_writeb(link->aux, DP_TEST_RESPONSE,
+			msm_dp_link->test_response);
+
+	return ret == 1;
+}
+
+int msm_dp_link_psm_config(struct msm_dp_link *msm_dp_link,
+			      struct msm_dp_link_info *link_info, bool enable)
+{
+	struct msm_dp_link_private *link = NULL;
+	int ret = 0;
+
+	if (!msm_dp_link) {
+		DRM_ERROR("invalid params\n");
+		return -EINVAL;
+	}
+
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
+
+	mutex_lock(&link->psm_mutex);
+	if (enable)
+		ret = msm_dp_aux_link_power_down(link->aux, link_info);
+	else
+		ret = msm_dp_aux_link_power_up(link->aux, link_info);
+
+	if (ret)
+		DRM_ERROR("Failed to %s low power mode\n", enable ?
+							"enter" : "exit");
+
+	mutex_unlock(&link->psm_mutex);
+	return ret;
+}
+
+bool msm_dp_link_send_edid_checksum(struct msm_dp_link *msm_dp_link, u8 checksum)
+{
+	struct msm_dp_link_private *link = NULL;
+	int ret = 0;
+
+	if (!msm_dp_link) {
+		DRM_ERROR("invalid input\n");
+		return false;
+	}
+
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
+
+	ret = drm_dp_dpcd_writeb(link->aux, DP_TEST_EDID_CHECKSUM,
+						checksum);
+	return ret == 1;
+}
+
+static void msm_dp_link_parse_vx_px(struct msm_dp_link_private *link)
+{
+	drm_dbg_dp(link->drm_dev, "vx: 0=%d, 1=%d, 2=%d, 3=%d\n",
+		drm_dp_get_adjust_request_voltage(link->link_status, 0),
+		drm_dp_get_adjust_request_voltage(link->link_status, 1),
+		drm_dp_get_adjust_request_voltage(link->link_status, 2),
+		drm_dp_get_adjust_request_voltage(link->link_status, 3));
+
+	drm_dbg_dp(link->drm_dev, "px: 0=%d, 1=%d, 2=%d, 3=%d\n",
+		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 0),
+		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 1),
+		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 2),
+		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 3));
+
+	/**
+	 * Update the voltage and pre-emphasis levels as per DPCD request
+	 * vector.
+	 */
+	drm_dbg_dp(link->drm_dev,
+			 "Current: v_level = 0x%x, p_level = 0x%x\n",
+			link->msm_dp_link.phy_params.v_level,
+			link->msm_dp_link.phy_params.p_level);
+	link->msm_dp_link.phy_params.v_level =
+		drm_dp_get_adjust_request_voltage(link->link_status, 0);
+	link->msm_dp_link.phy_params.p_level =
+		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 0);
+
+	link->msm_dp_link.phy_params.p_level >>= DP_TRAIN_PRE_EMPHASIS_SHIFT;
+
+	drm_dbg_dp(link->drm_dev,
+			"Requested: v_level = 0x%x, p_level = 0x%x\n",
+			link->msm_dp_link.phy_params.v_level,
+			link->msm_dp_link.phy_params.p_level);
+}
+
+/**
+ * msm_dp_link_process_phy_test_pattern_request() - process new phy link requests
+ * @link: Display Port Driver data
+ *
+ * This function will handle new phy link pattern requests that are initiated
+ * by the sink. The function will return 0 if a phy link pattern has been
+ * processed, otherwise it will return -EINVAL.
+ */
+static int msm_dp_link_process_phy_test_pattern_request(
+		struct msm_dp_link_private *link)
+{
+	if (!(link->request.test_requested & DP_TEST_LINK_PHY_TEST_PATTERN)) {
+		drm_dbg_dp(link->drm_dev, "no phy test\n");
+		return -EINVAL;
+	}
+
+	if (!is_link_rate_valid(link->request.test_link_rate) ||
+		!is_lane_count_valid(link->request.test_lane_count)) {
+		DRM_ERROR("Invalid: link rate = 0x%x,lane count = 0x%x\n",
+				link->request.test_link_rate,
+				link->request.test_lane_count);
+		return -EINVAL;
+	}
+
+	drm_dbg_dp(link->drm_dev,
+			"Current: rate = 0x%x, lane count = 0x%x\n",
+			link->msm_dp_link.link_params.rate,
+			link->msm_dp_link.link_params.num_lanes);
+
+	drm_dbg_dp(link->drm_dev,
+			"Requested: rate = 0x%x, lane count = 0x%x\n",
+			link->request.test_link_rate,
+			link->request.test_lane_count);
+
+	link->msm_dp_link.link_params.num_lanes = link->request.test_lane_count;
+	link->msm_dp_link.link_params.rate =
+		drm_dp_bw_code_to_link_rate(link->request.test_link_rate);
+
+	msm_dp_link_parse_vx_px(link);
+
+	return 0;
+}
+
+static bool msm_dp_link_read_psr_error_status(struct msm_dp_link_private *link)
+{
+	u8 status;
+
+	drm_dp_dpcd_read(link->aux, DP_PSR_ERROR_STATUS, &status, 1);
+
+	if (status & DP_PSR_LINK_CRC_ERROR)
+		DRM_ERROR("PSR LINK CRC ERROR\n");
+	else if (status & DP_PSR_RFB_STORAGE_ERROR)
+		DRM_ERROR("PSR RFB STORAGE ERROR\n");
+	else if (status & DP_PSR_VSC_SDP_UNCORRECTABLE_ERROR)
+		DRM_ERROR("PSR VSC SDP UNCORRECTABLE ERROR\n");
+	else
+		return false;
+
+	return true;
+}
+
+static bool msm_dp_link_psr_capability_changed(struct msm_dp_link_private *link)
+{
+	u8 status;
+
+	drm_dp_dpcd_read(link->aux, DP_PSR_ESI, &status, 1);
+
+	if (status & DP_PSR_CAPS_CHANGE) {
+		drm_dbg_dp(link->drm_dev, "PSR Capability Change\n");
+		return true;
+	}
+
+	return false;
+}
+
+static u8 get_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)
+{
+	return link_status[r - DP_LANE0_1_STATUS];
+}
+
+/**
+ * msm_dp_link_process_link_status_update() - processes link status updates
+ * @link: Display Port link module data
+ *
+ * This function will check for changes in the link status, e.g. clock
+ * recovery done on all lanes, and trigger link training if there is a
+ * failure/error on the link.
+ *
+ * The function will return 0 if the a link status update has been processed,
+ * otherwise it will return -EINVAL.
+ */
+static int msm_dp_link_process_link_status_update(struct msm_dp_link_private *link)
+{
+	bool channel_eq_done = drm_dp_channel_eq_ok(link->link_status,
+			link->msm_dp_link.link_params.num_lanes);
+
+	bool clock_recovery_done = drm_dp_clock_recovery_ok(link->link_status,
+			link->msm_dp_link.link_params.num_lanes);
+
+	drm_dbg_dp(link->drm_dev,
+		       "channel_eq_done = %d, clock_recovery_done = %d\n",
+                        channel_eq_done, clock_recovery_done);
+
+	if (channel_eq_done && clock_recovery_done)
+		return -EINVAL;
+
+	return 0;
+}
+
+/**
+ * msm_dp_link_process_ds_port_status_change() - process port status changes
+ * @link: Display Port Driver data
+ *
+ * This function will handle downstream port updates that are initiated by
+ * the sink. If the downstream port status has changed, the EDID is read via
+ * AUX.
+ *
+ * The function will return 0 if a downstream port update has been
+ * processed, otherwise it will return -EINVAL.
+ */
+static int msm_dp_link_process_ds_port_status_change(struct msm_dp_link_private *link)
+{
+	if (get_link_status(link->link_status, DP_LANE_ALIGN_STATUS_UPDATED) &
+					DP_DOWNSTREAM_PORT_STATUS_CHANGED)
+		goto reset;
+
+	if (link->prev_sink_count == link->msm_dp_link.sink_count)
+		return -EINVAL;
+
+reset:
+	/* reset prev_sink_count */
+	link->prev_sink_count = link->msm_dp_link.sink_count;
+
+	return 0;
+}
+
+static bool msm_dp_link_is_video_pattern_requested(struct msm_dp_link_private *link)
+{
+	return (link->request.test_requested & DP_TEST_LINK_VIDEO_PATTERN)
+		&& !(link->request.test_requested &
+		DP_TEST_LINK_AUDIO_DISABLED_VIDEO);
+}
+
+static bool msm_dp_link_is_audio_pattern_requested(struct msm_dp_link_private *link)
+{
+	return (link->request.test_requested & DP_TEST_LINK_AUDIO_PATTERN);
+}
+
+static void msm_dp_link_reset_data(struct msm_dp_link_private *link)
+{
+	link->request = (const struct msm_dp_link_request){ 0 };
+	link->msm_dp_link.test_video = (const struct msm_dp_link_test_video){ 0 };
+	link->msm_dp_link.test_video.test_bit_depth = DP_TEST_BIT_DEPTH_UNKNOWN;
+	link->msm_dp_link.test_audio = (const struct msm_dp_link_test_audio){ 0 };
+	link->msm_dp_link.phy_params.phy_test_pattern_sel = 0;
+	link->msm_dp_link.sink_request = 0;
+	link->msm_dp_link.test_response = 0;
+}
+
+/**
+ * msm_dp_link_process_request() - handle HPD IRQ transition to HIGH
+ * @msm_dp_link: pointer to link module data
+ *
+ * This function will handle the HPD IRQ state transitions from LOW to HIGH
+ * (including cases when there are back to back HPD IRQ HIGH) indicating
+ * the start of a new link training request or sink status update.
+ */
+int msm_dp_link_process_request(struct msm_dp_link *msm_dp_link)
+{
+	int ret = 0;
+	struct msm_dp_link_private *link;
+
+	if (!msm_dp_link) {
+		DRM_ERROR("invalid input\n");
+		return -EINVAL;
+	}
+
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
+
+	msm_dp_link_reset_data(link);
+
+	ret = msm_dp_link_parse_sink_status_field(link);
+	if (ret)
+		return ret;
+
+	if (link->request.test_requested == DP_TEST_LINK_EDID_READ) {
+		msm_dp_link->sink_request |= DP_TEST_LINK_EDID_READ;
+	} else if (!msm_dp_link_process_ds_port_status_change(link)) {
+		msm_dp_link->sink_request |= DS_PORT_STATUS_CHANGED;
+	} else if (!msm_dp_link_process_link_training_request(link)) {
+		msm_dp_link->sink_request |= DP_TEST_LINK_TRAINING;
+	} else if (!msm_dp_link_process_phy_test_pattern_request(link)) {
+		msm_dp_link->sink_request |= DP_TEST_LINK_PHY_TEST_PATTERN;
+	} else if (msm_dp_link_read_psr_error_status(link)) {
+		DRM_ERROR("PSR IRQ_HPD received\n");
+	} else if (msm_dp_link_psr_capability_changed(link)) {
+		drm_dbg_dp(link->drm_dev, "PSR Capability changed\n");
+	} else {
+		ret = msm_dp_link_process_link_status_update(link);
+		if (!ret) {
+			msm_dp_link->sink_request |= DP_LINK_STATUS_UPDATED;
+		} else {
+			if (msm_dp_link_is_video_pattern_requested(link)) {
+				ret = 0;
+				msm_dp_link->sink_request |= DP_TEST_LINK_VIDEO_PATTERN;
+			}
+			if (msm_dp_link_is_audio_pattern_requested(link)) {
+				msm_dp_link->sink_request |= DP_TEST_LINK_AUDIO_PATTERN;
+				ret = -EINVAL;
+			}
+		}
+	}
+
+	drm_dbg_dp(link->drm_dev, "sink request=%#x\n",
+				msm_dp_link->sink_request);
+	return ret;
+}
+
+int msm_dp_link_get_colorimetry_config(struct msm_dp_link *msm_dp_link)
+{
+	u32 cc = DP_MISC0_COLORIMERY_CFG_LEGACY_RGB;
+	struct msm_dp_link_private *link;
+
+	if (!msm_dp_link) {
+		DRM_ERROR("invalid input\n");
+		return -EINVAL;
+	}
+
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
+
+	/*
+	 * Unless a video pattern CTS test is ongoing, use RGB_VESA
+	 * Only RGB_VESA and RGB_CEA supported for now
+	 */
+	if (msm_dp_link_is_video_pattern_requested(link)) {
+		if (link->msm_dp_link.test_video.test_dyn_range &
+					DP_TEST_DYNAMIC_RANGE_CEA)
+			cc = DP_MISC0_COLORIMERY_CFG_CEA_RGB;
+	}
+
+	return cc;
+}
+
+int msm_dp_link_adjust_levels(struct msm_dp_link *msm_dp_link, u8 *link_status)
+{
+	int i;
+	u8 max_p_level;
+	int v_max = 0, p_max = 0;
+	struct msm_dp_link_private *link;
+
+	if (!msm_dp_link) {
+		DRM_ERROR("invalid input\n");
+		return -EINVAL;
+	}
+
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
+
+	/* use the max level across lanes */
+	for (i = 0; i < msm_dp_link->link_params.num_lanes; i++) {
+		u8 data_v = drm_dp_get_adjust_request_voltage(link_status, i);
+		u8 data_p = drm_dp_get_adjust_request_pre_emphasis(link_status,
+									 i);
+		drm_dbg_dp(link->drm_dev,
+				"lane=%d req_vol_swing=%d req_pre_emphasis=%d\n",
+				i, data_v, data_p);
+		if (v_max < data_v)
+			v_max = data_v;
+		if (p_max < data_p)
+			p_max = data_p;
+	}
+
+	msm_dp_link->phy_params.v_level = v_max >> DP_TRAIN_VOLTAGE_SWING_SHIFT;
+	msm_dp_link->phy_params.p_level = p_max >> DP_TRAIN_PRE_EMPHASIS_SHIFT;
+
+	/**
+	 * Adjust the voltage swing and pre-emphasis level combination to within
+	 * the allowable range.
+	 */
+	if (msm_dp_link->phy_params.v_level > DP_TRAIN_LEVEL_MAX) {
+		drm_dbg_dp(link->drm_dev,
+			"Requested vSwingLevel=%d, change to %d\n",
+			msm_dp_link->phy_params.v_level,
+			DP_TRAIN_LEVEL_MAX);
+		msm_dp_link->phy_params.v_level = DP_TRAIN_LEVEL_MAX;
+	}
+
+	if (msm_dp_link->phy_params.p_level > DP_TRAIN_LEVEL_MAX) {
+		drm_dbg_dp(link->drm_dev,
+			"Requested preEmphasisLevel=%d, change to %d\n",
+			msm_dp_link->phy_params.p_level,
+			DP_TRAIN_LEVEL_MAX);
+		msm_dp_link->phy_params.p_level = DP_TRAIN_LEVEL_MAX;
+	}
+
+	max_p_level = DP_TRAIN_LEVEL_MAX - msm_dp_link->phy_params.v_level;
+	if (msm_dp_link->phy_params.p_level > max_p_level) {
+		drm_dbg_dp(link->drm_dev,
+			"Requested preEmphasisLevel=%d, change to %d\n",
+			msm_dp_link->phy_params.p_level,
+			max_p_level);
+		msm_dp_link->phy_params.p_level = max_p_level;
+	}
+
+	drm_dbg_dp(link->drm_dev, "adjusted: v_level=%d, p_level=%d\n",
+		msm_dp_link->phy_params.v_level, msm_dp_link->phy_params.p_level);
+
+	return 0;
+}
+
+void msm_dp_link_reset_phy_params_vx_px(struct msm_dp_link *msm_dp_link)
+{
+	msm_dp_link->phy_params.v_level = 0;
+	msm_dp_link->phy_params.p_level = 0;
+}
+
+u32 msm_dp_link_get_test_bits_depth(struct msm_dp_link *msm_dp_link, u32 bpp)
+{
+	u32 tbd;
+	struct msm_dp_link_private *link;
+
+	link = container_of(msm_dp_link, struct msm_dp_link_private, msm_dp_link);
+
+	/*
+	 * Few simplistic rules and assumptions made here:
+	 *    1. Test bit depth is bit depth per color component
+	 *    2. Assume 3 color components
+	 */
+	switch (bpp) {
+	case 18:
+		tbd = DP_TEST_BIT_DEPTH_6;
+		break;
+	case 24:
+		tbd = DP_TEST_BIT_DEPTH_8;
+		break;
+	case 30:
+		tbd = DP_TEST_BIT_DEPTH_10;
+		break;
+	default:
+		drm_dbg_dp(link->drm_dev, "bpp=%d not supported, use bpc=8\n",
+			   bpp);
+		tbd = DP_TEST_BIT_DEPTH_8;
+		break;
+	}
+
+	tbd = (tbd >> DP_TEST_BIT_DEPTH_SHIFT);
+
+	return tbd;
+}
+
+struct msm_dp_link *msm_dp_link_get(struct device *dev, struct drm_dp_aux *aux)
+{
+	struct msm_dp_link_private *link;
+	struct msm_dp_link *msm_dp_link;
+
+	if (!dev || !aux) {
+		DRM_ERROR("invalid input\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	link = devm_kzalloc(dev, sizeof(*link), GFP_KERNEL);
+	if (!link)
+		return ERR_PTR(-ENOMEM);
+
+	link->aux   = aux;
+
+	mutex_init(&link->psm_mutex);
+	msm_dp_link = &link->msm_dp_link;
+
+	return msm_dp_link;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_link.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_link.h
@@ -0,0 +1,120 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DP_LINK_H_
+#define _DP_LINK_H_
+
+#include "dp_aux.h"
+
+#define DS_PORT_STATUS_CHANGED 0x200
+#define DP_TEST_BIT_DEPTH_UNKNOWN 0xFFFFFFFF
+#define DP_LINK_CAP_ENHANCED_FRAMING (1 << 0)
+
+struct msm_dp_link_info {
+	unsigned char revision;
+	unsigned int rate;
+	unsigned int num_lanes;
+	unsigned long capabilities;
+};
+
+#define DP_TRAIN_LEVEL_MAX	3
+
+struct msm_dp_link_test_video {
+	u32 test_video_pattern;
+	u32 test_bit_depth;
+	u32 test_dyn_range;
+	u32 test_h_total;
+	u32 test_v_total;
+	u32 test_h_start;
+	u32 test_v_start;
+	u32 test_hsync_pol;
+	u32 test_hsync_width;
+	u32 test_vsync_pol;
+	u32 test_vsync_width;
+	u32 test_h_width;
+	u32 test_v_height;
+	u32 test_rr_d;
+	u32 test_rr_n;
+};
+
+struct msm_dp_link_test_audio {
+	u32 test_audio_sampling_rate;
+	u32 test_audio_channel_count;
+	u32 test_audio_pattern_type;
+	u32 test_audio_period_ch_1;
+	u32 test_audio_period_ch_2;
+	u32 test_audio_period_ch_3;
+	u32 test_audio_period_ch_4;
+	u32 test_audio_period_ch_5;
+	u32 test_audio_period_ch_6;
+	u32 test_audio_period_ch_7;
+	u32 test_audio_period_ch_8;
+};
+
+struct msm_dp_link_phy_params {
+	u32 phy_test_pattern_sel;
+	u8 v_level;
+	u8 p_level;
+};
+
+struct msm_dp_link {
+	u32 sink_request;
+	u32 test_response;
+
+	u8 sink_count;
+	struct msm_dp_link_test_video test_video;
+	struct msm_dp_link_test_audio test_audio;
+	struct msm_dp_link_phy_params phy_params;
+	struct msm_dp_link_info link_params;
+};
+
+/**
+ * mdss_dp_test_bit_depth_to_bpp() - convert test bit depth to bpp
+ * @tbd: test bit depth
+ *
+ * Returns the bits per pixel (bpp) to be used corresponding to the
+ * git bit depth value. This function assumes that bit depth has
+ * already been validated.
+ */
+static inline u32 msm_dp_link_bit_depth_to_bpp(u32 tbd)
+{
+	/*
+	 * Few simplistic rules and assumptions made here:
+	 *    1. Bit depth is per color component
+	 *    2. If bit depth is unknown return 0
+	 *    3. Assume 3 color components
+	 */
+	switch (tbd) {
+	case DP_TEST_BIT_DEPTH_6:
+		return 18;
+	case DP_TEST_BIT_DEPTH_8:
+		return 24;
+	case DP_TEST_BIT_DEPTH_10:
+		return 30;
+	case DP_TEST_BIT_DEPTH_UNKNOWN:
+	default:
+		return 0;
+	}
+}
+
+void msm_dp_link_reset_phy_params_vx_px(struct msm_dp_link *msm_dp_link);
+u32 msm_dp_link_get_test_bits_depth(struct msm_dp_link *msm_dp_link, u32 bpp);
+int msm_dp_link_process_request(struct msm_dp_link *msm_dp_link);
+int msm_dp_link_get_colorimetry_config(struct msm_dp_link *msm_dp_link);
+int msm_dp_link_adjust_levels(struct msm_dp_link *msm_dp_link, u8 *link_status);
+bool msm_dp_link_send_test_response(struct msm_dp_link *msm_dp_link);
+int msm_dp_link_psm_config(struct msm_dp_link *msm_dp_link,
+		struct msm_dp_link_info *link_info, bool enable);
+bool msm_dp_link_send_edid_checksum(struct msm_dp_link *msm_dp_link, u8 checksum);
+
+/**
+ * msm_dp_link_get() - get the functionalities of dp test module
+ *
+ *
+ * return: a pointer to msm_dp_link struct
+ */
+struct msm_dp_link *msm_dp_link_get(struct device *dev, struct drm_dp_aux *aux);
+
+#endif /* _DP_LINK_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_mst_drm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_mst_drm.c
@@ -0,0 +1,1097 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <drm/drm_edid.h>
+#include "dp_mst_drm.h"
+
+static struct drm_private_state *msm_dp_mst_duplicate_bridge_state(struct drm_private_obj *obj)
+{
+	struct msm_dp_mst_bridge_state *state;
+
+	state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return NULL;
+
+	__drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
+
+	return &state->base;
+}
+
+static void msm_dp_mst_destroy_bridge_state(struct drm_private_obj *obj,
+					    struct drm_private_state *state)
+{
+	struct msm_dp_mst_bridge_state *priv_state =
+		to_msm_dp_mst_bridge_priv_state(state);
+
+	kfree(priv_state);
+}
+
+static const struct drm_private_state_funcs msm_dp_mst_bridge_state_funcs = {
+	.atomic_duplicate_state = msm_dp_mst_duplicate_bridge_state,
+	.atomic_destroy_state = msm_dp_mst_destroy_bridge_state,
+};
+
+/**
+ * dp_mst_find_vcpi_slots() - Find VCPI slots for this PBN value
+ * @mgr: manager to use
+ * @pbn: payload bandwidth to convert into slots.
+ *
+ * Calculate the number of VCPI slots that will be required for the given PBN
+ * value.
+ *
+ * RETURNS:
+ * The total slots required for this port, or error.
+ */
+static int msm_dp_mst_find_vcpi_slots(struct drm_dp_mst_topology_mgr *mgr, int pbn)
+{
+	int num_slots;
+	struct drm_dp_mst_topology_state *state;
+
+	state = to_drm_dp_mst_topology_state(mgr->base.state);
+	num_slots = DIV_ROUND_UP(pbn, state->pbn_div.full);
+
+	/* max. time slots - one slot for MTP header */
+	if (num_slots > 63)
+		return -ENOSPC;
+	return num_slots;
+}
+
+static int msm_dp_mst_calc_pbn_mode(struct drm_display_mode *mode, u32 bpp)
+{
+	int pbn;
+
+	// note : we can even drop dp_mst_calc_pbn_mode and just use this
+	// directly
+	pbn = drm_dp_calc_pbn_mode(mode->clock, bpp << 4);
+
+	return pbn;
+}
+
+static int msm_dp_mst_get_mst_pbn_div(struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_link_info *link_info;
+
+	link_info = &msm_dp_panel->link_info;
+
+	return link_info->rate * link_info->num_lanes / 54000;
+}
+
+static int _msm_dp_mst_compute_config(struct drm_atomic_state *state,
+				      struct msm_dp_mst *mst, struct drm_connector *connector,
+				      struct drm_display_mode *mode)
+{
+	int slots = 0, pbn;
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(connector);
+	int rc = 0;
+	struct drm_dp_mst_topology_state *mst_state;
+
+	struct msm_dp *dp_display = mst->msm_dp;
+	u32 bpp;
+
+	bpp = connector->display_info.bpc * 3;
+	//default to 24
+	if (!bpp)
+		bpp = 24;
+
+	pbn = msm_dp_mst_calc_pbn_mode(mode, bpp);
+
+	mst_state = to_drm_dp_mst_topology_state(mst->mst_mgr.base.state);
+
+	if (!mst_state->pbn_div.full)
+		mst_state->pbn_div.full = msm_dp_mst_get_mst_pbn_div(mst_conn->dp_panel);
+
+	rc = drm_dp_atomic_find_time_slots(state, &mst->mst_mgr, mst_conn->mst_port, pbn);
+	if (rc < 0) {
+		DRM_ERROR("conn:%d failed to find vcpi slots. pbn:%d, rc:%d\n",
+			  connector->base.id, pbn, rc);
+		goto end;
+	}
+
+	slots = rc;
+
+	rc = drm_dp_mst_atomic_check(state);
+	if (rc) {
+		DRM_ERROR("conn:%d mst atomic check failed: rc=%d\n", connector->base.id, rc);
+		slots = 0;
+		goto end;
+	}
+
+	drm_dbg_dp(dp_display->drm_dev, "conn:%d pbn:%d slots:%d rc:%d\n",
+		   connector->base.id, pbn, slots, rc);
+
+end:
+	return (rc < 0 ? rc : slots);
+}
+
+static void _msm_dp_mst_update_timeslots(struct msm_dp_mst *mst,
+					 struct msm_dp_mst_bridge *mst_bridge,
+					 struct drm_dp_mst_port *port)
+{
+	int i;
+	struct msm_dp_mst_bridge *msm_dp_bridge;
+	struct drm_dp_mst_topology_state *mst_state;
+	struct drm_dp_mst_atomic_payload *payload;
+	int prev_start = 0;
+	int prev_slots = 0;
+
+	mst_state = to_drm_dp_mst_topology_state(mst->mst_mgr.base.state);
+	payload = drm_atomic_get_mst_payload_state(mst_state, port);
+
+	if (!payload) {
+		DRM_ERROR("mst bridge [%d] update_timeslots failed, null payload\n",
+			  mst_bridge->id);
+		return;
+	}
+
+	for (i = 0; i < mst->max_streams; i++) {
+		msm_dp_bridge = &mst->mst_bridge[i];
+		if (mst_bridge == msm_dp_bridge) {
+			/*
+			 * When a payload was removed make sure to move any payloads after it
+			 * to the left so all payloads are aligned to the left.
+			 */
+			if (payload->vc_start_slot < 0) {
+				// cache the payload
+				prev_start = msm_dp_bridge->start_slot;
+				prev_slots = msm_dp_bridge->num_slots;
+				msm_dp_bridge->pbn = 0;
+				msm_dp_bridge->start_slot = 1;
+				msm_dp_bridge->num_slots = 0;
+				msm_dp_bridge->vcpi = 0;
+			} else { //add payload
+				msm_dp_bridge->pbn = payload->pbn;
+				msm_dp_bridge->start_slot = payload->vc_start_slot;
+				msm_dp_bridge->num_slots = payload->time_slots;
+				msm_dp_bridge->vcpi = payload->vcpi;
+			}
+		}
+	}
+
+	// Now commit all the updated payloads
+	for (i = 0; i < mst->max_streams; i++) {
+		msm_dp_bridge = &mst->mst_bridge[i];
+
+		//Shift payloads to the left if there was a removed payload.
+		if (payload->vc_start_slot < 0 && msm_dp_bridge->start_slot > prev_start)
+			msm_dp_bridge->start_slot -= prev_slots;
+
+		msm_dp_display_set_stream_info(mst->msm_dp, msm_dp_bridge->msm_dp_panel,
+					       msm_dp_bridge->id, msm_dp_bridge->start_slot,
+					       msm_dp_bridge->num_slots,
+					       msm_dp_bridge->pbn, msm_dp_bridge->vcpi);
+		drm_dbg_dp(mst->msm_dp->drm_dev,
+			   "conn:%d vcpi:%d start_slot:%d num_slots:%d, pbn:%d\n",
+			   DP_MST_CONN_ID(msm_dp_bridge), msm_dp_bridge->vcpi,
+			   msm_dp_bridge->start_slot,
+			   msm_dp_bridge->num_slots, msm_dp_bridge->pbn);
+	}
+}
+
+static int _msm_dp_mst_bridge_pre_enable_part1(struct msm_dp_mst_bridge *dp_bridge)
+{
+	struct msm_dp *msm_dp = dp_bridge->display;
+	struct msm_dp_mst *mst = msm_dp->msm_dp_mst;
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(dp_bridge->connector);
+	struct drm_dp_mst_port *port = mst_conn->mst_port;
+	struct drm_dp_mst_topology_state *mst_state;
+	struct drm_dp_mst_atomic_payload *payload;
+	struct msm_dp_panel *dp_panel = mst_conn->dp_panel;
+	int pbn, slots;
+	int rc = 0;
+
+	pbn = msm_dp_mst_calc_pbn_mode(&dp_panel->msm_dp_mode.drm_mode,
+				       msm_dp->connector->display_info.bpc * 3);
+
+	slots = msm_dp_mst_find_vcpi_slots(&mst->mst_mgr, pbn);
+
+	drm_dbg_dp(msm_dp->drm_dev, "conn:%d pbn:%d, slots:%d\n", DP_MST_CONN_ID(dp_bridge),
+		   pbn, slots);
+
+	mst_state = to_drm_dp_mst_topology_state(mst->mst_mgr.base.state);
+	payload = drm_atomic_get_mst_payload_state(mst_state, port);
+	if (!payload || payload->time_slots <= 0) {
+		DRM_ERROR("time slots not allocated for conn:%d\n", DP_MST_CONN_ID(dp_bridge));
+		rc = -EINVAL;
+		return rc;
+	}
+
+	drm_dp_mst_update_slots(mst_state, DP_CAP_ANSI_8B10B);
+
+	rc = drm_dp_add_payload_part1(&mst->mst_mgr, mst_state, payload);
+	if (rc) {
+		DRM_ERROR("payload allocation failure for conn:%d\n", DP_MST_CONN_ID(dp_bridge));
+		return rc;
+	}
+
+	_msm_dp_mst_update_timeslots(mst, dp_bridge, port);
+
+	return rc;
+}
+
+static void _msm_dp_mst_bridge_pre_enable_part2(struct msm_dp_mst_bridge *dp_bridge)
+{
+	struct msm_dp *msm_dp = dp_bridge->display;
+	struct msm_dp_mst *mst = msm_dp->msm_dp_mst;
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(dp_bridge->connector);
+	struct drm_dp_mst_port *port = mst_conn->mst_port;
+	struct drm_dp_mst_topology_state *mst_state;
+	struct drm_dp_mst_atomic_payload *payload;
+
+	drm_dp_check_act_status(&mst->mst_mgr);
+
+	mst_state = to_drm_dp_mst_topology_state(mst->mst_mgr.base.state);
+	payload = drm_atomic_get_mst_payload_state(mst_state, port);
+
+	if (!payload) {
+		DRM_ERROR("mst bridge [%d] null payload\n", dp_bridge->id);
+		return;
+	}
+
+	if (!payload->port) {
+		DRM_ERROR("mst bridge [%d] null port\n", dp_bridge->id);
+		return;
+	}
+
+	if (!payload->port->connector) {
+		DRM_ERROR("mst bridge [%d] part-2 failed, null connector\n",
+			  dp_bridge->id);
+		return;
+	}
+
+	if (payload->vc_start_slot == -1) {
+		DRM_ERROR("mst bridge [%d] part-2 failed, payload alloc part 1 failed\n",
+			  dp_bridge->id);
+		return;
+	}
+
+	drm_dp_add_payload_part2(&mst->mst_mgr, payload);
+	drm_dbg_dp(msm_dp->drm_dev, "mst bridge [%d] _pre enable part-2 complete\n",
+		   dp_bridge->id);
+}
+
+static void _msm_dp_mst_bridge_pre_disable_part1(struct msm_dp_mst_bridge *dp_bridge)
+{
+	struct msm_dp *msm_dp = dp_bridge->display;
+	struct msm_dp_mst *mst = msm_dp->msm_dp_mst;
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(dp_bridge->connector);
+	struct drm_dp_mst_port *port = mst_conn->mst_port;
+	struct drm_dp_mst_topology_state *mst_state;
+	struct drm_dp_mst_atomic_payload *payload;
+
+	mst_state = to_drm_dp_mst_topology_state(mst->mst_mgr.base.state);
+	payload = drm_atomic_get_mst_payload_state(mst_state, port);
+
+	if (!payload) {
+		DRM_ERROR("mst bridge [%d] _pre disable part-1 failed, null payload\n",
+			  dp_bridge->id);
+		return;
+	}
+
+	drm_dp_remove_payload_part1(&mst->mst_mgr, mst_state, payload);
+	_msm_dp_mst_update_timeslots(mst, dp_bridge, port);
+
+	drm_dbg_dp(msm_dp->drm_dev, "mst bridge [%d] _pre disable part-1 complete\n",
+		   dp_bridge->id);
+}
+
+static void _msm_dp_mst_bridge_pre_disable_part2(struct msm_dp_mst_bridge *dp_bridge)
+{
+	struct msm_dp *msm_dp = dp_bridge->display;
+	struct msm_dp_mst *mst = msm_dp->msm_dp_mst;
+
+	drm_dp_check_act_status(&mst->mst_mgr);
+
+	drm_dbg_dp(msm_dp->drm_dev, "mst bridge [%d] _pre disable part-2 complete\n",
+		   dp_bridge->id);
+}
+
+static void msm_dp_mst_bridge_atomic_pre_enable(struct drm_bridge *drm_bridge,
+						struct drm_bridge_state *old_bridge_state)
+{
+	int rc = 0;
+	struct msm_dp_mst_bridge *bridge;
+	struct msm_dp *dp;
+	struct msm_dp_mst_bridge_state *msm_dp_bridge_state;
+	struct msm_dp_mst *dp_mst;
+
+	if (!drm_bridge) {
+		DRM_ERROR("Invalid params\n");
+		return;
+	}
+
+	bridge = to_msm_dp_mst_bridge(drm_bridge);
+	msm_dp_bridge_state = to_msm_dp_mst_bridge_state(bridge);
+	dp = bridge->display;
+	dp_mst = dp->msm_dp_mst;
+
+	/* to cover cases of bridge_disable/bridge_enable without modeset */
+	bridge->connector = msm_dp_bridge_state->connector;
+	bridge->msm_dp_panel = msm_dp_bridge_state->msm_dp_panel;
+
+	if (!bridge->connector) {
+		DRM_ERROR("Invalid connector\n");
+		return;
+	}
+
+	mutex_lock(&dp_mst->mst_lock);
+	msm_dp_display_atomic_prepare(dp);
+
+	rc = _msm_dp_mst_bridge_pre_enable_part1(bridge);
+	if (rc) {
+		DRM_ERROR("[%d] DP display pre-enable failed, rc=%d\n", bridge->id, rc);
+		msm_dp_display_unprepare(dp);
+		mutex_unlock(&dp_mst->mst_lock);
+		return;
+	}
+
+	msm_dp_display_enable_helper(dp, bridge->msm_dp_panel);
+
+	_msm_dp_mst_bridge_pre_enable_part2(bridge);
+
+	drm_dbg_dp(dp->drm_dev, "conn:%d mode:%s fps:%d vcpi:%d slots:%d to %d\n",
+		   DP_MST_CONN_ID(bridge), bridge->drm_mode.name,
+		   drm_mode_vrefresh(&bridge->drm_mode),
+		   bridge->vcpi, bridge->start_slot,
+		   bridge->start_slot + bridge->num_slots);
+
+	mutex_unlock(&dp_mst->mst_lock);
+}
+
+static void msm_dp_mst_bridge_atomic_disable(struct drm_bridge *drm_bridge,
+					     struct drm_bridge_state *old_bridge_state)
+{
+	struct msm_dp_mst_bridge *bridge;
+	struct msm_dp *dp;
+	struct msm_dp_mst *mst;
+
+	if (!drm_bridge) {
+		DRM_ERROR("Invalid params\n");
+		return;
+	}
+
+	bridge = to_msm_dp_mst_bridge(drm_bridge);
+	if (!bridge->connector) {
+		DRM_ERROR("Invalid connector\n");
+		return;
+	}
+
+	dp = bridge->display;
+	mst = dp->msm_dp_mst;
+
+	mutex_lock(&mst->mst_lock);
+
+	_msm_dp_mst_bridge_pre_disable_part1(bridge);
+
+	msm_dp_display_disable_helper(dp, bridge->msm_dp_panel);
+
+	_msm_dp_mst_bridge_pre_disable_part2(bridge);
+
+	drm_dbg_dp(dp->drm_dev, "mst bridge:%d conn:%d disable complete\n", bridge->id,
+		   DP_MST_CONN_ID(bridge));
+
+	mutex_unlock(&mst->mst_lock);
+}
+
+static void msm_dp_mst_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
+						  struct drm_bridge_state *old_bridge_state)
+{
+	int conn = 0;
+	struct msm_dp_mst_bridge *bridge;
+	struct msm_dp *dp;
+	struct msm_dp_mst *mst;
+
+	if (!drm_bridge) {
+		DRM_ERROR("Invalid params\n");
+		return;
+	}
+
+	bridge = to_msm_dp_mst_bridge(drm_bridge);
+	if (!bridge->connector) {
+		DRM_ERROR("Invalid connector\n");
+		return;
+	}
+
+	conn = DP_MST_CONN_ID(bridge);
+
+	dp = bridge->display;
+	mst = dp->msm_dp_mst;
+
+	mutex_lock(&mst->mst_lock);
+
+	msm_dp_display_atomic_post_disable_helper(dp, bridge->msm_dp_panel);
+
+	if (!dp->mst_active)
+		msm_dp_display_unprepare(dp);
+
+	bridge->connector = NULL;
+	bridge->msm_dp_panel =  NULL;
+
+	drm_dbg_dp(dp->drm_dev, "mst bridge:%d conn:%d post disable complete\n",
+		   bridge->id, conn);
+
+	mutex_unlock(&mst->mst_lock);
+}
+
+static void msm_dp_mst_bridge_mode_set(struct drm_bridge *drm_bridge,
+				       const struct drm_display_mode *mode,
+				       const struct drm_display_mode *adjusted_mode)
+{
+	struct msm_dp_mst_bridge *bridge;
+	struct msm_dp_mst_bridge_state *dp_bridge_state;
+	struct msm_dp *dp;
+	struct msm_dp_panel *msm_dp_panel;
+
+	if (!drm_bridge || !mode || !adjusted_mode) {
+		DRM_ERROR("Invalid params\n");
+		return;
+	}
+
+	bridge = to_msm_dp_mst_bridge(drm_bridge);
+
+	dp_bridge_state = to_msm_dp_mst_bridge_state(bridge);
+	bridge->connector = dp_bridge_state->connector;
+	bridge->msm_dp_panel = dp_bridge_state->msm_dp_panel;
+
+	msm_dp_panel = bridge->msm_dp_panel;
+
+	dp = bridge->display;
+
+	memset(&bridge->msm_dp_mode, 0x0, sizeof(struct msm_dp_display_mode));
+	memcpy(&bridge->drm_mode, adjusted_mode, sizeof(bridge->drm_mode));
+
+	msm_dp_display_mode_set_helper(dp, mode, adjusted_mode, bridge->msm_dp_panel);
+	msm_dp_panel->mst_caps.pbn = msm_dp_mst_calc_pbn_mode(&msm_dp_panel->msm_dp_mode.drm_mode,
+							      msm_dp_panel->msm_dp_mode.bpp);
+	memcpy(&bridge->msm_dp_mode, &bridge->msm_dp_panel->msm_dp_mode,
+	       sizeof(struct msm_dp_display_mode));
+
+	drm_dbg_dp(dp->drm_dev, "mst bridge:%d conn:%d mode set complete %s\n", bridge->id,
+		   DP_MST_CONN_ID(bridge), mode->name);
+}
+
+/* DP MST Bridge APIs */
+static const struct drm_bridge_funcs msm_dp_mst_bridge_ops = {
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+	.atomic_destroy_state   = drm_atomic_helper_bridge_destroy_state,
+	.atomic_reset           = drm_atomic_helper_bridge_reset,
+	.atomic_pre_enable   = msm_dp_mst_bridge_atomic_pre_enable,
+	.atomic_disable      = msm_dp_mst_bridge_atomic_disable,
+	.atomic_post_disable = msm_dp_mst_bridge_atomic_post_disable,
+	.mode_set     = msm_dp_mst_bridge_mode_set,
+};
+
+int msm_dp_mst_drm_bridge_init(struct msm_dp *dp, struct drm_encoder *encoder)
+{
+	int rc = 0;
+	struct msm_dp_mst_bridge *bridge = NULL;
+	struct msm_dp_mst_bridge_state *state;
+	struct drm_device *dev;
+	struct msm_dp_mst *mst = dp->msm_dp_mst;
+	int i;
+
+	for (i = 0; i < mst->max_streams; i++) {
+		if (!mst->mst_bridge[i].in_use) {
+			bridge = &mst->mst_bridge[i];
+			bridge->encoder = encoder;
+			bridge->in_use = true;
+			bridge->id = i;
+			break;
+		}
+	}
+
+	if (i == mst->max_streams) {
+		DRM_ERROR("mst supports only %d bridges\n", i);
+		rc = -EACCES;
+		goto end;
+	}
+
+	dev = dp->drm_dev;
+	bridge->display = dp;
+	bridge->base.funcs = &msm_dp_mst_bridge_ops;
+	bridge->base.encoder = encoder;
+	bridge->base.type = dp->connector_type;
+	bridge->base.ops = DRM_BRIDGE_OP_MODES;
+	drm_bridge_add(&bridge->base);
+
+	rc = drm_bridge_attach(encoder, &bridge->base, NULL, 0);
+	if (rc) {
+		DRM_ERROR("failed to attach bridge, rc=%d\n", rc);
+		goto end;
+	}
+
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (!state) {
+		rc = -ENOMEM;
+		goto end;
+	}
+
+	drm_atomic_private_obj_init(dev, &bridge->obj,
+				    &state->base,
+				    &msm_dp_mst_bridge_state_funcs);
+
+	drm_dbg_dp(dp->drm_dev, "mst drm bridge init. bridge id:%d\n", i);
+
+	return 0;
+
+end:
+	return rc;
+}
+
+static struct msm_dp_mst_bridge_state *msm_dp_mst_br_priv_state(struct drm_atomic_state *st,
+								struct msm_dp_mst_bridge *bridge)
+{
+	struct drm_device *dev = bridge->base.dev;
+
+	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+
+	return to_msm_dp_mst_bridge_priv_state(drm_atomic_get_private_obj_state(st,
+										&bridge->obj));
+}
+
+static void msm_dp_mst_clear_panel_edid(struct msm_dp *dp_display)
+{
+	struct msm_dp_mst *mst = dp_display->msm_dp_mst;
+	struct msm_dp_mst_connector *mst_conn;
+	struct msm_dp_panel *dp_panel;
+	struct msm_dp_mst_bridge *dp_bridge;
+	int i;
+
+	if (!dp_display) {
+		DRM_ERROR("invalid input\n");
+		return;
+	}
+
+	for (i = 0; i < mst->max_streams; i++) {
+		dp_bridge = &mst->mst_bridge[i];
+		mst_conn = to_msm_dp_mst_connector(dp_bridge->connector);
+		dp_panel = dp_bridge->msm_dp_panel;
+
+		if (!dp_panel || !mst_conn || !mst_conn->mst_port)
+			continue;
+
+		if (dp_panel->drm_edid) {
+			drm_edid_free(dp_panel->drm_edid);
+			dp_panel->drm_edid = NULL;
+		}
+	}
+}
+
+/* DP MST HPD IRQ callback */
+void msm_dp_mst_display_hpd_irq(struct msm_dp *dp_display)
+{
+	int rc;
+	struct msm_dp_mst *mst = dp_display->msm_dp_mst;
+	u8 ack[8] = {};
+	u8 esi[14];
+	unsigned int esi_res = DP_SINK_COUNT_ESI + 1;
+	bool handled;
+
+	rc = drm_dp_dpcd_read(mst->dp_aux, DP_SINK_COUNT_ESI, esi, 14);
+	if (rc != 14) {
+		DRM_ERROR("dpcd sink status read failed, rlen=%d\n", rc);
+		return;
+	}
+
+	drm_dbg_dp(dp_display->drm_dev, "mst irq: esi1[0x%x] esi2[0x%x] esi3[0x%x]\n",
+		   esi[1], esi[2], esi[3]);
+
+	rc = drm_dp_mst_hpd_irq_handle_event(&mst->mst_mgr, esi, ack, &handled);
+
+	/* ack the request */
+	if (handled) {
+		rc = drm_dp_dpcd_writeb(mst->dp_aux, esi_res, ack[1]);
+
+		if (ack[1] & DP_UP_REQ_MSG_RDY)
+			msm_dp_mst_clear_panel_edid(dp_display);
+
+		if (rc != 1)
+			DRM_ERROR("dpcd esi_res failed. rc=%d\n", rc);
+
+		drm_dp_mst_hpd_irq_send_new_request(&mst->mst_mgr);
+	}
+	drm_dbg_dp(dp_display->drm_dev, "mst display hpd_irq handled:%d rc:%d\n", handled, rc);
+}
+
+/* DP MST Connector OPs */
+static int
+msm_dp_mst_connector_detect(struct drm_connector *connector,
+			    struct drm_modeset_acquire_ctx *ctx,
+			    bool force)
+{
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(connector);
+	struct msm_dp *dp_display = mst_conn->msm_dp;
+	struct msm_dp_mst *mst = dp_display->msm_dp_mst;
+	enum drm_connector_status status = connector_status_disconnected;
+
+	if (dp_display->link_ready && dp_display->mst_active)
+		status = drm_dp_mst_detect_port(connector,
+						ctx, &mst->mst_mgr, mst_conn->mst_port);
+
+	drm_dbg_dp(dp_display->drm_dev, "conn:%d status:%d\n", connector->base.id, status);
+
+	return (int)status;
+}
+
+static int msm_dp_mst_connector_get_modes(struct drm_connector *connector)
+{
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(connector);
+	struct msm_dp *dp_display = mst_conn->msm_dp;
+	struct msm_dp_mst *mst = dp_display->msm_dp_mst;
+	struct msm_dp_panel *dp_panel = mst_conn->dp_panel;
+
+	if (dp_panel->drm_edid)
+		goto duplicate_edid;
+
+	drm_edid_free(dp_panel->drm_edid);
+
+	dp_panel->drm_edid = drm_dp_mst_edid_read(connector, &mst->mst_mgr, mst_conn->mst_port);
+	if (!dp_panel->drm_edid) {
+		DRM_ERROR("get edid failed. id: %d\n", connector->base.id);
+		return -EINVAL;
+	}
+
+duplicate_edid:
+	drm_edid_connector_update(connector, dp_panel->drm_edid);
+
+	return drm_edid_connector_add_modes(connector);
+}
+
+static enum drm_mode_status msm_dp_mst_connector_mode_valid(struct drm_connector *connector,
+							    struct drm_display_mode *mode)
+{
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(connector);
+	struct msm_dp *dp_display = mst_conn->msm_dp;
+	struct drm_dp_mst_port *mst_port;
+	struct msm_dp_panel *dp_panel;
+	struct msm_dp_mst *mst;
+	u16 full_pbn, required_pbn;
+	int available_slots, required_slots;
+	struct msm_dp_mst_bridge_state *dp_bridge_state;
+	int i, slots_in_use = 0, active_enc_cnt = 0;
+	const u32 tot_slots = 63;
+
+	if (!connector || !mode || !dp_display) {
+		DRM_ERROR("invalid input\n");
+		return 0;
+	}
+
+	mst = dp_display->msm_dp_mst;
+	mst_conn = to_msm_dp_mst_connector(connector);
+	mst_port = mst_conn->mst_port;
+	dp_panel = mst_conn->dp_panel;
+
+	if (!dp_panel || !mst_port)
+		return MODE_ERROR;
+
+	/* dp bridge state is protected by drm_mode_config.connection_mutex */
+	for (i = 0; i < mst->max_streams; i++) {
+		dp_bridge_state = to_msm_dp_mst_bridge_state(&mst->mst_bridge[i]);
+		if (dp_bridge_state->connector &&
+		    dp_bridge_state->connector != connector) {
+			active_enc_cnt++;
+			slots_in_use += dp_bridge_state->num_slots;
+		}
+	}
+
+	if (active_enc_cnt < DP_STREAM_MAX) {
+		full_pbn = mst_port->full_pbn;
+		available_slots = tot_slots - slots_in_use;
+	} else {
+		DRM_ERROR("all mst streams are active\n");
+		return MODE_BAD;
+	}
+
+	required_pbn = msm_dp_mst_calc_pbn_mode(mode, connector->display_info.bpc * 3);
+
+	required_slots = msm_dp_mst_find_vcpi_slots(&mst->mst_mgr, required_pbn);
+
+	if (required_pbn > full_pbn || required_slots > available_slots) {
+		drm_dbg_dp(dp_display->drm_dev,
+			   "mode:%s not supported. pbn %d vs %d slots %d vs %d\n",
+			   mode->name, required_pbn, full_pbn,
+			   required_slots, available_slots);
+		return MODE_BAD;
+	}
+
+	return msm_dp_display_mode_valid(dp_display, &dp_display->connector->display_info, mode);
+}
+
+static struct drm_encoder *
+msm_dp_mst_atomic_best_encoder(struct drm_connector *connector, struct drm_atomic_state *state)
+{
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(connector);
+	struct msm_dp *dp_display = mst_conn->msm_dp;
+	struct msm_dp_mst *mst = dp_display->msm_dp_mst;
+	struct drm_encoder *enc = NULL;
+	struct msm_dp_mst_bridge_state *bridge_state;
+	u32 i;
+	struct drm_connector_state *conn_state = drm_atomic_get_new_connector_state(state,
+										    connector);
+
+	if (conn_state && conn_state->best_encoder)
+		return conn_state->best_encoder;
+
+	for (i = 0; i < mst->max_streams; i++) {
+		bridge_state = msm_dp_mst_br_priv_state(state, &mst->mst_bridge[i]);
+		if (IS_ERR(bridge_state))
+			goto end;
+
+		if (bridge_state->connector == connector) {
+			enc = mst->mst_bridge[i].encoder;
+			goto end;
+		}
+	}
+
+	for (i = 0; i < mst->max_streams; i++) {
+		bridge_state = msm_dp_mst_br_priv_state(state, &mst->mst_bridge[i]);
+
+		if (!bridge_state->connector) {
+			bridge_state->connector = connector;
+			bridge_state->msm_dp_panel = mst_conn->dp_panel;
+			enc = mst->mst_bridge[i].encoder;
+			break;
+		}
+	}
+
+end:
+	if (enc)
+		drm_dbg_dp(dp_display->drm_dev, "mst connector:%d atomic best encoder:%d\n",
+			   connector->base.id, i);
+	else
+		drm_dbg_dp(dp_display->drm_dev, "mst connector:%d atomic best encoder failed\n",
+			   connector->base.id);
+
+	return enc;
+}
+
+static int msm_dp_mst_connector_atomic_check(struct drm_connector *connector,
+					     struct drm_atomic_state *state)
+{
+	int rc = 0, slots, i;
+	bool vcpi_released = false;
+	struct drm_connector_state *old_conn_state;
+	struct drm_connector_state *new_conn_state;
+	struct drm_crtc *old_crtc;
+	struct drm_crtc_state *crtc_state;
+	struct msm_dp_mst_bridge *bridge;
+	struct msm_dp_mst_bridge_state *bridge_state;
+	struct drm_bridge *drm_bridge;
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(connector);
+	struct msm_dp *dp_display = mst_conn->msm_dp;
+	struct msm_dp_mst *mst = dp_display->msm_dp_mst;
+
+	if (!state)
+		return rc;
+
+	new_conn_state = drm_atomic_get_new_connector_state(state, connector);
+	if (!new_conn_state)
+		return rc;
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, connector);
+	if (!old_conn_state)
+		goto mode_set;
+
+	old_crtc = old_conn_state->crtc;
+	if (!old_crtc)
+		goto mode_set;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, old_crtc);
+
+	for (i = 0; i < mst->max_streams; i++) {
+		bridge = &mst->mst_bridge[i];
+		drm_dbg_dp(dp_display->drm_dev, "bridge id:%d, vcpi:%d, pbn:%d, slots:%d\n",
+			   bridge->id, bridge->vcpi, bridge->pbn,
+			   bridge->num_slots);
+	}
+
+	/*attempt to release vcpi slots on a modeset change for crtc state*/
+	if (drm_atomic_crtc_needs_modeset(crtc_state)) {
+		if (WARN_ON(!old_conn_state->best_encoder)) {
+			rc = -EINVAL;
+			goto end;
+		}
+
+		drm_bridge = drm_bridge_chain_get_first_bridge(old_conn_state->best_encoder);
+		if (WARN_ON(!drm_bridge)) {
+			rc = -EINVAL;
+			goto end;
+		}
+		bridge = to_msm_dp_mst_bridge(drm_bridge);
+
+		bridge_state = msm_dp_mst_br_priv_state(state, bridge);
+		if (IS_ERR(bridge_state)) {
+			rc = PTR_ERR(bridge_state);
+			goto end;
+		}
+
+		if (WARN_ON(bridge_state->connector != connector)) {
+			rc = -EINVAL;
+			goto end;
+		}
+
+		slots = bridge_state->num_slots;
+		if (slots > 0) {
+			rc = drm_dp_atomic_release_time_slots(state,
+							      &mst->mst_mgr,
+							      mst_conn->mst_port);
+			if (rc) {
+				DRM_ERROR("failed releasing %d vcpi slots %d\n", slots, rc);
+				goto end;
+			}
+			vcpi_released = true;
+		}
+
+		if (!new_conn_state->crtc) {
+			/* for cases where crtc is not disabled the slots are not
+			 * freed by drm_dp_atomic_release_time_slots. this results
+			 * in subsequent atomic_check failing since internal slots
+			 * were freed but not the dp mst mgr's
+			 */
+			bridge_state->num_slots = 0;
+			bridge_state->connector = NULL;
+			bridge_state->msm_dp_panel = NULL;
+
+			drm_dbg_dp(dp_display->drm_dev, "clear best encoder: %d\n", bridge->id);
+		}
+	}
+
+mode_set:
+	if (!new_conn_state->crtc)
+		goto end;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
+
+	if (drm_atomic_crtc_needs_modeset(crtc_state) && crtc_state->active) {
+		if (WARN_ON(!new_conn_state->best_encoder)) {
+			rc = -EINVAL;
+			goto end;
+		}
+
+		drm_bridge = drm_bridge_chain_get_first_bridge(new_conn_state->best_encoder);
+		if (WARN_ON(!drm_bridge)) {
+			rc = -EINVAL;
+			goto end;
+		}
+		bridge = to_msm_dp_mst_bridge(drm_bridge);
+
+		bridge_state = msm_dp_mst_br_priv_state(state, bridge);
+		if (IS_ERR(bridge_state)) {
+			rc = PTR_ERR(bridge_state);
+			goto end;
+		}
+
+		if (WARN_ON(bridge_state->connector != connector)) {
+			rc = -EINVAL;
+			goto end;
+		}
+
+		/*
+		 * check if vcpi slots are trying to get allocated in same phase
+		 * as deallocation. If so, go to end to avoid allocation.
+		 */
+		if (vcpi_released) {
+			drm_dbg_dp(dp_display->drm_dev,
+				   "skipping allocation since vcpi was released in the same state\n");
+			goto end;
+		}
+
+		if (WARN_ON(bridge_state->num_slots)) {
+			rc = -EINVAL;
+			goto end;
+		}
+
+		slots = _msm_dp_mst_compute_config(state, mst, connector, &crtc_state->mode);
+		if (slots < 0) {
+			rc = slots;
+			goto end;
+		}
+
+		bridge_state->num_slots = slots;
+	}
+
+end:
+	drm_dbg_dp(dp_display->drm_dev, "mst connector:%d atomic check ret %d\n",
+		   connector->base.id, rc);
+	return rc;
+}
+
+static void dp_mst_connector_destroy(struct drm_connector *connector)
+{
+	struct msm_dp_mst_connector *mst_conn = to_msm_dp_mst_connector(connector);
+	struct msm_dp_panel *dp_panel = mst_conn->dp_panel;
+
+	drm_connector_cleanup(connector);
+	drm_edid_free(dp_panel->drm_edid);
+	dp_panel->drm_edid = NULL;
+	drm_dp_mst_put_port_malloc(mst_conn->mst_port);
+	msm_dp_panel_put(mst_conn->dp_panel);
+}
+
+/* DRM MST callbacks */
+static const struct drm_connector_helper_funcs dp_drm_mst_connector_helper_funcs = {
+	.get_modes =    msm_dp_mst_connector_get_modes,
+	.detect_ctx =   msm_dp_mst_connector_detect,
+	.mode_valid =   msm_dp_mst_connector_mode_valid,
+	.atomic_best_encoder = msm_dp_mst_atomic_best_encoder,
+	.atomic_check = msm_dp_mst_connector_atomic_check,
+};
+
+static const struct drm_connector_funcs dp_drm_mst_connector_funcs = {
+	.reset = drm_atomic_helper_connector_reset,
+	.destroy = dp_mst_connector_destroy,
+	.fill_modes = drm_helper_probe_single_connector_modes,
+	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static struct drm_connector *
+msm_dp_mst_add_connector(struct drm_dp_mst_topology_mgr *mgr,
+			 struct drm_dp_mst_port *port, const char *pathprop)
+{
+	struct msm_dp_mst *dp_mst;
+	struct drm_device *dev;
+	struct msm_dp *dp_display;
+	struct msm_dp_mst_connector *mst_connector;
+	struct drm_connector *connector;
+	int rc, i;
+
+	dp_mst = container_of(mgr, struct msm_dp_mst, mst_mgr);
+
+	dp_display = dp_mst->msm_dp;
+	dev = dp_display->drm_dev;
+
+	mst_connector = devm_kzalloc(dev->dev, sizeof(*mst_connector), GFP_KERNEL);
+
+	/* make sure connector is not accessed before reset */
+	drm_modeset_lock_all(dev);
+
+	rc = drm_connector_init(dev, &mst_connector->connector, &dp_drm_mst_connector_funcs,
+				DRM_MODE_CONNECTOR_DisplayPort);
+	if (rc) {
+		drm_modeset_unlock_all(dev);
+		return NULL;
+	}
+
+	mst_connector->dp_panel = msm_dp_display_get_panel(dp_display);
+	if (!mst_connector->dp_panel) {
+		DRM_ERROR("failed to get dp_panel for connector\n");
+		drm_modeset_unlock_all(dev);
+		return NULL;
+	}
+
+	mst_connector->dp_panel->connector = &mst_connector->connector;
+	mst_connector->msm_dp = dp_display;
+	connector = &mst_connector->connector;
+	drm_connector_helper_add(&mst_connector->connector, &dp_drm_mst_connector_helper_funcs);
+
+	if (connector->funcs->reset)
+		connector->funcs->reset(connector);
+
+	/* add all encoders as possible encoders */
+	for (i = 0; i < dp_mst->max_streams; i++) {
+		rc = drm_connector_attach_encoder(&mst_connector->connector,
+						  dp_mst->mst_bridge[i].encoder);
+		if (rc) {
+			DRM_ERROR("failed to attach encoder to connector, %d\n", rc);
+			drm_modeset_unlock_all(dev);
+			return NULL;
+		}
+	}
+
+	mst_connector->mst_port = port;
+	drm_dp_mst_get_port_malloc(mst_connector->mst_port);
+
+	/* check if we need to call connector_reset here */
+
+	drm_object_attach_property(&mst_connector->connector.base,
+				   dev->mode_config.path_property, 0);
+	drm_object_attach_property(&mst_connector->connector.base,
+				   dev->mode_config.tile_property, 0);
+
+	/* unlock connector and make it accessible */
+	drm_modeset_unlock_all(dev);
+
+	drm_dbg_dp(dp_display->drm_dev, "add mst connector id:%d\n",
+		   mst_connector->connector.base.id);
+
+	return &mst_connector->connector;
+}
+
+int msm_dp_mst_display_set_mgr_state(struct msm_dp *dp_display, bool state)
+{
+	int rc;
+	struct msm_dp_mst *mst = dp_display->msm_dp_mst;
+
+	/*
+	 * on hpd high, set_mgr_state is called before hotplug event is sent
+	 * to usermode and mst_session_state should be updated here.
+	 * on hpd_low, set_mgr_state is called after hotplug event is sent and
+	 * the session_state was already updated prior to that.
+	 */
+	if (state)
+		mst->mst_session_hpd_state = state;
+
+	rc = drm_dp_mst_topology_mgr_set_mst(&mst->mst_mgr, state);
+	if (rc < 0) {
+		DRM_ERROR("failed to set topology mgr state to %d. rc %d\n",
+			  state, rc);
+	}
+
+	drm_dbg_dp(dp_display->drm_dev, "dp_mst_display_set_mgr_state state:%d\n", state);
+	return rc;
+}
+
+static const struct drm_dp_mst_topology_cbs msm_dp_mst_drm_cbs = {
+	.add_connector = msm_dp_mst_add_connector,
+};
+
+int msm_dp_mst_init(struct msm_dp *dp_display, u32 max_streams, u32 max_dpcd_transaction_bytes,
+		    struct drm_dp_aux *drm_aux)
+{
+	struct drm_device *dev;
+	int conn_base_id = 0;
+	int ret;
+	struct msm_dp_mst *msm_dp_mst;
+
+	if (!dp_display) {
+		DRM_ERROR("invalid params\n");
+		return 0;
+	}
+
+	dev = dp_display->drm_dev;
+
+	msm_dp_mst = devm_kzalloc(dev->dev, sizeof(*msm_dp_mst), GFP_KERNEL);
+	if (!msm_dp_mst)
+		return -ENOMEM;
+
+	// will expost the callbacks as direct APIs for hotplug
+	// lets drop install_info for now
+	memset(&msm_dp_mst->mst_mgr, 0, sizeof(msm_dp_mst->mst_mgr));
+	msm_dp_mst->mst_mgr.cbs = &msm_dp_mst_drm_cbs;
+	conn_base_id = dp_display->connector->base.id;
+	msm_dp_mst->msm_dp = dp_display;
+	msm_dp_mst->dp_aux = drm_aux;
+	msm_dp_mst->max_streams = max_streams;
+
+	ret = drm_dp_mst_topology_mgr_init(&msm_dp_mst->mst_mgr, dev,
+					   drm_aux,
+					   max_dpcd_transaction_bytes,
+					   max_streams,
+					   conn_base_id);
+	if (ret) {
+		DRM_ERROR("dp drm mst topology manager init failed\n");
+		return ret;
+	}
+
+	dp_display->msm_dp_mst = msm_dp_mst;
+
+	mutex_init(&msm_dp_mst->mst_lock);
+
+	msm_dp_mst->mst_initialized = true;
+
+	drm_dbg_dp(dp_display->drm_dev, "dp drm mst topology manager init completed\n");
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_mst_drm.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_mst_drm.h
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _DP_MST_DRM_H_
+#define _DP_MST_DRM_H_
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/version.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fixed.h>
+#include <drm/drm_connector.h>
+#include <drm/display/drm_dp_helper.h>
+#include <drm/display/drm_dp_mst_helper.h>
+
+#include "dp_panel.h"
+#include "dp_display.h"
+
+#define MAX_DP_MST_DRM_BRIDGES         4
+
+#define DP_MST_CONN_ID(bridge) ((bridge)->connector ? \
+		(bridge)->connector->base.id : 0)
+
+struct msm_dp_mst_bridge {
+	struct drm_bridge base;
+	struct drm_private_obj obj;
+	u32 id;
+
+	bool in_use;
+
+	struct msm_dp *display;
+	struct drm_encoder *encoder;
+
+	struct drm_display_mode drm_mode;
+	struct msm_dp_display_mode msm_dp_mode;
+	struct drm_connector *connector;
+	struct msm_dp_panel *msm_dp_panel;
+
+	int vcpi;
+	int pbn;
+	int num_slots;
+	int start_slot;
+};
+
+struct msm_dp_mst_bridge_state {
+	struct drm_private_state base;
+	struct drm_connector *connector;
+	struct msm_dp_panel *msm_dp_panel;
+	int num_slots;
+};
+
+struct msm_dp_mst {
+	bool mst_initialized;
+	struct drm_dp_mst_topology_mgr mst_mgr;
+	struct msm_dp_mst_bridge mst_bridge[MAX_DP_MST_DRM_BRIDGES];
+	struct msm_dp *msm_dp;
+	struct drm_dp_aux *dp_aux;
+	bool mst_session_hpd_state;
+	u32 max_streams;
+	struct mutex mst_lock;
+};
+
+struct msm_dp_mst_connector {
+	struct drm_connector connector;
+	struct drm_dp_mst_port *mst_port;
+	struct msm_dp *msm_dp;
+	struct msm_dp_panel *dp_panel;
+};
+
+#define to_msm_dp_mst_bridge(x)     container_of((x), struct msm_dp_mst_bridge, base)
+#define to_msm_dp_mst_bridge_priv(x) \
+		container_of((x), struct msm_dp_mst_bridge, obj)
+#define to_msm_dp_mst_bridge_priv_state(x) \
+		container_of((x), struct msm_dp_mst_bridge_state, base)
+#define to_msm_dp_mst_bridge_state(x) \
+		to_msm_dp_mst_bridge_priv_state((x)->obj.state)
+#define to_msm_dp_mst_connector(x) \
+		container_of((x), struct msm_dp_mst_connector, connector)
+int msm_dp_mst_drm_bridge_init(struct msm_dp *dp, struct drm_encoder *encoder);
+
+int msm_dp_mst_init(struct msm_dp *dp_display, u32 max_streams,
+		    u32 max_dpcd_transaction_bytes, struct drm_dp_aux *drm_aux);
+
+void msm_dp_mst_display_hpd_irq(struct msm_dp *dp_display);
+int msm_dp_mst_display_set_mgr_state(struct msm_dp *dp_display, bool state);
+
+#endif /* _DP_MST_DRM_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_panel.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_panel.c
@@ -0,0 +1,548 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ */
+
+#include "dp_panel.h"
+#include "dp_utils.h"
+
+#include <drm/drm_connector.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_of.h>
+#include <drm/drm_print.h>
+
+#define DP_MAX_NUM_DP_LANES	4
+#define DP_LINK_RATE_HBR2	540000 /* kbytes */
+
+struct msm_dp_panel_private {
+	struct device *dev;
+	struct drm_device *drm_dev;
+	struct msm_dp_panel msm_dp_panel;
+	struct drm_dp_aux *aux;
+	struct msm_dp_link *link;
+	struct msm_dp_catalog *catalog;
+	bool panel_on;
+};
+
+static void msm_dp_panel_read_psr_cap(struct msm_dp_panel_private *panel)
+{
+	ssize_t rlen;
+	struct msm_dp_panel *msm_dp_panel;
+
+	msm_dp_panel = &panel->msm_dp_panel;
+
+	/* edp sink */
+	if (msm_dp_panel->dpcd[DP_EDP_CONFIGURATION_CAP]) {
+		rlen = drm_dp_dpcd_read(panel->aux, DP_PSR_SUPPORT,
+				&msm_dp_panel->psr_cap, sizeof(msm_dp_panel->psr_cap));
+		if (rlen == sizeof(msm_dp_panel->psr_cap)) {
+			drm_dbg_dp(panel->drm_dev,
+				"psr version: 0x%x, psr_cap: 0x%x\n",
+				msm_dp_panel->psr_cap.version,
+				msm_dp_panel->psr_cap.capabilities);
+		} else
+			DRM_ERROR("failed to read psr info, rlen=%zd\n", rlen);
+	}
+}
+
+static int msm_dp_panel_read_dpcd(struct msm_dp_panel *msm_dp_panel)
+{
+	int rc;
+	struct msm_dp_panel_private *panel;
+	struct msm_dp_link_info *link_info;
+	u8 *dpcd, major, minor;
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+	dpcd = msm_dp_panel->dpcd;
+	rc = drm_dp_read_dpcd_caps(panel->aux, dpcd);
+	if (rc)
+		return rc;
+
+	msm_dp_panel->vsc_sdp_supported = drm_dp_vsc_sdp_supported(panel->aux, dpcd);
+	link_info = &msm_dp_panel->link_info;
+	link_info->revision = dpcd[DP_DPCD_REV];
+	major = (link_info->revision >> 4) & 0x0f;
+	minor = link_info->revision & 0x0f;
+
+	link_info->rate = drm_dp_max_link_rate(dpcd);
+	link_info->num_lanes = drm_dp_max_lane_count(dpcd);
+
+	/* Limit data lanes from data-lanes of endpoint property of dtsi */
+	if (link_info->num_lanes > msm_dp_panel->max_dp_lanes)
+		link_info->num_lanes = msm_dp_panel->max_dp_lanes;
+
+	/* Limit link rate from link-frequencies of endpoint property of dtsi */
+	if (link_info->rate > msm_dp_panel->max_dp_link_rate)
+		link_info->rate = msm_dp_panel->max_dp_link_rate;
+
+	drm_dbg_dp(panel->drm_dev, "version: %d.%d\n", major, minor);
+	drm_dbg_dp(panel->drm_dev, "link_rate=%d\n", link_info->rate);
+	drm_dbg_dp(panel->drm_dev, "lane_count=%d\n", link_info->num_lanes);
+
+	if (drm_dp_enhanced_frame_cap(dpcd))
+		link_info->capabilities |= DP_LINK_CAP_ENHANCED_FRAMING;
+
+	msm_dp_panel_read_psr_cap(panel);
+
+	return rc;
+}
+
+static u32 msm_dp_panel_get_supported_bpp(struct msm_dp_panel *msm_dp_panel,
+		u32 mode_edid_bpp, u32 mode_pclk_khz)
+{
+	const struct msm_dp_link_info *link_info;
+	const u32 max_supported_bpp = 30, min_supported_bpp = 18;
+	u32 bpp, data_rate_khz;
+
+	bpp = min(mode_edid_bpp, max_supported_bpp);
+
+	link_info = &msm_dp_panel->link_info;
+	data_rate_khz = link_info->num_lanes * link_info->rate * 8;
+
+	do {
+		if (mode_pclk_khz * bpp <= data_rate_khz)
+			return bpp;
+		bpp -= 6;
+	} while (bpp > min_supported_bpp);
+
+	return min_supported_bpp;
+}
+
+bool msm_dp_panel_read_mst_cap(struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_panel_private *panel;
+
+	if (!msm_dp_panel) {
+		DRM_ERROR("invalid input\n");
+		return false;
+	}
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+
+	return drm_dp_read_mst_cap(panel->aux, msm_dp_panel->dpcd);
+}
+
+int msm_dp_panel_read_link_caps(struct msm_dp_panel *msm_dp_panel,
+		struct drm_connector *connector)
+{
+	int rc, bw_code;
+	int count;
+	struct msm_dp_panel_private *panel;
+
+	if (!msm_dp_panel || !connector) {
+		DRM_ERROR("invalid input\n");
+		return -EINVAL;
+	}
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+
+	drm_dbg_dp(panel->drm_dev, "max_lanes=%d max_link_rate=%d\n",
+		msm_dp_panel->max_dp_lanes, msm_dp_panel->max_dp_link_rate);
+
+	rc = msm_dp_panel_read_dpcd(msm_dp_panel);
+	if (rc) {
+		DRM_ERROR("read dpcd failed %d\n", rc);
+		return rc;
+	}
+
+	bw_code = drm_dp_link_rate_to_bw_code(msm_dp_panel->link_info.rate);
+	if (!is_link_rate_valid(bw_code) ||
+			!is_lane_count_valid(msm_dp_panel->link_info.num_lanes) ||
+			(bw_code > msm_dp_panel->max_bw_code)) {
+		DRM_ERROR("Illegal link rate=%d lane=%d\n", msm_dp_panel->link_info.rate,
+				msm_dp_panel->link_info.num_lanes);
+		return -EINVAL;
+	}
+
+	if (drm_dp_is_branch(msm_dp_panel->dpcd)) {
+		count = drm_dp_read_sink_count(panel->aux);
+		if (!count) {
+			panel->link->sink_count = 0;
+			return -ENOTCONN;
+		}
+	}
+
+	return drm_dp_read_downstream_info(panel->aux, msm_dp_panel->dpcd,
+			 msm_dp_panel->downstream_ports);
+}
+
+int msm_dp_panel_read_edid(struct msm_dp_panel *msm_dp_panel, struct drm_connector *connector)
+{
+	struct msm_dp_panel_private *panel;
+
+	if (!msm_dp_panel || !connector) {
+		DRM_ERROR("invalid input\n");
+		return -EINVAL;
+	}
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+
+	drm_edid_free(msm_dp_panel->drm_edid);
+
+	msm_dp_panel->drm_edid = drm_edid_read_ddc(connector, &panel->aux->ddc);
+
+	drm_edid_connector_update(connector, msm_dp_panel->drm_edid);
+
+	if (!msm_dp_panel->drm_edid) {
+		DRM_ERROR("panel edid read failed\n");
+		/* check edid read fail is due to unplug */
+		if (!msm_dp_catalog_link_is_connected(panel->catalog)) {
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
+u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel,
+		u32 mode_edid_bpp, u32 mode_pclk_khz)
+{
+	struct msm_dp_panel_private *panel;
+	u32 bpp;
+
+	if (!msm_dp_panel || !mode_edid_bpp || !mode_pclk_khz) {
+		DRM_ERROR("invalid input\n");
+		return 0;
+	}
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+
+	if (msm_dp_panel->video_test)
+		bpp = msm_dp_link_bit_depth_to_bpp(
+				panel->link->test_video.test_bit_depth);
+	else
+		bpp = msm_dp_panel_get_supported_bpp(msm_dp_panel, mode_edid_bpp,
+				mode_pclk_khz);
+
+	return bpp;
+}
+
+int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel,
+	struct drm_connector *connector)
+{
+	if (!msm_dp_panel) {
+		DRM_ERROR("invalid input\n");
+		return -EINVAL;
+	}
+
+	if (msm_dp_panel->drm_edid)
+		return drm_edid_connector_add_modes(connector);
+
+	return 0;
+}
+
+static u8 msm_dp_panel_get_edid_checksum(const struct edid *edid)
+{
+	edid += edid->extensions;
+
+	return edid->checksum;
+}
+
+void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_panel_private *panel;
+
+	if (!msm_dp_panel) {
+		DRM_ERROR("invalid input\n");
+		return;
+	}
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+
+	if (panel->link->sink_request & DP_TEST_LINK_EDID_READ) {
+		/* FIXME: get rid of drm_edid_raw() */
+		const struct edid *edid = drm_edid_raw(msm_dp_panel->drm_edid);
+		u8 checksum;
+
+		if (edid)
+			checksum = msm_dp_panel_get_edid_checksum(edid);
+		else
+			checksum = msm_dp_panel->connector->real_edid_checksum;
+
+		msm_dp_link_send_edid_checksum(panel->link, checksum);
+		msm_dp_link_send_test_response(panel->link);
+	}
+}
+
+void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable)
+{
+	struct msm_dp_catalog *catalog;
+	struct msm_dp_panel_private *panel;
+
+	if (!msm_dp_panel) {
+		DRM_ERROR("invalid input\n");
+		return;
+	}
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+	catalog = panel->catalog;
+
+	if (!panel->panel_on) {
+		drm_dbg_dp(panel->drm_dev,
+				"DP panel not enabled, handle TPG on next on\n");
+		return;
+	}
+
+	if (!enable) {
+		msm_dp_catalog_panel_tpg_disable(catalog);
+		return;
+	}
+
+	drm_dbg_dp(panel->drm_dev, "calling catalog tpg_enable\n");
+	msm_dp_catalog_panel_tpg_enable(catalog, &panel->msm_dp_panel.msm_dp_mode.drm_mode);
+}
+
+static int msm_dp_panel_setup_vsc_sdp_yuv_420(struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_catalog *catalog;
+	struct msm_dp_panel_private *panel;
+	struct msm_dp_display_mode *msm_dp_mode;
+	struct drm_dp_vsc_sdp vsc_sdp_data;
+	struct dp_sdp vsc_sdp;
+	ssize_t len;
+
+	if (!msm_dp_panel) {
+		DRM_ERROR("invalid input\n");
+		return -EINVAL;
+	}
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+	catalog = panel->catalog;
+	msm_dp_mode = &msm_dp_panel->msm_dp_mode;
+	catalog->stream_id = msm_dp_panel->stream_id;
+
+	memset(&vsc_sdp_data, 0, sizeof(vsc_sdp_data));
+
+	/* VSC SDP header as per table 2-118 of DP 1.4 specification */
+	vsc_sdp_data.sdp_type = DP_SDP_VSC;
+	vsc_sdp_data.revision = 0x05;
+	vsc_sdp_data.length = 0x13;
+
+	/* VSC SDP Payload for DB16 */
+	vsc_sdp_data.pixelformat = DP_PIXELFORMAT_YUV420;
+	vsc_sdp_data.colorimetry = DP_COLORIMETRY_DEFAULT;
+
+	/* VSC SDP Payload for DB17 */
+	vsc_sdp_data.bpc = msm_dp_mode->bpp / 3;
+	vsc_sdp_data.dynamic_range = DP_DYNAMIC_RANGE_CTA;
+
+	/* VSC SDP Payload for DB18 */
+	vsc_sdp_data.content_type = DP_CONTENT_TYPE_GRAPHICS;
+
+	len = drm_dp_vsc_sdp_pack(&vsc_sdp_data, &vsc_sdp);
+	if (len < 0) {
+		DRM_ERROR("unable to pack vsc sdp\n");
+		return len;
+	}
+
+	msm_dp_catalog_panel_enable_vsc_sdp(catalog, &vsc_sdp);
+
+	return 0;
+}
+
+void msm_dp_panel_dump_regs(struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_catalog *catalog;
+	struct msm_dp_panel_private *panel;
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+	catalog = panel->catalog;
+
+	msm_dp_catalog_dump_regs(catalog);
+}
+
+int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel)
+{
+	u32 data, total_ver, total_hor;
+	struct msm_dp_catalog *catalog;
+	struct msm_dp_panel_private *panel;
+	struct drm_display_mode *drm_mode;
+	u32 width_blanking;
+	u32 sync_start;
+	u32 msm_dp_active;
+	u32 total;
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+	catalog = panel->catalog;
+	drm_mode = &panel->msm_dp_panel.msm_dp_mode.drm_mode;
+
+	drm_dbg_dp(panel->drm_dev, "width=%d hporch= %d %d %d\n",
+		drm_mode->hdisplay, drm_mode->htotal - drm_mode->hsync_end,
+		drm_mode->hsync_start - drm_mode->hdisplay,
+		drm_mode->hsync_end - drm_mode->hsync_start);
+
+	drm_dbg_dp(panel->drm_dev, "height=%d vporch= %d %d %d\n",
+		drm_mode->vdisplay, drm_mode->vtotal - drm_mode->vsync_end,
+		drm_mode->vsync_start - drm_mode->vdisplay,
+		drm_mode->vsync_end - drm_mode->vsync_start);
+
+	total_hor = drm_mode->htotal;
+
+	total_ver = drm_mode->vtotal;
+
+	data = total_ver;
+	data <<= 16;
+	data |= total_hor;
+
+	total = data;
+
+	data = (drm_mode->vtotal - drm_mode->vsync_start);
+	data <<= 16;
+	data |= (drm_mode->htotal - drm_mode->hsync_start);
+
+	sync_start = data;
+
+	data = drm_mode->vsync_end - drm_mode->vsync_start;
+	data <<= 16;
+	data |= (panel->msm_dp_panel.msm_dp_mode.v_active_low << 31);
+	data |= drm_mode->hsync_end - drm_mode->hsync_start;
+	data |= (panel->msm_dp_panel.msm_dp_mode.h_active_low << 15);
+
+	width_blanking = data;
+
+	data = drm_mode->vdisplay;
+	data <<= 16;
+	data |= drm_mode->hdisplay;
+
+	msm_dp_active = data;
+
+	msm_dp_catalog_panel_timing_cfg(catalog, total, sync_start, width_blanking, msm_dp_active);
+
+	if (msm_dp_panel->msm_dp_mode.out_fmt_is_yuv_420)
+		msm_dp_panel_setup_vsc_sdp_yuv_420(msm_dp_panel);
+
+	panel->panel_on = true;
+
+	return 0;
+}
+
+int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel)
+{
+	struct drm_display_mode *drm_mode;
+	struct msm_dp_panel_private *panel;
+
+	drm_mode = &msm_dp_panel->msm_dp_mode.drm_mode;
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+
+	/*
+	 * print resolution info as this is a result
+	 * of user initiated action of cable connection
+	 */
+	drm_dbg_dp(panel->drm_dev, "SET NEW RESOLUTION:\n");
+	drm_dbg_dp(panel->drm_dev, "%dx%d@%dfps\n",
+		drm_mode->hdisplay, drm_mode->vdisplay, drm_mode_vrefresh(drm_mode));
+	drm_dbg_dp(panel->drm_dev,
+			"h_porches(back|front|width) = (%d|%d|%d)\n",
+			drm_mode->htotal - drm_mode->hsync_end,
+			drm_mode->hsync_start - drm_mode->hdisplay,
+			drm_mode->hsync_end - drm_mode->hsync_start);
+	drm_dbg_dp(panel->drm_dev,
+			"v_porches(back|front|width) = (%d|%d|%d)\n",
+			drm_mode->vtotal - drm_mode->vsync_end,
+			drm_mode->vsync_start - drm_mode->vdisplay,
+			drm_mode->vsync_end - drm_mode->vsync_start);
+	drm_dbg_dp(panel->drm_dev, "pixel clock (KHz)=(%d)\n",
+				drm_mode->clock);
+	drm_dbg_dp(panel->drm_dev, "bpp = %d\n", msm_dp_panel->msm_dp_mode.bpp);
+
+	msm_dp_panel->msm_dp_mode.bpp = msm_dp_panel_get_mode_bpp(msm_dp_panel, msm_dp_panel->msm_dp_mode.bpp,
+						      msm_dp_panel->msm_dp_mode.drm_mode.clock);
+
+	drm_dbg_dp(panel->drm_dev, "updated bpp = %d\n",
+				msm_dp_panel->msm_dp_mode.bpp);
+
+	return 0;
+}
+
+static u32 msm_dp_panel_link_frequencies(struct device_node *of_node)
+{
+	struct device_node *endpoint;
+	u64 frequency = 0;
+	int cnt;
+
+	endpoint = of_graph_get_endpoint_by_regs(of_node, 1, 0); /* port@1 */
+	if (!endpoint)
+		return 0;
+
+	cnt = of_property_count_u64_elems(endpoint, "link-frequencies");
+
+	if (cnt > 0)
+		of_property_read_u64_index(endpoint, "link-frequencies",
+						cnt - 1, &frequency);
+	of_node_put(endpoint);
+
+	do_div(frequency,
+		10 * /* from symbol rate to link rate */
+		1000); /* kbytes */
+
+	return frequency;
+}
+
+static int msm_dp_panel_parse_dt(struct msm_dp_panel *msm_dp_panel)
+{
+	struct msm_dp_panel_private *panel;
+	struct device_node *of_node;
+	int cnt;
+
+	panel = container_of(msm_dp_panel, struct msm_dp_panel_private, msm_dp_panel);
+	of_node = panel->dev->of_node;
+
+	/*
+	 * data-lanes is the property of msm_dp_out endpoint
+	 */
+	cnt = drm_of_get_data_lanes_count_ep(of_node, 1, 0, 1, DP_MAX_NUM_DP_LANES);
+	if (cnt < 0) {
+		/* legacy code, data-lanes is the property of mdss_dp node */
+		cnt = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
+	}
+
+	if (cnt > 0)
+		msm_dp_panel->max_dp_lanes = cnt;
+	else
+		msm_dp_panel->max_dp_lanes = DP_MAX_NUM_DP_LANES; /* 4 lanes */
+
+	msm_dp_panel->max_dp_link_rate = msm_dp_panel_link_frequencies(of_node);
+	if (!msm_dp_panel->max_dp_link_rate)
+		msm_dp_panel->max_dp_link_rate = DP_LINK_RATE_HBR2;
+
+	return 0;
+}
+
+struct msm_dp_panel *msm_dp_panel_get(struct msm_dp_panel_in *in)
+{
+	struct msm_dp_panel_private *panel;
+	struct msm_dp_panel *msm_dp_panel;
+	int ret;
+
+	if (!in->dev || !in->catalog || !in->aux || !in->link) {
+		DRM_ERROR("invalid input\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	panel = devm_kzalloc(in->dev, sizeof(*panel), GFP_KERNEL);
+	if (!panel)
+		return ERR_PTR(-ENOMEM);
+
+	panel->dev = in->dev;
+	panel->aux = in->aux;
+	panel->catalog = in->catalog;
+	panel->link = in->link;
+
+	msm_dp_panel = &panel->msm_dp_panel;
+	msm_dp_panel->max_bw_code = DP_LINK_BW_8_1;
+
+	ret = msm_dp_panel_parse_dt(msm_dp_panel);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return msm_dp_panel;
+}
+
+void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel)
+{
+	if (!msm_dp_panel)
+		return;
+
+	drm_edid_free(msm_dp_panel->drm_edid);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_panel.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_panel.h
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DP_PANEL_H_
+#define _DP_PANEL_H_
+
+#include <drm/msm_drm.h>
+
+#include "dp_aux.h"
+#include "dp_link.h"
+
+struct edid;
+
+struct msm_dp_display_mode {
+	struct drm_display_mode drm_mode;
+	u32 bpp;
+	u32 h_active_low;
+	u32 v_active_low;
+	bool out_fmt_is_yuv_420;
+};
+
+struct msm_dp_panel_in {
+	struct device *dev;
+	struct drm_dp_aux *aux;
+	struct msm_dp_link *link;
+	struct msm_dp_catalog *catalog;
+};
+
+struct msm_dp_panel_psr {
+	u8 version;
+	u8 capabilities;
+};
+
+struct mst_caps {
+	u32 pbn_no_overhead;
+	u32 pbn;
+};
+
+struct msm_dp_panel {
+	/* dpcd raw data */
+	u8 dpcd[DP_RECEIVER_CAP_SIZE];
+	u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
+
+	struct msm_dp_link_info link_info;
+	const struct drm_edid *drm_edid;
+	struct drm_connector *connector;
+	struct msm_dp_display_mode msm_dp_mode;
+	struct msm_dp_panel_psr psr_cap;
+	bool video_test;
+	bool vsc_sdp_supported;
+
+	enum msm_dp_stream_id stream_id;
+
+	u32 max_dp_lanes;
+	u32 max_dp_link_rate;
+
+	u32 max_bw_code;
+
+	struct mst_caps mst_caps;
+};
+
+int msm_dp_panel_init_panel_info(struct msm_dp_panel *msm_dp_panel);
+int msm_dp_panel_deinit(struct msm_dp_panel *msm_dp_panel);
+int msm_dp_panel_timing_cfg(struct msm_dp_panel *msm_dp_panel);
+void msm_dp_panel_dump_regs(struct msm_dp_panel *msm_dp_panel);
+u32 msm_dp_panel_get_mode_bpp(struct msm_dp_panel *msm_dp_panel, u32 mode_max_bpp,
+	u32 mode_pclk_khz);
+int msm_dp_panel_read_link_caps(struct msm_dp_panel *msm_dp_panel,
+		struct drm_connector *connector);
+int msm_dp_panel_read_edid(struct msm_dp_panel *msm_dp_panel, struct drm_connector *connector);
+int msm_dp_panel_get_modes(struct msm_dp_panel *msm_dp_panel,
+		struct drm_connector *connector);
+void msm_dp_panel_handle_sink_request(struct msm_dp_panel *msm_dp_panel);
+void msm_dp_panel_tpg_config(struct msm_dp_panel *msm_dp_panel, bool enable);
+bool msm_dp_panel_read_mst_cap(struct msm_dp_panel *msm_dp_panel);
+
+/**
+ * is_link_rate_valid() - validates the link rate
+ * @lane_rate: link rate requested by the sink
+ *
+ * Returns true if the requested link rate is supported.
+ */
+static inline bool is_link_rate_valid(u32 bw_code)
+{
+	return (bw_code == DP_LINK_BW_1_62 ||
+		bw_code == DP_LINK_BW_2_7 ||
+		bw_code == DP_LINK_BW_5_4 ||
+		bw_code == DP_LINK_BW_8_1);
+}
+
+/**
+ * msm_dp_link_is_lane_count_valid() - validates the lane count
+ * @lane_count: lane count requested by the sink
+ *
+ * Returns true if the requested lane count is supported.
+ */
+static inline bool is_lane_count_valid(u32 lane_count)
+{
+	return (lane_count == 1 ||
+		lane_count == 2 ||
+		lane_count == 4);
+}
+
+struct msm_dp_panel *msm_dp_panel_get(struct msm_dp_panel_in *in);
+void msm_dp_panel_put(struct msm_dp_panel *msm_dp_panel);
+#endif /* _DP_PANEL_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_reg.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_reg.h
@@ -0,0 +1,368 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DP_REG_H_
+#define _DP_REG_H_
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+
+/* DP_TX Registers */
+#define REG_DP_HW_VERSION			(0x00000000)
+
+#define REG_DP_SW_RESET				(0x00000010)
+#define DP_SW_RESET				(0x00000001)
+
+#define REG_DP_PHY_CTRL				(0x00000014)
+#define DP_PHY_CTRL_SW_RESET_PLL		(0x00000001)
+#define DP_PHY_CTRL_SW_RESET			(0x00000004)
+
+#define REG_DP_CLK_CTRL				(0x00000018)
+#define REG_DP_CLK_ACTIVE			(0x0000001C)
+#define REG_DP_INTR_STATUS			(0x00000020)
+#define REG_DP_INTR_STATUS2			(0x00000024)
+#define REG_DP_INTR_STATUS3			(0x00000028)
+#define REG_DP_INTR_STATUS4			(0x0000002C)
+#define REG_DP_INTR_STATUS5			(0x00000034)
+
+#define PSR_UPDATE_INT				(0x00000001)
+#define PSR_CAPTURE_INT				(0x00000004)
+#define PSR_EXIT_INT				(0x00000010)
+#define PSR_UPDATE_ERROR_INT			(0x00000040)
+#define PSR_WAKE_ERROR_INT			(0x00000100)
+
+#define REG_DP_INTR_MASK4			(0x00000030)
+#define PSR_UPDATE_MASK				(0x00000001)
+#define PSR_CAPTURE_MASK			(0x00000002)
+#define PSR_EXIT_MASK				(0x00000004)
+#define PSR_UPDATE_ERROR_MASK			(0x00000008)
+#define PSR_WAKE_ERROR_MASK			(0x00000010)
+
+#define REG_DP_DP_HPD_CTRL			(0x00000000)
+#define DP_DP_HPD_CTRL_HPD_EN			(0x00000001)
+
+#define REG_DP_DP_HPD_INT_STATUS		(0x00000004)
+
+#define REG_DP_DP_HPD_INT_ACK			(0x00000008)
+#define DP_DP_HPD_PLUG_INT_ACK			(0x00000001)
+#define DP_DP_IRQ_HPD_INT_ACK			(0x00000002)
+#define DP_DP_HPD_REPLUG_INT_ACK		(0x00000004)
+#define DP_DP_HPD_UNPLUG_INT_ACK		(0x00000008)
+#define DP_DP_HPD_STATE_STATUS_BITS_MASK	(0x0000000F)
+#define DP_DP_HPD_STATE_STATUS_BITS_SHIFT	(0x1C)
+
+#define REG_DP_DP_HPD_INT_MASK			(0x0000000C)
+#define DP_DP_HPD_PLUG_INT_MASK			(0x00000001)
+#define DP_DP_IRQ_HPD_INT_MASK			(0x00000002)
+#define DP_DP_HPD_REPLUG_INT_MASK		(0x00000004)
+#define DP_DP_HPD_UNPLUG_INT_MASK		(0x00000008)
+#define DP_DP_HPD_INT_MASK			(DP_DP_HPD_PLUG_INT_MASK | \
+						DP_DP_IRQ_HPD_INT_MASK | \
+						DP_DP_HPD_REPLUG_INT_MASK | \
+						DP_DP_HPD_UNPLUG_INT_MASK)
+#define DP_DP_HPD_STATE_STATUS_CONNECTED	(0x40000000)
+#define DP_DP_HPD_STATE_STATUS_PENDING		(0x20000000)
+#define DP_DP_HPD_STATE_STATUS_DISCONNECTED	(0x00000000)
+#define DP_DP_HPD_STATE_STATUS_MASK		(0xE0000000)
+
+#define REG_DP_DP_HPD_REFTIMER			(0x00000018)
+#define DP_DP_HPD_REFTIMER_ENABLE		(1 << 16)
+
+#define REG_DP_DP_HPD_EVENT_TIME_0		(0x0000001C)
+#define REG_DP_DP_HPD_EVENT_TIME_1		(0x00000020)
+#define DP_DP_HPD_EVENT_TIME_0_VAL		(0x3E800FA)
+#define DP_DP_HPD_EVENT_TIME_1_VAL		(0x1F407D0)
+
+#define REG_DP_AUX_CTRL				(0x00000030)
+#define DP_AUX_CTRL_ENABLE			(0x00000001)
+#define DP_AUX_CTRL_RESET			(0x00000002)
+
+#define REG_DP_AUX_DATA				(0x00000034)
+#define DP_AUX_DATA_READ			(0x00000001)
+#define DP_AUX_DATA_WRITE			(0x00000000)
+#define DP_AUX_DATA_OFFSET			(0x00000008)
+#define DP_AUX_DATA_INDEX_OFFSET		(0x00000010)
+#define DP_AUX_DATA_MASK			(0x0000ff00)
+#define DP_AUX_DATA_INDEX_WRITE			(0x80000000)
+
+#define REG_DP_AUX_TRANS_CTRL			(0x00000038)
+#define DP_AUX_TRANS_CTRL_I2C			(0x00000100)
+#define DP_AUX_TRANS_CTRL_GO			(0x00000200)
+#define DP_AUX_TRANS_CTRL_NO_SEND_ADDR		(0x00000400)
+#define DP_AUX_TRANS_CTRL_NO_SEND_STOP		(0x00000800)
+
+#define REG_DP_TIMEOUT_COUNT			(0x0000003C)
+#define REG_DP_AUX_LIMITS			(0x00000040)
+#define REG_DP_AUX_STATUS			(0x00000044)
+
+#define DP_DPCD_CP_IRQ				(0x201)
+#define DP_DPCD_RXSTATUS			(0x69493)
+
+#define DP_INTERRUPT_TRANS_NUM			(0x000000A0)
+
+#define REG_DP_MAINLINK_CTRL			(0x00000000)
+#define DP_MAINLINK_CTRL_ENABLE			(0x00000001)
+#define DP_MAINLINK_CTRL_RESET			(0x00000002)
+#define DP_MAINLINK_CTRL_SW_BYPASS_SCRAMBLER	(0x00000010)
+#define DP_MAINLINK_CTRL_FLUSH_MODE_MASK	GENMASK(24, 23)
+#define DP_MAINLINK_FLUSH_MODE_UPDATE_SDP	FIELD_PREP(DP_MAINLINK_CTRL_FLUSH_MODE_MASK, 1)
+#define DP_MAINLINK_FLUSH_MODE_SDE_PERIPH_UPDATE	FIELD_PREP(DP_MAINLINK_CTRL_FLUSH_MODE_MASK, 3)
+#define DP_MAINLINK_FB_BOUNDARY_SEL		(0x02000000)
+
+#define REG_DP_STATE_CTRL			(0x00000004)
+#define DP_STATE_CTRL_LINK_TRAINING_PATTERN1	(0x00000001)
+#define DP_STATE_CTRL_LINK_TRAINING_PATTERN2	(0x00000002)
+#define DP_STATE_CTRL_LINK_TRAINING_PATTERN3	(0x00000004)
+#define DP_STATE_CTRL_LINK_TRAINING_PATTERN4	(0x00000008)
+#define DP_STATE_CTRL_LINK_SYMBOL_ERR_MEASURE	(0x00000010)
+#define DP_STATE_CTRL_LINK_PRBS7		(0x00000020)
+#define DP_STATE_CTRL_LINK_TEST_CUSTOM_PATTERN	(0x00000040)
+#define DP_STATE_CTRL_SEND_VIDEO		(0x00000080)
+#define DP_STATE_CTRL_PUSH_IDLE			(0x00000100)
+
+#define REG_DP_CONFIGURATION_CTRL		(0x00000008)
+#define DP_CONFIGURATION_CTRL_SYNC_ASYNC_CLK	(0x00000001)
+#define DP_CONFIGURATION_CTRL_STATIC_DYNAMIC_CN (0x00000002)
+#define DP_CONFIGURATION_CTRL_P_INTERLACED	(0x00000004)
+#define DP_CONFIGURATION_CTRL_INTERLACED_BTF	(0x00000008)
+#define DP_CONFIGURATION_CTRL_NUM_OF_LANES	(0x00000010)
+#define DP_CONFIGURATION_CTRL_ENHANCED_FRAMING	(0x00000040)
+#define DP_CONFIGURATION_CTRL_SEND_VSC		(0x00000080)
+#define DP_CONFIGURATION_CTRL_BPC		(0x00000100)
+#define DP_CONFIGURATION_CTRL_ASSR		(0x00000400)
+#define DP_CONFIGURATION_CTRL_RGB_YUV		(0x00000800)
+#define DP_CONFIGURATION_CTRL_LSCLK_DIV		(0x00002000)
+#define DP_CONFIGURATION_CTRL_NUM_OF_LANES_SHIFT	(0x04)
+#define DP_CONFIGURATION_CTRL_BPC_SHIFT		(0x08)
+#define DP_CONFIGURATION_CTRL_LSCLK_DIV_SHIFT	(0x0D)
+
+#define REG_DP_SOFTWARE_MVID			(0x00000010)
+#define REG_DP1_SOFTWARE_MVID			(0x00000414)
+#define REG_DP_SOFTWARE_NVID			(0x00000018)
+#define REG_DP1_SOFTWARE_NVID			(0x00000418)
+#define REG_DP_TOTAL_HOR_VER			(0x0000001C)
+#define REG_DP1_TOTAL_HOR_VER			(0x0000041C)
+#define REG_DP_START_HOR_VER_FROM_SYNC		(0x00000020)
+#define REG_DP_HSYNC_VSYNC_WIDTH_POLARITY	(0x00000024)
+#define REG_DP_ACTIVE_HOR_VER			(0x00000028)
+#define REG_DP_MISC1_MISC0			(0x0000002C)
+#define REG_DP1_MISC1_MISC0			(0x0000042C)
+
+#define DP_MISC0_SYNCHRONOUS_CLK		(0x00000001)
+#define DP_MISC0_COLORIMETRY_CFG_SHIFT		(0x00000001)
+#define DP_MISC0_TEST_BITS_DEPTH_SHIFT		(0x00000005)
+#define DP_MISC1_VSC_SDP			(0x00004000)
+
+#define DP_MISC0_COLORIMERY_CFG_LEGACY_RGB	(0)
+#define DP_MISC0_COLORIMERY_CFG_CEA_RGB		(0x04)
+
+#define REG_DP_VALID_BOUNDARY			(0x00000030)
+#define REG_DP_VALID_BOUNDARY_2			(0x00000034)
+
+#define REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING	(0x00000038)
+#define LANE0_MAPPING_SHIFT			(0x00000000)
+#define LANE1_MAPPING_SHIFT			(0x00000002)
+#define LANE2_MAPPING_SHIFT			(0x00000004)
+#define LANE3_MAPPING_SHIFT			(0x00000006)
+
+#define REG_DP_MAINLINK_READY			(0x00000040)
+#define DP_MAINLINK_READY_FOR_VIDEO		(0x00000001)
+#define DP_MAINLINK_READY_LINK_TRAINING_SHIFT	(0x00000003)
+
+#define REG_DP_MAINLINK_LEVELS			(0x00000044)
+#define DP_MAINLINK_SAFE_TO_EXIT_LEVEL_2	(0x00000002)
+
+
+#define REG_DP_TU				(0x0000004C)
+
+#define REG_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET	(0x00000054)
+#define DP_HBR2_ERM_PATTERN			(0x00010000)
+
+#define REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG0	(0x000000C0)
+#define REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG1	(0x000000C4)
+#define REG_DP_TEST_80BIT_CUSTOM_PATTERN_REG2	(0x000000C8)
+
+#define MMSS_DP_MISC1_MISC0			(0x0000002C)
+#define MMSS_DP_AUDIO_TIMING_GEN		(0x00000080)
+#define MMSS_DP_AUDIO_TIMING_RBR_32		(0x00000084)
+#define MMSS_DP_AUDIO_TIMING_HBR_32		(0x00000088)
+#define MMSS_DP_AUDIO_TIMING_RBR_44		(0x0000008C)
+#define MMSS_DP_AUDIO_TIMING_HBR_44		(0x00000090)
+#define MMSS_DP_AUDIO_TIMING_RBR_48		(0x00000094)
+#define MMSS_DP_AUDIO_TIMING_HBR_48		(0x00000098)
+
+#define REG_PSR_CONFIG				(0x00000100)
+#define DISABLE_PSR				(0x00000000)
+#define PSR1_SUPPORTED				(0x00000001)
+#define PSR2_WITHOUT_FRAMESYNC			(0x00000002)
+#define PSR2_WITH_FRAMESYNC			(0x00000003)
+
+#define REG_PSR_CMD				(0x00000110)
+#define PSR_ENTER				(0x00000001)
+#define PSR_EXIT				(0x00000002)
+
+#define MMSS_DP_PSR_CRC_RG			(0x00000154)
+#define MMSS_DP_PSR_CRC_B			(0x00000158)
+
+#define REG_DP_COMPRESSION_MODE_CTRL		(0x00000180)
+
+#define MMSS_DP_AUDIO_CFG			(0x00000200)
+#define MMSS_DP_AUDIO_STATUS			(0x00000204)
+#define MMSS_DP_AUDIO_PKT_CTRL			(0x00000208)
+#define MMSS_DP_AUDIO_PKT_CTRL2			(0x0000020C)
+#define MMSS_DP_AUDIO_ACR_CTRL			(0x00000210)
+#define MMSS_DP_AUDIO_CTRL_RESET		(0x00000214)
+
+#define MMSS_DP_SDP_CFG				(0x00000228)
+#define MMSS_DP1_SDP_CFG			(0x000004E0)
+#define GEN0_SDP_EN				(0x00020000)
+#define MMSS_DP_SDP_CFG2			(0x0000022C)
+#define MMSS_DP1_SDP_CFG2			(0x000004E4)
+
+#define MMSS_DP_AUDIO_TIMESTAMP_0		(0x00000230)
+#define MMSS_DP_AUDIO_TIMESTAMP_1		(0x00000234)
+#define GENERIC0_SDPSIZE_VALID			(0x00010000)
+
+#define MMSS_DP_AUDIO_STREAM_0			(0x00000240)
+#define MMSS_DP_AUDIO_STREAM_1			(0x00000244)
+
+#define MMSS_DP_SDP_CFG3			(0x0000024c)
+#define MMSS_DP1_SDP_CFG3			(0x000004E8)
+
+#define UPDATE_SDP				(0x00000001)
+
+#define MMSS_DP_EXTENSION_0			(0x00000250)
+#define MMSS_DP_EXTENSION_1			(0x00000254)
+#define MMSS_DP_EXTENSION_2			(0x00000258)
+#define MMSS_DP_EXTENSION_3			(0x0000025C)
+#define MMSS_DP_EXTENSION_4			(0x00000260)
+#define MMSS_DP_EXTENSION_5			(0x00000264)
+#define MMSS_DP_EXTENSION_6			(0x00000268)
+#define MMSS_DP_EXTENSION_7			(0x0000026C)
+#define MMSS_DP_EXTENSION_8			(0x00000270)
+#define MMSS_DP_EXTENSION_9			(0x00000274)
+#define MMSS_DP_AUDIO_COPYMANAGEMENT_0		(0x00000278)
+#define MMSS_DP_AUDIO_COPYMANAGEMENT_1		(0x0000027C)
+#define MMSS_DP_AUDIO_COPYMANAGEMENT_2		(0x00000280)
+#define MMSS_DP_AUDIO_COPYMANAGEMENT_3		(0x00000284)
+#define MMSS_DP_AUDIO_COPYMANAGEMENT_4		(0x00000288)
+#define MMSS_DP_AUDIO_COPYMANAGEMENT_5		(0x0000028C)
+#define MMSS_DP_AUDIO_ISRC_0			(0x00000290)
+#define MMSS_DP_AUDIO_ISRC_1			(0x00000294)
+#define MMSS_DP_AUDIO_ISRC_2			(0x00000298)
+#define MMSS_DP_AUDIO_ISRC_3			(0x0000029C)
+#define MMSS_DP_AUDIO_ISRC_4			(0x000002A0)
+#define MMSS_DP_AUDIO_ISRC_5			(0x000002A4)
+#define MMSS_DP_AUDIO_INFOFRAME_0		(0x000002A8)
+#define MMSS_DP_AUDIO_INFOFRAME_1		(0x000002AC)
+#define MMSS_DP_AUDIO_INFOFRAME_2		(0x000002B0)
+
+#define MMSS_DP_GENERIC0_0			(0x00000300)
+#define MMSS_DP_GENERIC0_1			(0x00000304)
+#define MMSS_DP_GENERIC0_2			(0x00000308)
+#define MMSS_DP_GENERIC0_3			(0x0000030C)
+#define MMSS_DP_GENERIC0_4			(0x00000310)
+#define MMSS_DP_GENERIC0_5			(0x00000314)
+#define MMSS_DP_GENERIC0_6			(0x00000318)
+#define MMSS_DP_GENERIC0_7			(0x0000031C)
+#define MMSS_DP_GENERIC0_8			(0x00000320)
+#define MMSS_DP_GENERIC0_9			(0x00000324)
+#define MMSS_DP_GENERIC1_0			(0x00000328)
+#define MMSS_DP_GENERIC1_1			(0x0000032C)
+#define MMSS_DP_GENERIC1_2			(0x00000330)
+#define MMSS_DP_GENERIC1_3			(0x00000334)
+#define MMSS_DP_GENERIC1_4			(0x00000338)
+#define MMSS_DP_GENERIC1_5			(0x0000033C)
+#define MMSS_DP_GENERIC1_6			(0x00000340)
+#define MMSS_DP_GENERIC1_7			(0x00000344)
+#define MMSS_DP_GENERIC1_8			(0x00000348)
+#define MMSS_DP_GENERIC1_9			(0x0000034C)
+
+#define MMSS_DP1_GENERIC0_0			(0x00000490)
+
+#define MMSS_DP_VSCEXT_0			(0x000002D0)
+#define MMSS_DP_VSCEXT_1			(0x000002D4)
+#define MMSS_DP_VSCEXT_2			(0x000002D8)
+#define MMSS_DP_VSCEXT_3			(0x000002DC)
+#define MMSS_DP_VSCEXT_4			(0x000002E0)
+#define MMSS_DP_VSCEXT_5			(0x000002E4)
+#define MMSS_DP_VSCEXT_6			(0x000002E8)
+#define MMSS_DP_VSCEXT_7			(0x000002EC)
+#define MMSS_DP_VSCEXT_8			(0x000002F0)
+#define MMSS_DP_VSCEXT_9			(0x000002F4)
+
+#define MMSS_DP_BIST_ENABLE			(0x00000000)
+#define DP_BIST_ENABLE_DPBIST_EN		(0x00000001)
+
+#define MMSS_DP_TIMING_ENGINE_EN		(0x00000010)
+#define DP_TIMING_ENGINE_EN_EN			(0x00000001)
+
+#define MMSS_DP_INTF_CONFIG			(0x00000014)
+#define MMSS_DP_INTF_HSYNC_CTL			(0x00000018)
+#define MMSS_DP_INTF_VSYNC_PERIOD_F0		(0x0000001C)
+#define MMSS_DP_INTF_VSYNC_PERIOD_F1		(0x00000020)
+#define MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F0	(0x00000024)
+#define MMSS_DP_INTF_VSYNC_PULSE_WIDTH_F1	(0x00000028)
+#define MMSS_INTF_DISPLAY_V_START_F0		(0x0000002C)
+#define MMSS_INTF_DISPLAY_V_START_F1		(0x00000030)
+#define MMSS_DP_INTF_DISPLAY_V_END_F0		(0x00000034)
+#define MMSS_DP_INTF_DISPLAY_V_END_F1		(0x00000038)
+#define MMSS_DP_INTF_ACTIVE_V_START_F0		(0x0000003C)
+#define MMSS_DP_INTF_ACTIVE_V_START_F1		(0x00000040)
+#define MMSS_DP_INTF_ACTIVE_V_END_F0		(0x00000044)
+#define MMSS_DP_INTF_ACTIVE_V_END_F1		(0x00000048)
+#define MMSS_DP_INTF_DISPLAY_HCTL		(0x0000004C)
+#define MMSS_DP_INTF_ACTIVE_HCTL		(0x00000050)
+#define MMSS_DP_INTF_POLARITY_CTL		(0x00000058)
+
+#define MMSS_DP_TPG_MAIN_CONTROL		(0x00000060)
+#define MMSS_DP_DSC_DTO				(0x0000007C)
+#define DP_TPG_CHECKERED_RECT_PATTERN		(0x00000100)
+
+#define MMSS_DP_TPG_VIDEO_CONFIG		(0x00000064)
+#define DP_TPG_VIDEO_CONFIG_BPP_8BIT		(0x00000001)
+#define DP_TPG_VIDEO_CONFIG_RGB			(0x00000004)
+
+#define MMSS_DP_ASYNC_FIFO_CONFIG		(0x00000088)
+
+#define REG_DP_PHY_AUX_INTERRUPT_CLEAR          (0x0000004C)
+#define REG_DP_PHY_AUX_BIST_CFG			(0x00000050)
+#define REG_DP_PHY_AUX_INTERRUPT_STATUS         (0x000000BC)
+
+/* DP MST related registers */
+#define REG_DP_MST_ACT                          (0x00000500)
+#define REG_DP_DP0_RG				(0x000004F8)
+#define REG_DP_DP1_RG				(0x000004FC)
+#define REG_DP_DP0_TIMESLOT_1_32		(0x00000404)
+#define REG_DP_DP0_TIMESLOT_33_63		(0x00000408)
+#define REG_DP_DP1_TIMESLOT_1_32		(0x0000040C)
+#define REG_DP_DP1_TIMESLOT_33_63		(0x00000410)
+
+/* DP HDCP 1.3 registers */
+#define DP_HDCP_CTRL                                   (0x0A0)
+#define DP_HDCP_STATUS                                 (0x0A4)
+#define DP_HDCP_SW_UPPER_AKSV                          (0x098)
+#define DP_HDCP_SW_LOWER_AKSV                          (0x09C)
+#define DP_HDCP_ENTROPY_CTRL0                          (0x350)
+#define DP_HDCP_ENTROPY_CTRL1                          (0x35C)
+#define DP_HDCP_SHA_STATUS                             (0x0C8)
+#define DP_HDCP_RCVPORT_DATA2_0                        (0x0B0)
+#define DP_HDCP_RCVPORT_DATA3                          (0x0A4)
+#define DP_HDCP_RCVPORT_DATA4                          (0x0A8)
+#define DP_HDCP_RCVPORT_DATA5                          (0x0C0)
+#define DP_HDCP_RCVPORT_DATA6                          (0x0C4)
+
+#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_SHA_CTRL           (0x024)
+#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_SHA_DATA           (0x028)
+#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA0      (0x004)
+#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA1      (0x008)
+#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA7      (0x00C)
+#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA8      (0x010)
+#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA9      (0x014)
+#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA10     (0x018)
+#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA11     (0x01C)
+#define HDCP_SEC_DP_TZ_HV_HLOS_HDCP_RCVPORT_DATA12     (0x020)
+
+#endif /* _DP_REG_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_utils.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_utils.c
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/types.h>
+
+#include "dp_utils.h"
+
+#define DP_SDP_HEADER_SIZE		8
+
+u8 msm_dp_utils_get_g0_value(u8 data)
+{
+	u8 c[4];
+	u8 g[4];
+	u8 ret_data = 0;
+	u8 i;
+
+	for (i = 0; i < 4; i++)
+		c[i] = (data >> i) & 0x01;
+
+	g[0] = c[3];
+	g[1] = c[0] ^ c[3];
+	g[2] = c[1];
+	g[3] = c[2];
+
+	for (i = 0; i < 4; i++)
+		ret_data = ((g[i] & 0x01) << i) | ret_data;
+
+	return ret_data;
+}
+
+u8 msm_dp_utils_get_g1_value(u8 data)
+{
+	u8 c[4];
+	u8 g[4];
+	u8 ret_data = 0;
+	u8 i;
+
+	for (i = 0; i < 4; i++)
+		c[i] = (data >> i) & 0x01;
+
+	g[0] = c[0] ^ c[3];
+	g[1] = c[0] ^ c[1] ^ c[3];
+	g[2] = c[1] ^ c[2];
+	g[3] = c[2] ^ c[3];
+
+	for (i = 0; i < 4; i++)
+		ret_data = ((g[i] & 0x01) << i) | ret_data;
+
+	return ret_data;
+}
+
+u8 msm_dp_utils_calculate_parity(u32 data)
+{
+	u8 x0 = 0;
+	u8 x1 = 0;
+	u8 ci = 0;
+	u8 iData = 0;
+	u8 i = 0;
+	u8 parity_byte;
+	u8 num_byte = (data & 0xFF00) > 0 ? 8 : 2;
+
+	for (i = 0; i < num_byte; i++) {
+		iData = (data >> i * 4) & 0xF;
+
+		ci = iData ^ x1;
+		x1 = x0 ^ msm_dp_utils_get_g1_value(ci);
+		x0 = msm_dp_utils_get_g0_value(ci);
+	}
+
+	parity_byte = x1 | (x0 << 4);
+
+	return parity_byte;
+}
+
+ssize_t msm_dp_utils_pack_sdp_header(struct dp_sdp_header *sdp_header, u32 *header_buff)
+{
+	size_t length;
+
+	length = sizeof(header_buff);
+	if (length < DP_SDP_HEADER_SIZE)
+		return -ENOSPC;
+
+	header_buff[0] = FIELD_PREP(HEADER_0_MASK, sdp_header->HB0) |
+		FIELD_PREP(PARITY_0_MASK, msm_dp_utils_calculate_parity(sdp_header->HB0)) |
+		FIELD_PREP(HEADER_1_MASK, sdp_header->HB1) |
+		FIELD_PREP(PARITY_1_MASK, msm_dp_utils_calculate_parity(sdp_header->HB1));
+
+	header_buff[1] = FIELD_PREP(HEADER_2_MASK, sdp_header->HB2) |
+		FIELD_PREP(PARITY_2_MASK, msm_dp_utils_calculate_parity(sdp_header->HB2)) |
+		FIELD_PREP(HEADER_3_MASK, sdp_header->HB3) |
+		FIELD_PREP(PARITY_3_MASK, msm_dp_utils_calculate_parity(sdp_header->HB3));
+
+	return length;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dp/dp_utils.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dp/dp_utils.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DP_UTILS_H_
+#define _DP_UTILS_H_
+
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <drm/display/drm_dp_helper.h>
+
+#define HEADER_BYTE_0_BIT	 0
+#define PARITY_BYTE_0_BIT	 8
+#define HEADER_BYTE_1_BIT	16
+#define PARITY_BYTE_1_BIT	24
+#define HEADER_BYTE_2_BIT	 0
+#define PARITY_BYTE_2_BIT	 8
+#define HEADER_BYTE_3_BIT	16
+#define PARITY_BYTE_3_BIT	24
+
+#define HEADER_0_MASK	    GENMASK(7, 0)
+#define PARITY_0_MASK	    GENMASK(15, 8)
+#define HEADER_1_MASK	    GENMASK(23, 16)
+#define PARITY_1_MASK	    GENMASK(31, 24)
+#define HEADER_2_MASK	    GENMASK(7, 0)
+#define PARITY_2_MASK	    GENMASK(15, 8)
+#define HEADER_3_MASK	    GENMASK(23, 16)
+#define PARITY_3_MASK	    GENMASK(31, 24)
+
+u8 msm_dp_utils_get_g0_value(u8 data);
+u8 msm_dp_utils_get_g1_value(u8 data);
+u8 msm_dp_utils_calculate_parity(u32 data);
+ssize_t msm_dp_utils_pack_sdp_header(struct dp_sdp_header *sdp_header, u32 *header_buff);
+
+#endif /* _DP_UTILS_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/dsi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/dsi.c
@@ -0,0 +1,261 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ */
+
+#include "dsi.h"
+
+bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi)
+{
+	unsigned long host_flags = msm_dsi_host_get_mode_flags(msm_dsi->host);
+
+	return !(host_flags & MIPI_DSI_MODE_VIDEO);
+}
+
+struct drm_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi)
+{
+	return msm_dsi_host_get_dsc_config(msm_dsi->host);
+}
+
+bool msm_dsi_wide_bus_enabled(struct msm_dsi *msm_dsi)
+{
+	return msm_dsi_host_is_wide_bus_enabled(msm_dsi->host);
+}
+
+static int dsi_get_phy(struct msm_dsi *msm_dsi)
+{
+	struct platform_device *pdev = msm_dsi->pdev;
+	struct platform_device *phy_pdev;
+	struct device_node *phy_node;
+
+	phy_node = of_parse_phandle(pdev->dev.of_node, "phys", 0);
+	if (!phy_node) {
+		DRM_DEV_ERROR(&pdev->dev, "cannot find phy device\n");
+		return -ENXIO;
+	}
+
+	phy_pdev = of_find_device_by_node(phy_node);
+	if (phy_pdev) {
+		msm_dsi->phy = platform_get_drvdata(phy_pdev);
+		msm_dsi->phy_dev = &phy_pdev->dev;
+	}
+
+	of_node_put(phy_node);
+
+	if (!phy_pdev) {
+		DRM_DEV_ERROR(&pdev->dev, "%s: phy driver is not ready\n", __func__);
+		return -EPROBE_DEFER;
+	}
+	if (!msm_dsi->phy) {
+		put_device(&phy_pdev->dev);
+		DRM_DEV_ERROR(&pdev->dev, "%s: phy driver is not ready\n", __func__);
+		return -EPROBE_DEFER;
+	}
+
+	return 0;
+}
+
+static void dsi_destroy(struct msm_dsi *msm_dsi)
+{
+	if (!msm_dsi)
+		return;
+
+	msm_dsi_manager_unregister(msm_dsi);
+
+	if (msm_dsi->phy_dev) {
+		put_device(msm_dsi->phy_dev);
+		msm_dsi->phy = NULL;
+		msm_dsi->phy_dev = NULL;
+	}
+
+	if (msm_dsi->host) {
+		msm_dsi_host_destroy(msm_dsi->host);
+		msm_dsi->host = NULL;
+	}
+
+	platform_set_drvdata(msm_dsi->pdev, NULL);
+}
+
+static struct msm_dsi *dsi_init(struct platform_device *pdev)
+{
+	struct msm_dsi *msm_dsi;
+	int ret;
+
+	if (!pdev)
+		return ERR_PTR(-ENXIO);
+
+	msm_dsi = devm_kzalloc(&pdev->dev, sizeof(*msm_dsi), GFP_KERNEL);
+	if (!msm_dsi)
+		return ERR_PTR(-ENOMEM);
+	DBG("dsi probed=%p", msm_dsi);
+
+	msm_dsi->id = -1;
+	msm_dsi->pdev = pdev;
+	platform_set_drvdata(pdev, msm_dsi);
+
+	/* Init dsi host */
+	ret = msm_dsi_host_init(msm_dsi);
+	if (ret)
+		goto destroy_dsi;
+
+	/* GET dsi PHY */
+	ret = dsi_get_phy(msm_dsi);
+	if (ret)
+		goto destroy_dsi;
+
+	/* Register to dsi manager */
+	ret = msm_dsi_manager_register(msm_dsi);
+	if (ret)
+		goto destroy_dsi;
+
+	return msm_dsi;
+
+destroy_dsi:
+	dsi_destroy(msm_dsi);
+	return ERR_PTR(ret);
+}
+
+static int dsi_bind(struct device *dev, struct device *master, void *data)
+{
+	struct msm_drm_private *priv = dev_get_drvdata(master);
+	struct msm_dsi *msm_dsi = dev_get_drvdata(dev);
+
+	priv->dsi[msm_dsi->id] = msm_dsi;
+
+	return 0;
+}
+
+static void dsi_unbind(struct device *dev, struct device *master,
+		void *data)
+{
+	struct msm_drm_private *priv = dev_get_drvdata(master);
+	struct msm_dsi *msm_dsi = dev_get_drvdata(dev);
+
+	msm_dsi_tx_buf_free(msm_dsi->host);
+	priv->dsi[msm_dsi->id] = NULL;
+}
+
+static const struct component_ops dsi_ops = {
+	.bind   = dsi_bind,
+	.unbind = dsi_unbind,
+};
+
+int dsi_dev_attach(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &dsi_ops);
+}
+
+void dsi_dev_detach(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dsi_ops);
+}
+
+static int dsi_dev_probe(struct platform_device *pdev)
+{
+	struct msm_dsi *msm_dsi;
+
+	DBG("");
+	msm_dsi = dsi_init(pdev);
+	if (IS_ERR(msm_dsi)) {
+		/* Don't fail the bind if the dsi port is not connected */
+		if (PTR_ERR(msm_dsi) == -ENODEV)
+			return 0;
+		else
+			return PTR_ERR(msm_dsi);
+	}
+
+	return 0;
+}
+
+static void dsi_dev_remove(struct platform_device *pdev)
+{
+	struct msm_dsi *msm_dsi = platform_get_drvdata(pdev);
+
+	DBG("");
+	dsi_destroy(msm_dsi);
+}
+
+static const struct of_device_id dt_match[] = {
+	{ .compatible = "qcom,mdss-dsi-ctrl" },
+
+	/* Deprecated, don't use */
+	{ .compatible = "qcom,dsi-ctrl-6g-qcm2290" },
+	{}
+};
+
+static const struct dev_pm_ops dsi_pm_ops = {
+	SET_RUNTIME_PM_OPS(msm_dsi_runtime_suspend, msm_dsi_runtime_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+};
+
+static struct platform_driver dsi_driver = {
+	.probe = dsi_dev_probe,
+	.remove_new = dsi_dev_remove,
+	.driver = {
+		.name = "msm_dsi",
+		.of_match_table = dt_match,
+		.pm = &dsi_pm_ops,
+	},
+};
+
+void __init msm_dsi_register(void)
+{
+	DBG("");
+	msm_dsi_phy_driver_register();
+	platform_driver_register(&dsi_driver);
+}
+
+void __exit msm_dsi_unregister(void)
+{
+	DBG("");
+	msm_dsi_phy_driver_unregister();
+	platform_driver_unregister(&dsi_driver);
+}
+
+int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
+			 struct drm_encoder *encoder)
+{
+	int ret;
+
+	msm_dsi->dev = dev;
+
+	ret = msm_dsi_host_modeset_init(msm_dsi->host, dev);
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev, "failed to modeset init host: %d\n", ret);
+		return ret;
+	}
+
+	if (msm_dsi_is_bonded_dsi(msm_dsi) &&
+	    !msm_dsi_is_master_dsi(msm_dsi)) {
+		/*
+		 * Do not return an eror here,
+		 * Just skip creating encoder/connector for the slave-DSI.
+		 */
+		return 0;
+	}
+
+	msm_dsi->encoder = encoder;
+
+	ret = msm_dsi_manager_bridge_init(msm_dsi);
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev, "failed to create dsi bridge: %d\n", ret);
+		return ret;
+	}
+
+	ret = msm_dsi_manager_ext_bridge_init(msm_dsi->id);
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev,
+			"failed to create dsi connector: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct msm_dsi *msm_dsi)
+{
+	msm_dsi_host_snapshot(disp_state, msm_dsi->host);
+	msm_dsi_phy_snapshot(disp_state, msm_dsi->phy);
+}
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/dsi.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/dsi.h
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __DSI_CONNECTOR_H__
+#define __DSI_CONNECTOR_H__
+
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include <drm/drm_bridge.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_mipi_dsi.h>
+
+#include "msm_drv.h"
+#include "disp/msm_disp_snapshot.h"
+
+#define DSI_0	0
+#define DSI_1	1
+#define DSI_MAX	2
+
+struct msm_dsi_phy_shared_timings;
+struct msm_dsi_phy_clk_request;
+
+enum msm_dsi_phy_usecase {
+	MSM_DSI_PHY_STANDALONE,
+	MSM_DSI_PHY_MASTER,
+	MSM_DSI_PHY_SLAVE,
+};
+
+#define DSI_BUS_CLK_MAX		4
+
+struct msm_dsi {
+	struct drm_device *dev;
+	struct platform_device *pdev;
+
+	/* internal dsi bridge attached to MDP interface */
+	struct drm_bridge *bridge;
+
+	struct mipi_dsi_host *host;
+	struct msm_dsi_phy *phy;
+
+	/*
+	 * external_bridge connected to dsi bridge output
+	 */
+	struct drm_bridge *external_bridge;
+
+	struct device *phy_dev;
+	bool phy_enabled;
+
+	/* the encoder we are hooked to (outside of dsi block) */
+	struct drm_encoder *encoder;
+
+	int id;
+};
+
+/* dsi manager */
+int msm_dsi_manager_bridge_init(struct msm_dsi *msm_dsi);
+int msm_dsi_manager_ext_bridge_init(u8 id);
+int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg);
+bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len);
+int msm_dsi_manager_register(struct msm_dsi *msm_dsi);
+void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi);
+void msm_dsi_manager_tpg_enable(void);
+
+/* msm dsi */
+static inline bool msm_dsi_device_connected(struct msm_dsi *msm_dsi)
+{
+	return msm_dsi->external_bridge;
+}
+
+/* dsi host */
+struct msm_dsi_host;
+int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
+					const struct mipi_dsi_msg *msg);
+void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
+					const struct mipi_dsi_msg *msg);
+int msm_dsi_host_cmd_tx(struct mipi_dsi_host *host,
+					const struct mipi_dsi_msg *msg);
+int msm_dsi_host_cmd_rx(struct mipi_dsi_host *host,
+					const struct mipi_dsi_msg *msg);
+void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host *host,
+					u32 dma_base, u32 len);
+int msm_dsi_host_enable(struct mipi_dsi_host *host);
+int msm_dsi_host_disable(struct mipi_dsi_host *host);
+void msm_dsi_host_enable_irq(struct mipi_dsi_host *host);
+void msm_dsi_host_disable_irq(struct mipi_dsi_host *host);
+int msm_dsi_host_power_on(struct mipi_dsi_host *host,
+			struct msm_dsi_phy_shared_timings *phy_shared_timings,
+			bool is_bonded_dsi, struct msm_dsi_phy *phy);
+int msm_dsi_host_power_off(struct mipi_dsi_host *host);
+int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host,
+				  const struct drm_display_mode *mode);
+enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
+					    const struct drm_display_mode *mode);
+unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host);
+int msm_dsi_host_register(struct mipi_dsi_host *host);
+void msm_dsi_host_unregister(struct mipi_dsi_host *host);
+void msm_dsi_host_set_phy_mode(struct mipi_dsi_host *host,
+			struct msm_dsi_phy *src_phy);
+int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
+			struct msm_dsi_phy *src_phy);
+void msm_dsi_host_reset_phy(struct mipi_dsi_host *host);
+void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host,
+	struct msm_dsi_phy_clk_request *clk_req,
+	bool is_bonded_dsi);
+void msm_dsi_host_destroy(struct mipi_dsi_host *host);
+int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
+					struct drm_device *dev);
+int msm_dsi_host_init(struct msm_dsi *msm_dsi);
+int msm_dsi_runtime_suspend(struct device *dev);
+int msm_dsi_runtime_resume(struct device *dev);
+int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host);
+int dsi_link_clk_set_rate_v2(struct msm_dsi_host *msm_host);
+int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host);
+int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host);
+void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host);
+void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host);
+unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_dsi,
+				    const struct drm_display_mode *mode);
+int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size);
+int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size);
+void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host);
+void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host);
+void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host);
+void msm_dsi_tx_buf_free(struct mipi_dsi_host *mipi_host);
+int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *iova);
+int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *iova);
+int dsi_clk_init_v2(struct msm_dsi_host *msm_host);
+int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host);
+int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi);
+int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi);
+void msm_dsi_host_snapshot(struct msm_disp_state *disp_state, struct mipi_dsi_host *host);
+void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host);
+struct drm_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host *host);
+bool msm_dsi_host_is_wide_bus_enabled(struct mipi_dsi_host *host);
+
+/* dsi phy */
+struct msm_dsi_phy;
+struct msm_dsi_phy_shared_timings {
+	u32 clk_post;
+	u32 clk_pre;
+	bool clk_pre_inc_by_2;
+	bool byte_intf_clk_div_2;
+};
+
+struct msm_dsi_phy_clk_request {
+	unsigned long bitclk_rate;
+	unsigned long escclk_rate;
+};
+
+void msm_dsi_phy_driver_register(void);
+void msm_dsi_phy_driver_unregister(void);
+int msm_dsi_phy_enable(struct msm_dsi_phy *phy,
+			struct msm_dsi_phy_clk_request *clk_req,
+			struct msm_dsi_phy_shared_timings *shared_timings);
+void msm_dsi_phy_disable(struct msm_dsi_phy *phy);
+void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,
+			     enum msm_dsi_phy_usecase uc);
+void msm_dsi_phy_pll_save_state(struct msm_dsi_phy *phy);
+int msm_dsi_phy_pll_restore_state(struct msm_dsi_phy *phy);
+void msm_dsi_phy_snapshot(struct msm_disp_state *disp_state, struct msm_dsi_phy *phy);
+bool msm_dsi_phy_set_continuous_clock(struct msm_dsi_phy *phy, bool enable);
+
+#endif /* __DSI_CONNECTOR_H__ */
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/dsi_cfg.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/dsi_cfg.c
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ */
+
+#include "dsi_cfg.h"
+
+static const char * const dsi_v2_bus_clk_names[] = {
+	"core_mmss", "iface", "bus",
+};
+
+static const struct regulator_bulk_data apq8064_dsi_regulators[] = {
+	{ .supply = "vdda", .init_load_uA = 100000 },	/* 1.2 V */
+	{ .supply = "avdd", .init_load_uA = 10000 },	/* 3.0 V */
+	{ .supply = "vddio", .init_load_uA = 100000 },	/* 1.8 V */
+};
+
+static const struct msm_dsi_config apq8064_dsi_cfg = {
+	.io_offset = 0,
+	.regulator_data = apq8064_dsi_regulators,
+	.num_regulators = ARRAY_SIZE(apq8064_dsi_regulators),
+	.bus_clk_names = dsi_v2_bus_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_v2_bus_clk_names),
+	.io_start = {
+		{ 0x4700000, 0x5800000 },
+	},
+};
+
+static const char * const dsi_6g_bus_clk_names[] = {
+	"mdp_core", "iface", "bus", "core_mmss",
+};
+
+static const struct regulator_bulk_data msm8974_apq8084_regulators[] = {
+	{ .supply = "vdd", .init_load_uA = 150000 },	/* 3.0 V */
+	{ .supply = "vdda", .init_load_uA = 100000 },	/* 1.2 V */
+	{ .supply = "vddio", .init_load_uA = 100000 },	/* 1.8 V */
+};
+
+static const struct msm_dsi_config msm8974_apq8084_dsi_cfg = {
+	.io_offset = DSI_6G_REG_SHIFT,
+	.regulator_data = msm8974_apq8084_regulators,
+	.num_regulators = ARRAY_SIZE(msm8974_apq8084_regulators),
+	.bus_clk_names = dsi_6g_bus_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_6g_bus_clk_names),
+	.io_start = {
+		{ 0xfd922800, 0xfd922b00 },
+	},
+};
+
+static const char * const dsi_v1_3_1_clk_names[] = {
+	"mdp_core", "iface", "bus",
+};
+
+static const struct regulator_bulk_data dsi_v1_3_1_regulators[] = {
+	{ .supply = "vdda", .init_load_uA = 100000 },	/* 1.2 V */
+	{ .supply = "vddio", .init_load_uA = 100000 },	/* 1.8 V */
+};
+
+static const struct msm_dsi_config msm8916_dsi_cfg = {
+	.io_offset = DSI_6G_REG_SHIFT,
+	.regulator_data = dsi_v1_3_1_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_v1_3_1_regulators),
+	.bus_clk_names = dsi_v1_3_1_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_v1_3_1_clk_names),
+	.io_start = {
+		{ 0x1a98000 },
+	},
+};
+
+static const struct msm_dsi_config msm8976_dsi_cfg = {
+	.io_offset = DSI_6G_REG_SHIFT,
+	.regulator_data = dsi_v1_3_1_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_v1_3_1_regulators),
+	.bus_clk_names = dsi_v1_3_1_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_v1_3_1_clk_names),
+	.io_start = {
+		{ 0x1a94000, 0x1a96000 },
+	},
+};
+
+static const struct regulator_bulk_data msm8994_dsi_regulators[] = {
+	{ .supply = "vdda", .init_load_uA = 100000 },	/* 1.25 V */
+	{ .supply = "vddio", .init_load_uA = 100000 },	/* 1.8 V */
+	{ .supply = "vcca", .init_load_uA = 10000 },	/* 1.0 V */
+	{ .supply = "vdd", .init_load_uA = 100000 },	/* 1.8 V */
+	{ .supply = "lab_reg", .init_load_uA = -1 },
+	{ .supply = "ibb_reg", .init_load_uA = -1 },
+};
+
+static const struct msm_dsi_config msm8994_dsi_cfg = {
+	.io_offset = DSI_6G_REG_SHIFT,
+	.regulator_data = msm8994_dsi_regulators,
+	.num_regulators = ARRAY_SIZE(msm8994_dsi_regulators),
+	.bus_clk_names = dsi_6g_bus_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_6g_bus_clk_names),
+	.io_start = {
+		{ 0xfd998000, 0xfd9a0000 },
+	},
+};
+
+static const struct regulator_bulk_data msm8996_dsi_regulators[] = {
+	{ .supply = "vdda", .init_load_uA = 18160 },	/* 1.25 V */
+	{ .supply = "vcca", .init_load_uA = 17000 },	/* 0.925 V */
+	{ .supply = "vddio", .init_load_uA = 100000 },	/* 1.8 V */
+};
+
+static const struct msm_dsi_config msm8996_dsi_cfg = {
+	.io_offset = DSI_6G_REG_SHIFT,
+	.regulator_data = msm8996_dsi_regulators,
+	.num_regulators = ARRAY_SIZE(msm8996_dsi_regulators),
+	.bus_clk_names = dsi_6g_bus_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_6g_bus_clk_names),
+	.io_start = {
+		{ 0x994000, 0x996000 },
+	},
+};
+
+static const char * const dsi_msm8998_bus_clk_names[] = {
+	"iface", "bus", "core",
+};
+
+static const struct regulator_bulk_data msm8998_dsi_regulators[] = {
+	{ .supply = "vdd", .init_load_uA = 367000 },	/* 0.9 V */
+	{ .supply = "vdda", .init_load_uA = 62800 },	/* 1.2 V */
+};
+
+static const struct msm_dsi_config msm8998_dsi_cfg = {
+	.io_offset = DSI_6G_REG_SHIFT,
+	.regulator_data = msm8998_dsi_regulators,
+	.num_regulators = ARRAY_SIZE(msm8998_dsi_regulators),
+	.bus_clk_names = dsi_msm8998_bus_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_msm8998_bus_clk_names),
+	.io_start = {
+		{ 0xc994000, 0xc996000 },
+	},
+};
+
+static const char * const dsi_sdm660_bus_clk_names[] = {
+	"iface", "bus", "core", "core_mmss",
+};
+
+static const struct regulator_bulk_data sdm660_dsi_regulators[] = {
+	{ .supply = "vdda", .init_load_uA = 12560 },	/* 1.2 V */
+};
+
+static const struct msm_dsi_config sdm660_dsi_cfg = {
+	.io_offset = DSI_6G_REG_SHIFT,
+	.regulator_data = sdm660_dsi_regulators,
+	.num_regulators = ARRAY_SIZE(sdm660_dsi_regulators),
+	.bus_clk_names = dsi_sdm660_bus_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_sdm660_bus_clk_names),
+	.io_start = {
+		{ 0xc994000, 0xc996000 },
+	},
+};
+
+static const char * const dsi_v2_4_clk_names[] = {
+	"iface", "bus",
+};
+
+static const struct regulator_bulk_data dsi_v2_4_regulators[] = {
+	{ .supply = "vdda", .init_load_uA = 21800 },	/* 1.2 V */
+	{ .supply = "refgen" },
+};
+
+static const struct msm_dsi_config sdm845_dsi_cfg = {
+	.io_offset = DSI_6G_REG_SHIFT,
+	.regulator_data = dsi_v2_4_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_v2_4_regulators),
+	.bus_clk_names = dsi_v2_4_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_v2_4_clk_names),
+	.io_start = {
+		{ 0xae94000, 0xae96000 }, /* SDM845 / SDM670 */
+		{ 0x5e94000 }, /* QCM2290 / SM6115 / SM6125 / SM6375 */
+	},
+};
+
+static const struct regulator_bulk_data sm8550_dsi_regulators[] = {
+	{ .supply = "vdda", .init_load_uA = 16800 },	/* 1.2 V */
+};
+
+static const struct msm_dsi_config sm8550_dsi_cfg = {
+	.io_offset = DSI_6G_REG_SHIFT,
+	.regulator_data = sm8550_dsi_regulators,
+	.num_regulators = ARRAY_SIZE(sm8550_dsi_regulators),
+	.bus_clk_names = dsi_v2_4_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_v2_4_clk_names),
+	.io_start = {
+		{ 0xae94000, 0xae96000 },
+	},
+};
+
+static const struct regulator_bulk_data sm8650_dsi_regulators[] = {
+	{ .supply = "vdda", .init_load_uA = 16600 },	/* 1.2 V */
+};
+
+static const struct msm_dsi_config sm8650_dsi_cfg = {
+	.io_offset = DSI_6G_REG_SHIFT,
+	.regulator_data = sm8650_dsi_regulators,
+	.num_regulators = ARRAY_SIZE(sm8650_dsi_regulators),
+	.bus_clk_names = dsi_v2_4_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_v2_4_clk_names),
+	.io_start = {
+		{ 0xae94000, 0xae96000 },
+	},
+};
+
+static const struct regulator_bulk_data sc7280_dsi_regulators[] = {
+	{ .supply = "vdda", .init_load_uA = 8350 },	/* 1.2 V */
+	{ .supply = "refgen" },
+};
+
+static const struct msm_dsi_config sc7280_dsi_cfg = {
+	.io_offset = DSI_6G_REG_SHIFT,
+	.regulator_data = sc7280_dsi_regulators,
+	.num_regulators = ARRAY_SIZE(sc7280_dsi_regulators),
+	.bus_clk_names = dsi_v2_4_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_v2_4_clk_names),
+	.io_start = {
+		{ 0xae94000, 0xae96000 },
+	},
+};
+
+static const struct regulator_bulk_data sa8775_dsi_regulators[] = {
+	{ .supply = "vdda", .init_load_uA = 30100 },    /* 1.2 V */
+	{ .supply = "refgen" },
+};
+
+static const struct msm_dsi_config sa8775_dsi_cfg = {
+	.io_offset = DSI_6G_REG_SHIFT,
+	.regulator_data = sa8775_dsi_regulators,
+	.num_regulators = ARRAY_SIZE(sa8775_dsi_regulators),
+	.bus_clk_names = dsi_v2_4_clk_names,
+	.num_bus_clks = ARRAY_SIZE(dsi_v2_4_clk_names),
+	.io_start = {
+		{ 0xae94000, 0xae96000 },
+	},
+};
+
+static const struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {
+	.link_clk_set_rate = dsi_link_clk_set_rate_v2,
+	.link_clk_enable = dsi_link_clk_enable_v2,
+	.link_clk_disable = dsi_link_clk_disable_v2,
+	.clk_init_ver = dsi_clk_init_v2,
+	.tx_buf_alloc = dsi_tx_buf_alloc_v2,
+	.tx_buf_get = dsi_tx_buf_get_v2,
+	.tx_buf_put = NULL,
+	.dma_base_get = dsi_dma_base_get_v2,
+	.calc_clk_rate = dsi_calc_clk_rate_v2,
+};
+
+static const struct msm_dsi_host_cfg_ops msm_dsi_6g_host_ops = {
+	.link_clk_set_rate = dsi_link_clk_set_rate_6g,
+	.link_clk_enable = dsi_link_clk_enable_6g,
+	.link_clk_disable = dsi_link_clk_disable_6g,
+	.clk_init_ver = NULL,
+	.tx_buf_alloc = dsi_tx_buf_alloc_6g,
+	.tx_buf_get = dsi_tx_buf_get_6g,
+	.tx_buf_put = dsi_tx_buf_put_6g,
+	.dma_base_get = dsi_dma_base_get_6g,
+	.calc_clk_rate = dsi_calc_clk_rate_6g,
+};
+
+static const struct msm_dsi_host_cfg_ops msm_dsi_6g_v2_host_ops = {
+	.link_clk_set_rate = dsi_link_clk_set_rate_6g,
+	.link_clk_enable = dsi_link_clk_enable_6g,
+	.link_clk_disable = dsi_link_clk_disable_6g,
+	.clk_init_ver = dsi_clk_init_6g_v2,
+	.tx_buf_alloc = dsi_tx_buf_alloc_6g,
+	.tx_buf_get = dsi_tx_buf_get_6g,
+	.tx_buf_put = dsi_tx_buf_put_6g,
+	.dma_base_get = dsi_dma_base_get_6g,
+	.calc_clk_rate = dsi_calc_clk_rate_6g,
+};
+
+static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] = {
+	{MSM_DSI_VER_MAJOR_V2, MSM_DSI_V2_VER_MINOR_8064,
+		&apq8064_dsi_cfg, &msm_dsi_v2_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_0,
+		&msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_0_2,
+		&msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_1,
+		&msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_1_1,
+		&msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_2,
+		&msm8974_apq8084_dsi_cfg, &msm_dsi_6g_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3,
+		&msm8994_dsi_cfg, &msm_dsi_6g_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_3_1,
+		&msm8916_dsi_cfg, &msm_dsi_6g_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_1,
+		&msm8996_dsi_cfg, &msm_dsi_6g_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V1_4_2,
+		&msm8976_dsi_cfg, &msm_dsi_6g_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_1_0,
+		&sdm660_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_0,
+		&msm8998_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_2_1,
+		&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_3_0,
+		&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_4_0,
+		&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_4_1,
+		&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_5_0,
+		&sc7280_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_6_0,
+		&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_5_1,
+		&sa8775_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_7_0,
+		&sm8550_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+	{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_8_0,
+		&sm8650_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+};
+
+const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor)
+{
+	const struct msm_dsi_cfg_handler *cfg_hnd = NULL;
+	int i;
+
+	for (i = ARRAY_SIZE(dsi_cfg_handlers) - 1; i >= 0; i--) {
+		if ((dsi_cfg_handlers[i].major == major) &&
+			(dsi_cfg_handlers[i].minor == minor)) {
+			cfg_hnd = &dsi_cfg_handlers[i];
+			break;
+		}
+	}
+
+	return cfg_hnd;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/dsi_cfg.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/dsi_cfg.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __MSM_DSI_CFG_H__
+#define __MSM_DSI_CFG_H__
+
+#include "dsi.h"
+
+#define MSM_DSI_VER_MAJOR_V2	0x02
+#define MSM_DSI_VER_MAJOR_6G	0x03
+#define MSM_DSI_6G_VER_MINOR_V1_0	0x10000000
+#define MSM_DSI_6G_VER_MINOR_V1_0_2	0x10000002
+#define MSM_DSI_6G_VER_MINOR_V1_1	0x10010000
+#define MSM_DSI_6G_VER_MINOR_V1_1_1	0x10010001
+#define MSM_DSI_6G_VER_MINOR_V1_2	0x10020000
+#define MSM_DSI_6G_VER_MINOR_V1_3	0x10030000
+#define MSM_DSI_6G_VER_MINOR_V1_3_1	0x10030001
+#define MSM_DSI_6G_VER_MINOR_V1_4_1	0x10040001
+#define MSM_DSI_6G_VER_MINOR_V1_4_2	0x10040002
+#define MSM_DSI_6G_VER_MINOR_V2_1_0	0x20010000
+#define MSM_DSI_6G_VER_MINOR_V2_2_0	0x20000000
+#define MSM_DSI_6G_VER_MINOR_V2_2_1	0x20020001
+#define MSM_DSI_6G_VER_MINOR_V2_3_0	0x20030000
+#define MSM_DSI_6G_VER_MINOR_V2_4_0	0x20040000
+#define MSM_DSI_6G_VER_MINOR_V2_4_1	0x20040001
+#define MSM_DSI_6G_VER_MINOR_V2_5_0	0x20050000
+#define MSM_DSI_6G_VER_MINOR_V2_5_1	0x20050001
+#define MSM_DSI_6G_VER_MINOR_V2_6_0	0x20060000
+#define MSM_DSI_6G_VER_MINOR_V2_7_0	0x20070000
+#define MSM_DSI_6G_VER_MINOR_V2_8_0	0x20080000
+
+#define MSM_DSI_V2_VER_MINOR_8064	0x0
+
+#define DSI_6G_REG_SHIFT	4
+
+/* Maximum number of configurations matched against the same hw revision */
+#define VARIANTS_MAX			2
+
+struct msm_dsi_config {
+	u32 io_offset;
+	const struct regulator_bulk_data *regulator_data;
+	int num_regulators;
+	const char * const *bus_clk_names;
+	const int num_bus_clks;
+	const resource_size_t io_start[VARIANTS_MAX][DSI_MAX];
+};
+
+struct msm_dsi_host_cfg_ops {
+	int (*link_clk_set_rate)(struct msm_dsi_host *msm_host);
+	int (*link_clk_enable)(struct msm_dsi_host *msm_host);
+	void (*link_clk_disable)(struct msm_dsi_host *msm_host);
+	int (*clk_init_ver)(struct msm_dsi_host *msm_host);
+	int (*tx_buf_alloc)(struct msm_dsi_host *msm_host, int size);
+	void* (*tx_buf_get)(struct msm_dsi_host *msm_host);
+	void (*tx_buf_put)(struct msm_dsi_host *msm_host);
+	int (*dma_base_get)(struct msm_dsi_host *msm_host, uint64_t *iova);
+	int (*calc_clk_rate)(struct msm_dsi_host *msm_host, bool is_bonded_dsi);
+};
+
+struct msm_dsi_cfg_handler {
+	u32 major;
+	u32 minor;
+	const struct msm_dsi_config *cfg;
+	const struct msm_dsi_host_cfg_ops *ops;
+};
+
+const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor);
+
+#endif /* __MSM_DSI_CFG_H__ */
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/dsi_host.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/dsi_host.c
@@ -0,0 +1,2592 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_graph.h>
+#include <linux/of_irq.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pm_opp.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/spinlock.h>
+
+#include <video/mipi_display.h>
+
+#include <drm/display/drm_dsc_helper.h>
+#include <drm/drm_of.h>
+
+#include "dsi.h"
+#include "dsi.xml.h"
+#include "sfpb.xml.h"
+#include "dsi_cfg.h"
+#include "msm_dsc_helper.h"
+#include "msm_kms.h"
+#include "msm_gem.h"
+#include "phy/dsi_phy.h"
+
+#define DSI_RESET_TOGGLE_DELAY_MS 20
+
+static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc);
+
+static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor)
+{
+	u32 ver;
+
+	if (!major || !minor)
+		return -EINVAL;
+
+	/*
+	 * From DSI6G(v3), addition of a 6G_HW_VERSION register at offset 0
+	 * makes all other registers 4-byte shifted down.
+	 *
+	 * In order to identify between DSI6G(v3) and beyond, and DSIv2 and
+	 * older, we read the DSI_VERSION register without any shift(offset
+	 * 0x1f0). In the case of DSIv2, this hast to be a non-zero value. In
+	 * the case of DSI6G, this has to be zero (the offset points to a
+	 * scratch register which we never touch)
+	 */
+
+	ver = msm_readl(base + REG_DSI_VERSION);
+	if (ver) {
+		/* older dsi host, there is no register shift */
+		ver = FIELD(ver, DSI_VERSION_MAJOR);
+		if (ver <= MSM_DSI_VER_MAJOR_V2) {
+			/* old versions */
+			*major = ver;
+			*minor = 0;
+			return 0;
+		} else {
+			return -EINVAL;
+		}
+	} else {
+		/*
+		 * newer host, offset 0 has 6G_HW_VERSION, the rest of the
+		 * registers are shifted down, read DSI_VERSION again with
+		 * the shifted offset
+		 */
+		ver = msm_readl(base + DSI_6G_REG_SHIFT + REG_DSI_VERSION);
+		ver = FIELD(ver, DSI_VERSION_MAJOR);
+		if (ver == MSM_DSI_VER_MAJOR_6G) {
+			/* 6G version */
+			*major = ver;
+			*minor = msm_readl(base + REG_DSI_6G_HW_VERSION);
+			return 0;
+		} else {
+			return -EINVAL;
+		}
+	}
+}
+
+#define DSI_ERR_STATE_ACK			0x0000
+#define DSI_ERR_STATE_TIMEOUT			0x0001
+#define DSI_ERR_STATE_DLN0_PHY			0x0002
+#define DSI_ERR_STATE_FIFO			0x0004
+#define DSI_ERR_STATE_MDP_FIFO_UNDERFLOW	0x0008
+#define DSI_ERR_STATE_INTERLEAVE_OP_CONTENTION	0x0010
+#define DSI_ERR_STATE_PLL_UNLOCKED		0x0020
+
+#define DSI_CLK_CTRL_ENABLE_CLKS	\
+		(DSI_CLK_CTRL_AHBS_HCLK_ON | DSI_CLK_CTRL_AHBM_SCLK_ON | \
+		DSI_CLK_CTRL_PCLK_ON | DSI_CLK_CTRL_DSICLK_ON | \
+		DSI_CLK_CTRL_BYTECLK_ON | DSI_CLK_CTRL_ESCCLK_ON | \
+		DSI_CLK_CTRL_FORCE_ON_DYN_AHBM_HCLK)
+
+struct msm_dsi_host {
+	struct mipi_dsi_host base;
+
+	struct platform_device *pdev;
+	struct drm_device *dev;
+
+	int id;
+
+	void __iomem *ctrl_base;
+	phys_addr_t ctrl_size;
+	struct regulator_bulk_data *supplies;
+
+	int num_bus_clks;
+	struct clk_bulk_data bus_clks[DSI_BUS_CLK_MAX];
+
+	struct clk *byte_clk;
+	struct clk *esc_clk;
+	struct clk *pixel_clk;
+	struct clk *byte_intf_clk;
+
+	unsigned long byte_clk_rate;
+	unsigned long byte_intf_clk_rate;
+	unsigned long pixel_clk_rate;
+	unsigned long esc_clk_rate;
+
+	/* DSI v2 specific clocks */
+	struct clk *src_clk;
+
+	unsigned long src_clk_rate;
+
+	struct gpio_desc *disp_en_gpio;
+	struct gpio_desc *te_gpio;
+
+	const struct msm_dsi_cfg_handler *cfg_hnd;
+
+	struct completion dma_comp;
+	struct completion video_comp;
+	struct mutex dev_mutex;
+	struct mutex cmd_mutex;
+	spinlock_t intr_lock; /* Protect interrupt ctrl register */
+
+	u32 err_work_state;
+	struct work_struct err_work;
+	struct workqueue_struct *workqueue;
+
+	/* DSI 6G TX buffer*/
+	struct drm_gem_object *tx_gem_obj;
+	struct msm_gem_address_space *aspace;
+
+	/* DSI v2 TX buffer */
+	void *tx_buf;
+	dma_addr_t tx_buf_paddr;
+
+	int tx_size;
+
+	u8 *rx_buf;
+
+	struct regmap *sfpb;
+
+	struct drm_display_mode *mode;
+	struct drm_dsc_config *dsc;
+
+	/* connected device info */
+	unsigned int channel;
+	unsigned int lanes;
+	enum mipi_dsi_pixel_format format;
+	unsigned long mode_flags;
+
+	/* lane data parsed via DT */
+	int dlane_swap;
+	int num_data_lanes;
+
+	/* from phy DT */
+	bool cphy_mode;
+
+	u32 dma_cmd_ctrl_restore;
+
+	bool registered;
+	bool power_on;
+	bool enabled;
+	int irq;
+};
+
+static u32 dsi_get_bpp(const enum mipi_dsi_pixel_format fmt)
+{
+	switch (fmt) {
+	case MIPI_DSI_FMT_RGB565:		return 16;
+	case MIPI_DSI_FMT_RGB666_PACKED:	return 18;
+	case MIPI_DSI_FMT_RGB666:
+	case MIPI_DSI_FMT_RGB888:
+	default:				return 24;
+	}
+}
+
+static inline u32 dsi_read(struct msm_dsi_host *msm_host, u32 reg)
+{
+	return msm_readl(msm_host->ctrl_base + reg);
+}
+static inline void dsi_write(struct msm_dsi_host *msm_host, u32 reg, u32 data)
+{
+	msm_writel(data, msm_host->ctrl_base + reg);
+}
+
+static const struct msm_dsi_cfg_handler *dsi_get_config(
+						struct msm_dsi_host *msm_host)
+{
+	const struct msm_dsi_cfg_handler *cfg_hnd = NULL;
+	struct device *dev = &msm_host->pdev->dev;
+	struct clk *ahb_clk;
+	int ret;
+	u32 major = 0, minor = 0;
+
+	ahb_clk = msm_clk_get(msm_host->pdev, "iface");
+	if (IS_ERR(ahb_clk)) {
+		pr_err("%s: cannot get interface clock\n", __func__);
+		goto exit;
+	}
+
+	pm_runtime_get_sync(dev);
+
+	ret = clk_prepare_enable(ahb_clk);
+	if (ret) {
+		pr_err("%s: unable to enable ahb_clk\n", __func__);
+		goto runtime_put;
+	}
+
+	ret = dsi_get_version(msm_host->ctrl_base, &major, &minor);
+	if (ret) {
+		pr_err("%s: Invalid version\n", __func__);
+		goto disable_clks;
+	}
+
+	cfg_hnd = msm_dsi_cfg_get(major, minor);
+
+	DBG("%s: Version %x:%x\n", __func__, major, minor);
+
+disable_clks:
+	clk_disable_unprepare(ahb_clk);
+runtime_put:
+	pm_runtime_put_sync(dev);
+exit:
+	return cfg_hnd;
+}
+
+static inline struct msm_dsi_host *to_msm_dsi_host(struct mipi_dsi_host *host)
+{
+	return container_of(host, struct msm_dsi_host, base);
+}
+
+int dsi_clk_init_v2(struct msm_dsi_host *msm_host)
+{
+	struct platform_device *pdev = msm_host->pdev;
+	int ret = 0;
+
+	msm_host->src_clk = msm_clk_get(pdev, "src");
+
+	if (IS_ERR(msm_host->src_clk)) {
+		ret = PTR_ERR(msm_host->src_clk);
+		pr_err("%s: can't find src clock. ret=%d\n",
+			__func__, ret);
+		msm_host->src_clk = NULL;
+		return ret;
+	}
+
+	return ret;
+}
+
+int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host)
+{
+	struct platform_device *pdev = msm_host->pdev;
+	int ret = 0;
+
+	msm_host->byte_intf_clk = msm_clk_get(pdev, "byte_intf");
+	if (IS_ERR(msm_host->byte_intf_clk)) {
+		ret = PTR_ERR(msm_host->byte_intf_clk);
+		pr_err("%s: can't find byte_intf clock. ret=%d\n",
+			__func__, ret);
+	}
+
+	return ret;
+}
+
+static int dsi_clk_init(struct msm_dsi_host *msm_host)
+{
+	struct platform_device *pdev = msm_host->pdev;
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
+	const struct msm_dsi_config *cfg = cfg_hnd->cfg;
+	int i, ret = 0;
+
+	/* get bus clocks */
+	for (i = 0; i < cfg->num_bus_clks; i++)
+		msm_host->bus_clks[i].id = cfg->bus_clk_names[i];
+	msm_host->num_bus_clks = cfg->num_bus_clks;
+
+	ret = devm_clk_bulk_get(&pdev->dev, msm_host->num_bus_clks, msm_host->bus_clks);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Unable to get clocks, ret = %d\n", ret);
+		goto exit;
+	}
+
+	/* get link and source clocks */
+	msm_host->byte_clk = msm_clk_get(pdev, "byte");
+	if (IS_ERR(msm_host->byte_clk)) {
+		ret = PTR_ERR(msm_host->byte_clk);
+		pr_err("%s: can't find dsi_byte clock. ret=%d\n",
+			__func__, ret);
+		msm_host->byte_clk = NULL;
+		goto exit;
+	}
+
+	msm_host->pixel_clk = msm_clk_get(pdev, "pixel");
+	if (IS_ERR(msm_host->pixel_clk)) {
+		ret = PTR_ERR(msm_host->pixel_clk);
+		pr_err("%s: can't find dsi_pixel clock. ret=%d\n",
+			__func__, ret);
+		msm_host->pixel_clk = NULL;
+		goto exit;
+	}
+
+	msm_host->esc_clk = msm_clk_get(pdev, "core");
+	if (IS_ERR(msm_host->esc_clk)) {
+		ret = PTR_ERR(msm_host->esc_clk);
+		pr_err("%s: can't find dsi_esc clock. ret=%d\n",
+			__func__, ret);
+		msm_host->esc_clk = NULL;
+		goto exit;
+	}
+
+	if (cfg_hnd->ops->clk_init_ver)
+		ret = cfg_hnd->ops->clk_init_ver(msm_host);
+exit:
+	return ret;
+}
+
+int msm_dsi_runtime_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct msm_dsi *msm_dsi = platform_get_drvdata(pdev);
+	struct mipi_dsi_host *host = msm_dsi->host;
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	if (!msm_host->cfg_hnd)
+		return 0;
+
+	clk_bulk_disable_unprepare(msm_host->num_bus_clks, msm_host->bus_clks);
+
+	return 0;
+}
+
+int msm_dsi_runtime_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct msm_dsi *msm_dsi = platform_get_drvdata(pdev);
+	struct mipi_dsi_host *host = msm_dsi->host;
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	if (!msm_host->cfg_hnd)
+		return 0;
+
+	return clk_bulk_prepare_enable(msm_host->num_bus_clks, msm_host->bus_clks);
+}
+
+int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
+{
+	int ret;
+
+	DBG("Set clk rates: pclk=%lu, byteclk=%lu",
+	    msm_host->pixel_clk_rate, msm_host->byte_clk_rate);
+
+	ret = dev_pm_opp_set_rate(&msm_host->pdev->dev,
+				  msm_host->byte_clk_rate);
+	if (ret) {
+		pr_err("%s: dev_pm_opp_set_rate failed %d\n", __func__, ret);
+		return ret;
+	}
+
+	ret = clk_set_rate(msm_host->pixel_clk, msm_host->pixel_clk_rate);
+	if (ret) {
+		pr_err("%s: Failed to set rate pixel clk, %d\n", __func__, ret);
+		return ret;
+	}
+
+	if (msm_host->byte_intf_clk) {
+		ret = clk_set_rate(msm_host->byte_intf_clk, msm_host->byte_intf_clk_rate);
+		if (ret) {
+			pr_err("%s: Failed to set rate byte intf clk, %d\n",
+			       __func__, ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+
+int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host)
+{
+	int ret;
+
+	ret = clk_prepare_enable(msm_host->esc_clk);
+	if (ret) {
+		pr_err("%s: Failed to enable dsi esc clk\n", __func__);
+		goto error;
+	}
+
+	ret = clk_prepare_enable(msm_host->byte_clk);
+	if (ret) {
+		pr_err("%s: Failed to enable dsi byte clk\n", __func__);
+		goto byte_clk_err;
+	}
+
+	ret = clk_prepare_enable(msm_host->pixel_clk);
+	if (ret) {
+		pr_err("%s: Failed to enable dsi pixel clk\n", __func__);
+		goto pixel_clk_err;
+	}
+
+	ret = clk_prepare_enable(msm_host->byte_intf_clk);
+	if (ret) {
+		pr_err("%s: Failed to enable byte intf clk\n",
+			   __func__);
+		goto byte_intf_clk_err;
+	}
+
+	return 0;
+
+byte_intf_clk_err:
+	clk_disable_unprepare(msm_host->pixel_clk);
+pixel_clk_err:
+	clk_disable_unprepare(msm_host->byte_clk);
+byte_clk_err:
+	clk_disable_unprepare(msm_host->esc_clk);
+error:
+	return ret;
+}
+
+int dsi_link_clk_set_rate_v2(struct msm_dsi_host *msm_host)
+{
+	int ret;
+
+	DBG("Set clk rates: pclk=%lu, byteclk=%lu, esc_clk=%lu, dsi_src_clk=%lu",
+	    msm_host->pixel_clk_rate, msm_host->byte_clk_rate,
+	    msm_host->esc_clk_rate, msm_host->src_clk_rate);
+
+	ret = clk_set_rate(msm_host->byte_clk, msm_host->byte_clk_rate);
+	if (ret) {
+		pr_err("%s: Failed to set rate byte clk, %d\n", __func__, ret);
+		return ret;
+	}
+
+	ret = clk_set_rate(msm_host->esc_clk, msm_host->esc_clk_rate);
+	if (ret) {
+		pr_err("%s: Failed to set rate esc clk, %d\n", __func__, ret);
+		return ret;
+	}
+
+	ret = clk_set_rate(msm_host->src_clk, msm_host->src_clk_rate);
+	if (ret) {
+		pr_err("%s: Failed to set rate src clk, %d\n", __func__, ret);
+		return ret;
+	}
+
+	ret = clk_set_rate(msm_host->pixel_clk, msm_host->pixel_clk_rate);
+	if (ret) {
+		pr_err("%s: Failed to set rate pixel clk, %d\n", __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host)
+{
+	int ret;
+
+	ret = clk_prepare_enable(msm_host->byte_clk);
+	if (ret) {
+		pr_err("%s: Failed to enable dsi byte clk\n", __func__);
+		goto error;
+	}
+
+	ret = clk_prepare_enable(msm_host->esc_clk);
+	if (ret) {
+		pr_err("%s: Failed to enable dsi esc clk\n", __func__);
+		goto esc_clk_err;
+	}
+
+	ret = clk_prepare_enable(msm_host->src_clk);
+	if (ret) {
+		pr_err("%s: Failed to enable dsi src clk\n", __func__);
+		goto src_clk_err;
+	}
+
+	ret = clk_prepare_enable(msm_host->pixel_clk);
+	if (ret) {
+		pr_err("%s: Failed to enable dsi pixel clk\n", __func__);
+		goto pixel_clk_err;
+	}
+
+	return 0;
+
+pixel_clk_err:
+	clk_disable_unprepare(msm_host->src_clk);
+src_clk_err:
+	clk_disable_unprepare(msm_host->esc_clk);
+esc_clk_err:
+	clk_disable_unprepare(msm_host->byte_clk);
+error:
+	return ret;
+}
+
+void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host)
+{
+	/* Drop the performance state vote */
+	dev_pm_opp_set_rate(&msm_host->pdev->dev, 0);
+	clk_disable_unprepare(msm_host->esc_clk);
+	clk_disable_unprepare(msm_host->pixel_clk);
+	clk_disable_unprepare(msm_host->byte_intf_clk);
+	clk_disable_unprepare(msm_host->byte_clk);
+}
+
+void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host)
+{
+	clk_disable_unprepare(msm_host->pixel_clk);
+	clk_disable_unprepare(msm_host->src_clk);
+	clk_disable_unprepare(msm_host->esc_clk);
+	clk_disable_unprepare(msm_host->byte_clk);
+}
+
+static unsigned long dsi_adjust_pclk_for_compression(const struct drm_display_mode *mode,
+		const struct drm_dsc_config *dsc)
+{
+	int new_hdisplay = DIV_ROUND_UP(mode->hdisplay * drm_dsc_get_bpp_int(dsc),
+			dsc->bits_per_component * 3);
+
+	int new_htotal = mode->htotal - mode->hdisplay + new_hdisplay;
+
+	return new_htotal * mode->vtotal * drm_mode_vrefresh(mode);
+}
+
+static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode,
+		const struct drm_dsc_config *dsc, bool is_bonded_dsi)
+{
+	unsigned long pclk_rate;
+
+	pclk_rate = mode->clock * 1000;
+
+	if (dsc)
+		pclk_rate = dsi_adjust_pclk_for_compression(mode, dsc);
+
+	/*
+	 * For bonded DSI mode, the current DRM mode has the complete width of the
+	 * panel. Since, the complete panel is driven by two DSI controllers,
+	 * the clock rates have to be split between the two dsi controllers.
+	 * Adjust the byte and pixel clock rates for each dsi host accordingly.
+	 */
+	if (is_bonded_dsi)
+		pclk_rate /= 2;
+
+	return pclk_rate;
+}
+
+unsigned long dsi_byte_clk_get_rate(struct mipi_dsi_host *host, bool is_bonded_dsi,
+				    const struct drm_display_mode *mode)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	u8 lanes = msm_host->lanes;
+	u32 bpp = dsi_get_bpp(msm_host->format);
+	unsigned long pclk_rate = dsi_get_pclk_rate(mode, msm_host->dsc, is_bonded_dsi);
+	unsigned long pclk_bpp;
+
+	if (lanes == 0) {
+		pr_err("%s: forcing mdss_dsi lanes to 1\n", __func__);
+		lanes = 1;
+	}
+
+	/* CPHY "byte_clk" is in units of 16 bits */
+	if (msm_host->cphy_mode)
+		pclk_bpp = mult_frac(pclk_rate, bpp, 16 * lanes);
+	else
+		pclk_bpp = mult_frac(pclk_rate, bpp, 8 * lanes);
+
+	return pclk_bpp;
+}
+
+static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+{
+	msm_host->pixel_clk_rate = dsi_get_pclk_rate(msm_host->mode, msm_host->dsc, is_bonded_dsi);
+	msm_host->byte_clk_rate = dsi_byte_clk_get_rate(&msm_host->base, is_bonded_dsi,
+							msm_host->mode);
+
+	DBG("pclk=%lu, bclk=%lu", msm_host->pixel_clk_rate,
+				msm_host->byte_clk_rate);
+
+}
+
+int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+{
+	if (!msm_host->mode) {
+		pr_err("%s: mode not set\n", __func__);
+		return -EINVAL;
+	}
+
+	dsi_calc_pclk(msm_host, is_bonded_dsi);
+	msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
+	return 0;
+}
+
+int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+{
+	u32 bpp = dsi_get_bpp(msm_host->format);
+	unsigned int esc_mhz, esc_div;
+	unsigned long byte_mhz;
+
+	dsi_calc_pclk(msm_host, is_bonded_dsi);
+
+	msm_host->src_clk_rate = mult_frac(msm_host->pixel_clk_rate, bpp, 8);
+
+	/*
+	 * esc clock is byte clock followed by a 4 bit divider,
+	 * we need to find an escape clock frequency within the
+	 * mipi DSI spec range within the maximum divider limit
+	 * We iterate here between an escape clock frequencey
+	 * between 20 Mhz to 5 Mhz and pick up the first one
+	 * that can be supported by our divider
+	 */
+
+	byte_mhz = msm_host->byte_clk_rate / 1000000;
+
+	for (esc_mhz = 20; esc_mhz >= 5; esc_mhz--) {
+		esc_div = DIV_ROUND_UP(byte_mhz, esc_mhz);
+
+		/*
+		 * TODO: Ideally, we shouldn't know what sort of divider
+		 * is available in mmss_cc, we're just assuming that
+		 * it'll always be a 4 bit divider. Need to come up with
+		 * a better way here.
+		 */
+		if (esc_div >= 1 && esc_div <= 16)
+			break;
+	}
+
+	if (esc_mhz < 5)
+		return -EINVAL;
+
+	msm_host->esc_clk_rate = msm_host->byte_clk_rate / esc_div;
+
+	DBG("esc=%lu, src=%lu", msm_host->esc_clk_rate,
+		msm_host->src_clk_rate);
+
+	return 0;
+}
+
+static void dsi_intr_ctrl(struct msm_dsi_host *msm_host, u32 mask, int enable)
+{
+	u32 intr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&msm_host->intr_lock, flags);
+	intr = dsi_read(msm_host, REG_DSI_INTR_CTRL);
+
+	if (enable)
+		intr |= mask;
+	else
+		intr &= ~mask;
+
+	DBG("intr=%x enable=%d", intr, enable);
+
+	dsi_write(msm_host, REG_DSI_INTR_CTRL, intr);
+	spin_unlock_irqrestore(&msm_host->intr_lock, flags);
+}
+
+static inline enum dsi_traffic_mode dsi_get_traffic_mode(const u32 mode_flags)
+{
+	if (mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
+		return BURST_MODE;
+	else if (mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE)
+		return NON_BURST_SYNCH_PULSE;
+
+	return NON_BURST_SYNCH_EVENT;
+}
+
+static inline enum dsi_vid_dst_format dsi_get_vid_fmt(
+				const enum mipi_dsi_pixel_format mipi_fmt)
+{
+	switch (mipi_fmt) {
+	case MIPI_DSI_FMT_RGB888:	return VID_DST_FORMAT_RGB888;
+	case MIPI_DSI_FMT_RGB666:	return VID_DST_FORMAT_RGB666_LOOSE;
+	case MIPI_DSI_FMT_RGB666_PACKED:	return VID_DST_FORMAT_RGB666;
+	case MIPI_DSI_FMT_RGB565:	return VID_DST_FORMAT_RGB565;
+	default:			return VID_DST_FORMAT_RGB888;
+	}
+}
+
+static inline enum dsi_cmd_dst_format dsi_get_cmd_fmt(
+				const enum mipi_dsi_pixel_format mipi_fmt)
+{
+	switch (mipi_fmt) {
+	case MIPI_DSI_FMT_RGB888:	return CMD_DST_FORMAT_RGB888;
+	case MIPI_DSI_FMT_RGB666_PACKED:
+	case MIPI_DSI_FMT_RGB666:	return CMD_DST_FORMAT_RGB666;
+	case MIPI_DSI_FMT_RGB565:	return CMD_DST_FORMAT_RGB565;
+	default:			return CMD_DST_FORMAT_RGB888;
+	}
+}
+
+static void dsi_ctrl_disable(struct msm_dsi_host *msm_host)
+{
+	dsi_write(msm_host, REG_DSI_CTRL, 0);
+}
+
+bool msm_dsi_host_is_wide_bus_enabled(struct mipi_dsi_host *host)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	return msm_host->dsc &&
+		(msm_host->cfg_hnd->major == MSM_DSI_VER_MAJOR_6G &&
+		 msm_host->cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V2_5_0);
+}
+
+static void dsi_ctrl_enable(struct msm_dsi_host *msm_host,
+			struct msm_dsi_phy_shared_timings *phy_shared_timings, struct msm_dsi_phy *phy)
+{
+	u32 flags = msm_host->mode_flags;
+	enum mipi_dsi_pixel_format mipi_fmt = msm_host->format;
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
+	u32 data = 0, lane_ctrl = 0;
+
+	if (flags & MIPI_DSI_MODE_VIDEO) {
+		if (flags & MIPI_DSI_MODE_VIDEO_HSE)
+			data |= DSI_VID_CFG0_PULSE_MODE_HSA_HE;
+		if (flags & MIPI_DSI_MODE_VIDEO_NO_HFP)
+			data |= DSI_VID_CFG0_HFP_POWER_STOP;
+		if (flags & MIPI_DSI_MODE_VIDEO_NO_HBP)
+			data |= DSI_VID_CFG0_HBP_POWER_STOP;
+		if (flags & MIPI_DSI_MODE_VIDEO_NO_HSA)
+			data |= DSI_VID_CFG0_HSA_POWER_STOP;
+		/* Always set low power stop mode for BLLP
+		 * to let command engine send packets
+		 */
+		data |= DSI_VID_CFG0_EOF_BLLP_POWER_STOP |
+			DSI_VID_CFG0_BLLP_POWER_STOP;
+		data |= DSI_VID_CFG0_TRAFFIC_MODE(dsi_get_traffic_mode(flags));
+		data |= DSI_VID_CFG0_DST_FORMAT(dsi_get_vid_fmt(mipi_fmt));
+		data |= DSI_VID_CFG0_VIRT_CHANNEL(msm_host->channel);
+		if (msm_dsi_host_is_wide_bus_enabled(&msm_host->base))
+			data |= DSI_VID_CFG0_DATABUS_WIDEN;
+		dsi_write(msm_host, REG_DSI_VID_CFG0, data);
+
+		/* Do not swap RGB colors */
+		data = DSI_VID_CFG1_RGB_SWAP(SWAP_RGB);
+		dsi_write(msm_host, REG_DSI_VID_CFG1, 0);
+	} else {
+		/* Do not swap RGB colors */
+		data = DSI_CMD_CFG0_RGB_SWAP(SWAP_RGB);
+		data |= DSI_CMD_CFG0_DST_FORMAT(dsi_get_cmd_fmt(mipi_fmt));
+		dsi_write(msm_host, REG_DSI_CMD_CFG0, data);
+
+		data = DSI_CMD_CFG1_WR_MEM_START(MIPI_DCS_WRITE_MEMORY_START) |
+			DSI_CMD_CFG1_WR_MEM_CONTINUE(
+					MIPI_DCS_WRITE_MEMORY_CONTINUE);
+		/* Always insert DCS command */
+		data |= DSI_CMD_CFG1_INSERT_DCS_COMMAND;
+		dsi_write(msm_host, REG_DSI_CMD_CFG1, data);
+
+		if (cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) {
+			data = dsi_read(msm_host, REG_DSI_CMD_MODE_MDP_CTRL2);
+
+			if (cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V1_3)
+				data |= DSI_CMD_MODE_MDP_CTRL2_BURST_MODE;
+
+			if (msm_dsi_host_is_wide_bus_enabled(&msm_host->base))
+				data |= DSI_CMD_MODE_MDP_CTRL2_DATABUS_WIDEN;
+
+			dsi_write(msm_host, REG_DSI_CMD_MODE_MDP_CTRL2, data);
+		}
+	}
+
+	dsi_write(msm_host, REG_DSI_CMD_DMA_CTRL,
+			DSI_CMD_DMA_CTRL_FROM_FRAME_BUFFER |
+			DSI_CMD_DMA_CTRL_LOW_POWER);
+
+	data = 0;
+	/* Always assume dedicated TE pin */
+	data |= DSI_TRIG_CTRL_TE;
+	data |= DSI_TRIG_CTRL_MDP_TRIGGER(TRIGGER_NONE);
+	data |= DSI_TRIG_CTRL_DMA_TRIGGER(TRIGGER_SW);
+	data |= DSI_TRIG_CTRL_STREAM(msm_host->channel);
+	if ((cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) &&
+		(cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V1_2))
+		data |= DSI_TRIG_CTRL_BLOCK_DMA_WITHIN_FRAME;
+	dsi_write(msm_host, REG_DSI_TRIG_CTRL, data);
+
+	data = DSI_CLKOUT_TIMING_CTRL_T_CLK_POST(phy_shared_timings->clk_post) |
+		DSI_CLKOUT_TIMING_CTRL_T_CLK_PRE(phy_shared_timings->clk_pre);
+	dsi_write(msm_host, REG_DSI_CLKOUT_TIMING_CTRL, data);
+
+	if ((cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) &&
+	    (cfg_hnd->minor > MSM_DSI_6G_VER_MINOR_V1_0) &&
+	    phy_shared_timings->clk_pre_inc_by_2)
+		dsi_write(msm_host, REG_DSI_T_CLK_PRE_EXTEND,
+			  DSI_T_CLK_PRE_EXTEND_INC_BY_2_BYTECLK);
+
+	data = 0;
+	if (!(flags & MIPI_DSI_MODE_NO_EOT_PACKET))
+		data |= DSI_EOT_PACKET_CTRL_TX_EOT_APPEND;
+	dsi_write(msm_host, REG_DSI_EOT_PACKET_CTRL, data);
+
+	/* allow only ack-err-status to generate interrupt */
+	dsi_write(msm_host, REG_DSI_ERR_INT_MASK0, 0x13ff3fe0);
+
+	dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_ERROR, 1);
+
+	dsi_write(msm_host, REG_DSI_CLK_CTRL, DSI_CLK_CTRL_ENABLE_CLKS);
+
+	data = DSI_CTRL_CLK_EN;
+
+	DBG("lane number=%d", msm_host->lanes);
+	data |= ((DSI_CTRL_LANE0 << msm_host->lanes) - DSI_CTRL_LANE0);
+
+	dsi_write(msm_host, REG_DSI_LANE_SWAP_CTRL,
+		  DSI_LANE_SWAP_CTRL_DLN_SWAP_SEL(msm_host->dlane_swap));
+
+	if (!(flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) {
+		lane_ctrl = dsi_read(msm_host, REG_DSI_LANE_CTRL);
+
+		if (msm_dsi_phy_set_continuous_clock(phy, true))
+			lane_ctrl &= ~DSI_LANE_CTRL_HS_REQ_SEL_PHY;
+
+		dsi_write(msm_host, REG_DSI_LANE_CTRL,
+			lane_ctrl | DSI_LANE_CTRL_CLKLN_HS_FORCE_REQUEST);
+	}
+
+	data |= DSI_CTRL_ENABLE;
+
+	dsi_write(msm_host, REG_DSI_CTRL, data);
+
+	if (msm_host->cphy_mode)
+		dsi_write(msm_host, REG_DSI_CPHY_MODE_CTRL, BIT(0));
+}
+
+static void dsi_update_dsc_timing(struct msm_dsi_host *msm_host, bool is_cmd_mode, u32 hdisplay)
+{
+	struct drm_dsc_config *dsc = msm_host->dsc;
+	u32 reg, reg_ctrl, reg_ctrl2;
+	u32 slice_per_intf, total_bytes_per_intf;
+	u32 pkt_per_line;
+	u32 eol_byte_num;
+	u32 bytes_per_pkt;
+
+	/* first calculate dsc parameters and then program
+	 * compress mode registers
+	 */
+	slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
+
+	total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
+	bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
+
+	eol_byte_num = total_bytes_per_intf % 3;
+
+	/*
+	 * Typically, pkt_per_line = slice_per_intf * slice_per_pkt.
+	 *
+	 * Since the current driver only supports slice_per_pkt = 1,
+	 * pkt_per_line will be equal to slice per intf for now.
+	 */
+	pkt_per_line = slice_per_intf;
+
+	if (is_cmd_mode) /* packet data type */
+		reg = DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE);
+	else
+		reg = DSI_VIDEO_COMPRESSION_MODE_CTRL_DATATYPE(MIPI_DSI_COMPRESSED_PIXEL_STREAM);
+
+	/* DSI_VIDEO_COMPRESSION_MODE & DSI_COMMAND_COMPRESSION_MODE
+	 * registers have similar offsets, so for below common code use
+	 * DSI_VIDEO_COMPRESSION_MODE_XXXX for setting bits
+	 */
+	reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_PKT_PER_LINE(pkt_per_line >> 1);
+	reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EOL_BYTE_NUM(eol_byte_num);
+	reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EN;
+
+	if (is_cmd_mode) {
+		reg_ctrl = dsi_read(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL);
+		reg_ctrl2 = dsi_read(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2);
+
+		reg_ctrl &= ~0xffff;
+		reg_ctrl |= reg;
+
+		reg_ctrl2 &= ~DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH__MASK;
+		reg_ctrl2 |= DSI_COMMAND_COMPRESSION_MODE_CTRL2_STREAM0_SLICE_WIDTH(dsc->slice_chunk_size);
+
+		dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, reg_ctrl);
+		dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, reg_ctrl2);
+	} else {
+		reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_WC(bytes_per_pkt);
+		dsi_write(msm_host, REG_DSI_VIDEO_COMPRESSION_MODE_CTRL, reg);
+	}
+}
+
+static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
+{
+	struct drm_display_mode *mode = msm_host->mode;
+	u32 hs_start = 0, vs_start = 0; /* take sync start as 0 */
+	u32 h_total = mode->htotal;
+	u32 v_total = mode->vtotal;
+	u32 hs_end = mode->hsync_end - mode->hsync_start;
+	u32 vs_end = mode->vsync_end - mode->vsync_start;
+	u32 ha_start = h_total - mode->hsync_start;
+	u32 ha_end = ha_start + mode->hdisplay;
+	u32 va_start = v_total - mode->vsync_start;
+	u32 va_end = va_start + mode->vdisplay;
+	u32 hdisplay = mode->hdisplay;
+	u32 wc;
+	int ret;
+	bool wide_bus_enabled = msm_dsi_host_is_wide_bus_enabled(&msm_host->base);
+
+	DBG("");
+
+	/*
+	 * For bonded DSI mode, the current DRM mode has
+	 * the complete width of the panel. Since, the complete
+	 * panel is driven by two DSI controllers, the horizontal
+	 * timings have to be split between the two dsi controllers.
+	 * Adjust the DSI host timing values accordingly.
+	 */
+	if (is_bonded_dsi) {
+		h_total /= 2;
+		hs_end /= 2;
+		ha_start /= 2;
+		ha_end /= 2;
+		hdisplay /= 2;
+	}
+
+	if (msm_host->dsc) {
+		struct drm_dsc_config *dsc = msm_host->dsc;
+		u32 bytes_per_pclk;
+
+		/* update dsc params with timing params */
+		if (!dsc || !mode->hdisplay || !mode->vdisplay) {
+			pr_err("DSI: invalid input: pic_width: %d pic_height: %d\n",
+			       mode->hdisplay, mode->vdisplay);
+			return;
+		}
+
+		dsc->pic_width = mode->hdisplay;
+		dsc->pic_height = mode->vdisplay;
+		DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height);
+
+		/* we do the calculations for dsc parameters here so that
+		 * panel can use these parameters
+		 */
+		ret = dsi_populate_dsc_params(msm_host, dsc);
+		if (ret)
+			return;
+
+		/* Divide the display by 3 but keep back/font porch and
+		 * pulse width same
+		 */
+		h_total -= hdisplay;
+		if (wide_bus_enabled && !(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO))
+			bytes_per_pclk = 6;
+		else
+			bytes_per_pclk = 3;
+
+		hdisplay = DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), bytes_per_pclk);
+
+		h_total += hdisplay;
+		ha_end = ha_start + hdisplay;
+	}
+
+	if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) {
+		if (msm_host->dsc)
+			dsi_update_dsc_timing(msm_host, false, mode->hdisplay);
+
+		dsi_write(msm_host, REG_DSI_ACTIVE_H,
+			DSI_ACTIVE_H_START(ha_start) |
+			DSI_ACTIVE_H_END(ha_end));
+		dsi_write(msm_host, REG_DSI_ACTIVE_V,
+			DSI_ACTIVE_V_START(va_start) |
+			DSI_ACTIVE_V_END(va_end));
+		dsi_write(msm_host, REG_DSI_TOTAL,
+			DSI_TOTAL_H_TOTAL(h_total - 1) |
+			DSI_TOTAL_V_TOTAL(v_total - 1));
+
+		dsi_write(msm_host, REG_DSI_ACTIVE_HSYNC,
+			DSI_ACTIVE_HSYNC_START(hs_start) |
+			DSI_ACTIVE_HSYNC_END(hs_end));
+		dsi_write(msm_host, REG_DSI_ACTIVE_VSYNC_HPOS, 0);
+		dsi_write(msm_host, REG_DSI_ACTIVE_VSYNC_VPOS,
+			DSI_ACTIVE_VSYNC_VPOS_START(vs_start) |
+			DSI_ACTIVE_VSYNC_VPOS_END(vs_end));
+	} else {		/* command mode */
+		if (msm_host->dsc)
+			dsi_update_dsc_timing(msm_host, true, mode->hdisplay);
+
+		/* image data and 1 byte write_memory_start cmd */
+		if (!msm_host->dsc)
+			wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1;
+		else
+			/*
+			 * When DSC is enabled, WC = slice_chunk_size * slice_per_pkt + 1.
+			 * Currently, the driver only supports default value of slice_per_pkt = 1
+			 *
+			 * TODO: Expand mipi_dsi_device struct to hold slice_per_pkt info
+			 *       and adjust DSC math to account for slice_per_pkt.
+			 */
+			wc = msm_host->dsc->slice_chunk_size + 1;
+
+		dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL,
+			DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) |
+			DSI_CMD_MDP_STREAM0_CTRL_VIRTUAL_CHANNEL(
+					msm_host->channel) |
+			DSI_CMD_MDP_STREAM0_CTRL_DATA_TYPE(
+					MIPI_DSI_DCS_LONG_WRITE));
+
+		dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_TOTAL,
+			DSI_CMD_MDP_STREAM0_TOTAL_H_TOTAL(hdisplay) |
+			DSI_CMD_MDP_STREAM0_TOTAL_V_TOTAL(mode->vdisplay));
+	}
+}
+
+static void dsi_sw_reset(struct msm_dsi_host *msm_host)
+{
+	u32 ctrl;
+
+	ctrl = dsi_read(msm_host, REG_DSI_CTRL);
+
+	if (ctrl & DSI_CTRL_ENABLE) {
+		dsi_write(msm_host, REG_DSI_CTRL, ctrl & ~DSI_CTRL_ENABLE);
+		/*
+		 * dsi controller need to be disabled before
+		 * clocks turned on
+		 */
+		wmb();
+	}
+
+	dsi_write(msm_host, REG_DSI_CLK_CTRL, DSI_CLK_CTRL_ENABLE_CLKS);
+	wmb(); /* clocks need to be enabled before reset */
+
+	/* dsi controller can only be reset while clocks are running */
+	dsi_write(msm_host, REG_DSI_RESET, 1);
+	msleep(DSI_RESET_TOGGLE_DELAY_MS); /* make sure reset happen */
+	dsi_write(msm_host, REG_DSI_RESET, 0);
+	wmb(); /* controller out of reset */
+
+	if (ctrl & DSI_CTRL_ENABLE) {
+		dsi_write(msm_host, REG_DSI_CTRL, ctrl);
+		wmb();	/* make sure dsi controller enabled again */
+	}
+}
+
+static void dsi_op_mode_config(struct msm_dsi_host *msm_host,
+					bool video_mode, bool enable)
+{
+	u32 dsi_ctrl;
+
+	dsi_ctrl = dsi_read(msm_host, REG_DSI_CTRL);
+
+	if (!enable) {
+		dsi_ctrl &= ~(DSI_CTRL_ENABLE | DSI_CTRL_VID_MODE_EN |
+				DSI_CTRL_CMD_MODE_EN);
+		dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_CMD_MDP_DONE |
+					DSI_IRQ_MASK_VIDEO_DONE, 0);
+	} else {
+		if (video_mode) {
+			dsi_ctrl |= DSI_CTRL_VID_MODE_EN;
+		} else {		/* command mode */
+			dsi_ctrl |= DSI_CTRL_CMD_MODE_EN;
+			dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_CMD_MDP_DONE, 1);
+		}
+		dsi_ctrl |= DSI_CTRL_ENABLE;
+	}
+
+	dsi_write(msm_host, REG_DSI_CTRL, dsi_ctrl);
+}
+
+static void dsi_set_tx_power_mode(int mode, struct msm_dsi_host *msm_host)
+{
+	u32 data;
+
+	data = dsi_read(msm_host, REG_DSI_CMD_DMA_CTRL);
+
+	if (mode == 0)
+		data &= ~DSI_CMD_DMA_CTRL_LOW_POWER;
+	else
+		data |= DSI_CMD_DMA_CTRL_LOW_POWER;
+
+	dsi_write(msm_host, REG_DSI_CMD_DMA_CTRL, data);
+}
+
+static void dsi_wait4video_done(struct msm_dsi_host *msm_host)
+{
+	u32 ret = 0;
+	struct device *dev = &msm_host->pdev->dev;
+
+	dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 1);
+
+	reinit_completion(&msm_host->video_comp);
+
+	ret = wait_for_completion_timeout(&msm_host->video_comp,
+			msecs_to_jiffies(70));
+
+	if (ret == 0)
+		DRM_DEV_ERROR(dev, "wait for video done timed out\n");
+
+	dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_VIDEO_DONE, 0);
+}
+
+static void dsi_wait4video_eng_busy(struct msm_dsi_host *msm_host)
+{
+	u32 data;
+
+	if (!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO))
+		return;
+
+	data = dsi_read(msm_host, REG_DSI_STATUS0);
+
+	/* if video mode engine is not busy, its because
+	 * either timing engine was not turned on or the
+	 * DSI controller has finished transmitting the video
+	 * data already, so no need to wait in those cases
+	 */
+	if (!(data & DSI_STATUS0_VIDEO_MODE_ENGINE_BUSY))
+		return;
+
+	if (msm_host->power_on && msm_host->enabled) {
+		dsi_wait4video_done(msm_host);
+		/* delay 4 ms to skip BLLP */
+		usleep_range(2000, 4000);
+	}
+}
+
+int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size)
+{
+	struct drm_device *dev = msm_host->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	uint64_t iova;
+	u8 *data;
+
+	msm_host->aspace = msm_gem_address_space_get(priv->kms->aspace);
+
+	data = msm_gem_kernel_new(dev, size, MSM_BO_WC,
+					msm_host->aspace,
+					&msm_host->tx_gem_obj, &iova);
+
+	if (IS_ERR(data)) {
+		msm_host->tx_gem_obj = NULL;
+		return PTR_ERR(data);
+	}
+
+	msm_gem_object_set_name(msm_host->tx_gem_obj, "tx_gem");
+
+	msm_host->tx_size = msm_host->tx_gem_obj->size;
+
+	return 0;
+}
+
+int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size)
+{
+	struct drm_device *dev = msm_host->dev;
+
+	msm_host->tx_buf = dma_alloc_coherent(dev->dev, size,
+					&msm_host->tx_buf_paddr, GFP_KERNEL);
+	if (!msm_host->tx_buf)
+		return -ENOMEM;
+
+	msm_host->tx_size = size;
+
+	return 0;
+}
+
+void msm_dsi_tx_buf_free(struct mipi_dsi_host *host)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	struct drm_device *dev = msm_host->dev;
+
+	/*
+	 * This is possible if we're tearing down before we've had a chance to
+	 * fully initialize. A very real possibility if our probe is deferred,
+	 * in which case we'll hit msm_dsi_host_destroy() without having run
+	 * through the dsi_tx_buf_alloc().
+	 */
+	if (!dev)
+		return;
+
+	if (msm_host->tx_gem_obj) {
+		msm_gem_kernel_put(msm_host->tx_gem_obj, msm_host->aspace);
+		msm_gem_address_space_put(msm_host->aspace);
+		msm_host->tx_gem_obj = NULL;
+		msm_host->aspace = NULL;
+	}
+
+	if (msm_host->tx_buf)
+		dma_free_coherent(dev->dev, msm_host->tx_size, msm_host->tx_buf,
+			msm_host->tx_buf_paddr);
+}
+
+void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host)
+{
+	return msm_gem_get_vaddr(msm_host->tx_gem_obj);
+}
+
+void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host)
+{
+	return msm_host->tx_buf;
+}
+
+void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host)
+{
+	msm_gem_put_vaddr(msm_host->tx_gem_obj);
+}
+
+/*
+ * prepare cmd buffer to be txed
+ */
+static int dsi_cmd_dma_add(struct msm_dsi_host *msm_host,
+			   const struct mipi_dsi_msg *msg)
+{
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
+	struct mipi_dsi_packet packet;
+	int len;
+	int ret;
+	u8 *data;
+
+	ret = mipi_dsi_create_packet(&packet, msg);
+	if (ret) {
+		pr_err("%s: create packet failed, %d\n", __func__, ret);
+		return ret;
+	}
+	len = (packet.size + 3) & (~0x3);
+
+	if (len > msm_host->tx_size) {
+		pr_err("%s: packet size is too big\n", __func__);
+		return -EINVAL;
+	}
+
+	data = cfg_hnd->ops->tx_buf_get(msm_host);
+	if (IS_ERR(data)) {
+		ret = PTR_ERR(data);
+		pr_err("%s: get vaddr failed, %d\n", __func__, ret);
+		return ret;
+	}
+
+	/* MSM specific command format in memory */
+	data[0] = packet.header[1];
+	data[1] = packet.header[2];
+	data[2] = packet.header[0];
+	data[3] = BIT(7); /* Last packet */
+	if (mipi_dsi_packet_format_is_long(msg->type))
+		data[3] |= BIT(6);
+	if (msg->rx_buf && msg->rx_len)
+		data[3] |= BIT(5);
+
+	/* Long packet */
+	if (packet.payload && packet.payload_length)
+		memcpy(data + 4, packet.payload, packet.payload_length);
+
+	/* Append 0xff to the end */
+	if (packet.size < len)
+		memset(data + packet.size, 0xff, len - packet.size);
+
+	if (cfg_hnd->ops->tx_buf_put)
+		cfg_hnd->ops->tx_buf_put(msm_host);
+
+	return len;
+}
+
+/*
+ * dsi_short_read1_resp: 1 parameter
+ */
+static int dsi_short_read1_resp(u8 *buf, const struct mipi_dsi_msg *msg)
+{
+	u8 *data = msg->rx_buf;
+	if (data && (msg->rx_len >= 1)) {
+		*data = buf[1]; /* strip out dcs type */
+		return 1;
+	} else {
+		pr_err("%s: read data does not match with rx_buf len %zu\n",
+			__func__, msg->rx_len);
+		return -EINVAL;
+	}
+}
+
+/*
+ * dsi_short_read2_resp: 2 parameter
+ */
+static int dsi_short_read2_resp(u8 *buf, const struct mipi_dsi_msg *msg)
+{
+	u8 *data = msg->rx_buf;
+	if (data && (msg->rx_len >= 2)) {
+		data[0] = buf[1]; /* strip out dcs type */
+		data[1] = buf[2];
+		return 2;
+	} else {
+		pr_err("%s: read data does not match with rx_buf len %zu\n",
+			__func__, msg->rx_len);
+		return -EINVAL;
+	}
+}
+
+static int dsi_long_read_resp(u8 *buf, const struct mipi_dsi_msg *msg)
+{
+	/* strip out 4 byte dcs header */
+	if (msg->rx_buf && msg->rx_len)
+		memcpy(msg->rx_buf, buf + 4, msg->rx_len);
+
+	return msg->rx_len;
+}
+
+int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *dma_base)
+{
+	struct drm_device *dev = msm_host->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+
+	if (!dma_base)
+		return -EINVAL;
+
+	return msm_gem_get_and_pin_iova(msm_host->tx_gem_obj,
+				priv->kms->aspace, dma_base);
+}
+
+int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *dma_base)
+{
+	if (!dma_base)
+		return -EINVAL;
+
+	*dma_base = msm_host->tx_buf_paddr;
+	return 0;
+}
+
+static int dsi_cmd_dma_tx(struct msm_dsi_host *msm_host, int len)
+{
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
+	int ret;
+	uint64_t dma_base;
+	bool triggered;
+
+	ret = cfg_hnd->ops->dma_base_get(msm_host, &dma_base);
+	if (ret) {
+		pr_err("%s: failed to get iova: %d\n", __func__, ret);
+		return ret;
+	}
+
+	reinit_completion(&msm_host->dma_comp);
+
+	dsi_wait4video_eng_busy(msm_host);
+
+	triggered = msm_dsi_manager_cmd_xfer_trigger(
+						msm_host->id, dma_base, len);
+	if (triggered) {
+		ret = wait_for_completion_timeout(&msm_host->dma_comp,
+					msecs_to_jiffies(200));
+		DBG("ret=%d", ret);
+		if (ret == 0)
+			ret = -ETIMEDOUT;
+		else
+			ret = len;
+	} else
+		ret = len;
+
+	return ret;
+}
+
+static int dsi_cmd_dma_rx(struct msm_dsi_host *msm_host,
+			u8 *buf, int rx_byte, int pkt_size)
+{
+	u32 *temp, data;
+	int i, j = 0, cnt;
+	u32 read_cnt;
+	u8 reg[16];
+	int repeated_bytes = 0;
+	int buf_offset = buf - msm_host->rx_buf;
+
+	temp = (u32 *)reg;
+	cnt = (rx_byte + 3) >> 2;
+	if (cnt > 4)
+		cnt = 4; /* 4 x 32 bits registers only */
+
+	if (rx_byte == 4)
+		read_cnt = 4;
+	else
+		read_cnt = pkt_size + 6;
+
+	/*
+	 * In case of multiple reads from the panel, after the first read, there
+	 * is possibility that there are some bytes in the payload repeating in
+	 * the RDBK_DATA registers. Since we read all the parameters from the
+	 * panel right from the first byte for every pass. We need to skip the
+	 * repeating bytes and then append the new parameters to the rx buffer.
+	 */
+	if (read_cnt > 16) {
+		int bytes_shifted;
+		/* Any data more than 16 bytes will be shifted out.
+		 * The temp read buffer should already contain these bytes.
+		 * The remaining bytes in read buffer are the repeated bytes.
+		 */
+		bytes_shifted = read_cnt - 16;
+		repeated_bytes = buf_offset - bytes_shifted;
+	}
+
+	for (i = cnt - 1; i >= 0; i--) {
+		data = dsi_read(msm_host, REG_DSI_RDBK_DATA(i));
+		*temp++ = ntohl(data); /* to host byte order */
+		DBG("data = 0x%x and ntohl(data) = 0x%x", data, ntohl(data));
+	}
+
+	for (i = repeated_bytes; i < 16; i++)
+		buf[j++] = reg[i];
+
+	return j;
+}
+
+static int dsi_cmds2buf_tx(struct msm_dsi_host *msm_host,
+				const struct mipi_dsi_msg *msg)
+{
+	int len, ret;
+	int bllp_len = msm_host->mode->hdisplay *
+			dsi_get_bpp(msm_host->format) / 8;
+
+	len = dsi_cmd_dma_add(msm_host, msg);
+	if (len < 0) {
+		pr_err("%s: failed to add cmd type = 0x%x\n",
+			__func__,  msg->type);
+		return len;
+	}
+
+	/* for video mode, do not send cmds more than
+	* one pixel line, since it only transmit it
+	* during BLLP.
+	*/
+	/* TODO: if the command is sent in LP mode, the bit rate is only
+	 * half of esc clk rate. In this case, if the video is already
+	 * actively streaming, we need to check more carefully if the
+	 * command can be fit into one BLLP.
+	 */
+	if ((msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) && (len > bllp_len)) {
+		pr_err("%s: cmd cannot fit into BLLP period, len=%d\n",
+			__func__, len);
+		return -EINVAL;
+	}
+
+	ret = dsi_cmd_dma_tx(msm_host, len);
+	if (ret < 0) {
+		pr_err("%s: cmd dma tx failed, type=0x%x, data0=0x%x, len=%d, ret=%d\n",
+			__func__, msg->type, (*(u8 *)(msg->tx_buf)), len, ret);
+		return ret;
+	} else if (ret < len) {
+		pr_err("%s: cmd dma tx failed, type=0x%x, data0=0x%x, ret=%d len=%d\n",
+			__func__, msg->type, (*(u8 *)(msg->tx_buf)), ret, len);
+		return -EIO;
+	}
+
+	return len;
+}
+
+static void dsi_err_worker(struct work_struct *work)
+{
+	struct msm_dsi_host *msm_host =
+		container_of(work, struct msm_dsi_host, err_work);
+	u32 status = msm_host->err_work_state;
+
+	pr_err_ratelimited("%s: status=%x\n", __func__, status);
+	if (status & DSI_ERR_STATE_MDP_FIFO_UNDERFLOW)
+		dsi_sw_reset(msm_host);
+
+	/* It is safe to clear here because error irq is disabled. */
+	msm_host->err_work_state = 0;
+
+	/* enable dsi error interrupt */
+	dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_ERROR, 1);
+}
+
+static void dsi_ack_err_status(struct msm_dsi_host *msm_host)
+{
+	u32 status;
+
+	status = dsi_read(msm_host, REG_DSI_ACK_ERR_STATUS);
+
+	if (status) {
+		dsi_write(msm_host, REG_DSI_ACK_ERR_STATUS, status);
+		/* Writing of an extra 0 needed to clear error bits */
+		dsi_write(msm_host, REG_DSI_ACK_ERR_STATUS, 0);
+		msm_host->err_work_state |= DSI_ERR_STATE_ACK;
+	}
+}
+
+static void dsi_timeout_status(struct msm_dsi_host *msm_host)
+{
+	u32 status;
+
+	status = dsi_read(msm_host, REG_DSI_TIMEOUT_STATUS);
+
+	if (status) {
+		dsi_write(msm_host, REG_DSI_TIMEOUT_STATUS, status);
+		msm_host->err_work_state |= DSI_ERR_STATE_TIMEOUT;
+	}
+}
+
+static void dsi_dln0_phy_err(struct msm_dsi_host *msm_host)
+{
+	u32 status;
+
+	status = dsi_read(msm_host, REG_DSI_DLN0_PHY_ERR);
+
+	if (status & (DSI_DLN0_PHY_ERR_DLN0_ERR_ESC |
+			DSI_DLN0_PHY_ERR_DLN0_ERR_SYNC_ESC |
+			DSI_DLN0_PHY_ERR_DLN0_ERR_CONTROL |
+			DSI_DLN0_PHY_ERR_DLN0_ERR_CONTENTION_LP0 |
+			DSI_DLN0_PHY_ERR_DLN0_ERR_CONTENTION_LP1)) {
+		dsi_write(msm_host, REG_DSI_DLN0_PHY_ERR, status);
+		msm_host->err_work_state |= DSI_ERR_STATE_DLN0_PHY;
+	}
+}
+
+static void dsi_fifo_status(struct msm_dsi_host *msm_host)
+{
+	u32 status;
+
+	status = dsi_read(msm_host, REG_DSI_FIFO_STATUS);
+
+	/* fifo underflow, overflow */
+	if (status) {
+		dsi_write(msm_host, REG_DSI_FIFO_STATUS, status);
+		msm_host->err_work_state |= DSI_ERR_STATE_FIFO;
+		if (status & DSI_FIFO_STATUS_CMD_MDP_FIFO_UNDERFLOW)
+			msm_host->err_work_state |=
+					DSI_ERR_STATE_MDP_FIFO_UNDERFLOW;
+	}
+}
+
+static void dsi_status(struct msm_dsi_host *msm_host)
+{
+	u32 status;
+
+	status = dsi_read(msm_host, REG_DSI_STATUS0);
+
+	if (status & DSI_STATUS0_INTERLEAVE_OP_CONTENTION) {
+		dsi_write(msm_host, REG_DSI_STATUS0, status);
+		msm_host->err_work_state |=
+			DSI_ERR_STATE_INTERLEAVE_OP_CONTENTION;
+	}
+}
+
+static void dsi_clk_status(struct msm_dsi_host *msm_host)
+{
+	u32 status;
+
+	status = dsi_read(msm_host, REG_DSI_CLK_STATUS);
+
+	if (status & DSI_CLK_STATUS_PLL_UNLOCKED) {
+		dsi_write(msm_host, REG_DSI_CLK_STATUS, status);
+		msm_host->err_work_state |= DSI_ERR_STATE_PLL_UNLOCKED;
+	}
+}
+
+static void dsi_error(struct msm_dsi_host *msm_host)
+{
+	/* disable dsi error interrupt */
+	dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_ERROR, 0);
+
+	dsi_clk_status(msm_host);
+	dsi_fifo_status(msm_host);
+	dsi_ack_err_status(msm_host);
+	dsi_timeout_status(msm_host);
+	dsi_status(msm_host);
+	dsi_dln0_phy_err(msm_host);
+
+	queue_work(msm_host->workqueue, &msm_host->err_work);
+}
+
+static irqreturn_t dsi_host_irq(int irq, void *ptr)
+{
+	struct msm_dsi_host *msm_host = ptr;
+	u32 isr;
+	unsigned long flags;
+
+	if (!msm_host->ctrl_base)
+		return IRQ_HANDLED;
+
+	spin_lock_irqsave(&msm_host->intr_lock, flags);
+	isr = dsi_read(msm_host, REG_DSI_INTR_CTRL);
+	dsi_write(msm_host, REG_DSI_INTR_CTRL, isr);
+	spin_unlock_irqrestore(&msm_host->intr_lock, flags);
+
+	DBG("isr=0x%x, id=%d", isr, msm_host->id);
+
+	if (isr & DSI_IRQ_ERROR)
+		dsi_error(msm_host);
+
+	if (isr & DSI_IRQ_VIDEO_DONE)
+		complete(&msm_host->video_comp);
+
+	if (isr & DSI_IRQ_CMD_DMA_DONE)
+		complete(&msm_host->dma_comp);
+
+	return IRQ_HANDLED;
+}
+
+static int dsi_host_init_panel_gpios(struct msm_dsi_host *msm_host,
+			struct device *panel_device)
+{
+	msm_host->disp_en_gpio = devm_gpiod_get_optional(panel_device,
+							 "disp-enable",
+							 GPIOD_OUT_LOW);
+	if (IS_ERR(msm_host->disp_en_gpio)) {
+		DBG("cannot get disp-enable-gpios %ld",
+				PTR_ERR(msm_host->disp_en_gpio));
+		return PTR_ERR(msm_host->disp_en_gpio);
+	}
+
+	msm_host->te_gpio = devm_gpiod_get_optional(panel_device, "disp-te",
+								GPIOD_IN);
+	if (IS_ERR(msm_host->te_gpio)) {
+		DBG("cannot get disp-te-gpios %ld", PTR_ERR(msm_host->te_gpio));
+		return PTR_ERR(msm_host->te_gpio);
+	}
+
+	return 0;
+}
+
+static int dsi_host_attach(struct mipi_dsi_host *host,
+					struct mipi_dsi_device *dsi)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	int ret;
+
+	if (dsi->lanes > msm_host->num_data_lanes)
+		return -EINVAL;
+
+	msm_host->channel = dsi->channel;
+	msm_host->lanes = dsi->lanes;
+	msm_host->format = dsi->format;
+	msm_host->mode_flags = dsi->mode_flags;
+	if (dsi->dsc)
+		msm_host->dsc = dsi->dsc;
+
+	/* Some gpios defined in panel DT need to be controlled by host */
+	ret = dsi_host_init_panel_gpios(msm_host, &dsi->dev);
+	if (ret)
+		return ret;
+
+	ret = dsi_dev_attach(msm_host->pdev);
+	if (ret)
+		return ret;
+
+	DBG("id=%d", msm_host->id);
+
+	return 0;
+}
+
+static int dsi_host_detach(struct mipi_dsi_host *host,
+					struct mipi_dsi_device *dsi)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	dsi_dev_detach(msm_host->pdev);
+
+	DBG("id=%d", msm_host->id);
+
+	return 0;
+}
+
+static ssize_t dsi_host_transfer(struct mipi_dsi_host *host,
+					const struct mipi_dsi_msg *msg)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	int ret;
+
+	if (!msg || !msm_host->power_on)
+		return -EINVAL;
+
+	mutex_lock(&msm_host->cmd_mutex);
+	ret = msm_dsi_manager_cmd_xfer(msm_host->id, msg);
+	mutex_unlock(&msm_host->cmd_mutex);
+
+	return ret;
+}
+
+static const struct mipi_dsi_host_ops dsi_host_ops = {
+	.attach = dsi_host_attach,
+	.detach = dsi_host_detach,
+	.transfer = dsi_host_transfer,
+};
+
+/*
+ * List of supported physical to logical lane mappings.
+ * For example, the 2nd entry represents the following mapping:
+ *
+ * "3012": Logic 3->Phys 0; Logic 0->Phys 1; Logic 1->Phys 2; Logic 2->Phys 3;
+ */
+static const int supported_data_lane_swaps[][4] = {
+	{ 0, 1, 2, 3 },
+	{ 3, 0, 1, 2 },
+	{ 2, 3, 0, 1 },
+	{ 1, 2, 3, 0 },
+	{ 0, 3, 2, 1 },
+	{ 1, 0, 3, 2 },
+	{ 2, 1, 0, 3 },
+	{ 3, 2, 1, 0 },
+};
+
+static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host,
+				    struct device_node *ep)
+{
+	struct device *dev = &msm_host->pdev->dev;
+	struct property *prop;
+	u32 lane_map[4];
+	int ret, i, len, num_lanes;
+
+	prop = of_find_property(ep, "data-lanes", &len);
+	if (!prop) {
+		DRM_DEV_DEBUG(dev,
+			"failed to find data lane mapping, using default\n");
+		/* Set the number of date lanes to 4 by default. */
+		msm_host->num_data_lanes = 4;
+		return 0;
+	}
+
+	num_lanes = drm_of_get_data_lanes_count(ep, 1, 4);
+	if (num_lanes < 0) {
+		DRM_DEV_ERROR(dev, "bad number of data lanes\n");
+		return num_lanes;
+	}
+
+	msm_host->num_data_lanes = num_lanes;
+
+	ret = of_property_read_u32_array(ep, "data-lanes", lane_map,
+					 num_lanes);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "failed to read lane data\n");
+		return ret;
+	}
+
+	/*
+	 * compare DT specified physical-logical lane mappings with the ones
+	 * supported by hardware
+	 */
+	for (i = 0; i < ARRAY_SIZE(supported_data_lane_swaps); i++) {
+		const int *swap = supported_data_lane_swaps[i];
+		int j;
+
+		/*
+		 * the data-lanes array we get from DT has a logical->physical
+		 * mapping. The "data lane swap" register field represents
+		 * supported configurations in a physical->logical mapping.
+		 * Translate the DT mapping to what we understand and find a
+		 * configuration that works.
+		 */
+		for (j = 0; j < num_lanes; j++) {
+			if (lane_map[j] < 0 || lane_map[j] > 3)
+				DRM_DEV_ERROR(dev, "bad physical lane entry %u\n",
+					lane_map[j]);
+
+			if (swap[lane_map[j]] != j)
+				break;
+		}
+
+		if (j == num_lanes) {
+			msm_host->dlane_swap = i;
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc)
+{
+	int ret;
+
+	if (dsc->bits_per_pixel & 0xf) {
+		DRM_DEV_ERROR(&msm_host->pdev->dev, "DSI does not support fractional bits_per_pixel\n");
+		return -EINVAL;
+	}
+
+	if (dsc->bits_per_component != 8) {
+		DRM_DEV_ERROR(&msm_host->pdev->dev, "DSI does not support bits_per_component != 8 yet\n");
+		return -EOPNOTSUPP;
+	}
+
+	dsc->simple_422 = 0;
+	dsc->convert_rgb = 1;
+	dsc->vbr_enable = 0;
+
+	drm_dsc_set_const_params(dsc);
+	drm_dsc_set_rc_buf_thresh(dsc);
+
+	/* handle only bpp = bpc = 8, pre-SCR panels */
+	ret = drm_dsc_setup_rc_params(dsc, DRM_DSC_1_1_PRE_SCR);
+	if (ret) {
+		DRM_DEV_ERROR(&msm_host->pdev->dev, "could not find DSC RC parameters\n");
+		return ret;
+	}
+
+	dsc->initial_scale_value = drm_dsc_initial_scale_value(dsc);
+	dsc->line_buf_depth = dsc->bits_per_component + 1;
+
+	return drm_dsc_compute_rc_parameters(dsc);
+}
+
+static int dsi_host_parse_dt(struct msm_dsi_host *msm_host)
+{
+	struct device *dev = &msm_host->pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct device_node *endpoint;
+	int ret = 0;
+
+	/*
+	 * Get the endpoint of the output port of the DSI host. In our case,
+	 * this is mapped to port number with reg = 1. Don't return an error if
+	 * the remote endpoint isn't defined. It's possible that there is
+	 * nothing connected to the dsi output.
+	 */
+	endpoint = of_graph_get_endpoint_by_regs(np, 1, -1);
+	if (!endpoint) {
+		DRM_DEV_DEBUG(dev, "%s: no endpoint\n", __func__);
+		return 0;
+	}
+
+	ret = dsi_host_parse_lane_data(msm_host, endpoint);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "%s: invalid lane configuration %d\n",
+			__func__, ret);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (of_property_read_bool(np, "syscon-sfpb")) {
+		msm_host->sfpb = syscon_regmap_lookup_by_phandle(np,
+					"syscon-sfpb");
+		if (IS_ERR(msm_host->sfpb)) {
+			DRM_DEV_ERROR(dev, "%s: failed to get sfpb regmap\n",
+				__func__);
+			ret = PTR_ERR(msm_host->sfpb);
+		}
+	}
+
+err:
+	of_node_put(endpoint);
+
+	return ret;
+}
+
+static int dsi_host_get_id(struct msm_dsi_host *msm_host)
+{
+	struct platform_device *pdev = msm_host->pdev;
+	const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg;
+	struct resource *res;
+	int i, j;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dsi_ctrl");
+	if (!res)
+		return -EINVAL;
+
+	for (i = 0; i < VARIANTS_MAX; i++)
+		for (j = 0; j < DSI_MAX; j++)
+			if (cfg->io_start[i][j] == res->start)
+				return j;
+
+	return -EINVAL;
+}
+
+int msm_dsi_host_init(struct msm_dsi *msm_dsi)
+{
+	struct msm_dsi_host *msm_host = NULL;
+	struct platform_device *pdev = msm_dsi->pdev;
+	const struct msm_dsi_config *cfg;
+	int ret;
+
+	msm_host = devm_kzalloc(&pdev->dev, sizeof(*msm_host), GFP_KERNEL);
+	if (!msm_host) {
+		return -ENOMEM;
+	}
+
+	msm_host->pdev = pdev;
+	msm_dsi->host = &msm_host->base;
+
+	ret = dsi_host_parse_dt(msm_host);
+	if (ret) {
+		pr_err("%s: failed to parse dt\n", __func__);
+		return ret;
+	}
+
+	msm_host->ctrl_base = msm_ioremap_size(pdev, "dsi_ctrl", &msm_host->ctrl_size);
+	if (IS_ERR(msm_host->ctrl_base)) {
+		pr_err("%s: unable to map Dsi ctrl base\n", __func__);
+		return PTR_ERR(msm_host->ctrl_base);
+	}
+
+	pm_runtime_enable(&pdev->dev);
+
+	msm_host->cfg_hnd = dsi_get_config(msm_host);
+	if (!msm_host->cfg_hnd) {
+		pr_err("%s: get config failed\n", __func__);
+		return -EINVAL;
+	}
+	cfg = msm_host->cfg_hnd->cfg;
+
+	msm_host->id = dsi_host_get_id(msm_host);
+	if (msm_host->id < 0) {
+		pr_err("%s: unable to identify DSI host index\n", __func__);
+		return msm_host->id;
+	}
+
+	/* fixup base address by io offset */
+	msm_host->ctrl_base += cfg->io_offset;
+
+	ret = devm_regulator_bulk_get_const(&pdev->dev, cfg->num_regulators,
+					    cfg->regulator_data,
+					    &msm_host->supplies);
+	if (ret)
+		return ret;
+
+	ret = dsi_clk_init(msm_host);
+	if (ret) {
+		pr_err("%s: unable to initialize dsi clks\n", __func__);
+		return ret;
+	}
+
+	msm_host->rx_buf = devm_kzalloc(&pdev->dev, SZ_4K, GFP_KERNEL);
+	if (!msm_host->rx_buf) {
+		pr_err("%s: alloc rx temp buf failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	ret = devm_pm_opp_set_clkname(&pdev->dev, "byte");
+	if (ret)
+		return ret;
+	/* OPP table is optional */
+	ret = devm_pm_opp_of_add_table(&pdev->dev);
+	if (ret && ret != -ENODEV) {
+		dev_err(&pdev->dev, "invalid OPP table in device tree\n");
+		return ret;
+	}
+
+	msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+	if (!msm_host->irq) {
+		dev_err(&pdev->dev, "failed to get irq\n");
+		return -EINVAL;
+	}
+
+	/* do not autoenable, will be enabled later */
+	ret = devm_request_irq(&pdev->dev, msm_host->irq, dsi_host_irq,
+			IRQF_TRIGGER_HIGH | IRQF_NO_AUTOEN,
+			"dsi_isr", msm_host);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to request IRQ%u: %d\n",
+				msm_host->irq, ret);
+		return ret;
+	}
+
+	init_completion(&msm_host->dma_comp);
+	init_completion(&msm_host->video_comp);
+	mutex_init(&msm_host->dev_mutex);
+	mutex_init(&msm_host->cmd_mutex);
+	spin_lock_init(&msm_host->intr_lock);
+
+	/* setup workqueue */
+	msm_host->workqueue = alloc_ordered_workqueue("dsi_drm_work", 0);
+	if (!msm_host->workqueue)
+		return -ENOMEM;
+
+	INIT_WORK(&msm_host->err_work, dsi_err_worker);
+
+	msm_dsi->id = msm_host->id;
+
+	DBG("Dsi Host %d initialized", msm_host->id);
+	return 0;
+}
+
+void msm_dsi_host_destroy(struct mipi_dsi_host *host)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	DBG("");
+	if (msm_host->workqueue) {
+		destroy_workqueue(msm_host->workqueue);
+		msm_host->workqueue = NULL;
+	}
+
+	mutex_destroy(&msm_host->cmd_mutex);
+	mutex_destroy(&msm_host->dev_mutex);
+
+	pm_runtime_disable(&msm_host->pdev->dev);
+}
+
+int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
+					struct drm_device *dev)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
+	int ret;
+
+	msm_host->dev = dev;
+
+	ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
+	if (ret) {
+		pr_err("%s: alloc tx gem obj failed, %d\n", __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+int msm_dsi_host_register(struct mipi_dsi_host *host)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	int ret;
+
+	/* Register mipi dsi host */
+	if (!msm_host->registered) {
+		host->dev = &msm_host->pdev->dev;
+		host->ops = &dsi_host_ops;
+		ret = mipi_dsi_host_register(host);
+		if (ret)
+			return ret;
+
+		msm_host->registered = true;
+	}
+
+	return 0;
+}
+
+void msm_dsi_host_unregister(struct mipi_dsi_host *host)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	if (msm_host->registered) {
+		mipi_dsi_host_unregister(host);
+		host->dev = NULL;
+		host->ops = NULL;
+		msm_host->registered = false;
+	}
+}
+
+int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
+				const struct mipi_dsi_msg *msg)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
+
+	/* TODO: make sure dsi_cmd_mdp is idle.
+	 * Since DSI6G v1.2.0, we can set DSI_TRIG_CTRL.BLOCK_DMA_WITHIN_FRAME
+	 * to ask H/W to wait until cmd mdp is idle. S/W wait is not needed.
+	 * How to handle the old versions? Wait for mdp cmd done?
+	 */
+
+	/*
+	 * mdss interrupt is generated in mdp core clock domain
+	 * mdp clock need to be enabled to receive dsi interrupt
+	 */
+	pm_runtime_get_sync(&msm_host->pdev->dev);
+	cfg_hnd->ops->link_clk_set_rate(msm_host);
+	cfg_hnd->ops->link_clk_enable(msm_host);
+
+	/* TODO: vote for bus bandwidth */
+
+	if (!(msg->flags & MIPI_DSI_MSG_USE_LPM))
+		dsi_set_tx_power_mode(0, msm_host);
+
+	msm_host->dma_cmd_ctrl_restore = dsi_read(msm_host, REG_DSI_CTRL);
+	dsi_write(msm_host, REG_DSI_CTRL,
+		msm_host->dma_cmd_ctrl_restore |
+		DSI_CTRL_CMD_MODE_EN |
+		DSI_CTRL_ENABLE);
+	dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_CMD_DMA_DONE, 1);
+
+	return 0;
+}
+
+void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
+				const struct mipi_dsi_msg *msg)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
+
+	dsi_intr_ctrl(msm_host, DSI_IRQ_MASK_CMD_DMA_DONE, 0);
+	dsi_write(msm_host, REG_DSI_CTRL, msm_host->dma_cmd_ctrl_restore);
+
+	if (!(msg->flags & MIPI_DSI_MSG_USE_LPM))
+		dsi_set_tx_power_mode(1, msm_host);
+
+	/* TODO: unvote for bus bandwidth */
+
+	cfg_hnd->ops->link_clk_disable(msm_host);
+	pm_runtime_put(&msm_host->pdev->dev);
+}
+
+int msm_dsi_host_cmd_tx(struct mipi_dsi_host *host,
+				const struct mipi_dsi_msg *msg)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	return dsi_cmds2buf_tx(msm_host, msg);
+}
+
+int msm_dsi_host_cmd_rx(struct mipi_dsi_host *host,
+				const struct mipi_dsi_msg *msg)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
+	int data_byte, rx_byte, dlen, end;
+	int short_response, diff, pkt_size, ret = 0;
+	char cmd;
+	int rlen = msg->rx_len;
+	u8 *buf;
+
+	if (rlen <= 2) {
+		short_response = 1;
+		pkt_size = rlen;
+		rx_byte = 4;
+	} else {
+		short_response = 0;
+		data_byte = 10;	/* first read */
+		if (rlen < data_byte)
+			pkt_size = rlen;
+		else
+			pkt_size = data_byte;
+		rx_byte = data_byte + 6; /* 4 header + 2 crc */
+	}
+
+	buf = msm_host->rx_buf;
+	end = 0;
+	while (!end) {
+		u8 tx[2] = {pkt_size & 0xff, pkt_size >> 8};
+		struct mipi_dsi_msg max_pkt_size_msg = {
+			.channel = msg->channel,
+			.type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
+			.tx_len = 2,
+			.tx_buf = tx,
+		};
+
+		DBG("rlen=%d pkt_size=%d rx_byte=%d",
+			rlen, pkt_size, rx_byte);
+
+		ret = dsi_cmds2buf_tx(msm_host, &max_pkt_size_msg);
+		if (ret < 2) {
+			pr_err("%s: Set max pkt size failed, %d\n",
+				__func__, ret);
+			return -EINVAL;
+		}
+
+		if ((cfg_hnd->major == MSM_DSI_VER_MAJOR_6G) &&
+			(cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V1_1)) {
+			/* Clear the RDBK_DATA registers */
+			dsi_write(msm_host, REG_DSI_RDBK_DATA_CTRL,
+					DSI_RDBK_DATA_CTRL_CLR);
+			wmb(); /* make sure the RDBK registers are cleared */
+			dsi_write(msm_host, REG_DSI_RDBK_DATA_CTRL, 0);
+			wmb(); /* release cleared status before transfer */
+		}
+
+		ret = dsi_cmds2buf_tx(msm_host, msg);
+		if (ret < 0) {
+			pr_err("%s: Read cmd Tx failed, %d\n", __func__, ret);
+			return ret;
+		} else if (ret < msg->tx_len) {
+			pr_err("%s: Read cmd Tx failed, too short: %d\n", __func__, ret);
+			return -ECOMM;
+		}
+
+		/*
+		 * once cmd_dma_done interrupt received,
+		 * return data from client is ready and stored
+		 * at RDBK_DATA register already
+		 * since rx fifo is 16 bytes, dcs header is kept at first loop,
+		 * after that dcs header lost during shift into registers
+		 */
+		dlen = dsi_cmd_dma_rx(msm_host, buf, rx_byte, pkt_size);
+
+		if (dlen <= 0)
+			return 0;
+
+		if (short_response)
+			break;
+
+		if (rlen <= data_byte) {
+			diff = data_byte - rlen;
+			end = 1;
+		} else {
+			diff = 0;
+			rlen -= data_byte;
+		}
+
+		if (!end) {
+			dlen -= 2; /* 2 crc */
+			dlen -= diff;
+			buf += dlen;	/* next start position */
+			data_byte = 14;	/* NOT first read */
+			if (rlen < data_byte)
+				pkt_size += rlen;
+			else
+				pkt_size += data_byte;
+			DBG("buf=%p dlen=%d diff=%d", buf, dlen, diff);
+		}
+	}
+
+	/*
+	 * For single Long read, if the requested rlen < 10,
+	 * we need to shift the start position of rx
+	 * data buffer to skip the bytes which are not
+	 * updated.
+	 */
+	if (pkt_size < 10 && !short_response)
+		buf = msm_host->rx_buf + (10 - rlen);
+	else
+		buf = msm_host->rx_buf;
+
+	cmd = buf[0];
+	switch (cmd) {
+	case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
+		pr_err("%s: rx ACK_ERR_PACLAGE\n", __func__);
+		ret = 0;
+		break;
+	case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:
+	case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
+		ret = dsi_short_read1_resp(buf, msg);
+		break;
+	case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
+	case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
+		ret = dsi_short_read2_resp(buf, msg);
+		break;
+	case MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE:
+	case MIPI_DSI_RX_DCS_LONG_READ_RESPONSE:
+		ret = dsi_long_read_resp(buf, msg);
+		break;
+	default:
+		pr_warn("%s:Invalid response cmd\n", __func__);
+		ret = 0;
+	}
+
+	return ret;
+}
+
+void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host *host, u32 dma_base,
+				  u32 len)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	dsi_write(msm_host, REG_DSI_DMA_BASE, dma_base);
+	dsi_write(msm_host, REG_DSI_DMA_LEN, len);
+	dsi_write(msm_host, REG_DSI_TRIG_DMA, 1);
+
+	/* Make sure trigger happens */
+	wmb();
+}
+
+void msm_dsi_host_set_phy_mode(struct mipi_dsi_host *host,
+	struct msm_dsi_phy *src_phy)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	msm_host->cphy_mode = src_phy->cphy_mode;
+}
+
+void msm_dsi_host_reset_phy(struct mipi_dsi_host *host)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	DBG("");
+	dsi_write(msm_host, REG_DSI_PHY_RESET, DSI_PHY_RESET_RESET);
+	/* Make sure fully reset */
+	wmb();
+	udelay(1000);
+	dsi_write(msm_host, REG_DSI_PHY_RESET, 0);
+	udelay(100);
+}
+
+void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host,
+			struct msm_dsi_phy_clk_request *clk_req,
+			bool is_bonded_dsi)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
+	int ret;
+
+	ret = cfg_hnd->ops->calc_clk_rate(msm_host, is_bonded_dsi);
+	if (ret) {
+		pr_err("%s: unable to calc clk rate, %d\n", __func__, ret);
+		return;
+	}
+
+	/* CPHY transmits 16 bits over 7 clock cycles
+	 * "byte_clk" is in units of 16-bits (see dsi_calc_pclk),
+	 * so multiply by 7 to get the "bitclk rate"
+	 */
+	if (msm_host->cphy_mode)
+		clk_req->bitclk_rate = msm_host->byte_clk_rate * 7;
+	else
+		clk_req->bitclk_rate = msm_host->byte_clk_rate * 8;
+	clk_req->escclk_rate = msm_host->esc_clk_rate;
+}
+
+void msm_dsi_host_enable_irq(struct mipi_dsi_host *host)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	enable_irq(msm_host->irq);
+}
+
+void msm_dsi_host_disable_irq(struct mipi_dsi_host *host)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	disable_irq(msm_host->irq);
+}
+
+int msm_dsi_host_enable(struct mipi_dsi_host *host)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	dsi_op_mode_config(msm_host,
+		!!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO), true);
+
+	/* TODO: clock should be turned off for command mode,
+	 * and only turned on before MDP START.
+	 * This part of code should be enabled once mdp driver support it.
+	 */
+	/* if (msm_panel->mode == MSM_DSI_CMD_MODE) {
+	 *	dsi_link_clk_disable(msm_host);
+	 *	pm_runtime_put(&msm_host->pdev->dev);
+	 * }
+	 */
+	msm_host->enabled = true;
+	return 0;
+}
+
+int msm_dsi_host_disable(struct mipi_dsi_host *host)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	msm_host->enabled = false;
+	dsi_op_mode_config(msm_host,
+		!!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO), false);
+
+	/* Since we have disabled INTF, the video engine won't stop so that
+	 * the cmd engine will be blocked.
+	 * Reset to disable video engine so that we can send off cmd.
+	 */
+	dsi_sw_reset(msm_host);
+
+	return 0;
+}
+
+static void msm_dsi_sfpb_config(struct msm_dsi_host *msm_host, bool enable)
+{
+	enum sfpb_ahb_arb_master_port_en en;
+
+	if (!msm_host->sfpb)
+		return;
+
+	en = enable ? SFPB_MASTER_PORT_ENABLE : SFPB_MASTER_PORT_DISABLE;
+
+	regmap_update_bits(msm_host->sfpb, REG_SFPB_GPREG,
+			SFPB_GPREG_MASTER_PORT_EN__MASK,
+			SFPB_GPREG_MASTER_PORT_EN(en));
+}
+
+int msm_dsi_host_power_on(struct mipi_dsi_host *host,
+			struct msm_dsi_phy_shared_timings *phy_shared_timings,
+			bool is_bonded_dsi, struct msm_dsi_phy *phy)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
+	int ret = 0;
+
+	mutex_lock(&msm_host->dev_mutex);
+	if (msm_host->power_on) {
+		DBG("dsi host already on");
+		goto unlock_ret;
+	}
+
+	msm_host->byte_intf_clk_rate = msm_host->byte_clk_rate;
+	if (phy_shared_timings->byte_intf_clk_div_2)
+		msm_host->byte_intf_clk_rate /= 2;
+
+	msm_dsi_sfpb_config(msm_host, true);
+
+	ret = regulator_bulk_enable(msm_host->cfg_hnd->cfg->num_regulators,
+				    msm_host->supplies);
+	if (ret) {
+		pr_err("%s:Failed to enable vregs.ret=%d\n",
+			__func__, ret);
+		goto unlock_ret;
+	}
+
+	pm_runtime_get_sync(&msm_host->pdev->dev);
+	ret = cfg_hnd->ops->link_clk_set_rate(msm_host);
+	if (!ret)
+		ret = cfg_hnd->ops->link_clk_enable(msm_host);
+	if (ret) {
+		pr_err("%s: failed to enable link clocks. ret=%d\n",
+		       __func__, ret);
+		goto fail_disable_reg;
+	}
+
+	ret = pinctrl_pm_select_default_state(&msm_host->pdev->dev);
+	if (ret) {
+		pr_err("%s: failed to set pinctrl default state, %d\n",
+			__func__, ret);
+		goto fail_disable_clk;
+	}
+
+	dsi_timing_setup(msm_host, is_bonded_dsi);
+	dsi_sw_reset(msm_host);
+	dsi_ctrl_enable(msm_host, phy_shared_timings, phy);
+
+	if (msm_host->disp_en_gpio)
+		gpiod_set_value(msm_host->disp_en_gpio, 1);
+
+	msm_host->power_on = true;
+	mutex_unlock(&msm_host->dev_mutex);
+
+	return 0;
+
+fail_disable_clk:
+	cfg_hnd->ops->link_clk_disable(msm_host);
+	pm_runtime_put(&msm_host->pdev->dev);
+fail_disable_reg:
+	regulator_bulk_disable(msm_host->cfg_hnd->cfg->num_regulators,
+			       msm_host->supplies);
+unlock_ret:
+	mutex_unlock(&msm_host->dev_mutex);
+	return ret;
+}
+
+int msm_dsi_host_power_off(struct mipi_dsi_host *host)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
+
+	mutex_lock(&msm_host->dev_mutex);
+	if (!msm_host->power_on) {
+		DBG("dsi host already off");
+		goto unlock_ret;
+	}
+
+	dsi_ctrl_disable(msm_host);
+
+	if (msm_host->disp_en_gpio)
+		gpiod_set_value(msm_host->disp_en_gpio, 0);
+
+	pinctrl_pm_select_sleep_state(&msm_host->pdev->dev);
+
+	cfg_hnd->ops->link_clk_disable(msm_host);
+	pm_runtime_put(&msm_host->pdev->dev);
+
+	regulator_bulk_disable(msm_host->cfg_hnd->cfg->num_regulators,
+			       msm_host->supplies);
+
+	msm_dsi_sfpb_config(msm_host, false);
+
+	DBG("-");
+
+	msm_host->power_on = false;
+
+unlock_ret:
+	mutex_unlock(&msm_host->dev_mutex);
+	return 0;
+}
+
+int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host,
+				  const struct drm_display_mode *mode)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	if (msm_host->mode) {
+		drm_mode_destroy(msm_host->dev, msm_host->mode);
+		msm_host->mode = NULL;
+	}
+
+	msm_host->mode = drm_mode_duplicate(msm_host->dev, mode);
+	if (!msm_host->mode) {
+		pr_err("%s: cannot duplicate mode\n", __func__);
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
+					    const struct drm_display_mode *mode)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	struct drm_dsc_config *dsc = msm_host->dsc;
+	int pic_width = mode->hdisplay;
+	int pic_height = mode->vdisplay;
+
+	if (!msm_host->dsc)
+		return MODE_OK;
+
+	if (pic_width % dsc->slice_width) {
+		pr_err("DSI: pic_width %d has to be multiple of slice %d\n",
+		       pic_width, dsc->slice_width);
+		return MODE_H_ILLEGAL;
+	}
+
+	if (pic_height % dsc->slice_height) {
+		pr_err("DSI: pic_height %d has to be multiple of slice %d\n",
+		       pic_height, dsc->slice_height);
+		return MODE_V_ILLEGAL;
+	}
+
+	return MODE_OK;
+}
+
+unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host)
+{
+	return to_msm_dsi_host(host)->mode_flags;
+}
+
+void msm_dsi_host_snapshot(struct msm_disp_state *disp_state, struct mipi_dsi_host *host)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	pm_runtime_get_sync(&msm_host->pdev->dev);
+
+	msm_disp_snapshot_add_block(disp_state, msm_host->ctrl_size,
+			msm_host->ctrl_base, "dsi%d_ctrl", msm_host->id);
+
+	pm_runtime_put_sync(&msm_host->pdev->dev);
+}
+
+static void msm_dsi_host_video_test_pattern_setup(struct msm_dsi_host *msm_host)
+{
+	u32 reg;
+
+	reg = dsi_read(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL);
+
+	dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_VIDEO_INIT_VAL, 0xff);
+	/* draw checkered rectangle pattern */
+	dsi_write(msm_host, REG_DSI_TPG_MAIN_CONTROL,
+			DSI_TPG_MAIN_CONTROL_CHECKERED_RECTANGLE_PATTERN);
+	/* use 24-bit RGB test pttern */
+	dsi_write(msm_host, REG_DSI_TPG_VIDEO_CONFIG,
+			DSI_TPG_VIDEO_CONFIG_BPP(VIDEO_CONFIG_24BPP) |
+			DSI_TPG_VIDEO_CONFIG_RGB);
+
+	reg |= DSI_TEST_PATTERN_GEN_CTRL_VIDEO_PATTERN_SEL(VID_MDSS_GENERAL_PATTERN);
+	dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL, reg);
+
+	DBG("Video test pattern setup done\n");
+}
+
+static void msm_dsi_host_cmd_test_pattern_setup(struct msm_dsi_host *msm_host)
+{
+	u32 reg;
+
+	reg = dsi_read(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL);
+
+	/* initial value for test pattern */
+	dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CMD_MDP_INIT_VAL0, 0xff);
+
+	reg |= DSI_TEST_PATTERN_GEN_CTRL_CMD_MDP_STREAM0_PATTERN_SEL(CMD_MDP_MDSS_GENERAL_PATTERN);
+
+	dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL, reg);
+	/* draw checkered rectangle pattern */
+	dsi_write(msm_host, REG_DSI_TPG_MAIN_CONTROL2,
+			DSI_TPG_MAIN_CONTROL2_CMD_MDP0_CHECKERED_RECTANGLE_PATTERN);
+
+	DBG("Cmd test pattern setup done\n");
+}
+
+void msm_dsi_host_test_pattern_en(struct mipi_dsi_host *host)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+	bool is_video_mode = !!(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO);
+	u32 reg;
+
+	if (is_video_mode)
+		msm_dsi_host_video_test_pattern_setup(msm_host);
+	else
+		msm_dsi_host_cmd_test_pattern_setup(msm_host);
+
+	reg = dsi_read(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL);
+	/* enable the test pattern generator */
+	dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL, (reg | DSI_TEST_PATTERN_GEN_CTRL_EN));
+
+	/* for command mode need to trigger one frame from tpg */
+	if (!is_video_mode)
+		dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CMD_STREAM0_TRIGGER,
+				DSI_TEST_PATTERN_GEN_CMD_STREAM0_TRIGGER_SW_TRIGGER);
+}
+
+struct drm_dsc_config *msm_dsi_host_get_dsc_config(struct mipi_dsi_host *host)
+{
+	struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+	return msm_host->dsc;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/dsi_manager.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/dsi_manager.c
@@ -0,0 +1,675 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ */
+
+#include "drm/drm_bridge_connector.h"
+
+#include "msm_kms.h"
+#include "dsi.h"
+
+#define DSI_CLOCK_MASTER	DSI_0
+#define DSI_CLOCK_SLAVE		DSI_1
+
+#define DSI_LEFT		DSI_0
+#define DSI_RIGHT		DSI_1
+
+/* According to the current drm framework sequence, take the encoder of
+ * DSI_1 as master encoder
+ */
+#define DSI_ENCODER_MASTER	DSI_1
+#define DSI_ENCODER_SLAVE	DSI_0
+
+struct msm_dsi_manager {
+	struct msm_dsi *dsi[DSI_MAX];
+
+	bool is_bonded_dsi;
+	bool is_sync_needed;
+	int master_dsi_link_id;
+};
+
+static struct msm_dsi_manager msm_dsim_glb;
+
+#define IS_BONDED_DSI()		(msm_dsim_glb.is_bonded_dsi)
+#define IS_SYNC_NEEDED()	(msm_dsim_glb.is_sync_needed)
+#define IS_MASTER_DSI_LINK(id)	(msm_dsim_glb.master_dsi_link_id == id)
+
+static inline struct msm_dsi *dsi_mgr_get_dsi(int id)
+{
+	return msm_dsim_glb.dsi[id];
+}
+
+static inline struct msm_dsi *dsi_mgr_get_other_dsi(int id)
+{
+	return msm_dsim_glb.dsi[(id + 1) % DSI_MAX];
+}
+
+static int dsi_mgr_parse_of(struct device_node *np, int id)
+{
+	struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
+
+	/* We assume 2 dsi nodes have the same information of bonded dsi and
+	 * sync-mode, and only one node specifies master in case of bonded mode.
+	 */
+	if (!msm_dsim->is_bonded_dsi)
+		msm_dsim->is_bonded_dsi = of_property_read_bool(np, "qcom,dual-dsi-mode");
+
+	if (msm_dsim->is_bonded_dsi) {
+		if (of_property_read_bool(np, "qcom,master-dsi"))
+			msm_dsim->master_dsi_link_id = id;
+		if (!msm_dsim->is_sync_needed)
+			msm_dsim->is_sync_needed = of_property_read_bool(
+					np, "qcom,sync-dual-dsi");
+	}
+
+	return 0;
+}
+
+static int dsi_mgr_setup_components(int id)
+{
+	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+	struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
+	struct msm_dsi *clk_master_dsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
+	struct msm_dsi *clk_slave_dsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
+	int ret;
+
+	if (!IS_BONDED_DSI()) {
+		ret = msm_dsi_host_register(msm_dsi->host);
+		if (ret)
+			return ret;
+
+		msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE);
+		msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
+	} else if (other_dsi) {
+		struct msm_dsi *master_link_dsi = IS_MASTER_DSI_LINK(id) ?
+							msm_dsi : other_dsi;
+		struct msm_dsi *slave_link_dsi = IS_MASTER_DSI_LINK(id) ?
+							other_dsi : msm_dsi;
+		/* Register slave host first, so that slave DSI device
+		 * has a chance to probe, and do not block the master
+		 * DSI device's probe.
+		 * Also, do not check defer for the slave host,
+		 * because only master DSI device adds the panel to global
+		 * panel list. The panel's device is the master DSI device.
+		 */
+		ret = msm_dsi_host_register(slave_link_dsi->host);
+		if (ret)
+			return ret;
+		ret = msm_dsi_host_register(master_link_dsi->host);
+		if (ret)
+			return ret;
+
+		/* PLL0 is to drive both 2 DSI link clocks in bonded DSI mode. */
+		msm_dsi_phy_set_usecase(clk_master_dsi->phy,
+					MSM_DSI_PHY_MASTER);
+		msm_dsi_phy_set_usecase(clk_slave_dsi->phy,
+					MSM_DSI_PHY_SLAVE);
+		msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
+		msm_dsi_host_set_phy_mode(other_dsi->host, other_dsi->phy);
+	}
+
+	return 0;
+}
+
+static int enable_phy(struct msm_dsi *msm_dsi,
+		      struct msm_dsi_phy_shared_timings *shared_timings)
+{
+	struct msm_dsi_phy_clk_request clk_req;
+	bool is_bonded_dsi = IS_BONDED_DSI();
+
+	msm_dsi_host_get_phy_clk_req(msm_dsi->host, &clk_req, is_bonded_dsi);
+
+	return msm_dsi_phy_enable(msm_dsi->phy, &clk_req, shared_timings);
+}
+
+static int
+dsi_mgr_phy_enable(int id,
+		   struct msm_dsi_phy_shared_timings shared_timings[DSI_MAX])
+{
+	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+	struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
+	struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
+	int ret;
+
+	/* In case of bonded DSI, some registers in PHY1 have been programmed
+	 * during PLL0 clock's set_rate. The PHY1 reset called by host1 here
+	 * will silently reset those PHY1 registers. Therefore we need to reset
+	 * and enable both PHYs before any PLL clock operation.
+	 */
+	if (IS_BONDED_DSI() && mdsi && sdsi) {
+		if (!mdsi->phy_enabled && !sdsi->phy_enabled) {
+			msm_dsi_host_reset_phy(mdsi->host);
+			msm_dsi_host_reset_phy(sdsi->host);
+
+			ret = enable_phy(mdsi,
+					 &shared_timings[DSI_CLOCK_MASTER]);
+			if (ret)
+				return ret;
+			ret = enable_phy(sdsi,
+					 &shared_timings[DSI_CLOCK_SLAVE]);
+			if (ret) {
+				msm_dsi_phy_disable(mdsi->phy);
+				return ret;
+			}
+		}
+	} else {
+		msm_dsi_host_reset_phy(msm_dsi->host);
+		ret = enable_phy(msm_dsi, &shared_timings[id]);
+		if (ret)
+			return ret;
+	}
+
+	msm_dsi->phy_enabled = true;
+
+	return 0;
+}
+
+static void dsi_mgr_phy_disable(int id)
+{
+	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+	struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
+	struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
+
+	/* disable DSI phy
+	 * In bonded dsi configuration, the phy should be disabled for the
+	 * first controller only when the second controller is disabled.
+	 */
+	msm_dsi->phy_enabled = false;
+	if (IS_BONDED_DSI() && mdsi && sdsi) {
+		if (!mdsi->phy_enabled && !sdsi->phy_enabled) {
+			msm_dsi_phy_disable(sdsi->phy);
+			msm_dsi_phy_disable(mdsi->phy);
+		}
+	} else {
+		msm_dsi_phy_disable(msm_dsi->phy);
+	}
+}
+
+struct dsi_bridge {
+	struct drm_bridge base;
+	int id;
+};
+
+#define to_dsi_bridge(x) container_of(x, struct dsi_bridge, base)
+
+static int dsi_mgr_bridge_get_id(struct drm_bridge *bridge)
+{
+	struct dsi_bridge *dsi_bridge = to_dsi_bridge(bridge);
+	return dsi_bridge->id;
+}
+
+static void msm_dsi_manager_set_split_display(u8 id)
+{
+	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+	struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
+	struct msm_drm_private *priv = msm_dsi->dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+	struct msm_dsi *master_dsi, *slave_dsi;
+
+	if (IS_BONDED_DSI() && !IS_MASTER_DSI_LINK(id)) {
+		master_dsi = other_dsi;
+		slave_dsi = msm_dsi;
+	} else {
+		master_dsi = msm_dsi;
+		slave_dsi = other_dsi;
+	}
+
+	if (!msm_dsi->external_bridge || !IS_BONDED_DSI())
+		return;
+
+	/*
+	 * Set split display info to kms once bonded DSI panel is connected to
+	 * both hosts.
+	 */
+	if (other_dsi && other_dsi->external_bridge && kms->funcs->set_split_display) {
+		kms->funcs->set_split_display(kms, master_dsi->encoder,
+					      slave_dsi->encoder,
+					      msm_dsi_is_cmd_mode(msm_dsi));
+	}
+}
+
+static int dsi_mgr_bridge_power_on(struct drm_bridge *bridge)
+{
+	int id = dsi_mgr_bridge_get_id(bridge);
+	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
+	struct mipi_dsi_host *host = msm_dsi->host;
+	struct msm_dsi_phy_shared_timings phy_shared_timings[DSI_MAX];
+	bool is_bonded_dsi = IS_BONDED_DSI();
+	int ret;
+
+	DBG("id=%d", id);
+
+	ret = dsi_mgr_phy_enable(id, phy_shared_timings);
+	if (ret)
+		goto phy_en_fail;
+
+	ret = msm_dsi_host_power_on(host, &phy_shared_timings[id], is_bonded_dsi, msm_dsi->phy);
+	if (ret) {
+		pr_err("%s: power on host %d failed, %d\n", __func__, id, ret);
+		goto host_on_fail;
+	}
+
+	if (is_bonded_dsi && msm_dsi1) {
+		ret = msm_dsi_host_power_on(msm_dsi1->host,
+				&phy_shared_timings[DSI_1], is_bonded_dsi, msm_dsi1->phy);
+		if (ret) {
+			pr_err("%s: power on host1 failed, %d\n",
+							__func__, ret);
+			goto host1_on_fail;
+		}
+	}
+
+	/*
+	 * Enable before preparing the panel, disable after unpreparing, so
+	 * that the panel can communicate over the DSI link.
+	 */
+	msm_dsi_host_enable_irq(host);
+	if (is_bonded_dsi && msm_dsi1)
+		msm_dsi_host_enable_irq(msm_dsi1->host);
+
+	return 0;
+
+host1_on_fail:
+	msm_dsi_host_power_off(host);
+host_on_fail:
+	dsi_mgr_phy_disable(id);
+phy_en_fail:
+	return ret;
+}
+
+static void dsi_mgr_bridge_power_off(struct drm_bridge *bridge)
+{
+	int id = dsi_mgr_bridge_get_id(bridge);
+	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
+	struct mipi_dsi_host *host = msm_dsi->host;
+	bool is_bonded_dsi = IS_BONDED_DSI();
+
+	msm_dsi_host_disable_irq(host);
+	if (is_bonded_dsi && msm_dsi1) {
+		msm_dsi_host_disable_irq(msm_dsi1->host);
+		msm_dsi_host_power_off(msm_dsi1->host);
+	}
+	msm_dsi_host_power_off(host);
+	dsi_mgr_phy_disable(id);
+}
+
+static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
+{
+	int id = dsi_mgr_bridge_get_id(bridge);
+	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
+	struct mipi_dsi_host *host = msm_dsi->host;
+	bool is_bonded_dsi = IS_BONDED_DSI();
+	int ret;
+
+	DBG("id=%d", id);
+	if (!msm_dsi_device_connected(msm_dsi))
+		return;
+
+	/* Do nothing with the host if it is slave-DSI in case of bonded DSI */
+	if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
+		return;
+
+	ret = dsi_mgr_bridge_power_on(bridge);
+	if (ret) {
+		dev_err(&msm_dsi->pdev->dev, "Power on failed: %d\n", ret);
+		return;
+	}
+
+	ret = msm_dsi_host_enable(host);
+	if (ret) {
+		pr_err("%s: enable host %d failed, %d\n", __func__, id, ret);
+		goto host_en_fail;
+	}
+
+	if (is_bonded_dsi && msm_dsi1) {
+		ret = msm_dsi_host_enable(msm_dsi1->host);
+		if (ret) {
+			pr_err("%s: enable host1 failed, %d\n", __func__, ret);
+			goto host1_en_fail;
+		}
+	}
+
+	return;
+
+host1_en_fail:
+	msm_dsi_host_disable(host);
+host_en_fail:
+	dsi_mgr_bridge_power_off(bridge);
+}
+
+void msm_dsi_manager_tpg_enable(void)
+{
+	struct msm_dsi *m_dsi = dsi_mgr_get_dsi(DSI_0);
+	struct msm_dsi *s_dsi = dsi_mgr_get_dsi(DSI_1);
+
+	/* if dual dsi, trigger tpg on master first then slave */
+	if (m_dsi) {
+		msm_dsi_host_test_pattern_en(m_dsi->host);
+		if (IS_BONDED_DSI() && s_dsi)
+			msm_dsi_host_test_pattern_en(s_dsi->host);
+	}
+}
+
+static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge)
+{
+	int id = dsi_mgr_bridge_get_id(bridge);
+	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+	struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
+	struct mipi_dsi_host *host = msm_dsi->host;
+	bool is_bonded_dsi = IS_BONDED_DSI();
+	int ret;
+
+	DBG("id=%d", id);
+
+	if (!msm_dsi_device_connected(msm_dsi))
+		return;
+
+	/*
+	 * Do nothing with the host if it is slave-DSI in case of bonded DSI.
+	 * It is safe to call dsi_mgr_phy_disable() here because a single PHY
+	 * won't be diabled until both PHYs request disable.
+	 */
+	if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
+		goto disable_phy;
+
+	ret = msm_dsi_host_disable(host);
+	if (ret)
+		pr_err("%s: host %d disable failed, %d\n", __func__, id, ret);
+
+	if (is_bonded_dsi && msm_dsi1) {
+		ret = msm_dsi_host_disable(msm_dsi1->host);
+		if (ret)
+			pr_err("%s: host1 disable failed, %d\n", __func__, ret);
+	}
+
+	msm_dsi_host_disable_irq(host);
+	if (is_bonded_dsi && msm_dsi1)
+		msm_dsi_host_disable_irq(msm_dsi1->host);
+
+	/* Save PHY status if it is a clock source */
+	msm_dsi_phy_pll_save_state(msm_dsi->phy);
+
+	ret = msm_dsi_host_power_off(host);
+	if (ret)
+		pr_err("%s: host %d power off failed,%d\n", __func__, id, ret);
+
+	if (is_bonded_dsi && msm_dsi1) {
+		ret = msm_dsi_host_power_off(msm_dsi1->host);
+		if (ret)
+			pr_err("%s: host1 power off failed, %d\n",
+								__func__, ret);
+	}
+
+disable_phy:
+	dsi_mgr_phy_disable(id);
+}
+
+static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
+		const struct drm_display_mode *mode,
+		const struct drm_display_mode *adjusted_mode)
+{
+	int id = dsi_mgr_bridge_get_id(bridge);
+	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+	struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
+	struct mipi_dsi_host *host = msm_dsi->host;
+	bool is_bonded_dsi = IS_BONDED_DSI();
+
+	DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
+
+	if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id))
+		return;
+
+	msm_dsi_host_set_display_mode(host, adjusted_mode);
+	if (is_bonded_dsi && other_dsi)
+		msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode);
+}
+
+static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge,
+						      const struct drm_display_info *info,
+						      const struct drm_display_mode *mode)
+{
+	int id = dsi_mgr_bridge_get_id(bridge);
+	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+	struct mipi_dsi_host *host = msm_dsi->host;
+	struct platform_device *pdev = msm_dsi->pdev;
+	struct dev_pm_opp *opp;
+	unsigned long byte_clk_rate;
+
+	byte_clk_rate = dsi_byte_clk_get_rate(host, IS_BONDED_DSI(), mode);
+
+	opp = dev_pm_opp_find_freq_ceil(&pdev->dev, &byte_clk_rate);
+	if (!IS_ERR(opp)) {
+		dev_pm_opp_put(opp);
+	} else if (PTR_ERR(opp) == -ERANGE) {
+		/*
+		 * An empty table is created by devm_pm_opp_set_clkname() even
+		 * if there is none. Thus find_freq_ceil will still return
+		 * -ERANGE in such case.
+		 */
+		if (dev_pm_opp_get_opp_count(&pdev->dev) != 0)
+			return MODE_CLOCK_RANGE;
+	} else {
+			return MODE_ERROR;
+	}
+
+	return msm_dsi_host_check_dsc(host, mode);
+}
+
+static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = {
+	.pre_enable = dsi_mgr_bridge_pre_enable,
+	.post_disable = dsi_mgr_bridge_post_disable,
+	.mode_set = dsi_mgr_bridge_mode_set,
+	.mode_valid = dsi_mgr_bridge_mode_valid,
+};
+
+/* initialize bridge */
+int msm_dsi_manager_bridge_init(struct msm_dsi *msm_dsi)
+{
+	struct drm_bridge *bridge = NULL;
+	struct dsi_bridge *dsi_bridge;
+	struct drm_encoder *encoder;
+	int ret;
+
+	dsi_bridge = devm_kzalloc(msm_dsi->dev->dev,
+				sizeof(*dsi_bridge), GFP_KERNEL);
+	if (!dsi_bridge)
+		return -ENOMEM;
+
+	dsi_bridge->id = msm_dsi->id;
+
+	encoder = msm_dsi->encoder;
+
+	bridge = &dsi_bridge->base;
+	bridge->funcs = &dsi_mgr_bridge_funcs;
+
+	ret = devm_drm_bridge_add(msm_dsi->dev->dev, bridge);
+	if (ret)
+		return ret;
+
+	ret = drm_bridge_attach(encoder, bridge, NULL, 0);
+	if (ret)
+		return ret;
+
+	msm_dsi->bridge = bridge;
+
+	return 0;
+}
+
+int msm_dsi_manager_ext_bridge_init(u8 id)
+{
+	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+	struct drm_device *dev = msm_dsi->dev;
+	struct drm_encoder *encoder;
+	struct drm_bridge *int_bridge, *ext_bridge;
+	int ret;
+
+	int_bridge = msm_dsi->bridge;
+	ext_bridge = devm_drm_of_get_bridge(&msm_dsi->pdev->dev,
+					    msm_dsi->pdev->dev.of_node, 1, 0);
+	if (IS_ERR(ext_bridge))
+		return PTR_ERR(ext_bridge);
+
+	msm_dsi->external_bridge = ext_bridge;
+
+	encoder = msm_dsi->encoder;
+
+	/*
+	 * Try first to create the bridge without it creating its own
+	 * connector.. currently some bridges support this, and others
+	 * do not (and some support both modes)
+	 */
+	ret = drm_bridge_attach(encoder, ext_bridge, int_bridge,
+			DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+	if (ret == -EINVAL) {
+		/*
+		 * link the internal dsi bridge to the external bridge,
+		 * connector is created by the next bridge.
+		 */
+		ret = drm_bridge_attach(encoder, ext_bridge, int_bridge, 0);
+		if (ret < 0)
+			return ret;
+	} else {
+		struct drm_connector *connector;
+
+		/* We are in charge of the connector, create one now. */
+		connector = drm_bridge_connector_init(dev, encoder);
+		if (IS_ERR(connector)) {
+			DRM_ERROR("Unable to create bridge connector\n");
+			return PTR_ERR(connector);
+		}
+
+		ret = drm_connector_attach_encoder(connector, encoder);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* The pipeline is ready, ping encoders if necessary */
+	msm_dsi_manager_set_split_display(id);
+
+	return 0;
+}
+
+int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg)
+{
+	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+	struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0);
+	struct mipi_dsi_host *host = msm_dsi->host;
+	bool is_read = (msg->rx_buf && msg->rx_len);
+	bool need_sync = (IS_SYNC_NEEDED() && !is_read);
+	int ret;
+
+	if (!msg->tx_buf || !msg->tx_len)
+		return 0;
+
+	/* In bonded master case, panel requires the same commands sent to
+	 * both DSI links. Host issues the command trigger to both links
+	 * when DSI_1 calls the cmd transfer function, no matter it happens
+	 * before or after DSI_0 cmd transfer.
+	 */
+	if (need_sync && (id == DSI_0))
+		return is_read ? msg->rx_len : msg->tx_len;
+
+	if (need_sync && msm_dsi0) {
+		ret = msm_dsi_host_xfer_prepare(msm_dsi0->host, msg);
+		if (ret) {
+			pr_err("%s: failed to prepare non-trigger host, %d\n",
+				__func__, ret);
+			return ret;
+		}
+	}
+	ret = msm_dsi_host_xfer_prepare(host, msg);
+	if (ret) {
+		pr_err("%s: failed to prepare host, %d\n", __func__, ret);
+		goto restore_host0;
+	}
+
+	ret = is_read ? msm_dsi_host_cmd_rx(host, msg) :
+			msm_dsi_host_cmd_tx(host, msg);
+
+	msm_dsi_host_xfer_restore(host, msg);
+
+restore_host0:
+	if (need_sync && msm_dsi0)
+		msm_dsi_host_xfer_restore(msm_dsi0->host, msg);
+
+	return ret;
+}
+
+bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len)
+{
+	struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
+	struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0);
+	struct mipi_dsi_host *host = msm_dsi->host;
+
+	if (IS_SYNC_NEEDED() && (id == DSI_0))
+		return false;
+
+	if (IS_SYNC_NEEDED() && msm_dsi0)
+		msm_dsi_host_cmd_xfer_commit(msm_dsi0->host, dma_base, len);
+
+	msm_dsi_host_cmd_xfer_commit(host, dma_base, len);
+
+	return true;
+}
+
+int msm_dsi_manager_register(struct msm_dsi *msm_dsi)
+{
+	struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
+	int id = msm_dsi->id;
+	int ret;
+
+	if (id >= DSI_MAX) {
+		pr_err("%s: invalid id %d\n", __func__, id);
+		return -EINVAL;
+	}
+
+	if (msm_dsim->dsi[id]) {
+		pr_err("%s: dsi%d already registered\n", __func__, id);
+		return -EBUSY;
+	}
+
+	msm_dsim->dsi[id] = msm_dsi;
+
+	ret = dsi_mgr_parse_of(msm_dsi->pdev->dev.of_node, id);
+	if (ret) {
+		pr_err("%s: failed to parse OF DSI info\n", __func__);
+		goto fail;
+	}
+
+	ret = dsi_mgr_setup_components(id);
+	if (ret) {
+		pr_err("%s: failed to register mipi dsi host for DSI %d: %d\n",
+			__func__, id, ret);
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	msm_dsim->dsi[id] = NULL;
+	return ret;
+}
+
+void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi)
+{
+	struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
+
+	if (msm_dsi->host)
+		msm_dsi_host_unregister(msm_dsi->host);
+
+	if (msm_dsi->id >= 0)
+		msm_dsim->dsi[msm_dsi->id] = NULL;
+}
+
+bool msm_dsi_is_bonded_dsi(struct msm_dsi *msm_dsi)
+{
+	return IS_BONDED_DSI();
+}
+
+bool msm_dsi_is_master_dsi(struct msm_dsi *msm_dsi)
+{
+	return IS_MASTER_DSI_LINK(msm_dsi->id);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/mmss_cc.xml.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/mmss_cc.xml.h
@@ -0,0 +1,131 @@
+#ifndef MMSS_CC_XML
+#define MMSS_CC_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://github.com/freedreno/envytools/
+git clone https://github.com/freedreno/envytools.git
+
+The rules-ng-ng source files this header was generated from are:
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml                   (    944 bytes, from 2022-07-23 20:21:46)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml   (   1572 bytes, from 2022-07-23 20:21:46)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml              (  20912 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml        (   2849 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml              (  37461 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml               (  18746 bytes, from 2022-04-28 17:29:36)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml        (   3236 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml (   4935 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml      (   7004 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml      (   3712 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml      (   5381 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml      (   4499 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml       (  11007 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml              (    602 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml           (   1686 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml           (    600 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml             (  42350 bytes, from 2022-09-20 17:45:56)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml               (  10416 bytes, from 2022-03-08 17:40:42)
+
+Copyright (C) 2013-2022 by the following authors:
+- Rob Clark <robdclark@gmail.com> (robclark)
+- Ilia Mirkin <imirkin@alum.mit.edu> (imirkin)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+
+enum mmss_cc_clk {
+	CLK = 0,
+	PCLK = 1,
+};
+
+#define REG_MMSS_CC_AHB						0x00000008
+
+static inline uint32_t __offset_CLK(enum mmss_cc_clk idx)
+{
+	switch (idx) {
+		case CLK: return 0x0000004c;
+		case PCLK: return 0x00000130;
+		default: return INVALID_IDX(idx);
+	}
+}
+static inline uint32_t REG_MMSS_CC_CLK(enum mmss_cc_clk i0) { return 0x00000000 + __offset_CLK(i0); }
+
+static inline uint32_t REG_MMSS_CC_CLK_CC(enum mmss_cc_clk i0) { return 0x00000000 + __offset_CLK(i0); }
+#define MMSS_CC_CLK_CC_CLK_EN					0x00000001
+#define MMSS_CC_CLK_CC_ROOT_EN					0x00000004
+#define MMSS_CC_CLK_CC_MND_EN					0x00000020
+#define MMSS_CC_CLK_CC_MND_MODE__MASK				0x000000c0
+#define MMSS_CC_CLK_CC_MND_MODE__SHIFT				6
+static inline uint32_t MMSS_CC_CLK_CC_MND_MODE(uint32_t val)
+{
+	return ((val) << MMSS_CC_CLK_CC_MND_MODE__SHIFT) & MMSS_CC_CLK_CC_MND_MODE__MASK;
+}
+#define MMSS_CC_CLK_CC_PMXO_SEL__MASK				0x00000300
+#define MMSS_CC_CLK_CC_PMXO_SEL__SHIFT				8
+static inline uint32_t MMSS_CC_CLK_CC_PMXO_SEL(uint32_t val)
+{
+	return ((val) << MMSS_CC_CLK_CC_PMXO_SEL__SHIFT) & MMSS_CC_CLK_CC_PMXO_SEL__MASK;
+}
+
+static inline uint32_t REG_MMSS_CC_CLK_MD(enum mmss_cc_clk i0) { return 0x00000004 + __offset_CLK(i0); }
+#define MMSS_CC_CLK_MD_D__MASK					0x000000ff
+#define MMSS_CC_CLK_MD_D__SHIFT					0
+static inline uint32_t MMSS_CC_CLK_MD_D(uint32_t val)
+{
+	return ((val) << MMSS_CC_CLK_MD_D__SHIFT) & MMSS_CC_CLK_MD_D__MASK;
+}
+#define MMSS_CC_CLK_MD_M__MASK					0x0000ff00
+#define MMSS_CC_CLK_MD_M__SHIFT					8
+static inline uint32_t MMSS_CC_CLK_MD_M(uint32_t val)
+{
+	return ((val) << MMSS_CC_CLK_MD_M__SHIFT) & MMSS_CC_CLK_MD_M__MASK;
+}
+
+static inline uint32_t REG_MMSS_CC_CLK_NS(enum mmss_cc_clk i0) { return 0x00000008 + __offset_CLK(i0); }
+#define MMSS_CC_CLK_NS_SRC__MASK				0x0000000f
+#define MMSS_CC_CLK_NS_SRC__SHIFT				0
+static inline uint32_t MMSS_CC_CLK_NS_SRC(uint32_t val)
+{
+	return ((val) << MMSS_CC_CLK_NS_SRC__SHIFT) & MMSS_CC_CLK_NS_SRC__MASK;
+}
+#define MMSS_CC_CLK_NS_PRE_DIV_FUNC__MASK			0x00fff000
+#define MMSS_CC_CLK_NS_PRE_DIV_FUNC__SHIFT			12
+static inline uint32_t MMSS_CC_CLK_NS_PRE_DIV_FUNC(uint32_t val)
+{
+	return ((val) << MMSS_CC_CLK_NS_PRE_DIV_FUNC__SHIFT) & MMSS_CC_CLK_NS_PRE_DIV_FUNC__MASK;
+}
+#define MMSS_CC_CLK_NS_VAL__MASK				0xff000000
+#define MMSS_CC_CLK_NS_VAL__SHIFT				24
+static inline uint32_t MMSS_CC_CLK_NS_VAL(uint32_t val)
+{
+	return ((val) << MMSS_CC_CLK_NS_VAL__SHIFT) & MMSS_CC_CLK_NS_VAL__MASK;
+}
+
+#define REG_MMSS_CC_DSI2_PIXEL_CC				0x00000094
+
+#define REG_MMSS_CC_DSI2_PIXEL_NS				0x000000e4
+
+#define REG_MMSS_CC_DSI2_PIXEL_CC2				0x00000264
+
+
+#endif /* MMSS_CC_XML */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy.c
@@ -0,0 +1,881 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+#include <dt-bindings/phy/phy.h>
+
+#include "dsi_phy.h"
+
+#define S_DIV_ROUND_UP(n, d)	\
+	(((n) >= 0) ? (((n) + (d) - 1) / (d)) : (((n) - (d) + 1) / (d)))
+
+static inline s32 linear_inter(s32 tmax, s32 tmin, s32 percent,
+				s32 min_result, bool even)
+{
+	s32 v;
+
+	v = (tmax - tmin) * percent;
+	v = S_DIV_ROUND_UP(v, 100) + tmin;
+	if (even && (v & 0x1))
+		return max_t(s32, min_result, v - 1);
+	else
+		return max_t(s32, min_result, v);
+}
+
+static void dsi_dphy_timing_calc_clk_zero(struct msm_dsi_dphy_timing *timing,
+					s32 ui, s32 coeff, s32 pcnt)
+{
+	s32 tmax, tmin, clk_z;
+	s32 temp;
+
+	/* reset */
+	temp = 300 * coeff - ((timing->clk_prepare >> 1) + 1) * 2 * ui;
+	tmin = S_DIV_ROUND_UP(temp, ui) - 2;
+	if (tmin > 255) {
+		tmax = 511;
+		clk_z = linear_inter(2 * tmin, tmin, pcnt, 0, true);
+	} else {
+		tmax = 255;
+		clk_z = linear_inter(tmax, tmin, pcnt, 0, true);
+	}
+
+	/* adjust */
+	temp = (timing->hs_rqst + timing->clk_prepare + clk_z) & 0x7;
+	timing->clk_zero = clk_z + 8 - temp;
+}
+
+int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing,
+			     struct msm_dsi_phy_clk_request *clk_req)
+{
+	const unsigned long bit_rate = clk_req->bitclk_rate;
+	const unsigned long esc_rate = clk_req->escclk_rate;
+	s32 ui, lpx;
+	s32 tmax, tmin;
+	s32 pcnt0 = 10;
+	s32 pcnt1 = (bit_rate > 1200000000) ? 15 : 10;
+	s32 pcnt2 = 10;
+	s32 pcnt3 = (bit_rate > 180000000) ? 10 : 40;
+	s32 coeff = 1000; /* Precision, should avoid overflow */
+	s32 temp;
+
+	if (!bit_rate || !esc_rate)
+		return -EINVAL;
+
+	ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
+	lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000);
+
+	tmax = S_DIV_ROUND_UP(95 * coeff, ui) - 2;
+	tmin = S_DIV_ROUND_UP(38 * coeff, ui) - 2;
+	timing->clk_prepare = linear_inter(tmax, tmin, pcnt0, 0, true);
+
+	temp = lpx / ui;
+	if (temp & 0x1)
+		timing->hs_rqst = temp;
+	else
+		timing->hs_rqst = max_t(s32, 0, temp - 2);
+
+	/* Calculate clk_zero after clk_prepare and hs_rqst */
+	dsi_dphy_timing_calc_clk_zero(timing, ui, coeff, pcnt2);
+
+	temp = 105 * coeff + 12 * ui - 20 * coeff;
+	tmax = S_DIV_ROUND_UP(temp, ui) - 2;
+	tmin = S_DIV_ROUND_UP(60 * coeff, ui) - 2;
+	timing->clk_trail = linear_inter(tmax, tmin, pcnt3, 0, true);
+
+	temp = 85 * coeff + 6 * ui;
+	tmax = S_DIV_ROUND_UP(temp, ui) - 2;
+	temp = 40 * coeff + 4 * ui;
+	tmin = S_DIV_ROUND_UP(temp, ui) - 2;
+	timing->hs_prepare = linear_inter(tmax, tmin, pcnt1, 0, true);
+
+	tmax = 255;
+	temp = ((timing->hs_prepare >> 1) + 1) * 2 * ui + 2 * ui;
+	temp = 145 * coeff + 10 * ui - temp;
+	tmin = S_DIV_ROUND_UP(temp, ui) - 2;
+	timing->hs_zero = linear_inter(tmax, tmin, pcnt2, 24, true);
+
+	temp = 105 * coeff + 12 * ui - 20 * coeff;
+	tmax = S_DIV_ROUND_UP(temp, ui) - 2;
+	temp = 60 * coeff + 4 * ui;
+	tmin = DIV_ROUND_UP(temp, ui) - 2;
+	timing->hs_trail = linear_inter(tmax, tmin, pcnt3, 0, true);
+
+	tmax = 255;
+	tmin = S_DIV_ROUND_UP(100 * coeff, ui) - 2;
+	timing->hs_exit = linear_inter(tmax, tmin, pcnt2, 0, true);
+
+	tmax = 63;
+	temp = ((timing->hs_exit >> 1) + 1) * 2 * ui;
+	temp = 60 * coeff + 52 * ui - 24 * ui - temp;
+	tmin = S_DIV_ROUND_UP(temp, 8 * ui) - 1;
+	timing->shared_timings.clk_post = linear_inter(tmax, tmin, pcnt2, 0,
+						       false);
+	tmax = 63;
+	temp = ((timing->clk_prepare >> 1) + 1) * 2 * ui;
+	temp += ((timing->clk_zero >> 1) + 1) * 2 * ui;
+	temp += 8 * ui + lpx;
+	tmin = S_DIV_ROUND_UP(temp, 8 * ui) - 1;
+	if (tmin > tmax) {
+		temp = linear_inter(2 * tmax, tmin, pcnt2, 0, false);
+		timing->shared_timings.clk_pre = temp >> 1;
+		timing->shared_timings.clk_pre_inc_by_2 = true;
+	} else {
+		timing->shared_timings.clk_pre =
+				linear_inter(tmax, tmin, pcnt2, 0, false);
+		timing->shared_timings.clk_pre_inc_by_2 = false;
+	}
+
+	timing->ta_go = 3;
+	timing->ta_sure = 0;
+	timing->ta_get = 4;
+
+	DBG("PHY timings: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
+		timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
+		timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero,
+		timing->clk_trail, timing->clk_prepare, timing->hs_exit,
+		timing->hs_zero, timing->hs_prepare, timing->hs_trail,
+		timing->hs_rqst);
+
+	return 0;
+}
+
+int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
+				struct msm_dsi_phy_clk_request *clk_req)
+{
+	const unsigned long bit_rate = clk_req->bitclk_rate;
+	const unsigned long esc_rate = clk_req->escclk_rate;
+	s32 ui, ui_x8;
+	s32 tmax, tmin;
+	s32 pcnt0 = 50;
+	s32 pcnt1 = 50;
+	s32 pcnt2 = 10;
+	s32 pcnt3 = 30;
+	s32 pcnt4 = 10;
+	s32 pcnt5 = 2;
+	s32 coeff = 1000; /* Precision, should avoid overflow */
+	s32 hb_en, hb_en_ckln, pd_ckln, pd;
+	s32 val, val_ckln;
+	s32 temp;
+
+	if (!bit_rate || !esc_rate)
+		return -EINVAL;
+
+	timing->hs_halfbyte_en = 0;
+	hb_en = 0;
+	timing->hs_halfbyte_en_ckln = 0;
+	hb_en_ckln = 0;
+	timing->hs_prep_dly_ckln = (bit_rate > 100000000) ? 0 : 3;
+	pd_ckln = timing->hs_prep_dly_ckln;
+	timing->hs_prep_dly = (bit_rate > 120000000) ? 0 : 1;
+	pd = timing->hs_prep_dly;
+
+	val = (hb_en << 2) + (pd << 1);
+	val_ckln = (hb_en_ckln << 2) + (pd_ckln << 1);
+
+	ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
+	ui_x8 = ui << 3;
+
+	temp = S_DIV_ROUND_UP(38 * coeff - val_ckln * ui, ui_x8);
+	tmin = max_t(s32, temp, 0);
+	temp = (95 * coeff - val_ckln * ui) / ui_x8;
+	tmax = max_t(s32, temp, 0);
+	timing->clk_prepare = linear_inter(tmax, tmin, pcnt0, 0, false);
+
+	temp = 300 * coeff - ((timing->clk_prepare << 3) + val_ckln) * ui;
+	tmin = S_DIV_ROUND_UP(temp - 11 * ui, ui_x8) - 3;
+	tmax = (tmin > 255) ? 511 : 255;
+	timing->clk_zero = linear_inter(tmax, tmin, pcnt5, 0, false);
+
+	tmin = DIV_ROUND_UP(60 * coeff + 3 * ui, ui_x8);
+	temp = 105 * coeff + 12 * ui - 20 * coeff;
+	tmax = (temp + 3 * ui) / ui_x8;
+	timing->clk_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
+
+	temp = S_DIV_ROUND_UP(40 * coeff + 4 * ui - val * ui, ui_x8);
+	tmin = max_t(s32, temp, 0);
+	temp = (85 * coeff + 6 * ui - val * ui) / ui_x8;
+	tmax = max_t(s32, temp, 0);
+	timing->hs_prepare = linear_inter(tmax, tmin, pcnt1, 0, false);
+
+	temp = 145 * coeff + 10 * ui - ((timing->hs_prepare << 3) + val) * ui;
+	tmin = S_DIV_ROUND_UP(temp - 11 * ui, ui_x8) - 3;
+	tmax = 255;
+	timing->hs_zero = linear_inter(tmax, tmin, pcnt4, 0, false);
+
+	tmin = DIV_ROUND_UP(60 * coeff + 4 * ui + 3 * ui, ui_x8);
+	temp = 105 * coeff + 12 * ui - 20 * coeff;
+	tmax = (temp + 3 * ui) / ui_x8;
+	timing->hs_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
+
+	temp = 50 * coeff + ((hb_en << 2) - 8) * ui;
+	timing->hs_rqst = S_DIV_ROUND_UP(temp, ui_x8);
+
+	tmin = DIV_ROUND_UP(100 * coeff, ui_x8) - 1;
+	tmax = 255;
+	timing->hs_exit = linear_inter(tmax, tmin, pcnt2, 0, false);
+
+	temp = 50 * coeff + ((hb_en_ckln << 2) - 8) * ui;
+	timing->hs_rqst_ckln = S_DIV_ROUND_UP(temp, ui_x8);
+
+	temp = 60 * coeff + 52 * ui - 43 * ui;
+	tmin = DIV_ROUND_UP(temp, ui_x8) - 1;
+	tmax = 63;
+	timing->shared_timings.clk_post =
+				linear_inter(tmax, tmin, pcnt2, 0, false);
+
+	temp = 8 * ui + ((timing->clk_prepare << 3) + val_ckln) * ui;
+	temp += (((timing->clk_zero + 3) << 3) + 11 - (pd_ckln << 1)) * ui;
+	temp += hb_en_ckln ? (((timing->hs_rqst_ckln << 3) + 4) * ui) :
+				(((timing->hs_rqst_ckln << 3) + 8) * ui);
+	tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
+	tmax = 63;
+	if (tmin > tmax) {
+		temp = linear_inter(tmax << 1, tmin, pcnt2, 0, false);
+		timing->shared_timings.clk_pre = temp >> 1;
+		timing->shared_timings.clk_pre_inc_by_2 = 1;
+	} else {
+		timing->shared_timings.clk_pre =
+				linear_inter(tmax, tmin, pcnt2, 0, false);
+		timing->shared_timings.clk_pre_inc_by_2 = 0;
+	}
+
+	timing->ta_go = 3;
+	timing->ta_sure = 0;
+	timing->ta_get = 4;
+
+	DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
+	    timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
+	    timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero,
+	    timing->clk_trail, timing->clk_prepare, timing->hs_exit,
+	    timing->hs_zero, timing->hs_prepare, timing->hs_trail,
+	    timing->hs_rqst, timing->hs_rqst_ckln, timing->hs_halfbyte_en,
+	    timing->hs_halfbyte_en_ckln, timing->hs_prep_dly,
+	    timing->hs_prep_dly_ckln);
+
+	return 0;
+}
+
+int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
+	struct msm_dsi_phy_clk_request *clk_req)
+{
+	const unsigned long bit_rate = clk_req->bitclk_rate;
+	const unsigned long esc_rate = clk_req->escclk_rate;
+	s32 ui, ui_x8;
+	s32 tmax, tmin;
+	s32 pcnt0 = 50;
+	s32 pcnt1 = 50;
+	s32 pcnt2 = 10;
+	s32 pcnt3 = 30;
+	s32 pcnt4 = 10;
+	s32 pcnt5 = 2;
+	s32 coeff = 1000; /* Precision, should avoid overflow */
+	s32 hb_en, hb_en_ckln;
+	s32 temp;
+
+	if (!bit_rate || !esc_rate)
+		return -EINVAL;
+
+	timing->hs_halfbyte_en = 0;
+	hb_en = 0;
+	timing->hs_halfbyte_en_ckln = 0;
+	hb_en_ckln = 0;
+
+	ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
+	ui_x8 = ui << 3;
+
+	temp = S_DIV_ROUND_UP(38 * coeff, ui_x8);
+	tmin = max_t(s32, temp, 0);
+	temp = (95 * coeff) / ui_x8;
+	tmax = max_t(s32, temp, 0);
+	timing->clk_prepare = linear_inter(tmax, tmin, pcnt0, 0, false);
+
+	temp = 300 * coeff - (timing->clk_prepare << 3) * ui;
+	tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
+	tmax = (tmin > 255) ? 511 : 255;
+	timing->clk_zero = linear_inter(tmax, tmin, pcnt5, 0, false);
+
+	tmin = DIV_ROUND_UP(60 * coeff + 3 * ui, ui_x8);
+	temp = 105 * coeff + 12 * ui - 20 * coeff;
+	tmax = (temp + 3 * ui) / ui_x8;
+	timing->clk_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
+
+	temp = S_DIV_ROUND_UP(40 * coeff + 4 * ui, ui_x8);
+	tmin = max_t(s32, temp, 0);
+	temp = (85 * coeff + 6 * ui) / ui_x8;
+	tmax = max_t(s32, temp, 0);
+	timing->hs_prepare = linear_inter(tmax, tmin, pcnt1, 0, false);
+
+	temp = 145 * coeff + 10 * ui - (timing->hs_prepare << 3) * ui;
+	tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
+	tmax = 255;
+	timing->hs_zero = linear_inter(tmax, tmin, pcnt4, 0, false);
+
+	tmin = DIV_ROUND_UP(60 * coeff + 4 * ui, ui_x8) - 1;
+	temp = 105 * coeff + 12 * ui - 20 * coeff;
+	tmax = (temp / ui_x8) - 1;
+	timing->hs_trail = linear_inter(tmax, tmin, pcnt3, 0, false);
+
+	temp = 50 * coeff + ((hb_en << 2) - 8) * ui;
+	timing->hs_rqst = S_DIV_ROUND_UP(temp, ui_x8);
+
+	tmin = DIV_ROUND_UP(100 * coeff, ui_x8) - 1;
+	tmax = 255;
+	timing->hs_exit = linear_inter(tmax, tmin, pcnt2, 0, false);
+
+	temp = 50 * coeff + ((hb_en_ckln << 2) - 8) * ui;
+	timing->hs_rqst_ckln = S_DIV_ROUND_UP(temp, ui_x8);
+
+	temp = 60 * coeff + 52 * ui - 43 * ui;
+	tmin = DIV_ROUND_UP(temp, ui_x8) - 1;
+	tmax = 63;
+	timing->shared_timings.clk_post =
+		linear_inter(tmax, tmin, pcnt2, 0, false);
+
+	temp = 8 * ui + (timing->clk_prepare << 3) * ui;
+	temp += (((timing->clk_zero + 3) << 3) + 11) * ui;
+	temp += hb_en_ckln ? (((timing->hs_rqst_ckln << 3) + 4) * ui) :
+		(((timing->hs_rqst_ckln << 3) + 8) * ui);
+	tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
+	tmax = 63;
+	if (tmin > tmax) {
+		temp = linear_inter(tmax << 1, tmin, pcnt2, 0, false);
+		timing->shared_timings.clk_pre = temp >> 1;
+		timing->shared_timings.clk_pre_inc_by_2 = 1;
+	} else {
+		timing->shared_timings.clk_pre =
+			linear_inter(tmax, tmin, pcnt2, 0, false);
+		timing->shared_timings.clk_pre_inc_by_2 = 0;
+	}
+
+	timing->shared_timings.byte_intf_clk_div_2 = true;
+
+	timing->ta_go = 3;
+	timing->ta_sure = 0;
+	timing->ta_get = 4;
+
+	DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
+		timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
+		timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero,
+		timing->clk_trail, timing->clk_prepare, timing->hs_exit,
+		timing->hs_zero, timing->hs_prepare, timing->hs_trail,
+		timing->hs_rqst, timing->hs_rqst_ckln, timing->hs_halfbyte_en,
+		timing->hs_halfbyte_en_ckln, timing->hs_prep_dly,
+		timing->hs_prep_dly_ckln);
+
+	return 0;
+}
+
+int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,
+	struct msm_dsi_phy_clk_request *clk_req)
+{
+	const unsigned long bit_rate = clk_req->bitclk_rate;
+	const unsigned long esc_rate = clk_req->escclk_rate;
+	s32 ui, ui_x8;
+	s32 tmax, tmin;
+	s32 pcnt_clk_prep = 50;
+	s32 pcnt_clk_zero = 2;
+	s32 pcnt_clk_trail = 30;
+	s32 pcnt_hs_prep = 50;
+	s32 pcnt_hs_zero = 10;
+	s32 pcnt_hs_trail = 30;
+	s32 pcnt_hs_exit = 10;
+	s32 coeff = 1000; /* Precision, should avoid overflow */
+	s32 hb_en;
+	s32 temp;
+
+	if (!bit_rate || !esc_rate)
+		return -EINVAL;
+
+	hb_en = 0;
+
+	ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
+	ui_x8 = ui << 3;
+
+	/* TODO: verify these calculations against latest downstream driver
+	 * everything except clk_post/clk_pre uses calculations from v3 based
+	 * on the downstream driver having the same calculations for v3 and v4
+	 */
+
+	temp = S_DIV_ROUND_UP(38 * coeff, ui_x8);
+	tmin = max_t(s32, temp, 0);
+	temp = (95 * coeff) / ui_x8;
+	tmax = max_t(s32, temp, 0);
+	timing->clk_prepare = linear_inter(tmax, tmin, pcnt_clk_prep, 0, false);
+
+	temp = 300 * coeff - (timing->clk_prepare << 3) * ui;
+	tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
+	tmax = (tmin > 255) ? 511 : 255;
+	timing->clk_zero = linear_inter(tmax, tmin, pcnt_clk_zero, 0, false);
+
+	tmin = DIV_ROUND_UP(60 * coeff + 3 * ui, ui_x8);
+	temp = 105 * coeff + 12 * ui - 20 * coeff;
+	tmax = (temp + 3 * ui) / ui_x8;
+	timing->clk_trail = linear_inter(tmax, tmin, pcnt_clk_trail, 0, false);
+
+	temp = S_DIV_ROUND_UP(40 * coeff + 4 * ui, ui_x8);
+	tmin = max_t(s32, temp, 0);
+	temp = (85 * coeff + 6 * ui) / ui_x8;
+	tmax = max_t(s32, temp, 0);
+	timing->hs_prepare = linear_inter(tmax, tmin, pcnt_hs_prep, 0, false);
+
+	temp = 145 * coeff + 10 * ui - (timing->hs_prepare << 3) * ui;
+	tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1;
+	tmax = 255;
+	timing->hs_zero = linear_inter(tmax, tmin, pcnt_hs_zero, 0, false);
+
+	tmin = DIV_ROUND_UP(60 * coeff + 4 * ui, ui_x8) - 1;
+	temp = 105 * coeff + 12 * ui - 20 * coeff;
+	tmax = (temp / ui_x8) - 1;
+	timing->hs_trail = linear_inter(tmax, tmin, pcnt_hs_trail, 0, false);
+
+	temp = 50 * coeff + ((hb_en << 2) - 8) * ui;
+	timing->hs_rqst = S_DIV_ROUND_UP(temp, ui_x8);
+
+	tmin = DIV_ROUND_UP(100 * coeff, ui_x8) - 1;
+	tmax = 255;
+	timing->hs_exit = linear_inter(tmax, tmin, pcnt_hs_exit, 0, false);
+
+	/* recommended min
+	 * = roundup((mipi_min_ns + t_hs_trail_ns)/(16*bit_clk_ns), 0) - 1
+	 */
+	temp = 60 * coeff + 52 * ui + + (timing->hs_trail + 1) * ui_x8;
+	tmin = DIV_ROUND_UP(temp, 16 * ui) - 1;
+	tmax = 255;
+	timing->shared_timings.clk_post = linear_inter(tmax, tmin, 5, 0, false);
+
+	/* recommended min
+	 * val1 = (tlpx_ns + clk_prepare_ns + clk_zero_ns + hs_rqst_ns)
+	 * val2 = (16 * bit_clk_ns)
+	 * final = roundup(val1/val2, 0) - 1
+	 */
+	temp = 52 * coeff + (timing->clk_prepare + timing->clk_zero + 1) * ui_x8 + 54 * coeff;
+	tmin = DIV_ROUND_UP(temp, 16 * ui) - 1;
+	tmax = 255;
+	timing->shared_timings.clk_pre = DIV_ROUND_UP((tmax - tmin) * 125, 10000) + tmin;
+
+	timing->shared_timings.byte_intf_clk_div_2 = true;
+
+	DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
+		timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
+		timing->clk_zero, timing->clk_trail, timing->clk_prepare, timing->hs_exit,
+		timing->hs_zero, timing->hs_prepare, timing->hs_trail, timing->hs_rqst);
+
+	return 0;
+}
+
+int msm_dsi_cphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,
+	struct msm_dsi_phy_clk_request *clk_req)
+{
+	const unsigned long bit_rate = clk_req->bitclk_rate;
+	const unsigned long esc_rate = clk_req->escclk_rate;
+	s32 ui, ui_x7;
+	s32 tmax, tmin;
+	s32 coeff = 1000; /* Precision, should avoid overflow */
+	s32 temp;
+
+	if (!bit_rate || !esc_rate)
+		return -EINVAL;
+
+	ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000);
+	ui_x7 = ui * 7;
+
+	temp = S_DIV_ROUND_UP(38 * coeff, ui_x7);
+	tmin = max_t(s32, temp, 0);
+	temp = (95 * coeff) / ui_x7;
+	tmax = max_t(s32, temp, 0);
+	timing->clk_prepare = linear_inter(tmax, tmin, 50, 0, false);
+
+	tmin = DIV_ROUND_UP(50 * coeff, ui_x7);
+	tmax = 255;
+	timing->hs_rqst = linear_inter(tmax, tmin, 1, 0, false);
+
+	tmin = DIV_ROUND_UP(100 * coeff, ui_x7) - 1;
+	tmax = 255;
+	timing->hs_exit = linear_inter(tmax, tmin, 10, 0, false);
+
+	tmin = 1;
+	tmax = 32;
+	timing->shared_timings.clk_post = linear_inter(tmax, tmin, 80, 0, false);
+
+	tmin = min_t(s32, 64, S_DIV_ROUND_UP(262 * coeff, ui_x7) - 1);
+	tmax = 64;
+	timing->shared_timings.clk_pre = linear_inter(tmax, tmin, 20, 0, false);
+
+	DBG("%d, %d, %d, %d, %d",
+		timing->shared_timings.clk_pre, timing->shared_timings.clk_post,
+		timing->clk_prepare, timing->hs_exit, timing->hs_rqst);
+
+	return 0;
+}
+
+static int dsi_phy_enable_resource(struct msm_dsi_phy *phy)
+{
+	struct device *dev = &phy->pdev->dev;
+	int ret;
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(phy->ahb_clk);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "%s: can't enable ahb clk, %d\n", __func__, ret);
+		pm_runtime_put_sync(dev);
+	}
+
+	return ret;
+}
+
+static void dsi_phy_disable_resource(struct msm_dsi_phy *phy)
+{
+	clk_disable_unprepare(phy->ahb_clk);
+	pm_runtime_put(&phy->pdev->dev);
+}
+
+static const struct of_device_id dsi_phy_dt_match[] = {
+#ifdef CONFIG_DRM_MSM_DSI_28NM_PHY
+	{ .compatible = "qcom,dsi-phy-28nm-hpm",
+	  .data = &dsi_phy_28nm_hpm_cfgs },
+	{ .compatible = "qcom,dsi-phy-28nm-hpm-fam-b",
+	  .data = &dsi_phy_28nm_hpm_famb_cfgs },
+	{ .compatible = "qcom,dsi-phy-28nm-lp",
+	  .data = &dsi_phy_28nm_lp_cfgs },
+	{ .compatible = "qcom,dsi-phy-28nm-8226",
+	  .data = &dsi_phy_28nm_8226_cfgs },
+#endif
+#ifdef CONFIG_DRM_MSM_DSI_20NM_PHY
+	{ .compatible = "qcom,dsi-phy-20nm",
+	  .data = &dsi_phy_20nm_cfgs },
+#endif
+#ifdef CONFIG_DRM_MSM_DSI_28NM_8960_PHY
+	{ .compatible = "qcom,dsi-phy-28nm-8960",
+	  .data = &dsi_phy_28nm_8960_cfgs },
+#endif
+#ifdef CONFIG_DRM_MSM_DSI_14NM_PHY
+	{ .compatible = "qcom,dsi-phy-14nm",
+	  .data = &dsi_phy_14nm_cfgs },
+	{ .compatible = "qcom,dsi-phy-14nm-2290",
+	  .data = &dsi_phy_14nm_2290_cfgs },
+	{ .compatible = "qcom,dsi-phy-14nm-660",
+	  .data = &dsi_phy_14nm_660_cfgs },
+	{ .compatible = "qcom,dsi-phy-14nm-8953",
+	  .data = &dsi_phy_14nm_8953_cfgs },
+	{ .compatible = "qcom,sm6125-dsi-phy-14nm",
+	  .data = &dsi_phy_14nm_2290_cfgs },
+#endif
+#ifdef CONFIG_DRM_MSM_DSI_10NM_PHY
+	{ .compatible = "qcom,dsi-phy-10nm",
+	  .data = &dsi_phy_10nm_cfgs },
+	{ .compatible = "qcom,dsi-phy-10nm-8998",
+	  .data = &dsi_phy_10nm_8998_cfgs },
+#endif
+#ifdef CONFIG_DRM_MSM_DSI_7NM_PHY
+	{ .compatible = "qcom,dsi-phy-7nm",
+	  .data = &dsi_phy_7nm_cfgs },
+	{ .compatible = "qcom,dsi-phy-7nm-8150",
+	  .data = &dsi_phy_7nm_8150_cfgs },
+	{ .compatible = "qcom,sc7280-dsi-phy-7nm",
+	  .data = &dsi_phy_7nm_7280_cfgs },
+	{ .compatible = "qcom,sm6375-dsi-phy-7nm",
+	  .data = &dsi_phy_7nm_6375_cfgs },
+	{ .compatible = "qcom,sm8350-dsi-phy-5nm",
+	  .data = &dsi_phy_5nm_8350_cfgs },
+	{ .compatible = "qcom,sa8775p-dsi-phy-5nm",
+	  .data = &dsi_phy_5nm_8775_cfgs },
+	{ .compatible = "qcom,sm8450-dsi-phy-5nm",
+	  .data = &dsi_phy_5nm_8450_cfgs },
+	{ .compatible = "qcom,sm8550-dsi-phy-4nm",
+	  .data = &dsi_phy_4nm_8550_cfgs },
+	{ .compatible = "qcom,sm8650-dsi-phy-4nm",
+	  .data = &dsi_phy_4nm_8650_cfgs },
+#endif
+	{}
+};
+
+/*
+ * Currently, we only support one SoC for each PHY type. When we have multiple
+ * SoCs for the same PHY, we can try to make the index searching a bit more
+ * clever.
+ */
+static int dsi_phy_get_id(struct msm_dsi_phy *phy)
+{
+	struct platform_device *pdev = phy->pdev;
+	const struct msm_dsi_phy_cfg *cfg = phy->cfg;
+	struct resource *res;
+	int i;
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dsi_phy");
+	if (!res)
+		return -EINVAL;
+
+	for (i = 0; i < cfg->num_dsi_phy; i++) {
+		if (cfg->io_start[i] == res->start)
+			return i;
+	}
+
+	return -EINVAL;
+}
+
+static int dsi_phy_driver_probe(struct platform_device *pdev)
+{
+	struct msm_dsi_phy *phy;
+	struct device *dev = &pdev->dev;
+	u32 phy_type;
+	int ret;
+
+	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+	if (!phy)
+		return -ENOMEM;
+
+	phy->provided_clocks = devm_kzalloc(dev,
+			struct_size(phy->provided_clocks, hws, NUM_PROVIDED_CLKS),
+			GFP_KERNEL);
+	if (!phy->provided_clocks)
+		return -ENOMEM;
+
+	phy->provided_clocks->num = NUM_PROVIDED_CLKS;
+
+	phy->cfg = of_device_get_match_data(&pdev->dev);
+	if (!phy->cfg)
+		return -ENODEV;
+
+	phy->pdev = pdev;
+
+	phy->id = dsi_phy_get_id(phy);
+	if (phy->id < 0)
+		return dev_err_probe(dev, phy->id,
+				     "Couldn't identify PHY index\n");
+
+	phy->regulator_ldo_mode = of_property_read_bool(dev->of_node,
+				"qcom,dsi-phy-regulator-ldo-mode");
+	if (!of_property_read_u32(dev->of_node, "phy-type", &phy_type))
+		phy->cphy_mode = (phy_type == PHY_TYPE_CPHY);
+
+	phy->base = msm_ioremap_size(pdev, "dsi_phy", &phy->base_size);
+	if (IS_ERR(phy->base))
+		return dev_err_probe(dev, PTR_ERR(phy->base),
+				     "Failed to map phy base\n");
+
+	phy->pll_base = msm_ioremap_size(pdev, "dsi_pll", &phy->pll_size);
+	if (IS_ERR(phy->pll_base))
+		return dev_err_probe(dev, PTR_ERR(phy->pll_base),
+				     "Failed to map pll base\n");
+
+	if (phy->cfg->has_phy_lane) {
+		phy->lane_base = msm_ioremap_size(pdev, "dsi_phy_lane", &phy->lane_size);
+		if (IS_ERR(phy->lane_base))
+			return dev_err_probe(dev, PTR_ERR(phy->lane_base),
+					     "Failed to map phy lane base\n");
+	}
+
+	if (phy->cfg->has_phy_regulator) {
+		phy->reg_base = msm_ioremap_size(pdev, "dsi_phy_regulator", &phy->reg_size);
+		if (IS_ERR(phy->reg_base))
+			return dev_err_probe(dev, PTR_ERR(phy->reg_base),
+					     "Failed to map phy regulator base\n");
+	}
+
+	if (phy->cfg->ops.parse_dt_properties) {
+		ret = phy->cfg->ops.parse_dt_properties(phy);
+		if (ret)
+			return ret;
+	}
+
+	ret = devm_regulator_bulk_get_const(dev, phy->cfg->num_regulators,
+					    phy->cfg->regulator_data,
+					    &phy->supplies);
+	if (ret)
+		return ret;
+
+	phy->ahb_clk = msm_clk_get(pdev, "iface");
+	if (IS_ERR(phy->ahb_clk))
+		return dev_err_probe(dev, PTR_ERR(phy->ahb_clk),
+				     "Unable to get ahb clk\n");
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		return ret;
+
+	/* PLL init will call into clk_register which requires
+	 * register access, so we need to enable power and ahb clock.
+	 */
+	ret = dsi_phy_enable_resource(phy);
+	if (ret)
+		return ret;
+
+	if (phy->cfg->ops.pll_init) {
+		ret = phy->cfg->ops.pll_init(phy);
+		if (ret)
+			return dev_err_probe(dev, ret,
+					     "PLL init failed; need separate clk driver\n");
+	}
+
+	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+				     phy->provided_clocks);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Failed to register clk provider\n");
+
+	dsi_phy_disable_resource(phy);
+
+	platform_set_drvdata(pdev, phy);
+
+	return 0;
+}
+
+static struct platform_driver dsi_phy_platform_driver = {
+	.probe      = dsi_phy_driver_probe,
+	.driver     = {
+		.name   = "msm_dsi_phy",
+		.of_match_table = dsi_phy_dt_match,
+	},
+};
+
+void __init msm_dsi_phy_driver_register(void)
+{
+	platform_driver_register(&dsi_phy_platform_driver);
+}
+
+void __exit msm_dsi_phy_driver_unregister(void)
+{
+	platform_driver_unregister(&dsi_phy_platform_driver);
+}
+
+int msm_dsi_phy_enable(struct msm_dsi_phy *phy,
+			struct msm_dsi_phy_clk_request *clk_req,
+			struct msm_dsi_phy_shared_timings *shared_timings)
+{
+	struct device *dev;
+	int ret;
+
+	if (!phy || !phy->cfg->ops.enable)
+		return -EINVAL;
+
+	dev = &phy->pdev->dev;
+
+	ret = dsi_phy_enable_resource(phy);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "%s: resource enable failed, %d\n",
+			__func__, ret);
+		goto res_en_fail;
+	}
+
+	ret = regulator_bulk_enable(phy->cfg->num_regulators, phy->supplies);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "%s: regulator enable failed, %d\n",
+			__func__, ret);
+		goto reg_en_fail;
+	}
+
+	ret = phy->cfg->ops.enable(phy, clk_req);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "%s: phy enable failed, %d\n", __func__, ret);
+		goto phy_en_fail;
+	}
+
+	memcpy(shared_timings, &phy->timing.shared_timings,
+	       sizeof(*shared_timings));
+
+	/*
+	 * Resetting DSI PHY silently changes its PLL registers to reset status,
+	 * which will confuse clock driver and result in wrong output rate of
+	 * link clocks. Restore PLL status if its PLL is being used as clock
+	 * source.
+	 */
+	if (phy->usecase != MSM_DSI_PHY_SLAVE) {
+		ret = msm_dsi_phy_pll_restore_state(phy);
+		if (ret) {
+			DRM_DEV_ERROR(dev, "%s: failed to restore phy state, %d\n",
+				__func__, ret);
+			goto pll_restor_fail;
+		}
+	}
+
+	return 0;
+
+pll_restor_fail:
+	if (phy->cfg->ops.disable)
+		phy->cfg->ops.disable(phy);
+phy_en_fail:
+	regulator_bulk_disable(phy->cfg->num_regulators, phy->supplies);
+reg_en_fail:
+	dsi_phy_disable_resource(phy);
+res_en_fail:
+	return ret;
+}
+
+void msm_dsi_phy_disable(struct msm_dsi_phy *phy)
+{
+	if (!phy || !phy->cfg->ops.disable)
+		return;
+
+	phy->cfg->ops.disable(phy);
+
+	regulator_bulk_disable(phy->cfg->num_regulators, phy->supplies);
+	dsi_phy_disable_resource(phy);
+}
+
+void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,
+			     enum msm_dsi_phy_usecase uc)
+{
+	if (phy)
+		phy->usecase = uc;
+}
+
+/* Returns true if we have to clear DSI_LANE_CTRL.HS_REQ_SEL_PHY */
+bool msm_dsi_phy_set_continuous_clock(struct msm_dsi_phy *phy, bool enable)
+{
+	if (!phy || !phy->cfg->ops.set_continuous_clock)
+		return false;
+
+	return phy->cfg->ops.set_continuous_clock(phy, enable);
+}
+
+void msm_dsi_phy_pll_save_state(struct msm_dsi_phy *phy)
+{
+	if (phy->cfg->ops.save_pll_state) {
+		phy->cfg->ops.save_pll_state(phy);
+		phy->state_saved = true;
+	}
+}
+
+int msm_dsi_phy_pll_restore_state(struct msm_dsi_phy *phy)
+{
+	int ret;
+
+	if (phy->cfg->ops.restore_pll_state && phy->state_saved) {
+		ret = phy->cfg->ops.restore_pll_state(phy);
+		if (ret)
+			return ret;
+
+		phy->state_saved = false;
+	}
+
+	return 0;
+}
+
+void msm_dsi_phy_snapshot(struct msm_disp_state *disp_state, struct msm_dsi_phy *phy)
+{
+	msm_disp_snapshot_add_block(disp_state,
+			phy->base_size, phy->base,
+			"dsi%d_phy", phy->id);
+
+	/* Do not try accessing PLL registers if it is switched off */
+	if (phy->pll_on)
+		msm_disp_snapshot_add_block(disp_state,
+			phy->pll_size, phy->pll_base,
+			"dsi%d_pll", phy->id);
+
+	if (phy->lane_base)
+		msm_disp_snapshot_add_block(disp_state,
+			phy->lane_size, phy->lane_base,
+			"dsi%d_lane", phy->id);
+
+	if (phy->reg_base)
+		msm_disp_snapshot_add_block(disp_state,
+			phy->reg_size, phy->reg_base,
+			"dsi%d_reg", phy->id);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef __DSI_PHY_H__
+#define __DSI_PHY_H__
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/regulator/consumer.h>
+
+#include "dsi.h"
+
+#define dsi_phy_read(offset) msm_readl((offset))
+#define dsi_phy_write(offset, data) msm_writel((data), (offset))
+#define dsi_phy_write_udelay(offset, data, delay_us) { msm_writel((data), (offset)); udelay(delay_us); }
+#define dsi_phy_write_ndelay(offset, data, delay_ns) { msm_writel((data), (offset)); ndelay(delay_ns); }
+
+struct msm_dsi_phy_ops {
+	int (*pll_init)(struct msm_dsi_phy *phy);
+	int (*enable)(struct msm_dsi_phy *phy,
+			struct msm_dsi_phy_clk_request *clk_req);
+	void (*disable)(struct msm_dsi_phy *phy);
+	void (*save_pll_state)(struct msm_dsi_phy *phy);
+	int (*restore_pll_state)(struct msm_dsi_phy *phy);
+	bool (*set_continuous_clock)(struct msm_dsi_phy *phy, bool enable);
+	int (*parse_dt_properties)(struct msm_dsi_phy *phy);
+};
+
+struct msm_dsi_phy_cfg {
+	const struct regulator_bulk_data *regulator_data;
+	int num_regulators;
+	struct msm_dsi_phy_ops ops;
+
+	unsigned long	min_pll_rate;
+	unsigned long	max_pll_rate;
+
+	const resource_size_t io_start[DSI_MAX];
+	const int num_dsi_phy;
+	const int quirks;
+	bool has_phy_regulator;
+	bool has_phy_lane;
+};
+
+extern const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_famb_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_28nm_8226_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_20nm_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_14nm_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_14nm_660_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_14nm_2290_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_14nm_8953_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_7nm_6375_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8350_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8775_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs;
+extern const struct msm_dsi_phy_cfg dsi_phy_4nm_8650_cfgs;
+
+struct msm_dsi_dphy_timing {
+	u32 clk_zero;
+	u32 clk_trail;
+	u32 clk_prepare;
+	u32 hs_exit;
+	u32 hs_zero;
+	u32 hs_prepare;
+	u32 hs_trail;
+	u32 hs_rqst;
+	u32 ta_go;
+	u32 ta_sure;
+	u32 ta_get;
+
+	struct msm_dsi_phy_shared_timings shared_timings;
+
+	/* For PHY v2 only */
+	u32 hs_rqst_ckln;
+	u32 hs_prep_dly;
+	u32 hs_prep_dly_ckln;
+	u8 hs_halfbyte_en;
+	u8 hs_halfbyte_en_ckln;
+};
+
+#define DSI_BYTE_PLL_CLK		0
+#define DSI_PIXEL_PLL_CLK		1
+#define NUM_PROVIDED_CLKS		2
+
+#define DSI_LANE_MAX			5
+
+struct msm_dsi_phy {
+	struct platform_device *pdev;
+	void __iomem *base;
+	void __iomem *pll_base;
+	void __iomem *reg_base;
+	void __iomem *lane_base;
+	phys_addr_t base_size;
+	phys_addr_t pll_size;
+	phys_addr_t reg_size;
+	phys_addr_t lane_size;
+	int id;
+
+	struct clk *ahb_clk;
+	struct regulator_bulk_data *supplies;
+
+	struct msm_dsi_dphy_timing timing;
+	const struct msm_dsi_phy_cfg *cfg;
+	void *tuning_cfg;
+
+	enum msm_dsi_phy_usecase usecase;
+	bool regulator_ldo_mode;
+	bool cphy_mode;
+
+	struct clk_hw *vco_hw;
+	bool pll_on;
+
+	struct clk_hw_onecell_data *provided_clocks;
+
+	bool state_saved;
+};
+
+/*
+ * PHY internal functions
+ */
+int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing,
+			     struct msm_dsi_phy_clk_request *clk_req);
+int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing,
+				struct msm_dsi_phy_clk_request *clk_req);
+int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing,
+				struct msm_dsi_phy_clk_request *clk_req);
+int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,
+				struct msm_dsi_phy_clk_request *clk_req);
+int msm_dsi_cphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing,
+				struct msm_dsi_phy_clk_request *clk_req);
+
+#endif /* __DSI_PHY_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy_10nm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy_10nm.c
@@ -0,0 +1,1061 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) 2018, The Linux Foundation
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/iopoll.h>
+
+#include "dsi_phy.h"
+#include "dsi.xml.h"
+#include "dsi_phy_10nm.xml.h"
+
+/*
+ * DSI PLL 10nm - clock diagram (eg: DSI0):
+ *
+ *           dsi0_pll_out_div_clk  dsi0_pll_bit_clk
+ *                              |                |
+ *                              |                |
+ *                 +---------+  |  +----------+  |  +----+
+ *  dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk
+ *                 +---------+  |  +----------+  |  +----+
+ *                              |                |
+ *                              |                |         dsi0_pll_by_2_bit_clk
+ *                              |                |          |
+ *                              |                |  +----+  |  |\  dsi0_pclk_mux
+ *                              |                |--| /2 |--o--| \   |
+ *                              |                |  +----+     |  \  |  +---------+
+ *                              |                --------------|  |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk
+ *                              |------------------------------|  /     +---------+
+ *                              |          +-----+             | /
+ *                              -----------| /4? |--o----------|/
+ *                                         +-----+  |           |
+ *                                                  |           |dsiclk_sel
+ *                                                  |
+ *                                                  dsi0_pll_post_out_div_clk
+ */
+
+#define VCO_REF_CLK_RATE		19200000
+#define FRAC_BITS 18
+
+/* v3.0.0 10nm implementation that requires the old timings settings */
+#define DSI_PHY_10NM_QUIRK_OLD_TIMINGS	BIT(0)
+
+struct dsi_pll_config {
+	bool enable_ssc;
+	bool ssc_center;
+	u32 ssc_freq;
+	u32 ssc_offset;
+	u32 ssc_adj_per;
+
+	/* out */
+	u32 pll_prop_gain_rate;
+	u32 decimal_div_start;
+	u32 frac_div_start;
+	u32 pll_clock_inverters;
+	u32 ssc_stepsize;
+	u32 ssc_div_per;
+};
+
+struct pll_10nm_cached_state {
+	unsigned long vco_rate;
+	u8 bit_clk_div;
+	u8 pix_clk_div;
+	u8 pll_out_div;
+	u8 pll_mux;
+};
+
+struct dsi_pll_10nm {
+	struct clk_hw clk_hw;
+
+	struct msm_dsi_phy *phy;
+
+	u64 vco_current_rate;
+
+	/* protects REG_DSI_10nm_PHY_CMN_CLK_CFG0 register */
+	spinlock_t postdiv_lock;
+
+	struct pll_10nm_cached_state cached_state;
+
+	struct dsi_pll_10nm *slave;
+};
+
+#define to_pll_10nm(x)	container_of(x, struct dsi_pll_10nm, clk_hw)
+
+/**
+ * struct dsi_phy_10nm_tuning_cfg - Holds 10nm PHY tuning config parameters.
+ * @rescode_offset_top: Offset for pull-up legs rescode.
+ * @rescode_offset_bot: Offset for pull-down legs rescode.
+ * @vreg_ctrl: vreg ctrl to drive LDO level
+ */
+struct dsi_phy_10nm_tuning_cfg {
+	u8 rescode_offset_top[DSI_LANE_MAX];
+	u8 rescode_offset_bot[DSI_LANE_MAX];
+	u8 vreg_ctrl;
+};
+
+/*
+ * Global list of private DSI PLL struct pointers. We need this for bonded DSI
+ * mode, where the master PLL's clk_ops needs access the slave's private data
+ */
+static struct dsi_pll_10nm *pll_10nm_list[DSI_MAX];
+
+static void dsi_pll_setup_config(struct dsi_pll_config *config)
+{
+	config->ssc_freq = 31500;
+	config->ssc_offset = 5000;
+	config->ssc_adj_per = 2;
+
+	config->enable_ssc = false;
+	config->ssc_center = false;
+}
+
+static void dsi_pll_calc_dec_frac(struct dsi_pll_10nm *pll, struct dsi_pll_config *config)
+{
+	u64 fref = VCO_REF_CLK_RATE;
+	u64 pll_freq;
+	u64 divider;
+	u64 dec, dec_multiple;
+	u32 frac;
+	u64 multiplier;
+
+	pll_freq = pll->vco_current_rate;
+
+	divider = fref * 2;
+
+	multiplier = 1 << FRAC_BITS;
+	dec_multiple = div_u64(pll_freq * multiplier, divider);
+	dec = div_u64_rem(dec_multiple, multiplier, &frac);
+
+	if (pll_freq <= 1900000000UL)
+		config->pll_prop_gain_rate = 8;
+	else if (pll_freq <= 3000000000UL)
+		config->pll_prop_gain_rate = 10;
+	else
+		config->pll_prop_gain_rate = 12;
+	if (pll_freq < 1100000000UL)
+		config->pll_clock_inverters = 8;
+	else
+		config->pll_clock_inverters = 0;
+
+	config->decimal_div_start = dec;
+	config->frac_div_start = frac;
+}
+
+#define SSC_CENTER		BIT(0)
+#define SSC_EN			BIT(1)
+
+static void dsi_pll_calc_ssc(struct dsi_pll_10nm *pll, struct dsi_pll_config *config)
+{
+	u32 ssc_per;
+	u32 ssc_mod;
+	u64 ssc_step_size;
+	u64 frac;
+
+	if (!config->enable_ssc) {
+		DBG("SSC not enabled\n");
+		return;
+	}
+
+	ssc_per = DIV_ROUND_CLOSEST(VCO_REF_CLK_RATE, config->ssc_freq) / 2 - 1;
+	ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1);
+	ssc_per -= ssc_mod;
+
+	frac = config->frac_div_start;
+	ssc_step_size = config->decimal_div_start;
+	ssc_step_size *= (1 << FRAC_BITS);
+	ssc_step_size += frac;
+	ssc_step_size *= config->ssc_offset;
+	ssc_step_size *= (config->ssc_adj_per + 1);
+	ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1));
+	ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000);
+
+	config->ssc_div_per = ssc_per;
+	config->ssc_stepsize = ssc_step_size;
+
+	pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n",
+		 config->decimal_div_start, frac, FRAC_BITS);
+	pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n",
+		 ssc_per, (u32)ssc_step_size, config->ssc_adj_per);
+}
+
+static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll, struct dsi_pll_config *config)
+{
+	void __iomem *base = pll->phy->pll_base;
+
+	if (config->enable_ssc) {
+		pr_debug("SSC is enabled\n");
+
+		dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_LOW_1,
+			      config->ssc_stepsize & 0xff);
+		dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_HIGH_1,
+			      config->ssc_stepsize >> 8);
+		dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_LOW_1,
+			      config->ssc_div_per & 0xff);
+		dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_HIGH_1,
+			      config->ssc_div_per >> 8);
+		dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_LOW_1,
+			      config->ssc_adj_per & 0xff);
+		dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_HIGH_1,
+			      config->ssc_adj_per >> 8);
+		dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_SSC_CONTROL,
+			      SSC_EN | (config->ssc_center ? SSC_CENTER : 0));
+	}
+}
+
+static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll)
+{
+	void __iomem *base = pll->phy->pll_base;
+
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_ONE, 0x80);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_DSM_DIVIDER, 0x00);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE,
+		      0xba);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE,
+		      0x0c);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_OUTDIV, 0x00);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CORE_OVERRIDE, 0x00);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO,
+		      0x08);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x08);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_BAND_SET_RATE_1, 0xc0);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1,
+		      0xfa);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1,
+		      0x4c);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PFILT, 0x29);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_IFILT, 0x3f);
+}
+
+static void dsi_pll_commit(struct dsi_pll_10nm *pll, struct dsi_pll_config *config)
+{
+	void __iomem *base = pll->phy->pll_base;
+
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1,
+		      config->decimal_div_start);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1,
+		      config->frac_div_start & 0xff);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1,
+		      (config->frac_div_start & 0xff00) >> 8);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1,
+		      (config->frac_div_start & 0x30000) >> 16);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCKDET_RATE_1, 64);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_DELAY, 0x06);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CMODE, 0x10);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CLOCK_INVERTERS,
+		      config->pll_clock_inverters);
+}
+
+static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long parent_rate)
+{
+	struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
+	struct dsi_pll_config config;
+
+	DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_10nm->phy->id, rate,
+	    parent_rate);
+
+	pll_10nm->vco_current_rate = rate;
+
+	dsi_pll_setup_config(&config);
+
+	dsi_pll_calc_dec_frac(pll_10nm, &config);
+
+	dsi_pll_calc_ssc(pll_10nm, &config);
+
+	dsi_pll_commit(pll_10nm, &config);
+
+	dsi_pll_config_hzindep_reg(pll_10nm);
+
+	dsi_pll_ssc_commit(pll_10nm, &config);
+
+	/* flush, ensure all register writes are done*/
+	wmb();
+
+	return 0;
+}
+
+static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll)
+{
+	struct device *dev = &pll->phy->pdev->dev;
+	int rc;
+	u32 status = 0;
+	u32 const delay_us = 100;
+	u32 const timeout_us = 5000;
+
+	rc = readl_poll_timeout_atomic(pll->phy->pll_base +
+				       REG_DSI_10nm_PHY_PLL_COMMON_STATUS_ONE,
+				       status,
+				       ((status & BIT(0)) > 0),
+				       delay_us,
+				       timeout_us);
+	if (rc)
+		DRM_DEV_ERROR(dev, "DSI PLL(%d) lock failed, status=0x%08x\n",
+			      pll->phy->id, status);
+
+	return rc;
+}
+
+static void dsi_pll_disable_pll_bias(struct dsi_pll_10nm *pll)
+{
+	u32 data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0);
+
+	dsi_phy_write(pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0);
+	dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0,
+		      data & ~BIT(5));
+	ndelay(250);
+}
+
+static void dsi_pll_enable_pll_bias(struct dsi_pll_10nm *pll)
+{
+	u32 data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0);
+
+	dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0,
+		      data | BIT(5));
+	dsi_phy_write(pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0xc0);
+	ndelay(250);
+}
+
+static void dsi_pll_disable_global_clk(struct dsi_pll_10nm *pll)
+{
+	u32 data;
+
+	data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
+	dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1,
+		      data & ~BIT(5));
+}
+
+static void dsi_pll_enable_global_clk(struct dsi_pll_10nm *pll)
+{
+	u32 data;
+
+	data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
+	dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1,
+		      data | BIT(5));
+}
+
+static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw)
+{
+	struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
+	struct device *dev = &pll_10nm->phy->pdev->dev;
+	int rc;
+
+	dsi_pll_enable_pll_bias(pll_10nm);
+	if (pll_10nm->slave)
+		dsi_pll_enable_pll_bias(pll_10nm->slave);
+
+	rc = dsi_pll_10nm_vco_set_rate(hw,pll_10nm->vco_current_rate, 0);
+	if (rc) {
+		DRM_DEV_ERROR(dev, "vco_set_rate failed, rc=%d\n", rc);
+		return rc;
+	}
+
+	/* Start PLL */
+	dsi_phy_write(pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL,
+		      0x01);
+
+	/*
+	 * ensure all PLL configurations are written prior to checking
+	 * for PLL lock.
+	 */
+	wmb();
+
+	/* Check for PLL lock */
+	rc = dsi_pll_10nm_lock_status(pll_10nm);
+	if (rc) {
+		DRM_DEV_ERROR(dev, "PLL(%d) lock failed\n", pll_10nm->phy->id);
+		goto error;
+	}
+
+	pll_10nm->phy->pll_on = true;
+
+	dsi_pll_enable_global_clk(pll_10nm);
+	if (pll_10nm->slave)
+		dsi_pll_enable_global_clk(pll_10nm->slave);
+
+	dsi_phy_write(pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL,
+		      0x01);
+	if (pll_10nm->slave)
+		dsi_phy_write(pll_10nm->slave->phy->base +
+			      REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0x01);
+
+error:
+	return rc;
+}
+
+static void dsi_pll_disable_sub(struct dsi_pll_10nm *pll)
+{
+	dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0);
+	dsi_pll_disable_pll_bias(pll);
+}
+
+static void dsi_pll_10nm_vco_unprepare(struct clk_hw *hw)
+{
+	struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
+
+	/*
+	 * To avoid any stray glitches while abruptly powering down the PLL
+	 * make sure to gate the clock using the clock enable bit before
+	 * powering down the PLL
+	 */
+	dsi_pll_disable_global_clk(pll_10nm);
+	dsi_phy_write(pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, 0);
+	dsi_pll_disable_sub(pll_10nm);
+	if (pll_10nm->slave) {
+		dsi_pll_disable_global_clk(pll_10nm->slave);
+		dsi_pll_disable_sub(pll_10nm->slave);
+	}
+	/* flush, ensure all register writes are done */
+	wmb();
+	pll_10nm->phy->pll_on = false;
+}
+
+static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw,
+						  unsigned long parent_rate)
+{
+	struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
+	void __iomem *base = pll_10nm->phy->pll_base;
+	u64 ref_clk = VCO_REF_CLK_RATE;
+	u64 vco_rate = 0x0;
+	u64 multiplier;
+	u32 frac;
+	u32 dec;
+	u64 pll_freq, tmp64;
+
+	dec = dsi_phy_read(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1);
+	dec &= 0xff;
+
+	frac = dsi_phy_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1);
+	frac |= ((dsi_phy_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1) &
+		  0xff) << 8);
+	frac |= ((dsi_phy_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1) &
+		  0x3) << 16);
+
+	/*
+	 * TODO:
+	 *	1. Assumes prescaler is disabled
+	 */
+	multiplier = 1 << FRAC_BITS;
+	pll_freq = dec * (ref_clk * 2);
+	tmp64 = (ref_clk * 2 * frac);
+	pll_freq += div_u64(tmp64, multiplier);
+
+	vco_rate = pll_freq;
+	pll_10nm->vco_current_rate = vco_rate;
+
+	DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x",
+	    pll_10nm->phy->id, (unsigned long)vco_rate, dec, frac);
+
+	return (unsigned long)vco_rate;
+}
+
+static long dsi_pll_10nm_clk_round_rate(struct clk_hw *hw,
+		unsigned long rate, unsigned long *parent_rate)
+{
+	struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw);
+
+	if      (rate < pll_10nm->phy->cfg->min_pll_rate)
+		return  pll_10nm->phy->cfg->min_pll_rate;
+	else if (rate > pll_10nm->phy->cfg->max_pll_rate)
+		return  pll_10nm->phy->cfg->max_pll_rate;
+	else
+		return rate;
+}
+
+static const struct clk_ops clk_ops_dsi_pll_10nm_vco = {
+	.round_rate = dsi_pll_10nm_clk_round_rate,
+	.set_rate = dsi_pll_10nm_vco_set_rate,
+	.recalc_rate = dsi_pll_10nm_vco_recalc_rate,
+	.prepare = dsi_pll_10nm_vco_prepare,
+	.unprepare = dsi_pll_10nm_vco_unprepare,
+};
+
+/*
+ * PLL Callbacks
+ */
+
+static void dsi_10nm_pll_save_state(struct msm_dsi_phy *phy)
+{
+	struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw);
+	struct pll_10nm_cached_state *cached = &pll_10nm->cached_state;
+	void __iomem *phy_base = pll_10nm->phy->base;
+	u32 cmn_clk_cfg0, cmn_clk_cfg1;
+
+	cached->pll_out_div = dsi_phy_read(pll_10nm->phy->pll_base +
+			REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE);
+	cached->pll_out_div &= 0x3;
+
+	cmn_clk_cfg0 = dsi_phy_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0);
+	cached->bit_clk_div = cmn_clk_cfg0 & 0xf;
+	cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4;
+
+	cmn_clk_cfg1 = dsi_phy_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
+	cached->pll_mux = cmn_clk_cfg1 & 0x3;
+
+	DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x",
+	    pll_10nm->phy->id, cached->pll_out_div, cached->bit_clk_div,
+	    cached->pix_clk_div, cached->pll_mux);
+}
+
+static int dsi_10nm_pll_restore_state(struct msm_dsi_phy *phy)
+{
+	struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw);
+	struct pll_10nm_cached_state *cached = &pll_10nm->cached_state;
+	void __iomem *phy_base = pll_10nm->phy->base;
+	u32 val;
+	int ret;
+
+	val = dsi_phy_read(pll_10nm->phy->pll_base + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE);
+	val &= ~0x3;
+	val |= cached->pll_out_div;
+	dsi_phy_write(pll_10nm->phy->pll_base + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, val);
+
+	dsi_phy_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0,
+		      cached->bit_clk_div | (cached->pix_clk_div << 4));
+
+	val = dsi_phy_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1);
+	val &= ~0x3;
+	val |= cached->pll_mux;
+	dsi_phy_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, val);
+
+	ret = dsi_pll_10nm_vco_set_rate(phy->vco_hw,
+			pll_10nm->vco_current_rate,
+			VCO_REF_CLK_RATE);
+	if (ret) {
+		DRM_DEV_ERROR(&pll_10nm->phy->pdev->dev,
+			"restore vco rate failed. ret=%d\n", ret);
+		return ret;
+	}
+
+	DBG("DSI PLL%d", pll_10nm->phy->id);
+
+	return 0;
+}
+
+static int dsi_10nm_set_usecase(struct msm_dsi_phy *phy)
+{
+	struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw);
+	void __iomem *base = phy->base;
+	u32 data = 0x0;	/* internal PLL */
+
+	DBG("DSI PLL%d", pll_10nm->phy->id);
+
+	switch (phy->usecase) {
+	case MSM_DSI_PHY_STANDALONE:
+		break;
+	case MSM_DSI_PHY_MASTER:
+		pll_10nm->slave = pll_10nm_list[(pll_10nm->phy->id + 1) % DSI_MAX];
+		break;
+	case MSM_DSI_PHY_SLAVE:
+		data = 0x1; /* external PLL */
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* set PLL src */
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, (data << 2));
+
+	return 0;
+}
+
+/*
+ * The post dividers and mux clocks are created using the standard divider and
+ * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux
+ * state to follow the master PLL's divider/mux state. Therefore, we don't
+ * require special clock ops that also configure the slave PLL registers
+ */
+static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **provided_clocks)
+{
+	char clk_name[32];
+	struct clk_init_data vco_init = {
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "ref",
+		},
+		.num_parents = 1,
+		.name = clk_name,
+		.flags = CLK_IGNORE_UNUSED,
+		.ops = &clk_ops_dsi_pll_10nm_vco,
+	};
+	struct device *dev = &pll_10nm->phy->pdev->dev;
+	struct clk_hw *hw, *pll_out_div, *pll_bit, *pll_by_2_bit;
+	struct clk_hw *pll_post_out_div, *pclk_mux;
+	int ret;
+
+	DBG("DSI%d", pll_10nm->phy->id);
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dvco_clk", pll_10nm->phy->id);
+	pll_10nm->clk_hw.init = &vco_init;
+
+	ret = devm_clk_hw_register(dev, &pll_10nm->clk_hw);
+	if (ret)
+		return ret;
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_out_div_clk", pll_10nm->phy->id);
+
+	pll_out_div = devm_clk_hw_register_divider_parent_hw(dev, clk_name,
+			&pll_10nm->clk_hw, CLK_SET_RATE_PARENT,
+			pll_10nm->phy->pll_base +
+				REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE,
+			0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
+	if (IS_ERR(pll_out_div)) {
+		ret = PTR_ERR(pll_out_div);
+		goto fail;
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_bit_clk", pll_10nm->phy->id);
+
+	/* BIT CLK: DIV_CTRL_3_0 */
+	pll_bit = devm_clk_hw_register_divider_parent_hw(dev, clk_name,
+			pll_out_div, CLK_SET_RATE_PARENT,
+			pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG0,
+			0, 4, CLK_DIVIDER_ONE_BASED, &pll_10nm->postdiv_lock);
+	if (IS_ERR(pll_bit)) {
+		ret = PTR_ERR(pll_bit);
+		goto fail;
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%d_phy_pll_out_byteclk", pll_10nm->phy->id);
+
+	/* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */
+	hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk_name,
+			pll_bit, CLK_SET_RATE_PARENT, 1, 8);
+	if (IS_ERR(hw)) {
+		ret = PTR_ERR(hw);
+		goto fail;
+	}
+
+	provided_clocks[DSI_BYTE_PLL_CLK] = hw;
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_by_2_bit_clk", pll_10nm->phy->id);
+
+	pll_by_2_bit = devm_clk_hw_register_fixed_factor_parent_hw(dev,
+			clk_name, pll_bit, 0, 1, 2);
+	if (IS_ERR(pll_by_2_bit)) {
+		ret = PTR_ERR(pll_by_2_bit);
+		goto fail;
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_post_out_div_clk", pll_10nm->phy->id);
+
+	pll_post_out_div = devm_clk_hw_register_fixed_factor_parent_hw(dev,
+			clk_name, pll_out_div, 0, 1, 4);
+	if (IS_ERR(pll_post_out_div)) {
+		ret = PTR_ERR(pll_post_out_div);
+		goto fail;
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%d_pclk_mux", pll_10nm->phy->id);
+
+	pclk_mux = devm_clk_hw_register_mux_parent_hws(dev, clk_name,
+			((const struct clk_hw *[]){
+				pll_bit,
+				pll_by_2_bit,
+				pll_out_div,
+				pll_post_out_div,
+			}), 4, 0, pll_10nm->phy->base +
+				REG_DSI_10nm_PHY_CMN_CLK_CFG1, 0, 2, 0, NULL);
+	if (IS_ERR(pclk_mux)) {
+		ret = PTR_ERR(pclk_mux);
+		goto fail;
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%d_phy_pll_out_dsiclk", pll_10nm->phy->id);
+
+	/* PIX CLK DIV : DIV_CTRL_7_4*/
+	hw = devm_clk_hw_register_divider_parent_hw(dev, clk_name, pclk_mux,
+			0, pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG0,
+			4, 4, CLK_DIVIDER_ONE_BASED, &pll_10nm->postdiv_lock);
+	if (IS_ERR(hw)) {
+		ret = PTR_ERR(hw);
+		goto fail;
+	}
+
+	provided_clocks[DSI_PIXEL_PLL_CLK] = hw;
+
+	return 0;
+
+fail:
+
+	return ret;
+}
+
+static int dsi_pll_10nm_init(struct msm_dsi_phy *phy)
+{
+	struct platform_device *pdev = phy->pdev;
+	struct dsi_pll_10nm *pll_10nm;
+	int ret;
+
+	pll_10nm = devm_kzalloc(&pdev->dev, sizeof(*pll_10nm), GFP_KERNEL);
+	if (!pll_10nm)
+		return -ENOMEM;
+
+	DBG("DSI PLL%d", phy->id);
+
+	pll_10nm_list[phy->id] = pll_10nm;
+
+	spin_lock_init(&pll_10nm->postdiv_lock);
+
+	pll_10nm->phy = phy;
+
+	ret = pll_10nm_register(pll_10nm, phy->provided_clocks->hws);
+	if (ret) {
+		DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
+		return ret;
+	}
+
+	phy->vco_hw = &pll_10nm->clk_hw;
+
+	/* TODO: Remove this when we have proper display handover support */
+	msm_dsi_phy_pll_save_state(phy);
+
+	return 0;
+}
+
+static int dsi_phy_hw_v3_0_is_pll_on(struct msm_dsi_phy *phy)
+{
+	void __iomem *base = phy->base;
+	u32 data = 0;
+
+	data = dsi_phy_read(base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL);
+	mb(); /* make sure read happened */
+
+	return (data & BIT(0));
+}
+
+static void dsi_phy_hw_v3_0_config_lpcdrx(struct msm_dsi_phy *phy, bool enable)
+{
+	void __iomem *lane_base = phy->lane_base;
+	int phy_lane_0 = 0;	/* TODO: Support all lane swap configs */
+
+	/*
+	 * LPRX and CDRX need to enabled only for physical data lane
+	 * corresponding to the logical data lane 0
+	 */
+	if (enable)
+		dsi_phy_write(lane_base +
+			      REG_DSI_10nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0x3);
+	else
+		dsi_phy_write(lane_base +
+			      REG_DSI_10nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0);
+}
+
+static void dsi_phy_hw_v3_0_lane_settings(struct msm_dsi_phy *phy)
+{
+	int i;
+	u8 tx_dctrl[] = { 0x00, 0x00, 0x00, 0x04, 0x01 };
+	void __iomem *lane_base = phy->lane_base;
+	struct dsi_phy_10nm_tuning_cfg *tuning_cfg = phy->tuning_cfg;
+
+	if (phy->cfg->quirks & DSI_PHY_10NM_QUIRK_OLD_TIMINGS)
+		tx_dctrl[3] = 0x02;
+
+	/* Strength ctrl settings */
+	for (i = 0; i < 5; i++) {
+		dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_LPTX_STR_CTRL(i),
+			      0x55);
+		/*
+		 * Disable LPRX and CDRX for all lanes. And later on, it will
+		 * be only enabled for the physical data lane corresponding
+		 * to the logical data lane 0
+		 */
+		dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_LPRX_CTRL(i), 0);
+		dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_PIN_SWAP(i), 0x0);
+		dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_HSTX_STR_CTRL(i),
+			      0x88);
+	}
+
+	dsi_phy_hw_v3_0_config_lpcdrx(phy, true);
+
+	/* other settings */
+	for (i = 0; i < 5; i++) {
+		dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG0(i), 0x0);
+		dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG1(i), 0x0);
+		dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG2(i), 0x0);
+		dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_CFG3(i),
+			      i == 4 ? 0x80 : 0x0);
+
+		/* platform specific dsi phy drive strength adjustment */
+		dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_OFFSET_TOP_CTRL(i),
+				tuning_cfg->rescode_offset_top[i]);
+		dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_OFFSET_BOT_CTRL(i),
+				tuning_cfg->rescode_offset_bot[i]);
+
+		dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(i),
+			      tx_dctrl[i]);
+	}
+
+	if (!(phy->cfg->quirks & DSI_PHY_10NM_QUIRK_OLD_TIMINGS)) {
+		/* Toggle BIT 0 to release freeze I/0 */
+		dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3), 0x05);
+		dsi_phy_write(lane_base + REG_DSI_10nm_PHY_LN_TX_DCTRL(3), 0x04);
+	}
+}
+
+static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy,
+			       struct msm_dsi_phy_clk_request *clk_req)
+{
+	int ret;
+	u32 status;
+	u32 const delay_us = 5;
+	u32 const timeout_us = 1000;
+	struct msm_dsi_dphy_timing *timing = &phy->timing;
+	void __iomem *base = phy->base;
+	struct dsi_phy_10nm_tuning_cfg *tuning_cfg = phy->tuning_cfg;
+	u32 data;
+
+	DBG("");
+
+	if (msm_dsi_dphy_timing_calc_v3(timing, clk_req)) {
+		DRM_DEV_ERROR(&phy->pdev->dev,
+			"%s: D-PHY timing calculation failed\n", __func__);
+		return -EINVAL;
+	}
+
+	if (dsi_phy_hw_v3_0_is_pll_on(phy))
+		pr_warn("PLL turned on before configuring PHY\n");
+
+	/* wait for REFGEN READY */
+	ret = readl_poll_timeout_atomic(base + REG_DSI_10nm_PHY_CMN_PHY_STATUS,
+					status, (status & BIT(0)),
+					delay_us, timeout_us);
+	if (ret) {
+		pr_err("Ref gen not ready. Aborting\n");
+		return -EINVAL;
+	}
+
+	/* de-assert digital and pll power down */
+	data = BIT(6) | BIT(5);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, data);
+
+	/* Assert PLL core reset */
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, 0x00);
+
+	/* turn off resync FIFO */
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0x00);
+
+	/* Select MS1 byte-clk */
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_GLBL_CTRL, 0x10);
+
+	/* Enable LDO with platform specific drive level/amplitude adjustment */
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_VREG_CTRL,
+		      tuning_cfg->vreg_ctrl);
+
+	/* Configure PHY lane swap (TODO: we need to calculate this) */
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CFG0, 0x21);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CFG1, 0x84);
+
+	/* DSI PHY timings */
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_0,
+		      timing->hs_halfbyte_en);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_1,
+		      timing->clk_zero);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_2,
+		      timing->clk_prepare);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_3,
+		      timing->clk_trail);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_4,
+		      timing->hs_exit);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_5,
+		      timing->hs_zero);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_6,
+		      timing->hs_prepare);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_7,
+		      timing->hs_trail);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_8,
+		      timing->hs_rqst);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_9,
+		      timing->ta_go | (timing->ta_sure << 3));
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_10,
+		      timing->ta_get);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_TIMING_CTRL_11,
+		      0x00);
+
+	/* Remove power down from all blocks */
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, 0x7f);
+
+	/* power up lanes */
+	data = dsi_phy_read(base + REG_DSI_10nm_PHY_CMN_CTRL_0);
+
+	/* TODO: only power up lanes that are used */
+	data |= 0x1F;
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, data);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CTRL0, 0x1F);
+
+	/* Select full-rate mode */
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_2, 0x40);
+
+	ret = dsi_10nm_set_usecase(phy);
+	if (ret) {
+		DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	/* DSI lane settings */
+	dsi_phy_hw_v3_0_lane_settings(phy);
+
+	DBG("DSI%d PHY enabled", phy->id);
+
+	return 0;
+}
+
+static void dsi_10nm_phy_disable(struct msm_dsi_phy *phy)
+{
+	void __iomem *base = phy->base;
+	u32 data;
+
+	DBG("");
+
+	if (dsi_phy_hw_v3_0_is_pll_on(phy))
+		pr_warn("Turning OFF PHY while PLL is on\n");
+
+	dsi_phy_hw_v3_0_config_lpcdrx(phy, false);
+	data = dsi_phy_read(base + REG_DSI_10nm_PHY_CMN_CTRL_0);
+
+	/* disable all lanes */
+	data &= ~0x1F;
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, data);
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_LANE_CTRL0, 0);
+
+	/* Turn off all PHY blocks */
+	dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_0, 0x00);
+	/* make sure phy is turned off */
+	wmb();
+
+	DBG("DSI%d PHY disabled", phy->id);
+}
+
+static int dsi_10nm_phy_parse_dt(struct msm_dsi_phy *phy)
+{
+	struct device *dev = &phy->pdev->dev;
+	struct dsi_phy_10nm_tuning_cfg *tuning_cfg;
+	s8 offset_top[DSI_LANE_MAX] = { 0 }; /* No offset */
+	s8 offset_bot[DSI_LANE_MAX] = { 0 }; /* No offset */
+	u32 ldo_level = 400; /* 400mV */
+	u8 level;
+	int ret, i;
+
+	tuning_cfg = devm_kzalloc(dev, sizeof(*tuning_cfg), GFP_KERNEL);
+	if (!tuning_cfg)
+		return -ENOMEM;
+
+	/* Drive strength adjustment parameters */
+	ret = of_property_read_u8_array(dev->of_node, "qcom,phy-rescode-offset-top",
+					offset_top, DSI_LANE_MAX);
+	if (ret && ret != -EINVAL) {
+		DRM_DEV_ERROR(dev, "failed to parse qcom,phy-rescode-offset-top, %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < DSI_LANE_MAX; i++) {
+		if (offset_top[i] < -32 || offset_top[i] > 31) {
+			DRM_DEV_ERROR(dev,
+				"qcom,phy-rescode-offset-top value %d is not in range [-32..31]\n",
+				offset_top[i]);
+			return -EINVAL;
+		}
+		tuning_cfg->rescode_offset_top[i] = 0x3f & offset_top[i];
+	}
+
+	ret = of_property_read_u8_array(dev->of_node, "qcom,phy-rescode-offset-bot",
+					offset_bot, DSI_LANE_MAX);
+	if (ret && ret != -EINVAL) {
+		DRM_DEV_ERROR(dev, "failed to parse qcom,phy-rescode-offset-bot, %d\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < DSI_LANE_MAX; i++) {
+		if (offset_bot[i] < -32 || offset_bot[i] > 31) {
+			DRM_DEV_ERROR(dev,
+				"qcom,phy-rescode-offset-bot value %d is not in range [-32..31]\n",
+				offset_bot[i]);
+			return -EINVAL;
+		}
+		tuning_cfg->rescode_offset_bot[i] = 0x3f & offset_bot[i];
+	}
+
+	/* Drive level/amplitude adjustment parameters */
+	ret = of_property_read_u32(dev->of_node, "qcom,phy-drive-ldo-level", &ldo_level);
+	if (ret && ret != -EINVAL) {
+		DRM_DEV_ERROR(dev, "failed to parse qcom,phy-drive-ldo-level, %d\n", ret);
+		return ret;
+	}
+
+	switch (ldo_level) {
+	case 375:
+		level = 0;
+		break;
+	case 400:
+		level = 1;
+		break;
+	case 425:
+		level = 2;
+		break;
+	case 450:
+		level = 3;
+		break;
+	case 475:
+		level = 4;
+		break;
+	case 500:
+		level = 5;
+		break;
+	default:
+		DRM_DEV_ERROR(dev, "qcom,phy-drive-ldo-level %d is not supported\n", ldo_level);
+		return -EINVAL;
+	}
+	tuning_cfg->vreg_ctrl = 0x58 | (0x7 & level);
+
+	phy->tuning_cfg = tuning_cfg;
+
+	return 0;
+}
+
+static const struct regulator_bulk_data dsi_phy_10nm_regulators[] = {
+	{ .supply = "vdds", .init_load_uA = 36000 },
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs = {
+	.has_phy_lane = true,
+	.regulator_data = dsi_phy_10nm_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_10nm_regulators),
+	.ops = {
+		.enable = dsi_10nm_phy_enable,
+		.disable = dsi_10nm_phy_disable,
+		.pll_init = dsi_pll_10nm_init,
+		.save_pll_state = dsi_10nm_pll_save_state,
+		.restore_pll_state = dsi_10nm_pll_restore_state,
+		.parse_dt_properties = dsi_10nm_phy_parse_dt,
+	},
+	.min_pll_rate = 1000000000UL,
+	.max_pll_rate = 3500000000UL,
+	.io_start = { 0xae94400, 0xae96400 },
+	.num_dsi_phy = 2,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs = {
+	.has_phy_lane = true,
+	.regulator_data = dsi_phy_10nm_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_10nm_regulators),
+	.ops = {
+		.enable = dsi_10nm_phy_enable,
+		.disable = dsi_10nm_phy_disable,
+		.pll_init = dsi_pll_10nm_init,
+		.save_pll_state = dsi_10nm_pll_save_state,
+		.restore_pll_state = dsi_10nm_pll_restore_state,
+		.parse_dt_properties = dsi_10nm_phy_parse_dt,
+	},
+	.min_pll_rate = 1000000000UL,
+	.max_pll_rate = 3500000000UL,
+	.io_start = { 0xc994400, 0xc996400 },
+	.num_dsi_phy = 2,
+	.quirks = DSI_PHY_10NM_QUIRK_OLD_TIMINGS,
+};
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy_14nm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy_14nm.c
@@ -0,0 +1,1101 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+
+#include "dsi_phy.h"
+#include "dsi.xml.h"
+#include "dsi_phy_14nm.xml.h"
+
+#define PHY_14NM_CKLN_IDX	4
+
+/*
+ * DSI PLL 14nm - clock diagram (eg: DSI0):
+ *
+ *         dsi0n1_postdiv_clk
+ *                         |
+ *                         |
+ *                 +----+  |  +----+
+ *  dsi0vco_clk ---| n1 |--o--| /8 |-- dsi0pllbyte
+ *                 +----+  |  +----+
+ *                         |           dsi0n1_postdivby2_clk
+ *                         |   +----+  |
+ *                         o---| /2 |--o--|\
+ *                         |   +----+     | \   +----+
+ *                         |              |  |--| n2 |-- dsi0pll
+ *                         o--------------| /   +----+
+ *                                        |/
+ */
+
+#define POLL_MAX_READS			15
+#define POLL_TIMEOUT_US			1000
+
+#define VCO_REF_CLK_RATE		19200000
+#define VCO_MIN_RATE			1300000000UL
+#define VCO_MAX_RATE			2600000000UL
+
+struct dsi_pll_config {
+	u64 vco_current_rate;
+
+	u32 ssc_en;	/* SSC enable/disable */
+
+	/* fixed params */
+	u32 plllock_cnt;
+	u32 ssc_center;
+	u32 ssc_adj_period;
+	u32 ssc_spread;
+	u32 ssc_freq;
+
+	/* calculated */
+	u32 dec_start;
+	u32 div_frac_start;
+	u32 ssc_period;
+	u32 ssc_step_size;
+	u32 plllock_cmp;
+	u32 pll_vco_div_ref;
+	u32 pll_vco_count;
+	u32 pll_kvco_div_ref;
+	u32 pll_kvco_count;
+};
+
+struct pll_14nm_cached_state {
+	unsigned long vco_rate;
+	u8 n2postdiv;
+	u8 n1postdiv;
+};
+
+struct dsi_pll_14nm {
+	struct clk_hw clk_hw;
+
+	struct msm_dsi_phy *phy;
+
+	/* protects REG_DSI_14nm_PHY_CMN_CLK_CFG0 register */
+	spinlock_t postdiv_lock;
+
+	struct pll_14nm_cached_state cached_state;
+
+	struct dsi_pll_14nm *slave;
+};
+
+#define to_pll_14nm(x)	container_of(x, struct dsi_pll_14nm, clk_hw)
+
+/*
+ * Private struct for N1/N2 post-divider clocks. These clocks are similar to
+ * the generic clk_divider class of clocks. The only difference is that it
+ * also sets the slave DSI PLL's post-dividers if in bonded DSI mode
+ */
+struct dsi_pll_14nm_postdiv {
+	struct clk_hw hw;
+
+	/* divider params */
+	u8 shift;
+	u8 width;
+	u8 flags; /* same flags as used by clk_divider struct */
+
+	struct dsi_pll_14nm *pll;
+};
+
+#define to_pll_14nm_postdiv(_hw) container_of(_hw, struct dsi_pll_14nm_postdiv, hw)
+
+/*
+ * Global list of private DSI PLL struct pointers. We need this for bonded DSI
+ * mode, where the master PLL's clk_ops needs access the slave's private data
+ */
+static struct dsi_pll_14nm *pll_14nm_list[DSI_MAX];
+
+static bool pll_14nm_poll_for_ready(struct dsi_pll_14nm *pll_14nm,
+				    u32 nb_tries, u32 timeout_us)
+{
+	bool pll_locked = false, pll_ready = false;
+	void __iomem *base = pll_14nm->phy->pll_base;
+	u32 tries, val;
+
+	tries = nb_tries;
+	while (tries--) {
+		val = dsi_phy_read(base + REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS);
+		pll_locked = !!(val & BIT(5));
+
+		if (pll_locked)
+			break;
+
+		udelay(timeout_us);
+	}
+
+	if (!pll_locked)
+		goto out;
+
+	tries = nb_tries;
+	while (tries--) {
+		val = dsi_phy_read(base + REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS);
+		pll_ready = !!(val & BIT(0));
+
+		if (pll_ready)
+			break;
+
+		udelay(timeout_us);
+	}
+
+out:
+	DBG("DSI PLL is %slocked, %sready", pll_locked ? "" : "*not* ", pll_ready ? "" : "*not* ");
+
+	return pll_locked && pll_ready;
+}
+
+static void dsi_pll_14nm_config_init(struct dsi_pll_config *pconf)
+{
+	/* fixed input */
+	pconf->plllock_cnt = 1;
+
+	/*
+	 * SSC is enabled by default. We might need DT props for configuring
+	 * some SSC params like PPM and center/down spread etc.
+	 */
+	pconf->ssc_en = 1;
+	pconf->ssc_center = 0;		/* down spread by default */
+	pconf->ssc_spread = 5;		/* PPM / 1000 */
+	pconf->ssc_freq = 31500;	/* default recommended */
+	pconf->ssc_adj_period = 37;
+}
+
+#define CEIL(x, y)		(((x) + ((y) - 1)) / (y))
+
+static void pll_14nm_ssc_calc(struct dsi_pll_14nm *pll, struct dsi_pll_config *pconf)
+{
+	u32 period, ssc_period;
+	u32 ref, rem;
+	u64 step_size;
+
+	DBG("vco=%lld ref=%d", pconf->vco_current_rate, VCO_REF_CLK_RATE);
+
+	ssc_period = pconf->ssc_freq / 500;
+	period = (u32)VCO_REF_CLK_RATE / 1000;
+	ssc_period  = CEIL(period, ssc_period);
+	ssc_period -= 1;
+	pconf->ssc_period = ssc_period;
+
+	DBG("ssc freq=%d spread=%d period=%d", pconf->ssc_freq,
+	    pconf->ssc_spread, pconf->ssc_period);
+
+	step_size = (u32)pconf->vco_current_rate;
+	ref = VCO_REF_CLK_RATE;
+	ref /= 1000;
+	step_size = div_u64(step_size, ref);
+	step_size <<= 20;
+	step_size = div_u64(step_size, 1000);
+	step_size *= pconf->ssc_spread;
+	step_size = div_u64(step_size, 1000);
+	step_size *= (pconf->ssc_adj_period + 1);
+
+	rem = 0;
+	step_size = div_u64_rem(step_size, ssc_period + 1, &rem);
+	if (rem)
+		step_size++;
+
+	DBG("step_size=%lld", step_size);
+
+	step_size &= 0x0ffff;	/* take lower 16 bits */
+
+	pconf->ssc_step_size = step_size;
+}
+
+static void pll_14nm_dec_frac_calc(struct dsi_pll_14nm *pll, struct dsi_pll_config *pconf)
+{
+	u64 multiplier = BIT(20);
+	u64 dec_start_multiple, dec_start, pll_comp_val;
+	u32 duration, div_frac_start;
+	u64 vco_clk_rate = pconf->vco_current_rate;
+	u64 fref = VCO_REF_CLK_RATE;
+
+	DBG("vco_clk_rate=%lld ref_clk_rate=%lld", vco_clk_rate, fref);
+
+	dec_start_multiple = div_u64(vco_clk_rate * multiplier, fref);
+	dec_start = div_u64_rem(dec_start_multiple, multiplier, &div_frac_start);
+
+	pconf->dec_start = (u32)dec_start;
+	pconf->div_frac_start = div_frac_start;
+
+	if (pconf->plllock_cnt == 0)
+		duration = 1024;
+	else if (pconf->plllock_cnt == 1)
+		duration = 256;
+	else if (pconf->plllock_cnt == 2)
+		duration = 128;
+	else
+		duration = 32;
+
+	pll_comp_val = duration * dec_start_multiple;
+	pll_comp_val = div_u64(pll_comp_val, multiplier);
+	do_div(pll_comp_val, 10);
+
+	pconf->plllock_cmp = (u32)pll_comp_val;
+}
+
+static u32 pll_14nm_kvco_slop(u32 vrate)
+{
+	u32 slop = 0;
+
+	if (vrate > VCO_MIN_RATE && vrate <= 1800000000UL)
+		slop =  600;
+	else if (vrate > 1800000000UL && vrate < 2300000000UL)
+		slop = 400;
+	else if (vrate > 2300000000UL && vrate < VCO_MAX_RATE)
+		slop = 280;
+
+	return slop;
+}
+
+static void pll_14nm_calc_vco_count(struct dsi_pll_14nm *pll, struct dsi_pll_config *pconf)
+{
+	u64 vco_clk_rate = pconf->vco_current_rate;
+	u64 fref = VCO_REF_CLK_RATE;
+	u32 vco_measure_time = 5;
+	u32 kvco_measure_time = 5;
+	u64 data;
+	u32 cnt;
+
+	data = fref * vco_measure_time;
+	do_div(data, 1000000);
+	data &= 0x03ff;	/* 10 bits */
+	data -= 2;
+	pconf->pll_vco_div_ref = data;
+
+	data = div_u64(vco_clk_rate, 1000000);	/* unit is Mhz */
+	data *= vco_measure_time;
+	do_div(data, 10);
+	pconf->pll_vco_count = data;
+
+	data = fref * kvco_measure_time;
+	do_div(data, 1000000);
+	data &= 0x03ff;	/* 10 bits */
+	data -= 1;
+	pconf->pll_kvco_div_ref = data;
+
+	cnt = pll_14nm_kvco_slop(vco_clk_rate);
+	cnt *= 2;
+	cnt /= 100;
+	cnt *= kvco_measure_time;
+	pconf->pll_kvco_count = cnt;
+}
+
+static void pll_db_commit_ssc(struct dsi_pll_14nm *pll, struct dsi_pll_config *pconf)
+{
+	void __iomem *base = pll->phy->pll_base;
+	u8 data;
+
+	data = pconf->ssc_adj_period;
+	data &= 0x0ff;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER1, data);
+	data = (pconf->ssc_adj_period >> 8);
+	data &= 0x03;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER2, data);
+
+	data = pconf->ssc_period;
+	data &= 0x0ff;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SSC_PER1, data);
+	data = (pconf->ssc_period >> 8);
+	data &= 0x0ff;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SSC_PER2, data);
+
+	data = pconf->ssc_step_size;
+	data &= 0x0ff;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE1, data);
+	data = (pconf->ssc_step_size >> 8);
+	data &= 0x0ff;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE2, data);
+
+	data = (pconf->ssc_center & 0x01);
+	data <<= 1;
+	data |= 0x01; /* enable */
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SSC_EN_CENTER, data);
+
+	wmb();	/* make sure register committed */
+}
+
+static void pll_db_commit_common(struct dsi_pll_14nm *pll,
+				 struct dsi_pll_config *pconf)
+{
+	void __iomem *base = pll->phy->pll_base;
+	u8 data;
+
+	/* confgiure the non frequency dependent pll registers */
+	data = 0;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_SYSCLK_EN_RESET, data);
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_TXCLK_EN, 1);
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL, 48);
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL2, 4 << 3); /* bandgap_timer */
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL5, 5); /* pll_wakeup_timer */
+
+	data = pconf->pll_vco_div_ref & 0xff;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF1, data);
+	data = (pconf->pll_vco_div_ref >> 8) & 0x3;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF2, data);
+
+	data = pconf->pll_kvco_div_ref & 0xff;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF1, data);
+	data = (pconf->pll_kvco_div_ref >> 8) & 0x3;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF2, data);
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_MISC1, 16);
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_IE_TRIM, 4);
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_IP_TRIM, 4);
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_CP_SET_CUR, 1 << 3 | 1);
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICPCSET, 0 << 3 | 0);
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICPMSET, 0 << 3 | 0);
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICP_SET, 4 << 3 | 4);
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_LPF1, 1 << 4 | 11);
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_IPTAT_TRIM, 7);
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_CRCTRL, 1 << 4 | 2);
+}
+
+static void pll_14nm_software_reset(struct dsi_pll_14nm *pll_14nm)
+{
+	void __iomem *cmn_base = pll_14nm->phy->base;
+
+	/* de assert pll start and apply pll sw reset */
+
+	/* stop pll */
+	dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0);
+
+	/* pll sw reset */
+	dsi_phy_write_udelay(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x20, 10);
+	wmb();	/* make sure register committed */
+
+	dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0);
+	wmb();	/* make sure register committed */
+}
+
+static void pll_db_commit_14nm(struct dsi_pll_14nm *pll,
+			       struct dsi_pll_config *pconf)
+{
+	void __iomem *base = pll->phy->pll_base;
+	void __iomem *cmn_base = pll->phy->base;
+	u8 data;
+
+	DBG("DSI%d PLL", pll->phy->id);
+
+	dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_LDO_CNTRL, 0x3c);
+
+	pll_db_commit_common(pll, pconf);
+
+	pll_14nm_software_reset(pll);
+
+	/* Use the /2 path in Mux */
+	dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG1, 1);
+
+	data = 0xff; /* data, clk, pll normal operation */
+	dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_0, data);
+
+	/* configure the frequency dependent pll registers */
+	data = pconf->dec_start;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_DEC_START, data);
+
+	data = pconf->div_frac_start & 0xff;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1, data);
+	data = (pconf->div_frac_start >> 8) & 0xff;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2, data);
+	data = (pconf->div_frac_start >> 16) & 0xf;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3, data);
+
+	data = pconf->plllock_cmp & 0xff;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP1, data);
+
+	data = (pconf->plllock_cmp >> 8) & 0xff;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP2, data);
+
+	data = (pconf->plllock_cmp >> 16) & 0x3;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP3, data);
+
+	data = pconf->plllock_cnt << 1 | 0 << 3; /* plllock_rng */
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP_EN, data);
+
+	data = pconf->pll_vco_count & 0xff;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_VCO_COUNT1, data);
+	data = (pconf->pll_vco_count >> 8) & 0xff;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_VCO_COUNT2, data);
+
+	data = pconf->pll_kvco_count & 0xff;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT1, data);
+	data = (pconf->pll_kvco_count >> 8) & 0x3;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT2, data);
+
+	/*
+	 * High nibble configures the post divider internal to the VCO. It's
+	 * fixed to divide by 1 for now.
+	 *
+	 * 0: divided by 1
+	 * 1: divided by 2
+	 * 2: divided by 4
+	 * 3: divided by 8
+	 */
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_LPF2_POSTDIV, 0 << 4 | 3);
+
+	if (pconf->ssc_en)
+		pll_db_commit_ssc(pll, pconf);
+
+	wmb();	/* make sure register committed */
+}
+
+/*
+ * VCO clock Callbacks
+ */
+static int dsi_pll_14nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long parent_rate)
+{
+	struct dsi_pll_14nm *pll_14nm = to_pll_14nm(hw);
+	struct dsi_pll_config conf;
+
+	DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_14nm->phy->id, rate,
+	    parent_rate);
+
+	dsi_pll_14nm_config_init(&conf);
+	conf.vco_current_rate = rate;
+
+	pll_14nm_dec_frac_calc(pll_14nm, &conf);
+
+	if (conf.ssc_en)
+		pll_14nm_ssc_calc(pll_14nm, &conf);
+
+	pll_14nm_calc_vco_count(pll_14nm, &conf);
+
+	/* commit the slave DSI PLL registers if we're master. Note that we
+	 * don't lock the slave PLL. We just ensure that the PLL/PHY registers
+	 * of the master and slave are identical
+	 */
+	if (pll_14nm->phy->usecase == MSM_DSI_PHY_MASTER) {
+		struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave;
+
+		pll_db_commit_14nm(pll_14nm_slave, &conf);
+	}
+
+	pll_db_commit_14nm(pll_14nm, &conf);
+
+	return 0;
+}
+
+static unsigned long dsi_pll_14nm_vco_recalc_rate(struct clk_hw *hw,
+						  unsigned long parent_rate)
+{
+	struct dsi_pll_14nm *pll_14nm = to_pll_14nm(hw);
+	void __iomem *base = pll_14nm->phy->pll_base;
+	u64 vco_rate, multiplier = BIT(20);
+	u32 div_frac_start;
+	u32 dec_start;
+	u64 ref_clk = parent_rate;
+
+	dec_start = dsi_phy_read(base + REG_DSI_14nm_PHY_PLL_DEC_START);
+	dec_start &= 0x0ff;
+
+	DBG("dec_start = %x", dec_start);
+
+	div_frac_start = (dsi_phy_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3)
+				& 0xf) << 16;
+	div_frac_start |= (dsi_phy_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2)
+				& 0xff) << 8;
+	div_frac_start |= dsi_phy_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1)
+				& 0xff;
+
+	DBG("div_frac_start = %x", div_frac_start);
+
+	vco_rate = ref_clk * dec_start;
+
+	vco_rate += ((ref_clk * div_frac_start) / multiplier);
+
+	/*
+	 * Recalculating the rate from dec_start and frac_start doesn't end up
+	 * the rate we originally set. Convert the freq to KHz, round it up and
+	 * convert it back to MHz.
+	 */
+	vco_rate = DIV_ROUND_UP_ULL(vco_rate, 1000) * 1000;
+
+	DBG("returning vco rate = %lu", (unsigned long)vco_rate);
+
+	return (unsigned long)vco_rate;
+}
+
+static int dsi_pll_14nm_vco_prepare(struct clk_hw *hw)
+{
+	struct dsi_pll_14nm *pll_14nm = to_pll_14nm(hw);
+	void __iomem *base = pll_14nm->phy->pll_base;
+	void __iomem *cmn_base = pll_14nm->phy->base;
+	bool locked;
+
+	DBG("");
+
+	if (unlikely(pll_14nm->phy->pll_on))
+		return 0;
+
+	if (dsi_pll_14nm_vco_recalc_rate(hw, VCO_REF_CLK_RATE) == 0)
+		dsi_pll_14nm_vco_set_rate(hw, pll_14nm->phy->cfg->min_pll_rate, VCO_REF_CLK_RATE);
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10);
+	dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1);
+
+	locked = pll_14nm_poll_for_ready(pll_14nm, POLL_MAX_READS,
+					 POLL_TIMEOUT_US);
+
+	if (unlikely(!locked)) {
+		DRM_DEV_ERROR(&pll_14nm->phy->pdev->dev, "DSI PLL lock failed\n");
+		return -EINVAL;
+	}
+
+	DBG("DSI PLL lock success");
+	pll_14nm->phy->pll_on = true;
+
+	return 0;
+}
+
+static void dsi_pll_14nm_vco_unprepare(struct clk_hw *hw)
+{
+	struct dsi_pll_14nm *pll_14nm = to_pll_14nm(hw);
+	void __iomem *cmn_base = pll_14nm->phy->base;
+
+	DBG("");
+
+	if (unlikely(!pll_14nm->phy->pll_on))
+		return;
+
+	dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0);
+
+	pll_14nm->phy->pll_on = false;
+}
+
+static long dsi_pll_14nm_clk_round_rate(struct clk_hw *hw,
+		unsigned long rate, unsigned long *parent_rate)
+{
+	struct dsi_pll_14nm *pll_14nm = to_pll_14nm(hw);
+
+	if      (rate < pll_14nm->phy->cfg->min_pll_rate)
+		return  pll_14nm->phy->cfg->min_pll_rate;
+	else if (rate > pll_14nm->phy->cfg->max_pll_rate)
+		return  pll_14nm->phy->cfg->max_pll_rate;
+	else
+		return rate;
+}
+
+static const struct clk_ops clk_ops_dsi_pll_14nm_vco = {
+	.round_rate = dsi_pll_14nm_clk_round_rate,
+	.set_rate = dsi_pll_14nm_vco_set_rate,
+	.recalc_rate = dsi_pll_14nm_vco_recalc_rate,
+	.prepare = dsi_pll_14nm_vco_prepare,
+	.unprepare = dsi_pll_14nm_vco_unprepare,
+};
+
+/*
+ * N1 and N2 post-divider clock callbacks
+ */
+#define div_mask(width)	((1 << (width)) - 1)
+static unsigned long dsi_pll_14nm_postdiv_recalc_rate(struct clk_hw *hw,
+						      unsigned long parent_rate)
+{
+	struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw);
+	struct dsi_pll_14nm *pll_14nm = postdiv->pll;
+	void __iomem *base = pll_14nm->phy->base;
+	u8 shift = postdiv->shift;
+	u8 width = postdiv->width;
+	u32 val;
+
+	DBG("DSI%d PLL parent rate=%lu", pll_14nm->phy->id, parent_rate);
+
+	val = dsi_phy_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0) >> shift;
+	val &= div_mask(width);
+
+	return divider_recalc_rate(hw, parent_rate, val, NULL,
+				   postdiv->flags, width);
+}
+
+static long dsi_pll_14nm_postdiv_round_rate(struct clk_hw *hw,
+					    unsigned long rate,
+					    unsigned long *prate)
+{
+	struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw);
+	struct dsi_pll_14nm *pll_14nm = postdiv->pll;
+
+	DBG("DSI%d PLL parent rate=%lu", pll_14nm->phy->id, rate);
+
+	return divider_round_rate(hw, rate, prate, NULL,
+				  postdiv->width,
+				  postdiv->flags);
+}
+
+static int dsi_pll_14nm_postdiv_set_rate(struct clk_hw *hw, unsigned long rate,
+					 unsigned long parent_rate)
+{
+	struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw);
+	struct dsi_pll_14nm *pll_14nm = postdiv->pll;
+	void __iomem *base = pll_14nm->phy->base;
+	spinlock_t *lock = &pll_14nm->postdiv_lock;
+	u8 shift = postdiv->shift;
+	u8 width = postdiv->width;
+	unsigned int value;
+	unsigned long flags = 0;
+	u32 val;
+
+	DBG("DSI%d PLL parent rate=%lu parent rate %lu", pll_14nm->phy->id, rate,
+	    parent_rate);
+
+	value = divider_get_val(rate, parent_rate, NULL, postdiv->width,
+				postdiv->flags);
+
+	spin_lock_irqsave(lock, flags);
+
+	val = dsi_phy_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0);
+	val &= ~(div_mask(width) << shift);
+
+	val |= value << shift;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val);
+
+	/* If we're master in bonded DSI mode, then the slave PLL's post-dividers
+	 * follow the master's post dividers
+	 */
+	if (pll_14nm->phy->usecase == MSM_DSI_PHY_MASTER) {
+		struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave;
+		void __iomem *slave_base = pll_14nm_slave->phy->base;
+
+		dsi_phy_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val);
+	}
+
+	spin_unlock_irqrestore(lock, flags);
+
+	return 0;
+}
+
+static const struct clk_ops clk_ops_dsi_pll_14nm_postdiv = {
+	.recalc_rate = dsi_pll_14nm_postdiv_recalc_rate,
+	.round_rate = dsi_pll_14nm_postdiv_round_rate,
+	.set_rate = dsi_pll_14nm_postdiv_set_rate,
+};
+
+/*
+ * PLL Callbacks
+ */
+
+static void dsi_14nm_pll_save_state(struct msm_dsi_phy *phy)
+{
+	struct dsi_pll_14nm *pll_14nm = to_pll_14nm(phy->vco_hw);
+	struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state;
+	void __iomem *cmn_base = pll_14nm->phy->base;
+	u32 data;
+
+	data = dsi_phy_read(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0);
+
+	cached_state->n1postdiv = data & 0xf;
+	cached_state->n2postdiv = (data >> 4) & 0xf;
+
+	DBG("DSI%d PLL save state %x %x", pll_14nm->phy->id,
+	    cached_state->n1postdiv, cached_state->n2postdiv);
+
+	cached_state->vco_rate = clk_hw_get_rate(phy->vco_hw);
+}
+
+static int dsi_14nm_pll_restore_state(struct msm_dsi_phy *phy)
+{
+	struct dsi_pll_14nm *pll_14nm = to_pll_14nm(phy->vco_hw);
+	struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state;
+	void __iomem *cmn_base = pll_14nm->phy->base;
+	u32 data;
+	int ret;
+
+	ret = dsi_pll_14nm_vco_set_rate(phy->vco_hw,
+					cached_state->vco_rate, 0);
+	if (ret) {
+		DRM_DEV_ERROR(&pll_14nm->phy->pdev->dev,
+			      "restore vco rate failed. ret=%d\n", ret);
+		return ret;
+	}
+
+	data = cached_state->n1postdiv | (cached_state->n2postdiv << 4);
+
+	DBG("DSI%d PLL restore state %x %x", pll_14nm->phy->id,
+	    cached_state->n1postdiv, cached_state->n2postdiv);
+
+	dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data);
+
+	/* also restore post-dividers for slave DSI PLL */
+	if (phy->usecase == MSM_DSI_PHY_MASTER) {
+		struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave;
+		void __iomem *slave_base = pll_14nm_slave->phy->base;
+
+		dsi_phy_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data);
+	}
+
+	return 0;
+}
+
+static int dsi_14nm_set_usecase(struct msm_dsi_phy *phy)
+{
+	struct dsi_pll_14nm *pll_14nm = to_pll_14nm(phy->vco_hw);
+	void __iomem *base = phy->pll_base;
+	u32 clkbuflr_en, bandgap = 0;
+
+	switch (phy->usecase) {
+	case MSM_DSI_PHY_STANDALONE:
+		clkbuflr_en = 0x1;
+		break;
+	case MSM_DSI_PHY_MASTER:
+		clkbuflr_en = 0x3;
+		pll_14nm->slave = pll_14nm_list[(pll_14nm->phy->id + 1) % DSI_MAX];
+		break;
+	case MSM_DSI_PHY_SLAVE:
+		clkbuflr_en = 0x0;
+		bandgap = 0x3;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_CLKBUFLR_EN, clkbuflr_en);
+	if (bandgap)
+		dsi_phy_write(base + REG_DSI_14nm_PHY_PLL_PLL_BANDGAP, bandgap);
+
+	return 0;
+}
+
+static struct clk_hw *pll_14nm_postdiv_register(struct dsi_pll_14nm *pll_14nm,
+						const char *name,
+						const struct clk_hw *parent_hw,
+						unsigned long flags,
+						u8 shift)
+{
+	struct dsi_pll_14nm_postdiv *pll_postdiv;
+	struct device *dev = &pll_14nm->phy->pdev->dev;
+	struct clk_init_data postdiv_init = {
+		.parent_hws = (const struct clk_hw *[]) { parent_hw },
+		.num_parents = 1,
+		.name = name,
+		.flags = flags,
+		.ops = &clk_ops_dsi_pll_14nm_postdiv,
+	};
+	int ret;
+
+	pll_postdiv = devm_kzalloc(dev, sizeof(*pll_postdiv), GFP_KERNEL);
+	if (!pll_postdiv)
+		return ERR_PTR(-ENOMEM);
+
+	pll_postdiv->pll = pll_14nm;
+	pll_postdiv->shift = shift;
+	/* both N1 and N2 postdividers are 4 bits wide */
+	pll_postdiv->width = 4;
+	/* range of each divider is from 1 to 15 */
+	pll_postdiv->flags = CLK_DIVIDER_ONE_BASED;
+	pll_postdiv->hw.init = &postdiv_init;
+
+	ret = devm_clk_hw_register(dev, &pll_postdiv->hw);
+	if (ret)
+		return ERR_PTR(ret);
+
+	return &pll_postdiv->hw;
+}
+
+static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm, struct clk_hw **provided_clocks)
+{
+	char clk_name[32];
+	struct clk_init_data vco_init = {
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "ref",
+		},
+		.num_parents = 1,
+		.name = clk_name,
+		.flags = CLK_IGNORE_UNUSED,
+		.ops = &clk_ops_dsi_pll_14nm_vco,
+	};
+	struct device *dev = &pll_14nm->phy->pdev->dev;
+	struct clk_hw *hw, *n1_postdiv, *n1_postdivby2;
+	int ret;
+
+	DBG("DSI%d", pll_14nm->phy->id);
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dvco_clk", pll_14nm->phy->id);
+	pll_14nm->clk_hw.init = &vco_init;
+
+	ret = devm_clk_hw_register(dev, &pll_14nm->clk_hw);
+	if (ret)
+		return ret;
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dn1_postdiv_clk", pll_14nm->phy->id);
+
+	/* N1 postdiv, bits 0-3 in REG_DSI_14nm_PHY_CMN_CLK_CFG0 */
+	n1_postdiv = pll_14nm_postdiv_register(pll_14nm, clk_name,
+			&pll_14nm->clk_hw, CLK_SET_RATE_PARENT, 0);
+	if (IS_ERR(n1_postdiv))
+		return PTR_ERR(n1_postdiv);
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dpllbyte", pll_14nm->phy->id);
+
+	/* DSI Byte clock = VCO_CLK / N1 / 8 */
+	hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk_name,
+			n1_postdiv, CLK_SET_RATE_PARENT, 1, 8);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	provided_clocks[DSI_BYTE_PLL_CLK] = hw;
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dn1_postdivby2_clk", pll_14nm->phy->id);
+
+	/*
+	 * Skip the mux for now, force DSICLK_SEL to 1, Add a /2 divider
+	 * on the way. Don't let it set parent.
+	 */
+	n1_postdivby2 = devm_clk_hw_register_fixed_factor_parent_hw(dev,
+			clk_name, n1_postdiv, 0, 1, 2);
+	if (IS_ERR(n1_postdivby2))
+		return PTR_ERR(n1_postdivby2);
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dpll", pll_14nm->phy->id);
+
+	/* DSI pixel clock = VCO_CLK / N1 / 2 / N2
+	 * This is the output of N2 post-divider, bits 4-7 in
+	 * REG_DSI_14nm_PHY_CMN_CLK_CFG0. Don't let it set parent.
+	 */
+	hw = pll_14nm_postdiv_register(pll_14nm, clk_name, n1_postdivby2,
+			0, 4);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+
+	provided_clocks[DSI_PIXEL_PLL_CLK] = hw;
+
+	return 0;
+}
+
+static int dsi_pll_14nm_init(struct msm_dsi_phy *phy)
+{
+	struct platform_device *pdev = phy->pdev;
+	struct dsi_pll_14nm *pll_14nm;
+	int ret;
+
+	if (!pdev)
+		return -ENODEV;
+
+	pll_14nm = devm_kzalloc(&pdev->dev, sizeof(*pll_14nm), GFP_KERNEL);
+	if (!pll_14nm)
+		return -ENOMEM;
+
+	DBG("PLL%d", phy->id);
+
+	pll_14nm_list[phy->id] = pll_14nm;
+
+	spin_lock_init(&pll_14nm->postdiv_lock);
+
+	pll_14nm->phy = phy;
+
+	ret = pll_14nm_register(pll_14nm, phy->provided_clocks->hws);
+	if (ret) {
+		DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
+		return ret;
+	}
+
+	phy->vco_hw = &pll_14nm->clk_hw;
+
+	return 0;
+}
+
+static void dsi_14nm_dphy_set_timing(struct msm_dsi_phy *phy,
+				     struct msm_dsi_dphy_timing *timing,
+				     int lane_idx)
+{
+	void __iomem *base = phy->lane_base;
+	bool clk_ln = (lane_idx == PHY_14NM_CKLN_IDX);
+	u32 zero = clk_ln ? timing->clk_zero : timing->hs_zero;
+	u32 prepare = clk_ln ? timing->clk_prepare : timing->hs_prepare;
+	u32 trail = clk_ln ? timing->clk_trail : timing->hs_trail;
+	u32 rqst = clk_ln ? timing->hs_rqst_ckln : timing->hs_rqst;
+	u32 prep_dly = clk_ln ? timing->hs_prep_dly_ckln : timing->hs_prep_dly;
+	u32 halfbyte_en = clk_ln ? timing->hs_halfbyte_en_ckln :
+				   timing->hs_halfbyte_en;
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_4(lane_idx),
+		      DSI_14nm_PHY_LN_TIMING_CTRL_4_HS_EXIT(timing->hs_exit));
+	dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_5(lane_idx),
+		      DSI_14nm_PHY_LN_TIMING_CTRL_5_HS_ZERO(zero));
+	dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_6(lane_idx),
+		      DSI_14nm_PHY_LN_TIMING_CTRL_6_HS_PREPARE(prepare));
+	dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_7(lane_idx),
+		      DSI_14nm_PHY_LN_TIMING_CTRL_7_HS_TRAIL(trail));
+	dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_8(lane_idx),
+		      DSI_14nm_PHY_LN_TIMING_CTRL_8_HS_RQST(rqst));
+	dsi_phy_write(base + REG_DSI_14nm_PHY_LN_CFG0(lane_idx),
+		      DSI_14nm_PHY_LN_CFG0_PREPARE_DLY(prep_dly));
+	dsi_phy_write(base + REG_DSI_14nm_PHY_LN_CFG1(lane_idx),
+		      halfbyte_en ? DSI_14nm_PHY_LN_CFG1_HALFBYTECLK_EN : 0);
+	dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_9(lane_idx),
+		      DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_GO(timing->ta_go) |
+		      DSI_14nm_PHY_LN_TIMING_CTRL_9_TA_SURE(timing->ta_sure));
+	dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_10(lane_idx),
+		      DSI_14nm_PHY_LN_TIMING_CTRL_10_TA_GET(timing->ta_get));
+	dsi_phy_write(base + REG_DSI_14nm_PHY_LN_TIMING_CTRL_11(lane_idx),
+		      DSI_14nm_PHY_LN_TIMING_CTRL_11_TRIG3_CMD(0xa0));
+}
+
+static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy,
+			       struct msm_dsi_phy_clk_request *clk_req)
+{
+	struct msm_dsi_dphy_timing *timing = &phy->timing;
+	u32 data;
+	int i;
+	int ret;
+	void __iomem *base = phy->base;
+	void __iomem *lane_base = phy->lane_base;
+	u32 glbl_test_ctrl;
+
+	if (msm_dsi_dphy_timing_calc_v2(timing, clk_req)) {
+		DRM_DEV_ERROR(&phy->pdev->dev,
+			      "%s: D-PHY timing calculation failed\n",
+			      __func__);
+		return -EINVAL;
+	}
+
+	data = 0x1c;
+	if (phy->usecase != MSM_DSI_PHY_STANDALONE)
+		data |= DSI_14nm_PHY_CMN_LDO_CNTRL_VREG_CTRL(32);
+	dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_LDO_CNTRL, data);
+
+	dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL, 0x1);
+
+	/* 4 data lanes + 1 clk lane configuration */
+	for (i = 0; i < 5; i++) {
+		dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_VREG_CNTRL(i),
+			      0x1d);
+
+		dsi_phy_write(lane_base +
+			      REG_DSI_14nm_PHY_LN_STRENGTH_CTRL_0(i), 0xff);
+		dsi_phy_write(lane_base +
+			      REG_DSI_14nm_PHY_LN_STRENGTH_CTRL_1(i),
+			      (i == PHY_14NM_CKLN_IDX) ? 0x00 : 0x06);
+
+		dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_CFG3(i),
+			      (i == PHY_14NM_CKLN_IDX) ? 0x8f : 0x0f);
+		dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_CFG2(i), 0x10);
+		dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_TEST_DATAPATH(i),
+			      0);
+		dsi_phy_write(lane_base + REG_DSI_14nm_PHY_LN_TEST_STR(i),
+			      0x88);
+
+		dsi_14nm_dphy_set_timing(phy, timing, i);
+	}
+
+	/* Make sure PLL is not start */
+	dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0x00);
+
+	wmb(); /* make sure everything is written before reset and enable */
+
+	/* reset digital block */
+	dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x80);
+	wmb(); /* ensure reset is asserted */
+	udelay(100);
+	dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x00);
+
+	glbl_test_ctrl = dsi_phy_read(base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL);
+	if (phy->id == DSI_1 && phy->usecase == MSM_DSI_PHY_SLAVE)
+		glbl_test_ctrl |= DSI_14nm_PHY_CMN_GLBL_TEST_CTRL_BITCLK_HS_SEL;
+	else
+		glbl_test_ctrl &= ~DSI_14nm_PHY_CMN_GLBL_TEST_CTRL_BITCLK_HS_SEL;
+	dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL, glbl_test_ctrl);
+	ret = dsi_14nm_set_usecase(phy);
+	if (ret) {
+		DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n",
+			      __func__, ret);
+		return ret;
+	}
+
+	/* Remove power down from PLL and all lanes */
+	dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CTRL_0, 0xff);
+
+	return 0;
+}
+
+static void dsi_14nm_phy_disable(struct msm_dsi_phy *phy)
+{
+	dsi_phy_write(phy->base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL, 0);
+	dsi_phy_write(phy->base + REG_DSI_14nm_PHY_CMN_CTRL_0, 0);
+
+	/* ensure that the phy is completely disabled */
+	wmb();
+}
+
+static const struct regulator_bulk_data dsi_phy_14nm_17mA_regulators[] = {
+	{ .supply = "vcca", .init_load_uA = 17000 },
+};
+
+static const struct regulator_bulk_data dsi_phy_14nm_73p4mA_regulators[] = {
+	{ .supply = "vcca", .init_load_uA = 73400 },
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_14nm_cfgs = {
+	.has_phy_lane = true,
+	.regulator_data = dsi_phy_14nm_17mA_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_14nm_17mA_regulators),
+	.ops = {
+		.enable = dsi_14nm_phy_enable,
+		.disable = dsi_14nm_phy_disable,
+		.pll_init = dsi_pll_14nm_init,
+		.save_pll_state = dsi_14nm_pll_save_state,
+		.restore_pll_state = dsi_14nm_pll_restore_state,
+	},
+	.min_pll_rate = VCO_MIN_RATE,
+	.max_pll_rate = VCO_MAX_RATE,
+	.io_start = { 0x994400, 0x996400 },
+	.num_dsi_phy = 2,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_14nm_660_cfgs = {
+	.has_phy_lane = true,
+	.regulator_data = dsi_phy_14nm_73p4mA_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_14nm_73p4mA_regulators),
+	.ops = {
+		.enable = dsi_14nm_phy_enable,
+		.disable = dsi_14nm_phy_disable,
+		.pll_init = dsi_pll_14nm_init,
+		.save_pll_state = dsi_14nm_pll_save_state,
+		.restore_pll_state = dsi_14nm_pll_restore_state,
+	},
+	.min_pll_rate = VCO_MIN_RATE,
+	.max_pll_rate = VCO_MAX_RATE,
+	.io_start = { 0xc994400, 0xc996400 },
+	.num_dsi_phy = 2,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_14nm_8953_cfgs = {
+	.has_phy_lane = true,
+	.regulator_data = dsi_phy_14nm_17mA_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_14nm_17mA_regulators),
+	.ops = {
+		.enable = dsi_14nm_phy_enable,
+		.disable = dsi_14nm_phy_disable,
+		.pll_init = dsi_pll_14nm_init,
+		.save_pll_state = dsi_14nm_pll_save_state,
+		.restore_pll_state = dsi_14nm_pll_restore_state,
+	},
+	.min_pll_rate = VCO_MIN_RATE,
+	.max_pll_rate = VCO_MAX_RATE,
+	.io_start = { 0x1a94400, 0x1a96400 },
+	.num_dsi_phy = 2,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_14nm_2290_cfgs = {
+	.has_phy_lane = true,
+	.ops = {
+		.enable = dsi_14nm_phy_enable,
+		.disable = dsi_14nm_phy_disable,
+		.pll_init = dsi_pll_14nm_init,
+		.save_pll_state = dsi_14nm_pll_save_state,
+		.restore_pll_state = dsi_14nm_pll_restore_state,
+	},
+	.min_pll_rate = VCO_MIN_RATE,
+	.max_pll_rate = VCO_MAX_RATE,
+	.io_start = { 0x5e94400 },
+	.num_dsi_phy = 1,
+};
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy_20nm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy_20nm.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ */
+
+#include "dsi_phy.h"
+#include "dsi.xml.h"
+#include "dsi_phy_20nm.xml.h"
+
+static void dsi_20nm_dphy_set_timing(struct msm_dsi_phy *phy,
+		struct msm_dsi_dphy_timing *timing)
+{
+	void __iomem *base = phy->base;
+
+	dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_0,
+		DSI_20nm_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero));
+	dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_1,
+		DSI_20nm_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail));
+	dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_2,
+		DSI_20nm_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare));
+	if (timing->clk_zero & BIT(8))
+		dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_3,
+			DSI_20nm_PHY_TIMING_CTRL_3_CLK_ZERO_8);
+	dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_4,
+		DSI_20nm_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit));
+	dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_5,
+		DSI_20nm_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero));
+	dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_6,
+		DSI_20nm_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare));
+	dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_7,
+		DSI_20nm_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail));
+	dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_8,
+		DSI_20nm_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst));
+	dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_9,
+		DSI_20nm_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) |
+		DSI_20nm_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure));
+	dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_10,
+		DSI_20nm_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get));
+	dsi_phy_write(base + REG_DSI_20nm_PHY_TIMING_CTRL_11,
+		DSI_20nm_PHY_TIMING_CTRL_11_TRIG3_CMD(0));
+}
+
+static void dsi_20nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable)
+{
+	void __iomem *base = phy->reg_base;
+
+	if (!enable) {
+		dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CAL_PWR_CFG, 0);
+		return;
+	}
+
+	if (phy->regulator_ldo_mode) {
+		dsi_phy_write(phy->base + REG_DSI_20nm_PHY_LDO_CNTRL, 0x1d);
+		return;
+	}
+
+	/* non LDO mode */
+	dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CTRL_1, 0x03);
+	dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CTRL_2, 0x03);
+	dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CTRL_3, 0x00);
+	dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CTRL_4, 0x20);
+	dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CAL_PWR_CFG, 0x01);
+	dsi_phy_write(phy->base + REG_DSI_20nm_PHY_LDO_CNTRL, 0x00);
+	dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CTRL_0, 0x03);
+}
+
+static int dsi_20nm_phy_enable(struct msm_dsi_phy *phy,
+				struct msm_dsi_phy_clk_request *clk_req)
+{
+	struct msm_dsi_dphy_timing *timing = &phy->timing;
+	int i;
+	void __iomem *base = phy->base;
+	u32 cfg_4[4] = {0x20, 0x40, 0x20, 0x00};
+	u32 val;
+
+	DBG("");
+
+	if (msm_dsi_dphy_timing_calc(timing, clk_req)) {
+		DRM_DEV_ERROR(&phy->pdev->dev,
+			"%s: D-PHY timing calculation failed\n", __func__);
+		return -EINVAL;
+	}
+
+	dsi_20nm_phy_regulator_ctrl(phy, true);
+
+	dsi_phy_write(base + REG_DSI_20nm_PHY_STRENGTH_0, 0xff);
+
+	val = dsi_phy_read(base + REG_DSI_20nm_PHY_GLBL_TEST_CTRL);
+	if (phy->id == DSI_1 && phy->usecase == MSM_DSI_PHY_STANDALONE)
+		val |= DSI_20nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL;
+	else
+		val &= ~DSI_20nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL;
+	dsi_phy_write(base + REG_DSI_20nm_PHY_GLBL_TEST_CTRL, val);
+
+	for (i = 0; i < 4; i++) {
+		dsi_phy_write(base + REG_DSI_20nm_PHY_LN_CFG_3(i),
+							(i >> 1) * 0x40);
+		dsi_phy_write(base + REG_DSI_20nm_PHY_LN_TEST_STR_0(i), 0x01);
+		dsi_phy_write(base + REG_DSI_20nm_PHY_LN_TEST_STR_1(i), 0x46);
+		dsi_phy_write(base + REG_DSI_20nm_PHY_LN_CFG_0(i), 0x02);
+		dsi_phy_write(base + REG_DSI_20nm_PHY_LN_CFG_1(i), 0xa0);
+		dsi_phy_write(base + REG_DSI_20nm_PHY_LN_CFG_4(i), cfg_4[i]);
+	}
+
+	dsi_phy_write(base + REG_DSI_20nm_PHY_LNCK_CFG_3, 0x80);
+	dsi_phy_write(base + REG_DSI_20nm_PHY_LNCK_TEST_STR0, 0x01);
+	dsi_phy_write(base + REG_DSI_20nm_PHY_LNCK_TEST_STR1, 0x46);
+	dsi_phy_write(base + REG_DSI_20nm_PHY_LNCK_CFG_0, 0x00);
+	dsi_phy_write(base + REG_DSI_20nm_PHY_LNCK_CFG_1, 0xa0);
+	dsi_phy_write(base + REG_DSI_20nm_PHY_LNCK_CFG_2, 0x00);
+	dsi_phy_write(base + REG_DSI_20nm_PHY_LNCK_CFG_4, 0x00);
+
+	dsi_20nm_dphy_set_timing(phy, timing);
+
+	dsi_phy_write(base + REG_DSI_20nm_PHY_CTRL_1, 0x00);
+
+	dsi_phy_write(base + REG_DSI_20nm_PHY_STRENGTH_1, 0x06);
+
+	/* make sure everything is written before enable */
+	wmb();
+	dsi_phy_write(base + REG_DSI_20nm_PHY_CTRL_0, 0x7f);
+
+	return 0;
+}
+
+static void dsi_20nm_phy_disable(struct msm_dsi_phy *phy)
+{
+	dsi_phy_write(phy->base + REG_DSI_20nm_PHY_CTRL_0, 0);
+	dsi_20nm_phy_regulator_ctrl(phy, false);
+}
+
+static const struct regulator_bulk_data dsi_phy_20nm_regulators[] = {
+	{ .supply = "vddio", .init_load_uA = 100000 },	/* 1.8 V */
+	{ .supply = "vcca", .init_load_uA = 10000 },	/* 1.0 V */
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_20nm_cfgs = {
+	.has_phy_regulator = true,
+	.regulator_data = dsi_phy_20nm_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_20nm_regulators),
+	.ops = {
+		.enable = dsi_20nm_phy_enable,
+		.disable = dsi_20nm_phy_disable,
+	},
+	.io_start = { 0xfd998500, 0xfd9a0500 },
+	.num_dsi_phy = 2,
+};
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy_28nm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy_28nm.c
@@ -0,0 +1,919 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+
+#include "dsi_phy.h"
+#include "dsi.xml.h"
+#include "dsi_phy_28nm.xml.h"
+
+/*
+ * DSI PLL 28nm - clock diagram (eg: DSI0):
+ *
+ *         dsi0analog_postdiv_clk
+ *                             |         dsi0indirect_path_div2_clk
+ *                             |          |
+ *                   +------+  |  +----+  |  |\   dsi0byte_mux
+ *  dsi0vco_clk --o--| DIV1 |--o--| /2 |--o--| \   |
+ *                |  +------+     +----+     | m|  |  +----+
+ *                |                          | u|--o--| /4 |-- dsi0pllbyte
+ *                |                          | x|     +----+
+ *                o--------------------------| /
+ *                |                          |/
+ *                |          +------+
+ *                o----------| DIV3 |------------------------- dsi0pll
+ *                           +------+
+ */
+
+#define POLL_MAX_READS			10
+#define POLL_TIMEOUT_US		50
+
+#define VCO_REF_CLK_RATE		19200000
+#define VCO_MIN_RATE			350000000
+#define VCO_MAX_RATE			750000000
+
+/* v2.0.0 28nm LP implementation */
+#define DSI_PHY_28NM_QUIRK_PHY_LP	BIT(0)
+#define DSI_PHY_28NM_QUIRK_PHY_8226	BIT(1)
+
+#define LPFR_LUT_SIZE			10
+struct lpfr_cfg {
+	unsigned long vco_rate;
+	u32 resistance;
+};
+
+/* Loop filter resistance: */
+static const struct lpfr_cfg lpfr_lut[LPFR_LUT_SIZE] = {
+	{ 479500000,  8 },
+	{ 480000000, 11 },
+	{ 575500000,  8 },
+	{ 576000000, 12 },
+	{ 610500000,  8 },
+	{ 659500000,  9 },
+	{ 671500000, 10 },
+	{ 672000000, 14 },
+	{ 708500000, 10 },
+	{ 750000000, 11 },
+};
+
+struct pll_28nm_cached_state {
+	unsigned long vco_rate;
+	u8 postdiv3;
+	u8 postdiv1;
+	u8 byte_mux;
+};
+
+struct dsi_pll_28nm {
+	struct clk_hw clk_hw;
+
+	struct msm_dsi_phy *phy;
+
+	struct pll_28nm_cached_state cached_state;
+};
+
+#define to_pll_28nm(x)	container_of(x, struct dsi_pll_28nm, clk_hw)
+
+static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm,
+				u32 nb_tries, u32 timeout_us)
+{
+	bool pll_locked = false;
+	u32 val;
+
+	while (nb_tries--) {
+		val = dsi_phy_read(pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_STATUS);
+		pll_locked = !!(val & DSI_28nm_PHY_PLL_STATUS_PLL_RDY);
+
+		if (pll_locked)
+			break;
+
+		udelay(timeout_us);
+	}
+	DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* ");
+
+	return pll_locked;
+}
+
+static void pll_28nm_software_reset(struct dsi_pll_28nm *pll_28nm)
+{
+	void __iomem *base = pll_28nm->phy->pll_base;
+
+	/*
+	 * Add HW recommended delays after toggling the software
+	 * reset bit off and back on.
+	 */
+	dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG,
+			     DSI_28nm_PHY_PLL_TEST_CFG_PLL_SW_RESET, 1);
+	dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG, 0x00, 1);
+}
+
+/*
+ * Clock Callbacks
+ */
+static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+		unsigned long parent_rate)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
+	struct device *dev = &pll_28nm->phy->pdev->dev;
+	void __iomem *base = pll_28nm->phy->pll_base;
+	unsigned long div_fbx1000, gen_vco_clk;
+	u32 refclk_cfg, frac_n_mode, frac_n_value;
+	u32 sdm_cfg0, sdm_cfg1, sdm_cfg2, sdm_cfg3;
+	u32 cal_cfg10, cal_cfg11;
+	u32 rem;
+	int i;
+
+	VERB("rate=%lu, parent's=%lu", rate, parent_rate);
+
+	/* Force postdiv2 to be div-4 */
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV2_CFG, 3);
+
+	/* Configure the Loop filter resistance */
+	for (i = 0; i < LPFR_LUT_SIZE; i++)
+		if (rate <= lpfr_lut[i].vco_rate)
+			break;
+	if (i == LPFR_LUT_SIZE) {
+		DRM_DEV_ERROR(dev, "unable to get loop filter resistance. vco=%lu\n",
+				rate);
+		return -EINVAL;
+	}
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LPFR_CFG, lpfr_lut[i].resistance);
+
+	/* Loop filter capacitance values : c1 and c2 */
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LPFC1_CFG, 0x70);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LPFC2_CFG, 0x15);
+
+	rem = rate % VCO_REF_CLK_RATE;
+	if (rem) {
+		refclk_cfg = DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR;
+		frac_n_mode = 1;
+		div_fbx1000 = rate / (VCO_REF_CLK_RATE / 500);
+		gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 500);
+	} else {
+		refclk_cfg = 0x0;
+		frac_n_mode = 0;
+		div_fbx1000 = rate / (VCO_REF_CLK_RATE / 1000);
+		gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 1000);
+	}
+
+	DBG("refclk_cfg = %d", refclk_cfg);
+
+	rem = div_fbx1000 % 1000;
+	frac_n_value = (rem << 16) / 1000;
+
+	DBG("div_fb = %lu", div_fbx1000);
+	DBG("frac_n_value = %d", frac_n_value);
+
+	DBG("Generated VCO Clock: %lu", gen_vco_clk);
+	rem = 0;
+	sdm_cfg1 = dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1);
+	sdm_cfg1 &= ~DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET__MASK;
+	if (frac_n_mode) {
+		sdm_cfg0 = 0x0;
+		sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(0);
+		sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(
+				(u32)(((div_fbx1000 / 1000) & 0x3f) - 1));
+		sdm_cfg3 = frac_n_value >> 8;
+		sdm_cfg2 = frac_n_value & 0xff;
+	} else {
+		sdm_cfg0 = DSI_28nm_PHY_PLL_SDM_CFG0_BYP;
+		sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(
+				(u32)(((div_fbx1000 / 1000) & 0x3f) - 1));
+		sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(0);
+		sdm_cfg2 = 0;
+		sdm_cfg3 = 0;
+	}
+
+	DBG("sdm_cfg0=%d", sdm_cfg0);
+	DBG("sdm_cfg1=%d", sdm_cfg1);
+	DBG("sdm_cfg2=%d", sdm_cfg2);
+	DBG("sdm_cfg3=%d", sdm_cfg3);
+
+	cal_cfg11 = (u32)(gen_vco_clk / (256 * 1000000));
+	cal_cfg10 = (u32)((gen_vco_clk % (256 * 1000000)) / 1000000);
+	DBG("cal_cfg10=%d, cal_cfg11=%d", cal_cfg10, cal_cfg11);
+
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CHGPUMP_CFG, 0x02);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG3,    0x2b);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG4,    0x06);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2,  0x0d);
+
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1, sdm_cfg1);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2,
+		      DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0(sdm_cfg2));
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3,
+		      DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8(sdm_cfg3));
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG4, 0x00);
+
+	/* Add hardware recommended delay for correct PLL configuration */
+	if (pll_28nm->phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP)
+		udelay(1000);
+	else
+		udelay(1);
+
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG, refclk_cfg);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG, 0x00);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_VCOLPF_CFG, 0x31);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0,   sdm_cfg0);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG0,   0x12);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG6,   0x30);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG7,   0x00);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG8,   0x60);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG9,   0x00);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG10,  cal_cfg10 & 0xff);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG11,  cal_cfg11 & 0xff);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_EFUSE_CFG,  0x20);
+
+	return 0;
+}
+
+static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
+
+	return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS,
+					POLL_TIMEOUT_US);
+}
+
+static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
+	void __iomem *base = pll_28nm->phy->pll_base;
+	u32 sdm0, doubler, sdm_byp_div;
+	u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3;
+	u32 ref_clk = VCO_REF_CLK_RATE;
+	unsigned long vco_rate;
+
+	VERB("parent_rate=%lu", parent_rate);
+
+	/* Check to see if the ref clk doubler is enabled */
+	doubler = dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG) &
+			DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR;
+	ref_clk += (doubler * VCO_REF_CLK_RATE);
+
+	/* see if it is integer mode or sdm mode */
+	sdm0 = dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0);
+	if (sdm0 & DSI_28nm_PHY_PLL_SDM_CFG0_BYP) {
+		/* integer mode */
+		sdm_byp_div = FIELD(
+				dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0),
+				DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV) + 1;
+		vco_rate = ref_clk * sdm_byp_div;
+	} else {
+		/* sdm mode */
+		sdm_dc_off = FIELD(
+				dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1),
+				DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET);
+		DBG("sdm_dc_off = %d", sdm_dc_off);
+		sdm2 = FIELD(dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2),
+				DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0);
+		sdm3 = FIELD(dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3),
+				DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8);
+		sdm_freq_seed = (sdm3 << 8) | sdm2;
+		DBG("sdm_freq_seed = %d", sdm_freq_seed);
+
+		vco_rate = (ref_clk * (sdm_dc_off + 1)) +
+			mult_frac(ref_clk, sdm_freq_seed, BIT(16));
+		DBG("vco rate = %lu", vco_rate);
+	}
+
+	DBG("returning vco rate = %lu", vco_rate);
+
+	return vco_rate;
+}
+
+static int _dsi_pll_28nm_vco_prepare_hpm(struct dsi_pll_28nm *pll_28nm)
+{
+	struct device *dev = &pll_28nm->phy->pdev->dev;
+	void __iomem *base = pll_28nm->phy->pll_base;
+	u32 max_reads = 5, timeout_us = 100;
+	bool locked;
+	u32 val;
+	int i;
+
+	DBG("id=%d", pll_28nm->phy->id);
+
+	pll_28nm_software_reset(pll_28nm);
+
+	/*
+	 * PLL power up sequence.
+	 * Add necessary delays recommended by hardware.
+	 */
+	val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
+	dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1);
+
+	val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
+	dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
+
+	val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
+	dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
+
+	val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
+	dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600);
+
+	for (i = 0; i < 2; i++) {
+		/* DSI Uniphy lock detect setting */
+		dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2,
+				     0x0c, 100);
+		dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d);
+
+		/* poll for PLL ready status */
+		locked = pll_28nm_poll_for_ready(pll_28nm, max_reads,
+						 timeout_us);
+		if (locked)
+			break;
+
+		pll_28nm_software_reset(pll_28nm);
+
+		/*
+		 * PLL power up sequence.
+		 * Add necessary delays recommended by hardware.
+		 */
+		val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
+		dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1);
+
+		val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
+		dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
+
+		val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
+		dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 250);
+
+		val &= ~DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
+		dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
+
+		val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
+		dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
+
+		val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
+		dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600);
+	}
+
+	if (unlikely(!locked))
+		DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
+	else
+		DBG("DSI PLL Lock success");
+
+	return locked ? 0 : -EINVAL;
+}
+
+static int dsi_pll_28nm_vco_prepare_hpm(struct clk_hw *hw)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
+	int i, ret;
+
+	if (unlikely(pll_28nm->phy->pll_on))
+		return 0;
+
+	for (i = 0; i < 3; i++) {
+		ret = _dsi_pll_28nm_vco_prepare_hpm(pll_28nm);
+		if (!ret) {
+			pll_28nm->phy->pll_on = true;
+			return 0;
+		}
+	}
+
+	return ret;
+}
+
+static int dsi_pll_28nm_vco_prepare_8226(struct clk_hw *hw)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
+	struct device *dev = &pll_28nm->phy->pdev->dev;
+	void __iomem *base = pll_28nm->phy->pll_base;
+	u32 max_reads = 5, timeout_us = 100;
+	bool locked;
+	u32 val;
+	int i;
+
+	DBG("id=%d", pll_28nm->phy->id);
+
+	pll_28nm_software_reset(pll_28nm);
+
+	/*
+	 * PLL power up sequence.
+	 * Add necessary delays recommended by hardware.
+	 */
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG1, 0x34);
+
+	val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
+	dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
+
+	val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
+	dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200);
+
+	val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
+	val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
+	dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600);
+
+	for (i = 0; i < 7; i++) {
+		/* DSI Uniphy lock detect setting */
+		dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d);
+		dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2,
+				0x0c, 100);
+		dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d);
+
+		/* poll for PLL ready status */
+		locked = pll_28nm_poll_for_ready(pll_28nm,
+						max_reads, timeout_us);
+		if (locked)
+			break;
+
+		pll_28nm_software_reset(pll_28nm);
+
+		/*
+		 * PLL power up sequence.
+		 * Add necessary delays recommended by hardware.
+		 */
+		dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG, 0x00, 50);
+
+		val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
+		val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
+		dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 100);
+
+		val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B;
+		val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
+		dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600);
+	}
+
+	if (unlikely(!locked))
+		DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
+	else
+		DBG("DSI PLL Lock success");
+
+	return locked ? 0 : -EINVAL;
+}
+
+static int dsi_pll_28nm_vco_prepare_lp(struct clk_hw *hw)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
+	struct device *dev = &pll_28nm->phy->pdev->dev;
+	void __iomem *base = pll_28nm->phy->pll_base;
+	bool locked;
+	u32 max_reads = 10, timeout_us = 50;
+	u32 val;
+
+	DBG("id=%d", pll_28nm->phy->id);
+
+	if (unlikely(pll_28nm->phy->pll_on))
+		return 0;
+
+	pll_28nm_software_reset(pll_28nm);
+
+	/*
+	 * PLL power up sequence.
+	 * Add necessary delays recommended by hardware.
+	 */
+	dsi_phy_write_ndelay(base + REG_DSI_28nm_PHY_PLL_CAL_CFG1, 0x34, 500);
+
+	val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B;
+	dsi_phy_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
+
+	val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B;
+	dsi_phy_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
+
+	val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B |
+		DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE;
+	dsi_phy_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500);
+
+	/* DSI PLL toggle lock detect setting */
+	dsi_phy_write_ndelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x04, 500);
+	dsi_phy_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x05, 512);
+
+	locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us);
+
+	if (unlikely(!locked)) {
+		DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
+		return -EINVAL;
+	}
+
+	DBG("DSI PLL lock success");
+	pll_28nm->phy->pll_on = true;
+
+	return 0;
+}
+
+static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
+
+	DBG("id=%d", pll_28nm->phy->id);
+
+	if (unlikely(!pll_28nm->phy->pll_on))
+		return;
+
+	dsi_phy_write(pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_GLB_CFG, 0x00);
+
+	pll_28nm->phy->pll_on = false;
+}
+
+static long dsi_pll_28nm_clk_round_rate(struct clk_hw *hw,
+		unsigned long rate, unsigned long *parent_rate)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
+
+	if      (rate < pll_28nm->phy->cfg->min_pll_rate)
+		return  pll_28nm->phy->cfg->min_pll_rate;
+	else if (rate > pll_28nm->phy->cfg->max_pll_rate)
+		return  pll_28nm->phy->cfg->max_pll_rate;
+	else
+		return rate;
+}
+
+static const struct clk_ops clk_ops_dsi_pll_28nm_vco_hpm = {
+	.round_rate = dsi_pll_28nm_clk_round_rate,
+	.set_rate = dsi_pll_28nm_clk_set_rate,
+	.recalc_rate = dsi_pll_28nm_clk_recalc_rate,
+	.prepare = dsi_pll_28nm_vco_prepare_hpm,
+	.unprepare = dsi_pll_28nm_vco_unprepare,
+	.is_enabled = dsi_pll_28nm_clk_is_enabled,
+};
+
+static const struct clk_ops clk_ops_dsi_pll_28nm_vco_lp = {
+	.round_rate = dsi_pll_28nm_clk_round_rate,
+	.set_rate = dsi_pll_28nm_clk_set_rate,
+	.recalc_rate = dsi_pll_28nm_clk_recalc_rate,
+	.prepare = dsi_pll_28nm_vco_prepare_lp,
+	.unprepare = dsi_pll_28nm_vco_unprepare,
+	.is_enabled = dsi_pll_28nm_clk_is_enabled,
+};
+
+static const struct clk_ops clk_ops_dsi_pll_28nm_vco_8226 = {
+	.round_rate = dsi_pll_28nm_clk_round_rate,
+	.set_rate = dsi_pll_28nm_clk_set_rate,
+	.recalc_rate = dsi_pll_28nm_clk_recalc_rate,
+	.prepare = dsi_pll_28nm_vco_prepare_8226,
+	.unprepare = dsi_pll_28nm_vco_unprepare,
+	.is_enabled = dsi_pll_28nm_clk_is_enabled,
+};
+
+/*
+ * PLL Callbacks
+ */
+
+static void dsi_28nm_pll_save_state(struct msm_dsi_phy *phy)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw);
+	struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
+	void __iomem *base = pll_28nm->phy->pll_base;
+
+	cached_state->postdiv3 =
+			dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG);
+	cached_state->postdiv1 =
+			dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG);
+	cached_state->byte_mux = dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_VREG_CFG);
+	if (dsi_pll_28nm_clk_is_enabled(phy->vco_hw))
+		cached_state->vco_rate = clk_hw_get_rate(phy->vco_hw);
+	else
+		cached_state->vco_rate = 0;
+}
+
+static int dsi_28nm_pll_restore_state(struct msm_dsi_phy *phy)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw);
+	struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
+	void __iomem *base = pll_28nm->phy->pll_base;
+	int ret;
+
+	ret = dsi_pll_28nm_clk_set_rate(phy->vco_hw,
+					cached_state->vco_rate, 0);
+	if (ret) {
+		DRM_DEV_ERROR(&pll_28nm->phy->pdev->dev,
+			"restore vco rate failed. ret=%d\n", ret);
+		return ret;
+	}
+
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG,
+		      cached_state->postdiv3);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG,
+		      cached_state->postdiv1);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_PLL_VREG_CFG,
+		      cached_state->byte_mux);
+
+	return 0;
+}
+
+static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **provided_clocks)
+{
+	char clk_name[32];
+	struct clk_init_data vco_init = {
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "ref", .name = "xo",
+		},
+		.num_parents = 1,
+		.name = clk_name,
+		.flags = CLK_IGNORE_UNUSED,
+	};
+	struct device *dev = &pll_28nm->phy->pdev->dev;
+	struct clk_hw *hw, *analog_postdiv, *indirect_path_div2, *byte_mux;
+	int ret;
+
+	DBG("%d", pll_28nm->phy->id);
+
+	if (pll_28nm->phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP)
+		vco_init.ops = &clk_ops_dsi_pll_28nm_vco_lp;
+	else if (pll_28nm->phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_8226)
+		vco_init.ops = &clk_ops_dsi_pll_28nm_vco_8226;
+	else
+		vco_init.ops = &clk_ops_dsi_pll_28nm_vco_hpm;
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dvco_clk", pll_28nm->phy->id);
+	pll_28nm->clk_hw.init = &vco_init;
+	ret = devm_clk_hw_register(dev, &pll_28nm->clk_hw);
+	if (ret)
+		return ret;
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%danalog_postdiv_clk", pll_28nm->phy->id);
+	analog_postdiv = devm_clk_hw_register_divider_parent_hw(dev, clk_name,
+			&pll_28nm->clk_hw, CLK_SET_RATE_PARENT,
+			pll_28nm->phy->pll_base +
+				REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG,
+			0, 4, 0, NULL);
+	if (IS_ERR(analog_postdiv))
+		return PTR_ERR(analog_postdiv);
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dindirect_path_div2_clk", pll_28nm->phy->id);
+	indirect_path_div2 = devm_clk_hw_register_fixed_factor_parent_hw(dev,
+			clk_name, analog_postdiv, CLK_SET_RATE_PARENT, 1, 2);
+	if (IS_ERR(indirect_path_div2))
+		return PTR_ERR(indirect_path_div2);
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dpll", pll_28nm->phy->id);
+	hw = devm_clk_hw_register_divider_parent_hw(dev, clk_name,
+			&pll_28nm->clk_hw, 0, pll_28nm->phy->pll_base +
+				REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG,
+			0, 8, 0, NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+	provided_clocks[DSI_PIXEL_PLL_CLK] = hw;
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dbyte_mux", pll_28nm->phy->id);
+	byte_mux = devm_clk_hw_register_mux_parent_hws(dev, clk_name,
+			((const struct clk_hw *[]){
+				&pll_28nm->clk_hw,
+				indirect_path_div2,
+			}), 2, CLK_SET_RATE_PARENT, pll_28nm->phy->pll_base +
+				REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL);
+	if (IS_ERR(byte_mux))
+		return PTR_ERR(byte_mux);
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dpllbyte", pll_28nm->phy->id);
+	hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk_name,
+			byte_mux, CLK_SET_RATE_PARENT, 1, 4);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+	provided_clocks[DSI_BYTE_PLL_CLK] = hw;
+
+	return 0;
+}
+
+static int dsi_pll_28nm_init(struct msm_dsi_phy *phy)
+{
+	struct platform_device *pdev = phy->pdev;
+	struct dsi_pll_28nm *pll_28nm;
+	int ret;
+
+	if (!pdev)
+		return -ENODEV;
+
+	pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL);
+	if (!pll_28nm)
+		return -ENOMEM;
+
+	pll_28nm->phy = phy;
+
+	ret = pll_28nm_register(pll_28nm, phy->provided_clocks->hws);
+	if (ret) {
+		DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
+		return ret;
+	}
+
+	phy->vco_hw = &pll_28nm->clk_hw;
+
+	return 0;
+}
+
+static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy,
+		struct msm_dsi_dphy_timing *timing)
+{
+	void __iomem *base = phy->base;
+
+	dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_0,
+		      DSI_28nm_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero));
+	dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_1,
+		      DSI_28nm_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail));
+	dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_2,
+		      DSI_28nm_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare));
+	if (timing->clk_zero & BIT(8))
+		dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_3,
+			      DSI_28nm_PHY_TIMING_CTRL_3_CLK_ZERO_8);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_4,
+		      DSI_28nm_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit));
+	dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_5,
+		      DSI_28nm_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero));
+	dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_6,
+		      DSI_28nm_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare));
+	dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_7,
+		      DSI_28nm_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail));
+	dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_8,
+		      DSI_28nm_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst));
+	dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_9,
+		      DSI_28nm_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) |
+		      DSI_28nm_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure));
+	dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_10,
+		      DSI_28nm_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get));
+	dsi_phy_write(base + REG_DSI_28nm_PHY_TIMING_CTRL_11,
+		      DSI_28nm_PHY_TIMING_CTRL_11_TRIG3_CMD(0));
+}
+
+static void dsi_28nm_phy_regulator_enable_dcdc(struct msm_dsi_phy *phy)
+{
+	void __iomem *base = phy->reg_base;
+
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 1);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3, 0);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2, 0x3);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x9);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x7);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20);
+	dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x00);
+}
+
+static void dsi_28nm_phy_regulator_enable_ldo(struct msm_dsi_phy *phy)
+{
+	void __iomem *base = phy->reg_base;
+
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_0, 0x0);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_5, 0x7);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_3, 0);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_2, 0x1);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_1, 0x1);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20);
+
+	if (phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP)
+		dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x05);
+	else
+		dsi_phy_write(phy->base + REG_DSI_28nm_PHY_LDO_CNTRL, 0x0d);
+}
+
+static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable)
+{
+	if (!enable) {
+		dsi_phy_write(phy->reg_base +
+			      REG_DSI_28nm_PHY_REGULATOR_CAL_PWR_CFG, 0);
+		return;
+	}
+
+	if (phy->regulator_ldo_mode)
+		dsi_28nm_phy_regulator_enable_ldo(phy);
+	else
+		dsi_28nm_phy_regulator_enable_dcdc(phy);
+}
+
+static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy,
+				struct msm_dsi_phy_clk_request *clk_req)
+{
+	struct msm_dsi_dphy_timing *timing = &phy->timing;
+	int i;
+	void __iomem *base = phy->base;
+	u32 val;
+
+	DBG("");
+
+	if (msm_dsi_dphy_timing_calc(timing, clk_req)) {
+		DRM_DEV_ERROR(&phy->pdev->dev,
+			      "%s: D-PHY timing calculation failed\n",
+			      __func__);
+		return -EINVAL;
+	}
+
+	dsi_phy_write(base + REG_DSI_28nm_PHY_STRENGTH_0, 0xff);
+
+	dsi_28nm_phy_regulator_ctrl(phy, true);
+
+	dsi_28nm_dphy_set_timing(phy, timing);
+
+	dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_1, 0x00);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f);
+
+	dsi_phy_write(base + REG_DSI_28nm_PHY_STRENGTH_1, 0x6);
+
+	for (i = 0; i < 4; i++) {
+		dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_0(i), 0);
+		dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_1(i), 0);
+		dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_2(i), 0);
+		dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_3(i), 0);
+		dsi_phy_write(base + REG_DSI_28nm_PHY_LN_CFG_4(i), 0);
+		dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_DATAPATH(i), 0);
+		dsi_phy_write(base + REG_DSI_28nm_PHY_LN_DEBUG_SEL(i), 0);
+		dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_STR_0(i), 0x1);
+		dsi_phy_write(base + REG_DSI_28nm_PHY_LN_TEST_STR_1(i), 0x97);
+	}
+
+	dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_CFG_4, 0);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_CFG_1, 0xc0);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_TEST_STR0, 0x1);
+	dsi_phy_write(base + REG_DSI_28nm_PHY_LNCK_TEST_STR1, 0xbb);
+
+	dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f);
+
+	val = dsi_phy_read(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL);
+	if (phy->id == DSI_1 && phy->usecase == MSM_DSI_PHY_SLAVE)
+		val &= ~DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL;
+	else
+		val |= DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL;
+	dsi_phy_write(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL, val);
+
+	return 0;
+}
+
+static void dsi_28nm_phy_disable(struct msm_dsi_phy *phy)
+{
+	dsi_phy_write(phy->base + REG_DSI_28nm_PHY_CTRL_0, 0);
+	dsi_28nm_phy_regulator_ctrl(phy, false);
+
+	/*
+	 * Wait for the registers writes to complete in order to
+	 * ensure that the phy is completely disabled
+	 */
+	wmb();
+}
+
+static const struct regulator_bulk_data dsi_phy_28nm_regulators[] = {
+	{ .supply = "vddio", .init_load_uA = 100000 },
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs = {
+	.has_phy_regulator = true,
+	.regulator_data = dsi_phy_28nm_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_28nm_regulators),
+	.ops = {
+		.enable = dsi_28nm_phy_enable,
+		.disable = dsi_28nm_phy_disable,
+		.pll_init = dsi_pll_28nm_init,
+		.save_pll_state = dsi_28nm_pll_save_state,
+		.restore_pll_state = dsi_28nm_pll_restore_state,
+	},
+	.min_pll_rate = VCO_MIN_RATE,
+	.max_pll_rate = VCO_MAX_RATE,
+	.io_start = { 0xfd922b00, 0xfd923100 },
+	.num_dsi_phy = 2,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_famb_cfgs = {
+	.has_phy_regulator = true,
+	.regulator_data = dsi_phy_28nm_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_28nm_regulators),
+	.ops = {
+		.enable = dsi_28nm_phy_enable,
+		.disable = dsi_28nm_phy_disable,
+		.pll_init = dsi_pll_28nm_init,
+		.save_pll_state = dsi_28nm_pll_save_state,
+		.restore_pll_state = dsi_28nm_pll_restore_state,
+	},
+	.min_pll_rate = VCO_MIN_RATE,
+	.max_pll_rate = VCO_MAX_RATE,
+	.io_start = { 0x1a94400, 0x1a96400 },
+	.num_dsi_phy = 2,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs = {
+	.has_phy_regulator = true,
+	.regulator_data = dsi_phy_28nm_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_28nm_regulators),
+	.ops = {
+		.enable = dsi_28nm_phy_enable,
+		.disable = dsi_28nm_phy_disable,
+		.pll_init = dsi_pll_28nm_init,
+		.save_pll_state = dsi_28nm_pll_save_state,
+		.restore_pll_state = dsi_28nm_pll_restore_state,
+	},
+	.min_pll_rate = VCO_MIN_RATE,
+	.max_pll_rate = VCO_MAX_RATE,
+	.io_start = { 0x1a98500 },
+	.num_dsi_phy = 1,
+	.quirks = DSI_PHY_28NM_QUIRK_PHY_LP,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_28nm_8226_cfgs = {
+	.has_phy_regulator = true,
+	.regulator_data = dsi_phy_28nm_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_28nm_regulators),
+	.ops = {
+		.enable = dsi_28nm_phy_enable,
+		.disable = dsi_28nm_phy_disable,
+		.pll_init = dsi_pll_28nm_init,
+		.save_pll_state = dsi_28nm_pll_save_state,
+		.restore_pll_state = dsi_28nm_pll_restore_state,
+	},
+	.min_pll_rate = VCO_MIN_RATE,
+	.max_pll_rate = VCO_MAX_RATE,
+	.io_start = { 0xfd922b00 },
+	.num_dsi_phy = 1,
+	.quirks = DSI_PHY_28NM_QUIRK_PHY_8226,
+};
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy_28nm_8960.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy_28nm_8960.c
@@ -0,0 +1,660 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+
+#include "dsi_phy.h"
+#include "dsi.xml.h"
+#include "dsi_phy_28nm_8960.xml.h"
+
+/*
+ * DSI PLL 28nm (8960/A family) - clock diagram (eg: DSI1):
+ *
+ *
+ *                        +------+
+ *  dsi1vco_clk ----o-----| DIV1 |---dsi1pllbit (not exposed as clock)
+ *  F * byte_clk    |     +------+
+ *                  | bit clock divider (F / 8)
+ *                  |
+ *                  |     +------+
+ *                  o-----| DIV2 |---dsi0pllbyte---o---> To byte RCG
+ *                  |     +------+                 | (sets parent rate)
+ *                  | byte clock divider (F)       |
+ *                  |                              |
+ *                  |                              o---> To esc RCG
+ *                  |                                (doesn't set parent rate)
+ *                  |
+ *                  |     +------+
+ *                  o-----| DIV3 |----dsi0pll------o---> To dsi RCG
+ *                        +------+                 | (sets parent rate)
+ *                  dsi clock divider (F * magic)  |
+ *                                                 |
+ *                                                 o---> To pixel rcg
+ *                                                  (doesn't set parent rate)
+ */
+
+#define POLL_MAX_READS		8000
+#define POLL_TIMEOUT_US		1
+
+#define VCO_REF_CLK_RATE	27000000
+#define VCO_MIN_RATE		600000000
+#define VCO_MAX_RATE		1200000000
+
+#define VCO_PREF_DIV_RATIO	27
+
+struct pll_28nm_cached_state {
+	unsigned long vco_rate;
+	u8 postdiv3;
+	u8 postdiv2;
+	u8 postdiv1;
+};
+
+struct clk_bytediv {
+	struct clk_hw hw;
+	void __iomem *reg;
+};
+
+struct dsi_pll_28nm {
+	struct clk_hw clk_hw;
+
+	struct msm_dsi_phy *phy;
+
+	struct pll_28nm_cached_state cached_state;
+};
+
+#define to_pll_28nm(x)	container_of(x, struct dsi_pll_28nm, clk_hw)
+
+static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm,
+				    int nb_tries, int timeout_us)
+{
+	bool pll_locked = false;
+	u32 val;
+
+	while (nb_tries--) {
+		val = dsi_phy_read(pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_RDY);
+		pll_locked = !!(val & DSI_28nm_8960_PHY_PLL_RDY_PLL_RDY);
+
+		if (pll_locked)
+			break;
+
+		udelay(timeout_us);
+	}
+	DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* ");
+
+	return pll_locked;
+}
+
+/*
+ * Clock Callbacks
+ */
+static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long parent_rate)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
+	void __iomem *base = pll_28nm->phy->pll_base;
+	u32 val, temp, fb_divider;
+
+	DBG("rate=%lu, parent's=%lu", rate, parent_rate);
+
+	temp = rate / 10;
+	val = VCO_REF_CLK_RATE / 10;
+	fb_divider = (temp * VCO_PREF_DIV_RATIO) / val;
+	fb_divider = fb_divider / 2 - 1;
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1,
+		      fb_divider & 0xff);
+
+	val = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2);
+
+	val |= (fb_divider >> 8) & 0x07;
+
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2,
+		      val);
+
+	val = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3);
+
+	val |= (VCO_PREF_DIV_RATIO - 1) & 0x3f;
+
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3,
+		      val);
+
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_6,
+		      0xf);
+
+	val = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8);
+	val |= 0x7 << 4;
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8,
+		      val);
+
+	return 0;
+}
+
+static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
+
+	return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS,
+					POLL_TIMEOUT_US);
+}
+
+static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw,
+						  unsigned long parent_rate)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
+	void __iomem *base = pll_28nm->phy->pll_base;
+	unsigned long vco_rate;
+	u32 status, fb_divider, temp, ref_divider;
+
+	VERB("parent_rate=%lu", parent_rate);
+
+	status = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0);
+
+	if (status & DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE) {
+		fb_divider = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1);
+		fb_divider &= 0xff;
+		temp = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2) & 0x07;
+		fb_divider = (temp << 8) | fb_divider;
+		fb_divider += 1;
+
+		ref_divider = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3);
+		ref_divider &= 0x3f;
+		ref_divider += 1;
+
+		/* multiply by 2 */
+		vco_rate = (parent_rate / ref_divider) * fb_divider * 2;
+	} else {
+		vco_rate = 0;
+	}
+
+	DBG("returning vco rate = %lu", vco_rate);
+
+	return vco_rate;
+}
+
+static int dsi_pll_28nm_vco_prepare(struct clk_hw *hw)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
+	struct device *dev = &pll_28nm->phy->pdev->dev;
+	void __iomem *base = pll_28nm->phy->pll_base;
+	bool locked;
+	unsigned int bit_div, byte_div;
+	int max_reads = 1000, timeout_us = 100;
+	u32 val;
+
+	DBG("id=%d", pll_28nm->phy->id);
+
+	if (unlikely(pll_28nm->phy->pll_on))
+		return 0;
+
+	/*
+	 * before enabling the PLL, configure the bit clock divider since we
+	 * don't expose it as a clock to the outside world
+	 * 1: read back the byte clock divider that should already be set
+	 * 2: divide by 8 to get bit clock divider
+	 * 3: write it to POSTDIV1
+	 */
+	val = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9);
+	byte_div = val + 1;
+	bit_div = byte_div / 8;
+
+	val = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8);
+	val &= ~0xf;
+	val |= (bit_div - 1);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8, val);
+
+	/* enable the PLL */
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0,
+		      DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE);
+
+	locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us);
+
+	if (unlikely(!locked)) {
+		DRM_DEV_ERROR(dev, "DSI PLL lock failed\n");
+		return -EINVAL;
+	}
+
+	DBG("DSI PLL lock success");
+	pll_28nm->phy->pll_on = true;
+
+	return 0;
+}
+
+static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
+
+	DBG("id=%d", pll_28nm->phy->id);
+
+	if (unlikely(!pll_28nm->phy->pll_on))
+		return;
+
+	dsi_phy_write(pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, 0x00);
+
+	pll_28nm->phy->pll_on = false;
+}
+
+static long dsi_pll_28nm_clk_round_rate(struct clk_hw *hw,
+		unsigned long rate, unsigned long *parent_rate)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw);
+
+	if      (rate < pll_28nm->phy->cfg->min_pll_rate)
+		return  pll_28nm->phy->cfg->min_pll_rate;
+	else if (rate > pll_28nm->phy->cfg->max_pll_rate)
+		return  pll_28nm->phy->cfg->max_pll_rate;
+	else
+		return rate;
+}
+
+static const struct clk_ops clk_ops_dsi_pll_28nm_vco = {
+	.round_rate = dsi_pll_28nm_clk_round_rate,
+	.set_rate = dsi_pll_28nm_clk_set_rate,
+	.recalc_rate = dsi_pll_28nm_clk_recalc_rate,
+	.prepare = dsi_pll_28nm_vco_prepare,
+	.unprepare = dsi_pll_28nm_vco_unprepare,
+	.is_enabled = dsi_pll_28nm_clk_is_enabled,
+};
+
+/*
+ * Custom byte clock divier clk_ops
+ *
+ * This clock is the entry point to configuring the PLL. The user (dsi host)
+ * will set this clock's rate to the desired byte clock rate. The VCO lock
+ * frequency is a multiple of the byte clock rate. The multiplication factor
+ * (shown as F in the diagram above) is a function of the byte clock rate.
+ *
+ * This custom divider clock ensures that its parent (VCO) is set to the
+ * desired rate, and that the byte clock postdivider (POSTDIV2) is configured
+ * accordingly
+ */
+#define to_clk_bytediv(_hw) container_of(_hw, struct clk_bytediv, hw)
+
+static unsigned long clk_bytediv_recalc_rate(struct clk_hw *hw,
+		unsigned long parent_rate)
+{
+	struct clk_bytediv *bytediv = to_clk_bytediv(hw);
+	unsigned int div;
+
+	div = dsi_phy_read(bytediv->reg) & 0xff;
+
+	return parent_rate / (div + 1);
+}
+
+/* find multiplication factor(wrt byte clock) at which the VCO should be set */
+static unsigned int get_vco_mul_factor(unsigned long byte_clk_rate)
+{
+	unsigned long bit_mhz;
+
+	/* convert to bit clock in Mhz */
+	bit_mhz = (byte_clk_rate * 8) / 1000000;
+
+	if (bit_mhz < 125)
+		return 64;
+	else if (bit_mhz < 250)
+		return 32;
+	else if (bit_mhz < 600)
+		return 16;
+	else
+		return 8;
+}
+
+static long clk_bytediv_round_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long *prate)
+{
+	unsigned long best_parent;
+	unsigned int factor;
+
+	factor = get_vco_mul_factor(rate);
+
+	best_parent = rate * factor;
+	*prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent);
+
+	return *prate / factor;
+}
+
+static int clk_bytediv_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct clk_bytediv *bytediv = to_clk_bytediv(hw);
+	u32 val;
+	unsigned int factor;
+
+	factor = get_vco_mul_factor(rate);
+
+	val = dsi_phy_read(bytediv->reg);
+	val |= (factor - 1) & 0xff;
+	dsi_phy_write(bytediv->reg, val);
+
+	return 0;
+}
+
+/* Our special byte clock divider ops */
+static const struct clk_ops clk_bytediv_ops = {
+	.round_rate = clk_bytediv_round_rate,
+	.set_rate = clk_bytediv_set_rate,
+	.recalc_rate = clk_bytediv_recalc_rate,
+};
+
+/*
+ * PLL Callbacks
+ */
+static void dsi_28nm_pll_save_state(struct msm_dsi_phy *phy)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw);
+	struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
+	void __iomem *base = pll_28nm->phy->pll_base;
+
+	cached_state->postdiv3 =
+			dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10);
+	cached_state->postdiv2 =
+			dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9);
+	cached_state->postdiv1 =
+			dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8);
+
+	cached_state->vco_rate = clk_hw_get_rate(phy->vco_hw);
+}
+
+static int dsi_28nm_pll_restore_state(struct msm_dsi_phy *phy)
+{
+	struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw);
+	struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state;
+	void __iomem *base = pll_28nm->phy->pll_base;
+	int ret;
+
+	ret = dsi_pll_28nm_clk_set_rate(phy->vco_hw,
+					cached_state->vco_rate, 0);
+	if (ret) {
+		DRM_DEV_ERROR(&pll_28nm->phy->pdev->dev,
+			      "restore vco rate failed. ret=%d\n", ret);
+		return ret;
+	}
+
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10,
+		      cached_state->postdiv3);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9,
+		      cached_state->postdiv2);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8,
+		      cached_state->postdiv1);
+
+	return 0;
+}
+
+static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **provided_clocks)
+{
+	char clk_name[32];
+	struct clk_init_data vco_init = {
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "ref",
+		},
+		.num_parents = 1,
+		.flags = CLK_IGNORE_UNUSED,
+		.ops = &clk_ops_dsi_pll_28nm_vco,
+	};
+	struct device *dev = &pll_28nm->phy->pdev->dev;
+	struct clk_hw *hw;
+	struct clk_bytediv *bytediv;
+	struct clk_init_data bytediv_init = { };
+	int ret;
+
+	DBG("%d", pll_28nm->phy->id);
+
+	bytediv = devm_kzalloc(dev, sizeof(*bytediv), GFP_KERNEL);
+	if (!bytediv)
+		return -ENOMEM;
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dvco_clk", pll_28nm->phy->id);
+	vco_init.name = clk_name;
+
+	pll_28nm->clk_hw.init = &vco_init;
+
+	ret = devm_clk_hw_register(dev, &pll_28nm->clk_hw);
+	if (ret)
+		return ret;
+
+	/* prepare and register bytediv */
+	bytediv->hw.init = &bytediv_init;
+	bytediv->reg = pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9;
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dpllbyte", pll_28nm->phy->id + 1);
+
+	bytediv_init.name = clk_name;
+	bytediv_init.ops = &clk_bytediv_ops;
+	bytediv_init.flags = CLK_SET_RATE_PARENT;
+	bytediv_init.parent_hws = (const struct clk_hw*[]){
+		&pll_28nm->clk_hw,
+	};
+	bytediv_init.num_parents = 1;
+
+	/* DIV2 */
+	ret = devm_clk_hw_register(dev, &bytediv->hw);
+	if (ret)
+		return ret;
+	provided_clocks[DSI_BYTE_PLL_CLK] = &bytediv->hw;
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dpll", pll_28nm->phy->id + 1);
+	/* DIV3 */
+	hw = devm_clk_hw_register_divider_parent_hw(dev, clk_name,
+			&pll_28nm->clk_hw, 0, pll_28nm->phy->pll_base +
+				REG_DSI_28nm_8960_PHY_PLL_CTRL_10,
+			0, 8, 0, NULL);
+	if (IS_ERR(hw))
+		return PTR_ERR(hw);
+	provided_clocks[DSI_PIXEL_PLL_CLK] = hw;
+
+	return 0;
+}
+
+static int dsi_pll_28nm_8960_init(struct msm_dsi_phy *phy)
+{
+	struct platform_device *pdev = phy->pdev;
+	struct dsi_pll_28nm *pll_28nm;
+	int ret;
+
+	if (!pdev)
+		return -ENODEV;
+
+	pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL);
+	if (!pll_28nm)
+		return -ENOMEM;
+
+	pll_28nm->phy = phy;
+
+	ret = pll_28nm_register(pll_28nm, phy->provided_clocks->hws);
+	if (ret) {
+		DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
+		return ret;
+	}
+
+	phy->vco_hw = &pll_28nm->clk_hw;
+
+	return 0;
+}
+
+static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy,
+		struct msm_dsi_dphy_timing *timing)
+{
+	void __iomem *base = phy->base;
+
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_0,
+		      DSI_28nm_8960_PHY_TIMING_CTRL_0_CLK_ZERO(timing->clk_zero));
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_1,
+		      DSI_28nm_8960_PHY_TIMING_CTRL_1_CLK_TRAIL(timing->clk_trail));
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_2,
+		      DSI_28nm_8960_PHY_TIMING_CTRL_2_CLK_PREPARE(timing->clk_prepare));
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_3, 0x0);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_4,
+		      DSI_28nm_8960_PHY_TIMING_CTRL_4_HS_EXIT(timing->hs_exit));
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_5,
+		      DSI_28nm_8960_PHY_TIMING_CTRL_5_HS_ZERO(timing->hs_zero));
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_6,
+		      DSI_28nm_8960_PHY_TIMING_CTRL_6_HS_PREPARE(timing->hs_prepare));
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_7,
+		      DSI_28nm_8960_PHY_TIMING_CTRL_7_HS_TRAIL(timing->hs_trail));
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_8,
+		      DSI_28nm_8960_PHY_TIMING_CTRL_8_HS_RQST(timing->hs_rqst));
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_9,
+		      DSI_28nm_8960_PHY_TIMING_CTRL_9_TA_GO(timing->ta_go) |
+		      DSI_28nm_8960_PHY_TIMING_CTRL_9_TA_SURE(timing->ta_sure));
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_10,
+		      DSI_28nm_8960_PHY_TIMING_CTRL_10_TA_GET(timing->ta_get));
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_TIMING_CTRL_11,
+		      DSI_28nm_8960_PHY_TIMING_CTRL_11_TRIG3_CMD(0));
+}
+
+static void dsi_28nm_phy_regulator_init(struct msm_dsi_phy *phy)
+{
+	void __iomem *base = phy->reg_base;
+
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_0, 0x3);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_1, 1);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_2, 1);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_3, 0);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_4,
+		      0x100);
+}
+
+static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy)
+{
+	void __iomem *base = phy->reg_base;
+
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_0, 0x3);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_1, 0xa);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_2, 0x4);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_3, 0x0);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CTRL_4, 0x20);
+}
+
+static void dsi_28nm_phy_calibration(struct msm_dsi_phy *phy)
+{
+	void __iomem *base = phy->reg_base;
+	u32 status;
+	int i = 5000;
+
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_REGULATOR_CAL_PWR_CFG,
+		      0x3);
+
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_SW_CFG_2, 0x0);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_1, 0x5a);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_3, 0x10);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_4, 0x1);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_CFG_0, 0x1);
+
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_TRIGGER, 0x1);
+	usleep_range(5000, 6000);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_MISC_CAL_HW_TRIGGER, 0x0);
+
+	do {
+		status = dsi_phy_read(base +
+				REG_DSI_28nm_8960_PHY_MISC_CAL_STATUS);
+
+		if (!(status & DSI_28nm_8960_PHY_MISC_CAL_STATUS_CAL_BUSY))
+			break;
+
+		udelay(1);
+	} while (--i > 0);
+}
+
+static void dsi_28nm_phy_lane_config(struct msm_dsi_phy *phy)
+{
+	void __iomem *base = phy->base;
+	int i;
+
+	for (i = 0; i < 4; i++) {
+		dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_CFG_0(i), 0x80);
+		dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_CFG_1(i), 0x45);
+		dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_CFG_2(i), 0x00);
+		dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_TEST_DATAPATH(i),
+			      0x00);
+		dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_TEST_STR_0(i),
+			      0x01);
+		dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LN_TEST_STR_1(i),
+			      0x66);
+	}
+
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_CFG_0, 0x40);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_CFG_1, 0x67);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_CFG_2, 0x0);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_TEST_DATAPATH, 0x0);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_TEST_STR0, 0x1);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_TEST_STR1, 0x88);
+}
+
+static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy,
+				struct msm_dsi_phy_clk_request *clk_req)
+{
+	struct msm_dsi_dphy_timing *timing = &phy->timing;
+	void __iomem *base = phy->base;
+
+	DBG("");
+
+	if (msm_dsi_dphy_timing_calc(timing, clk_req)) {
+		DRM_DEV_ERROR(&phy->pdev->dev,
+			      "%s: D-PHY timing calculation failed\n",
+			      __func__);
+		return -EINVAL;
+	}
+
+	dsi_28nm_phy_regulator_init(phy);
+
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LDO_CTRL, 0x04);
+
+	/* strength control */
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_STRENGTH_0, 0xff);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_STRENGTH_1, 0x00);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_STRENGTH_2, 0x06);
+
+	/* phy ctrl */
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_0, 0x5f);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_1, 0x00);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_2, 0x00);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_CTRL_3, 0x10);
+
+	dsi_28nm_phy_regulator_ctrl(phy);
+
+	dsi_28nm_phy_calibration(phy);
+
+	dsi_28nm_phy_lane_config(phy);
+
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_4, 0x0f);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_1, 0x03);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_0, 0x03);
+	dsi_phy_write(base + REG_DSI_28nm_8960_PHY_BIST_CTRL_4, 0x0);
+
+	dsi_28nm_dphy_set_timing(phy, timing);
+
+	return 0;
+}
+
+static void dsi_28nm_phy_disable(struct msm_dsi_phy *phy)
+{
+	dsi_phy_write(phy->base + REG_DSI_28nm_8960_PHY_CTRL_0, 0x0);
+
+	/*
+	 * Wait for the registers writes to complete in order to
+	 * ensure that the phy is completely disabled
+	 */
+	wmb();
+}
+
+static const struct regulator_bulk_data dsi_phy_28nm_8960_regulators[] = {
+	{ .supply = "vddio", .init_load_uA = 100000 },	/* 1.8 V */
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs = {
+	.has_phy_regulator = true,
+	.regulator_data = dsi_phy_28nm_8960_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_28nm_8960_regulators),
+	.ops = {
+		.enable = dsi_28nm_phy_enable,
+		.disable = dsi_28nm_phy_disable,
+		.pll_init = dsi_pll_28nm_8960_init,
+		.save_pll_state = dsi_28nm_pll_save_state,
+		.restore_pll_state = dsi_28nm_pll_restore_state,
+	},
+	.min_pll_rate = VCO_MIN_RATE,
+	.max_pll_rate = VCO_MAX_RATE,
+	.io_start = { 0x4700300, 0x5800300 },
+	.num_dsi_phy = 2,
+};
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy_7nm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/dsi/phy/dsi_phy_7nm.c
@@ -0,0 +1,1347 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) 2018, The Linux Foundation
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/iopoll.h>
+
+#include "dsi_phy.h"
+#include "dsi.xml.h"
+#include "dsi_phy_7nm.xml.h"
+
+/*
+ * DSI PLL 7nm - clock diagram (eg: DSI0): TODO: updated CPHY diagram
+ *
+ *           dsi0_pll_out_div_clk  dsi0_pll_bit_clk
+ *                              |                |
+ *                              |                |
+ *                 +---------+  |  +----------+  |  +----+
+ *  dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk
+ *                 +---------+  |  +----------+  |  +----+
+ *                              |                |
+ *                              |                |         dsi0_pll_by_2_bit_clk
+ *                              |                |          |
+ *                              |                |  +----+  |  |\  dsi0_pclk_mux
+ *                              |                |--| /2 |--o--| \   |
+ *                              |                |  +----+     |  \  |  +---------+
+ *                              |                --------------|  |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk
+ *                              |------------------------------|  /     +---------+
+ *                              |          +-----+             | /
+ *                              -----------| /4? |--o----------|/
+ *                                         +-----+  |           |
+ *                                                  |           |dsiclk_sel
+ *                                                  |
+ *                                                  dsi0_pll_post_out_div_clk
+ */
+
+#define VCO_REF_CLK_RATE		19200000
+#define FRAC_BITS 18
+
+/* Hardware is pre V4.1 */
+#define DSI_PHY_7NM_QUIRK_PRE_V4_1	BIT(0)
+/* Hardware is V4.1 */
+#define DSI_PHY_7NM_QUIRK_V4_1		BIT(1)
+/* Hardware is V4.2 */
+#define DSI_PHY_7NM_QUIRK_V4_2		BIT(2)
+/* Hardware is V4.3 */
+#define DSI_PHY_7NM_QUIRK_V4_3		BIT(3)
+/* Hardware is V5.2 */
+#define DSI_PHY_7NM_QUIRK_V5_2		BIT(4)
+
+struct dsi_pll_config {
+	bool enable_ssc;
+	bool ssc_center;
+	u32 ssc_freq;
+	u32 ssc_offset;
+	u32 ssc_adj_per;
+
+	/* out */
+	u32 decimal_div_start;
+	u32 frac_div_start;
+	u32 pll_clock_inverters;
+	u32 ssc_stepsize;
+	u32 ssc_div_per;
+};
+
+struct pll_7nm_cached_state {
+	unsigned long vco_rate;
+	u8 bit_clk_div;
+	u8 pix_clk_div;
+	u8 pll_out_div;
+	u8 pll_mux;
+};
+
+struct dsi_pll_7nm {
+	struct clk_hw clk_hw;
+
+	struct msm_dsi_phy *phy;
+
+	u64 vco_current_rate;
+
+	/* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */
+	spinlock_t postdiv_lock;
+
+	struct pll_7nm_cached_state cached_state;
+
+	struct dsi_pll_7nm *slave;
+};
+
+#define to_pll_7nm(x)	container_of(x, struct dsi_pll_7nm, clk_hw)
+
+/*
+ * Global list of private DSI PLL struct pointers. We need this for bonded DSI
+ * mode, where the master PLL's clk_ops needs access the slave's private data
+ */
+static struct dsi_pll_7nm *pll_7nm_list[DSI_MAX];
+
+static void dsi_pll_setup_config(struct dsi_pll_config *config)
+{
+	config->ssc_freq = 31500;
+	config->ssc_offset = 4800;
+	config->ssc_adj_per = 2;
+
+	/* TODO: ssc enable */
+	config->enable_ssc = false;
+	config->ssc_center = 0;
+}
+
+static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
+{
+	u64 fref = VCO_REF_CLK_RATE;
+	u64 pll_freq;
+	u64 divider;
+	u64 dec, dec_multiple;
+	u32 frac;
+	u64 multiplier;
+
+	pll_freq = pll->vco_current_rate;
+
+	divider = fref * 2;
+
+	multiplier = 1 << FRAC_BITS;
+	dec_multiple = div_u64(pll_freq * multiplier, divider);
+	dec = div_u64_rem(dec_multiple, multiplier, &frac);
+
+	if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1)
+		config->pll_clock_inverters = 0x28;
+	else if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
+		if (pll_freq <= 1300000000ULL)
+			config->pll_clock_inverters = 0xa0;
+		else if (pll_freq <= 2500000000ULL)
+			config->pll_clock_inverters = 0x20;
+		else if (pll_freq <= 4000000000ULL)
+			config->pll_clock_inverters = 0x00;
+		else
+			config->pll_clock_inverters = 0x40;
+	} else if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
+		if (pll_freq <= 1000000000ULL)
+			config->pll_clock_inverters = 0xa0;
+		else if (pll_freq <= 2500000000ULL)
+			config->pll_clock_inverters = 0x20;
+		else if (pll_freq <= 3020000000ULL)
+			config->pll_clock_inverters = 0x00;
+		else
+			config->pll_clock_inverters = 0x40;
+	} else {
+		/* 4.2, 4.3 */
+		if (pll_freq <= 1000000000ULL)
+			config->pll_clock_inverters = 0xa0;
+		else if (pll_freq <= 2500000000ULL)
+			config->pll_clock_inverters = 0x20;
+		else if (pll_freq <= 3500000000ULL)
+			config->pll_clock_inverters = 0x00;
+		else
+			config->pll_clock_inverters = 0x40;
+	}
+
+	config->decimal_div_start = dec;
+	config->frac_div_start = frac;
+}
+
+#define SSC_CENTER		BIT(0)
+#define SSC_EN			BIT(1)
+
+static void dsi_pll_calc_ssc(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
+{
+	u32 ssc_per;
+	u32 ssc_mod;
+	u64 ssc_step_size;
+	u64 frac;
+
+	if (!config->enable_ssc) {
+		DBG("SSC not enabled\n");
+		return;
+	}
+
+	ssc_per = DIV_ROUND_CLOSEST(VCO_REF_CLK_RATE, config->ssc_freq) / 2 - 1;
+	ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1);
+	ssc_per -= ssc_mod;
+
+	frac = config->frac_div_start;
+	ssc_step_size = config->decimal_div_start;
+	ssc_step_size *= (1 << FRAC_BITS);
+	ssc_step_size += frac;
+	ssc_step_size *= config->ssc_offset;
+	ssc_step_size *= (config->ssc_adj_per + 1);
+	ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1));
+	ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000);
+
+	config->ssc_div_per = ssc_per;
+	config->ssc_stepsize = ssc_step_size;
+
+	pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n",
+		 config->decimal_div_start, frac, FRAC_BITS);
+	pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n",
+		 ssc_per, (u32)ssc_step_size, config->ssc_adj_per);
+}
+
+static void dsi_pll_ssc_commit(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
+{
+	void __iomem *base = pll->phy->pll_base;
+
+	if (config->enable_ssc) {
+		pr_debug("SSC is enabled\n");
+
+		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_LOW_1,
+			      config->ssc_stepsize & 0xff);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_HIGH_1,
+			      config->ssc_stepsize >> 8);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_LOW_1,
+			      config->ssc_div_per & 0xff);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_HIGH_1,
+			      config->ssc_div_per >> 8);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_LOW_1,
+			      config->ssc_adj_per & 0xff);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_HIGH_1,
+			      config->ssc_adj_per >> 8);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_SSC_CONTROL,
+			      SSC_EN | (config->ssc_center ? SSC_CENTER : 0));
+	}
+}
+
+static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll)
+{
+	void __iomem *base = pll->phy->pll_base;
+	u8 analog_controls_five_1 = 0x01, vco_config_1 = 0x00;
+
+	if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1))
+		if (pll->vco_current_rate >= 3100000000ULL)
+			analog_controls_five_1 = 0x03;
+
+	if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
+		if (pll->vco_current_rate < 1520000000ULL)
+			vco_config_1 = 0x08;
+		else if (pll->vco_current_rate < 2990000000ULL)
+			vco_config_1 = 0x01;
+	}
+
+	if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_2) ||
+	    (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3)) {
+		if (pll->vco_current_rate < 1520000000ULL)
+			vco_config_1 = 0x08;
+		else if (pll->vco_current_rate >= 2990000000ULL)
+			vco_config_1 = 0x01;
+	}
+
+	if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
+		if (pll->vco_current_rate < 1557000000ULL)
+			vco_config_1 = 0x08;
+		else
+			vco_config_1 = 0x01;
+	}
+
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE_1,
+		      analog_controls_five_1);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_VCO_CONFIG_1, vco_config_1);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE, 0x01);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_DSM_DIVIDER, 0x00);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE, 0xba);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_OUTDIV, 0x00);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CORE_OVERRIDE, 0x00);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, 0x08);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x0a);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_BAND_SEL_RATE_1, 0xc0);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x84);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x82);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x4c);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x29);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x2f);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_IFILT, 0x2a);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_IFILT,
+		  !(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1) ? 0x3f : 0x22);
+
+	if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1)) {
+		dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
+		if (pll->slave)
+			dsi_phy_write(pll->slave->phy->pll_base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22);
+	}
+}
+
+static void dsi_pll_commit(struct dsi_pll_7nm *pll, struct dsi_pll_config *config)
+{
+	void __iomem *base = pll->phy->pll_base;
+
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1,
+		      config->decimal_div_start);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1,
+		      config->frac_div_start & 0xff);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1,
+		      (config->frac_div_start & 0xff00) >> 8);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1,
+		      (config->frac_div_start & 0x30000) >> 16);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, 0x40);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1,
+		      pll->phy->cphy_mode ? 0x00 : 0x10);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS,
+		      config->pll_clock_inverters);
+}
+
+static int dsi_pll_7nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
+				     unsigned long parent_rate)
+{
+	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
+	struct dsi_pll_config config;
+
+	DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_7nm->phy->id, rate,
+	    parent_rate);
+
+	pll_7nm->vco_current_rate = rate;
+
+	dsi_pll_setup_config(&config);
+
+	dsi_pll_calc_dec_frac(pll_7nm, &config);
+
+	dsi_pll_calc_ssc(pll_7nm, &config);
+
+	dsi_pll_commit(pll_7nm, &config);
+
+	dsi_pll_config_hzindep_reg(pll_7nm);
+
+	dsi_pll_ssc_commit(pll_7nm, &config);
+
+	/* flush, ensure all register writes are done*/
+	wmb();
+
+	return 0;
+}
+
+static int dsi_pll_7nm_lock_status(struct dsi_pll_7nm *pll)
+{
+	int rc;
+	u32 status = 0;
+	u32 const delay_us = 100;
+	u32 const timeout_us = 5000;
+
+	rc = readl_poll_timeout_atomic(pll->phy->pll_base +
+				       REG_DSI_7nm_PHY_PLL_COMMON_STATUS_ONE,
+				       status,
+				       ((status & BIT(0)) > 0),
+				       delay_us,
+				       timeout_us);
+	if (rc)
+		pr_err("DSI PLL(%d) lock failed, status=0x%08x\n",
+		       pll->phy->id, status);
+
+	return rc;
+}
+
+static void dsi_pll_disable_pll_bias(struct dsi_pll_7nm *pll)
+{
+	u32 data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);
+
+	dsi_phy_write(pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0);
+	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0, data & ~BIT(5));
+	ndelay(250);
+}
+
+static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll)
+{
+	u32 data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0);
+
+	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0, data | BIT(5));
+	dsi_phy_write(pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0xc0);
+	ndelay(250);
+}
+
+static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll)
+{
+	u32 data;
+
+	data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
+	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data & ~BIT(5));
+}
+
+static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll)
+{
+	u32 data;
+
+	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x04);
+
+	data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
+	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1,
+		      data | BIT(5) | BIT(4));
+}
+
+static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll)
+{
+	/*
+	 * Reset the PHY digital domain. This would be needed when
+	 * coming out of a CX or analog rail power collapse while
+	 * ensuring that the pads maintain LP00 or LP11 state
+	 */
+	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, BIT(0));
+	wmb(); /* Ensure that the reset is deasserted */
+	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, 0x0);
+	wmb(); /* Ensure that the reset is deasserted */
+}
+
+static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw)
+{
+	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
+	int rc;
+
+	dsi_pll_enable_pll_bias(pll_7nm);
+	if (pll_7nm->slave)
+		dsi_pll_enable_pll_bias(pll_7nm->slave);
+
+	/* Start PLL */
+	dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x01);
+
+	/*
+	 * ensure all PLL configurations are written prior to checking
+	 * for PLL lock.
+	 */
+	wmb();
+
+	/* Check for PLL lock */
+	rc = dsi_pll_7nm_lock_status(pll_7nm);
+	if (rc) {
+		pr_err("PLL(%d) lock failed\n", pll_7nm->phy->id);
+		goto error;
+	}
+
+	pll_7nm->phy->pll_on = true;
+
+	/*
+	 * assert power on reset for PHY digital in case the PLL is
+	 * enabled after CX of analog domain power collapse. This needs
+	 * to be done before enabling the global clk.
+	 */
+	dsi_pll_phy_dig_reset(pll_7nm);
+	if (pll_7nm->slave)
+		dsi_pll_phy_dig_reset(pll_7nm->slave);
+
+	dsi_pll_enable_global_clk(pll_7nm);
+	if (pll_7nm->slave)
+		dsi_pll_enable_global_clk(pll_7nm->slave);
+
+error:
+	return rc;
+}
+
+static void dsi_pll_disable_sub(struct dsi_pll_7nm *pll)
+{
+	dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0);
+	dsi_pll_disable_pll_bias(pll);
+}
+
+static void dsi_pll_7nm_vco_unprepare(struct clk_hw *hw)
+{
+	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
+
+	/*
+	 * To avoid any stray glitches while abruptly powering down the PLL
+	 * make sure to gate the clock using the clock enable bit before
+	 * powering down the PLL
+	 */
+	dsi_pll_disable_global_clk(pll_7nm);
+	dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0);
+	dsi_pll_disable_sub(pll_7nm);
+	if (pll_7nm->slave) {
+		dsi_pll_disable_global_clk(pll_7nm->slave);
+		dsi_pll_disable_sub(pll_7nm->slave);
+	}
+	/* flush, ensure all register writes are done */
+	wmb();
+	pll_7nm->phy->pll_on = false;
+}
+
+static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw,
+						  unsigned long parent_rate)
+{
+	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
+	void __iomem *base = pll_7nm->phy->pll_base;
+	u64 ref_clk = VCO_REF_CLK_RATE;
+	u64 vco_rate = 0x0;
+	u64 multiplier;
+	u32 frac;
+	u32 dec;
+	u64 pll_freq, tmp64;
+
+	dec = dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1);
+	dec &= 0xff;
+
+	frac = dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1);
+	frac |= ((dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1) &
+		  0xff) << 8);
+	frac |= ((dsi_phy_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1) &
+		  0x3) << 16);
+
+	/*
+	 * TODO:
+	 *	1. Assumes prescaler is disabled
+	 */
+	multiplier = 1 << FRAC_BITS;
+	pll_freq = dec * (ref_clk * 2);
+	tmp64 = (ref_clk * 2 * frac);
+	pll_freq += div_u64(tmp64, multiplier);
+
+	vco_rate = pll_freq;
+	pll_7nm->vco_current_rate = vco_rate;
+
+	DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x",
+	    pll_7nm->phy->id, (unsigned long)vco_rate, dec, frac);
+
+	return (unsigned long)vco_rate;
+}
+
+static long dsi_pll_7nm_clk_round_rate(struct clk_hw *hw,
+		unsigned long rate, unsigned long *parent_rate)
+{
+	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw);
+
+	if      (rate < pll_7nm->phy->cfg->min_pll_rate)
+		return  pll_7nm->phy->cfg->min_pll_rate;
+	else if (rate > pll_7nm->phy->cfg->max_pll_rate)
+		return  pll_7nm->phy->cfg->max_pll_rate;
+	else
+		return rate;
+}
+
+static const struct clk_ops clk_ops_dsi_pll_7nm_vco = {
+	.round_rate = dsi_pll_7nm_clk_round_rate,
+	.set_rate = dsi_pll_7nm_vco_set_rate,
+	.recalc_rate = dsi_pll_7nm_vco_recalc_rate,
+	.prepare = dsi_pll_7nm_vco_prepare,
+	.unprepare = dsi_pll_7nm_vco_unprepare,
+};
+
+/*
+ * PLL Callbacks
+ */
+
+static void dsi_7nm_pll_save_state(struct msm_dsi_phy *phy)
+{
+	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);
+	struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;
+	void __iomem *phy_base = pll_7nm->phy->base;
+	u32 cmn_clk_cfg0, cmn_clk_cfg1;
+
+	cached->pll_out_div = dsi_phy_read(pll_7nm->phy->pll_base +
+			REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);
+	cached->pll_out_div &= 0x3;
+
+	cmn_clk_cfg0 = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0);
+	cached->bit_clk_div = cmn_clk_cfg0 & 0xf;
+	cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4;
+
+	cmn_clk_cfg1 = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
+	cached->pll_mux = cmn_clk_cfg1 & 0x3;
+
+	DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x",
+	    pll_7nm->phy->id, cached->pll_out_div, cached->bit_clk_div,
+	    cached->pix_clk_div, cached->pll_mux);
+}
+
+static int dsi_7nm_pll_restore_state(struct msm_dsi_phy *phy)
+{
+	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);
+	struct pll_7nm_cached_state *cached = &pll_7nm->cached_state;
+	void __iomem *phy_base = pll_7nm->phy->base;
+	u32 val;
+	int ret;
+
+	val = dsi_phy_read(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE);
+	val &= ~0x3;
+	val |= cached->pll_out_div;
+	dsi_phy_write(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, val);
+
+	dsi_phy_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0,
+		      cached->bit_clk_div | (cached->pix_clk_div << 4));
+
+	val = dsi_phy_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
+	val &= ~0x3;
+	val |= cached->pll_mux;
+	dsi_phy_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, val);
+
+	ret = dsi_pll_7nm_vco_set_rate(phy->vco_hw,
+			pll_7nm->vco_current_rate,
+			VCO_REF_CLK_RATE);
+	if (ret) {
+		DRM_DEV_ERROR(&pll_7nm->phy->pdev->dev,
+			"restore vco rate failed. ret=%d\n", ret);
+		return ret;
+	}
+
+	DBG("DSI PLL%d", pll_7nm->phy->id);
+
+	return 0;
+}
+
+static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy)
+{
+	struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw);
+	void __iomem *base = phy->base;
+	u32 data = 0x0;	/* internal PLL */
+
+	DBG("DSI PLL%d", pll_7nm->phy->id);
+
+	switch (phy->usecase) {
+	case MSM_DSI_PHY_STANDALONE:
+		break;
+	case MSM_DSI_PHY_MASTER:
+		pll_7nm->slave = pll_7nm_list[(pll_7nm->phy->id + 1) % DSI_MAX];
+		break;
+	case MSM_DSI_PHY_SLAVE:
+		data = 0x1; /* external PLL */
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* set PLL src */
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, (data << 2));
+
+	return 0;
+}
+
+/*
+ * The post dividers and mux clocks are created using the standard divider and
+ * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux
+ * state to follow the master PLL's divider/mux state. Therefore, we don't
+ * require special clock ops that also configure the slave PLL registers
+ */
+static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provided_clocks)
+{
+	char clk_name[32];
+	struct clk_init_data vco_init = {
+		.parent_data = &(const struct clk_parent_data) {
+			.fw_name = "ref",
+		},
+		.num_parents = 1,
+		.name = clk_name,
+		.flags = CLK_IGNORE_UNUSED,
+		.ops = &clk_ops_dsi_pll_7nm_vco,
+	};
+	struct device *dev = &pll_7nm->phy->pdev->dev;
+	struct clk_hw *hw, *pll_out_div, *pll_bit, *pll_by_2_bit;
+	struct clk_hw *pll_post_out_div, *phy_pll_out_dsi_parent;
+	int ret;
+
+	DBG("DSI%d", pll_7nm->phy->id);
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%dvco_clk", pll_7nm->phy->id);
+	pll_7nm->clk_hw.init = &vco_init;
+
+	ret = devm_clk_hw_register(dev, &pll_7nm->clk_hw);
+	if (ret)
+		return ret;
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_out_div_clk", pll_7nm->phy->id);
+
+	pll_out_div = devm_clk_hw_register_divider_parent_hw(dev, clk_name,
+			&pll_7nm->clk_hw, CLK_SET_RATE_PARENT,
+			pll_7nm->phy->pll_base +
+				REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE,
+			0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL);
+	if (IS_ERR(pll_out_div)) {
+		ret = PTR_ERR(pll_out_div);
+		goto fail;
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_bit_clk", pll_7nm->phy->id);
+
+	/* BIT CLK: DIV_CTRL_3_0 */
+	pll_bit = devm_clk_hw_register_divider_parent_hw(dev, clk_name,
+			pll_out_div, CLK_SET_RATE_PARENT,
+			pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG0,
+			0, 4, CLK_DIVIDER_ONE_BASED, &pll_7nm->postdiv_lock);
+	if (IS_ERR(pll_bit)) {
+		ret = PTR_ERR(pll_bit);
+		goto fail;
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%d_phy_pll_out_byteclk", pll_7nm->phy->id);
+
+	/* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */
+	hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk_name,
+			pll_bit, CLK_SET_RATE_PARENT, 1,
+			pll_7nm->phy->cphy_mode ? 7 : 8);
+	if (IS_ERR(hw)) {
+		ret = PTR_ERR(hw);
+		goto fail;
+	}
+
+	provided_clocks[DSI_BYTE_PLL_CLK] = hw;
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_by_2_bit_clk", pll_7nm->phy->id);
+
+	pll_by_2_bit = devm_clk_hw_register_fixed_factor_parent_hw(dev,
+			clk_name, pll_bit, 0, 1, 2);
+	if (IS_ERR(pll_by_2_bit)) {
+		ret = PTR_ERR(pll_by_2_bit);
+		goto fail;
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id);
+
+	if (pll_7nm->phy->cphy_mode)
+		pll_post_out_div = devm_clk_hw_register_fixed_factor_parent_hw(
+				dev, clk_name, pll_out_div, 0, 2, 7);
+	else
+		pll_post_out_div = devm_clk_hw_register_fixed_factor_parent_hw(
+				dev, clk_name, pll_out_div, 0, 1, 4);
+	if (IS_ERR(pll_post_out_div)) {
+		ret = PTR_ERR(pll_post_out_div);
+		goto fail;
+	}
+
+	/* in CPHY mode, pclk_mux will always have post_out_div as parent
+	 * don't register a pclk_mux clock and just use post_out_div instead
+	 */
+	if (pll_7nm->phy->cphy_mode) {
+		u32 data;
+
+		data = dsi_phy_read(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1);
+		dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data | 3);
+
+		phy_pll_out_dsi_parent = pll_post_out_div;
+	} else {
+		snprintf(clk_name, sizeof(clk_name), "dsi%d_pclk_mux", pll_7nm->phy->id);
+
+		hw = devm_clk_hw_register_mux_parent_hws(dev, clk_name,
+				((const struct clk_hw *[]){
+					pll_bit,
+					pll_by_2_bit,
+				}), 2, 0, pll_7nm->phy->base +
+					REG_DSI_7nm_PHY_CMN_CLK_CFG1,
+				0, 1, 0, NULL);
+		if (IS_ERR(hw)) {
+			ret = PTR_ERR(hw);
+			goto fail;
+		}
+
+		phy_pll_out_dsi_parent = hw;
+	}
+
+	snprintf(clk_name, sizeof(clk_name), "dsi%d_phy_pll_out_dsiclk", pll_7nm->phy->id);
+
+	/* PIX CLK DIV : DIV_CTRL_7_4*/
+	hw = devm_clk_hw_register_divider_parent_hw(dev, clk_name,
+			phy_pll_out_dsi_parent, 0,
+			pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG0,
+			4, 4, CLK_DIVIDER_ONE_BASED, &pll_7nm->postdiv_lock);
+	if (IS_ERR(hw)) {
+		ret = PTR_ERR(hw);
+		goto fail;
+	}
+
+	provided_clocks[DSI_PIXEL_PLL_CLK] = hw;
+
+	return 0;
+
+fail:
+
+	return ret;
+}
+
+static int dsi_pll_7nm_init(struct msm_dsi_phy *phy)
+{
+	struct platform_device *pdev = phy->pdev;
+	struct dsi_pll_7nm *pll_7nm;
+	int ret;
+
+	pll_7nm = devm_kzalloc(&pdev->dev, sizeof(*pll_7nm), GFP_KERNEL);
+	if (!pll_7nm)
+		return -ENOMEM;
+
+	DBG("DSI PLL%d", phy->id);
+
+	pll_7nm_list[phy->id] = pll_7nm;
+
+	spin_lock_init(&pll_7nm->postdiv_lock);
+
+	pll_7nm->phy = phy;
+
+	ret = pll_7nm_register(pll_7nm, phy->provided_clocks->hws);
+	if (ret) {
+		DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret);
+		return ret;
+	}
+
+	phy->vco_hw = &pll_7nm->clk_hw;
+
+	/* TODO: Remove this when we have proper display handover support */
+	msm_dsi_phy_pll_save_state(phy);
+
+	return 0;
+}
+
+static int dsi_phy_hw_v4_0_is_pll_on(struct msm_dsi_phy *phy)
+{
+	void __iomem *base = phy->base;
+	u32 data = 0;
+
+	data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL);
+	mb(); /* make sure read happened */
+
+	return (data & BIT(0));
+}
+
+static void dsi_phy_hw_v4_0_config_lpcdrx(struct msm_dsi_phy *phy, bool enable)
+{
+	void __iomem *lane_base = phy->lane_base;
+	int phy_lane_0 = 0;	/* TODO: Support all lane swap configs */
+
+	/*
+	 * LPRX and CDRX need to enabled only for physical data lane
+	 * corresponding to the logical data lane 0
+	 */
+	if (enable)
+		dsi_phy_write(lane_base +
+			      REG_DSI_7nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0x3);
+	else
+		dsi_phy_write(lane_base +
+			      REG_DSI_7nm_PHY_LN_LPRX_CTRL(phy_lane_0), 0);
+}
+
+static void dsi_phy_hw_v4_0_lane_settings(struct msm_dsi_phy *phy)
+{
+	int i;
+	const u8 tx_dctrl_0[] = { 0x00, 0x00, 0x00, 0x04, 0x01 };
+	const u8 tx_dctrl_1[] = { 0x40, 0x40, 0x40, 0x46, 0x41 };
+	const u8 *tx_dctrl = tx_dctrl_0;
+	void __iomem *lane_base = phy->lane_base;
+
+	if (!(phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1))
+		tx_dctrl = tx_dctrl_1;
+
+	/* Strength ctrl settings */
+	for (i = 0; i < 5; i++) {
+		/*
+		 * Disable LPRX and CDRX for all lanes. And later on, it will
+		 * be only enabled for the physical data lane corresponding
+		 * to the logical data lane 0
+		 */
+		dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_LPRX_CTRL(i), 0);
+		dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_PIN_SWAP(i), 0x0);
+	}
+
+	dsi_phy_hw_v4_0_config_lpcdrx(phy, true);
+
+	/* other settings */
+	for (i = 0; i < 5; i++) {
+		dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG0(i), 0x0);
+		dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG1(i), 0x0);
+		dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_CFG2(i), i == 4 ? 0x8a : 0xa);
+		dsi_phy_write(lane_base + REG_DSI_7nm_PHY_LN_TX_DCTRL(i), tx_dctrl[i]);
+	}
+}
+
+static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy,
+			      struct msm_dsi_phy_clk_request *clk_req)
+{
+	int ret;
+	u32 status;
+	u32 const delay_us = 5;
+	u32 const timeout_us = 1000;
+	struct msm_dsi_dphy_timing *timing = &phy->timing;
+	void __iomem *base = phy->base;
+	bool less_than_1500_mhz;
+	u32 vreg_ctrl_0, vreg_ctrl_1, lane_ctrl0;
+	u32 glbl_pemph_ctrl_0;
+	u32 glbl_str_swi_cal_sel_ctrl, glbl_hstx_str_ctrl_0;
+	u32 glbl_rescode_top_ctrl, glbl_rescode_bot_ctrl;
+	u32 data;
+
+	DBG("");
+
+	if (phy->cphy_mode)
+		ret = msm_dsi_cphy_timing_calc_v4(timing, clk_req);
+	else
+		ret = msm_dsi_dphy_timing_calc_v4(timing, clk_req);
+	if (ret) {
+		DRM_DEV_ERROR(&phy->pdev->dev,
+			      "%s: PHY timing calculation failed\n", __func__);
+		return -EINVAL;
+	}
+
+	if (dsi_phy_hw_v4_0_is_pll_on(phy))
+		pr_warn("PLL turned on before configuring PHY\n");
+
+	/* Request for REFGEN READY */
+	if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3) ||
+	    (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
+		dsi_phy_write(phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10, 0x1);
+		udelay(500);
+	}
+
+	/* wait for REFGEN READY */
+	ret = readl_poll_timeout_atomic(base + REG_DSI_7nm_PHY_CMN_PHY_STATUS,
+					status, (status & BIT(0)),
+					delay_us, timeout_us);
+	if (ret) {
+		pr_err("Ref gen not ready. Aborting\n");
+		return -EINVAL;
+	}
+
+	/* TODO: CPHY enable path (this is for DPHY only) */
+
+	/* Alter PHY configurations if data rate less than 1.5GHZ*/
+	less_than_1500_mhz = (clk_req->bitclk_rate <= 1500000000);
+
+	glbl_str_swi_cal_sel_ctrl = 0x00;
+	if (phy->cphy_mode) {
+		vreg_ctrl_0 = 0x51;
+		vreg_ctrl_1 = 0x55;
+		glbl_hstx_str_ctrl_0 = 0x00;
+		glbl_pemph_ctrl_0 = 0x11;
+		lane_ctrl0 = 0x17;
+	} else {
+		vreg_ctrl_0 = less_than_1500_mhz ? 0x53 : 0x52;
+		vreg_ctrl_1 = 0x5c;
+		glbl_hstx_str_ctrl_0 = 0x88;
+		glbl_pemph_ctrl_0 = 0x00;
+		lane_ctrl0 = 0x1f;
+	}
+
+	if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
+		if (phy->cphy_mode) {
+			vreg_ctrl_0 = 0x45;
+			vreg_ctrl_1 = 0x41;
+			glbl_rescode_top_ctrl = 0x00;
+			glbl_rescode_bot_ctrl = 0x00;
+		} else {
+			vreg_ctrl_0 = 0x44;
+			vreg_ctrl_1 = 0x19;
+			glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3c :  0x03;
+			glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 :  0x3c;
+		}
+	} else if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3)) {
+		if (phy->cphy_mode) {
+			glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d :  0x01;
+			glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 :  0x3b;
+		} else {
+			glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d :  0x01;
+			glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 :  0x39;
+		}
+	} else if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_2) {
+		if (phy->cphy_mode) {
+			glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d :  0x01;
+			glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 :  0x3b;
+		} else {
+			glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3c :  0x00;
+			glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x38 :  0x39;
+		}
+	} else if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) {
+		if (phy->cphy_mode) {
+			glbl_hstx_str_ctrl_0 = 0x88;
+			glbl_rescode_top_ctrl = 0x00;
+			glbl_rescode_bot_ctrl = 0x3c;
+		} else {
+			glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d :  0x00;
+			glbl_rescode_bot_ctrl = less_than_1500_mhz ? 0x39 :  0x3c;
+		}
+	} else {
+		if (phy->cphy_mode) {
+			glbl_str_swi_cal_sel_ctrl = 0x03;
+			glbl_hstx_str_ctrl_0 = 0x66;
+		} else {
+			vreg_ctrl_0 = less_than_1500_mhz ? 0x5B : 0x59;
+			glbl_str_swi_cal_sel_ctrl = less_than_1500_mhz ? 0x03 : 0x00;
+			glbl_hstx_str_ctrl_0 = less_than_1500_mhz ? 0x66 : 0x88;
+		}
+		glbl_rescode_top_ctrl = 0x03;
+		glbl_rescode_bot_ctrl = 0x3c;
+	}
+
+	/* de-assert digital and pll power down */
+	data = BIT(6) | BIT(5);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, data);
+
+	/* Assert PLL core reset */
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x00);
+
+	/* turn off resync FIFO */
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0x00);
+
+	/* program CMN_CTRL_4 for minor_ver 2 chipsets*/
+	if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2) ||
+	    (dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_REVISION_ID0) & (0xf0)) == 0x20)
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_4, 0x04);
+
+	/* Configure PHY lane swap (TODO: we need to calculate this) */
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CFG0, 0x21);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CFG1, 0x84);
+
+	if (phy->cphy_mode)
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_CTRL, BIT(6));
+
+	/* Enable LDO */
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_0, vreg_ctrl_0);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_VREG_CTRL_1, vreg_ctrl_1);
+
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x00);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_STR_SWI_CAL_SEL_CTRL,
+		      glbl_str_swi_cal_sel_ctrl);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_HSTX_STR_CTRL_0,
+		      glbl_hstx_str_ctrl_0);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_0,
+		      glbl_pemph_ctrl_0);
+	if (phy->cphy_mode)
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_PEMPH_CTRL_1, 0x01);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_TOP_CTRL,
+		      glbl_rescode_top_ctrl);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_RESCODE_OFFSET_BOT_CTRL,
+		      glbl_rescode_bot_ctrl);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_LPTX_STR_CTRL, 0x55);
+
+	/* Remove power down from all blocks */
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, 0x7f);
+
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0, lane_ctrl0);
+
+	/* Select full-rate mode */
+	if (!phy->cphy_mode)
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_2, 0x40);
+
+	ret = dsi_7nm_set_usecase(phy);
+	if (ret) {
+		DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n",
+			__func__, ret);
+		return ret;
+	}
+
+	/* DSI PHY timings */
+	if (phy->cphy_mode) {
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0, 0x00);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4, timing->hs_exit);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5,
+			      timing->shared_timings.clk_pre);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6, timing->clk_prepare);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7,
+			      timing->shared_timings.clk_post);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8, timing->hs_rqst);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9, 0x02);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10, 0x04);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11, 0x00);
+	} else {
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_0, 0x00);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_1, timing->clk_zero);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_2, timing->clk_prepare);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_3, timing->clk_trail);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_4, timing->hs_exit);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_5, timing->hs_zero);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_6, timing->hs_prepare);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_7, timing->hs_trail);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_8, timing->hs_rqst);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_9, 0x02);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_10, 0x04);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_11, 0x00);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_12,
+			      timing->shared_timings.clk_pre);
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_TIMING_CTRL_13,
+			      timing->shared_timings.clk_post);
+	}
+
+	/* DSI lane settings */
+	dsi_phy_hw_v4_0_lane_settings(phy);
+
+	DBG("DSI%d PHY enabled", phy->id);
+
+	return 0;
+}
+
+static bool dsi_7nm_set_continuous_clock(struct msm_dsi_phy *phy, bool enable)
+{
+	void __iomem *base = phy->base;
+	u32 data;
+
+	data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL1);
+	if (enable)
+		data |= BIT(5) | BIT(6);
+	else
+		data &= ~(BIT(5) | BIT(6));
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL1, data);
+
+	return enable;
+}
+
+static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy)
+{
+	void __iomem *base = phy->base;
+	u32 data;
+
+	DBG("");
+
+	if (dsi_phy_hw_v4_0_is_pll_on(phy))
+		pr_warn("Turning OFF PHY while PLL is on\n");
+
+	dsi_phy_hw_v4_0_config_lpcdrx(phy, false);
+
+	/* Turn off REFGEN Vote */
+	if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3) ||
+	    (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2)) {
+		dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10, 0x0);
+		wmb();
+		/* Delay to ensure HW removes vote before PHY shut down */
+		udelay(2);
+	}
+
+	data = dsi_phy_read(base + REG_DSI_7nm_PHY_CMN_CTRL_0);
+
+	/* disable all lanes */
+	data &= ~0x1F;
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, data);
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_LANE_CTRL0, 0);
+
+	/* Turn off all PHY blocks */
+	dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_0, 0x00);
+	/* make sure phy is turned off */
+	wmb();
+
+	DBG("DSI%d PHY disabled", phy->id);
+}
+
+static const struct regulator_bulk_data dsi_phy_7nm_36mA_regulators[] = {
+	{ .supply = "vdds", .init_load_uA = 36000 },
+};
+
+static const struct regulator_bulk_data dsi_phy_7nm_37750uA_regulators[] = {
+	{ .supply = "vdds", .init_load_uA = 37550 },
+};
+
+static const struct regulator_bulk_data dsi_phy_7nm_115000uA_regulators[] = {
+	{ .supply = "vdds", .init_load_uA = 115000 },
+};
+
+static const struct regulator_bulk_data dsi_phy_7nm_98000uA_regulators[] = {
+	{ .supply = "vdds", .init_load_uA = 98000 },
+};
+
+static const struct regulator_bulk_data dsi_phy_7nm_97800uA_regulators[] = {
+	{ .supply = "vdds", .init_load_uA = 97800 },
+};
+
+static const struct regulator_bulk_data dsi_phy_7nm_98400uA_regulators[] = {
+	{ .supply = "vdds", .init_load_uA = 98400 },
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs = {
+	.has_phy_lane = true,
+	.regulator_data = dsi_phy_7nm_36mA_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_36mA_regulators),
+	.ops = {
+		.enable = dsi_7nm_phy_enable,
+		.disable = dsi_7nm_phy_disable,
+		.pll_init = dsi_pll_7nm_init,
+		.save_pll_state = dsi_7nm_pll_save_state,
+		.restore_pll_state = dsi_7nm_pll_restore_state,
+		.set_continuous_clock = dsi_7nm_set_continuous_clock,
+	},
+	.min_pll_rate = 600000000UL,
+#ifdef CONFIG_64BIT
+	.max_pll_rate = 5000000000UL,
+#else
+	.max_pll_rate = ULONG_MAX,
+#endif
+	.io_start = { 0xae94400, 0xae96400 },
+	.num_dsi_phy = 2,
+	.quirks = DSI_PHY_7NM_QUIRK_V4_1,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_7nm_6375_cfgs = {
+	.has_phy_lane = true,
+	.ops = {
+		.enable = dsi_7nm_phy_enable,
+		.disable = dsi_7nm_phy_disable,
+		.pll_init = dsi_pll_7nm_init,
+		.save_pll_state = dsi_7nm_pll_save_state,
+		.restore_pll_state = dsi_7nm_pll_restore_state,
+	},
+	.min_pll_rate = 600000000UL,
+#ifdef CONFIG_64BIT
+	.max_pll_rate = 5000000000ULL,
+#else
+	.max_pll_rate = ULONG_MAX,
+#endif
+	.io_start = { 0x5e94400 },
+	.num_dsi_phy = 1,
+	.quirks = DSI_PHY_7NM_QUIRK_V4_1,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs = {
+	.has_phy_lane = true,
+	.regulator_data = dsi_phy_7nm_36mA_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_36mA_regulators),
+	.ops = {
+		.enable = dsi_7nm_phy_enable,
+		.disable = dsi_7nm_phy_disable,
+		.pll_init = dsi_pll_7nm_init,
+		.save_pll_state = dsi_7nm_pll_save_state,
+		.restore_pll_state = dsi_7nm_pll_restore_state,
+		.set_continuous_clock = dsi_7nm_set_continuous_clock,
+	},
+	.min_pll_rate = 1000000000UL,
+	.max_pll_rate = 3500000000UL,
+	.io_start = { 0xae94400, 0xae96400 },
+	.num_dsi_phy = 2,
+	.quirks = DSI_PHY_7NM_QUIRK_PRE_V4_1,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_7nm_7280_cfgs = {
+	.has_phy_lane = true,
+	.regulator_data = dsi_phy_7nm_37750uA_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_37750uA_regulators),
+	.ops = {
+		.enable = dsi_7nm_phy_enable,
+		.disable = dsi_7nm_phy_disable,
+		.pll_init = dsi_pll_7nm_init,
+		.save_pll_state = dsi_7nm_pll_save_state,
+		.restore_pll_state = dsi_7nm_pll_restore_state,
+	},
+	.min_pll_rate = 600000000UL,
+#ifdef CONFIG_64BIT
+	.max_pll_rate = 5000000000ULL,
+#else
+	.max_pll_rate = ULONG_MAX,
+#endif
+	.io_start = { 0xae94400 },
+	.num_dsi_phy = 1,
+	.quirks = DSI_PHY_7NM_QUIRK_V4_1,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_5nm_8350_cfgs = {
+	.has_phy_lane = true,
+	.regulator_data = dsi_phy_7nm_37750uA_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_37750uA_regulators),
+	.ops = {
+		.enable = dsi_7nm_phy_enable,
+		.disable = dsi_7nm_phy_disable,
+		.pll_init = dsi_pll_7nm_init,
+		.save_pll_state = dsi_7nm_pll_save_state,
+		.restore_pll_state = dsi_7nm_pll_restore_state,
+		.set_continuous_clock = dsi_7nm_set_continuous_clock,
+	},
+	.min_pll_rate = 600000000UL,
+#ifdef CONFIG_64BIT
+	.max_pll_rate = 5000000000UL,
+#else
+	.max_pll_rate = ULONG_MAX,
+#endif
+	.io_start = { 0xae94400, 0xae96400 },
+	.num_dsi_phy = 2,
+	.quirks = DSI_PHY_7NM_QUIRK_V4_2,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_5nm_8775_cfgs = {
+	.has_phy_lane = true,
+	.regulator_data = dsi_phy_7nm_115000uA_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_115000uA_regulators),
+	.ops = {
+		.enable = dsi_7nm_phy_enable,
+		.disable = dsi_7nm_phy_disable,
+		.pll_init = dsi_pll_7nm_init,
+		.save_pll_state = dsi_7nm_pll_save_state,
+		.restore_pll_state = dsi_7nm_pll_restore_state,
+		.set_continuous_clock = dsi_7nm_set_continuous_clock,
+	},
+	.min_pll_rate = 600000000UL,
+#ifdef CONFIG_64BIT
+	.max_pll_rate = 5000000000UL,
+#else
+	.max_pll_rate = ULONG_MAX,
+#endif
+	.io_start = { 0xae94400, 0xae96400 },
+	.num_dsi_phy = 2,
+	.quirks = DSI_PHY_7NM_QUIRK_V4_2,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_5nm_8450_cfgs = {
+	.has_phy_lane = true,
+	.regulator_data = dsi_phy_7nm_97800uA_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_97800uA_regulators),
+	.ops = {
+		.enable = dsi_7nm_phy_enable,
+		.disable = dsi_7nm_phy_disable,
+		.pll_init = dsi_pll_7nm_init,
+		.save_pll_state = dsi_7nm_pll_save_state,
+		.restore_pll_state = dsi_7nm_pll_restore_state,
+		.set_continuous_clock = dsi_7nm_set_continuous_clock,
+	},
+	.min_pll_rate = 600000000UL,
+#ifdef CONFIG_64BIT
+	.max_pll_rate = 5000000000UL,
+#else
+	.max_pll_rate = ULONG_MAX,
+#endif
+	.io_start = { 0xae94400, 0xae96400 },
+	.num_dsi_phy = 2,
+	.quirks = DSI_PHY_7NM_QUIRK_V4_3,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_4nm_8550_cfgs = {
+	.has_phy_lane = true,
+	.regulator_data = dsi_phy_7nm_98400uA_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_98400uA_regulators),
+	.ops = {
+		.enable = dsi_7nm_phy_enable,
+		.disable = dsi_7nm_phy_disable,
+		.pll_init = dsi_pll_7nm_init,
+		.save_pll_state = dsi_7nm_pll_save_state,
+		.restore_pll_state = dsi_7nm_pll_restore_state,
+		.set_continuous_clock = dsi_7nm_set_continuous_clock,
+	},
+	.min_pll_rate = 600000000UL,
+#ifdef CONFIG_64BIT
+	.max_pll_rate = 5000000000UL,
+#else
+	.max_pll_rate = ULONG_MAX,
+#endif
+	.io_start = { 0xae95000, 0xae97000 },
+	.num_dsi_phy = 2,
+	.quirks = DSI_PHY_7NM_QUIRK_V5_2,
+};
+
+const struct msm_dsi_phy_cfg dsi_phy_4nm_8650_cfgs = {
+	.has_phy_lane = true,
+	.regulator_data = dsi_phy_7nm_98000uA_regulators,
+	.num_regulators = ARRAY_SIZE(dsi_phy_7nm_98000uA_regulators),
+	.ops = {
+		.enable = dsi_7nm_phy_enable,
+		.disable = dsi_7nm_phy_disable,
+		.pll_init = dsi_pll_7nm_init,
+		.save_pll_state = dsi_7nm_pll_save_state,
+		.restore_pll_state = dsi_7nm_pll_restore_state,
+		.set_continuous_clock = dsi_7nm_set_continuous_clock,
+	},
+	.min_pll_rate = 600000000UL,
+#ifdef CONFIG_64BIT
+	.max_pll_rate = 5000000000UL,
+#else
+	.max_pll_rate = ULONG_MAX,
+#endif
+	.io_start = { 0xae95000, 0xae97000 },
+	.num_dsi_phy = 2,
+	.quirks = DSI_PHY_7NM_QUIRK_V5_2,
+};
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/hdmi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/hdmi.c
@@ -0,0 +1,580 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2014 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#include <drm/drm_bridge_connector.h>
+#include <drm/drm_of.h>
+
+#include <sound/hdmi-codec.h>
+#include "hdmi.h"
+
+void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on)
+{
+	uint32_t ctrl = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&hdmi->reg_lock, flags);
+	if (power_on) {
+		ctrl |= HDMI_CTRL_ENABLE;
+		if (!hdmi->hdmi_mode) {
+			ctrl |= HDMI_CTRL_HDMI;
+			hdmi_write(hdmi, REG_HDMI_CTRL, ctrl);
+			ctrl &= ~HDMI_CTRL_HDMI;
+		} else {
+			ctrl |= HDMI_CTRL_HDMI;
+		}
+	} else {
+		ctrl = HDMI_CTRL_HDMI;
+	}
+
+	hdmi_write(hdmi, REG_HDMI_CTRL, ctrl);
+	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+	DBG("HDMI Core: %s, HDMI_CTRL=0x%08x",
+			power_on ? "Enable" : "Disable", ctrl);
+}
+
+static irqreturn_t msm_hdmi_irq(int irq, void *dev_id)
+{
+	struct hdmi *hdmi = dev_id;
+
+	/* Process HPD: */
+	msm_hdmi_hpd_irq(hdmi->bridge);
+
+	/* Process DDC: */
+	msm_hdmi_i2c_irq(hdmi->i2c);
+
+	/* Process HDCP: */
+	if (hdmi->hdcp_ctrl)
+		msm_hdmi_hdcp_irq(hdmi->hdcp_ctrl);
+
+	/* TODO audio.. */
+
+	return IRQ_HANDLED;
+}
+
+static void msm_hdmi_destroy(struct hdmi *hdmi)
+{
+	/*
+	 * at this point, hpd has been disabled,
+	 * after flush workq, it's safe to deinit hdcp
+	 */
+	if (hdmi->workq)
+		destroy_workqueue(hdmi->workq);
+	msm_hdmi_hdcp_destroy(hdmi);
+
+	if (hdmi->i2c)
+		msm_hdmi_i2c_destroy(hdmi->i2c);
+}
+
+static void msm_hdmi_put_phy(struct hdmi *hdmi)
+{
+	if (hdmi->phy_dev) {
+		put_device(hdmi->phy_dev);
+		hdmi->phy = NULL;
+		hdmi->phy_dev = NULL;
+	}
+}
+
+static int msm_hdmi_get_phy(struct hdmi *hdmi)
+{
+	struct platform_device *pdev = hdmi->pdev;
+	struct platform_device *phy_pdev;
+	struct device_node *phy_node;
+
+	phy_node = of_parse_phandle(pdev->dev.of_node, "phys", 0);
+	if (!phy_node) {
+		DRM_DEV_ERROR(&pdev->dev, "cannot find phy device\n");
+		return -ENXIO;
+	}
+
+	phy_pdev = of_find_device_by_node(phy_node);
+	of_node_put(phy_node);
+
+	if (!phy_pdev)
+		return dev_err_probe(&pdev->dev, -EPROBE_DEFER, "phy driver is not ready\n");
+
+	hdmi->phy = platform_get_drvdata(phy_pdev);
+	if (!hdmi->phy) {
+		put_device(&phy_pdev->dev);
+		return dev_err_probe(&pdev->dev, -EPROBE_DEFER, "phy driver is not ready\n");
+	}
+
+	hdmi->phy_dev = &phy_pdev->dev;
+
+	return 0;
+}
+
+/* construct hdmi at bind/probe time, grab all the resources.  If
+ * we are to EPROBE_DEFER we want to do it here, rather than later
+ * at modeset_init() time
+ */
+static int msm_hdmi_init(struct hdmi *hdmi)
+{
+	struct platform_device *pdev = hdmi->pdev;
+	int ret;
+
+	hdmi->workq = alloc_ordered_workqueue("msm_hdmi", 0);
+	if (!hdmi->workq) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	hdmi->i2c = msm_hdmi_i2c_init(hdmi);
+	if (IS_ERR(hdmi->i2c)) {
+		ret = PTR_ERR(hdmi->i2c);
+		DRM_DEV_ERROR(&pdev->dev, "failed to get i2c: %d\n", ret);
+		hdmi->i2c = NULL;
+		goto fail;
+	}
+
+	hdmi->hdcp_ctrl = msm_hdmi_hdcp_init(hdmi);
+	if (IS_ERR(hdmi->hdcp_ctrl)) {
+		dev_warn(&pdev->dev, "failed to init hdcp: disabled\n");
+		hdmi->hdcp_ctrl = NULL;
+	}
+
+	return 0;
+
+fail:
+	msm_hdmi_destroy(hdmi);
+
+	return ret;
+}
+
+/* Second part of initialization, the drm/kms level modeset_init,
+ * constructs/initializes mode objects, etc, is called from master
+ * driver (not hdmi sub-device's probe/bind!)
+ *
+ * Any resource (regulator/clk/etc) which could be missing at boot
+ * should be handled in msm_hdmi_init() so that failure happens from
+ * hdmi sub-device's probe.
+ */
+int msm_hdmi_modeset_init(struct hdmi *hdmi,
+		struct drm_device *dev, struct drm_encoder *encoder)
+{
+	int ret;
+
+	hdmi->dev = dev;
+	hdmi->encoder = encoder;
+
+	hdmi_audio_infoframe_init(&hdmi->audio.infoframe);
+
+	ret = msm_hdmi_bridge_init(hdmi);
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev, "failed to create HDMI bridge: %d\n", ret);
+		goto fail;
+	}
+
+	if (hdmi->next_bridge) {
+		ret = drm_bridge_attach(hdmi->encoder, hdmi->next_bridge, hdmi->bridge,
+					DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+		if (ret) {
+			DRM_DEV_ERROR(dev->dev, "failed to attach next HDMI bridge: %d\n", ret);
+			goto fail;
+		}
+	}
+
+	hdmi->connector = drm_bridge_connector_init(hdmi->dev, encoder);
+	if (IS_ERR(hdmi->connector)) {
+		ret = PTR_ERR(hdmi->connector);
+		DRM_DEV_ERROR(dev->dev, "failed to create HDMI connector: %d\n", ret);
+		hdmi->connector = NULL;
+		goto fail;
+	}
+
+	drm_connector_attach_encoder(hdmi->connector, hdmi->encoder);
+
+	ret = devm_request_irq(dev->dev, hdmi->irq,
+			msm_hdmi_irq, IRQF_TRIGGER_HIGH,
+			"hdmi_isr", hdmi);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dev->dev, "failed to request IRQ%u: %d\n",
+				hdmi->irq, ret);
+		goto fail;
+	}
+
+	ret = msm_hdmi_hpd_enable(hdmi->bridge);
+	if (ret < 0) {
+		DRM_DEV_ERROR(&hdmi->pdev->dev, "failed to enable HPD: %d\n", ret);
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	if (hdmi->connector) {
+		hdmi->connector->funcs->destroy(hdmi->connector);
+		hdmi->connector = NULL;
+	}
+
+	return ret;
+}
+
+/*
+ * The hdmi device:
+ */
+
+#define HDMI_CFG(item, entry) \
+	.item ## _names = item ##_names_ ## entry, \
+	.item ## _cnt   = ARRAY_SIZE(item ## _names_ ## entry)
+
+static const char *hpd_reg_names_8960[] = {"core-vdda"};
+static const char *hpd_clk_names_8960[] = {"core", "master_iface", "slave_iface"};
+
+static const struct hdmi_platform_config hdmi_tx_8960_config = {
+		HDMI_CFG(hpd_reg, 8960),
+		HDMI_CFG(hpd_clk, 8960),
+};
+
+static const char *pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"};
+static const char *pwr_clk_names_8x74[] = {"extp", "alt_iface"};
+static const char *hpd_clk_names_8x74[] = {"iface", "core", "mdp_core"};
+static unsigned long hpd_clk_freq_8x74[] = {0, 19200000, 0};
+
+static const struct hdmi_platform_config hdmi_tx_8974_config = {
+		HDMI_CFG(pwr_reg, 8x74),
+		HDMI_CFG(pwr_clk, 8x74),
+		HDMI_CFG(hpd_clk, 8x74),
+		.hpd_freq      = hpd_clk_freq_8x74,
+};
+
+/*
+ * HDMI audio codec callbacks
+ */
+static int msm_hdmi_audio_hw_params(struct device *dev, void *data,
+				    struct hdmi_codec_daifmt *daifmt,
+				    struct hdmi_codec_params *params)
+{
+	struct hdmi *hdmi = dev_get_drvdata(dev);
+	unsigned int chan;
+	unsigned int channel_allocation = 0;
+	unsigned int rate;
+	unsigned int level_shift  = 0; /* 0dB */
+	bool down_mix = false;
+
+	DRM_DEV_DEBUG(dev, "%u Hz, %d bit, %d channels\n", params->sample_rate,
+		 params->sample_width, params->cea.channels);
+
+	switch (params->cea.channels) {
+	case 2:
+		/* FR and FL speakers */
+		channel_allocation  = 0;
+		chan = MSM_HDMI_AUDIO_CHANNEL_2;
+		break;
+	case 4:
+		/* FC, LFE, FR and FL speakers */
+		channel_allocation  = 0x3;
+		chan = MSM_HDMI_AUDIO_CHANNEL_4;
+		break;
+	case 6:
+		/* RR, RL, FC, LFE, FR and FL speakers */
+		channel_allocation  = 0x0B;
+		chan = MSM_HDMI_AUDIO_CHANNEL_6;
+		break;
+	case 8:
+		/* FRC, FLC, RR, RL, FC, LFE, FR and FL speakers */
+		channel_allocation  = 0x1F;
+		chan = MSM_HDMI_AUDIO_CHANNEL_8;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (params->sample_rate) {
+	case 32000:
+		rate = HDMI_SAMPLE_RATE_32KHZ;
+		break;
+	case 44100:
+		rate = HDMI_SAMPLE_RATE_44_1KHZ;
+		break;
+	case 48000:
+		rate = HDMI_SAMPLE_RATE_48KHZ;
+		break;
+	case 88200:
+		rate = HDMI_SAMPLE_RATE_88_2KHZ;
+		break;
+	case 96000:
+		rate = HDMI_SAMPLE_RATE_96KHZ;
+		break;
+	case 176400:
+		rate = HDMI_SAMPLE_RATE_176_4KHZ;
+		break;
+	case 192000:
+		rate = HDMI_SAMPLE_RATE_192KHZ;
+		break;
+	default:
+		DRM_DEV_ERROR(dev, "rate[%d] not supported!\n",
+			params->sample_rate);
+		return -EINVAL;
+	}
+
+	msm_hdmi_audio_set_sample_rate(hdmi, rate);
+	msm_hdmi_audio_info_setup(hdmi, 1, chan, channel_allocation,
+			      level_shift, down_mix);
+
+	return 0;
+}
+
+static void msm_hdmi_audio_shutdown(struct device *dev, void *data)
+{
+	struct hdmi *hdmi = dev_get_drvdata(dev);
+
+	msm_hdmi_audio_info_setup(hdmi, 0, 0, 0, 0, 0);
+}
+
+static const struct hdmi_codec_ops msm_hdmi_audio_codec_ops = {
+	.hw_params = msm_hdmi_audio_hw_params,
+	.audio_shutdown = msm_hdmi_audio_shutdown,
+};
+
+static struct hdmi_codec_pdata codec_data = {
+	.ops = &msm_hdmi_audio_codec_ops,
+	.max_i2s_channels = 8,
+	.i2s = 1,
+};
+
+static int msm_hdmi_register_audio_driver(struct hdmi *hdmi, struct device *dev)
+{
+	hdmi->audio_pdev = platform_device_register_data(dev,
+							 HDMI_CODEC_DRV_NAME,
+							 PLATFORM_DEVID_AUTO,
+							 &codec_data,
+							 sizeof(codec_data));
+	return PTR_ERR_OR_ZERO(hdmi->audio_pdev);
+}
+
+static int msm_hdmi_bind(struct device *dev, struct device *master, void *data)
+{
+	struct msm_drm_private *priv = dev_get_drvdata(master);
+	struct hdmi *hdmi = dev_get_drvdata(dev);
+	int err;
+
+	err = msm_hdmi_init(hdmi);
+	if (err)
+		return err;
+	priv->hdmi = hdmi;
+
+	err = msm_hdmi_register_audio_driver(hdmi, dev);
+	if (err) {
+		DRM_ERROR("Failed to attach an audio codec %d\n", err);
+		hdmi->audio_pdev = NULL;
+	}
+
+	return 0;
+}
+
+static void msm_hdmi_unbind(struct device *dev, struct device *master,
+		void *data)
+{
+	struct msm_drm_private *priv = dev_get_drvdata(master);
+
+	if (priv->hdmi) {
+		if (priv->hdmi->audio_pdev)
+			platform_device_unregister(priv->hdmi->audio_pdev);
+
+		if (priv->hdmi->bridge)
+			msm_hdmi_hpd_disable(priv->hdmi);
+
+		msm_hdmi_destroy(priv->hdmi);
+		priv->hdmi = NULL;
+	}
+}
+
+static const struct component_ops msm_hdmi_ops = {
+		.bind   = msm_hdmi_bind,
+		.unbind = msm_hdmi_unbind,
+};
+
+static int msm_hdmi_dev_probe(struct platform_device *pdev)
+{
+	const struct hdmi_platform_config *config;
+	struct device *dev = &pdev->dev;
+	struct hdmi *hdmi;
+	struct resource *res;
+	int i, ret;
+
+	config = of_device_get_match_data(dev);
+	if (!config)
+		return -EINVAL;
+
+	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);
+	if (!hdmi)
+		return -ENOMEM;
+
+	hdmi->pdev = pdev;
+	hdmi->config = config;
+	spin_lock_init(&hdmi->reg_lock);
+
+	ret = drm_of_find_panel_or_bridge(pdev->dev.of_node, 1, 0, NULL, &hdmi->next_bridge);
+	if (ret && ret != -ENODEV)
+		return ret;
+
+	hdmi->mmio = msm_ioremap(pdev, "core_physical");
+	if (IS_ERR(hdmi->mmio))
+		return PTR_ERR(hdmi->mmio);
+
+	/* HDCP needs physical address of hdmi register */
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+		"core_physical");
+	if (!res)
+		return -EINVAL;
+	hdmi->mmio_phy_addr = res->start;
+
+	hdmi->qfprom_mmio = msm_ioremap(pdev, "qfprom_physical");
+	if (IS_ERR(hdmi->qfprom_mmio)) {
+		DRM_DEV_INFO(&pdev->dev, "can't find qfprom resource\n");
+		hdmi->qfprom_mmio = NULL;
+	}
+
+	hdmi->irq = platform_get_irq(pdev, 0);
+	if (hdmi->irq < 0)
+		return hdmi->irq;
+
+	hdmi->hpd_regs = devm_kcalloc(&pdev->dev,
+				      config->hpd_reg_cnt,
+				      sizeof(hdmi->hpd_regs[0]),
+				      GFP_KERNEL);
+	if (!hdmi->hpd_regs)
+		return -ENOMEM;
+
+	for (i = 0; i < config->hpd_reg_cnt; i++)
+		hdmi->hpd_regs[i].supply = config->hpd_reg_names[i];
+
+	ret = devm_regulator_bulk_get(&pdev->dev, config->hpd_reg_cnt, hdmi->hpd_regs);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to get hpd regulators\n");
+
+	hdmi->pwr_regs = devm_kcalloc(&pdev->dev,
+				      config->pwr_reg_cnt,
+				      sizeof(hdmi->pwr_regs[0]),
+				      GFP_KERNEL);
+	if (!hdmi->pwr_regs)
+		return -ENOMEM;
+
+	for (i = 0; i < config->pwr_reg_cnt; i++)
+		hdmi->pwr_regs[i].supply = config->pwr_reg_names[i];
+
+	ret = devm_regulator_bulk_get(&pdev->dev, config->pwr_reg_cnt, hdmi->pwr_regs);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to get pwr regulators\n");
+
+	hdmi->hpd_clks = devm_kcalloc(&pdev->dev,
+				      config->hpd_clk_cnt,
+				      sizeof(hdmi->hpd_clks[0]),
+				      GFP_KERNEL);
+	if (!hdmi->hpd_clks)
+		return -ENOMEM;
+
+	for (i = 0; i < config->hpd_clk_cnt; i++) {
+		struct clk *clk;
+
+		clk = msm_clk_get(pdev, config->hpd_clk_names[i]);
+		if (IS_ERR(clk))
+			return dev_err_probe(dev, PTR_ERR(clk),
+					     "failed to get hpd clk: %s\n",
+					     config->hpd_clk_names[i]);
+
+		hdmi->hpd_clks[i] = clk;
+	}
+
+	hdmi->pwr_clks = devm_kcalloc(&pdev->dev,
+				      config->pwr_clk_cnt,
+				      sizeof(hdmi->pwr_clks[0]),
+				      GFP_KERNEL);
+	if (!hdmi->pwr_clks)
+		return -ENOMEM;
+
+	for (i = 0; i < config->pwr_clk_cnt; i++) {
+		struct clk *clk;
+
+		clk = msm_clk_get(pdev, config->pwr_clk_names[i]);
+		if (IS_ERR(clk))
+			return dev_err_probe(dev, PTR_ERR(clk),
+					     "failed to get pwr clk: %s\n",
+					     config->pwr_clk_names[i]);
+
+		hdmi->pwr_clks[i] = clk;
+	}
+
+	hdmi->hpd_gpiod = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN);
+	/* This will catch e.g. -EPROBE_DEFER */
+	if (IS_ERR(hdmi->hpd_gpiod))
+		return dev_err_probe(dev, PTR_ERR(hdmi->hpd_gpiod),
+				     "failed to get hpd gpio\n");
+
+	if (!hdmi->hpd_gpiod)
+		DBG("failed to get HPD gpio");
+
+	if (hdmi->hpd_gpiod)
+		gpiod_set_consumer_name(hdmi->hpd_gpiod, "HDMI_HPD");
+
+	ret = msm_hdmi_get_phy(hdmi);
+	if (ret) {
+		DRM_DEV_ERROR(&pdev->dev, "failed to get phy\n");
+		return ret;
+	}
+
+	ret = devm_pm_runtime_enable(&pdev->dev);
+	if (ret)
+		goto err_put_phy;
+
+	platform_set_drvdata(pdev, hdmi);
+
+	ret = component_add(&pdev->dev, &msm_hdmi_ops);
+	if (ret)
+		goto err_put_phy;
+
+	return 0;
+
+err_put_phy:
+	msm_hdmi_put_phy(hdmi);
+	return ret;
+}
+
+static void msm_hdmi_dev_remove(struct platform_device *pdev)
+{
+	struct hdmi *hdmi = dev_get_drvdata(&pdev->dev);
+
+	component_del(&pdev->dev, &msm_hdmi_ops);
+
+	msm_hdmi_put_phy(hdmi);
+}
+
+static const struct of_device_id msm_hdmi_dt_match[] = {
+	{ .compatible = "qcom,hdmi-tx-8996", .data = &hdmi_tx_8974_config },
+	{ .compatible = "qcom,hdmi-tx-8994", .data = &hdmi_tx_8974_config },
+	{ .compatible = "qcom,hdmi-tx-8084", .data = &hdmi_tx_8974_config },
+	{ .compatible = "qcom,hdmi-tx-8974", .data = &hdmi_tx_8974_config },
+	{ .compatible = "qcom,hdmi-tx-8960", .data = &hdmi_tx_8960_config },
+	{ .compatible = "qcom,hdmi-tx-8660", .data = &hdmi_tx_8960_config },
+	{}
+};
+
+static struct platform_driver msm_hdmi_driver = {
+	.probe = msm_hdmi_dev_probe,
+	.remove_new = msm_hdmi_dev_remove,
+	.driver = {
+		.name = "hdmi_msm",
+		.of_match_table = msm_hdmi_dt_match,
+	},
+};
+
+void __init msm_hdmi_register(void)
+{
+	msm_hdmi_phy_driver_register();
+	platform_driver_register(&msm_hdmi_driver);
+}
+
+void __exit msm_hdmi_unregister(void)
+{
+	platform_driver_unregister(&msm_hdmi_driver);
+	msm_hdmi_phy_driver_unregister();
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/hdmi.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/hdmi.h
@@ -0,0 +1,271 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __HDMI_CONNECTOR_H__
+#define __HDMI_CONNECTOR_H__
+
+#include <linux/i2c.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/gpio/consumer.h>
+#include <linux/hdmi.h>
+
+#include <drm/drm_bridge.h>
+
+#include "msm_drv.h"
+#include "hdmi.xml.h"
+
+struct hdmi_phy;
+struct hdmi_platform_config;
+
+struct hdmi_audio {
+	bool enabled;
+	struct hdmi_audio_infoframe infoframe;
+	int rate;
+};
+
+struct hdmi_hdcp_ctrl;
+
+struct hdmi {
+	struct drm_device *dev;
+	struct platform_device *pdev;
+	struct platform_device *audio_pdev;
+
+	const struct hdmi_platform_config *config;
+
+	/* audio state: */
+	struct hdmi_audio audio;
+
+	/* video state: */
+	bool power_on;
+	unsigned long int pixclock;
+
+	void __iomem *mmio;
+	void __iomem *qfprom_mmio;
+	phys_addr_t mmio_phy_addr;
+
+	struct regulator_bulk_data *hpd_regs;
+	struct regulator_bulk_data *pwr_regs;
+	struct clk **hpd_clks;
+	struct clk **pwr_clks;
+
+	struct gpio_desc *hpd_gpiod;
+
+	struct hdmi_phy *phy;
+	struct device *phy_dev;
+
+	struct i2c_adapter *i2c;
+	struct drm_connector *connector;
+	struct drm_bridge *bridge;
+
+	struct drm_bridge *next_bridge;
+
+	/* the encoder we are hooked to (outside of hdmi block) */
+	struct drm_encoder *encoder;
+
+	bool hdmi_mode;               /* are we in hdmi mode? */
+
+	int irq;
+	struct workqueue_struct *workq;
+
+	struct hdmi_hdcp_ctrl *hdcp_ctrl;
+
+	/*
+	* spinlock to protect registers shared by different execution
+	* REG_HDMI_CTRL
+	* REG_HDMI_DDC_ARBITRATION
+	* REG_HDMI_HDCP_INT_CTRL
+	* REG_HDMI_HPD_CTRL
+	*/
+	spinlock_t reg_lock;
+};
+
+/* platform config data (ie. from DT, or pdata) */
+struct hdmi_platform_config {
+	/* regulators that need to be on for hpd: */
+	const char **hpd_reg_names;
+	int hpd_reg_cnt;
+
+	/* regulators that need to be on for screen pwr: */
+	const char **pwr_reg_names;
+	int pwr_reg_cnt;
+
+	/* clks that need to be on for hpd: */
+	const char **hpd_clk_names;
+	const long unsigned *hpd_freq;
+	int hpd_clk_cnt;
+
+	/* clks that need to be on for screen pwr (ie pixel clk): */
+	const char **pwr_clk_names;
+	int pwr_clk_cnt;
+};
+
+struct hdmi_bridge {
+	struct drm_bridge base;
+	struct hdmi *hdmi;
+	struct work_struct hpd_work;
+};
+#define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
+
+void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on);
+
+static inline void hdmi_write(struct hdmi *hdmi, u32 reg, u32 data)
+{
+	msm_writel(data, hdmi->mmio + reg);
+}
+
+static inline u32 hdmi_read(struct hdmi *hdmi, u32 reg)
+{
+	return msm_readl(hdmi->mmio + reg);
+}
+
+static inline u32 hdmi_qfprom_read(struct hdmi *hdmi, u32 reg)
+{
+	return msm_readl(hdmi->qfprom_mmio + reg);
+}
+
+/*
+ * hdmi phy:
+ */
+
+enum hdmi_phy_type {
+	MSM_HDMI_PHY_8x60,
+	MSM_HDMI_PHY_8960,
+	MSM_HDMI_PHY_8x74,
+	MSM_HDMI_PHY_8996,
+	MSM_HDMI_PHY_8998,
+	MSM_HDMI_PHY_MAX,
+};
+
+struct hdmi_phy_cfg {
+	enum hdmi_phy_type type;
+	void (*powerup)(struct hdmi_phy *phy, unsigned long int pixclock);
+	void (*powerdown)(struct hdmi_phy *phy);
+	const char * const *reg_names;
+	int num_regs;
+	const char * const *clk_names;
+	int num_clks;
+};
+
+extern const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg;
+extern const struct hdmi_phy_cfg msm_hdmi_phy_8960_cfg;
+extern const struct hdmi_phy_cfg msm_hdmi_phy_8x74_cfg;
+extern const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg;
+extern const struct hdmi_phy_cfg msm_hdmi_phy_8998_cfg;
+
+struct hdmi_phy {
+	struct platform_device *pdev;
+	void __iomem *mmio;
+	struct hdmi_phy_cfg *cfg;
+	const struct hdmi_phy_funcs *funcs;
+	struct regulator_bulk_data *regs;
+	struct clk **clks;
+};
+
+static inline void hdmi_phy_write(struct hdmi_phy *phy, u32 reg, u32 data)
+{
+	msm_writel(data, phy->mmio + reg);
+}
+
+static inline u32 hdmi_phy_read(struct hdmi_phy *phy, u32 reg)
+{
+	return msm_readl(phy->mmio + reg);
+}
+
+int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy);
+void msm_hdmi_phy_resource_disable(struct hdmi_phy *phy);
+void msm_hdmi_phy_powerup(struct hdmi_phy *phy, unsigned long int pixclock);
+void msm_hdmi_phy_powerdown(struct hdmi_phy *phy);
+void __init msm_hdmi_phy_driver_register(void);
+void __exit msm_hdmi_phy_driver_unregister(void);
+
+#ifdef CONFIG_COMMON_CLK
+int msm_hdmi_pll_8960_init(struct platform_device *pdev);
+int msm_hdmi_pll_8996_init(struct platform_device *pdev);
+int msm_hdmi_pll_8998_init(struct platform_device *pdev);
+#else
+static inline int msm_hdmi_pll_8960_init(struct platform_device *pdev)
+{
+	return -ENODEV;
+}
+
+static inline int msm_hdmi_pll_8996_init(struct platform_device *pdev)
+{
+	return -ENODEV;
+}
+
+static inline int msm_hdmi_pll_8998_init(struct platform_device *pdev)
+{
+	return -ENODEV;
+}
+#endif
+
+/*
+ * audio:
+ */
+/* Supported HDMI Audio channels and rates */
+#define	MSM_HDMI_AUDIO_CHANNEL_2	0
+#define	MSM_HDMI_AUDIO_CHANNEL_4	1
+#define	MSM_HDMI_AUDIO_CHANNEL_6	2
+#define	MSM_HDMI_AUDIO_CHANNEL_8	3
+
+#define	HDMI_SAMPLE_RATE_32KHZ		0
+#define	HDMI_SAMPLE_RATE_44_1KHZ	1
+#define	HDMI_SAMPLE_RATE_48KHZ		2
+#define	HDMI_SAMPLE_RATE_88_2KHZ	3
+#define	HDMI_SAMPLE_RATE_96KHZ		4
+#define	HDMI_SAMPLE_RATE_176_4KHZ	5
+#define	HDMI_SAMPLE_RATE_192KHZ		6
+
+int msm_hdmi_audio_update(struct hdmi *hdmi);
+int msm_hdmi_audio_info_setup(struct hdmi *hdmi, bool enabled,
+	uint32_t num_of_channels, uint32_t channel_allocation,
+	uint32_t level_shift, bool down_mix);
+void msm_hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate);
+
+
+/*
+ * hdmi bridge:
+ */
+
+int msm_hdmi_bridge_init(struct hdmi *hdmi);
+
+void msm_hdmi_hpd_irq(struct drm_bridge *bridge);
+enum drm_connector_status msm_hdmi_bridge_detect(
+		struct drm_bridge *bridge);
+int msm_hdmi_hpd_enable(struct drm_bridge *bridge);
+void msm_hdmi_hpd_disable(struct hdmi *hdmi);
+
+/*
+ * i2c adapter for ddc:
+ */
+
+void msm_hdmi_i2c_irq(struct i2c_adapter *i2c);
+void msm_hdmi_i2c_destroy(struct i2c_adapter *i2c);
+struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi);
+
+/*
+ * hdcp
+ */
+#ifdef CONFIG_DRM_MSM_HDMI_HDCP
+struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi);
+void msm_hdmi_hdcp_destroy(struct hdmi *hdmi);
+void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl);
+void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl);
+void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl);
+#else
+static inline struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi)
+{
+	return ERR_PTR(-ENXIO);
+}
+static inline void msm_hdmi_hdcp_destroy(struct hdmi *hdmi) {}
+static inline void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
+static inline void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
+static inline void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
+#endif
+
+#endif /* __HDMI_CONNECTOR_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/hdmi_audio.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/hdmi_audio.c
@@ -0,0 +1,254 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/hdmi.h>
+#include "hdmi.h"
+
+/* maps MSM_HDMI_AUDIO_CHANNEL_n consts used by audio driver to # of channels: */
+static int nchannels[] = { 2, 4, 6, 8 };
+
+/* Supported HDMI Audio sample rates */
+#define MSM_HDMI_SAMPLE_RATE_32KHZ		0
+#define MSM_HDMI_SAMPLE_RATE_44_1KHZ		1
+#define MSM_HDMI_SAMPLE_RATE_48KHZ		2
+#define MSM_HDMI_SAMPLE_RATE_88_2KHZ		3
+#define MSM_HDMI_SAMPLE_RATE_96KHZ		4
+#define MSM_HDMI_SAMPLE_RATE_176_4KHZ		5
+#define MSM_HDMI_SAMPLE_RATE_192KHZ		6
+#define MSM_HDMI_SAMPLE_RATE_MAX		7
+
+
+struct hdmi_msm_audio_acr {
+	uint32_t n;	/* N parameter for clock regeneration */
+	uint32_t cts;	/* CTS parameter for clock regeneration */
+};
+
+struct hdmi_msm_audio_arcs {
+	unsigned long int pixclock;
+	struct hdmi_msm_audio_acr lut[MSM_HDMI_SAMPLE_RATE_MAX];
+};
+
+#define HDMI_MSM_AUDIO_ARCS(pclk, ...) { (1000 * (pclk)), __VA_ARGS__ }
+
+/* Audio constants lookup table for hdmi_msm_audio_acr_setup */
+/* Valid Pixel-Clock rates: 25.2MHz, 27MHz, 27.03MHz, 74.25MHz, 148.5MHz */
+static const struct hdmi_msm_audio_arcs acr_lut[] = {
+	/*  25.200MHz  */
+	HDMI_MSM_AUDIO_ARCS(25200, {
+		{4096, 25200}, {6272, 28000}, {6144, 25200}, {12544, 28000},
+		{12288, 25200}, {25088, 28000}, {24576, 25200} }),
+	/*  27.000MHz  */
+	HDMI_MSM_AUDIO_ARCS(27000, {
+		{4096, 27000}, {6272, 30000}, {6144, 27000}, {12544, 30000},
+		{12288, 27000}, {25088, 30000}, {24576, 27000} }),
+	/*  27.027MHz */
+	HDMI_MSM_AUDIO_ARCS(27030, {
+		{4096, 27027}, {6272, 30030}, {6144, 27027}, {12544, 30030},
+		{12288, 27027}, {25088, 30030}, {24576, 27027} }),
+	/*  74.250MHz */
+	HDMI_MSM_AUDIO_ARCS(74250, {
+		{4096, 74250}, {6272, 82500}, {6144, 74250}, {12544, 82500},
+		{12288, 74250}, {25088, 82500}, {24576, 74250} }),
+	/* 148.500MHz */
+	HDMI_MSM_AUDIO_ARCS(148500, {
+		{4096, 148500}, {6272, 165000}, {6144, 148500}, {12544, 165000},
+		{12288, 148500}, {25088, 165000}, {24576, 148500} }),
+};
+
+static const struct hdmi_msm_audio_arcs *get_arcs(unsigned long int pixclock)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(acr_lut); i++) {
+		const struct hdmi_msm_audio_arcs *arcs = &acr_lut[i];
+		if (arcs->pixclock == pixclock)
+			return arcs;
+	}
+
+	return NULL;
+}
+
+int msm_hdmi_audio_update(struct hdmi *hdmi)
+{
+	struct hdmi_audio *audio = &hdmi->audio;
+	struct hdmi_audio_infoframe *info = &audio->infoframe;
+	const struct hdmi_msm_audio_arcs *arcs = NULL;
+	bool enabled = audio->enabled;
+	uint32_t acr_pkt_ctrl, vbi_pkt_ctrl, aud_pkt_ctrl;
+	uint32_t infofrm_ctrl, audio_config;
+
+	DBG("audio: enabled=%d, channels=%d, channel_allocation=0x%x, "
+		"level_shift_value=%d, downmix_inhibit=%d, rate=%d",
+		audio->enabled, info->channels,  info->channel_allocation,
+		info->level_shift_value, info->downmix_inhibit, audio->rate);
+	DBG("video: power_on=%d, pixclock=%lu", hdmi->power_on, hdmi->pixclock);
+
+	if (enabled && !(hdmi->power_on && hdmi->pixclock)) {
+		DBG("disabling audio: no video");
+		enabled = false;
+	}
+
+	if (enabled) {
+		arcs = get_arcs(hdmi->pixclock);
+		if (!arcs) {
+			DBG("disabling audio: unsupported pixclock: %lu",
+					hdmi->pixclock);
+			enabled = false;
+		}
+	}
+
+	/* Read first before writing */
+	acr_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_ACR_PKT_CTRL);
+	vbi_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_VBI_PKT_CTRL);
+	aud_pkt_ctrl = hdmi_read(hdmi, REG_HDMI_AUDIO_PKT_CTRL1);
+	infofrm_ctrl = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL0);
+	audio_config = hdmi_read(hdmi, REG_HDMI_AUDIO_CFG);
+
+	/* Clear N/CTS selection bits */
+	acr_pkt_ctrl &= ~HDMI_ACR_PKT_CTRL_SELECT__MASK;
+
+	if (enabled) {
+		uint32_t n, cts, multiplier;
+		enum hdmi_acr_cts select;
+		uint8_t buf[14];
+
+		n   = arcs->lut[audio->rate].n;
+		cts = arcs->lut[audio->rate].cts;
+
+		if ((MSM_HDMI_SAMPLE_RATE_192KHZ == audio->rate) ||
+				(MSM_HDMI_SAMPLE_RATE_176_4KHZ == audio->rate)) {
+			multiplier = 4;
+			n >>= 2; /* divide N by 4 and use multiplier */
+		} else if ((MSM_HDMI_SAMPLE_RATE_96KHZ == audio->rate) ||
+				(MSM_HDMI_SAMPLE_RATE_88_2KHZ == audio->rate)) {
+			multiplier = 2;
+			n >>= 1; /* divide N by 2 and use multiplier */
+		} else {
+			multiplier = 1;
+		}
+
+		DBG("n=%u, cts=%u, multiplier=%u", n, cts, multiplier);
+
+		acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_SOURCE;
+		acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_AUDIO_PRIORITY;
+		acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_N_MULTIPLIER(multiplier);
+
+		if ((MSM_HDMI_SAMPLE_RATE_48KHZ == audio->rate) ||
+				(MSM_HDMI_SAMPLE_RATE_96KHZ == audio->rate) ||
+				(MSM_HDMI_SAMPLE_RATE_192KHZ == audio->rate))
+			select = ACR_48;
+		else if ((MSM_HDMI_SAMPLE_RATE_44_1KHZ == audio->rate) ||
+				(MSM_HDMI_SAMPLE_RATE_88_2KHZ == audio->rate) ||
+				(MSM_HDMI_SAMPLE_RATE_176_4KHZ == audio->rate))
+			select = ACR_44;
+		else /* default to 32k */
+			select = ACR_32;
+
+		acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_SELECT(select);
+
+		hdmi_write(hdmi, REG_HDMI_ACR_0(select - 1),
+				HDMI_ACR_0_CTS(cts));
+		hdmi_write(hdmi, REG_HDMI_ACR_1(select - 1),
+				HDMI_ACR_1_N(n));
+
+		hdmi_write(hdmi, REG_HDMI_AUDIO_PKT_CTRL2,
+				COND(info->channels != 2, HDMI_AUDIO_PKT_CTRL2_LAYOUT) |
+				HDMI_AUDIO_PKT_CTRL2_OVERRIDE);
+
+		acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_CONT;
+		acr_pkt_ctrl |= HDMI_ACR_PKT_CTRL_SEND;
+
+		/* configure infoframe: */
+		hdmi_audio_infoframe_pack(info, buf, sizeof(buf));
+		hdmi_write(hdmi, REG_HDMI_AUDIO_INFO0,
+				(buf[3] <<  0) | (buf[4] <<  8) |
+				(buf[5] << 16) | (buf[6] << 24));
+		hdmi_write(hdmi, REG_HDMI_AUDIO_INFO1,
+				(buf[7] <<  0) | (buf[8] << 8));
+
+		hdmi_write(hdmi, REG_HDMI_GC, 0);
+
+		vbi_pkt_ctrl |= HDMI_VBI_PKT_CTRL_GC_ENABLE;
+		vbi_pkt_ctrl |= HDMI_VBI_PKT_CTRL_GC_EVERY_FRAME;
+
+		aud_pkt_ctrl |= HDMI_AUDIO_PKT_CTRL1_AUDIO_SAMPLE_SEND;
+
+		infofrm_ctrl |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND;
+		infofrm_ctrl |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT;
+		infofrm_ctrl |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE;
+		infofrm_ctrl |= HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE;
+
+		audio_config &= ~HDMI_AUDIO_CFG_FIFO_WATERMARK__MASK;
+		audio_config |= HDMI_AUDIO_CFG_FIFO_WATERMARK(4);
+		audio_config |= HDMI_AUDIO_CFG_ENGINE_ENABLE;
+	} else {
+		acr_pkt_ctrl &= ~HDMI_ACR_PKT_CTRL_CONT;
+		acr_pkt_ctrl &= ~HDMI_ACR_PKT_CTRL_SEND;
+		vbi_pkt_ctrl &= ~HDMI_VBI_PKT_CTRL_GC_ENABLE;
+		vbi_pkt_ctrl &= ~HDMI_VBI_PKT_CTRL_GC_EVERY_FRAME;
+		aud_pkt_ctrl &= ~HDMI_AUDIO_PKT_CTRL1_AUDIO_SAMPLE_SEND;
+		infofrm_ctrl &= ~HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND;
+		infofrm_ctrl &= ~HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT;
+		infofrm_ctrl &= ~HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE;
+		infofrm_ctrl &= ~HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE;
+		audio_config &= ~HDMI_AUDIO_CFG_ENGINE_ENABLE;
+	}
+
+	hdmi_write(hdmi, REG_HDMI_ACR_PKT_CTRL, acr_pkt_ctrl);
+	hdmi_write(hdmi, REG_HDMI_VBI_PKT_CTRL, vbi_pkt_ctrl);
+	hdmi_write(hdmi, REG_HDMI_AUDIO_PKT_CTRL1, aud_pkt_ctrl);
+	hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0, infofrm_ctrl);
+
+	hdmi_write(hdmi, REG_HDMI_AUD_INT,
+			COND(enabled, HDMI_AUD_INT_AUD_FIFO_URUN_INT) |
+			COND(enabled, HDMI_AUD_INT_AUD_SAM_DROP_INT));
+
+	hdmi_write(hdmi, REG_HDMI_AUDIO_CFG, audio_config);
+
+
+	DBG("audio %sabled", enabled ? "en" : "dis");
+
+	return 0;
+}
+
+int msm_hdmi_audio_info_setup(struct hdmi *hdmi, bool enabled,
+	uint32_t num_of_channels, uint32_t channel_allocation,
+	uint32_t level_shift, bool down_mix)
+{
+	struct hdmi_audio *audio;
+
+	if (!hdmi)
+		return -ENXIO;
+
+	audio = &hdmi->audio;
+
+	if (num_of_channels >= ARRAY_SIZE(nchannels))
+		return -EINVAL;
+
+	audio->enabled = enabled;
+	audio->infoframe.channels = nchannels[num_of_channels];
+	audio->infoframe.channel_allocation = channel_allocation;
+	audio->infoframe.level_shift_value = level_shift;
+	audio->infoframe.downmix_inhibit = down_mix;
+
+	return msm_hdmi_audio_update(hdmi);
+}
+
+void msm_hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate)
+{
+	struct hdmi_audio *audio;
+
+	if (!hdmi)
+		return;
+
+	audio = &hdmi->audio;
+
+	if ((rate < 0) || (rate >= MSM_HDMI_SAMPLE_RATE_MAX))
+		return;
+
+	audio->rate = rate;
+	msm_hdmi_audio_update(hdmi);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/hdmi_bridge.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/hdmi_bridge.c
@@ -0,0 +1,345 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/delay.h>
+#include <drm/drm_bridge_connector.h>
+#include <drm/drm_edid.h>
+
+#include "msm_kms.h"
+#include "hdmi.h"
+
+static void msm_hdmi_power_on(struct drm_bridge *bridge)
+{
+	struct drm_device *dev = bridge->dev;
+	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+	struct hdmi *hdmi = hdmi_bridge->hdmi;
+	const struct hdmi_platform_config *config = hdmi->config;
+	int i, ret;
+
+	pm_runtime_get_sync(&hdmi->pdev->dev);
+
+	ret = regulator_bulk_enable(config->pwr_reg_cnt, hdmi->pwr_regs);
+	if (ret)
+		DRM_DEV_ERROR(dev->dev, "failed to enable pwr regulator: %d\n", ret);
+
+	if (config->pwr_clk_cnt > 0) {
+		DBG("pixclock: %lu", hdmi->pixclock);
+		ret = clk_set_rate(hdmi->pwr_clks[0], hdmi->pixclock);
+		if (ret) {
+			DRM_DEV_ERROR(dev->dev, "failed to set pixel clk: %s (%d)\n",
+					config->pwr_clk_names[0], ret);
+		}
+	}
+
+	for (i = 0; i < config->pwr_clk_cnt; i++) {
+		ret = clk_prepare_enable(hdmi->pwr_clks[i]);
+		if (ret) {
+			DRM_DEV_ERROR(dev->dev, "failed to enable pwr clk: %s (%d)\n",
+					config->pwr_clk_names[i], ret);
+		}
+	}
+}
+
+static void power_off(struct drm_bridge *bridge)
+{
+	struct drm_device *dev = bridge->dev;
+	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+	struct hdmi *hdmi = hdmi_bridge->hdmi;
+	const struct hdmi_platform_config *config = hdmi->config;
+	int i, ret;
+
+	/* TODO do we need to wait for final vblank somewhere before
+	 * cutting the clocks?
+	 */
+	mdelay(16 + 4);
+
+	for (i = 0; i < config->pwr_clk_cnt; i++)
+		clk_disable_unprepare(hdmi->pwr_clks[i]);
+
+	ret = regulator_bulk_disable(config->pwr_reg_cnt, hdmi->pwr_regs);
+	if (ret)
+		DRM_DEV_ERROR(dev->dev, "failed to disable pwr regulator: %d\n", ret);
+
+	pm_runtime_put(&hdmi->pdev->dev);
+}
+
+#define AVI_IFRAME_LINE_NUMBER 1
+
+static void msm_hdmi_config_avi_infoframe(struct hdmi *hdmi)
+{
+	struct drm_crtc *crtc = hdmi->encoder->crtc;
+	const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+	union hdmi_infoframe frame;
+	u8 buffer[HDMI_INFOFRAME_SIZE(AVI)];
+	u32 val;
+	int len;
+
+	drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
+						 hdmi->connector, mode);
+
+	len = hdmi_infoframe_pack(&frame, buffer, sizeof(buffer));
+	if (len < 0) {
+		DRM_DEV_ERROR(&hdmi->pdev->dev,
+			"failed to configure avi infoframe\n");
+		return;
+	}
+
+	/*
+	 * the AVI_INFOx registers don't map exactly to how the AVI infoframes
+	 * are packed according to the spec. The checksum from the header is
+	 * written to the LSB byte of AVI_INFO0 and the version is written to
+	 * the third byte from the LSB of AVI_INFO3
+	 */
+	hdmi_write(hdmi, REG_HDMI_AVI_INFO(0),
+		   buffer[3] |
+		   buffer[4] << 8 |
+		   buffer[5] << 16 |
+		   buffer[6] << 24);
+
+	hdmi_write(hdmi, REG_HDMI_AVI_INFO(1),
+		   buffer[7] |
+		   buffer[8] << 8 |
+		   buffer[9] << 16 |
+		   buffer[10] << 24);
+
+	hdmi_write(hdmi, REG_HDMI_AVI_INFO(2),
+		   buffer[11] |
+		   buffer[12] << 8 |
+		   buffer[13] << 16 |
+		   buffer[14] << 24);
+
+	hdmi_write(hdmi, REG_HDMI_AVI_INFO(3),
+		   buffer[15] |
+		   buffer[16] << 8 |
+		   buffer[1] << 24);
+
+	hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL0,
+		   HDMI_INFOFRAME_CTRL0_AVI_SEND |
+		   HDMI_INFOFRAME_CTRL0_AVI_CONT);
+
+	val = hdmi_read(hdmi, REG_HDMI_INFOFRAME_CTRL1);
+	val &= ~HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE__MASK;
+	val |= HDMI_INFOFRAME_CTRL1_AVI_INFO_LINE(AVI_IFRAME_LINE_NUMBER);
+	hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val);
+}
+
+static void msm_hdmi_bridge_pre_enable(struct drm_bridge *bridge)
+{
+	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+	struct hdmi *hdmi = hdmi_bridge->hdmi;
+	struct hdmi_phy *phy = hdmi->phy;
+
+	DBG("power up");
+
+	if (!hdmi->power_on) {
+		msm_hdmi_phy_resource_enable(phy);
+		msm_hdmi_power_on(bridge);
+		hdmi->power_on = true;
+		if (hdmi->hdmi_mode) {
+			msm_hdmi_config_avi_infoframe(hdmi);
+			msm_hdmi_audio_update(hdmi);
+		}
+	}
+
+	msm_hdmi_phy_powerup(phy, hdmi->pixclock);
+
+	msm_hdmi_set_mode(hdmi, true);
+
+	if (hdmi->hdcp_ctrl)
+		msm_hdmi_hdcp_on(hdmi->hdcp_ctrl);
+}
+
+static void msm_hdmi_bridge_post_disable(struct drm_bridge *bridge)
+{
+	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+	struct hdmi *hdmi = hdmi_bridge->hdmi;
+	struct hdmi_phy *phy = hdmi->phy;
+
+	if (hdmi->hdcp_ctrl)
+		msm_hdmi_hdcp_off(hdmi->hdcp_ctrl);
+
+	DBG("power down");
+	msm_hdmi_set_mode(hdmi, false);
+
+	msm_hdmi_phy_powerdown(phy);
+
+	if (hdmi->power_on) {
+		power_off(bridge);
+		hdmi->power_on = false;
+		if (hdmi->hdmi_mode)
+			msm_hdmi_audio_update(hdmi);
+		msm_hdmi_phy_resource_disable(phy);
+	}
+}
+
+static void msm_hdmi_bridge_mode_set(struct drm_bridge *bridge,
+		 const struct drm_display_mode *mode,
+		 const struct drm_display_mode *adjusted_mode)
+{
+	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+	struct hdmi *hdmi = hdmi_bridge->hdmi;
+	int hstart, hend, vstart, vend;
+	uint32_t frame_ctrl;
+
+	mode = adjusted_mode;
+
+	hdmi->pixclock = mode->clock * 1000;
+
+	hstart = mode->htotal - mode->hsync_start;
+	hend   = mode->htotal - mode->hsync_start + mode->hdisplay;
+
+	vstart = mode->vtotal - mode->vsync_start - 1;
+	vend   = mode->vtotal - mode->vsync_start + mode->vdisplay - 1;
+
+	DBG("htotal=%d, vtotal=%d, hstart=%d, hend=%d, vstart=%d, vend=%d",
+			mode->htotal, mode->vtotal, hstart, hend, vstart, vend);
+
+	hdmi_write(hdmi, REG_HDMI_TOTAL,
+			HDMI_TOTAL_H_TOTAL(mode->htotal - 1) |
+			HDMI_TOTAL_V_TOTAL(mode->vtotal - 1));
+
+	hdmi_write(hdmi, REG_HDMI_ACTIVE_HSYNC,
+			HDMI_ACTIVE_HSYNC_START(hstart) |
+			HDMI_ACTIVE_HSYNC_END(hend));
+	hdmi_write(hdmi, REG_HDMI_ACTIVE_VSYNC,
+			HDMI_ACTIVE_VSYNC_START(vstart) |
+			HDMI_ACTIVE_VSYNC_END(vend));
+
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
+		hdmi_write(hdmi, REG_HDMI_VSYNC_TOTAL_F2,
+				HDMI_VSYNC_TOTAL_F2_V_TOTAL(mode->vtotal));
+		hdmi_write(hdmi, REG_HDMI_VSYNC_ACTIVE_F2,
+				HDMI_VSYNC_ACTIVE_F2_START(vstart + 1) |
+				HDMI_VSYNC_ACTIVE_F2_END(vend + 1));
+	} else {
+		hdmi_write(hdmi, REG_HDMI_VSYNC_TOTAL_F2,
+				HDMI_VSYNC_TOTAL_F2_V_TOTAL(0));
+		hdmi_write(hdmi, REG_HDMI_VSYNC_ACTIVE_F2,
+				HDMI_VSYNC_ACTIVE_F2_START(0) |
+				HDMI_VSYNC_ACTIVE_F2_END(0));
+	}
+
+	frame_ctrl = 0;
+	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+		frame_ctrl |= HDMI_FRAME_CTRL_HSYNC_LOW;
+	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+		frame_ctrl |= HDMI_FRAME_CTRL_VSYNC_LOW;
+	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+		frame_ctrl |= HDMI_FRAME_CTRL_INTERLACED_EN;
+	DBG("frame_ctrl=%08x", frame_ctrl);
+	hdmi_write(hdmi, REG_HDMI_FRAME_CTRL, frame_ctrl);
+
+	if (hdmi->hdmi_mode)
+		msm_hdmi_audio_update(hdmi);
+}
+
+static struct edid *msm_hdmi_bridge_get_edid(struct drm_bridge *bridge,
+		struct drm_connector *connector)
+{
+	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+	struct hdmi *hdmi = hdmi_bridge->hdmi;
+	struct edid *edid;
+	uint32_t hdmi_ctrl;
+
+	hdmi_ctrl = hdmi_read(hdmi, REG_HDMI_CTRL);
+	hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl | HDMI_CTRL_ENABLE);
+
+	edid = drm_get_edid(connector, hdmi->i2c);
+
+	hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl);
+
+	hdmi->hdmi_mode = drm_detect_hdmi_monitor(edid);
+
+	return edid;
+}
+
+static enum drm_mode_status msm_hdmi_bridge_mode_valid(struct drm_bridge *bridge,
+		const struct drm_display_info *info,
+		const struct drm_display_mode *mode)
+{
+	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+	struct hdmi *hdmi = hdmi_bridge->hdmi;
+	const struct hdmi_platform_config *config = hdmi->config;
+	struct msm_drm_private *priv = bridge->dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+	long actual, requested;
+
+	requested = 1000 * mode->clock;
+
+	/* for mdp5/apq8074, we manage our own pixel clk (as opposed to
+	 * mdp4/dtv stuff where pixel clk is assigned to mdp/encoder
+	 * instead):
+	 */
+	if (kms->funcs->round_pixclk)
+		actual = kms->funcs->round_pixclk(kms,
+			requested, hdmi_bridge->hdmi->encoder);
+	else if (config->pwr_clk_cnt > 0)
+		actual = clk_round_rate(hdmi->pwr_clks[0], requested);
+	else
+		actual = requested;
+
+	DBG("requested=%ld, actual=%ld", requested, actual);
+
+	if (actual != requested)
+		return MODE_CLOCK_RANGE;
+
+	return 0;
+}
+
+static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = {
+		.pre_enable = msm_hdmi_bridge_pre_enable,
+		.post_disable = msm_hdmi_bridge_post_disable,
+		.mode_set = msm_hdmi_bridge_mode_set,
+		.mode_valid = msm_hdmi_bridge_mode_valid,
+		.get_edid = msm_hdmi_bridge_get_edid,
+		.detect = msm_hdmi_bridge_detect,
+};
+
+static void
+msm_hdmi_hotplug_work(struct work_struct *work)
+{
+	struct hdmi_bridge *hdmi_bridge =
+		container_of(work, struct hdmi_bridge, hpd_work);
+	struct drm_bridge *bridge = &hdmi_bridge->base;
+
+	drm_bridge_hpd_notify(bridge, drm_bridge_detect(bridge));
+}
+
+/* initialize bridge */
+int msm_hdmi_bridge_init(struct hdmi *hdmi)
+{
+	struct drm_bridge *bridge = NULL;
+	struct hdmi_bridge *hdmi_bridge;
+	int ret;
+
+	hdmi_bridge = devm_kzalloc(hdmi->dev->dev,
+			sizeof(*hdmi_bridge), GFP_KERNEL);
+	if (!hdmi_bridge)
+		return -ENOMEM;
+
+	hdmi_bridge->hdmi = hdmi;
+	INIT_WORK(&hdmi_bridge->hpd_work, msm_hdmi_hotplug_work);
+
+	bridge = &hdmi_bridge->base;
+	bridge->funcs = &msm_hdmi_bridge_funcs;
+	bridge->ddc = hdmi->i2c;
+	bridge->type = DRM_MODE_CONNECTOR_HDMIA;
+	bridge->ops = DRM_BRIDGE_OP_HPD |
+		DRM_BRIDGE_OP_DETECT |
+		DRM_BRIDGE_OP_EDID;
+
+	ret = devm_drm_bridge_add(hdmi->dev->dev, bridge);
+	if (ret)
+		return ret;
+
+	ret = drm_bridge_attach(hdmi->encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+	if (ret)
+		return ret;
+
+	hdmi->bridge = bridge;
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/hdmi_hdcp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/hdmi_hdcp.c
@@ -0,0 +1,1428 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
+ */
+
+#include "hdmi.h"
+#include <linux/firmware/qcom/qcom_scm.h>
+
+#define HDCP_REG_ENABLE 0x01
+#define HDCP_REG_DISABLE 0x00
+#define HDCP_PORT_ADDR 0x74
+
+#define HDCP_INT_STATUS_MASK ( \
+		HDMI_HDCP_INT_CTRL_AUTH_SUCCESS_INT | \
+		HDMI_HDCP_INT_CTRL_AUTH_FAIL_INT | \
+		HDMI_HDCP_INT_CTRL_AUTH_XFER_REQ_INT | \
+		HDMI_HDCP_INT_CTRL_AUTH_XFER_DONE_INT)
+
+#define AUTH_WORK_RETRIES_TIME 100
+#define AUTH_RETRIES_TIME 30
+
+/* QFPROM Registers for HDMI/HDCP */
+#define QFPROM_RAW_FEAT_CONFIG_ROW0_LSB  0x000000F8
+#define QFPROM_RAW_FEAT_CONFIG_ROW0_MSB  0x000000FC
+#define HDCP_KSV_LSB                     0x000060D8
+#define HDCP_KSV_MSB                     0x000060DC
+
+enum DS_TYPE {  /* type of downstream device */
+	DS_UNKNOWN,
+	DS_RECEIVER,
+	DS_REPEATER,
+};
+
+enum hdmi_hdcp_state {
+	HDCP_STATE_NO_AKSV,
+	HDCP_STATE_INACTIVE,
+	HDCP_STATE_AUTHENTICATING,
+	HDCP_STATE_AUTHENTICATED,
+	HDCP_STATE_AUTH_FAILED
+};
+
+struct hdmi_hdcp_reg_data {
+	u32 reg_id;
+	u32 off;
+	char *name;
+	u32 reg_val;
+};
+
+struct hdmi_hdcp_ctrl {
+	struct hdmi *hdmi;
+	u32 auth_retries;
+	bool tz_hdcp;
+	enum hdmi_hdcp_state hdcp_state;
+	struct work_struct hdcp_auth_work;
+	struct work_struct hdcp_reauth_work;
+
+#define AUTH_ABORT_EV 1
+#define AUTH_RESULT_RDY_EV 2
+	unsigned long auth_event;
+	wait_queue_head_t auth_event_queue;
+
+	u32 ksv_fifo_w_index;
+	/*
+	 * store aksv from qfprom
+	 */
+	u32 aksv_lsb;
+	u32 aksv_msb;
+	bool aksv_valid;
+	u32 ds_type;
+	u32 bksv_lsb;
+	u32 bksv_msb;
+	u8 dev_count;
+	u8 depth;
+	u8 ksv_list[5 * 127];
+	bool max_cascade_exceeded;
+	bool max_dev_exceeded;
+};
+
+static int msm_hdmi_ddc_read(struct hdmi *hdmi, u16 addr, u8 offset,
+	u8 *data, u16 data_len)
+{
+	int rc;
+	int retry = 5;
+	struct i2c_msg msgs[] = {
+		{
+			.addr	= addr >> 1,
+			.flags	= 0,
+			.len	= 1,
+			.buf	= &offset,
+		}, {
+			.addr	= addr >> 1,
+			.flags	= I2C_M_RD,
+			.len	= data_len,
+			.buf	= data,
+		}
+	};
+
+	DBG("Start DDC read");
+retry:
+	rc = i2c_transfer(hdmi->i2c, msgs, 2);
+
+	retry--;
+	if (rc == 2)
+		rc = 0;
+	else if (retry > 0)
+		goto retry;
+	else
+		rc = -EIO;
+
+	DBG("End DDC read %d", rc);
+
+	return rc;
+}
+
+#define HDCP_DDC_WRITE_MAX_BYTE_NUM 32
+
+static int msm_hdmi_ddc_write(struct hdmi *hdmi, u16 addr, u8 offset,
+	u8 *data, u16 data_len)
+{
+	int rc;
+	int retry = 10;
+	u8 buf[HDCP_DDC_WRITE_MAX_BYTE_NUM];
+	struct i2c_msg msgs[] = {
+		{
+			.addr	= addr >> 1,
+			.flags	= 0,
+			.len	= 1,
+		}
+	};
+
+	DBG("Start DDC write");
+	if (data_len > (HDCP_DDC_WRITE_MAX_BYTE_NUM - 1)) {
+		pr_err("%s: write size too big\n", __func__);
+		return -ERANGE;
+	}
+
+	buf[0] = offset;
+	memcpy(&buf[1], data, data_len);
+	msgs[0].buf = buf;
+	msgs[0].len = data_len + 1;
+retry:
+	rc = i2c_transfer(hdmi->i2c, msgs, 1);
+
+	retry--;
+	if (rc == 1)
+		rc = 0;
+	else if (retry > 0)
+		goto retry;
+	else
+		rc = -EIO;
+
+	DBG("End DDC write %d", rc);
+
+	return rc;
+}
+
+static int msm_hdmi_hdcp_scm_wr(struct hdmi_hdcp_ctrl *hdcp_ctrl, u32 *preg,
+	u32 *pdata, u32 count)
+{
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	struct qcom_scm_hdcp_req scm_buf[QCOM_SCM_HDCP_MAX_REQ_CNT];
+	u32 resp, phy_addr, idx = 0;
+	int i, ret = 0;
+
+	WARN_ON(!pdata || !preg || (count == 0));
+
+	if (hdcp_ctrl->tz_hdcp) {
+		phy_addr = (u32)hdmi->mmio_phy_addr;
+
+		while (count) {
+			memset(scm_buf, 0, sizeof(scm_buf));
+			for (i = 0; i < count && i < QCOM_SCM_HDCP_MAX_REQ_CNT;
+				i++) {
+				scm_buf[i].addr = phy_addr + preg[idx];
+				scm_buf[i].val  = pdata[idx];
+				idx++;
+			}
+			ret = qcom_scm_hdcp_req(scm_buf, i, &resp);
+
+			if (ret || resp) {
+				pr_err("%s: error: scm_call ret=%d resp=%u\n",
+					__func__, ret, resp);
+				ret = -EINVAL;
+				break;
+			}
+
+			count -= i;
+		}
+	} else {
+		for (i = 0; i < count; i++)
+			hdmi_write(hdmi, preg[i], pdata[i]);
+	}
+
+	return ret;
+}
+
+void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u32 reg_val, hdcp_int_status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&hdmi->reg_lock, flags);
+	reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_INT_CTRL);
+	hdcp_int_status = reg_val & HDCP_INT_STATUS_MASK;
+	if (!hdcp_int_status) {
+		spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+		return;
+	}
+	/* Clear Interrupts */
+	reg_val |= hdcp_int_status << 1;
+	/* Clear AUTH_FAIL_INFO as well */
+	if (hdcp_int_status & HDMI_HDCP_INT_CTRL_AUTH_FAIL_INT)
+		reg_val |= HDMI_HDCP_INT_CTRL_AUTH_FAIL_INFO_ACK;
+	hdmi_write(hdmi, REG_HDMI_HDCP_INT_CTRL, reg_val);
+	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+
+	DBG("hdcp irq %x", hdcp_int_status);
+
+	if (hdcp_int_status & HDMI_HDCP_INT_CTRL_AUTH_SUCCESS_INT) {
+		pr_info("%s:AUTH_SUCCESS_INT received\n", __func__);
+		if (HDCP_STATE_AUTHENTICATING == hdcp_ctrl->hdcp_state) {
+			set_bit(AUTH_RESULT_RDY_EV, &hdcp_ctrl->auth_event);
+			wake_up_all(&hdcp_ctrl->auth_event_queue);
+		}
+	}
+
+	if (hdcp_int_status & HDMI_HDCP_INT_CTRL_AUTH_FAIL_INT) {
+		reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_LINK0_STATUS);
+		pr_info("%s: AUTH_FAIL_INT rcvd, LINK0_STATUS=0x%08x\n",
+			__func__, reg_val);
+		if (HDCP_STATE_AUTHENTICATED == hdcp_ctrl->hdcp_state)
+			queue_work(hdmi->workq, &hdcp_ctrl->hdcp_reauth_work);
+		else if (HDCP_STATE_AUTHENTICATING ==
+				hdcp_ctrl->hdcp_state) {
+			set_bit(AUTH_RESULT_RDY_EV, &hdcp_ctrl->auth_event);
+			wake_up_all(&hdcp_ctrl->auth_event_queue);
+		}
+	}
+}
+
+static int msm_hdmi_hdcp_msleep(struct hdmi_hdcp_ctrl *hdcp_ctrl, u32 ms, u32 ev)
+{
+	int rc;
+
+	rc = wait_event_timeout(hdcp_ctrl->auth_event_queue,
+		!!test_bit(ev, &hdcp_ctrl->auth_event),
+		msecs_to_jiffies(ms));
+	if (rc) {
+		pr_info("%s: msleep is canceled by event %d\n",
+				__func__, ev);
+		clear_bit(ev, &hdcp_ctrl->auth_event);
+		return -ECANCELED;
+	}
+
+	return 0;
+}
+
+static int msm_hdmi_hdcp_read_validate_aksv(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+
+	/* Fetch aksv from QFPROM, this info should be public. */
+	hdcp_ctrl->aksv_lsb = hdmi_qfprom_read(hdmi, HDCP_KSV_LSB);
+	hdcp_ctrl->aksv_msb = hdmi_qfprom_read(hdmi, HDCP_KSV_MSB);
+
+	/* check there are 20 ones in AKSV */
+	if ((hweight32(hdcp_ctrl->aksv_lsb) + hweight32(hdcp_ctrl->aksv_msb))
+			!= 20) {
+		pr_err("%s: AKSV QFPROM doesn't have 20 1's, 20 0's\n",
+			__func__);
+		pr_err("%s: QFPROM AKSV chk failed (AKSV=%02x%08x)\n",
+			__func__, hdcp_ctrl->aksv_msb,
+			hdcp_ctrl->aksv_lsb);
+		return -EINVAL;
+	}
+	DBG("AKSV=%02x%08x", hdcp_ctrl->aksv_msb, hdcp_ctrl->aksv_lsb);
+
+	return 0;
+}
+
+static int msm_reset_hdcp_ddc_failures(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u32 reg_val, failure, nack0;
+	int rc = 0;
+
+	/* Check for any DDC transfer failures */
+	reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DDC_STATUS);
+	failure = reg_val & HDMI_HDCP_DDC_STATUS_FAILED;
+	nack0 = reg_val & HDMI_HDCP_DDC_STATUS_NACK0;
+	DBG("HDCP_DDC_STATUS=0x%x, FAIL=%d, NACK0=%d",
+		reg_val, failure, nack0);
+
+	if (failure) {
+		/*
+		 * Indicates that the last HDCP HW DDC transfer failed.
+		 * This occurs when a transfer is attempted with HDCP DDC
+		 * disabled (HDCP_DDC_DISABLE=1) or the number of retries
+		 * matches HDCP_DDC_RETRY_CNT.
+		 * Failure occurred,  let's clear it.
+		 */
+		DBG("DDC failure detected");
+
+		/* First, Disable DDC */
+		hdmi_write(hdmi, REG_HDMI_HDCP_DDC_CTRL_0,
+			HDMI_HDCP_DDC_CTRL_0_DISABLE);
+
+		/* ACK the Failure to Clear it */
+		reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DDC_CTRL_1);
+		reg_val |= HDMI_HDCP_DDC_CTRL_1_FAILED_ACK;
+		hdmi_write(hdmi, REG_HDMI_HDCP_DDC_CTRL_1, reg_val);
+
+		/* Check if the FAILURE got Cleared */
+		reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DDC_STATUS);
+		if (reg_val & HDMI_HDCP_DDC_STATUS_FAILED)
+			pr_info("%s: Unable to clear HDCP DDC Failure\n",
+				__func__);
+
+		/* Re-Enable HDCP DDC */
+		hdmi_write(hdmi, REG_HDMI_HDCP_DDC_CTRL_0, 0);
+	}
+
+	if (nack0) {
+		DBG("Before: HDMI_DDC_SW_STATUS=0x%08x",
+			hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS));
+		/* Reset HDMI DDC software status */
+		reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
+		reg_val |= HDMI_DDC_CTRL_SW_STATUS_RESET;
+		hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
+
+		rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
+
+		reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
+		reg_val &= ~HDMI_DDC_CTRL_SW_STATUS_RESET;
+		hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
+
+		/* Reset HDMI DDC Controller */
+		reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
+		reg_val |= HDMI_DDC_CTRL_SOFT_RESET;
+		hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
+
+		/* If previous msleep is aborted, skip this msleep */
+		if (!rc)
+			rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
+
+		reg_val = hdmi_read(hdmi, REG_HDMI_DDC_CTRL);
+		reg_val &= ~HDMI_DDC_CTRL_SOFT_RESET;
+		hdmi_write(hdmi, REG_HDMI_DDC_CTRL, reg_val);
+		DBG("After: HDMI_DDC_SW_STATUS=0x%08x",
+			hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS));
+	}
+
+	return rc;
+}
+
+static int msm_hdmi_hdcp_hw_ddc_clean(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	int rc;
+	u32 hdcp_ddc_status, ddc_hw_status;
+	u32 xfer_done, xfer_req, hw_done;
+	bool hw_not_ready;
+	u32 timeout_count;
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+
+	if (hdmi_read(hdmi, REG_HDMI_DDC_HW_STATUS) == 0)
+		return 0;
+
+	/* Wait to be clean on DDC HW engine */
+	timeout_count = 100;
+	do {
+		hdcp_ddc_status = hdmi_read(hdmi, REG_HDMI_HDCP_DDC_STATUS);
+		ddc_hw_status = hdmi_read(hdmi, REG_HDMI_DDC_HW_STATUS);
+
+		xfer_done = hdcp_ddc_status & HDMI_HDCP_DDC_STATUS_XFER_DONE;
+		xfer_req = hdcp_ddc_status & HDMI_HDCP_DDC_STATUS_XFER_REQ;
+		hw_done = ddc_hw_status & HDMI_DDC_HW_STATUS_DONE;
+		hw_not_ready = !xfer_done || xfer_req || !hw_done;
+
+		if (hw_not_ready)
+			break;
+
+		timeout_count--;
+		if (!timeout_count) {
+			pr_warn("%s: hw_ddc_clean failed\n", __func__);
+			return -ETIMEDOUT;
+		}
+
+		rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
+		if (rc)
+			return rc;
+	} while (1);
+
+	return 0;
+}
+
+static void msm_hdmi_hdcp_reauth_work(struct work_struct *work)
+{
+	struct hdmi_hdcp_ctrl *hdcp_ctrl = container_of(work,
+		struct hdmi_hdcp_ctrl, hdcp_reauth_work);
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	unsigned long flags;
+	u32 reg_val;
+
+	DBG("HDCP REAUTH WORK");
+	/*
+	 * Disable HPD circuitry.
+	 * This is needed to reset the HDCP cipher engine so that when we
+	 * attempt a re-authentication, HW would clear the AN0_READY and
+	 * AN1_READY bits in HDMI_HDCP_LINK0_STATUS register
+	 */
+	spin_lock_irqsave(&hdmi->reg_lock, flags);
+	reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
+	reg_val &= ~HDMI_HPD_CTRL_ENABLE;
+	hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
+
+	/* Disable HDCP interrupts */
+	hdmi_write(hdmi, REG_HDMI_HDCP_INT_CTRL, 0);
+	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+
+	hdmi_write(hdmi, REG_HDMI_HDCP_RESET,
+		HDMI_HDCP_RESET_LINK0_DEAUTHENTICATE);
+
+	/* Wait to be clean on DDC HW engine */
+	if (msm_hdmi_hdcp_hw_ddc_clean(hdcp_ctrl)) {
+		pr_info("%s: reauth work aborted\n", __func__);
+		return;
+	}
+
+	/* Disable encryption and disable the HDCP block */
+	hdmi_write(hdmi, REG_HDMI_HDCP_CTRL, 0);
+
+	/* Enable HPD circuitry */
+	spin_lock_irqsave(&hdmi->reg_lock, flags);
+	reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
+	reg_val |= HDMI_HPD_CTRL_ENABLE;
+	hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
+	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+
+	/*
+	 * Only retry defined times then abort current authenticating process
+	 */
+	if (++hdcp_ctrl->auth_retries == AUTH_RETRIES_TIME) {
+		hdcp_ctrl->hdcp_state = HDCP_STATE_INACTIVE;
+		hdcp_ctrl->auth_retries = 0;
+		pr_info("%s: abort reauthentication!\n", __func__);
+
+		return;
+	}
+
+	DBG("Queue AUTH WORK");
+	hdcp_ctrl->hdcp_state = HDCP_STATE_AUTHENTICATING;
+	queue_work(hdmi->workq, &hdcp_ctrl->hdcp_auth_work);
+}
+
+static int msm_hdmi_hdcp_auth_prepare(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u32 link0_status;
+	u32 reg_val;
+	unsigned long flags;
+	int rc;
+
+	if (!hdcp_ctrl->aksv_valid) {
+		rc = msm_hdmi_hdcp_read_validate_aksv(hdcp_ctrl);
+		if (rc) {
+			pr_err("%s: ASKV validation failed\n", __func__);
+			hdcp_ctrl->hdcp_state = HDCP_STATE_NO_AKSV;
+			return -ENOTSUPP;
+		}
+		hdcp_ctrl->aksv_valid = true;
+	}
+
+	spin_lock_irqsave(&hdmi->reg_lock, flags);
+	/* disable HDMI Encrypt */
+	reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
+	reg_val &= ~HDMI_CTRL_ENCRYPTED;
+	hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
+
+	/* Enabling Software DDC */
+	reg_val = hdmi_read(hdmi, REG_HDMI_DDC_ARBITRATION);
+	reg_val &= ~HDMI_DDC_ARBITRATION_HW_ARBITRATION;
+	hdmi_write(hdmi, REG_HDMI_DDC_ARBITRATION, reg_val);
+	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+
+	/*
+	 * Write AKSV read from QFPROM to the HDCP registers.
+	 * This step is needed for HDCP authentication and must be
+	 * written before enabling HDCP.
+	 */
+	hdmi_write(hdmi, REG_HDMI_HDCP_SW_LOWER_AKSV, hdcp_ctrl->aksv_lsb);
+	hdmi_write(hdmi, REG_HDMI_HDCP_SW_UPPER_AKSV, hdcp_ctrl->aksv_msb);
+
+	/*
+	 * HDCP setup prior to enabling HDCP_CTRL.
+	 * Setup seed values for random number An.
+	 */
+	hdmi_write(hdmi, REG_HDMI_HDCP_ENTROPY_CTRL0, 0xB1FFB0FF);
+	hdmi_write(hdmi, REG_HDMI_HDCP_ENTROPY_CTRL1, 0xF00DFACE);
+
+	/* Disable the RngCipher state */
+	reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_DEBUG_CTRL);
+	reg_val &= ~HDMI_HDCP_DEBUG_CTRL_RNG_CIPHER;
+	hdmi_write(hdmi, REG_HDMI_HDCP_DEBUG_CTRL, reg_val);
+	DBG("HDCP_DEBUG_CTRL=0x%08x",
+		hdmi_read(hdmi, REG_HDMI_HDCP_DEBUG_CTRL));
+
+	/*
+	 * Ensure that all register writes are completed before
+	 * enabling HDCP cipher
+	 */
+	wmb();
+
+	/*
+	 * Enable HDCP
+	 * This needs to be done as early as possible in order for the
+	 * hardware to make An available to read
+	 */
+	hdmi_write(hdmi, REG_HDMI_HDCP_CTRL, HDMI_HDCP_CTRL_ENABLE);
+
+	/*
+	 * If we had stale values for the An ready bit, it should most
+	 * likely be cleared now after enabling HDCP cipher
+	 */
+	link0_status = hdmi_read(hdmi, REG_HDMI_HDCP_LINK0_STATUS);
+	DBG("After enabling HDCP Link0_Status=0x%08x", link0_status);
+	if (!(link0_status &
+		(HDMI_HDCP_LINK0_STATUS_AN_0_READY |
+		HDMI_HDCP_LINK0_STATUS_AN_1_READY)))
+		DBG("An not ready after enabling HDCP");
+
+	/* Clear any DDC failures from previous tries before enable HDCP*/
+	rc = msm_reset_hdcp_ddc_failures(hdcp_ctrl);
+
+	return rc;
+}
+
+static void msm_hdmi_hdcp_auth_fail(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u32 reg_val;
+	unsigned long flags;
+
+	DBG("hdcp auth failed, queue reauth work");
+	/* clear HDMI Encrypt */
+	spin_lock_irqsave(&hdmi->reg_lock, flags);
+	reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
+	reg_val &= ~HDMI_CTRL_ENCRYPTED;
+	hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
+	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+
+	hdcp_ctrl->hdcp_state = HDCP_STATE_AUTH_FAILED;
+	queue_work(hdmi->workq, &hdcp_ctrl->hdcp_reauth_work);
+}
+
+static void msm_hdmi_hdcp_auth_done(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u32 reg_val;
+	unsigned long flags;
+
+	/*
+	 * Disable software DDC before going into part3 to make sure
+	 * there is no Arbitration between software and hardware for DDC
+	 */
+	spin_lock_irqsave(&hdmi->reg_lock, flags);
+	reg_val = hdmi_read(hdmi, REG_HDMI_DDC_ARBITRATION);
+	reg_val |= HDMI_DDC_ARBITRATION_HW_ARBITRATION;
+	hdmi_write(hdmi, REG_HDMI_DDC_ARBITRATION, reg_val);
+	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+
+	/* enable HDMI Encrypt */
+	spin_lock_irqsave(&hdmi->reg_lock, flags);
+	reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
+	reg_val |= HDMI_CTRL_ENCRYPTED;
+	hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
+	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+
+	hdcp_ctrl->hdcp_state = HDCP_STATE_AUTHENTICATED;
+	hdcp_ctrl->auth_retries = 0;
+}
+
+/*
+ * hdcp authenticating part 1
+ * Wait Key/An ready
+ * Read BCAPS from sink
+ * Write BCAPS and AKSV into HDCP engine
+ * Write An and AKSV to sink
+ * Read BKSV from sink and write into HDCP engine
+ */
+static int msm_hdmi_hdcp_wait_key_an_ready(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	int rc;
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u32 link0_status, keys_state;
+	u32 timeout_count;
+	bool an_ready;
+
+	/* Wait for HDCP keys to be checked and validated */
+	timeout_count = 100;
+	do {
+		link0_status = hdmi_read(hdmi, REG_HDMI_HDCP_LINK0_STATUS);
+		keys_state = (link0_status >> 28) & 0x7;
+		if (keys_state == HDCP_KEYS_STATE_VALID)
+			break;
+
+		DBG("Keys not ready(%d). s=%d, l0=%0x08x",
+			timeout_count, keys_state, link0_status);
+
+		timeout_count--;
+		if (!timeout_count) {
+			pr_err("%s: Wait key state timedout", __func__);
+			return -ETIMEDOUT;
+		}
+
+		rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
+		if (rc)
+			return rc;
+	} while (1);
+
+	timeout_count = 100;
+	do {
+		link0_status = hdmi_read(hdmi, REG_HDMI_HDCP_LINK0_STATUS);
+		an_ready = (link0_status & HDMI_HDCP_LINK0_STATUS_AN_0_READY)
+			&& (link0_status & HDMI_HDCP_LINK0_STATUS_AN_1_READY);
+		if (an_ready)
+			break;
+
+		DBG("An not ready(%d). l0_status=0x%08x",
+			timeout_count, link0_status);
+
+		timeout_count--;
+		if (!timeout_count) {
+			pr_err("%s: Wait An timedout", __func__);
+			return -ETIMEDOUT;
+		}
+
+		rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
+		if (rc)
+			return rc;
+	} while (1);
+
+	return 0;
+}
+
+static int msm_hdmi_hdcp_send_aksv_an(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	int rc = 0;
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u32 link0_aksv_0, link0_aksv_1;
+	u32 link0_an[2];
+	u8 aksv[5];
+
+	/* Read An0 and An1 */
+	link0_an[0] = hdmi_read(hdmi, REG_HDMI_HDCP_RCVPORT_DATA5);
+	link0_an[1] = hdmi_read(hdmi, REG_HDMI_HDCP_RCVPORT_DATA6);
+
+	/* Read AKSV */
+	link0_aksv_0 = hdmi_read(hdmi, REG_HDMI_HDCP_RCVPORT_DATA3);
+	link0_aksv_1 = hdmi_read(hdmi, REG_HDMI_HDCP_RCVPORT_DATA4);
+
+	DBG("Link ASKV=%08x%08x", link0_aksv_0, link0_aksv_1);
+	/* Copy An and AKSV to byte arrays for transmission */
+	aksv[0] =  link0_aksv_0        & 0xFF;
+	aksv[1] = (link0_aksv_0 >> 8)  & 0xFF;
+	aksv[2] = (link0_aksv_0 >> 16) & 0xFF;
+	aksv[3] = (link0_aksv_0 >> 24) & 0xFF;
+	aksv[4] =  link0_aksv_1        & 0xFF;
+
+	/* Write An to offset 0x18 */
+	rc = msm_hdmi_ddc_write(hdmi, HDCP_PORT_ADDR, 0x18, (u8 *)link0_an,
+		(u16)sizeof(link0_an));
+	if (rc) {
+		pr_err("%s:An write failed\n", __func__);
+		return rc;
+	}
+	DBG("Link0-An=%08x%08x", link0_an[0], link0_an[1]);
+
+	/* Write AKSV to offset 0x10 */
+	rc = msm_hdmi_ddc_write(hdmi, HDCP_PORT_ADDR, 0x10, aksv, 5);
+	if (rc) {
+		pr_err("%s:AKSV write failed\n", __func__);
+		return rc;
+	}
+	DBG("Link0-AKSV=%02x%08x", link0_aksv_1 & 0xFF, link0_aksv_0);
+
+	return 0;
+}
+
+static int msm_hdmi_hdcp_recv_bksv(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	int rc = 0;
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u8 bksv[5];
+	u32 reg[2], data[2];
+
+	/* Read BKSV at offset 0x00 */
+	rc = msm_hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x00, bksv, 5);
+	if (rc) {
+		pr_err("%s:BKSV read failed\n", __func__);
+		return rc;
+	}
+
+	hdcp_ctrl->bksv_lsb = bksv[0] | (bksv[1] << 8) |
+		(bksv[2] << 16) | (bksv[3] << 24);
+	hdcp_ctrl->bksv_msb = bksv[4];
+	DBG(":BKSV=%02x%08x", hdcp_ctrl->bksv_msb, hdcp_ctrl->bksv_lsb);
+
+	/* check there are 20 ones in BKSV */
+	if ((hweight32(hdcp_ctrl->bksv_lsb) + hweight32(hdcp_ctrl->bksv_msb))
+			!= 20) {
+		pr_err(": BKSV doesn't have 20 1's and 20 0's\n");
+		pr_err(": BKSV chk fail. BKSV=%02x%02x%02x%02x%02x\n",
+			bksv[4], bksv[3], bksv[2], bksv[1], bksv[0]);
+		return -EINVAL;
+	}
+
+	/* Write BKSV read from sink to HDCP registers */
+	reg[0] = REG_HDMI_HDCP_RCVPORT_DATA0;
+	data[0] = hdcp_ctrl->bksv_lsb;
+	reg[1] = REG_HDMI_HDCP_RCVPORT_DATA1;
+	data[1] = hdcp_ctrl->bksv_msb;
+	rc = msm_hdmi_hdcp_scm_wr(hdcp_ctrl, reg, data, 2);
+
+	return rc;
+}
+
+static int msm_hdmi_hdcp_recv_bcaps(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	int rc = 0;
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u32 reg, data;
+	u8 bcaps;
+
+	rc = msm_hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x40, &bcaps, 1);
+	if (rc) {
+		pr_err("%s:BCAPS read failed\n", __func__);
+		return rc;
+	}
+	DBG("BCAPS=%02x", bcaps);
+
+	/* receiver (0), repeater (1) */
+	hdcp_ctrl->ds_type = (bcaps & BIT(6)) ? DS_REPEATER : DS_RECEIVER;
+
+	/* Write BCAPS to the hardware */
+	reg = REG_HDMI_HDCP_RCVPORT_DATA12;
+	data = (u32)bcaps;
+	rc = msm_hdmi_hdcp_scm_wr(hdcp_ctrl, &reg, &data, 1);
+
+	return rc;
+}
+
+static int msm_hdmi_hdcp_auth_part1_key_exchange(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	unsigned long flags;
+	int rc;
+
+	/* Wait for AKSV key and An ready */
+	rc = msm_hdmi_hdcp_wait_key_an_ready(hdcp_ctrl);
+	if (rc) {
+		pr_err("%s: wait key and an ready failed\n", __func__);
+		return rc;
+	}
+
+	/* Read BCAPS and send to HDCP engine */
+	rc = msm_hdmi_hdcp_recv_bcaps(hdcp_ctrl);
+	if (rc) {
+		pr_err("%s: read bcaps error, abort\n", __func__);
+		return rc;
+	}
+
+	/*
+	 * 1.1_Features turned off by default.
+	 * No need to write AInfo since 1.1_Features is disabled.
+	 */
+	hdmi_write(hdmi, REG_HDMI_HDCP_RCVPORT_DATA4, 0);
+
+	/* Send AKSV and An to sink */
+	rc = msm_hdmi_hdcp_send_aksv_an(hdcp_ctrl);
+	if (rc) {
+		pr_err("%s:An/Aksv write failed\n", __func__);
+		return rc;
+	}
+
+	/* Read BKSV and send to HDCP engine*/
+	rc = msm_hdmi_hdcp_recv_bksv(hdcp_ctrl);
+	if (rc) {
+		pr_err("%s:BKSV Process failed\n", __func__);
+		return rc;
+	}
+
+	/* Enable HDCP interrupts and ack/clear any stale interrupts */
+	spin_lock_irqsave(&hdmi->reg_lock, flags);
+	hdmi_write(hdmi, REG_HDMI_HDCP_INT_CTRL,
+		HDMI_HDCP_INT_CTRL_AUTH_SUCCESS_ACK |
+		HDMI_HDCP_INT_CTRL_AUTH_SUCCESS_MASK |
+		HDMI_HDCP_INT_CTRL_AUTH_FAIL_ACK |
+		HDMI_HDCP_INT_CTRL_AUTH_FAIL_MASK |
+		HDMI_HDCP_INT_CTRL_AUTH_FAIL_INFO_ACK);
+	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+
+	return 0;
+}
+
+/* read R0' from sink and pass it to HDCP engine */
+static int msm_hdmi_hdcp_auth_part1_recv_r0(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	int rc = 0;
+	u8 buf[2];
+
+	/*
+	 * HDCP Compliance Test case 1A-01:
+	 * Wait here at least 100ms before reading R0'
+	 */
+	rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 125, AUTH_ABORT_EV);
+	if (rc)
+		return rc;
+
+	/* Read R0' at offset 0x08 */
+	rc = msm_hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x08, buf, 2);
+	if (rc) {
+		pr_err("%s:R0' read failed\n", __func__);
+		return rc;
+	}
+	DBG("R0'=%02x%02x", buf[1], buf[0]);
+
+	/* Write R0' to HDCP registers and check to see if it is a match */
+	hdmi_write(hdmi, REG_HDMI_HDCP_RCVPORT_DATA2_0,
+		(((u32)buf[1]) << 8) | buf[0]);
+
+	return 0;
+}
+
+/* Wait for authenticating result: R0/R0' are matched or not */
+static int msm_hdmi_hdcp_auth_part1_verify_r0(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u32 link0_status;
+	int rc;
+
+	/* wait for hdcp irq, 10 sec should be long enough */
+	rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 10000, AUTH_RESULT_RDY_EV);
+	if (!rc) {
+		pr_err("%s: Wait Auth IRQ timeout\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	link0_status = hdmi_read(hdmi, REG_HDMI_HDCP_LINK0_STATUS);
+	if (!(link0_status & HDMI_HDCP_LINK0_STATUS_RI_MATCHES)) {
+		pr_err("%s: Authentication Part I failed\n", __func__);
+		return -EINVAL;
+	}
+
+	/* Enable HDCP Encryption */
+	hdmi_write(hdmi, REG_HDMI_HDCP_CTRL,
+		HDMI_HDCP_CTRL_ENABLE |
+		HDMI_HDCP_CTRL_ENCRYPTION_ENABLE);
+
+	return 0;
+}
+
+static int msm_hdmi_hdcp_recv_check_bstatus(struct hdmi_hdcp_ctrl *hdcp_ctrl,
+	u16 *pbstatus)
+{
+	int rc;
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	bool max_devs_exceeded = false, max_cascade_exceeded = false;
+	u32 repeater_cascade_depth = 0, down_stream_devices = 0;
+	u16 bstatus;
+	u8 buf[2];
+
+	/* Read BSTATUS at offset 0x41 */
+	rc = msm_hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x41, buf, 2);
+	if (rc) {
+		pr_err("%s: BSTATUS read failed\n", __func__);
+		goto error;
+	}
+	*pbstatus = bstatus = (buf[1] << 8) | buf[0];
+
+
+	down_stream_devices = bstatus & 0x7F;
+	repeater_cascade_depth = (bstatus >> 8) & 0x7;
+	max_devs_exceeded = (bstatus & BIT(7)) ? true : false;
+	max_cascade_exceeded = (bstatus & BIT(11)) ? true : false;
+
+	if (down_stream_devices == 0) {
+		/*
+		 * If no downstream devices are attached to the repeater
+		 * then part II fails.
+		 * todo: The other approach would be to continue PART II.
+		 */
+		pr_err("%s: No downstream devices\n", __func__);
+		rc = -EINVAL;
+		goto error;
+	}
+
+	/*
+	 * HDCP Compliance 1B-05:
+	 * Check if no. of devices connected to repeater
+	 * exceed max_devices_connected from bit 7 of Bstatus.
+	 */
+	if (max_devs_exceeded) {
+		pr_err("%s: no. of devs connected exceeds max allowed",
+			__func__);
+		rc = -EINVAL;
+		goto error;
+	}
+
+	/*
+	 * HDCP Compliance 1B-06:
+	 * Check if no. of cascade connected to repeater
+	 * exceed max_cascade_connected from bit 11 of Bstatus.
+	 */
+	if (max_cascade_exceeded) {
+		pr_err("%s: no. of cascade conn exceeds max allowed",
+			__func__);
+		rc = -EINVAL;
+		goto error;
+	}
+
+error:
+	hdcp_ctrl->dev_count = down_stream_devices;
+	hdcp_ctrl->max_cascade_exceeded = max_cascade_exceeded;
+	hdcp_ctrl->max_dev_exceeded = max_devs_exceeded;
+	hdcp_ctrl->depth = repeater_cascade_depth;
+	return rc;
+}
+
+static int msm_hdmi_hdcp_auth_part2_wait_ksv_fifo_ready(
+	struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	int rc;
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u32 reg, data;
+	u32 timeout_count;
+	u16 bstatus;
+	u8 bcaps;
+
+	/*
+	 * Wait until READY bit is set in BCAPS, as per HDCP specifications
+	 * maximum permitted time to check for READY bit is five seconds.
+	 */
+	timeout_count = 100;
+	do {
+		/* Read BCAPS at offset 0x40 */
+		rc = msm_hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x40, &bcaps, 1);
+		if (rc) {
+			pr_err("%s: BCAPS read failed\n", __func__);
+			return rc;
+		}
+
+		if (bcaps & BIT(5))
+			break;
+
+		timeout_count--;
+		if (!timeout_count) {
+			pr_err("%s: Wait KSV fifo ready timedout", __func__);
+			return -ETIMEDOUT;
+		}
+
+		rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
+		if (rc)
+			return rc;
+	} while (1);
+
+	rc = msm_hdmi_hdcp_recv_check_bstatus(hdcp_ctrl, &bstatus);
+	if (rc) {
+		pr_err("%s: bstatus error\n", __func__);
+		return rc;
+	}
+
+	/* Write BSTATUS and BCAPS to HDCP registers */
+	reg = REG_HDMI_HDCP_RCVPORT_DATA12;
+	data = bcaps | (bstatus << 8);
+	rc = msm_hdmi_hdcp_scm_wr(hdcp_ctrl, &reg, &data, 1);
+	if (rc) {
+		pr_err("%s: BSTATUS write failed\n", __func__);
+		return rc;
+	}
+
+	return 0;
+}
+
+/*
+ * hdcp authenticating part 2: 2nd
+ * read ksv fifo from sink
+ * transfer V' from sink to HDCP engine
+ * reset SHA engine
+ */
+static int msm_hdmi_hdcp_transfer_v_h(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	int rc = 0;
+	struct hdmi_hdcp_reg_data reg_data[]  = {
+		{REG_HDMI_HDCP_RCVPORT_DATA7,  0x20, "V' H0"},
+		{REG_HDMI_HDCP_RCVPORT_DATA8,  0x24, "V' H1"},
+		{REG_HDMI_HDCP_RCVPORT_DATA9,  0x28, "V' H2"},
+		{REG_HDMI_HDCP_RCVPORT_DATA10, 0x2C, "V' H3"},
+		{REG_HDMI_HDCP_RCVPORT_DATA11, 0x30, "V' H4"},
+	};
+	struct hdmi_hdcp_reg_data *rd;
+	u32 size = ARRAY_SIZE(reg_data);
+	u32 reg[ARRAY_SIZE(reg_data)];
+	u32 data[ARRAY_SIZE(reg_data)];
+	int i;
+
+	for (i = 0; i < size; i++) {
+		rd = &reg_data[i];
+		rc = msm_hdmi_ddc_read(hdmi, HDCP_PORT_ADDR,
+			rd->off, (u8 *)&data[i], (u16)sizeof(data[i]));
+		if (rc) {
+			pr_err("%s: Read %s failed\n", __func__, rd->name);
+			goto error;
+		}
+
+		DBG("%s =%x", rd->name, data[i]);
+		reg[i] = reg_data[i].reg_id;
+	}
+
+	rc = msm_hdmi_hdcp_scm_wr(hdcp_ctrl, reg, data, size);
+
+error:
+	return rc;
+}
+
+static int msm_hdmi_hdcp_recv_ksv_fifo(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	int rc;
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u32 ksv_bytes;
+
+	ksv_bytes = 5 * hdcp_ctrl->dev_count;
+
+	rc = msm_hdmi_ddc_read(hdmi, HDCP_PORT_ADDR, 0x43,
+		hdcp_ctrl->ksv_list, ksv_bytes);
+	if (rc)
+		pr_err("%s: KSV FIFO read failed\n", __func__);
+
+	return rc;
+}
+
+static int msm_hdmi_hdcp_reset_sha_engine(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	u32 reg[2], data[2];
+	u32 rc  = 0;
+
+	reg[0] = REG_HDMI_HDCP_SHA_CTRL;
+	data[0] = HDCP_REG_ENABLE;
+	reg[1] = REG_HDMI_HDCP_SHA_CTRL;
+	data[1] = HDCP_REG_DISABLE;
+
+	rc = msm_hdmi_hdcp_scm_wr(hdcp_ctrl, reg, data, 2);
+
+	return rc;
+}
+
+static int msm_hdmi_hdcp_auth_part2_recv_ksv_fifo(
+	struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	int rc;
+	u32 timeout_count;
+
+	/*
+	 * Read KSV FIFO over DDC
+	 * Key Selection vector FIFO Used to pull downstream KSVs
+	 * from HDCP Repeaters.
+	 * All bytes (DEVICE_COUNT * 5) must be read in a single,
+	 * auto incrementing access.
+	 * All bytes read as 0x00 for HDCP Receivers that are not
+	 * HDCP Repeaters (REPEATER == 0).
+	 */
+	timeout_count = 100;
+	do {
+		rc = msm_hdmi_hdcp_recv_ksv_fifo(hdcp_ctrl);
+		if (!rc)
+			break;
+
+		timeout_count--;
+		if (!timeout_count) {
+			pr_err("%s: Recv ksv fifo timedout", __func__);
+			return -ETIMEDOUT;
+		}
+
+		rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 25, AUTH_ABORT_EV);
+		if (rc)
+			return rc;
+	} while (1);
+
+	rc = msm_hdmi_hdcp_transfer_v_h(hdcp_ctrl);
+	if (rc) {
+		pr_err("%s: transfer V failed\n", __func__);
+		return rc;
+	}
+
+	/* reset SHA engine before write ksv fifo */
+	rc = msm_hdmi_hdcp_reset_sha_engine(hdcp_ctrl);
+	if (rc) {
+		pr_err("%s: fail to reset sha engine\n", __func__);
+		return rc;
+	}
+
+	return 0;
+}
+
+/*
+ * Write KSV FIFO to HDCP_SHA_DATA.
+ * This is done 1 byte at time starting with the LSB.
+ * Once 64 bytes have been written, we need to poll for
+ * HDCP_SHA_BLOCK_DONE before writing any further
+ * If the last byte is written, we need to poll for
+ * HDCP_SHA_COMP_DONE to wait until HW finish
+ */
+static int msm_hdmi_hdcp_write_ksv_fifo(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	int i;
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u32 ksv_bytes, last_byte = 0;
+	u8 *ksv_fifo = NULL;
+	u32 reg_val, data, reg;
+	u32 rc  = 0;
+
+	ksv_bytes  = 5 * hdcp_ctrl->dev_count;
+
+	/* Check if need to wait for HW completion */
+	if (hdcp_ctrl->ksv_fifo_w_index) {
+		reg_val = hdmi_read(hdmi, REG_HDMI_HDCP_SHA_STATUS);
+		DBG("HDCP_SHA_STATUS=%08x", reg_val);
+		if (hdcp_ctrl->ksv_fifo_w_index == ksv_bytes) {
+			/* check COMP_DONE if last write */
+			if (reg_val & HDMI_HDCP_SHA_STATUS_COMP_DONE) {
+				DBG("COMP_DONE");
+				return 0;
+			} else {
+				return -EAGAIN;
+			}
+		} else {
+			/* check BLOCK_DONE if not last write */
+			if (!(reg_val & HDMI_HDCP_SHA_STATUS_BLOCK_DONE))
+				return -EAGAIN;
+
+			DBG("BLOCK_DONE");
+		}
+	}
+
+	ksv_bytes  -= hdcp_ctrl->ksv_fifo_w_index;
+	if (ksv_bytes <= 64)
+		last_byte = 1;
+	else
+		ksv_bytes = 64;
+
+	ksv_fifo = hdcp_ctrl->ksv_list;
+	ksv_fifo += hdcp_ctrl->ksv_fifo_w_index;
+
+	for (i = 0; i < ksv_bytes; i++) {
+		/* Write KSV byte and set DONE bit[0] for last byte*/
+		reg_val = ksv_fifo[i] << 16;
+		if ((i == (ksv_bytes - 1)) && last_byte)
+			reg_val |= HDMI_HDCP_SHA_DATA_DONE;
+
+		reg = REG_HDMI_HDCP_SHA_DATA;
+		data = reg_val;
+		rc = msm_hdmi_hdcp_scm_wr(hdcp_ctrl, &reg, &data, 1);
+
+		if (rc)
+			return rc;
+	}
+
+	hdcp_ctrl->ksv_fifo_w_index += ksv_bytes;
+
+	/*
+	 *return -EAGAIN to notify caller to wait for COMP_DONE or BLOCK_DONE
+	 */
+	return -EAGAIN;
+}
+
+/* write ksv fifo into HDCP engine */
+static int msm_hdmi_hdcp_auth_part2_write_ksv_fifo(
+	struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	int rc;
+	u32 timeout_count;
+
+	hdcp_ctrl->ksv_fifo_w_index = 0;
+	timeout_count = 100;
+	do {
+		rc = msm_hdmi_hdcp_write_ksv_fifo(hdcp_ctrl);
+		if (!rc)
+			break;
+
+		if (rc != -EAGAIN)
+			return rc;
+
+		timeout_count--;
+		if (!timeout_count) {
+			pr_err("%s: Write KSV fifo timedout", __func__);
+			return -ETIMEDOUT;
+		}
+
+		rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
+		if (rc)
+			return rc;
+	} while (1);
+
+	return 0;
+}
+
+static int msm_hdmi_hdcp_auth_part2_check_v_match(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	int rc = 0;
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u32 link0_status;
+	u32 timeout_count = 100;
+
+	do {
+		link0_status = hdmi_read(hdmi, REG_HDMI_HDCP_LINK0_STATUS);
+		if (link0_status & HDMI_HDCP_LINK0_STATUS_V_MATCHES)
+			break;
+
+		timeout_count--;
+		if (!timeout_count) {
+				pr_err("%s: HDCP V Match timedout", __func__);
+				return -ETIMEDOUT;
+		}
+
+		rc = msm_hdmi_hdcp_msleep(hdcp_ctrl, 20, AUTH_ABORT_EV);
+		if (rc)
+			return rc;
+	} while (1);
+
+	return 0;
+}
+
+static void msm_hdmi_hdcp_auth_work(struct work_struct *work)
+{
+	struct hdmi_hdcp_ctrl *hdcp_ctrl = container_of(work,
+		struct hdmi_hdcp_ctrl, hdcp_auth_work);
+	int rc;
+
+	rc = msm_hdmi_hdcp_auth_prepare(hdcp_ctrl);
+	if (rc) {
+		pr_err("%s: auth prepare failed %d\n", __func__, rc);
+		goto end;
+	}
+
+	/* HDCP PartI */
+	rc = msm_hdmi_hdcp_auth_part1_key_exchange(hdcp_ctrl);
+	if (rc) {
+		pr_err("%s: key exchange failed %d\n", __func__, rc);
+		goto end;
+	}
+
+	rc = msm_hdmi_hdcp_auth_part1_recv_r0(hdcp_ctrl);
+	if (rc) {
+		pr_err("%s: receive r0 failed %d\n", __func__, rc);
+		goto end;
+	}
+
+	rc = msm_hdmi_hdcp_auth_part1_verify_r0(hdcp_ctrl);
+	if (rc) {
+		pr_err("%s: verify r0 failed %d\n", __func__, rc);
+		goto end;
+	}
+	pr_info("%s: Authentication Part I successful\n", __func__);
+	if (hdcp_ctrl->ds_type == DS_RECEIVER)
+		goto end;
+
+	/* HDCP PartII */
+	rc = msm_hdmi_hdcp_auth_part2_wait_ksv_fifo_ready(hdcp_ctrl);
+	if (rc) {
+		pr_err("%s: wait ksv fifo ready failed %d\n", __func__, rc);
+		goto end;
+	}
+
+	rc = msm_hdmi_hdcp_auth_part2_recv_ksv_fifo(hdcp_ctrl);
+	if (rc) {
+		pr_err("%s: recv ksv fifo failed %d\n", __func__, rc);
+		goto end;
+	}
+
+	rc = msm_hdmi_hdcp_auth_part2_write_ksv_fifo(hdcp_ctrl);
+	if (rc) {
+		pr_err("%s: write ksv fifo failed %d\n", __func__, rc);
+		goto end;
+	}
+
+	rc = msm_hdmi_hdcp_auth_part2_check_v_match(hdcp_ctrl);
+	if (rc)
+		pr_err("%s: check v match failed %d\n", __func__, rc);
+
+end:
+	if (rc == -ECANCELED) {
+		pr_info("%s: hdcp authentication canceled\n", __func__);
+	} else if (rc == -ENOTSUPP) {
+		pr_info("%s: hdcp is not supported\n", __func__);
+	} else if (rc) {
+		pr_err("%s: hdcp authentication failed\n", __func__);
+		msm_hdmi_hdcp_auth_fail(hdcp_ctrl);
+	} else {
+		msm_hdmi_hdcp_auth_done(hdcp_ctrl);
+	}
+}
+
+void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	u32 reg_val;
+	unsigned long flags;
+
+	if ((HDCP_STATE_INACTIVE != hdcp_ctrl->hdcp_state) ||
+		(HDCP_STATE_NO_AKSV == hdcp_ctrl->hdcp_state)) {
+		DBG("still active or activating or no askv. returning");
+		return;
+	}
+
+	/* clear HDMI Encrypt */
+	spin_lock_irqsave(&hdmi->reg_lock, flags);
+	reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
+	reg_val &= ~HDMI_CTRL_ENCRYPTED;
+	hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
+	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+
+	hdcp_ctrl->auth_event = 0;
+	hdcp_ctrl->hdcp_state = HDCP_STATE_AUTHENTICATING;
+	hdcp_ctrl->auth_retries = 0;
+	queue_work(hdmi->workq, &hdcp_ctrl->hdcp_auth_work);
+}
+
+void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl)
+{
+	struct hdmi *hdmi = hdcp_ctrl->hdmi;
+	unsigned long flags;
+	u32 reg_val;
+
+	if ((HDCP_STATE_INACTIVE == hdcp_ctrl->hdcp_state) ||
+		(HDCP_STATE_NO_AKSV == hdcp_ctrl->hdcp_state)) {
+		DBG("hdcp inactive or no aksv. returning");
+		return;
+	}
+
+	/*
+	 * Disable HPD circuitry.
+	 * This is needed to reset the HDCP cipher engine so that when we
+	 * attempt a re-authentication, HW would clear the AN0_READY and
+	 * AN1_READY bits in HDMI_HDCP_LINK0_STATUS register
+	 */
+	spin_lock_irqsave(&hdmi->reg_lock, flags);
+	reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
+	reg_val &= ~HDMI_HPD_CTRL_ENABLE;
+	hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
+
+	/*
+	 * Disable HDCP interrupts.
+	 * Also, need to set the state to inactive here so that any ongoing
+	 * reauth works will know that the HDCP session has been turned off.
+	 */
+	hdmi_write(hdmi, REG_HDMI_HDCP_INT_CTRL, 0);
+	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+
+	/*
+	 * Cancel any pending auth/reauth attempts.
+	 * If one is ongoing, this will wait for it to finish.
+	 * No more reauthentication attempts will be scheduled since we
+	 * set the current state to inactive.
+	 */
+	set_bit(AUTH_ABORT_EV, &hdcp_ctrl->auth_event);
+	wake_up_all(&hdcp_ctrl->auth_event_queue);
+	cancel_work_sync(&hdcp_ctrl->hdcp_auth_work);
+	cancel_work_sync(&hdcp_ctrl->hdcp_reauth_work);
+
+	hdmi_write(hdmi, REG_HDMI_HDCP_RESET,
+		HDMI_HDCP_RESET_LINK0_DEAUTHENTICATE);
+
+	/* Disable encryption and disable the HDCP block */
+	hdmi_write(hdmi, REG_HDMI_HDCP_CTRL, 0);
+
+	spin_lock_irqsave(&hdmi->reg_lock, flags);
+	reg_val = hdmi_read(hdmi, REG_HDMI_CTRL);
+	reg_val &= ~HDMI_CTRL_ENCRYPTED;
+	hdmi_write(hdmi, REG_HDMI_CTRL, reg_val);
+
+	/* Enable HPD circuitry */
+	reg_val = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
+	reg_val |= HDMI_HPD_CTRL_ENABLE;
+	hdmi_write(hdmi, REG_HDMI_HPD_CTRL, reg_val);
+	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+
+	hdcp_ctrl->hdcp_state = HDCP_STATE_INACTIVE;
+
+	DBG("HDCP: Off");
+}
+
+struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi)
+{
+	struct hdmi_hdcp_ctrl *hdcp_ctrl = NULL;
+
+	if (!hdmi->qfprom_mmio) {
+		pr_err("%s: HDCP is not supported without qfprom\n",
+			__func__);
+		return ERR_PTR(-EINVAL);
+	}
+
+	hdcp_ctrl = kzalloc(sizeof(*hdcp_ctrl), GFP_KERNEL);
+	if (!hdcp_ctrl)
+		return ERR_PTR(-ENOMEM);
+
+	INIT_WORK(&hdcp_ctrl->hdcp_auth_work, msm_hdmi_hdcp_auth_work);
+	INIT_WORK(&hdcp_ctrl->hdcp_reauth_work, msm_hdmi_hdcp_reauth_work);
+	init_waitqueue_head(&hdcp_ctrl->auth_event_queue);
+	hdcp_ctrl->hdmi = hdmi;
+	hdcp_ctrl->hdcp_state = HDCP_STATE_INACTIVE;
+	hdcp_ctrl->aksv_valid = false;
+
+	if (qcom_scm_hdcp_available())
+		hdcp_ctrl->tz_hdcp = true;
+	else
+		hdcp_ctrl->tz_hdcp = false;
+
+	return hdcp_ctrl;
+}
+
+void msm_hdmi_hdcp_destroy(struct hdmi *hdmi)
+{
+	if (hdmi) {
+		kfree(hdmi->hdcp_ctrl);
+		hdmi->hdcp_ctrl = NULL;
+	}
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/hdmi_hpd.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/hdmi_hpd.c
@@ -0,0 +1,262 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/pinctrl/consumer.h>
+
+#include "msm_kms.h"
+#include "hdmi.h"
+
+static void msm_hdmi_phy_reset(struct hdmi *hdmi)
+{
+	unsigned int val;
+
+	val = hdmi_read(hdmi, REG_HDMI_PHY_CTRL);
+
+	if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
+		/* pull low */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val & ~HDMI_PHY_CTRL_SW_RESET);
+	} else {
+		/* pull high */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val | HDMI_PHY_CTRL_SW_RESET);
+	}
+
+	if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
+		/* pull low */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
+	} else {
+		/* pull high */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val | HDMI_PHY_CTRL_SW_RESET_PLL);
+	}
+
+	msleep(100);
+
+	if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
+		/* pull high */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val | HDMI_PHY_CTRL_SW_RESET);
+	} else {
+		/* pull low */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val & ~HDMI_PHY_CTRL_SW_RESET);
+	}
+
+	if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
+		/* pull high */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val | HDMI_PHY_CTRL_SW_RESET_PLL);
+	} else {
+		/* pull low */
+		hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+				val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
+	}
+}
+
+static void enable_hpd_clocks(struct hdmi *hdmi, bool enable)
+{
+	const struct hdmi_platform_config *config = hdmi->config;
+	struct device *dev = &hdmi->pdev->dev;
+	int i, ret;
+
+	if (enable) {
+		for (i = 0; i < config->hpd_clk_cnt; i++) {
+			if (config->hpd_freq && config->hpd_freq[i]) {
+				ret = clk_set_rate(hdmi->hpd_clks[i],
+						   config->hpd_freq[i]);
+				if (ret)
+					dev_warn(dev,
+						 "failed to set clk %s (%d)\n",
+						 config->hpd_clk_names[i], ret);
+			}
+
+			ret = clk_prepare_enable(hdmi->hpd_clks[i]);
+			if (ret) {
+				DRM_DEV_ERROR(dev,
+					"failed to enable hpd clk: %s (%d)\n",
+					config->hpd_clk_names[i], ret);
+			}
+		}
+	} else {
+		for (i = config->hpd_clk_cnt - 1; i >= 0; i--)
+			clk_disable_unprepare(hdmi->hpd_clks[i]);
+	}
+}
+
+int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
+{
+	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+	struct hdmi *hdmi = hdmi_bridge->hdmi;
+	const struct hdmi_platform_config *config = hdmi->config;
+	struct device *dev = &hdmi->pdev->dev;
+	uint32_t hpd_ctrl;
+	int ret;
+	unsigned long flags;
+
+	ret = regulator_bulk_enable(config->hpd_reg_cnt, hdmi->hpd_regs);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "failed to enable hpd regulators: %d\n", ret);
+		goto fail;
+	}
+
+	ret = pinctrl_pm_select_default_state(dev);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "pinctrl state chg failed: %d\n", ret);
+		goto fail;
+	}
+
+	if (hdmi->hpd_gpiod)
+		gpiod_set_value_cansleep(hdmi->hpd_gpiod, 1);
+
+	pm_runtime_get_sync(dev);
+	enable_hpd_clocks(hdmi, true);
+
+	msm_hdmi_set_mode(hdmi, false);
+	msm_hdmi_phy_reset(hdmi);
+	msm_hdmi_set_mode(hdmi, true);
+
+	hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b);
+
+	/* enable HPD events: */
+	hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
+			HDMI_HPD_INT_CTRL_INT_CONNECT |
+			HDMI_HPD_INT_CTRL_INT_EN);
+
+	/* set timeout to 4.1ms (max) for hardware debounce */
+	spin_lock_irqsave(&hdmi->reg_lock, flags);
+	hpd_ctrl = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
+	hpd_ctrl |= HDMI_HPD_CTRL_TIMEOUT(0x1fff);
+
+	/* Toggle HPD circuit to trigger HPD sense */
+	hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
+			~HDMI_HPD_CTRL_ENABLE & hpd_ctrl);
+	hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
+			HDMI_HPD_CTRL_ENABLE | hpd_ctrl);
+	spin_unlock_irqrestore(&hdmi->reg_lock, flags);
+
+	return 0;
+
+fail:
+	return ret;
+}
+
+void msm_hdmi_hpd_disable(struct hdmi *hdmi)
+{
+	const struct hdmi_platform_config *config = hdmi->config;
+	struct device *dev = &hdmi->pdev->dev;
+	int ret;
+
+	/* Disable HPD interrupt */
+	hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, 0);
+
+	msm_hdmi_set_mode(hdmi, false);
+
+	enable_hpd_clocks(hdmi, false);
+	pm_runtime_put(dev);
+
+	ret = pinctrl_pm_select_sleep_state(dev);
+	if (ret)
+		dev_warn(dev, "pinctrl state chg failed: %d\n", ret);
+
+	ret = regulator_bulk_disable(config->hpd_reg_cnt, hdmi->hpd_regs);
+	if (ret)
+		dev_warn(dev, "failed to disable hpd regulator: %d\n", ret);
+}
+
+void msm_hdmi_hpd_irq(struct drm_bridge *bridge)
+{
+	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+	struct hdmi *hdmi = hdmi_bridge->hdmi;
+	uint32_t hpd_int_status, hpd_int_ctrl;
+
+	/* Process HPD: */
+	hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
+	hpd_int_ctrl   = hdmi_read(hdmi, REG_HDMI_HPD_INT_CTRL);
+
+	if ((hpd_int_ctrl & HDMI_HPD_INT_CTRL_INT_EN) &&
+			(hpd_int_status & HDMI_HPD_INT_STATUS_INT)) {
+		bool detected = !!(hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED);
+
+		/* ack & disable (temporarily) HPD events: */
+		hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
+			HDMI_HPD_INT_CTRL_INT_ACK);
+
+		DBG("status=%04x, ctrl=%04x", hpd_int_status, hpd_int_ctrl);
+
+		/* detect disconnect if we are connected or visa versa: */
+		hpd_int_ctrl = HDMI_HPD_INT_CTRL_INT_EN;
+		if (!detected)
+			hpd_int_ctrl |= HDMI_HPD_INT_CTRL_INT_CONNECT;
+		hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, hpd_int_ctrl);
+
+		queue_work(hdmi->workq, &hdmi_bridge->hpd_work);
+	}
+}
+
+static enum drm_connector_status detect_reg(struct hdmi *hdmi)
+{
+	uint32_t hpd_int_status;
+
+	pm_runtime_get_sync(&hdmi->pdev->dev);
+	enable_hpd_clocks(hdmi, true);
+
+	hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
+
+	enable_hpd_clocks(hdmi, false);
+	pm_runtime_put(&hdmi->pdev->dev);
+
+	return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
+			connector_status_connected : connector_status_disconnected;
+}
+
+#define HPD_GPIO_INDEX	2
+static enum drm_connector_status detect_gpio(struct hdmi *hdmi)
+{
+	return gpiod_get_value(hdmi->hpd_gpiod) ?
+			connector_status_connected :
+			connector_status_disconnected;
+}
+
+enum drm_connector_status msm_hdmi_bridge_detect(
+		struct drm_bridge *bridge)
+{
+	struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+	struct hdmi *hdmi = hdmi_bridge->hdmi;
+	enum drm_connector_status stat_gpio, stat_reg;
+	int retry = 20;
+
+	/*
+	 * some platforms may not have hpd gpio. Rely only on the status
+	 * provided by REG_HDMI_HPD_INT_STATUS in this case.
+	 */
+	if (!hdmi->hpd_gpiod)
+		return detect_reg(hdmi);
+
+	do {
+		stat_gpio = detect_gpio(hdmi);
+		stat_reg  = detect_reg(hdmi);
+
+		if (stat_gpio == stat_reg)
+			break;
+
+		mdelay(10);
+	} while (--retry);
+
+	/* the status we get from reading gpio seems to be more reliable,
+	 * so trust that one the most if we didn't manage to get hdmi and
+	 * gpio status to agree:
+	 */
+	if (stat_gpio != stat_reg) {
+		DBG("HDMI_HPD_INT_STATUS tells us: %d", stat_reg);
+		DBG("hpd gpio tells us: %d", stat_gpio);
+	}
+
+	return stat_gpio;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/hdmi_i2c.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/hdmi_i2c.c
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include "hdmi.h"
+
+struct hdmi_i2c_adapter {
+	struct i2c_adapter base;
+	struct hdmi *hdmi;
+	bool sw_done;
+	wait_queue_head_t ddc_event;
+};
+#define to_hdmi_i2c_adapter(x) container_of(x, struct hdmi_i2c_adapter, base)
+
+static void init_ddc(struct hdmi_i2c_adapter *hdmi_i2c)
+{
+	struct hdmi *hdmi = hdmi_i2c->hdmi;
+
+	hdmi_write(hdmi, REG_HDMI_DDC_CTRL,
+			HDMI_DDC_CTRL_SW_STATUS_RESET);
+	hdmi_write(hdmi, REG_HDMI_DDC_CTRL,
+			HDMI_DDC_CTRL_SOFT_RESET);
+
+	hdmi_write(hdmi, REG_HDMI_DDC_SPEED,
+			HDMI_DDC_SPEED_THRESHOLD(2) |
+			HDMI_DDC_SPEED_PRESCALE(10));
+
+	hdmi_write(hdmi, REG_HDMI_DDC_SETUP,
+			HDMI_DDC_SETUP_TIMEOUT(0xff));
+
+	/* enable reference timer for 27us */
+	hdmi_write(hdmi, REG_HDMI_DDC_REF,
+			HDMI_DDC_REF_REFTIMER_ENABLE |
+			HDMI_DDC_REF_REFTIMER(27));
+}
+
+static int ddc_clear_irq(struct hdmi_i2c_adapter *hdmi_i2c)
+{
+	struct hdmi *hdmi = hdmi_i2c->hdmi;
+	struct drm_device *dev = hdmi->dev;
+	uint32_t retry = 0xffff;
+	uint32_t ddc_int_ctrl;
+
+	do {
+		--retry;
+
+		hdmi_write(hdmi, REG_HDMI_DDC_INT_CTRL,
+				HDMI_DDC_INT_CTRL_SW_DONE_ACK |
+				HDMI_DDC_INT_CTRL_SW_DONE_MASK);
+
+		ddc_int_ctrl = hdmi_read(hdmi, REG_HDMI_DDC_INT_CTRL);
+
+	} while ((ddc_int_ctrl & HDMI_DDC_INT_CTRL_SW_DONE_INT) && retry);
+
+	if (!retry) {
+		DRM_DEV_ERROR(dev->dev, "timeout waiting for DDC\n");
+		return -ETIMEDOUT;
+	}
+
+	hdmi_i2c->sw_done = false;
+
+	return 0;
+}
+
+#define MAX_TRANSACTIONS 4
+
+static bool sw_done(struct hdmi_i2c_adapter *hdmi_i2c)
+{
+	struct hdmi *hdmi = hdmi_i2c->hdmi;
+
+	if (!hdmi_i2c->sw_done) {
+		uint32_t ddc_int_ctrl;
+
+		ddc_int_ctrl = hdmi_read(hdmi, REG_HDMI_DDC_INT_CTRL);
+
+		if ((ddc_int_ctrl & HDMI_DDC_INT_CTRL_SW_DONE_MASK) &&
+				(ddc_int_ctrl & HDMI_DDC_INT_CTRL_SW_DONE_INT)) {
+			hdmi_i2c->sw_done = true;
+			hdmi_write(hdmi, REG_HDMI_DDC_INT_CTRL,
+					HDMI_DDC_INT_CTRL_SW_DONE_ACK);
+		}
+	}
+
+	return hdmi_i2c->sw_done;
+}
+
+static int msm_hdmi_i2c_xfer(struct i2c_adapter *i2c,
+		struct i2c_msg *msgs, int num)
+{
+	struct hdmi_i2c_adapter *hdmi_i2c = to_hdmi_i2c_adapter(i2c);
+	struct hdmi *hdmi = hdmi_i2c->hdmi;
+	struct drm_device *dev = hdmi->dev;
+	static const uint32_t nack[] = {
+			HDMI_DDC_SW_STATUS_NACK0, HDMI_DDC_SW_STATUS_NACK1,
+			HDMI_DDC_SW_STATUS_NACK2, HDMI_DDC_SW_STATUS_NACK3,
+	};
+	int indices[MAX_TRANSACTIONS];
+	int ret, i, j, index = 0;
+	uint32_t ddc_status, ddc_data, i2c_trans;
+
+	num = min(num, MAX_TRANSACTIONS);
+
+	WARN_ON(!(hdmi_read(hdmi, REG_HDMI_CTRL) & HDMI_CTRL_ENABLE));
+
+	if (num == 0)
+		return num;
+
+	init_ddc(hdmi_i2c);
+
+	ret = ddc_clear_irq(hdmi_i2c);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < num; i++) {
+		struct i2c_msg *p = &msgs[i];
+		uint32_t raw_addr = p->addr << 1;
+
+		if (p->flags & I2C_M_RD)
+			raw_addr |= 1;
+
+		ddc_data = HDMI_DDC_DATA_DATA(raw_addr) |
+				HDMI_DDC_DATA_DATA_RW(DDC_WRITE);
+
+		if (i == 0) {
+			ddc_data |= HDMI_DDC_DATA_INDEX(0) |
+					HDMI_DDC_DATA_INDEX_WRITE;
+		}
+
+		hdmi_write(hdmi, REG_HDMI_DDC_DATA, ddc_data);
+		index++;
+
+		indices[i] = index;
+
+		if (p->flags & I2C_M_RD) {
+			index += p->len;
+		} else {
+			for (j = 0; j < p->len; j++) {
+				ddc_data = HDMI_DDC_DATA_DATA(p->buf[j]) |
+						HDMI_DDC_DATA_DATA_RW(DDC_WRITE);
+				hdmi_write(hdmi, REG_HDMI_DDC_DATA, ddc_data);
+				index++;
+			}
+		}
+
+		i2c_trans = HDMI_I2C_TRANSACTION_REG_CNT(p->len) |
+				HDMI_I2C_TRANSACTION_REG_RW(
+						(p->flags & I2C_M_RD) ? DDC_READ : DDC_WRITE) |
+				HDMI_I2C_TRANSACTION_REG_START;
+
+		if (i == (num - 1))
+			i2c_trans |= HDMI_I2C_TRANSACTION_REG_STOP;
+
+		hdmi_write(hdmi, REG_HDMI_I2C_TRANSACTION(i), i2c_trans);
+	}
+
+	/* trigger the transfer: */
+	hdmi_write(hdmi, REG_HDMI_DDC_CTRL,
+			HDMI_DDC_CTRL_TRANSACTION_CNT(num - 1) |
+			HDMI_DDC_CTRL_GO);
+
+	ret = wait_event_timeout(hdmi_i2c->ddc_event, sw_done(hdmi_i2c), HZ/4);
+	if (ret <= 0) {
+		if (ret == 0)
+			ret = -ETIMEDOUT;
+		dev_warn(dev->dev, "DDC timeout: %d\n", ret);
+		DBG("sw_status=%08x, hw_status=%08x, int_ctrl=%08x",
+				hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS),
+				hdmi_read(hdmi, REG_HDMI_DDC_HW_STATUS),
+				hdmi_read(hdmi, REG_HDMI_DDC_INT_CTRL));
+		return ret;
+	}
+
+	ddc_status = hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS);
+
+	/* read back results of any read transactions: */
+	for (i = 0; i < num; i++) {
+		struct i2c_msg *p = &msgs[i];
+
+		if (!(p->flags & I2C_M_RD))
+			continue;
+
+		/* check for NACK: */
+		if (ddc_status & nack[i]) {
+			DBG("ddc_status=%08x", ddc_status);
+			break;
+		}
+
+		ddc_data = HDMI_DDC_DATA_DATA_RW(DDC_READ) |
+				HDMI_DDC_DATA_INDEX(indices[i]) |
+				HDMI_DDC_DATA_INDEX_WRITE;
+
+		hdmi_write(hdmi, REG_HDMI_DDC_DATA, ddc_data);
+
+		/* discard first byte: */
+		hdmi_read(hdmi, REG_HDMI_DDC_DATA);
+
+		for (j = 0; j < p->len; j++) {
+			ddc_data = hdmi_read(hdmi, REG_HDMI_DDC_DATA);
+			p->buf[j] = FIELD(ddc_data, HDMI_DDC_DATA_DATA);
+		}
+	}
+
+	return i;
+}
+
+static u32 msm_hdmi_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm msm_hdmi_i2c_algorithm = {
+	.master_xfer	= msm_hdmi_i2c_xfer,
+	.functionality	= msm_hdmi_i2c_func,
+};
+
+void msm_hdmi_i2c_irq(struct i2c_adapter *i2c)
+{
+	struct hdmi_i2c_adapter *hdmi_i2c = to_hdmi_i2c_adapter(i2c);
+
+	if (sw_done(hdmi_i2c))
+		wake_up_all(&hdmi_i2c->ddc_event);
+}
+
+void msm_hdmi_i2c_destroy(struct i2c_adapter *i2c)
+{
+	struct hdmi_i2c_adapter *hdmi_i2c = to_hdmi_i2c_adapter(i2c);
+	i2c_del_adapter(i2c);
+	kfree(hdmi_i2c);
+}
+
+struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi)
+{
+	struct hdmi_i2c_adapter *hdmi_i2c;
+	struct i2c_adapter *i2c = NULL;
+	int ret;
+
+	hdmi_i2c = kzalloc(sizeof(*hdmi_i2c), GFP_KERNEL);
+	if (!hdmi_i2c) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	i2c = &hdmi_i2c->base;
+
+	hdmi_i2c->hdmi = hdmi;
+	init_waitqueue_head(&hdmi_i2c->ddc_event);
+
+
+	i2c->owner = THIS_MODULE;
+	snprintf(i2c->name, sizeof(i2c->name), "msm hdmi i2c");
+	i2c->dev.parent = &hdmi->pdev->dev;
+	i2c->algo = &msm_hdmi_i2c_algorithm;
+
+	ret = i2c_add_adapter(i2c);
+	if (ret)
+		goto fail;
+
+	return i2c;
+
+fail:
+	if (i2c)
+		msm_hdmi_i2c_destroy(i2c);
+	return ERR_PTR(ret);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/hdmi_phy.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/hdmi_phy.c
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "hdmi.h"
+
+static int msm_hdmi_phy_resource_init(struct hdmi_phy *phy)
+{
+	struct hdmi_phy_cfg *cfg = phy->cfg;
+	struct device *dev = &phy->pdev->dev;
+	int i, ret;
+
+	phy->regs = devm_kcalloc(dev, cfg->num_regs, sizeof(phy->regs[0]),
+				 GFP_KERNEL);
+	if (!phy->regs)
+		return -ENOMEM;
+
+	phy->clks = devm_kcalloc(dev, cfg->num_clks, sizeof(phy->clks[0]),
+				 GFP_KERNEL);
+	if (!phy->clks)
+		return -ENOMEM;
+
+	for (i = 0; i < cfg->num_regs; i++)
+		phy->regs[i].supply = cfg->reg_names[i];
+
+	ret = devm_regulator_bulk_get(dev, cfg->num_regs, phy->regs);
+	if (ret) {
+		if (ret != -EPROBE_DEFER)
+			DRM_DEV_ERROR(dev, "failed to get phy regulators: %d\n", ret);
+
+		return ret;
+	}
+
+	for (i = 0; i < cfg->num_clks; i++) {
+		struct clk *clk;
+
+		clk = msm_clk_get(phy->pdev, cfg->clk_names[i]);
+		if (IS_ERR(clk)) {
+			ret = PTR_ERR(clk);
+			DRM_DEV_ERROR(dev, "failed to get phy clock: %s (%d)\n",
+				cfg->clk_names[i], ret);
+			return ret;
+		}
+
+		phy->clks[i] = clk;
+	}
+
+	return 0;
+}
+
+int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy)
+{
+	struct hdmi_phy_cfg *cfg = phy->cfg;
+	struct device *dev = &phy->pdev->dev;
+	int i, ret = 0;
+
+	pm_runtime_get_sync(dev);
+
+	ret = regulator_bulk_enable(cfg->num_regs, phy->regs);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "failed to enable regulators: (%d)\n", ret);
+		return ret;
+	}
+
+	for (i = 0; i < cfg->num_clks; i++) {
+		ret = clk_prepare_enable(phy->clks[i]);
+		if (ret)
+			DRM_DEV_ERROR(dev, "failed to enable clock: %s (%d)\n",
+				cfg->clk_names[i], ret);
+	}
+
+	return ret;
+}
+
+void msm_hdmi_phy_resource_disable(struct hdmi_phy *phy)
+{
+	struct hdmi_phy_cfg *cfg = phy->cfg;
+	struct device *dev = &phy->pdev->dev;
+	int i;
+
+	for (i = cfg->num_clks - 1; i >= 0; i--)
+		clk_disable_unprepare(phy->clks[i]);
+
+	regulator_bulk_disable(cfg->num_regs, phy->regs);
+
+	pm_runtime_put_sync(dev);
+}
+
+void msm_hdmi_phy_powerup(struct hdmi_phy *phy, unsigned long int pixclock)
+{
+	if (!phy || !phy->cfg->powerup)
+		return;
+
+	phy->cfg->powerup(phy, pixclock);
+}
+
+void msm_hdmi_phy_powerdown(struct hdmi_phy *phy)
+{
+	if (!phy || !phy->cfg->powerdown)
+		return;
+
+	phy->cfg->powerdown(phy);
+}
+
+static int msm_hdmi_phy_pll_init(struct platform_device *pdev,
+			     enum hdmi_phy_type type)
+{
+	int ret;
+
+	switch (type) {
+	case MSM_HDMI_PHY_8960:
+		ret = msm_hdmi_pll_8960_init(pdev);
+		break;
+	case MSM_HDMI_PHY_8996:
+		ret = msm_hdmi_pll_8996_init(pdev);
+		break;
+	case MSM_HDMI_PHY_8998:
+		ret = msm_hdmi_pll_8998_init(pdev);
+		break;
+	/*
+	 * we don't have PLL support for these, don't report an error for now
+	 */
+	case MSM_HDMI_PHY_8x60:
+	case MSM_HDMI_PHY_8x74:
+	default:
+		ret = 0;
+		break;
+	}
+
+	return ret;
+}
+
+static int msm_hdmi_phy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct hdmi_phy *phy;
+	int ret;
+
+	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
+	if (!phy)
+		return -ENODEV;
+
+	phy->cfg = (struct hdmi_phy_cfg *)of_device_get_match_data(dev);
+	if (!phy->cfg)
+		return -ENODEV;
+
+	phy->mmio = msm_ioremap(pdev, "hdmi_phy");
+	if (IS_ERR(phy->mmio)) {
+		DRM_DEV_ERROR(dev, "%s: failed to map phy base\n", __func__);
+		return -ENOMEM;
+	}
+
+	phy->pdev = pdev;
+
+	ret = msm_hdmi_phy_resource_init(phy);
+	if (ret)
+		return ret;
+
+	pm_runtime_enable(&pdev->dev);
+
+	ret = msm_hdmi_phy_resource_enable(phy);
+	if (ret)
+		return ret;
+
+	ret = msm_hdmi_phy_pll_init(pdev, phy->cfg->type);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "couldn't init PLL\n");
+		msm_hdmi_phy_resource_disable(phy);
+		return ret;
+	}
+
+	msm_hdmi_phy_resource_disable(phy);
+
+	platform_set_drvdata(pdev, phy);
+
+	return 0;
+}
+
+static void msm_hdmi_phy_remove(struct platform_device *pdev)
+{
+	pm_runtime_disable(&pdev->dev);
+}
+
+static const struct of_device_id msm_hdmi_phy_dt_match[] = {
+	{ .compatible = "qcom,hdmi-phy-8660",
+	  .data = &msm_hdmi_phy_8x60_cfg },
+	{ .compatible = "qcom,hdmi-phy-8960",
+	  .data = &msm_hdmi_phy_8960_cfg },
+	{ .compatible = "qcom,hdmi-phy-8974",
+	  .data = &msm_hdmi_phy_8x74_cfg },
+	{ .compatible = "qcom,hdmi-phy-8084",
+	  .data = &msm_hdmi_phy_8x74_cfg },
+	{ .compatible = "qcom,hdmi-phy-8996",
+	  .data = &msm_hdmi_phy_8996_cfg },
+	{ .compatible = "qcom,hdmi-phy-8998",
+	  .data = &msm_hdmi_phy_8998_cfg },
+	{}
+};
+
+static struct platform_driver msm_hdmi_phy_platform_driver = {
+	.probe      = msm_hdmi_phy_probe,
+	.remove_new = msm_hdmi_phy_remove,
+	.driver     = {
+		.name   = "msm_hdmi_phy",
+		.of_match_table = msm_hdmi_phy_dt_match,
+	},
+};
+
+void __init msm_hdmi_phy_driver_register(void)
+{
+	platform_driver_register(&msm_hdmi_phy_platform_driver);
+}
+
+void __exit msm_hdmi_phy_driver_unregister(void)
+{
+	platform_driver_unregister(&msm_hdmi_phy_platform_driver);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/hdmi_phy_8960.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/hdmi_phy_8960.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include "hdmi.h"
+
+static void hdmi_phy_8960_powerup(struct hdmi_phy *phy,
+				  unsigned long int pixclock)
+{
+	DBG("pixclock: %lu", pixclock);
+
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG2, 0x00);
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG0, 0x1b);
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG1, 0xf2);
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG4, 0x00);
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG5, 0x00);
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG6, 0x00);
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG7, 0x00);
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG8, 0x00);
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG9, 0x00);
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG10, 0x00);
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG11, 0x00);
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG3, 0x20);
+}
+
+static void hdmi_phy_8960_powerdown(struct hdmi_phy *phy)
+{
+	DBG("");
+
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG2, 0x7f);
+}
+
+static const char * const hdmi_phy_8960_reg_names[] = {
+	"core-vdda",
+};
+
+static const char * const hdmi_phy_8960_clk_names[] = {
+	"slave_iface",
+};
+
+const struct hdmi_phy_cfg msm_hdmi_phy_8960_cfg = {
+	.type = MSM_HDMI_PHY_8960,
+	.powerup = hdmi_phy_8960_powerup,
+	.powerdown = hdmi_phy_8960_powerdown,
+	.reg_names = hdmi_phy_8960_reg_names,
+	.num_regs = ARRAY_SIZE(hdmi_phy_8960_reg_names),
+	.clk_names = hdmi_phy_8960_clk_names,
+	.num_clks = ARRAY_SIZE(hdmi_phy_8960_clk_names),
+};
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/hdmi_phy_8996.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/hdmi_phy_8996.c
@@ -0,0 +1,765 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+
+#include "hdmi.h"
+
+#define HDMI_VCO_MAX_FREQ			12000000000UL
+#define HDMI_VCO_MIN_FREQ			8000000000UL
+
+#define HDMI_PCLK_MAX_FREQ			600000000
+#define HDMI_PCLK_MIN_FREQ			25000000
+
+#define HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD	3400000000UL
+#define HDMI_DIG_FREQ_BIT_CLK_THRESHOLD		1500000000UL
+#define HDMI_MID_FREQ_BIT_CLK_THRESHOLD		750000000UL
+#define HDMI_CORECLK_DIV			5
+#define HDMI_DEFAULT_REF_CLOCK			19200000
+#define HDMI_PLL_CMP_CNT			1024
+
+#define HDMI_PLL_POLL_MAX_READS			100
+#define HDMI_PLL_POLL_TIMEOUT_US		150
+
+#define HDMI_NUM_TX_CHANNEL			4
+
+struct hdmi_pll_8996 {
+	struct platform_device *pdev;
+	struct clk_hw clk_hw;
+
+	/* pll mmio base */
+	void __iomem *mmio_qserdes_com;
+	/* tx channel base */
+	void __iomem *mmio_qserdes_tx[HDMI_NUM_TX_CHANNEL];
+};
+
+#define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8996, clk_hw)
+
+struct hdmi_8996_phy_pll_reg_cfg {
+	u32 tx_lx_lane_mode[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_tx_band[HDMI_NUM_TX_CHANNEL];
+	u32 com_svs_mode_clk_sel;
+	u32 com_hsclk_sel;
+	u32 com_pll_cctrl_mode0;
+	u32 com_pll_rctrl_mode0;
+	u32 com_cp_ctrl_mode0;
+	u32 com_dec_start_mode0;
+	u32 com_div_frac_start1_mode0;
+	u32 com_div_frac_start2_mode0;
+	u32 com_div_frac_start3_mode0;
+	u32 com_integloop_gain0_mode0;
+	u32 com_integloop_gain1_mode0;
+	u32 com_lock_cmp_en;
+	u32 com_lock_cmp1_mode0;
+	u32 com_lock_cmp2_mode0;
+	u32 com_lock_cmp3_mode0;
+	u32 com_core_clk_en;
+	u32 com_coreclk_div;
+	u32 com_vco_tune_ctrl;
+
+	u32 tx_lx_tx_drv_lvl[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_tx_emp_post1_lvl[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_vmode_ctrl1[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_vmode_ctrl2[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_res_code_lane_tx[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_hp_pd_enables[HDMI_NUM_TX_CHANNEL];
+
+	u32 phy_mode;
+};
+
+struct hdmi_8996_post_divider {
+	u64 vco_freq;
+	int hsclk_divsel;
+	int vco_ratio;
+	int tx_band_sel;
+	int half_rate_mode;
+};
+
+static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8996 *pll)
+{
+	return platform_get_drvdata(pll->pdev);
+}
+
+static inline void hdmi_pll_write(struct hdmi_pll_8996 *pll, int offset,
+				  u32 data)
+{
+	msm_writel(data, pll->mmio_qserdes_com + offset);
+}
+
+static inline u32 hdmi_pll_read(struct hdmi_pll_8996 *pll, int offset)
+{
+	return msm_readl(pll->mmio_qserdes_com + offset);
+}
+
+static inline void hdmi_tx_chan_write(struct hdmi_pll_8996 *pll, int channel,
+				      int offset, int data)
+{
+	 msm_writel(data, pll->mmio_qserdes_tx[channel] + offset);
+}
+
+static inline u32 pll_get_cpctrl(u64 frac_start, unsigned long ref_clk,
+				 bool gen_ssc)
+{
+	if ((frac_start != 0) || gen_ssc)
+		return (11000000 / (ref_clk / 20));
+
+	return 0x23;
+}
+
+static inline u32 pll_get_rctrl(u64 frac_start, bool gen_ssc)
+{
+	if ((frac_start != 0) || gen_ssc)
+		return 0x16;
+
+	return 0x10;
+}
+
+static inline u32 pll_get_cctrl(u64 frac_start, bool gen_ssc)
+{
+	if ((frac_start != 0) || gen_ssc)
+		return 0x28;
+
+	return 0x1;
+}
+
+static inline u32 pll_get_integloop_gain(u64 frac_start, u64 bclk, u32 ref_clk,
+					 bool gen_ssc)
+{
+	int digclk_divsel = bclk >= HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2;
+	u64 base;
+
+	if ((frac_start != 0) || gen_ssc)
+		base = (64 * ref_clk) / HDMI_DEFAULT_REF_CLOCK;
+	else
+		base = (1022 * ref_clk) / 100;
+
+	base <<= digclk_divsel;
+
+	return (base <= 2046 ? base : 2046);
+}
+
+static inline u32 pll_get_pll_cmp(u64 fdata, unsigned long ref_clk)
+{
+	u64 dividend = HDMI_PLL_CMP_CNT * fdata;
+	u32 divisor = ref_clk * 10;
+	u32 rem;
+
+	rem = do_div(dividend, divisor);
+	if (rem > (divisor >> 1))
+		dividend++;
+
+	return dividend - 1;
+}
+
+static inline u64 pll_cmp_to_fdata(u32 pll_cmp, unsigned long ref_clk)
+{
+	u64 fdata = ((u64)pll_cmp) * ref_clk * 10;
+
+	do_div(fdata, HDMI_PLL_CMP_CNT);
+
+	return fdata;
+}
+
+static int pll_get_post_div(struct hdmi_8996_post_divider *pd, u64 bclk)
+{
+	int ratio[] = { 2, 3, 4, 5, 6, 9, 10, 12, 14, 15, 20, 21, 25, 28, 35 };
+	int hs_divsel[] = { 0, 4, 8, 12, 1, 5, 2, 9, 3, 13, 10, 7, 14, 11, 15 };
+	int tx_band_sel[] = { 0, 1, 2, 3 };
+	u64 vco_freq[60];
+	u64 vco, vco_optimal;
+	int half_rate_mode = 0;
+	int vco_optimal_index, vco_freq_index;
+	int i, j;
+
+retry:
+	vco_optimal = HDMI_VCO_MAX_FREQ;
+	vco_optimal_index = -1;
+	vco_freq_index = 0;
+	for (i = 0; i < 15; i++) {
+		for (j = 0; j < 4; j++) {
+			u32 ratio_mult = ratio[i] << tx_band_sel[j];
+
+			vco = bclk >> half_rate_mode;
+			vco *= ratio_mult;
+			vco_freq[vco_freq_index++] = vco;
+		}
+	}
+
+	for (i = 0; i < 60; i++) {
+		u64 vco_tmp = vco_freq[i];
+
+		if ((vco_tmp >= HDMI_VCO_MIN_FREQ) &&
+		    (vco_tmp <= vco_optimal)) {
+			vco_optimal = vco_tmp;
+			vco_optimal_index = i;
+		}
+	}
+
+	if (vco_optimal_index == -1) {
+		if (!half_rate_mode) {
+			half_rate_mode = 1;
+			goto retry;
+		}
+	} else {
+		pd->vco_freq = vco_optimal;
+		pd->tx_band_sel = tx_band_sel[vco_optimal_index % 4];
+		pd->vco_ratio = ratio[vco_optimal_index / 4];
+		pd->hsclk_divsel = hs_divsel[vco_optimal_index / 4];
+
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int pll_calculate(unsigned long pix_clk, unsigned long ref_clk,
+			 struct hdmi_8996_phy_pll_reg_cfg *cfg)
+{
+	struct hdmi_8996_post_divider pd;
+	u64 bclk;
+	u64 tmds_clk;
+	u64 dec_start;
+	u64 frac_start;
+	u64 fdata;
+	u32 pll_divisor;
+	u32 rem;
+	u32 cpctrl;
+	u32 rctrl;
+	u32 cctrl;
+	u32 integloop_gain;
+	u32 pll_cmp;
+	int i, ret;
+
+	/* bit clk = 10 * pix_clk */
+	bclk = ((u64)pix_clk) * 10;
+
+	if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD)
+		tmds_clk = pix_clk >> 2;
+	else
+		tmds_clk = pix_clk;
+
+	ret = pll_get_post_div(&pd, bclk);
+	if (ret)
+		return ret;
+
+	dec_start = pd.vco_freq;
+	pll_divisor = 4 * ref_clk;
+	do_div(dec_start, pll_divisor);
+
+	frac_start = pd.vco_freq * (1 << 20);
+
+	rem = do_div(frac_start, pll_divisor);
+	frac_start -= dec_start * (1 << 20);
+	if (rem > (pll_divisor >> 1))
+		frac_start++;
+
+	cpctrl = pll_get_cpctrl(frac_start, ref_clk, false);
+	rctrl = pll_get_rctrl(frac_start, false);
+	cctrl = pll_get_cctrl(frac_start, false);
+	integloop_gain = pll_get_integloop_gain(frac_start, bclk,
+						ref_clk, false);
+
+	fdata = pd.vco_freq;
+	do_div(fdata, pd.vco_ratio);
+
+	pll_cmp = pll_get_pll_cmp(fdata, ref_clk);
+
+	DBG("VCO freq: %llu", pd.vco_freq);
+	DBG("fdata: %llu", fdata);
+	DBG("pix_clk: %lu", pix_clk);
+	DBG("tmds clk: %llu", tmds_clk);
+	DBG("HSCLK_SEL: %d", pd.hsclk_divsel);
+	DBG("DEC_START: %llu", dec_start);
+	DBG("DIV_FRAC_START: %llu", frac_start);
+	DBG("PLL_CPCTRL: %u", cpctrl);
+	DBG("PLL_RCTRL: %u", rctrl);
+	DBG("PLL_CCTRL: %u", cctrl);
+	DBG("INTEGLOOP_GAIN: %u", integloop_gain);
+	DBG("TX_BAND: %d", pd.tx_band_sel);
+	DBG("PLL_CMP: %u", pll_cmp);
+
+	/* Convert these values to register specific values */
+	if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD)
+		cfg->com_svs_mode_clk_sel = 1;
+	else
+		cfg->com_svs_mode_clk_sel = 2;
+
+	cfg->com_hsclk_sel = (0x20 | pd.hsclk_divsel);
+	cfg->com_pll_cctrl_mode0 = cctrl;
+	cfg->com_pll_rctrl_mode0 = rctrl;
+	cfg->com_cp_ctrl_mode0 = cpctrl;
+	cfg->com_dec_start_mode0 = dec_start;
+	cfg->com_div_frac_start1_mode0 = (frac_start & 0xff);
+	cfg->com_div_frac_start2_mode0 = ((frac_start & 0xff00) >> 8);
+	cfg->com_div_frac_start3_mode0 = ((frac_start & 0xf0000) >> 16);
+	cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xff);
+	cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xf00) >> 8);
+	cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xff);
+	cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xff00) >> 8);
+	cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16);
+	cfg->com_lock_cmp_en = 0x0;
+	cfg->com_core_clk_en = 0x2c;
+	cfg->com_coreclk_div = HDMI_CORECLK_DIV;
+	cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0;
+	cfg->com_vco_tune_ctrl = 0x0;
+
+	cfg->tx_lx_lane_mode[0] =
+		cfg->tx_lx_lane_mode[2] = 0x43;
+
+	cfg->tx_lx_hp_pd_enables[0] =
+		cfg->tx_lx_hp_pd_enables[1] =
+		cfg->tx_lx_hp_pd_enables[2] = 0x0c;
+	cfg->tx_lx_hp_pd_enables[3] = 0x3;
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++)
+		cfg->tx_lx_tx_band[i] = pd.tx_band_sel + 4;
+
+	if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) {
+		cfg->tx_lx_tx_drv_lvl[0] =
+			cfg->tx_lx_tx_drv_lvl[1] =
+			cfg->tx_lx_tx_drv_lvl[2] = 0x25;
+		cfg->tx_lx_tx_drv_lvl[3] = 0x22;
+
+		cfg->tx_lx_tx_emp_post1_lvl[0] =
+			cfg->tx_lx_tx_emp_post1_lvl[1] =
+			cfg->tx_lx_tx_emp_post1_lvl[2] = 0x23;
+		cfg->tx_lx_tx_emp_post1_lvl[3] = 0x27;
+
+		cfg->tx_lx_vmode_ctrl1[0] =
+			cfg->tx_lx_vmode_ctrl1[1] =
+			cfg->tx_lx_vmode_ctrl1[2] =
+			cfg->tx_lx_vmode_ctrl1[3] = 0x00;
+
+		cfg->tx_lx_vmode_ctrl2[0] =
+			cfg->tx_lx_vmode_ctrl2[1] =
+			cfg->tx_lx_vmode_ctrl2[2] = 0x0D;
+
+		cfg->tx_lx_vmode_ctrl2[3] = 0x00;
+	} else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) {
+		for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+			cfg->tx_lx_tx_drv_lvl[i] = 0x25;
+			cfg->tx_lx_tx_emp_post1_lvl[i] = 0x23;
+			cfg->tx_lx_vmode_ctrl1[i] = 0x00;
+		}
+
+		cfg->tx_lx_vmode_ctrl2[0] =
+			cfg->tx_lx_vmode_ctrl2[1] =
+			cfg->tx_lx_vmode_ctrl2[2] = 0x0D;
+		cfg->tx_lx_vmode_ctrl2[3] = 0x00;
+	} else {
+		for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+			cfg->tx_lx_tx_drv_lvl[i] = 0x20;
+			cfg->tx_lx_tx_emp_post1_lvl[i] = 0x20;
+			cfg->tx_lx_vmode_ctrl1[i] = 0x00;
+			cfg->tx_lx_vmode_ctrl2[i] = 0x0E;
+		}
+	}
+
+	DBG("com_svs_mode_clk_sel = 0x%x", cfg->com_svs_mode_clk_sel);
+	DBG("com_hsclk_sel = 0x%x", cfg->com_hsclk_sel);
+	DBG("com_lock_cmp_en = 0x%x", cfg->com_lock_cmp_en);
+	DBG("com_pll_cctrl_mode0 = 0x%x", cfg->com_pll_cctrl_mode0);
+	DBG("com_pll_rctrl_mode0 = 0x%x", cfg->com_pll_rctrl_mode0);
+	DBG("com_cp_ctrl_mode0 = 0x%x", cfg->com_cp_ctrl_mode0);
+	DBG("com_dec_start_mode0 = 0x%x", cfg->com_dec_start_mode0);
+	DBG("com_div_frac_start1_mode0 = 0x%x", cfg->com_div_frac_start1_mode0);
+	DBG("com_div_frac_start2_mode0 = 0x%x", cfg->com_div_frac_start2_mode0);
+	DBG("com_div_frac_start3_mode0 = 0x%x", cfg->com_div_frac_start3_mode0);
+	DBG("com_integloop_gain0_mode0 = 0x%x", cfg->com_integloop_gain0_mode0);
+	DBG("com_integloop_gain1_mode0 = 0x%x", cfg->com_integloop_gain1_mode0);
+	DBG("com_lock_cmp1_mode0 = 0x%x", cfg->com_lock_cmp1_mode0);
+	DBG("com_lock_cmp2_mode0 = 0x%x", cfg->com_lock_cmp2_mode0);
+	DBG("com_lock_cmp3_mode0 = 0x%x", cfg->com_lock_cmp3_mode0);
+	DBG("com_core_clk_en = 0x%x", cfg->com_core_clk_en);
+	DBG("com_coreclk_div = 0x%x", cfg->com_coreclk_div);
+	DBG("phy_mode = 0x%x", cfg->phy_mode);
+
+	DBG("tx_l0_lane_mode = 0x%x", cfg->tx_lx_lane_mode[0]);
+	DBG("tx_l2_lane_mode = 0x%x", cfg->tx_lx_lane_mode[2]);
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+		DBG("tx_l%d_tx_band = 0x%x", i, cfg->tx_lx_tx_band[i]);
+		DBG("tx_l%d_tx_drv_lvl = 0x%x", i, cfg->tx_lx_tx_drv_lvl[i]);
+		DBG("tx_l%d_tx_emp_post1_lvl = 0x%x", i,
+		    cfg->tx_lx_tx_emp_post1_lvl[i]);
+		DBG("tx_l%d_vmode_ctrl1 = 0x%x", i, cfg->tx_lx_vmode_ctrl1[i]);
+		DBG("tx_l%d_vmode_ctrl2 = 0x%x", i, cfg->tx_lx_vmode_ctrl2[i]);
+	}
+
+	return 0;
+}
+
+static int hdmi_8996_pll_set_clk_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long parent_rate)
+{
+	struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw);
+	struct hdmi_phy *phy = pll_get_phy(pll);
+	struct hdmi_8996_phy_pll_reg_cfg cfg;
+	int i, ret;
+
+	memset(&cfg, 0x00, sizeof(cfg));
+
+	ret = pll_calculate(rate, parent_rate, &cfg);
+	if (ret) {
+		DRM_ERROR("PLL calculation failed\n");
+		return ret;
+	}
+
+	/* Initially shut down PHY */
+	DBG("Disabling PHY");
+	hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x0);
+	udelay(500);
+
+	/* Power up sequence */
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_CTRL, 0x04);
+
+	hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x1);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_RESETSM_CNTRL, 0x20);
+	hdmi_phy_write(phy, REG_HDMI_8996_PHY_TX0_TX1_LANE_CTL, 0x0F);
+	hdmi_phy_write(phy, REG_HDMI_8996_PHY_TX2_TX3_LANE_CTL, 0x0F);
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_PHY_QSERDES_TX_LX_CLKBUF_ENABLE,
+				   0x03);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_PHY_QSERDES_TX_LX_TX_BAND,
+				   cfg.tx_lx_tx_band[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_PHY_QSERDES_TX_LX_RESET_TSYNC_EN,
+				   0x03);
+	}
+
+	hdmi_tx_chan_write(pll, 0, REG_HDMI_PHY_QSERDES_TX_LX_LANE_MODE,
+			   cfg.tx_lx_lane_mode[0]);
+	hdmi_tx_chan_write(pll, 2, REG_HDMI_PHY_QSERDES_TX_LX_LANE_MODE,
+			   cfg.tx_lx_lane_mode[2]);
+
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1E);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x07);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYSCLK_EN_SEL, 0x37);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYS_CLK_CTRL, 0x02);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CLK_ENABLE1, 0x0E);
+
+	/* Bypass VCO calibration */
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SVS_MODE_CLK_SEL,
+		       cfg.com_svs_mode_clk_sel);
+
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_TRIM, 0x0F);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_IVCO, 0x0F);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_CTRL,
+		       cfg.com_vco_tune_ctrl);
+
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_CTRL, 0x06);
+
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CLK_SELECT, 0x30);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_HSCLK_SEL,
+		       cfg.com_hsclk_sel);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP_EN,
+		       cfg.com_lock_cmp_en);
+
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_CCTRL_MODE0,
+		       cfg.com_pll_cctrl_mode0);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_RCTRL_MODE0,
+		       cfg.com_pll_rctrl_mode0);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CP_CTRL_MODE0,
+		       cfg.com_cp_ctrl_mode0);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DEC_START_MODE0,
+		       cfg.com_dec_start_mode0);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START1_MODE0,
+		       cfg.com_div_frac_start1_mode0);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START2_MODE0,
+		       cfg.com_div_frac_start2_mode0);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START3_MODE0,
+		       cfg.com_div_frac_start3_mode0);
+
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN0_MODE0,
+		       cfg.com_integloop_gain0_mode0);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN1_MODE0,
+		       cfg.com_integloop_gain1_mode0);
+
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE0,
+		       cfg.com_lock_cmp1_mode0);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE0,
+		       cfg.com_lock_cmp2_mode0);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE0,
+		       cfg.com_lock_cmp3_mode0);
+
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_MAP, 0x00);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CORE_CLK_EN,
+		       cfg.com_core_clk_en);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CORECLK_DIV,
+		       cfg.com_coreclk_div);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CMN_CONFIG, 0x02);
+
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_RESCODE_DIV_NUM, 0x15);
+
+	/* TX lanes setup (TX 0/1/2/3) */
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_PHY_QSERDES_TX_LX_TX_DRV_LVL,
+				   cfg.tx_lx_tx_drv_lvl[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_PHY_QSERDES_TX_LX_TX_EMP_POST1_LVL,
+				   cfg.tx_lx_tx_emp_post1_lvl[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_PHY_QSERDES_TX_LX_VMODE_CTRL1,
+				   cfg.tx_lx_vmode_ctrl1[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_PHY_QSERDES_TX_LX_VMODE_CTRL2,
+				   cfg.tx_lx_vmode_ctrl2[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_PHY_QSERDES_TX_LX_TX_DRV_LVL_OFFSET,
+				   0x00);
+		hdmi_tx_chan_write(pll, i,
+			REG_HDMI_PHY_QSERDES_TX_LX_RES_CODE_LANE_OFFSET,
+			0x00);
+		hdmi_tx_chan_write(pll, i,
+			REG_HDMI_PHY_QSERDES_TX_LX_TRAN_DRVR_EMP_EN,
+			0x03);
+		hdmi_tx_chan_write(pll, i,
+			REG_HDMI_PHY_QSERDES_TX_LX_PARRATE_REC_DETECT_IDLE_EN,
+			0x40);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_PHY_QSERDES_TX_LX_HP_PD_ENABLES,
+				   cfg.tx_lx_hp_pd_enables[i]);
+	}
+
+	hdmi_phy_write(phy, REG_HDMI_8996_PHY_MODE, cfg.phy_mode);
+	hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x1F);
+
+	/*
+	 * Ensure that vco configuration gets flushed to hardware before
+	 * enabling the PLL
+	 */
+	wmb();
+
+	return 0;
+}
+
+static int hdmi_8996_phy_ready_status(struct hdmi_phy *phy)
+{
+	u32 nb_tries = HDMI_PLL_POLL_MAX_READS;
+	unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US;
+	u32 status;
+	int phy_ready = 0;
+
+	DBG("Waiting for PHY ready");
+
+	while (nb_tries--) {
+		status = hdmi_phy_read(phy, REG_HDMI_8996_PHY_STATUS);
+		phy_ready = status & BIT(0);
+
+		if (phy_ready)
+			break;
+
+		udelay(timeout);
+	}
+
+	DBG("PHY is %sready", phy_ready ? "" : "*not* ");
+
+	return phy_ready;
+}
+
+static int hdmi_8996_pll_lock_status(struct hdmi_pll_8996 *pll)
+{
+	u32 status;
+	int nb_tries = HDMI_PLL_POLL_MAX_READS;
+	unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US;
+	int pll_locked = 0;
+
+	DBG("Waiting for PLL lock");
+
+	while (nb_tries--) {
+		status = hdmi_pll_read(pll,
+				       REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS);
+		pll_locked = status & BIT(0);
+
+		if (pll_locked)
+			break;
+
+		udelay(timeout);
+	}
+
+	DBG("HDMI PLL is %slocked", pll_locked ? "" : "*not* ");
+
+	return pll_locked;
+}
+
+static int hdmi_8996_pll_prepare(struct clk_hw *hw)
+{
+	struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw);
+	struct hdmi_phy *phy = pll_get_phy(pll);
+	int i, ret = 0;
+
+	hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x1);
+	udelay(100);
+
+	hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x19);
+	udelay(100);
+
+	ret = hdmi_8996_pll_lock_status(pll);
+	if (!ret)
+		return ret;
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++)
+		hdmi_tx_chan_write(pll, i,
+			REG_HDMI_PHY_QSERDES_TX_LX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN,
+			0x6F);
+
+	/* Disable SSC */
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_PER1, 0x0);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_PER2, 0x0);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_STEP_SIZE1, 0x0);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_STEP_SIZE2, 0x0);
+	hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_EN_CENTER, 0x2);
+
+	ret = hdmi_8996_phy_ready_status(phy);
+	if (!ret)
+		return ret;
+
+	/* Restart the retiming buffer */
+	hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x18);
+	udelay(1);
+	hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x19);
+
+	return 0;
+}
+
+static long hdmi_8996_pll_round_rate(struct clk_hw *hw,
+				     unsigned long rate,
+				     unsigned long *parent_rate)
+{
+	if (rate < HDMI_PCLK_MIN_FREQ)
+		return HDMI_PCLK_MIN_FREQ;
+	else if (rate > HDMI_PCLK_MAX_FREQ)
+		return HDMI_PCLK_MAX_FREQ;
+	else
+		return rate;
+}
+
+static unsigned long hdmi_8996_pll_recalc_rate(struct clk_hw *hw,
+					       unsigned long parent_rate)
+{
+	struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw);
+	u64 fdata;
+	u32 cmp1, cmp2, cmp3, pll_cmp;
+
+	cmp1 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE0);
+	cmp2 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE0);
+	cmp3 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE0);
+
+	pll_cmp = cmp1 | (cmp2 << 8) | (cmp3 << 16);
+
+	fdata = pll_cmp_to_fdata(pll_cmp + 1, parent_rate);
+
+	do_div(fdata, 10);
+
+	return fdata;
+}
+
+static void hdmi_8996_pll_unprepare(struct clk_hw *hw)
+{
+	struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw);
+	struct hdmi_phy *phy = pll_get_phy(pll);
+
+	hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x6);
+	usleep_range(100, 150);
+}
+
+static int hdmi_8996_pll_is_enabled(struct clk_hw *hw)
+{
+	struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw);
+	u32 status;
+	int pll_locked;
+
+	status = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS);
+	pll_locked = status & BIT(0);
+
+	return pll_locked;
+}
+
+static const struct clk_ops hdmi_8996_pll_ops = {
+	.set_rate = hdmi_8996_pll_set_clk_rate,
+	.round_rate = hdmi_8996_pll_round_rate,
+	.recalc_rate = hdmi_8996_pll_recalc_rate,
+	.prepare = hdmi_8996_pll_prepare,
+	.unprepare = hdmi_8996_pll_unprepare,
+	.is_enabled = hdmi_8996_pll_is_enabled,
+};
+
+static const struct clk_init_data pll_init = {
+	.name = "hdmipll",
+	.ops = &hdmi_8996_pll_ops,
+	.parent_data = (const struct clk_parent_data[]){
+		{ .fw_name = "xo", .name = "xo_board" },
+	},
+	.num_parents = 1,
+	.flags = CLK_IGNORE_UNUSED,
+};
+
+int msm_hdmi_pll_8996_init(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct hdmi_pll_8996 *pll;
+	int i, ret;
+
+	pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return -ENOMEM;
+
+	pll->pdev = pdev;
+
+	pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll");
+	if (IS_ERR(pll->mmio_qserdes_com)) {
+		DRM_DEV_ERROR(dev, "failed to map pll base\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+		char name[32];
+
+		snprintf(name, sizeof(name), "hdmi_tx_l%d", i);
+
+		pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name);
+		if (IS_ERR(pll->mmio_qserdes_tx[i])) {
+			DRM_DEV_ERROR(dev, "failed to map pll base\n");
+			return -ENOMEM;
+		}
+	}
+	pll->clk_hw.init = &pll_init;
+
+	ret = devm_clk_hw_register(dev, &pll->clk_hw);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "failed to register pll clock\n");
+		return ret;
+	}
+
+	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &pll->clk_hw);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "%s: failed to register clk provider: %d\n", __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const char * const hdmi_phy_8996_reg_names[] = {
+	"vddio",
+	"vcca",
+};
+
+static const char * const hdmi_phy_8996_clk_names[] = {
+	"iface", "ref",
+};
+
+const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg = {
+	.type = MSM_HDMI_PHY_8996,
+	.reg_names = hdmi_phy_8996_reg_names,
+	.num_regs = ARRAY_SIZE(hdmi_phy_8996_reg_names),
+	.clk_names = hdmi_phy_8996_clk_names,
+	.num_clks = ARRAY_SIZE(hdmi_phy_8996_clk_names),
+};
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/hdmi_phy_8998.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/hdmi_phy_8998.c
@@ -0,0 +1,779 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Freebox SAS
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+
+#include "hdmi.h"
+
+#define HDMI_VCO_MAX_FREQ			12000000000UL
+#define HDMI_VCO_MIN_FREQ			8000000000UL
+
+#define HDMI_PCLK_MAX_FREQ			600000000
+#define HDMI_PCLK_MIN_FREQ			25000000
+
+#define HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD	3400000000UL
+#define HDMI_DIG_FREQ_BIT_CLK_THRESHOLD		1500000000UL
+#define HDMI_MID_FREQ_BIT_CLK_THRESHOLD		750000000UL
+#define HDMI_CORECLK_DIV			5
+#define HDMI_DEFAULT_REF_CLOCK			19200000
+#define HDMI_PLL_CMP_CNT			1024
+
+#define HDMI_PLL_POLL_MAX_READS			100
+#define HDMI_PLL_POLL_TIMEOUT_US		150
+
+#define HDMI_NUM_TX_CHANNEL			4
+
+struct hdmi_pll_8998 {
+	struct platform_device *pdev;
+	struct clk_hw clk_hw;
+	unsigned long rate;
+
+	/* pll mmio base */
+	void __iomem *mmio_qserdes_com;
+	/* tx channel base */
+	void __iomem *mmio_qserdes_tx[HDMI_NUM_TX_CHANNEL];
+};
+
+#define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8998, clk_hw)
+
+struct hdmi_8998_phy_pll_reg_cfg {
+	u32 com_svs_mode_clk_sel;
+	u32 com_hsclk_sel;
+	u32 com_pll_cctrl_mode0;
+	u32 com_pll_rctrl_mode0;
+	u32 com_cp_ctrl_mode0;
+	u32 com_dec_start_mode0;
+	u32 com_div_frac_start1_mode0;
+	u32 com_div_frac_start2_mode0;
+	u32 com_div_frac_start3_mode0;
+	u32 com_integloop_gain0_mode0;
+	u32 com_integloop_gain1_mode0;
+	u32 com_lock_cmp_en;
+	u32 com_lock_cmp1_mode0;
+	u32 com_lock_cmp2_mode0;
+	u32 com_lock_cmp3_mode0;
+	u32 com_core_clk_en;
+	u32 com_coreclk_div_mode0;
+
+	u32 tx_lx_tx_band[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_tx_drv_lvl[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_tx_emp_post1_lvl[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_pre_driver_1[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_pre_driver_2[HDMI_NUM_TX_CHANNEL];
+	u32 tx_lx_res_code_offset[HDMI_NUM_TX_CHANNEL];
+
+	u32 phy_mode;
+};
+
+struct hdmi_8998_post_divider {
+	u64 vco_freq;
+	int hsclk_divsel;
+	int vco_ratio;
+	int tx_band_sel;
+	int half_rate_mode;
+};
+
+static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8998 *pll)
+{
+	return platform_get_drvdata(pll->pdev);
+}
+
+static inline void hdmi_pll_write(struct hdmi_pll_8998 *pll, int offset,
+				  u32 data)
+{
+	writel(data, pll->mmio_qserdes_com + offset);
+}
+
+static inline u32 hdmi_pll_read(struct hdmi_pll_8998 *pll, int offset)
+{
+	return readl(pll->mmio_qserdes_com + offset);
+}
+
+static inline void hdmi_tx_chan_write(struct hdmi_pll_8998 *pll, int channel,
+				      int offset, int data)
+{
+	 writel(data, pll->mmio_qserdes_tx[channel] + offset);
+}
+
+static inline u32 pll_get_cpctrl(u64 frac_start, unsigned long ref_clk,
+				 bool gen_ssc)
+{
+	if ((frac_start != 0) || gen_ssc)
+		return 0x8;
+
+	return 0x30;
+}
+
+static inline u32 pll_get_rctrl(u64 frac_start, bool gen_ssc)
+{
+	if ((frac_start != 0) || gen_ssc)
+		return 0x16;
+
+	return 0x18;
+}
+
+static inline u32 pll_get_cctrl(u64 frac_start, bool gen_ssc)
+{
+	if ((frac_start != 0) || gen_ssc)
+		return 0x34;
+
+	return 0x2;
+}
+
+static inline u32 pll_get_integloop_gain(u64 frac_start, u64 bclk, u32 ref_clk,
+					 bool gen_ssc)
+{
+	int digclk_divsel = bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2;
+	u64 base;
+
+	if ((frac_start != 0) || gen_ssc)
+		base = 0x3F;
+	else
+		base = 0xC4;
+
+	base <<= (digclk_divsel == 2 ? 1 : 0);
+
+	return (base <= 2046 ? base : 2046);
+}
+
+static inline u32 pll_get_pll_cmp(u64 fdata, unsigned long ref_clk)
+{
+	u64 dividend = HDMI_PLL_CMP_CNT * fdata;
+	u32 divisor = ref_clk * 10;
+	u32 rem;
+
+	rem = do_div(dividend, divisor);
+	if (rem > (divisor >> 1))
+		dividend++;
+
+	return dividend - 1;
+}
+
+static inline u64 pll_cmp_to_fdata(u32 pll_cmp, unsigned long ref_clk)
+{
+	u64 fdata = ((u64)pll_cmp) * ref_clk * 10;
+
+	do_div(fdata, HDMI_PLL_CMP_CNT);
+
+	return fdata;
+}
+
+#define HDMI_REF_CLOCK_HZ ((u64)19200000)
+#define HDMI_MHZ_TO_HZ ((u64)1000000)
+static int pll_get_post_div(struct hdmi_8998_post_divider *pd, u64 bclk)
+{
+	u32 const ratio_list[] = {1, 2, 3, 4, 5, 6,
+				     9, 10, 12, 15, 25};
+	u32 const band_list[] = {0, 1, 2, 3};
+	u32 const sz_ratio = ARRAY_SIZE(ratio_list);
+	u32 const sz_band = ARRAY_SIZE(band_list);
+	u32 const cmp_cnt = 1024;
+	u32 const th_min = 500, th_max = 1000;
+	u32 half_rate_mode = 0;
+	u32 list_elements;
+	int optimal_index;
+	u32 i, j, k;
+	u32 found_hsclk_divsel = 0, found_vco_ratio;
+	u32 found_tx_band_sel;
+	u64 const min_freq = HDMI_VCO_MIN_FREQ, max_freq = HDMI_VCO_MAX_FREQ;
+	u64 freq_list[ARRAY_SIZE(ratio_list) * ARRAY_SIZE(band_list)];
+	u64 found_vco_freq;
+	u64 freq_optimal;
+
+find_optimal_index:
+	freq_optimal = max_freq;
+	optimal_index = -1;
+	list_elements = 0;
+
+	for (i = 0; i < sz_ratio; i++) {
+		for (j = 0; j < sz_band; j++) {
+			u64 freq = div_u64(bclk, (1 << half_rate_mode));
+
+			freq *= (ratio_list[i] * (1 << band_list[j]));
+			freq_list[list_elements++] = freq;
+		}
+	}
+
+	for (k = 0; k < ARRAY_SIZE(freq_list); k++) {
+		u32 const clks_pll_div = 2, core_clk_div = 5;
+		u32 const rng1 = 16, rng2 = 8;
+		u32 th1, th2;
+		u64 core_clk, rvar1, rem;
+
+		core_clk = div_u64(freq_list[k],
+				   ratio_list[k / sz_band] * clks_pll_div *
+				   core_clk_div);
+
+		rvar1 = HDMI_REF_CLOCK_HZ * rng1 * HDMI_MHZ_TO_HZ;
+		rvar1 = div64_u64_rem(rvar1, (cmp_cnt * core_clk), &rem);
+		if (rem > ((cmp_cnt * core_clk) >> 1))
+			rvar1++;
+		th1 = rvar1;
+
+		rvar1 = HDMI_REF_CLOCK_HZ * rng2 * HDMI_MHZ_TO_HZ;
+		rvar1 = div64_u64_rem(rvar1, (cmp_cnt * core_clk), &rem);
+		if (rem > ((cmp_cnt * core_clk) >> 1))
+			rvar1++;
+		th2 = rvar1;
+
+		if (freq_list[k] >= min_freq &&
+				freq_list[k] <= max_freq) {
+			if ((th1 >= th_min && th1 <= th_max) ||
+					(th2 >= th_min && th2 <= th_max)) {
+				if (freq_list[k] <= freq_optimal) {
+					freq_optimal = freq_list[k];
+					optimal_index = k;
+				}
+			}
+		}
+	}
+
+	if (optimal_index == -1) {
+		if (!half_rate_mode) {
+			half_rate_mode = 1;
+			goto find_optimal_index;
+		} else {
+			return -EINVAL;
+		}
+	} else {
+		found_vco_ratio = ratio_list[optimal_index / sz_band];
+		found_tx_band_sel = band_list[optimal_index % sz_band];
+		found_vco_freq = freq_optimal;
+	}
+
+	switch (found_vco_ratio) {
+	case 1:
+		found_hsclk_divsel = 15;
+		break;
+	case 2:
+		found_hsclk_divsel = 0;
+		break;
+	case 3:
+		found_hsclk_divsel = 4;
+		break;
+	case 4:
+		found_hsclk_divsel = 8;
+		break;
+	case 5:
+		found_hsclk_divsel = 12;
+		break;
+	case 6:
+		found_hsclk_divsel = 1;
+		break;
+	case 9:
+		found_hsclk_divsel = 5;
+		break;
+	case 10:
+		found_hsclk_divsel = 2;
+		break;
+	case 12:
+		found_hsclk_divsel = 9;
+		break;
+	case 15:
+		found_hsclk_divsel = 13;
+		break;
+	case 25:
+		found_hsclk_divsel = 14;
+		break;
+	};
+
+	pd->vco_freq = found_vco_freq;
+	pd->tx_band_sel = found_tx_band_sel;
+	pd->vco_ratio = found_vco_ratio;
+	pd->hsclk_divsel = found_hsclk_divsel;
+
+	return 0;
+}
+
+static int pll_calculate(unsigned long pix_clk, unsigned long ref_clk,
+			 struct hdmi_8998_phy_pll_reg_cfg *cfg)
+{
+	struct hdmi_8998_post_divider pd;
+	u64 bclk;
+	u64 dec_start;
+	u64 frac_start;
+	u64 fdata;
+	u32 pll_divisor;
+	u32 rem;
+	u32 cpctrl;
+	u32 rctrl;
+	u32 cctrl;
+	u32 integloop_gain;
+	u32 pll_cmp;
+	int i, ret;
+
+	/* bit clk = 10 * pix_clk */
+	bclk = ((u64)pix_clk) * 10;
+
+	ret = pll_get_post_div(&pd, bclk);
+	if (ret)
+		return ret;
+
+	dec_start = pd.vco_freq;
+	pll_divisor = 4 * ref_clk;
+	do_div(dec_start, pll_divisor);
+
+	frac_start = pd.vco_freq * (1 << 20);
+
+	rem = do_div(frac_start, pll_divisor);
+	frac_start -= dec_start * (1 << 20);
+	if (rem > (pll_divisor >> 1))
+		frac_start++;
+
+	cpctrl = pll_get_cpctrl(frac_start, ref_clk, false);
+	rctrl = pll_get_rctrl(frac_start, false);
+	cctrl = pll_get_cctrl(frac_start, false);
+	integloop_gain = pll_get_integloop_gain(frac_start, bclk,
+						ref_clk, false);
+
+	fdata = pd.vco_freq;
+	do_div(fdata, pd.vco_ratio);
+
+	pll_cmp = pll_get_pll_cmp(fdata, ref_clk);
+
+	/* Convert these values to register specific values */
+	if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD)
+		cfg->com_svs_mode_clk_sel = 1;
+	else
+		cfg->com_svs_mode_clk_sel = 2;
+
+	cfg->com_hsclk_sel = (0x20 | pd.hsclk_divsel);
+	cfg->com_pll_cctrl_mode0 = cctrl;
+	cfg->com_pll_rctrl_mode0 = rctrl;
+	cfg->com_cp_ctrl_mode0 = cpctrl;
+	cfg->com_dec_start_mode0 = dec_start;
+	cfg->com_div_frac_start1_mode0 = (frac_start & 0xff);
+	cfg->com_div_frac_start2_mode0 = ((frac_start & 0xff00) >> 8);
+	cfg->com_div_frac_start3_mode0 = ((frac_start & 0xf0000) >> 16);
+	cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xff);
+	cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xf00) >> 8);
+	cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xff);
+	cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xff00) >> 8);
+	cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16);
+	cfg->com_lock_cmp_en = 0x0;
+	cfg->com_core_clk_en = 0x2c;
+	cfg->com_coreclk_div_mode0 = HDMI_CORECLK_DIV;
+	cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x5 : 0x4;
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++)
+		cfg->tx_lx_tx_band[i] = pd.tx_band_sel;
+
+	if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) {
+		cfg->tx_lx_tx_drv_lvl[0] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[1] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[2] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[3] = 0x0f;
+		cfg->tx_lx_tx_emp_post1_lvl[0] = 0x03;
+		cfg->tx_lx_tx_emp_post1_lvl[1] = 0x02;
+		cfg->tx_lx_tx_emp_post1_lvl[2] = 0x03;
+		cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00;
+		cfg->tx_lx_pre_driver_1[0] = 0x00;
+		cfg->tx_lx_pre_driver_1[1] = 0x00;
+		cfg->tx_lx_pre_driver_1[2] = 0x00;
+		cfg->tx_lx_pre_driver_1[3] = 0x00;
+		cfg->tx_lx_pre_driver_2[0] = 0x1C;
+		cfg->tx_lx_pre_driver_2[1] = 0x1C;
+		cfg->tx_lx_pre_driver_2[2] = 0x1C;
+		cfg->tx_lx_pre_driver_2[3] = 0x00;
+		cfg->tx_lx_res_code_offset[0] = 0x03;
+		cfg->tx_lx_res_code_offset[1] = 0x00;
+		cfg->tx_lx_res_code_offset[2] = 0x00;
+		cfg->tx_lx_res_code_offset[3] = 0x03;
+	} else if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD) {
+		cfg->tx_lx_tx_drv_lvl[0] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[1] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[2] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[3] = 0x0f;
+		cfg->tx_lx_tx_emp_post1_lvl[0] = 0x03;
+		cfg->tx_lx_tx_emp_post1_lvl[1] = 0x03;
+		cfg->tx_lx_tx_emp_post1_lvl[2] = 0x03;
+		cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00;
+		cfg->tx_lx_pre_driver_1[0] = 0x00;
+		cfg->tx_lx_pre_driver_1[1] = 0x00;
+		cfg->tx_lx_pre_driver_1[2] = 0x00;
+		cfg->tx_lx_pre_driver_1[3] = 0x00;
+		cfg->tx_lx_pre_driver_2[0] = 0x16;
+		cfg->tx_lx_pre_driver_2[1] = 0x16;
+		cfg->tx_lx_pre_driver_2[2] = 0x16;
+		cfg->tx_lx_pre_driver_2[3] = 0x18;
+		cfg->tx_lx_res_code_offset[0] = 0x03;
+		cfg->tx_lx_res_code_offset[1] = 0x00;
+		cfg->tx_lx_res_code_offset[2] = 0x00;
+		cfg->tx_lx_res_code_offset[3] = 0x00;
+	} else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) {
+		cfg->tx_lx_tx_drv_lvl[0] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[1] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[2] = 0x0f;
+		cfg->tx_lx_tx_drv_lvl[3] = 0x0f;
+		cfg->tx_lx_tx_emp_post1_lvl[0] = 0x05;
+		cfg->tx_lx_tx_emp_post1_lvl[1] = 0x05;
+		cfg->tx_lx_tx_emp_post1_lvl[2] = 0x05;
+		cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00;
+		cfg->tx_lx_pre_driver_1[0] = 0x00;
+		cfg->tx_lx_pre_driver_1[1] = 0x00;
+		cfg->tx_lx_pre_driver_1[2] = 0x00;
+		cfg->tx_lx_pre_driver_1[3] = 0x00;
+		cfg->tx_lx_pre_driver_2[0] = 0x0E;
+		cfg->tx_lx_pre_driver_2[1] = 0x0E;
+		cfg->tx_lx_pre_driver_2[2] = 0x0E;
+		cfg->tx_lx_pre_driver_2[3] = 0x0E;
+		cfg->tx_lx_res_code_offset[0] = 0x00;
+		cfg->tx_lx_res_code_offset[1] = 0x00;
+		cfg->tx_lx_res_code_offset[2] = 0x00;
+		cfg->tx_lx_res_code_offset[3] = 0x00;
+	} else {
+		cfg->tx_lx_tx_drv_lvl[0] = 0x01;
+		cfg->tx_lx_tx_drv_lvl[1] = 0x01;
+		cfg->tx_lx_tx_drv_lvl[2] = 0x01;
+		cfg->tx_lx_tx_drv_lvl[3] = 0x00;
+		cfg->tx_lx_tx_emp_post1_lvl[0] = 0x00;
+		cfg->tx_lx_tx_emp_post1_lvl[1] = 0x00;
+		cfg->tx_lx_tx_emp_post1_lvl[2] = 0x00;
+		cfg->tx_lx_tx_emp_post1_lvl[3] = 0x00;
+		cfg->tx_lx_pre_driver_1[0] = 0x00;
+		cfg->tx_lx_pre_driver_1[1] = 0x00;
+		cfg->tx_lx_pre_driver_1[2] = 0x00;
+		cfg->tx_lx_pre_driver_1[3] = 0x00;
+		cfg->tx_lx_pre_driver_2[0] = 0x16;
+		cfg->tx_lx_pre_driver_2[1] = 0x16;
+		cfg->tx_lx_pre_driver_2[2] = 0x16;
+		cfg->tx_lx_pre_driver_2[3] = 0x18;
+		cfg->tx_lx_res_code_offset[0] = 0x00;
+		cfg->tx_lx_res_code_offset[1] = 0x00;
+		cfg->tx_lx_res_code_offset[2] = 0x00;
+		cfg->tx_lx_res_code_offset[3] = 0x00;
+	}
+
+	return 0;
+}
+
+static int hdmi_8998_pll_set_clk_rate(struct clk_hw *hw, unsigned long rate,
+				      unsigned long parent_rate)
+{
+	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
+	struct hdmi_phy *phy = pll_get_phy(pll);
+	struct hdmi_8998_phy_pll_reg_cfg cfg = {};
+	int i, ret;
+
+	ret = pll_calculate(rate, parent_rate, &cfg);
+	if (ret) {
+		DRM_ERROR("PLL calculation failed\n");
+		return ret;
+	}
+
+	/* Initially shut down PHY */
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_PD_CTL, 0x0);
+	udelay(500);
+
+	/* Power up sequence */
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_PD_CTL, 0x1);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_RESETSM_CNTRL, 0x20);
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CMN_CTRL, 0x6);
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_INTERFACE_SELECT_TX_BAND,
+				   cfg.tx_lx_tx_band[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_CLKBUF_TERM_ENABLE,
+				   0x1);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_LANE_MODE,
+				   0x20);
+	}
+
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SYSCLK_BUF_ENABLE, 0x02);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x0B);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SYSCLK_EN_SEL, 0x37);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SYS_CLK_CTRL, 0x02);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CLK_ENABLE1, 0x0E);
+
+	/* Bypass VCO calibration */
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_SVS_MODE_CLK_SEL,
+		       cfg.com_svs_mode_clk_sel);
+
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_PLL_IVCO, 0x07);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_VCO_TUNE_CTRL, 0x00);
+
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CLK_SEL, 0x30);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_HSCLK_SEL,
+		       cfg.com_hsclk_sel);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP_EN,
+		       cfg.com_lock_cmp_en);
+
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_PLL_CCTRL_MODE0,
+		       cfg.com_pll_cctrl_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_PLL_RCTRL_MODE0,
+		       cfg.com_pll_rctrl_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CP_CTRL_MODE0,
+		       cfg.com_cp_ctrl_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DEC_START_MODE0,
+		       cfg.com_dec_start_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DIV_FRAC_START1_MODE0,
+		       cfg.com_div_frac_start1_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DIV_FRAC_START2_MODE0,
+		       cfg.com_div_frac_start2_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_DIV_FRAC_START3_MODE0,
+		       cfg.com_div_frac_start3_mode0);
+
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_INTEGLOOP_GAIN0_MODE0,
+		       cfg.com_integloop_gain0_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_INTEGLOOP_GAIN1_MODE0,
+		       cfg.com_integloop_gain1_mode0);
+
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP1_MODE0,
+		       cfg.com_lock_cmp1_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP2_MODE0,
+		       cfg.com_lock_cmp2_mode0);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_LOCK_CMP3_MODE0,
+		       cfg.com_lock_cmp3_mode0);
+
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_VCO_TUNE_MAP, 0x00);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CORE_CLK_EN,
+		       cfg.com_core_clk_en);
+	hdmi_pll_write(pll, REG_HDMI_8998_PHY_QSERDES_COM_CORECLK_DIV_MODE0,
+		       cfg.com_coreclk_div_mode0);
+
+	/* TX lanes setup (TX 0/1/2/3) */
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_DRV_LVL,
+				   cfg.tx_lx_tx_drv_lvl[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_EMP_POST1_LVL,
+				   cfg.tx_lx_tx_emp_post1_lvl[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_PRE_DRIVER_1,
+				   cfg.tx_lx_pre_driver_1[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_PRE_DRIVER_2,
+				   cfg.tx_lx_pre_driver_2[i]);
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_DRV_LVL_RES_CODE_OFFSET,
+				   cfg.tx_lx_res_code_offset[i]);
+	}
+
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_MODE, cfg.phy_mode);
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_LANE_CONFIG,
+				   0x10);
+	}
+
+	/*
+	 * Ensure that vco configuration gets flushed to hardware before
+	 * enabling the PLL
+	 */
+	wmb();
+
+	pll->rate = rate;
+
+	return 0;
+}
+
+static int hdmi_8998_phy_ready_status(struct hdmi_phy *phy)
+{
+	u32 nb_tries = HDMI_PLL_POLL_MAX_READS;
+	unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US;
+	u32 status;
+	int phy_ready = 0;
+
+	while (nb_tries--) {
+		status = hdmi_phy_read(phy, REG_HDMI_8998_PHY_STATUS);
+		phy_ready = status & BIT(0);
+
+		if (phy_ready)
+			break;
+
+		udelay(timeout);
+	}
+
+	return phy_ready;
+}
+
+static int hdmi_8998_pll_lock_status(struct hdmi_pll_8998 *pll)
+{
+	u32 status;
+	int nb_tries = HDMI_PLL_POLL_MAX_READS;
+	unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US;
+	int pll_locked = 0;
+
+	while (nb_tries--) {
+		status = hdmi_pll_read(pll,
+				       REG_HDMI_8998_PHY_QSERDES_COM_C_READY_STATUS);
+		pll_locked = status & BIT(0);
+
+		if (pll_locked)
+			break;
+
+		udelay(timeout);
+	}
+
+	return pll_locked;
+}
+
+static int hdmi_8998_pll_prepare(struct clk_hw *hw)
+{
+	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
+	struct hdmi_phy *phy = pll_get_phy(pll);
+	int i, ret = 0;
+
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x1);
+	udelay(100);
+
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x59);
+	udelay(100);
+
+	ret = hdmi_8998_pll_lock_status(pll);
+	if (!ret)
+		return ret;
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+		hdmi_tx_chan_write(pll, i,
+				   REG_HDMI_8998_PHY_TXn_LANE_CONFIG, 0x1F);
+	}
+
+	/* Ensure all registers are flushed to hardware */
+	wmb();
+
+	ret = hdmi_8998_phy_ready_status(phy);
+	if (!ret)
+		return ret;
+
+	/* Restart the retiming buffer */
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x58);
+	udelay(1);
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_CFG, 0x59);
+
+	/* Ensure all registers are flushed to hardware */
+	wmb();
+
+	return 0;
+}
+
+static long hdmi_8998_pll_round_rate(struct clk_hw *hw,
+				     unsigned long rate,
+				     unsigned long *parent_rate)
+{
+	if (rate < HDMI_PCLK_MIN_FREQ)
+		return HDMI_PCLK_MIN_FREQ;
+	else if (rate > HDMI_PCLK_MAX_FREQ)
+		return HDMI_PCLK_MAX_FREQ;
+	else
+		return rate;
+}
+
+static unsigned long hdmi_8998_pll_recalc_rate(struct clk_hw *hw,
+					       unsigned long parent_rate)
+{
+	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
+	return pll->rate;
+}
+
+static void hdmi_8998_pll_unprepare(struct clk_hw *hw)
+{
+	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
+	struct hdmi_phy *phy = pll_get_phy(pll);
+
+	hdmi_phy_write(phy, REG_HDMI_8998_PHY_PD_CTL, 0);
+	usleep_range(100, 150);
+}
+
+static int hdmi_8998_pll_is_enabled(struct clk_hw *hw)
+{
+	struct hdmi_pll_8998 *pll = hw_clk_to_pll(hw);
+	u32 status;
+	int pll_locked;
+
+	status = hdmi_pll_read(pll, REG_HDMI_8998_PHY_QSERDES_COM_C_READY_STATUS);
+	pll_locked = status & BIT(0);
+
+	return pll_locked;
+}
+
+static const struct clk_ops hdmi_8998_pll_ops = {
+	.set_rate = hdmi_8998_pll_set_clk_rate,
+	.round_rate = hdmi_8998_pll_round_rate,
+	.recalc_rate = hdmi_8998_pll_recalc_rate,
+	.prepare = hdmi_8998_pll_prepare,
+	.unprepare = hdmi_8998_pll_unprepare,
+	.is_enabled = hdmi_8998_pll_is_enabled,
+};
+
+static const struct clk_init_data pll_init = {
+	.name = "hdmipll",
+	.ops = &hdmi_8998_pll_ops,
+	.parent_data = (const struct clk_parent_data[]){
+		{ .fw_name = "xo", .name = "xo_board" },
+	},
+	.num_parents = 1,
+	.flags = CLK_IGNORE_UNUSED,
+};
+
+int msm_hdmi_pll_8998_init(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct hdmi_pll_8998 *pll;
+	int ret, i;
+
+	pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return -ENOMEM;
+
+	pll->pdev = pdev;
+
+	pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll");
+	if (IS_ERR(pll->mmio_qserdes_com)) {
+		DRM_DEV_ERROR(dev, "failed to map pll base\n");
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) {
+		char name[32];
+
+		snprintf(name, sizeof(name), "hdmi_tx_l%d", i);
+
+		pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name);
+		if (IS_ERR(pll->mmio_qserdes_tx[i])) {
+			DRM_DEV_ERROR(dev, "failed to map pll base\n");
+			return -ENOMEM;
+		}
+	}
+	pll->clk_hw.init = &pll_init;
+
+	ret = devm_clk_hw_register(dev, &pll->clk_hw);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "failed to register pll clock\n");
+		return ret;
+	}
+
+	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &pll->clk_hw);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const char * const hdmi_phy_8998_reg_names[] = {
+	"vddio",
+	"vcca",
+};
+
+static const char * const hdmi_phy_8998_clk_names[] = {
+	"iface", "ref", "xo",
+};
+
+const struct hdmi_phy_cfg msm_hdmi_phy_8998_cfg = {
+	.type = MSM_HDMI_PHY_8998,
+	.reg_names = hdmi_phy_8998_reg_names,
+	.num_regs = ARRAY_SIZE(hdmi_phy_8998_reg_names),
+	.clk_names = hdmi_phy_8998_clk_names,
+	.num_clks = ARRAY_SIZE(hdmi_phy_8998_clk_names),
+};
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/hdmi_phy_8x60.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/hdmi_phy_8x60.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/delay.h>
+
+#include "hdmi.h"
+
+static void hdmi_phy_8x60_powerup(struct hdmi_phy *phy,
+		unsigned long int pixclock)
+{
+	/* De-serializer delay D/C for non-lbk mode: */
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG0,
+		       HDMI_8x60_PHY_REG0_DESER_DEL_CTRL(3));
+
+	if (pixclock == 27000000) {
+		/* video_format == HDMI_VFRMT_720x480p60_16_9 */
+		hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG1,
+			       HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) |
+			       HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(3));
+	} else {
+		hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG1,
+			       HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) |
+			       HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(4));
+	}
+
+	/* No matter what, start from the power down mode: */
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2,
+		       HDMI_8x60_PHY_REG2_PD_PWRGEN |
+		       HDMI_8x60_PHY_REG2_PD_PLL |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
+		       HDMI_8x60_PHY_REG2_PD_DESER);
+
+	/* Turn PowerGen on: */
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2,
+		       HDMI_8x60_PHY_REG2_PD_PLL |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
+		       HDMI_8x60_PHY_REG2_PD_DESER);
+
+	/* Turn PLL power on: */
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2,
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
+		       HDMI_8x60_PHY_REG2_PD_DESER);
+
+	/* Write to HIGH after PLL power down de-assert: */
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG3,
+		       HDMI_8x60_PHY_REG3_PLL_ENABLE);
+
+	/* ASIC power on; PHY REG9 = 0 */
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG9, 0);
+
+	/* Enable PLL lock detect, PLL lock det will go high after lock
+	 * Enable the re-time logic
+	 */
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG12,
+		       HDMI_8x60_PHY_REG12_RETIMING_EN |
+		       HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN);
+
+	/* Drivers are on: */
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2,
+		       HDMI_8x60_PHY_REG2_PD_DESER);
+
+	/* If the RX detector is needed: */
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2,
+		       HDMI_8x60_PHY_REG2_RCV_SENSE_EN |
+		       HDMI_8x60_PHY_REG2_PD_DESER);
+
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG4, 0);
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG5, 0);
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG6, 0);
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG7, 0);
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG8, 0);
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG9, 0);
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG10, 0);
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG11, 0);
+
+	/* If we want to use lock enable based on counting: */
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG12,
+		       HDMI_8x60_PHY_REG12_RETIMING_EN |
+		       HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN |
+		       HDMI_8x60_PHY_REG12_FORCE_LOCK);
+}
+
+static void hdmi_phy_8x60_powerdown(struct hdmi_phy *phy)
+{
+	/* Assert RESET PHY from controller */
+	hdmi_phy_write(phy, REG_HDMI_PHY_CTRL,
+		       HDMI_PHY_CTRL_SW_RESET);
+	udelay(10);
+	/* De-assert RESET PHY from controller */
+	hdmi_phy_write(phy, REG_HDMI_PHY_CTRL, 0);
+	/* Turn off Driver */
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2,
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
+		       HDMI_8x60_PHY_REG2_PD_DESER);
+	udelay(10);
+	/* Disable PLL */
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG3, 0);
+	/* Power down PHY, but keep RX-sense: */
+	hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2,
+		       HDMI_8x60_PHY_REG2_RCV_SENSE_EN |
+		       HDMI_8x60_PHY_REG2_PD_PWRGEN |
+		       HDMI_8x60_PHY_REG2_PD_PLL |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
+		       HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
+		       HDMI_8x60_PHY_REG2_PD_DESER);
+}
+
+static const char * const hdmi_phy_8x60_reg_names[] = {
+	"core-vdda",
+};
+
+static const char * const hdmi_phy_8x60_clk_names[] = {
+	"slave_iface",
+};
+
+const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg = {
+	.type = MSM_HDMI_PHY_8x60,
+	.powerup = hdmi_phy_8x60_powerup,
+	.powerdown = hdmi_phy_8x60_powerdown,
+	.reg_names = hdmi_phy_8x60_reg_names,
+	.num_regs = ARRAY_SIZE(hdmi_phy_8x60_reg_names),
+	.clk_names = hdmi_phy_8x60_clk_names,
+	.num_clks = ARRAY_SIZE(hdmi_phy_8x60_clk_names),
+};
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/hdmi_phy_8x74.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/hdmi_phy_8x74.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include "hdmi.h"
+
+static void hdmi_phy_8x74_powerup(struct hdmi_phy *phy,
+		unsigned long int pixclock)
+{
+	hdmi_phy_write(phy, REG_HDMI_8x74_ANA_CFG0,   0x1b);
+	hdmi_phy_write(phy, REG_HDMI_8x74_ANA_CFG1,   0xf2);
+	hdmi_phy_write(phy, REG_HDMI_8x74_BIST_CFG0,  0x0);
+	hdmi_phy_write(phy, REG_HDMI_8x74_BIST_PATN0, 0x0);
+	hdmi_phy_write(phy, REG_HDMI_8x74_BIST_PATN1, 0x0);
+	hdmi_phy_write(phy, REG_HDMI_8x74_BIST_PATN2, 0x0);
+	hdmi_phy_write(phy, REG_HDMI_8x74_BIST_PATN3, 0x0);
+	hdmi_phy_write(phy, REG_HDMI_8x74_PD_CTRL1,   0x20);
+}
+
+static void hdmi_phy_8x74_powerdown(struct hdmi_phy *phy)
+{
+	hdmi_phy_write(phy, REG_HDMI_8x74_PD_CTRL0, 0x7f);
+}
+
+static const char * const hdmi_phy_8x74_reg_names[] = {
+	"core-vdda",
+	"vddio",
+};
+
+static const char * const hdmi_phy_8x74_clk_names[] = {
+	"iface", "alt_iface"
+};
+
+const struct hdmi_phy_cfg msm_hdmi_phy_8x74_cfg = {
+	.type = MSM_HDMI_PHY_8x74,
+	.powerup = hdmi_phy_8x74_powerup,
+	.powerdown = hdmi_phy_8x74_powerdown,
+	.reg_names = hdmi_phy_8x74_reg_names,
+	.num_regs = ARRAY_SIZE(hdmi_phy_8x74_reg_names),
+	.clk_names = hdmi_phy_8x74_clk_names,
+	.num_clks = ARRAY_SIZE(hdmi_phy_8x74_clk_names),
+};
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/hdmi_pll_8960.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/hdmi_pll_8960.c
@@ -0,0 +1,458 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+
+#include "hdmi.h"
+
+struct hdmi_pll_8960 {
+	struct platform_device *pdev;
+	struct clk_hw clk_hw;
+	void __iomem *mmio;
+
+	unsigned long pixclk;
+};
+
+#define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8960, clk_hw)
+
+/*
+ * HDMI PLL:
+ *
+ * To get the parent clock setup properly, we need to plug in hdmi pll
+ * configuration into common-clock-framework.
+ */
+
+struct pll_rate {
+	unsigned long rate;
+	int num_reg;
+	struct {
+		u32 val;
+		u32 reg;
+	} conf[32];
+};
+
+/* NOTE: keep sorted highest freq to lowest: */
+static const struct pll_rate freqtbl[] = {
+	{ 154000000, 14, {
+		{ 0x08, REG_HDMI_8960_PHY_PLL_REFCLK_CFG    },
+		{ 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+		{ 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+		{ 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0   },
+		{ 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1   },
+		{ 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3   },
+		{ 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5   },
+		{ 0x0d, REG_HDMI_8960_PHY_PLL_SDM_CFG0      },
+		{ 0x4d, REG_HDMI_8960_PHY_PLL_SDM_CFG1      },
+		{ 0x5e, REG_HDMI_8960_PHY_PLL_SDM_CFG2      },
+		{ 0x42, REG_HDMI_8960_PHY_PLL_SDM_CFG3      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4      },
+			}
+	},
+	/* 1080p60/1080p50 case */
+	{ 148500000, 27, {
+		{ 0x02, REG_HDMI_8960_PHY_PLL_REFCLK_CFG    },
+		{ 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG },
+		{ 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+		{ 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+		{ 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG  },
+		{ 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG },
+		{ 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B       },
+		{ 0x76, REG_HDMI_8960_PHY_PLL_SDM_CFG0      },
+		{ 0x01, REG_HDMI_8960_PHY_PLL_SDM_CFG1      },
+		{ 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG2      },
+		{ 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4      },
+		{ 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG3      },
+		{ 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0  },
+		{ 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1  },
+		{ 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2  },
+		{ 0xe6, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0   },
+		{ 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1   },
+		{ 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3   },
+		{ 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5   },
+		{ 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7   },
+			}
+	},
+	{ 108000000, 13, {
+		{ 0x08, REG_HDMI_8960_PHY_PLL_REFCLK_CFG    },
+		{ 0x21, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+		{ 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+		{ 0x1c, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0   },
+		{ 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1   },
+		{ 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2   },
+		{ 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5   },
+		{ 0x49, REG_HDMI_8960_PHY_PLL_SDM_CFG0      },
+		{ 0x49, REG_HDMI_8960_PHY_PLL_SDM_CFG1      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG2      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG3      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4      },
+			}
+	},
+	/* 720p60/720p50/1080i60/1080i50/1080p24/1080p30/1080p25 */
+	{ 74250000, 8, {
+		{ 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B       },
+		{ 0x12, REG_HDMI_8960_PHY_PLL_REFCLK_CFG    },
+		{ 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+		{ 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+		{ 0x76, REG_HDMI_8960_PHY_PLL_SDM_CFG0      },
+		{ 0xe6, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0   },
+		{ 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1   },
+		{ 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2   },
+			}
+	},
+	{ 74176000, 14, {
+		{ 0x18, REG_HDMI_8960_PHY_PLL_REFCLK_CFG    },
+		{ 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+		{ 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+		{ 0xe5, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0   },
+		{ 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1   },
+		{ 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3   },
+		{ 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5   },
+		{ 0x0c, REG_HDMI_8960_PHY_PLL_SDM_CFG0      },
+		{ 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG1      },
+		{ 0x7d, REG_HDMI_8960_PHY_PLL_SDM_CFG2      },
+		{ 0xbc, REG_HDMI_8960_PHY_PLL_SDM_CFG3      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4      },
+			}
+	},
+	{ 65000000, 14, {
+		{ 0x18, REG_HDMI_8960_PHY_PLL_REFCLK_CFG    },
+		{ 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+		{ 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+		{ 0x8a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0   },
+		{ 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1   },
+		{ 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3   },
+		{ 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5   },
+		{ 0x0b, REG_HDMI_8960_PHY_PLL_SDM_CFG0      },
+		{ 0x4b, REG_HDMI_8960_PHY_PLL_SDM_CFG1      },
+		{ 0x7b, REG_HDMI_8960_PHY_PLL_SDM_CFG2      },
+		{ 0x09, REG_HDMI_8960_PHY_PLL_SDM_CFG3      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4      },
+			}
+	},
+	/* 480p60/480i60 */
+	{ 27030000, 18, {
+		{ 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B       },
+		{ 0x38, REG_HDMI_8960_PHY_PLL_REFCLK_CFG    },
+		{ 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG },
+		{ 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+		{ 0xff, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG0      },
+		{ 0x4e, REG_HDMI_8960_PHY_PLL_SDM_CFG1      },
+		{ 0xd7, REG_HDMI_8960_PHY_PLL_SDM_CFG2      },
+		{ 0x03, REG_HDMI_8960_PHY_PLL_SDM_CFG3      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4      },
+		{ 0x2a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0   },
+		{ 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1   },
+		{ 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3   },
+		{ 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5   },
+		{ 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7   },
+			}
+	},
+	/* 576p50/576i50 */
+	{ 27000000, 27, {
+		{ 0x32, REG_HDMI_8960_PHY_PLL_REFCLK_CFG    },
+		{ 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG },
+		{ 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+		{ 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+		{ 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG  },
+		{ 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG },
+		{ 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B       },
+		{ 0x7b, REG_HDMI_8960_PHY_PLL_SDM_CFG0      },
+		{ 0x01, REG_HDMI_8960_PHY_PLL_SDM_CFG1      },
+		{ 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG2      },
+		{ 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4      },
+		{ 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG3      },
+		{ 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0  },
+		{ 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1  },
+		{ 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2  },
+		{ 0x2a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0   },
+		{ 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1   },
+		{ 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3   },
+		{ 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5   },
+		{ 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7   },
+			}
+	},
+	/* 640x480p60 */
+	{ 25200000, 27, {
+		{ 0x32, REG_HDMI_8960_PHY_PLL_REFCLK_CFG    },
+		{ 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG },
+		{ 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 },
+		{ 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 },
+		{ 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG  },
+		{ 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG },
+		{ 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B       },
+		{ 0x77, REG_HDMI_8960_PHY_PLL_SDM_CFG0      },
+		{ 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG1      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG2      },
+		{ 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4      },
+		{ 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1      },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2      },
+		{ 0x20, REG_HDMI_8960_PHY_PLL_SSC_CFG3      },
+		{ 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0  },
+		{ 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1  },
+		{ 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2  },
+		{ 0xf4, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0   },
+		{ 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1   },
+		{ 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3   },
+		{ 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5   },
+		{ 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6   },
+		{ 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7   },
+			}
+	},
+};
+
+static inline void pll_write(struct hdmi_pll_8960 *pll, u32 reg, u32 data)
+{
+	msm_writel(data, pll->mmio + reg);
+}
+
+static inline u32 pll_read(struct hdmi_pll_8960 *pll, u32 reg)
+{
+	return msm_readl(pll->mmio + reg);
+}
+
+static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8960 *pll)
+{
+	return platform_get_drvdata(pll->pdev);
+}
+
+static int hdmi_pll_enable(struct clk_hw *hw)
+{
+	struct hdmi_pll_8960 *pll = hw_clk_to_pll(hw);
+	struct hdmi_phy *phy = pll_get_phy(pll);
+	int timeout_count, pll_lock_retry = 10;
+	unsigned int val;
+
+	DBG("");
+
+	/* Assert PLL S/W reset */
+	pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x8d);
+	pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0, 0x10);
+	pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1, 0x1a);
+
+	/* Wait for a short time before de-asserting
+	 * to allow the hardware to complete its job.
+	 * This much of delay should be fine for hardware
+	 * to assert and de-assert.
+	 */
+	udelay(10);
+
+	/* De-assert PLL S/W reset */
+	pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x0d);
+
+	val = hdmi_phy_read(phy, REG_HDMI_8960_PHY_REG12);
+	val |= HDMI_8960_PHY_REG12_SW_RESET;
+	/* Assert PHY S/W reset */
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val);
+	val &= ~HDMI_8960_PHY_REG12_SW_RESET;
+	/*
+	 * Wait for a short time before de-asserting to allow the hardware to
+	 * complete its job. This much of delay should be fine for hardware to
+	 * assert and de-assert.
+	 */
+	udelay(10);
+	/* De-assert PHY S/W reset */
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val);
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG2,  0x3f);
+
+	val = hdmi_phy_read(phy, REG_HDMI_8960_PHY_REG12);
+	val |= HDMI_8960_PHY_REG12_PWRDN_B;
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val);
+	/* Wait 10 us for enabling global power for PHY */
+	mb();
+	udelay(10);
+
+	val = pll_read(pll, REG_HDMI_8960_PHY_PLL_PWRDN_B);
+	val |= HDMI_8960_PHY_PLL_PWRDN_B_PLL_PWRDN_B;
+	val &= ~HDMI_8960_PHY_PLL_PWRDN_B_PD_PLL;
+	pll_write(pll, REG_HDMI_8960_PHY_PLL_PWRDN_B, val);
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG2, 0x80);
+
+	timeout_count = 1000;
+	while (--pll_lock_retry > 0) {
+		/* are we there yet? */
+		val = pll_read(pll, REG_HDMI_8960_PHY_PLL_STATUS0);
+		if (val & HDMI_8960_PHY_PLL_STATUS0_PLL_LOCK)
+			break;
+
+		udelay(1);
+
+		if (--timeout_count > 0)
+			continue;
+
+		/*
+		 * PLL has still not locked.
+		 * Do a software reset and try again
+		 * Assert PLL S/W reset first
+		 */
+		pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x8d);
+		udelay(10);
+		pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x0d);
+
+		/*
+		 * Wait for a short duration for the PLL calibration
+		 * before checking if the PLL gets locked
+		 */
+		udelay(350);
+
+		timeout_count = 1000;
+	}
+
+	return 0;
+}
+
+static void hdmi_pll_disable(struct clk_hw *hw)
+{
+	struct hdmi_pll_8960 *pll = hw_clk_to_pll(hw);
+	struct hdmi_phy *phy = pll_get_phy(pll);
+	unsigned int val;
+
+	DBG("");
+
+	val = hdmi_phy_read(phy, REG_HDMI_8960_PHY_REG12);
+	val &= ~HDMI_8960_PHY_REG12_PWRDN_B;
+	hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val);
+
+	val = pll_read(pll, REG_HDMI_8960_PHY_PLL_PWRDN_B);
+	val |= HDMI_8960_PHY_REG12_SW_RESET;
+	val &= ~HDMI_8960_PHY_REG12_PWRDN_B;
+	pll_write(pll, REG_HDMI_8960_PHY_PLL_PWRDN_B, val);
+	/* Make sure HDMI PHY/PLL are powered down */
+	mb();
+}
+
+static const struct pll_rate *find_rate(unsigned long rate)
+{
+	int i;
+
+	for (i = 1; i < ARRAY_SIZE(freqtbl); i++)
+		if (rate > freqtbl[i].rate)
+			return &freqtbl[i - 1];
+
+	return &freqtbl[i - 1];
+}
+
+static unsigned long hdmi_pll_recalc_rate(struct clk_hw *hw,
+					  unsigned long parent_rate)
+{
+	struct hdmi_pll_8960 *pll = hw_clk_to_pll(hw);
+
+	return pll->pixclk;
+}
+
+static long hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long *parent_rate)
+{
+	const struct pll_rate *pll_rate = find_rate(rate);
+
+	return pll_rate->rate;
+}
+
+static int hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			     unsigned long parent_rate)
+{
+	struct hdmi_pll_8960 *pll = hw_clk_to_pll(hw);
+	const struct pll_rate *pll_rate = find_rate(rate);
+	int i;
+
+	DBG("rate=%lu", rate);
+
+	for (i = 0; i < pll_rate->num_reg; i++)
+		pll_write(pll, pll_rate->conf[i].reg, pll_rate->conf[i].val);
+
+	pll->pixclk = rate;
+
+	return 0;
+}
+
+static const struct clk_ops hdmi_pll_ops = {
+	.enable = hdmi_pll_enable,
+	.disable = hdmi_pll_disable,
+	.recalc_rate = hdmi_pll_recalc_rate,
+	.round_rate = hdmi_pll_round_rate,
+	.set_rate = hdmi_pll_set_rate,
+};
+
+static const struct clk_parent_data hdmi_pll_parents[] = {
+	{ .fw_name = "pxo", .name = "pxo_board" },
+};
+
+static struct clk_init_data pll_init = {
+	.name = "hdmi_pll",
+	.ops = &hdmi_pll_ops,
+	.parent_data = hdmi_pll_parents,
+	.num_parents = ARRAY_SIZE(hdmi_pll_parents),
+	.flags = CLK_IGNORE_UNUSED,
+};
+
+int msm_hdmi_pll_8960_init(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct hdmi_pll_8960 *pll;
+	int i, ret;
+
+	/* sanity check: */
+	for (i = 0; i < (ARRAY_SIZE(freqtbl) - 1); i++)
+		if (WARN_ON(freqtbl[i].rate < freqtbl[i + 1].rate))
+			return -EINVAL;
+
+	pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return -ENOMEM;
+
+	pll->mmio = msm_ioremap(pdev, "hdmi_pll");
+	if (IS_ERR(pll->mmio)) {
+		DRM_DEV_ERROR(dev, "failed to map pll base\n");
+		return -ENOMEM;
+	}
+
+	pll->pdev = pdev;
+	pll->clk_hw.init = &pll_init;
+
+	ret = devm_clk_hw_register(dev, &pll->clk_hw);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dev, "failed to register pll clock\n");
+		return ret;
+	}
+
+	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &pll->clk_hw);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "%s: failed to register clk provider: %d\n", __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/hdmi/qfprom.xml.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/hdmi/qfprom.xml.h
@@ -0,0 +1,61 @@
+#ifndef QFPROM_XML
+#define QFPROM_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://github.com/freedreno/envytools/
+git clone https://github.com/freedreno/envytools.git
+
+The rules-ng-ng source files this header was generated from are:
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/msm.xml                   (    944 bytes, from 2022-07-23 20:21:46)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/freedreno_copyright.xml   (   1572 bytes, from 2022-07-23 20:21:46)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp4.xml              (  20912 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp_common.xml        (   2849 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/mdp/mdp5.xml              (  37461 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi.xml               (  18746 bytes, from 2022-04-28 17:29:36)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_v2.xml        (   3236 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm_8960.xml (   4935 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_28nm.xml      (   7004 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_20nm.xml      (   3712 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_14nm.xml      (   5381 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_10nm.xml      (   4499 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/dsi_phy_7nm.xml       (  11007 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/sfpb.xml              (    602 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/dsi/mmss_cc.xml           (   1686 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/qfprom.xml           (    600 bytes, from 2022-03-08 17:40:42)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/hdmi/hdmi.xml             (  42350 bytes, from 2022-09-20 17:45:56)
+- /home/robclark/src/mesa/mesa/src/freedreno/registers/edp/edp.xml               (  10416 bytes, from 2022-03-08 17:40:42)
+
+Copyright (C) 2013-2022 by the following authors:
+- Rob Clark <robdclark@gmail.com> (robclark)
+- Ilia Mirkin <imirkin@alum.mit.edu> (imirkin)
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+
+#define REG_QFPROM_CONFIG_ROW0_LSB				0x00000238
+#define QFPROM_CONFIG_ROW0_LSB_HDMI_DISABLE			0x00200000
+#define QFPROM_CONFIG_ROW0_LSB_HDCP_DISABLE			0x00400000
+
+
+#endif /* QFPROM_XML */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_atomic.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_atomic.c
@@ -0,0 +1,313 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2014 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <drm/drm_atomic_uapi.h>
+#include <drm/drm_vblank.h>
+
+#include "msm_atomic_trace.h"
+#include "msm_drv.h"
+#include "msm_gem.h"
+#include "msm_kms.h"
+
+/*
+ * Helpers to control vblanks while we flush.. basically just to ensure
+ * that vblank accounting is switched on, so we get valid seqn/timestamp
+ * on pageflip events (if requested)
+ */
+
+static void vblank_get(struct msm_kms *kms, unsigned crtc_mask)
+{
+	struct drm_crtc *crtc;
+
+	for_each_crtc_mask(kms->dev, crtc, crtc_mask) {
+		if (!crtc->state->active)
+			continue;
+		drm_crtc_vblank_get(crtc);
+	}
+}
+
+static void vblank_put(struct msm_kms *kms, unsigned crtc_mask)
+{
+	struct drm_crtc *crtc;
+
+	for_each_crtc_mask(kms->dev, crtc, crtc_mask) {
+		if (!crtc->state->active)
+			continue;
+		drm_crtc_vblank_put(crtc);
+	}
+}
+
+static void lock_crtcs(struct msm_kms *kms, unsigned int crtc_mask)
+{
+	int crtc_index;
+	struct drm_crtc *crtc;
+
+	for_each_crtc_mask(kms->dev, crtc, crtc_mask) {
+		crtc_index = drm_crtc_index(crtc);
+		mutex_lock_nested(&kms->commit_lock[crtc_index], crtc_index);
+	}
+}
+
+static void unlock_crtcs(struct msm_kms *kms, unsigned int crtc_mask)
+{
+	struct drm_crtc *crtc;
+
+	for_each_crtc_mask_reverse(kms->dev, crtc, crtc_mask)
+		mutex_unlock(&kms->commit_lock[drm_crtc_index(crtc)]);
+}
+
+static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx)
+{
+	unsigned crtc_mask = BIT(crtc_idx);
+
+	trace_msm_atomic_async_commit_start(crtc_mask);
+
+	lock_crtcs(kms, crtc_mask);
+
+	if (!(kms->pending_crtc_mask & crtc_mask)) {
+		unlock_crtcs(kms, crtc_mask);
+		goto out;
+	}
+
+	kms->pending_crtc_mask &= ~crtc_mask;
+
+	kms->funcs->enable_commit(kms);
+
+	vblank_get(kms, crtc_mask);
+
+	/*
+	 * Flush hardware updates:
+	 */
+	trace_msm_atomic_flush_commit(crtc_mask);
+	kms->funcs->flush_commit(kms, crtc_mask);
+
+	/*
+	 * Wait for flush to complete:
+	 */
+	trace_msm_atomic_wait_flush_start(crtc_mask);
+	kms->funcs->wait_flush(kms, crtc_mask);
+	trace_msm_atomic_wait_flush_finish(crtc_mask);
+
+	vblank_put(kms, crtc_mask);
+
+	kms->funcs->complete_commit(kms, crtc_mask);
+	unlock_crtcs(kms, crtc_mask);
+	kms->funcs->disable_commit(kms);
+
+out:
+	trace_msm_atomic_async_commit_finish(crtc_mask);
+}
+
+static void msm_atomic_pending_work(struct kthread_work *work)
+{
+	struct msm_pending_timer *timer = container_of(work,
+			struct msm_pending_timer, work.work);
+
+	msm_atomic_async_commit(timer->kms, timer->crtc_idx);
+}
+
+int msm_atomic_init_pending_timer(struct msm_pending_timer *timer,
+		struct msm_kms *kms, int crtc_idx)
+{
+	timer->kms = kms;
+	timer->crtc_idx = crtc_idx;
+
+	timer->worker = kthread_create_worker(0, "atomic-worker-%d", crtc_idx);
+	if (IS_ERR(timer->worker)) {
+		int ret = PTR_ERR(timer->worker);
+		timer->worker = NULL;
+		return ret;
+	}
+	sched_set_fifo(timer->worker->task);
+
+	msm_hrtimer_work_init(&timer->work, timer->worker,
+			      msm_atomic_pending_work,
+			      CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+
+	return 0;
+}
+
+void msm_atomic_destroy_pending_timer(struct msm_pending_timer *timer)
+{
+	if (timer->worker)
+		kthread_destroy_worker(timer->worker);
+}
+
+static bool can_do_async(struct drm_atomic_state *state,
+		struct drm_crtc **async_crtc)
+{
+	struct drm_connector_state *connector_state;
+	struct drm_connector *connector;
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc *crtc;
+	int i, num_crtcs = 0;
+
+	if (!(state->legacy_cursor_update || state->async_update))
+		return false;
+
+	/* any connector change, means slow path: */
+	for_each_new_connector_in_state(state, connector, connector_state, i)
+		return false;
+
+	for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
+		if (drm_atomic_crtc_needs_modeset(crtc_state))
+			return false;
+		if (!crtc_state->active)
+			return false;
+		if (++num_crtcs > 1)
+			return false;
+		*async_crtc = crtc;
+	}
+
+	return true;
+}
+
+/* Get bitmask of crtcs that will need to be flushed.  The bitmask
+ * can be used with for_each_crtc_mask() iterator, to iterate
+ * effected crtcs without needing to preserve the atomic state.
+ */
+static unsigned get_crtc_mask(struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc *crtc;
+	unsigned i, mask = 0;
+
+	for_each_new_crtc_in_state(state, crtc, crtc_state, i)
+		mask |= drm_crtc_mask(crtc);
+
+	return mask;
+}
+
+int msm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state)
+{
+	struct drm_crtc_state *old_crtc_state, *new_crtc_state;
+	struct drm_crtc *crtc;
+	int i;
+
+	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
+				      new_crtc_state, i) {
+		if ((old_crtc_state->ctm && !new_crtc_state->ctm) ||
+		    (!old_crtc_state->ctm && new_crtc_state->ctm)) {
+			new_crtc_state->mode_changed = true;
+			state->allow_modeset = true;
+		}
+	}
+
+	return drm_atomic_helper_check(dev, state);
+}
+
+void msm_atomic_commit_tail(struct drm_atomic_state *state)
+{
+	struct drm_device *dev = state->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+	struct drm_crtc *async_crtc = NULL;
+	unsigned crtc_mask = get_crtc_mask(state);
+	bool async = can_do_async(state, &async_crtc);
+
+	trace_msm_atomic_commit_tail_start(async, crtc_mask);
+
+	drm_dp_mst_atomic_wait_for_dependencies(state);
+
+	kms->funcs->enable_commit(kms);
+
+	/*
+	 * Ensure any previous (potentially async) commit has
+	 * completed:
+	 */
+	lock_crtcs(kms, crtc_mask);
+	trace_msm_atomic_wait_flush_start(crtc_mask);
+	kms->funcs->wait_flush(kms, crtc_mask);
+	trace_msm_atomic_wait_flush_finish(crtc_mask);
+
+	/*
+	 * Now that there is no in-progress flush, prepare the
+	 * current update:
+	 */
+	if (kms->funcs->prepare_commit)
+		kms->funcs->prepare_commit(kms, state);
+
+	/*
+	 * Push atomic updates down to hardware:
+	 */
+	drm_atomic_helper_commit_modeset_disables(dev, state);
+	drm_atomic_helper_commit_planes(dev, state, 0);
+	drm_atomic_helper_commit_modeset_enables(dev, state);
+
+	if (async) {
+		struct msm_pending_timer *timer =
+			&kms->pending_timers[drm_crtc_index(async_crtc)];
+
+		/* async updates are limited to single-crtc updates: */
+		WARN_ON(crtc_mask != drm_crtc_mask(async_crtc));
+
+		/*
+		 * Start timer if we don't already have an update pending
+		 * on this crtc:
+		 */
+		if (!(kms->pending_crtc_mask & crtc_mask)) {
+			ktime_t vsync_time, wakeup_time;
+
+			kms->pending_crtc_mask |= crtc_mask;
+
+			if (drm_crtc_next_vblank_start(async_crtc, &vsync_time))
+				goto fallback;
+
+			wakeup_time = ktime_sub(vsync_time, ms_to_ktime(1));
+
+			msm_hrtimer_queue_work(&timer->work, wakeup_time,
+					HRTIMER_MODE_ABS);
+		}
+
+		kms->funcs->disable_commit(kms);
+		unlock_crtcs(kms, crtc_mask);
+		/*
+		 * At this point, from drm core's perspective, we
+		 * are done with the atomic update, so we can just
+		 * go ahead and signal that it is done:
+		 */
+		drm_atomic_helper_commit_hw_done(state);
+		drm_atomic_helper_cleanup_planes(dev, state);
+
+		trace_msm_atomic_commit_tail_finish(async, crtc_mask);
+
+		return;
+	}
+
+fallback:
+	/*
+	 * If there is any async flush pending on updated crtcs, fold
+	 * them into the current flush.
+	 */
+	kms->pending_crtc_mask &= ~crtc_mask;
+
+	vblank_get(kms, crtc_mask);
+
+	/*
+	 * Flush hardware updates:
+	 */
+	trace_msm_atomic_flush_commit(crtc_mask);
+	kms->funcs->flush_commit(kms, crtc_mask);
+	unlock_crtcs(kms, crtc_mask);
+	/*
+	 * Wait for flush to complete:
+	 */
+	trace_msm_atomic_wait_flush_start(crtc_mask);
+	kms->funcs->wait_flush(kms, crtc_mask);
+	trace_msm_atomic_wait_flush_finish(crtc_mask);
+
+	vblank_put(kms, crtc_mask);
+
+	lock_crtcs(kms, crtc_mask);
+	kms->funcs->complete_commit(kms, crtc_mask);
+	unlock_crtcs(kms, crtc_mask);
+	kms->funcs->disable_commit(kms);
+
+	drm_atomic_helper_commit_hw_done(state);
+	drm_atomic_helper_cleanup_planes(dev, state);
+
+	trace_msm_atomic_commit_tail_finish(async, crtc_mask);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_atomic_trace.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_atomic_trace.h
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#if !defined(_MSM_GPU_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
+#define _MSM_GPU_TRACE_H_
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM drm_msm_atomic
+#define TRACE_INCLUDE_FILE msm_atomic_trace
+
+TRACE_EVENT(msm_atomic_commit_tail_start,
+	    TP_PROTO(bool async, unsigned crtc_mask),
+	    TP_ARGS(async, crtc_mask),
+	    TP_STRUCT__entry(
+		    __field(bool, async)
+		    __field(u32, crtc_mask)
+		    ),
+	    TP_fast_assign(
+		    __entry->async = async;
+		    __entry->crtc_mask = crtc_mask;
+		    ),
+	    TP_printk("async=%d crtc_mask=%x",
+		    __entry->async, __entry->crtc_mask)
+);
+
+TRACE_EVENT(msm_atomic_commit_tail_finish,
+	    TP_PROTO(bool async, unsigned crtc_mask),
+	    TP_ARGS(async, crtc_mask),
+	    TP_STRUCT__entry(
+		    __field(bool, async)
+		    __field(u32, crtc_mask)
+		    ),
+	    TP_fast_assign(
+		    __entry->async = async;
+		    __entry->crtc_mask = crtc_mask;
+		    ),
+	    TP_printk("async=%d crtc_mask=%x",
+		    __entry->async, __entry->crtc_mask)
+);
+
+TRACE_EVENT(msm_atomic_async_commit_start,
+	    TP_PROTO(unsigned crtc_mask),
+	    TP_ARGS(crtc_mask),
+	    TP_STRUCT__entry(
+		    __field(u32, crtc_mask)
+		    ),
+	    TP_fast_assign(
+		    __entry->crtc_mask = crtc_mask;
+		    ),
+	    TP_printk("crtc_mask=%x",
+		    __entry->crtc_mask)
+);
+
+TRACE_EVENT(msm_atomic_async_commit_finish,
+	    TP_PROTO(unsigned crtc_mask),
+	    TP_ARGS(crtc_mask),
+	    TP_STRUCT__entry(
+		    __field(u32, crtc_mask)
+		    ),
+	    TP_fast_assign(
+		    __entry->crtc_mask = crtc_mask;
+		    ),
+	    TP_printk("crtc_mask=%x",
+		    __entry->crtc_mask)
+);
+
+TRACE_EVENT(msm_atomic_wait_flush_start,
+	    TP_PROTO(unsigned crtc_mask),
+	    TP_ARGS(crtc_mask),
+	    TP_STRUCT__entry(
+		    __field(u32, crtc_mask)
+		    ),
+	    TP_fast_assign(
+		    __entry->crtc_mask = crtc_mask;
+		    ),
+	    TP_printk("crtc_mask=%x",
+		    __entry->crtc_mask)
+);
+
+TRACE_EVENT(msm_atomic_wait_flush_finish,
+	    TP_PROTO(unsigned crtc_mask),
+	    TP_ARGS(crtc_mask),
+	    TP_STRUCT__entry(
+		    __field(u32, crtc_mask)
+		    ),
+	    TP_fast_assign(
+		    __entry->crtc_mask = crtc_mask;
+		    ),
+	    TP_printk("crtc_mask=%x",
+		    __entry->crtc_mask)
+);
+
+TRACE_EVENT(msm_atomic_flush_commit,
+	    TP_PROTO(unsigned crtc_mask),
+	    TP_ARGS(crtc_mask),
+	    TP_STRUCT__entry(
+		    __field(u32, crtc_mask)
+		    ),
+	    TP_fast_assign(
+		    __entry->crtc_mask = crtc_mask;
+		    ),
+	    TP_printk("crtc_mask=%x",
+		    __entry->crtc_mask)
+);
+
+#endif
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/msm
+#include <trace/define_trace.h>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_atomic_tracepoints.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_atomic_tracepoints.c
@@ -0,0 +1,3 @@
+// SPDX-License-Identifier: GPL-2.0
+#define CREATE_TRACE_POINTS
+#include "msm_atomic_trace.h"
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_debugfs.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_debugfs.c
@@ -0,0 +1,368 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013-2016 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/fault-inject.h>
+
+#include <drm/drm_debugfs.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_file.h>
+#include <drm/drm_framebuffer.h>
+
+#include "msm_drv.h"
+#include "msm_gpu.h"
+#include "msm_kms.h"
+#include "msm_debugfs.h"
+#include "disp/msm_disp_snapshot.h"
+
+/*
+ * GPU Snapshot:
+ */
+
+struct msm_gpu_show_priv {
+	struct msm_gpu_state *state;
+	struct drm_device *dev;
+};
+
+static int msm_gpu_show(struct seq_file *m, void *arg)
+{
+	struct drm_printer p = drm_seq_file_printer(m);
+	struct msm_gpu_show_priv *show_priv = m->private;
+	struct msm_drm_private *priv = show_priv->dev->dev_private;
+	struct msm_gpu *gpu = priv->gpu;
+	int ret;
+
+	ret = mutex_lock_interruptible(&gpu->lock);
+	if (ret)
+		return ret;
+
+	drm_printf(&p, "%s Status:\n", gpu->name);
+	gpu->funcs->show(gpu, show_priv->state, &p);
+
+	mutex_unlock(&gpu->lock);
+
+	return 0;
+}
+
+static int msm_gpu_release(struct inode *inode, struct file *file)
+{
+	struct seq_file *m = file->private_data;
+	struct msm_gpu_show_priv *show_priv = m->private;
+	struct msm_drm_private *priv = show_priv->dev->dev_private;
+	struct msm_gpu *gpu = priv->gpu;
+
+	mutex_lock(&gpu->lock);
+	gpu->funcs->gpu_state_put(show_priv->state);
+	mutex_unlock(&gpu->lock);
+
+	kfree(show_priv);
+
+	return single_release(inode, file);
+}
+
+static int msm_gpu_open(struct inode *inode, struct file *file)
+{
+	struct drm_device *dev = inode->i_private;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_gpu *gpu = priv->gpu;
+	struct msm_gpu_show_priv *show_priv;
+	int ret;
+
+	if (!gpu || !gpu->funcs->gpu_state_get)
+		return -ENODEV;
+
+	show_priv = kmalloc(sizeof(*show_priv), GFP_KERNEL);
+	if (!show_priv)
+		return -ENOMEM;
+
+	ret = mutex_lock_interruptible(&gpu->lock);
+	if (ret)
+		goto free_priv;
+
+	pm_runtime_get_sync(&gpu->pdev->dev);
+	msm_gpu_hw_init(gpu);
+	show_priv->state = gpu->funcs->gpu_state_get(gpu);
+	pm_runtime_put_sync(&gpu->pdev->dev);
+
+	mutex_unlock(&gpu->lock);
+
+	if (IS_ERR(show_priv->state)) {
+		ret = PTR_ERR(show_priv->state);
+		goto free_priv;
+	}
+
+	show_priv->dev = dev;
+
+	ret = single_open(file, msm_gpu_show, show_priv);
+	if (ret)
+		goto free_priv;
+
+	return 0;
+
+free_priv:
+	kfree(show_priv);
+	return ret;
+}
+
+static const struct file_operations msm_gpu_fops = {
+	.owner = THIS_MODULE,
+	.open = msm_gpu_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = msm_gpu_release,
+};
+
+/*
+ * Display Snapshot:
+ */
+
+static int msm_kms_show(struct seq_file *m, void *arg)
+{
+	struct drm_printer p = drm_seq_file_printer(m);
+	struct msm_disp_state *state = m->private;
+
+	msm_disp_state_print(state, &p);
+
+	return 0;
+}
+
+static int msm_kms_release(struct inode *inode, struct file *file)
+{
+	struct seq_file *m = file->private_data;
+	struct msm_disp_state *state = m->private;
+
+	msm_disp_state_free(state);
+
+	return single_release(inode, file);
+}
+
+static int msm_kms_open(struct inode *inode, struct file *file)
+{
+	struct drm_device *dev = inode->i_private;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_disp_state *state;
+	int ret;
+
+	if (!priv->kms)
+		return -ENODEV;
+
+	ret = mutex_lock_interruptible(&priv->kms->dump_mutex);
+	if (ret)
+		return ret;
+
+	state = msm_disp_snapshot_state_sync(priv->kms);
+
+	mutex_unlock(&priv->kms->dump_mutex);
+
+	if (IS_ERR(state)) {
+		return PTR_ERR(state);
+	}
+
+	ret = single_open(file, msm_kms_show, state);
+	if (ret) {
+		msm_disp_state_free(state);
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct file_operations msm_kms_fops = {
+	.owner = THIS_MODULE,
+	.open = msm_kms_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = msm_kms_release,
+};
+
+/*
+ * Other debugfs:
+ */
+
+static unsigned long last_shrink_freed;
+
+static int
+shrink_get(void *data, u64 *val)
+{
+	*val = last_shrink_freed;
+
+	return 0;
+}
+
+static int
+shrink_set(void *data, u64 val)
+{
+	struct drm_device *dev = data;
+
+	last_shrink_freed = msm_gem_shrinker_shrink(dev, val);
+
+	return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(shrink_fops,
+			 shrink_get, shrink_set,
+			 "0x%08llx\n");
+
+
+static int msm_gem_show(struct seq_file *m, void *arg)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	int ret;
+
+	ret = mutex_lock_interruptible(&priv->obj_lock);
+	if (ret)
+		return ret;
+
+	msm_gem_describe_objects(&priv->objects, m);
+
+	mutex_unlock(&priv->obj_lock);
+
+	return 0;
+}
+
+static int msm_mm_show(struct seq_file *m, void *arg)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_printer p = drm_seq_file_printer(m);
+
+	drm_mm_print(&dev->vma_offset_manager->vm_addr_space_mm, &p);
+
+	return 0;
+}
+
+static int msm_fb_show(struct seq_file *m, void *arg)
+{
+	struct drm_info_node *node = m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_framebuffer *fb, *fbdev_fb = NULL;
+
+	if (dev->fb_helper && dev->fb_helper->fb) {
+		seq_printf(m, "fbcon ");
+		fbdev_fb = dev->fb_helper->fb;
+		msm_framebuffer_describe(fbdev_fb, m);
+	}
+
+	mutex_lock(&dev->mode_config.fb_lock);
+	list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
+		if (fb == fbdev_fb)
+			continue;
+
+		seq_printf(m, "user ");
+		msm_framebuffer_describe(fb, m);
+	}
+	mutex_unlock(&dev->mode_config.fb_lock);
+
+	return 0;
+}
+
+static struct drm_info_list msm_debugfs_list[] = {
+		{"gem", msm_gem_show},
+		{ "mm", msm_mm_show },
+};
+
+static struct drm_info_list msm_kms_debugfs_list[] = {
+		{ "fb", msm_fb_show },
+};
+
+static int late_init_minor(struct drm_minor *minor)
+{
+	int ret;
+
+	if (!minor)
+		return 0;
+
+	ret = msm_rd_debugfs_init(minor);
+	if (ret) {
+		DRM_DEV_ERROR(minor->dev->dev, "could not install rd debugfs\n");
+		return ret;
+	}
+
+	ret = msm_perf_debugfs_init(minor);
+	if (ret) {
+		DRM_DEV_ERROR(minor->dev->dev, "could not install perf debugfs\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+int msm_debugfs_late_init(struct drm_device *dev)
+{
+	int ret;
+	ret = late_init_minor(dev->primary);
+	if (ret)
+		return ret;
+	ret = late_init_minor(dev->render);
+	return ret;
+}
+
+static void msm_debugfs_gpu_init(struct drm_minor *minor)
+{
+	struct drm_device *dev = minor->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct dentry *gpu_devfreq;
+
+	debugfs_create_file("gpu", S_IRUSR, minor->debugfs_root,
+		dev, &msm_gpu_fops);
+
+	debugfs_create_u32("hangcheck_period_ms", 0600, minor->debugfs_root,
+		&priv->hangcheck_period);
+
+	debugfs_create_bool("disable_err_irq", 0600, minor->debugfs_root,
+		&priv->disable_err_irq);
+
+	gpu_devfreq = debugfs_create_dir("devfreq", minor->debugfs_root);
+
+	debugfs_create_bool("idle_clamp",0600, gpu_devfreq,
+			    &priv->gpu_clamp_to_idle);
+
+	debugfs_create_u32("upthreshold",0600, gpu_devfreq,
+			   &priv->gpu_devfreq_config.upthreshold);
+
+	debugfs_create_u32("downdifferential",0600, gpu_devfreq,
+			   &priv->gpu_devfreq_config.downdifferential);
+}
+
+void msm_debugfs_init(struct drm_minor *minor)
+{
+	struct drm_device *dev = minor->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+
+	drm_debugfs_create_files(msm_debugfs_list,
+				 ARRAY_SIZE(msm_debugfs_list),
+				 minor->debugfs_root, minor);
+
+	if (priv->gpu_pdev)
+		msm_debugfs_gpu_init(minor);
+
+	if (priv->kms) {
+		drm_debugfs_create_files(msm_kms_debugfs_list,
+					 ARRAY_SIZE(msm_kms_debugfs_list),
+					 minor->debugfs_root, minor);
+		debugfs_create_file("kms", S_IRUSR, minor->debugfs_root,
+				    dev, &msm_kms_fops);
+	}
+
+	debugfs_create_file("shrink", S_IRWXU, minor->debugfs_root,
+		dev, &shrink_fops);
+
+	if (priv->kms && priv->kms->funcs->debugfs_init)
+		priv->kms->funcs->debugfs_init(priv->kms, minor);
+
+#ifdef CONFIG_FAULT_INJECTION
+	fault_create_debugfs_attr("fail_gem_alloc", minor->debugfs_root,
+				  &fail_gem_alloc);
+	fault_create_debugfs_attr("fail_gem_iova", minor->debugfs_root,
+				  &fail_gem_iova);
+#endif
+}
+#endif
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_debugfs.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_debugfs.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2016 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __MSM_DEBUGFS_H__
+#define __MSM_DEBUGFS_H__
+
+#ifdef CONFIG_DEBUG_FS
+void msm_debugfs_init(struct drm_minor *minor);
+#endif
+
+#endif /* __MSM_DEBUGFS_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_drv.c
@@ -0,0 +1,1118 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2016-2018, 2020-2021 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/fault-inject.h>
+#include <linux/of_address.h>
+#include <linux/uaccess.h>
+
+#include <drm/drm_drv.h>
+#include <drm/drm_file.h>
+#include <drm/drm_ioctl.h>
+#include <drm/drm_of.h>
+
+#include "msm_drv.h"
+#include "msm_debugfs.h"
+#include "msm_gem.h"
+#include "msm_gpu.h"
+#include "msm_kms.h"
+
+/*
+ * MSM driver version:
+ * - 1.0.0 - initial interface
+ * - 1.1.0 - adds madvise, and support for submits with > 4 cmd buffers
+ * - 1.2.0 - adds explicit fence support for submit ioctl
+ * - 1.3.0 - adds GMEM_BASE + NR_RINGS params, SUBMITQUEUE_NEW +
+ *           SUBMITQUEUE_CLOSE ioctls, and MSM_INFO_IOVA flag for
+ *           MSM_GEM_INFO ioctl.
+ * - 1.4.0 - softpin, MSM_RELOC_BO_DUMP, and GEM_INFO support to set/get
+ *           GEM object's debug name
+ * - 1.5.0 - Add SUBMITQUERY_QUERY ioctl
+ * - 1.6.0 - Syncobj support
+ * - 1.7.0 - Add MSM_PARAM_SUSPENDS to access suspend count
+ * - 1.8.0 - Add MSM_BO_CACHED_COHERENT for supported GPUs (a6xx)
+ * - 1.9.0 - Add MSM_SUBMIT_FENCE_SN_IN
+ * - 1.10.0 - Add MSM_SUBMIT_BO_NO_IMPLICIT
+ * - 1.11.0 - Add wait boost (MSM_WAIT_FENCE_BOOST, MSM_PREP_BOOST)
+ * - 1.12.0 - Add MSM_INFO_SET_METADATA and MSM_INFO_GET_METADATA
+ */
+#define MSM_VERSION_MAJOR	1
+#define MSM_VERSION_MINOR	12
+#define MSM_VERSION_PATCHLEVEL	0
+
+static void msm_deinit_vram(struct drm_device *ddev);
+
+static char *vram = "16m";
+MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU)");
+module_param(vram, charp, 0);
+
+bool dumpstate;
+MODULE_PARM_DESC(dumpstate, "Dump KMS state on errors");
+module_param(dumpstate, bool, 0600);
+
+static bool modeset = true;
+MODULE_PARM_DESC(modeset, "Use kernel modesetting [KMS] (1=on (default), 0=disable)");
+module_param(modeset, bool, 0600);
+
+#ifdef CONFIG_FAULT_INJECTION
+DECLARE_FAULT_ATTR(fail_gem_alloc);
+DECLARE_FAULT_ATTR(fail_gem_iova);
+#endif
+
+static int msm_drm_uninit(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct msm_drm_private *priv = platform_get_drvdata(pdev);
+	struct drm_device *ddev = priv->dev;
+
+	/*
+	 * Shutdown the hw if we're far enough along where things might be on.
+	 * If we run this too early, we'll end up panicking in any variety of
+	 * places. Since we don't register the drm device until late in
+	 * msm_drm_init, drm_dev->registered is used as an indicator that the
+	 * shutdown will be successful.
+	 */
+	if (ddev->registered) {
+		drm_dev_unregister(ddev);
+		if (priv->kms)
+			drm_atomic_helper_shutdown(ddev);
+	}
+
+	/* We must cancel and cleanup any pending vblank enable/disable
+	 * work before msm_irq_uninstall() to avoid work re-enabling an
+	 * irq after uninstall has disabled it.
+	 */
+
+	flush_workqueue(priv->wq);
+
+	msm_gem_shrinker_cleanup(ddev);
+
+	msm_perf_debugfs_cleanup(priv);
+	msm_rd_debugfs_cleanup(priv);
+
+	if (priv->kms)
+		msm_drm_kms_uninit(dev);
+
+	msm_deinit_vram(ddev);
+
+	component_unbind_all(dev, ddev);
+
+	ddev->dev_private = NULL;
+	drm_dev_put(ddev);
+
+	destroy_workqueue(priv->wq);
+
+	return 0;
+}
+
+bool msm_use_mmu(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+
+	/*
+	 * a2xx comes with its own MMU
+	 * On other platforms IOMMU can be declared specified either for the
+	 * MDP/DPU device or for its parent, MDSS device.
+	 */
+	return priv->is_a2xx ||
+		device_iommu_mapped(dev->dev) ||
+		device_iommu_mapped(dev->dev->parent);
+}
+
+static int msm_init_vram(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct device_node *node;
+	unsigned long size = 0;
+	int ret = 0;
+
+	/* In the device-tree world, we could have a 'memory-region'
+	 * phandle, which gives us a link to our "vram".  Allocating
+	 * is all nicely abstracted behind the dma api, but we need
+	 * to know the entire size to allocate it all in one go. There
+	 * are two cases:
+	 *  1) device with no IOMMU, in which case we need exclusive
+	 *     access to a VRAM carveout big enough for all gpu
+	 *     buffers
+	 *  2) device with IOMMU, but where the bootloader puts up
+	 *     a splash screen.  In this case, the VRAM carveout
+	 *     need only be large enough for fbdev fb.  But we need
+	 *     exclusive access to the buffer to avoid the kernel
+	 *     using those pages for other purposes (which appears
+	 *     as corruption on screen before we have a chance to
+	 *     load and do initial modeset)
+	 */
+
+	node = of_parse_phandle(dev->dev->of_node, "memory-region", 0);
+	if (node) {
+		struct resource r;
+		ret = of_address_to_resource(node, 0, &r);
+		of_node_put(node);
+		if (ret)
+			return ret;
+		size = r.end - r.start + 1;
+		DRM_INFO("using VRAM carveout: %lx@%pa\n", size, &r.start);
+
+		/* if we have no IOMMU, then we need to use carveout allocator.
+		 * Grab the entire DMA chunk carved out in early startup in
+		 * mach-msm:
+		 */
+	} else if (!msm_use_mmu(dev)) {
+		DRM_INFO("using %s VRAM carveout\n", vram);
+		size = memparse(vram, NULL);
+	}
+
+	if (size) {
+		unsigned long attrs = 0;
+		void *p;
+
+		priv->vram.size = size;
+
+		drm_mm_init(&priv->vram.mm, 0, (size >> PAGE_SHIFT) - 1);
+		spin_lock_init(&priv->vram.lock);
+
+		attrs |= DMA_ATTR_NO_KERNEL_MAPPING;
+		attrs |= DMA_ATTR_WRITE_COMBINE;
+
+		/* note that for no-kernel-mapping, the vaddr returned
+		 * is bogus, but non-null if allocation succeeded:
+		 */
+		p = dma_alloc_attrs(dev->dev, size,
+				&priv->vram.paddr, GFP_KERNEL, attrs);
+		if (!p) {
+			DRM_DEV_ERROR(dev->dev, "failed to allocate VRAM\n");
+			priv->vram.paddr = 0;
+			return -ENOMEM;
+		}
+
+		DRM_DEV_INFO(dev->dev, "VRAM: %08x->%08x\n",
+				(uint32_t)priv->vram.paddr,
+				(uint32_t)(priv->vram.paddr + size));
+	}
+
+	return ret;
+}
+
+static void msm_deinit_vram(struct drm_device *ddev)
+{
+	struct msm_drm_private *priv = ddev->dev_private;
+	unsigned long attrs = DMA_ATTR_NO_KERNEL_MAPPING;
+
+	if (!priv->vram.paddr)
+		return;
+
+	drm_mm_takedown(&priv->vram.mm);
+	dma_free_attrs(ddev->dev, priv->vram.size, NULL, priv->vram.paddr,
+			attrs);
+}
+
+static int msm_drm_init(struct device *dev, const struct drm_driver *drv)
+{
+	struct msm_drm_private *priv = dev_get_drvdata(dev);
+	struct drm_device *ddev;
+	int ret;
+
+	if (drm_firmware_drivers_only())
+		return -ENODEV;
+
+	ddev = drm_dev_alloc(drv, dev);
+	if (IS_ERR(ddev)) {
+		DRM_DEV_ERROR(dev, "failed to allocate drm_device\n");
+		return PTR_ERR(ddev);
+	}
+	ddev->dev_private = priv;
+	priv->dev = ddev;
+
+	priv->wq = alloc_ordered_workqueue("msm", 0);
+	if (!priv->wq) {
+		ret = -ENOMEM;
+		goto err_put_dev;
+	}
+
+	INIT_LIST_HEAD(&priv->objects);
+	mutex_init(&priv->obj_lock);
+
+	/*
+	 * Initialize the LRUs:
+	 */
+	mutex_init(&priv->lru.lock);
+	drm_gem_lru_init(&priv->lru.unbacked, &priv->lru.lock);
+	drm_gem_lru_init(&priv->lru.pinned,   &priv->lru.lock);
+	drm_gem_lru_init(&priv->lru.willneed, &priv->lru.lock);
+	drm_gem_lru_init(&priv->lru.dontneed, &priv->lru.lock);
+
+	/* Teach lockdep about lock ordering wrt. shrinker: */
+	fs_reclaim_acquire(GFP_KERNEL);
+	might_lock(&priv->lru.lock);
+	fs_reclaim_release(GFP_KERNEL);
+
+	if (priv->kms_init) {
+		ret = drmm_mode_config_init(ddev);
+		if (ret)
+			goto err_destroy_wq;
+	}
+
+	ret = msm_init_vram(ddev);
+	if (ret)
+		goto err_destroy_wq;
+
+	dma_set_max_seg_size(dev, UINT_MAX);
+
+	/* Bind all our sub-components: */
+	ret = component_bind_all(dev, ddev);
+	if (ret)
+		goto err_deinit_vram;
+
+	ret = msm_gem_shrinker_init(ddev);
+	if (ret)
+		goto err_msm_uninit;
+
+	if (priv->kms_init) {
+		ret = msm_drm_kms_init(dev, drv);
+		if (ret)
+			goto err_msm_uninit;
+	} else {
+		/* valid only for the dummy headless case, where of_node=NULL */
+		WARN_ON(dev->of_node);
+		ddev->driver_features &= ~DRIVER_MODESET;
+		ddev->driver_features &= ~DRIVER_ATOMIC;
+	}
+
+	ret = drm_dev_register(ddev, 0);
+	if (ret)
+		goto err_msm_uninit;
+
+	ret = msm_debugfs_late_init(ddev);
+	if (ret)
+		goto err_msm_uninit;
+
+	if (priv->kms_init) {
+		drm_kms_helper_poll_init(ddev);
+		msm_fbdev_setup(ddev);
+	}
+
+	return 0;
+
+err_msm_uninit:
+	msm_drm_uninit(dev);
+
+	return ret;
+
+err_deinit_vram:
+	msm_deinit_vram(ddev);
+err_destroy_wq:
+	destroy_workqueue(priv->wq);
+err_put_dev:
+	drm_dev_put(ddev);
+
+	return ret;
+}
+
+/*
+ * DRM operations:
+ */
+
+static void load_gpu(struct drm_device *dev)
+{
+	static DEFINE_MUTEX(init_lock);
+	struct msm_drm_private *priv = dev->dev_private;
+
+	mutex_lock(&init_lock);
+
+	if (!priv->gpu)
+		priv->gpu = adreno_load_gpu(dev);
+
+	mutex_unlock(&init_lock);
+}
+
+static int context_init(struct drm_device *dev, struct drm_file *file)
+{
+	static atomic_t ident = ATOMIC_INIT(0);
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_file_private *ctx;
+
+	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&ctx->submitqueues);
+	rwlock_init(&ctx->queuelock);
+
+	kref_init(&ctx->ref);
+	msm_submitqueue_init(dev, ctx);
+
+	ctx->aspace = msm_gpu_create_private_address_space(priv->gpu, current);
+	file->driver_priv = ctx;
+
+	ctx->seqno = atomic_inc_return(&ident);
+
+	return 0;
+}
+
+static int msm_open(struct drm_device *dev, struct drm_file *file)
+{
+	/* For now, load gpu on open.. to avoid the requirement of having
+	 * firmware in the initrd.
+	 */
+	load_gpu(dev);
+
+	return context_init(dev, file);
+}
+
+static void context_close(struct msm_file_private *ctx)
+{
+	msm_submitqueue_close(ctx);
+	msm_file_private_put(ctx);
+}
+
+static void msm_postclose(struct drm_device *dev, struct drm_file *file)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_file_private *ctx = file->driver_priv;
+
+	/*
+	 * It is not possible to set sysprof param to non-zero if gpu
+	 * is not initialized:
+	 */
+	if (priv->gpu)
+		msm_file_private_set_sysprof(ctx, priv->gpu, 0);
+
+	context_close(ctx);
+}
+
+/*
+ * DRM ioctls:
+ */
+
+static int msm_ioctl_get_param(struct drm_device *dev, void *data,
+		struct drm_file *file)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct drm_msm_param *args = data;
+	struct msm_gpu *gpu;
+
+	/* for now, we just have 3d pipe.. eventually this would need to
+	 * be more clever to dispatch to appropriate gpu module:
+	 */
+	if ((args->pipe != MSM_PIPE_3D0) || (args->pad != 0))
+		return -EINVAL;
+
+	gpu = priv->gpu;
+
+	if (!gpu)
+		return -ENXIO;
+
+	return gpu->funcs->get_param(gpu, file->driver_priv,
+				     args->param, &args->value, &args->len);
+}
+
+static int msm_ioctl_set_param(struct drm_device *dev, void *data,
+		struct drm_file *file)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct drm_msm_param *args = data;
+	struct msm_gpu *gpu;
+
+	if ((args->pipe != MSM_PIPE_3D0) || (args->pad != 0))
+		return -EINVAL;
+
+	gpu = priv->gpu;
+
+	if (!gpu)
+		return -ENXIO;
+
+	return gpu->funcs->set_param(gpu, file->driver_priv,
+				     args->param, args->value, args->len);
+}
+
+static int msm_ioctl_gem_new(struct drm_device *dev, void *data,
+		struct drm_file *file)
+{
+	struct drm_msm_gem_new *args = data;
+	uint32_t flags = args->flags;
+
+	if (args->flags & ~MSM_BO_FLAGS) {
+		DRM_ERROR("invalid flags: %08x\n", args->flags);
+		return -EINVAL;
+	}
+
+	/*
+	 * Uncached CPU mappings are deprecated, as of:
+	 *
+	 * 9ef364432db4 ("drm/msm: deprecate MSM_BO_UNCACHED (map as writecombine instead)")
+	 *
+	 * So promote them to WC.
+	 */
+	if (flags & MSM_BO_UNCACHED) {
+		flags &= ~MSM_BO_CACHED;
+		flags |= MSM_BO_WC;
+	}
+
+	if (should_fail(&fail_gem_alloc, args->size))
+		return -ENOMEM;
+
+	return msm_gem_new_handle(dev, file, args->size,
+			args->flags, &args->handle, NULL);
+}
+
+static inline ktime_t to_ktime(struct drm_msm_timespec timeout)
+{
+	return ktime_set(timeout.tv_sec, timeout.tv_nsec);
+}
+
+static int msm_ioctl_gem_cpu_prep(struct drm_device *dev, void *data,
+		struct drm_file *file)
+{
+	struct drm_msm_gem_cpu_prep *args = data;
+	struct drm_gem_object *obj;
+	ktime_t timeout = to_ktime(args->timeout);
+	int ret;
+
+	if (args->op & ~MSM_PREP_FLAGS) {
+		DRM_ERROR("invalid op: %08x\n", args->op);
+		return -EINVAL;
+	}
+
+	obj = drm_gem_object_lookup(file, args->handle);
+	if (!obj)
+		return -ENOENT;
+
+	ret = msm_gem_cpu_prep(obj, args->op, &timeout);
+
+	drm_gem_object_put(obj);
+
+	return ret;
+}
+
+static int msm_ioctl_gem_cpu_fini(struct drm_device *dev, void *data,
+		struct drm_file *file)
+{
+	struct drm_msm_gem_cpu_fini *args = data;
+	struct drm_gem_object *obj;
+	int ret;
+
+	obj = drm_gem_object_lookup(file, args->handle);
+	if (!obj)
+		return -ENOENT;
+
+	ret = msm_gem_cpu_fini(obj);
+
+	drm_gem_object_put(obj);
+
+	return ret;
+}
+
+static int msm_ioctl_gem_info_iova(struct drm_device *dev,
+		struct drm_file *file, struct drm_gem_object *obj,
+		uint64_t *iova)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_file_private *ctx = file->driver_priv;
+
+	if (!priv->gpu)
+		return -EINVAL;
+
+	if (should_fail(&fail_gem_iova, obj->size))
+		return -ENOMEM;
+
+	/*
+	 * Don't pin the memory here - just get an address so that userspace can
+	 * be productive
+	 */
+	return msm_gem_get_iova(obj, ctx->aspace, iova);
+}
+
+static int msm_ioctl_gem_info_set_iova(struct drm_device *dev,
+		struct drm_file *file, struct drm_gem_object *obj,
+		uint64_t iova)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_file_private *ctx = file->driver_priv;
+
+	if (!priv->gpu)
+		return -EINVAL;
+
+	/* Only supported if per-process address space is supported: */
+	if (priv->gpu->aspace == ctx->aspace)
+		return -EOPNOTSUPP;
+
+	if (should_fail(&fail_gem_iova, obj->size))
+		return -ENOMEM;
+
+	return msm_gem_set_iova(obj, ctx->aspace, iova);
+}
+
+static int msm_ioctl_gem_info_set_metadata(struct drm_gem_object *obj,
+					   __user void *metadata,
+					   u32 metadata_size)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	void *buf;
+	int ret;
+
+	/* Impose a moderate upper bound on metadata size: */
+	if (metadata_size > 128) {
+		return -EOVERFLOW;
+	}
+
+	/* Use a temporary buf to keep copy_from_user() outside of gem obj lock: */
+	buf = memdup_user(metadata, metadata_size);
+	if (IS_ERR(buf))
+		return PTR_ERR(buf);
+
+	ret = msm_gem_lock_interruptible(obj);
+	if (ret)
+		goto out;
+
+	msm_obj->metadata =
+		krealloc(msm_obj->metadata, metadata_size, GFP_KERNEL);
+	msm_obj->metadata_size = metadata_size;
+	memcpy(msm_obj->metadata, buf, metadata_size);
+
+	msm_gem_unlock(obj);
+
+out:
+	kfree(buf);
+
+	return ret;
+}
+
+static int msm_ioctl_gem_info_get_metadata(struct drm_gem_object *obj,
+					   __user void *metadata,
+					   u32 *metadata_size)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	void *buf;
+	int ret, len;
+
+	if (!metadata) {
+		/*
+		 * Querying the size is inherently racey, but
+		 * EXT_external_objects expects the app to confirm
+		 * via device and driver UUIDs that the exporter and
+		 * importer versions match.  All we can do from the
+		 * kernel side is check the length under obj lock
+		 * when userspace tries to retrieve the metadata
+		 */
+		*metadata_size = msm_obj->metadata_size;
+		return 0;
+	}
+
+	ret = msm_gem_lock_interruptible(obj);
+	if (ret)
+		return ret;
+
+	/* Avoid copy_to_user() under gem obj lock: */
+	len = msm_obj->metadata_size;
+	buf = kmemdup(msm_obj->metadata, len, GFP_KERNEL);
+
+	msm_gem_unlock(obj);
+
+	if (*metadata_size < len) {
+		ret = -ETOOSMALL;
+	} else if (copy_to_user(metadata, buf, len)) {
+		ret = -EFAULT;
+	} else {
+		*metadata_size = len;
+	}
+
+	kfree(buf);
+
+	return 0;
+}
+
+static int msm_ioctl_gem_info(struct drm_device *dev, void *data,
+		struct drm_file *file)
+{
+	struct drm_msm_gem_info *args = data;
+	struct drm_gem_object *obj;
+	struct msm_gem_object *msm_obj;
+	int i, ret = 0;
+
+	if (args->pad)
+		return -EINVAL;
+
+	switch (args->info) {
+	case MSM_INFO_GET_OFFSET:
+	case MSM_INFO_GET_IOVA:
+	case MSM_INFO_SET_IOVA:
+	case MSM_INFO_GET_FLAGS:
+		/* value returned as immediate, not pointer, so len==0: */
+		if (args->len)
+			return -EINVAL;
+		break;
+	case MSM_INFO_SET_NAME:
+	case MSM_INFO_GET_NAME:
+	case MSM_INFO_SET_METADATA:
+	case MSM_INFO_GET_METADATA:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	obj = drm_gem_object_lookup(file, args->handle);
+	if (!obj)
+		return -ENOENT;
+
+	msm_obj = to_msm_bo(obj);
+
+	switch (args->info) {
+	case MSM_INFO_GET_OFFSET:
+		args->value = msm_gem_mmap_offset(obj);
+		break;
+	case MSM_INFO_GET_IOVA:
+		ret = msm_ioctl_gem_info_iova(dev, file, obj, &args->value);
+		break;
+	case MSM_INFO_SET_IOVA:
+		ret = msm_ioctl_gem_info_set_iova(dev, file, obj, args->value);
+		break;
+	case MSM_INFO_GET_FLAGS:
+		if (obj->import_attach) {
+			ret = -EINVAL;
+			break;
+		}
+		/* Hide internal kernel-only flags: */
+		args->value = to_msm_bo(obj)->flags & MSM_BO_FLAGS;
+		ret = 0;
+		break;
+	case MSM_INFO_SET_NAME:
+		/* length check should leave room for terminating null: */
+		if (args->len >= sizeof(msm_obj->name)) {
+			ret = -EINVAL;
+			break;
+		}
+		if (copy_from_user(msm_obj->name, u64_to_user_ptr(args->value),
+				   args->len)) {
+			msm_obj->name[0] = '\0';
+			ret = -EFAULT;
+			break;
+		}
+		msm_obj->name[args->len] = '\0';
+		for (i = 0; i < args->len; i++) {
+			if (!isprint(msm_obj->name[i])) {
+				msm_obj->name[i] = '\0';
+				break;
+			}
+		}
+		break;
+	case MSM_INFO_GET_NAME:
+		if (args->value && (args->len < strlen(msm_obj->name))) {
+			ret = -ETOOSMALL;
+			break;
+		}
+		args->len = strlen(msm_obj->name);
+		if (args->value) {
+			if (copy_to_user(u64_to_user_ptr(args->value),
+					 msm_obj->name, args->len))
+				ret = -EFAULT;
+		}
+		break;
+	case MSM_INFO_SET_METADATA:
+		ret = msm_ioctl_gem_info_set_metadata(
+			obj, u64_to_user_ptr(args->value), args->len);
+		break;
+	case MSM_INFO_GET_METADATA:
+		ret = msm_ioctl_gem_info_get_metadata(
+			obj, u64_to_user_ptr(args->value), &args->len);
+		break;
+	}
+
+	drm_gem_object_put(obj);
+
+	return ret;
+}
+
+static int wait_fence(struct msm_gpu_submitqueue *queue, uint32_t fence_id,
+		      ktime_t timeout, uint32_t flags)
+{
+	struct dma_fence *fence;
+	int ret;
+
+	if (fence_after(fence_id, queue->last_fence)) {
+		DRM_ERROR_RATELIMITED("waiting on invalid fence: %u (of %u)\n",
+				      fence_id, queue->last_fence);
+		return -EINVAL;
+	}
+
+	/*
+	 * Map submitqueue scoped "seqno" (which is actually an idr key)
+	 * back to underlying dma-fence
+	 *
+	 * The fence is removed from the fence_idr when the submit is
+	 * retired, so if the fence is not found it means there is nothing
+	 * to wait for
+	 */
+	spin_lock(&queue->idr_lock);
+	fence = idr_find(&queue->fence_idr, fence_id);
+	if (fence)
+		fence = dma_fence_get_rcu(fence);
+	spin_unlock(&queue->idr_lock);
+
+	if (!fence)
+		return 0;
+
+	if (flags & MSM_WAIT_FENCE_BOOST)
+		dma_fence_set_deadline(fence, ktime_get());
+
+	ret = dma_fence_wait_timeout(fence, true, timeout_to_jiffies(&timeout));
+	if (ret == 0) {
+		ret = -ETIMEDOUT;
+	} else if (ret != -ERESTARTSYS) {
+		ret = 0;
+	}
+
+	dma_fence_put(fence);
+
+	return ret;
+}
+
+static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
+		struct drm_file *file)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct drm_msm_wait_fence *args = data;
+	struct msm_gpu_submitqueue *queue;
+	int ret;
+
+	if (args->flags & ~MSM_WAIT_FENCE_FLAGS) {
+		DRM_ERROR("invalid flags: %08x\n", args->flags);
+		return -EINVAL;
+	}
+
+	if (!priv->gpu)
+		return 0;
+
+	queue = msm_submitqueue_get(file->driver_priv, args->queueid);
+	if (!queue)
+		return -ENOENT;
+
+	ret = wait_fence(queue, args->fence, to_ktime(args->timeout), args->flags);
+
+	msm_submitqueue_put(queue);
+
+	return ret;
+}
+
+static int msm_ioctl_gem_madvise(struct drm_device *dev, void *data,
+		struct drm_file *file)
+{
+	struct drm_msm_gem_madvise *args = data;
+	struct drm_gem_object *obj;
+	int ret;
+
+	switch (args->madv) {
+	case MSM_MADV_DONTNEED:
+	case MSM_MADV_WILLNEED:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	obj = drm_gem_object_lookup(file, args->handle);
+	if (!obj) {
+		return -ENOENT;
+	}
+
+	ret = msm_gem_madvise(obj, args->madv);
+	if (ret >= 0) {
+		args->retained = ret;
+		ret = 0;
+	}
+
+	drm_gem_object_put(obj);
+
+	return ret;
+}
+
+
+static int msm_ioctl_submitqueue_new(struct drm_device *dev, void *data,
+		struct drm_file *file)
+{
+	struct drm_msm_submitqueue *args = data;
+
+	if (args->flags & ~MSM_SUBMITQUEUE_FLAGS)
+		return -EINVAL;
+
+	return msm_submitqueue_create(dev, file->driver_priv, args->prio,
+		args->flags, &args->id);
+}
+
+static int msm_ioctl_submitqueue_query(struct drm_device *dev, void *data,
+		struct drm_file *file)
+{
+	return msm_submitqueue_query(dev, file->driver_priv, data);
+}
+
+static int msm_ioctl_submitqueue_close(struct drm_device *dev, void *data,
+		struct drm_file *file)
+{
+	u32 id = *(u32 *) data;
+
+	return msm_submitqueue_remove(file->driver_priv, id);
+}
+
+static const struct drm_ioctl_desc msm_ioctls[] = {
+	DRM_IOCTL_DEF_DRV(MSM_GET_PARAM,    msm_ioctl_get_param,    DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(MSM_SET_PARAM,    msm_ioctl_set_param,    DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(MSM_GEM_NEW,      msm_ioctl_gem_new,      DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(MSM_GEM_INFO,     msm_ioctl_gem_info,     DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_PREP, msm_ioctl_gem_cpu_prep, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_FINI, msm_ioctl_gem_cpu_fini, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(MSM_GEM_SUBMIT,   msm_ioctl_gem_submit,   DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(MSM_WAIT_FENCE,   msm_ioctl_wait_fence,   DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(MSM_GEM_MADVISE,  msm_ioctl_gem_madvise,  DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_NEW,   msm_ioctl_submitqueue_new,   DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_CLOSE, msm_ioctl_submitqueue_close, DRM_RENDER_ALLOW),
+	DRM_IOCTL_DEF_DRV(MSM_SUBMITQUEUE_QUERY, msm_ioctl_submitqueue_query, DRM_RENDER_ALLOW),
+};
+
+static void msm_show_fdinfo(struct drm_printer *p, struct drm_file *file)
+{
+	struct drm_device *dev = file->minor->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+
+	if (!priv->gpu)
+		return;
+
+	msm_gpu_show_fdinfo(priv->gpu, file->driver_priv, p);
+
+	drm_show_memory_stats(p, file);
+}
+
+static const struct file_operations fops = {
+	.owner = THIS_MODULE,
+	DRM_GEM_FOPS,
+	.show_fdinfo = drm_show_fdinfo,
+};
+
+static const struct drm_driver msm_driver = {
+	.driver_features    = DRIVER_GEM |
+				DRIVER_RENDER |
+				DRIVER_ATOMIC |
+				DRIVER_MODESET |
+				DRIVER_SYNCOBJ,
+	.open               = msm_open,
+	.postclose          = msm_postclose,
+	.dumb_create        = msm_gem_dumb_create,
+	.dumb_map_offset    = msm_gem_dumb_map_offset,
+	.gem_prime_import_sg_table = msm_gem_prime_import_sg_table,
+#ifdef CONFIG_DEBUG_FS
+	.debugfs_init       = msm_debugfs_init,
+#endif
+	.show_fdinfo        = msm_show_fdinfo,
+	.ioctls             = msm_ioctls,
+	.num_ioctls         = ARRAY_SIZE(msm_ioctls),
+	.fops               = &fops,
+	.name               = "msm",
+	.desc               = "MSM Snapdragon DRM",
+	.date               = "20130625",
+	.major              = MSM_VERSION_MAJOR,
+	.minor              = MSM_VERSION_MINOR,
+	.patchlevel         = MSM_VERSION_PATCHLEVEL,
+};
+
+/*
+ * Componentized driver support:
+ */
+
+/*
+ * Identify what components need to be added by parsing what remote-endpoints
+ * our MDP output ports are connected to. In the case of LVDS on MDP4, there
+ * is no external component that we need to add since LVDS is within MDP4
+ * itself.
+ */
+static int add_components_mdp(struct device *master_dev,
+			      struct component_match **matchptr)
+{
+	struct device_node *np = master_dev->of_node;
+	struct device_node *ep_node;
+
+	for_each_endpoint_of_node(np, ep_node) {
+		struct device_node *intf;
+		struct of_endpoint ep;
+		int ret;
+
+		ret = of_graph_parse_endpoint(ep_node, &ep);
+		if (ret) {
+			DRM_DEV_ERROR(master_dev, "unable to parse port endpoint\n");
+			of_node_put(ep_node);
+			return ret;
+		}
+
+		/*
+		 * The LCDC/LVDS port on MDP4 is a speacial case where the
+		 * remote-endpoint isn't a component that we need to add
+		 */
+		if (of_device_is_compatible(np, "qcom,mdp4") &&
+		    ep.port == 0)
+			continue;
+
+		/*
+		 * It's okay if some of the ports don't have a remote endpoint
+		 * specified. It just means that the port isn't connected to
+		 * any external interface.
+		 */
+		intf = of_graph_get_remote_port_parent(ep_node);
+		if (!intf)
+			continue;
+
+		if (of_device_is_available(intf))
+			drm_of_component_match_add(master_dev, matchptr,
+						   component_compare_of, intf);
+
+		of_node_put(intf);
+	}
+
+	return 0;
+}
+
+/*
+ * We don't know what's the best binding to link the gpu with the drm device.
+ * Fow now, we just hunt for all the possible gpus that we support, and add them
+ * as components.
+ */
+static const struct of_device_id msm_gpu_match[] = {
+	{ .compatible = "qcom,adreno" },
+	{ .compatible = "qcom,adreno-3xx" },
+	{ .compatible = "amd,imageon" },
+	{ .compatible = "qcom,kgsl-3d0" },
+	{ },
+};
+
+static int add_gpu_components(struct device *dev,
+			      struct component_match **matchptr)
+{
+	struct device_node *np;
+
+	np = of_find_matching_node(NULL, msm_gpu_match);
+	if (!np)
+		return 0;
+
+	if (of_device_is_available(np))
+		drm_of_component_match_add(dev, matchptr, component_compare_of, np);
+
+	of_node_put(np);
+
+	return 0;
+}
+
+static int msm_drm_bind(struct device *dev)
+{
+	return msm_drm_init(dev, &msm_driver);
+}
+
+static void msm_drm_unbind(struct device *dev)
+{
+	msm_drm_uninit(dev);
+}
+
+const struct component_master_ops msm_drm_ops = {
+	.bind = msm_drm_bind,
+	.unbind = msm_drm_unbind,
+};
+
+int msm_drv_probe(struct device *master_dev,
+	int (*kms_init)(struct drm_device *dev),
+	struct msm_kms *kms)
+{
+	struct msm_drm_private *priv;
+	struct component_match *match = NULL;
+	int ret;
+
+	priv = devm_kzalloc(master_dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->kms = kms;
+	priv->kms_init = kms_init;
+	dev_set_drvdata(master_dev, priv);
+
+	/* Add mdp components if we have KMS. */
+	if (kms_init) {
+		ret = add_components_mdp(master_dev, &match);
+		if (ret)
+			return ret;
+	}
+
+	ret = add_gpu_components(master_dev, &match);
+	if (ret)
+		return ret;
+
+	/* on all devices that I am aware of, iommu's which can map
+	 * any address the cpu can see are used:
+	 */
+	ret = dma_set_mask_and_coherent(master_dev, ~0);
+	if (ret)
+		return ret;
+
+	ret = component_master_add_with_match(master_dev, &msm_drm_ops, match);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+/*
+ * Platform driver:
+ * Used only for headlesss GPU instances
+ */
+
+static int msm_pdev_probe(struct platform_device *pdev)
+{
+	return msm_drv_probe(&pdev->dev, NULL, NULL);
+}
+
+static void msm_pdev_remove(struct platform_device *pdev)
+{
+	component_master_del(&pdev->dev, &msm_drm_ops);
+}
+
+static struct platform_driver msm_platform_driver = {
+	.probe      = msm_pdev_probe,
+	.remove_new = msm_pdev_remove,
+	.driver     = {
+		.name   = "msm",
+	},
+};
+
+static int __init msm_drm_register(void)
+{
+	if (!modeset)
+		return -EINVAL;
+
+	DBG("init");
+	msm_mdp_register();
+	msm_dpu_register();
+	msm_dsi_register();
+	msm_hdmi_register();
+	msm_dp_register();
+	adreno_register();
+	msm_mdp4_register();
+	msm_mdss_register();
+	return platform_driver_register(&msm_platform_driver);
+}
+
+static void __exit msm_drm_unregister(void)
+{
+	DBG("fini");
+	platform_driver_unregister(&msm_platform_driver);
+	msm_mdss_unregister();
+	msm_mdp4_unregister();
+	msm_dp_unregister();
+	msm_hdmi_unregister();
+	adreno_unregister();
+	msm_dsi_unregister();
+	msm_mdp_unregister();
+	msm_dpu_unregister();
+}
+
+module_init(msm_drm_register);
+module_exit(msm_drm_unregister);
+
+MODULE_AUTHOR("Rob Clark <robdclark@gmail.com");
+MODULE_DESCRIPTION("MSM DRM Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_drv.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_drv.h
@@ -0,0 +1,599 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __MSM_DRV_H__
+#define __MSM_DRV_H__
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/devfreq.h>
+#include <linux/module.h>
+#include <linux/component.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/iommu.h>
+#include <linux/types.h>
+#include <linux/of_graph.h>
+#include <linux/of_device.h>
+#include <linux/sizes.h>
+#include <linux/kthread.h>
+
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/display/drm_dsc.h>
+#include <drm/display/drm_dp_mst_helper.h>
+#include <drm/msm_drm.h>
+#include <drm/drm_gem.h>
+
+#ifdef CONFIG_FAULT_INJECTION
+extern struct fault_attr fail_gem_alloc;
+extern struct fault_attr fail_gem_iova;
+#else
+#  define should_fail(attr, size) 0
+#endif
+
+struct msm_kms;
+struct msm_gpu;
+struct msm_mmu;
+struct msm_mdss;
+struct msm_rd_state;
+struct msm_perf_state;
+struct msm_gem_submit;
+struct msm_fence_context;
+struct msm_gem_address_space;
+struct msm_gem_vma;
+struct msm_disp_state;
+
+#define MAX_CRTCS      8
+#define MAX_BRIDGES    8
+
+#define FRAC_16_16(mult, div)    (((mult) << 16) / (div))
+
+enum msm_dp_controller {
+	MSM_DP_CONTROLLER_0,
+	MSM_DP_CONTROLLER_1,
+	MSM_DP_CONTROLLER_2,
+	MSM_DP_CONTROLLER_3,
+	MSM_DP_CONTROLLER_COUNT,
+};
+
+enum msm_dsi_controller {
+	MSM_DSI_CONTROLLER_0,
+	MSM_DSI_CONTROLLER_1,
+	MSM_DSI_CONTROLLER_COUNT,
+};
+
+#define MSM_GPU_MAX_RINGS 4
+#define MAX_H_TILES_PER_DISPLAY 2
+
+/**
+ * struct msm_display_topology - defines a display topology pipeline
+ * @num_lm:       number of layer mixers used
+ * @num_intf:     number of interfaces the panel is mounted on
+ * @num_dspp:     number of dspp blocks used
+ * @num_dsc:      number of Display Stream Compression (DSC) blocks used
+ * @needs_cdm:    indicates whether cdm block is needed for this display topology
+ */
+struct msm_display_topology {
+	u32 num_lm;
+	u32 num_intf;
+	u32 num_dspp;
+	u32 num_dsc;
+	bool needs_cdm;
+};
+
+/* Commit/Event thread specific structure */
+struct msm_drm_thread {
+	struct drm_device *dev;
+	struct kthread_worker *worker;
+};
+
+struct msm_drm_private {
+
+	struct drm_device *dev;
+
+	struct msm_kms *kms;
+	int (*kms_init)(struct drm_device *dev);
+
+	/* subordinate devices, if present: */
+	struct platform_device *gpu_pdev;
+
+	/* possibly this should be in the kms component, but it is
+	 * shared by both mdp4 and mdp5..
+	 */
+	struct hdmi *hdmi;
+
+	/* DSI is shared by mdp4 and mdp5 */
+	struct msm_dsi *dsi[MSM_DSI_CONTROLLER_COUNT];
+
+	struct msm_dp *dp[MSM_DP_CONTROLLER_COUNT];
+
+	/* when we have more than one 'msm_gpu' these need to be an array: */
+	struct msm_gpu *gpu;
+
+	/* gpu is only set on open(), but we need this info earlier */
+	bool is_a2xx;
+	bool has_cached_coherent;
+
+	struct msm_rd_state *rd;       /* debugfs to dump all submits */
+	struct msm_rd_state *hangrd;   /* debugfs to dump hanging submits */
+	struct msm_perf_state *perf;
+
+	/**
+	 * List of all GEM objects (mainly for debugfs, protected by obj_lock
+	 * (acquire before per GEM object lock)
+	 */
+	struct list_head objects;
+	struct mutex obj_lock;
+
+	/**
+	 * lru:
+	 *
+	 * The various LRU's that a GEM object is in at various stages of
+	 * it's lifetime.  Objects start out in the unbacked LRU.  When
+	 * pinned (for scannout or permanently mapped GPU buffers, like
+	 * ringbuffer, memptr, fw, etc) it moves to the pinned LRU.  When
+	 * unpinned, it moves into willneed or dontneed LRU depending on
+	 * madvise state.  When backing pages are evicted (willneed) or
+	 * purged (dontneed) it moves back into the unbacked LRU.
+	 *
+	 * The dontneed LRU is considered by the shrinker for objects
+	 * that are candidate for purging, and the willneed LRU is
+	 * considered for objects that could be evicted.
+	 */
+	struct {
+		/**
+		 * unbacked:
+		 *
+		 * The LRU for GEM objects without backing pages allocated.
+		 * This mostly exists so that objects are always is one
+		 * LRU.
+		 */
+		struct drm_gem_lru unbacked;
+
+		/**
+		 * pinned:
+		 *
+		 * The LRU for pinned GEM objects
+		 */
+		struct drm_gem_lru pinned;
+
+		/**
+		 * willneed:
+		 *
+		 * The LRU for unpinned GEM objects which are in madvise
+		 * WILLNEED state (ie. can be evicted)
+		 */
+		struct drm_gem_lru willneed;
+
+		/**
+		 * dontneed:
+		 *
+		 * The LRU for unpinned GEM objects which are in madvise
+		 * DONTNEED state (ie. can be purged)
+		 */
+		struct drm_gem_lru dontneed;
+
+		/**
+		 * lock:
+		 *
+		 * Protects manipulation of all of the LRUs.
+		 */
+		struct mutex lock;
+	} lru;
+
+	struct workqueue_struct *wq;
+
+	unsigned int num_crtcs;
+
+	struct msm_drm_thread event_thread[MAX_CRTCS];
+
+	/* VRAM carveout, used when no IOMMU: */
+	struct {
+		unsigned long size;
+		dma_addr_t paddr;
+		/* NOTE: mm managed at the page level, size is in # of pages
+		 * and position mm_node->start is in # of pages:
+		 */
+		struct drm_mm mm;
+		spinlock_t lock; /* Protects drm_mm node allocation/removal */
+	} vram;
+
+	struct notifier_block vmap_notifier;
+	struct shrinker *shrinker;
+
+	struct drm_atomic_state *pm_state;
+
+	/**
+	 * hangcheck_period: For hang detection, in ms
+	 *
+	 * Note that in practice, a submit/job will get at least two hangcheck
+	 * periods, due to checking for progress being implemented as simply
+	 * "have the CP position registers changed since last time?"
+	 */
+	unsigned int hangcheck_period;
+
+	/** gpu_devfreq_config: Devfreq tuning config for the GPU. */
+	struct devfreq_simple_ondemand_data gpu_devfreq_config;
+
+	/**
+	 * gpu_clamp_to_idle: Enable clamping to idle freq when inactive
+	 */
+	bool gpu_clamp_to_idle;
+
+	/**
+	 * disable_err_irq:
+	 *
+	 * Disable handling of GPU hw error interrupts, to force fallback to
+	 * sw hangcheck timer.  Written (via debugfs) by igt tests to test
+	 * the sw hangcheck mechanism.
+	 */
+	bool disable_err_irq;
+};
+
+struct msm_format {
+	uint32_t pixel_format;
+};
+
+struct msm_pending_timer;
+
+int msm_atomic_init_pending_timer(struct msm_pending_timer *timer,
+		struct msm_kms *kms, int crtc_idx);
+void msm_atomic_destroy_pending_timer(struct msm_pending_timer *timer);
+void msm_atomic_commit_tail(struct drm_atomic_state *state);
+int msm_atomic_check(struct drm_device *dev, struct drm_atomic_state *state);
+struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev);
+void msm_atomic_state_clear(struct drm_atomic_state *state);
+void msm_atomic_state_free(struct drm_atomic_state *state);
+
+int msm_crtc_enable_vblank(struct drm_crtc *crtc);
+void msm_crtc_disable_vblank(struct drm_crtc *crtc);
+
+int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu);
+void msm_unregister_mmu(struct drm_device *dev, struct msm_mmu *mmu);
+
+struct msm_gem_address_space *msm_kms_init_aspace(struct drm_device *dev);
+bool msm_use_mmu(struct drm_device *dev);
+
+int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+		struct drm_file *file);
+
+#ifdef CONFIG_DEBUG_FS
+unsigned long msm_gem_shrinker_shrink(struct drm_device *dev, unsigned long nr_to_scan);
+#endif
+
+int msm_gem_shrinker_init(struct drm_device *dev);
+void msm_gem_shrinker_cleanup(struct drm_device *dev);
+
+struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj);
+int msm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map);
+void msm_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map);
+struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
+		struct dma_buf_attachment *attach, struct sg_table *sg);
+int msm_gem_prime_pin(struct drm_gem_object *obj);
+void msm_gem_prime_unpin(struct drm_gem_object *obj);
+
+int msm_framebuffer_prepare(struct drm_framebuffer *fb,
+		struct msm_gem_address_space *aspace, bool needs_dirtyfb);
+void msm_framebuffer_cleanup(struct drm_framebuffer *fb,
+		struct msm_gem_address_space *aspace, bool needed_dirtyfb);
+uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb,
+		struct msm_gem_address_space *aspace, int plane);
+struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane);
+const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb);
+struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
+		struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd);
+struct drm_framebuffer * msm_alloc_stolen_fb(struct drm_device *dev,
+		int w, int h, int p, uint32_t format);
+
+#ifdef CONFIG_DRM_FBDEV_EMULATION
+void msm_fbdev_setup(struct drm_device *dev);
+#else
+static inline void msm_fbdev_setup(struct drm_device *dev)
+{
+}
+#endif
+
+struct hdmi;
+#ifdef CONFIG_DRM_MSM_HDMI
+int msm_hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev,
+		struct drm_encoder *encoder);
+void __init msm_hdmi_register(void);
+void __exit msm_hdmi_unregister(void);
+#else
+static inline int msm_hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev,
+		struct drm_encoder *encoder)
+{
+	return -EINVAL;
+}
+static inline void __init msm_hdmi_register(void) {}
+static inline void __exit msm_hdmi_unregister(void) {}
+#endif
+
+struct msm_dsi;
+#ifdef CONFIG_DRM_MSM_DSI
+int dsi_dev_attach(struct platform_device *pdev);
+void dsi_dev_detach(struct platform_device *pdev);
+void __init msm_dsi_register(void);
+void __exit msm_dsi_unregister(void);
+int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
+			 struct drm_encoder *encoder);
+void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct msm_dsi *msm_dsi);
+bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi);
+bool msm_dsi_is_bonded_dsi(struct msm_dsi *msm_dsi);
+bool msm_dsi_is_master_dsi(struct msm_dsi *msm_dsi);
+bool msm_dsi_wide_bus_enabled(struct msm_dsi *msm_dsi);
+struct drm_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi);
+#else
+static inline void __init msm_dsi_register(void)
+{
+}
+static inline void __exit msm_dsi_unregister(void)
+{
+}
+static inline int msm_dsi_modeset_init(struct msm_dsi *msm_dsi,
+				       struct drm_device *dev,
+				       struct drm_encoder *encoder)
+{
+	return -EINVAL;
+}
+static inline void msm_dsi_snapshot(struct msm_disp_state *disp_state, struct msm_dsi *msm_dsi)
+{
+}
+static inline bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi)
+{
+	return false;
+}
+static inline bool msm_dsi_is_bonded_dsi(struct msm_dsi *msm_dsi)
+{
+	return false;
+}
+static inline bool msm_dsi_is_master_dsi(struct msm_dsi *msm_dsi)
+{
+	return false;
+}
+static inline bool msm_dsi_wide_bus_enabled(struct msm_dsi *msm_dsi)
+{
+	return false;
+}
+
+static inline struct drm_dsc_config *msm_dsi_get_dsc_config(struct msm_dsi *msm_dsi)
+{
+	return NULL;
+}
+#endif
+
+#ifdef CONFIG_DRM_MSM_DP
+int __init msm_dp_register(void);
+void __exit msm_dp_unregister(void);
+int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
+			 struct drm_encoder *encoder, bool yuv_supported);
+void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display);
+bool msm_dp_is_yuv_420_enabled(const struct msm_dp *dp_display,
+			       const struct drm_display_mode *mode);
+bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display,
+			       const struct drm_display_mode *mode);
+bool msm_dp_wide_bus_available(const struct msm_dp *dp_display);
+
+int msm_dp_get_mst_max_stream(const struct msm_dp *dp_display);
+
+int msm_dp_mst_bridge_init(struct msm_dp *dp_display, struct drm_encoder *encoder);
+
+int msm_dp_mst_register(struct msm_dp *dp_display);
+
+int msm_dp_get_mst_intf_id(struct msm_dp *dp_display, int stream_id);
+
+#else
+static inline int __init msm_dp_register(void)
+{
+	return -EINVAL;
+}
+static inline void __exit msm_dp_unregister(void)
+{
+}
+static inline int msm_dp_modeset_init(struct msm_dp *dp_display,
+				       struct drm_device *dev,
+				       struct drm_encoder *encoder,
+				       bool yuv_supported)
+{
+	return -EINVAL;
+}
+
+static inline int msm_dp_get_mst_max_stream(struct msm_dp *dp_display)
+{
+	return -EINVAL;
+}
+
+static inline int msm_dp_mst_register(struct msm_dp *dp_display)
+{
+	return -EINVAL;
+}
+
+static inline int msm_dp_mst_bridge_init(struct msm_dp *dp_display, struct drm_encoder *encoder)
+{
+	return -EINVAL;
+}
+
+static inline void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp_display)
+{
+}
+
+static inline bool msm_dp_is_yuv_420_enabled(const struct msm_dp *dp_display,
+					     const struct drm_display_mode *mode)
+{
+	return false;
+}
+
+static inline bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display,
+					     const struct drm_display_mode *mode)
+{
+	return false;
+}
+
+static inline bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)
+{
+	return false;
+}
+
+static inline int msm_dp_get_mst_intf_id(struct msm_dp *dp_display, int stream_id)
+{
+	return -EINVAL;
+}
+
+#endif
+
+#ifdef CONFIG_DRM_MSM_MDP4
+void msm_mdp4_register(void);
+void msm_mdp4_unregister(void);
+#else
+static inline void msm_mdp4_register(void) {}
+static inline void msm_mdp4_unregister(void) {}
+#endif
+
+#ifdef CONFIG_DRM_MSM_MDP5
+void msm_mdp_register(void);
+void msm_mdp_unregister(void);
+#else
+static inline void msm_mdp_register(void) {}
+static inline void msm_mdp_unregister(void) {}
+#endif
+
+#ifdef CONFIG_DRM_MSM_DPU
+void msm_dpu_register(void);
+void msm_dpu_unregister(void);
+#else
+static inline void msm_dpu_register(void) {}
+static inline void msm_dpu_unregister(void) {}
+#endif
+
+#ifdef CONFIG_DRM_MSM_MDSS
+void msm_mdss_register(void);
+void msm_mdss_unregister(void);
+#else
+static inline void msm_mdss_register(void) {}
+static inline void msm_mdss_unregister(void) {}
+#endif
+
+#ifdef CONFIG_DEBUG_FS
+void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m);
+int msm_debugfs_late_init(struct drm_device *dev);
+int msm_rd_debugfs_init(struct drm_minor *minor);
+void msm_rd_debugfs_cleanup(struct msm_drm_private *priv);
+__printf(3, 4)
+void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
+		const char *fmt, ...);
+int msm_perf_debugfs_init(struct drm_minor *minor);
+void msm_perf_debugfs_cleanup(struct msm_drm_private *priv);
+#else
+static inline int msm_debugfs_late_init(struct drm_device *dev) { return 0; }
+__printf(3, 4)
+static inline void msm_rd_dump_submit(struct msm_rd_state *rd,
+			struct msm_gem_submit *submit,
+			const char *fmt, ...) {}
+static inline void msm_rd_debugfs_cleanup(struct msm_drm_private *priv) {}
+static inline void msm_perf_debugfs_cleanup(struct msm_drm_private *priv) {}
+#endif
+
+struct clk *msm_clk_get(struct platform_device *pdev, const char *name);
+
+struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count,
+	const char *name);
+void __iomem *msm_ioremap(struct platform_device *pdev, const char *name);
+void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name,
+		phys_addr_t *size);
+void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name);
+
+struct icc_path *msm_icc_get(struct device *dev, const char *name);
+
+#define msm_writel(data, addr) writel((data), (addr))
+#define msm_readl(addr) readl((addr))
+
+static inline void msm_rmw(void __iomem *addr, u32 mask, u32 or)
+{
+	u32 val = msm_readl(addr);
+
+	val &= ~mask;
+	msm_writel(val | or, addr);
+}
+
+/**
+ * struct msm_hrtimer_work - a helper to combine an hrtimer with kthread_work
+ *
+ * @timer: hrtimer to control when the kthread work is triggered
+ * @work:  the kthread work
+ * @worker: the kthread worker the work will be scheduled on
+ */
+struct msm_hrtimer_work {
+	struct hrtimer timer;
+	struct kthread_work work;
+	struct kthread_worker *worker;
+};
+
+void msm_hrtimer_queue_work(struct msm_hrtimer_work *work,
+			    ktime_t wakeup_time,
+			    enum hrtimer_mode mode);
+void msm_hrtimer_work_init(struct msm_hrtimer_work *work,
+			   struct kthread_worker *worker,
+			   kthread_work_func_t fn,
+			   clockid_t clock_id,
+			   enum hrtimer_mode mode);
+
+#define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
+#define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
+
+static inline int align_pitch(int width, int bpp)
+{
+	int bytespp = (bpp + 7) / 8;
+	/* adreno needs pitch aligned to 32 pixels: */
+	return bytespp * ALIGN(width, 32);
+}
+
+/* for the generated headers: */
+#define INVALID_IDX(idx) ({BUG(); 0;})
+#define fui(x)                ({BUG(); 0;})
+#define _mesa_float_to_half(x) ({BUG(); 0;})
+
+
+#define FIELD(val, name) (((val) & name ## __MASK) >> name ## __SHIFT)
+
+/* for conditionally setting boolean flag(s): */
+#define COND(bool, val) ((bool) ? (val) : 0)
+
+static inline unsigned long timeout_to_jiffies(const ktime_t *timeout)
+{
+	ktime_t now = ktime_get();
+	s64 remaining_jiffies;
+
+	if (ktime_compare(*timeout, now) < 0) {
+		remaining_jiffies = 0;
+	} else {
+		ktime_t rem = ktime_sub(*timeout, now);
+		remaining_jiffies = ktime_divns(rem, NSEC_PER_SEC / HZ);
+	}
+
+	return clamp(remaining_jiffies, 1LL, (s64)INT_MAX);
+}
+
+/* Driver helpers */
+
+extern const struct component_master_ops msm_drm_ops;
+
+int msm_kms_pm_prepare(struct device *dev);
+void msm_kms_pm_complete(struct device *dev);
+
+int msm_drv_probe(struct device *dev,
+	int (*kms_init)(struct drm_device *dev),
+	struct msm_kms *kms);
+void msm_kms_shutdown(struct platform_device *pdev);
+
+
+#endif /* __MSM_DRV_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_dsc_helper.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_dsc_helper.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved
+ *
+ * Helper methods for MSM-specific DSC calculations that are common between timing engine,
+ * DSI, and DP.
+ */
+
+#ifndef MSM_DSC_HELPER_H_
+#define MSM_DSC_HELPER_H_
+
+#include <linux/math.h>
+#include <drm/display/drm_dsc_helper.h>
+
+/**
+ * msm_dsc_get_slices_per_intf() - calculate number of slices per interface
+ * @dsc: Pointer to drm dsc config struct
+ * @intf_width: interface width in pixels
+ * Returns: Integer representing the number of slices for the given interface
+ */
+static inline u32 msm_dsc_get_slices_per_intf(const struct drm_dsc_config *dsc, u32 intf_width)
+{
+	return DIV_ROUND_UP(intf_width, dsc->slice_width);
+}
+
+/**
+ * msm_dsc_get_bytes_per_line() - calculate bytes per line
+ * @dsc: Pointer to drm dsc config struct
+ * Returns: Integer value representing bytes per line. DSI and DP need
+ *          to perform further calculations to turn this into pclk_per_intf,
+ *          such as dividing by different values depending on if widebus is enabled.
+ */
+static inline u32 msm_dsc_get_bytes_per_line(const struct drm_dsc_config *dsc)
+{
+	return dsc->slice_count * dsc->slice_chunk_size;
+}
+
+#endif /* MSM_DSC_HELPER_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_fb.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_fb.c
@@ -0,0 +1,285 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_damage_helper.h>
+#include <drm/drm_file.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_probe_helper.h>
+
+#include "msm_drv.h"
+#include "msm_kms.h"
+#include "msm_gem.h"
+
+struct msm_framebuffer {
+	struct drm_framebuffer base;
+	const struct msm_format *format;
+
+	/* Count of # of attached planes which need dirtyfb: */
+	refcount_t dirtyfb;
+
+	/* Framebuffer per-plane address, if pinned, else zero: */
+	uint64_t iova[DRM_FORMAT_MAX_PLANES];
+	atomic_t prepare_count;
+};
+#define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base)
+
+static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
+		const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos);
+
+static int msm_framebuffer_dirtyfb(struct drm_framebuffer *fb,
+				   struct drm_file *file_priv, unsigned int flags,
+				   unsigned int color, struct drm_clip_rect *clips,
+				   unsigned int num_clips)
+{
+	struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+
+	/* If this fb is not used on any display requiring pixel data to be
+	 * flushed, then skip dirtyfb
+	 */
+	if (refcount_read(&msm_fb->dirtyfb) == 1)
+		return 0;
+
+	return drm_atomic_helper_dirtyfb(fb, file_priv, flags, color,
+					 clips, num_clips);
+}
+
+static const struct drm_framebuffer_funcs msm_framebuffer_funcs = {
+	.create_handle = drm_gem_fb_create_handle,
+	.destroy = drm_gem_fb_destroy,
+	.dirty = msm_framebuffer_dirtyfb,
+};
+
+#ifdef CONFIG_DEBUG_FS
+void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m)
+{
+	struct msm_gem_stats stats = {};
+	int i, n = fb->format->num_planes;
+
+	seq_printf(m, "fb: %dx%d@%4.4s (%2d, ID:%d)\n",
+			fb->width, fb->height, (char *)&fb->format->format,
+			drm_framebuffer_read_refcount(fb), fb->base.id);
+
+	for (i = 0; i < n; i++) {
+		seq_printf(m, "   %d: offset=%d pitch=%d, obj: ",
+				i, fb->offsets[i], fb->pitches[i]);
+		msm_gem_describe(fb->obj[i], m, &stats);
+	}
+}
+#endif
+
+/* prepare/pin all the fb's bo's for scanout.
+ */
+int msm_framebuffer_prepare(struct drm_framebuffer *fb,
+		struct msm_gem_address_space *aspace,
+		bool needs_dirtyfb)
+{
+	struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+	int ret, i, n = fb->format->num_planes;
+
+	if (needs_dirtyfb)
+		refcount_inc(&msm_fb->dirtyfb);
+
+	atomic_inc(&msm_fb->prepare_count);
+
+	for (i = 0; i < n; i++) {
+		ret = msm_gem_get_and_pin_iova(fb->obj[i], aspace, &msm_fb->iova[i]);
+		drm_dbg_state(fb->dev, "FB[%u]: iova[%d]: %08llx (%d)\n",
+			      fb->base.id, i, msm_fb->iova[i], ret);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+void msm_framebuffer_cleanup(struct drm_framebuffer *fb,
+		struct msm_gem_address_space *aspace,
+		bool needed_dirtyfb)
+{
+	struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+	int i, n = fb->format->num_planes;
+
+	if (needed_dirtyfb)
+		refcount_dec(&msm_fb->dirtyfb);
+
+	for (i = 0; i < n; i++)
+		msm_gem_unpin_iova(fb->obj[i], aspace);
+
+	if (!atomic_dec_return(&msm_fb->prepare_count))
+		memset(msm_fb->iova, 0, sizeof(msm_fb->iova));
+}
+
+uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb,
+		struct msm_gem_address_space *aspace, int plane)
+{
+	struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+	return msm_fb->iova[plane] + fb->offsets[plane];
+}
+
+struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane)
+{
+	return drm_gem_fb_get_obj(fb, plane);
+}
+
+const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb)
+{
+	struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+	return msm_fb->format;
+}
+
+struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
+		struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+	const struct drm_format_info *info = drm_get_format_info(dev,
+								 mode_cmd);
+	struct drm_gem_object *bos[4] = {0};
+	struct drm_framebuffer *fb;
+	int ret, i, n = info->num_planes;
+
+	for (i = 0; i < n; i++) {
+		bos[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);
+		if (!bos[i]) {
+			ret = -ENXIO;
+			goto out_unref;
+		}
+	}
+
+	fb = msm_framebuffer_init(dev, mode_cmd, bos);
+	if (IS_ERR(fb)) {
+		ret = PTR_ERR(fb);
+		goto out_unref;
+	}
+
+	return fb;
+
+out_unref:
+	for (i = 0; i < n; i++)
+		drm_gem_object_put(bos[i]);
+	return ERR_PTR(ret);
+}
+
+static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
+		const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
+{
+	const struct drm_format_info *info = drm_get_format_info(dev,
+								 mode_cmd);
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+	struct msm_framebuffer *msm_fb = NULL;
+	struct drm_framebuffer *fb;
+	const struct msm_format *format;
+	int ret, i, n;
+
+	drm_dbg_state(dev, "create framebuffer: mode_cmd=%p (%dx%d@%4.4s)\n",
+			mode_cmd, mode_cmd->width, mode_cmd->height,
+			(char *)&mode_cmd->pixel_format);
+
+	n = info->num_planes;
+	format = kms->funcs->get_format(kms, mode_cmd->pixel_format,
+			mode_cmd->modifier[0]);
+	if (!format) {
+		DRM_DEV_ERROR(dev->dev, "unsupported pixel format: %4.4s\n",
+				(char *)&mode_cmd->pixel_format);
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	msm_fb = kzalloc(sizeof(*msm_fb), GFP_KERNEL);
+	if (!msm_fb) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	fb = &msm_fb->base;
+
+	msm_fb->format = format;
+
+	if (n > ARRAY_SIZE(fb->obj)) {
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	for (i = 0; i < n; i++) {
+		unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
+		unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
+		unsigned int min_size;
+
+		min_size = (height - 1) * mode_cmd->pitches[i]
+			 + width * info->cpp[i]
+			 + mode_cmd->offsets[i];
+
+		if (bos[i]->size < min_size) {
+			ret = -EINVAL;
+			goto fail;
+		}
+
+		msm_fb->base.obj[i] = bos[i];
+	}
+
+	drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
+
+	ret = drm_framebuffer_init(dev, fb, &msm_framebuffer_funcs);
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev, "framebuffer init failed: %d\n", ret);
+		goto fail;
+	}
+
+	refcount_set(&msm_fb->dirtyfb, 1);
+
+	drm_dbg_state(dev, "create: FB ID: %d (%p)\n", fb->base.id, fb);
+
+	return fb;
+
+fail:
+	kfree(msm_fb);
+
+	return ERR_PTR(ret);
+}
+
+struct drm_framebuffer *
+msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, int p, uint32_t format)
+{
+	struct drm_mode_fb_cmd2 mode_cmd = {
+		.pixel_format = format,
+		.width = w,
+		.height = h,
+		.pitches = { p },
+	};
+	struct drm_gem_object *bo;
+	struct drm_framebuffer *fb;
+	int size;
+
+	/* allocate backing bo */
+	size = mode_cmd.pitches[0] * mode_cmd.height;
+	DBG("allocating %d bytes for fb %d", size, dev->primary->index);
+	bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC | MSM_BO_STOLEN);
+	if (IS_ERR(bo)) {
+		dev_warn(dev->dev, "could not allocate stolen bo\n");
+		/* try regular bo: */
+		bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC);
+	}
+	if (IS_ERR(bo)) {
+		DRM_DEV_ERROR(dev->dev, "failed to allocate buffer object\n");
+		return ERR_CAST(bo);
+	}
+
+	msm_gem_object_set_name(bo, "stolenfb");
+
+	fb = msm_framebuffer_init(dev, &mode_cmd, &bo);
+	if (IS_ERR(fb)) {
+		DRM_DEV_ERROR(dev->dev, "failed to allocate fb\n");
+		/* note: if fb creation failed, we can't rely on fb destroy
+		 * to unref the bo:
+		 */
+		drm_gem_object_put(bo);
+		return ERR_CAST(fb);
+	}
+
+	return fb;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_fbdev.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_fbdev.c
@@ -0,0 +1,256 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/fb.h>
+
+#include <drm/drm_drv.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_framebuffer.h>
+#include <drm/drm_prime.h>
+
+#include "msm_drv.h"
+#include "msm_gem.h"
+#include "msm_kms.h"
+
+static bool fbdev = true;
+MODULE_PARM_DESC(fbdev, "Enable fbdev compat layer");
+module_param(fbdev, bool, 0600);
+
+/*
+ * fbdev funcs, to implement legacy fbdev interface on top of drm driver
+ */
+
+FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(msm_fbdev,
+				   drm_fb_helper_damage_range,
+				   drm_fb_helper_damage_area)
+
+static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
+{
+	struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par;
+	struct drm_gem_object *bo = msm_framebuffer_bo(helper->fb, 0);
+
+	return drm_gem_prime_mmap(bo, vma);
+}
+
+static void msm_fbdev_fb_destroy(struct fb_info *info)
+{
+	struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par;
+	struct drm_framebuffer *fb = helper->fb;
+	struct drm_gem_object *bo = msm_framebuffer_bo(fb, 0);
+
+	DBG();
+
+	drm_fb_helper_fini(helper);
+
+	/* this will free the backing object */
+	msm_gem_put_vaddr(bo);
+	drm_framebuffer_remove(fb);
+
+	drm_client_release(&helper->client);
+	drm_fb_helper_unprepare(helper);
+	kfree(helper);
+}
+
+static const struct fb_ops msm_fb_ops = {
+	.owner = THIS_MODULE,
+	__FB_DEFAULT_DEFERRED_OPS_RDWR(msm_fbdev),
+	DRM_FB_HELPER_DEFAULT_OPS,
+	__FB_DEFAULT_DEFERRED_OPS_DRAW(msm_fbdev),
+	.fb_mmap = msm_fbdev_mmap,
+	.fb_destroy = msm_fbdev_fb_destroy,
+};
+
+static int msm_fbdev_create(struct drm_fb_helper *helper,
+		struct drm_fb_helper_surface_size *sizes)
+{
+	struct drm_device *dev = helper->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct drm_framebuffer *fb = NULL;
+	struct drm_gem_object *bo;
+	struct fb_info *fbi = NULL;
+	uint64_t paddr;
+	uint32_t format;
+	int ret, pitch;
+
+	format = drm_mode_legacy_fb_format(sizes->surface_bpp, sizes->surface_depth);
+
+	DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,
+			sizes->surface_height, sizes->surface_bpp,
+			sizes->fb_width, sizes->fb_height);
+
+	pitch = align_pitch(sizes->surface_width, sizes->surface_bpp);
+	fb = msm_alloc_stolen_fb(dev, sizes->surface_width,
+			sizes->surface_height, pitch, format);
+
+	if (IS_ERR(fb)) {
+		DRM_DEV_ERROR(dev->dev, "failed to allocate fb\n");
+		return PTR_ERR(fb);
+	}
+
+	bo = msm_framebuffer_bo(fb, 0);
+
+	/*
+	 * NOTE: if we can be guaranteed to be able to map buffer
+	 * in panic (ie. lock-safe, etc) we could avoid pinning the
+	 * buffer now:
+	 */
+	ret = msm_gem_get_and_pin_iova(bo, priv->kms->aspace, &paddr);
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev, "failed to get buffer obj iova: %d\n", ret);
+		goto fail;
+	}
+
+	fbi = drm_fb_helper_alloc_info(helper);
+	if (IS_ERR(fbi)) {
+		DRM_DEV_ERROR(dev->dev, "failed to allocate fb info\n");
+		ret = PTR_ERR(fbi);
+		goto fail;
+	}
+
+	DBG("fbi=%p, dev=%p", fbi, dev);
+
+	helper->fb = fb;
+
+	fbi->fbops = &msm_fb_ops;
+
+	drm_fb_helper_fill_info(fbi, helper, sizes);
+
+	fbi->screen_buffer = msm_gem_get_vaddr(bo);
+	if (IS_ERR(fbi->screen_buffer)) {
+		ret = PTR_ERR(fbi->screen_buffer);
+		goto fail;
+	}
+	fbi->screen_size = bo->size;
+	fbi->fix.smem_start = paddr;
+	fbi->fix.smem_len = bo->size;
+
+	DBG("par=%p, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres);
+	DBG("allocated %dx%d fb", fb->width, fb->height);
+
+	return 0;
+
+fail:
+	drm_framebuffer_remove(fb);
+	return ret;
+}
+
+static int msm_fbdev_fb_dirty(struct drm_fb_helper *helper,
+			      struct drm_clip_rect *clip)
+{
+	struct drm_device *dev = helper->dev;
+	int ret;
+
+	/* Call damage handlers only if necessary */
+	if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2))
+		return 0;
+
+	if (helper->fb->funcs->dirty) {
+		ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1);
+		if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret))
+			return ret;
+	}
+
+	return 0;
+}
+
+static const struct drm_fb_helper_funcs msm_fb_helper_funcs = {
+	.fb_probe = msm_fbdev_create,
+	.fb_dirty = msm_fbdev_fb_dirty,
+};
+
+/*
+ * struct drm_client
+ */
+
+static void msm_fbdev_client_unregister(struct drm_client_dev *client)
+{
+	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
+
+	if (fb_helper->info) {
+		drm_fb_helper_unregister_info(fb_helper);
+	} else {
+		drm_client_release(&fb_helper->client);
+		drm_fb_helper_unprepare(fb_helper);
+		kfree(fb_helper);
+	}
+}
+
+static int msm_fbdev_client_restore(struct drm_client_dev *client)
+{
+	drm_fb_helper_lastclose(client->dev);
+
+	return 0;
+}
+
+static int msm_fbdev_client_hotplug(struct drm_client_dev *client)
+{
+	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
+	struct drm_device *dev = client->dev;
+	int ret;
+
+	if (dev->fb_helper)
+		return drm_fb_helper_hotplug_event(dev->fb_helper);
+
+	ret = drm_fb_helper_init(dev, fb_helper);
+	if (ret)
+		goto err_drm_err;
+
+	if (!drm_drv_uses_atomic_modeset(dev))
+		drm_helper_disable_unused_functions(dev);
+
+	ret = drm_fb_helper_initial_config(fb_helper);
+	if (ret)
+		goto err_drm_fb_helper_fini;
+
+	return 0;
+
+err_drm_fb_helper_fini:
+	drm_fb_helper_fini(fb_helper);
+err_drm_err:
+	drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret);
+	return ret;
+}
+
+static const struct drm_client_funcs msm_fbdev_client_funcs = {
+	.owner		= THIS_MODULE,
+	.unregister	= msm_fbdev_client_unregister,
+	.restore	= msm_fbdev_client_restore,
+	.hotplug	= msm_fbdev_client_hotplug,
+};
+
+/* initialize fbdev helper */
+void msm_fbdev_setup(struct drm_device *dev)
+{
+	struct drm_fb_helper *helper;
+	int ret;
+
+	if (!fbdev)
+		return;
+
+	drm_WARN(dev, !dev->registered, "Device has not been registered.\n");
+	drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n");
+
+	helper = kzalloc(sizeof(*helper), GFP_KERNEL);
+	if (!helper)
+		return;
+	drm_fb_helper_prepare(dev, helper, 32, &msm_fb_helper_funcs);
+
+	ret = drm_client_init(dev, &helper->client, "fbdev", &msm_fbdev_client_funcs);
+	if (ret) {
+		drm_err(dev, "Failed to register client: %d\n", ret);
+		goto err_drm_fb_helper_unprepare;
+	}
+
+	drm_client_register(&helper->client);
+
+	return;
+
+err_drm_fb_helper_unprepare:
+	drm_fb_helper_unprepare(helper);
+	kfree(helper);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_fence.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_fence.c
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013-2016 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/dma-fence.h>
+
+#include "msm_drv.h"
+#include "msm_fence.h"
+#include "msm_gpu.h"
+
+static struct msm_gpu *fctx2gpu(struct msm_fence_context *fctx)
+{
+	struct msm_drm_private *priv = fctx->dev->dev_private;
+	return priv->gpu;
+}
+
+static enum hrtimer_restart deadline_timer(struct hrtimer *t)
+{
+	struct msm_fence_context *fctx = container_of(t,
+			struct msm_fence_context, deadline_timer);
+
+	kthread_queue_work(fctx2gpu(fctx)->worker, &fctx->deadline_work);
+
+	return HRTIMER_NORESTART;
+}
+
+static void deadline_work(struct kthread_work *work)
+{
+	struct msm_fence_context *fctx = container_of(work,
+			struct msm_fence_context, deadline_work);
+
+	/* If deadline fence has already passed, nothing to do: */
+	if (msm_fence_completed(fctx, fctx->next_deadline_fence))
+		return;
+
+	msm_devfreq_boost(fctx2gpu(fctx), 2);
+}
+
+
+struct msm_fence_context *
+msm_fence_context_alloc(struct drm_device *dev, volatile uint32_t *fenceptr,
+		const char *name)
+{
+	struct msm_fence_context *fctx;
+	static int index = 0;
+
+	fctx = kzalloc(sizeof(*fctx), GFP_KERNEL);
+	if (!fctx)
+		return ERR_PTR(-ENOMEM);
+
+	fctx->dev = dev;
+	strscpy(fctx->name, name, sizeof(fctx->name));
+	fctx->context = dma_fence_context_alloc(1);
+	fctx->index = index++;
+	fctx->fenceptr = fenceptr;
+	spin_lock_init(&fctx->spinlock);
+
+	/*
+	 * Start out close to the 32b fence rollover point, so we can
+	 * catch bugs with fence comparisons.
+	 */
+	fctx->last_fence = 0xffffff00;
+	fctx->completed_fence = fctx->last_fence;
+	*fctx->fenceptr = fctx->last_fence;
+
+	hrtimer_init(&fctx->deadline_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+	fctx->deadline_timer.function = deadline_timer;
+
+	kthread_init_work(&fctx->deadline_work, deadline_work);
+
+	fctx->next_deadline = ktime_get();
+
+	return fctx;
+}
+
+void msm_fence_context_free(struct msm_fence_context *fctx)
+{
+	kfree(fctx);
+}
+
+bool msm_fence_completed(struct msm_fence_context *fctx, uint32_t fence)
+{
+	/*
+	 * Note: Check completed_fence first, as fenceptr is in a write-combine
+	 * mapping, so it will be more expensive to read.
+	 */
+	return (int32_t)(fctx->completed_fence - fence) >= 0 ||
+		(int32_t)(*fctx->fenceptr - fence) >= 0;
+}
+
+/* called from irq handler and workqueue (in recover path) */
+void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&fctx->spinlock, flags);
+	if (fence_after(fence, fctx->completed_fence))
+		fctx->completed_fence = fence;
+	if (msm_fence_completed(fctx, fctx->next_deadline_fence))
+		hrtimer_cancel(&fctx->deadline_timer);
+	spin_unlock_irqrestore(&fctx->spinlock, flags);
+}
+
+struct msm_fence {
+	struct dma_fence base;
+	struct msm_fence_context *fctx;
+};
+
+static inline struct msm_fence *to_msm_fence(struct dma_fence *fence)
+{
+	return container_of(fence, struct msm_fence, base);
+}
+
+static const char *msm_fence_get_driver_name(struct dma_fence *fence)
+{
+	return "msm";
+}
+
+static const char *msm_fence_get_timeline_name(struct dma_fence *fence)
+{
+	struct msm_fence *f = to_msm_fence(fence);
+	return f->fctx->name;
+}
+
+static bool msm_fence_signaled(struct dma_fence *fence)
+{
+	struct msm_fence *f = to_msm_fence(fence);
+	return msm_fence_completed(f->fctx, f->base.seqno);
+}
+
+static void msm_fence_set_deadline(struct dma_fence *fence, ktime_t deadline)
+{
+	struct msm_fence *f = to_msm_fence(fence);
+	struct msm_fence_context *fctx = f->fctx;
+	unsigned long flags;
+	ktime_t now;
+
+	spin_lock_irqsave(&fctx->spinlock, flags);
+	now = ktime_get();
+
+	if (ktime_after(now, fctx->next_deadline) ||
+			ktime_before(deadline, fctx->next_deadline)) {
+		fctx->next_deadline = deadline;
+		fctx->next_deadline_fence =
+			max(fctx->next_deadline_fence, (uint32_t)fence->seqno);
+
+		/*
+		 * Set timer to trigger boost 3ms before deadline, or
+		 * if we are already less than 3ms before the deadline
+		 * schedule boost work immediately.
+		 */
+		deadline = ktime_sub(deadline, ms_to_ktime(3));
+
+		if (ktime_after(now, deadline)) {
+			kthread_queue_work(fctx2gpu(fctx)->worker,
+					&fctx->deadline_work);
+		} else {
+			hrtimer_start(&fctx->deadline_timer, deadline,
+					HRTIMER_MODE_ABS);
+		}
+	}
+
+	spin_unlock_irqrestore(&fctx->spinlock, flags);
+}
+
+static const struct dma_fence_ops msm_fence_ops = {
+	.get_driver_name = msm_fence_get_driver_name,
+	.get_timeline_name = msm_fence_get_timeline_name,
+	.signaled = msm_fence_signaled,
+	.set_deadline = msm_fence_set_deadline,
+};
+
+struct dma_fence *
+msm_fence_alloc(void)
+{
+	struct msm_fence *f;
+
+	f = kzalloc(sizeof(*f), GFP_KERNEL);
+	if (!f)
+		return ERR_PTR(-ENOMEM);
+
+	return &f->base;
+}
+
+void
+msm_fence_init(struct dma_fence *fence, struct msm_fence_context *fctx)
+{
+	struct msm_fence *f = to_msm_fence(fence);
+
+	f->fctx = fctx;
+
+	/*
+	 * Until this point, the fence was just some pre-allocated memory,
+	 * no-one should have taken a reference to it yet.
+	 */
+	WARN_ON(kref_read(&fence->refcount));
+
+	dma_fence_init(&f->base, &msm_fence_ops, &fctx->spinlock,
+		       fctx->context, ++fctx->last_fence);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_fence.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_fence.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013-2016 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __MSM_FENCE_H__
+#define __MSM_FENCE_H__
+
+#include "msm_drv.h"
+
+/**
+ * struct msm_fence_context - fence context for gpu
+ *
+ * Each ringbuffer has a single fence context, with the GPU writing an
+ * incrementing fence seqno at the end of each submit
+ */
+struct msm_fence_context {
+	struct drm_device *dev;
+	/** name: human readable name for fence timeline */
+	char name[32];
+	/** context: see dma_fence_context_alloc() */
+	unsigned context;
+	/** index: similar to context, but local to msm_fence_context's */
+	unsigned index;
+
+	/**
+	 * last_fence:
+	 *
+	 * Last assigned fence, incremented each time a fence is created
+	 * on this fence context.  If last_fence == completed_fence,
+	 * there is no remaining pending work
+	 */
+	uint32_t last_fence;
+
+	/**
+	 * completed_fence:
+	 *
+	 * The last completed fence, updated from the CPU after interrupt
+	 * from GPU
+	 */
+	uint32_t completed_fence;
+
+	/**
+	 * fenceptr:
+	 *
+	 * The address that the GPU directly writes with completed fence
+	 * seqno.  This can be ahead of completed_fence.  We can peek at
+	 * this to see if a fence has already signaled but the CPU hasn't
+	 * gotten around to handling the irq and updating completed_fence
+	 */
+	volatile uint32_t *fenceptr;
+
+	spinlock_t spinlock;
+
+	/*
+	 * TODO this doesn't really deal with multiple deadlines, like
+	 * if userspace got multiple frames ahead.. OTOH atomic updates
+	 * don't queue, so maybe that is ok
+	 */
+
+	/** next_deadline: Time of next deadline */
+	ktime_t next_deadline;
+
+	/**
+	 * next_deadline_fence:
+	 *
+	 * Fence value for next pending deadline.  The deadline timer is
+	 * canceled when this fence is signaled.
+	 */
+	uint32_t next_deadline_fence;
+
+	struct hrtimer deadline_timer;
+	struct kthread_work deadline_work;
+};
+
+struct msm_fence_context * msm_fence_context_alloc(struct drm_device *dev,
+		volatile uint32_t *fenceptr, const char *name);
+void msm_fence_context_free(struct msm_fence_context *fctx);
+
+bool msm_fence_completed(struct msm_fence_context *fctx, uint32_t fence);
+void msm_update_fence(struct msm_fence_context *fctx, uint32_t fence);
+
+struct dma_fence * msm_fence_alloc(void);
+void msm_fence_init(struct dma_fence *fence, struct msm_fence_context *fctx);
+
+static inline bool
+fence_before(uint32_t a, uint32_t b)
+{
+   return (int32_t)(a - b) < 0;
+}
+
+static inline bool
+fence_after(uint32_t a, uint32_t b)
+{
+   return (int32_t)(a - b) > 0;
+}
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_gem.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_gem.c
@@ -0,0 +1,1371 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/dma-map-ops.h>
+#include <linux/vmalloc.h>
+#include <linux/spinlock.h>
+#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
+#include <linux/pfn_t.h>
+
+#include <drm/drm_prime.h>
+
+#include "msm_drv.h"
+#include "msm_fence.h"
+#include "msm_gem.h"
+#include "msm_gpu.h"
+#include "msm_mmu.h"
+
+static dma_addr_t physaddr(struct drm_gem_object *obj)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	struct msm_drm_private *priv = obj->dev->dev_private;
+	return (((dma_addr_t)msm_obj->vram_node->start) << PAGE_SHIFT) +
+			priv->vram.paddr;
+}
+
+static bool use_pages(struct drm_gem_object *obj)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	return !msm_obj->vram_node;
+}
+
+/*
+ * Cache sync.. this is a bit over-complicated, to fit dma-mapping
+ * API.  Really GPU cache is out of scope here (handled on cmdstream)
+ * and all we need to do is invalidate newly allocated pages before
+ * mapping to CPU as uncached/writecombine.
+ *
+ * On top of this, we have the added headache, that depending on
+ * display generation, the display's iommu may be wired up to either
+ * the toplevel drm device (mdss), or to the mdp sub-node, meaning
+ * that here we either have dma-direct or iommu ops.
+ *
+ * Let this be a cautionary tail of abstraction gone wrong.
+ */
+
+static void sync_for_device(struct msm_gem_object *msm_obj)
+{
+	struct device *dev = msm_obj->base.dev->dev;
+
+	dma_map_sgtable(dev, msm_obj->sgt, DMA_BIDIRECTIONAL, 0);
+}
+
+static void sync_for_cpu(struct msm_gem_object *msm_obj)
+{
+	struct device *dev = msm_obj->base.dev->dev;
+
+	dma_unmap_sgtable(dev, msm_obj->sgt, DMA_BIDIRECTIONAL, 0);
+}
+
+static void update_lru_active(struct drm_gem_object *obj)
+{
+	struct msm_drm_private *priv = obj->dev->dev_private;
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+	GEM_WARN_ON(!msm_obj->pages);
+
+	if (msm_obj->pin_count) {
+		drm_gem_lru_move_tail_locked(&priv->lru.pinned, obj);
+	} else if (msm_obj->madv == MSM_MADV_WILLNEED) {
+		drm_gem_lru_move_tail_locked(&priv->lru.willneed, obj);
+	} else {
+		GEM_WARN_ON(msm_obj->madv != MSM_MADV_DONTNEED);
+
+		drm_gem_lru_move_tail_locked(&priv->lru.dontneed, obj);
+	}
+}
+
+static void update_lru_locked(struct drm_gem_object *obj)
+{
+	struct msm_drm_private *priv = obj->dev->dev_private;
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+	msm_gem_assert_locked(&msm_obj->base);
+
+	if (!msm_obj->pages) {
+		GEM_WARN_ON(msm_obj->pin_count);
+
+		drm_gem_lru_move_tail_locked(&priv->lru.unbacked, obj);
+	} else {
+		update_lru_active(obj);
+	}
+}
+
+static void update_lru(struct drm_gem_object *obj)
+{
+	struct msm_drm_private *priv = obj->dev->dev_private;
+
+	mutex_lock(&priv->lru.lock);
+	update_lru_locked(obj);
+	mutex_unlock(&priv->lru.lock);
+}
+
+/* allocate pages from VRAM carveout, used when no IOMMU: */
+static struct page **get_pages_vram(struct drm_gem_object *obj, int npages)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	struct msm_drm_private *priv = obj->dev->dev_private;
+	dma_addr_t paddr;
+	struct page **p;
+	int ret, i;
+
+	p = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
+	if (!p)
+		return ERR_PTR(-ENOMEM);
+
+	spin_lock(&priv->vram.lock);
+	ret = drm_mm_insert_node(&priv->vram.mm, msm_obj->vram_node, npages);
+	spin_unlock(&priv->vram.lock);
+	if (ret) {
+		kvfree(p);
+		return ERR_PTR(ret);
+	}
+
+	paddr = physaddr(obj);
+	for (i = 0; i < npages; i++) {
+		p[i] = pfn_to_page(__phys_to_pfn(paddr));
+		paddr += PAGE_SIZE;
+	}
+
+	return p;
+}
+
+static struct page **get_pages(struct drm_gem_object *obj)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+	msm_gem_assert_locked(obj);
+
+	if (!msm_obj->pages) {
+		struct drm_device *dev = obj->dev;
+		struct page **p;
+		int npages = obj->size >> PAGE_SHIFT;
+
+		if (use_pages(obj))
+			p = drm_gem_get_pages(obj);
+		else
+			p = get_pages_vram(obj, npages);
+
+		if (IS_ERR(p)) {
+			DRM_DEV_ERROR(dev->dev, "could not get pages: %ld\n",
+					PTR_ERR(p));
+			return p;
+		}
+
+		msm_obj->pages = p;
+
+		msm_obj->sgt = drm_prime_pages_to_sg(obj->dev, p, npages);
+		if (IS_ERR(msm_obj->sgt)) {
+			void *ptr = ERR_CAST(msm_obj->sgt);
+
+			DRM_DEV_ERROR(dev->dev, "failed to allocate sgt\n");
+			msm_obj->sgt = NULL;
+			return ptr;
+		}
+
+		/* For non-cached buffers, ensure the new pages are clean
+		 * because display controller, GPU, etc. are not coherent:
+		 */
+		if (msm_obj->flags & MSM_BO_WC)
+			sync_for_device(msm_obj);
+
+		update_lru(obj);
+	}
+
+	return msm_obj->pages;
+}
+
+static void put_pages_vram(struct drm_gem_object *obj)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	struct msm_drm_private *priv = obj->dev->dev_private;
+
+	spin_lock(&priv->vram.lock);
+	drm_mm_remove_node(msm_obj->vram_node);
+	spin_unlock(&priv->vram.lock);
+
+	kvfree(msm_obj->pages);
+}
+
+static void put_pages(struct drm_gem_object *obj)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+	if (msm_obj->pages) {
+		if (msm_obj->sgt) {
+			/* For non-cached buffers, ensure the new
+			 * pages are clean because display controller,
+			 * GPU, etc. are not coherent:
+			 */
+			if (msm_obj->flags & MSM_BO_WC)
+				sync_for_cpu(msm_obj);
+
+			sg_free_table(msm_obj->sgt);
+			kfree(msm_obj->sgt);
+			msm_obj->sgt = NULL;
+		}
+
+		if (use_pages(obj))
+			drm_gem_put_pages(obj, msm_obj->pages, true, false);
+		else
+			put_pages_vram(obj);
+
+		msm_obj->pages = NULL;
+		update_lru(obj);
+	}
+}
+
+static struct page **msm_gem_pin_pages_locked(struct drm_gem_object *obj,
+					      unsigned madv)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+	msm_gem_assert_locked(obj);
+
+	if (msm_obj->madv > madv) {
+		DRM_DEV_DEBUG_DRIVER(obj->dev->dev, "Invalid madv state: %u vs %u\n",
+				     msm_obj->madv, madv);
+		return ERR_PTR(-EBUSY);
+	}
+
+	return get_pages(obj);
+}
+
+/*
+ * Update the pin count of the object, call under lru.lock
+ */
+void msm_gem_pin_obj_locked(struct drm_gem_object *obj)
+{
+	struct msm_drm_private *priv = obj->dev->dev_private;
+
+	msm_gem_assert_locked(obj);
+
+	to_msm_bo(obj)->pin_count++;
+	drm_gem_lru_move_tail_locked(&priv->lru.pinned, obj);
+}
+
+static void pin_obj_locked(struct drm_gem_object *obj)
+{
+	struct msm_drm_private *priv = obj->dev->dev_private;
+
+	mutex_lock(&priv->lru.lock);
+	msm_gem_pin_obj_locked(obj);
+	mutex_unlock(&priv->lru.lock);
+}
+
+struct page **msm_gem_pin_pages(struct drm_gem_object *obj)
+{
+	struct page **p;
+
+	msm_gem_lock(obj);
+	p = msm_gem_pin_pages_locked(obj, MSM_MADV_WILLNEED);
+	if (!IS_ERR(p))
+		pin_obj_locked(obj);
+	msm_gem_unlock(obj);
+
+	return p;
+}
+
+void msm_gem_unpin_pages(struct drm_gem_object *obj)
+{
+	msm_gem_lock(obj);
+	msm_gem_unpin_locked(obj);
+	msm_gem_unlock(obj);
+}
+
+static pgprot_t msm_gem_pgprot(struct msm_gem_object *msm_obj, pgprot_t prot)
+{
+	if (msm_obj->flags & MSM_BO_WC)
+		return pgprot_writecombine(prot);
+	return prot;
+}
+
+static vm_fault_t msm_gem_fault(struct vm_fault *vmf)
+{
+	struct vm_area_struct *vma = vmf->vma;
+	struct drm_gem_object *obj = vma->vm_private_data;
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	struct page **pages;
+	unsigned long pfn;
+	pgoff_t pgoff;
+	int err;
+	vm_fault_t ret;
+
+	/*
+	 * vm_ops.open/drm_gem_mmap_obj and close get and put
+	 * a reference on obj. So, we dont need to hold one here.
+	 */
+	err = msm_gem_lock_interruptible(obj);
+	if (err) {
+		ret = VM_FAULT_NOPAGE;
+		goto out;
+	}
+
+	if (GEM_WARN_ON(msm_obj->madv != MSM_MADV_WILLNEED)) {
+		msm_gem_unlock(obj);
+		return VM_FAULT_SIGBUS;
+	}
+
+	/* make sure we have pages attached now */
+	pages = get_pages(obj);
+	if (IS_ERR(pages)) {
+		ret = vmf_error(PTR_ERR(pages));
+		goto out_unlock;
+	}
+
+	/* We don't use vmf->pgoff since that has the fake offset: */
+	pgoff = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
+
+	pfn = page_to_pfn(pages[pgoff]);
+
+	VERB("Inserting %p pfn %lx, pa %lx", (void *)vmf->address,
+			pfn, pfn << PAGE_SHIFT);
+
+	ret = vmf_insert_pfn(vma, vmf->address, pfn);
+
+out_unlock:
+	msm_gem_unlock(obj);
+out:
+	return ret;
+}
+
+/** get mmap offset */
+static uint64_t mmap_offset(struct drm_gem_object *obj)
+{
+	struct drm_device *dev = obj->dev;
+	int ret;
+
+	msm_gem_assert_locked(obj);
+
+	/* Make it mmapable */
+	ret = drm_gem_create_mmap_offset(obj);
+
+	if (ret) {
+		DRM_DEV_ERROR(dev->dev, "could not allocate mmap offset\n");
+		return 0;
+	}
+
+	return drm_vma_node_offset_addr(&obj->vma_node);
+}
+
+uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj)
+{
+	uint64_t offset;
+
+	msm_gem_lock(obj);
+	offset = mmap_offset(obj);
+	msm_gem_unlock(obj);
+	return offset;
+}
+
+static struct msm_gem_vma *add_vma(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	struct msm_gem_vma *vma;
+
+	msm_gem_assert_locked(obj);
+
+	vma = msm_gem_vma_new(aspace);
+	if (!vma)
+		return ERR_PTR(-ENOMEM);
+
+	list_add_tail(&vma->list, &msm_obj->vmas);
+
+	return vma;
+}
+
+static struct msm_gem_vma *lookup_vma(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	struct msm_gem_vma *vma;
+
+	msm_gem_assert_locked(obj);
+
+	list_for_each_entry(vma, &msm_obj->vmas, list) {
+		if (vma->aspace == aspace)
+			return vma;
+	}
+
+	return NULL;
+}
+
+static void del_vma(struct msm_gem_vma *vma)
+{
+	if (!vma)
+		return;
+
+	list_del(&vma->list);
+	kfree(vma);
+}
+
+/*
+ * If close is true, this also closes the VMA (releasing the allocated
+ * iova range) in addition to removing the iommu mapping.  In the eviction
+ * case (!close), we keep the iova allocated, but only remove the iommu
+ * mapping.
+ */
+static void
+put_iova_spaces(struct drm_gem_object *obj, bool close)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	struct msm_gem_vma *vma;
+
+	msm_gem_assert_locked(obj);
+
+	list_for_each_entry(vma, &msm_obj->vmas, list) {
+		if (vma->aspace) {
+			msm_gem_vma_purge(vma);
+			if (close)
+				msm_gem_vma_close(vma);
+		}
+	}
+}
+
+/* Called with msm_obj locked */
+static void
+put_iova_vmas(struct drm_gem_object *obj)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	struct msm_gem_vma *vma, *tmp;
+
+	msm_gem_assert_locked(obj);
+
+	list_for_each_entry_safe(vma, tmp, &msm_obj->vmas, list) {
+		del_vma(vma);
+	}
+}
+
+static struct msm_gem_vma *get_vma_locked(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace,
+		u64 range_start, u64 range_end)
+{
+	struct msm_gem_vma *vma;
+
+	msm_gem_assert_locked(obj);
+
+	vma = lookup_vma(obj, aspace);
+
+	if (!vma) {
+		int ret;
+
+		vma = add_vma(obj, aspace);
+		if (IS_ERR(vma))
+			return vma;
+
+		ret = msm_gem_vma_init(vma, obj->size,
+			range_start, range_end);
+		if (ret) {
+			del_vma(vma);
+			return ERR_PTR(ret);
+		}
+	} else {
+		GEM_WARN_ON(vma->iova < range_start);
+		GEM_WARN_ON((vma->iova + obj->size) > range_end);
+	}
+
+	return vma;
+}
+
+int msm_gem_pin_vma_locked(struct drm_gem_object *obj, struct msm_gem_vma *vma)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	struct page **pages;
+	int prot = IOMMU_READ;
+
+	if (!(msm_obj->flags & MSM_BO_GPU_READONLY))
+		prot |= IOMMU_WRITE;
+
+	if (msm_obj->flags & MSM_BO_MAP_PRIV)
+		prot |= IOMMU_PRIV;
+
+	if (msm_obj->flags & MSM_BO_CACHED_COHERENT)
+		prot |= IOMMU_CACHE;
+
+	msm_gem_assert_locked(obj);
+
+	pages = msm_gem_pin_pages_locked(obj, MSM_MADV_WILLNEED);
+	if (IS_ERR(pages))
+		return PTR_ERR(pages);
+
+	return msm_gem_vma_map(vma, prot, msm_obj->sgt, obj->size);
+}
+
+void msm_gem_unpin_locked(struct drm_gem_object *obj)
+{
+	struct msm_drm_private *priv = obj->dev->dev_private;
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+	msm_gem_assert_locked(obj);
+
+	mutex_lock(&priv->lru.lock);
+	msm_obj->pin_count--;
+	GEM_WARN_ON(msm_obj->pin_count < 0);
+	update_lru_locked(obj);
+	mutex_unlock(&priv->lru.lock);
+}
+
+/* Special unpin path for use in fence-signaling path, avoiding the need
+ * to hold the obj lock by only depending on things that a protected by
+ * the LRU lock.  In particular we know that that we already have backing
+ * and and that the object's dma_resv has the fence for the current
+ * submit/job which will prevent us racing against page eviction.
+ */
+void msm_gem_unpin_active(struct drm_gem_object *obj)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+	msm_obj->pin_count--;
+	GEM_WARN_ON(msm_obj->pin_count < 0);
+	update_lru_active(obj);
+}
+
+struct msm_gem_vma *msm_gem_get_vma_locked(struct drm_gem_object *obj,
+					   struct msm_gem_address_space *aspace)
+{
+	return get_vma_locked(obj, aspace, 0, U64_MAX);
+}
+
+static int get_and_pin_iova_range_locked(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace, uint64_t *iova,
+		u64 range_start, u64 range_end)
+{
+	struct msm_gem_vma *vma;
+	int ret;
+
+	msm_gem_assert_locked(obj);
+
+	vma = get_vma_locked(obj, aspace, range_start, range_end);
+	if (IS_ERR(vma))
+		return PTR_ERR(vma);
+
+	ret = msm_gem_pin_vma_locked(obj, vma);
+	if (!ret) {
+		*iova = vma->iova;
+		pin_obj_locked(obj);
+	}
+
+	return ret;
+}
+
+/*
+ * get iova and pin it. Should have a matching put
+ * limits iova to specified range (in pages)
+ */
+int msm_gem_get_and_pin_iova_range(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace, uint64_t *iova,
+		u64 range_start, u64 range_end)
+{
+	int ret;
+
+	msm_gem_lock(obj);
+	ret = get_and_pin_iova_range_locked(obj, aspace, iova, range_start, range_end);
+	msm_gem_unlock(obj);
+
+	return ret;
+}
+
+/* get iova and pin it. Should have a matching put */
+int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace, uint64_t *iova)
+{
+	return msm_gem_get_and_pin_iova_range(obj, aspace, iova, 0, U64_MAX);
+}
+
+/*
+ * Get an iova but don't pin it. Doesn't need a put because iovas are currently
+ * valid for the life of the object
+ */
+int msm_gem_get_iova(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace, uint64_t *iova)
+{
+	struct msm_gem_vma *vma;
+	int ret = 0;
+
+	msm_gem_lock(obj);
+	vma = get_vma_locked(obj, aspace, 0, U64_MAX);
+	if (IS_ERR(vma)) {
+		ret = PTR_ERR(vma);
+	} else {
+		*iova = vma->iova;
+	}
+	msm_gem_unlock(obj);
+
+	return ret;
+}
+
+static int clear_iova(struct drm_gem_object *obj,
+		      struct msm_gem_address_space *aspace)
+{
+	struct msm_gem_vma *vma = lookup_vma(obj, aspace);
+
+	if (!vma)
+		return 0;
+
+	msm_gem_vma_purge(vma);
+	msm_gem_vma_close(vma);
+	del_vma(vma);
+
+	return 0;
+}
+
+/*
+ * Get the requested iova but don't pin it.  Fails if the requested iova is
+ * not available.  Doesn't need a put because iovas are currently valid for
+ * the life of the object.
+ *
+ * Setting an iova of zero will clear the vma.
+ */
+int msm_gem_set_iova(struct drm_gem_object *obj,
+		     struct msm_gem_address_space *aspace, uint64_t iova)
+{
+	int ret = 0;
+
+	msm_gem_lock(obj);
+	if (!iova) {
+		ret = clear_iova(obj, aspace);
+	} else {
+		struct msm_gem_vma *vma;
+		vma = get_vma_locked(obj, aspace, iova, iova + obj->size);
+		if (IS_ERR(vma)) {
+			ret = PTR_ERR(vma);
+		} else if (GEM_WARN_ON(vma->iova != iova)) {
+			clear_iova(obj, aspace);
+			ret = -EBUSY;
+		}
+	}
+	msm_gem_unlock(obj);
+
+	return ret;
+}
+
+/*
+ * Unpin a iova by updating the reference counts. The memory isn't actually
+ * purged until something else (shrinker, mm_notifier, destroy, etc) decides
+ * to get rid of it
+ */
+void msm_gem_unpin_iova(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace)
+{
+	struct msm_gem_vma *vma;
+
+	msm_gem_lock(obj);
+	vma = lookup_vma(obj, aspace);
+	if (!GEM_WARN_ON(!vma)) {
+		msm_gem_unpin_locked(obj);
+	}
+	msm_gem_unlock(obj);
+}
+
+int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
+		struct drm_mode_create_dumb *args)
+{
+	args->pitch = align_pitch(args->width, args->bpp);
+	args->size  = PAGE_ALIGN(args->pitch * args->height);
+	return msm_gem_new_handle(dev, file, args->size,
+			MSM_BO_SCANOUT | MSM_BO_WC, &args->handle, "dumb");
+}
+
+int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
+		uint32_t handle, uint64_t *offset)
+{
+	struct drm_gem_object *obj;
+	int ret = 0;
+
+	/* GEM does all our handle to object mapping */
+	obj = drm_gem_object_lookup(file, handle);
+	if (obj == NULL) {
+		ret = -ENOENT;
+		goto fail;
+	}
+
+	*offset = msm_gem_mmap_offset(obj);
+
+	drm_gem_object_put(obj);
+
+fail:
+	return ret;
+}
+
+static void *get_vaddr(struct drm_gem_object *obj, unsigned madv)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	struct page **pages;
+	int ret = 0;
+
+	msm_gem_assert_locked(obj);
+
+	if (obj->import_attach)
+		return ERR_PTR(-ENODEV);
+
+	pages = msm_gem_pin_pages_locked(obj, madv);
+	if (IS_ERR(pages))
+		return ERR_CAST(pages);
+
+	pin_obj_locked(obj);
+
+	/* increment vmap_count *before* vmap() call, so shrinker can
+	 * check vmap_count (is_vunmapable()) outside of msm_obj lock.
+	 * This guarantees that we won't try to msm_gem_vunmap() this
+	 * same object from within the vmap() call (while we already
+	 * hold msm_obj lock)
+	 */
+	msm_obj->vmap_count++;
+
+	if (!msm_obj->vaddr) {
+		msm_obj->vaddr = vmap(pages, obj->size >> PAGE_SHIFT,
+				VM_MAP, msm_gem_pgprot(msm_obj, PAGE_KERNEL));
+		if (msm_obj->vaddr == NULL) {
+			ret = -ENOMEM;
+			goto fail;
+		}
+	}
+
+	return msm_obj->vaddr;
+
+fail:
+	msm_obj->vmap_count--;
+	msm_gem_unpin_locked(obj);
+	return ERR_PTR(ret);
+}
+
+void *msm_gem_get_vaddr_locked(struct drm_gem_object *obj)
+{
+	return get_vaddr(obj, MSM_MADV_WILLNEED);
+}
+
+void *msm_gem_get_vaddr(struct drm_gem_object *obj)
+{
+	void *ret;
+
+	msm_gem_lock(obj);
+	ret = msm_gem_get_vaddr_locked(obj);
+	msm_gem_unlock(obj);
+
+	return ret;
+}
+
+/*
+ * Don't use this!  It is for the very special case of dumping
+ * submits from GPU hangs or faults, were the bo may already
+ * be MSM_MADV_DONTNEED, but we know the buffer is still on the
+ * active list.
+ */
+void *msm_gem_get_vaddr_active(struct drm_gem_object *obj)
+{
+	return get_vaddr(obj, __MSM_MADV_PURGED);
+}
+
+void msm_gem_put_vaddr_locked(struct drm_gem_object *obj)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+	msm_gem_assert_locked(obj);
+	GEM_WARN_ON(msm_obj->vmap_count < 1);
+
+	msm_obj->vmap_count--;
+	msm_gem_unpin_locked(obj);
+}
+
+void msm_gem_put_vaddr(struct drm_gem_object *obj)
+{
+	msm_gem_lock(obj);
+	msm_gem_put_vaddr_locked(obj);
+	msm_gem_unlock(obj);
+}
+
+/* Update madvise status, returns true if not purged, else
+ * false or -errno.
+ */
+int msm_gem_madvise(struct drm_gem_object *obj, unsigned madv)
+{
+	struct msm_drm_private *priv = obj->dev->dev_private;
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+	msm_gem_lock(obj);
+
+	mutex_lock(&priv->lru.lock);
+
+	if (msm_obj->madv != __MSM_MADV_PURGED)
+		msm_obj->madv = madv;
+
+	madv = msm_obj->madv;
+
+	/* If the obj is inactive, we might need to move it
+	 * between inactive lists
+	 */
+	update_lru_locked(obj);
+
+	mutex_unlock(&priv->lru.lock);
+
+	msm_gem_unlock(obj);
+
+	return (madv != __MSM_MADV_PURGED);
+}
+
+void msm_gem_purge(struct drm_gem_object *obj)
+{
+	struct drm_device *dev = obj->dev;
+	struct msm_drm_private *priv = obj->dev->dev_private;
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+	msm_gem_assert_locked(obj);
+	GEM_WARN_ON(!is_purgeable(msm_obj));
+
+	/* Get rid of any iommu mapping(s): */
+	put_iova_spaces(obj, true);
+
+	msm_gem_vunmap(obj);
+
+	drm_vma_node_unmap(&obj->vma_node, dev->anon_inode->i_mapping);
+
+	put_pages(obj);
+
+	put_iova_vmas(obj);
+
+	mutex_lock(&priv->lru.lock);
+	/* A one-way transition: */
+	msm_obj->madv = __MSM_MADV_PURGED;
+	mutex_unlock(&priv->lru.lock);
+
+	drm_gem_free_mmap_offset(obj);
+
+	/* Our goal here is to return as much of the memory as
+	 * is possible back to the system as we are called from OOM.
+	 * To do this we must instruct the shmfs to drop all of its
+	 * backing pages, *now*.
+	 */
+	shmem_truncate_range(file_inode(obj->filp), 0, (loff_t)-1);
+
+	invalidate_mapping_pages(file_inode(obj->filp)->i_mapping,
+			0, (loff_t)-1);
+}
+
+/*
+ * Unpin the backing pages and make them available to be swapped out.
+ */
+void msm_gem_evict(struct drm_gem_object *obj)
+{
+	struct drm_device *dev = obj->dev;
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+	msm_gem_assert_locked(obj);
+	GEM_WARN_ON(is_unevictable(msm_obj));
+
+	/* Get rid of any iommu mapping(s): */
+	put_iova_spaces(obj, false);
+
+	drm_vma_node_unmap(&obj->vma_node, dev->anon_inode->i_mapping);
+
+	put_pages(obj);
+}
+
+void msm_gem_vunmap(struct drm_gem_object *obj)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+	msm_gem_assert_locked(obj);
+
+	if (!msm_obj->vaddr || GEM_WARN_ON(!is_vunmapable(msm_obj)))
+		return;
+
+	vunmap(msm_obj->vaddr);
+	msm_obj->vaddr = NULL;
+}
+
+bool msm_gem_active(struct drm_gem_object *obj)
+{
+	msm_gem_assert_locked(obj);
+
+	if (to_msm_bo(obj)->pin_count)
+		return true;
+
+	return !dma_resv_test_signaled(obj->resv, dma_resv_usage_rw(true));
+}
+
+int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, ktime_t *timeout)
+{
+	bool write = !!(op & MSM_PREP_WRITE);
+	unsigned long remain =
+		op & MSM_PREP_NOSYNC ? 0 : timeout_to_jiffies(timeout);
+	long ret;
+
+	if (op & MSM_PREP_BOOST) {
+		dma_resv_set_deadline(obj->resv, dma_resv_usage_rw(write),
+				      ktime_get());
+	}
+
+	ret = dma_resv_wait_timeout(obj->resv, dma_resv_usage_rw(write),
+				    true,  remain);
+	if (ret == 0)
+		return remain == 0 ? -EBUSY : -ETIMEDOUT;
+	else if (ret < 0)
+		return ret;
+
+	/* TODO cache maintenance */
+
+	return 0;
+}
+
+int msm_gem_cpu_fini(struct drm_gem_object *obj)
+{
+	/* TODO cache maintenance */
+	return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m,
+		struct msm_gem_stats *stats)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	struct dma_resv *robj = obj->resv;
+	struct msm_gem_vma *vma;
+	uint64_t off = drm_vma_node_start(&obj->vma_node);
+	const char *madv;
+
+	msm_gem_lock(obj);
+
+	stats->all.count++;
+	stats->all.size += obj->size;
+
+	if (msm_gem_active(obj)) {
+		stats->active.count++;
+		stats->active.size += obj->size;
+	}
+
+	if (msm_obj->pages) {
+		stats->resident.count++;
+		stats->resident.size += obj->size;
+	}
+
+	switch (msm_obj->madv) {
+	case __MSM_MADV_PURGED:
+		stats->purged.count++;
+		stats->purged.size += obj->size;
+		madv = " purged";
+		break;
+	case MSM_MADV_DONTNEED:
+		stats->purgeable.count++;
+		stats->purgeable.size += obj->size;
+		madv = " purgeable";
+		break;
+	case MSM_MADV_WILLNEED:
+	default:
+		madv = "";
+		break;
+	}
+
+	seq_printf(m, "%08x: %c %2d (%2d) %08llx %p",
+			msm_obj->flags, msm_gem_active(obj) ? 'A' : 'I',
+			obj->name, kref_read(&obj->refcount),
+			off, msm_obj->vaddr);
+
+	seq_printf(m, " %08zu %9s %-32s\n", obj->size, madv, msm_obj->name);
+
+	if (!list_empty(&msm_obj->vmas)) {
+
+		seq_puts(m, "      vmas:");
+
+		list_for_each_entry(vma, &msm_obj->vmas, list) {
+			const char *name, *comm;
+			if (vma->aspace) {
+				struct msm_gem_address_space *aspace = vma->aspace;
+				struct task_struct *task =
+					get_pid_task(aspace->pid, PIDTYPE_PID);
+				if (task) {
+					comm = kstrdup(task->comm, GFP_KERNEL);
+					put_task_struct(task);
+				} else {
+					comm = NULL;
+				}
+				name = aspace->name;
+			} else {
+				name = comm = NULL;
+			}
+			seq_printf(m, " [%s%s%s: aspace=%p, %08llx,%s]",
+				name, comm ? ":" : "", comm ? comm : "",
+				vma->aspace, vma->iova,
+				vma->mapped ? "mapped" : "unmapped");
+			kfree(comm);
+		}
+
+		seq_puts(m, "\n");
+	}
+
+	dma_resv_describe(robj, m);
+	msm_gem_unlock(obj);
+}
+
+void msm_gem_describe_objects(struct list_head *list, struct seq_file *m)
+{
+	struct msm_gem_stats stats = {};
+	struct msm_gem_object *msm_obj;
+
+	seq_puts(m, "   flags       id ref  offset   kaddr            size     madv      name\n");
+	list_for_each_entry(msm_obj, list, node) {
+		struct drm_gem_object *obj = &msm_obj->base;
+		seq_puts(m, "   ");
+		msm_gem_describe(obj, m, &stats);
+	}
+
+	seq_printf(m, "Total:     %4d objects, %9zu bytes\n",
+			stats.all.count, stats.all.size);
+	seq_printf(m, "Active:    %4d objects, %9zu bytes\n",
+			stats.active.count, stats.active.size);
+	seq_printf(m, "Resident:  %4d objects, %9zu bytes\n",
+			stats.resident.count, stats.resident.size);
+	seq_printf(m, "Purgeable: %4d objects, %9zu bytes\n",
+			stats.purgeable.count, stats.purgeable.size);
+	seq_printf(m, "Purged:    %4d objects, %9zu bytes\n",
+			stats.purged.count, stats.purged.size);
+}
+#endif
+
+/* don't call directly!  Use drm_gem_object_put() */
+static void msm_gem_free_object(struct drm_gem_object *obj)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	struct drm_device *dev = obj->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+
+	mutex_lock(&priv->obj_lock);
+	list_del(&msm_obj->node);
+	mutex_unlock(&priv->obj_lock);
+
+	put_iova_spaces(obj, true);
+
+	if (obj->import_attach) {
+		GEM_WARN_ON(msm_obj->vaddr);
+
+		/* Don't drop the pages for imported dmabuf, as they are not
+		 * ours, just free the array we allocated:
+		 */
+		kvfree(msm_obj->pages);
+
+		put_iova_vmas(obj);
+
+		drm_prime_gem_destroy(obj, msm_obj->sgt);
+	} else {
+		msm_gem_vunmap(obj);
+		put_pages(obj);
+		put_iova_vmas(obj);
+	}
+
+	drm_gem_object_release(obj);
+
+	kfree(msm_obj->metadata);
+	kfree(msm_obj);
+}
+
+static int msm_gem_object_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+	vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
+	vma->vm_page_prot = msm_gem_pgprot(msm_obj, vm_get_page_prot(vma->vm_flags));
+
+	return 0;
+}
+
+/* convenience method to construct a GEM buffer object, and userspace handle */
+int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
+		uint32_t size, uint32_t flags, uint32_t *handle,
+		char *name)
+{
+	struct drm_gem_object *obj;
+	int ret;
+
+	obj = msm_gem_new(dev, size, flags);
+
+	if (IS_ERR(obj))
+		return PTR_ERR(obj);
+
+	if (name)
+		msm_gem_object_set_name(obj, "%s", name);
+
+	ret = drm_gem_handle_create(file, obj, handle);
+
+	/* drop reference from allocate - handle holds it now */
+	drm_gem_object_put(obj);
+
+	return ret;
+}
+
+static enum drm_gem_object_status msm_gem_status(struct drm_gem_object *obj)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	enum drm_gem_object_status status = 0;
+
+	if (msm_obj->pages)
+		status |= DRM_GEM_OBJECT_RESIDENT;
+
+	if (msm_obj->madv == MSM_MADV_DONTNEED)
+		status |= DRM_GEM_OBJECT_PURGEABLE;
+
+	return status;
+}
+
+static const struct vm_operations_struct vm_ops = {
+	.fault = msm_gem_fault,
+	.open = drm_gem_vm_open,
+	.close = drm_gem_vm_close,
+};
+
+static const struct drm_gem_object_funcs msm_gem_object_funcs = {
+	.free = msm_gem_free_object,
+	.pin = msm_gem_prime_pin,
+	.unpin = msm_gem_prime_unpin,
+	.get_sg_table = msm_gem_prime_get_sg_table,
+	.vmap = msm_gem_prime_vmap,
+	.vunmap = msm_gem_prime_vunmap,
+	.mmap = msm_gem_object_mmap,
+	.status = msm_gem_status,
+	.vm_ops = &vm_ops,
+};
+
+static int msm_gem_new_impl(struct drm_device *dev,
+		uint32_t size, uint32_t flags,
+		struct drm_gem_object **obj)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_gem_object *msm_obj;
+
+	switch (flags & MSM_BO_CACHE_MASK) {
+	case MSM_BO_CACHED:
+	case MSM_BO_WC:
+		break;
+	case MSM_BO_CACHED_COHERENT:
+		if (priv->has_cached_coherent)
+			break;
+		fallthrough;
+	default:
+		DRM_DEV_DEBUG(dev->dev, "invalid cache flag: %x\n",
+				(flags & MSM_BO_CACHE_MASK));
+		return -EINVAL;
+	}
+
+	msm_obj = kzalloc(sizeof(*msm_obj), GFP_KERNEL);
+	if (!msm_obj)
+		return -ENOMEM;
+
+	msm_obj->flags = flags;
+	msm_obj->madv = MSM_MADV_WILLNEED;
+
+	INIT_LIST_HEAD(&msm_obj->node);
+	INIT_LIST_HEAD(&msm_obj->vmas);
+
+	*obj = &msm_obj->base;
+	(*obj)->funcs = &msm_gem_object_funcs;
+
+	return 0;
+}
+
+struct drm_gem_object *msm_gem_new(struct drm_device *dev, uint32_t size, uint32_t flags)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_gem_object *msm_obj;
+	struct drm_gem_object *obj = NULL;
+	bool use_vram = false;
+	int ret;
+
+	size = PAGE_ALIGN(size);
+
+	if (!msm_use_mmu(dev))
+		use_vram = true;
+	else if ((flags & (MSM_BO_STOLEN | MSM_BO_SCANOUT)) && priv->vram.size)
+		use_vram = true;
+
+	if (GEM_WARN_ON(use_vram && !priv->vram.size))
+		return ERR_PTR(-EINVAL);
+
+	/* Disallow zero sized objects as they make the underlying
+	 * infrastructure grumpy
+	 */
+	if (size == 0)
+		return ERR_PTR(-EINVAL);
+
+	ret = msm_gem_new_impl(dev, size, flags, &obj);
+	if (ret)
+		return ERR_PTR(ret);
+
+	msm_obj = to_msm_bo(obj);
+
+	if (use_vram) {
+		struct msm_gem_vma *vma;
+		struct page **pages;
+
+		drm_gem_private_object_init(dev, obj, size);
+
+		msm_gem_lock(obj);
+
+		vma = add_vma(obj, NULL);
+		msm_gem_unlock(obj);
+		if (IS_ERR(vma)) {
+			ret = PTR_ERR(vma);
+			goto fail;
+		}
+
+		to_msm_bo(obj)->vram_node = &vma->node;
+
+		msm_gem_lock(obj);
+		pages = get_pages(obj);
+		msm_gem_unlock(obj);
+		if (IS_ERR(pages)) {
+			ret = PTR_ERR(pages);
+			goto fail;
+		}
+
+		vma->iova = physaddr(obj);
+	} else {
+		ret = drm_gem_object_init(dev, obj, size);
+		if (ret)
+			goto fail;
+		/*
+		 * Our buffers are kept pinned, so allocating them from the
+		 * MOVABLE zone is a really bad idea, and conflicts with CMA.
+		 * See comments above new_inode() why this is required _and_
+		 * expected if you're going to pin these pages.
+		 */
+		mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER);
+	}
+
+	drm_gem_lru_move_tail(&priv->lru.unbacked, obj);
+
+	mutex_lock(&priv->obj_lock);
+	list_add_tail(&msm_obj->node, &priv->objects);
+	mutex_unlock(&priv->obj_lock);
+
+	ret = drm_gem_create_mmap_offset(obj);
+	if (ret)
+		goto fail;
+
+	return obj;
+
+fail:
+	drm_gem_object_put(obj);
+	return ERR_PTR(ret);
+}
+
+struct drm_gem_object *msm_gem_import(struct drm_device *dev,
+		struct dma_buf *dmabuf, struct sg_table *sgt)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_gem_object *msm_obj;
+	struct drm_gem_object *obj;
+	uint32_t size;
+	int ret, npages;
+
+	/* if we don't have IOMMU, don't bother pretending we can import: */
+	if (!msm_use_mmu(dev)) {
+		DRM_DEV_ERROR(dev->dev, "cannot import without IOMMU\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	size = PAGE_ALIGN(dmabuf->size);
+
+	ret = msm_gem_new_impl(dev, size, MSM_BO_WC, &obj);
+	if (ret)
+		return ERR_PTR(ret);
+
+	drm_gem_private_object_init(dev, obj, size);
+
+	npages = size / PAGE_SIZE;
+
+	msm_obj = to_msm_bo(obj);
+	msm_gem_lock(obj);
+	msm_obj->sgt = sgt;
+	msm_obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
+	if (!msm_obj->pages) {
+		msm_gem_unlock(obj);
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	ret = drm_prime_sg_to_page_array(sgt, msm_obj->pages, npages);
+	if (ret) {
+		msm_gem_unlock(obj);
+		goto fail;
+	}
+
+	msm_gem_unlock(obj);
+
+	drm_gem_lru_move_tail(&priv->lru.pinned, obj);
+
+	mutex_lock(&priv->obj_lock);
+	list_add_tail(&msm_obj->node, &priv->objects);
+	mutex_unlock(&priv->obj_lock);
+
+	ret = drm_gem_create_mmap_offset(obj);
+	if (ret)
+		goto fail;
+
+	return obj;
+
+fail:
+	drm_gem_object_put(obj);
+	return ERR_PTR(ret);
+}
+
+void *msm_gem_kernel_new(struct drm_device *dev, uint32_t size,
+		uint32_t flags, struct msm_gem_address_space *aspace,
+		struct drm_gem_object **bo, uint64_t *iova)
+{
+	void *vaddr;
+	struct drm_gem_object *obj = msm_gem_new(dev, size, flags);
+	int ret;
+
+	if (IS_ERR(obj))
+		return ERR_CAST(obj);
+
+	if (iova) {
+		ret = msm_gem_get_and_pin_iova(obj, aspace, iova);
+		if (ret)
+			goto err;
+	}
+
+	vaddr = msm_gem_get_vaddr(obj);
+	if (IS_ERR(vaddr)) {
+		msm_gem_unpin_iova(obj, aspace);
+		ret = PTR_ERR(vaddr);
+		goto err;
+	}
+
+	if (bo)
+		*bo = obj;
+
+	return vaddr;
+err:
+	drm_gem_object_put(obj);
+
+	return ERR_PTR(ret);
+
+}
+
+void msm_gem_kernel_put(struct drm_gem_object *bo,
+		struct msm_gem_address_space *aspace)
+{
+	if (IS_ERR_OR_NULL(bo))
+		return;
+
+	msm_gem_put_vaddr(bo);
+	msm_gem_unpin_iova(bo, aspace);
+	drm_gem_object_put(bo);
+}
+
+void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(bo);
+	va_list ap;
+
+	if (!fmt)
+		return;
+
+	va_start(ap, fmt);
+	vsnprintf(msm_obj->name, sizeof(msm_obj->name), fmt, ap);
+	va_end(ap);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_gem.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_gem.h
@@ -0,0 +1,333 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __MSM_GEM_H__
+#define __MSM_GEM_H__
+
+#include <linux/kref.h>
+#include <linux/dma-resv.h>
+#include "drm/drm_exec.h"
+#include "drm/gpu_scheduler.h"
+#include "msm_drv.h"
+
+/* Make all GEM related WARN_ON()s ratelimited.. when things go wrong they
+ * tend to go wrong 1000s of times in a short timespan.
+ */
+#define GEM_WARN_ON(x)  WARN_RATELIMIT(x, "%s", __stringify(x))
+
+/* Additional internal-use only BO flags: */
+#define MSM_BO_STOLEN        0x10000000    /* try to use stolen/splash memory */
+#define MSM_BO_MAP_PRIV      0x20000000    /* use IOMMU_PRIV when mapping */
+
+struct msm_gem_address_space {
+	const char *name;
+	/* NOTE: mm managed at the page level, size is in # of pages
+	 * and position mm_node->start is in # of pages:
+	 */
+	struct drm_mm mm;
+	spinlock_t lock; /* Protects drm_mm node allocation/removal */
+	struct msm_mmu *mmu;
+	struct kref kref;
+
+	/* For address spaces associated with a specific process, this
+	 * will be non-NULL:
+	 */
+	struct pid *pid;
+
+	/* @faults: the number of GPU hangs associated with this address space */
+	int faults;
+
+	/** @va_start: lowest possible address to allocate */
+	uint64_t va_start;
+
+	/** @va_size: the size of the address space (in bytes) */
+	uint64_t va_size;
+};
+
+struct msm_gem_address_space *
+msm_gem_address_space_get(struct msm_gem_address_space *aspace);
+
+void msm_gem_address_space_put(struct msm_gem_address_space *aspace);
+
+struct msm_gem_address_space *
+msm_gem_address_space_create(struct msm_mmu *mmu, const char *name,
+		u64 va_start, u64 size);
+
+struct msm_fence_context;
+
+struct msm_gem_vma {
+	struct drm_mm_node node;
+	uint64_t iova;
+	struct msm_gem_address_space *aspace;
+	struct list_head list;    /* node in msm_gem_object::vmas */
+	bool mapped;
+};
+
+struct msm_gem_vma *msm_gem_vma_new(struct msm_gem_address_space *aspace);
+int msm_gem_vma_init(struct msm_gem_vma *vma, int size,
+		u64 range_start, u64 range_end);
+void msm_gem_vma_purge(struct msm_gem_vma *vma);
+int msm_gem_vma_map(struct msm_gem_vma *vma, int prot, struct sg_table *sgt, int size);
+void msm_gem_vma_close(struct msm_gem_vma *vma);
+
+struct msm_gem_object {
+	struct drm_gem_object base;
+
+	uint32_t flags;
+
+	/**
+	 * madv: are the backing pages purgeable?
+	 *
+	 * Protected by obj lock and LRU lock
+	 */
+	uint8_t madv;
+
+	/**
+	 * count of active vmap'ing
+	 */
+	uint8_t vmap_count;
+
+	/**
+	 * Node in list of all objects (mainly for debugfs, protected by
+	 * priv->obj_lock
+	 */
+	struct list_head node;
+
+	struct page **pages;
+	struct sg_table *sgt;
+	void *vaddr;
+
+	struct list_head vmas;    /* list of msm_gem_vma */
+
+	/* For physically contiguous buffers.  Used when we don't have
+	 * an IOMMU.  Also used for stolen/splashscreen buffer.
+	 */
+	struct drm_mm_node *vram_node;
+
+	char name[32]; /* Identifier to print for the debugfs files */
+
+	/* userspace metadata backchannel */
+	void *metadata;
+	u32 metadata_size;
+
+	/**
+	 * pin_count: Number of times the pages are pinned
+	 *
+	 * Protected by LRU lock.
+	 */
+	int pin_count;
+};
+#define to_msm_bo(x) container_of(x, struct msm_gem_object, base)
+
+uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj);
+int msm_gem_pin_vma_locked(struct drm_gem_object *obj, struct msm_gem_vma *vma);
+void msm_gem_unpin_locked(struct drm_gem_object *obj);
+void msm_gem_unpin_active(struct drm_gem_object *obj);
+struct msm_gem_vma *msm_gem_get_vma_locked(struct drm_gem_object *obj,
+					   struct msm_gem_address_space *aspace);
+int msm_gem_get_iova(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace, uint64_t *iova);
+int msm_gem_set_iova(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace, uint64_t iova);
+int msm_gem_get_and_pin_iova_range(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace, uint64_t *iova,
+		u64 range_start, u64 range_end);
+int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace, uint64_t *iova);
+void msm_gem_unpin_iova(struct drm_gem_object *obj,
+		struct msm_gem_address_space *aspace);
+void msm_gem_pin_obj_locked(struct drm_gem_object *obj);
+struct page **msm_gem_pin_pages(struct drm_gem_object *obj);
+void msm_gem_unpin_pages(struct drm_gem_object *obj);
+int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
+		struct drm_mode_create_dumb *args);
+int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
+		uint32_t handle, uint64_t *offset);
+void *msm_gem_get_vaddr_locked(struct drm_gem_object *obj);
+void *msm_gem_get_vaddr(struct drm_gem_object *obj);
+void *msm_gem_get_vaddr_active(struct drm_gem_object *obj);
+void msm_gem_put_vaddr_locked(struct drm_gem_object *obj);
+void msm_gem_put_vaddr(struct drm_gem_object *obj);
+int msm_gem_madvise(struct drm_gem_object *obj, unsigned madv);
+bool msm_gem_active(struct drm_gem_object *obj);
+int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, ktime_t *timeout);
+int msm_gem_cpu_fini(struct drm_gem_object *obj);
+int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
+		uint32_t size, uint32_t flags, uint32_t *handle, char *name);
+struct drm_gem_object *msm_gem_new(struct drm_device *dev,
+		uint32_t size, uint32_t flags);
+void *msm_gem_kernel_new(struct drm_device *dev, uint32_t size,
+		uint32_t flags, struct msm_gem_address_space *aspace,
+		struct drm_gem_object **bo, uint64_t *iova);
+void msm_gem_kernel_put(struct drm_gem_object *bo,
+		struct msm_gem_address_space *aspace);
+struct drm_gem_object *msm_gem_import(struct drm_device *dev,
+		struct dma_buf *dmabuf, struct sg_table *sgt);
+__printf(2, 3)
+void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...);
+
+#ifdef CONFIG_DEBUG_FS
+struct msm_gem_stats {
+	struct {
+		unsigned count;
+		size_t size;
+	} all, active, resident, purgeable, purged;
+};
+
+void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m,
+		struct msm_gem_stats *stats);
+void msm_gem_describe_objects(struct list_head *list, struct seq_file *m);
+#endif
+
+static inline void
+msm_gem_lock(struct drm_gem_object *obj)
+{
+	dma_resv_lock(obj->resv, NULL);
+}
+
+static inline int
+msm_gem_lock_interruptible(struct drm_gem_object *obj)
+{
+	return dma_resv_lock_interruptible(obj->resv, NULL);
+}
+
+static inline void
+msm_gem_unlock(struct drm_gem_object *obj)
+{
+	dma_resv_unlock(obj->resv);
+}
+
+static inline void
+msm_gem_assert_locked(struct drm_gem_object *obj)
+{
+	/*
+	 * Destroying the object is a special case.. msm_gem_free_object()
+	 * calls many things that WARN_ON if the obj lock is not held.  But
+	 * acquiring the obj lock in msm_gem_free_object() can cause a
+	 * locking order inversion between reservation_ww_class_mutex and
+	 * fs_reclaim.
+	 *
+	 * This deadlock is not actually possible, because no one should
+	 * be already holding the lock when msm_gem_free_object() is called.
+	 * Unfortunately lockdep is not aware of this detail.  So when the
+	 * refcount drops to zero, we pretend it is already locked.
+	 */
+	lockdep_assert_once(
+		(kref_read(&obj->refcount) == 0) ||
+		(lockdep_is_held(&obj->resv->lock.base) != LOCK_STATE_NOT_HELD)
+	);
+}
+
+/* imported/exported objects are not purgeable: */
+static inline bool is_unpurgeable(struct msm_gem_object *msm_obj)
+{
+	return msm_obj->base.import_attach || msm_obj->pin_count;
+}
+
+static inline bool is_purgeable(struct msm_gem_object *msm_obj)
+{
+	return (msm_obj->madv == MSM_MADV_DONTNEED) && msm_obj->sgt &&
+			!is_unpurgeable(msm_obj);
+}
+
+static inline bool is_vunmapable(struct msm_gem_object *msm_obj)
+{
+	msm_gem_assert_locked(&msm_obj->base);
+	return (msm_obj->vmap_count == 0) && msm_obj->vaddr;
+}
+
+static inline bool is_unevictable(struct msm_gem_object *msm_obj)
+{
+	return is_unpurgeable(msm_obj) || msm_obj->vaddr;
+}
+
+void msm_gem_purge(struct drm_gem_object *obj);
+void msm_gem_evict(struct drm_gem_object *obj);
+void msm_gem_vunmap(struct drm_gem_object *obj);
+
+/* Created per submit-ioctl, to track bo's and cmdstream bufs, etc,
+ * associated with the cmdstream submission for synchronization (and
+ * make it easier to unwind when things go wrong, etc).
+ */
+struct msm_gem_submit {
+	struct drm_sched_job base;
+	struct kref ref;
+	struct drm_device *dev;
+	struct msm_gpu *gpu;
+	struct msm_gem_address_space *aspace;
+	struct list_head node;   /* node in ring submit list */
+	struct drm_exec exec;
+	uint32_t seqno;		/* Sequence number of the submit on the ring */
+
+	/* Hw fence, which is created when the scheduler executes the job, and
+	 * is signaled when the hw finishes (via seqno write from cmdstream)
+	 */
+	struct dma_fence *hw_fence;
+
+	/* Userspace visible fence, which is signaled by the scheduler after
+	 * the hw_fence is signaled.
+	 */
+	struct dma_fence *user_fence;
+
+	int fence_id;       /* key into queue->fence_idr */
+	struct msm_gpu_submitqueue *queue;
+	struct pid *pid;    /* submitting process */
+	bool bos_pinned : 1;
+	bool fault_dumped:1;/* Limit devcoredump dumping to one per submit */
+	bool in_rb : 1;     /* "sudo" mode, copy cmds into RB */
+	struct msm_ringbuffer *ring;
+	unsigned int nr_cmds;
+	unsigned int nr_bos;
+	u32 ident;	   /* A "identifier" for the submit for logging */
+	struct {
+		uint32_t type;
+		uint32_t size;  /* in dwords */
+		uint64_t iova;
+		uint32_t offset;/* in dwords */
+		uint32_t idx;   /* cmdstream buffer idx in bos[] */
+		uint32_t nr_relocs;
+		struct drm_msm_gem_submit_reloc *relocs;
+	} *cmd;  /* array of size nr_cmds */
+	struct {
+		uint32_t flags;
+		union {
+			struct drm_gem_object *obj;
+			uint32_t handle;
+		};
+		uint64_t iova;
+	} bos[];
+};
+
+static inline struct msm_gem_submit *to_msm_submit(struct drm_sched_job *job)
+{
+	return container_of(job, struct msm_gem_submit, base);
+}
+
+void __msm_gem_submit_destroy(struct kref *kref);
+
+static inline void msm_gem_submit_get(struct msm_gem_submit *submit)
+{
+	kref_get(&submit->ref);
+}
+
+static inline void msm_gem_submit_put(struct msm_gem_submit *submit)
+{
+	kref_put(&submit->ref, __msm_gem_submit_destroy);
+}
+
+void msm_submit_retire(struct msm_gem_submit *submit);
+
+/* helper to determine of a buffer in submit should be dumped, used for both
+ * devcoredump and debugfs cmdstream dumping:
+ */
+static inline bool
+should_dump(struct msm_gem_submit *submit, int idx)
+{
+	extern bool rd_full;
+	return rd_full || (submit->bos[idx].flags & MSM_SUBMIT_BO_DUMP);
+}
+
+#endif /* __MSM_GEM_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_gem_prime.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_gem_prime.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/dma-buf.h>
+
+#include <drm/drm_prime.h>
+
+#include "msm_drv.h"
+#include "msm_gem.h"
+
+struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj)
+{
+	struct msm_gem_object *msm_obj = to_msm_bo(obj);
+	int npages = obj->size >> PAGE_SHIFT;
+
+	if (WARN_ON(!msm_obj->pages))  /* should have already pinned! */
+		return ERR_PTR(-ENOMEM);
+
+	return drm_prime_pages_to_sg(obj->dev, msm_obj->pages, npages);
+}
+
+int msm_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map)
+{
+	void *vaddr;
+
+	vaddr = msm_gem_get_vaddr_locked(obj);
+	if (IS_ERR(vaddr))
+		return PTR_ERR(vaddr);
+	iosys_map_set_vaddr(map, vaddr);
+
+	return 0;
+}
+
+void msm_gem_prime_vunmap(struct drm_gem_object *obj, struct iosys_map *map)
+{
+	msm_gem_put_vaddr_locked(obj);
+}
+
+struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
+		struct dma_buf_attachment *attach, struct sg_table *sg)
+{
+	return msm_gem_import(dev, attach->dmabuf, sg);
+}
+
+int msm_gem_prime_pin(struct drm_gem_object *obj)
+{
+	if (!obj->import_attach)
+		msm_gem_pin_pages(obj);
+	return 0;
+}
+
+void msm_gem_prime_unpin(struct drm_gem_object *obj)
+{
+	if (!obj->import_attach)
+		msm_gem_unpin_pages(obj);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_gem_shrinker.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_gem_shrinker.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2016 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/vmalloc.h>
+#include <linux/sched/mm.h>
+
+#include "msm_drv.h"
+#include "msm_gem.h"
+#include "msm_gpu.h"
+#include "msm_gpu_trace.h"
+
+/* Default disabled for now until it has some more testing on the different
+ * iommu combinations that can be paired with the driver:
+ */
+static bool enable_eviction = true;
+MODULE_PARM_DESC(enable_eviction, "Enable swappable GEM buffers");
+module_param(enable_eviction, bool, 0600);
+
+static bool can_swap(void)
+{
+	return enable_eviction && get_nr_swap_pages() > 0;
+}
+
+static bool can_block(struct shrink_control *sc)
+{
+	if (!(sc->gfp_mask & __GFP_DIRECT_RECLAIM))
+		return false;
+	return current_is_kswapd() || (sc->gfp_mask & __GFP_RECLAIM);
+}
+
+static unsigned long
+msm_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
+{
+	struct msm_drm_private *priv = shrinker->private_data;
+	unsigned count = priv->lru.dontneed.count;
+
+	if (can_swap())
+		count += priv->lru.willneed.count;
+
+	return count;
+}
+
+static bool
+purge(struct drm_gem_object *obj)
+{
+	if (!is_purgeable(to_msm_bo(obj)))
+		return false;
+
+	if (msm_gem_active(obj))
+		return false;
+
+	msm_gem_purge(obj);
+
+	return true;
+}
+
+static bool
+evict(struct drm_gem_object *obj)
+{
+	if (is_unevictable(to_msm_bo(obj)))
+		return false;
+
+	if (msm_gem_active(obj))
+		return false;
+
+	msm_gem_evict(obj);
+
+	return true;
+}
+
+static bool
+wait_for_idle(struct drm_gem_object *obj)
+{
+	enum dma_resv_usage usage = dma_resv_usage_rw(true);
+	return dma_resv_wait_timeout(obj->resv, usage, false, 10) > 0;
+}
+
+static bool
+active_purge(struct drm_gem_object *obj)
+{
+	if (!wait_for_idle(obj))
+		return false;
+
+	return purge(obj);
+}
+
+static bool
+active_evict(struct drm_gem_object *obj)
+{
+	if (!wait_for_idle(obj))
+		return false;
+
+	return evict(obj);
+}
+
+static unsigned long
+msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
+{
+	struct msm_drm_private *priv = shrinker->private_data;
+	struct {
+		struct drm_gem_lru *lru;
+		bool (*shrink)(struct drm_gem_object *obj);
+		bool cond;
+		unsigned long freed;
+		unsigned long remaining;
+	} stages[] = {
+		/* Stages of progressively more aggressive/expensive reclaim: */
+		{ &priv->lru.dontneed, purge,        true },
+		{ &priv->lru.willneed, evict,        can_swap() },
+		{ &priv->lru.dontneed, active_purge, can_block(sc) },
+		{ &priv->lru.willneed, active_evict, can_swap() && can_block(sc) },
+	};
+	long nr = sc->nr_to_scan;
+	unsigned long freed = 0;
+	unsigned long remaining = 0;
+
+	for (unsigned i = 0; (nr > 0) && (i < ARRAY_SIZE(stages)); i++) {
+		if (!stages[i].cond)
+			continue;
+		stages[i].freed =
+			drm_gem_lru_scan(stages[i].lru, nr,
+					&stages[i].remaining,
+					 stages[i].shrink);
+		nr -= stages[i].freed;
+		freed += stages[i].freed;
+		remaining += stages[i].remaining;
+	}
+
+	if (freed) {
+		trace_msm_gem_shrink(sc->nr_to_scan, stages[0].freed,
+				     stages[1].freed, stages[2].freed,
+				     stages[3].freed);
+	}
+
+	return (freed > 0 && remaining > 0) ? freed : SHRINK_STOP;
+}
+
+#ifdef CONFIG_DEBUG_FS
+unsigned long
+msm_gem_shrinker_shrink(struct drm_device *dev, unsigned long nr_to_scan)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct shrink_control sc = {
+		.nr_to_scan = nr_to_scan,
+	};
+	unsigned long ret = SHRINK_STOP;
+
+	fs_reclaim_acquire(GFP_KERNEL);
+	if (priv->shrinker)
+		ret = msm_gem_shrinker_scan(priv->shrinker, &sc);
+	fs_reclaim_release(GFP_KERNEL);
+
+	return ret;
+}
+#endif
+
+/* since we don't know any better, lets bail after a few
+ * and if necessary the shrinker will be invoked again.
+ * Seems better than unmapping *everything*
+ */
+static const int vmap_shrink_limit = 15;
+
+static bool
+vmap_shrink(struct drm_gem_object *obj)
+{
+	if (!is_vunmapable(to_msm_bo(obj)))
+		return false;
+
+	msm_gem_vunmap(obj);
+
+	return true;
+}
+
+static int
+msm_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr)
+{
+	struct msm_drm_private *priv =
+		container_of(nb, struct msm_drm_private, vmap_notifier);
+	struct drm_gem_lru *lrus[] = {
+		&priv->lru.dontneed,
+		&priv->lru.willneed,
+		&priv->lru.pinned,
+		NULL,
+	};
+	unsigned idx, unmapped = 0;
+	unsigned long remaining = 0;
+
+	for (idx = 0; lrus[idx] && unmapped < vmap_shrink_limit; idx++) {
+		unmapped += drm_gem_lru_scan(lrus[idx],
+					     vmap_shrink_limit - unmapped,
+					     &remaining,
+					     vmap_shrink);
+	}
+
+	*(unsigned long *)ptr += unmapped;
+
+	if (unmapped > 0)
+		trace_msm_gem_purge_vmaps(unmapped);
+
+	return NOTIFY_DONE;
+}
+
+/**
+ * msm_gem_shrinker_init - Initialize msm shrinker
+ * @dev: drm device
+ *
+ * This function registers and sets up the msm shrinker.
+ */
+int msm_gem_shrinker_init(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+
+	priv->shrinker = shrinker_alloc(0, "drm-msm_gem");
+	if (!priv->shrinker)
+		return -ENOMEM;
+
+	priv->shrinker->count_objects = msm_gem_shrinker_count;
+	priv->shrinker->scan_objects = msm_gem_shrinker_scan;
+	priv->shrinker->private_data = priv;
+
+	shrinker_register(priv->shrinker);
+
+	priv->vmap_notifier.notifier_call = msm_gem_shrinker_vmap;
+	WARN_ON(register_vmap_purge_notifier(&priv->vmap_notifier));
+
+	return 0;
+}
+
+/**
+ * msm_gem_shrinker_cleanup - Clean up msm shrinker
+ * @dev: drm device
+ *
+ * This function unregisters the msm shrinker.
+ */
+void msm_gem_shrinker_cleanup(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+
+	if (priv->shrinker) {
+		WARN_ON(unregister_vmap_purge_notifier(&priv->vmap_notifier));
+		shrinker_free(priv->shrinker);
+	}
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_gem_submit.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_gem_submit.c
@@ -0,0 +1,935 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/file.h>
+#include <linux/sync_file.h>
+#include <linux/uaccess.h>
+
+#include <drm/drm_drv.h>
+#include <drm/drm_file.h>
+#include <drm/drm_syncobj.h>
+
+#include "msm_drv.h"
+#include "msm_gpu.h"
+#include "msm_gem.h"
+#include "msm_gpu_trace.h"
+
+/* For userspace errors, use DRM_UT_DRIVER.. so that userspace can enable
+ * error msgs for debugging, but we don't spam dmesg by default
+ */
+#define SUBMIT_ERROR(submit, fmt, ...) \
+	DRM_DEV_DEBUG_DRIVER((submit)->dev->dev, fmt, ##__VA_ARGS__)
+
+/*
+ * Cmdstream submission:
+ */
+
+static struct msm_gem_submit *submit_create(struct drm_device *dev,
+		struct msm_gpu *gpu,
+		struct msm_gpu_submitqueue *queue, uint32_t nr_bos,
+		uint32_t nr_cmds)
+{
+	static atomic_t ident = ATOMIC_INIT(0);
+	struct msm_gem_submit *submit;
+	uint64_t sz;
+	int ret;
+
+	sz = struct_size(submit, bos, nr_bos) +
+			((u64)nr_cmds * sizeof(submit->cmd[0]));
+
+	if (sz > SIZE_MAX)
+		return ERR_PTR(-ENOMEM);
+
+	submit = kzalloc(sz, GFP_KERNEL | __GFP_NOWARN);
+	if (!submit)
+		return ERR_PTR(-ENOMEM);
+
+	submit->hw_fence = msm_fence_alloc();
+	if (IS_ERR(submit->hw_fence)) {
+		ret = PTR_ERR(submit->hw_fence);
+		kfree(submit);
+		return ERR_PTR(ret);
+	}
+
+	ret = drm_sched_job_init(&submit->base, queue->entity, 1, queue);
+	if (ret) {
+		kfree(submit->hw_fence);
+		kfree(submit);
+		return ERR_PTR(ret);
+	}
+
+	kref_init(&submit->ref);
+	submit->dev = dev;
+	submit->aspace = queue->ctx->aspace;
+	submit->gpu = gpu;
+	submit->cmd = (void *)&submit->bos[nr_bos];
+	submit->queue = queue;
+	submit->pid = get_pid(task_pid(current));
+	submit->ring = gpu->rb[queue->ring_nr];
+	submit->fault_dumped = false;
+
+	/* Get a unique identifier for the submission for logging purposes */
+	submit->ident = atomic_inc_return(&ident) - 1;
+
+	INIT_LIST_HEAD(&submit->node);
+
+	return submit;
+}
+
+void __msm_gem_submit_destroy(struct kref *kref)
+{
+	struct msm_gem_submit *submit =
+			container_of(kref, struct msm_gem_submit, ref);
+	unsigned i;
+
+	if (submit->fence_id) {
+		spin_lock(&submit->queue->idr_lock);
+		idr_remove(&submit->queue->fence_idr, submit->fence_id);
+		spin_unlock(&submit->queue->idr_lock);
+	}
+
+	dma_fence_put(submit->user_fence);
+
+	/*
+	 * If the submit is freed before msm_job_run(), then hw_fence is
+	 * just some pre-allocated memory, not a reference counted fence.
+	 * Once the job runs and the hw_fence is initialized, it will
+	 * have a refcount of at least one, since the submit holds a ref
+	 * to the hw_fence.
+	 */
+	if (kref_read(&submit->hw_fence->refcount) == 0) {
+		kfree(submit->hw_fence);
+	} else {
+		dma_fence_put(submit->hw_fence);
+	}
+
+	put_pid(submit->pid);
+	msm_submitqueue_put(submit->queue);
+
+	for (i = 0; i < submit->nr_cmds; i++)
+		kfree(submit->cmd[i].relocs);
+
+	kfree(submit);
+}
+
+static int submit_lookup_objects(struct msm_gem_submit *submit,
+		struct drm_msm_gem_submit *args, struct drm_file *file)
+{
+	unsigned i;
+	int ret = 0;
+
+	for (i = 0; i < args->nr_bos; i++) {
+		struct drm_msm_gem_submit_bo submit_bo;
+		void __user *userptr =
+			u64_to_user_ptr(args->bos + (i * sizeof(submit_bo)));
+
+		/* make sure we don't have garbage flags, in case we hit
+		 * error path before flags is initialized:
+		 */
+		submit->bos[i].flags = 0;
+
+		if (copy_from_user(&submit_bo, userptr, sizeof(submit_bo))) {
+			ret = -EFAULT;
+			i = 0;
+			goto out;
+		}
+
+/* at least one of READ and/or WRITE flags should be set: */
+#define MANDATORY_FLAGS (MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE)
+
+		if ((submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) ||
+			!(submit_bo.flags & MANDATORY_FLAGS)) {
+			SUBMIT_ERROR(submit, "invalid flags: %x\n", submit_bo.flags);
+			ret = -EINVAL;
+			i = 0;
+			goto out;
+		}
+
+		submit->bos[i].handle = submit_bo.handle;
+		submit->bos[i].flags = submit_bo.flags;
+	}
+
+	spin_lock(&file->table_lock);
+
+	for (i = 0; i < args->nr_bos; i++) {
+		struct drm_gem_object *obj;
+
+		/* normally use drm_gem_object_lookup(), but for bulk lookup
+		 * all under single table_lock just hit object_idr directly:
+		 */
+		obj = idr_find(&file->object_idr, submit->bos[i].handle);
+		if (!obj) {
+			SUBMIT_ERROR(submit, "invalid handle %u at index %u\n", submit->bos[i].handle, i);
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+
+		drm_gem_object_get(obj);
+
+		submit->bos[i].obj = obj;
+	}
+
+out_unlock:
+	spin_unlock(&file->table_lock);
+
+out:
+	submit->nr_bos = i;
+
+	return ret;
+}
+
+static int submit_lookup_cmds(struct msm_gem_submit *submit,
+		struct drm_msm_gem_submit *args, struct drm_file *file)
+{
+	unsigned i;
+	size_t sz;
+	int ret = 0;
+
+	for (i = 0; i < args->nr_cmds; i++) {
+		struct drm_msm_gem_submit_cmd submit_cmd;
+		void __user *userptr =
+			u64_to_user_ptr(args->cmds + (i * sizeof(submit_cmd)));
+
+		ret = copy_from_user(&submit_cmd, userptr, sizeof(submit_cmd));
+		if (ret) {
+			ret = -EFAULT;
+			goto out;
+		}
+
+		/* validate input from userspace: */
+		switch (submit_cmd.type) {
+		case MSM_SUBMIT_CMD_BUF:
+		case MSM_SUBMIT_CMD_IB_TARGET_BUF:
+		case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+			break;
+		default:
+			SUBMIT_ERROR(submit, "invalid type: %08x\n", submit_cmd.type);
+			return -EINVAL;
+		}
+
+		if (submit_cmd.size % 4) {
+			SUBMIT_ERROR(submit, "non-aligned cmdstream buffer size: %u\n",
+				     submit_cmd.size);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		submit->cmd[i].type = submit_cmd.type;
+		submit->cmd[i].size = submit_cmd.size / 4;
+		submit->cmd[i].offset = submit_cmd.submit_offset / 4;
+		submit->cmd[i].idx  = submit_cmd.submit_idx;
+		submit->cmd[i].nr_relocs = submit_cmd.nr_relocs;
+
+		userptr = u64_to_user_ptr(submit_cmd.relocs);
+
+		sz = array_size(submit_cmd.nr_relocs,
+				sizeof(struct drm_msm_gem_submit_reloc));
+		/* check for overflow: */
+		if (sz == SIZE_MAX) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		submit->cmd[i].relocs = kmalloc(sz, GFP_KERNEL | __GFP_NOWARN);
+		if (!submit->cmd[i].relocs) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		ret = copy_from_user(submit->cmd[i].relocs, userptr, sz);
+		if (ret) {
+			ret = -EFAULT;
+			goto out;
+		}
+	}
+
+out:
+	return ret;
+}
+
+/* This is where we make sure all the bo's are reserved and pin'd: */
+static int submit_lock_objects(struct msm_gem_submit *submit)
+{
+	int ret;
+
+	drm_exec_init(&submit->exec, DRM_EXEC_INTERRUPTIBLE_WAIT, submit->nr_bos);
+
+	drm_exec_until_all_locked (&submit->exec) {
+		for (unsigned i = 0; i < submit->nr_bos; i++) {
+			struct drm_gem_object *obj = submit->bos[i].obj;
+			ret = drm_exec_prepare_obj(&submit->exec, obj, 1);
+			drm_exec_retry_on_contention(&submit->exec);
+			if (ret)
+				goto error;
+		}
+	}
+
+	return 0;
+
+error:
+	return ret;
+}
+
+static int submit_fence_sync(struct msm_gem_submit *submit)
+{
+	int i, ret = 0;
+
+	for (i = 0; i < submit->nr_bos; i++) {
+		struct drm_gem_object *obj = submit->bos[i].obj;
+		bool write = submit->bos[i].flags & MSM_SUBMIT_BO_WRITE;
+
+		/* Otherwise userspace can ask for implicit sync to be
+		 * disabled on specific buffers.  This is useful for internal
+		 * usermode driver managed buffers, suballocation, etc.
+		 */
+		if (submit->bos[i].flags & MSM_SUBMIT_BO_NO_IMPLICIT)
+			continue;
+
+		ret = drm_sched_job_add_implicit_dependencies(&submit->base,
+							      obj,
+							      write);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static int submit_pin_objects(struct msm_gem_submit *submit)
+{
+	struct msm_drm_private *priv = submit->dev->dev_private;
+	int i, ret = 0;
+
+	for (i = 0; i < submit->nr_bos; i++) {
+		struct drm_gem_object *obj = submit->bos[i].obj;
+		struct msm_gem_vma *vma;
+
+		/* if locking succeeded, pin bo: */
+		vma = msm_gem_get_vma_locked(obj, submit->aspace);
+		if (IS_ERR(vma)) {
+			ret = PTR_ERR(vma);
+			break;
+		}
+
+		ret = msm_gem_pin_vma_locked(obj, vma);
+		if (ret)
+			break;
+
+		submit->bos[i].iova = vma->iova;
+	}
+
+	/*
+	 * A second loop while holding the LRU lock (a) avoids acquiring/dropping
+	 * the LRU lock for each individual bo, while (b) avoiding holding the
+	 * LRU lock while calling msm_gem_pin_vma_locked() (which could trigger
+	 * get_pages() which could trigger reclaim.. and if we held the LRU lock
+	 * could trigger deadlock with the shrinker).
+	 */
+	mutex_lock(&priv->lru.lock);
+	for (i = 0; i < submit->nr_bos; i++) {
+		msm_gem_pin_obj_locked(submit->bos[i].obj);
+	}
+	mutex_unlock(&priv->lru.lock);
+
+	submit->bos_pinned = true;
+
+	return ret;
+}
+
+static void submit_unpin_objects(struct msm_gem_submit *submit)
+{
+	if (!submit->bos_pinned)
+		return;
+
+	for (int i = 0; i < submit->nr_bos; i++) {
+		struct drm_gem_object *obj = submit->bos[i].obj;
+
+		msm_gem_unpin_locked(obj);
+	}
+
+	submit->bos_pinned = false;
+}
+
+static void submit_attach_object_fences(struct msm_gem_submit *submit)
+{
+	int i;
+
+	for (i = 0; i < submit->nr_bos; i++) {
+		struct drm_gem_object *obj = submit->bos[i].obj;
+
+		if (submit->bos[i].flags & MSM_SUBMIT_BO_WRITE)
+			dma_resv_add_fence(obj->resv, submit->user_fence,
+					   DMA_RESV_USAGE_WRITE);
+		else if (submit->bos[i].flags & MSM_SUBMIT_BO_READ)
+			dma_resv_add_fence(obj->resv, submit->user_fence,
+					   DMA_RESV_USAGE_READ);
+	}
+}
+
+static int submit_bo(struct msm_gem_submit *submit, uint32_t idx,
+		struct drm_gem_object **obj, uint64_t *iova)
+{
+	if (idx >= submit->nr_bos) {
+		SUBMIT_ERROR(submit, "invalid buffer index: %u (out of %u)\n",
+			     idx, submit->nr_bos);
+		return -EINVAL;
+	}
+
+	if (obj)
+		*obj = submit->bos[idx].obj;
+	if (iova)
+		*iova = submit->bos[idx].iova;
+
+	return 0;
+}
+
+/* process the reloc's and patch up the cmdstream as needed: */
+static int submit_reloc(struct msm_gem_submit *submit, struct drm_gem_object *obj,
+		uint32_t offset, uint32_t nr_relocs, struct drm_msm_gem_submit_reloc *relocs)
+{
+	uint32_t i, last_offset = 0;
+	uint32_t *ptr;
+	int ret = 0;
+
+	if (offset % 4) {
+		SUBMIT_ERROR(submit, "non-aligned cmdstream buffer: %u\n", offset);
+		return -EINVAL;
+	}
+
+	/* For now, just map the entire thing.  Eventually we probably
+	 * to do it page-by-page, w/ kmap() if not vmap()d..
+	 */
+	ptr = msm_gem_get_vaddr_locked(obj);
+
+	if (IS_ERR(ptr)) {
+		ret = PTR_ERR(ptr);
+		DBG("failed to map: %d", ret);
+		return ret;
+	}
+
+	for (i = 0; i < nr_relocs; i++) {
+		struct drm_msm_gem_submit_reloc submit_reloc = relocs[i];
+		uint32_t off;
+		uint64_t iova;
+
+		if (submit_reloc.submit_offset % 4) {
+			SUBMIT_ERROR(submit, "non-aligned reloc offset: %u\n",
+				     submit_reloc.submit_offset);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		/* offset in dwords: */
+		off = submit_reloc.submit_offset / 4;
+
+		if ((off >= (obj->size / 4)) ||
+				(off < last_offset)) {
+			SUBMIT_ERROR(submit, "invalid offset %u at reloc %u\n", off, i);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		ret = submit_bo(submit, submit_reloc.reloc_idx, NULL, &iova);
+		if (ret)
+			goto out;
+
+		iova += submit_reloc.reloc_offset;
+
+		if (submit_reloc.shift < 0)
+			iova >>= -submit_reloc.shift;
+		else
+			iova <<= submit_reloc.shift;
+
+		ptr[off] = iova | submit_reloc.or;
+
+		last_offset = off;
+	}
+
+out:
+	msm_gem_put_vaddr_locked(obj);
+
+	return ret;
+}
+
+/* Cleanup submit at end of ioctl.  In the error case, this also drops
+ * references, unpins, and drops active refcnt.  In the non-error case,
+ * this is done when the submit is retired.
+ */
+static void submit_cleanup(struct msm_gem_submit *submit, bool error)
+{
+	if (error) {
+		submit_unpin_objects(submit);
+		/* job wasn't enqueued to scheduler, so early retirement: */
+		msm_submit_retire(submit);
+	}
+
+	if (submit->exec.objects)
+		drm_exec_fini(&submit->exec);
+}
+
+void msm_submit_retire(struct msm_gem_submit *submit)
+{
+	int i;
+
+	for (i = 0; i < submit->nr_bos; i++) {
+		struct drm_gem_object *obj = submit->bos[i].obj;
+
+		drm_gem_object_put(obj);
+	}
+}
+
+struct msm_submit_post_dep {
+	struct drm_syncobj *syncobj;
+	uint64_t point;
+	struct dma_fence_chain *chain;
+};
+
+static struct drm_syncobj **msm_parse_deps(struct msm_gem_submit *submit,
+                                           struct drm_file *file,
+                                           uint64_t in_syncobjs_addr,
+                                           uint32_t nr_in_syncobjs,
+                                           size_t syncobj_stride)
+{
+	struct drm_syncobj **syncobjs = NULL;
+	struct drm_msm_gem_submit_syncobj syncobj_desc = {0};
+	int ret = 0;
+	uint32_t i, j;
+
+	syncobjs = kcalloc(nr_in_syncobjs, sizeof(*syncobjs),
+	                   GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
+	if (!syncobjs)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; i < nr_in_syncobjs; ++i) {
+		uint64_t address = in_syncobjs_addr + i * syncobj_stride;
+
+		if (copy_from_user(&syncobj_desc,
+			           u64_to_user_ptr(address),
+			           min(syncobj_stride, sizeof(syncobj_desc)))) {
+			ret = -EFAULT;
+			break;
+		}
+
+		if (syncobj_desc.point &&
+		    !drm_core_check_feature(submit->dev, DRIVER_SYNCOBJ_TIMELINE)) {
+			ret = -EOPNOTSUPP;
+			break;
+		}
+
+		if (syncobj_desc.flags & ~MSM_SUBMIT_SYNCOBJ_FLAGS) {
+			ret = -EINVAL;
+			break;
+		}
+
+		ret = drm_sched_job_add_syncobj_dependency(&submit->base, file,
+							   syncobj_desc.handle, syncobj_desc.point);
+		if (ret)
+			break;
+
+		if (syncobj_desc.flags & MSM_SUBMIT_SYNCOBJ_RESET) {
+			syncobjs[i] =
+				drm_syncobj_find(file, syncobj_desc.handle);
+			if (!syncobjs[i]) {
+				ret = -EINVAL;
+				break;
+			}
+		}
+	}
+
+	if (ret) {
+		for (j = 0; j <= i; ++j) {
+			if (syncobjs[j])
+				drm_syncobj_put(syncobjs[j]);
+		}
+		kfree(syncobjs);
+		return ERR_PTR(ret);
+	}
+	return syncobjs;
+}
+
+static void msm_reset_syncobjs(struct drm_syncobj **syncobjs,
+                               uint32_t nr_syncobjs)
+{
+	uint32_t i;
+
+	for (i = 0; syncobjs && i < nr_syncobjs; ++i) {
+		if (syncobjs[i])
+			drm_syncobj_replace_fence(syncobjs[i], NULL);
+	}
+}
+
+static struct msm_submit_post_dep *msm_parse_post_deps(struct drm_device *dev,
+                                                       struct drm_file *file,
+                                                       uint64_t syncobjs_addr,
+                                                       uint32_t nr_syncobjs,
+                                                       size_t syncobj_stride)
+{
+	struct msm_submit_post_dep *post_deps;
+	struct drm_msm_gem_submit_syncobj syncobj_desc = {0};
+	int ret = 0;
+	uint32_t i, j;
+
+	post_deps = kcalloc(nr_syncobjs, sizeof(*post_deps),
+			    GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
+	if (!post_deps)
+		return ERR_PTR(-ENOMEM);
+
+	for (i = 0; i < nr_syncobjs; ++i) {
+		uint64_t address = syncobjs_addr + i * syncobj_stride;
+
+		if (copy_from_user(&syncobj_desc,
+			           u64_to_user_ptr(address),
+			           min(syncobj_stride, sizeof(syncobj_desc)))) {
+			ret = -EFAULT;
+			break;
+		}
+
+		post_deps[i].point = syncobj_desc.point;
+
+		if (syncobj_desc.flags) {
+			ret = -EINVAL;
+			break;
+		}
+
+		if (syncobj_desc.point) {
+			if (!drm_core_check_feature(dev,
+			                            DRIVER_SYNCOBJ_TIMELINE)) {
+				ret = -EOPNOTSUPP;
+				break;
+			}
+
+			post_deps[i].chain = dma_fence_chain_alloc();
+			if (!post_deps[i].chain) {
+				ret = -ENOMEM;
+				break;
+			}
+		}
+
+		post_deps[i].syncobj =
+			drm_syncobj_find(file, syncobj_desc.handle);
+		if (!post_deps[i].syncobj) {
+			ret = -EINVAL;
+			break;
+		}
+	}
+
+	if (ret) {
+		for (j = 0; j <= i; ++j) {
+			dma_fence_chain_free(post_deps[j].chain);
+			if (post_deps[j].syncobj)
+				drm_syncobj_put(post_deps[j].syncobj);
+		}
+
+		kfree(post_deps);
+		return ERR_PTR(ret);
+	}
+
+	return post_deps;
+}
+
+static void msm_process_post_deps(struct msm_submit_post_dep *post_deps,
+                                  uint32_t count, struct dma_fence *fence)
+{
+	uint32_t i;
+
+	for (i = 0; post_deps && i < count; ++i) {
+		if (post_deps[i].chain) {
+			drm_syncobj_add_point(post_deps[i].syncobj,
+			                      post_deps[i].chain,
+			                      fence, post_deps[i].point);
+			post_deps[i].chain = NULL;
+		} else {
+			drm_syncobj_replace_fence(post_deps[i].syncobj,
+			                          fence);
+		}
+	}
+}
+
+int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+		struct drm_file *file)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct drm_msm_gem_submit *args = data;
+	struct msm_file_private *ctx = file->driver_priv;
+	struct msm_gem_submit *submit = NULL;
+	struct msm_gpu *gpu = priv->gpu;
+	struct msm_gpu_submitqueue *queue;
+	struct msm_ringbuffer *ring;
+	struct msm_submit_post_dep *post_deps = NULL;
+	struct drm_syncobj **syncobjs_to_reset = NULL;
+	int out_fence_fd = -1;
+	unsigned i;
+	int ret;
+
+	if (!gpu)
+		return -ENXIO;
+
+	if (args->pad)
+		return -EINVAL;
+
+	if (unlikely(!ctx->aspace) && !capable(CAP_SYS_RAWIO)) {
+		DRM_ERROR_RATELIMITED("IOMMU support or CAP_SYS_RAWIO required!\n");
+		return -EPERM;
+	}
+
+	/* for now, we just have 3d pipe.. eventually this would need to
+	 * be more clever to dispatch to appropriate gpu module:
+	 */
+	if (MSM_PIPE_ID(args->flags) != MSM_PIPE_3D0)
+		return -EINVAL;
+
+	if (MSM_PIPE_FLAGS(args->flags) & ~MSM_SUBMIT_FLAGS)
+		return -EINVAL;
+
+	if (args->flags & MSM_SUBMIT_SUDO) {
+		if (!IS_ENABLED(CONFIG_DRM_MSM_GPU_SUDO) ||
+		    !capable(CAP_SYS_RAWIO))
+			return -EINVAL;
+	}
+
+	queue = msm_submitqueue_get(ctx, args->queueid);
+	if (!queue)
+		return -ENOENT;
+
+	ring = gpu->rb[queue->ring_nr];
+
+	if (args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
+		out_fence_fd = get_unused_fd_flags(O_CLOEXEC);
+		if (out_fence_fd < 0) {
+			ret = out_fence_fd;
+			goto out_post_unlock;
+		}
+	}
+
+	submit = submit_create(dev, gpu, queue, args->nr_bos, args->nr_cmds);
+	if (IS_ERR(submit)) {
+		ret = PTR_ERR(submit);
+		goto out_post_unlock;
+	}
+
+	trace_msm_gpu_submit(pid_nr(submit->pid), ring->id, submit->ident,
+		args->nr_bos, args->nr_cmds);
+
+	ret = mutex_lock_interruptible(&queue->lock);
+	if (ret)
+		goto out_post_unlock;
+
+	if (args->flags & MSM_SUBMIT_SUDO)
+		submit->in_rb = true;
+
+	if (args->flags & MSM_SUBMIT_FENCE_FD_IN) {
+		struct dma_fence *in_fence;
+
+		in_fence = sync_file_get_fence(args->fence_fd);
+
+		if (!in_fence) {
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+
+		ret = drm_sched_job_add_dependency(&submit->base, in_fence);
+		if (ret)
+			goto out_unlock;
+	}
+
+	if (args->flags & MSM_SUBMIT_SYNCOBJ_IN) {
+		syncobjs_to_reset = msm_parse_deps(submit, file,
+		                                   args->in_syncobjs,
+		                                   args->nr_in_syncobjs,
+		                                   args->syncobj_stride);
+		if (IS_ERR(syncobjs_to_reset)) {
+			ret = PTR_ERR(syncobjs_to_reset);
+			goto out_unlock;
+		}
+	}
+
+	if (args->flags & MSM_SUBMIT_SYNCOBJ_OUT) {
+		post_deps = msm_parse_post_deps(dev, file,
+		                                args->out_syncobjs,
+		                                args->nr_out_syncobjs,
+		                                args->syncobj_stride);
+		if (IS_ERR(post_deps)) {
+			ret = PTR_ERR(post_deps);
+			goto out_unlock;
+		}
+	}
+
+	ret = submit_lookup_objects(submit, args, file);
+	if (ret)
+		goto out;
+
+	ret = submit_lookup_cmds(submit, args, file);
+	if (ret)
+		goto out;
+
+	/* copy_*_user while holding a ww ticket upsets lockdep */
+	ret = submit_lock_objects(submit);
+	if (ret)
+		goto out;
+
+	if (!(args->flags & MSM_SUBMIT_NO_IMPLICIT)) {
+		ret = submit_fence_sync(submit);
+		if (ret)
+			goto out;
+	}
+
+	ret = submit_pin_objects(submit);
+	if (ret)
+		goto out;
+
+	for (i = 0; i < args->nr_cmds; i++) {
+		struct drm_gem_object *obj;
+		uint64_t iova;
+
+		ret = submit_bo(submit, submit->cmd[i].idx, &obj, &iova);
+		if (ret)
+			goto out;
+
+		if (!submit->cmd[i].size ||
+			((submit->cmd[i].size + submit->cmd[i].offset) >
+				obj->size / 4)) {
+			SUBMIT_ERROR(submit, "invalid cmdstream size: %u\n", submit->cmd[i].size * 4);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		submit->cmd[i].iova = iova + (submit->cmd[i].offset * 4);
+
+		if (likely(!submit->cmd[i].nr_relocs))
+			continue;
+
+		if (!gpu->allow_relocs) {
+			SUBMIT_ERROR(submit, "relocs not allowed\n");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		ret = submit_reloc(submit, obj, submit->cmd[i].offset * 4,
+				submit->cmd[i].nr_relocs, submit->cmd[i].relocs);
+		if (ret)
+			goto out;
+	}
+
+	submit->nr_cmds = i;
+
+	idr_preload(GFP_KERNEL);
+
+	spin_lock(&queue->idr_lock);
+
+	/*
+	 * If using userspace provided seqno fence, validate that the id
+	 * is available before arming sched job.  Since access to fence_idr
+	 * is serialized on the queue lock, the slot should be still avail
+	 * after the job is armed
+	 */
+	if ((args->flags & MSM_SUBMIT_FENCE_SN_IN) &&
+			(!args->fence || idr_find(&queue->fence_idr, args->fence))) {
+		spin_unlock(&queue->idr_lock);
+		idr_preload_end();
+		ret = -EINVAL;
+		goto out;
+	}
+
+	drm_sched_job_arm(&submit->base);
+
+	submit->user_fence = dma_fence_get(&submit->base.s_fence->finished);
+
+	if (args->flags & MSM_SUBMIT_FENCE_SN_IN) {
+		/*
+		 * Userspace has assigned the seqno fence that it wants
+		 * us to use.  It is an error to pick a fence sequence
+		 * number that is not available.
+		 */
+		submit->fence_id = args->fence;
+		ret = idr_alloc_u32(&queue->fence_idr, submit->user_fence,
+				    &submit->fence_id, submit->fence_id,
+				    GFP_NOWAIT);
+		/*
+		 * We've already validated that the fence_id slot is valid,
+		 * so if idr_alloc_u32 failed, it is a kernel bug
+		 */
+		WARN_ON(ret);
+	} else {
+		/*
+		 * Allocate an id which can be used by WAIT_FENCE ioctl to map
+		 * back to the underlying fence.
+		 */
+		submit->fence_id = idr_alloc_cyclic(&queue->fence_idr,
+						    submit->user_fence, 1,
+						    INT_MAX, GFP_NOWAIT);
+	}
+
+	spin_unlock(&queue->idr_lock);
+	idr_preload_end();
+
+	if (submit->fence_id < 0) {
+		ret = submit->fence_id;
+		submit->fence_id = 0;
+	}
+
+	if (ret == 0 && args->flags & MSM_SUBMIT_FENCE_FD_OUT) {
+		struct sync_file *sync_file = sync_file_create(submit->user_fence);
+		if (!sync_file) {
+			ret = -ENOMEM;
+		} else {
+			fd_install(out_fence_fd, sync_file->file);
+			args->fence_fd = out_fence_fd;
+		}
+	}
+
+	if (ret)
+		goto out;
+
+	submit_attach_object_fences(submit);
+
+	/* The scheduler owns a ref now: */
+	msm_gem_submit_get(submit);
+
+	msm_rd_dump_submit(priv->rd, submit, NULL);
+
+	drm_sched_entity_push_job(&submit->base);
+
+	args->fence = submit->fence_id;
+	queue->last_fence = submit->fence_id;
+
+	msm_reset_syncobjs(syncobjs_to_reset, args->nr_in_syncobjs);
+	msm_process_post_deps(post_deps, args->nr_out_syncobjs,
+	                      submit->user_fence);
+
+
+out:
+	submit_cleanup(submit, !!ret);
+out_unlock:
+	mutex_unlock(&queue->lock);
+out_post_unlock:
+	if (ret && (out_fence_fd >= 0))
+		put_unused_fd(out_fence_fd);
+
+	if (!IS_ERR_OR_NULL(submit)) {
+		msm_gem_submit_put(submit);
+	} else {
+		/*
+		 * If the submit hasn't yet taken ownership of the queue
+		 * then we need to drop the reference ourself:
+		 */
+		msm_submitqueue_put(queue);
+	}
+	if (!IS_ERR_OR_NULL(post_deps)) {
+		for (i = 0; i < args->nr_out_syncobjs; ++i) {
+			kfree(post_deps[i].chain);
+			drm_syncobj_put(post_deps[i].syncobj);
+		}
+		kfree(post_deps);
+	}
+
+	if (!IS_ERR_OR_NULL(syncobjs_to_reset)) {
+		for (i = 0; i < args->nr_in_syncobjs; ++i) {
+			if (syncobjs_to_reset[i])
+				drm_syncobj_put(syncobjs_to_reset[i]);
+		}
+		kfree(syncobjs_to_reset);
+	}
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_gem_vma.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_gem_vma.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2016 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include "msm_drv.h"
+#include "msm_fence.h"
+#include "msm_gem.h"
+#include "msm_mmu.h"
+
+static void
+msm_gem_address_space_destroy(struct kref *kref)
+{
+	struct msm_gem_address_space *aspace = container_of(kref,
+			struct msm_gem_address_space, kref);
+
+	drm_mm_takedown(&aspace->mm);
+	if (aspace->mmu)
+		aspace->mmu->funcs->destroy(aspace->mmu);
+	put_pid(aspace->pid);
+	kfree(aspace);
+}
+
+
+void msm_gem_address_space_put(struct msm_gem_address_space *aspace)
+{
+	if (aspace)
+		kref_put(&aspace->kref, msm_gem_address_space_destroy);
+}
+
+struct msm_gem_address_space *
+msm_gem_address_space_get(struct msm_gem_address_space *aspace)
+{
+	if (!IS_ERR_OR_NULL(aspace))
+		kref_get(&aspace->kref);
+
+	return aspace;
+}
+
+/* Actually unmap memory for the vma */
+void msm_gem_vma_purge(struct msm_gem_vma *vma)
+{
+	struct msm_gem_address_space *aspace = vma->aspace;
+	unsigned size = vma->node.size;
+
+	/* Don't do anything if the memory isn't mapped */
+	if (!vma->mapped)
+		return;
+
+	aspace->mmu->funcs->unmap(aspace->mmu, vma->iova, size);
+
+	vma->mapped = false;
+}
+
+/* Map and pin vma: */
+int
+msm_gem_vma_map(struct msm_gem_vma *vma, int prot,
+		struct sg_table *sgt, int size)
+{
+	struct msm_gem_address_space *aspace = vma->aspace;
+	int ret;
+
+	if (GEM_WARN_ON(!vma->iova))
+		return -EINVAL;
+
+	if (vma->mapped)
+		return 0;
+
+	vma->mapped = true;
+
+	if (!aspace)
+		return 0;
+
+	/*
+	 * NOTE: iommu/io-pgtable can allocate pages, so we cannot hold
+	 * a lock across map/unmap which is also used in the job_run()
+	 * path, as this can cause deadlock in job_run() vs shrinker/
+	 * reclaim.
+	 *
+	 * Revisit this if we can come up with a scheme to pre-alloc pages
+	 * for the pgtable in map/unmap ops.
+	 */
+	ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova, sgt, size, prot);
+
+	if (ret) {
+		vma->mapped = false;
+	}
+
+	return ret;
+}
+
+/* Close an iova.  Warn if it is still in use */
+void msm_gem_vma_close(struct msm_gem_vma *vma)
+{
+	struct msm_gem_address_space *aspace = vma->aspace;
+
+	GEM_WARN_ON(vma->mapped);
+
+	spin_lock(&aspace->lock);
+	if (vma->iova)
+		drm_mm_remove_node(&vma->node);
+	spin_unlock(&aspace->lock);
+
+	vma->iova = 0;
+
+	msm_gem_address_space_put(aspace);
+}
+
+struct msm_gem_vma *msm_gem_vma_new(struct msm_gem_address_space *aspace)
+{
+	struct msm_gem_vma *vma;
+
+	vma = kzalloc(sizeof(*vma), GFP_KERNEL);
+	if (!vma)
+		return NULL;
+
+	vma->aspace = aspace;
+
+	return vma;
+}
+
+/* Initialize a new vma and allocate an iova for it */
+int msm_gem_vma_init(struct msm_gem_vma *vma, int size,
+		u64 range_start, u64 range_end)
+{
+	struct msm_gem_address_space *aspace = vma->aspace;
+	int ret;
+
+	if (GEM_WARN_ON(!aspace))
+		return -EINVAL;
+
+	if (GEM_WARN_ON(vma->iova))
+		return -EBUSY;
+
+	spin_lock(&aspace->lock);
+	ret = drm_mm_insert_node_in_range(&aspace->mm, &vma->node,
+					  size, PAGE_SIZE, 0,
+					  range_start, range_end, 0);
+	spin_unlock(&aspace->lock);
+
+	if (ret)
+		return ret;
+
+	vma->iova = vma->node.start;
+	vma->mapped = false;
+
+	kref_get(&aspace->kref);
+
+	return 0;
+}
+
+struct msm_gem_address_space *
+msm_gem_address_space_create(struct msm_mmu *mmu, const char *name,
+		u64 va_start, u64 size)
+{
+	struct msm_gem_address_space *aspace;
+
+	if (IS_ERR(mmu))
+		return ERR_CAST(mmu);
+
+	aspace = kzalloc(sizeof(*aspace), GFP_KERNEL);
+	if (!aspace)
+		return ERR_PTR(-ENOMEM);
+
+	spin_lock_init(&aspace->lock);
+	aspace->name = name;
+	aspace->mmu = mmu;
+	aspace->va_start = va_start;
+	aspace->va_size  = size;
+
+	drm_mm_init(&aspace->mm, va_start, size);
+
+	kref_init(&aspace->kref);
+
+	return aspace;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_gpu.c
@@ -0,0 +1,1023 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include "drm/drm_drv.h"
+
+#include "msm_gpu.h"
+#include "msm_gem.h"
+#include "msm_mmu.h"
+#include "msm_fence.h"
+#include "msm_gpu_trace.h"
+//#include "adreno/adreno_gpu.h"
+
+#include <generated/utsrelease.h>
+#include <linux/string_helpers.h>
+#include <linux/devcoredump.h>
+#include <linux/sched/task.h>
+
+/*
+ * Power Management:
+ */
+
+static int enable_pwrrail(struct msm_gpu *gpu)
+{
+	struct drm_device *dev = gpu->dev;
+	int ret = 0;
+
+	if (gpu->gpu_reg) {
+		ret = regulator_enable(gpu->gpu_reg);
+		if (ret) {
+			DRM_DEV_ERROR(dev->dev, "failed to enable 'gpu_reg': %d\n", ret);
+			return ret;
+		}
+	}
+
+	if (gpu->gpu_cx) {
+		ret = regulator_enable(gpu->gpu_cx);
+		if (ret) {
+			DRM_DEV_ERROR(dev->dev, "failed to enable 'gpu_cx': %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static int disable_pwrrail(struct msm_gpu *gpu)
+{
+	if (gpu->gpu_cx)
+		regulator_disable(gpu->gpu_cx);
+	if (gpu->gpu_reg)
+		regulator_disable(gpu->gpu_reg);
+	return 0;
+}
+
+static int enable_clk(struct msm_gpu *gpu)
+{
+	if (gpu->core_clk && gpu->fast_rate)
+		dev_pm_opp_set_rate(&gpu->pdev->dev, gpu->fast_rate);
+
+	/* Set the RBBM timer rate to 19.2Mhz */
+	if (gpu->rbbmtimer_clk)
+		clk_set_rate(gpu->rbbmtimer_clk, 19200000);
+
+	return clk_bulk_prepare_enable(gpu->nr_clocks, gpu->grp_clks);
+}
+
+static int disable_clk(struct msm_gpu *gpu)
+{
+	clk_bulk_disable_unprepare(gpu->nr_clocks, gpu->grp_clks);
+
+	/*
+	 * Set the clock to a deliberately low rate. On older targets the clock
+	 * speed had to be non zero to avoid problems. On newer targets this
+	 * will be rounded down to zero anyway so it all works out.
+	 */
+	if (gpu->core_clk)
+		dev_pm_opp_set_rate(&gpu->pdev->dev, 27000000);
+
+	if (gpu->rbbmtimer_clk)
+		clk_set_rate(gpu->rbbmtimer_clk, 0);
+
+	return 0;
+}
+
+static int enable_axi(struct msm_gpu *gpu)
+{
+	return clk_prepare_enable(gpu->ebi1_clk);
+}
+
+static int disable_axi(struct msm_gpu *gpu)
+{
+	clk_disable_unprepare(gpu->ebi1_clk);
+	return 0;
+}
+
+int msm_gpu_pm_resume(struct msm_gpu *gpu)
+{
+	int ret;
+
+	DBG("%s", gpu->name);
+	trace_msm_gpu_resume(0);
+
+	ret = enable_pwrrail(gpu);
+	if (ret)
+		return ret;
+
+	ret = enable_clk(gpu);
+	if (ret)
+		return ret;
+
+	ret = enable_axi(gpu);
+	if (ret)
+		return ret;
+
+	msm_devfreq_resume(gpu);
+
+	gpu->needs_hw_init = true;
+
+	return 0;
+}
+
+int msm_gpu_pm_suspend(struct msm_gpu *gpu)
+{
+	int ret;
+
+	DBG("%s", gpu->name);
+	trace_msm_gpu_suspend(0);
+
+	msm_devfreq_suspend(gpu);
+
+	ret = disable_axi(gpu);
+	if (ret)
+		return ret;
+
+	ret = disable_clk(gpu);
+	if (ret)
+		return ret;
+
+	ret = disable_pwrrail(gpu);
+	if (ret)
+		return ret;
+
+	gpu->suspend_count++;
+
+	return 0;
+}
+
+void msm_gpu_show_fdinfo(struct msm_gpu *gpu, struct msm_file_private *ctx,
+			 struct drm_printer *p)
+{
+	drm_printf(p, "drm-engine-gpu:\t%llu ns\n", ctx->elapsed_ns);
+	drm_printf(p, "drm-cycles-gpu:\t%llu\n", ctx->cycles);
+	drm_printf(p, "drm-maxfreq-gpu:\t%u Hz\n", gpu->fast_rate);
+}
+
+int msm_gpu_hw_init(struct msm_gpu *gpu)
+{
+	int ret;
+
+	WARN_ON(!mutex_is_locked(&gpu->lock));
+
+	if (!gpu->needs_hw_init)
+		return 0;
+
+	disable_irq(gpu->irq);
+	ret = gpu->funcs->hw_init(gpu);
+	if (!ret)
+		gpu->needs_hw_init = false;
+	enable_irq(gpu->irq);
+
+	return ret;
+}
+
+#ifdef CONFIG_DEV_COREDUMP
+static ssize_t msm_gpu_devcoredump_read(char *buffer, loff_t offset,
+		size_t count, void *data, size_t datalen)
+{
+	struct msm_gpu *gpu = data;
+	struct drm_print_iterator iter;
+	struct drm_printer p;
+	struct msm_gpu_state *state;
+
+	state = msm_gpu_crashstate_get(gpu);
+	if (!state)
+		return 0;
+
+	iter.data = buffer;
+	iter.offset = 0;
+	iter.start = offset;
+	iter.remain = count;
+
+	p = drm_coredump_printer(&iter);
+
+	drm_printf(&p, "---\n");
+	drm_printf(&p, "kernel: " UTS_RELEASE "\n");
+	drm_printf(&p, "module: " KBUILD_MODNAME "\n");
+	drm_printf(&p, "time: %lld.%09ld\n",
+		state->time.tv_sec, state->time.tv_nsec);
+	if (state->comm)
+		drm_printf(&p, "comm: %s\n", state->comm);
+	if (state->cmd)
+		drm_printf(&p, "cmdline: %s\n", state->cmd);
+
+	gpu->funcs->show(gpu, state, &p);
+
+	msm_gpu_crashstate_put(gpu);
+
+	return count - iter.remain;
+}
+
+static void msm_gpu_devcoredump_free(void *data)
+{
+	struct msm_gpu *gpu = data;
+
+	msm_gpu_crashstate_put(gpu);
+}
+
+static void msm_gpu_crashstate_get_bo(struct msm_gpu_state *state,
+		struct drm_gem_object *obj, u64 iova, bool full)
+{
+	struct msm_gpu_state_bo *state_bo = &state->bos[state->nr_bos];
+
+	/* Don't record write only objects */
+	state_bo->size = obj->size;
+	state_bo->iova = iova;
+
+	BUILD_BUG_ON(sizeof(state_bo->name) != sizeof(to_msm_bo(obj)->name));
+
+	memcpy(state_bo->name, to_msm_bo(obj)->name, sizeof(state_bo->name));
+
+	if (full) {
+		void *ptr;
+
+		state_bo->data = kvmalloc(obj->size, GFP_KERNEL);
+		if (!state_bo->data)
+			goto out;
+
+		msm_gem_lock(obj);
+		ptr = msm_gem_get_vaddr_active(obj);
+		msm_gem_unlock(obj);
+		if (IS_ERR(ptr)) {
+			kvfree(state_bo->data);
+			state_bo->data = NULL;
+			goto out;
+		}
+
+		memcpy(state_bo->data, ptr, obj->size);
+		msm_gem_put_vaddr(obj);
+	}
+out:
+	state->nr_bos++;
+}
+
+static void msm_gpu_crashstate_capture(struct msm_gpu *gpu,
+		struct msm_gem_submit *submit, char *comm, char *cmd)
+{
+	struct msm_gpu_state *state;
+
+	/* Check if the target supports capturing crash state */
+	if (!gpu->funcs->gpu_state_get)
+		return;
+
+	/* Only save one crash state at a time */
+	if (gpu->crashstate)
+		return;
+
+	state = gpu->funcs->gpu_state_get(gpu);
+	if (IS_ERR_OR_NULL(state))
+		return;
+
+	/* Fill in the additional crash state information */
+	state->comm = kstrdup(comm, GFP_KERNEL);
+	state->cmd = kstrdup(cmd, GFP_KERNEL);
+	state->fault_info = gpu->fault_info;
+
+	if (submit) {
+		int i;
+
+		state->bos = kcalloc(submit->nr_bos,
+			sizeof(struct msm_gpu_state_bo), GFP_KERNEL);
+
+		for (i = 0; state->bos && i < submit->nr_bos; i++) {
+			msm_gpu_crashstate_get_bo(state, submit->bos[i].obj,
+						  submit->bos[i].iova,
+						  should_dump(submit, i));
+		}
+	}
+
+	/* Set the active crash state to be dumped on failure */
+	gpu->crashstate = state;
+
+	dev_coredumpm(&gpu->pdev->dev, THIS_MODULE, gpu, 0, GFP_KERNEL,
+		msm_gpu_devcoredump_read, msm_gpu_devcoredump_free);
+}
+#else
+static void msm_gpu_crashstate_capture(struct msm_gpu *gpu,
+		struct msm_gem_submit *submit, char *comm, char *cmd)
+{
+}
+#endif
+
+/*
+ * Hangcheck detection for locked gpu:
+ */
+
+static struct msm_gem_submit *
+find_submit(struct msm_ringbuffer *ring, uint32_t fence)
+{
+	struct msm_gem_submit *submit;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ring->submit_lock, flags);
+	list_for_each_entry(submit, &ring->submits, node) {
+		if (submit->seqno == fence) {
+			spin_unlock_irqrestore(&ring->submit_lock, flags);
+			return submit;
+		}
+	}
+	spin_unlock_irqrestore(&ring->submit_lock, flags);
+
+	return NULL;
+}
+
+static void retire_submits(struct msm_gpu *gpu);
+
+static void get_comm_cmdline(struct msm_gem_submit *submit, char **comm, char **cmd)
+{
+	struct msm_file_private *ctx = submit->queue->ctx;
+	struct task_struct *task;
+
+	WARN_ON(!mutex_is_locked(&submit->gpu->lock));
+
+	/* Note that kstrdup will return NULL if argument is NULL: */
+	*comm = kstrdup(ctx->comm, GFP_KERNEL);
+	*cmd  = kstrdup(ctx->cmdline, GFP_KERNEL);
+
+	task = get_pid_task(submit->pid, PIDTYPE_PID);
+	if (!task)
+		return;
+
+	if (!*comm)
+		*comm = kstrdup(task->comm, GFP_KERNEL);
+
+	if (!*cmd)
+		*cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL);
+
+	put_task_struct(task);
+}
+
+static void recover_worker(struct kthread_work *work)
+{
+	struct msm_gpu *gpu = container_of(work, struct msm_gpu, recover_work);
+	struct drm_device *dev = gpu->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_gem_submit *submit;
+	struct msm_ringbuffer *cur_ring = gpu->funcs->active_ring(gpu);
+	char *comm = NULL, *cmd = NULL;
+	int i;
+
+	mutex_lock(&gpu->lock);
+
+	DRM_DEV_ERROR(dev->dev, "%s: hangcheck recover!\n", gpu->name);
+
+	submit = find_submit(cur_ring, cur_ring->memptrs->fence + 1);
+
+	/*
+	 * If the submit retired while we were waiting for the worker to run,
+	 * or waiting to acquire the gpu lock, then nothing more to do.
+	 */
+	if (!submit)
+		goto out_unlock;
+
+	/* Increment the fault counts */
+	submit->queue->faults++;
+	if (submit->aspace)
+		submit->aspace->faults++;
+
+	get_comm_cmdline(submit, &comm, &cmd);
+
+	if (comm && cmd) {
+		DRM_DEV_ERROR(dev->dev, "%s: offending task: %s (%s)\n",
+			      gpu->name, comm, cmd);
+
+		msm_rd_dump_submit(priv->hangrd, submit,
+				   "offending task: %s (%s)", comm, cmd);
+	} else {
+		DRM_DEV_ERROR(dev->dev, "%s: offending task: unknown\n", gpu->name);
+
+		msm_rd_dump_submit(priv->hangrd, submit, NULL);
+	}
+
+	/* Record the crash state */
+	pm_runtime_get_sync(&gpu->pdev->dev);
+	msm_gpu_crashstate_capture(gpu, submit, comm, cmd);
+
+	kfree(cmd);
+	kfree(comm);
+
+	/*
+	 * Update all the rings with the latest and greatest fence.. this
+	 * needs to happen after msm_rd_dump_submit() to ensure that the
+	 * bo's referenced by the offending submit are still around.
+	 */
+	for (i = 0; i < gpu->nr_rings; i++) {
+		struct msm_ringbuffer *ring = gpu->rb[i];
+
+		uint32_t fence = ring->memptrs->fence;
+
+		/*
+		 * For the current (faulting?) ring/submit advance the fence by
+		 * one more to clear the faulting submit
+		 */
+		if (ring == cur_ring)
+			ring->memptrs->fence = ++fence;
+
+		msm_update_fence(ring->fctx, fence);
+	}
+
+	if (msm_gpu_active(gpu)) {
+		/* retire completed submits, plus the one that hung: */
+		retire_submits(gpu);
+
+		gpu->funcs->recover(gpu);
+
+		/*
+		 * Replay all remaining submits starting with highest priority
+		 * ring
+		 */
+		for (i = 0; i < gpu->nr_rings; i++) {
+			struct msm_ringbuffer *ring = gpu->rb[i];
+			unsigned long flags;
+
+			spin_lock_irqsave(&ring->submit_lock, flags);
+			list_for_each_entry(submit, &ring->submits, node)
+				gpu->funcs->submit(gpu, submit);
+			spin_unlock_irqrestore(&ring->submit_lock, flags);
+		}
+	}
+
+	pm_runtime_put(&gpu->pdev->dev);
+
+out_unlock:
+	mutex_unlock(&gpu->lock);
+
+	msm_gpu_retire(gpu);
+}
+
+static void fault_worker(struct kthread_work *work)
+{
+	struct msm_gpu *gpu = container_of(work, struct msm_gpu, fault_work);
+	struct msm_gem_submit *submit;
+	struct msm_ringbuffer *cur_ring = gpu->funcs->active_ring(gpu);
+	char *comm = NULL, *cmd = NULL;
+
+	mutex_lock(&gpu->lock);
+
+	submit = find_submit(cur_ring, cur_ring->memptrs->fence + 1);
+	if (submit && submit->fault_dumped)
+		goto resume_smmu;
+
+	if (submit) {
+		get_comm_cmdline(submit, &comm, &cmd);
+
+		/*
+		 * When we get GPU iova faults, we can get 1000s of them,
+		 * but we really only want to log the first one.
+		 */
+		submit->fault_dumped = true;
+	}
+
+	/* Record the crash state */
+	pm_runtime_get_sync(&gpu->pdev->dev);
+	msm_gpu_crashstate_capture(gpu, submit, comm, cmd);
+	pm_runtime_put_sync(&gpu->pdev->dev);
+
+	kfree(cmd);
+	kfree(comm);
+
+resume_smmu:
+	memset(&gpu->fault_info, 0, sizeof(gpu->fault_info));
+	gpu->aspace->mmu->funcs->resume_translation(gpu->aspace->mmu);
+
+	mutex_unlock(&gpu->lock);
+}
+
+static void hangcheck_timer_reset(struct msm_gpu *gpu)
+{
+	struct msm_drm_private *priv = gpu->dev->dev_private;
+	mod_timer(&gpu->hangcheck_timer,
+			round_jiffies_up(jiffies + msecs_to_jiffies(priv->hangcheck_period)));
+}
+
+static bool made_progress(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
+{
+	if (ring->hangcheck_progress_retries >= DRM_MSM_HANGCHECK_PROGRESS_RETRIES)
+		return false;
+
+	if (!gpu->funcs->progress)
+		return false;
+
+	if (!gpu->funcs->progress(gpu, ring))
+		return false;
+
+	ring->hangcheck_progress_retries++;
+	return true;
+}
+
+static void hangcheck_handler(struct timer_list *t)
+{
+	struct msm_gpu *gpu = from_timer(gpu, t, hangcheck_timer);
+	struct drm_device *dev = gpu->dev;
+	struct msm_ringbuffer *ring = gpu->funcs->active_ring(gpu);
+	uint32_t fence = ring->memptrs->fence;
+
+	if (fence != ring->hangcheck_fence) {
+		/* some progress has been made.. ya! */
+		ring->hangcheck_fence = fence;
+		ring->hangcheck_progress_retries = 0;
+	} else if (fence_before(fence, ring->fctx->last_fence) &&
+			!made_progress(gpu, ring)) {
+		/* no progress and not done.. hung! */
+		ring->hangcheck_fence = fence;
+		ring->hangcheck_progress_retries = 0;
+		DRM_DEV_ERROR(dev->dev, "%s: hangcheck detected gpu lockup rb %d!\n",
+				gpu->name, ring->id);
+		DRM_DEV_ERROR(dev->dev, "%s:     completed fence: %u\n",
+				gpu->name, fence);
+		DRM_DEV_ERROR(dev->dev, "%s:     submitted fence: %u\n",
+				gpu->name, ring->fctx->last_fence);
+
+		kthread_queue_work(gpu->worker, &gpu->recover_work);
+	}
+
+	/* if still more pending work, reset the hangcheck timer: */
+	if (fence_after(ring->fctx->last_fence, ring->hangcheck_fence))
+		hangcheck_timer_reset(gpu);
+
+	/* workaround for missing irq: */
+	msm_gpu_retire(gpu);
+}
+
+/*
+ * Performance Counters:
+ */
+
+/* called under perf_lock */
+static int update_hw_cntrs(struct msm_gpu *gpu, uint32_t ncntrs, uint32_t *cntrs)
+{
+	uint32_t current_cntrs[ARRAY_SIZE(gpu->last_cntrs)];
+	int i, n = min(ncntrs, gpu->num_perfcntrs);
+
+	/* read current values: */
+	for (i = 0; i < gpu->num_perfcntrs; i++)
+		current_cntrs[i] = gpu_read(gpu, gpu->perfcntrs[i].sample_reg);
+
+	/* update cntrs: */
+	for (i = 0; i < n; i++)
+		cntrs[i] = current_cntrs[i] - gpu->last_cntrs[i];
+
+	/* save current values: */
+	for (i = 0; i < gpu->num_perfcntrs; i++)
+		gpu->last_cntrs[i] = current_cntrs[i];
+
+	return n;
+}
+
+static void update_sw_cntrs(struct msm_gpu *gpu)
+{
+	ktime_t time;
+	uint32_t elapsed;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpu->perf_lock, flags);
+	if (!gpu->perfcntr_active)
+		goto out;
+
+	time = ktime_get();
+	elapsed = ktime_to_us(ktime_sub(time, gpu->last_sample.time));
+
+	gpu->totaltime += elapsed;
+	if (gpu->last_sample.active)
+		gpu->activetime += elapsed;
+
+	gpu->last_sample.active = msm_gpu_active(gpu);
+	gpu->last_sample.time = time;
+
+out:
+	spin_unlock_irqrestore(&gpu->perf_lock, flags);
+}
+
+void msm_gpu_perfcntr_start(struct msm_gpu *gpu)
+{
+	unsigned long flags;
+
+	pm_runtime_get_sync(&gpu->pdev->dev);
+
+	spin_lock_irqsave(&gpu->perf_lock, flags);
+	/* we could dynamically enable/disable perfcntr registers too.. */
+	gpu->last_sample.active = msm_gpu_active(gpu);
+	gpu->last_sample.time = ktime_get();
+	gpu->activetime = gpu->totaltime = 0;
+	gpu->perfcntr_active = true;
+	update_hw_cntrs(gpu, 0, NULL);
+	spin_unlock_irqrestore(&gpu->perf_lock, flags);
+}
+
+void msm_gpu_perfcntr_stop(struct msm_gpu *gpu)
+{
+	gpu->perfcntr_active = false;
+	pm_runtime_put_sync(&gpu->pdev->dev);
+}
+
+/* returns -errno or # of cntrs sampled */
+int msm_gpu_perfcntr_sample(struct msm_gpu *gpu, uint32_t *activetime,
+		uint32_t *totaltime, uint32_t ncntrs, uint32_t *cntrs)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&gpu->perf_lock, flags);
+
+	if (!gpu->perfcntr_active) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	*activetime = gpu->activetime;
+	*totaltime = gpu->totaltime;
+
+	gpu->activetime = gpu->totaltime = 0;
+
+	ret = update_hw_cntrs(gpu, ncntrs, cntrs);
+
+out:
+	spin_unlock_irqrestore(&gpu->perf_lock, flags);
+
+	return ret;
+}
+
+/*
+ * Cmdstream submission/retirement:
+ */
+
+static void retire_submit(struct msm_gpu *gpu, struct msm_ringbuffer *ring,
+		struct msm_gem_submit *submit)
+{
+	int index = submit->seqno % MSM_GPU_SUBMIT_STATS_COUNT;
+	volatile struct msm_gpu_submit_stats *stats;
+	u64 elapsed, clock = 0, cycles;
+	unsigned long flags;
+
+	stats = &ring->memptrs->stats[index];
+	/* Convert 19.2Mhz alwayson ticks to nanoseconds for elapsed time */
+	elapsed = (stats->alwayson_end - stats->alwayson_start) * 10000;
+	do_div(elapsed, 192);
+
+	cycles = stats->cpcycles_end - stats->cpcycles_start;
+
+	/* Calculate the clock frequency from the number of CP cycles */
+	if (elapsed) {
+		clock = cycles * 1000;
+		do_div(clock, elapsed);
+	}
+
+	submit->queue->ctx->elapsed_ns += elapsed;
+	submit->queue->ctx->cycles     += cycles;
+
+	trace_msm_gpu_submit_retired(submit, elapsed, clock,
+		stats->alwayson_start, stats->alwayson_end);
+
+	msm_submit_retire(submit);
+
+	pm_runtime_mark_last_busy(&gpu->pdev->dev);
+
+	spin_lock_irqsave(&ring->submit_lock, flags);
+	list_del(&submit->node);
+	spin_unlock_irqrestore(&ring->submit_lock, flags);
+
+	/* Update devfreq on transition from active->idle: */
+	mutex_lock(&gpu->active_lock);
+	gpu->active_submits--;
+	WARN_ON(gpu->active_submits < 0);
+	if (!gpu->active_submits) {
+		msm_devfreq_idle(gpu);
+		pm_runtime_put_autosuspend(&gpu->pdev->dev);
+	}
+
+	mutex_unlock(&gpu->active_lock);
+
+	msm_gem_submit_put(submit);
+}
+
+static void retire_submits(struct msm_gpu *gpu)
+{
+	int i;
+
+	/* Retire the commits starting with highest priority */
+	for (i = 0; i < gpu->nr_rings; i++) {
+		struct msm_ringbuffer *ring = gpu->rb[i];
+
+		while (true) {
+			struct msm_gem_submit *submit = NULL;
+			unsigned long flags;
+
+			spin_lock_irqsave(&ring->submit_lock, flags);
+			submit = list_first_entry_or_null(&ring->submits,
+					struct msm_gem_submit, node);
+			spin_unlock_irqrestore(&ring->submit_lock, flags);
+
+			/*
+			 * If no submit, we are done.  If submit->fence hasn't
+			 * been signalled, then later submits are not signalled
+			 * either, so we are also done.
+			 */
+			if (submit && dma_fence_is_signaled(submit->hw_fence)) {
+				retire_submit(gpu, ring, submit);
+			} else {
+				break;
+			}
+		}
+	}
+
+	wake_up_all(&gpu->retire_event);
+}
+
+static void retire_worker(struct kthread_work *work)
+{
+	struct msm_gpu *gpu = container_of(work, struct msm_gpu, retire_work);
+
+	retire_submits(gpu);
+}
+
+/* call from irq handler to schedule work to retire bo's */
+void msm_gpu_retire(struct msm_gpu *gpu)
+{
+	int i;
+
+	for (i = 0; i < gpu->nr_rings; i++)
+		msm_update_fence(gpu->rb[i]->fctx, gpu->rb[i]->memptrs->fence);
+
+	kthread_queue_work(gpu->worker, &gpu->retire_work);
+	update_sw_cntrs(gpu);
+}
+
+/* add bo's to gpu's ring, and kick gpu: */
+void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)
+{
+	struct msm_ringbuffer *ring = submit->ring;
+	unsigned long flags;
+
+	WARN_ON(!mutex_is_locked(&gpu->lock));
+
+	pm_runtime_get_sync(&gpu->pdev->dev);
+
+	msm_gpu_hw_init(gpu);
+
+	submit->seqno = submit->hw_fence->seqno;
+
+	update_sw_cntrs(gpu);
+
+	/*
+	 * ring->submits holds a ref to the submit, to deal with the case
+	 * that a submit completes before msm_ioctl_gem_submit() returns.
+	 */
+	msm_gem_submit_get(submit);
+
+	spin_lock_irqsave(&ring->submit_lock, flags);
+	list_add_tail(&submit->node, &ring->submits);
+	spin_unlock_irqrestore(&ring->submit_lock, flags);
+
+	/* Update devfreq on transition from idle->active: */
+	mutex_lock(&gpu->active_lock);
+	if (!gpu->active_submits) {
+		pm_runtime_get(&gpu->pdev->dev);
+		msm_devfreq_active(gpu);
+	}
+	gpu->active_submits++;
+	mutex_unlock(&gpu->active_lock);
+
+	gpu->funcs->submit(gpu, submit);
+	gpu->cur_ctx_seqno = submit->queue->ctx->seqno;
+
+	pm_runtime_put(&gpu->pdev->dev);
+	hangcheck_timer_reset(gpu);
+}
+
+/*
+ * Init/Cleanup:
+ */
+
+static irqreturn_t irq_handler(int irq, void *data)
+{
+	struct msm_gpu *gpu = data;
+	return gpu->funcs->irq(gpu);
+}
+
+static int get_clocks(struct platform_device *pdev, struct msm_gpu *gpu)
+{
+	int ret = devm_clk_bulk_get_all(&pdev->dev, &gpu->grp_clks);
+
+	if (ret < 1) {
+		gpu->nr_clocks = 0;
+		return ret;
+	}
+
+	gpu->nr_clocks = ret;
+
+	gpu->core_clk = msm_clk_bulk_get_clock(gpu->grp_clks,
+		gpu->nr_clocks, "core");
+
+	gpu->rbbmtimer_clk = msm_clk_bulk_get_clock(gpu->grp_clks,
+		gpu->nr_clocks, "rbbmtimer");
+
+	return 0;
+}
+
+/* Return a new address space for a msm_drm_private instance */
+struct msm_gem_address_space *
+msm_gpu_create_private_address_space(struct msm_gpu *gpu, struct task_struct *task)
+{
+	struct msm_gem_address_space *aspace = NULL;
+	if (!gpu)
+		return NULL;
+
+	/*
+	 * If the target doesn't support private address spaces then return
+	 * the global one
+	 */
+	if (gpu->funcs->create_private_address_space) {
+		aspace = gpu->funcs->create_private_address_space(gpu);
+		if (!IS_ERR(aspace))
+			aspace->pid = get_pid(task_pid(task));
+	}
+
+	if (IS_ERR_OR_NULL(aspace))
+		aspace = msm_gem_address_space_get(gpu->aspace);
+
+	return aspace;
+}
+
+int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
+		struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
+		const char *name, struct msm_gpu_config *config)
+{
+	struct msm_drm_private *priv = drm->dev_private;
+	int i, ret, nr_rings = config->nr_rings;
+	void *memptrs;
+	uint64_t memptrs_iova;
+
+	if (WARN_ON(gpu->num_perfcntrs > ARRAY_SIZE(gpu->last_cntrs)))
+		gpu->num_perfcntrs = ARRAY_SIZE(gpu->last_cntrs);
+
+	gpu->dev = drm;
+	gpu->funcs = funcs;
+	gpu->name = name;
+
+	gpu->worker = kthread_create_worker(0, "gpu-worker");
+	if (IS_ERR(gpu->worker)) {
+		ret = PTR_ERR(gpu->worker);
+		gpu->worker = NULL;
+		goto fail;
+	}
+
+	sched_set_fifo_low(gpu->worker->task);
+
+	mutex_init(&gpu->active_lock);
+	mutex_init(&gpu->lock);
+	init_waitqueue_head(&gpu->retire_event);
+	kthread_init_work(&gpu->retire_work, retire_worker);
+	kthread_init_work(&gpu->recover_work, recover_worker);
+	kthread_init_work(&gpu->fault_work, fault_worker);
+
+	priv->hangcheck_period = DRM_MSM_HANGCHECK_DEFAULT_PERIOD;
+
+	/*
+	 * If progress detection is supported, halve the hangcheck timer
+	 * duration, as it takes two iterations of the hangcheck handler
+	 * to detect a hang.
+	 */
+	if (funcs->progress)
+		priv->hangcheck_period /= 2;
+
+	timer_setup(&gpu->hangcheck_timer, hangcheck_handler, 0);
+
+	spin_lock_init(&gpu->perf_lock);
+
+
+	/* Map registers: */
+	gpu->mmio = msm_ioremap(pdev, config->ioname);
+	if (IS_ERR(gpu->mmio)) {
+		ret = PTR_ERR(gpu->mmio);
+		goto fail;
+	}
+
+	/* Get Interrupt: */
+	gpu->irq = platform_get_irq(pdev, 0);
+	if (gpu->irq < 0) {
+		ret = gpu->irq;
+		goto fail;
+	}
+
+	ret = devm_request_irq(&pdev->dev, gpu->irq, irq_handler,
+			IRQF_TRIGGER_HIGH, "gpu-irq", gpu);
+	if (ret) {
+		DRM_DEV_ERROR(drm->dev, "failed to request IRQ%u: %d\n", gpu->irq, ret);
+		goto fail;
+	}
+
+	ret = get_clocks(pdev, gpu);
+	if (ret)
+		goto fail;
+
+	gpu->ebi1_clk = msm_clk_get(pdev, "bus");
+	DBG("ebi1_clk: %p", gpu->ebi1_clk);
+	if (IS_ERR(gpu->ebi1_clk))
+		gpu->ebi1_clk = NULL;
+
+	/* Acquire regulators: */
+	gpu->gpu_reg = devm_regulator_get(&pdev->dev, "vdd");
+	DBG("gpu_reg: %p", gpu->gpu_reg);
+	if (IS_ERR(gpu->gpu_reg))
+		gpu->gpu_reg = NULL;
+
+	gpu->gpu_cx = devm_regulator_get(&pdev->dev, "vddcx");
+	DBG("gpu_cx: %p", gpu->gpu_cx);
+	if (IS_ERR(gpu->gpu_cx))
+		gpu->gpu_cx = NULL;
+
+	platform_set_drvdata(pdev, &gpu->adreno_smmu);
+
+	msm_devfreq_init(gpu);
+
+
+	gpu->aspace = gpu->funcs->create_address_space(gpu, pdev);
+
+	if (gpu->aspace == NULL)
+		DRM_DEV_INFO(drm->dev, "%s: no IOMMU, fallback to VRAM carveout!\n", name);
+	else if (IS_ERR(gpu->aspace)) {
+		ret = PTR_ERR(gpu->aspace);
+		goto fail;
+	}
+
+	memptrs = msm_gem_kernel_new(drm,
+		sizeof(struct msm_rbmemptrs) * nr_rings,
+		check_apriv(gpu, MSM_BO_WC), gpu->aspace, &gpu->memptrs_bo,
+		&memptrs_iova);
+
+	if (IS_ERR(memptrs)) {
+		ret = PTR_ERR(memptrs);
+		DRM_DEV_ERROR(drm->dev, "could not allocate memptrs: %d\n", ret);
+		goto fail;
+	}
+
+	msm_gem_object_set_name(gpu->memptrs_bo, "memptrs");
+
+	if (nr_rings > ARRAY_SIZE(gpu->rb)) {
+		DRM_DEV_INFO_ONCE(drm->dev, "Only creating %zu ringbuffers\n",
+			ARRAY_SIZE(gpu->rb));
+		nr_rings = ARRAY_SIZE(gpu->rb);
+	}
+
+	/* Create ringbuffer(s): */
+	for (i = 0; i < nr_rings; i++) {
+		gpu->rb[i] = msm_ringbuffer_new(gpu, i, memptrs, memptrs_iova);
+
+		if (IS_ERR(gpu->rb[i])) {
+			ret = PTR_ERR(gpu->rb[i]);
+			DRM_DEV_ERROR(drm->dev,
+				"could not create ringbuffer %d: %d\n", i, ret);
+			goto fail;
+		}
+
+		memptrs += sizeof(struct msm_rbmemptrs);
+		memptrs_iova += sizeof(struct msm_rbmemptrs);
+	}
+
+	gpu->nr_rings = nr_rings;
+
+	refcount_set(&gpu->sysprof_active, 1);
+
+	return 0;
+
+fail:
+	for (i = 0; i < ARRAY_SIZE(gpu->rb); i++)  {
+		msm_ringbuffer_destroy(gpu->rb[i]);
+		gpu->rb[i] = NULL;
+	}
+
+	msm_gem_kernel_put(gpu->memptrs_bo, gpu->aspace);
+
+	platform_set_drvdata(pdev, NULL);
+	return ret;
+}
+
+void msm_gpu_cleanup(struct msm_gpu *gpu)
+{
+	int i;
+
+	DBG("%s", gpu->name);
+
+	for (i = 0; i < ARRAY_SIZE(gpu->rb); i++) {
+		msm_ringbuffer_destroy(gpu->rb[i]);
+		gpu->rb[i] = NULL;
+	}
+
+	msm_gem_kernel_put(gpu->memptrs_bo, gpu->aspace);
+
+	if (!IS_ERR_OR_NULL(gpu->aspace)) {
+		gpu->aspace->mmu->funcs->detach(gpu->aspace->mmu);
+		msm_gem_address_space_put(gpu->aspace);
+	}
+
+	if (gpu->worker) {
+		kthread_destroy_worker(gpu->worker);
+	}
+
+	msm_devfreq_cleanup(gpu);
+
+	platform_set_drvdata(gpu->pdev, NULL);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_gpu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_gpu.h
@@ -0,0 +1,710 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __MSM_GPU_H__
+#define __MSM_GPU_H__
+
+#include <linux/adreno-smmu-priv.h>
+#include <linux/clk.h>
+#include <linux/devfreq.h>
+#include <linux/interconnect.h>
+#include <linux/pm_opp.h>
+#include <linux/regulator/consumer.h>
+
+#include "msm_drv.h"
+#include "msm_fence.h"
+#include "msm_ringbuffer.h"
+#include "msm_gem.h"
+
+struct msm_gem_submit;
+struct msm_gpu_perfcntr;
+struct msm_gpu_state;
+struct msm_file_private;
+
+struct msm_gpu_config {
+	const char *ioname;
+	unsigned int nr_rings;
+};
+
+/* So far, with hardware that I've seen to date, we can have:
+ *  + zero, one, or two z180 2d cores
+ *  + a3xx or a2xx 3d core, which share a common CP (the firmware
+ *    for the CP seems to implement some different PM4 packet types
+ *    but the basics of cmdstream submission are the same)
+ *
+ * Which means that the eventual complete "class" hierarchy, once
+ * support for all past and present hw is in place, becomes:
+ *  + msm_gpu
+ *    + adreno_gpu
+ *      + a3xx_gpu
+ *      + a2xx_gpu
+ *    + z180_gpu
+ */
+struct msm_gpu_funcs {
+	int (*get_param)(struct msm_gpu *gpu, struct msm_file_private *ctx,
+			 uint32_t param, uint64_t *value, uint32_t *len);
+	int (*set_param)(struct msm_gpu *gpu, struct msm_file_private *ctx,
+			 uint32_t param, uint64_t value, uint32_t len);
+	int (*hw_init)(struct msm_gpu *gpu);
+
+	/**
+	 * @ucode_load: Optional hook to upload fw to GEM objs
+	 */
+	int (*ucode_load)(struct msm_gpu *gpu);
+
+	int (*pm_suspend)(struct msm_gpu *gpu);
+	int (*pm_resume)(struct msm_gpu *gpu);
+	void (*submit)(struct msm_gpu *gpu, struct msm_gem_submit *submit);
+	void (*flush)(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
+	irqreturn_t (*irq)(struct msm_gpu *irq);
+	struct msm_ringbuffer *(*active_ring)(struct msm_gpu *gpu);
+	void (*recover)(struct msm_gpu *gpu);
+	void (*destroy)(struct msm_gpu *gpu);
+#if defined(CONFIG_DEBUG_FS) || defined(CONFIG_DEV_COREDUMP)
+	/* show GPU status in debugfs: */
+	void (*show)(struct msm_gpu *gpu, struct msm_gpu_state *state,
+			struct drm_printer *p);
+	/* for generation specific debugfs: */
+	void (*debugfs_init)(struct msm_gpu *gpu, struct drm_minor *minor);
+#endif
+	/* note: gpu_busy() can assume that we have been pm_resumed */
+	u64 (*gpu_busy)(struct msm_gpu *gpu, unsigned long *out_sample_rate);
+	struct msm_gpu_state *(*gpu_state_get)(struct msm_gpu *gpu);
+	int (*gpu_state_put)(struct msm_gpu_state *state);
+	unsigned long (*gpu_get_freq)(struct msm_gpu *gpu);
+	/* note: gpu_set_freq() can assume that we have been pm_resumed */
+	void (*gpu_set_freq)(struct msm_gpu *gpu, struct dev_pm_opp *opp,
+			     bool suspended);
+	struct msm_gem_address_space *(*create_address_space)
+		(struct msm_gpu *gpu, struct platform_device *pdev);
+	struct msm_gem_address_space *(*create_private_address_space)
+		(struct msm_gpu *gpu);
+	uint32_t (*get_rptr)(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
+
+	/**
+	 * progress: Has the GPU made progress?
+	 *
+	 * Return true if GPU position in cmdstream has advanced (or changed)
+	 * since the last call.  To avoid false negatives, this should account
+	 * for cmdstream that is buffered in this FIFO upstream of the CP fw.
+	 */
+	bool (*progress)(struct msm_gpu *gpu, struct msm_ringbuffer *ring);
+};
+
+/* Additional state for iommu faults: */
+struct msm_gpu_fault_info {
+	u64 ttbr0;
+	unsigned long iova;
+	int flags;
+	const char *type;
+	const char *block;
+};
+
+/**
+ * struct msm_gpu_devfreq - devfreq related state
+ */
+struct msm_gpu_devfreq {
+	/** devfreq: devfreq instance */
+	struct devfreq *devfreq;
+
+	/** lock: lock for "suspended", "busy_cycles", and "time" */
+	struct mutex lock;
+
+	/**
+	 * idle_freq:
+	 *
+	 * Shadow frequency used while the GPU is idle.  From the PoV of
+	 * the devfreq governor, we are continuing to sample busyness and
+	 * adjust frequency while the GPU is idle, but we use this shadow
+	 * value as the GPU is actually clamped to minimum frequency while
+	 * it is inactive.
+	 */
+	unsigned long idle_freq;
+
+	/**
+	 * boost_constraint:
+	 *
+	 * A PM QoS constraint to boost min freq for a period of time
+	 * until the boost expires.
+	 */
+	struct dev_pm_qos_request boost_freq;
+
+	/**
+	 * busy_cycles: Last busy counter value, for calculating elapsed busy
+	 * cycles since last sampling period.
+	 */
+	u64 busy_cycles;
+
+	/** time: Time of last sampling period. */
+	ktime_t time;
+
+	/** idle_time: Time of last transition to idle: */
+	ktime_t idle_time;
+
+	/**
+	 * idle_work:
+	 *
+	 * Used to delay clamping to idle freq on active->idle transition.
+	 */
+	struct msm_hrtimer_work idle_work;
+
+	/**
+	 * boost_work:
+	 *
+	 * Used to reset the boost_constraint after the boost period has
+	 * elapsed
+	 */
+	struct msm_hrtimer_work boost_work;
+
+	/** suspended: tracks if we're suspended */
+	bool suspended;
+};
+
+struct msm_gpu {
+	const char *name;
+	struct drm_device *dev;
+	struct platform_device *pdev;
+	const struct msm_gpu_funcs *funcs;
+
+	struct adreno_smmu_priv adreno_smmu;
+
+	/* performance counters (hw & sw): */
+	spinlock_t perf_lock;
+	bool perfcntr_active;
+	struct {
+		bool active;
+		ktime_t time;
+	} last_sample;
+	uint32_t totaltime, activetime;    /* sw counters */
+	uint32_t last_cntrs[5];            /* hw counters */
+	const struct msm_gpu_perfcntr *perfcntrs;
+	uint32_t num_perfcntrs;
+
+	struct msm_ringbuffer *rb[MSM_GPU_MAX_RINGS];
+	int nr_rings;
+
+	/**
+	 * sysprof_active:
+	 *
+	 * The count of contexts that have enabled system profiling.
+	 */
+	refcount_t sysprof_active;
+
+	/**
+	 * cur_ctx_seqno:
+	 *
+	 * The ctx->seqno value of the last context to submit rendering,
+	 * and the one with current pgtables installed (for generations
+	 * that support per-context pgtables).  Tracked by seqno rather
+	 * than pointer value to avoid dangling pointers, and cases where
+	 * a ctx can be freed and a new one created with the same address.
+	 */
+	int cur_ctx_seqno;
+
+	/**
+	 * lock:
+	 *
+	 * General lock for serializing all the gpu things.
+	 *
+	 * TODO move to per-ring locking where feasible (ie. submit/retire
+	 * path, etc)
+	 */
+	struct mutex lock;
+
+	/**
+	 * active_submits:
+	 *
+	 * The number of submitted but not yet retired submits, used to
+	 * determine transitions between active and idle.
+	 *
+	 * Protected by active_lock
+	 */
+	int active_submits;
+
+	/** lock: protects active_submits and idle/active transitions */
+	struct mutex active_lock;
+
+	/* does gpu need hw_init? */
+	bool needs_hw_init;
+
+	/**
+	 * global_faults: number of GPU hangs not attributed to a particular
+	 * address space
+	 */
+	int global_faults;
+
+	void __iomem *mmio;
+	int irq;
+
+	struct msm_gem_address_space *aspace;
+
+	/* Power Control: */
+	struct regulator *gpu_reg, *gpu_cx;
+	struct clk_bulk_data *grp_clks;
+	int nr_clocks;
+	struct clk *ebi1_clk, *core_clk, *rbbmtimer_clk;
+	uint32_t fast_rate;
+
+	/* Hang and Inactivity Detection:
+	 */
+#define DRM_MSM_INACTIVE_PERIOD   66 /* in ms (roughly four frames) */
+
+#define DRM_MSM_HANGCHECK_DEFAULT_PERIOD 500 /* in ms */
+#define DRM_MSM_HANGCHECK_PROGRESS_RETRIES 3
+	struct timer_list hangcheck_timer;
+
+	/* Fault info for most recent iova fault: */
+	struct msm_gpu_fault_info fault_info;
+
+	/* work for handling GPU ioval faults: */
+	struct kthread_work fault_work;
+
+	/* work for handling GPU recovery: */
+	struct kthread_work recover_work;
+
+	/** retire_event: notified when submits are retired: */
+	wait_queue_head_t retire_event;
+
+	/* work for handling active-list retiring: */
+	struct kthread_work retire_work;
+
+	/* worker for retire/recover: */
+	struct kthread_worker *worker;
+
+	struct drm_gem_object *memptrs_bo;
+
+	struct msm_gpu_devfreq devfreq;
+
+	uint32_t suspend_count;
+
+	struct msm_gpu_state *crashstate;
+
+	/* True if the hardware supports expanded apriv (a650 and newer) */
+	bool hw_apriv;
+
+	/**
+	 * @allow_relocs: allow relocs in SUBMIT ioctl
+	 *
+	 * Mesa won't use relocs for driver version 1.4.0 and later.  This
+	 * switch-over happened early enough in mesa a6xx bringup that we
+	 * can disallow relocs for a6xx and newer.
+	 */
+	bool allow_relocs;
+
+	struct thermal_cooling_device *cooling;
+};
+
+static inline struct msm_gpu *dev_to_gpu(struct device *dev)
+{
+	struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(dev);
+
+	if (!adreno_smmu)
+		return NULL;
+
+	return container_of(adreno_smmu, struct msm_gpu, adreno_smmu);
+}
+
+/* It turns out that all targets use the same ringbuffer size */
+#define MSM_GPU_RINGBUFFER_SZ SZ_32K
+#define MSM_GPU_RINGBUFFER_BLKSIZE 32
+
+#define MSM_GPU_RB_CNTL_DEFAULT \
+		(AXXX_CP_RB_CNTL_BUFSZ(ilog2(MSM_GPU_RINGBUFFER_SZ / 8)) | \
+		AXXX_CP_RB_CNTL_BLKSZ(ilog2(MSM_GPU_RINGBUFFER_BLKSIZE / 8)))
+
+static inline bool msm_gpu_active(struct msm_gpu *gpu)
+{
+	int i;
+
+	for (i = 0; i < gpu->nr_rings; i++) {
+		struct msm_ringbuffer *ring = gpu->rb[i];
+
+		if (fence_after(ring->fctx->last_fence, ring->memptrs->fence))
+			return true;
+	}
+
+	return false;
+}
+
+/* Perf-Counters:
+ * The select_reg and select_val are just there for the benefit of the child
+ * class that actually enables the perf counter..  but msm_gpu base class
+ * will handle sampling/displaying the counters.
+ */
+
+struct msm_gpu_perfcntr {
+	uint32_t select_reg;
+	uint32_t sample_reg;
+	uint32_t select_val;
+	const char *name;
+};
+
+/*
+ * The number of priority levels provided by drm gpu scheduler.  The
+ * DRM_SCHED_PRIORITY_KERNEL priority level is treated specially in some
+ * cases, so we don't use it (no need for kernel generated jobs).
+ */
+#define NR_SCHED_PRIORITIES (1 + DRM_SCHED_PRIORITY_LOW - DRM_SCHED_PRIORITY_HIGH)
+
+/**
+ * struct msm_file_private - per-drm_file context
+ *
+ * @queuelock:    synchronizes access to submitqueues list
+ * @submitqueues: list of &msm_gpu_submitqueue created by userspace
+ * @queueid:      counter incremented each time a submitqueue is created,
+ *                used to assign &msm_gpu_submitqueue.id
+ * @aspace:       the per-process GPU address-space
+ * @ref:          reference count
+ * @seqno:        unique per process seqno
+ */
+struct msm_file_private {
+	rwlock_t queuelock;
+	struct list_head submitqueues;
+	int queueid;
+	struct msm_gem_address_space *aspace;
+	struct kref ref;
+	int seqno;
+
+	/**
+	 * sysprof:
+	 *
+	 * The value of MSM_PARAM_SYSPROF set by userspace.  This is
+	 * intended to be used by system profiling tools like Mesa's
+	 * pps-producer (perfetto), and restricted to CAP_SYS_ADMIN.
+	 *
+	 * Setting a value of 1 will preserve performance counters across
+	 * context switches.  Setting a value of 2 will in addition
+	 * suppress suspend.  (Performance counters lose state across
+	 * power collapse, which is undesirable for profiling in some
+	 * cases.)
+	 *
+	 * The value automatically reverts to zero when the drm device
+	 * file is closed.
+	 */
+	int sysprof;
+
+	/**
+	 * comm: Overridden task comm, see MSM_PARAM_COMM
+	 *
+	 * Accessed under msm_gpu::lock
+	 */
+	char *comm;
+
+	/**
+	 * cmdline: Overridden task cmdline, see MSM_PARAM_CMDLINE
+	 *
+	 * Accessed under msm_gpu::lock
+	 */
+	char *cmdline;
+
+	/**
+	 * elapsed:
+	 *
+	 * The total (cumulative) elapsed time GPU was busy with rendering
+	 * from this context in ns.
+	 */
+	uint64_t elapsed_ns;
+
+	/**
+	 * cycles:
+	 *
+	 * The total (cumulative) GPU cycles elapsed attributed to this
+	 * context.
+	 */
+	uint64_t cycles;
+
+	/**
+	 * entities:
+	 *
+	 * Table of per-priority-level sched entities used by submitqueues
+	 * associated with this &drm_file.  Because some userspace apps
+	 * make assumptions about rendering from multiple gl contexts
+	 * (of the same priority) within the process happening in FIFO
+	 * order without requiring any fencing beyond MakeCurrent(), we
+	 * create at most one &drm_sched_entity per-process per-priority-
+	 * level.
+	 */
+	struct drm_sched_entity *entities[NR_SCHED_PRIORITIES * MSM_GPU_MAX_RINGS];
+};
+
+/**
+ * msm_gpu_convert_priority - Map userspace priority to ring # and sched priority
+ *
+ * @gpu:        the gpu instance
+ * @prio:       the userspace priority level
+ * @ring_nr:    [out] the ringbuffer the userspace priority maps to
+ * @sched_prio: [out] the gpu scheduler priority level which the userspace
+ *              priority maps to
+ *
+ * With drm/scheduler providing it's own level of prioritization, our total
+ * number of available priority levels is (nr_rings * NR_SCHED_PRIORITIES).
+ * Each ring is associated with it's own scheduler instance.  However, our
+ * UABI is that lower numerical values are higher priority.  So mapping the
+ * single userspace priority level into ring_nr and sched_prio takes some
+ * care.  The userspace provided priority (when a submitqueue is created)
+ * is mapped to ring nr and scheduler priority as such:
+ *
+ *   ring_nr    = userspace_prio / NR_SCHED_PRIORITIES
+ *   sched_prio = NR_SCHED_PRIORITIES -
+ *                (userspace_prio % NR_SCHED_PRIORITIES) - 1
+ *
+ * This allows generations without preemption (nr_rings==1) to have some
+ * amount of prioritization, and provides more priority levels for gens
+ * that do have preemption.
+ */
+static inline int msm_gpu_convert_priority(struct msm_gpu *gpu, int prio,
+		unsigned *ring_nr, enum drm_sched_priority *sched_prio)
+{
+	unsigned rn, sp;
+
+	rn = div_u64_rem(prio, NR_SCHED_PRIORITIES, &sp);
+
+	/* invert sched priority to map to higher-numeric-is-higher-
+	 * priority convention
+	 */
+	sp = NR_SCHED_PRIORITIES - sp - 1;
+
+	if (rn >= gpu->nr_rings)
+		return -EINVAL;
+
+	*ring_nr = rn;
+	*sched_prio = sp;
+
+	return 0;
+}
+
+/**
+ * struct msm_gpu_submitqueues - Userspace created context.
+ *
+ * A submitqueue is associated with a gl context or vk queue (or equiv)
+ * in userspace.
+ *
+ * @id:        userspace id for the submitqueue, unique within the drm_file
+ * @flags:     userspace flags for the submitqueue, specified at creation
+ *             (currently unusued)
+ * @ring_nr:   the ringbuffer used by this submitqueue, which is determined
+ *             by the submitqueue's priority
+ * @faults:    the number of GPU hangs associated with this submitqueue
+ * @last_fence: the sequence number of the last allocated fence (for error
+ *             checking)
+ * @ctx:       the per-drm_file context associated with the submitqueue (ie.
+ *             which set of pgtables do submits jobs associated with the
+ *             submitqueue use)
+ * @node:      node in the context's list of submitqueues
+ * @fence_idr: maps fence-id to dma_fence for userspace visible fence
+ *             seqno, protected by submitqueue lock
+ * @idr_lock:  for serializing access to fence_idr
+ * @lock:      submitqueue lock for serializing submits on a queue
+ * @ref:       reference count
+ * @entity:    the submit job-queue
+ */
+struct msm_gpu_submitqueue {
+	int id;
+	u32 flags;
+	u32 ring_nr;
+	int faults;
+	uint32_t last_fence;
+	struct msm_file_private *ctx;
+	struct list_head node;
+	struct idr fence_idr;
+	struct spinlock idr_lock;
+	struct mutex lock;
+	struct kref ref;
+	struct drm_sched_entity *entity;
+};
+
+struct msm_gpu_state_bo {
+	u64 iova;
+	size_t size;
+	void *data;
+	bool encoded;
+	char name[32];
+};
+
+struct msm_gpu_state {
+	struct kref ref;
+	struct timespec64 time;
+
+	struct {
+		u64 iova;
+		u32 fence;
+		u32 seqno;
+		u32 rptr;
+		u32 wptr;
+		void *data;
+		int data_size;
+		bool encoded;
+	} ring[MSM_GPU_MAX_RINGS];
+
+	int nr_registers;
+	u32 *registers;
+
+	u32 rbbm_status;
+
+	char *comm;
+	char *cmd;
+
+	struct msm_gpu_fault_info fault_info;
+
+	int nr_bos;
+	struct msm_gpu_state_bo *bos;
+};
+
+static inline void gpu_write(struct msm_gpu *gpu, u32 reg, u32 data)
+{
+	msm_writel(data, gpu->mmio + (reg << 2));
+}
+
+static inline u32 gpu_read(struct msm_gpu *gpu, u32 reg)
+{
+	return msm_readl(gpu->mmio + (reg << 2));
+}
+
+static inline void gpu_rmw(struct msm_gpu *gpu, u32 reg, u32 mask, u32 or)
+{
+	msm_rmw(gpu->mmio + (reg << 2), mask, or);
+}
+
+static inline u64 gpu_read64(struct msm_gpu *gpu, u32 reg)
+{
+	u64 val;
+
+	/*
+	 * Why not a readq here? Two reasons: 1) many of the LO registers are
+	 * not quad word aligned and 2) the GPU hardware designers have a bit
+	 * of a history of putting registers where they fit, especially in
+	 * spins. The longer a GPU family goes the higher the chance that
+	 * we'll get burned.  We could do a series of validity checks if we
+	 * wanted to, but really is a readq() that much better? Nah.
+	 */
+
+	/*
+	 * For some lo/hi registers (like perfcounters), the hi value is latched
+	 * when the lo is read, so make sure to read the lo first to trigger
+	 * that
+	 */
+	val = (u64) msm_readl(gpu->mmio + (reg << 2));
+	val |= ((u64) msm_readl(gpu->mmio + ((reg + 1) << 2)) << 32);
+
+	return val;
+}
+
+static inline void gpu_write64(struct msm_gpu *gpu, u32 reg, u64 val)
+{
+	/* Why not a writeq here? Read the screed above */
+	msm_writel(lower_32_bits(val), gpu->mmio + (reg << 2));
+	msm_writel(upper_32_bits(val), gpu->mmio + ((reg + 1) << 2));
+}
+
+int msm_gpu_pm_suspend(struct msm_gpu *gpu);
+int msm_gpu_pm_resume(struct msm_gpu *gpu);
+
+void msm_gpu_show_fdinfo(struct msm_gpu *gpu, struct msm_file_private *ctx,
+			 struct drm_printer *p);
+
+int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx);
+struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
+		u32 id);
+int msm_submitqueue_create(struct drm_device *drm,
+		struct msm_file_private *ctx,
+		u32 prio, u32 flags, u32 *id);
+int msm_submitqueue_query(struct drm_device *drm, struct msm_file_private *ctx,
+		struct drm_msm_submitqueue_query *args);
+int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id);
+void msm_submitqueue_close(struct msm_file_private *ctx);
+
+void msm_submitqueue_destroy(struct kref *kref);
+
+int msm_file_private_set_sysprof(struct msm_file_private *ctx,
+				 struct msm_gpu *gpu, int sysprof);
+void __msm_file_private_destroy(struct kref *kref);
+
+static inline void msm_file_private_put(struct msm_file_private *ctx)
+{
+	kref_put(&ctx->ref, __msm_file_private_destroy);
+}
+
+static inline struct msm_file_private *msm_file_private_get(
+	struct msm_file_private *ctx)
+{
+	kref_get(&ctx->ref);
+	return ctx;
+}
+
+void msm_devfreq_init(struct msm_gpu *gpu);
+void msm_devfreq_cleanup(struct msm_gpu *gpu);
+void msm_devfreq_resume(struct msm_gpu *gpu);
+void msm_devfreq_suspend(struct msm_gpu *gpu);
+void msm_devfreq_boost(struct msm_gpu *gpu, unsigned factor);
+void msm_devfreq_active(struct msm_gpu *gpu);
+void msm_devfreq_idle(struct msm_gpu *gpu);
+
+int msm_gpu_hw_init(struct msm_gpu *gpu);
+
+void msm_gpu_perfcntr_start(struct msm_gpu *gpu);
+void msm_gpu_perfcntr_stop(struct msm_gpu *gpu);
+int msm_gpu_perfcntr_sample(struct msm_gpu *gpu, uint32_t *activetime,
+		uint32_t *totaltime, uint32_t ncntrs, uint32_t *cntrs);
+
+void msm_gpu_retire(struct msm_gpu *gpu);
+void msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit);
+
+int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
+		struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
+		const char *name, struct msm_gpu_config *config);
+
+struct msm_gem_address_space *
+msm_gpu_create_private_address_space(struct msm_gpu *gpu, struct task_struct *task);
+
+void msm_gpu_cleanup(struct msm_gpu *gpu);
+
+struct msm_gpu *adreno_load_gpu(struct drm_device *dev);
+void __init adreno_register(void);
+void __exit adreno_unregister(void);
+
+static inline void msm_submitqueue_put(struct msm_gpu_submitqueue *queue)
+{
+	if (queue)
+		kref_put(&queue->ref, msm_submitqueue_destroy);
+}
+
+static inline struct msm_gpu_state *msm_gpu_crashstate_get(struct msm_gpu *gpu)
+{
+	struct msm_gpu_state *state = NULL;
+
+	mutex_lock(&gpu->lock);
+
+	if (gpu->crashstate) {
+		kref_get(&gpu->crashstate->ref);
+		state = gpu->crashstate;
+	}
+
+	mutex_unlock(&gpu->lock);
+
+	return state;
+}
+
+static inline void msm_gpu_crashstate_put(struct msm_gpu *gpu)
+{
+	mutex_lock(&gpu->lock);
+
+	if (gpu->crashstate) {
+		if (gpu->funcs->gpu_state_put(gpu->crashstate))
+			gpu->crashstate = NULL;
+	}
+
+	mutex_unlock(&gpu->lock);
+}
+
+/*
+ * Simple macro to semi-cleanly add the MAP_PRIV flag for targets that can
+ * support expanded privileges
+ */
+#define check_apriv(gpu, flags) \
+	(((gpu)->hw_apriv ? MSM_BO_MAP_PRIV : 0) | (flags))
+
+
+#endif /* __MSM_GPU_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_gpu_devfreq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_gpu_devfreq.c
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include "msm_gpu.h"
+#include "msm_gpu_trace.h"
+
+#include <linux/devfreq.h>
+#include <linux/devfreq_cooling.h>
+#include <linux/math64.h>
+#include <linux/units.h>
+
+/*
+ * Power Management:
+ */
+
+static int msm_devfreq_target(struct device *dev, unsigned long *freq,
+		u32 flags)
+{
+	struct msm_gpu *gpu = dev_to_gpu(dev);
+	struct msm_gpu_devfreq *df = &gpu->devfreq;
+	struct dev_pm_opp *opp;
+
+	/*
+	 * Note that devfreq_recommended_opp() can modify the freq
+	 * to something that actually is in the opp table:
+	 */
+	opp = devfreq_recommended_opp(dev, freq, flags);
+	if (IS_ERR(opp))
+		return PTR_ERR(opp);
+
+	trace_msm_gpu_freq_change(dev_pm_opp_get_freq(opp));
+
+	/*
+	 * If the GPU is idle, devfreq is not aware, so just stash
+	 * the new target freq (to use when we return to active)
+	 */
+	if (df->idle_freq) {
+		df->idle_freq = *freq;
+		dev_pm_opp_put(opp);
+		return 0;
+	}
+
+	if (gpu->funcs->gpu_set_freq) {
+		mutex_lock(&df->lock);
+		gpu->funcs->gpu_set_freq(gpu, opp, df->suspended);
+		mutex_unlock(&df->lock);
+	} else {
+		dev_pm_opp_set_rate(dev, *freq);
+	}
+
+	dev_pm_opp_put(opp);
+
+	return 0;
+}
+
+static unsigned long get_freq(struct msm_gpu *gpu)
+{
+	struct msm_gpu_devfreq *df = &gpu->devfreq;
+
+	/*
+	 * If the GPU is idle, use the shadow/saved freq to avoid
+	 * confusing devfreq (which is unaware that we are switching
+	 * to lowest freq until the device is active again)
+	 */
+	if (df->idle_freq)
+		return df->idle_freq;
+
+	if (gpu->funcs->gpu_get_freq)
+		return gpu->funcs->gpu_get_freq(gpu);
+
+	return clk_get_rate(gpu->core_clk);
+}
+
+static int msm_devfreq_get_dev_status(struct device *dev,
+		struct devfreq_dev_status *status)
+{
+	struct msm_gpu *gpu = dev_to_gpu(dev);
+	struct msm_gpu_devfreq *df = &gpu->devfreq;
+	u64 busy_cycles, busy_time;
+	unsigned long sample_rate;
+	ktime_t time;
+
+	mutex_lock(&df->lock);
+
+	status->current_frequency = get_freq(gpu);
+	time = ktime_get();
+	status->total_time = ktime_us_delta(time, df->time);
+	df->time = time;
+
+	if (df->suspended) {
+		mutex_unlock(&df->lock);
+		status->busy_time = 0;
+		return 0;
+	}
+
+	busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate);
+	busy_time = busy_cycles - df->busy_cycles;
+	df->busy_cycles = busy_cycles;
+
+	mutex_unlock(&df->lock);
+
+	busy_time *= USEC_PER_SEC;
+	busy_time = div64_ul(busy_time, sample_rate);
+	if (WARN_ON(busy_time > ~0LU))
+		busy_time = ~0LU;
+
+	status->busy_time = busy_time;
+
+	return 0;
+}
+
+static int msm_devfreq_get_cur_freq(struct device *dev, unsigned long *freq)
+{
+	*freq = get_freq(dev_to_gpu(dev));
+
+	return 0;
+}
+
+static struct devfreq_dev_profile msm_devfreq_profile = {
+	.timer = DEVFREQ_TIMER_DELAYED,
+	.polling_ms = 50,
+	.target = msm_devfreq_target,
+	.get_dev_status = msm_devfreq_get_dev_status,
+	.get_cur_freq = msm_devfreq_get_cur_freq,
+};
+
+static void msm_devfreq_boost_work(struct kthread_work *work);
+static void msm_devfreq_idle_work(struct kthread_work *work);
+
+static bool has_devfreq(struct msm_gpu *gpu)
+{
+	struct msm_gpu_devfreq *df = &gpu->devfreq;
+	return !!df->devfreq;
+}
+
+void msm_devfreq_init(struct msm_gpu *gpu)
+{
+	struct msm_gpu_devfreq *df = &gpu->devfreq;
+	struct msm_drm_private *priv = gpu->dev->dev_private;
+
+	/* We need target support to do devfreq */
+	if (!gpu->funcs->gpu_busy)
+		return;
+
+	/*
+	 * Setup default values for simple_ondemand governor tuning.  We
+	 * want to throttle up at 50% load for the double-buffer case,
+	 * where due to stalling waiting for vblank we could get stuck
+	 * at (for ex) 30fps at 50% utilization.
+	 */
+	priv->gpu_devfreq_config.upthreshold = 50;
+	priv->gpu_devfreq_config.downdifferential = 10;
+
+	mutex_init(&df->lock);
+
+	dev_pm_qos_add_request(&gpu->pdev->dev, &df->boost_freq,
+			       DEV_PM_QOS_MIN_FREQUENCY, 0);
+
+	msm_devfreq_profile.initial_freq = gpu->fast_rate;
+
+	/*
+	 * Don't set the freq_table or max_state and let devfreq build the table
+	 * from OPP
+	 * After a deferred probe, these may have be left to non-zero values,
+	 * so set them back to zero before creating the devfreq device
+	 */
+	msm_devfreq_profile.freq_table = NULL;
+	msm_devfreq_profile.max_state = 0;
+
+	df->devfreq = devm_devfreq_add_device(&gpu->pdev->dev,
+			&msm_devfreq_profile, DEVFREQ_GOV_SIMPLE_ONDEMAND,
+			&priv->gpu_devfreq_config);
+
+	if (IS_ERR(df->devfreq)) {
+		DRM_DEV_ERROR(&gpu->pdev->dev, "Couldn't initialize GPU devfreq\n");
+		dev_pm_qos_remove_request(&df->boost_freq);
+		df->devfreq = NULL;
+		return;
+	}
+
+	devfreq_suspend_device(df->devfreq);
+
+	gpu->cooling = of_devfreq_cooling_register(gpu->pdev->dev.of_node, df->devfreq);
+	if (IS_ERR(gpu->cooling)) {
+		DRM_DEV_ERROR(&gpu->pdev->dev,
+				"Couldn't register GPU cooling device\n");
+		gpu->cooling = NULL;
+	}
+
+	msm_hrtimer_work_init(&df->boost_work, gpu->worker, msm_devfreq_boost_work,
+			      CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+	msm_hrtimer_work_init(&df->idle_work, gpu->worker, msm_devfreq_idle_work,
+			      CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+}
+
+static void cancel_idle_work(struct msm_gpu_devfreq *df)
+{
+	hrtimer_cancel(&df->idle_work.timer);
+	kthread_cancel_work_sync(&df->idle_work.work);
+}
+
+static void cancel_boost_work(struct msm_gpu_devfreq *df)
+{
+	hrtimer_cancel(&df->boost_work.timer);
+	kthread_cancel_work_sync(&df->boost_work.work);
+}
+
+void msm_devfreq_cleanup(struct msm_gpu *gpu)
+{
+	struct msm_gpu_devfreq *df = &gpu->devfreq;
+
+	if (!has_devfreq(gpu))
+		return;
+
+	devfreq_cooling_unregister(gpu->cooling);
+	dev_pm_qos_remove_request(&df->boost_freq);
+}
+
+void msm_devfreq_resume(struct msm_gpu *gpu)
+{
+	struct msm_gpu_devfreq *df = &gpu->devfreq;
+	unsigned long sample_rate;
+
+	if (!has_devfreq(gpu))
+		return;
+
+	mutex_lock(&df->lock);
+	df->busy_cycles = gpu->funcs->gpu_busy(gpu, &sample_rate);
+	df->time = ktime_get();
+	df->suspended = false;
+	mutex_unlock(&df->lock);
+
+	devfreq_resume_device(df->devfreq);
+}
+
+void msm_devfreq_suspend(struct msm_gpu *gpu)
+{
+	struct msm_gpu_devfreq *df = &gpu->devfreq;
+
+	if (!has_devfreq(gpu))
+		return;
+
+	mutex_lock(&df->lock);
+	df->suspended = true;
+	mutex_unlock(&df->lock);
+
+	devfreq_suspend_device(df->devfreq);
+
+	cancel_idle_work(df);
+	cancel_boost_work(df);
+}
+
+static void msm_devfreq_boost_work(struct kthread_work *work)
+{
+	struct msm_gpu_devfreq *df = container_of(work,
+			struct msm_gpu_devfreq, boost_work.work);
+
+	dev_pm_qos_update_request(&df->boost_freq, 0);
+}
+
+void msm_devfreq_boost(struct msm_gpu *gpu, unsigned factor)
+{
+	struct msm_gpu_devfreq *df = &gpu->devfreq;
+	uint64_t freq;
+
+	if (!has_devfreq(gpu))
+		return;
+
+	freq = get_freq(gpu);
+	freq *= factor;
+
+	/*
+	 * A nice little trap is that PM QoS operates in terms of KHz,
+	 * while devfreq operates in terms of Hz:
+	 */
+	do_div(freq, HZ_PER_KHZ);
+
+	dev_pm_qos_update_request(&df->boost_freq, freq);
+
+	msm_hrtimer_queue_work(&df->boost_work,
+			       ms_to_ktime(msm_devfreq_profile.polling_ms),
+			       HRTIMER_MODE_REL);
+}
+
+void msm_devfreq_active(struct msm_gpu *gpu)
+{
+	struct msm_gpu_devfreq *df = &gpu->devfreq;
+	unsigned int idle_time;
+	unsigned long target_freq;
+
+	if (!has_devfreq(gpu))
+		return;
+
+	/*
+	 * Cancel any pending transition to idle frequency:
+	 */
+	cancel_idle_work(df);
+
+	/*
+	 * Hold devfreq lock to synchronize with get_dev_status()/
+	 * target() callbacks
+	 */
+	mutex_lock(&df->devfreq->lock);
+
+	target_freq = df->idle_freq;
+
+	idle_time = ktime_to_ms(ktime_sub(ktime_get(), df->idle_time));
+
+	df->idle_freq = 0;
+
+	/*
+	 * We could have become active again before the idle work had a
+	 * chance to run, in which case the df->idle_freq would have
+	 * still been zero.  In this case, no need to change freq.
+	 */
+	if (target_freq)
+		msm_devfreq_target(&gpu->pdev->dev, &target_freq, 0);
+
+	mutex_unlock(&df->devfreq->lock);
+
+	/*
+	 * If we've been idle for a significant fraction of a polling
+	 * interval, then we won't meet the threshold of busyness for
+	 * the governor to ramp up the freq.. so give some boost
+	 */
+	if (idle_time > msm_devfreq_profile.polling_ms) {
+		msm_devfreq_boost(gpu, 2);
+	}
+}
+
+
+static void msm_devfreq_idle_work(struct kthread_work *work)
+{
+	struct msm_gpu_devfreq *df = container_of(work,
+			struct msm_gpu_devfreq, idle_work.work);
+	struct msm_gpu *gpu = container_of(df, struct msm_gpu, devfreq);
+	struct msm_drm_private *priv = gpu->dev->dev_private;
+	unsigned long idle_freq, target_freq = 0;
+
+	/*
+	 * Hold devfreq lock to synchronize with get_dev_status()/
+	 * target() callbacks
+	 */
+	mutex_lock(&df->devfreq->lock);
+
+	idle_freq = get_freq(gpu);
+
+	if (priv->gpu_clamp_to_idle)
+		msm_devfreq_target(&gpu->pdev->dev, &target_freq, 0);
+
+	df->idle_time = ktime_get();
+	df->idle_freq = idle_freq;
+
+	mutex_unlock(&df->devfreq->lock);
+}
+
+void msm_devfreq_idle(struct msm_gpu *gpu)
+{
+	struct msm_gpu_devfreq *df = &gpu->devfreq;
+
+	if (!has_devfreq(gpu))
+		return;
+
+	msm_hrtimer_queue_work(&df->idle_work, ms_to_ktime(1),
+			       HRTIMER_MODE_REL);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_gpu_trace.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_gpu_trace.h
@@ -0,0 +1,184 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#if !defined(_MSM_GPU_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
+#define _MSM_GPU_TRACE_H_
+
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM drm_msm_gpu
+#define TRACE_INCLUDE_FILE msm_gpu_trace
+
+TRACE_EVENT(msm_gpu_submit,
+	    TP_PROTO(pid_t pid, u32 ringid, u32 id, u32 nr_bos, u32 nr_cmds),
+	    TP_ARGS(pid, ringid, id, nr_bos, nr_cmds),
+	    TP_STRUCT__entry(
+		    __field(pid_t, pid)
+		    __field(u32, id)
+		    __field(u32, ringid)
+		    __field(u32, nr_cmds)
+		    __field(u32, nr_bos)
+		    ),
+	    TP_fast_assign(
+		    __entry->pid = pid;
+		    __entry->id = id;
+		    __entry->ringid = ringid;
+		    __entry->nr_bos = nr_bos;
+		    __entry->nr_cmds = nr_cmds
+		    ),
+	    TP_printk("id=%d pid=%d ring=%d bos=%d cmds=%d",
+		    __entry->id, __entry->pid, __entry->ringid,
+		    __entry->nr_bos, __entry->nr_cmds)
+);
+
+TRACE_EVENT(msm_gpu_submit_flush,
+	    TP_PROTO(struct msm_gem_submit *submit, u64 ticks),
+	    TP_ARGS(submit, ticks),
+	    TP_STRUCT__entry(
+		    __field(pid_t, pid)
+		    __field(u32, id)
+		    __field(u32, ringid)
+		    __field(u32, seqno)
+		    __field(u64, ticks)
+		    ),
+	    TP_fast_assign(
+		    __entry->pid = pid_nr(submit->pid);
+		    __entry->id = submit->ident;
+		    __entry->ringid = submit->ring->id;
+		    __entry->seqno = submit->seqno;
+		    __entry->ticks = ticks;
+		    ),
+	    TP_printk("id=%d pid=%d ring=%d:%d ticks=%lld",
+		    __entry->id, __entry->pid, __entry->ringid, __entry->seqno,
+		    __entry->ticks)
+);
+
+
+TRACE_EVENT(msm_gpu_submit_retired,
+	    TP_PROTO(struct msm_gem_submit *submit, u64 elapsed, u64 clock,
+		    u64 start, u64 end),
+	    TP_ARGS(submit, elapsed, clock, start, end),
+	    TP_STRUCT__entry(
+		    __field(pid_t, pid)
+		    __field(u32, id)
+		    __field(u32, ringid)
+		    __field(u32, seqno)
+		    __field(u64, elapsed)
+		    __field(u64, clock)
+		    __field(u64, start_ticks)
+		    __field(u64, end_ticks)
+		    ),
+	    TP_fast_assign(
+		    __entry->pid = pid_nr(submit->pid);
+		    __entry->id = submit->ident;
+		    __entry->ringid = submit->ring->id;
+		    __entry->seqno = submit->seqno;
+		    __entry->elapsed = elapsed;
+		    __entry->clock = clock;
+		    __entry->start_ticks = start;
+		    __entry->end_ticks = end;
+		    ),
+	    TP_printk("id=%d pid=%d ring=%d:%d elapsed=%lld ns mhz=%lld start=%lld end=%lld",
+		    __entry->id, __entry->pid, __entry->ringid, __entry->seqno,
+		    __entry->elapsed, __entry->clock,
+		    __entry->start_ticks, __entry->end_ticks)
+);
+
+
+TRACE_EVENT(msm_gpu_freq_change,
+		TP_PROTO(u32 freq),
+		TP_ARGS(freq),
+		TP_STRUCT__entry(
+			__field(u32, freq)
+			),
+		TP_fast_assign(
+			/* trace freq in MHz to match intel_gpu_freq_change, to make life easier
+			 * for userspace
+			 */
+			__entry->freq = DIV_ROUND_UP(freq, 1000000);
+			),
+		TP_printk("new_freq=%u", __entry->freq)
+);
+
+
+TRACE_EVENT(msm_gmu_freq_change,
+		TP_PROTO(u32 freq, u32 perf_index),
+		TP_ARGS(freq, perf_index),
+		TP_STRUCT__entry(
+			__field(u32, freq)
+			__field(u32, perf_index)
+			),
+		TP_fast_assign(
+			__entry->freq = freq;
+			__entry->perf_index = perf_index;
+			),
+		TP_printk("freq=%u, perf_index=%u", __entry->freq, __entry->perf_index)
+);
+
+
+TRACE_EVENT(msm_gem_shrink,
+		TP_PROTO(u32 nr_to_scan, u32 purged, u32 evicted,
+			 u32 active_purged, u32 active_evicted),
+		TP_ARGS(nr_to_scan, purged, evicted, active_purged, active_evicted),
+		TP_STRUCT__entry(
+			__field(u32, nr_to_scan)
+			__field(u32, purged)
+			__field(u32, evicted)
+			__field(u32, active_purged)
+			__field(u32, active_evicted)
+			),
+		TP_fast_assign(
+			__entry->nr_to_scan = nr_to_scan;
+			__entry->purged = purged;
+			__entry->evicted = evicted;
+			__entry->active_purged = active_purged;
+			__entry->active_evicted = active_evicted;
+			),
+		TP_printk("nr_to_scan=%u pg, purged=%u pg, evicted=%u pg, active_purged=%u pg, active_evicted=%u pg",
+			  __entry->nr_to_scan, __entry->purged, __entry->evicted,
+			  __entry->active_purged, __entry->active_evicted)
+);
+
+
+TRACE_EVENT(msm_gem_purge_vmaps,
+		TP_PROTO(u32 unmapped),
+		TP_ARGS(unmapped),
+		TP_STRUCT__entry(
+			__field(u32, unmapped)
+			),
+		TP_fast_assign(
+			__entry->unmapped = unmapped;
+			),
+		TP_printk("Purging %u vmaps", __entry->unmapped)
+);
+
+
+TRACE_EVENT(msm_gpu_suspend,
+		TP_PROTO(int dummy),
+		TP_ARGS(dummy),
+		TP_STRUCT__entry(
+			__field(u32, dummy)
+			),
+		TP_fast_assign(
+			__entry->dummy = dummy;
+			),
+		TP_printk("%u", __entry->dummy)
+);
+
+
+TRACE_EVENT(msm_gpu_resume,
+		TP_PROTO(int dummy),
+		TP_ARGS(dummy),
+		TP_STRUCT__entry(
+			__field(u32, dummy)
+			),
+		TP_fast_assign(
+			__entry->dummy = dummy;
+			),
+		TP_printk("%u", __entry->dummy)
+);
+
+#endif
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/msm
+#include <trace/define_trace.h>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_gpu_tracepoints.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_gpu_tracepoints.c
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "msm_gem.h"
+#include "msm_ringbuffer.h"
+
+#define CREATE_TRACE_POINTS
+#include "msm_gpu_trace.h"
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_io_utils.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_io_utils.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2016-2018, 2020-2021 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/interconnect.h>
+#include <linux/io.h>
+
+#include "msm_drv.h"
+
+/*
+ * Util/helpers:
+ */
+
+struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count,
+		const char *name)
+{
+	int i;
+	char n[32];
+
+	snprintf(n, sizeof(n), "%s_clk", name);
+
+	for (i = 0; bulk && i < count; i++) {
+		if (!strcmp(bulk[i].id, name) || !strcmp(bulk[i].id, n))
+			return bulk[i].clk;
+	}
+
+
+	return NULL;
+}
+
+struct clk *msm_clk_get(struct platform_device *pdev, const char *name)
+{
+	struct clk *clk;
+	char name2[32];
+
+	clk = devm_clk_get(&pdev->dev, name);
+	if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
+		return clk;
+
+	snprintf(name2, sizeof(name2), "%s_clk", name);
+
+	clk = devm_clk_get(&pdev->dev, name2);
+	if (!IS_ERR(clk))
+		dev_warn(&pdev->dev, "Using legacy clk name binding.  Use "
+				"\"%s\" instead of \"%s\"\n", name, name2);
+
+	return clk;
+}
+
+static void __iomem *_msm_ioremap(struct platform_device *pdev, const char *name,
+				  bool quiet, phys_addr_t *psize)
+{
+	struct resource *res;
+	unsigned long size;
+	void __iomem *ptr;
+
+	if (name)
+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
+	else
+		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!res) {
+		if (!quiet)
+			DRM_DEV_ERROR(&pdev->dev, "failed to get memory resource: %s\n", name);
+		return ERR_PTR(-EINVAL);
+	}
+
+	size = resource_size(res);
+
+	ptr = devm_ioremap(&pdev->dev, res->start, size);
+	if (!ptr) {
+		if (!quiet)
+			DRM_DEV_ERROR(&pdev->dev, "failed to ioremap: %s\n", name);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	if (psize)
+		*psize = size;
+
+	return ptr;
+}
+
+void __iomem *msm_ioremap(struct platform_device *pdev, const char *name)
+{
+	return _msm_ioremap(pdev, name, false, NULL);
+}
+
+void __iomem *msm_ioremap_quiet(struct platform_device *pdev, const char *name)
+{
+	return _msm_ioremap(pdev, name, true, NULL);
+}
+
+void __iomem *msm_ioremap_size(struct platform_device *pdev, const char *name,
+			  phys_addr_t *psize)
+{
+	return _msm_ioremap(pdev, name, false, psize);
+}
+
+static enum hrtimer_restart msm_hrtimer_worktimer(struct hrtimer *t)
+{
+	struct msm_hrtimer_work *work = container_of(t,
+			struct msm_hrtimer_work, timer);
+
+	kthread_queue_work(work->worker, &work->work);
+
+	return HRTIMER_NORESTART;
+}
+
+void msm_hrtimer_queue_work(struct msm_hrtimer_work *work,
+			    ktime_t wakeup_time,
+			    enum hrtimer_mode mode)
+{
+	hrtimer_start(&work->timer, wakeup_time, mode);
+}
+
+void msm_hrtimer_work_init(struct msm_hrtimer_work *work,
+			   struct kthread_worker *worker,
+			   kthread_work_func_t fn,
+			   clockid_t clock_id,
+			   enum hrtimer_mode mode)
+{
+	hrtimer_init(&work->timer, clock_id, mode);
+	work->timer.function = msm_hrtimer_worktimer;
+	work->worker = worker;
+	kthread_init_work(&work->work, fn);
+}
+
+struct icc_path *msm_icc_get(struct device *dev, const char *name)
+{
+	struct device *mdss_dev = dev->parent;
+	struct icc_path *path;
+
+	path = of_icc_get(dev, name);
+	if (path)
+		return path;
+
+	/*
+	 * If there are no interconnects attached to the corresponding device
+	 * node, of_icc_get() will return NULL.
+	 *
+	 * If the MDP5/DPU device node doesn't have interconnects, lookup the
+	 * path in the parent (MDSS) device.
+	 */
+	return of_icc_get(mdss_dev, name);
+
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_iommu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_iommu.c
@@ -0,0 +1,455 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/adreno-smmu-priv.h>
+#include <linux/io-pgtable.h>
+#include "msm_drv.h"
+#include "msm_mmu.h"
+
+struct msm_iommu {
+	struct msm_mmu base;
+	struct iommu_domain *domain;
+	atomic_t pagetables;
+};
+
+#define to_msm_iommu(x) container_of(x, struct msm_iommu, base)
+
+struct msm_iommu_pagetable {
+	struct msm_mmu base;
+	struct msm_mmu *parent;
+	struct io_pgtable_ops *pgtbl_ops;
+	const struct iommu_flush_ops *tlb;
+	struct device *iommu_dev;
+	unsigned long pgsize_bitmap;	/* Bitmap of page sizes in use */
+	phys_addr_t ttbr;
+	u32 asid;
+};
+static struct msm_iommu_pagetable *to_pagetable(struct msm_mmu *mmu)
+{
+	return container_of(mmu, struct msm_iommu_pagetable, base);
+}
+
+/* based on iommu_pgsize() in iommu.c: */
+static size_t calc_pgsize(struct msm_iommu_pagetable *pagetable,
+			   unsigned long iova, phys_addr_t paddr,
+			   size_t size, size_t *count)
+{
+	unsigned int pgsize_idx, pgsize_idx_next;
+	unsigned long pgsizes;
+	size_t offset, pgsize, pgsize_next;
+	unsigned long addr_merge = paddr | iova;
+
+	/* Page sizes supported by the hardware and small enough for @size */
+	pgsizes = pagetable->pgsize_bitmap & GENMASK(__fls(size), 0);
+
+	/* Constrain the page sizes further based on the maximum alignment */
+	if (likely(addr_merge))
+		pgsizes &= GENMASK(__ffs(addr_merge), 0);
+
+	/* Make sure we have at least one suitable page size */
+	BUG_ON(!pgsizes);
+
+	/* Pick the biggest page size remaining */
+	pgsize_idx = __fls(pgsizes);
+	pgsize = BIT(pgsize_idx);
+	if (!count)
+		return pgsize;
+
+	/* Find the next biggest support page size, if it exists */
+	pgsizes = pagetable->pgsize_bitmap & ~GENMASK(pgsize_idx, 0);
+	if (!pgsizes)
+		goto out_set_count;
+
+	pgsize_idx_next = __ffs(pgsizes);
+	pgsize_next = BIT(pgsize_idx_next);
+
+	/*
+	 * There's no point trying a bigger page size unless the virtual
+	 * and physical addresses are similarly offset within the larger page.
+	 */
+	if ((iova ^ paddr) & (pgsize_next - 1))
+		goto out_set_count;
+
+	/* Calculate the offset to the next page size alignment boundary */
+	offset = pgsize_next - (addr_merge & (pgsize_next - 1));
+
+	/*
+	 * If size is big enough to accommodate the larger page, reduce
+	 * the number of smaller pages.
+	 */
+	if (offset + pgsize_next <= size)
+		size = offset;
+
+out_set_count:
+	*count = size >> pgsize_idx;
+	return pgsize;
+}
+
+static int msm_iommu_pagetable_unmap(struct msm_mmu *mmu, u64 iova,
+		size_t size)
+{
+	struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
+	struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
+
+	while (size) {
+		size_t unmapped, pgsize, count;
+
+		pgsize = calc_pgsize(pagetable, iova, iova, size, &count);
+
+		unmapped = ops->unmap_pages(ops, iova, pgsize, count, NULL);
+		if (!unmapped)
+			break;
+
+		iova += unmapped;
+		size -= unmapped;
+	}
+
+	iommu_flush_iotlb_all(to_msm_iommu(pagetable->parent)->domain);
+
+	return (size == 0) ? 0 : -EINVAL;
+}
+
+static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 iova,
+		struct sg_table *sgt, size_t len, int prot)
+{
+	struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
+	struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
+	struct scatterlist *sg;
+	u64 addr = iova;
+	unsigned int i;
+
+	for_each_sgtable_sg(sgt, sg, i) {
+		size_t size = sg->length;
+		phys_addr_t phys = sg_phys(sg);
+
+		while (size) {
+			size_t pgsize, count, mapped = 0;
+			int ret;
+
+			pgsize = calc_pgsize(pagetable, addr, phys, size, &count);
+
+			ret = ops->map_pages(ops, addr, phys, pgsize, count,
+					     prot, GFP_KERNEL, &mapped);
+
+			/* map_pages could fail after mapping some of the pages,
+			 * so update the counters before error handling.
+			 */
+			phys += mapped;
+			addr += mapped;
+			size -= mapped;
+
+			if (ret) {
+				msm_iommu_pagetable_unmap(mmu, iova, addr - iova);
+				return -EINVAL;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void msm_iommu_pagetable_destroy(struct msm_mmu *mmu)
+{
+	struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
+	struct msm_iommu *iommu = to_msm_iommu(pagetable->parent);
+	struct adreno_smmu_priv *adreno_smmu =
+		dev_get_drvdata(pagetable->parent->dev);
+
+	/*
+	 * If this is the last attached pagetable for the parent,
+	 * disable TTBR0 in the arm-smmu driver
+	 */
+	if (atomic_dec_return(&iommu->pagetables) == 0)
+		adreno_smmu->set_ttbr0_cfg(adreno_smmu->cookie, NULL);
+
+	free_io_pgtable_ops(pagetable->pgtbl_ops);
+	kfree(pagetable);
+}
+
+int msm_iommu_pagetable_params(struct msm_mmu *mmu,
+		phys_addr_t *ttbr, int *asid)
+{
+	struct msm_iommu_pagetable *pagetable;
+
+	if (mmu->type != MSM_MMU_IOMMU_PAGETABLE)
+		return -EINVAL;
+
+	pagetable = to_pagetable(mmu);
+
+	if (ttbr)
+		*ttbr = pagetable->ttbr;
+
+	if (asid)
+		*asid = pagetable->asid;
+
+	return 0;
+}
+
+struct iommu_domain_geometry *msm_iommu_get_geometry(struct msm_mmu *mmu)
+{
+	struct msm_iommu *iommu = to_msm_iommu(mmu);
+
+	return &iommu->domain->geometry;
+}
+
+static const struct msm_mmu_funcs pagetable_funcs = {
+		.map = msm_iommu_pagetable_map,
+		.unmap = msm_iommu_pagetable_unmap,
+		.destroy = msm_iommu_pagetable_destroy,
+};
+
+static void msm_iommu_tlb_flush_all(void *cookie)
+{
+	struct msm_iommu_pagetable *pagetable = cookie;
+	struct adreno_smmu_priv *adreno_smmu;
+
+	if (!pm_runtime_get_if_in_use(pagetable->iommu_dev))
+		return;
+
+	adreno_smmu = dev_get_drvdata(pagetable->parent->dev);
+
+	pagetable->tlb->tlb_flush_all((void *)adreno_smmu->cookie);
+
+	pm_runtime_put_autosuspend(pagetable->iommu_dev);
+}
+
+static void msm_iommu_tlb_flush_walk(unsigned long iova, size_t size,
+		size_t granule, void *cookie)
+{
+	struct msm_iommu_pagetable *pagetable = cookie;
+	struct adreno_smmu_priv *adreno_smmu;
+
+	if (!pm_runtime_get_if_in_use(pagetable->iommu_dev))
+		return;
+
+	adreno_smmu = dev_get_drvdata(pagetable->parent->dev);
+
+	pagetable->tlb->tlb_flush_walk(iova, size, granule, (void *)adreno_smmu->cookie);
+
+	pm_runtime_put_autosuspend(pagetable->iommu_dev);
+}
+
+static void msm_iommu_tlb_add_page(struct iommu_iotlb_gather *gather,
+		unsigned long iova, size_t granule, void *cookie)
+{
+}
+
+static const struct iommu_flush_ops tlb_ops = {
+	.tlb_flush_all = msm_iommu_tlb_flush_all,
+	.tlb_flush_walk = msm_iommu_tlb_flush_walk,
+	.tlb_add_page = msm_iommu_tlb_add_page,
+};
+
+static int msm_fault_handler(struct iommu_domain *domain, struct device *dev,
+		unsigned long iova, int flags, void *arg);
+
+struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent)
+{
+	struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(parent->dev);
+	struct msm_iommu *iommu = to_msm_iommu(parent);
+	struct msm_iommu_pagetable *pagetable;
+	const struct io_pgtable_cfg *ttbr1_cfg = NULL;
+	struct io_pgtable_cfg ttbr0_cfg;
+	int ret;
+
+	/* Get the pagetable configuration from the domain */
+	if (adreno_smmu->cookie)
+		ttbr1_cfg = adreno_smmu->get_ttbr1_cfg(adreno_smmu->cookie);
+
+	/*
+	 * If you hit this WARN_ONCE() you are probably missing an entry in
+	 * qcom_smmu_impl_of_match[] in arm-smmu-qcom.c
+	 */
+	if (WARN_ONCE(!ttbr1_cfg, "No per-process page tables"))
+		return ERR_PTR(-ENODEV);
+
+	pagetable = kzalloc(sizeof(*pagetable), GFP_KERNEL);
+	if (!pagetable)
+		return ERR_PTR(-ENOMEM);
+
+	msm_mmu_init(&pagetable->base, parent->dev, &pagetable_funcs,
+		MSM_MMU_IOMMU_PAGETABLE);
+
+	/* Clone the TTBR1 cfg as starting point for TTBR0 cfg: */
+	ttbr0_cfg = *ttbr1_cfg;
+
+	/* The incoming cfg will have the TTBR1 quirk enabled */
+	ttbr0_cfg.quirks &= ~IO_PGTABLE_QUIRK_ARM_TTBR1;
+	ttbr0_cfg.tlb = &tlb_ops;
+
+	pagetable->pgtbl_ops = alloc_io_pgtable_ops(ARM_64_LPAE_S1,
+		&ttbr0_cfg, pagetable);
+
+	if (!pagetable->pgtbl_ops) {
+		kfree(pagetable);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	/*
+	 * If this is the first pagetable that we've allocated, send it back to
+	 * the arm-smmu driver as a trigger to set up TTBR0
+	 */
+	if (atomic_inc_return(&iommu->pagetables) == 1) {
+		ret = adreno_smmu->set_ttbr0_cfg(adreno_smmu->cookie, &ttbr0_cfg);
+		if (ret) {
+			free_io_pgtable_ops(pagetable->pgtbl_ops);
+			kfree(pagetable);
+			return ERR_PTR(ret);
+		}
+	}
+
+	/* Needed later for TLB flush */
+	pagetable->parent = parent;
+	pagetable->tlb = ttbr1_cfg->tlb;
+	pagetable->iommu_dev = ttbr1_cfg->iommu_dev;
+	pagetable->pgsize_bitmap = ttbr0_cfg.pgsize_bitmap;
+	pagetable->ttbr = ttbr0_cfg.arm_lpae_s1_cfg.ttbr;
+
+	/*
+	 * TODO we would like each set of page tables to have a unique ASID
+	 * to optimize TLB invalidation.  But iommu_flush_iotlb_all() will
+	 * end up flushing the ASID used for TTBR1 pagetables, which is not
+	 * what we want.  So for now just use the same ASID as TTBR1.
+	 */
+	pagetable->asid = 0;
+
+	return &pagetable->base;
+}
+
+static int msm_fault_handler(struct iommu_domain *domain, struct device *dev,
+		unsigned long iova, int flags, void *arg)
+{
+	struct msm_iommu *iommu = arg;
+	struct msm_mmu *mmu = &iommu->base;
+	struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(iommu->base.dev);
+	struct adreno_smmu_fault_info info, *ptr = NULL;
+
+	if (adreno_smmu->get_fault_info) {
+		adreno_smmu->get_fault_info(adreno_smmu->cookie, &info);
+		ptr = &info;
+	}
+
+	if (iommu->base.handler)
+		return iommu->base.handler(iommu->base.arg, iova, flags, ptr);
+
+	pr_warn_ratelimited("*** fault: iova=%16lx, flags=%d\n", iova, flags);
+
+	if (mmu->funcs->resume_translation)
+		mmu->funcs->resume_translation(mmu);
+
+	return 0;
+}
+
+static void msm_iommu_resume_translation(struct msm_mmu *mmu)
+{
+	struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(mmu->dev);
+
+	if (adreno_smmu->resume_translation)
+		adreno_smmu->resume_translation(adreno_smmu->cookie, true);
+}
+
+static void msm_iommu_detach(struct msm_mmu *mmu)
+{
+	struct msm_iommu *iommu = to_msm_iommu(mmu);
+
+	iommu_detach_device(iommu->domain, mmu->dev);
+}
+
+static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
+		struct sg_table *sgt, size_t len, int prot)
+{
+	struct msm_iommu *iommu = to_msm_iommu(mmu);
+	size_t ret;
+
+	/* The arm-smmu driver expects the addresses to be sign extended */
+	if (iova & BIT_ULL(48))
+		iova |= GENMASK_ULL(63, 49);
+
+	ret = iommu_map_sgtable(iommu->domain, iova, sgt, prot);
+	WARN_ON(!ret);
+
+	return (ret == len) ? 0 : -EINVAL;
+}
+
+static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, size_t len)
+{
+	struct msm_iommu *iommu = to_msm_iommu(mmu);
+
+	if (iova & BIT_ULL(48))
+		iova |= GENMASK_ULL(63, 49);
+
+	iommu_unmap(iommu->domain, iova, len);
+
+	return 0;
+}
+
+static void msm_iommu_destroy(struct msm_mmu *mmu)
+{
+	struct msm_iommu *iommu = to_msm_iommu(mmu);
+	iommu_domain_free(iommu->domain);
+	kfree(iommu);
+}
+
+static const struct msm_mmu_funcs funcs = {
+		.detach = msm_iommu_detach,
+		.map = msm_iommu_map,
+		.unmap = msm_iommu_unmap,
+		.destroy = msm_iommu_destroy,
+		.resume_translation = msm_iommu_resume_translation,
+};
+
+struct msm_mmu *msm_iommu_new(struct device *dev, unsigned long quirks)
+{
+	struct iommu_domain *domain;
+	struct msm_iommu *iommu;
+	int ret;
+
+	domain = iommu_domain_alloc(dev->bus);
+	if (!domain)
+		return NULL;
+
+	iommu_set_pgtable_quirks(domain, quirks);
+
+	iommu = kzalloc(sizeof(*iommu), GFP_KERNEL);
+	if (!iommu) {
+		iommu_domain_free(domain);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	iommu->domain = domain;
+	msm_mmu_init(&iommu->base, dev, &funcs, MSM_MMU_IOMMU);
+
+	atomic_set(&iommu->pagetables, 0);
+
+	ret = iommu_attach_device(iommu->domain, dev);
+	if (ret) {
+		iommu_domain_free(domain);
+		kfree(iommu);
+		return ERR_PTR(ret);
+	}
+
+	return &iommu->base;
+}
+
+struct msm_mmu *msm_iommu_gpu_new(struct device *dev, struct msm_gpu *gpu, unsigned long quirks)
+{
+	struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(dev);
+	struct msm_iommu *iommu;
+	struct msm_mmu *mmu;
+
+	mmu = msm_iommu_new(dev, quirks);
+	if (IS_ERR_OR_NULL(mmu))
+		return mmu;
+
+	iommu = to_msm_iommu(mmu);
+	iommu_set_fault_handler(iommu->domain, msm_fault_handler, iommu);
+
+	/* Enable stall on iommu fault: */
+	if (adreno_smmu->set_stall)
+		adreno_smmu->set_stall(adreno_smmu->cookie, true);
+
+	return mmu;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_kms.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_kms.c
@@ -0,0 +1,346 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2016-2018, 2020-2021 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include <linux/kthread.h>
+#include <linux/sched/mm.h>
+#include <uapi/linux/sched/types.h>
+
+#include <drm/drm_aperture.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_mode_config.h>
+#include <drm/drm_vblank.h>
+
+#include "disp/msm_disp_snapshot.h"
+#include "msm_drv.h"
+#include "msm_gem.h"
+#include "msm_kms.h"
+#include "msm_mmu.h"
+
+static const struct drm_mode_config_funcs mode_config_funcs = {
+	.fb_create = msm_framebuffer_create,
+	.atomic_check = msm_atomic_check,
+	.atomic_commit = drm_atomic_helper_commit,
+};
+
+static const struct drm_mode_config_helper_funcs mode_config_helper_funcs = {
+	.atomic_commit_tail = msm_atomic_commit_tail,
+	.atomic_commit_setup = drm_dp_mst_atomic_setup_commit,
+};
+
+static irqreturn_t msm_irq(int irq, void *arg)
+{
+	struct drm_device *dev = arg;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+
+	BUG_ON(!kms);
+
+	return kms->funcs->irq(kms);
+}
+
+static void msm_irq_preinstall(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+
+	BUG_ON(!kms);
+
+	kms->funcs->irq_preinstall(kms);
+}
+
+static int msm_irq_postinstall(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+
+	BUG_ON(!kms);
+
+	if (kms->funcs->irq_postinstall)
+		return kms->funcs->irq_postinstall(kms);
+
+	return 0;
+}
+
+static int msm_irq_install(struct drm_device *dev, unsigned int irq)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+	int ret;
+
+	if (irq == IRQ_NOTCONNECTED)
+		return -ENOTCONN;
+
+	msm_irq_preinstall(dev);
+
+	ret = request_irq(irq, msm_irq, 0, dev->driver->name, dev);
+	if (ret)
+		return ret;
+
+	kms->irq_requested = true;
+
+	ret = msm_irq_postinstall(dev);
+	if (ret) {
+		free_irq(irq, dev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void msm_irq_uninstall(struct drm_device *dev)
+{
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+
+	kms->funcs->irq_uninstall(kms);
+	if (kms->irq_requested)
+		free_irq(kms->irq, dev);
+}
+
+struct msm_vblank_work {
+	struct work_struct work;
+	struct drm_crtc *crtc;
+	bool enable;
+	struct msm_drm_private *priv;
+};
+
+static void vblank_ctrl_worker(struct work_struct *work)
+{
+	struct msm_vblank_work *vbl_work = container_of(work,
+						struct msm_vblank_work, work);
+	struct msm_drm_private *priv = vbl_work->priv;
+	struct msm_kms *kms = priv->kms;
+
+	if (vbl_work->enable)
+		kms->funcs->enable_vblank(kms, vbl_work->crtc);
+	else
+		kms->funcs->disable_vblank(kms,	vbl_work->crtc);
+
+	kfree(vbl_work);
+}
+
+static int vblank_ctrl_queue_work(struct msm_drm_private *priv,
+				  struct drm_crtc *crtc, bool enable)
+{
+	struct msm_vblank_work *vbl_work;
+
+	vbl_work = kzalloc(sizeof(*vbl_work), GFP_ATOMIC);
+	if (!vbl_work)
+		return -ENOMEM;
+
+	INIT_WORK(&vbl_work->work, vblank_ctrl_worker);
+
+	vbl_work->crtc = crtc;
+	vbl_work->enable = enable;
+	vbl_work->priv = priv;
+
+	queue_work(priv->wq, &vbl_work->work);
+
+	return 0;
+}
+
+int msm_crtc_enable_vblank(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+	if (!kms)
+		return -ENXIO;
+	drm_dbg_vbl(dev, "crtc=%u\n", crtc->base.id);
+	return vblank_ctrl_queue_work(priv, crtc, true);
+}
+
+void msm_crtc_disable_vblank(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_kms *kms = priv->kms;
+	if (!kms)
+		return;
+	drm_dbg_vbl(dev, "crtc=%u\n", crtc->base.id);
+	vblank_ctrl_queue_work(priv, crtc, false);
+}
+
+struct msm_gem_address_space *msm_kms_init_aspace(struct drm_device *dev)
+{
+	struct msm_gem_address_space *aspace;
+	struct msm_mmu *mmu;
+	struct device *mdp_dev = dev->dev;
+	struct device *mdss_dev = mdp_dev->parent;
+	struct device *iommu_dev;
+
+	/*
+	 * IOMMUs can be a part of MDSS device tree binding, or the
+	 * MDP/DPU device.
+	 */
+	if (device_iommu_mapped(mdp_dev))
+		iommu_dev = mdp_dev;
+	else
+		iommu_dev = mdss_dev;
+
+	mmu = msm_iommu_new(iommu_dev, 0);
+	if (IS_ERR(mmu))
+		return ERR_CAST(mmu);
+
+	if (!mmu) {
+		drm_info(dev, "no IOMMU, fallback to phys contig buffers for scanout\n");
+		return NULL;
+	}
+
+	aspace = msm_gem_address_space_create(mmu, "mdp_kms",
+		0x1000, 0x100000000 - 0x1000);
+	if (IS_ERR(aspace)) {
+		dev_err(mdp_dev, "aspace create, error %pe\n", aspace);
+		mmu->funcs->destroy(mmu);
+	}
+
+	return aspace;
+}
+
+void msm_drm_kms_uninit(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct msm_drm_private *priv = platform_get_drvdata(pdev);
+	struct drm_device *ddev = priv->dev;
+	struct msm_kms *kms = priv->kms;
+	int i;
+
+	BUG_ON(!kms);
+
+	/* clean up event worker threads */
+	for (i = 0; i < priv->num_crtcs; i++) {
+		if (priv->event_thread[i].worker)
+			kthread_destroy_worker(priv->event_thread[i].worker);
+	}
+
+	drm_kms_helper_poll_fini(ddev);
+
+	msm_disp_snapshot_destroy(ddev);
+
+	pm_runtime_get_sync(dev);
+	msm_irq_uninstall(ddev);
+	pm_runtime_put_sync(dev);
+
+	if (kms && kms->funcs)
+		kms->funcs->destroy(kms);
+}
+
+int msm_drm_kms_init(struct device *dev, const struct drm_driver *drv)
+{
+	struct msm_drm_private *priv = dev_get_drvdata(dev);
+	struct drm_device *ddev = priv->dev;
+	struct msm_kms *kms = priv->kms;
+	struct drm_crtc *crtc;
+	int ret;
+
+	/* the fw fb could be anywhere in memory */
+	ret = drm_aperture_remove_framebuffers(drv);
+	if (ret)
+		return ret;
+
+	ret = priv->kms_init(ddev);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "failed to load kms\n");
+		priv->kms = NULL;
+		return ret;
+	}
+
+	/* Enable normalization of plane zpos */
+	ddev->mode_config.normalize_zpos = true;
+
+	ddev->mode_config.funcs = &mode_config_funcs;
+	ddev->mode_config.helper_private = &mode_config_helper_funcs;
+
+	kms->dev = ddev;
+	ret = kms->funcs->hw_init(kms);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "kms hw init failed: %d\n", ret);
+		goto err_msm_uninit;
+	}
+
+	drm_helper_move_panel_connectors_to_head(ddev);
+
+	drm_for_each_crtc(crtc, ddev) {
+		struct msm_drm_thread *ev_thread;
+
+		/* initialize event thread */
+		ev_thread = &priv->event_thread[drm_crtc_index(crtc)];
+		ev_thread->dev = ddev;
+		ev_thread->worker = kthread_create_worker(0, "crtc_event:%d", crtc->base.id);
+		if (IS_ERR(ev_thread->worker)) {
+			ret = PTR_ERR(ev_thread->worker);
+			DRM_DEV_ERROR(dev, "failed to create crtc_event kthread\n");
+			ev_thread->worker = NULL;
+			goto err_msm_uninit;
+		}
+
+		sched_set_fifo(ev_thread->worker->task);
+	}
+
+	ret = drm_vblank_init(ddev, priv->num_crtcs);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dev, "failed to initialize vblank\n");
+		goto err_msm_uninit;
+	}
+
+	pm_runtime_get_sync(dev);
+	ret = msm_irq_install(ddev, kms->irq);
+	pm_runtime_put_sync(dev);
+	if (ret < 0) {
+		DRM_DEV_ERROR(dev, "failed to install IRQ handler\n");
+		goto err_msm_uninit;
+	}
+
+	ret = msm_disp_snapshot_init(ddev);
+	if (ret)
+		DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", ret);
+
+	drm_mode_config_reset(ddev);
+
+	return 0;
+
+err_msm_uninit:
+	return ret;
+}
+
+int msm_kms_pm_prepare(struct device *dev)
+{
+	struct msm_drm_private *priv = dev_get_drvdata(dev);
+	struct drm_device *ddev = priv ? priv->dev : NULL;
+
+	if (!priv || !priv->kms)
+		return 0;
+
+	return drm_mode_config_helper_suspend(ddev);
+}
+
+void msm_kms_pm_complete(struct device *dev)
+{
+	struct msm_drm_private *priv = dev_get_drvdata(dev);
+	struct drm_device *ddev = priv ? priv->dev : NULL;
+
+	if (!priv || !priv->kms)
+		return;
+
+	drm_mode_config_helper_resume(ddev);
+}
+
+void msm_kms_shutdown(struct platform_device *pdev)
+{
+	struct msm_drm_private *priv = platform_get_drvdata(pdev);
+	struct drm_device *drm = priv ? priv->dev : NULL;
+
+	/*
+	 * Shutdown the hw if we're far enough along where things might be on.
+	 * If we run this too early, we'll end up panicking in any variety of
+	 * places. Since we don't register the drm device until late in
+	 * msm_drm_init, drm_dev->registered is used as an indicator that the
+	 * shutdown will be successful.
+	 */
+	if (drm && drm->registered && priv->kms)
+		drm_atomic_helper_shutdown(drm);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_kms.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_kms.h
@@ -0,0 +1,201 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __MSM_KMS_H__
+#define __MSM_KMS_H__
+
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+
+#include "msm_drv.h"
+
+#define MAX_PLANE	4
+
+/* As there are different display controller blocks depending on the
+ * snapdragon version, the kms support is split out and the appropriate
+ * implementation is loaded at runtime.  The kms module is responsible
+ * for constructing the appropriate planes/crtcs/encoders/connectors.
+ */
+struct msm_kms_funcs {
+	/* hw initialization: */
+	int (*hw_init)(struct msm_kms *kms);
+	/* irq handling: */
+	void (*irq_preinstall)(struct msm_kms *kms);
+	int (*irq_postinstall)(struct msm_kms *kms);
+	void (*irq_uninstall)(struct msm_kms *kms);
+	irqreturn_t (*irq)(struct msm_kms *kms);
+	int (*enable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc);
+	void (*disable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc);
+
+	/*
+	 * Atomic commit handling:
+	 *
+	 * Note that in the case of async commits, the funcs which take
+	 * a crtc_mask (ie. ->flush_commit(), and ->complete_commit())
+	 * might not be evenly balanced with ->prepare_commit(), however
+	 * each crtc that effected by a ->prepare_commit() (potentially
+	 * multiple times) will eventually (at end of vsync period) be
+	 * flushed and completed.
+	 *
+	 * This has some implications about tracking of cleanup state,
+	 * for example SMP blocks to release after commit completes.  Ie.
+	 * cleanup state should be also duplicated in the various
+	 * duplicate_state() methods, as the current cleanup state at
+	 * ->complete_commit() time may have accumulated cleanup work
+	 * from multiple commits.
+	 */
+
+	/**
+	 * Enable/disable power/clks needed for hw access done in other
+	 * commit related methods.
+	 *
+	 * If mdp4 is migrated to runpm, we could probably drop these
+	 * and use runpm directly.
+	 */
+	void (*enable_commit)(struct msm_kms *kms);
+	void (*disable_commit)(struct msm_kms *kms);
+
+	/**
+	 * Prepare for atomic commit.  This is called after any previous
+	 * (async or otherwise) commit has completed.
+	 */
+	void (*prepare_commit)(struct msm_kms *kms, struct drm_atomic_state *state);
+
+	/**
+	 * Flush an atomic commit.  This is called after the hardware
+	 * updates have already been pushed down to effected planes/
+	 * crtcs/encoders/connectors.
+	 */
+	void (*flush_commit)(struct msm_kms *kms, unsigned crtc_mask);
+
+	/**
+	 * Wait for any in-progress flush to complete on the specified
+	 * crtcs.  This should not block if there is no in-progress
+	 * commit (ie. don't just wait for a vblank), as it will also
+	 * be called before ->prepare_commit() to ensure any potential
+	 * "async" commit has completed.
+	 */
+	void (*wait_flush)(struct msm_kms *kms, unsigned crtc_mask);
+
+	/**
+	 * Clean up after commit is completed.  This is called after
+	 * ->wait_flush(), to give the backend a chance to do any
+	 * post-commit cleanup.
+	 */
+	void (*complete_commit)(struct msm_kms *kms, unsigned crtc_mask);
+
+	/*
+	 * Format handling:
+	 */
+
+	/* get msm_format w/ optional format modifiers from drm_mode_fb_cmd2 */
+	const struct msm_format *(*get_format)(struct msm_kms *kms,
+					const uint32_t format,
+					const uint64_t modifiers);
+	/* do format checking on format modified through fb_cmd2 modifiers */
+	int (*check_modified_format)(const struct msm_kms *kms,
+			const struct msm_format *msm_fmt,
+			const struct drm_mode_fb_cmd2 *cmd,
+			struct drm_gem_object **bos);
+
+	/* misc: */
+	long (*round_pixclk)(struct msm_kms *kms, unsigned long rate,
+			struct drm_encoder *encoder);
+	int (*set_split_display)(struct msm_kms *kms,
+			struct drm_encoder *encoder,
+			struct drm_encoder *slave_encoder,
+			bool is_cmd_mode);
+	/* cleanup: */
+	void (*destroy)(struct msm_kms *kms);
+
+	/* snapshot: */
+	void (*snapshot)(struct msm_disp_state *disp_state, struct msm_kms *kms);
+
+#ifdef CONFIG_DEBUG_FS
+	/* debugfs: */
+	int (*debugfs_init)(struct msm_kms *kms, struct drm_minor *minor);
+#endif
+};
+
+struct msm_kms;
+
+/*
+ * A per-crtc timer for pending async atomic flushes.  Scheduled to expire
+ * shortly before vblank to flush pending async updates.
+ */
+struct msm_pending_timer {
+	struct msm_hrtimer_work work;
+	struct kthread_worker *worker;
+	struct msm_kms *kms;
+	unsigned crtc_idx;
+};
+
+struct msm_kms {
+	const struct msm_kms_funcs *funcs;
+	struct drm_device *dev;
+
+	/* irq number to be passed on to msm_irq_install */
+	int irq;
+	bool irq_requested;
+
+	/* mapper-id used to request GEM buffer mapped for scanout: */
+	struct msm_gem_address_space *aspace;
+
+	/* disp snapshot support */
+	struct kthread_worker *dump_worker;
+	struct kthread_work dump_work;
+	struct mutex dump_mutex;
+
+	/*
+	 * For async commit, where ->flush_commit() and later happens
+	 * from the crtc's pending_timer close to end of the frame:
+	 */
+	struct mutex commit_lock[MAX_CRTCS];
+	unsigned pending_crtc_mask;
+	struct msm_pending_timer pending_timers[MAX_CRTCS];
+};
+
+static inline int msm_kms_init(struct msm_kms *kms,
+		const struct msm_kms_funcs *funcs)
+{
+	unsigned i, ret;
+
+	for (i = 0; i < ARRAY_SIZE(kms->commit_lock); i++)
+		mutex_init(&kms->commit_lock[i]);
+
+	kms->funcs = funcs;
+
+	for (i = 0; i < ARRAY_SIZE(kms->pending_timers); i++) {
+		ret = msm_atomic_init_pending_timer(&kms->pending_timers[i], kms, i);
+		if (ret) {
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static inline void msm_kms_destroy(struct msm_kms *kms)
+{
+	unsigned i;
+
+	for (i = 0; i < ARRAY_SIZE(kms->pending_timers); i++)
+		msm_atomic_destroy_pending_timer(&kms->pending_timers[i]);
+}
+
+#define for_each_crtc_mask(dev, crtc, crtc_mask) \
+	drm_for_each_crtc(crtc, dev) \
+		for_each_if (drm_crtc_mask(crtc) & (crtc_mask))
+
+#define for_each_crtc_mask_reverse(dev, crtc, crtc_mask) \
+	drm_for_each_crtc_reverse(crtc, dev) \
+		for_each_if (drm_crtc_mask(crtc) & (crtc_mask))
+
+int msm_drm_kms_init(struct device *dev, const struct drm_driver *drv);
+void msm_drm_kms_uninit(struct device *dev);
+
+#endif /* __MSM_KMS_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_mdss.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_mdss.c
@@ -0,0 +1,702 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) 2018, The Linux Foundation
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/interconnect.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/irqdesc.h>
+#include <linux/irqchip/chained_irq.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+
+#include "msm_mdss.h"
+#include "msm_kms.h"
+
+#define HW_REV				0x0
+#define HW_INTR_STATUS			0x0010
+
+#define UBWC_DEC_HW_VERSION		0x58
+#define UBWC_STATIC			0x144
+#define UBWC_CTRL_2			0x150
+#define UBWC_PREDICTION_MODE		0x154
+
+#define MIN_IB_BW	400000000UL /* Min ib vote 400MB */
+
+#define DEFAULT_REG_BW	153600 /* Used in mdss fbdev driver */
+
+struct msm_mdss {
+	struct device *dev;
+
+	void __iomem *mmio;
+	struct clk_bulk_data *clocks;
+	size_t num_clocks;
+	bool is_mdp5;
+	struct {
+		unsigned long enabled_mask;
+		struct irq_domain *domain;
+	} irq_controller;
+	const struct msm_mdss_data *mdss_data;
+	struct icc_path *mdp_path[2];
+	u32 num_mdp_paths;
+	struct icc_path *reg_bus_path;
+};
+
+static int msm_mdss_parse_data_bus_icc_path(struct device *dev,
+					    struct msm_mdss *msm_mdss)
+{
+	struct icc_path *path0;
+	struct icc_path *path1;
+	struct icc_path *reg_bus_path;
+
+	path0 = devm_of_icc_get(dev, "mdp0-mem");
+	if (IS_ERR_OR_NULL(path0))
+		return PTR_ERR_OR_ZERO(path0);
+
+	msm_mdss->mdp_path[0] = path0;
+	msm_mdss->num_mdp_paths = 1;
+
+	path1 = devm_of_icc_get(dev, "mdp1-mem");
+	if (!IS_ERR_OR_NULL(path1)) {
+		msm_mdss->mdp_path[1] = path1;
+		msm_mdss->num_mdp_paths++;
+	}
+
+	reg_bus_path = of_icc_get(dev, "cpu-cfg");
+	if (!IS_ERR_OR_NULL(reg_bus_path))
+		msm_mdss->reg_bus_path = reg_bus_path;
+
+	return 0;
+}
+
+static void msm_mdss_irq(struct irq_desc *desc)
+{
+	struct msm_mdss *msm_mdss = irq_desc_get_handler_data(desc);
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+	u32 interrupts;
+
+	chained_irq_enter(chip, desc);
+
+	interrupts = readl_relaxed(msm_mdss->mmio + HW_INTR_STATUS);
+
+	while (interrupts) {
+		irq_hw_number_t hwirq = fls(interrupts) - 1;
+		int rc;
+
+		rc = generic_handle_domain_irq(msm_mdss->irq_controller.domain,
+					       hwirq);
+		if (rc < 0) {
+			dev_err(msm_mdss->dev, "handle irq fail: irq=%lu rc=%d\n",
+				  hwirq, rc);
+			break;
+		}
+
+		interrupts &= ~(1 << hwirq);
+	}
+
+	chained_irq_exit(chip, desc);
+}
+
+static void msm_mdss_irq_mask(struct irq_data *irqd)
+{
+	struct msm_mdss *msm_mdss = irq_data_get_irq_chip_data(irqd);
+
+	/* memory barrier */
+	smp_mb__before_atomic();
+	clear_bit(irqd->hwirq, &msm_mdss->irq_controller.enabled_mask);
+	/* memory barrier */
+	smp_mb__after_atomic();
+}
+
+static void msm_mdss_irq_unmask(struct irq_data *irqd)
+{
+	struct msm_mdss *msm_mdss = irq_data_get_irq_chip_data(irqd);
+
+	/* memory barrier */
+	smp_mb__before_atomic();
+	set_bit(irqd->hwirq, &msm_mdss->irq_controller.enabled_mask);
+	/* memory barrier */
+	smp_mb__after_atomic();
+}
+
+static struct irq_chip msm_mdss_irq_chip = {
+	.name = "msm_mdss",
+	.irq_mask = msm_mdss_irq_mask,
+	.irq_unmask = msm_mdss_irq_unmask,
+};
+
+static struct lock_class_key msm_mdss_lock_key, msm_mdss_request_key;
+
+static int msm_mdss_irqdomain_map(struct irq_domain *domain,
+		unsigned int irq, irq_hw_number_t hwirq)
+{
+	struct msm_mdss *msm_mdss = domain->host_data;
+
+	irq_set_lockdep_class(irq, &msm_mdss_lock_key, &msm_mdss_request_key);
+	irq_set_chip_and_handler(irq, &msm_mdss_irq_chip, handle_level_irq);
+
+	return irq_set_chip_data(irq, msm_mdss);
+}
+
+static const struct irq_domain_ops msm_mdss_irqdomain_ops = {
+	.map = msm_mdss_irqdomain_map,
+	.xlate = irq_domain_xlate_onecell,
+};
+
+static int _msm_mdss_irq_domain_add(struct msm_mdss *msm_mdss)
+{
+	struct device *dev;
+	struct irq_domain *domain;
+
+	dev = msm_mdss->dev;
+
+	domain = irq_domain_add_linear(dev->of_node, 32,
+			&msm_mdss_irqdomain_ops, msm_mdss);
+	if (!domain) {
+		dev_err(dev, "failed to add irq_domain\n");
+		return -EINVAL;
+	}
+
+	msm_mdss->irq_controller.enabled_mask = 0;
+	msm_mdss->irq_controller.domain = domain;
+
+	return 0;
+}
+
+static void msm_mdss_setup_ubwc_dec_20(struct msm_mdss *msm_mdss)
+{
+	const struct msm_mdss_data *data = msm_mdss->mdss_data;
+
+	writel_relaxed(data->ubwc_static, msm_mdss->mmio + UBWC_STATIC);
+}
+
+static void msm_mdss_setup_ubwc_dec_30(struct msm_mdss *msm_mdss)
+{
+	const struct msm_mdss_data *data = msm_mdss->mdss_data;
+	u32 value = (data->ubwc_swizzle & 0x1) |
+		    (data->highest_bank_bit & 0x3) << 4 |
+		    (data->macrotile_mode & 0x1) << 12;
+
+	if (data->ubwc_enc_version == UBWC_3_0)
+		value |= BIT(10);
+
+	if (data->ubwc_enc_version == UBWC_1_0)
+		value |= BIT(8);
+
+	writel_relaxed(value, msm_mdss->mmio + UBWC_STATIC);
+}
+
+static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss)
+{
+	const struct msm_mdss_data *data = msm_mdss->mdss_data;
+	u32 value = (data->ubwc_swizzle & 0x7) |
+		    (data->ubwc_static & 0x1) << 3 |
+		    (data->highest_bank_bit & 0x7) << 4 |
+		    (data->macrotile_mode & 0x1) << 12;
+
+	writel_relaxed(value, msm_mdss->mmio + UBWC_STATIC);
+
+	if (data->ubwc_enc_version == UBWC_3_0) {
+		writel_relaxed(1, msm_mdss->mmio + UBWC_CTRL_2);
+		writel_relaxed(0, msm_mdss->mmio + UBWC_PREDICTION_MODE);
+	} else {
+		if (data->ubwc_dec_version == UBWC_4_3)
+			writel_relaxed(3, msm_mdss->mmio + UBWC_CTRL_2);
+		else
+			writel_relaxed(2, msm_mdss->mmio + UBWC_CTRL_2);
+		writel_relaxed(1, msm_mdss->mmio + UBWC_PREDICTION_MODE);
+	}
+}
+
+const struct msm_mdss_data *msm_mdss_get_mdss_data(struct device *dev)
+{
+	struct msm_mdss *mdss;
+
+	if (!dev)
+		return ERR_PTR(-EINVAL);
+
+	mdss = dev_get_drvdata(dev);
+
+	return mdss->mdss_data;
+}
+
+static int msm_mdss_enable(struct msm_mdss *msm_mdss)
+{
+	int ret, i;
+
+	/*
+	 * Several components have AXI clocks that can only be turned on if
+	 * the interconnect is enabled (non-zero bandwidth). Let's make sure
+	 * that the interconnects are at least at a minimum amount.
+	 */
+	for (i = 0; i < msm_mdss->num_mdp_paths; i++)
+		icc_set_bw(msm_mdss->mdp_path[i], 0, Bps_to_icc(MIN_IB_BW));
+
+	if (msm_mdss->mdss_data && msm_mdss->mdss_data->reg_bus_bw)
+		icc_set_bw(msm_mdss->reg_bus_path, 0,
+			   msm_mdss->mdss_data->reg_bus_bw);
+	else
+		icc_set_bw(msm_mdss->reg_bus_path, 0,
+			   DEFAULT_REG_BW);
+
+	ret = clk_bulk_prepare_enable(msm_mdss->num_clocks, msm_mdss->clocks);
+	if (ret) {
+		dev_err(msm_mdss->dev, "clock enable failed, ret:%d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * Register access requires MDSS_MDP_CLK, which is not enabled by the
+	 * mdss on mdp5 hardware. Skip it for now.
+	 */
+	if (msm_mdss->is_mdp5 || !msm_mdss->mdss_data)
+		return 0;
+
+	/*
+	 * ubwc config is part of the "mdss" region which is not accessible
+	 * from the rest of the driver. hardcode known configurations here
+	 *
+	 * Decoder version can be read from the UBWC_DEC_HW_VERSION reg,
+	 * UBWC_n and the rest of params comes from hw data.
+	 */
+	switch (msm_mdss->mdss_data->ubwc_dec_version) {
+	case 0: /* no UBWC */
+	case UBWC_1_0:
+		/* do nothing */
+		break;
+	case UBWC_2_0:
+		msm_mdss_setup_ubwc_dec_20(msm_mdss);
+		break;
+	case UBWC_3_0:
+		msm_mdss_setup_ubwc_dec_30(msm_mdss);
+		break;
+	case UBWC_4_0:
+	case UBWC_4_3:
+		msm_mdss_setup_ubwc_dec_40(msm_mdss);
+		break;
+	default:
+		dev_err(msm_mdss->dev, "Unsupported UBWC decoder version %x\n",
+			msm_mdss->mdss_data->ubwc_dec_version);
+		dev_err(msm_mdss->dev, "HW_REV: 0x%x\n",
+			readl_relaxed(msm_mdss->mmio + HW_REV));
+		dev_err(msm_mdss->dev, "UBWC_DEC_HW_VERSION: 0x%x\n",
+			readl_relaxed(msm_mdss->mmio + UBWC_DEC_HW_VERSION));
+		break;
+	}
+
+	return ret;
+}
+
+static int msm_mdss_disable(struct msm_mdss *msm_mdss)
+{
+	int i;
+
+	clk_bulk_disable_unprepare(msm_mdss->num_clocks, msm_mdss->clocks);
+
+	for (i = 0; i < msm_mdss->num_mdp_paths; i++)
+		icc_set_bw(msm_mdss->mdp_path[i], 0, 0);
+
+	if (msm_mdss->reg_bus_path)
+		icc_set_bw(msm_mdss->reg_bus_path, 0, 0);
+
+	return 0;
+}
+
+static void msm_mdss_destroy(struct msm_mdss *msm_mdss)
+{
+	struct platform_device *pdev = to_platform_device(msm_mdss->dev);
+	int irq;
+
+	pm_runtime_suspend(msm_mdss->dev);
+	pm_runtime_disable(msm_mdss->dev);
+	irq_domain_remove(msm_mdss->irq_controller.domain);
+	msm_mdss->irq_controller.domain = NULL;
+	irq = platform_get_irq(pdev, 0);
+	irq_set_chained_handler_and_data(irq, NULL, NULL);
+}
+
+static int msm_mdss_reset(struct device *dev)
+{
+	struct reset_control *reset;
+
+	reset = reset_control_get_optional_exclusive(dev, NULL);
+	if (!reset) {
+		/* Optional reset not specified */
+		return 0;
+	} else if (IS_ERR(reset)) {
+		return dev_err_probe(dev, PTR_ERR(reset),
+				     "failed to acquire mdss reset\n");
+	}
+
+	reset_control_assert(reset);
+	/*
+	 * Tests indicate that reset has to be held for some period of time,
+	 * make it one frame in a typical system
+	 */
+	msleep(20);
+	reset_control_deassert(reset);
+
+	reset_control_put(reset);
+
+	return 0;
+}
+
+/*
+ * MDP5 MDSS uses at most three specified clocks.
+ */
+#define MDP5_MDSS_NUM_CLOCKS 3
+static int mdp5_mdss_parse_clock(struct platform_device *pdev, struct clk_bulk_data **clocks)
+{
+	struct clk_bulk_data *bulk;
+	int num_clocks = 0;
+	int ret;
+
+	if (!pdev)
+		return -EINVAL;
+
+	bulk = devm_kcalloc(&pdev->dev, MDP5_MDSS_NUM_CLOCKS, sizeof(struct clk_bulk_data), GFP_KERNEL);
+	if (!bulk)
+		return -ENOMEM;
+
+	bulk[num_clocks++].id = "iface";
+	bulk[num_clocks++].id = "bus";
+	bulk[num_clocks++].id = "vsync";
+
+	ret = devm_clk_bulk_get_optional(&pdev->dev, num_clocks, bulk);
+	if (ret)
+		return ret;
+
+	*clocks = bulk;
+
+	return num_clocks;
+}
+
+static struct msm_mdss *msm_mdss_init(struct platform_device *pdev, bool is_mdp5)
+{
+	struct msm_mdss *msm_mdss;
+	int ret;
+	int irq;
+
+	ret = msm_mdss_reset(&pdev->dev);
+	if (ret)
+		return ERR_PTR(ret);
+
+	msm_mdss = devm_kzalloc(&pdev->dev, sizeof(*msm_mdss), GFP_KERNEL);
+	if (!msm_mdss)
+		return ERR_PTR(-ENOMEM);
+
+	msm_mdss->mdss_data = of_device_get_match_data(&pdev->dev);
+
+	msm_mdss->mmio = devm_platform_ioremap_resource_byname(pdev, is_mdp5 ? "mdss_phys" : "mdss");
+	if (IS_ERR(msm_mdss->mmio))
+		return ERR_CAST(msm_mdss->mmio);
+
+	dev_dbg(&pdev->dev, "mapped mdss address space @%pK\n", msm_mdss->mmio);
+
+	ret = msm_mdss_parse_data_bus_icc_path(&pdev->dev, msm_mdss);
+	if (ret)
+		return ERR_PTR(ret);
+
+	if (is_mdp5)
+		ret = mdp5_mdss_parse_clock(pdev, &msm_mdss->clocks);
+	else
+		ret = devm_clk_bulk_get_all(&pdev->dev, &msm_mdss->clocks);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to parse clocks, ret=%d\n", ret);
+		return ERR_PTR(ret);
+	}
+	msm_mdss->num_clocks = ret;
+	msm_mdss->is_mdp5 = is_mdp5;
+
+	msm_mdss->dev = &pdev->dev;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return ERR_PTR(irq);
+
+	ret = _msm_mdss_irq_domain_add(msm_mdss);
+	if (ret)
+		return ERR_PTR(ret);
+
+	irq_set_chained_handler_and_data(irq, msm_mdss_irq,
+					 msm_mdss);
+
+	pm_runtime_enable(&pdev->dev);
+
+	return msm_mdss;
+}
+
+static int __maybe_unused mdss_runtime_suspend(struct device *dev)
+{
+	struct msm_mdss *mdss = dev_get_drvdata(dev);
+
+	DBG("");
+
+	return msm_mdss_disable(mdss);
+}
+
+static int __maybe_unused mdss_runtime_resume(struct device *dev)
+{
+	struct msm_mdss *mdss = dev_get_drvdata(dev);
+
+	DBG("");
+
+	return msm_mdss_enable(mdss);
+}
+
+static int __maybe_unused mdss_pm_suspend(struct device *dev)
+{
+
+	if (pm_runtime_suspended(dev))
+		return 0;
+
+	return mdss_runtime_suspend(dev);
+}
+
+static int __maybe_unused mdss_pm_resume(struct device *dev)
+{
+	if (pm_runtime_suspended(dev))
+		return 0;
+
+	return mdss_runtime_resume(dev);
+}
+
+static const struct dev_pm_ops mdss_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(mdss_pm_suspend, mdss_pm_resume)
+	SET_RUNTIME_PM_OPS(mdss_runtime_suspend, mdss_runtime_resume, NULL)
+};
+
+static int mdss_probe(struct platform_device *pdev)
+{
+	struct msm_mdss *mdss;
+	bool is_mdp5 = of_device_is_compatible(pdev->dev.of_node, "qcom,mdss");
+	struct device *dev = &pdev->dev;
+	int ret;
+
+	mdss = msm_mdss_init(pdev, is_mdp5);
+	if (IS_ERR(mdss))
+		return PTR_ERR(mdss);
+
+	platform_set_drvdata(pdev, mdss);
+
+	/*
+	 * MDP5/DPU based devices don't have a flat hierarchy. There is a top
+	 * level parent: MDSS, and children: MDP5/DPU, DSI, HDMI, eDP etc.
+	 * Populate the children devices, find the MDP5/DPU node, and then add
+	 * the interfaces to our components list.
+	 */
+	ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
+	if (ret) {
+		DRM_DEV_ERROR(dev, "failed to populate children devices\n");
+		msm_mdss_destroy(mdss);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void mdss_remove(struct platform_device *pdev)
+{
+	struct msm_mdss *mdss = platform_get_drvdata(pdev);
+
+	of_platform_depopulate(&pdev->dev);
+
+	msm_mdss_destroy(mdss);
+}
+
+static const struct msm_mdss_data msm8998_data = {
+	.ubwc_enc_version = UBWC_1_0,
+	.ubwc_dec_version = UBWC_1_0,
+	.highest_bank_bit = 2,
+	.reg_bus_bw = 76800,
+};
+
+static const struct msm_mdss_data qcm2290_data = {
+	/* no UBWC */
+	.highest_bank_bit = 0x2,
+	.reg_bus_bw = 76800,
+};
+
+static const struct msm_mdss_data sc7180_data = {
+	.ubwc_enc_version = UBWC_2_0,
+	.ubwc_dec_version = UBWC_2_0,
+	.ubwc_static = 0x1e,
+	.highest_bank_bit = 0x1,
+	.reg_bus_bw = 76800,
+};
+
+static const struct msm_mdss_data sc7280_data = {
+	.ubwc_enc_version = UBWC_3_0,
+	.ubwc_dec_version = UBWC_4_0,
+	.ubwc_swizzle = 6,
+	.ubwc_static = 1,
+	.highest_bank_bit = 1,
+	.macrotile_mode = 1,
+	.reg_bus_bw = 74000,
+};
+
+static const struct msm_mdss_data sc8180x_data = {
+	.ubwc_enc_version = UBWC_3_0,
+	.ubwc_dec_version = UBWC_3_0,
+	.highest_bank_bit = 3,
+	.macrotile_mode = 1,
+	.reg_bus_bw = 76800,
+};
+
+static const struct msm_mdss_data sc8280xp_data = {
+	.ubwc_enc_version = UBWC_4_0,
+	.ubwc_dec_version = UBWC_4_0,
+	.ubwc_swizzle = 6,
+	.ubwc_static = 1,
+	.highest_bank_bit = 3,
+	.macrotile_mode = 1,
+	.reg_bus_bw = 76800,
+};
+
+static const struct msm_mdss_data sdm670_data = {
+	.ubwc_enc_version = UBWC_2_0,
+	.ubwc_dec_version = UBWC_2_0,
+	.highest_bank_bit = 1,
+	.reg_bus_bw = 76800,
+};
+
+static const struct msm_mdss_data sdm845_data = {
+	.ubwc_enc_version = UBWC_2_0,
+	.ubwc_dec_version = UBWC_2_0,
+	.highest_bank_bit = 2,
+	.reg_bus_bw = 76800,
+};
+
+static const struct msm_mdss_data sm6350_data = {
+	.ubwc_enc_version = UBWC_2_0,
+	.ubwc_dec_version = UBWC_2_0,
+	.ubwc_swizzle = 6,
+	.ubwc_static = 0x1e,
+	.highest_bank_bit = 1,
+	.reg_bus_bw = 76800,
+};
+
+static const struct msm_mdss_data sm8150_data = {
+	.ubwc_enc_version = UBWC_3_0,
+	.ubwc_dec_version = UBWC_3_0,
+	.highest_bank_bit = 2,
+	.reg_bus_bw = 76800,
+};
+
+static const struct msm_mdss_data sm6115_data = {
+	.ubwc_enc_version = UBWC_1_0,
+	.ubwc_dec_version = UBWC_2_0,
+	.ubwc_swizzle = 7,
+	.ubwc_static = 0x11f,
+	.highest_bank_bit = 0x1,
+	.reg_bus_bw = 76800,
+};
+
+static const struct msm_mdss_data sm6125_data = {
+	.ubwc_enc_version = UBWC_1_0,
+	.ubwc_dec_version = UBWC_3_0,
+	.ubwc_swizzle = 1,
+	.highest_bank_bit = 1,
+	.reg_bus_bw = 76800,
+};
+
+static const struct msm_mdss_data sm8250_data = {
+	.ubwc_enc_version = UBWC_4_0,
+	.ubwc_dec_version = UBWC_4_0,
+	.ubwc_swizzle = 6,
+	.ubwc_static = 1,
+	/* TODO: highest_bank_bit = 2 for LP_DDR4 */
+	.highest_bank_bit = 3,
+	.macrotile_mode = 1,
+	.reg_bus_bw = 76800,
+};
+
+static const struct msm_mdss_data sm8350_data = {
+	.ubwc_enc_version = UBWC_4_0,
+	.ubwc_dec_version = UBWC_4_0,
+	.ubwc_swizzle = 6,
+	.ubwc_static = 1,
+	/* TODO: highest_bank_bit = 2 for LP_DDR4 */
+	.highest_bank_bit = 3,
+	.macrotile_mode = 1,
+	.reg_bus_bw = 74000,
+};
+
+static const struct msm_mdss_data qcs8300_data = {
+	.ubwc_enc_version = UBWC_4_0,
+	.ubwc_dec_version = UBWC_4_0,
+	.ubwc_swizzle = 6,
+	.ubwc_static = 1,
+	.highest_bank_bit = 3,
+	.macrotile_mode = 1,
+};
+
+static const struct msm_mdss_data sa8775p_data = {
+	.ubwc_enc_version = UBWC_4_0,
+	.ubwc_dec_version = UBWC_4_0,
+	.ubwc_swizzle = 4,
+	.ubwc_static = 1,
+	.highest_bank_bit = 0,
+	.macrotile_mode = 1,
+};
+
+static const struct msm_mdss_data sm8550_data = {
+	.ubwc_enc_version = UBWC_4_0,
+	.ubwc_dec_version = UBWC_4_3,
+	.ubwc_swizzle = 6,
+	.ubwc_static = 1,
+	/* TODO: highest_bank_bit = 2 for LP_DDR4 */
+	.highest_bank_bit = 3,
+	.macrotile_mode = 1,
+	.reg_bus_bw = 57000,
+};
+static const struct of_device_id mdss_dt_match[] = {
+	{ .compatible = "qcom,mdss" },
+	{ .compatible = "qcom,msm8998-mdss", .data = &msm8998_data },
+	{ .compatible = "qcom,qcm2290-mdss", .data = &qcm2290_data },
+	{ .compatible = "qcom,sdm670-mdss", .data = &sdm670_data },
+	{ .compatible = "qcom,sdm845-mdss", .data = &sdm845_data },
+	{ .compatible = "qcom,sc7180-mdss", .data = &sc7180_data },
+	{ .compatible = "qcom,sc7280-mdss", .data = &sc7280_data },
+	{ .compatible = "qcom,sc8180x-mdss", .data = &sc8180x_data },
+	{ .compatible = "qcom,sc8280xp-mdss", .data = &sc8280xp_data },
+	{ .compatible = "qcom,sm6115-mdss", .data = &sm6115_data },
+	{ .compatible = "qcom,sm6125-mdss", .data = &sm6125_data },
+	{ .compatible = "qcom,sm6350-mdss", .data = &sm6350_data },
+	{ .compatible = "qcom,sm6375-mdss", .data = &sm6350_data },
+	{ .compatible = "qcom,sm8150-mdss", .data = &sm8150_data },
+	{ .compatible = "qcom,sm8250-mdss", .data = &sm8250_data },
+	{ .compatible = "qcom,sm8350-mdss", .data = &sm8350_data },
+	{ .compatible = "qcom,sm8450-mdss", .data = &sm8350_data },
+	{ .compatible = "qcom,qcs8300-mdss", .data = &qcs8300_data },
+	{ .compatible = "qcom,sa8775p-mdss", .data = &sa8775p_data },
+	{ .compatible = "qcom,sm8550-mdss", .data = &sm8550_data },
+	{ .compatible = "qcom,sm8650-mdss", .data = &sm8550_data},
+	{}
+};
+MODULE_DEVICE_TABLE(of, mdss_dt_match);
+
+static struct platform_driver mdss_platform_driver = {
+	.probe      = mdss_probe,
+	.remove_new = mdss_remove,
+	.driver     = {
+		.name   = "msm-mdss",
+		.of_match_table = mdss_dt_match,
+		.pm     = &mdss_pm_ops,
+	},
+};
+
+void __init msm_mdss_register(void)
+{
+	platform_driver_register(&mdss_platform_driver);
+}
+
+void __exit msm_mdss_unregister(void)
+{
+	platform_driver_unregister(&mdss_platform_driver);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_mdss.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_mdss.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2018, The Linux Foundation
+ */
+
+#ifndef __MSM_MDSS_H__
+#define __MSM_MDSS_H__
+
+struct msm_mdss_data {
+	u32 ubwc_enc_version;
+	/* can be read from register 0x58 */
+	u32 ubwc_dec_version;
+	u32 ubwc_swizzle;
+	u32 ubwc_static;
+	u32 highest_bank_bit;
+	u32 macrotile_mode;
+	u32 reg_bus_bw;
+};
+
+#define UBWC_1_0 0x10000000
+#define UBWC_2_0 0x20000000
+#define UBWC_3_0 0x30000000
+#define UBWC_4_0 0x40000000
+#define UBWC_4_3 0x40030000
+
+const struct msm_mdss_data *msm_mdss_get_mdss_data(struct device *dev);
+
+#endif /* __MSM_MDSS_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_mmu.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_mmu.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __MSM_MMU_H__
+#define __MSM_MMU_H__
+
+#include <linux/iommu.h>
+
+struct msm_mmu_funcs {
+	void (*detach)(struct msm_mmu *mmu);
+	int (*map)(struct msm_mmu *mmu, uint64_t iova, struct sg_table *sgt,
+			size_t len, int prot);
+	int (*unmap)(struct msm_mmu *mmu, uint64_t iova, size_t len);
+	void (*destroy)(struct msm_mmu *mmu);
+	void (*resume_translation)(struct msm_mmu *mmu);
+};
+
+enum msm_mmu_type {
+	MSM_MMU_GPUMMU,
+	MSM_MMU_IOMMU,
+	MSM_MMU_IOMMU_PAGETABLE,
+};
+
+struct msm_mmu {
+	const struct msm_mmu_funcs *funcs;
+	struct device *dev;
+	int (*handler)(void *arg, unsigned long iova, int flags, void *data);
+	void *arg;
+	enum msm_mmu_type type;
+};
+
+static inline void msm_mmu_init(struct msm_mmu *mmu, struct device *dev,
+		const struct msm_mmu_funcs *funcs, enum msm_mmu_type type)
+{
+	mmu->dev = dev;
+	mmu->funcs = funcs;
+	mmu->type = type;
+}
+
+struct msm_mmu *msm_iommu_new(struct device *dev, unsigned long quirks);
+struct msm_mmu *msm_iommu_gpu_new(struct device *dev, struct msm_gpu *gpu, unsigned long quirks);
+
+static inline void msm_mmu_set_fault_handler(struct msm_mmu *mmu, void *arg,
+		int (*handler)(void *arg, unsigned long iova, int flags, void *data))
+{
+	mmu->arg = arg;
+	mmu->handler = handler;
+}
+
+struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent);
+
+int msm_iommu_pagetable_params(struct msm_mmu *mmu, phys_addr_t *ttbr,
+		int *asid);
+struct iommu_domain_geometry *msm_iommu_get_geometry(struct msm_mmu *mmu);
+
+#endif /* __MSM_MMU_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_perf.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_perf.c
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+/* For profiling, userspace can:
+ *
+ *   tail -f /sys/kernel/debug/dri/<minor>/gpu
+ *
+ * This will enable performance counters/profiling to track the busy time
+ * and any gpu specific performance counters that are supported.
+ */
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+
+#include <drm/drm_file.h>
+
+#include "msm_drv.h"
+#include "msm_gpu.h"
+
+struct msm_perf_state {
+	struct drm_device *dev;
+
+	bool open;
+	int cnt;
+	struct mutex read_lock;
+
+	char buf[256];
+	int buftot, bufpos;
+
+	unsigned long next_jiffies;
+};
+
+#define SAMPLE_TIME (HZ/4)
+
+/* wait for next sample time: */
+static int wait_sample(struct msm_perf_state *perf)
+{
+	unsigned long start_jiffies = jiffies;
+
+	if (time_after(perf->next_jiffies, start_jiffies)) {
+		unsigned long remaining_jiffies =
+			perf->next_jiffies - start_jiffies;
+		int ret = schedule_timeout_interruptible(remaining_jiffies);
+		if (ret > 0) {
+			/* interrupted */
+			return -ERESTARTSYS;
+		}
+	}
+	perf->next_jiffies += SAMPLE_TIME;
+	return 0;
+}
+
+static int refill_buf(struct msm_perf_state *perf)
+{
+	struct msm_drm_private *priv = perf->dev->dev_private;
+	struct msm_gpu *gpu = priv->gpu;
+	char *ptr = perf->buf;
+	int rem = sizeof(perf->buf);
+	int i, n;
+
+	if ((perf->cnt++ % 32) == 0) {
+		/* Header line: */
+		n = snprintf(ptr, rem, "%%BUSY");
+		ptr += n;
+		rem -= n;
+
+		for (i = 0; i < gpu->num_perfcntrs; i++) {
+			const struct msm_gpu_perfcntr *perfcntr = &gpu->perfcntrs[i];
+			n = snprintf(ptr, rem, "\t%s", perfcntr->name);
+			ptr += n;
+			rem -= n;
+		}
+	} else {
+		/* Sample line: */
+		uint32_t activetime = 0, totaltime = 0;
+		uint32_t cntrs[5];
+		uint32_t val;
+		int ret;
+
+		/* sleep until next sample time: */
+		ret = wait_sample(perf);
+		if (ret)
+			return ret;
+
+		ret = msm_gpu_perfcntr_sample(gpu, &activetime, &totaltime,
+				ARRAY_SIZE(cntrs), cntrs);
+		if (ret < 0)
+			return ret;
+
+		val = totaltime ? 1000 * activetime / totaltime : 0;
+		n = snprintf(ptr, rem, "%3d.%d%%", val / 10, val % 10);
+		ptr += n;
+		rem -= n;
+
+		for (i = 0; i < ret; i++) {
+			/* cycle counters (I think).. convert to MHz.. */
+			val = cntrs[i] / 10000;
+			n = snprintf(ptr, rem, "\t%5d.%02d",
+					val / 100, val % 100);
+			ptr += n;
+			rem -= n;
+		}
+	}
+
+	n = snprintf(ptr, rem, "\n");
+	ptr += n;
+	rem -= n;
+
+	perf->bufpos = 0;
+	perf->buftot = ptr - perf->buf;
+
+	return 0;
+}
+
+static ssize_t perf_read(struct file *file, char __user *buf,
+		size_t sz, loff_t *ppos)
+{
+	struct msm_perf_state *perf = file->private_data;
+	int n = 0, ret = 0;
+
+	mutex_lock(&perf->read_lock);
+
+	if (perf->bufpos >= perf->buftot) {
+		ret = refill_buf(perf);
+		if (ret)
+			goto out;
+	}
+
+	n = min((int)sz, perf->buftot - perf->bufpos);
+	if (copy_to_user(buf, &perf->buf[perf->bufpos], n)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	perf->bufpos += n;
+	*ppos += n;
+
+out:
+	mutex_unlock(&perf->read_lock);
+	if (ret)
+		return ret;
+	return n;
+}
+
+static int perf_open(struct inode *inode, struct file *file)
+{
+	struct msm_perf_state *perf = inode->i_private;
+	struct drm_device *dev = perf->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_gpu *gpu = priv->gpu;
+	int ret = 0;
+
+	if (!gpu)
+		return -ENODEV;
+
+	mutex_lock(&gpu->lock);
+
+	if (perf->open) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	file->private_data = perf;
+	perf->open = true;
+	perf->cnt = 0;
+	perf->buftot = 0;
+	perf->bufpos = 0;
+	msm_gpu_perfcntr_start(gpu);
+	perf->next_jiffies = jiffies + SAMPLE_TIME;
+
+out:
+	mutex_unlock(&gpu->lock);
+	return ret;
+}
+
+static int perf_release(struct inode *inode, struct file *file)
+{
+	struct msm_perf_state *perf = inode->i_private;
+	struct msm_drm_private *priv = perf->dev->dev_private;
+	msm_gpu_perfcntr_stop(priv->gpu);
+	perf->open = false;
+	return 0;
+}
+
+
+static const struct file_operations perf_debugfs_fops = {
+	.owner = THIS_MODULE,
+	.open = perf_open,
+	.read = perf_read,
+	.llseek = no_llseek,
+	.release = perf_release,
+};
+
+int msm_perf_debugfs_init(struct drm_minor *minor)
+{
+	struct msm_drm_private *priv = minor->dev->dev_private;
+	struct msm_perf_state *perf;
+
+	/* only create on first minor: */
+	if (priv->perf)
+		return 0;
+
+	perf = kzalloc(sizeof(*perf), GFP_KERNEL);
+	if (!perf)
+		return -ENOMEM;
+
+	perf->dev = minor->dev;
+
+	mutex_init(&perf->read_lock);
+	priv->perf = perf;
+
+	debugfs_create_file("perf", S_IFREG | S_IRUGO, minor->debugfs_root,
+			    perf, &perf_debugfs_fops);
+	return 0;
+}
+
+void msm_perf_debugfs_cleanup(struct msm_drm_private *priv)
+{
+	struct msm_perf_state *perf = priv->perf;
+
+	if (!perf)
+		return;
+
+	priv->perf = NULL;
+
+	mutex_destroy(&perf->read_lock);
+
+	kfree(perf);
+}
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_rd.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_rd.c
@@ -0,0 +1,423 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+/* For debugging crashes, userspace can:
+ *
+ *   tail -f /sys/kernel/debug/dri/<minor>/rd > logfile.rd
+ *
+ * to log the cmdstream in a format that is understood by freedreno/cffdump
+ * utility.  By comparing the last successfully completed fence #, to the
+ * cmdstream for the next fence, you can narrow down which process and submit
+ * caused the gpu crash/lockup.
+ *
+ * Additionally:
+ *
+ *   tail -f /sys/kernel/debug/dri/<minor>/hangrd > logfile.rd
+ *
+ * will capture just the cmdstream from submits which triggered a GPU hang.
+ *
+ * This bypasses drm_debugfs_create_files() mainly because we need to use
+ * our own fops for a bit more control.  In particular, we don't want to
+ * do anything if userspace doesn't have the debugfs file open.
+ *
+ * The module-param "rd_full", which defaults to false, enables snapshotting
+ * all (non-written) buffers in the submit, rather than just cmdstream bo's.
+ * This is useful to capture the contents of (for example) vbo's or textures,
+ * or shader programs (if not emitted inline in cmdstream).
+ */
+
+#include <linux/circ_buf.h>
+#include <linux/debugfs.h>
+#include <linux/kfifo.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+
+#include <drm/drm_file.h>
+
+#include "msm_drv.h"
+#include "msm_gpu.h"
+#include "msm_gem.h"
+
+bool rd_full = false;
+MODULE_PARM_DESC(rd_full, "If true, $debugfs/.../rd will snapshot all buffer contents");
+module_param_named(rd_full, rd_full, bool, 0600);
+
+#ifdef CONFIG_DEBUG_FS
+
+enum rd_sect_type {
+	RD_NONE,
+	RD_TEST,       /* ascii text */
+	RD_CMD,        /* ascii text */
+	RD_GPUADDR,    /* u32 gpuaddr, u32 size */
+	RD_CONTEXT,    /* raw dump */
+	RD_CMDSTREAM,  /* raw dump */
+	RD_CMDSTREAM_ADDR, /* gpu addr of cmdstream */
+	RD_PARAM,      /* u32 param_type, u32 param_val, u32 bitlen */
+	RD_FLUSH,      /* empty, clear previous params */
+	RD_PROGRAM,    /* shader program, raw dump */
+	RD_VERT_SHADER,
+	RD_FRAG_SHADER,
+	RD_BUFFER_CONTENTS,
+	RD_GPU_ID,
+	RD_CHIP_ID,
+};
+
+#define BUF_SZ 512  /* should be power of 2 */
+
+/* space used: */
+#define circ_count(circ) \
+	(CIRC_CNT((circ)->head, (circ)->tail, BUF_SZ))
+#define circ_count_to_end(circ) \
+	(CIRC_CNT_TO_END((circ)->head, (circ)->tail, BUF_SZ))
+/* space available: */
+#define circ_space(circ) \
+	(CIRC_SPACE((circ)->head, (circ)->tail, BUF_SZ))
+#define circ_space_to_end(circ) \
+	(CIRC_SPACE_TO_END((circ)->head, (circ)->tail, BUF_SZ))
+
+struct msm_rd_state {
+	struct drm_device *dev;
+
+	bool open;
+
+	/* fifo access is synchronized on the producer side by
+	 * write_lock.  And read_lock synchronizes the reads
+	 */
+	struct mutex read_lock, write_lock;
+
+	wait_queue_head_t fifo_event;
+	struct circ_buf fifo;
+
+	char buf[BUF_SZ];
+};
+
+static void rd_write(struct msm_rd_state *rd, const void *buf, int sz)
+{
+	struct circ_buf *fifo = &rd->fifo;
+	const char *ptr = buf;
+
+	while (sz > 0) {
+		char *fptr = &fifo->buf[fifo->head];
+		int n;
+
+		wait_event(rd->fifo_event, circ_space(&rd->fifo) > 0 || !rd->open);
+		if (!rd->open)
+			return;
+
+		/* Note that smp_load_acquire() is not strictly required
+		 * as CIRC_SPACE_TO_END() does not access the tail more
+		 * than once.
+		 */
+		n = min(sz, circ_space_to_end(&rd->fifo));
+		memcpy(fptr, ptr, n);
+
+		smp_store_release(&fifo->head, (fifo->head + n) & (BUF_SZ - 1));
+		sz  -= n;
+		ptr += n;
+
+		wake_up_all(&rd->fifo_event);
+	}
+}
+
+static void rd_write_section(struct msm_rd_state *rd,
+		enum rd_sect_type type, const void *buf, int sz)
+{
+	rd_write(rd, &type, 4);
+	rd_write(rd, &sz, 4);
+	rd_write(rd, buf, sz);
+}
+
+static ssize_t rd_read(struct file *file, char __user *buf,
+		size_t sz, loff_t *ppos)
+{
+	struct msm_rd_state *rd = file->private_data;
+	struct circ_buf *fifo = &rd->fifo;
+	const char *fptr = &fifo->buf[fifo->tail];
+	int n = 0, ret = 0;
+
+	mutex_lock(&rd->read_lock);
+
+	ret = wait_event_interruptible(rd->fifo_event,
+			circ_count(&rd->fifo) > 0);
+	if (ret)
+		goto out;
+
+	/* Note that smp_load_acquire() is not strictly required
+	 * as CIRC_CNT_TO_END() does not access the head more than
+	 * once.
+	 */
+	n = min_t(int, sz, circ_count_to_end(&rd->fifo));
+	if (copy_to_user(buf, fptr, n)) {
+		ret = -EFAULT;
+		goto out;
+	}
+
+	smp_store_release(&fifo->tail, (fifo->tail + n) & (BUF_SZ - 1));
+	*ppos += n;
+
+	wake_up_all(&rd->fifo_event);
+
+out:
+	mutex_unlock(&rd->read_lock);
+	if (ret)
+		return ret;
+	return n;
+}
+
+static int rd_open(struct inode *inode, struct file *file)
+{
+	struct msm_rd_state *rd = inode->i_private;
+	struct drm_device *dev = rd->dev;
+	struct msm_drm_private *priv = dev->dev_private;
+	struct msm_gpu *gpu = priv->gpu;
+	uint64_t val;
+	uint32_t gpu_id;
+	uint32_t zero = 0;
+	int ret = 0;
+
+	if (!gpu)
+		return -ENODEV;
+
+	mutex_lock(&gpu->lock);
+
+	if (rd->open) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	file->private_data = rd;
+	rd->open = true;
+
+	/* Reset fifo to clear any previously unread data: */
+	rd->fifo.head = rd->fifo.tail = 0;
+
+	/* the parsing tools need to know gpu-id to know which
+	 * register database to load.
+	 *
+	 * Note: These particular params do not require a context
+	 */
+	gpu->funcs->get_param(gpu, NULL, MSM_PARAM_GPU_ID, &val, &zero);
+	gpu_id = val;
+
+	rd_write_section(rd, RD_GPU_ID, &gpu_id, sizeof(gpu_id));
+
+	gpu->funcs->get_param(gpu, NULL, MSM_PARAM_CHIP_ID, &val, &zero);
+	rd_write_section(rd, RD_CHIP_ID, &val, sizeof(val));
+
+out:
+	mutex_unlock(&gpu->lock);
+	return ret;
+}
+
+static int rd_release(struct inode *inode, struct file *file)
+{
+	struct msm_rd_state *rd = inode->i_private;
+
+	rd->open = false;
+	wake_up_all(&rd->fifo_event);
+
+	return 0;
+}
+
+
+static const struct file_operations rd_debugfs_fops = {
+	.owner = THIS_MODULE,
+	.open = rd_open,
+	.read = rd_read,
+	.llseek = no_llseek,
+	.release = rd_release,
+};
+
+
+static void rd_cleanup(struct msm_rd_state *rd)
+{
+	if (!rd)
+		return;
+
+	mutex_destroy(&rd->read_lock);
+	mutex_destroy(&rd->write_lock);
+	kfree(rd);
+}
+
+static struct msm_rd_state *rd_init(struct drm_minor *minor, const char *name)
+{
+	struct msm_rd_state *rd;
+
+	rd = kzalloc(sizeof(*rd), GFP_KERNEL);
+	if (!rd)
+		return ERR_PTR(-ENOMEM);
+
+	rd->dev = minor->dev;
+	rd->fifo.buf = rd->buf;
+
+	mutex_init(&rd->read_lock);
+	mutex_init(&rd->write_lock);
+
+	init_waitqueue_head(&rd->fifo_event);
+
+	debugfs_create_file(name, S_IFREG | S_IRUGO, minor->debugfs_root, rd,
+			    &rd_debugfs_fops);
+
+	return rd;
+}
+
+int msm_rd_debugfs_init(struct drm_minor *minor)
+{
+	struct msm_drm_private *priv = minor->dev->dev_private;
+	struct msm_rd_state *rd;
+	int ret;
+
+	if (!priv->gpu_pdev)
+		return 0;
+
+	/* only create on first minor: */
+	if (priv->rd)
+		return 0;
+
+	rd = rd_init(minor, "rd");
+	if (IS_ERR(rd)) {
+		ret = PTR_ERR(rd);
+		goto fail;
+	}
+
+	priv->rd = rd;
+
+	rd = rd_init(minor, "hangrd");
+	if (IS_ERR(rd)) {
+		ret = PTR_ERR(rd);
+		goto fail;
+	}
+
+	priv->hangrd = rd;
+
+	return 0;
+
+fail:
+	msm_rd_debugfs_cleanup(priv);
+	return ret;
+}
+
+void msm_rd_debugfs_cleanup(struct msm_drm_private *priv)
+{
+	rd_cleanup(priv->rd);
+	priv->rd = NULL;
+
+	rd_cleanup(priv->hangrd);
+	priv->hangrd = NULL;
+}
+
+static void snapshot_buf(struct msm_rd_state *rd,
+		struct msm_gem_submit *submit, int idx,
+		uint64_t iova, uint32_t size, bool full)
+{
+	struct drm_gem_object *obj = submit->bos[idx].obj;
+	unsigned offset = 0;
+	const char *buf;
+
+	if (iova) {
+		offset = iova - submit->bos[idx].iova;
+	} else {
+		iova = submit->bos[idx].iova;
+		size = obj->size;
+	}
+
+	/*
+	 * Always write the GPUADDR header so can get a complete list of all the
+	 * buffers in the cmd
+	 */
+	rd_write_section(rd, RD_GPUADDR,
+			(uint32_t[3]){ iova, size, iova >> 32 }, 12);
+
+	if (!full)
+		return;
+
+	/* But only dump the contents of buffers marked READ */
+	if (!(submit->bos[idx].flags & MSM_SUBMIT_BO_READ))
+		return;
+
+	buf = msm_gem_get_vaddr_active(obj);
+	if (IS_ERR(buf))
+		return;
+
+	buf += offset;
+
+	rd_write_section(rd, RD_BUFFER_CONTENTS, buf, size);
+
+	msm_gem_put_vaddr_locked(obj);
+}
+
+/* called under gpu->lock */
+void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
+		const char *fmt, ...)
+{
+	struct task_struct *task;
+	char msg[256];
+	int i, n;
+
+	if (!rd->open)
+		return;
+
+	mutex_lock(&rd->write_lock);
+
+	if (fmt) {
+		va_list args;
+
+		va_start(args, fmt);
+		n = vscnprintf(msg, sizeof(msg), fmt, args);
+		va_end(args);
+
+		rd_write_section(rd, RD_CMD, msg, ALIGN(n, 4));
+	}
+
+	rcu_read_lock();
+	task = pid_task(submit->pid, PIDTYPE_PID);
+	if (task) {
+		n = scnprintf(msg, sizeof(msg), "%.*s/%d: fence=%u",
+				TASK_COMM_LEN, task->comm,
+				pid_nr(submit->pid), submit->seqno);
+	} else {
+		n = scnprintf(msg, sizeof(msg), "???/%d: fence=%u",
+				pid_nr(submit->pid), submit->seqno);
+	}
+	rcu_read_unlock();
+
+	rd_write_section(rd, RD_CMD, msg, ALIGN(n, 4));
+
+	for (i = 0; i < submit->nr_bos; i++)
+		snapshot_buf(rd, submit, i, 0, 0, should_dump(submit, i));
+
+	for (i = 0; i < submit->nr_cmds; i++) {
+		uint32_t szd  = submit->cmd[i].size; /* in dwords */
+
+		/* snapshot cmdstream bo's (if we haven't already): */
+		if (!should_dump(submit, i)) {
+			snapshot_buf(rd, submit, submit->cmd[i].idx,
+					submit->cmd[i].iova, szd * 4, true);
+		}
+	}
+
+	for (i = 0; i < submit->nr_cmds; i++) {
+		uint64_t iova = submit->cmd[i].iova;
+		uint32_t szd  = submit->cmd[i].size; /* in dwords */
+
+		switch (submit->cmd[i].type) {
+		case MSM_SUBMIT_CMD_IB_TARGET_BUF:
+			/* ignore IB-targets, we've logged the buffer, the
+			 * parser tool will follow the IB based on the logged
+			 * buffer/gpuaddr, so nothing more to do.
+			 */
+			break;
+		case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+		case MSM_SUBMIT_CMD_BUF:
+			rd_write_section(rd, RD_CMDSTREAM_ADDR,
+				(uint32_t[3]){ iova, szd, iova >> 32 }, 12);
+			break;
+		}
+	}
+
+	mutex_unlock(&rd->write_lock);
+}
+#endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_ringbuffer.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_ringbuffer.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#include "msm_ringbuffer.h"
+#include "msm_gpu.h"
+
+static uint num_hw_submissions = 8;
+MODULE_PARM_DESC(num_hw_submissions, "The max # of jobs to write into ringbuffer (default 8)");
+module_param(num_hw_submissions, uint, 0600);
+
+static struct dma_fence *msm_job_run(struct drm_sched_job *job)
+{
+	struct msm_gem_submit *submit = to_msm_submit(job);
+	struct msm_fence_context *fctx = submit->ring->fctx;
+	struct msm_gpu *gpu = submit->gpu;
+	struct msm_drm_private *priv = gpu->dev->dev_private;
+	int i;
+
+	msm_fence_init(submit->hw_fence, fctx);
+
+	mutex_lock(&priv->lru.lock);
+
+	for (i = 0; i < submit->nr_bos; i++) {
+		struct drm_gem_object *obj = submit->bos[i].obj;
+
+		msm_gem_unpin_active(obj);
+	}
+
+	submit->bos_pinned = false;
+
+	mutex_unlock(&priv->lru.lock);
+
+	/* TODO move submit path over to using a per-ring lock.. */
+	mutex_lock(&gpu->lock);
+
+	msm_gpu_submit(gpu, submit);
+
+	mutex_unlock(&gpu->lock);
+
+	return dma_fence_get(submit->hw_fence);
+}
+
+static void msm_job_free(struct drm_sched_job *job)
+{
+	struct msm_gem_submit *submit = to_msm_submit(job);
+
+	drm_sched_job_cleanup(job);
+	msm_gem_submit_put(submit);
+}
+
+static const struct drm_sched_backend_ops msm_sched_ops = {
+	.run_job = msm_job_run,
+	.free_job = msm_job_free
+};
+
+struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id,
+		void *memptrs, uint64_t memptrs_iova)
+{
+	struct msm_ringbuffer *ring;
+	long sched_timeout;
+	char name[32];
+	int ret;
+
+	/* We assume everwhere that MSM_GPU_RINGBUFFER_SZ is a power of 2 */
+	BUILD_BUG_ON(!is_power_of_2(MSM_GPU_RINGBUFFER_SZ));
+
+	ring = kzalloc(sizeof(*ring), GFP_KERNEL);
+	if (!ring) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	ring->gpu = gpu;
+	ring->id = id;
+
+	ring->start = msm_gem_kernel_new(gpu->dev, MSM_GPU_RINGBUFFER_SZ,
+		check_apriv(gpu, MSM_BO_WC | MSM_BO_GPU_READONLY),
+		gpu->aspace, &ring->bo, &ring->iova);
+
+	if (IS_ERR(ring->start)) {
+		ret = PTR_ERR(ring->start);
+		ring->start = NULL;
+		goto fail;
+	}
+
+	msm_gem_object_set_name(ring->bo, "ring%d", id);
+
+	ring->end   = ring->start + (MSM_GPU_RINGBUFFER_SZ >> 2);
+	ring->next  = ring->start;
+	ring->cur   = ring->start;
+
+	ring->memptrs = memptrs;
+	ring->memptrs_iova = memptrs_iova;
+
+	 /* currently managing hangcheck ourselves: */
+	sched_timeout = MAX_SCHEDULE_TIMEOUT;
+
+	ret = drm_sched_init(&ring->sched, &msm_sched_ops, NULL,
+			     DRM_SCHED_PRIORITY_COUNT,
+			     num_hw_submissions, 0, sched_timeout,
+			     NULL, NULL, to_msm_bo(ring->bo)->name, gpu->dev->dev);
+	if (ret) {
+		goto fail;
+	}
+
+	INIT_LIST_HEAD(&ring->submits);
+	spin_lock_init(&ring->submit_lock);
+	spin_lock_init(&ring->preempt_lock);
+
+	snprintf(name, sizeof(name), "gpu-ring-%d", ring->id);
+
+	ring->fctx = msm_fence_context_alloc(gpu->dev, &ring->memptrs->fence, name);
+
+	return ring;
+
+fail:
+	msm_ringbuffer_destroy(ring);
+	return ERR_PTR(ret);
+}
+
+void msm_ringbuffer_destroy(struct msm_ringbuffer *ring)
+{
+	if (IS_ERR_OR_NULL(ring))
+		return;
+
+	drm_sched_fini(&ring->sched);
+
+	msm_fence_context_free(ring->fctx);
+
+	msm_gem_kernel_put(ring->bo, ring->gpu->aspace);
+
+	kfree(ring);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_ringbuffer.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_ringbuffer.h
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ */
+
+#ifndef __MSM_RINGBUFFER_H__
+#define __MSM_RINGBUFFER_H__
+
+#include "drm/gpu_scheduler.h"
+#include "msm_drv.h"
+
+#define rbmemptr(ring, member)  \
+	((ring)->memptrs_iova + offsetof(struct msm_rbmemptrs, member))
+
+#define rbmemptr_stats(ring, index, member) \
+	(rbmemptr((ring), stats) + \
+	 ((index) * sizeof(struct msm_gpu_submit_stats)) + \
+	 offsetof(struct msm_gpu_submit_stats, member))
+
+struct msm_gpu_submit_stats {
+	u64 cpcycles_start;
+	u64 cpcycles_end;
+	u64 alwayson_start;
+	u64 alwayson_end;
+};
+
+#define MSM_GPU_SUBMIT_STATS_COUNT 64
+
+struct msm_rbmemptrs {
+	volatile uint32_t rptr;
+	volatile uint32_t fence;
+	/* Introduced on A7xx */
+	volatile uint32_t bv_fence;
+
+	volatile struct msm_gpu_submit_stats stats[MSM_GPU_SUBMIT_STATS_COUNT];
+	volatile u64 ttbr0;
+};
+
+struct msm_cp_state {
+	uint64_t ib1_base, ib2_base;
+	uint32_t ib1_rem, ib2_rem;
+};
+
+struct msm_ringbuffer {
+	struct msm_gpu *gpu;
+	int id;
+	struct drm_gem_object *bo;
+	uint32_t *start, *end, *cur, *next;
+
+	/*
+	 * The job scheduler for this ring.
+	 */
+	struct drm_gpu_scheduler sched;
+
+	/*
+	 * List of in-flight submits on this ring.  Protected by submit_lock.
+	 *
+	 * Currently just submits that are already written into the ring, not
+	 * submits that are still in drm_gpu_scheduler's queues.  At a later
+	 * step we could probably move to letting drm_gpu_scheduler manage
+	 * hangcheck detection and keep track of submit jobs that are in-
+	 * flight.
+	 */
+	struct list_head submits;
+	spinlock_t submit_lock;
+
+	uint64_t iova;
+	uint32_t hangcheck_fence;
+	struct msm_rbmemptrs *memptrs;
+	uint64_t memptrs_iova;
+	struct msm_fence_context *fctx;
+
+	/**
+	 * hangcheck_progress_retries:
+	 *
+	 * The number of extra hangcheck duration cycles that we have given
+	 * due to it appearing that the GPU is making forward progress.
+	 *
+	 * For GPU generations which support progress detection (see.
+	 * msm_gpu_funcs::progress()), if the GPU appears to be making progress
+	 * (ie. the CP has advanced in the command stream, we'll allow up to
+	 * DRM_MSM_HANGCHECK_PROGRESS_RETRIES expirations of the hangcheck timer
+	 * before killing the job.  But to detect progress we need two sample
+	 * points, so the duration of the hangcheck timer is halved.  In other
+	 * words we'll let the submit run for up to:
+	 *
+	 * (DRM_MSM_HANGCHECK_DEFAULT_PERIOD / 2) * (DRM_MSM_HANGCHECK_PROGRESS_RETRIES + 1)
+	 */
+	int hangcheck_progress_retries;
+
+	/**
+	 * last_cp_state: The state of the CP at the last call to gpu->progress()
+	 */
+	struct msm_cp_state last_cp_state;
+
+	/*
+	 * preempt_lock protects preemption and serializes wptr updates against
+	 * preemption.  Can be aquired from irq context.
+	 */
+	spinlock_t preempt_lock;
+};
+
+struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id,
+		void *memptrs, uint64_t memptrs_iova);
+void msm_ringbuffer_destroy(struct msm_ringbuffer *ring);
+
+/* ringbuffer helpers (the parts that are same for a3xx/a2xx/z180..) */
+
+static inline void
+OUT_RING(struct msm_ringbuffer *ring, uint32_t data)
+{
+	/*
+	 * ring->next points to the current command being written - it won't be
+	 * committed as ring->cur until the flush
+	 */
+	if (ring->next == ring->end)
+		ring->next = ring->start;
+	*(ring->next++) = data;
+}
+
+#endif /* __MSM_RINGBUFFER_H__ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/msm_submitqueue.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/msm_submitqueue.c
@@ -0,0 +1,307 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/kref.h>
+#include <linux/uaccess.h>
+
+#include "msm_gpu.h"
+
+int msm_file_private_set_sysprof(struct msm_file_private *ctx,
+				 struct msm_gpu *gpu, int sysprof)
+{
+	/*
+	 * Since pm_runtime and sysprof_active are both refcounts, we
+	 * call apply the new value first, and then unwind the previous
+	 * value
+	 */
+
+	switch (sysprof) {
+	default:
+		return -EINVAL;
+	case 2:
+		pm_runtime_get_sync(&gpu->pdev->dev);
+		fallthrough;
+	case 1:
+		refcount_inc(&gpu->sysprof_active);
+		fallthrough;
+	case 0:
+		break;
+	}
+
+	/* unwind old value: */
+	switch (ctx->sysprof) {
+	case 2:
+		pm_runtime_put_autosuspend(&gpu->pdev->dev);
+		fallthrough;
+	case 1:
+		refcount_dec(&gpu->sysprof_active);
+		fallthrough;
+	case 0:
+		break;
+	}
+
+	ctx->sysprof = sysprof;
+
+	return 0;
+}
+
+void __msm_file_private_destroy(struct kref *kref)
+{
+	struct msm_file_private *ctx = container_of(kref,
+		struct msm_file_private, ref);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ctx->entities); i++) {
+		if (!ctx->entities[i])
+			continue;
+
+		drm_sched_entity_destroy(ctx->entities[i]);
+		kfree(ctx->entities[i]);
+	}
+
+	msm_gem_address_space_put(ctx->aspace);
+	kfree(ctx->comm);
+	kfree(ctx->cmdline);
+	kfree(ctx);
+}
+
+void msm_submitqueue_destroy(struct kref *kref)
+{
+	struct msm_gpu_submitqueue *queue = container_of(kref,
+		struct msm_gpu_submitqueue, ref);
+
+	idr_destroy(&queue->fence_idr);
+
+	msm_file_private_put(queue->ctx);
+
+	kfree(queue);
+}
+
+struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
+		u32 id)
+{
+	struct msm_gpu_submitqueue *entry;
+
+	if (!ctx)
+		return NULL;
+
+	read_lock(&ctx->queuelock);
+
+	list_for_each_entry(entry, &ctx->submitqueues, node) {
+		if (entry->id == id) {
+			kref_get(&entry->ref);
+			read_unlock(&ctx->queuelock);
+
+			return entry;
+		}
+	}
+
+	read_unlock(&ctx->queuelock);
+	return NULL;
+}
+
+void msm_submitqueue_close(struct msm_file_private *ctx)
+{
+	struct msm_gpu_submitqueue *entry, *tmp;
+
+	if (!ctx)
+		return;
+
+	/*
+	 * No lock needed in close and there won't
+	 * be any more user ioctls coming our way
+	 */
+	list_for_each_entry_safe(entry, tmp, &ctx->submitqueues, node) {
+		list_del(&entry->node);
+		msm_submitqueue_put(entry);
+	}
+}
+
+static struct drm_sched_entity *
+get_sched_entity(struct msm_file_private *ctx, struct msm_ringbuffer *ring,
+		 unsigned ring_nr, enum drm_sched_priority sched_prio)
+{
+	static DEFINE_MUTEX(entity_lock);
+	unsigned idx = (ring_nr * NR_SCHED_PRIORITIES) + sched_prio;
+
+	/* We should have already validated that the requested priority is
+	 * valid by the time we get here.
+	 */
+	if (WARN_ON(idx >= ARRAY_SIZE(ctx->entities)))
+		return ERR_PTR(-EINVAL);
+
+	mutex_lock(&entity_lock);
+
+	if (!ctx->entities[idx]) {
+		struct drm_sched_entity *entity;
+		struct drm_gpu_scheduler *sched = &ring->sched;
+		int ret;
+
+		entity = kzalloc(sizeof(*ctx->entities[idx]), GFP_KERNEL);
+
+		ret = drm_sched_entity_init(entity, sched_prio, &sched, 1, NULL);
+		if (ret) {
+			mutex_unlock(&entity_lock);
+			kfree(entity);
+			return ERR_PTR(ret);
+		}
+
+		ctx->entities[idx] = entity;
+	}
+
+	mutex_unlock(&entity_lock);
+
+	return ctx->entities[idx];
+}
+
+int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx,
+		u32 prio, u32 flags, u32 *id)
+{
+	struct msm_drm_private *priv = drm->dev_private;
+	struct msm_gpu_submitqueue *queue;
+	enum drm_sched_priority sched_prio;
+	unsigned ring_nr;
+	int ret;
+
+	if (!ctx)
+		return -ENODEV;
+
+	if (!priv->gpu)
+		return -ENODEV;
+
+	ret = msm_gpu_convert_priority(priv->gpu, prio, &ring_nr, &sched_prio);
+	if (ret)
+		return ret;
+
+	queue = kzalloc(sizeof(*queue), GFP_KERNEL);
+
+	if (!queue)
+		return -ENOMEM;
+
+	kref_init(&queue->ref);
+	queue->flags = flags;
+	queue->ring_nr = ring_nr;
+
+	queue->entity = get_sched_entity(ctx, priv->gpu->rb[ring_nr],
+					 ring_nr, sched_prio);
+	if (IS_ERR(queue->entity)) {
+		ret = PTR_ERR(queue->entity);
+		kfree(queue);
+		return ret;
+	}
+
+	write_lock(&ctx->queuelock);
+
+	queue->ctx = msm_file_private_get(ctx);
+	queue->id = ctx->queueid++;
+
+	if (id)
+		*id = queue->id;
+
+	idr_init(&queue->fence_idr);
+	spin_lock_init(&queue->idr_lock);
+	mutex_init(&queue->lock);
+
+	list_add_tail(&queue->node, &ctx->submitqueues);
+
+	write_unlock(&ctx->queuelock);
+
+	return 0;
+}
+
+/*
+ * Create the default submit-queue (id==0), used for backwards compatibility
+ * for userspace that pre-dates the introduction of submitqueues.
+ */
+int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx)
+{
+	struct msm_drm_private *priv = drm->dev_private;
+	int default_prio, max_priority;
+
+	if (!priv->gpu)
+		return -ENODEV;
+
+	max_priority = (priv->gpu->nr_rings * NR_SCHED_PRIORITIES) - 1;
+
+	/*
+	 * Pick a medium priority level as default.  Lower numeric value is
+	 * higher priority, so round-up to pick a priority that is not higher
+	 * than the middle priority level.
+	 */
+	default_prio = DIV_ROUND_UP(max_priority, 2);
+
+	return msm_submitqueue_create(drm, ctx, default_prio, 0, NULL);
+}
+
+static int msm_submitqueue_query_faults(struct msm_gpu_submitqueue *queue,
+		struct drm_msm_submitqueue_query *args)
+{
+	size_t size = min_t(size_t, args->len, sizeof(queue->faults));
+	int ret;
+
+	/* If a zero length was passed in, return the data size we expect */
+	if (!args->len) {
+		args->len = sizeof(queue->faults);
+		return 0;
+	}
+
+	/* Set the length to the actual size of the data */
+	args->len = size;
+
+	ret = copy_to_user(u64_to_user_ptr(args->data), &queue->faults, size);
+
+	return ret ? -EFAULT : 0;
+}
+
+int msm_submitqueue_query(struct drm_device *drm, struct msm_file_private *ctx,
+		struct drm_msm_submitqueue_query *args)
+{
+	struct msm_gpu_submitqueue *queue;
+	int ret = -EINVAL;
+
+	if (args->pad)
+		return -EINVAL;
+
+	queue = msm_submitqueue_get(ctx, args->id);
+	if (!queue)
+		return -ENOENT;
+
+	if (args->param == MSM_SUBMITQUEUE_PARAM_FAULTS)
+		ret = msm_submitqueue_query_faults(queue, args);
+
+	msm_submitqueue_put(queue);
+
+	return ret;
+}
+
+int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id)
+{
+	struct msm_gpu_submitqueue *entry;
+
+	if (!ctx)
+		return 0;
+
+	/*
+	 * id 0 is the "default" queue and can't be destroyed
+	 * by the user
+	 */
+	if (!id)
+		return -ENOENT;
+
+	write_lock(&ctx->queuelock);
+
+	list_for_each_entry(entry, &ctx->submitqueues, node) {
+		if (entry->id == id) {
+			list_del(&entry->node);
+			write_unlock(&ctx->queuelock);
+
+			msm_submitqueue_put(entry);
+			return 0;
+		}
+	}
+
+	write_unlock(&ctx->queuelock);
+	return -ENOENT;
+}
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/adreno/a2xx.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/adreno/a2xx.xml
@@ -0,0 +1,1865 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="adreno/adreno_common.xml"/>
+<import file="adreno/adreno_pm4.xml"/>
+
+
+<enum name="a2xx_rb_dither_type">
+	<value name="DITHER_PIXEL" value="0"/>
+	<value name="DITHER_SUBPIXEL" value="1"/>
+</enum>
+
+<enum name="a2xx_colorformatx">
+	<value name="COLORX_4_4_4_4" value="0"/>
+	<value name="COLORX_1_5_5_5" value="1"/>
+	<value name="COLORX_5_6_5" value="2"/>
+	<value name="COLORX_8" value="3"/>
+	<value name="COLORX_8_8" value="4"/>
+	<value name="COLORX_8_8_8_8" value="5"/>
+	<value name="COLORX_S8_8_8_8" value="6"/>
+	<value name="COLORX_16_FLOAT" value="7"/>
+	<value name="COLORX_16_16_FLOAT" value="8"/>
+	<value name="COLORX_16_16_16_16_FLOAT" value="9"/>
+	<value name="COLORX_32_FLOAT" value="10"/>
+	<value name="COLORX_32_32_FLOAT" value="11"/>
+	<value name="COLORX_32_32_32_32_FLOAT" value="12"/>
+	<value name="COLORX_2_3_3" value="13"/>
+	<value name="COLORX_8_8_8" value="14"/>
+</enum>
+
+<enum name="a2xx_sq_surfaceformat">
+	<value name="FMT_1_REVERSE" value="0"/>
+	<value name="FMT_1" value="1"/>
+	<value name="FMT_8" value="2"/>
+	<value name="FMT_1_5_5_5" value="3"/>
+	<value name="FMT_5_6_5" value="4"/>
+	<value name="FMT_6_5_5" value="5"/>
+	<value name="FMT_8_8_8_8" value="6"/>
+	<value name="FMT_2_10_10_10" value="7"/>
+	<value name="FMT_8_A" value="8"/>
+	<value name="FMT_8_B" value="9"/>
+	<value name="FMT_8_8" value="10"/>
+	<value name="FMT_Cr_Y1_Cb_Y0" value="11"/>
+	<value name="FMT_Y1_Cr_Y0_Cb" value="12"/>
+	<value name="FMT_5_5_5_1" value="13"/>
+	<value name="FMT_8_8_8_8_A" value="14"/>
+	<value name="FMT_4_4_4_4" value="15"/>
+	<value name="FMT_8_8_8" value="16"/>
+	<value name="FMT_DXT1" value="18"/>
+	<value name="FMT_DXT2_3" value="19"/>
+	<value name="FMT_DXT4_5" value="20"/>
+	<value name="FMT_10_10_10_2" value="21"/>
+	<value name="FMT_24_8" value="22"/>
+	<value name="FMT_16" value="24"/>
+	<value name="FMT_16_16" value="25"/>
+	<value name="FMT_16_16_16_16" value="26"/>
+	<value name="FMT_16_EXPAND" value="27"/>
+	<value name="FMT_16_16_EXPAND" value="28"/>
+	<value name="FMT_16_16_16_16_EXPAND" value="29"/>
+	<value name="FMT_16_FLOAT" value="30"/>
+	<value name="FMT_16_16_FLOAT" value="31"/>
+	<value name="FMT_16_16_16_16_FLOAT" value="32"/>
+	<value name="FMT_32" value="33"/>
+	<value name="FMT_32_32" value="34"/>
+	<value name="FMT_32_32_32_32" value="35"/>
+	<value name="FMT_32_FLOAT" value="36"/>
+	<value name="FMT_32_32_FLOAT" value="37"/>
+	<value name="FMT_32_32_32_32_FLOAT" value="38"/>
+	<value name="FMT_ATI_TC_RGB" value="39"/>
+	<value name="FMT_ATI_TC_RGBA" value="40"/>
+	<value name="FMT_ATI_TC_555_565_RGB" value="41"/>
+	<value name="FMT_ATI_TC_555_565_RGBA" value="42"/>
+	<value name="FMT_ATI_TC_RGBA_INTERP" value="43"/>
+	<value name="FMT_ATI_TC_555_565_RGBA_INTERP" value="44"/>
+	<value name="FMT_ETC1_RGBA_INTERP" value="46"/>
+	<value name="FMT_ETC1_RGB" value="47"/>
+	<value name="FMT_ETC1_RGBA" value="48"/>
+	<value name="FMT_DXN" value="49"/>
+	<value name="FMT_2_3_3" value="51"/>
+	<value name="FMT_2_10_10_10_AS_16_16_16_16" value="54"/>
+	<value name="FMT_10_10_10_2_AS_16_16_16_16" value="55"/>
+	<value name="FMT_32_32_32_FLOAT" value="57"/>
+	<value name="FMT_DXT3A" value="58"/>
+	<value name="FMT_DXT5A" value="59"/>
+	<value name="FMT_CTX1" value="60"/>
+</enum>
+
+<enum name="a2xx_sq_ps_vtx_mode">
+	<value name="POSITION_1_VECTOR" value="0"/>
+	<value name="POSITION_2_VECTORS_UNUSED" value="1"/>
+	<value name="POSITION_2_VECTORS_SPRITE" value="2"/>
+	<value name="POSITION_2_VECTORS_EDGE" value="3"/>
+	<value name="POSITION_2_VECTORS_KILL" value="4"/>
+	<value name="POSITION_2_VECTORS_SPRITE_KILL" value="5"/>
+	<value name="POSITION_2_VECTORS_EDGE_KILL" value="6"/>
+	<value name="MULTIPASS" value="7"/>
+</enum>
+
+<enum name="a2xx_sq_sample_cntl">
+	<value name="CENTROIDS_ONLY" value="0"/>
+	<value name="CENTERS_ONLY" value="1"/>
+	<value name="CENTROIDS_AND_CENTERS" value="2"/>
+</enum>
+
+<enum name="a2xx_dx_clip_space">
+	<value name="DXCLIP_OPENGL" value="0"/>
+	<value name="DXCLIP_DIRECTX" value="1"/>
+</enum>
+
+<enum name="a2xx_pa_su_sc_polymode">
+	<value name="POLY_DISABLED" value="0"/>
+	<value name="POLY_DUALMODE" value="1"/>
+</enum>
+
+<enum name="a2xx_rb_edram_mode">
+	<value name="EDRAM_NOP" value="0"/>
+	<value name="COLOR_DEPTH" value="4"/>
+	<value name="DEPTH_ONLY" value="5"/>
+	<value name="EDRAM_COPY" value="6"/>
+</enum>
+
+<enum name="a2xx_pa_sc_pattern_bit_order">
+	<value name="LITTLE" value="0"/>
+	<value name="BIG" value="1"/>
+</enum>
+
+<enum name="a2xx_pa_sc_auto_reset_cntl">
+	<value name="NEVER" value="0"/>
+	<value name="EACH_PRIMITIVE" value="1"/>
+	<value name="EACH_PACKET" value="2"/>
+</enum>
+
+<enum name="a2xx_pa_pixcenter">
+	<value name="PIXCENTER_D3D" value="0"/>
+	<value name="PIXCENTER_OGL" value="1"/>
+</enum>
+
+<enum name="a2xx_pa_roundmode">
+	<value name="TRUNCATE" value="0"/>
+	<value name="ROUND" value="1"/>
+	<value name="ROUNDTOEVEN" value="2"/>
+	<value name="ROUNDTOODD" value="3"/>
+</enum>
+
+<enum name="a2xx_pa_quantmode">
+	<value name="ONE_SIXTEENTH" value="0"/>
+	<value name="ONE_EIGTH" value="1"/>
+	<value name="ONE_QUARTER" value="2"/>
+	<value name="ONE_HALF" value="3"/>
+	<value name="ONE" value="4"/>
+</enum>
+
+<enum name="a2xx_rb_copy_sample_select">
+	<value name="SAMPLE_0" value="0"/>
+	<value name="SAMPLE_1" value="1"/>
+	<value name="SAMPLE_2" value="2"/>
+	<value name="SAMPLE_3" value="3"/>
+	<value name="SAMPLE_01" value="4"/>
+	<value name="SAMPLE_23" value="5"/>
+	<value name="SAMPLE_0123" value="6"/>
+</enum>
+
+<enum name="a2xx_rb_blend_opcode">
+	<value name="BLEND2_DST_PLUS_SRC" value="0"/>
+	<value name="BLEND2_SRC_MINUS_DST" value="1"/>
+	<value name="BLEND2_MIN_DST_SRC" value="2"/>
+	<value name="BLEND2_MAX_DST_SRC" value="3"/>
+	<value name="BLEND2_DST_MINUS_SRC" value="4"/>
+	<value name="BLEND2_DST_PLUS_SRC_BIAS" value="5"/>
+</enum>
+
+<enum name="a2xx_su_perfcnt_select">
+	<value value="0" name="PERF_PAPC_PASX_REQ"/>
+	<value value="2" name="PERF_PAPC_PASX_FIRST_VECTOR"/>
+	<value value="3" name="PERF_PAPC_PASX_SECOND_VECTOR"/>
+	<value value="4" name="PERF_PAPC_PASX_FIRST_DEAD"/>
+	<value value="5" name="PERF_PAPC_PASX_SECOND_DEAD"/>
+	<value value="6" name="PERF_PAPC_PASX_VTX_KILL_DISCARD"/>
+	<value value="7" name="PERF_PAPC_PASX_VTX_NAN_DISCARD"/>
+	<value value="8" name="PERF_PAPC_PA_INPUT_PRIM"/>
+	<value value="9" name="PERF_PAPC_PA_INPUT_NULL_PRIM"/>
+	<value value="10" name="PERF_PAPC_PA_INPUT_EVENT_FLAG"/>
+	<value value="11" name="PERF_PAPC_PA_INPUT_FIRST_PRIM_SLOT"/>
+	<value value="12" name="PERF_PAPC_PA_INPUT_END_OF_PACKET"/>
+	<value value="13" name="PERF_PAPC_CLPR_CULL_PRIM"/>
+	<value value="15" name="PERF_PAPC_CLPR_VV_CULL_PRIM"/>
+	<value value="17" name="PERF_PAPC_CLPR_VTX_KILL_CULL_PRIM"/>
+	<value value="18" name="PERF_PAPC_CLPR_VTX_NAN_CULL_PRIM"/>
+	<value value="19" name="PERF_PAPC_CLPR_CULL_TO_NULL_PRIM"/>
+	<value value="21" name="PERF_PAPC_CLPR_VV_CLIP_PRIM"/>
+	<value value="23" name="PERF_PAPC_CLPR_POINT_CLIP_CANDIDATE"/>
+	<value value="24" name="PERF_PAPC_CLPR_CLIP_PLANE_CNT_1"/>
+	<value value="25" name="PERF_PAPC_CLPR_CLIP_PLANE_CNT_2"/>
+	<value value="26" name="PERF_PAPC_CLPR_CLIP_PLANE_CNT_3"/>
+	<value value="27" name="PERF_PAPC_CLPR_CLIP_PLANE_CNT_4"/>
+	<value value="28" name="PERF_PAPC_CLPR_CLIP_PLANE_CNT_5"/>
+	<value value="29" name="PERF_PAPC_CLPR_CLIP_PLANE_CNT_6"/>
+	<value value="30" name="PERF_PAPC_CLPR_CLIP_PLANE_NEAR"/>
+	<value value="31" name="PERF_PAPC_CLPR_CLIP_PLANE_FAR"/>
+	<value value="32" name="PERF_PAPC_CLPR_CLIP_PLANE_LEFT"/>
+	<value value="33" name="PERF_PAPC_CLPR_CLIP_PLANE_RIGHT"/>
+	<value value="34" name="PERF_PAPC_CLPR_CLIP_PLANE_TOP"/>
+	<value value="35" name="PERF_PAPC_CLPR_CLIP_PLANE_BOTTOM"/>
+	<value value="36" name="PERF_PAPC_CLSM_NULL_PRIM"/>
+	<value value="37" name="PERF_PAPC_CLSM_TOTALLY_VISIBLE_PRIM"/>
+	<value value="38" name="PERF_PAPC_CLSM_CLIP_PRIM"/>
+	<value value="39" name="PERF_PAPC_CLSM_CULL_TO_NULL_PRIM"/>
+	<value value="40" name="PERF_PAPC_CLSM_OUT_PRIM_CNT_1"/>
+	<value value="41" name="PERF_PAPC_CLSM_OUT_PRIM_CNT_2"/>
+	<value value="42" name="PERF_PAPC_CLSM_OUT_PRIM_CNT_3"/>
+	<value value="43" name="PERF_PAPC_CLSM_OUT_PRIM_CNT_4"/>
+	<value value="44" name="PERF_PAPC_CLSM_OUT_PRIM_CNT_5"/>
+	<value value="45" name="PERF_PAPC_CLSM_OUT_PRIM_CNT_6_7"/>
+	<value value="46" name="PERF_PAPC_CLSM_NON_TRIVIAL_CULL"/>
+	<value value="47" name="PERF_PAPC_SU_INPUT_PRIM"/>
+	<value value="48" name="PERF_PAPC_SU_INPUT_CLIP_PRIM"/>
+	<value value="49" name="PERF_PAPC_SU_INPUT_NULL_PRIM"/>
+	<value value="50" name="PERF_PAPC_SU_ZERO_AREA_CULL_PRIM"/>
+	<value value="51" name="PERF_PAPC_SU_BACK_FACE_CULL_PRIM"/>
+	<value value="52" name="PERF_PAPC_SU_FRONT_FACE_CULL_PRIM"/>
+	<value value="53" name="PERF_PAPC_SU_POLYMODE_FACE_CULL"/>
+	<value value="54" name="PERF_PAPC_SU_POLYMODE_BACK_CULL"/>
+	<value value="55" name="PERF_PAPC_SU_POLYMODE_FRONT_CULL"/>
+	<value value="56" name="PERF_PAPC_SU_POLYMODE_INVALID_FILL"/>
+	<value value="57" name="PERF_PAPC_SU_OUTPUT_PRIM"/>
+	<value value="58" name="PERF_PAPC_SU_OUTPUT_CLIP_PRIM"/>
+	<value value="59" name="PERF_PAPC_SU_OUTPUT_NULL_PRIM"/>
+	<value value="60" name="PERF_PAPC_SU_OUTPUT_EVENT_FLAG"/>
+	<value value="61" name="PERF_PAPC_SU_OUTPUT_FIRST_PRIM_SLOT"/>
+	<value value="62" name="PERF_PAPC_SU_OUTPUT_END_OF_PACKET"/>
+	<value value="63" name="PERF_PAPC_SU_OUTPUT_POLYMODE_FACE"/>
+	<value value="64" name="PERF_PAPC_SU_OUTPUT_POLYMODE_BACK"/>
+	<value value="65" name="PERF_PAPC_SU_OUTPUT_POLYMODE_FRONT"/>
+	<value value="66" name="PERF_PAPC_SU_OUT_CLIP_POLYMODE_FACE"/>
+	<value value="67" name="PERF_PAPC_SU_OUT_CLIP_POLYMODE_BACK"/>
+	<value value="68" name="PERF_PAPC_SU_OUT_CLIP_POLYMODE_FRONT"/>
+	<value value="69" name="PERF_PAPC_PASX_REQ_IDLE"/>
+	<value value="70" name="PERF_PAPC_PASX_REQ_BUSY"/>
+	<value value="71" name="PERF_PAPC_PASX_REQ_STALLED"/>
+	<value value="72" name="PERF_PAPC_PASX_REC_IDLE"/>
+	<value value="73" name="PERF_PAPC_PASX_REC_BUSY"/>
+	<value value="74" name="PERF_PAPC_PASX_REC_STARVED_SX"/>
+	<value value="75" name="PERF_PAPC_PASX_REC_STALLED"/>
+	<value value="76" name="PERF_PAPC_PASX_REC_STALLED_POS_MEM"/>
+	<value value="77" name="PERF_PAPC_PASX_REC_STALLED_CCGSM_IN"/>
+	<value value="78" name="PERF_PAPC_CCGSM_IDLE"/>
+	<value value="79" name="PERF_PAPC_CCGSM_BUSY"/>
+	<value value="80" name="PERF_PAPC_CCGSM_STALLED"/>
+	<value value="81" name="PERF_PAPC_CLPRIM_IDLE"/>
+	<value value="82" name="PERF_PAPC_CLPRIM_BUSY"/>
+	<value value="83" name="PERF_PAPC_CLPRIM_STALLED"/>
+	<value value="84" name="PERF_PAPC_CLPRIM_STARVED_CCGSM"/>
+	<value value="85" name="PERF_PAPC_CLIPSM_IDLE"/>
+	<value value="86" name="PERF_PAPC_CLIPSM_BUSY"/>
+	<value value="87" name="PERF_PAPC_CLIPSM_WAIT_CLIP_VERT_ENGH"/>
+	<value value="88" name="PERF_PAPC_CLIPSM_WAIT_HIGH_PRI_SEQ"/>
+	<value value="89" name="PERF_PAPC_CLIPSM_WAIT_CLIPGA"/>
+	<value value="90" name="PERF_PAPC_CLIPSM_WAIT_AVAIL_VTE_CLIP"/>
+	<value value="91" name="PERF_PAPC_CLIPSM_WAIT_CLIP_OUTSM"/>
+	<value value="92" name="PERF_PAPC_CLIPGA_IDLE"/>
+	<value value="93" name="PERF_PAPC_CLIPGA_BUSY"/>
+	<value value="94" name="PERF_PAPC_CLIPGA_STARVED_VTE_CLIP"/>
+	<value value="95" name="PERF_PAPC_CLIPGA_STALLED"/>
+	<value value="96" name="PERF_PAPC_CLIP_IDLE"/>
+	<value value="97" name="PERF_PAPC_CLIP_BUSY"/>
+	<value value="98" name="PERF_PAPC_SU_IDLE"/>
+	<value value="99" name="PERF_PAPC_SU_BUSY"/>
+	<value value="100" name="PERF_PAPC_SU_STARVED_CLIP"/>
+	<value value="101" name="PERF_PAPC_SU_STALLED_SC"/>
+	<value value="102" name="PERF_PAPC_SU_FACENESS_CULL"/>
+</enum>
+
+<enum name="a2xx_sc_perfcnt_select">
+	<value value="0" name="SC_SR_WINDOW_VALID"/>
+	<value value="1" name="SC_CW_WINDOW_VALID"/>
+	<value value="2" name="SC_QM_WINDOW_VALID"/>
+	<value value="3" name="SC_FW_WINDOW_VALID"/>
+	<value value="4" name="SC_EZ_WINDOW_VALID"/>
+	<value value="5" name="SC_IT_WINDOW_VALID"/>
+	<value value="6" name="SC_STARVED_BY_PA"/>
+	<value value="7" name="SC_STALLED_BY_RB_TILE"/>
+	<value value="8" name="SC_STALLED_BY_RB_SAMP"/>
+	<value value="9" name="SC_STARVED_BY_RB_EZ"/>
+	<value value="10" name="SC_STALLED_BY_SAMPLE_FF"/>
+	<value value="11" name="SC_STALLED_BY_SQ"/>
+	<value value="12" name="SC_STALLED_BY_SP"/>
+	<value value="13" name="SC_TOTAL_NO_PRIMS"/>
+	<value value="14" name="SC_NON_EMPTY_PRIMS"/>
+	<value value="15" name="SC_NO_TILES_PASSING_QM"/>
+	<value value="16" name="SC_NO_PIXELS_PRE_EZ"/>
+	<value value="17" name="SC_NO_PIXELS_POST_EZ"/>
+</enum>
+
+<enum name="a2xx_vgt_perfcount_select">
+	<value value="0" name="VGT_SQ_EVENT_WINDOW_ACTIVE"/>
+	<value value="1" name="VGT_SQ_SEND"/>
+	<value value="2" name="VGT_SQ_STALLED"/>
+	<value value="3" name="VGT_SQ_STARVED_BUSY"/>
+	<value value="4" name="VGT_SQ_STARVED_IDLE"/>
+	<value value="5" name="VGT_SQ_STATIC"/>
+	<value value="6" name="VGT_PA_EVENT_WINDOW_ACTIVE"/>
+	<value value="7" name="VGT_PA_CLIP_V_SEND"/>
+	<value value="8" name="VGT_PA_CLIP_V_STALLED"/>
+	<value value="9" name="VGT_PA_CLIP_V_STARVED_BUSY"/>
+	<value value="10" name="VGT_PA_CLIP_V_STARVED_IDLE"/>
+	<value value="11" name="VGT_PA_CLIP_V_STATIC"/>
+	<value value="12" name="VGT_PA_CLIP_P_SEND"/>
+	<value value="13" name="VGT_PA_CLIP_P_STALLED"/>
+	<value value="14" name="VGT_PA_CLIP_P_STARVED_BUSY"/>
+	<value value="15" name="VGT_PA_CLIP_P_STARVED_IDLE"/>
+	<value value="16" name="VGT_PA_CLIP_P_STATIC"/>
+	<value value="17" name="VGT_PA_CLIP_S_SEND"/>
+	<value value="18" name="VGT_PA_CLIP_S_STALLED"/>
+	<value value="19" name="VGT_PA_CLIP_S_STARVED_BUSY"/>
+	<value value="20" name="VGT_PA_CLIP_S_STARVED_IDLE"/>
+	<value value="21" name="VGT_PA_CLIP_S_STATIC"/>
+	<value value="22" name="RBIU_FIFOS_EVENT_WINDOW_ACTIVE"/>
+	<value value="23" name="RBIU_IMMED_DATA_FIFO_STARVED"/>
+	<value value="24" name="RBIU_IMMED_DATA_FIFO_STALLED"/>
+	<value value="25" name="RBIU_DMA_REQUEST_FIFO_STARVED"/>
+	<value value="26" name="RBIU_DMA_REQUEST_FIFO_STALLED"/>
+	<value value="27" name="RBIU_DRAW_INITIATOR_FIFO_STARVED"/>
+	<value value="28" name="RBIU_DRAW_INITIATOR_FIFO_STALLED"/>
+	<value value="29" name="BIN_PRIM_NEAR_CULL"/>
+	<value value="30" name="BIN_PRIM_ZERO_CULL"/>
+	<value value="31" name="BIN_PRIM_FAR_CULL"/>
+	<value value="32" name="BIN_PRIM_BIN_CULL"/>
+	<value value="33" name="BIN_PRIM_FACE_CULL"/>
+	<value value="34" name="SPARE34"/>
+	<value value="35" name="SPARE35"/>
+	<value value="36" name="SPARE36"/>
+	<value value="37" name="SPARE37"/>
+	<value value="38" name="SPARE38"/>
+	<value value="39" name="SPARE39"/>
+	<value value="40" name="TE_SU_IN_VALID"/>
+	<value value="41" name="TE_SU_IN_READ"/>
+	<value value="42" name="TE_SU_IN_PRIM"/>
+	<value value="43" name="TE_SU_IN_EOP"/>
+	<value value="44" name="TE_SU_IN_NULL_PRIM"/>
+	<value value="45" name="TE_WK_IN_VALID"/>
+	<value value="46" name="TE_WK_IN_READ"/>
+	<value value="47" name="TE_OUT_PRIM_VALID"/>
+	<value value="48" name="TE_OUT_PRIM_READ"/>
+</enum>
+
+<enum name="a2xx_tcr_perfcount_select">
+	<value value="0" name="DGMMPD_IPMUX0_STALL"/>
+	<value value="4" name="DGMMPD_IPMUX_ALL_STALL"/>
+	<value value="5" name="OPMUX0_L2_WRITES"/>
+</enum>
+
+<enum name="a2xx_tp_perfcount_select">
+	<value value="0" name="POINT_QUADS"/>
+	<value value="1" name="BILIN_QUADS"/>
+	<value value="2" name="ANISO_QUADS"/>
+	<value value="3" name="MIP_QUADS"/>
+	<value value="4" name="VOL_QUADS"/>
+	<value value="5" name="MIP_VOL_QUADS"/>
+	<value value="6" name="MIP_ANISO_QUADS"/>
+	<value value="7" name="VOL_ANISO_QUADS"/>
+	<value value="8" name="ANISO_2_1_QUADS"/>
+	<value value="9" name="ANISO_4_1_QUADS"/>
+	<value value="10" name="ANISO_6_1_QUADS"/>
+	<value value="11" name="ANISO_8_1_QUADS"/>
+	<value value="12" name="ANISO_10_1_QUADS"/>
+	<value value="13" name="ANISO_12_1_QUADS"/>
+	<value value="14" name="ANISO_14_1_QUADS"/>
+	<value value="15" name="ANISO_16_1_QUADS"/>
+	<value value="16" name="MIP_VOL_ANISO_QUADS"/>
+	<value value="17" name="ALIGN_2_QUADS"/>
+	<value value="18" name="ALIGN_4_QUADS"/>
+	<value value="19" name="PIX_0_QUAD"/>
+	<value value="20" name="PIX_1_QUAD"/>
+	<value value="21" name="PIX_2_QUAD"/>
+	<value value="22" name="PIX_3_QUAD"/>
+	<value value="23" name="PIX_4_QUAD"/>
+	<value value="24" name="TP_MIPMAP_LOD0"/>
+	<value value="25" name="TP_MIPMAP_LOD1"/>
+	<value value="26" name="TP_MIPMAP_LOD2"/>
+	<value value="27" name="TP_MIPMAP_LOD3"/>
+	<value value="28" name="TP_MIPMAP_LOD4"/>
+	<value value="29" name="TP_MIPMAP_LOD5"/>
+	<value value="30" name="TP_MIPMAP_LOD6"/>
+	<value value="31" name="TP_MIPMAP_LOD7"/>
+	<value value="32" name="TP_MIPMAP_LOD8"/>
+	<value value="33" name="TP_MIPMAP_LOD9"/>
+	<value value="34" name="TP_MIPMAP_LOD10"/>
+	<value value="35" name="TP_MIPMAP_LOD11"/>
+	<value value="36" name="TP_MIPMAP_LOD12"/>
+	<value value="37" name="TP_MIPMAP_LOD13"/>
+	<value value="38" name="TP_MIPMAP_LOD14"/>
+</enum>
+
+<enum name="a2xx_tcm_perfcount_select">
+	<value value="0" name="QUAD0_RD_LAT_FIFO_EMPTY"/>
+	<value value="3" name="QUAD0_RD_LAT_FIFO_4TH_FULL"/>
+	<value value="4" name="QUAD0_RD_LAT_FIFO_HALF_FULL"/>
+	<value value="5" name="QUAD0_RD_LAT_FIFO_FULL"/>
+	<value value="6" name="QUAD0_RD_LAT_FIFO_LT_4TH_FULL"/>
+	<value value="28" name="READ_STARVED_QUAD0"/>
+	<value value="32" name="READ_STARVED"/>
+	<value value="33" name="READ_STALLED_QUAD0"/>
+	<value value="37" name="READ_STALLED"/>
+	<value value="38" name="VALID_READ_QUAD0"/>
+	<value value="42" name="TC_TP_STARVED_QUAD0"/>
+	<value value="46" name="TC_TP_STARVED"/>
+</enum>
+
+<enum name="a2xx_tcf_perfcount_select">
+	<value value="0" name="VALID_CYCLES"/>
+	<value value="1" name="SINGLE_PHASES"/>
+	<value value="2" name="ANISO_PHASES"/>
+	<value value="3" name="MIP_PHASES"/>
+	<value value="4" name="VOL_PHASES"/>
+	<value value="5" name="MIP_VOL_PHASES"/>
+	<value value="6" name="MIP_ANISO_PHASES"/>
+	<value value="7" name="VOL_ANISO_PHASES"/>
+	<value value="8" name="ANISO_2_1_PHASES"/>
+	<value value="9" name="ANISO_4_1_PHASES"/>
+	<value value="10" name="ANISO_6_1_PHASES"/>
+	<value value="11" name="ANISO_8_1_PHASES"/>
+	<value value="12" name="ANISO_10_1_PHASES"/>
+	<value value="13" name="ANISO_12_1_PHASES"/>
+	<value value="14" name="ANISO_14_1_PHASES"/>
+	<value value="15" name="ANISO_16_1_PHASES"/>
+	<value value="16" name="MIP_VOL_ANISO_PHASES"/>
+	<value value="17" name="ALIGN_2_PHASES"/>
+	<value value="18" name="ALIGN_4_PHASES"/>
+	<value value="19" name="TPC_BUSY"/>
+	<value value="20" name="TPC_STALLED"/>
+	<value value="21" name="TPC_STARVED"/>
+	<value value="22" name="TPC_WORKING"/>
+	<value value="23" name="TPC_WALKER_BUSY"/>
+	<value value="24" name="TPC_WALKER_STALLED"/>
+	<value value="25" name="TPC_WALKER_WORKING"/>
+	<value value="26" name="TPC_ALIGNER_BUSY"/>
+	<value value="27" name="TPC_ALIGNER_STALLED"/>
+	<value value="28" name="TPC_ALIGNER_STALLED_BY_BLEND"/>
+	<value value="29" name="TPC_ALIGNER_STALLED_BY_CACHE"/>
+	<value value="30" name="TPC_ALIGNER_WORKING"/>
+	<value value="31" name="TPC_BLEND_BUSY"/>
+	<value value="32" name="TPC_BLEND_SYNC"/>
+	<value value="33" name="TPC_BLEND_STARVED"/>
+	<value value="34" name="TPC_BLEND_WORKING"/>
+	<value value="35" name="OPCODE_0x00"/>
+	<value value="36" name="OPCODE_0x01"/>
+	<value value="37" name="OPCODE_0x04"/>
+	<value value="38" name="OPCODE_0x10"/>
+	<value value="39" name="OPCODE_0x11"/>
+	<value value="40" name="OPCODE_0x12"/>
+	<value value="41" name="OPCODE_0x13"/>
+	<value value="42" name="OPCODE_0x18"/>
+	<value value="43" name="OPCODE_0x19"/>
+	<value value="44" name="OPCODE_0x1A"/>
+	<value value="45" name="OPCODE_OTHER"/>
+	<value value="56" name="IN_FIFO_0_EMPTY"/>
+	<value value="57" name="IN_FIFO_0_LT_HALF_FULL"/>
+	<value value="58" name="IN_FIFO_0_HALF_FULL"/>
+	<value value="59" name="IN_FIFO_0_FULL"/>
+	<value value="72" name="IN_FIFO_TPC_EMPTY"/>
+	<value value="73" name="IN_FIFO_TPC_LT_HALF_FULL"/>
+	<value value="74" name="IN_FIFO_TPC_HALF_FULL"/>
+	<value value="75" name="IN_FIFO_TPC_FULL"/>
+	<value value="76" name="TPC_TC_XFC"/>
+	<value value="77" name="TPC_TC_STATE"/>
+	<value value="78" name="TC_STALL"/>
+	<value value="79" name="QUAD0_TAPS"/>
+	<value value="83" name="QUADS"/>
+	<value value="84" name="TCA_SYNC_STALL"/>
+	<value value="85" name="TAG_STALL"/>
+	<value value="88" name="TCB_SYNC_STALL"/>
+	<value value="89" name="TCA_VALID"/>
+	<value value="90" name="PROBES_VALID"/>
+	<value value="91" name="MISS_STALL"/>
+	<value value="92" name="FETCH_FIFO_STALL"/>
+	<value value="93" name="TCO_STALL"/>
+	<value value="94" name="ANY_STALL"/>
+	<value value="95" name="TAG_MISSES"/>
+	<value value="96" name="TAG_HITS"/>
+	<value value="97" name="SUB_TAG_MISSES"/>
+	<value value="98" name="SET0_INVALIDATES"/>
+	<value value="99" name="SET1_INVALIDATES"/>
+	<value value="100" name="SET2_INVALIDATES"/>
+	<value value="101" name="SET3_INVALIDATES"/>
+	<value value="102" name="SET0_TAG_MISSES"/>
+	<value value="103" name="SET1_TAG_MISSES"/>
+	<value value="104" name="SET2_TAG_MISSES"/>
+	<value value="105" name="SET3_TAG_MISSES"/>
+	<value value="106" name="SET0_TAG_HITS"/>
+	<value value="107" name="SET1_TAG_HITS"/>
+	<value value="108" name="SET2_TAG_HITS"/>
+	<value value="109" name="SET3_TAG_HITS"/>
+	<value value="110" name="SET0_SUB_TAG_MISSES"/>
+	<value value="111" name="SET1_SUB_TAG_MISSES"/>
+	<value value="112" name="SET2_SUB_TAG_MISSES"/>
+	<value value="113" name="SET3_SUB_TAG_MISSES"/>
+	<value value="114" name="SET0_EVICT1"/>
+	<value value="115" name="SET0_EVICT2"/>
+	<value value="116" name="SET0_EVICT3"/>
+	<value value="117" name="SET0_EVICT4"/>
+	<value value="118" name="SET0_EVICT5"/>
+	<value value="119" name="SET0_EVICT6"/>
+	<value value="120" name="SET0_EVICT7"/>
+	<value value="121" name="SET0_EVICT8"/>
+	<value value="130" name="SET1_EVICT1"/>
+	<value value="131" name="SET1_EVICT2"/>
+	<value value="132" name="SET1_EVICT3"/>
+	<value value="133" name="SET1_EVICT4"/>
+	<value value="134" name="SET1_EVICT5"/>
+	<value value="135" name="SET1_EVICT6"/>
+	<value value="136" name="SET1_EVICT7"/>
+	<value value="137" name="SET1_EVICT8"/>
+	<value value="146" name="SET2_EVICT1"/>
+	<value value="147" name="SET2_EVICT2"/>
+	<value value="148" name="SET2_EVICT3"/>
+	<value value="149" name="SET2_EVICT4"/>
+	<value value="150" name="SET2_EVICT5"/>
+	<value value="151" name="SET2_EVICT6"/>
+	<value value="152" name="SET2_EVICT7"/>
+	<value value="153" name="SET2_EVICT8"/>
+	<value value="162" name="SET3_EVICT1"/>
+	<value value="163" name="SET3_EVICT2"/>
+	<value value="164" name="SET3_EVICT3"/>
+	<value value="165" name="SET3_EVICT4"/>
+	<value value="166" name="SET3_EVICT5"/>
+	<value value="167" name="SET3_EVICT6"/>
+	<value value="168" name="SET3_EVICT7"/>
+	<value value="169" name="SET3_EVICT8"/>
+	<value value="178" name="FF_EMPTY"/>
+	<value value="179" name="FF_LT_HALF_FULL"/>
+	<value value="180" name="FF_HALF_FULL"/>
+	<value value="181" name="FF_FULL"/>
+	<value value="182" name="FF_XFC"/>
+	<value value="183" name="FF_STALLED"/>
+	<value value="184" name="FG_MASKS"/>
+	<value value="185" name="FG_LEFT_MASKS"/>
+	<value value="186" name="FG_LEFT_MASK_STALLED"/>
+	<value value="187" name="FG_LEFT_NOT_DONE_STALL"/>
+	<value value="188" name="FG_LEFT_FG_STALL"/>
+	<value value="189" name="FG_LEFT_SECTORS"/>
+	<value value="195" name="FG0_REQUESTS"/>
+	<value value="196" name="FG0_STALLED"/>
+	<value value="199" name="MEM_REQ512"/>
+	<value value="200" name="MEM_REQ_SENT"/>
+	<value value="202" name="MEM_LOCAL_READ_REQ"/>
+	<value value="203" name="TC0_MH_STALLED"/>
+</enum>
+
+<enum name="a2xx_sq_perfcnt_select">
+	<value value="0" name="SQ_PIXEL_VECTORS_SUB"/>
+	<value value="1" name="SQ_VERTEX_VECTORS_SUB"/>
+	<value value="2" name="SQ_ALU0_ACTIVE_VTX_SIMD0"/>
+	<value value="3" name="SQ_ALU1_ACTIVE_VTX_SIMD0"/>
+	<value value="4" name="SQ_ALU0_ACTIVE_PIX_SIMD0"/>
+	<value value="5" name="SQ_ALU1_ACTIVE_PIX_SIMD0"/>
+	<value value="6" name="SQ_ALU0_ACTIVE_VTX_SIMD1"/>
+	<value value="7" name="SQ_ALU1_ACTIVE_VTX_SIMD1"/>
+	<value value="8" name="SQ_ALU0_ACTIVE_PIX_SIMD1"/>
+	<value value="9" name="SQ_ALU1_ACTIVE_PIX_SIMD1"/>
+	<value value="10" name="SQ_EXPORT_CYCLES"/>
+	<value value="11" name="SQ_ALU_CST_WRITTEN"/>
+	<value value="12" name="SQ_TEX_CST_WRITTEN"/>
+	<value value="13" name="SQ_ALU_CST_STALL"/>
+	<value value="14" name="SQ_ALU_TEX_STALL"/>
+	<value value="15" name="SQ_INST_WRITTEN"/>
+	<value value="16" name="SQ_BOOLEAN_WRITTEN"/>
+	<value value="17" name="SQ_LOOPS_WRITTEN"/>
+	<value value="18" name="SQ_PIXEL_SWAP_IN"/>
+	<value value="19" name="SQ_PIXEL_SWAP_OUT"/>
+	<value value="20" name="SQ_VERTEX_SWAP_IN"/>
+	<value value="21" name="SQ_VERTEX_SWAP_OUT"/>
+	<value value="22" name="SQ_ALU_VTX_INST_ISSUED"/>
+	<value value="23" name="SQ_TEX_VTX_INST_ISSUED"/>
+	<value value="24" name="SQ_VC_VTX_INST_ISSUED"/>
+	<value value="25" name="SQ_CF_VTX_INST_ISSUED"/>
+	<value value="26" name="SQ_ALU_PIX_INST_ISSUED"/>
+	<value value="27" name="SQ_TEX_PIX_INST_ISSUED"/>
+	<value value="28" name="SQ_VC_PIX_INST_ISSUED"/>
+	<value value="29" name="SQ_CF_PIX_INST_ISSUED"/>
+	<value value="30" name="SQ_ALU0_FIFO_EMPTY_SIMD0"/>
+	<value value="31" name="SQ_ALU1_FIFO_EMPTY_SIMD0"/>
+	<value value="32" name="SQ_ALU0_FIFO_EMPTY_SIMD1"/>
+	<value value="33" name="SQ_ALU1_FIFO_EMPTY_SIMD1"/>
+	<value value="34" name="SQ_ALU_NOPS"/>
+	<value value="35" name="SQ_PRED_SKIP"/>
+	<value value="36" name="SQ_SYNC_ALU_STALL_SIMD0_VTX"/>
+	<value value="37" name="SQ_SYNC_ALU_STALL_SIMD1_VTX"/>
+	<value value="38" name="SQ_SYNC_TEX_STALL_VTX"/>
+	<value value="39" name="SQ_SYNC_VC_STALL_VTX"/>
+	<value value="40" name="SQ_CONSTANTS_USED_SIMD0"/>
+	<value value="41" name="SQ_CONSTANTS_SENT_SP_SIMD0"/>
+	<value value="42" name="SQ_GPR_STALL_VTX"/>
+	<value value="43" name="SQ_GPR_STALL_PIX"/>
+	<value value="44" name="SQ_VTX_RS_STALL"/>
+	<value value="45" name="SQ_PIX_RS_STALL"/>
+	<value value="46" name="SQ_SX_PC_FULL"/>
+	<value value="47" name="SQ_SX_EXP_BUFF_FULL"/>
+	<value value="48" name="SQ_SX_POS_BUFF_FULL"/>
+	<value value="49" name="SQ_INTERP_QUADS"/>
+	<value value="50" name="SQ_INTERP_ACTIVE"/>
+	<value value="51" name="SQ_IN_PIXEL_STALL"/>
+	<value value="52" name="SQ_IN_VTX_STALL"/>
+	<value value="53" name="SQ_VTX_CNT"/>
+	<value value="54" name="SQ_VTX_VECTOR2"/>
+	<value value="55" name="SQ_VTX_VECTOR3"/>
+	<value value="56" name="SQ_VTX_VECTOR4"/>
+	<value value="57" name="SQ_PIXEL_VECTOR1"/>
+	<value value="58" name="SQ_PIXEL_VECTOR23"/>
+	<value value="59" name="SQ_PIXEL_VECTOR4"/>
+	<value value="60" name="SQ_CONSTANTS_USED_SIMD1"/>
+	<value value="61" name="SQ_CONSTANTS_SENT_SP_SIMD1"/>
+	<value value="62" name="SQ_SX_MEM_EXP_FULL"/>
+	<value value="63" name="SQ_ALU0_ACTIVE_VTX_SIMD2"/>
+	<value value="64" name="SQ_ALU1_ACTIVE_VTX_SIMD2"/>
+	<value value="65" name="SQ_ALU0_ACTIVE_PIX_SIMD2"/>
+	<value value="66" name="SQ_ALU1_ACTIVE_PIX_SIMD2"/>
+	<value value="67" name="SQ_ALU0_ACTIVE_VTX_SIMD3"/>
+	<value value="68" name="SQ_PERFCOUNT_VTX_QUAL_TP_DONE"/>
+	<value value="69" name="SQ_ALU0_ACTIVE_PIX_SIMD3"/>
+	<value value="70" name="SQ_PERFCOUNT_PIX_QUAL_TP_DONE"/>
+	<value value="71" name="SQ_ALU0_FIFO_EMPTY_SIMD2"/>
+	<value value="72" name="SQ_ALU1_FIFO_EMPTY_SIMD2"/>
+	<value value="73" name="SQ_ALU0_FIFO_EMPTY_SIMD3"/>
+	<value value="74" name="SQ_ALU1_FIFO_EMPTY_SIMD3"/>
+	<value value="75" name="SQ_SYNC_ALU_STALL_SIMD2_VTX"/>
+	<value value="76" name="SQ_PERFCOUNT_VTX_POP_THREAD"/>
+	<value value="77" name="SQ_SYNC_ALU_STALL_SIMD0_PIX"/>
+	<value value="78" name="SQ_SYNC_ALU_STALL_SIMD1_PIX"/>
+	<value value="79" name="SQ_SYNC_ALU_STALL_SIMD2_PIX"/>
+	<value value="80" name="SQ_PERFCOUNT_PIX_POP_THREAD"/>
+	<value value="81" name="SQ_SYNC_TEX_STALL_PIX"/>
+	<value value="82" name="SQ_SYNC_VC_STALL_PIX"/>
+	<value value="83" name="SQ_CONSTANTS_USED_SIMD2"/>
+	<value value="84" name="SQ_CONSTANTS_SENT_SP_SIMD2"/>
+	<value value="85" name="SQ_PERFCOUNT_VTX_DEALLOC_ACK"/>
+	<value value="86" name="SQ_PERFCOUNT_PIX_DEALLOC_ACK"/>
+	<value value="87" name="SQ_ALU0_FIFO_FULL_SIMD0"/>
+	<value value="88" name="SQ_ALU1_FIFO_FULL_SIMD0"/>
+	<value value="89" name="SQ_ALU0_FIFO_FULL_SIMD1"/>
+	<value value="90" name="SQ_ALU1_FIFO_FULL_SIMD1"/>
+	<value value="91" name="SQ_ALU0_FIFO_FULL_SIMD2"/>
+	<value value="92" name="SQ_ALU1_FIFO_FULL_SIMD2"/>
+	<value value="93" name="SQ_ALU0_FIFO_FULL_SIMD3"/>
+	<value value="94" name="SQ_ALU1_FIFO_FULL_SIMD3"/>
+	<value value="95" name="VC_PERF_STATIC"/>
+	<value value="96" name="VC_PERF_STALLED"/>
+	<value value="97" name="VC_PERF_STARVED"/>
+	<value value="98" name="VC_PERF_SEND"/>
+	<value value="99" name="VC_PERF_ACTUAL_STARVED"/>
+	<value value="100" name="PIXEL_THREAD_0_ACTIVE"/>
+	<value value="101" name="VERTEX_THREAD_0_ACTIVE"/>
+	<value value="102" name="PIXEL_THREAD_0_NUMBER"/>
+	<value value="103" name="VERTEX_THREAD_0_NUMBER"/>
+	<value value="104" name="VERTEX_EVENT_NUMBER"/>
+	<value value="105" name="PIXEL_EVENT_NUMBER"/>
+	<value value="106" name="PTRBUFF_EF_PUSH"/>
+	<value value="107" name="PTRBUFF_EF_POP_EVENT"/>
+	<value value="108" name="PTRBUFF_EF_POP_NEW_VTX"/>
+	<value value="109" name="PTRBUFF_EF_POP_DEALLOC"/>
+	<value value="110" name="PTRBUFF_EF_POP_PVECTOR"/>
+	<value value="111" name="PTRBUFF_EF_POP_PVECTOR_X"/>
+	<value value="112" name="PTRBUFF_EF_POP_PVECTOR_VNZ"/>
+	<value value="113" name="PTRBUFF_PB_DEALLOC"/>
+	<value value="114" name="PTRBUFF_PI_STATE_PPB_POP"/>
+	<value value="115" name="PTRBUFF_PI_RTR"/>
+	<value value="116" name="PTRBUFF_PI_READ_EN"/>
+	<value value="117" name="PTRBUFF_PI_BUFF_SWAP"/>
+	<value value="118" name="PTRBUFF_SQ_FREE_BUFF"/>
+	<value value="119" name="PTRBUFF_SQ_DEC"/>
+	<value value="120" name="PTRBUFF_SC_VALID_CNTL_EVENT"/>
+	<value value="121" name="PTRBUFF_SC_VALID_IJ_XFER"/>
+	<value value="122" name="PTRBUFF_SC_NEW_VECTOR_1_Q"/>
+	<value value="123" name="PTRBUFF_QUAL_NEW_VECTOR"/>
+	<value value="124" name="PTRBUFF_QUAL_EVENT"/>
+	<value value="125" name="PTRBUFF_END_BUFFER"/>
+	<value value="126" name="PTRBUFF_FILL_QUAD"/>
+	<value value="127" name="VERTS_WRITTEN_SPI"/>
+	<value value="128" name="TP_FETCH_INSTR_EXEC"/>
+	<value value="129" name="TP_FETCH_INSTR_REQ"/>
+	<value value="130" name="TP_DATA_RETURN"/>
+	<value value="131" name="SPI_WRITE_CYCLES_SP"/>
+	<value value="132" name="SPI_WRITES_SP"/>
+	<value value="133" name="SP_ALU_INSTR_EXEC"/>
+	<value value="134" name="SP_CONST_ADDR_TO_SQ"/>
+	<value value="135" name="SP_PRED_KILLS_TO_SQ"/>
+	<value value="136" name="SP_EXPORT_CYCLES_TO_SX"/>
+	<value value="137" name="SP_EXPORTS_TO_SX"/>
+	<value value="138" name="SQ_CYCLES_ELAPSED"/>
+	<value value="139" name="SQ_TCFS_OPT_ALLOC_EXEC"/>
+	<value value="140" name="SQ_TCFS_NO_OPT_ALLOC"/>
+	<value value="141" name="SQ_ALU0_NO_OPT_ALLOC"/>
+	<value value="142" name="SQ_ALU1_NO_OPT_ALLOC"/>
+	<value value="143" name="SQ_TCFS_ARB_XFC_CNT"/>
+	<value value="144" name="SQ_ALU0_ARB_XFC_CNT"/>
+	<value value="145" name="SQ_ALU1_ARB_XFC_CNT"/>
+	<value value="146" name="SQ_TCFS_CFS_UPDATE_CNT"/>
+	<value value="147" name="SQ_ALU0_CFS_UPDATE_CNT"/>
+	<value value="148" name="SQ_ALU1_CFS_UPDATE_CNT"/>
+	<value value="149" name="SQ_VTX_PUSH_THREAD_CNT"/>
+	<value value="150" name="SQ_VTX_POP_THREAD_CNT"/>
+	<value value="151" name="SQ_PIX_PUSH_THREAD_CNT"/>
+	<value value="152" name="SQ_PIX_POP_THREAD_CNT"/>
+	<value value="153" name="SQ_PIX_TOTAL"/>
+	<value value="154" name="SQ_PIX_KILLED"/>
+</enum>
+
+<enum name="a2xx_sx_perfcnt_select">
+	<value value="0" name="SX_EXPORT_VECTORS"/>
+	<value value="1" name="SX_DUMMY_QUADS"/>
+	<value value="2" name="SX_ALPHA_FAIL"/>
+	<value value="3" name="SX_RB_QUAD_BUSY"/>
+	<value value="4" name="SX_RB_COLOR_BUSY"/>
+	<value value="5" name="SX_RB_QUAD_STALL"/>
+	<value value="6" name="SX_RB_COLOR_STALL"/>
+</enum>
+
+<enum name="a2xx_rbbm_perfcount1_sel">
+	<value value="0" name="RBBM1_COUNT"/>
+	<value value="1" name="RBBM1_NRT_BUSY"/>
+	<value value="2" name="RBBM1_RB_BUSY"/>
+	<value value="3" name="RBBM1_SQ_CNTX0_BUSY"/>
+	<value value="4" name="RBBM1_SQ_CNTX17_BUSY"/>
+	<value value="5" name="RBBM1_VGT_BUSY"/>
+	<value value="6" name="RBBM1_VGT_NODMA_BUSY"/>
+	<value value="7" name="RBBM1_PA_BUSY"/>
+	<value value="8" name="RBBM1_SC_CNTX_BUSY"/>
+	<value value="9" name="RBBM1_TPC_BUSY"/>
+	<value value="10" name="RBBM1_TC_BUSY"/>
+	<value value="11" name="RBBM1_SX_BUSY"/>
+	<value value="12" name="RBBM1_CP_COHER_BUSY"/>
+	<value value="13" name="RBBM1_CP_NRT_BUSY"/>
+	<value value="14" name="RBBM1_GFX_IDLE_STALL"/>
+	<value value="15" name="RBBM1_INTERRUPT"/>
+</enum>
+
+<enum name="a2xx_cp_perfcount_sel">
+	<value value="0" name="ALWAYS_COUNT"/>
+	<value value="1" name="TRANS_FIFO_FULL"/>
+	<value value="2" name="TRANS_FIFO_AF"/>
+	<value value="3" name="RCIU_PFPTRANS_WAIT"/>
+	<value value="6" name="RCIU_NRTTRANS_WAIT"/>
+	<value value="8" name="CSF_NRT_READ_WAIT"/>
+	<value value="9" name="CSF_I1_FIFO_FULL"/>
+	<value value="10" name="CSF_I2_FIFO_FULL"/>
+	<value value="11" name="CSF_ST_FIFO_FULL"/>
+	<value value="13" name="CSF_RING_ROQ_FULL"/>
+	<value value="14" name="CSF_I1_ROQ_FULL"/>
+	<value value="15" name="CSF_I2_ROQ_FULL"/>
+	<value value="16" name="CSF_ST_ROQ_FULL"/>
+	<value value="18" name="MIU_TAG_MEM_FULL"/>
+	<value value="19" name="MIU_WRITECLEAN"/>
+	<value value="22" name="MIU_NRT_WRITE_STALLED"/>
+	<value value="23" name="MIU_NRT_READ_STALLED"/>
+	<value value="24" name="ME_WRITE_CONFIRM_FIFO_FULL"/>
+	<value value="25" name="ME_VS_DEALLOC_FIFO_FULL"/>
+	<value value="26" name="ME_PS_DEALLOC_FIFO_FULL"/>
+	<value value="27" name="ME_REGS_VS_EVENT_FIFO_FULL"/>
+	<value value="28" name="ME_REGS_PS_EVENT_FIFO_FULL"/>
+	<value value="29" name="ME_REGS_CF_EVENT_FIFO_FULL"/>
+	<value value="30" name="ME_MICRO_RB_STARVED"/>
+	<value value="31" name="ME_MICRO_I1_STARVED"/>
+	<value value="32" name="ME_MICRO_I2_STARVED"/>
+	<value value="33" name="ME_MICRO_ST_STARVED"/>
+	<value value="40" name="RCIU_RBBM_DWORD_SENT"/>
+	<value value="41" name="ME_BUSY_CLOCKS"/>
+	<value value="42" name="ME_WAIT_CONTEXT_AVAIL"/>
+	<value value="43" name="PFP_TYPE0_PACKET"/>
+	<value value="44" name="PFP_TYPE3_PACKET"/>
+	<value value="45" name="CSF_RB_WPTR_NEQ_RPTR"/>
+	<value value="46" name="CSF_I1_SIZE_NEQ_ZERO"/>
+	<value value="47" name="CSF_I2_SIZE_NEQ_ZERO"/>
+	<value value="48" name="CSF_RBI1I2_FETCHING"/>
+</enum>
+
+<enum name="a2xx_rb_perfcnt_select">
+	<value value="0" name="RBPERF_CNTX_BUSY"/>
+	<value value="1" name="RBPERF_CNTX_BUSY_MAX"/>
+	<value value="2" name="RBPERF_SX_QUAD_STARVED"/>
+	<value value="3" name="RBPERF_SX_QUAD_STARVED_MAX"/>
+	<value value="4" name="RBPERF_GA_GC_CH0_SYS_REQ"/>
+	<value value="5" name="RBPERF_GA_GC_CH0_SYS_REQ_MAX"/>
+	<value value="6" name="RBPERF_GA_GC_CH1_SYS_REQ"/>
+	<value value="7" name="RBPERF_GA_GC_CH1_SYS_REQ_MAX"/>
+	<value value="8" name="RBPERF_MH_STARVED"/>
+	<value value="9" name="RBPERF_MH_STARVED_MAX"/>
+	<value value="10" name="RBPERF_AZ_BC_COLOR_BUSY"/>
+	<value value="11" name="RBPERF_AZ_BC_COLOR_BUSY_MAX"/>
+	<value value="12" name="RBPERF_AZ_BC_Z_BUSY"/>
+	<value value="13" name="RBPERF_AZ_BC_Z_BUSY_MAX"/>
+	<value value="14" name="RBPERF_RB_SC_TILE_RTR_N"/>
+	<value value="15" name="RBPERF_RB_SC_TILE_RTR_N_MAX"/>
+	<value value="16" name="RBPERF_RB_SC_SAMP_RTR_N"/>
+	<value value="17" name="RBPERF_RB_SC_SAMP_RTR_N_MAX"/>
+	<value value="18" name="RBPERF_RB_SX_QUAD_RTR_N"/>
+	<value value="19" name="RBPERF_RB_SX_QUAD_RTR_N_MAX"/>
+	<value value="20" name="RBPERF_RB_SX_COLOR_RTR_N"/>
+	<value value="21" name="RBPERF_RB_SX_COLOR_RTR_N_MAX"/>
+	<value value="22" name="RBPERF_RB_SC_SAMP_LZ_BUSY"/>
+	<value value="23" name="RBPERF_RB_SC_SAMP_LZ_BUSY_MAX"/>
+	<value value="24" name="RBPERF_ZXP_STALL"/>
+	<value value="25" name="RBPERF_ZXP_STALL_MAX"/>
+	<value value="26" name="RBPERF_EVENT_PENDING"/>
+	<value value="27" name="RBPERF_EVENT_PENDING_MAX"/>
+	<value value="28" name="RBPERF_RB_MH_VALID"/>
+	<value value="29" name="RBPERF_RB_MH_VALID_MAX"/>
+	<value value="30" name="RBPERF_SX_RB_QUAD_SEND"/>
+	<value value="31" name="RBPERF_SX_RB_COLOR_SEND"/>
+	<value value="32" name="RBPERF_SC_RB_TILE_SEND"/>
+	<value value="33" name="RBPERF_SC_RB_SAMPLE_SEND"/>
+	<value value="34" name="RBPERF_SX_RB_MEM_EXPORT"/>
+	<value value="35" name="RBPERF_SX_RB_QUAD_EVENT"/>
+	<value value="36" name="RBPERF_SC_RB_TILE_EVENT_FILTERED"/>
+	<value value="37" name="RBPERF_SC_RB_TILE_EVENT_ALL"/>
+	<value value="38" name="RBPERF_RB_SC_EZ_SEND"/>
+	<value value="39" name="RBPERF_RB_SX_INDEX_SEND"/>
+	<value value="40" name="RBPERF_GMEM_INTFO_RD"/>
+	<value value="41" name="RBPERF_GMEM_INTF1_RD"/>
+	<value value="42" name="RBPERF_GMEM_INTFO_WR"/>
+	<value value="43" name="RBPERF_GMEM_INTF1_WR"/>
+	<value value="44" name="RBPERF_RB_CP_CONTEXT_DONE"/>
+	<value value="45" name="RBPERF_RB_CP_CACHE_FLUSH"/>
+	<value value="46" name="RBPERF_ZPASS_DONE"/>
+	<value value="47" name="RBPERF_ZCMD_VALID"/>
+	<value value="48" name="RBPERF_CCMD_VALID"/>
+	<value value="49" name="RBPERF_ACCUM_GRANT"/>
+	<value value="50" name="RBPERF_ACCUM_C0_GRANT"/>
+	<value value="51" name="RBPERF_ACCUM_C1_GRANT"/>
+	<value value="52" name="RBPERF_ACCUM_FULL_BE_WR"/>
+	<value value="53" name="RBPERF_ACCUM_REQUEST_NO_GRANT"/>
+	<value value="54" name="RBPERF_ACCUM_TIMEOUT_PULSE"/>
+	<value value="55" name="RBPERF_ACCUM_LIN_TIMEOUT_PULSE"/>
+	<value value="56" name="RBPERF_ACCUM_CAM_HIT_FLUSHING"/>
+</enum>
+
+<enum name="a2xx_mh_perfcnt_select">
+	<value value="0" name="CP_R0_REQUESTS"/>
+	<value value="1" name="CP_R1_REQUESTS"/>
+	<value value="2" name="CP_R2_REQUESTS"/>
+	<value value="3" name="CP_R3_REQUESTS"/>
+	<value value="4" name="CP_R4_REQUESTS"/>
+	<value value="5" name="CP_TOTAL_READ_REQUESTS"/>
+	<value value="6" name="CP_TOTAL_WRITE_REQUESTS"/>
+	<value value="7" name="CP_TOTAL_REQUESTS"/>
+	<value value="8" name="CP_DATA_BYTES_WRITTEN"/>
+	<value value="9" name="CP_WRITE_CLEAN_RESPONSES"/>
+	<value value="10" name="CP_R0_READ_BURSTS_RECEIVED"/>
+	<value value="11" name="CP_R1_READ_BURSTS_RECEIVED"/>
+	<value value="12" name="CP_R2_READ_BURSTS_RECEIVED"/>
+	<value value="13" name="CP_R3_READ_BURSTS_RECEIVED"/>
+	<value value="14" name="CP_R4_READ_BURSTS_RECEIVED"/>
+	<value value="15" name="CP_TOTAL_READ_BURSTS_RECEIVED"/>
+	<value value="16" name="CP_R0_DATA_BEATS_READ"/>
+	<value value="17" name="CP_R1_DATA_BEATS_READ"/>
+	<value value="18" name="CP_R2_DATA_BEATS_READ"/>
+	<value value="19" name="CP_R3_DATA_BEATS_READ"/>
+	<value value="20" name="CP_R4_DATA_BEATS_READ"/>
+	<value value="21" name="CP_TOTAL_DATA_BEATS_READ"/>
+	<value value="22" name="VGT_R0_REQUESTS"/>
+	<value value="23" name="VGT_R1_REQUESTS"/>
+	<value value="24" name="VGT_TOTAL_REQUESTS"/>
+	<value value="25" name="VGT_R0_READ_BURSTS_RECEIVED"/>
+	<value value="26" name="VGT_R1_READ_BURSTS_RECEIVED"/>
+	<value value="27" name="VGT_TOTAL_READ_BURSTS_RECEIVED"/>
+	<value value="28" name="VGT_R0_DATA_BEATS_READ"/>
+	<value value="29" name="VGT_R1_DATA_BEATS_READ"/>
+	<value value="30" name="VGT_TOTAL_DATA_BEATS_READ"/>
+	<value value="31" name="TC_TOTAL_REQUESTS"/>
+	<value value="32" name="TC_ROQ_REQUESTS"/>
+	<value value="33" name="TC_INFO_SENT"/>
+	<value value="34" name="TC_READ_BURSTS_RECEIVED"/>
+	<value value="35" name="TC_DATA_BEATS_READ"/>
+	<value value="36" name="TCD_BURSTS_READ"/>
+	<value value="37" name="RB_REQUESTS"/>
+	<value value="38" name="RB_DATA_BYTES_WRITTEN"/>
+	<value value="39" name="RB_WRITE_CLEAN_RESPONSES"/>
+	<value value="40" name="AXI_READ_REQUESTS_ID_0"/>
+	<value value="41" name="AXI_READ_REQUESTS_ID_1"/>
+	<value value="42" name="AXI_READ_REQUESTS_ID_2"/>
+	<value value="43" name="AXI_READ_REQUESTS_ID_3"/>
+	<value value="44" name="AXI_READ_REQUESTS_ID_4"/>
+	<value value="45" name="AXI_READ_REQUESTS_ID_5"/>
+	<value value="46" name="AXI_READ_REQUESTS_ID_6"/>
+	<value value="47" name="AXI_READ_REQUESTS_ID_7"/>
+	<value value="48" name="AXI_TOTAL_READ_REQUESTS"/>
+	<value value="49" name="AXI_WRITE_REQUESTS_ID_0"/>
+	<value value="50" name="AXI_WRITE_REQUESTS_ID_1"/>
+	<value value="51" name="AXI_WRITE_REQUESTS_ID_2"/>
+	<value value="52" name="AXI_WRITE_REQUESTS_ID_3"/>
+	<value value="53" name="AXI_WRITE_REQUESTS_ID_4"/>
+	<value value="54" name="AXI_WRITE_REQUESTS_ID_5"/>
+	<value value="55" name="AXI_WRITE_REQUESTS_ID_6"/>
+	<value value="56" name="AXI_WRITE_REQUESTS_ID_7"/>
+	<value value="57" name="AXI_TOTAL_WRITE_REQUESTS"/>
+	<value value="58" name="AXI_TOTAL_REQUESTS_ID_0"/>
+	<value value="59" name="AXI_TOTAL_REQUESTS_ID_1"/>
+	<value value="60" name="AXI_TOTAL_REQUESTS_ID_2"/>
+	<value value="61" name="AXI_TOTAL_REQUESTS_ID_3"/>
+	<value value="62" name="AXI_TOTAL_REQUESTS_ID_4"/>
+	<value value="63" name="AXI_TOTAL_REQUESTS_ID_5"/>
+	<value value="64" name="AXI_TOTAL_REQUESTS_ID_6"/>
+	<value value="65" name="AXI_TOTAL_REQUESTS_ID_7"/>
+	<value value="66" name="AXI_TOTAL_REQUESTS"/>
+	<value value="67" name="AXI_READ_CHANNEL_BURSTS_ID_0"/>
+	<value value="68" name="AXI_READ_CHANNEL_BURSTS_ID_1"/>
+	<value value="69" name="AXI_READ_CHANNEL_BURSTS_ID_2"/>
+	<value value="70" name="AXI_READ_CHANNEL_BURSTS_ID_3"/>
+	<value value="71" name="AXI_READ_CHANNEL_BURSTS_ID_4"/>
+	<value value="72" name="AXI_READ_CHANNEL_BURSTS_ID_5"/>
+	<value value="73" name="AXI_READ_CHANNEL_BURSTS_ID_6"/>
+	<value value="74" name="AXI_READ_CHANNEL_BURSTS_ID_7"/>
+	<value value="75" name="AXI_READ_CHANNEL_TOTAL_BURSTS"/>
+	<value value="76" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_0"/>
+	<value value="77" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_1"/>
+	<value value="78" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_2"/>
+	<value value="79" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_3"/>
+	<value value="80" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_4"/>
+	<value value="81" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_5"/>
+	<value value="82" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_6"/>
+	<value value="83" name="AXI_READ_CHANNEL_DATA_BEATS_READ_ID_7"/>
+	<value value="84" name="AXI_READ_CHANNEL_TOTAL_DATA_BEATS_READ"/>
+	<value value="85" name="AXI_WRITE_CHANNEL_BURSTS_ID_0"/>
+	<value value="86" name="AXI_WRITE_CHANNEL_BURSTS_ID_1"/>
+	<value value="87" name="AXI_WRITE_CHANNEL_BURSTS_ID_2"/>
+	<value value="88" name="AXI_WRITE_CHANNEL_BURSTS_ID_3"/>
+	<value value="89" name="AXI_WRITE_CHANNEL_BURSTS_ID_4"/>
+	<value value="90" name="AXI_WRITE_CHANNEL_BURSTS_ID_5"/>
+	<value value="91" name="AXI_WRITE_CHANNEL_BURSTS_ID_6"/>
+	<value value="92" name="AXI_WRITE_CHANNEL_BURSTS_ID_7"/>
+	<value value="93" name="AXI_WRITE_CHANNEL_TOTAL_BURSTS"/>
+	<value value="94" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_0"/>
+	<value value="95" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_1"/>
+	<value value="96" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_2"/>
+	<value value="97" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_3"/>
+	<value value="98" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_4"/>
+	<value value="99" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_5"/>
+	<value value="100" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_6"/>
+	<value value="101" name="AXI_WRITE_CHANNEL_DATA_BYTES_WRITTEN_ID_7"/>
+	<value value="102" name="AXI_WRITE_CHANNEL_TOTAL_DATA_BYTES_WRITTEN"/>
+	<value value="103" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_0"/>
+	<value value="104" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_1"/>
+	<value value="105" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_2"/>
+	<value value="106" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_3"/>
+	<value value="107" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_4"/>
+	<value value="108" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_5"/>
+	<value value="109" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_6"/>
+	<value value="110" name="AXI_WRITE_RESPONSE_CHANNEL_RESPONSES_ID_7"/>
+	<value value="111" name="AXI_WRITE_RESPONSE_CHANNEL_TOTAL_RESPONSES"/>
+	<value value="112" name="TOTAL_MMU_MISSES"/>
+	<value value="113" name="MMU_READ_MISSES"/>
+	<value value="114" name="MMU_WRITE_MISSES"/>
+	<value value="115" name="TOTAL_MMU_HITS"/>
+	<value value="116" name="MMU_READ_HITS"/>
+	<value value="117" name="MMU_WRITE_HITS"/>
+	<value value="118" name="SPLIT_MODE_TC_HITS"/>
+	<value value="119" name="SPLIT_MODE_TC_MISSES"/>
+	<value value="120" name="SPLIT_MODE_NON_TC_HITS"/>
+	<value value="121" name="SPLIT_MODE_NON_TC_MISSES"/>
+	<value value="122" name="STALL_AWAITING_TLB_MISS_FETCH"/>
+	<value value="123" name="MMU_TLB_MISS_READ_BURSTS_RECEIVED"/>
+	<value value="124" name="MMU_TLB_MISS_DATA_BEATS_READ"/>
+	<value value="125" name="CP_CYCLES_HELD_OFF"/>
+	<value value="126" name="VGT_CYCLES_HELD_OFF"/>
+	<value value="127" name="TC_CYCLES_HELD_OFF"/>
+	<value value="128" name="TC_ROQ_CYCLES_HELD_OFF"/>
+	<value value="129" name="TC_CYCLES_HELD_OFF_TCD_FULL"/>
+	<value value="130" name="RB_CYCLES_HELD_OFF"/>
+	<value value="131" name="TOTAL_CYCLES_ANY_CLNT_HELD_OFF"/>
+	<value value="132" name="TLB_MISS_CYCLES_HELD_OFF"/>
+	<value value="133" name="AXI_READ_REQUEST_HELD_OFF"/>
+	<value value="134" name="AXI_WRITE_REQUEST_HELD_OFF"/>
+	<value value="135" name="AXI_REQUEST_HELD_OFF"/>
+	<value value="136" name="AXI_REQUEST_HELD_OFF_INFLIGHT_LIMIT"/>
+	<value value="137" name="AXI_WRITE_DATA_HELD_OFF"/>
+	<value value="138" name="CP_SAME_PAGE_BANK_REQUESTS"/>
+	<value value="139" name="VGT_SAME_PAGE_BANK_REQUESTS"/>
+	<value value="140" name="TC_SAME_PAGE_BANK_REQUESTS"/>
+	<value value="141" name="TC_ARB_HOLD_SAME_PAGE_BANK_REQUESTS"/>
+	<value value="142" name="RB_SAME_PAGE_BANK_REQUESTS"/>
+	<value value="143" name="TOTAL_SAME_PAGE_BANK_REQUESTS"/>
+	<value value="144" name="CP_SAME_PAGE_BANK_REQUESTS_KILLED_FAIRNESS_LIMIT"/>
+	<value value="145" name="VGT_SAME_PAGE_BANK_REQUESTS_KILLED_FAIRNESS_LIMIT"/>
+	<value value="146" name="TC_SAME_PAGE_BANK_REQUESTS_KILLED_FAIRNESS_LIMIT"/>
+	<value value="147" name="RB_SAME_PAGE_BANK_REQUESTS_KILLED_FAIRNESS_LIMIT"/>
+	<value value="148" name="TOTAL_SAME_PAGE_BANK_KILLED_FAIRNESS_LIMIT"/>
+	<value value="149" name="TOTAL_MH_READ_REQUESTS"/>
+	<value value="150" name="TOTAL_MH_WRITE_REQUESTS"/>
+	<value value="151" name="TOTAL_MH_REQUESTS"/>
+	<value value="152" name="MH_BUSY"/>
+	<value value="153" name="CP_NTH_ACCESS_SAME_PAGE_BANK_SEQUENCE"/>
+	<value value="154" name="VGT_NTH_ACCESS_SAME_PAGE_BANK_SEQUENCE"/>
+	<value value="155" name="TC_NTH_ACCESS_SAME_PAGE_BANK_SEQUENCE"/>
+	<value value="156" name="RB_NTH_ACCESS_SAME_PAGE_BANK_SEQUENCE"/>
+	<value value="157" name="TC_ROQ_N_VALID_ENTRIES"/>
+	<value value="158" name="ARQ_N_ENTRIES"/>
+	<value value="159" name="WDB_N_ENTRIES"/>
+	<value value="160" name="MH_READ_LATENCY_OUTST_REQ_SUM"/>
+	<value value="161" name="MC_READ_LATENCY_OUTST_REQ_SUM"/>
+	<value value="162" name="MC_TOTAL_READ_REQUESTS"/>
+	<value value="163" name="ELAPSED_CYCLES_MH_GATED_CLK"/>
+	<value value="164" name="ELAPSED_CLK_CYCLES"/>
+	<value value="165" name="CP_W_16B_REQUESTS"/>
+	<value value="166" name="CP_W_32B_REQUESTS"/>
+	<value value="167" name="TC_16B_REQUESTS"/>
+	<value value="168" name="TC_32B_REQUESTS"/>
+	<value value="169" name="PA_REQUESTS"/>
+	<value value="170" name="PA_DATA_BYTES_WRITTEN"/>
+	<value value="171" name="PA_WRITE_CLEAN_RESPONSES"/>
+	<value value="172" name="PA_CYCLES_HELD_OFF"/>
+	<value value="173" name="AXI_READ_REQUEST_DATA_BEATS_ID_0"/>
+	<value value="174" name="AXI_READ_REQUEST_DATA_BEATS_ID_1"/>
+	<value value="175" name="AXI_READ_REQUEST_DATA_BEATS_ID_2"/>
+	<value value="176" name="AXI_READ_REQUEST_DATA_BEATS_ID_3"/>
+	<value value="177" name="AXI_READ_REQUEST_DATA_BEATS_ID_4"/>
+	<value value="178" name="AXI_READ_REQUEST_DATA_BEATS_ID_5"/>
+	<value value="179" name="AXI_READ_REQUEST_DATA_BEATS_ID_6"/>
+	<value value="180" name="AXI_READ_REQUEST_DATA_BEATS_ID_7"/>
+	<value value="181" name="AXI_TOTAL_READ_REQUEST_DATA_BEATS"/>
+</enum>
+
+<enum name="perf_mode_cnt">
+	<value name="PERF_STATE_RESET" value="0"/>
+	<value name="PERF_STATE_ENABLE" value="1"/>
+	<value name="PERF_STATE_FREEZE" value="2"/>
+</enum>
+
+<domain name="A2XX" width="32">
+
+	<bitset name="a2xx_vgt_current_bin_id_min_max" inline="yes">
+		<bitfield name="COLUMN" low="0" high="2" type="uint"/>
+		<bitfield name="ROW" low="3" high="5" type="uint"/>
+		<bitfield name="GUARD_BAND_MASK" low="6" high="8" type="uint"/>
+	</bitset>
+
+	<reg32 offset="0x0001" name="RBBM_PATCH_RELEASE"/>
+	<reg32 offset="0x003b" name="RBBM_CNTL"/>
+	<reg32 offset="0x003c" name="RBBM_SOFT_RESET"/>
+	<reg32 offset="0x00c0" name="CP_PFP_UCODE_ADDR"/>
+	<reg32 offset="0x00c1" name="CP_PFP_UCODE_DATA"/>
+
+	<enum name="adreno_mmu_clnt_beh">
+		<value name="BEH_NEVR" value="0"/>
+		<value name="BEH_TRAN_RNG" value="1"/>
+		<value name="BEH_TRAN_FLT" value="2"/>
+	</enum>
+
+	<!--
+		Note: these seem applicable only for a2xx devices with gpummu?  At
+		any rate, MH_MMU_CONFIG shows up in places in a3xx firmware where
+		it doesn't make sense, so I think offset 0x40 must be a different
+		register on a3xx.. so moving this back into A2XX domain:
+	 -->
+	<reg32 offset="0x0040" name="MH_MMU_CONFIG">
+		<bitfield name="MMU_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="SPLIT_MODE_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="RB_W_CLNT_BEHAVIOR" low="4" high="5" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="CP_W_CLNT_BEHAVIOR" low="6" high="7" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="CP_R0_CLNT_BEHAVIOR" low="8" high="9" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="CP_R1_CLNT_BEHAVIOR" low="10" high="11" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="CP_R2_CLNT_BEHAVIOR" low="12" high="13" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="CP_R3_CLNT_BEHAVIOR" low="14" high="15" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="CP_R4_CLNT_BEHAVIOR" low="16" high="17" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="VGT_R0_CLNT_BEHAVIOR" low="18" high="19" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="VGT_R1_CLNT_BEHAVIOR" low="20" high="21" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="TC_R_CLNT_BEHAVIOR" low="22" high="23" type="adreno_mmu_clnt_beh"/>
+		<bitfield name="PA_W_CLNT_BEHAVIOR" low="24" high="25" type="adreno_mmu_clnt_beh"/>
+	</reg32>
+	<reg32 offset="0x0041" name="MH_MMU_VA_RANGE">
+		<bitfield name="NUM_64KB_REGIONS" low="0" high="11" type="uint"/>
+		<bitfield name="VA_BASE" low="12" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0042" name="MH_MMU_PT_BASE"/>
+	<reg32 offset="0x0043" name="MH_MMU_PAGE_FAULT"/>
+	<reg32 offset="0x0044" name="MH_MMU_TRAN_ERROR"/>
+	<reg32 offset="0x0045" name="MH_MMU_INVALIDATE">
+		<bitfield name="INVALIDATE_ALL" pos="0" type="boolean"/>
+		<bitfield name="INVALIDATE_TC" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0046" name="MH_MMU_MPU_BASE"/>
+	<reg32 offset="0x0047" name="MH_MMU_MPU_END"/>
+
+	<reg32 offset="0x0394" name="NQWAIT_UNTIL"/>
+	<reg32 offset="0x0395" name="RBBM_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0396" name="RBBM_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0397" name="RBBM_PERFCOUNTER0_LO"/>
+	<reg32 offset="0x0398" name="RBBM_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0399" name="RBBM_PERFCOUNTER1_LO"/>
+	<reg32 offset="0x039a" name="RBBM_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x039b" name="RBBM_DEBUG"/>
+	<reg32 offset="0x039c" name="RBBM_PM_OVERRIDE1">
+		<bitfield name="RBBM_AHBCLK_PM_OVERRIDE" pos="0" type="boolean"/>
+		<bitfield name="SC_REG_SCLK_PM_OVERRIDE" pos="1" type="boolean"/>
+		<bitfield name="SC_SCLK_PM_OVERRIDE" pos="2" type="boolean"/>
+		<bitfield name="SP_TOP_SCLK_PM_OVERRIDE" pos="3" type="boolean"/>
+		<bitfield name="SP_V0_SCLK_PM_OVERRIDE" pos="4" type="boolean"/>
+		<bitfield name="SQ_REG_SCLK_PM_OVERRIDE" pos="5" type="boolean"/>
+		<bitfield name="SQ_REG_FIFOS_SCLK_PM_OVERRIDE" pos="6" type="boolean"/>
+		<bitfield name="SQ_CONST_MEM_SCLK_PM_OVERRIDE" pos="7" type="boolean"/>
+		<bitfield name="SQ_SQ_SCLK_PM_OVERRIDE" pos="8" type="boolean"/>
+		<bitfield name="SX_SCLK_PM_OVERRIDE" pos="9" type="boolean"/>
+		<bitfield name="SX_REG_SCLK_PM_OVERRIDE" pos="10" type="boolean"/>
+		<bitfield name="TCM_TCO_SCLK_PM_OVERRIDE" pos="11" type="boolean"/>
+		<bitfield name="TCM_TCM_SCLK_PM_OVERRIDE" pos="12" type="boolean"/>
+		<bitfield name="TCM_TCD_SCLK_PM_OVERRIDE" pos="13" type="boolean"/>
+		<bitfield name="TCM_REG_SCLK_PM_OVERRIDE" pos="14" type="boolean"/>
+		<bitfield name="TPC_TPC_SCLK_PM_OVERRIDE" pos="15" type="boolean"/>
+		<bitfield name="TPC_REG_SCLK_PM_OVERRIDE" pos="16" type="boolean"/>
+		<bitfield name="TCF_TCA_SCLK_PM_OVERRIDE" pos="17" type="boolean"/>
+		<bitfield name="TCF_TCB_SCLK_PM_OVERRIDE" pos="18" type="boolean"/>
+		<bitfield name="TCF_TCB_READ_SCLK_PM_OVERRIDE" pos="19" type="boolean"/>
+		<bitfield name="TP_TP_SCLK_PM_OVERRIDE" pos="20" type="boolean"/>
+		<bitfield name="TP_REG_SCLK_PM_OVERRIDE" pos="21" type="boolean"/>
+		<bitfield name="CP_G_SCLK_PM_OVERRIDE" pos="22" type="boolean"/>
+		<bitfield name="CP_REG_SCLK_PM_OVERRIDE" pos="23" type="boolean"/>
+		<bitfield name="CP_G_REG_SCLK_PM_OVERRIDE" pos="24" type="boolean"/>
+		<bitfield name="SPI_SCLK_PM_OVERRIDE" pos="25" type="boolean"/>
+		<bitfield name="RB_REG_SCLK_PM_OVERRIDE" pos="26" type="boolean"/>
+		<bitfield name="RB_SCLK_PM_OVERRIDE" pos="27" type="boolean"/>
+		<bitfield name="MH_MH_SCLK_PM_OVERRIDE" pos="28" type="boolean"/>
+		<bitfield name="MH_REG_SCLK_PM_OVERRIDE" pos="29" type="boolean"/>
+		<bitfield name="MH_MMU_SCLK_PM_OVERRIDE" pos="30" type="boolean"/>
+		<bitfield name="MH_TCROQ_SCLK_PM_OVERRIDE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x039d" name="RBBM_PM_OVERRIDE2">
+		<bitfield name="PA_REG_SCLK_PM_OVERRIDE" pos="0" type="boolean"/>
+		<bitfield name="PA_PA_SCLK_PM_OVERRIDE" pos="1" type="boolean"/>
+		<bitfield name="PA_AG_SCLK_PM_OVERRIDE" pos="2" type="boolean"/>
+		<bitfield name="VGT_REG_SCLK_PM_OVERRIDE" pos="3" type="boolean"/>
+		<bitfield name="VGT_FIFOS_SCLK_PM_OVERRIDE" pos="4" type="boolean"/>
+		<bitfield name="VGT_VGT_SCLK_PM_OVERRIDE" pos="5" type="boolean"/>
+		<bitfield name="DEBUG_PERF_SCLK_PM_OVERRIDE" pos="6" type="boolean"/>
+		<bitfield name="PERM_SCLK_PM_OVERRIDE" pos="7" type="boolean"/>
+		<bitfield name="GC_GA_GMEM0_PM_OVERRIDE" pos="8" type="boolean"/>
+		<bitfield name="GC_GA_GMEM1_PM_OVERRIDE" pos="9" type="boolean"/>
+		<bitfield name="GC_GA_GMEM2_PM_OVERRIDE" pos="10" type="boolean"/>
+		<bitfield name="GC_GA_GMEM3_PM_OVERRIDE" pos="11" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x03a0" name="RBBM_DEBUG_OUT"/>
+	<reg32 offset="0x03a1" name="RBBM_DEBUG_CNTL"/>
+	<reg32 offset="0x03b3" name="RBBM_READ_ERROR"/>
+	<reg32 offset="0x03b4" name="RBBM_INT_CNTL">
+		<bitfield name="RDERR_INT_MASK" pos="0" type="boolean"/>
+		<bitfield name="DISPLAY_UPDATE_INT_MASK" pos="1" type="boolean"/>
+		<bitfield name="GUI_IDLE_INT_MASK" pos="19" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x03b5" name="RBBM_INT_STATUS"/>
+	<reg32 offset="0x03b6" name="RBBM_INT_ACK"/>
+	<reg32 offset="0x03b7" name="MASTER_INT_SIGNAL">
+		<bitfield name="MH_INT_STAT" pos="5" type="boolean"/>
+		<bitfield name="SQ_INT_STAT" pos="26" type="boolean"/>
+		<bitfield name="CP_INT_STAT" pos="30" type="boolean"/>
+		<bitfield name="RBBM_INT_STAT" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x03f9" name="RBBM_PERIPHID1"/>
+	<reg32 offset="0x03fa" name="RBBM_PERIPHID2"/>
+	<reg32 offset="0x0444" name="CP_PERFMON_CNTL">
+		<!-- The width is uncertain -->
+		<bitfield name="PERF_MODE_CNT" low="0" high="2" type="perf_mode_cnt"/>
+	</reg32>
+	<reg32 offset="0x0445" name="CP_PERFCOUNTER_SELECT"/>
+	<reg32 offset="0x0446" name="CP_PERFCOUNTER_LO"/>
+	<reg32 offset="0x0447" name="CP_PERFCOUNTER_HI"/>
+	<reg32 offset="0x05d0" name="RBBM_STATUS">
+		<bitfield name="CMDFIFO_AVAIL" low="0" high="4" type="uint"/>
+		<bitfield name="TC_BUSY" pos="5" type="boolean"/>
+		<bitfield name="HIRQ_PENDING" pos="8" type="boolean"/>
+		<bitfield name="CPRQ_PENDING" pos="9" type="boolean"/>
+		<bitfield name="CFRQ_PENDING" pos="10" type="boolean"/>
+		<bitfield name="PFRQ_PENDING" pos="11" type="boolean"/>
+		<bitfield name="VGT_BUSY_NO_DMA" pos="12" type="boolean"/>
+		<bitfield name="RBBM_WU_BUSY" pos="14" type="boolean"/>
+		<bitfield name="CP_NRT_BUSY" pos="16" type="boolean"/>
+		<bitfield name="MH_BUSY" pos="18" type="boolean"/>
+		<bitfield name="MH_COHERENCY_BUSY" pos="19" type="boolean"/>
+		<bitfield name="SX_BUSY" pos="21" type="boolean"/>
+		<bitfield name="TPC_BUSY" pos="22" type="boolean"/>
+		<bitfield name="SC_CNTX_BUSY" pos="24" type="boolean"/>
+		<bitfield name="PA_BUSY" pos="25" type="boolean"/>
+		<bitfield name="VGT_BUSY" pos="26" type="boolean"/>
+		<bitfield name="SQ_CNTX17_BUSY" pos="27" type="boolean"/>
+		<bitfield name="SQ_CNTX0_BUSY" pos="28" type="boolean"/>
+		<bitfield name="RB_CNTX_BUSY" pos="30" type="boolean"/>
+		<bitfield name="GUI_ACTIVE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0a40" name="MH_ARBITER_CONFIG">
+		<bitfield name="SAME_PAGE_LIMIT" low="0" high="5" type="uint"/>
+		<bitfield name="SAME_PAGE_GRANULARITY" pos="6" type="boolean"/>
+		<bitfield name="L1_ARB_ENABLE" pos="7" type="boolean"/>
+		<bitfield name="L1_ARB_HOLD_ENABLE" pos="8" type="boolean"/>
+		<bitfield name="L2_ARB_CONTROL" pos="9" type="boolean"/>
+		<bitfield name="PAGE_SIZE" low="10" high="12" type="uint"/>
+		<bitfield name="TC_REORDER_ENABLE" pos="13" type="boolean"/>
+		<bitfield name="TC_ARB_HOLD_ENABLE" pos="14" type="boolean"/>
+		<bitfield name="IN_FLIGHT_LIMIT_ENABLE" pos="15" type="boolean"/>
+		<bitfield name="IN_FLIGHT_LIMIT" low="16" high="21" type="uint"/>
+		<bitfield name="CP_CLNT_ENABLE" pos="22" type="boolean"/>
+		<bitfield name="VGT_CLNT_ENABLE" pos="23" type="boolean"/>
+		<bitfield name="TC_CLNT_ENABLE" pos="24" type="boolean"/>
+		<bitfield name="RB_CLNT_ENABLE" pos="25" type="boolean"/>
+		<bitfield name="PA_CLNT_ENABLE" pos="26" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0a42" name="MH_INTERRUPT_MASK">
+		<bitfield name="AXI_READ_ERROR" pos="0" type="boolean"/>
+		<bitfield name="AXI_WRITE_ERROR" pos="1" type="boolean"/>
+		<bitfield name="MMU_PAGE_FAULT" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0a43" name="MH_INTERRUPT_STATUS"/>
+	<reg32 offset="0x0a44" name="MH_INTERRUPT_CLEAR"/>
+	<reg32 offset="0x0a54" name="MH_CLNT_INTF_CTRL_CONFIG1"/>
+	<reg32 offset="0x0a55" name="MH_CLNT_INTF_CTRL_CONFIG2"/>
+	<reg32 offset="0x0c01" name="A220_VSC_BIN_SIZE">
+		<bitfield name="WIDTH" low="0" high="4" shr="5" type="uint"/>
+		<bitfield name="HEIGHT" low="5" high="9" shr="5" type="uint"/>
+	</reg32>
+	<array offset="0x0c06" name="VSC_PIPE" stride="3" length="8">
+		<reg32 offset="0x0" name="CONFIG"/>
+		<reg32 offset="0x1" name="DATA_ADDRESS"/>
+		<reg32 offset="0x2" name="DATA_LENGTH"/>
+	</array>
+	<reg32 offset="0x0c38" name="PC_DEBUG_CNTL"/>
+	<reg32 offset="0x0c39" name="PC_DEBUG_DATA"/>
+	<reg32 offset="0x0c44" name="PA_SC_VIZ_QUERY_STATUS"/>
+	<reg32 offset="0x0c80" name="GRAS_DEBUG_CNTL"/>
+	<reg32 offset="0x0c80" name="PA_SU_DEBUG_CNTL"/>
+	<reg32 offset="0x0c81" name="GRAS_DEBUG_DATA"/>
+	<reg32 offset="0x0c81" name="PA_SU_DEBUG_DATA"/>
+	<reg32 offset="0x0c86" name="PA_SU_FACE_DATA">
+		<bitfield name="BASE_ADDR" low="5" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0d00" name="SQ_GPR_MANAGEMENT">
+		<bitfield name="REG_DYNAMIC" pos="0" type="boolean"/>
+		<bitfield name="REG_SIZE_PIX" low="4" high="11" type="uint"/>
+		<bitfield name="REG_SIZE_VTX" low="12" high="19" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0d01" name="SQ_FLOW_CONTROL"/>
+	<reg32 offset="0x0d02" name="SQ_INST_STORE_MANAGMENT">
+		<bitfield name="INST_BASE_PIX" low="0" high="11" type="uint"/>
+		<bitfield name="INST_BASE_VTX" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0d05" name="SQ_DEBUG_MISC"/>
+	<reg32 offset="0x0d34" name="SQ_INT_CNTL"/>
+	<reg32 offset="0x0d35" name="SQ_INT_STATUS"/>
+	<reg32 offset="0x0d36" name="SQ_INT_ACK"/>
+	<reg32 offset="0x0dae" name="SQ_DEBUG_INPUT_FSM"/>
+	<reg32 offset="0x0daf" name="SQ_DEBUG_CONST_MGR_FSM"/>
+	<reg32 offset="0x0db0" name="SQ_DEBUG_TP_FSM"/>
+	<reg32 offset="0x0db1" name="SQ_DEBUG_FSM_ALU_0"/>
+	<reg32 offset="0x0db2" name="SQ_DEBUG_FSM_ALU_1"/>
+	<reg32 offset="0x0db3" name="SQ_DEBUG_EXP_ALLOC"/>
+	<reg32 offset="0x0db4" name="SQ_DEBUG_PTR_BUFF"/>
+	<reg32 offset="0x0db5" name="SQ_DEBUG_GPR_VTX"/>
+	<reg32 offset="0x0db6" name="SQ_DEBUG_GPR_PIX"/>
+	<reg32 offset="0x0db7" name="SQ_DEBUG_TB_STATUS_SEL"/>
+	<reg32 offset="0x0db8" name="SQ_DEBUG_VTX_TB_0"/>
+	<reg32 offset="0x0db9" name="SQ_DEBUG_VTX_TB_1"/>
+	<reg32 offset="0x0dba" name="SQ_DEBUG_VTX_TB_STATUS_REG"/>
+	<reg32 offset="0x0dbb" name="SQ_DEBUG_VTX_TB_STATE_MEM"/>
+	<reg32 offset="0x0dbc" name="SQ_DEBUG_PIX_TB_0"/>
+	<reg32 offset="0x0dbd" name="SQ_DEBUG_PIX_TB_STATUS_REG_0"/>
+	<reg32 offset="0x0dbe" name="SQ_DEBUG_PIX_TB_STATUS_REG_1"/>
+	<reg32 offset="0x0dbf" name="SQ_DEBUG_PIX_TB_STATUS_REG_2"/>
+	<reg32 offset="0x0dc0" name="SQ_DEBUG_PIX_TB_STATUS_REG_3"/>
+	<reg32 offset="0x0dc1" name="SQ_DEBUG_PIX_TB_STATE_MEM"/>
+	<reg32 offset="0x0e00" name="TC_CNTL_STATUS">
+		<bitfield name="L2_INVALIDATE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0e1e" name="TP0_CHICKEN"/>
+	<reg32 offset="0x0f01" name="RB_BC_CONTROL">
+		<bitfield name="ACCUM_LINEAR_MODE_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="ACCUM_TIMEOUT_SELECT" low="1" high="2" type="uint"/>
+		<bitfield name="DISABLE_EDRAM_CAM" pos="3" type="boolean"/>
+		<bitfield name="DISABLE_EZ_FAST_CONTEXT_SWITCH" pos="4" type="boolean"/>
+		<bitfield name="DISABLE_EZ_NULL_ZCMD_DROP" pos="5" type="boolean"/>
+		<bitfield name="DISABLE_LZ_NULL_ZCMD_DROP" pos="6" type="boolean"/>
+		<bitfield name="ENABLE_AZ_THROTTLE" pos="7" type="boolean"/>
+		<bitfield name="AZ_THROTTLE_COUNT" low="8" high="12" type="uint"/>
+		<bitfield name="ENABLE_CRC_UPDATE" pos="14" type="boolean"/>
+		<bitfield name="CRC_MODE" pos="15" type="boolean"/>
+		<bitfield name="DISABLE_SAMPLE_COUNTERS" pos="16" type="boolean"/>
+		<bitfield name="DISABLE_ACCUM" pos="17" type="boolean"/>
+		<bitfield name="ACCUM_ALLOC_MASK" low="18" high="21" type="uint"/>
+		<bitfield name="LINEAR_PERFORMANCE_ENABLE" pos="22" type="boolean"/>
+		<bitfield name="ACCUM_DATA_FIFO_LIMIT" low="23" high="26" type="uint"/>
+		<bitfield name="MEM_EXPORT_TIMEOUT_SELECT" low="27" high="28" type="uint"/>
+		<bitfield name="MEM_EXPORT_LINEAR_MODE_ENABLE" pos="29" type="boolean"/>
+		<bitfield name="CRC_SYSTEM" pos="30" type="boolean"/>
+		<bitfield name="RESERVED6" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0f02" name="RB_EDRAM_INFO"/>
+	<reg32 offset="0x0f26" name="RB_DEBUG_CNTL"/>
+	<reg32 offset="0x0f27" name="RB_DEBUG_DATA"/>
+	<reg32 offset="0x2000" name="RB_SURFACE_INFO">
+		<bitfield name="SURFACE_PITCH" low="0" high="13" type="uint"/>
+		<bitfield name="MSAA_SAMPLES" low="14" high="15" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2001" name="RB_COLOR_INFO">
+		<bitfield name="FORMAT" low="0" high="3" type="a2xx_colorformatx"/>
+		<bitfield name="ROUND_MODE" low="4" high="5" type="uint"/>
+		<bitfield name="LINEAR" pos="6" type="boolean"/>
+		<bitfield name="ENDIAN" low="7" high="8" type="uint"/>
+		<bitfield name="SWAP" low="9" high="10" type="uint"/>
+		<bitfield name="BASE" low="12" high="31" shr="12"/>
+	</reg32>
+	<reg32 offset="0x2002" name="RB_DEPTH_INFO">
+		<bitfield name="DEPTH_FORMAT" pos="0" type="adreno_rb_depth_format"/>
+		<bitfield name="DEPTH_BASE" low="12" high="31" type="uint" shr="12"/>
+	</reg32>
+	<reg32 offset="0x2005" name="A225_RB_COLOR_INFO3"/>
+	<reg32 offset="0x2006" name="COHER_DEST_BASE_0"/>
+	<reg32 offset="0x200e" name="PA_SC_SCREEN_SCISSOR_TL" type="adreno_reg_xy"/>
+	<reg32 offset="0x200f" name="PA_SC_SCREEN_SCISSOR_BR" type="adreno_reg_xy"/>
+	<reg32 offset="0x2080" name="PA_SC_WINDOW_OFFSET">
+		<bitfield name="X" low="0" high="14" type="int"/>
+		<bitfield name="Y" low="16" high="30" type="int"/>
+		<bitfield name="DISABLE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2081" name="PA_SC_WINDOW_SCISSOR_TL" type="adreno_reg_xy"/>
+	<reg32 offset="0x2082" name="PA_SC_WINDOW_SCISSOR_BR" type="adreno_reg_xy"/>
+	<reg32 offset="0x2010" name="UNKNOWN_2010"/>
+	<reg32 offset="0x2100" name="VGT_MAX_VTX_INDX"/>
+	<reg32 offset="0x2101" name="VGT_MIN_VTX_INDX"/>
+	<reg32 offset="0x2102" name="VGT_INDX_OFFSET"/>
+	<reg32 offset="0x2103" name="A225_PC_MULTI_PRIM_IB_RESET_INDX"/>
+	<reg32 offset="0x2104" name="RB_COLOR_MASK">
+		<bitfield name="WRITE_RED" pos="0" type="boolean"/>
+		<bitfield name="WRITE_GREEN" pos="1" type="boolean"/>
+		<bitfield name="WRITE_BLUE" pos="2" type="boolean"/>
+		<bitfield name="WRITE_ALPHA" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2105" name="RB_BLEND_RED"/>
+	<reg32 offset="0x2106" name="RB_BLEND_GREEN"/>
+	<reg32 offset="0x2107" name="RB_BLEND_BLUE"/>
+	<reg32 offset="0x2108" name="RB_BLEND_ALPHA"/>
+	<reg32 offset="0x2109" name="RB_FOG_COLOR">
+		<bitfield name="FOG_RED" low="0" high="7" type="uint"/>
+		<bitfield name="FOG_GREEN" low="8" high="15" type="uint"/>
+		<bitfield name="FOG_BLUE" low="16" high="23" type="uint"/>
+	</reg32>
+	<reg32 offset="0x210c" name="RB_STENCILREFMASK_BF" type="adreno_rb_stencilrefmask"/>
+	<reg32 offset="0x210d" name="RB_STENCILREFMASK" type="adreno_rb_stencilrefmask"/>
+	<reg32 offset="0x210e" name="RB_ALPHA_REF"/>
+	<reg32 offset="0x210f" name="PA_CL_VPORT_XSCALE" type="float"/>
+	<reg32 offset="0x2110" name="PA_CL_VPORT_XOFFSET" type="float"/>
+	<reg32 offset="0x2111" name="PA_CL_VPORT_YSCALE" type="float"/>
+	<reg32 offset="0x2112" name="PA_CL_VPORT_YOFFSET" type="float"/>
+	<reg32 offset="0x2113" name="PA_CL_VPORT_ZSCALE" type="float"/>
+	<reg32 offset="0x2114" name="PA_CL_VPORT_ZOFFSET" type="float"/>
+	<reg32 offset="0x2180" name="SQ_PROGRAM_CNTL">
+		<doc>
+			note: only 0x3f worth of valid register values for VS_REGS and
+			PS_REGS, but high bit is set to indicate '0 registers used':
+		</doc>
+		<bitfield name="VS_REGS" low="0" high="7" type="uint"/>
+		<bitfield name="PS_REGS" low="8" high="15" type="uint"/>
+		<bitfield name="VS_RESOURCE" pos="16" type="boolean"/>
+		<bitfield name="PS_RESOURCE" pos="17" type="boolean"/>
+		<bitfield name="PARAM_GEN" pos="18" type="boolean"/>
+		<bitfield name="GEN_INDEX_PIX" pos="19" type="boolean"/>
+		<bitfield name="VS_EXPORT_COUNT" low="20" high="23" type="uint"/>
+		<bitfield name="VS_EXPORT_MODE" low="24" high="26" type="a2xx_sq_ps_vtx_mode"/>
+		<bitfield name="PS_EXPORT_MODE" low="27" high="30" type="uint"/>
+		<bitfield name="GEN_INDEX_VTX" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2181" name="SQ_CONTEXT_MISC">
+		<bitfield name="INST_PRED_OPTIMIZE" pos="0" type="boolean"/>
+		<bitfield name="SC_OUTPUT_SCREEN_XY" pos="1" type="boolean"/>
+		<bitfield name="SC_SAMPLE_CNTL" low="2" high="3" type="a2xx_sq_sample_cntl"/>
+		<bitfield name="PARAM_GEN_POS" low="8" high="15" type="uint"/>
+		<bitfield name="PERFCOUNTER_REF" pos="16" type="boolean"/>
+		<bitfield name="YEILD_OPTIMIZE" pos="17" type="boolean"/>
+		<bitfield name="TX_CACHE_SEL" pos="18" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2182" name="SQ_INTERPOLATOR_CNTL">
+		<bitfield name="PARAM_SHADE" low="0" high="15" type="uint"/>
+		<bitfield name="SAMPLING_PATTERN" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2183" name="SQ_WRAPPING_0">
+		<bitfield name="PARAM_WRAP_0" low="0" high="3" type="uint"/>
+		<bitfield name="PARAM_WRAP_1" low="4" high="7" type="uint"/>
+		<bitfield name="PARAM_WRAP_2" low="8" high="11" type="uint"/>
+		<bitfield name="PARAM_WRAP_3" low="12" high="15" type="uint"/>
+		<bitfield name="PARAM_WRAP_4" low="16" high="19" type="uint"/>
+		<bitfield name="PARAM_WRAP_5" low="20" high="23" type="uint"/>
+		<bitfield name="PARAM_WRAP_6" low="24" high="27" type="uint"/>
+		<bitfield name="PARAM_WRAP_7" low="28" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2184" name="SQ_WRAPPING_1">
+		<bitfield name="PARAM_WRAP_8" low="0" high="3" type="uint"/>
+		<bitfield name="PARAM_WRAP_9" low="4" high="7" type="uint"/>
+		<bitfield name="PARAM_WRAP_10" low="8" high="11" type="uint"/>
+		<bitfield name="PARAM_WRAP_11" low="12" high="15" type="uint"/>
+		<bitfield name="PARAM_WRAP_12" low="16" high="19" type="uint"/>
+		<bitfield name="PARAM_WRAP_13" low="20" high="23" type="uint"/>
+		<bitfield name="PARAM_WRAP_14" low="24" high="27" type="uint"/>
+		<bitfield name="PARAM_WRAP_15" low="28" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x21f6" name="SQ_PS_PROGRAM">
+		<bitfield name="BASE" low="0" high="11" type="uint"/>
+		<bitfield name="SIZE" low="12" high="23" type="uint"/>
+	</reg32>
+	<reg32 offset="0x21f7" name="SQ_VS_PROGRAM">
+		<bitfield name="BASE" low="0" high="11" type="uint"/>
+		<bitfield name="SIZE" low="12" high="23" type="uint"/>
+	</reg32>
+	<reg32 offset="0x21f9" name="VGT_EVENT_INITIATOR"/>
+	<reg32 offset="0x21fc" name="VGT_DRAW_INITIATOR" type="vgt_draw_initiator"/>
+	<reg32 offset="0x21fd" name="VGT_IMMED_DATA"/>
+	<reg32 offset="0x2200" name="RB_DEPTHCONTROL">
+		<bitfield name="STENCIL_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="Z_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="Z_WRITE_ENABLE" pos="2" type="boolean"/>
+		<bitfield name="EARLY_Z_ENABLE" pos="3" type="boolean"/>
+		<bitfield name="ZFUNC" low="4" high="6" type="adreno_compare_func"/>
+		<bitfield name="BACKFACE_ENABLE" pos="7" type="boolean"/>
+		<bitfield name="STENCILFUNC" low="8" high="10" type="adreno_compare_func"/>
+		<bitfield name="STENCILFAIL" low="11" high="13" type="adreno_stencil_op"/>
+		<bitfield name="STENCILZPASS" low="14" high="16" type="adreno_stencil_op"/>
+		<bitfield name="STENCILZFAIL" low="17" high="19" type="adreno_stencil_op"/>
+		<bitfield name="STENCILFUNC_BF" low="20" high="22" type="adreno_compare_func"/>
+		<bitfield name="STENCILFAIL_BF" low="23" high="25" type="adreno_stencil_op"/>
+		<bitfield name="STENCILZPASS_BF" low="26" high="28" type="adreno_stencil_op"/>
+		<bitfield name="STENCILZFAIL_BF" low="29" high="31" type="adreno_stencil_op"/>
+	</reg32>
+	<reg32 offset="0x2201" name="RB_BLEND_CONTROL">
+		<bitfield name="COLOR_SRCBLEND" low="0" high="4" type="adreno_rb_blend_factor"/>
+		<bitfield name="COLOR_COMB_FCN" low="5" high="7" type="a2xx_rb_blend_opcode"/>
+		<bitfield name="COLOR_DESTBLEND" low="8" high="12" type="adreno_rb_blend_factor"/>
+		<bitfield name="ALPHA_SRCBLEND" low="16" high="20" type="adreno_rb_blend_factor"/>
+		<bitfield name="ALPHA_COMB_FCN" low="21" high="23" type="a2xx_rb_blend_opcode"/>
+		<bitfield name="ALPHA_DESTBLEND" low="24" high="28" type="adreno_rb_blend_factor"/>
+		<bitfield name="BLEND_FORCE_ENABLE" pos="29" type="boolean"/>
+		<bitfield name="BLEND_FORCE" pos="30" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2202" name="RB_COLORCONTROL">
+		<bitfield name="ALPHA_FUNC" low="0" high="2" type="adreno_compare_func"/>
+		<bitfield name="ALPHA_TEST_ENABLE" pos="3" type="boolean"/>
+		<bitfield name="ALPHA_TO_MASK_ENABLE" pos="4" type="boolean"/>
+		<bitfield name="BLEND_DISABLE" pos="5" type="boolean"/>
+		<bitfield name="VOB_ENABLE" pos="6" type="boolean"/>
+		<bitfield name="VS_EXPORTS_FOG" pos="7" type="boolean"/>
+		<bitfield name="ROP_CODE" low="8" high="11" type="uint"/>
+		<bitfield name="DITHER_MODE" low="12" high="13" type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_TYPE" low="14" high="15" type="a2xx_rb_dither_type"/>
+		<bitfield name="PIXEL_FOG" pos="16" type="boolean"/>
+		<bitfield name="ALPHA_TO_MASK_OFFSET0" low="24" high="25" type="uint"/>
+		<bitfield name="ALPHA_TO_MASK_OFFSET1" low="26" high="27" type="uint"/>
+		<bitfield name="ALPHA_TO_MASK_OFFSET2" low="28" high="29" type="uint"/>
+		<bitfield name="ALPHA_TO_MASK_OFFSET3" low="30" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2203" name="VGT_CURRENT_BIN_ID_MAX" type="a2xx_vgt_current_bin_id_min_max"/>
+	<reg32 offset="0x2204" name="PA_CL_CLIP_CNTL">
+		<bitfield name="CLIP_DISABLE" pos="16" type="boolean"/>
+		<bitfield name="BOUNDARY_EDGE_FLAG_ENA" pos="18" type="boolean"/>
+		<bitfield name="DX_CLIP_SPACE_DEF" pos="19" type="a2xx_dx_clip_space"/>
+		<bitfield name="DIS_CLIP_ERR_DETECT" pos="20" type="boolean"/>
+		<bitfield name="VTX_KILL_OR" pos="21" type="boolean"/>
+		<bitfield name="XY_NAN_RETAIN" pos="22" type="boolean"/>
+		<bitfield name="Z_NAN_RETAIN" pos="23" type="boolean"/>
+		<bitfield name="W_NAN_RETAIN" pos="24" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2205" name="PA_SU_SC_MODE_CNTL">
+		<bitfield name="CULL_FRONT" pos="0" type="boolean"/>
+		<bitfield name="CULL_BACK" pos="1" type="boolean"/>
+		<bitfield name="FACE" pos="2" type="boolean"/>
+		<bitfield name="POLYMODE" low="3" high="4" type="a2xx_pa_su_sc_polymode"/>
+		<bitfield name="FRONT_PTYPE" low="5" high="7" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="BACK_PTYPE" low="8" high="10" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="POLY_OFFSET_FRONT_ENABLE" pos="11" type="boolean"/>
+		<bitfield name="POLY_OFFSET_BACK_ENABLE" pos="12" type="boolean"/>
+		<bitfield name="POLY_OFFSET_PARA_ENABLE" pos="13" type="boolean"/>
+		<bitfield name="MSAA_ENABLE" pos="15" type="boolean"/>
+		<bitfield name="VTX_WINDOW_OFFSET_ENABLE" pos="16" type="boolean"/>
+		<bitfield name="LINE_STIPPLE_ENABLE" pos="18" type="boolean"/>
+		<bitfield name="PROVOKING_VTX_LAST" pos="19" type="boolean"/>
+		<bitfield name="PERSP_CORR_DIS" pos="20" type="boolean"/>
+		<bitfield name="MULTI_PRIM_IB_ENA" pos="21" type="boolean"/>
+		<bitfield name="QUAD_ORDER_ENABLE" pos="23" type="boolean"/>
+		<bitfield name="WAIT_RB_IDLE_ALL_TRI" pos="25" type="boolean"/>
+		<bitfield name="WAIT_RB_IDLE_FIRST_TRI_NEW_STATE" pos="26" type="boolean"/>
+		<bitfield name="CLAMPED_FACENESS" pos="28" type="boolean"/>
+		<bitfield name="ZERO_AREA_FACENESS" pos="29" type="boolean"/>
+		<bitfield name="FACE_KILL_ENABLE" pos="30" type="boolean"/>
+		<bitfield name="FACE_WRITE_ENABLE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2206" name="PA_CL_VTE_CNTL">
+		<bitfield name="VPORT_X_SCALE_ENA" pos="0" type="boolean"/>
+		<bitfield name="VPORT_X_OFFSET_ENA" pos="1" type="boolean"/>
+		<bitfield name="VPORT_Y_SCALE_ENA" pos="2" type="boolean"/>
+		<bitfield name="VPORT_Y_OFFSET_ENA" pos="3" type="boolean"/>
+		<bitfield name="VPORT_Z_SCALE_ENA" pos="4" type="boolean"/>
+		<bitfield name="VPORT_Z_OFFSET_ENA" pos="5" type="boolean"/>
+		<bitfield name="VTX_XY_FMT" pos="8" type="boolean"/>
+		<bitfield name="VTX_Z_FMT" pos="9" type="boolean"/>
+		<bitfield name="VTX_W0_FMT" pos="10" type="boolean"/>
+		<bitfield name="PERFCOUNTER_REF" pos="11" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2207" name="VGT_CURRENT_BIN_ID_MIN" type="a2xx_vgt_current_bin_id_min_max"/>
+	<reg32 offset="0x2208" name="RB_MODECONTROL">
+		<bitfield name="EDRAM_MODE" low="0" high="2" type="a2xx_rb_edram_mode"/>
+	</reg32>
+	<reg32 offset="0x2209" name="A220_RB_LRZ_VSC_CONTROL"/>
+	<reg32 offset="0x220a" name="RB_SAMPLE_POS"/>
+	<reg32 offset="0x220b" name="CLEAR_COLOR">
+		<bitfield name="RED" low="0" high="7"/>
+		<bitfield name="GREEN" low="8" high="15"/>
+		<bitfield name="BLUE" low="16" high="23"/>
+		<bitfield name="ALPHA" low="24" high="31"/>
+	</reg32>
+	<reg32 offset="0x2210" name="A220_GRAS_CONTROL"/>
+	<reg32 offset="0x2280" name="PA_SU_POINT_SIZE">
+		<bitfield name="HEIGHT" low="0" high="15" type="ufixed" radix="4"/>
+		<bitfield name="WIDTH" low="16" high="31" type="ufixed" radix="4"/>
+	</reg32>
+	<reg32 offset="0x2281" name="PA_SU_POINT_MINMAX">
+		<bitfield name="MIN" low="0" high="15" type="ufixed" radix="4"/>
+		<bitfield name="MAX" low="16" high="31" type="ufixed" radix="4"/>
+	</reg32>
+	<reg32 offset="0x2282" name="PA_SU_LINE_CNTL">
+		<bitfield name="WIDTH" low="0" high="15" type="ufixed" radix="4"/>
+	</reg32>
+	<reg32 offset="0x2283" name="PA_SC_LINE_STIPPLE">
+		<bitfield name="LINE_PATTERN" low="0" high="15" type="hex"/>
+		<bitfield name="REPEAT_COUNT" low="16" high="23" type="uint"/>
+		<bitfield name="PATTERN_BIT_ORDER" pos="28" type="a2xx_pa_sc_pattern_bit_order"/>
+		<bitfield name="AUTO_RESET_CNTL" low="29" high="30" type="a2xx_pa_sc_auto_reset_cntl"/>
+	</reg32>
+	<reg32 offset="0x2293" name="PA_SC_VIZ_QUERY">
+		<bitfield name="VIZ_QUERY_ENA" pos="0" type="boolean"/>
+		<bitfield name="VIZ_QUERY_ID" low="1" high="6" type="uint"/>
+		<bitfield name="KILL_PIX_POST_EARLY_Z" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2294" name="VGT_ENHANCE"/>
+	<reg32 offset="0x2300" name="PA_SC_LINE_CNTL">
+		<bitfield name="BRES_CNTL" low="0" high="15" type="uint"/>
+		<bitfield name="USE_BRES_CNTL" pos="8" type="boolean"/>
+		<bitfield name="EXPAND_LINE_WIDTH" pos="9" type="boolean"/>
+		<bitfield name="LAST_PIXEL" pos="10" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2301" name="PA_SC_AA_CONFIG">
+		<bitfield name="MSAA_NUM_SAMPLES" low="0" high="2" type="uint"/>
+		<bitfield name="MAX_SAMPLE_DIST" low="13" high="16" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2302" name="PA_SU_VTX_CNTL">
+		<bitfield name="PIX_CENTER" pos="0" type="a2xx_pa_pixcenter"/>
+		<bitfield name="ROUND_MODE" low="1" high="2" type="a2xx_pa_roundmode"/>
+		<bitfield name="QUANT_MODE" low="7" high="9" type="a2xx_pa_quantmode"/>
+	</reg32>
+	<reg32 offset="0x2303" name="PA_CL_GB_VERT_CLIP_ADJ" type="float"/>
+	<reg32 offset="0x2304" name="PA_CL_GB_VERT_DISC_ADJ" type="float"/>
+	<reg32 offset="0x2305" name="PA_CL_GB_HORZ_CLIP_ADJ" type="float"/>
+	<reg32 offset="0x2306" name="PA_CL_GB_HORZ_DISC_ADJ" type="float"/>
+	<reg32 offset="0x2307" name="SQ_VS_CONST">
+		<bitfield name="BASE" low="0" high="8" type="uint"/>
+		<bitfield name="SIZE" low="12" high="20" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2308" name="SQ_PS_CONST">
+		<bitfield name="BASE" low="0" high="8" type="uint"/>
+		<bitfield name="SIZE" low="12" high="20" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2309" name="SQ_DEBUG_MISC_0"/>
+	<reg32 offset="0x230a" name="SQ_DEBUG_MISC_1"/>
+	<reg32 offset="0x2312" name="PA_SC_AA_MASK"/>
+	<reg32 offset="0x2316" name="VGT_VERTEX_REUSE_BLOCK_CNTL">
+		<bitfield name="VTX_REUSE_DEPTH" low="0" high="2" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2317" name="VGT_OUT_DEALLOC_CNTL">
+		<bitfield name="DEALLOC_DIST" low="0" high="1" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2318" name="RB_COPY_CONTROL">
+		<bitfield name="COPY_SAMPLE_SELECT" low="0" high="2" type="a2xx_rb_copy_sample_select"/>
+		<bitfield name="DEPTH_CLEAR_ENABLE" pos="3" type="boolean"/>
+		<bitfield name="CLEAR_MASK" low="4" high="7" type="hex"/>
+	</reg32>
+	<reg32 offset="0x2319" name="RB_COPY_DEST_BASE"/>
+	<reg32 offset="0x231a" name="RB_COPY_DEST_PITCH" shr="5" type="uint"/>
+	<reg32 offset="0x231b" name="RB_COPY_DEST_INFO">
+		<bitfield name="DEST_ENDIAN" low="0" high="2" type="adreno_rb_surface_endian"/>
+		<bitfield name="LINEAR" pos="3" type="boolean"/>
+		<bitfield name="FORMAT" low="4" high="7" type="a2xx_colorformatx"/>
+		<bitfield name="SWAP" low="8" high="9" type="uint"/>
+		<bitfield name="DITHER_MODE" low="10" high="11" type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_TYPE" low="12" high="13" type="a2xx_rb_dither_type"/>
+		<bitfield name="WRITE_RED" pos="14" type="boolean"/>
+		<bitfield name="WRITE_GREEN" pos="15" type="boolean"/>
+		<bitfield name="WRITE_BLUE" pos="16" type="boolean"/>
+		<bitfield name="WRITE_ALPHA" pos="17" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x231c" name="RB_COPY_DEST_OFFSET">
+		<bitfield name="X" low="0" high="12" type="uint"/>
+		<bitfield name="Y" low="13" high="25" type="uint"/>
+	</reg32>
+	<reg32 offset="0x231d" name="RB_DEPTH_CLEAR"/>
+	<reg32 offset="0x2324" name="RB_SAMPLE_COUNT_CTL"/>
+	<reg32 offset="0x2326" name="RB_COLOR_DEST_MASK"/>
+	<reg32 offset="0x2340" name="A225_GRAS_UCP0X"/>
+	<reg32 offset="0x2357" name="A225_GRAS_UCP5W"/>
+	<reg32 offset="0x2360" name="A225_GRAS_UCP_ENABLED"/>
+	<reg32 offset="0x2380" name="PA_SU_POLY_OFFSET_FRONT_SCALE"/>
+	<reg32 offset="0x2381" name="PA_SU_POLY_OFFSET_FRONT_OFFSET"/>
+	<reg32 offset="0x2382" name="PA_SU_POLY_OFFSET_BACK_SCALE"/>
+	<reg32 offset="0x2383" name="PA_SU_POLY_OFFSET_BACK_OFFSET"/>
+	<reg32 offset="0x4000" name="SQ_CONSTANT_0"/>
+	<reg32 offset="0x4800" name="SQ_FETCH_0"/>
+	<reg32 offset="0x4900" name="SQ_CF_BOOLEANS"/>
+	<reg32 offset="0x4908" name="SQ_CF_LOOP"/>
+	<reg32 offset="0xa29" name="COHER_SIZE_PM4"/>
+	<reg32 offset="0xa2a" name="COHER_BASE_PM4"/>
+	<reg32 offset="0xa2b" name="COHER_STATUS_PM4"/>
+
+	<reg32 offset="0x0c88" name="PA_SU_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0c89" name="PA_SU_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0c8a" name="PA_SU_PERFCOUNTER2_SELECT"/>
+	<reg32 offset="0x0c8b" name="PA_SU_PERFCOUNTER3_SELECT"/>
+	<reg32 offset="0x0c8c" name="PA_SU_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0c8d" name="PA_SU_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0c8e" name="PA_SU_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0c8f" name="PA_SU_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0c90" name="PA_SU_PERFCOUNTER2_LOW"/>
+	<reg32 offset="0x0c91" name="PA_SU_PERFCOUNTER2_HI"/>
+	<reg32 offset="0x0c92" name="PA_SU_PERFCOUNTER3_LOW"/>
+	<reg32 offset="0x0c93" name="PA_SU_PERFCOUNTER3_HI"/>
+	<reg32 offset="0x0c98" name="PA_SC_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0c99" name="PA_SC_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0c9a" name="PA_SC_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0c48" name="VGT_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0c49" name="VGT_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0c4a" name="VGT_PERFCOUNTER2_SELECT"/>
+	<reg32 offset="0x0c4b" name="VGT_PERFCOUNTER3_SELECT"/>
+	<reg32 offset="0x0c4c" name="VGT_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0c4e" name="VGT_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0c50" name="VGT_PERFCOUNTER2_LOW"/>
+	<reg32 offset="0x0c52" name="VGT_PERFCOUNTER3_LOW"/>
+	<reg32 offset="0x0c4d" name="VGT_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0c4f" name="VGT_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0c51" name="VGT_PERFCOUNTER2_HI"/>
+	<reg32 offset="0x0c53" name="VGT_PERFCOUNTER3_HI"/>
+	<reg32 offset="0x0e05" name="TCR_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0e08" name="TCR_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0e06" name="TCR_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0e09" name="TCR_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0e07" name="TCR_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0e0a" name="TCR_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0e1f" name="TP0_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0e20" name="TP0_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0e21" name="TP0_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0e22" name="TP0_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0e23" name="TP0_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0e24" name="TP0_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0e54" name="TCM_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0e57" name="TCM_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0e55" name="TCM_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0e58" name="TCM_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0e56" name="TCM_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0e59" name="TCM_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0e5a" name="TCF_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0e5d" name="TCF_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0e60" name="TCF_PERFCOUNTER2_SELECT"/>
+	<reg32 offset="0x0e63" name="TCF_PERFCOUNTER3_SELECT"/>
+	<reg32 offset="0x0e66" name="TCF_PERFCOUNTER4_SELECT"/>
+	<reg32 offset="0x0e69" name="TCF_PERFCOUNTER5_SELECT"/>
+	<reg32 offset="0x0e6c" name="TCF_PERFCOUNTER6_SELECT"/>
+	<reg32 offset="0x0e6f" name="TCF_PERFCOUNTER7_SELECT"/>
+	<reg32 offset="0x0e72" name="TCF_PERFCOUNTER8_SELECT"/>
+	<reg32 offset="0x0e75" name="TCF_PERFCOUNTER9_SELECT"/>
+	<reg32 offset="0x0e78" name="TCF_PERFCOUNTER10_SELECT"/>
+	<reg32 offset="0x0e7b" name="TCF_PERFCOUNTER11_SELECT"/>
+	<reg32 offset="0x0e5b" name="TCF_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0e5e" name="TCF_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0e61" name="TCF_PERFCOUNTER2_HI"/>
+	<reg32 offset="0x0e64" name="TCF_PERFCOUNTER3_HI"/>
+	<reg32 offset="0x0e67" name="TCF_PERFCOUNTER4_HI"/>
+	<reg32 offset="0x0e6a" name="TCF_PERFCOUNTER5_HI"/>
+	<reg32 offset="0x0e6d" name="TCF_PERFCOUNTER6_HI"/>
+	<reg32 offset="0x0e70" name="TCF_PERFCOUNTER7_HI"/>
+	<reg32 offset="0x0e73" name="TCF_PERFCOUNTER8_HI"/>
+	<reg32 offset="0x0e76" name="TCF_PERFCOUNTER9_HI"/>
+	<reg32 offset="0x0e79" name="TCF_PERFCOUNTER10_HI"/>
+	<reg32 offset="0x0e7c" name="TCF_PERFCOUNTER11_HI"/>
+	<reg32 offset="0x0e5c" name="TCF_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0e5f" name="TCF_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0e62" name="TCF_PERFCOUNTER2_LOW"/>
+	<reg32 offset="0x0e65" name="TCF_PERFCOUNTER3_LOW"/>
+	<reg32 offset="0x0e68" name="TCF_PERFCOUNTER4_LOW"/>
+	<reg32 offset="0x0e6b" name="TCF_PERFCOUNTER5_LOW"/>
+	<reg32 offset="0x0e6e" name="TCF_PERFCOUNTER6_LOW"/>
+	<reg32 offset="0x0e71" name="TCF_PERFCOUNTER7_LOW"/>
+	<reg32 offset="0x0e74" name="TCF_PERFCOUNTER8_LOW"/>
+	<reg32 offset="0x0e77" name="TCF_PERFCOUNTER9_LOW"/>
+	<reg32 offset="0x0e7a" name="TCF_PERFCOUNTER10_LOW"/>
+	<reg32 offset="0x0e7d" name="TCF_PERFCOUNTER11_LOW"/>
+	<reg32 offset="0x0dc8" name="SQ_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0dc9" name="SQ_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0dca" name="SQ_PERFCOUNTER2_SELECT"/>
+	<reg32 offset="0x0dcb" name="SQ_PERFCOUNTER3_SELECT"/>
+	<reg32 offset="0x0dcc" name="SQ_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0dcd" name="SQ_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0dce" name="SQ_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0dcf" name="SQ_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0dd0" name="SQ_PERFCOUNTER2_LOW"/>
+	<reg32 offset="0x0dd1" name="SQ_PERFCOUNTER2_HI"/>
+	<reg32 offset="0x0dd2" name="SQ_PERFCOUNTER3_LOW"/>
+	<reg32 offset="0x0dd3" name="SQ_PERFCOUNTER3_HI"/>
+	<reg32 offset="0x0dd4" name="SX_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0dd8" name="SX_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0dd9" name="SX_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0a46" name="MH_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0a4a" name="MH_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0a47" name="MH_PERFCOUNTER0_CONFIG"/>
+	<reg32 offset="0x0a4b" name="MH_PERFCOUNTER1_CONFIG"/>
+	<reg32 offset="0x0a48" name="MH_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0a4c" name="MH_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0a49" name="MH_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0a4d" name="MH_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0f04" name="RB_PERFCOUNTER0_SELECT"/>
+	<reg32 offset="0x0f05" name="RB_PERFCOUNTER1_SELECT"/>
+	<reg32 offset="0x0f06" name="RB_PERFCOUNTER2_SELECT"/>
+	<reg32 offset="0x0f07" name="RB_PERFCOUNTER3_SELECT"/>
+	<reg32 offset="0x0f08" name="RB_PERFCOUNTER0_LOW"/>
+	<reg32 offset="0x0f09" name="RB_PERFCOUNTER0_HI"/>
+	<reg32 offset="0x0f0a" name="RB_PERFCOUNTER1_LOW"/>
+	<reg32 offset="0x0f0b" name="RB_PERFCOUNTER1_HI"/>
+	<reg32 offset="0x0f0c" name="RB_PERFCOUNTER2_LOW"/>
+	<reg32 offset="0x0f0d" name="RB_PERFCOUNTER2_HI"/>
+	<reg32 offset="0x0f0e" name="RB_PERFCOUNTER3_LOW"/>
+	<reg32 offset="0x0f0f" name="RB_PERFCOUNTER3_HI"/>
+</domain>
+
+<domain name="A2XX_SQ_TEX" width="32">
+	<doc>Texture state dwords</doc>
+	<enum name="sq_tex_clamp">
+		<value name="SQ_TEX_WRAP" value="0"/>
+		<value name="SQ_TEX_MIRROR" value="1"/>
+		<value name="SQ_TEX_CLAMP_LAST_TEXEL" value="2"/>
+		<value name="SQ_TEX_MIRROR_ONCE_LAST_TEXEL" value="3"/>
+		<value name="SQ_TEX_CLAMP_HALF_BORDER" value="4"/>
+		<value name="SQ_TEX_MIRROR_ONCE_HALF_BORDER" value="5"/>
+		<value name="SQ_TEX_CLAMP_BORDER" value="6"/>
+		<value name="SQ_TEX_MIRROR_ONCE_BORDER" value="7"/>
+	</enum>
+	<enum name="sq_tex_swiz">
+		<value name="SQ_TEX_X" value="0"/>
+		<value name="SQ_TEX_Y" value="1"/>
+		<value name="SQ_TEX_Z" value="2"/>
+		<value name="SQ_TEX_W" value="3"/>
+		<value name="SQ_TEX_ZERO" value="4"/>
+		<value name="SQ_TEX_ONE" value="5"/>
+	</enum>
+	<enum name="sq_tex_filter">
+		<value name="SQ_TEX_FILTER_POINT" value="0"/>
+		<value name="SQ_TEX_FILTER_BILINEAR" value="1"/>
+		<value name="SQ_TEX_FILTER_BASEMAP" value="2"/>
+		<value name="SQ_TEX_FILTER_USE_FETCH_CONST" value="3"/>
+	</enum>
+	<enum name="sq_tex_aniso_filter">
+		<value name="SQ_TEX_ANISO_FILTER_DISABLED" value="0"/>
+		<value name="SQ_TEX_ANISO_FILTER_MAX_1_1" value="1"/>
+		<value name="SQ_TEX_ANISO_FILTER_MAX_2_1" value="2"/>
+		<value name="SQ_TEX_ANISO_FILTER_MAX_4_1" value="3"/>
+		<value name="SQ_TEX_ANISO_FILTER_MAX_8_1" value="4"/>
+		<value name="SQ_TEX_ANISO_FILTER_MAX_16_1" value="5"/>
+		<value name="SQ_TEX_ANISO_FILTER_USE_FETCH_CONST" value="7"/>
+	</enum>
+	<enum name="sq_tex_dimension">
+		<value name="SQ_TEX_DIMENSION_1D" value="0"/>
+		<value name="SQ_TEX_DIMENSION_2D" value="1"/>
+		<value name="SQ_TEX_DIMENSION_3D" value="2"/>
+		<value name="SQ_TEX_DIMENSION_CUBE" value="3"/>
+	</enum>
+	<enum name="sq_tex_border_color">
+		<value name="SQ_TEX_BORDER_COLOR_BLACK" value="0"/>
+		<value name="SQ_TEX_BORDER_COLOR_WHITE" value="1"/>
+		<value name="SQ_TEX_BORDER_COLOR_ACBYCR_BLACK" value="2"/>
+		<value name="SQ_TEX_BORDER_COLOR_ACBCRY_BLACK" value="3"/>
+	</enum>
+	<enum name="sq_tex_sign">
+		<value name="SQ_TEX_SIGN_UNSIGNED" value="0"/>
+		<value name="SQ_TEX_SIGN_SIGNED" value="1"/>
+		<!-- biased: 2*color-1 (range -1,1 when sampling) -->
+		<value name="SQ_TEX_SIGN_UNSIGNED_BIASED" value="2"/>
+		<!-- gamma: sRGB to linear - doesn't seem to work on adreno? -->
+		<value name="SQ_TEX_SIGN_GAMMA" value="3"/>
+	</enum>
+	<enum name="sq_tex_endian">
+		<value name="SQ_TEX_ENDIAN_NONE" value="0"/>
+		<value name="SQ_TEX_ENDIAN_8IN16" value="1"/>
+		<value name="SQ_TEX_ENDIAN_8IN32" value="2"/>
+		<value name="SQ_TEX_ENDIAN_16IN32" value="3"/>
+	</enum>
+	<enum name="sq_tex_clamp_policy">
+		<value name="SQ_TEX_CLAMP_POLICY_D3D" value="0"/>
+		<value name="SQ_TEX_CLAMP_POLICY_OGL" value="1"/>
+	</enum>
+	<enum name="sq_tex_num_format">
+		<value name="SQ_TEX_NUM_FORMAT_FRAC" value="0"/>
+		<value name="SQ_TEX_NUM_FORMAT_INT" value="1"/>
+	</enum>
+	<enum name="sq_tex_type">
+		<value name="SQ_TEX_TYPE_0" value="0"/>
+		<value name="SQ_TEX_TYPE_1" value="1"/>
+		<value name="SQ_TEX_TYPE_2" value="2"/>
+		<value name="SQ_TEX_TYPE_3" value="3"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="TYPE" low="0" high="1" type="sq_tex_type"/>
+		<bitfield name="SIGN_X" low="2" high="3" type="sq_tex_sign"/>
+		<bitfield name="SIGN_Y" low="4" high="5" type="sq_tex_sign"/>
+		<bitfield name="SIGN_Z" low="6" high="7" type="sq_tex_sign"/>
+		<bitfield name="SIGN_W" low="8" high="9" type="sq_tex_sign"/>
+		<bitfield name="CLAMP_X" low="10" high="12" type="sq_tex_clamp"/>
+		<bitfield name="CLAMP_Y" low="13" high="15" type="sq_tex_clamp"/>
+		<bitfield name="CLAMP_Z" low="16" high="18" type="sq_tex_clamp"/>
+		<bitfield name="PITCH" low="22" high="30" shr="5" type="uint"/>
+		<bitfield name="TILED" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="FORMAT" low="0" high="5" type="a2xx_sq_surfaceformat"/>
+		<bitfield name="ENDIANNESS" low="6" high="7" type="sq_tex_endian"/>
+		<bitfield name="REQUEST_SIZE" low="8" high="9" type="uint"/>
+		<bitfield name="STACKED" pos="10" type="boolean"/>
+		<bitfield name="CLAMP_POLICY" pos="11" type="sq_tex_clamp_policy"/>
+		<bitfield name="BASE_ADDRESS" low="12" high="31" type="uint" shr="12"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="WIDTH" low="0" high="12" type="uint"/>
+		<bitfield name="HEIGHT" low="13" high="25" type="uint"/>
+		<bitfield name="DEPTH" low="26" high="31" type="uint"/>
+		<!-- 1d/3d have different bit configurations -->
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="NUM_FORMAT" pos="0" type="sq_tex_num_format"/>
+		<bitfield name="SWIZ_X" low="1" high="3" type="sq_tex_swiz"/>
+		<bitfield name="SWIZ_Y" low="4" high="6" type="sq_tex_swiz"/>
+		<bitfield name="SWIZ_Z" low="7" high="9" type="sq_tex_swiz"/>
+		<bitfield name="SWIZ_W" low="10" high="12" type="sq_tex_swiz"/>
+		<bitfield name="EXP_ADJUST" low="13" high="18" type="int"/>
+		<bitfield name="XY_MAG_FILTER" low="19" high="20" type="sq_tex_filter"/>
+		<bitfield name="XY_MIN_FILTER" low="21" high="22" type="sq_tex_filter"/>
+		<bitfield name="MIP_FILTER" low="23" high="24" type="sq_tex_filter"/>
+		<bitfield name="ANISO_FILTER" low="25" high="27" type="sq_tex_aniso_filter"/>
+		<bitfield name="BORDER_SIZE" pos="31" type="uint"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="VOL_MAG_FILTER" pos="0" type="sq_tex_filter"/>
+		<bitfield name="VOL_MIN_FILTER" pos="1" type="sq_tex_filter"/>
+		<bitfield name="MIP_MIN_LEVEL" low="2" high="5" type="uint"/>
+		<bitfield name="MIP_MAX_LEVEL" low="6" high="9" type="uint"/>
+		<bitfield name="MAX_ANISO_WALK" pos="10" type="boolean"/>
+		<bitfield name="MIN_ANISO_WALK" pos="11" type="boolean"/>
+		<bitfield name="LOD_BIAS" low="12" high="21" type="fixed" radix="5"/>
+		<bitfield name="GRAD_EXP_ADJUST_H" low="22" high="26" type="uint"/>
+		<bitfield name="GRAD_EXP_ADJUST_V" low="27" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="BORDER_COLOR" low="0" high="1" type="sq_tex_border_color"/>
+		<bitfield name="FORCE_BCW_MAX" pos="2" type="boolean"/>
+		<bitfield name="TRI_CLAMP" low="3" high="4" type="uint"/>
+		<bitfield name="ANISO_BIAS" low="5" high="8" type="fixed" radix="0"/> <!-- radix unknown -->
+		<bitfield name="DIMENSION" low="9" high="10" type="sq_tex_dimension"/>
+		<bitfield name="PACKED_MIPS" pos="11" type="boolean"/>
+		<bitfield name="MIP_ADDRESS" low="12" high="31" type="uint" shr="12"/>
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/adreno/a3xx.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/adreno/a3xx.xml
@@ -0,0 +1,1751 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="adreno/adreno_common.xml"/>
+<import file="adreno/adreno_pm4.xml"/>
+
+<enum name="a3xx_tile_mode">
+	<value name="LINEAR" value="0"/>
+	<value name="TILE_4X4" value="1"/>    <!-- "normal" case for textures -->
+	<value name="TILE_32X32" value="2"/>  <!-- only used in GMEM -->
+	<value name="TILE_4X2" value="3"/>    <!-- only used for CrCb -->
+</enum>
+
+<enum name="a3xx_state_block_id">
+	<value name="HLSQ_BLOCK_ID_TP_TEX" value="2"/>
+	<value name="HLSQ_BLOCK_ID_TP_MIPMAP" value="3"/>
+	<value name="HLSQ_BLOCK_ID_SP_VS" value="4"/>
+	<value name="HLSQ_BLOCK_ID_SP_FS" value="6"/>
+</enum>
+
+<enum name="a3xx_cache_opcode">
+	<value name="INVALIDATE" value="1"/>
+</enum>
+
+<enum name="a3xx_vtx_fmt">
+	<value name="VFMT_32_FLOAT" value="0x0"/>
+	<value name="VFMT_32_32_FLOAT" value="0x1"/>
+	<value name="VFMT_32_32_32_FLOAT" value="0x2"/>
+	<value name="VFMT_32_32_32_32_FLOAT" value="0x3"/>
+
+	<value name="VFMT_16_FLOAT" value="0x4"/>
+	<value name="VFMT_16_16_FLOAT" value="0x5"/>
+	<value name="VFMT_16_16_16_FLOAT" value="0x6"/>
+	<value name="VFMT_16_16_16_16_FLOAT" value="0x7"/>
+
+	<value name="VFMT_32_FIXED" value="0x8"/>
+	<value name="VFMT_32_32_FIXED" value="0x9"/>
+	<value name="VFMT_32_32_32_FIXED" value="0xa"/>
+	<value name="VFMT_32_32_32_32_FIXED" value="0xb"/>
+
+	<value name="VFMT_16_SINT" value="0x10"/>
+	<value name="VFMT_16_16_SINT" value="0x11"/>
+	<value name="VFMT_16_16_16_SINT" value="0x12"/>
+	<value name="VFMT_16_16_16_16_SINT" value="0x13"/>
+	<value name="VFMT_16_UINT" value="0x14"/>
+	<value name="VFMT_16_16_UINT" value="0x15"/>
+	<value name="VFMT_16_16_16_UINT" value="0x16"/>
+	<value name="VFMT_16_16_16_16_UINT" value="0x17"/>
+	<value name="VFMT_16_SNORM" value="0x18"/>
+	<value name="VFMT_16_16_SNORM" value="0x19"/>
+	<value name="VFMT_16_16_16_SNORM" value="0x1a"/>
+	<value name="VFMT_16_16_16_16_SNORM" value="0x1b"/>
+	<value name="VFMT_16_UNORM" value="0x1c"/>
+	<value name="VFMT_16_16_UNORM" value="0x1d"/>
+	<value name="VFMT_16_16_16_UNORM" value="0x1e"/>
+	<value name="VFMT_16_16_16_16_UNORM" value="0x1f"/>
+
+	<!-- seems to be no NORM variants for 32bit.. -->
+	<value name="VFMT_32_UINT" value="0x20"/>
+	<value name="VFMT_32_32_UINT" value="0x21"/>
+	<value name="VFMT_32_32_32_UINT" value="0x22"/>
+	<value name="VFMT_32_32_32_32_UINT" value="0x23"/>
+	<value name="VFMT_32_SINT" value="0x24"/>
+	<value name="VFMT_32_32_SINT" value="0x25"/>
+	<value name="VFMT_32_32_32_SINT" value="0x26"/>
+	<value name="VFMT_32_32_32_32_SINT" value="0x27"/>
+
+	<value name="VFMT_8_UINT" value="0x28"/>
+	<value name="VFMT_8_8_UINT" value="0x29"/>
+	<value name="VFMT_8_8_8_UINT" value="0x2a"/>
+	<value name="VFMT_8_8_8_8_UINT" value="0x2b"/>
+	<value name="VFMT_8_UNORM" value="0x2c"/>
+	<value name="VFMT_8_8_UNORM" value="0x2d"/>
+	<value name="VFMT_8_8_8_UNORM" value="0x2e"/>
+	<value name="VFMT_8_8_8_8_UNORM" value="0x2f"/>
+	<value name="VFMT_8_SINT" value="0x30"/>
+	<value name="VFMT_8_8_SINT" value="0x31"/>
+	<value name="VFMT_8_8_8_SINT" value="0x32"/>
+	<value name="VFMT_8_8_8_8_SINT" value="0x33"/>
+	<value name="VFMT_8_SNORM" value="0x34"/>
+	<value name="VFMT_8_8_SNORM" value="0x35"/>
+	<value name="VFMT_8_8_8_SNORM" value="0x36"/>
+	<value name="VFMT_8_8_8_8_SNORM" value="0x37"/>
+	<value name="VFMT_10_10_10_2_UINT" value="0x38"/>
+	<value name="VFMT_10_10_10_2_UNORM" value="0x39"/>
+	<value name="VFMT_10_10_10_2_SINT" value="0x3a"/>
+	<value name="VFMT_10_10_10_2_SNORM" value="0x3b"/>
+	<value name="VFMT_2_10_10_10_UINT" value="0x3c"/>
+	<value name="VFMT_2_10_10_10_UNORM" value="0x3d"/>
+	<value name="VFMT_2_10_10_10_SINT" value="0x3e"/>
+	<value name="VFMT_2_10_10_10_SNORM" value="0x3f"/>
+
+	<value name="VFMT_NONE" value="0xff"/>
+</enum>
+
+<enum name="a3xx_tex_fmt">
+	<value name="TFMT_5_6_5_UNORM" value="0x4"/>
+	<value name="TFMT_5_5_5_1_UNORM" value="0x5"/>
+	<value name="TFMT_4_4_4_4_UNORM" value="0x7"/>
+	<value name="TFMT_Z16_UNORM" value="0x9"/>
+	<value name="TFMT_X8Z24_UNORM" value="0xa"/>
+	<value name="TFMT_Z32_FLOAT" value="0xb"/>
+
+	<!--
+		The NV12 tiled/linear formats seem to require gang'd sampler
+		slots (ie. sampler state N plus N+1) for Y and UV planes.
+		They fetch yuv in single sam instruction, but still require
+		colorspace conversion in the shader.
+	 -->
+	<value name="TFMT_UV_64X32" value="0x10"/>
+	<value name="TFMT_VU_64X32" value="0x11"/>
+	<value name="TFMT_Y_64X32" value="0x12"/>
+	<value name="TFMT_NV12_64X32" value="0x13"/>
+	<value name="TFMT_UV_LINEAR" value="0x14"/>
+	<value name="TFMT_VU_LINEAR" value="0x15"/>
+	<value name="TFMT_Y_LINEAR" value="0x16"/>
+	<value name="TFMT_NV12_LINEAR" value="0x17"/>
+	<value name="TFMT_I420_Y" value="0x18"/>
+	<value name="TFMT_I420_U" value="0x1a"/>
+	<value name="TFMT_I420_V" value="0x1b"/>
+
+	<value name="TFMT_ATC_RGB" value="0x20"/>
+	<value name="TFMT_ATC_RGBA_EXPLICIT" value="0x21"/>
+	<value name="TFMT_ETC1" value="0x22"/>
+	<value name="TFMT_ATC_RGBA_INTERPOLATED" value="0x23"/>
+
+	<value name="TFMT_DXT1" value="0x24"/>
+	<value name="TFMT_DXT3" value="0x25"/>
+	<value name="TFMT_DXT5" value="0x26"/>
+
+	<value name="TFMT_2_10_10_10_UNORM" value="0x28"/>
+	<value name="TFMT_10_10_10_2_UNORM" value="0x29"/>
+	<value name="TFMT_9_9_9_E5_FLOAT" value="0x2a"/>
+	<value name="TFMT_11_11_10_FLOAT" value="0x2b"/>
+	<value name="TFMT_A8_UNORM" value="0x2c"/>    <!-- GL_ALPHA -->
+	<value name="TFMT_L8_UNORM" value="0x2d"/>
+	<value name="TFMT_L8_A8_UNORM" value="0x2f"/> <!-- GL_LUMINANCE_ALPHA -->
+
+	<!--
+		NOTE: GL_ALPHA and GL_LUMINANCE_ALPHA aren't handled in a similar way
+		to float16, float32.. but they seem to use non-standard swizzle too..
+		perhaps we can ditch that if the pattern follows of 0xn0, 0xn1, 0xn2,
+		0xn3 for 1, 2, 3, 4 components respectively..
+
+		Only formats filled in below are the ones that have been observed by
+		the blob or tested.. you can guess what the missing ones are..
+	 -->
+
+	<value name="TFMT_8_UNORM" value="0x30"/>     <!-- GL_LUMINANCE -->
+	<value name="TFMT_8_8_UNORM" value="0x31"/>
+	<value name="TFMT_8_8_8_UNORM" value="0x32"/>
+	<value name="TFMT_8_8_8_8_UNORM" value="0x33"/>
+
+	<value name="TFMT_8_SNORM" value="0x34"/>
+	<value name="TFMT_8_8_SNORM" value="0x35"/>
+	<value name="TFMT_8_8_8_SNORM" value="0x36"/>
+	<value name="TFMT_8_8_8_8_SNORM" value="0x37"/>
+
+	<value name="TFMT_8_UINT" value="0x38"/>
+	<value name="TFMT_8_8_UINT" value="0x39"/>
+	<value name="TFMT_8_8_8_UINT" value="0x3a"/>
+	<value name="TFMT_8_8_8_8_UINT" value="0x3b"/>
+
+	<value name="TFMT_8_SINT" value="0x3c"/>
+	<value name="TFMT_8_8_SINT" value="0x3d"/>
+	<value name="TFMT_8_8_8_SINT" value="0x3e"/>
+	<value name="TFMT_8_8_8_8_SINT" value="0x3f"/>
+
+	<value name="TFMT_16_FLOAT" value="0x40"/>
+	<value name="TFMT_16_16_FLOAT" value="0x41"/>
+	<!-- TFMT_FLOAT_16_16_16 -->
+	<value name="TFMT_16_16_16_16_FLOAT" value="0x43"/>
+
+	<value name="TFMT_16_UINT" value="0x44"/>
+	<value name="TFMT_16_16_UINT" value="0x45"/>
+	<value name="TFMT_16_16_16_16_UINT" value="0x47"/>
+
+	<value name="TFMT_16_SINT" value="0x48"/>
+	<value name="TFMT_16_16_SINT" value="0x49"/>
+	<value name="TFMT_16_16_16_16_SINT" value="0x4b"/>
+
+	<value name="TFMT_16_UNORM" value="0x4c"/>
+	<value name="TFMT_16_16_UNORM" value="0x4d"/>
+	<value name="TFMT_16_16_16_16_UNORM" value="0x4f"/>
+
+	<value name="TFMT_16_SNORM" value="0x50"/>
+	<value name="TFMT_16_16_SNORM" value="0x51"/>
+	<value name="TFMT_16_16_16_16_SNORM" value="0x53"/>
+
+	<value name="TFMT_32_FLOAT" value="0x54"/>
+	<value name="TFMT_32_32_FLOAT" value="0x55"/>
+	<!-- TFMT_32_32_32_FLOAT -->
+	<value name="TFMT_32_32_32_32_FLOAT" value="0x57"/>
+
+	<value name="TFMT_32_UINT" value="0x58"/>
+	<value name="TFMT_32_32_UINT" value="0x59"/>
+	<value name="TFMT_32_32_32_32_UINT" value="0x5b"/>
+
+	<value name="TFMT_32_SINT" value="0x5c"/>
+	<value name="TFMT_32_32_SINT" value="0x5d"/>
+	<value name="TFMT_32_32_32_32_SINT" value="0x5f"/>
+
+	<value name="TFMT_2_10_10_10_UINT" value="0x60"/>
+	<value name="TFMT_10_10_10_2_UINT" value="0x61"/>
+
+	<value name="TFMT_ETC2_RG11_SNORM" value="0x70"/>
+	<value name="TFMT_ETC2_RG11_UNORM" value="0x71"/>
+	<value name="TFMT_ETC2_R11_SNORM" value="0x72"/>
+	<value name="TFMT_ETC2_R11_UNORM" value="0x73"/>
+	<value name="TFMT_ETC2_RGBA8" value="0x74"/>
+	<value name="TFMT_ETC2_RGB8A1" value="0x75"/>
+	<value name="TFMT_ETC2_RGB8" value="0x76"/>
+
+	<value name="TFMT_NONE" value="0xff"/>
+</enum>
+
+<enum name="a3xx_color_fmt">
+	<value name="RB_R5G6B5_UNORM"       value="0x00"/>
+	<value name="RB_R5G5B5A1_UNORM"     value="0x01"/>
+	<value name="RB_R4G4B4A4_UNORM"     value="0x03"/>
+	<value name="RB_R8G8B8_UNORM"	    value="0x04"/>
+	<value name="RB_R8G8B8A8_UNORM"	    value="0x08"/>
+	<value name="RB_R8G8B8A8_SNORM"	    value="0x09"/>
+	<value name="RB_R8G8B8A8_UINT"	    value="0x0a"/>
+	<value name="RB_R8G8B8A8_SINT"	    value="0x0b"/>
+	<value name="RB_R8G8_UNORM"	    value="0x0c"/>
+	<value name="RB_R8G8_SNORM"	    value="0x0d"/>
+	<value name="RB_R8G8_UINT"	    value="0x0e"/>
+	<value name="RB_R8G8_SINT"	    value="0x0f"/>
+	<value name="RB_R10G10B10A2_UNORM"  value="0x10"/>
+	<value name="RB_A2R10G10B10_UNORM"  value="0x11"/>
+	<value name="RB_R10G10B10A2_UINT"   value="0x12"/>
+	<value name="RB_A2R10G10B10_UINT"   value="0x13"/>
+
+	<value name="RB_A8_UNORM"	    value="0x14"/>
+	<value name="RB_R8_UNORM"	    value="0x15"/>
+
+	<value name="RB_R16_FLOAT"          value="0x18"/>
+	<value name="RB_R16G16_FLOAT"       value="0x19"/>
+	<value name="RB_R16G16B16A16_FLOAT" value="0x1b"/> <!-- GL_HALF_FLOAT_OES -->
+	<value name="RB_R11G11B10_FLOAT"    value="0x1c"/>
+
+	<value name="RB_R16_SNORM"          value="0x20"/>
+	<value name="RB_R16G16_SNORM"       value="0x21"/>
+	<value name="RB_R16G16B16A16_SNORM" value="0x23"/>
+
+	<value name="RB_R16_UNORM"          value="0x24"/>
+	<value name="RB_R16G16_UNORM"       value="0x25"/>
+	<value name="RB_R16G16B16A16_UNORM" value="0x27"/>
+
+	<value name="RB_R16_SINT"	    value="0x28"/>
+	<value name="RB_R16G16_SINT"	    value="0x29"/>
+	<value name="RB_R16G16B16A16_SINT"  value="0x2b"/>
+
+	<value name="RB_R16_UINT"	    value="0x2c"/>
+	<value name="RB_R16G16_UINT"	    value="0x2d"/>
+	<value name="RB_R16G16B16A16_UINT"  value="0x2f"/>
+
+	<value name="RB_R32_FLOAT"          value="0x30"/>
+	<value name="RB_R32G32_FLOAT"       value="0x31"/>
+	<value name="RB_R32G32B32A32_FLOAT" value="0x33"/> <!-- GL_FLOAT -->
+
+	<value name="RB_R32_SINT"	    value="0x34"/>
+	<value name="RB_R32G32_SINT"	    value="0x35"/>
+	<value name="RB_R32G32B32A32_SINT"  value="0x37"/>
+
+	<value name="RB_R32_UINT"	    value="0x38"/>
+	<value name="RB_R32G32_UINT"	    value="0x39"/>
+	<value name="RB_R32G32B32A32_UINT"  value="0x3b"/>
+
+	<value name="RB_NONE"               value="0xff"/>
+</enum>
+
+<enum name="a3xx_cp_perfcounter_select">
+	<value value="0x00" name="CP_ALWAYS_COUNT"/>
+	<value value="0x03" name="CP_AHB_PFPTRANS_WAIT"/>
+	<value value="0x06" name="CP_AHB_NRTTRANS_WAIT"/>
+	<value value="0x08" name="CP_CSF_NRT_READ_WAIT"/>
+	<value value="0x09" name="CP_CSF_I1_FIFO_FULL"/>
+	<value value="0x0a" name="CP_CSF_I2_FIFO_FULL"/>
+	<value value="0x0b" name="CP_CSF_ST_FIFO_FULL"/>
+	<value value="0x0c" name="CP_RESERVED_12"/>
+	<value value="0x0d" name="CP_CSF_RING_ROQ_FULL"/>
+	<value value="0x0e" name="CP_CSF_I1_ROQ_FULL"/>
+	<value value="0x0f" name="CP_CSF_I2_ROQ_FULL"/>
+	<value value="0x10" name="CP_CSF_ST_ROQ_FULL"/>
+	<value value="0x11" name="CP_RESERVED_17"/>
+	<value value="0x12" name="CP_MIU_TAG_MEM_FULL"/>
+	<value value="0x16" name="CP_MIU_NRT_WRITE_STALLED"/>
+	<value value="0x17" name="CP_MIU_NRT_READ_STALLED"/>
+	<value value="0x1a" name="CP_ME_REGS_RB_DONE_FIFO_FULL"/>
+	<value value="0x1b" name="CP_ME_REGS_VS_EVENT_FIFO_FULL"/>
+	<value value="0x1c" name="CP_ME_REGS_PS_EVENT_FIFO_FULL"/>
+	<value value="0x1d" name="CP_ME_REGS_CF_EVENT_FIFO_FULL"/>
+	<value value="0x1e" name="CP_ME_MICRO_RB_STARVED"/>
+	<value value="0x28" name="CP_AHB_RBBM_DWORD_SENT"/>
+	<value value="0x29" name="CP_ME_BUSY_CLOCKS"/>
+	<value value="0x2a" name="CP_ME_WAIT_CONTEXT_AVAIL"/>
+	<value value="0x2b" name="CP_PFP_TYPE0_PACKET"/>
+	<value value="0x2c" name="CP_PFP_TYPE3_PACKET"/>
+	<value value="0x2d" name="CP_CSF_RB_WPTR_NEQ_RPTR"/>
+	<value value="0x2e" name="CP_CSF_I1_SIZE_NEQ_ZERO"/>
+	<value value="0x2f" name="CP_CSF_I2_SIZE_NEQ_ZERO"/>
+	<value value="0x30" name="CP_CSF_RBI1I2_FETCHING"/>
+</enum>
+
+<enum name="a3xx_gras_tse_perfcounter_select">
+	<value value="0x00" name="GRAS_TSEPERF_INPUT_PRIM"/>
+	<value value="0x01" name="GRAS_TSEPERF_INPUT_NULL_PRIM"/>
+	<value value="0x02" name="GRAS_TSEPERF_TRIVAL_REJ_PRIM"/>
+	<value value="0x03" name="GRAS_TSEPERF_CLIPPED_PRIM"/>
+	<value value="0x04" name="GRAS_TSEPERF_NEW_PRIM"/>
+	<value value="0x05" name="GRAS_TSEPERF_ZERO_AREA_PRIM"/>
+	<value value="0x06" name="GRAS_TSEPERF_FACENESS_CULLED_PRIM"/>
+	<value value="0x07" name="GRAS_TSEPERF_ZERO_PIXEL_PRIM"/>
+	<value value="0x08" name="GRAS_TSEPERF_OUTPUT_NULL_PRIM"/>
+	<value value="0x09" name="GRAS_TSEPERF_OUTPUT_VISIBLE_PRIM"/>
+	<value value="0x0a" name="GRAS_TSEPERF_PRE_CLIP_PRIM"/>
+	<value value="0x0b" name="GRAS_TSEPERF_POST_CLIP_PRIM"/>
+	<value value="0x0c" name="GRAS_TSEPERF_WORKING_CYCLES"/>
+	<value value="0x0d" name="GRAS_TSEPERF_PC_STARVE"/>
+	<value value="0x0e" name="GRAS_TSERASPERF_STALL"/>
+</enum>
+
+<enum name="a3xx_gras_ras_perfcounter_select">
+	<value value="0x00" name="GRAS_RASPERF_16X16_TILES"/>
+	<value value="0x01" name="GRAS_RASPERF_8X8_TILES"/>
+	<value value="0x02" name="GRAS_RASPERF_4X4_TILES"/>
+	<value value="0x03" name="GRAS_RASPERF_WORKING_CYCLES"/>
+	<value value="0x04" name="GRAS_RASPERF_STALL_CYCLES_BY_RB"/>
+	<value value="0x05" name="GRAS_RASPERF_STALL_CYCLES_BY_VSC"/>
+	<value value="0x06" name="GRAS_RASPERF_STARVE_CYCLES_BY_TSE"/>
+</enum>
+
+<enum name="a3xx_hlsq_perfcounter_select">
+	<value value="0x00" name="HLSQ_PERF_SP_VS_CONSTANT"/>
+	<value value="0x01" name="HLSQ_PERF_SP_VS_INSTRUCTIONS"/>
+	<value value="0x02" name="HLSQ_PERF_SP_FS_CONSTANT"/>
+	<value value="0x03" name="HLSQ_PERF_SP_FS_INSTRUCTIONS"/>
+	<value value="0x04" name="HLSQ_PERF_TP_STATE"/>
+	<value value="0x05" name="HLSQ_PERF_QUADS"/>
+	<value value="0x06" name="HLSQ_PERF_PIXELS"/>
+	<value value="0x07" name="HLSQ_PERF_VERTICES"/>
+	<value value="0x08" name="HLSQ_PERF_FS8_THREADS"/>
+	<value value="0x09" name="HLSQ_PERF_FS16_THREADS"/>
+	<value value="0x0a" name="HLSQ_PERF_FS32_THREADS"/>
+	<value value="0x0b" name="HLSQ_PERF_VS8_THREADS"/>
+	<value value="0x0c" name="HLSQ_PERF_VS16_THREADS"/>
+	<value value="0x0d" name="HLSQ_PERF_SP_VS_DATA_BYTES"/>
+	<value value="0x0e" name="HLSQ_PERF_SP_FS_DATA_BYTES"/>
+	<value value="0x0f" name="HLSQ_PERF_ACTIVE_CYCLES"/>
+	<value value="0x10" name="HLSQ_PERF_STALL_CYCLES_SP_STATE"/>
+	<value value="0x11" name="HLSQ_PERF_STALL_CYCLES_SP_VS"/>
+	<value value="0x12" name="HLSQ_PERF_STALL_CYCLES_SP_FS"/>
+	<value value="0x13" name="HLSQ_PERF_STALL_CYCLES_UCHE"/>
+	<value value="0x14" name="HLSQ_PERF_RBBM_LOAD_CYCLES"/>
+	<value value="0x15" name="HLSQ_PERF_DI_TO_VS_START_SP0"/>
+	<value value="0x16" name="HLSQ_PERF_DI_TO_FS_START_SP0"/>
+	<value value="0x17" name="HLSQ_PERF_VS_START_TO_DONE_SP0"/>
+	<value value="0x18" name="HLSQ_PERF_FS_START_TO_DONE_SP0"/>
+	<value value="0x19" name="HLSQ_PERF_SP_STATE_COPY_CYCLES_VS"/>
+	<value value="0x1a" name="HLSQ_PERF_SP_STATE_COPY_CYCLES_FS"/>
+	<value value="0x1b" name="HLSQ_PERF_UCHE_LATENCY_CYCLES"/>
+	<value value="0x1c" name="HLSQ_PERF_UCHE_LATENCY_COUNT"/>
+</enum>
+
+<enum name="a3xx_pc_perfcounter_select">
+	<value value="0x00" name="PC_PCPERF_VISIBILITY_STREAMS"/>
+	<value value="0x01" name="PC_PCPERF_TOTAL_INSTANCES"/>
+	<value value="0x02" name="PC_PCPERF_PRIMITIVES_PC_VPC"/>
+	<value value="0x03" name="PC_PCPERF_PRIMITIVES_KILLED_BY_VS"/>
+	<value value="0x04" name="PC_PCPERF_PRIMITIVES_VISIBLE_BY_VS"/>
+	<value value="0x05" name="PC_PCPERF_DRAWCALLS_KILLED_BY_VS"/>
+	<value value="0x06" name="PC_PCPERF_DRAWCALLS_VISIBLE_BY_VS"/>
+	<value value="0x07" name="PC_PCPERF_VERTICES_TO_VFD"/>
+	<value value="0x08" name="PC_PCPERF_REUSED_VERTICES"/>
+	<value value="0x09" name="PC_PCPERF_CYCLES_STALLED_BY_VFD"/>
+	<value value="0x0a" name="PC_PCPERF_CYCLES_STALLED_BY_TSE"/>
+	<value value="0x0b" name="PC_PCPERF_CYCLES_STALLED_BY_VBIF"/>
+	<value value="0x0c" name="PC_PCPERF_CYCLES_IS_WORKING"/>
+</enum>
+
+<enum name="a3xx_rb_perfcounter_select">
+	<value value="0x00" name="RB_RBPERF_ACTIVE_CYCLES_ANY"/>
+	<value value="0x01" name="RB_RBPERF_ACTIVE_CYCLES_ALL"/>
+	<value value="0x02" name="RB_RBPERF_STARVE_CYCLES_BY_SP"/>
+	<value value="0x03" name="RB_RBPERF_STARVE_CYCLES_BY_RAS"/>
+	<value value="0x04" name="RB_RBPERF_STARVE_CYCLES_BY_MARB"/>
+	<value value="0x05" name="RB_RBPERF_STALL_CYCLES_BY_MARB"/>
+	<value value="0x06" name="RB_RBPERF_STALL_CYCLES_BY_HLSQ"/>
+	<value value="0x07" name="RB_RBPERF_RB_MARB_DATA"/>
+	<value value="0x08" name="RB_RBPERF_SP_RB_QUAD"/>
+	<value value="0x09" name="RB_RBPERF_RAS_EARLY_Z_QUADS"/>
+	<value value="0x0a" name="RB_RBPERF_GMEM_CH0_READ"/>
+	<value value="0x0b" name="RB_RBPERF_GMEM_CH1_READ"/>
+	<value value="0x0c" name="RB_RBPERF_GMEM_CH0_WRITE"/>
+	<value value="0x0d" name="RB_RBPERF_GMEM_CH1_WRITE"/>
+	<value value="0x0e" name="RB_RBPERF_CP_CONTEXT_DONE"/>
+	<value value="0x0f" name="RB_RBPERF_CP_CACHE_FLUSH"/>
+	<value value="0x10" name="RB_RBPERF_CP_ZPASS_DONE"/>
+</enum>
+
+<enum name="a3xx_rbbm_perfcounter_select">
+	<value value="0" name="RBBM_ALAWYS_ON"/>
+	<value value="1" name="RBBM_VBIF_BUSY"/>
+	<value value="2" name="RBBM_TSE_BUSY"/>
+	<value value="3" name="RBBM_RAS_BUSY"/>
+	<value value="4" name="RBBM_PC_DCALL_BUSY"/>
+	<value value="5" name="RBBM_PC_VSD_BUSY"/>
+	<value value="6" name="RBBM_VFD_BUSY"/>
+	<value value="7" name="RBBM_VPC_BUSY"/>
+	<value value="8" name="RBBM_UCHE_BUSY"/>
+	<value value="9" name="RBBM_VSC_BUSY"/>
+	<value value="10" name="RBBM_HLSQ_BUSY"/>
+	<value value="11" name="RBBM_ANY_RB_BUSY"/>
+	<value value="12" name="RBBM_ANY_TEX_BUSY"/>
+	<value value="13" name="RBBM_ANY_USP_BUSY"/>
+	<value value="14" name="RBBM_ANY_MARB_BUSY"/>
+	<value value="15" name="RBBM_ANY_ARB_BUSY"/>
+	<value value="16" name="RBBM_AHB_STATUS_BUSY"/>
+	<value value="17" name="RBBM_AHB_STATUS_STALLED"/>
+	<value value="18" name="RBBM_AHB_STATUS_TXFR"/>
+	<value value="19" name="RBBM_AHB_STATUS_TXFR_SPLIT"/>
+	<value value="20" name="RBBM_AHB_STATUS_TXFR_ERROR"/>
+	<value value="21" name="RBBM_AHB_STATUS_LONG_STALL"/>
+	<value value="22" name="RBBM_RBBM_STATUS_MASKED"/>
+</enum>
+
+<enum name="a3xx_sp_perfcounter_select">
+	<value value="0x00" name="SP_LM_LOAD_INSTRUCTIONS"/>
+	<value value="0x01" name="SP_LM_STORE_INSTRUCTIONS"/>
+	<value value="0x02" name="SP_LM_ATOMICS"/>
+	<value value="0x03" name="SP_UCHE_LOAD_INSTRUCTIONS"/>
+	<value value="0x04" name="SP_UCHE_STORE_INSTRUCTIONS"/>
+	<value value="0x05" name="SP_UCHE_ATOMICS"/>
+	<value value="0x06" name="SP_VS_TEX_INSTRUCTIONS"/>
+	<value value="0x07" name="SP_VS_CFLOW_INSTRUCTIONS"/>
+	<value value="0x08" name="SP_VS_EFU_INSTRUCTIONS"/>
+	<value value="0x09" name="SP_VS_FULL_ALU_INSTRUCTIONS"/>
+	<value value="0x0a" name="SP_VS_HALF_ALU_INSTRUCTIONS"/>
+	<value value="0x0b" name="SP_FS_TEX_INSTRUCTIONS"/>
+	<value value="0x0c" name="SP_FS_CFLOW_INSTRUCTIONS"/>
+	<value value="0x0d" name="SP_FS_EFU_INSTRUCTIONS"/>
+	<value value="0x0e" name="SP_FS_FULL_ALU_INSTRUCTIONS"/>
+	<value value="0x0f" name="SP_FS_HALF_ALU_INSTRUCTIONS"/>
+	<value value="0x10" name="SP_FS_BARY_INSTRUCTIONS"/>
+	<value value="0x11" name="SP_VS_INSTRUCTIONS"/>
+	<value value="0x12" name="SP_FS_INSTRUCTIONS"/>
+	<value value="0x13" name="SP_ADDR_LOCK_COUNT"/>
+	<value value="0x14" name="SP_UCHE_READ_TRANS"/>
+	<value value="0x15" name="SP_UCHE_WRITE_TRANS"/>
+	<value value="0x16" name="SP_EXPORT_VPC_TRANS"/>
+	<value value="0x17" name="SP_EXPORT_RB_TRANS"/>
+	<value value="0x18" name="SP_PIXELS_KILLED"/>
+	<value value="0x19" name="SP_ICL1_REQUESTS"/>
+	<value value="0x1a" name="SP_ICL1_MISSES"/>
+	<value value="0x1b" name="SP_ICL0_REQUESTS"/>
+	<value value="0x1c" name="SP_ICL0_MISSES"/>
+	<value value="0x1d" name="SP_ALU_ACTIVE_CYCLES"/>
+	<value value="0x1e" name="SP_EFU_ACTIVE_CYCLES"/>
+	<value value="0x1f" name="SP_STALL_CYCLES_BY_VPC"/>
+	<value value="0x20" name="SP_STALL_CYCLES_BY_TP"/>
+	<value value="0x21" name="SP_STALL_CYCLES_BY_UCHE"/>
+	<value value="0x22" name="SP_STALL_CYCLES_BY_RB"/>
+	<value value="0x23" name="SP_ACTIVE_CYCLES_ANY"/>
+	<value value="0x24" name="SP_ACTIVE_CYCLES_ALL"/>
+</enum>
+
+<enum name="a3xx_tp_perfcounter_select">
+	<value value="0x00" name="TPL1_TPPERF_L1_REQUESTS"/>
+	<value value="0x01" name="TPL1_TPPERF_TP0_L1_REQUESTS"/>
+	<value value="0x02" name="TPL1_TPPERF_TP0_L1_MISSES"/>
+	<value value="0x03" name="TPL1_TPPERF_TP1_L1_REQUESTS"/>
+	<value value="0x04" name="TPL1_TPPERF_TP1_L1_MISSES"/>
+	<value value="0x05" name="TPL1_TPPERF_TP2_L1_REQUESTS"/>
+	<value value="0x06" name="TPL1_TPPERF_TP2_L1_MISSES"/>
+	<value value="0x07" name="TPL1_TPPERF_TP3_L1_REQUESTS"/>
+	<value value="0x08" name="TPL1_TPPERF_TP3_L1_MISSES"/>
+	<value value="0x09" name="TPL1_TPPERF_OUTPUT_TEXELS_POINT"/>
+	<value value="0x0a" name="TPL1_TPPERF_OUTPUT_TEXELS_BILINEAR"/>
+	<value value="0x0b" name="TPL1_TPPERF_OUTPUT_TEXELS_MIP"/>
+	<value value="0x0c" name="TPL1_TPPERF_OUTPUT_TEXELS_ANISO"/>
+	<value value="0x0d" name="TPL1_TPPERF_BILINEAR_OPS"/>
+	<value value="0x0e" name="TPL1_TPPERF_QUADSQUADS_OFFSET"/>
+	<value value="0x0f" name="TPL1_TPPERF_QUADQUADS_SHADOW"/>
+	<value value="0x10" name="TPL1_TPPERF_QUADS_ARRAY"/>
+	<value value="0x11" name="TPL1_TPPERF_QUADS_PROJECTION"/>
+	<value value="0x12" name="TPL1_TPPERF_QUADS_GRADIENT"/>
+	<value value="0x13" name="TPL1_TPPERF_QUADS_1D2D"/>
+	<value value="0x14" name="TPL1_TPPERF_QUADS_3DCUBE"/>
+	<value value="0x15" name="TPL1_TPPERF_ZERO_LOD"/>
+	<value value="0x16" name="TPL1_TPPERF_OUTPUT_TEXELS"/>
+	<value value="0x17" name="TPL1_TPPERF_ACTIVE_CYCLES_ANY"/>
+	<value value="0x18" name="TPL1_TPPERF_ACTIVE_CYCLES_ALL"/>
+	<value value="0x19" name="TPL1_TPPERF_STALL_CYCLES_BY_ARB"/>
+	<value value="0x1a" name="TPL1_TPPERF_LATENCY"/>
+	<value value="0x1b" name="TPL1_TPPERF_LATENCY_TRANS"/>
+</enum>
+
+<enum name="a3xx_vfd_perfcounter_select">
+	<value value="0" name="VFD_PERF_UCHE_BYTE_FETCHED"/>
+	<value value="1" name="VFD_PERF_UCHE_TRANS"/>
+	<value value="2" name="VFD_PERF_VPC_BYPASS_COMPONENTS"/>
+	<value value="3" name="VFD_PERF_FETCH_INSTRUCTIONS"/>
+	<value value="4" name="VFD_PERF_DECODE_INSTRUCTIONS"/>
+	<value value="5" name="VFD_PERF_ACTIVE_CYCLES"/>
+	<value value="6" name="VFD_PERF_STALL_CYCLES_UCHE"/>
+	<value value="7" name="VFD_PERF_STALL_CYCLES_HLSQ"/>
+	<value value="8" name="VFD_PERF_STALL_CYCLES_VPC_BYPASS"/>
+	<value value="9" name="VFD_PERF_STALL_CYCLES_VPC_ALLOC"/>
+</enum>
+
+<enum name="a3xx_vpc_perfcounter_select">
+	<value value="0" name="VPC_PERF_SP_LM_PRIMITIVES"/>
+	<value value="1" name="VPC_PERF_COMPONENTS_FROM_SP"/>
+	<value value="2" name="VPC_PERF_SP_LM_COMPONENTS"/>
+	<value value="3" name="VPC_PERF_ACTIVE_CYCLES"/>
+	<value value="4" name="VPC_PERF_STALL_CYCLES_LM"/>
+	<value value="5" name="VPC_PERF_STALL_CYCLES_RAS"/>
+</enum>
+
+<enum name="a3xx_uche_perfcounter_select">
+	<value value="0x00" name="UCHE_UCHEPERF_VBIF_READ_BEATS_TP"/>
+	<value value="0x01" name="UCHE_UCHEPERF_VBIF_READ_BEATS_VFD"/>
+	<value value="0x02" name="UCHE_UCHEPERF_VBIF_READ_BEATS_HLSQ"/>
+	<value value="0x03" name="UCHE_UCHEPERF_VBIF_READ_BEATS_MARB"/>
+	<value value="0x04" name="UCHE_UCHEPERF_VBIF_READ_BEATS_SP"/>
+	<value value="0x08" name="UCHE_UCHEPERF_READ_REQUESTS_TP"/>
+	<value value="0x09" name="UCHE_UCHEPERF_READ_REQUESTS_VFD"/>
+	<value value="0x0a" name="UCHE_UCHEPERF_READ_REQUESTS_HLSQ"/>
+	<value value="0x0b" name="UCHE_UCHEPERF_READ_REQUESTS_MARB"/>
+	<value value="0x0c" name="UCHE_UCHEPERF_READ_REQUESTS_SP"/>
+	<value value="0x0d" name="UCHE_UCHEPERF_WRITE_REQUESTS_MARB"/>
+	<value value="0x0e" name="UCHE_UCHEPERF_WRITE_REQUESTS_SP"/>
+	<value value="0x0f" name="UCHE_UCHEPERF_TAG_CHECK_FAILS"/>
+	<value value="0x10" name="UCHE_UCHEPERF_EVICTS"/>
+	<value value="0x11" name="UCHE_UCHEPERF_FLUSHES"/>
+	<value value="0x12" name="UCHE_UCHEPERF_VBIF_LATENCY_CYCLES"/>
+	<value value="0x13" name="UCHE_UCHEPERF_VBIF_LATENCY_SAMPLES"/>
+	<value value="0x14" name="UCHE_UCHEPERF_ACTIVE_CYCLES"/>
+</enum>
+
+<enum name="a3xx_intp_mode">
+	<value name="SMOOTH" value="0"/>
+	<value name="FLAT" value="1"/>
+	<value name="ZERO" value="2"/>
+	<value name="ONE" value="3"/>
+</enum>
+
+<enum name="a3xx_repl_mode">
+	<value name="S" value="1"/>
+	<value name="T" value="2"/>
+	<value name="ONE_T" value="3"/>
+</enum>
+
+<domain name="A3XX" width="32">
+	<!-- RBBM registers -->
+	<reg32 offset="0x0000" name="RBBM_HW_VERSION"/>
+	<reg32 offset="0x0001" name="RBBM_HW_RELEASE"/>
+	<reg32 offset="0x0002" name="RBBM_HW_CONFIGURATION"/>
+	<reg32 offset="0x0010" name="RBBM_CLOCK_CTL"/>
+	<reg32 offset="0x0012" name="RBBM_SP_HYST_CNT"/>
+	<reg32 offset="0x0018" name="RBBM_SW_RESET_CMD"/>
+	<reg32 offset="0x0020" name="RBBM_AHB_CTL0"/>
+	<reg32 offset="0x0021" name="RBBM_AHB_CTL1"/>
+	<reg32 offset="0x0022" name="RBBM_AHB_CMD"/>
+	<reg32 offset="0x0027" name="RBBM_AHB_ERROR_STATUS"/>
+	<reg32 offset="0x002e" name="RBBM_GPR0_CTL"/>
+	<reg32 offset="0x0030" name="RBBM_STATUS">
+		<bitfield name="HI_BUSY" pos="0" type="boolean"/>
+		<bitfield name="CP_ME_BUSY" pos="1" type="boolean"/>
+		<bitfield name="CP_PFP_BUSY" pos="2" type="boolean"/>
+		<bitfield name="CP_NRT_BUSY" pos="14" type="boolean"/>
+		<bitfield name="VBIF_BUSY" pos="15" type="boolean"/>
+		<bitfield name="TSE_BUSY" pos="16" type="boolean"/>
+		<bitfield name="RAS_BUSY" pos="17" type="boolean"/>
+		<bitfield name="RB_BUSY" pos="18" type="boolean"/>
+		<bitfield name="PC_DCALL_BUSY" pos="19" type="boolean"/>
+		<bitfield name="PC_VSD_BUSY" pos="20" type="boolean"/>
+		<bitfield name="VFD_BUSY" pos="21" type="boolean"/>
+		<bitfield name="VPC_BUSY" pos="22" type="boolean"/>
+		<bitfield name="UCHE_BUSY" pos="23" type="boolean"/>
+		<bitfield name="SP_BUSY" pos="24" type="boolean"/>
+		<bitfield name="TPL1_BUSY" pos="25" type="boolean"/>
+		<bitfield name="MARB_BUSY" pos="26" type="boolean"/>
+		<bitfield name="VSC_BUSY" pos="27" type="boolean"/>
+		<bitfield name="ARB_BUSY" pos="28" type="boolean"/>
+		<bitfield name="HLSQ_BUSY" pos="29" type="boolean"/>
+		<bitfield name="GPU_BUSY_NOHC" pos="30" type="boolean"/>
+		<bitfield name="GPU_BUSY" pos="31" type="boolean"/>
+	</reg32>
+	<!-- used in fw CP_WAIT_FOR_IDLE, similar to NQWAIT_UNTIL on a2xx: -->
+	<reg32 offset="0x0040" name="RBBM_NQWAIT_UNTIL"/>
+	<reg32 offset="0x0033" name="RBBM_WAIT_IDLE_CLOCKS_CTL"/>
+	<reg32 offset="0x0050" name="RBBM_INTERFACE_HANG_INT_CTL"/>
+	<reg32 offset="0x0051" name="RBBM_INTERFACE_HANG_MASK_CTL0"/>
+	<reg32 offset="0x0054" name="RBBM_INTERFACE_HANG_MASK_CTL1"/>
+	<reg32 offset="0x0057" name="RBBM_INTERFACE_HANG_MASK_CTL2"/>
+	<reg32 offset="0x005a" name="RBBM_INTERFACE_HANG_MASK_CTL3"/>
+
+	<bitset name="A3XX_INT0">
+		<bitfield name="RBBM_GPU_IDLE" pos="0" type="boolean"/>
+		<bitfield name="RBBM_AHB_ERROR" pos="1" type="boolean"/>
+		<bitfield name="RBBM_REG_TIMEOUT" pos="2" type="boolean"/>
+		<bitfield name="RBBM_ME_MS_TIMEOUT" pos="3" type="boolean"/>
+		<bitfield name="RBBM_PFP_MS_TIMEOUT" pos="4" type="boolean"/>
+		<bitfield name="RBBM_ATB_BUS_OVERFLOW" pos="5" type="boolean"/>
+		<bitfield name="VFD_ERROR" pos="6" type="boolean"/>
+		<bitfield name="CP_SW_INT" pos="7" type="boolean"/>
+		<bitfield name="CP_T0_PACKET_IN_IB" pos="8" type="boolean"/>
+		<bitfield name="CP_OPCODE_ERROR" pos="9" type="boolean"/>
+		<bitfield name="CP_RESERVED_BIT_ERROR" pos="10" type="boolean"/>
+		<bitfield name="CP_HW_FAULT" pos="11" type="boolean"/>
+		<bitfield name="CP_DMA" pos="12" type="boolean"/>
+		<bitfield name="CP_IB2_INT" pos="13" type="boolean"/>
+		<bitfield name="CP_IB1_INT" pos="14" type="boolean"/>
+		<bitfield name="CP_RB_INT" pos="15" type="boolean"/>
+		<bitfield name="CP_REG_PROTECT_FAULT" pos="16" type="boolean"/>
+		<bitfield name="CP_RB_DONE_TS" pos="17" type="boolean"/>
+		<bitfield name="CP_VS_DONE_TS" pos="18" type="boolean"/>
+		<bitfield name="CP_PS_DONE_TS" pos="19" type="boolean"/>
+		<bitfield name="CACHE_FLUSH_TS" pos="20" type="boolean"/>
+		<bitfield name="CP_AHB_ERROR_HALT" pos="21" type="boolean"/>
+		<bitfield name="MISC_HANG_DETECT" pos="24" type="boolean"/>
+		<bitfield name="UCHE_OOB_ACCESS" pos="25" type="boolean"/>
+	</bitset>
+
+
+	<!--
+		set in pm4 fw INVALID_JUMP_TABLE_ENTRY and CP_INTERRUPT (compare
+		to CP_INT_STATUS in a2xx firmware), so this seems to be the a3xx
+		way for fw to raise and irq:
+	 -->
+	<reg32 offset="0x0060" name="RBBM_INT_SET_CMD" type="A3XX_INT0"/>
+	<reg32 offset="0x0061" name="RBBM_INT_CLEAR_CMD" type="A3XX_INT0"/>
+	<reg32 offset="0x0063" name="RBBM_INT_0_MASK" type="A3XX_INT0"/>
+	<reg32 offset="0x0064" name="RBBM_INT_0_STATUS" type="A3XX_INT0"/>
+	<reg32 offset="0x0080" name="RBBM_PERFCTR_CTL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0081" name="RBBM_PERFCTR_LOAD_CMD0"/>
+	<reg32 offset="0x0082" name="RBBM_PERFCTR_LOAD_CMD1"/>
+	<reg32 offset="0x0084" name="RBBM_PERFCTR_LOAD_VALUE_LO"/>
+	<reg32 offset="0x0085" name="RBBM_PERFCTR_LOAD_VALUE_HI"/>
+	<reg32 offset="0x0086" name="RBBM_PERFCOUNTER0_SELECT" type="a3xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x0087" name="RBBM_PERFCOUNTER1_SELECT" type="a3xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x0088" name="RBBM_GPU_BUSY_MASKED"/>
+	<reg32 offset="0x0090" name="RBBM_PERFCTR_CP_0_LO"/>
+	<reg32 offset="0x0091" name="RBBM_PERFCTR_CP_0_HI"/>
+	<reg32 offset="0x0092" name="RBBM_PERFCTR_RBBM_0_LO"/>
+	<reg32 offset="0x0093" name="RBBM_PERFCTR_RBBM_0_HI"/>
+	<reg32 offset="0x0094" name="RBBM_PERFCTR_RBBM_1_LO"/>
+	<reg32 offset="0x0095" name="RBBM_PERFCTR_RBBM_1_HI"/>
+	<reg32 offset="0x0096" name="RBBM_PERFCTR_PC_0_LO"/>
+	<reg32 offset="0x0097" name="RBBM_PERFCTR_PC_0_HI"/>
+	<reg32 offset="0x0098" name="RBBM_PERFCTR_PC_1_LO"/>
+	<reg32 offset="0x0099" name="RBBM_PERFCTR_PC_1_HI"/>
+	<reg32 offset="0x009a" name="RBBM_PERFCTR_PC_2_LO"/>
+	<reg32 offset="0x009b" name="RBBM_PERFCTR_PC_2_HI"/>
+	<reg32 offset="0x009c" name="RBBM_PERFCTR_PC_3_LO"/>
+	<reg32 offset="0x009d" name="RBBM_PERFCTR_PC_3_HI"/>
+	<reg32 offset="0x009e" name="RBBM_PERFCTR_VFD_0_LO"/>
+	<reg32 offset="0x009f" name="RBBM_PERFCTR_VFD_0_HI"/>
+	<reg32 offset="0x00a0" name="RBBM_PERFCTR_VFD_1_LO"/>
+	<reg32 offset="0x00a1" name="RBBM_PERFCTR_VFD_1_HI"/>
+	<reg32 offset="0x00a2" name="RBBM_PERFCTR_HLSQ_0_LO"/>
+	<reg32 offset="0x00a3" name="RBBM_PERFCTR_HLSQ_0_HI"/>
+	<reg32 offset="0x00a4" name="RBBM_PERFCTR_HLSQ_1_LO"/>
+	<reg32 offset="0x00a5" name="RBBM_PERFCTR_HLSQ_1_HI"/>
+	<reg32 offset="0x00a6" name="RBBM_PERFCTR_HLSQ_2_LO"/>
+	<reg32 offset="0x00a7" name="RBBM_PERFCTR_HLSQ_2_HI"/>
+	<reg32 offset="0x00a8" name="RBBM_PERFCTR_HLSQ_3_LO"/>
+	<reg32 offset="0x00a9" name="RBBM_PERFCTR_HLSQ_3_HI"/>
+	<reg32 offset="0x00aa" name="RBBM_PERFCTR_HLSQ_4_LO"/>
+	<reg32 offset="0x00ab" name="RBBM_PERFCTR_HLSQ_4_HI"/>
+	<reg32 offset="0x00ac" name="RBBM_PERFCTR_HLSQ_5_LO"/>
+	<reg32 offset="0x00ad" name="RBBM_PERFCTR_HLSQ_5_HI"/>
+	<reg32 offset="0x00ae" name="RBBM_PERFCTR_VPC_0_LO"/>
+	<reg32 offset="0x00af" name="RBBM_PERFCTR_VPC_0_HI"/>
+	<reg32 offset="0x00b0" name="RBBM_PERFCTR_VPC_1_LO"/>
+	<reg32 offset="0x00b1" name="RBBM_PERFCTR_VPC_1_HI"/>
+	<reg32 offset="0x00b2" name="RBBM_PERFCTR_TSE_0_LO"/>
+	<reg32 offset="0x00b3" name="RBBM_PERFCTR_TSE_0_HI"/>
+	<reg32 offset="0x00b4" name="RBBM_PERFCTR_TSE_1_LO"/>
+	<reg32 offset="0x00b5" name="RBBM_PERFCTR_TSE_1_HI"/>
+	<reg32 offset="0x00b6" name="RBBM_PERFCTR_RAS_0_LO"/>
+	<reg32 offset="0x00b7" name="RBBM_PERFCTR_RAS_0_HI"/>
+	<reg32 offset="0x00b8" name="RBBM_PERFCTR_RAS_1_LO"/>
+	<reg32 offset="0x00b9" name="RBBM_PERFCTR_RAS_1_HI"/>
+	<reg32 offset="0x00ba" name="RBBM_PERFCTR_UCHE_0_LO"/>
+	<reg32 offset="0x00bb" name="RBBM_PERFCTR_UCHE_0_HI"/>
+	<reg32 offset="0x00bc" name="RBBM_PERFCTR_UCHE_1_LO"/>
+	<reg32 offset="0x00bd" name="RBBM_PERFCTR_UCHE_1_HI"/>
+	<reg32 offset="0x00be" name="RBBM_PERFCTR_UCHE_2_LO"/>
+	<reg32 offset="0x00bf" name="RBBM_PERFCTR_UCHE_2_HI"/>
+	<reg32 offset="0x00c0" name="RBBM_PERFCTR_UCHE_3_LO"/>
+	<reg32 offset="0x00c1" name="RBBM_PERFCTR_UCHE_3_HI"/>
+	<reg32 offset="0x00c2" name="RBBM_PERFCTR_UCHE_4_LO"/>
+	<reg32 offset="0x00c3" name="RBBM_PERFCTR_UCHE_4_HI"/>
+	<reg32 offset="0x00c4" name="RBBM_PERFCTR_UCHE_5_LO"/>
+	<reg32 offset="0x00c5" name="RBBM_PERFCTR_UCHE_5_HI"/>
+	<reg32 offset="0x00c6" name="RBBM_PERFCTR_TP_0_LO"/>
+	<reg32 offset="0x00c7" name="RBBM_PERFCTR_TP_0_HI"/>
+	<reg32 offset="0x00c8" name="RBBM_PERFCTR_TP_1_LO"/>
+	<reg32 offset="0x00c9" name="RBBM_PERFCTR_TP_1_HI"/>
+	<reg32 offset="0x00ca" name="RBBM_PERFCTR_TP_2_LO"/>
+	<reg32 offset="0x00cb" name="RBBM_PERFCTR_TP_2_HI"/>
+	<reg32 offset="0x00cc" name="RBBM_PERFCTR_TP_3_LO"/>
+	<reg32 offset="0x00cd" name="RBBM_PERFCTR_TP_3_HI"/>
+	<reg32 offset="0x00ce" name="RBBM_PERFCTR_TP_4_LO"/>
+	<reg32 offset="0x00cf" name="RBBM_PERFCTR_TP_4_HI"/>
+	<reg32 offset="0x00d0" name="RBBM_PERFCTR_TP_5_LO"/>
+	<reg32 offset="0x00d1" name="RBBM_PERFCTR_TP_5_HI"/>
+	<reg32 offset="0x00d2" name="RBBM_PERFCTR_SP_0_LO"/>
+	<reg32 offset="0x00d3" name="RBBM_PERFCTR_SP_0_HI"/>
+	<reg32 offset="0x00d4" name="RBBM_PERFCTR_SP_1_LO"/>
+	<reg32 offset="0x00d5" name="RBBM_PERFCTR_SP_1_HI"/>
+	<reg32 offset="0x00d6" name="RBBM_PERFCTR_SP_2_LO"/>
+	<reg32 offset="0x00d7" name="RBBM_PERFCTR_SP_2_HI"/>
+	<reg32 offset="0x00d8" name="RBBM_PERFCTR_SP_3_LO"/>
+	<reg32 offset="0x00d9" name="RBBM_PERFCTR_SP_3_HI"/>
+	<reg32 offset="0x00da" name="RBBM_PERFCTR_SP_4_LO"/>
+	<reg32 offset="0x00db" name="RBBM_PERFCTR_SP_4_HI"/>
+	<reg32 offset="0x00dc" name="RBBM_PERFCTR_SP_5_LO"/>
+	<reg32 offset="0x00dd" name="RBBM_PERFCTR_SP_5_HI"/>
+	<reg32 offset="0x00de" name="RBBM_PERFCTR_SP_6_LO"/>
+	<reg32 offset="0x00df" name="RBBM_PERFCTR_SP_6_HI"/>
+	<reg32 offset="0x00e0" name="RBBM_PERFCTR_SP_7_LO"/>
+	<reg32 offset="0x00e1" name="RBBM_PERFCTR_SP_7_HI"/>
+	<reg32 offset="0x00e2" name="RBBM_PERFCTR_RB_0_LO"/>
+	<reg32 offset="0x00e3" name="RBBM_PERFCTR_RB_0_HI"/>
+	<reg32 offset="0x00e4" name="RBBM_PERFCTR_RB_1_LO"/>
+	<reg32 offset="0x00e5" name="RBBM_PERFCTR_RB_1_HI"/>
+	<reg32 offset="0x00ea" name="RBBM_PERFCTR_PWR_0_LO"/>
+	<reg32 offset="0x00eb" name="RBBM_PERFCTR_PWR_0_HI"/>
+	<reg32 offset="0x00ec" name="RBBM_PERFCTR_PWR_1_LO"/>
+	<reg32 offset="0x00ed" name="RBBM_PERFCTR_PWR_1_HI"/>
+	<reg32 offset="0x0100" name="RBBM_RBBM_CTL"/>
+	<reg32 offset="0x0111" name="RBBM_DEBUG_BUS_CTL"/>
+	<reg32 offset="0x0112" name="RBBM_DEBUG_BUS_DATA_STATUS"/>
+
+	<!-- CP registers -->
+	<reg32 offset="0x01c9" name="CP_PFP_UCODE_ADDR"/>
+	<reg32 offset="0x01ca" name="CP_PFP_UCODE_DATA"/>
+	<reg32 offset="0x01cc" name="CP_ROQ_ADDR"/>
+	<reg32 offset="0x01cd" name="CP_ROQ_DATA"/>
+	<reg32 offset="0x01d1" name="CP_MERCIU_ADDR"/>
+	<reg32 offset="0x01d2" name="CP_MERCIU_DATA"/>
+	<reg32 offset="0x01d3" name="CP_MERCIU_DATA2"/>
+	<!-- see a3xx_snapshot_cp_meq().. looks like the way to dump queue between pfp and pm4 -->
+	<reg32 offset="0x01da" name="CP_MEQ_ADDR"/>
+	<reg32 offset="0x01db" name="CP_MEQ_DATA"/>
+	<reg32 offset="0x01f5" name="CP_WFI_PEND_CTR"/>
+	<reg32 offset="0x039d" name="RBBM_PM_OVERRIDE2"/>
+
+	<reg32 offset="0x0445" name="CP_PERFCOUNTER_SELECT" type="a3xx_cp_perfcounter_select"/>
+	<reg32 offset="0x045c" name="CP_HW_FAULT"/>
+	<reg32 offset="0x045e" name="CP_PROTECT_CTRL"/>
+	<reg32 offset="0x045f" name="CP_PROTECT_STATUS"/>
+	<array offset="0x0460" name="CP_PROTECT" stride="1" length="16">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<reg32 offset="0x054d" name="CP_AHB_FAULT"/>
+
+	<reg32 offset="0x0d00" name="SQ_GPR_MANAGEMENT"/>
+	<reg32 offset="0x0d02" name="SQ_INST_STORE_MANAGMENT"/>
+	<reg32 offset="0x0e1e" name="TP0_CHICKEN"/>
+
+	<!-- these I guess or either SP or HLSQ since related to shader core setup: -->
+	<reg32 offset="0x0e22" name="SP_GLOBAL_MEM_SIZE" type="uint">
+		<doc>
+			The pair of MEM_SIZE/ADDR registers get programmed
+			in sequence with the size/addr of each buffer.
+		</doc>
+	</reg32>
+	<reg32 offset="0x0e23" name="SP_GLOBAL_MEM_ADDR"/>
+
+	<!-- GRAS registers -->
+	<reg32 offset="0x2040" name="GRAS_CL_CLIP_CNTL">
+		<bitfield name="IJ_PERSP_CENTER" pos="12" type="boolean"/>
+		<bitfield name="IJ_NON_PERSP_CENTER" pos="13" type="boolean"/>
+		<bitfield name="IJ_PERSP_CENTROID" pos="14" type="boolean"/>
+		<bitfield name="IJ_NON_PERSP_CENTROID" pos="15" type="boolean"/>
+		<bitfield name="CLIP_DISABLE" pos="16" type="boolean"/>
+		<bitfield name="ZFAR_CLIP_DISABLE" pos="17" type="boolean"/>
+		<bitfield name="VP_CLIP_CODE_IGNORE" pos="19" type="boolean"/>
+		<bitfield name="VP_XFORM_DISABLE" pos="20" type="boolean"/>
+		<bitfield name="PERSP_DIVISION_DISABLE" pos="21" type="boolean"/>
+		<bitfield name="ZERO_GB_SCALE_Z" pos="22" type="boolean">
+			<doc>aka clip_halfz</doc>
+		</bitfield>
+		<!-- set when gl_FragCoord.z is enabled in frag shader: -->
+		<bitfield name="ZCOORD" pos="23" type="boolean"/>
+		<bitfield name="WCOORD" pos="24" type="boolean"/>
+		<!-- set when frag shader writes z (so early z test disabled: -->
+		<bitfield name="ZCLIP_DISABLE" pos="25" type="boolean"/>
+		<bitfield name="NUM_USER_CLIP_PLANES" low="26" high="28" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2044" name="GRAS_CL_GB_CLIP_ADJ">
+		<bitfield name="HORZ" low="0" high="9" type="uint"/>
+		<bitfield name="VERT" low="10" high="19" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2048" name="GRAS_CL_VPORT_XOFFSET" type="float"/>
+	<reg32 offset="0x2049" name="GRAS_CL_VPORT_XSCALE" type="float"/>
+	<reg32 offset="0x204a" name="GRAS_CL_VPORT_YOFFSET" type="float"/>
+	<reg32 offset="0x204b" name="GRAS_CL_VPORT_YSCALE" type="float"/>
+	<reg32 offset="0x204c" name="GRAS_CL_VPORT_ZOFFSET" type="float"/>
+	<reg32 offset="0x204d" name="GRAS_CL_VPORT_ZSCALE" type="float"/>
+	<reg32 offset="0x2068" name="GRAS_SU_POINT_MINMAX">
+		<bitfield name="MIN" low="0" high="15" type="ufixed" radix="4"/>
+		<bitfield name="MAX" low="16" high="31" type="ufixed" radix="4"/>
+	</reg32>
+	<reg32 offset="0x2069" name="GRAS_SU_POINT_SIZE" type="fixed" radix="4"/>
+	<reg32 offset="0x206c" name="GRAS_SU_POLY_OFFSET_SCALE">
+		<bitfield name="VAL" low="0" high="23" type="fixed" radix="20"/>
+		<doc>range of -8.0 to 8.0</doc>
+	</reg32>
+	<reg32 offset="0x206d" name="GRAS_SU_POLY_OFFSET_OFFSET" radix="6" type="fixed">
+		<doc>range of -512.0 to 512.0</doc>
+	</reg32>
+	<reg32 offset="0x2070" name="GRAS_SU_MODE_CONTROL">
+		<bitfield name="CULL_FRONT" pos="0" type="boolean"/>
+		<bitfield name="CULL_BACK" pos="1" type="boolean"/>
+		<bitfield name="FRONT_CW" pos="2" type="boolean"/>
+		<bitfield name="LINEHALFWIDTH" low="3" high="10" radix="2" type="fixed"/>
+		<bitfield name="POLY_OFFSET" pos="11" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2072" name="GRAS_SC_CONTROL">
+		<!-- complete wild-ass-guess for sizes of these bitfields.. -->
+		<bitfield name="RENDER_MODE" low="4" high="7" type="a3xx_render_mode"/>
+		<bitfield name="MSAA_SAMPLES" low="8" high="11" type="a3xx_msaa_samples"/>
+		<bitfield name="RASTER_MODE" low="12" high="15"/>
+	</reg32>
+
+	<reg32 offset="0x2074" name="GRAS_SC_SCREEN_SCISSOR_TL" type="adreno_reg_xy"/>
+	<reg32 offset="0x2075" name="GRAS_SC_SCREEN_SCISSOR_BR" type="adreno_reg_xy"/>
+	<reg32 offset="0x2079" name="GRAS_SC_WINDOW_SCISSOR_TL" type="adreno_reg_xy"/>
+	<reg32 offset="0x207a" name="GRAS_SC_WINDOW_SCISSOR_BR" type="adreno_reg_xy"/>
+
+	<!-- RB registers -->
+	<reg32 offset="0x20c0" name="RB_MODE_CONTROL">
+		<!-- guess on the # of bits here.. -->
+		<bitfield name="GMEM_BYPASS" pos="7" type="boolean"/>
+		<doc>
+			RENDER_MODE is RB_RESOLVE_PASS for gmem->mem, otherwise RB_RENDER_PASS
+		</doc>
+		<bitfield name="RENDER_MODE" low="8" high="10" type="a3xx_render_mode"/>
+		<bitfield name="MRT" low="12" high="13" type="uint">
+			<doc>render targets - 1</doc>
+		</bitfield>
+		<bitfield name="MARB_CACHE_SPLIT_MODE" pos="15" type="boolean"/>
+		<bitfield name="PACKER_TIMER_ENABLE" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x20c1" name="RB_RENDER_CONTROL">
+		<bitfield name="DUAL_COLOR_IN_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="YUV_IN_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="COV_VALUE_INPUT_ENABLE" pos="2" type="boolean"/>
+		<!-- set when gl_FrontFacing is accessed in frag shader: -->
+		<bitfield name="FACENESS" pos="3" type="boolean"/>
+		<bitfield name="BIN_WIDTH" low="4" high="11" shr="5" type="uint"/>
+		<bitfield name="DISABLE_COLOR_PIPE" pos="12" type="boolean"/>
+		<!--
+			ENABLE_GMEM not set on mem2gmem..  so possibly it is actually
+			controlling blend or readback from GMEM??
+		 -->
+		<bitfield name="ENABLE_GMEM" pos="13" type="boolean"/>
+		<bitfield name="COORD_MASK" low="14" high="17" type="hex"/>
+		<bitfield name="I_CLAMP_ENABLE" pos="19" type="boolean"/>
+		<bitfield name="COV_VALUE_OUTPUT_ENABLE" pos="20" type="boolean"/>
+		<bitfield name="ALPHA_TEST" pos="22" type="boolean"/>
+		<bitfield name="ALPHA_TEST_FUNC" low="24" high="26" type="adreno_compare_func"/>
+		<bitfield name="ALPHA_TO_COVERAGE" pos="30" type="boolean"/>
+		<bitfield name="ALPHA_TO_ONE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x20c2" name="RB_MSAA_CONTROL">
+		<bitfield name="DISABLE" pos="10" type="boolean"/>
+		<bitfield name="SAMPLES" low="12" high="15" type="a3xx_msaa_samples"/>
+		<bitfield name="SAMPLE_MASK" low="16" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="0x20c3" name="RB_ALPHA_REF">
+		<bitfield name="UINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<array offset="0x20c4" name="RB_MRT" stride="4" length="4">
+		<reg32 offset="0x0" name="CONTROL">
+			<bitfield name="READ_DEST_ENABLE" pos="3" type="boolean"/>
+			<!-- both these bits seem to get set when enabling GL_BLEND.. -->
+			<bitfield name="BLEND" pos="4" type="boolean"/>
+			<bitfield name="BLEND2" pos="5" type="boolean"/>
+			<bitfield name="ROP_CODE" low="8" high="11" type="a3xx_rop_code"/>
+			<bitfield name="DITHER_MODE" low="12" high="13" type="adreno_rb_dither_mode"/>
+			<bitfield name="COMPONENT_ENABLE" low="24" high="27" type="hex"/>
+		</reg32>
+		<reg32 offset="0x1" name="BUF_INFO">
+			<bitfield name="COLOR_FORMAT" low="0" high="5" type="a3xx_color_fmt"/>
+			<bitfield name="COLOR_TILE_MODE" low="6" high="7" type="a3xx_tile_mode"/>
+			<bitfield name="COLOR_SWAP" low="10" high="11" type="a3xx_color_swap"/>
+			<bitfield name="COLOR_SRGB" pos="14" type="boolean"/>
+			<doc>
+				Pitch (actually, appears to be pitch in bytes, so really is a stride)
+				in GMEM, so pitch of the current tile.
+			</doc>
+			<bitfield name="COLOR_BUF_PITCH" low="17" high="31" shr="5" type="uint"/>
+		</reg32>
+		<reg32 offset="0x2" name="BUF_BASE">
+			<doc>offset into GMEM (or system memory address in bypass mode)</doc>
+			<bitfield name="COLOR_BUF_BASE" low="4" high="31" shr="5" type="hex"/>
+		</reg32>
+		<reg32 offset="0x3" name="BLEND_CONTROL">
+			<bitfield name="RGB_SRC_FACTOR" low="0" high="4" type="adreno_rb_blend_factor"/>
+			<bitfield name="RGB_BLEND_OPCODE" low="5" high="7" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="RGB_DEST_FACTOR" low="8" high="12" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_SRC_FACTOR" low="16" high="20" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_BLEND_OPCODE" low="21" high="23" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="ALPHA_DEST_FACTOR" low="24" high="28" type="adreno_rb_blend_factor"/>
+			<bitfield name="CLAMP_ENABLE" pos="29" type="boolean"/>
+		</reg32>
+	</array>
+
+	<reg32 offset="0x20e4" name="RB_BLEND_RED">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0x20e5" name="RB_BLEND_GREEN">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0x20e6" name="RB_BLEND_BLUE">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0x20e7" name="RB_BLEND_ALPHA">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+
+	<reg32 offset="0x20e8" name="RB_CLEAR_COLOR_DW0"/>
+	<reg32 offset="0x20e9" name="RB_CLEAR_COLOR_DW1"/>
+	<reg32 offset="0x20ea" name="RB_CLEAR_COLOR_DW2"/>
+	<reg32 offset="0x20eb" name="RB_CLEAR_COLOR_DW3"/>
+	<reg32 offset="0x20ec" name="RB_COPY_CONTROL">
+		<!-- not sure # of bits -->
+		<bitfield name="MSAA_RESOLVE" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="DEPTHCLEAR" pos="3" type="boolean"/>
+		<bitfield name="MODE" low="4" high="6" type="adreno_rb_copy_control_mode"/>
+		<bitfield name="MSAA_SRGB_DOWNSAMPLE" pos="7" type="boolean"/>
+		<bitfield name="FASTCLEAR" low="8" high="11" type="hex"/>
+		<bitfield name="DEPTH32_RESOLVE" pos="12" type="boolean"/> <!-- enabled on a Z32F copy -->
+		<bitfield name="GMEM_BASE" low="14" high="31" shr="14" type="hex"/>
+	</reg32>
+	<reg32 offset="0x20ed" name="RB_COPY_DEST_BASE">
+		<bitfield name="BASE" low="4" high="31" shr="5" type="hex"/>
+	</reg32>
+	<reg32 offset="0x20ee" name="RB_COPY_DEST_PITCH">
+		<doc>actually, appears to be pitch in bytes, so really is a stride</doc>
+		<!-- not actually sure about max pitch... -->
+		<bitfield name="PITCH" low="0" high="31" shr="5" type="uint"/>
+	</reg32>
+	<reg32 offset="0x20ef" name="RB_COPY_DEST_INFO">
+		<bitfield name="TILE" low="0" high="1" type="a3xx_tile_mode"/>
+		<bitfield name="FORMAT" low="2" high="7" type="a3xx_color_fmt"/>
+		<bitfield name="SWAP" low="8" high="9" type="a3xx_color_swap"/>
+		<bitfield name="DITHER_MODE" low="10" high="11" type="adreno_rb_dither_mode"/>
+		<bitfield name="COMPONENT_ENABLE" low="14" high="17" type="hex"/>
+		<bitfield name="ENDIAN" low="18" high="20" type="adreno_rb_surface_endian"/>
+	</reg32>
+	<reg32 offset="0x2100" name="RB_DEPTH_CONTROL">
+		<!--
+			guessing that this matches a2xx with the stencil fields
+			moved out into RB_STENCIL_CONTROL?
+		 -->
+		<bitfield name="FRAG_WRITES_Z" pos="0" type="boolean"/>
+		<bitfield name="Z_TEST_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="Z_WRITE_ENABLE" pos="2" type="boolean"/>
+		<bitfield name="EARLY_Z_DISABLE" pos="3" type="boolean"/>
+		<bitfield name="ZFUNC" low="4" high="6" type="adreno_compare_func"/>
+		<bitfield name="Z_CLAMP_ENABLE" pos="7" type="boolean"/>
+		<doc>Z_READ_ENABLE bit is set for zfunc other than GL_ALWAYS or GL_NEVER</doc>
+		<bitfield name="Z_READ_ENABLE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2101" name="RB_DEPTH_CLEAR">
+		<doc>seems to be always set to 0x00000000</doc>
+	</reg32>
+	<reg32 offset="0x2102" name="RB_DEPTH_INFO">
+		<bitfield name="DEPTH_FORMAT" low="0" high="1" type="adreno_rb_depth_format"/>
+		<doc>
+			DEPTH_BASE is offset in GMEM to depth/stencil buffer, ie
+			bin_w * bin_h / 1024 (possible rounded up to multiple of
+			something??  ie. 39 becomes 40, 78 becomes 80.. 75 becomes
+			80.. so maybe it needs to be multiple of 8??
+		</doc>
+		<bitfield name="DEPTH_BASE" low="11" high="31" shr="12" type="hex"/>
+	</reg32>
+	<reg32 offset="0x2103" name="RB_DEPTH_PITCH" shr="3" type="uint">
+		<doc>
+			Pitch of depth buffer or combined depth+stencil buffer
+			in z24s8 cases.
+		</doc>
+	</reg32>
+	<reg32 offset="0x2104" name="RB_STENCIL_CONTROL">
+		<bitfield name="STENCIL_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="STENCIL_ENABLE_BF" pos="1" type="boolean"/>
+		<!--
+			set for stencil operations that require read from stencil
+			buffer, but not for example for stencil clear (which does
+			not require read).. so guessing this is analogous to
+			READ_DEST_ENABLE for color buffer..
+		 -->
+		<bitfield name="STENCIL_READ" pos="2" type="boolean"/>
+		<bitfield name="FUNC" low="8" high="10" type="adreno_compare_func"/>
+		<bitfield name="FAIL" low="11" high="13" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS" low="14" high="16" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL" low="17" high="19" type="adreno_stencil_op"/>
+		<bitfield name="FUNC_BF" low="20" high="22" type="adreno_compare_func"/>
+		<bitfield name="FAIL_BF" low="23" high="25" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS_BF" low="26" high="28" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL_BF" low="29" high="31" type="adreno_stencil_op"/>
+	</reg32>
+	<reg32 offset="0x2105" name="RB_STENCIL_CLEAR">
+		<doc>seems to be always set to 0x00000000</doc>
+	</reg32>
+	<reg32 offset="0x2106" name="RB_STENCIL_INFO">
+		<doc>Base address for stencil when not using interleaved depth/stencil</doc>
+		<bitfield name="STENCIL_BASE" low="11" high="31" shr="12" type="hex"/>
+	</reg32>
+	<reg32 offset="0x2107" name="RB_STENCIL_PITCH" shr="3" type="uint">
+		<doc>pitch of stencil buffer when not using interleaved depth/stencil</doc>
+	</reg32>
+	<reg32 offset="0x2108" name="RB_STENCILREFMASK" type="adreno_rb_stencilrefmask"/>
+	<reg32 offset="0x2109" name="RB_STENCILREFMASK_BF" type="adreno_rb_stencilrefmask"/>
+	<!-- VSC == visibility stream c?? -->
+	<reg32 offset="0x210c" name="RB_LRZ_VSC_CONTROL">
+		<doc>seems to be set to 0x00000002 during binning pass</doc>
+		<bitfield name="BINNING_ENABLE" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x210e" name="RB_WINDOW_OFFSET">
+		<doc>X/Y offset of current bin</doc>
+		<bitfield name="X" low="0" high="15" type="uint"/>
+		<bitfield name="Y" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2110" name="RB_SAMPLE_COUNT_CONTROL">
+		<bitfield name="RESET" pos="0" type="boolean"/>
+		<bitfield name="COPY" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2111" name="RB_SAMPLE_COUNT_ADDR"/>
+	<reg32 offset="0x2114" name="RB_Z_CLAMP_MIN"/>
+	<reg32 offset="0x2115" name="RB_Z_CLAMP_MAX"/>
+
+	<!-- PC registers -->
+	<reg32 offset="0x21e1" name="VGT_BIN_BASE">
+		<doc>
+			seems to be where firmware writes BIN_DATA_ADDR from
+			CP_SET_BIN_DATA packet..  probably should be called
+			PC_BIN_BASE (just using name from yamato for now)
+		</doc>
+	</reg32>
+	<reg32 offset="0x21e2" name="VGT_BIN_SIZE">
+		<doc>probably should be PC_BIN_SIZE</doc>
+	</reg32>
+	<reg32 offset="0x21e4" name="PC_VSTREAM_CONTROL">
+		<doc>SIZE is current pipe width * height (in tiles)</doc>
+		<bitfield name="SIZE" low="16" high="21" type="uint"/>
+		<doc>
+			N is some sort of slot # between 0..(SIZE-1).  In case
+			multiple tiles use same pipe, each tile gets unique slot #
+		</doc>
+		<bitfield name="N" low="22" high="26" type="uint"/>
+	</reg32>
+	<reg32 offset="0x21ea" name="PC_VERTEX_REUSE_BLOCK_CNTL"/>
+	<reg32 offset="0x21ec" name="PC_PRIM_VTX_CNTL">
+		<doc>
+			STRIDE_IN_VPC: ALIGN(next_outloc - 8, 4) / 4
+			(but, in cases where you'd expect 1, the blob driver uses
+			2, so possibly 0 (no varying) or minimum of 2)
+		</doc>
+		<bitfield name="STRIDE_IN_VPC" low="0" high="4" type="uint"/>
+		<bitfield name="POLYMODE_FRONT_PTYPE" low="5" high="7" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="POLYMODE_BACK_PTYPE" low="8" high="10" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="POLYMODE_ENABLE" pos="12" type="boolean"/>
+		<bitfield name="PRIMITIVE_RESTART" pos="20" type="boolean"/>
+		<bitfield name="PROVOKING_VTX_LAST" pos="25" type="boolean"/>
+		<!-- PSIZE bit set if gl_PointSize written: -->
+		<bitfield name="PSIZE" pos="26" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x21ed" name="PC_RESTART_INDEX"/>
+
+	<!-- HLSQ registers -->
+	<bitset name="a3xx_hlsq_vs_fs_control_reg" inline="yes">
+		<bitfield name="CONSTLENGTH" low="0" high="9" type="uint"/>
+		<bitfield name="CONSTSTARTOFFSET" low="12" high="20" type="uint"/>
+		<bitfield name="INSTRLENGTH" low="24" high="31" type="uint"/>
+	</bitset>
+	<bitset name="a3xx_hlsq_const_vs_fs_presv_range_reg" inline="yes">
+		<!-- are these a3xx_regid?? -->
+		<bitfield name="STARTENTRY" low="0" high="8"/>
+		<bitfield name="ENDENTRY" low="16" high="24"/>
+	</bitset>
+
+	<reg32 offset="0x2200" name="HLSQ_CONTROL_0_REG">
+		<bitfield name="FSTHREADSIZE" low="4" high="5" type="a3xx_threadsize"/>
+		<bitfield name="FSSUPERTHREADENABLE" pos="6" type="boolean"/>
+		<bitfield name="COMPUTEMODE" pos="8" type="boolean"/>
+		<bitfield name="SPSHADERRESTART" pos="9" type="boolean"/>
+		<bitfield name="RESERVED2" pos="10" type="boolean"/>
+		<bitfield name="CYCLETIMEOUTLIMITVPC" low="12" high="23" type="uint"/>
+		<bitfield name="FSONLYTEX" pos="25" type="boolean"/>
+		<bitfield name="CHUNKDISABLE" pos="26" type="boolean"/>
+		<bitfield name="CONSTMODE" pos="27" type="uint"/>
+		<bitfield name="LAZYUPDATEDISABLE" pos="28" type="boolean"/>
+		<bitfield name="SPCONSTFULLUPDATE" pos="29" type="boolean"/>
+		<bitfield name="TPFULLUPDATE" pos="30" type="boolean"/>
+		<bitfield name="SINGLECONTEXT" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2201" name="HLSQ_CONTROL_1_REG">
+		<bitfield name="VSTHREADSIZE" low="6" high="7" type="a3xx_threadsize"/>
+		<bitfield name="VSSUPERTHREADENABLE" pos="8" type="boolean"/>
+		<bitfield name="FRAGCOORDXYREGID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="FRAGCOORDZWREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x2202" name="HLSQ_CONTROL_2_REG">
+		<bitfield name="FACENESSREGID" low="2" high="9" type="a3xx_regid"/>
+		<bitfield name="COVVALUEREGID" low="18" high="25" type="a3xx_regid"/>
+		<bitfield name="PRIMALLOCTHRESHOLD" low="26" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2203" name="HLSQ_CONTROL_3_REG">
+		<bitfield name="IJPERSPCENTERREGID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="IJNONPERSPCENTERREGID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="IJPERSPCENTROIDREGID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="IJNONPERSPCENTROIDREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x2204" name="HLSQ_VS_CONTROL_REG" type="a3xx_hlsq_vs_fs_control_reg"/>
+	<reg32 offset="0x2205" name="HLSQ_FS_CONTROL_REG" type="a3xx_hlsq_vs_fs_control_reg"/>
+	<reg32 offset="0x2206" name="HLSQ_CONST_VSPRESV_RANGE_REG" type="a3xx_hlsq_const_vs_fs_presv_range_reg"/>
+	<reg32 offset="0x2207" name="HLSQ_CONST_FSPRESV_RANGE_REG" type="a3xx_hlsq_const_vs_fs_presv_range_reg"/>
+	<reg32 offset="0x220a" name="HLSQ_CL_NDRANGE_0_REG">
+		<bitfield name="WORKDIM" low="0" high="1" type="uint"/>
+		<bitfield name="LOCALSIZE0" low="2" high="11" type="uint"/>
+		<bitfield name="LOCALSIZE1" low="12" high="21" type="uint"/>
+		<bitfield name="LOCALSIZE2" low="22" high="31" type="uint"/>
+	</reg32>
+	<array offset="0x220b" name="HLSQ_CL_GLOBAL_WORK" stride="2" length="3">
+		<doc>indexed by dimension</doc>
+		<reg32 offset="0" name="SIZE" type="uint"/>
+		<reg32 offset="1" name="OFFSET" type="uint"/>
+	</array>
+	<reg32 offset="0x2211" name="HLSQ_CL_CONTROL_0_REG"/>
+	<reg32 offset="0x2212" name="HLSQ_CL_CONTROL_1_REG"/>
+	<reg32 offset="0x2214" name="HLSQ_CL_KERNEL_CONST_REG"/>
+	<array offset="0x2215" name="HLSQ_CL_KERNEL_GROUP" stride="1" length="3">
+		<doc>indexed by dimension, global_size / local_size</doc>
+		<reg32 offset="0" name="RATIO" type="uint"/>
+	</array>
+	<reg32 offset="0x2216" name="HLSQ_CL_KERNEL_GROUP_Y_REG" type="uint"/>
+	<reg32 offset="0x2217" name="HLSQ_CL_KERNEL_GROUP_Z_REG" type="uint"/>
+	<reg32 offset="0x221a" name="HLSQ_CL_WG_OFFSET_REG"/>
+
+	<!-- VFD registers -->
+	<reg32 offset="0x2240" name="VFD_CONTROL_0">
+		<doc>
+			TOTALATTRTOVS is # of attributes to vertex shader, in register
+			slots (ie. vec4+vec3 -> 7)
+		</doc>
+		<bitfield name="TOTALATTRTOVS" low="0" high="17" type="uint"/>
+		<bitfield name="PACKETSIZE" low="18" high="21" type="uint"/>
+		<doc>STRMDECINSTRCNT is # of VFD_DECODE_INSTR registers valid</doc>
+		<bitfield name="STRMDECINSTRCNT" low="22" high="26" type="uint"/>
+		<doc>STRMFETCHINSTRCNT is # of VFD_FETCH_INSTR registers valid</doc>
+		<bitfield name="STRMFETCHINSTRCNT" low="27" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2241" name="VFD_CONTROL_1">
+		<doc>MAXSTORAGE could be # of attributes/vbo's</doc>
+		<bitfield name="MAXSTORAGE" low="0" high="3" type="uint"/>
+		<bitfield name="MAXTHRESHOLD" low="4" high="7" type="uint"/>
+		<bitfield name="MINTHRESHOLD" low="8" high="11" type="uint"/>
+		<bitfield name="REGID4VTX" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="REGID4INST" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x2242" name="VFD_INDEX_MIN" type="uint"/>
+	<reg32 offset="0x2243" name="VFD_INDEX_MAX" type="uint"/>
+	<reg32 offset="0x2244" name="VFD_INSTANCEID_OFFSET" type="uint"/>
+	<reg32 offset="0x2245" name="VFD_INDEX_OFFSET" type="uint"/>
+	<array offset="0x2246" name="VFD_FETCH" stride="2" length="16">
+		<reg32 offset="0x0" name="INSTR_0">
+			<bitfield name="FETCHSIZE" low="0" high="6" type="uint"/>
+			<bitfield name="BUFSTRIDE" low="7" high="15" type="uint"/>
+			<bitfield name="INSTANCED" pos="16" type="boolean"/>
+			<bitfield name="SWITCHNEXT" pos="17" type="boolean"/>
+			<bitfield name="INDEXCODE" low="18" high="23" type="uint"/>
+			<bitfield name="STEPRATE" low="24" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x1" name="INSTR_1"/>
+	</array>
+	<array offset="0x2266" name="VFD_DECODE" stride="1" length="16">
+		<reg32 offset="0x0" name="INSTR">
+			<bitfield name="WRITEMASK" low="0" high="3" type="hex"/>
+			<!-- not sure if this is a bit flag and another flag above it, or?? -->
+			<bitfield name="CONSTFILL" pos="4" type="boolean"/>
+			<bitfield name="FORMAT" low="6" high="11" type="a3xx_vtx_fmt"/>
+			<bitfield name="REGID" low="12" high="19" type="a3xx_regid"/>
+			<bitfield name="INT" pos="20" type="boolean"/>
+			<doc>SHIFTCNT appears to be size, ie. FLOAT_32_32_32 is 12, and BYTE_8 is 1</doc>
+			<bitfield name="SWAP" low="22" high="23" type="a3xx_color_swap"/>
+			<bitfield name="SHIFTCNT" low="24" high="28" type="uint"/>
+			<bitfield name="LASTCOMPVALID" pos="29" type="boolean"/>
+			<bitfield name="SWITCHNEXT" pos="30" type="boolean"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x227e" name="VFD_VS_THREADING_THRESHOLD">
+		<bitfield name="REGID_THRESHOLD" low="0" high="3" type="uint"/>
+		<!-- <bitfield name="RESERVED6" low="4" high="7" type="uint"/> -->
+		<bitfield name="REGID_VTXCNT" low="8" high="15" type="a3xx_regid"/>
+	</reg32>
+
+	<!-- VPC registers -->
+	<reg32 offset="0x2280" name="VPC_ATTR">
+		<bitfield name="TOTALATTR" low="0" high="8" type="uint"/>
+		<!-- PSIZE bit set if gl_PointSize written: -->
+		<bitfield name="PSIZE" pos="9" type="boolean"/>
+		<bitfield name="THRDASSIGN" low="12" high="27" type="uint"/>
+		<bitfield name="LMSIZE" low="28" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2281" name="VPC_PACK">
+		<!-- these are always seem to be set to same as TOTALATTR -->
+		<bitfield name="NUMFPNONPOSVAR" low="8" high="15" type="uint"/>
+		<bitfield name="NUMNONPOSVSVAR" low="16" high="23" type="uint"/>
+	</reg32>
+	<!--
+		varying interpolate mode.  One field per scalar/component
+		(since varying slots are scalar, so things don't have to
+		be aligned to vec4).
+		4 regs * 16 scalar components each => 16 vec4
+	 -->
+	<array offset="0x2282" name="VPC_VARYING_INTERP" stride="1" length="4">
+		<reg32 offset="0x0" name="MODE">
+			<bitfield name="C0" low="0"  high="1"  type="a3xx_intp_mode"/>
+			<bitfield name="C1" low="2"  high="3"  type="a3xx_intp_mode"/>
+			<bitfield name="C2" low="4"  high="5"  type="a3xx_intp_mode"/>
+			<bitfield name="C3" low="6"  high="7"  type="a3xx_intp_mode"/>
+			<bitfield name="C4" low="8"  high="9"  type="a3xx_intp_mode"/>
+			<bitfield name="C5" low="10" high="11" type="a3xx_intp_mode"/>
+			<bitfield name="C6" low="12" high="13" type="a3xx_intp_mode"/>
+			<bitfield name="C7" low="14" high="15" type="a3xx_intp_mode"/>
+			<bitfield name="C8" low="16" high="17" type="a3xx_intp_mode"/>
+			<bitfield name="C9" low="18" high="19" type="a3xx_intp_mode"/>
+			<bitfield name="CA" low="20" high="21" type="a3xx_intp_mode"/>
+			<bitfield name="CB" low="22" high="23" type="a3xx_intp_mode"/>
+			<bitfield name="CC" low="24" high="25" type="a3xx_intp_mode"/>
+			<bitfield name="CD" low="26" high="27" type="a3xx_intp_mode"/>
+			<bitfield name="CE" low="28" high="29" type="a3xx_intp_mode"/>
+			<bitfield name="CF" low="30" high="31" type="a3xx_intp_mode"/>
+		</reg32>
+	</array>
+	<array offset="0x2286" name="VPC_VARYING_PS_REPL" stride="1" length="4">
+		<reg32 offset="0x0" name="MODE">
+			<bitfield name="C0" low="0"  high="1"  type="a3xx_repl_mode"/>
+			<bitfield name="C1" low="2"  high="3"  type="a3xx_repl_mode"/>
+			<bitfield name="C2" low="4"  high="5"  type="a3xx_repl_mode"/>
+			<bitfield name="C3" low="6"  high="7"  type="a3xx_repl_mode"/>
+			<bitfield name="C4" low="8"  high="9"  type="a3xx_repl_mode"/>
+			<bitfield name="C5" low="10" high="11" type="a3xx_repl_mode"/>
+			<bitfield name="C6" low="12" high="13" type="a3xx_repl_mode"/>
+			<bitfield name="C7" low="14" high="15" type="a3xx_repl_mode"/>
+			<bitfield name="C8" low="16" high="17" type="a3xx_repl_mode"/>
+			<bitfield name="C9" low="18" high="19" type="a3xx_repl_mode"/>
+			<bitfield name="CA" low="20" high="21" type="a3xx_repl_mode"/>
+			<bitfield name="CB" low="22" high="23" type="a3xx_repl_mode"/>
+			<bitfield name="CC" low="24" high="25" type="a3xx_repl_mode"/>
+			<bitfield name="CD" low="26" high="27" type="a3xx_repl_mode"/>
+			<bitfield name="CE" low="28" high="29" type="a3xx_repl_mode"/>
+			<bitfield name="CF" low="30" high="31" type="a3xx_repl_mode"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x228a" name="VPC_VARY_CYLWRAP_ENABLE_0"/>
+	<reg32 offset="0x228b" name="VPC_VARY_CYLWRAP_ENABLE_1"/>
+
+	<!-- SP registers -->
+	<bitset name="a3xx_vs_fs_length_reg" inline="yes">
+		<bitfield name="SHADERLENGTH" low="0" high="31" type="uint"/>
+	</bitset>
+
+	<bitset name="sp_vs_fs_obj_offset_reg" inline="yes">
+		<bitfield name="FIRSTEXECINSTROFFSET" low="0" high="15" type="uint"/>
+		<doc>
+			From register spec:
+			SP_FS_OBJ_OFFSET_REG.CONSTOBJECTSTARTOFFSET [16:24]: Constant object
+			start offset in on chip RAM,
+			128bit aligned
+		</doc>
+		<bitfield name="CONSTOBJECTOFFSET" low="16" high="24" type="uint"/>
+		<bitfield name="SHADEROBJOFFSET" low="25" high="31" type="uint"/>
+	</bitset>
+
+	<reg32 offset="0x22c0" name="SP_SP_CTRL_REG">
+		<!-- this bit is set during resolve pass: -->
+		<bitfield name="RESOLVE" pos="16" type="boolean"/>
+		<bitfield name="CONSTMODE" pos="18" type="uint"/>
+		<bitfield name="BINNING" pos="19" type="boolean"/>
+		<bitfield name="SLEEPMODE" low="20" high="21" type="uint"/>
+		<!-- L0MODE==1 when oxiliForceSpL0ModeBuffer=1 -->
+		<bitfield name="L0MODE" low="22" high="23" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22c4" name="SP_VS_CTRL_REG0">
+		<bitfield name="THREADMODE" pos="0" type="a3xx_threadmode"/>
+		<bitfield name="INSTRBUFFERMODE" pos="1" type="a3xx_instrbuffermode"/>
+		<!-- maybe CACHEINVALID is two bits?? -->
+		<bitfield name="CACHEINVALID" pos="2" type="boolean"/>
+		<bitfield name="ALUSCHMODE" pos="3" type="boolean"/>
+		<doc>
+			The full/half register footprint is in units of four components,
+			so if r0.x is used, that counts as all of r0.[xyzw] as used.
+			There are separate full/half register footprint values as the
+			full and half registers are independent (not overlapping).
+			Presumably the thread scheduler hardware allocates the full/half
+			register names from the actual physical register file and
+			handles the register renaming.
+		</doc>
+		<bitfield name="HALFREGFOOTPRINT" low="4" high="9" type="uint"/>
+		<bitfield name="FULLREGFOOTPRINT" low="10" high="15" type="uint"/>
+		<bitfield name="THREADSIZE" pos="20" type="a3xx_threadsize"/>
+		<bitfield name="SUPERTHREADMODE" pos="21" type="boolean"/>
+		<doc>
+			From regspec:
+			SP_FS_CTRL_REG0.FS_LENGTH [31:24]: FS length, unit = 256bits.
+			If bit31 is 1, it means overflow
+			or any long shader.
+		</doc>
+		<bitfield name="LENGTH" low="24" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22c5" name="SP_VS_CTRL_REG1">
+		<bitfield name="CONSTLENGTH" low="0" high="9" type="uint"/>
+		<!--
+			not sure about full vs half const.. I can't get blob generate
+			something with a mediump/lowp uniform.
+		 -->
+		<bitfield name="CONSTFOOTPRINT" low="10" high="19" type="uint"/>
+		<bitfield name="INITIALOUTSTANDING" low="24" high="30" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22c6" name="SP_VS_PARAM_REG">
+		<bitfield name="POSREGID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="PSIZEREGID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="POS2DMODE" pos="16" type="boolean"/>
+		<bitfield name="TOTALVSOUTVAR" low="20" high="24" type="uint"/>
+	</reg32>
+	<array offset="0x22c7" name="SP_VS_OUT" stride="1" length="8">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="A_HALF" pos="8" type="boolean"/>
+			<bitfield name="A_COMPMASK" low="9" high="12" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="23" type="a3xx_regid"/>
+			<bitfield name="B_HALF" pos="24" type="boolean"/>
+			<bitfield name="B_COMPMASK" low="25" high="28" type="hex"/>
+		</reg32>
+	</array>
+	<array offset="0x22d0" name="SP_VS_VPC_DST" stride="1" length="4">
+		<reg32 offset="0x0" name="REG">
+			<doc>
+				These seem to be offsets for storage of the varyings.
+				Always seems to start from 8, possibly loc 0 and 4
+				are for gl_Position and gl_PointSize?
+			</doc>
+			<bitfield name="OUTLOC0" low="0" high="6" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="14" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="22" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="30" type="uint"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x22d4" name="SP_VS_OBJ_OFFSET_REG" type="sp_vs_fs_obj_offset_reg"/>
+	<doc>
+		SP_VS_OBJ_START_REG contains pointer to the vertex shader program,
+		immediately followed by the binning shader program (although I
+		guess that is probably just re-using the same gpu buffer)
+	</doc>
+	<reg32 offset="0x22d5" name="SP_VS_OBJ_START_REG"/>
+	<reg32 offset="0x22d6" name="SP_VS_PVT_MEM_PARAM_REG">
+		<bitfield name="MEMSIZEPERITEM" low="0" high="7" shr="7">
+			<doc>The size of memory that ldp/stp can address, in 128 byte increments.</doc>
+		</bitfield>
+		<bitfield name="HWSTACKOFFSET" low="8" high="23" type="uint"/>
+		<bitfield name="HWSTACKSIZEPERTHREAD" low="24" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22d7" name="SP_VS_PVT_MEM_ADDR_REG">
+		<bitfield name="BURSTLEN" low="0" high="4"/>
+		<bitfield name="SHADERSTARTADDRESS" shr="5" low="5" high="31"/>
+	</reg32>
+	<reg32 offset="0x22d8" name="SP_VS_PVT_MEM_SIZE_REG"/>
+	<reg32 offset="0x22df" name="SP_VS_LENGTH_REG" type="a3xx_vs_fs_length_reg"/>
+	<reg32 offset="0x22e0" name="SP_FS_CTRL_REG0">
+		<bitfield name="THREADMODE" pos="0" type="a3xx_threadmode"/>
+		<bitfield name="INSTRBUFFERMODE" pos="1" type="a3xx_instrbuffermode"/>
+		<!-- maybe CACHEINVALID is two bits?? -->
+		<bitfield name="CACHEINVALID" pos="2" type="boolean"/>
+		<bitfield name="ALUSCHMODE" pos="3" type="boolean"/>
+		<doc>
+			The full/half register footprint is in units of four components,
+			so if r0.x is used, that counts as all of r0.[xyzw] as used.
+			There are separate full/half register footprint values as the
+			full and half registers are independent (not overlapping).
+			Presumably the thread scheduler hardware allocates the full/half
+			register names from the actual physical register file and
+			handles the register renaming.
+		</doc>
+		<bitfield name="HALFREGFOOTPRINT" low="4" high="9" type="uint"/>
+		<bitfield name="FULLREGFOOTPRINT" low="10" high="15" type="uint"/>
+		<bitfield name="FSBYPASSENABLE" pos="17" type="boolean"/>
+		<bitfield name="INOUTREGOVERLAP" pos="18" type="boolean"/>
+		<bitfield name="OUTORDERED" pos="19" type="boolean"/>
+		<bitfield name="THREADSIZE" pos="20" type="a3xx_threadsize"/>
+		<bitfield name="SUPERTHREADMODE" pos="21" type="boolean"/>
+		<bitfield name="PIXLODENABLE" pos="22" type="boolean"/>
+		<bitfield name="COMPUTEMODE" pos="23" type="boolean"/>
+		<doc>
+			From regspec:
+			SP_FS_CTRL_REG0.FS_LENGTH [31:24]: FS length, unit = 256bits.
+			If bit31 is 1, it means overflow
+			or any long shader.
+		</doc>
+		<bitfield name="LENGTH" low="24" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22e1" name="SP_FS_CTRL_REG1">
+		<bitfield name="CONSTLENGTH" low="0" high="9" type="uint"/>
+		<bitfield name="CONSTFOOTPRINT" low="10" high="19" type="uint"/>
+		<bitfield name="INITIALOUTSTANDING" low="20" high="23" type="uint"/>
+		<bitfield name="HALFPRECVAROFFSET" low="24" high="30" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22e2" name="SP_FS_OBJ_OFFSET_REG" type="sp_vs_fs_obj_offset_reg"/>
+	<doc>SP_FS_OBJ_START_REG contains pointer to fragment shader program</doc>
+	<reg32 offset="0x22e3" name="SP_FS_OBJ_START_REG"/>
+	<reg32 offset="0x22e4" name="SP_FS_PVT_MEM_PARAM_REG">
+		<bitfield name="MEMSIZEPERITEM" low="0" high="7" type="uint"/>
+		<bitfield name="HWSTACKOFFSET" low="8" high="23" type="uint"/>
+		<bitfield name="HWSTACKSIZEPERTHREAD" low="24" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22e5" name="SP_FS_PVT_MEM_ADDR_REG">
+		<bitfield name="BURSTLEN" low="0" high="4"/>
+		<bitfield name="SHADERSTARTADDRESS" shr="5" low="5" high="31"/>
+	</reg32>
+	<reg32 offset="0x22e6" name="SP_FS_PVT_MEM_SIZE_REG"/>
+	<reg32 offset="0x22e8" name="SP_FS_FLAT_SHAD_MODE_REG_0">
+		<doc>seems to be one bit per scalar, '1' for flat, '0' for smooth</doc>
+	</reg32>
+	<reg32 offset="0x22e9" name="SP_FS_FLAT_SHAD_MODE_REG_1">
+		<doc>seems to be one bit per scalar, '1' for flat, '0' for smooth</doc>
+	</reg32>
+	<reg32 offset="0x22ec" name="SP_FS_OUTPUT_REG">
+		<bitfield name="MRT" low="0" high="1" type="uint">
+			<doc>render targets - 1</doc>
+		</bitfield>
+		<bitfield name="DEPTH_ENABLE" pos="7" type="boolean"/>
+		<bitfield name="DEPTH_REGID" low="8" high="15" type="a3xx_regid"/>
+	</reg32>
+	<array offset="0x22f0" name="SP_FS_MRT" stride="1" length="4">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="HALF_PRECISION" pos="8" type="boolean"/>
+			<bitfield name="SINT" pos="10" type="boolean"/>
+			<bitfield name="UINT" pos="11" type="boolean"/>
+		</reg32>
+	</array>
+	<array offset="0x22f4" name="SP_FS_IMAGE_OUTPUT" stride="1" length="4">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="MRTFORMAT" low="0" high="5" type="a3xx_color_fmt"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x22ff" name="SP_FS_LENGTH_REG" type="a3xx_vs_fs_length_reg"/>
+
+	<reg32 offset="0x2301" name="PA_SC_AA_CONFIG"/>
+	<!-- TPL1 registers -->
+	<!-- assume VS/FS_TEX_OFFSET is same -->
+	<bitset name="a3xx_tpl1_tp_vs_fs_tex_offset" inline="yes">
+		<bitfield name="SAMPLEROFFSET" low="0" high="7" type="uint"/>
+		<bitfield name="MEMOBJOFFSET" low="8" high="15" type="uint"/>
+		<!-- not sure the size of this: -->
+		<bitfield name="BASETABLEPTR" low="16" high="31" type="uint"/>
+	</bitset>
+	<reg32 offset="0x2340" name="TPL1_TP_VS_TEX_OFFSET" type="a3xx_tpl1_tp_vs_fs_tex_offset"/>
+	<reg32 offset="0x2341" name="TPL1_TP_VS_BORDER_COLOR_BASE_ADDR"/>
+	<reg32 offset="0x2342" name="TPL1_TP_FS_TEX_OFFSET" type="a3xx_tpl1_tp_vs_fs_tex_offset"/>
+	<reg32 offset="0x2343" name="TPL1_TP_FS_BORDER_COLOR_BASE_ADDR"/>
+
+	<!-- VBIF registers -->
+	<reg32 offset="0x3001" name="VBIF_CLKON"/>
+	<reg32 offset="0x300c" name="VBIF_FIXED_SORT_EN"/>
+	<reg32 offset="0x300d" name="VBIF_FIXED_SORT_SEL0"/>
+	<reg32 offset="0x300e" name="VBIF_FIXED_SORT_SEL1"/>
+	<reg32 offset="0x301c" name="VBIF_ABIT_SORT"/>
+	<reg32 offset="0x301d" name="VBIF_ABIT_SORT_CONF"/>
+	<reg32 offset="0x302a" name="VBIF_GATE_OFF_WRREQ_EN"/>
+	<reg32 offset="0x302c" name="VBIF_IN_RD_LIM_CONF0"/>
+	<reg32 offset="0x302d" name="VBIF_IN_RD_LIM_CONF1"/>
+	<reg32 offset="0x3030" name="VBIF_IN_WR_LIM_CONF0"/>
+	<reg32 offset="0x3031" name="VBIF_IN_WR_LIM_CONF1"/>
+	<reg32 offset="0x3034" name="VBIF_OUT_RD_LIM_CONF0"/>
+	<reg32 offset="0x3035" name="VBIF_OUT_WR_LIM_CONF0"/>
+	<reg32 offset="0x3036" name="VBIF_DDR_OUT_MAX_BURST"/>
+	<reg32 offset="0x303c" name="VBIF_ARB_CTL"/>
+	<reg32 offset="0x3049" name="VBIF_ROUND_ROBIN_QOS_ARB"/>
+	<reg32 offset="0x3058" name="VBIF_OUT_AXI_AMEMTYPE_CONF0"/>
+	<reg32 offset="0x305e" name="VBIF_OUT_AXI_AOOO_EN"/>
+	<reg32 offset="0x305f" name="VBIF_OUT_AXI_AOOO"/>
+
+	<bitset name="a3xx_vbif_perf_cnt" inline="yes">
+		<bitfield name="CNT0" pos="0" type="boolean"/>
+		<bitfield name="CNT1" pos="1" type="boolean"/>
+		<bitfield name="PWRCNT0" pos="2" type="boolean"/>
+		<bitfield name="PWRCNT1" pos="3" type="boolean"/>
+		<bitfield name="PWRCNT2" pos="4" type="boolean"/>
+	</bitset>
+
+	<reg32 offset="0x3070" name="VBIF_PERF_CNT_EN" type="a3xx_vbif_perf_cnt"/>
+	<reg32 offset="0x3071" name="VBIF_PERF_CNT_CLR" type="a3xx_vbif_perf_cnt"/>
+	<reg32 offset="0x3072" name="VBIF_PERF_CNT_SEL"/>
+	<reg32 offset="0x3073" name="VBIF_PERF_CNT0_LO"/>
+	<reg32 offset="0x3074" name="VBIF_PERF_CNT0_HI"/>
+	<reg32 offset="0x3075" name="VBIF_PERF_CNT1_LO"/>
+	<reg32 offset="0x3076" name="VBIF_PERF_CNT1_HI"/>
+	<reg32 offset="0x3077" name="VBIF_PERF_PWR_CNT0_LO"/>
+	<reg32 offset="0x3078" name="VBIF_PERF_PWR_CNT0_HI"/>
+	<reg32 offset="0x3079" name="VBIF_PERF_PWR_CNT1_LO"/>
+	<reg32 offset="0x307a" name="VBIF_PERF_PWR_CNT1_HI"/>
+	<reg32 offset="0x307b" name="VBIF_PERF_PWR_CNT2_LO"/>
+	<reg32 offset="0x307c" name="VBIF_PERF_PWR_CNT2_HI"/>
+
+
+	<reg32 offset="0x0c01" name="VSC_BIN_SIZE">
+		<bitfield name="WIDTH" low="0" high="4" shr="5" type="uint"/>
+		<bitfield name="HEIGHT" low="5" high="9" shr="5" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x0c02" name="VSC_SIZE_ADDRESS"/>
+	<array offset="0x0c06" name="VSC_PIPE" stride="3" length="8">
+		<reg32 offset="0x0" name="CONFIG">
+			<doc>
+				Configures the mapping between VSC_PIPE buffer and
+				bin, X/Y specify the bin index in the horiz/vert
+				direction (0,0 is upper left, 0,1 is leftmost bin
+				on second row, and so on).  W/H specify the number
+				of bins assigned to this VSC_PIPE in the horiz/vert
+				dimension.
+			</doc>
+			<bitfield name="X" low="0" high="9" type="uint"/>
+			<bitfield name="Y" low="10" high="19" type="uint"/>
+			<bitfield name="W" low="20" high="23" type="uint"/>
+			<bitfield name="H" low="24" high="27" type="uint"/>
+		</reg32>
+		<reg32 offset="0x1" name="DATA_ADDRESS"/>
+		<reg32 offset="0x2" name="DATA_LENGTH"/>
+	</array>
+	<reg32 offset="0x0c3c" name="VSC_BIN_CONTROL">
+		<doc>seems to be set to 0x00000001 during binning pass</doc>
+		<bitfield name="BINNING_ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0c3d" name="UNKNOWN_0C3D">
+		<doc>seems to be always set to 0x00000001</doc>
+	</reg32>
+	<reg32 offset="0x0c48" name="PC_PERFCOUNTER0_SELECT" type="a3xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0c49" name="PC_PERFCOUNTER1_SELECT" type="a3xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0c4a" name="PC_PERFCOUNTER2_SELECT" type="a3xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0c4b" name="PC_PERFCOUNTER3_SELECT" type="a3xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0c81" name="GRAS_TSE_DEBUG_ECO">
+		<doc>seems to be always set to 0x00000001</doc>
+	</reg32>
+
+	<reg32 offset="0x0c88" name="GRAS_PERFCOUNTER0_SELECT" type="a3xx_gras_tse_perfcounter_select"/>
+	<reg32 offset="0x0c89" name="GRAS_PERFCOUNTER1_SELECT" type="a3xx_gras_tse_perfcounter_select"/>
+	<reg32 offset="0x0c8a" name="GRAS_PERFCOUNTER2_SELECT" type="a3xx_gras_ras_perfcounter_select"/>
+	<reg32 offset="0x0c8b" name="GRAS_PERFCOUNTER3_SELECT" type="a3xx_gras_ras_perfcounter_select"/>
+	<array offset="0x0ca0" name="GRAS_CL_USER_PLANE" stride="4" length="6">
+		<reg32 offset="0x0" name="X"/>
+		<reg32 offset="0x1" name="Y"/>
+		<reg32 offset="0x2" name="Z"/>
+		<reg32 offset="0x3" name="W"/>
+	</array>
+	<reg32 offset="0x0cc0" name="RB_GMEM_BASE_ADDR"/>
+	<reg32 offset="0x0cc1" name="RB_DEBUG_ECO_CONTROLS_ADDR"/>
+	<reg32 offset="0x0cc6" name="RB_PERFCOUNTER0_SELECT" type="a3xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cc7" name="RB_PERFCOUNTER1_SELECT" type="a3xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0ce0" name="RB_FRAME_BUFFER_DIMENSION">
+		<bitfield name="WIDTH" low="0" high="13" type="uint"/>
+		<bitfield name="HEIGHT" low="14" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0e00" name="HLSQ_PERFCOUNTER0_SELECT" type="a3xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e01" name="HLSQ_PERFCOUNTER1_SELECT" type="a3xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e02" name="HLSQ_PERFCOUNTER2_SELECT" type="a3xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e03" name="HLSQ_PERFCOUNTER3_SELECT" type="a3xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e04" name="HLSQ_PERFCOUNTER4_SELECT" type="a3xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e05" name="HLSQ_PERFCOUNTER5_SELECT" type="a3xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e43" name="UNKNOWN_0E43">
+		<doc>seems to be always set to 0x00000001</doc>
+	</reg32>
+	<reg32 offset="0x0e44" name="VFD_PERFCOUNTER0_SELECT" type="a3xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e45" name="VFD_PERFCOUNTER1_SELECT" type="a3xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e61" name="VPC_VPC_DEBUG_RAM_SEL"/>
+	<reg32 offset="0x0e62" name="VPC_VPC_DEBUG_RAM_READ"/>
+	<reg32 offset="0x0e64" name="VPC_PERFCOUNTER0_SELECT" type="a3xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e65" name="VPC_PERFCOUNTER1_SELECT" type="a3xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e82" name="UCHE_CACHE_MODE_CONTROL_REG"/>
+	<reg32 offset="0x0e84" name="UCHE_PERFCOUNTER0_SELECT" type="a3xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e85" name="UCHE_PERFCOUNTER1_SELECT" type="a3xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e86" name="UCHE_PERFCOUNTER2_SELECT" type="a3xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e87" name="UCHE_PERFCOUNTER3_SELECT" type="a3xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e88" name="UCHE_PERFCOUNTER4_SELECT" type="a3xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e89" name="UCHE_PERFCOUNTER5_SELECT" type="a3xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea0" name="UCHE_CACHE_INVALIDATE0_REG">
+		<!-- might be shifted right by 5, assuming 32byte cache line size.. -->
+		<bitfield name="ADDR" low="0" high="27" type="hex"/>
+	</reg32>
+	<reg32 offset="0x0ea1" name="UCHE_CACHE_INVALIDATE1_REG">
+		<!-- might be shifted right by 5, assuming 32byte cache line size.. -->
+		<bitfield name="ADDR" low="0" high="27" type="hex"/>
+		<!-- I'd assume 2 bits, for FLUSH/INVALIDATE/CLEAN? -->
+		<bitfield name="OPCODE" low="28" high="29" type="a3xx_cache_opcode"/>
+		<bitfield name="ENTIRE_CACHE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0ea6" name="UNKNOWN_0EA6"/>
+	<reg32 offset="0x0ec4" name="SP_PERFCOUNTER0_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec5" name="SP_PERFCOUNTER1_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec6" name="SP_PERFCOUNTER2_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec7" name="SP_PERFCOUNTER3_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec8" name="SP_PERFCOUNTER4_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec9" name="SP_PERFCOUNTER5_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0eca" name="SP_PERFCOUNTER6_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ecb" name="SP_PERFCOUNTER7_SELECT" type="a3xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ee0" name="UNKNOWN_0EE0">
+		<doc>seems to be always set to 0x00000003</doc>
+	</reg32>
+	<reg32 offset="0x0f03" name="UNKNOWN_0F03">
+		<doc>seems to be always set to 0x00000001</doc>
+	</reg32>
+	<reg32 offset="0x0f04" name="TP_PERFCOUNTER0_SELECT" type="a3xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f05" name="TP_PERFCOUNTER1_SELECT" type="a3xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f06" name="TP_PERFCOUNTER2_SELECT" type="a3xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f07" name="TP_PERFCOUNTER3_SELECT" type="a3xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f08" name="TP_PERFCOUNTER4_SELECT" type="a3xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f09" name="TP_PERFCOUNTER5_SELECT" type="a3xx_tp_perfcounter_select"/>
+
+	<!-- this seems to be the register that CP_RUN_OPENCL writes: -->
+	<reg32 offset="0x21f0" name="VGT_CL_INITIATOR"/>
+
+	<!-- seems to be same as a2xx according to fwdump.. -->
+	<reg32 offset="0x21f9" name="VGT_EVENT_INITIATOR"/>
+	<reg32 offset="0x21fc" name="VGT_DRAW_INITIATOR" type="vgt_draw_initiator"/>
+	<reg32 offset="0x21fd" name="VGT_IMMED_DATA"/>
+</domain>
+
+<domain name="A3XX_TEX_SAMP" width="32">
+	<doc>Texture sampler dwords</doc>
+	<enum name="a3xx_tex_filter">
+		<value name="A3XX_TEX_NEAREST" value="0"/>
+		<value name="A3XX_TEX_LINEAR" value="1"/>
+		<value name="A3XX_TEX_ANISO" value="2"/>
+	</enum>
+	<enum name="a3xx_tex_clamp">
+		<value name="A3XX_TEX_REPEAT" value="0"/>
+		<value name="A3XX_TEX_CLAMP_TO_EDGE" value="1"/>
+		<value name="A3XX_TEX_MIRROR_REPEAT" value="2"/>
+		<value name="A3XX_TEX_CLAMP_TO_BORDER" value="3"/>
+		<value name="A3XX_TEX_MIRROR_CLAMP" value="4"/>
+	</enum>
+	<enum name="a3xx_tex_aniso">
+		<value name="A3XX_TEX_ANISO_1" value="0"/>
+		<value name="A3XX_TEX_ANISO_2" value="1"/>
+		<value name="A3XX_TEX_ANISO_4" value="2"/>
+		<value name="A3XX_TEX_ANISO_8" value="3"/>
+		<value name="A3XX_TEX_ANISO_16" value="4"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="CLAMPENABLE" pos="0" type="boolean"/>
+		<bitfield name="MIPFILTER_LINEAR" pos="1" type="boolean"/>
+		<bitfield name="XY_MAG" low="2" high="3" type="a3xx_tex_filter"/>
+		<bitfield name="XY_MIN" low="4" high="5" type="a3xx_tex_filter"/>
+		<bitfield name="WRAP_S" low="6" high="8" type="a3xx_tex_clamp"/>
+		<bitfield name="WRAP_T" low="9" high="11" type="a3xx_tex_clamp"/>
+		<bitfield name="WRAP_R" low="12" high="14" type="a3xx_tex_clamp"/>
+		<bitfield name="ANISO" low="15" high="17" type="a3xx_tex_aniso"/>
+		<bitfield name="COMPARE_FUNC" low="20" high="22" type="adreno_compare_func"/>
+		<bitfield name="CUBEMAPSEAMLESSFILTOFF" pos="24" type="boolean"/>
+		<!-- UNNORM_COORDS == CLK_NORMALIZED_COORDS_FALSE -->
+		<bitfield name="UNNORM_COORDS" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="LOD_BIAS" low="0" high="10" type="fixed" radix="6"/>
+		<bitfield name="MAX_LOD" low="12" high="21" type="ufixed" radix="6"/>
+		<bitfield name="MIN_LOD" low="22" high="31" type="ufixed" radix="6"/>
+	</reg32>
+</domain>
+
+<domain name="A3XX_TEX_CONST" width="32">
+	<doc>Texture constant dwords</doc>
+	<enum name="a3xx_tex_swiz">
+		<!-- same as a2xx? -->
+		<value name="A3XX_TEX_X" value="0"/>
+		<value name="A3XX_TEX_Y" value="1"/>
+		<value name="A3XX_TEX_Z" value="2"/>
+		<value name="A3XX_TEX_W" value="3"/>
+		<value name="A3XX_TEX_ZERO" value="4"/>
+		<value name="A3XX_TEX_ONE" value="5"/>
+	</enum>
+	<enum name="a3xx_tex_type">
+		<value name="A3XX_TEX_1D" value="0"/>
+		<value name="A3XX_TEX_2D" value="1"/>
+		<value name="A3XX_TEX_CUBE" value="2"/>
+		<value name="A3XX_TEX_3D" value="3"/>
+	</enum>
+	<enum name="a3xx_tex_msaa">
+		<value name="A3XX_TPL1_MSAA1X" value="0"/>
+		<value name="A3XX_TPL1_MSAA2X" value="1"/>
+		<value name="A3XX_TPL1_MSAA4X" value="2"/>
+		<value name="A3XX_TPL1_MSAA8X" value="3"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="TILE_MODE" low="0" high="1" type="a3xx_tile_mode"/>
+		<bitfield name="SRGB" pos="2" type="boolean"/>
+		<bitfield name="SWIZ_X" low="4" high="6" type="a3xx_tex_swiz"/>
+		<bitfield name="SWIZ_Y" low="7" high="9" type="a3xx_tex_swiz"/>
+		<bitfield name="SWIZ_Z" low="10" high="12" type="a3xx_tex_swiz"/>
+		<bitfield name="SWIZ_W" low="13" high="15" type="a3xx_tex_swiz"/>
+		<bitfield name="MIPLVLS" low="16" high="19" type="uint"/>
+		<bitfield name="MSAATEX" low="20" high="21" type="a3xx_tex_msaa"/>
+		<bitfield name="FMT" low="22" high="28" type="a3xx_tex_fmt"/>
+		<bitfield name="NOCONVERT" pos="29" type="boolean"/>
+		<bitfield name="TYPE" low="30" high="31" type="a3xx_tex_type"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="HEIGHT" low="0" high="13" type="uint"/>
+		<bitfield name="WIDTH" low="14" high="27" type="uint"/>
+		<!-- minimum pitch (for mipmap levels): log2(pitchalign / 16) -->
+		<bitfield name="PITCHALIGN" low="28" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<doc>INDX is index of texture address(es) in MIPMAP state block</doc>
+		<bitfield name="INDX" low="0" high="8" type="uint"/>
+		<doc>Pitch in bytes (so actually stride)</doc>
+		<bitfield name="PITCH" low="12" high="29" type="uint"/>
+		<doc>SWAP bit is set for BGRA instead of RGBA</doc>
+		<bitfield name="SWAP" low="30" high="31" type="a3xx_color_swap"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<!--
+		Update: the two LAYERSZn seem not to be the same thing.
+		According to Ilia's experimentation the first one goes up
+		to at *least* bit 14..
+		 -->
+		<bitfield name="LAYERSZ1" low="0" high="16" shr="12" type="uint"/>
+		<bitfield name="DEPTH" low="17" high="27" type="uint"/>
+		<bitfield name="LAYERSZ2" low="28" high="31" shr="12" type="uint"/>
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/adreno/a4xx.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/adreno/a4xx.xml
@@ -0,0 +1,2409 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="adreno/adreno_common.xml"/>
+<import file="adreno/adreno_pm4.xml"/>
+
+<enum name="a4xx_color_fmt">
+	<value name="RB4_A8_UNORM" value="0x01"/>
+	<value name="RB4_R8_UNORM" value="0x02"/>
+	<value name="RB4_R8_SNORM" value="0x03"/>
+	<value name="RB4_R8_UINT" value="0x04"/>
+	<value name="RB4_R8_SINT" value="0x05"/>
+
+	<value name="RB4_R4G4B4A4_UNORM" value="0x08"/>
+	<value name="RB4_R5G5B5A1_UNORM" value="0x0a"/>
+	<value name="RB4_R5G6B5_UNORM" value="0x0e"/>
+	<value name="RB4_R8G8_UNORM" value="0x0f"/>
+	<value name="RB4_R8G8_SNORM" value="0x10"/>
+	<value name="RB4_R8G8_UINT" value="0x11"/>
+	<value name="RB4_R8G8_SINT" value="0x12"/>
+	<value name="RB4_R16_UNORM" value="0x13"/>
+	<value name="RB4_R16_SNORM" value="0x14"/>
+	<value name="RB4_R16_FLOAT" value="0x15"/>
+	<value name="RB4_R16_UINT" value="0x16"/>
+	<value name="RB4_R16_SINT" value="0x17"/>
+
+	<value name="RB4_R8G8B8_UNORM" value="0x19"/>
+
+	<value name="RB4_R8G8B8A8_UNORM" value="0x1a"/>
+	<value name="RB4_R8G8B8A8_SNORM" value="0x1c"/>
+	<value name="RB4_R8G8B8A8_UINT" value="0x1d"/>
+	<value name="RB4_R8G8B8A8_SINT" value="0x1e"/>
+	<value name="RB4_R10G10B10A2_UNORM" value="0x1f"/>
+	<value name="RB4_R10G10B10A2_UINT" value="0x22"/>
+	<value name="RB4_R11G11B10_FLOAT" value="0x27"/>
+	<value name="RB4_R16G16_UNORM" value="0x28"/>
+	<value name="RB4_R16G16_SNORM" value="0x29"/>
+	<value name="RB4_R16G16_FLOAT" value="0x2a"/>
+	<value name="RB4_R16G16_UINT" value="0x2b"/>
+	<value name="RB4_R16G16_SINT" value="0x2c"/>
+	<value name="RB4_R32_FLOAT" value="0x2d"/>
+	<value name="RB4_R32_UINT" value="0x2e"/>
+	<value name="RB4_R32_SINT" value="0x2f"/>
+
+	<value name="RB4_R16G16B16A16_UNORM" value="0x34"/>
+	<value name="RB4_R16G16B16A16_SNORM" value="0x35"/>
+	<value name="RB4_R16G16B16A16_FLOAT" value="0x36"/>
+	<value name="RB4_R16G16B16A16_UINT" value="0x37"/>
+	<value name="RB4_R16G16B16A16_SINT" value="0x38"/>
+	<value name="RB4_R32G32_FLOAT" value="0x39"/>
+	<value name="RB4_R32G32_UINT" value="0x3a"/>
+	<value name="RB4_R32G32_SINT" value="0x3b"/>
+
+	<value name="RB4_R32G32B32A32_FLOAT" value="0x3c"/>
+	<value name="RB4_R32G32B32A32_UINT" value="0x3d"/>
+	<value name="RB4_R32G32B32A32_SINT" value="0x3e"/>
+
+	<value name="RB4_NONE" value="0xff"/>
+</enum>
+
+<enum name="a4xx_tile_mode">
+	<value name="TILE4_LINEAR" value="0"/>
+	<value name="TILE4_2" value="2"/>
+	<value name="TILE4_3" value="3"/>
+</enum>
+
+<enum name="a4xx_vtx_fmt" prefix="chipset">
+	<!-- hmm, shifted one compared to a3xx?!?  -->
+	<value name="VFMT4_32_FLOAT" value="0x1"/>
+	<value name="VFMT4_32_32_FLOAT" value="0x2"/>
+	<value name="VFMT4_32_32_32_FLOAT" value="0x3"/>
+	<value name="VFMT4_32_32_32_32_FLOAT" value="0x4"/>
+
+	<value name="VFMT4_16_FLOAT" value="0x5"/>
+	<value name="VFMT4_16_16_FLOAT" value="0x6"/>
+	<value name="VFMT4_16_16_16_FLOAT" value="0x7"/>
+	<value name="VFMT4_16_16_16_16_FLOAT" value="0x8"/>
+
+	<value name="VFMT4_32_FIXED" value="0x9"/>
+	<value name="VFMT4_32_32_FIXED" value="0xa"/>
+	<value name="VFMT4_32_32_32_FIXED" value="0xb"/>
+	<value name="VFMT4_32_32_32_32_FIXED" value="0xc"/>
+
+	<value name="VFMT4_11_11_10_FLOAT" value="0xd"/>
+
+	<!-- beyond here it does not appear to be shifted -->
+	<value name="VFMT4_16_SINT" value="0x10"/>
+	<value name="VFMT4_16_16_SINT" value="0x11"/>
+	<value name="VFMT4_16_16_16_SINT" value="0x12"/>
+	<value name="VFMT4_16_16_16_16_SINT" value="0x13"/>
+	<value name="VFMT4_16_UINT" value="0x14"/>
+	<value name="VFMT4_16_16_UINT" value="0x15"/>
+	<value name="VFMT4_16_16_16_UINT" value="0x16"/>
+	<value name="VFMT4_16_16_16_16_UINT" value="0x17"/>
+	<value name="VFMT4_16_SNORM" value="0x18"/>
+	<value name="VFMT4_16_16_SNORM" value="0x19"/>
+	<value name="VFMT4_16_16_16_SNORM" value="0x1a"/>
+	<value name="VFMT4_16_16_16_16_SNORM" value="0x1b"/>
+	<value name="VFMT4_16_UNORM" value="0x1c"/>
+	<value name="VFMT4_16_16_UNORM" value="0x1d"/>
+	<value name="VFMT4_16_16_16_UNORM" value="0x1e"/>
+	<value name="VFMT4_16_16_16_16_UNORM" value="0x1f"/>
+
+	<value name="VFMT4_32_UINT" value="0x20"/>
+	<value name="VFMT4_32_32_UINT" value="0x21"/>
+	<value name="VFMT4_32_32_32_UINT" value="0x22"/>
+	<value name="VFMT4_32_32_32_32_UINT" value="0x23"/>
+	<value name="VFMT4_32_SINT" value="0x24"/>
+	<value name="VFMT4_32_32_SINT" value="0x25"/>
+	<value name="VFMT4_32_32_32_SINT" value="0x26"/>
+	<value name="VFMT4_32_32_32_32_SINT" value="0x27"/>
+
+	<value name="VFMT4_8_UINT" value="0x28"/>
+	<value name="VFMT4_8_8_UINT" value="0x29"/>
+	<value name="VFMT4_8_8_8_UINT" value="0x2a"/>
+	<value name="VFMT4_8_8_8_8_UINT" value="0x2b"/>
+	<value name="VFMT4_8_UNORM" value="0x2c"/>
+	<value name="VFMT4_8_8_UNORM" value="0x2d"/>
+	<value name="VFMT4_8_8_8_UNORM" value="0x2e"/>
+	<value name="VFMT4_8_8_8_8_UNORM" value="0x2f"/>
+	<value name="VFMT4_8_SINT" value="0x30"/>
+	<value name="VFMT4_8_8_SINT" value="0x31"/>
+	<value name="VFMT4_8_8_8_SINT" value="0x32"/>
+	<value name="VFMT4_8_8_8_8_SINT" value="0x33"/>
+	<value name="VFMT4_8_SNORM" value="0x34"/>
+	<value name="VFMT4_8_8_SNORM" value="0x35"/>
+	<value name="VFMT4_8_8_8_SNORM" value="0x36"/>
+	<value name="VFMT4_8_8_8_8_SNORM" value="0x37"/>
+
+	<value name="VFMT4_10_10_10_2_UINT" value="0x38"/>
+	<value name="VFMT4_10_10_10_2_UNORM" value="0x39"/>
+	<value name="VFMT4_10_10_10_2_SINT" value="0x3a"/>
+	<value name="VFMT4_10_10_10_2_SNORM" value="0x3b"/>
+	<value name="VFMT4_2_10_10_10_UINT" value="0x3c"/>
+	<value name="VFMT4_2_10_10_10_UNORM" value="0x3d"/>
+	<value name="VFMT4_2_10_10_10_SINT" value="0x3e"/>
+	<value name="VFMT4_2_10_10_10_SNORM" value="0x3f"/>
+
+	<value name="VFMT4_NONE" value="0xff"/>
+</enum>
+
+<enum name="a4xx_tex_fmt">
+	<!-- 0x00 .. 0x02 -->
+
+	<!-- 8-bit formats -->
+	<value name="TFMT4_A8_UNORM" value="0x03"/>
+	<value name="TFMT4_8_UNORM"  value="0x04"/>
+	<value name="TFMT4_8_SNORM"  value="0x05"/>
+	<value name="TFMT4_8_UINT"   value="0x06"/>
+	<value name="TFMT4_8_SINT"   value="0x07"/>
+
+	<!-- 16-bit formats -->
+	<value name="TFMT4_4_4_4_4_UNORM" value="0x08"/>
+	<value name="TFMT4_5_5_5_1_UNORM" value="0x09"/>
+	<!-- 0x0a -->
+	<value name="TFMT4_5_6_5_UNORM"   value="0x0b"/>
+
+	<!-- 0x0c -->
+
+	<value name="TFMT4_L8_A8_UNORM" value="0x0d"/>
+	<value name="TFMT4_8_8_UNORM"   value="0x0e"/>
+	<value name="TFMT4_8_8_SNORM"   value="0x0f"/>
+	<value name="TFMT4_8_8_UINT"    value="0x10"/>
+	<value name="TFMT4_8_8_SINT"    value="0x11"/>
+
+	<value name="TFMT4_16_UNORM" value="0x12"/>
+	<value name="TFMT4_16_SNORM" value="0x13"/>
+	<value name="TFMT4_16_FLOAT" value="0x14"/>
+	<value name="TFMT4_16_UINT"  value="0x15"/>
+	<value name="TFMT4_16_SINT"  value="0x16"/>
+
+	<!-- 0x17 .. 0x1b -->
+
+	<!-- 32-bit formats -->
+	<value name="TFMT4_8_8_8_8_UNORM" value="0x1c"/>
+	<value name="TFMT4_8_8_8_8_SNORM" value="0x1d"/>
+	<value name="TFMT4_8_8_8_8_UINT"  value="0x1e"/>
+	<value name="TFMT4_8_8_8_8_SINT"  value="0x1f"/>
+
+	<value name="TFMT4_9_9_9_E5_FLOAT"   value="0x20"/>
+	<value name="TFMT4_10_10_10_2_UNORM" value="0x21"/>
+	<value name="TFMT4_10_10_10_2_UINT"  value="0x22"/>
+	<!-- 0x23 .. 0x24 -->
+	<value name="TFMT4_11_11_10_FLOAT"   value="0x25"/>
+
+	<value name="TFMT4_16_16_UNORM" value="0x26"/>
+	<value name="TFMT4_16_16_SNORM" value="0x27"/>
+	<value name="TFMT4_16_16_FLOAT" value="0x28"/>
+	<value name="TFMT4_16_16_UINT"  value="0x29"/>
+	<value name="TFMT4_16_16_SINT"  value="0x2a"/>
+
+	<value name="TFMT4_32_FLOAT" value="0x2b"/>
+	<value name="TFMT4_32_UINT"  value="0x2c"/>
+	<value name="TFMT4_32_SINT"  value="0x2d"/>
+
+	<!-- 0x2e .. 0x32 -->
+
+	<!-- 64-bit formats -->
+	<value name="TFMT4_16_16_16_16_UNORM" value="0x33"/>
+	<value name="TFMT4_16_16_16_16_SNORM" value="0x34"/>
+	<value name="TFMT4_16_16_16_16_FLOAT" value="0x35"/>
+	<value name="TFMT4_16_16_16_16_UINT"  value="0x36"/>
+	<value name="TFMT4_16_16_16_16_SINT"  value="0x37"/>
+
+	<value name="TFMT4_32_32_FLOAT" value="0x38"/>
+	<value name="TFMT4_32_32_UINT"  value="0x39"/>
+	<value name="TFMT4_32_32_SINT"  value="0x3a"/>
+
+	<!-- 96-bit formats -->
+	<value name="TFMT4_32_32_32_FLOAT" value="0x3b"/>
+	<value name="TFMT4_32_32_32_UINT"  value="0x3c"/>
+	<value name="TFMT4_32_32_32_SINT"  value="0x3d"/>
+
+	<!-- 0x3e -->
+
+	<!-- 128-bit formats -->
+	<value name="TFMT4_32_32_32_32_FLOAT" value="0x3f"/>
+	<value name="TFMT4_32_32_32_32_UINT"  value="0x40"/>
+	<value name="TFMT4_32_32_32_32_SINT"  value="0x41"/>
+
+	<!-- 0x42 .. 0x46 -->
+	<value name="TFMT4_X8Z24_UNORM" value="0x47"/>
+	<!-- 0x48 .. 0x55 -->
+
+	<!-- compressed formats -->
+	<value name="TFMT4_DXT1"                  value="0x56"/>
+	<value name="TFMT4_DXT3"                  value="0x57"/>
+	<value name="TFMT4_DXT5"                  value="0x58"/>
+	<!-- 0x59 -->
+	<value name="TFMT4_RGTC1_UNORM"           value="0x5a"/>
+	<value name="TFMT4_RGTC1_SNORM"           value="0x5b"/>
+	<!-- 0x5c .. 0x5d -->
+	<value name="TFMT4_RGTC2_UNORM"           value="0x5e"/>
+	<value name="TFMT4_RGTC2_SNORM"           value="0x5f"/>
+	<!-- 0x60 -->
+	<value name="TFMT4_BPTC_UFLOAT"           value="0x61"/>
+	<value name="TFMT4_BPTC_FLOAT"            value="0x62"/>
+	<value name="TFMT4_BPTC"                  value="0x63"/>
+	<value name="TFMT4_ATC_RGB"               value="0x64"/>
+	<value name="TFMT4_ATC_RGBA_EXPLICIT"     value="0x65"/>
+	<value name="TFMT4_ATC_RGBA_INTERPOLATED" value="0x66"/>
+	<value name="TFMT4_ETC2_RG11_UNORM"       value="0x67"/>
+	<value name="TFMT4_ETC2_RG11_SNORM"       value="0x68"/>
+	<value name="TFMT4_ETC2_R11_UNORM"        value="0x69"/>
+	<value name="TFMT4_ETC2_R11_SNORM"        value="0x6a"/>
+	<value name="TFMT4_ETC1"                  value="0x6b"/>
+	<value name="TFMT4_ETC2_RGB8"             value="0x6c"/>
+	<value name="TFMT4_ETC2_RGBA8"            value="0x6d"/>
+	<value name="TFMT4_ETC2_RGB8A1"           value="0x6e"/>
+	<value name="TFMT4_ASTC_4x4"              value="0x6f"/>
+	<value name="TFMT4_ASTC_5x4"              value="0x70"/>
+	<value name="TFMT4_ASTC_5x5"              value="0x71"/>
+	<value name="TFMT4_ASTC_6x5"              value="0x72"/>
+	<value name="TFMT4_ASTC_6x6"              value="0x73"/>
+	<value name="TFMT4_ASTC_8x5"              value="0x74"/>
+	<value name="TFMT4_ASTC_8x6"              value="0x75"/>
+	<value name="TFMT4_ASTC_8x8"              value="0x76"/>
+	<value name="TFMT4_ASTC_10x5"             value="0x77"/>
+	<value name="TFMT4_ASTC_10x6"             value="0x78"/>
+	<value name="TFMT4_ASTC_10x8"             value="0x79"/>
+	<value name="TFMT4_ASTC_10x10"            value="0x7a"/>
+	<value name="TFMT4_ASTC_12x10"            value="0x7b"/>
+	<value name="TFMT4_ASTC_12x12"            value="0x7c"/>
+	<!-- 0x7d .. 0x7f -->
+
+	<value name="TFMT4_NONE"                  value="0xff"/>
+</enum>
+
+<enum name="a4xx_depth_format">
+	<value name="DEPTH4_NONE" value="0"/>
+	<value name="DEPTH4_16" value="1"/>
+	<value name="DEPTH4_24_8" value="2"/>
+	<value name="DEPTH4_32" value="3"/>
+</enum>
+
+<!--
+NOTE counters extracted from test-perf log with the following awful
+script:
+##################
+#!/bin/bash
+
+log=$1
+
+grep -F "counter
+countable
+group" $log | grep -v gl > shortlist.txt
+
+countable=""
+IFS=$'\n'; for line in $(cat shortlist.txt); do
+	# parse ######### group[$n]: $name
+	l=${line########### group}
+	if [ $l != $line ];  then
+		group=`echo $line | awk '{print $3}'`
+		echo "Group: $group"
+		continue
+	fi
+	# parse #########   counter[$n]: $name
+	l=${line###########   counter}
+	if [ $l != $line ]; then
+		countable=`echo $line | awk '{print $3}'`
+		#echo "  Countable: $countable"
+		continue
+	fi
+	# parse 		countable:
+	l=${line##		countable:}
+	if [ $l != $line ]; then
+		val=`echo $line | awk '{print $2}'`
+		echo "<value value=\"$val\" name=\"$countable\"/>"
+	fi
+
+done
+##################
+ -->
+<enum name="a4xx_ccu_perfcounter_select">
+	<value value="0" name="CCU_BUSY_CYCLES"/>
+	<value value="2" name="CCU_RB_DEPTH_RETURN_STALL"/>
+	<value value="3" name="CCU_RB_COLOR_RETURN_STALL"/>
+	<value value="6" name="CCU_DEPTH_BLOCKS"/>
+	<value value="7" name="CCU_COLOR_BLOCKS"/>
+	<value value="8" name="CCU_DEPTH_BLOCK_HIT"/>
+	<value value="9" name="CCU_COLOR_BLOCK_HIT"/>
+	<value value="10" name="CCU_DEPTH_FLAG1_COUNT"/>
+	<value value="11" name="CCU_DEPTH_FLAG2_COUNT"/>
+	<value value="12" name="CCU_DEPTH_FLAG3_COUNT"/>
+	<value value="13" name="CCU_DEPTH_FLAG4_COUNT"/>
+	<value value="14" name="CCU_COLOR_FLAG1_COUNT"/>
+	<value value="15" name="CCU_COLOR_FLAG2_COUNT"/>
+	<value value="16" name="CCU_COLOR_FLAG3_COUNT"/>
+	<value value="17" name="CCU_COLOR_FLAG4_COUNT"/>
+	<value value="18" name="CCU_PARTIAL_BLOCK_READ"/>
+</enum>
+
+<!--
+NOTE other than CP_ALWAYS_COUNT (which is the only one we use so far),
+on a3xx the countable #'s from AMD_performance_monitor disagreed with
+TRM.  All these #'s for a4xx come from AMD_performance_monitor, so
+perhaps they should be taken with a grain of salt
+-->
+<enum name="a4xx_cp_perfcounter_select">
+	<!-- first ctr at least seems same as a3xx, so we can measure freq -->
+	<value value="0" name="CP_ALWAYS_COUNT"/>
+	<value value="1" name="CP_BUSY"/>
+	<value value="2" name="CP_PFP_IDLE"/>
+	<value value="3" name="CP_PFP_BUSY_WORKING"/>
+	<value value="4" name="CP_PFP_STALL_CYCLES_ANY"/>
+	<value value="5" name="CP_PFP_STARVE_CYCLES_ANY"/>
+	<value value="6" name="CP_PFP_STARVED_PER_LOAD_ADDR"/>
+	<value value="7" name="CP_PFP_STALLED_PER_STORE_ADDR"/>
+	<value value="8" name="CP_PFP_PC_PROFILE"/>
+	<value value="9" name="CP_PFP_MATCH_PM4_PKT_PROFILE"/>
+	<value value="10" name="CP_PFP_COND_INDIRECT_DISCARDED"/>
+	<value value="11" name="CP_LONG_RESUMPTIONS"/>
+	<value value="12" name="CP_RESUME_CYCLES"/>
+	<value value="13" name="CP_RESUME_TO_BOUNDARY_CYCLES"/>
+	<value value="14" name="CP_LONG_PREEMPTIONS"/>
+	<value value="15" name="CP_PREEMPT_CYCLES"/>
+	<value value="16" name="CP_PREEMPT_TO_BOUNDARY_CYCLES"/>
+	<value value="17" name="CP_ME_FIFO_EMPTY_PFP_IDLE"/>
+	<value value="18" name="CP_ME_FIFO_EMPTY_PFP_BUSY"/>
+	<value value="19" name="CP_ME_FIFO_NOT_EMPTY_NOT_FULL"/>
+	<value value="20" name="CP_ME_FIFO_FULL_ME_BUSY"/>
+	<value value="21" name="CP_ME_FIFO_FULL_ME_NON_WORKING"/>
+	<value value="22" name="CP_ME_WAITING_FOR_PACKETS"/>
+	<value value="23" name="CP_ME_BUSY_WORKING"/>
+	<value value="24" name="CP_ME_STARVE_CYCLES_ANY"/>
+	<value value="25" name="CP_ME_STARVE_CYCLES_PER_PROFILE"/>
+	<value value="26" name="CP_ME_STALL_CYCLES_PER_PROFILE"/>
+	<value value="27" name="CP_ME_PC_PROFILE"/>
+	<value value="28" name="CP_RCIU_FIFO_EMPTY"/>
+	<value value="29" name="CP_RCIU_FIFO_NOT_EMPTY_NOT_FULL"/>
+	<value value="30" name="CP_RCIU_FIFO_FULL"/>
+	<value value="31" name="CP_RCIU_FIFO_FULL_NO_CONTEXT"/>
+	<value value="32" name="CP_RCIU_FIFO_FULL_AHB_MASTER"/>
+	<value value="33" name="CP_RCIU_FIFO_FULL_OTHER"/>
+	<value value="34" name="CP_AHB_IDLE"/>
+	<value value="35" name="CP_AHB_STALL_ON_GRANT_NO_SPLIT"/>
+	<value value="36" name="CP_AHB_STALL_ON_GRANT_SPLIT"/>
+	<value value="37" name="CP_AHB_STALL_ON_GRANT_SPLIT_PROFILE"/>
+	<value value="38" name="CP_AHB_BUSY_WORKING"/>
+	<value value="39" name="CP_AHB_BUSY_STALL_ON_HRDY"/>
+	<value value="40" name="CP_AHB_BUSY_STALL_ON_HRDY_PROFILE"/>
+</enum>
+
+<enum name="a4xx_gras_ras_perfcounter_select">
+	<value value="0" name="RAS_SUPER_TILES"/>
+	<value value="1" name="RAS_8X8_TILES"/>
+	<value value="2" name="RAS_4X4_TILES"/>
+	<value value="3" name="RAS_BUSY_CYCLES"/>
+	<value value="4" name="RAS_STALL_CYCLES_BY_RB"/>
+	<value value="5" name="RAS_STALL_CYCLES_BY_VSC"/>
+	<value value="6" name="RAS_STARVE_CYCLES_BY_TSE"/>
+	<value value="7" name="RAS_SUPERTILE_CYCLES"/>
+	<value value="8" name="RAS_TILE_CYCLES"/>
+	<value value="9" name="RAS_FULLY_COVERED_SUPER_TILES"/>
+	<value value="10" name="RAS_FULLY_COVERED_8X8_TILES"/>
+	<value value="11" name="RAS_4X4_PRIM"/>
+	<value value="12" name="RAS_8X4_4X8_PRIM"/>
+	<value value="13" name="RAS_8X8_PRIM"/>
+</enum>
+
+<enum name="a4xx_gras_tse_perfcounter_select">
+	<value value="0" name="TSE_INPUT_PRIM"/>
+	<value value="1" name="TSE_INPUT_NULL_PRIM"/>
+	<value value="2" name="TSE_TRIVAL_REJ_PRIM"/>
+	<value value="3" name="TSE_CLIPPED_PRIM"/>
+	<value value="4" name="TSE_NEW_PRIM"/>
+	<value value="5" name="TSE_ZERO_AREA_PRIM"/>
+	<value value="6" name="TSE_FACENESS_CULLED_PRIM"/>
+	<value value="7" name="TSE_ZERO_PIXEL_PRIM"/>
+	<value value="8" name="TSE_OUTPUT_NULL_PRIM"/>
+	<value value="9" name="TSE_OUTPUT_VISIBLE_PRIM"/>
+	<value value="10" name="TSE_PRE_CLIP_PRIM"/>
+	<value value="11" name="TSE_POST_CLIP_PRIM"/>
+	<value value="12" name="TSE_BUSY_CYCLES"/>
+	<value value="13" name="TSE_PC_STARVE"/>
+	<value value="14" name="TSE_RAS_STALL"/>
+	<value value="15" name="TSE_STALL_BARYPLANE_FIFO_FULL"/>
+	<value value="16" name="TSE_STALL_ZPLANE_FIFO_FULL"/>
+</enum>
+
+<enum name="a4xx_hlsq_perfcounter_select">
+	<value value="0" name="HLSQ_SP_VS_STAGE_CONSTANT"/>
+	<value value="1" name="HLSQ_SP_VS_STAGE_INSTRUCTIONS"/>
+	<value value="2" name="HLSQ_SP_FS_STAGE_CONSTANT"/>
+	<value value="3" name="HLSQ_SP_FS_STAGE_INSTRUCTIONS"/>
+	<value value="4" name="HLSQ_TP_STATE"/>
+	<value value="5" name="HLSQ_QUADS"/>
+	<value value="6" name="HLSQ_PIXELS"/>
+	<value value="7" name="HLSQ_VERTICES"/>
+	<value value="13" name="HLSQ_SP_VS_STAGE_DATA_BYTES"/>
+	<value value="14" name="HLSQ_SP_FS_STAGE_DATA_BYTES"/>
+	<value value="15" name="HLSQ_BUSY_CYCLES"/>
+	<value value="16" name="HLSQ_STALL_CYCLES_SP_STATE"/>
+	<value value="17" name="HLSQ_STALL_CYCLES_SP_VS_STAGE"/>
+	<value value="18" name="HLSQ_STALL_CYCLES_SP_FS_STAGE"/>
+	<value value="19" name="HLSQ_STALL_CYCLES_UCHE"/>
+	<value value="20" name="HLSQ_RBBM_LOAD_CYCLES"/>
+	<value value="21" name="HLSQ_DI_TO_VS_START_SP"/>
+	<value value="22" name="HLSQ_DI_TO_FS_START_SP"/>
+	<value value="23" name="HLSQ_VS_STAGE_START_TO_DONE_SP"/>
+	<value value="24" name="HLSQ_FS_STAGE_START_TO_DONE_SP"/>
+	<value value="25" name="HLSQ_SP_STATE_COPY_CYCLES_VS_STAGE"/>
+	<value value="26" name="HLSQ_SP_STATE_COPY_CYCLES_FS_STAGE"/>
+	<value value="27" name="HLSQ_UCHE_LATENCY_CYCLES"/>
+	<value value="28" name="HLSQ_UCHE_LATENCY_COUNT"/>
+	<value value="29" name="HLSQ_STARVE_CYCLES_VFD"/>
+</enum>
+
+<enum name="a4xx_pc_perfcounter_select">
+	<value value="0" name="PC_VIS_STREAMS_LOADED"/>
+	<value value="2" name="PC_VPC_PRIMITIVES"/>
+	<value value="3" name="PC_DEAD_PRIM"/>
+	<value value="4" name="PC_LIVE_PRIM"/>
+	<value value="5" name="PC_DEAD_DRAWCALLS"/>
+	<value value="6" name="PC_LIVE_DRAWCALLS"/>
+	<value value="7" name="PC_VERTEX_MISSES"/>
+	<value value="9" name="PC_STALL_CYCLES_VFD"/>
+	<value value="10" name="PC_STALL_CYCLES_TSE"/>
+	<value value="11" name="PC_STALL_CYCLES_UCHE"/>
+	<value value="12" name="PC_WORKING_CYCLES"/>
+	<value value="13" name="PC_IA_VERTICES"/>
+	<value value="14" name="PC_GS_PRIMITIVES"/>
+	<value value="15" name="PC_HS_INVOCATIONS"/>
+	<value value="16" name="PC_DS_INVOCATIONS"/>
+	<value value="17" name="PC_DS_PRIMITIVES"/>
+	<value value="20" name="PC_STARVE_CYCLES_FOR_INDEX"/>
+	<value value="21" name="PC_STARVE_CYCLES_FOR_TESS_FACTOR"/>
+	<value value="22" name="PC_STARVE_CYCLES_FOR_VIZ_STREAM"/>
+	<value value="23" name="PC_STALL_CYCLES_TESS"/>
+	<value value="24" name="PC_STARVE_CYCLES_FOR_POSITION"/>
+	<value value="25" name="PC_MODE0_DRAWCALL"/>
+	<value value="26" name="PC_MODE1_DRAWCALL"/>
+	<value value="27" name="PC_MODE2_DRAWCALL"/>
+	<value value="28" name="PC_MODE3_DRAWCALL"/>
+	<value value="29" name="PC_MODE4_DRAWCALL"/>
+	<value value="30" name="PC_PREDICATED_DEAD_DRAWCALL"/>
+	<value value="31" name="PC_STALL_CYCLES_BY_TSE_ONLY"/>
+	<value value="32" name="PC_STALL_CYCLES_BY_VPC_ONLY"/>
+	<value value="33" name="PC_VPC_POS_DATA_TRANSACTION"/>
+	<value value="34" name="PC_BUSY_CYCLES"/>
+	<value value="35" name="PC_STARVE_CYCLES_DI"/>
+	<value value="36" name="PC_STALL_CYCLES_VPC"/>
+	<value value="37" name="TESS_WORKING_CYCLES"/>
+	<value value="38" name="TESS_NUM_CYCLES_SETUP_WORKING"/>
+	<value value="39" name="TESS_NUM_CYCLES_PTGEN_WORKING"/>
+	<value value="40" name="TESS_NUM_CYCLES_CONNGEN_WORKING"/>
+	<value value="41" name="TESS_BUSY_CYCLES"/>
+	<value value="42" name="TESS_STARVE_CYCLES_PC"/>
+	<value value="43" name="TESS_STALL_CYCLES_PC"/>
+</enum>
+
+<enum name="a4xx_pwr_perfcounter_select">
+	<!-- NOTE not actually used.. see RBBM_RBBM_CTL.RESET_PWR_CTR0/1 -->
+	<value value="0" name="PWR_CORE_CLOCK_CYCLES"/>
+	<value value="1" name="PWR_BUSY_CLOCK_CYCLES"/>
+</enum>
+
+<enum name="a4xx_rb_perfcounter_select">
+	<value value="0" name="RB_BUSY_CYCLES"/>
+	<value value="1" name="RB_BUSY_CYCLES_BINNING"/>
+	<value value="2" name="RB_BUSY_CYCLES_RENDERING"/>
+	<value value="3" name="RB_BUSY_CYCLES_RESOLVE"/>
+	<value value="4" name="RB_STARVE_CYCLES_BY_SP"/>
+	<value value="5" name="RB_STARVE_CYCLES_BY_RAS"/>
+	<value value="6" name="RB_STARVE_CYCLES_BY_MARB"/>
+	<value value="7" name="RB_STALL_CYCLES_BY_MARB"/>
+	<value value="8" name="RB_STALL_CYCLES_BY_HLSQ"/>
+	<value value="9" name="RB_RB_RB_MARB_DATA"/>
+	<value value="10" name="RB_SP_RB_QUAD"/>
+	<value value="11" name="RB_RAS_RB_Z_QUADS"/>
+	<value value="12" name="RB_GMEM_CH0_READ"/>
+	<value value="13" name="RB_GMEM_CH1_READ"/>
+	<value value="14" name="RB_GMEM_CH0_WRITE"/>
+	<value value="15" name="RB_GMEM_CH1_WRITE"/>
+	<value value="16" name="RB_CP_CONTEXT_DONE"/>
+	<value value="17" name="RB_CP_CACHE_FLUSH"/>
+	<value value="18" name="RB_CP_ZPASS_DONE"/>
+	<value value="19" name="RB_STALL_FIFO0_FULL"/>
+	<value value="20" name="RB_STALL_FIFO1_FULL"/>
+	<value value="21" name="RB_STALL_FIFO2_FULL"/>
+	<value value="22" name="RB_STALL_FIFO3_FULL"/>
+	<value value="23" name="RB_RB_HLSQ_TRANSACTIONS"/>
+	<value value="24" name="RB_Z_READ"/>
+	<value value="25" name="RB_Z_WRITE"/>
+	<value value="26" name="RB_C_READ"/>
+	<value value="27" name="RB_C_WRITE"/>
+	<value value="28" name="RB_C_READ_LATENCY"/>
+	<value value="29" name="RB_Z_READ_LATENCY"/>
+	<value value="30" name="RB_STALL_BY_UCHE"/>
+	<value value="31" name="RB_MARB_UCHE_TRANSACTIONS"/>
+	<value value="32" name="RB_CACHE_STALL_MISS"/>
+	<value value="33" name="RB_CACHE_STALL_FIFO_FULL"/>
+	<value value="34" name="RB_8BIT_BLENDER_UNITS_ACTIVE"/>
+	<value value="35" name="RB_16BIT_BLENDER_UNITS_ACTIVE"/>
+	<value value="36" name="RB_SAMPLER_UNITS_ACTIVE"/>
+	<value value="38" name="RB_TOTAL_PASS"/>
+	<value value="39" name="RB_Z_PASS"/>
+	<value value="40" name="RB_Z_FAIL"/>
+	<value value="41" name="RB_S_FAIL"/>
+	<value value="42" name="RB_POWER0"/>
+	<value value="43" name="RB_POWER1"/>
+	<value value="44" name="RB_POWER2"/>
+	<value value="45" name="RB_POWER3"/>
+	<value value="46" name="RB_POWER4"/>
+	<value value="47" name="RB_POWER5"/>
+	<value value="48" name="RB_POWER6"/>
+	<value value="49" name="RB_POWER7"/>
+</enum>
+
+<enum name="a4xx_rbbm_perfcounter_select">
+	<value value="0" name="RBBM_ALWAYS_ON"/>
+	<value value="1" name="RBBM_VBIF_BUSY"/>
+	<value value="2" name="RBBM_TSE_BUSY"/>
+	<value value="3" name="RBBM_RAS_BUSY"/>
+	<value value="4" name="RBBM_PC_DCALL_BUSY"/>
+	<value value="5" name="RBBM_PC_VSD_BUSY"/>
+	<value value="6" name="RBBM_VFD_BUSY"/>
+	<value value="7" name="RBBM_VPC_BUSY"/>
+	<value value="8" name="RBBM_UCHE_BUSY"/>
+	<value value="9" name="RBBM_VSC_BUSY"/>
+	<value value="10" name="RBBM_HLSQ_BUSY"/>
+	<value value="11" name="RBBM_ANY_RB_BUSY"/>
+	<value value="12" name="RBBM_ANY_TPL1_BUSY"/>
+	<value value="13" name="RBBM_ANY_SP_BUSY"/>
+	<value value="14" name="RBBM_ANY_MARB_BUSY"/>
+	<value value="15" name="RBBM_ANY_ARB_BUSY"/>
+	<value value="16" name="RBBM_AHB_STATUS_BUSY"/>
+	<value value="17" name="RBBM_AHB_STATUS_STALLED"/>
+	<value value="18" name="RBBM_AHB_STATUS_TXFR"/>
+	<value value="19" name="RBBM_AHB_STATUS_TXFR_SPLIT"/>
+	<value value="20" name="RBBM_AHB_STATUS_TXFR_ERROR"/>
+	<value value="21" name="RBBM_AHB_STATUS_LONG_STALL"/>
+	<value value="22" name="RBBM_STATUS_MASKED"/>
+	<value value="23" name="RBBM_CP_BUSY_GFX_CORE_IDLE"/>
+	<value value="24" name="RBBM_TESS_BUSY"/>
+	<value value="25" name="RBBM_COM_BUSY"/>
+	<value value="32" name="RBBM_DCOM_BUSY"/>
+	<value value="33" name="RBBM_ANY_CCU_BUSY"/>
+	<value value="34" name="RBBM_DPM_BUSY"/>
+</enum>
+
+<enum name="a4xx_sp_perfcounter_select">
+	<value value="0" name="SP_LM_LOAD_INSTRUCTIONS"/>
+	<value value="1" name="SP_LM_STORE_INSTRUCTIONS"/>
+	<value value="2" name="SP_LM_ATOMICS"/>
+	<value value="3" name="SP_GM_LOAD_INSTRUCTIONS"/>
+	<value value="4" name="SP_GM_STORE_INSTRUCTIONS"/>
+	<value value="5" name="SP_GM_ATOMICS"/>
+	<value value="6" name="SP_VS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="7" name="SP_VS_STAGE_CFLOW_INSTRUCTIONS"/>
+	<value value="8" name="SP_VS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="9" name="SP_VS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="10" name="SP_VS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="11" name="SP_FS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="12" name="SP_FS_STAGE_CFLOW_INSTRUCTIONS"/>
+	<value value="13" name="SP_FS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="14" name="SP_FS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="15" name="SP_FS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="17" name="SP_VS_INSTRUCTIONS"/>
+	<value value="18" name="SP_FS_INSTRUCTIONS"/>
+	<value value="19" name="SP_ADDR_LOCK_COUNT"/>
+	<value value="20" name="SP_UCHE_READ_TRANS"/>
+	<value value="21" name="SP_UCHE_WRITE_TRANS"/>
+	<value value="22" name="SP_EXPORT_VPC_TRANS"/>
+	<value value="23" name="SP_EXPORT_RB_TRANS"/>
+	<value value="24" name="SP_PIXELS_KILLED"/>
+	<value value="25" name="SP_ICL1_REQUESTS"/>
+	<value value="26" name="SP_ICL1_MISSES"/>
+	<value value="27" name="SP_ICL0_REQUESTS"/>
+	<value value="28" name="SP_ICL0_MISSES"/>
+	<value value="29" name="SP_ALU_WORKING_CYCLES"/>
+	<value value="30" name="SP_EFU_WORKING_CYCLES"/>
+	<value value="31" name="SP_STALL_CYCLES_BY_VPC"/>
+	<value value="32" name="SP_STALL_CYCLES_BY_TP"/>
+	<value value="33" name="SP_STALL_CYCLES_BY_UCHE"/>
+	<value value="34" name="SP_STALL_CYCLES_BY_RB"/>
+	<value value="35" name="SP_BUSY_CYCLES"/>
+	<value value="36" name="SP_HS_INSTRUCTIONS"/>
+	<value value="37" name="SP_DS_INSTRUCTIONS"/>
+	<value value="38" name="SP_GS_INSTRUCTIONS"/>
+	<value value="39" name="SP_CS_INSTRUCTIONS"/>
+	<value value="40" name="SP_SCHEDULER_NON_WORKING"/>
+	<value value="41" name="SP_WAVE_CONTEXTS"/>
+	<value value="42" name="SP_WAVE_CONTEXT_CYCLES"/>
+	<value value="43" name="SP_POWER0"/>
+	<value value="44" name="SP_POWER1"/>
+	<value value="45" name="SP_POWER2"/>
+	<value value="46" name="SP_POWER3"/>
+	<value value="47" name="SP_POWER4"/>
+	<value value="48" name="SP_POWER5"/>
+	<value value="49" name="SP_POWER6"/>
+	<value value="50" name="SP_POWER7"/>
+	<value value="51" name="SP_POWER8"/>
+	<value value="52" name="SP_POWER9"/>
+	<value value="53" name="SP_POWER10"/>
+	<value value="54" name="SP_POWER11"/>
+	<value value="55" name="SP_POWER12"/>
+	<value value="56" name="SP_POWER13"/>
+	<value value="57" name="SP_POWER14"/>
+	<value value="58" name="SP_POWER15"/>
+</enum>
+
+<enum name="a4xx_tp_perfcounter_select">
+	<value value="0" name="TP_L1_REQUESTS"/>
+	<value value="1" name="TP_L1_MISSES"/>
+	<value value="8" name="TP_QUADS_OFFSET"/>
+	<value value="9" name="TP_QUAD_SHADOW"/>
+	<value value="10" name="TP_QUADS_ARRAY"/>
+	<value value="11" name="TP_QUADS_GRADIENT"/>
+	<value value="12" name="TP_QUADS_1D2D"/>
+	<value value="13" name="TP_QUADS_3DCUBE"/>
+	<value value="16" name="TP_BUSY_CYCLES"/>
+	<value value="17" name="TP_STALL_CYCLES_BY_ARB"/>
+	<value value="20" name="TP_STATE_CACHE_REQUESTS"/>
+	<value value="21" name="TP_STATE_CACHE_MISSES"/>
+	<value value="22" name="TP_POWER0"/>
+	<value value="23" name="TP_POWER1"/>
+	<value value="24" name="TP_POWER2"/>
+	<value value="25" name="TP_POWER3"/>
+	<value value="26" name="TP_POWER4"/>
+	<value value="27" name="TP_POWER5"/>
+	<value value="28" name="TP_POWER6"/>
+	<value value="29" name="TP_POWER7"/>
+</enum>
+
+<enum name="a4xx_uche_perfcounter_select">
+	<value value="0" name="UCHE_VBIF_READ_BEATS_TP"/>
+	<value value="1" name="UCHE_VBIF_READ_BEATS_VFD"/>
+	<value value="2" name="UCHE_VBIF_READ_BEATS_HLSQ"/>
+	<value value="3" name="UCHE_VBIF_READ_BEATS_MARB"/>
+	<value value="4" name="UCHE_VBIF_READ_BEATS_SP"/>
+	<value value="5" name="UCHE_READ_REQUESTS_TP"/>
+	<value value="6" name="UCHE_READ_REQUESTS_VFD"/>
+	<value value="7" name="UCHE_READ_REQUESTS_HLSQ"/>
+	<value value="8" name="UCHE_READ_REQUESTS_MARB"/>
+	<value value="9" name="UCHE_READ_REQUESTS_SP"/>
+	<value value="10" name="UCHE_WRITE_REQUESTS_MARB"/>
+	<value value="11" name="UCHE_WRITE_REQUESTS_SP"/>
+	<value value="12" name="UCHE_TAG_CHECK_FAILS"/>
+	<value value="13" name="UCHE_EVICTS"/>
+	<value value="14" name="UCHE_FLUSHES"/>
+	<value value="15" name="UCHE_VBIF_LATENCY_CYCLES"/>
+	<value value="16" name="UCHE_VBIF_LATENCY_SAMPLES"/>
+	<value value="17" name="UCHE_BUSY_CYCLES"/>
+	<value value="18" name="UCHE_VBIF_READ_BEATS_PC"/>
+	<value value="19" name="UCHE_READ_REQUESTS_PC"/>
+	<value value="20" name="UCHE_WRITE_REQUESTS_VPC"/>
+	<value value="21" name="UCHE_STALL_BY_VBIF"/>
+	<value value="22" name="UCHE_WRITE_REQUESTS_VSC"/>
+	<value value="23" name="UCHE_POWER0"/>
+	<value value="24" name="UCHE_POWER1"/>
+	<value value="25" name="UCHE_POWER2"/>
+	<value value="26" name="UCHE_POWER3"/>
+	<value value="27" name="UCHE_POWER4"/>
+	<value value="28" name="UCHE_POWER5"/>
+	<value value="29" name="UCHE_POWER6"/>
+	<value value="30" name="UCHE_POWER7"/>
+</enum>
+
+<enum name="a4xx_vbif_perfcounter_select">
+	<value value="0" name="AXI_READ_REQUESTS_ID_0"/>
+	<value value="1" name="AXI_READ_REQUESTS_ID_1"/>
+	<value value="2" name="AXI_READ_REQUESTS_ID_2"/>
+	<value value="3" name="AXI_READ_REQUESTS_ID_3"/>
+	<value value="4" name="AXI_READ_REQUESTS_ID_4"/>
+	<value value="5" name="AXI_READ_REQUESTS_ID_5"/>
+	<value value="6" name="AXI_READ_REQUESTS_ID_6"/>
+	<value value="7" name="AXI_READ_REQUESTS_ID_7"/>
+	<value value="8" name="AXI_READ_REQUESTS_ID_8"/>
+	<value value="9" name="AXI_READ_REQUESTS_ID_9"/>
+	<value value="10" name="AXI_READ_REQUESTS_ID_10"/>
+	<value value="11" name="AXI_READ_REQUESTS_ID_11"/>
+	<value value="12" name="AXI_READ_REQUESTS_ID_12"/>
+	<value value="13" name="AXI_READ_REQUESTS_ID_13"/>
+	<value value="14" name="AXI_READ_REQUESTS_ID_14"/>
+	<value value="15" name="AXI_READ_REQUESTS_ID_15"/>
+	<value value="16" name="AXI0_READ_REQUESTS_TOTAL"/>
+	<value value="17" name="AXI1_READ_REQUESTS_TOTAL"/>
+	<value value="18" name="AXI2_READ_REQUESTS_TOTAL"/>
+	<value value="19" name="AXI3_READ_REQUESTS_TOTAL"/>
+	<value value="20" name="AXI_READ_REQUESTS_TOTAL"/>
+	<value value="21" name="AXI_WRITE_REQUESTS_ID_0"/>
+	<value value="22" name="AXI_WRITE_REQUESTS_ID_1"/>
+	<value value="23" name="AXI_WRITE_REQUESTS_ID_2"/>
+	<value value="24" name="AXI_WRITE_REQUESTS_ID_3"/>
+	<value value="25" name="AXI_WRITE_REQUESTS_ID_4"/>
+	<value value="26" name="AXI_WRITE_REQUESTS_ID_5"/>
+	<value value="27" name="AXI_WRITE_REQUESTS_ID_6"/>
+	<value value="28" name="AXI_WRITE_REQUESTS_ID_7"/>
+	<value value="29" name="AXI_WRITE_REQUESTS_ID_8"/>
+	<value value="30" name="AXI_WRITE_REQUESTS_ID_9"/>
+	<value value="31" name="AXI_WRITE_REQUESTS_ID_10"/>
+	<value value="32" name="AXI_WRITE_REQUESTS_ID_11"/>
+	<value value="33" name="AXI_WRITE_REQUESTS_ID_12"/>
+	<value value="34" name="AXI_WRITE_REQUESTS_ID_13"/>
+	<value value="35" name="AXI_WRITE_REQUESTS_ID_14"/>
+	<value value="36" name="AXI_WRITE_REQUESTS_ID_15"/>
+	<value value="37" name="AXI0_WRITE_REQUESTS_TOTAL"/>
+	<value value="38" name="AXI1_WRITE_REQUESTS_TOTAL"/>
+	<value value="39" name="AXI2_WRITE_REQUESTS_TOTAL"/>
+	<value value="40" name="AXI3_WRITE_REQUESTS_TOTAL"/>
+	<value value="41" name="AXI_WRITE_REQUESTS_TOTAL"/>
+	<value value="42" name="AXI_TOTAL_REQUESTS"/>
+	<value value="43" name="AXI_READ_DATA_BEATS_ID_0"/>
+	<value value="44" name="AXI_READ_DATA_BEATS_ID_1"/>
+	<value value="45" name="AXI_READ_DATA_BEATS_ID_2"/>
+	<value value="46" name="AXI_READ_DATA_BEATS_ID_3"/>
+	<value value="47" name="AXI_READ_DATA_BEATS_ID_4"/>
+	<value value="48" name="AXI_READ_DATA_BEATS_ID_5"/>
+	<value value="49" name="AXI_READ_DATA_BEATS_ID_6"/>
+	<value value="50" name="AXI_READ_DATA_BEATS_ID_7"/>
+	<value value="51" name="AXI_READ_DATA_BEATS_ID_8"/>
+	<value value="52" name="AXI_READ_DATA_BEATS_ID_9"/>
+	<value value="53" name="AXI_READ_DATA_BEATS_ID_10"/>
+	<value value="54" name="AXI_READ_DATA_BEATS_ID_11"/>
+	<value value="55" name="AXI_READ_DATA_BEATS_ID_12"/>
+	<value value="56" name="AXI_READ_DATA_BEATS_ID_13"/>
+	<value value="57" name="AXI_READ_DATA_BEATS_ID_14"/>
+	<value value="58" name="AXI_READ_DATA_BEATS_ID_15"/>
+	<value value="59" name="AXI0_READ_DATA_BEATS_TOTAL"/>
+	<value value="60" name="AXI1_READ_DATA_BEATS_TOTAL"/>
+	<value value="61" name="AXI2_READ_DATA_BEATS_TOTAL"/>
+	<value value="62" name="AXI3_READ_DATA_BEATS_TOTAL"/>
+	<value value="63" name="AXI_READ_DATA_BEATS_TOTAL"/>
+	<value value="64" name="AXI_WRITE_DATA_BEATS_ID_0"/>
+	<value value="65" name="AXI_WRITE_DATA_BEATS_ID_1"/>
+	<value value="66" name="AXI_WRITE_DATA_BEATS_ID_2"/>
+	<value value="67" name="AXI_WRITE_DATA_BEATS_ID_3"/>
+	<value value="68" name="AXI_WRITE_DATA_BEATS_ID_4"/>
+	<value value="69" name="AXI_WRITE_DATA_BEATS_ID_5"/>
+	<value value="70" name="AXI_WRITE_DATA_BEATS_ID_6"/>
+	<value value="71" name="AXI_WRITE_DATA_BEATS_ID_7"/>
+	<value value="72" name="AXI_WRITE_DATA_BEATS_ID_8"/>
+	<value value="73" name="AXI_WRITE_DATA_BEATS_ID_9"/>
+	<value value="74" name="AXI_WRITE_DATA_BEATS_ID_10"/>
+	<value value="75" name="AXI_WRITE_DATA_BEATS_ID_11"/>
+	<value value="76" name="AXI_WRITE_DATA_BEATS_ID_12"/>
+	<value value="77" name="AXI_WRITE_DATA_BEATS_ID_13"/>
+	<value value="78" name="AXI_WRITE_DATA_BEATS_ID_14"/>
+	<value value="79" name="AXI_WRITE_DATA_BEATS_ID_15"/>
+	<value value="80" name="AXI0_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="81" name="AXI1_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="82" name="AXI2_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="83" name="AXI3_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="84" name="AXI_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="85" name="AXI_DATA_BEATS_TOTAL"/>
+	<value value="86" name="CYCLES_HELD_OFF_ID_0"/>
+	<value value="87" name="CYCLES_HELD_OFF_ID_1"/>
+	<value value="88" name="CYCLES_HELD_OFF_ID_2"/>
+	<value value="89" name="CYCLES_HELD_OFF_ID_3"/>
+	<value value="90" name="CYCLES_HELD_OFF_ID_4"/>
+	<value value="91" name="CYCLES_HELD_OFF_ID_5"/>
+	<value value="92" name="CYCLES_HELD_OFF_ID_6"/>
+	<value value="93" name="CYCLES_HELD_OFF_ID_7"/>
+	<value value="94" name="CYCLES_HELD_OFF_ID_8"/>
+	<value value="95" name="CYCLES_HELD_OFF_ID_9"/>
+	<value value="96" name="CYCLES_HELD_OFF_ID_10"/>
+	<value value="97" name="CYCLES_HELD_OFF_ID_11"/>
+	<value value="98" name="CYCLES_HELD_OFF_ID_12"/>
+	<value value="99" name="CYCLES_HELD_OFF_ID_13"/>
+	<value value="100" name="CYCLES_HELD_OFF_ID_14"/>
+	<value value="101" name="CYCLES_HELD_OFF_ID_15"/>
+	<value value="102" name="AXI_READ_REQUEST_HELD_OFF"/>
+	<value value="103" name="AXI_WRITE_REQUEST_HELD_OFF"/>
+	<value value="104" name="AXI_REQUEST_HELD_OFF"/>
+	<value value="105" name="AXI_WRITE_DATA_HELD_OFF"/>
+	<value value="106" name="OCMEM_AXI_READ_REQUEST_HELD_OFF"/>
+	<value value="107" name="OCMEM_AXI_WRITE_REQUEST_HELD_OFF"/>
+	<value value="108" name="OCMEM_AXI_REQUEST_HELD_OFF"/>
+	<value value="109" name="OCMEM_AXI_WRITE_DATA_HELD_OFF"/>
+	<value value="110" name="ELAPSED_CYCLES_DDR"/>
+	<value value="111" name="ELAPSED_CYCLES_OCMEM"/>
+</enum>
+
+<enum name="a4xx_vfd_perfcounter_select">
+	<value value="0" name="VFD_UCHE_BYTE_FETCHED"/>
+	<value value="1" name="VFD_UCHE_TRANS"/>
+	<value value="3" name="VFD_FETCH_INSTRUCTIONS"/>
+	<value value="5" name="VFD_BUSY_CYCLES"/>
+	<value value="6" name="VFD_STALL_CYCLES_UCHE"/>
+	<value value="7" name="VFD_STALL_CYCLES_HLSQ"/>
+	<value value="8" name="VFD_STALL_CYCLES_VPC_BYPASS"/>
+	<value value="9" name="VFD_STALL_CYCLES_VPC_ALLOC"/>
+	<value value="13" name="VFD_MODE_0_FIBERS"/>
+	<value value="14" name="VFD_MODE_1_FIBERS"/>
+	<value value="15" name="VFD_MODE_2_FIBERS"/>
+	<value value="16" name="VFD_MODE_3_FIBERS"/>
+	<value value="17" name="VFD_MODE_4_FIBERS"/>
+	<value value="18" name="VFD_BFIFO_STALL"/>
+	<value value="19" name="VFD_NUM_VERTICES_TOTAL"/>
+	<value value="20" name="VFD_PACKER_FULL"/>
+	<value value="21" name="VFD_UCHE_REQUEST_FIFO_FULL"/>
+	<value value="22" name="VFD_STARVE_CYCLES_PC"/>
+	<value value="23" name="VFD_STARVE_CYCLES_UCHE"/>
+</enum>
+
+<enum name="a4xx_vpc_perfcounter_select">
+	<value value="2" name="VPC_SP_LM_COMPONENTS"/>
+	<value value="3" name="VPC_SP0_LM_BYTES"/>
+	<value value="4" name="VPC_SP1_LM_BYTES"/>
+	<value value="5" name="VPC_SP2_LM_BYTES"/>
+	<value value="6" name="VPC_SP3_LM_BYTES"/>
+	<value value="7" name="VPC_WORKING_CYCLES"/>
+	<value value="8" name="VPC_STALL_CYCLES_LM"/>
+	<value value="9" name="VPC_STARVE_CYCLES_RAS"/>
+	<value value="10" name="VPC_STREAMOUT_CYCLES"/>
+	<value value="12" name="VPC_UCHE_TRANSACTIONS"/>
+	<value value="13" name="VPC_STALL_CYCLES_UCHE"/>
+	<value value="14" name="VPC_BUSY_CYCLES"/>
+	<value value="15" name="VPC_STARVE_CYCLES_SP"/>
+</enum>
+
+<enum name="a4xx_vsc_perfcounter_select">
+	<value value="0" name="VSC_BUSY_CYCLES"/>
+	<value value="1" name="VSC_WORKING_CYCLES"/>
+	<value value="2" name="VSC_STALL_CYCLES_UCHE"/>
+	<value value="3" name="VSC_STARVE_CYCLES_RAS"/>
+	<value value="4" name="VSC_EOT_NUM"/>
+</enum>
+
+<domain name="A4XX" width="32">
+	<!-- RB registers -->
+	<reg32 offset="0x0cc0" name="RB_GMEM_BASE_ADDR"/>
+	<reg32 offset="0x0cc7" name="RB_PERFCTR_RB_SEL_0" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cc8" name="RB_PERFCTR_RB_SEL_1" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cc9" name="RB_PERFCTR_RB_SEL_2" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cca" name="RB_PERFCTR_RB_SEL_3" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0ccb" name="RB_PERFCTR_RB_SEL_4" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0ccc" name="RB_PERFCTR_RB_SEL_5" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0ccd" name="RB_PERFCTR_RB_SEL_6" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cce" name="RB_PERFCTR_RB_SEL_7" type="a4xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0ccf" name="RB_PERFCTR_CCU_SEL_0" type="a4xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0cd0" name="RB_PERFCTR_CCU_SEL_1" type="a4xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0cd1" name="RB_PERFCTR_CCU_SEL_2" type="a4xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0cd2" name="RB_PERFCTR_CCU_SEL_3" type="a4xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0ce0" name="RB_FRAME_BUFFER_DIMENSION">
+		<bitfield name="WIDTH" low="0" high="13" type="uint"/>
+		<bitfield name="HEIGHT" low="16" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="0x20cc" name="RB_CLEAR_COLOR_DW0"/>
+	<reg32 offset="0x20cd" name="RB_CLEAR_COLOR_DW1"/>
+	<reg32 offset="0x20ce" name="RB_CLEAR_COLOR_DW2"/>
+	<reg32 offset="0x20cf" name="RB_CLEAR_COLOR_DW3"/>
+	<reg32 offset="0x20a0" name="RB_MODE_CONTROL">
+		<!--
+		for non-bypass mode, these are bin width/height..  although
+		possibly bigger bitfields to hold entire width/height for
+		gmem-bypass??  Either way, it appears to need to be multiple
+		of 32..
+		-->
+		<bitfield name="WIDTH" low="0" high="5" shr="5" type="uint"/>
+		<bitfield name="HEIGHT" low="8" high="13" shr="5" type="uint"/>
+		<bitfield name="ENABLE_GMEM" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x20a1" name="RB_RENDER_CONTROL">
+		<bitfield name="BINNING_PASS" pos="0" type="boolean"/>
+		<!-- nearly everything has bit3 set.. -->
+		<!-- bit5 set on resolve and tiling pass -->
+		<bitfield name="DISABLE_COLOR_PIPE" pos="5" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x20a2" name="RB_MSAA_CONTROL">
+		<bitfield name="DISABLE" pos="12" type="boolean"/>
+		<bitfield name="SAMPLES" low="13" high="15" type="uint"/>
+	</reg32>
+	<reg32 offset="0x20a3" name="RB_RENDER_CONTROL2">
+		<bitfield name="COORD_MASK" low="0" high="3" type="hex"/>
+		<bitfield name="SAMPLEMASK" pos="4" type="boolean"/>
+		<bitfield name="FACENESS" pos="5" type="boolean"/>
+		<bitfield name="SAMPLEID" pos="6" type="boolean"/>
+		<bitfield name="MSAA_SAMPLES" low="7" high="9" type="uint"/>
+		<bitfield name="SAMPLEID_HR" pos="11" type="boolean"/>
+		<bitfield name="IJ_PERSP_PIXEL" pos="12" type="boolean"/>
+		<!-- the 2 below are just educated guesses -->
+		<bitfield name="IJ_PERSP_CENTROID" pos="13" type="boolean"/>
+		<bitfield name="IJ_PERSP_SAMPLE" pos="14" type="boolean"/>
+		<!-- needs to be enabled to get nopersp values,
+		     perhaps other cases too? -->
+		<bitfield name="SIZE" pos="15" type="boolean"/>
+	</reg32>
+	<array offset="0x20a4" name="RB_MRT" stride="5" length="8">
+		<reg32 offset="0x0" name="CONTROL">
+			<bitfield name="READ_DEST_ENABLE" pos="3" type="boolean"/>
+			<!-- both these bits seem to get set when enabling GL_BLEND.. -->
+			<bitfield name="BLEND" pos="4" type="boolean"/>
+			<bitfield name="BLEND2" pos="5" type="boolean"/>
+			<bitfield name="ROP_ENABLE" pos="6" type="boolean"/>
+			<bitfield name="ROP_CODE" low="8" high="11" type="a3xx_rop_code"/>
+			<bitfield name="COMPONENT_ENABLE" low="24" high="27" type="hex"/>
+		</reg32>
+		<reg32 offset="0x1" name="BUF_INFO">
+			<bitfield name="COLOR_FORMAT" low="0" high="5" type="a4xx_color_fmt"/>
+			<!--
+			    guestimate position of COLOR_TILE_MODE..  this works out if
+			    common value is 2, like on a3xx..
+			 -->
+			<bitfield name="COLOR_TILE_MODE" low="6" high="7" type="a4xx_tile_mode"/>
+			<bitfield name="DITHER_MODE" low="9" high="10" type="adreno_rb_dither_mode"/>
+			<bitfield name="COLOR_SWAP" low="11" high="12" type="a3xx_color_swap"/>
+			<bitfield name="COLOR_SRGB" pos="13" type="boolean"/>
+			<!-- note: possibly some # of lsb's aren't there: -->
+			<doc>
+				Pitch (actually, appears to be pitch in bytes, so really is a stride)
+				in GMEM, so pitch of the current tile.
+			</doc>
+			<bitfield name="COLOR_BUF_PITCH" low="14" high="31" shr="4" type="uint"/>
+		</reg32>
+		<reg32 offset="0x2" name="BASE"/>
+		<reg32 offset="0x3" name="CONTROL3">
+			<!-- probably missing some lsb's.. and guessing upper size -->
+			<!-- pitch * cpp * msaa: -->
+			<bitfield name="STRIDE" low="3" high="25" type="uint"/>
+		</reg32>
+		<reg32 offset="0x4" name="BLEND_CONTROL">
+			<bitfield name="RGB_SRC_FACTOR" low="0" high="4" type="adreno_rb_blend_factor"/>
+			<bitfield name="RGB_BLEND_OPCODE" low="5" high="7" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="RGB_DEST_FACTOR" low="8" high="12" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_SRC_FACTOR" low="16" high="20" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_BLEND_OPCODE" low="21" high="23" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="ALPHA_DEST_FACTOR" low="24" high="28" type="adreno_rb_blend_factor"/>
+		</reg32>
+	</array>
+
+	<reg32 offset="0x20f0" name="RB_BLEND_RED">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0x20f1" name="RB_BLEND_RED_F32" type="float"/>
+
+	<reg32 offset="0x20f2" name="RB_BLEND_GREEN">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0x20f3" name="RB_BLEND_GREEN_F32" type="float"/>
+
+	<reg32 offset="0x20f4" name="RB_BLEND_BLUE">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0x20f5" name="RB_BLEND_BLUE_F32" type="float"/>
+
+	<reg32 offset="0x20f6" name="RB_BLEND_ALPHA">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0x20f7" name="RB_BLEND_ALPHA_F32" type="float"/>
+
+	<reg32 offset="0x20f8" name="RB_ALPHA_CONTROL">
+		<bitfield name="ALPHA_REF" low="0" high="7" type="hex"/>
+		<bitfield name="ALPHA_TEST" pos="8" type="boolean"/>
+		<bitfield name="ALPHA_TEST_FUNC" low="9" high="11" type="adreno_compare_func"/>
+	</reg32>
+	<reg32 offset="0x20f9" name="RB_FS_OUTPUT">
+		<!-- per-mrt enable bit -->
+		<bitfield name="ENABLE_BLEND" low="0" high="7"/>
+		<bitfield name="INDEPENDENT_BLEND" pos="8" type="boolean"/>
+		<!-- a guess? -->
+		<bitfield name="SAMPLE_MASK" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="0x20fa" name="RB_SAMPLE_COUNT_CONTROL">
+		<bitfield name="COPY" pos="1" type="boolean"/>
+		<bitfield name="ADDR" low="2" high="31" shr="2"/>
+	</reg32>
+	<!-- always 00000000 for binning pass, else 0000000f: -->
+	<reg32 offset="0x20fb" name="RB_RENDER_COMPONENTS">
+		<bitfield name="RT0" low="0" high="3"/>
+		<bitfield name="RT1" low="4" high="7"/>
+		<bitfield name="RT2" low="8" high="11"/>
+		<bitfield name="RT3" low="12" high="15"/>
+		<bitfield name="RT4" low="16" high="19"/>
+		<bitfield name="RT5" low="20" high="23"/>
+		<bitfield name="RT6" low="24" high="27"/>
+		<bitfield name="RT7" low="28" high="31"/>
+	</reg32>
+
+	<reg32 offset="0x20fc" name="RB_COPY_CONTROL">
+		<!-- not sure # of bits -->
+		<bitfield name="MSAA_RESOLVE" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="MODE" low="4" high="6" type="adreno_rb_copy_control_mode"/>
+		<bitfield name="FASTCLEAR" low="8" high="11" type="hex"/>
+		<bitfield name="GMEM_BASE" low="14" high="31" shr="14" type="hex"/>
+	</reg32>
+	<reg32 offset="0x20fd" name="RB_COPY_DEST_BASE">
+		<bitfield name="BASE" low="5" high="31" shr="5" type="hex"/>
+	</reg32>
+	<reg32 offset="0x20fe" name="RB_COPY_DEST_PITCH">
+		<doc>actually, appears to be pitch in bytes, so really is a stride</doc>
+		<!-- not actually sure about max pitch... -->
+		<bitfield name="PITCH" low="0" high="31" shr="5" type="uint"/>
+	</reg32>
+	<reg32 offset="0x20ff" name="RB_COPY_DEST_INFO">
+		<bitfield name="FORMAT" low="2" high="7" type="a4xx_color_fmt"/>
+		<bitfield name="SWAP" low="8" high="9" type="a3xx_color_swap"/>
+		<bitfield name="DITHER_MODE" low="10" high="11" type="adreno_rb_dither_mode"/>
+		<bitfield name="COMPONENT_ENABLE" low="14" high="17" type="hex"/>
+		<bitfield name="ENDIAN" low="18" high="20" type="adreno_rb_surface_endian"/>
+		<bitfield name="TILE" low="24" high="25" type="a4xx_tile_mode"/>
+	</reg32>
+	<reg32 offset="0x2100" name="RB_FS_OUTPUT_REG">
+		<!-- bit0 set except for binning pass.. -->
+		<bitfield name="MRT" low="0" high="3" type="uint"/>
+		<bitfield name="FRAG_WRITES_Z" pos="5" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2101" name="RB_DEPTH_CONTROL">
+		<!--
+			guessing that this matches a2xx with the stencil fields
+			moved out into RB_STENCIL_CONTROL?
+		 -->
+		<bitfield name="FRAG_WRITES_Z" pos="0" type="boolean"/>
+		<bitfield name="Z_TEST_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="Z_WRITE_ENABLE" pos="2" type="boolean"/>
+		<bitfield name="ZFUNC" low="4" high="6" type="adreno_compare_func"/>
+		<bitfield name="Z_CLAMP_ENABLE" pos="7" type="boolean"/>
+		<bitfield name="EARLY_Z_DISABLE" pos="16" type="boolean"/>
+		<bitfield name="FORCE_FRAGZ_TO_FS" pos="17" type="boolean"/>
+		<doc>Z_READ_ENABLE bit is set for zfunc other than GL_ALWAYS or GL_NEVER</doc>
+		<bitfield name="Z_READ_ENABLE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2102" name="RB_DEPTH_CLEAR"/>
+	<reg32 offset="0x2103" name="RB_DEPTH_INFO">
+		<bitfield name="DEPTH_FORMAT" low="0" high="1" type="a4xx_depth_format"/>
+		<doc>
+			DEPTH_BASE is offset in GMEM to depth/stencil buffer, ie
+			bin_w * bin_h / 1024 (possible rounded up to multiple of
+			something??  ie. 39 becomes 40, 78 becomes 80.. 75 becomes
+			80.. so maybe it needs to be multiple of 8??
+		</doc>
+		<bitfield name="DEPTH_BASE" low="12" high="31" shr="12" type="hex"/>
+	</reg32>
+	<reg32 offset="0x2104" name="RB_DEPTH_PITCH" shr="5" type="uint">
+		<doc>stride of depth/stencil buffer</doc>
+	</reg32>
+	<reg32 offset="0x2105" name="RB_DEPTH_PITCH2" shr="5" type="uint">
+		<doc>???</doc>
+	</reg32>
+	<reg32 offset="0x2106" name="RB_STENCIL_CONTROL">
+		<bitfield name="STENCIL_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="STENCIL_ENABLE_BF" pos="1" type="boolean"/>
+		<!--
+			set for stencil operations that require read from stencil
+			buffer, but not for example for stencil clear (which does
+			not require read).. so guessing this is analogous to
+			READ_DEST_ENABLE for color buffer..
+		 -->
+		<bitfield name="STENCIL_READ" pos="2" type="boolean"/>
+		<bitfield name="FUNC" low="8" high="10" type="adreno_compare_func"/>
+		<bitfield name="FAIL" low="11" high="13" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS" low="14" high="16" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL" low="17" high="19" type="adreno_stencil_op"/>
+		<bitfield name="FUNC_BF" low="20" high="22" type="adreno_compare_func"/>
+		<bitfield name="FAIL_BF" low="23" high="25" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS_BF" low="26" high="28" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL_BF" low="29" high="31" type="adreno_stencil_op"/>
+	</reg32>
+	<reg32 offset="0x2107" name="RB_STENCIL_CONTROL2">
+		<!--
+		This seems to be set by blob if there is a stencil buffer
+		at all in GMEM, regardless of whether it is enabled for
+		a particular draw (ie. RB_STENCIL_CONTROL).  Not really
+		sure if that is required or just a quirk of the blob
+		-->
+		<bitfield name="STENCIL_BUFFER" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2108" name="RB_STENCIL_INFO">
+		<bitfield name="SEPARATE_STENCIL" pos="0" type="boolean"/>
+		<doc>Base address for stencil when not using interleaved depth/stencil</doc>
+		<bitfield name="STENCIL_BASE" low="12" high="31" shr="12" type="hex"/>
+	</reg32>
+	<reg32 offset="0x2109" name="RB_STENCIL_PITCH" shr="5" type="uint">
+		<doc>pitch of stencil buffer when not using interleaved depth/stencil</doc>
+	</reg32>
+
+	<reg32 offset="0x210b" name="RB_STENCILREFMASK" type="adreno_rb_stencilrefmask"/>
+	<reg32 offset="0x210c" name="RB_STENCILREFMASK_BF" type="adreno_rb_stencilrefmask"/>
+	<reg32 offset="0x210d" name="RB_BIN_OFFSET" type="adreno_reg_xy"/>
+	<array offset="0x2120" name="RB_VPORT_Z_CLAMP" stride="2" length="16">
+		<reg32 offset="0x0" name="MIN"/>
+		<reg32 offset="0x1" name="MAX"/>
+	</array>
+
+	<!-- RBBM registers -->
+	<reg32 offset="0x0000" name="RBBM_HW_VERSION"/>
+	<reg32 offset="0x0002" name="RBBM_HW_CONFIGURATION"/>
+	<array offset="0x4" name="RBBM_CLOCK_CTL_TP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x8" name="RBBM_CLOCK_CTL2_TP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0xc" name="RBBM_CLOCK_HYST_TP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x10" name="RBBM_CLOCK_DELAY_TP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<reg32 offset="0x0014" name="RBBM_CLOCK_CTL_UCHE "/>
+	<reg32 offset="0x0015" name="RBBM_CLOCK_CTL2_UCHE"/>
+	<reg32 offset="0x0016" name="RBBM_CLOCK_CTL3_UCHE"/>
+	<reg32 offset="0x0017" name="RBBM_CLOCK_CTL4_UCHE"/>
+	<reg32 offset="0x0018" name="RBBM_CLOCK_HYST_UCHE"/>
+	<reg32 offset="0x0019" name="RBBM_CLOCK_DELAY_UCHE"/>
+	<reg32 offset="0x001a" name="RBBM_CLOCK_MODE_GPC"/>
+	<reg32 offset="0x001b" name="RBBM_CLOCK_DELAY_GPC"/>
+	<reg32 offset="0x001c" name="RBBM_CLOCK_HYST_GPC"/>
+	<reg32 offset="0x001d" name="RBBM_CLOCK_CTL_TSE_RAS_RBBM"/>
+	<reg32 offset="0x001e" name="RBBM_CLOCK_HYST_TSE_RAS_RBBM"/>
+	<reg32 offset="0x001f" name="RBBM_CLOCK_DELAY_TSE_RAS_RBBM"/>
+	<reg32 offset="0x0020" name="RBBM_CLOCK_CTL"/>
+	<reg32 offset="0x0021" name="RBBM_SP_HYST_CNT"/>
+	<reg32 offset="0x0022" name="RBBM_SW_RESET_CMD"/>
+	<reg32 offset="0x0023" name="RBBM_AHB_CTL0"/>
+	<reg32 offset="0x0024" name="RBBM_AHB_CTL1"/>
+	<reg32 offset="0x0025" name="RBBM_AHB_CMD"/>
+	<reg32 offset="0x0026" name="RBBM_RB_SUB_BLOCK_SEL_CTL"/>
+	<reg32 offset="0x0028" name="RBBM_RAM_ACC_63_32"/>
+	<reg32 offset="0x002b" name="RBBM_WAIT_IDLE_CLOCKS_CTL"/>
+	<reg32 offset="0x002f" name="RBBM_INTERFACE_HANG_INT_CTL"/>
+	<reg32 offset="0x0034" name="RBBM_INTERFACE_HANG_MASK_CTL4"/>
+	<reg32 offset="0x0036" name="RBBM_INT_CLEAR_CMD"/>
+	<reg32 offset="0x0037" name="RBBM_INT_0_MASK"/>
+	<reg32 offset="0x003e" name="RBBM_RBBM_CTL"/>
+	<reg32 offset="0x003f" name="RBBM_AHB_DEBUG_CTL"/>
+	<reg32 offset="0x0041" name="RBBM_VBIF_DEBUG_CTL"/>
+	<reg32 offset="0x0042" name="RBBM_CLOCK_CTL2"/>
+	<reg32 offset="0x0045" name="RBBM_BLOCK_SW_RESET_CMD"/>
+	<reg32 offset="0x0047" name="RBBM_RESET_CYCLES"/>
+	<reg32 offset="0x0049" name="RBBM_EXT_TRACE_BUS_CTL"/>
+	<reg32 offset="0x004a" name="RBBM_CFG_DEBBUS_SEL_A"/>
+	<reg32 offset="0x004b" name="RBBM_CFG_DEBBUS_SEL_B"/>
+	<reg32 offset="0x004c" name="RBBM_CFG_DEBBUS_SEL_C"/>
+	<reg32 offset="0x004d" name="RBBM_CFG_DEBBUS_SEL_D"/>
+	<reg32 offset="0x0098" name="RBBM_POWER_CNTL_IP">
+		<bitfield name="SW_COLLAPSE" pos="0" type="boolean"/>
+		<bitfield name="SP_TP_PWR_ON" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x009c" name="RBBM_PERFCTR_CP_0_LO"/>
+	<reg32 offset="0x009d" name="RBBM_PERFCTR_CP_0_HI"/>
+	<reg32 offset="0x009e" name="RBBM_PERFCTR_CP_1_LO"/>
+	<reg32 offset="0x009f" name="RBBM_PERFCTR_CP_1_HI"/>
+	<reg32 offset="0x00a0" name="RBBM_PERFCTR_CP_2_LO"/>
+	<reg32 offset="0x00a1" name="RBBM_PERFCTR_CP_2_HI"/>
+	<reg32 offset="0x00a2" name="RBBM_PERFCTR_CP_3_LO"/>
+	<reg32 offset="0x00a3" name="RBBM_PERFCTR_CP_3_HI"/>
+	<reg32 offset="0x00a4" name="RBBM_PERFCTR_CP_4_LO"/>
+	<reg32 offset="0x00a5" name="RBBM_PERFCTR_CP_4_HI"/>
+	<reg32 offset="0x00a6" name="RBBM_PERFCTR_CP_5_LO"/>
+	<reg32 offset="0x00a7" name="RBBM_PERFCTR_CP_5_HI"/>
+	<reg32 offset="0x00a8" name="RBBM_PERFCTR_CP_6_LO"/>
+	<reg32 offset="0x00a9" name="RBBM_PERFCTR_CP_6_HI"/>
+	<reg32 offset="0x00aa" name="RBBM_PERFCTR_CP_7_LO"/>
+	<reg32 offset="0x00ab" name="RBBM_PERFCTR_CP_7_HI"/>
+	<reg32 offset="0x00ac" name="RBBM_PERFCTR_RBBM_0_LO"/>
+	<reg32 offset="0x00ad" name="RBBM_PERFCTR_RBBM_0_HI"/>
+	<reg32 offset="0x00ae" name="RBBM_PERFCTR_RBBM_1_LO"/>
+	<reg32 offset="0x00af" name="RBBM_PERFCTR_RBBM_1_HI"/>
+	<reg32 offset="0x00b0" name="RBBM_PERFCTR_RBBM_2_LO"/>
+	<reg32 offset="0x00b1" name="RBBM_PERFCTR_RBBM_2_HI"/>
+	<reg32 offset="0x00b2" name="RBBM_PERFCTR_RBBM_3_LO"/>
+	<reg32 offset="0x00b3" name="RBBM_PERFCTR_RBBM_3_HI"/>
+	<reg32 offset="0x00b4" name="RBBM_PERFCTR_PC_0_LO"/>
+	<reg32 offset="0x00b5" name="RBBM_PERFCTR_PC_0_HI"/>
+	<reg32 offset="0x00b6" name="RBBM_PERFCTR_PC_1_LO"/>
+	<reg32 offset="0x00b7" name="RBBM_PERFCTR_PC_1_HI"/>
+	<reg32 offset="0x00b8" name="RBBM_PERFCTR_PC_2_LO"/>
+	<reg32 offset="0x00b9" name="RBBM_PERFCTR_PC_2_HI"/>
+	<reg32 offset="0x00ba" name="RBBM_PERFCTR_PC_3_LO"/>
+	<reg32 offset="0x00bb" name="RBBM_PERFCTR_PC_3_HI"/>
+	<reg32 offset="0x00bc" name="RBBM_PERFCTR_PC_4_LO"/>
+	<reg32 offset="0x00bd" name="RBBM_PERFCTR_PC_4_HI"/>
+	<reg32 offset="0x00be" name="RBBM_PERFCTR_PC_5_LO"/>
+	<reg32 offset="0x00bf" name="RBBM_PERFCTR_PC_5_HI"/>
+	<reg32 offset="0x00c0" name="RBBM_PERFCTR_PC_6_LO"/>
+	<reg32 offset="0x00c1" name="RBBM_PERFCTR_PC_6_HI"/>
+	<reg32 offset="0x00c2" name="RBBM_PERFCTR_PC_7_LO"/>
+	<reg32 offset="0x00c3" name="RBBM_PERFCTR_PC_7_HI"/>
+	<reg32 offset="0x00c4" name="RBBM_PERFCTR_VFD_0_LO"/>
+	<reg32 offset="0x00c5" name="RBBM_PERFCTR_VFD_0_HI"/>
+	<reg32 offset="0x00c6" name="RBBM_PERFCTR_VFD_1_LO"/>
+	<reg32 offset="0x00c7" name="RBBM_PERFCTR_VFD_1_HI"/>
+	<reg32 offset="0x00c8" name="RBBM_PERFCTR_VFD_2_LO"/>
+	<reg32 offset="0x00c9" name="RBBM_PERFCTR_VFD_2_HI"/>
+	<reg32 offset="0x00ca" name="RBBM_PERFCTR_VFD_3_LO"/>
+	<reg32 offset="0x00cb" name="RBBM_PERFCTR_VFD_3_HI"/>
+	<reg32 offset="0x00cc" name="RBBM_PERFCTR_VFD_4_LO"/>
+	<reg32 offset="0x00cd" name="RBBM_PERFCTR_VFD_4_HI"/>
+	<reg32 offset="0x00ce" name="RBBM_PERFCTR_VFD_5_LO"/>
+	<reg32 offset="0x00cf" name="RBBM_PERFCTR_VFD_5_HI"/>
+	<reg32 offset="0x00d0" name="RBBM_PERFCTR_VFD_6_LO"/>
+	<reg32 offset="0x00d1" name="RBBM_PERFCTR_VFD_6_HI"/>
+	<reg32 offset="0x00d2" name="RBBM_PERFCTR_VFD_7_LO"/>
+	<reg32 offset="0x00d3" name="RBBM_PERFCTR_VFD_7_HI"/>
+	<reg32 offset="0x00d4" name="RBBM_PERFCTR_HLSQ_0_LO"/>
+	<reg32 offset="0x00d5" name="RBBM_PERFCTR_HLSQ_0_HI"/>
+	<reg32 offset="0x00d6" name="RBBM_PERFCTR_HLSQ_1_LO"/>
+	<reg32 offset="0x00d7" name="RBBM_PERFCTR_HLSQ_1_HI"/>
+	<reg32 offset="0x00d8" name="RBBM_PERFCTR_HLSQ_2_LO"/>
+	<reg32 offset="0x00d9" name="RBBM_PERFCTR_HLSQ_2_HI"/>
+	<reg32 offset="0x00da" name="RBBM_PERFCTR_HLSQ_3_LO"/>
+	<reg32 offset="0x00db" name="RBBM_PERFCTR_HLSQ_3_HI"/>
+	<reg32 offset="0x00dc" name="RBBM_PERFCTR_HLSQ_4_LO"/>
+	<reg32 offset="0x00dd" name="RBBM_PERFCTR_HLSQ_4_HI"/>
+	<reg32 offset="0x00de" name="RBBM_PERFCTR_HLSQ_5_LO"/>
+	<reg32 offset="0x00df" name="RBBM_PERFCTR_HLSQ_5_HI"/>
+	<reg32 offset="0x00e0" name="RBBM_PERFCTR_HLSQ_6_LO"/>
+	<reg32 offset="0x00e1" name="RBBM_PERFCTR_HLSQ_6_HI"/>
+	<reg32 offset="0x00e2" name="RBBM_PERFCTR_HLSQ_7_LO"/>
+	<reg32 offset="0x00e3" name="RBBM_PERFCTR_HLSQ_7_HI"/>
+	<reg32 offset="0x00e4" name="RBBM_PERFCTR_VPC_0_LO"/>
+	<reg32 offset="0x00e5" name="RBBM_PERFCTR_VPC_0_HI"/>
+	<reg32 offset="0x00e6" name="RBBM_PERFCTR_VPC_1_LO"/>
+	<reg32 offset="0x00e7" name="RBBM_PERFCTR_VPC_1_HI"/>
+	<reg32 offset="0x00e8" name="RBBM_PERFCTR_VPC_2_LO"/>
+	<reg32 offset="0x00e9" name="RBBM_PERFCTR_VPC_2_HI"/>
+	<reg32 offset="0x00ea" name="RBBM_PERFCTR_VPC_3_LO"/>
+	<reg32 offset="0x00eb" name="RBBM_PERFCTR_VPC_3_HI"/>
+	<reg32 offset="0x00ec" name="RBBM_PERFCTR_CCU_0_LO"/>
+	<reg32 offset="0x00ed" name="RBBM_PERFCTR_CCU_0_HI"/>
+	<reg32 offset="0x00ee" name="RBBM_PERFCTR_CCU_1_LO"/>
+	<reg32 offset="0x00ef" name="RBBM_PERFCTR_CCU_1_HI"/>
+	<reg32 offset="0x00f0" name="RBBM_PERFCTR_CCU_2_LO"/>
+	<reg32 offset="0x00f1" name="RBBM_PERFCTR_CCU_2_HI"/>
+	<reg32 offset="0x00f2" name="RBBM_PERFCTR_CCU_3_LO"/>
+	<reg32 offset="0x00f3" name="RBBM_PERFCTR_CCU_3_HI"/>
+	<reg32 offset="0x00f4" name="RBBM_PERFCTR_TSE_0_LO"/>
+	<reg32 offset="0x00f5" name="RBBM_PERFCTR_TSE_0_HI"/>
+	<reg32 offset="0x00f6" name="RBBM_PERFCTR_TSE_1_LO"/>
+	<reg32 offset="0x00f7" name="RBBM_PERFCTR_TSE_1_HI"/>
+	<reg32 offset="0x00f8" name="RBBM_PERFCTR_TSE_2_LO"/>
+	<reg32 offset="0x00f9" name="RBBM_PERFCTR_TSE_2_HI"/>
+	<reg32 offset="0x00fa" name="RBBM_PERFCTR_TSE_3_LO"/>
+	<reg32 offset="0x00fb" name="RBBM_PERFCTR_TSE_3_HI"/>
+	<reg32 offset="0x00fc" name="RBBM_PERFCTR_RAS_0_LO"/>
+	<reg32 offset="0x00fd" name="RBBM_PERFCTR_RAS_0_HI"/>
+	<reg32 offset="0x00fe" name="RBBM_PERFCTR_RAS_1_LO"/>
+	<reg32 offset="0x00ff" name="RBBM_PERFCTR_RAS_1_HI"/>
+	<reg32 offset="0x0100" name="RBBM_PERFCTR_RAS_2_LO"/>
+	<reg32 offset="0x0101" name="RBBM_PERFCTR_RAS_2_HI"/>
+	<reg32 offset="0x0102" name="RBBM_PERFCTR_RAS_3_LO"/>
+	<reg32 offset="0x0103" name="RBBM_PERFCTR_RAS_3_HI"/>
+	<reg32 offset="0x0104" name="RBBM_PERFCTR_UCHE_0_LO"/>
+	<reg32 offset="0x0105" name="RBBM_PERFCTR_UCHE_0_HI"/>
+	<reg32 offset="0x0106" name="RBBM_PERFCTR_UCHE_1_LO"/>
+	<reg32 offset="0x0107" name="RBBM_PERFCTR_UCHE_1_HI"/>
+	<reg32 offset="0x0108" name="RBBM_PERFCTR_UCHE_2_LO"/>
+	<reg32 offset="0x0109" name="RBBM_PERFCTR_UCHE_2_HI"/>
+	<reg32 offset="0x010a" name="RBBM_PERFCTR_UCHE_3_LO"/>
+	<reg32 offset="0x010b" name="RBBM_PERFCTR_UCHE_3_HI"/>
+	<reg32 offset="0x010c" name="RBBM_PERFCTR_UCHE_4_LO"/>
+	<reg32 offset="0x010d" name="RBBM_PERFCTR_UCHE_4_HI"/>
+	<reg32 offset="0x010e" name="RBBM_PERFCTR_UCHE_5_LO"/>
+	<reg32 offset="0x010f" name="RBBM_PERFCTR_UCHE_5_HI"/>
+	<reg32 offset="0x0110" name="RBBM_PERFCTR_UCHE_6_LO"/>
+	<reg32 offset="0x0111" name="RBBM_PERFCTR_UCHE_6_HI"/>
+	<reg32 offset="0x0112" name="RBBM_PERFCTR_UCHE_7_LO"/>
+	<reg32 offset="0x0113" name="RBBM_PERFCTR_UCHE_7_HI"/>
+	<reg32 offset="0x0114" name="RBBM_PERFCTR_TP_0_LO"/>
+	<reg32 offset="0x0115" name="RBBM_PERFCTR_TP_0_HI"/>
+	<reg32 offset="0x0116" name="RBBM_PERFCTR_TP_1_LO"/>
+	<reg32 offset="0x0117" name="RBBM_PERFCTR_TP_1_HI"/>
+	<reg32 offset="0x0118" name="RBBM_PERFCTR_TP_2_LO"/>
+	<reg32 offset="0x0119" name="RBBM_PERFCTR_TP_2_HI"/>
+	<reg32 offset="0x011a" name="RBBM_PERFCTR_TP_3_LO"/>
+	<reg32 offset="0x011b" name="RBBM_PERFCTR_TP_3_HI"/>
+	<reg32 offset="0x011c" name="RBBM_PERFCTR_TP_4_LO"/>
+	<reg32 offset="0x011d" name="RBBM_PERFCTR_TP_4_HI"/>
+	<reg32 offset="0x011e" name="RBBM_PERFCTR_TP_5_LO"/>
+	<reg32 offset="0x011f" name="RBBM_PERFCTR_TP_5_HI"/>
+	<reg32 offset="0x0120" name="RBBM_PERFCTR_TP_6_LO"/>
+	<reg32 offset="0x0121" name="RBBM_PERFCTR_TP_6_HI"/>
+	<reg32 offset="0x0122" name="RBBM_PERFCTR_TP_7_LO"/>
+	<reg32 offset="0x0123" name="RBBM_PERFCTR_TP_7_HI"/>
+	<reg32 offset="0x0124" name="RBBM_PERFCTR_SP_0_LO"/>
+	<reg32 offset="0x0125" name="RBBM_PERFCTR_SP_0_HI"/>
+	<reg32 offset="0x0126" name="RBBM_PERFCTR_SP_1_LO"/>
+	<reg32 offset="0x0127" name="RBBM_PERFCTR_SP_1_HI"/>
+	<reg32 offset="0x0128" name="RBBM_PERFCTR_SP_2_LO"/>
+	<reg32 offset="0x0129" name="RBBM_PERFCTR_SP_2_HI"/>
+	<reg32 offset="0x012a" name="RBBM_PERFCTR_SP_3_LO"/>
+	<reg32 offset="0x012b" name="RBBM_PERFCTR_SP_3_HI"/>
+	<reg32 offset="0x012c" name="RBBM_PERFCTR_SP_4_LO"/>
+	<reg32 offset="0x012d" name="RBBM_PERFCTR_SP_4_HI"/>
+	<reg32 offset="0x012e" name="RBBM_PERFCTR_SP_5_LO"/>
+	<reg32 offset="0x012f" name="RBBM_PERFCTR_SP_5_HI"/>
+	<reg32 offset="0x0130" name="RBBM_PERFCTR_SP_6_LO"/>
+	<reg32 offset="0x0131" name="RBBM_PERFCTR_SP_6_HI"/>
+	<reg32 offset="0x0132" name="RBBM_PERFCTR_SP_7_LO"/>
+	<reg32 offset="0x0133" name="RBBM_PERFCTR_SP_7_HI"/>
+	<reg32 offset="0x0134" name="RBBM_PERFCTR_SP_8_LO"/>
+	<reg32 offset="0x0135" name="RBBM_PERFCTR_SP_8_HI"/>
+	<reg32 offset="0x0136" name="RBBM_PERFCTR_SP_9_LO"/>
+	<reg32 offset="0x0137" name="RBBM_PERFCTR_SP_9_HI"/>
+	<reg32 offset="0x0138" name="RBBM_PERFCTR_SP_10_LO"/>
+	<reg32 offset="0x0139" name="RBBM_PERFCTR_SP_10_HI"/>
+	<reg32 offset="0x013a" name="RBBM_PERFCTR_SP_11_LO"/>
+	<reg32 offset="0x013b" name="RBBM_PERFCTR_SP_11_HI"/>
+	<reg32 offset="0x013c" name="RBBM_PERFCTR_RB_0_LO"/>
+	<reg32 offset="0x013d" name="RBBM_PERFCTR_RB_0_HI"/>
+	<reg32 offset="0x013e" name="RBBM_PERFCTR_RB_1_LO"/>
+	<reg32 offset="0x013f" name="RBBM_PERFCTR_RB_1_HI"/>
+	<reg32 offset="0x0140" name="RBBM_PERFCTR_RB_2_LO"/>
+	<reg32 offset="0x0141" name="RBBM_PERFCTR_RB_2_HI"/>
+	<reg32 offset="0x0142" name="RBBM_PERFCTR_RB_3_LO"/>
+	<reg32 offset="0x0143" name="RBBM_PERFCTR_RB_3_HI"/>
+	<reg32 offset="0x0144" name="RBBM_PERFCTR_RB_4_LO"/>
+	<reg32 offset="0x0145" name="RBBM_PERFCTR_RB_4_HI"/>
+	<reg32 offset="0x0146" name="RBBM_PERFCTR_RB_5_LO"/>
+	<reg32 offset="0x0147" name="RBBM_PERFCTR_RB_5_HI"/>
+	<reg32 offset="0x0148" name="RBBM_PERFCTR_RB_6_LO"/>
+	<reg32 offset="0x0149" name="RBBM_PERFCTR_RB_6_HI"/>
+	<reg32 offset="0x014a" name="RBBM_PERFCTR_RB_7_LO"/>
+	<reg32 offset="0x014b" name="RBBM_PERFCTR_RB_7_HI"/>
+	<reg32 offset="0x014c" name="RBBM_PERFCTR_VSC_0_LO"/>
+	<reg32 offset="0x014d" name="RBBM_PERFCTR_VSC_0_HI"/>
+	<reg32 offset="0x014e" name="RBBM_PERFCTR_VSC_1_LO"/>
+	<reg32 offset="0x014f" name="RBBM_PERFCTR_VSC_1_HI"/>
+	<reg32 offset="0x0166" name="RBBM_PERFCTR_PWR_0_LO"/>
+	<reg32 offset="0x0167" name="RBBM_PERFCTR_PWR_0_HI"/>
+	<reg32 offset="0x0168" name="RBBM_PERFCTR_PWR_1_LO"/>
+	<reg32 offset="0x0169" name="RBBM_PERFCTR_PWR_1_HI"/>
+	<reg32 offset="0x016e" name="RBBM_ALWAYSON_COUNTER_LO"/>
+	<reg32 offset="0x016f" name="RBBM_ALWAYSON_COUNTER_HI"/>
+	<array offset="0x0068" name="RBBM_CLOCK_CTL_SP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x006c" name="RBBM_CLOCK_CTL2_SP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x0070" name="RBBM_CLOCK_HYST_SP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x0074" name="RBBM_CLOCK_DELAY_SP" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x0078" name="RBBM_CLOCK_CTL_RB" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x007c" name="RBBM_CLOCK_CTL2_RB" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x0082" name="RBBM_CLOCK_CTL_MARB_CCU" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x0086" name="RBBM_CLOCK_HYST_RB_MARB_CCU" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<reg32 offset="0x0080" name="RBBM_CLOCK_HYST_COM_DCOM"/>
+	<reg32 offset="0x0081" name="RBBM_CLOCK_CTL_COM_DCOM"/>
+	<reg32 offset="0x008a" name="RBBM_CLOCK_CTL_HLSQ"/>
+	<reg32 offset="0x008b" name="RBBM_CLOCK_HYST_HLSQ"/>
+	<reg32 offset="0x008c" name="RBBM_CLOCK_DELAY_HLSQ"/>
+	<bitset name="A4XX_CGC_HLSQ">
+		<bitfield name="EARLY_CYC" low="20" high="22" type="uint"/>
+	</bitset>
+	<reg32 offset="0x008d" name="RBBM_CLOCK_DELAY_COM_DCOM"/>
+	<array offset="0x008e" name="RBBM_CLOCK_DELAY_RB_MARB_CCU_L1" stride="1" length="4">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<bitset name="A4XX_INT0">
+		<bitfield name="RBBM_GPU_IDLE" pos="0" type="boolean"/>
+		<bitfield name="RBBM_AHB_ERROR" pos="1" type="boolean"/>
+		<bitfield name="RBBM_REG_TIMEOUT" pos="2" type="boolean"/>
+		<bitfield name="RBBM_ME_MS_TIMEOUT" pos="3" type="boolean"/>
+		<bitfield name="RBBM_PFP_MS_TIMEOUT" pos="4" type="boolean"/>
+		<bitfield name="RBBM_ATB_BUS_OVERFLOW" pos="5" type="boolean"/>
+		<bitfield name="VFD_ERROR" pos="6" type="boolean"/>
+		<bitfield name="CP_SW_INT" pos="7" type="boolean"/>
+		<bitfield name="CP_T0_PACKET_IN_IB" pos="8" type="boolean"/>
+		<bitfield name="CP_OPCODE_ERROR" pos="9" type="boolean"/>
+		<bitfield name="CP_RESERVED_BIT_ERROR" pos="10" type="boolean"/>
+		<bitfield name="CP_HW_FAULT" pos="11" type="boolean"/>
+		<bitfield name="CP_DMA" pos="12" type="boolean"/>
+		<bitfield name="CP_IB2_INT" pos="13" type="boolean"/>
+		<bitfield name="CP_IB1_INT" pos="14" type="boolean"/>
+		<bitfield name="CP_RB_INT" pos="15" type="boolean"/>
+		<bitfield name="CP_REG_PROTECT_FAULT" pos="16" type="boolean"/>
+		<bitfield name="CP_RB_DONE_TS" pos="17" type="boolean"/>
+		<bitfield name="CP_VS_DONE_TS" pos="18" type="boolean"/>
+		<bitfield name="CP_PS_DONE_TS" pos="19" type="boolean"/>
+		<bitfield name="CACHE_FLUSH_TS" pos="20" type="boolean"/>
+		<bitfield name="CP_AHB_ERROR_HALT" pos="21" type="boolean"/>
+		<bitfield name="MISC_HANG_DETECT" pos="24" type="boolean"/>
+		<bitfield name="UCHE_OOB_ACCESS" pos="25" type="boolean"/>
+	</bitset>
+
+	<reg32 offset="0x0099" name="RBBM_SP_REGFILE_SLEEP_CNTL_0"/>
+	<reg32 offset="0x009a" name="RBBM_SP_REGFILE_SLEEP_CNTL_1"/>
+	<reg32 offset="0x0170" name="RBBM_PERFCTR_CTL"/>
+	<reg32 offset="0x0171" name="RBBM_PERFCTR_LOAD_CMD0"/>
+	<reg32 offset="0x0172" name="RBBM_PERFCTR_LOAD_CMD1"/>
+	<reg32 offset="0x0173" name="RBBM_PERFCTR_LOAD_CMD2"/>
+	<reg32 offset="0x0174" name="RBBM_PERFCTR_LOAD_VALUE_LO"/>
+	<reg32 offset="0x0175" name="RBBM_PERFCTR_LOAD_VALUE_HI"/>
+	<reg32 offset="0x0176" name="RBBM_PERFCTR_RBBM_SEL_0" type="a4xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x0177" name="RBBM_PERFCTR_RBBM_SEL_1" type="a4xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x0178" name="RBBM_PERFCTR_RBBM_SEL_2" type="a4xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x0179" name="RBBM_PERFCTR_RBBM_SEL_3" type="a4xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x017a" name="RBBM_GPU_BUSY_MASKED"/>
+	<reg32 offset="0x017d" name="RBBM_INT_0_STATUS"/>
+	<reg32 offset="0x0182" name="RBBM_CLOCK_STATUS"/>
+	<reg32 offset="0x0189" name="RBBM_AHB_STATUS"/>
+	<reg32 offset="0x018c" name="RBBM_AHB_ME_SPLIT_STATUS"/>
+	<reg32 offset="0x018d" name="RBBM_AHB_PFP_SPLIT_STATUS"/>
+	<reg32 offset="0x018f" name="RBBM_AHB_ERROR_STATUS"/>
+	<reg32 offset="0x0191" name="RBBM_STATUS">
+		<bitfield name="HI_BUSY" pos="0" type="boolean"/>
+		<bitfield name="CP_ME_BUSY" pos="1" type="boolean"/>
+		<bitfield name="CP_PFP_BUSY" pos="2" type="boolean"/>
+		<bitfield name="CP_NRT_BUSY" pos="14" type="boolean"/>
+		<bitfield name="VBIF_BUSY" pos="15" type="boolean"/>
+		<bitfield name="TSE_BUSY" pos="16" type="boolean"/>
+		<bitfield name="RAS_BUSY" pos="17" type="boolean"/>
+		<bitfield name="RB_BUSY" pos="18" type="boolean"/>
+		<bitfield name="PC_DCALL_BUSY" pos="19" type="boolean"/>
+		<bitfield name="PC_VSD_BUSY" pos="20" type="boolean"/>
+		<bitfield name="VFD_BUSY" pos="21" type="boolean"/>
+		<bitfield name="VPC_BUSY" pos="22" type="boolean"/>
+		<bitfield name="UCHE_BUSY" pos="23" type="boolean"/>
+		<bitfield name="SP_BUSY" pos="24" type="boolean"/>
+		<bitfield name="TPL1_BUSY" pos="25" type="boolean"/>
+		<bitfield name="MARB_BUSY" pos="26" type="boolean"/>
+		<bitfield name="VSC_BUSY" pos="27" type="boolean"/>
+		<bitfield name="ARB_BUSY" pos="28" type="boolean"/>
+		<bitfield name="HLSQ_BUSY" pos="29" type="boolean"/>
+		<bitfield name="GPU_BUSY_NOHC" pos="30" type="boolean"/>
+		<bitfield name="GPU_BUSY" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x019f" name="RBBM_INTERFACE_RRDY_STATUS5"/>
+	<reg32 offset="0x01b0" name="RBBM_POWER_STATUS">
+		<bitfield name="SP_TP_PWR_ON" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x01b8" name="RBBM_WAIT_IDLE_CLOCKS_CTL2"/>
+
+	<!-- CP registers -->
+	<reg32 offset="0x0228" name="CP_SCRATCH_UMASK"/>
+	<reg32 offset="0x0229" name="CP_SCRATCH_ADDR"/>
+	<reg32 offset="0x0200" name="CP_RB_BASE"/>
+	<reg32 offset="0x0201" name="CP_RB_CNTL"/>
+	<reg32 offset="0x0205" name="CP_RB_WPTR"/>
+	<reg32 offset="0x0203" name="CP_RB_RPTR_ADDR"/>
+	<reg32 offset="0x0204" name="CP_RB_RPTR"/>
+	<reg32 offset="0x0206" name="CP_IB1_BASE"/>
+	<reg32 offset="0x0207" name="CP_IB1_BUFSZ"/>
+	<reg32 offset="0x0208" name="CP_IB2_BASE"/>
+	<reg32 offset="0x0209" name="CP_IB2_BUFSZ"/>
+	<reg32 offset="0x020c" name="CP_ME_NRT_ADDR"/>
+	<reg32 offset="0x020d" name="CP_ME_NRT_DATA"/>
+	<reg32 offset="0x0217" name="CP_ME_RB_DONE_DATA"/>
+	<reg32 offset="0x0219" name="CP_QUEUE_THRESH2"/>
+	<reg32 offset="0x021b" name="CP_MERCIU_SIZE"/>
+	<reg32 offset="0x021c" name="CP_ROQ_ADDR"/>
+	<reg32 offset="0x021d" name="CP_ROQ_DATA"/>
+	<reg32 offset="0x021e" name="CP_MEQ_ADDR"/>
+	<reg32 offset="0x021f" name="CP_MEQ_DATA"/>
+	<reg32 offset="0x0220" name="CP_MERCIU_ADDR"/>
+	<reg32 offset="0x0221" name="CP_MERCIU_DATA"/>
+	<reg32 offset="0x0222" name="CP_MERCIU_DATA2"/>
+	<reg32 offset="0x0223" name="CP_PFP_UCODE_ADDR"/>
+	<reg32 offset="0x0224" name="CP_PFP_UCODE_DATA"/>
+	<reg32 offset="0x0225" name="CP_ME_RAM_WADDR"/>
+	<reg32 offset="0x0226" name="CP_ME_RAM_RADDR"/>
+	<reg32 offset="0x0227" name="CP_ME_RAM_DATA"/>
+	<reg32 offset="0x022a" name="CP_PREEMPT"/>
+	<reg32 offset="0x022c" name="CP_CNTL"/>
+	<reg32 offset="0x022d" name="CP_ME_CNTL"/>
+	<reg32 offset="0x022e" name="CP_DEBUG"/>
+	<reg32 offset="0x0231" name="CP_DEBUG_ECO_CONTROL"/>
+	<reg32 offset="0x0232" name="CP_DRAW_STATE_ADDR"/>
+	<array offset="0x0240" name="CP_PROTECT" stride="1" length="16">
+		<reg32 offset="0x0" name="REG" type="adreno_cp_protect"/>
+	</array>
+	<reg32 offset="0x0250" name="CP_PROTECT_CTRL"/>
+	<reg32 offset="0x04c0" name="CP_ST_BASE"/>
+	<reg32 offset="0x04ce" name="CP_STQ_AVAIL"/>
+	<reg32 offset="0x04d0" name="CP_MERCIU_STAT"/>
+	<reg32 offset="0x04d2" name="CP_WFI_PEND_CTR"/>
+	<reg32 offset="0x04d8" name="CP_HW_FAULT"/>
+	<reg32 offset="0x04da" name="CP_PROTECT_STATUS"/>
+	<reg32 offset="0x04dd" name="CP_EVENTS_IN_FLIGHT"/>
+	<reg32 offset="0x0500" name="CP_PERFCTR_CP_SEL_0" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0501" name="CP_PERFCTR_CP_SEL_1" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0502" name="CP_PERFCTR_CP_SEL_2" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0503" name="CP_PERFCTR_CP_SEL_3" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0504" name="CP_PERFCTR_CP_SEL_4" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0505" name="CP_PERFCTR_CP_SEL_5" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0506" name="CP_PERFCTR_CP_SEL_6" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0507" name="CP_PERFCTR_CP_SEL_7" type="a4xx_cp_perfcounter_select"/>
+	<reg32 offset="0x050b" name="CP_PERFCOMBINER_SELECT"/>
+	<array offset="0x0578" name="CP_SCRATCH" stride="1" length="23">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+
+
+	<!-- SP registers -->
+	<reg32 offset="0x0ec0" name="SP_VS_STATUS"/>
+	<reg32 offset="0x0ec3" name="SP_MODE_CONTROL"/>
+
+	<reg32 offset="0x0ec4" name="SP_PERFCTR_SP_SEL_0" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec5" name="SP_PERFCTR_SP_SEL_1" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec6" name="SP_PERFCTR_SP_SEL_2" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec7" name="SP_PERFCTR_SP_SEL_3" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec8" name="SP_PERFCTR_SP_SEL_4" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ec9" name="SP_PERFCTR_SP_SEL_5" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0eca" name="SP_PERFCTR_SP_SEL_6" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ecb" name="SP_PERFCTR_SP_SEL_7" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ecc" name="SP_PERFCTR_SP_SEL_8" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ecd" name="SP_PERFCTR_SP_SEL_9" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ece" name="SP_PERFCTR_SP_SEL_10" type="a4xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ecf" name="SP_PERFCTR_SP_SEL_11" type="a4xx_sp_perfcounter_select"/>
+
+	<reg32 offset="0x22c0" name="SP_SP_CTRL_REG">
+		<bitfield name="BINNING_PASS" pos="19" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x22c1" name="SP_INSTR_CACHE_CTRL">
+		<!-- set when VS in buffer mode: -->
+		<bitfield name="VS_BUFFER" pos="7" type="boolean"/>
+		<!-- set when FS in buffer mode: -->
+		<bitfield name="FS_BUFFER" pos="8" type="boolean"/>
+		<!-- set when both VS or FS in buffer mode: -->
+		<bitfield name="INSTR_BUFFER" pos="10" type="boolean"/>
+		<!-- TODO other bits probably matter when other stages active? -->
+	</reg32>
+
+	<bitset name="a4xx_sp_vs_fs_ctrl_reg0" inline="yes">
+		<!--
+			NOTE that SP_{VS,FS}_CTRL_REG1 are different, but so far REG0
+			appears to be the same..
+		-->
+		<bitfield name="THREADMODE" pos="0" type="a3xx_threadmode"/>
+		<!-- VARYING bit only for FS.. think it controls emitting (ei) flag? -->
+		<bitfield name="VARYING" pos="1" type="boolean"/>
+		<!-- maybe CACHEINVALID is two bits?? -->
+		<bitfield name="CACHEINVALID" pos="2" type="boolean"/>
+		<doc>
+			The full/half register footprint is in units of four components,
+			so if r0.x is used, that counts as all of r0.[xyzw] as used.
+			There are separate full/half register footprint values as the
+			full and half registers are independent (not overlapping).
+			Presumably the thread scheduler hardware allocates the full/half
+			register names from the actual physical register file and
+			handles the register renaming.
+		</doc>
+		<bitfield name="HALFREGFOOTPRINT" low="4" high="9" type="uint"/>
+		<bitfield name="FULLREGFOOTPRINT" low="10" high="15" type="uint"/>
+		<!-- maybe INOUTREGOVERLAP is a bitflag? -->
+		<bitfield name="INOUTREGOVERLAP" low="18" high="19" type="uint"/>
+		<bitfield name="THREADSIZE" pos="20" type="a3xx_threadsize"/>
+		<bitfield name="SUPERTHREADMODE" pos="21" type="boolean"/>
+		<bitfield name="PIXLODENABLE" pos="22" type="boolean"/>
+	</bitset>
+
+	<reg32 offset="0x22c4" name="SP_VS_CTRL_REG0" type="a4xx_sp_vs_fs_ctrl_reg0"/>
+	<reg32 offset="0x22c5" name="SP_VS_CTRL_REG1">
+		<bitfield name="CONSTLENGTH" low="0" high="7" type="uint"/>
+		<bitfield name="INITIALOUTSTANDING" low="24" high="30" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22c6" name="SP_VS_PARAM_REG">
+		<bitfield name="POSREGID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="PSIZEREGID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="TOTALVSOUTVAR" low="20" high="31" type="uint"/>
+	</reg32>
+	<array offset="0x22c7" name="SP_VS_OUT" stride="1" length="16">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="8" type="a3xx_regid"/>
+			<bitfield name="A_COMPMASK" low="9" high="12" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="24" type="a3xx_regid"/>
+			<bitfield name="B_COMPMASK" low="25" high="28" type="hex"/>
+		</reg32>
+	</array>
+	<array offset="0x22d8" name="SP_VS_VPC_DST" stride="1" length="8">
+		<reg32 offset="0x0" name="REG">
+			<doc>
+				These seem to be offsets for storage of the varyings.
+				Always seems to start from 8, possibly loc 0 and 4
+				are for gl_Position and gl_PointSize?
+			</doc>
+			<bitfield name="OUTLOC0" low="0" high="7" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="15" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="23" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="31" type="uint"/>
+		</reg32>
+	</array>
+
+	<reg32 offset="0x22e0" name="SP_VS_OBJ_OFFSET_REG">
+		<!-- always 00000000: -->
+		<doc>
+			From register spec:
+			SP_FS_OBJ_OFFSET_REG.CONSTOBJECTSTARTOFFSET [16:24]: Constant object
+			start offset in on chip RAM,
+			128bit aligned
+		</doc>
+		<bitfield name="CONSTOBJECTOFFSET" low="16" high="24" type="uint"/>
+		<bitfield name="SHADEROBJOFFSET" low="25" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22e1" name="SP_VS_OBJ_START"/>
+	<reg32 offset="0x22e2" name="SP_VS_PVT_MEM_PARAM"/>
+	<reg32 offset="0x22e3" name="SP_VS_PVT_MEM_ADDR"/>
+	<reg32 offset="0x22e5" name="SP_VS_LENGTH_REG" type="uint"/>
+	<reg32 offset="0x22e8" name="SP_FS_CTRL_REG0" type="a4xx_sp_vs_fs_ctrl_reg0"/>
+	<reg32 offset="0x22e9" name="SP_FS_CTRL_REG1">
+		<bitfield name="CONSTLENGTH" low="0" high="7" type="uint"/>
+		<bitfield name="FACENESS" pos="19" type="boolean"/>
+		<bitfield name="VARYING" pos="20" type="boolean"/>
+		<bitfield name="FRAGCOORD" pos="21" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x22ea" name="SP_FS_OBJ_OFFSET_REG">
+		<bitfield name="CONSTOBJECTOFFSET" low="16" high="24" type="uint"/>
+		<bitfield name="SHADEROBJOFFSET" low="25" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x22eb" name="SP_FS_OBJ_START"/>
+	<reg32 offset="0x22ec" name="SP_FS_PVT_MEM_PARAM"/>
+	<reg32 offset="0x22ed" name="SP_FS_PVT_MEM_ADDR"/>
+	<reg32 offset="0x22ef" name="SP_FS_LENGTH_REG" type="uint"/>
+	<reg32 offset="0x22f0" name="SP_FS_OUTPUT_REG">
+		<bitfield name="MRT" low="0" high="3" type="uint"/>
+		<bitfield name="DEPTH_ENABLE" pos="7" type="boolean"/>
+		<!-- TODO double check.. for now assume same as a3xx -->
+		<bitfield name="DEPTH_REGID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="SAMPLEMASK_REGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<array offset="0x22f1" name="SP_FS_MRT" stride="1" length="8">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="HALF_PRECISION" pos="8" type="boolean"/>
+			<bitfield name="COLOR_SINT" pos="10" type="boolean"/>
+			<bitfield name="COLOR_UINT" pos="11" type="boolean"/>
+			<bitfield name="MRTFORMAT" low="12" high="17" type="a4xx_color_fmt"/>
+			<bitfield name="COLOR_SRGB" pos="18" type="boolean"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x2300" name="SP_CS_CTRL_REG0" type="a4xx_sp_vs_fs_ctrl_reg0"/>
+	<reg32 offset="0x2301" name="SP_CS_OBJ_OFFSET_REG"/>
+	<reg32 offset="0x2302" name="SP_CS_OBJ_START"/>
+	<reg32 offset="0x2303" name="SP_CS_PVT_MEM_PARAM"/>
+	<reg32 offset="0x2304" name="SP_CS_PVT_MEM_ADDR"/>
+	<reg32 offset="0x2305" name="SP_CS_PVT_MEM_SIZE"/>
+	<reg32 offset="0x2306" name="SP_CS_LENGTH_REG" type="uint"/>
+	<reg32 offset="0x230d" name="SP_HS_OBJ_OFFSET_REG">
+		<bitfield name="CONSTOBJECTOFFSET" low="16" high="24" type="uint"/>
+		<bitfield name="SHADEROBJOFFSET" low="25" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x230e" name="SP_HS_OBJ_START"/>
+	<reg32 offset="0x230f" name="SP_HS_PVT_MEM_PARAM"/>
+	<reg32 offset="0x2310" name="SP_HS_PVT_MEM_ADDR"/>
+	<reg32 offset="0x2312" name="SP_HS_LENGTH_REG" type="uint"/>
+
+	<reg32 offset="0x231a" name="SP_DS_PARAM_REG">
+		<bitfield name="POSREGID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="TOTALGSOUTVAR" low="20" high="31" type="uint"/>
+	</reg32>
+	<array offset="0x231b" name="SP_DS_OUT" stride="1" length="16">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="8" type="a3xx_regid"/>
+			<bitfield name="A_COMPMASK" low="9" high="12" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="24" type="a3xx_regid"/>
+			<bitfield name="B_COMPMASK" low="25" high="28" type="hex"/>
+		</reg32>
+	</array>
+	<array offset="0x232c" name="SP_DS_VPC_DST" stride="1" length="8">
+		<reg32 offset="0x0" name="REG">
+			<doc>
+				These seem to be offsets for storage of the varyings.
+				Always seems to start from 8, possibly loc 0 and 4
+				are for gl_Position and gl_PointSize?
+			</doc>
+			<bitfield name="OUTLOC0" low="0" high="7" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="15" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="23" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="31" type="uint"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x2334" name="SP_DS_OBJ_OFFSET_REG">
+		<bitfield name="CONSTOBJECTOFFSET" low="16" high="24" type="uint"/>
+		<bitfield name="SHADEROBJOFFSET" low="25" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2335" name="SP_DS_OBJ_START"/>
+	<reg32 offset="0x2336" name="SP_DS_PVT_MEM_PARAM"/>
+	<reg32 offset="0x2337" name="SP_DS_PVT_MEM_ADDR"/>
+	<reg32 offset="0x2339" name="SP_DS_LENGTH_REG" type="uint"/>
+
+	<reg32 offset="0x2341" name="SP_GS_PARAM_REG">
+		<bitfield name="POSREGID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="PRIMREGID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="TOTALGSOUTVAR" low="20" high="31" type="uint"/>
+	</reg32>
+	<array offset="0x2342" name="SP_GS_OUT" stride="1" length="16">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="8" type="a3xx_regid"/>
+			<bitfield name="A_COMPMASK" low="9" high="12" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="24" type="a3xx_regid"/>
+			<bitfield name="B_COMPMASK" low="25" high="28" type="hex"/>
+		</reg32>
+	</array>
+	<array offset="0x2353" name="SP_GS_VPC_DST" stride="1" length="8">
+		<reg32 offset="0x0" name="REG">
+			<doc>
+				These seem to be offsets for storage of the varyings.
+				Always seems to start from 8, possibly loc 0 and 4
+				are for gl_Position and gl_PointSize?
+			</doc>
+			<bitfield name="OUTLOC0" low="0" high="7" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="15" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="23" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="31" type="uint"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x235b" name="SP_GS_OBJ_OFFSET_REG">
+		<bitfield name="CONSTOBJECTOFFSET" low="16" high="24" type="uint"/>
+		<bitfield name="SHADEROBJOFFSET" low="25" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x235c" name="SP_GS_OBJ_START"/>
+	<reg32 offset="0x235d" name="SP_GS_PVT_MEM_PARAM"/>
+	<reg32 offset="0x235e" name="SP_GS_PVT_MEM_ADDR"/>
+	<reg32 offset="0x2360" name="SP_GS_LENGTH_REG" type="uint"/>
+
+	<!-- VPC registers -->
+	<reg32 offset="0x0e60" name="VPC_DEBUG_RAM_SEL"/>
+	<reg32 offset="0x0e61" name="VPC_DEBUG_RAM_READ"/>
+	<reg32 offset="0x0e64" name="VPC_DEBUG_ECO_CONTROL"/>
+	<reg32 offset="0x0e65" name="VPC_PERFCTR_VPC_SEL_0" type="a4xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e66" name="VPC_PERFCTR_VPC_SEL_1" type="a4xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e67" name="VPC_PERFCTR_VPC_SEL_2" type="a4xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e68" name="VPC_PERFCTR_VPC_SEL_3" type="a4xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x2140" name="VPC_ATTR">
+		<bitfield name="TOTALATTR" low="0" high="8" type="uint"/>
+		<!-- PSIZE bit set if gl_PointSize written: -->
+		<bitfield name="PSIZE" pos="9" type="boolean"/>
+		<bitfield name="THRDASSIGN" low="12" high="13" type="uint"/>
+		<bitfield name="ENABLE" pos="25" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2141" name="VPC_PACK">
+		<bitfield name="NUMBYPASSVAR" low="0" high="7" type="uint"/>
+		<bitfield name="NUMFPNONPOSVAR" low="8" high="15" type="uint"/>
+		<bitfield name="NUMNONPOSVSVAR" low="16" high="23" type="uint"/>
+	</reg32>
+	<array offset="0x2142" name="VPC_VARYING_INTERP" stride="1" length="8">
+		<reg32 offset="0x0" name="MODE"/>
+	</array>
+	<array offset="0x214a" name="VPC_VARYING_PS_REPL" stride="1" length="8">
+		<reg32 offset="0x0" name="MODE"/>
+	</array>
+
+	<reg32 offset="0x216e" name="VPC_SO_FLUSH_WADDR_3"/>
+
+	<!-- VSC registers -->
+	<reg32 offset="0x0c00" name="VSC_BIN_SIZE">
+		<bitfield name="WIDTH" low="0" high="4" shr="5" type="uint"/>
+		<bitfield name="HEIGHT" low="5" high="9" shr="5" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0c01" name="VSC_SIZE_ADDRESS"/>
+	<reg32 offset="0x0c02" name="VSC_SIZE_ADDRESS2"/>
+	<reg32 offset="0x0c03" name="VSC_DEBUG_ECO_CONTROL"/>
+	<array offset="0x0c08" name="VSC_PIPE_CONFIG" stride="1" length="8">
+		<reg32 offset="0x0" name="REG">
+			<doc>
+				Configures the mapping between VSC_PIPE buffer and
+				bin, X/Y specify the bin index in the horiz/vert
+				direction (0,0 is upper left, 0,1 is leftmost bin
+				on second row, and so on).  W/H specify the number
+				of bins assigned to this VSC_PIPE in the horiz/vert
+				dimension.
+			</doc>
+			<bitfield name="X" low="0" high="9" type="uint"/>
+			<bitfield name="Y" low="10" high="19" type="uint"/>
+			<bitfield name="W" low="20" high="23" type="uint"/>
+			<bitfield name="H" low="24" high="27" type="uint"/>
+		</reg32>
+	</array>
+	<array offset="0x0c10" name="VSC_PIPE_DATA_ADDRESS" stride="1" length="8">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<array offset="0x0c18" name="VSC_PIPE_DATA_LENGTH" stride="1" length="8">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<reg32 offset="0x0c41" name="VSC_PIPE_PARTIAL_POSN_1"/>
+	<reg32 offset="0x0c50" name="VSC_PERFCTR_VSC_SEL_0" type="a4xx_vsc_perfcounter_select"/>
+	<reg32 offset="0x0c51" name="VSC_PERFCTR_VSC_SEL_1" type="a4xx_vsc_perfcounter_select"/>
+
+	<!-- VFD registers -->
+	<reg32 offset="0x0e40" name="VFD_DEBUG_CONTROL"/>
+	<reg32 offset="0x0e43" name="VFD_PERFCTR_VFD_SEL_0" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e44" name="VFD_PERFCTR_VFD_SEL_1" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e45" name="VFD_PERFCTR_VFD_SEL_2" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e46" name="VFD_PERFCTR_VFD_SEL_3" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e47" name="VFD_PERFCTR_VFD_SEL_4" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e48" name="VFD_PERFCTR_VFD_SEL_5" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e49" name="VFD_PERFCTR_VFD_SEL_6" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e4a" name="VFD_PERFCTR_VFD_SEL_7" type="a4xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x21d0" name="VGT_CL_INITIATOR"/>
+	<reg32 offset="0x21d9" name="VGT_EVENT_INITIATOR"/>
+	<reg32 offset="0x2200" name="VFD_CONTROL_0">
+		<doc>
+			TOTALATTRTOVS is # of attributes to vertex shader, in register
+			slots (ie. vec4+vec3 -> 7)
+		</doc>
+		<bitfield name="TOTALATTRTOVS" low="0" high="7" type="uint"/>
+		<doc>
+		BYPASSATTROVS seems to count varyings that are just directly
+		assigned from attributes (ie, "vFoo = aFoo;")
+		</doc>
+		<bitfield name="BYPASSATTROVS" low="9" high="16" type="uint"/>
+		<doc>STRMDECINSTRCNT is # of VFD_DECODE_INSTR registers valid</doc>
+		<bitfield name="STRMDECINSTRCNT" low="20" high="25" type="uint"/>
+		<doc>STRMFETCHINSTRCNT is # of VFD_FETCH_INSTR registers valid</doc>
+		<bitfield name="STRMFETCHINSTRCNT" low="26" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2201" name="VFD_CONTROL_1">
+		<doc>MAXSTORAGE could be # of attributes/vbo's</doc>
+		<bitfield name="MAXSTORAGE" low="0" high="15" type="uint"/>
+		<bitfield name="REGID4VTX" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="REGID4INST" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x2202" name="VFD_CONTROL_2"/>
+	<reg32 offset="0x2203" name="VFD_CONTROL_3">
+		<bitfield name="REGID_VTXCNT" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="REGID_TESSX" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="REGID_TESSY" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x2204" name="VFD_CONTROL_4"/>
+	<reg32 offset="0x2208" name="VFD_INDEX_OFFSET"/>
+	<array offset="0x220a" name="VFD_FETCH" stride="4" length="32">
+		<reg32 offset="0x0" name="INSTR_0">
+			<bitfield name="FETCHSIZE" low="0" high="6" type="uint"/>
+			<bitfield name="BUFSTRIDE" low="7" high="16" type="uint"/>
+			<bitfield name="SWITCHNEXT" pos="19" type="boolean"/>
+			<bitfield name="INSTANCED" pos="20" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x1" name="INSTR_1"/>
+		<reg32 offset="0x2" name="INSTR_2">
+			<bitfield name="SIZE" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="0x3" name="INSTR_3">
+			<!-- might well be bigger.. -->
+			<bitfield name="STEPRATE" low="0" high="8" type="uint"/>
+		</reg32>
+	</array>
+	<array offset="0x228a" name="VFD_DECODE" stride="1" length="32">
+		<reg32 offset="0x0" name="INSTR">
+			<bitfield name="WRITEMASK" low="0" high="3" type="hex"/>
+			<!-- not sure if this is a bit flag and another flag above it, or?? -->
+			<bitfield name="CONSTFILL" pos="4" type="boolean"/>
+			<bitfield name="FORMAT" low="6" high="11" type="a4xx_vtx_fmt"/>
+			<bitfield name="REGID" low="12" high="19" type="a3xx_regid"/>
+			<bitfield name="INT" pos="20" type="boolean"/>
+			<doc>SHIFTCNT appears to be size, ie. FLOAT_32_32_32 is 12, and BYTE_8 is 1</doc>
+			<bitfield name="SWAP" low="22" high="23" type="a3xx_color_swap"/>
+			<bitfield name="SHIFTCNT" low="24" high="28" type="uint"/>
+			<bitfield name="LASTCOMPVALID" pos="29" type="boolean"/>
+			<bitfield name="SWITCHNEXT" pos="30" type="boolean"/>
+		</reg32>
+	</array>
+
+	<!-- TPL1 registers -->
+	<reg32 offset="0x0f00" name="TPL1_DEBUG_ECO_CONTROL"/>
+	<!-- always 0000003a: -->
+	<reg32 offset="0x0f03" name="TPL1_TP_MODE_CONTROL"/>
+	<reg32 offset="0x0f04" name="TPL1_PERFCTR_TP_SEL_0" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f05" name="TPL1_PERFCTR_TP_SEL_1" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f06" name="TPL1_PERFCTR_TP_SEL_2" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f07" name="TPL1_PERFCTR_TP_SEL_3" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f08" name="TPL1_PERFCTR_TP_SEL_4" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f09" name="TPL1_PERFCTR_TP_SEL_5" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f0a" name="TPL1_PERFCTR_TP_SEL_6" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f0b" name="TPL1_PERFCTR_TP_SEL_7" type="a4xx_tp_perfcounter_select"/>
+	<reg32 offset="0x2380" name="TPL1_TP_TEX_OFFSET"/>
+	<reg32 offset="0x2381" name="TPL1_TP_TEX_COUNT">
+		<bitfield name="VS" low="0" high="7" type="uint"/>
+		<bitfield name="HS" low="8" high="15" type="uint"/>
+		<bitfield name="DS" low="16" high="23" type="uint"/>
+		<bitfield name="GS" low="24" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2384" name="TPL1_TP_VS_BORDER_COLOR_BASE_ADDR"/>
+	<reg32 offset="0x2387" name="TPL1_TP_HS_BORDER_COLOR_BASE_ADDR"/>
+	<reg32 offset="0x238a" name="TPL1_TP_DS_BORDER_COLOR_BASE_ADDR"/>
+	<reg32 offset="0x238d" name="TPL1_TP_GS_BORDER_COLOR_BASE_ADDR"/>
+	<reg32 offset="0x23a0" name="TPL1_TP_FS_TEX_COUNT">
+		<bitfield name="FS" low="0" high="7" type="uint"/>
+		<bitfield name="CS" low="8" high="15" type="uint"/>
+	</reg32>
+	<reg32 offset="0x23a1" name="TPL1_TP_FS_BORDER_COLOR_BASE_ADDR"/>
+	<reg32 offset="0x23a4" name="TPL1_TP_CS_BORDER_COLOR_BASE_ADDR"/>
+	<reg32 offset="0x23a5" name="TPL1_TP_CS_SAMPLER_BASE_ADDR"/>
+	<reg32 offset="0x23a6" name="TPL1_TP_CS_TEXMEMOBJ_BASE_ADDR"/>
+
+	<!-- GRAS registers -->
+	<reg32 offset="0x0c80" name="GRAS_TSE_STATUS"/>
+	<reg32 offset="0x0c81" name="GRAS_DEBUG_ECO_CONTROL"/>
+	<reg32 offset="0x0c88" name="GRAS_PERFCTR_TSE_SEL_0" type="a4xx_gras_tse_perfcounter_select"/>
+	<reg32 offset="0x0c89" name="GRAS_PERFCTR_TSE_SEL_1" type="a4xx_gras_tse_perfcounter_select"/>
+	<reg32 offset="0x0c8a" name="GRAS_PERFCTR_TSE_SEL_2" type="a4xx_gras_tse_perfcounter_select"/>
+	<reg32 offset="0x0c8b" name="GRAS_PERFCTR_TSE_SEL_3" type="a4xx_gras_tse_perfcounter_select"/>
+	<reg32 offset="0x0c8c" name="GRAS_PERFCTR_RAS_SEL_0" type="a4xx_gras_ras_perfcounter_select"/>
+	<reg32 offset="0x0c8d" name="GRAS_PERFCTR_RAS_SEL_1" type="a4xx_gras_ras_perfcounter_select"/>
+	<reg32 offset="0x0c8e" name="GRAS_PERFCTR_RAS_SEL_2" type="a4xx_gras_ras_perfcounter_select"/>
+	<reg32 offset="0x0c8f" name="GRAS_PERFCTR_RAS_SEL_3" type="a4xx_gras_ras_perfcounter_select"/>
+	<reg32 offset="0x2000" name="GRAS_CL_CLIP_CNTL">
+		<bitfield name="CLIP_DISABLE" pos="15" type="boolean"/>
+		<bitfield name="ZNEAR_CLIP_DISABLE" pos="16" type="boolean"/>
+		<bitfield name="ZFAR_CLIP_DISABLE" pos="17" type="boolean"/>
+		<bitfield name="ZERO_GB_SCALE_Z" pos="22" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2003" name="GRAS_CNTL">
+		<bitfield name="IJ_PERSP" pos="0" type="boolean"/>
+		<bitfield name="IJ_LINEAR" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2004" name="GRAS_CL_GB_CLIP_ADJ">
+		<bitfield name="HORZ" low="0" high="9" type="uint"/>
+		<bitfield name="VERT" low="10" high="19" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2008" name="GRAS_CL_VPORT_XOFFSET_0" type="float"/>
+	<reg32 offset="0x2009" name="GRAS_CL_VPORT_XSCALE_0" type="float"/>
+	<reg32 offset="0x200a" name="GRAS_CL_VPORT_YOFFSET_0" type="float"/>
+	<reg32 offset="0x200b" name="GRAS_CL_VPORT_YSCALE_0" type="float"/>
+	<reg32 offset="0x200c" name="GRAS_CL_VPORT_ZOFFSET_0" type="float"/>
+	<reg32 offset="0x200d" name="GRAS_CL_VPORT_ZSCALE_0" type="float"/>
+	<reg32 offset="0x2070" name="GRAS_SU_POINT_MINMAX">
+		<bitfield name="MIN" low="0" high="15" type="ufixed" radix="4"/>
+		<bitfield name="MAX" low="16" high="31" type="ufixed" radix="4"/>
+	</reg32>
+	<reg32 offset="0x2071" name="GRAS_SU_POINT_SIZE" type="fixed" radix="4"/>
+	<reg32 offset="0x2073" name="GRAS_ALPHA_CONTROL">
+		<bitfield name="ALPHA_TEST_ENABLE" pos="2" type="boolean"/>
+		<bitfield name="FORCE_FRAGZ_TO_FS" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x2074" name="GRAS_SU_POLY_OFFSET_SCALE" type="float"/>
+	<reg32 offset="0x2075" name="GRAS_SU_POLY_OFFSET_OFFSET" type="float"/>
+	<reg32 offset="0x2076" name="GRAS_SU_POLY_OFFSET_CLAMP" type="float"/>
+	<reg32 offset="0x2077" name="GRAS_DEPTH_CONTROL">
+		<!-- guestimating that this is GRAS based on addr -->
+		<bitfield name="FORMAT" low="0" high="1" type="a4xx_depth_format"/>
+	</reg32>
+	<reg32 offset="0x2078" name="GRAS_SU_MODE_CONTROL">
+		<bitfield name="CULL_FRONT" pos="0" type="boolean"/>
+		<bitfield name="CULL_BACK" pos="1" type="boolean"/>
+		<bitfield name="FRONT_CW" pos="2" type="boolean"/>
+		<bitfield name="LINEHALFWIDTH" low="3" high="10" radix="2" type="fixed"/>
+		<bitfield name="POLY_OFFSET" pos="11" type="boolean"/>
+		<bitfield name="MSAA_ENABLE" pos="13" type="boolean"/>
+		<!-- bit20 set whenever RENDER_MODE = RB_RENDERING_PASS -->
+		<bitfield name="RENDERING_PASS" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x207b" name="GRAS_SC_CONTROL">
+		<!-- complete wild-ass-guess for sizes of these bitfields.. -->
+		<bitfield name="RENDER_MODE" low="2" high="3" type="a3xx_render_mode"/>
+		<bitfield name="MSAA_SAMPLES" low="7" high="9" type="uint"/>
+		<bitfield name="MSAA_DISABLE" pos="11" type="boolean"/>
+		<bitfield name="RASTER_MODE" low="12" high="15"/>
+	</reg32>
+	<reg32 offset="0x207c" name="GRAS_SC_SCREEN_SCISSOR_TL" type="adreno_reg_xy"/>
+	<reg32 offset="0x207d" name="GRAS_SC_SCREEN_SCISSOR_BR" type="adreno_reg_xy"/>
+	<reg32 offset="0x209c" name="GRAS_SC_WINDOW_SCISSOR_BR" type="adreno_reg_xy"/>
+	<reg32 offset="0x209d" name="GRAS_SC_WINDOW_SCISSOR_TL" type="adreno_reg_xy"/>
+	<reg32 offset="0x209e" name="GRAS_SC_EXTENT_WINDOW_BR" type="adreno_reg_xy"/>
+	<reg32 offset="0x209f" name="GRAS_SC_EXTENT_WINDOW_TL" type="adreno_reg_xy"/>
+
+	<!-- UCHE registers -->
+	<reg32 offset="0x0e80" name="UCHE_CACHE_MODE_CONTROL"/>
+	<reg32 offset="0x0e83" name="UCHE_TRAP_BASE_LO"/>
+	<reg32 offset="0x0e84" name="UCHE_TRAP_BASE_HI"/>
+	<reg32 offset="0x0e88" name="UCHE_CACHE_STATUS"/>
+	<reg32 offset="0x0e8a" name="UCHE_INVALIDATE0"/>
+	<reg32 offset="0x0e8b" name="UCHE_INVALIDATE1"/>
+	<reg32 offset="0x0e8c" name="UCHE_CACHE_WAYS_VFD"/>
+	<reg32 offset="0x0e8e" name="UCHE_PERFCTR_UCHE_SEL_0" type="a4xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e8f" name="UCHE_PERFCTR_UCHE_SEL_1" type="a4xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e90" name="UCHE_PERFCTR_UCHE_SEL_2" type="a4xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e91" name="UCHE_PERFCTR_UCHE_SEL_3" type="a4xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e92" name="UCHE_PERFCTR_UCHE_SEL_4" type="a4xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e93" name="UCHE_PERFCTR_UCHE_SEL_5" type="a4xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e94" name="UCHE_PERFCTR_UCHE_SEL_6" type="a4xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0e95" name="UCHE_PERFCTR_UCHE_SEL_7" type="a4xx_uche_perfcounter_select"/>
+
+	<!-- HLSQ registers -->
+	<reg32 offset="0x0e00" name="HLSQ_TIMEOUT_THRESHOLD"/>
+	<reg32 offset="0x0e04" name="HLSQ_DEBUG_ECO_CONTROL"/>
+	<!-- always 00000000: -->
+	<reg32 offset="0x0e05" name="HLSQ_MODE_CONTROL"/>
+	<reg32 offset="0x0e0e" name="HLSQ_PERF_PIPE_MASK"/>
+	<reg32 offset="0x0e06" name="HLSQ_PERFCTR_HLSQ_SEL_0" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e07" name="HLSQ_PERFCTR_HLSQ_SEL_1" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e08" name="HLSQ_PERFCTR_HLSQ_SEL_2" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e09" name="HLSQ_PERFCTR_HLSQ_SEL_3" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e0a" name="HLSQ_PERFCTR_HLSQ_SEL_4" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e0b" name="HLSQ_PERFCTR_HLSQ_SEL_5" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e0c" name="HLSQ_PERFCTR_HLSQ_SEL_6" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e0d" name="HLSQ_PERFCTR_HLSQ_SEL_7" type="a4xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x23c0" name="HLSQ_CONTROL_0_REG">
+		<!-- I guess same as a3xx, but so far only seen 08000050 -->
+		<bitfield name="FSTHREADSIZE" pos="4" type="a3xx_threadsize"/>
+		<bitfield name="FSSUPERTHREADENABLE" pos="6" type="boolean"/>
+		<bitfield name="SPSHADERRESTART" pos="9" type="boolean"/>
+		<bitfield name="RESERVED2" pos="10" type="boolean"/>
+		<bitfield name="CHUNKDISABLE" pos="26" type="boolean"/>
+		<bitfield name="CONSTMODE" pos="27" type="uint"/>
+		<bitfield name="LAZYUPDATEDISABLE" pos="28" type="boolean"/>
+		<bitfield name="SPCONSTFULLUPDATE" pos="29" type="boolean"/>
+		<bitfield name="TPFULLUPDATE" pos="30" type="boolean"/>
+		<bitfield name="SINGLECONTEXT" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x23c1" name="HLSQ_CONTROL_1_REG">
+		<bitfield name="VSTHREADSIZE" pos="6" type="a3xx_threadsize"/>
+		<bitfield name="VSSUPERTHREADENABLE" pos="8" type="boolean"/>
+		<bitfield name="RESERVED1" pos="9" type="boolean"/>
+		<bitfield name="COORDREGID" low="16" high="23" type="a3xx_regid"/>
+		<!-- set if gl_FragCoord.[zw] used in frag shader: -->
+		<bitfield name="ZWCOORDREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x23c2" name="HLSQ_CONTROL_2_REG">
+		<bitfield name="PRIMALLOCTHRESHOLD" low="26" high="31" type="uint"/>
+		<bitfield name="FACEREGID" low="2" high="9" type="a3xx_regid"/>
+		<bitfield name="SAMPLEID_REGID" low="10" high="17" type="a3xx_regid"/>
+		<bitfield name="SAMPLEMASK_REGID" low="18" high="25" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x23c3" name="HLSQ_CONTROL_3_REG">
+		<!-- register loaded with position (bary.f) -->
+		<bitfield name="IJ_PERSP_PIXEL" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_PIXEL" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="IJ_PERSP_CENTROID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_CENTROID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<!-- 0x23c4 3 regids, lowest one goes to 0 when *not* per-sample shading -->
+	<reg32 offset="0x23c4" name="HLSQ_CONTROL_4_REG">
+		<bitfield name="IJ_PERSP_SAMPLE" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_SAMPLE" low="8" high="15" type="a3xx_regid"/>
+	</reg32>
+
+	<bitset name="a4xx_xs_control_reg" inline="yes">
+		<bitfield name="CONSTLENGTH" low="0" high="7" type="uint"/>
+		<bitfield name="CONSTOBJECTOFFSET" low="8" high="14" type="uint"/>
+		<bitfield name="SSBO_ENABLE" pos="15" type="boolean"/>
+		<bitfield name="ENABLED" pos="16" type="boolean"/>
+		<bitfield name="SHADEROBJOFFSET" low="17" high="23" type="uint"/>
+		<bitfield name="INSTRLENGTH" low="24" high="31" type="uint"/>
+	</bitset>
+	<reg32 offset="0x23c5" name="HLSQ_VS_CONTROL_REG" type="a4xx_xs_control_reg"/>
+	<reg32 offset="0x23c6" name="HLSQ_FS_CONTROL_REG" type="a4xx_xs_control_reg"/>
+	<reg32 offset="0x23c7" name="HLSQ_HS_CONTROL_REG" type="a4xx_xs_control_reg"/>
+	<reg32 offset="0x23c8" name="HLSQ_DS_CONTROL_REG" type="a4xx_xs_control_reg"/>
+	<reg32 offset="0x23c9" name="HLSQ_GS_CONTROL_REG" type="a4xx_xs_control_reg"/>
+	<reg32 offset="0x23ca" name="HLSQ_CS_CONTROL_REG" type="a4xx_xs_control_reg"/>
+	<reg32 offset="0x23cd" name="HLSQ_CL_NDRANGE_0">
+		<bitfield name="KERNELDIM" low="0" high="1" type="uint"/>
+		<!-- localsize is value minus one: -->
+		<bitfield name="LOCALSIZEX" low="2" high="11" type="uint"/>
+		<bitfield name="LOCALSIZEY" low="12" high="21" type="uint"/>
+		<bitfield name="LOCALSIZEZ" low="22" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x23ce" name="HLSQ_CL_NDRANGE_1">
+		<bitfield name="SIZE_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x23cf" name="HLSQ_CL_NDRANGE_2"/>
+	<reg32 offset="0x23d0" name="HLSQ_CL_NDRANGE_3">
+		<bitfield name="SIZE_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x23d1" name="HLSQ_CL_NDRANGE_4"/>
+	<reg32 offset="0x23d2" name="HLSQ_CL_NDRANGE_5">
+		<bitfield name="SIZE_Z" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x23d3" name="HLSQ_CL_NDRANGE_6"/>
+	<reg32 offset="0x23d4" name="HLSQ_CL_CONTROL_0">
+		<bitfield name="WGIDCONSTID" low="0" high="11" type="a3xx_regid"/>
+		<bitfield name="KERNELDIMCONSTID" low="12" high="23" type="a3xx_regid"/>
+		<bitfield name="LOCALIDREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x23d5" name="HLSQ_CL_CONTROL_1">
+		<!-- GLOBALSIZECONSTID? "kernel size" -->
+		<bitfield name="UNK0CONSTID" low="0" high="11" type="a3xx_regid"/>
+		<bitfield name="WORKGROUPSIZECONSTID" low="12" high="23" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x23d6" name="HLSQ_CL_KERNEL_CONST">
+		<!-- GLOBALOFFSETCONSTID -->
+		<bitfield name="UNK0CONSTID" low="0" high="11" type="a3xx_regid"/>
+		<bitfield name="NUMWGCONSTID" low="12" high="23" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x23d7" name="HLSQ_CL_KERNEL_GROUP_X"/>
+	<reg32 offset="0x23d8" name="HLSQ_CL_KERNEL_GROUP_Y"/>
+	<reg32 offset="0x23d9" name="HLSQ_CL_KERNEL_GROUP_Z"/>
+	<reg32 offset="0x23da" name="HLSQ_CL_WG_OFFSET">
+		<!-- WGOFFSETCONSTID -->
+		<bitfield name="UNK0CONSTID" low="0" high="11" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0x23db" name="HLSQ_UPDATE_CONTROL"/>
+
+	<!-- PC registers -->
+	<reg32 offset="0x0d00" name="PC_BINNING_COMMAND">
+		<bitfield name="BINNING_ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0d08" name="PC_TESSFACTOR_ADDR"/>
+	<reg32 offset="0x0d0c" name="PC_DRAWCALL_SETUP_OVERRIDE"/>
+	<reg32 offset="0x0d10" name="PC_PERFCTR_PC_SEL_0" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d11" name="PC_PERFCTR_PC_SEL_1" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d12" name="PC_PERFCTR_PC_SEL_2" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d13" name="PC_PERFCTR_PC_SEL_3" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d14" name="PC_PERFCTR_PC_SEL_4" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d15" name="PC_PERFCTR_PC_SEL_5" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d16" name="PC_PERFCTR_PC_SEL_6" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d17" name="PC_PERFCTR_PC_SEL_7" type="a4xx_pc_perfcounter_select"/>
+	<reg32 offset="0x21c0" name="PC_BIN_BASE"/>
+	<reg32 offset="0x21c2" name="PC_VSTREAM_CONTROL">
+		<doc>SIZE is current pipe width * height (in tiles)</doc>
+		<bitfield name="SIZE" low="16" high="21" type="uint"/>
+		<doc>
+			N is some sort of slot # between 0..(SIZE-1).  In case
+			multiple tiles use same pipe, each tile gets unique slot #
+		</doc>
+		<bitfield name="N" low="22" high="26" type="uint"/>
+	</reg32>
+	<reg32 offset="0x21c4" name="PC_PRIM_VTX_CNTL">
+		<!-- bit0 set if there is >= 1 varying (actually used by FS) -->
+		<bitfield name="VAROUT" low="0" high="3" type="uint">
+			<doc>in groups of 4x vec4, blob only uses values
+			0, 1, 2, 4, 6, 8</doc>
+		</bitfield>
+		<bitfield name="PRIMITIVE_RESTART" pos="20" type="boolean"/>
+		<bitfield name="PROVOKING_VTX_LAST" pos="25" type="boolean"/>
+		<!-- PSIZE bit set if gl_PointSize written: -->
+		<bitfield name="PSIZE" pos="26" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x21c5" name="PC_PRIM_VTX_CNTL2">
+		<bitfield name="POLYMODE_FRONT_PTYPE" low="0" high="2" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="POLYMODE_BACK_PTYPE" low="3" high="5" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="POLYMODE_ENABLE" pos="6" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x21c6" name="PC_RESTART_INDEX"/>
+	<reg32 offset="0x21e5" name="PC_GS_PARAM">
+		<bitfield name="MAX_VERTICES" low="0" high="9" type="uint"/><!-- +1, i.e. max is 1024 -->
+		<bitfield name="INVOCATIONS" low="11" high="15" type="uint"/><!-- +1, i.e. max is 32 -->
+		<bitfield name="PRIMTYPE" low="23" high="24" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="LAYER" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x21e7" name="PC_HS_PARAM">
+		<bitfield name="VERTICES_OUT" low="0" high="5" type="uint"/>
+		<bitfield name="SPACING" low="21" high="22" type="a4xx_tess_spacing"/>
+		<bitfield name="CW" pos="23" type="boolean"/>
+		<bitfield name="CONNECTED" pos="24" type="boolean"/>
+	</reg32>
+
+	<!-- VBIF registers -->
+	<reg32 offset="0x3000" name="VBIF_VERSION"/>
+	<reg32 offset="0x3001" name="VBIF_CLKON">
+		<bitfield name="FORCE_ON_TESTBUS" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x301c" name="VBIF_ABIT_SORT"/>
+	<reg32 offset="0x301d" name="VBIF_ABIT_SORT_CONF"/>
+	<reg32 offset="0x302a" name="VBIF_GATE_OFF_WRREQ_EN"/>
+	<reg32 offset="0x302c" name="VBIF_IN_RD_LIM_CONF0"/>
+	<reg32 offset="0x302d" name="VBIF_IN_RD_LIM_CONF1"/>
+	<reg32 offset="0x3030" name="VBIF_IN_WR_LIM_CONF0"/>
+	<reg32 offset="0x3031" name="VBIF_IN_WR_LIM_CONF1"/>
+	<reg32 offset="0x3049" name="VBIF_ROUND_ROBIN_QOS_ARB"/>
+	<reg32 offset="0x30c0" name="VBIF_PERF_CNT_EN0"/>
+	<reg32 offset="0x30c1" name="VBIF_PERF_CNT_EN1"/>
+	<reg32 offset="0x30c2" name="VBIF_PERF_CNT_EN2"/>
+	<reg32 offset="0x30c3" name="VBIF_PERF_CNT_EN3"/>
+	<reg32 offset="0x30d0" name="VBIF_PERF_CNT_SEL0" type="a4xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d1" name="VBIF_PERF_CNT_SEL1" type="a4xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d2" name="VBIF_PERF_CNT_SEL2" type="a4xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d3" name="VBIF_PERF_CNT_SEL3" type="a4xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d8" name="VBIF_PERF_CNT_LOW0"/>
+	<reg32 offset="0x30d9" name="VBIF_PERF_CNT_LOW1"/>
+	<reg32 offset="0x30da" name="VBIF_PERF_CNT_LOW2"/>
+	<reg32 offset="0x30db" name="VBIF_PERF_CNT_LOW3"/>
+	<reg32 offset="0x30e0" name="VBIF_PERF_CNT_HIGH0"/>
+	<reg32 offset="0x30e1" name="VBIF_PERF_CNT_HIGH1"/>
+	<reg32 offset="0x30e2" name="VBIF_PERF_CNT_HIGH2"/>
+	<reg32 offset="0x30e3" name="VBIF_PERF_CNT_HIGH3"/>
+	<reg32 offset="0x3100" name="VBIF_PERF_PWR_CNT_EN0"/>
+	<reg32 offset="0x3101" name="VBIF_PERF_PWR_CNT_EN1"/>
+	<reg32 offset="0x3102" name="VBIF_PERF_PWR_CNT_EN2"/>
+
+	<!--
+	Unknown registers:
+	(mostly related to DX11 features not used yet, I guess?)
+	-->
+
+	<!-- always 00000006: -->
+	<reg32 offset="0x0cc5" name="UNKNOWN_0CC5"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x0cc6" name="UNKNOWN_0CC6"/>
+
+	<!-- always 00000001: -->
+	<reg32 offset="0x0d01" name="UNKNOWN_0D01"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x0e42" name="UNKNOWN_0E42"/>
+
+	<!-- always 00040000: -->
+	<reg32 offset="0x0ec2" name="UNKNOWN_0EC2"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2001" name="UNKNOWN_2001"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x209b" name="UNKNOWN_209B"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x20ef" name="UNKNOWN_20EF"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2152" name="UNKNOWN_2152"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2153" name="UNKNOWN_2153"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2154" name="UNKNOWN_2154"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2155" name="UNKNOWN_2155"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2156" name="UNKNOWN_2156"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2157" name="UNKNOWN_2157"/>
+
+	<!-- always 0000000b: -->
+	<reg32 offset="0x21c3" name="UNKNOWN_21C3"/>
+
+	<!-- always 00000001: -->
+	<reg32 offset="0x21e6" name="UNKNOWN_21E6"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x2209" name="UNKNOWN_2209"/>
+
+	<!-- always 00000000: -->
+	<reg32 offset="0x22d7" name="UNKNOWN_22D7"/>
+
+        <!-- always 00fcfc00: -->
+        <reg32 offset="0x2352" name="UNKNOWN_2352"/>
+
+</domain>
+
+
+<domain name="A4XX_TEX_SAMP" width="32">
+	<doc>Texture sampler dwords</doc>
+	<enum name="a4xx_tex_filter">
+		<value name="A4XX_TEX_NEAREST" value="0"/>
+		<value name="A4XX_TEX_LINEAR" value="1"/>
+		<value name="A4XX_TEX_ANISO" value="2"/>
+	</enum>
+	<enum name="a4xx_tex_clamp">
+		<value name="A4XX_TEX_REPEAT" value="0"/>
+		<value name="A4XX_TEX_CLAMP_TO_EDGE" value="1"/>
+		<value name="A4XX_TEX_MIRROR_REPEAT" value="2"/>
+		<value name="A4XX_TEX_CLAMP_TO_BORDER" value="3"/>
+		<value name="A4XX_TEX_MIRROR_CLAMP" value="4"/>
+	</enum>
+	<enum name="a4xx_tex_aniso">
+		<value name="A4XX_TEX_ANISO_1" value="0"/>
+		<value name="A4XX_TEX_ANISO_2" value="1"/>
+		<value name="A4XX_TEX_ANISO_4" value="2"/>
+		<value name="A4XX_TEX_ANISO_8" value="3"/>
+		<value name="A4XX_TEX_ANISO_16" value="4"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="MIPFILTER_LINEAR_NEAR" pos="0" type="boolean"/>
+		<bitfield name="XY_MAG" low="1" high="2" type="a4xx_tex_filter"/>
+		<bitfield name="XY_MIN" low="3" high="4" type="a4xx_tex_filter"/>
+		<bitfield name="WRAP_S" low="5" high="7" type="a4xx_tex_clamp"/>
+		<bitfield name="WRAP_T" low="8" high="10" type="a4xx_tex_clamp"/>
+		<bitfield name="WRAP_R" low="11" high="13" type="a4xx_tex_clamp"/>
+		<bitfield name="ANISO" low="14" high="16" type="a4xx_tex_aniso"/>
+		<bitfield name="LOD_BIAS" low="19" high="31" type="fixed" radix="8"/><!-- no idea how many bits for real -->
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="COMPARE_FUNC" low="1" high="3" type="adreno_compare_func"/>
+		<bitfield name="CUBEMAPSEAMLESSFILTOFF" pos="4" type="boolean"/>
+		<bitfield name="UNNORM_COORDS" pos="5" type="boolean"/>
+		<bitfield name="MIPFILTER_LINEAR_FAR" pos="6" type="boolean"/>
+		<bitfield name="MAX_LOD" low="8" high="19" type="ufixed" radix="8"/>
+		<bitfield name="MIN_LOD" low="20" high="31" type="ufixed" radix="8"/>
+	</reg32>
+</domain>
+
+<domain name="A4XX_TEX_CONST" width="32">
+	<doc>Texture constant dwords</doc>
+	<enum name="a4xx_tex_swiz">
+		<!-- same as a2xx? -->
+		<value name="A4XX_TEX_X" value="0"/>
+		<value name="A4XX_TEX_Y" value="1"/>
+		<value name="A4XX_TEX_Z" value="2"/>
+		<value name="A4XX_TEX_W" value="3"/>
+		<value name="A4XX_TEX_ZERO" value="4"/>
+		<value name="A4XX_TEX_ONE" value="5"/>
+	</enum>
+	<enum name="a4xx_tex_type">
+		<value name="A4XX_TEX_1D" value="0"/>
+		<value name="A4XX_TEX_2D" value="1"/>
+		<value name="A4XX_TEX_CUBE" value="2"/>
+		<value name="A4XX_TEX_3D" value="3"/>
+		<value name="A4XX_TEX_BUFFER" value="4"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="TILED" pos="0" type="boolean"/>
+		<bitfield name="SRGB" pos="2" type="boolean"/>
+		<bitfield name="SWIZ_X" low="4" high="6" type="a4xx_tex_swiz"/>
+		<bitfield name="SWIZ_Y" low="7" high="9" type="a4xx_tex_swiz"/>
+		<bitfield name="SWIZ_Z" low="10" high="12" type="a4xx_tex_swiz"/>
+		<bitfield name="SWIZ_W" low="13" high="15" type="a4xx_tex_swiz"/>
+		<bitfield name="MIPLVLS" low="16" high="19" type="uint"/>
+		<bitfield name="FMT" low="22" high="28" type="a4xx_tex_fmt"/>
+		<bitfield name="TYPE" low="29" high="31" type="a4xx_tex_type"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="HEIGHT" low="0" high="14" type="uint"/>
+		<bitfield name="WIDTH" low="15" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<!-- minimum pitch (for mipmap levels): log2(pitchalign / 32) -->
+		<bitfield name="PITCHALIGN" low="0" high="3" type="uint"/>
+		<bitfield name="BUFFER" pos="6" type="boolean"/>
+		<doc>Pitch in bytes (so actually stride)</doc>
+		<bitfield name="PITCH" low="9" high="29" type="uint"/>
+		<bitfield name="SWAP" low="30" high="31" type="a3xx_color_swap"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="LAYERSZ" low="0" high="13" shr="12" type="uint"/>
+		<bitfield name="DEPTH" low="18" high="30" type="uint"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<!--
+		like a3xx we seem to have two LAYERSZ's.. although this one
+		seems too small to be useful, and when it overflows blob just
+		sets it to zero..
+		 -->
+		<bitfield name="LAYERSZ" low="0" high="3" shr="12" type="uint"/>
+		<bitfield name="BASE" low="5" high="31" shr="5"/>
+	</reg32>
+	<reg32 offset="5" name="5"/>
+	<reg32 offset="6" name="6"/>
+	<reg32 offset="7" name="7"/>
+</domain>
+
+<domain name="A4XX_SSBO_0" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="BASE" low="5" high="31" shr="5"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<doc>Pitch in bytes (so actually stride)</doc>
+		<bitfield name="PITCH" low="0" high="21" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="ARRAY_PITCH" low="12" high="25" shr="12" type="uint"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<!-- bytes per pixel: -->
+		<bitfield name="CPP" low="0" high="5" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="A4XX_SSBO_1" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="CPP" low="0" high="4" type="uint"/>
+		<bitfield name="FMT" low="8" high="15" type="a4xx_color_fmt"/>
+		<bitfield name="WIDTH" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="HEIGHT" low="0" high="15" type="uint"/>
+		<bitfield name="DEPTH" low="16" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/adreno/a5xx.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/adreno/a5xx.xml
@@ -0,0 +1,3039 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="adreno/adreno_common.xml"/>
+<import file="adreno/adreno_pm4.xml"/>
+
+<enum name="a5xx_color_fmt">
+	<value value="0x02" name="RB5_A8_UNORM"/>
+	<value value="0x03" name="RB5_R8_UNORM"/>
+	<value value="0x04" name="RB5_R8_SNORM"/>
+	<value value="0x05" name="RB5_R8_UINT"/>
+	<value value="0x06" name="RB5_R8_SINT"/>
+	<value value="0x08" name="RB5_R4G4B4A4_UNORM"/>
+	<value value="0x0a" name="RB5_R5G5B5A1_UNORM"/>
+	<value value="0x0e" name="RB5_R5G6B5_UNORM"/>
+	<value value="0x0f" name="RB5_R8G8_UNORM"/>
+	<value value="0x10" name="RB5_R8G8_SNORM"/>
+	<value value="0x11" name="RB5_R8G8_UINT"/>
+	<value value="0x12" name="RB5_R8G8_SINT"/>
+	<value value="0x15" name="RB5_R16_UNORM"/>
+	<value value="0x16" name="RB5_R16_SNORM"/>
+	<value value="0x17" name="RB5_R16_FLOAT"/>
+	<value value="0x18" name="RB5_R16_UINT"/>
+	<value value="0x19" name="RB5_R16_SINT"/>
+	<value value="0x30" name="RB5_R8G8B8A8_UNORM"/>
+	<value value="0x31" name="RB5_R8G8B8_UNORM"/>
+	<value value="0x32" name="RB5_R8G8B8A8_SNORM"/>
+	<value value="0x33" name="RB5_R8G8B8A8_UINT"/>
+	<value value="0x34" name="RB5_R8G8B8A8_SINT"/>
+	<value value="0x37" name="RB5_R10G10B10A2_UNORM"/>  <!-- GL_RGB10_A2 -->
+	<value value="0x3a" name="RB5_R10G10B10A2_UINT"/>   <!-- GL_RGB10_A2UI -->
+	<value value="0x42" name="RB5_R11G11B10_FLOAT"/>    <!-- GL_R11F_G11F_B10F -->
+	<value value="0x43" name="RB5_R16G16_UNORM"/>
+	<value value="0x44" name="RB5_R16G16_SNORM"/>
+	<value value="0x45" name="RB5_R16G16_FLOAT"/>
+	<value value="0x46" name="RB5_R16G16_UINT"/>
+	<value value="0x47" name="RB5_R16G16_SINT"/>
+	<value value="0x4a" name="RB5_R32_FLOAT"/>
+	<value value="0x4b" name="RB5_R32_UINT"/>
+	<value value="0x4c" name="RB5_R32_SINT"/>
+	<value value="0x60" name="RB5_R16G16B16A16_UNORM"/>
+	<value value="0x61" name="RB5_R16G16B16A16_SNORM"/>
+	<value value="0x62" name="RB5_R16G16B16A16_FLOAT"/>
+	<value value="0x63" name="RB5_R16G16B16A16_UINT"/>
+	<value value="0x64" name="RB5_R16G16B16A16_SINT"/>
+	<value value="0x67" name="RB5_R32G32_FLOAT"/>
+	<value value="0x68" name="RB5_R32G32_UINT"/>
+	<value value="0x69" name="RB5_R32G32_SINT"/>
+	<value value="0x82" name="RB5_R32G32B32A32_FLOAT"/>
+	<value value="0x83" name="RB5_R32G32B32A32_UINT"/>
+	<value value="0x84" name="RB5_R32G32B32A32_SINT"/>
+
+	<value value="0xff" name="RB5_NONE"/>
+</enum>
+
+<enum name="a5xx_tile_mode">
+	<value name="TILE5_LINEAR" value="0"/>
+	<value name="TILE5_2" value="2"/>
+	<value name="TILE5_3" value="3"/>
+</enum>
+
+<enum name="a5xx_vtx_fmt" prefix="chipset">
+	<value value="0x03" name="VFMT5_8_UNORM"/>
+	<value value="0x04" name="VFMT5_8_SNORM"/>
+	<value value="0x05" name="VFMT5_8_UINT"/>
+	<value value="0x06" name="VFMT5_8_SINT"/>
+
+	<value value="0x0f" name="VFMT5_8_8_UNORM"/>
+	<value value="0x10" name="VFMT5_8_8_SNORM"/>
+	<value value="0x11" name="VFMT5_8_8_UINT"/>
+	<value value="0x12" name="VFMT5_8_8_SINT"/>
+
+	<value value="0x15" name="VFMT5_16_UNORM"/>
+	<value value="0x16" name="VFMT5_16_SNORM"/>
+	<value value="0x17" name="VFMT5_16_FLOAT"/>
+	<value value="0x18" name="VFMT5_16_UINT"/>
+	<value value="0x19" name="VFMT5_16_SINT"/>
+
+	<value value="0x21" name="VFMT5_8_8_8_UNORM"/>
+	<value value="0x22" name="VFMT5_8_8_8_SNORM"/>
+	<value value="0x23" name="VFMT5_8_8_8_UINT"/>
+	<value value="0x24" name="VFMT5_8_8_8_SINT"/>
+
+	<value value="0x30" name="VFMT5_8_8_8_8_UNORM"/>
+	<value value="0x32" name="VFMT5_8_8_8_8_SNORM"/>
+	<value value="0x33" name="VFMT5_8_8_8_8_UINT"/>
+	<value value="0x34" name="VFMT5_8_8_8_8_SINT"/>
+
+	<value value="0x36" name="VFMT5_10_10_10_2_UNORM"/>
+	<value value="0x39" name="VFMT5_10_10_10_2_SNORM"/>
+	<value value="0x3a" name="VFMT5_10_10_10_2_UINT"/>
+	<value value="0x3b" name="VFMT5_10_10_10_2_SINT"/>
+
+	<value value="0x42" name="VFMT5_11_11_10_FLOAT"/>
+
+	<value value="0x43" name="VFMT5_16_16_UNORM"/>
+	<value value="0x44" name="VFMT5_16_16_SNORM"/>
+	<value value="0x45" name="VFMT5_16_16_FLOAT"/>
+	<value value="0x46" name="VFMT5_16_16_UINT"/>
+	<value value="0x47" name="VFMT5_16_16_SINT"/>
+
+	<value value="0x48" name="VFMT5_32_UNORM"/>
+	<value value="0x49" name="VFMT5_32_SNORM"/>
+	<value value="0x4a" name="VFMT5_32_FLOAT"/>
+	<value value="0x4b" name="VFMT5_32_UINT"/>
+	<value value="0x4c" name="VFMT5_32_SINT"/>
+	<value value="0x4d" name="VFMT5_32_FIXED"/>
+
+	<value value="0x58" name="VFMT5_16_16_16_UNORM"/>
+	<value value="0x59" name="VFMT5_16_16_16_SNORM"/>
+	<value value="0x5a" name="VFMT5_16_16_16_FLOAT"/>
+	<value value="0x5b" name="VFMT5_16_16_16_UINT"/>
+	<value value="0x5c" name="VFMT5_16_16_16_SINT"/>
+
+	<value value="0x60" name="VFMT5_16_16_16_16_UNORM"/>
+	<value value="0x61" name="VFMT5_16_16_16_16_SNORM"/>
+	<value value="0x62" name="VFMT5_16_16_16_16_FLOAT"/>
+	<value value="0x63" name="VFMT5_16_16_16_16_UINT"/>
+	<value value="0x64" name="VFMT5_16_16_16_16_SINT"/>
+
+	<value value="0x65" name="VFMT5_32_32_UNORM"/>
+	<value value="0x66" name="VFMT5_32_32_SNORM"/>
+	<value value="0x67" name="VFMT5_32_32_FLOAT"/>
+	<value value="0x68" name="VFMT5_32_32_UINT"/>
+	<value value="0x69" name="VFMT5_32_32_SINT"/>
+	<value value="0x6a" name="VFMT5_32_32_FIXED"/>
+
+	<value value="0x70" name="VFMT5_32_32_32_UNORM"/>
+	<value value="0x71" name="VFMT5_32_32_32_SNORM"/>
+	<value value="0x72" name="VFMT5_32_32_32_UINT"/>
+	<value value="0x73" name="VFMT5_32_32_32_SINT"/>
+	<value value="0x74" name="VFMT5_32_32_32_FLOAT"/>
+	<value value="0x75" name="VFMT5_32_32_32_FIXED"/>
+
+	<value value="0x80" name="VFMT5_32_32_32_32_UNORM"/>
+	<value value="0x81" name="VFMT5_32_32_32_32_SNORM"/>
+	<value value="0x82" name="VFMT5_32_32_32_32_FLOAT"/>
+	<value value="0x83" name="VFMT5_32_32_32_32_UINT"/>
+	<value value="0x84" name="VFMT5_32_32_32_32_SINT"/>
+	<value value="0x85" name="VFMT5_32_32_32_32_FIXED"/>
+
+	<value value="0xff" name="VFMT5_NONE"/>
+</enum>
+
+<enum name="a5xx_tex_fmt">
+	<value value="0x02" name="TFMT5_A8_UNORM"/>
+	<value value="0x03" name="TFMT5_8_UNORM"/>
+	<value value="0x04" name="TFMT5_8_SNORM"/>
+	<value value="0x05" name="TFMT5_8_UINT"/>
+	<value value="0x06" name="TFMT5_8_SINT"/>
+	<value value="0x08" name="TFMT5_4_4_4_4_UNORM"/>
+	<value value="0x0a" name="TFMT5_5_5_5_1_UNORM"/>
+	<value value="0x0e" name="TFMT5_5_6_5_UNORM"/>
+	<value value="0x0f" name="TFMT5_8_8_UNORM"/>
+	<value value="0x10" name="TFMT5_8_8_SNORM"/>
+	<value value="0x11" name="TFMT5_8_8_UINT"/>
+	<value value="0x12" name="TFMT5_8_8_SINT"/>
+	<value value="0x13" name="TFMT5_L8_A8_UNORM"/>
+	<value value="0x15" name="TFMT5_16_UNORM"/>
+	<value value="0x16" name="TFMT5_16_SNORM"/>
+	<value value="0x17" name="TFMT5_16_FLOAT"/>
+	<value value="0x18" name="TFMT5_16_UINT"/>
+	<value value="0x19" name="TFMT5_16_SINT"/>
+	<value value="0x30" name="TFMT5_8_8_8_8_UNORM"/>
+	<value value="0x31" name="TFMT5_8_8_8_UNORM"/>
+	<value value="0x32" name="TFMT5_8_8_8_8_SNORM"/>
+	<value value="0x33" name="TFMT5_8_8_8_8_UINT"/>
+	<value value="0x34" name="TFMT5_8_8_8_8_SINT"/>
+	<value value="0x35" name="TFMT5_9_9_9_E5_FLOAT"/>
+	<value value="0x36" name="TFMT5_10_10_10_2_UNORM"/>
+	<value value="0x3a" name="TFMT5_10_10_10_2_UINT"/>
+	<value value="0x42" name="TFMT5_11_11_10_FLOAT"/>
+	<value value="0x43" name="TFMT5_16_16_UNORM"/>
+	<value value="0x44" name="TFMT5_16_16_SNORM"/>
+	<value value="0x45" name="TFMT5_16_16_FLOAT"/>
+	<value value="0x46" name="TFMT5_16_16_UINT"/>
+	<value value="0x47" name="TFMT5_16_16_SINT"/>
+	<value value="0x4a" name="TFMT5_32_FLOAT"/>
+	<value value="0x4b" name="TFMT5_32_UINT"/>
+	<value value="0x4c" name="TFMT5_32_SINT"/>
+	<value value="0x60" name="TFMT5_16_16_16_16_UNORM"/>
+	<value value="0x61" name="TFMT5_16_16_16_16_SNORM"/>
+	<value value="0x62" name="TFMT5_16_16_16_16_FLOAT"/>
+	<value value="0x63" name="TFMT5_16_16_16_16_UINT"/>
+	<value value="0x64" name="TFMT5_16_16_16_16_SINT"/>
+	<value value="0x67" name="TFMT5_32_32_FLOAT"/>
+	<value value="0x68" name="TFMT5_32_32_UINT"/>
+	<value value="0x69" name="TFMT5_32_32_SINT"/>
+	<value value="0x72" name="TFMT5_32_32_32_UINT"/>
+	<value value="0x73" name="TFMT5_32_32_32_SINT"/>
+	<value value="0x74" name="TFMT5_32_32_32_FLOAT"/>
+	<value value="0x82" name="TFMT5_32_32_32_32_FLOAT"/>
+	<value value="0x83" name="TFMT5_32_32_32_32_UINT"/>
+	<value value="0x84" name="TFMT5_32_32_32_32_SINT"/>
+	<value value="0xa0" name="TFMT5_X8Z24_UNORM"/>
+
+	<value value="0xab" name="TFMT5_ETC2_RG11_UNORM"/>
+	<value value="0xac" name="TFMT5_ETC2_RG11_SNORM"/>
+	<value value="0xad" name="TFMT5_ETC2_R11_UNORM"/>
+	<value value="0xae" name="TFMT5_ETC2_R11_SNORM"/>
+	<value value="0xaf" name="TFMT5_ETC1"/>
+	<value value="0xb0" name="TFMT5_ETC2_RGB8"/>
+	<value value="0xb1" name="TFMT5_ETC2_RGBA8"/>
+	<value value="0xb2" name="TFMT5_ETC2_RGB8A1"/>
+	<value value="0xb3" name="TFMT5_DXT1"/>
+	<value value="0xb4" name="TFMT5_DXT3"/>
+	<value value="0xb5" name="TFMT5_DXT5"/>
+	<value value="0xb7" name="TFMT5_RGTC1_UNORM"/>
+	<value value="0xb8" name="TFMT5_RGTC1_SNORM"/>
+	<value value="0xbb" name="TFMT5_RGTC2_UNORM"/>
+	<value value="0xbc" name="TFMT5_RGTC2_SNORM"/>
+	<value value="0xbe" name="TFMT5_BPTC_UFLOAT"/>
+	<value value="0xbf" name="TFMT5_BPTC_FLOAT"/>
+	<value value="0xc0" name="TFMT5_BPTC"/>
+	<value value="0xc1" name="TFMT5_ASTC_4x4"/>
+	<value value="0xc2" name="TFMT5_ASTC_5x4"/>
+	<value value="0xc3" name="TFMT5_ASTC_5x5"/>
+	<value value="0xc4" name="TFMT5_ASTC_6x5"/>
+	<value value="0xc5" name="TFMT5_ASTC_6x6"/>
+	<value value="0xc6" name="TFMT5_ASTC_8x5"/>
+	<value value="0xc7" name="TFMT5_ASTC_8x6"/>
+	<value value="0xc8" name="TFMT5_ASTC_8x8"/>
+	<value value="0xc9" name="TFMT5_ASTC_10x5"/>
+	<value value="0xca" name="TFMT5_ASTC_10x6"/>
+	<value value="0xcb" name="TFMT5_ASTC_10x8"/>
+	<value value="0xcc" name="TFMT5_ASTC_10x10"/>
+	<value value="0xcd" name="TFMT5_ASTC_12x10"/>
+	<value value="0xce" name="TFMT5_ASTC_12x12"/>
+
+	<value value="0xff" name="TFMT5_NONE"/>
+</enum>
+
+<enum name="a5xx_depth_format">
+	<value name="DEPTH5_NONE" value="0"/>
+	<value name="DEPTH5_16" value="1"/>
+	<value name="DEPTH5_24_8" value="2"/>
+	<value name="DEPTH5_32" value="4"/>
+</enum>
+
+<enum name="a5xx_blit_buf">
+	<value value="0" name="BLIT_MRT0"/>
+	<value value="1" name="BLIT_MRT1"/>
+	<value value="2" name="BLIT_MRT2"/>
+	<value value="3" name="BLIT_MRT3"/>
+	<value value="4" name="BLIT_MRT4"/>
+	<value value="5" name="BLIT_MRT5"/>
+	<value value="6" name="BLIT_MRT6"/>
+	<value value="7" name="BLIT_MRT7"/>
+	<value value="8" name="BLIT_ZS"/>       <!-- depth or combined depth+stencil -->
+	<value value="9" name="BLIT_S"/>        <!-- separate stencil -->
+</enum>
+
+<!-- see comment in a4xx.xml about script to extract countables from test-perf output -->
+<enum name="a5xx_cp_perfcounter_select">
+	<value value="0" name="PERF_CP_ALWAYS_COUNT"/>
+	<value value="1" name="PERF_CP_BUSY_GFX_CORE_IDLE"/>
+	<value value="2" name="PERF_CP_BUSY_CYCLES"/>
+	<value value="3" name="PERF_CP_PFP_IDLE"/>
+	<value value="4" name="PERF_CP_PFP_BUSY_WORKING"/>
+	<value value="5" name="PERF_CP_PFP_STALL_CYCLES_ANY"/>
+	<value value="6" name="PERF_CP_PFP_STARVE_CYCLES_ANY"/>
+	<value value="7" name="PERF_CP_PFP_ICACHE_MISS"/>
+	<value value="8" name="PERF_CP_PFP_ICACHE_HIT"/>
+	<value value="9" name="PERF_CP_PFP_MATCH_PM4_PKT_PROFILE"/>
+	<value value="10" name="PERF_CP_ME_BUSY_WORKING"/>
+	<value value="11" name="PERF_CP_ME_IDLE"/>
+	<value value="12" name="PERF_CP_ME_STARVE_CYCLES_ANY"/>
+	<value value="13" name="PERF_CP_ME_FIFO_EMPTY_PFP_IDLE"/>
+	<value value="14" name="PERF_CP_ME_FIFO_EMPTY_PFP_BUSY"/>
+	<value value="15" name="PERF_CP_ME_FIFO_FULL_ME_BUSY"/>
+	<value value="16" name="PERF_CP_ME_FIFO_FULL_ME_NON_WORKING"/>
+	<value value="17" name="PERF_CP_ME_STALL_CYCLES_ANY"/>
+	<value value="18" name="PERF_CP_ME_ICACHE_MISS"/>
+	<value value="19" name="PERF_CP_ME_ICACHE_HIT"/>
+	<value value="20" name="PERF_CP_NUM_PREEMPTIONS"/>
+	<value value="21" name="PERF_CP_PREEMPTION_REACTION_DELAY"/>
+	<value value="22" name="PERF_CP_PREEMPTION_SWITCH_OUT_TIME"/>
+	<value value="23" name="PERF_CP_PREEMPTION_SWITCH_IN_TIME"/>
+	<value value="24" name="PERF_CP_DEAD_DRAWS_IN_BIN_RENDER"/>
+	<value value="25" name="PERF_CP_PREDICATED_DRAWS_KILLED"/>
+	<value value="26" name="PERF_CP_MODE_SWITCH"/>
+	<value value="27" name="PERF_CP_ZPASS_DONE"/>
+	<value value="28" name="PERF_CP_CONTEXT_DONE"/>
+	<value value="29" name="PERF_CP_CACHE_FLUSH"/>
+	<value value="30" name="PERF_CP_LONG_PREEMPTIONS"/>
+</enum>
+
+<enum name="a5xx_rbbm_perfcounter_select">
+	<value value="0" name="PERF_RBBM_ALWAYS_COUNT"/>
+	<value value="1" name="PERF_RBBM_ALWAYS_ON"/>
+	<value value="2" name="PERF_RBBM_TSE_BUSY"/>
+	<value value="3" name="PERF_RBBM_RAS_BUSY"/>
+	<value value="4" name="PERF_RBBM_PC_DCALL_BUSY"/>
+	<value value="5" name="PERF_RBBM_PC_VSD_BUSY"/>
+	<value value="6" name="PERF_RBBM_STATUS_MASKED"/>
+	<value value="7" name="PERF_RBBM_COM_BUSY"/>
+	<value value="8" name="PERF_RBBM_DCOM_BUSY"/>
+	<value value="9" name="PERF_RBBM_VBIF_BUSY"/>
+	<value value="10" name="PERF_RBBM_VSC_BUSY"/>
+	<value value="11" name="PERF_RBBM_TESS_BUSY"/>
+	<value value="12" name="PERF_RBBM_UCHE_BUSY"/>
+	<value value="13" name="PERF_RBBM_HLSQ_BUSY"/>
+</enum>
+
+<enum name="a5xx_pc_perfcounter_select">
+	<value value="0" name="PERF_PC_BUSY_CYCLES"/>
+	<value value="1" name="PERF_PC_WORKING_CYCLES"/>
+	<value value="2" name="PERF_PC_STALL_CYCLES_VFD"/>
+	<value value="3" name="PERF_PC_STALL_CYCLES_TSE"/>
+	<value value="4" name="PERF_PC_STALL_CYCLES_VPC"/>
+	<value value="5" name="PERF_PC_STALL_CYCLES_UCHE"/>
+	<value value="6" name="PERF_PC_STALL_CYCLES_TESS"/>
+	<value value="7" name="PERF_PC_STALL_CYCLES_TSE_ONLY"/>
+	<value value="8" name="PERF_PC_STALL_CYCLES_VPC_ONLY"/>
+	<value value="9" name="PERF_PC_PASS1_TF_STALL_CYCLES"/>
+	<value value="10" name="PERF_PC_STARVE_CYCLES_FOR_INDEX"/>
+	<value value="11" name="PERF_PC_STARVE_CYCLES_FOR_TESS_FACTOR"/>
+	<value value="12" name="PERF_PC_STARVE_CYCLES_FOR_VIZ_STREAM"/>
+	<value value="13" name="PERF_PC_STARVE_CYCLES_FOR_POSITION"/>
+	<value value="14" name="PERF_PC_STARVE_CYCLES_DI"/>
+	<value value="15" name="PERF_PC_VIS_STREAMS_LOADED"/>
+	<value value="16" name="PERF_PC_INSTANCES"/>
+	<value value="17" name="PERF_PC_VPC_PRIMITIVES"/>
+	<value value="18" name="PERF_PC_DEAD_PRIM"/>
+	<value value="19" name="PERF_PC_LIVE_PRIM"/>
+	<value value="20" name="PERF_PC_VERTEX_HITS"/>
+	<value value="21" name="PERF_PC_IA_VERTICES"/>
+	<value value="22" name="PERF_PC_IA_PRIMITIVES"/>
+	<value value="23" name="PERF_PC_GS_PRIMITIVES"/>
+	<value value="24" name="PERF_PC_HS_INVOCATIONS"/>
+	<value value="25" name="PERF_PC_DS_INVOCATIONS"/>
+	<value value="26" name="PERF_PC_VS_INVOCATIONS"/>
+	<value value="27" name="PERF_PC_GS_INVOCATIONS"/>
+	<value value="28" name="PERF_PC_DS_PRIMITIVES"/>
+	<value value="29" name="PERF_PC_VPC_POS_DATA_TRANSACTION"/>
+	<value value="30" name="PERF_PC_3D_DRAWCALLS"/>
+	<value value="31" name="PERF_PC_2D_DRAWCALLS"/>
+	<value value="32" name="PERF_PC_NON_DRAWCALL_GLOBAL_EVENTS"/>
+	<value value="33" name="PERF_TESS_BUSY_CYCLES"/>
+	<value value="34" name="PERF_TESS_WORKING_CYCLES"/>
+	<value value="35" name="PERF_TESS_STALL_CYCLES_PC"/>
+	<value value="36" name="PERF_TESS_STARVE_CYCLES_PC"/>
+</enum>
+
+<enum name="a5xx_vfd_perfcounter_select">
+	<value value="0" name="PERF_VFD_BUSY_CYCLES"/>
+	<value value="1" name="PERF_VFD_STALL_CYCLES_UCHE"/>
+	<value value="2" name="PERF_VFD_STALL_CYCLES_VPC_ALLOC"/>
+	<value value="3" name="PERF_VFD_STALL_CYCLES_MISS_VB"/>
+	<value value="4" name="PERF_VFD_STALL_CYCLES_MISS_Q"/>
+	<value value="5" name="PERF_VFD_STALL_CYCLES_SP_INFO"/>
+	<value value="6" name="PERF_VFD_STALL_CYCLES_SP_ATTR"/>
+	<value value="7" name="PERF_VFD_STALL_CYCLES_VFDP_VB"/>
+	<value value="8" name="PERF_VFD_STALL_CYCLES_VFDP_Q"/>
+	<value value="9" name="PERF_VFD_DECODER_PACKER_STALL"/>
+	<value value="10" name="PERF_VFD_STARVE_CYCLES_UCHE"/>
+	<value value="11" name="PERF_VFD_RBUFFER_FULL"/>
+	<value value="12" name="PERF_VFD_ATTR_INFO_FIFO_FULL"/>
+	<value value="13" name="PERF_VFD_DECODED_ATTRIBUTE_BYTES"/>
+	<value value="14" name="PERF_VFD_NUM_ATTRIBUTES"/>
+	<value value="15" name="PERF_VFD_INSTRUCTIONS"/>
+	<value value="16" name="PERF_VFD_UPPER_SHADER_FIBERS"/>
+	<value value="17" name="PERF_VFD_LOWER_SHADER_FIBERS"/>
+	<value value="18" name="PERF_VFD_MODE_0_FIBERS"/>
+	<value value="19" name="PERF_VFD_MODE_1_FIBERS"/>
+	<value value="20" name="PERF_VFD_MODE_2_FIBERS"/>
+	<value value="21" name="PERF_VFD_MODE_3_FIBERS"/>
+	<value value="22" name="PERF_VFD_MODE_4_FIBERS"/>
+	<value value="23" name="PERF_VFD_TOTAL_VERTICES"/>
+	<value value="24" name="PERF_VFD_NUM_ATTR_MISS"/>
+	<value value="25" name="PERF_VFD_1_BURST_REQ"/>
+	<value value="26" name="PERF_VFDP_STALL_CYCLES_VFD"/>
+	<value value="27" name="PERF_VFDP_STALL_CYCLES_VFD_INDEX"/>
+	<value value="28" name="PERF_VFDP_STALL_CYCLES_VFD_PROG"/>
+	<value value="29" name="PERF_VFDP_STARVE_CYCLES_PC"/>
+	<value value="30" name="PERF_VFDP_VS_STAGE_32_WAVES"/>
+</enum>
+
+<enum name="a5xx_hlsq_perfcounter_select">
+	<value value="0" name="PERF_HLSQ_BUSY_CYCLES"/>
+	<value value="1" name="PERF_HLSQ_STALL_CYCLES_UCHE"/>
+	<value value="2" name="PERF_HLSQ_STALL_CYCLES_SP_STATE"/>
+	<value value="3" name="PERF_HLSQ_STALL_CYCLES_SP_FS_STAGE"/>
+	<value value="4" name="PERF_HLSQ_UCHE_LATENCY_CYCLES"/>
+	<value value="5" name="PERF_HLSQ_UCHE_LATENCY_COUNT"/>
+	<value value="6" name="PERF_HLSQ_FS_STAGE_32_WAVES"/>
+	<value value="7" name="PERF_HLSQ_FS_STAGE_64_WAVES"/>
+	<value value="8" name="PERF_HLSQ_QUADS"/>
+	<value value="9" name="PERF_HLSQ_SP_STATE_COPY_TRANS_FS_STAGE"/>
+	<value value="10" name="PERF_HLSQ_SP_STATE_COPY_TRANS_VS_STAGE"/>
+	<value value="11" name="PERF_HLSQ_TP_STATE_COPY_TRANS_FS_STAGE"/>
+	<value value="12" name="PERF_HLSQ_TP_STATE_COPY_TRANS_VS_STAGE"/>
+	<value value="13" name="PERF_HLSQ_CS_INVOCATIONS"/>
+	<value value="14" name="PERF_HLSQ_COMPUTE_DRAWCALLS"/>
+</enum>
+
+<enum name="a5xx_vpc_perfcounter_select">
+	<value value="0" name="PERF_VPC_BUSY_CYCLES"/>
+	<value value="1" name="PERF_VPC_WORKING_CYCLES"/>
+	<value value="2" name="PERF_VPC_STALL_CYCLES_UCHE"/>
+	<value value="3" name="PERF_VPC_STALL_CYCLES_VFD_WACK"/>
+	<value value="4" name="PERF_VPC_STALL_CYCLES_HLSQ_PRIM_ALLOC"/>
+	<value value="5" name="PERF_VPC_STALL_CYCLES_PC"/>
+	<value value="6" name="PERF_VPC_STALL_CYCLES_SP_LM"/>
+	<value value="7" name="PERF_VPC_POS_EXPORT_STALL_CYCLES"/>
+	<value value="8" name="PERF_VPC_STARVE_CYCLES_SP"/>
+	<value value="9" name="PERF_VPC_STARVE_CYCLES_LRZ"/>
+	<value value="10" name="PERF_VPC_PC_PRIMITIVES"/>
+	<value value="11" name="PERF_VPC_SP_COMPONENTS"/>
+	<value value="12" name="PERF_VPC_SP_LM_PRIMITIVES"/>
+	<value value="13" name="PERF_VPC_SP_LM_COMPONENTS"/>
+	<value value="14" name="PERF_VPC_SP_LM_DWORDS"/>
+	<value value="15" name="PERF_VPC_STREAMOUT_COMPONENTS"/>
+	<value value="16" name="PERF_VPC_GRANT_PHASES"/>
+</enum>
+
+<enum name="a5xx_tse_perfcounter_select">
+	<value value="0" name="PERF_TSE_BUSY_CYCLES"/>
+	<value value="1" name="PERF_TSE_CLIPPING_CYCLES"/>
+	<value value="2" name="PERF_TSE_STALL_CYCLES_RAS"/>
+	<value value="3" name="PERF_TSE_STALL_CYCLES_LRZ_BARYPLANE"/>
+	<value value="4" name="PERF_TSE_STALL_CYCLES_LRZ_ZPLANE"/>
+	<value value="5" name="PERF_TSE_STARVE_CYCLES_PC"/>
+	<value value="6" name="PERF_TSE_INPUT_PRIM"/>
+	<value value="7" name="PERF_TSE_INPUT_NULL_PRIM"/>
+	<value value="8" name="PERF_TSE_TRIVAL_REJ_PRIM"/>
+	<value value="9" name="PERF_TSE_CLIPPED_PRIM"/>
+	<value value="10" name="PERF_TSE_ZERO_AREA_PRIM"/>
+	<value value="11" name="PERF_TSE_FACENESS_CULLED_PRIM"/>
+	<value value="12" name="PERF_TSE_ZERO_PIXEL_PRIM"/>
+	<value value="13" name="PERF_TSE_OUTPUT_NULL_PRIM"/>
+	<value value="14" name="PERF_TSE_OUTPUT_VISIBLE_PRIM"/>
+	<value value="15" name="PERF_TSE_CINVOCATION"/>
+	<value value="16" name="PERF_TSE_CPRIMITIVES"/>
+	<value value="17" name="PERF_TSE_2D_INPUT_PRIM"/>
+	<value value="18" name="PERF_TSE_2D_ALIVE_CLCLES"/>
+</enum>
+
+<enum name="a5xx_ras_perfcounter_select">
+	<value value="0" name="PERF_RAS_BUSY_CYCLES"/>
+	<value value="1" name="PERF_RAS_SUPERTILE_ACTIVE_CYCLES"/>
+	<value value="2" name="PERF_RAS_STALL_CYCLES_LRZ"/>
+	<value value="3" name="PERF_RAS_STARVE_CYCLES_TSE"/>
+	<value value="4" name="PERF_RAS_SUPER_TILES"/>
+	<value value="5" name="PERF_RAS_8X4_TILES"/>
+	<value value="6" name="PERF_RAS_MASKGEN_ACTIVE"/>
+	<value value="7" name="PERF_RAS_FULLY_COVERED_SUPER_TILES"/>
+	<value value="8" name="PERF_RAS_FULLY_COVERED_8X4_TILES"/>
+	<value value="9" name="PERF_RAS_PRIM_KILLED_INVISILBE"/>
+</enum>
+
+<enum name="a5xx_lrz_perfcounter_select">
+	<value value="0" name="PERF_LRZ_BUSY_CYCLES"/>
+	<value value="1" name="PERF_LRZ_STARVE_CYCLES_RAS"/>
+	<value value="2" name="PERF_LRZ_STALL_CYCLES_RB"/>
+	<value value="3" name="PERF_LRZ_STALL_CYCLES_VSC"/>
+	<value value="4" name="PERF_LRZ_STALL_CYCLES_VPC"/>
+	<value value="5" name="PERF_LRZ_STALL_CYCLES_FLAG_PREFETCH"/>
+	<value value="6" name="PERF_LRZ_STALL_CYCLES_UCHE"/>
+	<value value="7" name="PERF_LRZ_LRZ_READ"/>
+	<value value="8" name="PERF_LRZ_LRZ_WRITE"/>
+	<value value="9" name="PERF_LRZ_READ_LATENCY"/>
+	<value value="10" name="PERF_LRZ_MERGE_CACHE_UPDATING"/>
+	<value value="11" name="PERF_LRZ_PRIM_KILLED_BY_MASKGEN"/>
+	<value value="12" name="PERF_LRZ_PRIM_KILLED_BY_LRZ"/>
+	<value value="13" name="PERF_LRZ_VISIBLE_PRIM_AFTER_LRZ"/>
+	<value value="14" name="PERF_LRZ_FULL_8X8_TILES"/>
+	<value value="15" name="PERF_LRZ_PARTIAL_8X8_TILES"/>
+	<value value="16" name="PERF_LRZ_TILE_KILLED"/>
+	<value value="17" name="PERF_LRZ_TOTAL_PIXEL"/>
+	<value value="18" name="PERF_LRZ_VISIBLE_PIXEL_AFTER_LRZ"/>
+</enum>
+
+<enum name="a5xx_uche_perfcounter_select">
+	<value value="0" name="PERF_UCHE_BUSY_CYCLES"/>
+	<value value="1" name="PERF_UCHE_STALL_CYCLES_VBIF"/>
+	<value value="2" name="PERF_UCHE_VBIF_LATENCY_CYCLES"/>
+	<value value="3" name="PERF_UCHE_VBIF_LATENCY_SAMPLES"/>
+	<value value="4" name="PERF_UCHE_VBIF_READ_BEATS_TP"/>
+	<value value="5" name="PERF_UCHE_VBIF_READ_BEATS_VFD"/>
+	<value value="6" name="PERF_UCHE_VBIF_READ_BEATS_HLSQ"/>
+	<value value="7" name="PERF_UCHE_VBIF_READ_BEATS_LRZ"/>
+	<value value="8" name="PERF_UCHE_VBIF_READ_BEATS_SP"/>
+	<value value="9" name="PERF_UCHE_READ_REQUESTS_TP"/>
+	<value value="10" name="PERF_UCHE_READ_REQUESTS_VFD"/>
+	<value value="11" name="PERF_UCHE_READ_REQUESTS_HLSQ"/>
+	<value value="12" name="PERF_UCHE_READ_REQUESTS_LRZ"/>
+	<value value="13" name="PERF_UCHE_READ_REQUESTS_SP"/>
+	<value value="14" name="PERF_UCHE_WRITE_REQUESTS_LRZ"/>
+	<value value="15" name="PERF_UCHE_WRITE_REQUESTS_SP"/>
+	<value value="16" name="PERF_UCHE_WRITE_REQUESTS_VPC"/>
+	<value value="17" name="PERF_UCHE_WRITE_REQUESTS_VSC"/>
+	<value value="18" name="PERF_UCHE_EVICTS"/>
+	<value value="19" name="PERF_UCHE_BANK_REQ0"/>
+	<value value="20" name="PERF_UCHE_BANK_REQ1"/>
+	<value value="21" name="PERF_UCHE_BANK_REQ2"/>
+	<value value="22" name="PERF_UCHE_BANK_REQ3"/>
+	<value value="23" name="PERF_UCHE_BANK_REQ4"/>
+	<value value="24" name="PERF_UCHE_BANK_REQ5"/>
+	<value value="25" name="PERF_UCHE_BANK_REQ6"/>
+	<value value="26" name="PERF_UCHE_BANK_REQ7"/>
+	<value value="27" name="PERF_UCHE_VBIF_READ_BEATS_CH0"/>
+	<value value="28" name="PERF_UCHE_VBIF_READ_BEATS_CH1"/>
+	<value value="29" name="PERF_UCHE_GMEM_READ_BEATS"/>
+	<value value="30" name="PERF_UCHE_FLAG_COUNT"/>
+</enum>
+
+<enum name="a5xx_tp_perfcounter_select">
+	<value value="0" name="PERF_TP_BUSY_CYCLES"/>
+	<value value="1" name="PERF_TP_STALL_CYCLES_UCHE"/>
+	<value value="2" name="PERF_TP_LATENCY_CYCLES"/>
+	<value value="3" name="PERF_TP_LATENCY_TRANS"/>
+	<value value="4" name="PERF_TP_FLAG_CACHE_REQUEST_SAMPLES"/>
+	<value value="5" name="PERF_TP_FLAG_CACHE_REQUEST_LATENCY"/>
+	<value value="6" name="PERF_TP_L1_CACHELINE_REQUESTS"/>
+	<value value="7" name="PERF_TP_L1_CACHELINE_MISSES"/>
+	<value value="8" name="PERF_TP_SP_TP_TRANS"/>
+	<value value="9" name="PERF_TP_TP_SP_TRANS"/>
+	<value value="10" name="PERF_TP_OUTPUT_PIXELS"/>
+	<value value="11" name="PERF_TP_FILTER_WORKLOAD_16BIT"/>
+	<value value="12" name="PERF_TP_FILTER_WORKLOAD_32BIT"/>
+	<value value="13" name="PERF_TP_QUADS_RECEIVED"/>
+	<value value="14" name="PERF_TP_QUADS_OFFSET"/>
+	<value value="15" name="PERF_TP_QUADS_SHADOW"/>
+	<value value="16" name="PERF_TP_QUADS_ARRAY"/>
+	<value value="17" name="PERF_TP_QUADS_GRADIENT"/>
+	<value value="18" name="PERF_TP_QUADS_1D"/>
+	<value value="19" name="PERF_TP_QUADS_2D"/>
+	<value value="20" name="PERF_TP_QUADS_BUFFER"/>
+	<value value="21" name="PERF_TP_QUADS_3D"/>
+	<value value="22" name="PERF_TP_QUADS_CUBE"/>
+	<value value="23" name="PERF_TP_STATE_CACHE_REQUESTS"/>
+	<value value="24" name="PERF_TP_STATE_CACHE_MISSES"/>
+	<value value="25" name="PERF_TP_DIVERGENT_QUADS_RECEIVED"/>
+	<value value="26" name="PERF_TP_BINDLESS_STATE_CACHE_REQUESTS"/>
+	<value value="27" name="PERF_TP_BINDLESS_STATE_CACHE_MISSES"/>
+	<value value="28" name="PERF_TP_PRT_NON_RESIDENT_EVENTS"/>
+	<value value="29" name="PERF_TP_OUTPUT_PIXELS_POINT"/>
+	<value value="30" name="PERF_TP_OUTPUT_PIXELS_BILINEAR"/>
+	<value value="31" name="PERF_TP_OUTPUT_PIXELS_MIP"/>
+	<value value="32" name="PERF_TP_OUTPUT_PIXELS_ANISO"/>
+	<value value="33" name="PERF_TP_OUTPUT_PIXELS_ZERO_LOD"/>
+	<value value="34" name="PERF_TP_FLAG_CACHE_REQUESTS"/>
+	<value value="35" name="PERF_TP_FLAG_CACHE_MISSES"/>
+	<value value="36" name="PERF_TP_L1_5_L2_REQUESTS"/>
+	<value value="37" name="PERF_TP_2D_OUTPUT_PIXELS"/>
+	<value value="38" name="PERF_TP_2D_OUTPUT_PIXELS_POINT"/>
+	<value value="39" name="PERF_TP_2D_OUTPUT_PIXELS_BILINEAR"/>
+	<value value="40" name="PERF_TP_2D_FILTER_WORKLOAD_16BIT"/>
+	<value value="41" name="PERF_TP_2D_FILTER_WORKLOAD_32BIT"/>
+</enum>
+
+<enum name="a5xx_sp_perfcounter_select">
+	<value value="0" name="PERF_SP_BUSY_CYCLES"/>
+	<value value="1" name="PERF_SP_ALU_WORKING_CYCLES"/>
+	<value value="2" name="PERF_SP_EFU_WORKING_CYCLES"/>
+	<value value="3" name="PERF_SP_STALL_CYCLES_VPC"/>
+	<value value="4" name="PERF_SP_STALL_CYCLES_TP"/>
+	<value value="5" name="PERF_SP_STALL_CYCLES_UCHE"/>
+	<value value="6" name="PERF_SP_STALL_CYCLES_RB"/>
+	<value value="7" name="PERF_SP_SCHEDULER_NON_WORKING"/>
+	<value value="8" name="PERF_SP_WAVE_CONTEXTS"/>
+	<value value="9" name="PERF_SP_WAVE_CONTEXT_CYCLES"/>
+	<value value="10" name="PERF_SP_FS_STAGE_WAVE_CYCLES"/>
+	<value value="11" name="PERF_SP_FS_STAGE_WAVE_SAMPLES"/>
+	<value value="12" name="PERF_SP_VS_STAGE_WAVE_CYCLES"/>
+	<value value="13" name="PERF_SP_VS_STAGE_WAVE_SAMPLES"/>
+	<value value="14" name="PERF_SP_FS_STAGE_DURATION_CYCLES"/>
+	<value value="15" name="PERF_SP_VS_STAGE_DURATION_CYCLES"/>
+	<value value="16" name="PERF_SP_WAVE_CTRL_CYCLES"/>
+	<value value="17" name="PERF_SP_WAVE_LOAD_CYCLES"/>
+	<value value="18" name="PERF_SP_WAVE_EMIT_CYCLES"/>
+	<value value="19" name="PERF_SP_WAVE_NOP_CYCLES"/>
+	<value value="20" name="PERF_SP_WAVE_WAIT_CYCLES"/>
+	<value value="21" name="PERF_SP_WAVE_FETCH_CYCLES"/>
+	<value value="22" name="PERF_SP_WAVE_IDLE_CYCLES"/>
+	<value value="23" name="PERF_SP_WAVE_END_CYCLES"/>
+	<value value="24" name="PERF_SP_WAVE_LONG_SYNC_CYCLES"/>
+	<value value="25" name="PERF_SP_WAVE_SHORT_SYNC_CYCLES"/>
+	<value value="26" name="PERF_SP_WAVE_JOIN_CYCLES"/>
+	<value value="27" name="PERF_SP_LM_LOAD_INSTRUCTIONS"/>
+	<value value="28" name="PERF_SP_LM_STORE_INSTRUCTIONS"/>
+	<value value="29" name="PERF_SP_LM_ATOMICS"/>
+	<value value="30" name="PERF_SP_GM_LOAD_INSTRUCTIONS"/>
+	<value value="31" name="PERF_SP_GM_STORE_INSTRUCTIONS"/>
+	<value value="32" name="PERF_SP_GM_ATOMICS"/>
+	<value value="33" name="PERF_SP_VS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="34" name="PERF_SP_VS_STAGE_CFLOW_INSTRUCTIONS"/>
+	<value value="35" name="PERF_SP_VS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="36" name="PERF_SP_VS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="37" name="PERF_SP_VS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="38" name="PERF_SP_FS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="39" name="PERF_SP_FS_STAGE_CFLOW_INSTRUCTIONS"/>
+	<value value="40" name="PERF_SP_FS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="41" name="PERF_SP_FS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="42" name="PERF_SP_FS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="43" name="PERF_SP_FS_STAGE_BARY_INSTRUCTIONS"/>
+	<value value="44" name="PERF_SP_VS_INSTRUCTIONS"/>
+	<value value="45" name="PERF_SP_FS_INSTRUCTIONS"/>
+	<value value="46" name="PERF_SP_ADDR_LOCK_COUNT"/>
+	<value value="47" name="PERF_SP_UCHE_READ_TRANS"/>
+	<value value="48" name="PERF_SP_UCHE_WRITE_TRANS"/>
+	<value value="49" name="PERF_SP_EXPORT_VPC_TRANS"/>
+	<value value="50" name="PERF_SP_EXPORT_RB_TRANS"/>
+	<value value="51" name="PERF_SP_PIXELS_KILLED"/>
+	<value value="52" name="PERF_SP_ICL1_REQUESTS"/>
+	<value value="53" name="PERF_SP_ICL1_MISSES"/>
+	<value value="54" name="PERF_SP_ICL0_REQUESTS"/>
+	<value value="55" name="PERF_SP_ICL0_MISSES"/>
+	<value value="56" name="PERF_SP_HS_INSTRUCTIONS"/>
+	<value value="57" name="PERF_SP_DS_INSTRUCTIONS"/>
+	<value value="58" name="PERF_SP_GS_INSTRUCTIONS"/>
+	<value value="59" name="PERF_SP_CS_INSTRUCTIONS"/>
+	<value value="60" name="PERF_SP_GPR_READ"/>
+	<value value="61" name="PERF_SP_GPR_WRITE"/>
+	<value value="62" name="PERF_SP_LM_CH0_REQUESTS"/>
+	<value value="63" name="PERF_SP_LM_CH1_REQUESTS"/>
+	<value value="64" name="PERF_SP_LM_BANK_CONFLICTS"/>
+</enum>
+
+<enum name="a5xx_rb_perfcounter_select">
+	<value value="0" name="PERF_RB_BUSY_CYCLES"/>
+	<value value="1" name="PERF_RB_STALL_CYCLES_CCU"/>
+	<value value="2" name="PERF_RB_STALL_CYCLES_HLSQ"/>
+	<value value="3" name="PERF_RB_STALL_CYCLES_FIFO0_FULL"/>
+	<value value="4" name="PERF_RB_STALL_CYCLES_FIFO1_FULL"/>
+	<value value="5" name="PERF_RB_STALL_CYCLES_FIFO2_FULL"/>
+	<value value="6" name="PERF_RB_STARVE_CYCLES_SP"/>
+	<value value="7" name="PERF_RB_STARVE_CYCLES_LRZ_TILE"/>
+	<value value="8" name="PERF_RB_STARVE_CYCLES_CCU"/>
+	<value value="9" name="PERF_RB_STARVE_CYCLES_Z_PLANE"/>
+	<value value="10" name="PERF_RB_STARVE_CYCLES_BARY_PLANE"/>
+	<value value="11" name="PERF_RB_Z_WORKLOAD"/>
+	<value value="12" name="PERF_RB_HLSQ_ACTIVE"/>
+	<value value="13" name="PERF_RB_Z_READ"/>
+	<value value="14" name="PERF_RB_Z_WRITE"/>
+	<value value="15" name="PERF_RB_C_READ"/>
+	<value value="16" name="PERF_RB_C_WRITE"/>
+	<value value="17" name="PERF_RB_TOTAL_PASS"/>
+	<value value="18" name="PERF_RB_Z_PASS"/>
+	<value value="19" name="PERF_RB_Z_FAIL"/>
+	<value value="20" name="PERF_RB_S_FAIL"/>
+	<value value="21" name="PERF_RB_BLENDED_FXP_COMPONENTS"/>
+	<value value="22" name="PERF_RB_BLENDED_FP16_COMPONENTS"/>
+	<value value="23" name="RB_RESERVED"/>
+	<value value="24" name="PERF_RB_2D_ALIVE_CYCLES"/>
+	<value value="25" name="PERF_RB_2D_STALL_CYCLES_A2D"/>
+	<value value="26" name="PERF_RB_2D_STARVE_CYCLES_SRC"/>
+	<value value="27" name="PERF_RB_2D_STARVE_CYCLES_SP"/>
+	<value value="28" name="PERF_RB_2D_STARVE_CYCLES_DST"/>
+	<value value="29" name="PERF_RB_2D_VALID_PIXELS"/>
+</enum>
+
+<enum name="a5xx_rb_samples_perfcounter_select">
+	<value value="0" name="TOTAL_SAMPLES"/>
+	<value value="1" name="ZPASS_SAMPLES"/>
+	<value value="2" name="ZFAIL_SAMPLES"/>
+	<value value="3" name="SFAIL_SAMPLES"/>
+</enum>
+
+<enum name="a5xx_vsc_perfcounter_select">
+	<value value="0" name="PERF_VSC_BUSY_CYCLES"/>
+	<value value="1" name="PERF_VSC_WORKING_CYCLES"/>
+	<value value="2" name="PERF_VSC_STALL_CYCLES_UCHE"/>
+	<value value="3" name="PERF_VSC_EOT_NUM"/>
+</enum>
+
+<enum name="a5xx_ccu_perfcounter_select">
+	<value value="0" name="PERF_CCU_BUSY_CYCLES"/>
+	<value value="1" name="PERF_CCU_STALL_CYCLES_RB_DEPTH_RETURN"/>
+	<value value="2" name="PERF_CCU_STALL_CYCLES_RB_COLOR_RETURN"/>
+	<value value="3" name="PERF_CCU_STARVE_CYCLES_FLAG_RETURN"/>
+	<value value="4" name="PERF_CCU_DEPTH_BLOCKS"/>
+	<value value="5" name="PERF_CCU_COLOR_BLOCKS"/>
+	<value value="6" name="PERF_CCU_DEPTH_BLOCK_HIT"/>
+	<value value="7" name="PERF_CCU_COLOR_BLOCK_HIT"/>
+	<value value="8" name="PERF_CCU_PARTIAL_BLOCK_READ"/>
+	<value value="9" name="PERF_CCU_GMEM_READ"/>
+	<value value="10" name="PERF_CCU_GMEM_WRITE"/>
+	<value value="11" name="PERF_CCU_DEPTH_READ_FLAG0_COUNT"/>
+	<value value="12" name="PERF_CCU_DEPTH_READ_FLAG1_COUNT"/>
+	<value value="13" name="PERF_CCU_DEPTH_READ_FLAG2_COUNT"/>
+	<value value="14" name="PERF_CCU_DEPTH_READ_FLAG3_COUNT"/>
+	<value value="15" name="PERF_CCU_DEPTH_READ_FLAG4_COUNT"/>
+	<value value="16" name="PERF_CCU_COLOR_READ_FLAG0_COUNT"/>
+	<value value="17" name="PERF_CCU_COLOR_READ_FLAG1_COUNT"/>
+	<value value="18" name="PERF_CCU_COLOR_READ_FLAG2_COUNT"/>
+	<value value="19" name="PERF_CCU_COLOR_READ_FLAG3_COUNT"/>
+	<value value="20" name="PERF_CCU_COLOR_READ_FLAG4_COUNT"/>
+	<value value="21" name="PERF_CCU_2D_BUSY_CYCLES"/>
+	<value value="22" name="PERF_CCU_2D_RD_REQ"/>
+	<value value="23" name="PERF_CCU_2D_WR_REQ"/>
+	<value value="24" name="PERF_CCU_2D_REORDER_STARVE_CYCLES"/>
+	<value value="25" name="PERF_CCU_2D_PIXELS"/>
+</enum>
+
+<enum name="a5xx_cmp_perfcounter_select">
+	<value value="0" name="PERF_CMPDECMP_STALL_CYCLES_VBIF"/>
+	<value value="1" name="PERF_CMPDECMP_VBIF_LATENCY_CYCLES"/>
+	<value value="2" name="PERF_CMPDECMP_VBIF_LATENCY_SAMPLES"/>
+	<value value="3" name="PERF_CMPDECMP_VBIF_READ_DATA_CCU"/>
+	<value value="4" name="PERF_CMPDECMP_VBIF_WRITE_DATA_CCU"/>
+	<value value="5" name="PERF_CMPDECMP_VBIF_READ_REQUEST"/>
+	<value value="6" name="PERF_CMPDECMP_VBIF_WRITE_REQUEST"/>
+	<value value="7" name="PERF_CMPDECMP_VBIF_READ_DATA"/>
+	<value value="8" name="PERF_CMPDECMP_VBIF_WRITE_DATA"/>
+	<value value="9" name="PERF_CMPDECMP_FLAG_FETCH_CYCLES"/>
+	<value value="10" name="PERF_CMPDECMP_FLAG_FETCH_SAMPLES"/>
+	<value value="11" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG1_COUNT"/>
+	<value value="12" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG2_COUNT"/>
+	<value value="13" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG3_COUNT"/>
+	<value value="14" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG4_COUNT"/>
+	<value value="15" name="PERF_CMPDECMP_COLOR_WRITE_FLAG1_COUNT"/>
+	<value value="16" name="PERF_CMPDECMP_COLOR_WRITE_FLAG2_COUNT"/>
+	<value value="17" name="PERF_CMPDECMP_COLOR_WRITE_FLAG3_COUNT"/>
+	<value value="18" name="PERF_CMPDECMP_COLOR_WRITE_FLAG4_COUNT"/>
+	<value value="19" name="PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_REQ"/>
+	<value value="20" name="PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_WR"/>
+	<value value="21" name="PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_RETURN"/>
+	<value value="22" name="PERF_CMPDECMP_2D_RD_DATA"/>
+	<value value="23" name="PERF_CMPDECMP_2D_WR_DATA"/>
+</enum>
+
+<enum name="a5xx_vbif_perfcounter_select">
+	<value value="0" name="AXI_READ_REQUESTS_ID_0"/>
+	<value value="1" name="AXI_READ_REQUESTS_ID_1"/>
+	<value value="2" name="AXI_READ_REQUESTS_ID_2"/>
+	<value value="3" name="AXI_READ_REQUESTS_ID_3"/>
+	<value value="4" name="AXI_READ_REQUESTS_ID_4"/>
+	<value value="5" name="AXI_READ_REQUESTS_ID_5"/>
+	<value value="6" name="AXI_READ_REQUESTS_ID_6"/>
+	<value value="7" name="AXI_READ_REQUESTS_ID_7"/>
+	<value value="8" name="AXI_READ_REQUESTS_ID_8"/>
+	<value value="9" name="AXI_READ_REQUESTS_ID_9"/>
+	<value value="10" name="AXI_READ_REQUESTS_ID_10"/>
+	<value value="11" name="AXI_READ_REQUESTS_ID_11"/>
+	<value value="12" name="AXI_READ_REQUESTS_ID_12"/>
+	<value value="13" name="AXI_READ_REQUESTS_ID_13"/>
+	<value value="14" name="AXI_READ_REQUESTS_ID_14"/>
+	<value value="15" name="AXI_READ_REQUESTS_ID_15"/>
+	<value value="16" name="AXI0_READ_REQUESTS_TOTAL"/>
+	<value value="17" name="AXI1_READ_REQUESTS_TOTAL"/>
+	<value value="18" name="AXI2_READ_REQUESTS_TOTAL"/>
+	<value value="19" name="AXI3_READ_REQUESTS_TOTAL"/>
+	<value value="20" name="AXI_READ_REQUESTS_TOTAL"/>
+	<value value="21" name="AXI_WRITE_REQUESTS_ID_0"/>
+	<value value="22" name="AXI_WRITE_REQUESTS_ID_1"/>
+	<value value="23" name="AXI_WRITE_REQUESTS_ID_2"/>
+	<value value="24" name="AXI_WRITE_REQUESTS_ID_3"/>
+	<value value="25" name="AXI_WRITE_REQUESTS_ID_4"/>
+	<value value="26" name="AXI_WRITE_REQUESTS_ID_5"/>
+	<value value="27" name="AXI_WRITE_REQUESTS_ID_6"/>
+	<value value="28" name="AXI_WRITE_REQUESTS_ID_7"/>
+	<value value="29" name="AXI_WRITE_REQUESTS_ID_8"/>
+	<value value="30" name="AXI_WRITE_REQUESTS_ID_9"/>
+	<value value="31" name="AXI_WRITE_REQUESTS_ID_10"/>
+	<value value="32" name="AXI_WRITE_REQUESTS_ID_11"/>
+	<value value="33" name="AXI_WRITE_REQUESTS_ID_12"/>
+	<value value="34" name="AXI_WRITE_REQUESTS_ID_13"/>
+	<value value="35" name="AXI_WRITE_REQUESTS_ID_14"/>
+	<value value="36" name="AXI_WRITE_REQUESTS_ID_15"/>
+	<value value="37" name="AXI0_WRITE_REQUESTS_TOTAL"/>
+	<value value="38" name="AXI1_WRITE_REQUESTS_TOTAL"/>
+	<value value="39" name="AXI2_WRITE_REQUESTS_TOTAL"/>
+	<value value="40" name="AXI3_WRITE_REQUESTS_TOTAL"/>
+	<value value="41" name="AXI_WRITE_REQUESTS_TOTAL"/>
+	<value value="42" name="AXI_TOTAL_REQUESTS"/>
+	<value value="43" name="AXI_READ_DATA_BEATS_ID_0"/>
+	<value value="44" name="AXI_READ_DATA_BEATS_ID_1"/>
+	<value value="45" name="AXI_READ_DATA_BEATS_ID_2"/>
+	<value value="46" name="AXI_READ_DATA_BEATS_ID_3"/>
+	<value value="47" name="AXI_READ_DATA_BEATS_ID_4"/>
+	<value value="48" name="AXI_READ_DATA_BEATS_ID_5"/>
+	<value value="49" name="AXI_READ_DATA_BEATS_ID_6"/>
+	<value value="50" name="AXI_READ_DATA_BEATS_ID_7"/>
+	<value value="51" name="AXI_READ_DATA_BEATS_ID_8"/>
+	<value value="52" name="AXI_READ_DATA_BEATS_ID_9"/>
+	<value value="53" name="AXI_READ_DATA_BEATS_ID_10"/>
+	<value value="54" name="AXI_READ_DATA_BEATS_ID_11"/>
+	<value value="55" name="AXI_READ_DATA_BEATS_ID_12"/>
+	<value value="56" name="AXI_READ_DATA_BEATS_ID_13"/>
+	<value value="57" name="AXI_READ_DATA_BEATS_ID_14"/>
+	<value value="58" name="AXI_READ_DATA_BEATS_ID_15"/>
+	<value value="59" name="AXI0_READ_DATA_BEATS_TOTAL"/>
+	<value value="60" name="AXI1_READ_DATA_BEATS_TOTAL"/>
+	<value value="61" name="AXI2_READ_DATA_BEATS_TOTAL"/>
+	<value value="62" name="AXI3_READ_DATA_BEATS_TOTAL"/>
+	<value value="63" name="AXI_READ_DATA_BEATS_TOTAL"/>
+	<value value="64" name="AXI_WRITE_DATA_BEATS_ID_0"/>
+	<value value="65" name="AXI_WRITE_DATA_BEATS_ID_1"/>
+	<value value="66" name="AXI_WRITE_DATA_BEATS_ID_2"/>
+	<value value="67" name="AXI_WRITE_DATA_BEATS_ID_3"/>
+	<value value="68" name="AXI_WRITE_DATA_BEATS_ID_4"/>
+	<value value="69" name="AXI_WRITE_DATA_BEATS_ID_5"/>
+	<value value="70" name="AXI_WRITE_DATA_BEATS_ID_6"/>
+	<value value="71" name="AXI_WRITE_DATA_BEATS_ID_7"/>
+	<value value="72" name="AXI_WRITE_DATA_BEATS_ID_8"/>
+	<value value="73" name="AXI_WRITE_DATA_BEATS_ID_9"/>
+	<value value="74" name="AXI_WRITE_DATA_BEATS_ID_10"/>
+	<value value="75" name="AXI_WRITE_DATA_BEATS_ID_11"/>
+	<value value="76" name="AXI_WRITE_DATA_BEATS_ID_12"/>
+	<value value="77" name="AXI_WRITE_DATA_BEATS_ID_13"/>
+	<value value="78" name="AXI_WRITE_DATA_BEATS_ID_14"/>
+	<value value="79" name="AXI_WRITE_DATA_BEATS_ID_15"/>
+	<value value="80" name="AXI0_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="81" name="AXI1_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="82" name="AXI2_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="83" name="AXI3_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="84" name="AXI_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="85" name="AXI_DATA_BEATS_TOTAL"/>
+</enum>
+
+<domain name="A5XX" width="32">
+	<bitset name="A5XX_INT0">
+		<bitfield name="RBBM_GPU_IDLE" pos="0" type="boolean"/>
+		<bitfield name="RBBM_AHB_ERROR" pos="1" type="boolean"/>
+		<bitfield name="RBBM_TRANSFER_TIMEOUT" pos="2" type="boolean"/>
+		<bitfield name="RBBM_ME_MS_TIMEOUT" pos="3" type="boolean"/>
+		<bitfield name="RBBM_PFP_MS_TIMEOUT" pos="4" type="boolean"/>
+		<bitfield name="RBBM_ETS_MS_TIMEOUT" pos="5" type="boolean"/>
+		<bitfield name="RBBM_ATB_ASYNC_OVERFLOW" pos="6" type="boolean"/>
+		<bitfield name="RBBM_GPC_ERROR" pos="7" type="boolean"/>
+		<bitfield name="CP_SW" pos="8" type="boolean"/>
+		<bitfield name="CP_HW_ERROR" pos="9" type="boolean"/>
+		<bitfield name="CP_CCU_FLUSH_DEPTH_TS" pos="10" type="boolean"/>
+		<bitfield name="CP_CCU_FLUSH_COLOR_TS" pos="11" type="boolean"/>
+		<bitfield name="CP_CCU_RESOLVE_TS" pos="12" type="boolean"/>
+		<bitfield name="CP_IB2" pos="13" type="boolean"/>
+		<bitfield name="CP_IB1" pos="14" type="boolean"/>
+		<bitfield name="CP_RB" pos="15" type="boolean"/>
+		<bitfield name="CP_UNUSED_1" pos="16" type="boolean"/>
+		<bitfield name="CP_RB_DONE_TS" pos="17" type="boolean"/>
+		<bitfield name="CP_WT_DONE_TS" pos="18" type="boolean"/>
+		<bitfield name="UNKNOWN_1" pos="19" type="boolean"/>
+		<bitfield name="CP_CACHE_FLUSH_TS" pos="20" type="boolean"/>
+		<bitfield name="UNUSED_2" pos="21" type="boolean"/>
+		<bitfield name="RBBM_ATB_BUS_OVERFLOW" pos="22" type="boolean"/>
+		<bitfield name="MISC_HANG_DETECT" pos="23" type="boolean"/>
+		<bitfield name="UCHE_OOB_ACCESS" pos="24" type="boolean"/>
+		<bitfield name="UCHE_TRAP_INTR" pos="25" type="boolean"/>
+		<bitfield name="DEBBUS_INTR_0" pos="26" type="boolean"/>
+		<bitfield name="DEBBUS_INTR_1" pos="27" type="boolean"/>
+		<bitfield name="GPMU_VOLTAGE_DROOP" pos="28" type="boolean"/>
+		<bitfield name="GPMU_FIRMWARE" pos="29" type="boolean"/>
+		<bitfield name="ISDB_CPU_IRQ" pos="30" type="boolean"/>
+		<bitfield name="ISDB_UNDER_DEBUG" pos="31" type="boolean"/>
+	</bitset>
+
+	<!-- CP Interrupt bits -->
+	<bitset name="A5XX_CP_INT">
+		<bitfield name="CP_OPCODE_ERROR" pos="0" type="boolean"/>
+		<bitfield name="CP_RESERVED_BIT_ERROR" pos="1" type="boolean"/>
+		<bitfield name="CP_HW_FAULT_ERROR" pos="2" type="boolean"/>
+		<bitfield name="CP_DMA_ERROR" pos="3" type="boolean"/>
+		<bitfield name="CP_REGISTER_PROTECTION_ERROR" pos="4" type="boolean"/>
+		<bitfield name="CP_AHB_ERROR" pos="5" type="boolean"/>
+	</bitset>
+
+	<!-- CP registers -->
+	<reg32 offset="0x0800" name="CP_RB_BASE"/>
+	<reg32 offset="0x0801" name="CP_RB_BASE_HI"/>
+	<reg32 offset="0x0802" name="CP_RB_CNTL"/>
+	<reg32 offset="0x0804" name="CP_RB_RPTR_ADDR"/>
+	<reg32 offset="0x0805" name="CP_RB_RPTR_ADDR_HI"/>
+	<reg32 offset="0x0806" name="CP_RB_RPTR"/>
+	<reg32 offset="0x0807" name="CP_RB_WPTR"/>
+	<reg32 offset="0x0808" name="CP_PFP_STAT_ADDR"/>
+	<reg32 offset="0x0809" name="CP_PFP_STAT_DATA"/>
+	<reg32 offset="0x080b" name="CP_DRAW_STATE_ADDR"/>
+	<reg32 offset="0x080c" name="CP_DRAW_STATE_DATA"/>
+	<reg32 offset="0x080d" name="CP_ME_NRT_ADDR_LO"/>
+	<reg32 offset="0x080e" name="CP_ME_NRT_ADDR_HI"/>
+	<reg32 offset="0x0810" name="CP_ME_NRT_DATA"/>
+	<reg32 offset="0x0817" name="CP_CRASH_SCRIPT_BASE_LO"/>
+	<reg32 offset="0x0818" name="CP_CRASH_SCRIPT_BASE_HI"/>
+	<reg32 offset="0x0819" name="CP_CRASH_DUMP_CNTL"/>
+	<reg32 offset="0x081a" name="CP_ME_STAT_ADDR"/>
+	<reg32 offset="0x081f" name="CP_ROQ_THRESHOLDS_1"/>
+	<reg32 offset="0x0820" name="CP_ROQ_THRESHOLDS_2"/>
+	<reg32 offset="0x0821" name="CP_ROQ_DBG_ADDR"/>
+	<reg32 offset="0x0822" name="CP_ROQ_DBG_DATA"/>
+	<reg32 offset="0x0823" name="CP_MEQ_DBG_ADDR"/>
+	<reg32 offset="0x0824" name="CP_MEQ_DBG_DATA"/>
+	<reg32 offset="0x0825" name="CP_MEQ_THRESHOLDS"/>
+	<reg32 offset="0x0826" name="CP_MERCIU_SIZE"/>
+	<reg32 offset="0x0827" name="CP_MERCIU_DBG_ADDR"/>
+	<reg32 offset="0x0828" name="CP_MERCIU_DBG_DATA_1"/>
+	<reg32 offset="0x0829" name="CP_MERCIU_DBG_DATA_2"/>
+	<reg32 offset="0x082a" name="CP_PFP_UCODE_DBG_ADDR"/>
+	<reg32 offset="0x082b" name="CP_PFP_UCODE_DBG_DATA"/>
+	<reg32 offset="0x082f" name="CP_ME_UCODE_DBG_ADDR"/>
+	<reg32 offset="0x0830" name="CP_ME_UCODE_DBG_DATA"/>
+	<reg32 offset="0x0831" name="CP_CNTL"/>
+	<reg32 offset="0x0832" name="CP_PFP_ME_CNTL"/>
+	<reg32 offset="0x0833" name="CP_CHICKEN_DBG"/>
+	<reg32 offset="0x0835" name="CP_PFP_INSTR_BASE_LO"/>
+	<reg32 offset="0x0836" name="CP_PFP_INSTR_BASE_HI"/>
+	<reg32 offset="0x0838" name="CP_ME_INSTR_BASE_LO"/>
+	<reg32 offset="0x0839" name="CP_ME_INSTR_BASE_HI"/>
+	<reg32 offset="0x083b" name="CP_CONTEXT_SWITCH_CNTL"/>
+	<reg32 offset="0x083c" name="CP_CONTEXT_SWITCH_RESTORE_ADDR_LO"/>
+	<reg32 offset="0x083d" name="CP_CONTEXT_SWITCH_RESTORE_ADDR_HI"/>
+	<reg32 offset="0x083e" name="CP_CONTEXT_SWITCH_SAVE_ADDR_LO"/>
+	<reg32 offset="0x083f" name="CP_CONTEXT_SWITCH_SAVE_ADDR_HI"/>
+	<reg32 offset="0x0840" name="CP_CONTEXT_SWITCH_SMMU_INFO_LO"/>
+	<reg32 offset="0x0841" name="CP_CONTEXT_SWITCH_SMMU_INFO_HI"/>
+	<reg32 offset="0x0860" name="CP_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0b14" name="CP_ME_STAT_DATA"/>
+	<reg32 offset="0x0b15" name="CP_WFI_PEND_CTR"/>
+	<reg32 offset="0x0b18" name="CP_INTERRUPT_STATUS"/>
+	<reg32 offset="0x0b1a" name="CP_HW_FAULT"/>
+	<reg32 offset="0x0b1c" name="CP_PROTECT_STATUS"/>
+	<reg32 offset="0x0b1f" name="CP_IB1_BASE"/>
+	<reg32 offset="0x0b20" name="CP_IB1_BASE_HI"/>
+	<reg32 offset="0x0b21" name="CP_IB1_BUFSZ"/>
+	<reg32 offset="0x0b22" name="CP_IB2_BASE"/>
+	<reg32 offset="0x0b23" name="CP_IB2_BASE_HI"/>
+	<reg32 offset="0x0b24" name="CP_IB2_BUFSZ"/>
+	<array offset="0x0b78" name="CP_SCRATCH" stride="1" length="8">
+		<reg32 offset="0x0" name="REG" type="uint"/>
+	</array>
+	<array offset="0x0880" name="CP_PROTECT" stride="1" length="32">
+		<reg32 offset="0x0" name="REG" type="adreno_cp_protect"/>
+	</array>
+	<reg32 offset="0x08a0" name="CP_PROTECT_CNTL"/>
+	<reg32 offset="0x0b1b" name="CP_AHB_FAULT"/>
+	<reg32 offset="0x0bb0" name="CP_PERFCTR_CP_SEL_0" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bb1" name="CP_PERFCTR_CP_SEL_1" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bb2" name="CP_PERFCTR_CP_SEL_2" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bb3" name="CP_PERFCTR_CP_SEL_3" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bb4" name="CP_PERFCTR_CP_SEL_4" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bb5" name="CP_PERFCTR_CP_SEL_5" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bb6" name="CP_PERFCTR_CP_SEL_6" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bb7" name="CP_PERFCTR_CP_SEL_7" type="a5xx_cp_perfcounter_select"/>
+	<reg32 offset="0x0bc1" name="VSC_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0bba" name="CP_POWERCTR_CP_SEL_0"/>
+	<reg32 offset="0x0bbb" name="CP_POWERCTR_CP_SEL_1"/>
+	<reg32 offset="0x0bbc" name="CP_POWERCTR_CP_SEL_2"/>
+	<reg32 offset="0x0bbd" name="CP_POWERCTR_CP_SEL_3"/>
+
+	<!-- RBBM registers -->
+	<reg32 offset="0x0004" name="RBBM_CFG_DBGBUS_SEL_A"/>
+	<reg32 offset="0x0005" name="RBBM_CFG_DBGBUS_SEL_B"/>
+	<reg32 offset="0x0006" name="RBBM_CFG_DBGBUS_SEL_C"/>
+	<reg32 offset="0x0007" name="RBBM_CFG_DBGBUS_SEL_D"/>
+<!--
+#define A5XX_RBBM_CFG_DBGBUS_SEL_PING_INDEX_SHIFT    0x0
+#define A5XX_RBBM_CFG_DBGBUS_SEL_PING_BLK_SEL_SHIFT  0x8
+#define A5XX_RBBM_CFG_DBGBUS_SEL_PONG_INDEX_SHIFT    0x10
+#define A5XX_RBBM_CFG_DBGBUS_SEL_PONG_BLK_SEL_SHIFT  0x18
+ -->
+	<reg32 offset="0x0008" name="RBBM_CFG_DBGBUS_CNTLT"/>
+	<reg32 offset="0x0009" name="RBBM_CFG_DBGBUS_CNTLM"/>
+	<reg32 offset="0x0018" name="RBBM_CFG_DEBBUS_CTLTM_ENABLE_SHIFT"/>
+	<reg32 offset="0x000a" name="RBBM_CFG_DBGBUS_OPL"/>
+	<reg32 offset="0x000b" name="RBBM_CFG_DBGBUS_OPE"/>
+	<reg32 offset="0x000c" name="RBBM_CFG_DBGBUS_IVTL_0"/>
+	<reg32 offset="0x000d" name="RBBM_CFG_DBGBUS_IVTL_1"/>
+	<reg32 offset="0x000e" name="RBBM_CFG_DBGBUS_IVTL_2"/>
+	<reg32 offset="0x000f" name="RBBM_CFG_DBGBUS_IVTL_3"/>
+	<reg32 offset="0x0010" name="RBBM_CFG_DBGBUS_MASKL_0"/>
+	<reg32 offset="0x0011" name="RBBM_CFG_DBGBUS_MASKL_1"/>
+	<reg32 offset="0x0012" name="RBBM_CFG_DBGBUS_MASKL_2"/>
+	<reg32 offset="0x0013" name="RBBM_CFG_DBGBUS_MASKL_3"/>
+	<reg32 offset="0x0014" name="RBBM_CFG_DBGBUS_BYTEL_0"/>
+	<reg32 offset="0x0015" name="RBBM_CFG_DBGBUS_BYTEL_1"/>
+	<reg32 offset="0x0016" name="RBBM_CFG_DBGBUS_IVTE_0"/>
+	<reg32 offset="0x0017" name="RBBM_CFG_DBGBUS_IVTE_1"/>
+	<reg32 offset="0x0018" name="RBBM_CFG_DBGBUS_IVTE_2"/>
+	<reg32 offset="0x0019" name="RBBM_CFG_DBGBUS_IVTE_3"/>
+	<reg32 offset="0x001a" name="RBBM_CFG_DBGBUS_MASKE_0"/>
+	<reg32 offset="0x001b" name="RBBM_CFG_DBGBUS_MASKE_1"/>
+	<reg32 offset="0x001c" name="RBBM_CFG_DBGBUS_MASKE_2"/>
+	<reg32 offset="0x001d" name="RBBM_CFG_DBGBUS_MASKE_3"/>
+	<reg32 offset="0x001e" name="RBBM_CFG_DBGBUS_NIBBLEE"/>
+	<reg32 offset="0x001f" name="RBBM_CFG_DBGBUS_PTRC0"/>
+	<reg32 offset="0x0020" name="RBBM_CFG_DBGBUS_PTRC1"/>
+	<reg32 offset="0x0021" name="RBBM_CFG_DBGBUS_LOADREG"/>
+	<reg32 offset="0x0022" name="RBBM_CFG_DBGBUS_IDX"/>
+	<reg32 offset="0x0023" name="RBBM_CFG_DBGBUS_CLRC"/>
+	<reg32 offset="0x0024" name="RBBM_CFG_DBGBUS_LOADIVT"/>
+	<reg32 offset="0x002f" name="RBBM_INTERFACE_HANG_INT_CNTL"/>
+	<reg32 offset="0x0037" name="RBBM_INT_CLEAR_CMD"/>
+	<reg32 offset="0x0038" name="RBBM_INT_0_MASK">
+		<bitfield name="RBBM_GPU_IDLE" pos="0" type="boolean"/>
+		<bitfield name="RBBM_AHB_ERROR" pos="1" type="boolean"/>
+		<bitfield name="RBBM_TRANSFER_TIMEOUT" pos="2" type="boolean"/>
+		<bitfield name="RBBM_ME_MS_TIMEOUT" pos="3" type="boolean"/>
+		<bitfield name="RBBM_PFP_MS_TIMEOUT" pos="4" type="boolean"/>
+		<bitfield name="RBBM_ETS_MS_TIMEOUT" pos="5" type="boolean"/>
+		<bitfield name="RBBM_ATB_ASYNC_OVERFLOW" pos="6" type="boolean"/>
+		<bitfield name="RBBM_GPC_ERROR" pos="7" type="boolean"/>
+		<bitfield name="CP_SW" pos="8" type="boolean"/>
+		<bitfield name="CP_HW_ERROR" pos="9" type="boolean"/>
+		<bitfield name="CP_CCU_FLUSH_DEPTH_TS" pos="10" type="boolean"/>
+		<bitfield name="CP_CCU_FLUSH_COLOR_TS" pos="11" type="boolean"/>
+		<bitfield name="CP_CCU_RESOLVE_TS" pos="12" type="boolean"/>
+		<bitfield name="CP_IB2" pos="13" type="boolean"/>
+		<bitfield name="CP_IB1" pos="14" type="boolean"/>
+		<bitfield name="CP_RB" pos="15" type="boolean"/>
+		<bitfield name="CP_RB_DONE_TS" pos="17" type="boolean"/>
+		<bitfield name="CP_WT_DONE_TS" pos="18" type="boolean"/>
+		<bitfield name="CP_CACHE_FLUSH_TS" pos="20" type="boolean"/>
+		<bitfield name="RBBM_ATB_BUS_OVERFLOW" pos="22" type="boolean"/>
+		<bitfield name="MISC_HANG_DETECT" pos="23" type="boolean"/>
+		<bitfield name="UCHE_OOB_ACCESS" pos="24" type="boolean"/>
+		<bitfield name="UCHE_TRAP_INTR" pos="25" type="boolean"/>
+		<bitfield name="DEBBUS_INTR_0" pos="26" type="boolean"/>
+		<bitfield name="DEBBUS_INTR_1" pos="27" type="boolean"/>
+		<bitfield name="GPMU_VOLTAGE_DROOP" pos="28" type="boolean"/>
+		<bitfield name="GPMU_FIRMWARE" pos="29" type="boolean"/>
+		<bitfield name="ISDB_CPU_IRQ" pos="30" type="boolean"/>
+		<bitfield name="ISDB_UNDER_DEBUG" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x003f" name="RBBM_AHB_DBG_CNTL"/>
+	<reg32 offset="0x0041" name="RBBM_EXT_VBIF_DBG_CNTL"/>
+	<reg32 offset="0x0043" name="RBBM_SW_RESET_CMD"/>
+	<reg32 offset="0x0045" name="RBBM_BLOCK_SW_RESET_CMD"/>
+	<reg32 offset="0x0046" name="RBBM_BLOCK_SW_RESET_CMD2"/>
+	<reg32 offset="0x0048" name="RBBM_DBG_LO_HI_GPIO"/>
+	<reg32 offset="0x0049" name="RBBM_EXT_TRACE_BUS_CNTL"/>
+	<reg32 offset="0x004a" name="RBBM_CLOCK_CNTL_TP0"/>
+	<reg32 offset="0x004b" name="RBBM_CLOCK_CNTL_TP1"/>
+	<reg32 offset="0x004c" name="RBBM_CLOCK_CNTL_TP2"/>
+	<reg32 offset="0x004d" name="RBBM_CLOCK_CNTL_TP3"/>
+	<reg32 offset="0x004e" name="RBBM_CLOCK_CNTL2_TP0"/>
+	<reg32 offset="0x004f" name="RBBM_CLOCK_CNTL2_TP1"/>
+	<reg32 offset="0x0050" name="RBBM_CLOCK_CNTL2_TP2"/>
+	<reg32 offset="0x0051" name="RBBM_CLOCK_CNTL2_TP3"/>
+	<reg32 offset="0x0052" name="RBBM_CLOCK_CNTL3_TP0"/>
+	<reg32 offset="0x0053" name="RBBM_CLOCK_CNTL3_TP1"/>
+	<reg32 offset="0x0054" name="RBBM_CLOCK_CNTL3_TP2"/>
+	<reg32 offset="0x0055" name="RBBM_CLOCK_CNTL3_TP3"/>
+	<reg32 offset="0x0059" name="RBBM_READ_AHB_THROUGH_DBG"/>
+	<reg32 offset="0x005a" name="RBBM_CLOCK_CNTL_UCHE"/>
+	<reg32 offset="0x005b" name="RBBM_CLOCK_CNTL2_UCHE"/>
+	<reg32 offset="0x005c" name="RBBM_CLOCK_CNTL3_UCHE"/>
+	<reg32 offset="0x005d" name="RBBM_CLOCK_CNTL4_UCHE"/>
+	<reg32 offset="0x005e" name="RBBM_CLOCK_HYST_UCHE"/>
+	<reg32 offset="0x005f" name="RBBM_CLOCK_DELAY_UCHE"/>
+	<reg32 offset="0x0060" name="RBBM_CLOCK_MODE_GPC"/>
+	<reg32 offset="0x0061" name="RBBM_CLOCK_DELAY_GPC"/>
+	<reg32 offset="0x0062" name="RBBM_CLOCK_HYST_GPC"/>
+	<reg32 offset="0x0063" name="RBBM_CLOCK_CNTL_TSE_RAS_RBBM"/>
+	<reg32 offset="0x0064" name="RBBM_CLOCK_HYST_TSE_RAS_RBBM"/>
+	<reg32 offset="0x0065" name="RBBM_CLOCK_DELAY_TSE_RAS_RBBM"/>
+	<reg32 offset="0x0066" name="RBBM_CLOCK_DELAY_HLSQ"/>
+	<reg32 offset="0x0067" name="RBBM_CLOCK_CNTL"/>
+	<reg32 offset="0x0068" name="RBBM_CLOCK_CNTL_SP0"/>
+	<reg32 offset="0x0069" name="RBBM_CLOCK_CNTL_SP1"/>
+	<reg32 offset="0x006a" name="RBBM_CLOCK_CNTL_SP2"/>
+	<reg32 offset="0x006b" name="RBBM_CLOCK_CNTL_SP3"/>
+	<reg32 offset="0x006c" name="RBBM_CLOCK_CNTL2_SP0"/>
+	<reg32 offset="0x006d" name="RBBM_CLOCK_CNTL2_SP1"/>
+	<reg32 offset="0x006e" name="RBBM_CLOCK_CNTL2_SP2"/>
+	<reg32 offset="0x006f" name="RBBM_CLOCK_CNTL2_SP3"/>
+	<reg32 offset="0x0070" name="RBBM_CLOCK_HYST_SP0"/>
+	<reg32 offset="0x0071" name="RBBM_CLOCK_HYST_SP1"/>
+	<reg32 offset="0x0072" name="RBBM_CLOCK_HYST_SP2"/>
+	<reg32 offset="0x0073" name="RBBM_CLOCK_HYST_SP3"/>
+	<reg32 offset="0x0074" name="RBBM_CLOCK_DELAY_SP0"/>
+	<reg32 offset="0x0075" name="RBBM_CLOCK_DELAY_SP1"/>
+	<reg32 offset="0x0076" name="RBBM_CLOCK_DELAY_SP2"/>
+	<reg32 offset="0x0077" name="RBBM_CLOCK_DELAY_SP3"/>
+	<reg32 offset="0x0078" name="RBBM_CLOCK_CNTL_RB0"/>
+	<reg32 offset="0x0079" name="RBBM_CLOCK_CNTL_RB1"/>
+	<reg32 offset="0x007a" name="RBBM_CLOCK_CNTL_RB2"/>
+	<reg32 offset="0x007b" name="RBBM_CLOCK_CNTL_RB3"/>
+	<reg32 offset="0x007c" name="RBBM_CLOCK_CNTL2_RB0"/>
+	<reg32 offset="0x007d" name="RBBM_CLOCK_CNTL2_RB1"/>
+	<reg32 offset="0x007e" name="RBBM_CLOCK_CNTL2_RB2"/>
+	<reg32 offset="0x007f" name="RBBM_CLOCK_CNTL2_RB3"/>
+	<reg32 offset="0x0080" name="RBBM_CLOCK_HYST_RAC"/>
+	<reg32 offset="0x0081" name="RBBM_CLOCK_DELAY_RAC"/>
+	<reg32 offset="0x0082" name="RBBM_CLOCK_CNTL_CCU0"/>
+	<reg32 offset="0x0083" name="RBBM_CLOCK_CNTL_CCU1"/>
+	<reg32 offset="0x0084" name="RBBM_CLOCK_CNTL_CCU2"/>
+	<reg32 offset="0x0085" name="RBBM_CLOCK_CNTL_CCU3"/>
+	<reg32 offset="0x0086" name="RBBM_CLOCK_HYST_RB_CCU0"/>
+	<reg32 offset="0x0087" name="RBBM_CLOCK_HYST_RB_CCU1"/>
+	<reg32 offset="0x0088" name="RBBM_CLOCK_HYST_RB_CCU2"/>
+	<reg32 offset="0x0089" name="RBBM_CLOCK_HYST_RB_CCU3"/>
+	<reg32 offset="0x008a" name="RBBM_CLOCK_CNTL_RAC"/>
+	<reg32 offset="0x008b" name="RBBM_CLOCK_CNTL2_RAC"/>
+	<reg32 offset="0x008c" name="RBBM_CLOCK_DELAY_RB_CCU_L1_0"/>
+	<reg32 offset="0x008d" name="RBBM_CLOCK_DELAY_RB_CCU_L1_1"/>
+	<reg32 offset="0x008e" name="RBBM_CLOCK_DELAY_RB_CCU_L1_2"/>
+	<reg32 offset="0x008f" name="RBBM_CLOCK_DELAY_RB_CCU_L1_3"/>
+	<reg32 offset="0x0090" name="RBBM_CLOCK_HYST_VFD"/>
+	<reg32 offset="0x0091" name="RBBM_CLOCK_MODE_VFD"/>
+	<reg32 offset="0x0092" name="RBBM_CLOCK_DELAY_VFD"/>
+	<reg32 offset="0x0093" name="RBBM_AHB_CNTL0"/>
+	<reg32 offset="0x0094" name="RBBM_AHB_CNTL1"/>
+	<reg32 offset="0x0095" name="RBBM_AHB_CNTL2"/>
+	<reg32 offset="0x0096" name="RBBM_AHB_CMD"/>
+	<reg32 offset="0x009c" name="RBBM_INTERFACE_HANG_MASK_CNTL11"/>
+	<reg32 offset="0x009d" name="RBBM_INTERFACE_HANG_MASK_CNTL12"/>
+	<reg32 offset="0x009e" name="RBBM_INTERFACE_HANG_MASK_CNTL13"/>
+	<reg32 offset="0x009f" name="RBBM_INTERFACE_HANG_MASK_CNTL14"/>
+	<reg32 offset="0x00a0" name="RBBM_INTERFACE_HANG_MASK_CNTL15"/>
+	<reg32 offset="0x00a1" name="RBBM_INTERFACE_HANG_MASK_CNTL16"/>
+	<reg32 offset="0x00a2" name="RBBM_INTERFACE_HANG_MASK_CNTL17"/>
+	<reg32 offset="0x00a3" name="RBBM_INTERFACE_HANG_MASK_CNTL18"/>
+	<reg32 offset="0x00a4" name="RBBM_CLOCK_DELAY_TP0"/>
+	<reg32 offset="0x00a5" name="RBBM_CLOCK_DELAY_TP1"/>
+	<reg32 offset="0x00a6" name="RBBM_CLOCK_DELAY_TP2"/>
+	<reg32 offset="0x00a7" name="RBBM_CLOCK_DELAY_TP3"/>
+	<reg32 offset="0x00a8" name="RBBM_CLOCK_DELAY2_TP0"/>
+	<reg32 offset="0x00a9" name="RBBM_CLOCK_DELAY2_TP1"/>
+	<reg32 offset="0x00aa" name="RBBM_CLOCK_DELAY2_TP2"/>
+	<reg32 offset="0x00ab" name="RBBM_CLOCK_DELAY2_TP3"/>
+	<reg32 offset="0x00ac" name="RBBM_CLOCK_DELAY3_TP0"/>
+	<reg32 offset="0x00ad" name="RBBM_CLOCK_DELAY3_TP1"/>
+	<reg32 offset="0x00ae" name="RBBM_CLOCK_DELAY3_TP2"/>
+	<reg32 offset="0x00af" name="RBBM_CLOCK_DELAY3_TP3"/>
+	<reg32 offset="0x00b0" name="RBBM_CLOCK_HYST_TP0"/>
+	<reg32 offset="0x00b1" name="RBBM_CLOCK_HYST_TP1"/>
+	<reg32 offset="0x00b2" name="RBBM_CLOCK_HYST_TP2"/>
+	<reg32 offset="0x00b3" name="RBBM_CLOCK_HYST_TP3"/>
+	<reg32 offset="0x00b4" name="RBBM_CLOCK_HYST2_TP0"/>
+	<reg32 offset="0x00b5" name="RBBM_CLOCK_HYST2_TP1"/>
+	<reg32 offset="0x00b6" name="RBBM_CLOCK_HYST2_TP2"/>
+	<reg32 offset="0x00b7" name="RBBM_CLOCK_HYST2_TP3"/>
+	<reg32 offset="0x00b8" name="RBBM_CLOCK_HYST3_TP0"/>
+	<reg32 offset="0x00b9" name="RBBM_CLOCK_HYST3_TP1"/>
+	<reg32 offset="0x00ba" name="RBBM_CLOCK_HYST3_TP2"/>
+	<reg32 offset="0x00bb" name="RBBM_CLOCK_HYST3_TP3"/>
+	<reg32 offset="0x00c8" name="RBBM_CLOCK_CNTL_GPMU"/>
+	<reg32 offset="0x00c9" name="RBBM_CLOCK_DELAY_GPMU"/>
+	<reg32 offset="0x00ca" name="RBBM_CLOCK_HYST_GPMU"/>
+	<reg32 offset="0x03a0" name="RBBM_PERFCTR_CP_0_LO"/>
+	<reg32 offset="0x03a1" name="RBBM_PERFCTR_CP_0_HI"/>
+	<reg32 offset="0x03a2" name="RBBM_PERFCTR_CP_1_LO"/>
+	<reg32 offset="0x03a3" name="RBBM_PERFCTR_CP_1_HI"/>
+	<reg32 offset="0x03a4" name="RBBM_PERFCTR_CP_2_LO"/>
+	<reg32 offset="0x03a5" name="RBBM_PERFCTR_CP_2_HI"/>
+	<reg32 offset="0x03a6" name="RBBM_PERFCTR_CP_3_LO"/>
+	<reg32 offset="0x03a7" name="RBBM_PERFCTR_CP_3_HI"/>
+	<reg32 offset="0x03a8" name="RBBM_PERFCTR_CP_4_LO"/>
+	<reg32 offset="0x03a9" name="RBBM_PERFCTR_CP_4_HI"/>
+	<reg32 offset="0x03aa" name="RBBM_PERFCTR_CP_5_LO"/>
+	<reg32 offset="0x03ab" name="RBBM_PERFCTR_CP_5_HI"/>
+	<reg32 offset="0x03ac" name="RBBM_PERFCTR_CP_6_LO"/>
+	<reg32 offset="0x03ad" name="RBBM_PERFCTR_CP_6_HI"/>
+	<reg32 offset="0x03ae" name="RBBM_PERFCTR_CP_7_LO"/>
+	<reg32 offset="0x03af" name="RBBM_PERFCTR_CP_7_HI"/>
+	<reg32 offset="0x03b0" name="RBBM_PERFCTR_RBBM_0_LO"/>
+	<reg32 offset="0x03b1" name="RBBM_PERFCTR_RBBM_0_HI"/>
+	<reg32 offset="0x03b2" name="RBBM_PERFCTR_RBBM_1_LO"/>
+	<reg32 offset="0x03b3" name="RBBM_PERFCTR_RBBM_1_HI"/>
+	<reg32 offset="0x03b4" name="RBBM_PERFCTR_RBBM_2_LO"/>
+	<reg32 offset="0x03b5" name="RBBM_PERFCTR_RBBM_2_HI"/>
+	<reg32 offset="0x03b6" name="RBBM_PERFCTR_RBBM_3_LO"/>
+	<reg32 offset="0x03b7" name="RBBM_PERFCTR_RBBM_3_HI"/>
+	<reg32 offset="0x03b8" name="RBBM_PERFCTR_PC_0_LO"/>
+	<reg32 offset="0x03b9" name="RBBM_PERFCTR_PC_0_HI"/>
+	<reg32 offset="0x03ba" name="RBBM_PERFCTR_PC_1_LO"/>
+	<reg32 offset="0x03bb" name="RBBM_PERFCTR_PC_1_HI"/>
+	<reg32 offset="0x03bc" name="RBBM_PERFCTR_PC_2_LO"/>
+	<reg32 offset="0x03bd" name="RBBM_PERFCTR_PC_2_HI"/>
+	<reg32 offset="0x03be" name="RBBM_PERFCTR_PC_3_LO"/>
+	<reg32 offset="0x03bf" name="RBBM_PERFCTR_PC_3_HI"/>
+	<reg32 offset="0x03c0" name="RBBM_PERFCTR_PC_4_LO"/>
+	<reg32 offset="0x03c1" name="RBBM_PERFCTR_PC_4_HI"/>
+	<reg32 offset="0x03c2" name="RBBM_PERFCTR_PC_5_LO"/>
+	<reg32 offset="0x03c3" name="RBBM_PERFCTR_PC_5_HI"/>
+	<reg32 offset="0x03c4" name="RBBM_PERFCTR_PC_6_LO"/>
+	<reg32 offset="0x03c5" name="RBBM_PERFCTR_PC_6_HI"/>
+	<reg32 offset="0x03c6" name="RBBM_PERFCTR_PC_7_LO"/>
+	<reg32 offset="0x03c7" name="RBBM_PERFCTR_PC_7_HI"/>
+	<reg32 offset="0x03c8" name="RBBM_PERFCTR_VFD_0_LO"/>
+	<reg32 offset="0x03c9" name="RBBM_PERFCTR_VFD_0_HI"/>
+	<reg32 offset="0x03ca" name="RBBM_PERFCTR_VFD_1_LO"/>
+	<reg32 offset="0x03cb" name="RBBM_PERFCTR_VFD_1_HI"/>
+	<reg32 offset="0x03cc" name="RBBM_PERFCTR_VFD_2_LO"/>
+	<reg32 offset="0x03cd" name="RBBM_PERFCTR_VFD_2_HI"/>
+	<reg32 offset="0x03ce" name="RBBM_PERFCTR_VFD_3_LO"/>
+	<reg32 offset="0x03cf" name="RBBM_PERFCTR_VFD_3_HI"/>
+	<reg32 offset="0x03d0" name="RBBM_PERFCTR_VFD_4_LO"/>
+	<reg32 offset="0x03d1" name="RBBM_PERFCTR_VFD_4_HI"/>
+	<reg32 offset="0x03d2" name="RBBM_PERFCTR_VFD_5_LO"/>
+	<reg32 offset="0x03d3" name="RBBM_PERFCTR_VFD_5_HI"/>
+	<reg32 offset="0x03d4" name="RBBM_PERFCTR_VFD_6_LO"/>
+	<reg32 offset="0x03d5" name="RBBM_PERFCTR_VFD_6_HI"/>
+	<reg32 offset="0x03d6" name="RBBM_PERFCTR_VFD_7_LO"/>
+	<reg32 offset="0x03d7" name="RBBM_PERFCTR_VFD_7_HI"/>
+	<reg32 offset="0x03d8" name="RBBM_PERFCTR_HLSQ_0_LO"/>
+	<reg32 offset="0x03d9" name="RBBM_PERFCTR_HLSQ_0_HI"/>
+	<reg32 offset="0x03da" name="RBBM_PERFCTR_HLSQ_1_LO"/>
+	<reg32 offset="0x03db" name="RBBM_PERFCTR_HLSQ_1_HI"/>
+	<reg32 offset="0x03dc" name="RBBM_PERFCTR_HLSQ_2_LO"/>
+	<reg32 offset="0x03dd" name="RBBM_PERFCTR_HLSQ_2_HI"/>
+	<reg32 offset="0x03de" name="RBBM_PERFCTR_HLSQ_3_LO"/>
+	<reg32 offset="0x03df" name="RBBM_PERFCTR_HLSQ_3_HI"/>
+	<reg32 offset="0x03e0" name="RBBM_PERFCTR_HLSQ_4_LO"/>
+	<reg32 offset="0x03e1" name="RBBM_PERFCTR_HLSQ_4_HI"/>
+	<reg32 offset="0x03e2" name="RBBM_PERFCTR_HLSQ_5_LO"/>
+	<reg32 offset="0x03e3" name="RBBM_PERFCTR_HLSQ_5_HI"/>
+	<reg32 offset="0x03e4" name="RBBM_PERFCTR_HLSQ_6_LO"/>
+	<reg32 offset="0x03e5" name="RBBM_PERFCTR_HLSQ_6_HI"/>
+	<reg32 offset="0x03e6" name="RBBM_PERFCTR_HLSQ_7_LO"/>
+	<reg32 offset="0x03e7" name="RBBM_PERFCTR_HLSQ_7_HI"/>
+	<reg32 offset="0x03e8" name="RBBM_PERFCTR_VPC_0_LO"/>
+	<reg32 offset="0x03e9" name="RBBM_PERFCTR_VPC_0_HI"/>
+	<reg32 offset="0x03ea" name="RBBM_PERFCTR_VPC_1_LO"/>
+	<reg32 offset="0x03eb" name="RBBM_PERFCTR_VPC_1_HI"/>
+	<reg32 offset="0x03ec" name="RBBM_PERFCTR_VPC_2_LO"/>
+	<reg32 offset="0x03ed" name="RBBM_PERFCTR_VPC_2_HI"/>
+	<reg32 offset="0x03ee" name="RBBM_PERFCTR_VPC_3_LO"/>
+	<reg32 offset="0x03ef" name="RBBM_PERFCTR_VPC_3_HI"/>
+	<reg32 offset="0x03f0" name="RBBM_PERFCTR_CCU_0_LO"/>
+	<reg32 offset="0x03f1" name="RBBM_PERFCTR_CCU_0_HI"/>
+	<reg32 offset="0x03f2" name="RBBM_PERFCTR_CCU_1_LO"/>
+	<reg32 offset="0x03f3" name="RBBM_PERFCTR_CCU_1_HI"/>
+	<reg32 offset="0x03f4" name="RBBM_PERFCTR_CCU_2_LO"/>
+	<reg32 offset="0x03f5" name="RBBM_PERFCTR_CCU_2_HI"/>
+	<reg32 offset="0x03f6" name="RBBM_PERFCTR_CCU_3_LO"/>
+	<reg32 offset="0x03f7" name="RBBM_PERFCTR_CCU_3_HI"/>
+	<reg32 offset="0x03f8" name="RBBM_PERFCTR_TSE_0_LO"/>
+	<reg32 offset="0x03f9" name="RBBM_PERFCTR_TSE_0_HI"/>
+	<reg32 offset="0x03fa" name="RBBM_PERFCTR_TSE_1_LO"/>
+	<reg32 offset="0x03fb" name="RBBM_PERFCTR_TSE_1_HI"/>
+	<reg32 offset="0x03fc" name="RBBM_PERFCTR_TSE_2_LO"/>
+	<reg32 offset="0x03fd" name="RBBM_PERFCTR_TSE_2_HI"/>
+	<reg32 offset="0x03fe" name="RBBM_PERFCTR_TSE_3_LO"/>
+	<reg32 offset="0x03ff" name="RBBM_PERFCTR_TSE_3_HI"/>
+	<reg32 offset="0x0400" name="RBBM_PERFCTR_RAS_0_LO"/>
+	<reg32 offset="0x0401" name="RBBM_PERFCTR_RAS_0_HI"/>
+	<reg32 offset="0x0402" name="RBBM_PERFCTR_RAS_1_LO"/>
+	<reg32 offset="0x0403" name="RBBM_PERFCTR_RAS_1_HI"/>
+	<reg32 offset="0x0404" name="RBBM_PERFCTR_RAS_2_LO"/>
+	<reg32 offset="0x0405" name="RBBM_PERFCTR_RAS_2_HI"/>
+	<reg32 offset="0x0406" name="RBBM_PERFCTR_RAS_3_LO"/>
+	<reg32 offset="0x0407" name="RBBM_PERFCTR_RAS_3_HI"/>
+	<reg32 offset="0x0408" name="RBBM_PERFCTR_UCHE_0_LO"/>
+	<reg32 offset="0x0409" name="RBBM_PERFCTR_UCHE_0_HI"/>
+	<reg32 offset="0x040a" name="RBBM_PERFCTR_UCHE_1_LO"/>
+	<reg32 offset="0x040b" name="RBBM_PERFCTR_UCHE_1_HI"/>
+	<reg32 offset="0x040c" name="RBBM_PERFCTR_UCHE_2_LO"/>
+	<reg32 offset="0x040d" name="RBBM_PERFCTR_UCHE_2_HI"/>
+	<reg32 offset="0x040e" name="RBBM_PERFCTR_UCHE_3_LO"/>
+	<reg32 offset="0x040f" name="RBBM_PERFCTR_UCHE_3_HI"/>
+	<reg32 offset="0x0410" name="RBBM_PERFCTR_UCHE_4_LO"/>
+	<reg32 offset="0x0411" name="RBBM_PERFCTR_UCHE_4_HI"/>
+	<reg32 offset="0x0412" name="RBBM_PERFCTR_UCHE_5_LO"/>
+	<reg32 offset="0x0413" name="RBBM_PERFCTR_UCHE_5_HI"/>
+	<reg32 offset="0x0414" name="RBBM_PERFCTR_UCHE_6_LO"/>
+	<reg32 offset="0x0415" name="RBBM_PERFCTR_UCHE_6_HI"/>
+	<reg32 offset="0x0416" name="RBBM_PERFCTR_UCHE_7_LO"/>
+	<reg32 offset="0x0417" name="RBBM_PERFCTR_UCHE_7_HI"/>
+	<reg32 offset="0x0418" name="RBBM_PERFCTR_TP_0_LO"/>
+	<reg32 offset="0x0419" name="RBBM_PERFCTR_TP_0_HI"/>
+	<reg32 offset="0x041a" name="RBBM_PERFCTR_TP_1_LO"/>
+	<reg32 offset="0x041b" name="RBBM_PERFCTR_TP_1_HI"/>
+	<reg32 offset="0x041c" name="RBBM_PERFCTR_TP_2_LO"/>
+	<reg32 offset="0x041d" name="RBBM_PERFCTR_TP_2_HI"/>
+	<reg32 offset="0x041e" name="RBBM_PERFCTR_TP_3_LO"/>
+	<reg32 offset="0x041f" name="RBBM_PERFCTR_TP_3_HI"/>
+	<reg32 offset="0x0420" name="RBBM_PERFCTR_TP_4_LO"/>
+	<reg32 offset="0x0421" name="RBBM_PERFCTR_TP_4_HI"/>
+	<reg32 offset="0x0422" name="RBBM_PERFCTR_TP_5_LO"/>
+	<reg32 offset="0x0423" name="RBBM_PERFCTR_TP_5_HI"/>
+	<reg32 offset="0x0424" name="RBBM_PERFCTR_TP_6_LO"/>
+	<reg32 offset="0x0425" name="RBBM_PERFCTR_TP_6_HI"/>
+	<reg32 offset="0x0426" name="RBBM_PERFCTR_TP_7_LO"/>
+	<reg32 offset="0x0427" name="RBBM_PERFCTR_TP_7_HI"/>
+	<reg32 offset="0x0428" name="RBBM_PERFCTR_SP_0_LO"/>
+	<reg32 offset="0x0429" name="RBBM_PERFCTR_SP_0_HI"/>
+	<reg32 offset="0x042a" name="RBBM_PERFCTR_SP_1_LO"/>
+	<reg32 offset="0x042b" name="RBBM_PERFCTR_SP_1_HI"/>
+	<reg32 offset="0x042c" name="RBBM_PERFCTR_SP_2_LO"/>
+	<reg32 offset="0x042d" name="RBBM_PERFCTR_SP_2_HI"/>
+	<reg32 offset="0x042e" name="RBBM_PERFCTR_SP_3_LO"/>
+	<reg32 offset="0x042f" name="RBBM_PERFCTR_SP_3_HI"/>
+	<reg32 offset="0x0430" name="RBBM_PERFCTR_SP_4_LO"/>
+	<reg32 offset="0x0431" name="RBBM_PERFCTR_SP_4_HI"/>
+	<reg32 offset="0x0432" name="RBBM_PERFCTR_SP_5_LO"/>
+	<reg32 offset="0x0433" name="RBBM_PERFCTR_SP_5_HI"/>
+	<reg32 offset="0x0434" name="RBBM_PERFCTR_SP_6_LO"/>
+	<reg32 offset="0x0435" name="RBBM_PERFCTR_SP_6_HI"/>
+	<reg32 offset="0x0436" name="RBBM_PERFCTR_SP_7_LO"/>
+	<reg32 offset="0x0437" name="RBBM_PERFCTR_SP_7_HI"/>
+	<reg32 offset="0x0438" name="RBBM_PERFCTR_SP_8_LO"/>
+	<reg32 offset="0x0439" name="RBBM_PERFCTR_SP_8_HI"/>
+	<reg32 offset="0x043a" name="RBBM_PERFCTR_SP_9_LO"/>
+	<reg32 offset="0x043b" name="RBBM_PERFCTR_SP_9_HI"/>
+	<reg32 offset="0x043c" name="RBBM_PERFCTR_SP_10_LO"/>
+	<reg32 offset="0x043d" name="RBBM_PERFCTR_SP_10_HI"/>
+	<reg32 offset="0x043e" name="RBBM_PERFCTR_SP_11_LO"/>
+	<reg32 offset="0x043f" name="RBBM_PERFCTR_SP_11_HI"/>
+	<reg32 offset="0x0440" name="RBBM_PERFCTR_RB_0_LO"/>
+	<reg32 offset="0x0441" name="RBBM_PERFCTR_RB_0_HI"/>
+	<reg32 offset="0x0442" name="RBBM_PERFCTR_RB_1_LO"/>
+	<reg32 offset="0x0443" name="RBBM_PERFCTR_RB_1_HI"/>
+	<reg32 offset="0x0444" name="RBBM_PERFCTR_RB_2_LO"/>
+	<reg32 offset="0x0445" name="RBBM_PERFCTR_RB_2_HI"/>
+	<reg32 offset="0x0446" name="RBBM_PERFCTR_RB_3_LO"/>
+	<reg32 offset="0x0447" name="RBBM_PERFCTR_RB_3_HI"/>
+	<reg32 offset="0x0448" name="RBBM_PERFCTR_RB_4_LO"/>
+	<reg32 offset="0x0449" name="RBBM_PERFCTR_RB_4_HI"/>
+	<reg32 offset="0x044a" name="RBBM_PERFCTR_RB_5_LO"/>
+	<reg32 offset="0x044b" name="RBBM_PERFCTR_RB_5_HI"/>
+	<reg32 offset="0x044c" name="RBBM_PERFCTR_RB_6_LO"/>
+	<reg32 offset="0x044d" name="RBBM_PERFCTR_RB_6_HI"/>
+	<reg32 offset="0x044e" name="RBBM_PERFCTR_RB_7_LO"/>
+	<reg32 offset="0x044f" name="RBBM_PERFCTR_RB_7_HI"/>
+	<reg32 offset="0x0450" name="RBBM_PERFCTR_VSC_0_LO"/>
+	<reg32 offset="0x0451" name="RBBM_PERFCTR_VSC_0_HI"/>
+	<reg32 offset="0x0452" name="RBBM_PERFCTR_VSC_1_LO"/>
+	<reg32 offset="0x0453" name="RBBM_PERFCTR_VSC_1_HI"/>
+	<reg32 offset="0x0454" name="RBBM_PERFCTR_LRZ_0_LO"/>
+	<reg32 offset="0x0455" name="RBBM_PERFCTR_LRZ_0_HI"/>
+	<reg32 offset="0x0456" name="RBBM_PERFCTR_LRZ_1_LO"/>
+	<reg32 offset="0x0457" name="RBBM_PERFCTR_LRZ_1_HI"/>
+	<reg32 offset="0x0458" name="RBBM_PERFCTR_LRZ_2_LO"/>
+	<reg32 offset="0x0459" name="RBBM_PERFCTR_LRZ_2_HI"/>
+	<reg32 offset="0x045a" name="RBBM_PERFCTR_LRZ_3_LO"/>
+	<reg32 offset="0x045b" name="RBBM_PERFCTR_LRZ_3_HI"/>
+	<reg32 offset="0x045c" name="RBBM_PERFCTR_CMP_0_LO"/>
+	<reg32 offset="0x045d" name="RBBM_PERFCTR_CMP_0_HI"/>
+	<reg32 offset="0x045e" name="RBBM_PERFCTR_CMP_1_LO"/>
+	<reg32 offset="0x045f" name="RBBM_PERFCTR_CMP_1_HI"/>
+	<reg32 offset="0x0460" name="RBBM_PERFCTR_CMP_2_LO"/>
+	<reg32 offset="0x0461" name="RBBM_PERFCTR_CMP_2_HI"/>
+	<reg32 offset="0x0462" name="RBBM_PERFCTR_CMP_3_LO"/>
+	<reg32 offset="0x0463" name="RBBM_PERFCTR_CMP_3_HI"/>
+	<reg32 offset="0x046b" name="RBBM_PERFCTR_RBBM_SEL_0" type="a5xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x046c" name="RBBM_PERFCTR_RBBM_SEL_1" type="a5xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x046d" name="RBBM_PERFCTR_RBBM_SEL_2" type="a5xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x046e" name="RBBM_PERFCTR_RBBM_SEL_3" type="a5xx_rbbm_perfcounter_select"/>
+	<reg32 offset="0x04d2" name="RBBM_ALWAYSON_COUNTER_LO"/>
+	<reg32 offset="0x04d3" name="RBBM_ALWAYSON_COUNTER_HI"/>
+	<reg32 offset="0x04f5" name="RBBM_STATUS">
+		<bitfield high="31" low="31" name="GPU_BUSY_IGN_AHB" />
+		<bitfield high="30" low="30" name="GPU_BUSY_IGN_AHB_CP" />
+		<bitfield high="29" low="29" name="HLSQ_BUSY" />
+		<bitfield high="28" low="28" name="VSC_BUSY" />
+		<bitfield high="27" low="27" name="TPL1_BUSY" />
+		<bitfield high="26" low="26" name="SP_BUSY" />
+		<bitfield high="25" low="25" name="UCHE_BUSY" />
+		<bitfield high="24" low="24" name="VPC_BUSY" />
+		<bitfield high="23" low="23" name="VFDP_BUSY" />
+		<bitfield high="22" low="22" name="VFD_BUSY" />
+		<bitfield high="21" low="21" name="TESS_BUSY" />
+		<bitfield high="20" low="20" name="PC_VSD_BUSY" />
+		<bitfield high="19" low="19" name="PC_DCALL_BUSY" />
+		<bitfield high="18" low="18" name="GPMU_SLAVE_BUSY" />
+		<bitfield high="17" low="17" name="DCOM_BUSY" />
+		<bitfield high="16" low="16" name="COM_BUSY" />
+		<bitfield high="15" low="15" name="LRZ_BUZY" />
+		<bitfield high="14" low="14" name="A2D_DSP_BUSY" />
+		<bitfield high="13" low="13" name="CCUFCHE_BUSY" />
+		<bitfield high="12" low="12" name="RB_BUSY" />
+		<bitfield high="11" low="11" name="RAS_BUSY" />
+		<bitfield high="10" low="10" name="TSE_BUSY" />
+		<bitfield high="9" low="9" name="VBIF_BUSY" />
+		<bitfield high="8" low="8" name="GPU_BUSY_IGN_AHB_HYST" />
+		<bitfield high="7" low="7" name="CP_BUSY_IGN_HYST" />
+		<bitfield high="6" low="6" name="CP_BUSY" />
+		<bitfield high="5" low="5" name="GPMU_MASTER_BUSY" />
+		<bitfield high="4" low="4" name="CP_CRASH_BUSY" />
+		<bitfield high="3" low="3" name="CP_ETS_BUSY" />
+		<bitfield high="2" low="2" name="CP_PFP_BUSY" />
+		<bitfield high="1" low="1" name="CP_ME_BUSY" />
+		<bitfield high="0" low="0" name="HI_BUSY" />
+	</reg32>
+	<reg32 offset="0x0530" name="RBBM_STATUS3">
+		<bitfield pos="24" name="SMMU_STALLED_ON_FAULT" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x04e1" name="RBBM_INT_0_STATUS"/>
+	<reg32 offset="0x04f0" name="RBBM_AHB_ME_SPLIT_STATUS"/>
+	<reg32 offset="0x04f1" name="RBBM_AHB_PFP_SPLIT_STATUS"/>
+	<reg32 offset="0x04f3" name="RBBM_AHB_ETS_SPLIT_STATUS"/>
+	<reg32 offset="0x04f4" name="RBBM_AHB_ERROR_STATUS"/>
+	<reg32 offset="0x0464" name="RBBM_PERFCTR_CNTL"/>
+	<reg32 offset="0x0465" name="RBBM_PERFCTR_LOAD_CMD0"/>
+	<reg32 offset="0x0466" name="RBBM_PERFCTR_LOAD_CMD1"/>
+	<reg32 offset="0x0467" name="RBBM_PERFCTR_LOAD_CMD2"/>
+	<reg32 offset="0x0468" name="RBBM_PERFCTR_LOAD_CMD3"/>
+	<reg32 offset="0x0469" name="RBBM_PERFCTR_LOAD_VALUE_LO"/>
+	<reg32 offset="0x046a" name="RBBM_PERFCTR_LOAD_VALUE_HI"/>
+	<reg32 offset="0x046f" name="RBBM_PERFCTR_GPU_BUSY_MASKED"/>
+	<reg32 offset="0x04ed" name="RBBM_AHB_ERROR"/>
+	<reg32 offset="0x0504" name="RBBM_CFG_DBGBUS_EVENT_LOGIC"/>
+	<reg32 offset="0x0505" name="RBBM_CFG_DBGBUS_OVER"/>
+	<reg32 offset="0x0506" name="RBBM_CFG_DBGBUS_COUNT0"/>
+	<reg32 offset="0x0507" name="RBBM_CFG_DBGBUS_COUNT1"/>
+	<reg32 offset="0x0508" name="RBBM_CFG_DBGBUS_COUNT2"/>
+	<reg32 offset="0x0509" name="RBBM_CFG_DBGBUS_COUNT3"/>
+	<reg32 offset="0x050a" name="RBBM_CFG_DBGBUS_COUNT4"/>
+	<reg32 offset="0x050b" name="RBBM_CFG_DBGBUS_COUNT5"/>
+	<reg32 offset="0x050c" name="RBBM_CFG_DBGBUS_TRACE_ADDR"/>
+	<reg32 offset="0x050d" name="RBBM_CFG_DBGBUS_TRACE_BUF0"/>
+	<reg32 offset="0x050e" name="RBBM_CFG_DBGBUS_TRACE_BUF1"/>
+	<reg32 offset="0x050f" name="RBBM_CFG_DBGBUS_TRACE_BUF2"/>
+	<reg32 offset="0x0510" name="RBBM_CFG_DBGBUS_TRACE_BUF3"/>
+	<reg32 offset="0x0511" name="RBBM_CFG_DBGBUS_TRACE_BUF4"/>
+	<reg32 offset="0x0512" name="RBBM_CFG_DBGBUS_MISR0"/>
+	<reg32 offset="0x0513" name="RBBM_CFG_DBGBUS_MISR1"/>
+	<reg32 offset="0x0533" name="RBBM_ISDB_CNT"/>
+	<reg32 offset="0xf000" name="RBBM_SECVID_TRUST_CONFIG"/>
+	<reg32 offset="0xf400" name="RBBM_SECVID_TRUST_CNTL"/>
+	<reg32 offset="0xf800" name="RBBM_SECVID_TSB_TRUSTED_BASE_LO"/>
+	<reg32 offset="0xf801" name="RBBM_SECVID_TSB_TRUSTED_BASE_HI"/>
+	<reg32 offset="0xf802" name="RBBM_SECVID_TSB_TRUSTED_SIZE"/>
+	<reg32 offset="0xf803" name="RBBM_SECVID_TSB_CNTL"/>
+	<reg32 offset="0xf804" name="RBBM_SECVID_TSB_COMP_STATUS_LO"/>
+	<reg32 offset="0xf805" name="RBBM_SECVID_TSB_COMP_STATUS_HI"/>
+	<reg32 offset="0xf806" name="RBBM_SECVID_TSB_UCHE_STATUS_LO"/>
+	<reg32 offset="0xf807" name="RBBM_SECVID_TSB_UCHE_STATUS_HI"/>
+	<reg32 offset="0xf810" name="RBBM_SECVID_TSB_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+
+	<!-- VSC registers -->
+	<reg32 offset="0x0bc2" name="VSC_BIN_SIZE">
+		<bitfield name="WIDTH" low="0" high="7" shr="5" type="uint"/>
+		<bitfield name="HEIGHT" low="9" high="16" shr="5" type="uint"/>
+		<!-- b17 maybe BYPASS like RB_CNTL, but reg not written for bypass -->
+	</reg32>
+	<reg32 offset="0x0bc3" name="VSC_SIZE_ADDRESS_LO"/>
+	<reg32 offset="0x0bc4" name="VSC_SIZE_ADDRESS_HI"/>
+	<reg32 offset="0x0bc5" name="UNKNOWN_0BC5"/> <!-- always 00000000? -->
+	<reg32 offset="0x0bc6" name="UNKNOWN_0BC6"/> <!-- always 00000000? -->
+	<array offset="0x0bd0" name="VSC_PIPE_CONFIG" stride="1" length="16">
+		<reg32 offset="0x0" name="REG">
+			<doc>
+				Configures the mapping between VSC_PIPE buffer and
+				bin, X/Y specify the bin index in the horiz/vert
+				direction (0,0 is upper left, 0,1 is leftmost bin
+				on second row, and so on).  W/H specify the number
+				of bins assigned to this VSC_PIPE in the horiz/vert
+				dimension.
+			</doc>
+			<bitfield name="X" low="0" high="9" type="uint"/>
+			<bitfield name="Y" low="10" high="19" type="uint"/>
+			<bitfield name="W" low="20" high="23" type="uint"/>
+			<bitfield name="H" low="24" high="27" type="uint"/>
+		</reg32>
+	</array>
+	<array offset="0x0be0" name="VSC_PIPE_DATA_ADDRESS" stride="2" length="16">
+		<reg32 offset="0x0" name="LO"/>
+		<reg32 offset="0x1" name="HI"/>
+	</array>
+	<array offset="0x0c00" name="VSC_PIPE_DATA_LENGTH" stride="1" length="16">
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+	<reg32 offset="0x0c60" name="VSC_PERFCTR_VSC_SEL_0" type="a5xx_vsc_perfcounter_select"/>
+	<reg32 offset="0x0c61" name="VSC_PERFCTR_VSC_SEL_1" type="a5xx_vsc_perfcounter_select"/>
+
+	<!-- used for some blits?? -->
+	<reg32 offset="0x0cdd" name="VSC_RESOLVE_CNTL" type="adreno_reg_xy"/>
+
+	<!-- GRAS registers -->
+	<reg32 offset="0x0c81" name="GRAS_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0c90" name="GRAS_PERFCTR_TSE_SEL_0" type="a5xx_tse_perfcounter_select"/>
+	<reg32 offset="0x0c91" name="GRAS_PERFCTR_TSE_SEL_1" type="a5xx_tse_perfcounter_select"/>
+	<reg32 offset="0x0c92" name="GRAS_PERFCTR_TSE_SEL_2" type="a5xx_tse_perfcounter_select"/>
+	<reg32 offset="0x0c93" name="GRAS_PERFCTR_TSE_SEL_3" type="a5xx_tse_perfcounter_select"/>
+	<reg32 offset="0x0c94" name="GRAS_PERFCTR_RAS_SEL_0" type="a5xx_ras_perfcounter_select"/>
+	<reg32 offset="0x0c95" name="GRAS_PERFCTR_RAS_SEL_1" type="a5xx_ras_perfcounter_select"/>
+	<reg32 offset="0x0c96" name="GRAS_PERFCTR_RAS_SEL_2" type="a5xx_ras_perfcounter_select"/>
+	<reg32 offset="0x0c97" name="GRAS_PERFCTR_RAS_SEL_3" type="a5xx_ras_perfcounter_select"/>
+	<reg32 offset="0x0c98" name="GRAS_PERFCTR_LRZ_SEL_0" type="a5xx_lrz_perfcounter_select"/>
+	<reg32 offset="0x0c99" name="GRAS_PERFCTR_LRZ_SEL_1" type="a5xx_lrz_perfcounter_select"/>
+	<reg32 offset="0x0c9a" name="GRAS_PERFCTR_LRZ_SEL_2" type="a5xx_lrz_perfcounter_select"/>
+	<reg32 offset="0x0c9b" name="GRAS_PERFCTR_LRZ_SEL_3" type="a5xx_lrz_perfcounter_select"/>
+
+	<reg32 offset="0x0cc4" name="RB_DBG_ECO_CNTL"/> <!-- always 00100000? -->
+	<reg32 offset="0x0cc5" name="RB_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0cc6" name="RB_MODE_CNTL"/> <!-- always 00000044? -->
+	<reg32 offset="0x0cc7" name="RB_CCU_CNTL"/> <!-- always b0056080 or 10000000? -->
+	<reg32 offset="0x0cd0" name="RB_PERFCTR_RB_SEL_0" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd1" name="RB_PERFCTR_RB_SEL_1" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd2" name="RB_PERFCTR_RB_SEL_2" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd3" name="RB_PERFCTR_RB_SEL_3" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd4" name="RB_PERFCTR_RB_SEL_4" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd5" name="RB_PERFCTR_RB_SEL_5" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd6" name="RB_PERFCTR_RB_SEL_6" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd7" name="RB_PERFCTR_RB_SEL_7" type="a5xx_rb_perfcounter_select"/>
+	<reg32 offset="0x0cd8" name="RB_PERFCTR_CCU_SEL_0" type="a5xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0cd9" name="RB_PERFCTR_CCU_SEL_1" type="a5xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0cda" name="RB_PERFCTR_CCU_SEL_2" type="a5xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0cdb" name="RB_PERFCTR_CCU_SEL_3" type="a5xx_ccu_perfcounter_select"/>
+	<reg32 offset="0x0ce0" name="RB_POWERCTR_RB_SEL_0"/>
+	<reg32 offset="0x0ce1" name="RB_POWERCTR_RB_SEL_1"/>
+	<reg32 offset="0x0ce2" name="RB_POWERCTR_RB_SEL_2"/>
+	<reg32 offset="0x0ce3" name="RB_POWERCTR_RB_SEL_3"/>
+	<reg32 offset="0x0ce4" name="RB_POWERCTR_CCU_SEL_0"/>
+	<reg32 offset="0x0ce5" name="RB_POWERCTR_CCU_SEL_1"/>
+	<reg32 offset="0x0cec" name="RB_PERFCTR_CMP_SEL_0" type="a5xx_cmp_perfcounter_select"/>
+	<reg32 offset="0x0ced" name="RB_PERFCTR_CMP_SEL_1" type="a5xx_cmp_perfcounter_select"/>
+	<reg32 offset="0x0cee" name="RB_PERFCTR_CMP_SEL_2" type="a5xx_cmp_perfcounter_select"/>
+	<reg32 offset="0x0cef" name="RB_PERFCTR_CMP_SEL_3" type="a5xx_cmp_perfcounter_select"/>
+
+	<reg32 offset="0x0d00" name="PC_DBG_ECO_CNTL">
+		<bitfield name="TWOPASSUSEWFI" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0d01" name="PC_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0d02" name="PC_MODE_CNTL"/> <!-- always 0000001f? -->
+	<reg32 offset="0x0d04" name="PC_INDEX_BUF_LO"/>
+	<reg32 offset="0x0d05" name="PC_INDEX_BUF_HI"/>
+	<reg32 offset="0x0d06" name="PC_START_INDEX"/>
+	<reg32 offset="0x0d07" name="PC_MAX_INDEX"/>
+	<reg32 offset="0x0d08" name="PC_TESSFACTOR_ADDR_LO"/>
+	<reg32 offset="0x0d09" name="PC_TESSFACTOR_ADDR_HI"/>
+	<reg32 offset="0x0d10" name="PC_PERFCTR_PC_SEL_0" type="a5xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d11" name="PC_PERFCTR_PC_SEL_1" type="a5xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d12" name="PC_PERFCTR_PC_SEL_2" type="a5xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d13" name="PC_PERFCTR_PC_SEL_3" type="a5xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d14" name="PC_PERFCTR_PC_SEL_4" type="a5xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d15" name="PC_PERFCTR_PC_SEL_5" type="a5xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d16" name="PC_PERFCTR_PC_SEL_6" type="a5xx_pc_perfcounter_select"/>
+	<reg32 offset="0x0d17" name="PC_PERFCTR_PC_SEL_7" type="a5xx_pc_perfcounter_select"/>
+
+	<reg32 offset="0x0e00" name="HLSQ_TIMEOUT_THRESHOLD_0"/>
+	<reg32 offset="0x0e01" name="HLSQ_TIMEOUT_THRESHOLD_1"/>
+	<reg32 offset="0x0e04" name="HLSQ_DBG_ECO_CNTL"/>
+	<reg32 offset="0x0e05" name="HLSQ_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0e06" name="HLSQ_MODE_CNTL"/> <!-- always 00000001? -->
+	<reg32 offset="0x0e10" name="HLSQ_PERFCTR_HLSQ_SEL_0" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e11" name="HLSQ_PERFCTR_HLSQ_SEL_1" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e12" name="HLSQ_PERFCTR_HLSQ_SEL_2" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e13" name="HLSQ_PERFCTR_HLSQ_SEL_3" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e14" name="HLSQ_PERFCTR_HLSQ_SEL_4" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e15" name="HLSQ_PERFCTR_HLSQ_SEL_5" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e16" name="HLSQ_PERFCTR_HLSQ_SEL_6" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0e17" name="HLSQ_PERFCTR_HLSQ_SEL_7" type="a5xx_hlsq_perfcounter_select"/>
+	<reg32 offset="0x0f08" name="HLSQ_SPTP_RDSEL"/>
+	<reg32 offset="0xbc00" name="HLSQ_DBG_READ_SEL"/>
+	<reg32 offset="0xa000" name="HLSQ_DBG_AHB_READ_APERTURE"/>
+
+	<reg32 offset="0x0e41" name="VFD_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0e42" name="VFD_MODE_CNTL"/> <!-- always 00000000? -->
+	<reg32 offset="0x0e50" name="VFD_PERFCTR_VFD_SEL_0" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e51" name="VFD_PERFCTR_VFD_SEL_1" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e52" name="VFD_PERFCTR_VFD_SEL_2" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e53" name="VFD_PERFCTR_VFD_SEL_3" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e54" name="VFD_PERFCTR_VFD_SEL_4" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e55" name="VFD_PERFCTR_VFD_SEL_5" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e56" name="VFD_PERFCTR_VFD_SEL_6" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e57" name="VFD_PERFCTR_VFD_SEL_7" type="a5xx_vfd_perfcounter_select"/>
+	<reg32 offset="0x0e60" name="VPC_DBG_ECO_CNTL">
+		<bitfield name="ALLFLATOPTDIS" pos="10" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0e61" name="VPC_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0e62" name="VPC_MODE_CNTL">
+		<bitfield name="BINNING_PASS" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0e64" name="VPC_PERFCTR_VPC_SEL_0" type="a5xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e65" name="VPC_PERFCTR_VPC_SEL_1" type="a5xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e66" name="VPC_PERFCTR_VPC_SEL_2" type="a5xx_vpc_perfcounter_select"/>
+	<reg32 offset="0x0e67" name="VPC_PERFCTR_VPC_SEL_3" type="a5xx_vpc_perfcounter_select"/>
+
+	<reg32 offset="0x0e80" name="UCHE_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0e81" name="UCHE_MODE_CNTL"/>
+	<reg32 offset="0x0e82" name="UCHE_SVM_CNTL"/>
+	<reg32 offset="0x0e87" name="UCHE_WRITE_THRU_BASE_LO"/>
+	<reg32 offset="0x0e88" name="UCHE_WRITE_THRU_BASE_HI"/>
+	<reg32 offset="0x0e89" name="UCHE_TRAP_BASE_LO"/>
+	<reg32 offset="0x0e8a" name="UCHE_TRAP_BASE_HI"/>
+	<reg32 offset="0x0e8b" name="UCHE_GMEM_RANGE_MIN_LO"/>
+	<reg32 offset="0x0e8c" name="UCHE_GMEM_RANGE_MIN_HI"/>
+	<reg32 offset="0x0e8d" name="UCHE_GMEM_RANGE_MAX_LO"/>
+	<reg32 offset="0x0e8e" name="UCHE_GMEM_RANGE_MAX_HI"/>
+	<reg32 offset="0x0e8f" name="UCHE_DBG_ECO_CNTL_2"/>
+	<reg32 offset="0x0e90" name="UCHE_DBG_ECO_CNTL"/>
+	<reg32 offset="0x0e91" name="UCHE_CACHE_INVALIDATE_MIN_LO"/>
+	<reg32 offset="0x0e92" name="UCHE_CACHE_INVALIDATE_MIN_HI"/>
+	<reg32 offset="0x0e93" name="UCHE_CACHE_INVALIDATE_MAX_LO"/>
+	<reg32 offset="0x0e94" name="UCHE_CACHE_INVALIDATE_MAX_HI"/>
+	<reg32 offset="0x0e95" name="UCHE_CACHE_INVALIDATE"/>
+	<reg32 offset="0x0e96" name="UCHE_CACHE_WAYS"/>
+	<reg32 offset="0x0ea0" name="UCHE_PERFCTR_UCHE_SEL_0" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea1" name="UCHE_PERFCTR_UCHE_SEL_1" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea2" name="UCHE_PERFCTR_UCHE_SEL_2" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea3" name="UCHE_PERFCTR_UCHE_SEL_3" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea4" name="UCHE_PERFCTR_UCHE_SEL_4" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea5" name="UCHE_PERFCTR_UCHE_SEL_5" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea6" name="UCHE_PERFCTR_UCHE_SEL_6" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea7" name="UCHE_PERFCTR_UCHE_SEL_7" type="a5xx_uche_perfcounter_select"/>
+	<reg32 offset="0x0ea8" name="UCHE_POWERCTR_UCHE_SEL_0"/>
+	<reg32 offset="0x0ea9" name="UCHE_POWERCTR_UCHE_SEL_1"/>
+	<reg32 offset="0x0eaa" name="UCHE_POWERCTR_UCHE_SEL_2"/>
+	<reg32 offset="0x0eab" name="UCHE_POWERCTR_UCHE_SEL_3"/>
+	<reg32 offset="0x0eb1" name="UCHE_TRAP_LOG_LO"/>
+	<reg32 offset="0x0eb2" name="UCHE_TRAP_LOG_HI"/>
+
+	<reg32 offset="0x0ec0" name="SP_DBG_ECO_CNTL"/>
+	<reg32 offset="0x0ec1" name="SP_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0ec2" name="SP_MODE_CNTL"/> <!-- always 0000001e? -->
+	<reg32 offset="0x0ed0" name="SP_PERFCTR_SP_SEL_0"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed1" name="SP_PERFCTR_SP_SEL_1"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed2" name="SP_PERFCTR_SP_SEL_2"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed3" name="SP_PERFCTR_SP_SEL_3"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed4" name="SP_PERFCTR_SP_SEL_4"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed5" name="SP_PERFCTR_SP_SEL_5"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed6" name="SP_PERFCTR_SP_SEL_6"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed7" name="SP_PERFCTR_SP_SEL_7"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed8" name="SP_PERFCTR_SP_SEL_8"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0ed9" name="SP_PERFCTR_SP_SEL_9"  type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0eda" name="SP_PERFCTR_SP_SEL_10" type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0edb" name="SP_PERFCTR_SP_SEL_11" type="a5xx_sp_perfcounter_select"/>
+	<reg32 offset="0x0edc" name="SP_POWERCTR_SP_SEL_0"/>
+	<reg32 offset="0x0edd" name="SP_POWERCTR_SP_SEL_1"/>
+	<reg32 offset="0x0ede" name="SP_POWERCTR_SP_SEL_2"/>
+	<reg32 offset="0x0edf" name="SP_POWERCTR_SP_SEL_3"/>
+
+	<reg32 offset="0x0f01" name="TPL1_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0f02" name="TPL1_MODE_CNTL"/> <!-- always 00000544? -->
+	<reg32 offset="0x0f10" name="TPL1_PERFCTR_TP_SEL_0" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f11" name="TPL1_PERFCTR_TP_SEL_1" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f12" name="TPL1_PERFCTR_TP_SEL_2" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f13" name="TPL1_PERFCTR_TP_SEL_3" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f14" name="TPL1_PERFCTR_TP_SEL_4" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f15" name="TPL1_PERFCTR_TP_SEL_5" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f16" name="TPL1_PERFCTR_TP_SEL_6" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f17" name="TPL1_PERFCTR_TP_SEL_7" type="a5xx_tp_perfcounter_select"/>
+	<reg32 offset="0x0f18" name="TPL1_POWERCTR_TP_SEL_0"/>
+	<reg32 offset="0x0f19" name="TPL1_POWERCTR_TP_SEL_1"/>
+	<reg32 offset="0x0f1a" name="TPL1_POWERCTR_TP_SEL_2"/>
+	<reg32 offset="0x0f1b" name="TPL1_POWERCTR_TP_SEL_3"/>
+
+	<reg32 offset="0x3000" name="VBIF_VERSION"/>
+	<reg32 offset="0x3001" name="VBIF_CLKON"/>
+<!--
+#define A5XX_VBIF_CLKON_FORCE_ON_TESTBUS_MASK   0x1
+#define A5XX_VBIF_CLKON_FORCE_ON_TESTBUS_SHIFT  0x1
+ -->
+	<reg32 offset="0x3028" name="VBIF_ABIT_SORT"/>
+	<reg32 offset="0x3029" name="VBIF_ABIT_SORT_CONF"/>
+	<reg32 offset="0x3049" name="VBIF_ROUND_ROBIN_QOS_ARB"/>
+	<reg32 offset="0x302a" name="VBIF_GATE_OFF_WRREQ_EN"/>
+	<reg32 offset="0x302c" name="VBIF_IN_RD_LIM_CONF0"/>
+	<reg32 offset="0x302d" name="VBIF_IN_RD_LIM_CONF1"/>
+	<reg32 offset="0x3080" name="VBIF_XIN_HALT_CTRL0"/>
+<!--
+#define A5XX_VBIF_XIN_HALT_CTRL0_MASK	   0xF
+#define A510_VBIF_XIN_HALT_CTRL0_MASK	   0x7
+ -->
+	<reg32 offset="0x3081" name="VBIF_XIN_HALT_CTRL1"/>
+	<reg32 offset="0x3084" name="VBIF_TEST_BUS_OUT_CTRL"/>
+<!--
+#define A5XX_VBIF_TEST_BUS_OUT_CTRL_EN_MASK    0x1
+#define A5XX_VBIF_TEST_BUS_OUT_CTRL_EN_SHIFT   0x0
+ -->
+	<reg32 offset="0x3085" name="VBIF_TEST_BUS1_CTRL0"/>
+	<reg32 offset="0x3086" name="VBIF_TEST_BUS1_CTRL1"/>
+<!--
+#define A5XX_VBIF_TEST_BUS1_CTRL1_DATA_SEL_MASK  0xF
+#define A5XX_VBIF_TEST_BUS1_CTRL1_DATA_SEL_SHIFT 0x0
+ -->
+	<reg32 offset="0x3087" name="VBIF_TEST_BUS2_CTRL0"/>
+	<reg32 offset="0x3088" name="VBIF_TEST_BUS2_CTRL1"/>
+<!--
+#define A5XX_VBIF_TEST_BUS2_CTRL1_DATA_SEL_MASK     0xF
+#define A5XX_VBIF_TEST_BUS2_CTRL1_DATA_SEL_SHIFT    0x0
+ -->
+	<reg32 offset="0x308c" name="VBIF_TEST_BUS_OUT"/>
+	<reg32 offset="0x30c0" name="VBIF_PERF_CNT_EN0"/>
+	<reg32 offset="0x30c1" name="VBIF_PERF_CNT_EN1"/>
+	<reg32 offset="0x30c2" name="VBIF_PERF_CNT_EN2"/>
+	<reg32 offset="0x30c3" name="VBIF_PERF_CNT_EN3"/>
+	<reg32 offset="0x30c8" name="VBIF_PERF_CNT_CLR0"/>
+	<reg32 offset="0x30c9" name="VBIF_PERF_CNT_CLR1"/>
+	<reg32 offset="0x30ca" name="VBIF_PERF_CNT_CLR2"/>
+	<reg32 offset="0x30cb" name="VBIF_PERF_CNT_CLR3"/>
+	<reg32 offset="0x30d0" name="VBIF_PERF_CNT_SEL0" type="a5xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d1" name="VBIF_PERF_CNT_SEL1" type="a5xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d2" name="VBIF_PERF_CNT_SEL2" type="a5xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d3" name="VBIF_PERF_CNT_SEL3" type="a5xx_vbif_perfcounter_select"/>
+	<reg32 offset="0x30d8" name="VBIF_PERF_CNT_LOW0"/>
+	<reg32 offset="0x30d9" name="VBIF_PERF_CNT_LOW1"/>
+	<reg32 offset="0x30da" name="VBIF_PERF_CNT_LOW2"/>
+	<reg32 offset="0x30db" name="VBIF_PERF_CNT_LOW3"/>
+	<reg32 offset="0x30e0" name="VBIF_PERF_CNT_HIGH0"/>
+	<reg32 offset="0x30e1" name="VBIF_PERF_CNT_HIGH1"/>
+	<reg32 offset="0x30e2" name="VBIF_PERF_CNT_HIGH2"/>
+	<reg32 offset="0x30e3" name="VBIF_PERF_CNT_HIGH3"/>
+	<reg32 offset="0x3100" name="VBIF_PERF_PWR_CNT_EN0"/>
+	<reg32 offset="0x3101" name="VBIF_PERF_PWR_CNT_EN1"/>
+	<reg32 offset="0x3102" name="VBIF_PERF_PWR_CNT_EN2"/>
+	<reg32 offset="0x3110" name="VBIF_PERF_PWR_CNT_LOW0"/>
+	<reg32 offset="0x3111" name="VBIF_PERF_PWR_CNT_LOW1"/>
+	<reg32 offset="0x3112" name="VBIF_PERF_PWR_CNT_LOW2"/>
+	<reg32 offset="0x3118" name="VBIF_PERF_PWR_CNT_HIGH0"/>
+	<reg32 offset="0x3119" name="VBIF_PERF_PWR_CNT_HIGH1"/>
+	<reg32 offset="0x311a" name="VBIF_PERF_PWR_CNT_HIGH2"/>
+
+	<reg32 offset="0x8800" name="GPMU_INST_RAM_BASE"/>
+	<reg32 offset="0x9800" name="GPMU_DATA_RAM_BASE"/>
+
+<!--
+/* COUNTABLE FOR SP PERFCOUNTER */
+#define A5XX_SP_ALU_ACTIVE_CYCLES          0x1
+#define A5XX_SP0_ICL1_MISSES               0x35
+#define A5XX_SP_FS_CFLOW_INSTRUCTIONS      0x27
+
+/* COUNTABLE FOR TSE PERFCOUNTER */
+#define A5XX_TSE_INPUT_PRIM_NUM            0x6
+ -->
+	<reg32 offset="0xa840" name="SP_POWER_COUNTER_0_LO"/>
+	<reg32 offset="0xa841" name="SP_POWER_COUNTER_0_HI"/>
+	<reg32 offset="0xa842" name="SP_POWER_COUNTER_1_LO"/>
+	<reg32 offset="0xa843" name="SP_POWER_COUNTER_1_HI"/>
+	<reg32 offset="0xa844" name="SP_POWER_COUNTER_2_LO"/>
+	<reg32 offset="0xa845" name="SP_POWER_COUNTER_2_HI"/>
+	<reg32 offset="0xa846" name="SP_POWER_COUNTER_3_LO"/>
+	<reg32 offset="0xa847" name="SP_POWER_COUNTER_3_HI"/>
+	<reg32 offset="0xa848" name="TP_POWER_COUNTER_0_LO"/>
+	<reg32 offset="0xa849" name="TP_POWER_COUNTER_0_HI"/>
+	<reg32 offset="0xa84a" name="TP_POWER_COUNTER_1_LO"/>
+	<reg32 offset="0xa84b" name="TP_POWER_COUNTER_1_HI"/>
+	<reg32 offset="0xa84c" name="TP_POWER_COUNTER_2_LO"/>
+	<reg32 offset="0xa84d" name="TP_POWER_COUNTER_2_HI"/>
+	<reg32 offset="0xa84e" name="TP_POWER_COUNTER_3_LO"/>
+	<reg32 offset="0xa84f" name="TP_POWER_COUNTER_3_HI"/>
+	<reg32 offset="0xa850" name="RB_POWER_COUNTER_0_LO"/>
+	<reg32 offset="0xa851" name="RB_POWER_COUNTER_0_HI"/>
+	<reg32 offset="0xa852" name="RB_POWER_COUNTER_1_LO"/>
+	<reg32 offset="0xa853" name="RB_POWER_COUNTER_1_HI"/>
+	<reg32 offset="0xa854" name="RB_POWER_COUNTER_2_LO"/>
+	<reg32 offset="0xa855" name="RB_POWER_COUNTER_2_HI"/>
+	<reg32 offset="0xa856" name="RB_POWER_COUNTER_3_LO"/>
+	<reg32 offset="0xa857" name="RB_POWER_COUNTER_3_HI"/>
+	<reg32 offset="0xa858" name="CCU_POWER_COUNTER_0_LO"/>
+	<reg32 offset="0xa859" name="CCU_POWER_COUNTER_0_HI"/>
+	<reg32 offset="0xa85a" name="CCU_POWER_COUNTER_1_LO"/>
+	<reg32 offset="0xa85b" name="CCU_POWER_COUNTER_1_HI"/>
+	<reg32 offset="0xa85c" name="UCHE_POWER_COUNTER_0_LO"/>
+	<reg32 offset="0xa85d" name="UCHE_POWER_COUNTER_0_HI"/>
+	<reg32 offset="0xa85e" name="UCHE_POWER_COUNTER_1_LO"/>
+	<reg32 offset="0xa85f" name="UCHE_POWER_COUNTER_1_HI"/>
+	<reg32 offset="0xa860" name="UCHE_POWER_COUNTER_2_LO"/>
+	<reg32 offset="0xa861" name="UCHE_POWER_COUNTER_2_HI"/>
+	<reg32 offset="0xa862" name="UCHE_POWER_COUNTER_3_LO"/>
+	<reg32 offset="0xa863" name="UCHE_POWER_COUNTER_3_HI"/>
+	<reg32 offset="0xa864" name="CP_POWER_COUNTER_0_LO"/>
+	<reg32 offset="0xa865" name="CP_POWER_COUNTER_0_HI"/>
+	<reg32 offset="0xa866" name="CP_POWER_COUNTER_1_LO"/>
+	<reg32 offset="0xa867" name="CP_POWER_COUNTER_1_HI"/>
+	<reg32 offset="0xa868" name="CP_POWER_COUNTER_2_LO"/>
+	<reg32 offset="0xa869" name="CP_POWER_COUNTER_2_HI"/>
+	<reg32 offset="0xa86a" name="CP_POWER_COUNTER_3_LO"/>
+	<reg32 offset="0xa86b" name="CP_POWER_COUNTER_3_HI"/>
+	<reg32 offset="0xa86c" name="GPMU_POWER_COUNTER_0_LO"/>
+	<reg32 offset="0xa86d" name="GPMU_POWER_COUNTER_0_HI"/>
+	<reg32 offset="0xa86e" name="GPMU_POWER_COUNTER_1_LO"/>
+	<reg32 offset="0xa86f" name="GPMU_POWER_COUNTER_1_HI"/>
+	<reg32 offset="0xa870" name="GPMU_POWER_COUNTER_2_LO"/>
+	<reg32 offset="0xa871" name="GPMU_POWER_COUNTER_2_HI"/>
+	<reg32 offset="0xa872" name="GPMU_POWER_COUNTER_3_LO"/>
+	<reg32 offset="0xa873" name="GPMU_POWER_COUNTER_3_HI"/>
+	<reg32 offset="0xa874" name="GPMU_POWER_COUNTER_4_LO"/>
+	<reg32 offset="0xa875" name="GPMU_POWER_COUNTER_4_HI"/>
+	<reg32 offset="0xa876" name="GPMU_POWER_COUNTER_5_LO"/>
+	<reg32 offset="0xa877" name="GPMU_POWER_COUNTER_5_HI"/>
+	<reg32 offset="0xa878" name="GPMU_POWER_COUNTER_ENABLE"/>
+	<reg32 offset="0xa879" name="GPMU_ALWAYS_ON_COUNTER_LO"/>
+	<reg32 offset="0xa87a" name="GPMU_ALWAYS_ON_COUNTER_HI"/>
+	<reg32 offset="0xa87b" name="GPMU_ALWAYS_ON_COUNTER_RESET"/>
+	<reg32 offset="0xa87c" name="GPMU_POWER_COUNTER_SELECT_0"/>
+	<reg32 offset="0xa87d" name="GPMU_POWER_COUNTER_SELECT_1"/>
+
+	<reg32 offset="0xa880" name="GPMU_GPMU_SP_CLOCK_CONTROL"/>
+	<reg32 offset="0xa881" name="GPMU_SP_POWER_CNTL"/>
+	<reg32 offset="0xa886" name="GPMU_RBCCU_CLOCK_CNTL"/>
+	<reg32 offset="0xa887" name="GPMU_RBCCU_POWER_CNTL"/>
+	<reg32 offset="0xa88b" name="GPMU_SP_PWR_CLK_STATUS">
+		<bitfield name="PWR_ON" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa88d" name="GPMU_RBCCU_PWR_CLK_STATUS">
+		<bitfield name="PWR_ON" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa891" name="GPMU_PWR_COL_STAGGER_DELAY"/>
+	<reg32 offset="0xa892" name="GPMU_PWR_COL_INTER_FRAME_CTRL"/>
+	<reg32 offset="0xa893" name="GPMU_PWR_COL_INTER_FRAME_HYST"/>
+	<reg32 offset="0xa894" name="GPMU_PWR_COL_BINNING_CTRL"/>
+	<reg32 offset="0xa8a3" name="GPMU_CLOCK_THROTTLE_CTRL"/>
+	<reg32 offset="0xa8a8" name="GPMU_THROTTLE_UNMASK_FORCE_CTRL"/>
+	<reg32 offset="0xa8c1" name="GPMU_WFI_CONFIG"/>
+	<reg32 offset="0xa8d6" name="GPMU_RBBM_INTR_INFO"/>
+	<reg32 offset="0xa8d8" name="GPMU_CM3_SYSRESET"/>
+	<reg32 offset="0xa8e0" name="GPMU_GENERAL_0"/>
+	<reg32 offset="0xa8e1" name="GPMU_GENERAL_1"/>
+	<reg32 offset="0xac00" name="GPMU_TEMP_SENSOR_ID"/>
+	<reg32 offset="0xac01" name="GPMU_TEMP_SENSOR_CONFIG"/>
+	<reg32 offset="0xac02" name="GPMU_TEMP_VAL"/>
+	<reg32 offset="0xac03" name="GPMU_DELTA_TEMP_THRESHOLD"/>
+	<reg32 offset="0xac05" name="GPMU_TEMP_THRESHOLD_INTR_STATUS"/>
+	<reg32 offset="0xac06" name="GPMU_TEMP_THRESHOLD_INTR_EN_MASK"/>
+	<reg32 offset="0xac40" name="GPMU_LEAKAGE_TEMP_COEFF_0_1"/>
+	<reg32 offset="0xac41" name="GPMU_LEAKAGE_TEMP_COEFF_2_3"/>
+	<reg32 offset="0xac42" name="GPMU_LEAKAGE_VTG_COEFF_0_1"/>
+	<reg32 offset="0xac43" name="GPMU_LEAKAGE_VTG_COEFF_2_3"/>
+	<reg32 offset="0xac46" name="GPMU_BASE_LEAKAGE"/>
+	<reg32 offset="0xac60" name="GPMU_GPMU_VOLTAGE"/>
+	<reg32 offset="0xac61" name="GPMU_GPMU_VOLTAGE_INTR_STATUS"/>
+	<reg32 offset="0xac62" name="GPMU_GPMU_VOLTAGE_INTR_EN_MASK"/>
+	<reg32 offset="0xac80" name="GPMU_GPMU_PWR_THRESHOLD"/>
+	<reg32 offset="0xacc4" name="GPMU_GPMU_LLM_GLM_SLEEP_CTRL"/>
+	<reg32 offset="0xacc5" name="GPMU_GPMU_LLM_GLM_SLEEP_STATUS"/>
+	<reg32 offset="0xb80c" name="GDPM_CONFIG1"/>
+	<reg32 offset="0xb80d" name="GDPM_CONFIG2"/>
+	<reg32 offset="0xb80f" name="GDPM_INT_EN"/>
+	<reg32 offset="0xb811" name="GDPM_INT_MASK"/>
+	<reg32 offset="0xb9a0" name="GPMU_BEC_ENABLE"/>
+	<reg32 offset="0xc41a" name="GPU_CS_SENSOR_GENERAL_STATUS"/>
+	<reg32 offset="0xc41d" name="GPU_CS_AMP_CALIBRATION_STATUS1_0"/>
+	<reg32 offset="0xc41f" name="GPU_CS_AMP_CALIBRATION_STATUS1_2"/>
+	<reg32 offset="0xc421" name="GPU_CS_AMP_CALIBRATION_STATUS1_4"/>
+	<reg32 offset="0xc520" name="GPU_CS_ENABLE_REG"/>
+	<reg32 offset="0xc557" name="GPU_CS_AMP_CALIBRATION_CONTROL1"/>
+
+
+	<reg32 offset="0xe000" name="GRAS_CL_CNTL">
+		<bitfield name="ZERO_GB_SCALE_Z" pos="6" type="boolean"/>
+	</reg32>
+	<bitset name="a5xx_gras_xs_cl_cntl" inline="yes">
+		<bitfield name="CLIP_MASK" low="0" high="7"/>
+		<bitfield name="CULL_MASK" low="8" high="15"/>
+	</bitset>
+	<reg32 offset="0xe001" name="GRAS_VS_CL_CNTL" type="a5xx_gras_xs_cl_cntl"/>
+	<reg32 offset="0xe004" name="UNKNOWN_E004"/> <!-- always 00000000? -->
+	<reg32 offset="0xe005" name="GRAS_CNTL">
+		<!-- see also RB_RENDER_CONTROL0 -->
+		<bitfield name="IJ_PERSP_PIXEL" pos="0" type="boolean"/>
+		<bitfield name="IJ_PERSP_CENTROID" pos="1" type="boolean"/>
+		<bitfield name="IJ_PERSP_SAMPLE" pos="2" type="boolean"/>
+		<bitfield name="IJ_LINEAR_PIXEL" pos="3" type="boolean"/>
+		<bitfield name="IJ_LINEAR_CENTROID" pos="4" type="boolean"/>
+		<bitfield name="IJ_LINEAR_SAMPLE" pos="5" type="boolean"/>
+		<bitfield name="COORD_MASK" low="6" high="9" type="hex"/>
+	</reg32>
+	<reg32 offset="0xe006" name="GRAS_CL_GUARDBAND_CLIP_ADJ">
+		<bitfield name="HORZ" low="0" high="9" type="uint"/>
+		<bitfield name="VERT" low="10" high="19" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe010" name="GRAS_CL_VPORT_XOFFSET_0" type="float"/>
+	<reg32 offset="0xe011" name="GRAS_CL_VPORT_XSCALE_0" type="float"/>
+	<reg32 offset="0xe012" name="GRAS_CL_VPORT_YOFFSET_0" type="float"/>
+	<reg32 offset="0xe013" name="GRAS_CL_VPORT_YSCALE_0" type="float"/>
+	<reg32 offset="0xe014" name="GRAS_CL_VPORT_ZOFFSET_0" type="float"/>
+	<reg32 offset="0xe015" name="GRAS_CL_VPORT_ZSCALE_0" type="float"/>
+	<reg32 offset="0xe090" name="GRAS_SU_CNTL">
+		<bitfield name="CULL_FRONT" pos="0" type="boolean"/>
+		<bitfield name="CULL_BACK" pos="1" type="boolean"/>
+		<bitfield name="FRONT_CW" pos="2" type="boolean"/>
+		<bitfield name="LINEHALFWIDTH" low="3" high="10" radix="2" type="fixed"/>
+		<bitfield name="POLY_OFFSET" pos="11" type="boolean"/>
+		<bitfield name="LINE_MODE" pos="13" type="a5xx_line_mode"/>
+		<!-- probably LINEHALFWIDTH is the same as a4xx.. -->
+	</reg32>
+	<reg32 offset="0xe091" name="GRAS_SU_POINT_MINMAX">
+		<bitfield name="MIN" low="0" high="15" type="ufixed" radix="4"/>
+		<bitfield name="MAX" low="16" high="31" type="ufixed" radix="4"/>
+	</reg32>
+	<reg32 offset="0xe092" name="GRAS_SU_POINT_SIZE" type="fixed" radix="4"/>
+	<reg32 offset="0xe093" name="GRAS_SU_LAYERED"/>
+	<reg32 offset="0xe094" name="GRAS_SU_DEPTH_PLANE_CNTL">
+		<bitfield name="FRAG_WRITES_Z" pos="0" type="boolean"/>
+		<bitfield name="UNK1" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe095" name="GRAS_SU_POLY_OFFSET_SCALE" type="float"/>
+	<reg32 offset="0xe096" name="GRAS_SU_POLY_OFFSET_OFFSET" type="float"/>
+	<reg32 offset="0xe097" name="GRAS_SU_POLY_OFFSET_OFFSET_CLAMP" type="float"/>
+	<!-- duplicates RB_DEPTH_INFO0: -->
+	<reg32 offset="0xe098" name="GRAS_SU_DEPTH_BUFFER_INFO">
+		<bitfield name="DEPTH_FORMAT" low="0" high="2" type="a5xx_depth_format"/>
+	</reg32>
+	<reg32 offset="0xe099" name="GRAS_SU_CONSERVATIVE_RAS_CNTL"/> <!-- always 00000000? -->
+	<!--
+	guessing about window/screen/extent, I think they can in the end be
+	used interchangeably?
+	 -->
+	<reg32 offset="0xe0a0" name="GRAS_SC_CNTL">
+		<bitfield name="BINNING_PASS" pos="0" type="boolean"/>
+		<bitfield name="SAMPLES_PASSED" pos="15" type="boolean"/>
+	</reg32>
+	<!-- note, 0x4 for binning pass when frag writes z?? -->
+	<reg32 offset="0xe0a1" name="GRAS_SC_BIN_CNTL"/> <!-- always 00000000? -->
+	<reg32 offset="0xe0a2" name="GRAS_SC_RAS_MSAA_CNTL">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+	</reg32>
+	<reg32 offset="0xe0a3" name="GRAS_SC_DEST_MSAA_CNTL">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="MSAA_DISABLE" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe0a4" name="GRAS_SC_SCREEN_SCISSOR_CNTL"/> <!-- always 00000000? -->
+	<reg32 offset="0xe0aa" name="GRAS_SC_SCREEN_SCISSOR_TL_0" type="adreno_reg_xy"/>
+	<reg32 offset="0xe0ab" name="GRAS_SC_SCREEN_SCISSOR_BR_0" type="adreno_reg_xy"/>
+	<reg32 offset="0xe0ca" name="GRAS_SC_VIEWPORT_SCISSOR_TL_0" type="adreno_reg_xy"/>
+	<reg32 offset="0xe0cb" name="GRAS_SC_VIEWPORT_SCISSOR_BR_0" type="adreno_reg_xy"/>
+	<reg32 offset="0xe0ea" name="GRAS_SC_WINDOW_SCISSOR_TL" type="adreno_reg_xy"/>
+	<reg32 offset="0xe0eb" name="GRAS_SC_WINDOW_SCISSOR_BR" type="adreno_reg_xy"/>
+
+	<doc>
+		LRZ:  (Low Resolution Z ??)
+		----
+
+		I think it serves two functions, early discard of primitives in binning
+		pass without needing full resolution depth buffer, and also functions as
+		a depth-prepass, used during the GMEM draws to discard primitives that
+		would not be visible due to later draws.
+
+		The LRZ buffer always seems to be z16 format, regardless of actual
+		depth buffer format.
+
+		Note that LRZ write should be disabled when blend/stencil/etc is enabled,
+		since the occluded primitive can still contribute to final color value
+		of a fragment.
+
+		Only enabled for GL_LESS/GL_LEQUAL/GL_GREATER/GL_GEQUAL?
+	</doc>
+	<reg32 offset="0xe100" name="GRAS_LRZ_CNTL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<doc>LRZ write also disabled for blend/etc.</doc>
+		<bitfield name="LRZ_WRITE" pos="1" type="boolean"/>
+		<doc>update MAX instead of MIN value, ie. GL_GREATER/GL_GEQUAL</doc>
+		<bitfield name="GREATER" pos="2" type="boolean"/>
+		<!--
+		b3 set sometimes, when depth buffer isn't cleared.. maybe it
+		invalidates the LRZ buffer?  (Or just the covered positions?
+		 -->
+	</reg32>
+	<reg32 offset="0xe101" name="GRAS_LRZ_BUFFER_BASE_LO"/>
+	<reg32 offset="0xe102" name="GRAS_LRZ_BUFFER_BASE_HI"/>
+	<!--
+	lzr pitch is depth pitch (in pixels) / 8 (aligned to 32)..
+	 -->
+	<doc>
+		Pitch is depth width (in pixels) / 8 (aligned to 32).  Height
+		is also divided by 8 (ie. covers 8x8 pixels)
+	</doc>
+	<reg32 offset="0xe103" name="GRAS_LRZ_BUFFER_PITCH" shr="5" type="uint"/>
+	<reg32 offset="0xe104" name="GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_LO"/>
+	<reg32 offset="0xe105" name="GRAS_LRZ_FAST_CLEAR_BUFFER_BASE_HI"/>
+
+	<reg32 offset="0xe140" name="RB_CNTL">
+		<bitfield name="WIDTH" low="0" high="7" shr="5" type="uint"/>
+		<bitfield name="HEIGHT" low="9" high="16" shr="5" type="uint"/>
+		<bitfield name="BYPASS" pos="17" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe141" name="RB_RENDER_CNTL">
+<!--
+bit 3 set for normal draws
+bit 7 for RECTLIST (clear) when z32s8 (used for clear of depth32?  not set
+	for z32 with no stencil, but maybe in that case separate z/s not used?
+	see mrt-fbo-* zs=2)
+ -->
+		<bitfield name="BINNING_PASS" pos="0" type="boolean"/>
+		<bitfield name="SAMPLES_PASSED" pos="6" type="boolean"/>
+		<bitfield name="DISABLE_COLOR_PIPE" pos="7" type="boolean"/>
+		<!-- why everything twice?? maybe read vs write? -->
+		<!-- UBWC flag buffer enabled for depth/stencil: -->
+		<bitfield name="FLAG_DEPTH" pos="14" type="boolean"/>
+		<bitfield name="FLAG_DEPTH2" pos="15" type="boolean"/>
+		<!-- bitmask of MRTs using UBWC flag buffer: -->
+		<bitfield name="FLAG_MRTS" low="16" high="23"/>
+		<bitfield name="FLAG_MRTS2" low="24" high="31"/>
+	</reg32>
+	<reg32 offset="0xe142" name="RB_RAS_MSAA_CNTL">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+	</reg32>
+	<reg32 offset="0xe143" name="RB_DEST_MSAA_CNTL">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="MSAA_DISABLE" pos="2" type="boolean"/>
+	</reg32>
+	<!--
+	note: maybe not actually called RB_RENDER_CONTROLn (since RB_RENDER_CNTL
+	name comes from kernel and is probably right)
+	 -->
+	<reg32 offset="0xe144" name="RB_RENDER_CONTROL0">
+		<!-- see also GRAS_CNTL -->
+		<bitfield name="IJ_PERSP_PIXEL" pos="0" type="boolean"/>
+		<bitfield name="IJ_PERSP_CENTROID" pos="1" type="boolean"/>
+		<bitfield name="IJ_PERSP_SAMPLE" pos="2" type="boolean"/>
+		<bitfield name="IJ_LINEAR_PIXEL" pos="3" type="boolean"/>
+		<bitfield name="IJ_LINEAR_CENTROID" pos="4" type="boolean"/>
+		<bitfield name="IJ_LINEAR_SAMPLE" pos="5" type="boolean"/>
+		<bitfield name="COORD_MASK" low="6" high="9" type="hex"/>
+	</reg32>
+	<reg32 offset="0xe145" name="RB_RENDER_CONTROL1">
+		<bitfield name="SAMPLEMASK" pos="0" type="boolean"/>
+		<bitfield name="FACENESS" pos="1" type="boolean"/>
+		<bitfield name="SAMPLEID" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe146" name="RB_FS_OUTPUT_CNTL">
+		<!-- bit0 set except for binning pass.. -->
+		<bitfield name="MRT" low="0" high="3" type="uint"/>
+		<bitfield name="FRAG_WRITES_Z" pos="5" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe147" name="RB_RENDER_COMPONENTS">
+		<bitfield name="RT0" low="0" high="3"/>
+		<bitfield name="RT1" low="4" high="7"/>
+		<bitfield name="RT2" low="8" high="11"/>
+		<bitfield name="RT3" low="12" high="15"/>
+		<bitfield name="RT4" low="16" high="19"/>
+		<bitfield name="RT5" low="20" high="23"/>
+		<bitfield name="RT6" low="24" high="27"/>
+		<bitfield name="RT7" low="28" high="31"/>
+	</reg32>
+	<array offset="0xe150" name="RB_MRT" stride="7" length="8">
+		<reg32 offset="0x0" name="CONTROL">
+			<bitfield name="BLEND" pos="0" type="boolean"/>
+			<bitfield name="BLEND2" pos="1" type="boolean"/>
+			<bitfield name="ROP_ENABLE" pos="2" type="boolean"/>
+			<bitfield name="ROP_CODE" low="3" high="6" type="a3xx_rop_code"/>
+			<bitfield name="COMPONENT_ENABLE" low="7" high="10" type="hex"/>
+		</reg32>
+		<reg32 offset="0x1" name="BLEND_CONTROL">
+			<bitfield name="RGB_SRC_FACTOR" low="0" high="4" type="adreno_rb_blend_factor"/>
+			<bitfield name="RGB_BLEND_OPCODE" low="5" high="7" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="RGB_DEST_FACTOR" low="8" high="12" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_SRC_FACTOR" low="16" high="20" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_BLEND_OPCODE" low="21" high="23" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="ALPHA_DEST_FACTOR" low="24" high="28" type="adreno_rb_blend_factor"/>
+		</reg32>
+		<reg32 offset="0x2" name="BUF_INFO">
+			<!--
+			not sure if there is a separate COLOR_SWAP field like on a3xx/a4xx,
+			or if it is inherent in the format.  Will have to play with bits
+			once we get things working and see what happens.  If it is a diff
+			field, it doesn't seem to have the same encoding as a3xx/a4xx.
+			 -->
+			<bitfield name="COLOR_FORMAT" low="0" high="7" type="a5xx_color_fmt"/>
+			<bitfield name="COLOR_TILE_MODE" low="8" high="9" type="a5xx_tile_mode"/>
+			<bitfield name="DITHER_MODE" low="11" high="12" type="adreno_rb_dither_mode"/>
+			<bitfield name="COLOR_SWAP" low="13" high="14" type="a3xx_color_swap"/>
+			<bitfield name="COLOR_SRGB" pos="15" type="boolean"/>
+		</reg32>
+		<!--
+		at least in gmem, things seem to be aligned to pitch of 64..
+		maybe an artifact of tiled format used in gmem?
+		 -->
+		<reg32 offset="0x3" name="PITCH" shr="6" type="uint"/>
+		<reg32 offset="0x4" name="ARRAY_PITCH" shr="6" type="uint"/>
+		<reg32 offset="0x5" name="BASE_LO"/>
+		<reg32 offset="0x6" name="BASE_HI"/>
+	</array>
+	<reg32 offset="0xe1a0" name="RB_BLEND_RED">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0xe1a1" name="RB_BLEND_RED_F32" type="float"/>
+	<reg32 offset="0xe1a2" name="RB_BLEND_GREEN">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0xe1a3" name="RB_BLEND_GREEN_F32" type="float"/>
+	<reg32 offset="0xe1a4" name="RB_BLEND_BLUE">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0xe1a5" name="RB_BLEND_BLUE_F32" type="float"/>
+	<reg32 offset="0xe1a6" name="RB_BLEND_ALPHA">
+		<bitfield name="UINT" low="0" high="7" type="hex"/>
+		<bitfield name="SINT" low="8" high="15" type="hex"/>
+		<bitfield name="FLOAT" low="16" high="31" type="float"/>
+	</reg32>
+	<reg32 offset="0xe1a7" name="RB_BLEND_ALPHA_F32" type="float"/>
+	<reg32 offset="0xe1a8" name="RB_ALPHA_CONTROL">
+		<bitfield name="ALPHA_REF" low="0" high="7" type="hex"/>
+		<bitfield name="ALPHA_TEST" pos="8" type="boolean"/>
+		<bitfield name="ALPHA_TEST_FUNC" low="9" high="11" type="adreno_compare_func"/>
+	</reg32>
+	<reg32 offset="0xe1a9" name="RB_BLEND_CNTL">
+		<!-- per-mrt enable bit -->
+		<bitfield name="ENABLE_BLEND" low="0" high="7"/>
+		<bitfield name="INDEPENDENT_BLEND" pos="8" type="boolean"/>
+		<bitfield name="ALPHA_TO_COVERAGE" pos="10" type="boolean"/>
+		<!-- a guess? -->
+		<bitfield name="SAMPLE_MASK" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="0xe1b0" name="RB_DEPTH_PLANE_CNTL">
+		<bitfield name="FRAG_WRITES_Z" pos="0" type="boolean"/>
+		<bitfield name="UNK1" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe1b1" name="RB_DEPTH_CNTL">
+		<bitfield name="Z_TEST_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="Z_WRITE_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="ZFUNC" low="2" high="4" type="adreno_compare_func"/>
+		<doc>Z_READ_ENABLE bit is set for zfunc other than GL_ALWAYS or GL_NEVER</doc>
+		<bitfield name="Z_READ_ENABLE" pos="6" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe1b2" name="RB_DEPTH_BUFFER_INFO">
+		<bitfield name="DEPTH_FORMAT" low="0" high="2" type="a5xx_depth_format"/>
+	</reg32>
+	<reg32 offset="0xe1b3" name="RB_DEPTH_BUFFER_BASE_LO"/>
+	<reg32 offset="0xe1b4" name="RB_DEPTH_BUFFER_BASE_HI"/>
+	<reg32 offset="0xe1b5" name="RB_DEPTH_BUFFER_PITCH" shr="6" type="uint">
+		<doc>stride of depth/stencil buffer</doc>
+	</reg32>
+	<reg32 offset="0xe1b6" name="RB_DEPTH_BUFFER_ARRAY_PITCH" shr="6" type="uint">
+		<doc>size of layer</doc>
+	</reg32>
+	<reg32 offset="0xe1c0" name="RB_STENCIL_CONTROL">
+		<bitfield name="STENCIL_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="STENCIL_ENABLE_BF" pos="1" type="boolean"/>
+		<!--
+			set for stencil operations that require read from stencil
+			buffer, but not for example for stencil clear (which does
+			not require read).. so guessing this is analogous to
+			READ_DEST_ENABLE for color buffer..
+		 -->
+		<bitfield name="STENCIL_READ" pos="2" type="boolean"/>
+		<bitfield name="FUNC" low="8" high="10" type="adreno_compare_func"/>
+		<bitfield name="FAIL" low="11" high="13" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS" low="14" high="16" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL" low="17" high="19" type="adreno_stencil_op"/>
+		<bitfield name="FUNC_BF" low="20" high="22" type="adreno_compare_func"/>
+		<bitfield name="FAIL_BF" low="23" high="25" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS_BF" low="26" high="28" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL_BF" low="29" high="31" type="adreno_stencil_op"/>
+	</reg32>
+	<reg32 offset="0xe1c1" name="RB_STENCIL_INFO">
+		<bitfield name="SEPARATE_STENCIL" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe1c2" name="RB_STENCIL_BASE_LO"/>
+	<reg32 offset="0xe1c3" name="RB_STENCIL_BASE_HI"/>
+	<reg32 offset="0xe1c4" name="RB_STENCIL_PITCH" shr="6" type="uint"/>
+	<reg32 offset="0xe1c5" name="RB_STENCIL_ARRAY_PITCH" shr="6" type="uint"/>
+	<reg32 offset="0xe1c6" name="RB_STENCILREFMASK" type="adreno_rb_stencilrefmask"/>
+	<reg32 offset="0xe1c7" name="RB_STENCILREFMASK_BF" type="adreno_rb_stencilrefmask"/>
+	<reg32 offset="0xe1d0" name="RB_WINDOW_OFFSET" type="adreno_reg_xy"/>
+	<reg32 offset="0xe1d1" name="RB_SAMPLE_COUNT_CONTROL">
+		<bitfield name="COPY" pos="1" type="boolean"/>
+	</reg32>
+
+	<doc>
+		Blits:
+		------
+
+		Blits are triggered by CP_EVENT_WRITE:BLIT, compared to previous
+		generations where they shared most of the gl pipeline and were
+		triggered by CP_DRAW_INDX*
+
+		For gmem->mem blob uses RB_BLIT_CNTL.BUF to specify src of
+		blit (ie MRTn, ZS, etc) and RB_BLIT_DST_LO/HI for destination
+		gpuaddr.  The gmem offset is taken from RB_MRT[n].BASE_LO/HI
+
+		For mem->gmem blob uses just MRT0 or ZS and RB_BLIT_DST_LO/HI
+		for the GMEM offset, and gpuaddr from RB_MRT[0].BASE_LO/HI
+		(I suppose this is just to avoid trashing RB_MRT[1..7]??)
+	</doc>
+	<reg32 offset="0xe210" name="RB_BLIT_CNTL">
+		<bitfield name="BUF" low="0" high="3" type="a5xx_blit_buf"/>
+	</reg32>
+	<reg32 offset="0xe211" name="RB_RESOLVE_CNTL_1" type="adreno_reg_xy"/>
+	<reg32 offset="0xe212" name="RB_RESOLVE_CNTL_2" type="adreno_reg_xy"/>
+	<reg32 offset="0xe213" name="RB_RESOLVE_CNTL_3">
+		<!-- if b0 set, output is in TILE5_3 format -->
+		<bitfield name="TILED" pos="0" type="boolean"/>
+	<!--
+		0xe213:
+		        0x0 mem->gmem
+		        0xf gmem->mem with flag buffer (color)
+		        0x4 gmem->mem without flag buffer (color)
+		        0x7 BYPASS mode flag buffer result (ie. on readpix)
+		            also for gmem->mem preserving tiling
+	-->
+	</reg32>
+	<reg32 offset="0xe214" name="RB_BLIT_DST_LO"/>
+	<reg32 offset="0xe215" name="RB_BLIT_DST_HI"/>
+	<reg32 offset="0xe216" name="RB_BLIT_DST_PITCH" shr="6" type="uint"/>
+	<!-- array-pitch is size of layer -->
+	<reg32 offset="0xe217" name="RB_BLIT_DST_ARRAY_PITCH" shr="6" type="uint"/>
+	<reg32 offset="0xe218" name="RB_CLEAR_COLOR_DW0"/>
+	<reg32 offset="0xe219" name="RB_CLEAR_COLOR_DW1"/>
+	<reg32 offset="0xe21a" name="RB_CLEAR_COLOR_DW2"/>
+	<reg32 offset="0xe21b" name="RB_CLEAR_COLOR_DW3"/>
+	<reg32 offset="0xe21c" name="RB_CLEAR_CNTL">
+		<bitfield name="FAST_CLEAR" pos="1" type="boolean"/>
+		<bitfield name="MSAA_RESOLVE" pos="2" type="boolean"/>
+		<doc>
+			For MASK, if RB_BLIT_CNTL.BUF=BLIT_ZS:
+				1 - depth
+				2 - stencil
+				3 - depth+stencil
+			if RB_BLIT_CNTL.BUF=BLIT_MRTn
+				then probably a component mask, I always see 0xf
+		</doc>
+		<bitfield name="MASK" low="4" high="7"/>
+	</reg32>
+
+	<doc>
+		Buffer Metadata (flag buffers):
+		-------------------------------
+
+		Blob seems to stick some metadata at the front of the buffer,
+		both z/s and MRT.  I think this is same as UBWC (bandwidth
+		compression) metadata that mdp 1.7 and later supports.  See
+		1d3fae5698ce5358caab87a15383b690941697e8 in downstream kernel.
+		UBWC seems to stand for "universal bandwidth compression".
+
+		Before glReadPixels() it does a pair of BYPASS blits (at least
+		if metadata is used) presumably to resolve metadata.
+
+		NOTES: see: getUBwcBlockSize(), getUBwcMetaBufferSize() at
+		https://android.googlesource.com/platform/hardware/qcom/display/+/android-6.0.1_r40/msm8994/libgralloc/alloc_controller.cpp
+		(note that bpp in bytes, not bits, so really cpp)
+
+		Example Layout 2d w/ mipmap levels:
+
+			100x2000, ifmt=GL_RG, fmt=GL_RG16F, type=GL_FLOAT, meta=64x512@0x8000 (7x500)
+				base=c072e000, offset=16384, size=1703936
+
+				color		flags
+			0	c073a000	c0732000	- level 0 flags is address
+			1	c0838000	c0834000	  programmed in texture state
+			2	c0879000	c0877000
+			3	c089a000	c0899000
+			4	c08ab000	c08aa000
+			5	c08b4000	c08b3000
+			6	c08b9000	c08b8000
+			7	c08bc000	c08bb000
+			8	c08be000	c08bd000
+			9	c08c0000	c08bf000
+			10	c08c2000	c08c1000
+
+		ARRAY_PITCH is the combined size of all the levels plus flags,
+		so 0xc08c3000 - 0xc0732000 = 0x00191000 (1642496); each level
+		takes up a minimum of 2 pages (since color and flags parts are
+		each page aligned.
+
+			{ TILE_MODE = TILE5_3 | SWIZ_X = A5XX_TEX_X | SWIZ_Y = A5XX_TEX_Y | SWIZ_Z = A5XX_TEX_ZERO | SWIZ_W = A5XX_TEX_ONE | MIPLVLS = 0 | FMT = TFMT5_16_16_FLOAT | SWAP = WZYX }
+			{ WIDTH = 100 | HEIGHT = 2000 }
+			{ FETCHSIZE = TFETCH5_4_BYTE | PITCH = 512 | TYPE = A5XX_TEX_2D }
+			{ ARRAY_PITCH = 1642496 | 0x18800000 }  - NOTE c2dc always has 0x18800000 but
+			{ BASE_LO = 0xc0732000 }                  this varies for blob gles driver..
+			{ BASE_HI = 0 | DEPTH = 1 }               not sure what it is
+
+
+	</doc>
+	<reg32 offset="0xe240" name="RB_DEPTH_FLAG_BUFFER_BASE_LO"/>
+	<reg32 offset="0xe241" name="RB_DEPTH_FLAG_BUFFER_BASE_HI"/>
+	<reg32 offset="0xe242" name="RB_DEPTH_FLAG_BUFFER_PITCH">
+	</reg32>
+	<array offset="0xe243" name="RB_MRT_FLAG_BUFFER" stride="4" length="8">
+		<reg32 offset="0" name="ADDR_LO"/>
+		<reg32 offset="1" name="ADDR_HI"/>
+		<reg32 offset="2" name="PITCH" shr="6" type="uint"/>
+		<!-- array-pitch is size of layer -->
+		<reg32 offset="3" name="ARRAY_PITCH" shr="6" type="uint"/>
+	</array>
+	<reg32 offset="0xe263" name="RB_BLIT_FLAG_DST_LO"/>
+	<reg32 offset="0xe264" name="RB_BLIT_FLAG_DST_HI"/>
+	<reg32 offset="0xe265" name="RB_BLIT_FLAG_DST_PITCH" shr="6" type="uint"/>
+	<!-- array-pitch is size of layer -->
+	<reg32 offset="0xe266" name="RB_BLIT_FLAG_DST_ARRAY_PITCH" shr="6" type="uint"/>
+
+	<reg32 offset="0xe267" name="RB_SAMPLE_COUNT_ADDR_LO"/>
+	<reg32 offset="0xe268" name="RB_SAMPLE_COUNT_ADDR_HI"/>
+
+	<reg32 offset="0xe280" name="VPC_CNTL_0">
+		<doc>
+			num of varyings plus four for gl_Position (plus one if gl_PointSize)
+			plus # of transform-feedback (streamout) varyings if using the
+			hw streamout (rather than stg instructions in shader)
+		</doc>
+		<bitfield name="STRIDE_IN_VPC" low="0" high="6" type="uint"/>
+		<bitfield name="VARYING" pos="11" type="boolean"/>
+	</reg32>
+	<array offset="0xe282" name="VPC_VARYING_INTERP" stride="1" length="8">
+		<reg32 offset="0x0" name="MODE"/>
+	</array>
+	<array offset="0xe28a" name="VPC_VARYING_PS_REPL" stride="1" length="8">
+		<reg32 offset="0x0" name="MODE"/>
+	</array>
+	<reg32 offset="0xe292" name="UNKNOWN_E292"/>
+	<reg32 offset="0xe293" name="UNKNOWN_E293"/>
+	<array offset="0xe294" name="VPC_VAR" stride="1" length="4">
+		<!-- one bit per varying component: -->
+		<reg32 offset="0" name="DISABLE"/>
+	</array>
+	<reg32 offset="0xe298" name="VPC_GS_SIV_CNTL"/>
+	<reg32 offset="0xe29a" name="VPC_CLIP_CNTL">
+		<bitfield name="CLIP_MASK" low="0" high="7" type="uint"/>
+		<!-- there can be up to 8 total clip/cull distance outputs,
+		     but apparenly VPC can only deal with vec4, so when there are
+		     more than 4 outputs a second location needs to be programmed
+		-->
+		<bitfield name="CLIP_DIST_03_LOC" low="8" high="15" type="uint"/>
+		<bitfield name="CLIP_DIST_47_LOC" low="16" high="23" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0xe29d" name="VPC_PACK">
+		<bitfield name="NUMNONPOSVAR" low="0" high="7" type="uint"/>
+		<!--
+		This seems to be the OUTLOC for the psize output.  It could possibly
+		be the max-OUTLOC position, but it is only set when VS writes psize
+		(and blob always puts psize at highest OUTLOC)
+		 -->
+		<bitfield name="PSIZELOC" low="8" high="15" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe2a0" name="VPC_FS_PRIMITIVEID_CNTL"/>
+
+	<doc>
+		Stream-Out:
+		-----------
+
+		VPC_SO[0..3] registers setup details about streamout buffers, and
+		number of components to write to each.
+
+		VPC_SO_PROG provides the mapping between output varyings and the SO
+		buffers.  It is written multiple times (via a CP_CONTEXT_REG_BUNCH
+		packet, not sure if that matters), each write can handle up to two
+		components of stream-out output.  Order matches up to OUTLOC,
+		including padding.  So, if outputting first 3 varyings:
+
+			SP_VS_OUT[0].REG: { A_REGID = r0.w | A_COMPMASK = 0xf | B_REGID = r0.x | B_COMPMASK = 0x7 }
+			SP_VS_OUT[0x1].REG: { A_REGID = r1.w | A_COMPMASK = 0x3 | B_REGID = r2.y | B_COMPMASK = 0xf }
+			SP_VS_VPC_DST[0].REG: { OUTLOC0 = 0 | OUTLOC1 = 4 | OUTLOC2 = 8 | OUTLOC3 = 12 }
+
+		Then:
+
+			VPC_SO_PROG: { A_BUF = 0 | A_OFF = 0 | A_EN | A_BUF = 0 | B_OFF = 4 | B_EN }
+			VPC_SO_PROG: { A_BUF = 0 | A_OFF = 8 | A_EN | A_BUF = 0 | B_OFF = 12 | B_EN }
+			VPC_SO_PROG: { A_BUF = 2 | A_OFF = 0 | A_EN | A_BUF = 2 | B_OFF = 4 | B_EN }
+			VPC_SO_PROG: { A_BUF = 2 | A_OFF = 8 | A_EN | A_BUF = 0 | B_OFF = 0 }
+			VPC_SO_PROG: { A_BUF = 1 | A_OFF = 0 | A_EN | A_BUF = 1 | B_OFF = 4 | B_EN }
+
+		Note that varying order is OUTLOC0, OUTLOC2, OUTLOC1, and note
+		the padding between OUTLOC1 and OUTLOC2.
+
+		The BUF bitfield indicates which of the four streamout buffers
+		to write into at the specified offset.
+
+		The VPC_SO[n].FLUSH_BASE_LO/HI is used for hw to write back next
+		offset which gets loaded back into VPC_SO[n].BUFFER_OFFSET via a
+		CP_MEM_TO_REG.  Probably can be ignored until we have GS/etc, at
+		which point we can't calculate the offset on the CPU.
+	</doc>
+	<reg32 offset="0xe2a1" name="VPC_SO_BUF_CNTL">
+		<bitfield name="BUF0" pos="0" type="boolean"/>
+		<bitfield name="BUF1" pos="3" type="boolean"/>
+		<bitfield name="BUF2" pos="6" type="boolean"/>
+		<bitfield name="BUF3" pos="9" type="boolean"/>
+		<bitfield name="ENABLE" pos="15" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe2a2" name="VPC_SO_OVERRIDE">
+		<bitfield name="SO_DISABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe2a3" name="VPC_SO_CNTL">
+		<!-- always 0x10000 when SO enabled.. -->
+		<bitfield name="ENABLE" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe2a4" name="VPC_SO_PROG">
+		<bitfield name="A_BUF" low="0" high="1" type="uint"/>
+		<bitfield name="A_OFF" low="2" high="10" shr="2" type="uint"/>
+		<bitfield name="A_EN" pos="11" type="boolean"/>
+		<bitfield name="B_BUF" low="12" high="13" type="uint"/>
+		<bitfield name="B_OFF" low="14" high="22" shr="2" type="uint"/>
+		<bitfield name="B_EN" pos="23" type="boolean"/>
+	</reg32>
+	<array offset="0xe2a7" name="VPC_SO" stride="7" length="4">
+		<reg32 offset="0" name="BUFFER_BASE_LO"/>
+		<reg32 offset="1" name="BUFFER_BASE_HI"/>
+		<reg32 offset="2" name="BUFFER_SIZE"/>
+		<reg32 offset="3" name="NCOMP"/>  <!-- component count -->
+		<reg32 offset="4" name="BUFFER_OFFSET"/>
+		<reg32 offset="5" name="FLUSH_BASE_LO"/>
+		<reg32 offset="6" name="FLUSH_BASE_HI"/>
+	</array>
+
+	<reg32 offset="0xe384" name="PC_PRIMITIVE_CNTL">
+		<!-- # of varyings plus four for gl_Position (plus one if gl_PointSize) -->
+		<bitfield name="STRIDE_IN_VPC" low="0" high="6" type="uint"/>
+		<bitfield name="PRIMITIVE_RESTART" pos="8" type="boolean"/>
+		<bitfield name="COUNT_PRIMITIVES" pos="9" type="boolean"/><!-- enabled when gl_PrimitiveIDIn is used -->
+		<bitfield name="PROVOKING_VTX_LAST" pos="10" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe385" name="PC_PRIM_VTX_CNTL">
+		<bitfield name="PSIZE" pos="11" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe388" name="PC_RASTER_CNTL">
+		<bitfield name="POLYMODE_FRONT_PTYPE" low="0" high="2" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="POLYMODE_BACK_PTYPE" low="3" high="5" type="adreno_pa_su_sc_draw"/>
+		<bitfield name="POLYMODE_ENABLE" pos="6" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe389" name="PC_CLIP_CNTL">
+		<bitfield name="CLIP_MASK" low="0" high="7"/>
+	</reg32>
+	<reg32 offset="0xe38c" name="PC_RESTART_INDEX"/>
+	<reg32 offset="0xe38d" name="PC_GS_LAYERED"/>
+	<reg32 offset="0xe38e" name="PC_GS_PARAM">
+		<bitfield name="MAX_VERTICES" low="0" high="9" type="uint"/><!-- vertices - 1 -->
+		<bitfield name="INVOCATIONS" low="11" high="15" type="uint"/><!-- invoc - 1 -->
+		<bitfield name="PRIMTYPE" low="23" high="24" type="adreno_pa_su_sc_draw"/>
+	</reg32>
+	<reg32 offset="0xe38f" name="PC_HS_PARAM">
+		<bitfield name="VERTICES_OUT" low="0" high="5" type="uint"/>
+		<bitfield name="SPACING" low="21" high="22" type="a4xx_tess_spacing"/>
+		<bitfield name="CW" pos="23" type="boolean"/>
+		<bitfield name="CONNECTED" pos="24" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe3b0" name="PC_POWER_CNTL"/>
+
+	<reg32 offset="0xe400" name="VFD_CONTROL_0">
+		<bitfield name="VTXCNT" low="0" high="5" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe401" name="VFD_CONTROL_1">
+		<bitfield name="REGID4VTX" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="REGID4INST" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="REGID4PRIMID" low="16" high="23" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xe402" name="VFD_CONTROL_2">
+		<bitfield name="REGID_PATCHID" low="0" high="7" type="a3xx_regid"/><!-- same as VFD_CONTROL_3.REGID_PATCHID? -->
+	</reg32>
+	<reg32 offset="0xe403" name="VFD_CONTROL_3">
+		<bitfield name="REGID_PATCHID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="REGID_TESSX" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="REGID_TESSY" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xe404" name="VFD_CONTROL_4">
+	</reg32>
+	<reg32 offset="0xe405" name="VFD_CONTROL_5">
+		<!-- b0 set if gl_PrimitiveID used in fs ?? -->
+	</reg32>
+	<reg32 offset="0xe408" name="VFD_INDEX_OFFSET"/>
+	<reg32 offset="0xe409" name="VFD_INSTANCE_START_OFFSET"/>
+	<array offset="0xe40a" name="VFD_FETCH" stride="4" length="32">
+		<reg32 offset="0x0" name="BASE_LO"/>
+		<reg32 offset="0x1" name="BASE_HI"/>
+		<reg32 offset="0x2" name="SIZE" type="uint"/>
+		<reg32 offset="0x3" name="STRIDE" type="uint"/>
+	</array>
+	<array offset="0xe48a" name="VFD_DECODE" stride="2" length="32">
+		<reg32 offset="0x0" name="INSTR">
+			<!-- IDX appears to index into VFD_FETCH[] -->
+			<bitfield name="IDX" low="0" high="4" type="uint"/>
+			<bitfield name="INSTANCED" pos="17" type="boolean"/>
+			<bitfield name="FORMAT" low="20" high="27" type="a5xx_vtx_fmt"/>
+			<bitfield name="SWAP" low="28" high="29" type="a3xx_color_swap"/>
+			<bitfield name="UNK30" pos="30" type="boolean"/>
+			<bitfield name="FLOAT" pos="31" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x1" name="STEP_RATE"/> <!-- ??? -->
+	</array>
+	<array offset="0xe4ca" name="VFD_DEST_CNTL" stride="1" length="32">
+		<reg32 offset="0x0" name="INSTR">
+			<bitfield name="WRITEMASK" low="0" high="3" type="hex"/>
+			<bitfield name="REGID" low="4" high="11" type="a3xx_regid"/>
+		</reg32>
+	</array>
+	<reg32 offset="0xe4f0" name="VFD_POWER_CNTL"/>
+
+	<!-- 0x0 for compute, 0x10 for 3d? -->
+	<reg32 offset="0xe580" name="SP_SP_CNTL"/>
+
+	<bitset name="a5xx_xs_config" inline="yes">
+		<bitfield name="ENABLED" pos="0" type="boolean"/>
+		<bitfield name="CONSTOBJECTOFFSET" low="1" high="7" type="uint"/>
+		<bitfield name="SHADEROBJOFFSET" low="8" high="14" type="uint"/>
+	</bitset>
+	<bitset name="a5xx_xs_cntl" inline="yes">
+		<bitfield name="SSBO_ENABLE" pos="0" type="boolean"/>
+		<!--
+		no idea high bit.. could be this is amount of on-chip memory used
+		rather than total size?
+		 -->
+		<bitfield name="INSTRLEN" low="1" high="31" type="uint"/>
+	</bitset>
+	<bitset name="a5xx_sp_xs_ctrl_reg0" inline="yes">
+		<!-- bit1 almost always set -->
+		<!-- set for "buffer mode" (ie. shader small enough to fit internally) -->
+		<bitfield name="BUFFER" pos="2" type="boolean"/>
+		<!-- 24 or more (full size) GPRS and blob uses TWO_QUADS instead of FOUR_QUADS -->
+		<bitfield name="THREADSIZE" pos="3" type="a3xx_threadsize"/>
+		<bitfield name="HALFREGFOOTPRINT" low="4" high="9" type="uint"/>
+		<bitfield name="FULLREGFOOTPRINT" low="10" high="15" type="uint"/>
+		<bitfield name="VARYING" pos="16" type="boolean"/>
+		<bitfield name="PIXLODENABLE" pos="20" type="boolean"/>
+		<!-- seems to be nesting level for flow control:.. -->
+		<bitfield name="BRANCHSTACK" low="25" high="31" type="uint"/>
+	</bitset>
+	<!-- assuming things appear in same relative order as a4xx: -->
+	<!-- duplicated exactly w/ corresponding HLSQ_ regs starting at 0xe78b.. -->
+	<reg32 offset="0xe584" name="SP_VS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe585" name="SP_FS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe586" name="SP_HS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe587" name="SP_DS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe588" name="SP_GS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe589" name="SP_CS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe58a" name="SP_VS_CONFIG_MAX_CONST"/>
+	<reg32 offset="0xe58b" name="SP_FS_CONFIG_MAX_CONST"/>
+	<reg32 offset="0xe590" name="SP_VS_CTRL_REG0" type="a5xx_sp_xs_ctrl_reg0"/>
+	<reg32 offset="0xe592" name="SP_PRIMITIVE_CNTL">
+		<!-- # of VS outputs including pos/psize -->
+		<bitfield name="VSOUT" low="0" high="4" type="uint"/>
+	</reg32>
+	<array offset="0xe593" name="SP_VS_OUT" stride="1" length="16">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="A_COMPMASK" low="8" high="11" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="23" type="a3xx_regid"/>
+			<bitfield name="B_COMPMASK" low="24" high="27" type="hex"/>
+		</reg32>
+	</array>
+	<!--
+	Starting with a5xx, position/psize outputs from shader end up in the
+	SP_VS_OUT map, with highest OUTLOCn position.  (Generally they are
+	the last entries too, except when gl_PointCoord is used, blob inserts
+	an extra varying after, but with a lower OUTLOC position.  If present,
+	psize is last, preceded by position.
+	 -->
+	<array offset="0xe5a3" name="SP_VS_VPC_DST" stride="1" length="8">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="OUTLOC0" low="0" high="7" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="15" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="23" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="31" type="uint"/>
+		</reg32>
+	</array>
+	<reg32 offset="0xe5ab" name="UNKNOWN_E5AB"/>
+	<reg32 offset="0xe5ac" name="SP_VS_OBJ_START_LO"/>
+	<reg32 offset="0xe5ad" name="SP_VS_OBJ_START_HI"/>
+
+	<bitset name="a5xx_sp_xs_pvt_mem_param" inline="yes">
+		<bitfield name="MEMSIZEPERITEM" low="0" high="7" shr="9">
+			<doc>The size of memory that ldp/stp can address.</doc>
+		</bitfield>
+		<bitfield name="HWSTACKOFFSET" low="8" high="23" shr="11" type="uint"/>
+		<bitfield name="HWSTACKSIZEPERTHREAD" low="24" high="31">
+                        <doc>Guessing that this is the same as a3xx/a6xx.</doc>
+		</bitfield>
+	</bitset>
+
+	<bitset name="a5xx_sp_xs_pvt_mem_size" inline="yes">
+		<bitfield name="TOTALPVTMEMSIZE" low="0" high="17" shr="12"/>
+	</bitset>
+
+	<reg32 offset="0xe5ae" name="SP_VS_PVT_MEM_PARAM" type="a5xx_sp_xs_pvt_mem_param"/>
+	<reg64 offset="0xe5af" name="SP_VS_PVT_MEM_ADDR" type="waddress" align="32"/>
+	<reg32 offset="0xe5b1" name="SP_VS_PVT_MEM_SIZE" type="a5xx_sp_xs_pvt_mem_size"/>
+	<reg32 offset="0xe5c0" name="SP_FS_CTRL_REG0" type="a5xx_sp_xs_ctrl_reg0"/>
+	<reg32 offset="0xe5c2" name="UNKNOWN_E5C2"/>
+	<reg32 offset="0xe5c3" name="SP_FS_OBJ_START_LO"/>
+	<reg32 offset="0xe5c4" name="SP_FS_OBJ_START_HI"/>
+	<reg32 offset="0xe5c5" name="SP_FS_PVT_MEM_PARAM" type="a5xx_sp_xs_pvt_mem_param"/>
+	<reg64 offset="0xe5c6" name="SP_FS_PVT_MEM_ADDR" type="waddress" align="32"/>
+	<reg32 offset="0xe5c8" name="SP_FS_PVT_MEM_SIZE" type="a5xx_sp_xs_pvt_mem_size"/>
+	<reg32 offset="0xe5c9" name="SP_BLEND_CNTL">
+		<!-- per-mrt enable bit -->
+		<bitfield name="ENABLE_BLEND" low="0" high="7"/>
+		<bitfield name="UNK8" pos="8" type="boolean"/>
+		<bitfield name="ALPHA_TO_COVERAGE" pos="10" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xe5ca" name="SP_FS_OUTPUT_CNTL">
+		<bitfield name="MRT" low="0" high="3" type="uint"/>
+		<bitfield name="DEPTH_REGID" low="5" high="12" type="a3xx_regid"/>
+		<bitfield name="SAMPLEMASK_REGID" low="13" high="20" type="a3xx_regid"/>
+	</reg32>
+	<array offset="0xe5cb" name="SP_FS_OUTPUT" stride="1" length="8">
+		<doc>per MRT</doc>
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="HALF_PRECISION" pos="8" type="boolean"/>
+		</reg32>
+	</array>
+	<array offset="0xe5d3" name="SP_FS_MRT" stride="1" length="8">
+		<reg32 offset="0" name="REG">
+			<bitfield name="COLOR_FORMAT" low="0" high="7" type="a5xx_color_fmt"/>
+			<bitfield name="COLOR_SINT" pos="8" type="boolean"/>
+			<bitfield name="COLOR_UINT" pos="9" type="boolean"/>
+			<bitfield name="COLOR_SRGB" pos="10" type="boolean"/>
+		</reg32>
+	</array>
+	<!--
+	e5db/e5dc seems to look related to some optimization to do sample from
+	texture using varying value directly before shader thread starts?  I
+	guess that could optimize common simple frag shaders..
+	 -->
+	<reg32 offset="0xe5db" name="UNKNOWN_E5DB"/>
+	<reg32 offset="0xe5f0" name="SP_CS_CTRL_REG0" type="a5xx_sp_xs_ctrl_reg0"/>
+	<reg32 offset="0xe5f2" name="UNKNOWN_E5F2"/>
+	<reg32 offset="0xe5f3" name="SP_CS_OBJ_START_LO"/>
+	<reg32 offset="0xe5f4" name="SP_CS_OBJ_START_HI"/>
+	<reg32 offset="0xe5f5" name="SP_CS_PVT_MEM_PARAM" type="a5xx_sp_xs_pvt_mem_param"/>
+	<reg64 offset="0xe5f6" name="SP_CS_PVT_MEM_ADDR" type="waddress" align="32"/>
+	<reg32 offset="0xe5f8" name="SP_CS_PVT_MEM_SIZE" type="a5xx_sp_xs_pvt_mem_size"/>
+
+	<!-- e5f9 something compute related.. seems to change when HLSQ_CS_CNTL_1 changes -->
+
+	<reg32 offset="0xe600" name="SP_HS_CTRL_REG0" type="a5xx_sp_xs_ctrl_reg0"/>
+	<reg32 offset="0xe602" name="UNKNOWN_E602"/>
+	<reg32 offset="0xe603" name="SP_HS_OBJ_START_LO"/>
+	<reg32 offset="0xe604" name="SP_HS_OBJ_START_HI"/>
+	<reg32 offset="0xe605" name="SP_HS_PVT_MEM_PARAM" type="a5xx_sp_xs_pvt_mem_param"/>
+	<reg64 offset="0xe606" name="SP_HS_PVT_MEM_ADDR" type="waddress" align="32"/>
+	<reg32 offset="0xe608" name="SP_HS_PVT_MEM_SIZE" type="a5xx_sp_xs_pvt_mem_size"/>
+	<reg32 offset="0xe610" name="SP_DS_CTRL_REG0" type="a5xx_sp_xs_ctrl_reg0"/>
+	<reg32 offset="0xe62b" name="UNKNOWN_E62B"/>
+	<reg32 offset="0xe62c" name="SP_DS_OBJ_START_LO"/>
+	<reg32 offset="0xe62d" name="SP_DS_OBJ_START_HI"/>
+	<reg32 offset="0xe62e" name="SP_DS_PVT_MEM_PARAM" type="a5xx_sp_xs_pvt_mem_param"/>
+	<reg64 offset="0xe62f" name="SP_DS_PVT_MEM_ADDR" type="waddress" align="32"/>
+	<reg32 offset="0xe631" name="SP_DS_PVT_MEM_SIZE" type="a5xx_sp_xs_pvt_mem_size"/>
+	<reg32 offset="0xe640" name="SP_GS_CTRL_REG0" type="a5xx_sp_xs_ctrl_reg0"/>
+	<reg32 offset="0xe65b" name="UNKNOWN_E65B"/>
+	<reg32 offset="0xe65c" name="SP_GS_OBJ_START_LO"/>
+	<reg32 offset="0xe65d" name="SP_GS_OBJ_START_HI"/>
+	<reg32 offset="0xe65e" name="SP_GS_PVT_MEM_PARAM" type="a5xx_sp_xs_pvt_mem_param"/>
+	<reg64 offset="0xe65f" name="SP_GS_PVT_MEM_ADDR" type="waddress" align="32"/>
+	<reg32 offset="0xe661" name="SP_GS_PVT_MEM_SIZE" type="a5xx_sp_xs_pvt_mem_size"/>
+
+	<reg32 offset="0xe704" name="TPL1_TP_RAS_MSAA_CNTL">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+	</reg32>
+	<reg32 offset="0xe705" name="TPL1_TP_DEST_MSAA_CNTL">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="MSAA_DISABLE" pos="2" type="boolean"/>
+	</reg32>
+	<!-- either blob is doing it wrong, or this is not per-stage anymore: -->
+	<reg32 offset="0xe706" name="TPL1_TP_BORDER_COLOR_BASE_ADDR_LO"/>
+	<reg32 offset="0xe707" name="TPL1_TP_BORDER_COLOR_BASE_ADDR_HI"/>
+
+	<!--
+	so these have the same info that is normally in the CP_LOAD_STATE
+	packets.. not sure if they are normally written by pm4/me or if the
+	CP_LOAD_STATE mechanism is deprecated?
+	 -->
+	<reg32 offset="0xe700" name="TPL1_VS_TEX_COUNT" type="uint"/>
+	<reg32 offset="0xe701" name="TPL1_HS_TEX_COUNT" type="uint"/>
+	<reg32 offset="0xe702" name="TPL1_DS_TEX_COUNT" type="uint"/>
+	<reg32 offset="0xe703" name="TPL1_GS_TEX_COUNT" type="uint"/>
+
+	<reg32 offset="0xe722" name="TPL1_VS_TEX_SAMP_LO"/>
+	<reg32 offset="0xe723" name="TPL1_VS_TEX_SAMP_HI"/>
+	<reg32 offset="0xe724" name="TPL1_HS_TEX_SAMP_LO"/>
+	<reg32 offset="0xe725" name="TPL1_HS_TEX_SAMP_HI"/>
+	<reg32 offset="0xe726" name="TPL1_DS_TEX_SAMP_LO"/>
+	<reg32 offset="0xe727" name="TPL1_DS_TEX_SAMP_HI"/>
+	<reg32 offset="0xe728" name="TPL1_GS_TEX_SAMP_LO"/>
+	<reg32 offset="0xe729" name="TPL1_GS_TEX_SAMP_HI"/>
+
+	<reg32 offset="0xe72a" name="TPL1_VS_TEX_CONST_LO"/>
+	<reg32 offset="0xe72b" name="TPL1_VS_TEX_CONST_HI"/>
+	<reg32 offset="0xe72c" name="TPL1_HS_TEX_CONST_LO"/>
+	<reg32 offset="0xe72d" name="TPL1_HS_TEX_CONST_HI"/>
+	<reg32 offset="0xe72e" name="TPL1_DS_TEX_CONST_LO"/>
+	<reg32 offset="0xe72f" name="TPL1_DS_TEX_CONST_HI"/>
+	<reg32 offset="0xe730" name="TPL1_GS_TEX_CONST_LO"/>
+	<reg32 offset="0xe731" name="TPL1_GS_TEX_CONST_HI"/>
+
+	<reg32 offset="0xe750" name="TPL1_FS_TEX_COUNT" type="uint"/>
+	<reg32 offset="0xe751" name="TPL1_CS_TEX_COUNT" type="uint"/>
+
+	<reg32 offset="0xe75a" name="TPL1_FS_TEX_SAMP_LO"/>
+	<reg32 offset="0xe75b" name="TPL1_FS_TEX_SAMP_HI"/>
+	<reg32 offset="0xe75c" name="TPL1_CS_TEX_SAMP_LO"/>
+	<reg32 offset="0xe75d" name="TPL1_CS_TEX_SAMP_HI"/>
+	<reg32 offset="0xe75e" name="TPL1_FS_TEX_CONST_LO"/>
+	<reg32 offset="0xe75f" name="TPL1_FS_TEX_CONST_HI"/>
+	<reg32 offset="0xe760" name="TPL1_CS_TEX_CONST_LO"/>
+	<reg32 offset="0xe761" name="TPL1_CS_TEX_CONST_HI"/>
+
+	<reg32 offset="0xe764" name="TPL1_TP_FS_ROTATION_CNTL"/>
+
+	<reg32 offset="0xe784" name="HLSQ_CONTROL_0_REG">
+		<!-- 24 or more (full size) GPRS and blob uses TWO_QUADS instead of FOUR_QUADS -->
+		<bitfield name="FSTHREADSIZE" pos="0" type="a3xx_threadsize"/>
+		<bitfield name="CSTHREADSIZE" pos="2" type="a3xx_threadsize"/>
+	</reg32>
+	<reg32 offset="0xe785" name="HLSQ_CONTROL_1_REG">
+		<!-- I guess.. not set exactly same as a4xx, but similar: -->
+		<bitfield name="PRIMALLOCTHRESHOLD" low="0" high="5" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe786" name="HLSQ_CONTROL_2_REG">
+		<bitfield name="FACEREGID" low="0" high="7" type="a3xx_regid"/>
+		<!-- SAMPLEID is loaded into a half-precision register: -->
+		<bitfield name="SAMPLEID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="SAMPLEMASK" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="CENTERRHW" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xe787" name="HLSQ_CONTROL_3_REG">
+		<!-- register loaded with position (bary.f) -->
+		<bitfield name="IJ_PERSP_PIXEL" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_PIXEL" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="IJ_PERSP_CENTROID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_CENTROID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xe788" name="HLSQ_CONTROL_4_REG">
+		<bitfield name="IJ_PERSP_SAMPLE" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_SAMPLE" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="XYCOORDREGID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="ZWCOORDREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<!--
+	0x020fffff for normal draws, 0x1f00000 for compute.. maybe what state
+	is enabled?  We could probably try disabling different bits and see
+	what breaks to figure out which is what:
+	 -->
+	<reg32 offset="0xe78a" name="HLSQ_UPDATE_CNTL"/>
+	<reg32 offset="0xe78b" name="HLSQ_VS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe78c" name="HLSQ_FS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe78d" name="HLSQ_HS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe78e" name="HLSQ_DS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe78f" name="HLSQ_GS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe790" name="HLSQ_CS_CONFIG" type="a5xx_xs_config"/>
+	<reg32 offset="0xe791" name="HLSQ_VS_CNTL" type="a5xx_xs_cntl"/>
+	<reg32 offset="0xe792" name="HLSQ_FS_CNTL" type="a5xx_xs_cntl"/>
+	<reg32 offset="0xe793" name="HLSQ_HS_CNTL" type="a5xx_xs_cntl"/>
+	<reg32 offset="0xe794" name="HLSQ_DS_CNTL" type="a5xx_xs_cntl"/>
+	<reg32 offset="0xe795" name="HLSQ_GS_CNTL" type="a5xx_xs_cntl"/>
+	<reg32 offset="0xe796" name="HLSQ_CS_CNTL" type="a5xx_xs_cntl"/>
+	<reg32 offset="0xe7b9" name="HLSQ_CS_KERNEL_GROUP_X"/>
+	<reg32 offset="0xe7ba" name="HLSQ_CS_KERNEL_GROUP_Y"/>
+	<reg32 offset="0xe7bb" name="HLSQ_CS_KERNEL_GROUP_Z"/>
+	<reg32 offset="0xe7b0" name="HLSQ_CS_NDRANGE_0">
+		<bitfield name="KERNELDIM" low="0" high="1" type="uint"/>
+		<!-- localsize is value minus one: -->
+		<bitfield name="LOCALSIZEX" low="2" high="11" type="uint"/>
+		<bitfield name="LOCALSIZEY" low="12" high="21" type="uint"/>
+		<bitfield name="LOCALSIZEZ" low="22" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe7b1" name="HLSQ_CS_NDRANGE_1">
+		<bitfield name="GLOBALSIZE_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe7b2" name="HLSQ_CS_NDRANGE_2">
+		<bitfield name="GLOBALOFF_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe7b3" name="HLSQ_CS_NDRANGE_3">
+		<bitfield name="GLOBALSIZE_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe7b4" name="HLSQ_CS_NDRANGE_4">
+		<bitfield name="GLOBALOFF_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe7b5" name="HLSQ_CS_NDRANGE_5">
+		<bitfield name="GLOBALSIZE_Z" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe7b6" name="HLSQ_CS_NDRANGE_6">
+		<bitfield name="GLOBALOFF_Z" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xe7b7" name="HLSQ_CS_CNTL_0">
+		<bitfield name="WGIDCONSTID" low="0" high="7" type="a3xx_regid"/>
+		<!-- possibly one of these is KERNELDIMCONSTID? -->
+		<!--
+		UNK0 appears to be NUMWGCONSTID.. but only works in certain
+		cases?  Blob doesn't appear to use it, but instead emits
+		these via const (uniform).  Which requires some shenanigans
+		for indirect draws when the offset is not strongly aligned
+		enough to use as EXT_SRC_ADDR in CP_LOAD_STATE
+		 -->
+		<bitfield name="UNK0" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="UNK1" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="LOCALIDREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xe7b8" name="HLSQ_CS_CNTL_1"/>
+	<reg32 offset="0xe7c0" name="UNKNOWN_E7C0"/>
+	<reg32 offset="0xe7c3" name="HLSQ_VS_CONSTLEN" type="uint"/>
+	<reg32 offset="0xe7c4" name="HLSQ_VS_INSTRLEN" type="uint"/>
+	<reg32 offset="0xe7c5" name="UNKNOWN_E7C5"/>
+	<reg32 offset="0xe7c8" name="HLSQ_HS_CONSTLEN" type="uint"/>
+	<reg32 offset="0xe7c9" name="HLSQ_HS_INSTRLEN" type="uint"/>
+	<reg32 offset="0xe7ca" name="UNKNOWN_E7CA"/>
+	<reg32 offset="0xe7cd" name="HLSQ_DS_CONSTLEN" type="uint"/>
+	<reg32 offset="0xe7ce" name="HLSQ_DS_INSTRLEN" type="uint"/>
+	<reg32 offset="0xe7cf" name="UNKNOWN_E7CF"/>
+	<reg32 offset="0xe7d2" name="HLSQ_GS_CONSTLEN" type="uint"/>
+	<reg32 offset="0xe7d3" name="HLSQ_GS_INSTRLEN" type="uint"/>
+	<reg32 offset="0xe7d4" name="UNKNOWN_E7D4"/>
+	<reg32 offset="0xe7d7" name="HLSQ_FS_CONSTLEN" type="uint"/>
+	<reg32 offset="0xe7d8" name="HLSQ_FS_INSTRLEN" type="uint"/>
+	<reg32 offset="0xe7d9" name="UNKNOWN_E7D9"/>
+	<reg32 offset="0xe7dc" name="HLSQ_CS_CONSTLEN" type="uint"/>
+	<reg32 offset="0xe7dd" name="HLSQ_CS_INSTRLEN" type="uint"/>
+
+	<!--
+		Separate blit/2d or dma engine?  Seems to get used sometimes for
+		texture uploads, where a4xx blob would use normal draws.  Used
+		in render-mode 0x5..
+
+		Note seems mostly to be used for small blits, large blits seem
+		to use the CP_EVENT_WRITE:BLIT style of doing things.  See
+		cubemap-0003 (40x40) vs cubemap-0004 (256x256).
+
+		see cube-0000, cubemap-(1..3 but not 4+), quad-textured-10..17
+
+		Other nearby registers are probably color formats, etc.  The
+		blit coords are in CP packet.  Play more w/ glTexSubImage2D()
+		to work it out.
+
+		Separate this into a different domain??  Would that help to
+		restrict which registers we dump based on mode?
+
+		regs 0x2000 to 0x2004 (plus all-zero regs 0x2005-0x2009) look
+		like 2nd source for blending?  Used in mipmap generation.. but
+		maybe layout is a bit different.  (Possibly used for reading
+		src via sampler, to enable scaling??)  0x2040 also used in this
+		case.
+	 -->
+	<reg32 offset="0x2100" name="RB_2D_BLIT_CNTL"/>  <!-- same as 0x2180 -->
+	<reg32 offset="0x2101" name="RB_2D_SRC_SOLID_DW0"/>
+	<reg32 offset="0x2102" name="RB_2D_SRC_SOLID_DW1"/>
+	<reg32 offset="0x2103" name="RB_2D_SRC_SOLID_DW2"/>
+	<reg32 offset="0x2104" name="RB_2D_SRC_SOLID_DW3"/>
+
+	<bitset name="a5xx_2d_surf_info" inline="yes">
+		<bitfield name="COLOR_FORMAT" low="0" high="7" type="a5xx_color_fmt"/>
+		<bitfield name="TILE_MODE" low="8" high="9" type="a5xx_tile_mode"/>
+		<bitfield name="COLOR_SWAP" low="10" high="11" type="a3xx_color_swap"/>
+		<!-- b12 seems to be set when UBWC "FLAGS" buffer enabled -->
+		<bitfield name="FLAGS" pos="12" type="boolean"/>
+		<bitfield name="SRGB" pos="13" type="boolean"/>
+	</bitset>
+
+	<reg32 offset="0x2107" name="RB_2D_SRC_INFO" type="a5xx_2d_surf_info"/>
+	<reg32 offset="0x2108" name="RB_2D_SRC_LO"/>
+	<reg32 offset="0x2109" name="RB_2D_SRC_HI"/>
+	<reg32 offset="0x210a" name="RB_2D_SRC_SIZE">
+		<bitfield name="PITCH" low="0" high="15" shr="6" type="uint"/>
+		<bitfield name="ARRAY_PITCH" low="16" high="31" shr="6" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x2110" name="RB_2D_DST_INFO" type="a5xx_2d_surf_info"/>
+	<reg32 offset="0x2111" name="RB_2D_DST_LO"/>
+	<reg32 offset="0x2112" name="RB_2D_DST_HI"/>
+	<reg32 offset="0x2113" name="RB_2D_DST_SIZE">
+		<bitfield name="PITCH" low="0" high="15" shr="6" type="uint"/>
+		<bitfield name="ARRAY_PITCH" low="16" high="31" shr="6" type="uint"/>
+	</reg32>
+	<reg32 offset="0x2140" name="RB_2D_SRC_FLAGS_LO"/>
+	<reg32 offset="0x2141" name="RB_2D_SRC_FLAGS_HI"/>
+        <reg32 offset="0x2142" name="RB_2D_SRC_FLAGS_PITCH" shr="6" type="uint"/>
+	<reg32 offset="0x2143" name="RB_2D_DST_FLAGS_LO"/>
+	<reg32 offset="0x2144" name="RB_2D_DST_FLAGS_HI"/>
+        <reg32 offset="0x2145" name="RB_2D_DST_FLAGS_PITCH" shr="6" type="uint"/>
+	<reg32 offset="0x2180" name="GRAS_2D_BLIT_CNTL"/> <!-- same as 0x2100 -->
+	<!-- looks same as 0x2107: -->
+	<reg32 offset="0x2181" name="GRAS_2D_SRC_INFO" type="a5xx_2d_surf_info"/>
+	<!-- looks same as 0x2110: -->
+	<reg32 offset="0x2182" name="GRAS_2D_DST_INFO" type="a5xx_2d_surf_info"/>
+<!--
+0x2100 and 0x2180 look like same thing (RB and GRAS versions)..
+   0x86000000 for copy, 0x00000000 for fill?
+
+0x2184 0x9 for copy, 0x1 for blit (maybe bitmask of enabled src/dst???)
+ -->
+	<reg32 offset="0x2184" name="UNKNOWN_2184"/>
+</domain>
+
+<domain name="A5XX_TEX_SAMP" width="32">
+	<doc>Texture sampler dwords</doc>
+	<enum name="a5xx_tex_filter"> <!-- same as a4xx? -->
+		<value name="A5XX_TEX_NEAREST" value="0"/>
+		<value name="A5XX_TEX_LINEAR" value="1"/>
+		<value name="A5XX_TEX_ANISO" value="2"/>
+	</enum>
+	<enum name="a5xx_tex_clamp"> <!-- same as a4xx? -->
+		<value name="A5XX_TEX_REPEAT" value="0"/>
+		<value name="A5XX_TEX_CLAMP_TO_EDGE" value="1"/>
+		<value name="A5XX_TEX_MIRROR_REPEAT" value="2"/>
+		<value name="A5XX_TEX_CLAMP_TO_BORDER" value="3"/>
+		<value name="A5XX_TEX_MIRROR_CLAMP" value="4"/>
+	</enum>
+	<enum name="a5xx_tex_aniso"> <!-- same as a4xx? -->
+		<value name="A5XX_TEX_ANISO_1" value="0"/>
+		<value name="A5XX_TEX_ANISO_2" value="1"/>
+		<value name="A5XX_TEX_ANISO_4" value="2"/>
+		<value name="A5XX_TEX_ANISO_8" value="3"/>
+		<value name="A5XX_TEX_ANISO_16" value="4"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="MIPFILTER_LINEAR_NEAR" pos="0" type="boolean"/>
+		<bitfield name="XY_MAG" low="1" high="2" type="a5xx_tex_filter"/>
+		<bitfield name="XY_MIN" low="3" high="4" type="a5xx_tex_filter"/>
+		<bitfield name="WRAP_S" low="5" high="7" type="a5xx_tex_clamp"/>
+		<bitfield name="WRAP_T" low="8" high="10" type="a5xx_tex_clamp"/>
+		<bitfield name="WRAP_R" low="11" high="13" type="a5xx_tex_clamp"/>
+		<bitfield name="ANISO" low="14" high="16" type="a5xx_tex_aniso"/>
+		<bitfield name="LOD_BIAS" low="19" high="31" type="fixed" radix="8"/><!-- no idea how many bits for real -->
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="COMPARE_FUNC" low="1" high="3" type="adreno_compare_func"/>
+		<bitfield name="CUBEMAPSEAMLESSFILTOFF" pos="4" type="boolean"/>
+		<bitfield name="UNNORM_COORDS" pos="5" type="boolean"/>
+		<bitfield name="MIPFILTER_LINEAR_FAR" pos="6" type="boolean"/>
+		<bitfield name="MAX_LOD" low="8" high="19" type="ufixed" radix="8"/>
+		<bitfield name="MIN_LOD" low="20" high="31" type="ufixed" radix="8"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<!--
+		offset into border-color buffer?  Blob always uses 0x80 for FS state
+		if both VS and FS have border-color.
+Seems like when both VS and FS have bcolor, one starts 0x300 after other..
+and 0x80 in TEX_SAMP.2 ..  blob doesn't seem to be able to cope w/ multiple
+different border-color states per texture..  Looks something like:
+0000: 3f000000 00000000 00000000 3f800000 00008000 ffff0000 00004000 7fff0000
+0020: 00003800 3c000000 80100010 0000f008 ff000080 7f000040 c0000200 00800000
+0040: 00003800 3c000000 00000000 00000000 00000000 00000000 00000000 00000000
+*
+0300: 3f800000 3f800000 3f800000 3f800000 ffffffff ffffffff 7fff7fff 7fff7fff
+0320: 3c003c00 3c003c00 ffffffff 0000ffff ffffffff 7f7f7f7f ffffffff 00ffffff
+0340: 3c003c00 3c003c00 00000000 00000000 00000000 00000000 00000000 00000000
+
+		 -->
+		<bitfield name="BCOLOR_OFFSET" low="7" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3"/>
+</domain>
+
+<domain name="A5XX_TEX_CONST" width="32">
+	<doc>Texture constant dwords</doc>
+	<enum name="a5xx_tex_swiz"> <!-- same as a4xx? -->
+		<value name="A5XX_TEX_X" value="0"/>
+		<value name="A5XX_TEX_Y" value="1"/>
+		<value name="A5XX_TEX_Z" value="2"/>
+		<value name="A5XX_TEX_W" value="3"/>
+		<value name="A5XX_TEX_ZERO" value="4"/>
+		<value name="A5XX_TEX_ONE" value="5"/>
+	</enum>
+	<enum name="a5xx_tex_type"> <!-- same as a4xx? -->
+		<value name="A5XX_TEX_1D" value="0"/>
+		<value name="A5XX_TEX_2D" value="1"/>
+		<value name="A5XX_TEX_CUBE" value="2"/>
+		<value name="A5XX_TEX_3D" value="3"/>
+		<value name="A5XX_TEX_BUFFER" value="4"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="TILE_MODE" low="0" high="1" type="a5xx_tile_mode"/>
+		<bitfield name="SRGB" pos="2" type="boolean"/>
+		<bitfield name="SWIZ_X" low="4" high="6" type="a5xx_tex_swiz"/>
+		<bitfield name="SWIZ_Y" low="7" high="9" type="a5xx_tex_swiz"/>
+		<bitfield name="SWIZ_Z" low="10" high="12" type="a5xx_tex_swiz"/>
+		<bitfield name="SWIZ_W" low="13" high="15" type="a5xx_tex_swiz"/>
+		<bitfield name="MIPLVLS" low="16" high="19" type="uint"/>
+		<bitfield name="SAMPLES" low="20" high="21" type="a3xx_msaa_samples"/>
+		<bitfield name="FMT" low="22" high="29" type="a5xx_tex_fmt"/>
+		<bitfield name="SWAP" low="30" high="31" type="a3xx_color_swap"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="WIDTH" low="0" high="14" type="uint"/>
+		<bitfield name="HEIGHT" low="15" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<!--
+		b4 and b31 set for buffer/ssbo case, in which case low 15 bits
+		of size encoded in WIDTH, and high 15 bits encoded in HEIGHT
+
+		b31 is probably the 'BUFFER' bit.. it is the one that changes
+		behavior of texture in dEQP-GLES31.functional.texture.texture_buffer.render.as_fragment_texture.buffer_size_131071
+		 -->
+		<bitfield name="BUFFER" pos="4" type="boolean"/>
+		<!-- minimum pitch (for mipmap levels): log2(pitchalign / 64) -->
+		<bitfield name="PITCHALIGN" low="0" high="3" type="uint"/>
+		<doc>Pitch in bytes (so actually stride)</doc>
+		<bitfield name="PITCH" low="7" high="28" type="uint"/>
+		<bitfield name="TYPE" low="29" high="31" type="a5xx_tex_type"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<!--
+		ARRAY_PITCH is basically LAYERSZ for the first mipmap level, and
+		for 3d textures (laid out mipmap level first) MIN_LAYERSZ is the
+		layer size at the point that it stops being reduced moving to
+		higher (smaller) mipmap levels
+		 -->
+		<bitfield name="ARRAY_PITCH" low="0" high="13" shr="12" type="uint"/>
+		<bitfield name="MIN_LAYERSZ" low="23" high="26" shr="12"/>
+		<!--
+		by default levels with w < 16 are linear
+		TILE_ALL makes all levels have tiling
+		seems required when using UBWC, since all levels have UBWC (can possibly be disabled?)
+		 -->
+		<bitfield name="TILE_ALL" pos="27" type="boolean"/>
+		<bitfield name="FLAG" pos="28" type="boolean"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="BASE_LO" low="5" high="31" shr="5"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="BASE_HI" low="0" high="16"/>
+		<bitfield name="DEPTH" low="17" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="6" name="6"/>
+	<reg32 offset="7" name="7"/>
+	<reg32 offset="8" name="8"/>
+	<reg32 offset="9" name="9"/>
+	<reg32 offset="10" name="10"/>
+	<reg32 offset="11" name="11"/>
+</domain>
+
+<!--
+Note the "SSBO" state blocks are actually used for both images and SSBOs,
+naming is just because I r/e'd SSBOs first.  I should probably come up
+with a better name.
+-->
+<domain name="A5XX_SSBO_0" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="BASE_LO" low="5" high="31" shr="5"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<!-- no BASE_HI here?  Maybe this is only used for 32b mode? -->
+		<doc>Pitch in bytes (so actually stride)</doc>
+		<bitfield name="PITCH" low="0" high="21" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="ARRAY_PITCH" low="12" high="25" shr="12" type="uint"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<!-- bytes per pixel: -->
+		<bitfield name="CPP" low="0" high="5" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="A5XX_SSBO_1" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="FMT" low="8" high="15" type="a5xx_tex_fmt"/>
+		<bitfield name="WIDTH" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="HEIGHT" low="0" high="15" type="uint"/>
+		<bitfield name="DEPTH" low="16" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="A5XX_SSBO_2" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="BASE_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="BASE_HI" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="A5XX_UBO" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="BASE_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="BASE_HI" low="0" high="16"/>
+		<!-- size probably in high bits -->
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/adreno/a6xx.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/adreno/a6xx.xml
@@ -0,0 +1,6092 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="adreno/adreno_common.xml"/>
+<import file="adreno/adreno_pm4.xml"/>
+
+<!--
+Each register that is actually being used by driver should have "usage" defined,
+currently there are following usages:
+- "cmd" - the register is used outside of renderpass and blits,
+		roughly corresponds to registers used in ib1 for Freedreno
+- "rp_blit" - the register is used inside renderpass or blits
+		(ib2 for Freedreno)
+
+It is expected that register with "cmd" usage may be written into only at
+the start of the command buffer (ib1), while "rp_blit" usage indicates that register
+is either overwritten by renderpass/blit (ib2) or not used if not overwritten
+by a particular renderpass/blit.
+-->
+
+<!-- these might be same as a5xx -->
+<enum name="a6xx_tile_mode">
+	<value name="TILE6_LINEAR" value="0"/>
+	<value name="TILE6_2" value="2"/>
+	<value name="TILE6_3" value="3"/>
+</enum>
+
+<enum name="a6xx_format">
+	<value value="0x02" name="FMT6_A8_UNORM"/>
+	<value value="0x03" name="FMT6_8_UNORM"/>
+	<value value="0x04" name="FMT6_8_SNORM"/>
+	<value value="0x05" name="FMT6_8_UINT"/>
+	<value value="0x06" name="FMT6_8_SINT"/>
+
+	<value value="0x08" name="FMT6_4_4_4_4_UNORM"/>
+	<value value="0x0a" name="FMT6_5_5_5_1_UNORM"/>
+	<value value="0x0c" name="FMT6_1_5_5_5_UNORM"/> <!-- read only -->
+	<value value="0x0e" name="FMT6_5_6_5_UNORM"/>
+
+	<value value="0x0f" name="FMT6_8_8_UNORM"/>
+	<value value="0x10" name="FMT6_8_8_SNORM"/>
+	<value value="0x11" name="FMT6_8_8_UINT"/>
+	<value value="0x12" name="FMT6_8_8_SINT"/>
+	<value value="0x13" name="FMT6_L8_A8_UNORM"/>
+
+	<value value="0x15" name="FMT6_16_UNORM"/>
+	<value value="0x16" name="FMT6_16_SNORM"/>
+	<value value="0x17" name="FMT6_16_FLOAT"/>
+	<value value="0x18" name="FMT6_16_UINT"/>
+	<value value="0x19" name="FMT6_16_SINT"/>
+
+	<value value="0x21" name="FMT6_8_8_8_UNORM"/>
+	<value value="0x22" name="FMT6_8_8_8_SNORM"/>
+	<value value="0x23" name="FMT6_8_8_8_UINT"/>
+	<value value="0x24" name="FMT6_8_8_8_SINT"/>
+
+	<value value="0x30" name="FMT6_8_8_8_8_UNORM"/>
+	<value value="0x31" name="FMT6_8_8_8_X8_UNORM"/> <!-- samples 1 for alpha -->
+	<value value="0x32" name="FMT6_8_8_8_8_SNORM"/>
+	<value value="0x33" name="FMT6_8_8_8_8_UINT"/>
+	<value value="0x34" name="FMT6_8_8_8_8_SINT"/>
+
+	<value value="0x35" name="FMT6_9_9_9_E5_FLOAT"/>
+
+	<value value="0x36" name="FMT6_10_10_10_2_UNORM"/>
+	<value value="0x37" name="FMT6_10_10_10_2_UNORM_DEST"/>
+	<value value="0x39" name="FMT6_10_10_10_2_SNORM"/>
+	<value value="0x3a" name="FMT6_10_10_10_2_UINT"/>
+	<value value="0x3b" name="FMT6_10_10_10_2_SINT"/>
+
+	<value value="0x42" name="FMT6_11_11_10_FLOAT"/>
+
+	<value value="0x43" name="FMT6_16_16_UNORM"/>
+	<value value="0x44" name="FMT6_16_16_SNORM"/>
+	<value value="0x45" name="FMT6_16_16_FLOAT"/>
+	<value value="0x46" name="FMT6_16_16_UINT"/>
+	<value value="0x47" name="FMT6_16_16_SINT"/>
+
+	<value value="0x48" name="FMT6_32_UNORM"/>
+	<value value="0x49" name="FMT6_32_SNORM"/>
+	<value value="0x4a" name="FMT6_32_FLOAT"/>
+	<value value="0x4b" name="FMT6_32_UINT"/>
+	<value value="0x4c" name="FMT6_32_SINT"/>
+	<value value="0x4d" name="FMT6_32_FIXED"/>
+
+	<value value="0x58" name="FMT6_16_16_16_UNORM"/>
+	<value value="0x59" name="FMT6_16_16_16_SNORM"/>
+	<value value="0x5a" name="FMT6_16_16_16_FLOAT"/>
+	<value value="0x5b" name="FMT6_16_16_16_UINT"/>
+	<value value="0x5c" name="FMT6_16_16_16_SINT"/>
+
+	<value value="0x60" name="FMT6_16_16_16_16_UNORM"/>
+	<value value="0x61" name="FMT6_16_16_16_16_SNORM"/>
+	<value value="0x62" name="FMT6_16_16_16_16_FLOAT"/>
+	<value value="0x63" name="FMT6_16_16_16_16_UINT"/>
+	<value value="0x64" name="FMT6_16_16_16_16_SINT"/>
+
+	<value value="0x65" name="FMT6_32_32_UNORM"/>
+	<value value="0x66" name="FMT6_32_32_SNORM"/>
+	<value value="0x67" name="FMT6_32_32_FLOAT"/>
+	<value value="0x68" name="FMT6_32_32_UINT"/>
+	<value value="0x69" name="FMT6_32_32_SINT"/>
+	<value value="0x6a" name="FMT6_32_32_FIXED"/>
+
+	<value value="0x70" name="FMT6_32_32_32_UNORM"/>
+	<value value="0x71" name="FMT6_32_32_32_SNORM"/>
+	<value value="0x72" name="FMT6_32_32_32_UINT"/>
+	<value value="0x73" name="FMT6_32_32_32_SINT"/>
+	<value value="0x74" name="FMT6_32_32_32_FLOAT"/>
+	<value value="0x75" name="FMT6_32_32_32_FIXED"/>
+
+	<value value="0x80" name="FMT6_32_32_32_32_UNORM"/>
+	<value value="0x81" name="FMT6_32_32_32_32_SNORM"/>
+	<value value="0x82" name="FMT6_32_32_32_32_FLOAT"/>
+	<value value="0x83" name="FMT6_32_32_32_32_UINT"/>
+	<value value="0x84" name="FMT6_32_32_32_32_SINT"/>
+	<value value="0x85" name="FMT6_32_32_32_32_FIXED"/>
+
+	<value value="0x8c" name="FMT6_G8R8B8R8_422_UNORM"/> <!-- UYVY -->
+	<value value="0x8d" name="FMT6_R8G8R8B8_422_UNORM"/> <!-- YUYV -->
+	<value value="0x8e" name="FMT6_R8_G8B8_2PLANE_420_UNORM"/> <!-- NV12 -->
+	<value value="0x8f" name="FMT6_NV21"/>
+	<value value="0x90" name="FMT6_R8_G8_B8_3PLANE_420_UNORM"/> <!-- YV12 -->
+
+	<value value="0x91" name="FMT6_Z24_UNORM_S8_UINT_AS_R8G8B8A8"/>
+
+	<!-- Note: tiling/UBWC for these may be different from equivalent formats
+	For example FMT6_NV12_Y is not compatible with FMT6_8_UNORM
+	-->
+	<value value="0x94" name="FMT6_NV12_Y"/>
+	<value value="0x95" name="FMT6_NV12_UV"/>
+	<value value="0x96" name="FMT6_NV12_VU"/>
+	<value value="0x97" name="FMT6_NV12_4R"/>
+	<value value="0x98" name="FMT6_NV12_4R_Y"/>
+	<value value="0x99" name="FMT6_NV12_4R_UV"/>
+	<value value="0x9a" name="FMT6_P010"/>
+	<value value="0x9b" name="FMT6_P010_Y"/>
+	<value value="0x9c" name="FMT6_P010_UV"/>
+	<value value="0x9d" name="FMT6_TP10"/>
+	<value value="0x9e" name="FMT6_TP10_Y"/>
+	<value value="0x9f" name="FMT6_TP10_UV"/>
+
+	<value value="0xa0" name="FMT6_Z24_UNORM_S8_UINT"/>
+
+	<value value="0xab" name="FMT6_ETC2_RG11_UNORM"/>
+	<value value="0xac" name="FMT6_ETC2_RG11_SNORM"/>
+	<value value="0xad" name="FMT6_ETC2_R11_UNORM"/>
+	<value value="0xae" name="FMT6_ETC2_R11_SNORM"/>
+	<value value="0xaf" name="FMT6_ETC1"/>
+	<value value="0xb0" name="FMT6_ETC2_RGB8"/>
+	<value value="0xb1" name="FMT6_ETC2_RGBA8"/>
+	<value value="0xb2" name="FMT6_ETC2_RGB8A1"/>
+	<value value="0xb3" name="FMT6_DXT1"/>
+	<value value="0xb4" name="FMT6_DXT3"/>
+	<value value="0xb5" name="FMT6_DXT5"/>
+	<value value="0xb7" name="FMT6_RGTC1_UNORM"/>
+	<value value="0xb8" name="FMT6_RGTC1_SNORM"/>
+	<value value="0xbb" name="FMT6_RGTC2_UNORM"/>
+	<value value="0xbc" name="FMT6_RGTC2_SNORM"/>
+	<value value="0xbe" name="FMT6_BPTC_UFLOAT"/>
+	<value value="0xbf" name="FMT6_BPTC_FLOAT"/>
+	<value value="0xc0" name="FMT6_BPTC"/>
+	<value value="0xc1" name="FMT6_ASTC_4x4"/>
+	<value value="0xc2" name="FMT6_ASTC_5x4"/>
+	<value value="0xc3" name="FMT6_ASTC_5x5"/>
+	<value value="0xc4" name="FMT6_ASTC_6x5"/>
+	<value value="0xc5" name="FMT6_ASTC_6x6"/>
+	<value value="0xc6" name="FMT6_ASTC_8x5"/>
+	<value value="0xc7" name="FMT6_ASTC_8x6"/>
+	<value value="0xc8" name="FMT6_ASTC_8x8"/>
+	<value value="0xc9" name="FMT6_ASTC_10x5"/>
+	<value value="0xca" name="FMT6_ASTC_10x6"/>
+	<value value="0xcb" name="FMT6_ASTC_10x8"/>
+	<value value="0xcc" name="FMT6_ASTC_10x10"/>
+	<value value="0xcd" name="FMT6_ASTC_12x10"/>
+	<value value="0xce" name="FMT6_ASTC_12x12"/>
+
+	<!-- for sampling stencil (integer, 2nd channel), not available on a630 -->
+	<value value="0xea" name="FMT6_Z24_UINT_S8_UINT"/>
+
+	<!-- Not a hw enum, used internally in driver -->
+	<value value="0xff" name="FMT6_NONE"/>
+
+</enum>
+
+<!-- probably same as a5xx -->
+<enum name="a6xx_polygon_mode">
+	<value name="POLYMODE6_POINTS" value="1"/>
+	<value name="POLYMODE6_LINES" value="2"/>
+	<value name="POLYMODE6_TRIANGLES" value="3"/>
+</enum>
+
+<enum name="a6xx_depth_format">
+	<value name="DEPTH6_NONE" value="0"/>
+	<value name="DEPTH6_16" value="1"/>
+	<value name="DEPTH6_24_8" value="2"/>
+	<value name="DEPTH6_32" value="4"/>
+</enum>
+
+<bitset name="a6x_cp_protect" inline="yes">
+	<bitfield name="BASE_ADDR" low="0" high="17"/>
+	<bitfield name="MASK_LEN" low="18" high="30"/>
+	<bitfield name="READ" pos="31" type="boolean"/>
+</bitset>
+
+<enum name="a6xx_shader_id">
+	<value value="0x9" name="A6XX_TP0_TMO_DATA"/>
+	<value value="0xa" name="A6XX_TP0_SMO_DATA"/>
+	<value value="0xb" name="A6XX_TP0_MIPMAP_BASE_DATA"/>
+	<value value="0x19" name="A6XX_TP1_TMO_DATA"/>
+	<value value="0x1a" name="A6XX_TP1_SMO_DATA"/>
+	<value value="0x1b" name="A6XX_TP1_MIPMAP_BASE_DATA"/>
+	<value value="0x29" name="A6XX_SP_INST_DATA"/>
+	<value value="0x2a" name="A6XX_SP_LB_0_DATA"/>
+	<value value="0x2b" name="A6XX_SP_LB_1_DATA"/>
+	<value value="0x2c" name="A6XX_SP_LB_2_DATA"/>
+	<value value="0x2d" name="A6XX_SP_LB_3_DATA"/>
+	<value value="0x2e" name="A6XX_SP_LB_4_DATA"/>
+	<value value="0x2f" name="A6XX_SP_LB_5_DATA"/>
+	<value value="0x30" name="A6XX_SP_CB_BINDLESS_DATA"/>
+	<value value="0x31" name="A6XX_SP_CB_LEGACY_DATA"/>
+	<value value="0x32" name="A6XX_SP_UAV_DATA"/>
+	<value value="0x33" name="A6XX_SP_INST_TAG"/>
+	<value value="0x34" name="A6XX_SP_CB_BINDLESS_TAG"/>
+	<value value="0x35" name="A6XX_SP_TMO_UMO_TAG"/>
+	<value value="0x36" name="A6XX_SP_SMO_TAG"/>
+	<value value="0x37" name="A6XX_SP_STATE_DATA"/>
+	<value value="0x49" name="A6XX_HLSQ_CHUNK_CVS_RAM"/>
+	<value value="0x4a" name="A6XX_HLSQ_CHUNK_CPS_RAM"/>
+	<value value="0x4b" name="A6XX_HLSQ_CHUNK_CVS_RAM_TAG"/>
+	<value value="0x4c" name="A6XX_HLSQ_CHUNK_CPS_RAM_TAG"/>
+	<value value="0x4d" name="A6XX_HLSQ_ICB_CVS_CB_BASE_TAG"/>
+	<value value="0x4e" name="A6XX_HLSQ_ICB_CPS_CB_BASE_TAG"/>
+	<value value="0x50" name="A6XX_HLSQ_CVS_MISC_RAM"/>
+	<value value="0x51" name="A6XX_HLSQ_CPS_MISC_RAM"/>
+	<value value="0x52" name="A6XX_HLSQ_INST_RAM"/>
+	<value value="0x53" name="A6XX_HLSQ_GFX_CVS_CONST_RAM"/>
+	<value value="0x54" name="A6XX_HLSQ_GFX_CPS_CONST_RAM"/>
+	<value value="0x55" name="A6XX_HLSQ_CVS_MISC_RAM_TAG"/>
+	<value value="0x56" name="A6XX_HLSQ_CPS_MISC_RAM_TAG"/>
+	<value value="0x57" name="A6XX_HLSQ_INST_RAM_TAG"/>
+	<value value="0x58" name="A6XX_HLSQ_GFX_CVS_CONST_RAM_TAG"/>
+	<value value="0x59" name="A6XX_HLSQ_GFX_CPS_CONST_RAM_TAG"/>
+	<value value="0x5a" name="A6XX_HLSQ_PWR_REST_RAM"/>
+	<value value="0x5b" name="A6XX_HLSQ_PWR_REST_TAG"/>
+	<value value="0x60" name="A6XX_HLSQ_DATAPATH_META"/>
+	<value value="0x61" name="A6XX_HLSQ_FRONTEND_META"/>
+	<value value="0x62" name="A6XX_HLSQ_INDIRECT_META"/>
+	<value value="0x63" name="A6XX_HLSQ_BACKEND_META"/>
+	<value value="0x70" name="A6XX_SP_LB_6_DATA"/>
+	<value value="0x71" name="A6XX_SP_LB_7_DATA"/>
+	<value value="0x73" name="A6XX_HLSQ_INST_RAM_1"/>
+</enum>
+
+<enum name="a7xx_statetype_id">
+	<value value="0" name="A7XX_TP0_NCTX_REG"/>
+	<value value="1" name="A7XX_TP0_CTX0_3D_CVS_REG"/>
+	<value value="2" name="A7XX_TP0_CTX0_3D_CPS_REG"/>
+	<value value="3" name="A7XX_TP0_CTX1_3D_CVS_REG"/>
+	<value value="4" name="A7XX_TP0_CTX1_3D_CPS_REG"/>
+	<value value="5" name="A7XX_TP0_CTX2_3D_CPS_REG"/>
+	<value value="6" name="A7XX_TP0_CTX3_3D_CPS_REG"/>
+	<value value="9" name="A7XX_TP0_TMO_DATA"/>
+	<value value="10" name="A7XX_TP0_SMO_DATA"/>
+	<value value="11" name="A7XX_TP0_MIPMAP_BASE_DATA"/>
+	<value value="32" name="A7XX_SP_NCTX_REG"/>
+	<value value="33" name="A7XX_SP_CTX0_3D_CVS_REG"/>
+	<value value="34" name="A7XX_SP_CTX0_3D_CPS_REG"/>
+	<value value="35" name="A7XX_SP_CTX1_3D_CVS_REG"/>
+	<value value="36" name="A7XX_SP_CTX1_3D_CPS_REG"/>
+	<value value="37" name="A7XX_SP_CTX2_3D_CPS_REG"/>
+	<value value="38" name="A7XX_SP_CTX3_3D_CPS_REG"/>
+	<value value="39" name="A7XX_SP_INST_DATA"/>
+	<value value="40" name="A7XX_SP_INST_DATA_1"/>
+	<value value="41" name="A7XX_SP_LB_0_DATA"/>
+	<value value="42" name="A7XX_SP_LB_1_DATA"/>
+	<value value="43" name="A7XX_SP_LB_2_DATA"/>
+	<value value="44" name="A7XX_SP_LB_3_DATA"/>
+	<value value="45" name="A7XX_SP_LB_4_DATA"/>
+	<value value="46" name="A7XX_SP_LB_5_DATA"/>
+	<value value="47" name="A7XX_SP_LB_6_DATA"/>
+	<value value="48" name="A7XX_SP_LB_7_DATA"/>
+	<value value="49" name="A7XX_SP_CB_RAM"/>
+	<value value="50" name="A7XX_SP_LB_13_DATA"/>
+	<value value="51" name="A7XX_SP_LB_14_DATA"/>
+	<value value="52" name="A7XX_SP_INST_TAG"/>
+	<value value="53" name="A7XX_SP_INST_DATA_2"/>
+	<value value="54" name="A7XX_SP_TMO_TAG"/>
+	<value value="55" name="A7XX_SP_SMO_TAG"/>
+	<value value="56" name="A7XX_SP_STATE_DATA"/>
+	<value value="57" name="A7XX_SP_HWAVE_RAM"/>
+	<value value="58" name="A7XX_SP_L0_INST_BUF"/>
+	<value value="59" name="A7XX_SP_LB_8_DATA"/>
+	<value value="60" name="A7XX_SP_LB_9_DATA"/>
+	<value value="61" name="A7XX_SP_LB_10_DATA"/>
+	<value value="62" name="A7XX_SP_LB_11_DATA"/>
+	<value value="63" name="A7XX_SP_LB_12_DATA"/>
+	<value value="64" name="A7XX_HLSQ_DATAPATH_DSTR_META"/>
+	<value value="67" name="A7XX_HLSQ_L2STC_TAG_RAM"/>
+	<value value="68" name="A7XX_HLSQ_L2STC_INFO_CMD"/>
+	<value value="69" name="A7XX_HLSQ_CVS_BE_CTXT_BUF_RAM_TAG"/>
+	<value value="70" name="A7XX_HLSQ_CPS_BE_CTXT_BUF_RAM_TAG"/>
+	<value value="71" name="A7XX_HLSQ_GFX_CVS_BE_CTXT_BUF_RAM"/>
+	<value value="72" name="A7XX_HLSQ_GFX_CPS_BE_CTXT_BUF_RAM"/>
+	<value value="73" name="A7XX_HLSQ_CHUNK_CVS_RAM"/>
+	<value value="74" name="A7XX_HLSQ_CHUNK_CPS_RAM"/>
+	<value value="75" name="A7XX_HLSQ_CHUNK_CVS_RAM_TAG"/>
+	<value value="76" name="A7XX_HLSQ_CHUNK_CPS_RAM_TAG"/>
+	<value value="77" name="A7XX_HLSQ_ICB_CVS_CB_BASE_TAG"/>
+	<value value="78" name="A7XX_HLSQ_ICB_CPS_CB_BASE_TAG"/>
+	<value value="79" name="A7XX_HLSQ_CVS_MISC_RAM"/>
+	<value value="80" name="A7XX_HLSQ_CPS_MISC_RAM"/>
+	<value value="81" name="A7XX_HLSQ_CPS_MISC_RAM_1"/>
+	<value value="82" name="A7XX_HLSQ_INST_RAM"/>
+	<value value="83" name="A7XX_HLSQ_GFX_CVS_CONST_RAM"/>
+	<value value="84" name="A7XX_HLSQ_GFX_CPS_CONST_RAM"/>
+	<value value="85" name="A7XX_HLSQ_CVS_MISC_RAM_TAG"/>
+	<value value="86" name="A7XX_HLSQ_CPS_MISC_RAM_TAG"/>
+	<value value="87" name="A7XX_HLSQ_INST_RAM_TAG"/>
+	<value value="88" name="A7XX_HLSQ_GFX_CVS_CONST_RAM_TAG"/>
+	<value value="89" name="A7XX_HLSQ_GFX_CPS_CONST_RAM_TAG"/>
+	<value value="90" name="A7XX_HLSQ_GFX_LOCAL_MISC_RAM"/>
+	<value value="91" name="A7XX_HLSQ_GFX_LOCAL_MISC_RAM_TAG"/>
+	<value value="92" name="A7XX_HLSQ_INST_RAM_1"/>
+	<value value="93" name="A7XX_HLSQ_STPROC_META"/>
+	<value value="94" name="A7XX_HLSQ_BV_BE_META"/>
+	<value value="95" name="A7XX_HLSQ_INST_RAM_2"/>
+	<value value="96" name="A7XX_HLSQ_DATAPATH_META"/>
+	<value value="97" name="A7XX_HLSQ_FRONTEND_META"/>
+	<value value="98" name="A7XX_HLSQ_INDIRECT_META"/>
+	<value value="99" name="A7XX_HLSQ_BACKEND_META"/>
+</enum>
+
+<enum name="a6xx_debugbus_id">
+	<value value="0x1" name="A6XX_DBGBUS_CP"/>
+	<value value="0x2" name="A6XX_DBGBUS_RBBM"/>
+	<value value="0x3" name="A6XX_DBGBUS_VBIF"/>
+	<value value="0x4" name="A6XX_DBGBUS_HLSQ"/>
+	<value value="0x5" name="A6XX_DBGBUS_UCHE"/>
+	<value value="0x6" name="A6XX_DBGBUS_DPM"/>
+	<value value="0x7" name="A6XX_DBGBUS_TESS"/>
+	<value value="0x8" name="A6XX_DBGBUS_PC"/>
+	<value value="0x9" name="A6XX_DBGBUS_VFDP"/>
+	<value value="0xa" name="A6XX_DBGBUS_VPC"/>
+	<value value="0xb" name="A6XX_DBGBUS_TSE"/>
+	<value value="0xc" name="A6XX_DBGBUS_RAS"/>
+	<value value="0xd" name="A6XX_DBGBUS_VSC"/>
+	<value value="0xe" name="A6XX_DBGBUS_COM"/>
+	<value value="0x10" name="A6XX_DBGBUS_LRZ"/>
+	<value value="0x11" name="A6XX_DBGBUS_A2D"/>
+	<value value="0x12" name="A6XX_DBGBUS_CCUFCHE"/>
+	<value value="0x13" name="A6XX_DBGBUS_GMU_CX"/>
+	<value value="0x14" name="A6XX_DBGBUS_RBP"/>
+	<value value="0x15" name="A6XX_DBGBUS_DCS"/>
+	<value value="0x16" name="A6XX_DBGBUS_DBGC"/>
+	<value value="0x17" name="A6XX_DBGBUS_CX"/>
+	<value value="0x18" name="A6XX_DBGBUS_GMU_GX"/>
+	<value value="0x19" name="A6XX_DBGBUS_TPFCHE"/>
+	<value value="0x1a" name="A6XX_DBGBUS_GBIF_GX"/>
+	<value value="0x1d" name="A6XX_DBGBUS_GPC"/>
+	<value value="0x1e" name="A6XX_DBGBUS_LARC"/>
+	<value value="0x1f" name="A6XX_DBGBUS_HLSQ_SPTP"/>
+	<value value="0x20" name="A6XX_DBGBUS_RB_0"/>
+	<value value="0x21" name="A6XX_DBGBUS_RB_1"/>
+	<value value="0x22" name="A6XX_DBGBUS_RB_2"/>
+	<value value="0x24" name="A6XX_DBGBUS_UCHE_WRAPPER"/>
+	<value value="0x28" name="A6XX_DBGBUS_CCU_0"/>
+	<value value="0x29" name="A6XX_DBGBUS_CCU_1"/>
+	<value value="0x2a" name="A6XX_DBGBUS_CCU_2"/>
+	<value value="0x38" name="A6XX_DBGBUS_VFD_0"/>
+	<value value="0x39" name="A6XX_DBGBUS_VFD_1"/>
+	<value value="0x3a" name="A6XX_DBGBUS_VFD_2"/>
+	<value value="0x3b" name="A6XX_DBGBUS_VFD_3"/>
+	<value value="0x3c" name="A6XX_DBGBUS_VFD_4"/>
+	<value value="0x3d" name="A6XX_DBGBUS_VFD_5"/>
+	<value value="0x40" name="A6XX_DBGBUS_SP_0"/>
+	<value value="0x41" name="A6XX_DBGBUS_SP_1"/>
+	<value value="0x42" name="A6XX_DBGBUS_SP_2"/>
+	<value value="0x48" name="A6XX_DBGBUS_TPL1_0"/>
+	<value value="0x49" name="A6XX_DBGBUS_TPL1_1"/>
+	<value value="0x4a" name="A6XX_DBGBUS_TPL1_2"/>
+	<value value="0x4b" name="A6XX_DBGBUS_TPL1_3"/>
+	<value value="0x4c" name="A6XX_DBGBUS_TPL1_4"/>
+	<value value="0x4d" name="A6XX_DBGBUS_TPL1_5"/>
+	<value value="0x58" name="A6XX_DBGBUS_SPTP_0"/>
+	<value value="0x59" name="A6XX_DBGBUS_SPTP_1"/>
+	<value value="0x5a" name="A6XX_DBGBUS_SPTP_2"/>
+	<value value="0x5b" name="A6XX_DBGBUS_SPTP_3"/>
+	<value value="0x5c" name="A6XX_DBGBUS_SPTP_4"/>
+	<value value="0x5d" name="A6XX_DBGBUS_SPTP_5"/>
+</enum>
+
+<enum name="a7xx_state_location">
+	<value value="0" name="A7XX_HLSQ_STATE"/>
+	<value value="1" name="A7XX_HLSQ_DP"/>
+	<value value="2" name="A7XX_SP_TOP"/>
+	<value value="3" name="A7XX_USPTP"/>
+	<value value="4" name="A7XX_HLSQ_DP_STR"/>
+</enum>
+
+<enum name="a7xx_pipe">
+	<value value="0" name="A7XX_PIPE_NONE"/>
+	<value value="1" name="A7XX_PIPE_BR"/>
+	<value value="2" name="A7XX_PIPE_BV"/>
+	<value value="3" name="A7XX_PIPE_LPAC"/>
+</enum>
+
+<enum name="a7xx_cluster">
+	<value value="0" name="A7XX_CLUSTER_NONE"/>
+	<value value="1" name="A7XX_CLUSTER_FE"/>
+	<value value="2" name="A7XX_CLUSTER_SP_VS"/>
+	<value value="3" name="A7XX_CLUSTER_PC_VS"/>
+	<value value="4" name="A7XX_CLUSTER_GRAS"/>
+	<value value="5" name="A7XX_CLUSTER_SP_PS"/>
+	<value value="6" name="A7XX_CLUSTER_VPC_PS"/>
+	<value value="7" name="A7XX_CLUSTER_PS"/>
+</enum>
+
+<enum name="a7xx_debugbus_id">
+	<value value="1" name="A7XX_DBGBUS_CP_0_0"/>
+	<value value="2" name="A7XX_DBGBUS_CP_0_1"/>
+	<value value="3" name="A7XX_DBGBUS_RBBM"/>
+	<value value="5" name="A7XX_DBGBUS_GBIF_GX"/>
+	<value value="6" name="A7XX_DBGBUS_GBIF_CX"/>
+	<value value="7" name="A7XX_DBGBUS_HLSQ"/>
+	<value value="9" name="A7XX_DBGBUS_UCHE_0"/>
+	<value value="10" name="A7XX_DBGBUS_UCHE_1"/>
+	<value value="13" name="A7XX_DBGBUS_TESS_BR"/>
+	<value value="14" name="A7XX_DBGBUS_TESS_BV"/>
+	<value value="17" name="A7XX_DBGBUS_PC_BR"/>
+	<value value="18" name="A7XX_DBGBUS_PC_BV"/>
+	<value value="21" name="A7XX_DBGBUS_VFDP_BR"/>
+	<value value="22" name="A7XX_DBGBUS_VFDP_BV"/>
+	<value value="25" name="A7XX_DBGBUS_VPC_BR"/>
+	<value value="26" name="A7XX_DBGBUS_VPC_BV"/>
+	<value value="29" name="A7XX_DBGBUS_TSE_BR"/>
+	<value value="30" name="A7XX_DBGBUS_TSE_BV"/>
+	<value value="33" name="A7XX_DBGBUS_RAS_BR"/>
+	<value value="34" name="A7XX_DBGBUS_RAS_BV"/>
+	<value value="37" name="A7XX_DBGBUS_VSC"/>
+	<value value="39" name="A7XX_DBGBUS_COM_0"/>
+	<value value="43" name="A7XX_DBGBUS_LRZ_BR"/>
+	<value value="44" name="A7XX_DBGBUS_LRZ_BV"/>
+	<value value="47" name="A7XX_DBGBUS_UFC_0"/>
+	<value value="48" name="A7XX_DBGBUS_UFC_1"/>
+	<value value="55" name="A7XX_DBGBUS_GMU_GX"/>
+	<value value="59" name="A7XX_DBGBUS_DBGC"/>
+	<value value="60" name="A7XX_DBGBUS_CX"/>
+	<value value="61" name="A7XX_DBGBUS_GMU_CX"/>
+	<value value="62" name="A7XX_DBGBUS_GPC_BR"/>
+	<value value="63" name="A7XX_DBGBUS_GPC_BV"/>
+	<value value="66" name="A7XX_DBGBUS_LARC"/>
+	<value value="68" name="A7XX_DBGBUS_HLSQ_SPTP"/>
+	<value value="70" name="A7XX_DBGBUS_RB_0"/>
+	<value value="71" name="A7XX_DBGBUS_RB_1"/>
+	<value value="72" name="A7XX_DBGBUS_RB_2"/>
+	<value value="73" name="A7XX_DBGBUS_RB_3"/>
+	<value value="74" name="A7XX_DBGBUS_RB_4"/>
+	<value value="75" name="A7XX_DBGBUS_RB_5"/>
+	<value value="102" name="A7XX_DBGBUS_UCHE_WRAPPER"/>
+	<value value="106" name="A7XX_DBGBUS_CCU_0"/>
+	<value value="107" name="A7XX_DBGBUS_CCU_1"/>
+	<value value="108" name="A7XX_DBGBUS_CCU_2"/>
+	<value value="109" name="A7XX_DBGBUS_CCU_3"/>
+	<value value="110" name="A7XX_DBGBUS_CCU_4"/>
+	<value value="111" name="A7XX_DBGBUS_CCU_5"/>
+	<value value="138" name="A7XX_DBGBUS_VFD_BR_0"/>
+	<value value="139" name="A7XX_DBGBUS_VFD_BR_1"/>
+	<value value="140" name="A7XX_DBGBUS_VFD_BR_2"/>
+	<value value="141" name="A7XX_DBGBUS_VFD_BR_3"/>
+	<value value="142" name="A7XX_DBGBUS_VFD_BR_4"/>
+	<value value="143" name="A7XX_DBGBUS_VFD_BR_5"/>
+	<value value="144" name="A7XX_DBGBUS_VFD_BR_6"/>
+	<value value="145" name="A7XX_DBGBUS_VFD_BR_7"/>
+	<value value="202" name="A7XX_DBGBUS_VFD_BV_0"/>
+	<value value="203" name="A7XX_DBGBUS_VFD_BV_1"/>
+	<value value="204" name="A7XX_DBGBUS_VFD_BV_2"/>
+	<value value="205" name="A7XX_DBGBUS_VFD_BV_3"/>
+	<value value="234" name="A7XX_DBGBUS_USP_0"/>
+	<value value="235" name="A7XX_DBGBUS_USP_1"/>
+	<value value="236" name="A7XX_DBGBUS_USP_2"/>
+	<value value="237" name="A7XX_DBGBUS_USP_3"/>
+	<value value="238" name="A7XX_DBGBUS_USP_4"/>
+	<value value="239" name="A7XX_DBGBUS_USP_5"/>
+	<value value="266" name="A7XX_DBGBUS_TP_0"/>
+	<value value="267" name="A7XX_DBGBUS_TP_1"/>
+	<value value="268" name="A7XX_DBGBUS_TP_2"/>
+	<value value="269" name="A7XX_DBGBUS_TP_3"/>
+	<value value="270" name="A7XX_DBGBUS_TP_4"/>
+	<value value="271" name="A7XX_DBGBUS_TP_5"/>
+	<value value="272" name="A7XX_DBGBUS_TP_6"/>
+	<value value="273" name="A7XX_DBGBUS_TP_7"/>
+	<value value="274" name="A7XX_DBGBUS_TP_8"/>
+	<value value="275" name="A7XX_DBGBUS_TP_9"/>
+	<value value="276" name="A7XX_DBGBUS_TP_10"/>
+	<value value="277" name="A7XX_DBGBUS_TP_11"/>
+	<value value="330" name="A7XX_DBGBUS_USPTP_0"/>
+	<value value="331" name="A7XX_DBGBUS_USPTP_1"/>
+	<value value="332" name="A7XX_DBGBUS_USPTP_2"/>
+	<value value="333" name="A7XX_DBGBUS_USPTP_3"/>
+	<value value="334" name="A7XX_DBGBUS_USPTP_4"/>
+	<value value="335" name="A7XX_DBGBUS_USPTP_5"/>
+	<value value="336" name="A7XX_DBGBUS_USPTP_6"/>
+	<value value="337" name="A7XX_DBGBUS_USPTP_7"/>
+	<value value="338" name="A7XX_DBGBUS_USPTP_8"/>
+	<value value="339" name="A7XX_DBGBUS_USPTP_9"/>
+	<value value="340" name="A7XX_DBGBUS_USPTP_10"/>
+	<value value="341" name="A7XX_DBGBUS_USPTP_11"/>
+	<value value="396" name="A7XX_DBGBUS_CCHE_0"/>
+	<value value="397" name="A7XX_DBGBUS_CCHE_1"/>
+	<value value="398" name="A7XX_DBGBUS_CCHE_2"/>
+	<value value="408" name="A7XX_DBGBUS_VPC_DSTR_0"/>
+	<value value="409" name="A7XX_DBGBUS_VPC_DSTR_1"/>
+	<value value="410" name="A7XX_DBGBUS_VPC_DSTR_2"/>
+	<value value="411" name="A7XX_DBGBUS_HLSQ_DP_STR_0"/>
+	<value value="412" name="A7XX_DBGBUS_HLSQ_DP_STR_1"/>
+	<value value="413" name="A7XX_DBGBUS_HLSQ_DP_STR_2"/>
+	<value value="414" name="A7XX_DBGBUS_HLSQ_DP_STR_3"/>
+	<value value="415" name="A7XX_DBGBUS_HLSQ_DP_STR_4"/>
+	<value value="416" name="A7XX_DBGBUS_HLSQ_DP_STR_5"/>
+	<value value="443" name="A7XX_DBGBUS_UFC_DSTR_0"/>
+	<value value="444" name="A7XX_DBGBUS_UFC_DSTR_1"/>
+	<value value="445" name="A7XX_DBGBUS_UFC_DSTR_2"/>
+	<value value="446" name="A7XX_DBGBUS_CGC_SUBCORE"/>
+	<value value="447" name="A7XX_DBGBUS_CGC_CORE"/>
+</enum>
+
+<enum name="a6xx_cp_perfcounter_select">
+	<value value="0" name="PERF_CP_ALWAYS_COUNT"/>
+	<value value="1" name="PERF_CP_BUSY_GFX_CORE_IDLE"/>
+	<value value="2" name="PERF_CP_BUSY_CYCLES"/>
+	<value value="3" name="PERF_CP_NUM_PREEMPTIONS"/>
+	<value value="4" name="PERF_CP_PREEMPTION_REACTION_DELAY"/>
+	<value value="5" name="PERF_CP_PREEMPTION_SWITCH_OUT_TIME"/>
+	<value value="6" name="PERF_CP_PREEMPTION_SWITCH_IN_TIME"/>
+	<value value="7" name="PERF_CP_DEAD_DRAWS_IN_BIN_RENDER"/>
+	<value value="8" name="PERF_CP_PREDICATED_DRAWS_KILLED"/>
+	<value value="9" name="PERF_CP_MODE_SWITCH"/>
+	<value value="10" name="PERF_CP_ZPASS_DONE"/>
+	<value value="11" name="PERF_CP_CONTEXT_DONE"/>
+	<value value="12" name="PERF_CP_CACHE_FLUSH"/>
+	<value value="13" name="PERF_CP_LONG_PREEMPTIONS"/>
+	<value value="14" name="PERF_CP_SQE_I_CACHE_STARVE"/>
+	<value value="15" name="PERF_CP_SQE_IDLE"/>
+	<value value="16" name="PERF_CP_SQE_PM4_STARVE_RB_IB"/>
+	<value value="17" name="PERF_CP_SQE_PM4_STARVE_SDS"/>
+	<value value="18" name="PERF_CP_SQE_MRB_STARVE"/>
+	<value value="19" name="PERF_CP_SQE_RRB_STARVE"/>
+	<value value="20" name="PERF_CP_SQE_VSD_STARVE"/>
+	<value value="21" name="PERF_CP_VSD_DECODE_STARVE"/>
+	<value value="22" name="PERF_CP_SQE_PIPE_OUT_STALL"/>
+	<value value="23" name="PERF_CP_SQE_SYNC_STALL"/>
+	<value value="24" name="PERF_CP_SQE_PM4_WFI_STALL"/>
+	<value value="25" name="PERF_CP_SQE_SYS_WFI_STALL"/>
+	<value value="26" name="PERF_CP_SQE_T4_EXEC"/>
+	<value value="27" name="PERF_CP_SQE_LOAD_STATE_EXEC"/>
+	<value value="28" name="PERF_CP_SQE_SAVE_SDS_STATE"/>
+	<value value="29" name="PERF_CP_SQE_DRAW_EXEC"/>
+	<value value="30" name="PERF_CP_SQE_CTXT_REG_BUNCH_EXEC"/>
+	<value value="31" name="PERF_CP_SQE_EXEC_PROFILED"/>
+	<value value="32" name="PERF_CP_MEMORY_POOL_EMPTY"/>
+	<value value="33" name="PERF_CP_MEMORY_POOL_SYNC_STALL"/>
+	<value value="34" name="PERF_CP_MEMORY_POOL_ABOVE_THRESH"/>
+	<value value="35" name="PERF_CP_AHB_WR_STALL_PRE_DRAWS"/>
+	<value value="36" name="PERF_CP_AHB_STALL_SQE_GMU"/>
+	<value value="37" name="PERF_CP_AHB_STALL_SQE_WR_OTHER"/>
+	<value value="38" name="PERF_CP_AHB_STALL_SQE_RD_OTHER"/>
+	<value value="39" name="PERF_CP_CLUSTER0_EMPTY"/>
+	<value value="40" name="PERF_CP_CLUSTER1_EMPTY"/>
+	<value value="41" name="PERF_CP_CLUSTER2_EMPTY"/>
+	<value value="42" name="PERF_CP_CLUSTER3_EMPTY"/>
+	<value value="43" name="PERF_CP_CLUSTER4_EMPTY"/>
+	<value value="44" name="PERF_CP_CLUSTER5_EMPTY"/>
+	<value value="45" name="PERF_CP_PM4_DATA"/>
+	<value value="46" name="PERF_CP_PM4_HEADERS"/>
+	<value value="47" name="PERF_CP_VBIF_READ_BEATS"/>
+	<value value="48" name="PERF_CP_VBIF_WRITE_BEATS"/>
+	<value value="49" name="PERF_CP_SQE_INSTR_COUNTER"/>
+</enum>
+
+<enum name="a6xx_rbbm_perfcounter_select">
+	<value value="0" name="PERF_RBBM_ALWAYS_COUNT"/>
+	<value value="1" name="PERF_RBBM_ALWAYS_ON"/>
+	<value value="2" name="PERF_RBBM_TSE_BUSY"/>
+	<value value="3" name="PERF_RBBM_RAS_BUSY"/>
+	<value value="4" name="PERF_RBBM_PC_DCALL_BUSY"/>
+	<value value="5" name="PERF_RBBM_PC_VSD_BUSY"/>
+	<value value="6" name="PERF_RBBM_STATUS_MASKED"/>
+	<value value="7" name="PERF_RBBM_COM_BUSY"/>
+	<value value="8" name="PERF_RBBM_DCOM_BUSY"/>
+	<value value="9" name="PERF_RBBM_VBIF_BUSY"/>
+	<value value="10" name="PERF_RBBM_VSC_BUSY"/>
+	<value value="11" name="PERF_RBBM_TESS_BUSY"/>
+	<value value="12" name="PERF_RBBM_UCHE_BUSY"/>
+	<value value="13" name="PERF_RBBM_HLSQ_BUSY"/>
+</enum>
+
+<enum name="a6xx_pc_perfcounter_select">
+	<value value="0" name="PERF_PC_BUSY_CYCLES"/>
+	<value value="1" name="PERF_PC_WORKING_CYCLES"/>
+	<value value="2" name="PERF_PC_STALL_CYCLES_VFD"/>
+	<value value="3" name="PERF_PC_STALL_CYCLES_TSE"/>
+	<value value="4" name="PERF_PC_STALL_CYCLES_VPC"/>
+	<value value="5" name="PERF_PC_STALL_CYCLES_UCHE"/>
+	<value value="6" name="PERF_PC_STALL_CYCLES_TESS"/>
+	<value value="7" name="PERF_PC_STALL_CYCLES_TSE_ONLY"/>
+	<value value="8" name="PERF_PC_STALL_CYCLES_VPC_ONLY"/>
+	<value value="9" name="PERF_PC_PASS1_TF_STALL_CYCLES"/>
+	<value value="10" name="PERF_PC_STARVE_CYCLES_FOR_INDEX"/>
+	<value value="11" name="PERF_PC_STARVE_CYCLES_FOR_TESS_FACTOR"/>
+	<value value="12" name="PERF_PC_STARVE_CYCLES_FOR_VIZ_STREAM"/>
+	<value value="13" name="PERF_PC_STARVE_CYCLES_FOR_POSITION"/>
+	<value value="14" name="PERF_PC_STARVE_CYCLES_DI"/>
+	<value value="15" name="PERF_PC_VIS_STREAMS_LOADED"/>
+	<value value="16" name="PERF_PC_INSTANCES"/>
+	<value value="17" name="PERF_PC_VPC_PRIMITIVES"/>
+	<value value="18" name="PERF_PC_DEAD_PRIM"/>
+	<value value="19" name="PERF_PC_LIVE_PRIM"/>
+	<value value="20" name="PERF_PC_VERTEX_HITS"/>
+	<value value="21" name="PERF_PC_IA_VERTICES"/>
+	<value value="22" name="PERF_PC_IA_PRIMITIVES"/>
+	<value value="23" name="PERF_PC_GS_PRIMITIVES"/>
+	<value value="24" name="PERF_PC_HS_INVOCATIONS"/>
+	<value value="25" name="PERF_PC_DS_INVOCATIONS"/>
+	<value value="26" name="PERF_PC_VS_INVOCATIONS"/>
+	<value value="27" name="PERF_PC_GS_INVOCATIONS"/>
+	<value value="28" name="PERF_PC_DS_PRIMITIVES"/>
+	<value value="29" name="PERF_PC_VPC_POS_DATA_TRANSACTION"/>
+	<value value="30" name="PERF_PC_3D_DRAWCALLS"/>
+	<value value="31" name="PERF_PC_2D_DRAWCALLS"/>
+	<value value="32" name="PERF_PC_NON_DRAWCALL_GLOBAL_EVENTS"/>
+	<value value="33" name="PERF_TESS_BUSY_CYCLES"/>
+	<value value="34" name="PERF_TESS_WORKING_CYCLES"/>
+	<value value="35" name="PERF_TESS_STALL_CYCLES_PC"/>
+	<value value="36" name="PERF_TESS_STARVE_CYCLES_PC"/>
+	<value value="37" name="PERF_PC_TSE_TRANSACTION"/>
+	<value value="38" name="PERF_PC_TSE_VERTEX"/>
+	<value value="39" name="PERF_PC_TESS_PC_UV_TRANS"/>
+	<value value="40" name="PERF_PC_TESS_PC_UV_PATCHES"/>
+	<value value="41" name="PERF_PC_TESS_FACTOR_TRANS"/>
+</enum>
+
+<enum name="a6xx_vfd_perfcounter_select">
+	<value value="0" name="PERF_VFD_BUSY_CYCLES"/>
+	<value value="1" name="PERF_VFD_STALL_CYCLES_UCHE"/>
+	<value value="2" name="PERF_VFD_STALL_CYCLES_VPC_ALLOC"/>
+	<value value="3" name="PERF_VFD_STALL_CYCLES_SP_INFO"/>
+	<value value="4" name="PERF_VFD_STALL_CYCLES_SP_ATTR"/>
+	<value value="5" name="PERF_VFD_STARVE_CYCLES_UCHE"/>
+	<value value="6" name="PERF_VFD_RBUFFER_FULL"/>
+	<value value="7" name="PERF_VFD_ATTR_INFO_FIFO_FULL"/>
+	<value value="8" name="PERF_VFD_DECODED_ATTRIBUTE_BYTES"/>
+	<value value="9" name="PERF_VFD_NUM_ATTRIBUTES"/>
+	<value value="10" name="PERF_VFD_UPPER_SHADER_FIBERS"/>
+	<value value="11" name="PERF_VFD_LOWER_SHADER_FIBERS"/>
+	<value value="12" name="PERF_VFD_MODE_0_FIBERS"/>
+	<value value="13" name="PERF_VFD_MODE_1_FIBERS"/>
+	<value value="14" name="PERF_VFD_MODE_2_FIBERS"/>
+	<value value="15" name="PERF_VFD_MODE_3_FIBERS"/>
+	<value value="16" name="PERF_VFD_MODE_4_FIBERS"/>
+	<value value="17" name="PERF_VFD_TOTAL_VERTICES"/>
+	<value value="18" name="PERF_VFDP_STALL_CYCLES_VFD"/>
+	<value value="19" name="PERF_VFDP_STALL_CYCLES_VFD_INDEX"/>
+	<value value="20" name="PERF_VFDP_STALL_CYCLES_VFD_PROG"/>
+	<value value="21" name="PERF_VFDP_STARVE_CYCLES_PC"/>
+	<value value="22" name="PERF_VFDP_VS_STAGE_WAVES"/>
+</enum>
+
+<enum name="a6xx_hlsq_perfcounter_select">
+	<value value="0" name="PERF_HLSQ_BUSY_CYCLES"/>
+	<value value="1" name="PERF_HLSQ_STALL_CYCLES_UCHE"/>
+	<value value="2" name="PERF_HLSQ_STALL_CYCLES_SP_STATE"/>
+	<value value="3" name="PERF_HLSQ_STALL_CYCLES_SP_FS_STAGE"/>
+	<value value="4" name="PERF_HLSQ_UCHE_LATENCY_CYCLES"/>
+	<value value="5" name="PERF_HLSQ_UCHE_LATENCY_COUNT"/>
+	<value value="6" name="PERF_HLSQ_FS_STAGE_1X_WAVES"/>
+	<value value="7" name="PERF_HLSQ_FS_STAGE_2X_WAVES"/>
+	<value value="8" name="PERF_HLSQ_QUADS"/>
+	<value value="9" name="PERF_HLSQ_CS_INVOCATIONS"/>
+	<value value="10" name="PERF_HLSQ_COMPUTE_DRAWCALLS"/>
+	<value value="11" name="PERF_HLSQ_FS_DATA_WAIT_PROGRAMMING"/>
+	<value value="12" name="PERF_HLSQ_DUAL_FS_PROG_ACTIVE"/>
+	<value value="13" name="PERF_HLSQ_DUAL_VS_PROG_ACTIVE"/>
+	<value value="14" name="PERF_HLSQ_FS_BATCH_COUNT_ZERO"/>
+	<value value="15" name="PERF_HLSQ_VS_BATCH_COUNT_ZERO"/>
+	<value value="16" name="PERF_HLSQ_WAVE_PENDING_NO_QUAD"/>
+	<value value="17" name="PERF_HLSQ_WAVE_PENDING_NO_PRIM_BASE"/>
+	<value value="18" name="PERF_HLSQ_STALL_CYCLES_VPC"/>
+	<value value="19" name="PERF_HLSQ_PIXELS"/>
+	<value value="20" name="PERF_HLSQ_DRAW_MODE_SWITCH_VSFS_SYNC"/>
+</enum>
+
+<enum name="a6xx_vpc_perfcounter_select">
+	<value value="0" name="PERF_VPC_BUSY_CYCLES"/>
+	<value value="1" name="PERF_VPC_WORKING_CYCLES"/>
+	<value value="2" name="PERF_VPC_STALL_CYCLES_UCHE"/>
+	<value value="3" name="PERF_VPC_STALL_CYCLES_VFD_WACK"/>
+	<value value="4" name="PERF_VPC_STALL_CYCLES_HLSQ_PRIM_ALLOC"/>
+	<value value="5" name="PERF_VPC_STALL_CYCLES_PC"/>
+	<value value="6" name="PERF_VPC_STALL_CYCLES_SP_LM"/>
+	<value value="7" name="PERF_VPC_STARVE_CYCLES_SP"/>
+	<value value="8" name="PERF_VPC_STARVE_CYCLES_LRZ"/>
+	<value value="9" name="PERF_VPC_PC_PRIMITIVES"/>
+	<value value="10" name="PERF_VPC_SP_COMPONENTS"/>
+	<value value="11" name="PERF_VPC_STALL_CYCLES_VPCRAM_POS"/>
+	<value value="12" name="PERF_VPC_LRZ_ASSIGN_PRIMITIVES"/>
+	<value value="13" name="PERF_VPC_RB_VISIBLE_PRIMITIVES"/>
+	<value value="14" name="PERF_VPC_LM_TRANSACTION"/>
+	<value value="15" name="PERF_VPC_STREAMOUT_TRANSACTION"/>
+	<value value="16" name="PERF_VPC_VS_BUSY_CYCLES"/>
+	<value value="17" name="PERF_VPC_PS_BUSY_CYCLES"/>
+	<value value="18" name="PERF_VPC_VS_WORKING_CYCLES"/>
+	<value value="19" name="PERF_VPC_PS_WORKING_CYCLES"/>
+	<value value="20" name="PERF_VPC_STARVE_CYCLES_RB"/>
+	<value value="21" name="PERF_VPC_NUM_VPCRAM_READ_POS"/>
+	<value value="22" name="PERF_VPC_WIT_FULL_CYCLES"/>
+	<value value="23" name="PERF_VPC_VPCRAM_FULL_CYCLES"/>
+	<value value="24" name="PERF_VPC_LM_FULL_WAIT_FOR_INTP_END"/>
+	<value value="25" name="PERF_VPC_NUM_VPCRAM_WRITE"/>
+	<value value="26" name="PERF_VPC_NUM_VPCRAM_READ_SO"/>
+	<value value="27" name="PERF_VPC_NUM_ATTR_REQ_LM"/>
+</enum>
+
+<enum name="a6xx_tse_perfcounter_select">
+	<value value="0" name="PERF_TSE_BUSY_CYCLES"/>
+	<value value="1" name="PERF_TSE_CLIPPING_CYCLES"/>
+	<value value="2" name="PERF_TSE_STALL_CYCLES_RAS"/>
+	<value value="3" name="PERF_TSE_STALL_CYCLES_LRZ_BARYPLANE"/>
+	<value value="4" name="PERF_TSE_STALL_CYCLES_LRZ_ZPLANE"/>
+	<value value="5" name="PERF_TSE_STARVE_CYCLES_PC"/>
+	<value value="6" name="PERF_TSE_INPUT_PRIM"/>
+	<value value="7" name="PERF_TSE_INPUT_NULL_PRIM"/>
+	<value value="8" name="PERF_TSE_TRIVAL_REJ_PRIM"/>
+	<value value="9" name="PERF_TSE_CLIPPED_PRIM"/>
+	<value value="10" name="PERF_TSE_ZERO_AREA_PRIM"/>
+	<value value="11" name="PERF_TSE_FACENESS_CULLED_PRIM"/>
+	<value value="12" name="PERF_TSE_ZERO_PIXEL_PRIM"/>
+	<value value="13" name="PERF_TSE_OUTPUT_NULL_PRIM"/>
+	<value value="14" name="PERF_TSE_OUTPUT_VISIBLE_PRIM"/>
+	<value value="15" name="PERF_TSE_CINVOCATION"/>
+	<value value="16" name="PERF_TSE_CPRIMITIVES"/>
+	<value value="17" name="PERF_TSE_2D_INPUT_PRIM"/>
+	<value value="18" name="PERF_TSE_2D_ALIVE_CYCLES"/>
+	<value value="19" name="PERF_TSE_CLIP_PLANES"/>
+</enum>
+
+<enum name="a6xx_ras_perfcounter_select">
+	<value value="0" name="PERF_RAS_BUSY_CYCLES"/>
+	<value value="1" name="PERF_RAS_SUPERTILE_ACTIVE_CYCLES"/>
+	<value value="2" name="PERF_RAS_STALL_CYCLES_LRZ"/>
+	<value value="3" name="PERF_RAS_STARVE_CYCLES_TSE"/>
+	<value value="4" name="PERF_RAS_SUPER_TILES"/>
+	<value value="5" name="PERF_RAS_8X4_TILES"/>
+	<value value="6" name="PERF_RAS_MASKGEN_ACTIVE"/>
+	<value value="7" name="PERF_RAS_FULLY_COVERED_SUPER_TILES"/>
+	<value value="8" name="PERF_RAS_FULLY_COVERED_8X4_TILES"/>
+	<value value="9" name="PERF_RAS_PRIM_KILLED_INVISILBE"/>
+	<value value="10" name="PERF_RAS_SUPERTILE_GEN_ACTIVE_CYCLES"/>
+	<value value="11" name="PERF_RAS_LRZ_INTF_WORKING_CYCLES"/>
+	<value value="12" name="PERF_RAS_BLOCKS"/>
+</enum>
+
+<enum name="a6xx_uche_perfcounter_select">
+	<value value="0" name="PERF_UCHE_BUSY_CYCLES"/>
+	<value value="1" name="PERF_UCHE_STALL_CYCLES_ARBITER"/>
+	<value value="2" name="PERF_UCHE_VBIF_LATENCY_CYCLES"/>
+	<value value="3" name="PERF_UCHE_VBIF_LATENCY_SAMPLES"/>
+	<value value="4" name="PERF_UCHE_VBIF_READ_BEATS_TP"/>
+	<value value="5" name="PERF_UCHE_VBIF_READ_BEATS_VFD"/>
+	<value value="6" name="PERF_UCHE_VBIF_READ_BEATS_HLSQ"/>
+	<value value="7" name="PERF_UCHE_VBIF_READ_BEATS_LRZ"/>
+	<value value="8" name="PERF_UCHE_VBIF_READ_BEATS_SP"/>
+	<value value="9" name="PERF_UCHE_READ_REQUESTS_TP"/>
+	<value value="10" name="PERF_UCHE_READ_REQUESTS_VFD"/>
+	<value value="11" name="PERF_UCHE_READ_REQUESTS_HLSQ"/>
+	<value value="12" name="PERF_UCHE_READ_REQUESTS_LRZ"/>
+	<value value="13" name="PERF_UCHE_READ_REQUESTS_SP"/>
+	<value value="14" name="PERF_UCHE_WRITE_REQUESTS_LRZ"/>
+	<value value="15" name="PERF_UCHE_WRITE_REQUESTS_SP"/>
+	<value value="16" name="PERF_UCHE_WRITE_REQUESTS_VPC"/>
+	<value value="17" name="PERF_UCHE_WRITE_REQUESTS_VSC"/>
+	<value value="18" name="PERF_UCHE_EVICTS"/>
+	<value value="19" name="PERF_UCHE_BANK_REQ0"/>
+	<value value="20" name="PERF_UCHE_BANK_REQ1"/>
+	<value value="21" name="PERF_UCHE_BANK_REQ2"/>
+	<value value="22" name="PERF_UCHE_BANK_REQ3"/>
+	<value value="23" name="PERF_UCHE_BANK_REQ4"/>
+	<value value="24" name="PERF_UCHE_BANK_REQ5"/>
+	<value value="25" name="PERF_UCHE_BANK_REQ6"/>
+	<value value="26" name="PERF_UCHE_BANK_REQ7"/>
+	<value value="27" name="PERF_UCHE_VBIF_READ_BEATS_CH0"/>
+	<value value="28" name="PERF_UCHE_VBIF_READ_BEATS_CH1"/>
+	<value value="29" name="PERF_UCHE_GMEM_READ_BEATS"/>
+	<value value="30" name="PERF_UCHE_TPH_REF_FULL"/>
+	<value value="31" name="PERF_UCHE_TPH_VICTIM_FULL"/>
+	<value value="32" name="PERF_UCHE_TPH_EXT_FULL"/>
+	<value value="33" name="PERF_UCHE_VBIF_STALL_WRITE_DATA"/>
+	<value value="34" name="PERF_UCHE_DCMP_LATENCY_SAMPLES"/>
+	<value value="35" name="PERF_UCHE_DCMP_LATENCY_CYCLES"/>
+	<value value="36" name="PERF_UCHE_VBIF_READ_BEATS_PC"/>
+	<value value="37" name="PERF_UCHE_READ_REQUESTS_PC"/>
+	<value value="38" name="PERF_UCHE_RAM_READ_REQ"/>
+	<value value="39" name="PERF_UCHE_RAM_WRITE_REQ"/>
+</enum>
+
+<enum name="a6xx_tp_perfcounter_select">
+	<value value="0" name="PERF_TP_BUSY_CYCLES"/>
+	<value value="1" name="PERF_TP_STALL_CYCLES_UCHE"/>
+	<value value="2" name="PERF_TP_LATENCY_CYCLES"/>
+	<value value="3" name="PERF_TP_LATENCY_TRANS"/>
+	<value value="4" name="PERF_TP_FLAG_CACHE_REQUEST_SAMPLES"/>
+	<value value="5" name="PERF_TP_FLAG_CACHE_REQUEST_LATENCY"/>
+	<value value="6" name="PERF_TP_L1_CACHELINE_REQUESTS"/>
+	<value value="7" name="PERF_TP_L1_CACHELINE_MISSES"/>
+	<value value="8" name="PERF_TP_SP_TP_TRANS"/>
+	<value value="9" name="PERF_TP_TP_SP_TRANS"/>
+	<value value="10" name="PERF_TP_OUTPUT_PIXELS"/>
+	<value value="11" name="PERF_TP_FILTER_WORKLOAD_16BIT"/>
+	<value value="12" name="PERF_TP_FILTER_WORKLOAD_32BIT"/>
+	<value value="13" name="PERF_TP_QUADS_RECEIVED"/>
+	<value value="14" name="PERF_TP_QUADS_OFFSET"/>
+	<value value="15" name="PERF_TP_QUADS_SHADOW"/>
+	<value value="16" name="PERF_TP_QUADS_ARRAY"/>
+	<value value="17" name="PERF_TP_QUADS_GRADIENT"/>
+	<value value="18" name="PERF_TP_QUADS_1D"/>
+	<value value="19" name="PERF_TP_QUADS_2D"/>
+	<value value="20" name="PERF_TP_QUADS_BUFFER"/>
+	<value value="21" name="PERF_TP_QUADS_3D"/>
+	<value value="22" name="PERF_TP_QUADS_CUBE"/>
+	<value value="23" name="PERF_TP_DIVERGENT_QUADS_RECEIVED"/>
+	<value value="24" name="PERF_TP_PRT_NON_RESIDENT_EVENTS"/>
+	<value value="25" name="PERF_TP_OUTPUT_PIXELS_POINT"/>
+	<value value="26" name="PERF_TP_OUTPUT_PIXELS_BILINEAR"/>
+	<value value="27" name="PERF_TP_OUTPUT_PIXELS_MIP"/>
+	<value value="28" name="PERF_TP_OUTPUT_PIXELS_ANISO"/>
+	<value value="29" name="PERF_TP_OUTPUT_PIXELS_ZERO_LOD"/>
+	<value value="30" name="PERF_TP_FLAG_CACHE_REQUESTS"/>
+	<value value="31" name="PERF_TP_FLAG_CACHE_MISSES"/>
+	<value value="32" name="PERF_TP_L1_5_L2_REQUESTS"/>
+	<value value="33" name="PERF_TP_2D_OUTPUT_PIXELS"/>
+	<value value="34" name="PERF_TP_2D_OUTPUT_PIXELS_POINT"/>
+	<value value="35" name="PERF_TP_2D_OUTPUT_PIXELS_BILINEAR"/>
+	<value value="36" name="PERF_TP_2D_FILTER_WORKLOAD_16BIT"/>
+	<value value="37" name="PERF_TP_2D_FILTER_WORKLOAD_32BIT"/>
+	<value value="38" name="PERF_TP_TPA2TPC_TRANS"/>
+	<value value="39" name="PERF_TP_L1_MISSES_ASTC_1TILE"/>
+	<value value="40" name="PERF_TP_L1_MISSES_ASTC_2TILE"/>
+	<value value="41" name="PERF_TP_L1_MISSES_ASTC_4TILE"/>
+	<value value="42" name="PERF_TP_L1_5_L2_COMPRESS_REQS"/>
+	<value value="43" name="PERF_TP_L1_5_L2_COMPRESS_MISS"/>
+	<value value="44" name="PERF_TP_L1_BANK_CONFLICT"/>
+	<value value="45" name="PERF_TP_L1_5_MISS_LATENCY_CYCLES"/>
+	<value value="46" name="PERF_TP_L1_5_MISS_LATENCY_TRANS"/>
+	<value value="47" name="PERF_TP_QUADS_CONSTANT_MULTIPLIED"/>
+	<value value="48" name="PERF_TP_FRONTEND_WORKING_CYCLES"/>
+	<value value="49" name="PERF_TP_L1_TAG_WORKING_CYCLES"/>
+	<value value="50" name="PERF_TP_L1_DATA_WRITE_WORKING_CYCLES"/>
+	<value value="51" name="PERF_TP_PRE_L1_DECOM_WORKING_CYCLES"/>
+	<value value="52" name="PERF_TP_BACKEND_WORKING_CYCLES"/>
+	<value value="53" name="PERF_TP_FLAG_CACHE_WORKING_CYCLES"/>
+	<value value="54" name="PERF_TP_L1_5_CACHE_WORKING_CYCLES"/>
+	<value value="55" name="PERF_TP_STARVE_CYCLES_SP"/>
+	<value value="56" name="PERF_TP_STARVE_CYCLES_UCHE"/>
+</enum>
+
+<enum name="a6xx_sp_perfcounter_select">
+	<value value="0" name="PERF_SP_BUSY_CYCLES"/>
+	<value value="1" name="PERF_SP_ALU_WORKING_CYCLES"/>
+	<value value="2" name="PERF_SP_EFU_WORKING_CYCLES"/>
+	<value value="3" name="PERF_SP_STALL_CYCLES_VPC"/>
+	<value value="4" name="PERF_SP_STALL_CYCLES_TP"/>
+	<value value="5" name="PERF_SP_STALL_CYCLES_UCHE"/>
+	<value value="6" name="PERF_SP_STALL_CYCLES_RB"/>
+	<value value="7" name="PERF_SP_NON_EXECUTION_CYCLES"/>
+	<value value="8" name="PERF_SP_WAVE_CONTEXTS"/>
+	<value value="9" name="PERF_SP_WAVE_CONTEXT_CYCLES"/>
+	<value value="10" name="PERF_SP_FS_STAGE_WAVE_CYCLES"/>
+	<value value="11" name="PERF_SP_FS_STAGE_WAVE_SAMPLES"/>
+	<value value="12" name="PERF_SP_VS_STAGE_WAVE_CYCLES"/>
+	<value value="13" name="PERF_SP_VS_STAGE_WAVE_SAMPLES"/>
+	<value value="14" name="PERF_SP_FS_STAGE_DURATION_CYCLES"/>
+	<value value="15" name="PERF_SP_VS_STAGE_DURATION_CYCLES"/>
+	<value value="16" name="PERF_SP_WAVE_CTRL_CYCLES"/>
+	<value value="17" name="PERF_SP_WAVE_LOAD_CYCLES"/>
+	<value value="18" name="PERF_SP_WAVE_EMIT_CYCLES"/>
+	<value value="19" name="PERF_SP_WAVE_NOP_CYCLES"/>
+	<value value="20" name="PERF_SP_WAVE_WAIT_CYCLES"/>
+	<value value="21" name="PERF_SP_WAVE_FETCH_CYCLES"/>
+	<value value="22" name="PERF_SP_WAVE_IDLE_CYCLES"/>
+	<value value="23" name="PERF_SP_WAVE_END_CYCLES"/>
+	<value value="24" name="PERF_SP_WAVE_LONG_SYNC_CYCLES"/>
+	<value value="25" name="PERF_SP_WAVE_SHORT_SYNC_CYCLES"/>
+	<value value="26" name="PERF_SP_WAVE_JOIN_CYCLES"/>
+	<value value="27" name="PERF_SP_LM_LOAD_INSTRUCTIONS"/>
+	<value value="28" name="PERF_SP_LM_STORE_INSTRUCTIONS"/>
+	<value value="29" name="PERF_SP_LM_ATOMICS"/>
+	<value value="30" name="PERF_SP_GM_LOAD_INSTRUCTIONS"/>
+	<value value="31" name="PERF_SP_GM_STORE_INSTRUCTIONS"/>
+	<value value="32" name="PERF_SP_GM_ATOMICS"/>
+	<value value="33" name="PERF_SP_VS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="34" name="PERF_SP_VS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="35" name="PERF_SP_VS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="36" name="PERF_SP_VS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="37" name="PERF_SP_FS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="38" name="PERF_SP_FS_STAGE_CFLOW_INSTRUCTIONS"/>
+	<value value="39" name="PERF_SP_FS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="40" name="PERF_SP_FS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="41" name="PERF_SP_FS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="42" name="PERF_SP_FS_STAGE_BARY_INSTRUCTIONS"/>
+	<value value="43" name="PERF_SP_VS_INSTRUCTIONS"/>
+	<value value="44" name="PERF_SP_FS_INSTRUCTIONS"/>
+	<value value="45" name="PERF_SP_ADDR_LOCK_COUNT"/>
+	<value value="46" name="PERF_SP_UCHE_READ_TRANS"/>
+	<value value="47" name="PERF_SP_UCHE_WRITE_TRANS"/>
+	<value value="48" name="PERF_SP_EXPORT_VPC_TRANS"/>
+	<value value="49" name="PERF_SP_EXPORT_RB_TRANS"/>
+	<value value="50" name="PERF_SP_PIXELS_KILLED"/>
+	<value value="51" name="PERF_SP_ICL1_REQUESTS"/>
+	<value value="52" name="PERF_SP_ICL1_MISSES"/>
+	<value value="53" name="PERF_SP_HS_INSTRUCTIONS"/>
+	<value value="54" name="PERF_SP_DS_INSTRUCTIONS"/>
+	<value value="55" name="PERF_SP_GS_INSTRUCTIONS"/>
+	<value value="56" name="PERF_SP_CS_INSTRUCTIONS"/>
+	<value value="57" name="PERF_SP_GPR_READ"/>
+	<value value="58" name="PERF_SP_GPR_WRITE"/>
+	<value value="59" name="PERF_SP_FS_STAGE_HALF_EFU_INSTRUCTIONS"/>
+	<value value="60" name="PERF_SP_VS_STAGE_HALF_EFU_INSTRUCTIONS"/>
+	<value value="61" name="PERF_SP_LM_BANK_CONFLICTS"/>
+	<value value="62" name="PERF_SP_TEX_CONTROL_WORKING_CYCLES"/>
+	<value value="63" name="PERF_SP_LOAD_CONTROL_WORKING_CYCLES"/>
+	<value value="64" name="PERF_SP_FLOW_CONTROL_WORKING_CYCLES"/>
+	<value value="65" name="PERF_SP_LM_WORKING_CYCLES"/>
+	<value value="66" name="PERF_SP_DISPATCHER_WORKING_CYCLES"/>
+	<value value="67" name="PERF_SP_SEQUENCER_WORKING_CYCLES"/>
+	<value value="68" name="PERF_SP_LOW_EFFICIENCY_STARVED_BY_TP"/>
+	<value value="69" name="PERF_SP_STARVE_CYCLES_HLSQ"/>
+	<value value="70" name="PERF_SP_NON_EXECUTION_LS_CYCLES"/>
+	<value value="71" name="PERF_SP_WORKING_EU"/>
+	<value value="72" name="PERF_SP_ANY_EU_WORKING"/>
+	<value value="73" name="PERF_SP_WORKING_EU_FS_STAGE"/>
+	<value value="74" name="PERF_SP_ANY_EU_WORKING_FS_STAGE"/>
+	<value value="75" name="PERF_SP_WORKING_EU_VS_STAGE"/>
+	<value value="76" name="PERF_SP_ANY_EU_WORKING_VS_STAGE"/>
+	<value value="77" name="PERF_SP_WORKING_EU_CS_STAGE"/>
+	<value value="78" name="PERF_SP_ANY_EU_WORKING_CS_STAGE"/>
+	<value value="79" name="PERF_SP_GPR_READ_PREFETCH"/>
+	<value value="80" name="PERF_SP_GPR_READ_CONFLICT"/>
+	<value value="81" name="PERF_SP_GPR_WRITE_CONFLICT"/>
+	<value value="82" name="PERF_SP_GM_LOAD_LATENCY_CYCLES"/>
+	<value value="83" name="PERF_SP_GM_LOAD_LATENCY_SAMPLES"/>
+	<value value="84" name="PERF_SP_EXECUTABLE_WAVES"/>
+</enum>
+
+<enum name="a6xx_rb_perfcounter_select">
+	<value value="0" name="PERF_RB_BUSY_CYCLES"/>
+	<value value="1" name="PERF_RB_STALL_CYCLES_HLSQ"/>
+	<value value="2" name="PERF_RB_STALL_CYCLES_FIFO0_FULL"/>
+	<value value="3" name="PERF_RB_STALL_CYCLES_FIFO1_FULL"/>
+	<value value="4" name="PERF_RB_STALL_CYCLES_FIFO2_FULL"/>
+	<value value="5" name="PERF_RB_STARVE_CYCLES_SP"/>
+	<value value="6" name="PERF_RB_STARVE_CYCLES_LRZ_TILE"/>
+	<value value="7" name="PERF_RB_STARVE_CYCLES_CCU"/>
+	<value value="8" name="PERF_RB_STARVE_CYCLES_Z_PLANE"/>
+	<value value="9" name="PERF_RB_STARVE_CYCLES_BARY_PLANE"/>
+	<value value="10" name="PERF_RB_Z_WORKLOAD"/>
+	<value value="11" name="PERF_RB_HLSQ_ACTIVE"/>
+	<value value="12" name="PERF_RB_Z_READ"/>
+	<value value="13" name="PERF_RB_Z_WRITE"/>
+	<value value="14" name="PERF_RB_C_READ"/>
+	<value value="15" name="PERF_RB_C_WRITE"/>
+	<value value="16" name="PERF_RB_TOTAL_PASS"/>
+	<value value="17" name="PERF_RB_Z_PASS"/>
+	<value value="18" name="PERF_RB_Z_FAIL"/>
+	<value value="19" name="PERF_RB_S_FAIL"/>
+	<value value="20" name="PERF_RB_BLENDED_FXP_COMPONENTS"/>
+	<value value="21" name="PERF_RB_BLENDED_FP16_COMPONENTS"/>
+	<value value="22" name="PERF_RB_PS_INVOCATIONS"/>
+	<value value="23" name="PERF_RB_2D_ALIVE_CYCLES"/>
+	<value value="24" name="PERF_RB_2D_STALL_CYCLES_A2D"/>
+	<value value="25" name="PERF_RB_2D_STARVE_CYCLES_SRC"/>
+	<value value="26" name="PERF_RB_2D_STARVE_CYCLES_SP"/>
+	<value value="27" name="PERF_RB_2D_STARVE_CYCLES_DST"/>
+	<value value="28" name="PERF_RB_2D_VALID_PIXELS"/>
+	<value value="29" name="PERF_RB_3D_PIXELS"/>
+	<value value="30" name="PERF_RB_BLENDER_WORKING_CYCLES"/>
+	<value value="31" name="PERF_RB_ZPROC_WORKING_CYCLES"/>
+	<value value="32" name="PERF_RB_CPROC_WORKING_CYCLES"/>
+	<value value="33" name="PERF_RB_SAMPLER_WORKING_CYCLES"/>
+	<value value="34" name="PERF_RB_STALL_CYCLES_CCU_COLOR_READ"/>
+	<value value="35" name="PERF_RB_STALL_CYCLES_CCU_COLOR_WRITE"/>
+	<value value="36" name="PERF_RB_STALL_CYCLES_CCU_DEPTH_READ"/>
+	<value value="37" name="PERF_RB_STALL_CYCLES_CCU_DEPTH_WRITE"/>
+	<value value="38" name="PERF_RB_STALL_CYCLES_VPC"/>
+	<value value="39" name="PERF_RB_2D_INPUT_TRANS"/>
+	<value value="40" name="PERF_RB_2D_OUTPUT_RB_DST_TRANS"/>
+	<value value="41" name="PERF_RB_2D_OUTPUT_RB_SRC_TRANS"/>
+	<value value="42" name="PERF_RB_BLENDED_FP32_COMPONENTS"/>
+	<value value="43" name="PERF_RB_COLOR_PIX_TILES"/>
+	<value value="44" name="PERF_RB_STALL_CYCLES_CCU"/>
+	<value value="45" name="PERF_RB_EARLY_Z_ARB3_GRANT"/>
+	<value value="46" name="PERF_RB_LATE_Z_ARB3_GRANT"/>
+	<value value="47" name="PERF_RB_EARLY_Z_SKIP_GRANT"/>
+</enum>
+
+<enum name="a6xx_vsc_perfcounter_select">
+	<value value="0" name="PERF_VSC_BUSY_CYCLES"/>
+	<value value="1" name="PERF_VSC_WORKING_CYCLES"/>
+	<value value="2" name="PERF_VSC_STALL_CYCLES_UCHE"/>
+	<value value="3" name="PERF_VSC_EOT_NUM"/>
+	<value value="4" name="PERF_VSC_INPUT_TILES"/>
+</enum>
+
+<enum name="a6xx_ccu_perfcounter_select">
+	<value value="0" name="PERF_CCU_BUSY_CYCLES"/>
+	<value value="1" name="PERF_CCU_STALL_CYCLES_RB_DEPTH_RETURN"/>
+	<value value="2" name="PERF_CCU_STALL_CYCLES_RB_COLOR_RETURN"/>
+	<value value="3" name="PERF_CCU_STARVE_CYCLES_FLAG_RETURN"/>
+	<value value="4" name="PERF_CCU_DEPTH_BLOCKS"/>
+	<value value="5" name="PERF_CCU_COLOR_BLOCKS"/>
+	<value value="6" name="PERF_CCU_DEPTH_BLOCK_HIT"/>
+	<value value="7" name="PERF_CCU_COLOR_BLOCK_HIT"/>
+	<value value="8" name="PERF_CCU_PARTIAL_BLOCK_READ"/>
+	<value value="9" name="PERF_CCU_GMEM_READ"/>
+	<value value="10" name="PERF_CCU_GMEM_WRITE"/>
+	<value value="11" name="PERF_CCU_DEPTH_READ_FLAG0_COUNT"/>
+	<value value="12" name="PERF_CCU_DEPTH_READ_FLAG1_COUNT"/>
+	<value value="13" name="PERF_CCU_DEPTH_READ_FLAG2_COUNT"/>
+	<value value="14" name="PERF_CCU_DEPTH_READ_FLAG3_COUNT"/>
+	<value value="15" name="PERF_CCU_DEPTH_READ_FLAG4_COUNT"/>
+	<value value="16" name="PERF_CCU_DEPTH_READ_FLAG5_COUNT"/>
+	<value value="17" name="PERF_CCU_DEPTH_READ_FLAG6_COUNT"/>
+	<value value="18" name="PERF_CCU_DEPTH_READ_FLAG8_COUNT"/>
+	<value value="19" name="PERF_CCU_COLOR_READ_FLAG0_COUNT"/>
+	<value value="20" name="PERF_CCU_COLOR_READ_FLAG1_COUNT"/>
+	<value value="21" name="PERF_CCU_COLOR_READ_FLAG2_COUNT"/>
+	<value value="22" name="PERF_CCU_COLOR_READ_FLAG3_COUNT"/>
+	<value value="23" name="PERF_CCU_COLOR_READ_FLAG4_COUNT"/>
+	<value value="24" name="PERF_CCU_COLOR_READ_FLAG5_COUNT"/>
+	<value value="25" name="PERF_CCU_COLOR_READ_FLAG6_COUNT"/>
+	<value value="26" name="PERF_CCU_COLOR_READ_FLAG8_COUNT"/>
+	<value value="27" name="PERF_CCU_2D_RD_REQ"/>
+	<value value="28" name="PERF_CCU_2D_WR_REQ"/>
+</enum>
+
+<enum name="a6xx_lrz_perfcounter_select">
+	<value value="0" name="PERF_LRZ_BUSY_CYCLES"/>
+	<value value="1" name="PERF_LRZ_STARVE_CYCLES_RAS"/>
+	<value value="2" name="PERF_LRZ_STALL_CYCLES_RB"/>
+	<value value="3" name="PERF_LRZ_STALL_CYCLES_VSC"/>
+	<value value="4" name="PERF_LRZ_STALL_CYCLES_VPC"/>
+	<value value="5" name="PERF_LRZ_STALL_CYCLES_FLAG_PREFETCH"/>
+	<value value="6" name="PERF_LRZ_STALL_CYCLES_UCHE"/>
+	<value value="7" name="PERF_LRZ_LRZ_READ"/>
+	<value value="8" name="PERF_LRZ_LRZ_WRITE"/>
+	<value value="9" name="PERF_LRZ_READ_LATENCY"/>
+	<value value="10" name="PERF_LRZ_MERGE_CACHE_UPDATING"/>
+	<value value="11" name="PERF_LRZ_PRIM_KILLED_BY_MASKGEN"/>
+	<value value="12" name="PERF_LRZ_PRIM_KILLED_BY_LRZ"/>
+	<value value="13" name="PERF_LRZ_VISIBLE_PRIM_AFTER_LRZ"/>
+	<value value="14" name="PERF_LRZ_FULL_8X8_TILES"/>
+	<value value="15" name="PERF_LRZ_PARTIAL_8X8_TILES"/>
+	<value value="16" name="PERF_LRZ_TILE_KILLED"/>
+	<value value="17" name="PERF_LRZ_TOTAL_PIXEL"/>
+	<value value="18" name="PERF_LRZ_VISIBLE_PIXEL_AFTER_LRZ"/>
+	<value value="19" name="PERF_LRZ_FULLY_COVERED_TILES"/>
+	<value value="20" name="PERF_LRZ_PARTIAL_COVERED_TILES"/>
+	<value value="21" name="PERF_LRZ_FEEDBACK_ACCEPT"/>
+	<value value="22" name="PERF_LRZ_FEEDBACK_DISCARD"/>
+	<value value="23" name="PERF_LRZ_FEEDBACK_STALL"/>
+	<value value="24" name="PERF_LRZ_STALL_CYCLES_RB_ZPLANE"/>
+	<value value="25" name="PERF_LRZ_STALL_CYCLES_RB_BPLANE"/>
+	<value value="26" name="PERF_LRZ_STALL_CYCLES_VC"/>
+	<value value="27" name="PERF_LRZ_RAS_MASK_TRANS"/>
+</enum>
+
+<enum name="a6xx_cmp_perfcounter_select">
+	<value value="0" name="PERF_CMPDECMP_STALL_CYCLES_ARB"/>
+	<value value="1" name="PERF_CMPDECMP_VBIF_LATENCY_CYCLES"/>
+	<value value="2" name="PERF_CMPDECMP_VBIF_LATENCY_SAMPLES"/>
+	<value value="3" name="PERF_CMPDECMP_VBIF_READ_DATA_CCU"/>
+	<value value="4" name="PERF_CMPDECMP_VBIF_WRITE_DATA_CCU"/>
+	<value value="5" name="PERF_CMPDECMP_VBIF_READ_REQUEST"/>
+	<value value="6" name="PERF_CMPDECMP_VBIF_WRITE_REQUEST"/>
+	<value value="7" name="PERF_CMPDECMP_VBIF_READ_DATA"/>
+	<value value="8" name="PERF_CMPDECMP_VBIF_WRITE_DATA"/>
+	<value value="9" name="PERF_CMPDECMP_FLAG_FETCH_CYCLES"/>
+	<value value="10" name="PERF_CMPDECMP_FLAG_FETCH_SAMPLES"/>
+	<value value="11" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG1_COUNT"/>
+	<value value="12" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG2_COUNT"/>
+	<value value="13" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG3_COUNT"/>
+	<value value="14" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG4_COUNT"/>
+	<value value="15" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG5_COUNT"/>
+	<value value="16" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG6_COUNT"/>
+	<value value="17" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG8_COUNT"/>
+	<value value="18" name="PERF_CMPDECMP_COLOR_WRITE_FLAG1_COUNT"/>
+	<value value="19" name="PERF_CMPDECMP_COLOR_WRITE_FLAG2_COUNT"/>
+	<value value="20" name="PERF_CMPDECMP_COLOR_WRITE_FLAG3_COUNT"/>
+	<value value="21" name="PERF_CMPDECMP_COLOR_WRITE_FLAG4_COUNT"/>
+	<value value="22" name="PERF_CMPDECMP_COLOR_WRITE_FLAG5_COUNT"/>
+	<value value="23" name="PERF_CMPDECMP_COLOR_WRITE_FLAG6_COUNT"/>
+	<value value="24" name="PERF_CMPDECMP_COLOR_WRITE_FLAG8_COUNT"/>
+	<value value="25" name="PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_REQ"/>
+	<value value="26" name="PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_WR"/>
+	<value value="27" name="PERF_CMPDECMP_2D_STALL_CYCLES_VBIF_RETURN"/>
+	<value value="28" name="PERF_CMPDECMP_2D_RD_DATA"/>
+	<value value="29" name="PERF_CMPDECMP_2D_WR_DATA"/>
+	<value value="30" name="PERF_CMPDECMP_VBIF_READ_DATA_UCHE_CH0"/>
+	<value value="31" name="PERF_CMPDECMP_VBIF_READ_DATA_UCHE_CH1"/>
+	<value value="32" name="PERF_CMPDECMP_2D_OUTPUT_TRANS"/>
+	<value value="33" name="PERF_CMPDECMP_VBIF_WRITE_DATA_UCHE"/>
+	<value value="34" name="PERF_CMPDECMP_DEPTH_WRITE_FLAG0_COUNT"/>
+	<value value="35" name="PERF_CMPDECMP_COLOR_WRITE_FLAG0_COUNT"/>
+	<value value="36" name="PERF_CMPDECMP_COLOR_WRITE_FLAGALPHA_COUNT"/>
+	<value value="37" name="PERF_CMPDECMP_2D_BUSY_CYCLES"/>
+	<value value="38" name="PERF_CMPDECMP_2D_REORDER_STARVE_CYCLES"/>
+	<value value="39" name="PERF_CMPDECMP_2D_PIXELS"/>
+</enum>
+
+<!--
+Used in a6xx_2d_blit_cntl.. the value mostly seems to correlate to the
+component type/size, so I think it relates to internal format used for
+blending?  The one exception is that 16b unorm and 32b float use the
+same value... maybe 16b unorm is uncommon enough that it was just easier
+to upconvert to 32b float internally?
+
+ 8b unorm:  10 (sometimes 0, is the high bit part of something else?)
+16b unorm:   4
+
+32b int:     7
+16b int:     6
+ 8b int:     5
+
+32b float:   4
+16b float:   3
+ -->
+<enum name="a6xx_2d_ifmt">
+	<value value="0x10" name="R2D_UNORM8"/>
+	<value value="0x7"  name="R2D_INT32"/>
+	<value value="0x6"  name="R2D_INT16"/>
+	<value value="0x5"  name="R2D_INT8"/>
+	<value value="0x4"  name="R2D_FLOAT32"/>
+	<value value="0x3"  name="R2D_FLOAT16"/>
+	<value value="0x1"  name="R2D_UNORM8_SRGB"/>
+	<value value="0x0"  name="R2D_RAW"/>
+</enum>
+
+<enum name="a6xx_ztest_mode">
+	<doc>Allow early z-test and early-lrz (if applicable)</doc>
+	<value value="0x0" name="A6XX_EARLY_Z"/>
+	<doc>Disable early z-test and early-lrz test (if applicable)</doc>
+	<value value="0x1" name="A6XX_LATE_Z"/>
+	<doc>
+		A special mode that allows early-lrz test but disables
+		early-z test.  Which might sound a bit funny, since
+		lrz-test happens before z-test.  But as long as a couple
+		conditions are maintained this allows using lrz-test in
+		cases where fragment shader has kill/discard:
+
+		1) Disable lrz-write in cases where it is uncertain during
+		   binning pass that a fragment will pass.  Ie.  if frag
+		   shader has-kill, writes-z, or alpha/stencil test is
+		   enabled.  (For correctness, lrz-write must be disabled
+		   when blend is enabled.)  This is analogous to how a
+		   z-prepass works.
+
+		2) Disable lrz-write and test if a depth-test direction
+		   reversal is detected.  Due to condition (1), the contents
+		   of the lrz buffer are a conservative estimation of the
+		   depth buffer during the draw pass.  Meaning that geometry
+		   that we know for certain will not be visible will not pass
+		   lrz-test.  But geometry which may be (or contributes to
+		   blend) will pass the lrz-test.
+
+		This allows us to keep early-lrz-test in cases where the frag
+		shader does not write-z (ie. we know the z-value before FS)
+		and does not have side-effects (image/ssbo writes, etc), but
+		does have kill/discard.  Which turns out to be a common
+		enough case that it is useful to keep early-lrz test against
+		the conservative lrz buffer to discard fragments that we
+		know will definitely not be visible.
+	</doc>
+	<value value="0x2" name="A6XX_EARLY_LRZ_LATE_Z"/>
+	<doc>Not a real hw value, used internally by mesa</doc>
+	<value value="0x3" name="A6XX_INVALID_ZTEST"/>
+</enum>
+
+<enum name="a6xx_tess_spacing">
+	<value value="0x0" name="TESS_EQUAL"/>
+	<value value="0x2" name="TESS_FRACTIONAL_ODD"/>
+	<value value="0x3" name="TESS_FRACTIONAL_EVEN"/>
+</enum>
+<enum name="a6xx_tess_output">
+	<value value="0x0" name="TESS_POINTS"/>
+	<value value="0x1" name="TESS_LINES"/>
+	<value value="0x2" name="TESS_CW_TRIS"/>
+	<value value="0x3" name="TESS_CCW_TRIS"/>
+</enum>
+
+<enum name="a7xx_cp_perfcounter_select">
+	<value value="0" name="A7XX_PERF_CP_ALWAYS_COUNT"/>
+	<value value="1" name="A7XX_PERF_CP_BUSY_GFX_CORE_IDLE"/>
+	<value value="2" name="A7XX_PERF_CP_BUSY_CYCLES"/>
+	<value value="3" name="A7XX_PERF_CP_NUM_PREEMPTIONS"/>
+	<value value="4" name="A7XX_PERF_CP_PREEMPTION_REACTION_DELAY"/>
+	<value value="5" name="A7XX_PERF_CP_PREEMPTION_SWITCH_OUT_TIME"/>
+	<value value="6" name="A7XX_PERF_CP_PREEMPTION_SWITCH_IN_TIME"/>
+	<value value="7" name="A7XX_PERF_CP_DEAD_DRAWS_IN_BIN_RENDER"/>
+	<value value="8" name="A7XX_PERF_CP_PREDICATED_DRAWS_KILLED"/>
+	<value value="9" name="A7XX_PERF_CP_MODE_SWITCH"/>
+	<value value="10" name="A7XX_PERF_CP_ZPASS_DONE"/>
+	<value value="11" name="A7XX_PERF_CP_CONTEXT_DONE"/>
+	<value value="12" name="A7XX_PERF_CP_CACHE_FLUSH"/>
+	<value value="13" name="A7XX_PERF_CP_LONG_PREEMPTIONS"/>
+	<value value="14" name="A7XX_PERF_CP_SQE_I_CACHE_STARVE"/>
+	<value value="15" name="A7XX_PERF_CP_SQE_IDLE"/>
+	<value value="16" name="A7XX_PERF_CP_SQE_PM4_STARVE_RB_IB"/>
+	<value value="17" name="A7XX_PERF_CP_SQE_PM4_STARVE_SDS"/>
+	<value value="18" name="A7XX_PERF_CP_SQE_MRB_STARVE"/>
+	<value value="19" name="A7XX_PERF_CP_SQE_RRB_STARVE"/>
+	<value value="20" name="A7XX_PERF_CP_SQE_VSD_STARVE"/>
+	<value value="21" name="A7XX_PERF_CP_VSD_DECODE_STARVE"/>
+	<value value="22" name="A7XX_PERF_CP_SQE_PIPE_OUT_STALL"/>
+	<value value="23" name="A7XX_PERF_CP_SQE_SYNC_STALL"/>
+	<value value="24" name="A7XX_PERF_CP_SQE_PM4_WFI_STALL"/>
+	<value value="25" name="A7XX_PERF_CP_SQE_SYS_WFI_STALL"/>
+	<value value="26" name="A7XX_PERF_CP_SQE_T4_EXEC"/>
+	<value value="27" name="A7XX_PERF_CP_SQE_LOAD_STATE_EXEC"/>
+	<value value="28" name="A7XX_PERF_CP_SQE_SAVE_SDS_STATE"/>
+	<value value="29" name="A7XX_PERF_CP_SQE_DRAW_EXEC"/>
+	<value value="30" name="A7XX_PERF_CP_SQE_CTXT_REG_BUNCH_EXEC"/>
+	<value value="31" name="A7XX_PERF_CP_SQE_EXEC_PROFILED"/>
+	<value value="32" name="A7XX_PERF_CP_MEMORY_POOL_EMPTY"/>
+	<value value="33" name="A7XX_PERF_CP_MEMORY_POOL_SYNC_STALL"/>
+	<value value="34" name="A7XX_PERF_CP_MEMORY_POOL_ABOVE_THRESH"/>
+	<value value="35" name="A7XX_PERF_CP_AHB_WR_STALL_PRE_DRAWS"/>
+	<value value="36" name="A7XX_PERF_CP_AHB_STALL_SQE_GMU"/>
+	<value value="37" name="A7XX_PERF_CP_AHB_STALL_SQE_WR_OTHER"/>
+	<value value="38" name="A7XX_PERF_CP_AHB_STALL_SQE_RD_OTHER"/>
+	<value value="39" name="A7XX_PERF_CP_CLUSTER0_EMPTY"/>
+	<value value="40" name="A7XX_PERF_CP_CLUSTER1_EMPTY"/>
+	<value value="41" name="A7XX_PERF_CP_CLUSTER2_EMPTY"/>
+	<value value="42" name="A7XX_PERF_CP_CLUSTER3_EMPTY"/>
+	<value value="43" name="A7XX_PERF_CP_CLUSTER4_EMPTY"/>
+	<value value="44" name="A7XX_PERF_CP_CLUSTER5_EMPTY"/>
+	<value value="45" name="A7XX_PERF_CP_PM4_DATA"/>
+	<value value="46" name="A7XX_PERF_CP_PM4_HEADERS"/>
+	<value value="47" name="A7XX_PERF_CP_VBIF_READ_BEATS"/>
+	<value value="48" name="A7XX_PERF_CP_VBIF_WRITE_BEATS"/>
+	<value value="49" name="A7XX_PERF_CP_SQE_INSTR_COUNTER"/>
+	<value value="50" name="A7XX_PERF_CP_RESERVED_50"/>
+	<value value="51" name="A7XX_PERF_CP_RESERVED_51"/>
+	<value value="52" name="A7XX_PERF_CP_RESERVED_52"/>
+	<value value="53" name="A7XX_PERF_CP_RESERVED_53"/>
+	<value value="54" name="A7XX_PERF_CP_RESERVED_54"/>
+	<value value="55" name="A7XX_PERF_CP_RESERVED_55"/>
+	<value value="56" name="A7XX_PERF_CP_RESERVED_56"/>
+	<value value="57" name="A7XX_PERF_CP_RESERVED_57"/>
+	<value value="58" name="A7XX_PERF_CP_RESERVED_58"/>
+	<value value="59" name="A7XX_PERF_CP_RESERVED_59"/>
+	<value value="60" name="A7XX_PERF_CP_CLUSTER0_FULL"/>
+	<value value="61" name="A7XX_PERF_CP_CLUSTER1_FULL"/>
+	<value value="62" name="A7XX_PERF_CP_CLUSTER2_FULL"/>
+	<value value="63" name="A7XX_PERF_CP_CLUSTER3_FULL"/>
+	<value value="64" name="A7XX_PERF_CP_CLUSTER4_FULL"/>
+	<value value="65" name="A7XX_PERF_CP_CLUSTER5_FULL"/>
+	<value value="66" name="A7XX_PERF_CP_CLUSTER6_FULL"/>
+	<value value="67" name="A7XX_PERF_CP_CLUSTER6_EMPTY"/>
+	<value value="68" name="A7XX_PERF_CP_ICACHE_MISSES"/>
+	<value value="69" name="A7XX_PERF_CP_ICACHE_HITS"/>
+	<value value="70" name="A7XX_PERF_CP_ICACHE_STALL"/>
+	<value value="71" name="A7XX_PERF_CP_DCACHE_MISSES"/>
+	<value value="72" name="A7XX_PERF_CP_DCACHE_HITS"/>
+	<value value="73" name="A7XX_PERF_CP_DCACHE_STALLS"/>
+	<value value="74" name="A7XX_PERF_CP_AQE_SQE_STALL"/>
+	<value value="75" name="A7XX_PERF_CP_SQE_AQE_STARVE"/>
+	<value value="76" name="A7XX_PERF_CP_PREEMPT_LATENCY"/>
+	<value value="77" name="A7XX_PERF_CP_SQE_MD8_STALL_CYCLES"/>
+	<value value="78" name="A7XX_PERF_CP_SQE_MESH_EXEC_CYCLES"/>
+	<value value="79" name="A7XX_PERF_CP_AQE_NUM_AS_CHUNKS"/>
+	<value value="80" name="A7XX_PERF_CP_AQE_NUM_MS_CHUNKS"/>
+</enum>
+
+<enum name="a7xx_rbbm_perfcounter_select">
+	<value value="0" name="A7XX_PERF_RBBM_ALWAYS_COUNT"/>
+	<value value="1" name="A7XX_PERF_RBBM_ALWAYS_ON"/>
+	<value value="2" name="A7XX_PERF_RBBM_TSE_BUSY"/>
+	<value value="3" name="A7XX_PERF_RBBM_RAS_BUSY"/>
+	<value value="4" name="A7XX_PERF_RBBM_PC_DCALL_BUSY"/>
+	<value value="5" name="A7XX_PERF_RBBM_PC_VSD_BUSY"/>
+	<value value="6" name="A7XX_PERF_RBBM_STATUS_MASKED"/>
+	<value value="7" name="A7XX_PERF_RBBM_COM_BUSY"/>
+	<value value="8" name="A7XX_PERF_RBBM_DCOM_BUSY"/>
+	<value value="9" name="A7XX_PERF_RBBM_VBIF_BUSY"/>
+	<value value="10" name="A7XX_PERF_RBBM_VSC_BUSY"/>
+	<value value="11" name="A7XX_PERF_RBBM_TESS_BUSY"/>
+	<value value="12" name="A7XX_PERF_RBBM_UCHE_BUSY"/>
+	<value value="13" name="A7XX_PERF_RBBM_HLSQ_BUSY"/>
+</enum>
+
+<enum name="a7xx_pc_perfcounter_select">
+	<value value="0" name="A7XX_PERF_PC_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_PC_WORKING_CYCLES"/>
+	<value value="2" name="A7XX_PERF_PC_STALL_CYCLES_VFD"/>
+	<value value="3" name="A7XX_PERF_PC_RESERVED"/>
+	<value value="4" name="A7XX_PERF_PC_STALL_CYCLES_VPC"/>
+	<value value="5" name="A7XX_PERF_PC_STALL_CYCLES_UCHE"/>
+	<value value="6" name="A7XX_PERF_PC_STALL_CYCLES_TESS"/>
+	<value value="7" name="A7XX_PERF_PC_STALL_CYCLES_VFD_ONLY"/>
+	<value value="8" name="A7XX_PERF_PC_STALL_CYCLES_VPC_ONLY"/>
+	<value value="9" name="A7XX_PERF_PC_PASS1_TF_STALL_CYCLES"/>
+	<value value="10" name="A7XX_PERF_PC_STARVE_CYCLES_FOR_INDEX"/>
+	<value value="11" name="A7XX_PERF_PC_STARVE_CYCLES_FOR_TESS_FACTOR"/>
+	<value value="12" name="A7XX_PERF_PC_STARVE_CYCLES_FOR_VIZ_STREAM"/>
+	<value value="13" name="A7XX_PERF_PC_STARVE_CYCLES_DI"/>
+	<value value="14" name="A7XX_PERF_PC_VIS_STREAMS_LOADED"/>
+	<value value="15" name="A7XX_PERF_PC_INSTANCES"/>
+	<value value="16" name="A7XX_PERF_PC_VPC_PRIMITIVES"/>
+	<value value="17" name="A7XX_PERF_PC_DEAD_PRIM"/>
+	<value value="18" name="A7XX_PERF_PC_LIVE_PRIM"/>
+	<value value="19" name="A7XX_PERF_PC_VERTEX_HITS"/>
+	<value value="20" name="A7XX_PERF_PC_IA_VERTICES"/>
+	<value value="21" name="A7XX_PERF_PC_IA_PRIMITIVES"/>
+	<value value="22" name="A7XX_PERF_PC_RESERVED_22"/>
+	<value value="23" name="A7XX_PERF_PC_HS_INVOCATIONS"/>
+	<value value="24" name="A7XX_PERF_PC_DS_INVOCATIONS"/>
+	<value value="25" name="A7XX_PERF_PC_VS_INVOCATIONS"/>
+	<value value="26" name="A7XX_PERF_PC_GS_INVOCATIONS"/>
+	<value value="27" name="A7XX_PERF_PC_DS_PRIMITIVES"/>
+	<value value="28" name="A7XX_PERF_PC_3D_DRAWCALLS"/>
+	<value value="29" name="A7XX_PERF_PC_2D_DRAWCALLS"/>
+	<value value="30" name="A7XX_PERF_PC_NON_DRAWCALL_GLOBAL_EVENTS"/>
+	<value value="31" name="A7XX_PERF_PC_TESS_BUSY_CYCLES"/>
+	<value value="32" name="A7XX_PERF_PC_TESS_WORKING_CYCLES"/>
+	<value value="33" name="A7XX_PERF_PC_TESS_STALL_CYCLES_PC"/>
+	<value value="34" name="A7XX_PERF_PC_TESS_STARVE_CYCLES_PC"/>
+	<value value="35" name="A7XX_PERF_PC_TESS_SINGLE_PRIM_CYCLES"/>
+	<value value="36" name="A7XX_PERF_PC_TESS_PC_UV_TRANS"/>
+	<value value="37" name="A7XX_PERF_PC_TESS_PC_UV_PATCHES"/>
+	<value value="38" name="A7XX_PERF_PC_TESS_FACTOR_TRANS"/>
+	<value value="39" name="A7XX_PERF_PC_TAG_CHECKED_VERTICES"/>
+	<value value="40" name="A7XX_PERF_PC_MESH_VS_WAVES"/>
+	<value value="41" name="A7XX_PERF_PC_MESH_DRAWS"/>
+	<value value="42" name="A7XX_PERF_PC_MESH_DEAD_DRAWS"/>
+	<value value="43" name="A7XX_PERF_PC_MESH_MVIS_EN_DRAWS"/>
+	<value value="44" name="A7XX_PERF_PC_MESH_DEAD_PRIM"/>
+	<value value="45" name="A7XX_PERF_PC_MESH_LIVE_PRIM"/>
+	<value value="46" name="A7XX_PERF_PC_MESH_PA_EN_PRIM"/>
+	<value value="47" name="A7XX_PERF_PC_STARVE_CYCLES_FOR_MVIS_STREAM"/>
+	<value value="48" name="A7XX_PERF_PC_STARVE_CYCLES_PREDRAW"/>
+	<value value="49" name="A7XX_PERF_PC_STALL_CYCLES_COMPUTE_GFX"/>
+	<value value="50" name="A7XX_PERF_PC_STALL_CYCLES_GFX_COMPUTE"/>
+	<value value="51" name="A7XX_PERF_PC_TESS_PC_MULTI_PATCH_TRANS"/>
+</enum>
+
+<enum name="a7xx_vfd_perfcounter_select">
+	<value value="0" name="A7XX_PERF_VFD_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_VFD_STALL_CYCLES_UCHE"/>
+	<value value="2" name="A7XX_PERF_VFD_STALL_CYCLES_VPC_ALLOC"/>
+	<value value="3" name="A7XX_PERF_VFD_STALL_CYCLES_SP_INFO"/>
+	<value value="4" name="A7XX_PERF_VFD_STALL_CYCLES_SP_ATTR"/>
+	<value value="5" name="A7XX_PERF_VFD_STARVE_CYCLES_UCHE"/>
+	<value value="6" name="A7XX_PERF_VFD_RBUFFER_FULL"/>
+	<value value="7" name="A7XX_PERF_VFD_ATTR_INFO_FIFO_FULL"/>
+	<value value="8" name="A7XX_PERF_VFD_DECODED_ATTRIBUTE_BYTES"/>
+	<value value="9" name="A7XX_PERF_VFD_NUM_ATTRIBUTES"/>
+	<value value="10" name="A7XX_PERF_VFD_UPPER_SHADER_FIBERS"/>
+	<value value="11" name="A7XX_PERF_VFD_LOWER_SHADER_FIBERS"/>
+	<value value="12" name="A7XX_PERF_VFD_MODE_0_FIBERS"/>
+	<value value="13" name="A7XX_PERF_VFD_MODE_1_FIBERS"/>
+	<value value="14" name="A7XX_PERF_VFD_MODE_2_FIBERS"/>
+	<value value="15" name="A7XX_PERF_VFD_MODE_3_FIBERS"/>
+	<value value="16" name="A7XX_PERF_VFD_MODE_4_FIBERS"/>
+	<value value="17" name="A7XX_PERF_VFD_TOTAL_VERTICES"/>
+	<value value="18" name="A7XX_PERF_VFDP_STALL_CYCLES_VFD"/>
+	<value value="19" name="A7XX_PERF_VFDP_STALL_CYCLES_VFD_INDEX"/>
+	<value value="20" name="A7XX_PERF_VFDP_STALL_CYCLES_VFD_PROG"/>
+	<value value="21" name="A7XX_PERF_VFDP_STARVE_CYCLES_PC"/>
+	<value value="22" name="A7XX_PERF_VFDP_VS_STAGE_WAVES"/>
+	<value value="23" name="A7XX_PERF_VFD_STALL_CYCLES_PRG_END_FE"/>
+	<value value="24" name="A7XX_PERF_VFD_STALL_CYCLES_CBSYNC"/>
+</enum>
+
+<enum name="a7xx_hlsq_perfcounter_select">
+	<value value="0" name="A7XX_PERF_HLSQ_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_HLSQ_STALL_CYCLES_UCHE"/>
+	<value value="2" name="A7XX_PERF_HLSQ_STALL_CYCLES_SP_STATE"/>
+	<value value="3" name="A7XX_PERF_HLSQ_STALL_CYCLES_SP_FS_STAGE"/>
+	<value value="4" name="A7XX_PERF_HLSQ_UCHE_LATENCY_CYCLES"/>
+	<value value="5" name="A7XX_PERF_HLSQ_UCHE_LATENCY_COUNT"/>
+	<value value="6" name="A7XX_PERF_HLSQ_RESERVED_6"/>
+	<value value="7" name="A7XX_PERF_HLSQ_RESERVED_7"/>
+	<value value="8" name="A7XX_PERF_HLSQ_RESERVED_8"/>
+	<value value="9" name="A7XX_PERF_HLSQ_RESERVED_9"/>
+	<value value="10" name="A7XX_PERF_HLSQ_COMPUTE_DRAWCALLS"/>
+	<value value="11" name="A7XX_PERF_HLSQ_FS_DATA_WAIT_PROGRAMMING"/>
+	<value value="12" name="A7XX_PERF_HLSQ_DUAL_FS_PROG_ACTIVE"/>
+	<value value="13" name="A7XX_PERF_HLSQ_DUAL_VS_PROG_ACTIVE"/>
+	<value value="14" name="A7XX_PERF_HLSQ_FS_BATCH_COUNT_ZERO"/>
+	<value value="15" name="A7XX_PERF_HLSQ_VS_BATCH_COUNT_ZERO"/>
+	<value value="16" name="A7XX_PERF_HLSQ_WAVE_PENDING_NO_QUAD"/>
+	<value value="17" name="A7XX_PERF_HLSQ_WAVE_PENDING_NO_PRIM_BASE"/>
+	<value value="18" name="A7XX_PERF_HLSQ_STALL_CYCLES_VPC"/>
+	<value value="19" name="A7XX_PERF_HLSQ_RESERVED_19"/>
+	<value value="20" name="A7XX_PERF_HLSQ_DRAW_MODE_SWITCH_VSFS_SYNC"/>
+	<value value="21" name="A7XX_PERF_HLSQ_VSBR_STALL_CYCLES"/>
+	<value value="22" name="A7XX_PERF_HLSQ_FS_STALL_CYCLES"/>
+	<value value="23" name="A7XX_PERF_HLSQ_LPAC_STALL_CYCLES"/>
+	<value value="24" name="A7XX_PERF_HLSQ_BV_STALL_CYCLES"/>
+	<value value="25" name="A7XX_PERF_HLSQ_VSBR_DEREF_CYCLES"/>
+	<value value="26" name="A7XX_PERF_HLSQ_FS_DEREF_CYCLES"/>
+	<value value="27" name="A7XX_PERF_HLSQ_LPAC_DEREF_CYCLES"/>
+	<value value="28" name="A7XX_PERF_HLSQ_BV_DEREF_CYCLES"/>
+	<value value="29" name="A7XX_PERF_HLSQ_VSBR_S2W_CYCLES"/>
+	<value value="30" name="A7XX_PERF_HLSQ_FS_S2W_CYCLES"/>
+	<value value="31" name="A7XX_PERF_HLSQ_LPAC_S2W_CYCLES"/>
+	<value value="32" name="A7XX_PERF_HLSQ_BV_S2W_CYCLES"/>
+	<value value="33" name="A7XX_PERF_HLSQ_VSBR_WAIT_FS_S2W"/>
+	<value value="34" name="A7XX_PERF_HLSQ_FS_WAIT_VS_S2W"/>
+	<value value="35" name="A7XX_PERF_HLSQ_LPAC_WAIT_VS_S2W"/>
+	<value value="36" name="A7XX_PERF_HLSQ_BV_WAIT_FS_S2W"/>
+	<value value="37" name="A7XX_PERF_HLSQ_VS_WAIT_CONST_RESOURCE"/>
+	<value value="38" name="A7XX_PERF_HLSQ_FS_WAIT_SAME_VS_S2W"/>
+	<value value="39" name="A7XX_PERF_HLSQ_FS_STARVING_SP"/>
+	<value value="40" name="A7XX_PERF_HLSQ_VS_DATA_WAIT_PROGRAMMING"/>
+	<value value="41" name="A7XX_PERF_HLSQ_BV_DATA_WAIT_PROGRAMMING"/>
+	<value value="42" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXTS_VS"/>
+	<value value="43" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXT_CYCLES_VS"/>
+	<value value="44" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXTS_FS"/>
+	<value value="45" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXT_CYCLES_FS"/>
+	<value value="46" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXTS_BV"/>
+	<value value="47" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXT_CYCLES_BV"/>
+	<value value="48" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXTS_LPAC"/>
+	<value value="49" name="A7XX_PERF_HLSQ_STPROC_WAVE_CONTEXT_CYCLES_LPAC"/>
+	<value value="50" name="A7XX_PERF_HLSQ_SPTROC_STCHE_WARMUP_INC_VS"/>
+	<value value="51" name="A7XX_PERF_HLSQ_SPTROC_STCHE_WARMUP_INC_FS"/>
+	<value value="52" name="A7XX_PERF_HLSQ_SPTROC_STCHE_WARMUP_INC_BV"/>
+	<value value="53" name="A7XX_PERF_HLSQ_SPTROC_STCHE_WARMUP_INC_LPAC"/>
+	<value value="54" name="A7XX_PERF_HLSQ_SPTROC_STCHE_MISS_INC_VS"/>
+	<value value="55" name="A7XX_PERF_HLSQ_SPTROC_STCHE_MISS_INC_FS"/>
+	<value value="56" name="A7XX_PERF_HLSQ_SPTROC_STCHE_MISS_INC_BV"/>
+	<value value="57" name="A7XX_PERF_HLSQ_SPTROC_STCHE_MISS_INC_LPAC"/>
+</enum>
+
+<enum name="a7xx_vpc_perfcounter_select">
+	<value value="0" name="A7XX_PERF_VPC_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_VPC_WORKING_CYCLES"/>
+	<value value="2" name="A7XX_PERF_VPC_STALL_CYCLES_UCHE"/>
+	<value value="3" name="A7XX_PERF_VPC_STALL_CYCLES_VFD_WACK"/>
+	<value value="4" name="A7XX_PERF_VPC_STALL_CYCLES_HLSQ_PRIM_ALLOC"/>
+	<value value="5" name="A7XX_PERF_VPC_RESERVED_5"/>
+	<value value="6" name="A7XX_PERF_VPC_STALL_CYCLES_SP_LM"/>
+	<value value="7" name="A7XX_PERF_VPC_STARVE_CYCLES_SP"/>
+	<value value="8" name="A7XX_PERF_VPC_STARVE_CYCLES_LRZ"/>
+	<value value="9" name="A7XX_PERF_VPC_PC_PRIMITIVES"/>
+	<value value="10" name="A7XX_PERF_VPC_SP_COMPONENTS"/>
+	<value value="11" name="A7XX_PERF_VPC_STALL_CYCLES_VPCRAM_POS"/>
+	<value value="12" name="A7XX_PERF_VPC_LRZ_ASSIGN_PRIMITIVES"/>
+	<value value="13" name="A7XX_PERF_VPC_RB_VISIBLE_PRIMITIVES"/>
+	<value value="14" name="A7XX_PERF_VPC_LM_TRANSACTION"/>
+	<value value="15" name="A7XX_PERF_VPC_STREAMOUT_TRANSACTION"/>
+	<value value="16" name="A7XX_PERF_VPC_VS_BUSY_CYCLES"/>
+	<value value="17" name="A7XX_PERF_VPC_PS_BUSY_CYCLES"/>
+	<value value="18" name="A7XX_PERF_VPC_VS_WORKING_CYCLES"/>
+	<value value="19" name="A7XX_PERF_VPC_PS_WORKING_CYCLES"/>
+	<value value="20" name="A7XX_PERF_VPC_STARVE_CYCLES_RB"/>
+	<value value="21" name="A7XX_PERF_VPC_NUM_VPCRAM_READ_POS"/>
+	<value value="22" name="A7XX_PERF_VPC_WIT_FULL_CYCLES"/>
+	<value value="23" name="A7XX_PERF_VPC_VPCRAM_FULL_CYCLES"/>
+	<value value="24" name="A7XX_PERF_VPC_LM_FULL_WAIT_FOR_INTP_END"/>
+	<value value="25" name="A7XX_PERF_VPC_NUM_VPCRAM_WRITE"/>
+	<value value="26" name="A7XX_PERF_VPC_NUM_VPCRAM_READ_SO"/>
+	<value value="27" name="A7XX_PERF_VPC_NUM_ATTR_REQ_LM"/>
+	<value value="28" name="A7XX_PERF_VPC_STALL_CYCLE_TSE"/>
+	<value value="29" name="A7XX_PERF_VPC_TSE_PRIMITIVES"/>
+	<value value="30" name="A7XX_PERF_VPC_GS_PRIMITIVES"/>
+	<value value="31" name="A7XX_PERF_VPC_TSE_TRANSACTIONS"/>
+	<value value="32" name="A7XX_PERF_VPC_STALL_CYCLES_CCU"/>
+	<value value="33" name="A7XX_PERF_VPC_NUM_WM_HIT"/>
+	<value value="34" name="A7XX_PERF_VPC_STALL_DQ_WACK"/>
+	<value value="35" name="A7XX_PERF_VPC_STALL_CYCLES_CCHE"/>
+	<value value="36" name="A7XX_PERF_VPC_STARVE_CYCLES_CCHE"/>
+	<value value="37" name="A7XX_PERF_VPC_NUM_PA_REQ"/>
+	<value value="38" name="A7XX_PERF_VPC_NUM_LM_REQ_HIT"/>
+	<value value="39" name="A7XX_PERF_VPC_CCHE_REQBUF_FULL"/>
+	<value value="40" name="A7XX_PERF_VPC_STALL_CYCLES_LM_ACK"/>
+	<value value="41" name="A7XX_PERF_VPC_STALL_CYCLES_PRG_END_FE"/>
+	<value value="42" name="A7XX_PERF_VPC_STALL_CYCLES_PRG_END_PCVS"/>
+	<value value="43" name="A7XX_PERF_VPC_STALL_CYCLES_PRG_END_VPCPS"/>
+</enum>
+
+<enum name="a7xx_tse_perfcounter_select">
+	<value value="0" name="A7XX_PERF_TSE_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_TSE_CLIPPING_CYCLES"/>
+	<value value="2" name="A7XX_PERF_TSE_STALL_CYCLES_RAS"/>
+	<value value="3" name="A7XX_PERF_TSE_STALL_CYCLES_LRZ_BARYPLANE"/>
+	<value value="4" name="A7XX_PERF_TSE_STALL_CYCLES_LRZ_ZPLANE"/>
+	<value value="5" name="A7XX_PERF_TSE_STARVE_CYCLES_PC"/>
+	<value value="6" name="A7XX_PERF_TSE_INPUT_PRIM"/>
+	<value value="7" name="A7XX_PERF_TSE_INPUT_NULL_PRIM"/>
+	<value value="8" name="A7XX_PERF_TSE_TRIVAL_REJ_PRIM"/>
+	<value value="9" name="A7XX_PERF_TSE_CLIPPED_PRIM"/>
+	<value value="10" name="A7XX_PERF_TSE_ZERO_AREA_PRIM"/>
+	<value value="11" name="A7XX_PERF_TSE_FACENESS_CULLED_PRIM"/>
+	<value value="12" name="A7XX_PERF_TSE_ZERO_PIXEL_PRIM"/>
+	<value value="13" name="A7XX_PERF_TSE_OUTPUT_NULL_PRIM"/>
+	<value value="14" name="A7XX_PERF_TSE_OUTPUT_VISIBLE_PRIM"/>
+	<value value="15" name="A7XX_PERF_TSE_CINVOCATION"/>
+	<value value="16" name="A7XX_PERF_TSE_CPRIMITIVES"/>
+	<value value="17" name="A7XX_PERF_TSE_2D_INPUT_PRIM"/>
+	<value value="18" name="A7XX_PERF_TSE_2D_ALIVE_CYCLES"/>
+	<value value="19" name="A7XX_PERF_TSE_CLIP_PLANES"/>
+</enum>
+
+<enum name="a7xx_ras_perfcounter_select">
+	<value value="0" name="A7XX_PERF_RAS_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_RAS_SUPERTILE_ACTIVE_CYCLES"/>
+	<value value="2" name="A7XX_PERF_RAS_STALL_CYCLES_LRZ"/>
+	<value value="3" name="A7XX_PERF_RAS_STARVE_CYCLES_TSE"/>
+	<value value="4" name="A7XX_PERF_RAS_SUPER_TILES"/>
+	<value value="5" name="A7XX_PERF_RAS_8X4_TILES"/>
+	<value value="6" name="A7XX_PERF_RAS_MASKGEN_ACTIVE"/>
+	<value value="7" name="A7XX_PERF_RAS_FULLY_COVERED_SUPER_TILES"/>
+	<value value="8" name="A7XX_PERF_RAS_FULLY_COVERED_8X4_TILES"/>
+	<value value="9" name="A7XX_PERF_RAS_PRIM_KILLED_INVISILBE"/>
+	<value value="10" name="A7XX_PERF_RAS_SUPERTILE_GEN_ACTIVE_CYCLES"/>
+	<value value="11" name="A7XX_PERF_RAS_LRZ_INTF_WORKING_CYCLES"/>
+	<value value="12" name="A7XX_PERF_RAS_BLOCKS"/>
+	<value value="13" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_0_WORKING_CC_l2"/>
+	<value value="14" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_1_WORKING_CC_l2"/>
+	<value value="15" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_2_WORKING_CC_l2"/>
+	<value value="16" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_3_WORKING_CC_l2"/>
+	<value value="17" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_4_WORKING_CC_l2"/>
+	<value value="18" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_5_WORKING_CC_l2"/>
+	<value value="19" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_6_WORKING_CC_l2"/>
+	<value value="20" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_7_WORKING_CC_l2"/>
+	<value value="21" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_8_WORKING_CC_l2"/>
+	<value value="22" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_9_WORKING_CC_l2"/>
+	<value value="23" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_10_WORKING_CC_l2"/>
+	<value value="24" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_11_WORKING_CC_l2"/>
+	<value value="25" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_12_WORKING_CC_l2"/>
+	<value value="26" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_13_WORKING_CC_l2"/>
+	<value value="27" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_14_WORKING_CC_l2"/>
+	<value value="28" name="A7XX_PERF_RAS_SAMPLE_MASK_GEN_LANE_15_WORKING_CC_l2"/>
+	<value value="29" name="A7XX_PERF_RAS_FALSE_PARTIAL_STILE"/>
+
+</enum>
+
+<enum name="a7xx_uche_perfcounter_select">
+	<value value="0" name="A7XX_PERF_UCHE_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_UCHE_STALL_CYCLES_ARBITER"/>
+	<value value="2" name="A7XX_PERF_UCHE_VBIF_LATENCY_CYCLES"/>
+	<value value="3" name="A7XX_PERF_UCHE_VBIF_LATENCY_SAMPLES"/>
+	<value value="4" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_TP"/>
+	<value value="5" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_VFD"/>
+	<value value="6" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_HLSQ"/>
+	<value value="7" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_LRZ"/>
+	<value value="8" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_SP"/>
+	<value value="9" name="A7XX_PERF_UCHE_READ_REQUESTS_TP"/>
+	<value value="10" name="A7XX_PERF_UCHE_READ_REQUESTS_VFD"/>
+	<value value="11" name="A7XX_PERF_UCHE_READ_REQUESTS_HLSQ"/>
+	<value value="12" name="A7XX_PERF_UCHE_READ_REQUESTS_LRZ"/>
+	<value value="13" name="A7XX_PERF_UCHE_READ_REQUESTS_SP"/>
+	<value value="14" name="A7XX_PERF_UCHE_WRITE_REQUESTS_LRZ"/>
+	<value value="15" name="A7XX_PERF_UCHE_WRITE_REQUESTS_SP"/>
+	<value value="16" name="A7XX_PERF_UCHE_WRITE_REQUESTS_VPC"/>
+	<value value="17" name="A7XX_PERF_UCHE_WRITE_REQUESTS_VSC"/>
+	<value value="18" name="A7XX_PERF_UCHE_EVICTS"/>
+	<value value="19" name="A7XX_PERF_UCHE_BANK_REQ0"/>
+	<value value="20" name="A7XX_PERF_UCHE_BANK_REQ1"/>
+	<value value="21" name="A7XX_PERF_UCHE_BANK_REQ2"/>
+	<value value="22" name="A7XX_PERF_UCHE_BANK_REQ3"/>
+	<value value="23" name="A7XX_PERF_UCHE_BANK_REQ4"/>
+	<value value="24" name="A7XX_PERF_UCHE_BANK_REQ5"/>
+	<value value="25" name="A7XX_PERF_UCHE_BANK_REQ6"/>
+	<value value="26" name="A7XX_PERF_UCHE_BANK_REQ7"/>
+	<value value="27" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_CH0"/>
+	<value value="28" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_CH1"/>
+	<value value="29" name="A7XX_PERF_UCHE_GMEM_READ_BEATS"/>
+	<value value="30" name="A7XX_PERF_UCHE_TPH_REF_FULL"/>
+	<value value="31" name="A7XX_PERF_UCHE_TPH_VICTIM_FULL"/>
+	<value value="32" name="A7XX_PERF_UCHE_TPH_EXT_FULL"/>
+	<value value="33" name="A7XX_PERF_UCHE_VBIF_STALL_WRITE_DATA"/>
+	<value value="34" name="A7XX_PERF_UCHE_DCMP_LATENCY_SAMPLES"/>
+	<value value="35" name="A7XX_PERF_UCHE_DCMP_LATENCY_CYCLES"/>
+	<value value="36" name="A7XX_PERF_UCHE_VBIF_READ_BEATS_PC"/>
+	<value value="37" name="A7XX_PERF_UCHE_READ_REQUESTS_PC"/>
+	<value value="38" name="A7XX_PERF_UCHE_RAM_READ_REQ"/>
+	<value value="39" name="A7XX_PERF_UCHE_RAM_WRITE_REQ"/>
+	<value value="40" name="A7XX_PERF_UCHE_STARVED_CYCLES_VBIF_DECMP"/>
+	<value value="41" name="A7XX_PERF_UCHE_STALL_CYCLES_DECMP"/>
+	<value value="42" name="A7XX_PERF_UCHE_ARBITER_STALL_CYCLES_VBIF"/>
+	<value value="43" name="A7XX_PERF_UCHE_READ_REQUESTS_TP_UBWC"/>
+	<value value="44" name="A7XX_PERF_UCHE_READ_REQUESTS_TP_NONUBWC"/>
+	<value value="45" name="A7XX_PERF_UCHE_READ_REQUESTS_TP_GMEM"/>
+	<value value="46" name="A7XX_PERF_UCHE_LONG_LINE_ALL_EVICTS_KAILUA"/>
+	<value value="47" name="A7XX_PERF_UCHE_LONG_LINE_PARTIAL_EVICTS_KAILUA"/>
+	<value value="48" name="A7XX_PERF_UCHE_TPH_CONFLICT_CL_CCHE"/>
+	<value value="49" name="A7XX_PERF_UCHE_TPH_CONFLICT_CL_OTHER_KAILUA"/>
+	<value value="50" name="A7XX_PERF_UCHE_DBANK_CONFLICT_CL_CCHE"/>
+	<value value="51" name="A7XX_PERF_UCHE_DBANK_CONFLICT_CL_OTHER_CLIENTS"/>
+	<value value="52" name="A7XX_PERF_UCHE_VBIF_WRITE_BEATS_CH0"/>
+	<value value="53" name="A7XX_PERF_UCHE_VBIF_WRITE_BEATS_CH1"/>
+	<value value="54" name="A7XX_PERF_UCHE_CCHE_TPH_QUEUE_FULL"/>
+	<value value="55" name="A7XX_PERF_UCHE_CCHE_DPH_QUEUE_FULL"/>
+	<value value="56" name="A7XX_PERF_UCHE_GMEM_WRITE_BEATS"/>
+	<value value="57" name="A7XX_PERF_UCHE_UBWC_READ_BEATS"/>
+	<value value="58" name="A7XX_PERF_UCHE_UBWC_WRITE_BEATS"/>
+</enum>
+
+<enum name="a7xx_tp_perfcounter_select">
+	<value value="0" name="A7XX_PERF_TP_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_TP_STALL_CYCLES_UCHE"/>
+	<value value="2" name="A7XX_PERF_TP_LATENCY_CYCLES"/>
+	<value value="3" name="A7XX_PERF_TP_LATENCY_TRANS"/>
+	<value value="4" name="A7XX_PERF_TP_FLAG_FIFO_DELAY_SAMPLES"/>
+	<value value="5" name="A7XX_PERF_TP_FLAG_FIFO_DELAY_CYCLES"/>
+	<value value="6" name="A7XX_PERF_TP_L1_CACHELINE_REQUESTS"/>
+	<value value="7" name="A7XX_PERF_TP_L1_CACHELINE_MISSES"/>
+	<value value="8" name="A7XX_PERF_TP_SP_TP_TRANS"/>
+	<value value="9" name="A7XX_PERF_TP_TP_SP_TRANS"/>
+	<value value="10" name="A7XX_PERF_TP_OUTPUT_PIXELS"/>
+	<value value="11" name="A7XX_PERF_TP_FILTER_WORKLOAD_16BIT"/>
+	<value value="12" name="A7XX_PERF_TP_FILTER_WORKLOAD_32BIT"/>
+	<value value="13" name="A7XX_PERF_TP_QUADS_RECEIVED"/>
+	<value value="14" name="A7XX_PERF_TP_QUADS_OFFSET"/>
+	<value value="15" name="A7XX_PERF_TP_QUADS_SHADOW"/>
+	<value value="16" name="A7XX_PERF_TP_QUADS_ARRAY"/>
+	<value value="17" name="A7XX_PERF_TP_QUADS_GRADIENT"/>
+	<value value="18" name="A7XX_PERF_TP_QUADS_1D"/>
+	<value value="19" name="A7XX_PERF_TP_QUADS_2D"/>
+	<value value="20" name="A7XX_PERF_TP_QUADS_BUFFER"/>
+	<value value="21" name="A7XX_PERF_TP_QUADS_3D"/>
+	<value value="22" name="A7XX_PERF_TP_QUADS_CUBE"/>
+	<value value="23" name="A7XX_PERF_TP_DIVERGENT_QUADS_RECEIVED"/>
+	<value value="24" name="A7XX_PERF_TP_PRT_NON_RESIDENT_EVENTS"/>
+	<value value="25" name="A7XX_PERF_TP_OUTPUT_PIXELS_POINT"/>
+	<value value="26" name="A7XX_PERF_TP_OUTPUT_PIXELS_BILINEAR"/>
+	<value value="27" name="A7XX_PERF_TP_OUTPUT_PIXELS_MIP"/>
+	<value value="28" name="A7XX_PERF_TP_OUTPUT_PIXELS_ANISO"/>
+	<value value="29" name="A7XX_PERF_TP_OUTPUT_PIXELS_ZERO_LOD"/>
+	<value value="30" name="A7XX_PERF_TP_FLAG_CACHE_REQUESTS"/>
+	<value value="31" name="A7XX_PERF_TP_FLAG_CACHE_MISSES"/>
+	<value value="32" name="A7XX_PERF_TP_L1_5_L2_REQUESTS"/>
+	<value value="33" name="A7XX_PERF_TP_2D_OUTPUT_PIXELS"/>
+	<value value="34" name="A7XX_PERF_TP_2D_OUTPUT_PIXELS_POINT"/>
+	<value value="35" name="A7XX_PERF_TP_2D_OUTPUT_PIXELS_BILINEAR"/>
+	<value value="36" name="A7XX_PERF_TP_2D_FILTER_WORKLOAD_16BIT"/>
+	<value value="37" name="A7XX_PERF_TP_2D_FILTER_WORKLOAD_32BIT"/>
+	<value value="38" name="A7XX_PERF_TP_TPA2TPC_TRANS"/>
+	<value value="39" name="A7XX_PERF_TP_L1_MISSES_ASTC_1TILE"/>
+	<value value="40" name="A7XX_PERF_TP_L1_MISSES_ASTC_2TILE"/>
+	<value value="41" name="A7XX_PERF_TP_L1_MISSES_ASTC_4TILE"/>
+	<value value="42" name="A7XX_PERF_TP_L1_5_COMPRESS_REQS"/>
+	<value value="43" name="A7XX_PERF_TP_L1_5_L2_COMPRESS_MISS"/>
+	<value value="44" name="A7XX_PERF_TP_L1_BANK_CONFLICT"/>
+	<value value="45" name="A7XX_PERF_TP_L1_5_MISS_LATENCY_CYCLES"/>
+	<value value="46" name="A7XX_PERF_TP_L1_5_MISS_LATENCY_TRANS"/>
+	<value value="47" name="A7XX_PERF_TP_QUADS_CONSTANT_MULTIPLIED"/>
+	<value value="48" name="A7XX_PERF_TP_FRONTEND_WORKING_CYCLES"/>
+	<value value="49" name="A7XX_PERF_TP_L1_TAG_WORKING_CYCLES"/>
+	<value value="50" name="A7XX_PERF_TP_L1_DATA_WRITE_WORKING_CYCLES"/>
+	<value value="51" name="A7XX_PERF_TP_PRE_L1_DECOM_WORKING_CYCLES"/>
+	<value value="52" name="A7XX_PERF_TP_BACKEND_WORKING_CYCLES"/>
+	<value value="53" name="A7XX_PERF_TP_L1_5_CACHE_WORKING_CYCLES"/>
+	<value value="54" name="A7XX_PERF_TP_STARVE_CYCLES_SP"/>
+	<value value="55" name="A7XX_PERF_TP_STARVE_CYCLES_UCHE"/>
+	<value value="56" name="A7XX_PERF_TP_STALL_CYCLES_UFC"/>
+	<value value="57" name="A7XX_PERF_TP_FORMAT_DECOMP"/>
+	<value value="58" name="A7XX_PERF_TP_FILTER_POINT_FP16"/>
+	<value value="59" name="A7XX_PERF_TP_FILTER_POINT_FP32"/>
+	<value value="60" name="A7XX_PERF_TP_LATENCY_FIFO_FULL"/>
+	<value value="61" name="A7XX_PERF_TP_RESERVED_61"/>
+	<value value="62" name="A7XX_PERF_TP_RESERVED_62"/>
+	<value value="63" name="A7XX_PERF_TP_RESERVED_63"/>
+	<value value="64" name="A7XX_PERF_TP_RESERVED_64"/>
+	<value value="65" name="A7XX_PERF_TP_RESERVED_65"/>
+	<value value="66" name="A7XX_PERF_TP_RESERVED_66"/>
+	<value value="67" name="A7XX_PERF_TP_RESERVED_67"/>
+	<value value="68" name="A7XX_PERF_TP_RESERVED_68"/>
+	<value value="69" name="A7XX_PERF_TP_RESERVED_69"/>
+	<value value="70" name="A7XX_PERF_TP_RESERVED_70"/>
+	<value value="71" name="A7XX_PERF_TP_RESERVED_71"/>
+	<value value="72" name="A7XX_PERF_TP_RESERVED_72"/>
+	<value value="73" name="A7XX_PERF_TP_RESERVED_73"/>
+	<value value="74" name="A7XX_PERF_TP_RESERVED_74"/>
+	<value value="75" name="A7XX_PERF_TP_RESERVED_75"/>
+	<value value="76" name="A7XX_PERF_TP_RESERVED_76"/>
+	<value value="77" name="A7XX_PERF_TP_RESERVED_77"/>
+	<value value="78" name="A7XX_PERF_TP_RESERVED_78"/>
+	<value value="79" name="A7XX_PERF_TP_RESERVED_79"/>
+	<value value="80" name="A7XX_PERF_TP_RESERVED_80"/>
+	<value value="81" name="A7XX_PERF_TP_RESERVED_81"/>
+	<value value="82" name="A7XX_PERF_TP_RESERVED_82"/>
+	<value value="83" name="A7XX_PERF_TP_RESERVED_83"/>
+	<value value="84" name="A7XX_PERF_TP_RESERVED_84"/>
+	<value value="85" name="A7XX_PERF_TP_RESERVED_85"/>
+	<value value="86" name="A7XX_PERF_TP_RESERVED_86"/>
+	<value value="87" name="A7XX_PERF_TP_RESERVED_87"/>
+	<value value="88" name="A7XX_PERF_TP_RESERVED_88"/>
+	<value value="89" name="A7XX_PERF_TP_RESERVED_89"/>
+	<value value="90" name="A7XX_PERF_TP_RESERVED_90"/>
+	<value value="91" name="A7XX_PERF_TP_RESERVED_91"/>
+	<value value="92" name="A7XX_PERF_TP_RESERVED_92"/>
+	<value value="93" name="A7XX_PERF_TP_RESERVED_93"/>
+	<value value="94" name="A7XX_PERF_TP_RESERVED_94"/>
+	<value value="95" name="A7XX_PERF_TP_RESERVED_95"/>
+	<value value="96" name="A7XX_PERF_TP_RESERVED_96"/>
+	<value value="97" name="A7XX_PERF_TP_RESERVED_97"/>
+	<value value="98" name="A7XX_PERF_TP_RESERVED_98"/>
+	<value value="99" name="A7XX_PERF_TP_RESERVED_99"/>
+	<value value="100" name="A7XX_PERF_TP_RESERVED_100"/>
+	<value value="101" name="A7XX_PERF_TP_RESERVED_101"/>
+	<value value="102" name="A7XX_PERF_TP_RESERVED_102"/>
+	<value value="103" name="A7XX_PERF_TP_RESERVED_103"/>
+	<value value="104" name="A7XX_PERF_TP_RESERVED_104"/>
+	<value value="105" name="A7XX_PERF_TP_RESERVED_105"/>
+	<value value="106" name="A7XX_PERF_TP_RESERVED_106"/>
+	<value value="107" name="A7XX_PERF_TP_RESERVED_107"/>
+	<value value="108" name="A7XX_PERF_TP_RESERVED_108"/>
+	<value value="109" name="A7XX_PERF_TP_RESERVED_109"/>
+	<value value="110" name="A7XX_PERF_TP_RESERVED_110"/>
+	<value value="111" name="A7XX_PERF_TP_RESERVED_111"/>
+	<value value="112" name="A7XX_PERF_TP_RESERVED_112"/>
+	<value value="113" name="A7XX_PERF_TP_RESERVED_113"/>
+	<value value="114" name="A7XX_PERF_TP_RESERVED_114"/>
+	<value value="115" name="A7XX_PERF_TP_RESERVED_115"/>
+	<value value="116" name="A7XX_PERF_TP_RESERVED_116"/>
+	<value value="117" name="A7XX_PERF_TP_RESERVED_117"/>
+	<value value="118" name="A7XX_PERF_TP_RESERVED_118"/>
+	<value value="119" name="A7XX_PERF_TP_RESERVED_119"/>
+	<value value="120" name="A7XX_PERF_TP_RESERVED_120"/>
+	<value value="121" name="A7XX_PERF_TP_RESERVED_121"/>
+	<value value="122" name="A7XX_PERF_TP_RESERVED_122"/>
+	<value value="123" name="A7XX_PERF_TP_RESERVED_123"/>
+	<value value="124" name="A7XX_PERF_TP_RESERVED_124"/>
+	<value value="125" name="A7XX_PERF_TP_RESERVED_125"/>
+	<value value="126" name="A7XX_PERF_TP_RESERVED_126"/>
+	<value value="127" name="A7XX_PERF_TP_RESERVED_127"/>
+	<value value="128" name="A7XX_PERF_TP_FORMAT_DECOMP_BILINEAR"/>
+	<value value="129" name="A7XX_PERF_TP_PACKED_POINT_BOTH_VALID_FP16"/>
+	<value value="130" name="A7XX_PERF_TP_PACKED_POINT_SINGLE_VALID_FP16"/>
+	<value value="131" name="A7XX_PERF_TP_PACKED_POINT_BOTH_VALID_FP32"/>
+	<value value="132" name="A7XX_PERF_TP_PACKED_POINT_SINGLE_VALID_FP32"/>
+</enum>
+
+<enum name="a7xx_sp_perfcounter_select">
+	<value value="0" name="A7XX_PERF_SP_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_SP_ALU_WORKING_CYCLES"/>
+	<value value="2" name="A7XX_PERF_SP_EFU_WORKING_CYCLES"/>
+	<value value="3" name="A7XX_PERF_SP_STALL_CYCLES_VPC"/>
+	<value value="4" name="A7XX_PERF_SP_STALL_CYCLES_TP"/>
+	<value value="5" name="A7XX_PERF_SP_STALL_CYCLES_UCHE"/>
+	<value value="6" name="A7XX_PERF_SP_STALL_CYCLES_RB"/>
+	<value value="7" name="A7XX_PERF_SP_NON_EXECUTION_CYCLES"/>
+	<value value="8" name="A7XX_PERF_SP_WAVE_CONTEXTS"/>
+	<value value="9" name="A7XX_PERF_SP_WAVE_CONTEXT_CYCLES"/>
+	<value value="10" name="A7XX_PERF_SP_STAGE_WAVE_CYCLES"/>
+	<value value="11" name="A7XX_PERF_SP_STAGE_WAVE_SAMPLES"/>
+	<value value="12" name="A7XX_PERF_SP_VS_STAGE_WAVE_CYCLES"/>
+	<value value="13" name="A7XX_PERF_SP_VS_STAGE_WAVE_SAMPLES"/>
+	<value value="14" name="A7XX_PERF_SP_FS_STAGE_DURATION_CYCLES"/>
+	<value value="15" name="A7XX_PERF_SP_VS_STAGE_DURATION_CYCLES"/>
+	<value value="16" name="A7XX_PERF_SP_WAVE_CTRL_CYCLES"/>
+	<value value="17" name="A7XX_PERF_SP_WAVE_LOAD_CYCLES"/>
+	<value value="18" name="A7XX_PERF_SP_WAVE_EMIT_CYCLES"/>
+	<value value="19" name="A7XX_PERF_SP_WAVE_NOP_CYCLES"/>
+	<value value="20" name="A7XX_PERF_SP_WAVE_WAIT_CYCLES"/>
+	<value value="21" name="A7XX_PERF_SP_WAVE_FETCH_CYCLES"/>
+	<value value="22" name="A7XX_PERF_SP_WAVE_IDLE_CYCLES"/>
+	<value value="23" name="A7XX_PERF_SP_WAVE_END_CYCLES"/>
+	<value value="24" name="A7XX_PERF_SP_WAVE_LONG_SYNC_CYCLES"/>
+	<value value="25" name="A7XX_PERF_SP_WAVE_SHORT_SYNC_CYCLES"/>
+	<value value="26" name="A7XX_PERF_SP_WAVE_JOIN_CYCLES"/>
+	<value value="27" name="A7XX_PERF_SP_LM_LOAD_INSTRUCTIONS"/>
+	<value value="28" name="A7XX_PERF_SP_LM_STORE_INSTRUCTIONS"/>
+	<value value="29" name="A7XX_PERF_SP_LM_ATOMICS"/>
+	<value value="30" name="A7XX_PERF_SP_GM_LOAD_INSTRUCTIONS"/>
+	<value value="31" name="A7XX_PERF_SP_GM_STORE_INSTRUCTIONS"/>
+	<value value="32" name="A7XX_PERF_SP_GM_ATOMICS"/>
+	<value value="33" name="A7XX_PERF_SP_VS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="34" name="A7XX_PERF_SP_VS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="35" name="A7XX_PERF_SP_VS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="36" name="A7XX_PERF_SP_VS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="37" name="A7XX_PERF_SP_FS_STAGE_TEX_INSTRUCTIONS"/>
+	<value value="38" name="A7XX_PERF_SP_FS_STAGE_CFLOW_INSTRUCTIONS"/>
+	<value value="39" name="A7XX_PERF_SP_FS_STAGE_EFU_INSTRUCTIONS"/>
+	<value value="40" name="A7XX_PERF_SP_FS_STAGE_FULL_ALU_INSTRUCTIONS"/>
+	<value value="41" name="A7XX_PERF_SP_FS_STAGE_HALF_ALU_INSTRUCTIONS"/>
+	<value value="42" name="A7XX_PERF_SP_FS_STAGE_BARY_INSTRUCTIONS"/>
+	<value value="43" name="A7XX_PERF_SP_VS_INSTRUCTIONS"/>
+	<value value="44" name="A7XX_PERF_SP_FS_INSTRUCTIONS"/>
+	<value value="45" name="A7XX_PERF_SP_ADDR_LOCK_COUNT"/>
+	<value value="46" name="A7XX_PERF_SP_UCHE_READ_TRANS"/>
+	<value value="47" name="A7XX_PERF_SP_UCHE_WRITE_TRANS"/>
+	<value value="48" name="A7XX_PERF_SP_EXPORT_VPC_TRANS"/>
+	<value value="49" name="A7XX_PERF_SP_EXPORT_RB_TRANS"/>
+	<value value="50" name="A7XX_PERF_SP_PIXELS_KILLED"/>
+	<value value="51" name="A7XX_PERF_SP_ICL1_REQUESTS"/>
+	<value value="52" name="A7XX_PERF_SP_ICL1_MISSES"/>
+	<value value="53" name="A7XX_PERF_SP_HS_INSTRUCTIONS"/>
+	<value value="54" name="A7XX_PERF_SP_DS_INSTRUCTIONS"/>
+	<value value="55" name="A7XX_PERF_SP_GS_INSTRUCTIONS"/>
+	<value value="56" name="A7XX_PERF_SP_CS_INSTRUCTIONS"/>
+	<value value="57" name="A7XX_PERF_SP_GPR_READ"/>
+	<value value="58" name="A7XX_PERF_SP_GPR_WRITE"/>
+	<value value="59" name="A7XX_PERF_SP_FS_STAGE_HALF_EFU_INSTRUCTIONS"/>
+	<value value="60" name="A7XX_PERF_SP_VS_STAGE_HALF_EFU_INSTRUCTIONS"/>
+	<value value="61" name="A7XX_PERF_SP_LM_BANK_CONFLICTS"/>
+	<value value="62" name="A7XX_PERF_SP_TEX_CONTROL_WORKING_CYCLES"/>
+	<value value="63" name="A7XX_PERF_SP_LOAD_CONTROL_WORKING_CYCLES"/>
+	<value value="64" name="A7XX_PERF_SP_FLOW_CONTROL_WORKING_CYCLES"/>
+	<value value="65" name="A7XX_PERF_SP_LM_WORKING_CYCLES"/>
+	<value value="66" name="A7XX_PERF_SP_DISPATCHER_WORKING_CYCLES"/>
+	<value value="67" name="A7XX_PERF_SP_SEQUENCER_WORKING_CYCLES"/>
+	<value value="68" name="A7XX_PERF_SP_LOW_EFFICIENCY_STARVED_BY_TP"/>
+	<value value="69" name="A7XX_PERF_SP_STARVE_CYCLES_HLSQ"/>
+	<value value="70" name="A7XX_PERF_SP_NON_EXECUTION_LS_CYCLES"/>
+	<value value="71" name="A7XX_PERF_SP_WORKING_EU"/>
+	<value value="72" name="A7XX_PERF_SP_ANY_EU_WORKING"/>
+	<value value="73" name="A7XX_PERF_SP_WORKING_EU_FS_STAGE"/>
+	<value value="74" name="A7XX_PERF_SP_ANY_EU_WORKING_FS_STAGE"/>
+	<value value="75" name="A7XX_PERF_SP_WORKING_EU_VS_STAGE"/>
+	<value value="76" name="A7XX_PERF_SP_ANY_EU_WORKING_VS_STAGE"/>
+	<value value="77" name="A7XX_PERF_SP_WORKING_EU_CS_STAGE"/>
+	<value value="78" name="A7XX_PERF_SP_ANY_EU_WORKING_CS_STAGE"/>
+	<value value="79" name="A7XX_PERF_SP_GPR_READ_PREFETCH"/>
+	<value value="80" name="A7XX_PERF_SP_GPR_READ_CONFLICT"/>
+	<value value="81" name="A7XX_PERF_SP_GPR_WRITE_CONFLICT"/>
+	<value value="82" name="A7XX_PERF_SP_GM_LOAD_LATENCY_CYCLES"/>
+	<value value="83" name="A7XX_PERF_SP_GM_LOAD_LATENCY_SAMPLES"/>
+	<value value="84" name="A7XX_PERF_SP_EXECUTABLE_WAVES"/>
+	<value value="85" name="A7XX_PERF_SP_ICL1_MISS_FETCH_CYCLES"/>
+	<value value="86" name="A7XX_PERF_SP_WORKING_EU_LPAC"/>
+	<value value="87" name="A7XX_PERF_SP_BYPASS_BUSY_CYCLES"/>
+	<value value="88" name="A7XX_PERF_SP_ANY_EU_WORKING_LPAC"/>
+	<value value="89" name="A7XX_PERF_SP_WAVE_ALU_CYCLES"/>
+	<value value="90" name="A7XX_PERF_SP_WAVE_EFU_CYCLES"/>
+	<value value="91" name="A7XX_PERF_SP_WAVE_INT_CYCLES"/>
+	<value value="92" name="A7XX_PERF_SP_WAVE_CSP_CYCLES"/>
+	<value value="93" name="A7XX_PERF_SP_EWAVE_CONTEXTS"/>
+	<value value="94" name="A7XX_PERF_SP_EWAVE_CONTEXT_CYCLES"/>
+	<value value="95" name="A7XX_PERF_SP_LPAC_BUSY_CYCLES"/>
+	<value value="96" name="A7XX_PERF_SP_LPAC_INSTRUCTIONS"/>
+	<value value="97" name="A7XX_PERF_SP_FS_STAGE_1X_WAVES"/>
+	<value value="98" name="A7XX_PERF_SP_FS_STAGE_2X_WAVES"/>
+	<value value="99" name="A7XX_PERF_SP_QUADS"/>
+	<value value="100" name="A7XX_PERF_SP_CS_INVOCATIONS"/>
+	<value value="101" name="A7XX_PERF_SP_PIXELS"/>
+	<value value="102" name="A7XX_PERF_SP_LPAC_DRAWCALLS"/>
+	<value value="103" name="A7XX_PERF_SP_PI_WORKING_CYCLES"/>
+	<value value="104" name="A7XX_PERF_SP_WAVE_INPUT_CYCLES"/>
+	<value value="105" name="A7XX_PERF_SP_WAVE_OUTPUT_CYCLES"/>
+	<value value="106" name="A7XX_PERF_SP_WAVE_HWAVE_WAIT_CYCLES"/>
+	<value value="107" name="A7XX_PERF_SP_WAVE_HWAVE_SYNC"/>
+	<value value="108" name="A7XX_PERF_SP_OUTPUT_3D_PIXELS"/>
+	<value value="109" name="A7XX_PERF_SP_FULL_ALU_MAD_INSTRUCTIONS"/>
+	<value value="110" name="A7XX_PERF_SP_HALF_ALU_MAD_INSTRUCTIONS"/>
+	<value value="111" name="A7XX_PERF_SP_FULL_ALU_MUL_INSTRUCTIONS"/>
+	<value value="112" name="A7XX_PERF_SP_HALF_ALU_MUL_INSTRUCTIONS"/>
+	<value value="113" name="A7XX_PERF_SP_FULL_ALU_ADD_INSTRUCTIONS"/>
+	<value value="114" name="A7XX_PERF_SP_HALF_ALU_ADD_INSTRUCTIONS"/>
+	<value value="115" name="A7XX_PERF_SP_BARY_FP32_INSTRUCTIONS"/>
+	<value value="116" name="A7XX_PERF_SP_ALU_GPR_READ_CYCLES"/>
+	<value value="117" name="A7XX_PERF_SP_ALU_DATA_FORWARDING_CYCLES"/>
+	<value value="118" name="A7XX_PERF_SP_LM_FULL_CYCLES"/>
+	<value value="119" name="A7XX_PERF_SP_TEXTURE_FETCH_LATENCY_CYCLES"/>
+	<value value="120" name="A7XX_PERF_SP_TEXTURE_FETCH_LATENCY_SAMPLES"/>
+	<value value="121" name="A7XX_PERF_SP_FS_STAGE_PI_TEX_INSTRUCTION"/>
+	<value value="122" name="A7XX_PERF_SP_RAY_QUERY_INSTRUCTIONS"/>
+	<value value="123" name="A7XX_PERF_SP_RBRT_KICKOFF_FIBERS"/>
+	<value value="124" name="A7XX_PERF_SP_RBRT_KICKOFF_DQUADS"/>
+	<value value="125" name="A7XX_PERF_SP_RTU_BUSY_CYCLES"/>
+	<value value="126" name="A7XX_PERF_SP_RTU_L0_HITS"/>
+	<value value="127" name="A7XX_PERF_SP_RTU_L0_MISSES"/>
+	<value value="128" name="A7XX_PERF_SP_RTU_L0_HIT_ON_MISS"/>
+	<value value="129" name="A7XX_PERF_SP_RTU_STALL_CYCLES_WAVE_QUEUE"/>
+	<value value="130" name="A7XX_PERF_SP_RTU_STALL_CYCLES_L0_HIT_QUEUE"/>
+	<value value="131" name="A7XX_PERF_SP_RTU_STALL_CYCLES_L0_MISS_QUEUE"/>
+	<value value="132" name="A7XX_PERF_SP_RTU_STALL_CYCLES_L0D_IDX_QUEUE"/>
+	<value value="133" name="A7XX_PERF_SP_RTU_STALL_CYCLES_L0DATA"/>
+	<value value="134" name="A7XX_PERF_SP_RTU_STALL_CYCLES_REPLACE_CNT"/>
+	<value value="135" name="A7XX_PERF_SP_RTU_STALL_CYCLES_MRG_CNT"/>
+	<value value="136" name="A7XX_PERF_SP_RTU_STALL_CYCLES_UCHE"/>
+	<value value="137" name="A7XX_PERF_SP_RTU_OPERAND_FETCH_STALL_CYCLES_L0"/>
+	<value value="138" name="A7XX_PERF_SP_RTU_OPERAND_FETCH_STALL_CYCLES_INS_FIFO"/>
+	<value value="139" name="A7XX_PERF_SP_RTU_BVH_FETCH_LATENCY_CYCLES"/>
+	<value value="140" name="A7XX_PERF_SP_RTU_BVH_FETCH_LATENCY_SAMPLES"/>
+	<value value="141" name="A7XX_PERF_SP_STCHE_MISS_INC_VS"/>
+	<value value="142" name="A7XX_PERF_SP_STCHE_MISS_INC_FS"/>
+	<value value="143" name="A7XX_PERF_SP_STCHE_MISS_INC_BV"/>
+	<value value="144" name="A7XX_PERF_SP_STCHE_MISS_INC_LPAC"/>
+	<value value="145" name="A7XX_PERF_SP_VGPR_ACTIVE_CONTEXTS"/>
+	<value value="146" name="A7XX_PERF_SP_PGPR_ALLOC_CONTEXTS"/>
+	<value value="147" name="A7XX_PERF_SP_VGPR_ALLOC_CONTEXTS"/>
+	<value value="148" name="A7XX_PERF_SP_RTU_RAY_BOX_INTERSECTIONS"/>
+	<value value="149" name="A7XX_PERF_SP_RTU_RAY_TRIANGLE_INTERSECTIONS"/>
+	<value value="150" name="A7XX_PERF_SP_SCH_STALL_CYCLES_RTU"/>
+</enum>
+
+<enum name="a7xx_rb_perfcounter_select">
+	<value value="0" name="A7XX_PERF_RB_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_RB_STALL_CYCLES_HLSQ"/>
+	<value value="2" name="A7XX_PERF_RB_STALL_CYCLES_FIFO0_FULL"/>
+	<value value="3" name="A7XX_PERF_RB_STALL_CYCLES_FIFO1_FULL"/>
+	<value value="4" name="A7XX_PERF_RB_STALL_CYCLES_FIFO2_FULL"/>
+	<value value="5" name="A7XX_PERF_RB_STARVE_CYCLES_SP"/>
+	<value value="6" name="A7XX_PERF_RB_STARVE_CYCLES_LRZ_TILE"/>
+	<value value="7" name="A7XX_PERF_RB_STARVE_CYCLES_CCU"/>
+	<value value="8" name="A7XX_PERF_RB_STARVE_CYCLES_Z_PLANE"/>
+	<value value="9" name="A7XX_PERF_RB_STARVE_CYCLES_BARY_PLANE"/>
+	<value value="10" name="A7XX_PERF_RB_Z_WORKLOAD"/>
+	<value value="11" name="A7XX_PERF_RB_HLSQ_ACTIVE"/>
+	<value value="12" name="A7XX_PERF_RB_Z_READ"/>
+	<value value="13" name="A7XX_PERF_RB_Z_WRITE"/>
+	<value value="14" name="A7XX_PERF_RB_C_READ"/>
+	<value value="15" name="A7XX_PERF_RB_C_WRITE"/>
+	<value value="16" name="A7XX_PERF_RB_TOTAL_PASS"/>
+	<value value="17" name="A7XX_PERF_RB_Z_PASS"/>
+	<value value="18" name="A7XX_PERF_RB_Z_FAIL"/>
+	<value value="19" name="A7XX_PERF_RB_S_FAIL"/>
+	<value value="20" name="A7XX_PERF_RB_BLENDED_FXP_COMPONENTS"/>
+	<value value="21" name="A7XX_PERF_RB_BLENDED_FP16_COMPONENTS"/>
+	<value value="22" name="A7XX_PERF_RB_PS_INVOCATIONS"/>
+	<value value="23" name="A7XX_PERF_RB_2D_ALIVE_CYCLES"/>
+	<value value="24" name="A7XX_PERF_RB_2D_STALL_CYCLES_A2D"/>
+	<value value="25" name="A7XX_PERF_RB_2D_STARVE_CYCLES_SRC"/>
+	<value value="26" name="A7XX_PERF_RB_2D_STARVE_CYCLES_SP"/>
+	<value value="27" name="A7XX_PERF_RB_2D_STARVE_CYCLES_DST"/>
+	<value value="28" name="A7XX_PERF_RB_2D_VALID_PIXELS"/>
+	<value value="29" name="A7XX_PERF_RB_3D_PIXELS"/>
+	<value value="30" name="A7XX_PERF_RB_BLENDER_WORKING_CYCLES"/>
+	<value value="31" name="A7XX_PERF_RB_ZPROC_WORKING_CYCLES"/>
+	<value value="32" name="A7XX_PERF_RB_CPROC_WORKING_CYCLES"/>
+	<value value="33" name="A7XX_PERF_RB_SAMPLER_WORKING_CYCLES"/>
+	<value value="34" name="A7XX_PERF_RB_STALL_CYCLES_CCU_COLOR_READ"/>
+	<value value="35" name="A7XX_PERF_RB_STALL_CYCLES_CCU_COLOR_WRITE"/>
+	<value value="36" name="A7XX_PERF_RB_STALL_CYCLES_CCU_DEPTH_READ"/>
+	<value value="37" name="A7XX_PERF_RB_STALL_CYCLES_CCU_DEPTH_WRITE"/>
+	<value value="38" name="A7XX_PERF_RB_STALL_CYCLES_VPC"/>
+	<value value="39" name="A7XX_PERF_RB_2D_INPUT_TRANS"/>
+	<value value="40" name="A7XX_PERF_RB_2D_OUTPUT_RB_DST_TRANS"/>
+	<value value="41" name="A7XX_PERF_RB_2D_OUTPUT_RB_SRC_TRANS"/>
+	<value value="42" name="A7XX_PERF_RB_BLENDED_FP32_COMPONENTS"/>
+	<value value="43" name="A7XX_PERF_RB_COLOR_PIX_TILES"/>
+	<value value="44" name="A7XX_PERF_RB_STALL_CYCLES_CCU"/>
+	<value value="45" name="A7XX_PERF_RB_EARLY_Z_ARB3_GRANT"/>
+	<value value="46" name="A7XX_PERF_RB_LATE_Z_ARB3_GRANT"/>
+	<value value="47" name="A7XX_PERF_RB_EARLY_Z_SKIP_GRANT"/>
+	<value value="48" name="A7XX_PERF_RB_VRS_1x1_QUADS"/>
+	<value value="49" name="A7XX_PERF_RB_VRS_2x1_QUADS"/>
+	<value value="50" name="A7XX_PERF_RB_VRS_1x2_QUADS"/>
+	<value value="51" name="A7XX_PERF_RB_VRS_2x2_QUADS"/>
+	<value value="52" name="A7XX_PERF_RB_VRS_4x2_QUADS"/>
+	<value value="53" name="A7XX_PERF_RB_VRS_4x4_QUADS"/>
+</enum>
+
+<enum name="a7xx_vsc_perfcounter_select">
+	<value value="0" name="A7XX_PERF_VSC_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_VSC_WORKING_CYCLES"/>
+	<value value="2" name="A7XX_PERF_VSC_STALL_CYCLES_UCHE"/>
+	<value value="3" name="A7XX_PERF_VSC_EOT_NUM"/>
+	<value value="4" name="A7XX_PERF_VSC_INPUT_TILES"/>
+</enum>
+
+<enum name="a7xx_ccu_perfcounter_select">
+	<value value="0" name="A7XX_PERF_CCU_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_CCU_STALL_CYCLES_RB_DEPTH_RETURN"/>
+	<value value="2" name="A7XX_PERF_CCU_STALL_CYCLES_RB_COLOR_RETURN"/>
+	<value value="3" name="A7XX_PERF_CCU_DEPTH_BLOCKS"/>
+	<value value="4" name="A7XX_PERF_CCU_COLOR_BLOCKS"/>
+	<value value="5" name="A7XX_PERF_CCU_DEPTH_BLOCK_HIT"/>
+	<value value="6" name="A7XX_PERF_CCU_COLOR_BLOCK_HIT"/>
+	<value value="7" name="A7XX_PERF_CCU_PARTIAL_BLOCK_READ"/>
+	<value value="8" name="A7XX_PERF_CCU_GMEM_READ"/>
+	<value value="9" name="A7XX_PERF_CCU_GMEM_WRITE"/>
+	<value value="10" name="A7XX_PERF_CCU_2D_RD_REQ"/>
+	<value value="11" name="A7XX_PERF_CCU_2D_WR_REQ"/>
+	<value value="12" name="A7XX_PERF_CCU_UBWC_COLOR_BLOCKS_CONCURRENT"/>
+	<value value="13" name="A7XX_PERF_CCU_UBWC_DEPTH_BLOCKS_CONCURRENT"/>
+	<value value="14" name="A7XX_PERF_CCU_COLOR_RESOLVE_DROPPED"/>
+	<value value="15" name="A7XX_PERF_CCU_DEPTH_RESOLVE_DROPPED"/>
+	<value value="16" name="A7XX_PERF_CCU_COLOR_RENDER_CONCURRENT"/>
+	<value value="17" name="A7XX_PERF_CCU_DEPTH_RENDER_CONCURRENT"/>
+	<value value="18" name="A7XX_PERF_CCU_COLOR_RESOLVE_AFTER_RENDER"/>
+	<value value="19" name="A7XX_PERF_CCU_DEPTH_RESOLVE_AFTER_RENDER"/>
+	<value value="20" name="A7XX_PERF_CCU_GMEM_EXTRA_DEPTH_READ"/>
+	<value value="21" name="A7XX_PERF_CCU_GMEM_COLOR_READ_4AA"/>
+	<value value="22" name="A7XX_PERF_CCU_GMEM_COLOR_READ_4AA_FULL"/>
+</enum>
+
+<enum name="a7xx_lrz_perfcounter_select">
+	<value value="0" name="A7XX_PERF_LRZ_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_LRZ_STARVE_CYCLES_RAS"/>
+	<value value="2" name="A7XX_PERF_LRZ_STALL_CYCLES_RB"/>
+	<value value="3" name="A7XX_PERF_LRZ_STALL_CYCLES_VSC"/>
+	<value value="4" name="A7XX_PERF_LRZ_STALL_CYCLES_VPC"/>
+	<value value="5" name="A7XX_PERF_LRZ_STALL_CYCLES_FLAG_PREFETCH"/>
+	<value value="6" name="A7XX_PERF_LRZ_STALL_CYCLES_UCHE"/>
+	<value value="7" name="A7XX_PERF_LRZ_LRZ_READ"/>
+	<value value="8" name="A7XX_PERF_LRZ_LRZ_WRITE"/>
+	<value value="9" name="A7XX_PERF_LRZ_READ_LATENCY"/>
+	<value value="10" name="A7XX_PERF_LRZ_MERGE_CACHE_UPDATING"/>
+	<value value="11" name="A7XX_PERF_LRZ_PRIM_KILLED_BY_MASKGEN"/>
+	<value value="12" name="A7XX_PERF_LRZ_PRIM_KILLED_BY_LRZ"/>
+	<value value="13" name="A7XX_PERF_LRZ_VISIBLE_PRIM_AFTER_LRZ"/>
+	<value value="14" name="A7XX_PERF_LRZ_FULL_8X8_TILES"/>
+	<value value="15" name="A7XX_PERF_LRZ_PARTIAL_8X8_TILES"/>
+	<value value="16" name="A7XX_PERF_LRZ_TILE_KILLED"/>
+	<value value="17" name="A7XX_PERF_LRZ_TOTAL_PIXEL"/>
+	<value value="18" name="A7XX_PERF_LRZ_VISIBLE_PIXEL_AFTER_LRZ"/>
+	<value value="19" name="A7XX_PERF_LRZ_FEEDBACK_ACCEPT"/>
+	<value value="20" name="A7XX_PERF_LRZ_FEEDBACK_DISCARD"/>
+	<value value="21" name="A7XX_PERF_LRZ_FEEDBACK_STALL"/>
+	<value value="22" name="A7XX_PERF_LRZ_STALL_CYCLES_RB_ZPLANE"/>
+	<value value="23" name="A7XX_PERF_LRZ_STALL_CYCLES_RB_BPLANE"/>
+	<value value="24" name="A7XX_PERF_LRZ_RAS_MASK_TRANS"/>
+	<value value="25" name="A7XX_PERF_LRZ_STALL_CYCLES_MVC"/>
+	<value value="26" name="A7XX_PERF_LRZ_TILE_KILLED_BY_IMAGE_VRS"/>
+	<value value="27" name="A7XX_PERF_LRZ_TILE_KILLED_BY_Z"/>
+</enum>
+
+<enum name="a7xx_cmp_perfcounter_select">
+	<value value="0" name="A7XX_PERF_CMPDECMP_STALL_CYCLES_ARB"/>
+	<value value="1" name="A7XX_PERF_CMPDECMP_VBIF_LATENCY_CYCLES"/>
+	<value value="2" name="A7XX_PERF_CMPDECMP_VBIF_LATENCY_SAMPLES"/>
+	<value value="3" name="A7XX_PERF_CMPDECMP_VBIF_READ_DATA_CCU"/>
+	<value value="4" name="A7XX_PERF_CMPDECMP_VBIF_WRITE_DATA_CCU"/>
+	<value value="5" name="A7XX_PERF_CMPDECMP_VBIF_READ_REQUEST"/>
+	<value value="6" name="A7XX_PERF_CMPDECMP_VBIF_WRITE_REQUEST"/>
+	<value value="7" name="A7XX_PERF_CMPDECMP_VBIF_READ_DATA"/>
+	<value value="8" name="A7XX_PERF_CMPDECMP_VBIF_WRITE_DATA"/>
+	<value value="9" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG1_COUNT"/>
+	<value value="10" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG2_COUNT"/>
+	<value value="11" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG3_COUNT"/>
+	<value value="12" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG4_COUNT"/>
+	<value value="13" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG5_COUNT"/>
+	<value value="14" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG6_COUNT"/>
+	<value value="15" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG8_COUNT"/>
+	<value value="16" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG1_COUNT"/>
+	<value value="17" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG2_COUNT"/>
+	<value value="18" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG3_COUNT"/>
+	<value value="19" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG4_COUNT"/>
+	<value value="20" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG5_COUNT"/>
+	<value value="21" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG6_COUNT"/>
+	<value value="22" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG8_COUNT"/>
+	<value value="23" name="A7XX_PERF_CMPDECMP_VBIF_READ_DATA_UCHE_CH0"/>
+	<value value="24" name="A7XX_PERF_CMPDECMP_VBIF_READ_DATA_UCHE_CH1"/>
+	<value value="25" name="A7XX_PERF_CMPDECMP_VBIF_WRITE_DATA_UCHE"/>
+	<value value="26" name="A7XX_PERF_CMPDECMP_DEPTH_WRITE_FLAG0_COUNT"/>
+	<value value="27" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAG0_COUNT"/>
+	<value value="28" name="A7XX_PERF_CMPDECMP_COLOR_WRITE_FLAGALPHA_COUNT"/>
+	<value value="29" name="A7XX_PERF_CMPDECMP_RESOLVE_EVENTS"/>
+	<value value="30" name="A7XX_PERF_CMPDECMP_CONCURRENT_RESOLVE_EVENTS"/>
+	<value value="31" name="A7XX_PERF_CMPDECMP_DROPPED_CLEAR_EVENTS"/>
+	<value value="32" name="A7XX_PERF_CMPDECMP_ST_BLOCKS_CONCURRENT"/>
+	<value value="33" name="A7XX_PERF_CMPDECMP_LRZ_ST_BLOCKS_CONCURRENT"/>
+	<value value="34" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG0_COUNT"/>
+	<value value="35" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG1_COUNT"/>
+	<value value="36" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG2_COUNT"/>
+	<value value="37" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG3_COUNT"/>
+	<value value="38" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG4_COUNT"/>
+	<value value="39" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG5_COUNT"/>
+	<value value="40" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG6_COUNT"/>
+	<value value="41" name="A7XX_PERF_CMPDECMP_DEPTH_READ_FLAG8_COUNT"/>
+	<value value="42" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG0_COUNT"/>
+	<value value="43" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG1_COUNT"/>
+	<value value="44" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG2_COUNT"/>
+	<value value="45" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG3_COUNT"/>
+	<value value="46" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG4_COUNT"/>
+	<value value="47" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG5_COUNT"/>
+	<value value="48" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG6_COUNT"/>
+	<value value="49" name="A7XX_PERF_CMPDECMP_COLOR_READ_FLAG8_COUNT"/>
+</enum>
+
+<enum name="a7xx_gbif_perfcounter_select">
+	<value value="0" name="A7XX_PERF_GBIF_RESERVED_0"/>
+	<value value="1" name="A7XX_PERF_GBIF_RESERVED_1"/>
+	<value value="2" name="A7XX_PERF_GBIF_RESERVED_2"/>
+	<value value="3" name="A7XX_PERF_GBIF_RESERVED_3"/>
+	<value value="4" name="A7XX_PERF_GBIF_RESERVED_4"/>
+	<value value="5" name="A7XX_PERF_GBIF_RESERVED_5"/>
+	<value value="6" name="A7XX_PERF_GBIF_RESERVED_6"/>
+	<value value="7" name="A7XX_PERF_GBIF_RESERVED_7"/>
+	<value value="8" name="A7XX_PERF_GBIF_RESERVED_8"/>
+	<value value="9" name="A7XX_PERF_GBIF_RESERVED_9"/>
+	<value value="10" name="A7XX_PERF_GBIF_AXI0_READ_REQUESTS_TOTAL"/>
+	<value value="11" name="A7XX_PERF_GBIF_AXI1_READ_REQUESTS_TOTAL"/>
+	<value value="12" name="A7XX_PERF_GBIF_RESERVED_12"/>
+	<value value="13" name="A7XX_PERF_GBIF_RESERVED_13"/>
+	<value value="14" name="A7XX_PERF_GBIF_RESERVED_14"/>
+	<value value="15" name="A7XX_PERF_GBIF_RESERVED_15"/>
+	<value value="16" name="A7XX_PERF_GBIF_RESERVED_16"/>
+	<value value="17" name="A7XX_PERF_GBIF_RESERVED_17"/>
+	<value value="18" name="A7XX_PERF_GBIF_RESERVED_18"/>
+	<value value="19" name="A7XX_PERF_GBIF_RESERVED_19"/>
+	<value value="20" name="A7XX_PERF_GBIF_RESERVED_20"/>
+	<value value="21" name="A7XX_PERF_GBIF_RESERVED_21"/>
+	<value value="22" name="A7XX_PERF_GBIF_AXI0_WRITE_REQUESTS_TOTAL"/>
+	<value value="23" name="A7XX_PERF_GBIF_AXI1_WRITE_REQUESTS_TOTAL"/>
+	<value value="24" name="A7XX_PERF_GBIF_RESERVED_24"/>
+	<value value="25" name="A7XX_PERF_GBIF_RESERVED_25"/>
+	<value value="26" name="A7XX_PERF_GBIF_RESERVED_26"/>
+	<value value="27" name="A7XX_PERF_GBIF_RESERVED_27"/>
+	<value value="28" name="A7XX_PERF_GBIF_RESERVED_28"/>
+	<value value="29" name="A7XX_PERF_GBIF_RESERVED_29"/>
+	<value value="30" name="A7XX_PERF_GBIF_RESERVED_30"/>
+	<value value="31" name="A7XX_PERF_GBIF_RESERVED_31"/>
+	<value value="32" name="A7XX_PERF_GBIF_RESERVED_32"/>
+	<value value="33" name="A7XX_PERF_GBIF_RESERVED_33"/>
+	<value value="34" name="A7XX_PERF_GBIF_AXI0_READ_DATA_BEATS_TOTAL"/>
+	<value value="35" name="A7XX_PERF_GBIF_AXI1_READ_DATA_BEATS_TOTAL"/>
+	<value value="36" name="A7XX_PERF_GBIF_RESERVED_36"/>
+	<value value="37" name="A7XX_PERF_GBIF_RESERVED_37"/>
+	<value value="38" name="A7XX_PERF_GBIF_RESERVED_38"/>
+	<value value="39" name="A7XX_PERF_GBIF_RESERVED_39"/>
+	<value value="40" name="A7XX_PERF_GBIF_RESERVED_40"/>
+	<value value="41" name="A7XX_PERF_GBIF_RESERVED_41"/>
+	<value value="42" name="A7XX_PERF_GBIF_RESERVED_42"/>
+	<value value="43" name="A7XX_PERF_GBIF_RESERVED_43"/>
+	<value value="44" name="A7XX_PERF_GBIF_RESERVED_44"/>
+	<value value="45" name="A7XX_PERF_GBIF_RESERVED_45"/>
+	<value value="46" name="A7XX_PERF_GBIF_AXI0_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="47" name="A7XX_PERF_GBIF_AXI1_WRITE_DATA_BEATS_TOTAL"/>
+	<value value="48" name="A7XX_PERF_GBIF_RESERVED_48"/>
+	<value value="49" name="A7XX_PERF_GBIF_RESERVED_49"/>
+	<value value="50" name="A7XX_PERF_GBIF_RESERVED_50"/>
+	<value value="51" name="A7XX_PERF_GBIF_RESERVED_51"/>
+	<value value="52" name="A7XX_PERF_GBIF_RESERVED_52"/>
+	<value value="53" name="A7XX_PERF_GBIF_RESERVED_53"/>
+	<value value="54" name="A7XX_PERF_GBIF_RESERVED_54"/>
+	<value value="55" name="A7XX_PERF_GBIF_RESERVED_55"/>
+	<value value="56" name="A7XX_PERF_GBIF_RESERVED_56"/>
+	<value value="57" name="A7XX_PERF_GBIF_RESERVED_57"/>
+	<value value="58" name="A7XX_PERF_GBIF_RESERVED_58"/>
+	<value value="59" name="A7XX_PERF_GBIF_RESERVED_59"/>
+	<value value="60" name="A7XX_PERF_GBIF_RESERVED_60"/>
+	<value value="61" name="A7XX_PERF_GBIF_RESERVED_61"/>
+	<value value="62" name="A7XX_PERF_GBIF_RESERVED_62"/>
+	<value value="63" name="A7XX_PERF_GBIF_RESERVED_63"/>
+	<value value="64" name="A7XX_PERF_GBIF_RESERVED_64"/>
+	<value value="65" name="A7XX_PERF_GBIF_RESERVED_65"/>
+	<value value="66" name="A7XX_PERF_GBIF_RESERVED_66"/>
+	<value value="67" name="A7XX_PERF_GBIF_RESERVED_67"/>
+	<value value="68" name="A7XX_PERF_GBIF_CYCLES_CH0_HELD_OFF_RD_ALL"/>
+	<value value="69" name="A7XX_PERF_GBIF_CYCLES_CH1_HELD_OFF_RD_ALL"/>
+	<value value="70" name="A7XX_PERF_GBIF_CYCLES_CH0_HELD_OFF_WR_ALL"/>
+	<value value="71" name="A7XX_PERF_GBIF_CYCLES_CH1_HELD_OFF_WR_ALL"/>
+	<value value="72" name="A7XX_PERF_GBIF_AXI_CH0_REQUEST_HELD_OFF"/>
+	<value value="73" name="A7XX_PERF_GBIF_AXI_CH1_REQUEST_HELD_OFF"/>
+	<value value="74" name="A7XX_PERF_GBIF_AXI_REQUEST_HELD_OFF"/>
+	<value value="75" name="A7XX_PERF_GBIF_AXI_CH0_WRITE_DATA_HELD_OFF"/>
+	<value value="76" name="A7XX_PERF_GBIF_AXI_CH1_WRITE_DATA_HELD_OFF"/>
+	<value value="77" name="A7XX_PERF_GBIF_AXI_ALL_WRITE_DATA_HELD_OFF"/>
+	<value value="78" name="A7XX_PERF_GBIF_AXI_ALL_READ_BEATS"/>
+	<value value="79" name="A7XX_PERF_GBIF_AXI_ALL_WRITE_BEATS"/>
+	<value value="80" name="A7XX_PERF_GBIF_AXI_ALL_BEATS"/>
+</enum>
+
+<enum name="a7xx_ufc_perfcounter_select">
+	<value value="0" name="A7XX_PERF_UFC_BUSY_CYCLES"/>
+	<value value="1" name="A7XX_PERF_UFC_READ_DATA_VBIF"/>
+	<value value="2" name="A7XX_PERF_UFC_WRITE_DATA_VBIF"/>
+	<value value="3" name="A7XX_PERF_UFC_READ_REQUEST_VBIF"/>
+	<value value="4" name="A7XX_PERF_UFC_WRITE_REQUEST_VBIF"/>
+	<value value="5" name="A7XX_PERF_UFC_LRZ_FILTER_HIT"/>
+	<value value="6" name="A7XX_PERF_UFC_LRZ_FILTER_MISS"/>
+	<value value="7" name="A7XX_PERF_UFC_CRE_FILTER_HIT"/>
+	<value value="8" name="A7XX_PERF_UFC_CRE_FILTER_MISS"/>
+	<value value="9" name="A7XX_PERF_UFC_SP_FILTER_HIT"/>
+	<value value="10" name="A7XX_PERF_UFC_SP_FILTER_MISS"/>
+	<value value="11" name="A7XX_PERF_UFC_SP_REQUESTS"/>
+	<value value="12" name="A7XX_PERF_UFC_TP_FILTER_HIT"/>
+	<value value="13" name="A7XX_PERF_UFC_TP_FILTER_MISS"/>
+	<value value="14" name="A7XX_PERF_UFC_TP_REQUESTS"/>
+	<value value="15" name="A7XX_PERF_UFC_MAIN_HIT_LRZ_PREFETCH"/>
+	<value value="16" name="A7XX_PERF_UFC_MAIN_HIT_CRE_PREFETCH"/>
+	<value value="17" name="A7XX_PERF_UFC_MAIN_HIT_SP_PREFETCH"/>
+	<value value="18" name="A7XX_PERF_UFC_MAIN_HIT_TP_PREFETCH"/>
+	<value value="19" name="A7XX_PERF_UFC_MAIN_HIT_UBWC_READ"/>
+	<value value="20" name="A7XX_PERF_UFC_MAIN_HIT_UBWC_WRITE"/>
+	<value value="21" name="A7XX_PERF_UFC_MAIN_MISS_LRZ_PREFETCH"/>
+	<value value="22" name="A7XX_PERF_UFC_MAIN_MISS_CRE_PREFETCH"/>
+	<value value="23" name="A7XX_PERF_UFC_MAIN_MISS_SP_PREFETCH"/>
+	<value value="24" name="A7XX_PERF_UFC_MAIN_MISS_TP_PREFETCH"/>
+	<value value="25" name="A7XX_PERF_UFC_MAIN_MISS_UBWC_READ"/>
+	<value value="26" name="A7XX_PERF_UFC_MAIN_MISS_UBWC_WRITE"/>
+	<value value="27" name="A7XX_PERF_UFC_UBWC_READ_UFC_TRANS"/>
+	<value value="28" name="A7XX_PERF_UFC_UBWC_WRITE_UFC_TRANS"/>
+	<value value="29" name="A7XX_PERF_UFC_STALL_CYCLES_GBIF_CMD"/>
+	<value value="30" name="A7XX_PERF_UFC_STALL_CYCLES_GBIF_RDATA"/>
+	<value value="31" name="A7XX_PERF_UFC_STALL_CYCLES_GBIF_WDATA"/>
+	<value value="32" name="A7XX_PERF_UFC_STALL_CYCLES_UBWC_WR_FLAG"/>
+	<value value="33" name="A7XX_PERF_UFC_STALL_CYCLES_UBWC_FLAG_RTN"/>
+	<value value="34" name="A7XX_PERF_UFC_STALL_CYCLES_UBWC_EVENT"/>
+	<value value="35" name="A7XX_PERF_UFC_LRZ_PREFETCH_STALLED_CYCLES"/>
+	<value value="36" name="A7XX_PERF_UFC_CRE_PREFETCH_STALLED_CYCLES"/>
+	<value value="37" name="A7XX_PERF_UFC_SPTP_PREFETCH_STALLED_CYCLES"/>
+	<value value="38" name="A7XX_PERF_UFC_UBWC_RD_STALLED_CYCLES"/>
+	<value value="39" name="A7XX_PERF_UFC_UBWC_WR_STALLED_CYCLES"/>
+	<value value="40" name="A7XX_PERF_UFC_PREFETCH_STALLED_CYCLES"/>
+	<value value="41" name="A7XX_PERF_UFC_EVICTION_STALLED_CYCLES"/>
+	<value value="42" name="A7XX_PERF_UFC_LOCK_STALLED_CYCLES"/>
+	<value value="43" name="A7XX_PERF_UFC_MISS_LATENCY_CYCLES"/>
+	<value value="44" name="A7XX_PERF_UFC_MISS_LATENCY_SAMPLES"/>
+	<value value="45" name="A7XX_PERF_UFC_UBWC_REQ_STALLED_CYCLES"/>
+	<value value="46" name="A7XX_PERF_UFC_TP_HINT_TAG_MISS"/>
+	<value value="47" name="A7XX_PERF_UFC_TP_HINT_TAG_HIT_RDY"/>
+	<value value="48" name="A7XX_PERF_UFC_TP_HINT_TAG_HIT_NRDY"/>
+	<value value="49" name="A7XX_PERF_UFC_TP_HINT_IS_FCLEAR"/>
+	<value value="50" name="A7XX_PERF_UFC_TP_HINT_IS_ALPHA0"/>
+	<value value="51" name="A7XX_PERF_UFC_SP_L1_FILTER_HIT"/>
+	<value value="52" name="A7XX_PERF_UFC_SP_L1_FILTER_MISS"/>
+	<value value="53" name="A7XX_PERF_UFC_SP_L1_FILTER_REQUESTS"/>
+	<value value="54" name="A7XX_PERF_UFC_TP_L1_TAG_HIT_RDY"/>
+	<value value="55" name="A7XX_PERF_UFC_TP_L1_TAG_HIT_NRDY"/>
+	<value value="56" name="A7XX_PERF_UFC_TP_L1_TAG_MISS"/>
+	<value value="57" name="A7XX_PERF_UFC_TP_L1_FILTER_REQUESTS"/>
+</enum>
+
+<domain name="A6XX" width="32" prefix="variant" varset="chip">
+	<bitset name="A6XX_RBBM_INT_0_MASK" inline="no" varset="chip">
+		<bitfield name="RBBM_GPU_IDLE" pos="0" type="boolean"/>
+		<bitfield name="CP_AHB_ERROR" pos="1" type="boolean"/>
+		<bitfield name="CP_IPC_INTR_0" pos="4" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_IPC_INTR_1" pos="5" type="boolean" variants="A7XX-"/>
+		<bitfield name="RBBM_ATB_ASYNCFIFO_OVERFLOW" pos="6" type="boolean"/>
+		<bitfield name="RBBM_GPC_ERROR" pos="7" type="boolean"/>
+		<bitfield name="CP_SW" pos="8" type="boolean"/>
+		<bitfield name="CP_HW_ERROR" pos="9" type="boolean"/>
+		<bitfield name="CP_CCU_FLUSH_DEPTH_TS" pos="10" type="boolean"/>
+		<bitfield name="CP_CCU_FLUSH_COLOR_TS" pos="11" type="boolean"/>
+		<bitfield name="CP_CCU_RESOLVE_TS" pos="12" type="boolean"/>
+		<bitfield name="CP_IB2" pos="13" type="boolean"/>
+		<bitfield name="CP_IB1" pos="14" type="boolean"/>
+		<bitfield name="CP_RB" pos="15" type="boolean" variants="A6XX"/>
+		<!-- Same as above but different name??: -->
+		<bitfield name="PM4CPINTERRUPT" pos="15" type="boolean" variants="A7XX-"/>
+		<bitfield name="PM4CPINTERRUPTLPAC" pos="16" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_RB_DONE_TS" pos="17" type="boolean"/>
+		<bitfield name="CP_WT_DONE_TS" pos="18" type="boolean"/>
+		<bitfield name="CP_CACHE_FLUSH_TS" pos="20" type="boolean"/>
+		<bitfield name="CP_CACHE_FLUSH_TS_LPAC" pos="21" type="boolean" variants="A7XX-"/>
+		<bitfield name="RBBM_ATB_BUS_OVERFLOW" pos="22" type="boolean"/>
+		<bitfield name="RBBM_HANG_DETECT" pos="23" type="boolean"/>
+		<bitfield name="UCHE_OOB_ACCESS" pos="24" type="boolean"/>
+		<bitfield name="UCHE_TRAP_INTR" pos="25" type="boolean"/>
+		<bitfield name="DEBBUS_INTR_0" pos="26" type="boolean"/>
+		<bitfield name="DEBBUS_INTR_1" pos="27" type="boolean"/>
+		<bitfield name="TSBWRITEERROR" pos="28" type="boolean" variants="A7XX-"/>
+		<bitfield name="SWFUSEVIOLATION" pos="29" type="boolean" variants="A7XX-"/>
+		<bitfield name="ISDB_CPU_IRQ" pos="30" type="boolean"/>
+		<bitfield name="ISDB_UNDER_DEBUG" pos="31" type="boolean"/>
+	</bitset>
+
+	<!--
+		Note the _LPAC bits probably *actually* first appeared in a660, but the
+		_BV bits are new in a7xx
+	 -->
+	<bitset name="A6XX_CP_INT" varset="chip">
+		<bitfield name="CP_OPCODE_ERROR" pos="0" type="boolean"/>
+		<bitfield name="CP_UCODE_ERROR" pos="1" type="boolean"/>
+		<bitfield name="CP_HW_FAULT_ERROR" pos="2" type="boolean"/>
+		<bitfield name="CP_REGISTER_PROTECTION_ERROR" pos="4" type="boolean"/>
+		<bitfield name="CP_AHB_ERROR" pos="5" type="boolean"/>
+		<bitfield name="CP_VSD_PARITY_ERROR" pos="6" type="boolean"/>
+		<bitfield name="CP_ILLEGAL_INSTR_ERROR" pos="7" type="boolean"/>
+		<bitfield name="CP_OPCODE_ERROR_LPAC" pos="8" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_UCODE_ERROR_LPAC" pos="9" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_HW_FAULT_ERROR_LPAC" pos="10" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_REGISTER_PROTECTION_ERROR_LPAC" pos="11" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_ILLEGAL_INSTR_ERROR_LPAC" pos="12" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_OPCODE_ERROR_BV" pos="13" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_UCODE_ERROR_BV" pos="14" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_HW_FAULT_ERROR_BV" pos="15" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_REGISTER_PROTECTION_ERROR_BV" pos="16" type="boolean" variants="A7XX-"/>
+		<bitfield name="CP_ILLEGAL_INSTR_ERROR_BV" pos="17" type="boolean" variants="A7XX-"/>
+	</bitset>
+
+	<reg64 offset="0x0800" name="CP_RB_BASE"/>
+	<reg32 offset="0x0802" name="CP_RB_CNTL"/>
+	<reg64 offset="0x0804" name="CP_RB_RPTR_ADDR"/>
+	<reg32 offset="0x0806" name="CP_RB_RPTR"/>
+	<reg32 offset="0x0807" name="CP_RB_WPTR"/>
+	<reg32 offset="0x0808" name="CP_SQE_CNTL"/>
+	<reg32 offset="0x0812" name="CP_CP2GMU_STATUS">
+		<bitfield name="IFPC" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0821" name="CP_HW_FAULT"/>
+	<reg32 offset="0x0823" name="CP_INTERRUPT_STATUS" type="A6XX_CP_INT"/>
+	<reg32 offset="0x0824" name="CP_PROTECT_STATUS"/>
+	<reg32 offset="0x0825" name="CP_STATUS_1"/>
+	<reg64 offset="0x0830" name="CP_SQE_INSTR_BASE"/>
+	<reg32 offset="0x0840" name="CP_MISC_CNTL"/>
+	<reg32 offset="0x0844" name="CP_APRIV_CNTL">
+		<!-- Crashdumper writes -->
+		<bitfield pos="6" name="CDWRITE" type="boolean"/>
+		<!-- Crashdumper reads -->
+		<bitfield pos="5" name="CDREAD" type="boolean"/>
+
+		<!-- 4 is unknown -->
+
+		<!-- RPTR shadow writes -->
+		<bitfield pos="3" name="RBRPWB" type="boolean"/>
+		<!-- Memory accesses from PM4 packets in the ringbuffer -->
+		<bitfield pos="2" name="RBPRIVLEVEL" type="boolean"/>
+		<!-- Ringbuffer reads -->
+		<bitfield pos="1" name="RBFETCH" type="boolean"/>
+		<!-- Instruction cache fetches -->
+		<bitfield pos="0" name="ICACHE" type="boolean"/>
+	</reg32>
+	<!-- Preemptions taking longer than this threshold increment PERF_CP_LONG_PREEMPTIONS: -->
+	<reg32 offset="0x08C0" name="CP_PREEMPT_THRESHOLD"/>
+	<!-- all the threshold values seem to be in units of quad-dwords: -->
+	<reg32 offset="0x08C1" name="CP_ROQ_THRESHOLDS_1">
+		<doc>
+			b0..7 identifies where MRB data starts (and RB data ends)
+			b8.15 identifies where VSD data starts (and MRB data ends)
+			b16..23 identifies where IB1 data starts (and RB data ends)
+			b24..31 identifies where IB2 data starts (and IB1 data ends)
+		</doc>
+		<bitfield name="MRB_START" low="0" high="7" shr="2"/>
+		<bitfield name="VSD_START" low="8" high="15" shr="2"/>
+		<bitfield name="IB1_START" low="16" high="23" shr="2"/>
+		<bitfield name="IB2_START" low="24" high="31" shr="2"/>
+	</reg32>
+	<reg32 offset="0x08C2" name="CP_ROQ_THRESHOLDS_2">
+		<doc>
+			low bits identify where CP_SET_DRAW_STATE stateobj
+			processing starts (and IB2 data ends). I'm guessing
+			b8 is part of this since (from downstream kgsl):
+
+				/* ROQ sizes are twice as big on a640/a680 than on a630 */
+				if (adreno_is_a640(adreno_dev) || adreno_is_a680(adreno_dev)) {
+					kgsl_regwrite(device, A6XX_CP_ROQ_THRESHOLDS_2, 0x02000140);
+					kgsl_regwrite(device, A6XX_CP_ROQ_THRESHOLDS_1, 0x8040362C);
+				} ...
+		</doc>
+		<bitfield name="SDS_START" low="0" high="8" shr="2"/>
+		<!-- total ROQ size: -->
+		<bitfield name="ROQ_SIZE" low="16" high="31" shr="2"/>
+	</reg32>
+	<reg32 offset="0x08C3" name="CP_MEM_POOL_SIZE"/>
+	<reg32 offset="0x0841" name="CP_CHICKEN_DBG"/>
+	<reg32 offset="0x0842" name="CP_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0843" name="CP_DBG_ECO_CNTL"/>
+	<reg32 offset="0x084F" name="CP_PROTECT_CNTL">
+		<bitfield pos="3" name="LAST_SPAN_INF_RANGE" type="boolean"/>
+		<bitfield pos="1" name="ACCESS_FAULT_ON_VIOL_EN" type="boolean"/>
+		<bitfield pos="0" name="ACCESS_PROT_EN" type="boolean"/>
+	</reg32>
+
+	<array offset="0x0883" name="CP_SCRATCH" stride="1" length="8">
+		<reg32 offset="0x0" name="REG" type="uint"/>
+	</array>
+	<array offset="0x0850" name="CP_PROTECT" stride="1" length="32">
+		<reg32 offset="0x0" name="REG" type="a6x_cp_protect"/>
+	</array>
+
+	<reg32 offset="0x08A0" name="CP_CONTEXT_SWITCH_CNTL">
+		<bitfield name="STOP" pos="0" type="boolean"/>
+		<bitfield name="LEVEL" low="6" high="7"/>
+		<bitfield name="USES_GMEM" pos="8" type="boolean"/>
+		<bitfield name="SKIP_SAVE_RESTORE" pos="9" type="boolean"/>
+	</reg32>
+	<reg64 offset="0x08A1" name="CP_CONTEXT_SWITCH_SMMU_INFO"/>
+	<reg64 offset="0x08A3" name="CP_CONTEXT_SWITCH_PRIV_NON_SECURE_RESTORE_ADDR"/>
+	<reg64 offset="0x08A5" name="CP_CONTEXT_SWITCH_PRIV_SECURE_RESTORE_ADDR"/>
+	<reg64 offset="0x08A7" name="CP_CONTEXT_SWITCH_NON_PRIV_RESTORE_ADDR"/>
+	<reg32 offset="0x08ab" name="CP_CONTEXT_SWITCH_LEVEL_STATUS" variants="A7XX-"/>
+	<array offset="0x08D0" name="CP_PERFCTR_CP_SEL" stride="1" length="14"/>
+	<array offset="0x08e0" name="CP_BV_PERFCTR_CP_SEL" stride="1" length="7" variants="A7XX-"/>
+	<reg64 offset="0x0900" name="CP_CRASH_SCRIPT_BASE"/>
+	<reg32 offset="0x0902" name="CP_CRASH_DUMP_CNTL"/>
+	<reg32 offset="0x0903" name="CP_CRASH_DUMP_STATUS"/>
+	<reg32 offset="0x0908" name="CP_SQE_STAT_ADDR"/>
+	<reg32 offset="0x0909" name="CP_SQE_STAT_DATA"/>
+	<reg32 offset="0x090A" name="CP_DRAW_STATE_ADDR"/>
+	<reg32 offset="0x090B" name="CP_DRAW_STATE_DATA"/>
+	<reg32 offset="0x090C" name="CP_ROQ_DBG_ADDR"/>
+	<reg32 offset="0x090D" name="CP_ROQ_DBG_DATA"/>
+	<reg32 offset="0x090E" name="CP_MEM_POOL_DBG_ADDR"/>
+	<reg32 offset="0x090F" name="CP_MEM_POOL_DBG_DATA"/>
+	<reg32 offset="0x0910" name="CP_SQE_UCODE_DBG_ADDR"/>
+	<reg32 offset="0x0911" name="CP_SQE_UCODE_DBG_DATA"/>
+	<reg64 offset="0x0928" name="CP_IB1_BASE"/>
+	<reg32 offset="0x092A" name="CP_IB1_REM_SIZE"/>
+	<reg64 offset="0x092B" name="CP_IB2_BASE"/>
+	<reg32 offset="0x092D" name="CP_IB2_REM_SIZE"/>
+	<!-- SDS == CP_SET_DRAW_STATE: -->
+	<reg64 offset="0x092e" name="CP_SDS_BASE"/>
+	<reg32 offset="0x0930" name="CP_SDS_REM_SIZE"/>
+	<!-- MRB == MEM_READ_ADDR/$addr in SQE firmware -->
+	<reg64 offset="0x0931" name="CP_MRB_BASE"/>
+	<reg32 offset="0x0933" name="CP_MRB_REM_SIZE"/>
+	<!--
+	VSD == Visibility Stream Decode
+	This is used by CP to read the draw stream and skip empty draws
+	-->
+	<reg64 offset="0x0934" name="CP_VSD_BASE"/>
+
+	<bitset name="a6xx_roq_stat" inline="yes">
+		<bitfield name="RPTR" low="0" high="9"/>
+		<bitfield name="WPTR" low="16" high="25"/>
+	</bitset>
+	<reg32 offset="0x0939" name="CP_ROQ_RB_STAT" type="a6xx_roq_stat"/>
+	<reg32 offset="0x093a" name="CP_ROQ_IB1_STAT" type="a6xx_roq_stat"/>
+	<reg32 offset="0x093b" name="CP_ROQ_IB2_STAT" type="a6xx_roq_stat"/>
+	<reg32 offset="0x093c" name="CP_ROQ_SDS_STAT" type="a6xx_roq_stat"/>
+	<reg32 offset="0x093d" name="CP_ROQ_MRB_STAT" type="a6xx_roq_stat"/>
+	<reg32 offset="0x093e" name="CP_ROQ_VSD_STAT" type="a6xx_roq_stat"/>
+
+	<reg32 offset="0x0943" name="CP_IB1_DWORDS"/>
+	<reg32 offset="0x0944" name="CP_IB2_DWORDS"/>
+	<reg32 offset="0x0945" name="CP_SDS_DWORDS"/>
+	<reg32 offset="0x0946" name="CP_MRB_DWORDS"/>
+	<reg32 offset="0x0947" name="CP_VSD_DWORDS"/>
+
+	<reg32 offset="0x0948" name="CP_ROQ_AVAIL_RB">
+		<doc>number of remaining dwords incl current dword being consumed?</doc>
+		<bitfield name="REM" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="0x0949" name="CP_ROQ_AVAIL_IB1">
+		<doc>number of remaining dwords incl current dword being consumed?</doc>
+		<bitfield name="REM" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="0x094a" name="CP_ROQ_AVAIL_IB2">
+		<doc>number of remaining dwords incl current dword being consumed?</doc>
+		<bitfield name="REM" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="0x094b" name="CP_ROQ_AVAIL_SDS">
+		<doc>number of remaining dwords incl current dword being consumed?</doc>
+		<bitfield name="REM" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="0x094c" name="CP_ROQ_AVAIL_MRB">
+		<doc>number of dwords that have already been read but haven't been consumed by $addr</doc>
+		<bitfield name="REM" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="0x094d" name="CP_ROQ_AVAIL_VSD">
+		<doc>number of remaining dwords incl current dword being consumed?</doc>
+		<bitfield name="REM" low="16" high="31"/>
+	</reg32>
+
+	<bitset name="a7xx_aperture_cntl" inline="yes">
+		<bitfield name="PIPE" low="12" high="13" type="a7xx_pipe"/>
+		<bitfield name="CLUSTER" low="8" high="10" type="a7xx_cluster"/>
+		<bitfield name="CONTEXT" low="4" high="5"/>
+	</bitset>
+	<reg64 offset="0x0980" name="CP_ALWAYS_ON_COUNTER"/>
+	<reg32 offset="0x098D" name="CP_AHB_CNTL"/>
+	<reg32 offset="0x0A00" name="CP_APERTURE_CNTL_HOST" variants="A6XX"/>
+	<reg32 offset="0x0A00" name="CP_APERTURE_CNTL_HOST" type="a7xx_aperture_cntl" variants="A7XX-"/>
+	<reg32 offset="0x0A03" name="CP_APERTURE_CNTL_CD" variants="A6XX"/>
+	<reg32 offset="0x0A03" name="CP_APERTURE_CNTL_CD" type="a7xx_aperture_cntl" variants="A7XX-"/>
+
+	<reg32 offset="0x0a61" name="CP_BV_PROTECT_STATUS" variants="A7XX-"/>
+	<reg32 offset="0x0a64" name="CP_BV_HW_FAULT" variants="A7XX-"/>
+	<reg32 offset="0x0a81" name="CP_BV_DRAW_STATE_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0a82" name="CP_BV_DRAW_STATE_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0a83" name="CP_BV_ROQ_DBG_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0a84" name="CP_BV_ROQ_DBG_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0a85" name="CP_BV_SQE_UCODE_DBG_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0a86" name="CP_BV_SQE_UCODE_DBG_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0a87" name="CP_BV_SQE_STAT_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0a88" name="CP_BV_SQE_STAT_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0a96" name="CP_BV_MEM_POOL_DBG_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0a97" name="CP_BV_MEM_POOL_DBG_DATA" variants="A7XX-"/>
+	<reg64 offset="0x0a98" name="CP_BV_RB_RPTR_ADDR" variants="A7XX-"/>
+
+	<reg32 offset="0x0a9a" name="CP_RESOURCE_TBL_DBG_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0a9b" name="CP_RESOURCE_TBL_DBG_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0ad0" name="CP_BV_APRIV_CNTL" variants="A7XX-"/>
+	<reg32 offset="0x0ada" name="CP_BV_CHICKEN_DBG" variants="A7XX-"/>
+
+	<reg32 offset="0x0b0a" name="CP_LPAC_DRAW_STATE_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0b0b" name="CP_LPAC_DRAW_STATE_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0b0c" name="CP_LPAC_ROQ_DBG_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0b27" name="CP_SQE_AC_UCODE_DBG_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0b28" name="CP_SQE_AC_UCODE_DBG_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0b29" name="CP_SQE_AC_STAT_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0b2a" name="CP_SQE_AC_STAT_DATA" variants="A7XX-"/>
+
+	<reg32 offset="0x0b31" name="CP_LPAC_APRIV_CNTL" variants="A7XX-"/>
+	<reg32 offset="0x0B34" name="CP_LPAC_PROG_FIFO_SIZE"/>
+	<reg32 offset="0x0b35" name="CP_LPAC_ROQ_DBG_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0b36" name="CP_LPAC_FIFO_DBG_DATA" variants="A7XX-"/>
+	<reg32 offset="0x0b40" name="CP_LPAC_FIFO_DBG_ADDR" variants="A7XX-"/>
+	<reg32 offset="0x0b81" name="CP_LPAC_SQE_CNTL"/>
+	<reg64 offset="0x0b82" name="CP_LPAC_SQE_INSTR_BASE"/>
+
+	<reg64 offset="0x0b70" name="CP_AQE_INSTR_BASE_0" variants="A7XX-"/>
+	<reg64 offset="0x0b72" name="CP_AQE_INSTR_BASE_1" variants="A7XX-"/>
+	<reg32 offset="0x0b78" name="CP_AQE_APRIV_CNTL" variants="A7XX-"/>
+
+	<reg32 offset="0x0ba8" name="CP_AQE_ROQ_DBG_ADDR_0" variants="A7XX-"/>
+	<reg32 offset="0x0ba9" name="CP_AQE_ROQ_DBG_ADDR_1" variants="A7XX-"/>
+	<reg32 offset="0x0bac" name="CP_AQE_ROQ_DBG_DATA_0" variants="A7XX-"/>
+	<reg32 offset="0x0bad" name="CP_AQE_ROQ_DBG_DATA_1" variants="A7XX-"/>
+	<reg32 offset="0x0bb0" name="CP_AQE_UCODE_DBG_ADDR_0" variants="A7XX-"/>
+	<reg32 offset="0x0bb1" name="CP_AQE_UCODE_DBG_ADDR_1" variants="A7XX-"/>
+	<reg32 offset="0x0bb4" name="CP_AQE_UCODE_DBG_DATA_0" variants="A7XX-"/>
+	<reg32 offset="0x0bb5" name="CP_AQE_UCODE_DBG_DATA_1" variants="A7XX-"/>
+	<reg32 offset="0x0bb8" name="CP_AQE_STAT_ADDR_0" variants="A7XX-"/>
+	<reg32 offset="0x0bb9" name="CP_AQE_STAT_ADDR_1" variants="A7XX-"/>
+	<reg32 offset="0x0bbc" name="CP_AQE_STAT_DATA_0" variants="A7XX-"/>
+	<reg32 offset="0x0bbd" name="CP_AQE_STAT_DATA_1" variants="A7XX-"/>
+
+	<reg32 offset="0x0C01" name="VSC_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0018" name="RBBM_GPR0_CNTL"/>
+	<reg32 offset="0x0201" name="RBBM_INT_0_STATUS" type="A6XX_RBBM_INT_0_MASK"/>
+	<reg32 offset="0x0210" name="RBBM_STATUS">
+		<bitfield pos="23" name="GPU_BUSY_IGN_AHB" type="boolean"/>
+		<bitfield pos="22" name="GPU_BUSY_IGN_AHB_CP" type="boolean"/>
+		<bitfield pos="21" name="HLSQ_BUSY" type="boolean"/>
+		<bitfield pos="20" name="VSC_BUSY" type="boolean"/>
+		<bitfield pos="19" name="TPL1_BUSY" type="boolean"/>
+		<bitfield pos="18" name="SP_BUSY" type="boolean"/>
+		<bitfield pos="17" name="UCHE_BUSY" type="boolean"/>
+		<bitfield pos="16" name="VPC_BUSY" type="boolean"/>
+		<bitfield pos="15" name="VFD_BUSY" type="boolean"/>
+		<bitfield pos="14" name="TESS_BUSY" type="boolean"/>
+		<bitfield pos="13" name="PC_VSD_BUSY" type="boolean"/>
+		<bitfield pos="12" name="PC_DCALL_BUSY" type="boolean"/>
+		<bitfield pos="11" name="COM_DCOM_BUSY" type="boolean"/>
+		<bitfield pos="10" name="LRZ_BUSY" type="boolean"/>
+		<bitfield pos="9"  name="A2D_BUSY" type="boolean"/>
+		<bitfield pos="8"  name="CCU_BUSY" type="boolean"/>
+		<bitfield pos="7"  name="RB_BUSY" type="boolean"/>
+		<bitfield pos="6"  name="RAS_BUSY" type="boolean"/>
+		<bitfield pos="5"  name="TSE_BUSY" type="boolean"/>
+		<bitfield pos="4"  name="VBIF_BUSY" type="boolean"/>
+		<bitfield pos="3"  name="GFX_DBGC_BUSY" type="boolean"/>
+		<bitfield pos="2"  name="CP_BUSY" type="boolean"/>
+		<bitfield pos="1"  name="CP_AHB_BUSY_CP_MASTER" type="boolean"/>
+		<bitfield pos="0"  name="CP_AHB_BUSY_CX_MASTER" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0211" name="RBBM_STATUS1"/>
+	<reg32 offset="0x0212" name="RBBM_STATUS2"/>
+	<reg32 offset="0x0213" name="RBBM_STATUS3">
+		<bitfield pos="24" name="SMMU_STALLED_ON_FAULT" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0215" name="RBBM_VBIF_GX_RESET_STATUS"/>
+
+	<reg32 offset="0x0260" name="RBBM_CLOCK_MODE_CP" variants="A7XX-"/>
+	<reg32 offset="0x0284" name="RBBM_CLOCK_MODE_BV_LRZ" variants="A7XX-"/>
+	<reg32 offset="0x0285" name="RBBM_CLOCK_MODE_BV_GRAS" variants="A7XX-"/>
+	<reg32 offset="0x0286" name="RBBM_CLOCK_MODE2_GRAS" variants="A7XX-"/>
+	<reg32 offset="0x0287" name="RBBM_CLOCK_MODE_BV_VFD" variants="A7XX-"/>
+	<reg32 offset="0x0288" name="RBBM_CLOCK_MODE_BV_GPC" variants="A7XX-"/>
+
+	<reg32 offset="0x02c0" name="RBBM_SW_FUSE_INT_STATUS" variants="A7XX-"/>
+	<reg32 offset="0x02c1" name="RBBM_SW_FUSE_INT_MASK" variants="A7XX-"/>
+
+	<array offset="0x0400" name="RBBM_PERFCTR_CP" stride="2" length="14" variants="A6XX"/>
+	<array offset="0x041c" name="RBBM_PERFCTR_RBBM" stride="2" length="4" variants="A6XX"/>
+	<array offset="0x0424" name="RBBM_PERFCTR_PC" stride="2" length="8" variants="A6XX"/>
+	<array offset="0x0434" name="RBBM_PERFCTR_VFD" stride="2" length="8" variants="A6XX"/>
+	<array offset="0x0444" name="RBBM_PERFCTR_HLSQ" stride="2" length="6" variants="A6XX"/>
+	<array offset="0x0450" name="RBBM_PERFCTR_VPC" stride="2" length="6" variants="A6XX"/>
+	<array offset="0x045c" name="RBBM_PERFCTR_CCU" stride="2" length="5" variants="A6XX"/>
+	<array offset="0x0466" name="RBBM_PERFCTR_TSE" stride="2" length="4" variants="A6XX"/>
+	<array offset="0x046e" name="RBBM_PERFCTR_RAS" stride="2" length="4" variants="A6XX"/>
+	<array offset="0x0476" name="RBBM_PERFCTR_UCHE" stride="2" length="12" variants="A6XX"/>
+	<array offset="0x048e" name="RBBM_PERFCTR_TP" stride="2" length="12" variants="A6XX"/>
+	<array offset="0x04a6" name="RBBM_PERFCTR_SP" stride="2" length="24" variants="A6XX"/>
+	<array offset="0x04d6" name="RBBM_PERFCTR_RB" stride="2" length="8" variants="A6XX"/>
+	<array offset="0x04e6" name="RBBM_PERFCTR_VSC" stride="2" length="2" variants="A6XX"/>
+	<array offset="0x04ea" name="RBBM_PERFCTR_LRZ" stride="2" length="4" variants="A6XX"/>
+	<array offset="0x04f2" name="RBBM_PERFCTR_CMP" stride="2" length="4" variants="A6XX"/>
+
+	<array offset="0x0300" name="RBBM_PERFCTR_CP" stride="2" length="14" variants="A7XX-"/>
+	<array offset="0x031c" name="RBBM_PERFCTR_RBBM" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x0324" name="RBBM_PERFCTR_PC" stride="2" length="8" variants="A7XX-"/>
+	<array offset="0x0334" name="RBBM_PERFCTR_VFD" stride="2" length="8" variants="A7XX-"/>
+	<array offset="0x0344" name="RBBM_PERFCTR_HLSQ" stride="2" length="6" variants="A7XX-"/>
+	<array offset="0x0350" name="RBBM_PERFCTR_VPC" stride="2" length="6" variants="A7XX-"/>
+	<array offset="0x035c" name="RBBM_PERFCTR_CCU" stride="2" length="5" variants="A7XX-"/>
+	<array offset="0x0366" name="RBBM_PERFCTR_TSE" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x036e" name="RBBM_PERFCTR_RAS" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x0376" name="RBBM_PERFCTR_UCHE" stride="2" length="12" variants="A7XX-"/>
+	<array offset="0x038e" name="RBBM_PERFCTR_TP" stride="2" length="12" variants="A7XX-"/>
+	<array offset="0x03a6" name="RBBM_PERFCTR_SP" stride="2" length="24" variants="A7XX-"/>
+	<array offset="0x03d6" name="RBBM_PERFCTR_RB" stride="2" length="8" variants="A7XX-"/>
+	<array offset="0x03e6" name="RBBM_PERFCTR_VSC" stride="2" length="2" variants="A7XX-"/>
+	<array offset="0x03ea" name="RBBM_PERFCTR_LRZ" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x03f2" name="RBBM_PERFCTR_CMP" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x03fa" name="RBBM_PERFCTR_UFC" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x0410" name="RBBM_PERFCTR2_HLSQ" stride="2" length="6" variants="A7XX-"/>
+	<array offset="0x041c" name="RBBM_PERFCTR2_CP" stride="2" length="7" variants="A7XX-"/>
+	<array offset="0x042a" name="RBBM_PERFCTR2_SP" stride="2" length="12" variants="A7XX-"/>
+	<array offset="0x0442" name="RBBM_PERFCTR2_TP" stride="2" length="6" variants="A7XX-"/>
+	<array offset="0x044e" name="RBBM_PERFCTR2_UFC" stride="2" length="2" variants="A7XX-"/>
+	<array offset="0x0460" name="RBBM_PERFCTR_BV_PC" stride="2" length="8" variants="A7XX-"/>
+	<array offset="0x0470" name="RBBM_PERFCTR_BV_VFD" stride="2" length="8" variants="A7XX-"/>
+	<array offset="0x0480" name="RBBM_PERFCTR_BV_VPC" stride="2" length="6" variants="A7XX-"/>
+	<array offset="0x048c" name="RBBM_PERFCTR_BV_TSE" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x0494" name="RBBM_PERFCTR_BV_RAS" stride="2" length="4" variants="A7XX-"/>
+	<array offset="0x049c" name="RBBM_PERFCTR_BV_LRZ" stride="2" length="4" variants="A7XX-"/>
+
+	<reg32 offset="0x0500" name="RBBM_PERFCTR_CNTL"/>
+	<reg32 offset="0x0501" name="RBBM_PERFCTR_LOAD_CMD0"/>
+	<reg32 offset="0x0502" name="RBBM_PERFCTR_LOAD_CMD1"/>
+	<reg32 offset="0x0503" name="RBBM_PERFCTR_LOAD_CMD2"/>
+	<reg32 offset="0x0504" name="RBBM_PERFCTR_LOAD_CMD3"/>
+	<reg32 offset="0x0505" name="RBBM_PERFCTR_LOAD_VALUE_LO"/>
+	<reg32 offset="0x0506" name="RBBM_PERFCTR_LOAD_VALUE_HI"/>
+	<array offset="0x0507" name="RBBM_PERFCTR_RBBM_SEL" stride="1" length="4"/>
+	<reg32 offset="0x050B" name="RBBM_PERFCTR_GPU_BUSY_MASKED"/>
+	<reg32 offset="0x050e" name="RBBM_PERFCTR_SRAM_INIT_CMD"/>
+	<reg32 offset="0x050f" name="RBBM_PERFCTR_SRAM_INIT_STATUS"/>
+	<reg32 offset="0x0533" name="RBBM_ISDB_CNT"/>
+	<reg32 offset="0x0534" name="RBBM_NC_MODE_CNTL"/>
+	<reg32 offset="0x0535" name="RBBM_SNAPSHOT_STATUS" variants="A7XX-"/>
+
+	<!---
+	    This block of registers aren't tied to perf counters. They
+	    count various geometry stats, for example number of
+	    vertices in, number of primnitives assembled etc.
+	-->
+
+	<reg32 offset="0x0540" name="RBBM_PRIMCTR_0_LO"/>  <!-- vs vertices in -->
+	<reg32 offset="0x0541" name="RBBM_PRIMCTR_0_HI"/>
+	<reg32 offset="0x0542" name="RBBM_PRIMCTR_1_LO"/>  <!-- vs primitives out -->
+	<reg32 offset="0x0543" name="RBBM_PRIMCTR_1_HI"/>
+	<reg32 offset="0x0544" name="RBBM_PRIMCTR_2_LO"/>  <!-- hs vertices in -->
+	<reg32 offset="0x0545" name="RBBM_PRIMCTR_2_HI"/>
+	<reg32 offset="0x0546" name="RBBM_PRIMCTR_3_LO"/>  <!-- hs patches out -->
+	<reg32 offset="0x0547" name="RBBM_PRIMCTR_3_HI"/>
+	<reg32 offset="0x0548" name="RBBM_PRIMCTR_4_LO"/>  <!-- dss vertices in -->
+	<reg32 offset="0x0549" name="RBBM_PRIMCTR_4_HI"/>
+	<reg32 offset="0x054a" name="RBBM_PRIMCTR_5_LO"/>  <!-- ds primitives out -->
+	<reg32 offset="0x054b" name="RBBM_PRIMCTR_5_HI"/>
+	<reg32 offset="0x054c" name="RBBM_PRIMCTR_6_LO"/>  <!-- gs primitives in -->
+	<reg32 offset="0x054d" name="RBBM_PRIMCTR_6_HI"/>
+	<reg32 offset="0x054e" name="RBBM_PRIMCTR_7_LO"/>  <!-- gs primitives out -->
+	<reg32 offset="0x054f" name="RBBM_PRIMCTR_7_HI"/>
+	<reg32 offset="0x0550" name="RBBM_PRIMCTR_8_LO"/>  <!-- gs primitives out -->
+	<reg32 offset="0x0551" name="RBBM_PRIMCTR_8_HI"/>
+	<reg32 offset="0x0552" name="RBBM_PRIMCTR_9_LO"/>  <!-- raster primitives in -->
+	<reg32 offset="0x0553" name="RBBM_PRIMCTR_9_HI"/>
+	<reg32 offset="0x0554" name="RBBM_PRIMCTR_10_LO"/>
+	<reg32 offset="0x0555" name="RBBM_PRIMCTR_10_HI"/>
+
+	<reg32 offset="0xF400" name="RBBM_SECVID_TRUST_CNTL"/>
+	<reg64 offset="0xF800" name="RBBM_SECVID_TSB_TRUSTED_BASE"/>
+	<reg32 offset="0xF802" name="RBBM_SECVID_TSB_TRUSTED_SIZE"/>
+	<reg32 offset="0xF803" name="RBBM_SECVID_TSB_CNTL"/>
+	<reg32 offset="0xF810" name="RBBM_SECVID_TSB_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg64 offset="0xfc00" name="RBBM_SECVID_TSB_STATUS" variants="A7XX-"/>
+	<reg32 offset="0x00010" name="RBBM_VBIF_CLIENT_QOS_CNTL"/>
+	<reg32 offset="0x00011" name="RBBM_GBIF_CLIENT_QOS_CNTL"/>
+	<reg32 offset="0x00016" name="RBBM_GBIF_HALT"/>
+	<reg32 offset="0x00017" name="RBBM_GBIF_HALT_ACK"/>
+	<reg32 offset="0x0001c" name="RBBM_WAIT_FOR_GPU_IDLE_CMD">
+		<bitfield pos="0" name="WAIT_GPU_IDLE" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x00016" name="RBBM_GBIF_HALT" variants="A7XX-"/>
+	<reg32 offset="0x00017" name="RBBM_GBIF_HALT_ACK" variants="A7XX-"/>
+	<reg32 offset="0x0001f" name="RBBM_INTERFACE_HANG_INT_CNTL"/>
+	<reg32 offset="0x00037" name="RBBM_INT_CLEAR_CMD" type="A6XX_RBBM_INT_0_MASK"/>
+	<reg32 offset="0x00038" name="RBBM_INT_0_MASK" type="A6XX_RBBM_INT_0_MASK"/>
+	<reg32 offset="0x0003a" name="RBBM_INT_2_MASK" variants="A7XX-"/>
+	<reg32 offset="0x00042" name="RBBM_SP_HYST_CNT"/>
+	<reg32 offset="0x00043" name="RBBM_SW_RESET_CMD"/>
+	<reg32 offset="0x00044" name="RBBM_RAC_THRESHOLD_CNT"/>
+	<reg32 offset="0x00045" name="RBBM_BLOCK_SW_RESET_CMD"/>
+	<reg32 offset="0x00046" name="RBBM_BLOCK_SW_RESET_CMD2"/>
+	<reg32 offset="0x000ad" name="RBBM_CLOCK_CNTL_GLOBAL" variants="A7XX-"/>
+	<reg32 offset="0x000ae" name="RBBM_CLOCK_CNTL"/>
+	<reg32 offset="0x000b0" name="RBBM_CLOCK_CNTL_SP0"/>
+	<reg32 offset="0x000b1" name="RBBM_CLOCK_CNTL_SP1"/>
+	<reg32 offset="0x000b2" name="RBBM_CLOCK_CNTL_SP2"/>
+	<reg32 offset="0x000b3" name="RBBM_CLOCK_CNTL_SP3"/>
+	<reg32 offset="0x000b4" name="RBBM_CLOCK_CNTL2_SP0"/>
+	<reg32 offset="0x000b5" name="RBBM_CLOCK_CNTL2_SP1"/>
+	<reg32 offset="0x000b6" name="RBBM_CLOCK_CNTL2_SP2"/>
+	<reg32 offset="0x000b7" name="RBBM_CLOCK_CNTL2_SP3"/>
+	<reg32 offset="0x000b8" name="RBBM_CLOCK_DELAY_SP0"/>
+	<reg32 offset="0x000b9" name="RBBM_CLOCK_DELAY_SP1"/>
+	<reg32 offset="0x000ba" name="RBBM_CLOCK_DELAY_SP2"/>
+	<reg32 offset="0x000bb" name="RBBM_CLOCK_DELAY_SP3"/>
+	<reg32 offset="0x000bc" name="RBBM_CLOCK_HYST_SP0"/>
+	<reg32 offset="0x000bd" name="RBBM_CLOCK_HYST_SP1"/>
+	<reg32 offset="0x000be" name="RBBM_CLOCK_HYST_SP2"/>
+	<reg32 offset="0x000bf" name="RBBM_CLOCK_HYST_SP3"/>
+	<reg32 offset="0x000c0" name="RBBM_CLOCK_CNTL_TP0"/>
+	<reg32 offset="0x000c1" name="RBBM_CLOCK_CNTL_TP1"/>
+	<reg32 offset="0x000c2" name="RBBM_CLOCK_CNTL_TP2"/>
+	<reg32 offset="0x000c3" name="RBBM_CLOCK_CNTL_TP3"/>
+	<reg32 offset="0x000c4" name="RBBM_CLOCK_CNTL2_TP0"/>
+	<reg32 offset="0x000c5" name="RBBM_CLOCK_CNTL2_TP1"/>
+	<reg32 offset="0x000c6" name="RBBM_CLOCK_CNTL2_TP2"/>
+	<reg32 offset="0x000c7" name="RBBM_CLOCK_CNTL2_TP3"/>
+	<reg32 offset="0x000c8" name="RBBM_CLOCK_CNTL3_TP0"/>
+	<reg32 offset="0x000c9" name="RBBM_CLOCK_CNTL3_TP1"/>
+	<reg32 offset="0x000ca" name="RBBM_CLOCK_CNTL3_TP2"/>
+	<reg32 offset="0x000cb" name="RBBM_CLOCK_CNTL3_TP3"/>
+	<reg32 offset="0x000cc" name="RBBM_CLOCK_CNTL4_TP0"/>
+	<reg32 offset="0x000cd" name="RBBM_CLOCK_CNTL4_TP1"/>
+	<reg32 offset="0x000ce" name="RBBM_CLOCK_CNTL4_TP2"/>
+	<reg32 offset="0x000cf" name="RBBM_CLOCK_CNTL4_TP3"/>
+	<reg32 offset="0x000d0" name="RBBM_CLOCK_DELAY_TP0"/>
+	<reg32 offset="0x000d1" name="RBBM_CLOCK_DELAY_TP1"/>
+	<reg32 offset="0x000d2" name="RBBM_CLOCK_DELAY_TP2"/>
+	<reg32 offset="0x000d3" name="RBBM_CLOCK_DELAY_TP3"/>
+	<reg32 offset="0x000d4" name="RBBM_CLOCK_DELAY2_TP0"/>
+	<reg32 offset="0x000d5" name="RBBM_CLOCK_DELAY2_TP1"/>
+	<reg32 offset="0x000d6" name="RBBM_CLOCK_DELAY2_TP2"/>
+	<reg32 offset="0x000d7" name="RBBM_CLOCK_DELAY2_TP3"/>
+	<reg32 offset="0x000d8" name="RBBM_CLOCK_DELAY3_TP0"/>
+	<reg32 offset="0x000d9" name="RBBM_CLOCK_DELAY3_TP1"/>
+	<reg32 offset="0x000da" name="RBBM_CLOCK_DELAY3_TP2"/>
+	<reg32 offset="0x000db" name="RBBM_CLOCK_DELAY3_TP3"/>
+	<reg32 offset="0x000dc" name="RBBM_CLOCK_DELAY4_TP0"/>
+	<reg32 offset="0x000dd" name="RBBM_CLOCK_DELAY4_TP1"/>
+	<reg32 offset="0x000de" name="RBBM_CLOCK_DELAY4_TP2"/>
+	<reg32 offset="0x000df" name="RBBM_CLOCK_DELAY4_TP3"/>
+	<reg32 offset="0x000e0" name="RBBM_CLOCK_HYST_TP0"/>
+	<reg32 offset="0x000e1" name="RBBM_CLOCK_HYST_TP1"/>
+	<reg32 offset="0x000e2" name="RBBM_CLOCK_HYST_TP2"/>
+	<reg32 offset="0x000e3" name="RBBM_CLOCK_HYST_TP3"/>
+	<reg32 offset="0x000e4" name="RBBM_CLOCK_HYST2_TP0"/>
+	<reg32 offset="0x000e5" name="RBBM_CLOCK_HYST2_TP1"/>
+	<reg32 offset="0x000e6" name="RBBM_CLOCK_HYST2_TP2"/>
+	<reg32 offset="0x000e7" name="RBBM_CLOCK_HYST2_TP3"/>
+	<reg32 offset="0x000e8" name="RBBM_CLOCK_HYST3_TP0"/>
+	<reg32 offset="0x000e9" name="RBBM_CLOCK_HYST3_TP1"/>
+	<reg32 offset="0x000ea" name="RBBM_CLOCK_HYST3_TP2"/>
+	<reg32 offset="0x000eb" name="RBBM_CLOCK_HYST3_TP3"/>
+	<reg32 offset="0x000ec" name="RBBM_CLOCK_HYST4_TP0"/>
+	<reg32 offset="0x000ed" name="RBBM_CLOCK_HYST4_TP1"/>
+	<reg32 offset="0x000ee" name="RBBM_CLOCK_HYST4_TP2"/>
+	<reg32 offset="0x000ef" name="RBBM_CLOCK_HYST4_TP3"/>
+	<reg32 offset="0x000f0" name="RBBM_CLOCK_CNTL_RB0"/>
+	<reg32 offset="0x000f1" name="RBBM_CLOCK_CNTL_RB1"/>
+	<reg32 offset="0x000f2" name="RBBM_CLOCK_CNTL_RB2"/>
+	<reg32 offset="0x000f3" name="RBBM_CLOCK_CNTL_RB3"/>
+	<reg32 offset="0x000f4" name="RBBM_CLOCK_CNTL2_RB0"/>
+	<reg32 offset="0x000f5" name="RBBM_CLOCK_CNTL2_RB1"/>
+	<reg32 offset="0x000f6" name="RBBM_CLOCK_CNTL2_RB2"/>
+	<reg32 offset="0x000f7" name="RBBM_CLOCK_CNTL2_RB3"/>
+	<reg32 offset="0x000f8" name="RBBM_CLOCK_CNTL_CCU0"/>
+	<reg32 offset="0x000f9" name="RBBM_CLOCK_CNTL_CCU1"/>
+	<reg32 offset="0x000fa" name="RBBM_CLOCK_CNTL_CCU2"/>
+	<reg32 offset="0x000fb" name="RBBM_CLOCK_CNTL_CCU3"/>
+	<reg32 offset="0x00100" name="RBBM_CLOCK_HYST_RB_CCU0"/>
+	<reg32 offset="0x00101" name="RBBM_CLOCK_HYST_RB_CCU1"/>
+	<reg32 offset="0x00102" name="RBBM_CLOCK_HYST_RB_CCU2"/>
+	<reg32 offset="0x00103" name="RBBM_CLOCK_HYST_RB_CCU3"/>
+	<reg32 offset="0x00104" name="RBBM_CLOCK_CNTL_RAC"/>
+	<reg32 offset="0x00105" name="RBBM_CLOCK_CNTL2_RAC"/>
+	<reg32 offset="0x00106" name="RBBM_CLOCK_DELAY_RAC"/>
+	<reg32 offset="0x00107" name="RBBM_CLOCK_HYST_RAC"/>
+	<reg32 offset="0x00108" name="RBBM_CLOCK_CNTL_TSE_RAS_RBBM"/>
+	<reg32 offset="0x00109" name="RBBM_CLOCK_DELAY_TSE_RAS_RBBM"/>
+	<reg32 offset="0x0010a" name="RBBM_CLOCK_HYST_TSE_RAS_RBBM"/>
+	<reg32 offset="0x0010b" name="RBBM_CLOCK_CNTL_UCHE"/>
+	<reg32 offset="0x0010c" name="RBBM_CLOCK_CNTL2_UCHE"/>
+	<reg32 offset="0x0010d" name="RBBM_CLOCK_CNTL3_UCHE"/>
+	<reg32 offset="0x0010e" name="RBBM_CLOCK_CNTL4_UCHE"/>
+	<reg32 offset="0x0010f" name="RBBM_CLOCK_DELAY_UCHE"/>
+	<reg32 offset="0x00110" name="RBBM_CLOCK_HYST_UCHE"/>
+	<reg32 offset="0x00111" name="RBBM_CLOCK_MODE_VFD"/>
+	<reg32 offset="0x00112" name="RBBM_CLOCK_DELAY_VFD"/>
+	<reg32 offset="0x00113" name="RBBM_CLOCK_HYST_VFD"/>
+	<reg32 offset="0x00114" name="RBBM_CLOCK_MODE_GPC"/>
+	<reg32 offset="0x00115" name="RBBM_CLOCK_DELAY_GPC"/>
+	<reg32 offset="0x00116" name="RBBM_CLOCK_HYST_GPC"/>
+	<reg32 offset="0x00117" name="RBBM_CLOCK_DELAY_HLSQ_2"/>
+	<reg32 offset="0x00118" name="RBBM_CLOCK_CNTL_GMU_GX"/>
+	<reg32 offset="0x00119" name="RBBM_CLOCK_DELAY_GMU_GX"/>
+	<reg32 offset="0x0011a" name="RBBM_CLOCK_HYST_GMU_GX"/>
+	<reg32 offset="0x0011b" name="RBBM_CLOCK_MODE_HLSQ"/>
+	<reg32 offset="0x0011c" name="RBBM_CLOCK_DELAY_HLSQ"/>
+	<reg32 offset="0x0011d" name="RBBM_CLOCK_HYST_HLSQ"/>
+	<reg32 offset="0x0011e" name="RBBM_CGC_GLOBAL_LOAD_CMD" variants="A7XX-"/>
+	<reg32 offset="0x0011f" name="RBBM_CGC_P2S_TRIG_CMD" variants="A7XX-"/>
+	<reg32 offset="0x00120" name="RBBM_CLOCK_CNTL_TEX_FCHE"/>
+	<reg32 offset="0x00121" name="RBBM_CLOCK_DELAY_TEX_FCHE"/>
+	<reg32 offset="0x00122" name="RBBM_CLOCK_HYST_TEX_FCHE"/>
+	<reg32 offset="0x00122" name="RBBM_CGC_P2S_STATUS" variants="A7XX-">
+		<bitfield name="TXDONE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00123" name="RBBM_CLOCK_CNTL_FCHE"/>
+	<reg32 offset="0x00124" name="RBBM_CLOCK_DELAY_FCHE"/>
+	<reg32 offset="0x00125" name="RBBM_CLOCK_HYST_FCHE"/>
+	<reg32 offset="0x00126" name="RBBM_CLOCK_CNTL_MHUB"/>
+	<reg32 offset="0x00127" name="RBBM_CLOCK_DELAY_MHUB"/>
+	<reg32 offset="0x00128" name="RBBM_CLOCK_HYST_MHUB"/>
+	<reg32 offset="0x00129" name="RBBM_CLOCK_DELAY_GLC"/>
+	<reg32 offset="0x0012a" name="RBBM_CLOCK_HYST_GLC"/>
+	<reg32 offset="0x0012b" name="RBBM_CLOCK_CNTL_GLC"/>
+	<reg32 offset="0x0012f" name="RBBM_CLOCK_HYST2_VFD" variants="A7XX-"/>
+	<reg32 offset="0x005ff" name="RBBM_LPAC_GBIF_CLIENT_QOS_CNTL"/>
+
+	<reg32 offset="0x0600" name="DBGC_CFG_DBGBUS_SEL_A"/>
+	<reg32 offset="0x0601" name="DBGC_CFG_DBGBUS_SEL_B"/>
+	<reg32 offset="0x0602" name="DBGC_CFG_DBGBUS_SEL_C"/>
+	<reg32 offset="0x0603" name="DBGC_CFG_DBGBUS_SEL_D">
+		<bitfield high="7" low="0" name="PING_INDEX"/>
+		<bitfield high="15" low="8" name="PING_BLK_SEL"/>
+	</reg32>
+	<reg32 offset="0x0604" name="DBGC_CFG_DBGBUS_CNTLT">
+		<bitfield high="5" low="0" name="TRACEEN"/>
+		<bitfield high="14" low="12" name="GRANU"/>
+		<bitfield high="31" low="28" name="SEGT"/>
+	</reg32>
+	<reg32 offset="0x0605" name="DBGC_CFG_DBGBUS_CNTLM">
+		<bitfield high="27" low="24" name="ENABLE"/>
+	</reg32>
+	<reg32 offset="0x0608" name="DBGC_CFG_DBGBUS_IVTL_0"/>
+	<reg32 offset="0x0609" name="DBGC_CFG_DBGBUS_IVTL_1"/>
+	<reg32 offset="0x060a" name="DBGC_CFG_DBGBUS_IVTL_2"/>
+	<reg32 offset="0x060b" name="DBGC_CFG_DBGBUS_IVTL_3"/>
+	<reg32 offset="0x060c" name="DBGC_CFG_DBGBUS_MASKL_0"/>
+	<reg32 offset="0x060d" name="DBGC_CFG_DBGBUS_MASKL_1"/>
+	<reg32 offset="0x060e" name="DBGC_CFG_DBGBUS_MASKL_2"/>
+	<reg32 offset="0x060f" name="DBGC_CFG_DBGBUS_MASKL_3"/>
+	<reg32 offset="0x0610" name="DBGC_CFG_DBGBUS_BYTEL_0">
+		<bitfield high="3" low="0" name="BYTEL0"/>
+		<bitfield high="7" low="4" name="BYTEL1"/>
+		<bitfield high="11" low="8" name="BYTEL2"/>
+		<bitfield high="15" low="12" name="BYTEL3"/>
+		<bitfield high="19" low="16" name="BYTEL4"/>
+		<bitfield high="23" low="20" name="BYTEL5"/>
+		<bitfield high="27" low="24" name="BYTEL6"/>
+		<bitfield high="31" low="28" name="BYTEL7"/>
+	</reg32>
+	<reg32 offset="0x0611" name="DBGC_CFG_DBGBUS_BYTEL_1">
+		<bitfield high="3" low="0" name="BYTEL8"/>
+		<bitfield high="7" low="4" name="BYTEL9"/>
+		<bitfield high="11" low="8" name="BYTEL10"/>
+		<bitfield high="15" low="12" name="BYTEL11"/>
+		<bitfield high="19" low="16" name="BYTEL12"/>
+		<bitfield high="23" low="20" name="BYTEL13"/>
+		<bitfield high="27" low="24" name="BYTEL14"/>
+		<bitfield high="31" low="28" name="BYTEL15"/>
+	</reg32>
+	<reg32 offset="0x062f" name="DBGC_CFG_DBGBUS_TRACE_BUF1"/>
+	<reg32 offset="0x0630" name="DBGC_CFG_DBGBUS_TRACE_BUF2"/>
+	<array offset="0x0CD8" name="VSC_PERFCTR_VSC_SEL" stride="1" length="2"/>
+	<reg32 offset="0x0CD8" name="VSC_UNKNOWN_0CD8" variants="A7XX">
+		<doc>
+			Set to true when binning, isn't changed afterwards
+		</doc>
+		<bitfield name="BINNING" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xC800" name="HLSQ_DBG_AHB_READ_APERTURE"/>
+	<reg32 offset="0xD000" name="HLSQ_DBG_READ_SEL"/>
+	<reg32 offset="0x0E00" name="UCHE_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0x0E01" name="UCHE_MODE_CNTL"/>
+	<reg64 offset="0x0E05" name="UCHE_WRITE_RANGE_MAX"/>
+	<reg64 offset="0x0E07" name="UCHE_WRITE_THRU_BASE"/>
+	<reg64 offset="0x0E09" name="UCHE_TRAP_BASE"/>
+	<reg64 offset="0x0E0B" name="UCHE_GMEM_RANGE_MIN"/>
+	<reg64 offset="0x0E0D" name="UCHE_GMEM_RANGE_MAX"/>
+	<reg32 offset="0x0E17" name="UCHE_CACHE_WAYS" usage="cmd"/>
+	<reg32 offset="0x0E18" name="UCHE_FILTER_CNTL"/>
+	<reg32 offset="0x0E19" name="UCHE_CLIENT_PF" usage="cmd">
+		<bitfield high="7" low="0" name="PERFSEL"/>
+	</reg32>
+	<array offset="0x0E1C" name="UCHE_PERFCTR_UCHE_SEL" stride="1" length="12"/>
+	<reg32 offset="0x0e3a" name="UCHE_GBIF_GX_CONFIG"/>
+	<reg32 offset="0x0e3c" name="UCHE_CMDQ_CONFIG"/>
+
+	<reg32 offset="0x3000" name="VBIF_VERSION"/>
+	<reg32 offset="0x3001" name="VBIF_CLKON">
+		<bitfield pos="1" name="FORCE_ON_TESTBUS" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x302A" name="VBIF_GATE_OFF_WRREQ_EN"/>
+	<reg32 offset="0x3080" name="VBIF_XIN_HALT_CTRL0"/>
+	<reg32 offset="0x3081" name="VBIF_XIN_HALT_CTRL1"/>
+	<reg32 offset="0x3084" name="VBIF_TEST_BUS_OUT_CTRL"/>
+	<reg32 offset="0x3085" name="VBIF_TEST_BUS1_CTRL0"/>
+	<reg32 offset="0x3086" name="VBIF_TEST_BUS1_CTRL1">
+		<bitfield low="0" high="3" name="DATA_SEL"/>
+	</reg32>
+	<reg32 offset="0x3087" name="VBIF_TEST_BUS2_CTRL0"/>
+	<reg32 offset="0x3088" name="VBIF_TEST_BUS2_CTRL1">
+		<bitfield low="0" high="8" name="DATA_SEL"/>
+	</reg32>
+	<reg32 offset="0x308c" name="VBIF_TEST_BUS_OUT"/>
+	<reg32 offset="0x30d0" name="VBIF_PERF_CNT_SEL0"/>
+	<reg32 offset="0x30d1" name="VBIF_PERF_CNT_SEL1"/>
+	<reg32 offset="0x30d2" name="VBIF_PERF_CNT_SEL2"/>
+	<reg32 offset="0x30d3" name="VBIF_PERF_CNT_SEL3"/>
+	<reg32 offset="0x30d8" name="VBIF_PERF_CNT_LOW0"/>
+	<reg32 offset="0x30d9" name="VBIF_PERF_CNT_LOW1"/>
+	<reg32 offset="0x30da" name="VBIF_PERF_CNT_LOW2"/>
+	<reg32 offset="0x30db" name="VBIF_PERF_CNT_LOW3"/>
+	<reg32 offset="0x30e0" name="VBIF_PERF_CNT_HIGH0"/>
+	<reg32 offset="0x30e1" name="VBIF_PERF_CNT_HIGH1"/>
+	<reg32 offset="0x30e2" name="VBIF_PERF_CNT_HIGH2"/>
+	<reg32 offset="0x30e3" name="VBIF_PERF_CNT_HIGH3"/>
+	<reg32 offset="0x3100" name="VBIF_PERF_PWR_CNT_EN0"/>
+	<reg32 offset="0x3101" name="VBIF_PERF_PWR_CNT_EN1"/>
+	<reg32 offset="0x3102" name="VBIF_PERF_PWR_CNT_EN2"/>
+	<reg32 offset="0x3110" name="VBIF_PERF_PWR_CNT_LOW0"/>
+	<reg32 offset="0x3111" name="VBIF_PERF_PWR_CNT_LOW1"/>
+	<reg32 offset="0x3112" name="VBIF_PERF_PWR_CNT_LOW2"/>
+	<reg32 offset="0x3118" name="VBIF_PERF_PWR_CNT_HIGH0"/>
+	<reg32 offset="0x3119" name="VBIF_PERF_PWR_CNT_HIGH1"/>
+	<reg32 offset="0x311a" name="VBIF_PERF_PWR_CNT_HIGH2"/>
+
+	<reg32 offset="0x3c01" name="GBIF_SCACHE_CNTL0"/>
+	<reg32 offset="0x3c02" name="GBIF_SCACHE_CNTL1"/>
+	<reg32 offset="0x3c03" name="GBIF_QSB_SIDE0"/>
+	<reg32 offset="0x3c04" name="GBIF_QSB_SIDE1"/>
+	<reg32 offset="0x3c05" name="GBIF_QSB_SIDE2"/>
+	<reg32 offset="0x3c06" name="GBIF_QSB_SIDE3"/>
+	<reg32 offset="0x3c45" name="GBIF_HALT"/>
+	<reg32 offset="0x3c46" name="GBIF_HALT_ACK"/>
+	<reg32 offset="0x3cc0" name="GBIF_PERF_PWR_CNT_EN"/>
+	<reg32 offset="0x3cc1" name="GBIF_PERF_PWR_CNT_CLR"/>
+	<reg32 offset="0x3cc2" name="GBIF_PERF_CNT_SEL"/>
+	<reg32 offset="0x3cc3" name="GBIF_PERF_PWR_CNT_SEL"/>
+	<reg32 offset="0x3cc4" name="GBIF_PERF_CNT_LOW0"/>
+	<reg32 offset="0x3cc5" name="GBIF_PERF_CNT_LOW1"/>
+	<reg32 offset="0x3cc6" name="GBIF_PERF_CNT_LOW2"/>
+	<reg32 offset="0x3cc7" name="GBIF_PERF_CNT_LOW3"/>
+	<reg32 offset="0x3cc8" name="GBIF_PERF_CNT_HIGH0"/>
+	<reg32 offset="0x3cc9" name="GBIF_PERF_CNT_HIGH1"/>
+	<reg32 offset="0x3cca" name="GBIF_PERF_CNT_HIGH2"/>
+	<reg32 offset="0x3ccb" name="GBIF_PERF_CNT_HIGH3"/>
+	<reg32 offset="0x3ccc" name="GBIF_PWR_CNT_LOW0"/>
+	<reg32 offset="0x3ccd" name="GBIF_PWR_CNT_LOW1"/>
+	<reg32 offset="0x3cce" name="GBIF_PWR_CNT_LOW2"/>
+	<reg32 offset="0x3ccf" name="GBIF_PWR_CNT_HIGH0"/>
+	<reg32 offset="0x3cd0" name="GBIF_PWR_CNT_HIGH1"/>
+	<reg32 offset="0x3cd1" name="GBIF_PWR_CNT_HIGH2"/>
+
+	<reg32 offset="0x0c00" name="VSC_DBG_ECO_CNTL"/>
+	<reg32 offset="0x0c02" name="VSC_BIN_SIZE" usage="rp_blit">
+		<bitfield name="WIDTH" low="0" high="7" shr="5" type="uint"/>
+		<bitfield name="HEIGHT" low="8" high="16" shr="4" type="uint"/>
+	</reg32>
+	<reg64 offset="0x0c03" name="VSC_DRAW_STRM_SIZE_ADDRESS" type="waddress" usage="cmd"/>
+	<reg32 offset="0x0c06" name="VSC_BIN_COUNT" usage="rp_blit">
+		<bitfield name="NX" low="1" high="10" type="uint"/>
+		<bitfield name="NY" low="11" high="20" type="uint"/>
+	</reg32>
+	<array offset="0x0c10" name="VSC_PIPE_CONFIG" stride="1" length="32" usage="rp_blit">
+		<reg32 offset="0x0" name="REG">
+			<doc>
+				Configures the mapping between VSC_PIPE buffer and
+				bin, X/Y specify the bin index in the horiz/vert
+				direction (0,0 is upper left, 0,1 is leftmost bin
+				on second row, and so on).  W/H specify the number
+				of bins assigned to this VSC_PIPE in the horiz/vert
+				dimension.
+			</doc>
+			<bitfield name="X" low="0" high="9" type="uint"/>
+			<bitfield name="Y" low="10" high="19" type="uint"/>
+			<bitfield name="W" low="20" high="25" type="uint"/>
+			<bitfield name="H" low="26" high="31" type="uint"/>
+		</reg32>
+	</array>
+	<!--
+	HW binning primitive & draw streams, which enable draws and primitives
+	within a draw to be skipped in the main tile pass.  See:
+	https://github.com/freedreno/freedreno/wiki/Visibility-Stream-Format
+
+	Compared to a5xx and earlier, we just program the address of the first
+	stream and hw adds (pipe_num * VSC_*_STRM_PITCH)
+
+	LIMIT is set to PITCH - 64, to make room for a bit of overflow
+	 -->
+	<reg64 offset="0x0c30" name="VSC_PRIM_STRM_ADDRESS" type="waddress" usage="cmd"/>
+	<reg32 offset="0x0c32" name="VSC_PRIM_STRM_PITCH" usage="cmd"/>
+	<reg32 offset="0x0c33" name="VSC_PRIM_STRM_LIMIT" usage="cmd"/>
+	<reg64 offset="0x0c34" name="VSC_DRAW_STRM_ADDRESS" type="waddress" usage="cmd"/>
+	<reg32 offset="0x0c36" name="VSC_DRAW_STRM_PITCH" usage="cmd"/>
+	<reg32 offset="0x0c37" name="VSC_DRAW_STRM_LIMIT" usage="cmd"/>
+
+	<array offset="0x0c38" name="VSC_STATE" stride="1" length="32" usage="rp_blit">
+		<doc>
+			Seems to be a bitmap of which tiles mapped to the VSC
+			pipe contain geometry.
+
+			I suppose we can connect a maximum of 32 tiles to a
+			single VSC pipe.
+		</doc>
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+
+	<array offset="0x0c58" name="VSC_PRIM_STRM_SIZE" stride="1" length="32" variants="A6XX" usage="rp_blit">
+		<doc>
+			Has the size of data written to corresponding VSC_PRIM_STRM
+			buffer.
+		</doc>
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+
+	<array offset="0x0c78" name="VSC_DRAW_STRM_SIZE" stride="1" length="32" variants="A6XX" usage="rp_blit">
+		<doc>
+			Has the size of data written to corresponding VSC pipe, ie.
+			same thing that is written out to VSC_DRAW_STRM_SIZE_ADDRESS_LO/HI
+		</doc>
+		<reg32 offset="0x0" name="REG"/>
+	</array>
+
+	<reg32 offset="0x0d08" name="VSC_UNKNOWN_0D08" variants="A7XX-" usage="rp_blit"/>
+
+	<reg32 offset="0x0E10" name="UCHE_UNKNOWN_0E10" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0x0E11" name="UCHE_UNKNOWN_0E11" variants="A7XX-" usage="cmd"/>
+	<!-- always 0x03200000 ? -->
+	<reg32 offset="0x0e12" name="UCHE_UNKNOWN_0E12"  usage="cmd"/>
+
+	<!-- adreno_reg_xy has 15 bits per coordinate, but a6xx registers only have 14 -->
+	<bitset name="a6xx_reg_xy" inline="yes">
+		<bitfield name="X" low="0" high="13" type="uint"/>
+		<bitfield name="Y" low="16" high="29" type="uint"/>
+	</bitset>
+
+	<reg32 offset="0x8000" name="GRAS_CL_CNTL" usage="rp_blit">
+		<bitfield name="CLIP_DISABLE" pos="0" type="boolean"/>
+		<bitfield name="ZNEAR_CLIP_DISABLE" pos="1" type="boolean"/>
+		<bitfield name="ZFAR_CLIP_DISABLE" pos="2" type="boolean"/>
+		<bitfield name="Z_CLAMP_ENABLE" pos="5" type="boolean"/>
+		<!-- controls near z clip behavior (set for vulkan) -->
+		<bitfield name="ZERO_GB_SCALE_Z" pos="6" type="boolean"/>
+		<!-- guess based on a3xx and meaning of bits 8 and 9
+		     if the guess is right then this is related to point sprite clipping -->
+		<bitfield name="VP_CLIP_CODE_IGNORE" pos="7" type="boolean"/>
+		<bitfield name="VP_XFORM_DISABLE" pos="8" type="boolean"/>
+		<bitfield name="PERSP_DIVISION_DISABLE" pos="9" type="boolean"/>
+	</reg32>
+
+	<bitset name="a6xx_gras_xs_cl_cntl" inline="yes">
+		<bitfield name="CLIP_MASK" low="0" high="7"/>
+		<bitfield name="CULL_MASK" low="8" high="15"/>
+	</bitset>
+	<reg32 offset="0x8001" name="GRAS_VS_CL_CNTL" type="a6xx_gras_xs_cl_cntl" usage="rp_blit"/>
+	<reg32 offset="0x8002" name="GRAS_DS_CL_CNTL" type="a6xx_gras_xs_cl_cntl" usage="rp_blit"/>
+	<reg32 offset="0x8003" name="GRAS_GS_CL_CNTL" type="a6xx_gras_xs_cl_cntl" usage="rp_blit"/>
+	<reg32 offset="0x8004" name="GRAS_MAX_LAYER_INDEX" low="0" high="10" type="uint" usage="rp_blit"/>
+
+	<reg32 offset="0x8005" name="GRAS_CNTL" usage="rp_blit">
+		<!-- see also RB_RENDER_CONTROL0 -->
+		<bitfield name="IJ_PERSP_PIXEL" pos="0" type="boolean"/>
+		<bitfield name="IJ_PERSP_CENTROID" pos="1" type="boolean"/>
+		<bitfield name="IJ_PERSP_SAMPLE" pos="2" type="boolean"/>
+		<bitfield name="IJ_LINEAR_PIXEL" pos="3" type="boolean"/>
+		<bitfield name="IJ_LINEAR_CENTROID" pos="4" type="boolean"/>
+		<bitfield name="IJ_LINEAR_SAMPLE" pos="5" type="boolean"/>
+		<bitfield name="COORD_MASK" low="6" high="9" type="hex"/>
+		<bitfield name="UNK10" pos="10" type="boolean" variants="A7XX-"/>
+		<bitfield name="UNK11" pos="11" type="boolean" variants="A7XX-"/>
+	</reg32>
+	<reg32 offset="0x8006" name="GRAS_CL_GUARDBAND_CLIP_ADJ" usage="rp_blit">
+		<bitfield name="HORZ" low="0" high="8" type="uint"/>
+		<bitfield name="VERT" low="10" high="18" type="uint"/>
+	</reg32>
+
+	<!-- Something connected to depth-stencil attachment size -->
+	<reg32 offset="0x8007" name="GRAS_UNKNOWN_8007" variants="A7XX-" usage="rp_blit"/>
+
+	<reg32 offset="0x8008" name="GRAS_UNKNOWN_8008" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0x8009" name="GRAS_UNKNOWN_8009" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0x800a" name="GRAS_UNKNOWN_800A" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0x800b" name="GRAS_UNKNOWN_800B" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0x800c" name="GRAS_UNKNOWN_800C" variants="A7XX-" usage="cmd"/>
+
+	<!-- <reg32 offset="0x80f0" name="GRAS_UNKNOWN_80F0" type="a6xx_reg_xy"/> -->
+
+	<!-- 0x8006-0x800f invalid -->
+	<array offset="0x8010" name="GRAS_CL_VPORT" stride="6" length="16" usage="rp_blit">
+		<reg32 offset="0" name="XOFFSET" type="float"/>
+		<reg32 offset="1" name="XSCALE" type="float"/>
+		<reg32 offset="2" name="YOFFSET" type="float"/>
+		<reg32 offset="3" name="YSCALE" type="float"/>
+		<reg32 offset="4" name="ZOFFSET" type="float"/>
+		<reg32 offset="5" name="ZSCALE" type="float"/>
+	</array>
+	<array offset="0x8070" name="GRAS_CL_Z_CLAMP" stride="2" length="16" usage="rp_blit">
+		<reg32 offset="0" name="MIN" type="float"/>
+		<reg32 offset="1" name="MAX" type="float"/>
+	</array>
+
+	<reg32 offset="0x8090" name="GRAS_SU_CNTL" usage="rp_blit">
+		<bitfield name="CULL_FRONT" pos="0" type="boolean"/>
+		<bitfield name="CULL_BACK" pos="1" type="boolean"/>
+		<bitfield name="FRONT_CW" pos="2" type="boolean"/>
+		<bitfield name="LINEHALFWIDTH" low="3" high="10" radix="2" type="fixed"/>
+		<bitfield name="POLY_OFFSET" pos="11" type="boolean"/>
+		<bitfield name="UNK12" pos="12"/>
+		<bitfield name="LINE_MODE" pos="13" type="a5xx_line_mode"/>
+		<bitfield name="UNK15" low="15" high="16"/>
+		<!--
+                        On gen1 only MULTIVIEW_ENABLE exists. On gen3 we have
+                        the ability to add the view index to either the RT array
+                        index or the viewport index, and it seems that
+                        MULTIVIEW_ENABLE doesn't do anything, instead we need to
+                        set at least one of RENDERTARGETINDEXINCR or
+                        VIEWPORTINDEXINCR to enable multiview. The blob still
+                        sets MULTIVIEW_ENABLE regardless.
+                        TODO: what about gen2 (a640)?
+		-->
+		<bitfield name="MULTIVIEW_ENABLE" pos="17" type="boolean"/>
+		<bitfield name="RENDERTARGETINDEXINCR" pos="18" type="boolean"/>
+		<bitfield name="VIEWPORTINDEXINCR" pos="19" type="boolean"/>
+		<bitfield name="UNK20" low="20" high="22"/>
+	</reg32>
+	<reg32 offset="0x8091" name="GRAS_SU_POINT_MINMAX" usage="rp_blit">
+		<bitfield name="MIN" low="0" high="15" type="ufixed" radix="4"/>
+		<bitfield name="MAX" low="16" high="31" type="ufixed" radix="4"/>
+	</reg32>
+	<reg32 offset="0x8092" name="GRAS_SU_POINT_SIZE" low="0" high="15" type="fixed" radix="4" usage="rp_blit"/>
+	<!-- 0x8093 invalid -->
+	<reg32 offset="0x8094" name="GRAS_SU_DEPTH_PLANE_CNTL" usage="rp_blit">
+		<bitfield name="Z_MODE" low="0" high="1" type="a6xx_ztest_mode"/>
+	</reg32>
+	<reg32 offset="0x8095" name="GRAS_SU_POLY_OFFSET_SCALE" type="float" usage="rp_blit"/>
+	<reg32 offset="0x8096" name="GRAS_SU_POLY_OFFSET_OFFSET" type="float" usage="rp_blit"/>
+	<reg32 offset="0x8097" name="GRAS_SU_POLY_OFFSET_OFFSET_CLAMP" type="float" usage="rp_blit"/>
+	<!-- duplicates RB_DEPTH_BUFFER_INFO: -->
+	<reg32 offset="0x8098" name="GRAS_SU_DEPTH_BUFFER_INFO" usage="rp_blit">
+		<bitfield name="DEPTH_FORMAT" low="0" high="2" type="a6xx_depth_format"/>
+		<bitfield name="UNK3" pos="3"/>
+	</reg32>
+
+	<reg32 offset="0x8099" name="GRAS_SU_CONSERVATIVE_RAS_CNTL" usage="cmd">
+		<bitfield name="CONSERVATIVERASEN" pos="0" type="boolean"/>
+		<bitfield name="SHIFTAMOUNT" low="1" high="2"/>
+		<bitfield name="INNERCONSERVATIVERASEN" pos="3" type="boolean"/>
+		<bitfield name="UNK4" low="4" high="5"/>
+	</reg32>
+	<reg32 offset="0x809a" name="GRAS_SU_PATH_RENDERING_CNTL">
+		<bitfield name="UNK0" pos="0" type="boolean"/>
+		<bitfield name="LINELENGTHEN" pos="1" type="boolean"/>
+	</reg32>
+
+	<bitset name="a6xx_gras_layer_cntl" inline="yes">
+		<bitfield name="WRITES_LAYER" pos="0" type="boolean"/>
+		<bitfield name="WRITES_VIEW" pos="1" type="boolean"/>
+	</bitset>
+	<reg32 offset="0x809b" name="GRAS_VS_LAYER_CNTL" type="a6xx_gras_layer_cntl" usage="rp_blit"/>
+	<reg32 offset="0x809c" name="GRAS_GS_LAYER_CNTL" type="a6xx_gras_layer_cntl" usage="rp_blit"/>
+	<reg32 offset="0x809d" name="GRAS_DS_LAYER_CNTL" type="a6xx_gras_layer_cntl" usage="rp_blit"/>
+	<!-- 0x809e/0x809f invalid -->
+
+	<enum name="a6xx_sequenced_thread_dist">
+		<value value="0x0" name="DIST_SCREEN_COORD"/>
+		<value value="0x1" name="DIST_ALL_TO_RB0"/>
+	</enum>
+
+	<enum name="a6xx_single_prim_mode">
+		<value value="0x0" name="NO_FLUSH"/>
+		<doc>
+			In addition to FLUSH_PER_OVERLAP, guarantee that UCHE
+			and CCU don't get out of sync when fetching the previous
+			value for the current pixel. With NO_FLUSH, there's the
+			possibility that the flags for the current pixel are
+			flushed before the data or vice-versa, leading to
+			texture fetches via UCHE getting out of sync values.
+			This mode should eliminate that. It's used in bypass
+			mode for coherent blending
+			(GL_KHR_blend_equation_advanced_coherent) as well as
+			non-coherent blending.
+		</doc>
+		<value value="0x1" name="FLUSH_PER_OVERLAP_AND_OVERWRITE"/>
+		<doc>
+			Invalidate UCHE and wait for any pending work to finish
+			if there was possibly an overlapping primitive prior to
+			the current one. This is similar to a combination of
+			GRAS_SC_CONTROL::INJECT_L2_INVALIDATE_EVENT and
+			WAIT_RB_IDLE_ALL_TRI on a3xx. It's used in GMEM mode for
+			coherent blending
+			(GL_KHR_blend_equation_advanced_coherent).
+		</doc>
+		<value value="0x3" name="FLUSH_PER_OVERLAP"/>
+	</enum>
+
+	<!-- this probably has the same meaning as a3xx GRAS_SC_CONTROL::RASTER_MODE -->
+	<enum name="a6xx_raster_mode">
+		<value value="0x0" name="TYPE_TILED"/>
+		<value value="0x1" name="TYPE_WRITER"/>
+	</enum>
+
+	<!-- I'm guessing this is the same as a3xx -->
+	<enum name="a6xx_raster_direction">
+		<value value="0x0" name="LR_TB"/>
+		<value value="0x1" name="RL_TB"/>
+		<value value="0x2" name="LR_BT"/>
+		<value value="0x3" name="RB_BT"/>
+	</enum>
+
+	<reg32 offset="0x80a0" name="GRAS_SC_CNTL" usage="rp_blit">
+		<bitfield name="CCUSINGLECACHELINESIZE" low="0" high="2"/>
+		<bitfield name="SINGLE_PRIM_MODE" low="3" high="4" type="a6xx_single_prim_mode"/>
+		<bitfield name="RASTER_MODE" pos="5" type="a6xx_raster_mode"/>
+		<bitfield name="RASTER_DIRECTION" low="6" high="7" type="a6xx_raster_direction"/>
+		<bitfield name="SEQUENCED_THREAD_DISTRIBUTION" pos="8" type="a6xx_sequenced_thread_dist"/>
+		<!-- CCUSINGLECACHELINESIZE is ignored unless bit 9 is set -->
+		<bitfield name="UNK9" pos="9" type="boolean"/>
+		<bitfield name="ROTATION" low="10" high="11" type="uint"/>
+		<bitfield name="EARLYVIZOUTEN" pos="12" type="boolean"/>
+	</reg32>
+
+	<enum name="a6xx_render_mode">
+		<value value="0x0" name="RENDERING_PASS"/>
+		<value value="0x1" name="BINNING_PASS"/>
+	</enum>
+
+	<enum name="a6xx_buffers_location">
+		<value value="0" name="BUFFERS_IN_GMEM"/>
+		<value value="3" name="BUFFERS_IN_SYSMEM"/>
+	</enum>
+
+	<enum name="a6xx_lrz_feedback_mask">
+		<value value="0x0" name="LRZ_FEEDBACK_NONE"/>
+		<value value="0x1" name="LRZ_FEEDBACK_EARLY_Z"/>
+		<value value="0x2" name="LRZ_FEEDBACK_EARLY_LRZ_LATE_Z"/>
+		<!-- We don't have a flag type and this flags combination is often used -->
+		<value value="0x3" name="LRZ_FEEDBACK_EARLY_Z_OR_EARLY_LRZ_LATE_Z"/>
+		<value value="0x4" name="LRZ_FEEDBACK_LATE_Z"/>
+	</enum>
+
+	<reg32 offset="0x80a1" name="GRAS_BIN_CONTROL" usage="rp_blit">
+		<bitfield name="BINW" low="0" high="5" shr="5" type="uint"/>
+		<bitfield name="BINH" low="8" high="14" shr="4" type="uint"/>
+		<bitfield name="RENDER_MODE" low="18" high="20" type="a6xx_render_mode"/>
+		<doc>Disable LRZ feedback writes</doc>
+		<bitfield name="FORCE_LRZ_WRITE_DIS" pos="21" type="boolean"/>
+		<bitfield name="BUFFERS_LOCATION" low="22" high="23" type="a6xx_buffers_location" variants="A6XX"/>
+		<doc>
+			Allows draws that don't have GRAS_LRZ_CNTL.LRZ_WRITE but have
+			GRAS_LRZ_CNTL.ENABLE to contribute to LRZ during RENDERING pass.
+			In sysmem mode GRAS_LRZ_CNTL.LRZ_WRITE is not considered.
+		</doc>
+		<bitfield name="LRZ_FEEDBACK_ZMODE_MASK" low="24" high="26" type="a6xx_lrz_feedback_mask"/>
+		<bitfield name="UNK27" pos="27"/>
+	</reg32>
+
+	<reg32 offset="0x80a2" name="GRAS_RAS_MSAA_CNTL" usage="rp_blit">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="UNK2" pos="2"/>
+		<bitfield name="UNK3" pos="3"/>
+	</reg32>
+	<reg32 offset="0x80a3" name="GRAS_DEST_MSAA_CNTL" usage="rp_blit">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="MSAA_DISABLE" pos="2" type="boolean"/>
+	</reg32>
+
+	<bitset name="a6xx_sample_config" inline="yes">
+		<bitfield name="UNK0" pos="0"/>
+		<bitfield name="LOCATION_ENABLE" pos="1" type="boolean"/>
+	</bitset>
+
+	<bitset name="a6xx_sample_locations" inline="yes">
+		<bitfield name="SAMPLE_0_X" low="0" high="3" radix="4" type="fixed"/>
+		<bitfield name="SAMPLE_0_Y" low="4" high="7" radix="4" type="fixed"/>
+		<bitfield name="SAMPLE_1_X" low="8" high="11" radix="4" type="fixed"/>
+		<bitfield name="SAMPLE_1_Y" low="12" high="15" radix="4" type="fixed"/>
+		<bitfield name="SAMPLE_2_X" low="16" high="19" radix="4" type="fixed"/>
+		<bitfield name="SAMPLE_2_Y" low="20" high="23" radix="4" type="fixed"/>
+		<bitfield name="SAMPLE_3_X" low="24" high="27" radix="4" type="fixed"/>
+		<bitfield name="SAMPLE_3_Y" low="28" high="31" radix="4" type="fixed"/>
+	</bitset>
+
+	<reg32 offset="0x80a4" name="GRAS_SAMPLE_CONFIG" type="a6xx_sample_config" usage="rp_blit"/>
+	<reg32 offset="0x80a5" name="GRAS_SAMPLE_LOCATION_0" type="a6xx_sample_locations" usage="rp_blit"/>
+	<reg32 offset="0x80a6" name="GRAS_SAMPLE_LOCATION_1" type="a6xx_sample_locations" usage="rp_blit"/>
+
+	<reg32 offset="0x80a7" name="GRAS_UNKNOWN_80A7" variants="A7XX-" usage="cmd"/>
+
+	<!-- 0x80a7-0x80ae invalid -->
+	<reg32 offset="0x80af" name="GRAS_UNKNOWN_80AF" pos="0" usage="cmd"/>
+
+	<bitset name="a6xx_scissor_xy" inline="yes">
+		<bitfield name="X" low="0" high="15" type="uint"/>
+		<bitfield name="Y" low="16" high="31" type="uint"/>
+	</bitset>
+	<array offset="0x80b0" name="GRAS_SC_SCREEN_SCISSOR" stride="2" length="16" usage="rp_blit">
+		<reg32 offset="0" name="TL" type="a6xx_scissor_xy"/>
+		<reg32 offset="1" name="BR" type="a6xx_scissor_xy"/>
+	</array>
+	<array offset="0x80d0" name="GRAS_SC_VIEWPORT_SCISSOR" stride="2" length="16" usage="rp_blit">
+		<reg32 offset="0" name="TL" type="a6xx_scissor_xy"/>
+		<reg32 offset="1" name="BR" type="a6xx_scissor_xy"/>
+	</array>
+
+	<reg32 offset="0x80f0" name="GRAS_SC_WINDOW_SCISSOR_TL" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0x80f1" name="GRAS_SC_WINDOW_SCISSOR_BR" type="a6xx_reg_xy" usage="rp_blit"/>
+
+	<!-- 0x80f4 - 0x80fa are used for VK_KHR_fragment_shading_rate -->
+	<reg64 offset="0x80f4" name="GRAS_UNKNOWN_80F4" variants="A7XX-" usage="cmd"/>
+	<reg64 offset="0x80f5" name="GRAS_UNKNOWN_80F5" variants="A7XX-" usage="cmd"/>
+	<reg64 offset="0x80f6" name="GRAS_UNKNOWN_80F6" variants="A7XX-" usage="cmd"/>
+	<reg64 offset="0x80f8" name="GRAS_UNKNOWN_80F8" variants="A7XX-" usage="cmd"/>
+	<reg64 offset="0x80f9" name="GRAS_UNKNOWN_80F9" variants="A7XX-" usage="cmd"/>
+	<reg64 offset="0x80fa" name="GRAS_UNKNOWN_80FA" variants="A7XX-" usage="cmd"/>
+
+	<enum name="a6xx_lrz_dir_status">
+		<value value="0x1" name="LRZ_DIR_LE"/>
+		<value value="0x2" name="LRZ_DIR_GE"/>
+		<value value="0x3" name="LRZ_DIR_INVALID"/>
+	</enum>
+
+	<reg32 offset="0x8100" name="GRAS_LRZ_CNTL" usage="rp_blit">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<doc>LRZ write also disabled for blend/etc.</doc>
+		<bitfield name="LRZ_WRITE" pos="1" type="boolean"/>
+		<doc>update MAX instead of MIN value, ie. GL_GREATER/GL_GEQUAL</doc>
+		<bitfield name="GREATER" pos="2" type="boolean"/>
+		<doc>
+			Clears the LRZ block being touched to:
+			- 0.0 if GREATER
+			- 1.0 if LESS
+		</doc>
+		<bitfield name="FC_ENABLE" pos="3" type="boolean" variants="A6XX"/>
+		<!-- set when depth-test + depth-write enabled -->
+		<bitfield name="Z_TEST_ENABLE" pos="4" type="boolean"/>
+		<bitfield name="Z_BOUNDS_ENABLE" pos="5" type="boolean"/>
+		<bitfield name="DIR" low="6" high="7" type="a6xx_lrz_dir_status"/>
+		<doc>
+			If DISABLE_ON_WRONG_DIR enabled - write new LRZ direction into
+			buffer, in case of mismatched direction writes 0 (disables LRZ).
+		</doc>
+		<bitfield name="DIR_WRITE" pos="8" type="boolean"/>
+		<doc>
+			Disable LRZ based on previous direction and the current one.
+			If DIR_WRITE is not enabled - there is no write to direction buffer.
+		</doc>
+		<bitfield name="DISABLE_ON_WRONG_DIR" pos="9" type="boolean" variants="A6XX"/>
+		<bitfield name="Z_FUNC" low="11" high="13" type="adreno_compare_func" variants="A7XX-"/>
+	</reg32>
+
+	<enum name="a6xx_fragcoord_sample_mode">
+		<value value="0" name="FRAGCOORD_CENTER"/>
+		<value value="3" name="FRAGCOORD_SAMPLE"/>
+	</enum>
+
+	<reg32 offset="0x8101" name="GRAS_LRZ_PS_INPUT_CNTL" low="0" high="2" usage="rp_blit">
+		<bitfield name="SAMPLEID" pos="0" type="boolean"/>
+		<bitfield name="FRAGCOORDSAMPLEMODE" low="1" high="2" type="a6xx_fragcoord_sample_mode"/>
+	</reg32>
+
+	<reg32 offset="0x8102" name="GRAS_LRZ_MRT_BUF_INFO_0" usage="rp_blit">
+		<bitfield name="COLOR_FORMAT" low="0" high="7" type="a6xx_format"/>
+	</reg32>
+	<reg64 offset="0x8103" name="GRAS_LRZ_BUFFER_BASE" align="256" type="waddress" usage="rp_blit"/>
+	<reg32 offset="0x8105" name="GRAS_LRZ_BUFFER_PITCH" usage="rp_blit">
+		<!-- TODO: fix the shr fields -->
+		<bitfield name="PITCH" low="0" high="7" shr="5" type="uint"/>
+		<bitfield name="ARRAY_PITCH" low="10" high="28" shr="4" type="uint"/>
+	</reg32>
+
+	<!--
+	The LRZ "fast clear" buffer is initialized to zero's by blob, and
+	read/written when GRAS_LRZ_CNTL.FC_ENABLE (b3) is set.  It appears
+	to store 1b/block.  It appears that '0' means block has original
+	depth clear value, and '1' means that the corresponding block in
+	LRZ has been modified.  Ignoring alignment/padding, the size is
+	given by the formula:
+
+		// calculate LRZ size from depth size:
+		if (nr_samples == 4) {
+			width *= 2;
+			height *= 2;
+		} else if (nr_samples == 2) {
+			height *= 2;
+		}
+
+		lrz_width = div_round_up(width, 8);
+		lrz_heigh = div_round_up(height, 8);
+
+		// calculate # of blocks:
+		nblocksx = div_round_up(lrz_width, 16);
+		nblocksy = div_round_up(lrz_height, 4);
+
+		// fast-clear buffer is 1bit/block:
+		fc_sz = div_round_up(nblocksx * nblocksy, 8);
+
+	In practice the blob seems to switch off FC_ENABLE once the size
+	increases beyond 1 page.  Not sure if that is an actual limit or
+	not.
+	 -->
+	<reg64 offset="0x8106" name="GRAS_LRZ_FAST_CLEAR_BUFFER_BASE" align="64" type="waddress" usage="rp_blit"/>
+	<!-- 0x8108 invalid -->
+	<reg32 offset="0x8109" name="GRAS_SAMPLE_CNTL" usage="rp_blit">
+		<bitfield name="PER_SAMP_MODE" pos="0" type="boolean"/>
+	</reg32>
+	<!--
+	LRZ buffer represents a single array layer + mip level, and there is
+	a single buffer per depth image. Thus to reuse LRZ between renderpasses
+	it is necessary to track the depth view used in the past renderpass, which
+	GRAS_LRZ_DEPTH_VIEW is for.
+	GRAS_LRZ_CNTL checks if current value of GRAS_LRZ_DEPTH_VIEW is equal to
+	the value stored in the LRZ buffer, if not - LRZ is disabled.
+	-->
+	<reg32 offset="0x810a" name="GRAS_LRZ_DEPTH_VIEW" usage="cmd">
+		<bitfield name="BASE_LAYER" low="0" high="10" type="uint"/>
+		<bitfield name="LAYER_COUNT" low="16" high="26" type="uint"/>
+		<bitfield name="BASE_MIP_LEVEL" low="28" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x810b" name="GRAS_LRZ_CNTL2" variants="A7XX-" usage="rp_blit">
+		<bitfield name="DISABLE_ON_WRONG_DIR" pos="0" type="boolean"/>
+		<bitfield name="FC_ENABLE" pos="1" type="boolean"/>
+	</reg32>
+
+	<!-- 0x810c-0x810f invalid -->
+
+	<reg32 offset="0x8110" name="GRAS_UNKNOWN_8110" low="0" high="1" usage="cmd"/>
+
+	<!-- A bit tentative but it's a color and it is followed by LRZ_CLEAR -->
+	<reg32 offset="0x8111" name="GRAS_LRZ_CLEAR_DEPTH_F32" type="float" variants="A7XX-"/>
+
+	<reg32 offset="0x8113" name="GRAS_LRZ_DEPTH_BUFFER_INFO" variants="A7XX-" usage="rp_blit">
+		<bitfield name="DEPTH_FORMAT" low="0" high="2" type="a6xx_depth_format"/>
+		<bitfield name="UNK3" pos="3"/>
+	</reg32>
+
+	<!-- Always written together and always equal 09510840 00000a62 -->
+	<reg32 offset="0x8120" name="GRAS_UNKNOWN_8120" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0x8121" name="GRAS_UNKNOWN_8121" variants="A7XX-" usage="cmd"/>
+
+	<!-- 0x8112-0x83ff invalid -->
+
+	<enum name="a6xx_rotation">
+		<value value="0x0" name="ROTATE_0"/>
+		<value value="0x1" name="ROTATE_90"/>
+		<value value="0x2" name="ROTATE_180"/>
+		<value value="0x3" name="ROTATE_270"/>
+		<value value="0x4" name="ROTATE_HFLIP"/>
+		<value value="0x5" name="ROTATE_VFLIP"/>
+	</enum>
+
+	<bitset name="a6xx_2d_blit_cntl" inline="yes">
+		<bitfield name="ROTATE" low="0" high="2" type="a6xx_rotation"/>
+		<bitfield name="OVERWRITEEN" pos="3" type="boolean"/>
+		<bitfield name="UNK4" low="4" high="6"/>
+		<bitfield name="SOLID_COLOR" pos="7" type="boolean"/>
+		<bitfield name="COLOR_FORMAT" low="8" high="15" type="a6xx_format"/>
+		<bitfield name="SCISSOR" pos="16" type="boolean"/>
+		<bitfield name="UNK17" low="17" high="18"/>
+		<!-- required when blitting D24S8/D24X8 -->
+		<bitfield name="D24S8" pos="19" type="boolean"/>
+		<!-- some sort of channel mask, disabled channels are set to zero ? -->
+		<bitfield name="MASK" low="20" high="23"/>
+		<bitfield name="IFMT" low="24" high="28" type="a6xx_2d_ifmt"/>
+		<bitfield name="RASTER_MODE" pos="29" type="a6xx_raster_mode"/>
+		<bitfield name="UNK30" pos="30" type="boolean" variants="A7XX-"/>
+	</bitset>
+
+	<reg32 offset="0x8400" name="GRAS_2D_BLIT_CNTL" type="a6xx_2d_blit_cntl" usage="rp_blit"/>
+	<!-- note: the low 8 bits for src coords are valid, probably fixed point
+	     it would be a bit weird though, since we subtract 1 from BR coords
+	     apparently signed, gallium driver uses negative coords and it works?
+	 -->
+	<reg32 offset="0x8401" name="GRAS_2D_SRC_TL_X" low="8" high="24" type="int" usage="rp_blit"/>
+	<reg32 offset="0x8402" name="GRAS_2D_SRC_BR_X" low="8" high="24" type="int" usage="rp_blit"/>
+	<reg32 offset="0x8403" name="GRAS_2D_SRC_TL_Y" low="8" high="24" type="int" usage="rp_blit"/>
+	<reg32 offset="0x8404" name="GRAS_2D_SRC_BR_Y" low="8" high="24" type="int" usage="rp_blit"/>
+	<reg32 offset="0x8405" name="GRAS_2D_DST_TL" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0x8406" name="GRAS_2D_DST_BR" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0x8407" name="GRAS_2D_UNKNOWN_8407" low="0" high="31"/>
+	<reg32 offset="0x8408" name="GRAS_2D_UNKNOWN_8408" low="0" high="31"/>
+	<reg32 offset="0x8409" name="GRAS_2D_UNKNOWN_8409" low="0" high="31"/>
+	<reg32 offset="0x840a" name="GRAS_2D_RESOLVE_CNTL_1" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0x840b" name="GRAS_2D_RESOLVE_CNTL_2" type="a6xx_reg_xy" usage="rp_blit"/>
+	<!-- 0x840c-0x85ff invalid -->
+
+	<!-- always 0x880 ? (and 0 in a640/a650 traces?) -->
+	<reg32 offset="0x8600" name="GRAS_DBG_ECO_CNTL" usage="cmd">
+		<bitfield name="UNK7" pos="7" type="boolean"/>
+		<bitfield name="LRZCACHELOCKDIS" pos="11" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x8601" name="GRAS_ADDR_MODE_CNTL" pos="0" type="a5xx_address_mode"/>
+	<reg32 offset="0x8602" name="GRAS_NC_MODE_CNTL" variants="A7XX-"/>
+	<array offset="0x8610" name="GRAS_PERFCTR_TSE_SEL" stride="1" length="4"/>
+	<array offset="0x8614" name="GRAS_PERFCTR_RAS_SEL" stride="1" length="4"/>
+	<array offset="0x8618" name="GRAS_PERFCTR_LRZ_SEL" stride="1" length="4"/>
+
+	<!-- note 0x8620-0x87ff are not all invalid
+	(in particular, 0x8631/0x8632 have 0x3fff3fff mask and would be xy coords)
+	-->
+
+	<!-- same as GRAS_BIN_CONTROL, but without bit 27: -->
+	<reg32 offset="0x8800" name="RB_BIN_CONTROL" variants="A6XX" usage="rp_blit">
+		<bitfield name="BINW" low="0" high="5" shr="5" type="uint"/>
+		<bitfield name="BINH" low="8" high="14" shr="4" type="uint"/>
+		<bitfield name="RENDER_MODE" low="18" high="20" type="a6xx_render_mode"/>
+		<bitfield name="FORCE_LRZ_WRITE_DIS" pos="21" type="boolean"/>
+		<bitfield name="BUFFERS_LOCATION" low="22" high="23" type="a6xx_buffers_location"/>
+		<bitfield name="LRZ_FEEDBACK_ZMODE_MASK" low="24" high="26" type="a6xx_lrz_feedback_mask"/>
+	</reg32>
+
+	<reg32 offset="0x8800" name="RB_BIN_CONTROL" variants="A7XX-" usage="rp_blit">
+		<bitfield name="BINW" low="0" high="5" shr="5" type="uint"/>
+		<bitfield name="BINH" low="8" high="14" shr="4" type="uint"/>
+		<bitfield name="RENDER_MODE" low="18" high="20" type="a6xx_render_mode"/>
+		<bitfield name="FORCE_LRZ_WRITE_DIS" pos="21" type="boolean"/>
+		<bitfield name="LRZ_FEEDBACK_ZMODE_MASK" low="24" high="26" type="a6xx_lrz_feedback_mask"/>
+	</reg32>
+
+	<reg32 offset="0x8801" name="RB_RENDER_CNTL" variants="A6XX" usage="rp_blit">
+		<bitfield name="CCUSINGLECACHELINESIZE" low="3" high="5"/>
+		<bitfield name="EARLYVIZOUTEN" pos="6" type="boolean"/>
+		<!-- set during binning pass: -->
+		<bitfield name="BINNING" pos="7" type="boolean"/>
+		<bitfield name="UNK8" low="8" high="10"/>
+		<bitfield name="RASTER_MODE" pos="8" type="a6xx_raster_mode"/>
+		<bitfield name="RASTER_DIRECTION" low="9" high="10" type="a6xx_raster_direction"/>
+		<bitfield name="CONSERVATIVERASEN" pos="11" type="boolean"/>
+		<bitfield name="INNERCONSERVATIVERASEN" pos="12" type="boolean"/>
+		<!-- bit seems to be set whenever depth buffer enabled: -->
+		<bitfield name="FLAG_DEPTH" pos="14" type="boolean"/>
+		<!-- bitmask of MRTs using UBWC flag buffer: -->
+		<bitfield name="FLAG_MRTS" low="16" high="23"/>
+	</reg32>
+	<reg32 offset="0x8801" name="RB_RENDER_CNTL" variants="A7XX-" usage="rp_blit">
+		<bitfield name="EARLYVIZOUTEN" pos="6" type="boolean"/>
+		<!-- set during binning pass: -->
+		<bitfield name="BINNING" pos="7" type="boolean"/>
+		<bitfield name="RASTER_MODE" pos="8" type="a6xx_raster_mode"/>
+		<bitfield name="RASTER_DIRECTION" low="9" high="10" type="a6xx_raster_direction"/>
+		<bitfield name="CONSERVATIVERASEN" pos="11" type="boolean"/>
+		<bitfield name="INNERCONSERVATIVERASEN" pos="12" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x8116" name="GRAS_SU_RENDER_CNTL" variants="A7XX-" usage="rp_blit">
+		<bitfield name="BINNING" pos="7" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x8802" name="RB_RAS_MSAA_CNTL" usage="rp_blit">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="UNK2" pos="2"/>
+		<bitfield name="UNK3" pos="3"/>
+	</reg32>
+	<reg32 offset="0x8803" name="RB_DEST_MSAA_CNTL" usage="rp_blit">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="MSAA_DISABLE" pos="2" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x8804" name="RB_SAMPLE_CONFIG" type="a6xx_sample_config" usage="rp_blit"/>
+	<reg32 offset="0x8805" name="RB_SAMPLE_LOCATION_0" type="a6xx_sample_locations" usage="rp_blit"/>
+	<reg32 offset="0x8806" name="RB_SAMPLE_LOCATION_1" type="a6xx_sample_locations" usage="rp_blit"/>
+	<!-- 0x8807-0x8808 invalid -->
+	<!--
+	note: maybe not actually called RB_RENDER_CONTROLn (since RB_RENDER_CNTL
+	name comes from kernel and is probably right)
+	 -->
+	<reg32 offset="0x8809" name="RB_RENDER_CONTROL0" usage="rp_blit">
+		<!-- see also GRAS_CNTL -->
+		<bitfield name="IJ_PERSP_PIXEL" pos="0" type="boolean"/>
+		<bitfield name="IJ_PERSP_CENTROID" pos="1" type="boolean"/>
+		<bitfield name="IJ_PERSP_SAMPLE" pos="2" type="boolean"/>
+		<bitfield name="IJ_LINEAR_PIXEL" pos="3" type="boolean"/>
+		<bitfield name="IJ_LINEAR_CENTROID" pos="4" type="boolean"/>
+		<bitfield name="IJ_LINEAR_SAMPLE" pos="5" type="boolean"/>
+		<bitfield name="COORD_MASK" low="6" high="9" type="hex"/>
+		<bitfield name="UNK10" pos="10" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x880a" name="RB_RENDER_CONTROL1" usage="rp_blit">
+		<!-- enable bits for various FS sysvalue regs: -->
+		<bitfield name="SAMPLEMASK" pos="0" type="boolean"/>
+		<bitfield name="POSTDEPTHCOVERAGE" pos="1" type="boolean"/>
+		<bitfield name="FACENESS" pos="2" type="boolean"/>
+		<bitfield name="SAMPLEID" pos="3" type="boolean"/>
+		<bitfield name="FRAGCOORDSAMPLEMODE" low="4" high="5" type="a6xx_fragcoord_sample_mode"/>
+		<bitfield name="CENTERRHW" pos="6" type="boolean"/>
+		<bitfield name="LINELENGTHEN" pos="7" type="boolean"/>
+		<bitfield name="FOVEATION" pos="8" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x880b" name="RB_FS_OUTPUT_CNTL0" usage="rp_blit">
+		<bitfield name="DUAL_COLOR_IN_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="FRAG_WRITES_Z" pos="1" type="boolean"/>
+		<bitfield name="FRAG_WRITES_SAMPMASK" pos="2" type="boolean"/>
+		<bitfield name="FRAG_WRITES_STENCILREF" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x880c" name="RB_FS_OUTPUT_CNTL1" usage="rp_blit">
+		<bitfield name="MRT" low="0" high="3" type="uint"/>
+	</reg32>
+	<reg32 offset="0x880d" name="RB_RENDER_COMPONENTS" usage="rp_blit">
+		<bitfield name="RT0" low="0" high="3"/>
+		<bitfield name="RT1" low="4" high="7"/>
+		<bitfield name="RT2" low="8" high="11"/>
+		<bitfield name="RT3" low="12" high="15"/>
+		<bitfield name="RT4" low="16" high="19"/>
+		<bitfield name="RT5" low="20" high="23"/>
+		<bitfield name="RT6" low="24" high="27"/>
+		<bitfield name="RT7" low="28" high="31"/>
+	</reg32>
+	<reg32 offset="0x880e" name="RB_DITHER_CNTL" usage="cmd">
+		<bitfield name="DITHER_MODE_MRT0" low="0"  high="1"  type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_MODE_MRT1" low="2"  high="3"  type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_MODE_MRT2" low="4"  high="5"  type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_MODE_MRT3" low="6"  high="7"  type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_MODE_MRT4" low="8"  high="9"  type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_MODE_MRT5" low="10" high="11" type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_MODE_MRT6" low="12" high="13" type="adreno_rb_dither_mode"/>
+		<bitfield name="DITHER_MODE_MRT7" low="14" high="15" type="adreno_rb_dither_mode"/>
+	</reg32>
+	<reg32 offset="0x880f" name="RB_SRGB_CNTL" usage="rp_blit">
+		<!-- Same as SP_SRGB_CNTL -->
+		<bitfield name="SRGB_MRT0" pos="0" type="boolean"/>
+		<bitfield name="SRGB_MRT1" pos="1" type="boolean"/>
+		<bitfield name="SRGB_MRT2" pos="2" type="boolean"/>
+		<bitfield name="SRGB_MRT3" pos="3" type="boolean"/>
+		<bitfield name="SRGB_MRT4" pos="4" type="boolean"/>
+		<bitfield name="SRGB_MRT5" pos="5" type="boolean"/>
+		<bitfield name="SRGB_MRT6" pos="6" type="boolean"/>
+		<bitfield name="SRGB_MRT7" pos="7" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x8810" name="RB_SAMPLE_CNTL" usage="rp_blit">
+		<bitfield name="PER_SAMP_MODE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x8811" name="RB_UNKNOWN_8811" low="4" high="6" usage="cmd"/>
+	<reg32 offset="0x8812" name="RB_UNKNOWN_8812" variants="A7XX-" usage="rp_blit"/>
+	<!-- 0x8813-0x8817 invalid -->
+	<!-- always 0x0 ? -->
+	<reg32 offset="0x8818" name="RB_UNKNOWN_8818" low="0" high="6" usage="cmd"/>
+	<!-- 0x8819-0x881e all 32 bits -->
+	<reg32 offset="0x8819" name="RB_UNKNOWN_8819" usage="cmd"/>
+	<reg32 offset="0x881a" name="RB_UNKNOWN_881A" usage="cmd"/>
+	<reg32 offset="0x881b" name="RB_UNKNOWN_881B" usage="cmd"/>
+	<reg32 offset="0x881c" name="RB_UNKNOWN_881C" usage="cmd"/>
+	<reg32 offset="0x881d" name="RB_UNKNOWN_881D" usage="cmd"/>
+	<reg32 offset="0x881e" name="RB_UNKNOWN_881E" usage="cmd"/>
+	<!-- 0x881f invalid -->
+	<array offset="0x8820" name="RB_MRT" stride="8" length="8" usage="rp_blit">
+		<reg32 offset="0x0" name="CONTROL">
+			<bitfield name="BLEND" pos="0" type="boolean"/>
+			<bitfield name="BLEND2" pos="1" type="boolean"/>
+			<bitfield name="ROP_ENABLE" pos="2" type="boolean"/>
+			<bitfield name="ROP_CODE" low="3" high="6" type="a3xx_rop_code"/>
+			<bitfield name="COMPONENT_ENABLE" low="7" high="10" type="hex"/>
+		</reg32>
+		<reg32 offset="0x1" name="BLEND_CONTROL">
+			<bitfield name="RGB_SRC_FACTOR" low="0" high="4" type="adreno_rb_blend_factor"/>
+			<bitfield name="RGB_BLEND_OPCODE" low="5" high="7" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="RGB_DEST_FACTOR" low="8" high="12" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_SRC_FACTOR" low="16" high="20" type="adreno_rb_blend_factor"/>
+			<bitfield name="ALPHA_BLEND_OPCODE" low="21" high="23" type="a3xx_rb_blend_opcode"/>
+			<bitfield name="ALPHA_DEST_FACTOR" low="24" high="28" type="adreno_rb_blend_factor"/>
+		</reg32>
+		<reg32 offset="0x2" name="BUF_INFO" variants="A6XX">
+			<bitfield name="COLOR_FORMAT" low="0" high="7" type="a6xx_format"/>
+			<bitfield name="COLOR_TILE_MODE" low="8" high="9" type="a6xx_tile_mode"/>
+			<bitfield name="UNK10" pos="10"/>
+			<bitfield name="COLOR_SWAP" low="13" high="14" type="a3xx_color_swap"/>
+		</reg32>
+		<reg32 offset="0x2" name="BUF_INFO" variants="A7XX-">
+			<bitfield name="COLOR_FORMAT" low="0" high="7" type="a6xx_format"/>
+			<bitfield name="COLOR_TILE_MODE" low="8" high="9" type="a6xx_tile_mode"/>
+			<bitfield name="UNK10" pos="10"/>
+			<bitfield name="LOSSLESSCOMPEN" pos="11" type="boolean"/>
+			<bitfield name="COLOR_SWAP" low="13" high="14" type="a3xx_color_swap"/>
+			<bitfield name="MUTABLEEN" pos="16" type="boolean" variants="A7XX-"/>
+		</reg32>
+		<!--
+		at least in gmem, things seem to be aligned to pitch of 64..
+		maybe an artifact of tiled format used in gmem?
+		 -->
+		<reg32 offset="0x3" name="PITCH" shr="6" high="15" type="uint"/>
+		<reg32 offset="0x4" name="ARRAY_PITCH" shr="6" high="28" type="uint"/>
+		<!--
+		Compared to a5xx and before, we configure both a GMEM base and
+		external base.  Not sure if this is to facilitate GMEM save/
+		restore for context switch, or just to simplify state setup to
+		not have to care about GMEM vs BYPASS mode.
+		 -->
+		<!-- maybe something in low bits since alignment of 1 doesn't make sense? -->
+		<reg64 offset="0x5" name="BASE" type="waddress" align="1"/>
+
+		<reg32 offset="0x7" name="BASE_GMEM" low="12" high="31" shr="12"/>
+	</array>
+
+	<reg32 offset="0x8860" name="RB_BLEND_RED_F32" type="float" usage="rp_blit"/>
+	<reg32 offset="0x8861" name="RB_BLEND_GREEN_F32" type="float" usage="rp_blit"/>
+	<reg32 offset="0x8862" name="RB_BLEND_BLUE_F32" type="float" usage="rp_blit"/>
+	<reg32 offset="0x8863" name="RB_BLEND_ALPHA_F32" type="float" usage="rp_blit"/>
+	<reg32 offset="0x8864" name="RB_ALPHA_CONTROL" usage="cmd">
+		<bitfield name="ALPHA_REF" low="0" high="7" type="hex"/>
+		<bitfield name="ALPHA_TEST" pos="8" type="boolean"/>
+		<bitfield name="ALPHA_TEST_FUNC" low="9" high="11" type="adreno_compare_func"/>
+	</reg32>
+	<reg32 offset="0x8865" name="RB_BLEND_CNTL" usage="rp_blit">
+		<!-- per-mrt enable bit -->
+		<bitfield name="ENABLE_BLEND" low="0" high="7"/>
+		<bitfield name="INDEPENDENT_BLEND" pos="8" type="boolean"/>
+		<bitfield name="DUAL_COLOR_IN_ENABLE" pos="9" type="boolean"/>
+		<bitfield name="ALPHA_TO_COVERAGE" pos="10" type="boolean"/>
+		<bitfield name="ALPHA_TO_ONE" pos="11" type="boolean"/>
+		<bitfield name="SAMPLE_MASK" low="16" high="31"/>
+	</reg32>
+	<!-- 0x8866-0x886f invalid -->
+	<reg32 offset="0x8870" name="RB_DEPTH_PLANE_CNTL" usage="rp_blit">
+		<bitfield name="Z_MODE" low="0" high="1" type="a6xx_ztest_mode"/>
+	</reg32>
+
+	<reg32 offset="0x8871" name="RB_DEPTH_CNTL" usage="rp_blit">
+		<bitfield name="Z_TEST_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="Z_WRITE_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="ZFUNC" low="2" high="4" type="adreno_compare_func"/>
+		<bitfield name="Z_CLAMP_ENABLE" pos="5" type="boolean"/>
+		<doc>
+		Z_READ_ENABLE bit is set for zfunc other than GL_ALWAYS or GL_NEVER
+		also set when Z_BOUNDS_ENABLE is set
+		</doc>
+		<bitfield name="Z_READ_ENABLE" pos="6" type="boolean"/>
+		<bitfield name="Z_BOUNDS_ENABLE" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x8114" name="GRAS_SU_DEPTH_CNTL" usage="rp_blit">
+		<bitfield name="Z_TEST_ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<!-- duplicates GRAS_SU_DEPTH_BUFFER_INFO: -->
+	<reg32 offset="0x8872" name="RB_DEPTH_BUFFER_INFO" variants="A6XX" usage="rp_blit">
+		<bitfield name="DEPTH_FORMAT" low="0" high="2" type="a6xx_depth_format"/>
+		<bitfield name="UNK3" low="3" high="4"/>
+	</reg32>
+	<!-- first 4 bits duplicates GRAS_SU_DEPTH_BUFFER_INFO -->
+	<reg32 offset="0x8872" name="RB_DEPTH_BUFFER_INFO" variants="A7XX-" usage="rp_blit">
+		<bitfield name="DEPTH_FORMAT" low="0" high="2" type="a6xx_depth_format"/>
+		<bitfield name="UNK3" low="3" high="4"/>
+		<bitfield name="TILEMODE" low="5" high="6" type="a6xx_tile_mode"/>
+		<bitfield name="LOSSLESSCOMPEN" pos="7" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x8873" name="RB_DEPTH_BUFFER_PITCH" low="0" high="13" shr="6" type="uint" usage="rp_blit"/>
+	<reg32 offset="0x8874" name="RB_DEPTH_BUFFER_ARRAY_PITCH" low="0" high="27" shr="6" type="uint" usage="rp_blit"/>
+	<reg64 offset="0x8875" name="RB_DEPTH_BUFFER_BASE" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x8877" name="RB_DEPTH_BUFFER_BASE_GMEM" low="12" high="31" shr="12" usage="rp_blit"/>
+
+	<reg32 offset="0x8878" name="RB_Z_BOUNDS_MIN" type="float" usage="rp_blit"/>
+	<reg32 offset="0x8879" name="RB_Z_BOUNDS_MAX" type="float" usage="rp_blit"/>
+	<!-- 0x887a-0x887f invalid -->
+	<reg32 offset="0x8880" name="RB_STENCIL_CONTROL" usage="rp_blit">
+		<bitfield name="STENCIL_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="STENCIL_ENABLE_BF" pos="1" type="boolean"/>
+		<!--
+			set for stencil operations that require read from stencil
+			buffer, but not for example for stencil clear (which does
+			not require read).. so guessing this is analogous to
+			READ_DEST_ENABLE for color buffer..
+		 -->
+		<bitfield name="STENCIL_READ" pos="2" type="boolean"/>
+		<bitfield name="FUNC" low="8" high="10" type="adreno_compare_func"/>
+		<bitfield name="FAIL" low="11" high="13" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS" low="14" high="16" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL" low="17" high="19" type="adreno_stencil_op"/>
+		<bitfield name="FUNC_BF" low="20" high="22" type="adreno_compare_func"/>
+		<bitfield name="FAIL_BF" low="23" high="25" type="adreno_stencil_op"/>
+		<bitfield name="ZPASS_BF" low="26" high="28" type="adreno_stencil_op"/>
+		<bitfield name="ZFAIL_BF" low="29" high="31" type="adreno_stencil_op"/>
+	</reg32>
+	<reg32 offset="0x8115" name="GRAS_SU_STENCIL_CNTL" usage="rp_blit">
+		<bitfield name="STENCIL_ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x8881" name="RB_STENCIL_INFO" variants="A6XX" usage="rp_blit">
+		<bitfield name="SEPARATE_STENCIL" pos="0" type="boolean"/>
+		<bitfield name="UNK1" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x8881" name="RB_STENCIL_INFO" variants="A7XX-" usage="rp_blit">
+		<bitfield name="SEPARATE_STENCIL" pos="0" type="boolean"/>
+		<bitfield name="UNK1" pos="1" type="boolean"/>
+		<bitfield name="TILEMODE" low="2" high="3" type="a6xx_tile_mode"/>
+	</reg32>
+	<reg32 offset="0x8882" name="RB_STENCIL_BUFFER_PITCH" low="0" high="11" shr="6" type="uint" usage="rp_blit"/>
+	<reg32 offset="0x8883" name="RB_STENCIL_BUFFER_ARRAY_PITCH" low="0" high="23" shr="6" type="uint" usage="rp_blit"/>
+	<reg64 offset="0x8884" name="RB_STENCIL_BUFFER_BASE" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x8886" name="RB_STENCIL_BUFFER_BASE_GMEM" low="12" high="31" shr="12" usage="rp_blit"/>
+	<reg32 offset="0x8887" name="RB_STENCILREF" usage="rp_blit">
+		<bitfield name="REF" low="0" high="7"/>
+		<bitfield name="BFREF" low="8" high="15"/>
+	</reg32>
+	<reg32 offset="0x8888" name="RB_STENCILMASK" usage="rp_blit">
+		<bitfield name="MASK" low="0" high="7"/>
+		<bitfield name="BFMASK" low="8" high="15"/>
+	</reg32>
+	<reg32 offset="0x8889" name="RB_STENCILWRMASK" usage="rp_blit">
+		<bitfield name="WRMASK" low="0" high="7"/>
+		<bitfield name="BFWRMASK" low="8" high="15"/>
+	</reg32>
+	<!-- 0x888a-0x888f invalid -->
+	<reg32 offset="0x8890" name="RB_WINDOW_OFFSET" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0x8891" name="RB_SAMPLE_COUNT_CONTROL" usage="cmd">
+		<bitfield name="DISABLE" pos="0" type="boolean"/>
+		<bitfield name="COPY" pos="1" type="boolean"/>
+	</reg32>
+	<!-- 0x8892-0x8897 invalid -->
+	<reg32 offset="0x8898" name="RB_LRZ_CNTL" usage="rp_blit">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x8899" name="RB_UNKNOWN_8899" variants="A7XX-" usage="cmd"/>
+	<!-- 0x8899-0x88bf invalid -->
+	<!-- clamps depth value for depth test/write -->
+	<reg32 offset="0x88c0" name="RB_Z_CLAMP_MIN" type="float" usage="rp_blit"/>
+	<reg32 offset="0x88c1" name="RB_Z_CLAMP_MAX" type="float" usage="rp_blit"/>
+	<!-- 0x88c2-0x88cf invalid-->
+	<reg32 offset="0x88d0" name="RB_UNKNOWN_88D0" usage="rp_blit">
+		<bitfield name="UNK0" low="0" high="12"/>
+		<bitfield name="UNK16" low="16" high="26"/>
+	</reg32>
+	<reg32 offset="0x88d1" name="RB_BLIT_SCISSOR_TL" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0x88d2" name="RB_BLIT_SCISSOR_BR" type="a6xx_reg_xy" usage="rp_blit"/>
+	<!-- weird to duplicate other regs from same block?? -->
+	<reg32 offset="0x88d3" name="RB_BIN_CONTROL2" usage="rp_blit">
+		<bitfield name="BINW" low="0" high="5" shr="5" type="uint"/>
+		<bitfield name="BINH" low="8" high="14" shr="4" type="uint"/>
+	</reg32>
+	<reg32 offset="0x88d4" name="RB_WINDOW_OFFSET2" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0x88d5" name="RB_BLIT_GMEM_MSAA_CNTL" usage="rp_blit">
+		<bitfield name="SAMPLES" low="3" high="4" type="a3xx_msaa_samples"/>
+	</reg32>
+	<reg32 offset="0x88d6" name="RB_BLIT_BASE_GMEM" low="12" high="31" shr="12" usage="rp_blit"/>
+	<!-- s/DST_FORMAT/DST_INFO/ probably: -->
+	<reg32 offset="0x88d7" name="RB_BLIT_DST_INFO" usage="rp_blit">
+		<bitfield name="TILE_MODE" low="0" high="1" type="a6xx_tile_mode"/>
+		<bitfield name="FLAGS" pos="2" type="boolean"/>
+		<bitfield name="SAMPLES" low="3" high="4" type="a3xx_msaa_samples"/>
+		<bitfield name="COLOR_SWAP" low="5" high="6" type="a3xx_color_swap"/>
+		<bitfield name="COLOR_FORMAT" low="7" high="14" type="a6xx_format"/>
+		<bitfield name="UNK15" pos="15" type="boolean"/>
+		<bitfield name="MUTABLEEN" pos="16" type="boolean" variants="A7XX-"/>
+	</reg32>
+	<reg64 offset="0x88d8" name="RB_BLIT_DST" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x88da" name="RB_BLIT_DST_PITCH" low="0" high="15" shr="6" type="uint" usage="rp_blit"/>
+	<!-- array-pitch is size of layer -->
+	<reg32 offset="0x88db" name="RB_BLIT_DST_ARRAY_PITCH" low="0" high="28" shr="6" type="uint" usage="rp_blit"/>
+	<reg64 offset="0x88dc" name="RB_BLIT_FLAG_DST" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x88de" name="RB_BLIT_FLAG_DST_PITCH" usage="rp_blit">
+		<bitfield name="PITCH" low="0" high="10" shr="6" type="uint"/>
+		<bitfield name="ARRAY_PITCH" low="11" high="27" shr="7" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x88df" name="RB_BLIT_CLEAR_COLOR_DW0" usage="rp_blit"/>
+	<reg32 offset="0x88e0" name="RB_BLIT_CLEAR_COLOR_DW1" usage="rp_blit"/>
+	<reg32 offset="0x88e1" name="RB_BLIT_CLEAR_COLOR_DW2" usage="rp_blit"/>
+	<reg32 offset="0x88e2" name="RB_BLIT_CLEAR_COLOR_DW3" usage="rp_blit"/>
+
+	<!-- seems somewhat similar to what we called RB_CLEAR_CNTL on a5xx: -->
+	<reg32 offset="0x88e3" name="RB_BLIT_INFO" usage="rp_blit">
+		<bitfield name="UNK0" pos="0" type="boolean"/> <!-- s8 stencil restore/clear?  But also color restore? -->
+		<bitfield name="GMEM" pos="1" type="boolean"/> <!-- set for restore and clear to gmem? -->
+		<bitfield name="SAMPLE_0" pos="2" type="boolean"/> <!-- takes sample 0 instead of averaging -->
+		<bitfield name="DEPTH" pos="3" type="boolean"/> <!-- z16/z32/z24s8/x24x8 clear or resolve? -->
+		<doc>
+			For clearing depth/stencil
+				1 - depth
+				2 - stencil
+				3 - depth+stencil
+			For clearing color buffer:
+				then probably a component mask, I always see 0xf
+		</doc>
+		<bitfield name="CLEAR_MASK" low="4" high="7"/>
+		<!-- set when this is the last resolve on a650+ -->
+		<bitfield name="LAST" low="8" high="9"/>
+		<!--
+			a618 GLES: color render target number being resolved for RM6_RESOLVE, 0x8 for depth, 0x9 for separate stencil.
+			a618 VK: 0x8 for depth RM6_RESOLVE, 0x9 for separate stencil, 0 otherwise.
+
+			We believe this is related to concurrent resolves
+		 -->
+		<bitfield name="BUFFER_ID" low="12" high="15"/>
+	</reg32>
+	<reg32 offset="0x88e4" name="RB_UNKNOWN_88E4" variants="A7XX-" usage="rp_blit">
+		<!-- Value conditioned based on predicate, changed before blits -->
+		<bitfield name="UNK0" pos="0" type="boolean"/>
+	</reg32>
+
+	<enum name="a6xx_ccu_cache_size">
+		<value value="0x0" name="CCU_CACHE_SIZE_FULL"/>
+		<value value="0x1" name="CCU_CACHE_SIZE_HALF"/>
+		<value value="0x2" name="CCU_CACHE_SIZE_QUARTER"/>
+		<value value="0x3" name="CCU_CACHE_SIZE_EIGHTH"/>
+	</enum>
+	<reg32 offset="0x88e5" name="RB_CCU_CNTL2" variants="A7XX-" usage="cmd">
+		<bitfield name="DEPTH_OFFSET_HI" pos="0" type="hex"/>
+		<bitfield name="COLOR_OFFSET_HI" pos="2" type="hex"/>
+		<bitfield name="DEPTH_CACHE_SIZE" low="10" high="11" type="a6xx_ccu_cache_size"/>
+		<!-- GMEM offset of CCU depth cache -->
+		<bitfield name="DEPTH_OFFSET" low="12" high="20" shr="12" type="hex"/>
+		<bitfield name="COLOR_CACHE_SIZE" low="21" high="22" type="a6xx_ccu_cache_size"/>
+		<!-- GMEM offset of CCU color cache
+			for GMEM rendering, we set it to GMEM size minus the minimum
+			CCU color cache size. CCU color cache will be needed in some
+			resolve cases, and in those cases we need to reserve the end
+			of GMEM for color cache.
+		-->
+		<bitfield name="COLOR_OFFSET" low="23" high="31" shr="12" type="hex"/>
+	</reg32>
+	<!-- 0x88e6-0x88ef invalid -->
+	<!-- always 0x0 ? -->
+	<reg32 offset="0x88f0" name="RB_UNKNOWN_88F0" low="0" high="11" usage="cmd"/>
+	<!-- could be for separate stencil? (or may not be a flag buffer at all) -->
+	<reg64 offset="0x88f1" name="RB_UNK_FLAG_BUFFER_BASE" type="waddress" align="64"/>
+	<reg32 offset="0x88f3" name="RB_UNK_FLAG_BUFFER_PITCH">
+		<bitfield name="PITCH" low="0" high="10" shr="6" type="uint"/>
+		<bitfield name="ARRAY_PITCH" low="11" high="23" shr="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x88f4" name="RB_UNKNOWN_88F4" low="0" high="2"/>
+	<!-- Connected to VK_EXT_fragment_density_map? -->
+	<reg32 offset="0x88f5" name="RB_UNKNOWN_88F5" variants="A7XX-"/>
+	<!-- 0x88f6-0x88ff invalid -->
+	<reg64 offset="0x8900" name="RB_DEPTH_FLAG_BUFFER_BASE" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x8902" name="RB_DEPTH_FLAG_BUFFER_PITCH" usage="rp_blit">
+		<bitfield name="PITCH" low="0" high="6" shr="6" type="uint"/>
+		<!-- TODO: actually part of array pitch -->
+		<bitfield name="UNK8" low="8" high="10"/>
+		<bitfield name="ARRAY_PITCH" low="11" high="27" shr="7" type="uint"/>
+	</reg32>
+	<array offset="0x8903" name="RB_MRT_FLAG_BUFFER" stride="3" length="8" usage="rp_blit">
+		<reg64 offset="0" name="ADDR" type="waddress" align="64"/>
+		<reg32 offset="2" name="PITCH">
+			<bitfield name="PITCH" low="0" high="10" shr="6" type="uint"/>
+			<bitfield name="ARRAY_PITCH" low="11" high="28" shr="7" type="uint"/>
+		</reg32>
+	</array>
+	<!-- 0x891b-0x8926 invalid -->
+	<doc>
+		RB_SAMPLE_COUNT_ADDR register is used up to (and including) a730. After that
+		the address is specified through CP_EVENT_WRITE7::WRITE_SAMPLE_COUNT.
+	</doc>
+	<reg64 offset="0x8927" name="RB_SAMPLE_COUNT_ADDR" type="waddress" align="16" usage="cmd"/>
+	<!-- 0x8929-0x89ff invalid -->
+
+	<!-- TODO: there are some registers in the 0x8a00-0x8bff range -->
+
+	<!--
+		These show up in a6xx gen3+ but so far haven't found an example of
+		blob writing non-zero:
+	 -->
+	<reg32 offset="0x8a00" name="RB_UNKNOWN_8A00" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0x8a10" name="RB_UNKNOWN_8A10" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0x8a20" name="RB_UNKNOWN_8A20" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0x8a30" name="RB_UNKNOWN_8A30" variants="A6XX" usage="rp_blit"/>
+
+	<reg32 offset="0x8c00" name="RB_2D_BLIT_CNTL" type="a6xx_2d_blit_cntl" usage="rp_blit"/>
+	<reg32 offset="0x8c01" name="RB_2D_UNKNOWN_8C01" low="0" high="31" usage="rp_blit"/>
+
+	<bitset name="a6xx_2d_src_surf_info" inline="yes">
+		<bitfield name="COLOR_FORMAT" low="0" high="7" type="a6xx_format"/>
+		<bitfield name="TILE_MODE" low="8" high="9" type="a6xx_tile_mode"/>
+		<bitfield name="COLOR_SWAP" low="10" high="11" type="a3xx_color_swap"/>
+		<bitfield name="FLAGS" pos="12" type="boolean"/>
+		<bitfield name="SRGB" pos="13" type="boolean"/>
+		<bitfield name="SAMPLES" low="14" high="15" type="a3xx_msaa_samples"/>
+		<bitfield name="FILTER" pos="16" type="boolean"/>
+		<bitfield name="UNK17" pos="17" type="boolean"/>
+		<bitfield name="SAMPLES_AVERAGE" pos="18" type="boolean"/>
+		<bitfield name="UNK19" pos="19" type="boolean"/>
+		<bitfield name="UNK20" pos="20" type="boolean"/>
+		<bitfield name="UNK21" pos="21" type="boolean"/>
+		<bitfield name="UNK22" pos="22" type="boolean"/>
+		<bitfield name="UNK23" low="23" high="26"/>
+		<bitfield name="UNK28" pos="28" type="boolean"/>
+		<bitfield name="MUTABLEEN" pos="29" type="boolean" variants="A7XX-"/>
+	</bitset>
+
+	<bitset name="a6xx_2d_dst_surf_info" inline="yes">
+		<bitfield name="COLOR_FORMAT" low="0" high="7" type="a6xx_format"/>
+		<bitfield name="TILE_MODE" low="8" high="9" type="a6xx_tile_mode"/>
+		<bitfield name="COLOR_SWAP" low="10" high="11" type="a3xx_color_swap"/>
+		<bitfield name="FLAGS" pos="12" type="boolean"/>
+		<bitfield name="SRGB" pos="13" type="boolean"/>
+		<bitfield name="SAMPLES" low="14" high="15" type="a3xx_msaa_samples"/>
+		<bitfield name="MUTABLEEN" pos="17" type="boolean" variants="A7XX-"/>
+	</bitset>
+
+	<!-- 0x8c02-0x8c16 invalid -->
+	<reg32 offset="0x8c17" name="RB_2D_DST_INFO" type="a6xx_2d_dst_surf_info" usage="rp_blit"/>
+	<reg64 offset="0x8c18" name="RB_2D_DST" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x8c1a" name="RB_2D_DST_PITCH" low="0" high="15" shr="6" type="uint" usage="rp_blit"/>
+	<!-- this is a guess but seems likely (for NV12/IYUV): -->
+	<reg64 offset="0x8c1b" name="RB_2D_DST_PLANE1" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x8c1d" name="RB_2D_DST_PLANE_PITCH" low="0" high="15" shr="6" type="uint" usage="rp_blit"/>
+	<reg64 offset="0x8c1e" name="RB_2D_DST_PLANE2" type="waddress" align="64" usage="rp_blit"/>
+
+	<reg64 offset="0x8c20" name="RB_2D_DST_FLAGS" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x8c22" name="RB_2D_DST_FLAGS_PITCH" low="0" high="7" shr="6" type="uint" usage="rp_blit"/>
+	<!-- this is a guess but seems likely (for NV12 with UBWC): -->
+	<reg64 offset="0x8c23" name="RB_2D_DST_FLAGS_PLANE" type="waddress" align="64" usage="rp_blit"/>
+	<reg32 offset="0x8c25" name="RB_2D_DST_FLAGS_PLANE_PITCH" low="0" high="7" shr="6" type="uint" usage="rp_blit"/>
+
+	<!-- TODO: 0x8c26-0x8c33 are all full 32-bit registers -->
+	<!-- unlike a5xx, these are per channel values rather than packed -->
+	<reg32 offset="0x8c2c" name="RB_2D_SRC_SOLID_C0" usage="rp_blit"/>
+	<reg32 offset="0x8c2d" name="RB_2D_SRC_SOLID_C1" usage="rp_blit"/>
+	<reg32 offset="0x8c2e" name="RB_2D_SRC_SOLID_C2" usage="rp_blit"/>
+	<reg32 offset="0x8c2f" name="RB_2D_SRC_SOLID_C3" usage="rp_blit"/>
+
+	<reg32 offset="0x8c34" name="RB_UNKNOWN_8C34" variants="A7XX-" usage="cmd"/>
+
+	<!-- 0x8c35-0x8dff invalid -->
+
+	<!-- always 0x1 ? either doesn't exist for a650 or write-only: -->
+	<reg32 offset="0x8e01" name="RB_UNKNOWN_8E01" usage="cmd"/>
+	<!-- 0x8e00-0x8e03 invalid -->
+	<reg32 offset="0x8e04" name="RB_DBG_ECO_CNTL" usage="cmd"/> <!-- TODO: valid mask 0xfffffeff -->
+	<reg32 offset="0x8e05" name="RB_ADDR_MODE_CNTL" pos="0" type="a5xx_address_mode"/>
+	<!-- 0x02080000 in GMEM, zero otherwise?  -->
+	<reg32 offset="0x8e06" name="RB_UNKNOWN_8E06" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0x8e07" name="RB_CCU_CNTL" usage="cmd" variants="A6XX">
+		<bitfield name="GMEM_FAST_CLEAR_DISABLE" pos="0" type="boolean"/>
+		<!-- concurrent resolves are apparently a 2-bit enum on a650+ -->
+		<bitfield name="CONCURRENT_RESOLVE" pos="2" type="boolean"/>
+		<bitfield name="DEPTH_OFFSET_HI" pos="7" type="hex"/>
+		<bitfield name="COLOR_OFFSET_HI" pos="9" type="hex"/>
+		<bitfield name="DEPTH_CACHE_SIZE" low="10" high="11" type="a6xx_ccu_cache_size"/>
+		<!-- GMEM offset of CCU depth cache -->
+		<bitfield name="DEPTH_OFFSET" low="12" high="20" shr="12" type="hex"/>
+		<bitfield name="COLOR_CACHE_SIZE" low="21" high="22" type="a6xx_ccu_cache_size"/>
+		<!-- GMEM offset of CCU color cache
+			for GMEM rendering, we set it to GMEM size minus the minimum
+			CCU color cache size. CCU color cache will be needed in some
+			resolve cases, and in those cases we need to reserve the end
+			of GMEM for color cache.
+		-->
+		<bitfield name="COLOR_OFFSET" low="23" high="31" shr="12" type="hex"/>
+		<!--TODO: valid mask 0xfffffc1f -->
+	</reg32>
+	<reg32 offset="0x8e07" name="RB_CCU_CNTL" usage="cmd" variants="A7XX-">
+		<bitfield name="GMEM_FAST_CLEAR_DISABLE" pos="0" type="boolean"/>
+		<bitfield name="CONCURRENT_RESOLVE" pos="2" type="boolean"/>
+		<!-- rest of the bits were moved to RB_CCU_CNTL2 -->
+	</reg32>
+	<reg32 offset="0x8e08" name="RB_NC_MODE_CNTL">
+		<bitfield name="MODE" pos="0" type="boolean"/>
+		<bitfield name="LOWER_BIT" low="1" high="2" type="uint"/>
+		<bitfield name="MIN_ACCESS_LENGTH" pos="3" type="boolean"/> <!-- true=64b false=32b -->
+		<bitfield name="AMSBC" pos="4" type="boolean"/>
+		<bitfield name="UPPER_BIT" pos="10" type="uint"/>
+		<bitfield name="RGB565_PREDICATOR" pos="11" type="boolean"/>
+		<bitfield name="UNK12" low="12" high="13"/>
+	</reg32>
+	<reg32 offset="0x8e09" name="RB_UNKNOWN_8E09" variants="A7XX-" usage="cmd"/>
+	<!-- 0x8e09-0x8e0f invalid -->
+	<array offset="0x8e10" name="RB_PERFCTR_RB_SEL" stride="1" length="8"/>
+	<array offset="0x8e18" name="RB_PERFCTR_CCU_SEL" stride="1" length="5"/>
+	<!-- 0x8e1d-0x8e1f invalid -->
+	<!-- 0x8e20-0x8e25 more perfcntr sel? -->
+	<!-- 0x8e26-0x8e27 invalid -->
+	<reg32 offset="0x8e28" name="RB_CMP_DBG_ECO_CNTL"/>
+	<!-- 0x8e29-0x8e2b invalid -->
+	<array offset="0x8e2c" name="RB_PERFCTR_CMP_SEL" stride="1" length="4"/>
+	<array offset="0x8e30" name="RB_PERFCTR_UFC_SEL" stride="1" length="6" variants="A7XX-"/>
+	<reg32 offset="0x8e3b" name="RB_RB_SUB_BLOCK_SEL_CNTL_HOST"/>
+	<reg32 offset="0x8e3d" name="RB_RB_SUB_BLOCK_SEL_CNTL_CD"/>
+	<!-- 0x8e3e-0x8e4f invalid -->
+	<!-- GMEM save/restore for preemption: -->
+	<reg32 offset="0x8e50" name="RB_CONTEXT_SWITCH_GMEM_SAVE_RESTORE" pos="0" type="boolean"/>
+	<!-- address for GMEM save/restore? -->
+	<reg32 offset="0x8e51" name="RB_UNKNOWN_8E51" type="waddress" align="1"/>
+	<!-- 0x8e53-0x8e7f invalid -->
+	<reg32 offset="0x8e79" name="RB_UNKNOWN_8E79" variants="A7XX-" usage="cmd"/>
+	<!-- 0x8e80-0x8e83 are valid -->
+	<!-- 0x8e84-0x90ff invalid -->
+
+	<!-- 0x9000-0x90ff invalid -->
+
+	<reg32 offset="0x9100" name="VPC_GS_PARAM" variants="A6XX" usage="rp_blit">
+		<bitfield name="LINELENGTHLOC" low="0" high="7" type="uint"/>
+	</reg32>
+
+	<bitset name="a6xx_vpc_xs_clip_cntl" inline="yes">
+		<bitfield name="CLIP_MASK" low="0" high="7" type="uint"/>
+		<!-- there can be up to 8 total clip/cull distance outputs,
+		     but apparenly VPC can only deal with vec4, so when there are
+		     more than 4 outputs a second location needs to be programmed
+		-->
+		<bitfield name="CLIP_DIST_03_LOC" low="8" high="15" type="uint"/>
+		<bitfield name="CLIP_DIST_47_LOC" low="16" high="23" type="uint"/>
+	</bitset>
+	<reg32 offset="0x9101" name="VPC_VS_CLIP_CNTL" type="a6xx_vpc_xs_clip_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9102" name="VPC_GS_CLIP_CNTL" type="a6xx_vpc_xs_clip_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9103" name="VPC_DS_CLIP_CNTL" type="a6xx_vpc_xs_clip_cntl" usage="rp_blit"/>
+
+	<reg32 offset="0x9311" name="VPC_VS_CLIP_CNTL_V2" type="a6xx_vpc_xs_clip_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9312" name="VPC_GS_CLIP_CNTL_V2" type="a6xx_vpc_xs_clip_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9313" name="VPC_DS_CLIP_CNTL_V2" type="a6xx_vpc_xs_clip_cntl" usage="rp_blit"/>
+
+	<bitset name="a6xx_vpc_xs_layer_cntl" inline="yes">
+		<bitfield name="LAYERLOC" low="0" high="7" type="uint"/>
+		<bitfield name="VIEWLOC" low="8" high="15" type="uint"/>
+		<bitfield name="SHADINGRATELOC" low="16" high="23" type="uint" variants="A7XX-"/>
+	</bitset>
+
+	<reg32 offset="0x9104" name="VPC_VS_LAYER_CNTL" type="a6xx_vpc_xs_layer_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9105" name="VPC_GS_LAYER_CNTL" type="a6xx_vpc_xs_layer_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9106" name="VPC_DS_LAYER_CNTL" type="a6xx_vpc_xs_layer_cntl" usage="rp_blit"/>
+
+	<reg32 offset="0x9314" name="VPC_VS_LAYER_CNTL_V2" type="a6xx_vpc_xs_layer_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9315" name="VPC_GS_LAYER_CNTL_V2" type="a6xx_vpc_xs_layer_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9316" name="VPC_DS_LAYER_CNTL_V2" type="a6xx_vpc_xs_layer_cntl" usage="rp_blit"/>
+
+	<reg32 offset="0x9107" name="VPC_UNKNOWN_9107" variants="A6XX" usage="rp_blit">
+		<!-- this mirrors PC_RASTER_CNTL::DISCARD, although it seems it's unused -->
+		<bitfield name="RASTER_DISCARD" pos="0" type="boolean"/>
+		<bitfield name="UNK2" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x9108" name="VPC_POLYGON_MODE" usage="rp_blit">
+		<bitfield name="MODE" low="0" high="1" type="a6xx_polygon_mode"/>
+	</reg32>
+
+	<bitset name="a6xx_primitive_cntl_0" inline="yes">
+		<bitfield name="PRIMITIVE_RESTART" pos="0" type="boolean"/>
+		<bitfield name="PROVOKING_VTX_LAST" pos="1" type="boolean"/>
+		<bitfield name="D3D_VERTEX_ORDERING" pos="2" type="boolean">
+			<doc>
+				Swaps TESS_CW_TRIS/TESS_CCW_TRIS, and also makes
+				triangle fans and triangle strips use the D3D
+				order instead of the OpenGL order.
+			</doc>
+		</bitfield>
+		<bitfield name="UNK3" pos="3" type="boolean"/>
+	</bitset>
+
+	<bitset name="a6xx_primitive_cntl_5" inline="yes">
+		<doc>
+		  geometry shader
+		</doc>
+		<!-- TODO: first 16 bits are valid so something is wrong or missing here -->
+		<bitfield name="GS_VERTICES_OUT" low="0" high="7" type="uint"/>
+		<bitfield name="GS_INVOCATIONS" low="10" high="14" type="uint"/>
+		<bitfield name="LINELENGTHEN" pos="15" type="boolean"/>
+		<bitfield name="GS_OUTPUT" low="16" high="17" type="a6xx_tess_output"/>
+		<bitfield name="UNK18" pos="18"/>
+	</bitset>
+
+	<bitset name="a6xx_multiview_cntl" inline="yes">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="DISABLEMULTIPOS" pos="1" type="boolean">
+			<doc>
+				Multi-position output lets the last geometry
+				stage shader write multiple copies of
+				gl_Position. If disabled then the VS is run once
+				for each view, and ViewID is passed as a
+				register to the VS.
+			</doc>
+		</bitfield>
+		<bitfield name="VIEWS" low="2" high="6" type="uint"/>
+	</bitset>
+
+	<reg32 offset="0x9109" name="VPC_PRIMITIVE_CNTL_0" type="a6xx_primitive_cntl_0" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0x910a" name="VPC_PRIMITIVE_CNTL_5" type="a6xx_primitive_cntl_5" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0x910b" name="VPC_MULTIVIEW_MASK" type="hex" low="0" high="15" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0x910c" name="VPC_MULTIVIEW_CNTL" type="a6xx_multiview_cntl" variants="A7XX-" usage="rp_blit"/>
+
+	<enum name="a6xx_varying_interp_mode">
+		<value value="0" name="INTERP_SMOOTH"/>
+		<value value="1" name="INTERP_FLAT"/>
+		<value value="2" name="INTERP_ZERO"/>
+		<value value="3" name="INTERP_ONE"/>
+	</enum>
+
+	<enum name="a6xx_varying_ps_repl_mode">
+		<value value="0" name="PS_REPL_NONE"/>
+		<value value="1" name="PS_REPL_S"/>
+		<value value="2" name="PS_REPL_T"/>
+		<value value="3" name="PS_REPL_ONE_MINUS_T"/>
+	</enum>
+
+	<!-- 0x9109-0x91ff invalid -->
+	<array offset="0x9200" name="VPC_VARYING_INTERP" stride="1" length="8" usage="rp_blit">
+		<doc>Packed array of a6xx_varying_interp_mode</doc>
+		<reg32 offset="0x0" name="MODE"/>
+	</array>
+	<array offset="0x9208" name="VPC_VARYING_PS_REPL" stride="1" length="8" usage="rp_blit">
+		<doc>Packed array of a6xx_varying_ps_repl_mode</doc>
+		<reg32 offset="0x0" name="MODE"/>
+	</array>
+
+	<!-- always 0x0 -->
+	<reg32 offset="0x9210" name="VPC_UNKNOWN_9210" low="0" high="31" variants="A6XX" usage="cmd"/>
+	<reg32 offset="0x9211" name="VPC_UNKNOWN_9211" low="0" high="31" variants="A6XX" usage="cmd"/>
+
+	<array offset="0x9212" name="VPC_VAR" stride="1" length="4" usage="rp_blit">
+		<!-- one bit per varying component: -->
+		<reg32 offset="0" name="DISABLE"/>
+	</array>
+
+	<reg32 offset="0x9216" name="VPC_SO_CNTL" usage="rp_blit">
+		<!--
+			Choose which DWORD to write to. There is an array of
+			(4 * 64) DWORD's, dumped in the devcoredump at
+			HLSQ_INST_RAM dword 0x400. Each DWORD corresponds to a
+			(VPC location, stream) pair like so:
+
+			location 0, stream 0
+			location 2, stream 0
+			...
+			location 126, stream 0
+			location 0, stream 1
+			location 2, stream 1
+			...
+			location 126, stream 1
+			location 0, stream 2
+			...
+
+			When EmitStreamVertex(N) happens, the HW goes to DWORD
+			64 * N and then "executes" the next 64 DWORD's.
+
+			This field is auto-incremented when VPC_SO_PROG is
+			written to.
+		-->
+		<bitfield name="ADDR" low="0" high="7" type="hex"/>
+		<!-- clear all A_EN and B_EN bits for all DWORD's -->
+		<bitfield name="RESET" pos="16" type="boolean"/>
+	</reg32>
+	<!-- special register, write multiple times to load SO program (not readable) -->
+	<reg32 offset="0x9217" name="VPC_SO_PROG" usage="rp_blit">
+		<bitfield name="A_BUF" low="0" high="1" type="uint"/>
+		<bitfield name="A_OFF" low="2" high="10" shr="2" type="uint"/>
+		<bitfield name="A_EN" pos="11" type="boolean"/>
+		<bitfield name="B_BUF" low="12" high="13" type="uint"/>
+		<bitfield name="B_OFF" low="14" high="22" shr="2" type="uint"/>
+		<bitfield name="B_EN" pos="23" type="boolean"/>
+	</reg32>
+
+	<reg64 offset="0x9218" name="VPC_SO_STREAM_COUNTS" type="waddress" align="32" usage="cmd"/>
+
+	<array offset="0x921a" name="VPC_SO" stride="7" length="4" usage="cmd">
+		<reg64 offset="0" name="BUFFER_BASE" type="waddress" align="32"/>
+		<reg32 offset="2" name="BUFFER_SIZE" low="2" high="31" shr="2"/>
+		<reg32 offset="3" name="BUFFER_STRIDE" low="0" high="9" shr="2"/>
+		<reg32 offset="4" name="BUFFER_OFFSET" low="2" high="31" shr="2"/>
+		<reg64 offset="5" name="FLUSH_BASE" type="waddress" align="32"/>
+	</array>
+
+	<reg32 offset="0x9236" name="VPC_POINT_COORD_INVERT" usage="cmd">
+		<bitfield name="INVERT" pos="0" type="boolean"/>
+	</reg32>
+	<!-- 0x9237-0x92ff invalid -->
+	<!-- always 0x0 ? -->
+	<reg32 offset="0x9300" name="VPC_UNKNOWN_9300" low="0" high="2" usage="cmd"/>
+
+	<bitset name="a6xx_vpc_xs_pack" inline="yes">
+		<doc>
+			num of varyings plus four for gl_Position (plus one if gl_PointSize)
+			plus # of transform-feedback (streamout) varyings if using the
+			hw streamout (rather than stg instructions in shader)
+		</doc>
+		<bitfield name="STRIDE_IN_VPC" low="0" high="7" type="uint"/>
+		<bitfield name="POSITIONLOC" low="8" high="15" type="uint"/>
+		<bitfield name="PSIZELOC" low="16" high="23" type="uint"/>
+		<bitfield name="EXTRAPOS" low="24" high="27" type="uint">
+			<doc>
+				The number of extra copies of POSITION, i.e.
+				number of views minus one when multi-position
+				output is enabled, otherwise 0.
+			</doc>
+		</bitfield>
+	</bitset>
+	<reg32 offset="0x9301" name="VPC_VS_PACK" type="a6xx_vpc_xs_pack" usage="rp_blit"/>
+	<reg32 offset="0x9302" name="VPC_GS_PACK" type="a6xx_vpc_xs_pack" usage="rp_blit"/>
+	<reg32 offset="0x9303" name="VPC_DS_PACK" type="a6xx_vpc_xs_pack" usage="rp_blit"/>
+
+	<reg32 offset="0x9304" name="VPC_CNTL_0" usage="rp_blit">
+		<bitfield name="NUMNONPOSVAR" low="0" high="7" type="uint"/>
+		<!-- for fixed-function (i.e. no GS) gl_PrimitiveID in FS -->
+		<bitfield name="PRIMIDLOC" low="8" high="15" type="uint"/>
+		<bitfield name="VARYING" pos="16" type="boolean"/>
+		<bitfield name="VIEWIDLOC" low="24" high="31" type="uint">
+			<doc>
+				This VPC location will be overwritten with
+				ViewID when multiview is enabled. It's used when
+				fragment shaders read ViewID. It's only
+				strictly required for multi-position output,
+				where the same VS invocation is used for all the
+				views at once, but it can be used when multi-pos
+				output is disabled too, to avoid having to pass
+				ViewID through the VS.
+			</doc>
+		</bitfield>
+	</reg32>
+
+	<reg32 offset="0x9305" name="VPC_SO_STREAM_CNTL" usage="rp_blit">
+		<!--
+		It's offset by 1, and 0 means "disabled"
+		-->
+		<bitfield name="BUF0_STREAM" low="0" high="2" type="uint"/>
+		<bitfield name="BUF1_STREAM" low="3" high="5" type="uint"/>
+		<bitfield name="BUF2_STREAM" low="6" high="8" type="uint"/>
+		<bitfield name="BUF3_STREAM" low="9" high="11" type="uint"/>
+		<bitfield name="STREAM_ENABLE" low="15" high="18" type="hex"/>
+	</reg32>
+	<reg32 offset="0x9306" name="VPC_SO_DISABLE" usage="rp_blit">
+		<bitfield name="DISABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x9307" name="VPC_POLYGON_MODE2" variants="A7XX-" usage="rp_blit">
+		<bitfield name="MODE" low="0" high="1" type="a6xx_polygon_mode"/>
+	</reg32>
+	<reg32 offset="0x9308" name="VPC_ATTR_BUF_SIZE_GMEM" variants="A7XX-" usage="rp_blit">
+		<bitfield name="SIZE_GMEM" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="0x9309" name="VPC_ATTR_BUF_BASE_GMEM" variants="A7XX-" usage="rp_blit">
+		<bitfield name="BASE_GMEM" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="0x9b09" name="PC_ATTR_BUF_SIZE_GMEM" variants="A7XX-" usage="rp_blit">
+		<bitfield name="SIZE_GMEM" low="0" high="31"/>
+	</reg32>
+
+	<!-- 0x9307-0x95ff invalid -->
+
+	<!-- TODO: 0x9600-0x97ff range -->
+	<reg32 offset="0x9600" name="VPC_DBG_ECO_CNTL" usage="cmd"/> <!-- always 0x0 ? TODO: 0x1fbf37ff valid mask -->
+	<reg32 offset="0x9601" name="VPC_ADDR_MODE_CNTL" pos="0" type="a5xx_address_mode" usage="cmd"/>
+	<reg32 offset="0x9602" name="VPC_UNKNOWN_9602" pos="0" usage="cmd"/> <!-- always 0x0 ? -->
+	<reg32 offset="0x9603" name="VPC_UNKNOWN_9603" low="0" high="26"/>
+	<array offset="0x9604" name="VPC_PERFCTR_VPC_SEL" stride="1" length="6" variants="A6XX"/>
+	<array offset="0x960b" name="VPC_PERFCTR_VPC_SEL" stride="1" length="12" variants="A7XX-"/>
+	<!-- 0x960a-0x9623 invalid -->
+	<!-- TODO: regs from 0x9624-0x963a -->
+	<!-- 0x963b-0x97ff invalid -->
+
+	<reg32 offset="0x9800" name="PC_TESS_NUM_VERTEX" low="0" high="5" type="uint" usage="rp_blit"/>
+
+	<!-- always 0x0 ? -->
+	<reg32 offset="0x9801" name="PC_HS_INPUT_SIZE" usage="rp_blit">
+		<bitfield name="SIZE" low="0" high="10" type="uint"/>
+		<bitfield name="UNK13" pos="13"/>
+	</reg32>
+
+	<reg32 offset="0x9802" name="PC_TESS_CNTL" usage="rp_blit">
+		<bitfield name="SPACING" low="0" high="1" type="a6xx_tess_spacing"/>
+		<bitfield name="OUTPUT" low="2" high="3" type="a6xx_tess_output"/>
+	</reg32>
+
+	<reg32 offset="0x9803" name="PC_RESTART_INDEX" low="0" high="31" type="uint" usage="rp_blit"/>
+	<reg32 offset="0x9804" name="PC_MODE_CNTL" low="0" high="7" usage="rp_blit"/>
+
+	<reg32 offset="0x9805" name="PC_POWER_CNTL" low="0" high="2" usage="rp_blit"/>
+
+	<reg32 offset="0x9806" name="PC_PS_CNTL" usage="rp_blit">
+		<bitfield name="PRIMITIVEIDEN" pos="0" type="boolean"/>
+	</reg32>
+
+	<!-- New in a6xx gen3+ -->
+	<reg32 offset="0x9808" name="PC_SO_STREAM_CNTL" usage="rp_blit">
+		<bitfield name="STREAM_ENABLE" low="15" high="18" type="hex"/>
+	</reg32>
+
+	<reg32 offset="0x980a" name="PC_DGEN_SU_CONSERVATIVE_RAS_CNTL">
+		<bitfield name="CONSERVATIVERASEN" pos="0" type="boolean"/>
+	</reg32>
+	<!-- 0x980b-0x983f invalid -->
+
+	<!-- 0x9840 - 0x9842 are not readable -->
+	<reg32 offset="0x9840" name="PC_DRAW_CMD">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+
+	<reg32 offset="0x9841" name="PC_DISPATCH_CMD">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+
+	<reg32 offset="0x9842" name="PC_EVENT_CMD">
+		<!-- I think only the low bit is actually used? -->
+		<bitfield name="STATE_ID" low="16" high="23"/>
+		<bitfield name="EVENT" low="0" high="6" type="vgt_event_type"/>
+	</reg32>
+
+	<!--
+		0x9880 written in a lot of places by SQE, same value gets written
+		to control reg 0x12a.  Set by CP_SET_MARKER, so lets name it after
+		that
+	 -->
+	<reg32 offset="0x9880" name="PC_MARKER"/>
+
+	<!-- 0x9843-0x997f invalid -->
+
+	<reg32 offset="0x9981" name="PC_POLYGON_MODE" variants="A6XX" usage="rp_blit">
+		<bitfield name="MODE" low="0" high="1" type="a6xx_polygon_mode"/>
+	</reg32>
+	<reg32 offset="0x9809" name="PC_POLYGON_MODE" variants="A7XX-" usage="rp_blit">
+		<bitfield name="MODE" low="0" high="1" type="a6xx_polygon_mode"/>
+	</reg32>
+
+	<reg32 offset="0x9980" name="PC_RASTER_CNTL" variants="A6XX" usage="rp_blit">
+		<!-- which stream to send to GRAS -->
+		<bitfield name="STREAM" low="0" high="1" type="uint"/>
+		<!-- discard primitives before rasterization -->
+		<bitfield name="DISCARD" pos="2" type="boolean"/>
+	</reg32>
+	<!-- VPC_RASTER_CNTL -->
+	<reg32 offset="0x9107" name="PC_RASTER_CNTL" variants="A7XX-" usage="rp_blit">
+		<!-- which stream to send to GRAS -->
+		<bitfield name="STREAM" low="0" high="1" type="uint"/>
+		<!-- discard primitives before rasterization -->
+		<bitfield name="DISCARD" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x9317" name="PC_RASTER_CNTL_V2" variants="A7XX-" usage="rp_blit">
+		<!-- which stream to send to GRAS -->
+		<bitfield name="STREAM" low="0" high="1" type="uint"/>
+		<!-- discard primitives before rasterization -->
+		<bitfield name="DISCARD" pos="2" type="boolean"/>
+	</reg32>
+
+	<!-- Both are a750+.
+	     Probably needed to correctly overlap execution of several draws.
+	-->
+	<reg32 offset="0x9885" name="PC_TESS_PARAM_SIZE" variants="A7XX-" usage="cmd"/>
+	<!-- Blob adds a bit more space {0x10, 0x20, 0x30, 0x40} bytes, but the meaning of
+	     this additional space is not known.
+	-->
+	<reg32 offset="0x9886" name="PC_TESS_FACTOR_SIZE" variants="A7XX-" usage="cmd"/>
+
+	<!-- 0x9982-0x9aff invalid -->
+
+	<reg32 offset="0x9b00" name="PC_PRIMITIVE_CNTL_0" type="a6xx_primitive_cntl_0" usage="rp_blit"/>
+
+	<bitset name="a6xx_xs_out_cntl" inline="yes">
+		<doc>
+			num of varyings plus four for gl_Position (plus one if gl_PointSize)
+			plus # of transform-feedback (streamout) varyings if using the
+			hw streamout (rather than stg instructions in shader)
+		</doc>
+		<bitfield name="STRIDE_IN_VPC" low="0" high="7" type="uint"/>
+		<bitfield name="PSIZE" pos="8" type="boolean"/>
+		<bitfield name="LAYER" pos="9" type="boolean"/>
+		<bitfield name="VIEW" pos="10" type="boolean"/>
+		<!-- note: PC_VS_OUT_CNTL doesn't have the PRIMITIVE_ID bit -->
+		<bitfield name="PRIMITIVE_ID" pos="11" type="boolean"/>
+		<bitfield name="CLIP_MASK" low="16" high="23" type="uint"/>
+		<bitfield name="SHADINGRATE" pos="24" type="boolean" variants="A7XX-"/>
+	</bitset>
+
+	<reg32 offset="0x9b01" name="PC_VS_OUT_CNTL" type="a6xx_xs_out_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9b02" name="PC_GS_OUT_CNTL" type="a6xx_xs_out_cntl" usage="rp_blit"/>
+	<!-- since HS can't output anything, only PRIMITIVE_ID is valid -->
+	<reg32 offset="0x9b03" name="PC_HS_OUT_CNTL" type="a6xx_xs_out_cntl" usage="rp_blit"/>
+	<reg32 offset="0x9b04" name="PC_DS_OUT_CNTL" type="a6xx_xs_out_cntl" usage="rp_blit"/>
+
+	<reg32 offset="0x9b05" name="PC_PRIMITIVE_CNTL_5" type="a6xx_primitive_cntl_5" usage="rp_blit"/>
+
+	<reg32 offset="0x9b06" name="PC_PRIMITIVE_CNTL_6" variants="A6XX" usage="rp_blit">
+		<doc>
+		  size in vec4s of per-primitive storage for gs. TODO: not actually in VPC
+		</doc>
+		<bitfield name="STRIDE_IN_VPC" low="0" high="10" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x9b07" name="PC_MULTIVIEW_CNTL" type="a6xx_multiview_cntl" usage="rp_blit"/>
+	<!-- mask of enabled views, doesn't exist on A630 -->
+	<reg32 offset="0x9b08" name="PC_MULTIVIEW_MASK" type="hex" low="0" high="15" usage="rp_blit"/>
+	<!-- 0x9b09-0x9bff invalid -->
+	<reg32 offset="0x9c00" name="PC_2D_EVENT_CMD">
+		<!-- special register (but note first 8 bits can be written/read) -->
+		<bitfield name="EVENT" low="0" high="6" type="vgt_event_type"/>
+		<bitfield name="STATE_ID" low="8" high="15"/>
+	</reg32>
+	<!-- 0x9c01-0x9dff invalid -->
+	<!-- TODO: 0x9e00-0xa000 range incomplete -->
+	<reg32 offset="0x9e00" name="PC_DBG_ECO_CNTL"/>
+	<reg32 offset="0x9e01" name="PC_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg64 offset="0x9e04" name="PC_DRAW_INDX_BASE"/>
+	<reg32 offset="0x9e06" name="PC_DRAW_FIRST_INDX" type="uint"/>
+	<reg32 offset="0x9e07" name="PC_DRAW_MAX_INDICES" type="uint"/>
+	<reg64 offset="0x9e08" name="PC_TESSFACTOR_ADDR" variants="A6XX" type="waddress" align="32" usage="cmd"/>
+	<reg64 offset="0x9810" name="PC_TESSFACTOR_ADDR" variants="A7XX-" type="waddress" align="32" usage="cmd"/>
+
+	<reg32 offset="0x9e0b" name="PC_DRAW_INITIATOR" type="vgt_draw_initiator_a4xx">
+		<doc>
+			Possibly not really "initiating" the draw but the layout is similar
+			to VGT_DRAW_INITIATOR on older gens
+		</doc>
+	</reg32>
+	<reg32 offset="0x9e0c" name="PC_DRAW_NUM_INSTANCES" type="uint"/>
+	<reg32 offset="0x9e0d" name="PC_DRAW_NUM_INDICES" type="uint"/>
+
+	<!-- These match the contents of CP_SET_BIN_DATA (not written directly) -->
+	<reg32 offset="0x9e11" name="PC_VSTREAM_CONTROL">
+		<bitfield name="UNK0" low="0" high="15"/>
+		<bitfield name="VSC_SIZE" low="16" high="21" type="uint"/>
+		<bitfield name="VSC_N" low="22" high="26" type="uint"/>
+	</reg32>
+	<reg64 offset="0x9e12" name="PC_BIN_PRIM_STRM" type="waddress" align="32"/>
+	<reg64 offset="0x9e14" name="PC_BIN_DRAW_STRM" type="waddress" align="32"/>
+
+	<reg32 offset="0x9e1c" name="PC_VISIBILITY_OVERRIDE">
+		<doc>Written by CP_SET_VISIBILITY_OVERRIDE handler</doc>
+		<bitfield name="OVERRIDE" pos="0" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x9e24" name="PC_UNKNOWN_9E24" variants="A7XX-" usage="cmd"/>
+
+	<array offset="0x9e34" name="PC_PERFCTR_PC_SEL" stride="1" length="8" variants="A6XX"/>
+	<array offset="0x9e42" name="PC_PERFCTR_PC_SEL" stride="1" length="16" variants="A7XX-"/>
+
+	<!-- always 0x0 -->
+	<reg32 offset="0x9e72" name="PC_UNKNOWN_9E72" usage="cmd"/>
+
+	<reg32 offset="0xa000" name="VFD_CONTROL_0" usage="rp_blit">
+		<bitfield name="FETCH_CNT" low="0" high="5" type="uint"/>
+		<bitfield name="DECODE_CNT" low="8" high="13" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa001" name="VFD_CONTROL_1" usage="rp_blit">
+		<bitfield name="REGID4VTX" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="REGID4INST" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="REGID4PRIMID" low="16" high="23" type="a3xx_regid"/>
+		<!-- only used for VS in non-multi-position-output case -->
+		<bitfield name="REGID4VIEWID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xa002" name="VFD_CONTROL_2" usage="rp_blit">
+		<bitfield name="REGID_HSRELPATCHID" low="0" high="7" type="a3xx_regid">
+			<doc>
+				This is the ID of the current patch within the
+				subdraw, used to calculate the offset of the
+				patch within the HS->DS buffers. When a draw is
+				split into multiple subdraws then this differs
+				from gl_PrimitiveID on the second, third, etc.
+				subdraws.
+			</doc>
+		</bitfield>
+		<bitfield name="REGID_INVOCATIONID" low="8" high="15" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xa003" name="VFD_CONTROL_3" usage="rp_blit">
+		<bitfield name="REGID_DSPRIMID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="REGID_DSRELPATCHID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="REGID_TESSX" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="REGID_TESSY" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xa004" name="VFD_CONTROL_4" usage="rp_blit">
+		<bitfield name="UNK0" low="0" high="7" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xa005" name="VFD_CONTROL_5" usage="rp_blit">
+		<bitfield name="REGID_GSHEADER" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="UNK8" low="8" high="15" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xa006" name="VFD_CONTROL_6" usage="rp_blit">
+		<!--
+			True if gl_PrimitiveID is read via the FS
+		-->
+		<bitfield name="PRIMID4PSEN" pos="0" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0xa007" name="VFD_MODE_CNTL" usage="cmd">
+		<bitfield name="RENDER_MODE" low="0" high="2" type="a6xx_render_mode"/>
+	</reg32>
+
+	<reg32 offset="0xa008" name="VFD_MULTIVIEW_CNTL" type="a6xx_multiview_cntl" usage="rp_blit"/>
+	<reg32 offset="0xa009" name="VFD_ADD_OFFSET" usage="cmd">
+		<!-- add VFD_INDEX_OFFSET to REGID4VTX -->
+		<bitfield name="VERTEX" pos="0" type="boolean"/>
+		<!-- add VFD_INSTANCE_START_OFFSET to REGID4INST -->
+		<bitfield name="INSTANCE" pos="1" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0xa00e" name="VFD_INDEX_OFFSET" usage="rp_blit"/>
+	<reg32 offset="0xa00f" name="VFD_INSTANCE_START_OFFSET" usage="rp_blit"/>
+	<array offset="0xa010" name="VFD_FETCH" stride="4" length="32" usage="rp_blit">
+		<reg64 offset="0x0" name="BASE" type="address" align="1"/>
+		<reg32 offset="0x2" name="SIZE" type="uint"/>
+		<reg32 offset="0x3" name="STRIDE" low="0" high="11" type="uint"/>
+	</array>
+	<array offset="0xa090" name="VFD_DECODE" stride="2" length="32" usage="rp_blit">
+		<reg32 offset="0x0" name="INSTR">
+			<!-- IDX and byte OFFSET into VFD_FETCH -->
+			<bitfield name="IDX" low="0" high="4" type="uint"/>
+			<bitfield name="OFFSET" low="5" high="16"/>
+			<bitfield name="INSTANCED" pos="17" type="boolean"/>
+			<bitfield name="FORMAT" low="20" high="27" type="a6xx_format"/>
+			<bitfield name="SWAP" low="28" high="29" type="a3xx_color_swap"/>
+			<bitfield name="UNK30" pos="30" type="boolean"/>
+			<bitfield name="FLOAT" pos="31" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x1" name="STEP_RATE" type="uint"/>
+	</array>
+	<array offset="0xa0d0" name="VFD_DEST_CNTL" stride="1" length="32" usage="rp_blit">
+		<reg32 offset="0x0" name="INSTR">
+			<bitfield name="WRITEMASK" low="0" high="3" type="hex"/>
+			<bitfield name="REGID" low="4" high="11" type="a3xx_regid"/>
+		</reg32>
+	</array>
+
+	<reg32 offset="0xa0f8" name="VFD_POWER_CNTL" low="0" high="2" usage="rp_blit"/>
+
+	<reg32 offset="0xa600" name="VFD_UNKNOWN_A600" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xa601" name="VFD_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<array offset="0xa610" name="VFD_PERFCTR_VFD_SEL" stride="1" length="8" variants="A6XX"/>
+	<array offset="0xa610" name="VFD_PERFCTR_VFD_SEL" stride="1" length="16" variants="A7XX-"/>
+
+	<!--
+	Note: this seems to always be paired with another bit in another
+	block.
+	-->
+	<enum name="a6xx_threadsize">
+		<value value="0" name="THREAD64"/>
+		<value value="1" name="THREAD128"/>
+	</enum>
+
+	<bitset name="a6xx_sp_xs_ctrl_reg0" inline="yes">
+		<!-- if set to SINGLE, only use 1 concurrent wave on each SP -->
+		<bitfield name="THREADMODE" pos="0" type="a3xx_threadmode"/>
+		<!--
+		When b31 set we just see FULLREGFOOTPRINT set.  The pattern of
+		used registers is a bit odd too:
+			- used (half): 0-15 68-179 (cnt=128, max=179)
+			- used (full): 0-33 50-69 71 73 75 77 79 81 83 85 87 89-105 107 109 111 113 115 117 119 121 123 125 127>
+		whereas we usually see a (mostly) contiguous range of regs used.  But if
+		I merge the full and half ranges (ie. rN counts as hr(N*2) and hr(N*2+1)),
+		then:
+			- used (merged): 0-191 (cnt=192, max=191)
+		So I think if b31 is set, then the half precision registers overlap
+		the full precision registers.  (Which seems like a pretty sensible
+		feature, actually I'm not sure when you *wouldn't* want to use that,
+		since it gives register allocation more flexibility)
+		 -->
+		<bitfield name="HALFREGFOOTPRINT" low="1" high="6" type="uint"/>
+		<bitfield name="FULLREGFOOTPRINT" low="7" high="12" type="uint"/>
+		<!-- could it be a low bit of branchstack? -->
+		<bitfield name="UNK13" pos="13" type="boolean"/>
+		<!-- seems to be nesting level for flow control:.. -->
+		<bitfield name="BRANCHSTACK" low="14" high="19" type="uint"/>
+	</bitset>
+
+	<bitset name="a6xx_sp_xs_config" inline="yes">
+		<!--
+		Each of these are set if the given resource type is used
+		with the Vulkan/bindless binding model.
+		-->
+		<bitfield name="BINDLESS_TEX" pos="0" type="boolean"/>
+		<bitfield name="BINDLESS_SAMP" pos="1" type="boolean"/>
+		<bitfield name="BINDLESS_IBO" pos="2" type="boolean"/>
+		<bitfield name="BINDLESS_UBO" pos="3" type="boolean"/>
+
+		<bitfield name="ENABLED" pos="8" type="boolean"/>
+		<!--
+		number of textures and samplers.. these might be swapped, with GL I
+		always see the same value for both.
+		 -->
+		<bitfield name="NTEX" low="9" high="16" type="uint"/>
+		<bitfield name="NSAMP" low="17" high="21" type="uint"/>
+		<bitfield name="NIBO" low="22" high="28" type="uint"/>
+	</bitset>
+
+	<bitset name="a6xx_sp_xs_prim_cntl" inline="yes">
+		<!-- # of VS outputs including pos/psize -->
+		<bitfield name="OUT" low="0" high="5" type="uint"/>
+		<!-- FLAGS_REGID only for GS -->
+		<bitfield name="FLAGS_REGID" low="6" high="13" type="a3xx_regid"/>
+	</bitset>
+
+	<reg32 offset="0xa800" name="SP_VS_CTRL_REG0" type="a6xx_sp_xs_ctrl_reg0" usage="rp_blit">
+		<!--
+		This field actually controls all geometry stages. TCS, TES, and
+		GS must have the same mergedregs setting as VS.
+		-->
+		<bitfield name="MERGEDREGS" pos="20" type="boolean"/>
+		<!--
+		Creates a separate preamble-only thread?
+
+		Early preamble has the following limitations:
+		- Only shared, a1, and consts regs could be used
+		  (accessing other regs would result in GPU fault);
+		- No cat5/cat6, only stc/ldc variants are working;
+		- Values writen to shared regs are not accessible by the rest
+		  of the shader;
+		- Instructions before shps are also considered to be a part of
+		  early preamble;
+
+		Note, for all shaders from d3d11 games blob produced preambles
+		compatible with early preamble mode.
+		-->
+		<bitfield name="EARLYPREAMBLE" pos="21" type="boolean"/>
+	</reg32>
+	<!-- bitmask of true/false conditions for VS brac.N instructions,
+	     bit N corresponds to brac.N -->
+	<reg32 offset="0xa801" name="SP_VS_BRANCH_COND" type="hex"/>
+	<!-- # of VS outputs including pos/psize -->
+	<reg32 offset="0xa802" name="SP_VS_PRIMITIVE_CNTL" type="a6xx_sp_xs_prim_cntl" usage="rp_blit"/>
+	<array offset="0xa803" name="SP_VS_OUT" stride="1" length="16" usage="rp_blit">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="A_COMPMASK" low="8" high="11" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="23" type="a3xx_regid"/>
+			<bitfield name="B_COMPMASK" low="24" high="27" type="hex"/>
+		</reg32>
+	</array>
+	<!--
+	Starting with a5xx, position/psize outputs from shader end up in the
+	SP_VS_OUT map, with highest OUTLOCn position.  (Generally they are
+	the last entries too, except when gl_PointCoord is used, blob inserts
+	an extra varying after, but with a lower OUTLOC position.  If present,
+	psize is last, preceded by position.
+	 -->
+	<array offset="0xa813" name="SP_VS_VPC_DST" stride="1" length="8" usage="rp_blit">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="OUTLOC0" low="0" high="7" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="15" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="23" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="31" type="uint"/>
+		</reg32>
+	</array>
+
+	<bitset name="a6xx_sp_xs_pvt_mem_param" inline="yes">
+		<bitfield name="MEMSIZEPERITEM" low="0" high="7" shr="9">
+			<doc>The size of memory that ldp/stp can address.</doc>
+		</bitfield>
+		<bitfield name="HWSTACKSIZEPERTHREAD" low="24" high="31">
+                        <doc>
+				Seems to be the same as a3xx. The maximum stack
+				size in units of 4 calls, so a call depth of 7
+				would result in a value of 2.
+				TODO: What's the actual size per call, i.e. the
+				size of the PC? a3xx docs say it's 16 bits
+				there, but the length register now takes 28 bits
+				so it's probably been bumped to 32 bits.
+                        </doc>
+		</bitfield>
+	</bitset>
+
+	<bitset name="a6xx_sp_xs_pvt_mem_size" inline="yes">
+		<bitfield name="TOTALPVTMEMSIZE" low="0" high="17" shr="12"/>
+		<bitfield name="PERWAVEMEMLAYOUT" pos="31" type="boolean">
+			<doc>
+				There are four indices used to compute the
+				private memory location for an access:
+
+				- stp/ldp offset
+				- fiber id
+				- wavefront id (a swizzled version of what "getwid" returns)
+				- SP ID (the same as what "getspid" returns)
+
+				The stride for the SP ID is always set by
+				TOTALPVTMEMSIZE. In the per-wave layout, the
+				indices are used in this order:
+
+				- offset % 4 (offset within dword)
+				- fiber id
+				- offset / 4
+				- wavefront id
+				- SP ID
+
+				and the stride for the wavefront ID is
+				MEMSIZEPERITEM, multiplied by 128 (fibers per
+				wavefront). In the per-fiber layout, the indices
+				are used in this order:
+
+				- offset
+				- fiber id % 4
+				- wavefront id
+				- fiber id / 4
+				- SP ID
+
+				and the stride for the fiber id/wavefront id
+				combo is MEMSIZEPERITEM.
+
+				Note: Accesses of more than 1 dword do not work
+				with per-fiber layout. The blob will fall back
+				to per-wave instead.
+			</doc>
+		</bitfield>
+	</bitset>
+
+	<bitset name="a6xx_sp_xs_pvt_mem_hw_stack_offset" inline="yes">
+		<doc>
+			This seems to be be the equivalent of HWSTACKOFFSET in
+			a3xx. The ldp/stp offset formula above isn't affected by
+			HWSTACKSIZEPERTHREAD at all, so the HW return address
+			stack seems to be after all the normal per-SP private
+			memory.
+		</doc>
+		<bitfield name="OFFSET" low="0" high="18" shr="11"/>
+	</bitset>
+
+	<reg32 offset="0xa81b" name="SP_VS_OBJ_FIRST_EXEC_OFFSET" type="uint" usage="rp_blit"/>
+	<reg64 offset="0xa81c" name="SP_VS_OBJ_START" type="address" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa81e" name="SP_VS_PVT_MEM_PARAM" type="a6xx_sp_xs_pvt_mem_param" usage="rp_blit"/>
+	<reg64 offset="0xa81f" name="SP_VS_PVT_MEM_ADDR" type="waddress" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa821" name="SP_VS_PVT_MEM_SIZE" type="a6xx_sp_xs_pvt_mem_size" usage="rp_blit"/>
+	<reg32 offset="0xa822" name="SP_VS_TEX_COUNT" low="0" high="7" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa823" name="SP_VS_CONFIG" type="a6xx_sp_xs_config" usage="rp_blit"/>
+	<reg32 offset="0xa824" name="SP_VS_INSTRLEN" low="0" high="27" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa825" name="SP_VS_PVT_MEM_HW_STACK_OFFSET" type="a6xx_sp_xs_pvt_mem_hw_stack_offset" usage="rp_blit"/>
+	<reg32 offset="0xa82d" name="SP_VS_VGPR_CONFIG" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xa830" name="SP_HS_CTRL_REG0" type="a6xx_sp_xs_ctrl_reg0" usage="rp_blit">
+		<!-- There is no mergedregs bit, that comes from the VS. -->
+		<bitfield name="EARLYPREAMBLE" pos="20" type="boolean"/>
+	</reg32>
+	<!--
+	Total size of local storage in dwords divided by the wave size.
+	The maximum value is 64. With the wave size being always 64 for HS,
+	the maximum size of local storage should be:
+	 64 (wavesize) * 64 (SP_HS_WAVE_INPUT_SIZE) * 4 = 16k
+	-->
+	<reg32 offset="0xa831" name="SP_HS_WAVE_INPUT_SIZE" low="0" high="7" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa832" name="SP_HS_BRANCH_COND" type="hex" usage="rp_blit"/>
+
+	<!-- TODO: exact same layout as 0xa81b-0xa825 -->
+	<reg32 offset="0xa833" name="SP_HS_OBJ_FIRST_EXEC_OFFSET" type="uint" usage="rp_blit"/>
+	<reg64 offset="0xa834" name="SP_HS_OBJ_START" type="address" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa836" name="SP_HS_PVT_MEM_PARAM" type="a6xx_sp_xs_pvt_mem_param" usage="rp_blit"/>
+	<reg64 offset="0xa837" name="SP_HS_PVT_MEM_ADDR" type="waddress" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa839" name="SP_HS_PVT_MEM_SIZE" type="a6xx_sp_xs_pvt_mem_size" usage="rp_blit"/>
+	<reg32 offset="0xa83a" name="SP_HS_TEX_COUNT" low="0" high="7" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa83b" name="SP_HS_CONFIG" type="a6xx_sp_xs_config" usage="rp_blit"/>
+	<reg32 offset="0xa83c" name="SP_HS_INSTRLEN" low="0" high="27" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa83d" name="SP_HS_PVT_MEM_HW_STACK_OFFSET" type="a6xx_sp_xs_pvt_mem_hw_stack_offset" usage="rp_blit"/>
+	<reg32 offset="0xa82f" name="SP_HS_VGPR_CONFIG" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xa840" name="SP_DS_CTRL_REG0" type="a6xx_sp_xs_ctrl_reg0" usage="rp_blit">
+		<!-- There is no mergedregs bit, that comes from the VS. -->
+		<bitfield name="EARLYPREAMBLE" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa841" name="SP_DS_BRANCH_COND" type="hex"/>
+
+	<!-- TODO: exact same layout as 0xa802-0xa81a -->
+	<reg32 offset="0xa842" name="SP_DS_PRIMITIVE_CNTL" type="a6xx_sp_xs_prim_cntl" usage="rp_blit"/>
+	<array offset="0xa843" name="SP_DS_OUT" stride="1" length="16" usage="rp_blit">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="A_COMPMASK" low="8" high="11" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="23" type="a3xx_regid"/>
+			<bitfield name="B_COMPMASK" low="24" high="27" type="hex"/>
+		</reg32>
+	</array>
+	<array offset="0xa853" name="SP_DS_VPC_DST" stride="1" length="8" usage="rp_blit">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="OUTLOC0" low="0" high="7" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="15" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="23" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="31" type="uint"/>
+		</reg32>
+	</array>
+
+	<!-- TODO: exact same layout as 0xa81b-0xa825 -->
+	<reg32 offset="0xa85b" name="SP_DS_OBJ_FIRST_EXEC_OFFSET" type="uint" usage="rp_blit"/>
+	<reg64 offset="0xa85c" name="SP_DS_OBJ_START" type="address" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa85e" name="SP_DS_PVT_MEM_PARAM" type="a6xx_sp_xs_pvt_mem_param" usage="rp_blit"/>
+	<reg64 offset="0xa85f" name="SP_DS_PVT_MEM_ADDR" type="waddress" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa861" name="SP_DS_PVT_MEM_SIZE" type="a6xx_sp_xs_pvt_mem_size" usage="rp_blit"/>
+	<reg32 offset="0xa862" name="SP_DS_TEX_COUNT" low="0" high="7" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa863" name="SP_DS_CONFIG" type="a6xx_sp_xs_config" usage="rp_blit"/>
+	<reg32 offset="0xa864" name="SP_DS_INSTRLEN" low="0" high="27" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa865" name="SP_DS_PVT_MEM_HW_STACK_OFFSET" type="a6xx_sp_xs_pvt_mem_hw_stack_offset" usage="rp_blit"/>
+	<reg32 offset="0xa868" name="SP_DS_VGPR_CONFIG" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xa870" name="SP_GS_CTRL_REG0" type="a6xx_sp_xs_ctrl_reg0" usage="rp_blit">
+		<!-- There is no mergedregs bit, that comes from the VS. -->
+		<bitfield name="EARLYPREAMBLE" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa871" name="SP_GS_PRIM_SIZE" low="0" high="7" type="uint" usage="rp_blit">
+		<doc>
+			Normally the size of the output of the last stage in
+			dwords. It should be programmed as follows:
+
+			size less than 63    - size
+			size of 63 (?) or 64 - 63
+			size greater than 64 - 64
+
+			What to program when the size is 61-63 is a guess, but
+			both the blob and ir3 align the size to 4 dword's so it
+			doesn't matter in practice.
+		</doc>
+	</reg32>
+	<reg32 offset="0xa872" name="SP_GS_BRANCH_COND" type="hex" usage="rp_blit"/>
+
+	<!-- TODO: exact same layout as 0xa802-0xa81a -->
+	<reg32 offset="0xa873" name="SP_GS_PRIMITIVE_CNTL" type="a6xx_sp_xs_prim_cntl" usage="rp_blit"/>
+	<array offset="0xa874" name="SP_GS_OUT" stride="1" length="16" usage="rp_blit">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="A_REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="A_COMPMASK" low="8" high="11" type="hex"/>
+			<bitfield name="B_REGID" low="16" high="23" type="a3xx_regid"/>
+			<bitfield name="B_COMPMASK" low="24" high="27" type="hex"/>
+		</reg32>
+	</array>
+
+	<array offset="0xa884" name="SP_GS_VPC_DST" stride="1" length="8" usage="rp_blit">
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="OUTLOC0" low="0" high="7" type="uint"/>
+			<bitfield name="OUTLOC1" low="8" high="15" type="uint"/>
+			<bitfield name="OUTLOC2" low="16" high="23" type="uint"/>
+			<bitfield name="OUTLOC3" low="24" high="31" type="uint"/>
+		</reg32>
+	</array>
+
+	<!-- TODO: exact same layout as 0xa81b-0xa825 -->
+	<reg32 offset="0xa88c" name="SP_GS_OBJ_FIRST_EXEC_OFFSET" type="uint" usage="rp_blit"/>
+	<reg64 offset="0xa88d" name="SP_GS_OBJ_START" type="address" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa88f" name="SP_GS_PVT_MEM_PARAM" type="a6xx_sp_xs_pvt_mem_param" usage="rp_blit"/>
+	<reg64 offset="0xa890" name="SP_GS_PVT_MEM_ADDR" type="waddress" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa892" name="SP_GS_PVT_MEM_SIZE" type="a6xx_sp_xs_pvt_mem_size" usage="rp_blit"/>
+	<reg32 offset="0xa893" name="SP_GS_TEX_COUNT" low="0" high="7" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa894" name="SP_GS_CONFIG" type="a6xx_sp_xs_config" usage="rp_blit"/>
+	<reg32 offset="0xa895" name="SP_GS_INSTRLEN" low="0" high="27" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa896" name="SP_GS_PVT_MEM_HW_STACK_OFFSET" type="a6xx_sp_xs_pvt_mem_hw_stack_offset" usage="rp_blit"/>
+	<reg32 offset="0xa899" name="SP_GS_VGPR_CONFIG" variants="A7XX-" usage="cmd"/>
+
+	<reg64 offset="0xa8a0" name="SP_VS_TEX_SAMP" type="address" align="16" usage="cmd"/>
+	<reg64 offset="0xa8a2" name="SP_HS_TEX_SAMP" type="address" align="16" usage="cmd"/>
+	<reg64 offset="0xa8a4" name="SP_DS_TEX_SAMP" type="address" align="16" usage="cmd"/>
+	<reg64 offset="0xa8a6" name="SP_GS_TEX_SAMP" type="address" align="16" usage="cmd"/>
+	<reg64 offset="0xa8a8" name="SP_VS_TEX_CONST" type="address" align="64" usage="cmd"/>
+	<reg64 offset="0xa8aa" name="SP_HS_TEX_CONST" type="address" align="64" usage="cmd"/>
+	<reg64 offset="0xa8ac" name="SP_DS_TEX_CONST" type="address" align="64" usage="cmd"/>
+	<reg64 offset="0xa8ae" name="SP_GS_TEX_CONST" type="address" align="64" usage="cmd"/>
+
+	<!-- TODO: 4 unknown bool registers 0xa8c0-0xa8c3 -->
+
+	<reg32 offset="0xa980" name="SP_FS_CTRL_REG0" type="a6xx_sp_xs_ctrl_reg0" usage="rp_blit">
+		<bitfield name="THREADSIZE" pos="20" type="a6xx_threadsize"/>
+		<bitfield name="UNK21" pos="21" type="boolean"/>
+		<bitfield name="VARYING" pos="22" type="boolean"/>
+		<bitfield name="LODPIXMASK" pos="23" type="boolean">
+			<doc>
+				Enable ALL helper invocations in a quad. Necessary for
+				fine derivatives and quad subgroup ops.
+			</doc>
+		</bitfield>
+		<!-- note: vk blob uses bit24 -->
+		<bitfield name="UNK24" pos="24" type="boolean"/>
+		<bitfield name="UNK25" pos="25" type="boolean"/>
+		<bitfield name="PIXLODENABLE" pos="26" type="boolean">
+			<doc>
+				Enable helper invocations. Enables 3 out of 4 fragments,
+				because the coarse derivatives only use half of the quad
+				and so one pixel's value is always unused.
+			</doc>
+		</bitfield>
+		<bitfield name="UNK27" pos="27" type="boolean"/>
+		<bitfield name="EARLYPREAMBLE" pos="28" type="boolean"/>
+		<bitfield name="MERGEDREGS" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa981" name="SP_FS_BRANCH_COND" type="hex"/>
+	<reg32 offset="0xa982" name="SP_FS_OBJ_FIRST_EXEC_OFFSET" type="uint" usage="rp_blit"/>
+	<reg64 offset="0xa983" name="SP_FS_OBJ_START" type="address" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa985" name="SP_FS_PVT_MEM_PARAM" type="a6xx_sp_xs_pvt_mem_param" usage="rp_blit"/>
+	<reg64 offset="0xa986" name="SP_FS_PVT_MEM_ADDR" type="waddress" align="32" usage="rp_blit"/>
+	<reg32 offset="0xa988" name="SP_FS_PVT_MEM_SIZE" type="a6xx_sp_xs_pvt_mem_size" usage="rp_blit"/>
+
+	<reg32 offset="0xa989" name="SP_BLEND_CNTL" usage="rp_blit">
+		<!-- per-mrt enable bit -->
+		<bitfield name="ENABLE_BLEND" low="0" high="7"/>
+		<bitfield name="UNK8" pos="8" type="boolean"/>
+		<bitfield name="DUAL_COLOR_IN_ENABLE" pos="9" type="boolean"/>
+		<bitfield name="ALPHA_TO_COVERAGE" pos="10" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa98a" name="SP_SRGB_CNTL" usage="rp_blit">
+		<!-- Same as RB_SRGB_CNTL -->
+		<bitfield name="SRGB_MRT0" pos="0" type="boolean"/>
+		<bitfield name="SRGB_MRT1" pos="1" type="boolean"/>
+		<bitfield name="SRGB_MRT2" pos="2" type="boolean"/>
+		<bitfield name="SRGB_MRT3" pos="3" type="boolean"/>
+		<bitfield name="SRGB_MRT4" pos="4" type="boolean"/>
+		<bitfield name="SRGB_MRT5" pos="5" type="boolean"/>
+		<bitfield name="SRGB_MRT6" pos="6" type="boolean"/>
+		<bitfield name="SRGB_MRT7" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa98b" name="SP_FS_RENDER_COMPONENTS" usage="rp_blit">
+		<bitfield name="RT0" low="0" high="3"/>
+		<bitfield name="RT1" low="4" high="7"/>
+		<bitfield name="RT2" low="8" high="11"/>
+		<bitfield name="RT3" low="12" high="15"/>
+		<bitfield name="RT4" low="16" high="19"/>
+		<bitfield name="RT5" low="20" high="23"/>
+		<bitfield name="RT6" low="24" high="27"/>
+		<bitfield name="RT7" low="28" high="31"/>
+	</reg32>
+	<reg32 offset="0xa98c" name="SP_FS_OUTPUT_CNTL0" usage="rp_blit">
+		<bitfield name="DUAL_COLOR_IN_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="DEPTH_REGID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="SAMPMASK_REGID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="STENCILREF_REGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xa98d" name="SP_FS_OUTPUT_CNTL1" usage="rp_blit">
+		<bitfield name="MRT" low="0" high="3" type="uint"/>
+	</reg32>
+
+	<array offset="0xa98e" name="SP_FS_OUTPUT" stride="1" length="8" usage="rp_blit">
+		<doc>per MRT</doc>
+		<reg32 offset="0x0" name="REG">
+			<bitfield name="REGID" low="0" high="7" type="a3xx_regid"/>
+			<bitfield name="HALF_PRECISION" pos="8" type="boolean"/>
+		</reg32>
+	</array>
+
+	<array offset="0xa996" name="SP_FS_MRT" stride="1" length="8" usage="rp_blit">
+		<reg32 offset="0" name="REG">
+			<bitfield name="COLOR_FORMAT" low="0" high="7" type="a6xx_format"/>
+			<bitfield name="COLOR_SINT" pos="8" type="boolean"/>
+			<bitfield name="COLOR_UINT" pos="9" type="boolean"/>
+			<bitfield name="UNK10" pos="10" type="boolean"/>
+		</reg32>
+	</array>
+
+	<reg32 offset="0xa99e" name="SP_FS_PREFETCH_CNTL" usage="rp_blit">
+		<bitfield name="COUNT" low="0" high="2" type="uint"/>
+		<bitfield name="IJ_WRITE_DISABLE" pos="3" type="boolean"/>
+		<doc>
+			Similar to "(eq)" flag but disables helper invocations
+			after the texture prefetch.
+		</doc>
+		<bitfield name="ENDOFQUAD" pos="4" type="boolean" />
+		<doc>
+			Bypass writing to regs and overwrite output with color from
+			CONSTSLOTID const regs.
+		</doc>
+		<bitfield name="WRITE_COLOR_TO_OUTPUT" pos="5" type="boolean"/>
+		<bitfield name="CONSTSLOTID" low="6" high="14" type="uint"/>
+		<!-- Blob never uses it -->
+		<bitfield name="CONSTSLOTID4COORD" low="16" high="24" type="uint" variants="A7XX-"/>
+	</reg32>
+	<array offset="0xa99f" name="SP_FS_PREFETCH" stride="1" length="4" variants="A6XX" usage="rp_blit">
+		<reg32 offset="0" name="CMD" variants="A6XX">
+			<bitfield name="SRC" low="0" high="6" type="uint"/>
+			<bitfield name="SAMP_ID" low="7" high="10" type="uint"/>
+			<bitfield name="TEX_ID" low="11" high="15" type="uint"/>
+			<bitfield name="DST" low="16" high="21" type="a3xx_regid"/>
+			<bitfield name="WRMASK" low="22" high="25" type="hex"/>
+			<bitfield name="HALF" pos="26" type="boolean"/>
+			<doc>Results in color being zero</doc>
+			<bitfield name="UNK27" pos="27" type="boolean"/>
+			<bitfield name="BINDLESS" pos="28" type="boolean"/>
+			<bitfield name="CMD" low="29" high="31" type="a6xx_tex_prefetch_cmd"/>
+		</reg32>
+	</array>
+	<array offset="0xa99f" name="SP_FS_PREFETCH" stride="1" length="4" variants="A7XX-" usage="rp_blit">
+		<reg32 offset="0" name="CMD" variants="A7XX-">
+			<bitfield name="SRC" low="0" high="6" type="uint"/>
+			<bitfield name="SAMP_ID" low="7" high="9" type="uint"/>
+			<bitfield name="TEX_ID" low="10" high="12" type="uint"/>
+			<bitfield name="DST" low="13" high="18" type="a3xx_regid"/>
+			<bitfield name="WRMASK" low="19" high="22" type="hex"/>
+			<bitfield name="HALF" pos="23" type="boolean"/>
+			<bitfield name="BINDLESS" pos="25" type="boolean"/>
+			<bitfield name="CMD" low="26" high="29" type="a6xx_tex_prefetch_cmd"/>
+		</reg32>
+	</array>
+	<array offset="0xa9a3" name="SP_FS_BINDLESS_PREFETCH" stride="1" length="4" usage="rp_blit">
+		<reg32 offset="0" name="CMD">
+			<bitfield name="SAMP_ID" low="0" high="15" type="uint"/>
+			<bitfield name="TEX_ID" low="16" high="31" type="uint"/>
+		</reg32>
+	</array>
+	<reg32 offset="0xa9a7" name="SP_FS_TEX_COUNT" low="0" high="7" type="uint" usage="rp_blit"/>
+	<reg32 offset="0xa9a8" name="SP_UNKNOWN_A9A8" low="0" high="16" usage="cmd"/> <!-- always 0x0 ? -->
+	<reg32 offset="0xa9a9" name="SP_FS_PVT_MEM_HW_STACK_OFFSET" type="a6xx_sp_xs_pvt_mem_hw_stack_offset" usage="rp_blit"/>
+
+	<!-- TODO: unknown bool register at 0xa9aa, likely same as 0xa8c0-0xa8c3 but for FS -->
+
+
+
+
+	<reg32 offset="0xa9b0" name="SP_CS_CTRL_REG0" type="a6xx_sp_xs_ctrl_reg0" usage="cmd">
+		<bitfield name="THREADSIZE" pos="20" type="a6xx_threadsize"/>
+		<!-- seems to make SP use less concurrent threads when possible? -->
+		<bitfield name="UNK21" pos="21" type="boolean"/>
+		<!-- has a small impact on performance, not clear what it does -->
+		<bitfield name="UNK22" pos="22" type="boolean"/>
+		<bitfield name="EARLYPREAMBLE" pos="23" type="boolean"/>
+		<bitfield name="MERGEDREGS" pos="31" type="boolean"/>
+	</reg32>
+
+	<!-- set for compute shaders -->
+	<reg32 offset="0xa9b1" name="SP_CS_UNKNOWN_A9B1" usage="cmd">
+		<bitfield name="SHARED_SIZE" low="0" high="4" type="uint">
+			<doc>
+				If 0 - all 32k of shared storage is enabled, otherwise
+				(SHARED_SIZE + 1) * 1k is enabled.
+				The ldl/stl offset seems to be rewritten to 0 when it is beyond
+				this limit. This is different from ldlw/stlw, which wraps at
+				64k (and has 36k of storage on A640 - reads between 36k-64k
+				always return 0)
+			</doc>
+		</bitfield>
+		<bitfield name="UNK5" pos="5" type="boolean"/>
+		<!-- always 1 ? -->
+		<bitfield name="UNK6" pos="6" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xa9b2" name="SP_CS_BRANCH_COND" type="hex" usage="cmd"/>
+	<reg32 offset="0xa9b3" name="SP_CS_OBJ_FIRST_EXEC_OFFSET" type="uint" usage="cmd"/>
+	<reg64 offset="0xa9b4" name="SP_CS_OBJ_START" type="address" align="32" usage="cmd"/>
+	<reg32 offset="0xa9b6" name="SP_CS_PVT_MEM_PARAM" type="a6xx_sp_xs_pvt_mem_param" usage="cmd"/>
+	<reg64 offset="0xa9b7" name="SP_CS_PVT_MEM_ADDR" align="32" usage="cmd"/>
+	<reg32 offset="0xa9b9" name="SP_CS_PVT_MEM_SIZE" type="a6xx_sp_xs_pvt_mem_size" usage="cmd"/>
+	<reg32 offset="0xa9ba" name="SP_CS_TEX_COUNT" low="0" high="7" type="uint" usage="cmd"/>
+	<reg32 offset="0xa9bb" name="SP_CS_CONFIG" type="a6xx_sp_xs_config" usage="cmd"/>
+	<reg32 offset="0xa9bc" name="SP_CS_INSTRLEN" low="0" high="27" type="uint" usage="cmd"/>
+	<reg32 offset="0xa9bd" name="SP_CS_PVT_MEM_HW_STACK_OFFSET" type="a6xx_sp_xs_pvt_mem_hw_stack_offset" usage="cmd"/>
+	<reg32 offset="0xa9be" name="SP_CS_UNKNOWN_A9BE" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xa9c5" name="SP_CS_VGPR_CONFIG" variants="A7XX-" usage="cmd"/>
+
+	<!-- new in a6xx gen4, matches HLSQ_CS_CNTL_0 -->
+	<reg32 offset="0xa9c2" name="SP_CS_CNTL_0" usage="cmd">
+		<bitfield name="WGIDCONSTID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="WGSIZECONSTID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="WGOFFSETCONSTID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="LOCALIDREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<!-- new in a6xx gen4, matches HLSQ_CS_CNTL_1 -->
+	<reg32 offset="0xa9c3" name="SP_CS_CNTL_1" variants="A6XX" usage="cmd">
+		<!-- gl_LocalInvocationIndex -->
+		<bitfield name="LINEARLOCALIDREGID" low="0" high="7" type="a3xx_regid"/>
+		<!-- a650 has 6 "SP cores" (but 3 "SP"). this makes it use only
+		     one of those 6 "SP cores" -->
+		<bitfield name="SINGLE_SP_CORE" pos="8" type="boolean"/>
+		<!-- Must match SP_CS_CTRL -->
+		<bitfield name="THREADSIZE" pos="9" type="a6xx_threadsize"/>
+		<!-- 1 thread per wave (ignored if bit9 set) -->
+		<bitfield name="THREADSIZE_SCALAR" pos="10" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0xa9c3" name="SP_CS_CNTL_1" variants="A7XX-" usage="cmd">
+		<!-- gl_LocalInvocationIndex -->
+		<bitfield name="LINEARLOCALIDREGID" low="0" high="7" type="a3xx_regid"/>
+		<!-- Must match SP_CS_CTRL -->
+		<bitfield name="THREADSIZE" pos="8" type="a6xx_threadsize"/>
+		<!-- 1 thread per wave (would hang if THREAD128 is also set) -->
+		<bitfield name="THREADSIZE_SCALAR" pos="9" type="boolean"/>
+
+		<!-- Affects getone. If enabled, getone sometimes executed 1? less times
+		     than there are subgroups.
+		 -->
+		<bitfield name="UNK15" pos="15" type="boolean"/>
+	</reg32>
+
+	<!-- TODO: two 64kb aligned addresses at a9d0/a9d2 -->
+
+	<reg64 offset="0xa9e0" name="SP_FS_TEX_SAMP" type="address" align="16" usage="rp_blit"/>
+	<reg64 offset="0xa9e2" name="SP_CS_TEX_SAMP" type="address" align="16" usage="cmd"/>
+	<reg64 offset="0xa9e4" name="SP_FS_TEX_CONST" type="address" align="64" usage="rp_blit"/>
+	<reg64 offset="0xa9e6" name="SP_CS_TEX_CONST" type="address" align="64" usage="cmd"/>
+
+	<enum name="a6xx_bindless_descriptor_size">
+		<doc>
+			This can alternatively be interpreted as a pitch shift, ie, the
+			descriptor size is 2 &lt;&lt; N dwords
+		</doc>
+		<value value="1" name="BINDLESS_DESCRIPTOR_16B"/>
+		<value value="3" name="BINDLESS_DESCRIPTOR_64B"/>
+	</enum>
+
+	<array offset="0xa9e8" name="SP_CS_BINDLESS_BASE" stride="2" length="5" variants="A6XX" usage="cmd">
+		<reg64 offset="0" name="DESCRIPTOR" variants="A6XX">
+			<bitfield name="DESC_SIZE" low="0" high="1" type="a6xx_bindless_descriptor_size"/>
+			<bitfield name="ADDR" low="2" high="63" shr="2" type="address"/>
+		</reg64>
+	</array>
+	<array offset="0xa9e8" name="SP_CS_BINDLESS_BASE" stride="2" length="8" variants="A7XX-" usage="cmd">
+		<reg64 offset="0" name="DESCRIPTOR" variants="A7XX-">
+			<bitfield name="DESC_SIZE" low="0" high="1" type="a6xx_bindless_descriptor_size"/>
+			<bitfield name="ADDR" low="2" high="63" shr="2" type="address"/>
+		</reg64>
+	</array>
+
+	<!--
+	IBO state for compute shader:
+	 -->
+	<reg64 offset="0xa9f2" name="SP_CS_IBO" type="address" align="16"/>
+	<reg32 offset="0xaa00" name="SP_CS_IBO_COUNT" low="0" high="6" type="uint"/>
+
+	<!-- Correlated with avgs/uvgs usage in FS -->
+	<reg32 offset="0xaa01" name="SP_FS_VGPR_CONFIG" type="uint" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xaa02" name="SP_PS_ALIASED_COMPONENTS_CONTROL" variants="A7XX-" usage="cmd">
+		<bitfield name="ENABLED" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xaa03" name="SP_PS_ALIASED_COMPONENTS" variants="A7XX-" usage="cmd">
+		<doc>
+			Specify for which components the output color should be read
+			from alias, e.g. for:
+
+				alias.1.b32.0 r3.x, c8.x
+				alias.1.b32.0 r2.x, c4.x
+				alias.1.b32.0 r1.x, c4.x
+				alias.1.b32.0 r0.x, c0.x
+
+			the SP_PS_ALIASED_COMPONENTS would be 0x00001111
+		</doc>
+
+		<bitfield name="RT0" low="0" high="3"/>
+		<bitfield name="RT1" low="4" high="7"/>
+		<bitfield name="RT2" low="8" high="11"/>
+		<bitfield name="RT3" low="12" high="15"/>
+		<bitfield name="RT4" low="16" high="19"/>
+		<bitfield name="RT5" low="20" high="23"/>
+		<bitfield name="RT6" low="24" high="27"/>
+		<bitfield name="RT7" low="28" high="31"/>
+	</reg32>
+
+	<reg32 offset="0xaaf2" name="SP_UNKNOWN_AAF2" type="uint" usage="cmd"/>
+
+	<!--
+                This enum is probably similar in purpose to SNORMMODE on a3xx,
+                minus the snorm stuff, i.e. it controls what happens with an
+                out-of-bounds isam/isamm. GL and Vulkan robustness require us to
+                return 0 on out-of-bound textureFetch().
+	-->
+	<enum name="a6xx_isam_mode">
+		<value value="0x1" name="ISAMMODE_CL"/>
+		<value value="0x2" name="ISAMMODE_GL"/>
+	</enum>
+
+	<reg32 offset="0xab00" name="SP_MODE_CONTROL" usage="rp_blit">
+	  <!--
+	  When set, half register loads from the constant file will
+	  load a 32-bit value (so hc0.y loads the same value as c0.y)
+	  and implicitly convert it to 16b (f2f16, or u2u16, based on
+	  operand type).  When unset, half register loads from the
+	  constant file will load 16 bits from the packed constant
+	  file (so hc0.y loads the top 16 bits of the value of c0.x)
+	  -->
+		<bitfield name="CONSTANT_DEMOTION_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="ISAMMODE" low="1" high="2" type="a6xx_isam_mode"/>
+		<bitfield name="SHARED_CONSTS_ENABLE" pos="3" type="boolean"/> <!-- see HLSQ_SHARED_CONSTS -->
+	</reg32>
+
+	<reg32 offset="0xab01" name="SP_UNKNOWN_AB01" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xab02" name="SP_UNKNOWN_AB02" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xab04" name="SP_FS_CONFIG" type="a6xx_sp_xs_config" usage="rp_blit"/>
+	<reg32 offset="0xab05" name="SP_FS_INSTRLEN" low="0" high="27" type="uint" usage="rp_blit"/>
+
+	<array offset="0xab10" name="SP_BINDLESS_BASE" stride="2" length="5" variants="A6XX" usage="rp_blit">
+		<reg64 offset="0" name="DESCRIPTOR" variants="A6XX">
+			<bitfield name="DESC_SIZE" low="0" high="1" type="a6xx_bindless_descriptor_size"/>
+			<bitfield name="ADDR" low="2" high="63" shr="2" type="address"/>
+		</reg64>
+	</array>
+	<array offset="0xab0a" name="SP_BINDLESS_BASE" stride="2" length="8" variants="A7XX-" usage="rp_blit">
+		<reg64 offset="0" name="DESCRIPTOR" variants="A7XX-">
+			<bitfield name="DESC_SIZE" low="0" high="1" type="a6xx_bindless_descriptor_size"/>
+			<bitfield name="ADDR" low="2" high="63" shr="2" type="address"/>
+		</reg64>
+	</array>
+
+	<!--
+	Combined IBO state for 3d pipe, used for Image and SSBO write/atomic
+	instructions VS/HS/DS/GS/FS.  See SP_CS_IBO_* for compute shaders.
+	 -->
+	<reg64 offset="0xab1a" name="SP_IBO" type="address" align="16" usage="cmd"/>
+	<reg32 offset="0xab20" name="SP_IBO_COUNT" low="0" high="6" type="uint" usage="cmd"/>
+
+	<reg32 offset="0xab22" name="SP_UNKNOWN_AB22" variants="A7XX-" usage="cmd"/>
+
+	<bitset name="a6xx_sp_2d_dst_format" inline="yes">
+		<bitfield name="NORM" pos="0" type="boolean"/>
+		<bitfield name="SINT" pos="1" type="boolean"/>
+		<bitfield name="UINT" pos="2" type="boolean"/>
+		<!-- looks like HW only cares about the base type of this format,
+		     which matches the ifmt? -->
+		<bitfield name="COLOR_FORMAT" low="3" high="10" type="a6xx_format"/>
+		<!-- set when ifmt is R2D_UNORM8_SRGB -->
+		<bitfield name="SRGB" pos="11" type="boolean"/>
+		<!-- some sort of channel mask, not sure what it is for -->
+		<bitfield name="MASK" low="12" high="15"/>
+	</bitset>
+
+	<reg32 offset="0xacc0" name="SP_2D_DST_FORMAT" type="a6xx_sp_2d_dst_format" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xa9bf" name="SP_2D_DST_FORMAT" type="a6xx_sp_2d_dst_format" variants="A7XX-" usage="rp_blit"/>
+
+	<reg32 offset="0xae00" name="SP_DBG_ECO_CNTL" usage="cmd"/>
+	<reg32 offset="0xae01" name="SP_ADDR_MODE_CNTL" pos="0" type="a5xx_address_mode"/>
+	<reg32 offset="0xae02" name="SP_NC_MODE_CNTL">
+		<!-- TODO: valid bits 0x3c3f, see kernel -->
+	</reg32>
+	<reg32 offset="0xae03" name="SP_CHICKEN_BITS" usage="cmd"/>
+	<reg32 offset="0xae04" name="SP_FLOAT_CNTL" usage="cmd">
+		<bitfield name="F16_NO_INF" pos="3" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0xae06" name="SP_UNKNOWN_AE06" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xae08" name="SP_UNKNOWN_AE08" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xae09" name="SP_UNKNOWN_AE09" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xae0a" name="SP_UNKNOWN_AE0A" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xae0f" name="SP_PERFCTR_ENABLE" usage="cmd">
+		<!-- some perfcntrs are affected by a per-stage enable bit
+		     (PERF_SP_ALU_WORKING_CYCLES for example)
+		     TODO: verify position of HS/DS/GS bits -->
+		<bitfield name="VS" pos="0" type="boolean"/>
+		<bitfield name="HS" pos="1" type="boolean"/>
+		<bitfield name="DS" pos="2" type="boolean"/>
+		<bitfield name="GS" pos="3" type="boolean"/>
+		<bitfield name="FS" pos="4" type="boolean"/>
+		<bitfield name="CS" pos="5" type="boolean"/>
+	</reg32>
+	<array offset="0xae10" name="SP_PERFCTR_SP_SEL" stride="1" length="24"/>
+	<array offset="0xae60" name="SP_PERFCTR_HLSQ_SEL" stride="1" length="6" variants="A7XX-"/>
+	<reg32 offset="0xae6a" name="SP_UNKNOWN_AE6A" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xae6b" name="SP_UNKNOWN_AE6B" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xae6c" name="SP_UNKNOWN_AE6C" variants="A7XX-" usage="cmd"/>
+	<reg32 offset="0xae6d" name="SP_READ_SEL" variants="A7XX-">
+		<bitfield name="LOCATION" low="18" high="19" type="a7xx_state_location"/>
+		<bitfield name="PIPE" low="16" high="17" type="a7xx_pipe"/>
+		<bitfield name="STATETYPE" low="8" high="15" type="a7xx_statetype_id"/>
+		<bitfield name="USPTP" low="4" high="7"/>
+		<bitfield name="SPTP" low="0" high="3"/>
+	</reg32>
+	<reg32 offset="0xae71" name="SP_DBG_CNTL" variants="A7XX-"/>
+	<reg32 offset="0xae73" name="SP_UNKNOWN_AE73" variants="A7XX-" usage="cmd"/>
+	<array offset="0xae80" name="SP_PERFCTR_SP_SEL" stride="1" length="36" variants="A7XX-"/>
+	<!-- TODO: there are 4 more percntr select registers (0xae28-0xae2b) -->
+	<!-- TODO: there are a few unknown registers in the 0xae30-0xae52 range -->
+	<reg32 offset="0xbe22" name="SP_CONTEXT_SWITCH_GFX_PREEMPTION_SAFE_MODE"/>
+
+	<!--
+	The downstream kernel calls the debug cluster of registers
+	"a6xx_sp_ps_tp_cluster" but this actually specifies the border
+	color base for compute shaders.
+	-->
+	<reg64 offset="0xb180" name="SP_PS_TP_BORDER_COLOR_BASE_ADDR" type="address" align="128" usage="cmd"/>
+	<reg32 offset="0xb182" name="SP_UNKNOWN_B182" low="0" high="2" usage="cmd"/>
+	<reg32 offset="0xb183" name="SP_UNKNOWN_B183" low="0" high="23" usage="cmd"/>
+
+	<reg32 offset="0xb190" name="SP_UNKNOWN_B190"/>
+	<reg32 offset="0xb191" name="SP_UNKNOWN_B191"/>
+
+	<!-- could be all the stuff below here is actually TPL1?? -->
+
+	<reg32 offset="0xb300" name="SP_TP_RAS_MSAA_CNTL" usage="rp_blit">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="UNK2" low="2" high="3"/>
+	</reg32>
+	<reg32 offset="0xb301" name="SP_TP_DEST_MSAA_CNTL" usage="rp_blit">
+		<bitfield name="SAMPLES" low="0" high="1" type="a3xx_msaa_samples"/>
+		<bitfield name="MSAA_DISABLE" pos="2" type="boolean"/>
+	</reg32>
+
+	<!-- looks to work in the same way as a5xx: -->
+	<reg64 offset="0xb302" name="SP_TP_BORDER_COLOR_BASE_ADDR" type="address" align="128" usage="cmd"/>
+	<reg32 offset="0xb304" name="SP_TP_SAMPLE_CONFIG" type="a6xx_sample_config" usage="rp_blit"/>
+	<reg32 offset="0xb305" name="SP_TP_SAMPLE_LOCATION_0" type="a6xx_sample_locations" usage="rp_blit"/>
+	<reg32 offset="0xb306" name="SP_TP_SAMPLE_LOCATION_1" type="a6xx_sample_locations" usage="rp_blit"/>
+	<reg32 offset="0xb307" name="SP_TP_WINDOW_OFFSET" type="a6xx_reg_xy" usage="rp_blit"/>
+	<reg32 offset="0xb309" name="SP_TP_MODE_CNTL" usage="cmd">
+		<bitfield name="ISAMMODE" low="0" high="1" type="a6xx_isam_mode"/>
+		<bitfield name="UNK3" low="2" high="7"/>
+	</reg32>
+	<reg32 offset="0xb310" name="SP_UNKNOWN_B310" variants="A7XX-" usage="cmd"/>
+
+	<!--
+	Equiv to corresponding RB_2D_SRC_* regs on a5xx.. which were either
+	badly named or the functionality moved in a6xx.  But downstream kernel
+	calls this "a6xx_sp_ps_tp_2d_cluster"
+	 -->
+	<reg32 offset="0xb4c0" name="SP_PS_2D_SRC_INFO" type="a6xx_2d_src_surf_info" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb4c1" name="SP_PS_2D_SRC_SIZE" variants="A6XX" usage="rp_blit">
+		<bitfield name="WIDTH" low="0" high="14" type="uint"/>
+		<bitfield name="HEIGHT" low="15" high="29" type="uint"/>
+	</reg32>
+	<reg64 offset="0xb4c2" name="SP_PS_2D_SRC" type="address" align="16" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb4c4" name="SP_PS_2D_SRC_PITCH" variants="A6XX" usage="rp_blit">
+		<bitfield name="UNK0" low="0" high="8"/>
+		<bitfield name="PITCH" low="9" high="23" shr="6" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0xb2c0" name="SP_PS_2D_SRC_INFO" type="a6xx_2d_src_surf_info" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xb2c1" name="SP_PS_2D_SRC_SIZE" variants="A7XX">
+		<bitfield name="WIDTH" low="0" high="14" type="uint"/>
+		<bitfield name="HEIGHT" low="15" high="29" type="uint"/>
+	</reg32>
+	<reg64 offset="0xb2c2" name="SP_PS_2D_SRC" type="address" align="16" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xb2c4" name="SP_PS_2D_SRC_PITCH" variants="A7XX">
+		<bitfield name="UNK0" low="0" high="8"/>
+		<bitfield name="PITCH" low="9" high="23" shr="6" type="uint"/>
+	</reg32>
+
+	<!-- planes for NV12, etc. (TODO: not tested) -->
+	<reg64 offset="0xb4c5" name="SP_PS_2D_SRC_PLANE1" type="address" align="16" variants="A6XX"/>
+	<reg32 offset="0xb4c7" name="SP_PS_2D_SRC_PLANE_PITCH" low="0" high="11" shr="6" type="uint" variants="A6XX"/>
+	<reg64 offset="0xb4c8" name="SP_PS_2D_SRC_PLANE2" type="address" align="16" variants="A6XX"/>
+
+	<reg64 offset="0xb2c5" name="SP_PS_2D_SRC_PLANE1" type="address" align="16" variants="A7XX-"/>
+	<reg32 offset="0xb2c7" name="SP_PS_2D_SRC_PLANE_PITCH" low="0" high="11" shr="6" type="uint" variants="A7XX-"/>
+	<reg64 offset="0xb2c8" name="SP_PS_2D_SRC_PLANE2" type="address" align="16" variants="A7XX-"/>
+
+	<reg64 offset="0xb4ca" name="SP_PS_2D_SRC_FLAGS" type="address" align="16" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb4cc" name="SP_PS_2D_SRC_FLAGS_PITCH" low="0" high="7" shr="6" type="uint" variants="A6XX" usage="rp_blit"/>
+
+	<reg64 offset="0xb2ca" name="SP_PS_2D_SRC_FLAGS" type="address" align="16" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xb2cc" name="SP_PS_2D_SRC_FLAGS_PITCH" low="0" high="7" shr="6" type="uint" variants="A7XX-" usage="rp_blit"/>
+
+	<reg32 offset="0xb4cd" name="SP_PS_UNKNOWN_B4CD" low="6" high="31" variants="A6XX"/>
+	<reg32 offset="0xb4ce" name="SP_PS_UNKNOWN_B4CE" low="0" high="31" variants="A6XX"/>
+	<reg32 offset="0xb4cf" name="SP_PS_UNKNOWN_B4CF" low="0" high="30" variants="A6XX"/>
+	<reg32 offset="0xb4d0" name="SP_PS_UNKNOWN_B4D0" low="0" high="29" variants="A6XX"/>
+	<reg32 offset="0xb4d1" name="SP_WINDOW_OFFSET" type="a6xx_reg_xy" variants="A6XX" usage="rp_blit"/>
+
+	<reg32 offset="0xb2cd" name="SP_PS_UNKNOWN_B4CD" low="6" high="31" variants="A7XX"/>
+	<reg32 offset="0xb2ce" name="SP_PS_UNKNOWN_B4CE" low="0" high="31" variants="A7XX"/>
+	<reg32 offset="0xb2cf" name="SP_PS_UNKNOWN_B4CF" low="0" high="30" variants="A7XX"/>
+	<reg32 offset="0xb2d0" name="SP_PS_UNKNOWN_B4D0" low="0" high="29" variants="A7XX"/>
+	<reg32 offset="0xb2d1" name="SP_PS_2D_WINDOW_OFFSET" type="a6xx_reg_xy" variants="A7XX"/>
+	<reg32 offset="0xb2d2" name="SP_PS_UNKNOWN_B2D2" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xab21" name="SP_WINDOW_OFFSET" type="a6xx_reg_xy" variants="A7XX-" usage="rp_blit"/>
+
+	<!-- always 0x100000 or 0x1000000? -->
+	<reg32 offset="0xb600" name="TPL1_DBG_ECO_CNTL" low="0" high="25" usage="cmd"/>
+	<reg32 offset="0xb601" name="TPL1_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0xb602" name="TPL1_DBG_ECO_CNTL1" usage="cmd">
+		<!-- Affects UBWC in some way, if BLIT_OP_SCALE is done with this bit set
+		     and if other blit is done without it - UBWC image may be copied incorrectly.
+		 -->
+		<bitfield name="TP_UBWC_FLAG_HINT" pos="18" type="boolean"/>
+	</reg32>
+	<reg32 offset="0xb604" name="TPL1_NC_MODE_CNTL">
+		<bitfield name="MODE" pos="0" type="boolean"/>
+		<bitfield name="LOWER_BIT" low="1" high="2" type="uint"/>
+		<bitfield name="MIN_ACCESS_LENGTH" pos="3" type="boolean"/> <!-- true=64b false=32b -->
+		<bitfield name="UPPER_BIT" pos="4" type="uint"/>
+		<bitfield name="UNK6" low="6" high="7"/>
+	</reg32>
+	<reg32 offset="0xb605" name="TPL1_UNKNOWN_B605" low="0" high="7" type="uint" variants="A6XX" usage="cmd"/> <!-- always 0x0 or 0x44 ? -->
+
+	<reg32 offset="0xb608" name="TPL1_BICUBIC_WEIGHTS_TABLE_0" low="0" high="29" variants="A6XX"/>
+	<reg32 offset="0xb609" name="TPL1_BICUBIC_WEIGHTS_TABLE_1" low="0" high="29" variants="A6XX"/>
+	<reg32 offset="0xb60a" name="TPL1_BICUBIC_WEIGHTS_TABLE_2" low="0" high="29" variants="A6XX"/>
+	<reg32 offset="0xb60b" name="TPL1_BICUBIC_WEIGHTS_TABLE_3" low="0" high="29" variants="A6XX"/>
+	<reg32 offset="0xb60c" name="TPL1_BICUBIC_WEIGHTS_TABLE_4" low="0" high="29" variants="A6XX"/>
+
+	<reg32 offset="0xb608" name="TPL1_BICUBIC_WEIGHTS_TABLE_0" low="0" high="29" variants="A7XX" usage="cmd"/>
+	<reg32 offset="0xb609" name="TPL1_BICUBIC_WEIGHTS_TABLE_1" low="0" high="29" variants="A7XX" usage="cmd"/>
+	<reg32 offset="0xb60a" name="TPL1_BICUBIC_WEIGHTS_TABLE_2" low="0" high="29" variants="A7XX" usage="cmd"/>
+	<reg32 offset="0xb60b" name="TPL1_BICUBIC_WEIGHTS_TABLE_3" low="0" high="29" variants="A7XX" usage="cmd"/>
+	<reg32 offset="0xb60c" name="TPL1_BICUBIC_WEIGHTS_TABLE_4" low="0" high="29" variants="A7XX" usage="cmd"/>
+
+	<array offset="0xb610" name="TPL1_PERFCTR_TP_SEL" stride="1" length="12" variants="A6XX"/>
+	<array offset="0xb610" name="TPL1_PERFCTR_TP_SEL" stride="1" length="18" variants="A7XX"/>
+
+	<!-- TODO: 4 more perfcntr sel at 0xb620 ? -->
+
+	<bitset name="a6xx_hlsq_xs_cntl" inline="yes">
+		<bitfield name="CONSTLEN" low="0" high="7" shr="2" type="uint"/>
+		<bitfield name="ENABLED" pos="8" type="boolean"/>
+		<bitfield name="READ_IMM_SHARED_CONSTS" pos="9" type="boolean" variants="A7XX-"/>
+	</bitset>
+
+	<reg32 offset="0xb800" name="HLSQ_VS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb801" name="HLSQ_HS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb802" name="HLSQ_DS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb803" name="HLSQ_GS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A6XX" usage="rp_blit"/>
+
+	<reg32 offset="0xa827" name="HLSQ_VS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa83f" name="HLSQ_HS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa867" name="HLSQ_DS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa898" name="HLSQ_GS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A7XX-" usage="rp_blit"/>
+
+	<reg32 offset="0xa9aa" name="HLSQ_FS_UNKNOWN_A9AA" variants="A7XX-" usage="rp_blit">
+		<!-- Tentatively named, appears to disable consts being loaded via CP_LOAD_STATE6_FRAG -->
+		<bitfield name="CONSTS_LOAD_DISABLE" pos="0" type="boolean"/>
+	</reg32>
+
+	<!-- Always 0 -->
+	<reg32 offset="0xa9ac" name="HLSQ_UNKNOWN_A9AC" variants="A7XX-" usage="cmd"/>
+
+	<!-- Used in VK_KHR_fragment_shading_rate -->
+	<reg32 offset="0xa9ad" name="HLSQ_UNKNOWN_A9AD" variants="A7XX-" usage="cmd"/>
+
+	<reg32 offset="0xa9ae" name="HLSQ_UNKNOWN_A9AE" variants="A7XX-" usage="rp_blit">
+		<bitfield name="SYSVAL_REGS_COUNT" low="0" high="7" type="uint"/>
+		<!-- UNK8 is set on a730/a740 -->
+		<bitfield name="UNK8" pos="8" type="boolean"/>
+		<!-- UNK9 is set on a750 -->
+		<bitfield name="UNK9" pos="9" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0xb820" name="HLSQ_LOAD_STATE_GEOM_CMD"/>
+	<reg64 offset="0xb821" name="HLSQ_LOAD_STATE_GEOM_EXT_SRC_ADDR" align="16" type="address"/>
+	<reg32 offset="0xb823" name="HLSQ_LOAD_STATE_GEOM_DATA"/>
+
+
+	<bitset name="a6xx_hlsq_fs_cntl_0" inline="yes">
+		<!-- must match SP_FS_CTRL -->
+		<bitfield name="THREADSIZE" pos="0" type="a6xx_threadsize"/>
+		<bitfield name="VARYINGS" pos="1" type="boolean"/>
+		<bitfield name="UNK2" low="2" high="11"/>
+	</bitset>
+	<bitset name="a6xx_hlsq_control_3_reg" inline="yes">
+		<!-- register loaded with position (bary.f) -->
+		<bitfield name="IJ_PERSP_PIXEL" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_PIXEL" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="IJ_PERSP_CENTROID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_CENTROID" low="24" high="31" type="a3xx_regid"/>
+	</bitset>
+	<bitset name="a6xx_hlsq_control_4_reg" inline="yes">
+		<bitfield name="IJ_PERSP_SAMPLE" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="IJ_LINEAR_SAMPLE" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="XYCOORDREGID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="ZWCOORDREGID" low="24" high="31" type="a3xx_regid"/>
+	</bitset>
+	<bitset name="a6xx_hlsq_control_5_reg" inline="yes">
+		<bitfield name="LINELENGTHREGID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="FOVEATIONQUALITYREGID" low="8" high="15" type="a3xx_regid"/>
+	</bitset>
+
+	<reg32 offset="0xb980" type="a6xx_hlsq_fs_cntl_0" name="HLSQ_FS_CNTL_0" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb981" name="HLSQ_UNKNOWN_B981" pos="0" type="boolean" variants="A6XX"/> <!-- never used by blob -->
+	<reg32 offset="0xb982" name="HLSQ_CONTROL_1_REG" low="0" high="2" variants="A6XX" usage="rp_blit">
+		<!-- Sets the maximum number of primitives allowed in one FS wave minus one, similarly to the
+				 A3xx field, except that it's not necessary to set it to anything but the maximum, since
+				 the hardware will simply emit smaller waves when it runs out of space.	-->
+		<bitfield name="PRIMALLOCTHRESHOLD" low="0" high="2" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb983" name="HLSQ_CONTROL_2_REG" variants="A6XX" usage="rp_blit">
+		<bitfield name="FACEREGID" low="0" high="7" type="a3xx_regid"/>
+		<!-- SAMPLEID is loaded into a half-precision register: -->
+		<bitfield name="SAMPLEID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="SAMPLEMASK" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="CENTERRHW" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xb984" type="a6xx_hlsq_control_3_reg" name="HLSQ_CONTROL_3_REG" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb985" type="a6xx_hlsq_control_4_reg" name="HLSQ_CONTROL_4_REG" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb986" type="a6xx_hlsq_control_5_reg" name="HLSQ_CONTROL_5_REG" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb987" name="HLSQ_CS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A6XX" usage="cmd"/>
+	<reg32 offset="0xa9c6" type="a6xx_hlsq_fs_cntl_0" name="HLSQ_FS_CNTL_0" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa9c7" name="HLSQ_CONTROL_1_REG" low="0" high="2" variants="A7XX-" usage="rp_blit">
+			<bitfield name="PRIMALLOCTHRESHOLD" low="0" high="2" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa9c8" name="HLSQ_CONTROL_2_REG" variants="A7XX-" usage="rp_blit">
+		<bitfield name="FACEREGID" low="0" high="7" type="a3xx_regid"/>
+		<!-- SAMPLEID is loaded into a half-precision register: -->
+		<bitfield name="SAMPLEID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="SAMPLEMASK" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="CENTERRHW" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xa9c9" type="a6xx_hlsq_control_3_reg" name="HLSQ_CONTROL_3_REG" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa9ca" type="a6xx_hlsq_control_4_reg" name="HLSQ_CONTROL_4_REG" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa9cb" type="a6xx_hlsq_control_5_reg" name="HLSQ_CONTROL_5_REG" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa9cd" name="HLSQ_CS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A7XX-" usage="cmd"/>
+
+	<!-- TODO: what does KERNELDIM do exactly (blob sets it differently from turnip) -->
+	<reg32 offset="0xb990" name="HLSQ_CS_NDRANGE_0" variants="A6XX" usage="rp_blit">
+		<bitfield name="KERNELDIM" low="0" high="1" type="uint"/>
+		<!-- localsize is value minus one: -->
+		<bitfield name="LOCALSIZEX" low="2" high="11" type="uint"/>
+		<bitfield name="LOCALSIZEY" low="12" high="21" type="uint"/>
+		<bitfield name="LOCALSIZEZ" low="22" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb991" name="HLSQ_CS_NDRANGE_1" variants="A6XX" usage="rp_blit">
+		<bitfield name="GLOBALSIZE_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb992" name="HLSQ_CS_NDRANGE_2" variants="A6XX" usage="rp_blit">
+		<bitfield name="GLOBALOFF_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb993" name="HLSQ_CS_NDRANGE_3" variants="A6XX" usage="rp_blit">
+		<bitfield name="GLOBALSIZE_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb994" name="HLSQ_CS_NDRANGE_4" variants="A6XX" usage="rp_blit">
+		<bitfield name="GLOBALOFF_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb995" name="HLSQ_CS_NDRANGE_5" variants="A6XX" usage="rp_blit">
+		<bitfield name="GLOBALSIZE_Z" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb996" name="HLSQ_CS_NDRANGE_6" variants="A6XX" usage="rp_blit">
+		<bitfield name="GLOBALOFF_Z" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xb997" name="HLSQ_CS_CNTL_0" variants="A6XX" usage="rp_blit">
+		<!-- these are all vec3. first 3 need to be high regs
+		     WGSIZECONSTID is the local size (from HLSQ_CS_NDRANGE_0)
+		     WGOFFSETCONSTID is WGIDCONSTID*WGSIZECONSTID
+		-->
+		<bitfield name="WGIDCONSTID" low="0" high="7" type="a3xx_regid"/>
+		<bitfield name="WGSIZECONSTID" low="8" high="15" type="a3xx_regid"/>
+		<bitfield name="WGOFFSETCONSTID" low="16" high="23" type="a3xx_regid"/>
+		<bitfield name="LOCALIDREGID" low="24" high="31" type="a3xx_regid"/>
+	</reg32>
+	<reg32 offset="0xb998" name="HLSQ_CS_CNTL_1" variants="A6XX" usage="rp_blit">
+		<!-- gl_LocalInvocationIndex -->
+		<bitfield name="LINEARLOCALIDREGID" low="0" high="7" type="a3xx_regid"/>
+		<!-- a650 has 6 "SP cores" (but 3 "SP"). this makes it use only
+		     one of those 6 "SP cores" -->
+		<bitfield name="SINGLE_SP_CORE" pos="8" type="boolean"/>
+		<!-- Must match SP_CS_CTRL -->
+		<bitfield name="THREADSIZE" pos="9" type="a6xx_threadsize"/>
+		<!-- 1 thread per wave (ignored if bit9 set) -->
+		<bitfield name="THREADSIZE_SCALAR" pos="10" type="boolean"/>
+	</reg32>
+	<!--note: vulkan blob doesn't use these -->
+	<reg32 offset="0xb999" name="HLSQ_CS_KERNEL_GROUP_X" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb99a" name="HLSQ_CS_KERNEL_GROUP_Y" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xb99b" name="HLSQ_CS_KERNEL_GROUP_Z" variants="A6XX" usage="rp_blit"/>
+
+	<!-- TODO: what does KERNELDIM do exactly (blob sets it differently from turnip) -->
+	<reg32 offset="0xa9d4" name="HLSQ_CS_NDRANGE_0" variants="A7XX-" usage="rp_blit">
+		<bitfield name="KERNELDIM" low="0" high="1" type="uint"/>
+		<!-- localsize is value minus one: -->
+		<bitfield name="LOCALSIZEX" low="2" high="11" type="uint"/>
+		<bitfield name="LOCALSIZEY" low="12" high="21" type="uint"/>
+		<bitfield name="LOCALSIZEZ" low="22" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa9d5" name="HLSQ_CS_NDRANGE_1" variants="A7XX-" usage="rp_blit">
+		<bitfield name="GLOBALSIZE_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa9d6" name="HLSQ_CS_NDRANGE_2" variants="A7XX-" usage="rp_blit">
+		<bitfield name="GLOBALOFF_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa9d7" name="HLSQ_CS_NDRANGE_3" variants="A7XX-" usage="rp_blit">
+		<bitfield name="GLOBALSIZE_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa9d8" name="HLSQ_CS_NDRANGE_4" variants="A7XX-" usage="rp_blit">
+		<bitfield name="GLOBALOFF_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa9d9" name="HLSQ_CS_NDRANGE_5" variants="A7XX-" usage="rp_blit">
+		<bitfield name="GLOBALSIZE_Z" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0xa9da" name="HLSQ_CS_NDRANGE_6" variants="A7XX-" usage="rp_blit">
+		<bitfield name="GLOBALOFF_Z" low="0" high="31" type="uint"/>
+	</reg32>
+	<!--note: vulkan blob doesn't use these -->
+	<reg32 offset="0xa9dc" name="HLSQ_CS_KERNEL_GROUP_X" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa9dd" name="HLSQ_CS_KERNEL_GROUP_Y" variants="A7XX-" usage="rp_blit"/>
+	<reg32 offset="0xa9de" name="HLSQ_CS_KERNEL_GROUP_Z" variants="A7XX-" usage="rp_blit"/>
+
+	<enum name="a7xx_cs_yalign">
+		<value name="CS_YALIGN_1" value="8"/>
+		<value name="CS_YALIGN_2" value="4"/>
+		<value name="CS_YALIGN_4" value="2"/>
+		<value name="CS_YALIGN_8" value="1"/>
+	</enum>
+
+	<reg32 offset="0xa9db" name="HLSQ_CS_CNTL_1" variants="A7XX-" usage="rp_blit">
+		<!-- gl_LocalInvocationIndex -->
+		<bitfield name="LINEARLOCALIDREGID" low="0" high="7" type="a3xx_regid"/>
+		<!-- Must match SP_CS_CTRL -->
+		<bitfield name="THREADSIZE" pos="9" type="a6xx_threadsize"/>
+		<bitfield name="UNK11" pos="11" type="boolean"/>
+		<bitfield name="UNK22" pos="22" type="boolean"/>
+		<bitfield name="UNK26" pos="26" type="boolean"/>
+		<bitfield name="YALIGN" low="27" high="30" type="a7xx_cs_yalign"/>
+	</reg32>
+
+	<reg32 offset="0xa9df" name="HLSQ_CS_LOCAL_SIZE" variants="A7XX-" usage="cmd">
+		<!-- localsize is value minus one: -->
+		<bitfield name="LOCALSIZEX" low="2" high="11" type="uint"/>
+		<bitfield name="LOCALSIZEY" low="12" high="21" type="uint"/>
+		<bitfield name="LOCALSIZEZ" low="22" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0xb9a0" name="HLSQ_LOAD_STATE_FRAG_CMD"/>
+	<reg64 offset="0xb9a1" name="HLSQ_LOAD_STATE_FRAG_EXT_SRC_ADDR" align="16" type="address"/>
+	<reg32 offset="0xb9a3" name="HLSQ_LOAD_STATE_FRAG_DATA"/>
+
+	<!-- mirror of SP_CS_BINDLESS_BASE -->
+	<array offset="0xb9c0" name="HLSQ_CS_BINDLESS_BASE" stride="2" length="5" variants="A6XX" usage="rp_blit">
+		<reg64 offset="0" name="DESCRIPTOR">
+			<bitfield name="DESC_SIZE" low="0" high="1" type="a6xx_bindless_descriptor_size"/>
+			<bitfield name="ADDR" low="2" high="63" shr="2" type="address"/>
+		</reg64>
+	</array>
+
+	<!-- new in a6xx gen4, mirror of SP_CS_UNKNOWN_A9B1? -->
+	<reg32 offset="0xb9d0" name="HLSQ_CS_UNKNOWN_B9D0" variants="A6XX" usage="cmd">
+		<bitfield name="SHARED_SIZE" low="0" high="4" type="uint"/>
+		<bitfield name="UNK5" pos="5" type="boolean"/>
+		<!-- always 1 ? -->
+		<bitfield name="UNK6" pos="6" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0xbb00" name="HLSQ_DRAW_CMD" variants="A6XX">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+
+	<reg32 offset="0xbb01" name="HLSQ_DISPATCH_CMD" variants="A6XX">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+
+	<reg32 offset="0xbb02" name="HLSQ_EVENT_CMD" variants="A6XX">
+		<!-- I think only the low bit is actually used? -->
+		<bitfield name="STATE_ID" low="16" high="23"/>
+		<bitfield name="EVENT" low="0" high="6" type="vgt_event_type"/>
+	</reg32>
+
+	<reg32 offset="0xbb08" name="HLSQ_INVALIDATE_CMD" variants="A6XX" usage="cmd">
+		<doc>
+			This register clears pending loads queued up by
+			CP_LOAD_STATE6. Each bit resets a particular kind(s) of
+			CP_LOAD_STATE6.
+		</doc>
+
+		<!-- per-stage state: shader, non-bindless UBO, textures, and samplers -->
+		<bitfield name="VS_STATE" pos="0" type="boolean"/>
+		<bitfield name="HS_STATE" pos="1" type="boolean"/>
+		<bitfield name="DS_STATE" pos="2" type="boolean"/>
+		<bitfield name="GS_STATE" pos="3" type="boolean"/>
+		<bitfield name="FS_STATE" pos="4" type="boolean"/>
+		<bitfield name="CS_STATE" pos="5" type="boolean"/>
+
+		<bitfield name="CS_IBO" pos="6" type="boolean"/>
+		<bitfield name="GFX_IBO" pos="7" type="boolean"/>
+
+		<!-- Note: these only do something when HLSQ_SHARED_CONSTS is set to 1 -->
+		<bitfield name="CS_SHARED_CONST" pos="19" type="boolean"/>
+		<bitfield name="GFX_SHARED_CONST" pos="8" type="boolean"/>
+
+		<!-- SS6_BINDLESS: one bit per bindless base -->
+		<bitfield name="CS_BINDLESS" low="9" high="13" type="hex"/>
+		<bitfield name="GFX_BINDLESS" low="14" high="18" type="hex"/>
+	</reg32>
+
+	<reg32 offset="0xab1c" name="HLSQ_DRAW_CMD" variants="A7XX-">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+
+	<reg32 offset="0xab1d" name="HLSQ_DISPATCH_CMD" variants="A7XX-">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+
+	<reg32 offset="0xab1e" name="HLSQ_EVENT_CMD" variants="A7XX-">
+		<bitfield name="STATE_ID" low="16" high="23"/>
+		<bitfield name="EVENT" low="0" high="6" type="vgt_event_type"/>
+	</reg32>
+
+	<reg32 offset="0xab1f" name="HLSQ_INVALIDATE_CMD" variants="A7XX-" usage="cmd">
+		<doc>
+			This register clears pending loads queued up by
+			CP_LOAD_STATE6. Each bit resets a particular kind(s) of
+			CP_LOAD_STATE6.
+		</doc>
+
+		<!-- per-stage state: shader, non-bindless UBO, textures, and samplers -->
+		<bitfield name="VS_STATE" pos="0" type="boolean"/>
+		<bitfield name="HS_STATE" pos="1" type="boolean"/>
+		<bitfield name="DS_STATE" pos="2" type="boolean"/>
+		<bitfield name="GS_STATE" pos="3" type="boolean"/>
+		<bitfield name="FS_STATE" pos="4" type="boolean"/>
+		<bitfield name="CS_STATE" pos="5" type="boolean"/>
+
+		<bitfield name="CS_IBO" pos="6" type="boolean"/>
+		<bitfield name="GFX_IBO" pos="7" type="boolean"/>
+
+		<!-- SS6_BINDLESS: one bit per bindless base -->
+		<bitfield name="CS_BINDLESS" low="9" high="16" type="hex"/>
+		<bitfield name="GFX_BINDLESS" low="17" high="24" type="hex"/>
+	</reg32>
+
+	<reg32 offset="0xbb10" name="HLSQ_FS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A6XX" usage="rp_blit"/>
+	<reg32 offset="0xab03" name="HLSQ_FS_CNTL" type="a6xx_hlsq_xs_cntl" variants="A7XX-" usage="rp_blit"/>
+
+	<array offset="0xab40" name="HLSQ_SHARED_CONSTS_IMM" stride="1" length="64" variants="A7XX-"/>
+
+	<reg32 offset="0xbb11" name="HLSQ_SHARED_CONSTS" variants="A6XX" usage="cmd">
+		<doc>
+			Shared constants are intended to be used for Vulkan push
+			constants. When enabled, 8 vec4's are reserved in the FS
+			const pool and 16 in the geometry const pool although
+			only 8 are actually used (why?) and they are mapped to
+			c504-c511 in each stage. Both VS and FS shared consts
+			are written using ST6_CONSTANTS/SB6_IBO, so that both
+			the geometry and FS shared consts can be written at once
+			by using CP_LOAD_STATE6 rather than
+			CP_LOAD_STATE6_FRAG/CP_LOAD_STATE6_GEOM. In addition
+			DST_OFF and NUM_UNIT are in units of dwords instead of
+			vec4's.
+
+			There is also a separate shared constant pool for CS,
+			which is loaded through CP_LOAD_STATE6_FRAG with
+			ST6_UBO/ST6_IBO. However the only real difference for CS
+			is the dword units.
+		</doc>
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+	</reg32>
+
+	<!-- mirror of SP_BINDLESS_BASE -->
+	<array offset="0xbb20" name="HLSQ_BINDLESS_BASE" stride="2" length="5" variants="A6XX" usage="cmd">
+		<reg64 offset="0" name="DESCRIPTOR">
+			<bitfield name="DESC_SIZE" low="0" high="1" type="a6xx_bindless_descriptor_size"/>
+			<bitfield name="ADDR" low="2" high="63" shr="2" type="address"/>
+		</reg64>
+	</array>
+
+	<reg32 offset="0xbd80" name="HLSQ_2D_EVENT_CMD">
+		<bitfield name="STATE_ID" low="8" high="15"/>
+		<bitfield name="EVENT" low="0" high="6" type="vgt_event_type"/>
+	</reg32>
+
+	<reg32 offset="0xbe00" name="HLSQ_UNKNOWN_BE00" variants="A6XX" usage="cmd"/> <!-- all bits valid except bit 29 -->
+	<reg32 offset="0xbe01" name="HLSQ_UNKNOWN_BE01" low="4" high="6" variants="A6XX" usage="cmd"/>
+	<reg32 offset="0xbe04" name="HLSQ_DBG_ECO_CNTL" variants="A6XX" usage="cmd"/>
+	<reg32 offset="0xbe05" name="HLSQ_ADDR_MODE_CNTL" type="a5xx_address_mode"/>
+	<reg32 offset="0xbe08" name="HLSQ_UNKNOWN_BE08" low="0" high="15"/>
+	<array offset="0xbe10" name="HLSQ_PERFCTR_HLSQ_SEL" stride="1" length="6"/>
+
+	<!-- TODO: some valid registers between 0xbe20 and 0xbe33 -->
+	<reg32 offset="0xbe22" name="HLSQ_CONTEXT_SWITCH_GFX_PREEMPTION_SAFE_MODE"/>
+
+	<reg32 offset="0xc000" name="SP_AHB_READ_APERTURE" variants="A7XX-"/>
+
+	<!-- Don't know if these are SP, always 0 -->
+	<reg64 offset="0x0ce2" name="SP_UNKNOWN_0CE2" variants="A7XX-" usage="cmd"/>
+	<reg64 offset="0x0ce4" name="SP_UNKNOWN_0CE4" variants="A7XX-" usage="cmd"/>
+	<reg64 offset="0x0ce6" name="SP_UNKNOWN_0CE6" variants="A7XX-" usage="cmd"/>
+
+	<!--
+		These special registers signal the beginning/end of an event
+		sequence. The sequence used internally for an event looks like:
+		- write EVENT_CMD pipe register
+		- write CP_EVENT_START
+		- write HLSQ_EVENT_CMD with event or HLSQ_DRAW_CMD
+		- write PC_EVENT_CMD with event or PC_DRAW_CMD
+		- write HLSQ_EVENT_CMD(CONTEXT_DONE)
+		- write PC_EVENT_CMD(CONTEXT_DONE)
+		- write CP_EVENT_END
+		Writing to CP_EVENT_END seems to actually trigger the context roll
+	-->
+	<reg32 offset="0xd600" name="CP_EVENT_START">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+	<reg32 offset="0xd601" name="CP_EVENT_END">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+	<reg32 offset="0xd700" name="CP_2D_EVENT_START">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+	<reg32 offset="0xd701" name="CP_2D_EVENT_END">
+		<bitfield name="STATE_ID" low="0" high="7"/>
+	</reg32>
+</domain>
+
+<!-- Seems basically the same as a5xx, maybe move to common.xml.. -->
+<domain name="A6XX_TEX_SAMP" width="32">
+	<doc>Texture sampler dwords</doc>
+	<enum name="a6xx_tex_filter"> <!-- same as a4xx? -->
+		<value name="A6XX_TEX_NEAREST" value="0"/>
+		<value name="A6XX_TEX_LINEAR" value="1"/>
+		<value name="A6XX_TEX_ANISO" value="2"/>
+		<value name="A6XX_TEX_CUBIC" value="3"/> <!-- a650 only -->
+	</enum>
+	<enum name="a6xx_tex_clamp"> <!-- same as a4xx? -->
+		<value name="A6XX_TEX_REPEAT" value="0"/>
+		<value name="A6XX_TEX_CLAMP_TO_EDGE" value="1"/>
+		<value name="A6XX_TEX_MIRROR_REPEAT" value="2"/>
+		<value name="A6XX_TEX_CLAMP_TO_BORDER" value="3"/>
+		<value name="A6XX_TEX_MIRROR_CLAMP" value="4"/>
+	</enum>
+	<enum name="a6xx_tex_aniso"> <!-- same as a4xx? -->
+		<value name="A6XX_TEX_ANISO_1" value="0"/>
+		<value name="A6XX_TEX_ANISO_2" value="1"/>
+		<value name="A6XX_TEX_ANISO_4" value="2"/>
+		<value name="A6XX_TEX_ANISO_8" value="3"/>
+		<value name="A6XX_TEX_ANISO_16" value="4"/>
+	</enum>
+	<enum name="a6xx_reduction_mode">
+		<value name="A6XX_REDUCTION_MODE_AVERAGE" value="0"/>
+		<value name="A6XX_REDUCTION_MODE_MIN" value="1"/>
+		<value name="A6XX_REDUCTION_MODE_MAX" value="2"/>
+	</enum>
+
+	<reg32 offset="0" name="0">
+		<bitfield name="MIPFILTER_LINEAR_NEAR" pos="0" type="boolean"/>
+		<bitfield name="XY_MAG" low="1" high="2" type="a6xx_tex_filter"/>
+		<bitfield name="XY_MIN" low="3" high="4" type="a6xx_tex_filter"/>
+		<bitfield name="WRAP_S" low="5" high="7" type="a6xx_tex_clamp"/>
+		<bitfield name="WRAP_T" low="8" high="10" type="a6xx_tex_clamp"/>
+		<bitfield name="WRAP_R" low="11" high="13" type="a6xx_tex_clamp"/>
+		<bitfield name="ANISO" low="14" high="16" type="a6xx_tex_aniso"/>
+		<bitfield name="LOD_BIAS" low="19" high="31" type="fixed" radix="8"/><!-- no idea how many bits for real -->
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="CLAMPENABLE" pos="0" type="boolean">
+			<doc>
+				clamp result to [0, 1] if the format is unorm or
+				[-1, 1] if the format is snorm, *after*
+				filtering. Has no effect for other formats.
+			</doc>
+		</bitfield>
+		<bitfield name="COMPARE_FUNC" low="1" high="3" type="adreno_compare_func"/>
+		<bitfield name="CUBEMAPSEAMLESSFILTOFF" pos="4" type="boolean"/>
+		<bitfield name="UNNORM_COORDS" pos="5" type="boolean"/>
+		<bitfield name="MIPFILTER_LINEAR_FAR" pos="6" type="boolean"/>
+		<bitfield name="MAX_LOD" low="8" high="19" type="ufixed" radix="8"/>
+		<bitfield name="MIN_LOD" low="20" high="31" type="ufixed" radix="8"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="REDUCTION_MODE" low="0" high="1" type="a6xx_reduction_mode"/>
+		<bitfield name="CHROMA_LINEAR" pos="5" type="boolean"/>
+		<bitfield name="BCOLOR" low="7" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3"/>
+</domain>
+
+<domain name="A6XX_TEX_CONST" width="32" varset="chip">
+	<doc>Texture constant dwords</doc>
+	<enum name="a6xx_tex_swiz"> <!-- same as a4xx? -->
+		<value name="A6XX_TEX_X" value="0"/>
+		<value name="A6XX_TEX_Y" value="1"/>
+		<value name="A6XX_TEX_Z" value="2"/>
+		<value name="A6XX_TEX_W" value="3"/>
+		<value name="A6XX_TEX_ZERO" value="4"/>
+		<value name="A6XX_TEX_ONE" value="5"/>
+	</enum>
+	<enum name="a6xx_tex_type"> <!-- same as a4xx? -->
+		<value name="A6XX_TEX_1D" value="0"/>
+		<value name="A6XX_TEX_2D" value="1"/>
+		<value name="A6XX_TEX_CUBE" value="2"/>
+		<value name="A6XX_TEX_3D" value="3"/>
+		<value name="A6XX_TEX_BUFFER" value="4"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="TILE_MODE" low="0" high="1" type="a6xx_tile_mode"/>
+		<bitfield name="SRGB" pos="2" type="boolean"/>
+		<bitfield name="SWIZ_X" low="4" high="6" type="a6xx_tex_swiz"/>
+		<bitfield name="SWIZ_Y" low="7" high="9" type="a6xx_tex_swiz"/>
+		<bitfield name="SWIZ_Z" low="10" high="12" type="a6xx_tex_swiz"/>
+		<bitfield name="SWIZ_W" low="13" high="15" type="a6xx_tex_swiz"/>
+		<bitfield name="MIPLVLS" low="16" high="19" type="uint"/>
+		<!-- overlaps with MIPLVLS -->
+		<bitfield name="CHROMA_MIDPOINT_X" pos="16" type="boolean"/>
+		<bitfield name="CHROMA_MIDPOINT_Y" pos="18" type="boolean"/>
+		<bitfield name="SAMPLES" low="20" high="21" type="a3xx_msaa_samples"/>
+		<bitfield name="FMT" low="22" high="29" type="a6xx_format"/>
+		<!--
+			Why is the swap needed in addition to SWIZ_*? The swap
+			is performed before border color replacement, while the
+			swizzle is applied after after it.
+		-->
+		<bitfield name="SWAP" low="30" high="31" type="a3xx_color_swap"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="WIDTH" low="0" high="14" type="uint"/>
+		<bitfield name="HEIGHT" low="15" high="29" type="uint"/>
+		<bitfield name="MUTABLEEN" pos="31" type="boolean" variants="A7XX-"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<!--
+			These fields overlap PITCH, and are used instead of
+			PITCH/PITCHALIGN when TYPE is A6XX_TEX_BUFFER.
+		 -->
+		<doc> probably for D3D structured UAVs, normally set to 1 </doc>
+		<bitfield name="STRUCTSIZETEXELS" low="4" high="15" type="uint"/>
+		<bitfield name="STARTOFFSETTEXELS" low="16" high="21" type="uint"/>
+
+		<!-- minimum pitch (for mipmap levels): log2(pitchalign / 64) -->
+		<bitfield name="PITCHALIGN" low="0" high="3" type="uint"/>
+		<doc>Pitch in bytes (so actually stride)</doc>
+		<bitfield name="PITCH" low="7" high="28" type="uint"/>
+		<bitfield name="TYPE" low="29" high="31" type="a6xx_tex_type"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<!--
+		ARRAY_PITCH is basically LAYERSZ for the first mipmap level, and
+		for 3d textures (laid out mipmap level first) MIN_LAYERSZ is the
+		layer size at the point that it stops being reduced moving to
+		higher (smaller) mipmap levels
+		 -->
+		<bitfield name="ARRAY_PITCH" low="0" high="22" shr="12" type="uint"/>
+		<bitfield name="MIN_LAYERSZ" low="23" high="26" shr="12"/>
+		<!--
+		by default levels with w < 16 are linear
+		TILE_ALL makes all levels have tiling
+		seems required when using UBWC, since all levels have UBWC (can possibly be disabled?)
+		 -->
+		<bitfield name="TILE_ALL" pos="27" type="boolean"/>
+		<bitfield name="FLAG" pos="28" type="boolean"/>
+	</reg32>
+	<!-- for 2-3 plane format, BASE is flag buffer address (if enabled)
+	     the address of the non-flag base buffer is determined automatically,
+	     and must follow the flag buffer
+	 -->
+	<reg32 offset="4" name="4">
+		<bitfield name="BASE_LO" low="5" high="31" shr="5"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="BASE_HI" low="0" high="16"/>
+		<bitfield name="DEPTH" low="17" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="6" name="6">
+		<!-- overlaps with PLANE_PITCH -->
+		<bitfield name="MIN_LOD_CLAMP" low="0" high="11" type="ufixed" radix="8"/>
+		<!-- pitch for plane 2 / plane 3 -->
+		<bitfield name="PLANE_PITCH" low="8" high="31" type="uint"/>
+	</reg32>
+	<!-- 7/8 is plane 2 address for planar formats -->
+	<reg32 offset="7" name="7">
+		<bitfield name="FLAG_LO" low="5" high="31" shr="5"/>
+	</reg32>
+	<reg32 offset="8" name="8">
+		<bitfield name="FLAG_HI" low="0" high="16"/>
+	</reg32>
+	<!-- 9/10 is plane 3 address for planar formats -->
+	<reg32 offset="9" name="9">
+		<bitfield name="FLAG_BUFFER_ARRAY_PITCH" low="0" high="16" shr="4" type="uint"/>
+	</reg32>
+	<reg32 offset="10" name="10">
+		<bitfield name="FLAG_BUFFER_PITCH" low="0" high="6" shr="6" type="uint"/>
+		<!-- log2 size of the first level, required for mipmapping -->
+		<bitfield name="FLAG_BUFFER_LOGW" low="8" high="11" type="uint"/>
+		<bitfield name="FLAG_BUFFER_LOGH" low="12" high="15" type="uint"/>
+	</reg32>
+	<reg32 offset="11" name="11"/>
+	<reg32 offset="12" name="12"/>
+	<reg32 offset="13" name="13"/>
+	<reg32 offset="14" name="14"/>
+	<reg32 offset="15" name="15"/>
+</domain>
+
+<domain name="A6XX_UBO" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="BASE_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="BASE_HI" low="0" high="16"/>
+		<bitfield name="SIZE" low="17" high="31"/> <!-- size in vec4 (4xDWORD) units -->
+	</reg32>
+</domain>
+
+<domain name="A6XX_PDC" width="32">
+	<reg32 offset="0x1140" name="GPU_ENABLE_PDC"/>
+	<reg32 offset="0x1148" name="GPU_SEQ_START_ADDR"/>
+	<reg32 offset="0x1540" name="GPU_TCS0_CONTROL"/>
+	<reg32 offset="0x1541" name="GPU_TCS0_CMD_ENABLE_BANK"/>
+	<reg32 offset="0x1542" name="GPU_TCS0_CMD_WAIT_FOR_CMPL_BANK"/>
+	<reg32 offset="0x1543" name="GPU_TCS0_CMD0_MSGID"/>
+	<reg32 offset="0x1544" name="GPU_TCS0_CMD0_ADDR"/>
+	<reg32 offset="0x1545" name="GPU_TCS0_CMD0_DATA"/>
+	<reg32 offset="0x1572" name="GPU_TCS1_CONTROL"/>
+	<reg32 offset="0x1573" name="GPU_TCS1_CMD_ENABLE_BANK"/>
+	<reg32 offset="0x1574" name="GPU_TCS1_CMD_WAIT_FOR_CMPL_BANK"/>
+	<reg32 offset="0x1575" name="GPU_TCS1_CMD0_MSGID"/>
+	<reg32 offset="0x1576" name="GPU_TCS1_CMD0_ADDR"/>
+	<reg32 offset="0x1577" name="GPU_TCS1_CMD0_DATA"/>
+	<reg32 offset="0x15A4" name="GPU_TCS2_CONTROL"/>
+	<reg32 offset="0x15A5" name="GPU_TCS2_CMD_ENABLE_BANK"/>
+	<reg32 offset="0x15A6" name="GPU_TCS2_CMD_WAIT_FOR_CMPL_BANK"/>
+	<reg32 offset="0x15A7" name="GPU_TCS2_CMD0_MSGID"/>
+	<reg32 offset="0x15A8" name="GPU_TCS2_CMD0_ADDR"/>
+	<reg32 offset="0x15A9" name="GPU_TCS2_CMD0_DATA"/>
+	<reg32 offset="0x15D6" name="GPU_TCS3_CONTROL"/>
+	<reg32 offset="0x15D7" name="GPU_TCS3_CMD_ENABLE_BANK"/>
+	<reg32 offset="0x15D8" name="GPU_TCS3_CMD_WAIT_FOR_CMPL_BANK"/>
+	<reg32 offset="0x15D9" name="GPU_TCS3_CMD0_MSGID"/>
+	<reg32 offset="0x15DA" name="GPU_TCS3_CMD0_ADDR"/>
+	<reg32 offset="0x15DB" name="GPU_TCS3_CMD0_DATA"/>
+</domain>
+
+<domain name="A6XX_PDC_GPU_SEQ" width="32">
+	<reg32 offset="0x0" name="MEM_0"/>
+</domain>
+
+<domain name="A6XX_CX_DBGC" width="32">
+	<reg32 offset="0x0000" name="CFG_DBGBUS_SEL_A">
+		<bitfield high="7" low="0" name="PING_INDEX"/>
+		<bitfield high="15" low="8" name="PING_BLK_SEL"/>
+	</reg32>
+	<reg32 offset="0x0001" name="CFG_DBGBUS_SEL_B"/>
+	<reg32 offset="0x0002" name="CFG_DBGBUS_SEL_C"/>
+	<reg32 offset="0x0003" name="CFG_DBGBUS_SEL_D"/>
+	<reg32 offset="0x0004" name="CFG_DBGBUS_CNTLT">
+		<bitfield high="5" low="0" name="TRACEEN"/>
+		<bitfield high="14" low="12" name="GRANU"/>
+		<bitfield high="31" low="28" name="SEGT"/>
+	</reg32>
+	<reg32 offset="0x0005" name="CFG_DBGBUS_CNTLM">
+		<bitfield high="27" low="24" name="ENABLE"/>
+	</reg32>
+	<reg32 offset="0x0008" name="CFG_DBGBUS_IVTL_0"/>
+	<reg32 offset="0x0009" name="CFG_DBGBUS_IVTL_1"/>
+	<reg32 offset="0x000a" name="CFG_DBGBUS_IVTL_2"/>
+	<reg32 offset="0x000b" name="CFG_DBGBUS_IVTL_3"/>
+	<reg32 offset="0x000c" name="CFG_DBGBUS_MASKL_0"/>
+	<reg32 offset="0x000d" name="CFG_DBGBUS_MASKL_1"/>
+	<reg32 offset="0x000e" name="CFG_DBGBUS_MASKL_2"/>
+	<reg32 offset="0x000f" name="CFG_DBGBUS_MASKL_3"/>
+	<reg32 offset="0x0010" name="CFG_DBGBUS_BYTEL_0">
+		<bitfield high="3" low="0" name="BYTEL0"/>
+		<bitfield high="7" low="4" name="BYTEL1"/>
+		<bitfield high="11" low="8" name="BYTEL2"/>
+		<bitfield high="15" low="12" name="BYTEL3"/>
+		<bitfield high="19" low="16" name="BYTEL4"/>
+		<bitfield high="23" low="20" name="BYTEL5"/>
+		<bitfield high="27" low="24" name="BYTEL6"/>
+		<bitfield high="31" low="28" name="BYTEL7"/>
+	</reg32>
+	<reg32 offset="0x0011" name="CFG_DBGBUS_BYTEL_1">
+		<bitfield high="3" low="0" name="BYTEL8"/>
+		<bitfield high="7" low="4" name="BYTEL9"/>
+		<bitfield high="11" low="8" name="BYTEL10"/>
+		<bitfield high="15" low="12" name="BYTEL11"/>
+		<bitfield high="19" low="16" name="BYTEL12"/>
+		<bitfield high="23" low="20" name="BYTEL13"/>
+		<bitfield high="27" low="24" name="BYTEL14"/>
+		<bitfield high="31" low="28" name="BYTEL15"/>
+	</reg32>
+
+	<reg32 offset="0x002f" name="CFG_DBGBUS_TRACE_BUF1"/>
+	<reg32 offset="0x0030" name="CFG_DBGBUS_TRACE_BUF2"/>
+</domain>
+
+<domain name="A6XX_CX_MISC" width="32" prefix="variant" varset="chip">
+	<reg32 offset="0x0001" name="SYSTEM_CACHE_CNTL_0"/>
+	<reg32 offset="0x0002" name="SYSTEM_CACHE_CNTL_1"/>
+	<reg32 offset="0x0039" name="CX_MISC_TCM_RET_CNTL" variants="A7XX-"/>
+	<reg32 offset="0x0400" name="CX_MISC_SW_FUSE_VALUE" variants="A7XX-">
+		<bitfield pos="0" name="FASTBLEND" type="boolean"/>
+		<bitfield pos="1" name="LPAC" type="boolean"/>
+		<bitfield pos="2" name="RAYTRACING" type="boolean"/>
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/adreno/a6xx_gmu.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/adreno/a6xx_gmu.xml
@@ -0,0 +1,228 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="adreno/adreno_common.xml"/>
+
+<domain name="A6XX" width="32" prefix="variant" varset="chip">
+
+	<bitset name="A6XX_GMU_GPU_IDLE_STATUS">
+		<bitfield name="BUSY_IGN_AHB" pos="23"/>
+		<bitfield name="CX_GX_CPU_BUSY_IGN_AHB" pos="30"/>
+	</bitset>
+
+	<bitset name="A6XX_GMU_OOB">
+		<bitfield name="BOOT_SLUMBER_SET_MASK" pos="22"/>
+		<bitfield name="BOOT_SLUMBER_CHECK_MASK" pos="30"/>
+		<bitfield name="BOOT_SLUMBER_CLEAR_MASK" pos="30"/>
+		<bitfield name="DCVS_SET_MASK" pos="23"/>
+		<bitfield name="DCVS_CHECK_MASK" pos="31"/>
+		<bitfield name="DCVS_CLEAR_MASK" pos="31"/>
+		<bitfield name="GPU_SET_MASK" pos="18"/>
+		<bitfield name="GPU_CHECK_MASK" pos="26"/>
+		<bitfield name="GPU_CLEAR_MASK" pos="26"/>
+		<bitfield name="PERFCNTR_SET_MASK" pos="17"/>
+		<bitfield name="PERFCNTR_CHECK_MASK" pos="25"/>
+		<bitfield name="PERFCNTR_CLEAR_MASK" pos="25"/>
+	</bitset>
+
+	<bitset name="A6XX_HFI_IRQ">
+		<bitfield name="MSGQ_MASK" pos="0" />
+		<bitfield name="DSGQ_MASK" pos="1"/>
+		<bitfield name="BLOCKED_MSG_MASK" pos="2"/>
+		<bitfield name="CM3_FAULT_MASK" pos="23"/>
+		<bitfield name="GMU_ERR_MASK" low="16" high="22"/>
+		<bitfield name="OOB_MASK" low="24" high="31"/>
+	</bitset>
+
+	<bitset name="A6XX_HFI_H2F">
+		<bitfield name="IRQ_MASK_BIT" pos="0" />
+	</bitset>
+
+	<reg32 offset="0x80" name="GPU_GMU_GX_SPTPRAC_CLOCK_CONTROL"/>
+	<reg32 offset="0x81" name="GMU_GX_SPTPRAC_POWER_CONTROL"/>
+	<reg32 offset="0xc00" name="GMU_CM3_ITCM_START"/>
+	<reg32 offset="0x1c00" name="GMU_CM3_DTCM_START"/>
+	<reg32 offset="0x23f0" name="GMU_NMI_CONTROL_STATUS"/>
+	<reg32 offset="0x23f8" name="GMU_BOOT_SLUMBER_OPTION"/>
+	<reg32 offset="0x23f9" name="GMU_GX_VOTE_IDX"/>
+	<reg32 offset="0x23fa" name="GMU_MX_VOTE_IDX"/>
+	<reg32 offset="0x23fc" name="GMU_DCVS_ACK_OPTION"/>
+	<reg32 offset="0x23fd" name="GMU_DCVS_PERF_SETTING"/>
+	<reg32 offset="0x23fe" name="GMU_DCVS_BW_SETTING"/>
+	<reg32 offset="0x23ff" name="GMU_DCVS_RETURN"/>
+	<reg32 offset="0x4c00" name="GMU_ICACHE_CONFIG"/>
+	<reg32 offset="0x4c01" name="GMU_DCACHE_CONFIG"/>
+	<reg32 offset="0x4c0f" name="GMU_SYS_BUS_CONFIG"/>
+	<reg32 offset="0x5000" name="GMU_CM3_SYSRESET"/>
+	<reg32 offset="0x5001" name="GMU_CM3_BOOT_CONFIG"/>
+	<reg32 offset="0x501a" name="GMU_CM3_FW_BUSY"/>
+	<reg32 offset="0x501c" name="GMU_CM3_FW_INIT_RESULT"/>
+	<reg32 offset="0x502d" name="GMU_CM3_CFG"/>
+	<reg32 offset="0x5040" name="GMU_CX_GMU_POWER_COUNTER_ENABLE"/>
+	<reg32 offset="0x5041" name="GMU_CX_GMU_POWER_COUNTER_SELECT_0"/>
+	<reg32 offset="0x5042" name="GMU_CX_GMU_POWER_COUNTER_SELECT_1"/>
+	<reg32 offset="0x5044" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_0_L"/>
+	<reg32 offset="0x5045" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_0_H"/>
+	<reg32 offset="0x5046" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_1_L"/>
+	<reg32 offset="0x5047" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_1_H"/>
+	<reg32 offset="0x5048" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_2_L"/>
+	<reg32 offset="0x5049" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_2_H"/>
+	<reg32 offset="0x504a" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_3_L"/>
+	<reg32 offset="0x504b" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_3_H"/>
+	<reg32 offset="0x504c" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_4_L"/>
+	<reg32 offset="0x504d" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_4_H"/>
+	<reg32 offset="0x504e" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_5_L"/>
+	<reg32 offset="0x504f" name="GMU_CX_GMU_POWER_COUNTER_XOCLK_5_H"/>
+	<reg32 offset="0x50c0" name="GMU_PWR_COL_INTER_FRAME_CTRL">
+		<bitfield name="IFPC_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="HM_POWER_COLLAPSE_ENABLE" pos="1" type="boolean"/>
+		<bitfield name="SPTPRAC_POWER_CONTROL_ENABLE" pos="2" type="boolean"/>
+		<bitfield name="NUM_PASS_SKIPS" low="10" high="13"/>
+		<bitfield name="MIN_PASS_LENGTH" low="14" high="31"/>
+	</reg32>
+	<reg32 offset="0x50c1" name="GMU_PWR_COL_INTER_FRAME_HYST"/>
+	<reg32 offset="0x50c2" name="GMU_PWR_COL_SPTPRAC_HYST"/>
+	<reg32 offset="0x50d0" name="GMU_SPTPRAC_PWR_CLK_STATUS">
+		<bitfield name="SPTPRAC_GDSC_POWERING_OFF" pos="0" type="boolean"/>
+		<bitfield name="SPTPRAC_GDSC_POWERING_ON" pos="1" type="boolean"/>
+		<bitfield name="SPTPRAC_GDSC_POWER_OFF" pos="2" type="boolean"/>
+		<bitfield name="SPTPRAC_GDSC_POWER_ON" pos="3" type="boolean"/>
+		<bitfield name="SP_CLOCK_OFF" pos="4" type="boolean"/>
+		<bitfield name="GMU_UP_POWER_STATE" pos="5" type="boolean"/>
+		<bitfield name="GX_HM_GDSC_POWER_OFF" pos="6" type="boolean"/>
+		<bitfield name="GX_HM_CLK_OFF" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x50e4" name="GMU_GPU_NAP_CTRL">
+		<bitfield name="HW_NAP_ENABLE" pos="0"/>
+		<bitfield name="SID" low="4" high="8"/>
+	</reg32>
+	<reg32 offset="0x50e8" name="GMU_RPMH_CTRL">
+		<bitfield name="RPMH_INTERFACE_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="LLC_VOTE_ENABLE" pos="4" type="boolean"/>
+		<bitfield name="DDR_VOTE_ENABLE" pos="8" type="boolean"/>
+		<bitfield name="MX_VOTE_ENABLE" pos="9" type="boolean"/>
+		<bitfield name="CX_VOTE_ENABLE" pos="10" type="boolean"/>
+		<bitfield name="GFX_VOTE_ENABLE" pos="11" type="boolean"/>
+		<bitfield name="DDR_MIN_VOTE_ENABLE" pos="12" type="boolean"/>
+		<bitfield name="MX_MIN_VOTE_ENABLE" pos="13" type="boolean"/>
+		<bitfield name="CX_MIN_VOTE_ENABLE" pos="14" type="boolean"/>
+		<bitfield name="GFX_MIN_VOTE_ENABLE" pos="15" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x50e9" name="GMU_RPMH_HYST_CTRL"/>
+	<reg32 offset="0x50ec" name="GPU_GMU_CX_GMU_RPMH_POWER_STATE"/>
+	<reg32 offset="0x50f0" name="GPU_GMU_CX_GMU_CX_FAL_INTF"/>
+	<reg32 offset="0x50f1" name="GPU_GMU_CX_GMU_CX_FALNEXT_INTF"/>
+	<reg32 offset="0x5100" name="GPU_GMU_CX_GMU_PWR_COL_CP_MSG"/>
+	<reg32 offset="0x5101" name="GPU_GMU_CX_GMU_PWR_COL_CP_RESP"/>
+	<reg32 offset="0x51f0" name="GMU_BOOT_KMD_LM_HANDSHAKE"/>
+	<reg32 offset="0x5157" name="GMU_LLM_GLM_SLEEP_CTRL"/>
+	<reg32 offset="0x5158" name="GMU_LLM_GLM_SLEEP_STATUS"/>
+	<reg32 offset="0x5088" name="GMU_ALWAYS_ON_COUNTER_L"/>
+	<reg32 offset="0x5089" name="GMU_ALWAYS_ON_COUNTER_H"/>
+	<reg32 offset="0x50c3" name="GMU_GMU_PWR_COL_KEEPALIVE"/>
+	<reg32 offset="0x5180" name="GMU_HFI_CTRL_STATUS"/>
+	<reg32 offset="0x5181" name="GMU_HFI_VERSION_INFO"/>
+	<reg32 offset="0x5182" name="GMU_HFI_SFR_ADDR"/>
+	<reg32 offset="0x5183" name="GMU_HFI_MMAP_ADDR"/>
+	<reg32 offset="0x5184" name="GMU_HFI_QTBL_INFO"/>
+	<reg32 offset="0x5185" name="GMU_HFI_QTBL_ADDR"/>
+	<reg32 offset="0x5186" name="GMU_HFI_CTRL_INIT"/>
+	<reg32 offset="0x5190" name="GMU_GMU2HOST_INTR_SET"/>
+	<reg32 offset="0x5191" name="GMU_GMU2HOST_INTR_CLR"/>
+	<reg32 offset="0x5192" name="GMU_GMU2HOST_INTR_INFO">
+		<bitfield name="MSGQ" pos="0" type="boolean"/>
+		<bitfield name="CM3_FAULT" pos="23" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x5193" name="GMU_GMU2HOST_INTR_MASK"/>
+	<reg32 offset="0x5194" name="GMU_HOST2GMU_INTR_SET"/>
+	<reg32 offset="0x5195" name="GMU_HOST2GMU_INTR_CLR"/>
+	<reg32 offset="0x5196" name="GMU_HOST2GMU_INTR_RAW_INFO"/>
+	<reg32 offset="0x5197" name="GMU_HOST2GMU_INTR_EN_0"/>
+	<reg32 offset="0x5198" name="GMU_HOST2GMU_INTR_EN_1"/>
+	<reg32 offset="0x5199" name="GMU_HOST2GMU_INTR_EN_2"/>
+	<reg32 offset="0x519a" name="GMU_HOST2GMU_INTR_EN_3"/>
+	<reg32 offset="0x519b" name="GMU_HOST2GMU_INTR_INFO_0"/>
+	<reg32 offset="0x519c" name="GMU_HOST2GMU_INTR_INFO_1"/>
+	<reg32 offset="0x519d" name="GMU_HOST2GMU_INTR_INFO_2"/>
+	<reg32 offset="0x519e" name="GMU_HOST2GMU_INTR_INFO_3"/>
+	<reg32 offset="0x51c5" name="GMU_GENERAL_0"/>
+	<reg32 offset="0x51c6" name="GMU_GENERAL_1"/>
+	<reg32 offset="0x51cb" name="GMU_GENERAL_6"/>
+	<reg32 offset="0x51cc" name="GMU_GENERAL_7"/>
+	<reg32 offset="0x51cd" name="GMU_GENERAL_8" variants="A7XX"/>
+	<reg32 offset="0x51ce" name="GMU_GENERAL_9" variants="A7XX"/>
+	<reg32 offset="0x51cf" name="GMU_GENERAL_10" variants="A7XX"/>
+	<reg32 offset="0x515d" name="GMU_ISENSE_CTRL"/>
+	<reg32 offset="0x8920" name="GPU_CS_ENABLE_REG"/>
+	<reg32 offset="0x515d" name="GPU_GMU_CX_GMU_ISENSE_CTRL"/>
+	<reg32 offset="0x8578" name="GPU_CS_AMP_CALIBRATION_CONTROL3"/>
+	<reg32 offset="0x8558" name="GPU_CS_AMP_CALIBRATION_CONTROL2"/>
+	<reg32 offset="0x8580" name="GPU_CS_A_SENSOR_CTRL_0"/>
+	<reg32 offset="0x27ada" name="GPU_CS_A_SENSOR_CTRL_2"/>
+	<reg32 offset="0x881a" name="GPU_CS_SENSOR_GENERAL_STATUS"/>
+	<reg32 offset="0x8957" name="GPU_CS_AMP_CALIBRATION_CONTROL1"/>
+	<reg32 offset="0x881a" name="GPU_CS_SENSOR_GENERAL_STATUS"/>
+	<reg32 offset="0x881d" name="GPU_CS_AMP_CALIBRATION_STATUS1_0"/>
+	<reg32 offset="0x881f" name="GPU_CS_AMP_CALIBRATION_STATUS1_2"/>
+	<reg32 offset="0x8821" name="GPU_CS_AMP_CALIBRATION_STATUS1_4"/>
+	<reg32 offset="0x8965" name="GPU_CS_AMP_CALIBRATION_DONE"/>
+	<reg32 offset="0x896d" name="GPU_CS_AMP_PERIOD_CTRL"/>
+	<reg32 offset="0x8965" name="GPU_CS_AMP_CALIBRATION_DONE"/>
+	<reg32 offset="0x514d" name="GPU_GMU_CX_GMU_PWR_THRESHOLD"/>
+	<reg32 offset="0x9303" name="GMU_AO_INTERRUPT_EN"/>
+	<reg32 offset="0x9304" name="GMU_AO_HOST_INTERRUPT_CLR"/>
+	<reg32 offset="0x9305" name="GMU_AO_HOST_INTERRUPT_STATUS">
+		<bitfield name="WDOG_BITE" pos="0" type="boolean"/>
+		<bitfield name="RSCC_COMP" pos="1" type="boolean"/>
+		<bitfield name="VDROOP" pos="2" type="boolean"/>
+		<bitfield name="FENCE_ERR" pos="3" type="boolean"/>
+		<bitfield name="DBD_WAKEUP" pos="4" type="boolean"/>
+		<bitfield name="HOST_AHB_BUS_ERROR" pos="5" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x9306" name="GMU_AO_HOST_INTERRUPT_MASK"/>
+	<reg32 offset="0x9309" name="GPU_GMU_AO_GMU_CGC_MODE_CNTL"/>
+	<reg32 offset="0x930a" name="GPU_GMU_AO_GMU_CGC_DELAY_CNTL"/>
+	<reg32 offset="0x930b" name="GPU_GMU_AO_GMU_CGC_HYST_CNTL"/>
+	<reg32 offset="0x930c" name="GPU_GMU_AO_GPU_CX_BUSY_STATUS">
+		<bitfield name = "GPUBUSYIGNAHB" pos="23" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x930d" name="GPU_GMU_AO_GPU_CX_BUSY_STATUS2"/>
+	<reg32 offset="0x930e" name="GPU_GMU_AO_GPU_CX_BUSY_MASK"/>
+	<reg32 offset="0x9310" name="GMU_AO_AHB_FENCE_CTRL"/>
+	<reg32 offset="0x9313" name="GMU_AHB_FENCE_STATUS"/>
+	<reg32 offset="0x9314" name="GMU_AHB_FENCE_STATUS_CLR"/>
+	<reg32 offset="0x9315" name="GMU_RBBM_INT_UNMASKED_STATUS"/>
+	<reg32 offset="0x9316" name="GMU_AO_SPARE_CNTL"/>
+	<reg32 offset="0x9307" name="GMU_RSCC_CONTROL_REQ"/>
+	<reg32 offset="0x9308" name="GMU_RSCC_CONTROL_ACK"/>
+	<reg32 offset="0x9311" name="GMU_AHB_FENCE_RANGE_0"/>
+	<reg32 offset="0x9312" name="GMU_AHB_FENCE_RANGE_1"/>
+	<reg32 offset="0x9c03" name="GPU_CC_GX_GDSCR"/>
+	<reg32 offset="0x9d42" name="GPU_CC_GX_DOMAIN_MISC"/>
+	<reg32 offset="0xc001" name="GPU_CPR_FSM_CTL"/>
+
+	<!-- starts at offset 0x8c00 on most gpus -->
+	<reg32 offset="0x0004" name="GPU_RSCC_RSC_STATUS0_DRV0"/>
+	<reg32 offset="0x0008" name="RSCC_PDC_SEQ_START_ADDR"/>
+	<reg32 offset="0x0009" name="RSCC_PDC_MATCH_VALUE_LO"/>
+	<reg32 offset="0x000a" name="RSCC_PDC_MATCH_VALUE_HI"/>
+	<reg32 offset="0x000b" name="RSCC_PDC_SLAVE_ID_DRV0"/>
+	<reg32 offset="0x000d" name="RSCC_HIDDEN_TCS_CMD0_ADDR"/>
+	<reg32 offset="0x000e" name="RSCC_HIDDEN_TCS_CMD0_DATA"/>
+	<reg32 offset="0x0082" name="RSCC_TIMESTAMP_UNIT0_TIMESTAMP_L_DRV0"/>
+	<reg32 offset="0x0083" name="RSCC_TIMESTAMP_UNIT0_TIMESTAMP_H_DRV0"/>
+	<reg32 offset="0x0089" name="RSCC_TIMESTAMP_UNIT1_EN_DRV0"/>
+	<reg32 offset="0x008c" name="RSCC_TIMESTAMP_UNIT1_OUTPUT_DRV0"/>
+	<reg32 offset="0x0100" name="RSCC_OVERRIDE_START_ADDR"/>
+	<reg32 offset="0x0101" name="RSCC_SEQ_BUSY_DRV0"/>
+	<reg32 offset="0x0154" name="RSCC_SEQ_MEM_0_DRV0_A740" variants="A7XX"/>
+	<reg32 offset="0x0180" name="RSCC_SEQ_MEM_0_DRV0"/>
+	<reg32 offset="0x0346" name="RSCC_TCS0_DRV0_STATUS"/>
+	<reg32 offset="0x03ee" name="RSCC_TCS1_DRV0_STATUS"/>
+	<reg32 offset="0x0496" name="RSCC_TCS2_DRV0_STATUS"/>
+	<reg32 offset="0x053e" name="RSCC_TCS3_DRV0_STATUS"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/adreno/adreno_common.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/adreno/adreno_common.xml
@@ -0,0 +1,400 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<enum name="chip" bare="yes">
+	<value name="A2XX" value="2"/>
+	<value name="A3XX" value="3"/>
+	<value name="A4XX" value="4"/>
+	<value name="A5XX" value="5"/>
+	<value name="A6XX" value="6"/>
+	<value name="A7XX" value="7"/>
+</enum>
+
+<enum name="adreno_pa_su_sc_draw">
+	<value name="PC_DRAW_POINTS" value="0"/>
+	<value name="PC_DRAW_LINES" value="1"/>
+	<value name="PC_DRAW_TRIANGLES" value="2"/>
+</enum>
+
+<enum name="adreno_compare_func">
+	<value name="FUNC_NEVER" value="0"/>
+	<value name="FUNC_LESS" value="1"/>
+	<value name="FUNC_EQUAL" value="2"/>
+	<value name="FUNC_LEQUAL" value="3"/>
+	<value name="FUNC_GREATER" value="4"/>
+	<value name="FUNC_NOTEQUAL" value="5"/>
+	<value name="FUNC_GEQUAL" value="6"/>
+	<value name="FUNC_ALWAYS" value="7"/>
+</enum>
+
+<enum name="adreno_stencil_op">
+	<value name="STENCIL_KEEP" value="0"/>
+	<value name="STENCIL_ZERO" value="1"/>
+	<value name="STENCIL_REPLACE" value="2"/>
+	<value name="STENCIL_INCR_CLAMP" value="3"/>
+	<value name="STENCIL_DECR_CLAMP" value="4"/>
+	<value name="STENCIL_INVERT" value="5"/>
+	<value name="STENCIL_INCR_WRAP" value="6"/>
+	<value name="STENCIL_DECR_WRAP" value="7"/>
+</enum>
+
+<enum name="adreno_rb_blend_factor">
+	<value name="FACTOR_ZERO" value="0"/>
+	<value name="FACTOR_ONE" value="1"/>
+	<value name="FACTOR_SRC_COLOR" value="4"/>
+	<value name="FACTOR_ONE_MINUS_SRC_COLOR" value="5"/>
+	<value name="FACTOR_SRC_ALPHA" value="6"/>
+	<value name="FACTOR_ONE_MINUS_SRC_ALPHA" value="7"/>
+	<value name="FACTOR_DST_COLOR" value="8"/>
+	<value name="FACTOR_ONE_MINUS_DST_COLOR" value="9"/>
+	<value name="FACTOR_DST_ALPHA" value="10"/>
+	<value name="FACTOR_ONE_MINUS_DST_ALPHA" value="11"/>
+	<value name="FACTOR_CONSTANT_COLOR" value="12"/>
+	<value name="FACTOR_ONE_MINUS_CONSTANT_COLOR" value="13"/>
+	<value name="FACTOR_CONSTANT_ALPHA" value="14"/>
+	<value name="FACTOR_ONE_MINUS_CONSTANT_ALPHA" value="15"/>
+	<value name="FACTOR_SRC_ALPHA_SATURATE" value="16"/>
+	<value name="FACTOR_SRC1_COLOR" value="20"/>
+	<value name="FACTOR_ONE_MINUS_SRC1_COLOR" value="21"/>
+	<value name="FACTOR_SRC1_ALPHA" value="22"/>
+	<value name="FACTOR_ONE_MINUS_SRC1_ALPHA" value="23"/>
+</enum>
+
+<bitset name="adreno_rb_stencilrefmask" inline="yes">
+	<bitfield name="STENCILREF" low="0" high="7" type="hex"/>
+	<bitfield name="STENCILMASK" low="8" high="15" type="hex"/>
+	<bitfield name="STENCILWRITEMASK" low="16" high="23" type="hex"/>
+</bitset>
+
+<enum name="adreno_rb_surface_endian">
+	<value name="ENDIAN_NONE" value="0"/>
+	<value name="ENDIAN_8IN16" value="1"/>
+	<value name="ENDIAN_8IN32" value="2"/>
+	<value name="ENDIAN_16IN32" value="3"/>
+	<value name="ENDIAN_8IN64" value="4"/>
+	<value name="ENDIAN_8IN128" value="5"/>
+</enum>
+
+<enum name="adreno_rb_dither_mode">
+	<value name="DITHER_DISABLE" value="0"/>
+	<value name="DITHER_ALWAYS" value="1"/>
+	<value name="DITHER_IF_ALPHA_OFF" value="2"/>
+</enum>
+
+<enum name="adreno_rb_depth_format">
+	<value name="DEPTHX_16" value="0"/>
+	<value name="DEPTHX_24_8" value="1"/>
+	<value name="DEPTHX_32" value="2"/>
+</enum>
+
+<enum name="adreno_rb_copy_control_mode">
+	<value name="RB_COPY_RESOLVE" value="1"/>
+	<value name="RB_COPY_CLEAR" value="2"/>
+	<value name="RB_COPY_DEPTH_STENCIL" value="5"/>  <!-- not sure if this is part of MODE or another bitfield?? -->
+</enum>
+
+<bitset name="adreno_reg_xy" inline="yes">
+	<bitfield name="WINDOW_OFFSET_DISABLE" pos="31" type="boolean"/>
+	<bitfield name="X" low="0" high="14" type="uint"/>
+	<bitfield name="Y" low="16" high="30" type="uint"/>
+</bitset>
+
+<bitset name="adreno_cp_protect" inline="yes">
+	<bitfield name="BASE_ADDR" low="0" high="16"/>
+	<bitfield name="MASK_LEN" low="24" high="28"/>
+	<bitfield name="TRAP_WRITE" pos="29"/>
+	<bitfield name="TRAP_READ" pos="30"/>
+</bitset>
+
+<domain name="AXXX" width="32">
+	<brief>Registers in common between a2xx and a3xx</brief>
+
+	<reg32 offset="0x01c0" name="CP_RB_BASE"/>
+	<reg32 offset="0x01c1" name="CP_RB_CNTL">
+		<bitfield name="BUFSZ" low="0" high="5"/>
+		<bitfield name="BLKSZ" low="8" high="13"/>
+		<bitfield name="BUF_SWAP" low="16" high="17"/>
+		<bitfield name="POLL_EN" pos="20" type="boolean"/>
+		<bitfield name="NO_UPDATE" pos="27" type="boolean"/>
+		<bitfield name="RPTR_WR_EN" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x01c3" name="CP_RB_RPTR_ADDR">
+		<bitfield name="SWAP" low="0" high="1" type="uint"/>
+		<bitfield name="ADDR" low="2" high="31" shr="2"/>
+	</reg32>
+	<reg32 offset="0x01c4" name="CP_RB_RPTR" type="uint"/>
+	<reg32 offset="0x01c5" name="CP_RB_WPTR" type="uint"/>
+	<reg32 offset="0x01c6" name="CP_RB_WPTR_DELAY"/>
+	<reg32 offset="0x01c7" name="CP_RB_RPTR_WR"/>
+	<reg32 offset="0x01c8" name="CP_RB_WPTR_BASE"/>
+	<reg32 offset="0x01d5" name="CP_QUEUE_THRESHOLDS">
+		<bitfield name="CSQ_IB1_START" low="0" high="3" type="uint"/>
+		<bitfield name="CSQ_IB2_START" low="8" high="11" type="uint"/>
+		<bitfield name="CSQ_ST_START" low="16" high="19" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01d6" name="CP_MEQ_THRESHOLDS">
+		<bitfield name="MEQ_END" low="16" high="20" type="uint"/>
+		<bitfield name="ROQ_END" low="24" high="28" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01d7" name="CP_CSQ_AVAIL">
+		<bitfield name="RING" low="0" high="6" type="uint"/>
+		<bitfield name="IB1" low="8" high="14" type="uint"/>
+		<bitfield name="IB2" low="16" high="22" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01d8" name="CP_STQ_AVAIL">
+		<bitfield name="ST" low="0" high="6" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01d9" name="CP_MEQ_AVAIL">
+		<bitfield name="MEQ" low="0" high="4" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01dc" name="SCRATCH_UMSK">
+		<bitfield name="UMSK" low="0" high="7" type="uint"/>
+		<bitfield name="SWAP" low="16" high="17" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01dd" name="SCRATCH_ADDR"/>
+	<reg32 offset="0x01ea" name="CP_ME_RDADDR"/>
+
+	<reg32 offset="0x01ec" name="CP_STATE_DEBUG_INDEX"/>
+	<reg32 offset="0x01ed" name="CP_STATE_DEBUG_DATA"/>
+	<reg32 offset="0x01f2" name="CP_INT_CNTL">
+		<bitfield name="SW_INT_MASK" pos="19" type="boolean"/>
+		<bitfield name="T0_PACKET_IN_IB_MASK" pos="23" type="boolean"/>
+		<bitfield name="OPCODE_ERROR_MASK" pos="24" type="boolean"/>
+		<bitfield name="PROTECTED_MODE_ERROR_MASK" pos="25" type="boolean"/>
+		<bitfield name="RESERVED_BIT_ERROR_MASK" pos="26" type="boolean"/>
+		<bitfield name="IB_ERROR_MASK" pos="27" type="boolean"/>
+		<bitfield name="IB2_INT_MASK" pos="29" type="boolean"/>
+		<bitfield name="IB1_INT_MASK" pos="30" type="boolean"/>
+		<bitfield name="RB_INT_MASK" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x01f3" name="CP_INT_STATUS"/>
+	<reg32 offset="0x01f4" name="CP_INT_ACK"/>
+	<reg32 offset="0x01f6" name="CP_ME_CNTL">
+		<bitfield name="BUSY" pos="29" type="boolean"/>
+		<bitfield name="HALT" pos="28" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x01f7" name="CP_ME_STATUS"/>
+	<reg32 offset="0x01f8" name="CP_ME_RAM_WADDR"/>
+	<reg32 offset="0x01f9" name="CP_ME_RAM_RADDR"/>
+	<reg32 offset="0x01fa" name="CP_ME_RAM_DATA"/>
+	<reg32 offset="0x01fc" name="CP_DEBUG">
+		<bitfield name="PREDICATE_DISABLE" pos="23" type="boolean"/>
+		<bitfield name="PROG_END_PTR_ENABLE" pos="24" type="boolean"/>
+		<bitfield name="MIU_128BIT_WRITE_ENABLE" pos="25" type="boolean"/>
+		<bitfield name="PREFETCH_PASS_NOPS" pos="26" type="boolean"/>
+		<bitfield name="DYNAMIC_CLK_DISABLE" pos="27" type="boolean"/>
+		<bitfield name="PREFETCH_MATCH_DISABLE" pos="28" type="boolean"/>
+		<bitfield name="SIMPLE_ME_FLOW_CONTROL" pos="30" type="boolean"/>
+		<bitfield name="MIU_WRITE_PACK_DISABLE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x01fd" name="CP_CSQ_RB_STAT">
+		<bitfield name="RPTR" low="0" high="6" type="uint"/>
+		<bitfield name="WPTR" low="16" high="22" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01fe" name="CP_CSQ_IB1_STAT">
+		<bitfield name="RPTR" low="0" high="6" type="uint"/>
+		<bitfield name="WPTR" low="16" high="22" type="uint"/>
+	</reg32>
+	<reg32 offset="0x01ff" name="CP_CSQ_IB2_STAT">
+		<bitfield name="RPTR" low="0" high="6" type="uint"/>
+		<bitfield name="WPTR" low="16" high="22" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x0440" name="CP_NON_PREFETCH_CNTRS"/>
+	<reg32 offset="0x0443" name="CP_STQ_ST_STAT"/>
+	<reg32 offset="0x044d" name="CP_ST_BASE"/>
+	<reg32 offset="0x044e" name="CP_ST_BUFSZ"/>
+	<reg32 offset="0x044f" name="CP_MEQ_STAT"/>
+	<reg32 offset="0x0452" name="CP_MIU_TAG_STAT"/>
+	<reg32 offset="0x0454" name="CP_BIN_MASK_LO"/>
+	<reg32 offset="0x0455" name="CP_BIN_MASK_HI"/>
+	<reg32 offset="0x0456" name="CP_BIN_SELECT_LO"/>
+	<reg32 offset="0x0457" name="CP_BIN_SELECT_HI"/>
+	<reg32 offset="0x0458" name="CP_IB1_BASE"/>
+	<reg32 offset="0x0459" name="CP_IB1_BUFSZ"/>
+	<reg32 offset="0x045a" name="CP_IB2_BASE"/>
+	<reg32 offset="0x045b" name="CP_IB2_BUFSZ"/>
+	<reg32 offset="0x047f" name="CP_STAT">
+		<bitfield pos="31" name="CP_BUSY"/>
+		<bitfield pos="30" name="VS_EVENT_FIFO_BUSY"/>
+		<bitfield pos="29" name="PS_EVENT_FIFO_BUSY"/>
+		<bitfield pos="28" name="CF_EVENT_FIFO_BUSY"/>
+		<bitfield pos="27" name="RB_EVENT_FIFO_BUSY"/>
+		<bitfield pos="26" name="ME_BUSY"/>
+		<bitfield pos="25" name="MIU_WR_C_BUSY"/>
+		<bitfield pos="23" name="CP_3D_BUSY"/>
+		<bitfield pos="22" name="CP_NRT_BUSY"/>
+		<bitfield pos="21" name="RBIU_SCRATCH_BUSY"/>
+		<bitfield pos="20" name="RCIU_ME_BUSY"/>
+		<bitfield pos="19" name="RCIU_PFP_BUSY"/>
+		<bitfield pos="18" name="MEQ_RING_BUSY"/>
+		<bitfield pos="17" name="PFP_BUSY"/>
+		<bitfield pos="16" name="ST_QUEUE_BUSY"/>
+		<bitfield pos="13" name="INDIRECT2_QUEUE_BUSY"/>
+		<bitfield pos="12" name="INDIRECTS_QUEUE_BUSY"/>
+		<bitfield pos="11" name="RING_QUEUE_BUSY"/>
+		<bitfield pos="10" name="CSF_BUSY"/>
+		<bitfield pos="9"  name="CSF_ST_BUSY"/>
+		<bitfield pos="8"  name="EVENT_BUSY"/>
+		<bitfield pos="7"  name="CSF_INDIRECT2_BUSY"/>
+		<bitfield pos="6"  name="CSF_INDIRECTS_BUSY"/>
+		<bitfield pos="5"  name="CSF_RING_BUSY"/>
+		<bitfield pos="4"  name="RCIU_BUSY"/>
+		<bitfield pos="3"  name="RBIU_BUSY"/>
+		<bitfield pos="2"  name="MIU_RD_RETURN_BUSY"/>
+		<bitfield pos="1"  name="MIU_RD_REQ_BUSY"/>
+		<bitfield pos="0"  name="MIU_WR_BUSY"/>
+	</reg32>
+	<reg32 offset="0x0578" name="CP_SCRATCH_REG0" type="uint"/>
+	<reg32 offset="0x0579" name="CP_SCRATCH_REG1" type="uint"/>
+	<reg32 offset="0x057a" name="CP_SCRATCH_REG2" type="uint"/>
+	<reg32 offset="0x057b" name="CP_SCRATCH_REG3" type="uint"/>
+	<reg32 offset="0x057c" name="CP_SCRATCH_REG4" type="uint"/>
+	<reg32 offset="0x057d" name="CP_SCRATCH_REG5" type="uint"/>
+	<reg32 offset="0x057e" name="CP_SCRATCH_REG6" type="uint"/>
+	<reg32 offset="0x057f" name="CP_SCRATCH_REG7" type="uint"/>
+
+	<reg32 offset="0x0600" name="CP_ME_VS_EVENT_SRC"/>
+	<reg32 offset="0x0601" name="CP_ME_VS_EVENT_ADDR"/>
+	<reg32 offset="0x0602" name="CP_ME_VS_EVENT_DATA"/>
+	<reg32 offset="0x0603" name="CP_ME_VS_EVENT_ADDR_SWM"/>
+	<reg32 offset="0x0604" name="CP_ME_VS_EVENT_DATA_SWM"/>
+	<reg32 offset="0x0605" name="CP_ME_PS_EVENT_SRC"/>
+	<reg32 offset="0x0606" name="CP_ME_PS_EVENT_ADDR"/>
+	<reg32 offset="0x0607" name="CP_ME_PS_EVENT_DATA"/>
+	<reg32 offset="0x0608" name="CP_ME_PS_EVENT_ADDR_SWM"/>
+	<reg32 offset="0x0609" name="CP_ME_PS_EVENT_DATA_SWM"/>
+	<reg32 offset="0x060a" name="CP_ME_CF_EVENT_SRC"/>
+	<reg32 offset="0x060b" name="CP_ME_CF_EVENT_ADDR"/>
+	<reg32 offset="0x060c" name="CP_ME_CF_EVENT_DATA" type="uint"/>
+	<reg32 offset="0x060d" name="CP_ME_NRT_ADDR"/>
+	<reg32 offset="0x060e" name="CP_ME_NRT_DATA"/>
+	<reg32 offset="0x0612" name="CP_ME_VS_FETCH_DONE_SRC"/>
+	<reg32 offset="0x0613" name="CP_ME_VS_FETCH_DONE_ADDR"/>
+	<reg32 offset="0x0614" name="CP_ME_VS_FETCH_DONE_DATA"/>
+
+</domain>
+
+<!--
+	Common between A3xx and A4xx:
+ -->
+
+<enum name="a3xx_rop_code">
+	<value name="ROP_CLEAR"         value="0"/>
+	<value name="ROP_NOR"           value="1"/>
+	<value name="ROP_AND_INVERTED"  value="2"/>
+	<value name="ROP_COPY_INVERTED" value="3"/>
+	<value name="ROP_AND_REVERSE"   value="4"/>
+	<value name="ROP_INVERT"        value="5"/>
+	<value name="ROP_XOR"           value="6"/>
+	<value name="ROP_NAND"          value="7"/>
+	<value name="ROP_AND"           value="8"/>
+	<value name="ROP_EQUIV"         value="9"/>
+	<value name="ROP_NOOP"          value="10"/>
+	<value name="ROP_OR_INVERTED"   value="11"/>
+	<value name="ROP_COPY"          value="12"/>
+	<value name="ROP_OR_REVERSE"    value="13"/>
+	<value name="ROP_OR"            value="14"/>
+	<value name="ROP_SET"           value="15"/>
+</enum>
+
+<enum name="a3xx_render_mode">
+	<value name="RB_RENDERING_PASS" value="0"/>
+	<value name="RB_TILING_PASS" value="1"/>
+	<value name="RB_RESOLVE_PASS" value="2"/>
+	<value name="RB_COMPUTE_PASS" value="3"/>
+</enum>
+
+<enum name="a3xx_msaa_samples">
+	<value name="MSAA_ONE" value="0"/>
+	<value name="MSAA_TWO" value="1"/>
+	<value name="MSAA_FOUR" value="2"/>
+	<value name="MSAA_EIGHT" value="3"/>
+</enum>
+
+<enum name="a3xx_threadmode">
+	<value value="0" name="MULTI"/>
+	<value value="1" name="SINGLE"/>
+</enum>
+
+<enum name="a3xx_instrbuffermode">
+	<!--
+	When shader size goes above ~128 or so, blob switches to '0'
+	and doesn't emit shader in cmdstream.  When either is '0' it
+	doesn't get emitted via CP_LOAD_STATE.  When only one is
+	'0' the other gets size 256-others_size.  So I think that:
+		BUFFER => execute out of state memory
+		CACHE  => use available state memory as local cache
+	NOTE that when CACHE mode, also set CACHEINVALID flag!
+
+	TODO check if that 256 size is same for all a3xx
+	 -->
+	<value value="0" name="CACHE"/>
+	<value value="1" name="BUFFER"/>
+</enum>
+
+<enum name="a3xx_threadsize">
+	<value value="0" name="TWO_QUADS"/>
+	<value value="1" name="FOUR_QUADS"/>
+</enum>
+
+<enum name="a3xx_color_swap">
+	<value name="WZYX" value="0"/>
+	<value name="WXYZ" value="1"/>
+	<value name="ZYXW" value="2"/>
+	<value name="XYZW" value="3"/>
+</enum>
+
+<enum name="a3xx_rb_blend_opcode">
+	<value name="BLEND_DST_PLUS_SRC" value="0"/>
+	<value name="BLEND_SRC_MINUS_DST" value="1"/>
+	<value name="BLEND_DST_MINUS_SRC" value="2"/>
+	<value name="BLEND_MIN_DST_SRC" value="3"/>
+	<value name="BLEND_MAX_DST_SRC" value="4"/>
+</enum>
+
+<enum name="a4xx_tess_spacing">
+	<value name="EQUAL_SPACING" value="0"/>
+	<value name="ODD_SPACING" value="2"/>
+	<value name="EVEN_SPACING" value="3"/>
+</enum>
+
+<doc>Address mode for a5xx+</doc>
+<enum name="a5xx_address_mode">
+	<value name="ADDR_32B" value="0"/>
+	<value name="ADDR_64B" value="1"/>
+</enum>
+
+<doc>
+    Line mode for a5xx+
+	Note that Bresenham lines are only supported with MSAA disabled.
+</doc>
+<enum name="a5xx_line_mode">
+	<value value="0x0"  name="BRESENHAM"/>
+	<value value="0x1"  name="RECTANGULAR"/>
+</enum>
+
+<doc>
+	Blob (v615) seem to only use SAM and I wasn't able to coerce
+	it to produce any other command.
+	Probably valid for a4xx+ but not enabled or tested on anything
+	but a6xx.
+</doc>
+<enum name="a6xx_tex_prefetch_cmd">
+	<doc> Produces garbage </doc>
+	<value value="0x0" name="TEX_PREFETCH_UNK0"/>
+	<value value="0x1" name="TEX_PREFETCH_SAM"/>
+	<value value="0x2" name="TEX_PREFETCH_GATHER4R"/>
+	<value value="0x3" name="TEX_PREFETCH_GATHER4G"/>
+	<value value="0x4" name="TEX_PREFETCH_GATHER4B"/>
+	<value value="0x5" name="TEX_PREFETCH_GATHER4A"/>
+	<doc> Causes reads from an invalid address </doc>
+	<value value="0x6" name="TEX_PREFETCH_UNK6"/>
+	<doc> Results in color being zero </doc>
+	<value value="0x7" name="TEX_PREFETCH_UNK7"/>
+</enum>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/adreno/adreno_pm4.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/adreno/adreno_pm4.xml
@@ -0,0 +1,2263 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="adreno/adreno_common.xml"/>
+
+<enum name="vgt_event_type" varset="chip">
+	<value name="VS_DEALLOC" value="0"/>
+	<value name="PS_DEALLOC" value="1" variants="A2XX-A6XX"/>
+	<value name="VS_DONE_TS" value="2"/>
+	<value name="PS_DONE_TS" value="3"/>
+	<doc>
+		Flushes dirty data from UCHE, and also writes a GPU timestamp to
+		the address if one is provided.
+	</doc>
+	<value name="CACHE_FLUSH_TS" value="4"/>
+	<value name="CONTEXT_DONE" value="5"/>
+	<value name="CACHE_FLUSH" value="6" variants="A2XX-A4XX"/>
+	<value name="VIZQUERY_START" value="7" variants="A2XX"/>
+	<value name="HLSQ_FLUSH" value="7" variants="A3XX-A4XX"/>
+	<value name="VIZQUERY_END" value="8" variants="A2XX"/>
+	<value name="SC_WAIT_WC" value="9" variants="A2XX"/>
+	<value name="WRITE_PRIMITIVE_COUNTS" value="9" variants="A6XX"/>
+	<value name="START_PRIMITIVE_CTRS" value="11" variants="A6XX"/>
+	<value name="STOP_PRIMITIVE_CTRS" value="12" variants="A6XX"/>
+	<!-- Not sure that these 4 events don't have the same meaning as on A5XX+ -->
+	<value name="RST_PIX_CNT" value="13" variants="A2XX-A4XX"/>
+	<value name="RST_VTX_CNT" value="14" variants="A2XX-A4XX"/>
+	<value name="TILE_FLUSH" value="15" variants="A2XX-A4XX"/>
+	<value name="STAT_EVENT" value="16" variants="A2XX-A4XX"/>
+	<value name="CACHE_FLUSH_AND_INV_TS_EVENT" value="20" variants="A2XX-A4XX"/>
+	<doc>
+		If A6XX_RB_SAMPLE_COUNT_CONTROL.copy is true, writes OQ Z passed
+		sample counts to RB_SAMPLE_COUNT_ADDR.  This writes to main
+		memory, skipping UCHE.
+	</doc>
+	<value name="ZPASS_DONE" value="21"/>
+	<value name="CACHE_FLUSH_AND_INV_EVENT" value="22" variants="A2XX"/>
+
+	<doc>
+		Writes the GPU timestamp to the address that follows, once RB
+		access and flushes are complete.
+	</doc>
+	<value name="RB_DONE_TS" value="22" variants="A3XX-"/>
+
+	<value name="PERFCOUNTER_START" value="23" variants="A2XX-A4XX"/>
+	<value name="PERFCOUNTER_STOP" value="24" variants="A2XX-A4XX"/>
+	<value name="VS_FETCH_DONE" value="27"/>
+	<value name="FACENESS_FLUSH" value="28" variants="A2XX-A4XX"/>
+
+	<!-- a5xx events -->
+	<value name="WT_DONE_TS" value="8" variants="A5XX-"/>
+	<value name="START_FRAGMENT_CTRS" value="13" variants="A5XX-"/>
+	<value name="STOP_FRAGMENT_CTRS" value="14" variants="A5XX-"/>
+	<value name="START_COMPUTE_CTRS" value="15" variants="A5XX-"/>
+	<value name="STOP_COMPUTE_CTRS" value="16" variants="A5XX-"/>
+	<value name="FLUSH_SO_0" value="17" variants="A5XX-"/>
+	<value name="FLUSH_SO_1" value="18" variants="A5XX-"/>
+	<value name="FLUSH_SO_2" value="19" variants="A5XX-"/>
+	<value name="FLUSH_SO_3" value="20" variants="A5XX-"/>
+
+	<doc>
+		Invalidates depth attachment data from the CCU.  We assume this
+		happens in the last stage.
+	</doc>
+	<value name="PC_CCU_INVALIDATE_DEPTH" value="24" variants="A5XX-"/>
+
+	<doc>
+		Invalidates color attachment data from the CCU.  We assume this
+		happens in the last stage.
+	</doc>
+	<value name="PC_CCU_INVALIDATE_COLOR" value="25" variants="A5XX-"/>
+
+	<doc>
+		Flushes the small cache used by CP_EVENT_WRITE::BLIT (which,
+		along with its registers, would be better named RESOLVE).
+	</doc>
+	<value name="PC_CCU_RESOLVE_TS" value="26" variants="A6XX"/>
+
+	<doc>
+		Flushes depth attachment data from the CCU.  We assume this
+		happens in the last stage.
+	</doc>
+	<value name="PC_CCU_FLUSH_DEPTH_TS" value="28" variants="A5XX-"/>
+
+	<doc>
+		Flushes color attachment data from the CCU.  We assume this
+		happens in the last stage.
+	</doc>
+	<value name="PC_CCU_FLUSH_COLOR_TS" value="29" variants="A5XX-"/>
+
+	<doc>
+		2D blit to resolve GMEM to system memory (skipping CCU) at the
+		end of a render pass.  Compare to CP_BLIT's BLIT_OP_SCALE for
+		more general blitting.
+	</doc>
+	<value name="BLIT" value="30" variants="A5XX-"/>
+
+	<doc>
+		Clears based on GRAS_LRZ_CNTL configuration, could clear
+		fast-clear buffer or LRZ direction.
+		LRZ direction is stored at lrz_fc_offset + 0x200, has 1 byte which
+		could be expressed by enum:
+			CUR_DIR_DISABLED = 0x0
+			CUR_DIR_GE = 0x1
+			CUR_DIR_LE = 0x2
+			CUR_DIR_UNSET = 0x3
+		Clear of direction means setting the direction to CUR_DIR_UNSET.
+	</doc>
+	<value name="LRZ_CLEAR" value="37" variants="A5XX-"/>
+
+	<value name="LRZ_FLUSH" value="38" variants="A5XX-"/>
+	<value name="BLIT_OP_FILL_2D" value="39" variants="A5XX-"/>
+	<value name="BLIT_OP_COPY_2D" value="40" variants="A5XX-A6XX"/>
+	<value name="UNK_40" value="40" variants="A7XX"/>
+	<value name="BLIT_OP_SCALE_2D" value="42" variants="A5XX-"/>
+	<value name="CONTEXT_DONE_2D" value="43" variants="A5XX-"/>
+	<value name="UNK_2C" value="44" variants="A5XX-"/>
+	<value name="UNK_2D" value="45" variants="A5XX-"/>
+
+	<!-- a6xx events -->
+	<doc>
+		Invalidates UCHE.
+	</doc>
+	<value name="CACHE_INVALIDATE" value="49" variants="A6XX"/>
+
+	<value name="LABEL" value="63" variants="A6XX-"/>
+
+	<!-- note, some of these are the same as a6xx, just named differently -->
+
+	<doc> Doesn't seem to do anything </doc>
+	<value name="DUMMY_EVENT" value="1" variants="A7XX"/>
+	<value name="CCU_INVALIDATE_DEPTH" value="24" variants="A7XX"/>
+	<value name="CCU_INVALIDATE_COLOR" value="25" variants="A7XX"/>
+	<value name="CCU_RESOLVE_CLEAN" value="26" variants="A7XX"/>
+	<value name="CCU_FLUSH_DEPTH" value="28" variants="A7XX"/>
+	<value name="CCU_FLUSH_COLOR" value="29" variants="A7XX"/>
+	<value name="CCU_RESOLVE" value="30" variants="A7XX"/>
+	<value name="CCU_END_RESOLVE_GROUP" value="31" variants="A7XX"/>
+	<value name="CCU_CLEAN_DEPTH" value="32" variants="A7XX"/>
+	<value name="CCU_CLEAN_COLOR" value="33" variants="A7XX"/>
+	<value name="CACHE_RESET" value="48" variants="A7XX"/>
+	<value name="CACHE_CLEAN" value="49" variants="A7XX"/>
+	<!-- TODO: deal with name conflicts with other gens -->
+	<value name="CACHE_FLUSH7" value="50" variants="A7XX"/>
+	<value name="CACHE_INVALIDATE7" value="51" variants="A7XX"/>
+</enum>
+
+<enum name="pc_di_primtype">
+	<value name="DI_PT_NONE" value="0"/>
+	<!-- POINTLIST_PSIZE is used on a3xx/a4xx when gl_PointSize is written: -->
+	<value name="DI_PT_POINTLIST_PSIZE" value="1"/>
+	<value name="DI_PT_LINELIST" value="2"/>
+	<value name="DI_PT_LINESTRIP" value="3"/>
+	<value name="DI_PT_TRILIST" value="4"/>
+	<value name="DI_PT_TRIFAN" value="5"/>
+	<value name="DI_PT_TRISTRIP" value="6"/>
+	<value name="DI_PT_LINELOOP" value="7"/>  <!-- a22x, a3xx -->
+	<value name="DI_PT_RECTLIST" value="8"/>
+	<value name="DI_PT_POINTLIST" value="9"/>
+	<value name="DI_PT_LINE_ADJ" value="0xa"/>
+	<value name="DI_PT_LINESTRIP_ADJ" value="0xb"/>
+	<value name="DI_PT_TRI_ADJ" value="0xc"/>
+	<value name="DI_PT_TRISTRIP_ADJ" value="0xd"/>
+
+	<value name="DI_PT_PATCHES0" value="0x1f"/>
+	<value name="DI_PT_PATCHES1" value="0x20"/>
+	<value name="DI_PT_PATCHES2" value="0x21"/>
+	<value name="DI_PT_PATCHES3" value="0x22"/>
+	<value name="DI_PT_PATCHES4" value="0x23"/>
+	<value name="DI_PT_PATCHES5" value="0x24"/>
+	<value name="DI_PT_PATCHES6" value="0x25"/>
+	<value name="DI_PT_PATCHES7" value="0x26"/>
+	<value name="DI_PT_PATCHES8" value="0x27"/>
+	<value name="DI_PT_PATCHES9" value="0x28"/>
+	<value name="DI_PT_PATCHES10" value="0x29"/>
+	<value name="DI_PT_PATCHES11" value="0x2a"/>
+	<value name="DI_PT_PATCHES12" value="0x2b"/>
+	<value name="DI_PT_PATCHES13" value="0x2c"/>
+	<value name="DI_PT_PATCHES14" value="0x2d"/>
+	<value name="DI_PT_PATCHES15" value="0x2e"/>
+	<value name="DI_PT_PATCHES16" value="0x2f"/>
+	<value name="DI_PT_PATCHES17" value="0x30"/>
+	<value name="DI_PT_PATCHES18" value="0x31"/>
+	<value name="DI_PT_PATCHES19" value="0x32"/>
+	<value name="DI_PT_PATCHES20" value="0x33"/>
+	<value name="DI_PT_PATCHES21" value="0x34"/>
+	<value name="DI_PT_PATCHES22" value="0x35"/>
+	<value name="DI_PT_PATCHES23" value="0x36"/>
+	<value name="DI_PT_PATCHES24" value="0x37"/>
+	<value name="DI_PT_PATCHES25" value="0x38"/>
+	<value name="DI_PT_PATCHES26" value="0x39"/>
+	<value name="DI_PT_PATCHES27" value="0x3a"/>
+	<value name="DI_PT_PATCHES28" value="0x3b"/>
+	<value name="DI_PT_PATCHES29" value="0x3c"/>
+	<value name="DI_PT_PATCHES30" value="0x3d"/>
+	<value name="DI_PT_PATCHES31" value="0x3e"/>
+</enum>
+
+<enum name="pc_di_src_sel">
+	<value name="DI_SRC_SEL_DMA" value="0"/>
+	<value name="DI_SRC_SEL_IMMEDIATE" value="1"/>
+	<value name="DI_SRC_SEL_AUTO_INDEX" value="2"/>
+	<value name="DI_SRC_SEL_AUTO_XFB" value="3"/>
+</enum>
+
+<enum name="pc_di_face_cull_sel">
+	<value name="DI_FACE_CULL_NONE" value="0"/>
+	<value name="DI_FACE_CULL_FETCH" value="1"/>
+	<value name="DI_FACE_BACKFACE_CULL" value="2"/>
+	<value name="DI_FACE_FRONTFACE_CULL" value="3"/>
+</enum>
+
+<enum name="pc_di_index_size">
+	<value name="INDEX_SIZE_IGN" value="0"/>
+	<value name="INDEX_SIZE_16_BIT" value="0"/>
+	<value name="INDEX_SIZE_32_BIT" value="1"/>
+	<value name="INDEX_SIZE_8_BIT" value="2"/>
+	<value name="INDEX_SIZE_INVALID"/>
+</enum>
+
+<enum name="pc_di_vis_cull_mode">
+	<value name="IGNORE_VISIBILITY" value="0"/>
+	<value name="USE_VISIBILITY" value="1"/>
+</enum>
+
+<enum name="adreno_pm4_packet_type">
+	<value name="CP_TYPE0_PKT" value="0x00000000"/>
+	<value name="CP_TYPE1_PKT" value="0x40000000"/>
+	<value name="CP_TYPE2_PKT" value="0x80000000"/>
+	<value name="CP_TYPE3_PKT" value="0xc0000000"/>
+	<value name="CP_TYPE4_PKT" value="0x40000000"/>
+	<value name="CP_TYPE7_PKT" value="0x70000000"/>
+</enum>
+
+<!--
+   Note that in some cases, the same packet id is recycled on a later
+   generation, so variants attribute is used to distinguish.   They
+   may not be completely accurate, we would probably have to analyze
+   the pfp and me/pm4 firmware to verify the packet is actually
+   handled on a particular generation.  But it is at least enough to
+   disambiguate the packet-id's that were re-used for different
+   packets starting with a5xx.
+ -->
+<enum name="adreno_pm4_type3_packets" varset="chip">
+	<doc>initialize CP's micro-engine</doc>
+	<value name="CP_ME_INIT" value="0x48"/>
+	<doc>skip N 32-bit words to get to the next packet</doc>
+	<value name="CP_NOP" value="0x10"/>
+	<doc>
+		indirect buffer dispatch.  prefetch parser uses this packet
+		type to determine whether to pre-fetch the IB
+	</doc>
+	<value name="CP_PREEMPT_ENABLE" value="0x1c" variants="A5XX"/>
+	<value name="CP_PREEMPT_TOKEN" value="0x1e" variants="A5XX"/>
+	<value name="CP_INDIRECT_BUFFER" value="0x3f"/>
+	<doc>
+		Takes the same arguments as CP_INDIRECT_BUFFER, but jumps to
+		another buffer at the same level. Must be at the end of IB, and
+		doesn't work with draw state IB's.
+	</doc>
+	<value name="CP_INDIRECT_BUFFER_CHAIN" value="0x57" variants="A5XX-"/>
+	<doc>indirect buffer dispatch.  same as IB, but init is pipelined</doc>
+	<value name="CP_INDIRECT_BUFFER_PFD" value="0x37"/>
+	<doc>
+		Waits for the IDLE state of the engine before further drawing.
+		This is pipelined, so the CP may continue.
+	</doc>
+	<value name="CP_WAIT_FOR_IDLE" value="0x26"/>
+	<doc>wait until a register or memory location is a specific value</doc>
+	<value name="CP_WAIT_REG_MEM" value="0x3c"/>
+	<doc>wait until a register location is equal to a specific value</doc>
+	<value name="CP_WAIT_REG_EQ" value="0x52"/>
+	<doc>wait until a register location is >= a specific value</doc>
+	<value name="CP_WAIT_REG_GTE" value="0x53" variants="A2XX-A4XX"/>
+	<doc>wait until a read completes</doc>
+	<value name="CP_WAIT_UNTIL_READ" value="0x5c" variants="A2XX-A4XX"/>
+	<doc>wait until all base/size writes from an IB_PFD packet have completed</doc>
+	<!--
+		NOTE: CP_WAIT_IB_PFD_COMPLETE unimplemented at least since a5xx fw, and
+		recycled for something new on a7xx
+	 -->
+	<value name="CP_WAIT_IB_PFD_COMPLETE" value="0x5d" varset="chip" variants="A2XX-A4XX"/>
+	<doc>register read/modify/write</doc>
+	<value name="CP_REG_RMW" value="0x21"/>
+	<doc>Set binning configuration registers</doc>
+	<value name="CP_SET_BIN_DATA" value="0x2f" variants="A2XX-A4XX"/>
+	<value name="CP_SET_BIN_DATA5" value="0x2f" variants="A5XX-"/>
+	<doc>reads register in chip and writes to memory</doc>
+	<value name="CP_REG_TO_MEM" value="0x3e"/>
+	<doc>write N 32-bit words to memory</doc>
+	<value name="CP_MEM_WRITE" value="0x3d"/>
+	<doc>write CP_PROG_COUNTER value to memory</doc>
+	<value name="CP_MEM_WRITE_CNTR" value="0x4f"/>
+	<doc>conditional execution of a sequence of packets</doc>
+	<value name="CP_COND_EXEC" value="0x44"/>
+	<doc>conditional write to memory or register</doc>
+	<value name="CP_COND_WRITE" value="0x45" variants="A2XX-A4XX"/>
+	<value name="CP_COND_WRITE5" value="0x45" variants="A5XX-"/>
+	<doc>generate an event that creates a write to memory when completed</doc>
+	<value name="CP_EVENT_WRITE" value="0x46" variants="A2XX-A6XX"/>
+	<value name="CP_EVENT_WRITE7" value="0x46" variants="A7XX-"/>
+	<doc>generate a VS|PS_done event</doc>
+	<value name="CP_EVENT_WRITE_SHD" value="0x58"/>
+	<doc>generate a cache flush done event</doc>
+	<value name="CP_EVENT_WRITE_CFL" value="0x59"/>
+	<doc>generate a z_pass done event</doc>
+	<value name="CP_EVENT_WRITE_ZPD" value="0x5b"/>
+	<doc>
+		not sure the real name, but this seems to be what is used for
+		opencl, instead of CP_DRAW_INDX..
+	</doc>
+	<value name="CP_RUN_OPENCL" value="0x31"/>
+	<doc>initiate fetch of index buffer and draw</doc>
+	<value name="CP_DRAW_INDX" value="0x22"/>
+	<doc>draw using supplied indices in packet</doc>
+	<value name="CP_DRAW_INDX_2" value="0x36" variants="A2XX-A4XX"/>  <!-- this is something different on a6xx and unused on a5xx -->
+	<doc>initiate fetch of index buffer and binIDs and draw</doc>
+	<value name="CP_DRAW_INDX_BIN" value="0x34" variants="A2XX-A4XX"/>
+	<doc>initiate fetch of bin IDs and draw using supplied indices</doc>
+	<value name="CP_DRAW_INDX_2_BIN" value="0x35" variants="A2XX-A4XX"/>
+	<doc>begin/end initiator for viz query extent processing</doc>
+	<value name="CP_VIZ_QUERY" value="0x23" variants="A2XX-A4XX"/>
+	<doc>fetch state sub-blocks and initiate shader code DMAs</doc>
+	<value name="CP_SET_STATE" value="0x25"/>
+	<doc>load constant into chip and to memory</doc>
+	<value name="CP_SET_CONSTANT" value="0x2d" variants="A2XX"/>
+	<doc>load sequencer instruction memory (pointer-based)</doc>
+	<value name="CP_IM_LOAD" value="0x27"/>
+	<doc>load sequencer instruction memory (code embedded in packet)</doc>
+	<value name="CP_IM_LOAD_IMMEDIATE" value="0x2b"/>
+	<doc>load constants from a location in memory</doc>
+	<value name="CP_LOAD_CONSTANT_CONTEXT" value="0x2e" variants="A2XX"/>
+	<doc>selective invalidation of state pointers</doc>
+	<value name="CP_INVALIDATE_STATE" value="0x3b"/>
+	<doc>dynamically changes shader instruction memory partition</doc>
+	<value name="CP_SET_SHADER_BASES" value="0x4a" variants="A2XX-A4XX"/>
+	<doc>sets the 64-bit BIN_MASK register in the PFP</doc>
+	<value name="CP_SET_BIN_MASK" value="0x50" variants="A2XX-A4XX"/>
+	<doc>sets the 64-bit BIN_SELECT register in the PFP</doc>
+	<value name="CP_SET_BIN_SELECT" value="0x51" variants="A2XX-A4XX"/>
+	<doc>updates the current context, if needed</doc>
+	<value name="CP_CONTEXT_UPDATE" value="0x5e"/>
+	<doc>generate interrupt from the command stream</doc>
+	<value name="CP_INTERRUPT" value="0x40"/>
+	<doc>copy sequencer instruction memory to system memory</doc>
+	<value name="CP_IM_STORE" value="0x2c" variants="A2XX"/>
+
+	<!-- For a20x -->
+<!-- TODO handle variants..
+	<doc>
+		Program an offset that will added to the BIN_BASE value of
+		the 3D_DRAW_INDX_BIN packet
+	</doc>
+	<value name="CP_SET_BIN_BASE_OFFSET" value="0x4b"/>
+ -->
+
+	<!-- for a22x -->
+	<doc>
+		sets draw initiator flags register in PFP, gets bitwise-ORed into
+		every draw initiator
+	</doc>
+	<value name="CP_SET_DRAW_INIT_FLAGS" value="0x4b"/>
+	<doc>sets the register protection mode</doc>
+	<value name="CP_SET_PROTECTED_MODE" value="0x5f"/>
+
+	<value name="CP_BOOTSTRAP_UCODE" value="0x6f"/>
+
+	<!-- for a3xx -->
+	<doc>load high level sequencer command</doc>
+	<value name="CP_LOAD_STATE" value="0x30" variants="A3XX"/>
+	<value name="CP_LOAD_STATE4" value="0x30" variants="A4XX-A5XX"/>
+	<doc>Conditionally load a IB based on a flag, prefetch enabled</doc>
+	<value name="CP_COND_INDIRECT_BUFFER_PFE" value="0x3a"/>
+	<doc>Conditionally load a IB based on a flag, prefetch disabled</doc>
+	<value name="CP_COND_INDIRECT_BUFFER_PFD" value="0x32" variants="A3XX"/>
+	<doc>Load a buffer with pre-fetch enabled</doc>
+	<value name="CP_INDIRECT_BUFFER_PFE" value="0x3f" variants="A5XX"/>
+	<doc>Set bin (?)</doc>
+	<value name="CP_SET_BIN" value="0x4c" variants="A2XX"/>
+
+	<doc>test 2 memory locations to dword values specified</doc>
+	<value name="CP_TEST_TWO_MEMS" value="0x71"/>
+
+	<doc>Write register, ignoring context state for context sensitive registers</doc>
+	<value name="CP_REG_WR_NO_CTXT" value="0x78"/>
+
+	<doc>Record the real-time when this packet is processed by PFP</doc>
+	<value name="CP_RECORD_PFP_TIMESTAMP" value="0x11"/>
+
+	<!-- Used to switch GPU between secure and non-secure modes -->
+	<value name="CP_SET_SECURE_MODE" value="0x66"/>
+
+	<doc>PFP waits until the FIFO between the PFP and the ME is empty</doc>
+	<value name="CP_WAIT_FOR_ME" value="0x13"/>
+
+	<!-- for a4xx -->
+	<doc>
+		Used a bit like CP_SET_CONSTANT on a2xx, but can write multiple
+		groups of registers.  Looks like it can be used to create state
+		objects in GPU memory, and on state change only emit pointer
+		(via CP_SET_DRAW_STATE), which should be nice for reducing CPU
+		overhead:
+
+		(A4x) save PM4 stream pointers to execute upon a visible draw
+	</doc>
+	<value name="CP_SET_DRAW_STATE" value="0x43" variants="A4XX-"/>
+	<value name="CP_DRAW_INDX_OFFSET" value="0x38"/>
+	<value name="CP_DRAW_INDIRECT" value="0x28" variants="A4XX-"/>
+	<value name="CP_DRAW_INDX_INDIRECT" value="0x29" variants="A4XX-"/>
+	<value name="CP_DRAW_INDIRECT_MULTI" value="0x2a" variants="A6XX-"/>
+	<value name="CP_DRAW_AUTO" value="0x24"/>
+
+	<doc>
+		Enable or disable predication globally. Also resets the
+		predicate to "passing" and the local bit to enabled when
+		enabling global predication.
+	</doc>
+	<value name="CP_DRAW_PRED_ENABLE_GLOBAL" value="0x19"/>
+
+	<doc>
+		Enable or disable predication locally. Unlike globally enabling
+		predication, this packet doesn't touch any other state.
+		Predication only happens when enabled globally and locally and a
+		predicate has been set. This should be used for internal draws
+		which aren't supposed to use the predication state:
+
+		CP_DRAW_PRED_ENABLE_LOCAL(0)
+		... do draw...
+		CP_DRAW_PRED_ENABLE_LOCAL(1)
+	</doc>
+	<value name="CP_DRAW_PRED_ENABLE_LOCAL" value="0x1a"/>
+
+	<doc>
+		Latch a draw predicate into the internal register.
+	</doc>
+	<value name="CP_DRAW_PRED_SET" value="0x4e"/>
+
+	<doc>
+		for A4xx
+		Write to register with address that does not fit into type-0 pkt
+	</doc>
+	<value name="CP_WIDE_REG_WRITE" value="0x74" variants="A4XX"/>
+
+	<doc>copy from ME scratch RAM to a register</doc>
+	<value name="CP_SCRATCH_TO_REG" value="0x4d"/>
+
+	<doc>Copy from REG to ME scratch RAM</doc>
+	<value name="CP_REG_TO_SCRATCH" value="0x4a"/>
+
+	<doc>Wait for memory writes to complete</doc>
+	<value name="CP_WAIT_MEM_WRITES" value="0x12"/>
+
+	<doc>Conditional execution based on register comparison</doc>
+	<value name="CP_COND_REG_EXEC" value="0x47"/>
+
+	<doc>Memory to REG copy</doc>
+	<value name="CP_MEM_TO_REG" value="0x42"/>
+
+	<value name="CP_EXEC_CS_INDIRECT" value="0x41" variants="A4XX-"/>
+	<value name="CP_EXEC_CS" value="0x33"/>
+
+	<doc>
+		for a5xx
+	</doc>
+	<value name="CP_PERFCOUNTER_ACTION" value="0x50" variants="A5XX"/>
+	<!-- switches SMMU pagetable, used on a5xx+ only -->
+	<value name="CP_SMMU_TABLE_UPDATE" value="0x53" variants="A5XX-"/>
+	<!-- for a6xx -->
+	<doc>Tells CP the current mode of GPU operation</doc>
+	<value name="CP_SET_MARKER" value="0x65" variants="A6XX-"/>
+	<doc>Instruct CP to set a few internal CP registers</doc>
+	<value name="CP_SET_PSEUDO_REG" value="0x56" variants="A6XX-"/>
+	<!--
+	pairs of regid and value.. seems to be used to program some TF
+	related regs:
+	 -->
+	<value name="CP_CONTEXT_REG_BUNCH" value="0x5c" variants="A5XX-"/>
+	<!-- A5XX Enable yield in RB only -->
+	<value name="CP_YIELD_ENABLE" value="0x1c" variants="A5XX"/>
+	<doc>
+		Enables IB2 skipping.  If both GLOBAL and LOCAL are 1 and
+		nothing is left in the visibility stream, then
+		CP_INDIRECT_BUFFER will be skipped, and draws will early return
+		from their IB.
+	</doc>
+	<value name="CP_SKIP_IB2_ENABLE_GLOBAL" value="0x1d" variants="A5XX-"/>
+	<value name="CP_SKIP_IB2_ENABLE_LOCAL" value="0x23" variants="A5XX-"/>
+	<value name="CP_SET_SUBDRAW_SIZE" value="0x35" variants="A5XX-"/>
+	<value name="CP_WHERE_AM_I" value="0x62" variants="A5XX-"/>
+	<value name="CP_SET_VISIBILITY_OVERRIDE" value="0x64" variants="A5XX-"/>
+	<!-- Enable/Disable/Defer A5x global preemption model -->
+	<value name="CP_PREEMPT_ENABLE_GLOBAL" value="0x69" variants="A5XX"/>
+	<!-- Enable/Disable A5x local preemption model -->
+	<value name="CP_PREEMPT_ENABLE_LOCAL" value="0x6a" variants="A5XX"/>
+	<!-- Yield token on a5xx similar to CP_PREEMPT on a4xx -->
+	<value name="CP_CONTEXT_SWITCH_YIELD" value="0x6b" variants="A5XX-"/>
+	<!-- Inform CP about current render mode (needed for a5xx preemption) -->
+	<value name="CP_SET_RENDER_MODE" value="0x6c" variants="A5XX"/>
+	<value name="CP_COMPUTE_CHECKPOINT" value="0x6e" variants="A5XX"/>
+	<!-- check if this works on earlier.. -->
+	<value name="CP_MEM_TO_MEM" value="0x73" variants="A5XX-"/>
+
+	<doc>
+		General purpose 2D blit engine for image transfers and mipmap
+		generation.  Reads through UCHE, writes through the CCU cache in
+		the PS stage.
+	</doc>
+	<value name="CP_BLIT" value="0x2c" variants="A5XX-"/>
+
+	<!-- Test specified bit in specified register and set predicate -->
+	<value name="CP_REG_TEST" value="0x39" variants="A5XX-"/>
+
+	<!--
+	Seems to set the mode flags which control which CP_SET_DRAW_STATE
+	packets are executed, based on their ENABLE_MASK values
+	
+	CP_SET_MODE w/ payload of 0x1 seems to cause CP_SET_DRAW_STATE
+	packets w/ ENABLE_MASK & 0x6 to execute immediately
+	 -->
+	<value name="CP_SET_MODE" value="0x63" variants="A6XX-"/>
+
+	<!--
+	Seems like there are now separate blocks of state for VS vs FS/CS
+	(probably these amounts to geometry vs fragments so that geometry
+	stage of the pipeline for next draw can start while fragment stage
+	of current draw is still running.  The format of the payload of the
+	packets is the same, the only difference is the offsets of the regs
+	the firmware code that handles the packet writes.
+
+	Note that for CL, starting with a6xx, the preferred # of local
+	threads is no longer the same as the max, implying that the shader
+	core can now run warps from unrelated shaders (ie.
+	CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE vs
+	CL_KERNEL_WORK_GROUP_SIZE)
+	 -->
+	<value name="CP_LOAD_STATE6_GEOM" value="0x32" variants="A6XX-"/>
+	<value name="CP_LOAD_STATE6_FRAG" value="0x34" variants="A6XX-"/>
+	<!--
+	Note: For IBO state (Image/SSBOs) which have shared state across
+	shader stages, for 3d pipeline CP_LOAD_STATE6 is used.  But for
+	compute shaders, CP_LOAD_STATE6_FRAG is used.  Possibly they are
+	interchangable.
+	 -->
+	<value name="CP_LOAD_STATE6" value="0x36" variants="A6XX-"/>
+
+	<!-- internal packets: -->
+	<value name="IN_IB_PREFETCH_END" value="0x17" variants="A2XX"/>
+	<value name="IN_SUBBLK_PREFETCH" value="0x1f" variants="A2XX"/>
+	<value name="IN_INSTR_PREFETCH" value="0x20" variants="A2XX"/>
+	<value name="IN_INSTR_MATCH" value="0x47" variants="A2XX"/>
+	<value name="IN_CONST_PREFETCH" value="0x49" variants="A2XX"/>
+	<value name="IN_INCR_UPDT_STATE" value="0x55" variants="A2XX"/>
+	<value name="IN_INCR_UPDT_CONST" value="0x56" variants="A2XX"/>
+	<value name="IN_INCR_UPDT_INSTR" value="0x57" variants="A2XX"/>
+
+	<!-- internal jumptable entries on a6xx+, possibly a5xx: -->
+
+	<!-- jmptable entry used to handle type4 packet on a5xx+: -->
+	<value name="PKT4" value="0x04" variants="A5XX-"/>
+	<!-- called when ROQ is empty, "returns" from an IB or merged sequence of IBs -->
+	<value name="IN_IB_END" value="0x0a" variants="A6XX-"/>
+	<!-- handles IFPC save/restore -->
+	<value name="IN_GMU_INTERRUPT" value="0x0b" variants="A6XX-"/>
+	<!-- preemption/context-swtich routine -->
+	<value name="IN_PREEMPT" value="0x0f" variants="A6XX-"/>
+
+	<!-- TODO do these exist on A5xx? -->
+	<value name="CP_SCRATCH_WRITE" value="0x4c" variants="A6XX"/>
+	<value name="CP_REG_TO_MEM_OFFSET_MEM" value="0x74" variants="A6XX-"/>
+	<value name="CP_REG_TO_MEM_OFFSET_REG" value="0x72" variants="A6XX-"/>
+	<value name="CP_WAIT_MEM_GTE" value="0x14" variants="A6XX"/>
+	<value name="CP_WAIT_TWO_REGS" value="0x70" variants="A6XX"/>
+	<value name="CP_MEMCPY" value="0x75" variants="A6XX-"/>
+	<value name="CP_SET_BIN_DATA5_OFFSET" value="0x2e" variants="A6XX-"/>
+	<!-- A750+, set in place of CP_SET_BIN_DATA5_OFFSET but has different values -->
+	<value name="CP_SET_UNK_BIN_DATA" value="0x2d" variants="A7XX-"/>
+	<doc>
+                Write CP_CONTEXT_SWITCH_*_INFO from CP to the following dwords,
+                and forcibly switch to the indicated context.
+	</doc>
+	<value name="CP_CONTEXT_SWITCH" value="0x54" variants="A6XX"/>
+	<value name="CP_SET_AMBLE" value="0x55" variants="A6XX-"/>
+
+	<!--
+	Seems to always have the payload:
+	  00000002 00008801 00004010
+	or:
+	  00000002 00008801 00004090
+	or:
+	  00000002 00008801 00000010
+	  00000002 00008801 00010010
+	  00000002 00008801 00d64010
+	  ...
+	Note set for compute shaders..
+	Is 0x8801 a register offset?
+	This appears to be a special sort of register write packet
+	more or less, but the firmware has some special handling..
+	Seems like it intercepts/modifies certain register offsets,
+	but others are treated like a normal PKT4 reg write.  I
+	guess there are some registers that the fw controls certain
+	bits.
+	 -->
+	<value name="CP_REG_WRITE" value="0x6d" variants="A6XX"/>
+
+	<doc>
+		These first appear in a650_sqe.bin. They can in theory be used
+		to loop any sequence of IB1 commands, but in practice they are
+		used to loop over bins. There is a fixed-size per-iteration
+		prefix, used to set per-bin state, and then the following IB1
+		commands are executed until CP_END_BIN which are always the same
+		for each iteration and usually contain a list of
+		CP_INDIRECT_BUFFER calls to IB2 commands which setup state and
+		execute restore/draw/save commands. This replaces the previous
+		technique of just repeating the CP_INDIRECT_BUFFER calls and
+		"unrolling" the loop.
+	</doc>
+	<value name="CP_START_BIN" value="0x50" variants="A6XX-"/>
+	<value name="CP_END_BIN" value="0x51" variants="A6XX-"/>
+
+	<doc> Make next dword 1 to disable preemption, 0 to re-enable it. </doc>
+	<value name="CP_PREEMPT_DISABLE" value="0x6c" variants="A6XX"/>
+
+	<value name="CP_WAIT_TIMESTAMP" value="0x14" variants="A7XX-"/>
+	<value name="CP_GLOBAL_TIMESTAMP" value="0x15" variants="A7XX-"/>  <!-- payload 1 dword -->
+	<value name="CP_LOCAL_TIMESTAMP" value="0x16" variants="A7XX-"/>  <!-- payload 1 dword, follows 0x15 -->
+	<value name="CP_THREAD_CONTROL" value="0x17" variants="A7XX-"/>
+	<!-- payload 4 dwords, last two could be render target addr (one pkt per MRT), possibly used for GMEM save/restore?-->
+	<value name="CP_RESOURCE_LIST" value="0x18" variants="A7XX-"/>
+	<doc> Can clear BV/BR counters, or wait until one catches up to another </doc>
+	<value name="CP_BV_BR_COUNT_OPS" value="0x1b" variants="A7XX-"/>
+	<doc> Clears, adds to local, or adds to global timestamp </doc>
+	<value name="CP_MODIFY_TIMESTAMP" value="0x1c" variants="A7XX-"/>
+	<!-- similar to CP_CONTEXT_REG_BUNCH, but discards first two dwords?? -->
+	<value name="CP_CONTEXT_REG_BUNCH2" value="0x5d" variants="A7XX-"/>
+	<doc>
+		Write to a scratch memory that is read by CP_REG_TEST with
+		SOURCE_SCRATCH_MEM set. It's not the same scratch as scratch registers.
+		However it uses the same memory space.
+	</doc>
+	<value name="CP_MEM_TO_SCRATCH_MEM" value="0x49" variants="A7XX-"/>
+
+	<doc>
+		Executes an array of fixed-size command buffers where each
+		buffer is assumed to have one draw call, skipping buffers with
+		non-visible draw calls.
+	</doc>
+	<value name="CP_FIXED_STRIDE_DRAW_TABLE" value="0x7f" variants="A7XX-"/>
+
+	<doc>Reset various on-chip state used for synchronization</doc>
+	<value name="CP_RESET_CONTEXT_STATE" value="0x1f" variants="A7XX-"/>
+</enum>
+
+
+<domain name="CP_LOAD_STATE" width="32">
+	<doc>Load state, a3xx (and later?)</doc>
+	<enum name="adreno_state_block">
+		<value name="SB_VERT_TEX" value="0"/>
+		<value name="SB_VERT_MIPADDR" value="1"/>
+		<value name="SB_FRAG_TEX" value="2"/>
+		<value name="SB_FRAG_MIPADDR" value="3"/>
+		<value name="SB_VERT_SHADER" value="4"/>
+		<value name="SB_GEOM_SHADER" value="5"/>
+		<value name="SB_FRAG_SHADER" value="6"/>
+		<value name="SB_COMPUTE_SHADER" value="7"/>
+	</enum>
+	<enum name="adreno_state_type">
+		<value name="ST_SHADER" value="0"/>
+		<value name="ST_CONSTANTS" value="1"/>
+	</enum>
+	<enum name="adreno_state_src">
+		<value name="SS_DIRECT" value="0">
+			<doc>inline with the CP_LOAD_STATE packet</doc>
+		</value>
+		<value name="SS_INVALID_ALL_IC" value="2"/>
+		<value name="SS_INVALID_PART_IC" value="3"/>
+		<value name="SS_INDIRECT" value="4">
+			<doc>in buffer pointed to by EXT_SRC_ADDR</doc>
+		</value>
+		<value name="SS_INDIRECT_TCM" value="5"/>
+		<value name="SS_INDIRECT_STM" value="6"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="DST_OFF" low="0" high="15" type="uint"/>
+		<bitfield name="STATE_SRC" low="16" high="18" type="adreno_state_src"/>
+		<bitfield name="STATE_BLOCK" low="19" high="21" type="adreno_state_block"/>
+		<bitfield name="NUM_UNIT" low="22" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="STATE_TYPE" low="0" high="1" type="adreno_state_type"/>
+		<bitfield name="EXT_SRC_ADDR" low="2" high="31" shr="2"/>
+	</reg32>
+</domain>
+
+<domain name="CP_LOAD_STATE4" width="32" varset="chip">
+	<doc>Load state, a4xx+</doc>
+	<enum name="a4xx_state_block">
+		<!--
+		unknown: 0x7 and 0xf <- seen in compute shader
+
+		STATE_BLOCK = 0x6, STATE_TYPE = 0x2 possibly used for preemption?
+		Seen in some GL shaders.  Payload is NUM_UNIT dwords, and it contains
+		the gpuaddr of the following shader constants block.  DST_OFF seems
+		to specify which shader stage:
+
+		    16 -> vert
+		    36 -> tcs
+		    56 -> tes
+		    76 -> geom
+		    96 -> frag
+
+		Example:
+
+opcode: CP_LOAD_STATE4 (30) (12 dwords)
+        { DST_OFF = 16 | STATE_SRC = SS4_DIRECT | STATE_BLOCK = 0x6 | NUM_UNIT = 4 }
+        { STATE_TYPE = 0x2 | EXT_SRC_ADDR = 0 }
+        { EXT_SRC_ADDR_HI = 0 }
+                        0000: c0264100 00000000 00000000 00000000
+                0000: 70b0000b 01180010 00000002 00000000 c0264100 00000000 00000000 00000000
+
+opcode: CP_LOAD_STATE4 (30) (4 dwords)
+        { DST_OFF = 16 | STATE_SRC = SS4_INDIRECT | STATE_BLOCK = SB4_VS_SHADER | NUM_UNIT = 4 }
+        { STATE_TYPE = ST4_CONSTANTS | EXT_SRC_ADDR = 0xc0264100 }
+        { EXT_SRC_ADDR_HI = 0 }
+                        0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
+                        0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
+                        0000: 00000040 0000000c 00000000 00000000 00000000 00000000 00000000 00000000
+
+		STATE_BLOCK = 0x6, STATE_TYPE = 0x1, seen in compute shader.  NUM_UNITS * 2 dwords.
+
+		 -->
+		<value name="SB4_VS_TEX"    value="0x0"/>
+		<value name="SB4_HS_TEX"    value="0x1"/>    <!-- aka. TCS -->
+		<value name="SB4_DS_TEX"    value="0x2"/>    <!-- aka. TES -->
+		<value name="SB4_GS_TEX"    value="0x3"/>
+		<value name="SB4_FS_TEX"    value="0x4"/>
+		<value name="SB4_CS_TEX"    value="0x5"/>
+		<value name="SB4_VS_SHADER" value="0x8"/>
+		<value name="SB4_HS_SHADER" value="0x9"/>
+		<value name="SB4_DS_SHADER" value="0xa"/>
+		<value name="SB4_GS_SHADER" value="0xb"/>
+		<value name="SB4_FS_SHADER" value="0xc"/>
+		<value name="SB4_CS_SHADER" value="0xd"/>
+		<!--
+		for SSBO, STATE_TYPE=0 appears to be addresses (four dwords each),
+		STATE_TYPE=1 sizes, STATE_TYPE=2 addresses again (two dwords each)
+
+		Compute has it's own dedicated SSBO state, it seems, but the rest
+		of the stages share state
+		 -->
+		<value name="SB4_SSBO"   value="0xe"/>
+		<value name="SB4_CS_SSBO"   value="0xf"/>
+	</enum>
+	<enum name="a4xx_state_type">
+		<value name="ST4_SHADER" value="0"/>
+		<value name="ST4_CONSTANTS" value="1"/>
+		<value name="ST4_UBO" value="2"/>
+	</enum>
+	<enum name="a4xx_state_src">
+		<value name="SS4_DIRECT" value="0"/>
+		<value name="SS4_INDIRECT" value="2"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="DST_OFF" low="0" high="13" type="uint"/>
+		<bitfield name="STATE_SRC" low="16" high="17" type="a4xx_state_src"/>
+		<bitfield name="STATE_BLOCK" low="18" high="21" type="a4xx_state_block"/>
+		<bitfield name="NUM_UNIT" low="22" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="STATE_TYPE" low="0" high="1" type="a4xx_state_type"/>
+		<bitfield name="EXT_SRC_ADDR" low="2" high="31" shr="2"/>
+	</reg32>
+	<reg32 offset="2" name="2" varset="chip" variants="A5XX-">
+		<bitfield name="EXT_SRC_ADDR_HI" low="0" high="31" shr="0"/>
+	</reg32>
+</domain>
+
+<!-- looks basically same CP_LOAD_STATE4 -->
+<domain name="CP_LOAD_STATE6" width="32" varset="chip">
+	<doc>Load state, a6xx+</doc>
+	<enum name="a6xx_state_block">
+		<value name="SB6_VS_TEX"    value="0x0"/>
+		<value name="SB6_HS_TEX"    value="0x1"/>    <!-- aka. TCS -->
+		<value name="SB6_DS_TEX"    value="0x2"/>    <!-- aka. TES -->
+		<value name="SB6_GS_TEX"    value="0x3"/>
+		<value name="SB6_FS_TEX"    value="0x4"/>
+		<value name="SB6_CS_TEX"    value="0x5"/>
+		<value name="SB6_VS_SHADER" value="0x8"/>
+		<value name="SB6_HS_SHADER" value="0x9"/>
+		<value name="SB6_DS_SHADER" value="0xa"/>
+		<value name="SB6_GS_SHADER" value="0xb"/>
+		<value name="SB6_FS_SHADER" value="0xc"/>
+		<value name="SB6_CS_SHADER" value="0xd"/>
+		<value name="SB6_IBO"       value="0xe"/>
+		<value name="SB6_CS_IBO"    value="0xf"/>
+	</enum>
+	<enum name="a6xx_state_type">
+		<value name="ST6_SHADER" value="0"/>
+		<value name="ST6_CONSTANTS" value="1"/>
+		<value name="ST6_UBO" value="2"/>
+		<value name="ST6_IBO" value="3"/>
+	</enum>
+	<enum name="a6xx_state_src">
+		<value name="SS6_DIRECT" value="0"/>
+		<value name="SS6_BINDLESS" value="1"/> <!-- TODO does this exist on a4xx/a5xx? -->
+		<value name="SS6_INDIRECT" value="2"/>
+		<doc>
+		SS6_UBO used by the a6xx vulkan blob with tesselation constants
+		in this case, EXT_SRC_ADDR is (ubo_id shl 16 | offset)
+		to load constants from a UBO loaded with DST_OFF = 14 and offset 0,
+		EXT_SRC_ADDR = 0xe0000
+		(offset is a guess, should be in bytes given that maxUniformBufferRange=64k)
+		</doc>
+		<value name="SS6_UBO" value="3"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="DST_OFF" low="0" high="13" type="uint"/>
+		<bitfield name="STATE_TYPE" low="14" high="15" type="a6xx_state_type"/>
+		<bitfield name="STATE_SRC" low="16" high="17" type="a6xx_state_src"/>
+		<bitfield name="STATE_BLOCK" low="18" high="21" type="a6xx_state_block"/>
+		<bitfield name="NUM_UNIT" low="22" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="EXT_SRC_ADDR" low="2" high="31" shr="2"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="EXT_SRC_ADDR_HI" low="0" high="31" shr="0"/>
+	</reg32>
+	<reg64 offset="1" name="EXT_SRC_ADDR" type="address"/>
+</domain>
+
+<bitset name="vgt_draw_initiator" inline="yes">
+	<bitfield name="PRIM_TYPE" low="0" high="5" type="pc_di_primtype"/>
+	<bitfield name="SOURCE_SELECT" low="6" high="7" type="pc_di_src_sel"/>
+	<bitfield name="VIS_CULL" low="9" high="10" type="pc_di_vis_cull_mode"/>
+	<bitfield name="INDEX_SIZE" pos="11" type="pc_di_index_size"/>
+	<bitfield name="NOT_EOP" pos="12" type="boolean"/>
+	<bitfield name="SMALL_INDEX" pos="13" type="boolean"/>
+	<bitfield name="PRE_DRAW_INITIATOR_ENABLE" pos="14" type="boolean"/>
+	<bitfield name="NUM_INSTANCES" low="24" high="31" type="uint"/>
+</bitset>
+
+<!-- changed on a4xx: -->
+<enum name="a4xx_index_size">
+	<value name="INDEX4_SIZE_8_BIT" value="0"/>
+	<value name="INDEX4_SIZE_16_BIT" value="1"/>
+	<value name="INDEX4_SIZE_32_BIT" value="2"/>
+</enum>
+
+<enum name="a6xx_patch_type">
+  <value name="TESS_QUADS" value="0"/>
+  <value name="TESS_TRIANGLES" value="1"/>
+  <value name="TESS_ISOLINES" value="2"/>
+</enum>
+
+<bitset name="vgt_draw_initiator_a4xx" inline="yes">
+	<!-- When the 0x20 bit is set, it's the number of patch vertices - 1 -->
+	<bitfield name="PRIM_TYPE" low="0" high="5" type="pc_di_primtype"/>
+	<bitfield name="SOURCE_SELECT" low="6" high="7" type="pc_di_src_sel"/>
+	<bitfield name="VIS_CULL" low="8" high="9" type="pc_di_vis_cull_mode"/>
+	<bitfield name="INDEX_SIZE" low="10" high="11" type="a4xx_index_size"/>
+	<bitfield name="PATCH_TYPE" low="12" high="13" type="a6xx_patch_type"/>
+	<bitfield name="GS_ENABLE" pos="16" type="boolean"/>
+	<bitfield name="TESS_ENABLE" pos="17" type="boolean"/>
+</bitset>
+
+<domain name="CP_DRAW_INDX" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="VIZ_QUERY" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1" type="vgt_draw_initiator"/>
+	<reg32 offset="2" name="2">
+		<bitfield name="NUM_INDICES" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="INDX_BASE" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="INDX_SIZE" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_DRAW_INDX_2" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="VIZ_QUERY" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1" type="vgt_draw_initiator"/>
+	<reg32 offset="2" name="2">
+		<bitfield name="NUM_INDICES" low="0" high="31" type="uint"/>
+	</reg32>
+	<!-- followed by NUM_INDICES indices.. -->
+</domain>
+
+<domain name="CP_DRAW_INDX_OFFSET" width="32">
+	<reg32 offset="0" name="0" type="vgt_draw_initiator_a4xx"/>
+	<reg32 offset="1" name="1">
+		<bitfield name="NUM_INSTANCES" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="NUM_INDICES" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="FIRST_INDX" low="0" high="31"/>
+	</reg32>
+
+	<stripe varset="chip" variants="A5XX-">
+		<reg32 offset="4" name="4">
+			<bitfield name="INDX_BASE_LO" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="5" name="5">
+			<bitfield name="INDX_BASE_HI" low="0" high="31"/>
+		</reg32>
+		<reg64 offset="4" name="INDX_BASE" type="address"/>
+		<reg32 offset="6" name="6">
+			<!-- max # of elements in index buffer -->
+			<bitfield name="MAX_INDICES" low="0" high="31"/>
+		</reg32>
+	</stripe>
+
+	<reg32 offset="4" name="4">
+		<bitfield name="INDX_BASE" low="0" high="31" type="address"/>
+	</reg32>
+
+	<reg32 offset="5" name="5">
+		<bitfield name="INDX_SIZE" low="0" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_DRAW_INDIRECT" width="32" varset="chip" prefix="chip" variants="A4XX-">
+	<reg32 offset="0" name="0" type="vgt_draw_initiator_a4xx"/>
+	<stripe varset="chip" variants="A4XX">
+		<reg32 offset="1" name="1">
+			<bitfield name="INDIRECT" low="0" high="31"/>
+		</reg32>
+	</stripe>
+	<stripe varset="chip" variants="A5XX-">
+		<reg32 offset="1" name="1">
+			<bitfield name="INDIRECT_LO" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="2" name="2">
+			<bitfield name="INDIRECT_HI" low="0" high="31"/>
+		</reg32>
+		<reg64 offset="1" name="INDIRECT" type="address"/>
+	</stripe>
+</domain>
+
+<domain name="CP_DRAW_INDX_INDIRECT" width="32" varset="chip" prefix="chip" variants="A4XX-">
+	<reg32 offset="0" name="0" type="vgt_draw_initiator_a4xx"/>
+	<stripe varset="chip" variants="A4XX">
+		<reg32 offset="1" name="1">
+			<bitfield name="INDX_BASE" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="2" name="2">
+			<!-- max # of bytes in index buffer -->
+			<bitfield name="INDX_SIZE" low="0" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="3" name="3">
+			<bitfield name="INDIRECT" low="0" high="31"/>
+		</reg32>
+	</stripe>
+	<stripe varset="chip" variants="A5XX-">
+		<reg32 offset="1" name="1">
+			<bitfield name="INDX_BASE_LO" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="2" name="2">
+			<bitfield name="INDX_BASE_HI" low="0" high="31"/>
+		</reg32>
+		<reg64 offset="1" name="INDX_BASE" type="address"/>
+		<reg32 offset="3" name="3">
+			<!-- max # of elements in index buffer -->
+			<bitfield name="MAX_INDICES" low="0" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="4" name="4">
+			<bitfield name="INDIRECT_LO" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="5" name="5">
+			<bitfield name="INDIRECT_HI" low="0" high="31"/>
+		</reg32>
+		<reg64 offset="4" name="INDIRECT" type="address"/>
+	</stripe>
+</domain>
+
+<domain name="CP_DRAW_INDIRECT_MULTI" width="32" varset="chip" prefix="chip" variants="A6XX-">
+	<enum name="a6xx_draw_indirect_opcode">
+		<value name="INDIRECT_OP_NORMAL"  value="0x2"/>
+		<value name="INDIRECT_OP_INDEXED" value="0x4"/>
+		<value name="INDIRECT_OP_INDIRECT_COUNT" value="0x6"/>
+		<value name="INDIRECT_OP_INDIRECT_COUNT_INDEXED" value="0x7"/>
+	</enum>
+	<reg32 offset="0" name="0" type="vgt_draw_initiator_a4xx"/>
+	<reg32 offset="1" name="1">
+		<bitfield name="OPCODE" low="0" high="3" type="a6xx_draw_indirect_opcode" addvariant="yes"/>
+		<doc>
+		DST_OFF same as in CP_LOAD_STATE6 - vec4 VS const at this offset will
+		be updated for each draw to {draw_id, first_vertex, first_instance, 0}
+		value of 0 disables it
+		</doc>
+		<bitfield name="DST_OFF" low="8" high="21" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="DRAW_COUNT" type="uint"/>
+	<stripe varset="a6xx_draw_indirect_opcode" variants="INDIRECT_OP_NORMAL">
+		<reg64 offset="3" name="INDIRECT" type="address"/>
+		<reg32 offset="5" name="STRIDE" type="uint"/>
+	</stripe>
+	<stripe varset="a6xx_draw_indirect_opcode" variants="INDIRECT_OP_INDEXED" prefix="INDEXED">
+		<reg64 offset="3" name="INDEX" type="address"/>
+		<reg32 offset="5" name="MAX_INDICES" type="uint"/>
+		<reg64 offset="6" name="INDIRECT" type="address"/>
+		<reg32 offset="8" name="STRIDE" type="uint"/>
+	</stripe>
+	<stripe varset="a6xx_draw_indirect_opcode" variants="INDIRECT_OP_INDIRECT_COUNT" prefix="INDIRECT">
+		<reg64 offset="3" name="INDIRECT" type="address"/>
+		<reg64 offset="5" name="INDIRECT_COUNT" type="address"/>
+		<reg32 offset="7" name="STRIDE" type="uint"/>
+	</stripe>
+	<stripe varset="a6xx_draw_indirect_opcode" variants="INDIRECT_OP_INDIRECT_COUNT_INDEXED" prefix="INDIRECT_INDEXED">
+		<reg64 offset="3" name="INDEX" type="address"/>
+		<reg32 offset="5" name="MAX_INDICES" type="uint"/>
+		<reg64 offset="6" name="INDIRECT" type="address"/>
+		<reg64 offset="8" name="INDIRECT_COUNT" type="address"/>
+		<reg32 offset="10" name="STRIDE" type="uint"/>
+	</stripe>
+</domain>
+
+<domain name="CP_DRAW_AUTO" width="32">
+	<reg32 offset="0" name="0" type="vgt_draw_initiator_a4xx"/>
+	<reg32 offset="1" name="1">
+		<bitfield name="NUM_INSTANCES" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg64 offset="2" name="NUM_VERTICES_BASE" type="address"/>
+	<reg32 offset="4" name="4">
+		<bitfield name="NUM_VERTICES_OFFSET" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="STRIDE" low="0" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_DRAW_PRED_ENABLE_GLOBAL" width="32" varset="chip">
+	<reg32 offset="0" name="0">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+	</reg32>
+</domain>
+
+<domain name="CP_DRAW_PRED_ENABLE_LOCAL" width="32" varset="chip">
+	<reg32 offset="0" name="0">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+	</reg32>
+</domain>
+
+<domain name="CP_DRAW_PRED_SET" width="32" varset="chip">
+	<enum name="cp_draw_pred_src">
+		<!--
+			Sources 1-4 seem to be about combining reading
+			SO/primitive queries and setting the predicate, which is
+			a DX11-specific optimization (since in DX11 you can only
+			predicate on the result of queries).
+		-->
+		<value name="PRED_SRC_MEM" value="5">
+			<doc>
+				Read a 64-bit value at the given address and
+				test if it equals/doesn't equal 0.
+			</doc>
+		</value>
+	</enum>
+	<enum name="cp_draw_pred_test">
+		<value name="NE_0_PASS" value="0"/>
+		<value name="EQ_0_PASS" value="1"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="SRC" low="4" high="7" type="cp_draw_pred_src"/>
+		<bitfield name="TEST" pos="8" type="cp_draw_pred_test"/>
+	</reg32>
+	<reg64 offset="1" name="MEM_ADDR" type="address"/>
+</domain>
+
+<domain name="CP_SET_DRAW_STATE" width="32" varset="chip" variants="A4XX-">
+	<array offset="0" stride="3" length="100">
+		<reg32 offset="0" name="0">
+			<bitfield name="COUNT" low="0" high="15" type="uint"/>
+			<bitfield name="DIRTY" pos="16" type="boolean"/>
+			<bitfield name="DISABLE" pos="17" type="boolean"/>
+			<bitfield name="DISABLE_ALL_GROUPS" pos="18" type="boolean"/>
+			<bitfield name="LOAD_IMMED" pos="19" type="boolean"/>
+			<bitfield name="BINNING" pos="20" varset="chip" variants="A6XX-" type="boolean"/>
+			<bitfield name="GMEM" pos="21" varset="chip" variants="A6XX-" type="boolean"/>
+			<bitfield name="SYSMEM" pos="22" varset="chip" variants="A6XX-" type="boolean"/>
+			<bitfield name="GROUP_ID" low="24" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="1" name="1">
+			<bitfield name="ADDR_LO" low="0" high="31" type="hex"/>
+		</reg32>
+		<reg32 offset="2" name="2" varset="chip" variants="A5XX-">
+			<bitfield name="ADDR_HI" low="0" high="31" type="hex"/>
+		</reg32>
+	</array>
+</domain>
+
+<domain name="CP_SET_BIN" width="32">
+	<doc>value at offset 0 always seems to be 0x00000000..</doc>
+	<reg32 offset="0" name="0"/>
+	<reg32 offset="1" name="1">
+		<bitfield name="X1" low="0" high="15" type="uint"/>
+		<bitfield name="Y1" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="X2" low="0" high="15" type="uint"/>
+		<bitfield name="Y2" low="16" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_SET_BIN_DATA" width="32">
+	<reg32 offset="0" name="0">
+		<!-- corresponds to VSC_PIPE[n].DATA_ADDR -->
+		<bitfield name="BIN_DATA_ADDR" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<!-- seesm to correspond to VSC_SIZE_ADDRESS -->
+		<bitfield name="BIN_SIZE_ADDRESS" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_SET_BIN_DATA5" width="32">
+	<reg32 offset="0" name="0">
+		<!-- equiv to PC_VSTREAM_CONTROL.SIZE on a3xx/a4xx: -->
+		<bitfield name="VSC_SIZE" low="16" high="21" type="uint"/>
+		<!-- equiv to PC_VSTREAM_CONTROL.N on a3xx/a4xx: -->
+		<bitfield name="VSC_N" low="22" high="26" type="uint"/>
+	</reg32>
+	<!-- BIN_DATA_ADDR -> VSC_PIPE[p].DATA_ADDRESS -->
+	<reg32 offset="1" name="1">
+		<bitfield name="BIN_DATA_ADDR_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="BIN_DATA_ADDR_HI" low="0" high="31" type="hex"/>
+	</reg32>
+	<!-- BIN_SIZE_ADDRESS -> VSC_SIZE_ADDRESS + (p * 4)-->
+	<reg32 offset="3" name="3">
+		<bitfield name="BIN_SIZE_ADDRESS_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="BIN_SIZE_ADDRESS_HI" low="0" high="31"/>
+	</reg32>
+	<!-- new on a6xx, where BIN_DATA_ADDR is the DRAW_STRM: -->
+	<reg32 offset="5" name="5">
+		<bitfield name="BIN_PRIM_STRM_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="6" name="6">
+		<bitfield name="BIN_PRIM_STRM_HI" low="0" high="31"/>
+	</reg32>
+	<!--
+		a7xx adds a few more addresses to the end of the pkt
+	 -->
+	<reg64 offset="7" name="7"/>
+	<reg64 offset="9" name="9"/>
+</domain>
+
+<domain name="CP_SET_BIN_DATA5_OFFSET" width="32">
+	<doc>
+                Like CP_SET_BIN_DATA5, but set the pointers as offsets from the
+                pointers stored in VSC_PIPE_{DATA,DATA2,SIZE}_ADDRESS. Useful
+                for Vulkan where these values aren't known when the command
+                stream is recorded.
+	</doc>
+	<reg32 offset="0" name="0">
+		<!-- equiv to PC_VSTREAM_CONTROL.SIZE on a3xx/a4xx: -->
+		<bitfield name="VSC_SIZE" low="16" high="21" type="uint"/>
+		<!-- equiv to PC_VSTREAM_CONTROL.N on a3xx/a4xx: -->
+		<bitfield name="VSC_N" low="22" high="26" type="uint"/>
+	</reg32>
+	<!-- BIN_DATA_ADDR -> VSC_PIPE[p].DATA_ADDRESS -->
+	<reg32 offset="1" name="1">
+		<bitfield name="BIN_DATA_OFFSET" low="0" high="31" type="uint"/>
+	</reg32>
+	<!-- BIN_SIZE_ADDRESS -> VSC_SIZE_ADDRESS + (p * 4)-->
+	<reg32 offset="2" name="2">
+		<bitfield name="BIN_SIZE_OFFSET" low="0" high="31" type="uint"/>
+	</reg32>
+	<!-- BIN_DATA2_ADDR -> VSC_PIPE[p].DATA2_ADDRESS -->
+	<reg32 offset="3" name="3">
+		<bitfield name="BIN_DATA2_OFFSET" low="0" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_REG_RMW" width="32">
+	<doc>
+                Modifies DST_REG using two sources that can either be registers
+                or immediates. If SRC1_ADD is set, then do the following:
+
+			$dst = (($dst &amp; $src0) rot $rotate) + $src1
+
+		Otherwise:
+
+			$dst = (($dst &amp; $src0) rot $rotate) | $src1
+
+		Here "rot" means rotate left.
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="DST_REG" low="0" high="17" type="hex"/>
+		<bitfield name="ROTATE" low="24" high="28" type="uint"/>
+		<bitfield name="SRC1_ADD" pos="29" type="boolean"/>
+		<bitfield name="SRC1_IS_REG" pos="30" type="boolean"/>
+		<bitfield name="SRC0_IS_REG" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="SRC0" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="SRC1" low="0" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_REG_TO_MEM" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="REG" low="0" high="17" type="hex"/>
+		<!-- number of registers/dwords copied is max(CNT, 1). -->
+		<bitfield name="CNT" low="18" high="29" type="uint"/>
+		<bitfield name="64B" pos="30" type="boolean"/>
+		<bitfield name="ACCUMULATE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="DEST" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2" varset="chip" variants="A5XX-">
+		<bitfield name="DEST_HI" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_REG_TO_MEM_OFFSET_REG" width="32">
+	<doc>
+                Like CP_REG_TO_MEM, but the memory address to write to can be
+                offsetted using either one or two registers or scratch
+                registers.
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="REG" low="0" high="17" type="hex"/>
+		<!-- number of registers/dwords copied is max(CNT, 1). -->
+		<bitfield name="CNT" low="18" high="29" type="uint"/>
+		<bitfield name="64B" pos="30" type="boolean"/>
+		<bitfield name="ACCUMULATE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="DEST" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2" varset="chip" variants="A5XX-">
+		<bitfield name="DEST_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="OFFSET0" low="0" high="17" type="hex"/>
+		<bitfield name="OFFSET0_SCRATCH" pos="19" type="boolean"/>
+	</reg32>
+	<!-- followed by an optional identical OFFSET1 dword -->
+</domain>
+
+<domain name="CP_REG_TO_MEM_OFFSET_MEM" width="32">
+	<doc>
+                Like CP_REG_TO_MEM, but the memory address to write to can be
+                offsetted using a DWORD in memory.
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="REG" low="0" high="17" type="hex"/>
+		<!-- number of registers/dwords copied is max(CNT, 1). -->
+		<bitfield name="CNT" low="18" high="29" type="uint"/>
+		<bitfield name="64B" pos="30" type="boolean"/>
+		<bitfield name="ACCUMULATE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="DEST" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2" varset="chip" variants="A5XX-">
+		<bitfield name="DEST_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="OFFSET_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="OFFSET_HI" low="0" high="31" type="hex"/>
+	</reg32>
+</domain>
+
+<domain name="CP_MEM_TO_REG" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="REG" low="0" high="17" type="hex"/>
+		<!-- number of registers/dwords copied is max(CNT, 1). -->
+		<bitfield name="CNT" low="19" high="29" type="uint"/>
+		<!-- shift each DWORD left by 2 while copying -->
+		<bitfield name="SHIFT_BY_2" pos="30" type="boolean"/>
+		<!-- does the same thing as CP_MEM_TO_MEM::UNK31 -->
+		<bitfield name="UNK31" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="SRC" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2" varset="chip" variants="A5XX-">
+		<bitfield name="SRC_HI" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_MEM_TO_MEM" width="32">
+	<reg32 offset="0" name="0">
+		<!--
+		not sure how many src operands we have, but the low
+		bits negate the n'th src argument.
+		 -->
+		<bitfield name="NEG_A" pos="0" type="boolean"/>
+		<bitfield name="NEG_B" pos="1" type="boolean"/>
+		<bitfield name="NEG_C" pos="2" type="boolean"/>
+
+		<!-- if set treat src/dst as 64bit values -->
+		<bitfield name="DOUBLE" pos="29" type="boolean"/>
+		<!-- execute CP_WAIT_FOR_MEM_WRITES beforehand -->
+		<bitfield name="WAIT_FOR_MEM_WRITES" pos="30" type="boolean"/>
+		<!-- some other kind of wait -->
+		<bitfield name="UNK31" pos="31" type="boolean"/>
+	</reg32>
+	<!--
+	followed by sequence of addresses.. the first is the
+	destination and the rest are N src addresses which are
+	summed (after being negated if NEG_x bit set) allowing
+	to do things like 'result += end - start' (which turns
+	out to be useful for queries and accumulating results
+	across multiple tiles)
+	 -->
+</domain>
+
+<domain name="CP_MEMCPY" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="DWORDS" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="SRC_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="SRC_HI" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="DST_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="DST_HI" low="0" high="31" type="hex"/>
+	</reg32>
+</domain>
+
+<domain name="CP_REG_TO_SCRATCH" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="REG" low="0" high="17" type="hex"/>
+		<bitfield name="SCRATCH" low="20" high="22" type="uint"/>
+		<!-- number of registers/dwords copied is CNT + 1. -->
+		<bitfield name="CNT" low="24" high="26" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_SCRATCH_TO_REG" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="REG" low="0" high="17" type="hex"/>
+		<!-- note: CP_MEM_TO_REG always sets this when writing to the register -->
+		<bitfield name="UNK18" pos="18" type="boolean"/>
+		<bitfield name="SCRATCH" low="20" high="22" type="uint"/>
+		<!-- number of registers/dwords copied is CNT + 1. -->
+		<bitfield name="CNT" low="24" high="26" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_SCRATCH_WRITE" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="SCRATCH" low="20" high="22" type="uint"/>
+	</reg32>
+	<!-- followed by one or more DWORDs to write to scratch registers -->
+</domain>
+
+<domain name="CP_MEM_WRITE" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="ADDR_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="ADDR_HI" low="0" high="31"/>
+	</reg32>
+	<!-- followed by the DWORDs to write -->
+</domain>
+
+<enum name="cp_cond_function">
+	<value value="0" name="WRITE_ALWAYS"/>
+	<value value="1" name="WRITE_LT"/>
+	<value value="2" name="WRITE_LE"/>
+	<value value="3" name="WRITE_EQ"/>
+	<value value="4" name="WRITE_NE"/>
+	<value value="5" name="WRITE_GE"/>
+	<value value="6" name="WRITE_GT"/>
+</enum>
+
+<domain name="CP_COND_WRITE" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="FUNCTION" low="0" high="2" type="cp_cond_function"/>
+		<bitfield name="POLL_MEMORY" pos="4" type="boolean"/>
+		<bitfield name="WRITE_MEMORY" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="POLL_ADDR" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="REF" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="MASK" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="WRITE_ADDR" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="WRITE_DATA" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<enum name="poll_memory_type">
+	<value value="0" name="POLL_REGISTER"/>
+	<value value="1" name="POLL_MEMORY"/>
+	<value value="2" name="POLL_SCRATCH"/>
+	<value value="3" name="POLL_ON_CHIP" varset="chip" variants="A7XX-"/>
+</enum>
+
+<domain name="CP_COND_WRITE5" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="FUNCTION" low="0" high="2" type="cp_cond_function"/>
+		<bitfield name="SIGNED_COMPARE" pos="3" type="boolean"/>
+		<!-- POLL_REGISTER polls a register at POLL_ADDR_LO. -->
+		<bitfield name="POLL" low="4" high="5" type="poll_memory_type"/>
+		<bitfield name="WRITE_MEMORY" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="POLL_ADDR_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="POLL_ADDR_HI" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="REF" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="MASK" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="WRITE_ADDR_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="6" name="6">
+		<bitfield name="WRITE_ADDR_HI" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="7" name="7">
+		<bitfield name="WRITE_DATA" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_WAIT_MEM_GTE" width="32">
+        <doc>
+                Wait until a memory value is greater than or equal to the
+                reference, using signed comparison.
+	</doc>
+	<reg32 offset="0" name="0">
+		<!-- Reserved for flags, presumably? Unused in FW -->
+		<bitfield name="RESERVED" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="POLL_ADDR_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="POLL_ADDR_HI" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="REF" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_WAIT_REG_MEM" width="32">
+        <doc>
+                This uses the same internal comparison as CP_COND_WRITE,
+                but waits until the comparison is true instead. It busy-loops in
+                the CP for the given number of cycles before trying again.
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="FUNCTION" low="0" high="2" type="cp_cond_function"/>
+		<bitfield name="SIGNED_COMPARE" pos="3" type="boolean"/>
+		<bitfield name="POLL" low="4" high="5" type="poll_memory_type"/>
+		<bitfield name="WRITE_MEMORY" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="POLL_ADDR_LO" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="POLL_ADDR_HI" low="0" high="31" type="hex"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="REF" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="MASK" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="DELAY_LOOP_CYCLES" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_WAIT_TWO_REGS" width="32">
+	<doc>
+		Waits for REG0 to not be 0 or REG1 to not equal REF
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="REG0" low="0" high="17" type="hex"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="REG1" low="0" high="17" type="hex"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="REF" low="0" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_DISPATCH_COMPUTE" width="32">
+	<reg32 offset="0" name="0"/>
+	<reg32 offset="1" name="1">
+		<bitfield name="X" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="Y" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="Z" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_SET_RENDER_MODE" width="32">
+	<enum name="render_mode_cmd">
+		<value value="1" name="BYPASS"/>
+		<value value="2" name="BINNING"/>
+		<value value="3" name="GMEM"/>
+		<value value="5" name="BLIT2D"/>
+		<!-- placeholder name.. used when CP_BLIT packets with BLIT_OP_SCALE?? -->
+		<value value="7" name="BLIT2DSCALE"/>
+		<!-- 8 set before going back to BYPASS exiting 2D -->
+		<value value="8" name="END2D"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="MODE" low="0" high="8" type="render_mode_cmd"/>
+		<!--
+		normally 0x1/0x3, sometimes see 0x5/0x8 with unknown registers in
+		0x21xx range.. possibly (at least some) a5xx variants have a
+		2d core?
+		 -->
+	</reg32>
+	<!-- I think first buffer is for GPU to save context in case of ctx switch? -->
+	<reg32 offset="1" name="1">
+		<bitfield name="ADDR_0_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="ADDR_0_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<!--
+		set when in GMEM.. maybe indicates GMEM contents need to be
+		preserved on ctx switch?
+		 -->
+		<bitfield name="VSC_ENABLE" pos="3" type="boolean"/>
+		<bitfield name="GMEM_ENABLE" pos="4" type="boolean"/>
+	</reg32>
+	<reg32 offset="4" name="4"/>
+	<!-- second buffer looks like some cmdstream.. length in dwords: -->
+	<reg32 offset="5" name="5">
+		<bitfield name="ADDR_1_LEN" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="6" name="6">
+		<bitfield name="ADDR_1_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="7" name="7">
+		<bitfield name="ADDR_1_HI" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<!-- this looks fairly similar to CP_SET_RENDER_MODE minus first dword -->
+<domain name="CP_COMPUTE_CHECKPOINT" width="32">
+	<!-- I think first buffer is for GPU to save context in case of ctx switch? -->
+	<reg32 offset="0" name="0">
+		<bitfield name="ADDR_0_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="ADDR_0_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+	</reg32>
+	<reg32 offset="3" name="3"/>
+	<!-- second buffer looks like some cmdstream.. length in dwords: -->
+	<reg32 offset="4" name="4">
+		<bitfield name="ADDR_1_LEN" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="ADDR_1_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="6" name="6">
+		<bitfield name="ADDR_1_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="7" name="7"/>
+</domain>
+
+<domain name="CP_PERFCOUNTER_ACTION" width="32">
+	<reg32 offset="0" name="0">
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="ADDR_0_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="ADDR_0_HI" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain varset="chip" name="CP_EVENT_WRITE" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="EVENT" low="0" high="7" type="vgt_event_type"/>
+		<!-- when set, write back timestamp instead of value from packet: -->
+		<bitfield name="TIMESTAMP" pos="30" type="boolean"/>
+		<bitfield name="IRQ" pos="31" type="boolean"/>
+	</reg32>
+	<!--
+	TODO what is gpuaddr for, seems to be all 0's.. maybe needed for
+	context switch?
+	 -->
+	<reg32 offset="1" name="1">
+		<bitfield name="ADDR_0_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="ADDR_0_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<!-- ??? -->
+	</reg32>
+</domain>
+
+<domain varset="chip" name="CP_EVENT_WRITE7" width="32">
+	<enum name="event_write_src">
+		<!-- Write payload[0] -->
+		<value value="0" name="EV_WRITE_USER_32B"/>
+		<!-- Write payload[0] payload[1] -->
+		<value value="1" name="EV_WRITE_USER_64B"/>
+		<!-- Write (TIMESTAMP_GLOBAL + TIMESTAMP_LOCAL) -->
+		<value value="2" name="EV_WRITE_TIMESTAMP_SUM"/>
+		<value value="3" name="EV_WRITE_ALWAYSON"/>
+		<!-- Write payload[1] regs starting at payload[0] offset -->
+		<value value="4" name="EV_WRITE_REGS_CONTENT"/>
+	</enum>
+
+	<enum name="event_write_dst">
+		<value value="0" name="EV_DST_RAM"/>
+		<value value="1" name="EV_DST_ONCHIP"/>
+	</enum>
+
+	<reg32 offset="0" name="0">
+		<bitfield name="EVENT" low="0" high="7" type="vgt_event_type"/>
+		<bitfield name="WRITE_SAMPLE_COUNT" pos="12" type="boolean"/>
+		<!-- Write sample count at (iova + 16) -->
+		<bitfield name="SAMPLE_COUNT_END_OFFSET" pos="13" type="boolean"/>
+		<!-- *(iova + 8) = *(iova + 16) - *iova -->
+		<bitfield name="WRITE_SAMPLE_COUNT_DIFF" pos="14" type="boolean"/>
+
+		<!-- Next 4 flags are valid to set only when concurrent binning is enabled -->
+		<!-- Increment 16b BV counter. Valid only in BV pipe -->
+		<bitfield name="INC_BV_COUNT" pos="16" type="boolean"/>
+		<!-- Increment 16b BR counter. Valid only in BR pipe -->
+		<bitfield name="INC_BR_COUNT" pos="17" type="boolean"/>
+		<bitfield name="CLEAR_RENDER_RESOURCE" pos="18" type="boolean"/>
+		<bitfield name="CLEAR_LRZ_RESOURCE" pos="19" type="boolean"/>
+
+		<bitfield name="WRITE_SRC" low="20" high="22" type="event_write_src"/>
+		<bitfield name="WRITE_DST" pos="24" type="event_write_dst" addvariant="yes"/>
+		<!-- Writes into WRITE_DST from WRITE_SRC. RB_DONE_TS requires WRITE_ENABLED. -->
+		<bitfield name="WRITE_ENABLED" pos="27" type="boolean"/>
+	</reg32>
+
+	<stripe varset="event_write_dst" variants="EV_DST_RAM">
+		<reg32 offset="1" name="1">
+			<bitfield name="ADDR_0_LO" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="2" name="2">
+			<bitfield name="ADDR_0_HI" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="3" name="3">
+			<bitfield name="PAYLOAD_0" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="4" name="4">
+			<bitfield name="PAYLOAD_1" low="0" high="31"/>
+		</reg32>
+	</stripe>
+
+	<stripe varset="event_write_dst" variants="EV_DST_ONCHIP">
+		<reg32 offset="1" name="1">
+			<bitfield name="ONCHIP_ADDR_0" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="3" name="3">
+			<bitfield name="PAYLOAD_0" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="4" name="4">
+			<bitfield name="PAYLOAD_1" low="0" high="31"/>
+		</reg32>
+	</stripe>
+</domain>
+
+<domain name="CP_BLIT" width="32">
+	<enum name="cp_blit_cmd">
+		<value value="0" name="BLIT_OP_FILL"/>
+		<value value="1" name="BLIT_OP_COPY"/>
+		<value value="3" name="BLIT_OP_SCALE"/> <!-- used for mipmap generation -->
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="OP" low="0" high="3" type="cp_blit_cmd"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="SRC_X1" low="0" high="13" type="uint"/>
+		<bitfield name="SRC_Y1" low="16" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="SRC_X2" low="0" high="13" type="uint"/>
+		<bitfield name="SRC_Y2" low="16" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="DST_X1" low="0" high="13" type="uint"/>
+		<bitfield name="DST_Y1" low="16" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="DST_X2" low="0" high="13" type="uint"/>
+		<bitfield name="DST_Y2" low="16" high="29" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_EXEC_CS" width="32">
+	<reg32 offset="0" name="0">
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="NGROUPS_X" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="NGROUPS_Y" low="0" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="NGROUPS_Z" low="0" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_EXEC_CS_INDIRECT" width="32" varset="chip" prefix="chip" variants="A4XX-">
+	<reg32 offset="0" name="0">
+	</reg32>
+	<stripe varset="chip" variants="A4XX">
+		<reg32 offset="1" name="1">
+			<bitfield name="ADDR" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="2" name="2">
+			<!-- localsize is value minus one: -->
+			<bitfield name="LOCALSIZEX" low="2" high="11" type="uint"/>
+			<bitfield name="LOCALSIZEY" low="12" high="21" type="uint"/>
+			<bitfield name="LOCALSIZEZ" low="22" high="31" type="uint"/>
+		</reg32>
+	</stripe>
+	<stripe varset="chip" variants="A5XX-">
+		<reg32 offset="1" name="1">
+			<bitfield name="ADDR_LO" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="2" name="2">
+			<bitfield name="ADDR_HI" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="3" name="3">
+			<!-- localsize is value minus one: -->
+			<bitfield name="LOCALSIZEX" low="2" high="11" type="uint"/>
+			<bitfield name="LOCALSIZEY" low="12" high="21" type="uint"/>
+			<bitfield name="LOCALSIZEZ" low="22" high="31" type="uint"/>
+		</reg32>
+	</stripe>
+</domain>
+
+<domain name="CP_SET_MARKER" width="32" varset="chip" prefix="chip" variants="A6XX-">
+	<doc>Tell CP the current operation mode, indicates save and restore procedure</doc>
+	<enum name="a6xx_marker">
+		<value value="1" name="RM6_BYPASS"/>
+		<value value="2" name="RM6_BINNING"/>
+		<value value="4" name="RM6_GMEM"/>
+		<value value="5" name="RM6_ENDVIS"/>
+		<value value="6" name="RM6_RESOLVE"/>
+		<value value="7" name="RM6_YIELD"/>
+		<value value="8" name="RM6_COMPUTE"/>
+		<value value="0xc" name="RM6_BLIT2DSCALE"/>  <!-- no-op (at least on current sqe fw) -->
+
+		<!--
+			These values come from a6xx_set_marker() in the
+			downstream kernel, and they can only be set by the kernel
+		-->
+		<value value="0xd" name="RM6_IB1LIST_START"/>
+		<value value="0xe" name="RM6_IB1LIST_END"/>
+		<!-- IFPC - inter-frame power collapse -->
+		<value value="0x100" name="RM6_IFPC_ENABLE"/>
+		<value value="0x101" name="RM6_IFPC_DISABLE"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<!--
+			NOTE: blob driver and some versions of freedreno/turnip set
+			b4, which is unused (at least by current sqe fw), but interferes
+			with parsing if we extend the size of the bitfield to include
+			b8 (only sent by kernel mode driver).  Really, the way the
+			parsing works in the firmware, only b0-b3 are considered, but
+			if b8 is set, the low bits are interpreted differently.  To
+			model this, without getting confused by spurious b4, this is
+			described as two overlapping bitfields:
+		 -->
+		<bitfield name="MODE" low="0" high="8" type="a6xx_marker"/>
+		<bitfield name="MARKER" low="0" high="3" type="a6xx_marker"/>
+	</reg32>
+</domain>
+
+<domain name="CP_SET_PSEUDO_REG" width="32" varset="chip" prefix="chip" variants="A6XX-">
+	<doc>Set internal CP registers, used to indicate context save data addresses</doc>
+	<enum name="pseudo_reg">
+		<value value="0" name="SMMU_INFO"/>
+		<value value="1" name="NON_SECURE_SAVE_ADDR"/>
+		<value value="2" name="SECURE_SAVE_ADDR"/>
+		<value value="3" name="NON_PRIV_SAVE_ADDR"/>
+		<value value="4" name="COUNTER"/>
+
+		<!--
+			On a6xx the registers are set directly and CP_SET_BIN_DATA5_OFFSET reads them,
+			but that doesn't work with concurrent binning because BR will be reading from
+			a different set of streams than BV is writing, so on a7xx we have these
+			pseudo-regs instead, which do the right thing.
+
+			The corresponding VSC registers exist, and they're written by BV when it
+			encounters CP_SET_PSEUDO_REG. When BR later encounters the same CP_SET_PSEUDO_REG
+			it will only write some private scratch registers which are read by
+			CP_SET_BIN_DATA5_OFFSET.
+
+			If concurrent binning is disabled then BR also does binning so it will also
+			write the "real" registers in BR.
+		-->
+		<value value="8" name="DRAW_STRM_ADDRESS"/>
+		<value value="9" name="DRAW_STRM_SIZE_ADDRESS"/>
+		<value value="10" name="PRIM_STRM_ADDRESS"/>
+		<value value="11" name="UNK_STRM_ADDRESS"/>
+		<value value="12" name="UNK_STRM_SIZE_ADDRESS"/>
+
+		<value value="16" name="BINDLESS_BASE_0_ADDR"/>
+		<value value="17" name="BINDLESS_BASE_1_ADDR"/>
+		<value value="18" name="BINDLESS_BASE_2_ADDR"/>
+		<value value="19" name="BINDLESS_BASE_3_ADDR"/>
+		<value value="20" name="BINDLESS_BASE_4_ADDR"/>
+		<value value="21" name="BINDLESS_BASE_5_ADDR"/>
+		<value value="22" name="BINDLESS_BASE_6_ADDR"/>
+	</enum>
+	<array offset="0" stride="3" length="100">
+		<reg32 offset="0" name="0">
+			<bitfield name="PSEUDO_REG" low="0" high="10" type="pseudo_reg"/>
+		</reg32>
+		<reg32 offset="1" name="1">
+			<bitfield name="LO" low="0" high="31"/>
+		</reg32>
+		<reg32 offset="2" name="2">
+			<bitfield name="HI" low="0" high="31"/>
+		</reg32>
+	</array>
+</domain>
+
+<domain name="CP_REG_TEST" width="32" varset="chip" prefix="chip" variants="A6XX-">
+	<doc>
+		Tests bit in specified register and sets predicate for CP_COND_REG_EXEC.
+		So:
+
+			opcode: CP_REG_TEST (39) (2 dwords)
+			        { REG = 0xc10 | BIT = 0 }
+			               0000: 70b90001 00000c10
+			opcode: CP_COND_REG_EXEC (47) (3 dwords)
+			               0000: 70c70002 10000000 00000004
+			opcode: CP_INDIRECT_BUFFER (3f) (4 dwords)
+
+		Will execute the CP_INDIRECT_BUFFER only if b0 in the register at
+		offset 0x0c10 is 1
+	</doc>
+	<enum name="source_type">
+		<value value="0" name="SOURCE_REG"/>
+		<!-- Don't confuse with scratch registers, this is a separate memory
+			 written into by CP_MEM_TO_SCRATCH_MEM. -->
+		<value value="1" name="SOURCE_SCRATCH_MEM" varset="chip" variants="A7XX-"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<!-- the register to test -->
+		<bitfield name="REG" low="0" high="17" varset="source_type" variants="SOURCE_REG"/>
+		<bitfield name="SCRATCH_MEM_OFFSET" low="0" high="17" varset="source_type" variants="SOURCE_SCRATCH_MEM"/>
+		<bitfield name="SOURCE" pos="18" type="source_type" addvariant="yes"/>
+		<!-- the bit to test -->
+		<bitfield name="BIT" low="20" high="24" type="uint"/>
+		<!-- skip implied CP_WAIT_FOR_ME -->
+		<bitfield name="SKIP_WAIT_FOR_ME" pos="25" type="boolean"/>
+		<!-- the predicate bit to set (new in gen3+) -->
+		<bitfield name="PRED_BIT" low="26" high="30" type="uint"/>
+		<!-- update the predicate reg directly (new in gen3+) -->
+		<bitfield name="PRED_UPDATE" pos="31" type="boolean"/>
+	</reg32>
+
+        <!--
+		In PRED_UPDATE mode, the predicate reg is updated directly using two
+		more dwords, ignoring other bits:
+
+			PRED_REG = (PRED_REG & ~PRED_MASK) | (PRED_VAL & PRED_MASK);
+	-->
+	<reg32 offset="1" name="PRED_MASK" type="hex"/>
+	<reg32 offset="2" name="PRED_VAL" type="hex"/>
+</domain>
+
+<!-- I *think* this existed at least as far back as a4xx -->
+<domain name="CP_COND_REG_EXEC" width="32">
+	<enum name="compare_mode">
+		<!-- use the predicate bit set by CP_REG_TEST -->
+		<value value="1" name="PRED_TEST"/>
+		<!-- compare two registers directly for equality -->
+		<value value="2" name="REG_COMPARE"/>
+		<!-- test if certain render modes are set via CP_SET_MARKER -->
+		<value value="3" name="RENDER_MODE" varset="chip" variants="A6XX-"/>
+		<!-- compare REG0 for equality with immediate -->
+		<value value="4" name="REG_COMPARE_IMM" varset="chip" variants="A7XX-"/>
+		<!-- test which of BR/BV are enabled -->
+		<value value="5" name="THREAD_MODE" varset="chip" variants="A7XX-"/>
+	</enum>
+	<reg32 offset="0" name="0" varset="compare_mode">
+		<bitfield name="REG0" low="0" high="17" variants="REG_COMPARE" type="hex"/>
+
+		<!-- the predicate bit to test (new in gen3+) -->
+		<bitfield name="PRED_BIT" low="18" high="22" variants="PRED_TEST" type="uint"/>
+		<bitfield name="SKIP_WAIT_FOR_ME" pos="23" varset="chip" variants="A7XX-" type="boolean"/>
+		<!-- With REG_COMPARE instead of register read from ONCHIP memory -->
+		<bitfield name="ONCHIP_MEM" pos="24" varset="chip" variants="A7XX-" type="boolean"/>
+
+		<!--
+			Note: these bits have the same meaning, and use the same
+			internal mechanism as the bits in CP_SET_DRAW_STATE.
+			When RENDER_MODE is selected, they're used as
+			a bitmask of which modes pass the test.
+		-->
+
+		<!-- RM6_BINNING -->
+		<bitfield name="BINNING" pos="25" variants="RENDER_MODE" type="boolean"/>
+		<!-- all others -->
+		<bitfield name="GMEM" pos="26" variants="RENDER_MODE" type="boolean"/>
+		<!-- RM6_BYPASS -->
+		<bitfield name="SYSMEM" pos="27" variants="RENDER_MODE" type="boolean"/>
+
+		<bitfield name="BV" pos="25" variants="THREAD_MODE" type="boolean"/>
+		<bitfield name="BR" pos="26" variants="THREAD_MODE" type="boolean"/>
+		<bitfield name="LPAC" pos="27" variants="THREAD_MODE" type="boolean"/>
+
+		<bitfield name="MODE" low="28" high="31" type="compare_mode" addvariant="yes"/>
+	</reg32>
+
+	<stripe varset="compare_mode" variants="PRED_TEST">
+		<reg32 offset="1" name="1">
+			<bitfield name="DWORDS" low="0" high="23" type="uint"/>
+		</reg32>
+	</stripe>
+
+	<stripe varset="compare_mode" variants="REG_COMPARE">
+		<reg32 offset="1" name="1">
+			<bitfield name="REG1" low="0" high="17" type="hex"/>
+			<!-- Instead of register read from ONCHIP memory -->
+			<bitfield name="ONCHIP_MEM" pos="24" varset="chip" variants="A7XX-" type="boolean"/>
+		</reg32>
+	</stripe>
+
+	<stripe varset="compare_mode" variants="RENDER_MODE">
+		<reg32 offset="1" name="1">
+			<bitfield name="DWORDS" low="0" high="23" type="uint"/>
+		</reg32>
+	</stripe>
+
+	<stripe varset="compare_mode" variants="REG_COMPARE_IMM">
+		<reg32 offset="1" name="1">
+			<bitfield name="IMM" low="0" high="31"/>
+		</reg32>
+	</stripe>
+
+	<stripe varset="compare_mode" variants="THREAD_MODE">
+		<reg32 offset="1" name="1">
+			<bitfield name="DWORDS" low="0" high="23" type="uint"/>
+		</reg32>
+	</stripe>
+
+	<reg32 offset="2" name="2">
+		<bitfield name="DWORDS" low="0" high="23" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_COND_EXEC" width="32">
+	<doc>
+                Executes the following DWORDs of commands if the dword at ADDR0
+                is not equal to 0 and the dword at ADDR1 is less than REF
+                (signed comparison).
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="ADDR0_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="ADDR0_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="ADDR1_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="ADDR1_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="4" name="4">
+		<bitfield name="REF" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="5" name="5">
+		<bitfield name="DWORDS" low="0" high="31" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_SET_AMBLE" width="32">
+	<doc>
+                Used by the userspace and kernel drivers to set various IB's
+                which are executed during context save/restore for handling
+                state that isn't restored by the context switch routine itself.
+  </doc>
+	<enum name="amble_type">
+		<value name="PREAMBLE_AMBLE_TYPE" value="0">
+			<doc>Executed unconditionally when switching back to the context.</doc>
+		</value>
+		<value name="BIN_PREAMBLE_AMBLE_TYPE" value="1">
+                        <doc>
+				Executed when switching back after switching
+				away during execution of
+				a CP_SET_MARKER packet with RM6_BIN_RENDER_END as the
+				payload *and* skipsaverestore is set. This is
+				expected to restore static register values not
+				saved when skipsaverestore is set.
+			</doc>
+		</value>
+		<value name="POSTAMBLE_AMBLE_TYPE" value="2">
+                        <doc>
+				Executed when switching away from the context,
+				except for context switches initiated via
+				CP_YIELD.
+                        </doc>
+		</value>
+		<value name="KMD_AMBLE_TYPE" value="3">
+			<doc>
+				This can only be set by the RB (i.e. the kernel)
+				and executes with protected mode off, but
+				is otherwise similar to POSTAMBLE_AMBLE_TYPE.
+			</doc>
+		</value>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="ADDR_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="ADDR_HI" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="DWORDS" low="0" high="19" type="uint"/>
+		<bitfield name="TYPE" low="20" high="21" type="amble_type"/>
+	</reg32>
+</domain>
+
+<domain name="CP_REG_WRITE" width="32">
+	<enum name="reg_tracker">
+		<doc>
+			Keep shadow copies of these registers and only set them
+			when drawing, avoiding redundant writes:
+			- VPC_CNTL_0
+			- HLSQ_CONTROL_1_REG
+			- HLSQ_UNKNOWN_B980
+		</doc>
+		<value name="TRACK_CNTL_REG" value="0x1"/>
+		<doc>
+			Track RB_RENDER_CNTL, and insert a WFI in the following
+			situation:
+			- There is a write that disables binning
+			- There was a draw with binning left enabled, but in
+			  BYPASS mode
+			Presumably this is a hang workaround?
+		</doc>
+		<value name="TRACK_RENDER_CNTL" value="0x2"/>
+		<doc>
+			Do a mysterious CP_EVENT_WRITE 0x3f when the low bit of
+			the data to write is 0. Used by the Vulkan blob with
+			PC_MULTIVIEW_CNTL, but this isn't predicated on particular
+			register(s) like the others.
+		</doc>
+		<value name="UNK_EVENT_WRITE" value="0x4"/>
+		<doc>
+			Tracks GRAS_LRZ_CNTL::GREATER, GRAS_LRZ_CNTL::DIR, and
+			GRAS_LRZ_DEPTH_VIEW with previous values, and if one of
+			the following is true:
+			- GRAS_LRZ_CNTL::GREATER has changed
+			- GRAS_LRZ_CNTL::DIR has changed, the old value is not
+			  CUR_DIR_GE, and the new value is not CUR_DIR_DISABLED
+			- GRAS_LRZ_DEPTH_VIEW has changed
+			then it does a LRZ_FLUSH with GRAS_LRZ_CNTL::ENABLE
+			forced to 1.
+			Only exists in a650_sqe.fw.
+		</doc>
+		<value name="TRACK_LRZ" value="0x8"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="TRACKER" low="0" high="3" type="reg_tracker"/>
+	</reg32>
+	<reg32 offset="1" name="1"/>
+	<reg32 offset="2" name="2"/>
+</domain>
+
+<domain name="CP_SMMU_TABLE_UPDATE" width="32">
+	<doc>
+		Note that the SMMU's definition of TTBRn can take different forms
+		depending on the pgtable format.  But a5xx+ only uses aarch64
+		format.
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="TTBR0_LO" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="TTBR0_HI" low="0" high="15"/>
+		<bitfield name="ASID" low="16" high="31"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<doc>Unused, does not apply to aarch64 pgtable format</doc>
+		<bitfield name="CONTEXTIDR" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="CONTEXTBANK" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_START_BIN" width="32">
+	<reg32 offset="0" name="BIN_COUNT" type="uint"/>
+	<reg64 offset="1" name="PREFIX_ADDR" type="address"/>
+	<reg32 offset="3" name="PREFIX_DWORDS">
+		<doc>
+			Size of prefix for each bin. For each bin index i, the
+			prefix commands at PREFIX_ADDR + i * PREFIX_DWORDS are
+			executed in an IB2 before the IB1 commands following
+			this packet.
+		</doc>
+	</reg32>
+	<reg32 offset="4" name="BODY_DWORDS">
+		<doc>Number of dwords after this packet until CP_END_BIN</doc>
+	</reg32>
+</domain>
+
+<domain name="CP_WAIT_TIMESTAMP" width="32">
+	<enum name="ts_wait_value_src">
+		<!-- Wait for value at memory address to be >= SRC_0 (signed comparison) -->
+		<value value="0" name="TS_WAIT_GE_32B"/>
+		<!-- Wait for value at memory address to be >= SRC_0 (unsigned) -->
+		<value value="1" name="TS_WAIT_GE_64B"/>
+		<!-- Write (TIMESTAMP_GLOBAL + TIMESTAMP_LOCAL) -->
+		<value value="2" name="TS_WAIT_GE_TIMESTAMP_SUM"/>
+	</enum>
+
+	<enum name="ts_wait_type">
+		<value value="0" name="TS_WAIT_RAM"/>
+		<value value="1" name="TS_WAIT_ONCHIP"/>
+	</enum>
+
+	<reg32 offset="0" name="0">
+		<bitfield name="WAIT_VALUE_SRC" low="0" high="1" type="ts_wait_value_src"/>
+		<bitfield name="WAIT_DST" pos="4" type="ts_wait_type" addvariant="yes"/>
+	</reg32>
+
+	<stripe varset="ts_wait_type" variants="TS_WAIT_RAM">
+		<reg64 offset="1" name="ADDR" type="address"/>
+	</stripe>
+
+	<stripe varset="ts_wait_type" variants="TS_WAIT_ONCHIP">
+		<reg32 offset="1" name="ONCHIP_ADDR_0" low="0" high="31"/>
+	</stripe>
+
+	<reg32 offset="3" name="SRC_0"/>
+	<reg32 offset="4" name="SRC_1"/>
+</domain>
+
+<domain name="CP_BV_BR_COUNT_OPS" width="32">
+	<enum name="pipe_count_op">
+		<value name="PIPE_CLEAR_BV_BR" value="0x1"/>
+		<value name="PIPE_SET_BR_OFFSET" value="0x2"/>
+		<!-- Wait until for BV_counter > BR_counter -->
+		<value name="PIPE_BR_WAIT_FOR_BV" value="0x3"/>
+		<!-- Wait until (BR_counter + BR_OFFSET) > BV_counter -->
+		<value name="PIPE_BV_WAIT_FOR_BR" value="0x4"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="OP" low="0" high="3" type="pipe_count_op"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<bitfield name="BR_OFFSET" low="0" high="15" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="CP_MODIFY_TIMESTAMP" width="32">
+	<enum name="timestamp_op">
+		<value name="MODIFY_TIMESTAMP_CLEAR" value="0"/>
+		<value name="MODIFY_TIMESTAMP_ADD_GLOBAL" value="1"/>
+		<value name="MODIFY_TIMESTAMP_ADD_LOCAL" value="2"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield name="ADD" low="0" high="7" type="uint"/>
+		<bitfield name="OP" low="28" high="31" type="timestamp_op"/>
+	</reg32>
+</domain>
+
+<domain name="CP_MEM_TO_SCRATCH_MEM" width="32">
+	<doc>
+		Best guess is that it is a faster way to fetch all the VSC_STATE registers
+		and keep them in a local scratch memory instead of fetching every time
+		when skipping IBs.
+	</doc>
+	<reg32 offset="0" name="0">
+		<bitfield name="CNT" low="0" high="5" type="uint"/>
+	</reg32>
+	<reg32 offset="1" name="1">
+		<doc>Scratch memory size is 48 dwords`</doc>
+		<bitfield name="OFFSET" low="0" high="5" type="uint"/>
+	</reg32>
+	<reg32 offset="2" name="2">
+		<bitfield name="SRC" low="0" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="SRC_HI" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_THREAD_CONTROL" width="32">
+	<enum name="cp_thread">
+		<value name="CP_SET_THREAD_BR" value="1"/>    <!-- Render -->
+		<value name="CP_SET_THREAD_BV" value="2"/>    <!-- Visibility -->
+		<value name="CP_SET_THREAD_BOTH" value="3"/>
+	</enum>
+	<reg32 offset="0" name="0">
+		<bitfield low="0" high="1" name="THREAD" type="cp_thread"/>
+		<bitfield pos="27" name="CONCURRENT_BIN_DISABLE" type="boolean"/>
+		<bitfield pos="31" name="SYNC_THREADS" type="boolean"/>
+	</reg32>
+</domain>
+
+<domain name="CP_FIXED_STRIDE_DRAW_TABLE" width="32">
+	<reg64 offset="0" name="IB_BASE"/>
+	<reg32 offset="2" name="2">
+		<!-- STRIDE * COUNT -->
+		<bitfield name="IB_SIZE" low="0" high="11"/>
+		<bitfield name="STRIDE" low="20" high="31"/>
+	</reg32>
+	<reg32 offset="3" name="3">
+		<bitfield name="COUNT" low="0" high="31"/>
+	</reg32>
+</domain>
+
+<domain name="CP_RESET_CONTEXT_STATE" width="32">
+	<reg32 offset="0" name="0">
+		<bitfield name="CLEAR_ON_CHIP_TS" pos="0" type="boolean"/>
+		<bitfield name="CLEAR_RESOURCE_TABLE" pos="1" type="boolean"/>
+		<bitfield name="CLEAR_GLOBAL_LOCAL_TS" pos="2" type="boolean"/>
+	</reg32>
+</domain>
+
+</database>
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/dsi.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/dsi.xml
@@ -0,0 +1,390 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="DSI" width="32">
+	<enum name="dsi_traffic_mode">
+		<value name="NON_BURST_SYNCH_PULSE" value="0"/>
+		<value name="NON_BURST_SYNCH_EVENT" value="1"/>
+		<value name="BURST_MODE" value="2"/>
+	</enum>
+	<enum name="dsi_vid_dst_format">
+		<value name="VID_DST_FORMAT_RGB565" value="0"/>
+		<value name="VID_DST_FORMAT_RGB666" value="1"/>
+		<value name="VID_DST_FORMAT_RGB666_LOOSE" value="2"/>
+		<value name="VID_DST_FORMAT_RGB888" value="3"/>
+	</enum>
+	<enum name="dsi_rgb_swap">
+		<value name="SWAP_RGB" value="0"/>
+		<value name="SWAP_RBG" value="1"/>
+		<value name="SWAP_BGR" value="2"/>
+		<value name="SWAP_BRG" value="3"/>
+		<value name="SWAP_GRB" value="4"/>
+		<value name="SWAP_GBR" value="5"/>
+	</enum>
+	<enum name="dsi_cmd_trigger">
+		<value name="TRIGGER_NONE" value="0"/>
+		<value name="TRIGGER_SEOF" value="1"/>
+		<value name="TRIGGER_TE" value="2"/>
+		<value name="TRIGGER_SW" value="4"/>
+		<value name="TRIGGER_SW_SEOF" value="5"/>
+		<value name="TRIGGER_SW_TE" value="6"/>
+	</enum>
+	<enum name="dsi_cmd_dst_format">
+		<value name="CMD_DST_FORMAT_RGB111" value="0"/>
+		<value name="CMD_DST_FORMAT_RGB332" value="3"/>
+		<value name="CMD_DST_FORMAT_RGB444" value="4"/>
+		<value name="CMD_DST_FORMAT_RGB565" value="6"/>
+		<value name="CMD_DST_FORMAT_RGB666" value="7"/>
+		<value name="CMD_DST_FORMAT_RGB888" value="8"/>
+	</enum>
+	<enum name="dsi_lane_swap">
+		<value name="LANE_SWAP_0123" value="0"/>
+		<value name="LANE_SWAP_3012" value="1"/>
+		<value name="LANE_SWAP_2301" value="2"/>
+		<value name="LANE_SWAP_1230" value="3"/>
+		<value name="LANE_SWAP_0321" value="4"/>
+		<value name="LANE_SWAP_1032" value="5"/>
+		<value name="LANE_SWAP_2103" value="6"/>
+		<value name="LANE_SWAP_3210" value="7"/>
+	</enum>
+		<enum name="video_config_bpp">
+		<value name="VIDEO_CONFIG_18BPP" value="0"/>
+		<value name="VIDEO_CONFIG_24BPP" value="1"/>
+	</enum>
+	<enum name="video_pattern_sel">
+		<value name="VID_PRBS" value="0"/>
+		<value name="VID_INCREMENTAL" value="1"/>
+		<value name="VID_FIXED" value="2"/>
+		<value name="VID_MDSS_GENERAL_PATTERN" value="3"/>
+	</enum>
+	<enum name="cmd_mdp_stream0_pattern_sel">
+		<value name="CMD_MDP_PRBS" value="0"/>
+		<value name="CMD_MDP_INCREMENTAL" value="1"/>
+		<value name="CMD_MDP_FIXED" value="2"/>
+		<value name="CMD_MDP_MDSS_GENERAL_PATTERN" value="3"/>
+	</enum>
+	<enum name="cmd_dma_pattern_sel">
+		<value name="CMD_DMA_PRBS" value="0"/>
+		<value name="CMD_DMA_INCREMENTAL" value="1"/>
+		<value name="CMD_DMA_FIXED" value="2"/>
+		<value name="CMD_DMA_CUSTOM_PATTERN_DMA_FIFO" value="3"/>
+	</enum>
+	<bitset name="DSI_IRQ">
+		<bitfield name="CMD_DMA_DONE" pos="0" type="boolean"/>
+		<bitfield name="MASK_CMD_DMA_DONE" pos="1" type="boolean"/>
+		<bitfield name="CMD_MDP_DONE" pos="8" type="boolean"/>
+		<bitfield name="MASK_CMD_MDP_DONE" pos="9" type="boolean"/>
+		<bitfield name="VIDEO_DONE" pos="16" type="boolean"/>
+		<bitfield name="MASK_VIDEO_DONE" pos="17" type="boolean"/>
+		<bitfield name="BTA_DONE" pos="20" type="boolean"/>
+		<bitfield name="MASK_BTA_DONE" pos="21" type="boolean"/>
+		<bitfield name="ERROR" pos="24" type="boolean"/>
+		<bitfield name="MASK_ERROR" pos="25" type="boolean"/>
+	</bitset>
+
+	<reg32 offset="0x00000" name="6G_HW_VERSION">
+		<bitfield name="MAJOR" low="28" high="31" type="uint"/>
+		<bitfield name="MINOR" low="16" high="27" type="uint"/>
+		<bitfield name="STEP" low="0" high="15" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00000" name="CTRL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="VID_MODE_EN" pos="1" type="boolean"/>
+		<bitfield name="CMD_MODE_EN" pos="2" type="boolean"/>
+		<bitfield name="LANE0" pos="4" type="boolean"/>
+		<bitfield name="LANE1" pos="5" type="boolean"/>
+		<bitfield name="LANE2" pos="6" type="boolean"/>
+		<bitfield name="LANE3" pos="7" type="boolean"/>
+		<bitfield name="CLK_EN" pos="8" type="boolean"/>
+		<bitfield name="ECC_CHECK" pos="20" type="boolean"/>
+		<bitfield name="CRC_CHECK" pos="24" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x00004" name="STATUS0">
+		<bitfield name="CMD_MODE_ENGINE_BUSY" pos="0" type="boolean"/>
+		<bitfield name="CMD_MODE_DMA_BUSY" pos="1" type="boolean"/>
+		<bitfield name="CMD_MODE_MDP_BUSY" pos="2" type="boolean"/>
+		<bitfield name="VIDEO_MODE_ENGINE_BUSY" pos="3" type="boolean"/>
+		<bitfield name="DSI_BUSY" pos="4" type="boolean"/>  <!-- see mipi_dsi_cmd_bta_sw_trigger() -->
+		<bitfield name="INTERLEAVE_OP_CONTENTION" pos="31" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x00008" name="FIFO_STATUS">
+		<bitfield name="VIDEO_MDP_FIFO_OVERFLOW" pos="0" type="boolean"/>
+		<bitfield name="VIDEO_MDP_FIFO_UNDERFLOW" pos="3" type="boolean"/>
+		<bitfield name="CMD_MDP_FIFO_UNDERFLOW" pos="7" type="boolean"/>
+		<bitfield name="CMD_DMA_FIFO_RD_WATERMARK_REACH" pos="8" type="boolean"/>
+		<bitfield name="CMD_DMA_FIFO_WR_WATERMARK_REACH" pos="9" type="boolean"/>
+		<bitfield name="CMD_DMA_FIFO_UNDERFLOW" pos="10" type="boolean"/>
+		<bitfield name="DLN0_LP_FIFO_EMPTY"     pos="12" type="boolean"/>
+		<bitfield name="DLN0_LP_FIFO_FULL"      pos="13" type="boolean"/>
+		<bitfield name="DLN0_LP_FIFO_OVERFLOW"  pos="14" type="boolean"/>
+		<bitfield name="DLN0_HS_FIFO_EMPTY"     pos="16" type="boolean"/>
+		<bitfield name="DLN0_HS_FIFO_FULL"      pos="17" type="boolean"/>
+		<bitfield name="DLN0_HS_FIFO_OVERFLOW"  pos="18" type="boolean"/>
+		<bitfield name="DLN0_HS_FIFO_UNDERFLOW" pos="19" type="boolean"/>
+		<bitfield name="DLN1_HS_FIFO_EMPTY"     pos="20" type="boolean"/>
+		<bitfield name="DLN1_HS_FIFO_FULL"      pos="21" type="boolean"/>
+		<bitfield name="DLN1_HS_FIFO_OVERFLOW"  pos="22" type="boolean"/>
+		<bitfield name="DLN1_HS_FIFO_UNDERFLOW" pos="23" type="boolean"/>
+		<bitfield name="DLN2_HS_FIFO_EMPTY"     pos="24" type="boolean"/>
+		<bitfield name="DLN2_HS_FIFO_FULL"      pos="25" type="boolean"/>
+		<bitfield name="DLN2_HS_FIFO_OVERFLOW"  pos="26" type="boolean"/>
+		<bitfield name="DLN2_HS_FIFO_UNDERFLOW" pos="27" type="boolean"/>
+		<bitfield name="DLN3_HS_FIFO_EMPTY"     pos="28" type="boolean"/>
+		<bitfield name="DLN3_HS_FIFO_FULL"      pos="29" type="boolean"/>
+		<bitfield name="DLN3_HS_FIFO_OVERFLOW"  pos="30" type="boolean"/>
+		<bitfield name="DLN3_HS_FIFO_UNDERFLOW" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0000c" name="VID_CFG0">
+		<bitfield name="VIRT_CHANNEL" low="0" high="1" type="uint"/>  <!-- always zero? -->
+		<bitfield name="DST_FORMAT" low="4" high="5" type="dsi_vid_dst_format"/>
+		<bitfield name="TRAFFIC_MODE" low="8" high="9" type="dsi_traffic_mode"/>
+		<bitfield name="BLLP_POWER_STOP" pos="12" type="boolean"/>
+		<bitfield name="EOF_BLLP_POWER_STOP" pos="15" type="boolean"/>
+		<bitfield name="HSA_POWER_STOP" pos="16" type="boolean"/>
+		<bitfield name="HBP_POWER_STOP" pos="20" type="boolean"/>
+		<bitfield name="HFP_POWER_STOP" pos="24" type="boolean"/>
+		<bitfield name="DATABUS_WIDEN" pos="25" type="boolean"/>
+		<bitfield name="PULSE_MODE_HSA_HE" pos="28" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0001c" name="VID_CFG1">
+		<bitfield name="R_SEL" pos="0" type="boolean"/>
+		<bitfield name="G_SEL" pos="4" type="boolean"/>
+		<bitfield name="B_SEL" pos="8" type="boolean"/>
+		<bitfield name="RGB_SWAP" low="12" high="14" type="dsi_rgb_swap"/>
+	</reg32>
+	<reg32 offset="0x00020" name="ACTIVE_H">
+		<bitfield name="START" low="0" high="11" type="uint"/>
+		<bitfield name="END" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00024" name="ACTIVE_V">
+		<bitfield name="START" low="0" high="11" type="uint"/>
+		<bitfield name="END" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00028" name="TOTAL">
+		<bitfield name="H_TOTAL" low="0" high="11" type="uint"/>
+		<bitfield name="V_TOTAL" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0002c" name="ACTIVE_HSYNC">
+		<bitfield name="START" low="0" high="11" type="uint"/>
+		<bitfield name="END" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00030" name="ACTIVE_VSYNC_HPOS">
+		<bitfield name="START" low="0" high="11" type="uint"/>
+		<bitfield name="END" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00034" name="ACTIVE_VSYNC_VPOS">
+		<bitfield name="START" low="0" high="11" type="uint"/>
+		<bitfield name="END" low="16" high="27" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00038" name="CMD_DMA_CTRL">
+		<bitfield name="BROADCAST_EN" pos="31" type="boolean"/>
+		<bitfield name="FROM_FRAME_BUFFER" pos="28" type="boolean"/>
+		<bitfield name="LOW_POWER" pos="26" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0003c" name="CMD_CFG0">
+		<bitfield name="DST_FORMAT" low="0" high="3" type="dsi_cmd_dst_format"/>
+		<bitfield name="R_SEL" pos="4" type="boolean"/>
+		<bitfield name="G_SEL" pos="8" type="boolean"/>
+		<bitfield name="B_SEL" pos="12" type="boolean"/>
+		<bitfield name="INTERLEAVE_MAX" low="20" high="23" type="uint"/>
+		<bitfield name="RGB_SWAP" low="16" high="18" type="dsi_rgb_swap"/>
+	</reg32>
+	<reg32 offset="0x00040" name="CMD_CFG1">
+		<bitfield name="WR_MEM_START" low="0" high="7" type="uint"/>
+		<bitfield name="WR_MEM_CONTINUE" low="8" high="15" type="uint"/>
+		<bitfield name="INSERT_DCS_COMMAND" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00044" name="DMA_BASE"/>
+	<reg32 offset="0x00048" name="DMA_LEN"/>
+	<reg32 offset="0x00054" name="CMD_MDP_STREAM0_CTRL">
+		<bitfield name="DATA_TYPE" low="0" high="5" type="uint"/>
+		<bitfield name="VIRTUAL_CHANNEL" low="8" high="9" type="uint"/>
+		<bitfield name="WORD_COUNT" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00058" name="CMD_MDP_STREAM0_TOTAL">
+		<bitfield name="H_TOTAL" low="0" high="11" type="uint"/>
+		<bitfield name="V_TOTAL" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0005c" name="CMD_MDP_STREAM1_CTRL">
+		<bitfield name="DATA_TYPE" low="0" high="5" type="uint"/>
+		<bitfield name="VIRTUAL_CHANNEL" low="8" high="9" type="uint"/>
+		<bitfield name="WORD_COUNT" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00060" name="CMD_MDP_STREAM1_TOTAL">
+		<bitfield name="H_TOTAL" low="0" high="15" type="uint"/>
+		<bitfield name="V_TOTAL" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00064" name="ACK_ERR_STATUS"/>
+	<array offset="0x00068" name="RDBK" length="4" stride="4">
+		<reg32 offset="0x0" name="DATA"/>
+	</array>
+	<reg32 offset="0x00080" name="TRIG_CTRL">
+		<bitfield name="DMA_TRIGGER" low="0" high="2" type="dsi_cmd_trigger"/>
+		<bitfield name="MDP_TRIGGER" low="4" high="6" type="dsi_cmd_trigger"/>
+		<bitfield name="STREAM" low="8" high="9" type="uint"/>
+		<bitfield name="BLOCK_DMA_WITHIN_FRAME" pos="12" type="boolean"/>
+		<bitfield name="TE" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0008c" name="TRIG_DMA"/>
+	<reg32 offset="0x000b0" name="DLN0_PHY_ERR">
+		<bitfield name="DLN0_ERR_ESC" pos="0" type="boolean"/>
+		<bitfield name="DLN0_ERR_SYNC_ESC" pos="4" type="boolean"/>
+		<bitfield name="DLN0_ERR_CONTROL" pos="8" type="boolean"/>
+		<bitfield name="DLN0_ERR_CONTENTION_LP0" pos="12" type="boolean"/>
+		<bitfield name="DLN0_ERR_CONTENTION_LP1" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x000b4" name="LP_TIMER_CTRL">
+		<bitfield name="LP_RX_TO" low="0" high="15" type="uint"/>
+		<bitfield name="BTA_TO" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x000b8" name="HS_TIMER_CTRL">
+		<bitfield name="HS_TX_TO" low="0" high="15" type="uint"/>
+		<bitfield name="TIMER_RESOLUTION" low="16" high="19" type="uint"/>
+		<bitfield name="HS_TX_TO_STOP_EN" pos="28" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x000bc" name="TIMEOUT_STATUS"/>
+	<reg32 offset="0x000c0" name="CLKOUT_TIMING_CTRL">
+		<bitfield name="T_CLK_PRE" low="0" high="5" type="uint"/>
+		<bitfield name="T_CLK_POST" low="8" high="13" type="uint"/>
+	</reg32>
+	<reg32 offset="0x000c8" name="EOT_PACKET_CTRL">
+		<bitfield name="TX_EOT_APPEND" pos="0" type="boolean"/>
+		<bitfield name="RX_EOT_IGNORE" pos="4" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x000a4" name="LANE_STATUS">
+		<bitfield name="DLN0_STOPSTATE" pos="0" type="boolean"/>
+		<bitfield name="DLN1_STOPSTATE" pos="1" type="boolean"/>
+		<bitfield name="DLN2_STOPSTATE" pos="2" type="boolean"/>
+		<bitfield name="DLN3_STOPSTATE" pos="3" type="boolean"/>
+		<bitfield name="CLKLN_STOPSTATE" pos="4" type="boolean"/>
+		<bitfield name="DLN0_ULPS_ACTIVE_NOT" pos="8" type="boolean"/>
+		<bitfield name="DLN1_ULPS_ACTIVE_NOT" pos="9" type="boolean"/>
+		<bitfield name="DLN2_ULPS_ACTIVE_NOT" pos="10" type="boolean"/>
+		<bitfield name="DLN3_ULPS_ACTIVE_NOT" pos="11" type="boolean"/>
+		<bitfield name="CLKLN_ULPS_ACTIVE_NOT" pos="12" type="boolean"/>
+		<bitfield name="DLN0_DIRECTION" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x000a8" name="LANE_CTRL">
+		<bitfield name="HS_REQ_SEL_PHY" pos="24" type="boolean"/>
+		<bitfield name="CLKLN_HS_FORCE_REQUEST" pos="28" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x000ac" name="LANE_SWAP_CTRL">
+		<bitfield name="DLN_SWAP_SEL" low="0" high="2" type="dsi_lane_swap"/>
+	</reg32>
+	<reg32 offset="0x00108" name="ERR_INT_MASK0"/>
+	<reg32 offset="0x0010c" name="INTR_CTRL" type="DSI_IRQ"/>
+	<reg32 offset="0x00114" name="RESET"/>
+	<reg32 offset="0x00118" name="CLK_CTRL">
+		<bitfield name="AHBS_HCLK_ON" pos="0" type="boolean"/>
+		<bitfield name="AHBM_SCLK_ON" pos="1" type="boolean"/>
+		<bitfield name="PCLK_ON" pos="2" type="boolean"/>
+		<bitfield name="DSICLK_ON" pos="3" type="boolean"/>
+		<bitfield name="BYTECLK_ON" pos="4" type="boolean"/>
+		<bitfield name="ESCCLK_ON" pos="5" type="boolean"/>
+		<bitfield name="FORCE_ON_DYN_AHBM_HCLK" pos="9" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0011c" name="CLK_STATUS">
+		<bitfield name="DSI_AON_AHBM_HCLK_ACTIVE" pos="0" type="boolean"/>
+		<bitfield name="DSI_DYN_AHBM_HCLK_ACTIVE" pos="1" type="boolean"/>
+		<bitfield name="DSI_AON_AHBS_HCLK_ACTIVE" pos="2" type="boolean"/>
+		<bitfield name="DSI_DYN_AHBS_HCLK_ACTIVE" pos="3" type="boolean"/>
+		<bitfield name="DSI_AON_DSICLK_ACTIVE" pos="4" type="boolean"/>
+		<bitfield name="DSI_DYN_DSICLK_ACTIVE" pos="5" type="boolean"/>
+		<bitfield name="DSI_AON_BYTECLK_ACTIVE" pos="6" type="boolean"/>
+		<bitfield name="DSI_DYN_BYTECLK_ACTIVE" pos="7" type="boolean"/>
+		<bitfield name="DSI_AON_ESCCLK_ACTIVE" pos="8" type="boolean"/>
+		<bitfield name="DSI_AON_PCLK_ACTIVE" pos="9" type="boolean"/>
+		<bitfield name="DSI_DYN_PCLK_ACTIVE" pos="10" type="boolean"/>
+		<bitfield name="DSI_DYN_CMD_PCLK_ACTIVE" pos="12" type="boolean"/>
+		<bitfield name="DSI_CMD_PCLK_ACTIVE" pos="13" type="boolean"/>
+		<bitfield name="DSI_VID_PCLK_ACTIVE" pos="14" type="boolean"/>
+		<bitfield name="DSI_CAM_BIST_PCLK_ACT" pos="15" type="boolean"/>
+		<bitfield name="PLL_UNLOCKED" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00128" name="PHY_RESET">
+		<bitfield name="RESET" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00160" name="TEST_PATTERN_GEN_VIDEO_INIT_VAL"/>
+	<reg32 offset="0x00198" name="TPG_MAIN_CONTROL">
+		<bitfield name="CHECKERED_RECTANGLE_PATTERN" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x001a0" name="TPG_VIDEO_CONFIG">
+		<bitfield name="BPP" low="0" high="1" type="video_config_bpp"/>
+		<bitfield name="RGB" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00158" name="TEST_PATTERN_GEN_CTRL">
+		<bitfield name="CMD_DMA_PATTERN_SEL" low="16" high="17" type="cmd_dma_pattern_sel"/>
+		<bitfield name="CMD_MDP_STREAM0_PATTERN_SEL" low="8" high="9" type="cmd_mdp_stream0_pattern_sel"/>
+		<bitfield name="VIDEO_PATTERN_SEL" low="4" high="5" type="video_pattern_sel"/>
+		<bitfield name="TPG_DMA_FIFO_MODE" pos="2" type="boolean"/>
+		<bitfield name="CMD_DMA_TPG_EN" pos="1" type="boolean"/>
+		<bitfield name="EN" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00168" name="TEST_PATTERN_GEN_CMD_MDP_INIT_VAL0"/>
+	<reg32 offset="0x00180" name="TEST_PATTERN_GEN_CMD_STREAM0_TRIGGER">
+		<bitfield name="SW_TRIGGER" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0019c" name="TPG_MAIN_CONTROL2">
+		<bitfield name="CMD_MDP0_CHECKERED_RECTANGLE_PATTERN" pos="7" type="boolean"/>
+		<bitfield name="CMD_MDP1_CHECKERED_RECTANGLE_PATTERN" pos="16" type="boolean"/>
+		<bitfield name="CMD_MDP2_CHECKERED_RECTANGLE_PATTERN" pos="25" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0017c" name="T_CLK_PRE_EXTEND">
+		<bitfield name="INC_BY_2_BYTECLK" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x001b4" name="CMD_MODE_MDP_CTRL2">
+		<bitfield name="DST_FORMAT2" low="0" high="3" type="dsi_cmd_dst_format"/>
+		<bitfield name="R_SEL" pos="4" type="boolean"/>
+		<bitfield name="G_SEL" pos="5" type="boolean"/>
+		<bitfield name="B_SEL" pos="6" type="boolean"/>
+		<bitfield name="BYTE_MSB_LSB_FLIP" pos="7" type="boolean"/>
+		<bitfield name="RGB_SWAP" low="8" high="10" type="dsi_rgb_swap"/>
+		<bitfield name="INPUT_RGB_SWAP" low="12" high="14" type="dsi_rgb_swap"/>
+		<bitfield name="BURST_MODE" pos="16" type="boolean"/>
+		<bitfield name="DATABUS_WIDEN" pos="20" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x001b8" name="CMD_MODE_MDP_STREAM2_CTRL">
+		<bitfield name="DATA_TYPE" low="0" high="5" type="uint"/>
+		<bitfield name="VIRTUAL_CHANNEL" low="8" high="9" type="uint"/>
+		<bitfield name="WORD_COUNT" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x001d0" name="RDBK_DATA_CTRL">
+		<bitfield name="COUNT" low="16" high="23" type="uint"/>
+		<bitfield name="CLR" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x001f0" name="VERSION">
+		<bitfield name="MAJOR" low="24" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002d4" name="CPHY_MODE_CTRL"/>
+	<reg32 offset="0x0029c" name="VIDEO_COMPRESSION_MODE_CTRL">
+		<bitfield name="WC" low="16" high="31" type="uint"/>
+		<bitfield name="DATATYPE" low="8" high="13" type="uint"/>
+		<bitfield name="PKT_PER_LINE" low="6" high="7" type="uint"/>
+		<bitfield name="EOL_BYTE_NUM" low="4" high="5" type="uint"/>
+		<bitfield name="EN" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x002a4" name="COMMAND_COMPRESSION_MODE_CTRL">
+		<bitfield name="STREAM1_DATATYPE" low="24" high="29" type="uint"/>
+		<bitfield name="STREAM1_PKT_PER_LINE" low="22" high="23" type="uint"/>
+		<bitfield name="STREAM1_EOL_BYTE_NUM" low="20" high="21" type="uint"/>
+		<bitfield name="STREAM1_EN" pos="16" type="boolean"/>
+		<bitfield name="STREAM0_DATATYPE" low="8" high="13" type="uint"/>
+		<bitfield name="STREAM0_PKT_PER_LINE" low="6" high="7" type="uint"/>
+		<bitfield name="STREAM0_EOL_BYTE_NUM" low="4" high="5" type="uint"/>
+		<bitfield name="STREAM0_EN" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x002a8" name="COMMAND_COMPRESSION_MODE_CTRL2">
+		<bitfield name="STREAM1_SLICE_WIDTH" low="16" high="31" type="uint"/>
+		<bitfield name="STREAM0_SLICE_WIDTH" low="0" high="15" type="uint"/>
+	</reg32>
+
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/dsi_phy_10nm.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/dsi_phy_10nm.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="DSI_10nm_PHY_CMN" width="32">
+	<reg32 offset="0x00000" name="REVISION_ID0"/>
+	<reg32 offset="0x00004" name="REVISION_ID1"/>
+	<reg32 offset="0x00008" name="REVISION_ID2"/>
+	<reg32 offset="0x0000c" name="REVISION_ID3"/>
+	<reg32 offset="0x00010" name="CLK_CFG0"/>
+	<reg32 offset="0x00014" name="CLK_CFG1"/>
+	<reg32 offset="0x00018" name="GLBL_CTRL"/>
+	<reg32 offset="0x0001c" name="RBUF_CTRL"/>
+	<reg32 offset="0x00020" name="VREG_CTRL"/>
+	<reg32 offset="0x00024" name="CTRL_0"/>
+	<reg32 offset="0x00028" name="CTRL_1"/>
+	<reg32 offset="0x0002c" name="CTRL_2"/>
+	<reg32 offset="0x00030" name="LANE_CFG0"/>
+	<reg32 offset="0x00034" name="LANE_CFG1"/>
+	<reg32 offset="0x00038" name="PLL_CNTRL"/>
+	<reg32 offset="0x00098" name="LANE_CTRL0"/>
+	<reg32 offset="0x0009c" name="LANE_CTRL1"/>
+	<reg32 offset="0x000a0" name="LANE_CTRL2"/>
+	<reg32 offset="0x000a4" name="LANE_CTRL3"/>
+	<reg32 offset="0x000a8" name="LANE_CTRL4"/>
+	<reg32 offset="0x000ac" name="TIMING_CTRL_0"/>
+	<reg32 offset="0x000b0" name="TIMING_CTRL_1"/>
+	<reg32 offset="0x000b4" name="TIMING_CTRL_2"/>
+	<reg32 offset="0x000b8" name="TIMING_CTRL_3"/>
+	<reg32 offset="0x000bc" name="TIMING_CTRL_4"/>
+	<reg32 offset="0x000c0" name="TIMING_CTRL_5"/>
+	<reg32 offset="0x000c4" name="TIMING_CTRL_6"/>
+	<reg32 offset="0x000c8" name="TIMING_CTRL_7"/>
+	<reg32 offset="0x000cc" name="TIMING_CTRL_8"/>
+	<reg32 offset="0x000d0" name="TIMING_CTRL_9"/>
+	<reg32 offset="0x000d4" name="TIMING_CTRL_10"/>
+	<reg32 offset="0x000d8" name="TIMING_CTRL_11"/>
+	<reg32 offset="0x000ec" name="PHY_STATUS"/>
+	<reg32 offset="0x000f4" name="LANE_STATUS0"/>
+	<reg32 offset="0x000f8" name="LANE_STATUS1"/>
+</domain>
+
+<domain name="DSI_10nm_PHY" width="32">
+	<array offset="0x00000" name="LN" length="5" stride="0x80">
+		<reg32 offset="0x00" name="CFG0"/>
+		<reg32 offset="0x04" name="CFG1"/>
+		<reg32 offset="0x08" name="CFG2"/>
+		<reg32 offset="0x0c" name="CFG3"/>
+		<reg32 offset="0x10" name="TEST_DATAPATH"/>
+		<reg32 offset="0x14" name="PIN_SWAP"/>
+		<reg32 offset="0x18" name="HSTX_STR_CTRL"/>
+		<reg32 offset="0x1c" name="OFFSET_TOP_CTRL"/>
+		<reg32 offset="0x20" name="OFFSET_BOT_CTRL"/>
+		<reg32 offset="0x24" name="LPTX_STR_CTRL"/>
+		<reg32 offset="0x28" name="LPRX_CTRL"/>
+		<reg32 offset="0x2c" name="TX_DCTRL"/>
+	</array>
+</domain>
+
+<domain name="DSI_10nm_PHY_PLL" width="32">
+	<reg32 offset="0x0000" name="ANALOG_CONTROLS_ONE"/>
+	<reg32 offset="0x0004" name="ANALOG_CONTROLS_TWO"/>
+	<reg32 offset="0x0010" name="ANALOG_CONTROLS_THREE"/>
+	<reg32 offset="0x001c" name="DSM_DIVIDER"/>
+	<reg32 offset="0x0020" name="FEEDBACK_DIVIDER"/>
+	<reg32 offset="0x0024" name="SYSTEM_MUXES"/>
+	<reg32 offset="0x002c" name="CMODE"/>
+	<reg32 offset="0x0030" name="CALIBRATION_SETTINGS"/>
+	<reg32 offset="0x0054" name="BAND_SEL_CAL_SETTINGS_THREE"/>
+	<reg32 offset="0x0064" name="FREQ_DETECT_SETTINGS_ONE"/>
+	<reg32 offset="0x007c" name="PFILT"/>
+	<reg32 offset="0x0080" name="IFILT"/>
+	<reg32 offset="0x0094" name="OUTDIV"/>
+	<reg32 offset="0x00a4" name="CORE_OVERRIDE"/>
+	<reg32 offset="0x00a8" name="CORE_INPUT_OVERRIDE"/>
+	<reg32 offset="0x00b4" name="PLL_DIGITAL_TIMERS_TWO"/>
+	<reg32 offset="0x00cc" name="DECIMAL_DIV_START_1"/>
+	<reg32 offset="0x00d0" name="FRAC_DIV_START_LOW_1"/>
+	<reg32 offset="0x00d4" name="FRAC_DIV_START_MID_1"/>
+	<reg32 offset="0x00d8" name="FRAC_DIV_START_HIGH_1"/>
+	<reg32 offset="0x010c" name="SSC_STEPSIZE_LOW_1"/>
+	<reg32 offset="0x0110" name="SSC_STEPSIZE_HIGH_1"/>
+	<reg32 offset="0x0114" name="SSC_DIV_PER_LOW_1"/>
+	<reg32 offset="0x0118" name="SSC_DIV_PER_HIGH_1"/>
+	<reg32 offset="0x011c" name="SSC_DIV_ADJPER_LOW_1"/>
+	<reg32 offset="0x0120" name="SSC_DIV_ADJPER_HIGH_1"/>
+	<reg32 offset="0x013c" name="SSC_CONTROL"/>
+	<reg32 offset="0x0140" name="PLL_OUTDIV_RATE"/>
+	<reg32 offset="0x0144" name="PLL_LOCKDET_RATE_1"/>
+	<reg32 offset="0x014c" name="PLL_PROP_GAIN_RATE_1"/>
+	<reg32 offset="0x0154" name="PLL_BAND_SET_RATE_1"/>
+	<reg32 offset="0x015c" name="PLL_INT_GAIN_IFILT_BAND_1"/>
+	<reg32 offset="0x0164" name="PLL_FL_INT_GAIN_PFILT_BAND_1"/>
+	<reg32 offset="0x0180" name="PLL_LOCK_OVERRIDE"/>
+	<reg32 offset="0x0184" name="PLL_LOCK_DELAY"/>
+	<reg32 offset="0x018c" name="CLOCK_INVERTERS"/>
+	<reg32 offset="0x01a0" name="COMMON_STATUS_ONE"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/dsi_phy_14nm.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/dsi_phy_14nm.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="DSI_14nm_PHY_CMN" width="32">
+	<reg32 offset="0x00000" name="REVISION_ID0"/>
+	<reg32 offset="0x00004" name="REVISION_ID1"/>
+	<reg32 offset="0x00008" name="REVISION_ID2"/>
+	<reg32 offset="0x0000c" name="REVISION_ID3"/>
+	<reg32 offset="0x00010" name="CLK_CFG0">
+		<bitfield name="DIV_CTRL_3_0" low="4" high="7" type="uint"/>
+		<bitfield name="DIV_CTRL_7_4" low="4" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00014" name="CLK_CFG1">
+		<bitfield name="DSICLK_SEL" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00018" name="GLBL_TEST_CTRL">
+		<bitfield name="BITCLK_HS_SEL" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0001C" name="CTRL_0"/>
+	<reg32 offset="0x00020" name="CTRL_1">
+	</reg32>
+	<reg32 offset="0x00024" name="HW_TRIGGER"/>
+	<reg32 offset="0x00028" name="SW_CFG0"/>
+	<reg32 offset="0x0002C" name="SW_CFG1"/>
+	<reg32 offset="0x00030" name="SW_CFG2"/>
+	<reg32 offset="0x00034" name="HW_CFG0"/>
+	<reg32 offset="0x00038" name="HW_CFG1"/>
+	<reg32 offset="0x0003C" name="HW_CFG2"/>
+	<reg32 offset="0x00040" name="HW_CFG3"/>
+	<reg32 offset="0x00044" name="HW_CFG4"/>
+	<reg32 offset="0x00048" name="PLL_CNTRL">
+		<bitfield name="PLL_START" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0004C" name="LDO_CNTRL">
+		<bitfield name="VREG_CTRL" low="0" high="5" type="uint"/>
+	</reg32>
+</domain>
+
+<domain name="DSI_14nm_PHY" width="32">
+	<array offset="0x00000" name="LN" length="5" stride="0x80">
+		<reg32 offset="0x00" name="CFG0">
+			<bitfield name="PREPARE_DLY" low="6" high="7" type="uint"/>
+		</reg32>
+		<reg32 offset="0x04" name="CFG1">
+			<bitfield name="HALFBYTECLK_EN" pos="0" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x08" name="CFG2"/>
+		<reg32 offset="0x0c" name="CFG3"/>
+		<reg32 offset="0x10" name="TEST_DATAPATH"/>
+		<reg32 offset="0x14" name="TEST_STR"/>
+		<reg32 offset="0x18" name="TIMING_CTRL_4">
+			<bitfield name="HS_EXIT" low="0" high="7" type="uint"/>
+		</reg32>
+		<reg32 offset="0x1c" name="TIMING_CTRL_5">
+			<bitfield name="HS_ZERO" low="0" high="7" type="uint"/>
+		</reg32>
+		<reg32 offset="0x20" name="TIMING_CTRL_6">
+			<bitfield name="HS_PREPARE" low="0" high="7" type="uint"/>
+		</reg32>
+		<reg32 offset="0x24" name="TIMING_CTRL_7">
+			<bitfield name="HS_TRAIL" low="0" high="7" type="uint"/>
+		</reg32>
+		<reg32 offset="0x28" name="TIMING_CTRL_8">
+			<bitfield name="HS_RQST" low="0" high="7" type="uint"/>
+		</reg32>
+		<reg32 offset="0x2c" name="TIMING_CTRL_9">
+			<bitfield name="TA_GO" low="0" high="2" type="uint"/>
+			<bitfield name="TA_SURE" low="4" high="6" type="uint"/>
+		</reg32>
+		<reg32 offset="0x30" name="TIMING_CTRL_10">
+			<bitfield name="TA_GET" low="0" high="2" type="uint"/>
+		</reg32>
+		<reg32 offset="0x34" name="TIMING_CTRL_11">
+			<bitfield name="TRIG3_CMD" low="0" high="7" type="uint"/>
+		</reg32>
+		<reg32 offset="0x38" name="STRENGTH_CTRL_0"/>
+		<reg32 offset="0x3c" name="STRENGTH_CTRL_1"/>
+		<reg32 offset="0x64" name="VREG_CNTRL"/>
+	</array>
+</domain>
+
+<domain name="DSI_14nm_PHY_PLL" width="32">
+	<reg32 offset="0x000" name="IE_TRIM"/>
+	<reg32 offset="0x004" name="IP_TRIM"/>
+	<reg32 offset="0x010" name="IPTAT_TRIM"/>
+	<reg32 offset="0x01c" name="CLKBUFLR_EN"/>
+	<reg32 offset="0x028" name="SYSCLK_EN_RESET"/>
+	<reg32 offset="0x02c" name="RESETSM_CNTRL"/>
+	<reg32 offset="0x030" name="RESETSM_CNTRL2"/>
+	<reg32 offset="0x034" name="RESETSM_CNTRL3"/>
+	<reg32 offset="0x038" name="RESETSM_CNTRL4"/>
+	<reg32 offset="0x03c" name="RESETSM_CNTRL5"/>
+	<reg32 offset="0x040" name="KVCO_DIV_REF1"/>
+	<reg32 offset="0x044" name="KVCO_DIV_REF2"/>
+	<reg32 offset="0x048" name="KVCO_COUNT1"/>
+	<reg32 offset="0x04c" name="KVCO_COUNT2"/>
+	<reg32 offset="0x05c" name="VREF_CFG1"/>
+	<reg32 offset="0x058" name="KVCO_CODE"/>
+	<reg32 offset="0x06c" name="VCO_DIV_REF1"/>
+	<reg32 offset="0x070" name="VCO_DIV_REF2"/>
+	<reg32 offset="0x074" name="VCO_COUNT1"/>
+	<reg32 offset="0x078" name="VCO_COUNT2"/>
+	<reg32 offset="0x07c" name="PLLLOCK_CMP1"/>
+	<reg32 offset="0x080" name="PLLLOCK_CMP2"/>
+	<reg32 offset="0x084" name="PLLLOCK_CMP3"/>
+	<reg32 offset="0x088" name="PLLLOCK_CMP_EN"/>
+	<reg32 offset="0x08c" name="PLL_VCO_TUNE"/>
+	<reg32 offset="0x090" name="DEC_START"/>
+	<reg32 offset="0x094" name="SSC_EN_CENTER"/>
+	<reg32 offset="0x098" name="SSC_ADJ_PER1"/>
+	<reg32 offset="0x09c" name="SSC_ADJ_PER2"/>
+	<reg32 offset="0x0a0" name="SSC_PER1"/>
+	<reg32 offset="0x0a4" name="SSC_PER2"/>
+	<reg32 offset="0x0a8" name="SSC_STEP_SIZE1"/>
+	<reg32 offset="0x0ac" name="SSC_STEP_SIZE2"/>
+	<reg32 offset="0x0b4" name="DIV_FRAC_START1"/>
+	<reg32 offset="0x0b8" name="DIV_FRAC_START2"/>
+	<reg32 offset="0x0bc" name="DIV_FRAC_START3"/>
+	<reg32 offset="0x0c0" name="TXCLK_EN"/>
+	<reg32 offset="0x0c4" name="PLL_CRCTRL"/>
+	<reg32 offset="0x0cc" name="RESET_SM_READY_STATUS"/>
+	<reg32 offset="0x0e8" name="PLL_MISC1"/>
+	<reg32 offset="0x0f0" name="CP_SET_CUR"/>
+	<reg32 offset="0x0f4" name="PLL_ICPMSET"/>
+	<reg32 offset="0x0f8" name="PLL_ICPCSET"/>
+	<reg32 offset="0x0fc" name="PLL_ICP_SET"/>
+	<reg32 offset="0x100" name="PLL_LPF1"/>
+	<reg32 offset="0x104" name="PLL_LPF2_POSTDIV"/>
+	<reg32 offset="0x108" name="PLL_BANDGAP"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/dsi_phy_20nm.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/dsi_phy_20nm.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="DSI_20nm_PHY" width="32">
+	<array offset="0x00000" name="LN" length="4" stride="0x40">
+		<reg32 offset="0x00" name="CFG_0"/>
+		<reg32 offset="0x04" name="CFG_1"/>
+		<reg32 offset="0x08" name="CFG_2"/>
+		<reg32 offset="0x0c" name="CFG_3"/>
+		<reg32 offset="0x10" name="CFG_4"/>
+		<reg32 offset="0x14" name="TEST_DATAPATH"/>
+		<reg32 offset="0x18" name="DEBUG_SEL"/>
+		<reg32 offset="0x1c" name="TEST_STR_0"/>
+		<reg32 offset="0x20" name="TEST_STR_1"/>
+	</array>
+
+	<reg32 offset="0x00100" name="LNCK_CFG_0"/>
+	<reg32 offset="0x00104" name="LNCK_CFG_1"/>
+	<reg32 offset="0x00108" name="LNCK_CFG_2"/>
+	<reg32 offset="0x0010c" name="LNCK_CFG_3"/>
+	<reg32 offset="0x00110" name="LNCK_CFG_4"/>
+	<reg32 offset="0x00114" name="LNCK_TEST_DATAPATH"/>
+	<reg32 offset="0x00118" name="LNCK_DEBUG_SEL"/>
+	<reg32 offset="0x0011c" name="LNCK_TEST_STR0"/>
+	<reg32 offset="0x00120" name="LNCK_TEST_STR1"/>
+
+	<reg32 offset="0x00140" name="TIMING_CTRL_0">
+		<bitfield name="CLK_ZERO" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00144" name="TIMING_CTRL_1">
+		<bitfield name="CLK_TRAIL" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00148" name="TIMING_CTRL_2">
+		<bitfield name="CLK_PREPARE" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0014c" name="TIMING_CTRL_3">
+		<bitfield name="CLK_ZERO_8" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00150" name="TIMING_CTRL_4">
+		<bitfield name="HS_EXIT" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00154" name="TIMING_CTRL_5">
+		<bitfield name="HS_ZERO" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00158" name="TIMING_CTRL_6">
+		<bitfield name="HS_PREPARE" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0015c" name="TIMING_CTRL_7">
+		<bitfield name="HS_TRAIL" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00160" name="TIMING_CTRL_8">
+		<bitfield name="HS_RQST" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00164" name="TIMING_CTRL_9">
+		<bitfield name="TA_GO" low="0" high="2" type="uint"/>
+		<bitfield name="TA_SURE" low="4" high="6" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00168" name="TIMING_CTRL_10">
+		<bitfield name="TA_GET" low="0" high="2" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0016c" name="TIMING_CTRL_11">
+		<bitfield name="TRIG3_CMD" low="0" high="7" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00170" name="CTRL_0"/>
+	<reg32 offset="0x00174" name="CTRL_1"/>
+	<reg32 offset="0x00178" name="CTRL_2"/>
+	<reg32 offset="0x0017c" name="CTRL_3"/>
+	<reg32 offset="0x00180" name="CTRL_4"/>
+
+	<reg32 offset="0x00184" name="STRENGTH_0"/>
+	<reg32 offset="0x00188" name="STRENGTH_1"/>
+
+	<reg32 offset="0x001b4" name="BIST_CTRL_0"/>
+	<reg32 offset="0x001b8" name="BIST_CTRL_1"/>
+	<reg32 offset="0x001bc" name="BIST_CTRL_2"/>
+	<reg32 offset="0x001c0" name="BIST_CTRL_3"/>
+	<reg32 offset="0x001c4" name="BIST_CTRL_4"/>
+	<reg32 offset="0x001c8" name="BIST_CTRL_5"/>
+
+	<reg32 offset="0x001d4" name="GLBL_TEST_CTRL">
+		<bitfield name="BITCLK_HS_SEL" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x001dc" name="LDO_CNTRL"/>
+</domain>
+
+<domain name="DSI_20nm_PHY_REGULATOR" width="32">
+	<reg32 offset="0x00000" name="CTRL_0"/>
+	<reg32 offset="0x00004" name="CTRL_1"/>
+	<reg32 offset="0x00008" name="CTRL_2"/>
+	<reg32 offset="0x0000c" name="CTRL_3"/>
+	<reg32 offset="0x00010" name="CTRL_4"/>
+	<reg32 offset="0x00014" name="CTRL_5"/>
+	<reg32 offset="0x00018" name="CAL_PWR_CFG"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/dsi_phy_28nm.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/dsi_phy_28nm.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="DSI_28nm_PHY" width="32">
+	<array offset="0x00000" name="LN" length="4" stride="0x40">
+		<reg32 offset="0x00" name="CFG_0"/>
+		<reg32 offset="0x04" name="CFG_1"/>
+		<reg32 offset="0x08" name="CFG_2"/>
+		<reg32 offset="0x0c" name="CFG_3"/>
+		<reg32 offset="0x10" name="CFG_4"/>
+		<reg32 offset="0x14" name="TEST_DATAPATH"/>
+		<reg32 offset="0x18" name="DEBUG_SEL"/>
+		<reg32 offset="0x1c" name="TEST_STR_0"/>
+		<reg32 offset="0x20" name="TEST_STR_1"/>
+	</array>
+
+	<reg32 offset="0x00100" name="LNCK_CFG_0"/>
+	<reg32 offset="0x00104" name="LNCK_CFG_1"/>
+	<reg32 offset="0x00108" name="LNCK_CFG_2"/>
+	<reg32 offset="0x0010c" name="LNCK_CFG_3"/>
+	<reg32 offset="0x00110" name="LNCK_CFG_4"/>
+	<reg32 offset="0x00114" name="LNCK_TEST_DATAPATH"/>
+	<reg32 offset="0x00118" name="LNCK_DEBUG_SEL"/>
+	<reg32 offset="0x0011c" name="LNCK_TEST_STR0"/>
+	<reg32 offset="0x00120" name="LNCK_TEST_STR1"/>
+
+	<reg32 offset="0x00140" name="TIMING_CTRL_0">
+		<bitfield name="CLK_ZERO" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00144" name="TIMING_CTRL_1">
+		<bitfield name="CLK_TRAIL" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00148" name="TIMING_CTRL_2">
+		<bitfield name="CLK_PREPARE" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0014c" name="TIMING_CTRL_3">
+		<bitfield name="CLK_ZERO_8" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00150" name="TIMING_CTRL_4">
+		<bitfield name="HS_EXIT" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00154" name="TIMING_CTRL_5">
+		<bitfield name="HS_ZERO" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00158" name="TIMING_CTRL_6">
+		<bitfield name="HS_PREPARE" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0015c" name="TIMING_CTRL_7">
+		<bitfield name="HS_TRAIL" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00160" name="TIMING_CTRL_8">
+		<bitfield name="HS_RQST" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00164" name="TIMING_CTRL_9">
+		<bitfield name="TA_GO" low="0" high="2" type="uint"/>
+		<bitfield name="TA_SURE" low="4" high="6" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00168" name="TIMING_CTRL_10">
+		<bitfield name="TA_GET" low="0" high="2" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0016c" name="TIMING_CTRL_11">
+		<bitfield name="TRIG3_CMD" low="0" high="7" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00170" name="CTRL_0"/>
+	<reg32 offset="0x00174" name="CTRL_1"/>
+	<reg32 offset="0x00178" name="CTRL_2"/>
+	<reg32 offset="0x0017c" name="CTRL_3"/>
+	<reg32 offset="0x00180" name="CTRL_4"/>
+
+	<reg32 offset="0x00184" name="STRENGTH_0"/>
+	<reg32 offset="0x00188" name="STRENGTH_1"/>
+
+	<reg32 offset="0x001b4" name="BIST_CTRL_0"/>
+	<reg32 offset="0x001b8" name="BIST_CTRL_1"/>
+	<reg32 offset="0x001bc" name="BIST_CTRL_2"/>
+	<reg32 offset="0x001c0" name="BIST_CTRL_3"/>
+	<reg32 offset="0x001c4" name="BIST_CTRL_4"/>
+	<reg32 offset="0x001c8" name="BIST_CTRL_5"/>
+
+	<reg32 offset="0x001d4" name="GLBL_TEST_CTRL">
+		<bitfield name="BITCLK_HS_SEL" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x001dc" name="LDO_CNTRL"/>
+</domain>
+
+<domain name="DSI_28nm_PHY_REGULATOR" width="32">
+	<reg32 offset="0x00000" name="CTRL_0"/>
+	<reg32 offset="0x00004" name="CTRL_1"/>
+	<reg32 offset="0x00008" name="CTRL_2"/>
+	<reg32 offset="0x0000c" name="CTRL_3"/>
+	<reg32 offset="0x00010" name="CTRL_4"/>
+	<reg32 offset="0x00014" name="CTRL_5"/>
+	<reg32 offset="0x00018" name="CAL_PWR_CFG"/>
+</domain>
+
+<domain name="DSI_28nm_PHY_PLL" width="32">
+	<reg32 offset="0x00000" name="REFCLK_CFG">
+		<bitfield name="DBLR" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00004" name="POSTDIV1_CFG"/>
+	<reg32 offset="0x00008" name="CHGPUMP_CFG"/>
+	<reg32 offset="0x0000C" name="VCOLPF_CFG"/>
+	<reg32 offset="0x00010" name="VREG_CFG">
+		<bitfield name="POSTDIV1_BYPASS_B" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00014" name="PWRGEN_CFG"/>
+	<reg32 offset="0x00018" name="DMUX_CFG"/>
+	<reg32 offset="0x0001C" name="AMUX_CFG"/>
+	<reg32 offset="0x00020" name="GLB_CFG">
+		<bitfield name="PLL_PWRDN_B" pos="0" type="boolean"/>
+		<bitfield name="PLL_LDO_PWRDN_B" pos="1" type="boolean"/>
+		<bitfield name="PLL_PWRGEN_PWRDN_B" pos="2" type="boolean"/>
+		<bitfield name="PLL_ENABLE" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00024" name="POSTDIV2_CFG"/>
+	<reg32 offset="0x00028" name="POSTDIV3_CFG"/>
+	<reg32 offset="0x0002C" name="LPFR_CFG"/>
+	<reg32 offset="0x00030" name="LPFC1_CFG"/>
+	<reg32 offset="0x00034" name="LPFC2_CFG"/>
+	<reg32 offset="0x00038" name="SDM_CFG0">
+		<bitfield name="BYP_DIV" low="0" high="5" type="uint"/>
+		<bitfield name="BYP" pos="6" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0003C" name="SDM_CFG1">
+		<bitfield name="DC_OFFSET" low="0" high="5" type="uint"/>
+		<bitfield name="DITHER_EN" pos="6" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00040" name="SDM_CFG2">
+		<bitfield name="FREQ_SEED_7_0" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00044" name="SDM_CFG3">
+		<bitfield name="FREQ_SEED_15_8" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00048" name="SDM_CFG4"/>
+	<reg32 offset="0x0004C" name="SSC_CFG0"/>
+	<reg32 offset="0x00050" name="SSC_CFG1"/>
+	<reg32 offset="0x00054" name="SSC_CFG2"/>
+	<reg32 offset="0x00058" name="SSC_CFG3"/>
+	<reg32 offset="0x0005C" name="LKDET_CFG0"/>
+	<reg32 offset="0x00060" name="LKDET_CFG1"/>
+	<reg32 offset="0x00064" name="LKDET_CFG2"/>
+	<reg32 offset="0x00068" name="TEST_CFG">
+		<bitfield name="PLL_SW_RESET" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0006C" name="CAL_CFG0"/>
+	<reg32 offset="0x00070" name="CAL_CFG1"/>
+	<reg32 offset="0x00074" name="CAL_CFG2"/>
+	<reg32 offset="0x00078" name="CAL_CFG3"/>
+	<reg32 offset="0x0007C" name="CAL_CFG4"/>
+	<reg32 offset="0x00080" name="CAL_CFG5"/>
+	<reg32 offset="0x00084" name="CAL_CFG6"/>
+	<reg32 offset="0x00088" name="CAL_CFG7"/>
+	<reg32 offset="0x0008C" name="CAL_CFG8"/>
+	<reg32 offset="0x00090" name="CAL_CFG9"/>
+	<reg32 offset="0x00094" name="CAL_CFG10"/>
+	<reg32 offset="0x00098" name="CAL_CFG11"/>
+	<reg32 offset="0x0009C" name="EFUSE_CFG"/>
+	<reg32 offset="0x000A0" name="DEBUG_BUS_SEL"/>
+	<reg32 offset="0x000A4" name="CTRL_42"/>
+	<reg32 offset="0x000A8" name="CTRL_43"/>
+	<reg32 offset="0x000AC" name="CTRL_44"/>
+	<reg32 offset="0x000B0" name="CTRL_45"/>
+	<reg32 offset="0x000B4" name="CTRL_46"/>
+	<reg32 offset="0x000B8" name="CTRL_47"/>
+	<reg32 offset="0x000BC" name="CTRL_48"/>
+	<reg32 offset="0x000C0" name="STATUS">
+		<bitfield name="PLL_RDY" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x000C4" name="DEBUG_BUS0"/>
+	<reg32 offset="0x000C8" name="DEBUG_BUS1"/>
+	<reg32 offset="0x000CC" name="DEBUG_BUS2"/>
+	<reg32 offset="0x000D0" name="DEBUG_BUS3"/>
+	<reg32 offset="0x000D4" name="CTRL_54"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/dsi_phy_28nm_8960.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/dsi_phy_28nm_8960.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="DSI_28nm_8960_PHY" width="32">
+
+	<array offset="0x00000" name="LN" length="4" stride="0x40">
+		<reg32 offset="0x00" name="CFG_0"/>
+		<reg32 offset="0x04" name="CFG_1"/>
+		<reg32 offset="0x08" name="CFG_2"/>
+		<reg32 offset="0x0c" name="TEST_DATAPATH"/>
+		<reg32 offset="0x14" name="TEST_STR_0"/>
+		<reg32 offset="0x18" name="TEST_STR_1"/>
+	</array>
+
+	<reg32 offset="0x00100" name="LNCK_CFG_0"/>
+	<reg32 offset="0x00104" name="LNCK_CFG_1"/>
+	<reg32 offset="0x00108" name="LNCK_CFG_2"/>
+
+	<reg32 offset="0x0010c" name="LNCK_TEST_DATAPATH"/>
+	<reg32 offset="0x00114" name="LNCK_TEST_STR0"/>
+	<reg32 offset="0x00118" name="LNCK_TEST_STR1"/>
+
+	<reg32 offset="0x00140" name="TIMING_CTRL_0">
+		<bitfield name="CLK_ZERO" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00144" name="TIMING_CTRL_1">
+		<bitfield name="CLK_TRAIL" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00148" name="TIMING_CTRL_2">
+		<bitfield name="CLK_PREPARE" low="0" high="7" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x0014c" name="TIMING_CTRL_3"/>
+
+	<reg32 offset="0x00150" name="TIMING_CTRL_4">
+		<bitfield name="HS_EXIT" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00154" name="TIMING_CTRL_5">
+		<bitfield name="HS_ZERO" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00158" name="TIMING_CTRL_6">
+		<bitfield name="HS_PREPARE" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0015c" name="TIMING_CTRL_7">
+		<bitfield name="HS_TRAIL" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00160" name="TIMING_CTRL_8">
+		<bitfield name="HS_RQST" low="0" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00164" name="TIMING_CTRL_9">
+		<bitfield name="TA_GO" low="0" high="2" type="uint"/>
+		<bitfield name="TA_SURE" low="4" high="6" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00168" name="TIMING_CTRL_10">
+		<bitfield name="TA_GET" low="0" high="2" type="uint"/>
+	</reg32>
+	<reg32 offset="0x0016c" name="TIMING_CTRL_11">
+		<bitfield name="TRIG3_CMD" low="0" high="7" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00170" name="CTRL_0"/>
+	<reg32 offset="0x00174" name="CTRL_1"/>
+	<reg32 offset="0x00178" name="CTRL_2"/>
+	<reg32 offset="0x0017c" name="CTRL_3"/>
+
+	<reg32 offset="0x00180" name="STRENGTH_0"/>
+	<reg32 offset="0x00184" name="STRENGTH_1"/>
+	<reg32 offset="0x00188" name="STRENGTH_2"/>
+
+	<reg32 offset="0x0018c" name="BIST_CTRL_0"/>
+	<reg32 offset="0x00190" name="BIST_CTRL_1"/>
+	<reg32 offset="0x00194" name="BIST_CTRL_2"/>
+	<reg32 offset="0x00198" name="BIST_CTRL_3"/>
+	<reg32 offset="0x0019c" name="BIST_CTRL_4"/>
+
+	<reg32 offset="0x001b0" name="LDO_CTRL"/>
+</domain>
+
+<domain name="DSI_28nm_8960_PHY_MISC" width="32">
+	<reg32 offset="0x00000" name="REGULATOR_CTRL_0"/>
+	<reg32 offset="0x00004" name="REGULATOR_CTRL_1"/>
+	<reg32 offset="0x00008" name="REGULATOR_CTRL_2"/>
+	<reg32 offset="0x0000c" name="REGULATOR_CTRL_3"/>
+	<reg32 offset="0x00010" name="REGULATOR_CTRL_4"/>
+	<reg32 offset="0x00014" name="REGULATOR_CTRL_5"/>
+	<reg32 offset="0x00018" name="REGULATOR_CAL_PWR_CFG"/>
+	<reg32 offset="0x00028" name="CAL_HW_TRIGGER"/>
+	<reg32 offset="0x0002c" name="CAL_SW_CFG_0"/>
+	<reg32 offset="0x00030" name="CAL_SW_CFG_1"/>
+	<reg32 offset="0x00034" name="CAL_SW_CFG_2"/>
+	<reg32 offset="0x00038" name="CAL_HW_CFG_0"/>
+	<reg32 offset="0x0003c" name="CAL_HW_CFG_1"/>
+	<reg32 offset="0x00040" name="CAL_HW_CFG_2"/>
+	<reg32 offset="0x00044" name="CAL_HW_CFG_3"/>
+	<reg32 offset="0x00048" name="CAL_HW_CFG_4"/>
+	<reg32 offset="0x00050" name="CAL_STATUS">
+		<bitfield name="CAL_BUSY" pos="4" type="boolean"/>
+	</reg32>
+</domain>
+
+<domain name="DSI_28nm_8960_PHY_PLL" width="32">
+	<reg32 offset="0x00000" name="CTRL_0">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00004" name="CTRL_1"/>
+	<reg32 offset="0x00008" name="CTRL_2"/>
+	<reg32 offset="0x0000c" name="CTRL_3"/>
+	<reg32 offset="0x00010" name="CTRL_4"/>
+	<reg32 offset="0x00014" name="CTRL_5"/>
+	<reg32 offset="0x00018" name="CTRL_6"/>
+	<reg32 offset="0x0001c" name="CTRL_7"/>
+	<reg32 offset="0x00020" name="CTRL_8"/>
+	<reg32 offset="0x00024" name="CTRL_9"/>
+	<reg32 offset="0x00028" name="CTRL_10"/>
+	<reg32 offset="0x0002c" name="CTRL_11"/>
+	<reg32 offset="0x00030" name="CTRL_12"/>
+	<reg32 offset="0x00034" name="CTRL_13"/>
+	<reg32 offset="0x00038" name="CTRL_14"/>
+	<reg32 offset="0x0003c" name="CTRL_15"/>
+	<reg32 offset="0x00040" name="CTRL_16"/>
+	<reg32 offset="0x00044" name="CTRL_17"/>
+	<reg32 offset="0x00048" name="CTRL_18"/>
+	<reg32 offset="0x0004c" name="CTRL_19"/>
+	<reg32 offset="0x00050" name="CTRL_20"/>
+
+	<reg32 offset="0x00080" name="RDY">
+		<bitfield name="PLL_RDY" pos="0" type="boolean"/>
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/dsi_phy_7nm.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/dsi_phy_7nm.xml
@@ -0,0 +1,230 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="DSI_7nm_PHY_CMN" width="32">
+	<reg32 offset="0x00000" name="REVISION_ID0"/>
+	<reg32 offset="0x00004" name="REVISION_ID1"/>
+	<reg32 offset="0x00008" name="REVISION_ID2"/>
+	<reg32 offset="0x0000c" name="REVISION_ID3"/>
+	<reg32 offset="0x00010" name="CLK_CFG0"/>
+	<reg32 offset="0x00014" name="CLK_CFG1"/>
+	<reg32 offset="0x00018" name="GLBL_CTRL"/>
+	<reg32 offset="0x0001c" name="RBUF_CTRL"/>
+	<reg32 offset="0x00020" name="VREG_CTRL_0"/>
+	<reg32 offset="0x00024" name="CTRL_0"/>
+	<reg32 offset="0x00028" name="CTRL_1"/>
+	<reg32 offset="0x0002c" name="CTRL_2"/>
+	<reg32 offset="0x00030" name="CTRL_3"/>
+	<reg32 offset="0x00034" name="LANE_CFG0"/>
+	<reg32 offset="0x00038" name="LANE_CFG1"/>
+	<reg32 offset="0x0003c" name="PLL_CNTRL"/>
+	<reg32 offset="0x00040" name="DPHY_SOT"/>
+	<reg32 offset="0x000a0" name="LANE_CTRL0"/>
+	<reg32 offset="0x000a4" name="LANE_CTRL1"/>
+	<reg32 offset="0x000a8" name="LANE_CTRL2"/>
+	<reg32 offset="0x000ac" name="LANE_CTRL3"/>
+	<reg32 offset="0x000b0" name="LANE_CTRL4"/>
+	<reg32 offset="0x000b4" name="TIMING_CTRL_0"/>
+	<reg32 offset="0x000b8" name="TIMING_CTRL_1"/>
+	<reg32 offset="0x000bc" name="TIMING_CTRL_2"/>
+	<reg32 offset="0x000c0" name="TIMING_CTRL_3"/>
+	<reg32 offset="0x000c4" name="TIMING_CTRL_4"/>
+	<reg32 offset="0x000c8" name="TIMING_CTRL_5"/>
+	<reg32 offset="0x000cc" name="TIMING_CTRL_6"/>
+	<reg32 offset="0x000d0" name="TIMING_CTRL_7"/>
+	<reg32 offset="0x000d4" name="TIMING_CTRL_8"/>
+	<reg32 offset="0x000d8" name="TIMING_CTRL_9"/>
+	<reg32 offset="0x000dc" name="TIMING_CTRL_10"/>
+	<reg32 offset="0x000e0" name="TIMING_CTRL_11"/>
+	<reg32 offset="0x000e4" name="TIMING_CTRL_12"/>
+	<reg32 offset="0x000e8" name="TIMING_CTRL_13"/>
+	<reg32 offset="0x000ec" name="GLBL_HSTX_STR_CTRL_0"/>
+	<reg32 offset="0x000f0" name="GLBL_HSTX_STR_CTRL_1"/>
+	<reg32 offset="0x000f4" name="GLBL_RESCODE_OFFSET_TOP_CTRL"/>
+	<reg32 offset="0x000f8" name="GLBL_RESCODE_OFFSET_BOT_CTRL"/>
+	<reg32 offset="0x000fc" name="GLBL_RESCODE_OFFSET_MID_CTRL"/>
+	<reg32 offset="0x00100" name="GLBL_LPTX_STR_CTRL"/>
+	<reg32 offset="0x00104" name="GLBL_PEMPH_CTRL_0"/>
+	<reg32 offset="0x00108" name="GLBL_PEMPH_CTRL_1"/>
+	<reg32 offset="0x0010c" name="GLBL_STR_SWI_CAL_SEL_CTRL"/>
+	<reg32 offset="0x00110" name="VREG_CTRL_1"/>
+	<reg32 offset="0x00114" name="CTRL_4"/>
+	<reg32 offset="0x00128" name="GLBL_DIGTOP_SPARE4"/>
+	<reg32 offset="0x00140" name="PHY_STATUS"/>
+	<reg32 offset="0x00148" name="LANE_STATUS0"/>
+	<reg32 offset="0x0014c" name="LANE_STATUS1"/>
+	<reg32 offset="0x001ac" name="GLBL_DIGTOP_SPARE10"/>
+</domain>
+
+<domain name="DSI_7nm_PHY" width="32">
+	<array offset="0x00000" name="LN" length="5" stride="0x80">
+		<reg32 offset="0x00" name="CFG0"/>
+		<reg32 offset="0x04" name="CFG1"/>
+		<reg32 offset="0x08" name="CFG2"/>
+		<reg32 offset="0x0c" name="TEST_DATAPATH"/>
+		<reg32 offset="0x10" name="PIN_SWAP"/>
+		<reg32 offset="0x14" name="LPRX_CTRL"/>
+		<reg32 offset="0x18" name="TX_DCTRL"/>
+	</array>
+</domain>
+
+<domain name="DSI_7nm_PHY_PLL" width="32">
+	<reg32 offset="0x0000" name="ANALOG_CONTROLS_ONE"/>
+	<reg32 offset="0x0004" name="ANALOG_CONTROLS_TWO"/>
+	<reg32 offset="0x0008" name="INT_LOOP_SETTINGS"/>
+	<reg32 offset="0x000c" name="INT_LOOP_SETTINGS_TWO"/>
+	<reg32 offset="0x0010" name="ANALOG_CONTROLS_THREE"/>
+	<reg32 offset="0x0014" name="ANALOG_CONTROLS_FOUR"/>
+	<reg32 offset="0x0018" name="ANALOG_CONTROLS_FIVE"/>
+	<reg32 offset="0x001c" name="INT_LOOP_CONTROLS"/>
+	<reg32 offset="0x0020" name="DSM_DIVIDER"/>
+	<reg32 offset="0x0024" name="FEEDBACK_DIVIDER"/>
+	<reg32 offset="0x0028" name="SYSTEM_MUXES"/>
+	<reg32 offset="0x002c" name="FREQ_UPDATE_CONTROL_OVERRIDES"/>
+	<reg32 offset="0x0030" name="CMODE"/>
+	<reg32 offset="0x0034" name="PSM_CTRL"/>
+	<reg32 offset="0x0038" name="RSM_CTRL"/>
+	<reg32 offset="0x003c" name="VCO_TUNE_MAP"/>
+	<reg32 offset="0x0040" name="PLL_CNTRL"/>
+	<reg32 offset="0x0044" name="CALIBRATION_SETTINGS"/>
+	<reg32 offset="0x0048" name="BAND_SEL_CAL_TIMER_LOW"/>
+	<reg32 offset="0x004c" name="BAND_SEL_CAL_TIMER_HIGH"/>
+	<reg32 offset="0x0050" name="BAND_SEL_CAL_SETTINGS"/>
+	<reg32 offset="0x0054" name="BAND_SEL_MIN"/>
+	<reg32 offset="0x0058" name="BAND_SEL_MAX"/>
+	<reg32 offset="0x005c" name="BAND_SEL_PFILT"/>
+	<reg32 offset="0x0060" name="BAND_SEL_IFILT"/>
+	<reg32 offset="0x0064" name="BAND_SEL_CAL_SETTINGS_TWO"/>
+	<reg32 offset="0x0068" name="BAND_SEL_CAL_SETTINGS_THREE"/>
+	<reg32 offset="0x006c" name="BAND_SEL_CAL_SETTINGS_FOUR"/>
+	<reg32 offset="0x0070" name="BAND_SEL_ICODE_HIGH"/>
+	<reg32 offset="0x0074" name="BAND_SEL_ICODE_LOW"/>
+	<reg32 offset="0x0078" name="FREQ_DETECT_SETTINGS_ONE"/>
+	<reg32 offset="0x007c" name="FREQ_DETECT_THRESH"/>
+	<reg32 offset="0x0080" name="FREQ_DET_REFCLK_HIGH"/>
+	<reg32 offset="0x0084" name="FREQ_DET_REFCLK_LOW"/>
+	<reg32 offset="0x0088" name="FREQ_DET_PLLCLK_HIGH"/>
+	<reg32 offset="0x008c" name="FREQ_DET_PLLCLK_LOW"/>
+	<reg32 offset="0x0090" name="PFILT"/>
+	<reg32 offset="0x0094" name="IFILT"/>
+	<reg32 offset="0x0098" name="PLL_GAIN"/>
+	<reg32 offset="0x009c" name="ICODE_LOW"/>
+	<reg32 offset="0x00a0" name="ICODE_HIGH"/>
+	<reg32 offset="0x00a4" name="LOCKDET"/>
+	<reg32 offset="0x00a8" name="OUTDIV"/>
+	<reg32 offset="0x00ac" name="FASTLOCK_CONTROL"/>
+	<reg32 offset="0x00b0" name="PASS_OUT_OVERRIDE_ONE"/>
+	<reg32 offset="0x00b4" name="PASS_OUT_OVERRIDE_TWO"/>
+	<reg32 offset="0x00b8" name="CORE_OVERRIDE"/>
+	<reg32 offset="0x00bc" name="CORE_INPUT_OVERRIDE"/>
+	<reg32 offset="0x00c0" name="RATE_CHANGE"/>
+	<reg32 offset="0x00c4" name="PLL_DIGITAL_TIMERS"/>
+	<reg32 offset="0x00c8" name="PLL_DIGITAL_TIMERS_TWO"/>
+	<reg32 offset="0x00cc" name="DECIMAL_DIV_START"/>
+	<reg32 offset="0x00d0" name="FRAC_DIV_START_LOW"/>
+	<reg32 offset="0x00d4" name="FRAC_DIV_START_MID"/>
+	<reg32 offset="0x00d8" name="FRAC_DIV_START_HIGH"/>
+	<reg32 offset="0x00dc" name="DEC_FRAC_MUXES"/>
+	<reg32 offset="0x00e0" name="DECIMAL_DIV_START_1"/>
+	<reg32 offset="0x00e4" name="FRAC_DIV_START_LOW_1"/>
+	<reg32 offset="0x00e8" name="FRAC_DIV_START_MID_1"/>
+	<reg32 offset="0x00ec" name="FRAC_DIV_START_HIGH_1"/>
+	<reg32 offset="0x00f0" name="DECIMAL_DIV_START_2"/>
+	<reg32 offset="0x00f4" name="FRAC_DIV_START_LOW_2"/>
+	<reg32 offset="0x00f8" name="FRAC_DIV_START_MID_2"/>
+	<reg32 offset="0x00fc" name="FRAC_DIV_START_HIGH_2"/>
+	<reg32 offset="0x0100" name="MASH_CONTROL"/>
+	<reg32 offset="0x0104" name="SSC_STEPSIZE_LOW"/>
+	<reg32 offset="0x0108" name="SSC_STEPSIZE_HIGH"/>
+	<reg32 offset="0x010c" name="SSC_DIV_PER_LOW"/>
+	<reg32 offset="0x0110" name="SSC_DIV_PER_HIGH"/>
+	<reg32 offset="0x0114" name="SSC_ADJPER_LOW"/>
+	<reg32 offset="0x0118" name="SSC_ADJPER_HIGH"/>
+	<reg32 offset="0x011c" name="SSC_MUX_CONTROL"/>
+	<reg32 offset="0x0120" name="SSC_STEPSIZE_LOW_1"/>
+	<reg32 offset="0x0124" name="SSC_STEPSIZE_HIGH_1"/>
+	<reg32 offset="0x0128" name="SSC_DIV_PER_LOW_1"/>
+	<reg32 offset="0x012c" name="SSC_DIV_PER_HIGH_1"/>
+	<reg32 offset="0x0130" name="SSC_ADJPER_LOW_1"/>
+	<reg32 offset="0x0134" name="SSC_ADJPER_HIGH_1"/>
+	<reg32 offset="0x0138" name="SSC_STEPSIZE_LOW_2"/>
+	<reg32 offset="0x013c" name="SSC_STEPSIZE_HIGH_2"/>
+	<reg32 offset="0x0140" name="SSC_DIV_PER_LOW_2"/>
+	<reg32 offset="0x0144" name="SSC_DIV_PER_HIGH_2"/>
+	<reg32 offset="0x0148" name="SSC_ADJPER_LOW_2"/>
+	<reg32 offset="0x014c" name="SSC_ADJPER_HIGH_2"/>
+	<reg32 offset="0x0150" name="SSC_CONTROL"/>
+	<reg32 offset="0x0154" name="PLL_OUTDIV_RATE"/>
+	<reg32 offset="0x0158" name="PLL_LOCKDET_RATE_1"/>
+	<reg32 offset="0x015c" name="PLL_LOCKDET_RATE_2"/>
+	<reg32 offset="0x0160" name="PLL_PROP_GAIN_RATE_1"/>
+	<reg32 offset="0x0164" name="PLL_PROP_GAIN_RATE_2"/>
+	<reg32 offset="0x0168" name="PLL_BAND_SEL_RATE_1"/>
+	<reg32 offset="0x016c" name="PLL_BAND_SEL_RATE_2"/>
+	<reg32 offset="0x0170" name="PLL_INT_GAIN_IFILT_BAND_1"/>
+	<reg32 offset="0x0174" name="PLL_INT_GAIN_IFILT_BAND_2"/>
+	<reg32 offset="0x0178" name="PLL_FL_INT_GAIN_PFILT_BAND_1"/>
+	<reg32 offset="0x017c" name="PLL_FL_INT_GAIN_PFILT_BAND_2"/>
+	<reg32 offset="0x0180" name="PLL_FASTLOCK_EN_BAND"/>
+	<reg32 offset="0x0184" name="FREQ_TUNE_ACCUM_INIT_MID"/>
+	<reg32 offset="0x0188" name="FREQ_TUNE_ACCUM_INIT_HIGH"/>
+	<reg32 offset="0x018c" name="FREQ_TUNE_ACCUM_INIT_MUX"/>
+	<reg32 offset="0x0190" name="PLL_LOCK_OVERRIDE"/>
+	<reg32 offset="0x0194" name="PLL_LOCK_DELAY"/>
+	<reg32 offset="0x0198" name="PLL_LOCK_MIN_DELAY"/>
+	<reg32 offset="0x019c" name="CLOCK_INVERTERS"/>
+	<reg32 offset="0x01a0" name="SPARE_AND_JPC_OVERRIDES"/>
+	<reg32 offset="0x01a4" name="BIAS_CONTROL_1"/>
+	<reg32 offset="0x01a8" name="BIAS_CONTROL_2"/>
+	<reg32 offset="0x01ac" name="ALOG_OBSV_BUS_CTRL_1"/>
+	<reg32 offset="0x01b0" name="COMMON_STATUS_ONE"/>
+	<reg32 offset="0x01b4" name="COMMON_STATUS_TWO"/>
+	<reg32 offset="0x01b8" name="BAND_SEL_CAL"/>
+	<reg32 offset="0x01bc" name="ICODE_ACCUM_STATUS_LOW"/>
+	<reg32 offset="0x01c0" name="ICODE_ACCUM_STATUS_HIGH"/>
+	<reg32 offset="0x01c4" name="FD_OUT_LOW"/>
+	<reg32 offset="0x01c8" name="FD_OUT_HIGH"/>
+	<reg32 offset="0x01cc" name="ALOG_OBSV_BUS_STATUS_1"/>
+	<reg32 offset="0x01d0" name="PLL_MISC_CONFIG"/>
+	<reg32 offset="0x01d4" name="FLL_CONFIG"/>
+	<reg32 offset="0x01d8" name="FLL_FREQ_ACQ_TIME"/>
+	<reg32 offset="0x01dc" name="FLL_CODE0"/>
+	<reg32 offset="0x01e0" name="FLL_CODE1"/>
+	<reg32 offset="0x01e4" name="FLL_GAIN0"/>
+	<reg32 offset="0x01e8" name="FLL_GAIN1"/>
+	<reg32 offset="0x01ec" name="SW_RESET"/>
+	<reg32 offset="0x01f0" name="FAST_PWRUP"/>
+	<reg32 offset="0x01f4" name="LOCKTIME0"/>
+	<reg32 offset="0x01f8" name="LOCKTIME1"/>
+	<reg32 offset="0x01fc" name="DEBUG_BUS_SEL"/>
+	<reg32 offset="0x0200" name="DEBUG_BUS0"/>
+	<reg32 offset="0x0204" name="DEBUG_BUS1"/>
+	<reg32 offset="0x0208" name="DEBUG_BUS2"/>
+	<reg32 offset="0x020c" name="DEBUG_BUS3"/>
+	<reg32 offset="0x0210" name="ANALOG_FLL_CONTROL_OVERRIDES"/>
+	<reg32 offset="0x0214" name="VCO_CONFIG"/>
+	<reg32 offset="0x0218" name="VCO_CAL_CODE1_MODE0_STATUS"/>
+	<reg32 offset="0x021c" name="VCO_CAL_CODE1_MODE1_STATUS"/>
+	<reg32 offset="0x0220" name="RESET_SM_STATUS"/>
+	<reg32 offset="0x0224" name="TDC_OFFSET"/>
+	<reg32 offset="0x0228" name="PS3_PWRDOWN_CONTROLS"/>
+	<reg32 offset="0x022c" name="PS4_PWRDOWN_CONTROLS"/>
+	<reg32 offset="0x0230" name="PLL_RST_CONTROLS"/>
+	<reg32 offset="0x0234" name="GEAR_BAND_SELECT_CONTROLS"/>
+	<reg32 offset="0x0238" name="PSM_CLK_CONTROLS"/>
+	<reg32 offset="0x023c" name="SYSTEM_MUXES_2"/>
+	<reg32 offset="0x0240" name="VCO_CONFIG_1"/>
+	<reg32 offset="0x0244" name="VCO_CONFIG_2"/>
+	<reg32 offset="0x0248" name="CLOCK_INVERTERS_1"/>
+	<reg32 offset="0x024c" name="CLOCK_INVERTERS_2"/>
+	<reg32 offset="0x0250" name="CMODE_1"/>
+	<reg32 offset="0x0254" name="CMODE_2"/>
+	<reg32 offset="0x0258" name="ANALOG_CONTROLS_FIVE_1"/>
+	<reg32 offset="0x025c" name="ANALOG_CONTROLS_FIVE_2"/>
+	<reg32 offset="0x0260" name="PERF_OPTIMIZE"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/edp.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/edp.xml
@@ -0,0 +1,239 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="EDP" width="32">
+	<enum name="edp_color_depth">
+		<value name="EDP_6BIT"  value="0"/>
+		<value name="EDP_8BIT"  value="1"/>
+		<value name="EDP_10BIT" value="2"/>
+		<value name="EDP_12BIT" value="3"/>
+		<value name="EDP_16BIT" value="4"/>
+	</enum>
+
+	<enum name="edp_component_format">
+		<value name="EDP_RGB" value="0"/>
+		<value name="EDP_YUV422" value="1"/>
+		<value name="EDP_YUV444" value="2"/>
+	</enum>
+
+	<reg32 offset="0x0004" name="MAINLINK_CTRL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="RESET"  pos="1" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0008" name="STATE_CTRL">
+		<bitfield name="TRAIN_PATTERN_1"       pos="0" type="boolean"/>
+		<bitfield name="TRAIN_PATTERN_2"       pos="1" type="boolean"/>
+		<bitfield name="TRAIN_PATTERN_3"       pos="2" type="boolean"/>
+		<bitfield name="SYMBOL_ERR_RATE_MEAS"  pos="3" type="boolean"/>
+		<bitfield name="PRBS7"                 pos="4" type="boolean"/>
+		<bitfield name="CUSTOM_80_BIT_PATTERN" pos="5" type="boolean"/>
+		<bitfield name="SEND_VIDEO"            pos="6" type="boolean"/>
+		<bitfield name="PUSH_IDLE"             pos="7" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x000c" name="CONFIGURATION_CTRL">
+		<!-- next two may be swapped? -->
+		<bitfield name="SYNC_CLK" pos="0" type="boolean"/>
+		<bitfield name="STATIC_MVID" pos="1" type="boolean"/>
+		<bitfield name="PROGRESSIVE" pos="2" type="boolean"/>
+		<!-- # of lanes minus one: -->
+		<bitfield name="LANES" low="4" high="5" type="uint"/>
+		<bitfield name="ENHANCED_FRAMING" pos="6" type="boolean"/>
+		<!--
+		   NOTE: only 6bit and 8bit valid
+		 -->
+		<bitfield name="COLOR" pos="8" type="edp_color_depth"/>
+	</reg32>
+
+	<reg32 offset="0x0014" name="SOFTWARE_MVID" type="uint"/>
+	<reg32 offset="0x0018" name="SOFTWARE_NVID" type="uint"/>
+
+	<reg32 offset="0x001c" name="TOTAL_HOR_VER">
+		<bitfield name="HORIZ" low="0" high="15" type="uint"/>
+		<bitfield name="VERT"  low="16" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x0020" name="START_HOR_VER_FROM_SYNC">
+		<bitfield name="HORIZ" low="0" high="15" type="uint"/>
+		<bitfield name="VERT"  low="16" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x0024" name="HSYNC_VSYNC_WIDTH_POLARITY">
+		<bitfield name="HORIZ"  low="0" high="14" type="uint"/>
+		<bitfield name="NHSYNC" pos="15" type="boolean"/>
+		<bitfield name="VERT"   low="16" high="30" type="uint"/>
+		<bitfield name="NVSYNC" pos="31" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0028" name="ACTIVE_HOR_VER">
+		<bitfield name="HORIZ" low="0" high="15" type="uint"/>
+		<bitfield name="VERT"  low="16" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x002c" name="MISC1_MISC0">
+		<!-- MISC0 from DisplayPort v1.2 spec: -->
+		<bitfield name="MISC0" low="0" high="7"/>
+		<!-- aliased MISC0 bitfields: -->
+		<bitfield name="SYNC" pos="0" type="boolean"/>
+		<bitfield name="COMPONENT_FORMAT" low="1" high="2" type="edp_component_format"/>
+		<!-- CEA (vs VESA) color range: -->
+		<bitfield name="CEA" pos="3" type="boolean"/>
+		<!-- YCbCr Colorimetry ITU-R BT709-5 (vs ITU-R BT601-5): -->
+		<bitfield name="BT709_5" pos="4" type="boolean"/>
+		<bitfield name="COLOR" low="5" high="7" type="edp_color_depth"/>
+
+		<!-- MISC1 from DisplayPort v1.2 spec: -->
+		<bitfield name="MISC1" low="8" high="15"/>
+		<!-- aliased MISC1 bitfields: -->
+		<bitfield name="INTERLACED_ODD" pos="8" type="boolean"/>
+		<bitfield name="STEREO" low="9" high="10" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x0074" name="PHY_CTRL">
+		<bitfield name="SW_RESET_PLL" pos="0" type="boolean"/>
+		<bitfield name="SW_RESET" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0084" name="MAINLINK_READY">
+		<bitfield name="TRAIN_PATTERN_1_READY" pos="3" type="boolean"/>
+		<bitfield name="TRAIN_PATTERN_2_READY" pos="4" type="boolean"/>
+		<bitfield name="TRAIN_PATTERN_3_READY" pos="5" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0300" name="AUX_CTRL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="RESET"  pos="1" type="boolean"/>
+	</reg32>
+
+	<!-- interrupt registers come in sets of 3 bits, status/ack/en -->
+	<reg32 offset="0x0308" name="INTERRUPT_REG_1">
+		<bitfield name="HPD"                    pos="0"  type="boolean"/>
+		<bitfield name="HPD_ACK"                pos="1"  type="boolean"/>
+		<bitfield name="HPD_EN"                 pos="2"  type="boolean"/>
+		<bitfield name="AUX_I2C_DONE"           pos="3"  type="boolean"/>
+		<bitfield name="AUX_I2C_DONE_ACK"       pos="4"  type="boolean"/>
+		<bitfield name="AUX_I2C_DONE_EN"        pos="5"  type="boolean"/>
+		<bitfield name="WRONG_ADDR"             pos="6"  type="boolean"/>
+		<bitfield name="WRONG_ADDR_ACK"         pos="7"  type="boolean"/>
+		<bitfield name="WRONG_ADDR_EN"          pos="8"  type="boolean"/>
+		<bitfield name="TIMEOUT"                pos="9"  type="boolean"/>
+		<bitfield name="TIMEOUT_ACK"            pos="10" type="boolean"/>
+		<bitfield name="TIMEOUT_EN"             pos="11" type="boolean"/>
+		<bitfield name="NACK_DEFER"             pos="12" type="boolean"/>
+		<bitfield name="NACK_DEFER_ACK"         pos="13" type="boolean"/>
+		<bitfield name="NACK_DEFER_EN"          pos="14" type="boolean"/>
+		<bitfield name="WRONG_DATA_CNT"         pos="15" type="boolean"/>
+		<bitfield name="WRONG_DATA_CNT_ACK"     pos="16" type="boolean"/>
+		<bitfield name="WRONG_DATA_CNT_EN"      pos="17" type="boolean"/>
+		<bitfield name="I2C_NACK"               pos="18" type="boolean"/>
+		<bitfield name="I2C_NACK_ACK"           pos="19" type="boolean"/>
+		<bitfield name="I2C_NACK_EN"            pos="20" type="boolean"/>
+		<bitfield name="I2C_DEFER"              pos="21" type="boolean"/>
+		<bitfield name="I2C_DEFER_ACK"          pos="22" type="boolean"/>
+		<bitfield name="I2C_DEFER_EN"           pos="23" type="boolean"/>
+		<bitfield name="PLL_UNLOCK"             pos="24" type="boolean"/>
+		<bitfield name="PLL_UNLOCK_ACK"         pos="25" type="boolean"/>
+		<bitfield name="PLL_UNLOCK_EN"          pos="26" type="boolean"/>
+		<bitfield name="AUX_ERROR"              pos="27" type="boolean"/>
+		<bitfield name="AUX_ERROR_ACK"          pos="28" type="boolean"/>
+		<bitfield name="AUX_ERROR_EN"           pos="29" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x030c" name="INTERRUPT_REG_2">
+		<bitfield name="READY_FOR_VIDEO"        pos="0"  type="boolean"/>
+		<bitfield name="READY_FOR_VIDEO_ACK"    pos="1"  type="boolean"/>
+		<bitfield name="READY_FOR_VIDEO_EN"     pos="2"  type="boolean"/>
+		<bitfield name="IDLE_PATTERNs_SENT"     pos="3"  type="boolean"/>
+		<bitfield name="IDLE_PATTERNs_SENT_ACK" pos="4"  type="boolean"/>
+		<bitfield name="IDLE_PATTERNs_SENT_EN"  pos="5"  type="boolean"/>
+		<bitfield name="FRAME_END"              pos="9"  type="boolean"/>
+		<bitfield name="FRAME_END_ACK"          pos="7"  type="boolean"/>
+		<bitfield name="FRAME_END_EN"           pos="8"  type="boolean"/>
+		<bitfield name="CRC_UPDATED"            pos="9"  type="boolean"/>
+		<bitfield name="CRC_UPDATED_ACK"        pos="10" type="boolean"/>
+		<bitfield name="CRC_UPDATED_EN"         pos="11" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0310" name="INTERRUPT_TRANS_NUM"/>
+	<reg32 offset="0x0314" name="AUX_DATA">
+		<bitfield name="READ" pos="0" type="boolean"/>
+		<bitfield name="DATA" low="8" high="15"/>
+		<bitfield name="INDEX" low="16" high="23"/>
+		<bitfield name="INDEX_WRITE" pos="31" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0318" name="AUX_TRANS_CTRL">
+		<bitfield name="I2C" pos="8" type="boolean"/>
+		<bitfield name="GO"  pos="9" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0324" name="AUX_STATUS"/>
+</domain>
+
+<domain name="EDP_PHY" width="32">
+	<array offset="0x0400" name="LN" length="4" stride="0x40">
+		<reg32 offset="0x04" name="PD_CTL"/>
+	</array>
+	<reg32 offset="0x0510" name="GLB_VM_CFG0"/>
+	<reg32 offset="0x0514" name="GLB_VM_CFG1"/>
+	<reg32 offset="0x0518" name="GLB_MISC9"/>
+	<reg32 offset="0x0528" name="GLB_CFG"/>
+	<reg32 offset="0x052c" name="GLB_PD_CTL"/>
+	<reg32 offset="0x0598" name="GLB_PHY_STATUS"/>
+</domain>
+
+<domain name="EDP_28nm_PHY_PLL" width="32">
+	<reg32 offset="0x00000" name="REFCLK_CFG"/>
+	<reg32 offset="0x00004" name="POSTDIV1_CFG"/>
+	<reg32 offset="0x00008" name="CHGPUMP_CFG"/>
+	<reg32 offset="0x0000C" name="VCOLPF_CFG"/>
+	<reg32 offset="0x00010" name="VREG_CFG"/>
+	<reg32 offset="0x00014" name="PWRGEN_CFG"/>
+	<reg32 offset="0x00018" name="DMUX_CFG"/>
+	<reg32 offset="0x0001C" name="AMUX_CFG"/>
+	<reg32 offset="0x00020" name="GLB_CFG">
+		<bitfield name="PLL_PWRDN_B" pos="0" type="boolean"/>
+		<bitfield name="PLL_LDO_PWRDN_B" pos="1" type="boolean"/>
+		<bitfield name="PLL_PWRGEN_PWRDN_B" pos="2" type="boolean"/>
+		<bitfield name="PLL_ENABLE" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00024" name="POSTDIV2_CFG"/>
+	<reg32 offset="0x00028" name="POSTDIV3_CFG"/>
+	<reg32 offset="0x0002C" name="LPFR_CFG"/>
+	<reg32 offset="0x00030" name="LPFC1_CFG"/>
+	<reg32 offset="0x00034" name="LPFC2_CFG"/>
+	<reg32 offset="0x00038" name="SDM_CFG0"/>
+	<reg32 offset="0x0003C" name="SDM_CFG1"/>
+	<reg32 offset="0x00040" name="SDM_CFG2"/>
+	<reg32 offset="0x00044" name="SDM_CFG3"/>
+	<reg32 offset="0x00048" name="SDM_CFG4"/>
+	<reg32 offset="0x0004C" name="SSC_CFG0"/>
+	<reg32 offset="0x00050" name="SSC_CFG1"/>
+	<reg32 offset="0x00054" name="SSC_CFG2"/>
+	<reg32 offset="0x00058" name="SSC_CFG3"/>
+	<reg32 offset="0x0005C" name="LKDET_CFG0"/>
+	<reg32 offset="0x00060" name="LKDET_CFG1"/>
+	<reg32 offset="0x00064" name="LKDET_CFG2"/>
+	<reg32 offset="0x00068" name="TEST_CFG">
+		<bitfield name="PLL_SW_RESET" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0006C" name="CAL_CFG0"/>
+	<reg32 offset="0x00070" name="CAL_CFG1"/>
+	<reg32 offset="0x00074" name="CAL_CFG2"/>
+	<reg32 offset="0x00078" name="CAL_CFG3"/>
+	<reg32 offset="0x0007C" name="CAL_CFG4"/>
+	<reg32 offset="0x00080" name="CAL_CFG5"/>
+	<reg32 offset="0x00084" name="CAL_CFG6"/>
+	<reg32 offset="0x00088" name="CAL_CFG7"/>
+	<reg32 offset="0x0008C" name="CAL_CFG8"/>
+	<reg32 offset="0x00090" name="CAL_CFG9"/>
+	<reg32 offset="0x00094" name="CAL_CFG10"/>
+	<reg32 offset="0x00098" name="CAL_CFG11"/>
+	<reg32 offset="0x0009C" name="EFUSE_CFG"/>
+	<reg32 offset="0x000A0" name="DEBUG_BUS_SEL"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/hdmi.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/hdmi.xml
@@ -0,0 +1,1104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<!--
+	NOTE: also see mdss_hdmi_util.h.. newer devices using MDSS appear
+	to have the same HDMI block (or maybe a newer version?) but for
+	some reason duplicate the code under drivers/video/msm/mdss
+ -->
+
+<domain name="HDMI" width="32">
+	<enum name="hdmi_hdcp_key_state">
+		<value name="HDCP_KEYS_STATE_NO_KEYS" value="0"/>
+		<value name="HDCP_KEYS_STATE_NOT_CHECKED" value="1"/>
+		<value name="HDCP_KEYS_STATE_CHECKING" value="2"/>
+		<value name="HDCP_KEYS_STATE_VALID" value="3"/>
+		<value name="HDCP_KEYS_STATE_AKSV_NOT_VALID" value="4"/>
+		<value name="HDCP_KEYS_STATE_CHKSUM_MISMATCH" value="5"/>
+		<value name="HDCP_KEYS_STATE_PROD_AKSV" value="6"/>
+		<value name="HDCP_KEYS_STATE_RESERVED" value="7"/>
+	</enum>
+	<enum name="hdmi_ddc_read_write">
+		<value name="DDC_WRITE" value="0"/>
+		<value name="DDC_READ" value="1"/>
+	</enum>
+	<enum name="hdmi_acr_cts">
+		<value name="ACR_NONE" value="0"/>
+		<value name="ACR_32" value="1"/>
+		<value name="ACR_44" value="2"/>
+		<value name="ACR_48" value="3"/>
+	</enum>
+
+	<enum name="hdmi_cec_tx_status">
+		<value name="CEC_TX_OK" value="0"/>
+		<value name="CEC_TX_NACK" value="1"/>
+		<value name="CEC_TX_ARB_LOSS" value="2"/>
+		<value name="CEC_TX_MAX_RETRIES" value="3"/>
+	</enum>
+
+	<reg32 offset="0x00000" name="CTRL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="HDMI" pos="1" type="boolean"/>
+		<bitfield name="ENCRYPTED" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00020" name="AUDIO_PKT_CTRL1">
+		<bitfield name="AUDIO_SAMPLE_SEND" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00024" name="ACR_PKT_CTRL">
+		<!--
+			Guessing on order of bitfields from these comments:
+				/* AUDIO_PRIORITY | SOURCE */
+				acr_pck_ctrl_reg |= 0x80000100;
+				/* N_MULTIPLE(multiplier) */
+				acr_pck_ctrl_reg |= (multiplier & 7) << 16;
+				/* SEND | CONT */
+				acr_pck_ctrl_reg |= 0x00000003;
+		 -->
+		<bitfield name="CONT" pos="0" type="boolean"/>
+		<bitfield name="SEND" pos="1" type="boolean"/>
+		<bitfield name="SELECT" low="4" high="5" type="hdmi_acr_cts"/>
+		<bitfield name="SOURCE" pos="8" type="boolean"/>
+		<bitfield name="N_MULTIPLIER" low="16" high="18" type="uint"/>
+		<bitfield name="AUDIO_PRIORITY" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0028" name="VBI_PKT_CTRL">
+		<!--
+			Guessing on the order of bits from:
+				/* GC packet enable (every frame) */
+				/* HDMI_VBI_PKT_CTRL[0x0028] */
+				hdmi_msm_rmw32or(0x0028, 3 << 4);
+				/* HDMI_VBI_PKT_CTRL[0x0028] */
+				/* ISRC Send + Continuous */
+				hdmi_msm_rmw32or(0x0028, 3 << 8);
+				/* HDMI_VBI_PKT_CTRL[0x0028] */
+				/* ACP send, s/w source */
+				hdmi_msm_rmw32or(0x0028, 3 << 12);
+		 -->
+		<bitfield name="GC_ENABLE" pos="4" type="boolean"/>
+		<bitfield name="GC_EVERY_FRAME" pos="5" type="boolean"/>
+		<bitfield name="ISRC_SEND" pos="8" type="boolean"/>
+		<bitfield name="ISRC_CONTINUOUS" pos="9" type="boolean"/>
+		<bitfield name="ACP_SEND" pos="12" type="boolean"/>
+		<bitfield name="ACP_SRC_SW" pos="13" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0002c" name="INFOFRAME_CTRL0">
+		<!--
+			Guessing on the order of these flags, from this comment:
+				/* Set these flags */
+				/* AUDIO_INFO_UPDATE | AUDIO_INFO_SOURCE | AUDIO_INFO_CONT
+				 | AUDIO_INFO_SEND */
+				audio_info_ctrl_reg |= 0x000000F0;
+				/* 0x3 for AVI InfFrame enable (every frame) */
+				HDMI_OUTP(0x002C, HDMI_INP(0x002C) | 0x00000003L);
+		 -->
+		<bitfield name="AVI_SEND" pos="0" type="boolean"/>
+		<bitfield name="AVI_CONT" pos="1" type="boolean"/>           <!-- every frame -->
+		<bitfield name="AUDIO_INFO_SEND" pos="4" type="boolean"/>
+		<bitfield name="AUDIO_INFO_CONT" pos="5" type="boolean"/>    <!-- every frame -->
+		<bitfield name="AUDIO_INFO_SOURCE" pos="6" type="boolean"/>
+		<bitfield name="AUDIO_INFO_UPDATE" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00030" name="INFOFRAME_CTRL1">
+		<bitfield name="AVI_INFO_LINE" low="0" high="5" type="uint"/>
+		<bitfield name="AUDIO_INFO_LINE" low="8" high="13" type="uint"/>
+		<bitfield name="MPEG_INFO_LINE" low="16" high="21" type="uint"/>
+		<bitfield name="VENSPEC_INFO_LINE" low="24" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00034" name="GEN_PKT_CTRL">
+		<!--
+			0x0034 GEN_PKT_CTRL
+			  GENERIC0_SEND   0      0 = Disable Generic0 Packet Transmission
+			                         1 = Enable Generic0 Packet Transmission
+			  GENERIC0_CONT   1      0 = Send Generic0 Packet on next frame only
+			                         1 = Send Generic0 Packet on every frame
+			  GENERIC0_UPDATE 2      NUM
+			  GENERIC1_SEND   4      0 = Disable Generic1 Packet Transmission
+			                         1 = Enable Generic1 Packet Transmission
+			  GENERIC1_CONT   5      0 = Send Generic1 Packet on next frame only
+			                         1 = Send Generic1 Packet on every frame
+			  GENERIC0_LINE   21:16  NUM
+			  GENERIC1_LINE   29:24  NUM
+			
+			GENERIC0_LINE | GENERIC0_UPDATE | GENERIC0_CONT | GENERIC0_SEND
+			Setup HDMI TX generic packet control
+			Enable this packet to transmit every frame
+			Enable this packet to transmit every frame
+			Enable HDMI TX engine to transmit Generic packet 0
+			  HDMI_OUTP(0x0034, (1 << 16) | (1 << 2) | BIT(1) | BIT(0));
+		 -->
+		<bitfield name="GENERIC0_SEND" pos="0" type="boolean"/>
+		<bitfield name="GENERIC0_CONT" pos="1" type="boolean"/>
+		<bitfield name="GENERIC0_UPDATE" low="2" high="3" type="uint"/> <!-- ??? -->
+		<bitfield name="GENERIC1_SEND" pos="4" type="boolean"/>
+		<bitfield name="GENERIC1_CONT" pos="5" type="boolean"/>
+		<bitfield name="GENERIC0_LINE" low="16" high="21" type="uint"/>
+		<bitfield name="GENERIC1_LINE" low="24" high="29" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00040" name="GC">
+		<bitfield name="MUTE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00044" name="AUDIO_PKT_CTRL2">
+		<bitfield name="OVERRIDE" pos="0" type="boolean"/>
+		<bitfield name="LAYOUT" pos="1" type="boolean"/> <!-- 1 for >2 channels -->
+	</reg32>
+
+	<!--
+		AVI_INFO appears to be the infoframe in a slightly weird order..
+		starts with PB0 (checksum), and ends with version..
+	-->
+	<reg32 offset="0x0006c" name="AVI_INFO" stride="4" length="4"/>
+
+	<reg32 offset="0x00084" name="GENERIC0_HDR"/>
+	<reg32 offset="0x00088" name="GENERIC0" stride="4" length="7"/>
+
+	<reg32 offset="0x000a4" name="GENERIC1_HDR"/>
+	<reg32 offset="0x000a8" name="GENERIC1" stride="4" length="7"/>
+
+	<!--
+		TODO add a way to show symbolic offsets into array: hdmi_acr_cts-1
+	 -->
+	<array offset="0x00c4" name="ACR" length="3" stride="8" index="hdmi_acr_cts">
+		<reg32 offset="0" name="0">
+			<bitfield name="CTS" low="12" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="4" name="1">
+			<!-- not sure the actual # of bits.. -->
+			<bitfield name="N" low="0" high="31" type="uint"/>
+		</reg32>
+	</array>
+
+	<reg32 offset="0x000e4" name="AUDIO_INFO0">
+		<bitfield name="CHECKSUM" low="0" high="7"/>
+		<bitfield name="CC" low="8" high="10" type="uint"/> <!-- channel count -->
+	</reg32>
+	<reg32 offset="0x000e8" name="AUDIO_INFO1">
+		<bitfield name="CA" low="0" high="7"/>        <!-- Channel Allocation -->
+		<bitfield name="LSV" low="11" high="14"/>     <!-- Level Shift -->
+		<bitfield name="DM_INH" pos="15" type="boolean"/>  <!-- down-mix inhibit flag -->
+	</reg32>
+	<reg32 offset="0x00110" name="HDCP_CTRL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="ENCRYPTION_ENABLE" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00114" name="HDCP_DEBUG_CTRL">
+		<bitfield name="RNG_CIPHER" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00118" name="HDCP_INT_CTRL">
+		<bitfield name="AUTH_SUCCESS_INT" pos="0" type="boolean"/>
+		<bitfield name="AUTH_SUCCESS_ACK" pos="1" type="boolean"/>
+		<bitfield name="AUTH_SUCCESS_MASK" pos="2" type="boolean"/>
+		<bitfield name="AUTH_FAIL_INT" pos="4" type="boolean"/>
+		<bitfield name="AUTH_FAIL_ACK" pos="5" type="boolean"/>
+		<bitfield name="AUTH_FAIL_MASK" pos="6" type="boolean"/>
+		<bitfield name="AUTH_FAIL_INFO_ACK" pos="7" type="boolean"/>
+		<bitfield name="AUTH_XFER_REQ_INT" pos="8" type="boolean"/>
+		<bitfield name="AUTH_XFER_REQ_ACK" pos="9" type="boolean"/>
+		<bitfield name="AUTH_XFER_REQ_MASK" pos="10" type="boolean"/>
+		<bitfield name="AUTH_XFER_DONE_INT" pos="12" type="boolean"/>
+		<bitfield name="AUTH_XFER_DONE_ACK" pos="13" type="boolean"/>
+		<bitfield name="AUTH_XFER_DONE_MASK" pos="14" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0011c" name="HDCP_LINK0_STATUS">
+		<bitfield name="AN_0_READY" pos="8" type="boolean"/>
+		<bitfield name="AN_1_READY" pos="9" type="boolean"/>
+		<bitfield name="RI_MATCHES" pos="12" type="boolean"/>
+		<bitfield name="V_MATCHES" pos="20" type="boolean"/>
+		<bitfield name="KEY_STATE" low="28" high="30" type="hdmi_hdcp_key_state"/>
+	</reg32>
+	<reg32 offset="0x00120" name="HDCP_DDC_CTRL_0">
+		<bitfield name="DISABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00124" name="HDCP_DDC_CTRL_1">
+		<bitfield name="FAILED_ACK" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00128" name="HDCP_DDC_STATUS">
+		<bitfield name="XFER_REQ" pos="4" type="boolean"/>
+		<bitfield name="XFER_DONE" pos="10" type="boolean"/>
+		<bitfield name="ABORTED" pos="12" type="boolean"/>
+		<bitfield name="TIMEOUT" pos="13" type="boolean"/>
+		<bitfield name="NACK0" pos="14" type="boolean"/>
+		<bitfield name="NACK1" pos="15" type="boolean"/>
+		<bitfield name="FAILED" pos="16" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0012c" name="HDCP_ENTROPY_CTRL0"/>
+	<reg32 offset="0x0025c" name="HDCP_ENTROPY_CTRL1"/>
+
+	<reg32 offset="0x00130" name="HDCP_RESET">
+		<bitfield name="LINK0_DEAUTHENTICATE" pos="0" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x00134" name="HDCP_RCVPORT_DATA0"/>
+	<reg32 offset="0x00138" name="HDCP_RCVPORT_DATA1"/>
+	<reg32 offset="0x0013C" name="HDCP_RCVPORT_DATA2_0"/>
+	<reg32 offset="0x00140" name="HDCP_RCVPORT_DATA2_1"/>
+	<reg32 offset="0x00144" name="HDCP_RCVPORT_DATA3"/>
+	<reg32 offset="0x00148" name="HDCP_RCVPORT_DATA4"/>
+	<reg32 offset="0x0014c" name="HDCP_RCVPORT_DATA5"/>
+	<reg32 offset="0x00150" name="HDCP_RCVPORT_DATA6"/>
+	<reg32 offset="0x00154" name="HDCP_RCVPORT_DATA7"/>
+	<reg32 offset="0x00158" name="HDCP_RCVPORT_DATA8"/>
+	<reg32 offset="0x0015c" name="HDCP_RCVPORT_DATA9"/>
+	<reg32 offset="0x00160" name="HDCP_RCVPORT_DATA10"/>
+	<reg32 offset="0x00164" name="HDCP_RCVPORT_DATA11"/>
+	<reg32 offset="0x00168" name="HDCP_RCVPORT_DATA12"/>
+
+	<reg32 offset="0x0016c" name="VENSPEC_INFO0"/>
+	<reg32 offset="0x00170" name="VENSPEC_INFO1"/>
+	<reg32 offset="0x00174" name="VENSPEC_INFO2"/>
+	<reg32 offset="0x00178" name="VENSPEC_INFO3"/>
+	<reg32 offset="0x0017c" name="VENSPEC_INFO4"/>
+	<reg32 offset="0x00180" name="VENSPEC_INFO5"/>
+	<reg32 offset="0x00184" name="VENSPEC_INFO6"/>
+
+	<reg32 offset="0x001d0" name="AUDIO_CFG">
+		<bitfield name="ENGINE_ENABLE" pos="0" type="boolean"/>
+		<bitfield name="FIFO_WATERMARK" low="4" high="7" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00208" name="USEC_REFTIMER"/>
+	<reg32 offset="0x0020c" name="DDC_CTRL">
+		<!--
+			 0x020C HDMI_DDC_CTRL
+			[21:20] TRANSACTION_CNT
+				Number of transactions to be done in current transfer.
+				* 0x0: transaction0 only
+				* 0x1: transaction0, transaction1
+				* 0x2: transaction0, transaction1, transaction2
+				* 0x3: transaction0, transaction1, transaction2, transaction3
+			[3] SW_STATUS_RESET
+				Write 1 to reset HDMI_DDC_SW_STATUS flags, will reset SW_DONE,
+				ABORTED, TIMEOUT, SW_INTERRUPTED, BUFFER_OVERFLOW,
+				STOPPED_ON_NACK, NACK0, NACK1, NACK2, NACK3
+			[2] SEND_RESET Set to 1 to send reset sequence (9 clocks with no
+				data) at start of transfer.  This sequence is sent after GO is
+				written to 1, before the first transaction only.
+			[1] SOFT_RESET Write 1 to reset DDC controller
+			[0] GO WRITE ONLY. Write 1 to start DDC transfer.
+		 -->
+		<bitfield name="GO" pos="0" type="boolean"/>
+		<bitfield name="SOFT_RESET" pos="1" type="boolean"/>
+		<bitfield name="SEND_RESET" pos="2" type="boolean"/>
+		<bitfield name="SW_STATUS_RESET" pos="3" type="boolean"/>
+		<bitfield name="TRANSACTION_CNT" low="20" high="21" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00210" name="DDC_ARBITRATION">
+		<bitfield name="HW_ARBITRATION" pos="4" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00214" name="DDC_INT_CTRL">
+		<!--
+			HDMI_DDC_INT_CTRL[0x0214]
+			   [2] SW_DONE_MK Mask bit for SW_DONE_INT. Set to 1 to enable
+			       interrupt.
+			   [1] SW_DONE_ACK WRITE ONLY. Acknowledge bit for SW_DONE_INT.
+			       Write 1 to clear interrupt.
+			   [0] SW_DONE_INT READ ONLY. SW_DONE interrupt status */
+		 -->
+		<bitfield name="SW_DONE_INT" pos="0" type="boolean"/>
+		<bitfield name="SW_DONE_ACK" pos="1" type="boolean"/>
+		<bitfield name="SW_DONE_MASK" pos="2" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00218" name="DDC_SW_STATUS">
+		<bitfield name="NACK0" pos="12" type="boolean"/>
+		<bitfield name="NACK1" pos="13" type="boolean"/>
+		<bitfield name="NACK2" pos="14" type="boolean"/>
+		<bitfield name="NACK3" pos="15" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0021c" name="DDC_HW_STATUS">
+		<bitfield name="DONE" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00220" name="DDC_SPEED">
+		<!--
+		   0x0220 HDMI_DDC_SPEED
+		   [31:16] PRESCALE prescale = (m * xtal_frequency) /
+			(desired_i2c_speed), where m is multiply
+			factor, default: m = 1
+		   [1:0]   THRESHOLD Select threshold to use to determine whether value
+			sampled on SDA is a 1 or 0. Specified in terms of the ratio
+			between the number of sampled ones and the total number of times
+			SDA is sampled.
+			* 0x0: >0
+			* 0x1: 1/4 of total samples
+			* 0x2: 1/2 of total samples
+			* 0x3: 3/4 of total samples */
+		 -->
+		<bitfield name="THRESHOLD" low="0" high="1" type="uint"/>
+		<bitfield name="PRESCALE" low="16" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00224" name="DDC_SETUP">
+		<!--
+			 * 0x0224 HDMI_DDC_SETUP
+			 * Setting 31:24 bits : Time units to wait before timeout
+			 * when clock is being stalled by external sink device
+		 -->
+		<bitfield name="TIMEOUT" low="24" high="31" type="uint"/>
+	</reg32>
+	<!-- Guessing length is 4, as elsewhere the are references to trans0 thru trans3 -->
+	<array offset="0x00228" name="I2C_TRANSACTION" length="4" stride="4">
+		<reg32 offset="0" name="REG">
+			<!--
+				0x0228 HDMI_DDC_TRANS0
+				[23:16] CNT0 Byte count for first transaction (excluding the first
+					byte, which is usually the address).
+				[13] STOP0 Determines whether a stop bit will be sent after the first
+					transaction
+					* 0: NO STOP
+					* 1: STOP
+				[12] START0 Determines whether a start bit will be sent before the
+					first transaction
+					* 0: NO START
+					* 1: START
+				[8] STOP_ON_NACK0 Determines whether the current transfer will stop
+					if a NACK is received during the first transaction (current
+					transaction always stops).
+					* 0: STOP CURRENT TRANSACTION, GO TO NEXT TRANSACTION
+					* 1: STOP ALL TRANSACTIONS, SEND STOP BIT
+				[0] RW0 Read/write indicator for first transaction - set to 0 for
+					write, 1 for read. This bit only controls HDMI_DDC behaviour -
+					the R/W bit in the transaction is programmed into the DDC buffer
+					as the LSB of the address byte.
+					* 0: WRITE
+					* 1: READ
+			 -->
+			<bitfield name="RW" pos="0" type="hdmi_ddc_read_write"/>
+			<bitfield name="STOP_ON_NACK" pos="8" type="boolean"/>
+			<bitfield name="START" pos="12" type="boolean"/>
+			<bitfield name="STOP" pos="13" type="boolean"/>
+			<bitfield name="CNT" low="16" high="23" type="uint"/>
+		</reg32>
+	</array>
+	<reg32 offset="0x00238" name="DDC_DATA">
+		<!--
+			0x0238 HDMI_DDC_DATA
+			[31] INDEX_WRITE WRITE ONLY. To write index field, set this bit to
+				1 while writing HDMI_DDC_DATA.
+			[23:16] INDEX Use to set index into DDC buffer for next read or
+				current write, or to read index of current read or next write.
+				Writable only when INDEX_WRITE=1.
+			[15:8] DATA Use to fill or read the DDC buffer
+			[0] DATA_RW Select whether buffer access will be a read or write.
+				For writes, address auto-increments on write to HDMI_DDC_DATA.
+				For reads, address autoincrements on reads to HDMI_DDC_DATA.
+				* 0: Write
+				* 1: Read
+		 -->
+		<bitfield name="DATA_RW" pos="0" type="hdmi_ddc_read_write"/>
+		<bitfield name="DATA" low="8" high="15" type="uint"/>
+		<bitfield name="INDEX" low="16" high="23" type="uint"/>
+		<bitfield name="INDEX_WRITE" pos="31" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x0023c" name="HDCP_SHA_CTRL"/>
+	<reg32 offset="0x00240" name="HDCP_SHA_STATUS">
+		<bitfield name="BLOCK_DONE" pos="0" type="boolean"/>
+		<bitfield name="COMP_DONE" pos="4" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00244" name="HDCP_SHA_DATA">
+		<bitfield name="DONE" pos="0" type="boolean"/>
+	</reg32>
+
+	<reg32 offset="0x00250" name="HPD_INT_STATUS">
+		<bitfield name="INT" pos="0" type="boolean"/>  <!-- an irq has occurred -->
+		<bitfield name="CABLE_DETECTED" pos="1" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00254" name="HPD_INT_CTRL">
+		<!-- (this useful comment was removed in df6b645.. git archaeology is fun)
+			HPD_INT_CTRL[0x0254]
+			31:10 Reserved
+			9     RCV_PLUGIN_DET_MASK  receiver plug in interrupt mask.
+			                           When programmed to 1,
+			                           RCV_PLUGIN_DET_INT will toggle
+			                           the interrupt line
+			8:6   Reserved
+			5     RX_INT_EN            Panel RX interrupt enable
+			      0: Disable
+			      1: Enable
+			4     RX_INT_ACK           WRITE ONLY. Panel RX interrupt
+			                           ack
+			3     Reserved
+			2     INT_EN               Panel interrupt control
+			      0: Disable
+			      1: Enable
+			1     INT_POLARITY         Panel interrupt polarity
+			      0: generate interrupt on disconnect
+			      1: generate interrupt on connect
+			0     INT_ACK              WRITE ONLY. Panel interrupt ack
+		 -->
+		<bitfield name="INT_ACK" pos="0" type="boolean"/>
+		<bitfield name="INT_CONNECT" pos="1" type="boolean"/>
+		<bitfield name="INT_EN" pos="2" type="boolean"/>
+		<bitfield name="RX_INT_ACK" pos="4" type="boolean"/>
+		<bitfield name="RX_INT_EN" pos="5" type="boolean"/>
+		<bitfield name="RCV_PLUGIN_DET_MASK" pos="9" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00258" name="HPD_CTRL">
+		<bitfield name="TIMEOUT" low="0" high="12" type="uint"/>
+		<bitfield name="ENABLE" pos="28" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0027c" name="DDC_REF">
+		<!--
+			0x027C HDMI_DDC_REF
+			[16] REFTIMER_ENABLE	Enable the timer
+				* 0: Disable
+				* 1: Enable
+			[15:0] REFTIMER	Value to set the register in order to generate
+				DDC strobe. This register counts on HDCP application clock
+
+			/* Enable reference timer
+			 * 27 micro-seconds */
+			HDMI_OUTP_ND(0x027C, (1 << 16) | (27 << 0));
+		 -->
+		<bitfield name="REFTIMER_ENABLE" pos="16" type="boolean"/>
+		<bitfield name="REFTIMER" low="0" high="15" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00284" name="HDCP_SW_UPPER_AKSV"/>
+	<reg32 offset="0x00288" name="HDCP_SW_LOWER_AKSV"/>
+
+	<reg32 offset="0x0028c" name="CEC_CTRL">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="SEND_TRIGGER" pos="1" type="boolean"/>
+		<bitfield name="FRAME_SIZE" low="4" high="8" type="uint"/>
+		<bitfield name="LINE_OE" pos="9" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00290" name="CEC_WR_DATA">
+		<bitfield name="BROADCAST" pos="0" type="boolean"/>
+		<bitfield name="DATA" low="8" high="15" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00294" name="CEC_RETRANSMIT">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="COUNT" low="1" high="7" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00298" name="CEC_STATUS">
+		<bitfield name="BUSY" pos="0" type="boolean"/>
+		<bitfield name="TX_FRAME_DONE" pos="3" type="boolean"/>
+		<bitfield name="TX_STATUS" low="4" high="7" type="hdmi_cec_tx_status"/>
+	</reg32>
+	<reg32 offset="0x0029c" name="CEC_INT">
+		<bitfield name="TX_DONE" pos="0" type="boolean"/>
+		<bitfield name="TX_DONE_MASK" pos="1" type="boolean"/>
+		<bitfield name="TX_ERROR" pos="2" type="boolean"/>
+		<bitfield name="TX_ERROR_MASK" pos="3" type="boolean"/>
+		<bitfield name="MONITOR" pos="4" type="boolean"/>
+		<bitfield name="MONITOR_MASK" pos="5" type="boolean"/>
+		<bitfield name="RX_DONE" pos="6" type="boolean"/>
+		<bitfield name="RX_DONE_MASK" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x002a0" name="CEC_ADDR"/>
+	<reg32 offset="0x002a4" name="CEC_TIME">
+		<bitfield name="ENABLE" pos="0" type="boolean"/>
+		<bitfield name="SIGNAL_FREE_TIME" low="7" high="15" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002a8" name="CEC_REFTIMER">
+		<bitfield name="REFTIMER" low="0" high="15" type="uint"/>
+		<bitfield name="ENABLE" pos="16" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x002ac" name="CEC_RD_DATA">
+		<bitfield name="DATA" low="0" high="7" type="uint"/>
+		<bitfield name="SIZE" low="8" high="12" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002b0" name="CEC_RD_FILTER"/>
+
+	<reg32 offset="0x002b4" name="ACTIVE_HSYNC">
+		<bitfield name="START" low="0" high="12" type="uint"/>
+		<bitfield name="END" low="16" high="27" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002b8" name="ACTIVE_VSYNC">
+		<bitfield name="START" low="0" high="12" type="uint"/>
+		<bitfield name="END" low="16" high="28" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002bc" name="VSYNC_ACTIVE_F2">
+		<!-- interlaced, frame 2 -->
+		<bitfield name="START" low="0" high="12" type="uint"/>
+		<bitfield name="END" low="16" high="28" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002c0" name="TOTAL">
+		<bitfield name="H_TOTAL" low="0" high="12" type="uint"/>
+		<bitfield name="V_TOTAL" low="16" high="28" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002c4" name="VSYNC_TOTAL_F2">
+		<!-- interlaced, frame 2 -->
+		<bitfield name="V_TOTAL" low="0" high="12" type="uint"/>
+	</reg32>
+	<reg32 offset="0x002c8" name="FRAME_CTRL">
+		<bitfield name="RGB_MUX_SEL_BGR" pos="12" type="boolean"/>
+		<bitfield name="VSYNC_LOW" pos="28" type="boolean"/>
+		<bitfield name="HSYNC_LOW" pos="29" type="boolean"/>
+		<bitfield name="INTERLACED_EN" pos="31" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x002cc" name="AUD_INT">
+		<!--
+			HDMI_AUD_INT[0x02CC]
+			[3] AUD_SAM_DROP_MASK [R/W]
+			[2] AUD_SAM_DROP_ACK [W], AUD_SAM_DROP_INT [R]
+			[1] AUD_FIFO_URUN_MASK [R/W]
+			[0] AUD_FIFO_URUN_ACK [W], AUD_FIFO_URUN_INT [R]
+		 -->
+		<bitfield name="AUD_FIFO_URUN_INT" pos="0" type="boolean"/>  <!-- write to ack irq -->
+		<bitfield name="AUD_FIFO_URAN_MASK" pos="1" type="boolean"/> <!-- r/w, enables irq -->
+		<bitfield name="AUD_SAM_DROP_INT" pos="2" type="boolean"/>   <!-- write to ack irq -->
+		<bitfield name="AUD_SAM_DROP_MASK" pos="3" type="boolean"/>  <!-- r/w, enables irq -->
+	</reg32>
+	<reg32 offset="0x002d4" name="PHY_CTRL">
+		<!--
+			in hdmi_phy_reset() it appears to be toggling SW_RESET/
+			SW_RESET_PLL based on the value of the bit above, so
+			I'm guessing the bit above is a polarit bit
+		 -->
+		<bitfield name="SW_RESET_PLL" pos="0" type="boolean"/>
+		<bitfield name="SW_RESET_PLL_LOW" pos="1" type="boolean"/>
+		<bitfield name="SW_RESET" pos="2" type="boolean"/>
+		<bitfield name="SW_RESET_LOW" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x002dc" name="CEC_WR_RANGE"/>
+	<reg32 offset="0x002e0" name="CEC_RD_RANGE"/>
+	<reg32 offset="0x002e4" name="VERSION"/>
+	<reg32 offset="0x00360" name="CEC_COMPL_CTL"/>
+	<reg32 offset="0x00364" name="CEC_RD_START_RANGE"/>
+	<reg32 offset="0x00368" name="CEC_RD_TOTAL_RANGE"/>
+	<reg32 offset="0x0036c" name="CEC_RD_ERR_RESP_LO"/>
+	<reg32 offset="0x00370" name="CEC_WR_CHECK_CONFIG"/>
+
+</domain>
+
+<domain name="HDMI_8x60" width="32">
+	<reg32 offset="0x00000" name="PHY_REG0">
+		<bitfield name="DESER_DEL_CTRL" low="2" high="4" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00004" name="PHY_REG1">
+		<bitfield name="DTEST_MUX_SEL" low="4" high="7" type="uint"/>
+		<bitfield name="OUTVOL_SWING_CTRL" low="0" high="3" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00008" name="PHY_REG2">
+		<bitfield name="PD_DESER" pos="0" type="boolean"/>
+		<bitfield name="PD_DRIVE_1" pos="1" type="boolean"/>
+		<bitfield name="PD_DRIVE_2" pos="2" type="boolean"/>
+		<bitfield name="PD_DRIVE_3" pos="3" type="boolean"/>
+		<bitfield name="PD_DRIVE_4" pos="4" type="boolean"/>
+		<bitfield name="PD_PLL" pos="5" type="boolean"/>
+		<bitfield name="PD_PWRGEN" pos="6" type="boolean"/>
+		<bitfield name="RCV_SENSE_EN" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0000c" name="PHY_REG3">
+		<bitfield name="PLL_ENABLE" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00010" name="PHY_REG4"/>
+	<reg32 offset="0x00014" name="PHY_REG5"/>
+	<reg32 offset="0x00018" name="PHY_REG6"/>
+	<reg32 offset="0x0001c" name="PHY_REG7"/>
+	<reg32 offset="0x00020" name="PHY_REG8"/>
+	<reg32 offset="0x00024" name="PHY_REG9"/>
+	<reg32 offset="0x00028" name="PHY_REG10"/>
+	<reg32 offset="0x0002c" name="PHY_REG11"/>
+	<reg32 offset="0x00030" name="PHY_REG12">
+		<bitfield name="RETIMING_EN" pos="0" type="boolean"/>
+		<bitfield name="PLL_LOCK_DETECT_EN" pos="1" type="boolean"/>
+		<bitfield name="FORCE_LOCK" pos="4" type="boolean"/>
+	</reg32>
+</domain>
+
+<domain name="HDMI_8960" width="32">
+	<!--
+		some of the bitfields may be same as 8x60.. but no helpful comments
+		in msm_dss_io_8960.c
+	 -->
+	<reg32 offset="0x00000" name="PHY_REG0"/>
+	<reg32 offset="0x00004" name="PHY_REG1"/>
+	<reg32 offset="0x00008" name="PHY_REG2"/>
+	<reg32 offset="0x0000c" name="PHY_REG3"/>
+	<reg32 offset="0x00010" name="PHY_REG4"/>
+	<reg32 offset="0x00014" name="PHY_REG5"/>
+	<reg32 offset="0x00018" name="PHY_REG6"/>
+	<reg32 offset="0x0001c" name="PHY_REG7"/>
+	<reg32 offset="0x00020" name="PHY_REG8"/>
+	<reg32 offset="0x00024" name="PHY_REG9"/>
+	<reg32 offset="0x00028" name="PHY_REG10"/>
+	<reg32 offset="0x0002c" name="PHY_REG11"/>
+	<reg32 offset="0x00030" name="PHY_REG12">
+		<bitfield name="SW_RESET" pos="5" type="boolean"/>
+		<bitfield name="PWRDN_B" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00034" name="PHY_REG_BIST_CFG"/>
+	<reg32 offset="0x00038" name="PHY_DEBUG_BUS_SEL"/>
+	<reg32 offset="0x0003c" name="PHY_REG_MISC0"/>
+	<reg32 offset="0x00040" name="PHY_REG13"/>
+	<reg32 offset="0x00044" name="PHY_REG14"/>
+	<reg32 offset="0x00048" name="PHY_REG15"/>
+</domain>
+
+<domain name="HDMI_8960_PHY_PLL" width="32">
+	<reg32 offset="0x00000" name="REFCLK_CFG"/>
+	<reg32 offset="0x00004" name="CHRG_PUMP_CFG"/>
+	<reg32 offset="0x00008" name="LOOP_FLT_CFG0"/>
+	<reg32 offset="0x0000c" name="LOOP_FLT_CFG1"/>
+	<reg32 offset="0x00010" name="IDAC_ADJ_CFG"/>
+	<reg32 offset="0x00014" name="I_VI_KVCO_CFG"/>
+	<reg32 offset="0x00018" name="PWRDN_B">
+		<bitfield name="PD_PLL" pos="1" type="boolean"/>
+		<bitfield name="PLL_PWRDN_B" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0001c" name="SDM_CFG0"/>
+	<reg32 offset="0x00020" name="SDM_CFG1"/>
+	<reg32 offset="0x00024" name="SDM_CFG2"/>
+	<reg32 offset="0x00028" name="SDM_CFG3"/>
+	<reg32 offset="0x0002c" name="SDM_CFG4"/>
+	<reg32 offset="0x00030" name="SSC_CFG0"/>
+	<reg32 offset="0x00034" name="SSC_CFG1"/>
+	<reg32 offset="0x00038" name="SSC_CFG2"/>
+	<reg32 offset="0x0003c" name="SSC_CFG3"/>
+	<reg32 offset="0x00040" name="LOCKDET_CFG0"/>
+	<reg32 offset="0x00044" name="LOCKDET_CFG1"/>
+	<reg32 offset="0x00048" name="LOCKDET_CFG2"/>
+	<reg32 offset="0x0004c" name="VCOCAL_CFG0"/>
+	<reg32 offset="0x00050" name="VCOCAL_CFG1"/>
+	<reg32 offset="0x00054" name="VCOCAL_CFG2"/>
+	<reg32 offset="0x00058" name="VCOCAL_CFG3"/>
+	<reg32 offset="0x0005c" name="VCOCAL_CFG4"/>
+	<reg32 offset="0x00060" name="VCOCAL_CFG5"/>
+	<reg32 offset="0x00064" name="VCOCAL_CFG6"/>
+	<reg32 offset="0x00068" name="VCOCAL_CFG7"/>
+	<reg32 offset="0x0006c" name="DEBUG_SEL"/>
+	<reg32 offset="0x00070" name="MISC0"/>
+	<reg32 offset="0x00074" name="MISC1"/>
+	<reg32 offset="0x00078" name="MISC2"/>
+	<reg32 offset="0x0007c" name="MISC3"/>
+	<reg32 offset="0x00080" name="MISC4"/>
+	<reg32 offset="0x00084" name="MISC5"/>
+	<reg32 offset="0x00088" name="MISC6"/>
+	<reg32 offset="0x0008c" name="DEBUG_BUS0"/>
+	<reg32 offset="0x00090" name="DEBUG_BUS1"/>
+	<reg32 offset="0x00094" name="DEBUG_BUS2"/>
+	<reg32 offset="0x00098" name="STATUS0">
+		<bitfield name="PLL_LOCK" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0009c" name="STATUS1"/>
+</domain>
+
+<domain name="HDMI_8x74" width="32">
+	<!--
+		seems to be all mdp5+ have same?
+	 -->
+	<reg32 offset="0x00000" name="ANA_CFG0"/>
+	<reg32 offset="0x00004" name="ANA_CFG1"/>
+	<reg32 offset="0x00008" name="ANA_CFG2"/>
+	<reg32 offset="0x0000c" name="ANA_CFG3"/>
+	<reg32 offset="0x00010" name="PD_CTRL0"/>
+	<reg32 offset="0x00014" name="PD_CTRL1"/>
+	<reg32 offset="0x00018" name="GLB_CFG"/>
+	<reg32 offset="0x0001c" name="DCC_CFG0"/>
+	<reg32 offset="0x00020" name="DCC_CFG1"/>
+	<reg32 offset="0x00024" name="TXCAL_CFG0"/>
+	<reg32 offset="0x00028" name="TXCAL_CFG1"/>
+	<reg32 offset="0x0002c" name="TXCAL_CFG2"/>
+	<reg32 offset="0x00030" name="TXCAL_CFG3"/>
+	<reg32 offset="0x00034" name="BIST_CFG0"/>
+	<reg32 offset="0x0003c" name="BIST_PATN0"/>
+	<reg32 offset="0x00040" name="BIST_PATN1"/>
+	<reg32 offset="0x00044" name="BIST_PATN2"/>
+	<reg32 offset="0x00048" name="BIST_PATN3"/>
+	<reg32 offset="0x0005c" name="STATUS"/>
+</domain>
+
+<domain name="HDMI_28nm_PHY_PLL" width="32">
+	<reg32 offset="0x00000" name="REFCLK_CFG"/>
+	<reg32 offset="0x00004" name="POSTDIV1_CFG"/>
+	<reg32 offset="0x00008" name="CHGPUMP_CFG"/>
+	<reg32 offset="0x0000C" name="VCOLPF_CFG"/>
+	<reg32 offset="0x00010" name="VREG_CFG"/>
+	<reg32 offset="0x00014" name="PWRGEN_CFG"/>
+	<reg32 offset="0x00018" name="DMUX_CFG"/>
+	<reg32 offset="0x0001C" name="AMUX_CFG"/>
+	<reg32 offset="0x00020" name="GLB_CFG">
+		<bitfield name="PLL_PWRDN_B" pos="0" type="boolean"/>
+		<bitfield name="PLL_LDO_PWRDN_B" pos="1" type="boolean"/>
+		<bitfield name="PLL_PWRGEN_PWRDN_B" pos="2" type="boolean"/>
+		<bitfield name="PLL_ENABLE" pos="3" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x00024" name="POSTDIV2_CFG"/>
+	<reg32 offset="0x00028" name="POSTDIV3_CFG"/>
+	<reg32 offset="0x0002C" name="LPFR_CFG"/>
+	<reg32 offset="0x00030" name="LPFC1_CFG"/>
+	<reg32 offset="0x00034" name="LPFC2_CFG"/>
+	<reg32 offset="0x00038" name="SDM_CFG0"/>
+	<reg32 offset="0x0003C" name="SDM_CFG1"/>
+	<reg32 offset="0x00040" name="SDM_CFG2"/>
+	<reg32 offset="0x00044" name="SDM_CFG3"/>
+	<reg32 offset="0x00048" name="SDM_CFG4"/>
+	<reg32 offset="0x0004C" name="SSC_CFG0"/>
+	<reg32 offset="0x00050" name="SSC_CFG1"/>
+	<reg32 offset="0x00054" name="SSC_CFG2"/>
+	<reg32 offset="0x00058" name="SSC_CFG3"/>
+	<reg32 offset="0x0005C" name="LKDET_CFG0"/>
+	<reg32 offset="0x00060" name="LKDET_CFG1"/>
+	<reg32 offset="0x00064" name="LKDET_CFG2"/>
+	<reg32 offset="0x00068" name="TEST_CFG">
+		<bitfield name="PLL_SW_RESET" pos="0" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0006C" name="CAL_CFG0"/>
+	<reg32 offset="0x00070" name="CAL_CFG1"/>
+	<reg32 offset="0x00074" name="CAL_CFG2"/>
+	<reg32 offset="0x00078" name="CAL_CFG3"/>
+	<reg32 offset="0x0007C" name="CAL_CFG4"/>
+	<reg32 offset="0x00080" name="CAL_CFG5"/>
+	<reg32 offset="0x00084" name="CAL_CFG6"/>
+	<reg32 offset="0x00088" name="CAL_CFG7"/>
+	<reg32 offset="0x0008C" name="CAL_CFG8"/>
+	<reg32 offset="0x00090" name="CAL_CFG9"/>
+	<reg32 offset="0x00094" name="CAL_CFG10"/>
+	<reg32 offset="0x00098" name="CAL_CFG11"/>
+	<reg32 offset="0x0009C" name="EFUSE_CFG"/>
+	<reg32 offset="0x000A0" name="DEBUG_BUS_SEL"/>
+	<reg32 offset="0x000C0" name="STATUS"/>
+</domain>
+
+<domain name="HDMI_8996_PHY" width="32">
+	<reg32 offset="0x00000" name="CFG"/>
+	<reg32 offset="0x00004" name="PD_CTL"/>
+	<reg32 offset="0x00008" name="MODE"/>
+	<reg32 offset="0x0000C" name="MISR_CLEAR"/>
+	<reg32 offset="0x00010" name="TX0_TX1_BIST_CFG0"/>
+	<reg32 offset="0x00014" name="TX0_TX1_BIST_CFG1"/>
+	<reg32 offset="0x00018" name="TX0_TX1_PRBS_SEED_BYTE0"/>
+	<reg32 offset="0x0001C" name="TX0_TX1_PRBS_SEED_BYTE1"/>
+	<reg32 offset="0x00020" name="TX0_TX1_BIST_PATTERN0"/>
+	<reg32 offset="0x00024" name="TX0_TX1_BIST_PATTERN1"/>
+	<reg32 offset="0x00028" name="TX2_TX3_BIST_CFG0"/>
+	<reg32 offset="0x0002C" name="TX2_TX3_BIST_CFG1"/>
+	<reg32 offset="0x00030" name="TX2_TX3_PRBS_SEED_BYTE0"/>
+	<reg32 offset="0x00034" name="TX2_TX3_PRBS_SEED_BYTE1"/>
+	<reg32 offset="0x00038" name="TX2_TX3_BIST_PATTERN0"/>
+	<reg32 offset="0x0003C" name="TX2_TX3_BIST_PATTERN1"/>
+	<reg32 offset="0x00040" name="DEBUG_BUS_SEL"/>
+	<reg32 offset="0x00044" name="TXCAL_CFG0"/>
+	<reg32 offset="0x00048" name="TXCAL_CFG1"/>
+	<reg32 offset="0x0004C" name="TX0_TX1_LANE_CTL"/>
+	<reg32 offset="0x00050" name="TX2_TX3_LANE_CTL"/>
+	<reg32 offset="0x00054" name="LANE_BIST_CONFIG"/>
+	<reg32 offset="0x00058" name="CLOCK"/>
+	<reg32 offset="0x0005C" name="MISC1"/>
+	<reg32 offset="0x00060" name="MISC2"/>
+	<reg32 offset="0x00064" name="TX0_TX1_BIST_STATUS0"/>
+	<reg32 offset="0x00068" name="TX0_TX1_BIST_STATUS1"/>
+	<reg32 offset="0x0006C" name="TX0_TX1_BIST_STATUS2"/>
+	<reg32 offset="0x00070" name="TX2_TX3_BIST_STATUS0"/>
+	<reg32 offset="0x00074" name="TX2_TX3_BIST_STATUS1"/>
+	<reg32 offset="0x00078" name="TX2_TX3_BIST_STATUS2"/>
+	<reg32 offset="0x0007C" name="PRE_MISR_STATUS0"/>
+	<reg32 offset="0x00080" name="PRE_MISR_STATUS1"/>
+	<reg32 offset="0x00084" name="PRE_MISR_STATUS2"/>
+	<reg32 offset="0x00088" name="PRE_MISR_STATUS3"/>
+	<reg32 offset="0x0008C" name="POST_MISR_STATUS0"/>
+	<reg32 offset="0x00090" name="POST_MISR_STATUS1"/>
+	<reg32 offset="0x00094" name="POST_MISR_STATUS2"/>
+	<reg32 offset="0x00098" name="POST_MISR_STATUS3"/>
+	<reg32 offset="0x0009C" name="STATUS"/>
+	<reg32 offset="0x000A0" name="MISC3_STATUS"/>
+	<reg32 offset="0x000A4" name="MISC4_STATUS"/>
+	<reg32 offset="0x000A8" name="DEBUG_BUS0"/>
+	<reg32 offset="0x000AC" name="DEBUG_BUS1"/>
+	<reg32 offset="0x000B0" name="DEBUG_BUS2"/>
+	<reg32 offset="0x000B4" name="DEBUG_BUS3"/>
+	<reg32 offset="0x000B8" name="PHY_REVISION_ID0"/>
+	<reg32 offset="0x000BC" name="PHY_REVISION_ID1"/>
+	<reg32 offset="0x000C0" name="PHY_REVISION_ID2"/>
+	<reg32 offset="0x000C4" name="PHY_REVISION_ID3"/>
+</domain>
+
+<domain name="HDMI_PHY_QSERDES_COM" width="32">
+	<reg32 offset="0x00000" name="ATB_SEL1"/>
+	<reg32 offset="0x00004" name="ATB_SEL2"/>
+	<reg32 offset="0x00008" name="FREQ_UPDATE"/>
+	<reg32 offset="0x0000C" name="BG_TIMER"/>
+	<reg32 offset="0x00010" name="SSC_EN_CENTER"/>
+	<reg32 offset="0x00014" name="SSC_ADJ_PER1"/>
+	<reg32 offset="0x00018" name="SSC_ADJ_PER2"/>
+	<reg32 offset="0x0001C" name="SSC_PER1"/>
+	<reg32 offset="0x00020" name="SSC_PER2"/>
+	<reg32 offset="0x00024" name="SSC_STEP_SIZE1"/>
+	<reg32 offset="0x00028" name="SSC_STEP_SIZE2"/>
+	<reg32 offset="0x0002C" name="POST_DIV"/>
+	<reg32 offset="0x00030" name="POST_DIV_MUX"/>
+	<reg32 offset="0x00034" name="BIAS_EN_CLKBUFLR_EN"/>
+	<reg32 offset="0x00038" name="CLK_ENABLE1"/>
+	<reg32 offset="0x0003C" name="SYS_CLK_CTRL"/>
+	<reg32 offset="0x00040" name="SYSCLK_BUF_ENABLE"/>
+	<reg32 offset="0x00044" name="PLL_EN"/>
+	<reg32 offset="0x00048" name="PLL_IVCO"/>
+	<reg32 offset="0x0004C" name="LOCK_CMP1_MODE0"/>
+	<reg32 offset="0x00050" name="LOCK_CMP2_MODE0"/>
+	<reg32 offset="0x00054" name="LOCK_CMP3_MODE0"/>
+	<reg32 offset="0x00058" name="LOCK_CMP1_MODE1"/>
+	<reg32 offset="0x0005C" name="LOCK_CMP2_MODE1"/>
+	<reg32 offset="0x00060" name="LOCK_CMP3_MODE1"/>
+	<reg32 offset="0x00064" name="LOCK_CMP1_MODE2"/>
+	<reg32 offset="0x00064" name="CMN_RSVD0"/>
+	<reg32 offset="0x00068" name="LOCK_CMP2_MODE2"/>
+	<reg32 offset="0x00068" name="EP_CLOCK_DETECT_CTRL"/>
+	<reg32 offset="0x0006C" name="LOCK_CMP3_MODE2"/>
+	<reg32 offset="0x0006C" name="SYSCLK_DET_COMP_STATUS"/>
+	<reg32 offset="0x00070" name="BG_TRIM"/>
+	<reg32 offset="0x00074" name="CLK_EP_DIV"/>
+	<reg32 offset="0x00078" name="CP_CTRL_MODE0"/>
+	<reg32 offset="0x0007C" name="CP_CTRL_MODE1"/>
+	<reg32 offset="0x00080" name="CP_CTRL_MODE2"/>
+	<reg32 offset="0x00080" name="CMN_RSVD1"/>
+	<reg32 offset="0x00084" name="PLL_RCTRL_MODE0"/>
+	<reg32 offset="0x00088" name="PLL_RCTRL_MODE1"/>
+	<reg32 offset="0x0008C" name="PLL_RCTRL_MODE2"/>
+	<reg32 offset="0x0008C" name="CMN_RSVD2"/>
+	<reg32 offset="0x00090" name="PLL_CCTRL_MODE0"/>
+	<reg32 offset="0x00094" name="PLL_CCTRL_MODE1"/>
+	<reg32 offset="0x00098" name="PLL_CCTRL_MODE2"/>
+	<reg32 offset="0x00098" name="CMN_RSVD3"/>
+	<reg32 offset="0x0009C" name="PLL_CNTRL"/>
+	<reg32 offset="0x000A0" name="PHASE_SEL_CTRL"/>
+	<reg32 offset="0x000A4" name="PHASE_SEL_DC"/>
+	<reg32 offset="0x000A8" name="CORE_CLK_IN_SYNC_SEL"/>
+	<reg32 offset="0x000A8" name="BIAS_EN_CTRL_BY_PSM"/>
+	<reg32 offset="0x000AC" name="SYSCLK_EN_SEL"/>
+	<reg32 offset="0x000B0" name="CML_SYSCLK_SEL"/>
+	<reg32 offset="0x000B4" name="RESETSM_CNTRL"/>
+	<reg32 offset="0x000B8" name="RESETSM_CNTRL2"/>
+	<reg32 offset="0x000BC" name="RESTRIM_CTRL"/>
+	<reg32 offset="0x000C0" name="RESTRIM_CTRL2"/>
+	<reg32 offset="0x000C4" name="RESCODE_DIV_NUM"/>
+	<reg32 offset="0x000C8" name="LOCK_CMP_EN"/>
+	<reg32 offset="0x000CC" name="LOCK_CMP_CFG"/>
+	<reg32 offset="0x000D0" name="DEC_START_MODE0"/>
+	<reg32 offset="0x000D4" name="DEC_START_MODE1"/>
+	<reg32 offset="0x000D8" name="DEC_START_MODE2"/>
+	<reg32 offset="0x000D8" name="VCOCAL_DEADMAN_CTRL"/>
+	<reg32 offset="0x000DC" name="DIV_FRAC_START1_MODE0"/>
+	<reg32 offset="0x000E0" name="DIV_FRAC_START2_MODE0"/>
+	<reg32 offset="0x000E4" name="DIV_FRAC_START3_MODE0"/>
+	<reg32 offset="0x000E8" name="DIV_FRAC_START1_MODE1"/>
+	<reg32 offset="0x000EC" name="DIV_FRAC_START2_MODE1"/>
+	<reg32 offset="0x000F0" name="DIV_FRAC_START3_MODE1"/>
+	<reg32 offset="0x000F4" name="DIV_FRAC_START1_MODE2"/>
+	<reg32 offset="0x000F4" name="VCO_TUNE_MINVAL1"/>
+	<reg32 offset="0x000F8" name="DIV_FRAC_START2_MODE2"/>
+	<reg32 offset="0x000F8" name="VCO_TUNE_MINVAL2"/>
+	<reg32 offset="0x000FC" name="DIV_FRAC_START3_MODE2"/>
+	<reg32 offset="0x000FC" name="CMN_RSVD4"/>
+	<reg32 offset="0x00100" name="INTEGLOOP_INITVAL"/>
+	<reg32 offset="0x00104" name="INTEGLOOP_EN"/>
+	<reg32 offset="0x00108" name="INTEGLOOP_GAIN0_MODE0"/>
+	<reg32 offset="0x0010C" name="INTEGLOOP_GAIN1_MODE0"/>
+	<reg32 offset="0x00110" name="INTEGLOOP_GAIN0_MODE1"/>
+	<reg32 offset="0x00114" name="INTEGLOOP_GAIN1_MODE1"/>
+	<reg32 offset="0x00118" name="INTEGLOOP_GAIN0_MODE2"/>
+	<reg32 offset="0x00118" name="VCO_TUNE_MAXVAL1"/>
+	<reg32 offset="0x0011C" name="INTEGLOOP_GAIN1_MODE2"/>
+	<reg32 offset="0x0011C" name="VCO_TUNE_MAXVAL2"/>
+	<reg32 offset="0x00120" name="RES_TRIM_CONTROL2"/>
+	<reg32 offset="0x00124" name="VCO_TUNE_CTRL"/>
+	<reg32 offset="0x00128" name="VCO_TUNE_MAP"/>
+	<reg32 offset="0x0012C" name="VCO_TUNE1_MODE0"/>
+	<reg32 offset="0x00130" name="VCO_TUNE2_MODE0"/>
+	<reg32 offset="0x00134" name="VCO_TUNE1_MODE1"/>
+	<reg32 offset="0x00138" name="VCO_TUNE2_MODE1"/>
+	<reg32 offset="0x0013C" name="VCO_TUNE1_MODE2"/>
+	<reg32 offset="0x0013C" name="VCO_TUNE_INITVAL1"/>
+	<reg32 offset="0x00140" name="VCO_TUNE2_MODE2"/>
+	<reg32 offset="0x00140" name="VCO_TUNE_INITVAL2"/>
+	<reg32 offset="0x00144" name="VCO_TUNE_TIMER1"/>
+	<reg32 offset="0x00148" name="VCO_TUNE_TIMER2"/>
+	<reg32 offset="0x0014C" name="SAR"/>
+	<reg32 offset="0x00150" name="SAR_CLK"/>
+	<reg32 offset="0x00154" name="SAR_CODE_OUT_STATUS"/>
+	<reg32 offset="0x00158" name="SAR_CODE_READY_STATUS"/>
+	<reg32 offset="0x0015C" name="CMN_STATUS"/>
+	<reg32 offset="0x00160" name="RESET_SM_STATUS"/>
+	<reg32 offset="0x00164" name="RESTRIM_CODE_STATUS"/>
+	<reg32 offset="0x00168" name="PLLCAL_CODE1_STATUS"/>
+	<reg32 offset="0x0016C" name="PLLCAL_CODE2_STATUS"/>
+	<reg32 offset="0x00170" name="BG_CTRL"/>
+	<reg32 offset="0x00174" name="CLK_SELECT"/>
+	<reg32 offset="0x00178" name="HSCLK_SEL"/>
+	<reg32 offset="0x0017C" name="INTEGLOOP_BINCODE_STATUS"/>
+	<reg32 offset="0x00180" name="PLL_ANALOG"/>
+	<reg32 offset="0x00184" name="CORECLK_DIV"/>
+	<reg32 offset="0x00188" name="SW_RESET"/>
+	<reg32 offset="0x0018C" name="CORE_CLK_EN"/>
+	<reg32 offset="0x00190" name="C_READY_STATUS"/>
+	<reg32 offset="0x00194" name="CMN_CONFIG"/>
+	<reg32 offset="0x00198" name="CMN_RATE_OVERRIDE"/>
+	<reg32 offset="0x0019C" name="SVS_MODE_CLK_SEL"/>
+	<reg32 offset="0x001A0" name="DEBUG_BUS0"/>
+	<reg32 offset="0x001A4" name="DEBUG_BUS1"/>
+	<reg32 offset="0x001A8" name="DEBUG_BUS2"/>
+	<reg32 offset="0x001AC" name="DEBUG_BUS3"/>
+	<reg32 offset="0x001B0" name="DEBUG_BUS_SEL"/>
+	<reg32 offset="0x001B4" name="CMN_MISC1"/>
+	<reg32 offset="0x001B8" name="CMN_MISC2"/>
+	<reg32 offset="0x001BC" name="CORECLK_DIV_MODE1"/>
+	<reg32 offset="0x001C0" name="CORECLK_DIV_MODE2"/>
+	<reg32 offset="0x001C4" name="CMN_RSVD5"/>
+</domain>
+
+
+<domain name="HDMI_PHY_QSERDES_TX_LX" width="32">
+		<reg32 offset="0x00000" name="BIST_MODE_LANENO"/>
+		<reg32 offset="0x00004" name="BIST_INVERT"/>
+		<reg32 offset="0x00008" name="CLKBUF_ENABLE"/>
+		<reg32 offset="0x0000C" name="CMN_CONTROL_ONE"/>
+		<reg32 offset="0x00010" name="CMN_CONTROL_TWO"/>
+		<reg32 offset="0x00014" name="CMN_CONTROL_THREE"/>
+		<reg32 offset="0x00018" name="TX_EMP_POST1_LVL"/>
+		<reg32 offset="0x0001C" name="TX_POST2_EMPH"/>
+		<reg32 offset="0x00020" name="TX_BOOST_LVL_UP_DN"/>
+		<reg32 offset="0x00024" name="HP_PD_ENABLES"/>
+		<reg32 offset="0x00028" name="TX_IDLE_LVL_LARGE_AMP"/>
+		<reg32 offset="0x0002C" name="TX_DRV_LVL"/>
+		<reg32 offset="0x00030" name="TX_DRV_LVL_OFFSET"/>
+		<reg32 offset="0x00034" name="RESET_TSYNC_EN"/>
+		<reg32 offset="0x00038" name="PRE_STALL_LDO_BOOST_EN"/>
+		<reg32 offset="0x0003C" name="TX_BAND"/>
+		<reg32 offset="0x00040" name="SLEW_CNTL"/>
+		<reg32 offset="0x00044" name="INTERFACE_SELECT"/>
+		<reg32 offset="0x00048" name="LPB_EN"/>
+		<reg32 offset="0x0004C" name="RES_CODE_LANE_TX"/>
+		<reg32 offset="0x00050" name="RES_CODE_LANE_RX"/>
+		<reg32 offset="0x00054" name="RES_CODE_LANE_OFFSET"/>
+		<reg32 offset="0x00058" name="PERL_LENGTH1"/>
+		<reg32 offset="0x0005C" name="PERL_LENGTH2"/>
+		<reg32 offset="0x00060" name="SERDES_BYP_EN_OUT"/>
+		<reg32 offset="0x00064" name="DEBUG_BUS_SEL"/>
+		<reg32 offset="0x00068" name="HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN"/>
+		<reg32 offset="0x0006C" name="TX_POL_INV"/>
+		<reg32 offset="0x00070" name="PARRATE_REC_DETECT_IDLE_EN"/>
+		<reg32 offset="0x00074" name="BIST_PATTERN1"/>
+		<reg32 offset="0x00078" name="BIST_PATTERN2"/>
+		<reg32 offset="0x0007C" name="BIST_PATTERN3"/>
+		<reg32 offset="0x00080" name="BIST_PATTERN4"/>
+		<reg32 offset="0x00084" name="BIST_PATTERN5"/>
+		<reg32 offset="0x00088" name="BIST_PATTERN6"/>
+		<reg32 offset="0x0008C" name="BIST_PATTERN7"/>
+		<reg32 offset="0x00090" name="BIST_PATTERN8"/>
+		<reg32 offset="0x00094" name="LANE_MODE"/>
+		<reg32 offset="0x00098" name="IDAC_CAL_LANE_MODE"/>
+		<reg32 offset="0x0009C" name="IDAC_CAL_LANE_MODE_CONFIGURATION"/>
+		<reg32 offset="0x000A0" name="ATB_SEL1"/>
+		<reg32 offset="0x000A4" name="ATB_SEL2"/>
+		<reg32 offset="0x000A8" name="RCV_DETECT_LVL"/>
+		<reg32 offset="0x000AC" name="RCV_DETECT_LVL_2"/>
+		<reg32 offset="0x000B0" name="PRBS_SEED1"/>
+		<reg32 offset="0x000B4" name="PRBS_SEED2"/>
+		<reg32 offset="0x000B8" name="PRBS_SEED3"/>
+		<reg32 offset="0x000BC" name="PRBS_SEED4"/>
+		<reg32 offset="0x000C0" name="RESET_GEN"/>
+		<reg32 offset="0x000C4" name="RESET_GEN_MUXES"/>
+		<reg32 offset="0x000C8" name="TRAN_DRVR_EMP_EN"/>
+		<reg32 offset="0x000CC" name="TX_INTERFACE_MODE"/>
+		<reg32 offset="0x000D0" name="PWM_CTRL"/>
+		<reg32 offset="0x000D4" name="PWM_ENCODED_OR_DATA"/>
+		<reg32 offset="0x000D8" name="PWM_GEAR_1_DIVIDER_BAND2"/>
+		<reg32 offset="0x000DC" name="PWM_GEAR_2_DIVIDER_BAND2"/>
+		<reg32 offset="0x000E0" name="PWM_GEAR_3_DIVIDER_BAND2"/>
+		<reg32 offset="0x000E4" name="PWM_GEAR_4_DIVIDER_BAND2"/>
+		<reg32 offset="0x000E8" name="PWM_GEAR_1_DIVIDER_BAND0_1"/>
+		<reg32 offset="0x000EC" name="PWM_GEAR_2_DIVIDER_BAND0_1"/>
+		<reg32 offset="0x000F0" name="PWM_GEAR_3_DIVIDER_BAND0_1"/>
+		<reg32 offset="0x000F4" name="PWM_GEAR_4_DIVIDER_BAND0_1"/>
+		<reg32 offset="0x000F8" name="VMODE_CTRL1"/>
+		<reg32 offset="0x000FC" name="VMODE_CTRL2"/>
+		<reg32 offset="0x00100" name="TX_ALOG_INTF_OBSV_CNTL"/>
+		<reg32 offset="0x00104" name="BIST_STATUS"/>
+		<reg32 offset="0x00108" name="BIST_ERROR_COUNT1"/>
+		<reg32 offset="0x0010C" name="BIST_ERROR_COUNT2"/>
+		<reg32 offset="0x00110" name="TX_ALOG_INTF_OBSV"/>
+</domain>
+
+<domain name="HDMI_8998_PHY" width="32">
+	<reg32 offset="0x00000" name="CFG"/>
+	<reg32 offset="0x00004" name="PD_CTL"/>
+	<reg32 offset="0x00010" name="MODE"/>
+	<reg32 offset="0x0005C" name="CLOCK"/>
+	<reg32 offset="0x00068" name="CMN_CTRL"/>
+	<reg32 offset="0x000B4" name="STATUS"/>
+</domain>
+
+<domain name="HDMI_8998_PHY_QSERDES_COM" width="32">
+	<reg32 offset="0x0000" name="ATB_SEL1"/>
+	<reg32 offset="0x0004" name="ATB_SEL2"/>
+	<reg32 offset="0x0008" name="FREQ_UPDATE"/>
+	<reg32 offset="0x000C" name="BG_TIMER"/>
+	<reg32 offset="0x0010" name="SSC_EN_CENTER"/>
+	<reg32 offset="0x0014" name="SSC_ADJ_PER1"/>
+	<reg32 offset="0x0018" name="SSC_ADJ_PER2"/>
+	<reg32 offset="0x001C" name="SSC_PER1"/>
+	<reg32 offset="0x0020" name="SSC_PER2"/>
+	<reg32 offset="0x0024" name="SSC_STEP_SIZE1"/>
+	<reg32 offset="0x0028" name="SSC_STEP_SIZE2"/>
+	<reg32 offset="0x002C" name="POST_DIV"/>
+	<reg32 offset="0x0030" name="POST_DIV_MUX"/>
+	<reg32 offset="0x0034" name="BIAS_EN_CLKBUFLR_EN"/>
+	<reg32 offset="0x0038" name="CLK_ENABLE1"/>
+	<reg32 offset="0x003C" name="SYS_CLK_CTRL"/>
+	<reg32 offset="0x0040" name="SYSCLK_BUF_ENABLE"/>
+	<reg32 offset="0x0044" name="PLL_EN"/>
+	<reg32 offset="0x0048" name="PLL_IVCO"/>
+	<reg32 offset="0x004C" name="CMN_IETRIM"/>
+	<reg32 offset="0x0050" name="CMN_IPTRIM"/>
+	<reg32 offset="0x0060" name="CP_CTRL_MODE0"/>
+	<reg32 offset="0x0064" name="CP_CTRL_MODE1"/>
+	<reg32 offset="0x0068" name="PLL_RCTRL_MODE0"/>
+	<reg32 offset="0x006C" name="PLL_RCTRL_MODE1"/>
+	<reg32 offset="0x0070" name="PLL_CCTRL_MODE0"/>
+	<reg32 offset="0x0074" name="PLL_CCTRL_MODE1"/>
+	<reg32 offset="0x0078" name="PLL_CNTRL"/>
+	<reg32 offset="0x007C" name="BIAS_EN_CTRL_BY_PSM"/>
+	<reg32 offset="0x0080" name="SYSCLK_EN_SEL"/>
+	<reg32 offset="0x0084" name="CML_SYSCLK_SEL"/>
+	<reg32 offset="0x0088" name="RESETSM_CNTRL"/>
+	<reg32 offset="0x008C" name="RESETSM_CNTRL2"/>
+	<reg32 offset="0x0090" name="LOCK_CMP_EN"/>
+	<reg32 offset="0x0094" name="LOCK_CMP_CFG"/>
+	<reg32 offset="0x0098" name="LOCK_CMP1_MODE0"/>
+	<reg32 offset="0x009C" name="LOCK_CMP2_MODE0"/>
+	<reg32 offset="0x00A0" name="LOCK_CMP3_MODE0"/>
+	<reg32 offset="0x00B0" name="DEC_START_MODE0"/>
+	<reg32 offset="0x00B4" name="DEC_START_MODE1"/>
+	<reg32 offset="0x00B8" name="DIV_FRAC_START1_MODE0"/>
+	<reg32 offset="0x00BC" name="DIV_FRAC_START2_MODE0"/>
+	<reg32 offset="0x00C0" name="DIV_FRAC_START3_MODE0"/>
+	<reg32 offset="0x00C4" name="DIV_FRAC_START1_MODE1"/>
+	<reg32 offset="0x00C8" name="DIV_FRAC_START2_MODE1"/>
+	<reg32 offset="0x00CC" name="DIV_FRAC_START3_MODE1"/>
+	<reg32 offset="0x00D0" name="INTEGLOOP_INITVAL"/>
+	<reg32 offset="0x00D4" name="INTEGLOOP_EN"/>
+	<reg32 offset="0x00D8" name="INTEGLOOP_GAIN0_MODE0"/>
+	<reg32 offset="0x00DC" name="INTEGLOOP_GAIN1_MODE0"/>
+	<reg32 offset="0x00E0" name="INTEGLOOP_GAIN0_MODE1"/>
+	<reg32 offset="0x00E4" name="INTEGLOOP_GAIN1_MODE1"/>
+	<reg32 offset="0x00E8" name="VCOCAL_DEADMAN_CTRL"/>
+	<reg32 offset="0x00EC" name="VCO_TUNE_CTRL"/>
+	<reg32 offset="0x00F0" name="VCO_TUNE_MAP"/>
+	<reg32 offset="0x0124" name="CMN_STATUS"/>
+	<reg32 offset="0x0128" name="RESET_SM_STATUS"/>
+	<reg32 offset="0x0138" name="CLK_SEL"/>
+	<reg32 offset="0x013C" name="HSCLK_SEL"/>
+	<reg32 offset="0x0148" name="CORECLK_DIV_MODE0"/>
+	<reg32 offset="0x0150" name="SW_RESET"/>
+	<reg32 offset="0x0154" name="CORE_CLK_EN"/>
+	<reg32 offset="0x0158" name="C_READY_STATUS"/>
+	<reg32 offset="0x015C" name="CMN_CONFIG"/>
+	<reg32 offset="0x0164" name="SVS_MODE_CLK_SEL"/>
+</domain>
+
+<domain name="HDMI_8998_PHY_TXn" width="32">
+	<reg32 offset="0x0000" name="EMP_POST1_LVL"/>
+	<reg32 offset="0x0008" name="INTERFACE_SELECT_TX_BAND"/>
+	<reg32 offset="0x000C" name="CLKBUF_TERM_ENABLE"/>
+	<reg32 offset="0x0014" name="DRV_LVL_RES_CODE_OFFSET"/>
+	<reg32 offset="0x0018" name="DRV_LVL"/>
+	<reg32 offset="0x001C" name="LANE_CONFIG"/>
+	<reg32 offset="0x0024" name="PRE_DRIVER_1"/>
+	<reg32 offset="0x0028" name="PRE_DRIVER_2"/>
+	<reg32 offset="0x002C" name="LANE_MODE"/>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/mdp4.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/mdp4.xml
@@ -0,0 +1,504 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="display/mdp_common.xml"/>
+
+<domain name="MDP4" width="32">
+	<enum name="mdp4_pipe">
+		<brief>pipe names, index into PIPE[]</brief>
+		<value name="VG1" value="0"/>
+		<value name="VG2" value="1"/>
+		<value name="RGB1" value="2"/>
+		<value name="RGB2" value="3"/>
+		<value name="RGB3" value="4"/>
+		<value name="VG3" value="5"/>
+		<value name="VG4" value="6"/>
+	</enum>
+
+	<enum name="mdp4_mixer">
+		<value name="MIXER0" value="0"/>
+		<value name="MIXER1" value="1"/>
+		<value name="MIXER2" value="2"/>
+	</enum>
+
+	<enum name="mdp4_intf">
+		<!--
+			A bit confusing the enums for interface selection:
+				enum {
+					LCDC_RGB_INTF,			/* 0 */
+					DTV_INTF = LCDC_RGB_INTF,	/* 0 */
+					MDDI_LCDC_INTF,			/* 1 */
+					MDDI_INTF,			/* 2 */
+					EBI2_INTF,			/* 3 */
+					TV_INTF = EBI2_INTF,		/* 3 */
+					DSI_VIDEO_INTF,
+					DSI_CMD_INTF
+				};
+			there is some overlap, and not all the values end up getting
+			written to hw (mdp4_display_intf_sel() remaps the last two
+			values to MDDI_LCDC_INTF/MDDI_INTF with extra bits set).. so
+			taking some liberties in guessing the actual meanings/names:
+		 -->
+		<value name="INTF_LCDC_DTV" value="0"/>  <!-- LCDC RGB or DTV (external) -->
+		<value name="INTF_DSI_VIDEO" value="1"/>
+		<value name="INTF_DSI_CMD" value="2"/>
+		<value name="INTF_EBI2_TV" value="3"/>   <!-- EBI2 or TV (external) -->
+	</enum>
+	<enum name="mdp4_cursor_format">
+		<value name="CURSOR_ARGB" value="1"/>
+		<value name="CURSOR_XRGB" value="2"/>
+	</enum>
+	<enum name="mdp4_frame_format">
+		<value name="FRAME_LINEAR" value="0"/>
+		<value name="FRAME_TILE_ARGB_4X4" value="1"/>
+		<value name="FRAME_TILE_YCBCR_420" value="2"/>
+	</enum>
+	<enum name="mdp4_scale_unit">
+		<value name="SCALE_FIR" value="0"/>
+		<value name="SCALE_MN_PHASE" value="1"/>
+		<value name="SCALE_PIXEL_RPT" value="2"/>
+	</enum>
+
+	<bitset name="mdp4_layermixer_in_cfg" inline="yes">
+		<brief>appears to map pipe to mixer stage</brief>
+		<bitfield name="PIPE0" low="0"  high="2"  type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE0_MIXER1" pos="3" type="boolean"/>
+		<bitfield name="PIPE1" low="4"  high="6"  type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE1_MIXER1" pos="7" type="boolean"/>
+		<bitfield name="PIPE2" low="8"  high="10" type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE2_MIXER1" pos="11" type="boolean"/>
+		<bitfield name="PIPE3" low="12" high="14" type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE3_MIXER1" pos="15" type="boolean"/>
+		<bitfield name="PIPE4" low="16" high="18" type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE4_MIXER1" pos="19" type="boolean"/>
+		<bitfield name="PIPE5" low="20" high="22" type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE5_MIXER1" pos="23" type="boolean"/>
+		<bitfield name="PIPE6" low="24" high="26" type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE6_MIXER1" pos="27" type="boolean"/>
+		<bitfield name="PIPE7" low="28" high="30" type="mdp_mixer_stage_id"/>
+		<bitfield name="PIPE7_MIXER1" pos="31" type="boolean"/>
+	</bitset>
+
+	<bitset name="MDP4_IRQ">
+		<bitfield name="OVERLAY0_DONE" pos="0" type="boolean"/>
+		<bitfield name="OVERLAY1_DONE" pos="1" type="boolean"/>
+		<bitfield name="DMA_S_DONE" pos="2" type="boolean"/>
+		<bitfield name="DMA_E_DONE" pos="3" type="boolean"/>
+		<bitfield name="DMA_P_DONE" pos="4" type="boolean"/>
+		<bitfield name="VG1_HISTOGRAM" pos="5" type="boolean"/>
+		<bitfield name="VG2_HISTOGRAM" pos="6" type="boolean"/>
+		<bitfield name="PRIMARY_VSYNC" pos="7" type="boolean"/>
+		<bitfield name="PRIMARY_INTF_UDERRUN" pos="8" type="boolean"/>
+		<bitfield name="EXTERNAL_VSYNC" pos="9" type="boolean"/>
+		<bitfield name="EXTERNAL_INTF_UDERRUN" pos="10" type="boolean"/>
+		<bitfield name="PRIMARY_RDPTR" pos="11" type="boolean"/>  <!-- read pointer -->
+		<bitfield name="DMA_P_HISTOGRAM" pos="17" type="boolean"/>
+		<bitfield name="DMA_S_HISTOGRAM" pos="26" type="boolean"/>
+		<bitfield name="OVERLAY2_DONE" pos="30" type="boolean"/>
+	</bitset>
+
+	<reg32 offset="0x00000" name="VERSION">
+		<!--
+			from mdp_probe() we can see minor rev starts at 16.. assume
+			major is above that.. not sure the rest of bits but doesn't
+			really seem to matter
+		 -->
+		<bitfield name="MINOR" low="16" high="23" type="uint"/>
+		<bitfield name="MAJOR" low="24" high="31" type="uint"/>
+	</reg32>
+	<reg32 offset="0x00004" name="OVLP0_KICK"/>
+	<reg32 offset="0x00008" name="OVLP1_KICK"/>
+	<reg32 offset="0x000d0" name="OVLP2_KICK"/>
+	<reg32 offset="0x0000c" name="DMA_P_KICK"/>
+	<reg32 offset="0x00010" name="DMA_S_KICK"/>
+	<reg32 offset="0x00014" name="DMA_E_KICK"/>
+	<reg32 offset="0x00018" name="DISP_STATUS"/>
+
+	<reg32 offset="0x00038" name="DISP_INTF_SEL">
+		<bitfield name="PRIM" low="0" high="1" type="mdp4_intf"/>
+		<bitfield name="SEC" low="2" high="3" type="mdp4_intf"/>
+		<bitfield name="EXT" low="4" high="5" type="mdp4_intf"/>
+		<bitfield name="DSI_VIDEO" pos="6" type="boolean"/>
+		<bitfield name="DSI_CMD" pos="7" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x0003c" name="RESET_STATUS"/>  <!-- only mdp4 >v2.1 -->
+	<reg32 offset="0x0004c" name="READ_CNFG"/>  <!-- something about # of pending requests.. -->
+	<reg32 offset="0x00050" name="INTR_ENABLE" type="MDP4_IRQ"/>
+	<reg32 offset="0x00054" name="INTR_STATUS" type="MDP4_IRQ"/>
+	<reg32 offset="0x00058" name="INTR_CLEAR" type="MDP4_IRQ"/>
+	<reg32 offset="0x00060" name="EBI2_LCD0"/>
+	<reg32 offset="0x00064" name="EBI2_LCD1"/>
+	<reg32 offset="0x00070" name="PORTMAP_MODE"/>
+
+	<!-- mdp chip-select controller: -->
+	<reg32 offset="0x000c0" name="CS_CONTROLLER0"/>
+	<reg32 offset="0x000c4" name="CS_CONTROLLER1"/>
+
+	<reg32 offset="0x100f0" name="LAYERMIXER2_IN_CFG" type="mdp4_layermixer_in_cfg"/>
+	<reg32 offset="0x100fc" name="LAYERMIXER_IN_CFG_UPDATE_METHOD"/>
+	<reg32 offset="0x10100" name="LAYERMIXER_IN_CFG" type="mdp4_layermixer_in_cfg"/>
+
+	<reg32 offset="0x30050" name="VG2_SRC_FORMAT"/>
+	<reg32 offset="0x31008" name="VG2_CONST_COLOR"/>
+
+	<reg32 offset="0x18000" name="OVERLAY_FLUSH">
+		<bitfield name="OVLP0" pos="0" type="boolean"/>
+		<bitfield name="OVLP1" pos="1" type="boolean"/>
+		<bitfield name="VG1" pos="2" type="boolean"/>
+		<bitfield name="VG2" pos="3" type="boolean"/>
+		<bitfield name="RGB1" pos="4" type="boolean"/>
+		<bitfield name="RGB2" pos="5" type="boolean"/>
+	</reg32>
+
+	<array offsets="0x10000,0x18000,0x88000" name="OVLP" length="3" stride="0x8000">
+		<reg32 offset="0x0004" name="CFG"/>
+		<reg32 offset="0x0008" name="SIZE" type="reg_wh"/>
+		<reg32 offset="0x000c" name="BASE"/>
+		<reg32 offset="0x0010" name="STRIDE" type="uint"/>
+		<reg32 offset="0x0014" name="OPMODE"/>
+
+		<array offsets="0x0104,0x0124,0x0144,0x0160" name="STAGE" length="4" stride="0x1c">
+			<reg32 offset="0x00" name="OP">
+				<bitfield name="FG_ALPHA" low="0" high="1" type="mdp_alpha_type"/>
+				<bitfield name="FG_INV_ALPHA" pos="2" type="boolean"/>
+				<bitfield name="FG_MOD_ALPHA" pos="3" type="boolean"/>
+				<bitfield name="BG_ALPHA" low="4" high="5" type="mdp_alpha_type"/>
+				<bitfield name="BG_INV_ALPHA" pos="6" type="boolean"/>
+				<bitfield name="BG_MOD_ALPHA" pos="7" type="boolean"/>
+				<bitfield name="FG_TRANSP" pos="8" type="boolean"/>
+				<bitfield name="BG_TRANSP" pos="9" type="boolean"/>
+			</reg32>
+			<reg32 offset="0x04" name="FG_ALPHA"/>
+			<reg32 offset="0x08" name="BG_ALPHA"/>
+			<reg32 offset="0x0c" name="TRANSP_LOW0"/>
+			<reg32 offset="0x10" name="TRANSP_LOW1"/>
+			<reg32 offset="0x14" name="TRANSP_HIGH0"/>
+			<reg32 offset="0x18" name="TRANSP_HIGH1"/>
+		</array>
+
+		<array offsets="0x1004,0x1404,0x1804,0x1b84" name="STAGE_CO3" length="4" stride="4">
+			<reg32 offset="0" name="SEL">
+				<bitfield name="FG_ALPHA" pos="0" type="boolean"/> <!-- otherwise bg alpha -->
+			</reg32>
+		</array>
+
+		<reg32 offset="0x0180" name="TRANSP_LOW0"/>
+		<reg32 offset="0x0184" name="TRANSP_LOW1"/>
+		<reg32 offset="0x0188" name="TRANSP_HIGH0"/>
+		<reg32 offset="0x018c" name="TRANSP_HIGH1"/>
+
+		<reg32 offset="0x0200" name="CSC_CONFIG"/>
+
+		<array offset="0x2000" name="CSC" length="1" stride="0x700">
+			<array offset="0x400" name="MV" length="9" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x500" name="PRE_BV" length="3" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x580" name="POST_BV" length="3" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x600" name="PRE_LV" length="6" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x680" name="POST_LV" length="6" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+		</array>
+	</array>
+
+	<enum name="mdp4_dma">
+		<value name="DMA_P" value="0"/>
+		<value name="DMA_S" value="1"/>
+		<value name="DMA_E" value="2"/>
+	</enum>
+	<reg32 offset="0x90070" name="DMA_P_OP_MODE"/>
+	<array offset="0x94800" name="LUTN" length="2" stride="0x400">
+		<array offset="0" name="LUT" length="0x100" stride="4">
+			<reg32 offset="0" name="VAL"/>
+		</array>
+	</array>
+	<reg32 offset="0xa0028" name="DMA_S_OP_MODE"/>
+	<!-- I guess if DMA_S has an OP_MODE, it must have a LUT too.. -->
+	<reg32 offset="0xb0070" name="DMA_E_QUANT" length="3" stride="4"/>
+	<array offsets="0x90000,0xa0000,0xb0000" name="DMA" length="3" stride="0x10000" index="mdp4_dma">
+		<reg32 offset="0x0000" name="CONFIG">
+			<bitfield name="G_BPC" low="0" high="1" type="mdp_bpc"/>
+			<bitfield name="B_BPC" low="2" high="3" type="mdp_bpc"/>
+			<bitfield name="R_BPC" low="4" high="5" type="mdp_bpc"/>
+			<bitfield name="PACK_ALIGN_MSB" pos="7" type="boolean"/>
+			<bitfield name="PACK" low="8" high="15"/>
+			<!-- bit 24 is DITHER_EN on DMA_P, DEFLKR_EN on DMA_E -->
+			<bitfield name="DEFLKR_EN" pos="24" type="boolean"/>
+			<bitfield name="DITHER_EN" pos="24" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x0004" name="SRC_SIZE" type="reg_wh"/>
+		<reg32 offset="0x0008" name="SRC_BASE"/>
+		<reg32 offset="0x000c" name="SRC_STRIDE" type="uint"/>
+		<reg32 offset="0x0010" name="DST_SIZE" type="reg_wh"/>
+
+		<reg32 offset="0x0044" name="CURSOR_SIZE">
+			<!-- seems the limit is 64x64: -->
+			<bitfield name="WIDTH" low="0" high="6" type="uint"/>
+			<bitfield name="HEIGHT" low="16" high="22" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0048" name="CURSOR_BASE"/>
+		<reg32 offset="0x004c" name="CURSOR_POS">
+			<bitfield name="X" low="0" high="15" type="uint"/>
+			<bitfield name="Y" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0060" name="CURSOR_BLEND_CONFIG">
+			<bitfield name="CURSOR_EN" pos="0" type="boolean"/>
+			<bitfield name="FORMAT" low="1" high="2" type="mdp4_cursor_format"/>
+			<bitfield name="TRANSP_EN" pos="3" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x0064" name="CURSOR_BLEND_PARAM"/>
+		<reg32 offset="0x0068" name="BLEND_TRANS_LOW"/>
+		<reg32 offset="0x006c" name="BLEND_TRANS_HIGH"/>
+
+		<reg32 offset="0x1004" name="FETCH_CONFIG"/>
+		<array offset="0x3000" name="CSC" length="1" stride="0x700">
+			<array offset="0x400" name="MV" length="9" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x500" name="PRE_BV" length="3" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x580" name="POST_BV" length="3" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x600" name="PRE_LV" length="6" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x680" name="POST_LV" length="6" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+		</array>
+	</array>
+
+	<!--
+		TODO length should be 7, but that would collide w/ OVLP2..!?!
+		this register map is a bit strange..
+	 -->
+	<array offset="0x20000" name="PIPE" length="6" stride="0x10000" index="mdp4_pipe">
+		<reg32 offset="0x0000" name="SRC_SIZE" type="reg_wh"/>
+		<reg32 offset="0x0004" name="SRC_XY" type="reg_xy"/>
+		<reg32 offset="0x0008" name="DST_SIZE" type="reg_wh"/>
+		<reg32 offset="0x000c" name="DST_XY" type="reg_xy"/>
+		<reg32 offset="0x0010" name="SRCP0_BASE"/>
+		<reg32 offset="0x0014" name="SRCP1_BASE"/>
+		<reg32 offset="0x0018" name="SRCP2_BASE"/>
+		<reg32 offset="0x001c" name="SRCP3_BASE"/>
+		<reg32 offset="0x0040" name="SRC_STRIDE_A">
+			<bitfield name="P0" low="0" high="15" type="uint"/>
+			<bitfield name="P1" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0044" name="SRC_STRIDE_B">
+			<bitfield name="P2" low="0" high="15" type="uint"/>
+			<bitfield name="P3" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0048" name="SSTILE_FRAME_SIZE" type="reg_wh"/>
+		<reg32 offset="0x0050" name="SRC_FORMAT">
+			<bitfield name="G_BPC" low="0" high="1" type="mdp_bpc"/>
+			<bitfield name="B_BPC" low="2" high="3" type="mdp_bpc"/>
+			<bitfield name="R_BPC" low="4" high="5" type="mdp_bpc"/>
+			<bitfield name="A_BPC" low="6" high="7" type="mdp_bpc_alpha"/>
+			<bitfield name="ALPHA_ENABLE" pos="8" type="boolean"/>
+			<bitfield name="CPP" low="9" high="10" type="uint">
+				<brief>8bit characters per pixel minus 1</brief>
+			</bitfield>
+			<bitfield name="ROTATED_90" pos="12" type="boolean"/>
+			<bitfield name="UNPACK_COUNT" low="13" high="14" type="uint"/>
+			<bitfield name="UNPACK_TIGHT" pos="17" type="boolean"/>
+			<bitfield name="UNPACK_ALIGN_MSB" pos="18" type="boolean"/>
+			<bitfield name="FETCH_PLANES" low="19" high="20" type="uint"/>
+			<bitfield name="SOLID_FILL" pos="22" type="boolean"/>
+			<bitfield name="CHROMA_SAMP" low="26" high="27" type="mdp_chroma_samp_type"/>
+			<bitfield name="FRAME_FORMAT" low="29" high="30" type="mdp4_frame_format"/>
+		</reg32>
+		<reg32 offset="0x0054" name="SRC_UNPACK" type="mdp_unpack_pattern"/>
+		<reg32 offset="0x0058" name="OP_MODE">
+			<bitfield name="SCALEX_EN" pos="0" type="boolean"/>
+			<bitfield name="SCALEY_EN" pos="1" type="boolean"/>
+			<bitfield name="SCALEX_UNIT_SEL" low="2" high="3" type="mdp4_scale_unit"/>
+			<bitfield name="SCALEY_UNIT_SEL" low="4" high="5" type="mdp4_scale_unit"/>
+			<bitfield name="SRC_YCBCR" pos="9" type="boolean"/>
+			<bitfield name="DST_YCBCR" pos="10" type="boolean"/>
+			<bitfield name="CSC_EN" pos="11" type="boolean"/>
+			<bitfield name="FLIP_LR" pos="13" type="boolean"/>
+			<bitfield name="FLIP_UD" pos="14" type="boolean"/>
+			<bitfield name="DITHER_EN" pos="15" type="boolean"/>
+			<bitfield name="IGC_LUT_EN" pos="16" type="boolean"/>
+			<bitfield name="DEINT_EN" pos="18" type="boolean"/>
+			<bitfield name="DEINT_ODD_REF" pos="19" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x005c" name="PHASEX_STEP"/>
+		<reg32 offset="0x0060" name="PHASEY_STEP"/>
+		<reg32 offset="0x1004" name="FETCH_CONFIG"/>
+		<reg32 offset="0x1008" name="SOLID_COLOR"/>
+
+		<array offset="0x4000" name="CSC" length="1" stride="0x700">
+			<array offset="0x400" name="MV" length="9" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x500" name="PRE_BV" length="3" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x580" name="POST_BV" length="3" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x600" name="PRE_LV" length="6" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+			<array offset="0x680" name="POST_LV" length="6" stride="4">
+				<reg32 offset="0" name="VAL"/>
+			</array>
+		</array>
+	</array>
+
+	<!--
+		ENCODERS
+			LCDC and DSI seem the same, DTV is just slightly different..
+	 -->
+
+	<bitset name="mdp4_ctrl_polarity" inline="yes">
+		<!-- not entirely sure if these bits mean hi or low.. -->
+		<bitfield name="HSYNC_LOW" pos="0" type="boolean"/>
+		<bitfield name="VSYNC_LOW" pos="1" type="boolean"/>
+		<bitfield name="DATA_EN_LOW" pos="2" type="boolean"/>
+	</bitset>
+
+	<bitset name="mdp4_active_hctl" inline="yes">
+		<bitfield name="START" low="0" high="14" type="uint"/>
+		<bitfield name="END" low="16" high="30" type="uint"/>
+		<bitfield name="ACTIVE_START_X" pos="31" type="boolean"/>
+	</bitset>
+
+	<bitset name="mdp4_display_hctl" inline="yes">
+		<bitfield name="START" low="0" high="15" type="uint"/>
+		<bitfield name="END" low="16" high="31" type="uint"/>
+	</bitset>
+
+	<bitset name="mdp4_hsync_ctrl" inline="yes">
+		<bitfield name="PULSEW" low="0" high="15" type="uint"/>
+		<bitfield name="PERIOD" low="16" high="31" type="uint"/>
+	</bitset>
+
+	<bitset name="mdp4_underflow_clr" inline="yes">
+		<bitfield name="COLOR" low="0" high="23"/>
+		<bitfield name="ENABLE_RECOVERY" pos="31" type="boolean"/>
+	</bitset>
+
+	<!-- offset is 0xe0000 on !mdp4.. -->
+	<array offset="0xc0000" name="LCDC" length="1" stride="0x1000">
+		<reg32 offset="0x0000" name="ENABLE"/>
+		<reg32 offset="0x0004" name="HSYNC_CTRL" type="mdp4_hsync_ctrl"/>
+		<reg32 offset="0x0008" name="VSYNC_PERIOD" type="uint"/>
+		<reg32 offset="0x000c" name="VSYNC_LEN" type="uint"/>
+		<reg32 offset="0x0010" name="DISPLAY_HCTRL" type="mdp4_display_hctl"/>
+		<reg32 offset="0x0014" name="DISPLAY_VSTART" type="uint"/>
+		<reg32 offset="0x0018" name="DISPLAY_VEND" type="uint"/>
+		<reg32 offset="0x001c" name="ACTIVE_HCTL" type="mdp4_active_hctl"/>
+		<reg32 offset="0x0020" name="ACTIVE_VSTART" type="uint"/>
+		<reg32 offset="0x0024" name="ACTIVE_VEND" type="uint"/>
+		<reg32 offset="0x0028" name="BORDER_CLR"/>
+		<reg32 offset="0x002c" name="UNDERFLOW_CLR" type="mdp4_underflow_clr"/>
+		<reg32 offset="0x0030" name="HSYNC_SKEW"/>
+		<reg32 offset="0x0034" name="TEST_CNTL"/>
+		<reg32 offset="0x0038" name="CTRL_POLARITY" type="mdp4_ctrl_polarity"/>
+	</array>
+
+	<reg32 offset="0xc2000" name="LCDC_LVDS_INTF_CTL">
+		<bitfield name="MODE_SEL"           pos="2"  type="boolean"/>
+		<bitfield name="RGB_OUT"            pos="3"  type="boolean"/>
+		<bitfield name="CH_SWAP"            pos="4"  type="boolean"/>
+		<bitfield name="CH1_RES_BIT"        pos="5"  type="boolean"/>
+		<bitfield name="CH2_RES_BIT"        pos="6"  type="boolean"/>
+		<bitfield name="ENABLE"             pos="7"  type="boolean"/>
+		<bitfield name="CH1_DATA_LANE0_EN"  pos="8"  type="boolean"/>
+		<bitfield name="CH1_DATA_LANE1_EN"  pos="9"  type="boolean"/>
+		<bitfield name="CH1_DATA_LANE2_EN"  pos="10" type="boolean"/>
+		<bitfield name="CH1_DATA_LANE3_EN"  pos="11" type="boolean"/>
+		<bitfield name="CH2_DATA_LANE0_EN"  pos="12" type="boolean"/>
+		<bitfield name="CH2_DATA_LANE1_EN"  pos="13" type="boolean"/>
+		<bitfield name="CH2_DATA_LANE2_EN"  pos="14" type="boolean"/>
+		<bitfield name="CH2_DATA_LANE3_EN"  pos="15" type="boolean"/>
+		<bitfield name="CH1_CLK_LANE_EN"    pos="16" type="boolean"/>
+		<bitfield name="CH2_CLK_LANE_EN"    pos="17" type="boolean"/>
+	</reg32>
+
+	<array offset="0xc2014" name="LCDC_LVDS_MUX_CTL" length="4" stride="0x8">
+		<reg32 offset="0x0" name="3_TO_0">
+			<bitfield name="BIT0" low="0"  high="7"/>
+			<bitfield name="BIT1" low="8"  high="15"/>
+			<bitfield name="BIT2" low="16" high="23"/>
+			<bitfield name="BIT3" low="24" high="31"/>
+		</reg32>
+		<reg32 offset="0x4" name="6_TO_4">
+			<bitfield name="BIT4" low="0"  high="7"/>
+			<bitfield name="BIT5" low="8"  high="15"/>
+			<bitfield name="BIT6" low="16" high="23"/>
+		</reg32>
+	</array>
+
+	<reg32 offset="0xc2034" name="LCDC_LVDS_PHY_RESET"/>
+
+	<reg32 offset="0xc3000" name="LVDS_PHY_PLL_CTRL_0"/>
+	<reg32 offset="0xc3004" name="LVDS_PHY_PLL_CTRL_1"/>
+	<reg32 offset="0xc3008" name="LVDS_PHY_PLL_CTRL_2"/>
+	<reg32 offset="0xc300c" name="LVDS_PHY_PLL_CTRL_3"/>
+	<reg32 offset="0xc3014" name="LVDS_PHY_PLL_CTRL_5"/>
+	<reg32 offset="0xc3018" name="LVDS_PHY_PLL_CTRL_6"/>
+	<reg32 offset="0xc301c" name="LVDS_PHY_PLL_CTRL_7"/>
+	<reg32 offset="0xc3020" name="LVDS_PHY_PLL_CTRL_8"/>
+	<reg32 offset="0xc3024" name="LVDS_PHY_PLL_CTRL_9"/>
+	<reg32 offset="0xc3080" name="LVDS_PHY_PLL_LOCKED"/>
+	<reg32 offset="0xc3108" name="LVDS_PHY_CFG2"/>
+
+	<reg32 offset="0xc3100" name="LVDS_PHY_CFG0">
+		<bitfield name="SERIALIZATION_ENBLE" pos="4" type="boolean"/>
+		<bitfield name="CHANNEL0" pos="6" type="boolean"/>
+		<bitfield name="CHANNEL1" pos="7" type="boolean"/>
+	</reg32>
+
+	<array offset="0xd0000" name="DTV" length="1" stride="0x1000">
+		<reg32 offset="0x0000" name="ENABLE"/>
+		<reg32 offset="0x0004" name="HSYNC_CTRL" type="mdp4_hsync_ctrl"/>
+		<reg32 offset="0x0008" name="VSYNC_PERIOD" type="uint"/>
+		<reg32 offset="0x000c" name="VSYNC_LEN" type="uint"/>
+		<reg32 offset="0x0018" name="DISPLAY_HCTRL" type="mdp4_display_hctl"/>
+		<reg32 offset="0x001c" name="DISPLAY_VSTART" type="uint"/>
+		<reg32 offset="0x0020" name="DISPLAY_VEND" type="uint"/>
+		<reg32 offset="0x002c" name="ACTIVE_HCTL" type="mdp4_active_hctl"/>
+		<reg32 offset="0x0030" name="ACTIVE_VSTART" type="uint"/>
+		<reg32 offset="0x0038" name="ACTIVE_VEND" type="uint"/>
+		<reg32 offset="0x0040" name="BORDER_CLR"/>
+		<reg32 offset="0x0044" name="UNDERFLOW_CLR" type="mdp4_underflow_clr"/>
+		<reg32 offset="0x0048" name="HSYNC_SKEW"/>
+		<reg32 offset="0x004c" name="TEST_CNTL"/>
+		<reg32 offset="0x0050" name="CTRL_POLARITY" type="mdp4_ctrl_polarity"/>
+	</array>
+
+	<array offset="0xe0000" name="DSI" length="1" stride="0x1000">
+		<reg32 offset="0x0000" name="ENABLE"/>
+		<reg32 offset="0x0004" name="HSYNC_CTRL" type="mdp4_hsync_ctrl"/>
+		<reg32 offset="0x0008" name="VSYNC_PERIOD" type="uint"/>
+		<reg32 offset="0x000c" name="VSYNC_LEN" type="uint"/>
+		<reg32 offset="0x0010" name="DISPLAY_HCTRL" type="mdp4_display_hctl"/>
+		<reg32 offset="0x0014" name="DISPLAY_VSTART" type="uint"/>
+		<reg32 offset="0x0018" name="DISPLAY_VEND" type="uint"/>
+		<reg32 offset="0x001c" name="ACTIVE_HCTL" type="mdp4_active_hctl"/>
+		<reg32 offset="0x0020" name="ACTIVE_VSTART" type="uint"/>
+		<reg32 offset="0x0024" name="ACTIVE_VEND" type="uint"/>
+		<reg32 offset="0x0028" name="BORDER_CLR"/>
+		<reg32 offset="0x002c" name="UNDERFLOW_CLR" type="mdp4_underflow_clr"/>
+		<reg32 offset="0x0030" name="HSYNC_SKEW"/>
+		<reg32 offset="0x0034" name="TEST_CNTL"/>
+		<reg32 offset="0x0038" name="CTRL_POLARITY" type="mdp4_ctrl_polarity"/>
+	</array>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/mdp5.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/mdp5.xml
@@ -0,0 +1,790 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+<import file="display/mdp_common.xml"/>
+
+<!-- where does this belong? -->
+<domain name="VBIF" width="32">
+</domain>
+
+<domain name="MDP5" width="32">
+
+	<enum name="mdp5_intf_type">
+		<value name="INTF_DISABLED" value="0x0"/>
+		<value name="INTF_DSI"  value="0x1"/>
+		<value name="INTF_HDMI" value="0x3"/>
+		<value name="INTF_LCDC" value="0x5"/>
+		<value name="INTF_eDP"  value="0x9"/>
+		<value name="INTF_VIRTUAL"  value="0x64"/>
+		<!-- non-display interfaces are listed below: -->
+		<value name="INTF_WB"  value="0x65"/>
+	</enum>
+
+	<enum name="mdp5_intfnum">
+		<value name="NO_INTF" value="0"/>
+		<value name="INTF0"   value="1"/>
+		<value name="INTF1"   value="2"/>
+		<value name="INTF2"   value="3"/>
+		<value name="INTF3"   value="4"/>
+	</enum>
+
+	<enum name="mdp5_pipe">
+		<value name="SSPP_NONE" value="0"/>
+		<value name="SSPP_VIG0" value="1"/>
+		<value name="SSPP_VIG1" value="2"/>
+		<value name="SSPP_VIG2" value="3"/>
+		<value name="SSPP_RGB0" value="4"/>
+		<value name="SSPP_RGB1" value="5"/>
+		<value name="SSPP_RGB2" value="6"/>
+		<value name="SSPP_DMA0" value="7"/>
+		<value name="SSPP_DMA1" value="8"/>
+		<value name="SSPP_VIG3" value="9"/>
+		<value name="SSPP_RGB3" value="10"/>
+		<value name="SSPP_CURSOR0" value="11"/>
+		<value name="SSPP_CURSOR1" value="12"/>
+	</enum>
+
+	<enum name="mdp5_format">
+		<!-- TODO -->
+		<value name="DUMMY" value="0"/>
+	</enum>
+
+	<enum name="mdp5_ctl_mode">
+		<value name="MODE_NONE" value="0"/>
+		<value name="MODE_WB_0_BLOCK" value="1"/>
+		<value name="MODE_WB_1_BLOCK" value="2"/>
+		<value name="MODE_WB_0_LINE" value="3"/>
+		<value name="MODE_WB_1_LINE" value="4"/>
+		<value name="MODE_WB_2_LINE" value="5"/>
+	</enum>
+
+	<enum name="mdp5_pack_3d">
+		<value name="PACK_3D_FRAME_INT" value="0"/>
+		<value name="PACK_3D_H_ROW_INT" value="1"/>
+		<value name="PACK_3D_V_ROW_INT" value="2"/>
+		<value name="PACK_3D_COL_INT"   value="3"/>
+	</enum>
+
+	<enum name="mdp5_scale_filter">
+		<value name="SCALE_FILTER_NEAREST" value="0"/>
+		<value name="SCALE_FILTER_BIL" value="1"/>
+		<value name="SCALE_FILTER_PCMN" value="2"/>
+		<value name="SCALE_FILTER_CA" value="3"/>
+	</enum>
+
+	<enum name="mdp5_pipe_bwc">
+		<value name="BWC_LOSSLESS" value="0"/>
+		<value name="BWC_Q_HIGH"   value="1"/>
+		<value name="BWC_Q_MED"    value="2"/>
+	</enum>
+
+	<enum name="mdp5_cursor_format">
+		<value name="CURSOR_FMT_ARGB8888" value="0"/>
+		<value name="CURSOR_FMT_ARGB1555" value="2"/>
+		<value name="CURSOR_FMT_ARGB4444" value="4"/>
+	</enum>
+
+	<enum name="mdp5_cursor_alpha">
+		<value name="CURSOR_ALPHA_CONST" value="0"/>
+		<value name="CURSOR_ALPHA_PER_PIXEL" value="2"/>
+	</enum>
+
+	<bitset name="MDP5_IRQ">
+		<bitfield name="WB_0_DONE"                pos="0"  type="boolean"/>
+		<bitfield name="WB_1_DONE"                pos="1"  type="boolean"/>
+		<bitfield name="WB_2_DONE"                pos="4"  type="boolean"/>
+		<bitfield name="PING_PONG_0_DONE"         pos="8"  type="boolean"/>
+		<bitfield name="PING_PONG_1_DONE"         pos="9"  type="boolean"/>
+		<bitfield name="PING_PONG_2_DONE"         pos="10" type="boolean"/>
+		<bitfield name="PING_PONG_3_DONE"         pos="11" type="boolean"/>
+		<bitfield name="PING_PONG_0_RD_PTR"       pos="12" type="boolean"/>
+		<bitfield name="PING_PONG_1_RD_PTR"       pos="13" type="boolean"/>
+		<bitfield name="PING_PONG_2_RD_PTR"       pos="14" type="boolean"/>
+		<bitfield name="PING_PONG_3_RD_PTR"       pos="15" type="boolean"/>
+		<bitfield name="PING_PONG_0_WR_PTR"       pos="16" type="boolean"/>
+		<bitfield name="PING_PONG_1_WR_PTR"       pos="17" type="boolean"/>
+		<bitfield name="PING_PONG_2_WR_PTR"       pos="18" type="boolean"/>
+		<bitfield name="PING_PONG_3_WR_PTR"       pos="19" type="boolean"/>
+		<bitfield name="PING_PONG_0_AUTO_REF"     pos="20" type="boolean"/>
+		<bitfield name="PING_PONG_1_AUTO_REF"     pos="21" type="boolean"/>
+		<bitfield name="PING_PONG_2_AUTO_REF"     pos="22" type="boolean"/>
+		<bitfield name="PING_PONG_3_AUTO_REF"     pos="23" type="boolean"/>
+		<bitfield name="INTF0_UNDER_RUN"          pos="24" type="boolean"/>
+		<bitfield name="INTF0_VSYNC"              pos="25" type="boolean"/>
+		<bitfield name="INTF1_UNDER_RUN"          pos="26" type="boolean"/>
+		<bitfield name="INTF1_VSYNC"              pos="27" type="boolean"/>
+		<bitfield name="INTF2_UNDER_RUN"          pos="28" type="boolean"/>
+		<bitfield name="INTF2_VSYNC"              pos="29" type="boolean"/>
+		<bitfield name="INTF3_UNDER_RUN"          pos="30" type="boolean"/>
+		<bitfield name="INTF3_VSYNC"              pos="31" type="boolean"/>
+	</bitset>
+
+	<bitset name="mdp5_smp_alloc" inline="yes">
+        <!-- Use "mdp5_cfg->mdp.smp.clients[enum mdp5_pipe]" instead -->
+		<bitfield name="CLIENT0" low="0"  high="7"  type="uint"/>
+		<bitfield name="CLIENT1" low="8"  high="15" type="uint"/>
+		<bitfield name="CLIENT2" low="16" high="23" type="uint"/>
+	</bitset>
+
+	<reg32 offset="0x00000" name="HW_VERSION">
+		<bitfield name="STEP" low="0" high="15" type="uint"/>
+		<bitfield name="MINOR" low="16" high="27" type="uint"/>
+		<bitfield name="MAJOR" low="28" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00004" name="DISP_INTF_SEL">
+		<bitfield name="INTF0" low="0"  high="7"  type="mdp5_intf_type"/>
+		<bitfield name="INTF1" low="8"  high="15" type="mdp5_intf_type"/>
+		<bitfield name="INTF2" low="16" high="23" type="mdp5_intf_type"/>
+		<bitfield name="INTF3" low="24" high="31" type="mdp5_intf_type"/>
+	</reg32>
+	<reg32 offset="0x00010" name="INTR_EN" type="MDP5_IRQ"/>
+	<reg32 offset="0x00014" name="INTR_STATUS" type="MDP5_IRQ"/>
+	<reg32 offset="0x00018" name="INTR_CLEAR" type="MDP5_IRQ"/>
+	<reg32 offset="0x0001C" name="HIST_INTR_EN"/>
+	<reg32 offset="0x00020" name="HIST_INTR_STATUS"/>
+	<reg32 offset="0x00024" name="HIST_INTR_CLEAR"/>
+	<reg32 offset="0x00028" name="SPARE_0">
+		<bitfield name="SPLIT_DPL_SINGLE_FLUSH_EN" pos="0"/>
+	</reg32>
+
+	<array offset="0x00080" name="SMP_ALLOC_W" length="8" stride="4">
+		<reg32 offset="0" name="REG" type="mdp5_smp_alloc"/>
+	</array>
+	<array offset="0x00130" name="SMP_ALLOC_R" length="8" stride="4">
+		<reg32 offset="0" name="REG" type="mdp5_smp_alloc"/>
+	</array>
+
+	<enum name="mdp5_igc_type">
+		<value name="IGC_VIG" value="0"/>		<!-- 0x200 -->
+		<value name="IGC_RGB" value="1"/>		<!-- 0x210 -->
+		<value name="IGC_DMA" value="2"/>		<!-- 0x220 -->
+		<value name="IGC_DSPP" value="3"/>		<!-- 0x300 -->
+	</enum>
+	<array offsets="0x00200,0x00210,0x00220,0x00300" name="IGC" length="3" stride="0x10" index="mdp5_igc_type">
+		<array offset="0x00" name="LUT" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="VAL" low="0" high="11"/>
+				<bitfield name="INDEX_UPDATE" pos="25" type="boolean"/>
+				<!--
+					not sure about these:
+						/* INDEX_UPDATE */
+						data = (1 << 25) | (((~(1 << blk_idx)) & 0x7) << 28);
+						MDSS_MDP_REG_WRITE(offset, (cfg->c0_c1_data[0] & 0xFFF) | data);
+				-->
+				<bitfield name="DISABLE_PIPE_0" pos="28" type="boolean"/>
+				<bitfield name="DISABLE_PIPE_1" pos="29" type="boolean"/>
+				<bitfield name="DISABLE_PIPE_2" pos="30" type="boolean"/>
+			</reg32>
+		</array>
+	</array>
+	<reg32 offset="0x002f4" name="SPLIT_DPL_EN"/>
+	<reg32 offset="0x002f8" name="SPLIT_DPL_UPPER">
+		<bitfield name="SMART_PANEL" pos="1" type="boolean"/>
+		<bitfield name="SMART_PANEL_FREE_RUN" pos="2" type="boolean"/>
+		<bitfield name="INTF1_SW_TRG_MUX" pos="4" type="boolean"/>
+		<bitfield name="INTF2_SW_TRG_MUX" pos="8" type="boolean"/>
+	</reg32>
+	<reg32 offset="0x003f0" name="SPLIT_DPL_LOWER">
+		<bitfield name="SMART_PANEL" pos="1" type="boolean"/>
+		<bitfield name="SMART_PANEL_FREE_RUN" pos="2" type="boolean"/>
+		<bitfield name="INTF1_TG_SYNC" pos="4" type="boolean"/>
+		<bitfield name="INTF2_TG_SYNC" pos="8" type="boolean"/>
+	</reg32>
+
+<!-- check length/index.. -->
+	<array doffsets="mdp5_cfg->ctl.base[0],mdp5_cfg->ctl.base[1],mdp5_cfg->ctl.base[2],mdp5_cfg->ctl.base[3],mdp5_cfg->ctl.base[4]" name="CTL" length="5" stride="0x400">
+		<array offsets="0x000,0x004,0x008,0x00C,0x010,0x024" name="LAYER" length="6" stride="4">
+			<!--
+			NOTE: for backwards compat (from when there were fewer stages),
+			this register has the low three bits of mdp_mixer_stage_id, with
+			the high bit coming from LAYER_EXT
+			 -->
+			<reg32 offset="0" name="REG">
+				<bitfield name="VIG0"  low="0"  high="2"  type="uint"/>
+				<bitfield name="VIG1"  low="3"  high="5"  type="uint"/>
+				<bitfield name="VIG2"  low="6"  high="8"  type="uint"/>
+				<bitfield name="RGB0"  low="9"  high="11" type="uint"/>
+				<bitfield name="RGB1"  low="12" high="14" type="uint"/>
+				<bitfield name="RGB2"  low="15" high="17" type="uint"/>
+				<bitfield name="DMA0"  low="18" high="20" type="uint"/>
+				<bitfield name="DMA1"  low="21" high="23" type="uint"/>
+				<bitfield name="BORDER_COLOR" pos="24" type="boolean"/>
+				<bitfield name="CURSOR_OUT"   pos="25" type="boolean"/>
+				<bitfield name="VIG3"  low="26"  high="28"  type="uint"/>
+				<bitfield name="RGB3"  low="29" high="31" type="uint"/>
+			</reg32>
+		</array>
+		<reg32 offset="0x014" name="OP">
+			<bitfield name="MODE" low="0" high="3" type="mdp5_ctl_mode"/>
+			<bitfield name="INTF_NUM" low="4" high="6" type="mdp5_intfnum"/>
+			<bitfield name="CMD_MODE" pos="17" type="boolean"/>
+			<bitfield name="PACK_3D_ENABLE" pos="19" type="boolean"/>
+			<bitfield name="PACK_3D" low="20" high="21" type="mdp5_pack_3d"/>
+		</reg32>
+		<reg32 offset="0x018" name="FLUSH">
+			<bitfield name="VIG0" pos="0"  type="boolean"/>
+			<bitfield name="VIG1" pos="1"  type="boolean"/>
+			<bitfield name="VIG2" pos="2"  type="boolean"/>
+			<bitfield name="RGB0" pos="3"  type="boolean"/>
+			<bitfield name="RGB1" pos="4"  type="boolean"/>
+			<bitfield name="RGB2" pos="5"  type="boolean"/>
+			<bitfield name="LM0"  pos="6"  type="boolean"/>
+			<bitfield name="LM1"  pos="7"  type="boolean"/>
+			<bitfield name="LM2"  pos="8"  type="boolean"/>
+			<bitfield name="LM3"  pos="9"  type="boolean"/>
+			<bitfield name="LM4"  pos="10"  type="boolean"/>
+			<bitfield name="DMA0" pos="11" type="boolean"/>
+			<bitfield name="DMA1" pos="12" type="boolean"/>
+			<bitfield name="DSPP0" pos="13" type="boolean"/>
+			<bitfield name="DSPP1" pos="14" type="boolean"/>
+			<bitfield name="DSPP2" pos="15" type="boolean"/>
+			<bitfield name="WB"   pos="16" type="boolean"/>
+			<bitfield name="CTL"   pos="17" type="boolean"/>
+			<bitfield name="VIG3" pos="18"  type="boolean"/>
+			<bitfield name="RGB3" pos="19"  type="boolean"/>
+			<bitfield name="LM5"  pos="20"  type="boolean"/>
+			<bitfield name="DSPP3" pos="21" type="boolean"/>
+			<bitfield name="CURSOR_0" pos="22" type="boolean"/>
+			<bitfield name="CURSOR_1" pos="23" type="boolean"/>
+			<bitfield name="CHROMADOWN_0" pos="26" type="boolean"/>
+			<bitfield name="TIMING_3" pos="28" type="boolean"/>
+			<bitfield name="TIMING_2" pos="29" type="boolean"/>
+			<bitfield name="TIMING_1" pos="30" type="boolean"/>
+			<bitfield name="TIMING_0" pos="31" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x01C" name="START"/>
+		<reg32 offset="0x020" name="PACK_3D"/>
+		<array offsets="0x040,0x044,0x048,0x04C,0x050,0x054" name="LAYER_EXT" length="6" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="VIG0_BIT3"  pos="0"  type="boolean"/>
+				<bitfield name="VIG1_BIT3"  pos="2"  type="boolean"/>
+				<bitfield name="VIG2_BIT3"  pos="4"  type="boolean"/>
+				<bitfield name="VIG3_BIT3"  pos="6"  type="boolean"/>
+				<bitfield name="RGB0_BIT3"  pos="8"  type="boolean"/>
+				<bitfield name="RGB1_BIT3"  pos="10"  type="boolean"/>
+				<bitfield name="RGB2_BIT3"  pos="12"  type="boolean"/>
+				<bitfield name="RGB3_BIT3"  pos="14"  type="boolean"/>
+				<bitfield name="DMA0_BIT3"  pos="16"  type="boolean"/>
+				<bitfield name="DMA1_BIT3"  pos="18"  type="boolean"/>
+				<bitfield name="CURSOR0" low="20"  high="23"  type="mdp_mixer_stage_id"/>
+				<bitfield name="CURSOR1" low="26"  high="29"  type="mdp_mixer_stage_id"/>
+			</reg32>
+		</array>
+	</array>
+
+	<enum name="mdp5_data_format">
+		<value name="DATA_FORMAT_RGB" value="0"/>
+		<value name="DATA_FORMAT_YUV" value="1"/>
+	</enum>
+
+	<array doffsets="INVALID_IDX(idx),mdp5_cfg->pipe_vig.base[0],mdp5_cfg->pipe_vig.base[1],mdp5_cfg->pipe_vig.base[2],mdp5_cfg->pipe_rgb.base[0],mdp5_cfg->pipe_rgb.base[1],mdp5_cfg->pipe_rgb.base[2],mdp5_cfg->pipe_dma.base[0],mdp5_cfg->pipe_dma.base[1],mdp5_cfg->pipe_vig.base[3],mdp5_cfg->pipe_rgb.base[3],mdp5_cfg->pipe_cursor.base[0],mdp5_cfg->pipe_cursor.base[1]" name="PIPE" length="10" stride="0x400" index="mdp5_pipe">
+		<reg32 offset="0x200" name="OP_MODE">
+			<bitfield name="CSC_DST_DATA_FORMAT" pos="19" type="mdp5_data_format"/>
+			<bitfield name="CSC_SRC_DATA_FORMAT" pos="18" type="mdp5_data_format"/>
+			<bitfield name="CSC_1_EN" pos="17" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x2C4" name="HIST_CTL_BASE"/>
+		<reg32 offset="0x2F0" name="HIST_LUT_BASE"/>
+		<reg32 offset="0x300" name="HIST_LUT_SWAP"/>
+		<reg32 offset="0x320" name="CSC_1_MATRIX_COEFF_0">
+			<bitfield name="COEFF_11" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_12" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x324" name="CSC_1_MATRIX_COEFF_1">
+			<bitfield name="COEFF_13" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_21" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x328" name="CSC_1_MATRIX_COEFF_2">
+			<bitfield name="COEFF_22" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_23" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x32c" name="CSC_1_MATRIX_COEFF_3">
+			<bitfield name="COEFF_31" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_32" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x330" name="CSC_1_MATRIX_COEFF_4">
+			<bitfield name="COEFF_33" low="0" high="12" type="uint"/>
+		</reg32>
+		<array offset="0x334" name="CSC_1_PRE_CLAMP" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="HIGH"  low="0"  high="7"  type="uint"/>
+				<bitfield name="LOW"  low="8"  high="15"  type="uint"/>
+			</reg32>
+		</array>
+		<array offset="0x340" name="CSC_1_POST_CLAMP" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="HIGH"  low="0"  high="7"  type="uint"/>
+				<bitfield name="LOW"  low="8"  high="15"  type="uint"/>
+			</reg32>
+		</array>
+		<array offset="0x34c" name="CSC_1_PRE_BIAS" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="VALUE"  low="0"  high="8"  type="uint"/>
+			</reg32>
+		</array>
+		<array offset="0x358" name="CSC_1_POST_BIAS" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="VALUE"  low="0"  high="8"  type="uint"/>
+			</reg32>
+		</array>
+		<!-- SSPP: -->
+		<reg32 offset="0x000" name="SRC_SIZE" type="reg_wh"/>
+		<reg32 offset="0x004" name="SRC_IMG_SIZE" type="reg_wh"/>
+		<reg32 offset="0x008" name="SRC_XY" type="reg_xy"/>
+		<reg32 offset="0x00C" name="OUT_SIZE" type="reg_wh"/>
+		<reg32 offset="0x010" name="OUT_XY" type="reg_xy"/>
+		<reg32 offset="0x014" name="SRC0_ADDR"/>
+		<reg32 offset="0x018" name="SRC1_ADDR"/>
+		<reg32 offset="0x01C" name="SRC2_ADDR"/>
+		<reg32 offset="0x020" name="SRC3_ADDR"/>
+		<reg32 offset="0x024" name="SRC_STRIDE_A">
+			<bitfield name="P0" low="0" high="15" type="uint"/>
+			<bitfield name="P1" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x028" name="SRC_STRIDE_B">
+			<bitfield name="P2" low="0" high="15" type="uint"/>
+			<bitfield name="P3" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x02C" name="STILE_FRAME_SIZE"/>
+		<reg32 offset="0x030" name="SRC_FORMAT">
+			<bitfield name="G_BPC" low="0" high="1" type="mdp_bpc"/>
+			<bitfield name="B_BPC" low="2" high="3" type="mdp_bpc"/>
+			<bitfield name="R_BPC" low="4" high="5" type="mdp_bpc"/>
+			<bitfield name="A_BPC" low="6" high="7" type="mdp_bpc_alpha"/>
+			<bitfield name="ALPHA_ENABLE" pos="8" type="boolean"/>
+			<bitfield name="CPP" low="9" high="10" type="uint">
+				<brief>8bit characters per pixel minus 1</brief>
+			</bitfield>
+			<bitfield name="ROT90" pos="11" type="boolean"/>
+			<bitfield name="UNPACK_COUNT" low="12" high="13" type="uint"/>
+			<bitfield name="UNPACK_TIGHT" pos="17" type="boolean"/>
+			<bitfield name="UNPACK_ALIGN_MSB" pos="18" type="boolean"/>
+			<bitfield name="FETCH_TYPE" low="19" high="20" type="mdp_fetch_type"/>
+			<bitfield name="CHROMA_SAMP" low="23" high="24" type="mdp_chroma_samp_type"/>
+		</reg32>
+		<reg32 offset="0x034" name="SRC_UNPACK" type="mdp_unpack_pattern"/>
+		<reg32 offset="0x038" name="SRC_OP_MODE">
+			<bitfield name="BWC_EN" pos="0" type="boolean"/>
+			<bitfield name="BWC" low="1" high="2" type="mdp5_pipe_bwc"/>
+			<bitfield name="FLIP_LR" pos="13" type="boolean"/>
+			<bitfield name="FLIP_UD" pos="14" type="boolean"/>
+			<bitfield name="IGC_EN" pos="16" type="boolean"/>
+			<bitfield name="IGC_ROM_0" pos="17" type="boolean"/>
+			<bitfield name="IGC_ROM_1" pos="18" type="boolean"/>
+			<bitfield name="DEINTERLACE" pos="22" type="boolean"/>
+			<bitfield name="DEINTERLACE_ODD" pos="23" type="boolean"/>
+			<bitfield name="SW_PIX_EXT_OVERRIDE" pos="31" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x03c" name="SRC_CONSTANT_COLOR"/>
+		<reg32 offset="0x048" name="FETCH_CONFIG"/>
+		<reg32 offset="0x04c" name="VC1_RANGE"/>
+		<reg32 offset="0x050" name="REQPRIO_FIFO_WM_0"/>
+		<reg32 offset="0x054" name="REQPRIO_FIFO_WM_1"/>
+		<reg32 offset="0x058" name="REQPRIO_FIFO_WM_2"/>
+		<reg32 offset="0x070" name="SRC_ADDR_SW_STATUS"/>
+		<reg32 offset="0x0a4" name="CURRENT_SRC0_ADDR"/>
+		<reg32 offset="0x0a8" name="CURRENT_SRC1_ADDR"/>
+		<reg32 offset="0x0ac" name="CURRENT_SRC2_ADDR"/>
+		<reg32 offset="0x0b0" name="CURRENT_SRC3_ADDR"/>
+		<reg32 offset="0x0b4" name="DECIMATION">
+			<bitfield name="VERT" low="0" high="7" type="uint"/>
+			<bitfield name="HORZ" low="8" high="15" type="uint"/>
+		</reg32>
+		<array offsets="0x100,0x110,0x120" name="SW_PIX_EXT" length="3" stride="0x10" index="mdp_component_type">
+			<!--
+				Notes:
+				o These value only take effect if SW_PIX_EXT_OVERRIDE is set in SRC_OP_MODE register
+				o For signed values (int): + indicates overfetch, - indicates line drop
+			-->
+                        <reg32 offset="0x00" name="LR">
+				<bitfield name="LEFT_RPT" low="0" high="7" type="uint"/>
+				<bitfield name="LEFT_OVF" low="8" high="15" type="int"/>
+				<bitfield name="RIGHT_RPT" low="16" high="23" type="uint"/>
+				<bitfield name="RIGHT_OVF" low="24" high="31" type="int"/>
+			</reg32>
+			<reg32 offset="0x04" name="TB">
+				<bitfield name="TOP_RPT" low="0" high="7" type="uint"/>
+				<bitfield name="TOP_OVF" low="8" high="15" type="int"/>
+				<bitfield name="BOTTOM_RPT" low="16" high="23" type="uint"/>
+				<bitfield name="BOTTOM_OVF" low="24" high="31" type="int"/>
+			</reg32>
+			<reg32 offset="0x08" name="REQ_PIXELS">
+				<bitfield name="LEFT_RIGHT" low="0" high="15" type="uint"/>
+				<bitfield name="TOP_BOTTOM" low="16" high="31" type="uint"/>
+			</reg32>
+		</array>
+		<reg32 offset="0x204" name="SCALE_CONFIG">
+			<bitfield name="SCALEX_EN" pos="0" type="boolean"/>
+			<bitfield name="SCALEY_EN" pos="1" type="boolean"/>
+			<bitfield name="SCALEX_FILTER_COMP_0" low="8"  high="9"  type="mdp5_scale_filter"/>
+			<bitfield name="SCALEY_FILTER_COMP_0" low="10" high="11" type="mdp5_scale_filter"/>
+			<bitfield name="SCALEX_FILTER_COMP_1_2"  low="12" high="13" type="mdp5_scale_filter"/>
+			<bitfield name="SCALEY_FILTER_COMP_1_2"  low="14" high="15" type="mdp5_scale_filter"/>
+			<bitfield name="SCALEX_FILTER_COMP_3" low="16" high="17" type="mdp5_scale_filter"/>
+			<bitfield name="SCALEY_FILTER_COMP_3" low="18" high="19" type="mdp5_scale_filter"/>
+		</reg32>
+		<reg32 offset="0x210" name="SCALE_PHASE_STEP_X"/>
+		<reg32 offset="0x214" name="SCALE_PHASE_STEP_Y"/>
+		<reg32 offset="0x218" name="SCALE_CR_PHASE_STEP_X"/>
+		<reg32 offset="0x21c" name="SCALE_CR_PHASE_STEP_Y"/>
+		<reg32 offset="0x220" name="SCALE_INIT_PHASE_X"/>
+		<reg32 offset="0x224" name="SCALE_INIT_PHASE_Y"/>
+	</array>
+
+	<array doffsets="mdp5_cfg->lm.base[0],mdp5_cfg->lm.base[1],mdp5_cfg->lm.base[2],mdp5_cfg->lm.base[3],mdp5_cfg->lm.base[4],mdp5_cfg->lm.base[5]" name="LM" length="6" stride="0x400">
+		<reg32 offset="0x000" name="BLEND_COLOR_OUT">
+			<bitfield name="STAGE0_FG_ALPHA" pos="1" type="boolean"/>
+			<bitfield name="STAGE1_FG_ALPHA" pos="2" type="boolean"/>
+			<bitfield name="STAGE2_FG_ALPHA" pos="3" type="boolean"/>
+			<bitfield name="STAGE3_FG_ALPHA" pos="4" type="boolean"/>
+			<bitfield name="STAGE4_FG_ALPHA" pos="5" type="boolean"/>
+			<bitfield name="STAGE5_FG_ALPHA" pos="6" type="boolean"/>
+			<bitfield name="STAGE6_FG_ALPHA" pos="7" type="boolean"/>
+			<bitfield name="SPLIT_LEFT_RIGHT" pos="31" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x004" name="OUT_SIZE" type="reg_wh"/>
+		<reg32 offset="0x008" name="BORDER_COLOR_0"/>
+		<reg32 offset="0x010" name="BORDER_COLOR_1"/>
+		<array offsets="0x020,0x050,0x080,0x0B0,0x230,0x260,0x290" name="BLEND" length="7" stride="0x30">
+			<reg32 offset="0x00" name="OP_MODE">
+				<bitfield name="FG_ALPHA" low="0" high="1" type="mdp_alpha_type"/>
+				<bitfield name="FG_INV_ALPHA"     pos="2"  type="boolean"/>
+				<bitfield name="FG_MOD_ALPHA"     pos="3"  type="boolean"/>
+				<bitfield name="FG_INV_MOD_ALPHA" pos="4"  type="boolean"/>
+				<bitfield name="FG_TRANSP_EN"     pos="5"  type="boolean"/>
+				<bitfield name="BG_ALPHA" low="8" high="9" type="mdp_alpha_type"/>
+				<bitfield name="BG_INV_ALPHA"     pos="10" type="boolean"/>
+				<bitfield name="BG_MOD_ALPHA"     pos="11" type="boolean"/>
+				<bitfield name="BG_INV_MOD_ALPHA" pos="12" type="boolean"/>
+				<bitfield name="BG_TRANSP_EN"     pos="13" type="boolean"/>
+			</reg32>
+			<reg32 offset="0x04" name="FG_ALPHA"/>
+			<reg32 offset="0x08" name="BG_ALPHA"/>
+			<reg32 offset="0x0c" name="FG_TRANSP_LOW0"/>
+			<reg32 offset="0x10" name="FG_TRANSP_LOW1"/>
+			<reg32 offset="0x14" name="FG_TRANSP_HIGH0"/>
+			<reg32 offset="0x18" name="FG_TRANSP_HIGH1"/>
+			<reg32 offset="0x1c" name="BG_TRANSP_LOW0"/>
+			<reg32 offset="0x20" name="BG_TRANSP_LOW1"/>
+			<reg32 offset="0x24" name="BG_TRANSP_HIGH0"/>
+			<reg32 offset="0x28" name="BG_TRANSP_HIGH1"/>
+		</array>
+		<reg32 offset="0x0e0" name="CURSOR_IMG_SIZE">
+			<bitfield name="SRC_W" low="0" high="15" type="uint"/>
+			<bitfield name="SRC_H" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0e4" name="CURSOR_SIZE">
+			<bitfield name="ROI_W" low="0" high="15" type="uint"/>
+			<bitfield name="ROI_H" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0e8" name="CURSOR_XY">
+			<bitfield name="SRC_X" low="0" high="15" type="uint"/>
+			<bitfield name="SRC_Y" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0dc" name="CURSOR_STRIDE">
+			<bitfield name="STRIDE" low="0"  high="15"  type="uint"/>
+		</reg32>
+		<reg32 offset="0x0ec" name="CURSOR_FORMAT">
+			<bitfield name="FORMAT" low="0"  high="2"  type="mdp5_cursor_format"/>
+		</reg32>
+		<reg32 offset="0x0f0" name="CURSOR_BASE_ADDR"/>
+		<reg32 offset="0x0f4" name="CURSOR_START_XY">
+			<bitfield name="X_START" low="0" high="15" type="uint"/>
+			<bitfield name="Y_START" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x0f8" name="CURSOR_BLEND_CONFIG">
+			<bitfield name="BLEND_EN" pos="0" type="boolean"/>
+			<bitfield name="BLEND_ALPHA_SEL" low="1"  high="2"  type="mdp5_cursor_alpha"/>
+			<bitfield name="BLEND_TRANSP_EN" pos="3" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x0fc" name="CURSOR_BLEND_PARAM"/>
+		<reg32 offset="0x100" name="CURSOR_BLEND_TRANSP_LOW0"/>
+		<reg32 offset="0x104" name="CURSOR_BLEND_TRANSP_LOW1"/>
+		<reg32 offset="0x108" name="CURSOR_BLEND_TRANSP_HIGH0"/>
+		<reg32 offset="0x10c" name="CURSOR_BLEND_TRANSP_HIGH1"/>
+		<reg32 offset="0x110" name="GC_LUT_BASE"/>
+	</array>
+
+	<array doffsets="mdp5_cfg->dspp.base[0],mdp5_cfg->dspp.base[1],mdp5_cfg->dspp.base[2],mdp5_cfg->dspp.base[3]" name="DSPP" length="4" stride="0x400">
+		<reg32 offset="0x000" name="OP_MODE">
+			<bitfield name="IGC_LUT_EN" pos="0" type="boolean"/>
+			<bitfield name="IGC_TBL_IDX" low="1" high="3" type="uint"/>
+			<bitfield name="PCC_EN" pos="4" type="boolean"/>
+			<bitfield name="DITHER_EN" pos="8" type="boolean"/>
+			<bitfield name="HIST_EN" pos="16" type="boolean"/>
+			<bitfield name="AUTO_CLEAR" pos="17" type="boolean"/>
+			<bitfield name="HIST_LUT_EN" pos="19" type="boolean"/>
+			<bitfield name="PA_EN" pos="20" type="boolean"/>
+			<bitfield name="GAMUT_EN" pos="23" type="boolean"/>
+			<bitfield name="GAMUT_ORDER" pos="24" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x030" name="PCC_BASE"/>
+		<reg32 offset="0x150" name="DITHER_DEPTH"/>
+		<reg32 offset="0x210" name="HIST_CTL_BASE"/>
+		<reg32 offset="0x230" name="HIST_LUT_BASE"/>
+		<reg32 offset="0x234" name="HIST_LUT_SWAP"/>
+		<reg32 offset="0x238" name="PA_BASE"/>
+		<reg32 offset="0x2dc" name="GAMUT_BASE"/>
+		<reg32 offset="0x2b0" name="GC_BASE"/>
+	</array>
+
+	<array doffsets="mdp5_cfg->pp.base[0],mdp5_cfg->pp.base[1],mdp5_cfg->pp.base[2],mdp5_cfg->pp.base[3]" name="PP" length="4" stride="0x100">
+		<reg32 offset="0x000" name="TEAR_CHECK_EN"/>
+		<reg32 offset="0x004" name="SYNC_CONFIG_VSYNC">
+			<bitfield name="COUNT" low="0" high="18" type="uint"/>
+			<bitfield name="COUNTER_EN" pos="19" type="boolean"/>
+			<bitfield name="IN_EN" pos="20" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x008" name="SYNC_CONFIG_HEIGHT"/>
+		<reg32 offset="0x00c" name="SYNC_WRCOUNT">
+			<bitfield name="LINE_COUNT" low="0" high="15" type="uint"/>
+			<bitfield name="FRAME_COUNT" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x010" name="VSYNC_INIT_VAL"/>
+		<reg32 offset="0x014" name="INT_COUNT_VAL">
+			<bitfield name="LINE_COUNT" low="0" high="15" type="uint"/>
+			<bitfield name="FRAME_COUNT" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x018" name="SYNC_THRESH">
+			<bitfield name="START" low="0" high="15" type="uint"/>
+			<bitfield name="CONTINUE" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x01c" name="START_POS"/>
+		<reg32 offset="0x020" name="RD_PTR_IRQ"/>
+		<reg32 offset="0x024" name="WR_PTR_IRQ"/>
+		<reg32 offset="0x028" name="OUT_LINE_COUNT"/>
+		<reg32 offset="0x02c" name="PP_LINE_COUNT"/>
+		<reg32 offset="0x030" name="AUTOREFRESH_CONFIG"/>
+		<reg32 offset="0x034" name="FBC_MODE"/>
+		<reg32 offset="0x038" name="FBC_BUDGET_CTL"/>
+		<reg32 offset="0x03c" name="FBC_LOSSY_MODE"/>
+	</array>
+
+	<enum name="mdp5_block_size">
+		<value name="BLOCK_SIZE_64" value="0"/>
+		<value name="BLOCK_SIZE_128" value="1"/>
+	</enum>
+
+	<enum name="mdp5_rotate_mode">
+		<value name="ROTATE_0" value="0"/>
+		<value name="ROTATE_90" value="1"/>
+	</enum>
+
+	<enum name="mdp5_chroma_downsample_method">
+		<value name="DS_MTHD_NO_PIXEL_DROP" value="0"/>
+		<value name="DS_MTHD_PIXEL_DROP" value="1"/>
+	</enum>
+
+	<array doffsets="mdp5_cfg->wb.base[0],mdp5_cfg->wb.base[1],mdp5_cfg->wb.base[2],mdp5_cfg->wb.base[3],mdp5_cfg->wb.base[4]" name="WB" length="5" stride="0x400">
+		<reg32 offset="0x000" name="DST_FORMAT">
+			<bitfield name="DSTC0_OUT" low="0" high="1" type="uint"/>
+			<bitfield name="DSTC1_OUT" low="2" high="3" type="uint"/>
+			<bitfield name="DSTC2_OUT" low="4" high="5" type="uint"/>
+			<bitfield name="DSTC3_OUT" low="6" high="7" type="uint"/>
+			<bitfield name="DSTC3_EN" pos="8" type="boolean"/>
+			<bitfield name="DST_BPP" low="9" high="10" type="uint"/>
+			<bitfield name="PACK_COUNT" low="12" high="13" type="uint"/>
+			<bitfield name="DST_ALPHA_X" pos="14" type="boolean"/>
+			<bitfield name="PACK_TIGHT" pos="17" type="boolean"/>
+			<bitfield name="PACK_ALIGN_MSB" pos="18" type="boolean"/>
+			<bitfield name="WRITE_PLANES" low="19" high="20" type="uint"/>
+			<bitfield name="DST_DITHER_EN" pos="22" type="boolean"/>
+			<bitfield name="DST_CHROMA_SAMP" low="23" high="25" type="uint"/>
+			<bitfield name="DST_CHROMA_SITE" low="26" high="29" type="uint"/>
+			<bitfield name="FRAME_FORMAT" low="30" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x004" name="DST_OP_MODE">
+			<bitfield name="BWC_ENC_EN" pos="0" type="boolean"/>
+			<bitfield name="BWC_ENC_OP" low="1" high="2" type="uint"/>
+			<bitfield name="BLOCK_SIZE" low="4" high="4" type="uint"/>
+			<bitfield name="ROT_MODE" low="5" high="5" type="uint"/>
+			<bitfield name="ROT_EN" pos="6" type="boolean"/>
+			<bitfield name="CSC_EN" pos="8" type="boolean"/>
+			<bitfield name="CSC_SRC_DATA_FORMAT" low="9" high="9" type="uint"/>
+			<bitfield name="CSC_DST_DATA_FORMAT" low="10" high="10" type="uint"/>
+			<bitfield name="CHROMA_DWN_SAMPLE_EN" pos="11" type="boolean"/>
+			<bitfield name="CHROMA_DWN_SAMPLE_FORMAT" low="12" high="12" type="uint"/>
+			<bitfield name="CHROMA_DWN_SAMPLE_H_MTHD" low="13" high="13" type="uint"/>
+			<bitfield name="CHROMA_DWN_SAMPLE_V_MTHD" low="14" high="14" type="uint"/>
+		</reg32>
+		<reg32 offset="0x008" name="DST_PACK_PATTERN">
+			<bitfield name="ELEMENT0" low="0" high="1" type="uint"/>
+			<bitfield name="ELEMENT1" low="8" high="9" type="uint"/>
+			<bitfield name="ELEMENT2" low="16" high="17" type="uint"/>
+			<bitfield name="ELEMENT3" low="24" high="25" type="uint"/>
+		</reg32>
+		<reg32 offset="0x00c" name="DST0_ADDR"/>
+		<reg32 offset="0x010" name="DST1_ADDR"/>
+		<reg32 offset="0x014" name="DST2_ADDR"/>
+		<reg32 offset="0x018" name="DST3_ADDR"/>
+		<reg32 offset="0x01c" name="DST_YSTRIDE0">
+			<bitfield name="DST0_YSTRIDE" low="0" high="15" type="uint"/>
+			<bitfield name="DST1_YSTRIDE" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x020" name="DST_YSTRIDE1">
+			<bitfield name="DST2_YSTRIDE" low="0" high="15" type="uint"/>
+			<bitfield name="DST3_YSTRIDE" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x024" name="DST_DITHER_BITDEPTH"/>
+		<reg32 offset="0x030" name="DITHER_MATRIX_ROW0"/>
+		<reg32 offset="0x034" name="DITHER_MATRIX_ROW1"/>
+		<reg32 offset="0x038" name="DITHER_MATRIX_ROW2"/>
+		<reg32 offset="0x03c" name="DITHER_MATRIX_ROW3"/>
+		<reg32 offset="0x048" name="DST_WRITE_CONFIG"/>
+		<reg32 offset="0x050" name="ROTATION_DNSCALER"/>
+		<reg32 offset="0x060" name="N16_INIT_PHASE_X_0_3"/>
+		<reg32 offset="0x064" name="N16_INIT_PHASE_X_1_2"/>
+		<reg32 offset="0x068" name="N16_INIT_PHASE_Y_0_3"/>
+		<reg32 offset="0x06c" name="N16_INIT_PHASE_Y_1_2"/>
+		<reg32 offset="0x074" name="OUT_SIZE">
+			<bitfield name="DST_W" low="0" high="15" type="uint"/>
+			<bitfield name="DST_H" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x078" name="ALPHA_X_VALUE"/>
+		<reg32 offset="0x260" name="CSC_MATRIX_COEFF_0">
+			<bitfield name="COEFF_11" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_12" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x264" name="CSC_MATRIX_COEFF_1">
+			<bitfield name="COEFF_13" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_21" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x268" name="CSC_MATRIX_COEFF_2">
+			<bitfield name="COEFF_22" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_23" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x26c" name="CSC_MATRIX_COEFF_3">
+			<bitfield name="COEFF_31" low="0" high="12" type="uint"/>
+			<bitfield name="COEFF_32" low="16" high="28" type="uint"/>
+		</reg32>
+		<reg32 offset="0x270" name="CSC_MATRIX_COEFF_4">
+			<bitfield name="COEFF_33" low="0" high="12" type="uint"/>
+		</reg32>
+		<array offset="0x274" name="CSC_COMP_PRECLAMP" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="HIGH"  low="0"  high="7"  type="uint"/>
+				<bitfield name="LOW"  low="8"  high="15"  type="uint"/>
+			</reg32>
+		</array>
+		<array offset="0x280" name="CSC_COMP_POSTCLAMP" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="HIGH"  low="0"  high="7"  type="uint"/>
+				<bitfield name="LOW"  low="8"  high="15"  type="uint"/>
+			</reg32>
+		</array>
+		<array offset="0x28c" name="CSC_COMP_PREBIAS" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="VALUE"  low="0"  high="8"  type="uint"/>
+			</reg32>
+		</array>
+		<array offset="0x298" name="CSC_COMP_POSTBIAS" length="3" stride="4">
+			<reg32 offset="0" name="REG">
+				<bitfield name="VALUE"  low="0"  high="8"  type="uint"/>
+			</reg32>
+		</array>
+	</array>
+
+	<array doffsets="mdp5_cfg->intf.base[0],mdp5_cfg->intf.base[1],mdp5_cfg->intf.base[2],mdp5_cfg->intf.base[3],mdp5_cfg->intf.base[4]" name="INTF" length="5" stride="0x200">
+		<reg32 offset="0x000" name="TIMING_ENGINE_EN"/>
+		<reg32 offset="0x004" name="CONFIG"/>
+		<reg32 offset="0x008" name="HSYNC_CTL">
+			<bitfield name="PULSEW" low="0" high="15" type="uint"/>
+			<bitfield name="PERIOD" low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x00c" name="VSYNC_PERIOD_F0" type="uint"/>
+		<reg32 offset="0x010" name="VSYNC_PERIOD_F1" type="uint"/>
+		<reg32 offset="0x014" name="VSYNC_LEN_F0" type="uint"/>
+		<reg32 offset="0x018" name="VSYNC_LEN_F1" type="uint"/>
+		<reg32 offset="0x01c" name="DISPLAY_VSTART_F0" type="uint"/>
+		<reg32 offset="0x020" name="DISPLAY_VSTART_F1" type="uint"/>
+		<reg32 offset="0x024" name="DISPLAY_VEND_F0" type="uint"/>
+		<reg32 offset="0x028" name="DISPLAY_VEND_F1" type="uint"/>
+		<reg32 offset="0x02c" name="ACTIVE_VSTART_F0">
+			<bitfield name="VAL" low="0" high="30" type="uint"/>
+			<bitfield name="ACTIVE_V_ENABLE" pos="31" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x030" name="ACTIVE_VSTART_F1">
+			<bitfield name="VAL" low="0" high="30" type="uint"/>
+		</reg32>
+		<reg32 offset="0x034" name="ACTIVE_VEND_F0" type="uint"/>
+		<reg32 offset="0x038" name="ACTIVE_VEND_F1" type="uint"/>
+		<reg32 offset="0x03c" name="DISPLAY_HCTL">
+			<bitfield name="START" low="0"  high="15" type="uint"/>
+			<bitfield name="END"   low="16" high="31" type="uint"/>
+		</reg32>
+		<reg32 offset="0x040" name="ACTIVE_HCTL">
+			<bitfield name="START" low="0"  high="14" type="uint"/>
+			<bitfield name="END"   low="16" high="30" type="uint"/>
+			<bitfield name="ACTIVE_H_ENABLE" pos="31" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x044" name="BORDER_COLOR"/>
+		<reg32 offset="0x048" name="UNDERFLOW_COLOR"/>
+		<reg32 offset="0x04c" name="HSYNC_SKEW"/>
+		<reg32 offset="0x050" name="POLARITY_CTL">
+			<bitfield name="HSYNC_LOW" pos="0" type="boolean"/>
+			<bitfield name="VSYNC_LOW" pos="1" type="boolean"/>
+			<bitfield name="DATA_EN_LOW" pos="2" type="boolean"/>
+		</reg32>
+		<reg32 offset="0x054" name="TEST_CTL"/>
+		<reg32 offset="0x058" name="TP_COLOR0"/>
+		<reg32 offset="0x05c" name="TP_COLOR1"/>
+		<reg32 offset="0x084" name="DSI_CMD_MODE_TRIGGER_EN"/>
+		<reg32 offset="0x090" name="PANEL_FORMAT" type="mdp5_format"/>
+		<reg32 offset="0x0a8" name="FRAME_LINE_COUNT_EN"/>
+		<reg32 offset="0x0ac" name="FRAME_COUNT"/>
+		<reg32 offset="0x0b0" name="LINE_COUNT"/>
+		<reg32 offset="0x0f0" name="DEFLICKER_CONFIG"/>
+		<reg32 offset="0x0f4" name="DEFLICKER_STRNG_COEFF"/>
+		<reg32 offset="0x0f8" name="DEFLICKER_WEAK_COEFF"/>
+		<reg32 offset="0x100" name="TPG_ENABLE"/>
+		<reg32 offset="0x104" name="TPG_MAIN_CONTROL"/>
+		<reg32 offset="0x108" name="TPG_VIDEO_CONFIG"/>
+		<reg32 offset="0x10c" name="TPG_COMPONENT_LIMITS"/>
+		<reg32 offset="0x110" name="TPG_RECTANGLE"/>
+		<reg32 offset="0x114" name="TPG_INITIAL_VALUE"/>
+		<reg32 offset="0x118" name="TPG_BLK_WHITE_PATTERN_FRAME"/>
+		<reg32 offset="0x11c" name="TPG_RGB_MAPPING"/>
+	</array>
+
+	<array doffsets="mdp5_cfg->ad.base[0],mdp5_cfg->ad.base[1]" name="AD" length="2" stride="0x200">
+		<reg32 offset="0x000" name="BYPASS"/>
+		<reg32 offset="0x004" name="CTRL_0"/>
+		<reg32 offset="0x008" name="CTRL_1"/>
+		<reg32 offset="0x00c" name="FRAME_SIZE"/>
+		<reg32 offset="0x010" name="CON_CTRL_0"/>
+		<reg32 offset="0x014" name="CON_CTRL_1"/>
+		<reg32 offset="0x018" name="STR_MAN"/>
+		<reg32 offset="0x01c" name="VAR"/>
+		<reg32 offset="0x020" name="DITH"/>
+		<reg32 offset="0x024" name="DITH_CTRL"/>
+		<reg32 offset="0x028" name="AMP_LIM"/>
+		<reg32 offset="0x02c" name="SLOPE"/>
+		<reg32 offset="0x030" name="BW_LVL"/>
+		<reg32 offset="0x034" name="LOGO_POS"/>
+		<reg32 offset="0x038" name="LUT_FI"/>
+		<reg32 offset="0x07c" name="LUT_CC"/>
+		<reg32 offset="0x0c8" name="STR_LIM"/>
+		<reg32 offset="0x0cc" name="CALIB_AB"/>
+		<reg32 offset="0x0d0" name="CALIB_CD"/>
+		<reg32 offset="0x0d4" name="MODE_SEL"/>
+		<reg32 offset="0x0d8" name="TFILT_CTRL"/>
+		<reg32 offset="0x0dc" name="BL_MINMAX"/>
+		<reg32 offset="0x0e0" name="BL"/>
+		<reg32 offset="0x0e8" name="BL_MAX"/>
+		<reg32 offset="0x0ec" name="AL"/>
+		<reg32 offset="0x0f0" name="AL_MIN"/>
+		<reg32 offset="0x0f4" name="AL_FILT"/>
+		<reg32 offset="0x0f8" name="CFG_BUF"/>
+		<reg32 offset="0x100" name="LUT_AL"/>
+		<reg32 offset="0x144" name="TARG_STR"/>
+		<reg32 offset="0x148" name="START_CALC"/>
+		<reg32 offset="0x14c" name="STR_OUT"/>
+		<reg32 offset="0x154" name="BL_OUT"/>
+		<reg32 offset="0x158" name="CALC_DONE"/>
+	</array>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/mdp_common.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/mdp_common.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+
+<!-- random bits that seem same between mdp4 and mdp5 (ie. not much) -->
+
+<enum name="mdp_chroma_samp_type">
+    <value name="CHROMA_FULL"  value="0"/>
+    <value name="CHROMA_H2V1" value="1"/>
+    <value name="CHROMA_H1V2" value="2"/>
+    <value name="CHROMA_420"  value="3"/>
+</enum>
+
+<enum name="mdp_fetch_type">
+    <value name="MDP_PLANE_INTERLEAVED"   value="0"/>
+    <value name="MDP_PLANE_PLANAR"        value="1"/>
+    <value name="MDP_PLANE_PSEUDO_PLANAR" value="2"/>
+</enum>
+
+<enum name="mdp_mixer_stage_id">
+	<value name="STAGE_UNUSED" value="0"/>
+	<value name="STAGE_BASE" value="1"/>
+	<value name="STAGE0" value="2"/>   <!-- zorder 0 -->
+	<value name="STAGE1" value="3"/>   <!-- zorder 1 -->
+	<value name="STAGE2" value="4"/>   <!-- zorder 2 -->
+	<value name="STAGE3" value="5"/>   <!-- zorder 3 -->
+	<value name="STAGE4" value="6"/>   <!-- zorder 4 -->
+	<value name="STAGE5" value="7"/>   <!-- zorder 5 -->
+	<value name="STAGE6" value="8"/>   <!-- zorder 6 -->
+	<value name="STAGE_MAX" value="8"/> <!-- maximum zorder -->
+</enum>
+
+<enum name="mdp_alpha_type">
+	<value name="FG_CONST" value="0"/>
+	<value name="BG_CONST" value="1"/>
+	<value name="FG_PIXEL" value="2"/>
+	<value name="BG_PIXEL" value="3"/>
+</enum>
+
+<enum name="mdp_component_type">
+        <value name="COMP_0" value="0"/>	<!-- Y component -->
+        <value name="COMP_1_2" value="1"/>	<!-- Cb/Cr comp. -->
+        <value name="COMP_3" value="2"/>	<!-- Trans comp. -->
+        <value name="COMP_MAX" value="3"/>
+</enum>
+
+<enum name="mdp_bpc">
+	<brief>bits per component (non-alpha channel)</brief>
+	<value name="BPC4" value="0"/> <!-- 4 bits -->
+	<value name="BPC5" value="1"/> <!-- 5 bits -->
+	<value name="BPC6" value="2"/> <!-- 6 bits -->
+	<value name="BPC8" value="3"/> <!-- 8 bits -->
+</enum>
+
+<enum name="mdp_bpc_alpha">
+	<brief>bits per component (alpha channel)</brief>
+	<value name="BPC1A" value="0"/> <!-- 1 bit -->
+	<value name="BPC4A" value="1"/> <!-- 4 bits -->
+	<value name="BPC6A" value="2"/> <!-- 6 bits -->
+	<value name="BPC8A" value="3"/> <!-- 8 bits -->
+</enum>
+
+<enum name="mdp_fetch_mode">
+	<value name="MDP_FETCH_LINEAR" value="0"/>
+	<value name="MDP_FETCH_TILE" value="1"/>
+	<value name="MDP_FETCH_UBWC" value="2"/>
+</enum>
+
+<bitset name="reg_wh" inline="yes">
+    <bitfield name="HEIGHT" low="16" high="31" type="uint"/>
+    <bitfield name="WIDTH" low="0" high="15" type="uint"/>
+</bitset>
+
+<bitset name="reg_xy" inline="yes">
+    <bitfield name="Y" low="16" high="31" type="uint"/>
+    <bitfield name="X" low="0" high="15" type="uint"/>
+</bitset>
+
+<bitset name="mdp_unpack_pattern" inline="yes">
+	<bitfield name="ELEM0" low="0"  high="7"/>
+	<bitfield name="ELEM1" low="8"  high="15"/>
+	<bitfield name="ELEM2" low="16" high="23"/>
+	<bitfield name="ELEM3" low="24" high="31"/>
+</bitset>
+
+</database>
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/mdss.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/mdss.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="MDSS" width="32">
+	<reg32 offset="0x00000" name="HW_VERSION">
+		<bitfield name="STEP" low="0" high="15" type="uint"/>
+		<bitfield name="MINOR" low="16" high="27" type="uint"/>
+		<bitfield name="MAJOR" low="28" high="31" type="uint"/>
+	</reg32>
+
+	<reg32 offset="0x00010" name="HW_INTR_STATUS">
+		<bitfield name="INTR_MDP"  pos="0"  type="boolean"/>
+		<bitfield name="INTR_DSI0" pos="4"  type="boolean"/>
+		<bitfield name="INTR_DSI1" pos="5"  type="boolean"/>
+		<bitfield name="INTR_HDMI" pos="8"  type="boolean"/>
+		<bitfield name="INTR_EDP"  pos="12" type="boolean"/>
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/msm.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/msm.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://nouveau.freedesktop.org/ rules-ng.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<doc>
+	Register definitions for the display related hw blocks on
+	msm/snapdragon
+</doc>
+
+<!--
+<enum name="chipset">
+	<value name="MDP40"/>
+	<value name="MDP50"/>
+</enum>
+-->
+
+<import file="mdp4.xml"/>
+<import file="mdp5.xml"/>
+<import file="dsi.xml"/>
+<import file="dsi_phy_28nm_8960.xml"/>
+<import file="dsi_phy_28nm.xml"/>
+<import file="dsi_phy_20nm.xml"/>
+<import file="dsi_phy_14nm.xml"/>
+<import file="dsi_phy_10nm.xml"/>
+<import file="dsi_phy_7nm.xml"/>
+<import file="sfpb.xml"/>
+<import file="hdmi.xml"/>
+<import file="edp.xml"/>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/display/sfpb.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/display/sfpb.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+<import file="freedreno_copyright.xml"/>
+
+<domain name="SFPB" width="32">
+	<enum name="sfpb_ahb_arb_master_port_en">
+		<value name="SFPB_MASTER_PORT_ENABLE" value="3"/>
+		<value name="SFPB_MASTER_PORT_DISABLE" value="0"/>
+	</enum>
+	<reg32 offset="0x0058" name="GPREG">
+		<bitfield name="MASTER_PORT_EN" low="11" high="12" type="sfpb_ahb_arb_master_port_en"/>
+	</reg32>
+</domain>
+
+</database>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/freedreno_copyright.xml
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/freedreno_copyright.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<database xmlns="http://nouveau.freedesktop.org/"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="https://gitlab.freedesktop.org/freedreno/ rules-fd.xsd">
+
+<copyright year="2013">
+
+<author name="Rob Clark" email="robdclark@gmail.com"><nick name="robclark"/>
+Initial Author.
+</author>
+
+<author name="Ilia Mirkin" email="imirkin@alum.mit.edu"><nick name="imirkin"/>
+many a3xx/a4xx contributions
+</author>
+
+<license>
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+</license>
+
+</copyright>
+</database>
+
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/gen_header.py
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/gen_header.py
@@ -0,0 +1,971 @@
+#!/usr/bin/python3
+#
+# Copyright © 2019-2024 Google, Inc.
+#
+# SPDX-License-Identifier: MIT
+
+import xml.parsers.expat
+import sys
+import os
+import collections
+import argparse
+import time
+import datetime
+
+class Error(Exception):
+	def __init__(self, message):
+		self.message = message
+
+class Enum(object):
+	def __init__(self, name):
+		self.name = name
+		self.values = []
+
+	def has_name(self, name):
+		for (n, value) in self.values:
+			if n == name:
+				return True
+		return False
+
+	def names(self):
+		return [n for (n, value) in self.values]
+
+	def dump(self):
+		use_hex = False
+		for (name, value) in self.values:
+			if value > 0x1000:
+				use_hex = True
+
+		print("enum %s {" % self.name)
+		for (name, value) in self.values:
+			if use_hex:
+				print("\t%s = 0x%08x," % (name, value))
+			else:
+				print("\t%s = %d," % (name, value))
+		print("};\n")
+
+	def dump_pack_struct(self):
+		pass
+
+class Field(object):
+	def __init__(self, name, low, high, shr, type, parser):
+		self.name = name
+		self.low = low
+		self.high = high
+		self.shr = shr
+		self.type = type
+
+		builtin_types = [ None, "a3xx_regid", "boolean", "uint", "hex", "int", "fixed", "ufixed", "float", "address", "waddress" ]
+
+		maxpos = parser.current_bitsize - 1
+
+		if low < 0 or low > maxpos:
+			raise parser.error("low attribute out of range: %d" % low)
+		if high < 0 or high > maxpos:
+			raise parser.error("high attribute out of range: %d" % high)
+		if high < low:
+			raise parser.error("low is greater than high: low=%d, high=%d" % (low, high))
+		if self.type == "boolean" and not low == high:
+			raise parser.error("booleans should be 1 bit fields")
+		elif self.type == "float" and not (high - low == 31 or high - low == 15):
+			raise parser.error("floats should be 16 or 32 bit fields")
+		elif not self.type in builtin_types and not self.type in parser.enums:
+			raise parser.error("unknown type '%s'" % self.type)
+
+	def ctype(self, var_name):
+		if self.type == None:
+			type = "uint32_t"
+			val = var_name
+		elif self.type == "boolean":
+			type = "bool"
+			val = var_name
+		elif self.type == "uint" or self.type == "hex" or self.type == "a3xx_regid":
+			type = "uint32_t"
+			val = var_name
+		elif self.type == "int":
+			type = "int32_t"
+			val = var_name
+		elif self.type == "fixed":
+			type = "float"
+			val = "((int32_t)(%s * %d.0))" % (var_name, 1 << self.radix)
+		elif self.type == "ufixed":
+			type = "float"
+			val = "((uint32_t)(%s * %d.0))" % (var_name, 1 << self.radix)
+		elif self.type == "float" and self.high - self.low == 31:
+			type = "float"
+			val = "fui(%s)" % var_name
+		elif self.type == "float" and self.high - self.low == 15:
+			type = "float"
+			val = "_mesa_float_to_half(%s)" % var_name
+		elif self.type in [ "address", "waddress" ]:
+			type = "uint64_t"
+			val = var_name
+		else:
+			type = "enum %s" % self.type
+			val = var_name
+
+		if self.shr > 0:
+			val = "(%s >> %d)" % (val, self.shr)
+
+		return (type, val)
+
+def tab_to(name, value):
+	tab_count = (68 - (len(name) & ~7)) // 8
+	if tab_count <= 0:
+		tab_count = 1
+	print(name + ('\t' * tab_count) + value)
+
+def mask(low, high):
+	return ((0xffffffffffffffff >> (64 - (high + 1 - low))) << low)
+
+def field_name(reg, f):
+	if f.name:
+		name = f.name.lower()
+	else:
+		# We hit this path when a reg is defined with no bitset fields, ie.
+		# 	<reg32 offset="0x88db" name="RB_BLIT_DST_ARRAY_PITCH" low="0" high="28" shr="6" type="uint"/>
+		name = reg.name.lower()
+
+	if (name in [ "double", "float", "int" ]) or not (name[0].isalpha()):
+			name = "_" + name
+
+	return name
+
+# indices - array of (ctype, stride, __offsets_NAME)
+def indices_varlist(indices):
+	return ", ".join(["i%d" % i for i in range(len(indices))])
+
+def indices_prototype(indices):
+	return ", ".join(["%s i%d" % (ctype, idx)
+			for (idx, (ctype, stride, offset)) in  enumerate(indices)])
+
+def indices_strides(indices):
+	return " + ".join(["0x%x*i%d" % (stride, idx)
+					if stride else
+					"%s(i%d)" % (offset, idx)
+			for (idx, (ctype, stride, offset)) in  enumerate(indices)])
+
+class Bitset(object):
+	def __init__(self, name, template):
+		self.name = name
+		self.inline = False
+		if template:
+			self.fields = template.fields[:]
+		else:
+			self.fields = []
+
+	# Get address field if there is one in the bitset, else return None:
+	def get_address_field(self):
+		for f in self.fields:
+			if f.type in [ "address", "waddress" ]:
+				return f
+		return None
+
+	def dump_regpair_builder(self, reg):
+		print("#ifndef NDEBUG")
+		known_mask = 0
+		for f in self.fields:
+			known_mask |= mask(f.low, f.high)
+			if f.type in [ "boolean", "address", "waddress" ]:
+				continue
+			type, val = f.ctype("fields.%s" % field_name(reg, f))
+			print("    assert((%-40s & 0x%08x) == 0);" % (val, 0xffffffff ^ mask(0 , f.high - f.low)))
+		print("    assert((%-40s & 0x%08x) == 0);" % ("fields.unknown", known_mask))
+		print("#endif\n")
+
+		print("    return (struct fd_reg_pair) {")
+		if reg.array:
+			print("        .reg = REG_%s(__i)," % reg.full_name)
+		else:
+			print("        .reg = REG_%s," % reg.full_name)
+
+		print("        .value =")
+		for f in self.fields:
+			if f.type in [ "address", "waddress" ]:
+				continue
+			else:
+				type, val = f.ctype("fields.%s" % field_name(reg, f))
+				print("            (%-40s << %2d) |" % (val, f.low))
+		value_name = "dword"
+		if reg.bit_size == 64:
+			value_name = "qword"
+		print("            fields.unknown | fields.%s," % (value_name,))
+
+		address = self.get_address_field()
+		if address:
+			print("        .bo = fields.bo,")
+			print("        .is_address = true,")
+			if f.type == "waddress":
+				print("        .bo_write = true,")
+			print("        .bo_offset = fields.bo_offset,")
+			print("        .bo_shift = %d," % address.shr)
+			print("        .bo_low = %d," % address.low)
+
+		print("    };")
+
+	def dump_pack_struct(self, reg=None):
+		if not reg:
+			return
+
+		prefix = reg.full_name
+
+		print("struct %s {" % prefix)
+		for f in self.fields:
+			if f.type in [ "address", "waddress" ]:
+				tab_to("    __bo_type", "bo;")
+				tab_to("    uint32_t", "bo_offset;")
+				continue
+			name = field_name(reg, f)
+
+			type, val = f.ctype("var")
+
+			tab_to("    %s" % type, "%s;" % name)
+		if reg.bit_size == 64:
+			tab_to("    uint64_t", "unknown;")
+			tab_to("    uint64_t", "qword;")
+		else:
+			tab_to("    uint32_t", "unknown;")
+			tab_to("    uint32_t", "dword;")
+		print("};\n")
+
+		if reg.array:
+			print("static inline struct fd_reg_pair\npack_%s(uint32_t __i, struct %s fields)\n{" %
+				  (prefix, prefix))
+		else:
+			print("static inline struct fd_reg_pair\npack_%s(struct %s fields)\n{" %
+				  (prefix, prefix))
+
+		self.dump_regpair_builder(reg)
+
+		print("\n}\n")
+
+		if self.get_address_field():
+			skip = ", { .reg = 0 }"
+		else:
+			skip = ""
+
+		if reg.array:
+			print("#define %s(__i, ...) pack_%s(__i, __struct_cast(%s) { __VA_ARGS__ })%s\n" %
+				  (prefix, prefix, prefix, skip))
+		else:
+			print("#define %s(...) pack_%s(__struct_cast(%s) { __VA_ARGS__ })%s\n" %
+				  (prefix, prefix, prefix, skip))
+
+
+	def dump(self, prefix=None):
+		if prefix == None:
+			prefix = self.name
+		for f in self.fields:
+			if f.name:
+				name = prefix + "_" + f.name
+			else:
+				name = prefix
+
+			if not f.name and f.low == 0 and f.shr == 0 and not f.type in ["float", "fixed", "ufixed"]:
+				pass
+			elif f.type == "boolean" or (f.type == None and f.low == f.high):
+				tab_to("#define %s" % name, "0x%08x" % (1 << f.low))
+			else:
+				tab_to("#define %s__MASK" % name, "0x%08x" % mask(f.low, f.high))
+				tab_to("#define %s__SHIFT" % name, "%d" % f.low)
+				type, val = f.ctype("val")
+
+				print("static inline uint32_t %s(%s val)\n{" % (name, type))
+				if f.shr > 0:
+					print("\tassert(!(val & 0x%x));" % mask(0, f.shr - 1))
+				print("\treturn ((%s) << %s__SHIFT) & %s__MASK;\n}" % (val, name, name))
+		print()
+
+class Array(object):
+	def __init__(self, attrs, domain, variant, parent, index_type):
+		if "name" in attrs:
+			self.local_name = attrs["name"]
+		else:
+			self.local_name = ""
+		self.domain = domain
+		self.variant = variant
+		self.parent = parent
+		if self.parent:
+			self.name = self.parent.name + "_" + self.local_name
+		else:
+			self.name = self.local_name
+		if "offsets" in attrs:
+			self.offsets = map(lambda i: "0x%08x" % int(i, 0), attrs["offsets"].split(","))
+			self.fixed_offsets = True
+		elif "doffsets" in attrs:
+			self.offsets = map(lambda s: "(%s)" % s , attrs["doffsets"].split(","))
+			self.fixed_offsets = True
+		else:
+			self.offset = int(attrs["offset"], 0)
+			self.stride = int(attrs["stride"], 0)
+			self.fixed_offsets = False
+		if "index" in attrs:
+			self.index_type = index_type
+		else:
+			self.index_type = None
+		self.length = int(attrs["length"], 0)
+		if "usage" in attrs:
+			self.usages = attrs["usage"].split(',')
+		else:
+			self.usages = None
+
+	def index_ctype(self):
+		if not self.index_type:
+			return "uint32_t"
+		else:
+			return "enum %s" % self.index_type.name
+
+	# Generate array of (ctype, stride, __offsets_NAME)
+	def indices(self):
+		if self.parent:
+			indices = self.parent.indices()
+		else:
+			indices = []
+		if self.length != 1:
+			if self.fixed_offsets:
+				indices.append((self.index_ctype(), None, "__offset_%s" % self.local_name))
+			else:
+				indices.append((self.index_ctype(), self.stride, None))
+		return indices
+
+	def total_offset(self):
+		offset = 0
+		if not self.fixed_offsets:
+			offset += self.offset
+		if self.parent:
+			offset += self.parent.total_offset()
+		return offset
+
+	def dump(self):
+		proto = indices_varlist(self.indices())
+		strides = indices_strides(self.indices())
+		array_offset = self.total_offset()
+		if self.fixed_offsets:
+			print("static inline uint32_t __offset_%s(%s idx)" % (self.local_name, self.index_ctype()))
+			print("{\n\tswitch (idx) {")
+			if self.index_type:
+				for val, offset in zip(self.index_type.names(), self.offsets):
+					print("\t\tcase %s: return %s;" % (val, offset))
+			else:
+				for idx, offset in enumerate(self.offsets):
+					print("\t\tcase %d: return %s;" % (idx, offset))
+			print("\t\tdefault: return INVALID_IDX(idx);")
+			print("\t}\n}")
+		if proto == '':
+			tab_to("#define REG_%s_%s" % (self.domain, self.name), "0x%08x\n" % array_offset)
+		else:
+			tab_to("#define REG_%s_%s(%s)" % (self.domain, self.name, proto), "(0x%08x + %s )\n" % (array_offset, strides))
+
+	def dump_pack_struct(self):
+		pass
+
+	def dump_regpair_builder(self):
+		pass
+
+class Reg(object):
+	def __init__(self, attrs, domain, array, bit_size):
+		self.name = attrs["name"]
+		self.domain = domain
+		self.array = array
+		self.offset = int(attrs["offset"], 0)
+		self.type = None
+		self.bit_size = bit_size
+		if array:
+			self.name = array.name + "_" + self.name
+		self.full_name = self.domain + "_" + self.name
+		if "stride" in attrs:
+			self.stride = int(attrs["stride"], 0)
+			self.length = int(attrs["length"], 0)
+		else:
+			self.stride = None
+			self.length = None
+
+	# Generate array of (ctype, stride, __offsets_NAME)
+	def indices(self):
+		if self.array:
+			indices = self.array.indices()
+		else:
+			indices = []
+		if self.stride:
+			indices.append(("uint32_t", self.stride, None))
+		return indices
+
+	def total_offset(self):
+		if self.array:
+			return self.array.total_offset() + self.offset
+		else:
+			return self.offset
+
+	def dump(self):
+		proto = indices_prototype(self.indices())
+		strides = indices_strides(self.indices())
+		offset = self.total_offset()
+		if proto == '':
+			tab_to("#define REG_%s" % self.full_name, "0x%08x" % offset)
+		else:
+			print("static inline uint32_t REG_%s(%s) { return 0x%08x + %s; }" % (self.full_name, proto, offset, strides))
+
+		if self.bitset.inline:
+			self.bitset.dump(self.full_name)
+
+	def dump_pack_struct(self):
+		if self.bitset.inline:
+			self.bitset.dump_pack_struct(self)
+
+	def dump_regpair_builder(self):
+		if self.bitset.inline:
+			self.bitset.dump_regpair_builder(self)
+
+	def dump_py(self):
+		print("\tREG_%s = 0x%08x" % (self.full_name, self.offset))
+
+
+class Parser(object):
+	def __init__(self):
+		self.current_array = None
+		self.current_domain = None
+		self.current_prefix = None
+		self.current_prefix_type = None
+		self.current_stripe = None
+		self.current_bitset = None
+		self.current_bitsize = 32
+		# The varset attribute on the domain specifies the enum which
+		# specifies all possible hw variants:
+		self.current_varset = None
+		# Regs that have multiple variants.. we only generated the C++
+		# template based struct-packers for these
+		self.variant_regs = {}
+		# Information in which contexts regs are used, to be used in
+		# debug options
+		self.usage_regs = collections.defaultdict(list)
+		self.bitsets = {}
+		self.enums = {}
+		self.variants = set()
+		self.file = []
+		self.xml_files = []
+		self.copyright_year = None
+		self.authors = []
+		self.license = None
+
+	def error(self, message):
+		parser, filename = self.stack[-1]
+		return Error("%s:%d:%d: %s" % (filename, parser.CurrentLineNumber, parser.CurrentColumnNumber, message))
+
+	def prefix(self, variant=None):
+		if self.current_prefix_type == "variant" and variant:
+			return variant
+		elif self.current_stripe:
+			return self.current_stripe + "_" + self.current_domain
+		elif self.current_prefix:
+			return self.current_prefix + "_" + self.current_domain
+		else:
+			return self.current_domain
+
+	def parse_field(self, name, attrs):
+		try:
+			if "pos" in attrs:
+				high = low = int(attrs["pos"], 0)
+			elif "high" in attrs and "low" in attrs:
+				high = int(attrs["high"], 0)
+				low = int(attrs["low"], 0)
+			else:
+				low = 0
+				high = self.current_bitsize - 1
+
+			if "type" in attrs:
+				type = attrs["type"]
+			else:
+				type = None
+
+			if "shr" in attrs:
+				shr = int(attrs["shr"], 0)
+			else:
+				shr = 0
+
+			b = Field(name, low, high, shr, type, self)
+
+			if type == "fixed" or type == "ufixed":
+				b.radix = int(attrs["radix"], 0)
+
+			self.current_bitset.fields.append(b)
+		except ValueError as e:
+			raise self.error(e)
+
+	def parse_varset(self, attrs):
+		# Inherit the varset from the enclosing domain if not overriden:
+		varset = self.current_varset
+		if "varset" in attrs:
+			varset = self.enums[attrs["varset"]]
+		return varset
+
+	def parse_variants(self, attrs):
+		if not "variants" in attrs:
+				return None
+		variant = attrs["variants"].split(",")[0]
+		if "-" in variant:
+			variant = variant[:variant.index("-")]
+
+		varset = self.parse_varset(attrs)
+
+		assert varset.has_name(variant)
+
+		return variant
+
+	def add_all_variants(self, reg, attrs, parent_variant):
+		# TODO this should really handle *all* variants, including dealing
+		# with open ended ranges (ie. "A2XX,A4XX-") (we have the varset
+		# enum now to make that possible)
+		variant = self.parse_variants(attrs)
+		if not variant:
+			variant = parent_variant
+
+		if reg.name not in self.variant_regs:
+			self.variant_regs[reg.name] = {}
+		else:
+			# All variants must be same size:
+			v = next(iter(self.variant_regs[reg.name]))
+			assert self.variant_regs[reg.name][v].bit_size == reg.bit_size
+
+		self.variant_regs[reg.name][variant] = reg
+
+	def add_all_usages(self, reg, usages):
+		if not usages:
+			return
+
+		for usage in usages:
+			self.usage_regs[usage].append(reg)
+
+		self.variants.add(reg.domain)
+
+	def do_validate(self, schemafile):
+		if not self.validate:
+			return
+
+		try:
+			from lxml import etree
+
+			parser, filename = self.stack[-1]
+			dirname = os.path.dirname(filename)
+
+			# we expect this to look like <namespace url> schema.xsd.. I think
+			# technically it is supposed to be just a URL, but that doesn't
+			# quite match up to what we do.. Just skip over everything up to
+			# and including the first whitespace character:
+			schemafile = schemafile[schemafile.rindex(" ")+1:]
+
+			# this is a bit cheezy, but the xml file to validate could be
+			# in a child director, ie. we don't really know where the schema
+			# file is, the way the rnn C code does.  So if it doesn't exist
+			# just look one level up
+			if not os.path.exists(dirname + "/" + schemafile):
+				schemafile = "../" + schemafile
+
+			if not os.path.exists(dirname + "/" + schemafile):
+				raise self.error("Cannot find schema for: " + filename)
+
+			xmlschema_doc = etree.parse(dirname + "/" + schemafile)
+			xmlschema = etree.XMLSchema(xmlschema_doc)
+
+			xml_doc = etree.parse(filename)
+			if not xmlschema.validate(xml_doc):
+				error_str = str(xmlschema.error_log.filter_from_errors()[0])
+				raise self.error("Schema validation failed for: " + filename + "\n" + error_str)
+		except ImportError as e:
+			if self.validate:
+				raise e
+
+			print("lxml not found, skipping validation", file=sys.stderr)
+
+	def do_parse(self, filename):
+		filepath = os.path.abspath(filename)
+		if filepath in self.xml_files:
+			return
+		self.xml_files.append(filepath)
+		file = open(filename, "rb")
+		parser = xml.parsers.expat.ParserCreate()
+		self.stack.append((parser, filename))
+		parser.StartElementHandler = self.start_element
+		parser.EndElementHandler = self.end_element
+		parser.CharacterDataHandler = self.character_data
+		parser.buffer_text = True
+		parser.ParseFile(file)
+		self.stack.pop()
+		file.close()
+
+	def parse(self, rnn_path, filename, validate):
+		self.path = rnn_path
+		self.stack = []
+		self.validate = validate
+		self.do_parse(filename)
+
+	def parse_reg(self, attrs, bit_size):
+		self.current_bitsize = bit_size
+		if "type" in attrs and attrs["type"] in self.bitsets:
+			bitset = self.bitsets[attrs["type"]]
+			if bitset.inline:
+				self.current_bitset = Bitset(attrs["name"], bitset)
+				self.current_bitset.inline = True
+			else:
+				self.current_bitset = bitset
+		else:
+			self.current_bitset = Bitset(attrs["name"], None)
+			self.current_bitset.inline = True
+			if "type" in attrs:
+				self.parse_field(None, attrs)
+
+		variant = self.parse_variants(attrs)
+		if not variant and self.current_array:
+			variant = self.current_array.variant
+
+		self.current_reg = Reg(attrs, self.prefix(variant), self.current_array, bit_size)
+		self.current_reg.bitset = self.current_bitset
+
+		if len(self.stack) == 1:
+			self.file.append(self.current_reg)
+
+		if variant is not None:
+			self.add_all_variants(self.current_reg, attrs, variant)
+
+		usages = None
+		if "usage" in attrs:
+			usages = attrs["usage"].split(',')
+		elif self.current_array:
+			usages = self.current_array.usages
+
+		self.add_all_usages(self.current_reg, usages)
+
+	def start_element(self, name, attrs):
+		self.cdata = ""
+		if name == "import":
+			filename = attrs["file"]
+			self.do_parse(os.path.join(self.path, filename))
+		elif name == "domain":
+			self.current_domain = attrs["name"]
+			if "prefix" in attrs:
+				self.current_prefix = self.parse_variants(attrs)
+				self.current_prefix_type = attrs["prefix"]
+			else:
+				self.current_prefix = None
+				self.current_prefix_type = None
+			if "varset" in attrs:
+				self.current_varset = self.enums[attrs["varset"]]
+		elif name == "stripe":
+			self.current_stripe = self.parse_variants(attrs)
+		elif name == "enum":
+			self.current_enum_value = 0
+			self.current_enum = Enum(attrs["name"])
+			self.enums[attrs["name"]] = self.current_enum
+			if len(self.stack) == 1:
+				self.file.append(self.current_enum)
+		elif name == "value":
+			if "value" in attrs:
+				value = int(attrs["value"], 0)
+			else:
+				value = self.current_enum_value
+			self.current_enum.values.append((attrs["name"], value))
+		elif name == "reg32":
+			self.parse_reg(attrs, 32)
+		elif name == "reg64":
+			self.parse_reg(attrs, 64)
+		elif name == "array":
+			self.current_bitsize = 32
+			variant = self.parse_variants(attrs)
+			index_type = self.enums[attrs["index"]] if "index" in attrs else None
+			self.current_array = Array(attrs, self.prefix(variant), variant, self.current_array, index_type)
+			if len(self.stack) == 1:
+				self.file.append(self.current_array)
+		elif name == "bitset":
+			self.current_bitset = Bitset(attrs["name"], None)
+			if "inline" in attrs and attrs["inline"] == "yes":
+				self.current_bitset.inline = True
+			self.bitsets[self.current_bitset.name] = self.current_bitset
+			if len(self.stack) == 1 and not self.current_bitset.inline:
+				self.file.append(self.current_bitset)
+		elif name == "bitfield" and self.current_bitset:
+			self.parse_field(attrs["name"], attrs)
+		elif name == "database":
+			self.do_validate(attrs["xsi:schemaLocation"])
+		elif name == "copyright":
+			self.copyright_year = attrs["year"]
+		elif name == "author":
+			self.authors.append(attrs["name"] + " <" + attrs["email"] + "> " + attrs["name"])
+
+	def end_element(self, name):
+		if name == "domain":
+			self.current_domain = None
+			self.current_prefix = None
+			self.current_prefix_type = None
+		elif name == "stripe":
+			self.current_stripe = None
+		elif name == "bitset":
+			self.current_bitset = None
+		elif name == "reg32":
+			self.current_reg = None
+		elif name == "array":
+			self.current_array = self.current_array.parent
+		elif name == "enum":
+			self.current_enum = None
+		elif name == "license":
+			self.license = self.cdata
+
+	def character_data(self, data):
+		self.cdata += data
+
+	def dump_reg_usages(self):
+		d = collections.defaultdict(list)
+		for usage, regs in self.usage_regs.items():
+			for reg in regs:
+				variants = self.variant_regs.get(reg.name)
+				if variants:
+					for variant, vreg in variants.items():
+						if reg == vreg:
+							d[(usage, variant)].append(reg)
+				else:
+					for variant in self.variants:
+						d[(usage, variant)].append(reg)
+
+		print("#ifdef __cplusplus")
+
+		for usage, regs in self.usage_regs.items():
+			print("template<chip CHIP> constexpr inline uint16_t %s_REGS[] = {};" % (usage.upper()))
+
+		for (usage, variant), regs in d.items():
+			offsets = []
+
+			for reg in regs:
+				if reg.array:
+					for i in range(reg.array.length):
+						offsets.append(reg.array.offset + reg.offset + i * reg.array.stride)
+						if reg.bit_size == 64:
+							offsets.append(offsets[-1] + 1)
+				else:
+					offsets.append(reg.offset)
+					if reg.bit_size == 64:
+						offsets.append(offsets[-1] + 1)
+
+			offsets.sort()
+
+			print("template<> constexpr inline uint16_t %s_REGS<%s>[] = {" % (usage.upper(), variant))
+			for offset in offsets:
+				print("\t%s," % hex(offset))
+			print("};")
+
+		print("#endif")
+
+	def dump(self):
+		enums = []
+		bitsets = []
+		regs = []
+		for e in self.file:
+			if isinstance(e, Enum):
+				enums.append(e)
+			elif isinstance(e, Bitset):
+				bitsets.append(e)
+			else:
+				regs.append(e)
+
+		for e in enums + bitsets + regs:
+			e.dump()
+
+		self.dump_reg_usages()
+
+
+	def dump_regs_py(self):
+		regs = []
+		for e in self.file:
+			if isinstance(e, Reg):
+				regs.append(e)
+
+		for e in regs:
+			e.dump_py()
+
+
+	def dump_reg_variants(self, regname, variants):
+		# Don't bother for things that only have a single variant:
+		if len(variants) == 1:
+			return
+		print("#ifdef __cplusplus")
+		print("struct __%s {" % regname)
+		# TODO be more clever.. we should probably figure out which
+		# fields have the same type in all variants (in which they
+		# appear) and stuff everything else in a variant specific
+		# sub-structure.
+		seen_fields = []
+		bit_size = 32
+		array = False
+		address = None
+		for variant in variants.keys():
+			print("    /* %s fields: */" % variant)
+			reg = variants[variant]
+			bit_size = reg.bit_size
+			array = reg.array
+			for f in reg.bitset.fields:
+				fld_name = field_name(reg, f)
+				if fld_name in seen_fields:
+					continue
+				seen_fields.append(fld_name)
+				name = fld_name.lower()
+				if f.type in [ "address", "waddress" ]:
+					if address:
+						continue
+					address = f
+					tab_to("    __bo_type", "bo;")
+					tab_to("    uint32_t", "bo_offset;")
+					continue
+				type, val = f.ctype("var")
+				tab_to("    %s" %type, "%s;" %name)
+		print("    /* fallback fields: */")
+		if bit_size == 64:
+			tab_to("    uint64_t", "unknown;")
+			tab_to("    uint64_t", "qword;")
+		else:
+			tab_to("    uint32_t", "unknown;")
+			tab_to("    uint32_t", "dword;")
+		print("};")
+		# TODO don't hardcode the varset enum name
+		varenum = "chip"
+		print("template <%s %s>" % (varenum, varenum.upper()))
+		print("static inline struct fd_reg_pair")
+		xtra = ""
+		xtravar = ""
+		if array:
+			xtra = "int __i, "
+			xtravar = "__i, "
+		print("__%s(%sstruct __%s fields) {" % (regname, xtra, regname))
+		for variant in variants.keys():
+			print("  if (%s == %s) {" % (varenum.upper(), variant))
+			reg = variants[variant]
+			reg.dump_regpair_builder()
+			print("  } else")
+		print("    assert(!\"invalid variant\");")
+		print("}")
+
+		if bit_size == 64:
+			skip = ", { .reg = 0 }"
+		else:
+			skip = ""
+
+		print("#define %s(VARIANT, %s...) __%s<VARIANT>(%s{__VA_ARGS__})%s" % (regname, xtravar, regname, xtravar, skip))
+		print("#endif /* __cplusplus */")
+
+	def dump_structs(self):
+		for e in self.file:
+			e.dump_pack_struct()
+
+		for regname in self.variant_regs:
+			self.dump_reg_variants(regname, self.variant_regs[regname])
+
+
+def dump_c(args, guard, func):
+	p = Parser()
+
+	try:
+		p.parse(args.rnn, args.xml, args.validate)
+	except Error as e:
+		print(e, file=sys.stderr)
+		exit(1)
+
+	print("#ifndef %s\n#define %s\n" % (guard, guard))
+
+	print("""/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng gen_header.py tool in this git repository:
+http://gitlab.freedesktop.org/mesa/mesa/
+git clone https://gitlab.freedesktop.org/mesa/mesa.git
+
+The rules-ng-ng source files this header was generated from are:
+""")
+	maxlen = 0
+	for filepath in p.xml_files:
+		maxlen = max(maxlen, len(filepath))
+	for filepath in p.xml_files:
+		pad = " " * (maxlen - len(filepath))
+		filesize = str(os.path.getsize(filepath))
+		filesize = " " * (7 - len(filesize)) + filesize
+		filetime = time.ctime(os.path.getmtime(filepath))
+		print("- " + filepath + pad + " (" + filesize + " bytes, from " + filetime + ")")
+	if p.copyright_year:
+		current_year = str(datetime.date.today().year)
+		print()
+		print("Copyright (C) %s-%s by the following authors:" % (p.copyright_year, current_year))
+		for author in p.authors:
+			print("- " + author)
+	if p.license:
+		print(p.license)
+	print("*/")
+
+	print()
+	print("#ifdef __KERNEL__")
+	print("#include <linux/bug.h>")
+	print("#define assert(x) BUG_ON(!(x))")
+	print("#else")
+	print("#include <assert.h>")
+	print("#endif")
+	print()
+
+	print("#ifdef __cplusplus")
+	print("#define __struct_cast(X)")
+	print("#else")
+	print("#define __struct_cast(X) (struct X)")
+	print("#endif")
+	print()
+
+	func(p)
+
+	print("\n#endif /* %s */" % guard)
+
+
+def dump_c_defines(args):
+	guard = str.replace(os.path.basename(args.xml), '.', '_').upper()
+	dump_c(args, guard, lambda p: p.dump())
+
+
+def dump_c_pack_structs(args):
+	guard = str.replace(os.path.basename(args.xml), '.', '_').upper() + '_STRUCTS'
+	dump_c(args, guard, lambda p: p.dump_structs())
+
+
+def dump_py_defines(args):
+	p = Parser()
+
+	try:
+		p.parse(args.rnn, args.xml)
+	except Error as e:
+		print(e, file=sys.stderr)
+		exit(1)
+
+	file_name = os.path.splitext(os.path.basename(args.xml))[0]
+
+	print("from enum import IntEnum")
+	print("class %sRegs(IntEnum):" % file_name.upper())
+
+	os.path.basename(args.xml)
+
+	p.dump_regs_py()
+
+
+def main():
+	parser = argparse.ArgumentParser()
+	parser.add_argument('--rnn', type=str, required=True)
+	parser.add_argument('--xml', type=str, required=True)
+	parser.add_argument('--validate', default=False, action='store_true')
+	parser.add_argument('--no-validate', dest='validate', action='store_false')
+
+	subparsers = parser.add_subparsers()
+	subparsers.required = True
+
+	parser_c_defines = subparsers.add_parser('c-defines')
+	parser_c_defines.set_defaults(func=dump_c_defines)
+
+	parser_c_pack_structs = subparsers.add_parser('c-pack-structs')
+	parser_c_pack_structs.set_defaults(func=dump_c_pack_structs)
+
+	parser_py_defines = subparsers.add_parser('py-defines')
+	parser_py_defines.set_defaults(func=dump_py_defines)
+
+	args = parser.parse_args()
+	args.func(args)
+
+
+if __name__ == '__main__':
+	main()
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/msm_default/registers/rules-fd.xsd
+++ linux-qcom-6.8.0/drivers/gpu/drm/msm_default/registers/rules-fd.xsd
@@ -0,0 +1,404 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+	targetNamespace="http://nouveau.freedesktop.org/"
+	xmlns:rng="http://nouveau.freedesktop.org/"
+	elementFormDefault="qualified">
+
+	<annotation>
+		<documentation>
+			An updated version of the old rules.xml file from the
+			RivaTV project. Specifications by Pekka Paalanen,
+			preliminary attempt by KoalaBR,
+			first working version by Jakob Bornecrantz.
+			For specifications, see the file rules-ng-format.txt
+			in Nouveau CVS module 'rules-ng'.
+		</documentation>
+		<documentation>Version 0.1</documentation>
+	</annotation>
+
+
+	<!-- Elements -->
+
+	<element name="database"       type="rng:databaseType" />
+	<element name="import"         type="rng:importType" />
+	<element name="copyright"      type="rng:copyrightType" />
+	<element name="domain"         type="rng:domainType" />
+	<element name="array"          type="rng:arrayType" />
+	<element name="stripe"         type="rng:stripeType" />
+	<element name="reg64"          type="rng:registerType" />
+	<element name="reg32"          type="rng:registerType" />
+	<element name="bitset"         type="rng:bitsetType" />
+	<element name="bitfield"       type="rng:bitfieldType" />
+	<element name="enum"           type="rng:enumType" />
+	<element name="value"          type="rng:valueType" />
+
+	<!-- Copyright elements -->
+	<element name="author"         type="rng:authorType" />
+	<element name="nick"           type="rng:nickType" />
+	<element name="license"        type="rng:docType" />
+
+	<!-- Documentation elements -->
+	
+	<!-- FIXME: allowed only one  per parent element -->
+	<element name="brief" type="rng:briefType" />
+	
+	<element name="doc"  type="rng:docType" />
+	<element name="b"    type="rng:textformatType" />
+	<element name="i"    type="rng:textformatType" />
+	<element name="u"    type="rng:textformatType" />
+	<element name="code" type="rng:textcodeType" />
+	<element name="ul"   type="rng:listType" />
+	<element name="ol"   type="rng:listType" />
+	<element name="li"   type="rng:listitemType" />
+
+	<!-- Copyright element types -->
+
+	<complexType name="authorType" mixed="true">
+		<annotation>
+			<documentation>
+				register database author
+			</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<element ref="rng:nick" />
+		</choice>
+		<attribute name="name" type="string" use="required" />
+		<attribute name="email" type="string" use="required" />
+	</complexType>
+
+	<complexType name="nickType">
+		<annotation>
+			<documentation>nickType</documentation>
+		</annotation>
+		<attribute name="name" type="string" use="required" />
+	</complexType>
+
+	<!-- Database element types -->
+
+	<complexType name="databaseType">
+		<annotation>
+			<documentation>databaseType</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+		</choice>
+	</complexType>
+
+	<complexType name="importType">
+		<annotation>
+			<documentation>importType</documentation>
+		</annotation>
+		<attribute name="file" type="string" use="required" />
+	</complexType>
+
+	<complexType name="copyrightType">
+		<annotation>
+			<documentation>copyrightType</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+			<element ref="rng:author" />
+			<element ref="rng:license" />
+		</choice>
+		<attribute name="year" type="nonNegativeInteger" use="optional" />
+	</complexType>
+
+	<complexType name="domainType">
+		<annotation>
+			<documentation>domainType</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+			<group ref="rng:regarrayGroup" />
+		</choice>
+		<attribute name="name" type="NMTOKEN" use="required" />
+		<attribute name="prefix" type="NMTOKENS" use="optional" />
+		<attribute name="width" type="rng:DomainWidth" use="optional" />
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+		<attribute name="variants" type="string" use="optional" />
+	</complexType>
+
+	<complexType name="arrayType">
+		<annotation>
+			<documentation>arrayType</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+			<group ref="rng:regarrayGroup" />
+		</choice>
+		<attribute name="name" type="NMTOKEN" use="optional" />
+		<attribute name="offset" type="rng:HexOrNumber" use="optional" />
+		<attribute name="offsets" type="string" use="optional"/>
+		<attribute name="doffsets" type="string" use="optional"/>
+		<attribute name="index" type="NMTOKENS" use="optional"/>
+		<attribute name="stride" type="rng:HexOrNumber" use="required" />
+		<attribute name="length" type="rng:HexOrNumber" use="required" />
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+		<attribute name="variants" type="string" use="optional" />
+		<attribute name="usage" type="string" use="optional" />
+	</complexType>
+
+	<complexType name="stripeType">
+		<annotation>
+			<documentation>stripeType</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+			<group ref="rng:regarrayGroup" minOccurs="0" />
+		</choice>
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+		<attribute name="variants" type="string" use="optional" />
+		<attribute name="prefix" type="NMTOKENS" use="optional" />
+	</complexType>
+
+	<complexType name="registerType">
+		<annotation>
+			<documentation>
+				registerType used by reg32, reg64
+			</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+			<element ref="rng:value" />
+			<element ref="rng:bitfield" />
+		</choice>
+		<attribute name="name" type="NMTOKEN" use="required" />
+		<attribute name="offset" type="rng:HexOrNumber" use="required" />
+		<attribute name="type" type="NMTOKENS" use="optional" />
+		<attribute name="shr" type="nonNegativeInteger" use="optional" />
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+		<attribute name="variants" type="string" use="optional" />
+		<attribute name="stride" type="rng:HexOrNumber" use="optional" />
+		<attribute name="length" type="rng:HexOrNumber" use="optional" />
+		<attribute name="high" type="nonNegativeInteger" use="optional" />
+		<attribute name="low" type="nonNegativeInteger" use="optional" />
+		<attribute name="pos" type="nonNegativeInteger" use="optional" />
+		<attribute name="align" type="nonNegativeInteger" use="optional" />
+		<attribute name="radix" type="nonNegativeInteger" use="optional" />
+		<attribute name="usage" type="string" use="optional" />
+	</complexType>
+
+	<complexType name="bitsetType">
+		<annotation>
+			<documentation>bitsetType</documentation>
+		</annotation>
+		<choice maxOccurs="unbounded">
+			<element ref="rng:bitfield" />
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+		</choice>
+		<attribute name="name" type="NMTOKEN" use="required" />
+		<attribute name="inline" type="rng:Boolean" use="optional" />
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+	</complexType>
+
+	<complexType name="bitfieldType">
+		<annotation>
+			<documentation>bitfieldType</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<element ref="rng:value" maxOccurs="unbounded" />
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+		</choice>
+		<attribute name="name" type="NMTOKEN" use="required" />
+		<attribute name="high" type="nonNegativeInteger" use="optional" />
+		<attribute name="low" type="nonNegativeInteger" use="optional" />
+		<attribute name="pos" type="nonNegativeInteger" use="optional" />
+		<attribute name="radix" type="nonNegativeInteger" use="optional" />
+		<attribute name="type" type="NMTOKENS" use="optional" />
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+		<attribute name="variants" type="string" use="optional" />
+		<attribute name="addvariant" type="rng:Boolean" use="optional" />
+		<attribute name="shr" type="nonNegativeInteger" use="optional" />
+	</complexType>
+
+	<complexType name="enumType">
+		<annotation>
+			<documentation>enumType</documentation>
+		</annotation>
+		<choice maxOccurs="unbounded">
+			<element ref="rng:value" />
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+		</choice>
+		<attribute name="name" type="NMTOKEN" use="required" />
+		<attribute name="bare" type="rng:Boolean" use="optional" />
+		<attribute name="prefix" type="NMTOKENS" use="optional" />
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+	</complexType>
+
+	<complexType name="valueType">
+		<annotation>
+			<documentation>valueType</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:docGroup" />
+			<group ref="rng:topGroup" />
+		</choice>
+		<attribute name="name" type="NMTOKEN" use="required" />
+		<attribute name="value" type="string" use="optional" />
+		<attribute name="varset" type="NMTOKEN" use="optional" />
+		<attribute name="variants" type="string" use="optional" />
+	</complexType>
+
+	<!-- Documentation element types -->
+
+	<complexType name="briefType">
+		<annotation>
+			<documentation>
+				brief documentation, no markup
+			</documentation>
+		</annotation>
+		<simpleContent>
+			<extension base="string" />
+		</simpleContent>
+	</complexType>
+	
+	<complexType name="docType" mixed="true">
+		<annotation>
+			<documentation>
+				root element of documentation sub-tree
+			</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:textformatGroup" />
+			<group ref="rng:listGroup" />
+			<element ref="rng:code" />
+		</choice>
+	</complexType>
+	
+	<complexType name="textformatType" mixed="true">
+		<annotation>
+			<documentation>
+				for bold, underline, italics
+			</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:textformatGroup" />
+		</choice>
+	</complexType>
+	
+	<complexType name="textcodeType">
+		<simpleContent>
+			<extension base="string">
+				<attribute name="title" type="string" />
+			</extension>
+		</simpleContent>
+	</complexType>
+	
+	<complexType name="listType">
+		<annotation>
+			<documentation>
+				definition of a list, ordered or unordered
+			</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<element ref="rng:li" />
+		</choice>
+	</complexType>
+	
+	<complexType name="listitemType" mixed="true">
+		<annotation>
+			<documentation>
+				items of a list
+			</documentation>
+		</annotation>
+		<choice minOccurs="0" maxOccurs="unbounded">
+			<group ref="rng:textformatGroup" />
+			<group ref="rng:listGroup" />
+			<element ref="rng:code" />
+		</choice>
+	</complexType>
+
+
+
+	<!-- Attribute value types -->
+
+	<simpleType name="Hexadecimal">
+		<restriction base="string">
+			<pattern value="0x[0-9a-f]+" />
+			<pattern value="0x[0-9A-F]+" />
+			<pattern value="[0-9]" />
+		</restriction>
+	</simpleType>
+
+	<simpleType name="HexOrNumber">
+		<annotation>
+			<documentation>HexOrNumber</documentation>
+		</annotation>
+		<union memberTypes="rng:Hexadecimal nonNegativeInteger" />
+	</simpleType>
+
+	<simpleType name="Boolean">
+		<restriction base="string">
+			<enumeration value="true" />
+			<enumeration value="1" />
+			<enumeration value="yes" />
+			<enumeration value="false" />
+			<enumeration value="0" />
+			<enumeration value="no" />
+		</restriction>
+	</simpleType>
+
+	<simpleType name="DomainWidth">
+		<annotation>
+			<documentation>DomainWidth</documentation>
+		</annotation>
+		<restriction base="string">
+			<enumeration value="32" />
+		</restriction>
+	</simpleType>
+
+
+
+	<!-- Element groups -->
+
+	<group name="topGroup">
+		<choice>
+			<element ref="rng:copyright" />
+			<element ref="rng:domain" />
+			<element ref="rng:enum" />
+			<element ref="rng:bitset" />
+			<element ref="rng:import" />
+		</choice>
+	</group>
+	
+	<group name="regarrayGroup">
+		<choice>
+			<element ref="rng:reg64" />
+			<element ref="rng:reg32" />
+			<element ref="rng:array" />
+			<element ref="rng:stripe" />
+		</choice>
+	</group>
+	
+	<group name="docGroup">
+		<choice>
+			<element ref="rng:brief" />
+			<element ref="rng:doc" />
+		</choice>
+	</group>
+	
+	<group name="textformatGroup">
+		<choice>
+			<element ref="rng:b" />
+			<element ref="rng:i" />
+			<element ref="rng:u" />
+		</choice>
+	</group>
+	
+	<group name="listGroup">
+		<choice>
+			<element ref="rng:ul" />
+			<element ref="rng:ol" />
+		</choice>
+	</group>
+
+</schema>
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/mxsfb/lcdif_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/mxsfb/lcdif_drv.c
@@ -340,6 +340,9 @@
 	if (ret)
 		return ret;
 
+	if (pm_runtime_suspended(dev))
+		return 0;
+
 	return lcdif_rpm_suspend(dev);
 }
 
@@ -347,7 +350,8 @@
 {
 	struct drm_device *drm = dev_get_drvdata(dev);
 
-	lcdif_rpm_resume(dev);
+	if (!pm_runtime_suspended(dev))
+		lcdif_rpm_resume(dev);
 
 	return drm_mode_config_helper_resume(drm);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/dispnv04/crtc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/dispnv04/crtc.c
@@ -1157,7 +1157,7 @@
 	chan = drm->channel;
 	if (!chan)
 		return -ENODEV;
-	cli = (void *)chan->user.client;
+	cli = chan->cli;
 	push = chan->chan.push;
 
 	s = kzalloc(sizeof(*s), GFP_KERNEL);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/dispnv04/disp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/dispnv04/disp.c
@@ -68,7 +68,7 @@
 	if (nv_two_heads(dev))
 		NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0);
 
-	if (!runtime)
+	if (!runtime && !drm->headless)
 		cancel_work_sync(&drm->hpd_work);
 
 	if (!suspend)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c
@@ -209,6 +209,8 @@
 		struct drm_display_mode *mode;
 
 		mode = drm_mode_duplicate(encoder->dev, tv_mode);
+		if (!mode)
+			continue;
 
 		mode->clock = tv_norm->tv_enc_mode.vrefresh *
 			mode->htotal / 1000 *
@@ -258,6 +260,8 @@
 		if (modes[i].hdisplay == output_mode->hdisplay &&
 		    modes[i].vdisplay == output_mode->vdisplay) {
 			mode = drm_mode_duplicate(encoder->dev, output_mode);
+			if (!mode)
+				continue;
 			mode->type |= DRM_MODE_TYPE_PREFERRED;
 
 		} else {
@@ -265,6 +269,8 @@
 					    modes[i].vdisplay, 60, false,
 					    (output_mode->flags &
 					     DRM_MODE_FLAG_INTERLACE), false);
+			if (!mode)
+				continue;
 		}
 
 		/* CVT modes are sometimes unsuitable... */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/dispnv50/disp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/dispnv50/disp.c
@@ -914,7 +914,7 @@
 		msto->disabled = false;
 		drm_dp_remove_payload_part2(mgr, new_mst_state, old_payload, new_payload);
 	} else if (msto->enabled) {
-		drm_dp_add_payload_part2(mgr, state, new_payload);
+		drm_dp_add_payload_part2(mgr, new_payload);
 		msto->enabled = false;
 	}
 }
@@ -2679,7 +2679,7 @@
 			nv50_mstm_fini(nouveau_encoder(encoder));
 	}
 
-	if (!runtime)
+	if (!runtime && !drm->headless)
 		cancel_work_sync(&drm->hpd_work);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
@@ -15,7 +15,9 @@
 };
 
 struct nvkm_gsp_radix3 {
-	struct nvkm_gsp_mem mem[3];
+	struct nvkm_gsp_mem lvl0;
+	struct nvkm_gsp_mem lvl1;
+	struct sg_table lvl2;
 };
 
 int nvkm_gsp_sg(struct nvkm_device *, u64 size, struct sg_table *);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -272,6 +272,9 @@
 		getparam->value = (u64)ttm_resource_manager_usage(vram_mgr);
 		break;
 	}
+	case NOUVEAU_GETPARAM_HAS_VMA_TILEMODE:
+		getparam->value = 1;
+		break;
 	default:
 		NV_PRINTK(dbg, cli, "unknown parameter %lld\n", getparam->param);
 		return -EINVAL;
@@ -343,7 +346,7 @@
 	list_add(&chan->head, &abi16->channels);
 
 	/* create channel object and initialise dma and fence management */
-	ret = nouveau_channel_new(drm, device, false, runm, init->fb_ctxdma_handle,
+	ret = nouveau_channel_new(cli, false, runm, init->fb_ctxdma_handle,
 				  init->tt_ctxdma_handle, &chan->chan);
 	if (ret)
 		goto done;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -23,6 +23,7 @@
  */
 
 #include "nouveau_drv.h"
+#include "nouveau_bios.h"
 #include "nouveau_reg.h"
 #include "dispnv04/hw.h"
 #include "nouveau_encoder.h"
@@ -1677,7 +1678,7 @@
 	 */
 	if (nv_match_device(dev, 0x0201, 0x1462, 0x8851)) {
 		if (*conn == 0xf2005014 && *conf == 0xffffffff) {
-			fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 1, 1, 1);
+			fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 1, 1, DCB_OUTPUT_B);
 			return false;
 		}
 	}
@@ -1763,26 +1764,26 @@
 #ifdef __powerpc__
 	/* Apple iMac G4 NV17 */
 	if (of_machine_is_compatible("PowerMac4,5")) {
-		fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 0, all_heads, 1);
-		fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG, 1, all_heads, 2);
+		fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS, 0, all_heads, DCB_OUTPUT_B);
+		fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG, 1, all_heads, DCB_OUTPUT_C);
 		return;
 	}
 #endif
 
 	/* Make up some sane defaults */
 	fabricate_dcb_output(dcb, DCB_OUTPUT_ANALOG,
-			     bios->legacy.i2c_indices.crt, 1, 1);
+			     bios->legacy.i2c_indices.crt, 1, DCB_OUTPUT_B);
 
 	if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0)
 		fabricate_dcb_output(dcb, DCB_OUTPUT_TV,
 				     bios->legacy.i2c_indices.tv,
-				     all_heads, 0);
+				     all_heads, DCB_OUTPUT_A);
 
 	else if (bios->tmds.output0_script_ptr ||
 		 bios->tmds.output1_script_ptr)
 		fabricate_dcb_output(dcb, DCB_OUTPUT_TMDS,
 				     bios->legacy.i2c_indices.panel,
-				     all_heads, 1);
+				     all_heads, DCB_OUTPUT_B);
 }
 
 static int
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -241,28 +241,28 @@
 	}
 
 	nvbo->contig = !(tile_flags & NOUVEAU_GEM_TILE_NONCONTIG);
-	if (!nouveau_cli_uvmm(cli) || internal) {
-		/* for BO noVM allocs, don't assign kinds */
-		if (cli->device.info.family >= NV_DEVICE_INFO_V0_FERMI) {
-			nvbo->kind = (tile_flags & 0x0000ff00) >> 8;
-			if (!nvif_mmu_kind_valid(mmu, nvbo->kind)) {
-				kfree(nvbo);
-				return ERR_PTR(-EINVAL);
-			}
 
-			nvbo->comp = mmu->kind[nvbo->kind] != nvbo->kind;
-		} else if (cli->device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
-			nvbo->kind = (tile_flags & 0x00007f00) >> 8;
-			nvbo->comp = (tile_flags & 0x00030000) >> 16;
-			if (!nvif_mmu_kind_valid(mmu, nvbo->kind)) {
-				kfree(nvbo);
-				return ERR_PTR(-EINVAL);
-			}
-		} else {
-			nvbo->zeta = (tile_flags & 0x00000007);
+	if (cli->device.info.family >= NV_DEVICE_INFO_V0_FERMI) {
+		nvbo->kind = (tile_flags & 0x0000ff00) >> 8;
+		if (!nvif_mmu_kind_valid(mmu, nvbo->kind)) {
+			kfree(nvbo);
+			return ERR_PTR(-EINVAL);
+		}
+
+		nvbo->comp = mmu->kind[nvbo->kind] != nvbo->kind;
+	} else if (cli->device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
+		nvbo->kind = (tile_flags & 0x00007f00) >> 8;
+		nvbo->comp = (tile_flags & 0x00030000) >> 16;
+		if (!nvif_mmu_kind_valid(mmu, nvbo->kind)) {
+			kfree(nvbo);
+			return ERR_PTR(-EINVAL);
 		}
-		nvbo->mode = tile_mode;
+	} else {
+		nvbo->zeta = (tile_flags & 0x00000007);
+	}
+	nvbo->mode = tile_mode;
 
+	if (!nouveau_cli_uvmm(cli) || internal) {
 		/* Determine the desirable target GPU page size for the buffer. */
 		for (i = 0; i < vmm->page_nr; i++) {
 			/* Because we cannot currently allow VMM maps to fail
@@ -304,12 +304,6 @@
 		}
 		nvbo->page = vmm->page[pi].shift;
 	} else {
-		/* reject other tile flags when in VM mode. */
-		if (tile_mode)
-			return ERR_PTR(-EINVAL);
-		if (tile_flags & ~NOUVEAU_GEM_TILE_NONCONTIG)
-			return ERR_PTR(-EINVAL);
-
 		/* Determine the desirable target GPU page size for the buffer. */
 		for (i = 0; i < vmm->page_nr; i++) {
 			/* Because we cannot currently allow VMM maps to fail
@@ -856,7 +850,7 @@
 {
 	struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
 	struct nouveau_channel *chan = drm->ttm.chan;
-	struct nouveau_cli *cli = (void *)chan->user.client;
+	struct nouveau_cli *cli = chan->cli;
 	struct nouveau_fence *fence;
 	int ret;
 
@@ -1264,6 +1258,8 @@
 			drm_vma_node_unmap(&nvbo->bo.base.vma_node,
 					   bdev->dev_mapping);
 			nouveau_ttm_io_mem_free_locked(drm, nvbo->bo.resource);
+			nvbo->bo.resource->bus.offset = 0;
+			nvbo->bo.resource->bus.addr = NULL;
 			goto retry;
 		}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_chan.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nouveau_chan.c
@@ -52,7 +52,7 @@
 nouveau_channel_killed(struct nvif_event *event, void *repv, u32 repc)
 {
 	struct nouveau_channel *chan = container_of(event, typeof(*chan), kill);
-	struct nouveau_cli *cli = (void *)chan->user.client;
+	struct nouveau_cli *cli = chan->cli;
 
 	NV_PRINTK(warn, cli, "channel %d killed!\n", chan->chid);
 
@@ -66,7 +66,7 @@
 nouveau_channel_idle(struct nouveau_channel *chan)
 {
 	if (likely(chan && chan->fence && !atomic_read(&chan->killed))) {
-		struct nouveau_cli *cli = (void *)chan->user.client;
+		struct nouveau_cli *cli = chan->cli;
 		struct nouveau_fence *fence = NULL;
 		int ret;
 
@@ -142,10 +142,11 @@
 }
 
 static int
-nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
+nouveau_channel_prep(struct nouveau_cli *cli,
 		     u32 size, struct nouveau_channel **pchan)
 {
-	struct nouveau_cli *cli = (void *)device->object.client;
+	struct nouveau_drm *drm = cli->drm;
+	struct nvif_device *device = &cli->device;
 	struct nv_dma_v0 args = {};
 	struct nouveau_channel *chan;
 	u32 target;
@@ -155,6 +156,7 @@
 	if (!chan)
 		return -ENOMEM;
 
+	chan->cli = cli;
 	chan->device = device;
 	chan->drm = drm;
 	chan->vmm = nouveau_cli_vmm(cli);
@@ -254,7 +256,7 @@
 }
 
 static int
-nouveau_channel_ctor(struct nouveau_drm *drm, struct nvif_device *device, bool priv, u64 runm,
+nouveau_channel_ctor(struct nouveau_cli *cli, bool priv, u64 runm,
 		     struct nouveau_channel **pchan)
 {
 	const struct nvif_mclass hosts[] = {
@@ -279,7 +281,7 @@
 		struct nvif_chan_v0 chan;
 		char name[TASK_COMM_LEN+16];
 	} args;
-	struct nouveau_cli *cli = (void *)device->object.client;
+	struct nvif_device *device = &cli->device;
 	struct nouveau_channel *chan;
 	const u64 plength = 0x10000;
 	const u64 ioffset = plength;
@@ -298,7 +300,7 @@
 		size = ioffset + ilength;
 
 	/* allocate dma push buffer */
-	ret = nouveau_channel_prep(drm, device, size, &chan);
+	ret = nouveau_channel_prep(cli, size, &chan);
 	*pchan = chan;
 	if (ret)
 		return ret;
@@ -493,13 +495,12 @@
 }
 
 int
-nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
+nouveau_channel_new(struct nouveau_cli *cli,
 		    bool priv, u64 runm, u32 vram, u32 gart, struct nouveau_channel **pchan)
 {
-	struct nouveau_cli *cli = (void *)device->object.client;
 	int ret;
 
-	ret = nouveau_channel_ctor(drm, device, priv, runm, pchan);
+	ret = nouveau_channel_ctor(cli, priv, runm, pchan);
 	if (ret) {
 		NV_PRINTK(dbg, cli, "channel create, %d\n", ret);
 		return ret;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_chan.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nouveau_chan.h
@@ -12,6 +12,7 @@
 		struct nvif_push *push;
 	} chan;
 
+	struct nouveau_cli *cli;
 	struct nvif_device *device;
 	struct nouveau_drm *drm;
 	struct nouveau_vmm *vmm;
@@ -62,7 +63,7 @@
 int nouveau_channels_init(struct nouveau_drm *);
 void nouveau_channels_fini(struct nouveau_drm *);
 
-int  nouveau_channel_new(struct nouveau_drm *, struct nvif_device *, bool priv, u64 runm,
+int  nouveau_channel_new(struct nouveau_cli *, bool priv, u64 runm,
 			 u32 vram, u32 gart, struct nouveau_channel **);
 void nouveau_channel_del(struct nouveau_channel **);
 int  nouveau_channel_idle(struct nouveau_channel *);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -1001,6 +1001,9 @@
 		struct drm_display_mode *mode;
 
 		mode = drm_mode_duplicate(dev, nv_connector->native_mode);
+		if (!mode)
+			return 0;
+
 		drm_mode_probed_add(connector, mode);
 		ret = 1;
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_display.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -450,6 +450,9 @@
 {
 	struct nouveau_drm *drm = nouveau_drm(dev);
 
+	if (drm->headless)
+		return;
+
 	spin_lock_irq(&drm->hpd_lock);
 	drm->hpd_pending = ~0;
 	spin_unlock_irq(&drm->hpd_lock);
@@ -635,7 +638,7 @@
 	}
 	drm_connector_list_iter_end(&conn_iter);
 
-	if (!runtime)
+	if (!runtime && !drm->headless)
 		cancel_work_sync(&drm->hpd_work);
 
 	drm_kms_helper_poll_disable(dev);
@@ -729,6 +732,7 @@
 		/* no display hw */
 		if (ret == -ENODEV) {
 			ret = 0;
+			drm->headless = true;
 			goto disp_create_err;
 		}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_dmem.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nouveau_dmem.c
@@ -193,7 +193,7 @@
 	if (!spage || !(src & MIGRATE_PFN_MIGRATE))
 		goto done;
 
-	dpage = alloc_page_vma(GFP_HIGHUSER, vmf->vma, vmf->address);
+	dpage = alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vmf->vma, vmf->address);
 	if (!dpage)
 		goto done;
 
@@ -378,9 +378,9 @@
 	dma_addr_t *dma_addrs;
 	struct nouveau_fence *fence;
 
-	src_pfns = kcalloc(npages, sizeof(*src_pfns), GFP_KERNEL);
-	dst_pfns = kcalloc(npages, sizeof(*dst_pfns), GFP_KERNEL);
-	dma_addrs = kcalloc(npages, sizeof(*dma_addrs), GFP_KERNEL);
+	src_pfns = kvcalloc(npages, sizeof(*src_pfns), GFP_KERNEL | __GFP_NOFAIL);
+	dst_pfns = kvcalloc(npages, sizeof(*dst_pfns), GFP_KERNEL | __GFP_NOFAIL);
+	dma_addrs = kvcalloc(npages, sizeof(*dma_addrs), GFP_KERNEL | __GFP_NOFAIL);
 
 	migrate_device_range(src_pfns, chunk->pagemap.range.start >> PAGE_SHIFT,
 			npages);
@@ -406,11 +406,11 @@
 	migrate_device_pages(src_pfns, dst_pfns, npages);
 	nouveau_dmem_fence_done(&fence);
 	migrate_device_finalize(src_pfns, dst_pfns, npages);
-	kfree(src_pfns);
-	kfree(dst_pfns);
+	kvfree(src_pfns);
+	kvfree(dst_pfns);
 	for (i = 0; i < npages; i++)
 		dma_unmap_page(chunk->drm->dev->dev, dma_addrs[i], PAGE_SIZE, DMA_BIDIRECTIONAL);
-	kfree(dma_addrs);
+	kvfree(dma_addrs);
 }
 
 void
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_dp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nouveau_dp.c
@@ -225,12 +225,15 @@
 	u8 *dpcd = nv_encoder->dp.dpcd;
 	int ret = NOUVEAU_DP_NONE, hpd;
 
-	/* If we've already read the DPCD on an eDP device, we don't need to
-	 * reread it as it won't change
+	/* eDP ports don't support hotplugging - so there's no point in probing eDP ports unless we
+	 * haven't probed them once before.
 	 */
-	if (connector->connector_type == DRM_MODE_CONNECTOR_eDP &&
-	    dpcd[DP_DPCD_REV] != 0)
-		return NOUVEAU_DP_SST;
+	if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+		if (connector->status == connector_status_connected)
+			return NOUVEAU_DP_SST;
+		else if (connector->status == connector_status_disconnected)
+			return NOUVEAU_DP_NONE;
+	}
 
 	mutex_lock(&nv_encoder->dp.hpd_irq_lock);
 	if (mstm) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -356,7 +356,7 @@
 		return;
 	}
 
-	ret = nouveau_channel_new(drm, device, false, runm, NvDmaFB, NvDmaTT, &drm->cechan);
+	ret = nouveau_channel_new(&drm->client, true, runm, NvDmaFB, NvDmaTT, &drm->cechan);
 	if (ret)
 		NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
 }
@@ -384,7 +384,7 @@
 		return;
 	}
 
-	ret = nouveau_channel_new(drm, device, false, runm, NvDmaFB, NvDmaTT, &drm->channel);
+	ret = nouveau_channel_new(&drm->client, false, runm, NvDmaFB, NvDmaTT, &drm->channel);
 	if (ret) {
 		NV_ERROR(drm, "failed to create kernel channel, %d\n", ret);
 		nouveau_accel_gr_fini(drm);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -276,6 +276,7 @@
 	/* modesetting */
 	struct nvbios vbios;
 	struct nouveau_display *display;
+	bool headless;
 	struct work_struct hpd_work;
 	spinlock_t hpd_lock;
 	u32 hpd_pending;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_fence.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nouveau_fence.c
@@ -386,11 +386,13 @@
 			if (f) {
 				struct nouveau_channel *prev;
 				bool must_wait = true;
+				bool local;
 
 				rcu_read_lock();
 				prev = rcu_dereference(f->channel);
-				if (prev && (prev == chan ||
-					     fctx->sync(f, prev, chan) == 0))
+				local = prev && prev->cli->drm == chan->cli->drm;
+				if (local && (prev == chan ||
+					      fctx->sync(f, prev, chan) == 0))
 					must_wait = false;
 				rcu_read_unlock();
 				if (!must_wait)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_prime.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nouveau_prime.c
@@ -64,7 +64,8 @@
 	 * to the caller, instead of a normal nouveau_bo ttm reference. */
 	ret = drm_gem_object_init(dev, &nvbo->bo.base, size);
 	if (ret) {
-		nouveau_bo_ref(NULL, &nvbo);
+		drm_gem_object_release(&nvbo->bo.base);
+		kfree(nvbo);
 		obj = ERR_PTR(-ENOMEM);
 		goto unlock;
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nouveau_uvmm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nouveau_uvmm.c
@@ -812,15 +812,15 @@
 	struct drm_gpuva_op_unmap *u = r->unmap;
 	struct nouveau_uvma *uvma = uvma_from_va(u->va);
 	u64 addr = uvma->va.va.addr;
-	u64 range = uvma->va.va.range;
+	u64 end = uvma->va.va.addr + uvma->va.va.range;
 
 	if (r->prev)
 		addr = r->prev->va.addr + r->prev->va.range;
 
 	if (r->next)
-		range = r->next->va.addr - addr;
+		end = r->next->va.addr;
 
-	op_unmap_range(u, addr, range);
+	op_unmap_range(u, addr, end - addr);
 }
 
 static int
@@ -1803,6 +1803,7 @@
 {
 	struct nouveau_bo *nvbo = nouveau_gem_object(vm_bo->obj);
 
+	nouveau_bo_placement_set(nvbo, nvbo->valid_domains, 0);
 	return nouveau_bo_validate(nvbo, true, false);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/core/firmware.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nvkm/core/firmware.c
@@ -205,7 +205,8 @@
 		break;
 	case NVKM_FIRMWARE_IMG_DMA:
 		nvkm_memory_unref(&memory);
-		dma_free_coherent(fw->device->dev, sg_dma_len(&fw->mem.sgl), fw->img, fw->phys);
+		dma_free_noncoherent(fw->device->dev, sg_dma_len(&fw->mem.sgl),
+				     fw->img, fw->phys, DMA_TO_DEVICE);
 		break;
 	case NVKM_FIRMWARE_IMG_SGT:
 		nvkm_memory_unref(&memory);
@@ -236,10 +237,12 @@
 		break;
 	case NVKM_FIRMWARE_IMG_DMA: {
 		dma_addr_t addr;
-
 		len = ALIGN(fw->len, PAGE_SIZE);
 
-		fw->img = dma_alloc_coherent(fw->device->dev, len, &addr, GFP_KERNEL);
+		fw->img = dma_alloc_noncoherent(fw->device->dev,
+						len, &addr,
+						DMA_TO_DEVICE,
+						GFP_KERNEL);
 		if (fw->img) {
 			memcpy(fw->img, src, fw->len);
 			fw->phys = addr;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nvkm/engine/disp/mcp77.c
@@ -31,6 +31,7 @@
 	.state = g94_sor_state,
 	.power = nv50_sor_power,
 	.clock = nv50_sor_clock,
+	.bl = &nv50_sor_bl,
 	.hdmi = &g84_sor_hdmi,
 	.dp = &g94_sor_dp,
 };
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c
@@ -992,7 +992,7 @@
 		ctrl->data = data;
 
 		ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
-		if (ret == -EAGAIN && ctrl->retryTimeMs) {
+		if ((ret == -EAGAIN || ret == -EBUSY) && ctrl->retryTimeMs) {
 			/*
 			 * Device (likely an eDP panel) isn't ready yet, wait for the time specified
 			 * by GSP before retrying again
@@ -1060,33 +1060,44 @@
 	NV0073_CTRL_DP_AUXCH_CTRL_PARAMS *ctrl;
 	u8 size = *psize;
 	int ret;
+	int retries;
 
-	ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, NV0073_CTRL_CMD_DP_AUXCH_CTRL, sizeof(*ctrl));
-	if (IS_ERR(ctrl))
-		return PTR_ERR(ctrl);
+	for (retries = 0; retries < 3; ++retries) {
+		ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom, NV0073_CTRL_CMD_DP_AUXCH_CTRL, sizeof(*ctrl));
+		if (IS_ERR(ctrl))
+			return PTR_ERR(ctrl);
+
+		ctrl->subDeviceInstance = 0;
+		ctrl->displayId = BIT(outp->index);
+		ctrl->bAddrOnly = !size;
+		ctrl->cmd = type;
+		if (ctrl->bAddrOnly) {
+			ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, REQ_TYPE, WRITE);
+			ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD,  I2C_MOT, FALSE);
+		}
+		ctrl->addr = addr;
+		ctrl->size = !ctrl->bAddrOnly ? (size - 1) : 0;
+		memcpy(ctrl->data, data, size);
 
-	ctrl->subDeviceInstance = 0;
-	ctrl->displayId = BIT(outp->index);
-	ctrl->bAddrOnly = !size;
-	ctrl->cmd = type;
-	if (ctrl->bAddrOnly) {
-		ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD, REQ_TYPE, WRITE);
-		ctrl->cmd = NVDEF_SET(ctrl->cmd, NV0073_CTRL, DP_AUXCH_CMD,  I2C_MOT, FALSE);
-	}
-	ctrl->addr = addr;
-	ctrl->size = !ctrl->bAddrOnly ? (size - 1) : 0;
-	memcpy(ctrl->data, data, size);
-
-	ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
-	if (ret) {
-		nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
-		return PTR_ERR(ctrl);
+		ret = nvkm_gsp_rm_ctrl_push(&disp->rm.objcom, &ctrl, sizeof(*ctrl));
+		if ((ret == -EAGAIN || ret == -EBUSY) && ctrl->retryTimeMs) {
+			/*
+			 * Device (likely an eDP panel) isn't ready yet, wait for the time specified
+			 * by GSP before retrying again
+			 */
+			nvkm_debug(&disp->engine.subdev,
+				   "Waiting %dms for GSP LT panel delay before retrying in AUX\n",
+				   ctrl->retryTimeMs);
+			msleep(ctrl->retryTimeMs);
+			nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
+		} else {
+			memcpy(data, ctrl->data, size);
+			*psize = ctrl->size;
+			ret = ctrl->replyType;
+			nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
+			break;
+		}
 	}
-
-	memcpy(data, ctrl->data, size);
-	*psize = ctrl->size;
-	ret = ctrl->replyType;
-	nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
 	return ret;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
@@ -443,6 +443,7 @@
 		ret = gf100_grctx_generate(gr, chan, fifoch->inst);
 		if (ret) {
 			nvkm_error(&base->engine.subdev, "failed to construct context\n");
+			mutex_unlock(&gr->fecs.mutex);
 			return ret;
 		}
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/falcon/fw.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nvkm/falcon/fw.c
@@ -89,6 +89,7 @@
 		nvkm_falcon_fw_dtor_sigs(fw);
 	}
 
+
 	FLCNFW_DBG(fw, "resetting");
 	fw->func->reset(fw);
 
@@ -99,6 +100,12 @@
 			goto done;
 	}
 
+	/* after last write to the img, sync dma mappings */
+	dma_sync_single_for_device(fw->fw.device->dev,
+				   fw->fw.phys,
+				   sg_dma_len(&fw->fw.mem.sgl),
+				   DMA_TO_DEVICE);
+
 	ret = fw->func->load(fw);
 	if (ret)
 		goto done;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c
@@ -66,11 +66,16 @@
 	return ERR_PTR(-EINVAL);
 }
 
+static void of_fini(void *p)
+{
+	kfree(p);
+}
+
 const struct nvbios_source
 nvbios_of = {
 	.name = "OpenFirmware",
 	.init = of_init,
-	.fini = (void(*)(void *))kfree,
+	.fini = of_fini,
 	.read = of_read,
 	.size = of_size,
 	.rw = false,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm107.c
@@ -25,6 +25,7 @@
 
 #include <subdev/bios.h>
 #include <subdev/bios/init.h>
+#include <subdev/gsp.h>
 
 void
 gm107_devinit_disable(struct nvkm_devinit *init)
@@ -33,10 +34,13 @@
 	u32 r021c00 = nvkm_rd32(device, 0x021c00);
 	u32 r021c04 = nvkm_rd32(device, 0x021c04);
 
-	if (r021c00 & 0x00000001)
-		nvkm_subdev_disable(device, NVKM_ENGINE_CE, 0);
-	if (r021c00 & 0x00000004)
-		nvkm_subdev_disable(device, NVKM_ENGINE_CE, 2);
+	/* gsp only wants to enable/disable display */
+	if (!nvkm_gsp_rm(device->gsp)) {
+		if (r021c00 & 0x00000001)
+			nvkm_subdev_disable(device, NVKM_ENGINE_CE, 0);
+		if (r021c00 & 0x00000004)
+			nvkm_subdev_disable(device, NVKM_ENGINE_CE, 2);
+	}
 	if (r021c04 & 0x00000001)
 		nvkm_subdev_disable(device, NVKM_ENGINE_DISP, 0);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.h
@@ -46,6 +46,8 @@
 u32 gm200_ram_probe_fbp_amount(const struct nvkm_ram_func *, u32,
 			       struct nvkm_device *, int, int *);
 
+int gp100_ram_init(struct nvkm_ram *);
+
 /* RAM type-specific MR calculation routines */
 int nvkm_sddr2_calc(struct nvkm_ram *);
 int nvkm_sddr3_calc(struct nvkm_ram *);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c
@@ -27,7 +27,7 @@
 #include <subdev/bios/init.h>
 #include <subdev/bios/rammap.h>
 
-static int
+int
 gp100_ram_init(struct nvkm_ram *ram)
 {
 	struct nvkm_subdev *subdev = &ram->fb->subdev;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp102.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp102.c
@@ -5,6 +5,7 @@
 
 static const struct nvkm_ram_func
 gp102_ram = {
+	.init = gp100_ram_init,
 };
 
 int
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/fwsec.c
@@ -324,7 +324,7 @@
 		return ret;
 
 	/* Verify. */
-	err = nvkm_rd32(device, 0x001400 + (0xf * 4)) & 0x0000ffff;
+	err = nvkm_rd32(device, 0x001400 + (0x15 * 4)) & 0x0000ffff;
 	if (err) {
 		nvkm_error(subdev, "fwsec-sb: 0x%04x\n", err);
 		return -EIO;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c
@@ -76,7 +76,7 @@
 	switch (rpc_status) {
 	case 0x55: /* NV_ERR_NOT_READY */
 	case 0x66: /* NV_ERR_TIMEOUT_RETRY */
-		return -EAGAIN;
+		return -EBUSY;
 	case 0x51: /* NV_ERR_NO_MEMORY */
 		return -ENOMEM;
 	default:
@@ -119,6 +119,8 @@
 		return mqe->data;
 	}
 
+	size = ALIGN(repc + GSP_MSG_HDR_SIZE, GSP_PAGE_SIZE);
+
 	msg = kvmalloc(repc, GFP_KERNEL);
 	if (!msg)
 		return ERR_PTR(-ENOMEM);
@@ -127,19 +129,15 @@
 	len = min_t(u32, repc, len);
 	memcpy(msg, mqe->data, len);
 
-	rptr += DIV_ROUND_UP(len, GSP_PAGE_SIZE);
-	if (rptr == gsp->msgq.cnt)
-		rptr = 0;
-
 	repc -= len;
 
 	if (repc) {
 		mqe = (void *)((u8 *)gsp->shm.msgq.ptr + 0x1000 + 0 * 0x1000);
 		memcpy(msg + len, mqe, repc);
-
-		rptr += DIV_ROUND_UP(repc, GSP_PAGE_SIZE);
 	}
 
+	rptr = (rptr + DIV_ROUND_UP(size, GSP_PAGE_SIZE)) % gsp->msgq.cnt;
+
 	mb();
 	(*gsp->msgq.rptr) = rptr;
 	return msg;
@@ -161,7 +159,7 @@
 	u64 *end;
 	u64 csum = 0;
 	int free, time = 1000000;
-	u32 wptr, size;
+	u32 wptr, size, step;
 	u32 off = 0;
 
 	argc = ALIGN(GSP_MSG_HDR_SIZE + argc, GSP_PAGE_SIZE);
@@ -195,7 +193,9 @@
 		}
 
 		cqe = (void *)((u8 *)gsp->shm.cmdq.ptr + 0x1000 + wptr * 0x1000);
-		size = min_t(u32, argc, (gsp->cmdq.cnt - wptr) * GSP_PAGE_SIZE);
+		step = min_t(u32, free, (gsp->cmdq.cnt - wptr));
+		size = min_t(u32, argc, step * GSP_PAGE_SIZE);
+
 		memcpy(cqe, (u8 *)cmd + off, size);
 
 		wptr += DIV_ROUND_UP(size, 0x1000);
@@ -599,7 +599,7 @@
 
 	if (rpc->status) {
 		ret = ERR_PTR(r535_rpc_status_to_errno(rpc->status));
-		if (PTR_ERR(ret) != -EAGAIN)
+		if (PTR_ERR(ret) != -EAGAIN && PTR_ERR(ret) != -EBUSY)
 			nvkm_error(&gsp->subdev, "RM_ALLOC: 0x%x\n", rpc->status);
 	} else {
 		ret = repc ? rpc->params : NULL;
@@ -658,7 +658,7 @@
 
 	if (rpc->status) {
 		ret = r535_rpc_status_to_errno(rpc->status);
-		if (ret != -EAGAIN)
+		if (ret != -EAGAIN && ret != -EBUSY)
 			nvkm_error(&gsp->subdev, "cli:0x%08x obj:0x%08x ctrl cmd:0x%08x failed: 0x%08x\n",
 				   object->client->object.handle, object->handle, rpc->cmd, rpc->status);
 	}
@@ -1112,7 +1112,7 @@
 	rpc->numEntries = NV_GSP_REG_NUM_ENTRIES;
 
 	str_offset = offsetof(typeof(*rpc), entries[NV_GSP_REG_NUM_ENTRIES]);
-	strings = (char *)&rpc->entries[NV_GSP_REG_NUM_ENTRIES];
+	strings = (char *)rpc + str_offset;
 	for (i = 0; i < NV_GSP_REG_NUM_ENTRIES; i++) {
 		int name_len = strlen(r535_registry_entries[i].name) + 1;
 
@@ -1620,7 +1620,7 @@
 	meta->magic = GSP_FW_WPR_META_MAGIC;
 	meta->revision = GSP_FW_WPR_META_REVISION;
 
-	meta->sysmemAddrOfRadix3Elf = gsp->radix3.mem[0].addr;
+	meta->sysmemAddrOfRadix3Elf = gsp->radix3.lvl0.addr;
 	meta->sizeOfRadix3Elf = gsp->fb.wpr2.elf.size;
 
 	meta->sysmemAddrOfBootloader = gsp->boot.fw.addr;
@@ -1914,8 +1914,9 @@
 static void
 nvkm_gsp_radix3_dtor(struct nvkm_gsp *gsp, struct nvkm_gsp_radix3 *rx3)
 {
-	for (int i = ARRAY_SIZE(rx3->mem) - 1; i >= 0; i--)
-		nvkm_gsp_mem_dtor(gsp, &rx3->mem[i]);
+	nvkm_gsp_sg_free(gsp->subdev.device, &rx3->lvl2);
+	nvkm_gsp_mem_dtor(gsp, &rx3->lvl1);
+	nvkm_gsp_mem_dtor(gsp, &rx3->lvl0);
 }
 
 /**
@@ -1951,36 +1952,60 @@
 nvkm_gsp_radix3_sg(struct nvkm_gsp *gsp, struct sg_table *sgt, u64 size,
 		   struct nvkm_gsp_radix3 *rx3)
 {
-	u64 addr;
+	struct sg_dma_page_iter sg_dma_iter;
+	struct scatterlist *sg;
+	size_t bufsize;
+	u64 *pte;
+	int ret, i, page_idx = 0;
 
-	for (int i = ARRAY_SIZE(rx3->mem) - 1; i >= 0; i--) {
-		u64 *ptes;
-		size_t bufsize;
-		int ret, idx;
+	ret = nvkm_gsp_mem_ctor(gsp, GSP_PAGE_SIZE, &rx3->lvl0);
+	if (ret)
+		return ret;
 
-		bufsize = ALIGN((size / GSP_PAGE_SIZE) * sizeof(u64), GSP_PAGE_SIZE);
-		ret = nvkm_gsp_mem_ctor(gsp, bufsize, &rx3->mem[i]);
-		if (ret)
-			return ret;
+	ret = nvkm_gsp_mem_ctor(gsp, GSP_PAGE_SIZE, &rx3->lvl1);
+	if (ret)
+		goto lvl1_fail;
 
-		ptes = rx3->mem[i].data;
-		if (i == 2) {
-			struct scatterlist *sgl;
-
-			for_each_sgtable_dma_sg(sgt, sgl, idx) {
-				for (int j = 0; j < sg_dma_len(sgl) / GSP_PAGE_SIZE; j++)
-					*ptes++ = sg_dma_address(sgl) + (GSP_PAGE_SIZE * j);
-			}
-		} else {
-			for (int j = 0; j < size / GSP_PAGE_SIZE; j++)
-				*ptes++ = addr + GSP_PAGE_SIZE * j;
+	// Allocate level 2
+	bufsize = ALIGN((size / GSP_PAGE_SIZE) * sizeof(u64), GSP_PAGE_SIZE);
+	ret = nvkm_gsp_sg(gsp->subdev.device, bufsize, &rx3->lvl2);
+	if (ret)
+		goto lvl2_fail;
+
+	// Write the bus address of level 1 to level 0
+	pte = rx3->lvl0.data;
+	*pte = rx3->lvl1.addr;
+
+	// Write the bus address of each page in level 2 to level 1
+	pte = rx3->lvl1.data;
+	for_each_sgtable_dma_page(&rx3->lvl2, &sg_dma_iter, 0)
+		*pte++ = sg_page_iter_dma_address(&sg_dma_iter);
+
+	// Finally, write the bus address of each page in sgt to level 2
+	for_each_sgtable_sg(&rx3->lvl2, sg, i) {
+		void *sgl_end;
+
+		pte = sg_virt(sg);
+		sgl_end = (void *)pte + sg->length;
+
+		for_each_sgtable_dma_page(sgt, &sg_dma_iter, page_idx) {
+			*pte++ = sg_page_iter_dma_address(&sg_dma_iter);
+			page_idx++;
+
+			// Go to the next scatterlist for level 2 if we've reached the end
+			if ((void *)pte >= sgl_end)
+				break;
 		}
+	}
 
-		size = rx3->mem[i].size;
-		addr = rx3->mem[i].addr;
+	if (ret) {
+lvl2_fail:
+		nvkm_gsp_mem_dtor(gsp, &rx3->lvl1);
+lvl1_fail:
+		nvkm_gsp_mem_dtor(gsp, &rx3->lvl0);
 	}
 
-	return 0;
+	return ret;
 }
 
 int
@@ -2012,7 +2037,7 @@
 		sr = gsp->sr.meta.data;
 		sr->magic = GSP_FW_SR_META_MAGIC;
 		sr->revision = GSP_FW_SR_META_REVISION;
-		sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.mem[0].addr;
+		sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.lvl0.addr;
 		sr->sizeOfSuspendResumeData = len;
 
 		mbox0 = lower_32_bits(gsp->sr.meta.addr);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
@@ -222,8 +222,11 @@
 	void __iomem *map = NULL;
 
 	/* Already mapped? */
-	if (refcount_inc_not_zero(&iobj->maps))
+	if (refcount_inc_not_zero(&iobj->maps)) {
+		/* read barrier match the wmb on refcount set */
+		smp_rmb();
 		return iobj->map;
+	}
 
 	/* Take the lock, and re-check that another thread hasn't
 	 * already mapped the object in the meantime.
@@ -250,6 +253,8 @@
 			iobj->base.memory.ptrs = &nv50_instobj_fast;
 		else
 			iobj->base.memory.ptrs = &nv50_instobj_slow;
+		/* barrier to ensure the ptrs are written before refcount is set */
+		smp_wmb();
 		refcount_set(&iobj->maps, 1);
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/omapdrm/Kconfig
+++ linux-qcom-6.8.0/drivers/gpu/drm/omapdrm/Kconfig
@@ -4,7 +4,7 @@
 	depends on DRM && OF
 	depends on ARCH_OMAP2PLUS
 	select DRM_KMS_HELPER
-	select FB_DMAMEM_HELPERS if DRM_FBDEV_EMULATION
+	select FB_DMAMEM_HELPERS_DEFERRED if DRM_FBDEV_EMULATION
 	select VIDEOMODE_HELPERS
 	select HDMI
 	default n
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/omapdrm/dss/base.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/omapdrm/dss/base.c
@@ -139,21 +139,13 @@
 }
 
 int omapdss_device_connect(struct dss_device *dss,
-			   struct omap_dss_device *src,
 			   struct omap_dss_device *dst)
 {
-	dev_dbg(&dss->pdev->dev, "connect(%s, %s)\n",
-		src ? dev_name(src->dev) : "NULL",
+	dev_dbg(&dss->pdev->dev, "connect(%s)\n",
 		dst ? dev_name(dst->dev) : "NULL");
 
-	if (!dst) {
-		/*
-		 * The destination is NULL when the source is connected to a
-		 * bridge instead of a DSS device. Stop here, we will attach
-		 * the bridge later when we will have a DRM encoder.
-		 */
-		return src && src->bridge ? 0 : -EINVAL;
-	}
+	if (!dst)
+		return -EINVAL;
 
 	if (omapdss_device_is_connected(dst))
 		return -EBUSY;
@@ -163,19 +155,14 @@
 	return 0;
 }
 
-void omapdss_device_disconnect(struct omap_dss_device *src,
+void omapdss_device_disconnect(struct dss_device *dss,
 			       struct omap_dss_device *dst)
 {
-	struct dss_device *dss = src ? src->dss : dst->dss;
-
-	dev_dbg(&dss->pdev->dev, "disconnect(%s, %s)\n",
-		src ? dev_name(src->dev) : "NULL",
+	dev_dbg(&dss->pdev->dev, "disconnect(%s)\n",
 		dst ? dev_name(dst->dev) : "NULL");
 
-	if (!dst) {
-		WARN_ON(!src->bridge);
+	if (WARN_ON(!dst))
 		return;
-	}
 
 	if (!dst->id && !omapdss_device_is_connected(dst)) {
 		WARN_ON(1);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -242,9 +242,8 @@
 void omapdss_device_put(struct omap_dss_device *dssdev);
 struct omap_dss_device *omapdss_find_device_by_node(struct device_node *node);
 int omapdss_device_connect(struct dss_device *dss,
-			   struct omap_dss_device *src,
 			   struct omap_dss_device *dst);
-void omapdss_device_disconnect(struct omap_dss_device *src,
+void omapdss_device_disconnect(struct dss_device *dss,
 			       struct omap_dss_device *dst);
 
 int omap_dss_get_num_overlay_managers(void);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/omapdrm/omap_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -307,7 +307,7 @@
 	for (i = 0; i < priv->num_pipes; i++) {
 		struct omap_drm_pipeline *pipe = &priv->pipes[i];
 
-		omapdss_device_disconnect(NULL, pipe->output);
+		omapdss_device_disconnect(priv->dss, pipe->output);
 
 		omapdss_device_put(pipe->output);
 		pipe->output = NULL;
@@ -325,7 +325,7 @@
 	int r;
 
 	for_each_dss_output(output) {
-		r = omapdss_device_connect(priv->dss, NULL, output);
+		r = omapdss_device_connect(priv->dss, output);
 		if (r == -EPROBE_DEFER) {
 			omapdss_device_put(output);
 			return r;
@@ -695,6 +695,10 @@
 	soc = soc_device_match(omapdrm_soc_devices);
 	priv->omaprev = soc ? (uintptr_t)soc->data : 0;
 	priv->wq = alloc_ordered_workqueue("omapdrm", 0);
+	if (!priv->wq) {
+		ret = -ENOMEM;
+		goto err_alloc_workqueue;
+	}
 
 	mutex_init(&priv->list_lock);
 	INIT_LIST_HEAD(&priv->obj_list);
@@ -753,6 +757,7 @@
 	drm_mode_config_cleanup(ddev);
 	omap_gem_deinit(ddev);
 	destroy_workqueue(priv->wq);
+err_alloc_workqueue:
 	omap_disconnect_pipelines(ddev);
 	drm_dev_put(ddev);
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -51,6 +51,10 @@
 	omap_gem_roll(bo, fbi->var.yoffset * npages);
 }
 
+FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(omap_fbdev,
+				   drm_fb_helper_damage_range,
+				   drm_fb_helper_damage_area)
+
 static int omap_fbdev_pan_display(struct fb_var_screeninfo *var,
 		struct fb_info *fbi)
 {
@@ -78,11 +82,9 @@
 
 static int omap_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
-	struct drm_fb_helper *helper = info->par;
-	struct drm_framebuffer *fb = helper->fb;
-	struct drm_gem_object *bo = drm_gem_fb_get_obj(fb, 0);
+	vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
 
-	return drm_gem_mmap_obj(bo, omap_gem_mmap_size(bo), vma);
+	return fb_deferred_io_mmap(info, vma);
 }
 
 static void omap_fbdev_fb_destroy(struct fb_info *info)
@@ -94,6 +96,7 @@
 
 	DBG();
 
+	fb_deferred_io_cleanup(info);
 	drm_fb_helper_fini(helper);
 
 	omap_gem_unpin(bo);
@@ -104,15 +107,19 @@
 	kfree(fbdev);
 }
 
+/*
+ * For now, we cannot use FB_DEFAULT_DEFERRED_OPS and fb_deferred_io_mmap()
+ * because we use write-combine.
+ */
 static const struct fb_ops omap_fb_ops = {
 	.owner = THIS_MODULE,
-	__FB_DEFAULT_DMAMEM_OPS_RDWR,
+	__FB_DEFAULT_DEFERRED_OPS_RDWR(omap_fbdev),
 	.fb_check_var	= drm_fb_helper_check_var,
 	.fb_set_par	= drm_fb_helper_set_par,
 	.fb_setcmap	= drm_fb_helper_setcmap,
 	.fb_blank	= drm_fb_helper_blank,
 	.fb_pan_display = omap_fbdev_pan_display,
-	__FB_DEFAULT_DMAMEM_OPS_DRAW,
+	__FB_DEFAULT_DEFERRED_OPS_DRAW(omap_fbdev),
 	.fb_ioctl	= drm_fb_helper_ioctl,
 	.fb_mmap	= omap_fbdev_fb_mmap,
 	.fb_destroy	= omap_fbdev_fb_destroy,
@@ -213,6 +220,15 @@
 	fbi->fix.smem_start = dma_addr;
 	fbi->fix.smem_len = bo->size;
 
+	/* deferred I/O */
+	helper->fbdefio.delay = HZ / 20;
+	helper->fbdefio.deferred_io = drm_fb_helper_deferred_io;
+
+	fbi->fbdefio = &helper->fbdefio;
+	ret = fb_deferred_io_init(fbi);
+	if (ret)
+		goto fail;
+
 	/* if we have DMM, then we can use it for scrolling by just
 	 * shuffling pages around in DMM rather than doing sw blit.
 	 */
@@ -238,8 +254,20 @@
 	return ret;
 }
 
+static int omap_fbdev_dirty(struct drm_fb_helper *helper, struct drm_clip_rect *clip)
+{
+	if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2))
+		return 0;
+
+	if (helper->fb->funcs->dirty)
+		return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1);
+
+	return 0;
+}
+
 static const struct drm_fb_helper_funcs omap_fb_helper_funcs = {
 	.fb_probe = omap_fbdev_create,
+	.fb_dirty = omap_fbdev_dirty,
 };
 
 static struct drm_fb_helper *get_fb(struct fb_info *fbi)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/omapdrm/omap_gem.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -1401,8 +1401,6 @@
 
 	omap_obj = to_omap_bo(obj);
 
-	mutex_lock(&omap_obj->lock);
-
 	omap_obj->sgt = sgt;
 
 	if (omap_gem_sgt_is_contiguous(sgt, size)) {
@@ -1417,21 +1415,17 @@
 		pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL);
 		if (!pages) {
 			omap_gem_free_object(obj);
-			obj = ERR_PTR(-ENOMEM);
-			goto done;
+			return ERR_PTR(-ENOMEM);
 		}
 
 		omap_obj->pages = pages;
 		ret = drm_prime_sg_to_page_array(sgt, pages, npages);
 		if (ret) {
 			omap_gem_free_object(obj);
-			obj = ERR_PTR(-ENOMEM);
-			goto done;
+			return ERR_PTR(-ENOMEM);
 		}
 	}
 
-done:
-	mutex_unlock(&omap_obj->lock);
 	return obj;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/Kconfig
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/Kconfig
@@ -184,7 +184,7 @@
 
 config DRM_PANEL_ILITEK_ILI9341
 	tristate "Ilitek ILI9341 240x320 QVGA panels"
-	depends on OF && SPI
+	depends on SPI
 	select DRM_KMS_HELPER
 	select DRM_GEM_DMA_HELPER
 	depends on BACKLIGHT_CLASS_DEVICE
@@ -438,6 +438,16 @@
 	  around the Novatek NT36672A display controller, such as some
 	  Tianma panels used in a few Xiaomi Poco F1 mobile phones.
 
+config DRM_PANEL_NOVATEK_NT36672E
+	tristate "Novatek NT36672E DSI panel"
+	depends on OF
+	depends on DRM_MIPI_DSI
+	depends on BACKLIGHT_CLASS_DEVICE
+	help
+	  Say Y here if you want to enable support for Novatek NT36672E DSI Video Mode
+	  LCD panel module. The panel has a resolution of 1080x2408 and uses 24 bit
+	  RGB per pixel.
+
 config DRM_PANEL_NOVATEK_NT39016
 	tristate "Novatek NT39016 RGB/SPI panel"
 	depends on OF && SPI
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/Makefile
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/Makefile
@@ -41,6 +41,7 @@
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35950) += panel-novatek-nt35950.o
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36523) += panel-novatek-nt36523.o
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672A) += panel-novatek-nt36672a.o
+obj-$(CONFIG_DRM_PANEL_NOVATEK_NT36672E) += panel-novatek-nt36672e.o
 obj-$(CONFIG_DRM_PANEL_NOVATEK_NT39016) += panel-novatek-nt39016.o
 obj-$(CONFIG_DRM_PANEL_MANTIX_MLAF057WE51) += panel-mantix-mlaf057we51.o
 obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c
@@ -1507,7 +1507,11 @@
 	usleep_range(10000, 11000);
 
 	if (boe->desc->lp11_before_reset) {
-		mipi_dsi_dcs_nop(boe->dsi);
+		ret = mipi_dsi_dcs_nop(boe->dsi);
+		if (ret < 0) {
+			dev_err(&boe->dsi->dev, "Failed to send NOP: %d\n", ret);
+			goto poweroff;
+		}
 		usleep_range(1000, 2000);
 	}
 	gpiod_set_value(boe->enable_gpio, 1);
@@ -1528,13 +1532,13 @@
 	return 0;
 
 poweroff:
+	gpiod_set_value(boe->enable_gpio, 0);
 	regulator_disable(boe->avee);
 poweroffavdd:
 	regulator_disable(boe->avdd);
 poweroff1v8:
 	usleep_range(5000, 7000);
 	regulator_disable(boe->pp1800);
-	gpiod_set_value(boe->enable_gpio, 0);
 
 	return ret;
 }
@@ -1871,6 +1875,8 @@
 
 	gpiod_set_value(boe->enable_gpio, 0);
 
+	boe->base.prepare_prev_first = true;
+
 	drm_panel_init(&boe->base, dev, &boe_panel_funcs,
 		       DRM_MODE_CONNECTOR_DSI);
 	err = of_drm_get_panel_orientation(dev->of_node, &boe->orientation);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-edp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-edp.c
@@ -397,6 +397,7 @@
 {
 	struct panel_edp *p = dev_get_drvdata(dev);
 
+	drm_dp_dpcd_set_powered(p->aux, false);
 	gpiod_set_value_cansleep(p->enable_gpio, 0);
 	regulator_disable(p->supply);
 	p->unprepared_time = ktime_get_boottime();
@@ -413,8 +414,7 @@
 	if (!p->prepared)
 		return 0;
 
-	pm_runtime_mark_last_busy(panel->dev);
-	ret = pm_runtime_put_autosuspend(panel->dev);
+	ret = pm_runtime_put_sync_suspend(panel->dev);
 	if (ret < 0)
 		return ret;
 	p->prepared = false;
@@ -454,6 +454,7 @@
 	}
 
 	gpiod_set_value_cansleep(p->enable_gpio, 1);
+	drm_dp_dpcd_set_powered(p->aux, true);
 
 	delay = p->desc->delay.hpd_reliable;
 	if (p->no_hpd)
@@ -490,6 +491,7 @@
 	return 0;
 
 error:
+	drm_dp_dpcd_set_powered(p->aux, false);
 	gpiod_set_value_cansleep(p->enable_gpio, 0);
 	regulator_disable(p->supply);
 	p->unprepared_time = ktime_get_boottime();
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-himax-hx8394.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-himax-hx8394.c
@@ -370,8 +370,7 @@
 
 sleep_in:
 	/* This will probably fail, but let's try orderly power off anyway. */
-	ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
-	if (!ret)
+	if (!mipi_dsi_dcs_enter_sleep_mode(dsi))
 		msleep(50);
 
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-ilitek-ili9341.c
@@ -22,8 +22,9 @@
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
-#include <linux/of.h>
+#include <linux/property.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 
@@ -421,7 +422,7 @@
 
 	ili9341_dpi_init(ili);
 
-	return ret;
+	return 0;
 }
 
 static int ili9341_dpi_enable(struct drm_panel *panel)
@@ -691,7 +692,7 @@
 	 * Every new incarnation of this display must have a unique
 	 * data entry for the system in this driver.
 	 */
-	ili->conf = of_device_get_match_data(dev);
+	ili->conf = device_get_match_data(dev);
 	if (!ili->conf) {
 		dev_err(dev, "missing device configuration\n");
 		return -ENODEV;
@@ -714,18 +715,18 @@
 
 	reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
 	if (IS_ERR(reset))
-		dev_err(dev, "Failed to get gpio 'reset'\n");
+		return dev_err_probe(dev, PTR_ERR(reset), "Failed to get gpio 'reset'\n");
 
 	dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
 	if (IS_ERR(dc))
-		dev_err(dev, "Failed to get gpio 'dc'\n");
+		return dev_err_probe(dev, PTR_ERR(dc), "Failed to get gpio 'dc'\n");
 
 	if (!strcmp(id->name, "sf-tc240t-9370-t"))
 		return ili9341_dpi_probe(spi, dc, reset);
 	else if (!strcmp(id->name, "yx240qv29"))
 		return ili9341_dbi_probe(spi, dc, reset);
 
-	return -1;
+	return -ENODEV;
 }
 
 static void ili9341_remove(struct spi_device *spi)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-ilitek-ili9881c.c
@@ -1080,10 +1080,10 @@
 	msleep(5);
 
 	/* And reset it */
-	gpiod_set_value(ctx->reset, 1);
+	gpiod_set_value_cansleep(ctx->reset, 1);
 	msleep(20);
 
-	gpiod_set_value(ctx->reset, 0);
+	gpiod_set_value_cansleep(ctx->reset, 0);
 	msleep(20);
 
 	for (i = 0; i < ctx->desc->init_length; i++) {
@@ -1138,7 +1138,7 @@
 
 	mipi_dsi_dcs_enter_sleep_mode(ctx->dsi);
 	regulator_disable(ctx->power);
-	gpiod_set_value(ctx->reset, 1);
+	gpiod_set_value_cansleep(ctx->reset, 1);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c
@@ -560,7 +560,11 @@
 	usleep_range(10000, 11000);
 
 	// MIPI needs to keep the LP11 state before the lcm_reset pin is pulled high
-	mipi_dsi_dcs_nop(ili->dsi);
+	ret = mipi_dsi_dcs_nop(ili->dsi);
+	if (ret < 0) {
+		dev_err(&ili->dsi->dev, "Failed to send NOP: %d\n", ret);
+		goto poweroff;
+	}
 	usleep_range(1000, 2000);
 
 	gpiod_set_value(ili->enable_gpio, 1);
@@ -579,13 +583,13 @@
 	return 0;
 
 poweroff:
+	gpiod_set_value(ili->enable_gpio, 0);
 	regulator_disable(ili->avee);
 poweroffavdd:
 	regulator_disable(ili->avdd);
 poweroff1v8:
 	usleep_range(5000, 7000);
 	regulator_disable(ili->pp1800);
-	gpiod_set_value(ili->enable_gpio, 0);
 
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c
@@ -295,8 +295,6 @@
 	mipi_dsi_dcs_write_seq(dsi, 0xbd, 0x00);
 	mipi_dsi_dcs_write_seq(dsi, 0xc6, 0xef);
 	mipi_dsi_dcs_write_seq(dsi, 0xd4, 0x02);
-	mipi_dsi_dcs_write_seq(dsi, 0x11);
-	mipi_dsi_dcs_write_seq(dsi, 0x29);
 
 	ret = mipi_dsi_dcs_set_tear_on(dsi, 1);
 	if (ret < 0) {
@@ -326,7 +324,8 @@
 static const struct ltk050h3146w_desc ltk050h3148w_data = {
 	.mode = &ltk050h3148w_mode,
 	.init = ltk050h3148w_init_sequence,
-	.mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE | MIPI_DSI_MODE_VIDEO_BURST,
+	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
+		      MIPI_DSI_MODE_VIDEO_BURST,
 };
 
 static int ltk050h3146w_init_sequence(struct ltk050h3146w *ctx)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-novatek-nt35950.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-novatek-nt35950.c
@@ -556,15 +556,13 @@
 		}
 		dsi_r_host = of_find_mipi_dsi_host_by_node(dsi_r);
 		of_node_put(dsi_r);
-		if (!dsi_r_host) {
-			dev_err(dev, "Cannot get secondary DSI host\n");
-			return -EPROBE_DEFER;
-		}
+		if (!dsi_r_host)
+			return dev_err_probe(dev, -EPROBE_DEFER, "Cannot get secondary DSI host\n");
 
 		nt->dsi[1] = mipi_dsi_device_register_full(dsi_r_host, info);
-		if (!nt->dsi[1]) {
+		if (IS_ERR(nt->dsi[1])) {
 			dev_err(dev, "Cannot get secondary DSI node\n");
-			return -ENODEV;
+			return PTR_ERR(nt->dsi[1]);
 		}
 		num_dsis++;
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-novatek-nt36523.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-novatek-nt36523.c
@@ -933,8 +933,7 @@
 
 static const struct drm_display_mode elish_boe_modes[] = {
 	{
-		/* There is only one 120 Hz timing, but it doesn't work perfectly, 104 Hz preferred */
-		.clock = (1600 + 60 + 8 + 60) * (2560 + 26 + 4 + 168) * 104 / 1000,
+		.clock = (1600 + 60 + 8 + 60) * (2560 + 26 + 4 + 168) * 120 / 1000,
 		.hdisplay = 1600,
 		.hsync_start = 1600 + 60,
 		.hsync_end = 1600 + 60 + 8,
@@ -948,8 +947,7 @@
 
 static const struct drm_display_mode elish_csot_modes[] = {
 	{
-		/* There is only one 120 Hz timing, but it doesn't work perfectly, 104 Hz preferred */
-		.clock = (1600 + 200 + 40 + 52) * (2560 + 26 + 4 + 168) * 104 / 1000,
+		.clock = (1600 + 200 + 40 + 52) * (2560 + 26 + 4 + 168) * 120 / 1000,
 		.hdisplay = 1600,
 		.hsync_start = 1600 + 200,
 		.hsync_end = 1600 + 200 + 40,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-novatek-nt36672e.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-novatek-nt36672e.c
@@ -0,0 +1,643 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+
+#include <drm/drm_mipi_dsi.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+
+#include <video/mipi_display.h>
+
+static const char * const regulator_names[] = {
+	"vddi",
+	"avdd",
+	"avee",
+};
+
+static const unsigned long regulator_enable_loads[] = {
+	62000,
+	100000,
+	100000,
+};
+
+static const unsigned long regulator_disable_loads[] = {
+	80,
+	100,
+	100,
+};
+
+struct panel_desc {
+	const struct drm_display_mode *display_mode;
+	u32 width_mm;
+	u32 height_mm;
+	unsigned long mode_flags;
+	enum mipi_dsi_pixel_format format;
+	unsigned int lanes;
+	const char *panel_name;
+	int (*init_sequence)(struct mipi_dsi_device *dsi);
+};
+
+struct nt36672e_panel {
+	struct drm_panel panel;
+	struct mipi_dsi_device *dsi;
+	struct gpio_desc *reset_gpio;
+	struct regulator_bulk_data supplies[3];
+	const struct panel_desc *desc;
+};
+
+static inline struct nt36672e_panel *to_nt36672e_panel(struct drm_panel *panel)
+{
+	return container_of(panel, struct nt36672e_panel, panel);
+}
+
+static int nt36672e_1080x2408_60hz_init(struct mipi_dsi_device *dsi)
+{
+	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10);
+	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0xc0, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0xc1, 0x89, 0x28, 0x00, 0x08, 0x00, 0xaa, 0x02,
+				0x0e, 0x00, 0x2b, 0x00, 0x07, 0x0d, 0xb7, 0x0c, 0xb7);
+
+	mipi_dsi_dcs_write_seq(dsi, 0xc2, 0x1b, 0xa0);
+	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20);
+	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x01, 0x66);
+	mipi_dsi_dcs_write_seq(dsi, 0x06, 0x40);
+	mipi_dsi_dcs_write_seq(dsi, 0x07, 0x38);
+	mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x83);
+	mipi_dsi_dcs_write_seq(dsi, 0x69, 0x91);
+	mipi_dsi_dcs_write_seq(dsi, 0x95, 0xd1);
+	mipi_dsi_dcs_write_seq(dsi, 0x96, 0xd1);
+	mipi_dsi_dcs_write_seq(dsi, 0xf2, 0x64);
+	mipi_dsi_dcs_write_seq(dsi, 0xf3, 0x54);
+	mipi_dsi_dcs_write_seq(dsi, 0xf4, 0x64);
+	mipi_dsi_dcs_write_seq(dsi, 0xf5, 0x54);
+	mipi_dsi_dcs_write_seq(dsi, 0xf6, 0x64);
+	mipi_dsi_dcs_write_seq(dsi, 0xf7, 0x54);
+	mipi_dsi_dcs_write_seq(dsi, 0xf8, 0x64);
+	mipi_dsi_dcs_write_seq(dsi, 0xf9, 0x54);
+	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x24);
+	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x01, 0x0f);
+	mipi_dsi_dcs_write_seq(dsi, 0x03, 0x0c);
+	mipi_dsi_dcs_write_seq(dsi, 0x05, 0x1d);
+	mipi_dsi_dcs_write_seq(dsi, 0x08, 0x2f);
+	mipi_dsi_dcs_write_seq(dsi, 0x09, 0x2e);
+	mipi_dsi_dcs_write_seq(dsi, 0x0a, 0x2d);
+	mipi_dsi_dcs_write_seq(dsi, 0x0b, 0x2c);
+	mipi_dsi_dcs_write_seq(dsi, 0x11, 0x17);
+	mipi_dsi_dcs_write_seq(dsi, 0x12, 0x13);
+	mipi_dsi_dcs_write_seq(dsi, 0x13, 0x15);
+	mipi_dsi_dcs_write_seq(dsi, 0x15, 0x14);
+	mipi_dsi_dcs_write_seq(dsi, 0x16, 0x16);
+	mipi_dsi_dcs_write_seq(dsi, 0x17, 0x18);
+	mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x1d);
+	mipi_dsi_dcs_write_seq(dsi, 0x20, 0x2f);
+	mipi_dsi_dcs_write_seq(dsi, 0x21, 0x2e);
+	mipi_dsi_dcs_write_seq(dsi, 0x22, 0x2d);
+	mipi_dsi_dcs_write_seq(dsi, 0x23, 0x2c);
+	mipi_dsi_dcs_write_seq(dsi, 0x29, 0x17);
+	mipi_dsi_dcs_write_seq(dsi, 0x2a, 0x13);
+	mipi_dsi_dcs_write_seq(dsi, 0x2b, 0x15);
+	mipi_dsi_dcs_write_seq(dsi, 0x2f, 0x14);
+	mipi_dsi_dcs_write_seq(dsi, 0x30, 0x16);
+	mipi_dsi_dcs_write_seq(dsi, 0x31, 0x18);
+	mipi_dsi_dcs_write_seq(dsi, 0x32, 0x04);
+	mipi_dsi_dcs_write_seq(dsi, 0x34, 0x10);
+	mipi_dsi_dcs_write_seq(dsi, 0x35, 0x1f);
+	mipi_dsi_dcs_write_seq(dsi, 0x36, 0x1f);
+	mipi_dsi_dcs_write_seq(dsi, 0x4d, 0x14);
+	mipi_dsi_dcs_write_seq(dsi, 0x4e, 0x36);
+	mipi_dsi_dcs_write_seq(dsi, 0x4f, 0x36);
+	mipi_dsi_dcs_write_seq(dsi, 0x53, 0x36);
+	mipi_dsi_dcs_write_seq(dsi, 0x71, 0x30);
+	mipi_dsi_dcs_write_seq(dsi, 0x79, 0x11);
+	mipi_dsi_dcs_write_seq(dsi, 0x7a, 0x82);
+	mipi_dsi_dcs_write_seq(dsi, 0x7b, 0x8f);
+	mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x04);
+	mipi_dsi_dcs_write_seq(dsi, 0x80, 0x04);
+	mipi_dsi_dcs_write_seq(dsi, 0x81, 0x04);
+	mipi_dsi_dcs_write_seq(dsi, 0x82, 0x13);
+	mipi_dsi_dcs_write_seq(dsi, 0x84, 0x31);
+	mipi_dsi_dcs_write_seq(dsi, 0x85, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x86, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x87, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x90, 0x13);
+	mipi_dsi_dcs_write_seq(dsi, 0x92, 0x31);
+	mipi_dsi_dcs_write_seq(dsi, 0x93, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x94, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x95, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x9c, 0xf4);
+	mipi_dsi_dcs_write_seq(dsi, 0x9d, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0xa0, 0x0f);
+	mipi_dsi_dcs_write_seq(dsi, 0xa2, 0x0f);
+	mipi_dsi_dcs_write_seq(dsi, 0xa3, 0x02);
+	mipi_dsi_dcs_write_seq(dsi, 0xa4, 0x04);
+	mipi_dsi_dcs_write_seq(dsi, 0xa5, 0x04);
+	mipi_dsi_dcs_write_seq(dsi, 0xc6, 0xc0);
+	mipi_dsi_dcs_write_seq(dsi, 0xc9, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0xd9, 0x80);
+	mipi_dsi_dcs_write_seq(dsi, 0xe9, 0x02);
+	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x25);
+	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x18, 0x22);
+	mipi_dsi_dcs_write_seq(dsi, 0x19, 0xe4);
+	mipi_dsi_dcs_write_seq(dsi, 0x21, 0x40);
+	mipi_dsi_dcs_write_seq(dsi, 0x66, 0xd8);
+	mipi_dsi_dcs_write_seq(dsi, 0x68, 0x50);
+	mipi_dsi_dcs_write_seq(dsi, 0x69, 0x10);
+	mipi_dsi_dcs_write_seq(dsi, 0x6b, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x0d);
+	mipi_dsi_dcs_write_seq(dsi, 0x6e, 0x48);
+	mipi_dsi_dcs_write_seq(dsi, 0x72, 0x41);
+	mipi_dsi_dcs_write_seq(dsi, 0x73, 0x4a);
+	mipi_dsi_dcs_write_seq(dsi, 0x74, 0xd0);
+	mipi_dsi_dcs_write_seq(dsi, 0x77, 0x62);
+	mipi_dsi_dcs_write_seq(dsi, 0x79, 0x7e);
+	mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x03);
+	mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x15);
+	mipi_dsi_dcs_write_seq(dsi, 0x7f, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x84, 0x4d);
+	mipi_dsi_dcs_write_seq(dsi, 0xcf, 0x80);
+	mipi_dsi_dcs_write_seq(dsi, 0xd6, 0x80);
+	mipi_dsi_dcs_write_seq(dsi, 0xd7, 0x80);
+	mipi_dsi_dcs_write_seq(dsi, 0xef, 0x20);
+	mipi_dsi_dcs_write_seq(dsi, 0xf0, 0x84);
+	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x26);
+	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x81, 0x0f);
+	mipi_dsi_dcs_write_seq(dsi, 0x83, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x84, 0x03);
+	mipi_dsi_dcs_write_seq(dsi, 0x85, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x86, 0x03);
+	mipi_dsi_dcs_write_seq(dsi, 0x87, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x88, 0x05);
+	mipi_dsi_dcs_write_seq(dsi, 0x8a, 0x1a);
+	mipi_dsi_dcs_write_seq(dsi, 0x8b, 0x11);
+	mipi_dsi_dcs_write_seq(dsi, 0x8c, 0x24);
+	mipi_dsi_dcs_write_seq(dsi, 0x8e, 0x42);
+	mipi_dsi_dcs_write_seq(dsi, 0x8f, 0x11);
+	mipi_dsi_dcs_write_seq(dsi, 0x90, 0x11);
+	mipi_dsi_dcs_write_seq(dsi, 0x91, 0x11);
+	mipi_dsi_dcs_write_seq(dsi, 0x9a, 0x80);
+	mipi_dsi_dcs_write_seq(dsi, 0x9b, 0x04);
+	mipi_dsi_dcs_write_seq(dsi, 0x9c, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x9d, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x9e, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x27);
+	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x01, 0x68);
+	mipi_dsi_dcs_write_seq(dsi, 0x20, 0x81);
+	mipi_dsi_dcs_write_seq(dsi, 0x21, 0x6a);
+	mipi_dsi_dcs_write_seq(dsi, 0x25, 0x81);
+	mipi_dsi_dcs_write_seq(dsi, 0x26, 0x94);
+	mipi_dsi_dcs_write_seq(dsi, 0x6e, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x6f, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x70, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x71, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x72, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x75, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x76, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x77, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0x7d, 0x09);
+	mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x67);
+	mipi_dsi_dcs_write_seq(dsi, 0x80, 0x23);
+	mipi_dsi_dcs_write_seq(dsi, 0x82, 0x09);
+	mipi_dsi_dcs_write_seq(dsi, 0x83, 0x67);
+	mipi_dsi_dcs_write_seq(dsi, 0x88, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x89, 0x10);
+	mipi_dsi_dcs_write_seq(dsi, 0xa5, 0x10);
+	mipi_dsi_dcs_write_seq(dsi, 0xa6, 0x23);
+	mipi_dsi_dcs_write_seq(dsi, 0xa7, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x40);
+	mipi_dsi_dcs_write_seq(dsi, 0xe5, 0x02);
+	mipi_dsi_dcs_write_seq(dsi, 0xe6, 0xd3);
+	mipi_dsi_dcs_write_seq(dsi, 0xeb, 0x03);
+	mipi_dsi_dcs_write_seq(dsi, 0xec, 0x28);
+	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2a);
+	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x00, 0x91);
+	mipi_dsi_dcs_write_seq(dsi, 0x03, 0x20);
+	mipi_dsi_dcs_write_seq(dsi, 0x07, 0x50);
+	mipi_dsi_dcs_write_seq(dsi, 0x0a, 0x70);
+	mipi_dsi_dcs_write_seq(dsi, 0x0c, 0x04);
+	mipi_dsi_dcs_write_seq(dsi, 0x0d, 0x40);
+	mipi_dsi_dcs_write_seq(dsi, 0x0f, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x11, 0xe0);
+	mipi_dsi_dcs_write_seq(dsi, 0x15, 0x0f);
+	mipi_dsi_dcs_write_seq(dsi, 0x16, 0xa4);
+	mipi_dsi_dcs_write_seq(dsi, 0x19, 0x0f);
+	mipi_dsi_dcs_write_seq(dsi, 0x1a, 0x78);
+	mipi_dsi_dcs_write_seq(dsi, 0x1b, 0x23);
+	mipi_dsi_dcs_write_seq(dsi, 0x1d, 0x36);
+	mipi_dsi_dcs_write_seq(dsi, 0x1e, 0x3e);
+	mipi_dsi_dcs_write_seq(dsi, 0x1f, 0x3e);
+	mipi_dsi_dcs_write_seq(dsi, 0x20, 0x3e);
+	mipi_dsi_dcs_write_seq(dsi, 0x28, 0xfd);
+	mipi_dsi_dcs_write_seq(dsi, 0x29, 0x12);
+	mipi_dsi_dcs_write_seq(dsi, 0x2a, 0xe1);
+	mipi_dsi_dcs_write_seq(dsi, 0x2d, 0x0a);
+	mipi_dsi_dcs_write_seq(dsi, 0x30, 0x49);
+	mipi_dsi_dcs_write_seq(dsi, 0x33, 0x96);
+	mipi_dsi_dcs_write_seq(dsi, 0x34, 0xff);
+	mipi_dsi_dcs_write_seq(dsi, 0x35, 0x40);
+	mipi_dsi_dcs_write_seq(dsi, 0x36, 0xde);
+	mipi_dsi_dcs_write_seq(dsi, 0x37, 0xf9);
+	mipi_dsi_dcs_write_seq(dsi, 0x38, 0x45);
+	mipi_dsi_dcs_write_seq(dsi, 0x39, 0xd9);
+	mipi_dsi_dcs_write_seq(dsi, 0x3a, 0x49);
+	mipi_dsi_dcs_write_seq(dsi, 0x4a, 0xf0);
+	mipi_dsi_dcs_write_seq(dsi, 0x7a, 0x09);
+	mipi_dsi_dcs_write_seq(dsi, 0x7b, 0x40);
+	mipi_dsi_dcs_write_seq(dsi, 0x7f, 0xf0);
+	mipi_dsi_dcs_write_seq(dsi, 0x83, 0x0f);
+	mipi_dsi_dcs_write_seq(dsi, 0x84, 0xa4);
+	mipi_dsi_dcs_write_seq(dsi, 0x87, 0x0f);
+	mipi_dsi_dcs_write_seq(dsi, 0x88, 0x78);
+	mipi_dsi_dcs_write_seq(dsi, 0x89, 0x23);
+	mipi_dsi_dcs_write_seq(dsi, 0x8b, 0x36);
+	mipi_dsi_dcs_write_seq(dsi, 0x8c, 0x7d);
+	mipi_dsi_dcs_write_seq(dsi, 0x8d, 0x7d);
+	mipi_dsi_dcs_write_seq(dsi, 0x8e, 0x7d);
+	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x20);
+	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00,
+				0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8);
+	mipi_dsi_dcs_write_seq(dsi, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01,
+				0x7a, 0x01, 0xa9, 0x01, 0xf2, 0x02, 0x2d, 0x02, 0x2e);
+	mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03,
+				0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
+	mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
+				0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
+				0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1);
+	mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01,
+				0x83, 0x01, 0xb2, 0x01, 0xfa, 0x02, 0x34, 0x02, 0x36);
+	mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03,
+				0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b);
+	mipi_dsi_dcs_write_seq(dsi, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03,
+				0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
+				0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1);
+	mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01,
+				0x81, 0x01, 0xaf, 0x01, 0xf5, 0x02, 0x2f, 0x02, 0x31);
+	mipi_dsi_dcs_write_seq(dsi, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03,
+				0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
+	mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
+				0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x21);
+	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0xb0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x49, 0x00,
+				0x6a, 0x00, 0x89, 0x00, 0x9f, 0x00, 0xb6, 0x00, 0xc8);
+	mipi_dsi_dcs_write_seq(dsi, 0xb1, 0x00, 0xd9, 0x01, 0x10, 0x01, 0x3a, 0x01,
+				0x7a, 0x01, 0xa9, 0x01, 0xf2, 0x02, 0x2d, 0x02, 0x2e);
+	mipi_dsi_dcs_write_seq(dsi, 0xb2, 0x02, 0x64, 0x02, 0xa3, 0x02, 0xca, 0x03,
+				0x00, 0x03, 0x1e, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
+	mipi_dsi_dcs_write_seq(dsi, 0xb3, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
+				0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0xb4, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
+				0x71, 0x00, 0x90, 0x00, 0xa7, 0x00, 0xbf, 0x00, 0xd1);
+	mipi_dsi_dcs_write_seq(dsi, 0xb5, 0x00, 0xe2, 0x01, 0x1a, 0x01, 0x43, 0x01,
+				0x83, 0x01, 0xb2, 0x01, 0xfa, 0x02, 0x34, 0x02, 0x36);
+	mipi_dsi_dcs_write_seq(dsi, 0xb6, 0x02, 0x6b, 0x02, 0xa8, 0x02, 0xd0, 0x03,
+				0x03, 0x03, 0x21, 0x03, 0x4d, 0x03, 0x5b, 0x03, 0x6b);
+	mipi_dsi_dcs_write_seq(dsi, 0xb7, 0x03, 0x7e, 0x03, 0x94, 0x03, 0xac, 0x03,
+				0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0xb8, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x51, 0x00,
+				0x72, 0x00, 0x92, 0x00, 0xa8, 0x00, 0xbf, 0x00, 0xd1);
+	mipi_dsi_dcs_write_seq(dsi, 0xb9, 0x00, 0xe2, 0x01, 0x18, 0x01, 0x42, 0x01,
+				0x81, 0x01, 0xaf, 0x01, 0xf5, 0x02, 0x2f, 0x02, 0x31);
+	mipi_dsi_dcs_write_seq(dsi, 0xba, 0x02, 0x68, 0x02, 0xa6, 0x02, 0xcd, 0x03,
+				0x01, 0x03, 0x1f, 0x03, 0x4a, 0x03, 0x59, 0x03, 0x6a);
+	mipi_dsi_dcs_write_seq(dsi, 0xbb, 0x03, 0x7d, 0x03, 0x93, 0x03, 0xab, 0x03,
+				0xc8, 0x03, 0xec, 0x03, 0xfe, 0x00, 0x00);
+	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x2c);
+	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x61, 0x1f);
+	mipi_dsi_dcs_write_seq(dsi, 0x62, 0x1f);
+	mipi_dsi_dcs_write_seq(dsi, 0x7e, 0x03);
+	mipi_dsi_dcs_write_seq(dsi, 0x6a, 0x14);
+	mipi_dsi_dcs_write_seq(dsi, 0x6b, 0x36);
+	mipi_dsi_dcs_write_seq(dsi, 0x6c, 0x36);
+	mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x36);
+	mipi_dsi_dcs_write_seq(dsi, 0x53, 0x04);
+	mipi_dsi_dcs_write_seq(dsi, 0x54, 0x04);
+	mipi_dsi_dcs_write_seq(dsi, 0x55, 0x04);
+	mipi_dsi_dcs_write_seq(dsi, 0x56, 0x0f);
+	mipi_dsi_dcs_write_seq(dsi, 0x58, 0x0f);
+	mipi_dsi_dcs_write_seq(dsi, 0x59, 0x0f);
+	mipi_dsi_dcs_write_seq(dsi, 0xff, 0xf0);
+	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x5a, 0x00);
+
+	mipi_dsi_dcs_write_seq(dsi, 0xff, 0x10);
+	mipi_dsi_dcs_write_seq(dsi, 0xfb, 0x01);
+	mipi_dsi_dcs_write_seq(dsi, 0x51, 0xff);
+	mipi_dsi_dcs_write_seq(dsi, 0x53, 0x24);
+	mipi_dsi_dcs_write_seq(dsi, 0x55, 0x01);
+
+	return 0;
+}
+
+static int nt36672e_power_on(struct nt36672e_panel *ctx)
+{
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	int ret, i;
+
+	for (i = 0; i < ARRAY_SIZE(ctx->supplies); i++) {
+		ret = regulator_set_load(ctx->supplies[i].consumer,
+				regulator_enable_loads[i]);
+		if (ret) {
+			dev_err(&dsi->dev, "regulator set load failed for supply %s: %d\n",
+				ctx->supplies[i].supply, ret);
+			return ret;
+		}
+	}
+
+	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	if (ret < 0) {
+		dev_err(&dsi->dev, "regulator bulk enable failed: %d\n", ret);
+		return ret;
+	}
+
+	/*
+	 * Reset sequence of nt36672e panel requires the panel to be out of reset
+	 * for 10ms, followed by being held in reset for 10ms and then out again.
+	 */
+	gpiod_set_value(ctx->reset_gpio, 1);
+	usleep_range(10000, 20000);
+	gpiod_set_value(ctx->reset_gpio, 0);
+	usleep_range(10000, 20000);
+	gpiod_set_value(ctx->reset_gpio, 1);
+	usleep_range(10000, 20000);
+
+	return 0;
+}
+
+static int nt36672e_power_off(struct nt36672e_panel *ctx)
+{
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	int ret = 0;
+	int i;
+
+	gpiod_set_value(ctx->reset_gpio, 0);
+
+	for (i = 0; i < ARRAY_SIZE(ctx->supplies); i++) {
+		ret = regulator_set_load(ctx->supplies[i].consumer,
+				regulator_disable_loads[i]);
+		if (ret) {
+			dev_err(&dsi->dev, "regulator set load failed for supply %s: %d\n",
+				ctx->supplies[i].supply, ret);
+			return ret;
+		}
+	}
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
+	if (ret)
+		dev_err(&dsi->dev, "regulator bulk disable failed: %d\n", ret);
+
+	return ret;
+}
+
+static int nt36672e_on(struct nt36672e_panel *ctx)
+{
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	const struct panel_desc *desc = ctx->desc;
+	int ret = 0;
+
+	dsi->mode_flags |= MIPI_DSI_MODE_LPM;
+
+	if (desc->init_sequence) {
+		ret = desc->init_sequence(dsi);
+		if (ret < 0) {
+			dev_err(&dsi->dev, "panel init sequence failed: %d\n", ret);
+			return ret;
+		}
+	}
+
+	ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
+	if (ret < 0) {
+		dev_err(&dsi->dev, "Failed to exit sleep mode: %d\n", ret);
+		return ret;
+	}
+	msleep(120);
+
+	ret = mipi_dsi_dcs_set_display_on(dsi);
+	if (ret < 0) {
+		dev_err(&dsi->dev, "Failed to set display on: %d\n", ret);
+		return ret;
+	}
+	msleep(100);
+
+	return 0;
+}
+
+static int nt36672e_off(struct nt36672e_panel *ctx)
+{
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	int ret = 0;
+
+	dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
+
+	ret = mipi_dsi_dcs_set_display_off(dsi);
+	if (ret < 0) {
+		dev_err(&dsi->dev, "Failed to set display off: %d\n", ret);
+		return ret;
+	}
+	msleep(20);
+
+	ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
+	if (ret < 0) {
+		dev_err(&dsi->dev, "Failed to enter sleep mode: %d\n", ret);
+		return ret;
+	}
+	msleep(60);
+
+	return 0;
+}
+
+static int nt36672e_panel_prepare(struct drm_panel *panel)
+{
+	struct nt36672e_panel *ctx = to_nt36672e_panel(panel);
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	int ret = 0;
+
+	ret = nt36672e_power_on(ctx);
+	if (ret < 0)
+		return ret;
+
+	ret = nt36672e_on(ctx);
+	if (ret < 0) {
+		dev_err(&dsi->dev, "Failed to initialize panel: %d\n", ret);
+		if (nt36672e_power_off(ctx))
+			dev_err(&dsi->dev, "power off failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int nt36672e_panel_unprepare(struct drm_panel *panel)
+{
+	struct nt36672e_panel *ctx = to_nt36672e_panel(panel);
+	struct mipi_dsi_device *dsi = ctx->dsi;
+	int ret = 0;
+
+	ret = nt36672e_off(ctx);
+	if (ret < 0)
+		dev_err(&dsi->dev, "Failed to un-initialize panel: %d\n", ret);
+
+	ret = nt36672e_power_off(ctx);
+	if (ret < 0)
+		dev_err(&dsi->dev, "power off failed: %d\n", ret);
+
+	return 0;
+}
+
+static const struct drm_display_mode nt36672e_1080x2408_60hz = {
+	.name = "1080x2408",
+	.clock = 181690,
+	.hdisplay = 1080,
+	.hsync_start = 1080 + 76,
+	.hsync_end = 1080 + 76 + 12,
+	.htotal = 1080 + 76 + 12 + 56,
+	.vdisplay = 2408,
+	.vsync_start = 2408 + 46,
+	.vsync_end = 2408 + 46 + 10,
+	.vtotal = 2408 + 46 + 10 + 10,
+	.flags = 0,
+};
+
+static const struct panel_desc nt36672e_panel_desc = {
+	.display_mode = &nt36672e_1080x2408_60hz,
+	.width_mm = 74,
+	.height_mm = 131,
+	.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM | MIPI_DSI_CLOCK_NON_CONTINUOUS,
+	.format = MIPI_DSI_FMT_RGB888,
+	.lanes = 4,
+	.panel_name = "nt36672e fhd plus panel",
+	.init_sequence = nt36672e_1080x2408_60hz_init,
+};
+
+static int nt36672e_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector)
+{
+	struct nt36672e_panel *ctx = to_nt36672e_panel(panel);
+	struct drm_display_mode *mode;
+
+	mode = drm_mode_duplicate(connector->dev, ctx->desc->display_mode);
+	if (!mode)
+		return -ENOMEM;
+
+	drm_mode_set_name(mode);
+
+	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+	connector->display_info.width_mm = ctx->desc->width_mm;
+	connector->display_info.height_mm = ctx->desc->height_mm;
+	drm_mode_probed_add(connector, mode);
+
+	return 1;
+}
+
+static const struct drm_panel_funcs nt36672e_drm_funcs = {
+	.prepare = nt36672e_panel_prepare,
+	.unprepare = nt36672e_panel_unprepare,
+	.get_modes = nt36672e_panel_get_modes,
+};
+
+static int nt36672e_panel_probe(struct mipi_dsi_device *dsi)
+{
+	struct device *dev = &dsi->dev;
+	struct nt36672e_panel *ctx;
+	int i, ret = 0;
+
+	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	ctx->desc = of_device_get_match_data(dev);
+	if (!ctx->desc) {
+		dev_err(dev, "missing device configuration\n");
+		return -ENODEV;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(ctx->supplies); i++)
+		ctx->supplies[i].supply = regulator_names[i];
+
+	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
+			ctx->supplies);
+	if (ret < 0)
+		return ret;
+
+	ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(ctx->reset_gpio))
+		return dev_err_probe(dev, PTR_ERR(ctx->reset_gpio), "Failed to get reset-gpios\n");
+
+	ctx->dsi = dsi;
+	mipi_dsi_set_drvdata(dsi, ctx);
+
+	dsi->lanes = ctx->desc->lanes;
+	dsi->format = ctx->desc->format;
+	dsi->mode_flags = ctx->desc->mode_flags;
+
+	drm_panel_init(&ctx->panel, dev, &nt36672e_drm_funcs, DRM_MODE_CONNECTOR_DSI);
+
+	ret = drm_panel_of_backlight(&ctx->panel);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to get backlight\n");
+
+	ctx->panel.prepare_prev_first = true;
+
+	drm_panel_add(&ctx->panel);
+
+	ret = mipi_dsi_attach(dsi);
+	if (ret < 0) {
+		dev_err(dev, "Failed to attach to DSI host: %d\n", ret);
+		goto err_dsi_attach;
+	}
+
+	return 0;
+
+err_dsi_attach:
+	drm_panel_remove(&ctx->panel);
+	return ret;
+}
+
+static void nt36672e_panel_remove(struct mipi_dsi_device *dsi)
+{
+	struct nt36672e_panel *ctx = mipi_dsi_get_drvdata(dsi);
+
+	mipi_dsi_detach(ctx->dsi);
+	mipi_dsi_device_unregister(ctx->dsi);
+
+	drm_panel_remove(&ctx->panel);
+}
+
+static const struct of_device_id nt36672e_of_match[] = {
+	{
+		.compatible = "novatek,nt36672e",
+		.data = &nt36672e_panel_desc,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, nt36672e_of_match);
+
+static struct mipi_dsi_driver nt36672e_panel_driver = {
+	.driver = {
+		.name = "panel-novatek-nt36672e",
+		.of_match_table = nt36672e_of_match,
+	},
+	.probe = nt36672e_panel_probe,
+	.remove = nt36672e_panel_remove,
+};
+module_mipi_dsi_driver(nt36672e_panel_driver);
+
+MODULE_AUTHOR("Ritesh Kumar <quic_riteshk@quicinc.com>");
+MODULE_DESCRIPTION("Novatek NT36672E DSI Panel Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-samsung-atna33xc20.c
@@ -72,6 +72,7 @@
 	if (p->el3_was_on)
 		atana33xc20_wait(p->el_on3_off_time, 150);
 
+	drm_dp_dpcd_set_powered(p->aux, false);
 	ret = regulator_disable(p->supply);
 	if (ret)
 		return ret;
@@ -93,6 +94,7 @@
 	ret = regulator_enable(p->supply);
 	if (ret)
 		return ret;
+	drm_dp_dpcd_set_powered(p->aux, true);
 	p->powered_on_time = ktime_get_boottime();
 
 	if (p->no_hpd) {
@@ -107,19 +109,17 @@
 		if (hpd_asserted < 0)
 			ret = hpd_asserted;
 
-		if (ret)
+		if (ret) {
 			dev_warn(dev, "Error waiting for HPD GPIO: %d\n", ret);
-
-		return ret;
-	}
-
-	if (p->aux->wait_hpd_asserted) {
+			goto error;
+		}
+	} else if (p->aux->wait_hpd_asserted) {
 		ret = p->aux->wait_hpd_asserted(p->aux, HPD_MAX_US);
 
-		if (ret)
+		if (ret) {
 			dev_warn(dev, "Controller error waiting for HPD: %d\n", ret);
-
-		return ret;
+			goto error;
+		}
 	}
 
 	/*
@@ -131,6 +131,12 @@
 	 * right times.
 	 */
 	return 0;
+
+error:
+	drm_dp_dpcd_set_powered(p->aux, false);
+	regulator_disable(p->supply);
+
+	return ret;
 }
 
 static int atana33xc20_disable(struct drm_panel *panel)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-simple.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-simple.c
@@ -1367,6 +1367,23 @@
 	.vtotal = 800 + 6 + 8 + 2,
 };
 
+static const struct panel_desc boe_bp082wx1_100 = {
+	.modes = &boe_bp101wx1_100_mode,
+	.num_modes = 1,
+	.bpc = 8,
+	.size = {
+		.width = 177,
+		.height = 110,
+	},
+	.delay = {
+		.enable = 50,
+		.disable = 50,
+	},
+	.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
+	.bus_flags = DRM_BUS_FLAG_DE_HIGH,
+	.connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
 static const struct panel_desc boe_bp101wx1_100 = {
 	.modes = &boe_bp101wx1_100_mode,
 	.num_modes = 1,
@@ -2547,6 +2564,9 @@
 		.unprepare = 200,
 		.disable = 400,
 	},
+	.bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
+	.bus_flags = DRM_BUS_FLAG_DE_HIGH,
+	.connector_type = DRM_MODE_CONNECTOR_LVDS,
 };
 
 static const struct display_timing innolux_g156hce_l01_timings = {
@@ -2660,6 +2680,7 @@
 	.vfront_porch = { 3, 5, 10 },
 	.vback_porch = { 2, 5, 10 },
 	.vsync_len = { 5, 5, 5 },
+	.flags = DISPLAY_FLAGS_DE_HIGH,
 };
 
 static const struct panel_desc koe_tx26d202vm0bwa = {
@@ -4249,6 +4270,31 @@
 	.connector_type = DRM_MODE_CONNECTOR_LVDS,
 };
 
+static const struct drm_display_mode mchp_ac69t88a_mode = {
+	.clock = 25000,
+	.hdisplay = 800,
+	.hsync_start = 800 + 88,
+	.hsync_end = 800 + 88 + 5,
+	.htotal = 800 + 88 + 5 + 40,
+	.vdisplay = 480,
+	.vsync_start = 480 + 23,
+	.vsync_end = 480 + 23 + 5,
+	.vtotal = 480 + 23 + 5 + 1,
+};
+
+static const struct panel_desc mchp_ac69t88a = {
+	.modes = &mchp_ac69t88a_mode,
+	.num_modes = 1,
+	.bpc = 8,
+	.size = {
+		.width = 108,
+		.height = 65,
+	},
+	.bus_flags = DRM_BUS_FLAG_DE_HIGH,
+	.bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
+	.connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
 static const struct drm_display_mode arm_rtsm_mode[] = {
 	{
 		.clock = 65000,
@@ -4346,6 +4392,9 @@
 		.compatible = "bananapi,s070wv20-ct16",
 		.data = &bananapi_s070wv20_ct16,
 	}, {
+		.compatible = "boe,bp082wx1-100",
+		.data = &boe_bp082wx1_100,
+	}, {
 		.compatible = "boe,bp101wx1-100",
 		.data = &boe_bp101wx1_100,
 	}, {
@@ -4697,6 +4746,9 @@
 		.compatible = "yes-optoelectronics,ytc700tlag-05-201c",
 		.data = &yes_optoelectronics_ytc700tlag_05_201c,
 	}, {
+		.compatible = "microchip,ac69t88a",
+		.data = &mchp_ac69t88a,
+	}, {
 		/* Must be the last entry */
 		.compatible = "panel-dpi",
 		.data = &panel_dpi,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-sitronix-st7701.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-sitronix-st7701.c
@@ -1010,6 +1010,7 @@
 
 	drm_panel_init(&st7701->panel, &dsi->dev, &st7701_funcs,
 		       DRM_MODE_CONNECTOR_DSI);
+	st7701->panel.prepare_prev_first = true;
 
 	/**
 	 * Once sleep out has been issued, ST7701 IC required to wait 120ms
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-sitronix-st7789v.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-sitronix-st7789v.c
@@ -282,15 +282,15 @@
 static const struct drm_display_mode jt240mhqs_hwt_ek_e3_mode = {
 	.clock = 6000,
 	.hdisplay = 240,
-	.hsync_start = 240 + 28,
-	.hsync_end = 240 + 28 + 10,
-	.htotal = 240 + 28 + 10 + 10,
+	.hsync_start = 240 + 38,
+	.hsync_end = 240 + 38 + 10,
+	.htotal = 240 + 38 + 10 + 10,
 	.vdisplay = 280,
-	.vsync_start = 280 + 8,
-	.vsync_end = 280 + 8 + 4,
-	.vtotal = 280 + 8 + 4 + 4,
-	.width_mm = 43,
-	.height_mm = 37,
+	.vsync_start = 280 + 48,
+	.vsync_end = 280 + 48 + 4,
+	.vtotal = 280 + 48 + 4 + 4,
+	.width_mm = 37,
+	.height_mm = 43,
 	.flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
 };
 
@@ -643,7 +643,9 @@
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to get backlight\n");
 
-	of_drm_get_panel_orientation(spi->dev.of_node, &ctx->orientation);
+	ret = of_drm_get_panel_orientation(spi->dev.of_node, &ctx->orientation);
+	if (ret)
+		return dev_err_probe(&spi->dev, ret, "Failed to get orientation\n");
 
 	drm_panel_add(&ctx->panel);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-synaptics-r63353.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-synaptics-r63353.c
@@ -325,7 +325,7 @@
 {
 	struct r63353_panel *rpanel = mipi_dsi_get_drvdata(dsi);
 
-	r63353_panel_unprepare(&rpanel->base);
+	drm_panel_unprepare(&rpanel->base);
 }
 
 static const struct r63353_desc sharp_ls068b3sx02_data = {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panel/panel-visionox-rm69299.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panel/panel-visionox-rm69299.c
@@ -253,8 +253,6 @@
 	struct visionox_rm69299 *ctx = mipi_dsi_get_drvdata(dsi);
 
 	mipi_dsi_detach(ctx->dsi);
-	mipi_dsi_device_unregister(ctx->dsi);
-
 	drm_panel_remove(&ctx->panel);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -38,7 +38,7 @@
 		return PTR_ERR(opp);
 	dev_pm_opp_put(opp);
 
-	err =  dev_pm_opp_set_rate(dev, *freq);
+	err = dev_pm_opp_set_rate(dev, *freq);
 	if (!err)
 		ptdev->pfdevfreq.current_frequency = *freq;
 
@@ -182,6 +182,7 @@
 	 * if any and will avoid a switch off by regulator_late_cleanup()
 	 */
 	ret = dev_pm_opp_set_opp(dev, opp);
+	dev_pm_opp_put(opp);
 	if (ret) {
 		DRM_DEV_ERROR(dev, "Couldn't set recommended OPP\n");
 		return ret;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -796,3 +796,4 @@
 MODULE_AUTHOR("Panfrost Project Developers");
 MODULE_DESCRIPTION("Panfrost DRM Driver");
 MODULE_LICENSE("GPL v2");
+MODULE_SOFTDEP("pre: governor_simpleondemand");
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panfrost/panfrost_gpu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panfrost/panfrost_gpu.c
@@ -177,7 +177,6 @@
 struct panfrost_model {
 	const char *name;
 	u32 id;
-	u32 id_mask;
 	u64 features;
 	u64 issues;
 	struct {
@@ -441,19 +440,19 @@
 
 	gpu_write(pfdev, SHADER_PWROFF_LO, pfdev->features.shader_present);
 	ret = readl_relaxed_poll_timeout(pfdev->iomem + SHADER_PWRTRANS_LO,
-					 val, !val, 1, 1000);
+					 val, !val, 1, 2000);
 	if (ret)
 		dev_err(pfdev->dev, "shader power transition timeout");
 
 	gpu_write(pfdev, TILER_PWROFF_LO, pfdev->features.tiler_present);
 	ret = readl_relaxed_poll_timeout(pfdev->iomem + TILER_PWRTRANS_LO,
-					 val, !val, 1, 1000);
+					 val, !val, 1, 2000);
 	if (ret)
 		dev_err(pfdev->dev, "tiler power transition timeout");
 
 	gpu_write(pfdev, L2_PWROFF_LO, pfdev->features.l2_present);
 	ret = readl_poll_timeout(pfdev->iomem + L2_PWRTRANS_LO,
-				 val, !val, 0, 1000);
+				 val, !val, 0, 2000);
 	if (ret)
 		dev_err(pfdev->dev, "l2 power transition timeout");
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -502,11 +502,18 @@
 	mapping_set_unevictable(mapping);
 
 	for (i = page_offset; i < page_offset + NUM_FAULT_PAGES; i++) {
+		/* Can happen if the last fault only partially filled this
+		 * section of the pages array before failing. In that case
+		 * we skip already filled pages.
+		 */
+		if (pages[i])
+			continue;
+
 		pages[i] = shmem_read_mapping_page(mapping, i);
 		if (IS_ERR(pages[i])) {
 			ret = PTR_ERR(pages[i]);
 			pages[i] = NULL;
-			goto err_pages;
+			goto err_unlock;
 		}
 	}
 
@@ -514,7 +521,7 @@
 	ret = sg_alloc_table_from_pages(sgt, pages + page_offset,
 					NUM_FAULT_PAGES, 0, SZ_2M, GFP_KERNEL);
 	if (ret)
-		goto err_pages;
+		goto err_unlock;
 
 	ret = dma_map_sgtable(pfdev->dev, sgt, DMA_BIDIRECTIONAL, 0);
 	if (ret)
@@ -537,8 +544,6 @@
 
 err_map:
 	sg_free_table(sgt);
-err_pages:
-	drm_gem_shmem_put_pages(&bo->base);
 err_unlock:
 	dma_resv_unlock(obj->resv);
 err_bo:
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/qxl/qxl_display.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/qxl/qxl_display.c
@@ -236,6 +236,9 @@
 		return 0;
 
 	mode = drm_cvt_mode(dev, width, height, 60, false, false, false);
+	if (!mode)
+		return 0;
+
 	if (preferred)
 		mode->type |= DRM_MODE_TYPE_PREFERRED;
 	mode->hdisplay = width;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/atombios_encoders.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -2179,7 +2179,7 @@
 void
 radeon_atom_encoder_init(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct drm_encoder *encoder;
 
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/cik.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/cik.c
@@ -7585,7 +7585,7 @@
 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
 
 				if (rdev->irq.crtc_vblank_int[0]) {
-					drm_handle_vblank(rdev->ddev, 0);
+					drm_handle_vblank(rdev_to_drm(rdev), 0);
 					rdev->pm.vblank_sync = true;
 					wake_up(&rdev->irq.vblank_queue);
 				}
@@ -7615,7 +7615,7 @@
 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
 
 				if (rdev->irq.crtc_vblank_int[1]) {
-					drm_handle_vblank(rdev->ddev, 1);
+					drm_handle_vblank(rdev_to_drm(rdev), 1);
 					rdev->pm.vblank_sync = true;
 					wake_up(&rdev->irq.vblank_queue);
 				}
@@ -7645,7 +7645,7 @@
 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
 
 				if (rdev->irq.crtc_vblank_int[2]) {
-					drm_handle_vblank(rdev->ddev, 2);
+					drm_handle_vblank(rdev_to_drm(rdev), 2);
 					rdev->pm.vblank_sync = true;
 					wake_up(&rdev->irq.vblank_queue);
 				}
@@ -7675,7 +7675,7 @@
 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
 
 				if (rdev->irq.crtc_vblank_int[3]) {
-					drm_handle_vblank(rdev->ddev, 3);
+					drm_handle_vblank(rdev_to_drm(rdev), 3);
 					rdev->pm.vblank_sync = true;
 					wake_up(&rdev->irq.vblank_queue);
 				}
@@ -7705,7 +7705,7 @@
 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
 
 				if (rdev->irq.crtc_vblank_int[4]) {
-					drm_handle_vblank(rdev->ddev, 4);
+					drm_handle_vblank(rdev_to_drm(rdev), 4);
 					rdev->pm.vblank_sync = true;
 					wake_up(&rdev->irq.vblank_queue);
 				}
@@ -7735,7 +7735,7 @@
 					DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
 
 				if (rdev->irq.crtc_vblank_int[5]) {
-					drm_handle_vblank(rdev->ddev, 5);
+					drm_handle_vblank(rdev_to_drm(rdev), 5);
 					rdev->pm.vblank_sync = true;
 					wake_up(&rdev->irq.vblank_queue);
 				}
@@ -8581,7 +8581,7 @@
 	/* Initialize surface registers */
 	radeon_surface_init(rdev);
 	/* Initialize clocks */
-	radeon_get_clock_info(rdev->ddev);
+	radeon_get_clock_info(rdev_to_drm(rdev));
 
 	/* Fence driver */
 	radeon_fence_driver_init(rdev);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/dce6_afmt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/dce6_afmt.c
@@ -91,7 +91,7 @@
 			pin = &rdev->audio.pin[i];
 			pin_count = 0;
 
-			list_for_each_entry(encoder, &rdev->ddev->mode_config.encoder_list, head) {
+			list_for_each_entry(encoder, &rdev_to_drm(rdev)->mode_config.encoder_list, head) {
 				if (radeon_encoder_is_digital(encoder)) {
 					radeon_encoder = to_radeon_encoder(encoder);
 					dig = radeon_encoder->enc_priv;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/evergreen.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/evergreen.c
@@ -1673,7 +1673,7 @@
  */
 void evergreen_pm_prepare(struct radeon_device *rdev)
 {
-	struct drm_device *ddev = rdev->ddev;
+	struct drm_device *ddev = rdev_to_drm(rdev);
 	struct drm_crtc *crtc;
 	struct radeon_crtc *radeon_crtc;
 	u32 tmp;
@@ -1698,7 +1698,7 @@
  */
 void evergreen_pm_finish(struct radeon_device *rdev)
 {
-	struct drm_device *ddev = rdev->ddev;
+	struct drm_device *ddev = rdev_to_drm(rdev);
 	struct drm_crtc *crtc;
 	struct radeon_crtc *radeon_crtc;
 	u32 tmp;
@@ -1763,7 +1763,7 @@
  */
 void evergreen_hpd_init(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct drm_connector *connector;
 	unsigned enabled = 0;
 	u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) |
@@ -1804,7 +1804,7 @@
  */
 void evergreen_hpd_fini(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct drm_connector *connector;
 	unsigned disabled = 0;
 
@@ -4757,7 +4757,7 @@
 				event_name = "vblank";
 
 				if (rdev->irq.crtc_vblank_int[crtc_idx]) {
-					drm_handle_vblank(rdev->ddev, crtc_idx);
+					drm_handle_vblank(rdev_to_drm(rdev), crtc_idx);
 					rdev->pm.vblank_sync = true;
 					wake_up(&rdev->irq.vblank_queue);
 				}
@@ -5215,7 +5215,7 @@
 	/* Initialize surface registers */
 	radeon_surface_init(rdev);
 	/* Initialize clocks */
-	radeon_get_clock_info(rdev->ddev);
+	radeon_get_clock_info(rdev_to_drm(rdev));
 	/* Fence driver */
 	radeon_fence_driver_init(rdev);
 	/* initialize AGP */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/evergreen_cs.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -395,7 +395,7 @@
 	struct evergreen_cs_track *track = p->track;
 	struct eg_surface surf;
 	unsigned pitch, slice, mslice;
-	unsigned long offset;
+	u64 offset;
 	int r;
 
 	mslice = G_028C6C_SLICE_MAX(track->cb_color_view[id]) + 1;
@@ -433,14 +433,14 @@
 		return r;
 	}
 
-	offset = track->cb_color_bo_offset[id] << 8;
+	offset = (u64)track->cb_color_bo_offset[id] << 8;
 	if (offset & (surf.base_align - 1)) {
-		dev_warn(p->dev, "%s:%d cb[%d] bo base %ld not aligned with %ld\n",
+		dev_warn(p->dev, "%s:%d cb[%d] bo base %llu not aligned with %ld\n",
 			 __func__, __LINE__, id, offset, surf.base_align);
 		return -EINVAL;
 	}
 
-	offset += surf.layer_size * mslice;
+	offset += (u64)surf.layer_size * mslice;
 	if (offset > radeon_bo_size(track->cb_color_bo[id])) {
 		/* old ddx are broken they allocate bo with w*h*bpp but
 		 * program slice with ALIGN(h, 8), catch this and patch
@@ -448,14 +448,14 @@
 		 */
 		if (!surf.mode) {
 			uint32_t *ib = p->ib.ptr;
-			unsigned long tmp, nby, bsize, size, min = 0;
+			u64 tmp, nby, bsize, size, min = 0;
 
 			/* find the height the ddx wants */
 			if (surf.nby > 8) {
 				min = surf.nby - 8;
 			}
 			bsize = radeon_bo_size(track->cb_color_bo[id]);
-			tmp = track->cb_color_bo_offset[id] << 8;
+			tmp = (u64)track->cb_color_bo_offset[id] << 8;
 			for (nby = surf.nby; nby > min; nby--) {
 				size = nby * surf.nbx * surf.bpe * surf.nsamples;
 				if ((tmp + size * mslice) <= bsize) {
@@ -467,7 +467,7 @@
 				slice = ((nby * surf.nbx) / 64) - 1;
 				if (!evergreen_surface_check(p, &surf, "cb")) {
 					/* check if this one works */
-					tmp += surf.layer_size * mslice;
+					tmp += (u64)surf.layer_size * mslice;
 					if (tmp <= bsize) {
 						ib[track->cb_color_slice_idx[id]] = slice;
 						goto old_ddx_ok;
@@ -476,9 +476,9 @@
 			}
 		}
 		dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, "
-			 "offset %d, max layer %d, bo size %ld, slice %d)\n",
+			 "offset %llu, max layer %d, bo size %ld, slice %d)\n",
 			 __func__, __LINE__, id, surf.layer_size,
-			track->cb_color_bo_offset[id] << 8, mslice,
+			(u64)track->cb_color_bo_offset[id] << 8, mslice,
 			radeon_bo_size(track->cb_color_bo[id]), slice);
 		dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n",
 			 __func__, __LINE__, surf.nbx, surf.nby,
@@ -562,7 +562,7 @@
 	struct evergreen_cs_track *track = p->track;
 	struct eg_surface surf;
 	unsigned pitch, slice, mslice;
-	unsigned long offset;
+	u64 offset;
 	int r;
 
 	mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
@@ -608,18 +608,18 @@
 		return r;
 	}
 
-	offset = track->db_s_read_offset << 8;
+	offset = (u64)track->db_s_read_offset << 8;
 	if (offset & (surf.base_align - 1)) {
-		dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n",
+		dev_warn(p->dev, "%s:%d stencil read bo base %llu not aligned with %ld\n",
 			 __func__, __LINE__, offset, surf.base_align);
 		return -EINVAL;
 	}
-	offset += surf.layer_size * mslice;
+	offset += (u64)surf.layer_size * mslice;
 	if (offset > radeon_bo_size(track->db_s_read_bo)) {
 		dev_warn(p->dev, "%s:%d stencil read bo too small (layer size %d, "
-			 "offset %ld, max layer %d, bo size %ld)\n",
+			 "offset %llu, max layer %d, bo size %ld)\n",
 			 __func__, __LINE__, surf.layer_size,
-			(unsigned long)track->db_s_read_offset << 8, mslice,
+			(u64)track->db_s_read_offset << 8, mslice,
 			radeon_bo_size(track->db_s_read_bo));
 		dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n",
 			 __func__, __LINE__, track->db_depth_size,
@@ -627,18 +627,18 @@
 		return -EINVAL;
 	}
 
-	offset = track->db_s_write_offset << 8;
+	offset = (u64)track->db_s_write_offset << 8;
 	if (offset & (surf.base_align - 1)) {
-		dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n",
+		dev_warn(p->dev, "%s:%d stencil write bo base %llu not aligned with %ld\n",
 			 __func__, __LINE__, offset, surf.base_align);
 		return -EINVAL;
 	}
-	offset += surf.layer_size * mslice;
+	offset += (u64)surf.layer_size * mslice;
 	if (offset > radeon_bo_size(track->db_s_write_bo)) {
 		dev_warn(p->dev, "%s:%d stencil write bo too small (layer size %d, "
-			 "offset %ld, max layer %d, bo size %ld)\n",
+			 "offset %llu, max layer %d, bo size %ld)\n",
 			 __func__, __LINE__, surf.layer_size,
-			(unsigned long)track->db_s_write_offset << 8, mslice,
+			(u64)track->db_s_write_offset << 8, mslice,
 			radeon_bo_size(track->db_s_write_bo));
 		return -EINVAL;
 	}
@@ -659,7 +659,7 @@
 	struct evergreen_cs_track *track = p->track;
 	struct eg_surface surf;
 	unsigned pitch, slice, mslice;
-	unsigned long offset;
+	u64 offset;
 	int r;
 
 	mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1;
@@ -706,34 +706,34 @@
 		return r;
 	}
 
-	offset = track->db_z_read_offset << 8;
+	offset = (u64)track->db_z_read_offset << 8;
 	if (offset & (surf.base_align - 1)) {
-		dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n",
+		dev_warn(p->dev, "%s:%d stencil read bo base %llu not aligned with %ld\n",
 			 __func__, __LINE__, offset, surf.base_align);
 		return -EINVAL;
 	}
-	offset += surf.layer_size * mslice;
+	offset += (u64)surf.layer_size * mslice;
 	if (offset > radeon_bo_size(track->db_z_read_bo)) {
 		dev_warn(p->dev, "%s:%d depth read bo too small (layer size %d, "
-			 "offset %ld, max layer %d, bo size %ld)\n",
+			 "offset %llu, max layer %d, bo size %ld)\n",
 			 __func__, __LINE__, surf.layer_size,
-			(unsigned long)track->db_z_read_offset << 8, mslice,
+			(u64)track->db_z_read_offset << 8, mslice,
 			radeon_bo_size(track->db_z_read_bo));
 		return -EINVAL;
 	}
 
-	offset = track->db_z_write_offset << 8;
+	offset = (u64)track->db_z_write_offset << 8;
 	if (offset & (surf.base_align - 1)) {
-		dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n",
+		dev_warn(p->dev, "%s:%d stencil write bo base %llu not aligned with %ld\n",
 			 __func__, __LINE__, offset, surf.base_align);
 		return -EINVAL;
 	}
-	offset += surf.layer_size * mslice;
+	offset += (u64)surf.layer_size * mslice;
 	if (offset > radeon_bo_size(track->db_z_write_bo)) {
 		dev_warn(p->dev, "%s:%d depth write bo too small (layer size %d, "
-			 "offset %ld, max layer %d, bo size %ld)\n",
+			 "offset %llu, max layer %d, bo size %ld)\n",
 			 __func__, __LINE__, surf.layer_size,
-			(unsigned long)track->db_z_write_offset << 8, mslice,
+			(u64)track->db_z_write_offset << 8, mslice,
 			radeon_bo_size(track->db_z_write_bo));
 		return -EINVAL;
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/ni.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/ni.c
@@ -813,7 +813,7 @@
 			err = 0;
 		} else if (rdev->smc_fw->size != smc_req_size) {
 			pr_err("ni_mc: Bogus length %zu in firmware \"%s\"\n",
-			       rdev->mc_fw->size, fw_name);
+			       rdev->smc_fw->size, fw_name);
 			err = -EINVAL;
 		}
 	}
@@ -2373,7 +2373,7 @@
 	/* Initialize surface registers */
 	radeon_surface_init(rdev);
 	/* Initialize clocks */
-	radeon_get_clock_info(rdev->ddev);
+	radeon_get_clock_info(rdev_to_drm(rdev));
 	/* Fence driver */
 	radeon_fence_driver_init(rdev);
 	/* initialize memory controller */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/pptable.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/pptable.h
@@ -424,7 +424,7 @@
 typedef struct _ATOM_PPLIB_STATE_V2
 {
       //number of valid dpm levels in this state; Driver uses it to calculate the whole 
-      //size of the state: sizeof(ATOM_PPLIB_STATE_V2) + (ucNumDPMLevels - 1) * sizeof(UCHAR)
+      //size of the state: struct_size(ATOM_PPLIB_STATE_V2, clockInfoIndex, ucNumDPMLevels)
       UCHAR ucNumDPMLevels;
       
       //a index to the array of nonClockInfos
@@ -432,14 +432,14 @@
       /**
       * Driver will read the first ucNumDPMLevels in this array
       */
-      UCHAR clockInfoIndex[1];
+      UCHAR clockInfoIndex[] __counted_by(ucNumDPMLevels);
 } ATOM_PPLIB_STATE_V2;
 
 typedef struct _StateArray{
     //how many states we have 
     UCHAR ucNumEntries;
     
-    ATOM_PPLIB_STATE_V2 states[1];
+    ATOM_PPLIB_STATE_V2 states[] /* __counted_by(ucNumEntries) */;
 }StateArray;
 
 
@@ -450,7 +450,7 @@
     //sizeof(ATOM_PPLIB_CLOCK_INFO)
     UCHAR ucEntrySize;
     
-    UCHAR clockInfo[1];
+    UCHAR clockInfo[] __counted_by(ucNumEntries);
 }ClockInfoArray;
 
 typedef struct _NonClockInfoArray{
@@ -460,7 +460,7 @@
     //sizeof(ATOM_PPLIB_NONCLOCK_INFO)
     UCHAR ucEntrySize;
     
-    ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[1];
+    ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[] __counted_by(ucNumEntries);
 }NonClockInfoArray;
 
 typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/r100.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/r100.c
@@ -458,7 +458,7 @@
  */
 void r100_pm_prepare(struct radeon_device *rdev)
 {
-	struct drm_device *ddev = rdev->ddev;
+	struct drm_device *ddev = rdev_to_drm(rdev);
 	struct drm_crtc *crtc;
 	struct radeon_crtc *radeon_crtc;
 	u32 tmp;
@@ -489,7 +489,7 @@
  */
 void r100_pm_finish(struct radeon_device *rdev)
 {
-	struct drm_device *ddev = rdev->ddev;
+	struct drm_device *ddev = rdev_to_drm(rdev);
 	struct drm_crtc *crtc;
 	struct radeon_crtc *radeon_crtc;
 	u32 tmp;
@@ -602,7 +602,7 @@
  */
 void r100_hpd_init(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct drm_connector *connector;
 	unsigned enable = 0;
 
@@ -625,7 +625,7 @@
  */
 void r100_hpd_fini(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct drm_connector *connector;
 	unsigned disable = 0;
 
@@ -797,7 +797,7 @@
 		/* Vertical blank interrupts */
 		if (status & RADEON_CRTC_VBLANK_STAT) {
 			if (rdev->irq.crtc_vblank_int[0]) {
-				drm_handle_vblank(rdev->ddev, 0);
+				drm_handle_vblank(rdev_to_drm(rdev), 0);
 				rdev->pm.vblank_sync = true;
 				wake_up(&rdev->irq.vblank_queue);
 			}
@@ -806,7 +806,7 @@
 		}
 		if (status & RADEON_CRTC2_VBLANK_STAT) {
 			if (rdev->irq.crtc_vblank_int[1]) {
-				drm_handle_vblank(rdev->ddev, 1);
+				drm_handle_vblank(rdev_to_drm(rdev), 1);
 				rdev->pm.vblank_sync = true;
 				wake_up(&rdev->irq.vblank_queue);
 			}
@@ -1015,45 +1015,65 @@
 
 	DRM_DEBUG_KMS("\n");
 
-	if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) ||
-	    (rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) ||
-	    (rdev->family == CHIP_RS200)) {
+	switch (rdev->family) {
+	case CHIP_R100:
+	case CHIP_RV100:
+	case CHIP_RV200:
+	case CHIP_RS100:
+	case CHIP_RS200:
 		DRM_INFO("Loading R100 Microcode\n");
 		fw_name = FIRMWARE_R100;
-	} else if ((rdev->family == CHIP_R200) ||
-		   (rdev->family == CHIP_RV250) ||
-		   (rdev->family == CHIP_RV280) ||
-		   (rdev->family == CHIP_RS300)) {
+		break;
+
+	case CHIP_R200:
+	case CHIP_RV250:
+	case CHIP_RV280:
+	case CHIP_RS300:
 		DRM_INFO("Loading R200 Microcode\n");
 		fw_name = FIRMWARE_R200;
-	} else if ((rdev->family == CHIP_R300) ||
-		   (rdev->family == CHIP_R350) ||
-		   (rdev->family == CHIP_RV350) ||
-		   (rdev->family == CHIP_RV380) ||
-		   (rdev->family == CHIP_RS400) ||
-		   (rdev->family == CHIP_RS480)) {
+		break;
+
+	case CHIP_R300:
+	case CHIP_R350:
+	case CHIP_RV350:
+	case CHIP_RV380:
+	case CHIP_RS400:
+	case CHIP_RS480:
 		DRM_INFO("Loading R300 Microcode\n");
 		fw_name = FIRMWARE_R300;
-	} else if ((rdev->family == CHIP_R420) ||
-		   (rdev->family == CHIP_R423) ||
-		   (rdev->family == CHIP_RV410)) {
+		break;
+
+	case CHIP_R420:
+	case CHIP_R423:
+	case CHIP_RV410:
 		DRM_INFO("Loading R400 Microcode\n");
 		fw_name = FIRMWARE_R420;
-	} else if ((rdev->family == CHIP_RS690) ||
-		   (rdev->family == CHIP_RS740)) {
+		break;
+
+	case CHIP_RS690:
+	case CHIP_RS740:
 		DRM_INFO("Loading RS690/RS740 Microcode\n");
 		fw_name = FIRMWARE_RS690;
-	} else if (rdev->family == CHIP_RS600) {
+		break;
+
+	case CHIP_RS600:
 		DRM_INFO("Loading RS600 Microcode\n");
 		fw_name = FIRMWARE_RS600;
-	} else if ((rdev->family == CHIP_RV515) ||
-		   (rdev->family == CHIP_R520) ||
-		   (rdev->family == CHIP_RV530) ||
-		   (rdev->family == CHIP_R580) ||
-		   (rdev->family == CHIP_RV560) ||
-		   (rdev->family == CHIP_RV570)) {
+		break;
+
+	case CHIP_RV515:
+	case CHIP_R520:
+	case CHIP_RV530:
+	case CHIP_R580:
+	case CHIP_RV560:
+	case CHIP_RV570:
 		DRM_INFO("Loading R500 Microcode\n");
 		fw_name = FIRMWARE_R520;
+		break;
+
+	default:
+		DRM_ERROR("Unsupported Radeon family %u\n", rdev->family);
+		return -EINVAL;
 	}
 
 	err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
@@ -1470,7 +1490,7 @@
 	header = radeon_get_ib_value(p, h_idx);
 	crtc_id = radeon_get_ib_value(p, h_idx + 5);
 	reg = R100_CP_PACKET0_GET_REG(header);
-	crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id);
+	crtc = drm_crtc_find(rdev_to_drm(p->rdev), p->filp, crtc_id);
 	if (!crtc) {
 		DRM_ERROR("cannot find crtc %d\n", crtc_id);
 		return -ENOENT;
@@ -3058,7 +3078,7 @@
 void  r100_debugfs_rbbm_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	struct dentry *root = rdev->ddev->primary->debugfs_root;
+	struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
 
 	debugfs_create_file("r100_rbbm_info", 0444, root, rdev,
 			    &r100_debugfs_rbbm_info_fops);
@@ -3068,7 +3088,7 @@
 void r100_debugfs_cp_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	struct dentry *root = rdev->ddev->primary->debugfs_root;
+	struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
 
 	debugfs_create_file("r100_cp_ring_info", 0444, root, rdev,
 			    &r100_debugfs_cp_ring_info_fops);
@@ -3080,7 +3100,7 @@
 void  r100_debugfs_mc_info_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	struct dentry *root = rdev->ddev->primary->debugfs_root;
+	struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
 
 	debugfs_create_file("r100_mc_info", 0444, root, rdev,
 			    &r100_debugfs_mc_info_fops);
@@ -3946,7 +3966,7 @@
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* post */
-	radeon_combios_asic_init(rdev->ddev);
+	radeon_combios_asic_init(rdev_to_drm(rdev));
 	/* Resume clock after posting */
 	r100_clock_startup(rdev);
 	/* Initialize surface registers */
@@ -4055,7 +4075,7 @@
 	/* Set asic errata */
 	r100_errata(rdev);
 	/* Initialize clocks */
-	radeon_get_clock_info(rdev->ddev);
+	radeon_get_clock_info(rdev_to_drm(rdev));
 	/* initialize AGP */
 	if (rdev->flags & RADEON_IS_AGP) {
 		r = radeon_agp_init(rdev);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/r300.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/r300.c
@@ -615,7 +615,7 @@
 static void rv370_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	struct dentry *root = rdev->ddev->primary->debugfs_root;
+	struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
 
 	debugfs_create_file("rv370_pcie_gart_info", 0444, root, rdev,
 			    &rv370_debugfs_pcie_gart_info_fops);
@@ -1451,7 +1451,7 @@
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* post */
-	radeon_combios_asic_init(rdev->ddev);
+	radeon_combios_asic_init(rdev_to_drm(rdev));
 	/* Resume clock after posting */
 	r300_clock_startup(rdev);
 	/* Initialize surface registers */
@@ -1537,7 +1537,7 @@
 	/* Set asic errata */
 	r300_errata(rdev);
 	/* Initialize clocks */
-	radeon_get_clock_info(rdev->ddev);
+	radeon_get_clock_info(rdev_to_drm(rdev));
 	/* initialize AGP */
 	if (rdev->flags & RADEON_IS_AGP) {
 		r = radeon_agp_init(rdev);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/r420.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/r420.c
@@ -321,7 +321,7 @@
 	if (rdev->is_atom_bios) {
 		atom_asic_init(rdev->mode_info.atom_context);
 	} else {
-		radeon_combios_asic_init(rdev->ddev);
+		radeon_combios_asic_init(rdev_to_drm(rdev));
 	}
 	/* Resume clock after posting */
 	r420_clock_resume(rdev);
@@ -413,7 +413,7 @@
 		return -EINVAL;
 
 	/* Initialize clocks */
-	radeon_get_clock_info(rdev->ddev);
+	radeon_get_clock_info(rdev_to_drm(rdev));
 	/* initialize AGP */
 	if (rdev->flags & RADEON_IS_AGP) {
 		r = radeon_agp_init(rdev);
@@ -492,7 +492,7 @@
 void r420_debugfs_pipes_info_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	struct dentry *root = rdev->ddev->primary->debugfs_root;
+	struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
 
 	debugfs_create_file("r420_pipes_info", 0444, root, rdev,
 			    &r420_debugfs_pipes_info_fops);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/r520.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/r520.c
@@ -287,7 +287,7 @@
 		atom_asic_init(rdev->mode_info.atom_context);
 	}
 	/* Initialize clocks */
-	radeon_get_clock_info(rdev->ddev);
+	radeon_get_clock_info(rdev_to_drm(rdev));
 	/* initialize AGP */
 	if (rdev->flags & RADEON_IS_AGP) {
 		r = radeon_agp_init(rdev);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/r600.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/r600.c
@@ -950,7 +950,7 @@
 
 void r600_hpd_init(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct drm_connector *connector;
 	unsigned enable = 0;
 
@@ -1017,7 +1017,7 @@
 
 void r600_hpd_fini(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct drm_connector *connector;
 	unsigned disable = 0;
 
@@ -3280,7 +3280,7 @@
 	/* Initialize surface registers */
 	radeon_surface_init(rdev);
 	/* Initialize clocks */
-	radeon_get_clock_info(rdev->ddev);
+	radeon_get_clock_info(rdev_to_drm(rdev));
 	/* Fence driver */
 	radeon_fence_driver_init(rdev);
 	if (rdev->flags & RADEON_IS_AGP) {
@@ -4136,7 +4136,7 @@
 					DRM_DEBUG("IH: D1 vblank - IH event w/o asserted irq bit?\n");
 
 				if (rdev->irq.crtc_vblank_int[0]) {
-					drm_handle_vblank(rdev->ddev, 0);
+					drm_handle_vblank(rdev_to_drm(rdev), 0);
 					rdev->pm.vblank_sync = true;
 					wake_up(&rdev->irq.vblank_queue);
 				}
@@ -4166,7 +4166,7 @@
 					DRM_DEBUG("IH: D2 vblank - IH event w/o asserted irq bit?\n");
 
 				if (rdev->irq.crtc_vblank_int[1]) {
-					drm_handle_vblank(rdev->ddev, 1);
+					drm_handle_vblank(rdev_to_drm(rdev), 1);
 					rdev->pm.vblank_sync = true;
 					wake_up(&rdev->irq.vblank_queue);
 				}
@@ -4358,7 +4358,7 @@
 static void r600_debugfs_mc_info_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	struct dentry *root = rdev->ddev->primary->debugfs_root;
+	struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
 
 	debugfs_create_file("r600_mc_info", 0444, root, rdev,
 			    &r600_debugfs_mc_info_fops);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/r600_cs.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/r600_cs.c
@@ -884,7 +884,7 @@
 	crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
 	reg = R600_CP_PACKET0_GET_REG(header);
 
-	crtc = drm_crtc_find(p->rdev->ddev, p->filp, crtc_id);
+	crtc = drm_crtc_find(rdev_to_drm(p->rdev), p->filp, crtc_id);
 	if (!crtc) {
 		DRM_ERROR("cannot find crtc %d\n", crtc_id);
 		return -ENOENT;
@@ -2104,7 +2104,7 @@
 				return -EINVAL;
 			}
 
-			offset = radeon_get_ib_value(p, idx+1) << 8;
+			offset = (u64)radeon_get_ib_value(p, idx+1) << 8;
 			if (offset != track->vgt_strmout_bo_offset[idx_value]) {
 				DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo offset does not match: 0x%llx, 0x%x\n",
 					  offset, track->vgt_strmout_bo_offset[idx_value]);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/r600_dpm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/r600_dpm.c
@@ -155,7 +155,7 @@
 
 u32 r600_dpm_get_vblank_time(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct drm_crtc *crtc;
 	struct radeon_crtc *radeon_crtc;
 	u32 vblank_in_pixels;
@@ -182,7 +182,7 @@
 
 u32 r600_dpm_get_vrefresh(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct drm_crtc *crtc;
 	struct radeon_crtc *radeon_crtc;
 	u32 vrefresh = 0;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/r600_hdmi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/r600_hdmi.c
@@ -116,7 +116,7 @@
 {
 	struct radeon_device *rdev = container_of(work, struct radeon_device,
 						  audio_work);
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct r600_audio_pin audio_status = r600_audio_status(rdev);
 	struct drm_encoder *encoder;
 	bool changed = false;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon.h
@@ -132,7 +132,6 @@
 /* RADEON_IB_POOL_SIZE must be a power of 2 */
 #define RADEON_IB_POOL_SIZE			16
 #define RADEON_DEBUGFS_MAX_COMPONENTS		32
-#define RADEONFB_CONN_LIMIT			4
 #define RADEON_BIOS_NUM_SCRATCH			8
 
 /* internal ring indices */
@@ -2479,6 +2478,11 @@
 u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 index);
 void cik_mm_wdoorbell(struct radeon_device *rdev, u32 index, u32 v);
 
+static inline struct drm_device *rdev_to_drm(struct radeon_device *rdev)
+{
+	return rdev->ddev;
+}
+
 /*
  * Cast helper
  */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_acpi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -405,11 +405,11 @@
 	if (req.pending & ATIF_DGPU_DISPLAY_EVENT) {
 		if ((rdev->flags & RADEON_IS_PX) &&
 		    radeon_atpx_dgpu_req_power_for_displays()) {
-			pm_runtime_get_sync(rdev->ddev->dev);
+			pm_runtime_get_sync(rdev_to_drm(rdev)->dev);
 			/* Just fire off a uevent and let userspace tell us what to do */
-			drm_helper_hpd_irq_event(rdev->ddev);
-			pm_runtime_mark_last_busy(rdev->ddev->dev);
-			pm_runtime_put_autosuspend(rdev->ddev->dev);
+			drm_helper_hpd_irq_event(rdev_to_drm(rdev));
+			pm_runtime_mark_last_busy(rdev_to_drm(rdev)->dev);
+			pm_runtime_put_autosuspend(rdev_to_drm(rdev)->dev);
 		}
 	}
 	/* TODO: check other events */
@@ -736,7 +736,7 @@
 		struct radeon_encoder *target = NULL;
 
 		/* Find the encoder controlling the brightness */
-		list_for_each_entry(tmp, &rdev->ddev->mode_config.encoder_list,
+		list_for_each_entry(tmp, &rdev_to_drm(rdev)->mode_config.encoder_list,
 				head) {
 			struct radeon_encoder *enc = to_radeon_encoder(tmp);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_agp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_agp.c
@@ -161,7 +161,7 @@
 
 static int radeon_agp_head_acquire(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct pci_dev *pdev = to_pci_dev(dev->dev);
 
 	if (!rdev->agp)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_atombios.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -187,7 +187,7 @@
 
 			if (i2c.valid) {
 				sprintf(stmp, "0x%x", i2c.i2c_id);
-				rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp);
+				rdev->i2c_bus[i] = radeon_i2c_create(rdev_to_drm(rdev), &i2c, stmp);
 			}
 			gpio = (ATOM_GPIO_I2C_ASSIGMENT *)
 				((u8 *)gpio + sizeof(ATOM_GPIO_I2C_ASSIGMENT));
@@ -923,8 +923,12 @@
 		max_device = ATOM_MAX_SUPPORTED_DEVICE_INFO;
 
 	for (i = 0; i < max_device; i++) {
-		ATOM_CONNECTOR_INFO_I2C ci =
-		    supported_devices->info.asConnInfo[i];
+		ATOM_CONNECTOR_INFO_I2C ci;
+
+		if (frev > 1)
+			ci = supported_devices->info_2d1.asConnInfo[i];
+		else
+			ci = supported_devices->info.asConnInfo[i];
 
 		bios_connectors[i].valid = false;
 
@@ -1713,26 +1717,29 @@
 					fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record;
 					if (fake_edid_record->ucFakeEDIDLength) {
 						struct edid *edid;
-						int edid_size =
-							max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength);
-						edid = kmalloc(edid_size, GFP_KERNEL);
-						if (edid) {
-							memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0],
-							       fake_edid_record->ucFakeEDIDLength);
+						int edid_size;
 
+						if (fake_edid_record->ucFakeEDIDLength == 128)
+							edid_size = fake_edid_record->ucFakeEDIDLength;
+						else
+							edid_size = fake_edid_record->ucFakeEDIDLength * 128;
+						edid = kmemdup(&fake_edid_record->ucFakeEDIDString[0],
+							       edid_size, GFP_KERNEL);
+						if (edid) {
 							if (drm_edid_is_valid(edid)) {
 								rdev->mode_info.bios_hardcoded_edid = edid;
 								rdev->mode_info.bios_hardcoded_edid_size = edid_size;
-							} else
+							} else {
 								kfree(edid);
+							}
 						}
+						record += struct_size(fake_edid_record,
+								      ucFakeEDIDString,
+								      edid_size);
+					} else {
+						/* empty fake edid record must be 3 bytes long */
+						record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
 					}
-					record += fake_edid_record->ucFakeEDIDLength ?
-						  struct_size(fake_edid_record,
-							      ucFakeEDIDString,
-							      fake_edid_record->ucFakeEDIDLength) :
-						  /* empty fake edid record must be 3 bytes long */
-						  sizeof(ATOM_FAKE_EDID_PATCH_RECORD) + 1;
 					break;
 				case LCD_PANEL_RESOLUTION_RECORD_TYPE:
 					panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_audio.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_audio.c
@@ -197,7 +197,7 @@
 		return;
 
 	if (rdev->mode_info.mode_config_initialized) {
-		list_for_each_entry(encoder, &rdev->ddev->mode_config.encoder_list, head) {
+		list_for_each_entry(encoder, &rdev_to_drm(rdev)->mode_config.encoder_list, head) {
 			if (radeon_encoder_is_digital(encoder)) {
 				radeon_encoder = to_radeon_encoder(encoder);
 				dig = radeon_encoder->enc_priv;
@@ -760,19 +760,25 @@
 	if (!rdev->audio.enabled || !rdev->mode_info.mode_config_initialized)
 		return 0;
 
-	list_for_each_entry(encoder, &rdev->ddev->mode_config.encoder_list, head) {
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		const struct drm_connector_helper_funcs *connector_funcs =
+				connector->helper_private;
+		encoder = connector_funcs->best_encoder(connector);
+
+		if (!encoder)
+			continue;
+
 		if (!radeon_encoder_is_digital(encoder))
 			continue;
 		radeon_encoder = to_radeon_encoder(encoder);
 		dig = radeon_encoder->enc_priv;
 		if (!dig->pin || dig->pin->id != port)
 			continue;
-		connector = radeon_get_connector_for_encoder(encoder);
-		if (!connector)
-			continue;
 		*enabled = true;
+		mutex_lock(&connector->eld_mutex);
 		ret = drm_eld_size(connector->eld);
 		memcpy(buf, connector->eld, min(max_bytes, ret));
+		mutex_unlock(&connector->eld_mutex);
 		break;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_combios.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_combios.c
@@ -372,7 +372,7 @@
 	int edid_info, size;
 	struct edid *edid;
 	unsigned char *raw;
-	edid_info = combios_get_table_offset(rdev->ddev, COMBIOS_HARDCODED_EDID_TABLE);
+	edid_info = combios_get_table_offset(rdev_to_drm(rdev), COMBIOS_HARDCODED_EDID_TABLE);
 	if (!edid_info)
 		return false;
 
@@ -642,7 +642,7 @@
 
 static struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct radeon_i2c_bus_rec i2c;
 	u16 offset;
 	u8 id, blocks, clk, data;
@@ -670,7 +670,7 @@
 
 void radeon_combios_i2c_init(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct radeon_i2c_bus_rec i2c;
 
 	/* actual hw pads
@@ -812,7 +812,7 @@
 
 bool radeon_combios_sideport_present(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	u16 igp_info;
 
 	/* sideport is AMD only */
@@ -915,7 +915,7 @@
 enum radeon_tv_std
 radeon_combios_get_tv_info(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	uint16_t tv_info;
 	enum radeon_tv_std tv_std = TV_STD_NTSC;
 
@@ -2637,7 +2637,7 @@
 
 void radeon_combios_get_power_modes(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	u16 offset, misc, misc2 = 0;
 	u8 rev, tmp;
 	int state_index = 0;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_device.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_device.c
@@ -760,7 +760,7 @@
 		if (rdev->is_atom_bios)
 			atom_asic_init(rdev->mode_info.atom_context);
 		else
-			radeon_combios_asic_init(rdev->ddev);
+			radeon_combios_asic_init(rdev_to_drm(rdev));
 		return true;
 	} else {
 		dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
@@ -980,7 +980,7 @@
 		return -ENOMEM;
 
 	rdev->mode_info.atom_card_info = atom_card_info;
-	atom_card_info->dev = rdev->ddev;
+	atom_card_info->dev = rdev_to_drm(rdev);
 	atom_card_info->reg_read = cail_reg_read;
 	atom_card_info->reg_write = cail_reg_write;
 	/* needed for iio ops */
@@ -1005,7 +1005,7 @@
 
 	mutex_init(&rdev->mode_info.atom_context->mutex);
 	mutex_init(&rdev->mode_info.atom_context->scratch_mutex);
-	radeon_atom_initialize_bios_scratch_regs(rdev->ddev);
+	radeon_atom_initialize_bios_scratch_regs(rdev_to_drm(rdev));
 	atom_allocate_fb_scratch(rdev->mode_info.atom_context);
 	return 0;
 }
@@ -1049,7 +1049,7 @@
  */
 int radeon_combios_init(struct radeon_device *rdev)
 {
-	radeon_combios_initialize_bios_scratch_regs(rdev->ddev);
+	radeon_combios_initialize_bios_scratch_regs(rdev_to_drm(rdev));
 	return 0;
 }
 
@@ -1847,7 +1847,7 @@
 
 	downgrade_write(&rdev->exclusive_lock);
 
-	drm_helper_resume_force_mode(rdev->ddev);
+	drm_helper_resume_force_mode(rdev_to_drm(rdev));
 
 	/* set the power state here in case we are a PX system or headless */
 	if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_display.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_display.c
@@ -302,13 +302,13 @@
 	if ((radeon_use_pflipirq == 2) && ASIC_IS_DCE4(rdev))
 		return;
 
-	spin_lock_irqsave(&rdev->ddev->event_lock, flags);
+	spin_lock_irqsave(&rdev_to_drm(rdev)->event_lock, flags);
 	if (radeon_crtc->flip_status != RADEON_FLIP_SUBMITTED) {
 		DRM_DEBUG_DRIVER("radeon_crtc->flip_status = %d != "
 				 "RADEON_FLIP_SUBMITTED(%d)\n",
 				 radeon_crtc->flip_status,
 				 RADEON_FLIP_SUBMITTED);
-		spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
+		spin_unlock_irqrestore(&rdev_to_drm(rdev)->event_lock, flags);
 		return;
 	}
 
@@ -334,7 +334,7 @@
 	 */
 	if (update_pending &&
 	    (DRM_SCANOUTPOS_VALID &
-	     radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id,
+	     radeon_get_crtc_scanoutpos(rdev_to_drm(rdev), crtc_id,
 					GET_DISTANCE_TO_VBLANKSTART,
 					&vpos, &hpos, NULL, NULL,
 					&rdev->mode_info.crtcs[crtc_id]->base.hwmode)) &&
@@ -347,7 +347,7 @@
 		 */
 		update_pending = 0;
 	}
-	spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
+	spin_unlock_irqrestore(&rdev_to_drm(rdev)->event_lock, flags);
 	if (!update_pending)
 		radeon_crtc_handle_flip(rdev, crtc_id);
 }
@@ -370,14 +370,14 @@
 	if (radeon_crtc == NULL)
 		return;
 
-	spin_lock_irqsave(&rdev->ddev->event_lock, flags);
+	spin_lock_irqsave(&rdev_to_drm(rdev)->event_lock, flags);
 	work = radeon_crtc->flip_work;
 	if (radeon_crtc->flip_status != RADEON_FLIP_SUBMITTED) {
 		DRM_DEBUG_DRIVER("radeon_crtc->flip_status = %d != "
 				 "RADEON_FLIP_SUBMITTED(%d)\n",
 				 radeon_crtc->flip_status,
 				 RADEON_FLIP_SUBMITTED);
-		spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
+		spin_unlock_irqrestore(&rdev_to_drm(rdev)->event_lock, flags);
 		return;
 	}
 
@@ -389,7 +389,7 @@
 	if (work->event)
 		drm_crtc_send_vblank_event(&radeon_crtc->base, work->event);
 
-	spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
+	spin_unlock_irqrestore(&rdev_to_drm(rdev)->event_lock, flags);
 
 	drm_crtc_vblank_put(&radeon_crtc->base);
 	radeon_irq_kms_pflip_irq_put(rdev, work->crtc_id);
@@ -408,7 +408,7 @@
 	struct radeon_flip_work *work =
 		container_of(__work, struct radeon_flip_work, flip_work);
 	struct radeon_device *rdev = work->rdev;
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[work->crtc_id];
 
 	struct drm_crtc *crtc = &radeon_crtc->base;
@@ -683,7 +683,7 @@
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_crtc *radeon_crtc;
 
-	radeon_crtc = kzalloc(sizeof(struct radeon_crtc) + (RADEONFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
+	radeon_crtc = kzalloc(sizeof(*radeon_crtc), GFP_KERNEL);
 	if (radeon_crtc == NULL)
 		return;
 
@@ -709,12 +709,6 @@
 	dev->mode_config.cursor_width = radeon_crtc->max_cursor_width;
 	dev->mode_config.cursor_height = radeon_crtc->max_cursor_height;
 
-#if 0
-	radeon_crtc->mode_set.crtc = &radeon_crtc->base;
-	radeon_crtc->mode_set.connectors = (struct drm_connector **)(radeon_crtc + 1);
-	radeon_crtc->mode_set.num_connectors = 0;
-#endif
-
 	if (rdev->is_atom_bios && (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom))
 		radeon_atombios_init_crtc(dev, radeon_crtc);
 	else
@@ -1407,7 +1401,7 @@
 
 	if (rdev->is_atom_bios) {
 		rdev->mode_info.coherent_mode_property =
-			drm_property_create_range(rdev->ddev, 0 , "coherent", 0, 1);
+			drm_property_create_range(rdev_to_drm(rdev), 0, "coherent", 0, 1);
 		if (!rdev->mode_info.coherent_mode_property)
 			return -ENOMEM;
 	}
@@ -1415,57 +1409,57 @@
 	if (!ASIC_IS_AVIVO(rdev)) {
 		sz = ARRAY_SIZE(radeon_tmds_pll_enum_list);
 		rdev->mode_info.tmds_pll_property =
-			drm_property_create_enum(rdev->ddev, 0,
+			drm_property_create_enum(rdev_to_drm(rdev), 0,
 					    "tmds_pll",
 					    radeon_tmds_pll_enum_list, sz);
 	}
 
 	rdev->mode_info.load_detect_property =
-		drm_property_create_range(rdev->ddev, 0, "load detection", 0, 1);
+		drm_property_create_range(rdev_to_drm(rdev), 0, "load detection", 0, 1);
 	if (!rdev->mode_info.load_detect_property)
 		return -ENOMEM;
 
-	drm_mode_create_scaling_mode_property(rdev->ddev);
+	drm_mode_create_scaling_mode_property(rdev_to_drm(rdev));
 
 	sz = ARRAY_SIZE(radeon_tv_std_enum_list);
 	rdev->mode_info.tv_std_property =
-		drm_property_create_enum(rdev->ddev, 0,
+		drm_property_create_enum(rdev_to_drm(rdev), 0,
 				    "tv standard",
 				    radeon_tv_std_enum_list, sz);
 
 	sz = ARRAY_SIZE(radeon_underscan_enum_list);
 	rdev->mode_info.underscan_property =
-		drm_property_create_enum(rdev->ddev, 0,
+		drm_property_create_enum(rdev_to_drm(rdev), 0,
 				    "underscan",
 				    radeon_underscan_enum_list, sz);
 
 	rdev->mode_info.underscan_hborder_property =
-		drm_property_create_range(rdev->ddev, 0,
+		drm_property_create_range(rdev_to_drm(rdev), 0,
 					"underscan hborder", 0, 128);
 	if (!rdev->mode_info.underscan_hborder_property)
 		return -ENOMEM;
 
 	rdev->mode_info.underscan_vborder_property =
-		drm_property_create_range(rdev->ddev, 0,
+		drm_property_create_range(rdev_to_drm(rdev), 0,
 					"underscan vborder", 0, 128);
 	if (!rdev->mode_info.underscan_vborder_property)
 		return -ENOMEM;
 
 	sz = ARRAY_SIZE(radeon_audio_enum_list);
 	rdev->mode_info.audio_property =
-		drm_property_create_enum(rdev->ddev, 0,
+		drm_property_create_enum(rdev_to_drm(rdev), 0,
 					 "audio",
 					 radeon_audio_enum_list, sz);
 
 	sz = ARRAY_SIZE(radeon_dither_enum_list);
 	rdev->mode_info.dither_property =
-		drm_property_create_enum(rdev->ddev, 0,
+		drm_property_create_enum(rdev_to_drm(rdev), 0,
 					 "dither",
 					 radeon_dither_enum_list, sz);
 
 	sz = ARRAY_SIZE(radeon_output_csc_enum_list);
 	rdev->mode_info.output_csc_property =
-		drm_property_create_enum(rdev->ddev, 0,
+		drm_property_create_enum(rdev_to_drm(rdev), 0,
 					 "output_csc",
 					 radeon_output_csc_enum_list, sz);
 
@@ -1584,29 +1578,29 @@
 	int i;
 	int ret;
 
-	drm_mode_config_init(rdev->ddev);
+	drm_mode_config_init(rdev_to_drm(rdev));
 	rdev->mode_info.mode_config_initialized = true;
 
-	rdev->ddev->mode_config.funcs = &radeon_mode_funcs;
+	rdev_to_drm(rdev)->mode_config.funcs = &radeon_mode_funcs;
 
 	if (radeon_use_pflipirq == 2 && rdev->family >= CHIP_R600)
-		rdev->ddev->mode_config.async_page_flip = true;
+		rdev_to_drm(rdev)->mode_config.async_page_flip = true;
 
 	if (ASIC_IS_DCE5(rdev)) {
-		rdev->ddev->mode_config.max_width = 16384;
-		rdev->ddev->mode_config.max_height = 16384;
+		rdev_to_drm(rdev)->mode_config.max_width = 16384;
+		rdev_to_drm(rdev)->mode_config.max_height = 16384;
 	} else if (ASIC_IS_AVIVO(rdev)) {
-		rdev->ddev->mode_config.max_width = 8192;
-		rdev->ddev->mode_config.max_height = 8192;
+		rdev_to_drm(rdev)->mode_config.max_width = 8192;
+		rdev_to_drm(rdev)->mode_config.max_height = 8192;
 	} else {
-		rdev->ddev->mode_config.max_width = 4096;
-		rdev->ddev->mode_config.max_height = 4096;
+		rdev_to_drm(rdev)->mode_config.max_width = 4096;
+		rdev_to_drm(rdev)->mode_config.max_height = 4096;
 	}
 
-	rdev->ddev->mode_config.preferred_depth = 24;
-	rdev->ddev->mode_config.prefer_shadow = 1;
+	rdev_to_drm(rdev)->mode_config.preferred_depth = 24;
+	rdev_to_drm(rdev)->mode_config.prefer_shadow = 1;
 
-	rdev->ddev->mode_config.fb_modifiers_not_supported = true;
+	rdev_to_drm(rdev)->mode_config.fb_modifiers_not_supported = true;
 
 	ret = radeon_modeset_create_props(rdev);
 	if (ret) {
@@ -1624,11 +1618,11 @@
 
 	/* allocate crtcs */
 	for (i = 0; i < rdev->num_crtc; i++) {
-		radeon_crtc_init(rdev->ddev, i);
+		radeon_crtc_init(rdev_to_drm(rdev), i);
 	}
 
 	/* okay we should have all the bios connectors */
-	ret = radeon_setup_enc_conn(rdev->ddev);
+	ret = radeon_setup_enc_conn(rdev_to_drm(rdev));
 	if (!ret) {
 		return ret;
 	}
@@ -1645,7 +1639,7 @@
 	/* setup afmt */
 	radeon_afmt_init(rdev);
 
-	drm_kms_helper_poll_init(rdev->ddev);
+	drm_kms_helper_poll_init(rdev_to_drm(rdev));
 
 	/* do pm late init */
 	ret = radeon_pm_late_init(rdev);
@@ -1656,11 +1650,11 @@
 void radeon_modeset_fini(struct radeon_device *rdev)
 {
 	if (rdev->mode_info.mode_config_initialized) {
-		drm_kms_helper_poll_fini(rdev->ddev);
+		drm_kms_helper_poll_fini(rdev_to_drm(rdev));
 		radeon_hpd_fini(rdev);
-		drm_helper_force_disable_all(rdev->ddev);
+		drm_helper_force_disable_all(rdev_to_drm(rdev));
 		radeon_afmt_fini(rdev);
-		drm_mode_config_cleanup(rdev->ddev);
+		drm_mode_config_cleanup(rdev_to_drm(rdev));
 		rdev->mode_info.mode_config_initialized = false;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_encoders.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -43,7 +43,7 @@
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	struct drm_encoder *clone_encoder;
-	uint32_t index_mask = 0;
+	uint32_t index_mask = drm_encoder_mask(encoder);
 	int count;
 
 	/* DIG routing gets problematic */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_fbdev.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_fbdev.c
@@ -67,7 +67,7 @@
 	int height = mode_cmd->height;
 	u32 cpp;
 
-	info = drm_get_format_info(rdev->ddev, mode_cmd);
+	info = drm_get_format_info(rdev_to_drm(rdev), mode_cmd);
 	cpp = info->cpp[0];
 
 	/* need to align pitch with crtc limits */
@@ -148,15 +148,15 @@
 	struct radeon_device *rdev = fb_helper->dev->dev_private;
 	int ret;
 
-	ret = pm_runtime_get_sync(rdev->ddev->dev);
+	ret = pm_runtime_get_sync(rdev_to_drm(rdev)->dev);
 	if (ret < 0 && ret != -EACCES)
 		goto err_pm_runtime_mark_last_busy;
 
 	return 0;
 
 err_pm_runtime_mark_last_busy:
-	pm_runtime_mark_last_busy(rdev->ddev->dev);
-	pm_runtime_put_autosuspend(rdev->ddev->dev);
+	pm_runtime_mark_last_busy(rdev_to_drm(rdev)->dev);
+	pm_runtime_put_autosuspend(rdev_to_drm(rdev)->dev);
 	return ret;
 }
 
@@ -165,8 +165,8 @@
 	struct drm_fb_helper *fb_helper = info->par;
 	struct radeon_device *rdev = fb_helper->dev->dev_private;
 
-	pm_runtime_mark_last_busy(rdev->ddev->dev);
-	pm_runtime_put_autosuspend(rdev->ddev->dev);
+	pm_runtime_mark_last_busy(rdev_to_drm(rdev)->dev);
+	pm_runtime_put_autosuspend(rdev_to_drm(rdev)->dev);
 
 	return 0;
 }
@@ -236,7 +236,7 @@
 		ret = -ENOMEM;
 		goto err_radeon_fbdev_destroy_pinned_object;
 	}
-	ret = radeon_framebuffer_init(rdev->ddev, fb, &mode_cmd, gobj);
+	ret = radeon_framebuffer_init(rdev_to_drm(rdev), fb, &mode_cmd, gobj);
 	if (ret) {
 		DRM_ERROR("failed to initialize framebuffer %d\n", ret);
 		goto err_kfree;
@@ -374,12 +374,12 @@
 	fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL);
 	if (!fb_helper)
 		return;
-	drm_fb_helper_prepare(rdev->ddev, fb_helper, bpp_sel, &radeon_fbdev_fb_helper_funcs);
+	drm_fb_helper_prepare(rdev_to_drm(rdev), fb_helper, bpp_sel, &radeon_fbdev_fb_helper_funcs);
 
-	ret = drm_client_init(rdev->ddev, &fb_helper->client, "radeon-fbdev",
+	ret = drm_client_init(rdev_to_drm(rdev), &fb_helper->client, "radeon-fbdev",
 			      &radeon_fbdev_client_funcs);
 	if (ret) {
-		drm_err(rdev->ddev, "Failed to register client: %d\n", ret);
+		drm_err(rdev_to_drm(rdev), "Failed to register client: %d\n", ret);
 		goto err_drm_client_init;
 	}
 
@@ -394,13 +394,13 @@
 
 void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state)
 {
-	if (rdev->ddev->fb_helper)
-		drm_fb_helper_set_suspend(rdev->ddev->fb_helper, state);
+	if (rdev_to_drm(rdev)->fb_helper)
+		drm_fb_helper_set_suspend(rdev_to_drm(rdev)->fb_helper, state);
 }
 
 bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
 {
-	struct drm_fb_helper *fb_helper = rdev->ddev->fb_helper;
+	struct drm_fb_helper *fb_helper = rdev_to_drm(rdev)->fb_helper;
 	struct drm_gem_object *gobj;
 
 	if (!fb_helper)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_fence.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_fence.c
@@ -149,7 +149,7 @@
 		       rdev->fence_context + ring,
 		       seq);
 	radeon_fence_ring_emit(rdev, ring, *fence);
-	trace_radeon_fence_emit(rdev->ddev, ring, (*fence)->seq);
+	trace_radeon_fence_emit(rdev_to_drm(rdev), ring, (*fence)->seq);
 	radeon_fence_schedule_check(rdev, ring);
 	return 0;
 }
@@ -488,7 +488,7 @@
 		if (!target_seq[i])
 			continue;
 
-		trace_radeon_fence_wait_begin(rdev->ddev, i, target_seq[i]);
+		trace_radeon_fence_wait_begin(rdev_to_drm(rdev), i, target_seq[i]);
 		radeon_irq_kms_sw_irq_get(rdev, i);
 	}
 
@@ -510,7 +510,7 @@
 			continue;
 
 		radeon_irq_kms_sw_irq_put(rdev, i);
-		trace_radeon_fence_wait_end(rdev->ddev, i, target_seq[i]);
+		trace_radeon_fence_wait_end(rdev_to_drm(rdev), i, target_seq[i]);
 	}
 
 	return r;
@@ -994,7 +994,7 @@
 void radeon_debugfs_fence_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	struct dentry *root = rdev->ddev->primary->debugfs_root;
+	struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
 
 	debugfs_create_file("radeon_gpu_reset", 0444, root, rdev,
 			    &radeon_debugfs_gpu_reset_fops);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_gem.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_gem.c
@@ -641,7 +641,7 @@
 	if (r)
 		goto error_unlock;
 
-	if (bo_va->it.start)
+	if (bo_va->it.start && bo_va->bo)
 		r = radeon_vm_bo_update(rdev, bo_va, bo_va->bo->tbo.resource);
 
 error_unlock:
@@ -898,7 +898,7 @@
 void radeon_gem_debugfs_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	struct dentry *root = rdev->ddev->primary->debugfs_root;
+	struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
 
 	debugfs_create_file("radeon_gem_info", 0444, root, rdev,
 			    &radeon_debugfs_gem_info_fops);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_i2c.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -1011,7 +1011,7 @@
 		    struct radeon_i2c_bus_rec *rec,
 		    const char *name)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	int i;
 
 	for (i = 0; i < RADEON_MAX_I2C_BUS; i++) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_ib.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_ib.c
@@ -307,7 +307,7 @@
 static void radeon_debugfs_sa_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	struct dentry *root = rdev->ddev->primary->debugfs_root;
+	struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
 
 	debugfs_create_file("radeon_sa_info", 0444, root, rdev,
 			    &radeon_debugfs_sa_info_fops);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_irq_kms.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_irq_kms.c
@@ -80,7 +80,7 @@
 {
 	struct radeon_device *rdev = container_of(work, struct radeon_device,
 						  hotplug_work.work);
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct drm_mode_config *mode_config = &dev->mode_config;
 	struct drm_connector *connector;
 
@@ -101,7 +101,7 @@
 {
 	struct radeon_device *rdev = container_of(work, struct radeon_device,
 						  dp_work);
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct drm_mode_config *mode_config = &dev->mode_config;
 	struct drm_connector *connector;
 
@@ -197,7 +197,7 @@
 
 static int radeon_irq_install(struct radeon_device *rdev, int irq)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	int ret;
 
 	if (irq == IRQ_NOTCONNECTED)
@@ -218,7 +218,7 @@
 
 static void radeon_irq_uninstall(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct pci_dev *pdev = to_pci_dev(dev->dev);
 
 	radeon_driver_irq_uninstall_kms(dev);
@@ -322,9 +322,9 @@
 	spin_lock_init(&rdev->irq.lock);
 
 	/* Disable vblank irqs aggressively for power-saving */
-	rdev->ddev->vblank_disable_immediate = true;
+	rdev_to_drm(rdev)->vblank_disable_immediate = true;
 
-	r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
+	r = drm_vblank_init(rdev_to_drm(rdev), rdev->num_crtc);
 	if (r) {
 		return r;
 	}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_object.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_object.c
@@ -152,7 +152,7 @@
 	bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL);
 	if (bo == NULL)
 		return -ENOMEM;
-	drm_gem_private_object_init(rdev->ddev, &bo->tbo.base, size);
+	drm_gem_private_object_init(rdev_to_drm(rdev), &bo->tbo.base, size);
 	bo->rdev = rdev;
 	bo->surface_reg = -1;
 	INIT_LIST_HEAD(&bo->list);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_pm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_pm.c
@@ -281,7 +281,7 @@
 
 	if (rdev->irq.installed) {
 		i = 0;
-		drm_for_each_crtc(crtc, rdev->ddev) {
+		drm_for_each_crtc(crtc, rdev_to_drm(rdev)) {
 			if (rdev->pm.active_crtcs & (1 << i)) {
 				/* This can fail if a modeset is in progress */
 				if (drm_crtc_vblank_get(crtc) == 0)
@@ -298,7 +298,7 @@
 
 	if (rdev->irq.installed) {
 		i = 0;
-		drm_for_each_crtc(crtc, rdev->ddev) {
+		drm_for_each_crtc(crtc, rdev_to_drm(rdev)) {
 			if (rdev->pm.req_vblank & (1 << i)) {
 				rdev->pm.req_vblank &= ~(1 << i);
 				drm_crtc_vblank_put(crtc);
@@ -670,7 +670,7 @@
 				      char *buf)
 {
 	struct radeon_device *rdev = dev_get_drvdata(dev);
-	struct drm_device *ddev = rdev->ddev;
+	struct drm_device *ddev = rdev_to_drm(rdev);
 	int temp;
 
 	/* Can't get temperature when the card is off */
@@ -714,7 +714,7 @@
 				      struct device_attribute *attr, char *buf)
 {
 	struct radeon_device *rdev = dev_get_drvdata(dev);
-	struct drm_device *ddev = rdev->ddev;
+	struct drm_device *ddev = rdev_to_drm(rdev);
 	u32 sclk = 0;
 
 	/* Can't get clock frequency when the card is off */
@@ -739,7 +739,7 @@
 				      struct device_attribute *attr, char *buf)
 {
 	struct radeon_device *rdev = dev_get_drvdata(dev);
-	struct drm_device *ddev = rdev->ddev;
+	struct drm_device *ddev = rdev_to_drm(rdev);
 	u16 vddc = 0;
 
 	/* Can't get vddc when the card is off */
@@ -1691,7 +1691,7 @@
 
 static void radeon_pm_compute_clocks_old(struct radeon_device *rdev)
 {
-	struct drm_device *ddev = rdev->ddev;
+	struct drm_device *ddev = rdev_to_drm(rdev);
 	struct drm_crtc *crtc;
 	struct radeon_crtc *radeon_crtc;
 
@@ -1764,7 +1764,7 @@
 
 static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev)
 {
-	struct drm_device *ddev = rdev->ddev;
+	struct drm_device *ddev = rdev_to_drm(rdev);
 	struct drm_crtc *crtc;
 	struct radeon_crtc *radeon_crtc;
 	struct radeon_connector *radeon_connector;
@@ -1825,7 +1825,7 @@
 	 */
 	for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) {
 		if (rdev->pm.active_crtcs & (1 << crtc)) {
-			vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev,
+			vbl_status = radeon_get_crtc_scanoutpos(rdev_to_drm(rdev),
 								crtc,
 								USE_REAL_VBLANKSTART,
 								&vpos, &hpos, NULL, NULL,
@@ -1917,7 +1917,7 @@
 static int radeon_debugfs_pm_info_show(struct seq_file *m, void *unused)
 {
 	struct radeon_device *rdev = m->private;
-	struct drm_device *ddev = rdev->ddev;
+	struct drm_device *ddev = rdev_to_drm(rdev);
 
 	if  ((rdev->flags & RADEON_IS_PX) &&
 	     (ddev->switch_power_state != DRM_SWITCH_POWER_ON)) {
@@ -1954,7 +1954,7 @@
 static void radeon_debugfs_pm_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	struct dentry *root = rdev->ddev->primary->debugfs_root;
+	struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
 
 	debugfs_create_file("radeon_pm_info", 0444, root, rdev,
 			    &radeon_debugfs_pm_info_fops);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_ring.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_ring.c
@@ -548,7 +548,7 @@
 {
 #if defined(CONFIG_DEBUG_FS)
 	const char *ring_name = radeon_debugfs_ring_idx_to_name(ring->idx);
-	struct dentry *root = rdev->ddev->primary->debugfs_root;
+	struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
 
 	if (ring_name)
 		debugfs_create_file(ring_name, 0444, root, ring,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/radeon_ttm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -687,8 +687,8 @@
 
 	/* No others user of address space so set it to 0 */
 	r = ttm_device_init(&rdev->mman.bdev, &radeon_bo_driver, rdev->dev,
-			       rdev->ddev->anon_inode->i_mapping,
-			       rdev->ddev->vma_offset_manager,
+			       rdev_to_drm(rdev)->anon_inode->i_mapping,
+			       rdev_to_drm(rdev)->vma_offset_manager,
 			       rdev->need_swiotlb,
 			       dma_addressing_limited(&rdev->pdev->dev));
 	if (r) {
@@ -895,7 +895,7 @@
 static void radeon_ttm_debugfs_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	struct drm_minor *minor = rdev->ddev->primary;
+	struct drm_minor *minor = rdev_to_drm(rdev)->primary;
 	struct dentry *root = minor->debugfs_root;
 
 	debugfs_create_file("radeon_vram", 0444, root, rdev,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/rs400.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/rs400.c
@@ -378,7 +378,7 @@
 static void rs400_debugfs_pcie_gart_info_init(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	struct dentry *root = rdev->ddev->primary->debugfs_root;
+	struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
 
 	debugfs_create_file("rs400_gart_info", 0444, root, rdev,
 			    &rs400_debugfs_gart_info_fops);
@@ -473,7 +473,7 @@
 			RREG32(R_0007C0_CP_STAT));
 	}
 	/* post */
-	radeon_combios_asic_init(rdev->ddev);
+	radeon_combios_asic_init(rdev_to_drm(rdev));
 	/* Resume clock after posting */
 	r300_clock_startup(rdev);
 	/* Initialize surface registers */
@@ -551,7 +551,7 @@
 		return -EINVAL;
 
 	/* Initialize clocks */
-	radeon_get_clock_info(rdev->ddev);
+	radeon_get_clock_info(rdev_to_drm(rdev));
 	/* initialize memory controller */
 	rs400_mc_init(rdev);
 	/* Fence driver */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/rs600.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/rs600.c
@@ -322,7 +322,7 @@
 
 void rs600_pm_prepare(struct radeon_device *rdev)
 {
-	struct drm_device *ddev = rdev->ddev;
+	struct drm_device *ddev = rdev_to_drm(rdev);
 	struct drm_crtc *crtc;
 	struct radeon_crtc *radeon_crtc;
 	u32 tmp;
@@ -340,7 +340,7 @@
 
 void rs600_pm_finish(struct radeon_device *rdev)
 {
-	struct drm_device *ddev = rdev->ddev;
+	struct drm_device *ddev = rdev_to_drm(rdev);
 	struct drm_crtc *crtc;
 	struct radeon_crtc *radeon_crtc;
 	u32 tmp;
@@ -409,7 +409,7 @@
 
 void rs600_hpd_init(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct drm_connector *connector;
 	unsigned enable = 0;
 
@@ -436,7 +436,7 @@
 
 void rs600_hpd_fini(struct radeon_device *rdev)
 {
-	struct drm_device *dev = rdev->ddev;
+	struct drm_device *dev = rdev_to_drm(rdev);
 	struct drm_connector *connector;
 	unsigned disable = 0;
 
@@ -798,7 +798,7 @@
 		/* Vertical blank interrupts */
 		if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) {
 			if (rdev->irq.crtc_vblank_int[0]) {
-				drm_handle_vblank(rdev->ddev, 0);
+				drm_handle_vblank(rdev_to_drm(rdev), 0);
 				rdev->pm.vblank_sync = true;
 				wake_up(&rdev->irq.vblank_queue);
 			}
@@ -807,7 +807,7 @@
 		}
 		if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) {
 			if (rdev->irq.crtc_vblank_int[1]) {
-				drm_handle_vblank(rdev->ddev, 1);
+				drm_handle_vblank(rdev_to_drm(rdev), 1);
 				rdev->pm.vblank_sync = true;
 				wake_up(&rdev->irq.vblank_queue);
 			}
@@ -1134,7 +1134,7 @@
 		return -EINVAL;
 
 	/* Initialize clocks */
-	radeon_get_clock_info(rdev->ddev);
+	radeon_get_clock_info(rdev_to_drm(rdev));
 	/* initialize memory controller */
 	rs600_mc_init(rdev);
 	r100_debugfs_rbbm_init(rdev);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/rs690.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/rs690.c
@@ -845,7 +845,7 @@
 		return -EINVAL;
 
 	/* Initialize clocks */
-	radeon_get_clock_info(rdev->ddev);
+	radeon_get_clock_info(rdev_to_drm(rdev));
 	/* initialize memory controller */
 	rs690_mc_init(rdev);
 	rv515_debugfs(rdev);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/rv515.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/rv515.c
@@ -255,7 +255,7 @@
 void rv515_debugfs(struct radeon_device *rdev)
 {
 #if defined(CONFIG_DEBUG_FS)
-	struct dentry *root = rdev->ddev->primary->debugfs_root;
+	struct dentry *root = rdev_to_drm(rdev)->primary->debugfs_root;
 
 	debugfs_create_file("rv515_pipes_info", 0444, root, rdev,
 			    &rv515_debugfs_pipes_info_fops);
@@ -636,7 +636,7 @@
 	if (radeon_boot_test_post_card(rdev) == false)
 		return -EINVAL;
 	/* Initialize clocks */
-	radeon_get_clock_info(rdev->ddev);
+	radeon_get_clock_info(rdev_to_drm(rdev));
 	/* initialize AGP */
 	if (rdev->flags & RADEON_IS_AGP) {
 		r = radeon_agp_init(rdev);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/rv770.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/rv770.c
@@ -1935,7 +1935,7 @@
 	/* Initialize surface registers */
 	radeon_surface_init(rdev);
 	/* Initialize clocks */
-	radeon_get_clock_info(rdev->ddev);
+	radeon_get_clock_info(rdev_to_drm(rdev));
 	/* Fence driver */
 	radeon_fence_driver_init(rdev);
 	/* initialize AGP */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/si.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/si.c
@@ -6296,7 +6296,7 @@
 				event_name = "vblank";
 
 				if (rdev->irq.crtc_vblank_int[crtc_idx]) {
-					drm_handle_vblank(rdev->ddev, crtc_idx);
+					drm_handle_vblank(rdev_to_drm(rdev), crtc_idx);
 					rdev->pm.vblank_sync = true;
 					wake_up(&rdev->irq.vblank_queue);
 				}
@@ -6858,7 +6858,7 @@
 	/* Initialize surface registers */
 	radeon_surface_init(rdev);
 	/* Initialize clocks */
-	radeon_get_clock_info(rdev->ddev);
+	radeon_get_clock_info(rdev_to_drm(rdev));
 
 	/* Fence driver */
 	radeon_fence_driver_init(rdev);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/radeon/sumo_dpm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/radeon/sumo_dpm.c
@@ -1621,6 +1621,8 @@
 
 	for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) {
 		if (table[i].ulSupportedSCLK != 0) {
+			if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES)
+				continue;
 			vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit =
 				table[i].usVoltageID;
 			vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit =
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c
@@ -171,6 +171,13 @@
 	drm_kms_helper_poll_fini(ddev);
 }
 
+static void shmob_drm_shutdown(struct platform_device *pdev)
+{
+	struct shmob_drm_device *sdev = platform_get_drvdata(pdev);
+
+	drm_atomic_helper_shutdown(&sdev->ddev);
+}
+
 static int shmob_drm_probe(struct platform_device *pdev)
 {
 	struct shmob_drm_platform_data *pdata = pdev->dev.platform_data;
@@ -273,6 +280,7 @@
 static struct platform_driver shmob_drm_platform_driver = {
 	.probe		= shmob_drm_probe,
 	.remove_new	= shmob_drm_remove,
+	.shutdown	= shmob_drm_shutdown,
 	.driver		= {
 		.name	= "shmob-drm",
 		.of_match_table = of_match_ptr(shmob_drm_of_table),
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/rockchip/cdn-dp-core.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/rockchip/cdn-dp-core.c
@@ -946,9 +946,6 @@
 {
 	struct cdn_dp_device *dp = container_of(work, struct cdn_dp_device,
 						event_work);
-	struct drm_connector *connector = &dp->connector;
-	enum drm_connector_status old_status;
-
 	int ret;
 
 	mutex_lock(&dp->lock);
@@ -1010,11 +1007,7 @@
 
 out:
 	mutex_unlock(&dp->lock);
-
-	old_status = connector->status;
-	connector->status = connector->funcs->detect(connector, false);
-	if (old_status != connector->status)
-		drm_kms_helper_hotplug_event(dp->drm_dev);
+	drm_connector_helper_hpd_irq_event(&dp->connector);
 }
 
 static int cdn_dp_pd_event(struct notifier_block *nb,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -434,6 +434,8 @@
 		HIWORD_UPDATE(RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK,
 			      RK3328_HDMI_SDAIN_MSK | RK3328_HDMI_SCLIN_MSK |
 			      RK3328_HDMI_HPD_IOE));
+
+	dw_hdmi_rk3328_read_hpd(dw_hdmi, data);
 }
 
 static const struct dw_hdmi_phy_ops rk3228_hdmi_phy_ops = {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/rockchip/inno_hdmi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/rockchip/inno_hdmi.c
@@ -411,7 +411,7 @@
 	hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_L, value & 0xFF);
 	hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF);
 
-	value = mode->hsync_start - mode->hdisplay;
+	value = mode->htotal - mode->hsync_start;
 	hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_L, value & 0xFF);
 	hdmi_writeb(hdmi, HDMI_VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF);
 
@@ -426,7 +426,7 @@
 	value = mode->vtotal - mode->vdisplay;
 	hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VBLANK, value & 0xFF);
 
-	value = mode->vsync_start - mode->vdisplay;
+	value = mode->vtotal - mode->vsync_start;
 	hdmi_writeb(hdmi, HDMI_VIDEO_EXT_VDELAY, value & 0xFF);
 
 	value = mode->vsync_end - mode->vsync_start;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -396,8 +396,8 @@
 	if (info->is_yuv)
 		is_yuv = true;
 
-	if (dst_w > 3840) {
-		DRM_DEV_ERROR(vop->dev, "Maximum dst width (3840) exceeded\n");
+	if (dst_w > 4096) {
+		DRM_DEV_ERROR(vop->dev, "Maximum dst width (4096) exceeded\n");
 		return;
 	}
 
@@ -1093,10 +1093,10 @@
 	if (!plane->state->fb)
 		return -EINVAL;
 
-	if (state)
-		crtc_state = drm_atomic_get_existing_crtc_state(state,
-								new_plane_state->crtc);
-	else /* Special case for asynchronous cursor updates. */
+	crtc_state = drm_atomic_get_existing_crtc_state(state, new_plane_state->crtc);
+
+	/* Special case for asynchronous cursor updates. */
+	if (!crtc_state)
 		crtc_state = plane->crtc->state;
 
 	return drm_atomic_helper_check_plane_state(plane->state, crtc_state,
@@ -1583,6 +1583,10 @@
 	VOP_AFBC_SET(vop, enable, s->enable_afbc);
 	vop_cfg_done(vop);
 
+	/* Ack the DMA transfer of the previous frame (RK3066). */
+	if (VOP_HAS_REG(vop, common, dma_stop))
+		VOP_REG_SET(vop, common, dma_stop, 0);
+
 	spin_unlock(&vop->reg_lock);
 
 	/*
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/rockchip/rockchip_drm_vop.h
@@ -122,6 +122,7 @@
 	struct vop_reg lut_buffer_index;
 	struct vop_reg gate_en;
 	struct vop_reg mmu_en;
+	struct vop_reg dma_stop;
 	struct vop_reg out_mode;
 	struct vop_reg standby;
 };
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -33,7 +33,6 @@
 #include <uapi/linux/videodev2.h>
 #include <dt-bindings/soc/rockchip,vop2.h>
 
-#include "rockchip_drm_drv.h"
 #include "rockchip_drm_gem.h"
 #include "rockchip_drm_vop2.h"
 #include "rockchip_rgb.h"
@@ -550,6 +549,25 @@
 	if (modifier == DRM_FORMAT_MOD_INVALID)
 		return false;
 
+	if (vop2->data->soc_id == 3568 || vop2->data->soc_id == 3566) {
+		if (vop2_cluster_window(win)) {
+			if (modifier == DRM_FORMAT_MOD_LINEAR) {
+				drm_dbg_kms(vop2->drm,
+					    "Cluster window only supports format with afbc\n");
+				return false;
+			}
+		}
+	}
+
+	if (format == DRM_FORMAT_XRGB2101010 || format == DRM_FORMAT_XBGR2101010) {
+		if (vop2->data->soc_id == 3588) {
+			if (!rockchip_afbc(plane, modifier)) {
+				drm_dbg_kms(vop2->drm, "Only support 32 bpp format with afbc\n");
+				return false;
+			}
+		}
+	}
+
 	if (modifier == DRM_FORMAT_MOD_LINEAR)
 		return true;
 
@@ -706,6 +724,8 @@
 	const struct drm_format_info *info;
 	u16 hor_scl_mode, ver_scl_mode;
 	u16 hscl_filter_mode, vscl_filter_mode;
+	uint16_t cbcr_src_w = src_w;
+	uint16_t cbcr_src_h = src_h;
 	u8 gt2 = 0;
 	u8 gt4 = 0;
 	u32 val;
@@ -763,27 +783,27 @@
 	vop2_win_write(win, VOP2_WIN_YRGB_VSCL_FILTER_MODE, vscl_filter_mode);
 
 	if (info->is_yuv) {
-		src_w /= info->hsub;
-		src_h /= info->vsub;
+		cbcr_src_w /= info->hsub;
+		cbcr_src_h /= info->vsub;
 
 		gt4 = 0;
 		gt2 = 0;
 
-		if (src_h >= (4 * dst_h)) {
+		if (cbcr_src_h >= (4 * dst_h)) {
 			gt4 = 1;
-			src_h >>= 2;
-		} else if (src_h >= (2 * dst_h)) {
+			cbcr_src_h >>= 2;
+		} else if (cbcr_src_h >= (2 * dst_h)) {
 			gt2 = 1;
-			src_h >>= 1;
+			cbcr_src_h >>= 1;
 		}
 
-		hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
-		ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
+		hor_scl_mode = scl_get_scl_mode(cbcr_src_w, dst_w);
+		ver_scl_mode = scl_get_scl_mode(cbcr_src_h, dst_h);
 
-		val = vop2_scale_factor(src_w, dst_w);
+		val = vop2_scale_factor(cbcr_src_w, dst_w);
 		vop2_win_write(win, VOP2_WIN_SCALE_CBCR_X, val);
 
-		val = vop2_scale_factor(src_h, dst_h);
+		val = vop2_scale_factor(cbcr_src_h, dst_h);
 		vop2_win_write(win, VOP2_WIN_SCALE_CBCR_Y, val);
 
 		vop2_win_write(win, VOP2_WIN_VSD_CBCR_GT4, gt4);
@@ -1318,6 +1338,12 @@
 		&fb->format->format,
 		afbc_en ? "AFBC" : "", &yrgb_mst);
 
+	if (vop2->data->soc_id > 3568) {
+		vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data->axi_bus_id);
+		vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data->axi_yrgb_r_id);
+		vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id);
+	}
+
 	if (vop2_cluster_window(win))
 		vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en);
 
@@ -1719,9 +1745,9 @@
 		else
 			dclk_out_rate = v_pixclk >> 2;
 
-		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000);
+		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
 		if (!dclk_rate) {
-			drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld KHZ\n",
+			drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld Hz\n",
 				dclk_out_rate);
 			return 0;
 		}
@@ -1736,9 +1762,9 @@
 		 * dclk_rate = N * dclk_core_rate N = (1,2,4 ),
 		 * we get a little factor here
 		 */
-		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000);
+		dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
 		if (!dclk_rate) {
-			drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld KHZ\n",
+			drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld Hz\n",
 				dclk_out_rate);
 			return 0;
 		}
@@ -2157,7 +2183,6 @@
 
 static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win)
 {
-	u32 offset = (main_win->data->phys_id * 0x10);
 	struct vop2_alpha_config alpha_config;
 	struct vop2_alpha alpha;
 	struct drm_plane_state *bottom_win_pstate;
@@ -2165,6 +2190,7 @@
 	u16 src_glb_alpha_val, dst_glb_alpha_val;
 	bool premulti_en = false;
 	bool swap = false;
+	u32 offset = 0;
 
 	/* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
 	bottom_win_pstate = main_win->base.state;
@@ -2183,6 +2209,22 @@
 	vop2_parse_alpha(&alpha_config, &alpha);
 
 	alpha.src_color_ctrl.bits.src_dst_swap = swap;
+
+	switch (main_win->data->phys_id) {
+	case ROCKCHIP_VOP2_CLUSTER0:
+		offset = 0x0;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER1:
+		offset = 0x10;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER2:
+		offset = 0x20;
+		break;
+	case ROCKCHIP_VOP2_CLUSTER3:
+		offset = 0x30;
+		break;
+	}
+
 	vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
 		    alpha.src_color_ctrl.val);
 	vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
@@ -2230,6 +2272,12 @@
 		struct vop2_win *win = to_vop2_win(plane);
 		int zpos = plane->state->normalized_zpos;
 
+		/*
+		 * Need to configure alpha from second layer.
+		 */
+		if (zpos == 0)
+			continue;
+
 		if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
 			premulti_en = 1;
 		else
@@ -2306,7 +2354,10 @@
 	struct drm_plane *plane;
 	u32 layer_sel = 0;
 	u32 port_sel;
-	unsigned int nlayer, ofs;
+	u8 layer_id;
+	u8 old_layer_id;
+	u8 layer_sel_id;
+	unsigned int ofs;
 	u32 ovl_ctrl;
 	int i;
 	struct vop2_video_port *vp0 = &vop2->vps[0];
@@ -2342,7 +2393,7 @@
 		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
 			(vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
 	else
-		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
+		port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8);
 
 	layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
 
@@ -2350,9 +2401,30 @@
 	for (i = 0; i < vp->id; i++)
 		ofs += vop2->vps[i].nlayers;
 
-	nlayer = 0;
 	drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
 		struct vop2_win *win = to_vop2_win(plane);
+		struct vop2_win *old_win;
+
+		layer_id = (u8)(plane->state->normalized_zpos + ofs);
+
+		/*
+		 * Find the layer this win bind in old state.
+		 */
+		for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
+			layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
+			if (layer_sel_id == win->data->layer_sel_id)
+				break;
+		}
+
+		/*
+		 * Find the win bind to this layer in old state
+		 */
+		for (i = 0; i < vop2->data->win_size; i++) {
+			old_win = &vop2->win[i];
+			layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf;
+			if (layer_sel_id == old_win->data->layer_sel_id)
+				break;
+		}
 
 		switch (win->data->phys_id) {
 		case ROCKCHIP_VOP2_CLUSTER0:
@@ -2397,17 +2469,14 @@
 			break;
 		}
 
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
-							  0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(plane->state->normalized_zpos + ofs,
-							 win->data->layer_sel_id);
-		nlayer++;
-	}
-
-	/* configure unused layers to 0x5 (reserved) */
-	for (; nlayer < vp->nlayers; nlayer++) {
-		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 0x7);
-		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(nlayer + ofs, 5);
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id);
+		/*
+		 * When we bind a window from layerM to layerN, we also need to move the old
+		 * window on layerN to layerM to avoid one window selected by two or more layers.
+		 */
+		layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
+		layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
 	}
 
 	vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
@@ -2442,9 +2511,11 @@
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
 			break;
 		case ROCKCHIP_VOP2_SMART0:
+		case ROCKCHIP_VOP2_ESMART2:
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
 			break;
 		case ROCKCHIP_VOP2_SMART1:
+		case ROCKCHIP_VOP2_ESMART3:
 			sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
 			break;
 		}
@@ -2863,6 +2934,10 @@
 	[VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
 	[VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
 	[VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
+	/* RK3588 only, reserved bit on rk3568*/
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
 
 	/* Scale */
 	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
@@ -2955,6 +3030,10 @@
 	[VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
 	[VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
 	[VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
+	[VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
+	[VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
+	/* RK3588 only, reserved register on rk3568 */
+	[VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
 
 	/* Scale */
 	[VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -9,6 +9,7 @@
 
 #include <linux/regmap.h>
 #include <drm/drm_modes.h>
+#include "rockchip_drm_drv.h"
 #include "rockchip_drm_vop.h"
 
 #define VOP2_VP_FEATURE_OUTPUT_10BIT        BIT(0)
@@ -78,6 +79,9 @@
 	VOP2_WIN_COLOR_KEY,
 	VOP2_WIN_COLOR_KEY_EN,
 	VOP2_WIN_DITHER_UP,
+	VOP2_WIN_AXI_BUS_ID,
+	VOP2_WIN_AXI_YRGB_R_ID,
+	VOP2_WIN_AXI_UV_R_ID,
 
 	/* scale regs */
 	VOP2_WIN_SCALE_YRGB_X,
@@ -140,6 +144,10 @@
 	unsigned int layer_sel_id;
 	uint64_t feature;
 
+	uint8_t axi_bus_id;
+	uint8_t axi_yrgb_r_id;
+	uint8_t axi_uv_r_id;
+
 	unsigned int max_upscale_factor;
 	unsigned int max_downscale_factor;
 	const u8 dly[VOP2_DLY_MODE_MAX];
@@ -308,6 +316,7 @@
 
 #define RK3568_CLUSTER_WIN_CTRL0		0x00
 #define RK3568_CLUSTER_WIN_CTRL1		0x04
+#define RK3568_CLUSTER_WIN_CTRL2		0x08
 #define RK3568_CLUSTER_WIN_YRGB_MST		0x10
 #define RK3568_CLUSTER_WIN_CBR_MST		0x14
 #define RK3568_CLUSTER_WIN_VIR			0x18
@@ -330,6 +339,7 @@
 /* (E)smart register definition, offset relative to window base */
 #define RK3568_SMART_CTRL0			0x00
 #define RK3568_SMART_CTRL1			0x04
+#define RK3588_SMART_AXI_CTRL			0x08
 #define RK3568_SMART_REGION0_CTRL		0x10
 #define RK3568_SMART_REGION0_YRGB_MST		0x14
 #define RK3568_SMART_REGION0_CBR_MST		0x18
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/rockchip/rockchip_lvds.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/rockchip/rockchip_lvds.c
@@ -576,8 +576,7 @@
 		ret = -EINVAL;
 		goto err_put_port;
 	} else if (ret) {
-		DRM_DEV_ERROR(dev, "failed to find panel and bridge node\n");
-		ret = -EPROBE_DEFER;
+		dev_err_probe(dev, ret, "failed to find panel and bridge node\n");
 		goto err_put_port;
 	}
 	if (lvds->panel)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/rockchip/rockchip_vop2_reg.c
@@ -17,9 +17,7 @@
 
 static const uint32_t formats_cluster[] = {
 	DRM_FORMAT_XRGB2101010,
-	DRM_FORMAT_ARGB2101010,
 	DRM_FORMAT_XBGR2101010,
-	DRM_FORMAT_ABGR2101010,
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
 	DRM_FORMAT_XBGR8888,
@@ -315,7 +313,7 @@
  * AXI1 is a read only bus.
  *
  * Every window on a AXI bus must assigned two unique
- * read id(yrgb_id/uv_id, valid id are 0x1~0xe).
+ * read id(yrgb_r_id/uv_r_id, valid id are 0x1~0xe).
  *
  * AXI0:
  * Cluster0/1, Esmart0/1, WriteBack
@@ -335,6 +333,9 @@
 		.layer_sel_id = 0,
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 2,
+		.axi_uv_r_id = 3,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -351,6 +352,9 @@
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 6,
+		.axi_uv_r_id = 7,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -366,6 +370,9 @@
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 2,
+		.axi_uv_r_id = 3,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -381,6 +388,9 @@
 		.supported_rotations = DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270 |
 				       DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_PRIMARY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 6,
+		.axi_uv_r_id = 7,
 		.max_upscale_factor = 4,
 		.max_downscale_factor = 4,
 		.dly = { 4, 26, 29 },
@@ -395,6 +405,9 @@
 		.layer_sel_id = 2,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0x0a,
+		.axi_uv_r_id = 0x0b,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
@@ -408,6 +421,9 @@
 		.layer_sel_id = 3,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 0,
+		.axi_yrgb_r_id = 0x0c,
+		.axi_uv_r_id = 0x01,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
@@ -421,6 +437,9 @@
 		.layer_sel_id = 6,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 0x0a,
+		.axi_uv_r_id = 0x0b,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
@@ -434,6 +453,9 @@
 		.layer_sel_id = 7,
 		.supported_rotations = DRM_MODE_REFLECT_Y,
 		.type = DRM_PLANE_TYPE_OVERLAY,
+		.axi_bus_id = 1,
+		.axi_yrgb_r_id = 0x0c,
+		.axi_uv_r_id = 0x0d,
 		.max_upscale_factor = 8,
 		.max_downscale_factor = 8,
 		.dly = { 23, 45, 48 },
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/rockchip/rockchip_vop_reg.c
@@ -455,6 +455,7 @@
 };
 
 static const struct vop_common rk3066_common = {
+	.dma_stop = VOP_REG(RK3066_SYS_CTRL0, 0x1, 0),
 	.standby = VOP_REG(RK3066_SYS_CTRL0, 0x1, 1),
 	.out_mode = VOP_REG(RK3066_DSP_CTRL0, 0xf, 0),
 	.cfg_done = VOP_REG(RK3066_REG_CFG_DONE, 0x1, 0),
@@ -503,6 +504,7 @@
 	.output = &rk3066_output,
 	.win = rk3066_vop_win_data,
 	.win_size = ARRAY_SIZE(rk3066_vop_win_data),
+	.feature = VOP_FEATURE_INTERNAL_RGB,
 	.max_output = { 1920, 1080 },
 };
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/scheduler/sched_entity.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/scheduler/sched_entity.c
@@ -71,13 +71,19 @@
 	entity->guilty = guilty;
 	entity->num_sched_list = num_sched_list;
 	entity->priority = priority;
+	/*
+	 * It's perfectly valid to initialize an entity without having a valid
+	 * scheduler attached. It's just not valid to use the scheduler before it
+	 * is initialized itself.
+	 */
 	entity->sched_list = num_sched_list > 1 ? sched_list : NULL;
 	RCU_INIT_POINTER(entity->last_scheduled, NULL);
 	RB_CLEAR_NODE(&entity->rb_tree_node);
 
-	if (!sched_list[0]->sched_rq) {
-		/* Warn drivers not to do this and to fix their DRM
-		 * calling order.
+	if (num_sched_list && !sched_list[0]->sched_rq) {
+		/* Since every entry covered by num_sched_list
+		 * should be non-NULL and therefore we warn drivers
+		 * not to do this and to fix their DRM calling order.
 		 */
 		pr_warn("%s: called with uninitialized scheduler\n", __func__);
 	} else if (num_sched_list) {
@@ -127,8 +133,10 @@
 {
 	WARN_ON(!num_sched_list || !sched_list);
 
+	spin_lock(&entity->rq_lock);
 	entity->sched_list = sched_list;
 	entity->num_sched_list = num_sched_list;
+	spin_unlock(&entity->rq_lock);
 }
 EXPORT_SYMBOL(drm_sched_entity_modify_sched);
 
@@ -374,7 +382,7 @@
 		container_of(cb, struct drm_sched_entity, cb);
 
 	drm_sched_entity_clear_dep(f, cb);
-	drm_sched_wakeup(entity->rq->sched, entity);
+	drm_sched_wakeup(entity->rq->sched);
 }
 
 /**
@@ -591,6 +599,9 @@
 
 	/* first job wakes up scheduler */
 	if (first) {
+		struct drm_gpu_scheduler *sched;
+		struct drm_sched_rq *rq;
+
 		/* Add the entity to the run queue */
 		spin_lock(&entity->rq_lock);
 		if (entity->stopped) {
@@ -600,13 +611,16 @@
 			return;
 		}
 
-		drm_sched_rq_add_entity(entity->rq, entity);
+		rq = entity->rq;
+		sched = rq->sched;
+
+		drm_sched_rq_add_entity(rq, entity);
 		spin_unlock(&entity->rq_lock);
 
 		if (drm_sched_policy == DRM_SCHED_POLICY_FIFO)
 			drm_sched_rq_update_fifo(entity, submit_ts);
 
-		drm_sched_wakeup(entity->rq->sched, entity);
+		drm_sched_wakeup(sched);
 	}
 }
 EXPORT_SYMBOL(drm_sched_entity_push_job);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/scheduler/sched_main.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/scheduler/sched_main.c
@@ -806,6 +806,14 @@
 		return -EINVAL;
 	}
 
+	/*
+	 * We don't know for sure how the user has allocated. Thus, zero the
+	 * struct so that unallowed (i.e., too early) usage of pointers that
+	 * this function does not set is guaranteed to lead to a NULL pointer
+	 * exception instead of UB.
+	 */
+	memset(job, 0, sizeof(*job));
+
 	job->entity = entity;
 	job->credits = credits;
 	job->s_fence = drm_sched_fence_alloc(entity, owner);
@@ -1022,15 +1030,12 @@
 /**
  * drm_sched_wakeup - Wake up the scheduler if it is ready to queue
  * @sched: scheduler instance
- * @entity: the scheduler entity
  *
  * Wake up the scheduler if we can queue jobs.
  */
-void drm_sched_wakeup(struct drm_gpu_scheduler *sched,
-		      struct drm_sched_entity *entity)
+void drm_sched_wakeup(struct drm_gpu_scheduler *sched)
 {
-	if (drm_sched_can_queue(sched, entity))
-		drm_sched_run_job_queue(sched);
+	drm_sched_run_job_queue(sched);
 }
 
 /**
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/sti/sti_cursor.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/sti/sti_cursor.c
@@ -200,6 +200,9 @@
 		return 0;
 
 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	if (IS_ERR(crtc_state))
+		return PTR_ERR(crtc_state);
+
 	mode = &crtc_state->mode;
 	dst_x = new_plane_state->crtc_x;
 	dst_y = new_plane_state->crtc_y;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/sti/sti_gdp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/sti/sti_gdp.c
@@ -638,6 +638,9 @@
 
 	mixer = to_sti_mixer(crtc);
 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	if (IS_ERR(crtc_state))
+		return PTR_ERR(crtc_state);
+
 	mode = &crtc_state->mode;
 	dst_x = new_plane_state->crtc_x;
 	dst_y = new_plane_state->crtc_y;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/sti/sti_hdmi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/sti/sti_hdmi.c
@@ -1221,7 +1221,9 @@
 	struct drm_connector *connector = hdmi->drm_connector;
 
 	DRM_DEBUG_DRIVER("\n");
+	mutex_lock(&connector->eld_mutex);
 	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
+	mutex_unlock(&connector->eld_mutex);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/sti/sti_hqvdp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/sti/sti_hqvdp.c
@@ -1037,6 +1037,9 @@
 		return 0;
 
 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
+	if (IS_ERR(crtc_state))
+		return PTR_ERR(crtc_state);
+
 	mode = &crtc_state->mode;
 	dst_x = new_plane_state->crtc_x;
 	dst_y = new_plane_state->crtc_y;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/sti/sti_mixer.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/sti/sti_mixer.c
@@ -137,7 +137,7 @@
 	}
 }
 
-static void mixer_dbg_mxn(struct seq_file *s, void *addr)
+static void mixer_dbg_mxn(struct seq_file *s, void __iomem *addr)
 {
 	int i;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/stm/drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/stm/drv.c
@@ -25,6 +25,7 @@
 #include <drm/drm_module.h>
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_vblank.h>
+#include <drm/drm_managed.h>
 
 #include "ltdc.h"
 
@@ -75,7 +76,7 @@
 
 	DRM_DEBUG("%s\n", __func__);
 
-	ldev = devm_kzalloc(ddev->dev, sizeof(*ldev), GFP_KERNEL);
+	ldev = drmm_kzalloc(ddev, sizeof(*ldev), GFP_KERNEL);
 	if (!ldev)
 		return -ENOMEM;
 
@@ -203,12 +204,14 @@
 
 	ret = drm_dev_register(ddev, 0);
 	if (ret)
-		goto err_put;
+		goto err_unload;
 
 	drm_fbdev_dma_setup(ddev, 16);
 
 	return 0;
 
+err_unload:
+	drv_unload(ddev);
 err_put:
 	drm_dev_put(ddev);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/stm/ltdc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/stm/ltdc.c
@@ -36,6 +36,7 @@
 #include <drm/drm_probe_helper.h>
 #include <drm/drm_simple_kms_helper.h>
 #include <drm/drm_vblank.h>
+#include <drm/drm_managed.h>
 
 #include <video/videomode.h>
 
@@ -1199,7 +1200,6 @@
 }
 
 static const struct drm_crtc_funcs ltdc_crtc_funcs = {
-	.destroy = drm_crtc_cleanup,
 	.set_config = drm_atomic_helper_set_config,
 	.page_flip = drm_atomic_helper_page_flip,
 	.reset = drm_atomic_helper_crtc_reset,
@@ -1212,7 +1212,6 @@
 };
 
 static const struct drm_crtc_funcs ltdc_crtc_with_crc_support_funcs = {
-	.destroy = drm_crtc_cleanup,
 	.set_config = drm_atomic_helper_set_config,
 	.page_flip = drm_atomic_helper_page_flip,
 	.reset = drm_atomic_helper_crtc_reset,
@@ -1514,6 +1513,9 @@
 	/* Disable layer */
 	regmap_write_bits(ldev->regmap, LTDC_L1CR + lofs, LXCR_LEN | LXCR_CLUTEN |  LXCR_HMEN, 0);
 
+	/* Reset the layer transparency to hide any related background color */
+	regmap_write_bits(ldev->regmap, LTDC_L1CACR + lofs, LXCACR_CONSTA, 0x00);
+
 	/* Commit shadow registers = update plane at next vblank */
 	if (ldev->caps.plane_reg_shadow)
 		regmap_write_bits(ldev->regmap, LTDC_L1RCR + lofs,
@@ -1545,7 +1547,6 @@
 static const struct drm_plane_funcs ltdc_plane_funcs = {
 	.update_plane = drm_atomic_helper_update_plane,
 	.disable_plane = drm_atomic_helper_disable_plane,
-	.destroy = drm_plane_cleanup,
 	.reset = drm_atomic_helper_plane_reset,
 	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
@@ -1572,7 +1573,6 @@
 	const u64 *modifiers = ltdc_format_modifiers;
 	u32 lofs = index * LAY_OFS;
 	u32 val;
-	int ret;
 
 	/* Allocate the biggest size according to supported color formats */
 	formats = devm_kzalloc(dev, (ldev->caps.pix_fmt_nb +
@@ -1580,6 +1580,8 @@
 			       ARRAY_SIZE(ltdc_drm_fmt_ycbcr_sp) +
 			       ARRAY_SIZE(ltdc_drm_fmt_ycbcr_fp)) *
 			       sizeof(*formats), GFP_KERNEL);
+	if (!formats)
+		return NULL;
 
 	for (i = 0; i < ldev->caps.pix_fmt_nb; i++) {
 		drm_fmt = ldev->caps.pix_fmt_drm[i];
@@ -1613,14 +1615,10 @@
 		}
 	}
 
-	plane = devm_kzalloc(dev, sizeof(*plane), GFP_KERNEL);
-	if (!plane)
-		return NULL;
-
-	ret = drm_universal_plane_init(ddev, plane, possible_crtcs,
-				       &ltdc_plane_funcs, formats, nb_fmt,
-				       modifiers, type, NULL);
-	if (ret < 0)
+	plane = drmm_universal_plane_alloc(ddev, struct drm_plane, dev,
+					   possible_crtcs, &ltdc_plane_funcs, formats,
+					   nb_fmt, modifiers, type, NULL);
+	if (IS_ERR(plane))
 		return NULL;
 
 	if (ldev->caps.ycbcr_input) {
@@ -1643,15 +1641,6 @@
 	return plane;
 }
 
-static void ltdc_plane_destroy_all(struct drm_device *ddev)
-{
-	struct drm_plane *plane, *plane_temp;
-
-	list_for_each_entry_safe(plane, plane_temp,
-				 &ddev->mode_config.plane_list, head)
-		drm_plane_cleanup(plane);
-}
-
 static int ltdc_crtc_init(struct drm_device *ddev, struct drm_crtc *crtc)
 {
 	struct ltdc_device *ldev = ddev->dev_private;
@@ -1677,14 +1666,14 @@
 
 	/* Init CRTC according to its hardware features */
 	if (ldev->caps.crc)
-		ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
-						&ltdc_crtc_with_crc_support_funcs, NULL);
+		ret = drmm_crtc_init_with_planes(ddev, crtc, primary, NULL,
+						 &ltdc_crtc_with_crc_support_funcs, NULL);
 	else
-		ret = drm_crtc_init_with_planes(ddev, crtc, primary, NULL,
-						&ltdc_crtc_funcs, NULL);
+		ret = drmm_crtc_init_with_planes(ddev, crtc, primary, NULL,
+						 &ltdc_crtc_funcs, NULL);
 	if (ret) {
 		DRM_ERROR("Can not initialize CRTC\n");
-		goto cleanup;
+		return ret;
 	}
 
 	drm_crtc_helper_add(crtc, &ltdc_crtc_helper_funcs);
@@ -1698,9 +1687,8 @@
 	for (i = 1; i < ldev->caps.nb_layers; i++) {
 		overlay = ltdc_plane_create(ddev, DRM_PLANE_TYPE_OVERLAY, i);
 		if (!overlay) {
-			ret = -ENOMEM;
 			DRM_ERROR("Can not create overlay plane %d\n", i);
-			goto cleanup;
+			return -ENOMEM;
 		}
 		if (ldev->caps.dynamic_zorder)
 			drm_plane_create_zpos_property(overlay, i, 0, ldev->caps.nb_layers - 1);
@@ -1713,10 +1701,6 @@
 	}
 
 	return 0;
-
-cleanup:
-	ltdc_plane_destroy_all(ddev);
-	return ret;
 }
 
 static void ltdc_encoder_disable(struct drm_encoder *encoder)
@@ -1776,23 +1760,19 @@
 	struct drm_encoder *encoder;
 	int ret;
 
-	encoder = devm_kzalloc(ddev->dev, sizeof(*encoder), GFP_KERNEL);
-	if (!encoder)
-		return -ENOMEM;
+	encoder = drmm_simple_encoder_alloc(ddev, struct drm_encoder, dev,
+					    DRM_MODE_ENCODER_DPI);
+	if (IS_ERR(encoder))
+		return PTR_ERR(encoder);
 
 	encoder->possible_crtcs = CRTC_MASK;
 	encoder->possible_clones = 0;	/* No cloning support */
 
-	drm_simple_encoder_init(ddev, encoder, DRM_MODE_ENCODER_DPI);
-
 	drm_encoder_helper_add(encoder, &ltdc_encoder_helper_funcs);
 
 	ret = drm_bridge_attach(encoder, bridge, NULL, 0);
-	if (ret) {
-		if (ret != -EPROBE_DEFER)
-			drm_encoder_cleanup(encoder);
+	if (ret)
 		return ret;
-	}
 
 	DRM_DEBUG_DRIVER("Bridge encoder:%d created\n", encoder->base.id);
 
@@ -1962,8 +1942,7 @@
 			goto err;
 
 		if (panel) {
-			bridge = drm_panel_bridge_add_typed(panel,
-							    DRM_MODE_CONNECTOR_DPI);
+			bridge = drmm_panel_bridge_add(ddev, panel);
 			if (IS_ERR(bridge)) {
 				DRM_ERROR("panel-bridge endpoint %d\n", i);
 				ret = PTR_ERR(bridge);
@@ -2045,7 +2024,7 @@
 		}
 	}
 
-	crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL);
+	crtc = drmm_kzalloc(ddev, sizeof(*crtc), GFP_KERNEL);
 	if (!crtc) {
 		DRM_ERROR("Failed to allocate crtc\n");
 		ret = -ENOMEM;
@@ -2072,9 +2051,6 @@
 
 	return 0;
 err:
-	for (i = 0; i < nb_endpoints; i++)
-		drm_of_panel_bridge_remove(ddev->dev->of_node, 0, i);
-
 	clk_disable_unprepare(ldev->pixel_clk);
 
 	return ret;
@@ -2082,16 +2058,8 @@
 
 void ltdc_unload(struct drm_device *ddev)
 {
-	struct device *dev = ddev->dev;
-	int nb_endpoints, i;
-
 	DRM_DEBUG_DRIVER("\n");
 
-	nb_endpoints = of_graph_get_endpoint_count(dev->of_node);
-
-	for (i = 0; i < nb_endpoints; i++)
-		drm_of_panel_bridge_remove(ddev->dev->of_node, 0, i);
-
 	pm_runtime_disable(ddev->dev);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -82,7 +82,8 @@
 	return 0;
 }
 
-static void sun4i_hdmi_disable(struct drm_encoder *encoder)
+static void sun4i_hdmi_disable(struct drm_encoder *encoder,
+			       struct drm_atomic_state *state)
 {
 	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
 	u32 val;
@@ -96,37 +97,17 @@
 	clk_disable_unprepare(hdmi->tmds_clk);
 }
 
-static void sun4i_hdmi_enable(struct drm_encoder *encoder)
+static void sun4i_hdmi_enable(struct drm_encoder *encoder,
+			      struct drm_atomic_state *state)
 {
 	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
 	struct drm_display_info *display = &hdmi->connector.display_info;
+	unsigned int x, y;
 	u32 val = 0;
 
 	DRM_DEBUG_DRIVER("Enabling the HDMI Output\n");
 
-	clk_prepare_enable(hdmi->tmds_clk);
-
-	sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
-	val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
-	val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
-	writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
-
-	val = SUN4I_HDMI_VID_CTRL_ENABLE;
-	if (display->is_hdmi)
-		val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE;
-
-	writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
-}
-
-static void sun4i_hdmi_mode_set(struct drm_encoder *encoder,
-				struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode)
-{
-	struct sun4i_hdmi *hdmi = drm_encoder_to_sun4i_hdmi(encoder);
-	unsigned int x, y;
-	u32 val;
-
 	clk_set_rate(hdmi->mod_clk, mode->crtc_clock * 1000);
 	clk_set_rate(hdmi->tmds_clk, mode->crtc_clock * 1000);
 
@@ -178,6 +159,19 @@
 		val |= SUN4I_HDMI_VID_TIMING_POL_VSYNC;
 
 	writel(val, hdmi->base + SUN4I_HDMI_VID_TIMING_POL_REG);
+
+	clk_prepare_enable(hdmi->tmds_clk);
+
+	sun4i_hdmi_setup_avi_infoframes(hdmi, mode);
+	val |= SUN4I_HDMI_PKT_CTRL_TYPE(0, SUN4I_HDMI_PKT_AVI);
+	val |= SUN4I_HDMI_PKT_CTRL_TYPE(1, SUN4I_HDMI_PKT_END);
+	writel(val, hdmi->base + SUN4I_HDMI_PKT_CTRL_REG(0));
+
+	val = SUN4I_HDMI_VID_CTRL_ENABLE;
+	if (display->is_hdmi)
+		val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE;
+
+	writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG);
 }
 
 static enum drm_mode_status sun4i_hdmi_mode_valid(struct drm_encoder *encoder,
@@ -201,9 +195,8 @@
 
 static const struct drm_encoder_helper_funcs sun4i_hdmi_helper_funcs = {
 	.atomic_check	= sun4i_hdmi_atomic_check,
-	.disable	= sun4i_hdmi_disable,
-	.enable		= sun4i_hdmi_enable,
-	.mode_set	= sun4i_hdmi_mode_set,
+	.atomic_disable	= sun4i_hdmi_disable,
+	.atomic_enable	= sun4i_hdmi_enable,
 	.mode_valid	= sun4i_hdmi_mode_valid,
 };
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/tegra/dpaux.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/tegra/dpaux.c
@@ -522,7 +522,7 @@
 	if (err < 0) {
 		dev_err(dpaux->dev, "failed to request IRQ#%u: %d\n",
 			dpaux->irq, err);
-		return err;
+		goto err_pm_disable;
 	}
 
 	disable_irq(dpaux->irq);
@@ -542,7 +542,7 @@
 	 */
 	err = tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_I2C);
 	if (err < 0)
-		return err;
+		goto err_pm_disable;
 
 #ifdef CONFIG_GENERIC_PINCONF
 	dpaux->desc.name = dev_name(&pdev->dev);
@@ -555,7 +555,8 @@
 	dpaux->pinctrl = devm_pinctrl_register(&pdev->dev, &dpaux->desc, dpaux);
 	if (IS_ERR(dpaux->pinctrl)) {
 		dev_err(&pdev->dev, "failed to register pincontrol\n");
-		return PTR_ERR(dpaux->pinctrl);
+		err = PTR_ERR(dpaux->pinctrl);
+		goto err_pm_disable;
 	}
 #endif
 	/* enable and clear all interrupts */
@@ -571,10 +572,15 @@
 	err = devm_of_dp_aux_populate_ep_devices(&dpaux->aux);
 	if (err < 0) {
 		dev_err(dpaux->dev, "failed to populate AUX bus: %d\n", err);
-		return err;
+		goto err_pm_disable;
 	}
 
 	return 0;
+
+err_pm_disable:
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+	return err;
 }
 
 static void tegra_dpaux_remove(struct platform_device *pdev)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/tegra/dsi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/tegra/dsi.c
@@ -1544,9 +1544,11 @@
 	np = of_parse_phandle(dsi->dev->of_node, "nvidia,ganged-mode", 0);
 	if (np) {
 		struct platform_device *gangster = of_find_device_by_node(np);
+		of_node_put(np);
+		if (!gangster)
+			return -EPROBE_DEFER;
 
 		dsi->slave = platform_get_drvdata(gangster);
-		of_node_put(np);
 
 		if (!dsi->slave) {
 			put_device(&gangster->dev);
@@ -1594,44 +1596,58 @@
 
 	if (!pdev->dev.pm_domain) {
 		dsi->rst = devm_reset_control_get(&pdev->dev, "dsi");
-		if (IS_ERR(dsi->rst))
-			return PTR_ERR(dsi->rst);
+		if (IS_ERR(dsi->rst)) {
+			err = PTR_ERR(dsi->rst);
+			goto remove;
+		}
 	}
 
 	dsi->clk = devm_clk_get(&pdev->dev, NULL);
-	if (IS_ERR(dsi->clk))
-		return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk),
-				     "cannot get DSI clock\n");
+	if (IS_ERR(dsi->clk)) {
+		err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk),
+				    "cannot get DSI clock\n");
+		goto remove;
+	}
 
 	dsi->clk_lp = devm_clk_get(&pdev->dev, "lp");
-	if (IS_ERR(dsi->clk_lp))
-		return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_lp),
-				     "cannot get low-power clock\n");
+	if (IS_ERR(dsi->clk_lp)) {
+		err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_lp),
+				    "cannot get low-power clock\n");
+		goto remove;
+	}
 
 	dsi->clk_parent = devm_clk_get(&pdev->dev, "parent");
-	if (IS_ERR(dsi->clk_parent))
-		return dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_parent),
-				     "cannot get parent clock\n");
+	if (IS_ERR(dsi->clk_parent)) {
+		err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->clk_parent),
+				    "cannot get parent clock\n");
+		goto remove;
+	}
 
 	dsi->vdd = devm_regulator_get(&pdev->dev, "avdd-dsi-csi");
-	if (IS_ERR(dsi->vdd))
-		return dev_err_probe(&pdev->dev, PTR_ERR(dsi->vdd),
-				     "cannot get VDD supply\n");
+	if (IS_ERR(dsi->vdd)) {
+		err = dev_err_probe(&pdev->dev, PTR_ERR(dsi->vdd),
+				    "cannot get VDD supply\n");
+		goto remove;
+	}
 
 	err = tegra_dsi_setup_clocks(dsi);
 	if (err < 0) {
 		dev_err(&pdev->dev, "cannot setup clocks\n");
-		return err;
+		goto remove;
 	}
 
 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	dsi->regs = devm_ioremap_resource(&pdev->dev, regs);
-	if (IS_ERR(dsi->regs))
-		return PTR_ERR(dsi->regs);
+	if (IS_ERR(dsi->regs)) {
+		err = PTR_ERR(dsi->regs);
+		goto remove;
+	}
 
 	dsi->mipi = tegra_mipi_request(&pdev->dev, pdev->dev.of_node);
-	if (IS_ERR(dsi->mipi))
-		return PTR_ERR(dsi->mipi);
+	if (IS_ERR(dsi->mipi)) {
+		err = PTR_ERR(dsi->mipi);
+		goto remove;
+	}
 
 	dsi->host.ops = &tegra_dsi_host_ops;
 	dsi->host.dev = &pdev->dev;
@@ -1659,9 +1675,12 @@
 	return 0;
 
 unregister:
+	pm_runtime_disable(&pdev->dev);
 	mipi_dsi_host_unregister(&dsi->host);
 mipi_free:
 	tegra_mipi_free(dsi->mipi);
+remove:
+	tegra_output_remove(&dsi->output);
 	return err;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/tegra/fb.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/tegra/fb.c
@@ -159,6 +159,7 @@
 
 		if (gem->size < size) {
 			err = -EINVAL;
+			drm_gem_object_put(gem);
 			goto unreference;
 		}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/tegra/hdmi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/tegra/hdmi.c
@@ -1856,12 +1856,14 @@
 		return err;
 
 	hdmi->regs = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(hdmi->regs))
-		return PTR_ERR(hdmi->regs);
+	if (IS_ERR(hdmi->regs)) {
+		err = PTR_ERR(hdmi->regs);
+		goto remove;
+	}
 
 	err = platform_get_irq(pdev, 0);
 	if (err < 0)
-		return err;
+		goto remove;
 
 	hdmi->irq = err;
 
@@ -1870,18 +1872,18 @@
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n",
 			hdmi->irq, err);
-		return err;
+		goto remove;
 	}
 
 	platform_set_drvdata(pdev, hdmi);
 
 	err = devm_pm_runtime_enable(&pdev->dev);
 	if (err)
-		return err;
+		goto remove;
 
 	err = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
 	if (err)
-		return err;
+		goto remove;
 
 	INIT_LIST_HEAD(&hdmi->client.list);
 	hdmi->client.ops = &hdmi_client_ops;
@@ -1891,10 +1893,14 @@
 	if (err < 0) {
 		dev_err(&pdev->dev, "failed to register host1x client: %d\n",
 			err);
-		return err;
+		goto remove;
 	}
 
 	return 0;
+
+remove:
+	tegra_output_remove(&hdmi->output);
+	return err;
 }
 
 static void tegra_hdmi_remove(struct platform_device *pdev)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/tegra/output.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/tegra/output.c
@@ -142,8 +142,10 @@
 					GPIOD_IN,
 					"HDMI hotplug detect");
 	if (IS_ERR(output->hpd_gpio)) {
-		if (PTR_ERR(output->hpd_gpio) != -ENOENT)
-			return PTR_ERR(output->hpd_gpio);
+		if (PTR_ERR(output->hpd_gpio) != -ENOENT) {
+			err = PTR_ERR(output->hpd_gpio);
+			goto put_i2c;
+		}
 
 		output->hpd_gpio = NULL;
 	}
@@ -152,7 +154,7 @@
 		err = gpiod_to_irq(output->hpd_gpio);
 		if (err < 0) {
 			dev_err(output->dev, "gpiod_to_irq(): %d\n", err);
-			return err;
+			goto put_i2c;
 		}
 
 		output->hpd_irq = err;
@@ -165,7 +167,7 @@
 		if (err < 0) {
 			dev_err(output->dev, "failed to request IRQ#%u: %d\n",
 				output->hpd_irq, err);
-			return err;
+			goto put_i2c;
 		}
 
 		output->connector.polled = DRM_CONNECTOR_POLL_HPD;
@@ -179,6 +181,12 @@
 	}
 
 	return 0;
+
+put_i2c:
+	if (output->ddc)
+		i2c_put_adapter(output->ddc);
+
+	return err;
 }
 
 void tegra_output_remove(struct tegra_output *output)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/tegra/rgb.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/tegra/rgb.c
@@ -225,26 +225,28 @@
 	rgb->clk = devm_clk_get(dc->dev, NULL);
 	if (IS_ERR(rgb->clk)) {
 		dev_err(dc->dev, "failed to get clock\n");
-		return PTR_ERR(rgb->clk);
+		err = PTR_ERR(rgb->clk);
+		goto remove;
 	}
 
 	rgb->clk_parent = devm_clk_get(dc->dev, "parent");
 	if (IS_ERR(rgb->clk_parent)) {
 		dev_err(dc->dev, "failed to get parent clock\n");
-		return PTR_ERR(rgb->clk_parent);
+		err = PTR_ERR(rgb->clk_parent);
+		goto remove;
 	}
 
 	err = clk_set_parent(rgb->clk, rgb->clk_parent);
 	if (err < 0) {
 		dev_err(dc->dev, "failed to set parent clock: %d\n", err);
-		return err;
+		goto remove;
 	}
 
 	rgb->pll_d_out0 = clk_get_sys(NULL, "pll_d_out0");
 	if (IS_ERR(rgb->pll_d_out0)) {
 		err = PTR_ERR(rgb->pll_d_out0);
 		dev_err(dc->dev, "failed to get pll_d_out0: %d\n", err);
-		return err;
+		goto remove;
 	}
 
 	if (dc->soc->has_pll_d2_out0) {
@@ -252,13 +254,19 @@
 		if (IS_ERR(rgb->pll_d2_out0)) {
 			err = PTR_ERR(rgb->pll_d2_out0);
 			dev_err(dc->dev, "failed to get pll_d2_out0: %d\n", err);
-			return err;
+			goto put_pll;
 		}
 	}
 
 	dc->rgb = &rgb->output;
 
 	return 0;
+
+put_pll:
+	clk_put(rgb->pll_d_out0);
+remove:
+	tegra_output_remove(&rgb->output);
+	return err;
 }
 
 void tegra_dc_rgb_remove(struct tegra_dc *dc)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/tests/drm_buddy_test.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/tests/drm_buddy_test.c
@@ -260,30 +260,30 @@
 		KUNIT_ASSERT_FALSE_MSG(test,
 				       drm_buddy_alloc_blocks(&mm, 0, mm_size,
 							      ps, ps, list, 0),
-				       "buddy_alloc hit an error size=%u\n",
+				       "buddy_alloc hit an error size=%lu\n",
 				       ps);
 	} while (++i < n_pages);
 
 	KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
 							   3 * ps, ps, &allocated,
 							   DRM_BUDDY_CONTIGUOUS_ALLOCATION),
-			       "buddy_alloc didn't error size=%u\n", 3 * ps);
+			       "buddy_alloc didn't error size=%lu\n", 3 * ps);
 
 	drm_buddy_free_list(&mm, &middle);
 	KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
 							   3 * ps, ps, &allocated,
 							   DRM_BUDDY_CONTIGUOUS_ALLOCATION),
-			       "buddy_alloc didn't error size=%u\n", 3 * ps);
+			       "buddy_alloc didn't error size=%lu\n", 3 * ps);
 	KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
 							   2 * ps, ps, &allocated,
 							   DRM_BUDDY_CONTIGUOUS_ALLOCATION),
-			       "buddy_alloc didn't error size=%u\n", 2 * ps);
+			       "buddy_alloc didn't error size=%lu\n", 2 * ps);
 
 	drm_buddy_free_list(&mm, &right);
 	KUNIT_ASSERT_TRUE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
 							   3 * ps, ps, &allocated,
 							   DRM_BUDDY_CONTIGUOUS_ALLOCATION),
-			       "buddy_alloc didn't error size=%u\n", 3 * ps);
+			       "buddy_alloc didn't error size=%lu\n", 3 * ps);
 	/*
 	 * At this point we should have enough contiguous space for 2 blocks,
 	 * however they are never buddies (since we freed middle and right) so
@@ -292,13 +292,13 @@
 	KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
 							    2 * ps, ps, &allocated,
 							    DRM_BUDDY_CONTIGUOUS_ALLOCATION),
-			       "buddy_alloc hit an error size=%u\n", 2 * ps);
+			       "buddy_alloc hit an error size=%lu\n", 2 * ps);
 
 	drm_buddy_free_list(&mm, &left);
 	KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size,
 							    3 * ps, ps, &allocated,
 							    DRM_BUDDY_CONTIGUOUS_ALLOCATION),
-			       "buddy_alloc hit an error size=%u\n", 3 * ps);
+			       "buddy_alloc hit an error size=%lu\n", 3 * ps);
 
 	total = 0;
 	list_for_each_entry(block, &allocated, link)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/tests/drm_gem_shmem_test.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/tests/drm_gem_shmem_test.c
@@ -102,6 +102,17 @@
 
 	sg_init_one(sgt->sgl, buf, TEST_SIZE);
 
+	/*
+	 * Set the DMA mask to 64-bits and map the sgtables
+	 * otherwise drm_gem_shmem_free will cause a warning
+	 * on debug kernels.
+	 */
+	ret = dma_set_mask(drm_dev->dev, DMA_BIT_MASK(64));
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
+	ret = dma_map_sgtable(drm_dev->dev, sgt, DMA_BIDIRECTIONAL, 0);
+	KUNIT_ASSERT_EQ(test, ret, 0);
+
 	/* Init a mock DMA-BUF */
 	buf_mock.size = TEST_SIZE;
 	attach_mock.dmabuf = &buf_mock;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/tests/drm_mm_test.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/tests/drm_mm_test.c
@@ -157,7 +157,7 @@
 
 	/* After creation, it should all be one massive hole */
 	if (!assert_one_hole(test, &mm, 0, size)) {
-		KUNIT_FAIL(test, "");
+		KUNIT_FAIL(test, "mm not one hole on creation");
 		goto out;
 	}
 
@@ -171,14 +171,14 @@
 
 	/* After filling the range entirely, there should be no holes */
 	if (!assert_no_holes(test, &mm)) {
-		KUNIT_FAIL(test, "");
+		KUNIT_FAIL(test, "mm has holes when filled");
 		goto out;
 	}
 
 	/* And then after emptying it again, the massive hole should be back */
 	drm_mm_remove_node(&tmp);
 	if (!assert_one_hole(test, &mm, 0, size)) {
-		KUNIT_FAIL(test, "");
+		KUNIT_FAIL(test, "mm does not have single hole after emptying");
 		goto out;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/tidss/tidss_crtc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/tidss/tidss_crtc.c
@@ -265,6 +265,16 @@
 
 	reinit_completion(&tcrtc->framedone_completion);
 
+	/*
+	 * If a layer is left enabled when the videoport is disabled, and the
+	 * vid pipeline that was used for the layer is taken into use on
+	 * another videoport, the DSS will report sync lost issues. Disable all
+	 * the layers here as a work-around.
+	 */
+	for (u32 layer = 0; layer < tidss->feat->num_planes; layer++)
+		dispc_ovr_enable_layer(tidss->dispc, tcrtc->hw_videoport, layer,
+				       false);
+
 	dispc_vp_disable(tidss->dispc, tcrtc->hw_videoport);
 
 	if (!wait_for_completion_timeout(&tcrtc->framedone_completion,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/tidss/tidss_plane.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/tidss/tidss_plane.c
@@ -213,7 +213,7 @@
 
 	drm_plane_helper_add(&tplane->plane, &tidss_plane_helper_funcs);
 
-	drm_plane_create_zpos_property(&tplane->plane, hw_plane_id, 0,
+	drm_plane_create_zpos_property(&tplane->plane, tidss->num_planes, 0,
 				       num_planes - 1);
 
 	ret = drm_plane_create_color_properties(&tplane->plane,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/ttm/ttm_bo.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/ttm/ttm_bo.c
@@ -346,6 +346,7 @@
 		if (!dma_resv_test_signaled(bo->base.resv,
 					    DMA_RESV_USAGE_BOOKKEEP) ||
 		    (want_init_on_free() && (bo->ttm != NULL)) ||
+		    bo->type == ttm_bo_type_sg ||
 		    !dma_resv_trylock(bo->base.resv)) {
 			/* The BO is not idle, resurrect it for delayed destroy */
 			ttm_bo_flush_all_fences(bo);
@@ -770,7 +771,7 @@
  * This function may sleep while waiting for space to become available.
  * Returns:
  * -EBUSY: No space available (only if no_wait == 1).
- * -ENOMEM: Could not allocate memory for the buffer object, either due to
+ * -ENOSPC: Could not allocate space for the buffer object, either due to
  * fragmentation or concurrent allocators.
  * -ERESTARTSYS: An interruptible sleep was interrupted by a signal.
  */
@@ -830,7 +831,7 @@
 			goto error;
 	}
 
-	ret = -ENOMEM;
+	ret = -ENOSPC;
 	if (!type_found) {
 		pr_err(TTM_PFX "No compatible memory type found\n");
 		ret = -EINVAL;
@@ -916,6 +917,9 @@
 		return -EINVAL;
 
 	ret = ttm_bo_move_buffer(bo, placement, ctx);
+	/* For backward compatibility with userspace */
+	if (ret == -ENOSPC)
+		return -ENOMEM;
 	if (ret)
 		return ret;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -294,7 +294,13 @@
 	enum ttm_caching caching;
 
 	man = ttm_manager_type(bo->bdev, res->mem_type);
-	caching = man->use_tt ? bo->ttm->caching : res->bus.caching;
+	if (man->use_tt) {
+		caching = bo->ttm->caching;
+		if (bo->ttm->page_flags & TTM_TT_FLAG_DECRYPTED)
+			tmp = pgprot_decrypted(tmp);
+	} else  {
+		caching = res->bus.caching;
+	}
 
 	return ttm_prot_from_caching(caching, tmp);
 }
@@ -337,6 +343,8 @@
 		.no_wait_gpu = false
 	};
 	struct ttm_tt *ttm = bo->ttm;
+	struct ttm_resource_manager *man =
+			ttm_manager_type(bo->bdev, bo->resource->mem_type);
 	pgprot_t prot;
 	int ret;
 
@@ -346,7 +354,8 @@
 	if (ret)
 		return ret;
 
-	if (num_pages == 1 && ttm->caching == ttm_cached) {
+	if (num_pages == 1 && ttm->caching == ttm_cached &&
+	    !(man->use_tt && (ttm->page_flags & TTM_TT_FLAG_DECRYPTED))) {
 		/*
 		 * We're mapping a single page, and the desired
 		 * page protection is consistent with the bo.
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/ttm/ttm_pool.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/ttm/ttm_pool.c
@@ -288,17 +288,23 @@
 						  enum ttm_caching caching,
 						  unsigned int order)
 {
-	if (pool->use_dma_alloc || pool->nid != NUMA_NO_NODE)
+	if (pool->use_dma_alloc)
 		return &pool->caching[caching].orders[order];
 
 #ifdef CONFIG_X86
 	switch (caching) {
 	case ttm_write_combined:
+		if (pool->nid != NUMA_NO_NODE)
+			return &pool->caching[caching].orders[order];
+
 		if (pool->use_dma32)
 			return &global_dma32_write_combined[order];
 
 		return &global_write_combined[order];
 	case ttm_uncached:
+		if (pool->nid != NUMA_NO_NODE)
+			return &pool->caching[caching].orders[order];
+
 		if (pool->use_dma32)
 			return &global_dma32_uncached[order];
 
@@ -566,11 +572,17 @@
 	pool->use_dma_alloc = use_dma_alloc;
 	pool->use_dma32 = use_dma32;
 
-	if (use_dma_alloc || nid != NUMA_NO_NODE) {
-		for (i = 0; i < TTM_NUM_CACHING_TYPES; ++i)
-			for (j = 0; j < NR_PAGE_ORDERS; ++j)
-				ttm_pool_type_init(&pool->caching[i].orders[j],
-						   pool, i, j);
+	for (i = 0; i < TTM_NUM_CACHING_TYPES; ++i) {
+		for (j = 0; j < NR_PAGE_ORDERS; ++j) {
+			struct ttm_pool_type *pt;
+
+			/* Initialize only pool types which are actually used */
+			pt = ttm_pool_select_type(pool, i, j);
+			if (pt != &pool->caching[i].orders[j])
+				continue;
+
+			ttm_pool_type_init(pt, pool, i, j);
+		}
 	}
 }
 EXPORT_SYMBOL(ttm_pool_init);
@@ -599,10 +611,16 @@
 {
 	unsigned int i, j;
 
-	if (pool->use_dma_alloc || pool->nid != NUMA_NO_NODE) {
-		for (i = 0; i < TTM_NUM_CACHING_TYPES; ++i)
-			for (j = 0; j < NR_PAGE_ORDERS; ++j)
-				ttm_pool_type_fini(&pool->caching[i].orders[j]);
+	for (i = 0; i < TTM_NUM_CACHING_TYPES; ++i) {
+		for (j = 0; j < NR_PAGE_ORDERS; ++j) {
+			struct ttm_pool_type *pt;
+
+			pt = ttm_pool_select_type(pool, i, j);
+			if (pt != &pool->caching[i].orders[j])
+				continue;
+
+			ttm_pool_type_fini(pt);
+		}
 	}
 
 	/* We removed the pool types from the LRU, but we need to also make sure
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/ttm/ttm_tt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/ttm/ttm_tt.c
@@ -31,11 +31,14 @@
 
 #define pr_fmt(fmt) "[TTM] " fmt
 
+#include <linux/cc_platform.h>
 #include <linux/sched.h>
 #include <linux/shmem_fs.h>
 #include <linux/file.h>
 #include <linux/module.h>
 #include <drm/drm_cache.h>
+#include <drm/drm_device.h>
+#include <drm/drm_util.h>
 #include <drm/ttm/ttm_bo.h>
 #include <drm/ttm/ttm_tt.h>
 
@@ -60,6 +63,7 @@
 int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc)
 {
 	struct ttm_device *bdev = bo->bdev;
+	struct drm_device *ddev = bo->base.dev;
 	uint32_t page_flags = 0;
 
 	dma_resv_assert_held(bo->base.resv);
@@ -81,6 +85,15 @@
 		pr_err("Illegal buffer object type\n");
 		return -EINVAL;
 	}
+	/*
+	 * When using dma_alloc_coherent with memory encryption the
+	 * mapped TT pages need to be decrypted or otherwise the drivers
+	 * will end up sending encrypted mem to the gpu.
+	 */
+	if (bdev->pool.use_dma_alloc && cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) {
+		page_flags |= TTM_TT_FLAG_DECRYPTED;
+		drm_info_once(ddev, "TT memory decryption enabled.");
+	}
 
 	bo->ttm = bdev->funcs->ttm_tt_create(bo, page_flags);
 	if (unlikely(bo->ttm == NULL))
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/udl/udl_modeset.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/udl/udl_modeset.c
@@ -527,8 +527,7 @@
 
 	drm_connector_helper_add(connector, &udl_connector_helper_funcs);
 
-	connector->polled = DRM_CONNECTOR_POLL_HPD |
-			    DRM_CONNECTOR_POLL_CONNECT |
+	connector->polled = DRM_CONNECTOR_POLL_CONNECT |
 			    DRM_CONNECTOR_POLL_DISCONNECT;
 
 	return connector;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/v3d/v3d_debugfs.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/v3d/v3d_debugfs.c
@@ -237,8 +237,8 @@
 	if (v3d->ver >= 40) {
 		int cycle_count_reg = V3D_PCTR_CYCLE_COUNT(v3d->ver);
 		V3D_CORE_WRITE(core, V3D_V4_PCTR_0_SRC_0_3,
-			       V3D_SET_FIELD(cycle_count_reg,
-					     V3D_PCTR_S0));
+			       V3D_SET_FIELD_VER(cycle_count_reg,
+						 V3D_PCTR_S0, v3d->ver));
 		V3D_CORE_WRITE(core, V3D_V4_PCTR_0_CLR, 1);
 		V3D_CORE_WRITE(core, V3D_V4_PCTR_0_EN, 1);
 	} else {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/v3d/v3d_drv.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/v3d/v3d_drv.h
@@ -536,11 +536,16 @@
 void v3d_irq_reset(struct v3d_dev *v3d);
 
 /* v3d_mmu.c */
+int v3d_mmu_flush_all(struct v3d_dev *v3d);
 int v3d_mmu_set_page_table(struct v3d_dev *v3d);
 void v3d_mmu_insert_ptes(struct v3d_bo *bo);
 void v3d_mmu_remove_ptes(struct v3d_bo *bo);
 
 /* v3d_sched.c */
+void v3d_timestamp_query_info_free(struct v3d_timestamp_query_info *query_info,
+				   unsigned int count);
+void v3d_performance_query_info_free(struct v3d_performance_query_info *query_info,
+				     unsigned int count);
 int v3d_sched_init(struct v3d_dev *v3d);
 void v3d_sched_fini(struct v3d_dev *v3d);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/v3d/v3d_irq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/v3d/v3d_irq.c
@@ -70,6 +70,8 @@
 	list_add_tail(&bo->unref_head, &v3d->bin_job->render->unref_list);
 	spin_unlock_irqrestore(&v3d->job_lock, irqflags);
 
+	v3d_mmu_flush_all(v3d);
+
 	V3D_CORE_WRITE(0, V3D_PTB_BPOA, bo->node.start << PAGE_SHIFT);
 	V3D_CORE_WRITE(0, V3D_PTB_BPOS, obj->size);
 
@@ -105,7 +107,6 @@
 		struct v3d_file_priv *file = v3d->bin_job->base.file->driver_priv;
 		u64 runtime = local_clock() - file->start_ns[V3D_BIN];
 
-		file->enabled_ns[V3D_BIN] += local_clock() - file->start_ns[V3D_BIN];
 		file->jobs_sent[V3D_BIN]++;
 		v3d->queue[V3D_BIN].jobs_sent++;
 
@@ -116,7 +117,10 @@
 		v3d->queue[V3D_BIN].enabled_ns += runtime;
 
 		trace_v3d_bcl_irq(&v3d->drm, fence->seqno);
+
+		v3d->bin_job = NULL;
 		dma_fence_signal(&fence->base);
+
 		status = IRQ_HANDLED;
 	}
 
@@ -126,7 +130,6 @@
 		struct v3d_file_priv *file = v3d->render_job->base.file->driver_priv;
 		u64 runtime = local_clock() - file->start_ns[V3D_RENDER];
 
-		file->enabled_ns[V3D_RENDER] += local_clock() - file->start_ns[V3D_RENDER];
 		file->jobs_sent[V3D_RENDER]++;
 		v3d->queue[V3D_RENDER].jobs_sent++;
 
@@ -137,7 +140,10 @@
 		v3d->queue[V3D_RENDER].enabled_ns += runtime;
 
 		trace_v3d_rcl_irq(&v3d->drm, fence->seqno);
+
+		v3d->render_job = NULL;
 		dma_fence_signal(&fence->base);
+
 		status = IRQ_HANDLED;
 	}
 
@@ -147,7 +153,6 @@
 		struct v3d_file_priv *file = v3d->csd_job->base.file->driver_priv;
 		u64 runtime = local_clock() - file->start_ns[V3D_CSD];
 
-		file->enabled_ns[V3D_CSD] += local_clock() - file->start_ns[V3D_CSD];
 		file->jobs_sent[V3D_CSD]++;
 		v3d->queue[V3D_CSD].jobs_sent++;
 
@@ -158,7 +163,10 @@
 		v3d->queue[V3D_CSD].enabled_ns += runtime;
 
 		trace_v3d_csd_irq(&v3d->drm, fence->seqno);
+
+		v3d->csd_job = NULL;
 		dma_fence_signal(&fence->base);
+
 		status = IRQ_HANDLED;
 	}
 
@@ -195,7 +203,6 @@
 		struct v3d_file_priv *file = v3d->tfu_job->base.file->driver_priv;
 		u64 runtime = local_clock() - file->start_ns[V3D_TFU];
 
-		file->enabled_ns[V3D_TFU] += local_clock() - file->start_ns[V3D_TFU];
 		file->jobs_sent[V3D_TFU]++;
 		v3d->queue[V3D_TFU].jobs_sent++;
 
@@ -206,7 +213,10 @@
 		v3d->queue[V3D_TFU].enabled_ns += runtime;
 
 		trace_v3d_tfu_irq(&v3d->drm, fence->seqno);
+
+		v3d->tfu_job = NULL;
 		dma_fence_signal(&fence->base);
+
 		status = IRQ_HANDLED;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/v3d/v3d_mmu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/v3d/v3d_mmu.c
@@ -30,36 +30,27 @@
 #define V3D_PTE_WRITEABLE BIT(29)
 #define V3D_PTE_VALID BIT(28)
 
-static int v3d_mmu_flush_all(struct v3d_dev *v3d)
+int v3d_mmu_flush_all(struct v3d_dev *v3d)
 {
 	int ret;
 
-	/* Make sure that another flush isn't already running when we
-	 * start this one.
-	 */
-	ret = wait_for(!(V3D_READ(V3D_MMU_CTL) &
-			 V3D_MMU_CTL_TLB_CLEARING), 100);
-	if (ret)
-		dev_err(v3d->drm.dev, "TLB clear wait idle pre-wait failed\n");
-
-	V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL) |
-		  V3D_MMU_CTL_TLB_CLEAR);
-
-	V3D_WRITE(V3D_MMUC_CONTROL,
-		  V3D_MMUC_CONTROL_FLUSH |
+	V3D_WRITE(V3D_MMUC_CONTROL, V3D_MMUC_CONTROL_FLUSH |
 		  V3D_MMUC_CONTROL_ENABLE);
 
-	ret = wait_for(!(V3D_READ(V3D_MMU_CTL) &
-			 V3D_MMU_CTL_TLB_CLEARING), 100);
+	ret = wait_for(!(V3D_READ(V3D_MMUC_CONTROL) &
+			 V3D_MMUC_CONTROL_FLUSHING), 100);
 	if (ret) {
-		dev_err(v3d->drm.dev, "TLB clear wait idle failed\n");
+		dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n");
 		return ret;
 	}
 
-	ret = wait_for(!(V3D_READ(V3D_MMUC_CONTROL) &
-			 V3D_MMUC_CONTROL_FLUSHING), 100);
+	V3D_WRITE(V3D_MMU_CTL, V3D_READ(V3D_MMU_CTL) |
+		  V3D_MMU_CTL_TLB_CLEAR);
+
+	ret = wait_for(!(V3D_READ(V3D_MMU_CTL) &
+			 V3D_MMU_CTL_TLB_CLEARING), 100);
 	if (ret)
-		dev_err(v3d->drm.dev, "MMUC flush wait idle failed\n");
+		dev_err(v3d->drm.dev, "MMU TLB clear wait idle failed\n");
 
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/v3d/v3d_perfmon.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/v3d/v3d_perfmon.c
@@ -37,23 +37,24 @@
 
 	for (i = 0; i < ncounters; i++) {
 		u32 source = i / 4;
-		u32 channel = V3D_SET_FIELD(perfmon->counters[i], V3D_PCTR_S0);
+		u32 channel = V3D_SET_FIELD_VER(perfmon->counters[i], V3D_PCTR_S0,
+						v3d->ver);
 
 		i++;
-		channel |= V3D_SET_FIELD(i < ncounters ? perfmon->counters[i] : 0,
-					 V3D_PCTR_S1);
+		channel |= V3D_SET_FIELD_VER(i < ncounters ? perfmon->counters[i] : 0,
+					     V3D_PCTR_S1, v3d->ver);
 		i++;
-		channel |= V3D_SET_FIELD(i < ncounters ? perfmon->counters[i] : 0,
-					 V3D_PCTR_S2);
+		channel |= V3D_SET_FIELD_VER(i < ncounters ? perfmon->counters[i] : 0,
+					     V3D_PCTR_S2, v3d->ver);
 		i++;
-		channel |= V3D_SET_FIELD(i < ncounters ? perfmon->counters[i] : 0,
-					 V3D_PCTR_S3);
+		channel |= V3D_SET_FIELD_VER(i < ncounters ? perfmon->counters[i] : 0,
+					     V3D_PCTR_S3, v3d->ver);
 		V3D_CORE_WRITE(0, V3D_V4_PCTR_0_SRC_X(source), channel);
 	}
 
+	V3D_CORE_WRITE(0, V3D_V4_PCTR_0_EN, mask);
 	V3D_CORE_WRITE(0, V3D_V4_PCTR_0_CLR, mask);
 	V3D_CORE_WRITE(0, V3D_PCTR_0_OVERFLOW, mask);
-	V3D_CORE_WRITE(0, V3D_V4_PCTR_0_EN, mask);
 
 	v3d->active_perfmon = perfmon;
 }
@@ -103,6 +104,11 @@
 static int v3d_perfmon_idr_del(int id, void *elem, void *data)
 {
 	struct v3d_perfmon *perfmon = elem;
+	struct v3d_dev *v3d = (struct v3d_dev *)data;
+
+	/* If the active perfmon is being destroyed, stop it first */
+	if (perfmon == v3d->active_perfmon)
+		v3d_perfmon_stop(v3d, perfmon, false);
 
 	v3d_perfmon_put(perfmon);
 
@@ -111,8 +117,10 @@
 
 void v3d_perfmon_close_file(struct v3d_file_priv *v3d_priv)
 {
+	struct v3d_dev *v3d = v3d_priv->v3d;
+
 	mutex_lock(&v3d_priv->perfmon.lock);
-	idr_for_each(&v3d_priv->perfmon.idr, v3d_perfmon_idr_del, NULL);
+	idr_for_each(&v3d_priv->perfmon.idr, v3d_perfmon_idr_del, v3d);
 	idr_destroy(&v3d_priv->perfmon.idr);
 	mutex_unlock(&v3d_priv->perfmon.lock);
 	mutex_destroy(&v3d_priv->perfmon.lock);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/v3d/v3d_regs.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/v3d/v3d_regs.h
@@ -15,6 +15,14 @@
 		fieldval & field##_MASK;				\
 	 })
 
+#define V3D_SET_FIELD_VER(value, field, ver)				\
+	({								\
+		typeof(ver) _ver = (ver);				\
+		u32 fieldval = (value) << field##_SHIFT(_ver);		\
+		WARN_ON((fieldval & ~field##_MASK(_ver)) != 0);		\
+		fieldval & field##_MASK(_ver);				\
+	 })
+
 #define V3D_GET_FIELD(word, field) (((word) & field##_MASK) >>		\
 				    field##_SHIFT)
 
@@ -354,18 +362,15 @@
 #define V3D_V4_PCTR_0_SRC_28_31                        0x0067c
 #define V3D_V4_PCTR_0_SRC_X(x)                         (V3D_V4_PCTR_0_SRC_0_3 + \
 							4 * (x))
-# define V3D_PCTR_S0_MASK                              V3D_MASK(6, 0)
-# define V3D_V7_PCTR_S0_MASK                           V3D_MASK(7, 0)
-# define V3D_PCTR_S0_SHIFT                             0
-# define V3D_PCTR_S1_MASK                              V3D_MASK(14, 8)
-# define V3D_V7_PCTR_S1_MASK                           V3D_MASK(15, 8)
-# define V3D_PCTR_S1_SHIFT                             8
-# define V3D_PCTR_S2_MASK                              V3D_MASK(22, 16)
-# define V3D_V7_PCTR_S2_MASK                           V3D_MASK(23, 16)
-# define V3D_PCTR_S2_SHIFT                             16
-# define V3D_PCTR_S3_MASK                              V3D_MASK(30, 24)
-# define V3D_V7_PCTR_S3_MASK                           V3D_MASK(31, 24)
-# define V3D_PCTR_S3_SHIFT                             24
+# define V3D_PCTR_S0_MASK(ver) (((ver) >= 71) ? V3D_MASK(7, 0) : V3D_MASK(6, 0))
+# define V3D_PCTR_S0_SHIFT(ver)                        0
+# define V3D_PCTR_S1_MASK(ver) (((ver) >= 71) ? V3D_MASK(15, 8) : V3D_MASK(14, 8))
+# define V3D_PCTR_S1_SHIFT(ver)                        8
+# define V3D_PCTR_S2_MASK(ver) (((ver) >= 71) ? V3D_MASK(23, 16) : V3D_MASK(22, 16))
+# define V3D_PCTR_S2_SHIFT(ver)                        16
+# define V3D_PCTR_S3_MASK(ver) (((ver) >= 71) ? V3D_MASK(31, 24) : V3D_MASK(30, 24))
+# define V3D_PCTR_S3_SHIFT(ver)                        24
+
 #define V3D_PCTR_CYCLE_COUNT(ver) ((ver >= 71) ? 0 : 32)
 
 /* Output values of the counters. */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/v3d/v3d_sched.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/v3d/v3d_sched.c
@@ -73,24 +73,44 @@
 	v3d_job_cleanup(job);
 }
 
+void
+v3d_timestamp_query_info_free(struct v3d_timestamp_query_info *query_info,
+			      unsigned int count)
+{
+	if (query_info->queries) {
+		unsigned int i;
+
+		for (i = 0; i < count; i++)
+			drm_syncobj_put(query_info->queries[i].syncobj);
+
+		kvfree(query_info->queries);
+	}
+}
+
+void
+v3d_performance_query_info_free(struct v3d_performance_query_info *query_info,
+				unsigned int count)
+{
+	if (query_info->queries) {
+		unsigned int i;
+
+		for (i = 0; i < count; i++)
+			drm_syncobj_put(query_info->queries[i].syncobj);
+
+		kvfree(query_info->queries);
+	}
+}
+
 static void
 v3d_cpu_job_free(struct drm_sched_job *sched_job)
 {
 	struct v3d_cpu_job *job = to_cpu_job(sched_job);
-	struct v3d_timestamp_query_info *timestamp_query = &job->timestamp_query;
-	struct v3d_performance_query_info *performance_query = &job->performance_query;
 
-	if (timestamp_query->queries) {
-		for (int i = 0; i < timestamp_query->count; i++)
-			drm_syncobj_put(timestamp_query->queries[i].syncobj);
-		kvfree(timestamp_query->queries);
-	}
+	v3d_timestamp_query_info_free(&job->timestamp_query,
+				      job->timestamp_query.count);
 
-	if (performance_query->queries) {
-		for (int i = 0; i < performance_query->count; i++)
-			drm_syncobj_put(performance_query->queries[i].syncobj);
-		kvfree(performance_query->queries);
-	}
+	v3d_performance_query_info_free(&job->performance_query,
+					job->performance_query.count);
 
 	v3d_job_cleanup(&job->base);
 }
@@ -263,7 +283,7 @@
 	struct v3d_file_priv *file = job->base.file->driver_priv;
 	struct drm_device *dev = &v3d->drm;
 	struct dma_fence *fence;
-	int i, csd_cfg0_reg, csd_cfg_reg_count;
+	int i, csd_cfg0_reg;
 
 	v3d->csd_job = job;
 
@@ -285,9 +305,17 @@
 	v3d_switch_perfmon(v3d, &job->base);
 
 	csd_cfg0_reg = V3D_CSD_QUEUED_CFG0(v3d->ver);
-	csd_cfg_reg_count = v3d->ver < 71 ? 6 : 7;
-	for (i = 1; i <= csd_cfg_reg_count; i++)
+	for (i = 1; i <= 6; i++)
 		V3D_CORE_WRITE(0, csd_cfg0_reg + 4 * i, job->args.cfg[i]);
+
+	/* Although V3D 7.1 has an eighth configuration register, we are not
+	 * using it. Therefore, make sure it remains unused.
+	 *
+	 * XXX: Set the CFG7 register
+	 */
+	if (v3d->ver >= 71)
+		V3D_CORE_WRITE(0, V3D_V7_CSD_QUEUED_CFG7, 0);
+
 	/* CFG0 write kicks off the job. */
 	V3D_CORE_WRITE(0, csd_cfg0_reg, job->args.cfg[0]);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/v3d/v3d_submit.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/v3d/v3d_submit.c
@@ -452,6 +452,8 @@
 {
 	u32 __user *offsets, *syncs;
 	struct drm_v3d_timestamp_query timestamp;
+	unsigned int i;
+	int err;
 
 	if (!job) {
 		DRM_DEBUG("CPU job extension was attached to a GPU job.\n");
@@ -480,26 +482,34 @@
 	offsets = u64_to_user_ptr(timestamp.offsets);
 	syncs = u64_to_user_ptr(timestamp.syncs);
 
-	for (int i = 0; i < timestamp.count; i++) {
+	for (i = 0; i < timestamp.count; i++) {
 		u32 offset, sync;
 
 		if (copy_from_user(&offset, offsets++, sizeof(offset))) {
-			kvfree(job->timestamp_query.queries);
-			return -EFAULT;
+			err = -EFAULT;
+			goto error;
 		}
 
 		job->timestamp_query.queries[i].offset = offset;
 
 		if (copy_from_user(&sync, syncs++, sizeof(sync))) {
-			kvfree(job->timestamp_query.queries);
-			return -EFAULT;
+			err = -EFAULT;
+			goto error;
 		}
 
 		job->timestamp_query.queries[i].syncobj = drm_syncobj_find(file_priv, sync);
+		if (!job->timestamp_query.queries[i].syncobj) {
+			err = -ENOENT;
+			goto error;
+		}
 	}
 	job->timestamp_query.count = timestamp.count;
 
 	return 0;
+
+error:
+	v3d_timestamp_query_info_free(&job->timestamp_query, i);
+	return err;
 }
 
 static int
@@ -509,6 +519,8 @@
 {
 	u32 __user *syncs;
 	struct drm_v3d_reset_timestamp_query reset;
+	unsigned int i;
+	int err;
 
 	if (!job) {
 		DRM_DEBUG("CPU job extension was attached to a GPU job.\n");
@@ -533,21 +545,29 @@
 
 	syncs = u64_to_user_ptr(reset.syncs);
 
-	for (int i = 0; i < reset.count; i++) {
+	for (i = 0; i < reset.count; i++) {
 		u32 sync;
 
 		job->timestamp_query.queries[i].offset = reset.offset + 8 * i;
 
 		if (copy_from_user(&sync, syncs++, sizeof(sync))) {
-			kvfree(job->timestamp_query.queries);
-			return -EFAULT;
+			err = -EFAULT;
+			goto error;
 		}
 
 		job->timestamp_query.queries[i].syncobj = drm_syncobj_find(file_priv, sync);
+		if (!job->timestamp_query.queries[i].syncobj) {
+			err = -ENOENT;
+			goto error;
+		}
 	}
 	job->timestamp_query.count = reset.count;
 
 	return 0;
+
+error:
+	v3d_timestamp_query_info_free(&job->timestamp_query, i);
+	return err;
 }
 
 /* Get data for the copy timestamp query results job submission. */
@@ -558,7 +578,8 @@
 {
 	u32 __user *offsets, *syncs;
 	struct drm_v3d_copy_timestamp_query copy;
-	int i;
+	unsigned int i;
+	int err;
 
 	if (!job) {
 		DRM_DEBUG("CPU job extension was attached to a GPU job.\n");
@@ -591,18 +612,22 @@
 		u32 offset, sync;
 
 		if (copy_from_user(&offset, offsets++, sizeof(offset))) {
-			kvfree(job->timestamp_query.queries);
-			return -EFAULT;
+			err = -EFAULT;
+			goto error;
 		}
 
 		job->timestamp_query.queries[i].offset = offset;
 
 		if (copy_from_user(&sync, syncs++, sizeof(sync))) {
-			kvfree(job->timestamp_query.queries);
-			return -EFAULT;
+			err = -EFAULT;
+			goto error;
 		}
 
 		job->timestamp_query.queries[i].syncobj = drm_syncobj_find(file_priv, sync);
+		if (!job->timestamp_query.queries[i].syncobj) {
+			err = -ENOENT;
+			goto error;
+		}
 	}
 	job->timestamp_query.count = copy.count;
 
@@ -613,6 +638,10 @@
 	job->copy.stride = copy.stride;
 
 	return 0;
+
+error:
+	v3d_timestamp_query_info_free(&job->timestamp_query, i);
+	return err;
 }
 
 static int
@@ -623,6 +652,8 @@
 	u32 __user *syncs;
 	u64 __user *kperfmon_ids;
 	struct drm_v3d_reset_performance_query reset;
+	unsigned int i, j;
+	int err;
 
 	if (!job) {
 		DRM_DEBUG("CPU job extension was attached to a GPU job.\n");
@@ -637,6 +668,12 @@
 	if (copy_from_user(&reset, ext, sizeof(reset)))
 		return -EFAULT;
 
+	if (reset.nperfmons > V3D_MAX_PERFMONS)
+		return -EINVAL;
+
+	if (reset.nperfmons > V3D_MAX_PERFMONS)
+		return -EINVAL;
+
 	job->job_type = V3D_CPU_JOB_TYPE_RESET_PERFORMANCE_QUERY;
 
 	job->performance_query.queries = kvmalloc_array(reset.count,
@@ -648,39 +685,47 @@
 	syncs = u64_to_user_ptr(reset.syncs);
 	kperfmon_ids = u64_to_user_ptr(reset.kperfmon_ids);
 
-	for (int i = 0; i < reset.count; i++) {
+	for (i = 0; i < reset.count; i++) {
 		u32 sync;
 		u64 ids;
 		u32 __user *ids_pointer;
 		u32 id;
 
 		if (copy_from_user(&sync, syncs++, sizeof(sync))) {
-			kvfree(job->performance_query.queries);
-			return -EFAULT;
+			err = -EFAULT;
+			goto error;
 		}
 
-		job->performance_query.queries[i].syncobj = drm_syncobj_find(file_priv, sync);
-
 		if (copy_from_user(&ids, kperfmon_ids++, sizeof(ids))) {
-			kvfree(job->performance_query.queries);
-			return -EFAULT;
+			err = -EFAULT;
+			goto error;
 		}
 
 		ids_pointer = u64_to_user_ptr(ids);
 
-		for (int j = 0; j < reset.nperfmons; j++) {
+		for (j = 0; j < reset.nperfmons; j++) {
 			if (copy_from_user(&id, ids_pointer++, sizeof(id))) {
-				kvfree(job->performance_query.queries);
-				return -EFAULT;
+				err = -EFAULT;
+				goto error;
 			}
 
 			job->performance_query.queries[i].kperfmon_ids[j] = id;
 		}
+
+		job->performance_query.queries[i].syncobj = drm_syncobj_find(file_priv, sync);
+		if (!job->performance_query.queries[i].syncobj) {
+			err = -ENOENT;
+			goto error;
+		}
 	}
 	job->performance_query.count = reset.count;
 	job->performance_query.nperfmons = reset.nperfmons;
 
 	return 0;
+
+error:
+	v3d_performance_query_info_free(&job->performance_query, i);
+	return err;
 }
 
 static int
@@ -691,6 +736,8 @@
 	u32 __user *syncs;
 	u64 __user *kperfmon_ids;
 	struct drm_v3d_copy_performance_query copy;
+	unsigned int i, j;
+	int err;
 
 	if (!job) {
 		DRM_DEBUG("CPU job extension was attached to a GPU job.\n");
@@ -708,6 +755,12 @@
 	if (copy.pad)
 		return -EINVAL;
 
+	if (copy.nperfmons > V3D_MAX_PERFMONS)
+		return -EINVAL;
+
+	if (copy.nperfmons > V3D_MAX_PERFMONS)
+		return -EINVAL;
+
 	job->job_type = V3D_CPU_JOB_TYPE_COPY_PERFORMANCE_QUERY;
 
 	job->performance_query.queries = kvmalloc_array(copy.count,
@@ -719,34 +772,38 @@
 	syncs = u64_to_user_ptr(copy.syncs);
 	kperfmon_ids = u64_to_user_ptr(copy.kperfmon_ids);
 
-	for (int i = 0; i < copy.count; i++) {
+	for (i = 0; i < copy.count; i++) {
 		u32 sync;
 		u64 ids;
 		u32 __user *ids_pointer;
 		u32 id;
 
 		if (copy_from_user(&sync, syncs++, sizeof(sync))) {
-			kvfree(job->performance_query.queries);
-			return -EFAULT;
+			err = -EFAULT;
+			goto error;
 		}
 
-		job->performance_query.queries[i].syncobj = drm_syncobj_find(file_priv, sync);
-
 		if (copy_from_user(&ids, kperfmon_ids++, sizeof(ids))) {
-			kvfree(job->performance_query.queries);
-			return -EFAULT;
+			err = -EFAULT;
+			goto error;
 		}
 
 		ids_pointer = u64_to_user_ptr(ids);
 
-		for (int j = 0; j < copy.nperfmons; j++) {
+		for (j = 0; j < copy.nperfmons; j++) {
 			if (copy_from_user(&id, ids_pointer++, sizeof(id))) {
-				kvfree(job->performance_query.queries);
-				return -EFAULT;
+				err = -EFAULT;
+				goto error;
 			}
 
 			job->performance_query.queries[i].kperfmon_ids[j] = id;
 		}
+
+		job->performance_query.queries[i].syncobj = drm_syncobj_find(file_priv, sync);
+		if (!job->performance_query.queries[i].syncobj) {
+			err = -ENOENT;
+			goto error;
+		}
 	}
 	job->performance_query.count = copy.count;
 	job->performance_query.nperfmons = copy.nperfmons;
@@ -759,6 +816,10 @@
 	job->copy.stride = copy.stride;
 
 	return 0;
+
+error:
+	v3d_performance_query_info_free(&job->performance_query, i);
+	return err;
 }
 
 /* Whenever userspace sets ioctl extensions, v3d_get_extensions parses data
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vboxvideo/hgsmi_base.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vboxvideo/hgsmi_base.c
@@ -139,7 +139,15 @@
 		flags |= VBOX_MOUSE_POINTER_VISIBLE;
 	}
 
-	p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len, HGSMI_CH_VBVA,
+	/*
+	 * The 4 extra bytes come from switching struct vbva_mouse_pointer_shape
+	 * from having a 4 bytes fixed array at the end to using a proper VLA
+	 * at the end. These 4 extra bytes were not subtracted from sizeof(*p)
+	 * before the switch to the VLA, so this way the behavior is unchanged.
+	 * Chances are these 4 extra bytes are not necessary but they are kept
+	 * to avoid regressions.
+	 */
+	p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len + 4, HGSMI_CH_VBVA,
 			       VBVA_MOUSE_POINTER_SHAPE);
 	if (!p)
 		return -ENOMEM;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vboxvideo/vboxvideo.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/vboxvideo/vboxvideo.h
@@ -351,10 +351,8 @@
 	 * Bytes in the gap between the AND and the XOR mask are undefined.
 	 * XOR mask scanlines have no gap between them and size of XOR mask is:
 	 * xor_len = width * 4 * height.
-	 *
-	 * Preallocate 4 bytes for accessing actual data as p->data.
 	 */
-	u8 data[4];
+	u8 data[];
 } __packed;
 
 /* pointer is visible */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/tests/vc4_mock.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/tests/vc4_mock.c
@@ -157,11 +157,11 @@
 			    drm_dev_unregister,
 			    struct drm_device *);
 
-static struct vc4_dev *__mock_device(struct kunit *test, bool is_vc5)
+static struct vc4_dev *__mock_device(struct kunit *test, enum vc4_gen gen)
 {
 	struct drm_device *drm;
-	const struct drm_driver *drv = is_vc5 ? &vc5_drm_driver : &vc4_drm_driver;
-	const struct vc4_mock_desc *desc = is_vc5 ? &vc5_mock : &vc4_mock;
+	const struct drm_driver *drv = (gen == VC4_GEN_5) ? &vc5_drm_driver : &vc4_drm_driver;
+	const struct vc4_mock_desc *desc = (gen == VC4_GEN_5) ? &vc5_mock : &vc4_mock;
 	struct vc4_dev *vc4;
 	struct device *dev;
 	int ret;
@@ -175,7 +175,7 @@
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
 
 	vc4->dev = dev;
-	vc4->is_vc5 = is_vc5;
+	vc4->gen = gen;
 
 	vc4->hvs = __vc4_hvs_alloc(vc4, NULL);
 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4->hvs);
@@ -200,10 +200,10 @@
 
 struct vc4_dev *vc4_mock_device(struct kunit *test)
 {
-	return __mock_device(test, false);
+	return __mock_device(test, VC4_GEN_4);
 }
 
 struct vc4_dev *vc5_mock_device(struct kunit *test)
 {
-	return __mock_device(test, true);
+	return __mock_device(test, VC4_GEN_5);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_bo.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_bo.c
@@ -251,7 +251,7 @@
 {
 	struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	mutex_lock(&vc4->purgeable.lock);
@@ -265,7 +265,7 @@
 {
 	struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	/* list_del_init() is used here because the caller might release
@@ -396,7 +396,7 @@
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	struct vc4_bo *bo;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return ERR_PTR(-ENODEV);
 
 	bo = kzalloc(sizeof(*bo), GFP_KERNEL);
@@ -427,7 +427,7 @@
 	struct drm_gem_dma_object *dma_obj;
 	struct vc4_bo *bo;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return ERR_PTR(-ENODEV);
 
 	if (size == 0)
@@ -496,7 +496,7 @@
 	struct vc4_bo *bo = NULL;
 	int ret;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	ret = vc4_dumb_fixup_args(args);
@@ -622,7 +622,7 @@
 	struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
 	int ret;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	/* Fast path: if the BO is already retained by someone, no need to
@@ -661,7 +661,7 @@
 {
 	struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	/* Fast path: if the BO is still retained by someone, no need to test
@@ -783,7 +783,7 @@
 	struct vc4_bo *bo = NULL;
 	int ret;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	ret = vc4_grab_bin_bo(vc4, vc4file);
@@ -813,7 +813,7 @@
 	struct drm_vc4_mmap_bo *args = data;
 	struct drm_gem_object *gem_obj;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	gem_obj = drm_gem_object_lookup(file_priv, args->handle);
@@ -839,7 +839,7 @@
 	struct vc4_bo *bo = NULL;
 	int ret;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	if (args->size == 0)
@@ -918,7 +918,7 @@
 	struct vc4_bo *bo;
 	bool t_format;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	if (args->flags != 0)
@@ -964,7 +964,7 @@
 	struct drm_gem_object *gem_obj;
 	struct vc4_bo *bo;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	if (args->flags != 0 || args->modifier != 0)
@@ -1007,7 +1007,7 @@
 	int ret;
 	int i;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	/* Create the initial set of BO labels that the kernel will
@@ -1071,7 +1071,7 @@
 	struct drm_gem_object *gem_obj;
 	int ret = 0, label;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	if (!args->len)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_crtc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -263,7 +263,7 @@
 		 * Removing 1 from the FIFO full level however
 		 * seems to completely remove that issue.
 		 */
-		if (!vc4->is_vc5)
+		if (vc4->gen == VC4_GEN_4)
 			return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX - 1;
 
 		return fifo_len_bytes - 3 * HVS_FIFO_LATENCY_PIX;
@@ -428,7 +428,7 @@
 	if (is_dsi)
 		CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
 
-	if (vc4->is_vc5)
+	if (vc4->gen == VC4_GEN_5)
 		CRTC_WRITE(PV_MUX_CFG,
 			   VC4_SET_FIELD(PV_MUX_CFG_RGB_PIXEL_MUX_MODE_NO_SWAP,
 					 PV_MUX_CFG_RGB_PIXEL_MUX_MODE));
@@ -913,7 +913,7 @@
 	struct dma_fence *fence;
 	int ret;
 
-	if (!vc4->is_vc5) {
+	if (vc4->gen == VC4_GEN_4) {
 		struct vc4_bo *bo = to_vc4_bo(&dma_bo->base);
 
 		return vc4_queue_seqno_cb(dev, &flip_state->cb.seqno, bo->seqno,
@@ -1000,7 +1000,7 @@
 	struct vc4_bo *bo = to_vc4_bo(&dma_bo->base);
 	int ret;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	/*
@@ -1043,7 +1043,7 @@
 		struct drm_device *dev = crtc->dev;
 		struct vc4_dev *vc4 = to_vc4_dev(dev);
 
-		if (vc4->is_vc5)
+		if (vc4->gen == VC4_GEN_5)
 			return vc5_async_page_flip(crtc, fb, event, flags);
 		else
 			return vc4_async_page_flip(crtc, fb, event, flags);
@@ -1338,9 +1338,8 @@
 
 	drm_crtc_helper_add(crtc, crtc_helper_funcs);
 
-	if (!vc4->is_vc5) {
+	if (vc4->gen == VC4_GEN_4) {
 		drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
-
 		drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
 
 		/* We support CTM, but only for one CRTC at a time. It's therefore
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_drv.c
@@ -98,7 +98,7 @@
 	if (args->pad != 0)
 		return -EINVAL;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	if (!vc4->v3d)
@@ -147,7 +147,7 @@
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	struct vc4_file *vc4file;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	vc4file = kzalloc(sizeof(*vc4file), GFP_KERNEL);
@@ -165,7 +165,7 @@
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	struct vc4_file *vc4file = file->driver_priv;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	if (vc4file->bin_bo_used)
@@ -291,13 +291,17 @@
 	struct vc4_dev *vc4;
 	struct device_node *node;
 	struct drm_crtc *crtc;
-	bool is_vc5;
+	enum vc4_gen gen;
 	int ret = 0;
 
 	dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
-	is_vc5 = of_device_is_compatible(dev->of_node, "brcm,bcm2711-vc5");
-	if (is_vc5)
+	if (of_device_is_compatible(dev->of_node, "brcm,bcm2711-vc5"))
+		gen = VC4_GEN_5;
+	else
+		gen = VC4_GEN_4;
+
+	if (gen == VC4_GEN_5)
 		driver = &vc5_drm_driver;
 	else
 		driver = &vc4_drm_driver;
@@ -315,13 +319,13 @@
 	vc4 = devm_drm_dev_alloc(dev, driver, struct vc4_dev, base);
 	if (IS_ERR(vc4))
 		return PTR_ERR(vc4);
-	vc4->is_vc5 = is_vc5;
+	vc4->gen = gen;
 	vc4->dev = dev;
 
 	drm = &vc4->base;
 	platform_set_drvdata(pdev, drm);
 
-	if (!is_vc5) {
+	if (gen == VC4_GEN_4) {
 		ret = drmm_mutex_init(drm, &vc4->bin_bo_lock);
 		if (ret)
 			goto err;
@@ -335,7 +339,7 @@
 	if (ret)
 		goto err;
 
-	if (!is_vc5) {
+	if (gen == VC4_GEN_4) {
 		ret = vc4_gem_init(drm);
 		if (ret)
 			goto err;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_drv.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_drv.h
@@ -79,11 +79,16 @@
 	u64 counters[] __counted_by(ncounters);
 };
 
+enum vc4_gen {
+	VC4_GEN_4,
+	VC4_GEN_5,
+};
+
 struct vc4_dev {
 	struct drm_device base;
 	struct device *dev;
 
-	bool is_vc5;
+	enum vc4_gen gen;
 
 	unsigned int irq;
 
@@ -314,6 +319,7 @@
 	struct platform_device *pdev;
 	void __iomem *regs;
 	u32 __iomem *dlist;
+	unsigned int dlist_mem_size;
 
 	struct clk *core_clk;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_gem.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_gem.c
@@ -76,7 +76,7 @@
 	u32 i;
 	int ret = 0;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	if (!vc4->v3d) {
@@ -389,7 +389,7 @@
 	unsigned long timeout_expire;
 	DEFINE_WAIT(wait);
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	if (vc4->finished_seqno >= seqno)
@@ -474,7 +474,7 @@
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	struct vc4_exec_info *exec;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 again:
@@ -522,7 +522,7 @@
 	if (!exec)
 		return;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	/* A previous RCL may have written to one of our textures, and
@@ -543,7 +543,7 @@
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	bool was_empty = list_empty(&vc4->render_job_list);
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	list_move_tail(&exec->head, &vc4->render_job_list);
@@ -970,7 +970,7 @@
 	unsigned long irqflags;
 	struct vc4_seqno_cb *cb, *cb_temp;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	spin_lock_irqsave(&vc4->job_lock, irqflags);
@@ -1009,7 +1009,7 @@
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	unsigned long irqflags;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	cb->func = func;
@@ -1065,7 +1065,7 @@
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	struct drm_vc4_wait_seqno *args = data;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	return vc4_wait_for_seqno_ioctl_helper(dev, args->seqno,
@@ -1082,7 +1082,7 @@
 	struct drm_gem_object *gem_obj;
 	struct vc4_bo *bo;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	if (args->pad != 0)
@@ -1131,7 +1131,7 @@
 				  args->shader_rec_size,
 				  args->bo_handle_count);
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	if (!vc4->v3d) {
@@ -1268,7 +1268,7 @@
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	int ret;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	vc4->dma_fence_context = dma_fence_context_alloc(1);
@@ -1327,7 +1327,7 @@
 	struct vc4_bo *bo;
 	int ret;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	switch (args->madv) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -179,6 +179,8 @@
 	if (!drm_dev_enter(drm, &idx))
 		return -ENODEV;
 
+	WARN_ON(pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev));
+
 	drm_print_regset32(&p, &vc4_hdmi->hdmi_regset);
 	drm_print_regset32(&p, &vc4_hdmi->hd_regset);
 	drm_print_regset32(&p, &vc4_hdmi->cec_regset);
@@ -188,6 +190,8 @@
 	drm_print_regset32(&p, &vc4_hdmi->ram_regset);
 	drm_print_regset32(&p, &vc4_hdmi->rm_regset);
 
+	pm_runtime_put(&vc4_hdmi->pdev->dev);
+
 	drm_dev_exit(idx);
 
 	return 0;
@@ -458,6 +462,7 @@
 {
 	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 	enum drm_connector_status status = connector_status_disconnected;
+	int ret;
 
 	/*
 	 * NOTE: This function should really take vc4_hdmi->mutex, but
@@ -470,7 +475,12 @@
 	 * the lock for now.
 	 */
 
-	WARN_ON(pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev));
+	ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev);
+	if (ret) {
+		drm_err_once(connector->dev, "Failed to retain HDMI power domain: %d\n",
+			     ret);
+		return connector_status_unknown;
+	}
 
 	if (vc4_hdmi->hpd_gpio) {
 		if (gpiod_get_value_cansleep(vc4_hdmi->hpd_gpio))
@@ -508,7 +518,7 @@
 	edid = drm_get_edid(connector, vc4_hdmi->ddc);
 	cec_s_phys_addr_from_edid(vc4_hdmi->cec_adap, edid);
 	if (!edid)
-		return -ENODEV;
+		return 0;
 
 	drm_connector_update_edid_property(connector, edid);
 	ret = drm_add_edid_modes(connector, edid);
@@ -2396,7 +2406,7 @@
 	}
 
 	if (!vc4_hdmi_audio_can_stream(vc4_hdmi)) {
-		ret = -ENODEV;
+		ret = -ENOTSUPP;
 		goto out_dev_exit;
 	}
 
@@ -2524,6 +2534,7 @@
 	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
 	struct drm_device *drm = vc4_hdmi->connector.dev;
 	struct drm_encoder *encoder = &vc4_hdmi->encoder.base;
+	struct vc4_dev *vc4 = to_vc4_dev(drm);
 	unsigned int sample_rate = params->sample_rate;
 	unsigned int channels = params->channels;
 	unsigned long flags;
@@ -2581,11 +2592,18 @@
 					     VC4_HDMI_AUDIO_PACKET_CEA_MASK);
 
 	/* Set the MAI threshold */
-	HDMI_WRITE(HDMI_MAI_THR,
-		   VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_PANICHIGH) |
-		   VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_PANICLOW) |
-		   VC4_SET_FIELD(0x06, VC4_HD_MAI_THR_DREQHIGH) |
-		   VC4_SET_FIELD(0x08, VC4_HD_MAI_THR_DREQLOW));
+	if (vc4->gen >= VC4_GEN_5)
+		HDMI_WRITE(HDMI_MAI_THR,
+			   VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICHIGH) |
+			   VC4_SET_FIELD(0x10, VC4_HD_MAI_THR_PANICLOW) |
+			   VC4_SET_FIELD(0x1c, VC4_HD_MAI_THR_DREQHIGH) |
+			   VC4_SET_FIELD(0x1c, VC4_HD_MAI_THR_DREQLOW));
+	else
+		HDMI_WRITE(HDMI_MAI_THR,
+			   VC4_SET_FIELD(0x8, VC4_HD_MAI_THR_PANICHIGH) |
+			   VC4_SET_FIELD(0x8, VC4_HD_MAI_THR_PANICLOW) |
+			   VC4_SET_FIELD(0x6, VC4_HD_MAI_THR_DREQHIGH) |
+			   VC4_SET_FIELD(0x8, VC4_HD_MAI_THR_DREQLOW));
 
 	HDMI_WRITE(HDMI_MAI_CONFIG,
 		   VC4_HDMI_MAI_CONFIG_BIT_REVERSE |
@@ -2655,9 +2673,9 @@
 	struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
 	struct drm_connector *connector = &vc4_hdmi->connector;
 
-	mutex_lock(&vc4_hdmi->mutex);
+	mutex_lock(&connector->eld_mutex);
 	memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
-	mutex_unlock(&vc4_hdmi->mutex);
+	mutex_unlock(&connector->eld_mutex);
 
 	return 0;
 }
@@ -2739,6 +2757,8 @@
 		index = 1;
 
 	addr = of_get_address(dev->of_node, index, NULL, NULL);
+	if (!addr)
+		return -EINVAL;
 
 	vc4_hdmi->audio.dma_data.addr = be32_to_cpup(addr) + mai_data->offset;
 	vc4_hdmi->audio.dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_hvs.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -110,7 +110,8 @@
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	struct vc4_hvs *hvs = vc4->hvs;
 	struct drm_printer p = drm_seq_file_printer(m);
-	unsigned int next_entry_start = 0;
+	unsigned int dlist_mem_size = hvs->dlist_mem_size;
+	unsigned int next_entry_start;
 	unsigned int i, j;
 	u32 dlist_word, dispstat;
 
@@ -124,8 +125,9 @@
 		}
 
 		drm_printf(&p, "HVS chan %u:\n", i);
+		next_entry_start = 0;
 
-		for (j = HVS_READ(SCALER_DISPLISTX(i)); j < 256; j++) {
+		for (j = HVS_READ(SCALER_DISPLISTX(i)); j < dlist_mem_size; j++) {
 			dlist_word = readl((u32 __iomem *)vc4->hvs->dlist + j);
 			drm_printf(&p, "dlist: %02d: 0x%08x\n", j,
 				   dlist_word);
@@ -222,6 +224,9 @@
 	if (!drm_dev_enter(drm, &idx))
 		return;
 
+	if (hvs->vc4->gen != VC4_GEN_4)
+		goto exit;
+
 	/* The LUT memory is laid out with each HVS channel in order,
 	 * each of which takes 256 writes for R, 256 for G, then 256
 	 * for B.
@@ -237,6 +242,7 @@
 	for (i = 0; i < crtc->gamma_size; i++)
 		HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_b[i]);
 
+exit:
 	drm_dev_exit(idx);
 }
 
@@ -291,7 +297,7 @@
 	u32 reg;
 	int ret;
 
-	if (!vc4->is_vc5)
+	if (vc4->gen == VC4_GEN_4)
 		return output;
 
 	/*
@@ -372,7 +378,7 @@
 	dispctrl = SCALER_DISPCTRLX_ENABLE;
 	dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(chan));
 
-	if (!vc4->is_vc5) {
+	if (vc4->gen == VC4_GEN_4) {
 		dispctrl |= VC4_SET_FIELD(mode->hdisplay,
 					  SCALER_DISPCTRLX_WIDTH) |
 			    VC4_SET_FIELD(mode->vdisplay,
@@ -394,7 +400,7 @@
 	dispbkgndx &= ~SCALER_DISPBKGND_INTERLACE;
 
 	HVS_WRITE(SCALER_DISPBKGNDX(chan), dispbkgndx |
-		  ((!vc4->is_vc5) ? SCALER_DISPBKGND_GAMMA : 0) |
+		  ((vc4->gen == VC4_GEN_4) ? SCALER_DISPBKGND_GAMMA : 0) |
 		  (interlace ? SCALER_DISPBKGND_INTERLACE : 0));
 
 	/* Reload the LUT, since the SRAMs would have been disabled if
@@ -415,13 +421,11 @@
 	if (!drm_dev_enter(drm, &idx))
 		return;
 
-	if (HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_ENABLE)
+	if (!(HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_ENABLE))
 		goto out;
 
-	HVS_WRITE(SCALER_DISPCTRLX(chan),
-		  HVS_READ(SCALER_DISPCTRLX(chan)) | SCALER_DISPCTRLX_RESET);
-	HVS_WRITE(SCALER_DISPCTRLX(chan),
-		  HVS_READ(SCALER_DISPCTRLX(chan)) & ~SCALER_DISPCTRLX_ENABLE);
+	HVS_WRITE(SCALER_DISPCTRLX(chan), SCALER_DISPCTRLX_RESET);
+	HVS_WRITE(SCALER_DISPCTRLX(chan), 0);
 
 	/* Once we leave, the scaler should be disabled and its fifo empty. */
 	WARN_ON_ONCE(HVS_READ(SCALER_DISPCTRLX(chan)) & SCALER_DISPCTRLX_RESET);
@@ -580,7 +584,7 @@
 	}
 
 	if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED)
-		return;
+		goto exit;
 
 	if (debug_dump_regs) {
 		DRM_INFO("CRTC %d HVS before:\n", drm_crtc_index(crtc));
@@ -663,12 +667,14 @@
 		vc4_hvs_dump_state(hvs);
 	}
 
+exit:
 	drm_dev_exit(idx);
 }
 
 void vc4_hvs_mask_underrun(struct vc4_hvs *hvs, int channel)
 {
-	struct drm_device *drm = &hvs->vc4->base;
+	struct vc4_dev *vc4 = hvs->vc4;
+	struct drm_device *drm = &vc4->base;
 	u32 dispctrl;
 	int idx;
 
@@ -676,8 +682,9 @@
 		return;
 
 	dispctrl = HVS_READ(SCALER_DISPCTRL);
-	dispctrl &= ~(hvs->vc4->is_vc5 ? SCALER5_DISPCTRL_DSPEISLUR(channel) :
-					 SCALER_DISPCTRL_DSPEISLUR(channel));
+	dispctrl &= ~((vc4->gen == VC4_GEN_5) ?
+		      SCALER5_DISPCTRL_DSPEISLUR(channel) :
+		      SCALER_DISPCTRL_DSPEISLUR(channel));
 
 	HVS_WRITE(SCALER_DISPCTRL, dispctrl);
 
@@ -686,7 +693,8 @@
 
 void vc4_hvs_unmask_underrun(struct vc4_hvs *hvs, int channel)
 {
-	struct drm_device *drm = &hvs->vc4->base;
+	struct vc4_dev *vc4 = hvs->vc4;
+	struct drm_device *drm = &vc4->base;
 	u32 dispctrl;
 	int idx;
 
@@ -694,8 +702,9 @@
 		return;
 
 	dispctrl = HVS_READ(SCALER_DISPCTRL);
-	dispctrl |= (hvs->vc4->is_vc5 ? SCALER5_DISPCTRL_DSPEISLUR(channel) :
-					SCALER_DISPCTRL_DSPEISLUR(channel));
+	dispctrl |= ((vc4->gen == VC4_GEN_5) ?
+		     SCALER5_DISPCTRL_DSPEISLUR(channel) :
+		     SCALER_DISPCTRL_DSPEISLUR(channel));
 
 	HVS_WRITE(SCALER_DISPSTAT,
 		  SCALER_DISPSTAT_EUFLOW(channel));
@@ -738,8 +747,10 @@
 	control = HVS_READ(SCALER_DISPCTRL);
 
 	for (channel = 0; channel < SCALER_CHANNELS_COUNT; channel++) {
-		dspeislur = vc4->is_vc5 ? SCALER5_DISPCTRL_DSPEISLUR(channel) :
-					  SCALER_DISPCTRL_DSPEISLUR(channel);
+		dspeislur = (vc4->gen == VC4_GEN_5) ?
+			SCALER5_DISPCTRL_DSPEISLUR(channel) :
+			SCALER_DISPCTRL_DSPEISLUR(channel);
+
 		/* Interrupt masking is not always honored, so check it here. */
 		if (status & SCALER_DISPSTAT_EUFLOW(channel) &&
 		    control & dspeislur) {
@@ -767,7 +778,7 @@
 	if (!vc4->hvs)
 		return -ENODEV;
 
-	if (!vc4->is_vc5)
+	if (vc4->gen == VC4_GEN_4)
 		debugfs_create_bool("hvs_load_tracker", S_IRUGO | S_IWUSR,
 				    minor->debugfs_root,
 				    &vc4->load_tracker_enabled);
@@ -800,16 +811,17 @@
 	 * our 16K), since we don't want to scramble the screen when
 	 * transitioning from the firmware's boot setup to runtime.
 	 */
+	hvs->dlist_mem_size = (SCALER_DLIST_SIZE >> 2) - HVS_BOOTLOADER_DLIST_END;
 	drm_mm_init(&hvs->dlist_mm,
 		    HVS_BOOTLOADER_DLIST_END,
-		    (SCALER_DLIST_SIZE >> 2) - HVS_BOOTLOADER_DLIST_END);
+		    hvs->dlist_mem_size);
 
 	/* Set up the HVS LBM memory manager.  We could have some more
 	 * complicated data structure that allowed reuse of LBM areas
 	 * between planes when they don't overlap on the screen, but
 	 * for now we just allocate globally.
 	 */
-	if (!vc4->is_vc5)
+	if (vc4->gen == VC4_GEN_4)
 		/* 48k words of 2x12-bit pixels */
 		drm_mm_init(&hvs->lbm_mm, 0, 48 * 1024);
 	else
@@ -843,7 +855,7 @@
 	hvs->regset.regs = hvs_regs;
 	hvs->regset.nregs = ARRAY_SIZE(hvs_regs);
 
-	if (vc4->is_vc5) {
+	if (vc4->gen == VC4_GEN_5) {
 		struct rpi_firmware *firmware;
 		struct device_node *node;
 		unsigned int max_rate;
@@ -881,7 +893,7 @@
 		}
 	}
 
-	if (!vc4->is_vc5)
+	if (vc4->gen == VC4_GEN_4)
 		hvs->dlist = hvs->regs + SCALER_DLIST_START;
 	else
 		hvs->dlist = hvs->regs + SCALER5_DLIST_START;
@@ -922,7 +934,7 @@
 		    SCALER_DISPCTRL_DISPEIRQ(1) |
 		    SCALER_DISPCTRL_DISPEIRQ(2);
 
-	if (!vc4->is_vc5)
+	if (vc4->gen == VC4_GEN_4)
 		dispctrl &= ~(SCALER_DISPCTRL_DMAEIRQ |
 			      SCALER_DISPCTRL_SLVWREIRQ |
 			      SCALER_DISPCTRL_SLVRDEIRQ |
@@ -962,11 +974,22 @@
 	dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC1);
 	dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2);
 
+	/* Set AXI panic mode.
+	 * VC4 panics when < 2 lines in FIFO.
+	 * VC5 panics when less than 1 line in the FIFO.
+	 */
+	dispctrl &= ~(SCALER_DISPCTRL_PANIC0_MASK |
+		      SCALER_DISPCTRL_PANIC1_MASK |
+		      SCALER_DISPCTRL_PANIC2_MASK);
+	dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC0);
+	dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC1);
+	dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2);
+
 	HVS_WRITE(SCALER_DISPCTRL, dispctrl);
 
 	/* Recompute Composite Output Buffer (COB) allocations for the displays
 	 */
-	if (!vc4->is_vc5) {
+	if (vc4->gen == VC4_GEN_4) {
 		/* The COB is 20736 pixels, or just over 10 lines at 2048 wide.
 		 * The bottom 2048 pixels are full 32bpp RGBA (intended for the
 		 * TXP composing RGBA to memory), whilst the remainder are only
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_irq.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_irq.c
@@ -263,7 +263,7 @@
 {
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	if (!vc4->v3d)
@@ -280,7 +280,7 @@
 {
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	if (!vc4->v3d)
@@ -303,7 +303,7 @@
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	int ret;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	if (irq == IRQ_NOTCONNECTED)
@@ -324,7 +324,7 @@
 {
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	vc4_irq_disable(dev);
@@ -337,7 +337,7 @@
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	unsigned long irqflags;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	/* Acknowledge any stale IRQs. */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_kms.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_kms.c
@@ -369,7 +369,7 @@
 		old_hvs_state->fifo_state[channel].pending_commit = NULL;
 	}
 
-	if (vc4->is_vc5) {
+	if (vc4->gen == VC4_GEN_5) {
 		unsigned long state_rate = max(old_hvs_state->core_clock_rate,
 					       new_hvs_state->core_clock_rate);
 		unsigned long core_rate = clamp_t(unsigned long, state_rate,
@@ -388,7 +388,7 @@
 
 	vc4_ctm_commit(vc4, state);
 
-	if (vc4->is_vc5)
+	if (vc4->gen == VC4_GEN_5)
 		vc5_hvs_pv_muxing_commit(vc4, state);
 	else
 		vc4_hvs_pv_muxing_commit(vc4, state);
@@ -406,7 +406,7 @@
 
 	drm_atomic_helper_cleanup_planes(dev, state);
 
-	if (vc4->is_vc5) {
+	if (vc4->gen == VC4_GEN_5) {
 		unsigned long core_rate = min_t(unsigned long,
 						hvs->max_core_rate,
 						new_hvs_state->core_clock_rate);
@@ -461,7 +461,7 @@
 	struct vc4_dev *vc4 = to_vc4_dev(dev);
 	struct drm_mode_fb_cmd2 mode_cmd_local;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return ERR_PTR(-ENODEV);
 
 	/* If the user didn't specify a modifier, use the
@@ -1040,7 +1040,7 @@
 	 * the BCM2711, but the load tracker computations are used for
 	 * the core clock rate calculation.
 	 */
-	if (!vc4->is_vc5) {
+	if (vc4->gen == VC4_GEN_4) {
 		/* Start with the load tracker enabled. Can be
 		 * disabled through the debugfs load_tracker file.
 		 */
@@ -1056,7 +1056,7 @@
 		return ret;
 	}
 
-	if (vc4->is_vc5) {
+	if (vc4->gen == VC4_GEN_5) {
 		dev->mode_config.max_width = 7680;
 		dev->mode_config.max_height = 7680;
 	} else {
@@ -1064,7 +1064,7 @@
 		dev->mode_config.max_height = 2048;
 	}
 
-	dev->mode_config.funcs = vc4->is_vc5 ? &vc5_mode_funcs : &vc4_mode_funcs;
+	dev->mode_config.funcs = (vc4->gen > VC4_GEN_4) ? &vc5_mode_funcs : &vc4_mode_funcs;
 	dev->mode_config.helper_private = &vc4_mode_config_helpers;
 	dev->mode_config.preferred_depth = 24;
 	dev->mode_config.async_page_flip = true;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_perfmon.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_perfmon.c
@@ -23,7 +23,7 @@
 		return;
 
 	vc4 = perfmon->dev;
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	refcount_inc(&perfmon->refcnt);
@@ -37,7 +37,7 @@
 		return;
 
 	vc4 = perfmon->dev;
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	if (refcount_dec_and_test(&perfmon->refcnt))
@@ -49,7 +49,7 @@
 	unsigned int i;
 	u32 mask;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	if (WARN_ON_ONCE(!perfmon || vc4->active_perfmon))
@@ -69,7 +69,7 @@
 {
 	unsigned int i;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	if (WARN_ON_ONCE(!vc4->active_perfmon ||
@@ -90,7 +90,7 @@
 	struct vc4_dev *vc4 = vc4file->dev;
 	struct vc4_perfmon *perfmon;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return NULL;
 
 	mutex_lock(&vc4file->perfmon.lock);
@@ -105,7 +105,7 @@
 {
 	struct vc4_dev *vc4 = vc4file->dev;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	mutex_init(&vc4file->perfmon.lock);
@@ -116,6 +116,11 @@
 static int vc4_perfmon_idr_del(int id, void *elem, void *data)
 {
 	struct vc4_perfmon *perfmon = elem;
+	struct vc4_dev *vc4 = (struct vc4_dev *)data;
+
+	/* If the active perfmon is being destroyed, stop it first */
+	if (perfmon == vc4->active_perfmon)
+		vc4_perfmon_stop(vc4, perfmon, false);
 
 	vc4_perfmon_put(perfmon);
 
@@ -126,11 +131,11 @@
 {
 	struct vc4_dev *vc4 = vc4file->dev;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	mutex_lock(&vc4file->perfmon.lock);
-	idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, NULL);
+	idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, vc4);
 	idr_destroy(&vc4file->perfmon.idr);
 	mutex_unlock(&vc4file->perfmon.lock);
 	mutex_destroy(&vc4file->perfmon.lock);
@@ -146,7 +151,7 @@
 	unsigned int i;
 	int ret;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	if (!vc4->v3d) {
@@ -200,7 +205,7 @@
 	struct drm_vc4_perfmon_destroy *req = data;
 	struct vc4_perfmon *perfmon;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	if (!vc4->v3d) {
@@ -228,7 +233,7 @@
 	struct vc4_perfmon *perfmon;
 	int ret;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	if (!vc4->v3d) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_plane.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_plane.c
@@ -587,10 +587,10 @@
 	}
 
 	/* Align it to 64 or 128 (hvs5) bytes */
-	lbm = roundup(lbm, vc4->is_vc5 ? 128 : 64);
+	lbm = roundup(lbm, vc4->gen == VC4_GEN_5 ? 128 : 64);
 
 	/* Each "word" of the LBM memory contains 2 or 4 (hvs5) pixels */
-	lbm /= vc4->is_vc5 ? 4 : 2;
+	lbm /= vc4->gen == VC4_GEN_5 ? 4 : 2;
 
 	return lbm;
 }
@@ -706,7 +706,7 @@
 		ret = drm_mm_insert_node_generic(&vc4->hvs->lbm_mm,
 						 &vc4_state->lbm,
 						 lbm_size,
-						 vc4->is_vc5 ? 64 : 32,
+						 vc4->gen == VC4_GEN_5 ? 64 : 32,
 						 0, 0);
 		spin_unlock_irqrestore(&vc4->hvs->mm_lock, irqflags);
 
@@ -1057,7 +1057,7 @@
 	mix_plane_alpha = state->alpha != DRM_BLEND_ALPHA_OPAQUE &&
 			  fb->format->has_alpha;
 
-	if (!vc4->is_vc5) {
+	if (vc4->gen == VC4_GEN_4) {
 	/* Control word */
 		vc4_dlist_write(vc4_state,
 				SCALER_CTL0_VALID |
@@ -1505,9 +1505,6 @@
 
 	drm_gem_plane_helper_prepare_fb(plane, state);
 
-	if (plane->state->fb == state->fb)
-		return 0;
-
 	return vc4_bo_inc_usecnt(bo);
 }
 
@@ -1516,7 +1513,7 @@
 {
 	struct vc4_bo *bo;
 
-	if (plane->state->fb == state->fb || !state->fb)
+	if (!state->fb)
 		return;
 
 	bo = to_vc4_bo(&drm_fb_dma_get_gem_obj(state->fb, 0)->base);
@@ -1632,7 +1629,7 @@
 	};
 
 	for (i = 0; i < ARRAY_SIZE(hvs_formats); i++) {
-		if (!hvs_formats[i].hvs5_only || vc4->is_vc5) {
+		if (!hvs_formats[i].hvs5_only || vc4->gen == VC4_GEN_5) {
 			formats[num_formats] = hvs_formats[i].drm;
 			num_formats++;
 		}
@@ -1647,7 +1644,7 @@
 		return ERR_CAST(vc4_plane);
 	plane = &vc4_plane->base;
 
-	if (vc4->is_vc5)
+	if (vc4->gen == VC4_GEN_5)
 		drm_plane_helper_add(plane, &vc5_plane_helper_funcs);
 	else
 		drm_plane_helper_add(plane, &vc4_plane_helper_funcs);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_render_cl.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_render_cl.c
@@ -599,7 +599,7 @@
 	bool has_bin = args->bin_cl_size != 0;
 	int ret;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	if (args->min_x_tile > args->max_x_tile ||
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_v3d.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_v3d.c
@@ -127,7 +127,7 @@
 int
 vc4_v3d_pm_get(struct vc4_dev *vc4)
 {
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	mutex_lock(&vc4->power_lock);
@@ -148,7 +148,7 @@
 void
 vc4_v3d_pm_put(struct vc4_dev *vc4)
 {
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	mutex_lock(&vc4->power_lock);
@@ -178,7 +178,7 @@
 	uint64_t seqno = 0;
 	struct vc4_exec_info *exec;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 try_again:
@@ -325,7 +325,7 @@
 {
 	int ret = 0;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	mutex_lock(&vc4->bin_bo_lock);
@@ -360,7 +360,7 @@
 
 void vc4_v3d_bin_bo_put(struct vc4_dev *vc4)
 {
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return;
 
 	mutex_lock(&vc4->bin_bo_lock);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_validate.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_validate.c
@@ -109,7 +109,7 @@
 	struct drm_gem_dma_object *obj;
 	struct vc4_bo *bo;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return NULL;
 
 	if (hindex >= exec->bo_count) {
@@ -169,7 +169,7 @@
 	uint32_t utile_w = utile_width(cpp);
 	uint32_t utile_h = utile_height(cpp);
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return false;
 
 	/* The shaded vertex format stores signed 12.4 fixed point
@@ -495,7 +495,7 @@
 	uint32_t dst_offset = 0;
 	uint32_t src_offset = 0;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	while (src_offset < len) {
@@ -942,7 +942,7 @@
 	uint32_t i;
 	int ret = 0;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return -ENODEV;
 
 	for (i = 0; i < exec->shader_state_count; i++) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vc4/vc4_validate_shaders.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vc4/vc4_validate_shaders.c
@@ -786,7 +786,7 @@
 	struct vc4_validated_shader_info *validated_shader = NULL;
 	struct vc4_shader_validation_state validation_state;
 
-	if (WARN_ON_ONCE(vc4->is_vc5))
+	if (WARN_ON_ONCE(vc4->gen == VC4_GEN_5))
 		return NULL;
 
 	memset(&validation_state, 0, sizeof(validation_state));
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -194,6 +194,13 @@
 #define to_virtio_gpu_framebuffer(x) \
 	container_of(x, struct virtio_gpu_framebuffer, base)
 
+struct virtio_gpu_plane_state {
+	struct drm_plane_state base;
+	struct virtio_gpu_fence *fence;
+};
+#define to_virtio_gpu_plane_state(x) \
+	container_of(x, struct virtio_gpu_plane_state, base)
+
 struct virtio_gpu_queue {
 	struct virtqueue *vq;
 	spinlock_t qlock;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -66,11 +66,28 @@
 	return format;
 }
 
+static struct
+drm_plane_state *virtio_gpu_plane_duplicate_state(struct drm_plane *plane)
+{
+	struct virtio_gpu_plane_state *new;
+
+	if (WARN_ON(!plane->state))
+		return NULL;
+
+	new = kzalloc(sizeof(*new), GFP_KERNEL);
+	if (!new)
+		return NULL;
+
+	__drm_atomic_helper_plane_duplicate_state(plane, &new->base);
+
+	return &new->base;
+}
+
 static const struct drm_plane_funcs virtio_gpu_plane_funcs = {
 	.update_plane		= drm_atomic_helper_update_plane,
 	.disable_plane		= drm_atomic_helper_disable_plane,
 	.reset			= drm_atomic_helper_plane_reset,
-	.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+	.atomic_duplicate_state = virtio_gpu_plane_duplicate_state,
 	.atomic_destroy_state	= drm_atomic_helper_plane_destroy_state,
 };
 
@@ -138,11 +155,13 @@
 	struct drm_device *dev = plane->dev;
 	struct virtio_gpu_device *vgdev = dev->dev_private;
 	struct virtio_gpu_framebuffer *vgfb;
+	struct virtio_gpu_plane_state *vgplane_st;
 	struct virtio_gpu_object *bo;
 
 	vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
+	vgplane_st = to_virtio_gpu_plane_state(plane->state);
 	bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]);
-	if (vgfb->fence) {
+	if (vgplane_st->fence) {
 		struct virtio_gpu_object_array *objs;
 
 		objs = virtio_gpu_array_alloc(1);
@@ -151,13 +170,11 @@
 		virtio_gpu_array_add_obj(objs, vgfb->base.obj[0]);
 		virtio_gpu_array_lock_resv(objs);
 		virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, x, y,
-					      width, height, objs, vgfb->fence);
+					      width, height, objs,
+					      vgplane_st->fence);
 		virtio_gpu_notify(vgdev);
-
-		dma_fence_wait_timeout(&vgfb->fence->f, true,
+		dma_fence_wait_timeout(&vgplane_st->fence->f, true,
 				       msecs_to_jiffies(50));
-		dma_fence_put(&vgfb->fence->f);
-		vgfb->fence = NULL;
 	} else {
 		virtio_gpu_cmd_resource_flush(vgdev, bo->hw_res_handle, x, y,
 					      width, height, NULL, NULL);
@@ -247,20 +264,23 @@
 	struct drm_device *dev = plane->dev;
 	struct virtio_gpu_device *vgdev = dev->dev_private;
 	struct virtio_gpu_framebuffer *vgfb;
+	struct virtio_gpu_plane_state *vgplane_st;
 	struct virtio_gpu_object *bo;
 
 	if (!new_state->fb)
 		return 0;
 
 	vgfb = to_virtio_gpu_framebuffer(new_state->fb);
+	vgplane_st = to_virtio_gpu_plane_state(new_state);
 	bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]);
 	if (!bo || (plane->type == DRM_PLANE_TYPE_PRIMARY && !bo->guest_blob))
 		return 0;
 
-	if (bo->dumb && (plane->state->fb != new_state->fb)) {
-		vgfb->fence = virtio_gpu_fence_alloc(vgdev, vgdev->fence_drv.context,
+	if (bo->dumb) {
+		vgplane_st->fence = virtio_gpu_fence_alloc(vgdev,
+						     vgdev->fence_drv.context,
 						     0);
-		if (!vgfb->fence)
+		if (!vgplane_st->fence)
 			return -ENOMEM;
 	}
 
@@ -270,15 +290,15 @@
 static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane,
 					struct drm_plane_state *state)
 {
-	struct virtio_gpu_framebuffer *vgfb;
+	struct virtio_gpu_plane_state *vgplane_st;
 
 	if (!state->fb)
 		return;
 
-	vgfb = to_virtio_gpu_framebuffer(state->fb);
-	if (vgfb->fence) {
-		dma_fence_put(&vgfb->fence->f);
-		vgfb->fence = NULL;
+	vgplane_st = to_virtio_gpu_plane_state(state);
+	if (vgplane_st->fence) {
+		dma_fence_put(&vgplane_st->fence->f);
+		vgplane_st->fence = NULL;
 	}
 }
 
@@ -291,6 +311,7 @@
 	struct virtio_gpu_device *vgdev = dev->dev_private;
 	struct virtio_gpu_output *output = NULL;
 	struct virtio_gpu_framebuffer *vgfb;
+	struct virtio_gpu_plane_state *vgplane_st;
 	struct virtio_gpu_object *bo = NULL;
 	uint32_t handle;
 
@@ -303,6 +324,7 @@
 
 	if (plane->state->fb) {
 		vgfb = to_virtio_gpu_framebuffer(plane->state->fb);
+		vgplane_st = to_virtio_gpu_plane_state(plane->state);
 		bo = gem_to_virtio_gpu_obj(vgfb->base.obj[0]);
 		handle = bo->hw_res_handle;
 	} else {
@@ -322,11 +344,9 @@
 			(vgdev, 0,
 			 plane->state->crtc_w,
 			 plane->state->crtc_h,
-			 0, 0, objs, vgfb->fence);
+			 0, 0, objs, vgplane_st->fence);
 		virtio_gpu_notify(vgdev);
-		dma_fence_wait(&vgfb->fence->f, true);
-		dma_fence_put(&vgfb->fence->f);
-		vgfb->fence = NULL;
+		dma_fence_wait(&vgplane_st->fence->f, true);
 	}
 
 	if (plane->state->fb != old_state->fb) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/virtio/virtgpu_submit.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/virtio/virtgpu_submit.c
@@ -48,7 +48,7 @@
 static int virtio_gpu_do_fence_wait(struct virtio_gpu_submit *submit,
 				    struct dma_fence *in_fence)
 {
-	u32 context = submit->fence_ctx + submit->ring_idx;
+	u64 context = submit->fence_ctx + submit->ring_idx;
 
 	if (dma_fence_match_context(in_fence, context))
 		return 0;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vkms/vkms_composer.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vkms/vkms_composer.c
@@ -123,6 +123,8 @@
 				      enum lut_channel channel)
 {
 	s64 lut_index = get_lut_index(lut, channel_value);
+	u16 *floor_lut_value, *ceil_lut_value;
+	u16 floor_channel_value, ceil_channel_value;
 
 	/*
 	 * This checks if `struct drm_color_lut` has any gap added by the compiler
@@ -130,11 +132,15 @@
 	 */
 	static_assert(sizeof(struct drm_color_lut) == sizeof(__u16) * 4);
 
-	u16 *floor_lut_value = (__u16 *)&lut->base[drm_fixp2int(lut_index)];
-	u16 *ceil_lut_value = (__u16 *)&lut->base[drm_fixp2int_ceil(lut_index)];
+	floor_lut_value = (__u16 *)&lut->base[drm_fixp2int(lut_index)];
+	if (drm_fixp2int(lut_index) == (lut->lut_length - 1))
+		/* We're at the end of the LUT array, use same value for ceil and floor */
+		ceil_lut_value = floor_lut_value;
+	else
+		ceil_lut_value = (__u16 *)&lut->base[drm_fixp2int_ceil(lut_index)];
 
-	u16 floor_channel_value = floor_lut_value[channel];
-	u16 ceil_channel_value = ceil_lut_value[channel];
+	floor_channel_value = floor_lut_value[channel];
+	ceil_channel_value = ceil_lut_value[channel];
 
 	return lerp_u16(floor_channel_value, ceil_channel_value,
 			lut_index & DRM_FIXED_DECIMAL_MASK);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vkms/vkms_output.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vkms/vkms_output.c
@@ -84,7 +84,7 @@
 				 DRM_MODE_CONNECTOR_VIRTUAL);
 	if (ret) {
 		DRM_ERROR("Failed to init connector\n");
-		goto err_connector;
+		return ret;
 	}
 
 	drm_connector_helper_add(connector, &vkms_conn_helper_funcs);
@@ -119,8 +119,5 @@
 err_encoder:
 	drm_connector_cleanup(connector);
 
-err_connector:
-	drm_crtc_cleanup(crtc);
-
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/Kconfig
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/Kconfig
@@ -2,7 +2,7 @@
 config DRM_VMWGFX
 	tristate "DRM driver for VMware Virtual GPU"
 	depends on DRM && PCI && MMU
-	depends on X86 || ARM64
+	depends on (X86 && HYPERVISOR_GUEST) || ARM64
 	select DRM_TTM
 	select DRM_TTM_HELPER
 	select MAPPING_DIRTY_HELPERS
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/ttm_object.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/ttm_object.c
@@ -87,14 +87,11 @@
  *
  * @object_lock: lock that protects idr.
  *
- * @object_count: Per device object count.
- *
  * This is the per-device data structure needed for ttm object management.
  */
 
 struct ttm_object_device {
 	spinlock_t object_lock;
-	atomic_t object_count;
 	struct dma_buf_ops ops;
 	void (*dmabuf_release)(struct dma_buf *dma_buf);
 	struct idr idr;
@@ -431,7 +428,6 @@
 		return NULL;
 
 	spin_lock_init(&tdev->object_lock);
-	atomic_set(&tdev->object_count, 0);
 
 	/*
 	 * Our base is at VMWGFX_NUM_MOB + 1 because we want to create
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmw_surface_cache.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmw_surface_cache.h
@@ -1,6 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
 /**********************************************************
- * Copyright 2021 VMware, Inc.
- * SPDX-License-Identifier: GPL-2.0 OR MIT
+ *
+ * Copyright (c) 2021-2024 Broadcom. All Rights Reserved. The term
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
  *
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
@@ -31,6 +33,10 @@
 
 #include <drm/vmwgfx_drm.h>
 
+#define SVGA3D_FLAGS_UPPER_32(svga3d_flags) ((svga3d_flags) >> 32)
+#define SVGA3D_FLAGS_LOWER_32(svga3d_flags) \
+	((svga3d_flags) & ((uint64_t)U32_MAX))
+
 static inline u32 clamped_umul32(u32 a, u32 b)
 {
 	uint64_t tmp = (uint64_t) a*b;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c
@@ -27,6 +27,8 @@
  **************************************************************************/
 
 #include "vmwgfx_drv.h"
+
+#include "vmwgfx_bo.h"
 #include <linux/highmem.h>
 
 /*
@@ -420,13 +422,105 @@
 	return 0;
 }
 
+static void *map_external(struct vmw_bo *bo, struct iosys_map *map)
+{
+	struct vmw_private *vmw =
+		container_of(bo->tbo.bdev, struct vmw_private, bdev);
+	void *ptr = NULL;
+	int ret;
+
+	if (bo->tbo.base.import_attach) {
+		ret = dma_buf_vmap(bo->tbo.base.dma_buf, map);
+		if (ret) {
+			drm_dbg_driver(&vmw->drm,
+				       "Wasn't able to map external bo!\n");
+			goto out;
+		}
+		ptr = map->vaddr;
+	} else {
+		ptr = vmw_bo_map_and_cache(bo);
+	}
+
+out:
+	return ptr;
+}
+
+static void unmap_external(struct vmw_bo *bo, struct iosys_map *map)
+{
+	if (bo->tbo.base.import_attach)
+		dma_buf_vunmap(bo->tbo.base.dma_buf, map);
+	else
+		vmw_bo_unmap(bo);
+}
+
+static int vmw_external_bo_copy(struct vmw_bo *dst, u32 dst_offset,
+				u32 dst_stride, struct vmw_bo *src,
+				u32 src_offset, u32 src_stride,
+				u32 width_in_bytes, u32 height,
+				struct vmw_diff_cpy *diff)
+{
+	struct vmw_private *vmw =
+		container_of(dst->tbo.bdev, struct vmw_private, bdev);
+	size_t dst_size = dst->tbo.resource->size;
+	size_t src_size = src->tbo.resource->size;
+	struct iosys_map dst_map = {0};
+	struct iosys_map src_map = {0};
+	int ret, i;
+	int x_in_bytes;
+	u8 *vsrc;
+	u8 *vdst;
+
+	vsrc = map_external(src, &src_map);
+	if (!vsrc) {
+		drm_dbg_driver(&vmw->drm, "Wasn't able to map src\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	vdst = map_external(dst, &dst_map);
+	if (!vdst) {
+		drm_dbg_driver(&vmw->drm, "Wasn't able to map dst\n");
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	vsrc += src_offset;
+	vdst += dst_offset;
+	if (src_stride == dst_stride) {
+		dst_size -= dst_offset;
+		src_size -= src_offset;
+		memcpy(vdst, vsrc,
+		       min(dst_stride * height, min(dst_size, src_size)));
+	} else {
+		WARN_ON(dst_stride < width_in_bytes);
+		for (i = 0; i < height; ++i) {
+			memcpy(vdst, vsrc, width_in_bytes);
+			vsrc += src_stride;
+			vdst += dst_stride;
+		}
+	}
+
+	x_in_bytes = (dst_offset % dst_stride);
+	diff->rect.x1 =  x_in_bytes / diff->cpp;
+	diff->rect.y1 = ((dst_offset - x_in_bytes) / dst_stride);
+	diff->rect.x2 = diff->rect.x1 + width_in_bytes / diff->cpp;
+	diff->rect.y2 = diff->rect.y1 + height;
+
+	ret = 0;
+out:
+	unmap_external(src, &src_map);
+	unmap_external(dst, &dst_map);
+
+	return ret;
+}
+
 /**
  * vmw_bo_cpu_blit - in-kernel cpu blit.
  *
- * @dst: Destination buffer object.
+ * @vmw_dst: Destination buffer object.
  * @dst_offset: Destination offset of blit start in bytes.
  * @dst_stride: Destination stride in bytes.
- * @src: Source buffer object.
+ * @vmw_src: Source buffer object.
  * @src_offset: Source offset of blit start in bytes.
  * @src_stride: Source stride in bytes.
  * @w: Width of blit.
@@ -444,20 +538,29 @@
  * Neither of the buffer objects may be placed in PCI memory
  * (Fixed memory in TTM terminology) when using this function.
  */
-int vmw_bo_cpu_blit(struct ttm_buffer_object *dst,
+int vmw_bo_cpu_blit(struct vmw_bo *vmw_dst,
 		    u32 dst_offset, u32 dst_stride,
-		    struct ttm_buffer_object *src,
+		    struct vmw_bo *vmw_src,
 		    u32 src_offset, u32 src_stride,
 		    u32 w, u32 h,
 		    struct vmw_diff_cpy *diff)
 {
+	struct ttm_buffer_object *src = &vmw_src->tbo;
+	struct ttm_buffer_object *dst = &vmw_dst->tbo;
 	struct ttm_operation_ctx ctx = {
 		.interruptible = false,
 		.no_wait_gpu = false
 	};
 	u32 j, initial_line = dst_offset / dst_stride;
-	struct vmw_bo_blit_line_data d;
+	struct vmw_bo_blit_line_data d = {0};
 	int ret = 0;
+	struct page **dst_pages = NULL;
+	struct page **src_pages = NULL;
+	bool src_external = (src->ttm->page_flags & TTM_TT_FLAG_EXTERNAL) != 0;
+	bool dst_external = (dst->ttm->page_flags & TTM_TT_FLAG_EXTERNAL) != 0;
+
+	if (WARN_ON(dst == src))
+		return -EINVAL;
 
 	/* Buffer objects need to be either pinned or reserved: */
 	if (!(dst->pin_count))
@@ -477,12 +580,40 @@
 			return ret;
 	}
 
+	if (src_external || dst_external)
+		return vmw_external_bo_copy(vmw_dst, dst_offset, dst_stride,
+					    vmw_src, src_offset, src_stride,
+					    w, h, diff);
+
+	if (!src->ttm->pages && src->ttm->sg) {
+		src_pages = kvmalloc_array(src->ttm->num_pages,
+					   sizeof(struct page *), GFP_KERNEL);
+		if (!src_pages)
+			return -ENOMEM;
+		ret = drm_prime_sg_to_page_array(src->ttm->sg, src_pages,
+						 src->ttm->num_pages);
+		if (ret)
+			goto out;
+	}
+	if (!dst->ttm->pages && dst->ttm->sg) {
+		dst_pages = kvmalloc_array(dst->ttm->num_pages,
+					   sizeof(struct page *), GFP_KERNEL);
+		if (!dst_pages) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		ret = drm_prime_sg_to_page_array(dst->ttm->sg, dst_pages,
+						 dst->ttm->num_pages);
+		if (ret)
+			goto out;
+	}
+
 	d.mapped_dst = 0;
 	d.mapped_src = 0;
 	d.dst_addr = NULL;
 	d.src_addr = NULL;
-	d.dst_pages = dst->ttm->pages;
-	d.src_pages = src->ttm->pages;
+	d.dst_pages = dst->ttm->pages ? dst->ttm->pages : dst_pages;
+	d.src_pages = src->ttm->pages ? src->ttm->pages : src_pages;
 	d.dst_num_pages = PFN_UP(dst->resource->size);
 	d.src_num_pages = PFN_UP(src->resource->size);
 	d.dst_prot = ttm_io_prot(dst, dst->resource, PAGE_KERNEL);
@@ -504,6 +635,10 @@
 		kunmap_atomic(d.src_addr);
 	if (d.dst_addr)
 		kunmap_atomic(d.dst_addr);
+	if (src_pages)
+		kvfree(src_pages);
+	if (dst_pages)
+		kvfree(dst_pages);
 
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /**************************************************************************
  *
- * Copyright © 2011-2023 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
+ * Copyright (c) 2011-2024 Broadcom. All Rights Reserved. The term
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -28,15 +28,39 @@
 
 #include "vmwgfx_bo.h"
 #include "vmwgfx_drv.h"
-
+#include "vmwgfx_resource_priv.h"
 
 #include <drm/ttm/ttm_placement.h>
 
 static void vmw_bo_release(struct vmw_bo *vbo)
 {
+	struct vmw_resource *res;
+
 	WARN_ON(vbo->tbo.base.funcs &&
 		kref_read(&vbo->tbo.base.refcount) != 0);
 	vmw_bo_unmap(vbo);
+
+	xa_destroy(&vbo->detached_resources);
+	WARN_ON(vbo->is_dumb && !vbo->dumb_surface);
+	if (vbo->is_dumb && vbo->dumb_surface) {
+		res = &vbo->dumb_surface->res;
+		WARN_ON(vbo != res->guest_memory_bo);
+		WARN_ON(!res->guest_memory_bo);
+		if (res->guest_memory_bo) {
+			/* Reserve and switch the backing mob. */
+			mutex_lock(&res->dev_priv->cmdbuf_mutex);
+			(void)vmw_resource_reserve(res, false, true);
+			vmw_resource_mob_detach(res);
+			if (res->coherent)
+				vmw_bo_dirty_release(res->guest_memory_bo);
+			res->guest_memory_bo = NULL;
+			res->guest_memory_offset = 0;
+			vmw_resource_unreserve(res, false, false, false, NULL,
+					       0);
+			mutex_unlock(&res->dev_priv->cmdbuf_mutex);
+		}
+		vmw_surface_unreference(&vbo->dumb_surface);
+	}
 	drm_gem_object_release(&vbo->tbo.base);
 }
 
@@ -204,6 +228,7 @@
 			     VMW_BO_DOMAIN_VRAM,
 			     VMW_BO_DOMAIN_VRAM);
 	buf->places[0].lpfn = PFN_UP(bo->resource->size);
+	buf->busy_places[0].lpfn = PFN_UP(bo->resource->size);
 	ret = ttm_bo_validate(bo, &buf->placement, &ctx);
 
 	/* For some reason we didn't end up at the start of vram */
@@ -325,18 +350,26 @@
  */
 void *vmw_bo_map_and_cache(struct vmw_bo *vbo)
 {
+	return vmw_bo_map_and_cache_size(vbo, vbo->tbo.base.size);
+}
+
+void *vmw_bo_map_and_cache_size(struct vmw_bo *vbo, size_t size)
+{
 	struct ttm_buffer_object *bo = &vbo->tbo;
 	bool not_used;
 	void *virtual;
 	int ret;
 
+	atomic_inc(&vbo->map_count);
+
 	virtual = ttm_kmap_obj_virtual(&vbo->map, &not_used);
 	if (virtual)
 		return virtual;
 
-	ret = ttm_bo_kmap(bo, 0, PFN_UP(bo->base.size), &vbo->map);
+	ret = ttm_bo_kmap(bo, 0, PFN_UP(size), &vbo->map);
 	if (ret)
-		DRM_ERROR("Buffer object map failed: %d.\n", ret);
+		DRM_ERROR("Buffer object map failed: %d (size: bo = %zu, map = %zu).\n",
+			  ret, bo->base.size, size);
 
 	return ttm_kmap_obj_virtual(&vbo->map, &not_used);
 }
@@ -352,11 +385,17 @@
  */
 void vmw_bo_unmap(struct vmw_bo *vbo)
 {
+	int map_count;
+
 	if (vbo->map.bo == NULL)
 		return;
 
-	ttm_bo_kunmap(&vbo->map);
-	vbo->map.bo = NULL;
+	map_count = atomic_dec_return(&vbo->map_count);
+
+	if (!map_count) {
+		ttm_bo_kunmap(&vbo->map);
+		vbo->map.bo = NULL;
+	}
 }
 
 
@@ -377,7 +416,8 @@
 {
 	struct ttm_operation_ctx ctx = {
 		.interruptible = params->bo_type != ttm_bo_type_kernel,
-		.no_wait_gpu = false
+		.no_wait_gpu = false,
+		.resv = params->resv,
 	};
 	struct ttm_device *bdev = &dev_priv->bdev;
 	struct drm_device *vdev = &dev_priv->drm;
@@ -388,20 +428,23 @@
 	BUILD_BUG_ON(TTM_MAX_BO_PRIORITY <= 3);
 	vmw_bo->tbo.priority = 3;
 	vmw_bo->res_tree = RB_ROOT;
+	xa_init(&vmw_bo->detached_resources);
+	atomic_set(&vmw_bo->map_count, 0);
 
 	params->size = ALIGN(params->size, PAGE_SIZE);
 	drm_gem_private_object_init(vdev, &vmw_bo->tbo.base, params->size);
 
 	vmw_bo_placement_set(vmw_bo, params->domain, params->busy_domain);
 	ret = ttm_bo_init_reserved(bdev, &vmw_bo->tbo, params->bo_type,
-				   &vmw_bo->placement, 0, &ctx, NULL,
-				   NULL, destroy);
+				   &vmw_bo->placement, 0, &ctx,
+				   params->sg, params->resv, destroy);
 	if (unlikely(ret))
 		return ret;
 
 	if (params->pin)
 		ttm_bo_pin(&vmw_bo->tbo);
-	ttm_bo_unreserve(&vmw_bo->tbo);
+	if (!params->keep_resv)
+		ttm_bo_unreserve(&vmw_bo->tbo);
 
 	return 0;
 }
@@ -652,52 +695,6 @@
 	dma_fence_put(&fence->base);
 }
 
-
-/**
- * vmw_dumb_create - Create a dumb kms buffer
- *
- * @file_priv: Pointer to a struct drm_file identifying the caller.
- * @dev: Pointer to the drm device.
- * @args: Pointer to a struct drm_mode_create_dumb structure
- * Return: Zero on success, negative error code on failure.
- *
- * This is a driver callback for the core drm create_dumb functionality.
- * Note that this is very similar to the vmw_bo_alloc ioctl, except
- * that the arguments have a different format.
- */
-int vmw_dumb_create(struct drm_file *file_priv,
-		    struct drm_device *dev,
-		    struct drm_mode_create_dumb *args)
-{
-	struct vmw_private *dev_priv = vmw_priv(dev);
-	struct vmw_bo *vbo;
-	int cpp = DIV_ROUND_UP(args->bpp, 8);
-	int ret;
-
-	switch (cpp) {
-	case 1: /* DRM_FORMAT_C8 */
-	case 2: /* DRM_FORMAT_RGB565 */
-	case 4: /* DRM_FORMAT_XRGB8888 */
-		break;
-	default:
-		/*
-		 * Dumb buffers don't allow anything else.
-		 * This is tested via IGT's dumb_buffers
-		 */
-		return -EINVAL;
-	}
-
-	args->pitch = args->width * cpp;
-	args->size = ALIGN(args->pitch * args->height, PAGE_SIZE);
-
-	ret = vmw_gem_object_create_with_handle(dev_priv, file_priv,
-						args->size, &args->handle,
-						&vbo);
-	/* drop reference from allocate - handle holds it now */
-	drm_gem_object_put(&vbo->tbo.base);
-	return ret;
-}
-
 /**
  * vmw_bo_swap_notify - swapout notify callback.
  *
@@ -836,3 +833,43 @@
 
 	vmw_bo_placement_set(bo, domain, domain);
 }
+
+void vmw_bo_add_detached_resource(struct vmw_bo *vbo, struct vmw_resource *res)
+{
+	xa_store(&vbo->detached_resources, (unsigned long)res, res, GFP_KERNEL);
+}
+
+void vmw_bo_del_detached_resource(struct vmw_bo *vbo, struct vmw_resource *res)
+{
+	xa_erase(&vbo->detached_resources, (unsigned long)res);
+}
+
+struct vmw_surface *vmw_bo_surface(struct vmw_bo *vbo)
+{
+	unsigned long index;
+	struct vmw_resource *res = NULL;
+	struct vmw_surface *surf = NULL;
+	struct rb_node *rb_itr = vbo->res_tree.rb_node;
+
+	if (vbo->is_dumb && vbo->dumb_surface) {
+		res = &vbo->dumb_surface->res;
+		goto out;
+	}
+
+	xa_for_each(&vbo->detached_resources, index, res) {
+		if (res->func->res_type == vmw_res_surface)
+			goto out;
+	}
+
+	for (rb_itr = rb_first(&vbo->res_tree); rb_itr;
+	     rb_itr = rb_next(rb_itr)) {
+		res = rb_entry(rb_itr, struct vmw_resource, mob_node);
+		if (res->func->res_type == vmw_res_surface)
+			goto out;
+	}
+
+out:
+	if (res)
+		surf = vmw_res_to_srf(res);
+	return surf;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h
@@ -1,7 +1,8 @@
 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
 /**************************************************************************
  *
- * Copyright 2023 VMware, Inc., Palo Alto, CA., USA
+ * Copyright (c) 2023-2024 Broadcom. All Rights Reserved. The term
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -35,11 +36,13 @@
 
 #include <linux/rbtree_types.h>
 #include <linux/types.h>
+#include <linux/xarray.h>
 
 struct vmw_bo_dirty;
 struct vmw_fence_obj;
 struct vmw_private;
 struct vmw_resource;
+struct vmw_surface;
 
 enum vmw_bo_domain {
 	VMW_BO_DOMAIN_SYS           = BIT(0),
@@ -53,8 +56,11 @@
 	u32 domain;
 	u32 busy_domain;
 	enum ttm_bo_type bo_type;
-	size_t size;
 	bool pin;
+	bool keep_resv;
+	size_t size;
+	struct dma_resv *resv;
+	struct sg_table *sg;
 };
 
 /**
@@ -66,6 +72,8 @@
  * @map: Kmap object for semi-persistent mappings
  * @res_tree: RB tree of resources using this buffer object as a backing MOB
  * @res_prios: Eviction priority counts for attached resources
+ * @map_count: The number of currently active maps. Will differ from the
+ * cpu_writers because it includes kernel maps.
  * @cpu_writers: Number of synccpu write grabs. Protected by reservation when
  * increased. May be decreased without reservation.
  * @dx_query_ctx: DX context if this buffer object is used as a DX query MOB
@@ -83,11 +91,16 @@
 
 	struct rb_root res_tree;
 	u32 res_prios[TTM_MAX_BO_PRIORITY];
+	struct xarray detached_resources;
 
+	atomic_t map_count;
 	atomic_t cpu_writers;
 	/* Not ref-counted.  Protected by binding_mutex */
 	struct vmw_resource *dx_query_ctx;
 	struct vmw_bo_dirty *dirty;
+
+	bool is_dumb;
+	struct vmw_surface *dumb_surface;
 };
 
 void vmw_bo_placement_set(struct vmw_bo *bo, u32 domain, u32 busy_domain);
@@ -122,15 +135,21 @@
 			 struct vmw_fence_obj *fence);
 
 void *vmw_bo_map_and_cache(struct vmw_bo *vbo);
+void *vmw_bo_map_and_cache_size(struct vmw_bo *vbo, size_t size);
 void vmw_bo_unmap(struct vmw_bo *vbo);
 
 void vmw_bo_move_notify(struct ttm_buffer_object *bo,
 			struct ttm_resource *mem);
 void vmw_bo_swap_notify(struct ttm_buffer_object *bo);
 
+void vmw_bo_add_detached_resource(struct vmw_bo *vbo, struct vmw_resource *res);
+void vmw_bo_del_detached_resource(struct vmw_bo *vbo, struct vmw_resource *res);
+struct vmw_surface *vmw_bo_surface(struct vmw_bo *vbo);
+
 int vmw_user_bo_lookup(struct drm_file *filp,
 		       u32 handle,
 		       struct vmw_bo **out);
+
 /**
  * vmw_bo_adjust_prio - Adjust the buffer object eviction priority
  * according to attached resources
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -399,7 +399,8 @@
 		.busy_domain = VMW_BO_DOMAIN_SYS,
 		.bo_type = ttm_bo_type_kernel,
 		.size = PAGE_SIZE,
-		.pin = true
+		.pin = true,
+		.keep_resv = true,
 	};
 
 	/*
@@ -411,10 +412,6 @@
 	if (unlikely(ret != 0))
 		return ret;
 
-	ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL);
-	BUG_ON(ret != 0);
-	vmw_bo_pin_reserved(vbo, true);
-
 	ret = ttm_bo_kmap(&vbo->tbo, 0, 1, &map);
 	if (likely(ret == 0)) {
 		result = ttm_kmap_obj_virtual(&map, &dummy);
@@ -666,11 +663,12 @@
 		[vmw_dma_map_populate] = "Caching DMA mappings.",
 		[vmw_dma_map_bind] = "Giving up DMA mappings early."};
 
-	/* TTM currently doesn't fully support SEV encryption. */
-	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
-		return -EINVAL;
-
-	if (vmw_force_coherent)
+	/*
+	 * When running with SEV we always want dma mappings, because
+	 * otherwise ttm tt pool pages will bounce through swiotlb running
+	 * out of available space.
+	 */
+	if (vmw_force_coherent || cc_platform_has(CC_ATTR_MEM_ENCRYPT))
 		dev_priv->map_mode = vmw_dma_alloc_coherent;
 	else if (vmw_restrict_iommu)
 		dev_priv->map_mode = vmw_dma_map_bind;
@@ -955,13 +953,6 @@
 				vmw_read(dev_priv,
 					 SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB);
 
-		/*
-		 * Workaround for low memory 2D VMs to compensate for the
-		 * allocation taken by fbdev
-		 */
-		if (!(dev_priv->capabilities & SVGA_CAP_3D))
-			mem_size *= 3;
-
 		dev_priv->max_mob_pages = mem_size * 1024 / PAGE_SIZE;
 		dev_priv->max_primary_mem =
 			vmw_read(dev_priv, SVGA_REG_MAX_PRIMARY_MEM);
@@ -1444,12 +1435,15 @@
 					    root, "system_ttm");
 	ttm_resource_manager_create_debugfs(ttm_manager_type(&vmw->bdev, TTM_PL_VRAM),
 					    root, "vram_ttm");
-	ttm_resource_manager_create_debugfs(ttm_manager_type(&vmw->bdev, VMW_PL_GMR),
-					    root, "gmr_ttm");
-	ttm_resource_manager_create_debugfs(ttm_manager_type(&vmw->bdev, VMW_PL_MOB),
-					    root, "mob_ttm");
-	ttm_resource_manager_create_debugfs(ttm_manager_type(&vmw->bdev, VMW_PL_SYSTEM),
-					    root, "system_mob_ttm");
+	if (vmw->has_gmr)
+		ttm_resource_manager_create_debugfs(ttm_manager_type(&vmw->bdev, VMW_PL_GMR),
+						    root, "gmr_ttm");
+	if (vmw->has_mob) {
+		ttm_resource_manager_create_debugfs(ttm_manager_type(&vmw->bdev, VMW_PL_MOB),
+						    root, "mob_ttm");
+		ttm_resource_manager_create_debugfs(ttm_manager_type(&vmw->bdev, VMW_PL_SYSTEM),
+						    root, "system_mob_ttm");
+	}
 }
 
 static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
@@ -1624,6 +1618,7 @@
 
 	.prime_fd_to_handle = vmw_prime_fd_to_handle,
 	.prime_handle_to_fd = vmw_prime_handle_to_fd,
+	.gem_prime_import_sg_table = vmw_prime_import_sg_table,
 
 	.fops = &vmwgfx_driver_fops,
 	.name = VMWGFX_DRIVER_NAME,
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -1,7 +1,8 @@
 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
 /**************************************************************************
  *
- * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
+ * Copyright (c) 2009-2024 Broadcom. All Rights Reserved. The term
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -61,7 +62,7 @@
 #define VMWGFX_DRIVER_MINOR 20
 #define VMWGFX_DRIVER_PATCHLEVEL 0
 #define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
-#define VMWGFX_MAX_DISPLAYS 16
+#define VMWGFX_NUM_DISPLAY_UNITS 8
 #define VMWGFX_CMD_BOUNCE_INIT_SIZE 32768
 
 #define VMWGFX_MIN_INITIAL_WIDTH 1280
@@ -81,7 +82,7 @@
 #define VMWGFX_NUM_GB_CONTEXT 256
 #define VMWGFX_NUM_GB_SHADER 20000
 #define VMWGFX_NUM_GB_SURFACE 32768
-#define VMWGFX_NUM_GB_SCREEN_TARGET VMWGFX_MAX_DISPLAYS
+#define VMWGFX_NUM_GB_SCREEN_TARGET VMWGFX_NUM_DISPLAY_UNITS
 #define VMWGFX_NUM_DXCONTEXT 256
 #define VMWGFX_NUM_DXQUERY 512
 #define VMWGFX_NUM_MOB (VMWGFX_NUM_GB_CONTEXT +\
@@ -117,25 +118,8 @@
 	unsigned long key;
 };
 
-
-/**
- * struct vmw_validate_buffer - Carries validation info about buffers.
- *
- * @base: Validation info for TTM.
- * @hash: Hash entry for quick lookup of the TTM buffer object.
- *
- * This structure contains also driver private validation info
- * on top of the info needed by TTM.
- */
-struct vmw_validate_buffer {
-	struct ttm_validate_buffer base;
-	struct vmwgfx_hash_item hash;
-	bool validate_as_mob;
-};
-
 struct vmw_res_func;
 
-
 /**
  * struct vmw-resource - base class for hardware resources
  *
@@ -445,15 +429,6 @@
 struct vmw_legacy_display;
 struct vmw_overlay;
 
-struct vmw_vga_topology_state {
-	uint32_t width;
-	uint32_t height;
-	uint32_t primary;
-	uint32_t pos_x;
-	uint32_t pos_y;
-};
-
-
 /*
  * struct vmw_otable - Guest Memory OBject table metadata
  *
@@ -501,7 +476,6 @@
 	struct drm_device drm;
 	struct ttm_device bdev;
 
-	struct drm_vma_offset_manager vma_manager;
 	u32 pci_id;
 	resource_size_t io_start;
 	resource_size_t vram_start;
@@ -787,6 +761,26 @@
 extern void vmw_gmr_unbind(struct vmw_private *dev_priv, int gmr_id);
 
 /**
+ * User handles
+ */
+struct vmw_user_object {
+	struct vmw_surface *surface;
+	struct vmw_bo *buffer;
+};
+
+int vmw_user_object_lookup(struct vmw_private *dev_priv, struct drm_file *filp,
+			   u32 handle, struct vmw_user_object *uo);
+struct vmw_user_object *vmw_user_object_ref(struct vmw_user_object *uo);
+void vmw_user_object_unref(struct vmw_user_object *uo);
+bool vmw_user_object_is_null(struct vmw_user_object *uo);
+struct vmw_surface *vmw_user_object_surface(struct vmw_user_object *uo);
+struct vmw_bo *vmw_user_object_buffer(struct vmw_user_object *uo);
+void *vmw_user_object_map(struct vmw_user_object *uo);
+void *vmw_user_object_map_size(struct vmw_user_object *uo, size_t size);
+void vmw_user_object_unmap(struct vmw_user_object *uo);
+bool vmw_user_object_is_mapped(struct vmw_user_object *uo);
+
+/**
  * Resource utilities - vmwgfx_resource.c
  */
 struct vmw_user_resource_conv;
@@ -800,11 +794,6 @@
 extern int vmw_resource_reserve(struct vmw_resource *res, bool interruptible,
 				bool no_backup);
 extern bool vmw_resource_needs_backup(const struct vmw_resource *res);
-extern int vmw_user_lookup_handle(struct vmw_private *dev_priv,
-				  struct drm_file *filp,
-				  uint32_t handle,
-				  struct vmw_surface **out_surf,
-				  struct vmw_bo **out_buf);
 extern int vmw_user_resource_lookup_handle(
 	struct vmw_private *dev_priv,
 	struct ttm_object_file *tfile,
@@ -1067,9 +1056,6 @@
 int vmw_kms_write_svga(struct vmw_private *vmw_priv,
 		       unsigned width, unsigned height, unsigned pitch,
 		       unsigned bpp, unsigned depth);
-bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
-				uint32_t pitch,
-				uint32_t height);
 int vmw_kms_present(struct vmw_private *dev_priv,
 		    struct drm_file *file_priv,
 		    struct vmw_framebuffer *vfb,
@@ -1084,9 +1070,6 @@
 int vmw_kms_resume(struct drm_device *dev);
 void vmw_kms_lost_device(struct drm_device *dev);
 
-int vmw_dumb_create(struct drm_file *file_priv,
-		    struct drm_device *dev,
-		    struct drm_mode_create_dumb *args);
 extern int vmw_resource_pin(struct vmw_resource *res, bool interruptible);
 extern void vmw_resource_unpin(struct vmw_resource *res);
 extern enum vmw_res_type vmw_res_type(const struct vmw_resource *res);
@@ -1131,6 +1114,9 @@
 				  struct drm_file *file_priv,
 				  uint32_t handle, uint32_t flags,
 				  int *prime_fd);
+struct drm_gem_object *vmw_prime_import_sg_table(struct drm_device *dev,
+						 struct dma_buf_attachment *attach,
+						 struct sg_table *table);
 
 /*
  * MemoryOBject management -  vmwgfx_mob.c
@@ -1200,6 +1186,15 @@
 int vmw_gb_surface_define(struct vmw_private *dev_priv,
 			  const struct vmw_surface_metadata *req,
 			  struct vmw_surface **srf_out);
+struct vmw_surface *vmw_lookup_surface_for_buffer(struct vmw_private *vmw,
+						  struct vmw_bo *bo,
+						  u32 handle);
+u32 vmw_lookup_surface_handle_for_buffer(struct vmw_private *vmw,
+					 struct vmw_bo *bo,
+					 u32 handle);
+int vmw_dumb_create(struct drm_file *file_priv,
+		    struct drm_device *dev,
+		    struct drm_mode_create_dumb *args);
 
 /*
  * Shader management - vmwgfx_shader.c
@@ -1355,9 +1350,9 @@
 
 void vmw_memcpy(struct vmw_diff_cpy *diff, u8 *dest, const u8 *src, size_t n);
 
-int vmw_bo_cpu_blit(struct ttm_buffer_object *dst,
+int vmw_bo_cpu_blit(struct vmw_bo *dst,
 		    u32 dst_offset, u32 dst_stride,
-		    struct ttm_buffer_object *src,
+		    struct vmw_bo *src,
 		    u32 src_offset, u32 src_stride,
 		    u32 w, u32 h,
 		    struct vmw_diff_cpy *diff);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -447,7 +447,7 @@
 	    vmw_res_type(ctx) == vmw_res_dx_context) {
 		for (i = 0; i < cotable_max; ++i) {
 			res = vmw_context_cotable(ctx, i);
-			if (IS_ERR(res))
+			if (IS_ERR_OR_NULL(res))
 				continue;
 
 			ret = vmw_execbuf_res_val_add(sw_context, res,
@@ -1266,6 +1266,8 @@
 		return -EINVAL;
 
 	cotable_res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXQUERY);
+	if (IS_ERR_OR_NULL(cotable_res))
+		return cotable_res ? PTR_ERR(cotable_res) : -EINVAL;
 	ret = vmw_cotable_notify(cotable_res, cmd->body.queryId);
 
 	return ret;
@@ -2484,6 +2486,8 @@
 		return ret;
 
 	res = vmw_context_cotable(ctx_node->ctx, vmw_view_cotables[view_type]);
+	if (IS_ERR_OR_NULL(res))
+		return res ? PTR_ERR(res) : -EINVAL;
 	ret = vmw_cotable_notify(res, cmd->defined_id);
 	if (unlikely(ret != 0))
 		return ret;
@@ -2569,8 +2573,8 @@
 
 	so_type = vmw_so_cmd_to_type(header->id);
 	res = vmw_context_cotable(ctx_node->ctx, vmw_so_cotables[so_type]);
-	if (IS_ERR(res))
-		return PTR_ERR(res);
+	if (IS_ERR_OR_NULL(res))
+		return res ? PTR_ERR(res) : -EINVAL;
 	cmd = container_of(header, typeof(*cmd), header);
 	ret = vmw_cotable_notify(res, cmd->defined_id);
 
@@ -2689,6 +2693,8 @@
 		return -EINVAL;
 
 	res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXSHADER);
+	if (IS_ERR_OR_NULL(res))
+		return res ? PTR_ERR(res) : -EINVAL;
 	ret = vmw_cotable_notify(res, cmd->body.shaderId);
 	if (ret)
 		return ret;
@@ -3010,6 +3016,8 @@
 	}
 
 	res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_STREAMOUTPUT);
+	if (IS_ERR_OR_NULL(res))
+		return res ? PTR_ERR(res) : -EINVAL;
 	ret = vmw_cotable_notify(res, cmd->body.soid);
 	if (ret)
 		return ret;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -32,7 +32,6 @@
 #define VMW_FENCE_WRAP (1 << 31)
 
 struct vmw_fence_manager {
-	int num_fence_objects;
 	struct vmw_private *dev_priv;
 	spinlock_t lock;
 	struct list_head fence_list;
@@ -124,13 +123,13 @@
 {
 	struct vmw_fence_obj *fence =
 		container_of(f, struct vmw_fence_obj, base);
-
 	struct vmw_fence_manager *fman = fman_from_fence(fence);
 
-	spin_lock(&fman->lock);
-	list_del_init(&fence->head);
-	--fman->num_fence_objects;
-	spin_unlock(&fman->lock);
+	if (!list_empty(&fence->head)) {
+		spin_lock(&fman->lock);
+		list_del_init(&fence->head);
+		spin_unlock(&fman->lock);
+	}
 	fence->destroy(fence);
 }
 
@@ -257,7 +256,6 @@
 	.release = vmw_fence_obj_destroy,
 };
 
-
 /*
  * Execute signal actions on fences recently signaled.
  * This is done from a workqueue so we don't have to execute
@@ -355,7 +353,6 @@
 		goto out_unlock;
 	}
 	list_add_tail(&fence->head, &fman->fence_list);
-	++fman->num_fence_objects;
 
 out_unlock:
 	spin_unlock(&fman->lock);
@@ -403,7 +400,7 @@
 				      u32 passed_seqno)
 {
 	u32 goal_seqno;
-	struct vmw_fence_obj *fence;
+	struct vmw_fence_obj *fence, *next_fence;
 
 	if (likely(!fman->seqno_valid))
 		return false;
@@ -413,7 +410,7 @@
 		return false;
 
 	fman->seqno_valid = false;
-	list_for_each_entry(fence, &fman->fence_list, head) {
+	list_for_each_entry_safe(fence, next_fence, &fman->fence_list, head) {
 		if (!list_empty(&fence->seq_passed_actions)) {
 			fman->seqno_valid = true;
 			vmw_fence_goal_write(fman->dev_priv,
@@ -991,7 +988,7 @@
 	}
 
 	event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED;
-	event->event.base.length = sizeof(*event);
+	event->event.base.length = sizeof(event->event);
 	event->event.user_data = user_data;
 
 	ret = drm_event_reserve_init(dev, file_priv, &event->base, &event->event.base);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c
@@ -149,6 +149,39 @@
 	return ret;
 }
 
+struct drm_gem_object *vmw_prime_import_sg_table(struct drm_device *dev,
+						 struct dma_buf_attachment *attach,
+						 struct sg_table *table)
+{
+	int ret;
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct drm_gem_object *gem = NULL;
+	struct vmw_bo *vbo;
+	struct vmw_bo_params params = {
+		.domain = (dev_priv->has_mob) ? VMW_BO_DOMAIN_SYS : VMW_BO_DOMAIN_VRAM,
+		.busy_domain = VMW_BO_DOMAIN_SYS,
+		.bo_type = ttm_bo_type_sg,
+		.size = attach->dmabuf->size,
+		.pin = false,
+		.keep_resv = true,
+		.resv = attach->dmabuf->resv,
+		.sg = table,
+
+	};
+
+	dma_resv_lock(params.resv, NULL);
+
+	ret = vmw_bo_create(dev_priv, &params, &vbo);
+	if (ret != 0)
+		goto out_no_bo;
+
+	vbo->tbo.base.funcs = &vmw_gem_object_funcs;
+
+	gem = &vbo->tbo.base;
+out_no_bo:
+	dma_resv_unlock(params.resv);
+	return gem;
+}
 
 int vmw_gem_object_create_ioctl(struct drm_device *dev, void *data,
 				struct drm_file *filp)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c
@@ -64,8 +64,11 @@
 	ttm_resource_init(bo, place, *res);
 
 	id = ida_alloc_max(&gman->gmr_ida, gman->max_gmr_ids - 1, GFP_KERNEL);
-	if (id < 0)
+	if (id < 0) {
+		ttm_resource_fini(man, *res);
+		kfree(*res);
 		return id;
+	}
 
 	spin_lock(&gman->lock);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /**************************************************************************
  *
- * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
+ * Copyright (c) 2009-2024 Broadcom. All Rights Reserved. The term
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -35,6 +36,7 @@
 #include <drm/drm_fourcc.h>
 #include <drm/drm_rect.h>
 #include <drm/drm_sysfs.h>
+#include <drm/drm_edid.h>
 
 void vmw_du_cleanup(struct vmw_display_unit *du)
 {
@@ -184,14 +186,16 @@
  */
 static u32 *vmw_du_cursor_plane_acquire_image(struct vmw_plane_state *vps)
 {
-	bool is_iomem;
-	if (vps->surf) {
-		if (vps->surf_mapped)
-			return vmw_bo_map_and_cache(vps->surf->res.guest_memory_bo);
-		return vps->surf->snooper.image;
-	} else if (vps->bo)
-		return ttm_kmap_obj_virtual(&vps->bo->map, &is_iomem);
-	return NULL;
+	struct vmw_surface *surf;
+
+	if (vmw_user_object_is_null(&vps->uo))
+		return NULL;
+
+	surf = vmw_user_object_surface(&vps->uo);
+	if (surf && !vmw_user_object_is_mapped(&vps->uo))
+		return surf->snooper.image;
+
+	return vmw_user_object_map(&vps->uo);
 }
 
 static bool vmw_du_cursor_plane_has_changed(struct vmw_plane_state *old_vps,
@@ -216,7 +220,7 @@
 	new_image = vmw_du_cursor_plane_acquire_image(new_vps);
 
 	changed = false;
-	if (old_image && new_image)
+	if (old_image && new_image && old_image != new_image)
 		changed = memcmp(old_image, new_image, size) != 0;
 
 	return changed;
@@ -272,6 +276,7 @@
 	u32 size = vmw_du_cursor_mob_size(vps->base.crtc_w, vps->base.crtc_h);
 	u32 i;
 	u32 cursor_max_dim, mob_max_size;
+	struct vmw_fence_obj *fence = NULL;
 	int ret;
 
 	if (!dev_priv->has_mob ||
@@ -313,7 +318,15 @@
 	if (ret != 0)
 		goto teardown;
 
-	vmw_bo_fence_single(&vps->cursor.bo->tbo, NULL);
+	ret = vmw_execbuf_fence_commands(NULL, dev_priv, &fence, NULL);
+	if (ret != 0) {
+		ttm_bo_unreserve(&vps->cursor.bo->tbo);
+		goto teardown;
+	}
+
+	dma_fence_wait(&fence->base, false);
+	dma_fence_put(&fence->base);
+
 	ttm_bo_unreserve(&vps->cursor.bo->tbo);
 	return 0;
 
@@ -519,22 +532,16 @@
  * vmw_du_plane_unpin_surf - unpins resource associated with a framebuffer surface
  *
  * @vps: plane state associated with the display surface
- * @unreference: true if we also want to unreference the display.
  */
-void vmw_du_plane_unpin_surf(struct vmw_plane_state *vps,
-			     bool unreference)
+void vmw_du_plane_unpin_surf(struct vmw_plane_state *vps)
 {
-	if (vps->surf) {
+	struct vmw_surface *surf = vmw_user_object_surface(&vps->uo);
+
+	if (surf) {
 		if (vps->pinned) {
-			vmw_resource_unpin(&vps->surf->res);
+			vmw_resource_unpin(&surf->res);
 			vps->pinned--;
 		}
-
-		if (unreference) {
-			if (vps->pinned)
-				DRM_ERROR("Surface still pinned\n");
-			vmw_surface_unreference(&vps->surf);
-		}
 	}
 }
 
@@ -555,7 +562,7 @@
 {
 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
 
-	vmw_du_plane_unpin_surf(vps, false);
+	vmw_du_plane_unpin_surf(vps);
 }
 
 
@@ -643,36 +650,15 @@
 {
 	struct vmw_cursor_plane *vcp = vmw_plane_to_vcp(plane);
 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
-	bool is_iomem;
-
-	if (vps->surf_mapped) {
-		vmw_bo_unmap(vps->surf->res.guest_memory_bo);
-		vps->surf_mapped = false;
-	}
-
-	if (vps->bo && ttm_kmap_obj_virtual(&vps->bo->map, &is_iomem)) {
-		const int ret = ttm_bo_reserve(&vps->bo->tbo, true, false, NULL);
 
-		if (likely(ret == 0)) {
-			ttm_bo_kunmap(&vps->bo->map);
-			ttm_bo_unreserve(&vps->bo->tbo);
-		}
-	}
+	if (!vmw_user_object_is_null(&vps->uo))
+		vmw_user_object_unmap(&vps->uo);
 
 	vmw_du_cursor_plane_unmap_cm(vps);
 	vmw_du_put_cursor_mob(vcp, vps);
 
-	vmw_du_plane_unpin_surf(vps, false);
-
-	if (vps->surf) {
-		vmw_surface_unreference(&vps->surf);
-		vps->surf = NULL;
-	}
-
-	if (vps->bo) {
-		vmw_bo_unreference(&vps->bo);
-		vps->bo = NULL;
-	}
+	vmw_du_plane_unpin_surf(vps);
+	vmw_user_object_unref(&vps->uo);
 }
 
 
@@ -691,60 +677,48 @@
 	struct drm_framebuffer *fb = new_state->fb;
 	struct vmw_cursor_plane *vcp = vmw_plane_to_vcp(plane);
 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
+	struct vmw_bo *bo = NULL;
 	int ret = 0;
 
-	if (vps->surf) {
-		vmw_surface_unreference(&vps->surf);
-		vps->surf = NULL;
-	}
-
-	if (vps->bo) {
-		vmw_bo_unreference(&vps->bo);
-		vps->bo = NULL;
+	if (!vmw_user_object_is_null(&vps->uo)) {
+		vmw_user_object_unmap(&vps->uo);
+		vmw_user_object_unref(&vps->uo);
 	}
 
 	if (fb) {
 		if (vmw_framebuffer_to_vfb(fb)->bo) {
-			vps->bo = vmw_framebuffer_to_vfbd(fb)->buffer;
-			vmw_bo_reference(vps->bo);
+			vps->uo.buffer = vmw_framebuffer_to_vfbd(fb)->buffer;
+			vps->uo.surface = NULL;
 		} else {
-			vps->surf = vmw_framebuffer_to_vfbs(fb)->surface;
-			vmw_surface_reference(vps->surf);
+			memcpy(&vps->uo, &vmw_framebuffer_to_vfbs(fb)->uo, sizeof(vps->uo));
 		}
+		vmw_user_object_ref(&vps->uo);
 	}
 
-	if (!vps->surf && vps->bo) {
-		const u32 size = new_state->crtc_w * new_state->crtc_h * sizeof(u32);
+	bo = vmw_user_object_buffer(&vps->uo);
+	if (bo) {
+		struct ttm_operation_ctx ctx = {false, false};
 
-		/*
-		 * Not using vmw_bo_map_and_cache() helper here as we need to
-		 * reserve the ttm_buffer_object first which
-		 * vmw_bo_map_and_cache() omits.
-		 */
-		ret = ttm_bo_reserve(&vps->bo->tbo, true, false, NULL);
-
-		if (unlikely(ret != 0))
+		ret = ttm_bo_reserve(&bo->tbo, true, false, NULL);
+		if (ret != 0)
 			return -ENOMEM;
 
-		ret = ttm_bo_kmap(&vps->bo->tbo, 0, PFN_UP(size), &vps->bo->map);
-
-		ttm_bo_unreserve(&vps->bo->tbo);
-
-		if (unlikely(ret != 0))
+		ret = ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
+		if (ret != 0)
 			return -ENOMEM;
-	} else if (vps->surf && !vps->bo && vps->surf->res.guest_memory_bo) {
 
-		WARN_ON(vps->surf->snooper.image);
-		ret = ttm_bo_reserve(&vps->surf->res.guest_memory_bo->tbo, true, false,
-				     NULL);
-		if (unlikely(ret != 0))
-			return -ENOMEM;
-		vmw_bo_map_and_cache(vps->surf->res.guest_memory_bo);
-		ttm_bo_unreserve(&vps->surf->res.guest_memory_bo->tbo);
-		vps->surf_mapped = true;
+		vmw_bo_pin_reserved(bo, true);
+		if (vmw_framebuffer_to_vfb(fb)->bo) {
+			const u32 size = new_state->crtc_w * new_state->crtc_h * sizeof(u32);
+
+			(void)vmw_bo_map_and_cache_size(bo, size);
+		} else {
+			vmw_bo_map_and_cache(bo);
+		}
+		ttm_bo_unreserve(&bo->tbo);
 	}
 
-	if (vps->surf || vps->bo) {
+	if (!vmw_user_object_is_null(&vps->uo)) {
 		vmw_du_get_cursor_mob(vcp, vps);
 		vmw_du_cursor_plane_map_cm(vps);
 	}
@@ -766,15 +740,18 @@
 	struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
 	struct vmw_plane_state *old_vps = vmw_plane_state_to_vps(old_state);
+	struct vmw_bo *old_bo = NULL;
+	struct vmw_bo *new_bo = NULL;
+	struct ww_acquire_ctx ctx;
 	s32 hotspot_x, hotspot_y;
+	int ret;
 
 	hotspot_x = du->hotspot_x + new_state->hotspot_x;
 	hotspot_y = du->hotspot_y + new_state->hotspot_y;
 
-	du->cursor_surface = vps->surf;
-	du->cursor_bo = vps->bo;
+	du->cursor_surface = vmw_user_object_surface(&vps->uo);
 
-	if (!vps->surf && !vps->bo) {
+	if (vmw_user_object_is_null(&vps->uo)) {
 		vmw_cursor_update_position(dev_priv, false, 0, 0);
 		return;
 	}
@@ -782,10 +759,33 @@
 	vps->cursor.hotspot_x = hotspot_x;
 	vps->cursor.hotspot_y = hotspot_y;
 
-	if (vps->surf) {
+	if (du->cursor_surface)
 		du->cursor_age = du->cursor_surface->snooper.age;
+
+	ww_acquire_init(&ctx, &reservation_ww_class);
+
+	if (!vmw_user_object_is_null(&old_vps->uo)) {
+		old_bo = vmw_user_object_buffer(&old_vps->uo);
+		ret = ttm_bo_reserve(&old_bo->tbo, false, false, &ctx);
+		if (ret != 0)
+			return;
 	}
 
+	if (!vmw_user_object_is_null(&vps->uo)) {
+		new_bo = vmw_user_object_buffer(&vps->uo);
+		if (old_bo != new_bo) {
+			ret = ttm_bo_reserve(&new_bo->tbo, false, false, &ctx);
+			if (ret != 0) {
+				if (old_bo) {
+					ttm_bo_unreserve(&old_bo->tbo);
+					ww_acquire_fini(&ctx);
+				}
+				return;
+			}
+		} else {
+			new_bo = NULL;
+		}
+	}
 	if (!vmw_du_cursor_plane_has_changed(old_vps, vps)) {
 		/*
 		 * If it hasn't changed, avoid making the device do extra
@@ -803,6 +803,13 @@
 						hotspot_x, hotspot_y);
 	}
 
+	if (new_bo)
+		ttm_bo_unreserve(&new_bo->tbo);
+	if (old_bo)
+		ttm_bo_unreserve(&old_bo->tbo);
+
+	ww_acquire_fini(&ctx);
+
 	du->cursor_x = new_state->crtc_x + du->set_gui_x;
 	du->cursor_y = new_state->crtc_y + du->set_gui_y;
 
@@ -855,15 +862,6 @@
 						  DRM_PLANE_NO_SCALING,
 						  DRM_PLANE_NO_SCALING,
 						  false, true);
-
-	if (!ret && new_fb) {
-		struct drm_crtc *crtc = new_state->crtc;
-		struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
-
-		vmw_connector_state_to_vcs(du->connector.state);
-	}
-
-
 	return ret;
 }
 
@@ -912,7 +910,7 @@
 	}
 
 	if (!vmw_framebuffer_to_vfb(fb)->bo) {
-		surface = vmw_framebuffer_to_vfbs(fb)->surface;
+		surface = vmw_user_object_surface(&vmw_framebuffer_to_vfbs(fb)->uo);
 
 		WARN_ON(!surface);
 
@@ -930,6 +928,7 @@
 int vmw_du_crtc_atomic_check(struct drm_crtc *crtc,
 			     struct drm_atomic_state *state)
 {
+	struct vmw_private *vmw = vmw_priv(crtc->dev);
 	struct drm_crtc_state *new_state = drm_atomic_get_new_crtc_state(state,
 									 crtc);
 	struct vmw_display_unit *du = vmw_crtc_to_du(new_state->crtc);
@@ -937,9 +936,13 @@
 	bool has_primary = new_state->plane_mask &
 			   drm_plane_mask(crtc->primary);
 
-	/* We always want to have an active plane with an active CRTC */
-	if (has_primary != new_state->enable)
-		return -EINVAL;
+	/*
+	 * This is fine in general, but broken userspace might expect
+	 * some actual rendering so give a clue as why it's blank.
+	 */
+	if (new_state->enable && !has_primary)
+		drm_dbg_driver(&vmw->drm,
+			       "CRTC without a primary plane will be blank.\n");
 
 
 	if (new_state->connector_mask != connector_mask &&
@@ -1074,12 +1077,7 @@
 	memset(&vps->cursor, 0, sizeof(vps->cursor));
 
 	/* Each ref counted resource needs to be acquired again */
-	if (vps->surf)
-		(void) vmw_surface_reference(vps->surf);
-
-	if (vps->bo)
-		(void) vmw_bo_reference(vps->bo);
-
+	vmw_user_object_ref(&vps->uo);
 	state = &vps->base;
 
 	__drm_atomic_helper_plane_duplicate_state(plane, state);
@@ -1128,11 +1126,7 @@
 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(state);
 
 	/* Should have been freed by cleanup_fb */
-	if (vps->surf)
-		vmw_surface_unreference(&vps->surf);
-
-	if (vps->bo)
-		vmw_bo_unreference(&vps->bo);
+	vmw_user_object_unref(&vps->uo);
 
 	drm_atomic_helper_plane_destroy_state(plane, state);
 }
@@ -1227,7 +1221,7 @@
 		vmw_framebuffer_to_vfbs(framebuffer);
 
 	drm_framebuffer_cleanup(framebuffer);
-	vmw_surface_unreference(&vfbs->surface);
+	vmw_user_object_unref(&vfbs->uo);
 
 	kfree(vfbs);
 }
@@ -1272,29 +1266,42 @@
 	return -ENOSYS;
 }
 
+static int vmw_framebuffer_surface_create_handle(struct drm_framebuffer *fb,
+						 struct drm_file *file_priv,
+						 unsigned int *handle)
+{
+	struct vmw_framebuffer_surface *vfbs = vmw_framebuffer_to_vfbs(fb);
+	struct vmw_bo *bo = vmw_user_object_buffer(&vfbs->uo);
+
+	if (WARN_ON(!bo))
+		return -EINVAL;
+	return drm_gem_handle_create(file_priv, &bo->tbo.base, handle);
+}
 
 static const struct drm_framebuffer_funcs vmw_framebuffer_surface_funcs = {
+	.create_handle = vmw_framebuffer_surface_create_handle,
 	.destroy = vmw_framebuffer_surface_destroy,
 	.dirty = drm_atomic_helper_dirtyfb,
 };
 
 static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv,
-					   struct vmw_surface *surface,
+					   struct vmw_user_object *uo,
 					   struct vmw_framebuffer **out,
 					   const struct drm_mode_fb_cmd2
-					   *mode_cmd,
-					   bool is_bo_proxy)
+					   *mode_cmd)
 
 {
 	struct drm_device *dev = &dev_priv->drm;
 	struct vmw_framebuffer_surface *vfbs;
-	enum SVGA3dSurfaceFormat format;
+	struct vmw_surface *surface;
 	int ret;
 
 	/* 3D is only supported on HWv8 and newer hosts */
 	if (dev_priv->active_display_unit == vmw_du_legacy)
 		return -ENOSYS;
 
+	surface = vmw_user_object_surface(uo);
+
 	/*
 	 * Sanity checks.
 	 */
@@ -1322,34 +1329,6 @@
 		return -EINVAL;
 	}
 
-	switch (mode_cmd->pixel_format) {
-	case DRM_FORMAT_ARGB8888:
-		format = SVGA3D_A8R8G8B8;
-		break;
-	case DRM_FORMAT_XRGB8888:
-		format = SVGA3D_X8R8G8B8;
-		break;
-	case DRM_FORMAT_RGB565:
-		format = SVGA3D_R5G6B5;
-		break;
-	case DRM_FORMAT_XRGB1555:
-		format = SVGA3D_A1R5G5B5;
-		break;
-	default:
-		DRM_ERROR("Invalid pixel format: %p4cc\n",
-			  &mode_cmd->pixel_format);
-		return -EINVAL;
-	}
-
-	/*
-	 * For DX, surface format validation is done when surface->scanout
-	 * is set.
-	 */
-	if (!has_sm4_context(dev_priv) && format != surface->metadata.format) {
-		DRM_ERROR("Invalid surface format for requested mode.\n");
-		return -EINVAL;
-	}
-
 	vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL);
 	if (!vfbs) {
 		ret = -ENOMEM;
@@ -1357,9 +1336,8 @@
 	}
 
 	drm_helper_mode_fill_fb_struct(dev, &vfbs->base.base, mode_cmd);
-	vfbs->surface = vmw_surface_reference(surface);
-	vfbs->base.user_handle = mode_cmd->handles[0];
-	vfbs->is_bo_proxy = is_bo_proxy;
+	memcpy(&vfbs->uo, uo, sizeof(vfbs->uo));
+	vmw_user_object_ref(&vfbs->uo);
 
 	*out = &vfbs->base;
 
@@ -1371,7 +1349,7 @@
 	return 0;
 
 out_err2:
-	vmw_surface_unreference(&surface);
+	vmw_user_object_unref(&vfbs->uo);
 	kfree(vfbs);
 out_err1:
 	return ret;
@@ -1387,7 +1365,6 @@
 {
 	struct vmw_framebuffer_bo *vfbd =
 			vmw_framebuffer_to_vfbd(fb);
-
 	return drm_gem_handle_create(file_priv, &vfbd->buffer->tbo.base, handle);
 }
 
@@ -1408,86 +1385,6 @@
 	.dirty = drm_atomic_helper_dirtyfb,
 };
 
-/**
- * vmw_create_bo_proxy - create a proxy surface for the buffer object
- *
- * @dev: DRM device
- * @mode_cmd: parameters for the new surface
- * @bo_mob: MOB backing the buffer object
- * @srf_out: newly created surface
- *
- * When the content FB is a buffer object, we create a surface as a proxy to the
- * same buffer.  This way we can do a surface copy rather than a surface DMA.
- * This is a more efficient approach
- *
- * RETURNS:
- * 0 on success, error code otherwise
- */
-static int vmw_create_bo_proxy(struct drm_device *dev,
-			       const struct drm_mode_fb_cmd2 *mode_cmd,
-			       struct vmw_bo *bo_mob,
-			       struct vmw_surface **srf_out)
-{
-	struct vmw_surface_metadata metadata = {0};
-	uint32_t format;
-	struct vmw_resource *res;
-	unsigned int bytes_pp;
-	int ret;
-
-	switch (mode_cmd->pixel_format) {
-	case DRM_FORMAT_ARGB8888:
-	case DRM_FORMAT_XRGB8888:
-		format = SVGA3D_X8R8G8B8;
-		bytes_pp = 4;
-		break;
-
-	case DRM_FORMAT_RGB565:
-	case DRM_FORMAT_XRGB1555:
-		format = SVGA3D_R5G6B5;
-		bytes_pp = 2;
-		break;
-
-	case 8:
-		format = SVGA3D_P8;
-		bytes_pp = 1;
-		break;
-
-	default:
-		DRM_ERROR("Invalid framebuffer format %p4cc\n",
-			  &mode_cmd->pixel_format);
-		return -EINVAL;
-	}
-
-	metadata.format = format;
-	metadata.mip_levels[0] = 1;
-	metadata.num_sizes = 1;
-	metadata.base_size.width = mode_cmd->pitches[0] / bytes_pp;
-	metadata.base_size.height =  mode_cmd->height;
-	metadata.base_size.depth = 1;
-	metadata.scanout = true;
-
-	ret = vmw_gb_surface_define(vmw_priv(dev), &metadata, srf_out);
-	if (ret) {
-		DRM_ERROR("Failed to allocate proxy content buffer\n");
-		return ret;
-	}
-
-	res = &(*srf_out)->res;
-
-	/* Reserve and switch the backing mob. */
-	mutex_lock(&res->dev_priv->cmdbuf_mutex);
-	(void) vmw_resource_reserve(res, false, true);
-	vmw_user_bo_unref(&res->guest_memory_bo);
-	res->guest_memory_bo = vmw_user_bo_ref(bo_mob);
-	res->guest_memory_offset = 0;
-	vmw_resource_unreserve(res, false, false, false, NULL, 0);
-	mutex_unlock(&res->dev_priv->cmdbuf_mutex);
-
-	return 0;
-}
-
-
-
 static int vmw_kms_new_framebuffer_bo(struct vmw_private *dev_priv,
 				      struct vmw_bo *bo,
 				      struct vmw_framebuffer **out,
@@ -1526,7 +1423,6 @@
 	drm_helper_mode_fill_fb_struct(dev, &vfbd->base.base, mode_cmd);
 	vfbd->base.bo = true;
 	vfbd->buffer = vmw_bo_reference(bo);
-	vfbd->base.user_handle = mode_cmd->handles[0];
 	*out = &vfbd->base;
 
 	ret = drm_framebuffer_init(dev, &vfbd->base.base,
@@ -1567,55 +1463,24 @@
  * vmw_kms_new_framebuffer - Create a new framebuffer.
  *
  * @dev_priv: Pointer to device private struct.
- * @bo: Pointer to buffer object to wrap the kms framebuffer around.
- * Either @bo or @surface must be NULL.
- * @surface: Pointer to a surface to wrap the kms framebuffer around.
- * Either @bo or @surface must be NULL.
- * @only_2d: No presents will occur to this buffer object based framebuffer.
- * This helps the code to do some important optimizations.
+ * @uo: Pointer to user object to wrap the kms framebuffer around.
+ * Either the buffer or surface inside the user object must be NULL.
  * @mode_cmd: Frame-buffer metadata.
  */
 struct vmw_framebuffer *
 vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
-			struct vmw_bo *bo,
-			struct vmw_surface *surface,
-			bool only_2d,
+			struct vmw_user_object *uo,
 			const struct drm_mode_fb_cmd2 *mode_cmd)
 {
 	struct vmw_framebuffer *vfb = NULL;
-	bool is_bo_proxy = false;
 	int ret;
 
-	/*
-	 * We cannot use the SurfaceDMA command in an non-accelerated VM,
-	 * therefore, wrap the buffer object in a surface so we can use the
-	 * SurfaceCopy command.
-	 */
-	if (vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)  &&
-	    bo && only_2d &&
-	    mode_cmd->width > 64 &&  /* Don't create a proxy for cursor */
-	    dev_priv->active_display_unit == vmw_du_screen_target) {
-		ret = vmw_create_bo_proxy(&dev_priv->drm, mode_cmd,
-					  bo, &surface);
-		if (ret)
-			return ERR_PTR(ret);
-
-		is_bo_proxy = true;
-	}
-
 	/* Create the new framebuffer depending one what we have */
-	if (surface) {
-		ret = vmw_kms_new_framebuffer_surface(dev_priv, surface, &vfb,
-						      mode_cmd,
-						      is_bo_proxy);
-		/*
-		 * vmw_create_bo_proxy() adds a reference that is no longer
-		 * needed
-		 */
-		if (is_bo_proxy)
-			vmw_surface_unreference(&surface);
-	} else if (bo) {
-		ret = vmw_kms_new_framebuffer_bo(dev_priv, bo, &vfb,
+	if (vmw_user_object_surface(uo)) {
+		ret = vmw_kms_new_framebuffer_surface(dev_priv, uo, &vfb,
+						      mode_cmd);
+	} else if (uo->buffer) {
+		ret = vmw_kms_new_framebuffer_bo(dev_priv, uo->buffer, &vfb,
 						 mode_cmd);
 	} else {
 		BUG();
@@ -1637,14 +1502,12 @@
 {
 	struct vmw_private *dev_priv = vmw_priv(dev);
 	struct vmw_framebuffer *vfb = NULL;
-	struct vmw_surface *surface = NULL;
-	struct vmw_bo *bo = NULL;
+	struct vmw_user_object uo = {0};
 	int ret;
 
 	/* returns either a bo or surface */
-	ret = vmw_user_lookup_handle(dev_priv, file_priv,
-				     mode_cmd->handles[0],
-				     &surface, &bo);
+	ret = vmw_user_object_lookup(dev_priv, file_priv, mode_cmd->handles[0],
+				     &uo);
 	if (ret) {
 		DRM_ERROR("Invalid buffer object handle %u (0x%x).\n",
 			  mode_cmd->handles[0], mode_cmd->handles[0]);
@@ -1652,29 +1515,25 @@
 	}
 
 
-	if (!bo &&
+	if (vmw_user_object_surface(&uo) &&
 	    !vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)) {
 		DRM_ERROR("Surface size cannot exceed %dx%d\n",
 			dev_priv->texture_max_width,
 			dev_priv->texture_max_height);
+		ret = -EINVAL;
 		goto err_out;
 	}
 
 
-	vfb = vmw_kms_new_framebuffer(dev_priv, bo, surface,
-				      !(dev_priv->capabilities & SVGA_CAP_3D),
-				      mode_cmd);
+	vfb = vmw_kms_new_framebuffer(dev_priv, &uo, mode_cmd);
 	if (IS_ERR(vfb)) {
 		ret = PTR_ERR(vfb);
 		goto err_out;
 	}
 
 err_out:
-	/* vmw_user_lookup_handle takes one ref so does new_fb */
-	if (bo)
-		vmw_user_bo_unref(&bo);
-	if (surface)
-		vmw_surface_unreference(&surface);
+	/* vmw_user_object_lookup takes one ref so does new_fb */
+	vmw_user_object_unref(&uo);
 
 	if (ret) {
 		DRM_ERROR("failed to create vmw_framebuffer: %i\n", ret);
@@ -2149,13 +2008,12 @@
 	return 0;
 }
 
+static
 bool vmw_kms_validate_mode_vram(struct vmw_private *dev_priv,
-				uint32_t pitch,
-				uint32_t height)
+				u64 pitch,
+				u64 height)
 {
-	return ((u64) pitch * (u64) height) < (u64)
-		((dev_priv->active_display_unit == vmw_du_screen_target) ?
-		 dev_priv->max_primary_mem : dev_priv->vram_size);
+	return (pitch * height) < (u64)dev_priv->vram_size;
 }
 
 /**
@@ -2278,107 +2136,6 @@
 		connector_status_connected : connector_status_disconnected);
 }
 
-static struct drm_display_mode vmw_kms_connector_builtin[] = {
-	/* 640x480@60Hz */
-	{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
-		   752, 800, 0, 480, 489, 492, 525, 0,
-		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
-	/* 800x600@60Hz */
-	{ DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840,
-		   968, 1056, 0, 600, 601, 605, 628, 0,
-		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1024x768@60Hz */
-	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
-		   1184, 1344, 0, 768, 771, 777, 806, 0,
-		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
-	/* 1152x864@75Hz */
-	{ DRM_MODE("1152x864", DRM_MODE_TYPE_DRIVER, 108000, 1152, 1216,
-		   1344, 1600, 0, 864, 865, 868, 900, 0,
-		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1280x720@60Hz */
-	{ DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74500, 1280, 1344,
-		   1472, 1664, 0, 720, 723, 728, 748, 0,
-		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1280x768@60Hz */
-	{ DRM_MODE("1280x768", DRM_MODE_TYPE_DRIVER, 79500, 1280, 1344,
-		   1472, 1664, 0, 768, 771, 778, 798, 0,
-		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1280x800@60Hz */
-	{ DRM_MODE("1280x800", DRM_MODE_TYPE_DRIVER, 83500, 1280, 1352,
-		   1480, 1680, 0, 800, 803, 809, 831, 0,
-		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
-	/* 1280x960@60Hz */
-	{ DRM_MODE("1280x960", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1376,
-		   1488, 1800, 0, 960, 961, 964, 1000, 0,
-		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1280x1024@60Hz */
-	{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 108000, 1280, 1328,
-		   1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
-		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1360x768@60Hz */
-	{ DRM_MODE("1360x768", DRM_MODE_TYPE_DRIVER, 85500, 1360, 1424,
-		   1536, 1792, 0, 768, 771, 777, 795, 0,
-		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1440x1050@60Hz */
-	{ DRM_MODE("1400x1050", DRM_MODE_TYPE_DRIVER, 121750, 1400, 1488,
-		   1632, 1864, 0, 1050, 1053, 1057, 1089, 0,
-		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1440x900@60Hz */
-	{ DRM_MODE("1440x900", DRM_MODE_TYPE_DRIVER, 106500, 1440, 1520,
-		   1672, 1904, 0, 900, 903, 909, 934, 0,
-		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1600x1200@60Hz */
-	{ DRM_MODE("1600x1200", DRM_MODE_TYPE_DRIVER, 162000, 1600, 1664,
-		   1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
-		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1680x1050@60Hz */
-	{ DRM_MODE("1680x1050", DRM_MODE_TYPE_DRIVER, 146250, 1680, 1784,
-		   1960, 2240, 0, 1050, 1053, 1059, 1089, 0,
-		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1792x1344@60Hz */
-	{ DRM_MODE("1792x1344", DRM_MODE_TYPE_DRIVER, 204750, 1792, 1920,
-		   2120, 2448, 0, 1344, 1345, 1348, 1394, 0,
-		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1853x1392@60Hz */
-	{ DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952,
-		   2176, 2528, 0, 1392, 1393, 1396, 1439, 0,
-		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1920x1080@60Hz */
-	{ DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 173000, 1920, 2048,
-		   2248, 2576, 0, 1080, 1083, 1088, 1120, 0,
-		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1920x1200@60Hz */
-	{ DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056,
-		   2256, 2592, 0, 1200, 1203, 1209, 1245, 0,
-		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 1920x1440@60Hz */
-	{ DRM_MODE("1920x1440", DRM_MODE_TYPE_DRIVER, 234000, 1920, 2048,
-		   2256, 2600, 0, 1440, 1441, 1444, 1500, 0,
-		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 2560x1440@60Hz */
-	{ DRM_MODE("2560x1440", DRM_MODE_TYPE_DRIVER, 241500, 2560, 2608,
-		   2640, 2720, 0, 1440, 1443, 1448, 1481, 0,
-		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
-	/* 2560x1600@60Hz */
-	{ DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752,
-		   3032, 3504, 0, 1600, 1603, 1609, 1658, 0,
-		   DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) },
-	/* 2880x1800@60Hz */
-	{ DRM_MODE("2880x1800", DRM_MODE_TYPE_DRIVER, 337500, 2880, 2928,
-		   2960, 3040, 0, 1800, 1803, 1809, 1852, 0,
-		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
-	/* 3840x2160@60Hz */
-	{ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 533000, 3840, 3888,
-		   3920, 4000, 0, 2160, 2163, 2168, 2222, 0,
-		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
-	/* 3840x2400@60Hz */
-	{ DRM_MODE("3840x2400", DRM_MODE_TYPE_DRIVER, 592250, 3840, 3888,
-		   3920, 4000, 0, 2400, 2403, 2409, 2469, 0,
-		   DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) },
-	/* Terminate */
-	{ DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) },
-};
-
 /**
  * vmw_guess_mode_timing - Provide fake timings for a
  * 60Hz vrefresh mode.
@@ -2400,88 +2157,6 @@
 }
 
 
-int vmw_du_connector_fill_modes(struct drm_connector *connector,
-				uint32_t max_width, uint32_t max_height)
-{
-	struct vmw_display_unit *du = vmw_connector_to_du(connector);
-	struct drm_device *dev = connector->dev;
-	struct vmw_private *dev_priv = vmw_priv(dev);
-	struct drm_display_mode *mode = NULL;
-	struct drm_display_mode *bmode;
-	struct drm_display_mode prefmode = { DRM_MODE("preferred",
-		DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
-		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-		DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
-	};
-	int i;
-	u32 assumed_bpp = 4;
-
-	if (dev_priv->assume_16bpp)
-		assumed_bpp = 2;
-
-	max_width  = min(max_width,  dev_priv->texture_max_width);
-	max_height = min(max_height, dev_priv->texture_max_height);
-
-	/*
-	 * For STDU extra limit for a mode on SVGA_REG_SCREENTARGET_MAX_WIDTH/
-	 * HEIGHT registers.
-	 */
-	if (dev_priv->active_display_unit == vmw_du_screen_target) {
-		max_width  = min(max_width,  dev_priv->stdu_max_width);
-		max_height = min(max_height, dev_priv->stdu_max_height);
-	}
-
-	/* Add preferred mode */
-	mode = drm_mode_duplicate(dev, &prefmode);
-	if (!mode)
-		return 0;
-	mode->hdisplay = du->pref_width;
-	mode->vdisplay = du->pref_height;
-	vmw_guess_mode_timing(mode);
-	drm_mode_set_name(mode);
-
-	if (vmw_kms_validate_mode_vram(dev_priv,
-					mode->hdisplay * assumed_bpp,
-					mode->vdisplay)) {
-		drm_mode_probed_add(connector, mode);
-	} else {
-		drm_mode_destroy(dev, mode);
-		mode = NULL;
-	}
-
-	if (du->pref_mode) {
-		list_del_init(&du->pref_mode->head);
-		drm_mode_destroy(dev, du->pref_mode);
-	}
-
-	/* mode might be null here, this is intended */
-	du->pref_mode = mode;
-
-	for (i = 0; vmw_kms_connector_builtin[i].type != 0; i++) {
-		bmode = &vmw_kms_connector_builtin[i];
-		if (bmode->hdisplay > max_width ||
-		    bmode->vdisplay > max_height)
-			continue;
-
-		if (!vmw_kms_validate_mode_vram(dev_priv,
-						bmode->hdisplay * assumed_bpp,
-						bmode->vdisplay))
-			continue;
-
-		mode = drm_mode_duplicate(dev, bmode);
-		if (!mode)
-			return 0;
-
-		drm_mode_probed_add(connector, mode);
-	}
-
-	drm_connector_list_update(connector);
-	/* Move the prefered mode first, help apps pick the right mode. */
-	drm_mode_sort(&connector->modes);
-
-	return 1;
-}
-
 /**
  * vmw_kms_update_layout_ioctl - Handler for DRM_VMW_UPDATE_LAYOUT ioctl
  * @dev: drm device for the ioctl
@@ -2508,7 +2183,7 @@
 	struct drm_mode_config *mode_config = &dev->mode_config;
 	struct drm_vmw_update_layout_arg *arg =
 		(struct drm_vmw_update_layout_arg *)data;
-	void __user *user_rects;
+	const void __user *user_rects;
 	struct drm_vmw_rect *rects;
 	struct drm_rect *drm_rects;
 	unsigned rects_size;
@@ -2520,6 +2195,8 @@
 					    VMWGFX_MIN_INITIAL_HEIGHT};
 		vmw_du_update_layout(dev_priv, 1, &def_rect);
 		return 0;
+	} else if (arg->num_outputs > VMWGFX_NUM_DISPLAY_UNITS) {
+		return -E2BIG;
 	}
 
 	rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect);
@@ -2747,72 +2424,6 @@
 }
 
 /**
- * vmw_kms_update_proxy - Helper function to update a proxy surface from
- * its backing MOB.
- *
- * @res: Pointer to the surface resource
- * @clips: Clip rects in framebuffer (surface) space.
- * @num_clips: Number of clips in @clips.
- * @increment: Integer with which to increment the clip counter when looping.
- * Used to skip a predetermined number of clip rects.
- *
- * This function makes sure the proxy surface is updated from its backing MOB
- * using the region given by @clips. The surface resource @res and its backing
- * MOB needs to be reserved and validated on call.
- */
-int vmw_kms_update_proxy(struct vmw_resource *res,
-			 const struct drm_clip_rect *clips,
-			 unsigned num_clips,
-			 int increment)
-{
-	struct vmw_private *dev_priv = res->dev_priv;
-	struct drm_vmw_size *size = &vmw_res_to_srf(res)->metadata.base_size;
-	struct {
-		SVGA3dCmdHeader header;
-		SVGA3dCmdUpdateGBImage body;
-	} *cmd;
-	SVGA3dBox *box;
-	size_t copy_size = 0;
-	int i;
-
-	if (!clips)
-		return 0;
-
-	cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd) * num_clips);
-	if (!cmd)
-		return -ENOMEM;
-
-	for (i = 0; i < num_clips; ++i, clips += increment, ++cmd) {
-		box = &cmd->body.box;
-
-		cmd->header.id = SVGA_3D_CMD_UPDATE_GB_IMAGE;
-		cmd->header.size = sizeof(cmd->body);
-		cmd->body.image.sid = res->id;
-		cmd->body.image.face = 0;
-		cmd->body.image.mipmap = 0;
-
-		if (clips->x1 > size->width || clips->x2 > size->width ||
-		    clips->y1 > size->height || clips->y2 > size->height) {
-			DRM_ERROR("Invalid clips outsize of framebuffer.\n");
-			return -EINVAL;
-		}
-
-		box->x = clips->x1;
-		box->y = clips->y1;
-		box->z = 0;
-		box->w = clips->x2 - clips->x1;
-		box->h = clips->y2 - clips->y1;
-		box->d = 1;
-
-		copy_size += sizeof(*cmd);
-	}
-
-	vmw_cmd_commit(dev_priv, copy_size);
-
-	return 0;
-}
-
-/**
  * vmw_kms_create_implicit_placement_property - Set up the implicit placement
  * property.
  *
@@ -2946,8 +2557,9 @@
 	} else {
 		struct vmw_framebuffer_surface *vfbs =
 			container_of(update->vfb, typeof(*vfbs), base);
+		struct vmw_surface *surf = vmw_user_object_surface(&vfbs->uo);
 
-		ret = vmw_validation_add_resource(&val_ctx, &vfbs->surface->res,
+		ret = vmw_validation_add_resource(&val_ctx, &surf->res,
 						  0, VMW_RES_DIRTY_NONE, NULL,
 						  NULL);
 	}
@@ -3022,3 +2634,174 @@
 	vmw_validation_unref_lists(&val_ctx);
 	return ret;
 }
+
+/**
+ * vmw_connector_mode_valid - implements drm_connector_helper_funcs.mode_valid callback
+ *
+ * @connector: the drm connector, part of a DU container
+ * @mode: drm mode to check
+ *
+ * Returns MODE_OK on success, or a drm_mode_status error code.
+ */
+enum drm_mode_status vmw_connector_mode_valid(struct drm_connector *connector,
+					      struct drm_display_mode *mode)
+{
+	enum drm_mode_status ret;
+	struct drm_device *dev = connector->dev;
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	u32 assumed_cpp = 4;
+
+	if (dev_priv->assume_16bpp)
+		assumed_cpp = 2;
+
+	ret = drm_mode_validate_size(mode, dev_priv->texture_max_width,
+				     dev_priv->texture_max_height);
+	if (ret != MODE_OK)
+		return ret;
+
+	if (!vmw_kms_validate_mode_vram(dev_priv,
+					mode->hdisplay * assumed_cpp,
+					mode->vdisplay))
+		return MODE_MEM;
+
+	return MODE_OK;
+}
+
+/**
+ * vmw_connector_get_modes - implements drm_connector_helper_funcs.get_modes callback
+ *
+ * @connector: the drm connector, part of a DU container
+ *
+ * Returns the number of added modes.
+ */
+int vmw_connector_get_modes(struct drm_connector *connector)
+{
+	struct vmw_display_unit *du = vmw_connector_to_du(connector);
+	struct drm_device *dev = connector->dev;
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct drm_display_mode *mode = NULL;
+	struct drm_display_mode prefmode = { DRM_MODE("preferred",
+		DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
+	};
+	u32 max_width;
+	u32 max_height;
+	u32 num_modes;
+
+	/* Add preferred mode */
+	mode = drm_mode_duplicate(dev, &prefmode);
+	if (!mode)
+		return 0;
+
+	mode->hdisplay = du->pref_width;
+	mode->vdisplay = du->pref_height;
+	vmw_guess_mode_timing(mode);
+	drm_mode_set_name(mode);
+
+	drm_mode_probed_add(connector, mode);
+	drm_dbg_kms(dev, "preferred mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
+
+	/* Probe connector for all modes not exceeding our geom limits */
+	max_width  = dev_priv->texture_max_width;
+	max_height = dev_priv->texture_max_height;
+
+	if (dev_priv->active_display_unit == vmw_du_screen_target) {
+		max_width  = min(dev_priv->stdu_max_width,  max_width);
+		max_height = min(dev_priv->stdu_max_height, max_height);
+	}
+
+	num_modes = 1 + drm_add_modes_noedid(connector, max_width, max_height);
+
+	return num_modes;
+}
+
+struct vmw_user_object *vmw_user_object_ref(struct vmw_user_object *uo)
+{
+	if (uo->buffer)
+		vmw_user_bo_ref(uo->buffer);
+	else if (uo->surface)
+		vmw_surface_reference(uo->surface);
+	return uo;
+}
+
+void vmw_user_object_unref(struct vmw_user_object *uo)
+{
+	if (uo->buffer)
+		vmw_user_bo_unref(&uo->buffer);
+	else if (uo->surface)
+		vmw_surface_unreference(&uo->surface);
+}
+
+struct vmw_bo *
+vmw_user_object_buffer(struct vmw_user_object *uo)
+{
+	if (uo->buffer)
+		return uo->buffer;
+	else if (uo->surface)
+		return uo->surface->res.guest_memory_bo;
+	return NULL;
+}
+
+struct vmw_surface *
+vmw_user_object_surface(struct vmw_user_object *uo)
+{
+	if (uo->buffer)
+		return uo->buffer->dumb_surface;
+	return uo->surface;
+}
+
+void *vmw_user_object_map(struct vmw_user_object *uo)
+{
+	struct vmw_bo *bo = vmw_user_object_buffer(uo);
+
+	WARN_ON(!bo);
+	return vmw_bo_map_and_cache(bo);
+}
+
+void *vmw_user_object_map_size(struct vmw_user_object *uo, size_t size)
+{
+	struct vmw_bo *bo = vmw_user_object_buffer(uo);
+
+	WARN_ON(!bo);
+	return vmw_bo_map_and_cache_size(bo, size);
+}
+
+void vmw_user_object_unmap(struct vmw_user_object *uo)
+{
+	struct vmw_bo *bo = vmw_user_object_buffer(uo);
+	int ret;
+
+	WARN_ON(!bo);
+
+	/* Fence the mob creation so we are guarateed to have the mob */
+	ret = ttm_bo_reserve(&bo->tbo, false, false, NULL);
+	if (ret != 0)
+		return;
+
+	vmw_bo_unmap(bo);
+	vmw_bo_pin_reserved(bo, false);
+
+	ttm_bo_unreserve(&bo->tbo);
+}
+
+bool vmw_user_object_is_mapped(struct vmw_user_object *uo)
+{
+	struct vmw_bo *bo;
+
+	if (!uo || vmw_user_object_is_null(uo))
+		return false;
+
+	bo = vmw_user_object_buffer(uo);
+
+	if (WARN_ON(!bo))
+		return false;
+
+	WARN_ON(bo->map.bo && !bo->map.virtual);
+	return bo->map.virtual;
+}
+
+bool vmw_user_object_is_null(struct vmw_user_object *uo)
+{
+	return !uo->buffer && !uo->surface;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -1,7 +1,8 @@
 /* SPDX-License-Identifier: GPL-2.0 OR MIT */
 /**************************************************************************
  *
- * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
+ * Copyright (c) 2009-2024 Broadcom. All Rights Reserved. The term
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -198,9 +199,6 @@
 	s32 unit_y2;
 };
 
-#define VMWGFX_NUM_DISPLAY_UNITS 8
-
-
 #define vmw_framebuffer_to_vfb(x) \
 	container_of(x, struct vmw_framebuffer, base)
 #define vmw_framebuffer_to_vfbs(x) \
@@ -217,25 +215,13 @@
 struct vmw_framebuffer {
 	struct drm_framebuffer base;
 	bool bo;
-	uint32_t user_handle;
-};
-
-/*
- * Clip rectangle
- */
-struct vmw_clip_rect {
-	int x1, x2, y1, y2;
 };
 
 struct vmw_framebuffer_surface {
 	struct vmw_framebuffer base;
-	struct vmw_surface *surface;
-	struct vmw_bo *buffer;
-	struct list_head head;
-	bool is_bo_proxy;  /* true if this is proxy surface for DMA buf */
+	struct vmw_user_object uo;
 };
 
-
 struct vmw_framebuffer_bo {
 	struct vmw_framebuffer base;
 	struct vmw_bo *buffer;
@@ -243,10 +229,10 @@
 
 
 static const uint32_t __maybe_unused vmw_primary_plane_formats[] = {
-	DRM_FORMAT_XRGB1555,
-	DRM_FORMAT_RGB565,
 	DRM_FORMAT_XRGB8888,
 	DRM_FORMAT_ARGB8888,
+	DRM_FORMAT_RGB565,
+	DRM_FORMAT_XRGB1555,
 };
 
 static const uint32_t __maybe_unused vmw_cursor_plane_formats[] = {
@@ -287,8 +273,7 @@
  */
 struct vmw_plane_state {
 	struct drm_plane_state base;
-	struct vmw_surface *surf;
-	struct vmw_bo *bo;
+	struct vmw_user_object uo;
 
 	int content_fb_type;
 	unsigned long bo_size;
@@ -359,7 +344,6 @@
 	struct vmw_cursor_plane cursor;
 
 	struct vmw_surface *cursor_surface;
-	struct vmw_bo *cursor_bo;
 	size_t cursor_age;
 
 	int cursor_x;
@@ -378,7 +362,6 @@
 	unsigned pref_width;
 	unsigned pref_height;
 	bool pref_active;
-	struct drm_display_mode *pref_mode;
 
 	/*
 	 * Gui positioning
@@ -390,11 +373,6 @@
 	int set_gui_y;
 };
 
-struct vmw_validation_ctx {
-	struct vmw_resource *res;
-	struct vmw_bo *buf;
-};
-
 #define vmw_crtc_to_du(x) \
 	container_of(x, struct vmw_display_unit, crtc)
 #define vmw_connector_to_du(x) \
@@ -428,8 +406,6 @@
 void vmw_du_connector_restore(struct drm_connector *connector);
 enum drm_connector_status
 vmw_du_connector_detect(struct drm_connector *connector, bool force);
-int vmw_du_connector_fill_modes(struct drm_connector *connector,
-				uint32_t max_width, uint32_t max_height);
 int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
 			 struct vmw_framebuffer *framebuffer,
 			 const struct drm_clip_rect *clips,
@@ -438,6 +414,9 @@
 			 int num_clips,
 			 int increment,
 			 struct vmw_kms_dirty *dirty);
+enum drm_mode_status vmw_connector_mode_valid(struct drm_connector *connector,
+					      struct drm_display_mode *mode);
+int vmw_connector_get_modes(struct drm_connector *connector);
 
 void vmw_kms_helper_validation_finish(struct vmw_private *dev_priv,
 				      struct drm_file *file_priv,
@@ -453,9 +432,7 @@
 		     uint32_t num_clips);
 struct vmw_framebuffer *
 vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
-			struct vmw_bo *bo,
-			struct vmw_surface *surface,
-			bool only_2d,
+			struct vmw_user_object *uo,
 			const struct drm_mode_fb_cmd2 *mode_cmd);
 void vmw_guess_mode_timing(struct drm_display_mode *mode);
 void vmw_kms_update_implicit_fb(struct vmw_private *dev_priv);
@@ -482,8 +459,7 @@
 struct drm_plane_state *vmw_du_plane_duplicate_state(struct drm_plane *plane);
 void vmw_du_plane_destroy_state(struct drm_plane *plane,
 				struct drm_plane_state *state);
-void vmw_du_plane_unpin_surf(struct vmw_plane_state *vps,
-			     bool unreference);
+void vmw_du_plane_unpin_surf(struct vmw_plane_state *vps);
 
 int vmw_du_crtc_atomic_check(struct drm_crtc *crtc,
 			     struct drm_atomic_state *state);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /**************************************************************************
  *
- * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
+ * Copyright (c) 2009-2024 Broadcom. All Rights Reserved. The term
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -146,8 +147,9 @@
 	struct vmw_bo *buf;
 	int ret;
 
-	buf = vfb->bo ?  vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
-		vmw_framebuffer_to_vfbs(&vfb->base)->surface->res.guest_memory_bo;
+	buf = vfb->bo ?
+		vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
+		vmw_user_object_buffer(&vmw_framebuffer_to_vfbs(&vfb->base)->uo);
 
 	if (!buf)
 		return 0;
@@ -168,8 +170,10 @@
 	struct vmw_private *dev_priv = vmw_priv(vfb->base.dev);
 	struct vmw_bo *buf;
 
-	buf = vfb->bo ?  vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
-		vmw_framebuffer_to_vfbs(&vfb->base)->surface->res.guest_memory_bo;
+	buf = vfb->bo ?
+		vmw_framebuffer_to_vfbd(&vfb->base)->buffer :
+		vmw_user_object_buffer(&vmw_framebuffer_to_vfbs(&vfb->base)->uo);
+
 
 	if (WARN_ON(!buf))
 		return 0;
@@ -304,7 +308,7 @@
 static const struct drm_connector_funcs vmw_legacy_connector_funcs = {
 	.dpms = vmw_du_connector_dpms,
 	.detect = vmw_du_connector_detect,
-	.fill_modes = vmw_du_connector_fill_modes,
+	.fill_modes = drm_helper_probe_single_connector_modes,
 	.destroy = vmw_ldu_connector_destroy,
 	.reset = vmw_du_connector_reset,
 	.atomic_duplicate_state = vmw_du_connector_duplicate_state,
@@ -313,6 +317,8 @@
 
 static const struct
 drm_connector_helper_funcs vmw_ldu_connector_helper_funcs = {
+	.get_modes = vmw_connector_get_modes,
+	.mode_valid = vmw_connector_mode_valid
 };
 
 static int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv,
@@ -449,7 +455,6 @@
 	ldu->base.pref_active = (unit == 0);
 	ldu->base.pref_width = dev_priv->initial_width;
 	ldu->base.pref_height = dev_priv->initial_height;
-	ldu->base.pref_mode = NULL;
 
 	/*
 	 * Remove this after enabling atomic because property values can
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
@@ -48,8 +48,6 @@
 
 #define RETRIES                 3
 
-#define VMW_HYPERVISOR_MAGIC    0x564D5868
-
 #define VMW_PORT_CMD_MSG        30
 #define VMW_PORT_CMD_HB_MSG     0
 #define VMW_PORT_CMD_OPEN_CHANNEL  (MSG_TYPE_OPEN << 16 | VMW_PORT_CMD_MSG)
@@ -104,20 +102,18 @@
  */
 static int vmw_open_channel(struct rpc_channel *channel, unsigned int protocol)
 {
-	unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
+	u32 ecx, edx, esi, edi;
 
-	VMW_PORT(VMW_PORT_CMD_OPEN_CHANNEL,
-		(protocol | GUESTMSG_FLAG_COOKIE), si, di,
-		0,
-		VMW_HYPERVISOR_MAGIC,
-		eax, ebx, ecx, edx, si, di);
+	vmware_hypercall6(VMW_PORT_CMD_OPEN_CHANNEL,
+			  (protocol | GUESTMSG_FLAG_COOKIE), 0,
+			  &ecx, &edx, &esi, &edi);
 
 	if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
 		return -EINVAL;
 
 	channel->channel_id  = HIGH_WORD(edx);
-	channel->cookie_high = si;
-	channel->cookie_low  = di;
+	channel->cookie_high = esi;
+	channel->cookie_low  = edi;
 
 	return 0;
 }
@@ -133,17 +129,13 @@
  */
 static int vmw_close_channel(struct rpc_channel *channel)
 {
-	unsigned long eax, ebx, ecx, edx, si, di;
+	u32 ecx;
 
-	/* Set up additional parameters */
-	si  = channel->cookie_high;
-	di  = channel->cookie_low;
-
-	VMW_PORT(VMW_PORT_CMD_CLOSE_CHANNEL,
-		0, si, di,
-		channel->channel_id << 16,
-		VMW_HYPERVISOR_MAGIC,
-		eax, ebx, ecx, edx, si, di);
+	vmware_hypercall5(VMW_PORT_CMD_CLOSE_CHANNEL,
+			  0, channel->channel_id << 16,
+			  channel->cookie_high,
+			  channel->cookie_low,
+			  &ecx);
 
 	if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
 		return -EINVAL;
@@ -163,24 +155,18 @@
 static unsigned long vmw_port_hb_out(struct rpc_channel *channel,
 				     const char *msg, bool hb)
 {
-	unsigned long si, di, eax, ebx, ecx, edx;
+	u32 ebx, ecx;
 	unsigned long msg_len = strlen(msg);
 
 	/* HB port can't access encrypted memory. */
 	if (hb && !cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
-		unsigned long bp = channel->cookie_high;
-		u32 channel_id = (channel->channel_id << 16);
-
-		si = (uintptr_t) msg;
-		di = channel->cookie_low;
-
-		VMW_PORT_HB_OUT(
+		vmware_hypercall_hb_out(
 			(MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
-			msg_len, si, di,
-			VMWARE_HYPERVISOR_HB | channel_id |
-			VMWARE_HYPERVISOR_OUT,
-			VMW_HYPERVISOR_MAGIC, bp,
-			eax, ebx, ecx, edx, si, di);
+			msg_len,
+			channel->channel_id << 16,
+			(uintptr_t) msg, channel->cookie_low,
+			channel->cookie_high,
+			&ebx);
 
 		return ebx;
 	}
@@ -194,14 +180,13 @@
 		memcpy(&word, msg, bytes);
 		msg_len -= bytes;
 		msg += bytes;
-		si = channel->cookie_high;
-		di = channel->cookie_low;
 
-		VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_SENDPAYLOAD << 16),
-			 word, si, di,
-			 channel->channel_id << 16,
-			 VMW_HYPERVISOR_MAGIC,
-			 eax, ebx, ecx, edx, si, di);
+		vmware_hypercall5(VMW_PORT_CMD_MSG |
+				  (MSG_TYPE_SENDPAYLOAD << 16),
+				  word, channel->channel_id << 16,
+				  channel->cookie_high,
+				  channel->cookie_low,
+				  &ecx);
 	}
 
 	return ecx;
@@ -220,22 +205,17 @@
 static unsigned long vmw_port_hb_in(struct rpc_channel *channel, char *reply,
 				    unsigned long reply_len, bool hb)
 {
-	unsigned long si, di, eax, ebx, ecx, edx;
+	u32 ebx, ecx, edx;
 
 	/* HB port can't access encrypted memory */
 	if (hb && !cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
-		unsigned long bp = channel->cookie_low;
-		u32 channel_id = (channel->channel_id << 16);
-
-		si = channel->cookie_high;
-		di = (uintptr_t) reply;
-
-		VMW_PORT_HB_IN(
+		vmware_hypercall_hb_in(
 			(MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
-			reply_len, si, di,
-			VMWARE_HYPERVISOR_HB | channel_id,
-			VMW_HYPERVISOR_MAGIC, bp,
-			eax, ebx, ecx, edx, si, di);
+			reply_len,
+			channel->channel_id << 16,
+			channel->cookie_high,
+			(uintptr_t) reply, channel->cookie_low,
+			&ebx);
 
 		return ebx;
 	}
@@ -245,14 +225,13 @@
 	while (reply_len) {
 		unsigned int bytes = min_t(unsigned long, reply_len, 4);
 
-		si = channel->cookie_high;
-		di = channel->cookie_low;
-
-		VMW_PORT(VMW_PORT_CMD_MSG | (MSG_TYPE_RECVPAYLOAD << 16),
-			 MESSAGE_STATUS_SUCCESS, si, di,
-			 channel->channel_id << 16,
-			 VMW_HYPERVISOR_MAGIC,
-			 eax, ebx, ecx, edx, si, di);
+		vmware_hypercall7(VMW_PORT_CMD_MSG |
+				  (MSG_TYPE_RECVPAYLOAD << 16),
+				  MESSAGE_STATUS_SUCCESS,
+				  channel->channel_id << 16,
+				  channel->cookie_high,
+				  channel->cookie_low,
+				  &ebx, &ecx, &edx);
 
 		if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0)
 			break;
@@ -276,22 +255,18 @@
  */
 static int vmw_send_msg(struct rpc_channel *channel, const char *msg)
 {
-	unsigned long eax, ebx, ecx, edx, si, di;
+	u32 ebx, ecx;
 	size_t msg_len = strlen(msg);
 	int retries = 0;
 
 	while (retries < RETRIES) {
 		retries++;
 
-		/* Set up additional parameters */
-		si  = channel->cookie_high;
-		di  = channel->cookie_low;
-
-		VMW_PORT(VMW_PORT_CMD_SENDSIZE,
-			msg_len, si, di,
-			channel->channel_id << 16,
-			VMW_HYPERVISOR_MAGIC,
-			eax, ebx, ecx, edx, si, di);
+		vmware_hypercall5(VMW_PORT_CMD_SENDSIZE,
+				  msg_len, channel->channel_id << 16,
+				  channel->cookie_high,
+				  channel->cookie_low,
+				  &ecx);
 
 		if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
 			/* Expected success. Give up. */
@@ -329,7 +304,7 @@
 static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
 			size_t *msg_len)
 {
-	unsigned long eax, ebx, ecx, edx, si, di;
+	u32 ebx, ecx, edx;
 	char *reply;
 	size_t reply_len;
 	int retries = 0;
@@ -341,15 +316,11 @@
 	while (retries < RETRIES) {
 		retries++;
 
-		/* Set up additional parameters */
-		si  = channel->cookie_high;
-		di  = channel->cookie_low;
-
-		VMW_PORT(VMW_PORT_CMD_RECVSIZE,
-			0, si, di,
-			channel->channel_id << 16,
-			VMW_HYPERVISOR_MAGIC,
-			eax, ebx, ecx, edx, si, di);
+		vmware_hypercall7(VMW_PORT_CMD_RECVSIZE,
+				  0, channel->channel_id << 16,
+				  channel->cookie_high,
+				  channel->cookie_low,
+				  &ebx, &ecx, &edx);
 
 		if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
 			DRM_ERROR("Failed to get reply size for host message.\n");
@@ -384,16 +355,12 @@
 
 		reply[reply_len] = '\0';
 
-
-		/* Ack buffer */
-		si  = channel->cookie_high;
-		di  = channel->cookie_low;
-
-		VMW_PORT(VMW_PORT_CMD_RECVSTATUS,
-			MESSAGE_STATUS_SUCCESS, si, di,
-			channel->channel_id << 16,
-			VMW_HYPERVISOR_MAGIC,
-			eax, ebx, ecx, edx, si, di);
+		vmware_hypercall5(VMW_PORT_CMD_RECVSTATUS,
+				  MESSAGE_STATUS_SUCCESS,
+				  channel->channel_id << 16,
+				  channel->cookie_high,
+				  channel->cookie_low,
+				  &ecx);
 
 		if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
 			kfree(reply);
@@ -652,13 +619,7 @@
  */
 static inline void hypervisor_ppn_reset_all(void)
 {
-	unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
-
-	VMW_PORT(VMW_PORT_CMD_MKSGS_RESET,
-		0, si, di,
-		0,
-		VMW_HYPERVISOR_MAGIC,
-		eax, ebx, ecx, edx, si, di);
+	vmware_hypercall1(VMW_PORT_CMD_MKSGS_RESET, 0);
 }
 
 /**
@@ -669,13 +630,7 @@
  */
 static inline void hypervisor_ppn_add(PPN64 pfn)
 {
-	unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
-
-	VMW_PORT(VMW_PORT_CMD_MKSGS_ADD_PPN,
-		(unsigned long)pfn, si, di,
-		0,
-		VMW_HYPERVISOR_MAGIC,
-		eax, ebx, ecx, edx, si, di);
+	vmware_hypercall1(VMW_PORT_CMD_MKSGS_ADD_PPN, (unsigned long)pfn);
 }
 
 /**
@@ -686,13 +641,7 @@
  */
 static inline void hypervisor_ppn_remove(PPN64 pfn)
 {
-	unsigned long eax, ebx, ecx, edx, si = 0, di = 0;
-
-	VMW_PORT(VMW_PORT_CMD_MKSGS_REMOVE_PPN,
-		(unsigned long)pfn, si, di,
-		0,
-		VMW_HYPERVISOR_MAGIC,
-		eax, ebx, ecx, edx, si, di);
+	vmware_hypercall1(VMW_PORT_CMD_MKSGS_REMOVE_PPN, (unsigned long)pfn);
 }
 
 #if IS_ENABLED(CONFIG_DRM_VMWGFX_MKSSTATS)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_msg_arm64.h
@@ -34,6 +34,8 @@
 #define VMWARE_HYPERVISOR_HB  BIT(0)
 #define VMWARE_HYPERVISOR_OUT BIT(1)
 
+#define VMWARE_HYPERVISOR_MAGIC	0x564D5868
+
 #define X86_IO_MAGIC 0x86
 
 #define X86_IO_W7_SIZE_SHIFT 0
@@ -45,86 +47,158 @@
 #define X86_IO_W7_IMM_SHIFT  5
 #define X86_IO_W7_IMM_MASK  (0xff << X86_IO_W7_IMM_SHIFT)
 
-static inline void vmw_port(unsigned long cmd, unsigned long in_ebx,
-			    unsigned long in_si, unsigned long in_di,
-			    unsigned long flags, unsigned long magic,
-			    unsigned long *eax, unsigned long *ebx,
-			    unsigned long *ecx, unsigned long *edx,
-			    unsigned long *si, unsigned long *di)
+static inline
+unsigned long vmware_hypercall1(unsigned long cmd, unsigned long in1)
+{
+	register u64 x0 asm("x0") = VMWARE_HYPERVISOR_MAGIC;
+	register u64 x1 asm("x1") = in1;
+	register u64 x2 asm("x2") = cmd;
+	register u64 x3 asm("x3") = VMWARE_HYPERVISOR_PORT;
+	register u64 x7 asm("x7") = ((u64)X86_IO_MAGIC << 32) |
+				    X86_IO_W7_WITH |
+				    X86_IO_W7_DIR |
+				    (2 << X86_IO_W7_SIZE_SHIFT);
+
+	asm_inline volatile (
+		"mrs xzr, mdccsr_el0; "
+		: "+r" (x0)
+		: "r" (x1), "r" (x2), "r" (x3), "r" (x7)
+		: "memory");
+
+	return x0;
+}
+
+static inline
+unsigned long vmware_hypercall5(unsigned long cmd, unsigned long in1,
+				unsigned long in3, unsigned long in4,
+				unsigned long in5, u32 *out2)
+{
+	register u64 x0 asm("x0") = VMWARE_HYPERVISOR_MAGIC;
+	register u64 x1 asm("x1") = in1;
+	register u64 x2 asm("x2") = cmd;
+	register u64 x3 asm("x3") = in3 | VMWARE_HYPERVISOR_PORT;
+	register u64 x4 asm("x4") = in4;
+	register u64 x5 asm("x5") = in5;
+	register u64 x7 asm("x7") = ((u64)X86_IO_MAGIC << 32) |
+				    X86_IO_W7_WITH |
+				    X86_IO_W7_DIR |
+				    (2 << X86_IO_W7_SIZE_SHIFT);
+
+	asm_inline volatile (
+		"mrs xzr, mdccsr_el0; "
+		: "+r" (x0), "+r" (x2)
+		: "r" (x1), "r" (x3), "r" (x4), "r" (x5), "r" (x7)
+		: "memory");
+
+	*out2 = x2;
+	return x0;
+}
+
+static inline
+unsigned long vmware_hypercall6(unsigned long cmd, unsigned long in1,
+				unsigned long in3, u32 *out2,
+				u32 *out3, u32 *out4, u32 *out5)
 {
-	register u64 x0 asm("x0") = magic;
-	register u64 x1 asm("x1") = in_ebx;
+	register u64 x0 asm("x0") = VMWARE_HYPERVISOR_MAGIC;
+	register u64 x1 asm("x1") = in1;
 	register u64 x2 asm("x2") = cmd;
-	register u64 x3 asm("x3") = flags | VMWARE_HYPERVISOR_PORT;
-	register u64 x4 asm("x4") = in_si;
-	register u64 x5 asm("x5") = in_di;
+	register u64 x3 asm("x3") = in3 | VMWARE_HYPERVISOR_PORT;
+	register u64 x4 asm("x4");
+	register u64 x5 asm("x5");
+	register u64 x7 asm("x7") = ((u64)X86_IO_MAGIC << 32) |
+				    X86_IO_W7_WITH |
+				    X86_IO_W7_DIR |
+				    (2 << X86_IO_W7_SIZE_SHIFT);
+
+	asm_inline volatile (
+		"mrs xzr, mdccsr_el0; "
+		: "+r" (x0), "+r" (x2), "+r" (x3), "=r" (x4), "=r" (x5)
+		: "r" (x1), "r" (x7)
+		: "memory");
+
+	*out2 = x2;
+	*out3 = x3;
+	*out4 = x4;
+	*out5 = x5;
+	return x0;
+}
 
+static inline
+unsigned long vmware_hypercall7(unsigned long cmd, unsigned long in1,
+				unsigned long in3, unsigned long in4,
+				unsigned long in5, u32 *out1,
+				u32 *out2, u32 *out3)
+{
+	register u64 x0 asm("x0") = VMWARE_HYPERVISOR_MAGIC;
+	register u64 x1 asm("x1") = in1;
+	register u64 x2 asm("x2") = cmd;
+	register u64 x3 asm("x3") = in3 | VMWARE_HYPERVISOR_PORT;
+	register u64 x4 asm("x4") = in4;
+	register u64 x5 asm("x5") = in5;
 	register u64 x7 asm("x7") = ((u64)X86_IO_MAGIC << 32) |
 				    X86_IO_W7_WITH |
 				    X86_IO_W7_DIR |
 				    (2 << X86_IO_W7_SIZE_SHIFT);
 
-	asm volatile("mrs xzr, mdccsr_el0 \n\t"
-		     : "+r"(x0), "+r"(x1), "+r"(x2),
-		       "+r"(x3), "+r"(x4), "+r"(x5)
-		     : "r"(x7)
-		     :);
-	*eax = x0;
-	*ebx = x1;
-	*ecx = x2;
-	*edx = x3;
-	*si = x4;
-	*di = x5;
-}
-
-static inline void vmw_port_hb(unsigned long cmd, unsigned long in_ecx,
-			       unsigned long in_si, unsigned long in_di,
-			       unsigned long flags, unsigned long magic,
-			       unsigned long bp, u32 w7dir,
-			       unsigned long *eax, unsigned long *ebx,
-			       unsigned long *ecx, unsigned long *edx,
-			       unsigned long *si, unsigned long *di)
+	asm_inline volatile (
+		"mrs xzr, mdccsr_el0; "
+		: "+r" (x0), "+r" (x1), "+r" (x2), "+r" (x3)
+		: "r" (x4), "r" (x5), "r" (x7)
+		: "memory");
+
+	*out1 = x1;
+	*out2 = x2;
+	*out3 = x3;
+	return x0;
+}
+
+static inline
+unsigned long vmware_hypercall_hb(unsigned long cmd, unsigned long in2,
+				  unsigned long in3, unsigned long in4,
+				  unsigned long in5, unsigned long in6,
+				  u32 *out1, int dir)
 {
-	register u64 x0 asm("x0") = magic;
+	register u64 x0 asm("x0") = VMWARE_HYPERVISOR_MAGIC;
 	register u64 x1 asm("x1") = cmd;
-	register u64 x2 asm("x2") = in_ecx;
-	register u64 x3 asm("x3") = flags | VMWARE_HYPERVISOR_PORT_HB;
-	register u64 x4 asm("x4") = in_si;
-	register u64 x5 asm("x5") = in_di;
-	register u64 x6 asm("x6") = bp;
+	register u64 x2 asm("x2") = in2;
+	register u64 x3 asm("x3") = in3 | VMWARE_HYPERVISOR_PORT_HB;
+	register u64 x4 asm("x4") = in4;
+	register u64 x5 asm("x5") = in5;
+	register u64 x6 asm("x6") = in6;
 	register u64 x7 asm("x7") = ((u64)X86_IO_MAGIC << 32) |
 				    X86_IO_W7_STR |
 				    X86_IO_W7_WITH |
-				    w7dir;
+				    dir;
 
-	asm volatile("mrs xzr, mdccsr_el0 \n\t"
-		     : "+r"(x0), "+r"(x1), "+r"(x2),
-		       "+r"(x3), "+r"(x4), "+r"(x5)
-		     : "r"(x6), "r"(x7)
-		     :);
-	*eax = x0;
-	*ebx = x1;
-	*ecx = x2;
-	*edx = x3;
-	*si  = x4;
-	*di  = x5;
-}
-
-#define VMW_PORT(cmd, in_ebx, in_si, in_di, flags, magic, eax, ebx, ecx, edx,  \
-		 si, di)                                                       \
-	vmw_port(cmd, in_ebx, in_si, in_di, flags, magic, &eax, &ebx, &ecx,    \
-		 &edx, &si, &di)
-
-#define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di, flags, magic, bp, eax, ebx, \
-		        ecx, edx, si, di)                                      \
-	vmw_port_hb(cmd, in_ecx, in_si, in_di, flags, magic, bp,               \
-                    0, &eax, &ebx, &ecx, &edx, &si, &di)
-
-#define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di, flags, magic, bp, eax, ebx,  \
-		       ecx, edx, si, di)                                       \
-	vmw_port_hb(cmd, in_ecx, in_si, in_di, flags, magic, bp,               \
-		    X86_IO_W7_DIR, &eax, &ebx, &ecx, &edx, &si, &di)
+	asm_inline volatile (
+		"mrs xzr, mdccsr_el0; "
+		: "+r" (x0), "+r" (x1)
+		: "r" (x2), "r" (x3), "r" (x4), "r" (x5),
+		  "r" (x6), "r" (x7)
+		: "memory");
 
+	*out1 = x1;
+	return x0;
+}
+
+static inline
+unsigned long vmware_hypercall_hb_out(unsigned long cmd, unsigned long in2,
+				      unsigned long in3, unsigned long in4,
+				      unsigned long in5, unsigned long in6,
+				      u32 *out1)
+{
+	return vmware_hypercall_hb(cmd, in2, in3, in4, in5, in6, out1, 0);
+}
+
+static inline
+unsigned long vmware_hypercall_hb_in(unsigned long cmd, unsigned long in2,
+				     unsigned long in3, unsigned long in4,
+				     unsigned long in5, unsigned long in6,
+				     u32 *out1)
+{
+	return vmware_hypercall_hb(cmd, in2, in3, in4, in5, in6,  out1,
+				   X86_IO_W7_DIR);
+}
 #endif
 
 #endif /* _VMWGFX_MSG_ARM64_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_msg_x86.h
@@ -37,191 +37,6 @@
 
 #include <asm/vmware.h>
 
-/**
- * Hypervisor-specific bi-directional communication channel.  Should never
- * execute on bare metal hardware.  The caller must make sure to check for
- * supported hypervisor before using these macros.
- *
- * The last two parameters are both input and output and must be initialized.
- *
- * @cmd: [IN] Message Cmd
- * @in_ebx: [IN] Message Len, through EBX
- * @in_si: [IN] Input argument through SI, set to 0 if not used
- * @in_di: [IN] Input argument through DI, set ot 0 if not used
- * @flags: [IN] hypercall flags + [channel id]
- * @magic: [IN] hypervisor magic value
- * @eax: [OUT] value of EAX register
- * @ebx: [OUT] e.g. status from an HB message status command
- * @ecx: [OUT] e.g. status from a non-HB message status command
- * @edx: [OUT] e.g. channel id
- * @si:  [OUT]
- * @di:  [OUT]
- */
-#define VMW_PORT(cmd, in_ebx, in_si, in_di,	\
-                 flags, magic,		\
-                 eax, ebx, ecx, edx, si, di)	\
-({						\
-        asm volatile (VMWARE_HYPERCALL :	\
-                "=a"(eax),			\
-                "=b"(ebx),			\
-                "=c"(ecx),			\
-                "=d"(edx),			\
-                "=S"(si),			\
-                "=D"(di) :			\
-                "a"(magic),			\
-                "b"(in_ebx),			\
-                "c"(cmd),			\
-                "d"(flags),			\
-                "S"(in_si),			\
-                "D"(in_di) :			\
-                "memory");			\
-})
-
-
-/**
- * Hypervisor-specific bi-directional communication channel.  Should never
- * execute on bare metal hardware.  The caller must make sure to check for
- * supported hypervisor before using these macros.
- *
- * The last 3 parameters are both input and output and must be initialized.
- *
- * @cmd: [IN] Message Cmd
- * @in_ecx: [IN] Message Len, through ECX
- * @in_si: [IN] Input argument through SI, set to 0 if not used
- * @in_di: [IN] Input argument through DI, set to 0 if not used
- * @flags: [IN] hypercall flags + [channel id]
- * @magic: [IN] hypervisor magic value
- * @bp:  [IN]
- * @eax: [OUT] value of EAX register
- * @ebx: [OUT] e.g. status from an HB message status command
- * @ecx: [OUT] e.g. status from a non-HB message status command
- * @edx: [OUT] e.g. channel id
- * @si:  [OUT]
- * @di:  [OUT]
- */
-#ifdef __x86_64__
-
-#define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di,	\
-                        flags, magic, bp,		\
-                        eax, ebx, ecx, edx, si, di)	\
-({							\
-        asm volatile (					\
-		UNWIND_HINT_SAVE			\
-		"push %%rbp;"				\
-		UNWIND_HINT_UNDEFINED			\
-                "mov %12, %%rbp;"			\
-                VMWARE_HYPERCALL_HB_OUT			\
-                "pop %%rbp;"				\
-		UNWIND_HINT_RESTORE :			\
-                "=a"(eax),				\
-                "=b"(ebx),				\
-                "=c"(ecx),				\
-                "=d"(edx),				\
-                "=S"(si),				\
-                "=D"(di) :				\
-                "a"(magic),				\
-                "b"(cmd),				\
-                "c"(in_ecx),				\
-                "d"(flags),				\
-                "S"(in_si),				\
-                "D"(in_di),				\
-                "r"(bp) :				\
-                "memory", "cc");			\
-})
-
-
-#define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di,	\
-                       flags, magic, bp,		\
-                       eax, ebx, ecx, edx, si, di)	\
-({							\
-        asm volatile (					\
-		UNWIND_HINT_SAVE			\
-		"push %%rbp;"				\
-		UNWIND_HINT_UNDEFINED			\
-                "mov %12, %%rbp;"			\
-                VMWARE_HYPERCALL_HB_IN			\
-                "pop %%rbp;"				\
-		UNWIND_HINT_RESTORE :			\
-                "=a"(eax),				\
-                "=b"(ebx),				\
-                "=c"(ecx),				\
-                "=d"(edx),				\
-                "=S"(si),				\
-                "=D"(di) :				\
-                "a"(magic),				\
-                "b"(cmd),				\
-                "c"(in_ecx),				\
-                "d"(flags),				\
-                "S"(in_si),				\
-                "D"(in_di),				\
-                "r"(bp) :				\
-                "memory", "cc");			\
-})
-
-#elif defined(__i386__)
-
-/*
- * In the 32-bit version of this macro, we store bp in a memory location
- * because we've ran out of registers.
- * Now we can't reference that memory location while we've modified
- * %esp or %ebp, so we first push it on the stack, just before we push
- * %ebp, and then when we need it we read it from the stack where we
- * just pushed it.
- */
-#define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di,	\
-                        flags, magic, bp,		\
-                        eax, ebx, ecx, edx, si, di)	\
-({							\
-        asm volatile ("push %12;"			\
-                "push %%ebp;"				\
-                "mov 0x04(%%esp), %%ebp;"		\
-                VMWARE_HYPERCALL_HB_OUT			\
-                "pop %%ebp;"				\
-                "add $0x04, %%esp;" :			\
-                "=a"(eax),				\
-                "=b"(ebx),				\
-                "=c"(ecx),				\
-                "=d"(edx),				\
-                "=S"(si),				\
-                "=D"(di) :				\
-                "a"(magic),				\
-                "b"(cmd),				\
-                "c"(in_ecx),				\
-                "d"(flags),				\
-                "S"(in_si),				\
-                "D"(in_di),				\
-                "m"(bp) :				\
-                "memory", "cc");			\
-})
-
-
-#define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di,	\
-                       flags, magic, bp,		\
-                       eax, ebx, ecx, edx, si, di)	\
-({							\
-        asm volatile ("push %12;"			\
-                "push %%ebp;"				\
-                "mov 0x04(%%esp), %%ebp;"		\
-                VMWARE_HYPERCALL_HB_IN			\
-                "pop %%ebp;"				\
-                "add $0x04, %%esp;" :			\
-                "=a"(eax),				\
-                "=b"(ebx),				\
-                "=c"(ecx),				\
-                "=d"(edx),				\
-                "=S"(si),				\
-                "=D"(di) :				\
-                "a"(magic),				\
-                "b"(cmd),				\
-                "c"(in_ecx),				\
-                "d"(flags),				\
-                "S"(in_si),				\
-                "D"(in_di),				\
-                "m"(bp) :				\
-                "memory", "cc");			\
-})
-#endif /* defined(__i386__) */
-
 #endif /* defined(__i386__) || defined(__x86_64__) */
 
 #endif /* _VMWGFX_MSG_X86_H */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c
@@ -92,7 +92,7 @@
 {
 	struct vmw_escape_video_flush *flush;
 	size_t fifo_size;
-	bool have_so = (dev_priv->active_display_unit == vmw_du_screen_object);
+	bool have_so = (dev_priv->active_display_unit != vmw_du_legacy);
 	int i, num_items;
 	SVGAGuestPtr ptr;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_prime.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_prime.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /**************************************************************************
  *
- * Copyright 2013 VMware, Inc., Palo Alto, CA., USA
+ * Copyright (c) 2013-2024 Broadcom. All Rights Reserved. The term
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -31,6 +32,7 @@
  */
 
 #include "vmwgfx_drv.h"
+#include "vmwgfx_bo.h"
 #include "ttm_object.h"
 #include <linux/dma-buf.h>
 
@@ -75,8 +77,12 @@
 			   int fd, u32 *handle)
 {
 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+	int ret = ttm_prime_fd_to_handle(tfile, fd, handle);
 
-	return ttm_prime_fd_to_handle(tfile, fd, handle);
+	if (ret)
+		ret = drm_gem_prime_fd_to_handle(dev, file_priv, fd, handle);
+
+	return ret;
 }
 
 int vmw_prime_handle_to_fd(struct drm_device *dev,
@@ -84,6 +90,35 @@
 			   uint32_t handle, uint32_t flags,
 			   int *prime_fd)
 {
+	struct vmw_private *vmw = vmw_priv(dev);
 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
-	return ttm_prime_handle_to_fd(tfile, handle, flags, prime_fd);
+	struct vmw_bo *vbo;
+	int ret;
+	int surf_handle;
+
+	if (handle > VMWGFX_NUM_MOB) {
+		ret = ttm_prime_handle_to_fd(tfile, handle, flags, prime_fd);
+	} else {
+		ret = vmw_user_bo_lookup(file_priv, handle, &vbo);
+		if (ret)
+			return ret;
+		if (vbo && vbo->is_dumb) {
+			ret = drm_gem_prime_handle_to_fd(dev, file_priv, handle,
+							 flags, prime_fd);
+		} else {
+			surf_handle = vmw_lookup_surface_handle_for_buffer(vmw,
+									   vbo,
+									   handle);
+			if (surf_handle > 0)
+				ret = ttm_prime_handle_to_fd(tfile, surf_handle,
+							     flags, prime_fd);
+			else
+				ret = drm_gem_prime_handle_to_fd(dev, file_priv,
+								 handle, flags,
+								 prime_fd);
+		}
+		vmw_user_bo_unref(&vbo);
+	}
+
+	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /**************************************************************************
  *
- * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
+ * Copyright (c) 2009-2024 Broadcom. All Rights Reserved. The term
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -58,6 +59,7 @@
 
 	rb_link_node(&res->mob_node, parent, new);
 	rb_insert_color(&res->mob_node, &gbo->res_tree);
+	vmw_bo_del_detached_resource(gbo, res);
 
 	vmw_bo_prio_add(gbo, res->used_prio);
 }
@@ -287,28 +289,35 @@
  *
  * The pointer this pointed at by out_surf and out_buf needs to be null.
  */
-int vmw_user_lookup_handle(struct vmw_private *dev_priv,
+int vmw_user_object_lookup(struct vmw_private *dev_priv,
 			   struct drm_file *filp,
-			   uint32_t handle,
-			   struct vmw_surface **out_surf,
-			   struct vmw_bo **out_buf)
+			   u32 handle,
+			   struct vmw_user_object *uo)
 {
 	struct ttm_object_file *tfile = vmw_fpriv(filp)->tfile;
 	struct vmw_resource *res;
 	int ret;
 
-	BUG_ON(*out_surf || *out_buf);
+	WARN_ON(uo->surface || uo->buffer);
 
 	ret = vmw_user_resource_lookup_handle(dev_priv, tfile, handle,
 					      user_surface_converter,
 					      &res);
 	if (!ret) {
-		*out_surf = vmw_res_to_srf(res);
+		uo->surface = vmw_res_to_srf(res);
 		return 0;
 	}
 
-	*out_surf = NULL;
-	ret = vmw_user_bo_lookup(filp, handle, out_buf);
+	uo->surface = NULL;
+	ret = vmw_user_bo_lookup(filp, handle, &uo->buffer);
+	if (!ret && !uo->buffer->is_dumb) {
+		uo->surface = vmw_lookup_surface_for_buffer(dev_priv,
+							    uo->buffer,
+							    handle);
+		if (uo->surface)
+			vmw_user_bo_unref(&uo->buffer);
+	}
+
 	return ret;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /**************************************************************************
  *
- * Copyright 2011-2023 VMware, Inc., Palo Alto, CA., USA
+ * Copyright (c) 2011-2024 Broadcom. All Rights Reserved. The term
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -89,7 +90,6 @@
 struct vmw_screen_object_unit {
 	struct vmw_display_unit base;
 
-	unsigned long buffer_size; /**< Size of allocated buffer */
 	struct vmw_bo *buffer; /**< Backing store buffer */
 
 	bool defined;
@@ -239,8 +239,7 @@
 		struct vmw_connector_state *vmw_conn_state;
 		int x, y;
 
-		sou->buffer = vps->bo;
-		sou->buffer_size = vps->bo_size;
+		sou->buffer = vmw_user_object_buffer(&vps->uo);
 
 		conn_state = sou->base.connector.state;
 		vmw_conn_state = vmw_connector_state_to_vcs(conn_state);
@@ -255,7 +254,6 @@
 
 	} else {
 		sou->buffer = NULL;
-		sou->buffer_size = 0;
 	}
 }
 
@@ -347,7 +345,7 @@
 static const struct drm_connector_funcs vmw_sou_connector_funcs = {
 	.dpms = vmw_du_connector_dpms,
 	.detect = vmw_du_connector_detect,
-	.fill_modes = vmw_du_connector_fill_modes,
+	.fill_modes = drm_helper_probe_single_connector_modes,
 	.destroy = vmw_sou_connector_destroy,
 	.reset = vmw_du_connector_reset,
 	.atomic_duplicate_state = vmw_du_connector_duplicate_state,
@@ -357,6 +355,8 @@
 
 static const struct
 drm_connector_helper_funcs vmw_sou_connector_helper_funcs = {
+	.get_modes = vmw_connector_get_modes,
+	.mode_valid = vmw_connector_mode_valid
 };
 
 
@@ -382,10 +382,11 @@
 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
 	struct drm_crtc *crtc = plane->state->crtc ?
 		plane->state->crtc : old_state->crtc;
+	struct vmw_bo *bo = vmw_user_object_buffer(&vps->uo);
 
-	if (vps->bo)
-		vmw_bo_unpin(vmw_priv(crtc->dev), vps->bo, false);
-	vmw_bo_unreference(&vps->bo);
+	if (bo)
+		vmw_bo_unpin(vmw_priv(crtc->dev), bo, false);
+	vmw_user_object_unref(&vps->uo);
 	vps->bo_size = 0;
 
 	vmw_du_plane_cleanup_fb(plane, old_state);
@@ -417,9 +418,10 @@
 		.bo_type = ttm_bo_type_device,
 		.pin = true
 	};
+	struct vmw_bo *bo = NULL;
 
 	if (!new_fb) {
-		vmw_bo_unreference(&vps->bo);
+		vmw_user_object_unref(&vps->uo);
 		vps->bo_size = 0;
 
 		return 0;
@@ -428,17 +430,17 @@
 	bo_params.size = new_state->crtc_w * new_state->crtc_h * 4;
 	dev_priv = vmw_priv(crtc->dev);
 
-	if (vps->bo) {
+	bo = vmw_user_object_buffer(&vps->uo);
+	if (bo) {
 		if (vps->bo_size == bo_params.size) {
 			/*
 			 * Note that this might temporarily up the pin-count
 			 * to 2, until cleanup_fb() is called.
 			 */
-			return vmw_bo_pin_in_vram(dev_priv, vps->bo,
-						      true);
+			return vmw_bo_pin_in_vram(dev_priv, bo, true);
 		}
 
-		vmw_bo_unreference(&vps->bo);
+		vmw_user_object_unref(&vps->uo);
 		vps->bo_size = 0;
 	}
 
@@ -448,7 +450,7 @@
 	 * resume the overlays, this is preferred to failing to alloc.
 	 */
 	vmw_overlay_pause_all(dev_priv);
-	ret = vmw_bo_create(dev_priv, &bo_params, &vps->bo);
+	ret = vmw_gem_object_create(dev_priv, &bo_params, &vps->uo.buffer);
 	vmw_overlay_resume_all(dev_priv);
 	if (ret)
 		return ret;
@@ -459,7 +461,7 @@
 	 * TTM already thinks the buffer is pinned, but make sure the
 	 * pin_count is upped.
 	 */
-	return vmw_bo_pin_in_vram(dev_priv, vps->bo, true);
+	return vmw_bo_pin_in_vram(dev_priv, vps->uo.buffer, true);
 }
 
 static uint32_t vmw_sou_bo_fifo_size(struct vmw_du_update_plane *update,
@@ -586,6 +588,7 @@
 {
 	struct vmw_kms_sou_dirty_cmd *blit = cmd;
 	struct vmw_framebuffer_surface *vfbs;
+	struct vmw_surface *surf = NULL;
 
 	vfbs = container_of(update->vfb, typeof(*vfbs), base);
 
@@ -593,7 +596,8 @@
 	blit->header.size = sizeof(blit->body) + sizeof(SVGASignedRect) *
 		num_hits;
 
-	blit->body.srcImage.sid = vfbs->surface->res.id;
+	surf = vmw_user_object_surface(&vfbs->uo);
+	blit->body.srcImage.sid = surf->res.id;
 	blit->body.destScreenId = update->du->unit;
 
 	/* Update the source and destination bounding box later in post_clip */
@@ -826,7 +830,6 @@
 	sou->base.pref_active = (unit == 0);
 	sou->base.pref_width = dev_priv->initial_width;
 	sou->base.pref_height = dev_priv->initial_height;
-	sou->base.pref_mode = NULL;
 
 	/*
 	 * Remove this after enabling atomic because property values can
@@ -1108,7 +1111,7 @@
 	int ret;
 
 	if (!srf)
-		srf = &vfbs->surface->res;
+		srf = &vmw_user_object_surface(&vfbs->uo)->res;
 
 	ret = vmw_validation_add_resource(&val_ctx, srf, 0, VMW_RES_DIRTY_NONE,
 					  NULL, NULL);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c
@@ -896,7 +896,8 @@
 		.busy_domain = VMW_BO_DOMAIN_SYS,
 		.bo_type = ttm_bo_type_device,
 		.size = size,
-		.pin = true
+		.pin = true,
+		.keep_resv = true,
 	};
 
 	if (!vmw_shader_id_ok(user_key, shader_type))
@@ -906,10 +907,6 @@
 	if (unlikely(ret != 0))
 		goto out;
 
-	ret = ttm_bo_reserve(&buf->tbo, false, true, NULL);
-	if (unlikely(ret != 0))
-		goto no_reserve;
-
 	/* Map and copy shader bytecode. */
 	ret = ttm_bo_kmap(&buf->tbo, 0, PFN_UP(size), &map);
 	if (unlikely(ret != 0)) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /******************************************************************************
  *
- * COPYRIGHT (C) 2014-2023 VMware, Inc., Palo Alto, CA., USA
+ * Copyright (c) 2014-2024 Broadcom. All Rights Reserved. The term
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -28,6 +29,7 @@
 #include "vmwgfx_bo.h"
 #include "vmwgfx_kms.h"
 #include "vmw_surface_cache.h"
+#include <linux/fsnotify.h>
 
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
@@ -41,7 +43,14 @@
 #define vmw_connector_to_stdu(x) \
 	container_of(x, struct vmw_screen_target_display_unit, base.connector)
 
-
+/*
+ * Some renderers such as llvmpipe will align the width and height of their
+ * buffers to match their tile size. We need to keep this in mind when exposing
+ * modes to userspace so that this possible over-allocation will not exceed
+ * graphics memory. 64x64 pixels seems to be a reasonable upper bound for the
+ * tile size of current renderers.
+ */
+#define GPU_TILE_SIZE 64
 
 enum stdu_content_type {
 	SAME_AS_DISPLAY = 0,
@@ -490,7 +499,7 @@
 		container_of(dirty->unit, typeof(*stdu), base);
 	s32 width, height;
 	s32 src_pitch, dst_pitch;
-	struct ttm_buffer_object *src_bo, *dst_bo;
+	struct vmw_bo *src_bo, *dst_bo;
 	u32 src_offset, dst_offset;
 	struct vmw_diff_cpy diff = VMW_CPU_BLIT_DIFF_INITIALIZER(stdu->cpp);
 
@@ -505,11 +514,11 @@
 
 	/* Assume we are blitting from Guest (bo) to Host (display_srf) */
 	src_pitch = stdu->display_srf->metadata.base_size.width * stdu->cpp;
-	src_bo = &stdu->display_srf->res.guest_memory_bo->tbo;
+	src_bo = stdu->display_srf->res.guest_memory_bo;
 	src_offset = ddirty->top * src_pitch + ddirty->left * stdu->cpp;
 
 	dst_pitch = ddirty->pitch;
-	dst_bo = &ddirty->buf->tbo;
+	dst_bo = ddirty->buf;
 	dst_offset = ddirty->fb_top * dst_pitch + ddirty->fb_left * stdu->cpp;
 
 	(void) vmw_bo_cpu_blit(dst_bo, dst_offset, dst_pitch,
@@ -724,7 +733,7 @@
 	int ret;
 
 	if (!srf)
-		srf = &vfbs->surface->res;
+		srf = &vmw_user_object_surface(&vfbs->uo)->res;
 
 	ret = vmw_validation_add_resource(&val_ctx, srf, 0, VMW_RES_DIRTY_NONE,
 					  NULL, NULL);
@@ -735,12 +744,6 @@
 	if (ret)
 		goto out_unref;
 
-	if (vfbs->is_bo_proxy) {
-		ret = vmw_kms_update_proxy(srf, clips, num_clips, inc);
-		if (ret)
-			goto out_finish;
-	}
-
 	sdirty.base.fifo_commit = vmw_kms_stdu_surface_fifo_commit;
 	sdirty.base.clip = vmw_kms_stdu_surface_clip;
 	sdirty.base.fifo_reserve_size = sizeof(struct vmw_stdu_surface_copy) +
@@ -754,7 +757,7 @@
 	ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, vclips,
 				   dest_x, dest_y, num_clips, inc,
 				   &sdirty.base);
-out_finish:
+
 	vmw_kms_helper_validation_finish(dev_priv, NULL, &val_ctx, out_fence,
 					 NULL);
 
@@ -825,12 +828,76 @@
 	vmw_stdu_destroy(vmw_connector_to_stdu(connector));
 }
 
+static enum drm_mode_status
+vmw_stdu_connector_mode_valid(struct drm_connector *connector,
+			      struct drm_display_mode *mode)
+{
+	enum drm_mode_status ret;
+	struct drm_device *dev = connector->dev;
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	u64 assumed_cpp = dev_priv->assume_16bpp ? 2 : 4;
+	/* Align width and height to account for GPU tile over-alignment */
+	u64 required_mem = ALIGN(mode->hdisplay, GPU_TILE_SIZE) *
+			   ALIGN(mode->vdisplay, GPU_TILE_SIZE) *
+			   assumed_cpp;
+	required_mem = ALIGN(required_mem, PAGE_SIZE);
+
+	ret = drm_mode_validate_size(mode, dev_priv->stdu_max_width,
+				     dev_priv->stdu_max_height);
+	if (ret != MODE_OK)
+		return ret;
+
+	ret = drm_mode_validate_size(mode, dev_priv->texture_max_width,
+				     dev_priv->texture_max_height);
+	if (ret != MODE_OK)
+		return ret;
+
+	if (required_mem > dev_priv->max_primary_mem)
+		return MODE_MEM;
+
+	if (required_mem > dev_priv->max_mob_pages * PAGE_SIZE)
+		return MODE_MEM;
+
+	if (required_mem > dev_priv->max_mob_size)
+		return MODE_MEM;
+
+	return MODE_OK;
+}
+
+/*
+ * Trigger a modeset if the X,Y position of the Screen Target changes.
+ * This is needed when multi-mon is cycled. The original Screen Target will have
+ * the same mode but its relative X,Y position in the topology will change.
+ */
+static int vmw_stdu_connector_atomic_check(struct drm_connector *conn,
+					   struct drm_atomic_state *state)
+{
+	struct drm_connector_state *conn_state;
+	struct vmw_screen_target_display_unit *du;
+	struct drm_crtc_state *new_crtc_state;
+
+	conn_state = drm_atomic_get_connector_state(state, conn);
 
+	if (IS_ERR(conn_state))
+		return PTR_ERR(conn_state);
+
+	du = vmw_connector_to_stdu(conn);
+
+	if (!conn_state->crtc)
+		return 0;
+
+	new_crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+	if (du->base.gui_x != du->base.set_gui_x ||
+	    du->base.gui_y != du->base.set_gui_y)
+		new_crtc_state->mode_changed = true;
+
+	return 0;
+}
 
 static const struct drm_connector_funcs vmw_stdu_connector_funcs = {
 	.dpms = vmw_du_connector_dpms,
 	.detect = vmw_du_connector_detect,
-	.fill_modes = vmw_du_connector_fill_modes,
+	.fill_modes = drm_helper_probe_single_connector_modes,
 	.destroy = vmw_stdu_connector_destroy,
 	.reset = vmw_du_connector_reset,
 	.atomic_duplicate_state = vmw_du_connector_duplicate_state,
@@ -840,6 +907,9 @@
 
 static const struct
 drm_connector_helper_funcs vmw_stdu_connector_helper_funcs = {
+	.get_modes = vmw_connector_get_modes,
+	.mode_valid = vmw_stdu_connector_mode_valid,
+	.atomic_check = vmw_stdu_connector_atomic_check,
 };
 
 
@@ -866,9 +936,8 @@
 {
 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
 
-	if (vps->surf)
+	if (vmw_user_object_surface(&vps->uo))
 		WARN_ON(!vps->pinned);
-
 	vmw_du_plane_cleanup_fb(plane, old_state);
 
 	vps->content_fb_type = SAME_AS_DISPLAY;
@@ -876,7 +945,6 @@
 }
 
 
-
 /**
  * vmw_stdu_primary_plane_prepare_fb - Readies the display surface
  *
@@ -900,13 +968,15 @@
 	enum stdu_content_type new_content_type;
 	struct vmw_framebuffer_surface *new_vfbs;
 	uint32_t hdisplay = new_state->crtc_w, vdisplay = new_state->crtc_h;
+	struct drm_plane_state *old_state = plane->state;
+	struct drm_rect rect;
 	int ret;
 
 	/* No FB to prepare */
 	if (!new_fb) {
-		if (vps->surf) {
+		if (vmw_user_object_surface(&vps->uo)) {
 			WARN_ON(vps->pinned != 0);
-			vmw_surface_unreference(&vps->surf);
+			vmw_user_object_unref(&vps->uo);
 		}
 
 		return 0;
@@ -916,8 +986,8 @@
 	new_vfbs = (vfb->bo) ? NULL : vmw_framebuffer_to_vfbs(new_fb);
 
 	if (new_vfbs &&
-	    new_vfbs->surface->metadata.base_size.width == hdisplay &&
-	    new_vfbs->surface->metadata.base_size.height == vdisplay)
+	    vmw_user_object_surface(&new_vfbs->uo)->metadata.base_size.width == hdisplay &&
+	    vmw_user_object_surface(&new_vfbs->uo)->metadata.base_size.height == vdisplay)
 		new_content_type = SAME_AS_DISPLAY;
 	else if (vfb->bo)
 		new_content_type = SEPARATE_BO;
@@ -955,29 +1025,29 @@
 			metadata.num_sizes = 1;
 			metadata.scanout = true;
 		} else {
-			metadata = new_vfbs->surface->metadata;
+			metadata = vmw_user_object_surface(&new_vfbs->uo)->metadata;
 		}
 
 		metadata.base_size.width = hdisplay;
 		metadata.base_size.height = vdisplay;
 		metadata.base_size.depth = 1;
 
-		if (vps->surf) {
+		if (vmw_user_object_surface(&vps->uo)) {
 			struct drm_vmw_size cur_base_size =
-				vps->surf->metadata.base_size;
+				vmw_user_object_surface(&vps->uo)->metadata.base_size;
 
 			if (cur_base_size.width != metadata.base_size.width ||
 			    cur_base_size.height != metadata.base_size.height ||
-			    vps->surf->metadata.format != metadata.format) {
+			    vmw_user_object_surface(&vps->uo)->metadata.format != metadata.format) {
 				WARN_ON(vps->pinned != 0);
-				vmw_surface_unreference(&vps->surf);
+				vmw_user_object_unref(&vps->uo);
 			}
 
 		}
 
-		if (!vps->surf) {
+		if (!vmw_user_object_surface(&vps->uo)) {
 			ret = vmw_gb_surface_define(dev_priv, &metadata,
-						    &vps->surf);
+						    &vps->uo.surface);
 			if (ret != 0) {
 				DRM_ERROR("Couldn't allocate STDU surface.\n");
 				return ret;
@@ -990,18 +1060,19 @@
 		 * The only time we add a reference in prepare_fb is if the
 		 * state object doesn't have a reference to begin with
 		 */
-		if (vps->surf) {
+		if (vmw_user_object_surface(&vps->uo)) {
 			WARN_ON(vps->pinned != 0);
-			vmw_surface_unreference(&vps->surf);
+			vmw_user_object_unref(&vps->uo);
 		}
 
-		vps->surf = vmw_surface_reference(new_vfbs->surface);
+		memcpy(&vps->uo, &new_vfbs->uo, sizeof(vps->uo));
+		vmw_user_object_ref(&vps->uo);
 	}
 
-	if (vps->surf) {
+	if (vmw_user_object_surface(&vps->uo)) {
 
 		/* Pin new surface before flipping */
-		ret = vmw_resource_pin(&vps->surf->res, false);
+		ret = vmw_resource_pin(&vmw_user_object_surface(&vps->uo)->res, false);
 		if (ret)
 			goto out_srf_unref;
 
@@ -1011,6 +1082,34 @@
 	vps->content_fb_type = new_content_type;
 
 	/*
+	 * The drm fb code will do blit's via the vmap interface, which doesn't
+	 * trigger vmw_bo page dirty tracking due to being kernel side (and thus
+	 * doesn't require mmap'ing) so we have to update the surface's dirty
+	 * regions by hand but we want to be careful to not overwrite the
+	 * resource if it has been written to by the gpu (res_dirty).
+	 */
+	if (vps->uo.buffer && vps->uo.buffer->is_dumb) {
+		struct vmw_surface *surf = vmw_user_object_surface(&vps->uo);
+		struct vmw_resource *res = &surf->res;
+
+		if (!res->res_dirty && drm_atomic_helper_damage_merged(old_state,
+								       new_state,
+								       &rect)) {
+			/*
+			 * At some point it might be useful to actually translate
+			 * (rect.x1, rect.y1) => start, and (rect.x2, rect.y2) => end,
+			 * but currently the fb code will just report the entire fb
+			 * dirty so in practice it doesn't matter.
+			 */
+			pgoff_t start = res->guest_memory_offset >> PAGE_SHIFT;
+			pgoff_t end = __KERNEL_DIV_ROUND_UP(res->guest_memory_offset +
+							    res->guest_memory_size,
+							    PAGE_SIZE);
+			vmw_resource_dirty_update(res, start, end);
+		}
+	}
+
+	/*
 	 * This should only happen if the buffer object is too large to create a
 	 * proxy surface for.
 	 */
@@ -1020,7 +1119,7 @@
 	return 0;
 
 out_srf_unref:
-	vmw_surface_unreference(&vps->surf);
+	vmw_user_object_unref(&vps->uo);
 	return ret;
 }
 
@@ -1066,7 +1165,7 @@
 	struct vmw_diff_cpy diff = VMW_CPU_BLIT_DIFF_INITIALIZER(0);
 	struct vmw_stdu_update_gb_image *cmd_img = cmd;
 	struct vmw_stdu_update *cmd_update;
-	struct ttm_buffer_object *src_bo, *dst_bo;
+	struct vmw_bo *src_bo, *dst_bo;
 	u32 src_offset, dst_offset;
 	s32 src_pitch, dst_pitch;
 	s32 width, height;
@@ -1080,11 +1179,11 @@
 
 	diff.cpp = stdu->cpp;
 
-	dst_bo = &stdu->display_srf->res.guest_memory_bo->tbo;
+	dst_bo = stdu->display_srf->res.guest_memory_bo;
 	dst_pitch = stdu->display_srf->metadata.base_size.width * stdu->cpp;
 	dst_offset = bb->y1 * dst_pitch + bb->x1 * stdu->cpp;
 
-	src_bo = &vfbbo->buffer->tbo;
+	src_bo = vfbbo->buffer;
 	src_pitch = update->vfb->base.pitches[0];
 	src_offset = bo_update->fb_top * src_pitch + bo_update->fb_left *
 		stdu->cpp;
@@ -1162,14 +1261,8 @@
 vmw_stdu_surface_fifo_size_same_display(struct vmw_du_update_plane *update,
 					uint32_t num_hits)
 {
-	struct vmw_framebuffer_surface *vfbs;
 	uint32_t size = 0;
 
-	vfbs = container_of(update->vfb, typeof(*vfbs), base);
-
-	if (vfbs->is_bo_proxy)
-		size += sizeof(struct vmw_stdu_update_gb_image) * num_hits;
-
 	size += sizeof(struct vmw_stdu_update);
 
 	return size;
@@ -1178,14 +1271,8 @@
 static uint32_t vmw_stdu_surface_fifo_size(struct vmw_du_update_plane *update,
 					   uint32_t num_hits)
 {
-	struct vmw_framebuffer_surface *vfbs;
 	uint32_t size = 0;
 
-	vfbs = container_of(update->vfb, typeof(*vfbs), base);
-
-	if (vfbs->is_bo_proxy)
-		size += sizeof(struct vmw_stdu_update_gb_image) * num_hits;
-
 	size += sizeof(struct vmw_stdu_surface_copy) + sizeof(SVGA3dCopyBox) *
 		num_hits + sizeof(struct vmw_stdu_update);
 
@@ -1193,47 +1280,6 @@
 }
 
 static uint32_t
-vmw_stdu_surface_update_proxy(struct vmw_du_update_plane *update, void *cmd)
-{
-	struct vmw_framebuffer_surface *vfbs;
-	struct drm_plane_state *state = update->plane->state;
-	struct drm_plane_state *old_state = update->old_state;
-	struct vmw_stdu_update_gb_image *cmd_update = cmd;
-	struct drm_atomic_helper_damage_iter iter;
-	struct drm_rect clip;
-	uint32_t copy_size = 0;
-
-	vfbs = container_of(update->vfb, typeof(*vfbs), base);
-
-	/*
-	 * proxy surface is special where a buffer object type fb is wrapped
-	 * in a surface and need an update gb image command to sync with device.
-	 */
-	drm_atomic_helper_damage_iter_init(&iter, old_state, state);
-	drm_atomic_for_each_plane_damage(&iter, &clip) {
-		SVGA3dBox *box = &cmd_update->body.box;
-
-		cmd_update->header.id = SVGA_3D_CMD_UPDATE_GB_IMAGE;
-		cmd_update->header.size = sizeof(cmd_update->body);
-		cmd_update->body.image.sid = vfbs->surface->res.id;
-		cmd_update->body.image.face = 0;
-		cmd_update->body.image.mipmap = 0;
-
-		box->x = clip.x1;
-		box->y = clip.y1;
-		box->z = 0;
-		box->w = drm_rect_width(&clip);
-		box->h = drm_rect_height(&clip);
-		box->d = 1;
-
-		copy_size += sizeof(*cmd_update);
-		cmd_update++;
-	}
-
-	return copy_size;
-}
-
-static uint32_t
 vmw_stdu_surface_populate_copy(struct vmw_du_update_plane  *update, void *cmd,
 			       uint32_t num_hits)
 {
@@ -1247,7 +1293,7 @@
 	cmd_copy->header.id = SVGA_3D_CMD_SURFACE_COPY;
 	cmd_copy->header.size = sizeof(cmd_copy->body) + sizeof(SVGA3dCopyBox) *
 		num_hits;
-	cmd_copy->body.src.sid = vfbs->surface->res.id;
+	cmd_copy->body.src.sid = vmw_user_object_surface(&vfbs->uo)->res.id;
 	cmd_copy->body.dest.sid = stdu->display_srf->res.id;
 
 	return sizeof(*cmd_copy);
@@ -1318,10 +1364,7 @@
 	srf_update.mutex = &dev_priv->cmdbuf_mutex;
 	srf_update.intr = true;
 
-	if (vfbs->is_bo_proxy)
-		srf_update.post_prepare = vmw_stdu_surface_update_proxy;
-
-	if (vfbs->surface->res.id != stdu->display_srf->res.id) {
+	if (vmw_user_object_surface(&vfbs->uo)->res.id != stdu->display_srf->res.id) {
 		srf_update.calc_fifo_size = vmw_stdu_surface_fifo_size;
 		srf_update.pre_clip = vmw_stdu_surface_populate_copy;
 		srf_update.clip = vmw_stdu_surface_populate_clip;
@@ -1365,7 +1408,7 @@
 		stdu = vmw_crtc_to_stdu(crtc);
 		dev_priv = vmw_priv(crtc->dev);
 
-		stdu->display_srf = vps->surf;
+		stdu->display_srf = vmw_user_object_surface(&vps->uo);
 		stdu->content_fb_type = vps->content_fb_type;
 		stdu->cpp = vps->cpp;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0 OR MIT
 /**************************************************************************
  *
- * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
+ * Copyright (c) 2009-2024 Broadcom. All Rights Reserved. The term
+ * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
@@ -36,9 +37,6 @@
 #include <drm/ttm/ttm_placement.h>
 
 #define SVGA3D_FLAGS_64(upper32, lower32) (((uint64_t)upper32 << 32) | lower32)
-#define SVGA3D_FLAGS_UPPER_32(svga3d_flags) (svga3d_flags >> 32)
-#define SVGA3D_FLAGS_LOWER_32(svga3d_flags) \
-	(svga3d_flags & ((uint64_t)U32_MAX))
 
 /**
  * struct vmw_user_surface - User-space visible surface resource
@@ -687,6 +685,14 @@
 	struct vmw_resource *res = &user_srf->srf.res;
 
 	*p_base = NULL;
+
+	/*
+	 * Dumb buffers own the resource and they'll unref the
+	 * resource themselves
+	 */
+	if (res && res->guest_memory_bo && res->guest_memory_bo->is_dumb)
+		return;
+
 	vmw_resource_unreference(&res);
 }
 
@@ -813,7 +819,8 @@
 		}
 	}
 	res->guest_memory_size = cur_bo_offset;
-	if (metadata->scanout &&
+	if (!file_priv->atomic &&
+	    metadata->scanout &&
 	    metadata->num_sizes == 1 &&
 	    metadata->sizes[0].width == VMW_CURSOR_SNOOP_WIDTH &&
 	    metadata->sizes[0].height == VMW_CURSOR_SNOOP_HEIGHT &&
@@ -867,6 +874,7 @@
 			vmw_resource_unreference(&res);
 			goto out_unlock;
 		}
+		vmw_bo_add_detached_resource(res->guest_memory_bo, res);
 	}
 
 	tmp = vmw_resource_reference(&srf->res);
@@ -894,6 +902,113 @@
 	return ret;
 }
 
+static struct vmw_user_surface *
+vmw_lookup_user_surface_for_buffer(struct vmw_private *vmw, struct vmw_bo *bo,
+				   u32 handle)
+{
+	struct vmw_user_surface *user_srf = NULL;
+	struct vmw_surface *surf;
+	struct ttm_base_object *base;
+
+	surf = vmw_bo_surface(bo);
+	if (surf) {
+		rcu_read_lock();
+		user_srf = container_of(surf, struct vmw_user_surface, srf);
+		base = &user_srf->prime.base;
+		if (base && !kref_get_unless_zero(&base->refcount)) {
+			drm_dbg_driver(&vmw->drm,
+				       "%s: referencing a stale surface handle %d\n",
+					__func__, handle);
+			base = NULL;
+			user_srf = NULL;
+		}
+		rcu_read_unlock();
+	}
+
+	return user_srf;
+}
+
+struct vmw_surface *vmw_lookup_surface_for_buffer(struct vmw_private *vmw,
+						  struct vmw_bo *bo,
+						  u32 handle)
+{
+	struct vmw_user_surface *user_srf =
+		vmw_lookup_user_surface_for_buffer(vmw, bo, handle);
+	struct vmw_surface *surf = NULL;
+	struct ttm_base_object *base;
+
+	if (user_srf) {
+		surf = vmw_surface_reference(&user_srf->srf);
+		base = &user_srf->prime.base;
+		ttm_base_object_unref(&base);
+	}
+	return surf;
+}
+
+u32 vmw_lookup_surface_handle_for_buffer(struct vmw_private *vmw,
+					 struct vmw_bo *bo,
+					 u32 handle)
+{
+	struct vmw_user_surface *user_srf =
+		vmw_lookup_user_surface_for_buffer(vmw, bo, handle);
+	int surf_handle = 0;
+	struct ttm_base_object *base;
+
+	if (user_srf) {
+		base = &user_srf->prime.base;
+		surf_handle = (u32)base->handle;
+		ttm_base_object_unref(&base);
+	}
+	return surf_handle;
+}
+
+static int vmw_buffer_prime_to_surface_base(struct vmw_private *dev_priv,
+					    struct drm_file *file_priv,
+					    u32 fd, u32 *handle,
+					    struct ttm_base_object **base_p)
+{
+	struct ttm_base_object *base;
+	struct vmw_bo *bo;
+	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+	struct vmw_user_surface *user_srf;
+	int ret;
+
+	ret = drm_gem_prime_fd_to_handle(&dev_priv->drm, file_priv, fd, handle);
+	if (ret) {
+		drm_warn(&dev_priv->drm,
+			 "Wasn't able to find user buffer for fd = %u.\n", fd);
+		return ret;
+	}
+
+	ret = vmw_user_bo_lookup(file_priv, *handle, &bo);
+	if (ret) {
+		drm_warn(&dev_priv->drm,
+			 "Wasn't able to lookup user buffer for handle = %u.\n", *handle);
+		return ret;
+	}
+
+	user_srf = vmw_lookup_user_surface_for_buffer(dev_priv, bo, *handle);
+	if (WARN_ON(!user_srf)) {
+		drm_warn(&dev_priv->drm,
+			 "User surface fd %d (handle %d) is null.\n", fd, *handle);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	base = &user_srf->prime.base;
+	ret = ttm_ref_object_add(tfile, base, NULL, false);
+	if (ret) {
+		drm_warn(&dev_priv->drm,
+			 "Couldn't add an object ref for the buffer (%d).\n", *handle);
+		goto out;
+	}
+
+	*base_p = base;
+out:
+	vmw_user_bo_unref(&bo);
+
+	return ret;
+}
 
 static int
 vmw_surface_handle_reference(struct vmw_private *dev_priv,
@@ -903,15 +1018,19 @@
 			     struct ttm_base_object **base_p)
 {
 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
-	struct vmw_user_surface *user_srf;
+	struct vmw_user_surface *user_srf = NULL;
 	uint32_t handle;
 	struct ttm_base_object *base;
 	int ret;
 
 	if (handle_type == DRM_VMW_HANDLE_PRIME) {
 		ret = ttm_prime_fd_to_handle(tfile, u_handle, &handle);
-		if (unlikely(ret != 0))
-			return ret;
+		if (ret)
+			return vmw_buffer_prime_to_surface_base(dev_priv,
+								file_priv,
+								u_handle,
+								&handle,
+								base_p);
 	} else {
 		handle = u_handle;
 	}
@@ -1505,7 +1624,12 @@
 		ret = vmw_user_bo_lookup(file_priv, req->base.buffer_handle,
 					 &res->guest_memory_bo);
 		if (ret == 0) {
-			if (res->guest_memory_bo->tbo.base.size < res->guest_memory_size) {
+			if (res->guest_memory_bo->is_dumb) {
+				VMW_DEBUG_USER("Can't backup surface with a dumb buffer.\n");
+				vmw_user_bo_unref(&res->guest_memory_bo);
+				ret = -EINVAL;
+				goto out_unlock;
+			} else if (res->guest_memory_bo->tbo.base.size < res->guest_memory_size) {
 				VMW_DEBUG_USER("Surface backup buffer too small.\n");
 				vmw_user_bo_unref(&res->guest_memory_bo);
 				ret = -EINVAL;
@@ -1564,6 +1688,7 @@
 	rep->handle      = user_srf->prime.base.handle;
 	rep->backup_size = res->guest_memory_size;
 	if (res->guest_memory_bo) {
+		vmw_bo_add_detached_resource(res->guest_memory_bo, res);
 		rep->buffer_map_handle =
 			drm_vma_node_offset_addr(&res->guest_memory_bo->tbo.base.vma_node);
 		rep->buffer_size = res->guest_memory_bo->tbo.base.size;
@@ -2106,3 +2231,145 @@
 out_unlock:
 	return ret;
 }
+
+static SVGA3dSurfaceFormat vmw_format_bpp_to_svga(struct vmw_private *vmw,
+						  int bpp)
+{
+	switch (bpp) {
+	case 8: /* DRM_FORMAT_C8 */
+		return SVGA3D_P8;
+	case 16: /* DRM_FORMAT_RGB565 */
+		return SVGA3D_R5G6B5;
+	case 32: /* DRM_FORMAT_XRGB8888 */
+		if (has_sm4_context(vmw))
+			return SVGA3D_B8G8R8X8_UNORM;
+		return SVGA3D_X8R8G8B8;
+	default:
+		drm_warn(&vmw->drm, "Unsupported format bpp: %d\n", bpp);
+		return SVGA3D_X8R8G8B8;
+	}
+}
+
+/**
+ * vmw_dumb_create - Create a dumb kms buffer
+ *
+ * @file_priv: Pointer to a struct drm_file identifying the caller.
+ * @dev: Pointer to the drm device.
+ * @args: Pointer to a struct drm_mode_create_dumb structure
+ * Return: Zero on success, negative error code on failure.
+ *
+ * This is a driver callback for the core drm create_dumb functionality.
+ * Note that this is very similar to the vmw_bo_alloc ioctl, except
+ * that the arguments have a different format.
+ */
+int vmw_dumb_create(struct drm_file *file_priv,
+		    struct drm_device *dev,
+		    struct drm_mode_create_dumb *args)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+	struct vmw_bo *vbo = NULL;
+	struct vmw_resource *res = NULL;
+	union drm_vmw_gb_surface_create_ext_arg arg = { 0 };
+	struct drm_vmw_gb_surface_create_ext_req *req = &arg.req;
+	int ret;
+	struct drm_vmw_size drm_size = {
+		.width = args->width,
+		.height = args->height,
+		.depth = 1,
+	};
+	SVGA3dSurfaceFormat format = vmw_format_bpp_to_svga(dev_priv, args->bpp);
+	const struct SVGA3dSurfaceDesc *desc = vmw_surface_get_desc(format);
+	SVGA3dSurfaceAllFlags flags = SVGA3D_SURFACE_HINT_TEXTURE |
+				      SVGA3D_SURFACE_HINT_RENDERTARGET |
+				      SVGA3D_SURFACE_SCREENTARGET;
+
+	if (vmw_surface_is_dx_screen_target_format(format)) {
+		flags |= SVGA3D_SURFACE_BIND_SHADER_RESOURCE |
+			 SVGA3D_SURFACE_BIND_RENDER_TARGET;
+	}
+
+	/*
+	 * Without mob support we're just going to use raw memory buffer
+	 * because we wouldn't be able to support full surface coherency
+	 * without mobs. There also no reason to support surface coherency
+	 * without 3d (i.e. gpu usage on the host) because then all the
+	 * contents is going to be rendered guest side.
+	 */
+	if (!dev_priv->has_mob || !vmw_supports_3d(dev_priv)) {
+		int cpp = DIV_ROUND_UP(args->bpp, 8);
+
+		switch (cpp) {
+		case 1: /* DRM_FORMAT_C8 */
+		case 2: /* DRM_FORMAT_RGB565 */
+		case 4: /* DRM_FORMAT_XRGB8888 */
+			break;
+		default:
+			/*
+			 * Dumb buffers don't allow anything else.
+			 * This is tested via IGT's dumb_buffers
+			 */
+			return -EINVAL;
+		}
+
+		args->pitch = args->width * cpp;
+		args->size = ALIGN(args->pitch * args->height, PAGE_SIZE);
+
+		ret = vmw_gem_object_create_with_handle(dev_priv, file_priv,
+							args->size, &args->handle,
+							&vbo);
+		/* drop reference from allocate - handle holds it now */
+		drm_gem_object_put(&vbo->tbo.base);
+		return ret;
+	}
+
+	req->version = drm_vmw_gb_surface_v1;
+	req->multisample_pattern = SVGA3D_MS_PATTERN_NONE;
+	req->quality_level = SVGA3D_MS_QUALITY_NONE;
+	req->buffer_byte_stride = 0;
+	req->must_be_zero = 0;
+	req->base.svga3d_flags = SVGA3D_FLAGS_LOWER_32(flags);
+	req->svga3d_flags_upper_32_bits = SVGA3D_FLAGS_UPPER_32(flags);
+	req->base.format = (uint32_t)format;
+	req->base.drm_surface_flags = drm_vmw_surface_flag_scanout;
+	req->base.drm_surface_flags |= drm_vmw_surface_flag_shareable;
+	req->base.drm_surface_flags |= drm_vmw_surface_flag_create_buffer;
+	req->base.drm_surface_flags |= drm_vmw_surface_flag_coherent;
+	req->base.base_size.width = args->width;
+	req->base.base_size.height = args->height;
+	req->base.base_size.depth = 1;
+	req->base.array_size = 0;
+	req->base.mip_levels = 1;
+	req->base.multisample_count = 0;
+	req->base.buffer_handle = SVGA3D_INVALID_ID;
+	req->base.autogen_filter = SVGA3D_TEX_FILTER_NONE;
+	ret = vmw_gb_surface_define_ext_ioctl(dev, &arg, file_priv);
+	if (ret) {
+		drm_warn(dev, "Unable to create a dumb buffer\n");
+		return ret;
+	}
+
+	args->handle = arg.rep.buffer_handle;
+	args->size = arg.rep.buffer_size;
+	args->pitch = vmw_surface_calculate_pitch(desc, &drm_size);
+
+	ret = vmw_user_resource_lookup_handle(dev_priv, tfile, arg.rep.handle,
+					      user_surface_converter,
+					      &res);
+	if (ret) {
+		drm_err(dev, "Created resource handle doesn't exist!\n");
+		goto err;
+	}
+
+	vbo = res->guest_memory_bo;
+	vbo->is_dumb = true;
+	vbo->dumb_surface = vmw_res_to_srf(res);
+
+err:
+	if (res)
+		vmw_resource_unreference(&res);
+	if (ret)
+		ttm_ref_object_base_unref(tfile, arg.rep.handle);
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
@@ -220,13 +220,18 @@
 	switch (dev_priv->map_mode) {
 	case vmw_dma_map_bind:
 	case vmw_dma_map_populate:
-		vsgt->sgt = &vmw_tt->sgt;
-		ret = sg_alloc_table_from_pages_segment(
-			&vmw_tt->sgt, vsgt->pages, vsgt->num_pages, 0,
-			(unsigned long)vsgt->num_pages << PAGE_SHIFT,
-			dma_get_max_seg_size(dev_priv->drm.dev), GFP_KERNEL);
-		if (ret)
-			goto out_sg_alloc_fail;
+		if (vmw_tt->dma_ttm.page_flags  & TTM_TT_FLAG_EXTERNAL) {
+			vsgt->sgt = vmw_tt->dma_ttm.sg;
+		} else {
+			vsgt->sgt = &vmw_tt->sgt;
+			ret = sg_alloc_table_from_pages_segment(&vmw_tt->sgt,
+				vsgt->pages, vsgt->num_pages, 0,
+				(unsigned long)vsgt->num_pages << PAGE_SHIFT,
+				dma_get_max_seg_size(dev_priv->drm.dev),
+				GFP_KERNEL);
+			if (ret)
+				goto out_sg_alloc_fail;
+		}
 
 		ret = vmw_ttm_map_for_dma(vmw_tt);
 		if (unlikely(ret != 0))
@@ -241,8 +246,9 @@
 	return 0;
 
 out_map_fail:
-	sg_free_table(vmw_tt->vsgt.sgt);
-	vmw_tt->vsgt.sgt = NULL;
+	drm_warn(&dev_priv->drm, "VSG table map failed!");
+	sg_free_table(vsgt->sgt);
+	vsgt->sgt = NULL;
 out_sg_alloc_fail:
 	return ret;
 }
@@ -388,15 +394,17 @@
 static int vmw_ttm_populate(struct ttm_device *bdev,
 			    struct ttm_tt *ttm, struct ttm_operation_ctx *ctx)
 {
-	int ret;
+	bool external = (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) != 0;
 
-	/* TODO: maybe completely drop this ? */
 	if (ttm_tt_is_populated(ttm))
 		return 0;
 
-	ret = ttm_pool_alloc(&bdev->pool, ttm, ctx);
+	if (external && ttm->sg)
+		return  drm_prime_sg_to_dma_addr_array(ttm->sg,
+						       ttm->dma_address,
+						       ttm->num_pages);
 
-	return ret;
+	return ttm_pool_alloc(&bdev->pool, ttm, ctx);
 }
 
 static void vmw_ttm_unpopulate(struct ttm_device *bdev,
@@ -404,6 +412,10 @@
 {
 	struct vmw_ttm_tt *vmw_tt = container_of(ttm, struct vmw_ttm_tt,
 						 dma_ttm);
+	bool external = (ttm->page_flags & TTM_TT_FLAG_EXTERNAL) != 0;
+
+	if (external)
+		return;
 
 	vmw_ttm_unbind(bdev, ttm);
 
@@ -422,6 +434,7 @@
 {
 	struct vmw_ttm_tt *vmw_be;
 	int ret;
+	bool external = bo->type == ttm_bo_type_sg;
 
 	vmw_be = kzalloc(sizeof(*vmw_be), GFP_KERNEL);
 	if (!vmw_be)
@@ -430,7 +443,10 @@
 	vmw_be->dev_priv = vmw_priv_from_ttm(bo->bdev);
 	vmw_be->mob = NULL;
 
-	if (vmw_be->dev_priv->map_mode == vmw_dma_alloc_coherent)
+	if (external)
+		page_flags |= TTM_TT_FLAG_EXTERNAL | TTM_TT_FLAG_EXTERNAL_MAPPABLE;
+
+	if (vmw_be->dev_priv->map_mode == vmw_dma_alloc_coherent || external)
 		ret = ttm_sg_tt_init(&vmw_be->dma_ttm, bo, page_flags,
 				     ttm_cached);
 	else
@@ -588,15 +604,14 @@
 		.busy_domain = domain,
 		.bo_type = ttm_bo_type_kernel,
 		.size = bo_size,
-		.pin = true
+		.pin = true,
+		.keep_resv = true,
 	};
 
 	ret = vmw_bo_create(dev_priv, &bo_params, &vbo);
 	if (unlikely(ret != 0))
 		return ret;
 
-	ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL);
-	BUG_ON(ret != 0);
 	ret = vmw_ttm_populate(vbo->tbo.bdev, vbo->tbo.ttm, &ctx);
 	if (likely(ret == 0)) {
 		struct vmw_ttm_tt *vmw_tt =
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_validation.c
@@ -32,9 +32,6 @@
 
 #include <linux/slab.h>
 
-
-#define VMWGFX_VALIDATION_MEM_GRAN (16*PAGE_SIZE)
-
 /**
  * struct vmw_validation_bo_node - Buffer object validation metadata.
  * @base: Metadata used for TTM reservation- and validation.
@@ -112,20 +109,10 @@
 		return NULL;
 
 	if (ctx->mem_size_left < size) {
-		struct page *page;
-
-		if (ctx->vm && ctx->vm_size_left < PAGE_SIZE) {
-			ctx->vm_size_left += VMWGFX_VALIDATION_MEM_GRAN;
-			ctx->total_mem += VMWGFX_VALIDATION_MEM_GRAN;
-		}
-
-		page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+		struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO);
 		if (!page)
 			return NULL;
 
-		if (ctx->vm)
-			ctx->vm_size_left -= PAGE_SIZE;
-
 		list_add_tail(&page->lru, &ctx->page_list);
 		ctx->page_address = page_address(page);
 		ctx->mem_size_left = PAGE_SIZE;
@@ -155,10 +142,6 @@
 	}
 
 	ctx->mem_size_left = 0;
-	if (ctx->vm && ctx->total_mem) {
-		ctx->total_mem = 0;
-		ctx->vm_size_left = 0;
-	}
 }
 
 /**
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/vmwgfx/vmwgfx_validation.h
@@ -52,10 +52,6 @@
  * buffer objects
  * @mem_size_left: Free memory left in the last page in @page_list
  * @page_address: Kernel virtual address of the last page in @page_list
- * @vm: A pointer to the memory reservation interface or NULL if no
- * memory reservation is needed.
- * @vm_size_left: Amount of reserved memory that so far has not been allocated.
- * @total_mem: Amount of reserved memory.
  */
 struct vmw_validation_context {
 	struct vmw_sw_context *sw_context;
@@ -68,9 +64,6 @@
 	unsigned int merge_dups;
 	unsigned int mem_size_left;
 	u8 *page_address;
-	struct vmw_validation_mem *vm;
-	size_t vm_size_left;
-	size_t total_mem;
 };
 
 struct vmw_bo;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/Makefile
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/Makefile
@@ -35,27 +35,15 @@
 subdir-ccflags-y += -I$(obj) -I$(srctree)/$(src)
 
 # generated sources
-hostprogs := xe_gen_wa_oob
 
+hostprogs := xe_gen_wa_oob
 generated_oob := $(obj)/generated/xe_wa_oob.c $(obj)/generated/xe_wa_oob.h
-
 quiet_cmd_wa_oob = GEN     $(notdir $(generated_oob))
       cmd_wa_oob = mkdir -p $(@D); $^ $(generated_oob)
-
-$(generated_oob) &: $(obj)/xe_gen_wa_oob $(srctree)/$(src)/xe_wa_oob.rules
+$(obj)/generated/%_wa_oob.c $(obj)/generated/%_wa_oob.h: $(obj)/xe_gen_wa_oob \
+		 $(srctree)/$(src)/xe_wa_oob.rules
 	$(call cmd,wa_oob)
 
-uses_generated_oob := \
-	$(obj)/xe_gsc.o \
-	$(obj)/xe_guc.o \
-	$(obj)/xe_migrate.o \
-	$(obj)/xe_ring_ops.o \
-	$(obj)/xe_vm.o \
-	$(obj)/xe_wa.o \
-	$(obj)/xe_ttm_stolen_mgr.o
-
-$(uses_generated_oob): $(generated_oob)
-
 # Please keep these build lists sorted!
 
 # core driver code
@@ -161,8 +149,8 @@
 	-Ddrm_i915_gem_object=xe_bo \
 	-Ddrm_i915_private=xe_device
 
-CFLAGS_i915-display/intel_fbdev.o = $(call cc-disable-warning, override-init)
-CFLAGS_i915-display/intel_display_device.o = $(call cc-disable-warning, override-init)
+CFLAGS_i915-display/intel_fbdev.o = -Wno-override-init
+CFLAGS_i915-display/intel_display_device.o = -Wno-override-init
 
 # Rule to build SOC code shared with i915
 $(obj)/i915-soc/%.o: $(srctree)/drivers/gpu/drm/i915/soc/%.c FORCE
@@ -302,3 +290,6 @@
 
 $(obj)/%.hdrtest: $(src)/%.h FORCE
 	$(call if_changed_dep,hdrtest)
+
+uses_generated_oob := $(addprefix $(obj)/, $(xe-y))
+$(uses_generated_oob): $(obj)/generated/xe_wa_oob.h
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/compat-i915-headers/i915_drv.h
@@ -84,7 +84,8 @@
 #define IS_ROCKETLAKE(dev_priv)	IS_PLATFORM(dev_priv, XE_ROCKETLAKE)
 #define IS_DG1(dev_priv)        IS_PLATFORM(dev_priv, XE_DG1)
 #define IS_ALDERLAKE_S(dev_priv) IS_PLATFORM(dev_priv, XE_ALDERLAKE_S)
-#define IS_ALDERLAKE_P(dev_priv) IS_PLATFORM(dev_priv, XE_ALDERLAKE_P)
+#define IS_ALDERLAKE_P(dev_priv) (IS_PLATFORM(dev_priv, XE_ALDERLAKE_P) || \
+				  IS_PLATFORM(dev_priv, XE_ALDERLAKE_N))
 #define IS_XEHPSDV(dev_priv) (dev_priv && 0)
 #define IS_DG2(dev_priv)	IS_PLATFORM(dev_priv, XE_DG2)
 #define IS_PONTEVECCHIO(dev_priv) IS_PLATFORM(dev_priv, XE_PVC)
@@ -108,7 +109,7 @@
 #define HAS_GMD_ID(xe) GRAPHICS_VERx100(xe) >= 1270
 
 /* Workarounds not handled yet */
-#define IS_DISPLAY_STEP(xe, first, last) ({u8 __step = (xe)->info.step.display; first <= __step && __step <= last; })
+#define IS_DISPLAY_STEP(xe, first, last) ({u8 __step = (xe)->info.step.display; first <= __step && __step < last; })
 #define IS_GRAPHICS_STEP(xe, first, last) ({u8 __step = (xe)->info.step.graphics; first <= __step && __step <= last; })
 
 #define IS_LP(xe) (0)
@@ -214,7 +215,6 @@
 	     intel_runtime_pm_put((rpm), (wf)), (wf) = 0)
 
 #define pdev_to_i915 pdev_to_xe_device
-#define RUNTIME_INFO(xe)		(&(xe)->info.i915_runtime)
 
 #define FORCEWAKE_ALL XE_FORCEWAKE_ALL
 #define HPD_STORM_DEFAULT_THRESHOLD 50
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/display/intel_fb_bo.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/display/intel_fb_bo.c
@@ -31,7 +31,7 @@
 
 	ret = ttm_bo_reserve(&bo->ttm, true, false, NULL);
 	if (ret)
-		return ret;
+		goto err;
 
 	if (!(bo->flags & XE_BO_SCANOUT_BIT)) {
 		/*
@@ -42,12 +42,16 @@
 		 */
 		if (XE_IOCTL_DBG(i915, !list_empty(&bo->ttm.base.gpuva.list))) {
 			ttm_bo_unreserve(&bo->ttm);
-			return -EINVAL;
+			ret = -EINVAL;
+			goto err;
 		}
 		bo->flags |= XE_BO_SCANOUT_BIT;
 	}
 	ttm_bo_unreserve(&bo->ttm);
+	return 0;
 
+err:
+	xe_bo_put(bo);
 	return ret;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/regs/xe_engine_regs.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/regs/xe_engine_regs.h
@@ -44,9 +44,10 @@
 #define GSCCS_RING_BASE				0x11a000
 
 #define RING_TAIL(base)				XE_REG((base) + 0x30)
+#define   TAIL_ADDR				REG_GENMASK(20, 3)
 
 #define RING_HEAD(base)				XE_REG((base) + 0x34)
-#define   HEAD_ADDR				0x001FFFFC
+#define   HEAD_ADDR				REG_GENMASK(20, 2)
 
 #define RING_START(base)			XE_REG((base) + 0x38)
 
@@ -120,7 +121,7 @@
 #define RING_EXECLIST_STATUS_LO(base)		XE_REG((base) + 0x234)
 #define RING_EXECLIST_STATUS_HI(base)		XE_REG((base) + 0x234 + 4)
 
-#define RING_CONTEXT_CONTROL(base)		XE_REG((base) + 0x244)
+#define RING_CONTEXT_CONTROL(base)		XE_REG((base) + 0x244, XE_REG_OPTION_MASKED)
 #define	  CTX_CTRL_INHIBIT_SYN_CTX_SWITCH	REG_BIT(3)
 #define	  CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT	REG_BIT(0)
 
@@ -133,7 +134,6 @@
 #define   RING_VALID_MASK			0x00000001
 #define   RING_VALID				0x00000001
 #define   STOP_RING				REG_BIT(8)
-#define   TAIL_ADDR				0x001FFFF8
 
 #define RING_CTX_TIMESTAMP(base)		XE_REG((base) + 0x3a8)
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/regs/xe_gt_regs.h
@@ -78,6 +78,7 @@
 
 #define FF_MODE					XE_REG_MCR(0x6210)
 #define   DIS_TE_AUTOSTRIP			REG_BIT(31)
+#define   VS_HIT_MAX_VALUE_MASK			REG_GENMASK(25, 20)
 #define   DIS_MESH_PARTIAL_AUTOSTRIP		REG_BIT(16)
 #define   DIS_MESH_AUTOSTRIP			REG_BIT(15)
 
@@ -327,6 +328,7 @@
 
 #define HALF_SLICE_CHICKEN7				XE_REG_MCR(0xe194, XE_REG_OPTION_MASKED)
 #define   DG2_DISABLE_ROUND_ENABLE_ALLOW_FOR_SSLA	REG_BIT(15)
+#define   CLEAR_OPTIMIZATION_DISABLE			REG_BIT(6)
 
 #define CACHE_MODE_SS				XE_REG_MCR(0xe420, XE_REG_OPTION_MASKED)
 #define   DISABLE_ECC				REG_BIT(5)
@@ -392,7 +394,7 @@
  *   [4-6]     RSVD
  *   [7]       Disabled
  */
-#define CCS_MODE				XE_REG(0x14804)
+#define CCS_MODE				XE_REG(0x14804, XE_REG_OPTION_MASKED)
 #define   CCS_MODE_CSLICE_0_3_MASK		REG_GENMASK(11, 0) /* 3 bits per cslice */
 #define   CCS_MODE_CSLICE_MASK			0x7 /* CCS0-3 + rsvd */
 #define   CCS_MODE_CSLICE_WIDTH			ilog2(CCS_MODE_CSLICE_MASK + 1)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/tests/xe_dma_buf.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/tests/xe_dma_buf.c
@@ -12,6 +12,7 @@
 #include "tests/xe_pci_test.h"
 
 #include "xe_pci.h"
+#include "xe_pm.h"
 
 static bool p2p_enabled(struct dma_buf_test_params *params)
 {
@@ -259,6 +260,7 @@
 	const struct dma_buf_test_params *params;
 	struct kunit *test = xe_cur_kunit();
 
+	xe_pm_runtime_get(xe);
 	for (params = test_params; params->mem_mask; ++params) {
 		struct dma_buf_test_params p = *params;
 
@@ -266,6 +268,7 @@
 		test->priv = &p;
 		xe_test_dmabuf_import_same_driver(xe);
 	}
+	xe_pm_runtime_put(xe);
 
 	/* A non-zero return would halt iteration over driver devices */
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/tests/xe_migrate.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/tests/xe_migrate.c
@@ -114,21 +114,21 @@
 						   region |
 						   XE_BO_NEEDS_CPU_ACCESS);
 	if (IS_ERR(remote)) {
-		KUNIT_FAIL(test, "Failed to allocate remote bo for %s: %li\n",
-			   str, PTR_ERR(remote));
+		KUNIT_FAIL(test, "Failed to allocate remote bo for %s: %pe\n",
+			   str, remote);
 		return;
 	}
 
 	err = xe_bo_validate(remote, NULL, false);
 	if (err) {
-		KUNIT_FAIL(test, "Failed to validate system bo for %s: %li\n",
+		KUNIT_FAIL(test, "Failed to validate system bo for %s: %i\n",
 			   str, err);
 		goto out_unlock;
 	}
 
 	err = xe_bo_vmap(remote);
 	if (err) {
-		KUNIT_FAIL(test, "Failed to vmap system bo for %s: %li\n",
+		KUNIT_FAIL(test, "Failed to vmap system bo for %s: %i\n",
 			   str, err);
 		goto out_unlock;
 	}
@@ -303,8 +303,8 @@
 				    XE_BO_CREATE_VRAM_IF_DGFX(tile) |
 				    XE_BO_CREATE_PINNED_BIT);
 	if (IS_ERR(tiny)) {
-		KUNIT_FAIL(test, "Failed to allocate fake pt: %li\n",
-			   PTR_ERR(pt));
+		KUNIT_FAIL(test, "Failed to allocate tiny fake pt: %li\n",
+			   PTR_ERR(tiny));
 		goto free_pt;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_bb.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_bb.c
@@ -65,7 +65,8 @@
 {
 	u32 size = drm_suballoc_size(bb->bo);
 
-	bb->cs[bb->len++] = MI_BATCH_BUFFER_END;
+	if (bb->len == 0 || bb->cs[bb->len - 1] != MI_BATCH_BUFFER_END)
+		bb->cs[bb->len++] = MI_BATCH_BUFFER_END;
 
 	xe_gt_assert(q->gt, bb->len * 4 + bb_prefetch(q->gt) <= size);
 
@@ -96,7 +97,8 @@
 {
 	u64 addr = xe_sa_bo_gpu_addr(bb->bo);
 
-	xe_gt_assert(q->gt, !(q->vm && q->vm->flags & XE_VM_FLAG_MIGRATION));
+	xe_gt_assert(q->gt, !xe_sched_job_is_migration(q));
+	xe_gt_assert(q->gt, q->width == 1);
 	return __xe_bb_create_job(q, bb, &addr);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_bo.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_bo.c
@@ -140,9 +140,6 @@
 			.mem_type = XE_PL_TT,
 		};
 		*c += 1;
-
-		if (bo->props.preferred_mem_type == XE_BO_PROPS_INVALID)
-			bo->props.preferred_mem_type = XE_PL_TT;
 	}
 }
 
@@ -177,25 +174,15 @@
 	}
 	places[*c] = place;
 	*c += 1;
-
-	if (bo->props.preferred_mem_type == XE_BO_PROPS_INVALID)
-		bo->props.preferred_mem_type = mem_type;
 }
 
 static void try_add_vram(struct xe_device *xe, struct xe_bo *bo,
 			 u32 bo_flags, u32 *c)
 {
-	if (bo->props.preferred_gt == XE_GT1) {
-		if (bo_flags & XE_BO_CREATE_VRAM1_BIT)
-			add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM1, c);
-		if (bo_flags & XE_BO_CREATE_VRAM0_BIT)
-			add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM0, c);
-	} else {
-		if (bo_flags & XE_BO_CREATE_VRAM0_BIT)
-			add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM0, c);
-		if (bo_flags & XE_BO_CREATE_VRAM1_BIT)
-			add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM1, c);
-	}
+	if (bo_flags & XE_BO_CREATE_VRAM0_BIT)
+		add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM0, c);
+	if (bo_flags & XE_BO_CREATE_VRAM1_BIT)
+		add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM1, c);
 }
 
 static void try_add_stolen(struct xe_device *xe, struct xe_bo *bo,
@@ -219,17 +206,8 @@
 {
 	u32 c = 0;
 
-	bo->props.preferred_mem_type = XE_BO_PROPS_INVALID;
-
-	/* The order of placements should indicate preferred location */
-
-	if (bo->props.preferred_mem_class == DRM_XE_MEM_REGION_CLASS_SYSMEM) {
-		try_add_system(xe, bo, bo_flags, &c);
-		try_add_vram(xe, bo, bo_flags, &c);
-	} else {
-		try_add_vram(xe, bo, bo_flags, &c);
-		try_add_system(xe, bo, bo_flags, &c);
-	}
+	try_add_vram(xe, bo, bo_flags, &c);
+	try_add_system(xe, bo, bo_flags, &c);
 	try_add_stolen(xe, bo, bo_flags, &c);
 
 	if (!c)
@@ -337,7 +315,7 @@
 	struct xe_device *xe = xe_bo_device(bo);
 	struct xe_ttm_tt *tt;
 	unsigned long extra_pages;
-	enum ttm_caching caching;
+	enum ttm_caching caching = ttm_cached;
 	int err;
 
 	tt = kzalloc(sizeof(*tt), GFP_KERNEL);
@@ -351,26 +329,35 @@
 		extra_pages = DIV_ROUND_UP(xe_device_ccs_bytes(xe, bo->size),
 					   PAGE_SIZE);
 
-	switch (bo->cpu_caching) {
-	case DRM_XE_GEM_CPU_CACHING_WC:
-		caching = ttm_write_combined;
-		break;
-	default:
-		caching = ttm_cached;
-		break;
-	}
-
-	WARN_ON((bo->flags & XE_BO_CREATE_USER_BIT) && !bo->cpu_caching);
-
 	/*
-	 * Display scanout is always non-coherent with the CPU cache.
-	 *
-	 * For Xe_LPG and beyond, PPGTT PTE lookups are also non-coherent and
-	 * require a CPU:WC mapping.
+	 * DGFX system memory is always WB / ttm_cached, since
+	 * other caching modes are only supported on x86. DGFX
+	 * GPU system memory accesses are always coherent with the
+	 * CPU.
 	 */
-	if ((!bo->cpu_caching && bo->flags & XE_BO_SCANOUT_BIT) ||
-	    (xe->info.graphics_verx100 >= 1270 && bo->flags & XE_BO_PAGETABLE))
-		caching = ttm_write_combined;
+	if (!IS_DGFX(xe)) {
+		switch (bo->cpu_caching) {
+		case DRM_XE_GEM_CPU_CACHING_WC:
+			caching = ttm_write_combined;
+			break;
+		default:
+			caching = ttm_cached;
+			break;
+		}
+
+		WARN_ON((bo->flags & XE_BO_CREATE_USER_BIT) && !bo->cpu_caching);
+
+		/*
+		 * Display scanout is always non-coherent with the CPU cache.
+		 *
+		 * For Xe_LPG and beyond, PPGTT PTE lookups are also
+		 * non-coherent and require a CPU:WC mapping.
+		 */
+		if ((!bo->cpu_caching && bo->flags & XE_BO_SCANOUT_BIT) ||
+		    (xe->info.graphics_verx100 >= 1270 &&
+		     bo->flags & XE_BO_PAGETABLE))
+			caching = ttm_write_combined;
+	}
 
 	err = ttm_tt_init(&tt->ttm, &bo->ttm, page_flags, caching, extra_pages);
 	if (err) {
@@ -650,8 +637,8 @@
 	tt_has_data = ttm && (ttm_tt_is_populated(ttm) ||
 			      (ttm->page_flags & TTM_TT_FLAG_SWAPPED));
 
-	move_lacks_source = handle_system_ccs ? (!bo->ccs_cleared)  :
-						(!mem_type_is_vram(old_mem_type) && !tt_has_data);
+	move_lacks_source = !old_mem || (handle_system_ccs ? (!bo->ccs_cleared) :
+					 (!mem_type_is_vram(old_mem_type) && !tt_has_data));
 
 	needs_clear = (ttm && ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC) ||
 		(!ttm && ttm_bo->type == ttm_bo_type_device);
@@ -831,8 +818,8 @@
 	if (WARN_ON(!xe_bo_is_pinned(bo)))
 		return -EINVAL;
 
-	if (WARN_ON(!xe_bo_is_vram(bo)))
-		return -EINVAL;
+	if (!xe_bo_is_vram(bo))
+		return 0;
 
 	ret = ttm_bo_mem_space(&bo->ttm, &placement, &new_mem, &ctx);
 	if (ret)
@@ -886,6 +873,7 @@
 		.interruptible = false,
 	};
 	struct ttm_resource *new_mem;
+	struct ttm_place *place = &bo->placements[0];
 	int ret;
 
 	xe_bo_assert_held(bo);
@@ -896,9 +884,15 @@
 	if (WARN_ON(!xe_bo_is_pinned(bo)))
 		return -EINVAL;
 
-	if (WARN_ON(xe_bo_is_vram(bo) || !bo->ttm.ttm))
+	if (WARN_ON(xe_bo_is_vram(bo)))
+		return -EINVAL;
+
+	if (WARN_ON(!bo->ttm.ttm && !xe_bo_is_stolen(bo)))
 		return -EINVAL;
 
+	if (!mem_type_is_vram(place->mem_type))
+		return 0;
+
 	ret = ttm_bo_mem_space(&bo->ttm, &bo->placement, &new_mem, &ctx);
 	if (ret)
 		return ret;
@@ -1106,19 +1100,12 @@
 	}
 }
 
-static bool should_migrate_to_system(struct xe_bo *bo)
-{
-	struct xe_device *xe = xe_bo_device(bo);
-
-	return xe_device_in_fault_mode(xe) && bo->props.cpu_atomic;
-}
-
 static vm_fault_t xe_gem_fault(struct vm_fault *vmf)
 {
 	struct ttm_buffer_object *tbo = vmf->vma->vm_private_data;
 	struct drm_device *ddev = tbo->base.dev;
 	vm_fault_t ret;
-	int idx, r = 0;
+	int idx;
 
 	ret = ttm_bo_vm_reserve(tbo, vmf);
 	if (ret)
@@ -1129,17 +1116,8 @@
 
 		trace_xe_bo_cpu_fault(bo);
 
-		if (should_migrate_to_system(bo)) {
-			r = xe_bo_migrate(bo, XE_PL_TT);
-			if (r == -EBUSY || r == -ERESTARTSYS || r == -EINTR)
-				ret = VM_FAULT_NOPAGE;
-			else if (r)
-				ret = VM_FAULT_SIGBUS;
-		}
-		if (!ret)
-			ret = ttm_bo_vm_fault_reserved(vmf,
-						       vmf->vma->vm_page_prot,
-						       TTM_BO_VM_NUM_PREFAULT);
+		ret = ttm_bo_vm_fault_reserved(vmf, vmf->vma->vm_page_prot,
+					       TTM_BO_VM_NUM_PREFAULT);
 		drm_dev_exit(idx);
 	} else {
 		ret = ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot);
@@ -1253,9 +1231,6 @@
 	bo->flags = flags;
 	bo->cpu_caching = cpu_caching;
 	bo->ttm.base.funcs = &xe_gem_object_funcs;
-	bo->props.preferred_mem_class = XE_BO_PROPS_INVALID;
-	bo->props.preferred_gt = XE_BO_PROPS_INVALID;
-	bo->props.preferred_mem_type = XE_BO_PROPS_INVALID;
 	bo->ttm.priority = XE_BO_PRIORITY_NORMAL;
 	INIT_LIST_HEAD(&bo->pinned_link);
 #ifdef CONFIG_PROC_FS
@@ -1540,7 +1515,7 @@
 	return bo;
 }
 
-static void __xe_bo_unpin_map_no_vm(struct drm_device *drm, void *arg)
+static void __xe_bo_unpin_map_no_vm(void *arg)
 {
 	xe_bo_unpin_map_no_vm(arg);
 }
@@ -1555,7 +1530,7 @@
 	if (IS_ERR(bo))
 		return bo;
 
-	ret = drmm_add_action_or_reset(&xe->drm, __xe_bo_unpin_map_no_vm, bo);
+	ret = devm_add_action_or_reset(xe->drm.dev, __xe_bo_unpin_map_no_vm, bo);
 	if (ret)
 		return ERR_PTR(ret);
 
@@ -1633,6 +1608,7 @@
 
 int xe_bo_pin(struct xe_bo *bo)
 {
+	struct ttm_place *place = &bo->placements[0];
 	struct xe_device *xe = xe_bo_device(bo);
 	int err;
 
@@ -1663,21 +1639,21 @@
 	 */
 	if (IS_DGFX(xe) && !(IS_ENABLED(CONFIG_DRM_XE_DEBUG) &&
 	    bo->flags & XE_BO_INTERNAL_TEST)) {
-		struct ttm_place *place = &(bo->placements[0]);
-
 		if (mem_type_is_vram(place->mem_type)) {
 			xe_assert(xe, place->flags & TTM_PL_FLAG_CONTIGUOUS);
 
 			place->fpfn = (xe_bo_addr(bo, 0, PAGE_SIZE) -
 				       vram_region_gpu_offset(bo->ttm.resource)) >> PAGE_SHIFT;
 			place->lpfn = place->fpfn + (bo->size >> PAGE_SHIFT);
-
-			spin_lock(&xe->pinned.lock);
-			list_add_tail(&bo->pinned_link, &xe->pinned.kernel_bo_present);
-			spin_unlock(&xe->pinned.lock);
 		}
 	}
 
+	if (mem_type_is_vram(place->mem_type) || bo->flags & XE_BO_CREATE_GGTT_BIT) {
+		spin_lock(&xe->pinned.lock);
+		list_add_tail(&bo->pinned_link, &xe->pinned.kernel_bo_present);
+		spin_unlock(&xe->pinned.lock);
+	}
+
 	ttm_bo_pin(&bo->ttm);
 
 	/*
@@ -1724,24 +1700,19 @@
 
 void xe_bo_unpin(struct xe_bo *bo)
 {
+	struct ttm_place *place = &bo->placements[0];
 	struct xe_device *xe = xe_bo_device(bo);
 
 	xe_assert(xe, !bo->ttm.base.import_attach);
 	xe_assert(xe, xe_bo_is_pinned(bo));
 
-	if (IS_DGFX(xe) && !(IS_ENABLED(CONFIG_DRM_XE_DEBUG) &&
-	    bo->flags & XE_BO_INTERNAL_TEST)) {
-		struct ttm_place *place = &(bo->placements[0]);
+	if (mem_type_is_vram(place->mem_type) || bo->flags & XE_BO_CREATE_GGTT_BIT) {
+		xe_assert(xe, !list_empty(&bo->pinned_link));
 
-		if (mem_type_is_vram(place->mem_type)) {
-			xe_assert(xe, !list_empty(&bo->pinned_link));
-
-			spin_lock(&xe->pinned.lock);
-			list_del_init(&bo->pinned_link);
-			spin_unlock(&xe->pinned.lock);
-		}
+		spin_lock(&xe->pinned.lock);
+		list_del_init(&bo->pinned_link);
+		spin_unlock(&xe->pinned.lock);
 	}
-
 	ttm_bo_unpin(&bo->ttm);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_bo_evict.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_bo_evict.c
@@ -34,14 +34,22 @@
 	u8 id;
 	int ret;
 
-	if (!IS_DGFX(xe))
-		return 0;
-
 	/* User memory */
-	for (mem_type = XE_PL_VRAM0; mem_type <= XE_PL_VRAM1; ++mem_type) {
+	for (mem_type = XE_PL_TT; mem_type <= XE_PL_VRAM1; ++mem_type) {
 		struct ttm_resource_manager *man =
 			ttm_manager_type(bdev, mem_type);
 
+		/*
+		 * On igpu platforms with flat CCS we need to ensure we save and restore any CCS
+		 * state since this state lives inside graphics stolen memory which doesn't survive
+		 * hibernation.
+		 *
+		 * This can be further improved by only evicting objects that we know have actually
+		 * used a compression enabled PAT index.
+		 */
+		if (mem_type == XE_PL_TT && (IS_DGFX(xe) || !xe_device_has_flat_ccs(xe)))
+			continue;
+
 		if (man) {
 			ret = ttm_resource_manager_evict_all(bdev, man);
 			if (ret)
@@ -125,9 +133,6 @@
 	struct xe_bo *bo;
 	int ret;
 
-	if (!IS_DGFX(xe))
-		return 0;
-
 	spin_lock(&xe->pinned.lock);
 	for (;;) {
 		bo = list_first_entry_or_null(&xe->pinned.evicted,
@@ -159,7 +164,6 @@
 		 * should setup the iosys map.
 		 */
 		xe_assert(xe, !iosys_map_is_null(&bo->vmap));
-		xe_assert(xe, xe_bo_is_vram(bo));
 
 		xe_bo_put(bo);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_bo_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_bo_types.h
@@ -56,25 +56,6 @@
 	 */
 	struct list_head client_link;
 #endif
-	/** @props: BO user controlled properties */
-	struct {
-		/** @preferred_mem: preferred memory class for this BO */
-		s16 preferred_mem_class;
-		/** @prefered_gt: preferred GT for this BO */
-		s16 preferred_gt;
-		/** @preferred_mem_type: preferred memory type */
-		s32 preferred_mem_type;
-		/**
-		 * @cpu_atomic: the CPU expects to do atomics operations to
-		 * this BO
-		 */
-		bool cpu_atomic;
-		/**
-		 * @device_atomic: the device expects to do atomics operations
-		 * to this BO
-		 */
-		bool device_atomic;
-	} props;
 	/** @freed: List node for delayed put. */
 	struct llist_node freed;
 	/** @created: Whether the bo has passed initial creation */
@@ -85,7 +66,8 @@
 
 	/**
 	 * @cpu_caching: CPU caching mode. Currently only used for userspace
-	 * objects.
+	 * objects. Exceptions are system memory on DGFX, which is always
+	 * WB.
 	 */
 	u16 cpu_caching;
 };
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_devcoredump.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_devcoredump.c
@@ -62,16 +62,19 @@
 				   size_t count, void *data, size_t datalen)
 {
 	struct xe_devcoredump *coredump = data;
+	struct xe_device *xe;
 	struct xe_devcoredump_snapshot *ss;
 	struct drm_printer p;
 	struct drm_print_iterator iter;
 	struct timespec64 ts;
 	int i;
 
-	/* Our device is gone already... */
-	if (!data || !coredump_to_xe(coredump))
+	if (!coredump)
 		return -ENODEV;
 
+	xe = coredump_to_xe(coredump);
+	ss = &coredump->snapshot;
+
 	iter.data = buffer;
 	iter.offset = 0;
 	iter.start = offset;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_device.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_device.c
@@ -190,12 +190,18 @@
 {
 	struct xe_device *xe = to_xe_device(dev);
 
+	if (xe->preempt_fence_wq)
+		destroy_workqueue(xe->preempt_fence_wq);
+
 	if (xe->ordered_wq)
 		destroy_workqueue(xe->ordered_wq);
 
 	if (xe->unordered_wq)
 		destroy_workqueue(xe->unordered_wq);
 
+	if (xe->destroy_wq)
+		destroy_workqueue(xe->destroy_wq);
+
 	ttm_device_fini(&xe->ttm);
 }
 
@@ -255,9 +261,16 @@
 	INIT_LIST_HEAD(&xe->pinned.external_vram);
 	INIT_LIST_HEAD(&xe->pinned.evicted);
 
+	xe->preempt_fence_wq = alloc_ordered_workqueue("xe-preempt-fence-wq", 0);
 	xe->ordered_wq = alloc_ordered_workqueue("xe-ordered-wq", 0);
 	xe->unordered_wq = alloc_workqueue("xe-unordered-wq", 0, 0);
-	if (!xe->ordered_wq || !xe->unordered_wq) {
+	xe->destroy_wq = alloc_workqueue("xe-destroy-wq", 0, 0);
+	if (!xe->ordered_wq || !xe->unordered_wq ||
+	    !xe->preempt_fence_wq || !xe->destroy_wq) {
+		/*
+		 * Cleanup done in xe_device_destroy via
+		 * drmm_add_action_or_reset register above
+		 */
 		drm_err(&xe->drm, "Failed to allocate xe workqueues\n");
 		err = -ENOMEM;
 		goto err;
@@ -377,8 +390,14 @@
 	return err;
 }
 
-/*
- * Initialize MMIO resources that don't require any knowledge about tile count.
+/**
+ * xe_device_probe_early: Device early probe
+ * @xe: xe device instance
+ *
+ * Initialize MMIO resources that don't require any
+ * knowledge about tile count. Also initialize pcode
+ *
+ * Return: 0 on success, error code on failure
  */
 int xe_device_probe_early(struct xe_device *xe)
 {
@@ -392,6 +411,10 @@
 	if (err)
 		return err;
 
+	err = xe_pcode_probe_early(xe);
+	if (err)
+		return err;
+
 	return 0;
 }
 
@@ -437,7 +460,9 @@
 	if (err)
 		return err;
 
-	xe_mmio_probe_tiles(xe);
+	err = xe_mmio_probe_tiles(xe);
+	if (err)
+		return err;
 
 	xe_ttm_sys_mgr_init(xe);
 
@@ -454,11 +479,8 @@
 	if (err)
 		return err;
 
-	for_each_gt(gt, xe, id) {
-		err = xe_pcode_probe(gt);
-		if (err)
-			return err;
-	}
+	for_each_gt(gt, xe, id)
+		xe_pcode_init(gt);
 
 	err = xe_display_init_noirq(xe);
 	if (err)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_device.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_device.h
@@ -58,7 +58,7 @@
 
 static inline struct xe_gt *xe_tile_get_gt(struct xe_tile *tile, u8 gt_id)
 {
-	if (drm_WARN_ON(&tile_to_xe(tile)->drm, gt_id > XE_MAX_GT_PER_TILE))
+	if (drm_WARN_ON(&tile_to_xe(tile)->drm, gt_id >= XE_MAX_GT_PER_TILE))
 		gt_id = 0;
 
 	return gt_id ? tile->media_gt : tile->primary_gt;
@@ -79,7 +79,7 @@
 	if (MEDIA_VER(xe) >= 13) {
 		gt = xe_tile_get_gt(root_tile, gt_id);
 	} else {
-		if (drm_WARN_ON(&xe->drm, gt_id > XE_MAX_TILES_PER_DEVICE))
+		if (drm_WARN_ON(&xe->drm, gt_id >= XE_MAX_TILES_PER_DEVICE))
 			gt_id = 0;
 
 		gt = xe->tiles[gt_id].primary_gt;
@@ -166,4 +166,18 @@
 
 u32 xe_device_ccs_bytes(struct xe_device *xe, u64 size);
 
+/*
+ * Occasionally it is seen that the G2H worker starts running after a delay of more than
+ * a second even after being queued and activated by the Linux workqueue subsystem. This
+ * leads to G2H timeout error. The root cause of issue lies with scheduling latency of
+ * Lunarlake Hybrid CPU. Issue disappears if we disable Lunarlake atom cores from BIOS
+ * and this is beyond xe kmd.
+ *
+ * TODO: Drop this change once workqueue scheduling delay issue is fixed on LNL Hybrid CPU.
+ */
+#define LNL_FLUSH_WORKQUEUE(wq__) \
+	flush_workqueue(wq__)
+#define LNL_FLUSH_WORK(wrk__) \
+	flush_work(wrk__)
+
 #endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_device_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_device_types.h
@@ -276,12 +276,6 @@
 		u8 has_heci_gscfi:1;
 		/** @skip_guc_pc: Skip GuC based PM feature init */
 		u8 skip_guc_pc:1;
-
-#if IS_ENABLED(CONFIG_DRM_XE_DISPLAY)
-		struct {
-			u32 rawclk_freq;
-		} i915_runtime;
-#endif
 	} info;
 
 	/** @irq: device interrupt state */
@@ -356,12 +350,18 @@
 	/** @ufence_wq: user fence wait queue */
 	wait_queue_head_t ufence_wq;
 
+	/** @preempt_fence_wq: used to serialize preempt fences */
+	struct workqueue_struct *preempt_fence_wq;
+
 	/** @ordered_wq: used to serialize compute mode resume */
 	struct workqueue_struct *ordered_wq;
 
 	/** @unordered_wq: used to serialize unordered work, mostly display */
 	struct workqueue_struct *unordered_wq;
 
+	/** @destroy_wq: used to serialize user destroy work, like queue */
+	struct workqueue_struct *destroy_wq;
+
 	/** @tiles: device tiles */
 	struct xe_tile tiles[XE_MAX_TILES_PER_DEVICE];
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_display.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_display.c
@@ -108,11 +108,6 @@
 	xe->display.hotplug.dp_wq = alloc_ordered_workqueue("xe-dp", 0);
 
 	drmm_mutex_init(&xe->drm, &xe->sb_lock);
-	drmm_mutex_init(&xe->drm, &xe->display.backlight.lock);
-	drmm_mutex_init(&xe->drm, &xe->display.audio.mutex);
-	drmm_mutex_init(&xe->drm, &xe->display.wm.wm_mutex);
-	drmm_mutex_init(&xe->drm, &xe->display.pps.mutex);
-	drmm_mutex_init(&xe->drm, &xe->display.hdcp.hdcp_mutex);
 	xe->enabled_irq_mask = ~0;
 
 	err = drmm_add_action_or_reset(&xe->drm, display_destroy, NULL);
@@ -154,7 +149,7 @@
 		return;
 
 	intel_display_driver_remove_noirq(xe);
-	intel_power_domains_driver_remove(xe);
+	intel_opregion_cleanup(xe);
 }
 
 int xe_display_init_noirq(struct xe_device *xe)
@@ -180,8 +175,10 @@
 	intel_display_device_info_runtime_init(xe);
 
 	err = intel_display_driver_probe_noirq(xe);
-	if (err)
+	if (err) {
+		intel_opregion_cleanup(xe);
 		return err;
+	}
 
 	return drmm_add_action_or_reset(&xe->drm, xe_display_fini_noirq, NULL);
 }
@@ -322,7 +319,28 @@
 	return false;
 }
 
-void xe_display_pm_suspend(struct xe_device *xe)
+static void xe_display_flush_cleanup_work(struct xe_device *xe)
+{
+	struct intel_crtc *crtc;
+
+	for_each_intel_crtc(&xe->drm, crtc) {
+		struct drm_crtc_commit *commit;
+
+		spin_lock(&crtc->base.commit_lock);
+		commit = list_first_entry_or_null(&crtc->base.commit_list,
+						  struct drm_crtc_commit, commit_entry);
+		if (commit)
+			drm_crtc_commit_get(commit);
+		spin_unlock(&crtc->base.commit_lock);
+
+		if (commit) {
+			wait_for_completion(&commit->cleanup_done);
+			drm_crtc_commit_put(commit);
+		}
+	}
+}
+
+void xe_display_pm_suspend(struct xe_device *xe, bool runtime)
 {
 	bool s2idle = suspend_to_idle();
 	if (!xe->info.enable_display)
@@ -336,7 +354,10 @@
 	if (has_display(xe))
 		drm_kms_helper_poll_disable(&xe->drm);
 
-	intel_display_driver_suspend(xe);
+	if (!runtime)
+		intel_display_driver_suspend(xe);
+
+	xe_display_flush_cleanup_work(xe);
 
 	intel_dp_mst_suspend(xe);
 
@@ -372,7 +393,7 @@
 	intel_power_domains_resume(xe);
 }
 
-void xe_display_pm_resume(struct xe_device *xe)
+void xe_display_pm_resume(struct xe_device *xe, bool runtime)
 {
 	if (!xe->info.enable_display)
 		return;
@@ -387,7 +408,8 @@
 
 	/* MST sideband requires HPD interrupts enabled */
 	intel_dp_mst_resume(xe);
-	intel_display_driver_resume(xe);
+	if (!runtime)
+		intel_display_driver_resume(xe);
 
 	intel_hpd_poll_disable(xe);
 	if (has_display(xe))
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_display.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_display.h
@@ -34,10 +34,10 @@
 void xe_display_irq_reset(struct xe_device *xe);
 void xe_display_irq_postinstall(struct xe_device *xe, struct xe_gt *gt);
 
-void xe_display_pm_suspend(struct xe_device *xe);
+void xe_display_pm_suspend(struct xe_device *xe, bool runtime);
 void xe_display_pm_suspend_late(struct xe_device *xe);
 void xe_display_pm_resume_early(struct xe_device *xe);
-void xe_display_pm_resume(struct xe_device *xe);
+void xe_display_pm_resume(struct xe_device *xe, bool runtime);
 
 #else
 
@@ -63,10 +63,10 @@
 static inline void xe_display_irq_reset(struct xe_device *xe) {}
 static inline void xe_display_irq_postinstall(struct xe_device *xe, struct xe_gt *gt) {}
 
-static inline void xe_display_pm_suspend(struct xe_device *xe) {}
+static inline void xe_display_pm_suspend(struct xe_device *xe, bool runtime) {}
 static inline void xe_display_pm_suspend_late(struct xe_device *xe) {}
 static inline void xe_display_pm_resume_early(struct xe_device *xe) {}
-static inline void xe_display_pm_resume(struct xe_device *xe) {}
+static inline void xe_display_pm_resume(struct xe_device *xe, bool runtime) {}
 
 #endif /* CONFIG_DRM_XE_DISPLAY */
 #endif /* _XE_DISPLAY_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_drm_client.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_drm_client.c
@@ -9,6 +9,7 @@
 #include <linux/slab.h>
 #include <linux/types.h>
 
+#include "xe_assert.h"
 #include "xe_bo.h"
 #include "xe_bo_types.h"
 #include "xe_device_types.h"
@@ -78,7 +79,7 @@
 
 	spin_lock(&client->bos_lock);
 	bo->client = xe_drm_client_get(client);
-	list_add_tail_rcu(&bo->client_link, &client->bos_list);
+	list_add_tail(&bo->client_link, &client->bos_list);
 	spin_unlock(&client->bos_lock);
 }
 
@@ -93,10 +94,13 @@
  */
 void xe_drm_client_remove_bo(struct xe_bo *bo)
 {
+	struct xe_device *xe = ttm_to_xe_device(bo->ttm.bdev);
 	struct xe_drm_client *client = bo->client;
 
+	xe_assert(xe, !kref_read(&bo->ttm.base.refcount));
+
 	spin_lock(&client->bos_lock);
-	list_del_rcu(&bo->client_link);
+	list_del_init(&bo->client_link);
 	spin_unlock(&client->bos_lock);
 
 	xe_drm_client_put(client);
@@ -108,6 +112,8 @@
 	u64 sz = bo->size;
 	u32 mem_type;
 
+	xe_bo_assert_held(bo);
+
 	if (bo->placement.placement)
 		mem_type = bo->placement.placement->mem_type;
 	else
@@ -138,6 +144,7 @@
 	struct xe_drm_client *client;
 	struct drm_gem_object *obj;
 	struct xe_bo *bo;
+	LLIST_HEAD(deferred);
 	unsigned int id;
 	u32 mem_type;
 
@@ -148,20 +155,50 @@
 	idr_for_each_entry(&file->object_idr, obj, id) {
 		struct xe_bo *bo = gem_to_xe_bo(obj);
 
-		bo_meminfo(bo, stats);
+		if (dma_resv_trylock(bo->ttm.base.resv)) {
+			bo_meminfo(bo, stats);
+			xe_bo_unlock(bo);
+		} else {
+			xe_bo_get(bo);
+			spin_unlock(&file->table_lock);
+
+			xe_bo_lock(bo, false);
+			bo_meminfo(bo, stats);
+			xe_bo_unlock(bo);
+
+			xe_bo_put(bo);
+			spin_lock(&file->table_lock);
+		}
 	}
 	spin_unlock(&file->table_lock);
 
 	/* Internal objects. */
 	spin_lock(&client->bos_lock);
-	list_for_each_entry_rcu(bo, &client->bos_list, client_link) {
+	list_for_each_entry(bo, &client->bos_list, client_link) {
 		if (!bo || !kref_get_unless_zero(&bo->ttm.base.refcount))
 			continue;
-		bo_meminfo(bo, stats);
-		xe_bo_put(bo);
+
+		if (dma_resv_trylock(bo->ttm.base.resv)) {
+			bo_meminfo(bo, stats);
+			xe_bo_unlock(bo);
+		} else {
+			spin_unlock(&client->bos_lock);
+
+			xe_bo_lock(bo, false);
+			bo_meminfo(bo, stats);
+			xe_bo_unlock(bo);
+
+			spin_lock(&client->bos_lock);
+			/* The bo ref will prevent this bo from being removed from the list */
+			xe_assert(xef->xe, !list_empty(&bo->client_link));
+		}
+
+		xe_bo_put_deferred(bo, &deferred);
 	}
 	spin_unlock(&client->bos_lock);
 
+	xe_bo_put_commit(&deferred);
+
 	for (mem_type = XE_PL_SYSTEM; mem_type < TTM_NUM_MEM_TYPES; ++mem_type) {
 		if (!xe_mem_type_to_name[mem_type])
 			continue;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_exec.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_exec.c
@@ -40,11 +40,6 @@
  * user knows an exec writes to a BO and reads from the BO in the next exec, it
  * is the user's responsibility to pass in / out fence between the two execs).
  *
- * Implicit dependencies for external BOs are handled by using the dma-buf
- * implicit dependency uAPI (TODO: add link). To make this works each exec must
- * install the job's fence into the DMA_RESV_USAGE_WRITE slot of every external
- * BO mapped in the VM.
- *
  * We do not allow a user to trigger a bind at exec time rather we have a VM
  * bind IOCTL which uses the same in / out fence interface as exec. In that
  * sense, a VM bind is basically the same operation as an exec from the user
@@ -58,8 +53,8 @@
  * behind any pending kernel operations on any external BOs in VM or any BOs
  * private to the VM. This is accomplished by the rebinds waiting on BOs
  * DMA_RESV_USAGE_KERNEL slot (kernel ops) and kernel ops waiting on all BOs
- * slots (inflight execs are in the DMA_RESV_USAGE_BOOKING for private BOs and
- * in DMA_RESV_USAGE_WRITE for external BOs).
+ * slots (inflight execs are in the DMA_RESV_USAGE_BOOKKEEP for private BOs and
+ * for external BOs).
  *
  * Rebinds / dma-resv usage applies to non-compute mode VMs only as for compute
  * mode VMs we use preempt fences and a rebind worker (TODO: add link).
@@ -111,9 +106,8 @@
 	u64 addresses[XE_HW_ENGINE_MAX_INSTANCE];
 	struct drm_gpuvm_exec vm_exec = {.extra.fn = xe_exec_fn};
 	struct drm_exec *exec = &vm_exec.exec;
-	u32 i, num_syncs = 0, num_ufence = 0;
+	u32 i, num_syncs, num_ufence = 0;
 	struct xe_sched_job *job;
-	struct dma_fence *rebind_fence;
 	struct xe_vm *vm;
 	bool write_locked, skip_retry = false;
 	ktime_t end = 0;
@@ -128,12 +122,16 @@
 	if (XE_IOCTL_DBG(xe, !q))
 		return -ENOENT;
 
-	if (XE_IOCTL_DBG(xe, q->flags & EXEC_QUEUE_FLAG_VM))
-		return -EINVAL;
+	if (XE_IOCTL_DBG(xe, q->flags & EXEC_QUEUE_FLAG_VM)) {
+		err = -EINVAL;
+		goto err_exec_queue;
+	}
 
 	if (XE_IOCTL_DBG(xe, args->num_batch_buffer &&
-			 q->width != args->num_batch_buffer))
-		return -EINVAL;
+			 q->width != args->num_batch_buffer)) {
+		err = -EINVAL;
+		goto err_exec_queue;
+	}
 
 	if (XE_IOCTL_DBG(xe, q->flags & EXEC_QUEUE_FLAG_BANNED)) {
 		err = -ECANCELED;
@@ -150,15 +148,15 @@
 
 	vm = q->vm;
 
-	for (i = 0; i < args->num_syncs; i++) {
-		err = xe_sync_entry_parse(xe, xef, &syncs[num_syncs++],
-					  &syncs_user[i], SYNC_PARSE_FLAG_EXEC |
+	for (num_syncs = 0; num_syncs < args->num_syncs; num_syncs++) {
+		err = xe_sync_entry_parse(xe, xef, &syncs[num_syncs],
+					  &syncs_user[num_syncs], SYNC_PARSE_FLAG_EXEC |
 					  (xe_vm_in_lr_mode(vm) ?
 					   SYNC_PARSE_FLAG_LR_MODE : 0));
 		if (err)
 			goto err_syncs;
 
-		if (xe_sync_is_ufence(&syncs[i]))
+		if (xe_sync_is_ufence(&syncs[num_syncs]))
 			num_ufence++;
 	}
 
@@ -196,6 +194,30 @@
 			goto err_unlock_list;
 	}
 
+	if (!args->num_batch_buffer) {
+		err = xe_vm_lock(vm, true);
+		if (err)
+			goto err_unlock_list;
+
+		if (!xe_vm_in_lr_mode(vm)) {
+			struct dma_fence *fence;
+
+			fence = xe_sync_in_fence_get(syncs, num_syncs, q, vm);
+			if (IS_ERR(fence)) {
+				err = PTR_ERR(fence);
+				xe_vm_unlock(vm);
+				goto err_unlock_list;
+			}
+			for (i = 0; i < num_syncs; i++)
+				xe_sync_entry_signal(&syncs[i], NULL, fence);
+			xe_exec_queue_last_fence_set(q, vm, fence);
+			dma_fence_put(fence);
+		}
+
+		xe_vm_unlock(vm);
+		goto err_unlock_list;
+	}
+
 	vm_exec.vm = &vm->gpuvm;
 	vm_exec.num_fences = 1 + vm->xe->info.tile_count;
 	vm_exec.flags = DRM_EXEC_INTERRUPTIBLE_WAIT;
@@ -216,24 +238,6 @@
 		goto err_exec;
 	}
 
-	if (!args->num_batch_buffer) {
-		if (!xe_vm_in_lr_mode(vm)) {
-			struct dma_fence *fence;
-
-			fence = xe_sync_in_fence_get(syncs, num_syncs, q, vm);
-			if (IS_ERR(fence)) {
-				err = PTR_ERR(fence);
-				goto err_exec;
-			}
-			for (i = 0; i < num_syncs; i++)
-				xe_sync_entry_signal(&syncs[i], NULL, fence);
-			xe_exec_queue_last_fence_set(q, vm, fence);
-			dma_fence_put(fence);
-		}
-
-		goto err_exec;
-	}
-
 	if (xe_exec_queue_is_lr(q) && xe_exec_queue_ring_full(q)) {
 		err = -EWOULDBLOCK;	/* Aliased to -EAGAIN */
 		skip_retry = true;
@@ -251,35 +255,11 @@
 	 * Rebind any invalidated userptr or evicted BOs in the VM, non-compute
 	 * VM mode only.
 	 */
-	rebind_fence = xe_vm_rebind(vm, false);
-	if (IS_ERR(rebind_fence)) {
-		err = PTR_ERR(rebind_fence);
+	err = xe_vm_rebind(vm, false);
+	if (err)
 		goto err_put_job;
-	}
 
-	/*
-	 * We store the rebind_fence in the VM so subsequent execs don't get
-	 * scheduled before the rebinds of userptrs / evicted BOs is complete.
-	 */
-	if (rebind_fence) {
-		dma_fence_put(vm->rebind_fence);
-		vm->rebind_fence = rebind_fence;
-	}
-	if (vm->rebind_fence) {
-		if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
-			     &vm->rebind_fence->flags)) {
-			dma_fence_put(vm->rebind_fence);
-			vm->rebind_fence = NULL;
-		} else {
-			dma_fence_get(vm->rebind_fence);
-			err = drm_sched_job_add_dependency(&job->drm,
-							   vm->rebind_fence);
-			if (err)
-				goto err_put_job;
-		}
-	}
-
-	/* Wait behind munmap style rebinds */
+	/* Wait behind rebinds */
 	if (!xe_vm_in_lr_mode(vm)) {
 		err = drm_sched_job_add_resv_dependencies(&job->drm,
 							  xe_vm_resv(vm),
@@ -314,7 +294,8 @@
 	xe_sched_job_arm(job);
 	if (!xe_vm_in_lr_mode(vm))
 		drm_gpuvm_resv_add_fence(&vm->gpuvm, exec, &job->drm.s_fence->finished,
-					 DMA_RESV_USAGE_BOOKKEEP, DMA_RESV_USAGE_WRITE);
+					 DMA_RESV_USAGE_BOOKKEEP,
+					 DMA_RESV_USAGE_BOOKKEEP);
 
 	for (i = 0; i < num_syncs; i++)
 		xe_sync_entry_signal(&syncs[i], job,
@@ -349,8 +330,8 @@
 	if (err == -EAGAIN && !skip_retry)
 		goto retry;
 err_syncs:
-	for (i = 0; i < num_syncs; i++)
-		xe_sync_entry_cleanup(&syncs[i]);
+	while (num_syncs--)
+		xe_sync_entry_cleanup(&syncs[num_syncs]);
 	kfree(syncs);
 err_exec_queue:
 	xe_exec_queue_put(q);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_exec_queue.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_exec_queue.c
@@ -60,12 +60,14 @@
 	q->fence_irq = &gt->fence_irq[hwe->class];
 	q->ring_ops = gt->ring_ops[hwe->class];
 	q->ops = gt->exec_queue_ops;
-	INIT_LIST_HEAD(&q->compute.link);
+	INIT_LIST_HEAD(&q->lr.link);
 	INIT_LIST_HEAD(&q->multi_gt_link);
 
 	q->sched_props.timeslice_us = hwe->eclass->sched_props.timeslice_us;
 	q->sched_props.preempt_timeout_us =
 				hwe->eclass->sched_props.preempt_timeout_us;
+	q->sched_props.job_timeout_ms =
+				hwe->eclass->sched_props.job_timeout_ms;
 	if (q->flags & EXEC_QUEUE_FLAG_KERNEL &&
 	    q->flags & EXEC_QUEUE_FLAG_HIGH_PRIORITY)
 		q->sched_props.priority = XE_EXEC_QUEUE_PRIORITY_KERNEL;
@@ -389,34 +391,6 @@
 	return 0;
 }
 
-static const enum xe_engine_class user_to_xe_engine_class[] = {
-	[DRM_XE_ENGINE_CLASS_RENDER] = XE_ENGINE_CLASS_RENDER,
-	[DRM_XE_ENGINE_CLASS_COPY] = XE_ENGINE_CLASS_COPY,
-	[DRM_XE_ENGINE_CLASS_VIDEO_DECODE] = XE_ENGINE_CLASS_VIDEO_DECODE,
-	[DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE] = XE_ENGINE_CLASS_VIDEO_ENHANCE,
-	[DRM_XE_ENGINE_CLASS_COMPUTE] = XE_ENGINE_CLASS_COMPUTE,
-};
-
-static struct xe_hw_engine *
-find_hw_engine(struct xe_device *xe,
-	       struct drm_xe_engine_class_instance eci)
-{
-	u32 idx;
-
-	if (eci.engine_class > ARRAY_SIZE(user_to_xe_engine_class))
-		return NULL;
-
-	if (eci.gt_id >= xe->info.gt_count)
-		return NULL;
-
-	idx = array_index_nospec(eci.engine_class,
-				 ARRAY_SIZE(user_to_xe_engine_class));
-
-	return xe_gt_hw_engine(xe_device_get_gt(xe, eci.gt_id),
-			       user_to_xe_engine_class[idx],
-			       eci.engine_instance, true);
-}
-
 static u32 bind_exec_queue_logical_mask(struct xe_device *xe, struct xe_gt *gt,
 					struct drm_xe_engine_class_instance *eci,
 					u16 width, u16 num_placements)
@@ -438,8 +412,7 @@
 		if (xe_hw_engine_is_reserved(hwe))
 			continue;
 
-		if (hwe->class ==
-		    user_to_xe_engine_class[DRM_XE_ENGINE_CLASS_COPY])
+		if (hwe->class == XE_ENGINE_CLASS_COPY)
 			logical_mask |= BIT(hwe->logical_instance);
 	}
 
@@ -468,7 +441,7 @@
 
 			n = j * width + i;
 
-			hwe = find_hw_engine(xe, eci[n]);
+			hwe = xe_hw_engine_lookup(xe, eci[n]);
 			if (XE_IOCTL_DBG(xe, !hwe))
 				return 0;
 
@@ -546,7 +519,7 @@
 			if (XE_IOCTL_DBG(xe, !logical_mask))
 				return -EINVAL;
 
-			hwe = find_hw_engine(xe, eci[0]);
+			hwe = xe_hw_engine_lookup(xe, eci[0]);
 			if (XE_IOCTL_DBG(xe, !hwe))
 				return -EINVAL;
 
@@ -585,7 +558,7 @@
 		if (XE_IOCTL_DBG(xe, !logical_mask))
 			return -EINVAL;
 
-		hwe = find_hw_engine(xe, eci[0]);
+		hwe = xe_hw_engine_lookup(xe, eci[0]);
 		if (XE_IOCTL_DBG(xe, !hwe))
 			return -EINVAL;
 
@@ -613,8 +586,7 @@
 			return PTR_ERR(q);
 
 		if (xe_vm_in_preempt_fence_mode(vm)) {
-			q->compute.context = dma_fence_context_alloc(1);
-			spin_lock_init(&q->compute.lock);
+			q->lr.context = dma_fence_context_alloc(1);
 
 			err = xe_vm_add_compute_exec_queue(vm, q);
 			if (XE_IOCTL_DBG(xe, err))
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_exec_queue_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_exec_queue_types.h
@@ -132,11 +132,13 @@
 		u32 timeslice_us;
 		/** @preempt_timeout_us: preemption timeout in micro-seconds */
 		u32 preempt_timeout_us;
+		/** @job_timeout_ms: job timeout in milliseconds */
+		u32 job_timeout_ms;
 		/** @priority: priority of this exec queue */
 		enum xe_exec_queue_priority priority;
 	} sched_props;
 
-	/** @compute: compute exec queue state */
+	/** @lr: long-running exec queue state */
 	struct {
 		/** @pfence: preemption fence */
 		struct dma_fence *pfence;
@@ -146,9 +148,7 @@
 		u32 seqno;
 		/** @link: link into VM's list of exec queues */
 		struct list_head link;
-		/** @lock: preemption fences lock */
-		spinlock_t lock;
-	} compute;
+	} lr;
 
 	/** @ops: submission backend exec queue operations */
 	const struct xe_exec_queue_ops *ops;
@@ -157,6 +157,11 @@
 	const struct xe_ring_ops *ring_ops;
 	/** @entity: DRM sched entity for this exec queue (1 to 1 relationship) */
 	struct drm_sched_entity *entity;
+	/**
+	 * @tlb_flush_seqno: The seqno of the last rebind tlb flush performed
+	 * Protected by @vm's resv. Unused if @vm == NULL.
+	 */
+	u64 tlb_flush_seqno;
 	/** @lrc: logical ring context for this exec queue */
 	struct xe_lrc lrc[];
 };
@@ -188,9 +193,11 @@
 	int (*suspend)(struct xe_exec_queue *q);
 	/**
 	 * @suspend_wait: Wait for an exec queue to suspend executing, should be
-	 * call after suspend.
+	 * call after suspend. In dma-fencing path thus must return within a
+	 * reasonable amount of time. -ETIME return shall indicate an error
+	 * waiting for suspend resulting in associated VM getting killed.
 	 */
-	void (*suspend_wait)(struct xe_exec_queue *q);
+	int (*suspend_wait)(struct xe_exec_queue *q);
 	/**
 	 * @resume: Resume exec queue execution, exec queue must be in a suspended
 	 * state and dma fence returned from most recent suspend call must be
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_execlist.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_execlist.c
@@ -429,10 +429,11 @@
 	return 0;
 }
 
-static void execlist_exec_queue_suspend_wait(struct xe_exec_queue *q)
+static int execlist_exec_queue_suspend_wait(struct xe_exec_queue *q)
 
 {
 	/* NIY */
+	return 0;
 }
 
 static void execlist_exec_queue_resume(struct xe_exec_queue *q)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_force_wake.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_force_wake.h
@@ -24,14 +24,25 @@
 xe_force_wake_ref(struct xe_force_wake *fw,
 		  enum xe_force_wake_domains domain)
 {
-	xe_gt_assert(fw->gt, domain);
+	xe_gt_assert(fw->gt, domain != XE_FORCEWAKE_ALL);
 	return fw->domains[ffs(domain) - 1].ref;
 }
 
+/**
+ * xe_force_wake_assert_held - asserts domain is awake
+ * @fw : xe_force_wake structure
+ * @domain: xe_force_wake_domains apart from XE_FORCEWAKE_ALL
+ *
+ * xe_force_wake_assert_held() is designed to confirm a particular
+ * forcewake domain's wakefulness; it doesn't verify the wakefulness of
+ * multiple domains. Make sure the caller doesn't input multiple
+ * domains(XE_FORCEWAKE_ALL) as a parameter.
+ */
 static inline void
 xe_force_wake_assert_held(struct xe_force_wake *fw,
 			  enum xe_force_wake_domains domain)
 {
+	xe_gt_assert(fw->gt, domain != XE_FORCEWAKE_ALL);
 	xe_gt_assert(fw->gt, fw->awake_domains & domain);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_gpu_scheduler.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_gpu_scheduler.c
@@ -90,6 +90,11 @@
 	cancel_work_sync(&sched->work_process_msg);
 }
 
+void xe_sched_submission_resume_tdr(struct xe_gpu_scheduler *sched)
+{
+	drm_sched_resume_timeout(&sched->base, sched->base.timeout);
+}
+
 void xe_sched_add_msg(struct xe_gpu_scheduler *sched,
 		      struct xe_sched_msg *msg)
 {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_gpu_scheduler.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_gpu_scheduler.h
@@ -22,6 +22,8 @@
 void xe_sched_submission_start(struct xe_gpu_scheduler *sched);
 void xe_sched_submission_stop(struct xe_gpu_scheduler *sched);
 
+void xe_sched_submission_resume_tdr(struct xe_gpu_scheduler *sched);
+
 void xe_sched_add_msg(struct xe_gpu_scheduler *sched,
 		      struct xe_sched_msg *msg);
 
@@ -49,7 +51,9 @@
 static inline void xe_sched_add_pending_job(struct xe_gpu_scheduler *sched,
 					    struct xe_sched_job *job)
 {
+	spin_lock(&sched->base.job_list_lock);
 	list_add(&job->drm.list, &sched->base.pending_list);
+	spin_unlock(&sched->base.job_list_lock);
 }
 
 static inline
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_gsc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_gsc.c
@@ -391,10 +391,22 @@
 void xe_gsc_load_start(struct xe_gsc *gsc)
 {
 	struct xe_gt *gt = gsc_to_gt(gsc);
+	struct xe_device *xe = gt_to_xe(gt);
 
 	if (!xe_uc_fw_is_loadable(&gsc->fw) || !gsc->q)
 		return;
 
+	/*
+	 * The GSC HW is only reset by driver FLR or D3cold entry. We don't
+	 * support the former at runtime, while the latter is only supported on
+	 * DGFX, for which we don't support GSC. Therefore, if GSC failed to
+	 * load previously there is no need to try again because the HW is
+	 * stuck in the error state.
+	 */
+	xe_assert(xe, !IS_DGFX(xe));
+	if (xe_uc_fw_is_in_error_state(&gsc->fw))
+		return;
+
 	/* GSC FW survives GT reset and D3Hot */
 	if (gsc_fw_is_loaded(gt)) {
 		xe_uc_fw_change_status(&gsc->fw, XE_UC_FIRMWARE_TRANSFERRED);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_gt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_gt.c
@@ -384,7 +384,9 @@
 			 err);
 
 	/* Initialize CCS mode sysfs after early initialization of HW engines */
-	xe_gt_ccs_mode_sysfs_init(gt);
+	err = xe_gt_ccs_mode_sysfs_init(gt);
+	if (err)
+		goto err_force_wake;
 
 	err = xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
 	XE_WARN_ON(err);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_ccs_mode.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_gt_ccs_mode.c
@@ -66,10 +66,16 @@
 		}
 	}
 
+	/*
+	 * Mask bits need to be set for the register. Though only Xe2+
+	 * platforms require setting of mask bits, it won't harm for older
+	 * platforms as these bits are unused there.
+	 */
+	mode |= CCS_MODE_CSLICE_0_3_MASK << 16;
 	xe_mmio_write32(gt, CCS_MODE, mode);
 
-	xe_gt_info(gt, "CCS_MODE=%x config:%08x, num_engines:%d, num_slices:%d\n",
-		   mode, config, num_engines, num_slices);
+	xe_gt_dbg(gt, "CCS_MODE=%x config:%08x, num_engines:%d, num_slices:%d\n",
+		  mode, config, num_engines, num_slices);
 }
 
 void xe_gt_apply_ccs_mode(struct xe_gt *gt)
@@ -167,25 +173,20 @@
  * and it is expected that there are no open drm clients while doing so.
  * The number of available compute slices is exposed to user through a per-gt
  * 'num_cslices' sysfs interface.
+ *
+ * Returns: Returns error value for failure and 0 for success.
  */
-void xe_gt_ccs_mode_sysfs_init(struct xe_gt *gt)
+int xe_gt_ccs_mode_sysfs_init(struct xe_gt *gt)
 {
 	struct xe_device *xe = gt_to_xe(gt);
 	int err;
 
 	if (!xe_gt_ccs_mode_enabled(gt))
-		return;
+		return 0;
 
 	err = sysfs_create_files(gt->sysfs, gt_ccs_mode_attrs);
-	if (err) {
-		drm_warn(&xe->drm, "Sysfs creation for ccs_mode failed err: %d\n", err);
-		return;
-	}
+	if (err)
+		return err;
 
-	err = drmm_add_action_or_reset(&xe->drm, xe_gt_ccs_mode_sysfs_fini, gt);
-	if (err) {
-		sysfs_remove_files(gt->sysfs, gt_ccs_mode_attrs);
-		drm_warn(&xe->drm, "%s: drmm_add_action_or_reset failed, err: %d\n",
-			 __func__, err);
-	}
+	return drmm_add_action_or_reset(&xe->drm, xe_gt_ccs_mode_sysfs_fini, gt);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_ccs_mode.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_gt_ccs_mode.h
@@ -12,7 +12,7 @@
 #include "xe_platform_types.h"
 
 void xe_gt_apply_ccs_mode(struct xe_gt *gt);
-void xe_gt_ccs_mode_sysfs_init(struct xe_gt *gt);
+int xe_gt_ccs_mode_sysfs_init(struct xe_gt *gt);
 
 static inline bool xe_gt_ccs_mode_enabled(const struct xe_gt *gt)
 {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_idle.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_gt_idle.c
@@ -126,6 +126,13 @@
 static void gt_idle_sysfs_fini(struct drm_device *drm, void *arg)
 {
 	struct kobject *kobj = arg;
+	struct xe_gt *gt = kobj_to_gt(kobj->parent);
+
+	if (gt_to_xe(gt)->info.skip_guc_pc) {
+		XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FW_GT));
+		xe_gt_idle_disable_c6(gt);
+		xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
+	}
 
 	sysfs_remove_files(kobj, gt_idle_attrs);
 	kobject_put(kobj);
@@ -184,7 +191,7 @@
 void xe_gt_idle_disable_c6(struct xe_gt *gt)
 {
 	xe_device_assert_mem_access(gt_to_xe(gt));
-	xe_force_wake_assert_held(gt_to_fw(gt), XE_FORCEWAKE_ALL);
+	xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GT);
 
 	xe_mmio_write32(gt, PG_ENABLE, 0);
 	xe_mmio_write32(gt, RC_CONTROL, 0);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_mcr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_gt_mcr.c
@@ -6,6 +6,7 @@
 #include "xe_gt_mcr.h"
 
 #include "regs/xe_gt_regs.h"
+#include "xe_assert.h"
 #include "xe_gt.h"
 #include "xe_gt_topology.h"
 #include "xe_gt_types.h"
@@ -291,14 +292,40 @@
 	gt->steering[LNCF].instance_target = 0;		/* unused */
 }
 
-static void init_steering_dss(struct xe_gt *gt)
+static unsigned int dss_per_group(struct xe_gt *gt)
+{
+	if (gt_to_xe(gt)->info.platform == XE_PVC)
+		return 8;
+	else if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1250)
+		return 4;
+	else
+		return 6;
+}
+
+/**
+ * xe_gt_mcr_get_dss_steering - Get the group/instance steering for a DSS
+ * @gt: GT structure
+ * @dss: DSS ID to obtain steering for
+ * @group: pointer to storage for steering group ID
+ * @instance: pointer to storage for steering instance ID
+ */
+void xe_gt_mcr_get_dss_steering(struct xe_gt *gt, unsigned int dss, u16 *group, u16 *instance)
 {
-	unsigned int dss = min(xe_dss_mask_group_ffs(gt->fuse_topo.g_dss_mask, 0, 0),
-			       xe_dss_mask_group_ffs(gt->fuse_topo.c_dss_mask, 0, 0));
-	unsigned int dss_per_grp = gt_to_xe(gt)->info.platform == XE_PVC ? 8 : 4;
+	int dss_per_grp = dss_per_group(gt);
+
+	xe_gt_assert(gt, dss < XE_MAX_DSS_FUSE_BITS);
+
+	*group = dss / dss_per_grp;
+	*instance = dss % dss_per_grp;
+}
 
-	gt->steering[DSS].group_target = dss / dss_per_grp;
-	gt->steering[DSS].instance_target = dss % dss_per_grp;
+static void init_steering_dss(struct xe_gt *gt)
+{
+	xe_gt_mcr_get_dss_steering(gt,
+				   min(xe_dss_mask_group_ffs(gt->fuse_topo.g_dss_mask, 0, 0),
+				       xe_dss_mask_group_ffs(gt->fuse_topo.c_dss_mask, 0, 0)),
+				   &gt->steering[DSS].group_target,
+				   &gt->steering[DSS].instance_target);
 }
 
 static void init_steering_oaddrm(struct xe_gt *gt)
@@ -312,7 +339,7 @@
 	else
 		gt->steering[OADDRM].group_target = 1;
 
-	gt->steering[DSS].instance_target = 0;		/* unused */
+	gt->steering[OADDRM].instance_target = 0;	/* unused */
 }
 
 static void init_steering_sqidi_psmi(struct xe_gt *gt)
@@ -327,8 +354,8 @@
 
 static void init_steering_inst0(struct xe_gt *gt)
 {
-	gt->steering[DSS].group_target = 0;		/* unused */
-	gt->steering[DSS].instance_target = 0;		/* unused */
+	gt->steering[INSTANCE0].group_target = 0;	/* unused */
+	gt->steering[INSTANCE0].instance_target = 0;	/* unused */
 }
 
 static const struct {
@@ -357,7 +384,7 @@
 	if (gt->info.type == XE_GT_TYPE_MEDIA) {
 		drm_WARN_ON(&xe->drm, MEDIA_VER(xe) < 13);
 
-		if (MEDIA_VER(xe) >= 20) {
+		if (MEDIA_VERx100(xe) >= 1301) {
 			gt->steering[OADDRM].ranges = xe2lpm_gpmxmt_steering_table;
 			gt->steering[INSTANCE0].ranges = xe2lpm_instance0_steering_table;
 		} else {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_mcr.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_gt_mcr.h
@@ -7,6 +7,7 @@
 #define _XE_GT_MCR_H_
 
 #include "regs/xe_reg_defs.h"
+#include "xe_gt_topology.h"
 
 struct drm_printer;
 struct xe_gt;
@@ -25,5 +26,18 @@
 			       u32 value);
 
 void xe_gt_mcr_steering_dump(struct xe_gt *gt, struct drm_printer *p);
+void xe_gt_mcr_get_dss_steering(struct xe_gt *gt, unsigned int dss, u16 *group, u16 *instance);
+
+/*
+ * Loop over each DSS and determine the group and instance IDs that
+ * should be used to steer MCR accesses toward this DSS.
+ * @dss: DSS ID to obtain steering for
+ * @gt: GT structure
+ * @group: steering group ID, data type: u16
+ * @instance: steering instance ID, data type: u16
+ */
+#define for_each_dss_steering(dss, gt, group, instance) \
+	for_each_dss((dss), (gt)) \
+		for_each_if((xe_gt_mcr_get_dss_steering((gt), (dss), &(group), &(instance)), true))
 
 #endif /* _XE_GT_MCR_H_ */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_pagefault.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_gt_pagefault.c
@@ -69,7 +69,7 @@
 static bool vma_is_valid(struct xe_tile *tile, struct xe_vma *vma)
 {
 	return BIT(tile->id) & vma->tile_present &&
-		!(BIT(tile->id) & vma->usm.tile_invalidated);
+		!(BIT(tile->id) & vma->tile_invalidated);
 }
 
 static bool vma_matches(struct xe_vma *vma, u64 page_addr)
@@ -146,10 +146,12 @@
 	/* ASID to VM */
 	mutex_lock(&xe->usm.lock);
 	vm = xa_load(&xe->usm.asid_to_vm, pf->asid);
-	if (vm)
+	if (vm && xe_vm_in_fault_mode(vm))
 		xe_vm_get(vm);
+	else
+		vm = NULL;
 	mutex_unlock(&xe->usm.lock);
-	if (!vm || !xe_vm_in_fault_mode(vm))
+	if (!vm)
 		return -EINVAL;
 
 retry_userptr:
@@ -224,7 +226,7 @@
 
 	if (xe_vma_is_userptr(vma))
 		ret = xe_vma_userptr_check_repin(to_userptr_vma(vma));
-	vma->usm.tile_invalidated &= ~BIT(tile->id);
+	vma->tile_invalidated &= ~BIT(tile->id);
 
 unlock_dma_resv:
 	drm_exec_fini(&exec);
@@ -285,9 +287,9 @@
 	bool ret = false;
 
 	spin_lock_irq(&pf_queue->lock);
-	if (pf_queue->head != pf_queue->tail) {
+	if (pf_queue->tail != pf_queue->head) {
 		desc = (const struct xe_guc_pagefault_desc *)
-			(pf_queue->data + pf_queue->head);
+			(pf_queue->data + pf_queue->tail);
 
 		pf->fault_level = FIELD_GET(PFD_FAULT_LEVEL, desc->dw0);
 		pf->trva_fault = FIELD_GET(XE2_PFD_TRVA_FAULT, desc->dw0);
@@ -305,8 +307,8 @@
 		pf->page_addr |= FIELD_GET(PFD_VIRTUAL_ADDR_LO, desc->dw2) <<
 			PFD_VIRTUAL_ADDR_LO_SHIFT;
 
-		pf_queue->head = (pf_queue->head + PF_MSG_LEN_DW) %
-			PF_QUEUE_NUM_DW;
+		pf_queue->tail = (pf_queue->tail + PF_MSG_LEN_DW) %
+			pf_queue->num_dw;
 		ret = true;
 	}
 	spin_unlock_irq(&pf_queue->lock);
@@ -318,7 +320,8 @@
 {
 	lockdep_assert_held(&pf_queue->lock);
 
-	return CIRC_SPACE(pf_queue->tail, pf_queue->head, PF_QUEUE_NUM_DW) <=
+	return CIRC_SPACE(pf_queue->head, pf_queue->tail,
+			  pf_queue->num_dw) <=
 		PF_MSG_LEN_DW;
 }
 
@@ -337,11 +340,17 @@
 	asid = FIELD_GET(PFD_ASID, msg[1]);
 	pf_queue = gt->usm.pf_queue + (asid % NUM_PF_QUEUE);
 
+	/*
+	 * The below logic doesn't work unless PF_QUEUE_NUM_DW % PF_MSG_LEN_DW == 0
+	 */
+	xe_gt_assert(gt, !(pf_queue->num_dw % PF_MSG_LEN_DW));
+
 	spin_lock_irqsave(&pf_queue->lock, flags);
 	full = pf_queue_full(pf_queue);
 	if (!full) {
-		memcpy(pf_queue->data + pf_queue->tail, msg, len * sizeof(u32));
-		pf_queue->tail = (pf_queue->tail + len) % PF_QUEUE_NUM_DW;
+		memcpy(pf_queue->data + pf_queue->head, msg, len * sizeof(u32));
+		pf_queue->head = (pf_queue->head + len) %
+			pf_queue->num_dw;
 		queue_work(gt->usm.pf_wq, &pf_queue->worker);
 	} else {
 		drm_warn(&xe->drm, "PF Queue full, shouldn't be possible");
@@ -387,7 +396,7 @@
 		send_pagefault_reply(&gt->uc.guc, &reply);
 
 		if (time_after(jiffies, threshold) &&
-		    pf_queue->head != pf_queue->tail) {
+		    pf_queue->tail != pf_queue->head) {
 			queue_work(gt->usm.pf_wq, w);
 			break;
 		}
@@ -396,18 +405,59 @@
 
 static void acc_queue_work_func(struct work_struct *w);
 
+static void pagefault_fini(void *arg)
+{
+	struct xe_gt *gt = arg;
+	struct xe_device *xe = gt_to_xe(gt);
+
+	if (!xe->info.has_usm)
+		return;
+
+	destroy_workqueue(gt->usm.acc_wq);
+	destroy_workqueue(gt->usm.pf_wq);
+}
+
+static int xe_alloc_pf_queue(struct xe_gt *gt, struct pf_queue *pf_queue)
+{
+	struct xe_device *xe = gt_to_xe(gt);
+	xe_dss_mask_t all_dss;
+	int num_dss, num_eus;
+
+	bitmap_or(all_dss, gt->fuse_topo.g_dss_mask, gt->fuse_topo.c_dss_mask,
+		  XE_MAX_DSS_FUSE_BITS);
+
+	num_dss = bitmap_weight(all_dss, XE_MAX_DSS_FUSE_BITS);
+	num_eus = bitmap_weight(gt->fuse_topo.eu_mask_per_dss,
+				XE_MAX_EU_FUSE_BITS) * num_dss;
+
+	/* user can issue separate page faults per EU and per CS */
+	pf_queue->num_dw =
+		(num_eus + XE_NUM_HW_ENGINES) * PF_MSG_LEN_DW;
+
+	pf_queue->gt = gt;
+	pf_queue->data = devm_kcalloc(xe->drm.dev, pf_queue->num_dw,
+				      sizeof(u32), GFP_KERNEL);
+	if (!pf_queue->data)
+		return -ENOMEM;
+
+	spin_lock_init(&pf_queue->lock);
+	INIT_WORK(&pf_queue->worker, pf_queue_work_func);
+
+	return 0;
+}
+
 int xe_gt_pagefault_init(struct xe_gt *gt)
 {
 	struct xe_device *xe = gt_to_xe(gt);
-	int i;
+	int i, ret = 0;
 
 	if (!xe->info.has_usm)
 		return 0;
 
 	for (i = 0; i < NUM_PF_QUEUE; ++i) {
-		gt->usm.pf_queue[i].gt = gt;
-		spin_lock_init(&gt->usm.pf_queue[i].lock);
-		INIT_WORK(&gt->usm.pf_queue[i].worker, pf_queue_work_func);
+		ret = xe_alloc_pf_queue(gt, &gt->usm.pf_queue[i]);
+		if (ret)
+			return ret;
 	}
 	for (i = 0; i < NUM_ACC_QUEUE; ++i) {
 		gt->usm.acc_queue[i].gt = gt;
@@ -423,10 +473,12 @@
 	gt->usm.acc_wq = alloc_workqueue("xe_gt_access_counter_work_queue",
 					 WQ_UNBOUND | WQ_HIGHPRI,
 					 NUM_ACC_QUEUE);
-	if (!gt->usm.acc_wq)
+	if (!gt->usm.acc_wq) {
+		destroy_workqueue(gt->usm.pf_wq);
 		return -ENOMEM;
+	}
 
-	return 0;
+	return devm_add_action_or_reset(xe->drm.dev, pagefault_fini, gt);
 }
 
 void xe_gt_pagefault_reset(struct xe_gt *gt)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c
@@ -20,6 +20,8 @@
 					tlb_invalidation.fence_tdr.work);
 	struct xe_gt_tlb_invalidation_fence *fence, *next;
 
+	LNL_FLUSH_WORK(&gt->uc.guc.ct.g2h_worker);
+
 	spin_lock_irq(&gt->tlb_invalidation.pending_lock);
 	list_for_each_entry_safe(fence, next,
 				 &gt->tlb_invalidation.pending_fences, link) {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_topology.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_gt_topology.c
@@ -11,9 +11,6 @@
 #include "xe_gt.h"
 #include "xe_mmio.h"
 
-#define XE_MAX_DSS_FUSE_BITS (32 * XE_MAX_DSS_FUSE_REGS)
-#define XE_MAX_EU_FUSE_BITS (32 * XE_MAX_EU_FUSE_REGS)
-
 static void
 load_dss_mask(struct xe_gt *gt, xe_dss_mask_t mask, int numregs, ...)
 {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_topology.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_gt_topology.h
@@ -8,6 +8,17 @@
 
 #include "xe_gt_types.h"
 
+/*
+ * Loop over each DSS with the bit is 1 in geometry or compute mask
+ * @dss: iterated DSS bit from the DSS mask
+ * @gt: GT structure
+ */
+#define for_each_dss(dss, gt) \
+	for_each_or_bit((dss), \
+			(gt)->fuse_topo.g_dss_mask, \
+			(gt)->fuse_topo.c_dss_mask, \
+			XE_MAX_DSS_FUSE_BITS)
+
 struct drm_printer;
 
 void xe_gt_topology_init(struct xe_gt *gt);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_gt_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_gt_types.h
@@ -25,10 +25,12 @@
 };
 
 #define XE_MAX_DSS_FUSE_REGS	3
+#define XE_MAX_DSS_FUSE_BITS	(32 * XE_MAX_DSS_FUSE_REGS)
 #define XE_MAX_EU_FUSE_REGS	1
+#define XE_MAX_EU_FUSE_BITS	(32 * XE_MAX_EU_FUSE_REGS)
 
-typedef unsigned long xe_dss_mask_t[BITS_TO_LONGS(32 * XE_MAX_DSS_FUSE_REGS)];
-typedef unsigned long xe_eu_mask_t[BITS_TO_LONGS(32 * XE_MAX_EU_FUSE_REGS)];
+typedef unsigned long xe_dss_mask_t[BITS_TO_LONGS(XE_MAX_DSS_FUSE_BITS)];
+typedef unsigned long xe_eu_mask_t[BITS_TO_LONGS(XE_MAX_EU_FUSE_BITS)];
 
 struct xe_mmio_range {
 	u32 start;
@@ -222,19 +224,24 @@
 		struct pf_queue {
 			/** @gt: back pointer to GT */
 			struct xe_gt *gt;
-#define PF_QUEUE_NUM_DW	128
 			/** @data: data in the page fault queue */
-			u32 data[PF_QUEUE_NUM_DW];
+			u32 *data;
 			/**
-			 * @head: head pointer in DWs for page fault queue,
-			 * moved by worker which processes faults.
+			 * @usm.pf_queue.num_dw: number of DWORDS in the page
+			 * fault queue. Dynamically calculated based on the number
+			 * of compute resources available.
 			 */
-			u16 head;
+			u32 num_dw;
 			/**
 			 * @tail: tail pointer in DWs for page fault queue,
-			 * moved by G2H handler.
+			 * moved by worker which processes faults (consumer).
 			 */
 			u16 tail;
+			/**
+			 * @head: head pointer in DWs for page fault queue,
+			 * moved by G2H handler (producer).
+			 */
+			u16 head;
 			/** @lock: protects page fault queue */
 			spinlock_t lock;
 			/** @worker: to process page faults */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_guc_ct.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_guc_ct.c
@@ -503,16 +503,12 @@
 		num_g2h = 1;
 
 		if (g2h_fence_needs_alloc(g2h_fence)) {
-			void *ptr;
-
 			g2h_fence->seqno = (ct->fence_seqno++ & 0xffff);
-			ptr = xa_store(&ct->fence_lookup,
-				       g2h_fence->seqno,
-				       g2h_fence, GFP_ATOMIC);
-			if (IS_ERR(ptr)) {
-				ret = PTR_ERR(ptr);
+			ret = xa_err(xa_store(&ct->fence_lookup,
+					      g2h_fence->seqno, g2h_fence,
+					      GFP_ATOMIC));
+			if (ret)
 				goto out;
-			}
 		}
 	}
 
@@ -710,14 +706,11 @@
 retry_same_fence:
 	ret = guc_ct_send(ct, action, len, 0, 0, &g2h_fence);
 	if (unlikely(ret == -ENOMEM)) {
-		void *ptr;
-
 		/* Retry allocation /w GFP_KERNEL */
-		ptr = xa_store(&ct->fence_lookup,
-			       g2h_fence.seqno,
-			       &g2h_fence, GFP_KERNEL);
-		if (IS_ERR(ptr))
-			return PTR_ERR(ptr);
+		ret = xa_err(xa_store(&ct->fence_lookup, g2h_fence.seqno,
+				      &g2h_fence, GFP_KERNEL));
+		if (ret)
+			return ret;
 
 		goto retry_same_fence;
 	} else if (unlikely(ret)) {
@@ -734,16 +727,35 @@
 	}
 
 	ret = wait_event_timeout(ct->g2h_fence_wq, g2h_fence.done, HZ);
+
+	if (!ret) {
+		LNL_FLUSH_WORK(&ct->g2h_worker);
+		if (g2h_fence.done) {
+			drm_warn(&xe->drm, "G2H fence %u, action %04x, done\n",
+				 g2h_fence.seqno, action[0]);
+			ret = 1;
+		}
+	}
+
+	/*
+	 * Ensure we serialize with completion side to prevent UAF with fence going out of scope on
+	 * the stack, since we have no clue if it will fire after the timeout before we can erase
+	 * from the xa. Also we have some dependent loads and stores below for which we need the
+	 * correct ordering, and we lack the needed barriers.
+	 */
+	mutex_lock(&ct->lock);
 	if (!ret) {
-		drm_err(&xe->drm, "Timed out wait for G2H, fence %u, action %04x",
-			g2h_fence.seqno, action[0]);
+		drm_err(&xe->drm, "Timed out wait for G2H, fence %u, action %04x, done %s",
+			g2h_fence.seqno, action[0], str_yes_no(g2h_fence.done));
 		xa_erase_irq(&ct->fence_lookup, g2h_fence.seqno);
+		mutex_unlock(&ct->lock);
 		return -ETIME;
 	}
 
 	if (g2h_fence.retry) {
 		drm_warn(&xe->drm, "Send retry, action 0x%04x, reason %d",
 			 action[0], g2h_fence.reason);
+		mutex_unlock(&ct->lock);
 		goto retry;
 	}
 	if (g2h_fence.fail) {
@@ -752,6 +764,8 @@
 		ret = -EIO;
 	}
 
+	mutex_unlock(&ct->lock);
+
 	return ret > 0 ? 0 : ret;
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_guc_pc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_guc_pc.c
@@ -381,8 +381,6 @@
 	struct xe_device *xe = gt_to_xe(gt);
 	u32 freq;
 
-	xe_device_mem_access_get(gt_to_xe(gt));
-
 	/* When in RC6, actual frequency reported will be 0. */
 	if (GRAPHICS_VERx100(xe) >= 1270) {
 		freq = xe_mmio_read32(gt, MTL_MIRROR_TARGET_WP1);
@@ -394,8 +392,6 @@
 
 	freq = decode_freq(freq);
 
-	xe_device_mem_access_put(gt_to_xe(gt));
-
 	return freq;
 }
 
@@ -412,14 +408,13 @@
 	struct xe_gt *gt = pc_to_gt(pc);
 	int ret;
 
-	xe_device_mem_access_get(gt_to_xe(gt));
 	/*
 	 * GuC SLPC plays with cur freq request when GuCRC is enabled
 	 * Block RC6 for a more reliable read.
 	 */
 	ret = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
 	if (ret)
-		goto out;
+		return ret;
 
 	*freq = xe_mmio_read32(gt, RPNSWREQ);
 
@@ -427,9 +422,7 @@
 	*freq = decode_freq(*freq);
 
 	XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
-out:
-	xe_device_mem_access_put(gt_to_xe(gt));
-	return ret;
+	return 0;
 }
 
 /**
@@ -451,12 +444,7 @@
  */
 u32 xe_guc_pc_get_rpe_freq(struct xe_guc_pc *pc)
 {
-	struct xe_gt *gt = pc_to_gt(pc);
-	struct xe_device *xe = gt_to_xe(gt);
-
-	xe_device_mem_access_get(xe);
 	pc_update_rp_values(pc);
-	xe_device_mem_access_put(xe);
 
 	return pc->rpe_freq;
 }
@@ -485,7 +473,6 @@
 	struct xe_gt *gt = pc_to_gt(pc);
 	int ret;
 
-	xe_device_mem_access_get(pc_to_xe(pc));
 	mutex_lock(&pc->freq_lock);
 	if (!pc->freq_ready) {
 		/* Might be in the middle of a gt reset */
@@ -511,7 +498,6 @@
 	XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
 out:
 	mutex_unlock(&pc->freq_lock);
-	xe_device_mem_access_put(pc_to_xe(pc));
 	return ret;
 }
 
@@ -528,7 +514,6 @@
 {
 	int ret;
 
-	xe_device_mem_access_get(pc_to_xe(pc));
 	mutex_lock(&pc->freq_lock);
 	if (!pc->freq_ready) {
 		/* Might be in the middle of a gt reset */
@@ -544,8 +529,6 @@
 
 out:
 	mutex_unlock(&pc->freq_lock);
-	xe_device_mem_access_put(pc_to_xe(pc));
-
 	return ret;
 }
 
@@ -561,7 +544,6 @@
 {
 	int ret;
 
-	xe_device_mem_access_get(pc_to_xe(pc));
 	mutex_lock(&pc->freq_lock);
 	if (!pc->freq_ready) {
 		/* Might be in the middle of a gt reset */
@@ -577,7 +559,6 @@
 
 out:
 	mutex_unlock(&pc->freq_lock);
-	xe_device_mem_access_put(pc_to_xe(pc));
 	return ret;
 }
 
@@ -594,7 +575,6 @@
 {
 	int ret;
 
-	xe_device_mem_access_get(pc_to_xe(pc));
 	mutex_lock(&pc->freq_lock);
 	if (!pc->freq_ready) {
 		/* Might be in the middle of a gt reset */
@@ -610,7 +590,6 @@
 
 out:
 	mutex_unlock(&pc->freq_lock);
-	xe_device_mem_access_put(pc_to_xe(pc));
 	return ret;
 }
 
@@ -623,8 +602,6 @@
 	struct xe_gt *gt = pc_to_gt(pc);
 	u32 reg, gt_c_state;
 
-	xe_device_mem_access_get(gt_to_xe(gt));
-
 	if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270) {
 		reg = xe_mmio_read32(gt, MTL_MIRROR_TARGET_WP1);
 		gt_c_state = REG_FIELD_GET(MTL_CC_MASK, reg);
@@ -633,8 +610,6 @@
 		gt_c_state = REG_FIELD_GET(RCN_MASK, reg);
 	}
 
-	xe_device_mem_access_put(gt_to_xe(gt));
-
 	switch (gt_c_state) {
 	case GT_C6:
 		return GT_IDLE_C6;
@@ -654,9 +629,7 @@
 	struct xe_gt *gt = pc_to_gt(pc);
 	u32 reg;
 
-	xe_device_mem_access_get(gt_to_xe(gt));
 	reg = xe_mmio_read32(gt, GT_GFX_RC6);
-	xe_device_mem_access_put(gt_to_xe(gt));
 
 	return reg;
 }
@@ -670,9 +643,7 @@
 	struct xe_gt *gt = pc_to_gt(pc);
 	u64 reg;
 
-	xe_device_mem_access_get(gt_to_xe(gt));
 	reg = xe_mmio_read32(gt, MTL_MEDIA_MC6);
-	xe_device_mem_access_put(gt_to_xe(gt));
 
 	return reg;
 }
@@ -801,23 +772,19 @@
 	if (xe->info.skip_guc_pc)
 		return 0;
 
-	xe_device_mem_access_get(pc_to_xe(pc));
-
 	ret = pc_action_setup_gucrc(pc, XE_GUCRC_HOST_CONTROL);
 	if (ret)
-		goto out;
+		return ret;
 
 	ret = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
 	if (ret)
-		goto out;
+		return ret;
 
 	xe_gt_idle_disable_c6(gt);
 
 	XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
 
-out:
-	xe_device_mem_access_put(pc_to_xe(pc));
-	return ret;
+	return 0;
 }
 
 static void pc_init_pcode_freq(struct xe_guc_pc *pc)
@@ -870,11 +837,9 @@
 
 	xe_gt_assert(gt, xe_device_uc_enabled(xe));
 
-	xe_device_mem_access_get(pc_to_xe(pc));
-
 	ret = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
 	if (ret)
-		goto out_fail_force_wake;
+		return ret;
 
 	if (xe->info.skip_guc_pc) {
 		if (xe->info.platform != XE_PVC)
@@ -914,8 +879,6 @@
 
 out:
 	XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
-out_fail_force_wake:
-	xe_device_mem_access_put(pc_to_xe(pc));
 	return ret;
 }
 
@@ -928,12 +891,9 @@
 	struct xe_device *xe = pc_to_xe(pc);
 	int ret;
 
-	xe_device_mem_access_get(pc_to_xe(pc));
-
 	if (xe->info.skip_guc_pc) {
 		xe_gt_idle_disable_c6(pc_to_gt(pc));
-		ret = 0;
-		goto out;
+		return 0;
 	}
 
 	mutex_lock(&pc->freq_lock);
@@ -942,16 +902,14 @@
 
 	ret = pc_action_shutdown(pc);
 	if (ret)
-		goto out;
+		return ret;
 
 	if (wait_for_pc_state(pc, SLPC_GLOBAL_STATE_NOT_RUNNING)) {
 		drm_err(&pc_to_xe(pc)->drm, "GuC PC Shutdown failed\n");
-		ret = -EIO;
+		return -EIO;
 	}
 
-out:
-	xe_device_mem_access_put(pc_to_xe(pc));
-	return ret;
+	return 0;
 }
 
 /**
@@ -960,16 +918,7 @@
  */
 void xe_guc_pc_fini(struct xe_guc_pc *pc)
 {
-	struct xe_device *xe = pc_to_xe(pc);
-
-	if (xe->info.skip_guc_pc) {
-		xe_device_mem_access_get(xe);
-		xe_gt_idle_disable_c6(pc_to_gt(pc));
-		xe_device_mem_access_put(xe);
-		return;
-	}
-
-	XE_WARN_ON(xe_guc_pc_gucrc_disable(pc));
+	xe_guc_pc_gucrc_disable(pc);
 	XE_WARN_ON(xe_guc_pc_stop(pc));
 	mutex_destroy(&pc->freq_lock);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_guc_submit.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_guc_submit.c
@@ -23,6 +23,7 @@
 #include "xe_force_wake.h"
 #include "xe_gpu_scheduler.h"
 #include "xe_gt.h"
+#include "xe_gt_printk.h"
 #include "xe_guc.h"
 #include "xe_guc_ct.h"
 #include "xe_guc_exec_queue_types.h"
@@ -230,10 +231,26 @@
 }
 #endif
 
+static void xe_guc_submit_fini(struct xe_guc *guc)
+{
+	struct xe_device *xe = guc_to_xe(guc);
+	struct xe_gt *gt = guc_to_gt(guc);
+	int ret;
+
+	ret = wait_event_timeout(guc->submission_state.fini_wq,
+				 xa_empty(&guc->submission_state.exec_queue_lookup),
+				 HZ * 5);
+
+	drain_workqueue(xe->destroy_wq);
+
+	xe_gt_assert(gt, ret);
+}
+
 static void guc_submit_fini(struct drm_device *drm, void *arg)
 {
 	struct xe_guc *guc = arg;
 
+	xe_guc_submit_fini(guc);
 	xa_destroy(&guc->submission_state.exec_queue_lookup);
 	ida_destroy(&guc->submission_state.guc_ids);
 	bitmap_free(guc->submission_state.guc_ids_bitmap);
@@ -256,7 +273,6 @@
 	fs_reclaim_acquire(GFP_KERNEL);
 
 	mutex_lock(&guc->submission_state.lock);
-	might_lock(&guc->submission_state.suspend.lock);
 	mutex_unlock(&guc->submission_state.lock);
 
 	fs_reclaim_release(GFP_KERNEL);
@@ -285,8 +301,7 @@
 	xa_init(&guc->submission_state.exec_queue_lookup);
 	ida_init(&guc->submission_state.guc_ids);
 
-	spin_lock_init(&guc->submission_state.suspend.lock);
-	guc->submission_state.suspend.context = dma_fence_context_alloc(1);
+	init_waitqueue_head(&guc->submission_state.fini_wq);
 
 	primelockdep(guc);
 
@@ -312,12 +327,14 @@
 				      order_base_2(q->width));
 	else
 		ida_simple_remove(&guc->submission_state.guc_ids, q->guc->id);
+
+	if (xa_empty(&guc->submission_state.exec_queue_lookup))
+		wake_up(&guc->submission_state.fini_wq);
 }
 
 static int alloc_guc_id(struct xe_guc *guc, struct xe_exec_queue *q)
 {
 	int ret;
-	void *ptr;
 	int i;
 
 	/*
@@ -346,12 +363,10 @@
 		q->guc->id += GUC_ID_START_MLRC;
 
 	for (i = 0; i < q->width; ++i) {
-		ptr = xa_store(&guc->submission_state.exec_queue_lookup,
-			       q->guc->id + i, q, GFP_NOWAIT);
-		if (IS_ERR(ptr)) {
-			ret = PTR_ERR(ptr);
+		ret = xa_err(xa_store(&guc->submission_state.exec_queue_lookup,
+				      q->guc->id + i, q, GFP_NOWAIT));
+		if (ret)
 			goto err_release;
-		}
 	}
 
 	return 0;
@@ -1038,13 +1053,16 @@
 
 static void guc_exec_queue_fini_async(struct xe_exec_queue *q)
 {
+	struct xe_guc *guc = exec_queue_to_guc(q);
+	struct xe_device *xe = guc_to_xe(guc);
+
 	INIT_WORK(&q->guc->fini_async, __guc_exec_queue_fini_async);
 
 	/* We must block on kernel engines so slabs are empty on driver unload */
 	if (q->flags & EXEC_QUEUE_FLAG_PERMANENT)
 		__guc_exec_queue_fini_async(&q->guc->fini_async);
 	else
-		queue_work(system_wq, &q->guc->fini_async);
+		queue_work(xe->destroy_wq, &q->guc->fini_async);
 }
 
 static void __guc_exec_queue_fini(struct xe_guc *guc, struct xe_exec_queue *q)
@@ -1089,6 +1107,15 @@
 	kfree(msg);
 }
 
+static void __suspend_fence_signal(struct xe_exec_queue *q)
+{
+	if (!q->guc->suspend_pending)
+		return;
+
+	WRITE_ONCE(q->guc->suspend_pending, false);
+	wake_up(&q->guc->suspend_wait);
+}
+
 static void suspend_fence_signal(struct xe_exec_queue *q)
 {
 	struct xe_guc *guc = exec_queue_to_guc(q);
@@ -1098,9 +1125,7 @@
 		  guc_read_stopped(guc));
 	xe_assert(xe, q->guc->suspend_pending);
 
-	q->guc->suspend_pending = false;
-	smp_wmb();
-	wake_up(&q->guc->suspend_wait);
+	__suspend_fence_signal(q);
 }
 
 static void __guc_exec_queue_process_msg_suspend(struct xe_sched_msg *msg)
@@ -1216,7 +1241,7 @@
 	init_waitqueue_head(&ge->suspend_wait);
 
 	timeout = (q->vm && xe_vm_in_lr_mode(q->vm)) ? MAX_SCHEDULE_TIMEOUT :
-		  q->hwe->eclass->sched_props.job_timeout_ms;
+		  msecs_to_jiffies(q->sched_props.job_timeout_ms);
 	err = xe_sched_init(&ge->sched, &drm_sched_ops, &xe_sched_ops,
 			    get_submit_wq(guc),
 			    q->lrc[0].ring.size / MAX_JOB_SIZE_BYTES, 64,
@@ -1253,6 +1278,7 @@
 	return 0;
 
 err_entity:
+	mutex_unlock(&guc->submission_state.lock);
 	xe_sched_entity_fini(&ge->entity);
 err_sched:
 	xe_sched_fini(&ge->sched);
@@ -1266,6 +1292,7 @@
 {
 	trace_xe_exec_queue_kill(q);
 	set_exec_queue_killed(q);
+	__suspend_fence_signal(q);
 	xe_guc_exec_queue_trigger_cleanup(q);
 }
 
@@ -1376,12 +1403,31 @@
 	return 0;
 }
 
-static void guc_exec_queue_suspend_wait(struct xe_exec_queue *q)
+static int guc_exec_queue_suspend_wait(struct xe_exec_queue *q)
 {
 	struct xe_guc *guc = exec_queue_to_guc(q);
+	int ret;
+
+	/*
+	 * Likely don't need to check exec_queue_killed() as we clear
+	 * suspend_pending upon kill but to be paranoid but races in which
+	 * suspend_pending is set after kill also check kill here.
+	 */
+	ret = wait_event_timeout(q->guc->suspend_wait,
+				 !READ_ONCE(q->guc->suspend_pending) ||
+				 exec_queue_killed(q) ||
+				 guc_read_stopped(guc),
+				 HZ * 5);
 
-	wait_event(q->guc->suspend_wait, !q->guc->suspend_pending ||
-		   guc_read_stopped(guc));
+	if (!ret) {
+		xe_gt_warn(guc_to_gt(guc),
+			   "Suspend fence, guc_id=%d, failed to respond",
+			   q->guc->id);
+		/* XXX: Trigger GT reset? */
+		return -ETIME;
+	}
+
+	return 0;
 }
 
 static void guc_exec_queue_resume(struct xe_exec_queue *q)
@@ -1457,8 +1503,8 @@
 			    !xe_sched_job_completed(job)) ||
 			    xe_sched_invalidate_job(job, 2)) {
 				trace_xe_sched_job_ban(job);
-				xe_sched_tdr_queue_imm(&q->guc->sched);
 				set_exec_queue_banned(q);
+				xe_sched_tdr_queue_imm(&q->guc->sched);
 			}
 		}
 	}
@@ -1497,8 +1543,13 @@
 
 	mutex_lock(&guc->submission_state.lock);
 
-	xa_for_each(&guc->submission_state.exec_queue_lookup, index, q)
+	xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) {
+		/* Prevent redundant attempts to stop parallel queues */
+		if (q->guc->id != index)
+			continue;
+
 		guc_exec_queue_stop(guc, q);
+	}
 
 	mutex_unlock(&guc->submission_state.lock);
 
@@ -1524,6 +1575,7 @@
 	}
 
 	xe_sched_submission_start(sched);
+	xe_sched_submission_resume_tdr(sched);
 }
 
 int xe_guc_submit_start(struct xe_guc *guc)
@@ -1536,8 +1588,13 @@
 
 	mutex_lock(&guc->submission_state.lock);
 	atomic_dec(&guc->submission_state.stopped);
-	xa_for_each(&guc->submission_state.exec_queue_lookup, index, q)
+	xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) {
+		/* Prevent redundant attempts to start parallel queues */
+		if (q->guc->id != index)
+			continue;
+
 		guc_exec_queue_start(q);
+	}
 	mutex_unlock(&guc->submission_state.lock);
 
 	wake_up_all(&guc->ct.wq);
@@ -1575,6 +1632,11 @@
 		q->guc->id,
 	};
 
+	xe_gt_assert(guc_to_gt(guc), exec_queue_destroyed(q));
+	xe_gt_assert(guc_to_gt(guc), exec_queue_registered(q));
+	xe_gt_assert(guc_to_gt(guc), !exec_queue_pending_disable(q));
+	xe_gt_assert(guc_to_gt(guc), !exec_queue_pending_enable(q));
+
 	trace_xe_exec_queue_deregister(q);
 
 	xe_guc_ct_send_g2h_handler(&guc->ct, action, ARRAY_SIZE(action));
@@ -1830,7 +1892,7 @@
 	snapshot->sched_props.preempt_timeout_us =
 		q->sched_props.preempt_timeout_us;
 
-	snapshot->lrc = kmalloc_array(q->width, sizeof(struct lrc_snapshot),
+	snapshot->lrc = kmalloc_array(q->width, sizeof(struct xe_lrc_snapshot *),
 				      GFP_ATOMIC);
 
 	if (!snapshot->lrc) {
@@ -1839,14 +1901,7 @@
 		for (i = 0; i < q->width; ++i) {
 			struct xe_lrc *lrc = q->lrc + i;
 
-			snapshot->lrc[i].context_desc =
-				lower_32_bits(xe_lrc_ggtt_addr(lrc));
-			snapshot->lrc[i].head = xe_lrc_ring_head(lrc);
-			snapshot->lrc[i].tail.internal = lrc->ring.tail;
-			snapshot->lrc[i].tail.memory =
-				xe_lrc_read_ctx_reg(lrc, CTX_RING_TAIL);
-			snapshot->lrc[i].start_seqno = xe_lrc_start_seqno(lrc);
-			snapshot->lrc[i].seqno = xe_lrc_seqno(lrc);
+			snapshot->lrc[i] = xe_lrc_snapshot_capture(lrc);
 		}
 	}
 
@@ -1912,18 +1967,9 @@
 	drm_printf(p, "\tPreempt timeout: %u (us)\n",
 		   snapshot->sched_props.preempt_timeout_us);
 
-	for (i = 0; snapshot->lrc && i < snapshot->width; ++i) {
-		drm_printf(p, "\tHW Context Desc: 0x%08x\n",
-			   snapshot->lrc[i].context_desc);
-		drm_printf(p, "\tLRC Head: (memory) %u\n",
-			   snapshot->lrc[i].head);
-		drm_printf(p, "\tLRC Tail: (internal) %u, (memory) %u\n",
-			   snapshot->lrc[i].tail.internal,
-			   snapshot->lrc[i].tail.memory);
-		drm_printf(p, "\tStart seqno: (memory) %d\n",
-			   snapshot->lrc[i].start_seqno);
-		drm_printf(p, "\tSeqno: (memory) %d\n", snapshot->lrc[i].seqno);
-	}
+	for (i = 0; snapshot->lrc && i < snapshot->width; ++i)
+		xe_lrc_snapshot_print(snapshot->lrc[i], p);
+
 	drm_printf(p, "\tSchedule State: 0x%x\n", snapshot->schedule_state);
 	drm_printf(p, "\tFlags: 0x%lx\n", snapshot->exec_queue_flags);
 
@@ -1948,10 +1994,15 @@
  */
 void xe_guc_exec_queue_snapshot_free(struct xe_guc_submit_exec_queue_snapshot *snapshot)
 {
+	int i;
 	if (!snapshot)
 		return;
 
-	kfree(snapshot->lrc);
+	if (snapshot->lrc) {
+		for (i = 0; i < snapshot->width; i++)
+			xe_lrc_snapshot_free(snapshot->lrc[i]);
+		kfree(snapshot->lrc);
+	}
 	kfree(snapshot->pending_list);
 	kfree(snapshot);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_guc_submit_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_guc_submit_types.h
@@ -61,17 +61,6 @@
 	u32 wq[WQ_SIZE / sizeof(u32)];
 };
 
-struct lrc_snapshot {
-	u32 context_desc;
-	u32 head;
-	struct {
-		u32 internal;
-		u32 memory;
-	} tail;
-	u32 start_seqno;
-	u32 seqno;
-};
-
 struct pending_list_snapshot {
 	u32 seqno;
 	bool fence;
@@ -109,7 +98,7 @@
 	} sched_props;
 
 	/** @lrc: LRC Snapshot */
-	struct lrc_snapshot *lrc;
+	struct xe_lrc_snapshot **lrc;
 
 	/** @schedule_state: Schedule State at the moment of Crash */
 	u32 schedule_state;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_guc_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_guc_types.h
@@ -43,15 +43,6 @@
 		atomic_t stopped;
 		/** @lock: protects submission state */
 		struct mutex lock;
-		/** @suspend: suspend fence state */
-		struct {
-			/** @lock: suspend fences lock */
-			spinlock_t lock;
-			/** @context: suspend fences context */
-			u64 context;
-			/** @seqno: suspend fences seqno */
-			u32 seqno;
-		} suspend;
 #ifdef CONFIG_PROVE_LOCKING
 #define NUM_SUBMIT_WQ	256
 		/** @submit_wq_pool: submission ordered workqueues pool */
@@ -61,6 +52,8 @@
 #endif
 		/** @enabled: submission is enabled */
 		bool enabled;
+		/** @submission_state.fini_wq: submit fini wait queue */
+		wait_queue_head_t fini_wq;
 	} submission_state;
 	/** @hwconfig: Hardware config state */
 	struct {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_huc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_huc.c
@@ -53,7 +53,6 @@
 	struct xe_gt *gt = huc_to_gt(huc);
 	struct xe_device *xe = gt_to_xe(gt);
 	struct xe_bo *bo;
-	int err;
 
 	/* we use a single object for both input and output */
 	bo = xe_bo_create_pin_map(xe, gt_to_tile(gt), NULL,
@@ -66,13 +65,7 @@
 
 	huc->gsc_pkt = bo;
 
-	err = drmm_add_action_or_reset(&xe->drm, free_gsc_pkt, huc);
-	if (err) {
-		free_gsc_pkt(&xe->drm, huc);
-		return err;
-	}
-
-	return 0;
+	return drmm_add_action_or_reset(&xe->drm, free_gsc_pkt, huc);
 }
 
 int xe_huc_init(struct xe_huc *huc)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_hw_engine.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_hw_engine.c
@@ -5,7 +5,10 @@
 
 #include "xe_hw_engine.h"
 
+#include <linux/nospec.h>
+
 #include <drm/drm_managed.h>
+#include <drm/xe_drm.h>
 
 #include "regs/xe_engine_regs.h"
 #include "regs/xe_gt_regs.h"
@@ -341,7 +344,7 @@
 	 * Bspec: 72161
 	 */
 	const u8 mocs_write_idx = gt->mocs.uc_index;
-	const u8 mocs_read_idx = hwe->class == XE_ENGINE_CLASS_COMPUTE &&
+	const u8 mocs_read_idx = hwe->class == XE_ENGINE_CLASS_COMPUTE && IS_DGFX(xe) &&
 				 (GRAPHICS_VER(xe) >= 20 || xe->info.platform == XE_PVC) ?
 				 gt->mocs.wb_index : gt->mocs.uc_index;
 	u32 ring_cmd_cctl_val = REG_FIELD_PREP(CMD_CCTL_WRITE_OVERRIDE_MASK, mocs_write_idx) |
@@ -881,3 +884,31 @@
 	return xe->info.has_usm && hwe->class == XE_ENGINE_CLASS_COPY &&
 		hwe->instance == gt->usm.reserved_bcs_instance;
 }
+
+static const enum xe_engine_class user_to_xe_engine_class[] = {
+	[DRM_XE_ENGINE_CLASS_RENDER] = XE_ENGINE_CLASS_RENDER,
+	[DRM_XE_ENGINE_CLASS_COPY] = XE_ENGINE_CLASS_COPY,
+	[DRM_XE_ENGINE_CLASS_VIDEO_DECODE] = XE_ENGINE_CLASS_VIDEO_DECODE,
+	[DRM_XE_ENGINE_CLASS_VIDEO_ENHANCE] = XE_ENGINE_CLASS_VIDEO_ENHANCE,
+	[DRM_XE_ENGINE_CLASS_COMPUTE] = XE_ENGINE_CLASS_COMPUTE,
+};
+
+struct xe_hw_engine *
+xe_hw_engine_lookup(struct xe_device *xe,
+		    struct drm_xe_engine_class_instance eci)
+{
+	unsigned int idx;
+
+	if (eci.engine_class > ARRAY_SIZE(user_to_xe_engine_class))
+		return NULL;
+
+	if (eci.gt_id >= xe->info.gt_count)
+		return NULL;
+
+	idx = array_index_nospec(eci.engine_class,
+				 ARRAY_SIZE(user_to_xe_engine_class));
+
+	return xe_gt_hw_engine(xe_device_get_gt(xe, eci.gt_id),
+			       user_to_xe_engine_class[idx],
+			       eci.engine_instance, true);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_hw_engine.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_hw_engine.h
@@ -9,6 +9,8 @@
 #include "xe_hw_engine_types.h"
 
 struct drm_printer;
+struct drm_xe_engine_class_instance;
+struct xe_device;
 
 #ifdef CONFIG_DRM_XE_JOB_TIMEOUT_MIN
 #define XE_HW_ENGINE_JOB_TIMEOUT_MIN CONFIG_DRM_XE_JOB_TIMEOUT_MIN
@@ -62,6 +64,11 @@
 void xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe);
 
 bool xe_hw_engine_is_reserved(struct xe_hw_engine *hwe);
+
+struct xe_hw_engine *
+xe_hw_engine_lookup(struct xe_device *xe,
+		    struct drm_xe_engine_class_instance eci);
+
 static inline bool xe_hw_engine_is_valid(struct xe_hw_engine *hwe)
 {
 	return hwe->name;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_hwmon.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_hwmon.c
@@ -191,9 +191,10 @@
 				     PKG_PWR_LIM_1_EN, 0);
 
 		if (reg_val & PKG_PWR_LIM_1_EN) {
+			drm_warn(&gt_to_xe(hwmon->gt)->drm, "PL1 disable is not supported!\n");
 			ret = -EOPNOTSUPP;
-			goto unlock;
 		}
+		goto unlock;
 	}
 
 	/* Computation in 64-bits to avoid overflow. Round to nearest. */
@@ -288,7 +289,7 @@
 	 * As y can be < 2, we compute tau4 = (4 | x) << y
 	 * and then add 2 when doing the final right shift to account for units
 	 */
-	tau4 = ((1 << x_w) | x) << y;
+	tau4 = (u64)((1 << x_w) | x) << y;
 
 	/* val in hwmon interface units (millisec) */
 	out = mul_u64_u32_shr(tau4, SF_TIME, hwmon->scl_shift_time + x_w);
@@ -328,7 +329,7 @@
 	r = FIELD_PREP(PKG_MAX_WIN, PKG_MAX_WIN_DEFAULT);
 	x = REG_FIELD_GET(PKG_MAX_WIN_X, r);
 	y = REG_FIELD_GET(PKG_MAX_WIN_Y, r);
-	tau4 = ((1 << x_w) | x) << y;
+	tau4 = (u64)((1 << x_w) | x) << y;
 	max_win = mul_u64_u32_shr(tau4, SF_TIME, hwmon->scl_shift_time + x_w);
 
 	if (val > max_win)
@@ -426,7 +427,7 @@
 {
 	return xe_pcode_write(gt, PCODE_MBOX(PCODE_POWER_SETUP,
 			      POWER_SETUP_SUBCOMMAND_WRITE_I1, 0),
-			      uval);
+			      (uval & POWER_SETUP_I1_DATA_MASK));
 }
 
 static int xe_hwmon_power_curr_crit_read(struct xe_hwmon *hwmon, long *value, u32 scale_factor)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_lrc.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_lrc.c
@@ -5,6 +5,8 @@
 
 #include "xe_lrc.h"
 
+#include <generated/xe_wa_oob.h>
+
 #include "instructions/xe_mi_commands.h"
 #include "instructions/xe_gfxpipe_commands.h"
 #include "regs/xe_engine_regs.h"
@@ -20,6 +22,7 @@
 #include "xe_hw_fence.h"
 #include "xe_map.h"
 #include "xe_vm.h"
+#include "xe_wa.h"
 
 #define LRC_VALID				(1 << 0)
 #define LRC_PRIVILEGE				(1 << 8)
@@ -29,6 +32,17 @@
 #define ENGINE_CLASS_SHIFT			61
 #define ENGINE_INSTANCE_SHIFT			48
 
+struct xe_lrc_snapshot {
+	u32 context_desc;
+	u32 head;
+	struct {
+		u32 internal;
+		u32 memory;
+	} tail;
+	u32 start_seqno;
+	u32 seqno;
+};
+
 static struct xe_device *
 lrc_to_xe(struct xe_lrc *lrc)
 {
@@ -95,7 +109,6 @@
 #define REG16(x) \
 	(((x) >> 9) | BIT(7) | BUILD_BUG_ON_ZERO(x >= 0x10000)), \
 	(((x) >> 2) & 0x7f)
-#define END 0
 {
 	const u32 base = hwe->mmio_base;
 
@@ -166,7 +179,7 @@
 	REG16(0x274),
 	REG16(0x270),
 
-	END
+	0
 };
 
 static const u8 dg2_xcs_offsets[] = {
@@ -200,7 +213,7 @@
 	REG16(0x274),
 	REG16(0x270),
 
-	END
+	0
 };
 
 static const u8 gen12_rcs_offsets[] = {
@@ -296,7 +309,7 @@
 	REG(0x084),
 	NOP(1),
 
-	END
+	0
 };
 
 static const u8 xehp_rcs_offsets[] = {
@@ -337,7 +350,7 @@
 	LRI(1, 0),
 	REG(0x0c8),
 
-	END
+	0
 };
 
 static const u8 dg2_rcs_offsets[] = {
@@ -380,7 +393,7 @@
 	LRI(1, 0),
 	REG(0x0c8),
 
-	END
+	0
 };
 
 static const u8 mtl_rcs_offsets[] = {
@@ -423,7 +436,7 @@
 	LRI(1, 0),
 	REG(0x0c8),
 
-	END
+	0
 };
 
 #define XE2_CTX_COMMON \
@@ -469,7 +482,7 @@
 	LRI(1, 0),              /* [0x47] */
 	REG(0x0c8),             /* [0x48] R_PWR_CLK_STATE */
 
-	END
+	0
 };
 
 static const u8 xe2_bcs_offsets[] = {
@@ -480,16 +493,15 @@
 	REG16(0x200),           /* [0x42] BCS_SWCTRL */
 	REG16(0x204),           /* [0x44] BLIT_CCTL */
 
-	END
+	0
 };
 
 static const u8 xe2_xcs_offsets[] = {
 	XE2_CTX_COMMON,
 
-	END
+	0
 };
 
-#undef END
 #undef REG16
 #undef REG
 #undef LRI
@@ -525,9 +537,8 @@
 
 static void set_context_control(u32 *regs, struct xe_hw_engine *hwe)
 {
-	regs[CTX_CONTEXT_CONTROL] = _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH) |
-				    _MASKED_BIT_DISABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT) |
-				    CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT;
+	regs[CTX_CONTEXT_CONTROL] = _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH |
+						       CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT);
 
 	/* TODO: Timestamp */
 }
@@ -1217,19 +1228,31 @@
 	int state_table_size = 0;
 
 	/*
-	 * At the moment we only need to emit non-register state for the RCS
-	 * engine.
+	 * Wa_14019789679
+	 *
+	 * If the driver doesn't explicitly emit the SVG instructions while
+	 * setting up the default LRC, the context switch will write 0's
+	 * (noops) into the LRC memory rather than the expected instruction
+	 * headers.  Application contexts start out as a copy of the default
+	 * LRC, and if they also do not emit specific settings for some SVG
+	 * state, then on context restore they'll unintentionally inherit
+	 * whatever state setting the previous context had programmed into the
+	 * hardware (i.e., the lack of a 3DSTATE_* instruction in the LRC will
+	 * prevent the hardware from resetting that state back to any specific
+	 * value).
+	 *
+	 * The official workaround only requires emitting 3DSTATE_MESH_CONTROL
+	 * since that's a specific state setting that can easily cause GPU
+	 * hangs if unintentionally inherited.  However to be safe we'll
+	 * continue to emit all of the SVG state since it's best not to leak
+	 * any of the state between contexts, even if that leakage is harmless.
 	 */
-	if (q->hwe->class != XE_ENGINE_CLASS_RENDER)
-		return;
-
-	switch (GRAPHICS_VERx100(xe)) {
-	case 1255:
-	case 1270 ... 2004:
+	if (XE_WA(gt, 14019789679) && q->hwe->class == XE_ENGINE_CLASS_RENDER) {
 		state_table = xe_hpg_svg_state;
 		state_table_size = ARRAY_SIZE(xe_hpg_svg_state);
-		break;
-	default:
+	}
+
+	if (!state_table) {
 		xe_gt_dbg(gt, "No non-register state to emit on graphics ver %d.%02d\n",
 			  GRAPHICS_VER(xe), GRAPHICS_VERx100(xe) % 100);
 		return;
@@ -1262,3 +1285,37 @@
 		bb->len += num_dw;
 	}
 }
+
+struct xe_lrc_snapshot *xe_lrc_snapshot_capture(struct xe_lrc *lrc)
+{
+	struct xe_lrc_snapshot *snapshot = kmalloc(sizeof(*snapshot), GFP_NOWAIT);
+
+	if (!snapshot)
+		return NULL;
+
+	snapshot->context_desc = xe_lrc_ggtt_addr(lrc);
+	snapshot->head = xe_lrc_ring_head(lrc);
+	snapshot->tail.internal = lrc->ring.tail;
+	snapshot->tail.memory = xe_lrc_read_ctx_reg(lrc, CTX_RING_TAIL);
+	snapshot->start_seqno = xe_lrc_start_seqno(lrc);
+	snapshot->seqno = xe_lrc_seqno(lrc);
+	return snapshot;
+}
+
+void xe_lrc_snapshot_print(struct xe_lrc_snapshot *snapshot, struct drm_printer *p)
+{
+	if (!snapshot)
+		return;
+
+	drm_printf(p, "\tHW Context Desc: 0x%08x\n", snapshot->context_desc);
+	drm_printf(p, "\tLRC Head: (memory) %u\n", snapshot->head);
+	drm_printf(p, "\tLRC Tail: (internal) %u, (memory) %u\n",
+		   snapshot->tail.internal, snapshot->tail.memory);
+	drm_printf(p, "\tStart seqno: (memory) %d\n", snapshot->start_seqno);
+	drm_printf(p, "\tSeqno: (memory) %d\n", snapshot->seqno);
+}
+
+void xe_lrc_snapshot_free(struct xe_lrc_snapshot *snapshot)
+{
+	kfree(snapshot);
+}
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_lrc.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_lrc.h
@@ -55,4 +55,8 @@
 
 void xe_lrc_emit_hwe_state_instructions(struct xe_exec_queue *q, struct xe_bb *bb);
 
+struct xe_lrc_snapshot *xe_lrc_snapshot_capture(struct xe_lrc *lrc);
+void xe_lrc_snapshot_print(struct xe_lrc_snapshot *snapshot, struct drm_printer *p);
+void xe_lrc_snapshot_free(struct xe_lrc_snapshot *snapshot);
+
 #endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_lrc_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_lrc_types.h
@@ -43,4 +43,6 @@
 	struct xe_hw_fence_ctx fence_ctx;
 };
 
+struct xe_lrc_snapshot;
+
 #endif
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_migrate.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_migrate.c
@@ -32,7 +32,6 @@
 #include "xe_sync.h"
 #include "xe_trace.h"
 #include "xe_vm.h"
-#include "xe_wa.h"
 
 /**
  * struct xe_migrate - migrate context.
@@ -68,7 +67,7 @@
 
 #define MAX_PREEMPTDISABLE_TRANSFER SZ_8M /* Around 1ms. */
 #define MAX_CCS_LIMITED_TRANSFER SZ_4M /* XE_PAGE_SIZE * (FIELD_MAX(XE2_CCS_SIZE_MASK) + 1) */
-#define NUM_KERNEL_PDE 17
+#define NUM_KERNEL_PDE 15
 #define NUM_PT_SLOTS 32
 #define LEVEL0_PAGE_TABLE_ENCODE_SIZE SZ_2M
 
@@ -126,10 +125,11 @@
 	struct xe_device *xe = tile_to_xe(tile);
 	u16 pat_index = xe->pat.idx[XE_CACHE_WB];
 	u8 id = tile->id;
-	u32 num_entries = NUM_PT_SLOTS, num_level = vm->pt_root[id]->level;
+	u32 num_entries = NUM_PT_SLOTS, num_level = vm->pt_root[id]->level,
+	    num_setup = num_level + 1;
 	u32 map_ofs, level, i;
 	struct xe_bo *bo, *batch = tile->mem.kernel_bb_pool->bo;
-	u64 entry;
+	u64 entry, pt30_ofs;
 
 	/* Can't bump NUM_PT_SLOTS too high */
 	BUILD_BUG_ON(NUM_PT_SLOTS > SZ_2M/XE_PAGE_SIZE);
@@ -145,14 +145,17 @@
 				  num_entries * XE_PAGE_SIZE,
 				  ttm_bo_type_kernel,
 				  XE_BO_CREATE_VRAM_IF_DGFX(tile) |
-				  XE_BO_CREATE_PINNED_BIT);
+				  XE_BO_CREATE_PINNED_BIT |
+				  XE_BO_PAGETABLE);
 	if (IS_ERR(bo))
 		return PTR_ERR(bo);
 
-	entry = vm->pt_ops->pde_encode_bo(bo, bo->size - XE_PAGE_SIZE, pat_index);
+	/* PT31 reserved for 2M identity map */
+	pt30_ofs = bo->size - 2 * XE_PAGE_SIZE;
+	entry = vm->pt_ops->pde_encode_bo(bo, pt30_ofs, pat_index);
 	xe_pt_write(xe, &vm->pt_root[id]->bo->vmap, 0, entry);
 
-	map_ofs = (num_entries - num_level) * XE_PAGE_SIZE;
+	map_ofs = (num_entries - num_setup) * XE_PAGE_SIZE;
 
 	/* Map the entire BO in our level 0 pt */
 	for (i = 0, level = 0; i < num_entries; level++) {
@@ -216,15 +219,15 @@
 		if (vm->flags & XE_VM_FLAG_64K && level == 1)
 			flags = XE_PDE_64K;
 
-		entry = vm->pt_ops->pde_encode_bo(bo, map_ofs + (level - 1) *
+		entry = vm->pt_ops->pde_encode_bo(bo, map_ofs + (u64)(level - 1) *
 						  XE_PAGE_SIZE, pat_index);
 		xe_map_wr(xe, &bo->vmap, map_ofs + XE_PAGE_SIZE * level, u64,
 			  entry | flags);
 	}
 
 	/* Write PDE's that point to our BO. */
-	for (i = 0; i < num_entries - num_level; i++) {
-		entry = vm->pt_ops->pde_encode_bo(bo, i * XE_PAGE_SIZE,
+	for (i = 0; i < map_ofs / PAGE_SIZE; i++) {
+		entry = vm->pt_ops->pde_encode_bo(bo, (u64)i * XE_PAGE_SIZE,
 						  pat_index);
 
 		xe_map_wr(xe, &bo->vmap, map_ofs + XE_PAGE_SIZE +
@@ -241,28 +244,54 @@
 	/* Identity map the entire vram at 256GiB offset */
 	if (IS_DGFX(xe)) {
 		u64 pos, ofs, flags;
+		/* XXX: Unclear if this should be usable_size? */
+		u64 vram_limit =  xe->mem.vram.actual_physical_size +
+			xe->mem.vram.dpa_base;
 
 		level = 2;
 		ofs = map_ofs + XE_PAGE_SIZE * level + 256 * 8;
 		flags = vm->pt_ops->pte_encode_addr(xe, 0, pat_index, level,
 						    true, 0);
 
+		xe_assert(xe, IS_ALIGNED(xe->mem.vram.usable_size, SZ_2M));
+
 		/*
-		 * Use 1GB pages, it shouldn't matter the physical amount of
-		 * vram is less, when we don't access it.
+		 * Use 1GB pages when possible, last chunk always use 2M
+		 * pages as mixing reserved memory (stolen, WOCPM) with a single
+		 * mapping is not allowed on certain platforms.
 		 */
-		for (pos = xe->mem.vram.dpa_base;
-		     pos < xe->mem.vram.actual_physical_size + xe->mem.vram.dpa_base;
-		     pos += SZ_1G, ofs += 8)
+		for (pos = xe->mem.vram.dpa_base; pos < vram_limit;
+		     pos += SZ_1G, ofs += 8) {
+			if (pos + SZ_1G >= vram_limit) {
+				u64 pt31_ofs = bo->size - XE_PAGE_SIZE;
+
+				entry = vm->pt_ops->pde_encode_bo(bo, pt31_ofs,
+								  pat_index);
+				xe_map_wr(xe, &bo->vmap, ofs, u64, entry);
+
+				flags = vm->pt_ops->pte_encode_addr(xe, 0,
+								    pat_index,
+								    level - 1,
+								    true, 0);
+
+				for (ofs = pt31_ofs; pos < vram_limit;
+				     pos += SZ_2M, ofs += 8)
+					xe_map_wr(xe, &bo->vmap, ofs, u64, pos | flags);
+				break;	/* Ensure pos == vram_limit assert correct */
+			}
+
 			xe_map_wr(xe, &bo->vmap, ofs, u64, pos | flags);
+		}
+
+		xe_assert(xe, pos == vram_limit);
 	}
 
 	/*
 	 * Example layout created above, with root level = 3:
 	 * [PT0...PT7]: kernel PT's for copy/clear; 64 or 4KiB PTE's
 	 * [PT8]: Kernel PT for VM_BIND, 4 KiB PTE's
-	 * [PT9...PT28]: Userspace PT's for VM_BIND, 4 KiB PTE's
-	 * [PT29 = PDE 0] [PT30 = PDE 1] [PT31 = PDE 2]
+	 * [PT9...PT27]: Userspace PT's for VM_BIND, 4 KiB PTE's
+	 * [PT28 = PDE 0] [PT29 = PDE 1] [PT30 = PDE 2] [PT31 = 2M vram identity map]
 	 *
 	 * This makes the lowest part of the VM point to the pagetables.
 	 * Hence the lowest 2M in the vm should point to itself, with a few writes
@@ -280,7 +309,7 @@
 #define VM_SA_UPDATE_UNIT_SIZE		(XE_PAGE_SIZE / NUM_VMUSA_UNIT_PER_PAGE)
 #define NUM_VMUSA_WRITES_PER_UNIT	(VM_SA_UPDATE_UNIT_SIZE / sizeof(u64))
 	drm_suballoc_manager_init(&m->vm_update_sa,
-				  (map_ofs / XE_PAGE_SIZE - NUM_KERNEL_PDE) *
+				  (size_t)(map_ofs / XE_PAGE_SIZE - NUM_KERNEL_PDE) *
 				  NUM_VMUSA_UNIT_PER_PAGE, 0);
 
 	m->pt_bo = bo;
@@ -288,10 +317,6 @@
 }
 
 /*
- * Due to workaround 16017236439, odd instance hardware copy engines are
- * faster than even instance ones.
- * This function returns the mask involving all fast copy engines and the
- * reserved copy engine to be used as logical mask for migrate engine.
  * Including the reserved copy engine is required to avoid deadlocks due to
  * migrate jobs servicing the faults gets stuck behind the job that faulted.
  */
@@ -305,8 +330,7 @@
 		if (hwe->class != XE_ENGINE_CLASS_COPY)
 			continue;
 
-		if (!XE_WA(gt, 16017236439) ||
-		    xe_gt_is_usm_hwe(gt, hwe) || hwe->instance & 1)
+		if (xe_gt_is_usm_hwe(gt, hwe))
 			logical_mask |= BIT(hwe->logical_instance);
 	}
 
@@ -357,6 +381,10 @@
 		if (!hwe || !logical_mask)
 			return ERR_PTR(-EINVAL);
 
+		/*
+		 * XXX: Currently only reserving 1 (likely slow) BCS instance on
+		 * PVC, may want to revisit if performance is needed.
+		 */
 		m->q = xe_exec_queue_create(xe, vm, logical_mask, 1, hwe,
 					    EXEC_QUEUE_FLAG_KERNEL |
 					    EXEC_QUEUE_FLAG_PERMANENT |
@@ -479,7 +507,7 @@
 	struct xe_vm *vm = m->q->vm;
 	u16 pat_index;
 	u32 ptes;
-	u64 ofs = at_pt * XE_PAGE_SIZE;
+	u64 ofs = (u64)at_pt * XE_PAGE_SIZE;
 	u64 cur_ofs;
 
 	/* Indirect access needs compression enabled uncached PAT index */
@@ -1327,7 +1355,7 @@
 						 GFP_KERNEL, true, 0);
 			if (IS_ERR(sa_bo)) {
 				err = PTR_ERR(sa_bo);
-				goto err;
+				goto err_bb;
 			}
 
 			ppgtt_ofs = NUM_KERNEL_PDE +
@@ -1378,7 +1406,7 @@
 					 update_idx);
 	if (IS_ERR(job)) {
 		err = PTR_ERR(job);
-		goto err_bb;
+		goto err_sa;
 	}
 
 	/* Wait on BO move */
@@ -1427,12 +1455,12 @@
 
 err_job:
 	xe_sched_job_put(job);
+err_sa:
+	drm_suballoc_free(sa_bo, NULL);
 err_bb:
 	if (!q)
 		mutex_unlock(&m->job_mutex);
 	xe_bb_free(bb, NULL);
-err:
-	drm_suballoc_free(sa_bo, NULL);
 	return ERR_PTR(err);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_mmio.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_mmio.c
@@ -218,6 +218,21 @@
 	return xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
 }
 
+static void vram_fini(void *arg)
+{
+	struct xe_device *xe = arg;
+	struct xe_tile *tile;
+	int id;
+
+	if (xe->mem.vram.mapping)
+		iounmap(xe->mem.vram.mapping);
+
+	xe->mem.vram.mapping = NULL;
+
+	for_each_tile(tile, xe, id)
+		tile->mem.vram.mapping = NULL;
+}
+
 int xe_mmio_probe_vram(struct xe_device *xe)
 {
 	struct xe_tile *tile;
@@ -294,10 +309,21 @@
 	drm_info(&xe->drm, "Available VRAM: %pa, %pa\n", &xe->mem.vram.io_start,
 		 &available_size);
 
-	return 0;
+	return devm_add_action_or_reset(xe->drm.dev, vram_fini, xe);
+}
+
+static void tiles_fini(void *arg)
+{
+	struct xe_device *xe = arg;
+	struct xe_tile *tile;
+	int id;
+
+	for_each_tile(tile, xe, id)
+		if (tile != xe_device_get_root_tile(xe))
+			tile->mmio.regs = NULL;
 }
 
-void xe_mmio_probe_tiles(struct xe_device *xe)
+int xe_mmio_probe_tiles(struct xe_device *xe)
 {
 	size_t tile_mmio_size = SZ_16M, tile_mmio_ext_size = xe->info.tile_mmio_ext_size;
 	u8 id, tile_count = xe->info.tile_count;
@@ -348,15 +374,18 @@
 			regs += tile_mmio_ext_size;
 		}
 	}
+
+	return devm_add_action_or_reset(xe->drm.dev, tiles_fini, xe);
 }
 
-static void mmio_fini(struct drm_device *drm, void *arg)
+static void mmio_fini(void *arg)
 {
 	struct xe_device *xe = arg;
+	struct xe_tile *root_tile = xe_device_get_root_tile(xe);
 
 	pci_iounmap(to_pci_dev(xe->drm.dev), xe->mmio.regs);
-	if (xe->mem.vram.mapping)
-		iounmap(xe->mem.vram.mapping);
+	xe->mmio.regs = NULL;
+	root_tile->mmio.regs = NULL;
 }
 
 static int xe_verify_lmem_ready(struct xe_device *xe)
@@ -394,7 +423,7 @@
 		return -EIO;
 	}
 
-	return drmm_add_action_or_reset(&xe->drm, mmio_fini, xe);
+	return devm_add_action_or_reset(xe->drm.dev, mmio_fini, xe);
 }
 
 int xe_mmio_root_tile_init(struct xe_device *xe)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_mmio.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_mmio.h
@@ -22,7 +22,7 @@
 
 int xe_mmio_init(struct xe_device *xe);
 int xe_mmio_root_tile_init(struct xe_device *xe);
-void xe_mmio_probe_tiles(struct xe_device *xe);
+int xe_mmio_probe_tiles(struct xe_device *xe);
 
 static inline u8 xe_mmio_read8(struct xe_gt *gt, struct xe_reg reg)
 {
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_module.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_module.c
@@ -8,6 +8,8 @@
 #include <linux/init.h>
 #include <linux/module.h>
 
+#include <drm/drm_module.h>
+
 #include "xe_drv.h"
 #include "xe_hw_fence.h"
 #include "xe_pci.h"
@@ -48,6 +50,14 @@
 MODULE_PARM_DESC(force_probe,
 		 "Force probe options for specified devices. See CONFIG_DRM_XE_FORCE_PROBE for details.");
 
+static int xe_check_nomodeset(void)
+{
+	if (drm_firmware_drivers_only())
+		return -ENODEV;
+
+	return 0;
+}
+
 struct init_funcs {
 	int (*init)(void);
 	void (*exit)(void);
@@ -55,6 +65,9 @@
 
 static const struct init_funcs init_funcs[] = {
 	{
+		.init = xe_check_nomodeset,
+	},
+	{
 		.init = xe_hw_fence_module_init,
 		.exit = xe_hw_fence_module_exit,
 	},
@@ -68,15 +81,35 @@
 	},
 };
 
+static int __init xe_call_init_func(unsigned int i)
+{
+	if (WARN_ON(i >= ARRAY_SIZE(init_funcs)))
+		return 0;
+	if (!init_funcs[i].init)
+		return 0;
+
+	return init_funcs[i].init();
+}
+
+static void xe_call_exit_func(unsigned int i)
+{
+	if (WARN_ON(i >= ARRAY_SIZE(init_funcs)))
+		return;
+	if (!init_funcs[i].exit)
+		return;
+
+	init_funcs[i].exit();
+}
+
 static int __init xe_init(void)
 {
 	int err, i;
 
 	for (i = 0; i < ARRAY_SIZE(init_funcs); i++) {
-		err = init_funcs[i].init();
+		err = xe_call_init_func(i);
 		if (err) {
 			while (i--)
-				init_funcs[i].exit();
+				xe_call_exit_func(i);
 			return err;
 		}
 	}
@@ -89,7 +122,7 @@
 	int i;
 
 	for (i = ARRAY_SIZE(init_funcs) - 1; i >= 0; i--)
-		init_funcs[i].exit();
+		xe_call_exit_func(i);
 }
 
 module_init(xe_init);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_pat.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_pat.c
@@ -452,7 +452,7 @@
 {
 	struct xe_device *xe = gt_to_xe(gt);
 
-	if (!xe->pat.ops->dump)
+	if (!xe->pat.ops)
 		return;
 
 	xe->pat.ops->dump(gt, p);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_pci.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_pci.c
@@ -848,6 +848,8 @@
 	if (err)
 		return err;
 
+	pci_restore_state(pdev);
+
 	err = pci_enable_device(pdev);
 	if (err)
 		return err;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_pcode.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_pcode.c
@@ -10,6 +10,8 @@
 
 #include <drm/drm_managed.h>
 
+#include "xe_assert.h"
+#include "xe_device.h"
 #include "xe_gt.h"
 #include "xe_mmio.h"
 #include "xe_pcode_api.h"
@@ -43,8 +45,6 @@
 		[PCODE_ERROR_MASK] = {-EPROTO, "Unknown"},
 	};
 
-	lockdep_assert_held(&gt->pcode.lock);
-
 	err = xe_mmio_read32(gt, PCODE_MAILBOX) & PCODE_ERROR_MASK;
 	if (err) {
 		drm_err(&gt_to_xe(gt)->drm, "PCODE Mailbox failed: %d %s", err,
@@ -55,17 +55,15 @@
 	return 0;
 }
 
-static int pcode_mailbox_rw(struct xe_gt *gt, u32 mbox, u32 *data0, u32 *data1,
-			    unsigned int timeout_ms, bool return_data,
-			    bool atomic)
+static int __pcode_mailbox_rw(struct xe_gt *gt, u32 mbox, u32 *data0, u32 *data1,
+			      unsigned int timeout_ms, bool return_data,
+			      bool atomic)
 {
 	int err;
 
 	if (gt_to_xe(gt)->info.skip_pcode)
 		return 0;
 
-	lockdep_assert_held(&gt->pcode.lock);
-
 	if ((xe_mmio_read32(gt, PCODE_MAILBOX) & PCODE_READY) != 0)
 		return -EAGAIN;
 
@@ -87,6 +85,18 @@
 	return pcode_mailbox_status(gt);
 }
 
+static int pcode_mailbox_rw(struct xe_gt *gt, u32 mbox, u32 *data0, u32 *data1,
+			    unsigned int timeout_ms, bool return_data,
+			    bool atomic)
+{
+	if (gt_to_xe(gt)->info.skip_pcode)
+		return 0;
+
+	lockdep_assert_held(&gt->pcode.lock);
+
+	return __pcode_mailbox_rw(gt, mbox, data0, data1, timeout_ms, return_data, atomic);
+}
+
 int xe_pcode_write_timeout(struct xe_gt *gt, u32 mbox, u32 data, int timeout)
 {
 	int err;
@@ -109,15 +119,21 @@
 	return err;
 }
 
-static int xe_pcode_try_request(struct xe_gt *gt, u32 mbox,
-				u32 request, u32 reply_mask, u32 reply,
-				u32 *status, bool atomic, int timeout_us)
+static int pcode_try_request(struct xe_gt *gt, u32 mbox,
+			     u32 request, u32 reply_mask, u32 reply,
+			     u32 *status, bool atomic, int timeout_us, bool locked)
 {
 	int slept, wait = 10;
 
+	xe_gt_assert(gt, timeout_us > 0);
+
 	for (slept = 0; slept < timeout_us; slept += wait) {
-		*status = pcode_mailbox_rw(gt, mbox, &request, NULL, 1, true,
-					   atomic);
+		if (locked)
+			*status = pcode_mailbox_rw(gt, mbox, &request, NULL, 1, true,
+						   atomic);
+		else
+			*status = __pcode_mailbox_rw(gt, mbox, &request, NULL, 1, true,
+						     atomic);
 		if ((*status == 0) && ((request & reply_mask) == reply))
 			return 0;
 
@@ -156,10 +172,12 @@
 	u32 status;
 	int ret;
 
+	xe_gt_assert(gt, timeout_base_ms <= 3);
+
 	mutex_lock(&gt->pcode.lock);
 
-	ret = xe_pcode_try_request(gt, mbox, request, reply_mask, reply, &status,
-				   false, timeout_base_ms * 1000);
+	ret = pcode_try_request(gt, mbox, request, reply_mask, reply, &status,
+				false, timeout_base_ms * 1000, true);
 	if (!ret)
 		goto out;
 
@@ -175,10 +193,9 @@
 	 */
 	drm_err(&gt_to_xe(gt)->drm,
 		"PCODE timeout, retrying with preemption disabled\n");
-	drm_WARN_ON_ONCE(&gt_to_xe(gt)->drm, timeout_base_ms > 1);
 	preempt_disable();
-	ret = xe_pcode_try_request(gt, mbox, request, reply_mask, reply, &status,
-				   true, timeout_base_ms * 1000);
+	ret = pcode_try_request(gt, mbox, request, reply_mask, reply, &status,
+				true, 50 * 1000, true);
 	preempt_enable();
 
 out:
@@ -238,59 +255,71 @@
 }
 
 /**
- * xe_pcode_init - Ensure PCODE is initialized
- * @gt: gt instance
+ * xe_pcode_ready - Ensure PCODE is initialized
+ * @xe: xe instance
+ * @locked: true if lock held, false otherwise
  *
- * This function ensures that PCODE is properly initialized. To be called during
- * probe and resume paths.
+ * PCODE init mailbox is polled only on root gt of root tile
+ * as the root tile provides the initialization is complete only
+ * after all the tiles have completed the initialization.
+ * Called only on early probe without locks and with locks in
+ * resume path.
  *
- * It returns 0 on success, and -error number on failure.
+ * Returns 0 on success, and -error number on failure.
  */
-int xe_pcode_init(struct xe_gt *gt)
+int xe_pcode_ready(struct xe_device *xe, bool locked)
 {
 	u32 status, request = DGFX_GET_INIT_STATUS;
+	struct xe_gt *gt = xe_root_mmio_gt(xe);
 	int timeout_us = 180000000; /* 3 min */
 	int ret;
 
-	if (gt_to_xe(gt)->info.skip_pcode)
+	if (xe->info.skip_pcode)
 		return 0;
 
-	if (!IS_DGFX(gt_to_xe(gt)))
+	if (!IS_DGFX(xe))
 		return 0;
 
-	mutex_lock(&gt->pcode.lock);
-	ret = xe_pcode_try_request(gt, DGFX_PCODE_STATUS, request,
-				   DGFX_INIT_STATUS_COMPLETE,
-				   DGFX_INIT_STATUS_COMPLETE,
-				   &status, false, timeout_us);
-	mutex_unlock(&gt->pcode.lock);
+	if (locked)
+		mutex_lock(&gt->pcode.lock);
+
+	ret = pcode_try_request(gt, DGFX_PCODE_STATUS, request,
+				DGFX_INIT_STATUS_COMPLETE,
+				DGFX_INIT_STATUS_COMPLETE,
+				&status, false, timeout_us, locked);
+
+	if (locked)
+		mutex_unlock(&gt->pcode.lock);
 
 	if (ret)
-		drm_err(&gt_to_xe(gt)->drm,
+		drm_err(&xe->drm,
 			"PCODE initialization timedout after: 3 min\n");
 
 	return ret;
 }
 
 /**
- * xe_pcode_probe - Prepare xe_pcode and also ensure PCODE is initialized.
+ * xe_pcode_init: initialize components of PCODE
  * @gt: gt instance
  *
- * This function initializes the xe_pcode component, and when needed, it ensures
- * that PCODE has properly performed its initialization and it is really ready
- * to go. To be called once only during probe.
- *
- * It returns 0 on success, and -error number on failure.
+ * This function initializes the xe_pcode component.
+ * To be called once only during probe.
  */
-int xe_pcode_probe(struct xe_gt *gt)
+void xe_pcode_init(struct xe_gt *gt)
 {
 	drmm_mutex_init(&gt_to_xe(gt)->drm, &gt->pcode.lock);
+}
 
-	if (gt_to_xe(gt)->info.skip_pcode)
-		return 0;
-
-	if (!IS_DGFX(gt_to_xe(gt)))
-		return 0;
-
-	return xe_pcode_init(gt);
+/**
+ * xe_pcode_probe_early: initializes PCODE
+ * @xe: xe instance
+ *
+ * This function checks the initialization status of PCODE
+ * To be called once only during early probe without locks.
+ *
+ * Returns 0 on success, error code otherwise
+ */
+int xe_pcode_probe_early(struct xe_device *xe)
+{
+	return xe_pcode_ready(xe, false);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_pcode.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_pcode.h
@@ -8,9 +8,11 @@
 
 #include <linux/types.h>
 struct xe_gt;
+struct xe_device;
 
-int xe_pcode_probe(struct xe_gt *gt);
-int xe_pcode_init(struct xe_gt *gt);
+void xe_pcode_init(struct xe_gt *gt);
+int xe_pcode_probe_early(struct xe_device *xe);
+int xe_pcode_ready(struct xe_device *xe, bool locked);
 int xe_pcode_init_min_freq_table(struct xe_gt *gt, u32 min_gt_freq,
 				 u32 max_gt_freq);
 int xe_pcode_read(struct xe_gt *gt, u32 mbox, u32 *val, u32 *val1);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_pm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_pm.c
@@ -54,21 +54,23 @@
 	u8 id;
 	int err;
 
+	drm_dbg(&xe->drm, "Suspending device\n");
+
 	for_each_gt(gt, xe, id)
 		xe_gt_suspend_prepare(gt);
 
+	xe_display_pm_suspend(xe, false);
+
 	/* FIXME: Super racey... */
 	err = xe_bo_evict_all(xe);
 	if (err)
-		return err;
-
-	xe_display_pm_suspend(xe);
+		goto err;
 
 	for_each_gt(gt, xe, id) {
 		err = xe_gt_suspend(gt);
 		if (err) {
-			xe_display_pm_resume(xe);
-			return err;
+			xe_display_pm_resume(xe, false);
+			goto err;
 		}
 	}
 
@@ -76,7 +78,11 @@
 
 	xe_display_pm_suspend_late(xe);
 
+	drm_dbg(&xe->drm, "Device suspended\n");
 	return 0;
+err:
+	drm_dbg(&xe->drm, "Device suspend failed %d\n", err);
+	return err;
 }
 
 /**
@@ -92,14 +98,14 @@
 	u8 id;
 	int err;
 
+	drm_dbg(&xe->drm, "Resuming device\n");
+
 	for_each_tile(tile, xe, id)
 		xe_wa_apply_tile_workarounds(tile);
 
-	for_each_gt(gt, xe, id) {
-		err = xe_pcode_init(gt);
-		if (err)
-			return err;
-	}
+	err = xe_pcode_ready(xe, true);
+	if (err)
+		return err;
 
 	xe_display_pm_resume_early(xe);
 
@@ -109,20 +115,24 @@
 	 */
 	err = xe_bo_restore_kernel(xe);
 	if (err)
-		return err;
+		goto err;
 
 	xe_irq_resume(xe);
 
-	xe_display_pm_resume(xe);
-
 	for_each_gt(gt, xe, id)
 		xe_gt_resume(gt);
 
+	xe_display_pm_resume(xe, false);
+
 	err = xe_bo_restore_user(xe);
 	if (err)
-		return err;
+		goto err;
 
+	drm_dbg(&xe->drm, "Device resumed\n");
 	return 0;
+err:
+	drm_dbg(&xe->drm, "Device resume failed %d\n", err);
+	return err;
 }
 
 static bool xe_pm_pci_d3cold_capable(struct pci_dev *pdev)
@@ -248,6 +258,8 @@
 	lock_map_acquire(&xe_device_mem_access_lockdep_map);
 
 	if (xe->d3cold.allowed) {
+		xe_display_pm_suspend(xe, true);
+
 		err = xe_bo_evict_all(xe);
 		if (err)
 			goto out;
@@ -260,7 +272,12 @@
 	}
 
 	xe_irq_suspend(xe);
+
+	if (xe->d3cold.allowed)
+		xe_display_pm_suspend_late(xe);
 out:
+	if (err)
+		xe_display_pm_resume(xe, true);
 	lock_map_release(&xe_device_mem_access_lockdep_map);
 	xe_pm_write_callback_task(xe, NULL);
 	return err;
@@ -286,11 +303,11 @@
 	xe->d3cold.power_lost = xe_guc_in_reset(&gt->uc.guc);
 
 	if (xe->d3cold.allowed && xe->d3cold.power_lost) {
-		for_each_gt(gt, xe, id) {
-			err = xe_pcode_init(gt);
-			if (err)
-				goto out;
-		}
+		err = xe_pcode_ready(xe, true);
+		if (err)
+			goto out;
+
+		xe_display_pm_resume_early(xe);
 
 		/*
 		 * This only restores pinned memory which is the memory
@@ -307,6 +324,7 @@
 		xe_gt_resume(gt);
 
 	if (xe->d3cold.allowed && xe->d3cold.power_lost) {
+		xe_display_pm_resume(xe, true);
 		err = xe_bo_restore_user(xe);
 		if (err)
 			goto out;
@@ -330,7 +348,7 @@
 
 int xe_pm_runtime_get_if_active(struct xe_device *xe)
 {
-	return pm_runtime_get_if_active(xe->drm.dev, true);
+	return pm_runtime_get_if_active(xe->drm.dev);
 }
 
 void xe_pm_assert_unbounded_bridge(struct xe_device *xe)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_preempt_fence.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_preempt_fence.c
@@ -17,17 +17,31 @@
 		container_of(w, typeof(*pfence), preempt_work);
 	struct xe_exec_queue *q = pfence->q;
 
-	if (pfence->error)
+	if (pfence->error) {
 		dma_fence_set_error(&pfence->base, pfence->error);
-	else
-		q->ops->suspend_wait(q);
+	} else if (!q->ops->reset_status(q)) {
+		int err = q->ops->suspend_wait(q);
 
-	dma_fence_signal(&pfence->base);
-	dma_fence_end_signalling(cookie);
+		if (err)
+			dma_fence_set_error(&pfence->base, err);
+	} else {
+		dma_fence_set_error(&pfence->base, -ENOENT);
+	}
 
+	dma_fence_signal(&pfence->base);
+	/*
+	 * Opt for keep everything in the fence critical section. This looks really strange since we
+	 * have just signalled the fence, however the preempt fences are all signalled via single
+	 * global ordered-wq, therefore anything that happens in this callback can easily block
+	 * progress on the entire wq, which itself may prevent other published preempt fences from
+	 * ever signalling.  Therefore try to keep everything here in the callback in the fence
+	 * critical section. For example if something below grabs a scary lock like vm->lock,
+	 * lockdep should complain since we also hold that lock whilst waiting on preempt fences to
+	 * complete.
+	 */
 	xe_vm_queue_rebind_worker(q->vm);
-
 	xe_exec_queue_put(q);
+	dma_fence_end_signalling(cookie);
 }
 
 static const char *
@@ -49,7 +63,7 @@
 	struct xe_exec_queue *q = pfence->q;
 
 	pfence->error = q->ops->suspend(q);
-	queue_work(system_unbound_wq, &pfence->preempt_work);
+	queue_work(q->vm->xe->preempt_fence_wq, &pfence->preempt_work);
 	return true;
 }
 
@@ -120,8 +134,9 @@
 {
 	list_del_init(&pfence->link);
 	pfence->q = xe_exec_queue_get(q);
+	spin_lock_init(&pfence->lock);
 	dma_fence_init(&pfence->base, &preempt_fence_ops,
-		      &q->compute.lock, context, seqno);
+		      &pfence->lock, context, seqno);
 
 	return &pfence->base;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_preempt_fence_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_preempt_fence_types.h
@@ -25,6 +25,8 @@
 	struct xe_exec_queue *q;
 	/** @preempt_work: work struct which issues preemption */
 	struct work_struct preempt_work;
+	/** @lock: dma-fence fence lock */
+	spinlock_t lock;
 	/** @error: preempt fence is in error state */
 	int error;
 };
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_pt.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_pt.c
@@ -1255,11 +1255,13 @@
 	 * non-faulting LR, in particular on user-space batch buffer chaining,
 	 * it needs to be done here.
 	 */
-	if ((rebind && !xe_vm_in_lr_mode(vm) && !vm->batch_invalidate_tlb) ||
-	    (!rebind && xe_vm_has_scratch(vm) && xe_vm_in_preempt_fence_mode(vm))) {
+	if ((!rebind && xe_vm_has_scratch(vm) && xe_vm_in_preempt_fence_mode(vm))) {
 		ifence = kzalloc(sizeof(*ifence), GFP_KERNEL);
 		if (!ifence)
 			return ERR_PTR(-ENOMEM);
+	} else if (rebind && !xe_vm_in_lr_mode(vm)) {
+		/* We bump also if batch_invalidate_tlb is true */
+		vm->tlb_flush_seqno++;
 	}
 
 	rfence = kzalloc(sizeof(*rfence), GFP_KERNEL);
@@ -1298,7 +1300,7 @@
 		}
 
 		/* add shared fence now for pagetable delayed destroy */
-		dma_resv_add_fence(xe_vm_resv(vm), fence, !rebind &&
+		dma_resv_add_fence(xe_vm_resv(vm), fence, rebind ||
 				   last_munmap_rebind ?
 				   DMA_RESV_USAGE_KERNEL :
 				   DMA_RESV_USAGE_BOOKKEEP);
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_query.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_query.c
@@ -132,7 +132,7 @@
 		return -EINVAL;
 
 	eci = &resp.eci;
-	if (eci->gt_id > XE_MAX_GT_PER_TILE)
+	if (eci->gt_id >= XE_MAX_GT_PER_TILE)
 		return -EINVAL;
 
 	gt = xe_device_get_gt(xe, eci->gt_id);
@@ -160,7 +160,11 @@
 
 	xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
 	xe_device_mem_access_put(xe);
-	resp.width = 36;
+
+	if (GRAPHICS_VER(xe) >= 20)
+		resp.width = 64;
+	else
+		resp.width = 36;
 
 	/* Only write to the output fields of user query */
 	if (put_user(resp.cpu_timestamp, &query_ptr->cpu_timestamp))
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_reg_sr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_reg_sr.c
@@ -26,46 +26,27 @@
 #include "xe_reg_whitelist.h"
 #include "xe_rtp_types.h"
 
-#define XE_REG_SR_GROW_STEP_DEFAULT	16
-
 static void reg_sr_fini(struct drm_device *drm, void *arg)
 {
 	struct xe_reg_sr *sr = arg;
+	struct xe_reg_sr_entry *entry;
+	unsigned long reg;
+
+	xa_for_each(&sr->xa, reg, entry)
+		kfree(entry);
 
 	xa_destroy(&sr->xa);
-	kfree(sr->pool.arr);
-	memset(&sr->pool, 0, sizeof(sr->pool));
 }
 
 int xe_reg_sr_init(struct xe_reg_sr *sr, const char *name, struct xe_device *xe)
 {
 	xa_init(&sr->xa);
-	memset(&sr->pool, 0, sizeof(sr->pool));
-	sr->pool.grow_step = XE_REG_SR_GROW_STEP_DEFAULT;
 	sr->name = name;
 
 	return drmm_add_action_or_reset(&xe->drm, reg_sr_fini, sr);
 }
 EXPORT_SYMBOL_IF_KUNIT(xe_reg_sr_init);
 
-static struct xe_reg_sr_entry *alloc_entry(struct xe_reg_sr *sr)
-{
-	if (sr->pool.used == sr->pool.allocated) {
-		struct xe_reg_sr_entry *arr;
-
-		arr = krealloc_array(sr->pool.arr,
-				     ALIGN(sr->pool.allocated + 1, sr->pool.grow_step),
-				     sizeof(*arr), GFP_KERNEL);
-		if (!arr)
-			return NULL;
-
-		sr->pool.arr = arr;
-		sr->pool.allocated += sr->pool.grow_step;
-	}
-
-	return &sr->pool.arr[sr->pool.used++];
-}
-
 static bool compatible_entries(const struct xe_reg_sr_entry *e1,
 			       const struct xe_reg_sr_entry *e2)
 {
@@ -111,7 +92,7 @@
 		return 0;
 	}
 
-	pentry = alloc_entry(sr);
+	pentry = kmalloc(sizeof(*pentry), GFP_KERNEL);
 	if (!pentry) {
 		ret = -ENOMEM;
 		goto fail;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_reg_sr_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_reg_sr_types.h
@@ -20,12 +20,6 @@
 };
 
 struct xe_reg_sr {
-	struct {
-		struct xe_reg_sr_entry *arr;
-		unsigned int used;
-		unsigned int allocated;
-		unsigned int grow_step;
-	} pool;
 	struct xarray xa;
 	const char *name;
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_ring_ops.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_ring_ops.c
@@ -78,6 +78,16 @@
 	return i;
 }
 
+static int emit_flush_dw(u32 *dw, int i)
+{
+	dw[i++] = MI_FLUSH_DW | MI_FLUSH_IMM_DW;
+	dw[i++] = 0;
+	dw[i++] = 0;
+	dw[i++] = 0;
+
+	return i;
+}
+
 static int emit_flush_imm_ggtt(u32 addr, u32 value, bool invalidate_tlb,
 			       u32 *dw, int i)
 {
@@ -227,10 +237,9 @@
 {
 	u32 dw[MAX_JOB_SIZE_DW], i = 0;
 	u32 ppgtt_flag = get_ppgtt_flag(job);
-	struct xe_vm *vm = job->q->vm;
 	struct xe_gt *gt = job->q->gt;
 
-	if (vm && vm->batch_invalidate_tlb) {
+	if (job->ring_ops_flush_tlb) {
 		dw[i++] = preparser_disable(true);
 		i = emit_flush_imm_ggtt(xe_lrc_start_seqno_ggtt_addr(lrc),
 					seqno, true, dw, i);
@@ -242,10 +251,12 @@
 
 	i = emit_bb_start(batch_addr, ppgtt_flag, dw, i);
 
-	if (job->user_fence.used)
+	if (job->user_fence.used) {
+		i = emit_flush_dw(dw, i);
 		i = emit_store_imm_ppgtt_posted(job->user_fence.addr,
 						job->user_fence.value,
 						dw, i);
+	}
 
 	i = emit_flush_imm_ggtt(xe_lrc_seqno_ggtt_addr(lrc), seqno, false, dw, i);
 
@@ -278,7 +289,6 @@
 	struct xe_gt *gt = job->q->gt;
 	struct xe_device *xe = gt_to_xe(gt);
 	bool decode = job->q->class == XE_ENGINE_CLASS_VIDEO_DECODE;
-	struct xe_vm *vm = job->q->vm;
 
 	dw[i++] = preparser_disable(true);
 
@@ -290,22 +300,24 @@
 			i = emit_aux_table_inv(gt, VE0_AUX_INV, dw, i);
 	}
 
-	if (vm && vm->batch_invalidate_tlb)
+	if (job->ring_ops_flush_tlb)
 		i = emit_flush_imm_ggtt(xe_lrc_start_seqno_ggtt_addr(lrc),
 					seqno, true, dw, i);
 
 	dw[i++] = preparser_disable(false);
 
-	if (!vm || !vm->batch_invalidate_tlb)
+	if (!job->ring_ops_flush_tlb)
 		i = emit_store_imm_ggtt(xe_lrc_start_seqno_ggtt_addr(lrc),
 					seqno, dw, i);
 
 	i = emit_bb_start(batch_addr, ppgtt_flag, dw, i);
 
-	if (job->user_fence.used)
+	if (job->user_fence.used) {
+		i = emit_flush_dw(dw, i);
 		i = emit_store_imm_ppgtt_posted(job->user_fence.addr,
 						job->user_fence.value,
 						dw, i);
+	}
 
 	i = emit_flush_imm_ggtt(xe_lrc_seqno_ggtt_addr(lrc), seqno, false, dw, i);
 
@@ -325,7 +337,6 @@
 	struct xe_gt *gt = job->q->gt;
 	struct xe_device *xe = gt_to_xe(gt);
 	bool lacks_render = !(gt->info.engine_mask & XE_HW_ENGINE_RCS_MASK);
-	struct xe_vm *vm = job->q->vm;
 	u32 mask_flags = 0;
 
 	dw[i++] = preparser_disable(true);
@@ -335,7 +346,7 @@
 		mask_flags = PIPE_CONTROL_3D_ENGINE_FLAGS;
 
 	/* See __xe_pt_bind_vma() for a discussion on TLB invalidations. */
-	i = emit_pipe_invalidate(mask_flags, vm && vm->batch_invalidate_tlb, dw, i);
+	i = emit_pipe_invalidate(mask_flags, job->ring_ops_flush_tlb, dw, i);
 
 	/* hsdes: 1809175790 */
 	if (has_aux_ccs(xe))
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_rtp.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_rtp.c
@@ -200,7 +200,7 @@
 	if (first == last)
 		bitmap_set(ctx->active_entries, first, 1);
 	else
-		bitmap_set(ctx->active_entries, first, last - first + 2);
+		bitmap_set(ctx->active_entries, first, last - first + 1);
 }
 
 /**
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_sched_job.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_sched_job.c
@@ -188,13 +188,14 @@
 {
 	struct xe_sched_job *job =
 		container_of(ref, struct xe_sched_job, refcount);
+	struct xe_exec_queue *q = job->q;
 
 	if (unlikely(job->q->flags & EXEC_QUEUE_FLAG_KERNEL))
 		xe_device_mem_access_put(job_to_xe(job));
-	xe_exec_queue_put(job->q);
 	dma_fence_put(job->fence);
 	drm_sched_job_cleanup(&job->drm);
 	job_free(job);
+	xe_exec_queue_put(q);
 }
 
 void xe_sched_job_set_error(struct xe_sched_job *job, int error)
@@ -250,6 +251,16 @@
 
 void xe_sched_job_arm(struct xe_sched_job *job)
 {
+	struct xe_exec_queue *q = job->q;
+	struct xe_vm *vm = q->vm;
+
+	if (vm && !xe_sched_job_is_migration(q) && !xe_vm_in_lr_mode(vm) &&
+	    (vm->batch_invalidate_tlb || vm->tlb_flush_seqno != q->tlb_flush_seqno)) {
+		xe_vm_assert_held(vm);
+		q->tlb_flush_seqno = vm->tlb_flush_seqno;
+		job->ring_ops_flush_tlb = true;
+	}
+
 	drm_sched_job_arm(&job->drm);
 }
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_sched_job_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_sched_job_types.h
@@ -39,6 +39,8 @@
 	} user_fence;
 	/** @migrate_flush_flags: Additional flush flags for migration jobs */
 	u32 migrate_flush_flags;
+	/** @ring_ops_flush_tlb: The ring ops need to flush TLB before payload. */
+	bool ring_ops_flush_tlb;
 	/** @batch_addr: batch buffer address of job */
 	u64 batch_addr[];
 };
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_sync.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_sync.c
@@ -54,7 +54,7 @@
 {
 	struct xe_user_fence *ufence;
 
-	ufence = kmalloc(sizeof(*ufence), GFP_KERNEL);
+	ufence = kzalloc(sizeof(*ufence), GFP_KERNEL);
 	if (!ufence)
 		return NULL;
 
@@ -80,8 +80,12 @@
 		mmput(ufence->mm);
 	}
 
-	wake_up_all(&ufence->xe->ufence_wq);
+	/*
+	 * Wake up waiters only after updating the ufence state, allowing the UMD
+	 * to safely reuse the same ufence without encountering -EBUSY errors.
+	 */
 	WRITE_ONCE(ufence->signalled, 1);
+	wake_up_all(&ufence->xe->ufence_wq);
 	user_fence_put(ufence);
 }
 
@@ -268,7 +272,7 @@
 	if (sync->fence)
 		dma_fence_put(sync->fence);
 	if (sync->chain_fence)
-		dma_fence_put(&sync->chain_fence->base);
+		dma_fence_chain_free(sync->chain_fence);
 	if (sync->ufence)
 		user_fence_put(sync->ufence);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_trace.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_trace.h
@@ -468,7 +468,7 @@
 	     TP_ARGS(vma)
 );
 
-DEFINE_EVENT(xe_vma, xe_vma_usm_invalidate,
+DEFINE_EVENT(xe_vma, xe_vma_invalidate,
 	     TP_PROTO(struct xe_vma *vma),
 	     TP_ARGS(vma)
 );
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c
@@ -205,6 +205,11 @@
 	u64 stolen_size, io_size, pgsize;
 	int err;
 
+	if (!mgr) {
+		drm_dbg_kms(&xe->drm, "Stolen mgr init failed\n");
+		return;
+	}
+
 	if (IS_DGFX(xe))
 		stolen_size = detect_bar2_dgfx(xe, mgr);
 	else if (GRAPHICS_VERx100(xe) >= 1270)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
@@ -91,7 +91,7 @@
 
 	min_page_size = mgr->default_page_size;
 	if (tbo->page_alignment)
-		min_page_size = tbo->page_alignment << PAGE_SHIFT;
+		min_page_size = (u64)tbo->page_alignment << PAGE_SHIFT;
 
 	if (WARN_ON(min_page_size < mm->chunk_size)) {
 		err = -EINVAL;
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_tuning.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_tuning.c
@@ -86,6 +86,14 @@
 				   REG_FIELD_PREP(L3_PWM_TIMER_INIT_VAL_MASK, 0x7f)))
 	},
 
+	/* Xe2_HPG */
+
+	{ XE_RTP_NAME("Tuning: vs hit max value"),
+	  XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)),
+	  XE_RTP_ACTIONS(FIELD_SET(FF_MODE, VS_HIT_MAX_VALUE_MASK,
+				   REG_FIELD_PREP(VS_HIT_MAX_VALUE_MASK, 0x3f)))
+	},
+
 	{}
 };
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_uc_fw.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_uc_fw.h
@@ -63,7 +63,7 @@
 	return "<invalid>";
 }
 
-static inline int xe_uc_fw_status_to_error(enum xe_uc_fw_status status)
+static inline int xe_uc_fw_status_to_error(const enum xe_uc_fw_status status)
 {
 	switch (status) {
 	case XE_UC_FIRMWARE_NOT_SUPPORTED:
@@ -105,7 +105,7 @@
 }
 
 static inline enum xe_uc_fw_status
-__xe_uc_fw_status(struct xe_uc_fw *uc_fw)
+__xe_uc_fw_status(const struct xe_uc_fw *uc_fw)
 {
 	/* shouldn't call this before checking hw/blob availability */
 	XE_WARN_ON(uc_fw->status == XE_UC_FIRMWARE_UNINITIALIZED);
@@ -152,6 +152,11 @@
 	return uc_fw->user_overridden;
 }
 
+static inline bool xe_uc_fw_is_in_error_state(const struct xe_uc_fw *uc_fw)
+{
+	return xe_uc_fw_status_to_error(__xe_uc_fw_status(uc_fw)) < 0;
+}
+
 static inline void xe_uc_fw_sanitize(struct xe_uc_fw *uc_fw)
 {
 	if (xe_uc_fw_is_loaded(uc_fw))
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_vm.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_vm.c
@@ -179,10 +179,10 @@
 	lockdep_assert_held(&vm->lock);
 	xe_vm_assert_held(vm);
 
-	list_for_each_entry(q, &vm->preempt.exec_queues, compute.link) {
-		if (!q->compute.pfence ||
-		    (q->compute.pfence && test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
-						   &q->compute.pfence->flags))) {
+	list_for_each_entry(q, &vm->preempt.exec_queues, lr.link) {
+		if (!q->lr.pfence ||
+		    test_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
+			     &q->lr.pfence->flags)) {
 			return true;
 		}
 	}
@@ -225,14 +225,16 @@
 
 	xe_vm_assert_held(vm);
 
-	list_for_each_entry(q, &vm->preempt.exec_queues, compute.link) {
-		if (q->compute.pfence) {
-			long timeout = dma_fence_wait(q->compute.pfence, false);
+	list_for_each_entry(q, &vm->preempt.exec_queues, lr.link) {
+		if (q->lr.pfence) {
+			long timeout = dma_fence_wait(q->lr.pfence, false);
 
-			if (timeout < 0)
+			/* Only -ETIME on fence indicates VM needs to be killed */
+			if (timeout < 0 || q->lr.pfence->error == -ETIME)
 				return -ETIME;
-			dma_fence_put(q->compute.pfence);
-			q->compute.pfence = NULL;
+
+			dma_fence_put(q->lr.pfence);
+			q->lr.pfence = NULL;
 		}
 	}
 
@@ -244,7 +246,7 @@
 	struct xe_exec_queue *q;
 
 	xe_vm_assert_held(vm);
-	list_for_each_entry(q, &vm->preempt.exec_queues, compute.link) {
+	list_for_each_entry(q, &vm->preempt.exec_queues, lr.link) {
 		if (!xe_exec_queue_is_idle(q))
 			return false;
 	}
@@ -257,17 +259,17 @@
 	struct list_head *link;
 	struct xe_exec_queue *q;
 
-	list_for_each_entry(q, &vm->preempt.exec_queues, compute.link) {
+	list_for_each_entry(q, &vm->preempt.exec_queues, lr.link) {
 		struct dma_fence *fence;
 
 		link = list->next;
 		xe_assert(vm->xe, link != list);
 
 		fence = xe_preempt_fence_arm(to_preempt_fence_from_link(link),
-					     q, q->compute.context,
-					     ++q->compute.seqno);
-		dma_fence_put(q->compute.pfence);
-		q->compute.pfence = fence;
+					     q, q->lr.context,
+					     ++q->lr.seqno);
+		dma_fence_put(q->lr.pfence);
+		q->lr.pfence = fence;
 	}
 }
 
@@ -287,10 +289,10 @@
 	if (err)
 		goto out_unlock;
 
-	list_for_each_entry(q, &vm->preempt.exec_queues, compute.link)
-		if (q->compute.pfence) {
+	list_for_each_entry(q, &vm->preempt.exec_queues, lr.link)
+		if (q->lr.pfence) {
 			dma_resv_add_fence(bo->ttm.base.resv,
-					   q->compute.pfence,
+					   q->lr.pfence,
 					   DMA_RESV_USAGE_BOOKKEEP);
 		}
 
@@ -307,10 +309,10 @@
 	lockdep_assert_held(&vm->lock);
 	xe_vm_assert_held(vm);
 
-	list_for_each_entry(q, &vm->preempt.exec_queues, compute.link) {
+	list_for_each_entry(q, &vm->preempt.exec_queues, lr.link) {
 		q->ops->resume(q);
 
-		drm_gpuvm_resv_add_fence(&vm->gpuvm, exec, q->compute.pfence,
+		drm_gpuvm_resv_add_fence(&vm->gpuvm, exec, q->lr.pfence,
 					 DMA_RESV_USAGE_BOOKKEEP, DMA_RESV_USAGE_BOOKKEEP);
 	}
 }
@@ -334,16 +336,16 @@
 	if (err)
 		goto out_up_write;
 
-	pfence = xe_preempt_fence_create(q, q->compute.context,
-					 ++q->compute.seqno);
+	pfence = xe_preempt_fence_create(q, q->lr.context,
+					 ++q->lr.seqno);
 	if (!pfence) {
 		err = -ENOMEM;
 		goto out_fini;
 	}
 
-	list_add(&q->compute.link, &vm->preempt.exec_queues);
+	list_add(&q->lr.link, &vm->preempt.exec_queues);
 	++vm->preempt.num_exec_queues;
-	q->compute.pfence = pfence;
+	q->lr.pfence = pfence;
 
 	down_read(&vm->userptr.notifier_lock);
 
@@ -380,12 +382,12 @@
 		return;
 
 	down_write(&vm->lock);
-	list_del(&q->compute.link);
+	list_del(&q->lr.link);
 	--vm->preempt.num_exec_queues;
-	if (q->compute.pfence) {
-		dma_fence_enable_sw_signaling(q->compute.pfence);
-		dma_fence_put(q->compute.pfence);
-		q->compute.pfence = NULL;
+	if (q->lr.pfence) {
+		dma_fence_enable_sw_signaling(q->lr.pfence);
+		dma_fence_put(q->lr.pfence);
+		q->lr.pfence = NULL;
 	}
 	up_write(&vm->lock);
 }
@@ -411,6 +413,14 @@
 
 #define XE_VM_REBIND_RETRY_TIMEOUT_MS 1000
 
+/*
+ * xe_vm_kill() - VM Kill
+ * @vm: The VM.
+ * @unlocked: Flag indicates the VM's dma-resv is not held
+ *
+ * Kill the VM by setting banned flag indicated VM is no longer available for
+ * use. If in preempt fence mode, also kill all exec queue attached to the VM.
+ */
 static void xe_vm_kill(struct xe_vm *vm)
 {
 	struct xe_exec_queue *q;
@@ -421,7 +431,7 @@
 	vm->flags |= XE_VM_FLAG_BANNED;
 	trace_xe_vm_kill(vm);
 
-	list_for_each_entry(q, &vm->preempt.exec_queues, compute.link)
+	list_for_each_entry(q, &vm->preempt.exec_queues, lr.link)
 		q->ops->kill(q);
 	xe_vm_unlock(vm);
 
@@ -520,7 +530,6 @@
 {
 	struct xe_vm *vm = container_of(w, struct xe_vm, preempt.rebind_work);
 	struct drm_exec exec;
-	struct dma_fence *rebind_fence;
 	unsigned int fence_count = 0;
 	LIST_HEAD(preempt_fences);
 	ktime_t end = 0;
@@ -566,18 +575,11 @@
 	if (err)
 		goto out_unlock;
 
-	rebind_fence = xe_vm_rebind(vm, true);
-	if (IS_ERR(rebind_fence)) {
-		err = PTR_ERR(rebind_fence);
+	err = xe_vm_rebind(vm, true);
+	if (err)
 		goto out_unlock;
-	}
-
-	if (rebind_fence) {
-		dma_fence_wait(rebind_fence, false);
-		dma_fence_put(rebind_fence);
-	}
 
-	/* Wait on munmap style VM unbinds */
+	/* Wait on rebinds and munmap style VM unbinds */
 	wait = dma_resv_wait_timeout(xe_vm_resv(vm),
 				     DMA_RESV_USAGE_KERNEL,
 				     false, MAX_SCHEDULE_TIMEOUT);
@@ -706,6 +708,7 @@
 	int err = 0;
 	LIST_HEAD(tmp_evict);
 
+	xe_assert(vm->xe, !xe_vm_in_fault_mode(vm));
 	lockdep_assert_held_write(&vm->lock);
 
 	/* Collect invalidated userptrs */
@@ -722,11 +725,27 @@
 	list_for_each_entry_safe(uvma, next, &vm->userptr.repin_list,
 				 userptr.repin_link) {
 		err = xe_vma_userptr_pin_pages(uvma);
-		if (err < 0)
-			return err;
+		if (err == -EFAULT) {
+			list_del_init(&uvma->userptr.repin_link);
 
-		list_del_init(&uvma->userptr.repin_link);
-		list_move_tail(&uvma->vma.combined_links.rebind, &vm->rebind_list);
+			/* Wait for pending binds */
+			xe_vm_lock(vm, false);
+			dma_resv_wait_timeout(xe_vm_resv(vm),
+					      DMA_RESV_USAGE_BOOKKEEP,
+					      false, MAX_SCHEDULE_TIMEOUT);
+
+			err = xe_vm_invalidate_vma(&uvma->vma);
+			xe_vm_unlock(vm);
+			if (err)
+				return err;
+		} else {
+			if (err < 0)
+				return err;
+
+			list_del_init(&uvma->userptr.repin_link);
+			list_move_tail(&uvma->vma.combined_links.rebind,
+				       &vm->rebind_list);
+		}
 	}
 
 	return 0;
@@ -754,14 +773,14 @@
 	       struct xe_sync_entry *syncs, u32 num_syncs,
 	       bool first_op, bool last_op);
 
-struct dma_fence *xe_vm_rebind(struct xe_vm *vm, bool rebind_worker)
+int xe_vm_rebind(struct xe_vm *vm, bool rebind_worker)
 {
-	struct dma_fence *fence = NULL;
+	struct dma_fence *fence;
 	struct xe_vma *vma, *next;
 
 	lockdep_assert_held(&vm->lock);
 	if (xe_vm_in_lr_mode(vm) && !rebind_worker)
-		return NULL;
+		return 0;
 
 	xe_vm_assert_held(vm);
 	list_for_each_entry_safe(vma, next, &vm->rebind_list,
@@ -769,17 +788,17 @@
 		xe_assert(vm->xe, vma->tile_present);
 
 		list_del_init(&vma->combined_links.rebind);
-		dma_fence_put(fence);
 		if (rebind_worker)
 			trace_xe_vma_rebind_worker(vma);
 		else
 			trace_xe_vma_rebind_exec(vma);
 		fence = xe_vm_bind_vma(vma, NULL, NULL, 0, false, false);
 		if (IS_ERR(fence))
-			return fence;
+			return PTR_ERR(fence);
+		dma_fence_put(fence);
 	}
 
-	return fence;
+	return 0;
 }
 
 static void xe_vma_free(struct xe_vma *vma)
@@ -1558,7 +1577,6 @@
 		XE_WARN_ON(vm->pt_root[id]);
 
 	trace_xe_vm_free(vm);
-	dma_fence_put(vm->rebind_fence);
 	kfree(vm);
 }
 
@@ -1916,12 +1934,6 @@
 	if (IS_ERR(vm))
 		return PTR_ERR(vm);
 
-	mutex_lock(&xef->vm.lock);
-	err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL);
-	mutex_unlock(&xef->vm.lock);
-	if (err)
-		goto err_close_and_put;
-
 	if (xe->info.has_asid) {
 		mutex_lock(&xe->usm.lock);
 		err = xa_alloc_cyclic(&xe->usm.asid_to_vm, &asid, vm,
@@ -1929,12 +1941,11 @@
 				      &xe->usm.next_asid, GFP_KERNEL);
 		mutex_unlock(&xe->usm.lock);
 		if (err < 0)
-			goto err_free_id;
+			goto err_close_and_put;
 
 		vm->usm.asid = asid;
 	}
 
-	args->vm_id = id;
 	vm->xef = xef;
 
 	/* Record BO memory for VM pagetable created against client */
@@ -1947,12 +1958,17 @@
 	args->reserved[0] = xe_bo_main_addr(vm->pt_root[0]->bo, XE_PAGE_SIZE);
 #endif
 
-	return 0;
-
-err_free_id:
+	/* user id alloc must always be last in ioctl to prevent UAF */
 	mutex_lock(&xef->vm.lock);
-	xa_erase(&xef->vm.xa, id);
+	err = xa_alloc(&xef->vm.xa, &id, vm, xa_limit_32b, GFP_KERNEL);
 	mutex_unlock(&xef->vm.lock);
+	if (err)
+		goto err_close_and_put;
+
+	args->vm_id = id;
+
+	return 0;
+
 err_close_and_put:
 	xe_vm_close_and_put(vm);
 
@@ -2010,7 +2026,7 @@
 			return err;
 	}
 
-	if (vma->tile_mask != (vma->tile_present & ~vma->usm.tile_invalidated)) {
+	if (vma->tile_mask != (vma->tile_present & ~vma->tile_invalidated)) {
 		return xe_vm_bind(vm, vma, q, xe_vma_bo(vma), syncs, num_syncs,
 				  true, first_op, last_op);
 	} else {
@@ -3184,9 +3200,8 @@
 	u8 id;
 	int ret;
 
-	xe_assert(xe, xe_vm_in_fault_mode(xe_vma_vm(vma)));
 	xe_assert(xe, !xe_vma_is_null(vma));
-	trace_xe_vma_usm_invalidate(vma);
+	trace_xe_vma_invalidate(vma);
 
 	/* Check that we don't race with page-table updates */
 	if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
@@ -3224,7 +3239,7 @@
 		}
 	}
 
-	vma->usm.tile_invalidated = vma->tile_mask;
+	vma->tile_invalidated = vma->tile_mask;
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_vm.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_vm.h
@@ -207,7 +207,7 @@
 
 int xe_vm_userptr_check_repin(struct xe_vm *vm);
 
-struct dma_fence *xe_vm_rebind(struct xe_vm *vm, bool rebind_worker);
+int xe_vm_rebind(struct xe_vm *vm, bool rebind_worker);
 
 int xe_vm_invalidate_vma(struct xe_vma *vma);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_vm_types.h
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_vm_types.h
@@ -83,11 +83,8 @@
 		struct work_struct destroy_work;
 	};
 
-	/** @usm: unified shared memory state */
-	struct {
-		/** @tile_invalidated: VMA has been invalidated */
-		u8 tile_invalidated;
-	} usm;
+	/** @tile_invalidated: VMA has been invalidated */
+	u8 tile_invalidated;
 
 	/** @tile_mask: Tile mask of where to create binding for this VMA */
 	u8 tile_mask;
@@ -174,9 +171,6 @@
 	 */
 	struct list_head rebind_list;
 
-	/** @rebind_fence: rebind fence from execbuf */
-	struct dma_fence *rebind_fence;
-
 	/**
 	 * @destroy_work: worker to destroy VM, needed as a dma_fence signaling
 	 * from an irq context can be last put and the destroy needs to be able
@@ -285,6 +279,11 @@
 		bool capture_once;
 	} error_capture;
 
+	/**
+	 * @tlb_flush_seqno: Required TLB flush seqno for the next exec.
+	 * protected by the vm resv.
+	 */
+	u64 tlb_flush_seqno;
 	/** @batch_invalidate_tlb: Always invalidate TLB before batch start */
 	bool batch_invalidate_tlb;
 	/** @xef: XE file handle for tracking this VM's drm client */
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_wa.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_wa.c
@@ -528,6 +528,14 @@
 	  XE_RTP_ACTIONS(SET(XEHP_HDC_CHICKEN0, DIS_ATOMIC_CHAINING_TYPED_WRITES,
 			     XE_RTP_NOCHECK))
 	},
+	{ XE_RTP_NAME("14021402888"),
+	  XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)),
+	  XE_RTP_ACTIONS(SET(HALF_SLICE_CHICKEN7, CLEAR_OPTIMIZATION_DISABLE))
+	},
+	{ XE_RTP_NAME("14021402888"),
+	  XE_RTP_RULES(GRAPHICS_VERSION(2004), ENGINE_CLASS(RENDER)),
+	  XE_RTP_ACTIONS(SET(HALF_SLICE_CHICKEN7, CLEAR_OPTIMIZATION_DISABLE))
+	},
 
 	/* PVC */
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_wa_oob.rules
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_wa_oob.rules
@@ -22,3 +22,5 @@
 14019821291	MEDIA_VERSION_RANGE(1300, 2000)
 14015076503	MEDIA_VERSION(1300)
 16020292621	GRAPHICS_VERSION(2004), GRAPHICS_STEP(A0, B0)
+14019789679	GRAPHICS_VERSION(1255)
+		GRAPHICS_VERSION_RANGE(1270, 2004)
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xe/xe_wait_user_fence.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xe/xe_wait_user_fence.c
@@ -155,6 +155,13 @@
 		}
 
 		if (!timeout) {
+			LNL_FLUSH_WORKQUEUE(xe->ordered_wq);
+			err = do_compare(addr, args->value, args->mask,
+					 args->op);
+			if (err <= 0) {
+				drm_dbg(&xe->drm, "LNL_FLUSH_WORKQUEUE resolved ufence timeout\n");
+				break;
+			}
 			err = -ETIME;
 			break;
 		}
@@ -169,9 +176,6 @@
 			args->timeout = 0;
 	}
 
-	if (!timeout && !(err < 0))
-		err = -ETIME;
-
 	if (q)
 		xe_exec_queue_put(q);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xlnx/zynqmp_dpsub.c
@@ -256,12 +256,12 @@
 	if (ret)
 		goto err_dp;
 
+	drm_bridge_add(dpsub->bridge);
+
 	if (dpsub->dma_enabled) {
 		ret = zynqmp_dpsub_drm_init(dpsub);
 		if (ret)
 			goto err_disp;
-	} else {
-		drm_bridge_add(dpsub->bridge);
 	}
 
 	dev_info(&pdev->dev, "ZynqMP DisplayPort Subsystem driver probed");
@@ -269,6 +269,7 @@
 	return 0;
 
 err_disp:
+	drm_bridge_remove(dpsub->bridge);
 	zynqmp_disp_remove(dpsub);
 err_dp:
 	zynqmp_dp_remove(dpsub);
@@ -288,9 +289,8 @@
 
 	if (dpsub->drm)
 		zynqmp_dpsub_drm_cleanup(dpsub);
-	else
-		drm_bridge_remove(dpsub->bridge);
 
+	drm_bridge_remove(dpsub->bridge);
 	zynqmp_disp_remove(dpsub);
 	zynqmp_dp_remove(dpsub);
 
--- linux-qcom-6.8.0.orig/drivers/gpu/drm/xlnx/zynqmp_kms.c
+++ linux-qcom-6.8.0/drivers/gpu/drm/xlnx/zynqmp_kms.c
@@ -433,23 +433,28 @@
 				DRM_BRIDGE_ATTACH_NO_CONNECTOR);
 	if (ret) {
 		dev_err(dpsub->dev, "failed to attach bridge to encoder\n");
-		return ret;
+		goto err_encoder;
 	}
 
 	/* Create the connector for the chain of bridges. */
 	connector = drm_bridge_connector_init(&dpsub->drm->dev, encoder);
 	if (IS_ERR(connector)) {
 		dev_err(dpsub->dev, "failed to created connector\n");
-		return PTR_ERR(connector);
+		ret = PTR_ERR(connector);
+		goto err_encoder;
 	}
 
 	ret = drm_connector_attach_encoder(connector, encoder);
 	if (ret < 0) {
 		dev_err(dpsub->dev, "failed to attach connector to encoder\n");
-		return ret;
+		goto err_encoder;
 	}
 
 	return 0;
+
+err_encoder:
+	drm_encoder_cleanup(encoder);
+	return ret;
 }
 
 static void zynqmp_dpsub_drm_release(struct drm_device *drm, void *res)
@@ -500,12 +505,12 @@
 	if (ret)
 		return ret;
 
-	drm_kms_helper_poll_init(drm);
-
 	ret = zynqmp_dpsub_kms_init(dpsub);
 	if (ret < 0)
 		goto err_poll_fini;
 
+	drm_kms_helper_poll_init(drm);
+
 	/* Reset all components and register the DRM device. */
 	drm_mode_config_reset(drm);
 
@@ -527,7 +532,8 @@
 {
 	struct drm_device *drm = &dpsub->drm->dev;
 
-	drm_dev_unregister(drm);
+	drm_dev_unplug(drm);
 	drm_atomic_helper_shutdown(drm);
+	drm_encoder_cleanup(&dpsub->drm->encoder);
 	drm_kms_helper_poll_fini(drm);
 }
--- linux-qcom-6.8.0.orig/drivers/gpu/host1x/bus.c
+++ linux-qcom-6.8.0/drivers/gpu/host1x/bus.c
@@ -351,11 +351,6 @@
 	return 0;
 }
 
-static int host1x_dma_configure(struct device *dev)
-{
-	return of_dma_configure(dev, dev->of_node, true);
-}
-
 static const struct dev_pm_ops host1x_device_pm_ops = {
 	.suspend = pm_generic_suspend,
 	.resume = pm_generic_resume,
@@ -369,7 +364,6 @@
 	.name = "host1x",
 	.match = host1x_device_match,
 	.uevent = host1x_device_uevent,
-	.dma_configure = host1x_dma_configure,
 	.pm = &host1x_device_pm_ops,
 };
 
@@ -458,8 +452,6 @@
 	device->dev.bus = &host1x_bus_type;
 	device->dev.parent = host1x->dev;
 
-	of_dma_configure(&device->dev, host1x->dev->of_node, true);
-
 	device->dev.dma_parms = &device->dma_parms;
 	dma_set_max_seg_size(&device->dev, UINT_MAX);
 
--- linux-qcom-6.8.0.orig/drivers/greybus/interface.c
+++ linux-qcom-6.8.0/drivers/greybus/interface.c
@@ -694,6 +694,7 @@
 
 	trace_gb_interface_release(intf);
 
+	cancel_work_sync(&intf->mode_switch_work);
 	kfree(intf);
 }
 
--- linux-qcom-6.8.0.orig/drivers/hid/amd-sfh-hid/Kconfig
+++ linux-qcom-6.8.0/drivers/hid/amd-sfh-hid/Kconfig
@@ -6,6 +6,7 @@
 config AMD_SFH_HID
 	tristate "AMD Sensor Fusion Hub"
 	depends on HID
+	depends on X86
 	help
 	  If you say yes to this option, support will be included for the
 	  AMD Sensor Fusion Hub.
--- linux-qcom-6.8.0.orig/drivers/hid/amd-sfh-hid/amd_sfh_client.c
+++ linux-qcom-6.8.0/drivers/hid/amd-sfh-hid/amd_sfh_client.c
@@ -236,9 +236,9 @@
 	cl_data->in_data = in_data;
 
 	for (i = 0; i < cl_data->num_hid_devices; i++) {
-		in_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8,
-								  &cl_data->sensor_dma_addr[i],
-								  GFP_KERNEL);
+		in_data->sensor_virt_addr[i] = dmam_alloc_coherent(dev, sizeof(int) * 8,
+								   &cl_data->sensor_dma_addr[i],
+								   GFP_KERNEL);
 		if (!in_data->sensor_virt_addr[i]) {
 			rc = -ENOMEM;
 			goto cleanup;
@@ -288,12 +288,22 @@
 		mp2_ops->start(privdata, info);
 		cl_data->sensor_sts[i] = amd_sfh_wait_for_response
 						(privdata, cl_data->sensor_idx[i], SENSOR_ENABLED);
+
+		if (cl_data->sensor_sts[i] == SENSOR_ENABLED)
+			cl_data->is_any_sensor_enabled = true;
+	}
+
+	if (!cl_data->is_any_sensor_enabled ||
+	    (mp2_ops->discovery_status && mp2_ops->discovery_status(privdata) == 0)) {
+		dev_warn(dev, "Failed to discover, sensors not enabled is %d\n",
+			 cl_data->is_any_sensor_enabled);
+		rc = -EOPNOTSUPP;
+		goto cleanup;
 	}
 
 	for (i = 0; i < cl_data->num_hid_devices; i++) {
 		cl_data->cur_hid_dev = i;
 		if (cl_data->sensor_sts[i] == SENSOR_ENABLED) {
-			cl_data->is_any_sensor_enabled = true;
 			rc = amdtp_hid_probe(i, cl_data);
 			if (rc)
 				goto cleanup;
@@ -305,12 +315,6 @@
 			cl_data->sensor_sts[i]);
 	}
 
-	if (!cl_data->is_any_sensor_enabled ||
-	   (mp2_ops->discovery_status && mp2_ops->discovery_status(privdata) == 0)) {
-		dev_warn(dev, "Failed to discover, sensors not enabled is %d\n", cl_data->is_any_sensor_enabled);
-		rc = -EOPNOTSUPP;
-		goto cleanup;
-	}
 	schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP));
 	return 0;
 
@@ -327,7 +331,6 @@
 int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata)
 {
 	struct amdtp_cl_data *cl_data = privdata->cl_data;
-	struct amd_input_data *in_data = cl_data->in_data;
 	int i, status;
 
 	for (i = 0; i < cl_data->num_hid_devices; i++) {
@@ -347,12 +350,5 @@
 	cancel_delayed_work_sync(&cl_data->work_buffer);
 	amdtp_hid_remove(cl_data);
 
-	for (i = 0; i < cl_data->num_hid_devices; i++) {
-		if (in_data->sensor_virt_addr[i]) {
-			dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int),
-					  in_data->sensor_virt_addr[i],
-					  cl_data->sensor_dma_addr[i]);
-		}
-	}
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/hid/amd-sfh-hid/amd_sfh_common.h
+++ linux-qcom-6.8.0/drivers/hid/amd-sfh-hid/amd_sfh_common.h
@@ -19,6 +19,9 @@
 #define AMD_C2P_MSG(regno) (0x10500 + ((regno) * 4))
 #define AMD_P2C_MSG(regno) (0x10680 + ((regno) * 4))
 
+#define AMD_C2P_MSG_V1(regno) (0x10900 + ((regno) * 4))
+#define AMD_P2C_MSG_V1(regno) (0x10500 + ((regno) * 4))
+
 #define SENSOR_ENABLED			4
 #define SENSOR_DISABLED			5
 
@@ -53,6 +56,9 @@
 	/* mp2 active control status */
 	u32 mp2_acs;
 	struct sfh_dev_status dev_en;
+	struct work_struct work;
+	u8 init_done;
+	u8 rver;
 };
 
 struct amd_mp2_ops {
@@ -79,4 +85,14 @@
 int amd_sfh_irq_init_v2(struct amd_mp2_dev *privdata);
 void amd_sfh_clear_intr(struct amd_mp2_dev *privdata);
 int amd_sfh_irq_init(struct amd_mp2_dev *privdata);
+
+static inline u64 amd_get_c2p_val(struct amd_mp2_dev *mp2, u32 idx)
+{
+	return mp2->rver == 1 ? AMD_C2P_MSG_V1(idx) :  AMD_C2P_MSG(idx);
+}
+
+static inline u64 amd_get_p2c_val(struct amd_mp2_dev *mp2, u32 idx)
+{
+	return mp2->rver == 1 ? AMD_P2C_MSG_V1(idx) :  AMD_P2C_MSG(idx);
+}
 #endif
--- linux-qcom-6.8.0.orig/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
+++ linux-qcom-6.8.0/drivers/hid/amd-sfh-hid/amd_sfh_hid.c
@@ -171,11 +171,13 @@
 void amdtp_hid_remove(struct amdtp_cl_data *cli_data)
 {
 	int i;
+	struct amdtp_hid_data *hid_data;
 
 	for (i = 0; i < cli_data->num_hid_devices; ++i) {
 		if (cli_data->hid_sensor_hubs[i]) {
-			kfree(cli_data->hid_sensor_hubs[i]->driver_data);
+			hid_data = cli_data->hid_sensor_hubs[i]->driver_data;
 			hid_destroy_device(cli_data->hid_sensor_hubs[i]);
+			kfree(hid_data);
 			cli_data->hid_sensor_hubs[i] = NULL;
 		}
 	}
--- linux-qcom-6.8.0.orig/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+++ linux-qcom-6.8.0/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
@@ -10,6 +10,7 @@
 
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/devm-helpers.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmi.h>
 #include <linux/interrupt.h>
@@ -35,15 +36,17 @@
 module_param_named(sensor_mask, sensor_mask_override, int, 0444);
 MODULE_PARM_DESC(sensor_mask, "override the detected sensors mask");
 
+static bool intr_disable = true;
+
 static int amd_sfh_wait_response_v2(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts)
 {
 	union cmd_response cmd_resp;
 
-	/* Get response with status within a max of 1600 ms timeout */
+	/* Get response with status within a max of 10 seconds timeout */
 	if (!readl_poll_timeout(mp2->mmio + AMD_P2C_MSG(0), cmd_resp.resp,
 				(cmd_resp.response_v2.response == sensor_sts &&
 				cmd_resp.response_v2.status == 0 && (sid == 0xff ||
-				cmd_resp.response_v2.sensor_id == sid)), 500, 1600000))
+				cmd_resp.response_v2.sensor_id == sid)), 500, 10000000))
 		return cmd_resp.response_v2.response;
 
 	return SENSOR_DISABLED;
@@ -55,7 +58,7 @@
 
 	cmd_base.ul = 0;
 	cmd_base.cmd_v2.cmd_id = ENABLE_SENSOR;
-	cmd_base.cmd_v2.intr_disable = 1;
+	cmd_base.cmd_v2.intr_disable = intr_disable;
 	cmd_base.cmd_v2.period = info.period;
 	cmd_base.cmd_v2.sensor_id = info.sensor_idx;
 	cmd_base.cmd_v2.length = 16;
@@ -73,7 +76,7 @@
 
 	cmd_base.ul = 0;
 	cmd_base.cmd_v2.cmd_id = DISABLE_SENSOR;
-	cmd_base.cmd_v2.intr_disable = 1;
+	cmd_base.cmd_v2.intr_disable = intr_disable;
 	cmd_base.cmd_v2.period = 0;
 	cmd_base.cmd_v2.sensor_id = sensor_idx;
 	cmd_base.cmd_v2.length  = 16;
@@ -87,7 +90,7 @@
 	union sfh_cmd_base cmd_base;
 
 	cmd_base.cmd_v2.cmd_id = STOP_ALL_SENSORS;
-	cmd_base.cmd_v2.intr_disable = 1;
+	cmd_base.cmd_v2.intr_disable = intr_disable;
 	cmd_base.cmd_v2.period = 0;
 	cmd_base.cmd_v2.sensor_id = 0;
 
@@ -96,9 +99,9 @@
 
 void amd_sfh_clear_intr_v2(struct amd_mp2_dev *privdata)
 {
-	if (readl(privdata->mmio + AMD_P2C_MSG(4))) {
-		writel(0, privdata->mmio + AMD_P2C_MSG(4));
-		writel(0xf, privdata->mmio + AMD_P2C_MSG(5));
+	if (readl(privdata->mmio + amd_get_p2c_val(privdata, 4))) {
+		writel(0, privdata->mmio + amd_get_p2c_val(privdata, 4));
+		writel(0xf, privdata->mmio + amd_get_p2c_val(privdata, 5));
 	}
 }
 
@@ -292,6 +295,26 @@
 	return 0;
 }
 
+static int mp2_disable_intr(const struct dmi_system_id *id)
+{
+	intr_disable = false;
+	return 0;
+}
+
+static const struct dmi_system_id dmi_sfh_table[] = {
+	{
+		/*
+		 * https://bugzilla.kernel.org/show_bug.cgi?id=218104
+		 */
+		.callback = mp2_disable_intr,
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook x360 435 G7"),
+		},
+	},
+	{}
+};
+
 static const struct dmi_system_id dmi_nodevs[] = {
 	{
 		/*
@@ -307,6 +330,48 @@
 	{ }
 };
 
+static void sfh1_1_init_work(struct work_struct *work)
+{
+	struct amd_mp2_dev *mp2 = container_of(work, struct amd_mp2_dev, work);
+	struct pci_dev *pdev = mp2->pdev;
+	int rc;
+
+	rc = mp2->sfh1_1_ops->init(mp2);
+	if (rc) {
+		dev_err(&pdev->dev, "sfh1_1_init failed err %d\n", rc);
+		return;
+	}
+
+	amd_sfh_clear_intr(mp2);
+	mp2->init_done = 1;
+}
+
+static void sfh_init_work(struct work_struct *work)
+{
+	struct amd_mp2_dev *mp2 = container_of(work, struct amd_mp2_dev, work);
+	struct pci_dev *pdev = mp2->pdev;
+	int rc;
+
+	rc = amd_sfh_hid_client_init(mp2);
+	if (rc) {
+		amd_sfh_clear_intr(mp2);
+		dev_err(&pdev->dev, "amd_sfh_hid_client_init failed err %d\n", rc);
+		return;
+	}
+
+	amd_sfh_clear_intr(mp2);
+	mp2->init_done = 1;
+}
+
+static void amd_sfh_remove(struct pci_dev *pdev)
+{
+	struct amd_mp2_dev *mp2 = pci_get_drvdata(pdev);
+
+	flush_work(&mp2->work);
+	if (mp2->init_done)
+		mp2->mp2_ops->remove(mp2);
+}
+
 static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	struct amd_mp2_dev *privdata;
@@ -315,6 +380,8 @@
 	if (dmi_first_match(dmi_nodevs))
 		return -ENODEV;
 
+	dmi_check_system(dmi_sfh_table);
+
 	privdata = devm_kzalloc(&pdev->dev, sizeof(*privdata), GFP_KERNEL);
 	if (!privdata)
 		return -ENOMEM;
@@ -343,10 +410,15 @@
 
 	privdata->sfh1_1_ops = (const struct amd_sfh1_1_ops *)id->driver_data;
 	if (privdata->sfh1_1_ops) {
-		rc = privdata->sfh1_1_ops->init(privdata);
+		if (boot_cpu_data.x86 >= 0x1A)
+			privdata->rver = 1;
+
+		rc = devm_work_autocancel(&pdev->dev, &privdata->work, sfh1_1_init_work);
 		if (rc)
 			return rc;
-		goto init_done;
+
+		schedule_work(&privdata->work);
+		return 0;
 	}
 
 	mp2_select_ops(privdata);
@@ -357,33 +429,34 @@
 		return rc;
 	}
 
-	rc = amd_sfh_hid_client_init(privdata);
+	rc = devm_work_autocancel(&pdev->dev, &privdata->work, sfh_init_work);
 	if (rc) {
 		amd_sfh_clear_intr(privdata);
-		if (rc != -EOPNOTSUPP)
-			dev_err(&pdev->dev, "amd_sfh_hid_client_init failed\n");
 		return rc;
 	}
 
-init_done:
-	amd_sfh_clear_intr(privdata);
-
-	return devm_add_action_or_reset(&pdev->dev, privdata->mp2_ops->remove, privdata);
+	schedule_work(&privdata->work);
+	return 0;
 }
 
 static void amd_sfh_shutdown(struct pci_dev *pdev)
 {
 	struct amd_mp2_dev *mp2 = pci_get_drvdata(pdev);
 
-	if (mp2 && mp2->mp2_ops)
-		mp2->mp2_ops->stop_all(mp2);
+	if (mp2) {
+		flush_work(&mp2->work);
+		if (mp2->init_done)
+			mp2->mp2_ops->stop_all(mp2);
+	}
 }
 
 static int __maybe_unused amd_mp2_pci_resume(struct device *dev)
 {
 	struct amd_mp2_dev *mp2 = dev_get_drvdata(dev);
 
-	mp2->mp2_ops->resume(mp2);
+	flush_work(&mp2->work);
+	if (mp2->init_done)
+		mp2->mp2_ops->resume(mp2);
 
 	return 0;
 }
@@ -392,7 +465,9 @@
 {
 	struct amd_mp2_dev *mp2 = dev_get_drvdata(dev);
 
-	mp2->mp2_ops->suspend(mp2);
+	flush_work(&mp2->work);
+	if (mp2->init_done)
+		mp2->mp2_ops->suspend(mp2);
 
 	return 0;
 }
@@ -414,6 +489,7 @@
 	.probe		= amd_mp2_pci_probe,
 	.driver.pm	= &amd_mp2_pm_ops,
 	.shutdown	= amd_sfh_shutdown,
+	.remove		= amd_sfh_remove,
 };
 module_pci_driver(amd_mp2_pci_driver);
 
--- linux-qcom-6.8.0.orig/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
+++ linux-qcom-6.8.0/drivers/hid/amd-sfh-hid/amd_sfh_pcie.h
@@ -90,10 +90,10 @@
 struct hpd_status {
 	union {
 		struct {
-			u32 human_presence_report : 4;
-			u32 human_presence_actual : 4;
-			u32 probablity		  : 8;
 			u32 object_distance       : 16;
+			u32 probablity		  : 8;
+			u32 human_presence_actual : 4;
+			u32 human_presence_report : 4;
 		} shpd;
 		u32 val;
 	};
--- linux-qcom-6.8.0.orig/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
+++ linux-qcom-6.8.0/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
@@ -251,7 +251,7 @@
 		break;
 	case HPD_IDX:
 		get_common_inputs(&hpd_input.common_property, report_id);
-		hpdstatus.val = readl(mp2->mmio + AMD_C2P_MSG(4));
+		hpdstatus.val = readl(mp2->mmio + amd_get_c2p_val(mp2, 4));
 		hpd_input.human_presence = hpdstatus.shpd.presence;
 		report_size = sizeof(hpd_input);
 		memcpy(input_report, &hpd_input, sizeof(hpd_input));
--- linux-qcom-6.8.0.orig/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
+++ linux-qcom-6.8.0/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
@@ -172,7 +172,7 @@
 		if (rc)
 			goto cleanup;
 
-		writel(0, privdata->mmio + AMD_P2C_MSG(0));
+		writel(0, privdata->mmio + amd_get_p2c_val(privdata, 0));
 		mp2_ops->start(privdata, info);
 		status = amd_sfh_wait_for_response
 				(privdata, cl_data->sensor_idx[i], ENABLE_SENSOR);
@@ -227,6 +227,11 @@
 	struct amd_mp2_sensor_info info;
 	int i, status;
 
+	if (!cl_data->is_any_sensor_enabled) {
+		amd_sfh_clear_intr(mp2);
+		return;
+	}
+
 	for (i = 0; i < cl_data->num_hid_devices; i++) {
 		if (cl_data->sensor_sts[i] == SENSOR_DISABLED) {
 			info.sensor_idx = cl_data->sensor_idx[i];
@@ -252,6 +257,11 @@
 	struct amdtp_cl_data *cl_data = mp2->cl_data;
 	int i, status;
 
+	if (!cl_data->is_any_sensor_enabled) {
+		amd_sfh_clear_intr(mp2);
+		return;
+	}
+
 	for (i = 0; i < cl_data->num_hid_devices; i++) {
 		if (cl_data->sensor_idx[i] != HPD_IDX &&
 		    cl_data->sensor_sts[i] == SENSOR_ENABLED) {
@@ -298,7 +308,7 @@
 
 int amd_sfh1_1_init(struct amd_mp2_dev *mp2)
 {
-	u32 phy_base = readl(mp2->mmio + AMD_C2P_MSG(22));
+	u32 phy_base = readl(mp2->mmio + amd_get_c2p_val(mp2, 22));
 	struct device *dev = &mp2->pdev->dev;
 	struct sfh_base_info binfo;
 	int rc;
--- linux-qcom-6.8.0.orig/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
+++ linux-qcom-6.8.0/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
@@ -20,7 +20,7 @@
 	struct sfh_cmd_response cmd_resp;
 
 	/* Get response with status within a max of 10000 ms timeout */
-	if (!readl_poll_timeout(mp2->mmio + AMD_P2C_MSG(0), cmd_resp.resp,
+	if (!readl_poll_timeout(mp2->mmio + amd_get_p2c_val(mp2, 0), cmd_resp.resp,
 				(cmd_resp.response.response == 0 &&
 				cmd_resp.response.cmd_id == cmd_id && (sid == 0xff ||
 				cmd_resp.response.sensor_id == sid)), 500, 10000000))
@@ -39,7 +39,7 @@
 	cmd_base.cmd.sub_cmd_value = 1;
 	cmd_base.cmd.sensor_id = info.sensor_idx;
 
-	writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0));
+	writel(cmd_base.ul, privdata->mmio + amd_get_c2p_val(privdata, 0));
 }
 
 static void amd_stop_sensor(struct amd_mp2_dev *privdata, u16 sensor_idx)
@@ -52,8 +52,8 @@
 	cmd_base.cmd.sub_cmd_value = 1;
 	cmd_base.cmd.sensor_id = sensor_idx;
 
-	writeq(0x0, privdata->mmio + AMD_C2P_MSG(1));
-	writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0));
+	writeq(0x0, privdata->mmio + amd_get_c2p_val(privdata, 1));
+	writel(cmd_base.ul, privdata->mmio + amd_get_c2p_val(privdata, 0));
 }
 
 static void amd_stop_all_sensor(struct amd_mp2_dev *privdata)
@@ -66,7 +66,7 @@
 	/* 0xf indicates all sensors */
 	cmd_base.cmd.sensor_id = 0xf;
 
-	writel(cmd_base.ul, privdata->mmio + AMD_C2P_MSG(0));
+	writel(cmd_base.ul, privdata->mmio + amd_get_c2p_val(privdata, 0));
 }
 
 static struct amd_mp2_ops amd_sfh_ops = {
--- linux-qcom-6.8.0.orig/drivers/hid/bpf/Kconfig
+++ linux-qcom-6.8.0/drivers/hid/bpf/Kconfig
@@ -3,7 +3,7 @@
 
 config HID_BPF
 	bool "HID-BPF support"
-	depends on BPF
+	depends on BPF_JIT
 	depends on BPF_SYSCALL
 	depends on DYNAMIC_FTRACE_WITH_DIRECT_CALLS
 	help
--- linux-qcom-6.8.0.orig/drivers/hid/hid-asus.c
+++ linux-qcom-6.8.0/drivers/hid/hid-asus.c
@@ -335,36 +335,20 @@
 	if (drvdata->quirks & QUIRK_MEDION_E1239T)
 		return asus_e1239t_event(drvdata, data, size);
 
-	if (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) {
+	/*
+	 * Skip these report ID, the device emits a continuous stream associated
+	 * with the AURA mode it is in which looks like an 'echo'.
+	 */
+	if (report->id == FEATURE_KBD_LED_REPORT_ID1 || report->id == FEATURE_KBD_LED_REPORT_ID2)
+		return -1;
+	if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) {
 		/*
-		 * Skip these report ID, the device emits a continuous stream associated
-		 * with the AURA mode it is in which looks like an 'echo'.
+		 * G713 and G733 send these codes on some keypresses, depending on
+		 * the key pressed it can trigger a shutdown event if not caught.
 		*/
-		if (report->id == FEATURE_KBD_LED_REPORT_ID1 ||
-				report->id == FEATURE_KBD_LED_REPORT_ID2) {
+		if (data[0] == 0x02 && data[1] == 0x30) {
 			return -1;
-		/* Additional report filtering */
-		} else if (report->id == FEATURE_KBD_REPORT_ID) {
-			/*
-			 * G14 and G15 send these codes on some keypresses with no
-			 * discernable reason for doing so. We'll filter them out to avoid
-			 * unmapped warning messages later.
-			*/
-			if (data[1] == 0xea || data[1] == 0xec || data[1] == 0x02 ||
-					data[1] == 0x8a || data[1] == 0x9e) {
-				return -1;
-			}
 		}
-		if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) {
-			/*
-			 * G713 and G733 send these codes on some keypresses, depending on
-			 * the key pressed it can trigger a shutdown event if not caught.
-			*/
-			if(data[0] == 0x02 && data[1] == 0x30) {
-				return -1;
-			}
-		}
-
 	}
 
 	if (drvdata->quirks & QUIRK_ROG_CLAYMORE_II_KEYBOARD) {
@@ -897,7 +881,10 @@
 		case 0xb3: asus_map_key_clear(KEY_PROG3);	break; /* Fn+Left next aura */
 		case 0x6a: asus_map_key_clear(KEY_F13);		break; /* Screenpad toggle */
 		case 0x4b: asus_map_key_clear(KEY_F14);		break; /* Arrows/Pg-Up/Dn toggle */
-
+		case 0xa5: asus_map_key_clear(KEY_F15);		break; /* ROG Ally left back */
+		case 0xa6: asus_map_key_clear(KEY_F16);		break; /* ROG Ally QAM button */
+		case 0xa7: asus_map_key_clear(KEY_F17);		break; /* ROG Ally ROG long-press */
+		case 0xa8: asus_map_key_clear(KEY_F18);		break; /* ROG Ally ROG long-press-release */
 
 		default:
 			/* ASUS lazily declares 256 usages, ignore the rest,
@@ -1250,6 +1237,19 @@
 		rdesc[205] = 0x01;
 	}
 
+	/* match many more n-key devices */
+	if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD && *rsize > 15) {
+		for (int i = 0; i < *rsize - 15; i++) {
+			/* offset to the count from 0x5a report part always 14 */
+			if (rdesc[i] == 0x85 && rdesc[i + 1] == 0x5a &&
+			    rdesc[i + 14] == 0x95 && rdesc[i + 15] == 0x05) {
+				hid_info(hdev, "Fixing up Asus N-Key report descriptor\n");
+				rdesc[i + 15] = 0x01;
+				break;
+			}
+		}
+	}
+
 	return rdesc;
 }
 
@@ -1277,6 +1277,15 @@
 	    USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3),
 	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
+	    USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR),
+	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
+	    USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY),
+	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
+	    USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X),
+	  QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
 	    USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD),
 	  QUIRK_ROG_CLAYMORE_II_KEYBOARD },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
@@ -1319,4 +1328,4 @@
 };
 module_hid_driver(asus_driver);
 
-MODULE_LICENSE("GPL");
\ No newline at end of file
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/hid/hid-core.c
+++ linux-qcom-6.8.0/drivers/hid/hid-core.c
@@ -1125,6 +1125,8 @@
 	while (multiplier_collection->parent_idx != -1 &&
 	       multiplier_collection->type != HID_COLLECTION_LOGICAL)
 		multiplier_collection = &hid->collection[multiplier_collection->parent_idx];
+	if (multiplier_collection->type != HID_COLLECTION_LOGICAL)
+		multiplier_collection = NULL;
 
 	effective_multiplier = hid_calculate_multiplier(hid, multiplier);
 
@@ -1448,7 +1450,6 @@
 			hid_warn(hid,
 				 "%s() called with too large value %d (n: %d)! (%s)\n",
 				 __func__, value, n, current->comm);
-			WARN_ON(1);
 			value &= m;
 		}
 	}
@@ -1876,7 +1877,7 @@
 
 	u32 len = hid_report_len(report) + 7;
 
-	return kmalloc(len, flags);
+	return kzalloc(len, flags);
 }
 EXPORT_SYMBOL_GPL(hid_alloc_report_buf);
 
@@ -2608,9 +2609,10 @@
 	/*
 	 * hid-generic implements .match(), so we must be dealing with a
 	 * different HID driver here, and can simply check if
-	 * hid_ignore_special_drivers is set or not.
+	 * hid_ignore_special_drivers or HID_QUIRK_IGNORE_SPECIAL_DRIVER
+	 * are set or not.
 	 */
-	return !hid_ignore_special_drivers;
+	return !hid_ignore_special_drivers && !(hdev->quirks & HID_QUIRK_IGNORE_SPECIAL_DRIVER);
 }
 
 static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv)
--- linux-qcom-6.8.0.orig/drivers/hid/hid-cougar.c
+++ linux-qcom-6.8.0/drivers/hid/hid-cougar.c
@@ -106,7 +106,7 @@
 static __u8 *cougar_report_fixup(struct hid_device *hdev, __u8 *rdesc,
 				 unsigned int *rsize)
 {
-	if (rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
+	if (*rsize >= 117 && rdesc[2] == 0x09 && rdesc[3] == 0x02 &&
 	    (rdesc[115] | rdesc[116] << 8) >= HID_MAX_USAGES) {
 		hid_info(hdev,
 			"usage count exceeds max: fixing up report descriptor\n");
--- linux-qcom-6.8.0.orig/drivers/hid/hid-debug.c
+++ linux-qcom-6.8.0/drivers/hid/hid-debug.c
@@ -974,6 +974,8 @@
 	[KEY_CAMERA_ACCESS_ENABLE] = "CameraAccessEnable",
 	[KEY_CAMERA_ACCESS_DISABLE] = "CameraAccessDisable",
 	[KEY_CAMERA_ACCESS_TOGGLE] = "CameraAccessToggle",
+	[KEY_ACCESSIBILITY] = "Accessibility",
+	[KEY_DO_NOT_DISTURB] = "DoNotDisturb",
 	[KEY_DICTATE] = "Dictate",
 	[KEY_MICMUTE] = "MicrophoneMute",
 	[KEY_BRIGHTNESS_MIN] = "BrightnessMin",
--- linux-qcom-6.8.0.orig/drivers/hid/hid-generic.c
+++ linux-qcom-6.8.0/drivers/hid/hid-generic.c
@@ -40,6 +40,9 @@
 	if (ignore_special_driver)
 		return true;
 
+	if (hdev->quirks & HID_QUIRK_IGNORE_SPECIAL_DRIVER)
+		return true;
+
 	if (hdev->quirks & HID_QUIRK_HAVE_SPECIAL_DRIVER)
 		return false;
 
--- linux-qcom-6.8.0.orig/drivers/hid/hid-hyperv.c
+++ linux-qcom-6.8.0/drivers/hid/hid-hyperv.c
@@ -422,6 +422,25 @@
 	return 0;
 }
 
+static int mousevsc_hid_probe(struct hid_device *hid_dev, const struct hid_device_id *id)
+{
+	int ret;
+
+	ret = hid_parse(hid_dev);
+	if (ret) {
+		hid_err(hid_dev, "parse failed\n");
+		return ret;
+	}
+
+	ret = hid_hw_start(hid_dev, HID_CONNECT_HIDINPUT | HID_CONNECT_HIDDEV);
+	if (ret) {
+		hid_err(hid_dev, "hw start failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
 static const struct hid_ll_driver mousevsc_ll_driver = {
 	.parse = mousevsc_hid_parse,
 	.open = mousevsc_hid_open,
@@ -431,7 +450,16 @@
 	.raw_request = mousevsc_hid_raw_request,
 };
 
-static struct hid_driver mousevsc_hid_driver;
+static const struct hid_device_id mousevsc_devices[] = {
+	{ HID_DEVICE(BUS_VIRTUAL, HID_GROUP_ANY, 0x045E, 0x0621) },
+	{ }
+};
+
+static struct hid_driver mousevsc_hid_driver = {
+	.name = "hid-hyperv",
+	.id_table = mousevsc_devices,
+	.probe = mousevsc_hid_probe,
+};
 
 static int mousevsc_probe(struct hv_device *device,
 			const struct hv_vmbus_device_id *dev_id)
@@ -473,7 +501,6 @@
 	}
 
 	hid_dev->ll_driver = &mousevsc_ll_driver;
-	hid_dev->driver = &mousevsc_hid_driver;
 	hid_dev->bus = BUS_VIRTUAL;
 	hid_dev->vendor = input_dev->hid_dev_info.vendor;
 	hid_dev->product = input_dev->hid_dev_info.product;
@@ -488,20 +515,6 @@
 	if (ret)
 		goto probe_err2;
 
-
-	ret = hid_parse(hid_dev);
-	if (ret) {
-		hid_err(hid_dev, "parse failed\n");
-		goto probe_err2;
-	}
-
-	ret = hid_hw_start(hid_dev, HID_CONNECT_HIDINPUT | HID_CONNECT_HIDDEV);
-
-	if (ret) {
-		hid_err(hid_dev, "hw start failed\n");
-		goto probe_err2;
-	}
-
 	device_init_wakeup(&device->device, true);
 
 	input_dev->connected = true;
@@ -579,12 +592,23 @@
 
 static int __init mousevsc_init(void)
 {
-	return vmbus_driver_register(&mousevsc_drv);
+	int ret;
+
+	ret = hid_register_driver(&mousevsc_hid_driver);
+	if (ret)
+		return ret;
+
+	ret = vmbus_driver_register(&mousevsc_drv);
+	if (ret)
+		hid_unregister_driver(&mousevsc_hid_driver);
+
+	return ret;
 }
 
 static void __exit mousevsc_exit(void)
 {
 	vmbus_driver_unregister(&mousevsc_drv);
+	hid_unregister_driver(&mousevsc_hid_driver);
 }
 
 MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/hid/hid-ids.h
+++ linux-qcom-6.8.0/drivers/hid/hid-ids.h
@@ -94,6 +94,7 @@
 #define USB_DEVICE_ID_APPLE_MAGICMOUSE2	0x0269
 #define USB_DEVICE_ID_APPLE_MAGICTRACKPAD	0x030e
 #define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2	0x0265
+#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC	0x0324
 #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI	0x020e
 #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO	0x020f
 #define USB_DEVICE_ID_APPLE_GEYSER_ANSI	0x0214
@@ -208,6 +209,9 @@
 #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD	0x1866
 #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2	0x19b6
 #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3	0x1a30
+#define USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR		0x18c6
+#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY		0x1abe
+#define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_ALLY_X		0x1b4c
 #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD	0x196b
 #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD	0x1869
 
@@ -414,22 +418,9 @@
 #define USB_DEVICE_ID_TOSHIBA_CLICK_L9W	0x0401
 #define USB_DEVICE_ID_HP_X2		0x074d
 #define USB_DEVICE_ID_HP_X2_10_COVER	0x0755
-#define I2C_DEVICE_ID_HP_ENVY_X360_15	0x2d05
-#define I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100	0x29CF
-#define I2C_DEVICE_ID_HP_ENVY_X360_EU0009NV	0x2CF9
-#define I2C_DEVICE_ID_HP_SPECTRE_X360_15	0x2817
-#define I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG  0x29DF
-#define I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN 0x2BC8
-#define I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN 0x2C82
 #define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN	0x2544
 #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN	0x2706
-#define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN	0x261A
-#define I2C_DEVICE_ID_SURFACE_GO2_TOUCHSCREEN	0x2A1C
-#define I2C_DEVICE_ID_LENOVO_YOGA_C630_TOUCHSCREEN	0x279F
-#define I2C_DEVICE_ID_HP_SPECTRE_X360_13T_AW100	0x29F5
-#define I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V1	0x2BED
-#define I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V2	0x2BEE
-#define I2C_DEVICE_ID_HP_ENVY_X360_15_EU0556NG		0x2D02
+#define I2C_DEVICE_ID_CHROMEBOOK_TROGDOR_POMPOM	0x2F81
 
 #define USB_VENDOR_ID_ELECOM		0x056e
 #define USB_DEVICE_ID_ELECOM_BM084	0x0061
@@ -515,7 +506,10 @@
 #define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100
 
 #define I2C_VENDOR_ID_GOODIX		0x27c6
+#define I2C_DEVICE_ID_GOODIX_01E8	0x01e8
+#define I2C_DEVICE_ID_GOODIX_01E9	0x01e9
 #define I2C_DEVICE_ID_GOODIX_01F0	0x01f0
+#define I2C_DEVICE_ID_GOODIX_0D42	0x0d42
 
 #define USB_VENDOR_ID_GOODTOUCH		0x1aad
 #define USB_DEVICE_ID_GOODTOUCH_000f	0x000f
@@ -802,6 +796,7 @@
 #define USB_DEVICE_ID_LENOVO_X1_TAB	0x60a3
 #define USB_DEVICE_ID_LENOVO_X1_TAB3	0x60b5
 #define USB_DEVICE_ID_LENOVO_X12_TAB	0x60fe
+#define USB_DEVICE_ID_LENOVO_X12_TAB2	0x61ae
 #define USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E	0x600e
 #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D	0x608d
 #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019	0x6019
@@ -822,6 +817,7 @@
 #define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e
 #define USB_DEVICE_ID_LOGITECH_T651	0xb00c
 #define USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD	0xb309
+#define USB_DEVICE_ID_LOGITECH_CASA_TOUCHPAD	0xbb00
 #define USB_DEVICE_ID_LOGITECH_C007	0xc007
 #define USB_DEVICE_ID_LOGITECH_C077	0xc077
 #define USB_DEVICE_ID_LOGITECH_RECEIVER	0xc101
@@ -873,6 +869,7 @@
 #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1	0xc539
 #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1	0xc53f
 #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY	0xc53a
+#define USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER	0xc548
 #define USB_DEVICE_ID_SPACETRAVELLER	0xc623
 #define USB_DEVICE_ID_SPACENAVIGATOR	0xc626
 #define USB_DEVICE_ID_DINOVO_DESKTOP	0xc704
@@ -1041,6 +1038,8 @@
 #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES	0xc056
 #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES	0xc057
 #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES	0xc058
+#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES	0x430c
+#define USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES		0x431e
 
 #define USB_VENDOR_ID_PANASONIC		0x04da
 #define USB_DEVICE_ID_PANABOARD_UBT780	0x1044
--- linux-qcom-6.8.0.orig/drivers/hid/hid-input.c
+++ linux-qcom-6.8.0/drivers/hid/hid-input.c
@@ -373,10 +373,6 @@
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
 		USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD),
 	  HID_BATTERY_QUIRK_IGNORE },
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN),
-	  HID_BATTERY_QUIRK_IGNORE },
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN),
-	  HID_BATTERY_QUIRK_IGNORE },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN),
 	  HID_BATTERY_QUIRK_IGNORE },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
@@ -387,30 +383,13 @@
 	  HID_BATTERY_QUIRK_AVOID_QUERY },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_SW),
 	  HID_BATTERY_QUIRK_AVOID_QUERY },
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15),
-	  HID_BATTERY_QUIRK_IGNORE },
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100),
-	  HID_BATTERY_QUIRK_IGNORE },
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_EU0009NV),
-	  HID_BATTERY_QUIRK_IGNORE },
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15),
-	  HID_BATTERY_QUIRK_IGNORE },
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG),
-	  HID_BATTERY_QUIRK_IGNORE },
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN),
-	  HID_BATTERY_QUIRK_IGNORE },
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO2_TOUCHSCREEN),
-	  HID_BATTERY_QUIRK_IGNORE },
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_LENOVO_YOGA_C630_TOUCHSCREEN),
-	  HID_BATTERY_QUIRK_IGNORE },
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_13T_AW100),
-	  HID_BATTERY_QUIRK_IGNORE },
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V1),
-	  HID_BATTERY_QUIRK_IGNORE },
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_14T_EA100_V2),
-	  HID_BATTERY_QUIRK_IGNORE },
-	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15_EU0556NG),
-	  HID_BATTERY_QUIRK_IGNORE },
+	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_CHROMEBOOK_TROGDOR_POMPOM),
+	  HID_BATTERY_QUIRK_AVOID_QUERY },
+	/*
+	 * Elan I2C-HID touchscreens seem to all report a non present battery,
+	 * set HID_BATTERY_QUIRK_IGNORE for all Elan I2C-HID devices.
+	 */
+	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, HID_ANY_ID), HID_BATTERY_QUIRK_IGNORE },
 	{}
 };
 
@@ -831,9 +810,31 @@
 			break;
 		}
 
+		if ((usage->hid & 0xf0) == 0x90) { /* SystemControl & D-pad */
+			switch (usage->hid) {
+			case HID_GD_UP:	   usage->hat_dir = 1; break;
+			case HID_GD_DOWN:  usage->hat_dir = 5; break;
+			case HID_GD_RIGHT: usage->hat_dir = 3; break;
+			case HID_GD_LEFT:  usage->hat_dir = 7; break;
+			case HID_GD_DO_NOT_DISTURB:
+				map_key_clear(KEY_DO_NOT_DISTURB); break;
+			default: goto unknown;
+			}
+
+			if (usage->hid <= HID_GD_LEFT) {
+				if (field->dpad) {
+					map_abs(field->dpad);
+					goto ignore;
+				}
+				map_abs(ABS_HAT0X);
+			}
+			break;
+		}
+
 		if ((usage->hid & 0xf0) == 0xa0) {	/* SystemControl */
 			switch (usage->hid & 0xf) {
 			case 0x9: map_key_clear(KEY_MICMUTE); break;
+			case 0xa: map_key_clear(KEY_ACCESSIBILITY); break;
 			default: goto ignore;
 			}
 			break;
@@ -856,22 +857,6 @@
 		if (field->application == HID_GD_SYSTEM_CONTROL)
 			goto ignore;
 
-		if ((usage->hid & 0xf0) == 0x90) {	/* D-pad */
-			switch (usage->hid) {
-			case HID_GD_UP:	   usage->hat_dir = 1; break;
-			case HID_GD_DOWN:  usage->hat_dir = 5; break;
-			case HID_GD_RIGHT: usage->hat_dir = 3; break;
-			case HID_GD_LEFT:  usage->hat_dir = 7; break;
-			default: goto unknown;
-			}
-			if (field->dpad) {
-				map_abs(field->dpad);
-				goto ignore;
-			}
-			map_abs(ABS_HAT0X);
-			break;
-		}
-
 		switch (usage->hid) {
 		/* These usage IDs map directly to the usage codes. */
 		case HID_GD_X: case HID_GD_Y: case HID_GD_Z:
--- linux-qcom-6.8.0.orig/drivers/hid/hid-lenovo.c
+++ linux-qcom-6.8.0/drivers/hid/hid-lenovo.c
@@ -54,10 +54,10 @@
 	/* 0: Up
 	 * 1: Down (undecided)
 	 * 2: Scrolling
-	 * 3: Patched firmware, disable workaround
 	 */
 	u8 middlebutton_state;
 	bool fn_lock;
+	bool middleclick_workaround_cptkbd;
 };
 
 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
@@ -473,6 +473,7 @@
 		return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field,
 							       usage, bit, max);
 	case USB_DEVICE_ID_LENOVO_X1_TAB:
+	case USB_DEVICE_ID_LENOVO_X1_TAB3:
 		return lenovo_input_mapping_x1_tab_kbd(hdev, hi, field, usage, bit, max);
 	default:
 		return 0;
@@ -583,6 +584,7 @@
 		break;
 	case USB_DEVICE_ID_LENOVO_TP10UBKBD:
 	case USB_DEVICE_ID_LENOVO_X1_TAB:
+	case USB_DEVICE_ID_LENOVO_X1_TAB3:
 		ret = lenovo_led_set_tp10ubkbd(hdev, TP10UBKBD_FN_LOCK_LED, value);
 		if (ret)
 			return ret;
@@ -621,6 +623,36 @@
 	return count;
 }
 
+static ssize_t attr_middleclick_workaround_show_cptkbd(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	struct hid_device *hdev = to_hid_device(dev);
+	struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n",
+		cptkbd_data->middleclick_workaround_cptkbd);
+}
+
+static ssize_t attr_middleclick_workaround_store_cptkbd(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t count)
+{
+	struct hid_device *hdev = to_hid_device(dev);
+	struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
+	int value;
+
+	if (kstrtoint(buf, 10, &value))
+		return -EINVAL;
+	if (value < 0 || value > 1)
+		return -EINVAL;
+
+	cptkbd_data->middleclick_workaround_cptkbd = !!value;
+
+	return count;
+}
+
 
 static struct device_attribute dev_attr_fn_lock =
 	__ATTR(fn_lock, S_IWUSR | S_IRUGO,
@@ -632,10 +664,16 @@
 			attr_sensitivity_show_cptkbd,
 			attr_sensitivity_store_cptkbd);
 
+static struct device_attribute dev_attr_middleclick_workaround_cptkbd =
+	__ATTR(middleclick_workaround, S_IWUSR | S_IRUGO,
+			attr_middleclick_workaround_show_cptkbd,
+			attr_middleclick_workaround_store_cptkbd);
+
 
 static struct attribute *lenovo_attributes_cptkbd[] = {
 	&dev_attr_fn_lock.attr,
 	&dev_attr_sensitivity_cptkbd.attr,
+	&dev_attr_middleclick_workaround_cptkbd.attr,
 	NULL
 };
 
@@ -686,23 +724,7 @@
 {
 	struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
 
-	if (cptkbd_data->middlebutton_state != 3) {
-		/* REL_X and REL_Y events during middle button pressed
-		 * are only possible on patched, bug-free firmware
-		 * so set middlebutton_state to 3
-		 * to never apply workaround anymore
-		 */
-		if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD &&
-				cptkbd_data->middlebutton_state == 1 &&
-				usage->type == EV_REL &&
-				(usage->code == REL_X || usage->code == REL_Y)) {
-			cptkbd_data->middlebutton_state = 3;
-			/* send middle button press which was hold before */
-			input_event(field->hidinput->input,
-				EV_KEY, BTN_MIDDLE, 1);
-			input_sync(field->hidinput->input);
-		}
-
+	if (cptkbd_data->middleclick_workaround_cptkbd) {
 		/* "wheel" scroll events */
 		if (usage->type == EV_REL && (usage->code == REL_WHEEL ||
 				usage->code == REL_HWHEEL)) {
@@ -757,6 +779,7 @@
 		return lenovo_event_cptkbd(hdev, field, usage, value);
 	case USB_DEVICE_ID_LENOVO_TP10UBKBD:
 	case USB_DEVICE_ID_LENOVO_X1_TAB:
+	case USB_DEVICE_ID_LENOVO_X1_TAB3:
 		return lenovo_event_tp10ubkbd(hdev, field, usage, value);
 	default:
 		return 0;
@@ -1039,6 +1062,7 @@
 		break;
 	case USB_DEVICE_ID_LENOVO_TP10UBKBD:
 	case USB_DEVICE_ID_LENOVO_X1_TAB:
+	case USB_DEVICE_ID_LENOVO_X1_TAB3:
 		ret = lenovo_led_set_tp10ubkbd(hdev, tp10ubkbd_led[led_nr], value);
 		break;
 	}
@@ -1166,6 +1190,7 @@
 	cptkbd_data->middlebutton_state = 0;
 	cptkbd_data->fn_lock = true;
 	cptkbd_data->sensitivity = 0x05;
+	cptkbd_data->middleclick_workaround_cptkbd = true;
 	lenovo_features_set_cptkbd(hdev);
 
 	ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd);
@@ -1268,6 +1293,7 @@
 		break;
 	case USB_DEVICE_ID_LENOVO_TP10UBKBD:
 	case USB_DEVICE_ID_LENOVO_X1_TAB:
+	case USB_DEVICE_ID_LENOVO_X1_TAB3:
 		ret = lenovo_probe_tp10ubkbd(hdev);
 		break;
 	default:
@@ -1354,6 +1380,7 @@
 		break;
 	case USB_DEVICE_ID_LENOVO_TP10UBKBD:
 	case USB_DEVICE_ID_LENOVO_X1_TAB:
+	case USB_DEVICE_ID_LENOVO_X1_TAB3:
 		lenovo_remove_tp10ubkbd(hdev);
 		break;
 	}
@@ -1403,6 +1430,8 @@
 	 */
 	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
 		     USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB) },
+	{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
+		     USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB3) },
 	{ }
 };
 
--- linux-qcom-6.8.0.orig/drivers/hid/hid-logitech-dj.c
+++ linux-qcom-6.8.0/drivers/hid/hid-logitech-dj.c
@@ -965,9 +965,7 @@
 		}
 		break;
 	case REPORT_TYPE_MOUSE:
-		workitem->reports_supported |= STD_MOUSE | HIDPP;
-		if (djrcv_dev->type == recvr_type_mouse_only)
-			workitem->reports_supported |= MULTIMEDIA;
+		workitem->reports_supported |= STD_MOUSE | HIDPP | MULTIMEDIA;
 		break;
 	}
 }
@@ -1286,8 +1284,10 @@
 		 */
 		msleep(50);
 
-		if (retval)
+		if (retval) {
+			kfree(dj_report);
 			return retval;
+		}
 	}
 
 	/*
--- linux-qcom-6.8.0.orig/drivers/hid/hid-magicmouse.c
+++ linux-qcom-6.8.0/drivers/hid/hid-magicmouse.c
@@ -227,7 +227,9 @@
 		touch_minor = tdata[4];
 		state = tdata[7] & TOUCH_STATE_MASK;
 		down = state != TOUCH_STATE_NONE;
-	} else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
+	} else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
+		   input->id.product ==
+			   USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
 		id = tdata[8] & 0xf;
 		x = (tdata[1] << 27 | tdata[0] << 19) >> 19;
 		y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19);
@@ -259,8 +261,9 @@
 	/* If requested, emulate a scroll wheel by detecting small
 	 * vertical touch motions.
 	 */
-	if (emulate_scroll_wheel && (input->id.product !=
-			USB_DEVICE_ID_APPLE_MAGICTRACKPAD2)) {
+	if (emulate_scroll_wheel &&
+	    input->id.product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
+	    input->id.product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
 		unsigned long now = jiffies;
 		int step_x = msc->touches[id].scroll_x - x;
 		int step_y = msc->touches[id].scroll_y - y;
@@ -359,7 +362,9 @@
 		input_report_abs(input, ABS_MT_POSITION_X, x);
 		input_report_abs(input, ABS_MT_POSITION_Y, y);
 
-		if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2)
+		if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
+		    input->id.product ==
+			    USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC)
 			input_report_abs(input, ABS_MT_PRESSURE, pressure);
 
 		if (report_undeciphered) {
@@ -367,7 +372,9 @@
 			    input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2)
 				input_event(input, EV_MSC, MSC_RAW, tdata[7]);
 			else if (input->id.product !=
-					USB_DEVICE_ID_APPLE_MAGICTRACKPAD2)
+					 USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
+				 input->id.product !=
+					 USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC)
 				input_event(input, EV_MSC, MSC_RAW, tdata[8]);
 		}
 	}
@@ -493,7 +500,9 @@
 		magicmouse_emit_buttons(msc, clicks & 3);
 		input_report_rel(input, REL_X, x);
 		input_report_rel(input, REL_Y, y);
-	} else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
+	} else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
+		   input->id.product ==
+			   USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
 		input_mt_sync_frame(input);
 		input_report_key(input, BTN_MOUSE, clicks & 1);
 	} else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
@@ -545,7 +554,9 @@
 			__set_bit(REL_WHEEL_HI_RES, input->relbit);
 			__set_bit(REL_HWHEEL_HI_RES, input->relbit);
 		}
-	} else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
+	} else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
+		   input->id.product ==
+			   USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
 		/* If the trackpad has been connected to a Mac, the name is
 		 * automatically personalized, e.g., "José Expósito's Trackpad".
 		 * When connected through Bluetooth, the personalized name is
@@ -621,7 +632,9 @@
 				  MOUSE_RES_X);
 		input_abs_set_res(input, ABS_MT_POSITION_Y,
 				  MOUSE_RES_Y);
-	} else if (input->id.product ==  USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
+	} else if (input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
+		   input->id.product ==
+			   USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
 		input_set_abs_params(input, ABS_MT_PRESSURE, 0, 253, 0, 0);
 		input_set_abs_params(input, ABS_PRESSURE, 0, 253, 0, 0);
 		input_set_abs_params(input, ABS_MT_ORIENTATION, -3, 4, 0, 0);
@@ -660,7 +673,8 @@
 	input_set_events_per_packet(input, 60);
 
 	if (report_undeciphered &&
-	    input->id.product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
+	    input->id.product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
+	    input->id.product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
 		__set_bit(EV_MSC, input->evbit);
 		__set_bit(MSC_RAW, input->mscbit);
 	}
@@ -685,7 +699,9 @@
 
 	/* Magic Trackpad does not give relative data after switching to MT */
 	if ((hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD ||
-	     hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) &&
+	     hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
+	     hi->input->id.product ==
+		     USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) &&
 	    field->flags & HID_MAIN_ITEM_RELATIVE)
 		return -1;
 
@@ -721,7 +737,8 @@
 	int ret;
 	int feature_size;
 
-	if (hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
+	if (hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
+	    hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
 		if (hdev->vendor == BT_VENDOR_ID_APPLE) {
 			feature_size = sizeof(feature_mt_trackpad2_bt);
 			feature = feature_mt_trackpad2_bt;
@@ -766,7 +783,8 @@
 
 	if (!hdev->battery || hdev->vendor != USB_VENDOR_ID_APPLE ||
 	    (hdev->product != USB_DEVICE_ID_APPLE_MAGICMOUSE2 &&
-	     hdev->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2))
+	     hdev->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 &&
+	     hdev->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC))
 		return -1;
 
 	report_enum = &hdev->report_enum[hdev->battery_report_type];
@@ -835,7 +853,9 @@
 
 	if (id->vendor == USB_VENDOR_ID_APPLE &&
 	    (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
-	     (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 && hdev->type != HID_TYPE_USBMOUSE)))
+	     ((id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
+	       id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) &&
+	      hdev->type != HID_TYPE_USBMOUSE)))
 		return 0;
 
 	if (!msc->input) {
@@ -850,7 +870,8 @@
 	else if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2)
 		report = hid_register_report(hdev, HID_INPUT_REPORT,
 			MOUSE2_REPORT_ID, 0);
-	else if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) {
+	else if (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
+		 id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) {
 		if (id->vendor == BT_VENDOR_ID_APPLE)
 			report = hid_register_report(hdev, HID_INPUT_REPORT,
 				TRACKPAD2_BT_REPORT_ID, 0);
@@ -920,7 +941,8 @@
 	 */
 	if (hdev->vendor == USB_VENDOR_ID_APPLE &&
 	    (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 ||
-	     hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) &&
+	     hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 ||
+	     hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) &&
 	    *rsize == 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) {
 		hid_info(hdev,
 			 "fixing up magicmouse battery report descriptor\n");
@@ -951,6 +973,10 @@
 		USB_DEVICE_ID_APPLE_MAGICTRACKPAD2), .driver_data = 0 },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
 		USB_DEVICE_ID_APPLE_MAGICTRACKPAD2), .driver_data = 0 },
+	{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE,
+		USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE,
+		USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC), .driver_data = 0 },
 	{ }
 };
 MODULE_DEVICE_TABLE(hid, magic_mice);
--- linux-qcom-6.8.0.orig/drivers/hid/hid-mcp2221.c
+++ linux-qcom-6.8.0/drivers/hid/hid-mcp2221.c
@@ -944,9 +944,11 @@
 /* This is needed to be sure hid_hw_stop() isn't called twice by the subsystem */
 static void mcp2221_remove(struct hid_device *hdev)
 {
+#if IS_REACHABLE(CONFIG_IIO)
 	struct mcp2221 *mcp = hid_get_drvdata(hdev);
 
 	cancel_delayed_work_sync(&mcp->init_work);
+#endif
 }
 
 #if IS_REACHABLE(CONFIG_IIO)
--- linux-qcom-6.8.0.orig/drivers/hid/hid-multitouch.c
+++ linux-qcom-6.8.0/drivers/hid/hid-multitouch.c
@@ -1442,6 +1442,30 @@
 	return 0;
 }
 
+static __u8 *mt_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+			     unsigned int *size)
+{
+	if (hdev->vendor == I2C_VENDOR_ID_GOODIX &&
+	    (hdev->product == I2C_DEVICE_ID_GOODIX_01E8 ||
+	     hdev->product == I2C_DEVICE_ID_GOODIX_01E9)) {
+		if (rdesc[607] == 0x15) {
+			rdesc[607] = 0x25;
+			dev_info(
+				&hdev->dev,
+				"GT7868Q report descriptor fixup is applied.\n");
+		} else {
+			dev_info(
+				&hdev->dev,
+				"The byte is not expected for fixing the report descriptor. \
+It's possible that the touchpad firmware is not suitable for applying the fix. \
+got: %x\n",
+				rdesc[607]);
+		}
+	}
+
+	return rdesc;
+}
+
 static void mt_report(struct hid_device *hid, struct hid_report *report)
 {
 	struct mt_device *td = hid_get_drvdata(hid);
@@ -1993,6 +2017,10 @@
 		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
 			USB_VENDOR_ID_ELAN, 0x3148) },
 
+	{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
+		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+			USB_VENDOR_ID_ELAN, 0x32ae) },
+
 	/* Elitegroup panel */
 	{ .driver_data = MT_CLS_SERIAL,
 		MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP,
@@ -2036,6 +2064,14 @@
 		MT_BT_DEVICE(USB_VENDOR_ID_FRUCTEL,
 			USB_DEVICE_ID_GAMETEL_MT_MODE) },
 
+	/* Goodix GT7868Q devices */
+	{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
+	  HID_DEVICE(BUS_I2C, HID_GROUP_ANY, I2C_VENDOR_ID_GOODIX,
+		     I2C_DEVICE_ID_GOODIX_01E8) },
+	{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
+	  HID_DEVICE(BUS_I2C, HID_GROUP_ANY, I2C_VENDOR_ID_GOODIX,
+		     I2C_DEVICE_ID_GOODIX_01E9) },
+
 	/* GoodTouch panels */
 	{ .driver_data = MT_CLS_NSMU,
 		MT_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH,
@@ -2051,6 +2087,11 @@
 		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
 			0x347d, 0x7853) },
 
+	/* HONOR MagicBook Art 14 touchpad */
+	{ .driver_data = MT_CLS_VTL,
+		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+			0x35cc, 0x0104) },
+
 	/* Ilitek dual touch panel */
 	{  .driver_data = MT_CLS_NSMU,
 		MT_USB_DEVICE(USB_VENDOR_ID_ILITEK,
@@ -2082,6 +2123,22 @@
 			   USB_VENDOR_ID_LENOVO,
 			   USB_DEVICE_ID_LENOVO_X12_TAB) },
 
+	/* Lenovo X12 TAB Gen 2 */
+	{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
+		HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
+			   USB_VENDOR_ID_LENOVO,
+			   USB_DEVICE_ID_LENOVO_X12_TAB2) },
+
+	/* Logitech devices */
+	{ .driver_data = MT_CLS_NSMU,
+		HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH_WIN_8,
+			USB_VENDOR_ID_LOGITECH,
+			USB_DEVICE_ID_LOGITECH_CASA_TOUCHPAD) },
+	{ .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU,
+		HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8,
+			USB_VENDOR_ID_LOGITECH,
+			USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER) },
+
 	/* MosArt panels */
 	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
 		MT_USB_DEVICE(USB_VENDOR_ID_ASUS,
@@ -2238,6 +2295,11 @@
 		HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, USB_VENDOR_ID_GOOGLE,
 			USB_DEVICE_ID_GOOGLE_WHISKERS) },
 
+	/* Hantick */
+	{ .driver_data = MT_CLS_NSMU,
+		HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+			   I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288) },
+
 	/* Generic MT device */
 	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) },
 
@@ -2265,6 +2327,7 @@
 	.feature_mapping = mt_feature_mapping,
 	.usage_table = mt_grabbed_usages,
 	.event = mt_event,
+	.report_fixup = mt_report_fixup,
 	.report = mt_report,
 	.suspend = pm_ptr(mt_suspend),
 	.reset_resume = pm_ptr(mt_reset_resume),
--- linux-qcom-6.8.0.orig/drivers/hid/hid-nintendo.c
+++ linux-qcom-6.8.0/drivers/hid/hid-nintendo.c
@@ -481,10 +481,10 @@
 	{ BTN_TR,		JC_BTN_R,	},
 	{ BTN_TR2,		JC_BTN_LSTICK,	}, /* ZR */
 	{ BTN_START,		JC_BTN_PLUS,	},
-	{ BTN_FORWARD,		JC_BTN_Y,	}, /* C UP */
-	{ BTN_BACK,		JC_BTN_ZR,	}, /* C DOWN */
-	{ BTN_LEFT,		JC_BTN_X,	}, /* C LEFT */
-	{ BTN_RIGHT,		JC_BTN_MINUS,	}, /* C RIGHT */
+	{ BTN_SELECT,		JC_BTN_Y,	}, /* C UP */
+	{ BTN_X,		JC_BTN_ZR,	}, /* C DOWN */
+	{ BTN_Y,		JC_BTN_X,	}, /* C LEFT */
+	{ BTN_C,		JC_BTN_MINUS,	}, /* C RIGHT */
 	{ BTN_MODE,		JC_BTN_HOME,	},
 	{ BTN_Z,		JC_BTN_CAP,	},
 	{ /* sentinel */ },
--- linux-qcom-6.8.0.orig/drivers/hid/hid-nvidia-shield.c
+++ linux-qcom-6.8.0/drivers/hid/hid-nvidia-shield.c
@@ -283,7 +283,9 @@
 		return haptics;
 
 	input_set_capability(haptics, EV_FF, FF_RUMBLE);
-	input_ff_create_memless(haptics, NULL, play_effect);
+	ret = input_ff_create_memless(haptics, NULL, play_effect);
+	if (ret)
+		goto err;
 
 	ret = input_register_device(haptics);
 	if (ret)
--- linux-qcom-6.8.0.orig/drivers/hid/hid-plantronics.c
+++ linux-qcom-6.8.0/drivers/hid/hid-plantronics.c
@@ -38,8 +38,10 @@
 			    (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER)
 
 #define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0)
+#define PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS BIT(1)
 
 #define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */
+#define PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT 220 /* ms */
 
 struct plt_drv_data {
 	unsigned long device_type;
@@ -137,6 +139,21 @@
 
 		drv_data->last_volume_key_ts = cur_ts;
 	}
+	if (drv_data->quirks & PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS) {
+		unsigned long prev_ts, cur_ts;
+
+		/* Usages are filtered in plantronics_usages. */
+
+		if (!value) /* Handle key presses only. */
+			return 0;
+
+		prev_ts = drv_data->last_volume_key_ts;
+		cur_ts = jiffies;
+		if (jiffies_to_msecs(cur_ts - prev_ts) <= PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT)
+			return 1; /* Ignore the followed opposite volume key. */
+
+		drv_data->last_volume_key_ts = cur_ts;
+	}
 
 	return 0;
 }
@@ -210,6 +227,12 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
 					 USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES),
 		.driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+					 USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES),
+		.driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS,
+					 USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES),
+		.driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) },
 	{ }
 };
--- linux-qcom-6.8.0.orig/drivers/hid/hid-sensor-hub.c
+++ linux-qcom-6.8.0/drivers/hid/hid-sensor-hub.c
@@ -730,23 +730,30 @@
 	return ret;
 }
 
+static int sensor_hub_finalize_pending_fn(struct device *dev, void *data)
+{
+	struct hid_sensor_hub_device *hsdev = dev->platform_data;
+
+	if (hsdev->pending.status)
+		complete(&hsdev->pending.ready);
+
+	return 0;
+}
+
 static void sensor_hub_remove(struct hid_device *hdev)
 {
 	struct sensor_hub_data *data = hid_get_drvdata(hdev);
 	unsigned long flags;
-	int i;
 
 	hid_dbg(hdev, " hardware removed\n");
 	hid_hw_close(hdev);
 	hid_hw_stop(hdev);
+
 	spin_lock_irqsave(&data->lock, flags);
-	for (i = 0; i < data->hid_sensor_client_cnt; ++i) {
-		struct hid_sensor_hub_device *hsdev =
-			data->hid_sensor_hub_client_devs[i].platform_data;
-		if (hsdev->pending.status)
-			complete(&hsdev->pending.ready);
-	}
+	device_for_each_child(&hdev->dev, NULL,
+			      sensor_hub_finalize_pending_fn);
 	spin_unlock_irqrestore(&data->lock, flags);
+
 	mfd_remove_devices(&hdev->dev);
 	mutex_destroy(&data->mutex);
 }
--- linux-qcom-6.8.0.orig/drivers/hid/hid-thrustmaster.c
+++ linux-qcom-6.8.0/drivers/hid/hid-thrustmaster.c
@@ -170,6 +170,14 @@
 	ep = &usbif->cur_altsetting->endpoint[1];
 	b_ep = ep->desc.bEndpointAddress;
 
+	/* Are the expected endpoints present? */
+	u8 ep_addr[1] = {b_ep};
+
+	if (!usb_check_int_endpoints(usbif, ep_addr)) {
+		hid_err(hdev, "Unexpected non-int endpoint\n");
+		return;
+	}
+
 	for (i = 0; i < ARRAY_SIZE(setup_arr); ++i) {
 		memcpy(send_buf, setup_arr[i], setup_arr_sizes[i]);
 
--- linux-qcom-6.8.0.orig/drivers/hid/i2c-hid/i2c-hid-core.c
+++ linux-qcom-6.8.0/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -50,6 +50,7 @@
 #define I2C_HID_QUIRK_BAD_INPUT_SIZE		BIT(3)
 #define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET	BIT(4)
 #define I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND	BIT(5)
+#define I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME BIT(6)
 
 /* Command opcodes */
 #define I2C_HID_OPCODE_RESET			0x01
@@ -64,7 +65,6 @@
 /* flags */
 #define I2C_HID_STARTED		0
 #define I2C_HID_RESET_PENDING	1
-#define I2C_HID_READ_PENDING	2
 
 #define I2C_HID_PWR_ON		0x00
 #define I2C_HID_PWR_SLEEP	0x01
@@ -106,6 +106,7 @@
 
 	wait_queue_head_t	wait;		/* For waiting the interrupt */
 
+	struct mutex		cmd_lock;	/* protects cmdbuf and rawbuf */
 	struct mutex		reset_lock;
 
 	struct i2chid_ops	*ops;
@@ -140,6 +141,8 @@
 	{ USB_VENDOR_ID_ELAN, HID_ANY_ID,
 		 I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET |
 		 I2C_HID_QUIRK_BOGUS_IRQ },
+	{ I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_0D42,
+		 I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME },
 	{ 0, 0 }
 };
 
@@ -190,15 +193,10 @@
 		msgs[n].len = recv_len;
 		msgs[n].buf = recv_buf;
 		n++;
-
-		set_bit(I2C_HID_READ_PENDING, &ihid->flags);
 	}
 
 	ret = i2c_transfer(client->adapter, msgs, n);
 
-	if (recv_len)
-		clear_bit(I2C_HID_READ_PENDING, &ihid->flags);
-
 	if (ret != n)
 		return ret < 0 ? ret : -EIO;
 
@@ -208,6 +206,8 @@
 static int i2c_hid_read_register(struct i2c_hid *ihid, __le16 reg,
 				 void *buf, size_t len)
 {
+	guard(mutex)(&ihid->cmd_lock);
+
 	*(__le16 *)ihid->cmdbuf = reg;
 
 	return i2c_hid_xfer(ihid, ihid->cmdbuf, sizeof(__le16), buf, len);
@@ -240,6 +240,8 @@
 
 	i2c_hid_dbg(ihid, "%s\n", __func__);
 
+	guard(mutex)(&ihid->cmd_lock);
+
 	/* Command register goes first */
 	*(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister;
 	length += sizeof(__le16);
@@ -330,6 +332,8 @@
 	if (!do_set && le16_to_cpu(ihid->hdesc.wMaxOutputLength) == 0)
 		return -ENOSYS;
 
+	guard(mutex)(&ihid->cmd_lock);
+
 	if (do_set) {
 		/* Command register goes first */
 		*(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister;
@@ -372,6 +376,8 @@
 {
 	size_t length;
 
+	guard(mutex)(&ihid->cmd_lock);
+
 	/* SET_POWER uses command register */
 	*(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister;
 	length = sizeof(__le16);
@@ -443,25 +449,27 @@
 	if (ret)
 		return ret;
 
-	/* Prepare reset command. Command register goes first. */
-	*(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister;
-	length += sizeof(__le16);
-	/* Next is RESET command itself */
-	length += i2c_hid_encode_command(ihid->cmdbuf + length,
-					 I2C_HID_OPCODE_RESET, 0, 0);
+	scoped_guard(mutex, &ihid->cmd_lock) {
+		/* Prepare reset command. Command register goes first. */
+		*(__le16 *)ihid->cmdbuf = ihid->hdesc.wCommandRegister;
+		length += sizeof(__le16);
+		/* Next is RESET command itself */
+		length += i2c_hid_encode_command(ihid->cmdbuf + length,
+						 I2C_HID_OPCODE_RESET, 0, 0);
 
-	set_bit(I2C_HID_RESET_PENDING, &ihid->flags);
+		set_bit(I2C_HID_RESET_PENDING, &ihid->flags);
 
-	ret = i2c_hid_xfer(ihid, ihid->cmdbuf, length, NULL, 0);
-	if (ret) {
-		dev_err(&ihid->client->dev,
-			"failed to reset device: %d\n", ret);
-		goto err_clear_reset;
-	}
+		ret = i2c_hid_xfer(ihid, ihid->cmdbuf, length, NULL, 0);
+		if (ret) {
+			dev_err(&ihid->client->dev,
+				"failed to reset device: %d\n", ret);
+			break;
+		}
 
-	return 0;
+		return 0;
+	}
 
-err_clear_reset:
+	/* Clean up if sending reset command failed */
 	clear_bit(I2C_HID_RESET_PENDING, &ihid->flags);
 	i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP);
 	return ret;
@@ -556,9 +564,6 @@
 {
 	struct i2c_hid *ihid = dev_id;
 
-	if (test_bit(I2C_HID_READ_PENDING, &ihid->flags))
-		return IRQ_HANDLED;
-
 	i2c_hid_get_input(ihid);
 
 	return IRQ_HANDLED;
@@ -735,12 +740,15 @@
 	mutex_lock(&ihid->reset_lock);
 	do {
 		ret = i2c_hid_start_hwreset(ihid);
-		if (ret)
+		if (ret == 0)
+			ret = i2c_hid_finish_hwreset(ihid);
+		else
 			msleep(1000);
 	} while (tries-- > 0 && ret);
+	mutex_unlock(&ihid->reset_lock);
 
 	if (ret)
-		goto abort_reset;
+		return ret;
 
 	use_override = i2c_hid_get_dmi_hid_report_desc_override(client->name,
 								&rsize);
@@ -750,11 +758,8 @@
 		i2c_hid_dbg(ihid, "Using a HID report descriptor override\n");
 	} else {
 		rdesc = kzalloc(rsize, GFP_KERNEL);
-
-		if (!rdesc) {
-			ret = -ENOMEM;
-			goto abort_reset;
-		}
+		if (!rdesc)
+			return -ENOMEM;
 
 		i2c_hid_dbg(ihid, "asking HID report descriptor\n");
 
@@ -763,23 +768,10 @@
 					    rdesc, rsize);
 		if (ret) {
 			hid_err(hid, "reading report descriptor failed\n");
-			goto abort_reset;
+			goto out;
 		}
 	}
 
-	/*
-	 * Windows directly reads the report-descriptor after sending reset
-	 * and then waits for resets completion afterwards. Some touchpads
-	 * actually wait for the report-descriptor to be read before signalling
-	 * reset completion.
-	 */
-	ret = i2c_hid_finish_hwreset(ihid);
-abort_reset:
-	clear_bit(I2C_HID_RESET_PENDING, &ihid->flags);
-	mutex_unlock(&ihid->reset_lock);
-	if (ret)
-		goto out;
-
 	i2c_hid_dbg(ihid, "Report Descriptor: %*ph\n", rsize, rdesc);
 
 	ret = hid_parse_report(hid, rdesc, rsize);
@@ -981,6 +973,13 @@
 
 	enable_irq(client->irq);
 
+	/* On Goodix 27c6:0d42 wait extra time before device wakeup.
+	 * It's not clear why but if we send wakeup too early, the device will
+	 * never trigger input interrupts.
+	 */
+	if (ihid->quirks & I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME)
+		msleep(1500);
+
 	/* Instead of resetting device, simply powers the device on. This
 	 * solves "incomplete reports" on Raydium devices 2386:3118 and
 	 * 2386:4B33 and fixes various SIS touchscreens no longer sending
@@ -1212,6 +1211,7 @@
 	ihid->is_panel_follower = drm_is_panel_follower(&client->dev);
 
 	init_waitqueue_head(&ihid->wait);
+	mutex_init(&ihid->cmd_lock);
 	mutex_init(&ihid->reset_lock);
 	INIT_WORK(&ihid->panel_follower_prepare_work, ihid_core_panel_prepare_work);
 
--- linux-qcom-6.8.0.orig/drivers/hid/i2c-hid/i2c-hid-of-elan.c
+++ linux-qcom-6.8.0/drivers/hid/i2c-hid/i2c-hid-of-elan.c
@@ -31,6 +31,7 @@
 	struct regulator *vcc33;
 	struct regulator *vccio;
 	struct gpio_desc *reset_gpio;
+	bool no_reset_on_power_off;
 	const struct elan_i2c_hid_chip_data *chip_data;
 };
 
@@ -40,17 +41,17 @@
 		container_of(ops, struct i2c_hid_of_elan, ops);
 	int ret;
 
+	gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);
+
 	if (ihid_elan->vcc33) {
 		ret = regulator_enable(ihid_elan->vcc33);
 		if (ret)
-			return ret;
+			goto err_deassert_reset;
 	}
 
 	ret = regulator_enable(ihid_elan->vccio);
-	if (ret) {
-		regulator_disable(ihid_elan->vcc33);
-		return ret;
-	}
+	if (ret)
+		goto err_disable_vcc33;
 
 	if (ihid_elan->chip_data->post_power_delay_ms)
 		msleep(ihid_elan->chip_data->post_power_delay_ms);
@@ -60,6 +61,15 @@
 		msleep(ihid_elan->chip_data->post_gpio_reset_on_delay_ms);
 
 	return 0;
+
+err_disable_vcc33:
+	if (ihid_elan->vcc33)
+		regulator_disable(ihid_elan->vcc33);
+err_deassert_reset:
+	if (ihid_elan->no_reset_on_power_off)
+		gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0);
+
+	return ret;
 }
 
 static void elan_i2c_hid_power_down(struct i2chid_ops *ops)
@@ -67,7 +77,14 @@
 	struct i2c_hid_of_elan *ihid_elan =
 		container_of(ops, struct i2c_hid_of_elan, ops);
 
-	gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);
+	/*
+	 * Do not assert reset when the hardware allows for it to remain
+	 * deasserted regardless of the state of the (shared) power supply to
+	 * avoid wasting power when the supply is left on.
+	 */
+	if (!ihid_elan->no_reset_on_power_off)
+		gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);
+
 	if (ihid_elan->chip_data->post_gpio_reset_off_delay_ms)
 		msleep(ihid_elan->chip_data->post_gpio_reset_off_delay_ms);
 
@@ -79,6 +96,7 @@
 static int i2c_hid_of_elan_probe(struct i2c_client *client)
 {
 	struct i2c_hid_of_elan *ihid_elan;
+	int ret;
 
 	ihid_elan = devm_kzalloc(&client->dev, sizeof(*ihid_elan), GFP_KERNEL);
 	if (!ihid_elan)
@@ -93,21 +111,38 @@
 	if (IS_ERR(ihid_elan->reset_gpio))
 		return PTR_ERR(ihid_elan->reset_gpio);
 
+	ihid_elan->no_reset_on_power_off = of_property_read_bool(client->dev.of_node,
+						"no-reset-on-power-off");
+
 	ihid_elan->vccio = devm_regulator_get(&client->dev, "vccio");
-	if (IS_ERR(ihid_elan->vccio))
-		return PTR_ERR(ihid_elan->vccio);
+	if (IS_ERR(ihid_elan->vccio)) {
+		ret = PTR_ERR(ihid_elan->vccio);
+		goto err_deassert_reset;
+	}
 
 	ihid_elan->chip_data = device_get_match_data(&client->dev);
 
 	if (ihid_elan->chip_data->main_supply_name) {
 		ihid_elan->vcc33 = devm_regulator_get(&client->dev,
 						      ihid_elan->chip_data->main_supply_name);
-		if (IS_ERR(ihid_elan->vcc33))
-			return PTR_ERR(ihid_elan->vcc33);
+		if (IS_ERR(ihid_elan->vcc33)) {
+			ret = PTR_ERR(ihid_elan->vcc33);
+			goto err_deassert_reset;
+		}
 	}
 
-	return i2c_hid_core_probe(client, &ihid_elan->ops,
-				  ihid_elan->chip_data->hid_descriptor_address, 0);
+	ret = i2c_hid_core_probe(client, &ihid_elan->ops,
+				 ihid_elan->chip_data->hid_descriptor_address, 0);
+	if (ret)
+		goto err_deassert_reset;
+
+	return 0;
+
+err_deassert_reset:
+	if (ihid_elan->no_reset_on_power_off)
+		gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0);
+
+	return ret;
 }
 
 static const struct elan_i2c_hid_chip_data elan_ekth6915_chip_data = {
--- linux-qcom-6.8.0.orig/drivers/hid/intel-ish-hid/ipc/ipc.c
+++ linux-qcom-6.8.0/drivers/hid/intel-ish-hid/ipc/ipc.c
@@ -948,6 +948,7 @@
 	if (!dev)
 		return NULL;
 
+	dev->devc = &pdev->dev;
 	ishtp_device_init(dev);
 
 	init_waitqueue_head(&dev->wait_hw_ready);
@@ -983,7 +984,6 @@
 	}
 
 	dev->ops = &ish_hw_ops;
-	dev->devc = &pdev->dev;
 	dev->mtu = IPC_PAYLOAD_SIZE - sizeof(struct ishtp_msg_hdr);
 	return dev;
 }
--- linux-qcom-6.8.0.orig/drivers/hid/intel-ish-hid/ipc/pci-ish.c
+++ linux-qcom-6.8.0/drivers/hid/intel-ish-hid/ipc/pci-ish.c
@@ -172,6 +172,11 @@
 
 	/* request and enable interrupt */
 	ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
+	if (ret < 0) {
+		dev_err(dev, "ISH: Failed to allocate IRQ vectors\n");
+		return ret;
+	}
+
 	if (!pdev->msi_enabled && !pdev->msix_enabled)
 		irq_flag = IRQF_SHARED;
 
--- linux-qcom-6.8.0.orig/drivers/hid/intel-ish-hid/ishtp-fw-loader.c
+++ linux-qcom-6.8.0/drivers/hid/intel-ish-hid/ishtp-fw-loader.c
@@ -635,7 +635,7 @@
 				  const struct firmware *fw,
 				  const struct shim_fw_info fw_info)
 {
-	int rv;
+	int rv = 0;
 	void *dma_buf;
 	dma_addr_t dma_buf_phy;
 	u32 fragment_offset, fragment_size, payload_max_size;
--- linux-qcom-6.8.0.orig/drivers/hid/wacom_sys.c
+++ linux-qcom-6.8.0/drivers/hid/wacom_sys.c
@@ -1370,17 +1370,6 @@
 	if (!name)
 		return -ENOMEM;
 
-	if (!read_only) {
-		led->trigger.name = name;
-		error = devm_led_trigger_register(dev, &led->trigger);
-		if (error) {
-			hid_err(wacom->hdev,
-				"failed to register LED trigger %s: %d\n",
-				led->cdev.name, error);
-			return error;
-		}
-	}
-
 	led->group = group;
 	led->id = id;
 	led->wacom = wacom;
@@ -1397,6 +1386,19 @@
 		led->cdev.brightness_set = wacom_led_readonly_brightness_set;
 	}
 
+	if (!read_only) {
+		led->trigger.name = name;
+		if (id == wacom->led.groups[group].select)
+			led->trigger.brightness = wacom_leds_brightness_get(led);
+		error = devm_led_trigger_register(dev, &led->trigger);
+		if (error) {
+			hid_err(wacom->hdev,
+				"failed to register LED trigger %s: %d\n",
+				led->cdev.name, error);
+			return error;
+		}
+	}
+
 	error = devm_led_classdev_register(dev, &led->cdev);
 	if (error) {
 		hid_err(wacom->hdev,
@@ -2241,7 +2243,8 @@
 		if (hid_is_usb(wacom->hdev)) {
 			struct usb_interface *intf = to_usb_interface(wacom->hdev->dev.parent);
 			struct usb_device *dev = interface_to_usbdev(intf);
-			product_name = dev->product;
+			if (dev->product != NULL)
+				product_name = dev->product;
 		}
 
 		if (wacom->hdev->bus == BUS_I2C) {
--- linux-qcom-6.8.0.orig/drivers/hid/wacom_wac.c
+++ linux-qcom-6.8.0/drivers/hid/wacom_wac.c
@@ -714,13 +714,12 @@
 	case 0x8e2: /* IntuosHT2 pen */
 	case 0x022:
 	case 0x200: /* Pro Pen 3 */
-	case 0x04200: /* Pro Pen 3 */
 	case 0x10842: /* MobileStudio Pro Pro Pen slim */
 	case 0x14802: /* Intuos4/5 13HD/24HD Classic Pen */
 	case 0x16802: /* Cintiq 13HD Pro Pen */
 	case 0x18802: /* DTH2242 Pen */
 	case 0x10802: /* Intuos4/5 13HD/24HD General Pen */
-	case 0x80842: /* Intuos Pro and Cintiq Pro 3D Pen */
+	case 0x8842: /* Intuos Pro and Cintiq Pro 3D Pen */
 		tool_type = BTN_TOOL_PEN;
 		break;
 
@@ -1400,9 +1399,9 @@
 					rotation -= 1800;
 
 				input_report_abs(pen_input, ABS_TILT_X,
-						 (char)frame[7]);
+						 (signed char)frame[7]);
 				input_report_abs(pen_input, ABS_TILT_Y,
-						 (char)frame[8]);
+						 (signed char)frame[8]);
 				input_report_abs(pen_input, ABS_Z, rotation);
 				input_report_abs(pen_input, ABS_WHEEL,
 						 get_unaligned_le16(&frame[11]));
@@ -1925,12 +1924,14 @@
 	int fmax = field->logical_maximum;
 	unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
 	int resolution_code = code;
-	int resolution = hidinput_calc_abs_res(field, resolution_code);
+	int resolution;
 
 	if (equivalent_usage == HID_DG_TWIST) {
 		resolution_code = ABS_RZ;
 	}
 
+	resolution = hidinput_calc_abs_res(field, resolution_code);
+
 	if (equivalent_usage == HID_GD_X) {
 		fmin += features->offset_left;
 		fmax -= features->offset_right;
@@ -2367,6 +2368,9 @@
 		wacom_map_usage(input, usage, field, EV_KEY, BTN_STYLUS3, 0);
 		features->quirks &= ~WACOM_QUIRK_PEN_BUTTON3;
 		break;
+	case WACOM_HID_WD_SEQUENCENUMBER:
+		wacom_wac->hid_data.sequence_number = -1;
+		break;
 	}
 }
 
@@ -2491,9 +2495,15 @@
 		wacom_wac->hid_data.barrelswitch3 = value;
 		return;
 	case WACOM_HID_WD_SEQUENCENUMBER:
-		if (wacom_wac->hid_data.sequence_number != value)
-			hid_warn(hdev, "Dropped %hu packets", (unsigned short)(value - wacom_wac->hid_data.sequence_number));
+		if (wacom_wac->hid_data.sequence_number != value &&
+		    wacom_wac->hid_data.sequence_number >= 0) {
+			int sequence_size = field->logical_maximum - field->logical_minimum + 1;
+			int drop_count = (value - wacom_wac->hid_data.sequence_number) % sequence_size;
+			hid_warn(hdev, "Dropped %d packets", drop_count);
+		}
 		wacom_wac->hid_data.sequence_number = value + 1;
+		if (wacom_wac->hid_data.sequence_number > field->logical_maximum)
+			wacom_wac->hid_data.sequence_number = field->logical_minimum;
 		return;
 	}
 
@@ -4911,6 +4921,10 @@
 	HID_DEVICE(BUS_I2C, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
 	.driver_data = (kernel_ulong_t)&wacom_features_##prod
 
+#define PCI_DEVICE_WACOM(prod)						\
+	HID_DEVICE(BUS_PCI, HID_GROUP_WACOM, USB_VENDOR_ID_WACOM, prod),\
+	.driver_data = (kernel_ulong_t)&wacom_features_##prod
+
 #define USB_DEVICE_LENOVO(prod)					\
 	HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, prod),			\
 	.driver_data = (kernel_ulong_t)&wacom_features_##prod
@@ -5080,6 +5094,7 @@
 
 	{ USB_DEVICE_WACOM(HID_ANY_ID) },
 	{ I2C_DEVICE_WACOM(HID_ANY_ID) },
+	{ PCI_DEVICE_WACOM(HID_ANY_ID) },
 	{ BT_DEVICE_WACOM(HID_ANY_ID) },
 	{ }
 };
--- linux-qcom-6.8.0.orig/drivers/hid/wacom_wac.h
+++ linux-qcom-6.8.0/drivers/hid/wacom_wac.h
@@ -325,7 +325,7 @@
 	int bat_connected;
 	int ps_connected;
 	bool pad_input_event_flag;
-	unsigned short sequence_number;
+	int sequence_number;
 	ktime_t time_delayed;
 };
 
--- linux-qcom-6.8.0.orig/drivers/hv/Kconfig
+++ linux-qcom-6.8.0/drivers/hv/Kconfig
@@ -16,6 +16,7 @@
 config HYPERV_VTL_MODE
 	bool "Enable Linux to boot in VTL context"
 	depends on X86_64 && HYPERV
+	depends on SMP
 	default n
 	help
 	  Virtual Secure Mode (VSM) is a set of hypervisor capabilities and
--- linux-qcom-6.8.0.orig/drivers/hv/channel.c
+++ linux-qcom-6.8.0/drivers/hv/channel.c
@@ -153,7 +153,9 @@
 	hv_ringbuffer_cleanup(&channel->inbound);
 
 	if (channel->ringbuffer_page) {
-		__free_pages(channel->ringbuffer_page,
+		/* In a CoCo VM leak the memory if it didn't get re-encrypted */
+		if (!channel->ringbuffer_gpadlhandle.decrypted)
+			__free_pages(channel->ringbuffer_page,
 			     get_order(channel->ringbuffer_pagecount
 				       << PAGE_SHIFT));
 		channel->ringbuffer_page = NULL;
@@ -436,9 +438,18 @@
 		(atomic_inc_return(&vmbus_connection.next_gpadl_handle) - 1);
 
 	ret = create_gpadl_header(type, kbuffer, size, send_offset, &msginfo);
-	if (ret)
+	if (ret) {
+		gpadl->decrypted = false;
 		return ret;
+	}
 
+	/*
+	 * Set the "decrypted" flag to true for the set_memory_decrypted()
+	 * success case. In the failure case, the encryption state of the
+	 * memory is unknown. Leave "decrypted" as true to ensure the
+	 * memory will be leaked instead of going back on the free list.
+	 */
+	gpadl->decrypted = true;
 	ret = set_memory_decrypted((unsigned long)kbuffer,
 				   PFN_UP(size));
 	if (ret) {
@@ -527,9 +538,15 @@
 
 	kfree(msginfo);
 
-	if (ret)
-		set_memory_encrypted((unsigned long)kbuffer,
-				     PFN_UP(size));
+	if (ret) {
+		/*
+		 * If set_memory_encrypted() fails, the decrypted flag is
+		 * left as true so the memory is leaked instead of being
+		 * put back on the free list.
+		 */
+		if (!set_memory_encrypted((unsigned long)kbuffer, PFN_UP(size)))
+			gpadl->decrypted = false;
+	}
 
 	return ret;
 }
@@ -850,6 +867,8 @@
 	if (ret)
 		pr_warn("Fail to set mem host visibility in GPADL teardown %d.\n", ret);
 
+	gpadl->decrypted = ret;
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(vmbus_teardown_gpadl);
--- linux-qcom-6.8.0.orig/drivers/hv/connection.c
+++ linux-qcom-6.8.0/drivers/hv/connection.c
@@ -237,8 +237,17 @@
 				vmbus_connection.monitor_pages[0], 1);
 	ret |= set_memory_decrypted((unsigned long)
 				vmbus_connection.monitor_pages[1], 1);
-	if (ret)
+	if (ret) {
+		/*
+		 * If set_memory_decrypted() fails, the encryption state
+		 * of the memory is unknown. So leak the memory instead
+		 * of risking returning decrypted memory to the free list.
+		 * For simplicity, always handle both pages the same.
+		 */
+		vmbus_connection.monitor_pages[0] = NULL;
+		vmbus_connection.monitor_pages[1] = NULL;
 		goto cleanup;
+	}
 
 	/*
 	 * Set_memory_decrypted() will change the memory contents if
@@ -337,13 +346,19 @@
 		vmbus_connection.int_page = NULL;
 	}
 
-	set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[0], 1);
-	set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[1], 1);
+	if (vmbus_connection.monitor_pages[0]) {
+		if (!set_memory_encrypted(
+			(unsigned long)vmbus_connection.monitor_pages[0], 1))
+			hv_free_hyperv_page(vmbus_connection.monitor_pages[0]);
+		vmbus_connection.monitor_pages[0] = NULL;
+	}
 
-	hv_free_hyperv_page(vmbus_connection.monitor_pages[0]);
-	hv_free_hyperv_page(vmbus_connection.monitor_pages[1]);
-	vmbus_connection.monitor_pages[0] = NULL;
-	vmbus_connection.monitor_pages[1] = NULL;
+	if (vmbus_connection.monitor_pages[1]) {
+		if (!set_memory_encrypted(
+			(unsigned long)vmbus_connection.monitor_pages[1], 1))
+			hv_free_hyperv_page(vmbus_connection.monitor_pages[1]);
+		vmbus_connection.monitor_pages[1] = NULL;
+	}
 }
 
 /*
--- linux-qcom-6.8.0.orig/drivers/hv/hv_kvp.c
+++ linux-qcom-6.8.0/drivers/hv/hv_kvp.c
@@ -767,6 +767,12 @@
 	 */
 	kvp_transaction.state = HVUTIL_DEVICE_INIT;
 
+	return 0;
+}
+
+int
+hv_kvp_init_transport(void)
+{
 	hvt = hvutil_transport_init(kvp_devname, CN_KVP_IDX, CN_KVP_VAL,
 				    kvp_on_msg, kvp_on_reset);
 	if (!hvt)
--- linux-qcom-6.8.0.orig/drivers/hv/hv_snapshot.c
+++ linux-qcom-6.8.0/drivers/hv/hv_snapshot.c
@@ -388,6 +388,12 @@
 	 */
 	vss_transaction.state = HVUTIL_DEVICE_INIT;
 
+	return 0;
+}
+
+int
+hv_vss_init_transport(void)
+{
 	hvt = hvutil_transport_init(vss_devname, CN_VSS_IDX, CN_VSS_VAL,
 				    vss_on_msg, vss_on_reset);
 	if (!hvt) {
--- linux-qcom-6.8.0.orig/drivers/hv/hv_util.c
+++ linux-qcom-6.8.0/drivers/hv/hv_util.c
@@ -141,6 +141,7 @@
 static struct hv_util_service util_kvp = {
 	.util_cb = hv_kvp_onchannelcallback,
 	.util_init = hv_kvp_init,
+	.util_init_transport = hv_kvp_init_transport,
 	.util_pre_suspend = hv_kvp_pre_suspend,
 	.util_pre_resume = hv_kvp_pre_resume,
 	.util_deinit = hv_kvp_deinit,
@@ -149,6 +150,7 @@
 static struct hv_util_service util_vss = {
 	.util_cb = hv_vss_onchannelcallback,
 	.util_init = hv_vss_init,
+	.util_init_transport = hv_vss_init_transport,
 	.util_pre_suspend = hv_vss_pre_suspend,
 	.util_pre_resume = hv_vss_pre_resume,
 	.util_deinit = hv_vss_deinit,
@@ -621,6 +623,13 @@
 	if (ret)
 		goto error;
 
+	if (srv->util_init_transport) {
+		ret = srv->util_init_transport();
+		if (ret) {
+			vmbus_close(dev->channel);
+			goto error;
+		}
+	}
 	return 0;
 
 error:
--- linux-qcom-6.8.0.orig/drivers/hv/hyperv_vmbus.h
+++ linux-qcom-6.8.0/drivers/hv/hyperv_vmbus.h
@@ -370,12 +370,14 @@
 void vmbus_on_msg_dpc(unsigned long data);
 
 int hv_kvp_init(struct hv_util_service *srv);
+int hv_kvp_init_transport(void);
 void hv_kvp_deinit(void);
 int hv_kvp_pre_suspend(void);
 int hv_kvp_pre_resume(void);
 void hv_kvp_onchannelcallback(void *context);
 
 int hv_vss_init(struct hv_util_service *srv);
+int hv_vss_init_transport(void);
 void hv_vss_deinit(void);
 int hv_vss_pre_suspend(void);
 int hv_vss_pre_resume(void);
--- linux-qcom-6.8.0.orig/drivers/hv/vmbus_drv.c
+++ linux-qcom-6.8.0/drivers/hv/vmbus_drv.c
@@ -1962,6 +1962,7 @@
 	 */
 	device_unregister(&device_obj->device);
 }
+EXPORT_SYMBOL_GPL(vmbus_device_unregister);
 
 #ifdef CONFIG_ACPI
 /*
--- linux-qcom-6.8.0.orig/drivers/hwmon/Kconfig
+++ linux-qcom-6.8.0/drivers/hwmon/Kconfig
@@ -38,6 +38,18 @@
 
 comment "Native drivers"
 
+config SENSORS_AAEON
+	tristate "AAEON hwmon driver"
+	depends on X86
+	depends on UBUNTU_ODM_DRIVERS
+	select MFD_AAEON
+	help
+	  This hwmon driver adds support for reporting temperature or fan
+	  speed and voltage on Single Board Computers produced by AAEON.
+
+	  This driver leverages the ASUS WMI interface to access device
+	  resources.
+
 config SENSORS_ABITUGURU
 	tristate "Abit uGuru (rev 1 & 2)"
 	depends on (X86 && DMI) || COMPILE_TEST
@@ -174,6 +186,7 @@
 	tristate "Analog Devices ADM9240 and compatibles"
 	depends on I2C
 	select HWMON_VID
+	select REGMAP_I2C
 	help
 	  If you say yes here you get support for Analog Devices ADM9240,
 	  Dallas DS1780, National Semiconductor LM81 sensor chips.
@@ -235,6 +248,7 @@
 config SENSORS_ADT7470
 	tristate "Analog Devices ADT7470"
 	depends on I2C
+	select REGMAP_I2C
 	help
 	  If you say yes here you get support for the Analog Devices
 	  ADT7470 temperature monitoring chips.
@@ -956,6 +970,7 @@
 config SENSORS_LTC2991
 	tristate "Analog Devices LTC2991"
 	depends on I2C
+	select REGMAP_I2C
 	help
 	  If you say yes here you get support for Analog Devices LTC2991
 	  Octal I2C Voltage, Current, and Temperature Monitor. The LTC2991
@@ -1232,6 +1247,7 @@
 config SENSORS_MC34VR500
 	tristate "NXP MC34VR500 hardware monitoring driver"
 	depends on I2C
+	select REGMAP_I2C
 	help
 	  If you say yes here you get support for the temperature and input
 	  voltage sensors of the NXP MC34VR500.
@@ -2170,6 +2186,7 @@
 config SENSORS_TMP513
 	tristate "Texas Instruments TMP513 and compatibles"
 	depends on I2C
+	select REGMAP_I2C
 	help
 	  If you say yes here you get support for Texas Instruments TMP512,
 	  and TMP513 temperature and power supply sensor chips.
--- linux-qcom-6.8.0.orig/drivers/hwmon/Makefile
+++ linux-qcom-6.8.0/drivers/hwmon/Makefile
@@ -15,6 +15,7 @@
 
 # Native drivers
 # asb100, then w83781d go first, as they can override other drivers' addresses.
+obj-$(CONFIG_SENSORS_AAEON)     += hwmon-aaeon.o
 obj-$(CONFIG_SENSORS_ASB100)	+= asb100.o
 obj-$(CONFIG_SENSORS_W83627HF)	+= w83627hf.o
 obj-$(CONFIG_SENSORS_W83773G)	+= w83773g.o
--- linux-qcom-6.8.0.orig/drivers/hwmon/acpi_power_meter.c
+++ linux-qcom-6.8.0/drivers/hwmon/acpi_power_meter.c
@@ -883,6 +883,22 @@
 	strcpy(acpi_device_class(device), ACPI_POWER_METER_CLASS);
 	device->driver_data = resource;
 
+#if IS_REACHABLE(CONFIG_ACPI_IPMI)
+	/*
+	 * On Dell systems several methods of acpi_power_meter access
+	 * variables in IPMI region, so wait until IPMI space handler is
+	 * installed by acpi_ipmi and also wait until SMI is selected to make
+	 * the space handler fully functional.
+	 */
+	if (dmi_match(DMI_SYS_VENDOR, "Dell Inc.")) {
+		struct acpi_device *ipi_device = acpi_dev_get_first_match_dev("IPI0001", NULL, -1);
+
+		if (ipi_device && acpi_wait_for_acpi_ipmi())
+				dev_warn(&device->dev, "Waiting for ACPI IPMI timeout");
+		acpi_dev_put(ipi_device);
+	}
+#endif
+
 	res = read_capabilities(resource);
 	if (res)
 		goto exit_free;
--- linux-qcom-6.8.0.orig/drivers/hwmon/adc128d818.c
+++ linux-qcom-6.8.0/drivers/hwmon/adc128d818.c
@@ -176,7 +176,7 @@
 
 	mutex_lock(&data->update_lock);
 	/* 10 mV LSB on limit registers */
-	regval = clamp_val(DIV_ROUND_CLOSEST(val, 10), 0, 255);
+	regval = DIV_ROUND_CLOSEST(clamp_val(val, 0, 2550), 10);
 	data->in[index][nr] = regval << 4;
 	reg = index == 1 ? ADC128_REG_IN_MIN(nr) : ADC128_REG_IN_MAX(nr);
 	i2c_smbus_write_byte_data(data->client, reg, regval);
@@ -214,7 +214,7 @@
 		return err;
 
 	mutex_lock(&data->update_lock);
-	regval = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127);
+	regval = DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), 1000);
 	data->temp[index] = regval << 1;
 	i2c_smbus_write_byte_data(data->client,
 				  index == 1 ? ADC128_REG_TEMP_MAX
--- linux-qcom-6.8.0.orig/drivers/hwmon/adt7475.c
+++ linux-qcom-6.8.0/drivers/hwmon/adt7475.c
@@ -1900,7 +1900,7 @@
 		data->pwm[CONTROL][index] &= ~0xE0;
 		data->pwm[CONTROL][index] |= (7 << 5);
 
-		i2c_smbus_write_byte_data(client, PWM_CONFIG_REG(index),
+		i2c_smbus_write_byte_data(client, PWM_REG(index),
 					  data->pwm[INPUT][index]);
 
 		i2c_smbus_write_byte_data(client, PWM_CONFIG_REG(index),
--- linux-qcom-6.8.0.orig/drivers/hwmon/amc6821.c
+++ linux-qcom-6.8.0/drivers/hwmon/amc6821.c
@@ -934,10 +934,21 @@
 
 MODULE_DEVICE_TABLE(i2c, amc6821_id);
 
+static const struct of_device_id __maybe_unused amc6821_of_match[] = {
+	{
+		.compatible = "ti,amc6821",
+		.data = (void *)amc6821,
+	},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(of, amc6821_of_match);
+
 static struct i2c_driver amc6821_driver = {
 	.class = I2C_CLASS_HWMON,
 	.driver = {
 		.name	= "amc6821",
+		.of_match_table = of_match_ptr(amc6821_of_match),
 	},
 	.probe = amc6821_probe,
 	.id_table = amc6821_id,
--- linux-qcom-6.8.0.orig/drivers/hwmon/asus-ec-sensors.c
+++ linux-qcom-6.8.0/drivers/hwmon/asus-ec-sensors.c
@@ -412,7 +412,7 @@
 
 static const struct ec_board_info board_info_strix_x570_e_gaming = {
 	.sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB |
-		SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM |
+		SENSOR_TEMP_T_SENSOR |
 		SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU |
 		SENSOR_IN_CPU_CORE,
 	.mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX,
--- linux-qcom-6.8.0.orig/drivers/hwmon/coretemp.c
+++ linux-qcom-6.8.0/drivers/hwmon/coretemp.c
@@ -39,13 +39,18 @@
 module_param_named(tjmax, force_tjmax, int, 0444);
 MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");
 
-#define PKG_SYSFS_ATTR_NO	1	/* Sysfs attribute for package temp */
-#define BASE_SYSFS_ATTR_NO	2	/* Sysfs Base attr no for coretemp */
 #define NUM_REAL_CORES		512	/* Number of Real cores per cpu */
 #define CORETEMP_NAME_LENGTH	28	/* String Length of attrs */
-#define MAX_CORE_ATTRS		4	/* Maximum no of basic attrs */
-#define TOTAL_ATTRS		(MAX_CORE_ATTRS + 1)
-#define MAX_CORE_DATA		(NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)
+
+enum coretemp_attr_index {
+	ATTR_LABEL,
+	ATTR_CRIT_ALARM,
+	ATTR_TEMP,
+	ATTR_TJMAX,
+	ATTR_TTARGET,
+	MAX_CORE_ATTRS = ATTR_TJMAX + 1,	/* Maximum no of basic attrs */
+	TOTAL_ATTRS = ATTR_TTARGET + 1		/* Maximum no of possible attrs */
+};
 
 #ifdef CONFIG_SMP
 #define for_each_sibling(i, cpu) \
@@ -65,19 +70,17 @@
  * @status_reg: One of IA32_THERM_STATUS or IA32_PACKAGE_THERM_STATUS,
  *		from where the temperature values should be read.
  * @attr_size:  Total number of pre-core attrs displayed in the sysfs.
- * @is_pkg_data: If this is 1, the temp_data holds pkgtemp data.
- *		Otherwise, temp_data holds coretemp data.
  */
 struct temp_data {
 	int temp;
 	int tjmax;
 	unsigned long last_updated;
 	unsigned int cpu;
+	int index;
 	u32 cpu_core_id;
 	u32 status_reg;
 	int attr_size;
-	bool is_pkg_data;
-	struct sensor_device_attribute sd_attrs[TOTAL_ATTRS];
+	struct device_attribute sd_attrs[TOTAL_ATTRS];
 	char attr_name[TOTAL_ATTRS][CORETEMP_NAME_LENGTH];
 	struct attribute *attrs[TOTAL_ATTRS + 1];
 	struct attribute_group attr_group;
@@ -88,10 +91,11 @@
 struct platform_data {
 	struct device		*hwmon_dev;
 	u16			pkg_id;
-	u16			cpu_map[NUM_REAL_CORES];
+	int			nr_cores;
 	struct ida		ida;
 	struct cpumask		cpumask;
-	struct temp_data	*core_data[MAX_CORE_DATA];
+	struct temp_data	*pkg_data;
+	struct temp_data	**core_data;
 	struct device_attribute name_attr;
 };
 
@@ -143,6 +147,11 @@
 				 */
 };
 
+static bool is_pkg_temp_data(struct temp_data *tdata)
+{
+	return tdata->index < 0;
+}
+
 static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
 {
 	/* The 100C is default for both mobile and non mobile CPUs */
@@ -332,11 +341,10 @@
 static ssize_t show_label(struct device *dev,
 				struct device_attribute *devattr, char *buf)
 {
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct platform_data *pdata = dev_get_drvdata(dev);
-	struct temp_data *tdata = pdata->core_data[attr->index];
+	struct temp_data *tdata = container_of(devattr, struct temp_data, sd_attrs[ATTR_LABEL]);
 
-	if (tdata->is_pkg_data)
+	if (is_pkg_temp_data(tdata))
 		return sprintf(buf, "Package id %u\n", pdata->pkg_id);
 
 	return sprintf(buf, "Core %u\n", tdata->cpu_core_id);
@@ -346,9 +354,8 @@
 				struct device_attribute *devattr, char *buf)
 {
 	u32 eax, edx;
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct platform_data *pdata = dev_get_drvdata(dev);
-	struct temp_data *tdata = pdata->core_data[attr->index];
+	struct temp_data *tdata = container_of(devattr, struct temp_data,
+						sd_attrs[ATTR_CRIT_ALARM]);
 
 	mutex_lock(&tdata->update_lock);
 	rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx);
@@ -360,9 +367,7 @@
 static ssize_t show_tjmax(struct device *dev,
 			struct device_attribute *devattr, char *buf)
 {
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct platform_data *pdata = dev_get_drvdata(dev);
-	struct temp_data *tdata = pdata->core_data[attr->index];
+	struct temp_data *tdata = container_of(devattr, struct temp_data, sd_attrs[ATTR_TJMAX]);
 	int tjmax;
 
 	mutex_lock(&tdata->update_lock);
@@ -375,9 +380,7 @@
 static ssize_t show_ttarget(struct device *dev,
 				struct device_attribute *devattr, char *buf)
 {
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct platform_data *pdata = dev_get_drvdata(dev);
-	struct temp_data *tdata = pdata->core_data[attr->index];
+	struct temp_data *tdata = container_of(devattr, struct temp_data, sd_attrs[ATTR_TTARGET]);
 	int ttarget;
 
 	mutex_lock(&tdata->update_lock);
@@ -393,9 +396,7 @@
 			struct device_attribute *devattr, char *buf)
 {
 	u32 eax, edx;
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct platform_data *pdata = dev_get_drvdata(dev);
-	struct temp_data *tdata = pdata->core_data[attr->index];
+	struct temp_data *tdata = container_of(devattr, struct temp_data, sd_attrs[ATTR_TEMP]);
 	int tjmax;
 
 	mutex_lock(&tdata->update_lock);
@@ -410,7 +411,7 @@
 		 * Return it instead of reporting an error which doesn't
 		 * really help at all.
 		 */
-		tdata->temp = tjmax - ((eax >> 16) & 0x7f) * 1000;
+		tdata->temp = tjmax - ((eax >> 16) & 0xff) * 1000;
 		tdata->last_updated = jiffies;
 	}
 
@@ -418,8 +419,7 @@
 	return sprintf(buf, "%d\n", tdata->temp);
 }
 
-static int create_core_attrs(struct temp_data *tdata, struct device *dev,
-			     int index)
+static int create_core_attrs(struct temp_data *tdata, struct device *dev)
 {
 	int i;
 	static ssize_t (*const rd_ptr[TOTAL_ATTRS]) (struct device *dev,
@@ -436,16 +436,15 @@
 		 * The attr number is always core id + 2
 		 * The Pkgtemp will always show up as temp1_*, if available
 		 */
-		int attr_no = tdata->is_pkg_data ? 1 : tdata->cpu_core_id + 2;
+		int attr_no = is_pkg_temp_data(tdata) ? 1 : tdata->cpu_core_id + 2;
 
 		snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH,
 			 "temp%d_%s", attr_no, suffixes[i]);
-		sysfs_attr_init(&tdata->sd_attrs[i].dev_attr.attr);
-		tdata->sd_attrs[i].dev_attr.attr.name = tdata->attr_name[i];
-		tdata->sd_attrs[i].dev_attr.attr.mode = 0444;
-		tdata->sd_attrs[i].dev_attr.show = rd_ptr[i];
-		tdata->sd_attrs[i].index = index;
-		tdata->attrs[i] = &tdata->sd_attrs[i].dev_attr.attr;
+		sysfs_attr_init(&tdata->sd_attrs[i].attr);
+		tdata->sd_attrs[i].attr.name = tdata->attr_name[i];
+		tdata->sd_attrs[i].attr.mode = 0444;
+		tdata->sd_attrs[i].show = rd_ptr[i];
+		tdata->attrs[i] = &tdata->sd_attrs[i].attr;
 	}
 	tdata->attr_group.attrs = tdata->attrs;
 	return sysfs_create_group(&dev->kobj, &tdata->attr_group);
@@ -477,17 +476,44 @@
 	return NULL;
 }
 
-static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag)
+static struct temp_data *
+init_temp_data(struct platform_data *pdata, unsigned int cpu, int pkg_flag)
 {
 	struct temp_data *tdata;
 
+	if (!pdata->core_data) {
+		/*
+		 * TODO:
+		 * The information of actual possible cores in a package is broken for now.
+		 * Will replace hardcoded NUM_REAL_CORES with actual per package core count
+		 * when this information becomes available.
+		 */
+		pdata->nr_cores = NUM_REAL_CORES;
+		pdata->core_data = kcalloc(pdata->nr_cores, sizeof(struct temp_data *),
+					   GFP_KERNEL);
+		if (!pdata->core_data)
+			return NULL;
+	}
+
 	tdata = kzalloc(sizeof(struct temp_data), GFP_KERNEL);
 	if (!tdata)
 		return NULL;
 
+	if (pkg_flag) {
+		pdata->pkg_data = tdata;
+		/* Use tdata->index as indicator of package temp data */
+		tdata->index = -1;
+	} else {
+		tdata->index = ida_alloc_max(&pdata->ida, pdata->nr_cores - 1, GFP_KERNEL);
+		if (tdata->index < 0) {
+			kfree(tdata);
+			return NULL;
+		}
+		pdata->core_data[tdata->index] = tdata;
+	}
+
 	tdata->status_reg = pkg_flag ? MSR_IA32_PACKAGE_THERM_STATUS :
 							MSR_IA32_THERM_STATUS;
-	tdata->is_pkg_data = pkg_flag;
 	tdata->cpu = cpu;
 	tdata->cpu_core_id = topology_core_id(cpu);
 	tdata->attr_size = MAX_CORE_ATTRS;
@@ -495,6 +521,36 @@
 	return tdata;
 }
 
+static void destroy_temp_data(struct platform_data *pdata, struct temp_data *tdata)
+{
+	if (is_pkg_temp_data(tdata)) {
+		pdata->pkg_data = NULL;
+		kfree(pdata->core_data);
+		pdata->core_data = NULL;
+		pdata->nr_cores = 0;
+	} else {
+		pdata->core_data[tdata->index] = NULL;
+		ida_free(&pdata->ida, tdata->index);
+	}
+	kfree(tdata);
+}
+
+static struct temp_data *get_temp_data(struct platform_data *pdata, int cpu)
+{
+	int i;
+
+	/* cpu < 0 means get pkg temp_data */
+	if (cpu < 0)
+		return pdata->pkg_data;
+
+	for (i = 0; i < pdata->nr_cores; i++) {
+		if (pdata->core_data[i] &&
+		    pdata->core_data[i]->cpu_core_id == topology_core_id(cpu))
+			return pdata->core_data[i];
+	}
+	return NULL;
+}
+
 static int create_core_data(struct platform_device *pdev, unsigned int cpu,
 			    int pkg_flag)
 {
@@ -502,37 +558,19 @@
 	struct platform_data *pdata = platform_get_drvdata(pdev);
 	struct cpuinfo_x86 *c = &cpu_data(cpu);
 	u32 eax, edx;
-	int err, index;
+	int err;
 
 	if (!housekeeping_cpu(cpu, HK_TYPE_MISC))
 		return 0;
 
-	/*
-	 * Get the index of tdata in pdata->core_data[]
-	 * tdata for package: pdata->core_data[1]
-	 * tdata for core: pdata->core_data[2] .. pdata->core_data[NUM_REAL_CORES + 1]
-	 */
-	if (pkg_flag) {
-		index = PKG_SYSFS_ATTR_NO;
-	} else {
-		index = ida_alloc_max(&pdata->ida, NUM_REAL_CORES - 1, GFP_KERNEL);
-		if (index < 0)
-			return index;
-
-		pdata->cpu_map[index] = topology_core_id(cpu);
-		index += BASE_SYSFS_ATTR_NO;
-	}
-
-	tdata = init_temp_data(cpu, pkg_flag);
-	if (!tdata) {
-		err = -ENOMEM;
-		goto ida_free;
-	}
+	tdata = init_temp_data(pdata, cpu, pkg_flag);
+	if (!tdata)
+		return -ENOMEM;
 
 	/* Test if we can access the status register */
 	err = rdmsr_safe_on_cpu(cpu, tdata->status_reg, &eax, &edx);
 	if (err)
-		goto exit_free;
+		goto err;
 
 	/* Make sure tdata->tjmax is a valid indicator for dynamic/static tjmax */
 	get_tjmax(tdata, &pdev->dev);
@@ -546,20 +584,15 @@
 		if (get_ttarget(tdata, &pdev->dev) >= 0)
 			tdata->attr_size++;
 
-	pdata->core_data[index] = tdata;
-
 	/* Create sysfs interfaces */
-	err = create_core_attrs(tdata, pdata->hwmon_dev, index);
+	err = create_core_attrs(tdata, pdata->hwmon_dev);
 	if (err)
-		goto exit_free;
+		goto err;
 
 	return 0;
-exit_free:
-	pdata->core_data[index] = NULL;
-	kfree(tdata);
-ida_free:
-	if (!pkg_flag)
-		ida_free(&pdata->ida, index - BASE_SYSFS_ATTR_NO);
+
+err:
+	destroy_temp_data(pdata, tdata);
 	return err;
 }
 
@@ -570,10 +603,8 @@
 		dev_err(&pdev->dev, "Adding Core %u failed\n", cpu);
 }
 
-static void coretemp_remove_core(struct platform_data *pdata, int indx)
+static void coretemp_remove_core(struct platform_data *pdata, struct temp_data *tdata)
 {
-	struct temp_data *tdata = pdata->core_data[indx];
-
 	/* if we errored on add then this is already gone */
 	if (!tdata)
 		return;
@@ -581,11 +612,7 @@
 	/* Remove the sysfs attributes */
 	sysfs_remove_group(&pdata->hwmon_dev->kobj, &tdata->attr_group);
 
-	kfree(pdata->core_data[indx]);
-	pdata->core_data[indx] = NULL;
-
-	if (indx >= BASE_SYSFS_ATTR_NO)
-		ida_free(&pdata->ida, indx - BASE_SYSFS_ATTR_NO);
+	destroy_temp_data(pdata, tdata);
 }
 
 static int coretemp_device_add(int zoneid)
@@ -698,7 +725,7 @@
 	struct platform_device *pdev = coretemp_get_pdev(cpu);
 	struct platform_data *pd;
 	struct temp_data *tdata;
-	int i, indx = -1, target;
+	int target;
 
 	/* No need to tear down any interfaces for suspend */
 	if (cpuhp_tasks_frozen)
@@ -709,18 +736,7 @@
 	if (!pd->hwmon_dev)
 		return 0;
 
-	for (i = 0; i < NUM_REAL_CORES; i++) {
-		if (pd->cpu_map[i] == topology_core_id(cpu)) {
-			indx = i + BASE_SYSFS_ATTR_NO;
-			break;
-		}
-	}
-
-	/* Too many cores and this core is not populated, just return */
-	if (indx < 0)
-		return 0;
-
-	tdata = pd->core_data[indx];
+	tdata = get_temp_data(pd, cpu);
 
 	cpumask_clear_cpu(cpu, &pd->cpumask);
 
@@ -731,7 +747,7 @@
 	 */
 	target = cpumask_any_and(&pd->cpumask, topology_sibling_cpumask(cpu));
 	if (target >= nr_cpu_ids) {
-		coretemp_remove_core(pd, indx);
+		coretemp_remove_core(pd, tdata);
 	} else if (tdata && tdata->cpu == cpu) {
 		mutex_lock(&tdata->update_lock);
 		tdata->cpu = target;
@@ -741,10 +757,10 @@
 	/*
 	 * If all cores in this pkg are offline, remove the interface.
 	 */
-	tdata = pd->core_data[PKG_SYSFS_ATTR_NO];
+	tdata = get_temp_data(pd, -1);
 	if (cpumask_empty(&pd->cpumask)) {
 		if (tdata)
-			coretemp_remove_core(pd, PKG_SYSFS_ATTR_NO);
+			coretemp_remove_core(pd, tdata);
 		hwmon_device_unregister(pd->hwmon_dev);
 		pd->hwmon_dev = NULL;
 		return 0;
--- linux-qcom-6.8.0.orig/drivers/hwmon/corsair-cpro.c
+++ linux-qcom-6.8.0/drivers/hwmon/corsair-cpro.c
@@ -16,6 +16,7 @@
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/spinlock.h>
 #include <linux/types.h>
 
 #define USB_VENDOR_ID_CORSAIR			0x1b1c
@@ -77,8 +78,11 @@
 struct ccp_device {
 	struct hid_device *hdev;
 	struct device *hwmon_dev;
+	/* For reinitializing the completion below */
+	spinlock_t wait_input_report_lock;
 	struct completion wait_input_report;
 	struct mutex mutex; /* whenever buffer is used, lock before send_usb_cmd */
+	u8 *cmd_buffer;
 	u8 *buffer;
 	int target[6];
 	DECLARE_BITMAP(temp_cnct, NUM_TEMP_SENSORS);
@@ -111,15 +115,23 @@
 	unsigned long t;
 	int ret;
 
-	memset(ccp->buffer, 0x00, OUT_BUFFER_SIZE);
-	ccp->buffer[0] = command;
-	ccp->buffer[1] = byte1;
-	ccp->buffer[2] = byte2;
-	ccp->buffer[3] = byte3;
-
+	memset(ccp->cmd_buffer, 0x00, OUT_BUFFER_SIZE);
+	ccp->cmd_buffer[0] = command;
+	ccp->cmd_buffer[1] = byte1;
+	ccp->cmd_buffer[2] = byte2;
+	ccp->cmd_buffer[3] = byte3;
+
+	/*
+	 * Disable raw event parsing for a moment to safely reinitialize the
+	 * completion. Reinit is done because hidraw could have triggered
+	 * the raw event parsing and marked the ccp->wait_input_report
+	 * completion as done.
+	 */
+	spin_lock_bh(&ccp->wait_input_report_lock);
 	reinit_completion(&ccp->wait_input_report);
+	spin_unlock_bh(&ccp->wait_input_report_lock);
 
-	ret = hid_hw_output_report(ccp->hdev, ccp->buffer, OUT_BUFFER_SIZE);
+	ret = hid_hw_output_report(ccp->hdev, ccp->cmd_buffer, OUT_BUFFER_SIZE);
 	if (ret < 0)
 		return ret;
 
@@ -135,11 +147,12 @@
 	struct ccp_device *ccp = hid_get_drvdata(hdev);
 
 	/* only copy buffer when requested */
-	if (completion_done(&ccp->wait_input_report))
-		return 0;
-
-	memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size));
-	complete(&ccp->wait_input_report);
+	spin_lock(&ccp->wait_input_report_lock);
+	if (!completion_done(&ccp->wait_input_report)) {
+		memcpy(ccp->buffer, data, min(IN_BUFFER_SIZE, size));
+		complete_all(&ccp->wait_input_report);
+	}
+	spin_unlock(&ccp->wait_input_report_lock);
 
 	return 0;
 }
@@ -492,7 +505,11 @@
 	if (!ccp)
 		return -ENOMEM;
 
-	ccp->buffer = devm_kmalloc(&hdev->dev, OUT_BUFFER_SIZE, GFP_KERNEL);
+	ccp->cmd_buffer = devm_kmalloc(&hdev->dev, OUT_BUFFER_SIZE, GFP_KERNEL);
+	if (!ccp->cmd_buffer)
+		return -ENOMEM;
+
+	ccp->buffer = devm_kmalloc(&hdev->dev, IN_BUFFER_SIZE, GFP_KERNEL);
 	if (!ccp->buffer)
 		return -ENOMEM;
 
@@ -510,7 +527,9 @@
 
 	ccp->hdev = hdev;
 	hid_set_drvdata(hdev, ccp);
+
 	mutex_init(&ccp->mutex);
+	spin_lock_init(&ccp->wait_input_report_lock);
 	init_completion(&ccp->wait_input_report);
 
 	hid_device_io_start(hdev);
--- linux-qcom-6.8.0.orig/drivers/hwmon/corsair-psu.c
+++ linux-qcom-6.8.0/drivers/hwmon/corsair-psu.c
@@ -875,15 +875,16 @@
 	{ HID_USB_DEVICE(0x1b1c, 0x1c04) }, /* Corsair HX650i */
 	{ HID_USB_DEVICE(0x1b1c, 0x1c05) }, /* Corsair HX750i */
 	{ HID_USB_DEVICE(0x1b1c, 0x1c06) }, /* Corsair HX850i */
-	{ HID_USB_DEVICE(0x1b1c, 0x1c07) }, /* Corsair HX1000i Series 2022 */
-	{ HID_USB_DEVICE(0x1b1c, 0x1c08) }, /* Corsair HX1200i */
+	{ HID_USB_DEVICE(0x1b1c, 0x1c07) }, /* Corsair HX1000i Legacy */
+	{ HID_USB_DEVICE(0x1b1c, 0x1c08) }, /* Corsair HX1200i Legacy */
 	{ HID_USB_DEVICE(0x1b1c, 0x1c09) }, /* Corsair RM550i */
 	{ HID_USB_DEVICE(0x1b1c, 0x1c0a) }, /* Corsair RM650i */
 	{ HID_USB_DEVICE(0x1b1c, 0x1c0b) }, /* Corsair RM750i */
 	{ HID_USB_DEVICE(0x1b1c, 0x1c0c) }, /* Corsair RM850i */
 	{ HID_USB_DEVICE(0x1b1c, 0x1c0d) }, /* Corsair RM1000i */
 	{ HID_USB_DEVICE(0x1b1c, 0x1c1e) }, /* Corsair HX1000i Series 2023 */
-	{ HID_USB_DEVICE(0x1b1c, 0x1c1f) }, /* Corsair HX1500i Series 2022 and 2023 */
+	{ HID_USB_DEVICE(0x1b1c, 0x1c1f) }, /* Corsair HX1500i Legacy and Series 2023 */
+	{ HID_USB_DEVICE(0x1b1c, 0x1c23) }, /* Corsair HX1200i Series 2023 */
 	{ },
 };
 MODULE_DEVICE_TABLE(hid, corsairpsu_idtable);
--- linux-qcom-6.8.0.orig/drivers/hwmon/drivetemp.c
+++ linux-qcom-6.8.0/drivers/hwmon/drivetemp.c
@@ -165,6 +165,7 @@
 {
 	u8 scsi_cmd[MAX_COMMAND_SIZE];
 	enum req_op op;
+	int err;
 
 	memset(scsi_cmd, 0, sizeof(scsi_cmd));
 	scsi_cmd[0] = ATA_16;
@@ -192,8 +193,11 @@
 	scsi_cmd[12] = lba_high;
 	scsi_cmd[14] = ata_command;
 
-	return scsi_execute_cmd(st->sdev, scsi_cmd, op, st->smartdata,
-				ATA_SECT_SIZE, HZ, 5, NULL);
+	err = scsi_execute_cmd(st->sdev, scsi_cmd, op, st->smartdata,
+			       ATA_SECT_SIZE, 10 * HZ, 5, NULL);
+	if (err > 0)
+		err = -EIO;
+	return err;
 }
 
 static int drivetemp_ata_command(struct drivetemp_data *st, u8 feature,
--- linux-qcom-6.8.0.orig/drivers/hwmon/emc2305.c
+++ linux-qcom-6.8.0/drivers/hwmon/emc2305.c
@@ -3,6 +3,7 @@
  * Hardware monitoring driver for EMC2305 fan controller
  *
  * Copyright (C) 2022 Nvidia Technologies Ltd.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/err.h>
@@ -530,6 +531,18 @@
 	return 0;
 }
 
+
+static int emc2305_detect(struct i2c_client *client, struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = client->adapter;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	strscpy(info->type, "emc2303", I2C_NAME_SIZE);
+	return 0;
+}
+
 static int emc2305_probe(struct i2c_client *client)
 {
 	struct i2c_adapter *adapter = client->adapter;
@@ -618,10 +631,27 @@
 	.probe = emc2305_probe,
 	.remove	  = emc2305_remove,
 	.id_table = emc2305_ids,
+	.detect = emc2305_detect,
 	.address_list = emc2305_normal_i2c,
 };
 
-module_i2c_driver(emc2305_driver);
+static struct i2c_board_info emc2305_i2c_info = {
+	I2C_BOARD_INFO("emc2303", 0x2c),
+};
+
+static int __init emc2305_init(void)
+{
+	i2c_register_board_info(1, &emc2305_i2c_info, 1);
+	return i2c_add_driver(&emc2305_driver);
+}
+
+static void __exit emc2305_exit(void)
+{
+	i2c_del_driver(&emc2305_driver);
+}
+
+module_init(emc2305_init);
+module_exit(emc2305_exit);
 
 MODULE_AUTHOR("Nvidia");
 MODULE_DESCRIPTION("Microchip EMC2305 fan controller driver");
--- linux-qcom-6.8.0.orig/drivers/hwmon/hp-wmi-sensors.c
+++ linux-qcom-6.8.0/drivers/hwmon/hp-wmi-sensors.c
@@ -1637,6 +1637,8 @@
 		goto out_unlock;
 
 	wobj = out.pointer;
+	if (!wobj)
+		goto out_unlock;
 
 	err = populate_event_from_wobj(dev, &event, wobj);
 	if (err) {
--- linux-qcom-6.8.0.orig/drivers/hwmon/hwmon-aaeon.c
+++ linux-qcom-6.8.0/drivers/hwmon/hwmon-aaeon.c
@@ -0,0 +1,568 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * AAEON HWMON driver
+ * Copyright (c) 2021, AAEON Ltd.
+ *
+ * Author: Edward Lin	<edward1_lin@aaeon.com.tw>
+ * Author: Kunyang Fan	<kunyang_fan@aaeon.com.tw>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/acpi.h>
+#include <linux/err.h>
+#include <linux/jiffies.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_data/x86/asus-wmi.h>
+#include <linux/platform_device.h>
+
+#define DRVNAME "hwmon-aaeon"
+
+#define AAEON_WMI_MGMT_GUID		"97845ED0-4E6D-11DE-8A39-0800200C9A66"
+
+#define AAEON_VERSION_METHOD_ID		0x00000000
+#define HWM_INFORMATION_METHOD_ID	0x00030000
+#define HWM_METHOD_ID				0x00030001
+
+#define BITMAP_TEMP_ARG			0x12
+#define BITMAP_FAN_ARG			0x13
+#define BITMAP_VOLTAGE_ARG		0x14
+
+#define SENSOR_TEMP_NUMBER		0
+#define SENSOR_FAN_NUMBER		1
+#define SENSOR_VOLTAGE_NUMBER	2
+#define SENSOR_MAX_NUMBER		2
+
+static ssize_t aaeon_show_sensor(struct device *dev,
+			       struct device_attribute *devattr, char *buf);
+static ssize_t aaeon_show_sensor_name(struct device *dev,
+				    struct device_attribute *devattr,
+				    char *buf);
+static ssize_t aaeon_show_version(struct device *dev,
+				  struct device_attribute *devattr, char *buf);
+static ssize_t name_show(struct device *dev, struct device_attribute *devattr,
+			 char *buf);
+static int aaeon_get_version(void);
+static int aaeon_hwmon_probe(struct platform_device *pdev);
+static int aaeon_hwmon_remove(struct platform_device *pdev);
+
+static const char * const temp_sensors_name_table[] = {
+			"CPU_Temp",
+			"SYS1_Temp",
+			"SYS2_Temp",
+};
+
+static const char * const temp_sensors_name_table_V3[] = {
+			"SYS_Temp",
+			"CPU_Temp",
+};
+
+static const char * const fan_sensors_name_table[] = {
+			"CPU_FAN",
+			"SYS1_FAN",
+			"SYS2_FAN",
+			"Chasis1_FAN",
+			"Chasis2_FAN",
+};
+
+static const char * const fan_sensors_name_table_V3[] = {
+			"Chasis_FAN",
+			"CPU_FAN",
+};
+
+static const char * const voltage_sensors_name_table[] = {
+			"VCORE_Voltage",
+			"VMEM_Voltage",
+			"+12_Voltage",
+			"+5_Voltage",
+			"+3.3_Voltage",
+			"+1.8_Voltage",
+			"5VSB_Voltage",
+			"3VSB_Voltage",
+			"VBAT_Voltage",
+};
+
+static const char * const voltage_sensors_name_table_V3[] = {
+			"VCORE_Voltage",
+			"+5_Voltage",
+			"AVCC_Voltage",
+			"+3.3_Voltage",
+			"+12_Voltage",
+			"VCOREREFIN_Voltage",
+			"VIN4_Voltage",
+			"3VSB_Voltage",
+			"VBAT_Voltage",
+};
+
+struct aaeon_hwmon_data {
+	struct device *hwmon_dev;
+	int bfpi_version;
+	u32 temp_bitmap;
+	u32 fan_bitmap;
+	u32 voltage_bitmap;
+	unsigned int sensors_number[SENSOR_MAX_NUMBER + 1];
+	const char * const *temp_names;
+	const char * const *fan_names;
+	const char * const *voltage_names;
+};
+
+/* Temperature attributes */
+static struct sensor_device_attribute_2 temp_sys_nodes_atts[] = {
+	SENSOR_ATTR_2(temp1_input, 0444, aaeon_show_sensor, NULL,
+				SENSOR_TEMP_NUMBER, 0),
+	SENSOR_ATTR_2(temp1_label, 0444, aaeon_show_sensor_name, NULL,
+				SENSOR_TEMP_NUMBER, 0),
+	SENSOR_ATTR_2(temp2_input, 0444, aaeon_show_sensor, NULL,
+				SENSOR_TEMP_NUMBER, 1),
+	SENSOR_ATTR_2(temp2_label, 0444, aaeon_show_sensor_name, NULL,
+				SENSOR_TEMP_NUMBER, 1),
+	SENSOR_ATTR_2(temp3_input, 0444, aaeon_show_sensor, NULL,
+				SENSOR_TEMP_NUMBER, 2),
+	SENSOR_ATTR_2(temp3_label, 0444, aaeon_show_sensor_name, NULL,
+				SENSOR_TEMP_NUMBER, 2),
+};
+
+/* Cooler Fan attributes */
+static struct sensor_device_attribute_2 fan_sys_nodes_atts[] = {
+	SENSOR_ATTR_2(fan1_input, 0444, aaeon_show_sensor, NULL,
+				SENSOR_FAN_NUMBER, 0),
+	SENSOR_ATTR_2(fan1_label, 0444, aaeon_show_sensor_name, NULL,
+				SENSOR_FAN_NUMBER, 0),
+	SENSOR_ATTR_2(fan2_input, 0444, aaeon_show_sensor, NULL,
+				SENSOR_FAN_NUMBER, 1),
+	SENSOR_ATTR_2(fan2_label, 0444, aaeon_show_sensor_name, NULL,
+				SENSOR_FAN_NUMBER, 1),
+	SENSOR_ATTR_2(fan3_input, 0444, aaeon_show_sensor, NULL,
+				SENSOR_FAN_NUMBER, 2),
+	SENSOR_ATTR_2(fan3_label, 0444, aaeon_show_sensor_name, NULL,
+				SENSOR_FAN_NUMBER, 2),
+	SENSOR_ATTR_2(fan4_input, 0444, aaeon_show_sensor, NULL,
+				SENSOR_FAN_NUMBER, 3),
+	SENSOR_ATTR_2(fan4_label, 0444, aaeon_show_sensor_name, NULL,
+				SENSOR_FAN_NUMBER, 3),
+	SENSOR_ATTR_2(fan5_input, 0444, aaeon_show_sensor, NULL,
+				SENSOR_FAN_NUMBER, 4),
+	SENSOR_ATTR_2(fan5_label, 0444, aaeon_show_sensor_name, NULL,
+				SENSOR_FAN_NUMBER, 4),
+};
+
+/* Voltage attributes */
+static struct sensor_device_attribute_2 voltage_sys_nodes_atts[] = {
+	SENSOR_ATTR_2(in1_input, 0444, aaeon_show_sensor, NULL,
+			SENSOR_VOLTAGE_NUMBER, 0),
+	SENSOR_ATTR_2(in1_label, 0444, aaeon_show_sensor_name, NULL,
+			SENSOR_VOLTAGE_NUMBER, 0),
+	SENSOR_ATTR_2(in2_input, 0444, aaeon_show_sensor, NULL,
+			SENSOR_VOLTAGE_NUMBER, 1),
+	SENSOR_ATTR_2(in2_label, 0444, aaeon_show_sensor_name, NULL,
+			SENSOR_VOLTAGE_NUMBER, 1),
+	SENSOR_ATTR_2(in3_input, 0444, aaeon_show_sensor, NULL,
+			SENSOR_VOLTAGE_NUMBER, 2),
+	SENSOR_ATTR_2(in3_label, 0444, aaeon_show_sensor_name, NULL,
+			SENSOR_VOLTAGE_NUMBER, 2),
+	SENSOR_ATTR_2(in4_input, 0444, aaeon_show_sensor, NULL,
+			SENSOR_VOLTAGE_NUMBER, 3),
+	SENSOR_ATTR_2(in4_label, 0444, aaeon_show_sensor_name, NULL,
+			SENSOR_VOLTAGE_NUMBER, 3),
+	SENSOR_ATTR_2(in5_input, 0444, aaeon_show_sensor, NULL,
+			SENSOR_VOLTAGE_NUMBER, 4),
+	SENSOR_ATTR_2(in5_label, 0444, aaeon_show_sensor_name, NULL,
+			SENSOR_VOLTAGE_NUMBER, 4),
+	SENSOR_ATTR_2(in6_input, 0444, aaeon_show_sensor, NULL,
+			SENSOR_VOLTAGE_NUMBER, 5),
+	SENSOR_ATTR_2(in6_label, 0444, aaeon_show_sensor_name, NULL,
+			SENSOR_VOLTAGE_NUMBER, 5),
+	SENSOR_ATTR_2(in7_input, 0444, aaeon_show_sensor, NULL,
+			SENSOR_VOLTAGE_NUMBER, 6),
+	SENSOR_ATTR_2(in7_label, 0444, aaeon_show_sensor_name, NULL,
+			SENSOR_VOLTAGE_NUMBER, 6),
+	SENSOR_ATTR_2(in8_input, 0444, aaeon_show_sensor, NULL,
+			SENSOR_VOLTAGE_NUMBER, 7),
+	SENSOR_ATTR_2(in8_label, 0444, aaeon_show_sensor_name, NULL,
+			SENSOR_VOLTAGE_NUMBER, 7),
+	SENSOR_ATTR_2(in9_input, 0444, aaeon_show_sensor, NULL,
+			SENSOR_VOLTAGE_NUMBER, 8),
+	SENSOR_ATTR_2(in9_label, 0444, aaeon_show_sensor_name, NULL,
+			SENSOR_VOLTAGE_NUMBER, 8),
+
+};
+
+static struct sensor_device_attribute_2 info_sys_nodes_atts[] = {
+	/* WMI version Information */
+	SENSOR_ATTR_2(AAEON_VERSION, 0444, aaeon_show_version, NULL, 0, 0),
+};
+
+DEVICE_ATTR_RO(name);
+static ssize_t name_show(struct device *dev, struct device_attribute *devattr,
+			 char *buf)
+{
+	return sprintf(buf, "%s\n", DRVNAME);
+}
+
+static ssize_t aaeon_show_version(struct device *dev,
+				  struct device_attribute *devattr, char *buf)
+{
+	struct aaeon_hwmon_data *data =
+			(struct aaeon_hwmon_data *)dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", data->bfpi_version);
+}
+
+static ssize_t aaeon_show_sensor_name(struct device *dev,
+				    struct device_attribute *devattr, char *buf)
+{
+	u8 nr = to_sensor_dev_attr_2(devattr)->nr;
+	u8 index = to_sensor_dev_attr_2(devattr)->index;
+	struct aaeon_hwmon_data *data =
+			(struct aaeon_hwmon_data *)dev_get_drvdata(dev);
+
+	if (nr > SENSOR_MAX_NUMBER || index >= data->sensors_number[nr]) {
+		pr_debug("Can not check the device");
+		return -1;
+	}
+
+	switch (nr) {
+	case SENSOR_TEMP_NUMBER:
+		return sprintf(buf, "%s\n", data->temp_names[index]);
+	case SENSOR_FAN_NUMBER:
+		return sprintf(buf, "%s\n", data->fan_names[index]);
+	case SENSOR_VOLTAGE_NUMBER:
+		return sprintf(buf, "%s\n", data->voltage_names[index]);
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+static ssize_t aaeon_show_sensor(struct device *dev,
+			       struct device_attribute *devattr, char *buf)
+{
+	u8 nr = to_sensor_dev_attr_2(devattr)->nr;
+	u8 index = to_sensor_dev_attr_2(devattr)->index;
+	u32 dev_id;
+	int retval, err;
+	struct aaeon_hwmon_data *data =
+			(struct aaeon_hwmon_data *)dev_get_drvdata(dev);
+
+	if (nr > SENSOR_MAX_NUMBER || index >= data->sensors_number[nr]) {
+		pr_debug("Can not check the device");
+		return -1;
+	}
+
+	/* For the V3 version, index need offset */
+	if (data->bfpi_version == 0x03 && nr != SENSOR_VOLTAGE_NUMBER)
+		index++;
+
+	dev_id = (index << 12) | (nr << 8);
+	err = asus_wmi_evaluate_method(HWM_METHOD_ID, dev_id, 0, &retval);
+	if (err)
+		return err;
+
+	/* For the V3 version, need to convert the raw value*/
+	if (nr == SENSOR_VOLTAGE_NUMBER && data->bfpi_version == 0x03) {
+		switch (index) {
+		case 0: /* VCORE */
+			retval = retval * 16;
+			break;
+		case 1: /* +5V */
+			retval = (retval * 2008) / 50;
+			break;
+		case 2: /* AVCC */
+			retval = retval * 16;
+			break;
+		case 3: /* +3.3V */
+			retval = retval * 16;
+			break;
+		case 4: /* +12V */
+			retval = retval * 96;
+			break;
+		case 5: /* VCOREREFIN */
+			retval = (retval * 552) / 41;
+			break;
+		case 6: /* VIN4 */
+			retval = retval * 8;
+			break;
+		case 7: /* 3VSB */
+			retval = retval * 16;
+			break;
+		case 8: /* VBAT */
+			retval = retval * 16;
+			break;
+		default:
+			break;
+		}
+	} else if (nr == SENSOR_TEMP_NUMBER && data->bfpi_version == 0x03)
+		retval = retval * 1000;
+
+	return sprintf(buf, "%d\n", retval);
+}
+
+static int aaeon_hwmon_create_sub_sysfs_fs(struct platform_device *pdev,
+					struct sensor_device_attribute_2 *attr,
+					int sensor_number,
+					u32 sensor_mask,
+					int bfpi_version)
+{
+	int i, err = 0;
+
+	for (i = 0; i < sensor_number; i++) {
+		if (bfpi_version == 0x03 || sensor_mask & BIT(i)) {
+			err = device_create_file(&pdev->dev, &attr[2 * i].dev_attr);
+			if (err)
+				break;
+			err = device_create_file(&pdev->dev, &attr[2 * i + 1].dev_attr);
+			if (err)
+				break;
+		}
+	}
+
+	return err;
+}
+
+static int
+aaeon_hwmon_create_sysfs_files(struct platform_device *pdev, struct aaeon_hwmon_data *data)
+{
+	int err;
+
+	/* register sysfs interface files */
+	err = device_create_file(&pdev->dev, &dev_attr_name);
+	if (err)
+		return err;
+
+	/* registe sysfs to dump sensors BFPI version */
+	err = device_create_file(&pdev->dev, &info_sys_nodes_atts[0].dev_attr);
+	if (err)
+		return err;
+
+	/* create temperature name and value node */
+	err = aaeon_hwmon_create_sub_sysfs_fs(pdev, temp_sys_nodes_atts,
+				data->sensors_number[SENSOR_TEMP_NUMBER],
+				data->temp_bitmap, data->bfpi_version);
+	if (err)
+		return err;
+
+	/* create fan name and value node */
+	err = aaeon_hwmon_create_sub_sysfs_fs(pdev, fan_sys_nodes_atts,
+				data->sensors_number[SENSOR_FAN_NUMBER],
+				data->fan_bitmap, data->bfpi_version);
+	if (err)
+		return err;
+
+	/* create voltage name and value node */
+	err = aaeon_hwmon_create_sub_sysfs_fs(pdev, voltage_sys_nodes_atts,
+				data->sensors_number[SENSOR_VOLTAGE_NUMBER],
+				data->voltage_bitmap, data->bfpi_version);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static void aaeon_hwmon_remove_sub_sysfs_fs(struct platform_device *pdev,
+					struct sensor_device_attribute_2 *attr,
+					int sensor_number,
+					u32 sensor_mask,
+					int bfpi_version)
+{
+	int i;
+
+	for (i = 0; i < sensor_number; i++) {
+		if (bfpi_version == 0x03 || sensor_mask & BIT(i)) {
+			device_remove_file(&pdev->dev, &attr[2 * i].dev_attr);
+			device_remove_file(&pdev->dev, &attr[2 * i + 1].dev_attr);
+		}
+	}
+}
+
+static void
+aaeon_hwmon_remove_sysfs_files(struct platform_device *pdev,
+			       struct aaeon_hwmon_data *data)
+{
+	/* degister sysfs interface files */
+	device_remove_file(&pdev->dev, &dev_attr_name);
+
+	/* degiste sysfs to dump sensors BFPI version */
+	device_remove_file(&pdev->dev, &info_sys_nodes_atts[0].dev_attr);
+
+	/* remove temperature name and value node */
+	aaeon_hwmon_remove_sub_sysfs_fs(pdev, temp_sys_nodes_atts,
+				data->sensors_number[SENSOR_TEMP_NUMBER],
+				data->temp_bitmap,
+				data->bfpi_version);
+
+	/* remove fan name and value node */
+	aaeon_hwmon_remove_sub_sysfs_fs(pdev, fan_sys_nodes_atts,
+				data->sensors_number[SENSOR_FAN_NUMBER],
+				data->fan_bitmap,
+				data->bfpi_version);
+
+	/* remove voltage name and value node */
+	aaeon_hwmon_remove_sub_sysfs_fs(pdev, voltage_sys_nodes_atts,
+				data->sensors_number[SENSOR_VOLTAGE_NUMBER],
+				data->voltage_bitmap,
+				data->bfpi_version);
+}
+
+static int aaeon_hwmon_remove(struct platform_device *pdev)
+{
+	struct aaeon_hwmon_data *data = platform_get_drvdata(pdev);
+
+	if (data->hwmon_dev)
+		hwmon_device_unregister(data->hwmon_dev);
+
+	aaeon_hwmon_remove_sysfs_files(pdev, data);
+
+	return 0;
+}
+
+static int aaeon_get_version(void)
+{
+	int err, retval;
+	u32 dev_id = 0x00;
+
+	err = asus_wmi_evaluate_method(AAEON_VERSION_METHOD_ID, dev_id, 0,
+				       &retval);
+	if (err)
+		return err;
+
+	return retval;
+}
+
+static int aaeon_hwmon_init_drv_data(struct aaeon_hwmon_data *data)
+{
+	int err;
+
+	data->bfpi_version = aaeon_get_version();
+	if (data->bfpi_version < 0) {
+		pr_debug("Error BFPI verion\n");
+		return -1;
+	}
+
+	if (data->bfpi_version == 0x03) {
+		/* set the number of bits in temp bitmap */
+		data->sensors_number[SENSOR_TEMP_NUMBER] =
+				ARRAY_SIZE(temp_sensors_name_table_V3);
+		data->temp_names = temp_sensors_name_table_V3;
+
+		/* set the number of bits in fan bitmap */
+		data->sensors_number[SENSOR_FAN_NUMBER] =
+				ARRAY_SIZE(fan_sensors_name_table_V3);
+		data->fan_names = fan_sensors_name_table_V3;
+
+		/* set the number of bits in voltage bitmap */
+		data->sensors_number[SENSOR_VOLTAGE_NUMBER] =
+				ARRAY_SIZE(voltage_sensors_name_table_V3);
+		data->voltage_names = voltage_sensors_name_table_V3;
+	} else {
+		/* set the number of bits in temp bitmap */
+		data->sensors_number[SENSOR_TEMP_NUMBER] =
+				ARRAY_SIZE(temp_sensors_name_table);
+		data->temp_names = temp_sensors_name_table;
+
+		/* set the number of bits in fan bitmap */
+		data->sensors_number[SENSOR_FAN_NUMBER] =
+				ARRAY_SIZE(fan_sensors_name_table);
+		data->fan_names = fan_sensors_name_table;
+
+		/* set the number of bits in voltage bitmap */
+		data->sensors_number[SENSOR_VOLTAGE_NUMBER] =
+				ARRAY_SIZE(voltage_sensors_name_table);
+		data->voltage_names = voltage_sensors_name_table;
+	}
+
+	/* get temp supported bitmap */
+	err = asus_wmi_evaluate_method(HWM_INFORMATION_METHOD_ID,
+				BITMAP_TEMP_ARG, 0, &data->temp_bitmap);
+	if (err)
+		return err;
+
+	/* get fan supported bitmap */
+	err = asus_wmi_evaluate_method(HWM_INFORMATION_METHOD_ID,
+				BITMAP_FAN_ARG, 0, &data->fan_bitmap);
+	if (err)
+		return err;
+
+	/* get voltage supported bitmap */
+	err = asus_wmi_evaluate_method(HWM_INFORMATION_METHOD_ID,
+				BITMAP_VOLTAGE_ARG, 0, &data->voltage_bitmap);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int aaeon_hwmon_probe(struct platform_device *pdev)
+{
+	int err;
+	struct aaeon_hwmon_data *data;
+
+	pr_debug("aaeon hwomon device probe (support V3)!\n");
+	if (!wmi_has_guid(AAEON_WMI_MGMT_GUID)) {
+		pr_info("AAEON Management GUID not found\n");
+		return -ENODEV;
+	}
+
+	data = devm_kzalloc(&pdev->dev, sizeof(struct aaeon_hwmon_data),
+			    GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	err = aaeon_hwmon_init_drv_data(data);
+	if (err) {
+		pr_info("Error to get sensor support bitmap\n");
+		goto exit;
+	}
+
+	if (data->bfpi_version != 0x03 && data->temp_bitmap == 0 &&
+		data->fan_bitmap == 0 && data->voltage_bitmap == 0) {
+		pr_debug("No sensors found\n");
+		err = -ENODEV;
+		goto exit;
+	}
+
+	platform_set_drvdata(pdev, data);
+	err = aaeon_hwmon_create_sysfs_files(pdev, data);
+	if (err)
+		goto exit;
+
+	data->hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev,
+							  "AAEON_HWM",
+							  data,
+							  NULL,
+							  NULL);
+	if (IS_ERR(data->hwmon_dev)) {
+		err = PTR_ERR(data->hwmon_dev);
+		data->hwmon_dev = NULL;
+		goto exit_unregister_sysfs;
+	}
+
+	return 0;
+
+exit_unregister_sysfs:
+	aaeon_hwmon_remove(pdev);
+exit:
+	return err;
+}
+
+static struct platform_driver aaeon_hwmon_driver = {
+	.driver = {
+		.name = DRVNAME,
+		.owner = THIS_MODULE,
+	},
+	.probe = aaeon_hwmon_probe,
+	.remove = aaeon_hwmon_remove,
+};
+
+module_platform_driver_probe(aaeon_hwmon_driver, aaeon_hwmon_probe);
+
+MODULE_ALIAS("platform:hwmon-aaeon");
+MODULE_DESCRIPTION("AAEON Hardware Monitoring Driver");
+MODULE_AUTHOR("Edward Lin <edward1_lin@aaeon.com.tw>");
+MODULE_AUTHOR("Kunyang Fan <kunyang_fan@aaeon.com.tw>");
+MODULE_LICENSE("GPL v2");
--- linux-qcom-6.8.0.orig/drivers/hwmon/intel-m10-bmc-hwmon.c
+++ linux-qcom-6.8.0/drivers/hwmon/intel-m10-bmc-hwmon.c
@@ -358,7 +358,7 @@
 	{ 0x4f0, 0x4f4, 0x4f8, 0x52c, 0x0, 500, "Board Top Near FPGA Temperature" },
 	{ 0x4fc, 0x500, 0x504, 0x52c, 0x0, 500, "Board Bottom Near CVL Temperature" },
 	{ 0x508, 0x50c, 0x510, 0x52c, 0x0, 500, "Board Top East Near VRs Temperature" },
-	{ 0x514, 0x518, 0x51c, 0x52c, 0x0, 500, "Columbiaville Die Temperature" },
+	{ 0x514, 0x518, 0x51c, 0x52c, 0x0, 500, "CVL Die Temperature" },
 	{ 0x520, 0x524, 0x528, 0x52c, 0x0, 500, "Board Rear Side Temperature" },
 	{ 0x530, 0x534, 0x538, 0x52c, 0x0, 500, "Board Front Side Temperature" },
 	{ 0x53c, 0x540, 0x544, 0x0, 0x0, 500, "QSFP1 Case Temperature" },
@@ -429,7 +429,7 @@
 };
 
 static const struct m10bmc_sdata n6000bmc_power_tbl[] = {
-	{ 0x724, 0x0, 0x0, 0x0, 0x0, 1, "Board Power" },
+	{ 0x724, 0x0, 0x0, 0x0, 0x0, 1000, "Board Power" },
 };
 
 static const struct hwmon_channel_info * const n6000bmc_hinfo[] = {
--- linux-qcom-6.8.0.orig/drivers/hwmon/k10temp.c
+++ linux-qcom-6.8.0/drivers/hwmon/k10temp.c
@@ -153,8 +153,9 @@
 
 static void read_tempreg_nb_zen(struct pci_dev *pdev, u32 *regval)
 {
-	amd_smn_read(amd_pci_dev_to_node_id(pdev),
-		     ZEN_REPORTED_TEMP_CTRL_BASE, regval);
+	if (amd_smn_read(amd_pci_dev_to_node_id(pdev),
+			 ZEN_REPORTED_TEMP_CTRL_BASE, regval))
+		*regval = 0;
 }
 
 static long get_raw_temp(struct k10temp_data *data)
@@ -205,6 +206,7 @@
 			     long *val)
 {
 	struct k10temp_data *data = dev_get_drvdata(dev);
+	int ret = -EOPNOTSUPP;
 	u32 regval;
 
 	switch (attr) {
@@ -221,13 +223,17 @@
 				*val = 0;
 			break;
 		case 2 ... 13:		/* Tccd{1-12} */
-			amd_smn_read(amd_pci_dev_to_node_id(data->pdev),
-				     ZEN_CCD_TEMP(data->ccd_offset, channel - 2),
-						  &regval);
+			ret = amd_smn_read(amd_pci_dev_to_node_id(data->pdev),
+					   ZEN_CCD_TEMP(data->ccd_offset, channel - 2),
+					   &regval);
+
+			if (ret)
+				return ret;
+
 			*val = (regval & ZEN_CCD_TEMP_MASK) * 125 - 49000;
 			break;
 		default:
-			return -EOPNOTSUPP;
+			return ret;
 		}
 		break;
 	case hwmon_temp_max:
@@ -243,7 +249,7 @@
 			- ((regval >> 24) & 0xf)) * 500 + 52000;
 		break;
 	default:
-		return -EOPNOTSUPP;
+		return ret;
 	}
 	return 0;
 }
@@ -381,8 +387,20 @@
 	int 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)
 			data->show_temp |= BIT(TCCD_BIT(i));
 	}
@@ -528,6 +546,7 @@
 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F3) },
 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F3) },
 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F3) },
+	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F3) },
 	{ PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
 	{}
 };
--- linux-qcom-6.8.0.orig/drivers/hwmon/lm95234.c
+++ linux-qcom-6.8.0/drivers/hwmon/lm95234.c
@@ -301,7 +301,8 @@
 	if (ret < 0)
 		return ret;
 
-	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, index ? 255 : 127);
+	val = DIV_ROUND_CLOSEST(clamp_val(val, 0, (index ? 255 : 127) * 1000),
+				1000);
 
 	mutex_lock(&data->update_lock);
 	data->tcrit2[index] = val;
@@ -350,7 +351,7 @@
 	if (ret < 0)
 		return ret;
 
-	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255);
+	val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 255000), 1000);
 
 	mutex_lock(&data->update_lock);
 	data->tcrit1[index] = val;
@@ -391,7 +392,7 @@
 	if (ret < 0)
 		return ret;
 
-	val = DIV_ROUND_CLOSEST(val, 1000);
+	val = DIV_ROUND_CLOSEST(clamp_val(val, -255000, 255000), 1000);
 	val = clamp_val((int)data->tcrit1[index] - val, 0, 31);
 
 	mutex_lock(&data->update_lock);
@@ -431,7 +432,7 @@
 		return ret;
 
 	/* Accuracy is 1/2 degrees C */
-	val = clamp_val(DIV_ROUND_CLOSEST(val, 500), -128, 127);
+	val = DIV_ROUND_CLOSEST(clamp_val(val, -64000, 63500), 500);
 
 	mutex_lock(&data->update_lock);
 	data->toffset[index] = val;
--- linux-qcom-6.8.0.orig/drivers/hwmon/ltc2991.c
+++ linux-qcom-6.8.0/drivers/hwmon/ltc2991.c
@@ -42,9 +42,9 @@
 #define LTC2991_V7_V8_FILT_EN		BIT(7)
 #define LTC2991_V7_V8_TEMP_EN		BIT(5)
 #define LTC2991_V7_V8_DIFF_EN		BIT(4)
-#define LTC2991_V5_V6_FILT_EN		BIT(7)
-#define LTC2991_V5_V6_TEMP_EN		BIT(5)
-#define LTC2991_V5_V6_DIFF_EN		BIT(4)
+#define LTC2991_V5_V6_FILT_EN		BIT(3)
+#define LTC2991_V5_V6_TEMP_EN		BIT(1)
+#define LTC2991_V5_V6_DIFF_EN		BIT(0)
 
 #define LTC2991_REPEAT_ACQ_EN		BIT(4)
 #define LTC2991_T_INT_FILT_EN		BIT(3)
@@ -125,7 +125,7 @@
 
 	/* Vx-Vy, 19.075uV/LSB */
 	*val = DIV_ROUND_CLOSEST(sign_extend32(reg_val, 14) * 19075,
-				 st->r_sense_uohm[channel]);
+				 (s32)st->r_sense_uohm[channel]);
 
 	return 0;
 }
@@ -225,8 +225,8 @@
 	case hwmon_temp:
 		switch (attr) {
 		case hwmon_temp_input:
-			if (st->temp_en[channel] ||
-			    channel == LTC2991_T_INT_CH_NR)
+			if (channel == LTC2991_T_INT_CH_NR ||
+			    st->temp_en[channel])
 				return 0444;
 			break;
 		}
--- linux-qcom-6.8.0.orig/drivers/hwmon/ltc2992.c
+++ linux-qcom-6.8.0/drivers/hwmon/ltc2992.c
@@ -876,9 +876,11 @@
 
 		ret = fwnode_property_read_u32(child, "shunt-resistor-micro-ohms", &val);
 		if (!ret) {
-			if (!val)
+			if (!val) {
+				fwnode_handle_put(child);
 				return dev_err_probe(&st->client->dev, -EINVAL,
 						     "shunt resistor value cannot be zero\n");
+			}
 			st->r_sense_uohm[addr] = val;
 		}
 	}
--- linux-qcom-6.8.0.orig/drivers/hwmon/max16065.c
+++ linux-qcom-6.8.0/drivers/hwmon/max16065.c
@@ -79,7 +79,7 @@
 };
 
 struct max16065_data {
-	enum chips type;
+	enum chips chip;
 	struct i2c_client *client;
 	const struct attribute_group *groups[4];
 	struct mutex update_lock;
@@ -114,9 +114,10 @@
 	return limit * range / 256;
 }
 
-static inline int MV_TO_LIMIT(int mv, int range)
+static inline int MV_TO_LIMIT(unsigned long mv, int range)
 {
-	return clamp_val(DIV_ROUND_CLOSEST(mv * 256, range), 0, 255);
+	mv = clamp_val(mv, 0, ULONG_MAX / 256);
+	return DIV_ROUND_CLOSEST(clamp_val(mv * 256, 0, range * 255), range);
 }
 
 static inline int ADC_TO_CURR(int adc, int gain)
@@ -161,10 +162,17 @@
 						     MAX16065_CURR_SENSE);
 		}
 
-		for (i = 0; i < DIV_ROUND_UP(data->num_adc, 8); i++)
+		for (i = 0; i < 2; i++)
 			data->fault[i]
 			  = i2c_smbus_read_byte_data(client, MAX16065_FAULT(i));
 
+		/*
+		 * MAX16067 and MAX16068 have separate undervoltage and
+		 * overvoltage alarm bits. Squash them together.
+		 */
+		if (data->chip == max16067 || data->chip == max16068)
+			data->fault[0] |= data->fault[1];
+
 		data->last_updated = jiffies;
 		data->valid = true;
 	}
@@ -493,8 +501,6 @@
 	.is_visible = max16065_secondary_is_visible,
 };
 
-static const struct i2c_device_id max16065_id[];
-
 static int max16065_probe(struct i2c_client *client)
 {
 	struct i2c_adapter *adapter = client->adapter;
@@ -505,7 +511,7 @@
 	bool have_secondary;		/* true if chip has secondary limits */
 	bool secondary_is_max = false;	/* secondary limits reflect max */
 	int groups = 0;
-	const struct i2c_device_id *id = i2c_match_id(max16065_id, client);
+	enum chips chip = (uintptr_t)i2c_get_match_data(client);
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
 				     | I2C_FUNC_SMBUS_READ_WORD_DATA))
@@ -515,12 +521,13 @@
 	if (unlikely(!data))
 		return -ENOMEM;
 
+	data->chip = chip;
 	data->client = client;
 	mutex_init(&data->update_lock);
 
-	data->num_adc = max16065_num_adc[id->driver_data];
-	data->have_current = max16065_have_current[id->driver_data];
-	have_secondary = max16065_have_secondary[id->driver_data];
+	data->num_adc = max16065_num_adc[chip];
+	data->have_current = max16065_have_current[chip];
+	have_secondary = max16065_have_secondary[chip];
 
 	if (have_secondary) {
 		val = i2c_smbus_read_byte_data(client, MAX16065_SW_ENABLE);
--- linux-qcom-6.8.0.orig/drivers/hwmon/max6697.c
+++ linux-qcom-6.8.0/drivers/hwmon/max6697.c
@@ -311,6 +311,7 @@
 		return ret;
 
 	mutex_lock(&data->update_lock);
+	temp = clamp_val(temp, -1000000, 1000000);	/* prevent underflow */
 	temp = DIV_ROUND_CLOSEST(temp, 1000) + data->temp_offset;
 	temp = clamp_val(temp, 0, data->type == max6581 ? 255 : 127);
 	data->temp[nr][index] = temp;
@@ -428,14 +429,14 @@
 static SENSOR_DEVICE_ATTR_RO(temp7_max_alarm, alarm, 21);
 static SENSOR_DEVICE_ATTR_RO(temp8_max_alarm, alarm, 23);
 
-static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, alarm, 14);
+static SENSOR_DEVICE_ATTR_RO(temp1_crit_alarm, alarm, 15);
 static SENSOR_DEVICE_ATTR_RO(temp2_crit_alarm, alarm, 8);
 static SENSOR_DEVICE_ATTR_RO(temp3_crit_alarm, alarm, 9);
 static SENSOR_DEVICE_ATTR_RO(temp4_crit_alarm, alarm, 10);
 static SENSOR_DEVICE_ATTR_RO(temp5_crit_alarm, alarm, 11);
 static SENSOR_DEVICE_ATTR_RO(temp6_crit_alarm, alarm, 12);
 static SENSOR_DEVICE_ATTR_RO(temp7_crit_alarm, alarm, 13);
-static SENSOR_DEVICE_ATTR_RO(temp8_crit_alarm, alarm, 15);
+static SENSOR_DEVICE_ATTR_RO(temp8_crit_alarm, alarm, 14);
 
 static SENSOR_DEVICE_ATTR_RO(temp2_fault, alarm, 1);
 static SENSOR_DEVICE_ATTR_RO(temp3_fault, alarm, 2);
--- linux-qcom-6.8.0.orig/drivers/hwmon/nct6775-core.c
+++ linux-qcom-6.8.0/drivers/hwmon/nct6775-core.c
@@ -2262,7 +2262,7 @@
 	if (err < 0)
 		return err;
 
-	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127);
+	val = DIV_ROUND_CLOSEST(clamp_val(val, -128000, 127000), 1000);
 
 	mutex_lock(&data->update_lock);
 	data->temp_offset[nr] = val;
@@ -2878,8 +2878,7 @@
 	if (err < 0)
 		return err;
 
-	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0,
-			data->target_temp_mask);
+	val = DIV_ROUND_CLOSEST(clamp_val(val, 0, data->target_temp_mask * 1000), 1000);
 
 	mutex_lock(&data->update_lock);
 	data->target_temp[nr] = val;
@@ -2959,7 +2958,7 @@
 		return err;
 
 	/* Limit tolerance as needed */
-	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, data->tolerance_mask);
+	val = DIV_ROUND_CLOSEST(clamp_val(val, 0, data->tolerance_mask * 1000), 1000);
 
 	mutex_lock(&data->update_lock);
 	data->temp_tolerance[index][nr] = val;
@@ -3085,7 +3084,7 @@
 	if (err < 0)
 		return err;
 
-	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 255);
+	val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 255000), 1000);
 
 	mutex_lock(&data->update_lock);
 	data->weight_temp[index][nr] = val;
--- linux-qcom-6.8.0.orig/drivers/hwmon/nct6775-platform.c
+++ linux-qcom-6.8.0/drivers/hwmon/nct6775-platform.c
@@ -1269,6 +1269,7 @@
 	"EX-B760M-V5 D4",
 	"EX-H510M-V3",
 	"EX-H610M-V3 D4",
+	"G15CF",
 	"PRIME A620M-A",
 	"PRIME B560-PLUS",
 	"PRIME B560-PLUS AC-HES",
@@ -1349,6 +1350,8 @@
 	"Pro H610M-CT D4",
 	"Pro H610T D4",
 	"Pro Q670M-C",
+	"Pro WS 600M-CL",
+	"Pro WS 665-ACE",
 	"Pro WS W680-ACE",
 	"Pro WS W680-ACE IPMI",
 	"Pro WS W790-ACE",
--- linux-qcom-6.8.0.orig/drivers/hwmon/ntc_thermistor.c
+++ linux-qcom-6.8.0/drivers/hwmon/ntc_thermistor.c
@@ -62,6 +62,7 @@
 	[NTC_SSG1404001221]   = { "ssg1404_001221",  TYPE_NCPXXWB473 },
 	[NTC_LAST]            = { },
 };
+MODULE_DEVICE_TABLE(platform, ntc_thermistor_id);
 
 /*
  * A compensation table should be sorted by the values of .ohm
--- linux-qcom-6.8.0.orig/drivers/hwmon/pmbus/pmbus.h
+++ linux-qcom-6.8.0/drivers/hwmon/pmbus/pmbus.h
@@ -418,6 +418,12 @@
 enum pmbus_data_format { linear = 0, ieee754, direct, vid };
 enum vrm_version { vr11 = 0, vr12, vr13, imvp9, amd625mv };
 
+/* PMBus revision identifiers */
+#define PMBUS_REV_10 0x00	/* PMBus revision 1.0 */
+#define PMBUS_REV_11 0x11	/* PMBus revision 1.1 */
+#define PMBUS_REV_12 0x22	/* PMBus revision 1.2 */
+#define PMBUS_REV_13 0x33	/* PMBus revision 1.3 */
+
 struct pmbus_driver_info {
 	int pages;		/* Total number of pages */
 	u8 phases[PMBUS_PAGES];	/* Number of phases per page */
--- linux-qcom-6.8.0.orig/drivers/hwmon/pmbus/pmbus_core.c
+++ linux-qcom-6.8.0/drivers/hwmon/pmbus/pmbus_core.c
@@ -85,6 +85,8 @@
 
 	u32 flags;		/* from platform data */
 
+	u8 revision;	/* The PMBus revision the device is compliant with */
+
 	int exponent[PMBUS_PAGES];
 				/* linear mode: exponent for output voltages */
 
@@ -1095,9 +1097,14 @@
 
 	regval = status & mask;
 	if (regval) {
-		ret = _pmbus_write_byte_data(client, page, reg, regval);
-		if (ret)
-			goto unlock;
+		if (data->revision >= PMBUS_REV_12) {
+			ret = _pmbus_write_byte_data(client, page, reg, regval);
+			if (ret)
+				goto unlock;
+		} else {
+			pmbus_clear_fault_page(client, page);
+		}
+
 	}
 	if (s1 && s2) {
 		s64 v1, v2;
@@ -2640,6 +2647,10 @@
 			data->flags |= PMBUS_WRITE_PROTECTED | PMBUS_SKIP_STATUS_CHECK;
 	}
 
+	ret = i2c_smbus_read_byte_data(client, PMBUS_REVISION);
+	if (ret >= 0)
+		data->revision = ret;
+
 	if (data->info->pages)
 		pmbus_clear_faults(client);
 	else
@@ -3188,7 +3199,17 @@
 
 static int pmbus_write_smbalert_mask(struct i2c_client *client, u8 page, u8 reg, u8 val)
 {
-	return pmbus_write_word_data(client, page, PMBUS_SMBALERT_MASK, reg | (val << 8));
+	int ret;
+
+	ret = _pmbus_write_word_data(client, page, PMBUS_SMBALERT_MASK, reg | (val << 8));
+
+	/*
+	 * Clear fault systematically in case writing PMBUS_SMBALERT_MASK
+	 * is not supported by the chip.
+	 */
+	pmbus_clear_fault_page(client, page);
+
+	return ret;
 }
 
 static irqreturn_t pmbus_fault_handler(int irq, void *pdata)
--- linux-qcom-6.8.0.orig/drivers/hwmon/pmbus/ucd9000.c
+++ linux-qcom-6.8.0/drivers/hwmon/pmbus/ucd9000.c
@@ -80,11 +80,11 @@
  * It has been observed that the UCD90320 randomly fails register access when
  * doing another access right on the back of a register write. To mitigate this
  * make sure that there is a minimum delay between a write access and the
- * following access. The 250us is based on experimental data. At a delay of
- * 200us the issue seems to go away. Add a bit of extra margin to allow for
+ * following access. The 500 is based on experimental data. At a delay of
+ * 350us the issue seems to go away. Add a bit of extra margin to allow for
  * system to system differences.
  */
-#define UCD90320_WAIT_DELAY_US 250
+#define UCD90320_WAIT_DELAY_US 500
 
 static inline void ucd90320_wait(const struct ucd9000_data *data)
 {
--- linux-qcom-6.8.0.orig/drivers/hwmon/shtc1.c
+++ linux-qcom-6.8.0/drivers/hwmon/shtc1.c
@@ -238,7 +238,7 @@
 
 	if (np) {
 		data->setup.blocking_io = of_property_read_bool(np, "sensirion,blocking-io");
-		data->setup.high_precision = !of_property_read_bool(np, "sensicon,low-precision");
+		data->setup.high_precision = !of_property_read_bool(np, "sensirion,low-precision");
 	} else {
 		if (client->dev.platform_data)
 			data->setup = *(struct shtc1_platform_data *)dev->platform_data;
--- linux-qcom-6.8.0.orig/drivers/hwmon/tmp513.c
+++ linux-qcom-6.8.0/drivers/hwmon/tmp513.c
@@ -182,7 +182,7 @@
 	struct regmap *regmap;
 };
 
-// Set the shift based on the gain 8=4, 4=3, 2=2, 1=1
+// Set the shift based on the gain: 8 -> 1, 4 -> 2, 2 -> 3, 1 -> 4
 static inline u8 tmp51x_get_pga_shift(struct tmp51x_data *data)
 {
 	return 5 - ffs(data->pga_gain);
@@ -204,8 +204,11 @@
 		 * 2's complement number shifted by one to four depending
 		 * on the pga gain setting. 1lsb = 10uV
 		 */
-		*val = sign_extend32(regval, 17 - tmp51x_get_pga_shift(data));
-		*val = DIV_ROUND_CLOSEST(*val * 10 * MILLI, data->shunt_uohms);
+		*val = sign_extend32(regval,
+				     reg == TMP51X_SHUNT_CURRENT_RESULT ?
+				     16 - tmp51x_get_pga_shift(data) : 15);
+		*val = DIV_ROUND_CLOSEST(*val * 10 * (long)MILLI, (long)data->shunt_uohms);
+
 		break;
 	case TMP51X_BUS_VOLTAGE_RESULT:
 	case TMP51X_BUS_VOLTAGE_H_LIMIT:
@@ -220,8 +223,8 @@
 		break;
 	case TMP51X_BUS_CURRENT_RESULT:
 		// Current = (ShuntVoltage * CalibrationRegister) / 4096
-		*val = sign_extend32(regval, 16) * data->curr_lsb_ua;
-		*val = DIV_ROUND_CLOSEST(*val, MILLI);
+		*val = sign_extend32(regval, 15) * (long)data->curr_lsb_ua;
+		*val = DIV_ROUND_CLOSEST(*val, (long)MILLI);
 		break;
 	case TMP51X_LOCAL_TEMP_RESULT:
 	case TMP51X_REMOTE_TEMP_RESULT_1:
@@ -232,7 +235,7 @@
 	case TMP51X_REMOTE_TEMP_LIMIT_2:
 	case TMP513_REMOTE_TEMP_LIMIT_3:
 		// 1lsb = 0.0625 degrees centigrade
-		*val = sign_extend32(regval, 16) >> TMP51X_TEMP_SHIFT;
+		*val = sign_extend32(regval, 15) >> TMP51X_TEMP_SHIFT;
 		*val = DIV_ROUND_CLOSEST(*val * 625, 10);
 		break;
 	case TMP51X_N_FACTOR_AND_HYST_1:
@@ -261,7 +264,7 @@
 		 * The user enter current value and we convert it to
 		 * voltage. 1lsb = 10uV
 		 */
-		val = DIV_ROUND_CLOSEST(val * data->shunt_uohms, 10 * MILLI);
+		val = DIV_ROUND_CLOSEST(val * (long)data->shunt_uohms, 10 * (long)MILLI);
 		max_val = U16_MAX >> tmp51x_get_pga_shift(data);
 		regval = clamp_val(val, -max_val, max_val);
 		break;
--- linux-qcom-6.8.0.orig/drivers/hwmon/tps23861.c
+++ linux-qcom-6.8.0/drivers/hwmon/tps23861.c
@@ -132,7 +132,7 @@
 	if (err < 0)
 		return err;
 
-	*val = (regval * TEMPERATURE_LSB) - 20000;
+	*val = ((long)regval * TEMPERATURE_LSB) - 20000;
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/hwmon/w83627ehf.c
+++ linux-qcom-6.8.0/drivers/hwmon/w83627ehf.c
@@ -895,7 +895,7 @@
 	if (err < 0)
 		return err;
 
-	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 127);
+	val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 127000), 1000);
 
 	mutex_lock(&data->update_lock);
 	data->target_temp[nr] = val;
@@ -920,7 +920,7 @@
 		return err;
 
 	/* Limit the temp to 0C - 15C */
-	val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), 0, 15);
+	val = DIV_ROUND_CLOSEST(clamp_val(val, 0, 15000), 1000);
 
 	mutex_lock(&data->update_lock);
 	reg = w83627ehf_read_value(data, W83627EHF_REG_TOLERANCE[nr]);
--- linux-qcom-6.8.0.orig/drivers/hwspinlock/hwspinlock_core.c
+++ linux-qcom-6.8.0/drivers/hwspinlock/hwspinlock_core.c
@@ -306,6 +306,34 @@
 EXPORT_SYMBOL_GPL(__hwspin_unlock);
 
 /**
+ * hwspin_lock_bust() - bust a specific hwspinlock
+ * @hwlock: a previously-acquired hwspinlock which we want to bust
+ * @id: identifier of the remote lock holder, if applicable
+ *
+ * This function will bust a hwspinlock that was previously acquired as
+ * long as the current owner of the lock matches the id given by the caller.
+ *
+ * Context: Process context.
+ *
+ * Returns: 0 on success, or -EINVAL if the hwspinlock does not exist, or
+ * the bust operation fails, and -EOPNOTSUPP if the bust operation is not
+ * defined for the hwspinlock.
+ */
+int hwspin_lock_bust(struct hwspinlock *hwlock, unsigned int id)
+{
+	if (WARN_ON(!hwlock))
+		return -EINVAL;
+
+	if (!hwlock->bank->ops->bust) {
+		pr_err("bust operation not defined\n");
+		return -EOPNOTSUPP;
+	}
+
+	return hwlock->bank->ops->bust(hwlock, id);
+}
+EXPORT_SYMBOL_GPL(hwspin_lock_bust);
+
+/**
  * of_hwspin_lock_simple_xlate - translate hwlock_spec to return a lock id
  * @hwlock_spec: hwlock specifier as found in the device tree
  *
--- linux-qcom-6.8.0.orig/drivers/hwspinlock/hwspinlock_internal.h
+++ linux-qcom-6.8.0/drivers/hwspinlock/hwspinlock_internal.h
@@ -21,6 +21,8 @@
  * @trylock: make a single attempt to take the lock. returns 0 on
  *	     failure and true on success. may _not_ sleep.
  * @unlock:  release the lock. always succeed. may _not_ sleep.
+ * @bust:    optional, platform-specific bust handler, called by hwspinlock
+ *	     core to bust a specific lock.
  * @relax:   optional, platform-specific relax handler, called by hwspinlock
  *	     core while spinning on a lock, between two successive
  *	     invocations of @trylock. may _not_ sleep.
@@ -28,6 +30,7 @@
 struct hwspinlock_ops {
 	int (*trylock)(struct hwspinlock *lock);
 	void (*unlock)(struct hwspinlock *lock);
+	int (*bust)(struct hwspinlock *lock, unsigned int id);
 	void (*relax)(struct hwspinlock *lock);
 };
 
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/Kconfig
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/Kconfig
@@ -35,6 +35,7 @@
 	tristate "Coresight generic TMC driver"
 
 	depends on CORESIGHT_LINKS_AND_SINKS
+	select CORESIGHT_CSR
 	help
 	  This enables support for the Trace Memory Controller driver.
 	  Depending on its configuration the device can act as a link (embedded
@@ -133,6 +134,14 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called coresight-stm.
 
+config CORESIGHT_CSR
+	tristate "CoreSight Slave Register driver"
+	help
+	  This driver provides support for CoreSight Slave Register block
+	  that hosts miscellaneous configuration registers.
+	  Those configuration registers can be used to control, various
+	  coresight configurations.
+
 config CORESIGHT_CPU_DEBUG
 	tristate "CoreSight CPU Debug driver"
 	depends on ARM || ARM64
@@ -163,6 +172,15 @@
 
 	  Say N if unsure.
 
+config CORESIGHT_REMOTE_ETM
+	tristate "Remote processor ETM trace support"
+	select QCOM_QMI_HELPERS
+	help
+	  Enables support for ETM trace collection on remote processor using
+	  CoreSight framework. Enabling this will allow turning on ETM
+	  tracing on remote processor via sysfs by configuring the required
+	  CoreSight components.
+
 config CORESIGHT_CTI
 	tristate "CoreSight Cross Trigger Interface (CTI) driver"
 	depends on ARM || ARM64
@@ -202,6 +220,20 @@
 	  To compile this driver as a module, choose M here: the module will be
 	  called coresight-trbe.
 
+config CORESIGHT_TGU
+	tristate "CoreSight Trigger Generation Unit driver"
+	help
+	  This driver provides support for Trigger Generation Unit that is
+	  used to detect patterns or sequences on a given set of signals.
+	  TGU is used to monitor a particular bus within a given region to
+	  detect illegal transaction sequences or slave responses. It is also
+	  used to monitor a data stream to detect protocol violations and to
+	  provide a trigger point for centering data around a specific event
+	  within the trace data buffer.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called coresight-tgu.
+
 config ULTRASOC_SMB
 	tristate "Ultrasoc system memory buffer drivers"
 	depends on ACPI || COMPILE_TEST
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/Makefile
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/Makefile
@@ -2,6 +2,8 @@
 #
 # Makefile for CoreSight drivers.
 #
+CFLAGS_coresight-stm.o := -D__DISABLE_TRACE_MMIO__
+
 obj-$(CONFIG_CORESIGHT) += coresight.o
 coresight-y := coresight-core.o  coresight-etm-perf.o coresight-platform.o \
 		coresight-sysfs.o coresight-syscfg.o coresight-config.o \
@@ -9,7 +11,8 @@
 		coresight-syscfg-configfs.o coresight-trace-id.o
 obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o
 coresight-tmc-y := coresight-tmc-core.o coresight-tmc-etf.o \
-		      coresight-tmc-etr.o
+		      coresight-tmc-etr.o coresight-byte-cntr.o \
+		      coresight-tmc-usb.o
 obj-$(CONFIG_CORESIGHT_SINK_TPIU) += coresight-tpiu.o
 obj-$(CONFIG_CORESIGHT_SINK_ETBV10) += coresight-etb10.o
 obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \
@@ -24,6 +27,7 @@
 obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
 obj-$(CONFIG_CORESIGHT_CATU) += coresight-catu.o
 obj-$(CONFIG_CORESIGHT_CTI) += coresight-cti.o
+obj-$(CONFIG_CORESIGHT_REMOTE_ETM) += coresight-remote-etm.o
 obj-$(CONFIG_CORESIGHT_TRBE) += coresight-trbe.o
 obj-$(CONFIG_CORESIGHT_TPDM) += coresight-tpdm.o
 obj-$(CONFIG_CORESIGHT_TPDA) += coresight-tpda.o
@@ -31,3 +35,5 @@
 		   coresight-cti-sysfs.o
 obj-$(CONFIG_ULTRASOC_SMB) += ultrasoc-smb.o
 obj-$(CONFIG_CORESIGHT_DUMMY) += coresight-dummy.o
+obj-$(CONFIG_CORESIGHT_CSR) += coresight-csr.o
+obj-$(CONFIG_CORESIGHT_TGU) += coresight-tgu.o
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-byte-cntr.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-byte-cntr.c
@@ -0,0 +1,400 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/fs.h>
+#include <linux/of_irq.h>
+#include <linux/moduleparam.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/property.h>
+
+#include "coresight-priv.h"
+#include "coresight-byte-cntr.h"
+#include "coresight-common.h"
+
+#define CSR_BYTECNTVAL		(0x06C)
+
+static void tmc_etr_read_bytes(struct byte_cntr *byte_cntr_data, long offset,
+			       size_t bytes, size_t *len, char **bufp)
+{
+	struct tmc_drvdata *tmcdrvdata = byte_cntr_data->tmcdrvdata;
+	struct etr_buf *etr_buf = tmcdrvdata->sysfs_buf;
+	size_t actual;
+
+	if (*len >= bytes)
+		*len = bytes;
+	else if (((uint32_t)offset % bytes) + *len > bytes)
+		*len = bytes - ((uint32_t)offset % bytes);
+
+	actual = tmc_etr_buf_get_data(etr_buf, offset, *len, bufp);
+	*len = actual;
+	if (actual == bytes || (actual + (uint32_t)offset) % bytes == 0)
+		atomic_dec(&byte_cntr_data->irq_cnt);
+}
+
+
+static irqreturn_t etr_handler(int irq, void *data)
+{
+	struct byte_cntr *byte_cntr_data = data;
+	struct tmc_drvdata *tmcdrvdata = byte_cntr_data->tmcdrvdata;
+
+	if (tmcdrvdata->out_mode == TMC_ETR_OUT_MODE_USB) {
+		atomic_inc(&byte_cntr_data->irq_cnt);
+		wake_up(&byte_cntr_data->usb_wait_wq);
+	} else if (tmcdrvdata->out_mode == TMC_ETR_OUT_MODE_MEM) {
+		atomic_inc(&byte_cntr_data->irq_cnt);
+		wake_up(&byte_cntr_data->wq);
+	}
+
+	byte_cntr_data->total_irq++;
+
+	return IRQ_HANDLED;
+}
+
+
+static long tmc_etr_flush_remaining_bytes(struct tmc_drvdata *tmcdrvdata, long offset,
+			size_t len, char **bufpp)
+{
+	long req_size, actual = 0;
+	struct etr_buf *etr_buf;
+	struct device *dev;
+	struct byte_cntr *byte_cntr_data;
+
+	if (!tmcdrvdata)
+		return -EINVAL;
+
+	byte_cntr_data = tmcdrvdata->byte_cntr;
+	if (!byte_cntr_data)
+		return -EINVAL;
+
+	etr_buf = tmcdrvdata->sysfs_buf;
+	dev = &tmcdrvdata->csdev->dev;
+
+	req_size = ((byte_cntr_data->rwp_offset < offset) ? tmcdrvdata->size : 0) +
+		byte_cntr_data->rwp_offset - offset;
+
+	if (req_size > len)
+		req_size = len;
+
+	if (req_size > 0)
+		actual = tmc_etr_buf_get_data(etr_buf, offset, req_size, bufpp);
+
+	return actual;
+}
+
+
+static ssize_t tmc_etr_byte_cntr_read(struct file *fp, char __user *data,
+			       size_t len, loff_t *ppos)
+{
+	struct byte_cntr *byte_cntr_data = fp->private_data;
+	struct tmc_drvdata *tmcdrvdata = byte_cntr_data->tmcdrvdata;
+	char *bufp = NULL;
+	long actual;
+	int ret = 0;
+
+	if (!data)
+		return -EINVAL;
+
+	mutex_lock(&byte_cntr_data->byte_cntr_lock);
+	if (!byte_cntr_data->read_active) {
+		actual = tmc_etr_flush_remaining_bytes(tmcdrvdata,
+				byte_cntr_data->offset, len, &bufp);
+		if (actual > 0) {
+			len = actual;
+			goto copy;
+		} else {
+			ret = -EINVAL;
+			goto err0;
+		}
+	}
+
+	if (byte_cntr_data->enable) {
+		if (!atomic_read(&byte_cntr_data->irq_cnt)) {
+			mutex_unlock(&byte_cntr_data->byte_cntr_lock);
+			if (wait_event_interruptible(byte_cntr_data->wq,
+				atomic_read(&byte_cntr_data->irq_cnt) > 0
+				|| !byte_cntr_data->enable))
+				return -ERESTARTSYS;
+			mutex_lock(&byte_cntr_data->byte_cntr_lock);
+			if (!byte_cntr_data->read_active) {
+				actual = tmc_etr_flush_remaining_bytes(tmcdrvdata,
+						byte_cntr_data->offset, len, &bufp);
+				if (actual > 0) {
+					len = actual;
+					goto copy;
+				} else {
+					ret = -EINVAL;
+					goto err0;
+				}
+			}
+		}
+
+		tmc_etr_read_bytes(byte_cntr_data, byte_cntr_data->offset,
+				   byte_cntr_data->block_size, &len, &bufp);
+
+	} else {
+		actual = tmc_etr_flush_remaining_bytes(tmcdrvdata,
+				byte_cntr_data->offset, len, &bufp);
+		if (actual > 0) {
+			len = actual;
+			goto copy;
+		} else {
+			ret = -EINVAL;
+			goto err0;
+		}
+	}
+
+copy:
+	if (copy_to_user(data, bufp, len)) {
+		mutex_unlock(&byte_cntr_data->byte_cntr_lock);
+		dev_dbg(&tmcdrvdata->csdev->dev,
+			"%s: copy_to_user failed\n", __func__);
+		return -EFAULT;
+	}
+
+	byte_cntr_data->total_size += len;
+
+	if (byte_cntr_data->offset + len >= tmcdrvdata->size)
+		byte_cntr_data->offset = 0;
+	else
+		byte_cntr_data->offset += len;
+
+	goto out;
+
+err0:
+	mutex_unlock(&byte_cntr_data->byte_cntr_lock);
+	return ret;
+out:
+	mutex_unlock(&byte_cntr_data->byte_cntr_lock);
+	return len;
+}
+
+void tmc_etr_byte_cntr_start(struct byte_cntr *byte_cntr_data)
+{
+	if (!byte_cntr_data)
+		return;
+
+	mutex_lock(&byte_cntr_data->byte_cntr_lock);
+
+	if (byte_cntr_data->block_size == 0
+		|| byte_cntr_data->read_active) {
+		mutex_unlock(&byte_cntr_data->byte_cntr_lock);
+		return;
+	}
+
+	atomic_set(&byte_cntr_data->irq_cnt, 0);
+	byte_cntr_data->enable = true;
+	mutex_unlock(&byte_cntr_data->byte_cntr_lock);
+}
+EXPORT_SYMBOL_GPL(tmc_etr_byte_cntr_start);
+
+void tmc_etr_byte_cntr_stop(struct byte_cntr *byte_cntr_data)
+{
+	if (!byte_cntr_data)
+		return;
+
+	mutex_lock(&byte_cntr_data->byte_cntr_lock);
+	byte_cntr_data->rwp_offset =
+		tmc_get_rwp_offset(byte_cntr_data->tmcdrvdata);
+	byte_cntr_data->enable = false;
+	byte_cntr_data->read_active = false;
+	atomic_set(&byte_cntr_data->irq_cnt, 0);
+	wake_up(&byte_cntr_data->wq);
+	coresight_csr_set_byte_cntr(byte_cntr_data->csr,
+				byte_cntr_data->irqctrl_offset, 0);
+	mutex_unlock(&byte_cntr_data->byte_cntr_lock);
+
+}
+EXPORT_SYMBOL_GPL(tmc_etr_byte_cntr_stop);
+
+static int tmc_etr_byte_cntr_release(struct inode *in, struct file *fp)
+{
+	struct byte_cntr *byte_cntr_data = fp->private_data;
+	struct device *dev = &byte_cntr_data->tmcdrvdata->csdev->dev;
+
+	mutex_lock(&byte_cntr_data->byte_cntr_lock);
+	byte_cntr_data->read_active = false;
+
+	atomic_set(&byte_cntr_data->irq_cnt, 0);
+
+	if (byte_cntr_data->enable)
+		coresight_csr_set_byte_cntr(byte_cntr_data->csr,
+				byte_cntr_data->irqctrl_offset, 0);
+
+	disable_irq_wake(byte_cntr_data->byte_cntr_irq);
+
+	dev_dbg(dev, "send data total size: %lld bytes, irq_cnt: %lld, offset: %lld rwp_offset: %lld\n",
+		byte_cntr_data->total_size, byte_cntr_data->total_irq,
+		byte_cntr_data->offset,	byte_cntr_data->rwp_offset);
+	mutex_unlock(&byte_cntr_data->byte_cntr_lock);
+
+	return 0;
+}
+
+static int tmc_etr_byte_cntr_open(struct inode *in, struct file *fp)
+{
+	struct byte_cntr *byte_cntr_data =
+			container_of(in->i_cdev, struct byte_cntr, dev);
+	struct tmc_drvdata *tmcdrvdata = byte_cntr_data->tmcdrvdata;
+
+	mutex_lock(&byte_cntr_data->byte_cntr_lock);
+
+	if (byte_cntr_data->read_active) {
+		mutex_unlock(&byte_cntr_data->byte_cntr_lock);
+		return -EBUSY;
+	}
+
+	if (tmcdrvdata->mode != CS_MODE_SYSFS ||
+			!byte_cntr_data->block_size) {
+		mutex_unlock(&byte_cntr_data->byte_cntr_lock);
+		return -EINVAL;
+	}
+
+	enable_irq_wake(byte_cntr_data->byte_cntr_irq);
+	/* IRQ is a '8- byte' counter and to observe interrupt at
+	 * 'block_size' bytes of data
+	 */
+
+	coresight_csr_set_byte_cntr(byte_cntr_data->csr, byte_cntr_data->irqctrl_offset,
+				(byte_cntr_data->block_size) / 8);
+
+	fp->private_data = byte_cntr_data;
+	nonseekable_open(in, fp);
+	byte_cntr_data->enable = true;
+	byte_cntr_data->read_active = true;
+	byte_cntr_data->total_size = 0;
+	byte_cntr_data->offset = tmc_get_rwp_offset(tmcdrvdata);
+	byte_cntr_data->total_irq = 0;
+	mutex_unlock(&byte_cntr_data->byte_cntr_lock);
+	return 0;
+}
+
+static const struct file_operations byte_cntr_fops = {
+	.owner		= THIS_MODULE,
+	.open		= tmc_etr_byte_cntr_open,
+	.read		= tmc_etr_byte_cntr_read,
+	.release	= tmc_etr_byte_cntr_release,
+	.llseek		= no_llseek,
+};
+
+static int byte_cntr_register_chardev(struct byte_cntr *byte_cntr_data)
+{
+	int ret;
+	unsigned int baseminor = 0;
+	unsigned int count = 1;
+	struct device *device;
+	dev_t dev;
+
+	ret = alloc_chrdev_region(&dev, baseminor, count, byte_cntr_data->name);
+	if (ret < 0) {
+		pr_err("alloc_chrdev_region failed %d\n", ret);
+		return ret;
+	}
+	cdev_init(&byte_cntr_data->dev, &byte_cntr_fops);
+
+	byte_cntr_data->dev.owner = THIS_MODULE;
+	byte_cntr_data->dev.ops = &byte_cntr_fops;
+
+	ret = cdev_add(&byte_cntr_data->dev, dev, 1);
+	if (ret)
+		goto exit_unreg_chrdev_region;
+
+	byte_cntr_data->driver_class = class_create(byte_cntr_data->class_name);
+	if (IS_ERR(byte_cntr_data->driver_class)) {
+		ret = -ENOMEM;
+		pr_err("class_create failed %d\n", ret);
+		goto exit_unreg_chrdev_region;
+	}
+
+	device = device_create(byte_cntr_data->driver_class, NULL,
+			       byte_cntr_data->dev.dev, byte_cntr_data,
+			       byte_cntr_data->name);
+
+	if (IS_ERR(device)) {
+		pr_err("class_device_create failed %d\n", ret);
+		ret = -ENOMEM;
+		goto exit_destroy_class;
+	}
+
+	return 0;
+
+exit_destroy_class:
+	class_destroy(byte_cntr_data->driver_class);
+exit_unreg_chrdev_region:
+	unregister_chrdev_region(byte_cntr_data->dev.dev, 1);
+	return ret;
+}
+
+struct byte_cntr *byte_cntr_init(struct amba_device *adev,
+				 struct tmc_drvdata *drvdata)
+{
+	struct device *dev = &adev->dev;
+	struct device_node *np = adev->dev.of_node;
+	int byte_cntr_irq;
+	int ret;
+	struct byte_cntr *byte_cntr_data;
+
+	byte_cntr_irq = of_irq_get_byname(np, "byte-cntr-irq");
+	if (byte_cntr_irq < 0)
+		return NULL;
+
+	byte_cntr_data = devm_kzalloc(dev, sizeof(*byte_cntr_data), GFP_KERNEL);
+	if (!byte_cntr_data)
+		return NULL;
+
+	ret = devm_request_irq(dev, byte_cntr_irq, etr_handler,
+			       IRQF_TRIGGER_RISING | IRQF_SHARED,
+			       dev_name(dev), byte_cntr_data);
+	if (ret) {
+		dev_err(dev, "Byte_cntr interrupt registration failed\n");
+		return NULL;
+	}
+
+	ret = of_property_read_u32(dev->of_node, "csr-irqctrl-offset",
+				&byte_cntr_data->irqctrl_offset);
+
+	if (ret) {
+		dev_dbg(dev, "Get byte cntr csr irqctrl offset failed\n");
+		byte_cntr_data->irqctrl_offset = CSR_BYTECNTVAL;
+	}
+
+	ret = device_property_read_string(dev, "byte-cntr-name", &byte_cntr_data->name);
+	if (ret) {
+		dev_dbg(dev, "Get byte cntr name failed\n");
+		byte_cntr_data->name = "byte-cntr";
+	}
+
+	ret = device_property_read_string(dev, "byte-cntr-class-name",
+				&byte_cntr_data->class_name);
+	if (ret) {
+		dev_dbg(dev, "Get byte cntr class name failed\n");
+		byte_cntr_data->class_name = "coresight-tmc-etr-stream";
+	}
+
+	ret = byte_cntr_register_chardev(byte_cntr_data);
+	if (ret) {
+		dev_err(dev, "Byte_cntr char dev registration failed\n");
+		return NULL;
+	}
+
+	byte_cntr_data->byte_cntr_irq = byte_cntr_irq;
+	byte_cntr_data->csr = drvdata->csr;
+	byte_cntr_data->tmcdrvdata = drvdata;
+	atomic_set(&byte_cntr_data->irq_cnt, 0);
+	init_waitqueue_head(&byte_cntr_data->wq);
+	mutex_init(&byte_cntr_data->byte_cntr_lock);
+
+	return byte_cntr_data;
+}
+
+void byte_cntr_remove(struct byte_cntr *byte_cntr_data)
+{
+	device_destroy(byte_cntr_data->driver_class,
+				byte_cntr_data->dev.dev);
+	class_destroy(byte_cntr_data->driver_class);
+	unregister_chrdev_region(byte_cntr_data->dev.dev, 1);
+}
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-byte-cntr.h
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-byte-cntr.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _CORESIGHT_BYTE_CNTR_H
+#define _CORESIGHT_BYTE_CNTR_H
+#include <linux/cdev.h>
+#include <linux/amba/bus.h>
+#include <linux/wait.h>
+#include <linux/mutex.h>
+#include "coresight-tmc.h"
+
+struct byte_cntr {
+	struct cdev		dev;
+	struct class		*driver_class;
+	bool			enable;
+	bool			read_active;
+	uint32_t		byte_cntr_value;
+	uint32_t		block_size;
+	int			byte_cntr_irq;
+	atomic_t		irq_cnt;
+	atomic_t	usb_free_buf;
+	wait_queue_head_t	wq;
+	wait_queue_head_t	usb_wait_wq;
+	struct workqueue_struct	*usb_wq;
+	struct qdss_request	*usb_req;
+	struct work_struct	read_work;
+	struct mutex		usb_bypass_lock;
+	struct mutex		byte_cntr_lock;
+	struct coresight_csr		*csr;
+	struct tmc_drvdata	*tmcdrvdata;
+	const char		*name;
+	const char		*class_name;
+	int			irqctrl_offset;
+	unsigned long	offset;
+	unsigned long	rwp_offset;
+	uint64_t		total_size;
+	uint64_t		total_irq;
+
+};
+
+extern void tmc_etr_byte_cntr_start(struct byte_cntr *byte_cntr_data);
+extern void tmc_etr_byte_cntr_stop(struct byte_cntr *byte_cntr_data);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-common.h
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-common.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _CORESIGHT_COMMON_H
+#define _CORESIGHT_COMMON_H
+
+#define BM(lsb, msb)		((BIT(msb) - BIT(lsb)) + BIT(msb))
+#define BVAL(val, n)            ((val & BIT(n)) >> n)
+
+struct coresight_csr {
+	const char *name;
+	struct list_head link;
+};
+
+#if IS_ENABLED(CONFIG_CORESIGHT_CSR)
+extern void msm_qdss_csr_enable_bam_to_usb(struct coresight_csr *csr);
+extern void msm_qdss_csr_enable_flush(struct coresight_csr *csr);
+extern void msm_qdss_csr_disable_bam_to_usb(struct coresight_csr *csr);
+extern void msm_qdss_csr_disable_flush(struct coresight_csr *csr);
+extern void msm_qdss_csr_enable_eth(struct coresight_csr *csr);
+extern void msm_qdss_csr_disable_eth(struct coresight_csr *csr);
+extern int coresight_csr_hwctrl_set(struct coresight_csr *csr, uint64_t addr,
+				 uint32_t val);
+extern void coresight_csr_set_byte_cntr(struct coresight_csr *csr, int irqctrl_offset,
+				 uint32_t count);
+extern struct coresight_csr *coresight_csr_get(const char *name);
+extern int coresight_csr_set_etr_atid(struct coresight_device *csdev, int atid, bool enable);
+#if IS_ENABLED(CONFIG_OF)
+extern int of_get_coresight_csr_name(struct device_node *node,
+				const char **csr_name);
+#else
+static inline int of_get_coresight_csr_name(struct device_node *node,
+		const char **csr_name){ return -EINVAL; }
+#endif
+
+#else
+static inline void msm_qdss_csr_enable_bam_to_usb(struct coresight_csr *csr) {}
+static inline void msm_qdss_csr_disable_bam_to_usb(struct coresight_csr *csr) {}
+static inline void msm_qdss_csr_disable_flush(struct coresight_csr *csr) {}
+static inline void msm_qdss_csr_enable_eth(struct coresight_csr *csr) {}
+static inline void msm_qdss_csr_disable_eth(struct coresight_csr *csr) {}
+static inline int coresight_csr_hwctrl_set(struct coresight_csr *csr,
+	uint64_t addr, uint32_t val) { return -EINVAL; }
+static inline void coresight_csr_set_byte_cntr(struct coresight_csr *csr, int irqctrl_offset,
+					   uint32_t count) {}
+static inline struct coresight_csr *coresight_csr_get(const char *name)
+					{ return NULL; }
+static inline int coresight_csr_set_etr_atid(struct coresight_device *csdev, int atid, bool enable)
+				{return -EINVAL; }
+static inline int of_get_coresight_csr_name(struct device_node *node,
+		const char **csr_name){ return -EINVAL; }
+#endif
+#endif
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-core.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-core.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/build_bug.h>
@@ -441,8 +442,26 @@
 	}
 }
 
+/*
+ * Helper function to call source_ops(csdev)->disable and also disable the
+ * helpers.
+ *
+ * There is an imbalance between coresight_enable_path() and
+ * coresight_disable_path(). Enabling also enables the source's helpers as part
+ * of the path, but disabling always skips the first item in the path (which is
+ * the source), so sources and their helpers don't get disabled as part of that
+ * function and we need the extra step here.
+ */
+void coresight_disable_source(struct coresight_device *csdev, void *data)
+{
+	if (source_ops(csdev)->disable)
+		source_ops(csdev)->disable(csdev, data);
+	coresight_disable_helpers(csdev);
+}
+EXPORT_SYMBOL_GPL(coresight_disable_source);
+
 /**
- *  coresight_disable_source - Drop the reference count by 1 and disable
+ *  coresight_disable_source_sysfs - Drop the reference count by 1 and disable
  *  the device if there are no users left.
  *
  *  @csdev: The coresight device to disable
@@ -451,17 +470,15 @@
  *
  *  Returns true if the device has been disabled.
  */
-bool coresight_disable_source(struct coresight_device *csdev, void *data)
+static bool coresight_disable_source_sysfs(struct coresight_device *csdev,
+					   void *data)
 {
 	if (atomic_dec_return(&csdev->refcnt) == 0) {
-		if (source_ops(csdev)->disable)
-			source_ops(csdev)->disable(csdev, data);
-		coresight_disable_helpers(csdev);
+		coresight_disable_source(csdev, data);
 		csdev->enable = false;
 	}
 	return !csdev->enable;
 }
-EXPORT_SYMBOL_GPL(coresight_disable_source);
 
 /*
  * coresight_disable_path_from : Disable components in the given path beyond
@@ -618,6 +635,7 @@
 
 	return csdev;
 }
+EXPORT_SYMBOL_GPL(coresight_get_sink);
 
 static struct coresight_device *
 coresight_find_enabled_sink(struct coresight_device *csdev)
@@ -1094,6 +1112,7 @@
 	if (subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_PROC &&
 	    subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE &&
 	    subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM &&
+	    subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_REMOTE_PROC &&
 	    subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS) {
 		dev_err(&csdev->dev, "wrong device subtype in %s\n", function);
 		return -EINVAL;
@@ -1102,13 +1121,120 @@
 	return 0;
 }
 
+static int coresight_store_path(struct coresight_device *csdev,
+		struct list_head *path)
+{
+	int cpu, ret;
+	enum coresight_dev_subtype_source subtype;
+	u32 hash;
+
+	subtype = csdev->subtype.source_subtype;
+
+	switch (subtype) {
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
+		/*
+		 * When working from sysFS it is important to keep track
+		 * of the paths that were created so that they can be
+		 * undone in 'coresight_disable()'.  Since there can only
+		 * be a single session per tracer (when working from sysFS)
+		 * a per-cpu variable will do just fine.
+		 */
+		cpu = source_ops(csdev)->cpu_id(csdev);
+		per_cpu(tracer_path, cpu) = path;
+		break;
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM:
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_REMOTE_PROC:
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS:
+		/*
+		 * Use the hash of source's device name as ID
+		 * and map the ID to the pointer of the path.
+		 */
+		hash = hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev)));
+		ret = idr_alloc_u32(&path_idr, path, &hash, hash, GFP_KERNEL);
+		if (ret)
+			return ret;
+		break;
+	default:
+		/* We can't be here */
+		break;
+	}
+
+	return 0;
+}
+
+static struct list_head *coresight_remove_path(struct coresight_device *csdev)
+{
+	int cpu;
+	struct list_head *path;
+	u32 hash;
+
+	switch (csdev->subtype.source_subtype) {
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
+		cpu = source_ops(csdev)->cpu_id(csdev);
+		path = per_cpu(tracer_path, cpu);
+		per_cpu(tracer_path, cpu) = NULL;
+		break;
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM:
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_REMOTE_PROC:
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS:
+		hash = hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev)));
+		/* Find the path by the hash. */
+		path = idr_find(&path_idr, hash);
+		if (path == NULL) {
+			pr_err("Path is not found for %s\n", dev_name(&csdev->dev));
+			return NULL;
+		}
+		idr_remove(&path_idr, hash);
+		break;
+	default:
+		/* We can't be here */
+		path = NULL;
+		break;
+	}
+
+	return path;
+}
+
+struct list_head *coresight_get_path(struct coresight_device *csdev)
+{
+	int cpu;
+	struct list_head *path;
+	u32 hash;
+
+	switch (csdev->subtype.source_subtype) {
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
+		cpu = source_ops(csdev)->cpu_id(csdev);
+		path = per_cpu(tracer_path, cpu);
+		break;
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM:
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_REMOTE_PROC:
+	case CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS:
+		hash = hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev)));
+		/* Find the path by the hash. */
+		path = idr_find(&path_idr, hash);
+		if (path == NULL) {
+			pr_err("Path is not found for %s\n", dev_name(&csdev->dev));
+			return NULL;
+		}
+		break;
+	default:
+		path = NULL;
+		break;
+	}
+
+	return path;
+}
+EXPORT_SYMBOL_GPL(coresight_get_path);
+
 int coresight_enable(struct coresight_device *csdev)
 {
-	int cpu, ret = 0;
+	int ret = 0;
 	struct coresight_device *sink;
 	struct list_head *path;
 	enum coresight_dev_subtype_source subtype;
-	u32 hash;
 
 	subtype = csdev->subtype.source_subtype;
 
@@ -1142,43 +1268,18 @@
 		goto out;
 	}
 
-	ret = coresight_enable_path(path, CS_MODE_SYSFS, NULL);
+	ret = coresight_store_path(csdev, path);
 	if (ret)
 		goto err_path;
 
+	ret = coresight_enable_path(path, CS_MODE_SYSFS, NULL);
+	if (ret)
+		goto err_enable_path;
+
 	ret = coresight_enable_source(csdev, CS_MODE_SYSFS, NULL);
 	if (ret)
 		goto err_source;
 
-	switch (subtype) {
-	case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
-		/*
-		 * When working from sysFS it is important to keep track
-		 * of the paths that were created so that they can be
-		 * undone in 'coresight_disable()'.  Since there can only
-		 * be a single session per tracer (when working from sysFS)
-		 * a per-cpu variable will do just fine.
-		 */
-		cpu = source_ops(csdev)->cpu_id(csdev);
-		per_cpu(tracer_path, cpu) = path;
-		break;
-	case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
-	case CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM:
-	case CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS:
-		/*
-		 * Use the hash of source's device name as ID
-		 * and map the ID to the pointer of the path.
-		 */
-		hash = hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev)));
-		ret = idr_alloc_u32(&path_idr, path, &hash, hash, GFP_KERNEL);
-		if (ret)
-			goto err_source;
-		break;
-	default:
-		/* We can't be here */
-		break;
-	}
-
 out:
 	mutex_unlock(&coresight_mutex);
 	return ret;
@@ -1186,6 +1287,9 @@
 err_source:
 	coresight_disable_path(path);
 
+err_enable_path:
+	coresight_remove_path(csdev);
+
 err_path:
 	coresight_release_path(path);
 	goto out;
@@ -1194,9 +1298,8 @@
 
 void coresight_disable(struct coresight_device *csdev)
 {
-	int cpu, ret;
+	int ret;
 	struct list_head *path = NULL;
-	u32 hash;
 
 	mutex_lock(&coresight_mutex);
 
@@ -1204,31 +1307,12 @@
 	if (ret)
 		goto out;
 
-	if (!csdev->enable || !coresight_disable_source(csdev, NULL))
+	if (!csdev->enable || !coresight_disable_source_sysfs(csdev, NULL))
 		goto out;
 
-	switch (csdev->subtype.source_subtype) {
-	case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
-		cpu = source_ops(csdev)->cpu_id(csdev);
-		path = per_cpu(tracer_path, cpu);
-		per_cpu(tracer_path, cpu) = NULL;
-		break;
-	case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
-	case CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM:
-	case CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS:
-		hash = hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev)));
-		/* Find the path by the hash. */
-		path = idr_find(&path_idr, hash);
-		if (path == NULL) {
-			pr_err("Path is not found for %s\n", dev_name(&csdev->dev));
-			goto out;
-		}
-		idr_remove(&path_idr, hash);
-		break;
-	default:
-		/* We can't be here */
-		break;
-	}
+	path = coresight_remove_path(csdev);
+	if (!path)
+		goto out;
 
 	coresight_disable_path(path);
 	coresight_release_path(path);
@@ -1766,33 +1850,36 @@
  * duplicate indices for the same device (e.g, if we defer probing of
  * a device due to dependencies), in case the index is requested again.
  */
-char *coresight_alloc_device_name(struct coresight_dev_list *dict,
+const char *coresight_alloc_device_name(struct coresight_dev_list *dict,
 				  struct device *dev)
 {
 	int idx;
-	char *name = NULL;
+	const char *name = NULL;
 	struct fwnode_handle **list;
 
 	mutex_lock(&coresight_mutex);
 
-	idx = coresight_search_device_idx(dict, dev_fwnode(dev));
-	if (idx < 0) {
-		/* Make space for the new entry */
-		idx = dict->nr_idx;
-		list = krealloc_array(dict->fwnode_list,
-				      idx + 1, sizeof(*dict->fwnode_list),
-				      GFP_KERNEL);
-		if (ZERO_OR_NULL_PTR(list)) {
-			idx = -ENOMEM;
-			goto done;
+	name = coresight_get_device_name(dev);
+	if (!name) {
+		idx = coresight_search_device_idx(dict, dev_fwnode(dev));
+		if (idx < 0) {
+			/* Make space for the new entry */
+			idx = dict->nr_idx;
+			list = krealloc_array(dict->fwnode_list,
+					      idx + 1, sizeof(*dict->fwnode_list),
+					      GFP_KERNEL);
+			if (ZERO_OR_NULL_PTR(list)) {
+				idx = -ENOMEM;
+				goto done;
+			}
+
+			list[idx] = dev_fwnode(dev);
+			dict->fwnode_list = list;
+			dict->nr_idx = idx + 1;
 		}
 
-		list[idx] = dev_fwnode(dev);
-		dict->fwnode_list = list;
-		dict->nr_idx = idx + 1;
+		name = devm_kasprintf(dev, GFP_KERNEL, "%s%d", dict->pfx, idx);
 	}
-
-	name = devm_kasprintf(dev, GFP_KERNEL, "%s%d", dict->pfx, idx);
 done:
 	mutex_unlock(&coresight_mutex);
 	return name;
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-csr.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-csr.c
@@ -0,0 +1,1091 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2012-2013, 2015-2017, 2019-2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/coresight.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/of_platform.h>
+
+#include "coresight-priv.h"
+#include "coresight-common.h"
+#include "coresight-tmc.h"
+
+#define csr_writel(drvdata, val, off)	__raw_writel((val), drvdata->base + off)
+#define csr_readl(drvdata, off)		__raw_readl(drvdata->base + off)
+
+#define CSR_LOCK(drvdata)						\
+do {									\
+	mb(); /* ensure configuration take effect before we lock it */	\
+	csr_writel(drvdata, 0x0, CORESIGHT_LAR);			\
+} while (0)
+#define CSR_UNLOCK(drvdata)						\
+do {									\
+	csr_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR);		\
+	mb(); /* ensure unlock take effect before we configure */	\
+} while (0)
+
+#define CSR_SWDBGPWRCTRL	(0x000)
+#define CSR_SWDBGPWRACK		(0x004)
+#define CSR_SWSPADREG0		(0x008)
+#define CSR_SWSPADREG1		(0x00C)
+#define CSR_STMTRANSCTRL	(0x010)
+#define CSR_STMAWIDCTRL		(0x014)
+#define CSR_STMCHNOFST0		(0x018)
+#define CSR_STMCHNOFST1		(0x01C)
+#define CSR_STMEXTHWCTRL0	(0x020)
+#define CSR_STMEXTHWCTRL1	(0x024)
+#define CSR_STMEXTHWCTRL2	(0x028)
+#define CSR_STMEXTHWCTRL3	(0x02C)
+#define CSR_USBBAMCTRL		(0x030)
+#define CSR_USBFLSHCTRL		(0x034)
+#define CSR_TIMESTAMPCTRL	(0x038)
+#define CSR_AOTIMEVAL0		(0x03C)
+#define CSR_AOTIMEVAL1		(0x040)
+#define CSR_QDSSTIMEVAL0	(0x044)
+#define CSR_QDSSTIMEVAL1	(0x048)
+#define CSR_QDSSTIMELOAD0	(0x04C)
+#define CSR_QDSSTIMELOAD1	(0x050)
+#define CSR_DAPMSAVAL		(0x054)
+#define CSR_QDSSCLKVOTE		(0x058)
+#define CSR_QDSSCLKIPI		(0x05C)
+#define CSR_QDSSPWRREQIGNORE	(0x060)
+#define CSR_QDSSSPARE		(0x064)
+#define CSR_IPCAT		(0x068)
+#define CSR_BYTECNTVAL		(0x06C)
+#define CSR_TS_HBEAT_VAL0_LO	(0x084)
+#define CSR_TS_HBEAT_VAL0_HI	(0x088)
+#define CSR_TS_HBEAT_VAL1_LO	(0x08c)
+#define CSR_TS_HBEAT_VAL1_HI	(0x090)
+#define CSR_TS_HBEAT_MASK0_LO	(0x094)
+#define CSR_TS_HBEAT_MASK0_HI	(0x098)
+#define CSR_TS_HBEAT_MASK1_LO	(0x09c)
+#define CSR_TS_HBEAT_MASK1_HI	(0x0a0)
+#define CSR_ARADDR_EXT		(0x130)
+#define CSR_AWADDR_EXT		(0x134)
+#define MSR_NUM			((drvdata->msr_end - drvdata->msr_start + 1) \
+				/ sizeof(uint32_t))
+#define MSR_MAX_NUM		128
+
+#define BLKSIZE_256		0
+#define BLKSIZE_512		1
+#define BLKSIZE_1024		2
+#define BLKSIZE_2048		3
+
+#define FLUSHPERIOD_1	    0x1
+#define FLUSHPERIOD_2048	0x800
+#define PERFLSHEOT_BIT		BIT(18)
+
+#define CSR_ATID_REG_OFFSET(atid, atid_offset) \
+		((atid / 32) * 4 + atid_offset)
+
+#define CSR_ATID_REG_BIT(atid)	(atid % 32)
+#define CSR_MAX_ATID	128
+#define CSR_ATID_REG_SIZE	0xc
+
+#define CSR_ARADDR_EXT_VAL	0x104
+#define CSR_AWADDR_EXT_VAL	0x104
+
+#define CSR_ATID_REG_OFFSET(atid, atid_offset) \
+		((atid / 32) * 4 + atid_offset)
+
+#define CSR_ATID_REG_BIT(atid)	(atid % 32)
+#define CSR_MAX_ATID	128
+#define CSR_ATID_REG_SIZE	0xc
+
+struct csr_drvdata {
+	void __iomem		*base;
+	phys_addr_t		pbase;
+	phys_addr_t		msr_start;
+	phys_addr_t		msr_end;
+	struct device		*dev;
+	struct coresight_device	*csdev;
+	uint32_t		*msr;
+	atomic_t		*msr_refcnt;
+	uint32_t		blksize;
+	uint32_t		flushperiod;
+	u64			hbeat_val0;
+	u64			hbeat_val1;
+	u64			hbeat_mask0;
+	u64			hbeat_mask1;
+	struct coresight_csr		csr;
+	struct clk		*clk;
+	spinlock_t		spin_lock;
+	bool			usb_bam_support;
+	bool			perflsheot_set_support;
+	bool			hwctrl_set_support;
+	bool			set_byte_cntr_support;
+	bool			timestamp_support;
+	bool			enable_flush;
+	bool			msr_support;
+	uint32_t		atid_offset;
+};
+
+DEFINE_CORESIGHT_DEVLIST(csr_devs, "csr");
+
+static LIST_HEAD(csr_list);
+static DEFINE_SPINLOCK(csr_spinlock);
+
+#define to_csr_drvdata(c) container_of(c, struct csr_drvdata, csr)
+
+static void msm_qdss_csr_config_flush_period(struct csr_drvdata *drvdata)
+{
+	uint32_t usbflshctrl;
+
+	CSR_UNLOCK(drvdata);
+
+	usbflshctrl = csr_readl(drvdata, CSR_USBFLSHCTRL);
+	usbflshctrl = (usbflshctrl & ~0x3FFFC) | (drvdata->flushperiod << 2);
+	csr_writel(drvdata, usbflshctrl, CSR_USBFLSHCTRL);
+
+	CSR_LOCK(drvdata);
+}
+
+void msm_qdss_csr_enable_bam_to_usb(struct coresight_csr *csr)
+{
+	struct csr_drvdata *drvdata;
+	uint32_t usbbamctrl;
+	unsigned long flags;
+
+	if (csr == NULL)
+		return;
+
+	drvdata = to_csr_drvdata(csr);
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->usb_bam_support)
+		return;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+	CSR_UNLOCK(drvdata);
+
+	usbbamctrl = csr_readl(drvdata, CSR_USBBAMCTRL);
+	usbbamctrl = (usbbamctrl & ~0x3) | drvdata->blksize;
+	csr_writel(drvdata, usbbamctrl, CSR_USBBAMCTRL);
+
+	usbbamctrl |= 0x4;
+	csr_writel(drvdata, usbbamctrl, CSR_USBBAMCTRL);
+
+	CSR_LOCK(drvdata);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+}
+EXPORT_SYMBOL_GPL(msm_qdss_csr_enable_bam_to_usb);
+
+void msm_qdss_csr_enable_flush(struct coresight_csr *csr)
+{
+	struct csr_drvdata *drvdata;
+	uint32_t usbflshctrl;
+	unsigned long flags;
+
+	if (csr == NULL)
+		return;
+
+	drvdata = to_csr_drvdata(csr);
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->usb_bam_support)
+		return;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+
+	msm_qdss_csr_config_flush_period(drvdata);
+
+	CSR_UNLOCK(drvdata);
+
+	usbflshctrl = csr_readl(drvdata, CSR_USBFLSHCTRL);
+	usbflshctrl |= 0x2;
+	if (drvdata->perflsheot_set_support)
+		usbflshctrl |= PERFLSHEOT_BIT;
+	csr_writel(drvdata, usbflshctrl, CSR_USBFLSHCTRL);
+
+	CSR_LOCK(drvdata);
+	drvdata->enable_flush = true;
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+}
+EXPORT_SYMBOL_GPL(msm_qdss_csr_enable_flush);
+
+void msm_qdss_csr_disable_bam_to_usb(struct coresight_csr *csr)
+{
+	struct csr_drvdata *drvdata;
+	uint32_t usbbamctrl;
+	unsigned long flags;
+
+	if (csr == NULL)
+		return;
+
+	drvdata = to_csr_drvdata(csr);
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->usb_bam_support)
+		return;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+	CSR_UNLOCK(drvdata);
+
+	usbbamctrl = csr_readl(drvdata, CSR_USBBAMCTRL);
+	usbbamctrl &= (~0x4);
+	csr_writel(drvdata, usbbamctrl, CSR_USBBAMCTRL);
+
+	CSR_LOCK(drvdata);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+}
+EXPORT_SYMBOL_GPL(msm_qdss_csr_disable_bam_to_usb);
+
+void msm_qdss_csr_disable_flush(struct coresight_csr *csr)
+{
+	struct csr_drvdata *drvdata;
+	uint32_t usbflshctrl;
+	unsigned long flags;
+
+	if (csr == NULL)
+		return;
+
+	drvdata = to_csr_drvdata(csr);
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->usb_bam_support)
+		return;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+	CSR_UNLOCK(drvdata);
+
+	usbflshctrl = csr_readl(drvdata, CSR_USBFLSHCTRL);
+	usbflshctrl &= ~0x2;
+	if (drvdata->perflsheot_set_support)
+		usbflshctrl &= ~PERFLSHEOT_BIT;
+	csr_writel(drvdata, usbflshctrl, CSR_USBFLSHCTRL);
+
+	CSR_LOCK(drvdata);
+	drvdata->enable_flush = false;
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+}
+EXPORT_SYMBOL_GPL(msm_qdss_csr_disable_flush);
+
+void msm_qdss_csr_enable_eth(struct coresight_csr *csr)
+{
+	struct csr_drvdata *drvdata;
+	unsigned long flags;
+
+	if (csr == NULL)
+		return;
+
+	drvdata = to_csr_drvdata(csr);
+	if (IS_ERR_OR_NULL(drvdata))
+		return;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+	CSR_UNLOCK(drvdata);
+	csr_writel(drvdata, CSR_ARADDR_EXT_VAL, CSR_ARADDR_EXT);
+	csr_writel(drvdata, CSR_AWADDR_EXT_VAL, CSR_AWADDR_EXT);
+	CSR_LOCK(drvdata);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+}
+EXPORT_SYMBOL_GPL(msm_qdss_csr_enable_eth);
+
+void msm_qdss_csr_disable_eth(struct coresight_csr *csr)
+{
+	struct csr_drvdata *drvdata;
+	unsigned long flags;
+
+	if (csr == NULL)
+		return;
+
+	drvdata = to_csr_drvdata(csr);
+	if (IS_ERR_OR_NULL(drvdata))
+		return;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+	CSR_UNLOCK(drvdata);
+	csr_writel(drvdata, 0, CSR_ARADDR_EXT);
+	csr_writel(drvdata, 0, CSR_AWADDR_EXT);
+	CSR_LOCK(drvdata);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+}
+EXPORT_SYMBOL_GPL(msm_qdss_csr_disable_eth);
+
+int coresight_csr_hwctrl_set(struct coresight_csr *csr, uint64_t addr,
+			 uint32_t val)
+{
+	struct csr_drvdata *drvdata;
+	int ret = 0;
+	unsigned long flags;
+
+	if (csr == NULL)
+		return -EINVAL;
+
+	drvdata = to_csr_drvdata(csr);
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->hwctrl_set_support)
+		return -EINVAL;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+	CSR_UNLOCK(drvdata);
+
+	if (addr == (drvdata->pbase + CSR_STMEXTHWCTRL0))
+		csr_writel(drvdata, val, CSR_STMEXTHWCTRL0);
+	else if (addr == (drvdata->pbase + CSR_STMEXTHWCTRL1))
+		csr_writel(drvdata, val, CSR_STMEXTHWCTRL1);
+	else if (addr == (drvdata->pbase + CSR_STMEXTHWCTRL2))
+		csr_writel(drvdata, val, CSR_STMEXTHWCTRL2);
+	else if (addr == (drvdata->pbase + CSR_STMEXTHWCTRL3))
+		csr_writel(drvdata, val, CSR_STMEXTHWCTRL3);
+	else
+		ret = -EINVAL;
+
+	CSR_LOCK(drvdata);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(coresight_csr_hwctrl_set);
+
+void coresight_csr_set_byte_cntr(struct coresight_csr *csr, int irqctrl_offset, uint32_t count)
+{
+	struct csr_drvdata *drvdata;
+	unsigned long flags;
+
+	if (csr == NULL)
+		return;
+
+	drvdata = to_csr_drvdata(csr);
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->set_byte_cntr_support)
+		return;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+	CSR_UNLOCK(drvdata);
+
+	csr_writel(drvdata, count, irqctrl_offset);
+
+	/* make sure byte count value is written */
+	mb();
+
+	CSR_LOCK(drvdata);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+}
+EXPORT_SYMBOL_GPL(coresight_csr_set_byte_cntr);
+
+static int __coresight_csr_set_etr_atid(struct coresight_csr *csr,
+			uint32_t atid_offset, uint32_t atid,
+			bool enable)
+{
+	struct csr_drvdata *drvdata;
+	unsigned long flags;
+	uint32_t reg_offset;
+	int bit;
+	uint32_t val;
+
+	if (csr == NULL)
+		return -EINVAL;
+
+	drvdata = to_csr_drvdata(csr);
+	if (IS_ERR_OR_NULL(drvdata))
+		return -EINVAL;
+
+	if (atid < 0 || atid_offset <= 0)
+		return -EINVAL;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+	CSR_UNLOCK(drvdata);
+
+	reg_offset = CSR_ATID_REG_OFFSET(atid, atid_offset);
+	bit = CSR_ATID_REG_BIT(atid);
+	if (reg_offset - atid_offset > CSR_ATID_REG_SIZE
+		|| bit >= CSR_MAX_ATID) {
+		CSR_LOCK(drvdata);
+		spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+		return -EINVAL;
+	}
+
+	val = csr_readl(drvdata, reg_offset);
+	if (enable)
+		val = val | BIT(bit);
+	else
+		val = val & ~BIT(bit);
+	csr_writel(drvdata, val, reg_offset);
+
+	CSR_LOCK(drvdata);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+	return 0;
+}
+
+/*
+ * of_coresight_get_csr_atid_offset: Get the csr atid register offset of a sink device.
+ *
+ * Returns the csr atid offset. If the result is less than zero, it means
+ * failure.
+ */
+static int of_coresight_get_csr_atid_offset(struct coresight_device *csdev,
+				u32 *atid_offset)
+{
+	return of_property_read_u32(csdev->dev.parent->of_node,
+					"csr-atid-offset", atid_offset);
+}
+
+int coresight_csr_set_etr_atid(struct coresight_device *csdev, int atid, bool enable)
+{
+	struct list_head *path = NULL;
+	struct coresight_device *sink_csdev;
+	int atid_offset;
+	struct coresight_csr *csr;
+	const char *csr_name;
+	struct tmc_drvdata *drvdata;
+	unsigned long flags;
+
+	path = coresight_get_path(csdev);
+
+	if (!path)
+		return -EINVAL;
+
+	sink_csdev = coresight_get_sink(path);
+
+	if (!sink_csdev)
+		return -EINVAL;
+	/* if no csr for this sink, indicates this sink is not etr.*/
+	if (of_get_coresight_csr_name(sink_csdev->dev.parent->of_node, &csr_name))
+		return 0;
+
+	csr = coresight_csr_get(csr_name);
+
+	if (of_coresight_get_csr_atid_offset(sink_csdev, &atid_offset))
+		return -EINVAL;
+
+	drvdata = dev_get_drvdata(sink_csdev->dev.parent);
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+	if (enable && (++drvdata->atid_refcnt[atid] == 1)) {
+		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		return __coresight_csr_set_etr_atid(csr, atid_offset, atid, enable);
+	} else if (!enable && (--drvdata->atid_refcnt[atid] == 0)) {
+		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		return __coresight_csr_set_etr_atid(csr, atid_offset, atid, enable);
+	}
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(coresight_csr_set_etr_atid);
+
+struct coresight_csr *coresight_csr_get(const char *name)
+{
+	struct coresight_csr *csr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&csr_spinlock, flags);
+	list_for_each_entry(csr, &csr_list, link) {
+		if (!strcmp(csr->name, name)) {
+			spin_unlock_irqrestore(&csr_spinlock, flags);
+			return csr;
+		}
+	}
+
+	spin_unlock_irqrestore(&csr_spinlock, flags);
+	return ERR_PTR(-EINVAL);
+}
+EXPORT_SYMBOL_GPL(coresight_csr_get);
+
+int of_get_coresight_csr_name(struct device_node *node, const char **csr_name)
+{
+	struct device_node *csr_node;
+	struct csr_drvdata *drvdata;
+	struct platform_device *pdev;
+
+	csr_node = of_parse_phandle(node, "coresight-csr", 0);
+	if (!csr_node)
+		return -EINVAL;
+
+	pdev = of_find_device_by_node(csr_node);
+	if (!pdev)
+		return -EINVAL;
+
+	drvdata = platform_get_drvdata(pdev);
+	if (drvdata && drvdata->csr.name)
+		*csr_name = drvdata->csr.name;
+
+	of_node_put(csr_node);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_get_coresight_csr_name);
+
+static ssize_t timestamp_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	ssize_t size = 0;
+	uint64_t time_tick = 0;
+	uint32_t val, time_val0, time_val1;
+	int ret;
+	unsigned long flags;
+
+	struct csr_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->timestamp_support) {
+		dev_err(dev, "Invalid param\n");
+		return 0;
+	}
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+	CSR_UNLOCK(drvdata);
+
+	val = csr_readl(drvdata, CSR_TIMESTAMPCTRL);
+
+	val  = val & ~BIT(0);
+	csr_writel(drvdata, val, CSR_TIMESTAMPCTRL);
+
+	val  = val | BIT(0);
+	csr_writel(drvdata, val, CSR_TIMESTAMPCTRL);
+
+	time_val0 = csr_readl(drvdata, CSR_QDSSTIMEVAL0);
+	time_val1 = csr_readl(drvdata, CSR_QDSSTIMEVAL1);
+
+	CSR_LOCK(drvdata);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+
+	clk_disable_unprepare(drvdata->clk);
+
+	time_tick |= (uint64_t)time_val1 << 32;
+	time_tick |= (uint64_t)time_val0;
+	size = scnprintf(buf, PAGE_SIZE, "%llu\n", time_tick);
+	dev_dbg(dev, "timestamp : %s\n", buf);
+	return size;
+}
+
+static DEVICE_ATTR_RO(timestamp);
+
+static ssize_t msr_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	int i;
+	ssize_t len = 0;
+	struct csr_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->msr_support ||
+			IS_ERR_OR_NULL(drvdata->msr))
+		return -EINVAL;
+	for (i = 0; i < MSR_NUM; i++)
+		len += scnprintf(buf + len, PAGE_SIZE - len, "%d 0x%x\n",
+			i, drvdata->msr[i]);
+	return len;
+}
+
+static ssize_t msr_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf,
+				 size_t size)
+{
+	uint32_t offset, val, rval;
+	int nval, ret;
+	unsigned long flags;
+	struct csr_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->msr_support ||
+			IS_ERR_OR_NULL(drvdata->msr))
+		return -EINVAL;
+
+	nval = sscanf(buf, "%x %x", &offset, &val);
+	if (nval != 2)
+		return -EINVAL;
+	if (offset >= MSR_NUM)
+		return -EINVAL;
+
+	if (atomic_read(drvdata->msr_refcnt) == 0) {
+		ret = clk_prepare_enable(drvdata->clk);
+		if (ret)
+			return ret;
+		atomic_inc(drvdata->msr_refcnt);
+	}
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+	CSR_UNLOCK(drvdata);
+	csr_writel(drvdata, val, drvdata->msr_start + offset * 4);
+	rval = csr_readl(drvdata, drvdata->msr_start + offset * 4);
+	drvdata->msr[offset] = rval;
+	CSR_LOCK(drvdata);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+	return size;
+}
+
+static DEVICE_ATTR_RW(msr);
+
+static ssize_t msr_reset_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf,
+				 size_t size)
+{
+	unsigned long flags, val;
+	int i;
+	struct csr_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->msr_support ||
+			IS_ERR_OR_NULL(drvdata->msr))
+		return -EINVAL;
+
+	if (kstrtoul(buf, 0, &val) || val != 1)
+		return -EINVAL;
+
+	if (atomic_read(drvdata->msr_refcnt) == 0)
+		return -EINVAL;
+
+	atomic_set(drvdata->msr_refcnt, 0);
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+	CSR_UNLOCK(drvdata);
+	for (i = 0; i < MSR_NUM; i++) {
+		csr_writel(drvdata, 0, drvdata->msr_start + i * 4);
+		drvdata->msr[i] = 0;
+	}
+	CSR_LOCK(drvdata);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+	clk_disable_unprepare(drvdata->clk);
+	return size;
+}
+
+static DEVICE_ATTR_WO(msr_reset);
+
+static ssize_t flushperiod_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct csr_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->usb_bam_support) {
+		dev_err(dev, "Invalid param\n");
+		return -EINVAL;
+	}
+
+	return scnprintf(buf, PAGE_SIZE, "%#x\n", drvdata->flushperiod);
+}
+
+static ssize_t flushperiod_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf,
+				size_t size)
+{
+	unsigned long flags;
+	unsigned long val;
+	struct csr_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->usb_bam_support) {
+		dev_err(dev, "Invalid param\n");
+		return -EINVAL;
+	}
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+
+	if (kstrtoul(buf, 0, &val) || val > 0xffff) {
+		spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+		return -EINVAL;
+	}
+
+	if (drvdata->flushperiod == val)
+		goto out;
+
+	drvdata->flushperiod = val;
+
+	if (drvdata->enable_flush)
+		msm_qdss_csr_config_flush_period(drvdata);
+
+out:
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+	return size;
+}
+
+static DEVICE_ATTR_RW(flushperiod);
+
+static ssize_t hbeat_val0_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct csr_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->timestamp_support)
+		return -EINVAL;
+
+	return scnprintf(buf, PAGE_SIZE, "%llx\n", drvdata->hbeat_val0);
+}
+
+static ssize_t hbeat_val0_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf,
+				 size_t size)
+{
+	struct csr_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val, flags;
+	u32 val_lo, val_hi;
+	int ret;
+
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->timestamp_support)
+		return -EINVAL;
+
+	if (kstrtoul(buf, 16, &val))
+		return -EINVAL;
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+
+	drvdata->hbeat_val0 = val;
+	val_lo = val & 0xFFFFFFFF;
+	val_hi = val >> 32;
+
+	CSR_UNLOCK(drvdata);
+	csr_writel(drvdata, val_lo, CSR_TS_HBEAT_VAL0_LO);
+	csr_writel(drvdata, val_hi, CSR_TS_HBEAT_VAL0_HI);
+	CSR_LOCK(drvdata);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+	clk_disable_unprepare(drvdata->clk);
+	return size;
+}
+static DEVICE_ATTR_RW(hbeat_val0);
+
+static ssize_t hbeat_val1_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct csr_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->timestamp_support)
+		return -EINVAL;
+
+	return scnprintf(buf, PAGE_SIZE, "%llx\n", drvdata->hbeat_val1);
+}
+
+static ssize_t hbeat_val1_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf,
+				 size_t size)
+{
+	struct csr_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val, flags;
+	u32 val_lo, val_hi;
+	int ret;
+
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->timestamp_support)
+		return -EINVAL;
+
+	if (kstrtoul(buf, 16, &val))
+		return -EINVAL;
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+
+	drvdata->hbeat_val1 = val;
+	val_lo = val & 0xFFFFFFFF;
+	val_hi = val >> 32;
+
+	CSR_UNLOCK(drvdata);
+	csr_writel(drvdata, val_lo, CSR_TS_HBEAT_VAL1_LO);
+	csr_writel(drvdata, val_hi, CSR_TS_HBEAT_VAL1_HI);
+	CSR_LOCK(drvdata);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+	clk_disable_unprepare(drvdata->clk);
+	return size;
+}
+static DEVICE_ATTR_RW(hbeat_val1);
+
+static ssize_t hbeat_mask0_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct csr_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->timestamp_support)
+		return -EINVAL;
+
+	return scnprintf(buf, PAGE_SIZE, "%llx\n", drvdata->hbeat_mask0);
+}
+
+static ssize_t hbeat_mask0_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf,
+				 size_t size)
+{
+	struct csr_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val, flags;
+	u32 val_lo, val_hi;
+	int ret;
+
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->timestamp_support)
+		return -EINVAL;
+
+	if (kstrtoul(buf, 16, &val))
+		return -EINVAL;
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+
+	drvdata->hbeat_mask0 = val;
+	val_lo = val & 0xFFFFFFFF;
+	val_hi = val >> 32;
+
+	CSR_UNLOCK(drvdata);
+	csr_writel(drvdata, val_lo, CSR_TS_HBEAT_MASK0_LO);
+	csr_writel(drvdata, val_hi, CSR_TS_HBEAT_MASK0_HI);
+	CSR_LOCK(drvdata);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+	clk_disable_unprepare(drvdata->clk);
+	return size;
+}
+static DEVICE_ATTR_RW(hbeat_mask0);
+
+static ssize_t hbeat_mask1_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct csr_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->timestamp_support)
+		return -EINVAL;
+
+	return scnprintf(buf, PAGE_SIZE, "%llx\n", drvdata->hbeat_mask1);
+}
+
+static ssize_t hbeat_mask1_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf,
+				 size_t size)
+{
+	struct csr_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val, flags;
+	u32 val_lo, val_hi;
+	int ret;
+
+	if (IS_ERR_OR_NULL(drvdata) || !drvdata->timestamp_support)
+		return -EINVAL;
+
+	if (kstrtoul(buf, 16, &val))
+		return -EINVAL;
+
+	ret = clk_prepare_enable(drvdata->clk);
+	if (ret)
+		return ret;
+
+	spin_lock_irqsave(&drvdata->spin_lock, flags);
+
+	drvdata->hbeat_mask1 = val;
+	val_lo = val & 0xFFFFFFFF;
+	val_hi = val >> 32;
+
+	CSR_UNLOCK(drvdata);
+	csr_writel(drvdata, val_lo, CSR_TS_HBEAT_MASK1_LO);
+	csr_writel(drvdata, val_hi, CSR_TS_HBEAT_MASK1_HI);
+	CSR_LOCK(drvdata);
+	spin_unlock_irqrestore(&drvdata->spin_lock, flags);
+	clk_disable_unprepare(drvdata->clk);
+	return size;
+}
+static DEVICE_ATTR_RW(hbeat_mask1);
+
+static struct attribute *swao_csr_attrs[] = {
+	&dev_attr_timestamp.attr,
+	&dev_attr_msr.attr,
+	&dev_attr_msr_reset.attr,
+	&dev_attr_hbeat_val0.attr,
+	&dev_attr_hbeat_val1.attr,
+	&dev_attr_hbeat_mask0.attr,
+	&dev_attr_hbeat_mask1.attr,
+	NULL,
+};
+
+static struct attribute_group swao_csr_attr_grp = {
+	.attrs = swao_csr_attrs,
+};
+
+static const struct attribute_group *swao_csr_attr_grps[] = {
+	&swao_csr_attr_grp,
+	NULL,
+};
+
+static struct attribute *csr_attrs[] = {
+	&dev_attr_flushperiod.attr,
+	NULL,
+};
+
+static struct attribute_group csr_attr_grp = {
+	.attrs = csr_attrs,
+};
+
+static const struct attribute_group *csr_attr_grps[] = {
+	&csr_attr_grp,
+	NULL,
+};
+
+static int csr_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct device *dev = &pdev->dev;
+	struct coresight_platform_data *pdata;
+	struct csr_drvdata *drvdata;
+	struct resource *res, *msr_res;
+	struct coresight_desc desc = { 0 };
+
+	desc.name = coresight_alloc_device_name(&csr_devs, dev);
+	if (!desc.name)
+		return -ENOMEM;
+	pdata = coresight_get_platform_data(dev);
+	if (IS_ERR(pdata))
+		return PTR_ERR(pdata);
+	pdev->dev.platform_data = pdata;
+
+	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+	drvdata->dev = &pdev->dev;
+	platform_set_drvdata(pdev, drvdata);
+
+	drvdata->clk = devm_clk_get(dev, "apb_pclk");
+	if (IS_ERR(drvdata->clk))
+		dev_dbg(dev, "csr not config clk\n");
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr-base");
+	if (!res)
+		return -ENODEV;
+	drvdata->pbase = res->start;
+
+	drvdata->base = devm_ioremap(dev, res->start, resource_size(res));
+	if (!drvdata->base)
+		return -ENOMEM;
+
+	ret = of_property_read_u32(pdev->dev.of_node, "qcom,blk-size",
+			&drvdata->blksize);
+	if (ret)
+		drvdata->blksize = BLKSIZE_256;
+
+	drvdata->usb_bam_support = of_property_read_bool(pdev->dev.of_node,
+						"qcom,usb-bam-support");
+	if (!drvdata->usb_bam_support)
+		dev_dbg(dev, "usb_bam support handled by other subsystem\n");
+	else
+		dev_dbg(dev, "usb_bam operation supported\n");
+
+	drvdata->hwctrl_set_support = of_property_read_bool(pdev->dev.of_node,
+						"qcom,hwctrl-set-support");
+	if (!drvdata->hwctrl_set_support)
+		dev_dbg(dev, "hwctrl_set_support handled by other subsystem\n");
+	else
+		dev_dbg(dev, "hwctrl_set_support operation supported\n");
+
+	drvdata->set_byte_cntr_support = of_property_read_bool(
+			pdev->dev.of_node, "qcom,set-byte-cntr-support");
+	if (!drvdata->set_byte_cntr_support)
+		dev_dbg(dev, "set byte_cntr_support handled by other subsystem\n");
+	else
+		dev_dbg(dev, "set_byte_cntr_support operation supported\n");
+
+	drvdata->timestamp_support = of_property_read_bool(pdev->dev.of_node,
+						"qcom,timestamp-support");
+	if (!drvdata->timestamp_support)
+		dev_dbg(dev, "timestamp_support handled by other subsystem\n");
+	else
+		dev_dbg(dev, "timestamp_support operation supported\n");
+
+	drvdata->perflsheot_set_support = of_property_read_bool(
+			pdev->dev.of_node, "qcom,perflsheot-set-support");
+	if (!drvdata->perflsheot_set_support)
+		dev_dbg(dev, "perflsheot_set_support handled by other subsystem\n");
+	else
+		dev_dbg(dev, "perflsheot_set_support operation supported\n");
+
+	if (drvdata->usb_bam_support)
+		drvdata->flushperiod = FLUSHPERIOD_1;
+	drvdata->msr_support = of_property_read_bool(pdev->dev.of_node,
+						"qcom,msr-support");
+	if (!drvdata->msr_support) {
+		dev_dbg(dev, "msr_support handled by other subsystem\n");
+	} else {
+		msr_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+				"msr-base");
+		if (!msr_res || msr_res->start < res->start || msr_res->end
+		> res->end)
+			return -ENODEV;
+		drvdata->msr_start = msr_res->start - res->start;
+		drvdata->msr_end = msr_res->end - res->start;
+		drvdata->msr = devm_kzalloc(dev, MSR_NUM * sizeof(uint32_t),
+						GFP_KERNEL);
+		if (!drvdata->msr)
+			return -ENOMEM;
+
+		drvdata->msr_refcnt = devm_kzalloc(dev, sizeof(atomic_t),
+				GFP_KERNEL);
+		if (!drvdata->msr_refcnt)
+			return -ENOMEM;
+		atomic_set(drvdata->msr_refcnt, 0);
+		dev_dbg(dev, "msr_support operation supported\n");
+	}
+
+	desc.type = CORESIGHT_DEV_TYPE_HELPER;
+	desc.pdata = pdev->dev.platform_data;
+	desc.dev = &pdev->dev;
+	if (drvdata->timestamp_support || drvdata->msr_support)
+		desc.groups = swao_csr_attr_grps;
+	else if (drvdata->usb_bam_support)
+		desc.groups = csr_attr_grps;
+
+	drvdata->csdev = coresight_register(&desc);
+	if (IS_ERR(drvdata->csdev))
+		return PTR_ERR(drvdata->csdev);
+
+	/* Store the driver data pointer for use in exported functions */
+	spin_lock_init(&drvdata->spin_lock);
+	drvdata->csr.name = desc.name;
+
+	spin_lock(&csr_spinlock);
+	list_add_tail(&drvdata->csr.link, &csr_list);
+	spin_unlock(&csr_spinlock);
+
+	dev_info(dev, "CSR initialized: %s\n", drvdata->csr.name);
+	return 0;
+}
+
+static int csr_remove(struct platform_device *pdev)
+{
+	struct csr_drvdata *drvdata = platform_get_drvdata(pdev);
+
+	spin_lock(&csr_spinlock);
+	list_del(&drvdata->csr.link);
+	spin_unlock(&csr_spinlock);
+
+	coresight_unregister(drvdata->csdev);
+	return 0;
+}
+
+static const struct of_device_id csr_match[] = {
+	{.compatible = "qcom,coresight-csr"},
+	{}
+};
+
+static struct platform_driver csr_driver = {
+	.probe          = csr_probe,
+	.remove         = csr_remove,
+	.driver         = {
+		.name   = "coresight-csr",
+		.of_match_table = csr_match,
+		.suppress_bind_attrs = true,
+	},
+};
+
+static int __init csr_init(void)
+{
+	return platform_driver_register(&csr_driver);
+}
+module_init(csr_init);
+
+static void __exit csr_exit(void)
+{
+	platform_driver_unregister(&csr_driver);
+}
+module_exit(csr_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CoreSight CSR driver");
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-cti-core.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-cti-core.c
@@ -69,16 +69,29 @@
 	writel_relaxed(0, drvdata->base + CTICONTROL);
 
 	/* write the CTI trigger registers */
-	for (i = 0; i < config->nr_trig_max; i++) {
-		writel_relaxed(config->ctiinen[i], drvdata->base + CTIINEN(i));
-		writel_relaxed(config->ctiouten[i],
-			       drvdata->base + CTIOUTEN(i));
-	}
+	if (drvdata->extended_cti) {
+		for (i = 0; i < config->nr_trig_max; i++) {
+			writel_relaxed(config->ctiinen[i], drvdata->base + CTIINEN_EXTENDED(i));
+			writel_relaxed(config->ctiouten[i],
+				      drvdata->base + CTIOUTEN_EXTENDED(i));
+		}
 
-	/* other regs */
-	writel_relaxed(config->ctigate, drvdata->base + CTIGATE);
-	writel_relaxed(config->asicctl, drvdata->base + ASICCTL);
-	writel_relaxed(config->ctiappset, drvdata->base + CTIAPPSET);
+		/* other regs */
+		writel_relaxed(config->ctigate, drvdata->base + CTIGATE_EXTENDED);
+		writel_relaxed(config->asicctl, drvdata->base + ASICCTL_EXTENDED);
+		writel_relaxed(config->ctiappset, drvdata->base + CTIAPPSET_EXTENDED);
+	} else {
+		for (i = 0; i < config->nr_trig_max; i++) {
+			writel_relaxed(config->ctiinen[i], drvdata->base + CTIINEN(i));
+			writel_relaxed(config->ctiouten[i],
+					      drvdata->base + CTIOUTEN(i));
+		}
+
+		/* other regs */
+		writel_relaxed(config->ctigate, drvdata->base + CTIGATE);
+		writel_relaxed(config->asicctl, drvdata->base + ASICCTL);
+		writel_relaxed(config->ctiappset, drvdata->base + CTIAPPSET);
+	}
 
 	/* re-enable CTI */
 	writel_relaxed(1, drvdata->base + CTICONTROL);
@@ -99,10 +112,12 @@
 	if (config->hw_enabled || !config->hw_powered)
 		goto cti_state_unchanged;
 
-	/* claim the device */
-	rc = coresight_claim_device(drvdata->csdev);
-	if (rc)
-		goto cti_err_not_enabled;
+	if (!drvdata->extended_cti) {
+		/* claim the device */
+		rc = coresight_claim_device(drvdata->csdev);
+		if (rc)
+			goto cti_err_not_enabled;
+	}
 
 	cti_write_all_hw_regs(drvdata);
 
@@ -175,7 +190,8 @@
 	writel_relaxed(0, drvdata->base + CTICONTROL);
 	config->hw_enabled = false;
 
-	coresight_disclaim_device_unlocked(csdev);
+	if (!drvdata->extended_cti)
+		coresight_disclaim_device_unlocked(csdev);
 	CS_LOCK(drvdata->base);
 	spin_unlock(&drvdata->spinlock);
 	return ret;
@@ -270,8 +286,10 @@
 	cti_dev->nr_trig_con++;
 
 	/* add connection usage bit info to overall info */
-	drvdata->config.trig_in_use |= tc->con_in->used_mask;
-	drvdata->config.trig_out_use |= tc->con_out->used_mask;
+	bitmap_or(drvdata->config.trig_in_use, drvdata->config.trig_in_use,
+			tc->con_in->used_mask, drvdata->config.nr_trig_max);
+	bitmap_or(drvdata->config.trig_out_use, drvdata->config.trig_out_use,
+			tc->con_out->used_mask, drvdata->config.nr_trig_max);
 
 	return 0;
 }
@@ -314,7 +332,6 @@
 {
 	int ret = 0;
 	int n_trigs = drvdata->config.nr_trig_max;
-	u32 n_trig_mask = GENMASK(n_trigs - 1, 0);
 	struct cti_trig_con *tc = NULL;
 
 	/*
@@ -325,8 +342,8 @@
 	if (!tc)
 		return -ENOMEM;
 
-	tc->con_in->used_mask = n_trig_mask;
-	tc->con_out->used_mask = n_trig_mask;
+	bitmap_fill(tc->con_in->used_mask, n_trigs);
+	bitmap_fill(tc->con_out->used_mask, n_trigs);
 	ret = cti_add_connection_entry(dev, drvdata, tc, NULL, "default");
 	return ret;
 }
@@ -339,7 +356,6 @@
 {
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *config = &drvdata->config;
-	u32 trig_bitmask;
 	u32 chan_bitmask;
 	u32 reg_value;
 	int reg_offset;
@@ -349,25 +365,27 @@
 	   (trigger_idx >= config->nr_trig_max))
 		return -EINVAL;
 
-	trig_bitmask = BIT(trigger_idx);
-
 	/* ensure registered triggers and not out filtered */
 	if (direction == CTI_TRIG_IN)	{
-		if (!(trig_bitmask & config->trig_in_use))
+		if (!(test_bit(trigger_idx, config->trig_in_use)))
 			return -EINVAL;
 	} else {
-		if (!(trig_bitmask & config->trig_out_use))
+		if (!(test_bit(trigger_idx, config->trig_out_use)))
 			return -EINVAL;
 
 		if ((config->trig_filter_enable) &&
-		    (config->trig_out_filter & trig_bitmask))
+		    test_bit(trigger_idx, config->trig_out_filter))
 			return -EINVAL;
 	}
 
 	/* update the local register values */
 	chan_bitmask = BIT(channel_idx);
-	reg_offset = (direction == CTI_TRIG_IN ? CTIINEN(trigger_idx) :
-		      CTIOUTEN(trigger_idx));
+	if (drvdata->extended_cti)
+		reg_offset = (direction == CTI_TRIG_IN ? CTIINEN_EXTENDED(trigger_idx) :
+			      CTIOUTEN_EXTENDED(trigger_idx));
+	else
+		reg_offset = (direction == CTI_TRIG_IN ? CTIINEN(trigger_idx) :
+			      CTIOUTEN(trigger_idx));
 
 	spin_lock(&drvdata->spinlock);
 
@@ -423,8 +441,12 @@
 	}
 	if (err == 0) {
 		config->ctigate = reg_value;
-		if (cti_active(config))
-			cti_write_single_reg(drvdata, CTIGATE, reg_value);
+		if (cti_active(config)) {
+			if (drvdata->extended_cti)
+				cti_write_single_reg(drvdata, CTIGATE_EXTENDED, reg_value);
+			else
+				cti_write_single_reg(drvdata, CTIGATE, reg_value);
+		}
 	}
 	spin_unlock(&drvdata->spinlock);
 	return err;
@@ -451,19 +473,28 @@
 	case CTI_CHAN_SET:
 		config->ctiappset |= chan_bitmask;
 		reg_value  = config->ctiappset;
-		reg_offset = CTIAPPSET;
+		if (drvdata->extended_cti)
+			reg_offset = CTIAPPSET_EXTENDED;
+		else
+			reg_offset = CTIAPPSET;
 		break;
 
 	case CTI_CHAN_CLR:
 		config->ctiappset &= ~chan_bitmask;
 		reg_value = chan_bitmask;
-		reg_offset = CTIAPPCLEAR;
+		if (drvdata->extended_cti)
+			reg_offset = CTIAPPCLEAR_EXTENDED;
+		else
+			reg_offset = CTIAPPCLEAR;
 		break;
 
 	case CTI_CHAN_PULSE:
 		config->ctiappset &= ~chan_bitmask;
 		reg_value = chan_bitmask;
-		reg_offset = CTIAPPPULSE;
+		if (drvdata->extended_cti)
+			reg_offset = CTIAPPPULSE_EXTENDED;
+		else
+			reg_offset = CTIAPPPULSE;
 		break;
 
 	default:
@@ -857,6 +888,11 @@
 	coresight_unregister(drvdata->csdev);
 }
 
+static bool is_extended_cti(struct device *dev)
+{
+	return fwnode_property_present(dev->fwnode, "qcom,extended_cti");
+}
+
 static int cti_probe(struct amba_device *adev, const struct amba_id *id)
 {
 	int ret = 0;
@@ -948,6 +984,7 @@
 	drvdata->csdev_release = drvdata->csdev->dev.release;
 	drvdata->csdev->dev.release = cti_device_release;
 
+	drvdata->extended_cti = is_extended_cti(dev);
 	/* all done - dec pm refcount */
 	pm_runtime_put(&adev->dev);
 	dev_info(&drvdata->csdev->dev, "CTI initialized\n");
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-cti-platform.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-cti-platform.c
@@ -136,8 +136,8 @@
 		goto create_v8_etm_out;
 
 	/* build connection data */
-	tc->con_in->used_mask = 0xF0; /* sigs <4,5,6,7> */
-	tc->con_out->used_mask = 0xF0; /* sigs <4,5,6,7> */
+	bitmap_set(tc->con_in->used_mask, 4, 4); /* sigs <4,5,6,7> */
+	bitmap_set(tc->con_out->used_mask, 4, 4); /* sigs <4,5,6,7> */
 
 	/*
 	 * The EXTOUT type signals from the ETM are connected to a set of input
@@ -194,10 +194,10 @@
 		goto of_create_v8_out;
 
 	/* Set the v8 PE CTI connection data */
-	tc->con_in->used_mask = 0x3; /* sigs <0 1> */
+	bitmap_set(tc->con_in->used_mask, 0, 2); /* sigs <0 1> */
 	tc->con_in->sig_types[0] = PE_DBGTRIGGER;
 	tc->con_in->sig_types[1] = PE_PMUIRQ;
-	tc->con_out->used_mask = 0x7; /* sigs <0 1 2 > */
+	bitmap_set(tc->con_out->used_mask, 0, 3); /* sigs <0 1 2 > */
 	tc->con_out->sig_types[0] = PE_EDBGREQ;
 	tc->con_out->sig_types[1] = PE_DBGRESTART;
 	tc->con_out->sig_types[2] = PE_CTIIRQ;
@@ -213,7 +213,7 @@
 		goto of_create_v8_out;
 
 	/* filter pe_edbgreq - PE trigout sig <0> */
-	drvdata->config.trig_out_filter |= 0x1;
+	set_bit(0, drvdata->config.trig_out_filter);
 
 of_create_v8_out:
 	return ret;
@@ -257,7 +257,7 @@
 	if (!err) {
 		/* set the signal usage mask */
 		for (idx = 0; idx < tgrp->nr_sigs; idx++)
-			tgrp->used_mask |= BIT(values[idx]);
+			set_bit(values[idx], tgrp->used_mask);
 	}
 
 	kfree(values);
@@ -331,7 +331,9 @@
 
 	err = cti_plat_read_trig_group(tg, fwnode, CTI_DT_FILTER_OUT_SIGS);
 	if (!err)
-		drvdata->config.trig_out_filter |= tg->used_mask;
+		bitmap_or(drvdata->config.trig_out_filter,
+				drvdata->config.trig_out_filter,
+				tg->used_mask, drvdata->config.nr_trig_max);
 
 	kfree(tg);
 	return err;
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-cti-sysfs.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-cti-sysfs.c
@@ -251,60 +251,6 @@
 	NULL,
 };
 
-/* CTI low level programming registers */
-
-/*
- * Show a simple 32 bit value if enabled and powered.
- * If inaccessible & pcached_val not NULL then show cached value.
- */
-static ssize_t cti_reg32_show(struct device *dev, char *buf,
-			      u32 *pcached_val, int reg_offset)
-{
-	u32 val = 0;
-	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
-	struct cti_config *config = &drvdata->config;
-
-	spin_lock(&drvdata->spinlock);
-	if ((reg_offset >= 0) && cti_active(config)) {
-		CS_UNLOCK(drvdata->base);
-		val = readl_relaxed(drvdata->base + reg_offset);
-		if (pcached_val)
-			*pcached_val = val;
-		CS_LOCK(drvdata->base);
-	} else if (pcached_val) {
-		val = *pcached_val;
-	}
-	spin_unlock(&drvdata->spinlock);
-	return sprintf(buf, "%#x\n", val);
-}
-
-/*
- * Store a simple 32 bit value.
- * If pcached_val not NULL, then copy to here too,
- * if reg_offset >= 0 then write through if enabled.
- */
-static ssize_t cti_reg32_store(struct device *dev, const char *buf,
-			       size_t size, u32 *pcached_val, int reg_offset)
-{
-	unsigned long val;
-	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
-	struct cti_config *config = &drvdata->config;
-
-	if (kstrtoul(buf, 0, &val))
-		return -EINVAL;
-
-	spin_lock(&drvdata->spinlock);
-	/* local store */
-	if (pcached_val)
-		*pcached_val = (u32)val;
-
-	/* write through if offset and enabled */
-	if ((reg_offset >= 0) && cti_active(config))
-		cti_write_single_reg(drvdata, reg_offset, val);
-	spin_unlock(&drvdata->spinlock);
-	return size;
-}
-
 /* Standard macro for simple rw cti config registers */
 #define cti_config_reg32_rw(name, cfgname, offset)			\
 static ssize_t name##_show(struct device *dev,				\
@@ -388,8 +334,13 @@
 	config->ctiinen[index] = val;
 
 	/* write through if enabled */
-	if (cti_active(config))
-		cti_write_single_reg(drvdata, CTIINEN(index), val);
+	if (cti_active(config)) {
+		if (drvdata->extended_cti)
+			cti_write_single_reg(drvdata, CTIINEN_EXTENDED(index), val);
+		else
+			cti_write_single_reg(drvdata, CTIINEN(index), val);
+	}
+
 	spin_unlock(&drvdata->spinlock);
 	return size;
 }
@@ -427,8 +378,13 @@
 	config->ctiouten[index] = val;
 
 	/* write through if enabled */
-	if (cti_active(config))
-		cti_write_single_reg(drvdata, CTIOUTEN(index), val);
+	if (cti_active(config)) {
+		if (drvdata->extended_cti)
+			cti_write_single_reg(drvdata, CTIOUTEN_EXTENDED(index), val);
+		else
+			cti_write_single_reg(drvdata, CTIOUTEN(index), val);
+	}
+
 	spin_unlock(&drvdata->spinlock);
 	return size;
 }
@@ -448,9 +404,143 @@
 }
 static DEVICE_ATTR_WO(intack);
 
-cti_config_reg32_rw(gate, ctigate, CTIGATE);
-cti_config_reg32_rw(asicctl, asicctl, ASICCTL);
-cti_config_reg32_rw(appset, ctiappset, CTIAPPSET);
+static ssize_t gate_show(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	u32 val = 0;
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	struct cti_config *config = &drvdata->config;
+
+	spin_lock(&drvdata->spinlock);
+	if (cti_active(config)) {
+		CS_UNLOCK(drvdata->base);
+		if (drvdata->extended_cti)
+			val = readl_relaxed(drvdata->base + CTIGATE_EXTENDED);
+		else
+			val = readl_relaxed(drvdata->base + CTIGATE);
+		CS_LOCK(drvdata->base);
+	}
+	spin_unlock(&drvdata->spinlock);
+	return scnprintf(buf, PAGE_SIZE, "%#x\n", val);
+
+}
+
+static ssize_t gate_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t size)
+{
+	unsigned long val;
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	struct cti_config *config = &drvdata->config;
+
+	if (kstrtoul(buf, 0, &val))
+		return -EINVAL;
+
+	spin_lock(&drvdata->spinlock);
+	/* write through if offset and enabled */
+	if (cti_active(config)) {
+		if (drvdata->extended_cti)
+			cti_write_single_reg(drvdata, CTIGATE_EXTENDED, val);
+		else
+			cti_write_single_reg(drvdata, CTIGATE, val);
+	}
+	spin_unlock(&drvdata->spinlock);
+	return size;
+}
+static DEVICE_ATTR_RW(gate);
+
+static ssize_t asicctl_show(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	u32 val = 0;
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	struct cti_config *config = &drvdata->config;
+
+	spin_lock(&drvdata->spinlock);
+	if (cti_active(config)) {
+		CS_UNLOCK(drvdata->base);
+		if (drvdata->extended_cti)
+			val = readl_relaxed(drvdata->base + ASICCTL_EXTENDED);
+		else
+			val = readl_relaxed(drvdata->base + ASICCTL);
+		CS_LOCK(drvdata->base);
+	}
+	spin_unlock(&drvdata->spinlock);
+	return scnprintf(buf, PAGE_SIZE, "%#x\n", val);
+
+}
+
+static ssize_t asicctl_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t size)
+{
+	unsigned long val;
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	struct cti_config *config = &drvdata->config;
+
+	if (kstrtoul(buf, 0, &val))
+		return -EINVAL;
+
+	spin_lock(&drvdata->spinlock);
+	/* write through if offset and enabled */
+	if (cti_active(config)) {
+		if (drvdata->extended_cti)
+			cti_write_single_reg(drvdata, ASICCTL_EXTENDED, val);
+		else
+			cti_write_single_reg(drvdata, ASICCTL, val);
+	}
+	spin_unlock(&drvdata->spinlock);
+	return size;
+}
+static DEVICE_ATTR_RW(asicctl);
+
+static ssize_t appset_show(struct device *dev,
+			   struct device_attribute *attr,
+			   char *buf)
+{
+	u32 val = 0;
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	struct cti_config *config = &drvdata->config;
+
+	spin_lock(&drvdata->spinlock);
+	if (cti_active(config)) {
+		CS_UNLOCK(drvdata->base);
+		if (drvdata->extended_cti)
+			val = readl_relaxed(drvdata->base + CTIAPPSET_EXTENDED);
+		else
+			val = readl_relaxed(drvdata->base + CTIAPPSET);
+		CS_LOCK(drvdata->base);
+	}
+	spin_unlock(&drvdata->spinlock);
+	return scnprintf(buf, PAGE_SIZE, "%#x\n", val);
+
+}
+
+static ssize_t appset_store(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t size)
+{
+	unsigned long val;
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	struct cti_config *config = &drvdata->config;
+
+	if (kstrtoul(buf, 0, &val))
+		return -EINVAL;
+
+	spin_lock(&drvdata->spinlock);
+	/* write through if offset and enabled */
+	if (cti_active(config)) {
+		if (drvdata->extended_cti)
+			cti_write_single_reg(drvdata, CTIAPPSET_EXTENDED, val);
+		else
+			cti_write_single_reg(drvdata, CTIAPPSET, val);
+	}
+	spin_unlock(&drvdata->spinlock);
+	return size;
+}
+static DEVICE_ATTR_RW(appset);
 
 static ssize_t appclear_store(struct device *dev,
 			      struct device_attribute *attr,
@@ -469,8 +559,12 @@
 	config->ctiappset &= ~val;
 
 	/* write through if enabled */
-	if (cti_active(config))
-		cti_write_single_reg(drvdata, CTIAPPCLEAR, val);
+	if (cti_active(config)) {
+		if (drvdata->extended_cti)
+			cti_write_single_reg(drvdata, CTIAPPCLEAR, val);
+		else
+			cti_write_single_reg(drvdata, CTIAPPCLEAR_EXTENDED, val);
+	}
 	spin_unlock(&drvdata->spinlock);
 	return size;
 }
@@ -490,13 +584,147 @@
 	spin_lock(&drvdata->spinlock);
 
 	/* write through if enabled */
-	if (cti_active(config))
-		cti_write_single_reg(drvdata, CTIAPPPULSE, val);
+	if (cti_active(config)) {
+		if (drvdata->extended_cti)
+			cti_write_single_reg(drvdata, CTIAPPPULSE_EXTENDED, val);
+		else
+			cti_write_single_reg(drvdata, CTIAPPPULSE, val);
+	}
 	spin_unlock(&drvdata->spinlock);
 	return size;
 }
 static DEVICE_ATTR_WO(apppulse);
 
+static ssize_t triginstatus_show(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	struct cti_config *config = &drvdata->config;
+	u32 val = 0;
+	u32 n, i = 0;
+	ssize_t len = 0;
+	int ret;
+
+	ret = pm_runtime_get_sync(dev->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(dev->parent);
+		return ret;
+	}
+
+	spin_lock(&drvdata->spinlock);
+	if (drvdata->config.hw_powered) {
+		if (drvdata->extended_cti) {
+			i = (config->nr_trig_max - 1) / 32;
+			for (n = 0; n <= i; n++) {
+				val = readl_relaxed(drvdata->base + CTITRIGINSTATUS_EXTENDED(n));
+				len += scnprintf(buf + len, PAGE_SIZE - len, "%u - %u : 0x%x\n", n,
+							((n+1) * 32) - 1, val);
+			}
+		} else
+			val = readl_relaxed(drvdata->base + CTITRIGINSTATUS);
+	}
+	spin_unlock(&drvdata->spinlock);
+	pm_runtime_put_sync(dev->parent);
+
+	if (drvdata->extended_cti)
+		return len;
+	else
+		return scnprintf(buf, PAGE_SIZE, "0x%x\n", val);
+}
+static DEVICE_ATTR_RO(triginstatus);
+
+static ssize_t trigoutstatus_show(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	struct cti_config *config = &drvdata->config;
+	u32 val = 0;
+	u32 n, i = 0;
+	ssize_t len = 0;
+	int ret;
+
+	ret = pm_runtime_get_sync(dev->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(dev->parent);
+		return ret;
+	}
+
+	spin_lock(&drvdata->spinlock);
+	if (drvdata->config.hw_powered) {
+		if (drvdata->extended_cti) {
+			i = (config->nr_trig_max - 1) / 32;
+			for (n = 0; n <= i; n++) {
+				val = readl_relaxed(drvdata->base + CTITRIGOUTSTATUS_EXTENDED(n));
+				len += scnprintf(buf + len, PAGE_SIZE - len, "%u - %u : 0x%x\n", n,
+						((n+1) * 32) - 1,  val);
+			}
+		} else
+			val = readl_relaxed(drvdata->base + CTITRIGOUTSTATUS);
+	}
+	spin_unlock(&drvdata->spinlock);
+	pm_runtime_put_sync(dev->parent);
+
+	if (drvdata->extended_cti)
+		return len;
+	else
+		return scnprintf(buf, PAGE_SIZE, "0x%x\n", val);
+}
+static DEVICE_ATTR_RO(trigoutstatus);
+
+static ssize_t chinstatus_show(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	u32 val = 0;
+	int ret;
+
+	ret = pm_runtime_get_sync(dev->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(dev->parent);
+		return ret;
+	}
+
+	spin_lock(&drvdata->spinlock);
+	if (drvdata->config.hw_powered) {
+		if (drvdata->extended_cti)
+			val = readl_relaxed(drvdata->base + CTICHINSTATUS_EXTENDED);
+		else
+			val = readl_relaxed(drvdata->base + CTICHINSTATUS);
+	}
+	spin_unlock(&drvdata->spinlock);
+	pm_runtime_put_sync(dev->parent);
+
+	return scnprintf(buf, PAGE_SIZE, "0x%x\n", val);
+}
+static DEVICE_ATTR_RO(chinstatus);
+
+static ssize_t choutstatus_show(struct device *dev,
+			   struct device_attribute *attr, char *buf)
+{
+	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	u32 val = 0;
+	int ret;
+
+	ret = pm_runtime_get_sync(dev->parent);
+	if (ret < 0) {
+		pm_runtime_put_noidle(dev->parent);
+		return ret;
+	}
+
+	spin_lock(&drvdata->spinlock);
+	if (drvdata->config.hw_powered) {
+		if (drvdata->extended_cti)
+			val = readl_relaxed(drvdata->base + CTICHOUTSTATUS_EXTENDED);
+		else
+			val = readl_relaxed(drvdata->base + CTICHOUTSTATUS);
+	}
+	spin_unlock(&drvdata->spinlock);
+	pm_runtime_put_sync(dev->parent);
+
+	return scnprintf(buf, PAGE_SIZE, "0x%x\n", val);
+}
+static DEVICE_ATTR_RO(choutstatus);
+
 /*
  * Define CONFIG_CORESIGHT_CTI_INTEGRATION_REGS to enable the access to the
  * integration control registers. Normally only used to investigate connection
@@ -512,10 +740,10 @@
 	&dev_attr_appset.attr,
 	&dev_attr_appclear.attr,
 	&dev_attr_apppulse.attr,
-	coresight_cti_reg(triginstatus, CTITRIGINSTATUS),
-	coresight_cti_reg(trigoutstatus, CTITRIGOUTSTATUS),
-	coresight_cti_reg(chinstatus, CTICHINSTATUS),
-	coresight_cti_reg(choutstatus, CTICHOUTSTATUS),
+	&dev_attr_triginstatus.attr,
+	&dev_attr_trigoutstatus.attr,
+	&dev_attr_chinstatus.attr,
+	&dev_attr_choutstatus.attr,
 #ifdef CONFIG_CORESIGHT_CTI_INTEGRATION_REGS
 	coresight_cti_reg_rw(itctrl, CORESIGHT_ITCTRL),
 	coresight_cti_reg(ittrigin, ITTRIGIN),
@@ -711,10 +939,8 @@
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *cfg = &drvdata->config;
 	int size = 0, nr_trig_max = cfg->nr_trig_max;
-	unsigned long mask = cfg->trig_out_filter;
 
-	if (mask)
-		size = bitmap_print_to_pagebuf(true, buf, &mask, nr_trig_max);
+	size = bitmap_print_to_pagebuf(true, buf, cfg->trig_out_filter, nr_trig_max);
 	return size;
 }
 static DEVICE_ATTR_RO(trigout_filtered);
@@ -926,9 +1152,8 @@
 	struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *cfg = &drvdata->config;
-	unsigned long mask = con->con_in->used_mask;
 
-	return bitmap_print_to_pagebuf(true, buf, &mask, cfg->nr_trig_max);
+	return bitmap_print_to_pagebuf(true, buf, con->con_in->used_mask, cfg->nr_trig_max);
 }
 
 static ssize_t trigout_sig_show(struct device *dev,
@@ -940,9 +1165,8 @@
 	struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var;
 	struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct cti_config *cfg = &drvdata->config;
-	unsigned long mask = con->con_out->used_mask;
 
-	return bitmap_print_to_pagebuf(true, buf, &mask, cfg->nr_trig_max);
+	return bitmap_print_to_pagebuf(true, buf, con->con_out->used_mask, cfg->nr_trig_max);
 }
 
 /* convert a sig type id to a name */
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-cti.h
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-cti.h
@@ -37,6 +37,20 @@
 #define CTICHOUTSTATUS		0x13C
 #define CTIGATE			0x140
 #define ASICCTL			0x144
+
+#define CTIINTACK_EXTENDED(n)   (0x020 + (4 * n))
+#define CTIAPPSET_EXTENDED      0x004
+#define CTIAPPCLEAR_EXTENDED    0x008
+#define CTIAPPPULSE_EXTENDED    0x00C
+#define CTIINEN_EXTENDED(n)     (0x400 + (4 * n))
+#define CTIOUTEN_EXTENDED(n)    (0x800 + (4 * n))
+#define CTITRIGINSTATUS_EXTENDED(n)     (0x040 + (4 * n))
+#define CTITRIGOUTSTATUS_EXTENDED(n)    (0x060 + (4 * n))
+#define CTICHINSTATUS_EXTENDED  0x080
+#define CTICHOUTSTATUS_EXTENDED 0x084
+#define CTIGATE_EXTENDED        0x088
+#define ASICCTL_EXTENDED        0x08c
+
 /* Integration test registers */
 #define ITCHINACK		0xEDC /* WO CTI CSSoc 400 only*/
 #define ITTRIGINACK		0xEE0 /* WO CTI CSSoc 400 only*/
@@ -46,6 +60,16 @@
 #define ITTRIGOUTACK		0xEF0 /* RO CTI CSSoc 400 only*/
 #define ITCHIN			0xEF4 /* RO */
 #define ITTRIGIN		0xEF8 /* RO */
+
+#define ITCHINACK_EXTENDED		0xE70 /* WO CTI CSSoc 400 only*/
+#define ITTRIGINACK_EXTENDED(n)		(0xE80 + (4 * n)) /* WO CTI CSSoc 400 only*/
+#define ITCHOUT_EXTENDED		0xE74 /* WO RW-600 */
+#define ITTRIGOUT_EXTENDED(n)		(0xEA + (4 * n)) /* WO RW-600 */
+#define ITCHOUTACK_EXTENDED		0xE78 /* RO CTI CSSoc 400 only*/
+#define ITTRIGOUTACK_EXTENDED(n)	(0xEC0 + (4 * n)) /* RO CTI CSSoc 400 only*/
+#define ITCHIN_EXTENDED			0xE7C /* RO */
+#define ITTRIGIN_EXTENDED(n)		(0xEE0 + (4 * n)) /* RO */
+
 /* management registers */
 #define CTIDEVAFF0		0xFA8
 #define CTIDEVAFF1		0xFAC
@@ -56,7 +80,7 @@
  * Max of in and out defined in the DEVID register.
  * - pick up actual number used from .dts parameters if present.
  */
-#define CTIINOUTEN_MAX		32
+#define CTIINOUTEN_MAX		128
 
 /**
  * Group of related trigger signals
@@ -67,7 +91,7 @@
  */
 struct cti_trig_grp {
 	int nr_sigs;
-	u32 used_mask;
+	DECLARE_BITMAP(used_mask, CTIINOUTEN_MAX);
 	int sig_types[];
 };
 
@@ -146,9 +170,9 @@
 	bool hw_powered;
 
 	/* registered triggers and filtering */
-	u32 trig_in_use;
-	u32 trig_out_use;
-	u32 trig_out_filter;
+	DECLARE_BITMAP(trig_in_use, CTIINOUTEN_MAX);
+	DECLARE_BITMAP(trig_out_use, CTIINOUTEN_MAX);
+	DECLARE_BITMAP(trig_out_filter, CTIINOUTEN_MAX);
 	bool trig_filter_enable;
 	u8 xtrig_rchan_sel;
 
@@ -179,6 +203,7 @@
 	struct cti_config config;
 	struct list_head node;
 	void (*csdev_release)(struct device *dev);
+	bool	extended_cti;
 };
 
 /*
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-dummy.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-dummy.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/coresight.h>
@@ -11,10 +11,12 @@
 #include <linux/pm_runtime.h>
 
 #include "coresight-priv.h"
+#include "coresight-trace-id.h"
 
 struct dummy_drvdata {
 	struct device			*dev;
 	struct coresight_device		*csdev;
+	u8				traceid;
 };
 
 DEFINE_CORESIGHT_DEVLIST(source_devs, "dummy_source");
@@ -23,6 +25,9 @@
 static int dummy_source_enable(struct coresight_device *csdev,
 			       struct perf_event *event, enum cs_mode mode)
 {
+	if (!coresight_take_mode(csdev, mode))
+		return -EBUSY;
+
 	dev_dbg(csdev->dev.parent, "Dummy source enabled\n");
 
 	return 0;
@@ -31,6 +36,7 @@
 static void dummy_source_disable(struct coresight_device *csdev,
 				 struct perf_event *event)
 {
+	coresight_set_mode(csdev, CS_MODE_DISABLED);
 	dev_dbg(csdev->dev.parent, "Dummy source disabled\n");
 }
 
@@ -67,6 +73,32 @@
 	.sink_ops = &dummy_sink_ops,
 };
 
+/* User can get the trace id of dummy source from this node. */
+static ssize_t traceid_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	unsigned long val;
+	struct dummy_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	val = drvdata->traceid;
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
+}
+static DEVICE_ATTR_RO(traceid);
+
+static struct attribute *coresight_dummy_attrs[] = {
+	&dev_attr_traceid.attr,
+	NULL,
+};
+
+static const struct attribute_group coresight_dummy_group = {
+	.attrs = coresight_dummy_attrs,
+};
+
+static const struct attribute_group *coresight_dummy_groups[] = {
+	&coresight_dummy_group,
+	NULL,
+};
+
 static int dummy_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -74,6 +106,11 @@
 	struct coresight_platform_data *pdata;
 	struct dummy_drvdata *drvdata;
 	struct coresight_desc desc = { 0 };
+	int ret, trace_id;
+
+	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
 
 	if (of_device_is_compatible(node, "arm,coresight-dummy-source")) {
 
@@ -85,6 +122,25 @@
 		desc.subtype.source_subtype =
 					CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS;
 		desc.ops = &dummy_source_cs_ops;
+		desc.groups = coresight_dummy_groups;
+
+		ret = coresight_get_source_traceid(dev, &trace_id);
+		if (!ret) {
+			/* Get the preferred id if id is set in device tree. */
+			ret = coresight_trace_id_get_system_id(trace_id);
+			if (ret < 0)
+				return ret;
+
+		} else {
+			/* Get next available id if id is not set in device tree. */
+			trace_id = coresight_trace_id_get_system_id(TRACE_ID_ANY);
+			if (trace_id < 0) {
+				ret = trace_id;
+				return ret;
+			}
+		}
+		drvdata->traceid = (u8)trace_id;
+
 	} else if (of_device_is_compatible(node, "arm,coresight-dummy-sink")) {
 		desc.name = coresight_alloc_device_name(&sink_devs, dev);
 		if (!desc.name)
@@ -103,10 +159,6 @@
 		return PTR_ERR(pdata);
 	pdev->dev.platform_data = pdata;
 
-	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
-	if (!drvdata)
-		return -ENOMEM;
-
 	drvdata->dev = &pdev->dev;
 	platform_set_drvdata(pdev, drvdata);
 
@@ -126,7 +178,10 @@
 {
 	struct dummy_drvdata *drvdata = platform_get_drvdata(pdev);
 	struct device *dev = &pdev->dev;
+	struct device_node *node = dev->of_node;
 
+	if (of_device_is_compatible(node, "arm,coresight-dummy-source"))
+		coresight_trace_id_put_system_id(drvdata->traceid);
 	pm_runtime_disable(dev);
 	coresight_unregister(drvdata->csdev);
 }
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -589,7 +589,7 @@
 		return;
 
 	/* stop tracer */
-	source_ops(csdev)->disable(csdev, event);
+	coresight_disable_source(csdev, event);
 
 	/* tell the core */
 	event->hw.state = PERF_HES_STOPPED;
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-etm3x-core.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-etm3x-core.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Description: CoreSight Program Flow Trace driver
  */
@@ -33,6 +34,7 @@
 #include "coresight-etm.h"
 #include "coresight-etm-perf.h"
 #include "coresight-trace-id.h"
+#include "coresight-common.h"
 
 /*
  * Not really modular but using module_param is the easiest way to
@@ -484,7 +486,7 @@
 			   struct perf_event *event)
 {
 	struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	int trace_id;
+	int trace_id, ret = 0;
 
 	if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id()))
 		return -EINVAL;
@@ -508,8 +510,14 @@
 	}
 	drvdata->traceid = (u8)trace_id;
 
+	coresight_csr_set_etr_atid(csdev, drvdata->traceid, true);
+
 	/* And enable it */
-	return etm_enable_hw(drvdata);
+	ret = etm_enable_hw(drvdata);
+	if (ret)
+		coresight_csr_set_etr_atid(csdev, drvdata->traceid, false);
+
+	return ret;
 }
 
 static int etm_enable_sysfs(struct coresight_device *csdev)
@@ -525,6 +533,8 @@
 	if (ret < 0)
 		goto unlock_enable_sysfs;
 
+	coresight_csr_set_etr_atid(csdev, drvdata->traceid, true);
+
 	/*
 	 * Configure the ETM only if the CPU is online.  If it isn't online
 	 * hw configuration will take place on the local CPU during bring up.
@@ -541,8 +551,10 @@
 		ret = -ENODEV;
 	}
 
-	if (ret)
+	if (ret) {
+		coresight_csr_set_etr_atid(csdev, drvdata->traceid, false);
 		etm_release_trace_id(drvdata);
+	}
 
 unlock_enable_sysfs:
 	spin_unlock(&drvdata->spinlock);
@@ -695,6 +707,8 @@
 		return;
 	}
 
+	coresight_csr_set_etr_atid(csdev, drvdata->traceid, false);
+
 	if (mode)
 		local_set(&drvdata->mode, CS_MODE_DISABLED);
 }
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-etm4x-core.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-etm4x-core.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/acpi.h>
@@ -45,6 +46,7 @@
 #include "coresight-self-hosted-trace.h"
 #include "coresight-syscfg.h"
 #include "coresight-trace-id.h"
+#include "coresight-common.h"
 
 static int boot_enable;
 module_param(boot_enable, int, 0444);
@@ -784,8 +786,12 @@
 	}
 	drvdata->trcid = (u8)trace_id;
 
+	coresight_csr_set_etr_atid(csdev, drvdata->trcid, true);
+
 	/* And enable it */
 	ret = etm4_enable_hw(drvdata);
+	if (ret)
+		coresight_csr_set_etr_atid(csdev, drvdata->trcid, false);
 
 out:
 	return ret;
@@ -813,6 +819,8 @@
 	if (ret < 0)
 		goto unlock_sysfs_enable;
 
+	coresight_csr_set_etr_atid(csdev, drvdata->trcid, true);
+
 	/*
 	 * Executing etm4_enable_hw on the cpu whose ETM is being enabled
 	 * ensures that register writes occur when cpu is powered.
@@ -825,8 +833,10 @@
 	if (!ret)
 		drvdata->sticky_enable = true;
 
-	if (ret)
+	if (ret) {
+		coresight_csr_set_etr_atid(csdev, drvdata->trcid, false);
 		etm4_release_trace_id(drvdata);
+	}
 
 unlock_sysfs_enable:
 	spin_unlock(&drvdata->spinlock);
@@ -1024,6 +1034,8 @@
 		break;
 	}
 
+	coresight_csr_set_etr_atid(csdev, drvdata->trcid, false);
+
 	if (mode)
 		local_set(&drvdata->mode, CS_MODE_DISABLED);
 }
@@ -1200,6 +1212,7 @@
 	struct etm4_init_arg *init_arg = info;
 	struct etmv4_drvdata *drvdata;
 	struct csdev_access *csa;
+	struct device *dev = init_arg->dev;
 	int i;
 
 	drvdata = dev_get_drvdata(init_arg->dev);
@@ -1213,6 +1226,10 @@
 	if (!etm4_init_csdev_access(drvdata, csa))
 		return;
 
+	if (!csa->io_mem ||
+	    fwnode_property_present(dev_fwnode(dev), "qcom,skip-power-up"))
+		drvdata->skip_power_up = true;
+
 	/* Detect the support for OS Lock before we actually use it */
 	etm_detect_os_lock(drvdata, csa);
 
@@ -1239,6 +1256,8 @@
 	drvdata->nr_event = FIELD_GET(TRCIDR0_NUMEVENT_MASK, etmidr0);
 	/* QSUPP, bits[16:15] Q element support field */
 	drvdata->q_support = FIELD_GET(TRCIDR0_QSUPP_MASK, etmidr0);
+	if (drvdata->q_support)
+		drvdata->q_filt = !!(etmidr0 & TRCIDR0_QFILT);
 	/* TSSIZE, bits[28:24] Global timestamp size field */
 	drvdata->ts_size = FIELD_GET(TRCIDR0_TSSIZE_MASK, etmidr0);
 
@@ -1731,16 +1750,14 @@
 	state->trcccctlr = etm4x_read32(csa, TRCCCCTLR);
 	state->trcbbctlr = etm4x_read32(csa, TRCBBCTLR);
 	state->trctraceidr = etm4x_read32(csa, TRCTRACEIDR);
-	state->trcqctlr = etm4x_read32(csa, TRCQCTLR);
+	if (drvdata->q_filt)
+		state->trcqctlr = etm4x_read32(csa, TRCQCTLR);
 
 	state->trcvictlr = etm4x_read32(csa, TRCVICTLR);
 	state->trcviiectlr = etm4x_read32(csa, TRCVIIECTLR);
 	state->trcvissctlr = etm4x_read32(csa, TRCVISSCTLR);
 	if (drvdata->nr_pe_cmp)
 		state->trcvipcssctlr = etm4x_read32(csa, TRCVIPCSSCTLR);
-	state->trcvdctlr = etm4x_read32(csa, TRCVDCTLR);
-	state->trcvdsacctlr = etm4x_read32(csa, TRCVDSACCTLR);
-	state->trcvdarcctlr = etm4x_read32(csa, TRCVDARCCTLR);
 
 	for (i = 0; i < drvdata->nrseqstate - 1; i++)
 		state->trcseqevr[i] = etm4x_read32(csa, TRCSEQEVRn(i));
@@ -1757,7 +1774,8 @@
 		state->trccntvr[i] = etm4x_read32(csa, TRCCNTVRn(i));
 	}
 
-	for (i = 0; i < drvdata->nr_resource * 2; i++)
+	/* Resource selector pair 0 is reserved */
+	for (i = 2; i < drvdata->nr_resource * 2; i++)
 		state->trcrsctlr[i] = etm4x_read32(csa, TRCRSCTLRn(i));
 
 	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
@@ -1842,8 +1860,10 @@
 {
 	int i;
 	struct etmv4_save_state *state = drvdata->save_state;
-	struct csdev_access tmp_csa = CSDEV_ACCESS_IOMEM(drvdata->base);
-	struct csdev_access *csa = &tmp_csa;
+	struct csdev_access *csa = &drvdata->csdev->access;
+
+	if (WARN_ON(!drvdata->csdev))
+		return;
 
 	etm4_cs_unlock(drvdata, csa);
 	etm4x_relaxed_write32(csa, state->trcclaimset, TRCCLAIMSET);
@@ -1862,16 +1882,14 @@
 	etm4x_relaxed_write32(csa, state->trcccctlr, TRCCCCTLR);
 	etm4x_relaxed_write32(csa, state->trcbbctlr, TRCBBCTLR);
 	etm4x_relaxed_write32(csa, state->trctraceidr, TRCTRACEIDR);
-	etm4x_relaxed_write32(csa, state->trcqctlr, TRCQCTLR);
+	if (drvdata->q_filt)
+		etm4x_relaxed_write32(csa, state->trcqctlr, TRCQCTLR);
 
 	etm4x_relaxed_write32(csa, state->trcvictlr, TRCVICTLR);
 	etm4x_relaxed_write32(csa, state->trcviiectlr, TRCVIIECTLR);
 	etm4x_relaxed_write32(csa, state->trcvissctlr, TRCVISSCTLR);
 	if (drvdata->nr_pe_cmp)
 		etm4x_relaxed_write32(csa, state->trcvipcssctlr, TRCVIPCSSCTLR);
-	etm4x_relaxed_write32(csa, state->trcvdctlr, TRCVDCTLR);
-	etm4x_relaxed_write32(csa, state->trcvdsacctlr, TRCVDSACCTLR);
-	etm4x_relaxed_write32(csa, state->trcvdarcctlr, TRCVDARCCTLR);
 
 	for (i = 0; i < drvdata->nrseqstate - 1; i++)
 		etm4x_relaxed_write32(csa, state->trcseqevr[i], TRCSEQEVRn(i));
@@ -1888,7 +1906,8 @@
 		etm4x_relaxed_write32(csa, state->trccntvr[i], TRCCNTVRn(i));
 	}
 
-	for (i = 0; i < drvdata->nr_resource * 2; i++)
+	/* Resource selector pair 0 is reserved */
+	for (i = 2; i < drvdata->nr_resource * 2; i++)
 		etm4x_relaxed_write32(csa, state->trcrsctlr[i], TRCRSCTLRn(i));
 
 	for (i = 0; i < drvdata->nr_ss_cmp; i++) {
@@ -2040,11 +2059,6 @@
 	if (!drvdata->arch)
 		return -EINVAL;
 
-	/* TRCPDCR is not accessible with system instructions. */
-	if (!desc.access.io_mem ||
-	    fwnode_property_present(dev_fwnode(dev), "qcom,skip-power-up"))
-		drvdata->skip_power_up = true;
-
 	major = ETM_ARCH_MAJOR_VERSION(drvdata->arch);
 	minor = ETM_ARCH_MINOR_VERSION(drvdata->arch);
 
@@ -2217,6 +2231,9 @@
 	ret = etm4_probe(&pdev->dev);
 
 	pm_runtime_put(&pdev->dev);
+	if (ret)
+		pm_runtime_disable(&pdev->dev);
+
 	return ret;
 }
 
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-etm4x.h
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-etm4x.h
@@ -43,9 +43,6 @@
 #define TRCVIIECTLR			0x084
 #define TRCVISSCTLR			0x088
 #define TRCVIPCSSCTLR			0x08C
-#define TRCVDCTLR			0x0A0
-#define TRCVDSACCTLR			0x0A4
-#define TRCVDARCCTLR			0x0A8
 /* Derived resources registers */
 #define TRCSEQEVRn(n)			(0x100 + (n * 4)) /* n = 0-2 */
 #define TRCSEQRSTEVR			0x118
@@ -90,9 +87,6 @@
 /* Address Comparator registers n = 0-15 */
 #define TRCACVRn(n)			(0x400 + (n * 8))
 #define TRCACATRn(n)			(0x480 + (n * 8))
-/* Data Value Comparator Value registers, n = 0-7 */
-#define TRCDVCVRn(n)			(0x500 + (n * 16))
-#define TRCDVCMRn(n)			(0x580 + (n * 16))
 /* ContextID/Virtual ContextID comparators, n = 0-7 */
 #define TRCCIDCVRn(n)			(0x600 + (n * 8))
 #define TRCVMIDCVRn(n)			(0x640 + (n * 8))
@@ -141,6 +135,7 @@
 #define TRCIDR0_TRCCCI				BIT(7)
 #define TRCIDR0_RETSTACK			BIT(9)
 #define TRCIDR0_NUMEVENT_MASK			GENMASK(11, 10)
+#define TRCIDR0_QFILT				BIT(14)
 #define TRCIDR0_QSUPP_MASK			GENMASK(16, 15)
 #define TRCIDR0_TSSIZE_MASK			GENMASK(28, 24)
 
@@ -272,9 +267,6 @@
 /* List of registers accessible via System instructions */
 #define ETM4x_ONLY_SYSREG_LIST(op, val)		\
 	CASE_##op((val), TRCPROCSELR)		\
-	CASE_##op((val), TRCVDCTLR)		\
-	CASE_##op((val), TRCVDSACCTLR)		\
-	CASE_##op((val), TRCVDARCCTLR)		\
 	CASE_##op((val), TRCOSLAR)
 
 #define ETM_COMMON_SYSREG_LIST(op, val)		\
@@ -422,22 +414,6 @@
 	CASE_##op((val), TRCACATRn(13))		\
 	CASE_##op((val), TRCACATRn(14))		\
 	CASE_##op((val), TRCACATRn(15))		\
-	CASE_##op((val), TRCDVCVRn(0))		\
-	CASE_##op((val), TRCDVCVRn(1))		\
-	CASE_##op((val), TRCDVCVRn(2))		\
-	CASE_##op((val), TRCDVCVRn(3))		\
-	CASE_##op((val), TRCDVCVRn(4))		\
-	CASE_##op((val), TRCDVCVRn(5))		\
-	CASE_##op((val), TRCDVCVRn(6))		\
-	CASE_##op((val), TRCDVCVRn(7))		\
-	CASE_##op((val), TRCDVCMRn(0))		\
-	CASE_##op((val), TRCDVCMRn(1))		\
-	CASE_##op((val), TRCDVCMRn(2))		\
-	CASE_##op((val), TRCDVCMRn(3))		\
-	CASE_##op((val), TRCDVCMRn(4))		\
-	CASE_##op((val), TRCDVCMRn(5))		\
-	CASE_##op((val), TRCDVCMRn(6))		\
-	CASE_##op((val), TRCDVCMRn(7))		\
 	CASE_##op((val), TRCCIDCVRn(0))		\
 	CASE_##op((val), TRCCIDCVRn(1))		\
 	CASE_##op((val), TRCCIDCVRn(2))		\
@@ -907,9 +883,6 @@
 	u32	trcviiectlr;
 	u32	trcvissctlr;
 	u32	trcvipcssctlr;
-	u32	trcvdctlr;
-	u32	trcvdsacctlr;
-	u32	trcvdarcctlr;
 
 	u32	trcseqevr[ETM_MAX_SEQ_STATES];
 	u32	trcseqrstevr;
@@ -982,6 +955,7 @@
  * @os_unlock:  True if access to management registers is allowed.
  * @instrp0:	Tracing of load and store instructions
  *		as P0 elements is supported.
+ * @q_filt:	Q element filtering support, if Q elements are supported.
  * @trcbb:	Indicates if the trace unit supports branch broadcast tracing.
  * @trccond:	If the trace unit supports conditional
  *		instruction tracing.
@@ -1045,6 +1019,7 @@
 	bool				boot_enable;
 	bool				os_unlock;
 	bool				instrp0;
+	bool				q_filt;
 	bool				trcbb;
 	bool				trccond;
 	bool				retstack;
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-funnel.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-funnel.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2012, 2017, The Linux Foundation. All rights reserved.
  *
  * Description: CoreSight Funnel driver
  */
@@ -19,6 +19,7 @@
 #include <linux/coresight.h>
 #include <linux/amba/bus.h>
 #include <linux/clk.h>
+#include <linux/of_address.h>
 
 #include "coresight-priv.h"
 
@@ -209,13 +210,38 @@
 };
 ATTRIBUTE_GROUPS(coresight_funnel);
 
+static int funnel_get_resource_byname(struct device_node *np,
+				   char *ch_base, struct resource *res)
+{
+	const char *name = NULL;
+	int index = 0, found = 0;
+
+	while (!of_property_read_string_index(np, "reg-names", index, &name)) {
+		if (strcmp(ch_base, name)) {
+			index++;
+			continue;
+		}
+
+		/* We have a match and @index is where it's at */
+		found = 1;
+		break;
+	}
+
+	if (!found)
+		return -EINVAL;
+
+	return of_address_to_resource(np, index, res);
+}
+
 static int funnel_probe(struct device *dev, struct resource *res)
 {
 	int ret;
 	void __iomem *base;
 	struct coresight_platform_data *pdata = NULL;
 	struct funnel_drvdata *drvdata;
+	struct resource res_real;
 	struct coresight_desc desc = { 0 };
+	struct device_node *np = dev->of_node;
 
 	if (is_of_node(dev_fwnode(dev)) &&
 	    of_device_is_compatible(dev->of_node, "arm,coresight-funnel"))
@@ -236,11 +262,26 @@
 			return ret;
 	}
 
-	/*
-	 * Map the device base for dynamic-funnel, which has been
-	 * validated by AMBA core.
-	 */
-	if (res) {
+	if (of_property_read_bool(np, "qcom,duplicate-funnel")) {
+		ret = funnel_get_resource_byname(np, "funnel-base-real",
+						 &res_real);
+		if (ret)
+			return ret;
+
+		res = &res_real;
+		base = devm_ioremap(dev, res->start, resource_size(res));
+		if (IS_ERR(base)) {
+			ret = PTR_ERR(base);
+			goto out_disable_clk;
+		}
+		drvdata->base = base;
+		desc.groups = coresight_funnel_groups;
+		desc.access = CSDEV_ACCESS_IOMEM(base);
+	} else if (res) {
+		/*
+		 * Map the device base for dynamic-funnel, which has been
+		 * validated by AMBA core.
+		 */
 		base = devm_ioremap_resource(dev, res);
 		if (IS_ERR(base)) {
 			ret = PTR_ERR(base);
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-platform.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-platform.c
@@ -184,6 +184,33 @@
 }
 
 /*
+ * of_coresight_get_trace_id: Get the atid of a source device.
+ *
+ * Returns 0 on success.
+ */
+static int of_coresight_get_trace_id(struct device *dev, u32 *id)
+{
+
+	return of_property_read_u32(dev->of_node, "arm,trace-id", id);
+}
+
+static const char *of_coresight_get_device_name(struct device *dev)
+{
+	const char *name = NULL;
+
+	if (!dev->of_node)
+		return NULL;
+
+	/*
+	 * Get the device name from DT. The name describes the HW or
+	 * system the device is for.
+	 */
+	of_property_read_string(dev->of_node, "device-name", &name);
+
+	return name;
+}
+
+/*
  * of_coresight_parse_endpoint : Parse the given output endpoint @ep
  * and fill the connection information in @pdata->out_conns
  *
@@ -297,8 +324,10 @@
 			continue;
 
 		ret = of_coresight_parse_endpoint(dev, ep, pdata);
-		if (ret)
+		if (ret) {
+			of_node_put(ep);
 			return ret;
+		}
 	}
 
 	return 0;
@@ -315,6 +344,17 @@
 {
 	return -ENODEV;
 }
+
+static inline int of_coresight_get_trace_id(struct device *dev, u32 *id)
+{
+	return -ENODEV;
+}
+
+static inline const char *of_coresight_get_device_name(struct device *dev)
+{
+	return NULL;
+}
+
 #endif
 
 #ifdef CONFIG_ACPI
@@ -794,6 +834,24 @@
 }
 EXPORT_SYMBOL_GPL(coresight_get_cpu);
 
+int coresight_get_source_traceid(struct device *dev, u32 *id)
+{
+	if (!is_of_node(dev->fwnode))
+		return -EINVAL;
+
+	return of_coresight_get_trace_id(dev, id);
+}
+EXPORT_SYMBOL_GPL(coresight_get_source_traceid);
+
+const char *coresight_get_device_name(struct device *dev)
+{
+	if (is_of_node(dev->fwnode))
+		return of_coresight_get_device_name(dev);
+	else
+		return NULL;
+}
+EXPORT_SYMBOL_GPL(coresight_get_device_name);
+
 struct coresight_platform_data *
 coresight_get_platform_data(struct device *dev)
 {
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-priv.h
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-priv.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CORESIGHT_PRIV_H
@@ -132,6 +133,7 @@
 struct coresight_device *coresight_get_sink(struct list_head *path);
 struct coresight_device *
 coresight_get_enabled_sink(struct coresight_device *source);
+struct list_head *coresight_get_path(struct coresight_device *csdev);
 struct coresight_device *coresight_get_sink_by_id(u32 id);
 struct coresight_device *
 coresight_find_default_sink(struct coresight_device *csdev);
@@ -233,6 +235,6 @@
 struct coresight_device *coresight_get_percpu_sink(int cpu);
 int coresight_enable_source(struct coresight_device *csdev, enum cs_mode mode,
 			    void *data);
-bool coresight_disable_source(struct coresight_device *csdev, void *data);
+void coresight_disable_source(struct coresight_device *csdev, void *data);
 
 #endif
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-qmi.h
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-qmi.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _CORESIGHT_QMI_H
+#define _CORESIGHT_QMI_H
+
+#include <linux/soc/qcom/qmi.h>
+
+#define CORESIGHT_QMI_SVC_ID			(0x33)
+#define CORESIGHT_QMI_VERSION			(1)
+
+#define CORESIGHT_QMI_GET_ETM_REQ_V01		(0x002B)
+#define CORESIGHT_QMI_GET_ETM_RESP_V01		(0x002B)
+#define CORESIGHT_QMI_SET_ETM_REQ_V01		(0x002C)
+#define CORESIGHT_QMI_SET_ETM_RESP_V01		(0x002C)
+
+#define CORESIGHT_QMI_GET_ETM_REQ_MAX_LEN	(0)
+#define CORESIGHT_QMI_GET_ETM_RESP_MAX_LEN	(14)
+#define CORESIGHT_QMI_SET_ETM_REQ_MAX_LEN	(7)
+#define CORESIGHT_QMI_SET_ETM_RESP_MAX_LEN	(7)
+
+#define TIMEOUT_MS				(10000)
+
+enum coresight_etm_state_enum_type_v01 {
+	/* To force a 32 bit signed enum. Do not change or use */
+	CORESIGHT_ETM_STATE_ENUM_TYPE_MIN_ENUM_VAL_V01 = INT_MIN,
+	CORESIGHT_ETM_STATE_DISABLED_V01 = 0,
+	CORESIGHT_ETM_STATE_ENABLED_V01 = 1,
+	CORESIGHT_ETM_STATE_ENUM_TYPE_MAX_ENUM_VAL_01 = INT_MAX,
+};
+
+struct coresight_get_etm_req_msg_v01 {
+	/*
+	 * This element is a placeholder to prevent declaration of
+	 * empty struct. Do not change.
+	 */
+	char __placeholder;
+};
+
+struct coresight_get_etm_resp_msg_v01 {
+	/* Mandatory */
+	/* QMI result Code */
+	struct qmi_response_type_v01 resp;
+
+	/* Optional */
+	/* ETM output state, must be set to true if state is being passed */
+	uint8_t state_valid;
+	/* Present when result code is QMI_RESULT_SUCCESS */
+	enum coresight_etm_state_enum_type_v01 state;
+};
+
+struct coresight_set_etm_req_msg_v01 {
+	/* Mandatory */
+	/* ETM output state */
+	enum coresight_etm_state_enum_type_v01 state;
+};
+
+struct coresight_set_etm_resp_msg_v01 {
+	/* Mandatory */
+	struct qmi_response_type_v01 resp;
+};
+
+static struct qmi_elem_info coresight_set_etm_req_msg_v01_ei[] = {
+	{
+		.data_type = QMI_UNSIGNED_4_BYTE,
+		.elem_len  = 1,
+		.elem_size = sizeof(enum coresight_etm_state_enum_type_v01),
+		.array_type  = NO_ARRAY,
+		.tlv_type  = 0x01,
+		.offset    = offsetof(struct coresight_set_etm_req_msg_v01,
+				      state),
+		.ei_array  = NULL,
+	},
+	{
+		.data_type = QMI_EOTI,
+		.elem_len  = 0,
+		.elem_size = 0,
+		.array_type  = NO_ARRAY,
+		.tlv_type  = 0,
+		.offset    = 0,
+		.ei_array  = NULL,
+	},
+};
+
+static struct qmi_elem_info coresight_set_etm_resp_msg_v01_ei[] = {
+	{
+		.data_type = QMI_STRUCT,
+		.elem_len  = 1,
+		.elem_size = sizeof(struct qmi_response_type_v01),
+		.array_type  = NO_ARRAY,
+		.tlv_type  = 0x02,
+		.offset    = offsetof(struct coresight_set_etm_resp_msg_v01,
+				      resp),
+		.ei_array  = qmi_response_type_v01_ei,
+	},
+	{
+		.data_type = QMI_EOTI,
+		.elem_len  = 0,
+		.elem_size = 0,
+		.array_type  = NO_ARRAY,
+		.tlv_type  = 0,
+		.offset    = 0,
+		.ei_array  = NULL,
+	},
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-remote-etm.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-remote-etm.c
@@ -0,0 +1,376 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/sysfs.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/coresight.h>
+#include "coresight-qmi.h"
+#include "coresight-priv.h"
+#include "coresight-common.h"
+
+#define REMOTE_ETM_TRACE_ID_START	192
+
+DEFINE_CORESIGHT_DEVLIST(remote_etm_devs, "remote-etm");
+
+static DEFINE_MUTEX(remote_etm_lock);
+static LIST_HEAD(remote_etm_list);
+
+struct remote_etm_drvdata {
+	struct device			*dev;
+	struct coresight_device		*csdev;
+	struct mutex			mutex;
+	struct qmi_handle		handle;
+	uint32_t			inst_id;
+	bool				enable;
+	bool service_connected;
+	bool security;
+	struct sockaddr_qrtr s_addr;
+	struct list_head link;
+	uint32_t			*traceids;
+	uint32_t			num_trcid;
+};
+
+static int service_remote_etm_new_server(struct qmi_handle *qmi,
+		struct qmi_service *svc)
+{
+	struct remote_etm_drvdata *drvdata = container_of(qmi,
+					struct remote_etm_drvdata, handle);
+
+	drvdata->s_addr.sq_family = AF_QIPCRTR;
+	drvdata->s_addr.sq_node = svc->node;
+	drvdata->s_addr.sq_port = svc->port;
+	drvdata->service_connected = true;
+	dev_info(drvdata->dev,
+		"Connection established between QMI handle and %d service\n",
+		drvdata->inst_id);
+
+	return 0;
+}
+
+static void service_remote_etm_del_server(struct qmi_handle *qmi,
+		struct qmi_service *svc)
+{
+	struct remote_etm_drvdata *drvdata = container_of(qmi,
+					struct remote_etm_drvdata, handle);
+	drvdata->service_connected = false;
+	dev_info(drvdata->dev,
+		"Connection disconnected between QMI handle and %d service\n",
+		drvdata->inst_id);
+}
+
+static struct qmi_ops server_ops = {
+	.new_server = service_remote_etm_new_server,
+	.del_server = service_remote_etm_del_server,
+};
+
+static int remote_etm_enable(struct coresight_device *csdev,
+			     struct perf_event *event, u32 mode)
+{
+	struct remote_etm_drvdata *drvdata =
+		dev_get_drvdata(csdev->dev.parent);
+	struct coresight_set_etm_req_msg_v01 req;
+	struct coresight_set_etm_resp_msg_v01 resp = { { 0, 0 } };
+	struct qmi_txn txn;
+	int i, ret;
+
+	mutex_lock(&drvdata->mutex);
+	for (i = 0; i < drvdata->num_trcid; i++)
+		coresight_csr_set_etr_atid(csdev, drvdata->traceids[i], true);
+
+	if (!drvdata->service_connected) {
+		dev_err(drvdata->dev, "QMI service not connected!\n");
+		ret = EINVAL;
+		goto err;
+	}
+	/*
+	 * The QMI handle may be NULL in the following scenarios:
+	 * 1. QMI service is not present
+	 * 2. QMI service is present but attempt to enable remote ETM is earlier
+	 *    than service is ready to handle request
+	 * 3. Connection between QMI client and QMI service failed
+	 *
+	 * Enable CoreSight without processing further QMI commands which
+	 * provides the option to enable remote ETM by other means.
+	 */
+	req.state = CORESIGHT_ETM_STATE_ENABLED_V01;
+
+	ret = qmi_txn_init(&drvdata->handle, &txn,
+			coresight_set_etm_resp_msg_v01_ei,
+			&resp);
+
+	if (ret < 0) {
+		dev_err(drvdata->dev, "QMI tx init failed , ret:%d\n",
+				ret);
+		goto err;
+	}
+
+	ret = qmi_send_request(&drvdata->handle, &drvdata->s_addr,
+			&txn, CORESIGHT_QMI_SET_ETM_REQ_V01,
+			CORESIGHT_QMI_SET_ETM_REQ_MAX_LEN,
+			coresight_set_etm_req_msg_v01_ei,
+			&req);
+	if (ret < 0) {
+		dev_err(drvdata->dev, "QMI send ACK failed, ret:%d\n",
+				ret);
+		qmi_txn_cancel(&txn);
+		goto err;
+	}
+
+	ret = qmi_txn_wait(&txn, msecs_to_jiffies(TIMEOUT_MS));
+	if (ret < 0) {
+		dev_err(drvdata->dev, "QMI qmi txn wait failed, ret:%d\n",
+				ret);
+		goto err;
+	}
+
+	/* Check the response */
+	if (resp.resp.result != QMI_RESULT_SUCCESS_V01)
+		dev_err(drvdata->dev, "QMI request failed 0x%x\n",
+				resp.resp.error);
+
+	drvdata->enable = true;
+	mutex_unlock(&drvdata->mutex);
+
+	dev_info(drvdata->dev, "Remote ETM tracing enabled for instance %d\n",
+				drvdata->inst_id);
+	return 0;
+err:
+	for (i = 0; i < drvdata->num_trcid; i++)
+		coresight_csr_set_etr_atid(csdev, drvdata->traceids[i], false);
+
+	mutex_unlock(&drvdata->mutex);
+	return ret;
+}
+
+static void remote_etm_disable(struct coresight_device *csdev,
+			       struct perf_event *event)
+{
+	struct remote_etm_drvdata *drvdata =
+		 dev_get_drvdata(csdev->dev.parent);
+	struct coresight_set_etm_req_msg_v01 req;
+	struct coresight_set_etm_resp_msg_v01 resp = { { 0, 0 } };
+	struct qmi_txn txn;
+	int i, ret;
+
+	mutex_lock(&drvdata->mutex);
+	if (!drvdata->service_connected) {
+		dev_err(drvdata->dev, "QMI service not connected!\n");
+		goto err;
+	}
+
+	req.state = CORESIGHT_ETM_STATE_DISABLED_V01;
+
+	ret = qmi_txn_init(&drvdata->handle, &txn,
+			coresight_set_etm_resp_msg_v01_ei,
+			&resp);
+
+	if (ret < 0) {
+		dev_err(drvdata->dev, "QMI tx init failed , ret:%d\n",
+				ret);
+		goto err;
+	}
+
+	ret = qmi_send_request(&drvdata->handle, &drvdata->s_addr,
+			&txn, CORESIGHT_QMI_SET_ETM_REQ_V01,
+			CORESIGHT_QMI_SET_ETM_REQ_MAX_LEN,
+			coresight_set_etm_req_msg_v01_ei,
+			&req);
+	if (ret < 0) {
+		dev_err(drvdata->dev, "QMI send req failed, ret:%d\n",
+				 ret);
+		qmi_txn_cancel(&txn);
+		goto err;
+	}
+
+	ret = qmi_txn_wait(&txn, msecs_to_jiffies(TIMEOUT_MS));
+	if (ret < 0) {
+		dev_err(drvdata->dev, "QMI qmi txn wait failed, ret:%d\n",
+				ret);
+		goto err;
+	}
+
+	/* Check the response */
+	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
+		dev_err(drvdata->dev, "QMI request failed 0x%x\n",
+				resp.resp.error);
+		goto err;
+	}
+
+	for (i = 0; i < drvdata->num_trcid; i++)
+		coresight_csr_set_etr_atid(csdev, drvdata->traceids[i], false);
+
+	drvdata->enable = false;
+	dev_info(drvdata->dev, "Remote ETM tracing disabled for instance %d\n",
+				drvdata->inst_id);
+err:
+	mutex_unlock(&drvdata->mutex);
+}
+
+static const struct coresight_ops_source remote_etm_source_ops = {
+	.enable		= remote_etm_enable,
+	.disable	= remote_etm_disable,
+};
+
+static const struct coresight_ops remote_cs_ops = {
+	.source_ops	= &remote_etm_source_ops,
+};
+
+static int remote_etm_get_traceid(struct remote_etm_drvdata *drvdata)
+{
+	int ret, i;
+	struct device *dev = drvdata->dev;
+	uint32_t *atid;
+
+	ret = of_property_count_u32_elems(dev->of_node, "atid");
+	if (ret < 0) {
+		ret = of_property_read_u32(dev->of_node, "qcom,atid-num",
+				&drvdata->num_trcid);
+		if (ret)
+			return -EINVAL;
+	} else
+		drvdata->num_trcid = ret;
+
+	atid = devm_kcalloc(dev, drvdata->num_trcid, sizeof(*atid), GFP_KERNEL);
+	if (!atid)
+		return -ENOMEM;
+
+	ret = of_property_read_u32_array(dev->of_node, "atid",
+					 atid, drvdata->num_trcid);
+	if (ret)
+		return ret;
+
+	drvdata->traceids = devm_kcalloc(dev, drvdata->num_trcid,
+					 sizeof(uint32_t), GFP_KERNEL);
+	if (!drvdata->traceids)
+		return -ENOMEM;
+
+	for (i = 0; i < drvdata->num_trcid; i++)
+		drvdata->traceids[i] = (uint32_t)atid[i];
+
+	return 0;
+}
+
+static int remote_etm_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct coresight_platform_data *pdata;
+	struct remote_etm_drvdata *drvdata;
+	struct coresight_desc desc = {0 };
+	int ret;
+
+	desc.name = coresight_alloc_device_name(&remote_etm_devs, dev);
+	if (!desc.name)
+		return -ENOMEM;
+	pdata = coresight_get_platform_data(dev);
+	if (IS_ERR(pdata))
+		return PTR_ERR(pdata);
+	pdev->dev.platform_data = pdata;
+
+	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	drvdata->dev = &pdev->dev;
+	platform_set_drvdata(pdev, drvdata);
+
+	ret = of_property_read_u32(pdev->dev.of_node, "qcom,inst-id",
+			&drvdata->inst_id);
+	if (ret)
+		return ret;
+
+	mutex_init(&drvdata->mutex);
+
+	ret = qmi_handle_init(&drvdata->handle,
+			CORESIGHT_QMI_SET_ETM_REQ_MAX_LEN,
+			&server_ops, NULL);
+	if (ret < 0) {
+		dev_err(dev, "Remote ETM client init failed ret:%d\n", ret);
+		return ret;
+	}
+
+	qmi_add_lookup(&drvdata->handle,
+			CORESIGHT_QMI_SVC_ID,
+			CORESIGHT_QMI_VERSION,
+			drvdata->inst_id);
+
+	desc.type = CORESIGHT_DEV_TYPE_SOURCE;
+	desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_REMOTE_PROC;
+	desc.ops = &remote_cs_ops;
+	desc.pdata = pdev->dev.platform_data;
+	desc.dev = &pdev->dev;
+	drvdata->csdev = coresight_register(&desc);
+	if (IS_ERR(drvdata->csdev)) {
+		ret = PTR_ERR(drvdata->csdev);
+		goto err;
+	}
+
+	ret = remote_etm_get_traceid(drvdata);
+	if (ret)
+		drvdata->num_trcid = 0;
+
+	dev_info(dev, "Remote ETM initialized\n");
+
+	pm_runtime_enable(dev);
+	if (drvdata->inst_id >= sizeof(int)*BITS_PER_BYTE)
+		dev_err(dev, "inst_id greater than boot_enable bit mask\n");
+
+	list_add_tail(&drvdata->link, &remote_etm_list);
+
+	return 0;
+err:
+	qmi_handle_release(&drvdata->handle);
+	return ret;
+}
+
+static int remote_etm_remove(struct platform_device *pdev)
+{
+	struct remote_etm_drvdata *drvdata = platform_get_drvdata(pdev);
+	struct device *dev = &pdev->dev;
+
+	list_del(&drvdata->link);
+	pm_runtime_disable(dev);
+	qmi_handle_release(&drvdata->handle);
+	coresight_unregister(drvdata->csdev);
+	return 0;
+}
+
+static const struct of_device_id remote_etm_match[] = {
+	{.compatible = "qcom,coresight-remote-etm"},
+	{}
+};
+
+static struct platform_driver remote_etm_driver = {
+	.probe          = remote_etm_probe,
+	.remove         = remote_etm_remove,
+	.driver         = {
+		.name   = "coresight-remote-etm",
+		.of_match_table = remote_etm_match,
+	},
+};
+
+int __init remote_etm_init(void)
+{
+	return platform_driver_register(&remote_etm_driver);
+}
+module_init(remote_etm_init);
+
+void __exit remote_etm_exit(void)
+{
+	platform_driver_unregister(&remote_etm_driver);
+}
+module_exit(remote_etm_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CoreSight Remote ETM driver");
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-stm.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-stm.c
@@ -2,6 +2,8 @@
 /*
  * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
  *
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
  * Description: CoreSight System Trace Macrocell driver
  *
  * Initial implementation by Pratik Patel
@@ -32,6 +34,7 @@
 
 #include "coresight-priv.h"
 #include "coresight-trace-id.h"
+#include "coresight-common.h"
 
 #define STMDMASTARTR			0xc04
 #define STMDMASTOPR			0xc08
@@ -207,6 +210,8 @@
 	if (val)
 		return -EBUSY;
 
+	coresight_csr_set_etr_atid(csdev, drvdata->traceid, true);
+
 	pm_runtime_get_sync(csdev->dev.parent);
 
 	spin_lock(&drvdata->spinlock);
@@ -276,6 +281,8 @@
 
 		pm_runtime_put(csdev->dev.parent);
 
+		coresight_csr_set_etr_atid(csdev, drvdata->traceid, false);
+
 		local_set(&drvdata->mode, CS_MODE_DISABLED);
 		dev_dbg(&csdev->dev, "STM tracing disabled\n");
 	}
@@ -890,7 +897,7 @@
 		goto stm_unregister;
 	}
 
-	trace_id = coresight_trace_id_get_system_id();
+	trace_id = coresight_trace_id_get_system_id(TRACE_ID_ANY);
 	if (trace_id < 0) {
 		ret = trace_id;
 		goto cs_unregister;
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-tgu.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-tgu.c
@@ -0,0 +1,529 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/amba/bus.h>
+#include <linux/topology.h>
+#include <linux/of.h>
+#include <linux/coresight.h>
+
+#include "coresight-priv.h"
+
+#define tgu_writel(drvdata, val, off)	__raw_writel((val), drvdata->base + off)
+#define tgu_readl(drvdata, off)		__raw_readl(drvdata->base + off)
+
+#define TGU_LOCK(drvdata)						\
+do {									\
+	mb(); /* ensure configuration take effect before we lock it */	\
+	tgu_writel(drvdata, 0x0, CORESIGHT_LAR);			\
+} while (0)
+#define TGU_UNLOCK(drvdata)						\
+do {									\
+	tgu_writel(drvdata, CORESIGHT_UNLOCK, CORESIGHT_LAR);		\
+	mb(); /* ensure unlock take effect before we configure */	\
+} while (0)
+
+#define TGU_CONTROL			0x0000
+#define TIMER0_STATUS			0x0004
+#define COUNTER0_STATUS			0x000C
+#define TGU_STATUS			0x0014
+#define TIMER0_COMPARE_STEP(n)		(0x0040 + 0x1D8 * n)
+#define COUNTER0_COMPARE_STEP(n)	(0x0048 + 0x1D8 * n)
+#define GROUP_REG_STEP(grp, reg, step)	(0x0074 + 0x60 * grp + 0x4 * reg + \
+								 0x1D8 * step)
+#define CONDITION_DECODE_STEP(m, n)	(0x0050 + 0x4 * m + 0x1D8 * n)
+#define CONDITION_SELECT_STEP(m, n)	(0x0060 + 0x4 * m + 0x1D8 * n)
+#define GROUP0				0x0074
+#define GROUP1				0x00D4
+#define GROUP2				0x0134
+#define GROUP3				0x0194
+#define TGU_LAR				0x0FB0
+
+#define MAX_GROUP_SETS			256
+#define MAX_GROUPS			4
+#define MAX_CONDITION_SETS		64
+#define MAX_TIMER_COUNTER_SETS		8
+
+#define to_tgu_drvdata(c)		container_of(c, struct tgu_drvdata, tgu)
+
+struct Trigger_group_data {
+	unsigned long grpaddr;
+	unsigned long value;
+};
+
+struct Trigger_condition_data {
+	unsigned long condaddr;
+	unsigned long value;
+};
+
+struct Trigger_select_data {
+	unsigned long selectaddr;
+	unsigned long value;
+};
+
+struct Trigger_timer_data {
+	unsigned long timeraddr;
+	unsigned long value;
+};
+
+struct Trigger_counter_data {
+	unsigned long counteraddr;
+	unsigned long value;
+};
+struct tgu_drvdata {
+	void __iomem			*base;
+	struct device			*dev;
+	struct coresight_device		*csdev;
+	struct clk			*clk;
+	spinlock_t			spinlock;
+	int				max_steps;
+	int				max_conditions;
+	int				max_regs;
+	int				max_timer_counter;
+	struct Trigger_group_data	*grp_data;
+	struct Trigger_condition_data	*condition_data;
+	struct Trigger_select_data	*select_data;
+	struct Trigger_timer_data	*timer_data;
+	struct Trigger_counter_data	*counter_data;
+	int				grp_refcnt;
+	int				cond_refcnt;
+	int				select_refcnt;
+	int				timer_refcnt;
+	int				counter_refcnt;
+	bool				enable;
+};
+
+DEFINE_CORESIGHT_DEVLIST(tgu_devs, "tgu");
+
+static ssize_t enable_tgu_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t size)
+{
+	unsigned long value;
+	struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	int ret, i, j;
+
+	if (kstrtoul(buf, 16, &value))
+		return -EINVAL;
+
+	/* Enable clock */
+	ret = pm_runtime_get_sync(drvdata->dev);
+	if (ret < 0) {
+		pm_runtime_put(drvdata->dev);
+		return ret;
+	}
+
+	spin_lock(&drvdata->spinlock);
+	/* Unlock the TGU LAR */
+	TGU_UNLOCK(drvdata);
+
+	if (value) {
+
+		/* Disable TGU to program the triggers */
+		tgu_writel(drvdata, 0, TGU_CONTROL);
+
+		/* program the TGU Group data for the desired use case*/
+
+		for (i = 0; i <= drvdata->grp_refcnt; i++)
+			tgu_writel(drvdata, drvdata->grp_data[i].value,
+						drvdata->grp_data[i].grpaddr);
+
+		/* program the unused Condition Decode registers NOT bits to 1*/
+		for (i = 0; i <= drvdata->max_conditions; i++) {
+			for (j = 0; j <= drvdata->max_steps; j++)
+				tgu_writel(drvdata, 0x1000000,
+						CONDITION_DECODE_STEP(i, j));
+		}
+		/* program the TGU Condition Decode for the desired use case*/
+		for (i = 0; i <= drvdata->cond_refcnt; i++)
+			tgu_writel(drvdata, drvdata->condition_data[i].value,
+					drvdata->condition_data[i].condaddr);
+
+		/* program the TGU Condition Select for the desired use case*/
+		for (i = 0; i <= drvdata->select_refcnt; i++)
+			tgu_writel(drvdata, drvdata->select_data[i].value,
+					drvdata->select_data[i].selectaddr);
+
+		/*  Timer and Counter Check */
+		for (i = 0; i <= drvdata->timer_refcnt; i++)
+			tgu_writel(drvdata, drvdata->timer_data[i].value,
+					drvdata->timer_data[i].timeraddr);
+
+		for (i = 0; i <= drvdata->counter_refcnt; i++)
+			tgu_writel(drvdata, drvdata->counter_data[i].value,
+					drvdata->counter_data[i].counteraddr);
+
+		/* Enable TGU to program the triggers */
+		tgu_writel(drvdata, 1, TGU_CONTROL);
+
+		drvdata->enable = true;
+		dev_dbg(dev, "Coresight-TGU enabled\n");
+
+	} else {
+		/* Disable TGU to program the triggers */
+		tgu_writel(drvdata, 0, TGU_CONTROL);
+
+		pm_runtime_put(drvdata->dev);
+		dev_dbg(dev, "Coresight-TGU disabled\n");
+	}
+
+	TGU_LOCK(drvdata);
+	spin_unlock(&drvdata->spinlock);
+	return size;
+}
+static DEVICE_ATTR_WO(enable_tgu);
+
+static ssize_t reset_tgu_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t size)
+{
+	unsigned long value;
+	struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	int ret;
+
+	if (kstrtoul(buf, 16, &value))
+		return -EINVAL;
+
+	if (!drvdata->enable) {
+		/* Enable clock */
+		ret = pm_runtime_get_sync(drvdata->dev);
+		if (ret < 0) {
+			pm_runtime_put(drvdata->dev);
+			return ret;
+		}
+	}
+
+	spin_lock(&drvdata->spinlock);
+	/* Unlock the TGU LAR */
+	TGU_UNLOCK(drvdata);
+
+	if (value) {
+		/* Disable TGU to program the triggers */
+		tgu_writel(drvdata, 0, TGU_CONTROL);
+
+		/* Reset the Reference counters*/
+		drvdata->grp_refcnt = 0;
+		drvdata->cond_refcnt = 0;
+		drvdata->select_refcnt = 0;
+		drvdata->timer_refcnt = 0;
+		drvdata->counter_refcnt = 0;
+
+		dev_dbg(dev, "Coresight-TGU disabled\n");
+	} else
+		dev_dbg(dev, "Invalid input to reset the TGU\n");
+
+	TGU_LOCK(drvdata);
+	spin_unlock(&drvdata->spinlock);
+	pm_runtime_put(drvdata->dev);
+	return size;
+}
+static DEVICE_ATTR_WO(reset_tgu);
+
+static ssize_t set_group_store(struct device *dev, struct device_attribute
+					*attr, const char *buf, size_t size)
+{
+	struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	int grp, reg, step;
+	unsigned long value;
+
+	if (drvdata->grp_refcnt >= MAX_GROUP_SETS) {
+		dev_err(drvdata->dev, " Too many groups are being configured\n");
+		return -EINVAL;
+	}
+
+	if (sscanf(buf, "%d %d %d %lx", &grp, &reg, &step, &value) != 4)
+		return -EINVAL;
+
+	spin_lock(&drvdata->spinlock);
+	if ((grp <= MAX_GROUPS) && (reg <= drvdata->max_regs)) {
+		drvdata->grp_data[drvdata->grp_refcnt].grpaddr =
+						GROUP_REG_STEP(grp, reg, step);
+		drvdata->grp_data[drvdata->grp_refcnt].value = value;
+		drvdata->grp_refcnt++;
+	} else
+		dev_err(drvdata->dev, "Invalid group data\n");
+
+	spin_unlock(&drvdata->spinlock);
+
+	return size;
+}
+static DEVICE_ATTR_WO(set_group);
+
+static ssize_t set_condition_store(struct device *dev, struct device_attribute
+					*attr, const char *buf, size_t size)
+{
+	struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long value;
+	int cond, step;
+
+	if (drvdata->cond_refcnt >= MAX_CONDITION_SETS) {
+		dev_err(drvdata->dev, " Too many groups are being configured\n");
+		return -EINVAL;
+	}
+
+	if (sscanf(buf, "%d %d %lx", &cond, &step, &value) != 3)
+		return -EINVAL;
+
+	spin_lock(&drvdata->spinlock);
+	if ((cond <= drvdata->max_conditions) && (step <=
+						drvdata->max_steps)) {
+		drvdata->condition_data[drvdata->cond_refcnt].condaddr =
+					CONDITION_DECODE_STEP(cond, step);
+		drvdata->condition_data[drvdata->cond_refcnt].value = value;
+		drvdata->cond_refcnt++;
+	} else
+		dev_err(drvdata->dev, "Invalid condition decode data\n");
+
+	spin_unlock(&drvdata->spinlock);
+
+	return size;
+}
+static DEVICE_ATTR_WO(set_condition);
+
+static ssize_t set_select_store(struct device *dev, struct device_attribute
+					*attr, const char *buf, size_t size)
+{
+	struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long value;
+	int select, step;
+
+	if (drvdata->select_refcnt >= MAX_CONDITION_SETS) {
+		dev_err(drvdata->dev, " Too many groups are being configured\n");
+		return -EINVAL;
+	}
+
+	if (sscanf(buf, "%d %d %lx", &select, &step, &value) != 3)
+		return -EINVAL;
+
+	spin_lock(&drvdata->spinlock);
+
+	if ((select <= drvdata->max_conditions) && (step <=
+					drvdata->max_steps)) {
+		drvdata->select_data[drvdata->select_refcnt].selectaddr =
+					CONDITION_SELECT_STEP(select, step);
+		drvdata->select_data[drvdata->select_refcnt].value = value;
+		drvdata->select_refcnt++;
+	} else
+		dev_err(drvdata->dev, "Invalid select decode data\n");
+
+	spin_unlock(&drvdata->spinlock);
+
+	return size;
+}
+static DEVICE_ATTR_WO(set_select);
+
+static ssize_t set_timer_store(struct device *dev, struct device_attribute
+					*attr, const char *buf, size_t size)
+{
+	struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long value;
+	int step;
+
+	if (drvdata->timer_refcnt >= MAX_TIMER_COUNTER_SETS) {
+		dev_err(drvdata->dev, " Too many groups are being configured\n");
+		return -EINVAL;
+	}
+
+	if (sscanf(buf, "%d %lx", &step, &value) != 2)
+		return -EINVAL;
+
+	spin_lock(&drvdata->spinlock);
+	if (step <= drvdata->max_timer_counter) {
+		drvdata->timer_data[drvdata->timer_refcnt].timeraddr =
+						TIMER0_COMPARE_STEP(step);
+		drvdata->timer_data[drvdata->timer_refcnt].value = value;
+		drvdata->timer_refcnt++;
+	} else
+		dev_err(drvdata->dev, "Invalid TGU timer data\n");
+
+	spin_unlock(&drvdata->spinlock);
+
+	return size;
+}
+static DEVICE_ATTR_WO(set_timer);
+
+static ssize_t set_counter_store(struct device *dev, struct device_attribute
+					*attr, const char *buf, size_t size)
+{
+	struct tgu_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long value;
+	int step;
+
+	if (drvdata->counter_refcnt >= MAX_TIMER_COUNTER_SETS) {
+		dev_err(drvdata->dev, " Too many groups are being configured\n");
+		return -EINVAL;
+	}
+
+	if (sscanf(buf, "%d %lx", &step, &value) != 2)
+		return -EINVAL;
+
+	spin_lock(&drvdata->spinlock);
+	if (step <= drvdata->max_timer_counter) {
+		drvdata->counter_data[drvdata->counter_refcnt].counteraddr =
+						COUNTER0_COMPARE_STEP(step);
+		drvdata->counter_data[drvdata->counter_refcnt].value = value;
+		drvdata->counter_refcnt++;
+	} else
+		dev_err(drvdata->dev, "Invalid TGU counter data\n");
+
+	spin_unlock(&drvdata->spinlock);
+
+	return size;
+}
+static DEVICE_ATTR_WO(set_counter);
+
+static struct attribute *tgu_attrs[] = {
+	&dev_attr_enable_tgu.attr,
+	&dev_attr_reset_tgu.attr,
+	&dev_attr_set_group.attr,
+	&dev_attr_set_condition.attr,
+	&dev_attr_set_select.attr,
+	&dev_attr_set_timer.attr,
+	&dev_attr_set_counter.attr,
+	NULL,
+};
+
+static struct attribute_group tgu_attr_grp = {
+	.attrs = tgu_attrs,
+};
+
+static const struct attribute_group *tgu_attr_grps[] = {
+	&tgu_attr_grp,
+	NULL,
+};
+
+static int tgu_probe(struct amba_device *adev, const struct amba_id *id)
+{
+	int ret = 0;
+	struct device *dev = &adev->dev;
+	struct coresight_platform_data *pdata;
+	struct tgu_drvdata *drvdata;
+	struct coresight_desc desc = { 0 };
+
+	desc.name = coresight_alloc_device_name(&tgu_devs, dev);
+	if (!desc.name)
+		return -ENOMEM;
+	pdata = coresight_get_platform_data(dev);
+	if (IS_ERR(pdata))
+		return PTR_ERR(pdata);
+	adev->dev.platform_data = pdata;
+
+	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	drvdata->dev = &adev->dev;
+
+	dev_set_drvdata(dev, drvdata);
+
+	drvdata->base = devm_ioremap_resource(dev, &adev->res);
+	if (!drvdata->base)
+		return -ENOMEM;
+
+	spin_lock_init(&drvdata->spinlock);
+
+	ret = of_property_read_u32(adev->dev.of_node, "tgu-steps",
+						&drvdata->max_steps);
+	if (ret)
+		return -EINVAL;
+
+	ret = of_property_read_u32(adev->dev.of_node, "tgu-conditions",
+						&drvdata->max_conditions);
+	if (ret)
+		return -EINVAL;
+
+	ret = of_property_read_u32(adev->dev.of_node, "tgu-regs",
+							&drvdata->max_regs);
+	if (ret)
+		return -EINVAL;
+
+	ret = of_property_read_u32(adev->dev.of_node, "tgu-timer-counters",
+						&drvdata->max_timer_counter);
+	if (ret)
+		return -EINVAL;
+
+	/* Alloc memory for Grps, Conditions and Steps */
+	drvdata->grp_data = devm_kzalloc(dev, MAX_GROUP_SETS *
+				       sizeof(*drvdata->grp_data),
+				       GFP_KERNEL);
+	if (!drvdata->grp_data)
+		return -ENOMEM;
+
+	drvdata->condition_data = devm_kzalloc(dev, MAX_CONDITION_SETS *
+				       sizeof(*drvdata->condition_data),
+				       GFP_KERNEL);
+
+	if (!drvdata->condition_data)
+		return -ENOMEM;
+
+	drvdata->select_data = devm_kzalloc(dev, MAX_CONDITION_SETS *
+				       sizeof(*drvdata->select_data),
+				       GFP_KERNEL);
+	if (!drvdata->select_data)
+		return -ENOMEM;
+
+	drvdata->timer_data = devm_kzalloc(dev, MAX_TIMER_COUNTER_SETS *
+				       sizeof(*drvdata->timer_data),
+				       GFP_KERNEL);
+	if (!drvdata->timer_data)
+		return -ENOMEM;
+
+	drvdata->counter_data = devm_kzalloc(dev, MAX_TIMER_COUNTER_SETS *
+				       sizeof(*drvdata->counter_data),
+				       GFP_KERNEL);
+	if (!drvdata->counter_data)
+		return -ENOMEM;
+
+	drvdata->enable = false;
+
+	desc.type = CORESIGHT_DEV_TYPE_HELPER;
+	desc.pdata = adev->dev.platform_data;
+	desc.dev = &adev->dev;
+	desc.groups = tgu_attr_grps;
+	drvdata->csdev = coresight_register(&desc);
+	if (IS_ERR(drvdata->csdev)) {
+		ret = PTR_ERR(drvdata->csdev);
+		goto err;
+	}
+
+	pm_runtime_put(&adev->dev);
+	dev_dbg(dev, "TGU initialized\n");
+	return 0;
+err:
+	pm_runtime_put(&adev->dev);
+	return ret;
+}
+
+static struct amba_id tgu_ids[] = {
+	{
+		.id	=	0x0003b999,
+		.mask	=	0x0003ffff,
+		.data	=	"TGU",
+	},
+	{ 0, 0},
+};
+
+static struct amba_driver tgu_driver = {
+	.drv = {
+		.name			=	"coresight-tgu",
+		.owner			=	THIS_MODULE,
+		.suppress_bind_attrs	=	true,
+	},
+	.probe		=	tgu_probe,
+	.id_table	=	tgu_ids,
+};
+
+builtin_amba_driver(tgu_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("CoreSight TGU driver");
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -2,6 +2,8 @@
 /* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * Description: CoreSight Trace Memory Controller driver
+ *
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/kernel.h>
@@ -10,7 +12,6 @@
 #include <linux/device.h>
 #include <linux/idr.h>
 #include <linux/io.h>
-#include <linux/iommu.h>
 #include <linux/err.h>
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
@@ -27,6 +28,7 @@
 
 #include "coresight-priv.h"
 #include "coresight-tmc.h"
+#include "coresight-common.h"
 
 DEFINE_CORESIGHT_DEVLIST(etb_devs, "tmc_etb");
 DEFINE_CORESIGHT_DEVLIST(etf_devs, "tmc_etf");
@@ -183,19 +185,25 @@
 	ssize_t actual;
 	struct tmc_drvdata *drvdata = container_of(file->private_data,
 						   struct tmc_drvdata, miscdev);
+
+	mutex_lock(&drvdata->mem_lock);
 	actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
-	if (actual <= 0)
+	if (actual <= 0) {
+		mutex_unlock(&drvdata->mem_lock);
 		return 0;
+	}
 
 	if (copy_to_user(data, bufp, actual)) {
 		dev_dbg(&drvdata->csdev->dev,
 			"%s: copy_to_user failed\n", __func__);
+		mutex_unlock(&drvdata->mem_lock);
 		return -EFAULT;
 	}
 
 	*ppos += actual;
 	dev_dbg(&drvdata->csdev->dev, "%zu bytes copied\n", actual);
 
+	mutex_unlock(&drvdata->mem_lock);
 	return actual;
 }
 
@@ -330,14 +338,93 @@
 
 static DEVICE_ATTR_RW(buffer_size);
 
-static struct attribute *coresight_tmc_attrs[] = {
+static ssize_t block_size_show(struct device *dev,
+			     struct device_attribute *attr,
+			     char *buf)
+{
+	struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	uint32_t val = 0;
+
+	if (drvdata->byte_cntr)
+		val = drvdata->byte_cntr->block_size;
+
+	return scnprintf(buf, PAGE_SIZE, "%d\n",
+			val);
+}
+
+static ssize_t block_size_store(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf,
+			      size_t size)
+{
+	struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+
+	if (kstrtoul(buf, 0, &val))
+		return -EINVAL;
+
+	if (!drvdata->byte_cntr)
+		return -EINVAL;
+
+	if (val && val < 4096) {
+		pr_err("Assign minimum block size of 4096 bytes\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&drvdata->byte_cntr->byte_cntr_lock);
+	drvdata->byte_cntr->block_size = val;
+	mutex_unlock(&drvdata->byte_cntr->byte_cntr_lock);
+
+	return size;
+}
+static DEVICE_ATTR_RW(block_size);
+
+static ssize_t out_mode_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	return scnprintf(buf, PAGE_SIZE, "%s\n",
+			str_tmc_etr_out_mode[drvdata->out_mode]);
+}
+
+static ssize_t out_mode_store(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf, size_t size)
+{
+	struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	char str[10] = "";
+	int ret;
+
+	if (strlen(buf) >= 10)
+		return -EINVAL;
+	if (sscanf(buf, "%s", str) != 1)
+		return -EINVAL;
+
+	ret = tmc_etr_switch_mode(drvdata, str);
+	return ret ? ret : size;
+}
+static DEVICE_ATTR_RW(out_mode);
+
+static struct attribute *coresight_tmc_etr_attrs[] = {
 	&dev_attr_trigger_cntr.attr,
 	&dev_attr_buffer_size.attr,
+	&dev_attr_block_size.attr,
+	&dev_attr_out_mode.attr,
+	NULL,
+};
+
+static struct attribute *coresight_tmc_etf_attrs[] = {
+	&dev_attr_trigger_cntr.attr,
 	NULL,
 };
 
-static const struct attribute_group coresight_tmc_group = {
-	.attrs = coresight_tmc_attrs,
+static const struct attribute_group coresight_tmc_etr_group = {
+	.attrs = coresight_tmc_etr_attrs,
+};
+
+static const struct attribute_group coresight_tmc_etf_group = {
+	.attrs = coresight_tmc_etf_attrs,
 };
 
 static const struct attribute_group coresight_tmc_mgmt_group = {
@@ -345,15 +432,14 @@
 	.name = "mgmt",
 };
 
-static const struct attribute_group *coresight_etf_groups[] = {
-	&coresight_tmc_group,
+static const struct attribute_group *coresight_tmc_etr_groups[] = {
+	&coresight_tmc_etr_group,
 	&coresight_tmc_mgmt_group,
 	NULL,
 };
 
-static const struct attribute_group *coresight_etr_groups[] = {
-	&coresight_etr_group,
-	&coresight_tmc_group,
+static const struct attribute_group *coresight_tmc_etf_groups[] = {
+	&coresight_tmc_etf_group,
 	&coresight_tmc_mgmt_group,
 	NULL,
 };
@@ -467,36 +553,48 @@
 	desc.access = CSDEV_ACCESS_IOMEM(base);
 
 	spin_lock_init(&drvdata->spinlock);
+	mutex_init(&drvdata->mem_lock);
 
 	devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID);
 	drvdata->config_type = BMVAL(devid, 6, 7);
 	drvdata->memwidth = tmc_get_memwidth(devid);
 	/* This device is not associated with a session */
 	drvdata->pid = -1;
-	drvdata->etr_mode = ETR_MODE_AUTO;
 
 	if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) {
+		drvdata->out_mode = TMC_ETR_OUT_MODE_MEM;
 		drvdata->size = tmc_etr_get_default_buffer_size(dev);
 		drvdata->max_burst_size = tmc_etr_get_max_burst_size(dev);
 	} else {
 		drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4;
 	}
 
+	ret = of_get_coresight_csr_name(adev->dev.of_node, &drvdata->csr_name);
+	if (ret)
+		dev_info(dev, "No csr data\n");
+	else {
+		drvdata->csr = coresight_csr_get(drvdata->csr_name);
+		if (IS_ERR(drvdata->csr)) {
+			dev_info(dev, "failed to get csr, defer probe\n");
+			return -EPROBE_DEFER;
+		}
+	}
+
 	desc.dev = dev;
 
 	switch (drvdata->config_type) {
 	case TMC_CONFIG_TYPE_ETB:
-		desc.groups = coresight_etf_groups;
 		desc.type = CORESIGHT_DEV_TYPE_SINK;
 		desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER;
 		desc.ops = &tmc_etb_cs_ops;
+		desc.groups = coresight_tmc_etf_groups;
 		dev_list = &etb_devs;
 		break;
 	case TMC_CONFIG_TYPE_ETR:
-		desc.groups = coresight_etr_groups;
 		desc.type = CORESIGHT_DEV_TYPE_SINK;
 		desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_SYSMEM;
 		desc.ops = &tmc_etr_cs_ops;
+		desc.groups = coresight_tmc_etr_groups;
 		ret = tmc_etr_setup_caps(dev, devid,
 					 coresight_get_uci_data(id));
 		if (ret)
@@ -504,13 +602,18 @@
 		idr_init(&drvdata->idr);
 		mutex_init(&drvdata->idr_mutex);
 		dev_list = &etr_devs;
+
+		drvdata->byte_cntr = byte_cntr_init(adev, drvdata);
+		ret = tmc_etr_usb_init(adev, drvdata);
+		if (ret)
+			goto out;
 		break;
 	case TMC_CONFIG_TYPE_ETF:
-		desc.groups = coresight_etf_groups;
 		desc.type = CORESIGHT_DEV_TYPE_LINKSINK;
 		desc.subtype.sink_subtype = CORESIGHT_DEV_SUBTYPE_SINK_BUFFER;
 		desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_FIFO;
 		desc.ops = &tmc_etf_cs_ops;
+		desc.groups = coresight_tmc_etf_groups;
 		dev_list = &etf_devs;
 		break;
 	default:
@@ -561,7 +664,10 @@
 	if (drvdata->mode == CS_MODE_DISABLED)
 		goto out;
 
-	if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
+	if (drvdata->config_type == TMC_CONFIG_TYPE_ETR &&
+		(drvdata->out_mode == TMC_ETR_OUT_MODE_MEM ||
+		 (drvdata->out_mode == TMC_ETR_OUT_MODE_USB &&
+		  drvdata->usb_data->usb_mode == TMC_ETR_USB_SW)))
 		tmc_etr_disable_hw(drvdata);
 
 	/*
@@ -582,6 +688,11 @@
 	 * etb fops in this case, device is there until last file
 	 * handler to this device is closed.
 	 */
+
+	if (drvdata->config_type == TMC_CONFIG_TYPE_ETR
+			&& drvdata->byte_cntr)
+		byte_cntr_remove(drvdata->byte_cntr);
+
 	misc_deregister(&drvdata->miscdev);
 	coresight_unregister(drvdata->csdev);
 }
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -84,6 +84,12 @@
 {
 	CS_UNLOCK(drvdata->base);
 
+	/* Check if the etf already disabled*/
+	if (!(readl_relaxed(drvdata->base + TMC_CTL) & TMC_CTL_CAPT_EN)) {
+		CS_LOCK(drvdata->base);
+		return;
+	}
+
 	tmc_flush_and_stop(drvdata);
 	/*
 	 * When operating in sysFS mode the content of the buffer needs to be
@@ -663,7 +669,6 @@
 	char *buf = NULL;
 	enum tmc_mode mode;
 	unsigned long flags;
-	int rc = 0;
 
 	/* config types are set a boot time and never change */
 	if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETB &&
@@ -689,11 +694,7 @@
 		 * can't be NULL.
 		 */
 		memset(drvdata->buf, 0, drvdata->size);
-		rc = __tmc_etb_enable_hw(drvdata);
-		if (rc) {
-			spin_unlock_irqrestore(&drvdata->spinlock, flags);
-			return rc;
-		}
+		__tmc_etb_enable_hw(drvdata);
 	} else {
 		/*
 		 * The ETB/ETF is not tracing and the buffer was just read.
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -26,12 +26,6 @@
 	size_t		size;
 };
 
-struct etr_buf_hw {
-	bool	has_iommu;
-	bool	has_etr_sg;
-	bool	has_catu;
-};
-
 /*
  * etr_perf_buffer - Perf buffer used for ETR
  * @drvdata		- The ETR drvdaga this buffer has been allocated for.
@@ -57,6 +51,10 @@
 /* Lower limit for ETR hardware buffer */
 #define TMC_ETR_PERF_MIN_BUF_SIZE	SZ_1M
 
+
+/* SW USB reserved memory size */
+#define TMC_ETR_SW_USB_BUF_SIZE SZ_64M
+
 /*
  * The TMC ETR SG has a page size of 4K. The SG table contains pointers
  * to 4KB buffers. However, the OS may use a PAGE_SIZE different from
@@ -261,9 +259,43 @@
 {
 	tmc_free_table_pages(sg_table);
 	tmc_free_data_pages(sg_table);
+	kfree(sg_table);
 }
 EXPORT_SYMBOL_GPL(tmc_free_sg_table);
 
+static long tmc_flat_get_rwp_offset(struct tmc_drvdata *drvdata)
+{
+	dma_addr_t paddr = drvdata->sysfs_buf->hwaddr;
+	u64 rwp;
+
+	rwp = tmc_read_rwp(drvdata);
+	return rwp - paddr;
+}
+
+static long tmc_sg_get_rwp_offset(struct tmc_drvdata *drvdata)
+{
+	struct etr_buf *etr_buf = drvdata->sysfs_buf;
+	struct etr_sg_table *etr_table = etr_buf->private;
+	struct tmc_sg_table *table = etr_table->sg_table;
+	u64 rwp;
+	long w_offset;
+
+	rwp = tmc_read_rwp(drvdata);
+	w_offset = tmc_sg_get_data_page_offset(table, rwp);
+
+	return w_offset;
+}
+
+long tmc_get_rwp_offset(struct tmc_drvdata *drvdata)
+{
+	struct etr_buf *etr_buf = drvdata->sysfs_buf;
+
+	if (etr_buf->mode == ETR_MODE_FLAT)
+		return tmc_flat_get_rwp_offset(drvdata);
+	else
+		return tmc_sg_get_rwp_offset(drvdata);
+}
+
 /*
  * Alloc pages for the table. Since this will be used by the device,
  * allocate the pages closer to the device (i.e, dev_to_node(dev)
@@ -342,7 +374,6 @@
 		rc = tmc_alloc_table_pages(sg_table);
 	if (rc) {
 		tmc_free_sg_table(sg_table);
-		kfree(sg_table);
 		return ERR_PTR(rc);
 	}
 
@@ -836,22 +867,6 @@
 	}
 }
 
-static void get_etr_buf_hw(struct device *dev, struct etr_buf_hw *buf_hw)
-{
-	struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
-
-	buf_hw->has_iommu = iommu_get_domain_for_dev(dev->parent);
-	buf_hw->has_etr_sg = tmc_etr_has_cap(drvdata, TMC_ETR_SG);
-	buf_hw->has_catu = !!tmc_etr_get_catu_device(drvdata);
-}
-
-static bool etr_can_use_flat_mode(struct etr_buf_hw *buf_hw, ssize_t etr_buf_size)
-{
-	bool has_sg = buf_hw->has_catu || buf_hw->has_etr_sg;
-
-	return !has_sg || buf_hw->has_iommu || etr_buf_size < SZ_1M;
-}
-
 /*
  * tmc_alloc_etr_buf: Allocate a buffer use by ETR.
  * @drvdata	: ETR device details.
@@ -865,22 +880,23 @@
 					 int node, void **pages)
 {
 	int rc = -ENOMEM;
+	bool has_etr_sg, has_iommu;
+	bool has_sg, has_catu;
 	struct etr_buf *etr_buf;
-	struct etr_buf_hw buf_hw;
 	struct device *dev = &drvdata->csdev->dev;
 
-	get_etr_buf_hw(dev, &buf_hw);
+	has_etr_sg = tmc_etr_has_cap(drvdata, TMC_ETR_SG);
+	has_iommu = iommu_get_domain_for_dev(dev->parent);
+	has_catu = !!tmc_etr_get_catu_device(drvdata);
+
+	has_sg = has_catu || has_etr_sg;
+
 	etr_buf = kzalloc(sizeof(*etr_buf), GFP_KERNEL);
 	if (!etr_buf)
 		return ERR_PTR(-ENOMEM);
 
 	etr_buf->size = size;
 
-	/* If there is user directive for buffer mode, try that first */
-	if (drvdata->etr_mode != ETR_MODE_AUTO)
-		rc = tmc_etr_mode_alloc_buf(drvdata->etr_mode, drvdata,
-					    etr_buf, node, pages);
-
 	/*
 	 * If we have to use an existing list of pages, we cannot reliably
 	 * use a contiguous DMA memory (even if we have an IOMMU). Otherwise,
@@ -893,13 +909,14 @@
 	 * Fallback to available mechanisms.
 	 *
 	 */
-	if (rc && !pages && etr_can_use_flat_mode(&buf_hw, size))
+	if (!pages && (drvdata->out_mode != TMC_ETR_OUT_MODE_USB) &&
+	    (!has_sg || has_iommu || size < SZ_1M))
 		rc = tmc_etr_mode_alloc_buf(ETR_MODE_FLAT, drvdata,
 					    etr_buf, node, pages);
-	if (rc && buf_hw.has_etr_sg)
+	if (rc && has_etr_sg)
 		rc = tmc_etr_mode_alloc_buf(ETR_MODE_ETR_SG, drvdata,
 					    etr_buf, node, pages);
-	if (rc && buf_hw.has_catu)
+	if (rc && has_catu)
 		rc = tmc_etr_mode_alloc_buf(ETR_MODE_CATU, drvdata,
 					    etr_buf, node, pages);
 	if (rc) {
@@ -926,7 +943,7 @@
  * Returns: The size of the linear data available @pos, with *bufpp
  * updated to point to the buffer.
  */
-static ssize_t tmc_etr_buf_get_data(struct etr_buf *etr_buf,
+ssize_t tmc_etr_buf_get_data(struct etr_buf *etr_buf,
 				    u64 offset, size_t len, char **bufpp)
 {
 	/* Adjust the length to limit this transaction to end of buffer */
@@ -1104,7 +1121,12 @@
 static struct etr_buf *
 tmc_etr_setup_sysfs_buf(struct tmc_drvdata *drvdata)
 {
-	return tmc_alloc_etr_buf(drvdata, drvdata->size,
+	if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB &&
+		drvdata->usb_data->usb_mode == TMC_ETR_USB_SW)
+		return tmc_alloc_etr_buf(drvdata, TMC_ETR_SW_USB_BUF_SIZE,
+				0, cpu_to_node(0), NULL);
+	else
+		return tmc_alloc_etr_buf(drvdata, drvdata->size,
 				 0, cpu_to_node(0), NULL);
 }
 
@@ -1218,13 +1240,10 @@
 	int ret = 0;
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
-	struct etr_buf *sysfs_buf = tmc_etr_get_sysfs_buffer(csdev);
+	struct etr_buf *sysfs_buf = NULL;
 
-	if (IS_ERR(sysfs_buf))
-		return PTR_ERR(sysfs_buf);
 
 	spin_lock_irqsave(&drvdata->spinlock, flags);
-
 	/*
 	 * In sysFS mode we can have multiple writers per sink.  Since this
 	 * sink is already enabled no memory is needed and the HW need not be
@@ -1232,20 +1251,49 @@
 	 */
 	if (drvdata->mode == CS_MODE_SYSFS) {
 		atomic_inc(&csdev->refcnt);
-		goto out;
+		goto unlock_out;
+	}
+
+	if (drvdata->reading || drvdata->mode == CS_MODE_PERF) {
+		ret = -EBUSY;
+		goto unlock_out;
+	}
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+
+	sysfs_buf = tmc_etr_get_sysfs_buffer(csdev);
+
+	if (IS_ERR(sysfs_buf))
+		return PTR_ERR(sysfs_buf);
+
+	spin_lock_irqsave(&drvdata->spinlock, flags);
+
+	if ((drvdata->out_mode == TMC_ETR_OUT_MODE_MEM) ||
+		(drvdata->out_mode == TMC_ETR_OUT_MODE_USB &&
+			drvdata->usb_data->usb_mode ==
+			TMC_ETR_USB_SW)) {
+		ret = tmc_etr_enable_hw(drvdata, sysfs_buf);
+		if (ret)
+			goto unlock_out;
 	}
 
-	ret = tmc_etr_enable_hw(drvdata, sysfs_buf);
 	if (!ret) {
 		drvdata->mode = CS_MODE_SYSFS;
 		atomic_inc(&csdev->refcnt);
 	}
 
-out:
 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
-	if (!ret)
-		dev_dbg(&csdev->dev, "TMC-ETR enabled\n");
+	if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM)
+		tmc_etr_byte_cntr_start(drvdata->byte_cntr);
+	if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB)
+		tmc_usb_enable(drvdata->usb_data);
+
+	dev_dbg(&csdev->dev, "TMC-ETR enabled\n");
+
+	return 0;
+
+unlock_out:
+	spin_unlock_irqrestore(&drvdata->spinlock, flags);
 
 	return ret;
 }
@@ -1697,9 +1745,15 @@
 static int tmc_enable_etr_sink(struct coresight_device *csdev,
 			       enum cs_mode mode, void *data)
 {
+	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	int ret;
+
 	switch (mode) {
 	case CS_MODE_SYSFS:
-		return tmc_enable_etr_sink_sysfs(csdev);
+		mutex_lock(&drvdata->mem_lock);
+		ret = tmc_enable_etr_sink_sysfs(csdev);
+		mutex_unlock(&drvdata->mem_lock);
+		return ret;
 	case CS_MODE_PERF:
 		return tmc_enable_etr_sink_perf(csdev, data);
 	default:
@@ -1707,7 +1761,8 @@
 	}
 }
 
-static int tmc_disable_etr_sink(struct coresight_device *csdev)
+static int _tmc_disable_etr_sink(struct coresight_device *csdev,
+				bool mode_switch)
 {
 	unsigned long flags;
 	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
@@ -1719,14 +1774,27 @@
 		return -EBUSY;
 	}
 
-	if (atomic_dec_return(&csdev->refcnt)) {
+	if (atomic_dec_return(&csdev->refcnt) && !mode_switch) {
 		spin_unlock_irqrestore(&drvdata->spinlock, flags);
 		return -EBUSY;
 	}
 
 	/* Complain if we (somehow) got out of sync */
 	WARN_ON_ONCE(drvdata->mode == CS_MODE_DISABLED);
-	tmc_etr_disable_hw(drvdata);
+	if (drvdata->out_mode == TMC_ETR_OUT_MODE_MEM ||
+		(drvdata->out_mode == TMC_ETR_OUT_MODE_USB &&
+			drvdata->usb_data->usb_mode == TMC_ETR_USB_SW)) {
+		if (drvdata->out_mode == TMC_ETR_OUT_MODE_USB) {
+			spin_unlock_irqrestore(&drvdata->spinlock, flags);
+			tmc_usb_disable(drvdata->usb_data);
+			spin_lock_irqsave(&drvdata->spinlock, flags);
+		}
+		tmc_etr_disable_hw(drvdata);
+	} else {
+		spin_unlock_irqrestore(&drvdata->spinlock, flags);
+		return -EINVAL;
+	}
+
 	/* Dissociate from monitored process. */
 	drvdata->pid = -1;
 	drvdata->mode = CS_MODE_DISABLED;
@@ -1734,11 +1802,73 @@
 	drvdata->perf_buf = NULL;
 
 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	tmc_etr_byte_cntr_stop(drvdata->byte_cntr);
 
 	dev_dbg(&csdev->dev, "TMC-ETR disabled\n");
 	return 0;
 }
 
+static int tmc_disable_etr_sink(struct coresight_device *csdev)
+{
+	struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	int ret;
+
+	mutex_lock(&drvdata->mem_lock);
+	ret = _tmc_disable_etr_sink(csdev, false);
+	mutex_unlock(&drvdata->mem_lock);
+	return ret;
+}
+
+int tmc_etr_switch_mode(struct tmc_drvdata *drvdata, const char *out_mode)
+{
+	enum tmc_etr_out_mode new_mode, old_mode;
+
+	mutex_lock(&drvdata->mem_lock);
+	if (!strcmp(out_mode, str_tmc_etr_out_mode[TMC_ETR_OUT_MODE_MEM]))
+		new_mode = TMC_ETR_OUT_MODE_MEM;
+	else if (!strcmp(out_mode, str_tmc_etr_out_mode[TMC_ETR_OUT_MODE_USB])) {
+		if (drvdata->usb_data->usb_mode == TMC_ETR_USB_NONE) {
+			dev_err(&drvdata->csdev->dev,
+					"USB mode is not supported.\n");
+			mutex_unlock(&drvdata->mem_lock);
+			return -EINVAL;
+		}
+		new_mode = TMC_ETR_OUT_MODE_USB;
+	} else {
+		mutex_unlock(&drvdata->mem_lock);
+		return -EINVAL;
+	}
+
+	if (new_mode == drvdata->out_mode) {
+		mutex_unlock(&drvdata->mem_lock);
+		return 0;
+	}
+
+	if (drvdata->mode == CS_MODE_DISABLED) {
+		drvdata->out_mode = new_mode;
+		mutex_unlock(&drvdata->mem_lock);
+		return 0;
+	}
+
+	_tmc_disable_etr_sink(drvdata->csdev, true);
+	old_mode = drvdata->out_mode;
+	drvdata->out_mode = new_mode;
+
+	if (tmc_enable_etr_sink_sysfs(drvdata->csdev)) {
+		drvdata->out_mode = old_mode;
+		tmc_enable_etr_sink_sysfs(drvdata->csdev);
+		dev_err(&drvdata->csdev->dev,
+				"Switch to %s failed. Fall back to %s.\n",
+				str_tmc_etr_out_mode[new_mode],
+				str_tmc_etr_out_mode[old_mode]);
+		mutex_unlock(&drvdata->mem_lock);
+		return -EINVAL;
+	}
+
+	mutex_unlock(&drvdata->mem_lock);
+	return 0;
+}
+
 static const struct coresight_ops_sink tmc_etr_sink_ops = {
 	.enable		= tmc_enable_etr_sink,
 	.disable	= tmc_disable_etr_sink,
@@ -1760,12 +1890,18 @@
 	if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
 		return -EINVAL;
 
+	mutex_lock(&drvdata->mem_lock);
 	spin_lock_irqsave(&drvdata->spinlock, flags);
 	if (drvdata->reading) {
 		ret = -EBUSY;
 		goto out;
 	}
 
+	if (drvdata->byte_cntr && drvdata->byte_cntr->enable) {
+		ret = -EINVAL;
+		goto out;
+	}
+
 	/*
 	 * We can safely allow reads even if the ETR is operating in PERF mode,
 	 * since the sysfs session is captured in mode specific data.
@@ -1783,6 +1919,7 @@
 	drvdata->reading = true;
 out:
 	spin_unlock_irqrestore(&drvdata->spinlock, flags);
+	mutex_unlock(&drvdata->mem_lock);
 
 	return ret;
 }
@@ -1796,6 +1933,7 @@
 	if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
 		return -EINVAL;
 
+	mutex_lock(&drvdata->mem_lock);
 	spin_lock_irqsave(&drvdata->spinlock, flags);
 
 	/* RE-enable the TMC if need be */
@@ -1822,72 +1960,6 @@
 	if (sysfs_buf)
 		tmc_etr_free_sysfs_buf(sysfs_buf);
 
+	mutex_unlock(&drvdata->mem_lock);
 	return 0;
 }
-
-static const char *const buf_modes_str[] = {
-	[ETR_MODE_FLAT]		= "flat",
-	[ETR_MODE_ETR_SG]	= "tmc-sg",
-	[ETR_MODE_CATU]		= "catu",
-	[ETR_MODE_AUTO]		= "auto",
-};
-
-static ssize_t buf_modes_available_show(struct device *dev,
-					    struct device_attribute *attr, char *buf)
-{
-	struct etr_buf_hw buf_hw;
-	ssize_t size = 0;
-
-	get_etr_buf_hw(dev, &buf_hw);
-	size += sysfs_emit(buf, "%s ", buf_modes_str[ETR_MODE_AUTO]);
-	size += sysfs_emit_at(buf, size, "%s ", buf_modes_str[ETR_MODE_FLAT]);
-	if (buf_hw.has_etr_sg)
-		size += sysfs_emit_at(buf, size, "%s ", buf_modes_str[ETR_MODE_ETR_SG]);
-
-	if (buf_hw.has_catu)
-		size += sysfs_emit_at(buf, size, "%s ", buf_modes_str[ETR_MODE_CATU]);
-
-	size += sysfs_emit_at(buf, size, "\n");
-	return size;
-}
-static DEVICE_ATTR_RO(buf_modes_available);
-
-static ssize_t buf_mode_preferred_show(struct device *dev,
-					 struct device_attribute *attr, char *buf)
-{
-	struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
-
-	return sysfs_emit(buf, "%s\n", buf_modes_str[drvdata->etr_mode]);
-}
-
-static ssize_t buf_mode_preferred_store(struct device *dev,
-					  struct device_attribute *attr,
-					  const char *buf, size_t size)
-{
-	struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent);
-	struct etr_buf_hw buf_hw;
-
-	get_etr_buf_hw(dev, &buf_hw);
-	if (sysfs_streq(buf, buf_modes_str[ETR_MODE_FLAT]))
-		drvdata->etr_mode = ETR_MODE_FLAT;
-	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_ETR_SG]) && buf_hw.has_etr_sg)
-		drvdata->etr_mode = ETR_MODE_ETR_SG;
-	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_CATU]) && buf_hw.has_catu)
-		drvdata->etr_mode = ETR_MODE_CATU;
-	else if (sysfs_streq(buf, buf_modes_str[ETR_MODE_AUTO]))
-		drvdata->etr_mode = ETR_MODE_AUTO;
-	else
-		return -EINVAL;
-	return size;
-}
-static DEVICE_ATTR_RW(buf_mode_preferred);
-
-static struct attribute *coresight_etr_attrs[] = {
-	&dev_attr_buf_modes_available.attr,
-	&dev_attr_buf_mode_preferred.attr,
-	NULL,
-};
-
-const struct attribute_group coresight_etr_group = {
-	.attrs = coresight_etr_attrs,
-};
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-tmc-usb.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-tmc-usb.c
@@ -0,0 +1,470 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Description: CoreSight TMC USB driver
+ */
+
+#include <linux/of_address.h>
+#include <linux/delay.h>
+#include <linux/soc/qcom/usb_qdss.h>
+#include <linux/time.h>
+#include <linux/slab.h>
+#include "coresight-tmc-usb.h"
+#include "coresight-priv.h"
+#include "coresight-common.h"
+#include "coresight-tmc.h"
+
+#define USB_BLK_SIZE 65536
+#define USB_SG_NUM (USB_BLK_SIZE / PAGE_SIZE)
+#define USB_BUF_NUM 255
+#define USB_TIME_OUT (5 * HZ)
+
+#define TMC_AXICTL_VALUE	(0xf02)
+#define TMC_FFCR_VALUE		(0x133)
+
+static int usb_bypass_start(struct byte_cntr *byte_cntr_data)
+{
+	long offset;
+	struct tmc_drvdata *tmcdrvdata;
+
+	if (!byte_cntr_data)
+		return -ENOMEM;
+
+	tmcdrvdata = byte_cntr_data->tmcdrvdata;
+	mutex_lock(&byte_cntr_data->usb_bypass_lock);
+
+
+	dev_info(&tmcdrvdata->csdev->dev,
+			"%s: Start usb bypass\n", __func__);
+	if (tmcdrvdata->mode != CS_MODE_SYSFS) {
+		mutex_unlock(&byte_cntr_data->usb_bypass_lock);
+		return -EINVAL;
+	}
+
+	offset = tmc_get_rwp_offset(tmcdrvdata);
+	if (offset < 0) {
+		dev_err(&tmcdrvdata->csdev->dev,
+			"%s: invalid rwp offset value\n", __func__);
+		mutex_unlock(&byte_cntr_data->usb_bypass_lock);
+		return offset;
+	}
+	byte_cntr_data->offset = offset;
+
+	/*Ensure usbch is ready*/
+	if (!tmcdrvdata->usb_data->usbch) {
+		int i;
+
+		for (i = TIMEOUT_US; i > 0; i--) {
+			if (tmcdrvdata->usb_data->usbch)
+				break;
+
+			if (i - 1)
+				udelay(1);
+			else {
+				dev_err(&tmcdrvdata->csdev->dev,
+					"timeout while waiting usbch to be ready\n");
+				mutex_unlock(&byte_cntr_data->usb_bypass_lock);
+				return -EAGAIN;
+			}
+		}
+	}
+	atomic_set(&byte_cntr_data->usb_free_buf, USB_BUF_NUM);
+
+	byte_cntr_data->read_active = true;
+	/*
+	 * IRQ is a '8- byte' counter and to observe interrupt at
+	 * 'block_size' bytes of data
+	 */
+	coresight_csr_set_byte_cntr(byte_cntr_data->csr,
+			byte_cntr_data->irqctrl_offset,
+			USB_BLK_SIZE / 8);
+
+	atomic_set(&byte_cntr_data->irq_cnt, 0);
+	mutex_unlock(&byte_cntr_data->usb_bypass_lock);
+
+	return 0;
+}
+
+static void usb_bypass_stop(struct byte_cntr *byte_cntr_data)
+{
+	if (!byte_cntr_data)
+		return;
+
+	mutex_lock(&byte_cntr_data->usb_bypass_lock);
+	if (byte_cntr_data->read_active)
+		byte_cntr_data->read_active = false;
+	else {
+		mutex_unlock(&byte_cntr_data->usb_bypass_lock);
+		return;
+	}
+	wake_up(&byte_cntr_data->usb_wait_wq);
+	pr_info("coresight: stop usb bypass\n");
+	coresight_csr_set_byte_cntr(byte_cntr_data->csr, byte_cntr_data->irqctrl_offset, 0);
+	mutex_unlock(&byte_cntr_data->usb_bypass_lock);
+
+}
+
+static int usb_transfer_small_packet(struct byte_cntr *drvdata, size_t *small_size)
+{
+	int ret = 0;
+	struct tmc_drvdata *tmcdrvdata = drvdata->tmcdrvdata;
+	struct etr_buf *etr_buf = tmcdrvdata->sysfs_buf;
+	struct qdss_request *usb_req = NULL;
+	size_t req_size;
+	long actual;
+	long w_offset;
+
+	w_offset = tmc_get_rwp_offset(tmcdrvdata);
+	if (w_offset < 0) {
+		ret = w_offset;
+		dev_err_ratelimited(&tmcdrvdata->csdev->dev,
+			"%s: RWP offset is invalid\n", __func__);
+		goto out;
+	}
+
+	req_size = ((w_offset < drvdata->offset) ? etr_buf->size : 0) +
+				w_offset - drvdata->offset;
+
+	/*
+	 * Byte-cntr irq number may mismatch with the data size in ETR sink.
+	 * When irq_cnt is 0 and pending data size is more than block size,
+	 * calculate the irq_cnt by SW.
+	 */
+	if (req_size + *small_size >= USB_BLK_SIZE
+			&& atomic_read(&drvdata->irq_cnt) == 0) {
+		atomic_set(&drvdata->irq_cnt, (req_size + *small_size)/USB_BLK_SIZE);
+		goto out;
+	}
+
+	while (req_size > 0) {
+
+		usb_req = kzalloc(sizeof(*usb_req), GFP_KERNEL);
+		if (!usb_req) {
+			ret = -EFAULT;
+			goto out;
+		}
+
+		actual = tmc_etr_buf_get_data(etr_buf, drvdata->offset,
+					req_size, &usb_req->buf);
+
+		if (actual <= 0 || actual > req_size) {
+			kfree(usb_req);
+			usb_req = NULL;
+			dev_err_ratelimited(&tmcdrvdata->csdev->dev,
+				"%s: Invalid data in ETR\n", __func__);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		usb_req->length = actual;
+		drvdata->usb_req = usb_req;
+		req_size -= actual;
+
+		if ((drvdata->offset + actual) >=
+				tmcdrvdata->sysfs_buf->size)
+			drvdata->offset = 0;
+		else
+			drvdata->offset += actual;
+
+		*small_size += actual;
+
+		if (atomic_read(&drvdata->usb_free_buf) > 0) {
+			ret = usb_qdss_write(tmcdrvdata->usb_data->usbch, usb_req);
+
+			if (ret) {
+				kfree(usb_req);
+				usb_req = NULL;
+				drvdata->usb_req = NULL;
+				dev_err_ratelimited(&tmcdrvdata->csdev->dev,
+					"Write data failed:%d\n", ret);
+				goto out;
+			}
+
+			atomic_dec(&drvdata->usb_free_buf);
+		} else {
+			dev_err(&tmcdrvdata->csdev->dev,
+			"Drop data, offset = %ld, len = %ld\n",
+				drvdata->offset, req_size);
+			kfree(usb_req);
+			drvdata->usb_req = NULL;
+		}
+	}
+
+out:
+	return ret;
+}
+
+static void usb_read_work_fn(struct work_struct *work)
+{
+	int ret, i, seq = 0;
+	struct qdss_request *usb_req = NULL;
+	size_t req_size, req_sg_num, small_size = 0;
+	long actual;
+	ssize_t actual_total = 0;
+	char *buf;
+	struct byte_cntr *drvdata =
+		container_of(work, struct byte_cntr, read_work);
+	struct tmc_drvdata *tmcdrvdata = drvdata->tmcdrvdata;
+	struct etr_buf *etr_buf = tmcdrvdata->sysfs_buf;
+
+	while (tmcdrvdata->mode == CS_MODE_SYSFS
+		&& tmcdrvdata->out_mode == TMC_ETR_OUT_MODE_USB) {
+		if (!atomic_read(&drvdata->irq_cnt)) {
+			ret =  wait_event_interruptible_timeout(
+				drvdata->usb_wait_wq,
+				atomic_read(&drvdata->irq_cnt) > 0
+				|| tmcdrvdata->mode != CS_MODE_SYSFS || tmcdrvdata->out_mode
+				!= TMC_ETR_OUT_MODE_USB
+				|| !drvdata->read_active, USB_TIME_OUT);
+			if (ret == -ERESTARTSYS || tmcdrvdata->mode != CS_MODE_SYSFS
+			|| tmcdrvdata->out_mode != TMC_ETR_OUT_MODE_USB
+			|| !drvdata->read_active)
+				break;
+
+			if (ret == 0) {
+				ret = usb_transfer_small_packet(drvdata, &small_size);
+				if (ret && ret != -EAGAIN)
+					return;
+				continue;
+			}
+		}
+
+		req_size = USB_BLK_SIZE - small_size;
+		small_size = 0;
+		actual_total = 0;
+
+		if (req_size > 0) {
+			seq++;
+			req_sg_num = (req_size - 1) / PAGE_SIZE + 1;
+			usb_req = kzalloc(sizeof(*usb_req), GFP_KERNEL);
+			if (!usb_req)
+				return;
+			usb_req->sg = kcalloc(req_sg_num,
+				sizeof(*(usb_req->sg)), GFP_KERNEL);
+			if (!usb_req->sg) {
+				kfree(usb_req);
+				usb_req = NULL;
+				return;
+			}
+
+			for (i = 0; i < req_sg_num; i++) {
+				actual = tmc_etr_buf_get_data(etr_buf,
+							drvdata->offset,
+							PAGE_SIZE, &buf);
+
+				if (actual <= 0 || actual > PAGE_SIZE) {
+					kfree(usb_req->sg);
+					kfree(usb_req);
+					usb_req = NULL;
+					dev_err_ratelimited(
+						&tmcdrvdata->csdev->dev,
+						"Invalid data in ETR\n");
+					return;
+				}
+
+				sg_set_buf(&usb_req->sg[i], buf, actual);
+
+				if (i == 0)
+					usb_req->buf = buf;
+				if (i == req_sg_num - 1)
+					sg_mark_end(&usb_req->sg[i]);
+
+				if ((drvdata->offset + actual) >=
+					tmcdrvdata->sysfs_buf->size)
+					drvdata->offset = 0;
+				else
+					drvdata->offset += actual;
+				actual_total += actual;
+			}
+
+			usb_req->length = actual_total;
+			drvdata->usb_req = usb_req;
+			usb_req->num_sgs = i;
+
+			if (atomic_read(&drvdata->usb_free_buf) > 0) {
+				ret = usb_qdss_write(tmcdrvdata->usb_data->usbch,
+						drvdata->usb_req);
+				if (ret) {
+					kfree(usb_req->sg);
+					kfree(usb_req);
+					usb_req = NULL;
+					drvdata->usb_req = NULL;
+					dev_err_ratelimited(
+						&tmcdrvdata->csdev->dev,
+						"Write data failed:%d\n", ret);
+					if (ret == -EAGAIN)
+						continue;
+					return;
+				}
+				atomic_dec(&drvdata->usb_free_buf);
+
+			} else {
+				dev_err(&tmcdrvdata->csdev->dev,
+				"Drop data, offset = %ld, seq = %d, irq = %d\n",
+					drvdata->offset, seq,
+					atomic_read(&drvdata->irq_cnt));
+				kfree(usb_req->sg);
+				kfree(usb_req);
+				drvdata->usb_req = NULL;
+			}
+		}
+
+		if (atomic_read(&drvdata->irq_cnt) > 0)
+			atomic_dec(&drvdata->irq_cnt);
+	}
+	dev_err(&tmcdrvdata->csdev->dev, "TMC has been stopped.\n");
+}
+
+static void usb_write_done(struct byte_cntr *drvdata,
+				   struct qdss_request *d_req)
+{
+	atomic_inc(&drvdata->usb_free_buf);
+	if (d_req->status)
+		pr_err_ratelimited("USB write failed err:%d\n", d_req->status);
+	kfree(d_req->sg);
+	kfree(d_req);
+}
+
+static int usb_bypass_init(struct byte_cntr *byte_cntr_data)
+{
+	byte_cntr_data->usb_wq = create_singlethread_workqueue("byte-cntr");
+	if (!byte_cntr_data->usb_wq)
+		return -ENOMEM;
+
+	byte_cntr_data->offset = 0;
+	mutex_init(&byte_cntr_data->usb_bypass_lock);
+	init_waitqueue_head(&byte_cntr_data->usb_wait_wq);
+	atomic_set(&byte_cntr_data->usb_free_buf, USB_BUF_NUM);
+	INIT_WORK(&(byte_cntr_data->read_work), usb_read_work_fn);
+
+	return 0;
+}
+
+void usb_notifier(void *priv, unsigned int event, struct qdss_request *d_req,
+		  struct usb_qdss_ch *ch)
+{
+	struct tmc_drvdata *drvdata = priv;
+	int ret = 0;
+
+	if (!drvdata)
+		return;
+
+	if (drvdata->out_mode != TMC_ETR_OUT_MODE_USB) {
+		dev_err(&drvdata->csdev->dev,
+		"%s: ETR is not USB mode.\n", __func__);
+		return;
+	}
+
+	switch (event) {
+	case USB_QDSS_CONNECT:
+		if (drvdata->mode == CS_MODE_DISABLED) {
+			dev_err_ratelimited(&drvdata->csdev->dev,
+				"%s: ETR is disabled.\n", __func__);
+			return;
+		}
+
+		if (drvdata->usb_data->usb_mode == TMC_ETR_USB_SW) {
+			ret = usb_bypass_start(drvdata->byte_cntr);
+			if (ret < 0)
+				return;
+
+			usb_qdss_alloc_req(ch, USB_BUF_NUM);
+			queue_work(drvdata->byte_cntr->usb_wq, &(drvdata->byte_cntr->read_work));
+		}
+		break;
+
+	case USB_QDSS_DISCONNECT:
+		if (drvdata->mode == CS_MODE_DISABLED) {
+			dev_err_ratelimited(&drvdata->csdev->dev,
+				 "%s: ETR is disabled.\n", __func__);
+			return;
+		}
+
+		if (drvdata->usb_data->usb_mode == TMC_ETR_USB_SW) {
+			usb_bypass_stop(drvdata->byte_cntr);
+			flush_work(&((drvdata->byte_cntr->read_work)));
+			usb_qdss_free_req(drvdata->usb_data->usbch);
+		}
+		break;
+
+	case USB_QDSS_DATA_WRITE_DONE:
+		if (drvdata->usb_data->usb_mode == TMC_ETR_USB_SW)
+			usb_write_done(drvdata->byte_cntr, d_req);
+		break;
+
+	default:
+		break;
+	}
+
+}
+
+static bool tmc_etr_support_usb_bypass(struct device *dev)
+{
+	return fwnode_property_present(dev->fwnode, "qcom,sw-usb");
+}
+
+int tmc_usb_enable(struct tmc_usb_data *usb_data)
+{
+	struct tmc_drvdata *tmcdrvdata;
+
+	if (!usb_data)
+		return -EINVAL;
+
+	tmcdrvdata = usb_data->tmcdrvdata;
+	if (usb_data->usb_mode == TMC_ETR_USB_SW)
+		usb_data->usbch = usb_qdss_open(USB_QDSS_CH_SW, tmcdrvdata, usb_notifier);
+
+	if (IS_ERR_OR_NULL(usb_data->usbch)) {
+		dev_err(&tmcdrvdata->csdev->dev, "usb_qdss_open failed for qdss.\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+void tmc_usb_disable(struct tmc_usb_data *usb_data)
+{
+	struct tmc_drvdata *tmcdrvdata = usb_data->tmcdrvdata;
+
+	if (usb_data->usb_mode == TMC_ETR_USB_SW)
+		usb_bypass_stop(tmcdrvdata->byte_cntr);
+
+	if (usb_data->usbch)
+		usb_qdss_close(usb_data->usbch);
+	else
+		dev_err(&tmcdrvdata->csdev->dev, "usb channel is null.\n");
+}
+
+int tmc_etr_usb_init(struct amba_device *adev,
+		     struct tmc_drvdata *drvdata)
+{
+	struct device *dev = &adev->dev;
+	struct tmc_usb_data *usb_data;
+	struct byte_cntr *byte_cntr_data;
+	int ret;
+
+	usb_data = devm_kzalloc(dev, sizeof(*usb_data), GFP_KERNEL);
+	if (!usb_data)
+		return -ENOMEM;
+
+	drvdata->usb_data = usb_data;
+	drvdata->usb_data->tmcdrvdata = drvdata;
+	byte_cntr_data = drvdata->byte_cntr;
+
+	if (tmc_etr_support_usb_bypass(dev)) {
+		usb_data->usb_mode = TMC_ETR_USB_SW;
+
+		if (!byte_cntr_data)
+			return -EINVAL;
+
+		ret = usb_bypass_init(byte_cntr_data);
+		if (ret)
+			return -EINVAL;
+
+		return 0;
+	}
+
+	usb_data->usb_mode = TMC_ETR_USB_NONE;
+	pr_err("%s: ETR usb property is not configured!\n", dev_name(dev));
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-tmc-usb.h
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-tmc-usb.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _CORESIGHT_TMC_USB_H
+#define _CORESIGHT_TMC_USB_H
+
+#include <linux/amba/bus.h>
+#include <linux/soc/qcom/usb_qdss.h>
+
+#define TMC_USB_BAM_PIPE_INDEX	0
+#define TMC_USB_BAM_NR_PIPES	2
+
+#define USB_QDSS_CH_SW	"qdss"
+
+enum tmc_etr_usb_mode {
+	TMC_ETR_USB_NONE,
+	TMC_ETR_USB_SW,
+};
+
+struct tmc_usb_data {
+	struct usb_qdss_ch	*usbch;
+	enum tmc_etr_usb_mode	usb_mode;
+	struct tmc_drvdata	*tmcdrvdata;
+};
+
+extern int tmc_usb_enable(struct tmc_usb_data *usb_data);
+extern void tmc_usb_disable(struct tmc_usb_data *usb_data);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-tmc.h
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-tmc.h
@@ -12,6 +12,9 @@
 #include <linux/miscdevice.h>
 #include <linux/mutex.h>
 #include <linux/refcount.h>
+#include "coresight-byte-cntr.h"
+#include "coresight-tmc-usb.h"
+#include "coresight-trace-id.h"
 
 #define TMC_RSZ			0x004
 #define TMC_STS			0x00c
@@ -135,11 +138,22 @@
 	ETR_MODE_FLAT,		/* Uses contiguous flat buffer */
 	ETR_MODE_ETR_SG,	/* Uses in-built TMC ETR SG mechanism */
 	ETR_MODE_CATU,		/* Use SG mechanism in CATU */
-	ETR_MODE_AUTO,		/* Use the default mechanism */
 };
 
 struct etr_buf_operations;
 
+enum tmc_etr_out_mode {
+	TMC_ETR_OUT_MODE_NONE,
+	TMC_ETR_OUT_MODE_MEM,
+	TMC_ETR_OUT_MODE_USB,
+};
+
+static const char * const str_tmc_etr_out_mode[] = {
+	[TMC_ETR_OUT_MODE_NONE]		= "none",
+	[TMC_ETR_OUT_MODE_MEM]		= "mem",
+	[TMC_ETR_OUT_MODE_USB]		= "usb",
+};
+
 /**
  * struct etr_buf - Details of the buffer used by ETR
  * refcount	; Number of sources currently using this etr_buf.
@@ -206,13 +220,19 @@
 	u32			mode;
 	enum tmc_config_type	config_type;
 	enum tmc_mem_intf_width	memwidth;
+	struct mutex		mem_lock;
 	u32			trigger_cntr;
 	u32			etr_caps;
-	enum etr_mode		etr_mode;
 	struct idr		idr;
 	struct mutex		idr_mutex;
 	struct etr_buf		*sysfs_buf;
+	struct byte_cntr	*byte_cntr;
+	struct coresight_csr	*csr;
+	const char		*csr_name;
 	struct etr_buf		*perf_buf;
+	enum tmc_etr_out_mode	out_mode;
+	struct tmc_usb_data	*usb_data;
+	u8			atid_refcnt[CORESIGHT_TRACE_ID_RES_TOP];
 };
 
 struct etr_buf_operations {
@@ -261,6 +281,8 @@
 void tmc_flush_and_stop(struct tmc_drvdata *drvdata);
 void tmc_enable_hw(struct tmc_drvdata *drvdata);
 void tmc_disable_hw(struct tmc_drvdata *drvdata);
+extern int tmc_etr_usb_init(struct amba_device *adev,
+		struct tmc_drvdata *drvdata);
 u32 tmc_get_memwidth_mask(struct tmc_drvdata *drvdata);
 
 /* ETB/ETF functions */
@@ -271,13 +293,20 @@
 
 ssize_t tmc_etb_get_sysfs_trace(struct tmc_drvdata *drvdata,
 				loff_t pos, size_t len, char **bufpp);
+ssize_t tmc_etr_buf_get_data(struct etr_buf *etr_buf,
+				u64 offset, size_t len, char **bufpp);
 /* ETR functions */
 int tmc_read_prepare_etr(struct tmc_drvdata *drvdata);
 int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata);
 void tmc_etr_disable_hw(struct tmc_drvdata *drvdata);
+struct byte_cntr *byte_cntr_init(struct amba_device *adev,
+					struct tmc_drvdata *drvdata);
+void byte_cntr_remove(struct byte_cntr *byte_cntr);
 extern const struct coresight_ops tmc_etr_cs_ops;
 ssize_t tmc_etr_get_sysfs_trace(struct tmc_drvdata *drvdata,
 				loff_t pos, size_t len, char **bufpp);
+long tmc_get_rwp_offset(struct tmc_drvdata *drvdata);
+int tmc_etr_switch_mode(struct tmc_drvdata *drvdata, const char *out_mode);
 
 
 #define TMC_REG_PAIR(name, lo_off, hi_off)				\
@@ -336,6 +365,5 @@
 void tmc_etr_remove_catu_ops(void);
 struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev,
 				   enum cs_mode mode, void *data);
-extern const struct attribute_group coresight_etr_group;
 
 #endif
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-tpda.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-tpda.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/amba/bus.h>
@@ -18,6 +18,7 @@
 #include "coresight-priv.h"
 #include "coresight-tpda.h"
 #include "coresight-trace-id.h"
+#include "coresight-tpdm.h"
 
 DEFINE_CORESIGHT_DEVLIST(tpda_devs, "tpda");
 
@@ -28,24 +29,59 @@
 			CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
 }
 
+static void tpda_clear_element_size(struct coresight_device *csdev)
+{
+	struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+	drvdata->dsb_esize = 0;
+	drvdata->cmb_esize = 0;
+}
+
+static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32 *val)
+{
+	/* Clear all relevant fields */
+	*val &= ~(TPDA_Pn_CR_DSBSIZE | TPDA_Pn_CR_CMBSIZE);
+
+	if (drvdata->dsb_esize == 64)
+		*val |= TPDA_Pn_CR_DSBSIZE;
+	else if (drvdata->dsb_esize == 32)
+		*val &= ~TPDA_Pn_CR_DSBSIZE;
+
+	if (drvdata->cmb_esize == 64)
+		*val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
+	else if (drvdata->cmb_esize == 32)
+		*val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
+	else if (drvdata->cmb_esize == 8)
+		*val &= ~TPDA_Pn_CR_CMBSIZE;
+}
+
 /*
- * Read the DSB element size from the TPDM device
+ * Read the element size from the TPDM device. One TPDM must have at least one of the
+ * element size property.
  * Returns
- *    The dsb element size read from the devicetree if available.
- *    0 - Otherwise, with a warning once.
+ *    0 - The element size property is read
+ *    Others - Cannot read the property of the element size
  */
-static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
+static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
+				  struct coresight_device *csdev)
 {
-	int rc = 0;
-	u8 size = 0;
+	int rc = -EINVAL;
+	struct tpdm_drvdata *tpdm_data = dev_get_drvdata(csdev->dev.parent);
+
+	if (tpdm_has_dsb_dataset(tpdm_data)) {
+		rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
+				"qcom,dsb-element-bits", &drvdata->dsb_esize);
+	}
+	if (tpdm_has_cmb_dataset(tpdm_data)) {
+		rc = fwnode_property_read_u32(dev_fwnode(csdev->dev.parent),
+				"qcom,cmb-element-bits", &drvdata->cmb_esize);
+	}
 
-	rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
-			"qcom,dsb-element-size", &size);
 	if (rc)
 		dev_warn_once(&csdev->dev,
-			"Failed to read TPDM DSB Element size: %d\n", rc);
+			"Failed to read TPDM Element size: %d\n", rc);
 
-	return size;
+	return rc;
 }
 
 /*
@@ -56,11 +92,12 @@
  * Parameter "inport" is used to pass in the input port number
  * of TPDA, and it is set to -1 in the recursize call.
  */
-static int tpda_get_element_size(struct coresight_device *csdev,
+static int tpda_get_element_size(struct tpda_drvdata *drvdata,
+				 struct coresight_device *csdev,
 				 int inport)
 {
-	int dsb_size = -ENOENT;
-	int i, size;
+	int rc = 0;
+	int i;
 	struct coresight_device *in;
 
 	for (i = 0; i < csdev->pdata->nr_inconns; i++) {
@@ -69,30 +106,26 @@
 			continue;
 
 		/* Ignore the paths that do not match port */
-		if (inport > 0 &&
+		if (inport >= 0 &&
 		    csdev->pdata->in_conns[i]->dest_port != inport)
 			continue;
 
 		if (coresight_device_is_tpdm(in)) {
-			size = tpdm_read_dsb_element_size(in);
+			if (drvdata->dsb_esize || drvdata->cmb_esize)
+				return -EEXIST;
+			rc = tpdm_read_element_size(drvdata, in);
+			if (rc)
+				return rc;
 		} else {
 			/* Recurse down the path */
-			size = tpda_get_element_size(in, -1);
-		}
-
-		if (size < 0)
-			return size;
-
-		if (dsb_size < 0) {
-			/* Found a size, save it. */
-			dsb_size = size;
-		} else {
-			/* Found duplicate TPDMs */
-			return -EEXIST;
+			rc = tpda_get_element_size(drvdata, in, -1);
+			if (rc)
+				return rc;
 		}
 	}
 
-	return dsb_size;
+
+	return rc;
 }
 
 /* Settings pre enabling port control register */
@@ -109,37 +142,24 @@
 static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
 {
 	u32 val;
-	int size;
+	int rc;
 
 	val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
-	/*
-	 * Configure aggregator port n DSB data set element size
-	 * Set the bit to 0 if the size is 32
-	 * Set the bit to 1 if the size is 64
-	 */
-	size = tpda_get_element_size(drvdata->csdev, port);
-	switch (size) {
-	case 32:
-		val &= ~TPDA_Pn_CR_DSBSIZE;
-		break;
-	case 64:
-		val |= TPDA_Pn_CR_DSBSIZE;
-		break;
-	case 0:
-		return -EEXIST;
-	case -EEXIST:
+	tpda_clear_element_size(drvdata->csdev);
+	rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
+	if (!rc && (drvdata->dsb_esize || drvdata->cmb_esize)) {
+		tpda_set_element_size(drvdata, &val);
+		/* Enable the port */
+		val |= TPDA_Pn_CR_ENA;
+		writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
+	} else if (rc == -EEXIST)
 		dev_warn_once(&drvdata->csdev->dev,
-			"Detected multiple TPDMs on port %d", -EEXIST);
-		return -EEXIST;
-	default:
-		return -EINVAL;
-	}
-
-	/* Enable the port */
-	val |= TPDA_Pn_CR_ENA;
-	writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
+			      "Detected multiple TPDMs on port %d", port);
+	else
+		dev_warn_once(&drvdata->csdev->dev,
+			      "Didn't find TPDM element size");
 
-	return 0;
+	return rc;
 }
 
 static int __tpda_enable(struct tpda_drvdata *drvdata, int port)
@@ -224,7 +244,7 @@
 	 * same trace-id. When TPDA does packetization, different
 	 * port will have unique channel number for decoding.
 	 */
-	atid = coresight_trace_id_get_system_id();
+	atid = coresight_trace_id_get_system_id(TRACE_ID_ANY);
 	if (atid < 0)
 		return atid;
 
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-tpda.h
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-tpda.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CORESIGHT_CORESIGHT_TPDA_H
@@ -10,6 +10,8 @@
 #define TPDA_Pn_CR(n)		(0x004 + (n * 4))
 /* Aggregator port enable bit */
 #define TPDA_Pn_CR_ENA		BIT(0)
+/* Aggregator port CMB data set element size bit */
+#define TPDA_Pn_CR_CMBSIZE		GENMASK(7, 6)
 /* Aggregator port DSB data set element size bit */
 #define TPDA_Pn_CR_DSBSIZE		BIT(8)
 
@@ -25,6 +27,8 @@
  * @csdev:      component vitals needed by the framework.
  * @spinlock:   lock for the drvdata value.
  * @enable:     enable status of the component.
+ * @dsb_esize   Record the DSB element size.
+ * @cmb_esize   Record the CMB element size.
  */
 struct tpda_drvdata {
 	void __iomem		*base;
@@ -32,6 +36,8 @@
 	struct coresight_device	*csdev;
 	spinlock_t		spinlock;
 	u8			atid;
+	u32			dsb_esize;
+	u32			cmb_esize;
 };
 
 #endif  /* _CORESIGHT_CORESIGHT_TPDA_H */
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-tpdm.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -18,9 +18,15 @@
 
 #include "coresight-priv.h"
 #include "coresight-tpdm.h"
+#include "coresight-common.h"
+#include "coresight-tpda.h"
+
+#define TPDA_KEY	"tpda"
 
 DEFINE_CORESIGHT_DEVLIST(tpdm_devs, "tpdm");
 
+static int coresight_get_aggre_atid(struct coresight_device *csdev);
+
 /* Read dataset array member with the index number */
 static ssize_t tpdm_simple_dataset_show(struct device *dev,
 					struct device_attribute *attr,
@@ -66,6 +72,31 @@
 			return -EINVAL;
 		return sysfs_emit(buf, "0x%x\n",
 				drvdata->dsb->msr[tpdm_attr->idx]);
+	case CMB_TRIG_PATT:
+		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+			drvdata->cmb->trig_patt[tpdm_attr->idx]);
+	case CMB_TRIG_PATT_MASK:
+		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+			drvdata->cmb->trig_patt_mask[tpdm_attr->idx]);
+	case CMB_PATT:
+		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+			drvdata->cmb->patt_val[tpdm_attr->idx]);
+	case CMB_PATT_MASK:
+		if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+			drvdata->cmb->patt_mask[tpdm_attr->idx]);
+	case CMB_MSR:
+		if (tpdm_attr->idx >= drvdata->cmb_msr_num)
+			return -EINVAL;
+		return sysfs_emit(buf, "0x%x\n",
+				drvdata->cmb->msr[tpdm_attr->idx]);
 	}
 	return -EINVAL;
 }
@@ -77,67 +108,103 @@
 					 size_t size)
 {
 	unsigned long val;
-	ssize_t ret = size;
+	ssize_t ret = -EINVAL;
 
 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 	struct tpdm_dataset_attribute *tpdm_attr =
 		container_of(attr, struct tpdm_dataset_attribute, attr);
 
 	if (kstrtoul(buf, 0, &val))
-		return -EINVAL;
+		return ret;
 
-	spin_lock(&drvdata->spinlock);
+	guard(spinlock)(&drvdata->spinlock);
 	switch (tpdm_attr->mem) {
 	case DSB_TRIG_PATT:
-		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
+		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
 			drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
 		break;
 	case DSB_TRIG_PATT_MASK:
-		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
+		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
 			drvdata->dsb->trig_patt_mask[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
 		break;
 	case DSB_PATT:
-		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
+		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
 			drvdata->dsb->patt_val[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
 		break;
 	case DSB_PATT_MASK:
-		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
+		if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
 			drvdata->dsb->patt_mask[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
 		break;
 	case DSB_MSR:
-		if (tpdm_attr->idx < drvdata->dsb_msr_num)
+		if (tpdm_attr->idx < drvdata->dsb_msr_num) {
 			drvdata->dsb->msr[tpdm_attr->idx] = val;
-		else
-			ret = -EINVAL;
+			ret = size;
+		}
+		break;
+	case CMB_TRIG_PATT:
+		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
+			drvdata->cmb->trig_patt[tpdm_attr->idx] = val;
+			ret = size;
+		}
+		break;
+	case CMB_TRIG_PATT_MASK:
+		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
+			drvdata->cmb->trig_patt_mask[tpdm_attr->idx] = val;
+			ret = size;
+		}
+		break;
+	case CMB_PATT:
+		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
+			drvdata->cmb->patt_val[tpdm_attr->idx] = val;
+			ret = size;
+		}
+		break;
+	case CMB_PATT_MASK:
+		if (tpdm_attr->idx < TPDM_CMB_MAX_PATT) {
+			drvdata->cmb->patt_mask[tpdm_attr->idx] = val;
+			ret = size;
+		}
+		break;
+	case CMB_MSR:
+		if (tpdm_attr->idx < drvdata->cmb_msr_num) {
+			drvdata->cmb->msr[tpdm_attr->idx] = val;
+			ret = size;
+		}
 		break;
 	default:
-		ret = -EINVAL;
+		break;
 	}
-	spin_unlock(&drvdata->spinlock);
 
 	return ret;
 }
 
-static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
+static umode_t tpdm_dsb_is_visible(struct kobject *kobj,
+				   struct attribute *attr, int n)
 {
-	return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
+	struct device *dev = kobj_to_dev(kobj);
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	if (drvdata && tpdm_has_dsb_dataset(drvdata))
+		return attr->mode;
+
+	return 0;
 }
 
-static umode_t tpdm_dsb_is_visible(struct kobject *kobj,
+static umode_t tpdm_cmb_is_visible(struct kobject *kobj,
 				   struct attribute *attr, int n)
 {
 	struct device *dev = kobj_to_dev(kobj);
 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
 
-	if (drvdata && tpdm_has_dsb_dataset(drvdata))
+	if (drvdata && tpdm_has_cmb_dataset(drvdata))
 		return attr->mode;
 
 	return 0;
@@ -159,6 +226,23 @@
 	return 0;
 }
 
+static umode_t tpdm_cmb_msr_is_visible(struct kobject *kobj,
+				       struct attribute *attr, int n)
+{
+	struct device *dev = kobj_to_dev(kobj);
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	struct device_attribute *dev_attr =
+		container_of(attr, struct device_attribute, attr);
+	struct tpdm_dataset_attribute *tpdm_attr =
+		container_of(dev_attr, struct tpdm_dataset_attribute, attr);
+
+	if (tpdm_attr->idx < drvdata->cmb_msr_num)
+		return attr->mode;
+
+	return 0;
+}
+
 static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
 {
 	if (tpdm_has_dsb_dataset(drvdata)) {
@@ -167,6 +251,9 @@
 		drvdata->dsb->trig_ts = true;
 		drvdata->dsb->trig_type = false;
 	}
+
+	if (drvdata->cmb)
+		memset(drvdata->cmb, 0, sizeof(struct cmb_dataset));
 }
 
 static void set_dsb_mode(struct tpdm_drvdata *drvdata, u32 *val)
@@ -233,25 +320,27 @@
 {
 	u32 val, i;
 
+	if (!tpdm_has_dsb_dataset(drvdata))
+		return;
+
 	for (i = 0; i < TPDM_DSB_MAX_EDCR; i++)
 		writel_relaxed(drvdata->dsb->edge_ctrl[i],
-			   drvdata->base + TPDM_DSB_EDCR(i));
+			       drvdata->base + TPDM_DSB_EDCR(i));
 	for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++)
 		writel_relaxed(drvdata->dsb->edge_ctrl_mask[i],
-			   drvdata->base + TPDM_DSB_EDCMR(i));
+			       drvdata->base + TPDM_DSB_EDCMR(i));
 	for (i = 0; i < TPDM_DSB_MAX_PATT; i++) {
 		writel_relaxed(drvdata->dsb->patt_val[i],
-			   drvdata->base + TPDM_DSB_TPR(i));
+			       drvdata->base + TPDM_DSB_TPR(i));
 		writel_relaxed(drvdata->dsb->patt_mask[i],
-			   drvdata->base + TPDM_DSB_TPMR(i));
+			       drvdata->base + TPDM_DSB_TPMR(i));
 		writel_relaxed(drvdata->dsb->trig_patt[i],
-			   drvdata->base + TPDM_DSB_XPR(i));
+			       drvdata->base + TPDM_DSB_XPR(i));
 		writel_relaxed(drvdata->dsb->trig_patt_mask[i],
-			   drvdata->base + TPDM_DSB_XPMR(i));
+			       drvdata->base + TPDM_DSB_XPMR(i));
 	}
 
 	set_dsb_tier(drvdata);
-
 	set_dsb_msr(drvdata);
 
 	val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
@@ -267,6 +356,76 @@
 	writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
 }
 
+static void set_cmb_tier(struct tpdm_drvdata *drvdata)
+{
+	u32 val;
+
+	val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
+
+	/* Clear all relevant fields */
+	val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
+		 TPDM_CMB_TIER_XTRIG_TSENAB);
+
+	/* Set pattern timestamp type and enablement */
+	if (drvdata->cmb->patt_ts)
+		val |= TPDM_CMB_TIER_PATT_TSENAB;
+
+	/* Set trigger timestamp */
+	if (drvdata->cmb->trig_ts)
+		val |= TPDM_CMB_TIER_XTRIG_TSENAB;
+
+	/* Set all timestamp enablement*/
+	if (drvdata->cmb->ts_all)
+		val |= TPDM_CMB_TIER_TS_ALL;
+
+	writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
+}
+
+static void set_cmb_msr(struct tpdm_drvdata *drvdata)
+{
+	int i;
+
+	for (i = 0; i < drvdata->cmb_msr_num; i++)
+		writel_relaxed(drvdata->cmb->msr[i],
+			   drvdata->base + TPDM_CMB_MSR(i));
+}
+
+static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
+{
+	u32 val, i;
+
+	if (!tpdm_has_cmb_dataset(drvdata))
+		return;
+
+	/* Configure pattern registers */
+	for (i = 0; i < TPDM_CMB_MAX_PATT; i++) {
+		writel_relaxed(drvdata->cmb->patt_val[i],
+			drvdata->base + TPDM_CMB_TPR(i));
+		writel_relaxed(drvdata->cmb->patt_mask[i],
+			drvdata->base + TPDM_CMB_TPMR(i));
+		writel_relaxed(drvdata->cmb->trig_patt[i],
+			drvdata->base + TPDM_CMB_XPR(i));
+		writel_relaxed(drvdata->cmb->trig_patt_mask[i],
+			drvdata->base + TPDM_CMB_XPMR(i));
+	}
+
+	set_cmb_tier(drvdata);
+	set_cmb_msr(drvdata);
+
+	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
+	/*
+	 * Set to 0 for continuous CMB collection mode,
+	 * 1 for trace-on-change CMB collection mode.
+	 */
+	if (drvdata->cmb->trace_mode)
+		val |= TPDM_CMB_CR_MODE;
+	else
+		val &= ~TPDM_CMB_CR_MODE;
+	/* Set the enable bit of CMB control register to 1 */
+	val |= TPDM_CMB_CR_ENA;
+	writel_relaxed(val, drvdata->base + TPDM_CMB_CR);
+}
+
 /*
  * TPDM enable operations
  * The TPDM or Monitor serves as data collection component for various
@@ -279,8 +438,8 @@
 {
 	CS_UNLOCK(drvdata->base);
 
-	if (tpdm_has_dsb_dataset(drvdata))
-		tpdm_enable_dsb(drvdata);
+	tpdm_enable_dsb(drvdata);
+	tpdm_enable_cmb(drvdata);
 
 	CS_LOCK(drvdata->base);
 }
@@ -289,6 +448,7 @@
 		       enum cs_mode mode)
 {
 	struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+	int ret = -EINVAL;
 
 	spin_lock(&drvdata->spinlock);
 	if (drvdata->enable) {
@@ -296,6 +456,19 @@
 		return -EBUSY;
 	}
 
+	if (!coresight_take_mode(csdev, mode)) {
+		spin_unlock(&drvdata->spinlock);
+		return -EBUSY;
+	}
+
+	ret = coresight_get_aggre_atid(csdev);
+	if (ret < 0) {
+		spin_unlock(&drvdata->spinlock);
+		return ret;
+	}
+	drvdata->traceid = ret;
+	coresight_csr_set_etr_atid(csdev, drvdata->traceid, true);
+
 	__tpdm_enable(drvdata);
 	drvdata->enable = true;
 	spin_unlock(&drvdata->spinlock);
@@ -308,19 +481,35 @@
 {
 	u32 val;
 
+	if (!tpdm_has_dsb_dataset(drvdata))
+		return;
+
 	/* Set the enable bit of DSB control register to 0 */
 	val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
 	val &= ~TPDM_DSB_CR_ENA;
 	writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
 }
 
+static void tpdm_disable_cmb(struct tpdm_drvdata *drvdata)
+{
+	u32 val;
+
+	if (!tpdm_has_cmb_dataset(drvdata))
+		return;
+
+	val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
+	/* Set the enable bit of CMB control register to 0 */
+	val &= ~TPDM_CMB_CR_ENA;
+	writel_relaxed(val, drvdata->base + TPDM_CMB_CR);
+}
+
 /* TPDM disable operations */
 static void __tpdm_disable(struct tpdm_drvdata *drvdata)
 {
 	CS_UNLOCK(drvdata->base);
 
-	if (tpdm_has_dsb_dataset(drvdata))
-		tpdm_disable_dsb(drvdata);
+	tpdm_disable_dsb(drvdata);
+	tpdm_disable_cmb(drvdata);
 
 	CS_LOCK(drvdata->base);
 }
@@ -337,7 +526,10 @@
 	}
 
 	__tpdm_disable(drvdata);
+	coresight_set_mode(csdev, CS_MODE_DISABLED);
 	drvdata->enable = false;
+	coresight_csr_set_etr_atid(csdev, drvdata->traceid, false);
+	drvdata->traceid = 0;
 	spin_unlock(&drvdata->spinlock);
 
 	dev_dbg(drvdata->dev, "TPDM tracing disabled\n");
@@ -366,6 +558,12 @@
 		if (!drvdata->dsb)
 			return -ENOMEM;
 	}
+	if (tpdm_has_cmb_dataset(drvdata) && (!drvdata->cmb)) {
+		drvdata->cmb = devm_kzalloc(drvdata->dev,
+						sizeof(*drvdata->cmb), GFP_KERNEL);
+		if (!drvdata->cmb)
+			return -ENOMEM;
+	}
 	tpdm_reset_datasets(drvdata);
 
 	return 0;
@@ -431,9 +629,56 @@
 }
 static DEVICE_ATTR_WO(integration_test);
 
+static bool coresight_is_tpda_device(struct coresight_device *csdev)
+{
+	if (strnstr(dev_name(&csdev->dev), TPDA_KEY, strlen(dev_name(&csdev->dev))))
+		return true;
+
+	return false;
+}
+
+static int coresight_get_aggre_atid(struct coresight_device *csdev)
+{
+	int i, atid;
+	struct tpda_drvdata *tpda_drvdata;
+
+	if (coresight_is_tpda_device(csdev)) {
+		tpda_drvdata = dev_get_drvdata(csdev->dev.parent);
+		return tpda_drvdata->atid;
+	}
+
+	/*
+	 * Recursively explore each port found on this element.
+	 */
+	for (i = 0; i < csdev->pdata->nr_outconns; i++) {
+		struct coresight_device *child_dev;
+
+		child_dev = csdev->pdata->out_conns[i]->dest_dev;
+		if (child_dev)
+			atid = coresight_get_aggre_atid(child_dev);
+		if (atid > 0)
+			return atid;
+	}
+
+	return -EINVAL;
+}
+
+static ssize_t traceid_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	unsigned long atid;
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	atid = drvdata->traceid;
+
+	return scnprintf(buf, PAGE_SIZE, "%#lx\n", atid);
+}
+static DEVICE_ATTR_RO(traceid);
+
 static struct attribute *tpdm_attrs[] = {
 	&dev_attr_reset_dataset.attr,
 	&dev_attr_integration_test.attr,
+	&dev_attr_traceid.attr,
 	NULL,
 };
 
@@ -577,9 +822,18 @@
 			      char *buf)
 {
 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	struct tpdm_dataset_attribute *tpdm_attr =
+		container_of(attr, struct tpdm_dataset_attribute, attr);
+	ssize_t size = -EINVAL;
 
-	return sysfs_emit(buf, "%u\n",
-			 (unsigned int)drvdata->dsb->patt_ts);
+	if (tpdm_attr->mem == DSB_PATT)
+		size = sysfs_emit(buf, "%u\n",
+				  (unsigned int)drvdata->dsb->patt_ts);
+	else if (tpdm_attr->mem == CMB_PATT)
+		size = sysfs_emit(buf, "%u\n",
+				  (unsigned int)drvdata->cmb->patt_ts);
+
+	return size;
 }
 
 /*
@@ -591,17 +845,23 @@
 			       size_t size)
 {
 	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	struct tpdm_dataset_attribute *tpdm_attr =
+		container_of(attr, struct tpdm_dataset_attribute, attr);
 	unsigned long val;
 
 	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
 		return -EINVAL;
 
-	spin_lock(&drvdata->spinlock);
-	drvdata->dsb->patt_ts = !!val;
-	spin_unlock(&drvdata->spinlock);
+	guard(spinlock)(&drvdata->spinlock);
+	if (tpdm_attr->mem == DSB_PATT)
+		drvdata->dsb->patt_ts = !!val;
+	else if (tpdm_attr->mem == CMB_PATT)
+		drvdata->cmb->patt_ts = !!val;
+	else
+		return -EINVAL;
+
 	return size;
 }
-static DEVICE_ATTR_RW(enable_ts);
 
 static ssize_t set_type_show(struct device *dev,
 			     struct device_attribute *attr,
@@ -704,6 +964,96 @@
 }
 static DEVICE_ATTR_RW(dsb_trig_ts);
 
+static ssize_t cmb_mode_show(struct device *dev,
+			     struct device_attribute *attr,
+			     char *buf)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	return sysfs_emit(buf, "%x\n", drvdata->cmb->trace_mode);
+
+}
+
+static ssize_t cmb_mode_store(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf,
+			      size_t size)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long trace_mode;
+
+	if (kstrtoul(buf, 0, &trace_mode) || (trace_mode & ~1UL))
+		return -EINVAL;
+
+	spin_lock(&drvdata->spinlock);
+	drvdata->cmb->trace_mode = trace_mode;
+	spin_unlock(&drvdata->spinlock);
+	return size;
+}
+static DEVICE_ATTR_RW(cmb_mode);
+
+static ssize_t cmb_ts_all_show(struct device *dev,
+			       struct device_attribute *attr,
+			       char *buf)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	return sysfs_emit(buf, "%u\n",
+			  (unsigned int)drvdata->cmb->ts_all);
+}
+
+static ssize_t cmb_ts_all_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf,
+				size_t size)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+
+	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
+		return -EINVAL;
+
+	guard(spinlock)(&drvdata->spinlock);
+	if (val)
+		drvdata->cmb->ts_all = true;
+	else
+		drvdata->cmb->ts_all = false;
+
+	return size;
+}
+static DEVICE_ATTR_RW(cmb_ts_all);
+
+static ssize_t cmb_trig_ts_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+	return sysfs_emit(buf, "%u\n",
+			  (unsigned int)drvdata->cmb->trig_ts);
+}
+
+static ssize_t cmb_trig_ts_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf,
+				 size_t size)
+{
+	struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+	unsigned long val;
+
+	if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
+		return -EINVAL;
+
+	guard(spinlock)(&drvdata->spinlock);
+	if (val)
+		drvdata->cmb->trig_ts = true;
+	else
+		drvdata->cmb->trig_ts = false;
+
+	return size;
+}
+static DEVICE_ATTR_RW(cmb_trig_ts);
+
 static struct attribute *tpdm_dsb_edge_attrs[] = {
 	&dev_attr_ctrl_idx.attr,
 	&dev_attr_ctrl_val.attr,
@@ -772,7 +1122,7 @@
 	DSB_PATT_MASK_ATTR(5),
 	DSB_PATT_MASK_ATTR(6),
 	DSB_PATT_MASK_ATTR(7),
-	&dev_attr_enable_ts.attr,
+	DSB_PATT_ENABLE_TS,
 	&dev_attr_set_type.attr,
 	NULL,
 };
@@ -813,6 +1163,59 @@
 	NULL,
 };
 
+static struct attribute *tpdm_cmb_trig_patt_attrs[] = {
+	CMB_TRIG_PATT_ATTR(0),
+	CMB_TRIG_PATT_ATTR(1),
+	CMB_TRIG_PATT_MASK_ATTR(0),
+	CMB_TRIG_PATT_MASK_ATTR(1),
+	NULL,
+};
+
+static struct attribute *tpdm_cmb_patt_attrs[] = {
+	CMB_PATT_ATTR(0),
+	CMB_PATT_ATTR(1),
+	CMB_PATT_MASK_ATTR(0),
+	CMB_PATT_MASK_ATTR(1),
+	CMB_PATT_ENABLE_TS,
+	NULL,
+};
+
+static struct attribute *tpdm_cmb_msr_attrs[] = {
+	CMB_MSR_ATTR(0),
+	CMB_MSR_ATTR(1),
+	CMB_MSR_ATTR(2),
+	CMB_MSR_ATTR(3),
+	CMB_MSR_ATTR(4),
+	CMB_MSR_ATTR(5),
+	CMB_MSR_ATTR(6),
+	CMB_MSR_ATTR(7),
+	CMB_MSR_ATTR(8),
+	CMB_MSR_ATTR(9),
+	CMB_MSR_ATTR(10),
+	CMB_MSR_ATTR(11),
+	CMB_MSR_ATTR(12),
+	CMB_MSR_ATTR(13),
+	CMB_MSR_ATTR(14),
+	CMB_MSR_ATTR(15),
+	CMB_MSR_ATTR(16),
+	CMB_MSR_ATTR(17),
+	CMB_MSR_ATTR(18),
+	CMB_MSR_ATTR(19),
+	CMB_MSR_ATTR(20),
+	CMB_MSR_ATTR(21),
+	CMB_MSR_ATTR(22),
+	CMB_MSR_ATTR(23),
+	CMB_MSR_ATTR(24),
+	CMB_MSR_ATTR(25),
+	CMB_MSR_ATTR(26),
+	CMB_MSR_ATTR(27),
+	CMB_MSR_ATTR(28),
+	CMB_MSR_ATTR(29),
+	CMB_MSR_ATTR(30),
+	CMB_MSR_ATTR(31),
+	NULL,
+};
+
 static struct attribute *tpdm_dsb_attrs[] = {
 	&dev_attr_dsb_mode.attr,
 	&dev_attr_dsb_trig_ts.attr,
@@ -820,6 +1223,13 @@
 	NULL,
 };
 
+static struct attribute *tpdm_cmb_attrs[] = {
+	&dev_attr_cmb_mode.attr,
+	&dev_attr_cmb_ts_all.attr,
+	&dev_attr_cmb_trig_ts.attr,
+	NULL,
+};
+
 static struct attribute_group tpdm_dsb_attr_grp = {
 	.attrs = tpdm_dsb_attrs,
 	.is_visible = tpdm_dsb_is_visible,
@@ -849,6 +1259,29 @@
 	.name = "dsb_msr",
 };
 
+static struct attribute_group tpdm_cmb_attr_grp = {
+	.attrs = tpdm_cmb_attrs,
+	.is_visible = tpdm_cmb_is_visible,
+};
+
+static struct attribute_group tpdm_cmb_trig_patt_grp = {
+	.attrs = tpdm_cmb_trig_patt_attrs,
+	.is_visible = tpdm_cmb_is_visible,
+	.name = "cmb_trig_patt",
+};
+
+static struct attribute_group tpdm_cmb_patt_grp = {
+	.attrs = tpdm_cmb_patt_attrs,
+	.is_visible = tpdm_cmb_is_visible,
+	.name = "cmb_patt",
+};
+
+static struct attribute_group tpdm_cmb_msr_grp = {
+	.attrs = tpdm_cmb_msr_attrs,
+	.is_visible = tpdm_cmb_msr_is_visible,
+	.name = "cmb_msr",
+};
+
 static const struct attribute_group *tpdm_attr_grps[] = {
 	&tpdm_attr_grp,
 	&tpdm_dsb_attr_grp,
@@ -856,6 +1289,10 @@
 	&tpdm_dsb_trig_patt_grp,
 	&tpdm_dsb_patt_grp,
 	&tpdm_dsb_msr_grp,
+	&tpdm_cmb_attr_grp,
+	&tpdm_cmb_trig_patt_grp,
+	&tpdm_cmb_patt_grp,
+	&tpdm_cmb_msr_grp,
 	NULL,
 };
 
@@ -894,6 +1331,10 @@
 		of_property_read_u32(drvdata->dev->of_node,
 			   "qcom,dsb-msrs-num", &drvdata->dsb_msr_num);
 
+	if (drvdata && tpdm_has_cmb_dataset(drvdata))
+		of_property_read_u32(drvdata->dev->of_node,
+			   "qcom,cmb-msrs-num", &drvdata->cmb_msr_num);
+
 	/* Set up coresight component description */
 	desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
 	if (!desc.name)
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-tpdm.h
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -9,6 +9,38 @@
 /* The max number of the datasets that TPDM supports */
 #define TPDM_DATASETS       7
 
+/* CMB Subunit Registers */
+#define TPDM_CMB_CR		(0xA00)
+/* CMB subunit timestamp insertion enable register */
+#define TPDM_CMB_TIER		(0xA04)
+/* CMB subunit timestamp pattern registers */
+#define TPDM_CMB_TPR(n)		(0xA08 + (n * 4))
+/* CMB subunit timestamp pattern mask registers */
+#define TPDM_CMB_TPMR(n)	(0xA10 + (n * 4))
+/* CMB subunit trigger pattern registers */
+#define TPDM_CMB_XPR(n)		(0xA18 + (n * 4))
+/* CMB subunit trigger pattern mask registers */
+#define TPDM_CMB_XPMR(n)	(0xA20 + (n * 4))
+/* CMB MSR register */
+#define TPDM_CMB_MSR(n)		(0xA80 + (n * 4))
+
+/* Enable bit for CMB subunit */
+#define TPDM_CMB_CR_ENA		BIT(0)
+/* Trace collection mode for CMB subunit */
+#define TPDM_CMB_CR_MODE	BIT(1)
+/* Timestamp control for pattern match */
+#define TPDM_CMB_TIER_PATT_TSENAB	BIT(0)
+/* CMB CTI timestamp request */
+#define TPDM_CMB_TIER_XTRIG_TSENAB	BIT(1)
+/* For timestamp fo all trace */
+#define TPDM_CMB_TIER_TS_ALL		BIT(2)
+
+/* Patten register number */
+#define TPDM_CMB_MAX_PATT		2
+
+/* MAX number of DSB MSR */
+#define TPDM_CMB_MAX_MSR 32
+
 /* DSB Subunit Registers */
 #define TPDM_DSB_CR		(0x780)
 #define TPDM_DSB_TIER		(0x784)
@@ -79,10 +111,12 @@
  *
  * PERIPHIDR0[0] : Fix to 1 if ImplDef subunit present, else 0
  * PERIPHIDR0[1] : Fix to 1 if DSB subunit present, else 0
+ * PERIPHIDR0[2] : Fix to 1 if CMB subunit present, else 0
  */
 
 #define TPDM_PIDR0_DS_IMPDEF	BIT(0)
 #define TPDM_PIDR0_DS_DSB	BIT(1)
+#define TPDM_PIDR0_DS_CMB	BIT(2)
 
 #define TPDM_DSB_MAX_LINES	256
 /* MAX number of EDCR registers */
@@ -113,6 +147,15 @@
 	   }								\
 	})[0].attr.attr)
 
+#define tpdm_patt_enable_ts(name, mem)				\
+	(&((struct tpdm_dataset_attribute[]) {			\
+	   {							\
+		__ATTR(name, 0644, enable_ts_show,		\
+		enable_ts_store),		\
+		mem,						\
+	   }							\
+	})[0].attr.attr)
+
 #define DSB_EDGE_CTRL_ATTR(nr)					\
 		tpdm_simple_dataset_ro(edcr##nr,		\
 		DSB_EDGE_CTRL, nr)
@@ -137,10 +180,38 @@
 		tpdm_simple_dataset_rw(tpmr##nr,		\
 		DSB_PATT_MASK, nr)
 
+#define DSB_PATT_ENABLE_TS					\
+		tpdm_patt_enable_ts(enable_ts,			\
+		DSB_PATT)
+
 #define DSB_MSR_ATTR(nr)					\
 		tpdm_simple_dataset_rw(msr##nr,			\
 		DSB_MSR, nr)
 
+#define CMB_TRIG_PATT_ATTR(nr)					\
+		tpdm_simple_dataset_rw(xpr##nr,			\
+		CMB_TRIG_PATT, nr)
+
+#define CMB_TRIG_PATT_MASK_ATTR(nr)				\
+		tpdm_simple_dataset_rw(xpmr##nr,		\
+		CMB_TRIG_PATT_MASK, nr)
+
+#define CMB_PATT_ATTR(nr)					\
+		tpdm_simple_dataset_rw(tpr##nr,			\
+		CMB_PATT, nr)
+
+#define CMB_PATT_MASK_ATTR(nr)					\
+		tpdm_simple_dataset_rw(tpmr##nr,		\
+		CMB_PATT_MASK, nr)
+
+#define CMB_PATT_ENABLE_TS					\
+		tpdm_patt_enable_ts(enable_ts,			\
+		CMB_PATT)
+
+#define CMB_MSR_ATTR(nr)					\
+		tpdm_simple_dataset_rw(msr##nr,			\
+		CMB_MSR, nr)
+
 /**
  * struct dsb_dataset - specifics associated to dsb dataset
  * @mode:             DSB programming mode
@@ -174,6 +245,30 @@
 };
 
 /**
+ * struct cmb_dataset
+ * @trace_mode:       Dataset collection mode
+ * @patt_val:         Save value for pattern
+ * @patt_mask:        Save value for pattern mask
+ * @trig_patt:        Save value for trigger pattern
+ * @trig_patt_mask:   Save value for trigger pattern mask
+ * @msr               Save value for MSR
+ * @patt_ts:          Indicates if pattern match for timestamp is enabled.
+ * @trig_ts:          Indicates if CTI trigger for timestamp is enabled.
+ * @ts_all:           Indicates if timestamp is enabled for all packets.
+ */
+struct cmb_dataset {
+	u32			trace_mode;
+	u32			patt_val[TPDM_CMB_MAX_PATT];
+	u32			patt_mask[TPDM_CMB_MAX_PATT];
+	u32			trig_patt[TPDM_CMB_MAX_PATT];
+	u32			trig_patt_mask[TPDM_CMB_MAX_PATT];
+	u32			msr[TPDM_CMB_MAX_MSR];
+	bool			patt_ts;
+	bool			trig_ts;
+	bool			ts_all;
+};
+
+/**
  * struct tpdm_drvdata - specifics associated to an TPDM component
  * @base:       memory mapped base address for this component.
  * @dev:        The device entity associated to this component.
@@ -182,7 +277,9 @@
  * @enable:     enable status of the component.
  * @datasets:   The datasets types present of the TPDM.
  * @dsb         Specifics associated to TPDM DSB.
+ * @cmb         Specifics associated to TPDM CMB.
  * @dsb_msr_num Number of MSR supported by DSB TPDM
+ * @cmb_msr_num Number of MSR supported by CMB TPDM
  */
 
 struct tpdm_drvdata {
@@ -193,7 +290,10 @@
 	bool			enable;
 	unsigned long		datasets;
 	struct dsb_dataset	*dsb;
+	struct cmb_dataset	*cmb;
 	u32			dsb_msr_num;
+	u32			cmb_msr_num;
+	u32			traceid;
 };
 
 /* Enumerate members of various datasets */
@@ -205,6 +305,11 @@
 	DSB_PATT,
 	DSB_PATT_MASK,
 	DSB_MSR,
+	CMB_TRIG_PATT,
+	CMB_TRIG_PATT_MASK,
+	CMB_PATT,
+	CMB_PATT_MASK,
+	CMB_MSR
 };
 
 /**
@@ -220,4 +325,13 @@
 	u32 idx;
 };
 
+static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
+{
+	return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
+}
+
+static bool tpdm_has_cmb_dataset(struct tpdm_drvdata *drvdata)
+{
+	return (drvdata->datasets & TPDM_PIDR0_DS_CMB);
+}
 #endif  /* _CORESIGHT_CORESIGHT_TPDM_H */
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-trace-id.c
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-trace-id.c
@@ -75,21 +75,26 @@
  * Allocate new ID and set in use
  *
  * if @preferred_id is a valid id then try to use that value if available.
- * if @preferred_id is not valid and @prefer_odd_id is true, try for odd id.
+ * if TRACE_ID_WANT_PREFERRED is set, @preferred_id must be free, otherwise return
+ * error -EINVAL.
+ * if @preferred_id is not valid and TRACE_ID_WANT_ODD is true, try for odd id.
  *
  * Otherwise allocate next available ID.
  */
 static int coresight_trace_id_alloc_new_id(struct coresight_trace_id_map *id_map,
-					   int preferred_id, bool prefer_odd_id)
+					   int preferred_id, unsigned int flags)
 {
 	int id = 0;
 
 	/* for backwards compatibility, cpu IDs may use preferred value */
-	if (IS_VALID_CS_TRACE_ID(preferred_id) &&
-	    !test_bit(preferred_id, id_map->used_ids)) {
-		id = preferred_id;
-		goto trace_id_allocated;
-	} else if (prefer_odd_id) {
+	if (IS_VALID_CS_TRACE_ID(preferred_id)) {
+		if (!test_bit(preferred_id, id_map->used_ids)) {
+			id = preferred_id;
+			goto trace_id_allocated;
+		} else if (WARN((flags & TRACE_ID_WANT_PREFERRED), "Trace ID %d is used.\n",
+					preferred_id))
+			return -EINVAL;
+	} else if (flags & TRACE_ID_WANT_ODD) {
 	/* may use odd ids to avoid preferred legacy cpu IDs */
 		id = coresight_trace_id_find_odd_id(id_map);
 		if (id)
@@ -175,7 +180,7 @@
 	 */
 	id = coresight_trace_id_alloc_new_id(id_map,
 					     CORESIGHT_LEGACY_CPU_TRACE_ID(cpu),
-					     false);
+					     TRACE_ID_ANY);
 	if (!IS_VALID_CS_TRACE_ID(id))
 		goto get_cpu_id_out_unlock;
 
@@ -222,14 +227,19 @@
 	DUMP_ID_MAP(id_map);
 }
 
-static int coresight_trace_id_map_get_system_id(struct coresight_trace_id_map *id_map)
+static int coresight_trace_id_map_get_system_id(struct coresight_trace_id_map *id_map,
+					int preferred_id)
 {
 	unsigned long flags;
 	int id;
+	unsigned int traceid_flags = 0;
 
 	spin_lock_irqsave(&id_map_lock, flags);
 	/* prefer odd IDs for system components to avoid legacy CPU IDS */
-	id = coresight_trace_id_alloc_new_id(id_map, 0, true);
+	traceid_flags = TRACE_ID_WANT_ODD;
+	traceid_flags |= preferred_id > 0 ? TRACE_ID_WANT_PREFERRED : 0;
+
+	id = coresight_trace_id_alloc_new_id(id_map, preferred_id, traceid_flags);
 	spin_unlock_irqrestore(&id_map_lock, flags);
 
 	DUMP_ID(id);
@@ -269,9 +279,9 @@
 }
 EXPORT_SYMBOL_GPL(coresight_trace_id_read_cpu_id);
 
-int coresight_trace_id_get_system_id(void)
+int coresight_trace_id_get_system_id(int id)
 {
-	return coresight_trace_id_map_get_system_id(&id_map_default);
+	return coresight_trace_id_map_get_system_id(&id_map_default, id);
 }
 EXPORT_SYMBOL_GPL(coresight_trace_id_get_system_id);
 
--- linux-qcom-6.8.0.orig/drivers/hwtracing/coresight/coresight-trace-id.h
+++ linux-qcom-6.8.0/drivers/hwtracing/coresight/coresight-trace-id.h
@@ -61,6 +61,12 @@
 	DECLARE_BITMAP(pend_rel_ids, CORESIGHT_TRACE_IDS_MAX);
 };
 
+enum trace_id_flags {
+	TRACE_ID_ANY = 0x0,
+	TRACE_ID_WANT_ODD = 0x1,
+	TRACE_ID_WANT_PREFERRED = 0x2,
+};
+
 /* Allocate and release IDs for a single default trace ID map */
 
 /**
@@ -118,9 +124,12 @@
  *
  * Used to allocate IDs for system trace sources such as STM.
  *
+ * @id: Preferred id value. If id is TRACE_ID_ANY, get a free id from id map.
+ * If id is greater than TRACE_ID_ANY, get a preferred id.
+ *
  * return: Trace ID or -EINVAL if allocation is impossible.
  */
-int coresight_trace_id_get_system_id(void);
+int coresight_trace_id_get_system_id(int id);
 
 /**
  * Release an allocated system trace ID.
--- linux-qcom-6.8.0.orig/drivers/hwtracing/intel_th/pci.c
+++ linux-qcom-6.8.0/drivers/hwtracing/intel_th/pci.c
@@ -290,6 +290,16 @@
 		.driver_data = (kernel_ulong_t)&intel_th_2x,
 	},
 	{
+		/* Meteor Lake-S CPU */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xae24),
+		.driver_data = (kernel_ulong_t)&intel_th_2x,
+	},
+	{
+		/* Meteor Lake-S */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7f26),
+		.driver_data = (kernel_ulong_t)&intel_th_2x,
+	},
+	{
 		/* Raptor Lake-S */
 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7a26),
 		.driver_data = (kernel_ulong_t)&intel_th_2x,
@@ -300,6 +310,26 @@
 		.driver_data = (kernel_ulong_t)&intel_th_2x,
 	},
 	{
+		/* Granite Rapids */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0963),
+		.driver_data = (kernel_ulong_t)&intel_th_2x,
+	},
+	{
+		/* Granite Rapids SOC */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3256),
+		.driver_data = (kernel_ulong_t)&intel_th_2x,
+	},
+	{
+		/* Sapphire Rapids SOC */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3456),
+		.driver_data = (kernel_ulong_t)&intel_th_2x,
+	},
+	{
+		/* Lunar Lake */
+		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa824),
+		.driver_data = (kernel_ulong_t)&intel_th_2x,
+	},
+	{
 		/* Alder Lake CPU */
 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f),
 		.driver_data = (kernel_ulong_t)&intel_th_2x,
--- linux-qcom-6.8.0.orig/drivers/hwtracing/ptt/hisi_ptt.c
+++ linux-qcom-6.8.0/drivers/hwtracing/ptt/hisi_ptt.c
@@ -998,6 +998,9 @@
 	int ret;
 	u32 val;
 
+	if (event->attr.type != hisi_ptt->hisi_ptt_pmu.type)
+		return -ENOENT;
+
 	if (event->cpu < 0) {
 		dev_dbg(event->pmu->dev, "Per-task mode not supported\n");
 		return -EOPNOTSUPP;
@@ -1006,9 +1009,6 @@
 	if (event->attach_state & PERF_ATTACH_TASK)
 		return -EOPNOTSUPP;
 
-	if (event->attr.type != hisi_ptt->hisi_ptt_pmu.type)
-		return -ENOENT;
-
 	ret = hisi_ptt_trace_valid_filter(hisi_ptt, event->attr.config);
 	if (ret < 0)
 		return ret;
--- linux-qcom-6.8.0.orig/drivers/hwtracing/stm/Kconfig
+++ linux-qcom-6.8.0/drivers/hwtracing/stm/Kconfig
@@ -48,6 +48,20 @@
 
 	  If you don't know what this is, say N.
 
+config STM_PROTO_OST
+	tristate "MIPI OST STM framing protocol driver"
+	default CONFIG_STM
+	help
+	  This is an implementation of MIPI OST protocol to be used
+	  over the STP transport. In addition to the data payload, it
+	  also carries additional metadata for entity, better
+	  means of trace source identification, etc.
+
+	  The receiving side must be able to decode this protocol in
+	  addition to the MIPI STP, in order to extract the data.
+
+	  If you don't know what this is, say N.
+
 config STM_SOURCE_CONSOLE
 	tristate "Kernel console over STM devices"
 	help
--- linux-qcom-6.8.0.orig/drivers/hwtracing/stm/Makefile
+++ linux-qcom-6.8.0/drivers/hwtracing/stm/Makefile
@@ -5,9 +5,11 @@
 
 obj-$(CONFIG_STM_PROTO_BASIC) += stm_p_basic.o
 obj-$(CONFIG_STM_PROTO_SYS_T) += stm_p_sys-t.o
+obj-$(CONFIG_STM_PROTO_OST) += stm_p_ost.o
 
 stm_p_basic-y		:= p_basic.o
 stm_p_sys-t-y		:= p_sys-t.o
+stm_p_ost-y		:= p_ost.o
 
 obj-$(CONFIG_STM_DUMMY)	+= dummy_stm.o
 
--- linux-qcom-6.8.0.orig/drivers/hwtracing/stm/core.c
+++ linux-qcom-6.8.0/drivers/hwtracing/stm/core.c
@@ -868,8 +868,11 @@
 		return -ENOMEM;
 
 	stm->major = register_chrdev(0, stm_data->name, &stm_fops);
-	if (stm->major < 0)
-		goto err_free;
+	if (stm->major < 0) {
+		err = stm->major;
+		vfree(stm);
+		return err;
+	}
 
 	device_initialize(&stm->dev);
 	stm->dev.devt = MKDEV(stm->major, 0);
@@ -913,10 +916,8 @@
 err_device:
 	unregister_chrdev(stm->major, stm_data->name);
 
-	/* matches device_initialize() above */
+	/* calls stm_device_release() */
 	put_device(&stm->dev);
-err_free:
-	vfree(stm);
 
 	return err;
 }
--- linux-qcom-6.8.0.orig/drivers/hwtracing/stm/p_ost.c
+++ linux-qcom-6.8.0/drivers/hwtracing/stm/p_ost.c
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ *
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * MIPI OST framing protocol for STM devices.
+ */
+
+#include <linux/configfs.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/stm.h>
+#include <linux/sched/clock.h>
+#include "stm.h"
+
+#define OST_TOKEN_STARTSIMPLE		(0x10)
+#define OST_VERSION_MIPI1		(0x10 << 8)
+#define OST_ENTITY_FTRACE		(0x01 << 16)
+#define OST_CONTROL_PROTOCOL		(0x0 << 24)
+
+#define DATA_HEADER (OST_TOKEN_STARTSIMPLE | OST_VERSION_MIPI1 | \
+			OST_ENTITY_FTRACE | OST_CONTROL_PROTOCOL)
+
+#define STM_MAKE_VERSION(ma, mi)	((ma << 8) | mi)
+#define STM_HEADER_MAGIC		(0x5953)
+
+static ssize_t notrace ost_write(struct stm_data *data,
+		struct stm_output *output, unsigned int chan,
+		const char *buf, size_t count)
+{
+	unsigned int c = output->channel + chan;
+	unsigned int m = output->master;
+	const unsigned char nil = 0;
+	u32 header = DATA_HEADER;
+	u8 trc_hdr[24];
+	ssize_t sz;
+
+	/*
+	 * STP framing rules for OST frames:
+	 *   * the first packet of the OST frame is marked;
+	 *   * the last packet is a FLAG.
+	 */
+	/* Message layout: HEADER / DATA / TAIL */
+	/* HEADER */
+
+	sz = data->packet(data, m, c, STP_PACKET_DATA, STP_PACKET_MARKED,
+			  4, (u8 *)&header);
+	if (sz <= 0)
+		return sz;
+	*(uint16_t *)(trc_hdr) = STM_MAKE_VERSION(0, 3);
+	*(uint16_t *)(trc_hdr + 2) = STM_HEADER_MAGIC;
+	*(uint32_t *)(trc_hdr + 4) = raw_smp_processor_id();
+	*(uint64_t *)(trc_hdr + 8) = sched_clock();
+	*(uint64_t *)(trc_hdr + 16) = task_tgid_nr(get_current());
+	sz = stm_data_write(data, m, c, false, trc_hdr, sizeof(trc_hdr));
+	if (sz <= 0)
+		return sz;
+
+	/* DATA */
+	sz = stm_data_write(data, m, c, false, buf, count);
+
+	/* TAIL */
+	if (sz > 0)
+		data->packet(data, m, c, STP_PACKET_FLAG,
+			STP_PACKET_TIMESTAMPED, 0, &nil);
+
+	return sz;
+}
+
+static const struct stm_protocol_driver ost_pdrv = {
+	.owner			= THIS_MODULE,
+	.name			= "p_ost",
+	.write			= ost_write,
+};
+
+static int ost_stm_init(void)
+{
+	return stm_register_protocol(&ost_pdrv);
+}
+
+static void ost_stm_exit(void)
+{
+	stm_unregister_protocol(&ost_pdrv);
+}
+
+module_init(ost_stm_init);
+module_exit(ost_stm_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MIPI Open System Trace STM framing protocol driver");
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/Kconfig
+++ linux-qcom-6.8.0/drivers/i2c/busses/Kconfig
@@ -159,6 +159,8 @@
 	    Raptor Lake (PCH)
 	    Meteor Lake (SOC and PCH)
 	    Birch Stream (SOC)
+	    Arrow Lake (SOC)
+	    Panther Lake (SOC)
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-i801.
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-aspeed.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-aspeed.c
@@ -170,6 +170,13 @@
 
 static int aspeed_i2c_reset(struct aspeed_i2c_bus *bus);
 
+/* precondition: bus.lock has been acquired. */
+static void aspeed_i2c_do_stop(struct aspeed_i2c_bus *bus)
+{
+	bus->master_state = ASPEED_I2C_MASTER_STOP;
+	writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG);
+}
+
 static int aspeed_i2c_recover_bus(struct aspeed_i2c_bus *bus)
 {
 	unsigned long time_left, flags;
@@ -187,7 +194,7 @@
 			command);
 
 		reinit_completion(&bus->cmd_complete);
-		writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG);
+		aspeed_i2c_do_stop(bus);
 		spin_unlock_irqrestore(&bus->lock, flags);
 
 		time_left = wait_for_completion_timeout(
@@ -391,13 +398,6 @@
 }
 
 /* precondition: bus.lock has been acquired. */
-static void aspeed_i2c_do_stop(struct aspeed_i2c_bus *bus)
-{
-	bus->master_state = ASPEED_I2C_MASTER_STOP;
-	writel(ASPEED_I2CD_M_STOP_CMD, bus->base + ASPEED_I2C_CMD_REG);
-}
-
-/* precondition: bus.lock has been acquired. */
 static void aspeed_i2c_next_msg_or_stop(struct aspeed_i2c_bus *bus)
 {
 	if (bus->msgs_index + 1 < bus->msgs_count) {
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-at91-slave.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-at91-slave.c
@@ -106,8 +106,7 @@
 
 static u32 at91_twi_func(struct i2c_adapter *adapter)
 {
-	return I2C_FUNC_SLAVE | I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL
-		| I2C_FUNC_SMBUS_READ_BLOCK_DATA;
+	return I2C_FUNC_SLAVE;
 }
 
 static const struct i2c_algorithm at91_twi_algorithm_slave = {
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-cadence.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-cadence.c
@@ -633,6 +633,7 @@
 
 	if (hold_clear) {
 		ctrl_reg &= ~CDNS_I2C_CR_HOLD;
+		ctrl_reg &= ~CDNS_I2C_CR_CLR_FIFO;
 		/*
 		 * In case of Xilinx Zynq SOC, clear the HOLD bit before transfer size
 		 * register reaches '0'. This is an IP bug which causes transfer size
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-designware-common.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-designware-common.c
@@ -441,7 +441,8 @@
 
 void __i2c_dw_disable(struct dw_i2c_dev *dev)
 {
-	unsigned int raw_intr_stats;
+	struct i2c_timings *t = &dev->timings;
+	unsigned int raw_intr_stats, ic_stats;
 	unsigned int enable;
 	int timeout = 100;
 	bool abort_needed;
@@ -449,10 +450,25 @@
 	int ret;
 
 	regmap_read(dev->map, DW_IC_RAW_INTR_STAT, &raw_intr_stats);
+	regmap_read(dev->map, DW_IC_STATUS, &ic_stats);
 	regmap_read(dev->map, DW_IC_ENABLE, &enable);
 
-	abort_needed = raw_intr_stats & DW_IC_INTR_MST_ON_HOLD;
+	abort_needed = (raw_intr_stats & DW_IC_INTR_MST_ON_HOLD) ||
+			(ic_stats & DW_IC_STATUS_MASTER_HOLD_TX_FIFO_EMPTY);
 	if (abort_needed) {
+		if (!(enable & DW_IC_ENABLE_ENABLE)) {
+			regmap_write(dev->map, DW_IC_ENABLE, DW_IC_ENABLE_ENABLE);
+			/*
+			 * Wait 10 times the signaling period of the highest I2C
+			 * transfer supported by the driver (for 400KHz this is
+			 * 25us) to ensure the I2C ENABLE bit is already set
+			 * as described in the DesignWare I2C databook.
+			 */
+			fsleep(DIV_ROUND_CLOSEST_ULL(10 * MICRO, t->bus_freq_hz));
+			/* Set ENABLE bit before setting ABORT */
+			enable |= DW_IC_ENABLE_ENABLE;
+		}
+
 		regmap_write(dev->map, DW_IC_ENABLE, enable | DW_IC_ENABLE_ABORT);
 		ret = regmap_read_poll_timeout(dev->map, DW_IC_ENABLE, enable,
 					       !(enable & DW_IC_ENABLE_ABORT), 10,
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-designware-core.h
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-designware-core.h
@@ -109,6 +109,7 @@
 						 DW_IC_INTR_RX_UNDER | \
 						 DW_IC_INTR_RD_REQ)
 
+#define DW_IC_ENABLE_ENABLE			BIT(0)
 #define DW_IC_ENABLE_ABORT			BIT(1)
 
 #define DW_IC_STATUS_ACTIVITY			BIT(0)
@@ -116,6 +117,7 @@
 #define DW_IC_STATUS_RFNE			BIT(3)
 #define DW_IC_STATUS_MASTER_ACTIVITY		BIT(5)
 #define DW_IC_STATUS_SLAVE_ACTIVITY		BIT(6)
+#define DW_IC_STATUS_MASTER_HOLD_TX_FIFO_EMPTY	BIT(7)
 
 #define DW_IC_SDA_HOLD_RX_SHIFT			16
 #define DW_IC_SDA_HOLD_RX_MASK			GENMASK(23, 16)
@@ -318,7 +320,7 @@
 #define AMD_UCSI_INTR_EN			0xd
 
 #define TXGBE_TX_FIFO_DEPTH			4
-#define TXGBE_RX_FIFO_DEPTH			0
+#define TXGBE_RX_FIFO_DEPTH			1
 
 struct i2c_dw_semaphore_callbacks {
 	int	(*probe)(struct dw_i2c_dev *dev);
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-designware-master.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-designware-master.c
@@ -253,6 +253,34 @@
 	regmap_write(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_MASTER_MASK);
 }
 
+/*
+ * This function waits for the controller to be idle before disabling I2C
+ * When the controller is not in the IDLE state, the MST_ACTIVITY bit
+ * (IC_STATUS[5]) is set.
+ *
+ * Values:
+ * 0x1 (ACTIVE): Controller not idle
+ * 0x0 (IDLE): Controller is idle
+ *
+ * The function is called after completing the current transfer.
+ *
+ * Returns:
+ * False when the controller is in the IDLE state.
+ * True when the controller is in the ACTIVE state.
+ */
+static bool i2c_dw_is_controller_active(struct dw_i2c_dev *dev)
+{
+	u32 status;
+
+	regmap_read(dev->map, DW_IC_STATUS, &status);
+	if (!(status & DW_IC_STATUS_MASTER_ACTIVITY))
+		return false;
+
+	return regmap_read_poll_timeout(dev->map, DW_IC_STATUS, status,
+				       !(status & DW_IC_STATUS_MASTER_ACTIVITY),
+				       1100, 20000) != 0;
+}
+
 static int i2c_dw_check_stopbit(struct dw_i2c_dev *dev)
 {
 	u32 val;
@@ -695,6 +723,16 @@
 	}
 
 	/*
+	 * This happens rarely (~1:500) and is hard to reproduce. Debug trace
+	 * showed that IC_STATUS had value of 0x23 when STOP_DET occurred,
+	 * if disable IC_ENABLE.ENABLE immediately that can result in
+	 * IC_RAW_INTR_STAT.MASTER_ON_HOLD holding SCL low. Check if
+	 * controller is still ACTIVE before disabling I2C.
+	 */
+	if (i2c_dw_is_controller_active(dev))
+		dev_err(dev->dev, "controller active\n");
+
+	/*
 	 * We must disable the adapter before returning and signaling the end
 	 * of the current transfer. Otherwise the hardware might continue
 	 * generating interrupts which in turn causes a race condition with
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-designware-slave.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-designware-slave.c
@@ -220,7 +220,7 @@
 
 void i2c_dw_configure_slave(struct dw_i2c_dev *dev)
 {
-	dev->functionality = I2C_FUNC_SLAVE | DW_IC_DEFAULT_FUNCTIONALITY;
+	dev->functionality = I2C_FUNC_SLAVE;
 
 	dev->slave_cfg = DW_IC_CON_RX_FIFO_FULL_HLD_CTRL |
 			 DW_IC_CON_RESTART_EN | DW_IC_CON_STOP_DET_IFADDRESSED;
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-i801.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-i801.c
@@ -80,6 +80,9 @@
  * Meteor Lake SoC-S (SOC)	0xae22	32	hard	yes	yes	yes
  * Meteor Lake PCH-S (PCH)	0x7f23	32	hard	yes	yes	yes
  * Birch Stream (SOC)		0x5796	32	hard	yes	yes	yes
+ * Arrow Lake-H (SOC)		0x7722	32	hard	yes	yes	yes
+ * Panther Lake-H (SOC)		0xe322	32	hard	yes	yes	yes
+ * Panther Lake-P (SOC)		0xe422	32	hard	yes	yes	yes
  *
  * Features supported by this driver:
  * Software PEC				no
@@ -234,6 +237,7 @@
 #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_M_SMBUS		0x54a3
 #define PCI_DEVICE_ID_INTEL_BIRCH_STREAM_SMBUS		0x5796
 #define PCI_DEVICE_ID_INTEL_BROXTON_SMBUS		0x5ad4
+#define PCI_DEVICE_ID_INTEL_ARROW_LAKE_H_SMBUS		0x7722
 #define PCI_DEVICE_ID_INTEL_RAPTOR_LAKE_S_SMBUS		0x7a23
 #define PCI_DEVICE_ID_INTEL_ALDER_LAKE_S_SMBUS		0x7aa3
 #define PCI_DEVICE_ID_INTEL_METEOR_LAKE_P_SMBUS		0x7e22
@@ -256,6 +260,8 @@
 #define PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS		0xa323
 #define PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS		0xa3a3
 #define PCI_DEVICE_ID_INTEL_METEOR_LAKE_SOC_S_SMBUS	0xae22
+#define PCI_DEVICE_ID_INTEL_PANTHER_LAKE_H_SMBUS	0xe322
+#define PCI_DEVICE_ID_INTEL_PANTHER_LAKE_P_SMBUS	0xe422
 
 struct i801_mux_config {
 	char *gpio_chip;
@@ -1040,13 +1046,16 @@
 	{ PCI_DEVICE_DATA(INTEL, METEOR_LAKE_SOC_S_SMBUS,	FEATURES_ICH5 | FEATURE_TCO_CNL) },
 	{ PCI_DEVICE_DATA(INTEL, METEOR_LAKE_PCH_S_SMBUS,	FEATURES_ICH5 | FEATURE_TCO_CNL) },
 	{ PCI_DEVICE_DATA(INTEL, BIRCH_STREAM_SMBUS,		FEATURES_ICH5 | FEATURE_TCO_CNL) },
+	{ PCI_DEVICE_DATA(INTEL, ARROW_LAKE_H_SMBUS,		FEATURES_ICH5 | FEATURE_TCO_CNL) },
+	{ PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_H_SMBUS,		FEATURES_ICH5 | FEATURE_TCO_CNL) },
+	{ PCI_DEVICE_DATA(INTEL, PANTHER_LAKE_P_SMBUS,		FEATURES_ICH5 | FEATURE_TCO_CNL) },
 	{ 0, }
 };
 
 MODULE_DEVICE_TABLE(pci, i801_ids);
 
 #if defined CONFIG_X86 && defined CONFIG_DMI
-static unsigned char apanel_addr;
+static unsigned char apanel_addr __ro_after_init;
 
 /* Scan the system ROM for the signature "FJKEYINF" */
 static __init const void __iomem *bios_signature(const void __iomem *bios)
@@ -1732,8 +1741,15 @@
 
 	i801_add_tco(priv);
 
+	/*
+	 * adapter.name is used by platform code to find the main I801 adapter
+	 * to instantiante i2c_clients, do not change.
+	 */
 	snprintf(priv->adapter.name, sizeof(priv->adapter.name),
-		"SMBus I801 adapter at %04lx", priv->smba);
+		 "SMBus %s adapter at %04lx",
+		 (priv->features & FEATURE_IDF) ? "I801 IDF" : "I801",
+		 priv->smba);
+
 	err = i2c_add_adapter(&priv->adapter);
 	if (err) {
 		platform_device_unregister(priv->tco_pdev);
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-imx-lpi2c.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-imx-lpi2c.c
@@ -99,6 +99,7 @@
 	__u8			*rx_buf;
 	__u8			*tx_buf;
 	struct completion	complete;
+	unsigned long		rate_per;
 	unsigned int		msglen;
 	unsigned int		delivered;
 	unsigned int		block_data;
@@ -207,9 +208,7 @@
 
 	lpi2c_imx_set_mode(lpi2c_imx);
 
-	clk_rate = clk_get_rate(lpi2c_imx->clks[0].clk);
-	if (!clk_rate)
-		return -EINVAL;
+	clk_rate = lpi2c_imx->rate_per;
 
 	if (lpi2c_imx->mode == HS || lpi2c_imx->mode == ULTRA_FAST)
 		filt = 0;
@@ -590,6 +589,20 @@
 	if (ret)
 		return ret;
 
+	/*
+	 * Lock the parent clock rate to avoid getting parent clock upon
+	 * each transfer
+	 */
+	ret = devm_clk_rate_exclusive_get(&pdev->dev, lpi2c_imx->clks[0].clk);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "can't lock I2C peripheral clock rate\n");
+
+	lpi2c_imx->rate_per = clk_get_rate(lpi2c_imx->clks[0].clk);
+	if (!lpi2c_imx->rate_per)
+		return dev_err_probe(&pdev->dev, -EINVAL,
+				     "can't get I2C peripheral clock rate\n");
+
 	pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT);
 	pm_runtime_use_autosuspend(&pdev->dev);
 	pm_runtime_get_noresume(&pdev->dev);
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-imx.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-imx.c
@@ -286,6 +286,7 @@
 	{ .compatible = "fsl,imx6sll-i2c", .data = &imx6_i2c_hwdata, },
 	{ .compatible = "fsl,imx6sx-i2c", .data = &imx6_i2c_hwdata, },
 	{ .compatible = "fsl,imx6ul-i2c", .data = &imx6_i2c_hwdata, },
+	{ .compatible = "fsl,imx7d-i2c", .data = &imx6_i2c_hwdata, },
 	{ .compatible = "fsl,imx7s-i2c", .data = &imx6_i2c_hwdata, },
 	{ .compatible = "fsl,imx8mm-i2c", .data = &imx6_i2c_hwdata, },
 	{ .compatible = "fsl,imx8mn-i2c", .data = &imx6_i2c_hwdata, },
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-isch.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-isch.c
@@ -99,8 +99,7 @@
 	if (retries > MAX_RETRIES) {
 		dev_err(&sch_adapter.dev, "SMBus Timeout!\n");
 		result = -ETIMEDOUT;
-	}
-	if (temp & 0x04) {
+	} else if (temp & 0x04) {
 		result = -EIO;
 		dev_dbg(&sch_adapter.dev, "Bus collision! SMBus may be "
 			"locked until next hard reset. (sorry!)\n");
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-microchip-corei2c.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-microchip-corei2c.c
@@ -93,27 +93,35 @@
  * @base:		pointer to register struct
  * @dev:		device reference
  * @i2c_clk:		clock reference for i2c input clock
+ * @msg_queue:		pointer to the messages requiring sending
  * @buf:		pointer to msg buffer for easier use
  * @msg_complete:	xfer completion object
  * @adapter:		core i2c abstraction
  * @msg_err:		error code for completed message
  * @bus_clk_rate:	current i2c bus clock rate
  * @isr_status:		cached copy of local ISR status
+ * @total_num:		total number of messages to be sent/received
+ * @current_num:	index of the current message being sent/received
  * @msg_len:		number of bytes transferred in msg
  * @addr:		address of the current slave
+ * @restart_needed:	whether or not a repeated start is required after current message
  */
 struct mchp_corei2c_dev {
 	void __iomem *base;
 	struct device *dev;
 	struct clk *i2c_clk;
+	struct i2c_msg *msg_queue;
 	u8 *buf;
 	struct completion msg_complete;
 	struct i2c_adapter adapter;
 	int msg_err;
+	int total_num;
+	int current_num;
 	u32 bus_clk_rate;
 	u32 isr_status;
 	u16 msg_len;
 	u8 addr;
+	bool restart_needed;
 };
 
 static void mchp_corei2c_core_disable(struct mchp_corei2c_dev *idev)
@@ -222,6 +230,47 @@
 	return 0;
 }
 
+static void mchp_corei2c_next_msg(struct mchp_corei2c_dev *idev)
+{
+	struct i2c_msg *this_msg;
+	u8 ctrl;
+
+	if (idev->current_num >= idev->total_num) {
+		complete(&idev->msg_complete);
+		return;
+	}
+
+	/*
+	 * If there's been an error, the isr needs to return control
+	 * to the "main" part of the driver, so as not to keep sending
+	 * messages once it completes and clears the SI bit.
+	 */
+	if (idev->msg_err) {
+		complete(&idev->msg_complete);
+		return;
+	}
+
+	this_msg = idev->msg_queue++;
+
+	if (idev->current_num < (idev->total_num - 1)) {
+		struct i2c_msg *next_msg = idev->msg_queue;
+
+		idev->restart_needed = next_msg->flags & I2C_M_RD;
+	} else {
+		idev->restart_needed = false;
+	}
+
+	idev->addr = i2c_8bit_addr_from_msg(this_msg);
+	idev->msg_len = this_msg->len;
+	idev->buf = this_msg->buf;
+
+	ctrl = readb(idev->base + CORE_I2C_CTRL);
+	ctrl |= CTRL_STA;
+	writeb(ctrl, idev->base + CORE_I2C_CTRL);
+
+	idev->current_num++;
+}
+
 static irqreturn_t mchp_corei2c_handle_isr(struct mchp_corei2c_dev *idev)
 {
 	u32 status = idev->isr_status;
@@ -238,8 +287,6 @@
 		ctrl &= ~CTRL_STA;
 		writeb(idev->addr, idev->base + CORE_I2C_DATA);
 		writeb(ctrl, idev->base + CORE_I2C_CTRL);
-		if (idev->msg_len == 0)
-			finished = true;
 		break;
 	case STATUS_M_ARB_LOST:
 		idev->msg_err = -EAGAIN;
@@ -247,10 +294,14 @@
 		break;
 	case STATUS_M_SLAW_ACK:
 	case STATUS_M_TX_DATA_ACK:
-		if (idev->msg_len > 0)
+		if (idev->msg_len > 0) {
 			mchp_corei2c_fill_tx(idev);
-		else
-			last_byte = true;
+		} else {
+			if (idev->restart_needed)
+				finished = true;
+			else
+				last_byte = true;
+		}
 		break;
 	case STATUS_M_TX_DATA_NACK:
 	case STATUS_M_SLAR_NACK:
@@ -287,7 +338,7 @@
 		mchp_corei2c_stop(idev);
 
 	if (last_byte || finished)
-		complete(&idev->msg_complete);
+		mchp_corei2c_next_msg(idev);
 
 	return IRQ_HANDLED;
 }
@@ -311,21 +362,48 @@
 	return ret;
 }
 
-static int mchp_corei2c_xfer_msg(struct mchp_corei2c_dev *idev,
-				 struct i2c_msg *msg)
+static int mchp_corei2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+			     int num)
 {
-	u8 ctrl;
+	struct mchp_corei2c_dev *idev = i2c_get_adapdata(adap);
+	struct i2c_msg *this_msg = msgs;
 	unsigned long time_left;
+	u8 ctrl;
+
+	mchp_corei2c_core_enable(idev);
 
-	idev->addr = i2c_8bit_addr_from_msg(msg);
-	idev->msg_len = msg->len;
-	idev->buf = msg->buf;
+	/*
+	 * The isr controls the flow of a transfer, this info needs to be saved
+	 * to a location that it can access the queue information from.
+	 */
+	idev->restart_needed = false;
+	idev->msg_queue = msgs;
+	idev->total_num = num;
+	idev->current_num = 0;
+
+	/*
+	 * But the first entry to the isr is triggered by the start in this
+	 * function, so the first message needs to be "dequeued".
+	 */
+	idev->addr = i2c_8bit_addr_from_msg(this_msg);
+	idev->msg_len = this_msg->len;
+	idev->buf = this_msg->buf;
 	idev->msg_err = 0;
 
-	reinit_completion(&idev->msg_complete);
+	if (idev->total_num > 1) {
+		struct i2c_msg *next_msg = msgs + 1;
 
-	mchp_corei2c_core_enable(idev);
+		idev->restart_needed = next_msg->flags & I2C_M_RD;
+	}
 
+	idev->current_num++;
+	idev->msg_queue++;
+
+	reinit_completion(&idev->msg_complete);
+
+	/*
+	 * Send the first start to pass control to the isr
+	 */
 	ctrl = readb(idev->base + CORE_I2C_CTRL);
 	ctrl |= CTRL_STA;
 	writeb(ctrl, idev->base + CORE_I2C_CTRL);
@@ -335,20 +413,8 @@
 	if (!time_left)
 		return -ETIMEDOUT;
 
-	return idev->msg_err;
-}
-
-static int mchp_corei2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
-			     int num)
-{
-	struct mchp_corei2c_dev *idev = i2c_get_adapdata(adap);
-	int i, ret;
-
-	for (i = 0; i < num; i++) {
-		ret = mchp_corei2c_xfer_msg(idev, msgs++);
-		if (ret)
-			return ret;
-	}
+	if (idev->msg_err)
+		return idev->msg_err;
 
 	return num;
 }
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-ocores.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-ocores.c
@@ -442,8 +442,8 @@
 	oc_setreg(i2c, OCI2C_PREHIGH, prescale >> 8);
 
 	/* Init the device */
-	oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK);
 	oc_setreg(i2c, OCI2C_CONTROL, ctrl | OCI2C_CTRL_EN);
+	oc_setreg(i2c, OCI2C_CMD, OCI2C_CMD_IACK);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-pnx.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-pnx.c
@@ -15,7 +15,6 @@
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
-#include <linux/timer.h>
 #include <linux/completion.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -32,7 +31,6 @@
 	int			ret;		/* Return value */
 	int			mode;		/* Interface mode */
 	struct completion	complete;	/* I/O completion */
-	struct timer_list	timer;		/* Timeout */
 	u8 *			buf;		/* Data buffer */
 	int			len;		/* Length of data buffer */
 	int			order;		/* RX Bytes to order via TX */
@@ -97,7 +95,7 @@
 
 static inline int wait_timeout(struct i2c_pnx_algo_data *data)
 {
-	long timeout = data->timeout;
+	long timeout = jiffies_to_msecs(data->timeout);
 	while (timeout > 0 &&
 			(ioread32(I2C_REG_STS(data)) & mstatus_active)) {
 		mdelay(1);
@@ -108,7 +106,7 @@
 
 static inline int wait_reset(struct i2c_pnx_algo_data *data)
 {
-	long timeout = data->timeout;
+	long timeout = jiffies_to_msecs(data->timeout);
 	while (timeout > 0 &&
 			(ioread32(I2C_REG_CTL(data)) & mcntrl_reset)) {
 		mdelay(1);
@@ -117,24 +115,6 @@
 	return (timeout <= 0);
 }
 
-static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data)
-{
-	struct timer_list *timer = &alg_data->mif.timer;
-	unsigned long expires = msecs_to_jiffies(alg_data->timeout);
-
-	if (expires <= 1)
-		expires = 2;
-
-	del_timer_sync(timer);
-
-	dev_dbg(&alg_data->adapter.dev, "Timer armed at %lu plus %lu jiffies.\n",
-		jiffies, expires);
-
-	timer->expires = jiffies + expires;
-
-	add_timer(timer);
-}
-
 /**
  * i2c_pnx_start - start a device
  * @slave_addr:		slave address
@@ -259,8 +239,6 @@
 				~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
 				  I2C_REG_CTL(alg_data));
 
-			del_timer_sync(&alg_data->mif.timer);
-
 			dev_dbg(&alg_data->adapter.dev,
 				"%s(): Waking up xfer routine.\n",
 				__func__);
@@ -276,8 +254,6 @@
 			~(mcntrl_afie | mcntrl_naie | mcntrl_drmie),
 			  I2C_REG_CTL(alg_data));
 
-		/* Stop timer. */
-		del_timer_sync(&alg_data->mif.timer);
 		dev_dbg(&alg_data->adapter.dev,
 			"%s(): Waking up xfer routine after zero-xfer.\n",
 			__func__);
@@ -364,8 +340,6 @@
 				 mcntrl_drmie | mcntrl_daie);
 			iowrite32(ctl, I2C_REG_CTL(alg_data));
 
-			/* Kill timer. */
-			del_timer_sync(&alg_data->mif.timer);
 			complete(&alg_data->mif.complete);
 		}
 	}
@@ -400,8 +374,6 @@
 			 mcntrl_drmie);
 		iowrite32(ctl, I2C_REG_CTL(alg_data));
 
-		/* Stop timer, to prevent timeout. */
-		del_timer_sync(&alg_data->mif.timer);
 		complete(&alg_data->mif.complete);
 	} else if (stat & mstatus_nai) {
 		/* Slave did not acknowledge, generate a STOP */
@@ -419,8 +391,6 @@
 		/* Our return value. */
 		alg_data->mif.ret = -EIO;
 
-		/* Stop timer, to prevent timeout. */
-		del_timer_sync(&alg_data->mif.timer);
 		complete(&alg_data->mif.complete);
 	} else {
 		/*
@@ -453,9 +423,8 @@
 	return IRQ_HANDLED;
 }
 
-static void i2c_pnx_timeout(struct timer_list *t)
+static void i2c_pnx_timeout(struct i2c_pnx_algo_data *alg_data)
 {
-	struct i2c_pnx_algo_data *alg_data = from_timer(alg_data, t, mif.timer);
 	u32 ctl;
 
 	dev_err(&alg_data->adapter.dev,
@@ -472,7 +441,6 @@
 	iowrite32(ctl, I2C_REG_CTL(alg_data));
 	wait_reset(alg_data);
 	alg_data->mif.ret = -EIO;
-	complete(&alg_data->mif.complete);
 }
 
 static inline void bus_reset_if_active(struct i2c_pnx_algo_data *alg_data)
@@ -514,6 +482,7 @@
 	struct i2c_msg *pmsg;
 	int rc = 0, completed = 0, i;
 	struct i2c_pnx_algo_data *alg_data = adap->algo_data;
+	unsigned long time_left;
 	u32 stat;
 
 	dev_dbg(&alg_data->adapter.dev,
@@ -548,7 +517,6 @@
 		dev_dbg(&alg_data->adapter.dev, "%s(): mode %d, %d bytes\n",
 			__func__, alg_data->mif.mode, alg_data->mif.len);
 
-		i2c_pnx_arm_timer(alg_data);
 
 		/* initialize the completion var */
 		init_completion(&alg_data->mif.complete);
@@ -564,7 +532,10 @@
 			break;
 
 		/* Wait for completion */
-		wait_for_completion(&alg_data->mif.complete);
+		time_left = wait_for_completion_timeout(&alg_data->mif.complete,
+							alg_data->timeout);
+		if (time_left == 0)
+			i2c_pnx_timeout(alg_data);
 
 		if (!(rc = alg_data->mif.ret))
 			completed++;
@@ -653,7 +624,10 @@
 	alg_data->adapter.algo_data = alg_data;
 	alg_data->adapter.nr = pdev->id;
 
-	alg_data->timeout = I2C_PNX_TIMEOUT_DEFAULT;
+	alg_data->timeout = msecs_to_jiffies(I2C_PNX_TIMEOUT_DEFAULT);
+	if (alg_data->timeout <= 1)
+		alg_data->timeout = 2;
+
 #ifdef CONFIG_OF
 	alg_data->adapter.dev.of_node = of_node_get(pdev->dev.of_node);
 	if (pdev->dev.of_node) {
@@ -673,8 +647,6 @@
 	if (IS_ERR(alg_data->clk))
 		return PTR_ERR(alg_data->clk);
 
-	timer_setup(&alg_data->mif.timer, i2c_pnx_timeout, 0);
-
 	snprintf(alg_data->adapter.name, sizeof(alg_data->adapter.name),
 		 "%s", pdev->name);
 
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-qcom-cci.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-qcom-cci.c
@@ -817,6 +817,7 @@
 	 * Do not add any new ones unless they introduce a new config
 	 */
 	{ .compatible = "qcom,msm8916-cci", .data = &cci_v1_data},
+	{ .compatible = "qcom,sc7280-cci", .data = &cci_v2_data},
 	{ .compatible = "qcom,sdm845-cci", .data = &cci_v2_data},
 	{ .compatible = "qcom,sm8250-cci", .data = &cci_v2_data},
 	{ .compatible = "qcom,sm8450-cci", .data = &cci_v2_data},
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-qcom-geni.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-qcom-geni.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+// Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
 
 #include <linux/acpi.h>
 #include <linux/clk.h>
@@ -16,6 +17,24 @@
 #include <linux/pm_runtime.h>
 #include <linux/soc/qcom/geni-se.h>
 #include <linux/spinlock.h>
+#include <soc/qcom/qup_fw_load.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/qup_buses_trace.h>
+
+void i2c_trace_log(struct device *dev, const char *fmt, ...)
+{
+	struct va_format vaf = {
+		.fmt = fmt,
+	};
+
+	va_list args;
+
+	va_start(args, fmt);
+	vaf.va = &args;
+	trace_buses_log_info(dev_name(dev), &vaf);
+	va_end(args);
+}
 
 #define SE_I2C_TX_TRANS_LEN		0x26c
 #define SE_I2C_RX_TRANS_LEN		0x270
@@ -77,6 +96,8 @@
 #define XFER_TIMEOUT		HZ
 #define RST_TIMEOUT		HZ
 
+static int geni_i2c_runtime_resume(struct device *dev);
+
 struct geni_i2c_dev {
 	struct geni_se se;
 	u32 tx_wm;
@@ -99,6 +120,7 @@
 	struct dma_chan *rx_c;
 	bool gpi_mode;
 	bool abort_done;
+	bool is_shared;
 };
 
 struct geni_i2c_desc {
@@ -198,10 +220,10 @@
 		rx_st = readl_relaxed(gi2c->se.base + SE_GENI_RX_FIFO_STATUS);
 		tx_st = readl_relaxed(gi2c->se.base + SE_GENI_TX_FIFO_STATUS);
 	}
-	dev_dbg(gi2c->se.dev, "DMA:%d tx_stat:0x%x, rx_stat:0x%x, irq-stat:0x%x\n",
-		dma, tx_st, rx_st, m_stat);
-	dev_dbg(gi2c->se.dev, "m_cmd:0x%x, geni_status:0x%x, geni_ios:0x%x\n",
-		m_cmd, geni_s, geni_ios);
+	i2c_trace_log(gi2c->se.dev, "DMA:%d tx_stat:0x%x, rx_stat:0x%x, irq-stat:0x%x\n",
+		      dma, tx_st, rx_st, m_stat);
+	i2c_trace_log(gi2c->se.dev, "m_cmd:0x%x, geni_status:0x%x, geni_ios:0x%x\n",
+		      m_cmd, geni_s, geni_ios);
 }
 
 static void geni_i2c_err(struct geni_i2c_dev *gi2c, int err)
@@ -209,8 +231,8 @@
 	if (!gi2c->err)
 		gi2c->err = gi2c_log[err].err;
 	if (gi2c->cur)
-		dev_dbg(gi2c->se.dev, "len:%d, slv-addr:0x%x, RD/WR:%d\n",
-			gi2c->cur->len, gi2c->cur->addr, gi2c->cur->flags);
+		i2c_trace_log(gi2c->se.dev, "len:%d, slv-addr:0x%x, RD/WR:%d\n",
+			      gi2c->cur->len, gi2c->cur->addr, gi2c->cur->flags);
 
 	switch (err) {
 	case GENI_ABORT_DONE:
@@ -218,7 +240,7 @@
 		break;
 	case NACK:
 	case GENI_TIMEOUT:
-		dev_dbg(gi2c->se.dev, "%s\n", gi2c_log[err].msg);
+		i2c_trace_log(gi2c->se.dev, "%s\n", gi2c_log[err].msg);
 		break;
 	default:
 		dev_err(gi2c->se.dev, "%s\n", gi2c_log[err].msg);
@@ -270,8 +292,8 @@
 		if (!dma)
 			writel_relaxed(0, base + SE_GENI_TX_WATERMARK_REG);
 	} else if (dma) {
-		dev_dbg(gi2c->se.dev, "i2c dma tx:0x%x, dma rx:0x%x\n",
-			dm_tx_st, dm_rx_st);
+		i2c_trace_log(gi2c->se.dev, "i2c dma tx:0x%x, dma rx:0x%x\n",
+			      dm_tx_st, dm_rx_st);
 	} else if (cur->flags & I2C_M_RD &&
 		   m_stat & (M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN)) {
 		u32 rxcnt = rx_st & RX_FIFO_WC_MSK;
@@ -484,13 +506,20 @@
 
 static void i2c_gpi_cb_result(void *cb, const struct dmaengine_result *result)
 {
-	struct geni_i2c_dev *gi2c = cb;
+	struct gpi_i2c_config *i2c = cb;
+	struct geni_i2c_dev *gi2c = i2c->gi2c;
 
-	if (result->result != DMA_TRANS_NOERROR) {
+	if (i2c->status & (BIT(NACK) << 5)) {
+		geni_i2c_err(gi2c, NACK);
+	} else if (i2c->status & (BIT(BUS_PROTO) << 5)) {
+		geni_i2c_err(gi2c, BUS_PROTO);
+	} else if (i2c->status & (BIT(ARB_LOST) << 5)) {
+		geni_i2c_err(gi2c, ARB_LOST);
+	} else if (result->result != DMA_TRANS_NOERROR) {
 		dev_err(gi2c->se.dev, "DMA txn failed:%d\n", result->result);
 		gi2c->err = -EIO;
 	} else if (result->residue) {
-		dev_dbg(gi2c->se.dev, "DMA xfer has pending: %d\n", result->residue);
+		i2c_trace_log(gi2c->se.dev, "DMA xfer has pending: %d\n", result->residue);
 	}
 
 	complete(&gi2c->done);
@@ -568,7 +597,7 @@
 	}
 
 	desc->callback_result = i2c_gpi_cb_result;
-	desc->callback_param = gi2c;
+	desc->callback_param = peripheral;
 
 	dmaengine_submit(desc);
 	*buf = dma_buf;
@@ -585,33 +614,46 @@
 static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], int num)
 {
 	struct dma_slave_config config = {};
-	struct gpi_i2c_config peripheral = {};
-	int i, ret = 0, timeout;
+	struct gpi_i2c_config *peripheral;
+	int i, ret = 0;
+	unsigned long time_left;
 	dma_addr_t tx_addr, rx_addr;
 	void *tx_buf = NULL, *rx_buf = NULL;
 	const struct geni_i2c_clk_fld *itr = gi2c->clk_fld;
 
-	config.peripheral_config = &peripheral;
-	config.peripheral_size = sizeof(peripheral);
+	peripheral = devm_kzalloc(gi2c->se.dev, sizeof(*peripheral), GFP_KERNEL);
+	if (!peripheral)
+		return -ENOMEM;
+
+	config.peripheral_config = peripheral;
+	config.peripheral_size = sizeof(struct gpi_i2c_config);
 
-	peripheral.pack_enable = I2C_PACK_TX | I2C_PACK_RX;
-	peripheral.cycle_count = itr->t_cycle_cnt;
-	peripheral.high_count = itr->t_high_cnt;
-	peripheral.low_count = itr->t_low_cnt;
-	peripheral.clk_div = itr->clk_div;
-	peripheral.set_config = 1;
-	peripheral.multi_msg = false;
+	peripheral->pack_enable = I2C_PACK_TX | I2C_PACK_RX;
+	peripheral->cycle_count = itr->t_cycle_cnt;
+	peripheral->high_count = itr->t_high_cnt;
+	peripheral->low_count = itr->t_low_cnt;
+	peripheral->clk_div = itr->clk_div;
+	peripheral->set_config = 1;
+	peripheral->multi_msg = false;
+	peripheral->gi2c = gi2c;
 
+	if (gi2c->is_shared)
+		peripheral->shared_se = true;
+
+	i2c_trace_log(gi2c->se.dev, "%s: num:%d addr:0x%x\n",
+		      __func__, num, msgs[0].addr);
 	for (i = 0; i < num; i++) {
 		gi2c->cur = &msgs[i];
 		gi2c->err = 0;
-		dev_dbg(gi2c->se.dev, "msg[%d].len:%d\n", i, gi2c->cur->len);
+		i2c_trace_log(gi2c->se.dev, "msg[%d].len:%d\n", i, gi2c->cur->len);
 
-		peripheral.stretch = 0;
+		peripheral->first_msg = (i == 0) ? 1 : 0;
+		peripheral->last_msg = (i == num - 1) ? 1 : 0;
+		peripheral->stretch = 0;
 		if (i < num - 1)
-			peripheral.stretch = 1;
+			peripheral->stretch = 1;
 
-		peripheral.addr = msgs[i].addr;
+		peripheral->addr = msgs[i].addr;
 
 		ret =  geni_i2c_gpi(gi2c, &msgs[i], &config,
 				    &tx_addr, &tx_buf, I2C_WRITE, gi2c->tx_c);
@@ -629,12 +671,9 @@
 
 		dma_async_issue_pending(gi2c->tx_c);
 
-		timeout = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
-		if (!timeout) {
-			dev_err(gi2c->se.dev, "I2C timeout gpi flags:%d addr:0x%x\n",
-				gi2c->cur->flags, gi2c->cur->addr);
+		time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT);
+		if (!time_left)
 			gi2c->err = -ETIMEDOUT;
-		}
 
 		if (gi2c->err) {
 			ret = gi2c->err;
@@ -659,17 +698,23 @@
 {
 	int i, ret = 0;
 
+	i2c_trace_log(gi2c->se.dev, "%s: num:%d addr:0x%x\n",
+		      __func__, num, msgs[0].addr);
 	for (i = 0; i < num; i++) {
 		u32 m_param = i < (num - 1) ? STOP_STRETCH : 0;
 
 		m_param |= ((msgs[i].addr << SLV_ADDR_SHFT) & SLV_ADDR_MSK);
 
 		gi2c->cur = &msgs[i];
-		if (msgs[i].flags & I2C_M_RD)
+		if (msgs[i].flags & I2C_M_RD) {
+			i2c_trace_log(gi2c->se.dev, "%s: msgs[%d].len:%d R\n",
+				      __func__, i, gi2c->cur->len);
 			ret = geni_i2c_rx_one_msg(gi2c, &msgs[i], m_param);
-		else
+		} else {
+			i2c_trace_log(gi2c->se.dev, "%s: msgs[%d].len:%d W\n",
+				      __func__, i, gi2c->cur->len);
 			ret = geni_i2c_tx_one_msg(gi2c, &msgs[i], m_param);
-
+		}
 		if (ret)
 			return ret;
 	}
@@ -682,17 +727,24 @@
 			 int num)
 {
 	struct geni_i2c_dev *gi2c = i2c_get_adapdata(adap);
+	struct device *dev = gi2c->se.dev;
 	int ret;
 
 	gi2c->err = 0;
 	reinit_completion(&gi2c->done);
 	ret = pm_runtime_get_sync(gi2c->se.dev);
-	if (ret < 0) {
-		dev_err(gi2c->se.dev, "error turning SE resources:%d\n", ret);
-		pm_runtime_put_noidle(gi2c->se.dev);
-		/* Set device in suspended since resume failed */
-		pm_runtime_set_suspended(gi2c->se.dev);
-		return ret;
+	if (ret < 0 && gi2c->suspended) {
+		i2c_trace_log(gi2c->se.dev, "%s: pm_runtime_get_sync failed ! doing force resume\n",
+			      __func__);
+		ret = geni_i2c_runtime_resume(gi2c->se.dev);
+		if (ret) {
+			dev_err(gi2c->se.dev, "error turning SE resources:%d\n", ret);
+			pm_runtime_put_noidle(gi2c->se.dev);
+			/* Set device in suspended since resume failed */
+			pm_runtime_set_suspended(gi2c->se.dev);
+			return ret;
+		}
+		atomic_inc(&dev->power.usage_count);
 	}
 
 	qcom_geni_i2c_conf(gi2c);
@@ -756,7 +808,7 @@
 		goto err_rx;
 	}
 
-	dev_dbg(gi2c->se.dev, "Grabbed GPI dma channels\n");
+	i2c_trace_log(gi2c->se.dev, "Grabbed GPI dma channels\n");
 	return 0;
 
 err_rx:
@@ -765,10 +817,42 @@
 	return ret;
 }
 
+/**
+ * geni_check_fw_validity: Function to checks firmware validity.
+ * @gi2c: geni i2c device.
+ *
+ * This function checks firmware validity by reading se protocol
+ * register. In case protocol value is not correct, it will try
+ * to load se firmware. if firmware load is failed, it will return
+ * failure. if firmware load is success, it will recheck firmware
+ * validity by checking proto value.
+ *
+ * return: Return 0 if no error, else return error value.
+ */
+static int geni_check_fw_validity(struct geni_i2c_dev *gi2c)
+{
+	struct device *dev = gi2c->se.dev;
+	u32 proto;
+	int ret;
+
+	proto = geni_se_read_proto(&gi2c->se);
+	if (proto != GENI_SE_I2C) {
+		ret = geni_load_se_firmware(&gi2c->se, GENI_SE_I2C);
+		if (ret) {
+			if (ret == -ENOENT)
+				return -EPROBE_DEFER;
+
+			dev_err(dev, "Cannot load firmware from linux for i2c error: %d\n", ret);
+			return -ENXIO;
+		}
+	}
+	return 0;
+}
+
 static int geni_i2c_probe(struct platform_device *pdev)
 {
 	struct geni_i2c_dev *gi2c;
-	u32 proto, tx_depth, fifo_disable;
+	u32 tx_depth, fifo_disable;
 	int ret;
 	struct device *dev = &pdev->dev;
 	const struct geni_i2c_desc *desc = NULL;
@@ -798,7 +882,7 @@
 	ret = device_property_read_u32(dev, "clock-frequency",
 				       &gi2c->clk_freq_out);
 	if (ret) {
-		dev_info(dev, "Bus frequency not specified, default to 100kHz.\n");
+		i2c_trace_log(dev, "Bus frequency not specified, default to 100kHz.\n");
 		gi2c->clk_freq_out = KHZ(100);
 	}
 
@@ -820,15 +904,13 @@
 	init_completion(&gi2c->done);
 	spin_lock_init(&gi2c->lock);
 	platform_set_drvdata(pdev, gi2c);
-	ret = devm_request_irq(dev, gi2c->irq, geni_i2c_irq, 0,
+	ret = devm_request_irq(dev, gi2c->irq, geni_i2c_irq, IRQF_NO_AUTOEN | IRQF_EARLY_RESUME | IRQF_NO_SUSPEND,
 			       dev_name(dev), gi2c);
 	if (ret) {
 		dev_err(dev, "Request_irq failed:%d: err:%d\n",
 			gi2c->irq, ret);
 		return ret;
 	}
-	/* Disable the interrupt so that the system can enter low-power mode */
-	disable_irq(gi2c->irq);
 	i2c_set_adapdata(&gi2c->adap, gi2c);
 	gi2c->adap.dev.parent = dev;
 	gi2c->adap.dev.of_node = dev->of_node;
@@ -861,12 +943,12 @@
 		clk_disable_unprepare(gi2c->core_clk);
 		return ret;
 	}
-	proto = geni_se_read_proto(&gi2c->se);
-	if (proto != GENI_SE_I2C) {
-		dev_err(dev, "Invalid proto %d\n", proto);
+
+	ret = geni_check_fw_validity(gi2c);
+	if (ret) {
 		geni_se_resources_off(&gi2c->se);
 		clk_disable_unprepare(gi2c->core_clk);
-		return -ENXIO;
+		return ret;
 	}
 
 	if (desc && desc->no_dma_support)
@@ -884,7 +966,7 @@
 			return dev_err_probe(dev, ret, "Failed to setup GPI DMA mode\n");
 		}
 
-		dev_dbg(dev, "Using GPI DMA mode for I2C\n");
+		i2c_trace_log(dev, "Using GPI DMA mode for I2C\n");
 	} else {
 		gi2c->gpi_mode = false;
 		tx_depth = geni_se_get_tx_fifo_depth(&gi2c->se);
@@ -905,7 +987,12 @@
 		geni_se_config_packing(&gi2c->se, BITS_PER_BYTE,
 				       PACKING_BYTES_PW, true, true, true);
 
-		dev_dbg(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth);
+		i2c_trace_log(dev, "i2c fifo/se-dma mode. fifo depth:%d\n", tx_depth);
+	}
+
+	if (of_property_read_bool(pdev->dev.of_node, "qcom,shared-se")) {
+		gi2c->is_shared = true;
+		i2c_trace_log(&pdev->dev, "Multi-EE usecase with shared SE\n");
 	}
 
 	clk_disable_unprepare(gi2c->core_clk);
@@ -932,7 +1019,7 @@
 		goto err_dma;
 	}
 
-	dev_dbg(dev, "Geni-I2C adaptor successfully added\n");
+	i2c_trace_log(dev, "Geni-I2C adaptor successfully added\n");
 
 	return 0;
 
@@ -964,14 +1051,17 @@
 	struct geni_i2c_dev *gi2c = dev_get_drvdata(dev);
 
 	disable_irq(gi2c->irq);
-	ret = geni_se_resources_off(&gi2c->se);
-	if (ret) {
-		enable_irq(gi2c->irq);
-		return ret;
 
+	if (gi2c->is_shared) {
+		geni_se_clks_off(&gi2c->se);
 	} else {
-		gi2c->suspended = 1;
+		ret = geni_se_resources_off(&gi2c->se);
+		if (ret) {
+			enable_irq(gi2c->irq);
+			return ret;
+		}
 	}
+	gi2c->suspended = 1;
 
 	clk_disable_unprepare(gi2c->core_clk);
 
@@ -988,12 +1078,17 @@
 		return ret;
 
 	ret = clk_prepare_enable(gi2c->core_clk);
-	if (ret)
+	if (ret) {
+		geni_icc_disable(&gi2c->se);
 		return ret;
+	}
 
 	ret = geni_se_resources_on(&gi2c->se);
-	if (ret)
+	if (ret) {
+		clk_disable_unprepare(gi2c->core_clk);
+		geni_icc_disable(&gi2c->se);
 		return ret;
+	}
 
 	enable_irq(gi2c->irq);
 	gi2c->suspended = 0;
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-rcar.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-rcar.c
@@ -130,6 +130,8 @@
 #define ID_P_PM_BLOCKED		BIT(31)
 #define ID_P_MASK		GENMASK(31, 27)
 
+#define ID_SLAVE_NACK		BIT(0)
+
 enum rcar_i2c_type {
 	I2C_RCAR_GEN1,
 	I2C_RCAR_GEN2,
@@ -166,6 +168,7 @@
 	int irq;
 
 	struct i2c_client *host_notify_client;
+	u8 slave_flags;
 };
 
 #define rcar_i2c_priv_to_dev(p)		((p)->adap.dev.parent)
@@ -257,6 +260,14 @@
 	}
 }
 
+static void rcar_i2c_reset_slave(struct rcar_i2c_priv *priv)
+{
+	rcar_i2c_write(priv, ICSIER, 0);
+	rcar_i2c_write(priv, ICSSR, 0);
+	rcar_i2c_write(priv, ICSCR, SDBS);
+	rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */
+}
+
 static int rcar_i2c_bus_barrier(struct rcar_i2c_priv *priv)
 {
 	int ret;
@@ -648,6 +659,7 @@
 {
 	u32 ssr_raw, ssr_filtered;
 	u8 value;
+	int ret;
 
 	ssr_raw = rcar_i2c_read(priv, ICSSR) & 0xff;
 	ssr_filtered = ssr_raw & rcar_i2c_read(priv, ICSIER);
@@ -663,7 +675,10 @@
 			rcar_i2c_write(priv, ICRXTX, value);
 			rcar_i2c_write(priv, ICSIER, SDE | SSR | SAR);
 		} else {
-			i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, &value);
+			ret = i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_REQUESTED, &value);
+			if (ret)
+				priv->slave_flags |= ID_SLAVE_NACK;
+
 			rcar_i2c_read(priv, ICRXTX);	/* dummy read */
 			rcar_i2c_write(priv, ICSIER, SDR | SSR | SAR);
 		}
@@ -676,18 +691,21 @@
 	if (ssr_filtered & SSR) {
 		i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value);
 		rcar_i2c_write(priv, ICSCR, SIE | SDBS); /* clear our NACK */
+		priv->slave_flags &= ~ID_SLAVE_NACK;
 		rcar_i2c_write(priv, ICSIER, SAR);
 		rcar_i2c_write(priv, ICSSR, ~SSR & 0xff);
 	}
 
 	/* master wants to write to us */
 	if (ssr_filtered & SDR) {
-		int ret;
-
 		value = rcar_i2c_read(priv, ICRXTX);
 		ret = i2c_slave_event(priv->slave, I2C_SLAVE_WRITE_RECEIVED, &value);
-		/* Send NACK in case of error */
-		rcar_i2c_write(priv, ICSCR, SIE | SDBS | (ret < 0 ? FNA : 0));
+		if (ret)
+			priv->slave_flags |= ID_SLAVE_NACK;
+
+		/* Send NACK in case of error, but it will come 1 byte late :( */
+		rcar_i2c_write(priv, ICSCR, SIE | SDBS |
+			       (priv->slave_flags & ID_SLAVE_NACK ? FNA : 0));
 		rcar_i2c_write(priv, ICSSR, ~SDR & 0xff);
 	}
 
@@ -875,6 +893,10 @@
 {
 	int ret;
 
+	/* Don't reset if a slave instance is currently running */
+	if (priv->slave)
+		return -EISCONN;
+
 	ret = reset_control_reset(priv->rstc);
 	if (ret)
 		return ret;
@@ -903,10 +925,10 @@
 
 	/* Gen3+ needs a reset. That also allows RXDMA once */
 	if (priv->devtype >= I2C_RCAR_GEN3) {
-		priv->flags &= ~ID_P_NO_RXDMA;
 		ret = rcar_i2c_do_reset(priv);
 		if (ret)
 			goto out;
+		priv->flags &= ~ID_P_NO_RXDMA;
 	}
 
 	rcar_i2c_init(priv);
@@ -1033,11 +1055,8 @@
 
 	/* ensure no irq is running before clearing ptr */
 	disable_irq(priv->irq);
-	rcar_i2c_write(priv, ICSIER, 0);
-	rcar_i2c_write(priv, ICSSR, 0);
+	rcar_i2c_reset_slave(priv);
 	enable_irq(priv->irq);
-	rcar_i2c_write(priv, ICSCR, SDBS);
-	rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */
 
 	priv->slave = NULL;
 
@@ -1152,7 +1171,9 @@
 		goto out_pm_disable;
 	}
 
-	rcar_i2c_write(priv, ICSAR, 0); /* Gen2: must be 0 if not using slave */
+	/* Bring hardware to known state */
+	rcar_i2c_init(priv);
+	rcar_i2c_reset_slave(priv);
 
 	if (priv->devtype < I2C_RCAR_GEN3) {
 		irqflags |= IRQF_NO_THREAD;
@@ -1168,6 +1189,7 @@
 	if (of_property_read_bool(dev->of_node, "smbus"))
 		priv->flags |= ID_P_HOST_NOTIFY;
 
+	/* R-Car Gen3+ needs a reset before every transfer */
 	if (priv->devtype >= I2C_RCAR_GEN3) {
 		priv->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
 		if (IS_ERR(priv->rstc)) {
@@ -1178,6 +1200,9 @@
 		ret = reset_control_status(priv->rstc);
 		if (ret < 0)
 			goto out_pm_put;
+
+		/* hard reset disturbs HostNotify local target, so disable it */
+		priv->flags &= ~ID_P_HOST_NOTIFY;
 	}
 
 	ret = platform_get_irq(pdev, 0);
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-riic.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-riic.c
@@ -324,7 +324,7 @@
 		if (brl <= (0x1F + 3))
 			break;
 
-		total_ticks /= 2;
+		total_ticks = DIV_ROUND_UP(total_ticks, 2);
 		rate /= 2;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-stm32f7.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-stm32f7.c
@@ -2395,7 +2395,7 @@
 	struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev);
 
 	if (!stm32f7_i2c_is_slave_registered(i2c_dev))
-		clk_disable_unprepare(i2c_dev->clk);
+		clk_disable(i2c_dev->clk);
 
 	return 0;
 }
@@ -2406,9 +2406,9 @@
 	int ret;
 
 	if (!stm32f7_i2c_is_slave_registered(i2c_dev)) {
-		ret = clk_prepare_enable(i2c_dev->clk);
+		ret = clk_enable(i2c_dev->clk);
 		if (ret) {
-			dev_err(dev, "failed to prepare_enable clock\n");
+			dev_err(dev, "failed to enable clock\n");
 			return ret;
 		}
 	}
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-synquacer.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-synquacer.c
@@ -138,7 +138,6 @@
 	int			irq;
 	struct device		*dev;
 	void __iomem		*base;
-	struct clk		*pclk;
 	u32			pclkrate;
 	u32			speed_khz;
 	u32			timeout_ms;
@@ -535,6 +534,7 @@
 static int synquacer_i2c_probe(struct platform_device *pdev)
 {
 	struct synquacer_i2c *i2c;
+	struct clk *pclk;
 	u32 bus_speed;
 	int ret;
 
@@ -550,17 +550,13 @@
 	device_property_read_u32(&pdev->dev, "socionext,pclk-rate",
 				 &i2c->pclkrate);
 
-	i2c->pclk = devm_clk_get(&pdev->dev, "pclk");
-	if (PTR_ERR(i2c->pclk) == -EPROBE_DEFER)
-		return -EPROBE_DEFER;
-	if (!IS_ERR_OR_NULL(i2c->pclk)) {
-		dev_dbg(&pdev->dev, "clock source %p\n", i2c->pclk);
-
-		ret = clk_prepare_enable(i2c->pclk);
-		if (ret)
-			return dev_err_probe(&pdev->dev, ret, "failed to enable clock\n");
-		i2c->pclkrate = clk_get_rate(i2c->pclk);
-	}
+	pclk = devm_clk_get_optional_enabled(&pdev->dev, "pclk");
+	if (IS_ERR(pclk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(pclk),
+				     "failed to get and enable clock\n");
+
+	if (pclk)
+		i2c->pclkrate = clk_get_rate(pclk);
 
 	if (i2c->pclkrate < SYNQUACER_I2C_MIN_CLK_RATE ||
 	    i2c->pclkrate > SYNQUACER_I2C_MAX_CLK_RATE)
@@ -615,8 +611,6 @@
 	struct synquacer_i2c *i2c = platform_get_drvdata(pdev);
 
 	i2c_del_adapter(&i2c->adapter);
-	if (!IS_ERR(i2c->pclk))
-		clk_disable_unprepare(i2c->pclk);
 };
 
 static const struct of_device_id synquacer_i2c_dt_ids[] __maybe_unused = {
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-tegra.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-tegra.c
@@ -1804,9 +1804,9 @@
 	 * domain.
 	 *
 	 * VI I2C device shouldn't be marked as IRQ-safe because VI I2C won't
-	 * be used for atomic transfers.
+	 * be used for atomic transfers. ACPI device is not IRQ safe also.
 	 */
-	if (!IS_VI(i2c_dev))
+	if (!IS_VI(i2c_dev) && !has_acpi_companion(i2c_dev->dev))
 		pm_runtime_irq_safe(i2c_dev->dev);
 
 	pm_runtime_enable(i2c_dev->dev);
--- linux-qcom-6.8.0.orig/drivers/i2c/busses/i2c-xiic.c
+++ linux-qcom-6.8.0/drivers/i2c/busses/i2c-xiic.c
@@ -772,14 +772,17 @@
 			goto out;
 		}
 
-		xiic_fill_tx_fifo(i2c);
-
-		/* current message sent and there is space in the fifo */
-		if (!xiic_tx_space(i2c) && xiic_tx_fifo_space(i2c) >= 2) {
+		if (xiic_tx_space(i2c)) {
+			xiic_fill_tx_fifo(i2c);
+		} else {
+			/* current message fully written */
 			dev_dbg(i2c->adap.dev.parent,
 				"%s end of message sent, nmsgs: %d\n",
 				__func__, i2c->nmsgs);
-			if (i2c->nmsgs > 1) {
+			/* Don't move onto the next message until the TX FIFO empties,
+			 * to ensure that a NAK is not missed.
+			 */
+			if (i2c->nmsgs > 1 && (pend & XIIC_INTR_TX_EMPTY_MASK)) {
 				i2c->nmsgs--;
 				i2c->tx_msg++;
 				xfer_more = 1;
@@ -790,11 +793,7 @@
 					"%s Got TX IRQ but no more to do...\n",
 					__func__);
 			}
-		} else if (!xiic_tx_space(i2c) && (i2c->nmsgs == 1))
-			/* current frame is sent and is last,
-			 * make sure to disable tx half
-			 */
-			xiic_irq_dis(i2c, XIIC_INTR_TX_HALF_MASK);
+		}
 	}
 
 	if (pend & XIIC_INTR_BNB_MASK) {
@@ -844,23 +843,11 @@
 	return (sr & XIIC_SR_BUS_BUSY_MASK) ? -EBUSY : 0;
 }
 
-static int xiic_busy(struct xiic_i2c *i2c)
+static int xiic_wait_not_busy(struct xiic_i2c *i2c)
 {
 	int tries = 3;
 	int err;
 
-	if (i2c->tx_msg || i2c->rx_msg)
-		return -EBUSY;
-
-	/* In single master mode bus can only be busy, when in use by this
-	 * driver. If the register indicates bus being busy for some reason we
-	 * should ignore it, since bus will never be released and i2c will be
-	 * stuck forever.
-	 */
-	if (i2c->singlemaster) {
-		return 0;
-	}
-
 	/* for instance if previous transfer was terminated due to TX error
 	 * it might be that the bus is on it's way to become available
 	 * give it at most 3 ms to wake
@@ -1104,9 +1091,35 @@
 
 	mutex_lock(&i2c->lock);
 
-	ret = xiic_busy(i2c);
-	if (ret)
+	if (i2c->tx_msg || i2c->rx_msg) {
+		dev_err(i2c->adap.dev.parent,
+			"cannot start a transfer while busy\n");
+		ret = -EBUSY;
 		goto out;
+	}
+
+	/* In single master mode bus can only be busy, when in use by this
+	 * driver. If the register indicates bus being busy for some reason we
+	 * should ignore it, since bus will never be released and i2c will be
+	 * stuck forever.
+	 */
+	if (!i2c->singlemaster) {
+		ret = xiic_wait_not_busy(i2c);
+		if (ret) {
+			/* If the bus is stuck in a busy state, such as due to spurious low
+			 * pulses on the bus causing a false start condition to be detected,
+			 * then try to recover by re-initializing the controller and check
+			 * again if the bus is still busy.
+			 */
+			dev_warn(i2c->adap.dev.parent, "I2C bus busy timeout, reinitializing\n");
+			ret = xiic_reinit(i2c);
+			if (ret)
+				goto out;
+			ret = xiic_wait_not_busy(i2c);
+			if (ret)
+				goto out;
+		}
+	}
 
 	i2c->tx_msg = msgs;
 	i2c->rx_msg = NULL;
@@ -1164,10 +1177,8 @@
 		return err;
 
 	err = xiic_start_xfer(i2c, msgs, num);
-	if (err < 0) {
-		dev_err(adap->dev.parent, "Error xiic_start_xfer\n");
+	if (err < 0)
 		goto out;
-	}
 
 	err = wait_for_completion_timeout(&i2c->completion, XIIC_XFER_TIMEOUT);
 	mutex_lock(&i2c->lock);
@@ -1326,8 +1337,8 @@
 	return 0;
 
 err_pm_disable:
-	pm_runtime_set_suspended(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
 
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/i2c/i2c-atr.c
+++ linux-qcom-6.8.0/drivers/i2c/i2c-atr.c
@@ -412,7 +412,7 @@
 				dev_name(dev), ret);
 		break;
 
-	case BUS_NOTIFY_DEL_DEVICE:
+	case BUS_NOTIFY_REMOVED_DEVICE:
 		i2c_atr_detach_client(client->adapter, client);
 		break;
 
--- linux-qcom-6.8.0.orig/drivers/i2c/i2c-core-acpi.c
+++ linux-qcom-6.8.0/drivers/i2c/i2c-core-acpi.c
@@ -355,6 +355,25 @@
 	{}
 };
 
+static const struct acpi_device_id i2c_acpi_force_100khz_device_ids[] = {
+	/*
+	 * When a 400KHz freq is used on this model of ELAN touchpad in Linux,
+	 * excessive smoothing (similar to when the touchpad's firmware detects
+	 * a noisy signal) is sometimes applied. As some devices' (e.g, Lenovo
+	 * V15 G4) ACPI tables specify a 400KHz frequency for this device and
+	 * some I2C busses (e.g, Designware I2C) default to a 400KHz freq,
+	 * force the speed to 100KHz as a workaround.
+	 *
+	 * For future investigation: This problem may be related to the default
+	 * HCNT/LCNT values given by some busses' drivers, because they are not
+	 * specified in the aforementioned devices' ACPI tables, and because
+	 * the device works without issues on Windows at what is expected to be
+	 * a 400KHz frequency. The root cause of the issue is not known.
+	 */
+	{ "ELAN06FA", 0 },
+	{}
+};
+
 static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level,
 					   void *data, void **return_value)
 {
@@ -373,6 +392,9 @@
 	if (acpi_match_device_ids(adev, i2c_acpi_force_400khz_device_ids) == 0)
 		lookup->force_speed = I2C_MAX_FAST_MODE_FREQ;
 
+	if (acpi_match_device_ids(adev, i2c_acpi_force_100khz_device_ids) == 0)
+		lookup->force_speed = I2C_MAX_STANDARD_MODE_FREQ;
+
 	return AE_OK;
 }
 
@@ -445,6 +467,11 @@
 	return i2c_find_device_by_fwnode(acpi_fwnode_handle(adev));
 }
 
+static struct i2c_adapter *i2c_acpi_find_adapter_by_adev(struct acpi_device *adev)
+{
+	return i2c_find_adapter_by_fwnode(acpi_fwnode_handle(adev));
+}
+
 static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value,
 			   void *arg)
 {
@@ -471,11 +498,17 @@
 			break;
 
 		client = i2c_acpi_find_client_by_adev(adev);
-		if (!client)
-			break;
+		if (client) {
+			i2c_unregister_device(client);
+			put_device(&client->dev);
+		}
+
+		adapter = i2c_acpi_find_adapter_by_adev(adev);
+		if (adapter) {
+			acpi_unbind_one(&adapter->dev);
+			put_device(&adapter->dev);
+		}
 
-		i2c_unregister_device(client);
-		put_device(&client->dev);
 		break;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/i2c/i2c-core-base.c
+++ linux-qcom-6.8.0/drivers/i2c/i2c-core-base.c
@@ -915,6 +915,27 @@
 	return 0;
 }
 
+/*
+ * Serialize device instantiation in case it can be instantiated explicitly
+ * and by auto-detection
+ */
+static int i2c_lock_addr(struct i2c_adapter *adap, unsigned short addr,
+			 unsigned short flags)
+{
+	if (!(flags & I2C_CLIENT_TEN) &&
+	    test_and_set_bit(addr, adap->addrs_in_instantiation))
+		return -EBUSY;
+
+	return 0;
+}
+
+static void i2c_unlock_addr(struct i2c_adapter *adap, unsigned short addr,
+			    unsigned short flags)
+{
+	if (!(flags & I2C_CLIENT_TEN))
+		clear_bit(addr, adap->addrs_in_instantiation);
+}
+
 /**
  * i2c_new_client_device - instantiate an i2c device
  * @adap: the adapter managing the device
@@ -962,6 +983,10 @@
 		goto out_err_silent;
 	}
 
+	status = i2c_lock_addr(adap, client->addr, client->flags);
+	if (status)
+		goto out_err_silent;
+
 	/* Check for address business */
 	status = i2c_check_addr_busy(adap, i2c_encode_flags_to_addr(client));
 	if (status)
@@ -993,6 +1018,8 @@
 	dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",
 		client->name, dev_name(&client->dev));
 
+	i2c_unlock_addr(adap, client->addr, client->flags);
+
 	return client;
 
 out_remove_swnode:
@@ -1004,6 +1031,7 @@
 	dev_err(&adap->dev,
 		"Failed to register i2c client %s at 0x%02x (%d)\n",
 		client->name, client->addr, status);
+	i2c_unlock_addr(adap, client->addr, client->flags);
 out_err_silent:
 	if (need_put)
 		put_device(&client->dev);
@@ -1067,6 +1095,7 @@
 
 static const struct i2c_device_id dummy_id[] = {
 	{ "dummy", 0 },
+	{ "smbus_host_notify", 0 },
 	{ },
 };
 
@@ -2200,13 +2229,18 @@
  * Returns negative errno, else the number of messages executed.
  *
  * Adapter lock must be held when calling this function. No debug logging
- * takes place. adap->algo->master_xfer existence isn't checked.
+ * takes place.
  */
 int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
 {
 	unsigned long orig_jiffies;
 	int ret, try;
 
+	if (!adap->algo->master_xfer) {
+		dev_dbg(&adap->dev, "I2C level transfers not supported\n");
+		return -EOPNOTSUPP;
+	}
+
 	if (WARN_ON(!msgs || num < 1))
 		return -EINVAL;
 
@@ -2273,11 +2307,6 @@
 {
 	int ret;
 
-	if (!adap->algo->master_xfer) {
-		dev_dbg(&adap->dev, "I2C level transfers not supported\n");
-		return -EOPNOTSUPP;
-	}
-
 	/* REVISIT the fault reporting model here is weak:
 	 *
 	 *  - When we get an error after receiving N bytes from a slave,
--- linux-qcom-6.8.0.orig/drivers/i2c/i2c-slave-testunit.c
+++ linux-qcom-6.8.0/drivers/i2c/i2c-slave-testunit.c
@@ -33,6 +33,7 @@
 
 enum testunit_flags {
 	TU_FLAG_IN_PROCESS,
+	TU_FLAG_NACK,
 };
 
 struct testunit_data {
@@ -95,8 +96,10 @@
 
 	switch (event) {
 	case I2C_SLAVE_WRITE_RECEIVED:
-		if (test_bit(TU_FLAG_IN_PROCESS, &tu->flags))
-			return -EBUSY;
+		if (test_bit(TU_FLAG_IN_PROCESS | TU_FLAG_NACK, &tu->flags)) {
+			ret = -EBUSY;
+			break;
+		}
 
 		if (tu->reg_idx < TU_NUM_REGS)
 			tu->regs[tu->reg_idx] = *val;
@@ -118,9 +121,23 @@
 			queue_delayed_work(system_long_wq, &tu->worker,
 					   msecs_to_jiffies(10 * tu->regs[TU_REG_DELAY]));
 		}
-		fallthrough;
+
+		/*
+		 * Reset reg_idx to avoid that work gets queued again in case of
+		 * STOP after a following read message. But do not clear TU regs
+		 * here because we still need them in the workqueue!
+		 */
+		tu->reg_idx = 0;
+
+		clear_bit(TU_FLAG_NACK, &tu->flags);
+		break;
 
 	case I2C_SLAVE_WRITE_REQUESTED:
+		if (test_bit(TU_FLAG_IN_PROCESS | TU_FLAG_NACK, &tu->flags)) {
+			ret = -EBUSY;
+			break;
+		}
+
 		memset(tu->regs, 0, TU_NUM_REGS);
 		tu->reg_idx = 0;
 		break;
@@ -135,6 +152,10 @@
 		break;
 	}
 
+	/* If an error occurred somewhen, we NACK everything until next STOP */
+	if (ret)
+		set_bit(TU_FLAG_NACK, &tu->flags);
+
 	return ret;
 }
 
--- linux-qcom-6.8.0.orig/drivers/i2c/i2c-smbus.c
+++ linux-qcom-6.8.0/drivers/i2c/i2c-smbus.c
@@ -34,6 +34,7 @@
 	struct i2c_client *client = i2c_verify_client(dev);
 	struct alert_data *data = addrp;
 	struct i2c_driver *driver;
+	int ret;
 
 	if (!client || client->addr != data->addr)
 		return 0;
@@ -47,16 +48,47 @@
 	device_lock(dev);
 	if (client->dev.driver) {
 		driver = to_i2c_driver(client->dev.driver);
-		if (driver->alert)
+		if (driver->alert) {
+			/* Stop iterating after we find the device */
 			driver->alert(client, data->type, data->data);
-		else
+			ret = -EBUSY;
+		} else {
 			dev_warn(&client->dev, "no driver alert()!\n");
-	} else
+			ret = -EOPNOTSUPP;
+		}
+	} else {
 		dev_dbg(&client->dev, "alert with no driver\n");
+		ret = -ENODEV;
+	}
+	device_unlock(dev);
+
+	return ret;
+}
+
+/* Same as above, but call back all drivers with alert handler */
+
+static int smbus_do_alert_force(struct device *dev, void *addrp)
+{
+	struct i2c_client *client = i2c_verify_client(dev);
+	struct alert_data *data = addrp;
+	struct i2c_driver *driver;
+
+	if (!client || (client->flags & I2C_CLIENT_TEN))
+		return 0;
+
+	/*
+	 * Drivers should either disable alerts, or provide at least
+	 * a minimal handler. Lock so the driver won't change.
+	 */
+	device_lock(dev);
+	if (client->dev.driver) {
+		driver = to_i2c_driver(client->dev.driver);
+		if (driver->alert)
+			driver->alert(client, data->type, data->data);
+	}
 	device_unlock(dev);
 
-	/* Stop iterating after we find the device */
-	return -EBUSY;
+	return 0;
 }
 
 /*
@@ -67,6 +99,7 @@
 {
 	struct i2c_smbus_alert *alert = d;
 	struct i2c_client *ara;
+	unsigned short prev_addr = I2C_CLIENT_END; /* Not a valid address */
 
 	ara = alert->ara;
 
@@ -94,8 +127,25 @@
 			data.addr, data.data);
 
 		/* Notify driver for the device which issued the alert */
-		device_for_each_child(&ara->adapter->dev, &data,
-				      smbus_do_alert);
+		status = device_for_each_child(&ara->adapter->dev, &data,
+					       smbus_do_alert);
+		/*
+		 * If we read the same address more than once, and the alert
+		 * was not handled by a driver, it won't do any good to repeat
+		 * the loop because it will never terminate. Try again, this
+		 * time calling the alert handlers of all devices connected to
+		 * the bus, and abort the loop afterwards. If this helps, we
+		 * are all set. If it doesn't, there is nothing else we can do,
+		 * so we might as well abort the loop.
+		 * Note: This assumes that a driver with alert handler handles
+		 * the alert properly and clears it if necessary.
+		 */
+		if (data.addr == prev_addr && status != -EBUSY) {
+			device_for_each_child(&ara->adapter->dev, &data,
+					      smbus_do_alert_force);
+			break;
+		}
+		prev_addr = data.addr;
 	}
 
 	return IRQ_HANDLED;
--- linux-qcom-6.8.0.orig/drivers/i2c/muxes/i2c-demux-pinctrl.c
+++ linux-qcom-6.8.0/drivers/i2c/muxes/i2c-demux-pinctrl.c
@@ -261,7 +261,9 @@
 	pm_runtime_no_callbacks(&pdev->dev);
 
 	/* switch to first parent as active master */
-	i2c_demux_activate_master(priv, 0);
+	err = i2c_demux_activate_master(priv, 0);
+	if (err)
+		goto err_rollback;
 
 	err = device_create_file(&pdev->dev, &dev_attr_available_masters);
 	if (err)
--- linux-qcom-6.8.0.orig/drivers/i3c/master.c
+++ linux-qcom-6.8.0/drivers/i3c/master.c
@@ -281,7 +281,8 @@
 	struct i3c_device_info devinfo;
 	u16 manuf, part, ext;
 
-	i3c_device_get_info(i3cdev, &devinfo);
+	if (i3cdev->desc)
+		devinfo = i3cdev->desc->info;
 	manuf = I3C_PID_MANUF_ID(devinfo.pid);
 	part = I3C_PID_PART_ID(devinfo.pid);
 	ext = I3C_PID_EXTRA_INFO(devinfo.pid);
@@ -343,10 +344,10 @@
 };
 
 static enum i3c_addr_slot_status
-i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr)
+i3c_bus_get_addr_slot_status_mask(struct i3c_bus *bus, u16 addr, u32 mask)
 {
 	unsigned long status;
-	int bitpos = addr * 2;
+	int bitpos = addr * I3C_ADDR_SLOT_STATUS_BITS;
 
 	if (addr > I2C_MAX_ADDR)
 		return I3C_ADDR_SLOT_RSVD;
@@ -354,22 +355,33 @@
 	status = bus->addrslots[bitpos / BITS_PER_LONG];
 	status >>= bitpos % BITS_PER_LONG;
 
-	return status & I3C_ADDR_SLOT_STATUS_MASK;
+	return status & mask;
 }
 
-static void i3c_bus_set_addr_slot_status(struct i3c_bus *bus, u16 addr,
-					 enum i3c_addr_slot_status status)
+static enum i3c_addr_slot_status
+i3c_bus_get_addr_slot_status(struct i3c_bus *bus, u16 addr)
 {
-	int bitpos = addr * 2;
+	return i3c_bus_get_addr_slot_status_mask(bus, addr, I3C_ADDR_SLOT_STATUS_MASK);
+}
+
+static void i3c_bus_set_addr_slot_status_mask(struct i3c_bus *bus, u16 addr,
+					      enum i3c_addr_slot_status status, u32 mask)
+{
+	int bitpos = addr * I3C_ADDR_SLOT_STATUS_BITS;
 	unsigned long *ptr;
 
 	if (addr > I2C_MAX_ADDR)
 		return;
 
 	ptr = bus->addrslots + (bitpos / BITS_PER_LONG);
-	*ptr &= ~((unsigned long)I3C_ADDR_SLOT_STATUS_MASK <<
-						(bitpos % BITS_PER_LONG));
-	*ptr |= (unsigned long)status << (bitpos % BITS_PER_LONG);
+	*ptr &= ~((unsigned long)mask << (bitpos % BITS_PER_LONG));
+	*ptr |= ((unsigned long)status & mask) << (bitpos % BITS_PER_LONG);
+}
+
+static void i3c_bus_set_addr_slot_status(struct i3c_bus *bus, u16 addr,
+					 enum i3c_addr_slot_status status)
+{
+	i3c_bus_set_addr_slot_status_mask(bus, addr, status, I3C_ADDR_SLOT_STATUS_MASK);
 }
 
 static bool i3c_bus_dev_addr_is_avail(struct i3c_bus *bus, u8 addr)
@@ -381,13 +393,44 @@
 	return status == I3C_ADDR_SLOT_FREE;
 }
 
+/*
+ * ┌────┬─────────────┬───┬─────────┬───┐
+ * │S/Sr│ 7'h7E RnW=0 │ACK│ ENTDAA  │ T ├────┐
+ * └────┴─────────────┴───┴─────────┴───┘    │
+ * ┌─────────────────────────────────────────┘
+ * │  ┌──┬─────────────┬───┬─────────────────┬────────────────┬───┬─────────┐
+ * └─►│Sr│7'h7E RnW=1  │ACK│48bit UID BCR DCR│Assign 7bit Addr│PAR│ ACK/NACK│
+ *    └──┴─────────────┴───┴─────────────────┴────────────────┴───┴─────────┘
+ * Some master controllers (such as HCI) need to prepare the entire above transaction before
+ * sending it out to the I3C bus. This means that a 7-bit dynamic address needs to be allocated
+ * before knowing the target device's UID information.
+ *
+ * However, some I3C targets may request specific addresses (called as "init_dyn_addr"), which is
+ * typically specified by the DT-'s assigned-address property. Lower addresses having higher IBI
+ * priority. If it is available, i3c_bus_get_free_addr() preferably return a free address that is
+ * not in the list of desired addresses (called as "init_dyn_addr"). This allows the device with
+ * the "init_dyn_addr" to switch to its "init_dyn_addr" when it hot-joins the I3C bus. Otherwise,
+ * if the "init_dyn_addr" is already in use by another I3C device, the target device will not be
+ * able to switch to its desired address.
+ *
+ * If the previous step fails, fallback returning one of the remaining unassigned address,
+ * regardless of its state in the desired list.
+ */
 static int i3c_bus_get_free_addr(struct i3c_bus *bus, u8 start_addr)
 {
 	enum i3c_addr_slot_status status;
 	u8 addr;
 
 	for (addr = start_addr; addr < I3C_MAX_ADDR; addr++) {
-		status = i3c_bus_get_addr_slot_status(bus, addr);
+		status = i3c_bus_get_addr_slot_status_mask(bus, addr,
+							   I3C_ADDR_SLOT_EXT_STATUS_MASK);
+		if (status == I3C_ADDR_SLOT_FREE)
+			return addr;
+	}
+
+	for (addr = start_addr; addr < I3C_MAX_ADDR; addr++) {
+		status = i3c_bus_get_addr_slot_status_mask(bus, addr,
+							   I3C_ADDR_SLOT_STATUS_MASK);
 		if (status == I3C_ADDR_SLOT_FREE)
 			return addr;
 	}
@@ -1415,7 +1458,7 @@
 					     I3C_ADDR_SLOT_FREE);
 
 	if (dev->boardinfo && dev->boardinfo->init_dyn_addr)
-		i3c_bus_set_addr_slot_status(&master->bus, dev->info.dyn_addr,
+		i3c_bus_set_addr_slot_status(&master->bus, dev->boardinfo->init_dyn_addr,
 					     I3C_ADDR_SLOT_FREE);
 }
 
@@ -1504,16 +1547,9 @@
 				       u8 old_dyn_addr)
 {
 	struct i3c_master_controller *master = i3c_dev_get_master(dev);
-	enum i3c_addr_slot_status status;
 	int ret;
 
-	if (dev->info.dyn_addr != old_dyn_addr &&
-	    (!dev->boardinfo ||
-	     dev->info.dyn_addr != dev->boardinfo->init_dyn_addr)) {
-		status = i3c_bus_get_addr_slot_status(&master->bus,
-						      dev->info.dyn_addr);
-		if (status != I3C_ADDR_SLOT_FREE)
-			return -EBUSY;
+	if (dev->info.dyn_addr != old_dyn_addr) {
 		i3c_bus_set_addr_slot_status(&master->bus,
 					     dev->info.dyn_addr,
 					     I3C_ADDR_SLOT_I3C_DEV);
@@ -1866,6 +1902,12 @@
 		goto err_bus_cleanup;
 	}
 
+	if (master->ops->set_speed) {
+		ret = master->ops->set_speed(master, I3C_OPEN_DRAIN_SLOW_SPEED);
+		if (ret)
+			goto err_bus_cleanup;
+	}
+
 	/*
 	 * Reset all dynamic address that may have been assigned before
 	 * (assigned by the bootloader for example).
@@ -1874,6 +1916,12 @@
 	if (ret && ret != I3C_ERROR_M2)
 		goto err_bus_cleanup;
 
+	if (master->ops->set_speed) {
+		ret = master->ops->set_speed(master, I3C_OPEN_DRAIN_NORMAL_SPEED);
+		if (ret)
+			goto err_bus_cleanup;
+	}
+
 	/* Disable all slave events before starting DAA. */
 	ret = i3c_master_disec_locked(master, I3C_BROADCAST_ADDR,
 				      I3C_CCC_EVENT_SIR | I3C_CCC_EVENT_MR |
@@ -1904,9 +1952,11 @@
 			goto err_rstdaa;
 		}
 
-		i3c_bus_set_addr_slot_status(&master->bus,
-					     i3cboardinfo->init_dyn_addr,
-					     I3C_ADDR_SLOT_I3C_DEV);
+		/* Do not mark as occupied until real device exist in bus */
+		i3c_bus_set_addr_slot_status_mask(&master->bus,
+						  i3cboardinfo->init_dyn_addr,
+						  I3C_ADDR_SLOT_EXT_DESIRED,
+						  I3C_ADDR_SLOT_EXT_STATUS_MASK);
 
 		/*
 		 * Only try to create/attach devices that have a static
@@ -2037,11 +2087,16 @@
 			ibireq.max_payload_len = olddev->ibi->max_payload_len;
 			ibireq.num_slots = olddev->ibi->num_slots;
 
-			if (olddev->ibi->enabled) {
+			if (olddev->ibi->enabled)
 				enable_ibi = true;
-				i3c_dev_disable_ibi_locked(olddev);
-			}
-
+			/*
+			 * The olddev should not receive any commands on the
+			 * i3c bus as it does not exist and has been assigned
+			 * a new address. This will result in NACK or timeout.
+			 * So, update the olddev->ibi->enabled flag to false
+			 * to avoid DISEC with OldAddr.
+			 */
+			olddev->ibi->enabled = false;
 			i3c_dev_free_ibi_locked(olddev);
 		}
 		mutex_unlock(&olddev->ibi_lock);
@@ -2069,7 +2124,8 @@
 	else
 		expected_dyn_addr = newdev->info.dyn_addr;
 
-	if (newdev->info.dyn_addr != expected_dyn_addr) {
+	if (newdev->info.dyn_addr != expected_dyn_addr &&
+	    i3c_bus_get_addr_slot_status(&master->bus, expected_dyn_addr) == I3C_ADDR_SLOT_FREE) {
 		/*
 		 * Try to apply the expected dynamic address. If it fails, keep
 		 * the address assigned by the master.
--- linux-qcom-6.8.0.orig/drivers/i3c/master/dw-i3c-master.c
+++ linux-qcom-6.8.0/drivers/i3c/master/dw-i3c-master.c
@@ -1136,6 +1136,23 @@
 	data->ibi_pool = NULL;
 }
 
+static void dw_i3c_master_enable_sir_signal(struct dw_i3c_master *master, bool enable)
+{
+	u32 reg;
+
+	reg = readl(master->regs + INTR_STATUS_EN);
+	reg &= ~INTR_IBI_THLD_STAT;
+	if (enable)
+		reg |= INTR_IBI_THLD_STAT;
+	writel(reg, master->regs + INTR_STATUS_EN);
+
+	reg = readl(master->regs + INTR_SIGNAL_EN);
+	reg &= ~INTR_IBI_THLD_STAT;
+	if (enable)
+		reg |= INTR_IBI_THLD_STAT;
+	writel(reg, master->regs + INTR_SIGNAL_EN);
+}
+
 static void dw_i3c_master_set_sir_enabled(struct dw_i3c_master *master,
 					  struct i3c_dev_desc *dev,
 					  u8 idx, bool enable)
@@ -1163,28 +1180,41 @@
 		global = reg == 0xffffffff;
 		reg &= ~BIT(idx);
 	} else {
-		global = reg == 0;
+		bool hj_rejected = !!(readl(master->regs + DEVICE_CTRL) & DEV_CTRL_HOT_JOIN_NACK);
+
 		reg |= BIT(idx);
+		global = (reg == 0xffffffff) && hj_rejected;
 	}
 	writel(reg, master->regs + IBI_SIR_REQ_REJECT);
 
-	if (global) {
-		reg = readl(master->regs + INTR_STATUS_EN);
-		reg &= ~INTR_IBI_THLD_STAT;
-		if (enable)
-			reg |= INTR_IBI_THLD_STAT;
-		writel(reg, master->regs + INTR_STATUS_EN);
-
-		reg = readl(master->regs + INTR_SIGNAL_EN);
-		reg &= ~INTR_IBI_THLD_STAT;
-		if (enable)
-			reg |= INTR_IBI_THLD_STAT;
-		writel(reg, master->regs + INTR_SIGNAL_EN);
-	}
+	if (global)
+		dw_i3c_master_enable_sir_signal(master, enable);
+
 
 	spin_unlock_irqrestore(&master->devs_lock, flags);
 }
 
+static int dw_i3c_master_enable_hotjoin(struct i3c_master_controller *m)
+{
+	struct dw_i3c_master *master = to_dw_i3c_master(m);
+
+	dw_i3c_master_enable_sir_signal(master, true);
+	writel(readl(master->regs + DEVICE_CTRL) & ~DEV_CTRL_HOT_JOIN_NACK,
+	       master->regs + DEVICE_CTRL);
+
+	return 0;
+}
+
+static int dw_i3c_master_disable_hotjoin(struct i3c_master_controller *m)
+{
+	struct dw_i3c_master *master = to_dw_i3c_master(m);
+
+	writel(readl(master->regs + DEVICE_CTRL) | DEV_CTRL_HOT_JOIN_NACK,
+	       master->regs + DEVICE_CTRL);
+
+	return 0;
+}
+
 static int dw_i3c_master_enable_ibi(struct i3c_dev_desc *dev)
 {
 	struct dw_i3c_i2c_dev_data *data = i3c_dev_get_master_data(dev);
@@ -1324,6 +1354,8 @@
 
 		if (IBI_TYPE_SIRQ(reg)) {
 			dw_i3c_master_handle_ibi_sir(master, reg);
+		} else if (IBI_TYPE_HJ(reg)) {
+			queue_work(master->base.wq, &master->hj_work);
 		} else {
 			len = IBI_QUEUE_STATUS_DATA_LEN(reg);
 			dev_info(&master->base.dev,
@@ -1391,6 +1423,8 @@
 	.enable_ibi = dw_i3c_master_enable_ibi,
 	.disable_ibi = dw_i3c_master_disable_ibi,
 	.recycle_ibi_slot = dw_i3c_master_recycle_ibi_slot,
+	.enable_hotjoin = dw_i3c_master_enable_hotjoin,
+	.disable_hotjoin = dw_i3c_master_disable_hotjoin,
 };
 
 /* default platform ops implementations */
@@ -1410,6 +1444,14 @@
 	.set_dat_ibi = dw_i3c_platform_set_dat_ibi_nop,
 };
 
+static void dw_i3c_hj_work(struct work_struct *work)
+{
+	struct dw_i3c_master *master =
+		container_of(work, typeof(*master), hj_work);
+
+	i3c_master_do_daa(&master->base);
+}
+
 int dw_i3c_common_probe(struct dw_i3c_master *master,
 			struct platform_device *pdev)
 {
@@ -1467,6 +1509,7 @@
 	if (master->ibi_capable)
 		ops = &dw_mipi_i3c_ibi_ops;
 
+	INIT_WORK(&master->hj_work, dw_i3c_hj_work);
 	ret = i3c_master_register(&master->base, &pdev->dev, ops, false);
 	if (ret)
 		goto err_assert_rst;
@@ -1485,6 +1528,7 @@
 
 void dw_i3c_common_remove(struct dw_i3c_master *master)
 {
+	cancel_work_sync(&master->hj_work);
 	i3c_master_unregister(&master->base);
 
 	reset_control_assert(master->core_rst);
--- linux-qcom-6.8.0.orig/drivers/i3c/master/dw-i3c-master.h
+++ linux-qcom-6.8.0/drivers/i3c/master/dw-i3c-master.h
@@ -57,6 +57,8 @@
 
 	/* platform-specific data */
 	const struct dw_i3c_platform_ops *platform_ops;
+
+	struct work_struct hj_work;
 };
 
 struct dw_i3c_platform_ops {
--- linux-qcom-6.8.0.orig/drivers/i3c/master/i3c-master-cdns.c
+++ linux-qcom-6.8.0/drivers/i3c/master/i3c-master-cdns.c
@@ -1666,6 +1666,7 @@
 {
 	struct cdns_i3c_master *master = platform_get_drvdata(pdev);
 
+	cancel_work_sync(&master->hj_work);
 	i3c_master_unregister(&master->base);
 
 	clk_disable_unprepare(master->sysclk);
--- linux-qcom-6.8.0.orig/drivers/i3c/master/mipi-i3c-hci/core.c
+++ linux-qcom-6.8.0/drivers/i3c/master/mipi-i3c-hci/core.c
@@ -631,6 +631,7 @@
 static int i3c_hci_init(struct i3c_hci *hci)
 {
 	u32 regval, offset;
+	bool size_in_dwords;
 	int ret;
 
 	/* Validate HCI hardware version */
@@ -654,11 +655,16 @@
 	hci->caps = reg_read(HC_CAPABILITIES);
 	DBG("caps = %#x", hci->caps);
 
+	size_in_dwords = hci->version_major < 1 ||
+			 (hci->version_major == 1 && hci->version_minor < 1);
+
 	regval = reg_read(DAT_SECTION);
 	offset = FIELD_GET(DAT_TABLE_OFFSET, regval);
 	hci->DAT_regs = offset ? hci->base_regs + offset : NULL;
 	hci->DAT_entries = FIELD_GET(DAT_TABLE_SIZE, regval);
 	hci->DAT_entry_size = FIELD_GET(DAT_ENTRY_SIZE, regval) ? 0 : 8;
+	if (size_in_dwords)
+		hci->DAT_entries = 4 * hci->DAT_entries / hci->DAT_entry_size;
 	dev_info(&hci->master.dev, "DAT: %u %u-bytes entries at offset %#x\n",
 		 hci->DAT_entries, hci->DAT_entry_size, offset);
 
@@ -667,6 +673,8 @@
 	hci->DCT_regs = offset ? hci->base_regs + offset : NULL;
 	hci->DCT_entries = FIELD_GET(DCT_TABLE_SIZE, regval);
 	hci->DCT_entry_size = FIELD_GET(DCT_ENTRY_SIZE, regval) ? 0 : 16;
+	if (size_in_dwords)
+		hci->DCT_entries = 4 * hci->DCT_entries / hci->DCT_entry_size;
 	dev_info(&hci->master.dev, "DCT: %u %u-bytes entries at offset %#x\n",
 		 hci->DCT_entries, hci->DCT_entry_size, offset);
 
--- linux-qcom-6.8.0.orig/drivers/i3c/master/mipi-i3c-hci/dma.c
+++ linux-qcom-6.8.0/drivers/i3c/master/mipi-i3c-hci/dma.c
@@ -174,10 +174,10 @@
 	for (i = 0; i < rings->total; i++) {
 		rh = &rings->headers[i];
 
+		rh_reg_write(INTR_SIGNAL_ENABLE, 0);
 		rh_reg_write(RING_CONTROL, 0);
 		rh_reg_write(CR_SETUP, 0);
 		rh_reg_write(IBI_SETUP, 0);
-		rh_reg_write(INTR_SIGNAL_ENABLE, 0);
 
 		if (rh->xfer)
 			dma_free_coherent(&hci->master.dev,
@@ -294,7 +294,10 @@
 
 		rh->ibi_chunk_sz = dma_get_cache_alignment();
 		rh->ibi_chunk_sz *= IBI_CHUNK_CACHELINES;
-		BUG_ON(rh->ibi_chunk_sz > 256);
+		if (rh->ibi_chunk_sz > 256) {
+			ret = -EINVAL;
+			goto err_out;
+		}
 
 		ibi_status_ring_sz = rh->ibi_status_sz * rh->ibi_status_entries;
 		ibi_data_ring_sz = rh->ibi_chunk_sz * rh->ibi_chunks_total;
--- linux-qcom-6.8.0.orig/drivers/i3c/master/svc-i3c-master.c
+++ linux-qcom-6.8.0/drivers/i3c/master/svc-i3c-master.c
@@ -128,8 +128,8 @@
 /* This parameter depends on the implementation and may be tuned */
 #define SVC_I3C_FIFO_SIZE 16
 
-#define SVC_I3C_EVENT_IBI	BIT(0)
-#define SVC_I3C_EVENT_HOTJOIN	BIT(1)
+#define SVC_I3C_EVENT_IBI	GENMASK(7, 0)
+#define SVC_I3C_EVENT_HOTJOIN	BIT(31)
 
 struct svc_i3c_cmd {
 	u8 addr;
@@ -182,6 +182,7 @@
  * @ibi.lock: IBI lock
  * @lock: Transfer lock, protect between IBI work thread and callbacks from master
  * @enabled_events: Bit masks for enable events (IBI, HotJoin).
+ * @mctrl_config: Configuration value in SVC_I3C_MCTRL for setting speed back.
  */
 struct svc_i3c_master {
 	struct i3c_master_controller base;
@@ -211,7 +212,8 @@
 		spinlock_t lock;
 	} ibi;
 	struct mutex lock;
-	int enabled_events;
+	u32 enabled_events;
+	u32 mctrl_config;
 };
 
 /**
@@ -415,6 +417,19 @@
 	int ret;
 
 	mutex_lock(&master->lock);
+	/*
+	 * IBIWON may be set before SVC_I3C_MCTRL_REQUEST_AUTO_IBI, causing
+	 * readl_relaxed_poll_timeout() to return immediately. Consequently,
+	 * ibitype will be 0 since it was last updated only after the 8th SCL
+	 * cycle, leading to missed client IBI handlers.
+	 *
+	 * A typical scenario is when IBIWON occurs and bus arbitration is lost
+	 * at svc_i3c_master_priv_xfers().
+	 *
+	 * Clear SVC_I3C_MINT_IBIWON before sending SVC_I3C_MCTRL_REQUEST_AUTO_IBI.
+	 */
+	writel(SVC_I3C_MINT_IBIWON, master->regs + SVC_I3C_MSTATUS);
+
 	/* Acknowledge the incoming interrupt with the AUTOIBI mechanism */
 	writel(SVC_I3C_MCTRL_REQUEST_AUTO_IBI |
 	       SVC_I3C_MCTRL_IBIRESP_AUTO,
@@ -429,9 +444,6 @@
 		goto reenable_ibis;
 	}
 
-	/* Clear the interrupt status */
-	writel(SVC_I3C_MINT_IBIWON, master->regs + SVC_I3C_MSTATUS);
-
 	status = readl(master->regs + SVC_I3C_MSTATUS);
 	ibitype = SVC_I3C_MSTATUS_IBITYPE(status);
 	ibiaddr = SVC_I3C_MSTATUS_IBIADDR(status);
@@ -519,6 +531,54 @@
 	return IRQ_HANDLED;
 }
 
+static int svc_i3c_master_set_speed(struct i3c_master_controller *m,
+				     enum i3c_open_drain_speed speed)
+{
+	struct svc_i3c_master *master = to_svc_i3c_master(m);
+	struct i3c_bus *bus = i3c_master_get_bus(&master->base);
+	u32 ppbaud, odbaud, odhpp, mconfig;
+	unsigned long fclk_rate;
+	int ret;
+
+	ret = pm_runtime_resume_and_get(master->dev);
+	if (ret < 0) {
+		dev_err(master->dev, "<%s> Cannot get runtime PM.\n", __func__);
+		return ret;
+	}
+
+	switch (speed) {
+	case I3C_OPEN_DRAIN_SLOW_SPEED:
+		fclk_rate = clk_get_rate(master->fclk);
+		if (!fclk_rate) {
+			ret = -EINVAL;
+			goto rpm_out;
+		}
+		/*
+		 * Set 50% duty-cycle I2C speed to I3C OPEN-DRAIN mode, so the first
+		 * broadcast address is visible to all I2C/I3C devices on the I3C bus.
+		 * I3C device working as a I2C device will turn off its 50ns Spike
+		 * Filter to change to I3C mode.
+		 */
+		mconfig = master->mctrl_config;
+		ppbaud = FIELD_GET(GENMASK(11, 8), mconfig);
+		odhpp = 0;
+		odbaud = DIV_ROUND_UP(fclk_rate, bus->scl_rate.i2c * (2 + 2 * ppbaud)) - 1;
+		mconfig &= ~GENMASK(24, 16);
+		mconfig |= SVC_I3C_MCONFIG_ODBAUD(odbaud) | SVC_I3C_MCONFIG_ODHPP(odhpp);
+		writel(mconfig, master->regs + SVC_I3C_MCONFIG);
+		break;
+	case I3C_OPEN_DRAIN_NORMAL_SPEED:
+		writel(master->mctrl_config, master->regs + SVC_I3C_MCONFIG);
+		break;
+	}
+
+rpm_out:
+	pm_runtime_mark_last_busy(master->dev);
+	pm_runtime_put_autosuspend(master->dev);
+
+	return ret;
+}
+
 static int svc_i3c_master_bus_init(struct i3c_master_controller *m)
 {
 	struct svc_i3c_master *master = to_svc_i3c_master(m);
@@ -601,6 +661,7 @@
 	      SVC_I3C_MCONFIG_I2CBAUD(i2cbaud);
 	writel(reg, master->regs + SVC_I3C_MCONFIG);
 
+	master->mctrl_config = reg;
 	/* Master core's registration */
 	ret = i3c_master_get_free_addr(m, 0);
 	if (ret < 0)
@@ -957,12 +1018,27 @@
 		goto rpm_out;
 	}
 
-	/* Register all devices who participated to the core */
-	for (i = 0; i < dev_nb; i++) {
-		ret = i3c_master_add_i3c_dev_locked(m, addrs[i]);
-		if (ret)
-			goto rpm_out;
-	}
+	/*
+	 * Register all devices who participated to the core
+	 *
+	 * If two devices (A and B) are detected in DAA and address 0xa is assigned to
+	 * device A and 0xb to device B, a failure in i3c_master_add_i3c_dev_locked()
+	 * for device A (addr: 0xa) could prevent device B (addr: 0xb) from being
+	 * registered on the bus. The I3C stack might still consider 0xb a free
+	 * address. If a subsequent Hotjoin occurs, 0xb might be assigned to Device A,
+	 * causing both devices A and B to use the same address 0xb, violating the I3C
+	 * specification.
+	 *
+	 * The return value for i3c_master_add_i3c_dev_locked() should not be checked
+	 * because subsequent steps will scan the entire I3C bus, independent of
+	 * whether i3c_master_add_i3c_dev_locked() returns success.
+	 *
+	 * If device A registration fails, there is still a chance to register device
+	 * B. i3c_master_add_i3c_dev_locked() can reset DAA if a failure occurs while
+	 * retrieving device information.
+	 */
+	for (i = 0; i < dev_nb; i++)
+		i3c_master_add_i3c_dev_locked(m, addrs[i]);
 
 	/* Configure IBI auto-rules */
 	ret = svc_i3c_update_ibirules(master);
@@ -1042,29 +1118,59 @@
 			       u8 *in, const u8 *out, unsigned int xfer_len,
 			       unsigned int *actual_len, bool continued)
 {
+	int retry = 2;
 	u32 reg;
 	int ret;
 
 	/* clean SVC_I3C_MINT_IBIWON w1c bits */
 	writel(SVC_I3C_MINT_IBIWON, master->regs + SVC_I3C_MSTATUS);
 
-	writel(SVC_I3C_MCTRL_REQUEST_START_ADDR |
-	       xfer_type |
-	       SVC_I3C_MCTRL_IBIRESP_NACK |
-	       SVC_I3C_MCTRL_DIR(rnw) |
-	       SVC_I3C_MCTRL_ADDR(addr) |
-	       SVC_I3C_MCTRL_RDTERM(*actual_len),
-	       master->regs + SVC_I3C_MCTRL);
 
-	ret = readl_poll_timeout(master->regs + SVC_I3C_MSTATUS, reg,
+	while (retry--) {
+		writel(SVC_I3C_MCTRL_REQUEST_START_ADDR |
+		       xfer_type |
+		       SVC_I3C_MCTRL_IBIRESP_NACK |
+		       SVC_I3C_MCTRL_DIR(rnw) |
+		       SVC_I3C_MCTRL_ADDR(addr) |
+		       SVC_I3C_MCTRL_RDTERM(*actual_len),
+		       master->regs + SVC_I3C_MCTRL);
+
+		ret = readl_poll_timeout(master->regs + SVC_I3C_MSTATUS, reg,
 				 SVC_I3C_MSTATUS_MCTRLDONE(reg), 0, 1000);
-	if (ret)
-		goto emit_stop;
+		if (ret)
+			goto emit_stop;
 
-	if (readl(master->regs + SVC_I3C_MERRWARN) & SVC_I3C_MERRWARN_NACK) {
-		ret = -ENXIO;
-		*actual_len = 0;
-		goto emit_stop;
+		if (readl(master->regs + SVC_I3C_MERRWARN) & SVC_I3C_MERRWARN_NACK) {
+			/*
+			 * According to I3C Spec 1.1.1, 11-Jun-2021, section: 5.1.2.2.3.
+			 * If the Controller chooses to start an I3C Message with an I3C Dynamic
+			 * Address, then special provisions shall be made because that same I3C
+			 * Target may be initiating an IBI or a Controller Role Request. So, one of
+			 * three things may happen: (skip 1, 2)
+			 *
+			 * 3. The Addresses match and the RnW bits also match, and so neither
+			 * Controller nor Target will ACK since both are expecting the other side to
+			 * provide ACK. As a result, each side might think it had "won" arbitration,
+			 * but neither side would continue, as each would subsequently see that the
+			 * other did not provide ACK.
+			 * ...
+			 * For either value of RnW: Due to the NACK, the Controller shall defer the
+			 * Private Write or Private Read, and should typically transmit the Target
+			 * Address again after a Repeated START (i.e., the next one or any one prior
+			 * to a STOP in the Frame). Since the Address Header following a Repeated
+			 * START is not arbitrated, the Controller will always win (see Section
+			 * 5.1.2.2.4).
+			 */
+			if (retry && addr != 0x7e) {
+				writel(SVC_I3C_MERRWARN_NACK, master->regs + SVC_I3C_MERRWARN);
+			} else {
+				ret = -ENXIO;
+				*actual_len = 0;
+				goto emit_stop;
+			}
+		} else {
+			break;
+		}
 	}
 
 	/*
@@ -1080,7 +1186,7 @@
 	 * and yield the above events handler.
 	 */
 	if (SVC_I3C_MSTATUS_IBIWON(reg)) {
-		ret = -ENXIO;
+		ret = -EAGAIN;
 		*actual_len = 0;
 		goto emit_stop;
 	}
@@ -1495,7 +1601,7 @@
 		return ret;
 	}
 
-	master->enabled_events |= SVC_I3C_EVENT_IBI;
+	master->enabled_events++;
 	svc_i3c_master_enable_interrupts(master, SVC_I3C_MINT_SLVSTART);
 
 	return i3c_master_enec_locked(m, dev->info.dyn_addr, I3C_CCC_EVENT_SIR);
@@ -1507,7 +1613,7 @@
 	struct svc_i3c_master *master = to_svc_i3c_master(m);
 	int ret;
 
-	master->enabled_events &= ~SVC_I3C_EVENT_IBI;
+	master->enabled_events--;
 	if (!master->enabled_events)
 		svc_i3c_master_disable_interrupts(master);
 
@@ -1580,6 +1686,7 @@
 	.disable_ibi = svc_i3c_master_disable_ibi,
 	.enable_hotjoin = svc_i3c_master_enable_hotjoin,
 	.disable_hotjoin = svc_i3c_master_disable_hotjoin,
+	.set_speed = svc_i3c_master_set_speed,
 };
 
 static int svc_i3c_master_prepare_clks(struct svc_i3c_master *master)
@@ -1697,8 +1804,8 @@
 rpm_disable:
 	pm_runtime_dont_use_autosuspend(&pdev->dev);
 	pm_runtime_put_noidle(&pdev->dev);
-	pm_runtime_set_suspended(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
+	pm_runtime_set_suspended(&pdev->dev);
 
 err_disable_clks:
 	svc_i3c_master_unprepare_clks(master);
@@ -1710,6 +1817,7 @@
 {
 	struct svc_i3c_master *master = platform_get_drvdata(pdev);
 
+	cancel_work_sync(&master->hj_work);
 	i3c_master_unregister(&master->base);
 
 	pm_runtime_dont_use_autosuspend(&pdev->dev);
--- linux-qcom-6.8.0.orig/drivers/idle/intel_idle.c
+++ linux-qcom-6.8.0/drivers/idle/intel_idle.c
@@ -121,6 +121,12 @@
 #define CPUIDLE_FLAG_INIT_XSTATE	BIT(17)
 
 /*
+ * Ignore the sub-state when matching mwait hints between the ACPI _CST and
+ * custom tables.
+ */
+#define CPUIDLE_FLAG_PARTIAL_HINT_MATCH	BIT(18)
+
+/*
  * MWAIT takes an 8-bit "hint" in EAX "suggesting"
  * the C-state (top nibble) and sub-state (bottom nibble)
  * 0x00 means "MWAIT(C1)", 0x10 means "MWAIT(C2)" etc.
@@ -1022,6 +1028,88 @@
 		.enter = NULL }
 };
 
+static struct cpuidle_state gnr_cstates[] __initdata = {
+	{
+		.name = "C1",
+		.desc = "MWAIT 0x00",
+		.flags = MWAIT2flg(0x00),
+		.exit_latency = 1,
+		.target_residency = 1,
+		.enter = &intel_idle,
+		.enter_s2idle = intel_idle_s2idle, },
+	{
+		.name = "C1E",
+		.desc = "MWAIT 0x01",
+		.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
+		.exit_latency = 4,
+		.target_residency = 4,
+		.enter = &intel_idle,
+		.enter_s2idle = intel_idle_s2idle, },
+	{
+		.name = "C6",
+		.desc = "MWAIT 0x20",
+		.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED |
+					   CPUIDLE_FLAG_INIT_XSTATE |
+					   CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
+		.exit_latency = 170,
+		.target_residency = 650,
+		.enter = &intel_idle,
+		.enter_s2idle = intel_idle_s2idle, },
+	{
+		.name = "C6P",
+		.desc = "MWAIT 0x21",
+		.flags = MWAIT2flg(0x21) | CPUIDLE_FLAG_TLB_FLUSHED |
+					   CPUIDLE_FLAG_INIT_XSTATE |
+					   CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
+		.exit_latency = 210,
+		.target_residency = 1000,
+		.enter = &intel_idle,
+		.enter_s2idle = intel_idle_s2idle, },
+	{
+		.enter = NULL }
+};
+
+static struct cpuidle_state gnrd_cstates[] __initdata = {
+	{
+		.name = "C1",
+		.desc = "MWAIT 0x00",
+		.flags = MWAIT2flg(0x00),
+		.exit_latency = 1,
+		.target_residency = 1,
+		.enter = &intel_idle,
+		.enter_s2idle = intel_idle_s2idle, },
+	{
+		.name = "C1E",
+		.desc = "MWAIT 0x01",
+		.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
+		.exit_latency = 4,
+		.target_residency = 4,
+		.enter = &intel_idle,
+		.enter_s2idle = intel_idle_s2idle, },
+	{
+		.name = "C6",
+		.desc = "MWAIT 0x20",
+		.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED |
+					   CPUIDLE_FLAG_INIT_XSTATE |
+					   CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
+		.exit_latency = 220,
+		.target_residency = 650,
+		.enter = &intel_idle,
+		.enter_s2idle = intel_idle_s2idle, },
+	{
+		.name = "C6P",
+		.desc = "MWAIT 0x21",
+		.flags = MWAIT2flg(0x21) | CPUIDLE_FLAG_TLB_FLUSHED |
+					   CPUIDLE_FLAG_INIT_XSTATE |
+					   CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
+		.exit_latency = 240,
+		.target_residency = 750,
+		.enter = &intel_idle,
+		.enter_s2idle = intel_idle_s2idle, },
+	{
+		.enter = NULL }
+};
+
 static struct cpuidle_state atom_cstates[] __initdata = {
 	{
 		.name = "C1E",
@@ -1315,7 +1403,8 @@
 	{
 		.name = "C6S",
 		.desc = "MWAIT 0x22",
-		.flags = MWAIT2flg(0x22) | CPUIDLE_FLAG_TLB_FLUSHED,
+		.flags = MWAIT2flg(0x22) | CPUIDLE_FLAG_TLB_FLUSHED |
+					   CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
 		.exit_latency = 270,
 		.target_residency = 700,
 		.enter = &intel_idle,
@@ -1323,7 +1412,8 @@
 	{
 		.name = "C6SP",
 		.desc = "MWAIT 0x23",
-		.flags = MWAIT2flg(0x23) | CPUIDLE_FLAG_TLB_FLUSHED,
+		.flags = MWAIT2flg(0x23) | CPUIDLE_FLAG_TLB_FLUSHED |
+					   CPUIDLE_FLAG_PARTIAL_HINT_MATCH,
 		.exit_latency = 310,
 		.target_residency = 900,
 		.enter = &intel_idle,
@@ -1453,6 +1543,18 @@
 	.use_acpi = true,
 };
 
+static const struct idle_cpu idle_cpu_gnr __initconst = {
+	.state_table = gnr_cstates,
+	.disable_promotion_to_c1e = true,
+	.use_acpi = true,
+};
+
+static const struct idle_cpu idle_cpu_gnrd __initconst = {
+	.state_table = gnrd_cstates,
+	.disable_promotion_to_c1e = true,
+	.use_acpi = true,
+};
+
 static const struct idle_cpu idle_cpu_avn __initconst = {
 	.state_table = avn_cstates,
 	.disable_promotion_to_c1e = true,
@@ -1475,6 +1577,10 @@
 	.use_acpi = true,
 };
 
+static const struct idle_cpu idle_cpu_tmt __initconst = {
+	.disable_promotion_to_c1e = true,
+};
+
 static const struct idle_cpu idle_cpu_snr __initconst = {
 	.state_table = snr_cstates,
 	.disable_promotion_to_c1e = true,
@@ -1533,11 +1639,15 @@
 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GRACEMONT,	&idle_cpu_gmt),
 	X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X,	&idle_cpu_spr),
 	X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X,	&idle_cpu_spr),
+	X86_MATCH_INTEL_FAM6_MODEL(GRANITERAPIDS_X,	&idle_cpu_gnr),
+	X86_MATCH_INTEL_FAM6_MODEL(GRANITERAPIDS_D,	&idle_cpu_gnrd),
 	X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL,	&idle_cpu_knl),
 	X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM,	&idle_cpu_knl),
 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT,	&idle_cpu_bxt),
 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_PLUS,	&idle_cpu_bxt),
 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT_D,	&idle_cpu_dnv),
+	X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT,	&idle_cpu_tmt),
+	X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L,	&idle_cpu_tmt),
 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D,	&idle_cpu_snr),
 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_CRESTMONT,	&idle_cpu_grr),
 	X86_MATCH_INTEL_FAM6_MODEL(ATOM_CRESTMONT_X,	&idle_cpu_srf),
@@ -1692,7 +1802,7 @@
 	}
 }
 
-static bool __init intel_idle_off_by_default(u32 mwait_hint)
+static bool __init intel_idle_off_by_default(unsigned int flags, u32 mwait_hint)
 {
 	int cstate, limit;
 
@@ -1709,7 +1819,15 @@
 	 * the interesting states are ACPI_CSTATE_FFH.
 	 */
 	for (cstate = 1; cstate < limit; cstate++) {
-		if (acpi_state_table.states[cstate].address == mwait_hint)
+		u32 acpi_hint = acpi_state_table.states[cstate].address;
+		u32 table_hint = mwait_hint;
+
+		if (flags & CPUIDLE_FLAG_PARTIAL_HINT_MATCH) {
+			acpi_hint &= ~MWAIT_SUBSTATE_MASK;
+			table_hint &= ~MWAIT_SUBSTATE_MASK;
+		}
+
+		if (acpi_hint == table_hint)
 			return false;
 	}
 	return true;
@@ -1719,7 +1837,10 @@
 
 static inline bool intel_idle_acpi_cst_extract(void) { return false; }
 static inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { }
-static inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; }
+static inline bool intel_idle_off_by_default(unsigned int flags, u32 mwait_hint)
+{
+	return false;
+}
 #endif /* !CONFIG_ACPI_PROCESSOR_CSTATE */
 
 /**
@@ -2045,7 +2166,7 @@
 
 		if ((disabled_states_mask & BIT(drv->state_count)) ||
 		    ((icpu->use_acpi || force_use_acpi) &&
-		     intel_idle_off_by_default(mwait_hint) &&
+		     intel_idle_off_by_default(state->flags, mwait_hint) &&
 		     !(state->flags & CPUIDLE_FLAG_ALWAYS_ENABLE)))
 			state->flags |= CPUIDLE_FLAG_OFF;
 
@@ -2074,7 +2195,7 @@
 
 	drv->state_count = 1;
 
-	if (icpu)
+	if (icpu && icpu->state_table)
 		intel_idle_init_cstates_icpu(drv);
 	else
 		intel_idle_init_cstates_acpi(drv);
@@ -2208,7 +2329,11 @@
 
 	icpu = (const struct idle_cpu *)id->driver_data;
 	if (icpu) {
-		cpuidle_state_table = icpu->state_table;
+		if (icpu->state_table)
+			cpuidle_state_table = icpu->state_table;
+		else if (!intel_idle_acpi_cst_extract())
+			return -ENODEV;
+
 		auto_demotion_disable_flags = icpu->auto_demotion_disable_flags;
 		if (icpu->disable_promotion_to_c1e)
 			c1e_promotion = C1E_PROMOTION_DISABLE;
--- linux-qcom-6.8.0.orig/drivers/iio/Kconfig
+++ linux-qcom-6.8.0/drivers/iio/Kconfig
@@ -71,6 +71,15 @@
 	help
 	  Provides helper functions for setting up triggered events.
 
+config IIO_BACKEND
+	tristate
+	help
+	  Framework to handle complex IIO aggregate devices. The typical
+	  architecture that can make use of this framework is to have one
+	  device as the frontend device which can be "linked" against one or
+	  multiple backend devices. The framework then makes it easy to get
+	  and control such backend devices.
+
 source "drivers/iio/accel/Kconfig"
 source "drivers/iio/adc/Kconfig"
 source "drivers/iio/addac/Kconfig"
--- linux-qcom-6.8.0.orig/drivers/iio/Makefile
+++ linux-qcom-6.8.0/drivers/iio/Makefile
@@ -13,6 +13,7 @@
 obj-$(CONFIG_IIO_SW_DEVICE) += industrialio-sw-device.o
 obj-$(CONFIG_IIO_SW_TRIGGER) += industrialio-sw-trigger.o
 obj-$(CONFIG_IIO_TRIGGERED_EVENT) += industrialio-triggered-event.o
+obj-$(CONFIG_IIO_BACKEND) += industrialio-backend.o
 
 obj-y += accel/
 obj-y += adc/
--- linux-qcom-6.8.0.orig/drivers/iio/accel/Kconfig
+++ linux-qcom-6.8.0/drivers/iio/accel/Kconfig
@@ -326,6 +326,8 @@
 config FXLS8962AF
 	tristate
 	depends on I2C || !I2C # cannot be built-in for modular I2C
+	select IIO_BUFFER
+	select IIO_KFIFO_BUF
 
 config FXLS8962AF_I2C
 	tristate "NXP FXLS8962AF/FXLS8964AF Accelerometer I2C Driver"
@@ -414,6 +416,8 @@
 
 config IIO_KX022A
 	tristate
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 
 config IIO_KX022A_SPI
 	tristate "Kionix KX022A tri-axis digital accelerometer SPI interface"
--- linux-qcom-6.8.0.orig/drivers/iio/accel/bma400_core.c
+++ linux-qcom-6.8.0/drivers/iio/accel/bma400_core.c
@@ -1219,7 +1219,8 @@
 static int bma400_tap_event_en(struct bma400_data *data,
 			       enum iio_event_direction dir, int state)
 {
-	unsigned int mask, field_value;
+	unsigned int mask;
+	unsigned int field_value = 0;
 	int ret;
 
 	/*
--- linux-qcom-6.8.0.orig/drivers/iio/accel/kionix-kx022a.c
+++ linux-qcom-6.8.0/drivers/iio/accel/kionix-kx022a.c
@@ -594,7 +594,7 @@
 	if (ret)
 		return ret;
 
-	*val = le16_to_cpu(data->buffer[0]);
+	*val = (s16)le16_to_cpu(data->buffer[0]);
 
 	return IIO_VAL_INT;
 }
--- linux-qcom-6.8.0.orig/drivers/iio/accel/mxc4005.c
+++ linux-qcom-6.8.0/drivers/iio/accel/mxc4005.c
@@ -5,6 +5,7 @@
  * Copyright (c) 2014, Intel Corporation.
  */
 
+#include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/i2c.h>
 #include <linux/iio/iio.h>
@@ -27,11 +28,16 @@
 #define MXC4005_REG_ZOUT_UPPER		0x07
 #define MXC4005_REG_ZOUT_LOWER		0x08
 
+#define MXC4005_REG_INT_MASK0		0x0A
+
 #define MXC4005_REG_INT_MASK1		0x0B
 #define MXC4005_REG_INT_MASK1_BIT_DRDYE	0x01
 
+#define MXC4005_REG_INT_CLR0		0x00
+
 #define MXC4005_REG_INT_CLR1		0x01
 #define MXC4005_REG_INT_CLR1_BIT_DRDYC	0x01
+#define MXC4005_REG_INT_CLR1_SW_RST	0x10
 
 #define MXC4005_REG_CONTROL		0x0D
 #define MXC4005_REG_CONTROL_MASK_FSR	GENMASK(6, 5)
@@ -39,6 +45,9 @@
 
 #define MXC4005_REG_DEVICE_ID		0x0E
 
+/* Datasheet does not specify a reset time, this is a conservative guess */
+#define MXC4005_RESET_TIME_US		2000
+
 enum mxc4005_axis {
 	AXIS_X,
 	AXIS_Y,
@@ -62,6 +71,8 @@
 		s64 timestamp __aligned(8);
 	} scan;
 	bool trigger_enabled;
+	unsigned int control;
+	unsigned int int_mask1;
 };
 
 /*
@@ -113,7 +124,9 @@
 static bool mxc4005_is_writeable_reg(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
+	case MXC4005_REG_INT_CLR0:
 	case MXC4005_REG_INT_CLR1:
+	case MXC4005_REG_INT_MASK0:
 	case MXC4005_REG_INT_MASK1:
 	case MXC4005_REG_CONTROL:
 		return true;
@@ -330,23 +343,20 @@
 {
 	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
 	struct mxc4005_data *data = iio_priv(indio_dev);
+	unsigned int val;
 	int ret;
 
 	mutex_lock(&data->mutex);
-	if (state) {
-		ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1,
-				   MXC4005_REG_INT_MASK1_BIT_DRDYE);
-	} else {
-		ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1,
-				   ~MXC4005_REG_INT_MASK1_BIT_DRDYE);
-	}
 
+	val = state ? MXC4005_REG_INT_MASK1_BIT_DRDYE : 0;
+	ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, val);
 	if (ret < 0) {
 		mutex_unlock(&data->mutex);
 		dev_err(data->dev, "failed to update reg_int_mask1");
 		return ret;
 	}
 
+	data->int_mask1 = val;
 	data->trigger_enabled = state;
 	mutex_unlock(&data->mutex);
 
@@ -382,6 +392,21 @@
 
 	dev_dbg(data->dev, "MXC4005 chip id %02x\n", reg);
 
+	ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1,
+			   MXC4005_REG_INT_CLR1_SW_RST);
+	if (ret < 0)
+		return dev_err_probe(data->dev, ret, "resetting chip\n");
+
+	fsleep(MXC4005_RESET_TIME_US);
+
+	ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK0, 0);
+	if (ret < 0)
+		return dev_err_probe(data->dev, ret, "writing INT_MASK0\n");
+
+	ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, 0);
+	if (ret < 0)
+		return dev_err_probe(data->dev, ret, "writing INT_MASK1\n");
+
 	return 0;
 }
 
@@ -469,6 +494,58 @@
 	return devm_iio_device_register(&client->dev, indio_dev);
 }
 
+static int mxc4005_suspend(struct device *dev)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct mxc4005_data *data = iio_priv(indio_dev);
+	int ret;
+
+	/* Save control to restore it on resume */
+	ret = regmap_read(data->regmap, MXC4005_REG_CONTROL, &data->control);
+	if (ret < 0)
+		dev_err(data->dev, "failed to read reg_control\n");
+
+	return ret;
+}
+
+static int mxc4005_resume(struct device *dev)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct mxc4005_data *data = iio_priv(indio_dev);
+	int ret;
+
+	ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1,
+			   MXC4005_REG_INT_CLR1_SW_RST);
+	if (ret) {
+		dev_err(data->dev, "failed to reset chip: %d\n", ret);
+		return ret;
+	}
+
+	fsleep(MXC4005_RESET_TIME_US);
+
+	ret = regmap_write(data->regmap, MXC4005_REG_CONTROL, data->control);
+	if (ret) {
+		dev_err(data->dev, "failed to restore control register\n");
+		return ret;
+	}
+
+	ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK0, 0);
+	if (ret) {
+		dev_err(data->dev, "failed to restore interrupt 0 mask\n");
+		return ret;
+	}
+
+	ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1, data->int_mask1);
+	if (ret) {
+		dev_err(data->dev, "failed to restore interrupt 1 mask\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(mxc4005_pm_ops, mxc4005_suspend, mxc4005_resume);
+
 static const struct acpi_device_id mxc4005_acpi_match[] = {
 	{"MXC4005",	0},
 	{"MXC6655",	0},
@@ -495,6 +572,7 @@
 		.name = MXC4005_DRV_NAME,
 		.acpi_match_table = ACPI_PTR(mxc4005_acpi_match),
 		.of_match_table = mxc4005_of_match,
+		.pm = pm_sleep_ptr(&mxc4005_pm_ops),
 	},
 	.probe		= mxc4005_probe,
 	.id_table	= mxc4005_id,
--- linux-qcom-6.8.0.orig/drivers/iio/adc/Kconfig
+++ linux-qcom-6.8.0/drivers/iio/adc/Kconfig
@@ -291,7 +291,7 @@
 config AD9467
 	tristate "Analog Devices AD9467 High Speed ADC driver"
 	depends on SPI
-	depends on ADI_AXI_ADC
+	select IIO_BACKEND
 	help
 	  Say yes here to build support for Analog Devices:
 	  * AD9467 16-Bit, 200 MSPS/250 MSPS Analog-to-Digital Converter
@@ -309,7 +309,7 @@
 	select IIO_BUFFER_HW_CONSUMER
 	select IIO_BUFFER_DMAENGINE
 	select REGMAP_MMIO
-	depends on OF
+	select IIO_BACKEND
 	help
 	  Say yes here to build support for Analog Devices Generic
 	  AXI ADC IP core. The IP core is used for interfacing with
@@ -1013,6 +1013,31 @@
 	  To compile this driver as a module, choose M here: the module will
 	  be called qcom-spmi-adc5.
 
+config QCOM_SPMI_ADC5_GEN3
+	tristate "Qualcomm Technologies Inc. SPMI PMIC5 GEN3 ADC"
+	depends on SPMI && THERMAL
+	select REGMAP_SPMI
+	select QCOM_VADC_COMMON
+	help
+	  This is the IIO Voltage PMIC5 Gen3 ADC driver for Qualcomm Technologies Inc. PMICs.
+
+	  The driver supports reading multiple channels. The ADC is a 16-bit
+	  sigma-delta ADC. The hardware supports calibrated results for
+	  conversion requests and clients include reading phone power supply
+	  voltage, on board system thermistors connected to the PMIC ADC,
+	  PMIC die temperature, charger temperature, battery current, USB voltage
+	  input and voltage signals connected to supported PMIC GPIO pins. The
+	  hardware supports internal pull-up for thermistors and can choose between
+	  a 30k, 100k or 400k ohm pull up using the ADC channels.
+
+	  In addition, the same driver supports ADC thermal monitoring devices too.
+	  They appear as thermal zones with multiple trip points. A thermal client sets
+	  threshold temperature for both warm and cool trips and gets updated when a
+	  threshold is reached.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called qcom-spmi-adc5-gen3.
+
 config RCAR_GYRO_ADC
 	tristate "Renesas R-Car GyroADC driver"
 	depends on ARCH_RCAR_GEN2 || COMPILE_TEST
@@ -1338,6 +1363,8 @@
 config TI_ADS8688
 	tristate "Texas Instruments ADS8688"
 	depends on SPI
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	help
 	  If you say yes here you get support for Texas Instruments ADS8684 and
 	  and ADS8688 ADC chips
@@ -1348,6 +1375,8 @@
 config TI_ADS124S08
 	tristate "Texas Instruments ADS124S08"
 	depends on SPI
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	help
 	  If you say yes here you get support for Texas Instruments ADS124S08
 	  and ADS124S06 ADC chips
@@ -1382,6 +1411,9 @@
 config TI_LMP92064
 	tristate "Texas Instruments LMP92064 ADC driver"
 	depends on SPI
+	select REGMAP_SPI
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	help
 	  Say yes here to build support for the LMP92064 Precision Current and Voltage
 	  sensor.
--- linux-qcom-6.8.0.orig/drivers/iio/adc/Makefile
+++ linux-qcom-6.8.0/drivers/iio/adc/Makefile
@@ -88,6 +88,7 @@
 obj-$(CONFIG_NPCM_ADC) += npcm_adc.o
 obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o
 obj-$(CONFIG_QCOM_SPMI_ADC5) += qcom-spmi-adc5.o
+obj-$(CONFIG_QCOM_SPMI_ADC5_GEN3) += qcom-spmi-adc5-gen3.o
 obj-$(CONFIG_QCOM_SPMI_IADC) += qcom-spmi-iadc.o
 obj-$(CONFIG_QCOM_SPMI_RRADC) += qcom-spmi-rradc.o
 obj-$(CONFIG_QCOM_VADC_COMMON) += qcom-vadc-common.o
--- linux-qcom-6.8.0.orig/drivers/iio/adc/ad7124.c
+++ linux-qcom-6.8.0/drivers/iio/adc/ad7124.c
@@ -14,7 +14,8 @@
 #include <linux/kernel.h>
 #include <linux/kfifo.h>
 #include <linux/module.h>
-#include <linux/of.h>
+#include <linux/mod_devicetable.h>
+#include <linux/property.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
 
@@ -146,15 +147,18 @@
 struct ad7124_channel_config {
 	bool live;
 	unsigned int cfg_slot;
-	enum ad7124_ref_sel refsel;
-	bool bipolar;
-	bool buf_positive;
-	bool buf_negative;
-	unsigned int vref_mv;
-	unsigned int pga_bits;
-	unsigned int odr;
-	unsigned int odr_sel_bits;
-	unsigned int filter_type;
+	/* Following fields are used to compare equality. */
+	struct_group(config_props,
+		enum ad7124_ref_sel refsel;
+		bool bipolar;
+		bool buf_positive;
+		bool buf_negative;
+		unsigned int vref_mv;
+		unsigned int pga_bits;
+		unsigned int odr;
+		unsigned int odr_sel_bits;
+		unsigned int filter_type;
+	);
 };
 
 struct ad7124_channel {
@@ -333,11 +337,12 @@
 	ptrdiff_t cmp_size;
 	int i;
 
-	cmp_size = (u8 *)&cfg->live - (u8 *)cfg;
+	cmp_size = sizeof_field(struct ad7124_channel_config, config_props);
 	for (i = 0; i < st->num_channels; i++) {
 		cfg_aux = &st->channels[i].cfg;
 
-		if (cfg_aux->live && !memcmp(cfg, cfg_aux, cmp_size))
+		if (cfg_aux->live &&
+		    !memcmp(&cfg->config_props, &cfg_aux->config_props, cmp_size))
 			return cfg_aux;
 	}
 
@@ -638,7 +643,7 @@
 
 	switch (info) {
 	case IIO_CHAN_INFO_SAMP_FREQ:
-		if (val2 != 0) {
+		if (val2 != 0 || val == 0) {
 			ret = -EINVAL;
 			break;
 		}
@@ -761,6 +766,7 @@
 	if (ret < 0)
 		return ret;
 
+	fsleep(200);
 	timeout = 100;
 	do {
 		ret = ad_sd_read_reg(&st->sd, AD7124_STATUS, 1, &readval);
@@ -807,22 +813,19 @@
 	return 0;
 }
 
-static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev,
-					  struct device_node *np)
+static int ad7124_parse_channel_config(struct iio_dev *indio_dev,
+				       struct device *dev)
 {
 	struct ad7124_state *st = iio_priv(indio_dev);
 	struct ad7124_channel_config *cfg;
 	struct ad7124_channel *channels;
-	struct device_node *child;
 	struct iio_chan_spec *chan;
 	unsigned int ain[2], channel = 0, tmp;
 	int ret;
 
-	st->num_channels = of_get_available_child_count(np);
-	if (!st->num_channels) {
-		dev_err(indio_dev->dev.parent, "no channel children\n");
-		return -ENODEV;
-	}
+	st->num_channels = device_get_child_node_count(dev);
+	if (!st->num_channels)
+		return dev_err_probe(dev, -ENODEV, "no channel children\n");
 
 	chan = devm_kcalloc(indio_dev->dev.parent, st->num_channels,
 			    sizeof(*chan), GFP_KERNEL);
@@ -838,39 +841,37 @@
 	indio_dev->num_channels = st->num_channels;
 	st->channels = channels;
 
-	for_each_available_child_of_node(np, child) {
-		cfg = &st->channels[channel].cfg;
-
-		ret = of_property_read_u32(child, "reg", &channel);
+	device_for_each_child_node_scoped(dev, child) {
+		ret = fwnode_property_read_u32(child, "reg", &channel);
 		if (ret)
-			goto err;
+			return ret;
 
-		if (channel >= indio_dev->num_channels) {
-			dev_err(indio_dev->dev.parent,
+		if (channel >= indio_dev->num_channels)
+			return dev_err_probe(dev, -EINVAL,
 				"Channel index >= number of channels\n");
-			ret = -EINVAL;
-			goto err;
-		}
 
-		ret = of_property_read_u32_array(child, "diff-channels",
-						 ain, 2);
+		ret = fwnode_property_read_u32_array(child, "diff-channels",
+						     ain, 2);
 		if (ret)
-			goto err;
+			return ret;
 
 		st->channels[channel].nr = channel;
 		st->channels[channel].ain = AD7124_CHANNEL_AINP(ain[0]) |
 						  AD7124_CHANNEL_AINM(ain[1]);
 
-		cfg->bipolar = of_property_read_bool(child, "bipolar");
+		cfg = &st->channels[channel].cfg;
+		cfg->bipolar = fwnode_property_read_bool(child, "bipolar");
 
-		ret = of_property_read_u32(child, "adi,reference-select", &tmp);
+		ret = fwnode_property_read_u32(child, "adi,reference-select", &tmp);
 		if (ret)
 			cfg->refsel = AD7124_INT_REF;
 		else
 			cfg->refsel = tmp;
 
-		cfg->buf_positive = of_property_read_bool(child, "adi,buffered-positive");
-		cfg->buf_negative = of_property_read_bool(child, "adi,buffered-negative");
+		cfg->buf_positive =
+			fwnode_property_read_bool(child, "adi,buffered-positive");
+		cfg->buf_negative =
+			fwnode_property_read_bool(child, "adi,buffered-negative");
 
 		chan[channel] = ad7124_channel_template;
 		chan[channel].address = channel;
@@ -880,10 +881,6 @@
 	}
 
 	return 0;
-err:
-	of_node_put(child);
-
-	return ret;
 }
 
 static int ad7124_setup(struct ad7124_state *st)
@@ -926,6 +923,9 @@
 		 * set all channels to this default value.
 		 */
 		ad7124_set_channel_odr(st, i, 10);
+
+		/* Disable all channels to prevent unintended conversions. */
+		ad_sd_write_reg(&st->sd, AD7124_CHANNEL(i), 2, 0);
 	}
 
 	return ret;
@@ -943,9 +943,7 @@
 	struct iio_dev *indio_dev;
 	int i, ret;
 
-	info = of_device_get_match_data(&spi->dev);
-	if (!info)
-		info = (void *)spi_get_device_id(spi)->driver_data;
+	info = spi_get_device_match_data(spi);
 	if (!info)
 		return -ENODEV;
 
@@ -965,7 +963,7 @@
 	if (ret < 0)
 		return ret;
 
-	ret = ad7124_of_parse_channel_config(indio_dev, spi->dev.of_node);
+	ret = ad7124_parse_channel_config(indio_dev, &spi->dev);
 	if (ret < 0)
 		return ret;
 
--- linux-qcom-6.8.0.orig/drivers/iio/adc/ad7192.c
+++ linux-qcom-6.8.0/drivers/iio/adc/ad7192.c
@@ -17,7 +17,9 @@
 #include <linux/err.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
-#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/property.h>
 
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
@@ -364,19 +366,19 @@
 		freq <= AD7192_EXT_FREQ_MHZ_MAX);
 }
 
-static int ad7192_of_clock_select(struct ad7192_state *st)
+static int ad7192_clock_select(struct ad7192_state *st)
 {
-	struct device_node *np = st->sd.spi->dev.of_node;
+	struct device *dev = &st->sd.spi->dev;
 	unsigned int clock_sel;
 
 	clock_sel = AD7192_CLK_INT;
 
 	/* use internal clock */
 	if (!st->mclk) {
-		if (of_property_read_bool(np, "adi,int-clock-output-enable"))
+		if (device_property_read_bool(dev, "adi,int-clock-output-enable"))
 			clock_sel = AD7192_CLK_INT_CO;
 	} else {
-		if (of_property_read_bool(np, "adi,clock-xtal"))
+		if (device_property_read_bool(dev, "adi,clock-xtal"))
 			clock_sel = AD7192_CLK_EXT_MCLK1_2;
 		else
 			clock_sel = AD7192_CLK_EXT_MCLK2;
@@ -385,7 +387,7 @@
 	return clock_sel;
 }
 
-static int ad7192_setup(struct iio_dev *indio_dev, struct device_node *np)
+static int ad7192_setup(struct iio_dev *indio_dev, struct device *dev)
 {
 	struct ad7192_state *st = iio_priv(indio_dev);
 	bool rej60_en, refin2_en;
@@ -407,7 +409,7 @@
 	id = FIELD_GET(AD7192_ID_MASK, id);
 
 	if (id != st->chip_info->chip_id)
-		dev_warn(&st->sd.spi->dev, "device ID query failed (0x%X != 0x%X)\n",
+		dev_warn(dev, "device ID query failed (0x%X != 0x%X)\n",
 			 id, st->chip_info->chip_id);
 
 	st->mode = FIELD_PREP(AD7192_MODE_SEL_MASK, AD7192_MODE_IDLE) |
@@ -416,30 +418,30 @@
 
 	st->conf = FIELD_PREP(AD7192_CONF_GAIN_MASK, 0);
 
-	rej60_en = of_property_read_bool(np, "adi,rejection-60-Hz-enable");
+	rej60_en = device_property_read_bool(dev, "adi,rejection-60-Hz-enable");
 	if (rej60_en)
 		st->mode |= AD7192_MODE_REJ60;
 
-	refin2_en = of_property_read_bool(np, "adi,refin2-pins-enable");
+	refin2_en = device_property_read_bool(dev, "adi,refin2-pins-enable");
 	if (refin2_en && st->chip_info->chip_id != CHIPID_AD7195)
 		st->conf |= AD7192_CONF_REFSEL;
 
 	st->conf &= ~AD7192_CONF_CHOP;
 
-	buf_en = of_property_read_bool(np, "adi,buffer-enable");
+	buf_en = device_property_read_bool(dev, "adi,buffer-enable");
 	if (buf_en)
 		st->conf |= AD7192_CONF_BUF;
 
-	bipolar = of_property_read_bool(np, "bipolar");
+	bipolar = device_property_read_bool(dev, "bipolar");
 	if (!bipolar)
 		st->conf |= AD7192_CONF_UNIPOLAR;
 
-	burnout_curr_en = of_property_read_bool(np,
-						"adi,burnout-currents-enable");
+	burnout_curr_en = device_property_read_bool(dev,
+						    "adi,burnout-currents-enable");
 	if (burnout_curr_en && buf_en) {
 		st->conf |= AD7192_CONF_BURN;
 	} else if (burnout_curr_en) {
-		dev_warn(&st->sd.spi->dev,
+		dev_warn(dev,
 			 "Can't enable burnout currents: see CHOP or buffer\n");
 	}
 
@@ -1117,9 +1119,10 @@
 	}
 	st->int_vref_mv = ret / 1000;
 
-	st->chip_info = of_device_get_match_data(&spi->dev);
+	st->chip_info = spi_get_device_match_data(spi);
 	if (!st->chip_info)
-		st->chip_info = (void *)spi_get_device_id(spi)->driver_data;
+		return -ENODEV;
+
 	indio_dev->name = st->chip_info->name;
 	indio_dev->modes = INDIO_DIRECT_MODE;
 	indio_dev->channels = st->chip_info->channels;
@@ -1140,7 +1143,7 @@
 	if (IS_ERR(st->mclk))
 		return PTR_ERR(st->mclk);
 
-	st->clock_sel = ad7192_of_clock_select(st);
+	st->clock_sel = ad7192_clock_select(st);
 
 	if (st->clock_sel == AD7192_CLK_EXT_MCLK1_2 ||
 	    st->clock_sel == AD7192_CLK_EXT_MCLK2) {
@@ -1152,7 +1155,7 @@
 		}
 	}
 
-	ret = ad7192_setup(indio_dev, spi->dev.of_node);
+	ret = ad7192_setup(indio_dev, &spi->dev);
 	if (ret)
 		return ret;
 
--- linux-qcom-6.8.0.orig/drivers/iio/adc/ad7266.c
+++ linux-qcom-6.8.0/drivers/iio/adc/ad7266.c
@@ -157,6 +157,8 @@
 		ret = ad7266_read_single(st, val, chan->address);
 		iio_device_release_direct_mode(indio_dev);
 
+		if (ret < 0)
+			return ret;
 		*val = (*val >> 2) & 0xfff;
 		if (chan->scan_type.sign == 's')
 			*val = sign_extend32(*val,
--- linux-qcom-6.8.0.orig/drivers/iio/adc/ad7606.c
+++ linux-qcom-6.8.0/drivers/iio/adc/ad7606.c
@@ -49,7 +49,7 @@
 	1, 2, 4, 8, 16, 32, 64, 128,
 };
 
-static int ad7606_reset(struct ad7606_state *st)
+int ad7606_reset(struct ad7606_state *st)
 {
 	if (st->gpio_reset) {
 		gpiod_set_value(st->gpio_reset, 1);
@@ -60,6 +60,7 @@
 
 	return -ENODEV;
 }
+EXPORT_SYMBOL_NS_GPL(ad7606_reset, IIO_AD7606);
 
 static int ad7606_reg_access(struct iio_dev *indio_dev,
 			     unsigned int reg,
@@ -88,31 +89,6 @@
 {
 	unsigned int num = st->chip_info->num_channels - 1;
 	u16 *data = st->data;
-	int ret;
-
-	/*
-	 * The frstdata signal is set to high while and after reading the sample
-	 * of the first channel and low for all other channels. This can be used
-	 * to check that the incoming data is correctly aligned. During normal
-	 * operation the data should never become unaligned, but some glitch or
-	 * electrostatic discharge might cause an extra read or clock cycle.
-	 * Monitoring the frstdata signal allows to recover from such failure
-	 * situations.
-	 */
-
-	if (st->gpio_frstdata) {
-		ret = st->bops->read_block(st->dev, 1, data);
-		if (ret)
-			return ret;
-
-		if (!gpiod_get_value(st->gpio_frstdata)) {
-			ad7606_reset(st);
-			return -EIO;
-		}
-
-		data++;
-		num--;
-	}
 
 	return st->bops->read_block(st->dev, num, data);
 }
@@ -239,9 +215,9 @@
 	struct ad7606_state *st = iio_priv(indio_dev);
 	DECLARE_BITMAP(values, 3);
 
-	values[0] = val;
+	values[0] = val & GENMASK(2, 0);
 
-	gpiod_set_array_value(ARRAY_SIZE(values), st->gpio_os->desc,
+	gpiod_set_array_value(st->gpio_os->ndescs, st->gpio_os->desc,
 			      st->gpio_os->info, values);
 
 	/* AD7616 requires a reset to update value */
@@ -446,7 +422,7 @@
 		return PTR_ERR(st->gpio_range);
 
 	st->gpio_standby = devm_gpiod_get_optional(dev, "standby",
-						   GPIOD_OUT_HIGH);
+						   GPIOD_OUT_LOW);
 	if (IS_ERR(st->gpio_standby))
 		return PTR_ERR(st->gpio_standby);
 
@@ -689,7 +665,7 @@
 
 	if (st->gpio_standby) {
 		gpiod_set_value(st->gpio_range, 1);
-		gpiod_set_value(st->gpio_standby, 0);
+		gpiod_set_value(st->gpio_standby, 1);
 	}
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/iio/adc/ad7606.h
+++ linux-qcom-6.8.0/drivers/iio/adc/ad7606.h
@@ -151,6 +151,8 @@
 		 const char *name, unsigned int id,
 		 const struct ad7606_bus_ops *bops);
 
+int ad7606_reset(struct ad7606_state *st);
+
 enum ad7606_supported_device_ids {
 	ID_AD7605_4,
 	ID_AD7606_8,
--- linux-qcom-6.8.0.orig/drivers/iio/adc/ad7606_par.c
+++ linux-qcom-6.8.0/drivers/iio/adc/ad7606_par.c
@@ -7,6 +7,7 @@
 
 #include <linux/mod_devicetable.h>
 #include <linux/module.h>
+#include <linux/gpio/consumer.h>
 #include <linux/platform_device.h>
 #include <linux/types.h>
 #include <linux/err.h>
@@ -21,8 +22,29 @@
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct ad7606_state *st = iio_priv(indio_dev);
 
-	insw((unsigned long)st->base_address, buf, count);
 
+	/*
+	 * On the parallel interface, the frstdata signal is set to high while
+	 * and after reading the sample of the first channel and low for all
+	 * other channels.  This can be used to check that the incoming data is
+	 * correctly aligned.  During normal operation the data should never
+	 * become unaligned, but some glitch or electrostatic discharge might
+	 * cause an extra read or clock cycle.  Monitoring the frstdata signal
+	 * allows to recover from such failure situations.
+	 */
+	int num = count;
+	u16 *_buf = buf;
+
+	if (st->gpio_frstdata) {
+		insw((unsigned long)st->base_address, _buf, 1);
+		if (!gpiod_get_value(st->gpio_frstdata)) {
+			ad7606_reset(st);
+			return -EIO;
+		}
+		_buf++;
+		num--;
+	}
+	insw((unsigned long)st->base_address, _buf, num);
 	return 0;
 }
 
@@ -35,8 +57,28 @@
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct ad7606_state *st = iio_priv(indio_dev);
-
-	insb((unsigned long)st->base_address, buf, count * 2);
+	/*
+	 * On the parallel interface, the frstdata signal is set to high while
+	 * and after reading the sample of the first channel and low for all
+	 * other channels.  This can be used to check that the incoming data is
+	 * correctly aligned.  During normal operation the data should never
+	 * become unaligned, but some glitch or electrostatic discharge might
+	 * cause an extra read or clock cycle.  Monitoring the frstdata signal
+	 * allows to recover from such failure situations.
+	 */
+	int num = count;
+	u16 *_buf = buf;
+
+	if (st->gpio_frstdata) {
+		insb((unsigned long)st->base_address, _buf, 2);
+		if (!gpiod_get_value(st->gpio_frstdata)) {
+			ad7606_reset(st);
+			return -EIO;
+		}
+		_buf++;
+		num--;
+	}
+	insb((unsigned long)st->base_address, _buf, num * 2);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/iio/adc/ad7606_spi.c
+++ linux-qcom-6.8.0/drivers/iio/adc/ad7606_spi.c
@@ -249,8 +249,9 @@
 static int ad7606B_sw_mode_config(struct iio_dev *indio_dev)
 {
 	struct ad7606_state *st = iio_priv(indio_dev);
-	unsigned long os[3] = {1};
+	DECLARE_BITMAP(os, 3);
 
+	bitmap_fill(os, 3);
 	/*
 	 * Software mode is enabled when all three oversampling
 	 * pins are set to high. If oversampling gpios are defined
@@ -258,7 +259,7 @@
 	 * otherwise, they must be hardwired to VDD
 	 */
 	if (st->gpio_os) {
-		gpiod_set_array_value(ARRAY_SIZE(os),
+		gpiod_set_array_value(st->gpio_os->ndescs,
 				      st->gpio_os->desc, st->gpio_os->info, os);
 	}
 	/* OS of 128 and 256 are available only in software mode */
--- linux-qcom-6.8.0.orig/drivers/iio/adc/ad7780.c
+++ linux-qcom-6.8.0/drivers/iio/adc/ad7780.c
@@ -152,7 +152,7 @@
 
 	switch (m) {
 	case IIO_CHAN_INFO_SCALE:
-		if (val != 0)
+		if (val != 0 || val2 == 0)
 			return -EINVAL;
 
 		vref = st->int_vref_mv * 1000000LL;
--- linux-qcom-6.8.0.orig/drivers/iio/adc/ad7923.c
+++ linux-qcom-6.8.0/drivers/iio/adc/ad7923.c
@@ -48,7 +48,7 @@
 
 struct ad7923_state {
 	struct spi_device		*spi;
-	struct spi_transfer		ring_xfer[5];
+	struct spi_transfer		ring_xfer[9];
 	struct spi_transfer		scan_single_xfer[2];
 	struct spi_message		ring_msg;
 	struct spi_message		scan_single_msg;
@@ -64,7 +64,7 @@
 	 * Length = 8 channels + 4 extra for 8 byte timestamp
 	 */
 	__be16				rx_buf[12] __aligned(IIO_DMA_MINALIGN);
-	__be16				tx_buf[4];
+	__be16				tx_buf[8];
 };
 
 struct ad7923_chip_info {
--- linux-qcom-6.8.0.orig/drivers/iio/adc/ad9467.c
+++ linux-qcom-6.8.0/drivers/iio/adc/ad9467.c
@@ -17,13 +17,12 @@
 #include <linux/of.h>
 
 
+#include <linux/iio/backend.h>
 #include <linux/iio/iio.h>
 #include <linux/iio/sysfs.h>
 
 #include <linux/clk.h>
 
-#include <linux/iio/adc/adi-axi-adc.h>
-
 /*
  * ADI High-Speed ADC common spi interface registers
  * See Application-Note AN-877:
@@ -102,15 +101,20 @@
 #define AD9467_REG_VREF_MASK		0x0F
 
 struct ad9467_chip_info {
-	struct adi_axi_adc_chip_info	axi_adc_info;
-	unsigned int			default_output_mode;
-	unsigned int			vref_mask;
+	const char		*name;
+	unsigned int		id;
+	const struct		iio_chan_spec *channels;
+	unsigned int		num_channels;
+	const unsigned int	(*scale_table)[2];
+	int			num_scales;
+	unsigned long		max_rate;
+	unsigned int		default_output_mode;
+	unsigned int		vref_mask;
 };
 
-#define to_ad9467_chip_info(_info)	\
-	container_of(_info, struct ad9467_chip_info, axi_adc_info)
-
 struct ad9467_state {
+	const struct ad9467_chip_info	*info;
+	struct iio_backend		*back;
 	struct spi_device		*spi;
 	struct clk			*clk;
 	unsigned int			output_mode;
@@ -151,10 +155,10 @@
 	return spi_write(spi, buf, ARRAY_SIZE(buf));
 }
 
-static int ad9467_reg_access(struct adi_axi_adc_conv *conv, unsigned int reg,
+static int ad9467_reg_access(struct iio_dev *indio_dev, unsigned int reg,
 			     unsigned int writeval, unsigned int *readval)
 {
-	struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+	struct ad9467_state *st = iio_priv(indio_dev);
 	struct spi_device *spi = st->spi;
 	int ret;
 
@@ -191,10 +195,10 @@
 	{2300, 8}, {2400, 9}, {2500, 10},
 };
 
-static void __ad9467_get_scale(struct adi_axi_adc_conv *conv, int index,
+static void __ad9467_get_scale(struct ad9467_state *st, int index,
 			       unsigned int *val, unsigned int *val2)
 {
-	const struct adi_axi_adc_chip_info *info = conv->chip_info;
+	const struct ad9467_chip_info *info = st->info;
 	const struct iio_chan_spec *chan = &info->channels[0];
 	unsigned int tmp;
 
@@ -221,60 +225,52 @@
 }
 
 static const struct iio_chan_spec ad9434_channels[] = {
-	AD9467_CHAN(0, 0, 12, 'S'),
+	AD9467_CHAN(0, 0, 12, 's'),
 };
 
 static const struct iio_chan_spec ad9467_channels[] = {
-	AD9467_CHAN(0, 0, 16, 'S'),
+	AD9467_CHAN(0, 0, 16, 's'),
 };
 
 static const struct ad9467_chip_info ad9467_chip_tbl = {
-	.axi_adc_info = {
-		.name = "ad9467",
-		.id = CHIPID_AD9467,
-		.max_rate = 250000000UL,
-		.scale_table = ad9467_scale_table,
-		.num_scales = ARRAY_SIZE(ad9467_scale_table),
-		.channels = ad9467_channels,
-		.num_channels = ARRAY_SIZE(ad9467_channels),
-	},
+	.name = "ad9467",
+	.id = CHIPID_AD9467,
+	.max_rate = 250000000UL,
+	.scale_table = ad9467_scale_table,
+	.num_scales = ARRAY_SIZE(ad9467_scale_table),
+	.channels = ad9467_channels,
+	.num_channels = ARRAY_SIZE(ad9467_channels),
 	.default_output_mode = AD9467_DEF_OUTPUT_MODE,
 	.vref_mask = AD9467_REG_VREF_MASK,
 };
 
 static const struct ad9467_chip_info ad9434_chip_tbl = {
-	.axi_adc_info = {
-		.name = "ad9434",
-		.id = CHIPID_AD9434,
-		.max_rate = 500000000UL,
-		.scale_table = ad9434_scale_table,
-		.num_scales = ARRAY_SIZE(ad9434_scale_table),
-		.channels = ad9434_channels,
-		.num_channels = ARRAY_SIZE(ad9434_channels),
-	},
+	.name = "ad9434",
+	.id = CHIPID_AD9434,
+	.max_rate = 500000000UL,
+	.scale_table = ad9434_scale_table,
+	.num_scales = ARRAY_SIZE(ad9434_scale_table),
+	.channels = ad9434_channels,
+	.num_channels = ARRAY_SIZE(ad9434_channels),
 	.default_output_mode = AD9434_DEF_OUTPUT_MODE,
 	.vref_mask = AD9434_REG_VREF_MASK,
 };
 
 static const struct ad9467_chip_info ad9265_chip_tbl = {
-	.axi_adc_info = {
-		.name = "ad9265",
-		.id = CHIPID_AD9265,
-		.max_rate = 125000000UL,
-		.scale_table = ad9265_scale_table,
-		.num_scales = ARRAY_SIZE(ad9265_scale_table),
-		.channels = ad9467_channels,
-		.num_channels = ARRAY_SIZE(ad9467_channels),
-	},
+	.name = "ad9265",
+	.id = CHIPID_AD9265,
+	.max_rate = 125000000UL,
+	.scale_table = ad9265_scale_table,
+	.num_scales = ARRAY_SIZE(ad9265_scale_table),
+	.channels = ad9467_channels,
+	.num_channels = ARRAY_SIZE(ad9467_channels),
 	.default_output_mode = AD9265_DEF_OUTPUT_MODE,
 	.vref_mask = AD9265_REG_VREF_MASK,
 };
 
-static int ad9467_get_scale(struct adi_axi_adc_conv *conv, int *val, int *val2)
+static int ad9467_get_scale(struct ad9467_state *st, int *val, int *val2)
 {
-	const struct adi_axi_adc_chip_info *info = conv->chip_info;
-	const struct ad9467_chip_info *info1 = to_ad9467_chip_info(info);
-	struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+	const struct ad9467_chip_info *info = st->info;
 	unsigned int i, vref_val;
 	int ret;
 
@@ -282,7 +278,7 @@
 	if (ret < 0)
 		return ret;
 
-	vref_val = ret & info1->vref_mask;
+	vref_val = ret & info->vref_mask;
 
 	for (i = 0; i < info->num_scales; i++) {
 		if (vref_val == info->scale_table[i][1])
@@ -292,15 +288,14 @@
 	if (i == info->num_scales)
 		return -ERANGE;
 
-	__ad9467_get_scale(conv, i, val, val2);
+	__ad9467_get_scale(st, i, val, val2);
 
 	return IIO_VAL_INT_PLUS_MICRO;
 }
 
-static int ad9467_set_scale(struct adi_axi_adc_conv *conv, int val, int val2)
+static int ad9467_set_scale(struct ad9467_state *st, int val, int val2)
 {
-	const struct adi_axi_adc_chip_info *info = conv->chip_info;
-	struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+	const struct ad9467_chip_info *info = st->info;
 	unsigned int scale_val[2];
 	unsigned int i;
 	int ret;
@@ -309,7 +304,7 @@
 		return -EINVAL;
 
 	for (i = 0; i < info->num_scales; i++) {
-		__ad9467_get_scale(conv, i, &scale_val[0], &scale_val[1]);
+		__ad9467_get_scale(st, i, &scale_val[0], &scale_val[1]);
 		if (scale_val[0] != val || scale_val[1] != val2)
 			continue;
 
@@ -326,15 +321,15 @@
 	return -EINVAL;
 }
 
-static int ad9467_read_raw(struct adi_axi_adc_conv *conv,
+static int ad9467_read_raw(struct iio_dev *indio_dev,
 			   struct iio_chan_spec const *chan,
 			   int *val, int *val2, long m)
 {
-	struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+	struct ad9467_state *st = iio_priv(indio_dev);
 
 	switch (m) {
 	case IIO_CHAN_INFO_SCALE:
-		return ad9467_get_scale(conv, val, val2);
+		return ad9467_get_scale(st, val, val2);
 	case IIO_CHAN_INFO_SAMP_FREQ:
 		*val = clk_get_rate(st->clk);
 
@@ -344,17 +339,17 @@
 	}
 }
 
-static int ad9467_write_raw(struct adi_axi_adc_conv *conv,
+static int ad9467_write_raw(struct iio_dev *indio_dev,
 			    struct iio_chan_spec const *chan,
 			    int val, int val2, long mask)
 {
-	const struct adi_axi_adc_chip_info *info = conv->chip_info;
-	struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+	struct ad9467_state *st = iio_priv(indio_dev);
+	const struct ad9467_chip_info *info = st->info;
 	long r_clk;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_SCALE:
-		return ad9467_set_scale(conv, val, val2);
+		return ad9467_set_scale(st, val, val2);
 	case IIO_CHAN_INFO_SAMP_FREQ:
 		r_clk = clk_round_rate(st->clk, val);
 		if (r_clk < 0 || r_clk > info->max_rate) {
@@ -369,13 +364,13 @@
 	}
 }
 
-static int ad9467_read_avail(struct adi_axi_adc_conv *conv,
+static int ad9467_read_avail(struct iio_dev *indio_dev,
 			     struct iio_chan_spec const *chan,
 			     const int **vals, int *type, int *length,
 			     long mask)
 {
-	const struct adi_axi_adc_chip_info *info = conv->chip_info;
-	struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+	struct ad9467_state *st = iio_priv(indio_dev);
+	const struct ad9467_chip_info *info = st->info;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_SCALE:
@@ -389,6 +384,33 @@
 	}
 }
 
+static int ad9467_update_scan_mode(struct iio_dev *indio_dev,
+				   const unsigned long *scan_mask)
+{
+	struct ad9467_state *st = iio_priv(indio_dev);
+	unsigned int c;
+	int ret;
+
+	for (c = 0; c < st->info->num_channels; c++) {
+		if (test_bit(c, scan_mask))
+			ret = iio_backend_chan_enable(st->back, c);
+		else
+			ret = iio_backend_chan_disable(st->back, c);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static const struct iio_info ad9467_info = {
+	.read_raw = ad9467_read_raw,
+	.write_raw = ad9467_write_raw,
+	.update_scan_mode = ad9467_update_scan_mode,
+	.debugfs_reg_access = ad9467_reg_access,
+	.read_avail = ad9467_read_avail,
+};
+
 static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode)
 {
 	int ret;
@@ -401,10 +423,9 @@
 				AN877_ADC_TRANSFER_SYNC);
 }
 
-static int ad9467_scale_fill(struct adi_axi_adc_conv *conv)
+static int ad9467_scale_fill(struct ad9467_state *st)
 {
-	const struct adi_axi_adc_chip_info *info = conv->chip_info;
-	struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+	const struct ad9467_chip_info *info = st->info;
 	unsigned int i, val1, val2;
 
 	st->scales = devm_kmalloc_array(&st->spi->dev, info->num_scales,
@@ -413,7 +434,7 @@
 		return -ENOMEM;
 
 	for (i = 0; i < info->num_scales; i++) {
-		__ad9467_get_scale(conv, i, &val1, &val2);
+		__ad9467_get_scale(st, i, &val1, &val2);
 		st->scales[i][0] = val1;
 		st->scales[i][1] = val2;
 	}
@@ -421,11 +442,27 @@
 	return 0;
 }
 
-static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv)
+static int ad9467_setup(struct ad9467_state *st)
 {
-	struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+	struct iio_backend_data_fmt data = {
+		.sign_extend = true,
+		.enable = true,
+	};
+	unsigned int c, mode;
+	int ret;
+
+	mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT;
+	ret = ad9467_outputmode_set(st->spi, mode);
+	if (ret)
+		return ret;
 
-	return ad9467_outputmode_set(st->spi, st->output_mode);
+	for (c = 0; c < st->info->num_channels; c++) {
+		ret = iio_backend_data_format_set(st->back, c, &data);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
 }
 
 static int ad9467_reset(struct device *dev)
@@ -443,25 +480,65 @@
 	return 0;
 }
 
+static int ad9467_iio_backend_get(struct ad9467_state *st)
+{
+	struct device *dev = &st->spi->dev;
+	struct device_node *__back;
+
+	st->back = devm_iio_backend_get(dev, NULL);
+	if (!IS_ERR(st->back))
+		return 0;
+	/* If not found, don't error out as we might have legacy DT property */
+	if (PTR_ERR(st->back) != -ENOENT)
+		return PTR_ERR(st->back);
+
+	/*
+	 * if we don't get the backend using the normal API's, use the legacy
+	 * 'adi,adc-dev' property. So we get all nodes with that property, and
+	 * look for the one pointing at us. Then we directly lookup that fwnode
+	 * on the backend list of registered devices. This is done so we don't
+	 * make io-backends mandatory which would break DT ABI.
+	 */
+	for_each_node_with_property(__back, "adi,adc-dev") {
+		struct device_node *__me;
+
+		__me = of_parse_phandle(__back, "adi,adc-dev", 0);
+		if (!__me)
+			continue;
+
+		if (!device_match_of_node(dev, __me)) {
+			of_node_put(__me);
+			continue;
+		}
+
+		of_node_put(__me);
+		st->back = __devm_iio_backend_get_from_fwnode_lookup(dev,
+								     of_fwnode_handle(__back));
+		of_node_put(__back);
+		return PTR_ERR_OR_ZERO(st->back);
+	}
+
+	return -ENODEV;
+}
+
 static int ad9467_probe(struct spi_device *spi)
 {
-	const struct ad9467_chip_info *info;
-	struct adi_axi_adc_conv *conv;
+	struct iio_dev *indio_dev;
 	struct ad9467_state *st;
 	unsigned int id;
 	int ret;
 
-	info = spi_get_device_match_data(spi);
-	if (!info)
-		return -ENODEV;
-
-	conv = devm_adi_axi_adc_conv_register(&spi->dev, sizeof(*st));
-	if (IS_ERR(conv))
-		return PTR_ERR(conv);
+	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+	if (!indio_dev)
+		return -ENOMEM;
 
-	st = adi_axi_adc_conv_priv(conv);
+	st = iio_priv(indio_dev);
 	st->spi = spi;
 
+	st->info = spi_get_device_match_data(spi);
+	if (!st->info)
+		return -ENODEV;
+
 	st->clk = devm_clk_get_enabled(&spi->dev, "adc-clk");
 	if (IS_ERR(st->clk))
 		return PTR_ERR(st->clk);
@@ -475,29 +552,39 @@
 	if (ret)
 		return ret;
 
-	conv->chip_info = &info->axi_adc_info;
-
-	ret = ad9467_scale_fill(conv);
+	ret = ad9467_scale_fill(st);
 	if (ret)
 		return ret;
 
 	id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID);
-	if (id != conv->chip_info->id) {
+	if (id != st->info->id) {
 		dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n",
-			id, conv->chip_info->id);
+			id, st->info->id);
 		return -ENODEV;
 	}
 
-	conv->reg_access = ad9467_reg_access;
-	conv->write_raw = ad9467_write_raw;
-	conv->read_raw = ad9467_read_raw;
-	conv->read_avail = ad9467_read_avail;
-	conv->preenable_setup = ad9467_preenable_setup;
+	indio_dev->name = st->info->name;
+	indio_dev->channels = st->info->channels;
+	indio_dev->num_channels = st->info->num_channels;
+	indio_dev->info = &ad9467_info;
 
-	st->output_mode = info->default_output_mode |
-			  AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT;
+	ret = ad9467_iio_backend_get(st);
+	if (ret)
+		return ret;
 
-	return 0;
+	ret = devm_iio_backend_request_buffer(&spi->dev, st->back, indio_dev);
+	if (ret)
+		return ret;
+
+	ret = devm_iio_backend_enable(&spi->dev, st->back);
+	if (ret)
+		return ret;
+
+	ret = ad9467_setup(st);
+	if (ret)
+		return ret;
+
+	return devm_iio_device_register(&spi->dev, indio_dev);
 }
 
 static const struct of_device_id ad9467_of_match[] = {
@@ -529,4 +616,4 @@
 MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices AD9467 ADC driver");
 MODULE_LICENSE("GPL v2");
-MODULE_IMPORT_NS(IIO_ADI_AXI);
+MODULE_IMPORT_NS(IIO_BACKEND);
--- linux-qcom-6.8.0.orig/drivers/iio/adc/adi-axi-adc.c
+++ linux-qcom-6.8.0/drivers/iio/adc/adi-axi-adc.c
@@ -8,6 +8,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/clk.h>
+#include <linux/err.h>
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/module.h>
@@ -17,13 +18,12 @@
 #include <linux/regmap.h>
 #include <linux/slab.h>
 
-#include <linux/iio/iio.h>
-#include <linux/iio/sysfs.h>
-#include <linux/iio/buffer.h>
-#include <linux/iio/buffer-dmaengine.h>
-
 #include <linux/fpga/adi-axi-common.h>
-#include <linux/iio/adc/adi-axi-adc.h>
+
+#include <linux/iio/backend.h>
+#include <linux/iio/buffer-dmaengine.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
 
 /*
  * Register definitions:
@@ -44,6 +44,7 @@
 #define   ADI_AXI_REG_CHAN_CTRL_PN_SEL_OWR	BIT(10)
 #define   ADI_AXI_REG_CHAN_CTRL_IQCOR_EN	BIT(9)
 #define   ADI_AXI_REG_CHAN_CTRL_DCFILT_EN	BIT(8)
+#define   ADI_AXI_REG_CHAN_CTRL_FMT_MASK	GENMASK(6, 4)
 #define   ADI_AXI_REG_CHAN_CTRL_FMT_SIGNEXT	BIT(6)
 #define   ADI_AXI_REG_CHAN_CTRL_FMT_TYPE	BIT(5)
 #define   ADI_AXI_REG_CHAN_CTRL_FMT_EN		BIT(4)
@@ -55,286 +56,100 @@
 	 ADI_AXI_REG_CHAN_CTRL_FMT_EN |		\
 	 ADI_AXI_REG_CHAN_CTRL_ENABLE)
 
-struct adi_axi_adc_core_info {
-	unsigned int				version;
-};
-
 struct adi_axi_adc_state {
-	struct mutex				lock;
-
-	struct adi_axi_adc_client		*client;
 	struct regmap				*regmap;
-};
-
-struct adi_axi_adc_client {
-	struct list_head			entry;
-	struct adi_axi_adc_conv			conv;
-	struct adi_axi_adc_state		*state;
 	struct device				*dev;
-	const struct adi_axi_adc_core_info	*info;
 };
 
-static LIST_HEAD(registered_clients);
-static DEFINE_MUTEX(registered_clients_lock);
-
-static struct adi_axi_adc_client *conv_to_client(struct adi_axi_adc_conv *conv)
+static int axi_adc_enable(struct iio_backend *back)
 {
-	return container_of(conv, struct adi_axi_adc_client, conv);
-}
-
-void *adi_axi_adc_conv_priv(struct adi_axi_adc_conv *conv)
-{
-	struct adi_axi_adc_client *cl = conv_to_client(conv);
-
-	return (char *)cl + ALIGN(sizeof(struct adi_axi_adc_client),
-				  IIO_DMA_MINALIGN);
-}
-EXPORT_SYMBOL_NS_GPL(adi_axi_adc_conv_priv, IIO_ADI_AXI);
-
-static int adi_axi_adc_config_dma_buffer(struct device *dev,
-					 struct iio_dev *indio_dev)
-{
-	const char *dma_name;
-
-	if (!device_property_present(dev, "dmas"))
-		return 0;
-
-	if (device_property_read_string(dev, "dma-names", &dma_name))
-		dma_name = "rx";
-
-	return devm_iio_dmaengine_buffer_setup(indio_dev->dev.parent,
-					       indio_dev, dma_name);
-}
-
-static int adi_axi_adc_read_raw(struct iio_dev *indio_dev,
-				struct iio_chan_spec const *chan,
-				int *val, int *val2, long mask)
-{
-	struct adi_axi_adc_state *st = iio_priv(indio_dev);
-	struct adi_axi_adc_conv *conv = &st->client->conv;
-
-	if (!conv->read_raw)
-		return -EOPNOTSUPP;
-
-	return conv->read_raw(conv, chan, val, val2, mask);
-}
-
-static int adi_axi_adc_write_raw(struct iio_dev *indio_dev,
-				 struct iio_chan_spec const *chan,
-				 int val, int val2, long mask)
-{
-	struct adi_axi_adc_state *st = iio_priv(indio_dev);
-	struct adi_axi_adc_conv *conv = &st->client->conv;
-
-	if (!conv->write_raw)
-		return -EOPNOTSUPP;
-
-	return conv->write_raw(conv, chan, val, val2, mask);
-}
-
-static int adi_axi_adc_read_avail(struct iio_dev *indio_dev,
-				  struct iio_chan_spec const *chan,
-				  const int **vals, int *type, int *length,
-				  long mask)
-{
-	struct adi_axi_adc_state *st = iio_priv(indio_dev);
-	struct adi_axi_adc_conv *conv = &st->client->conv;
-
-	if (!conv->read_avail)
-		return -EOPNOTSUPP;
-
-	return conv->read_avail(conv, chan, vals, type, length, mask);
-}
-
-static int adi_axi_adc_update_scan_mode(struct iio_dev *indio_dev,
-					const unsigned long *scan_mask)
-{
-	struct adi_axi_adc_state *st = iio_priv(indio_dev);
-	struct adi_axi_adc_conv *conv = &st->client->conv;
-	unsigned int i;
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
 	int ret;
 
-	for (i = 0; i < conv->chip_info->num_channels; i++) {
-		if (test_bit(i, scan_mask))
-			ret = regmap_set_bits(st->regmap,
-					      ADI_AXI_REG_CHAN_CTRL(i),
-					      ADI_AXI_REG_CHAN_CTRL_ENABLE);
-		else
-			ret = regmap_clear_bits(st->regmap,
-						ADI_AXI_REG_CHAN_CTRL(i),
-						ADI_AXI_REG_CHAN_CTRL_ENABLE);
-		if (ret)
-			return ret;
-	}
+	ret = regmap_set_bits(st->regmap, ADI_AXI_REG_RSTN,
+			      ADI_AXI_REG_RSTN_MMCM_RSTN);
+	if (ret)
+		return ret;
 
-	return 0;
+	fsleep(10000);
+	return regmap_set_bits(st->regmap, ADI_AXI_REG_RSTN,
+			       ADI_AXI_REG_RSTN_RSTN | ADI_AXI_REG_RSTN_MMCM_RSTN);
 }
 
-static struct adi_axi_adc_conv *adi_axi_adc_conv_register(struct device *dev,
-							  size_t sizeof_priv)
+static void axi_adc_disable(struct iio_backend *back)
 {
-	struct adi_axi_adc_client *cl;
-	size_t alloc_size;
-
-	alloc_size = ALIGN(sizeof(struct adi_axi_adc_client), IIO_DMA_MINALIGN);
-	if (sizeof_priv)
-		alloc_size += ALIGN(sizeof_priv, IIO_DMA_MINALIGN);
-
-	cl = kzalloc(alloc_size, GFP_KERNEL);
-	if (!cl)
-		return ERR_PTR(-ENOMEM);
-
-	mutex_lock(&registered_clients_lock);
-
-	cl->dev = get_device(dev);
-
-	list_add_tail(&cl->entry, &registered_clients);
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
 
-	mutex_unlock(&registered_clients_lock);
-
-	return &cl->conv;
+	regmap_write(st->regmap, ADI_AXI_REG_RSTN, 0);
 }
 
-static void adi_axi_adc_conv_unregister(struct adi_axi_adc_conv *conv)
+static int axi_adc_data_format_set(struct iio_backend *back, unsigned int chan,
+				   const struct iio_backend_data_fmt *data)
 {
-	struct adi_axi_adc_client *cl = conv_to_client(conv);
-
-	mutex_lock(&registered_clients_lock);
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
+	u32 val;
 
-	list_del(&cl->entry);
-	put_device(cl->dev);
+	if (!data->enable)
+		return regmap_clear_bits(st->regmap,
+					 ADI_AXI_REG_CHAN_CTRL(chan),
+					 ADI_AXI_REG_CHAN_CTRL_FMT_EN);
 
-	mutex_unlock(&registered_clients_lock);
+	val = FIELD_PREP(ADI_AXI_REG_CHAN_CTRL_FMT_EN, true);
+	if (data->sign_extend)
+		val |= FIELD_PREP(ADI_AXI_REG_CHAN_CTRL_FMT_SIGNEXT, true);
+	if (data->type == IIO_BACKEND_OFFSET_BINARY)
+		val |= FIELD_PREP(ADI_AXI_REG_CHAN_CTRL_FMT_TYPE, true);
 
-	kfree(cl);
+	return regmap_update_bits(st->regmap, ADI_AXI_REG_CHAN_CTRL(chan),
+				  ADI_AXI_REG_CHAN_CTRL_FMT_MASK, val);
 }
 
-static void devm_adi_axi_adc_conv_release(void *conv)
+static int axi_adc_chan_enable(struct iio_backend *back, unsigned int chan)
 {
-	adi_axi_adc_conv_unregister(conv);
-}
-
-struct adi_axi_adc_conv *devm_adi_axi_adc_conv_register(struct device *dev,
-							size_t sizeof_priv)
-{
-	struct adi_axi_adc_conv *conv;
-	int ret;
-
-	conv = adi_axi_adc_conv_register(dev, sizeof_priv);
-	if (IS_ERR(conv))
-		return conv;
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
 
-	ret = devm_add_action_or_reset(dev, devm_adi_axi_adc_conv_release,
-				       conv);
-	if (ret)
-		return ERR_PTR(ret);
-
-	return conv;
+	return regmap_set_bits(st->regmap, ADI_AXI_REG_CHAN_CTRL(chan),
+			       ADI_AXI_REG_CHAN_CTRL_ENABLE);
 }
-EXPORT_SYMBOL_NS_GPL(devm_adi_axi_adc_conv_register, IIO_ADI_AXI);
-
-static const struct iio_info adi_axi_adc_info = {
-	.read_raw = &adi_axi_adc_read_raw,
-	.write_raw = &adi_axi_adc_write_raw,
-	.update_scan_mode = &adi_axi_adc_update_scan_mode,
-	.read_avail = &adi_axi_adc_read_avail,
-};
-
-static const struct adi_axi_adc_core_info adi_axi_adc_10_0_a_info = {
-	.version = ADI_AXI_PCORE_VER(10, 0, 'a'),
-};
 
-static struct adi_axi_adc_client *adi_axi_adc_attach_client(struct device *dev)
+static int axi_adc_chan_disable(struct iio_backend *back, unsigned int chan)
 {
-	const struct adi_axi_adc_core_info *info;
-	struct adi_axi_adc_client *cl;
-	struct device_node *cln;
-
-	info = of_device_get_match_data(dev);
-	if (!info)
-		return ERR_PTR(-ENODEV);
-
-	cln = of_parse_phandle(dev->of_node, "adi,adc-dev", 0);
-	if (!cln) {
-		dev_err(dev, "No 'adi,adc-dev' node defined\n");
-		return ERR_PTR(-ENODEV);
-	}
-
-	mutex_lock(&registered_clients_lock);
-
-	list_for_each_entry(cl, &registered_clients, entry) {
-		if (!cl->dev)
-			continue;
-
-		if (cl->dev->of_node != cln)
-			continue;
-
-		if (!try_module_get(cl->dev->driver->owner)) {
-			mutex_unlock(&registered_clients_lock);
-			of_node_put(cln);
-			return ERR_PTR(-ENODEV);
-		}
-
-		get_device(cl->dev);
-		cl->info = info;
-		mutex_unlock(&registered_clients_lock);
-		of_node_put(cln);
-		return cl;
-	}
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
 
-	mutex_unlock(&registered_clients_lock);
-	of_node_put(cln);
-
-	return ERR_PTR(-EPROBE_DEFER);
+	return regmap_clear_bits(st->regmap, ADI_AXI_REG_CHAN_CTRL(chan),
+				 ADI_AXI_REG_CHAN_CTRL_ENABLE);
 }
 
-static int adi_axi_adc_setup_channels(struct device *dev,
-				      struct adi_axi_adc_state *st)
+static struct iio_buffer *axi_adc_request_buffer(struct iio_backend *back,
+						 struct iio_dev *indio_dev)
 {
-	struct adi_axi_adc_conv *conv = &st->client->conv;
-	int i, ret;
+	struct adi_axi_adc_state *st = iio_backend_get_priv(back);
+	struct iio_buffer *buffer;
+	const char *dma_name;
+	int ret;
 
-	if (conv->preenable_setup) {
-		ret = conv->preenable_setup(conv);
-		if (ret)
-			return ret;
-	}
+	if (device_property_read_string(st->dev, "dma-names", &dma_name))
+		dma_name = "rx";
 
-	for (i = 0; i < conv->chip_info->num_channels; i++) {
-		ret = regmap_write(st->regmap, ADI_AXI_REG_CHAN_CTRL(i),
-				   ADI_AXI_REG_CHAN_CTRL_DEFAULTS);
-		if (ret)
-			return ret;
+	buffer = iio_dmaengine_buffer_alloc(st->dev, dma_name);
+	if (IS_ERR(buffer)) {
+		dev_err(st->dev, "Could not get DMA buffer, %ld\n",
+			PTR_ERR(buffer));
+		return ERR_CAST(buffer);
 	}
 
-	return 0;
-}
-
-static int axi_adc_reset(struct adi_axi_adc_state *st)
-{
-	int ret;
-
-	ret = regmap_write(st->regmap, ADI_AXI_REG_RSTN, 0);
+	indio_dev->modes |= INDIO_BUFFER_HARDWARE;
+	ret = iio_device_attach_buffer(indio_dev, buffer);
 	if (ret)
-		return ret;
-
-	mdelay(10);
-	ret = regmap_write(st->regmap, ADI_AXI_REG_RSTN,
-			   ADI_AXI_REG_RSTN_MMCM_RSTN);
-	if (ret)
-		return ret;
+		return ERR_PTR(ret);
 
-	mdelay(10);
-	return regmap_write(st->regmap, ADI_AXI_REG_RSTN,
-			    ADI_AXI_REG_RSTN_RSTN | ADI_AXI_REG_RSTN_MMCM_RSTN);
+	return buffer;
 }
 
-static void adi_axi_adc_cleanup(void *data)
+static void axi_adc_free_buffer(struct iio_backend *back,
+				struct iio_buffer *buffer)
 {
-	struct adi_axi_adc_client *cl = data;
-
-	put_device(cl->dev);
-	module_put(cl->dev->driver->owner);
+	iio_dmaengine_buffer_free(buffer);
 }
 
 static const struct regmap_config axi_adc_regmap_config = {
@@ -344,45 +159,52 @@
 	.max_register = 0x0800,
 };
 
+static const struct iio_backend_ops adi_axi_adc_generic = {
+	.enable = axi_adc_enable,
+	.disable = axi_adc_disable,
+	.data_format_set = axi_adc_data_format_set,
+	.chan_enable = axi_adc_chan_enable,
+	.chan_disable = axi_adc_chan_disable,
+	.request_buffer = axi_adc_request_buffer,
+	.free_buffer = axi_adc_free_buffer,
+};
+
 static int adi_axi_adc_probe(struct platform_device *pdev)
 {
-	struct adi_axi_adc_conv *conv;
-	struct iio_dev *indio_dev;
-	struct adi_axi_adc_client *cl;
+	const unsigned int *expected_ver;
 	struct adi_axi_adc_state *st;
 	void __iomem *base;
 	unsigned int ver;
+	struct clk *clk;
 	int ret;
 
-	cl = adi_axi_adc_attach_client(&pdev->dev);
-	if (IS_ERR(cl))
-		return PTR_ERR(cl);
-
-	ret = devm_add_action_or_reset(&pdev->dev, adi_axi_adc_cleanup, cl);
-	if (ret)
-		return ret;
-
-	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*st));
-	if (indio_dev == NULL)
+	st = devm_kzalloc(&pdev->dev, sizeof(*st), GFP_KERNEL);
+	if (!st)
 		return -ENOMEM;
 
-	st = iio_priv(indio_dev);
-	st->client = cl;
-	cl->state = st;
-	mutex_init(&st->lock);
-
 	base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
+	st->dev = &pdev->dev;
 	st->regmap = devm_regmap_init_mmio(&pdev->dev, base,
 					   &axi_adc_regmap_config);
 	if (IS_ERR(st->regmap))
 		return PTR_ERR(st->regmap);
 
-	conv = &st->client->conv;
+	expected_ver = device_get_match_data(&pdev->dev);
+	if (!expected_ver)
+		return -ENODEV;
 
-	ret = axi_adc_reset(st);
+	clk = devm_clk_get_enabled(&pdev->dev, NULL);
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	/*
+	 * Force disable the core. Up to the frontend to enable us. And we can
+	 * still read/write registers...
+	 */
+	ret = regmap_write(st->regmap, ADI_AXI_REG_RSTN, 0);
 	if (ret)
 		return ret;
 
@@ -390,33 +212,19 @@
 	if (ret)
 		return ret;
 
-	if (cl->info->version > ver) {
+	if (ADI_AXI_PCORE_VER_MAJOR(ver) != ADI_AXI_PCORE_VER_MAJOR(*expected_ver)) {
 		dev_err(&pdev->dev,
-			"IP core version is too old. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n",
-			ADI_AXI_PCORE_VER_MAJOR(cl->info->version),
-			ADI_AXI_PCORE_VER_MINOR(cl->info->version),
-			ADI_AXI_PCORE_VER_PATCH(cl->info->version),
+			"Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n",
+			ADI_AXI_PCORE_VER_MAJOR(*expected_ver),
+			ADI_AXI_PCORE_VER_MINOR(*expected_ver),
+			ADI_AXI_PCORE_VER_PATCH(*expected_ver),
 			ADI_AXI_PCORE_VER_MAJOR(ver),
 			ADI_AXI_PCORE_VER_MINOR(ver),
 			ADI_AXI_PCORE_VER_PATCH(ver));
 		return -ENODEV;
 	}
 
-	indio_dev->info = &adi_axi_adc_info;
-	indio_dev->name = "adi-axi-adc";
-	indio_dev->modes = INDIO_DIRECT_MODE;
-	indio_dev->num_channels = conv->chip_info->num_channels;
-	indio_dev->channels = conv->chip_info->channels;
-
-	ret = adi_axi_adc_config_dma_buffer(&pdev->dev, indio_dev);
-	if (ret)
-		return ret;
-
-	ret = adi_axi_adc_setup_channels(&pdev->dev, st);
-	if (ret)
-		return ret;
-
-	ret = devm_iio_device_register(&pdev->dev, indio_dev);
+	ret = devm_iio_backend_register(&pdev->dev, &adi_axi_adc_generic, st);
 	if (ret)
 		return ret;
 
@@ -428,6 +236,8 @@
 	return 0;
 }
 
+static unsigned int adi_axi_adc_10_0_a_info = ADI_AXI_PCORE_VER(10, 0, 'a');
+
 /* Match table for of_platform binding */
 static const struct of_device_id adi_axi_adc_of_match[] = {
 	{ .compatible = "adi,axi-adc-10.0.a", .data = &adi_axi_adc_10_0_a_info },
@@ -447,3 +257,5 @@
 MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
 MODULE_DESCRIPTION("Analog Devices Generic AXI ADC IP core driver");
 MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS(IIO_DMAENGINE_BUFFER);
+MODULE_IMPORT_NS(IIO_BACKEND);
--- linux-qcom-6.8.0.orig/drivers/iio/adc/at91_adc.c
+++ linux-qcom-6.8.0/drivers/iio/adc/at91_adc.c
@@ -984,7 +984,7 @@
 	return ret;
 
 err:
-	input_free_device(st->ts_input);
+	input_free_device(input);
 	return ret;
 }
 
--- linux-qcom-6.8.0.orig/drivers/iio/adc/qcom-spmi-adc5-gen3.c
+++ linux-qcom-6.8.0/drivers/iio/adc/qcom-spmi-adc5-gen3.c
@@ -0,0 +1,1198 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <asm/unaligned.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/adc/qcom-vadc-common.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/log2.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/thermal.h>
+
+#include <dt-bindings/iio/qcom,spmi-vadc.h>
+
+#define ADC5_GEN3_HS				0x45
+#define ADC5_GEN3_HS_BUSY			BIT(7)
+#define ADC5_GEN3_HS_READY			BIT(0)
+
+#define ADC5_GEN3_STATUS1			0x46
+#define ADC5_GEN3_STATUS1_CONV_FAULT		BIT(7)
+#define ADC5_GEN3_STATUS1_THR_CROSS		BIT(6)
+#define ADC5_GEN3_STATUS1_EOC			BIT(0)
+
+#define ADC5_GEN3_TM_EN_STS			0x47
+#define ADC5_GEN3_TM_HIGH_STS			0x48
+#define ADC5_GEN3_TM_LOW_STS			0x49
+
+#define ADC5_GEN3_EOC_STS			0x4a
+#define ADC5_GEN3_EOC_CHAN_0			BIT(0)
+
+#define ADC5_GEN3_EOC_CLR			0x4b
+#define ADC5_GEN3_TM_HIGH_STS_CLR		0x4c
+#define ADC5_GEN3_TM_LOW_STS_CLR		0x4d
+#define ADC5_GEN3_CONV_ERR_CLR			0x4e
+#define ADC5_GEN3_CONV_ERR_CLR_REQ		BIT(0)
+
+#define ADC5_GEN3_SID				0x4f
+#define ADC5_GEN3_SID_MASK			GENMASK(3, 0)
+
+#define ADC5_GEN3_PERPH_CH			0x50
+#define ADC5_GEN3_CHAN_CONV_REQ			BIT(7)
+
+#define ADC5_GEN3_TIMER_SEL			0x51
+#define ADC5_GEN3_TIME_IMMEDIATE		0x1
+
+#define ADC5_GEN3_DIG_PARAM			0x52
+#define ADC5_GEN3_DIG_PARAM_CAL_SEL_MASK	GENMASK(5, 4)
+#define ADC5_GEN3_DIG_PARAM_DEC_RATIO_SEL_MASK	GENMASK(3, 2)
+
+#define ADC5_GEN3_FAST_AVG			0x53
+#define ADC5_GEN3_FAST_AVG_CTL_EN		BIT(7)
+#define ADC5_GEN3_FAST_AVG_CTL_SAMPLES_MASK	GENMASK(2, 0)
+
+#define ADC5_GEN3_ADC_CH_SEL_CTL		0x54
+#define ADC5_GEN3_DELAY_CTL			0x55
+#define ADC5_GEN3_HW_SETTLE_DELAY_MASK		GENMASK(3, 0)
+
+#define ADC5_GEN3_CH_EN				0x56
+#define ADC5_GEN3_HIGH_THR_INT_EN		BIT(1)
+#define ADC5_GEN3_LOW_THR_INT_EN		BIT(0)
+
+#define ADC5_GEN3_LOW_THR0			0x57
+#define ADC5_GEN3_LOW_THR1			0x58
+#define ADC5_GEN3_HIGH_THR0			0x59
+#define ADC5_GEN3_HIGH_THR1			0x5a
+
+#define ADC5_GEN3_CH_DATA0(channel)	(0x5c + (channel) * 2)
+#define ADC5_GEN3_CH_DATA1(channel)	(0x5d + (channel) * 2)
+
+#define ADC5_GEN3_CONV_REQ			0xe5
+#define ADC5_GEN3_CONV_REQ_REQ			BIT(0)
+
+#define ADC5_GEN3_VIRTUAL_SID_MASK			GENMASK(15, 8)
+#define ADC5_GEN3_CHANNEL_MASK			GENMASK(7, 0)
+#define V_CHAN(x)		\
+	(FIELD_PREP(ADC5_GEN3_VIRTUAL_SID_MASK, (x).sid) | (x).channel)	\
+
+enum adc5_cal_method {
+	ADC5_NO_CAL = 0,
+	ADC5_RATIOMETRIC_CAL,
+	ADC5_ABSOLUTE_CAL
+};
+
+enum adc5_time_select {
+	MEAS_INT_DISABLE = 0,
+	MEAS_INT_IMMEDIATE,
+	MEAS_INT_50MS,
+	MEAS_INT_100MS,
+	MEAS_INT_1S,
+	MEAS_INT_NONE,
+};
+
+struct adc5_sdam_data {
+	u16			base_addr;
+	const char		*irq_name;
+	int			irq;
+};
+
+/**
+ * struct adc5_channel_prop - ADC channel property.
+ * @channel: channel number, refer to the channel list.
+ * @cal_method: calibration method.
+ * @decimation: sampling rate supported for the channel.
+ * @sid: slave id of PMIC owning the channel.
+ * @prescale: channel scaling performed on the input signal.
+ * @hw_settle_time: the time between AMUX being configured and the
+ *	start of conversion.
+ * @avg_samples: ability to provide single result from the ADC
+ *	that is an average of multiple measurements.
+ * @sdam_index: Index for which SDAM this channel is on.
+ * @scale_fn_type: Represents the scaling function to convert voltage
+ *	physical units desired by the client for the channel.
+ * @label: Channel name used in device tree.
+ * @chip: pointer to top-level ADC device structure.
+ * @adc_tm: indicates if the channel is used for TM measurements.
+ * @tm_chan_index: TM channel number used (ranging from 1-7).
+ * @timer: time period of recurring TM measurement.
+ * @tzd: pointer to thermal device corresponding to TM channel.
+ * @high_thr_en: TM high threshold crossing detection enabled.
+ * @low_thr_en: TM low threshold crossing detection enabled.
+ * @last_temp: last temperature that caused threshold violation,
+ *	or a thermal TM channel.
+ * @last_temp_set: indicates if last_temp is stored.
+ */
+struct adc5_channel_prop {
+	unsigned int			channel;
+	enum adc5_cal_method		cal_method;
+	unsigned int			decimation;
+	unsigned int			sid;
+	unsigned int			prescale;
+	unsigned int			hw_settle_time;
+	unsigned int			avg_samples;
+	unsigned int			sdam_index;
+
+	enum vadc_scale_fn_type		scale_fn_type;
+	const char			*label;
+
+	struct adc5_chip		*chip;
+	/* TM(thermal monitoring related) properties */
+	bool				adc_tm;
+	unsigned int			tm_chan_index;
+	unsigned int			timer;
+	struct thermal_zone_device	*tzd;
+	bool				high_thr_en;
+	bool				low_thr_en;
+	int				last_temp;
+	bool				last_temp_set;
+};
+
+/**
+ * struct adc5_chip - ADC private structure.
+ * @regmap: SPMI ADC5 Gen3 peripheral register map field.
+ * @dev: SPMI ADC5 Gen3 device.
+ * @base: pointer to array of ADC peripheral base and interrupt.
+ * @num_sdams: number of SDAMs (Shared Direct Access Memory Module) being used.
+ * @nchannels: number of ADC channels.
+ * @chan_props: array of ADC channel properties.
+ * @iio_chans: array of IIO channels specification.
+ * @complete: ADC result notification after interrupt is received.
+ * @lock: ADC lock for access to the peripheral, to prevent concurrent
+ * requests from multiple clients.
+ * @data: software configuration data.
+ * @n_tm_channels: number of ADC channels used for TM measurements.
+ * @tm_handler_work: scheduled work for handling TM threshold violation.
+ */
+struct adc5_chip {
+	struct regmap			*regmap;
+	struct device			*dev;
+	struct adc5_sdam_data		*base;
+	unsigned int			num_sdams;
+	unsigned int			nchannels;
+	struct adc5_channel_prop	*chan_props;
+	struct iio_chan_spec		*iio_chans;
+	struct completion		complete;
+	struct mutex			lock;
+	const struct adc5_data		*data;
+	/* TM properties */
+	unsigned int			n_tm_channels;
+	struct work_struct		tm_handler_work;
+};
+
+static int adc5_gen3_read(struct adc5_chip *adc, unsigned int sdam_index,
+				u16 offset, u8 *data, int len)
+{
+	return regmap_bulk_read(adc->regmap, adc->base[sdam_index].base_addr + offset, data, len);
+}
+
+static int adc5_gen3_write(struct adc5_chip *adc, unsigned int sdam_index,
+				u16 offset, u8 *data, int len)
+{
+	return regmap_bulk_write(adc->regmap, adc->base[sdam_index].base_addr + offset, data, len);
+}
+
+static int adc5_gen3_read_voltage_data(struct adc5_chip *adc, u16 *data, u8 sdam_index)
+{
+	int ret;
+	u8 rslt[2];
+
+	ret = adc5_gen3_read(adc, sdam_index, ADC5_GEN3_CH_DATA0(0), rslt, 2);
+	if (ret)
+		return ret;
+
+	*data = get_unaligned_le16(rslt);
+
+	if (*data == ADC5_USR_DATA_CHECK) {
+		dev_err(adc->dev, "Invalid data:%#x\n", *data);
+		return -EINVAL;
+	}
+
+	dev_dbg(adc->dev, "voltage raw code:%#x\n", *data);
+
+	return 0;
+}
+
+static void adc5_gen3_update_dig_param(struct adc5_chip *adc,
+			struct adc5_channel_prop *prop, u8 *data)
+{
+	/* Update calibration select and decimation ratio select*/
+	*data &= ~(ADC5_GEN3_DIG_PARAM_CAL_SEL_MASK | ADC5_GEN3_DIG_PARAM_DEC_RATIO_SEL_MASK);
+	*data |= FIELD_PREP(ADC5_GEN3_DIG_PARAM_CAL_SEL_MASK, prop->cal_method);
+	*data |= FIELD_PREP(ADC5_GEN3_DIG_PARAM_DEC_RATIO_SEL_MASK, prop->decimation);
+}
+
+# define ADC5_GEN3_READ_CONFIG_REGS 7
+
+static int adc5_gen3_configure(struct adc5_chip *adc,
+			struct adc5_channel_prop *prop)
+{
+	u8 sdam_index = prop->sdam_index;
+	u8 conv_req = 0;
+	u8 buf[ADC5_GEN3_READ_CONFIG_REGS];
+	int ret;
+
+	/* Reserve channel 0 of first SDAM for immediate conversions */
+	if (prop->adc_tm)
+		sdam_index = 0;
+
+	ret = adc5_gen3_read(adc, sdam_index, ADC5_GEN3_SID, buf, sizeof(buf));
+	if (ret)
+		return ret;
+
+	/* Write SID */
+	buf[0] = FIELD_PREP(ADC5_GEN3_SID_MASK, prop->sid);
+
+	/*
+	 * Use channel 0 by default for immediate conversion and
+	 * to indicate there is an actual conversion request
+	 */
+	buf[1] = ADC5_GEN3_CHAN_CONV_REQ | 0;
+
+	buf[2] = ADC5_GEN3_TIME_IMMEDIATE;
+
+	/* Digital param selection */
+	adc5_gen3_update_dig_param(adc, prop, &buf[3]);
+
+	/* Update fast average sample value */
+	buf[4] &= ~ADC5_GEN3_FAST_AVG_CTL_SAMPLES_MASK;
+	buf[4] |= prop->avg_samples | ADC5_GEN3_FAST_AVG_CTL_EN;
+
+	/* Select ADC channel */
+	buf[5] = prop->channel;
+
+	/* Select HW settle delay for channel */
+	buf[6] = FIELD_PREP(ADC5_GEN3_HW_SETTLE_DELAY_MASK, prop->hw_settle_time);
+
+	reinit_completion(&adc->complete);
+
+	ret = adc5_gen3_write(adc, sdam_index, ADC5_GEN3_SID, buf, sizeof(buf));
+	if (ret)
+		return ret;
+
+	conv_req = ADC5_GEN3_CONV_REQ_REQ;
+	return adc5_gen3_write(adc, sdam_index, ADC5_GEN3_CONV_REQ, &conv_req, 1);
+}
+
+/**
+ * Worst case delay from PBS in readying handshake bit
+ * can be up to 15ms, when PBS is busy running other
+ * simultaneous transactions, while in the best case, it is
+ * already ready at this point. Assigning polling delay and
+ * retry count accordingly.
+ */
+
+#define ADC5_GEN3_HS_DELAY_MIN_US		100
+#define ADC5_GEN3_HS_DELAY_MAX_US		110
+#define ADC5_GEN3_HS_RETRY_COUNT		150
+
+static int adc5_gen3_poll_wait_hs(struct adc5_chip *adc,
+				unsigned int sdam_index)
+{
+	u8 conv_req = ADC5_GEN3_CONV_REQ_REQ;
+	u8 status = 0;
+	int ret, count;
+
+	for (count = 0; count < ADC5_GEN3_HS_RETRY_COUNT; count++) {
+		ret = adc5_gen3_read(adc, sdam_index, ADC5_GEN3_HS, &status, 1);
+		if (ret)
+			return ret;
+
+		if (status == ADC5_GEN3_HS_READY) {
+			ret = adc5_gen3_read(adc, sdam_index, ADC5_GEN3_CONV_REQ,
+					&conv_req, 1);
+			if (ret)
+				return ret;
+
+			if (!conv_req)
+				return 0;
+		}
+
+		usleep_range(ADC5_GEN3_HS_DELAY_MIN_US,
+			ADC5_GEN3_HS_DELAY_MAX_US);
+	}
+
+	dev_err(adc->dev, "Setting HS ready bit timed out, status:%#x\n", status);
+	return -ETIMEDOUT;
+}
+
+/**
+ * Worst case delay from PBS for conversion time can be
+ * up to 500ms, when PBS has timed out twice, once for
+ * the initial attempt and once for a retry of the same
+ * transaction.
+ */
+
+#define ADC5_GEN3_CONV_TIMEOUT_MS	501
+
+static int adc5_gen3_do_conversion(struct adc5_chip *adc,
+			struct adc5_channel_prop *prop,
+			u16 *data_volt)
+{
+	u8 val, sdam_index = prop->sdam_index;
+	unsigned long rc;
+	int ret;
+
+	/* Reserve channel 0 of first SDAM for immediate conversions */
+	if (prop->adc_tm)
+		sdam_index = 0;
+
+	mutex_lock(&adc->lock);
+	ret = adc5_gen3_poll_wait_hs(adc, 0);
+	if (ret)
+		goto unlock;
+
+	ret = adc5_gen3_configure(adc, prop);
+	if (ret) {
+		dev_err(adc->dev, "ADC configure failed with %d\n", ret);
+		goto unlock;
+	}
+
+	/* No support for polling mode at present*/
+	rc = wait_for_completion_timeout(&adc->complete,
+					msecs_to_jiffies(ADC5_GEN3_CONV_TIMEOUT_MS));
+	if (!rc) {
+		dev_err(adc->dev, "Reading ADC channel %s timed out\n",
+			prop->label);
+		ret = -ETIMEDOUT;
+		goto unlock;
+	}
+
+	ret = adc5_gen3_read_voltage_data(adc, data_volt, sdam_index);
+	if (ret)
+		goto unlock;
+
+	val = BIT(0);
+	ret = adc5_gen3_write(adc, sdam_index, ADC5_GEN3_EOC_CLR, &val, 1);
+	if (ret)
+		goto unlock;
+
+	/* To indicate conversion request is only to clear a status */
+	val = 0;
+	ret = adc5_gen3_write(adc, sdam_index, ADC5_GEN3_PERPH_CH, &val, 1);
+	if (ret)
+		goto unlock;
+
+	val = ADC5_GEN3_CONV_REQ_REQ;
+	ret = adc5_gen3_write(adc, sdam_index, ADC5_GEN3_CONV_REQ, &val, 1);
+
+unlock:
+	mutex_unlock(&adc->lock);
+
+	return ret;
+}
+
+static int get_sdam_from_irq(struct adc5_chip *adc, int irq)
+{
+	int i;
+
+	for (i = 0; i < adc->num_sdams; i++) {
+		if (adc->base[i].irq == irq)
+			return i;
+	}
+	return -ENOENT;
+}
+
+static irqreturn_t adc5_gen3_isr(int irq, void *dev_id)
+{
+	struct adc5_chip *adc = dev_id;
+	u8 status, tm_status[2], eoc_status, val;
+	int ret, sdam_num;
+
+	sdam_num = get_sdam_from_irq(adc, irq);
+	if (sdam_num < 0) {
+		dev_err(adc->dev, "adc irq %d not associated with an sdam\n", irq);
+		return IRQ_HANDLED;
+	}
+
+	ret = adc5_gen3_read(adc, sdam_num, ADC5_GEN3_STATUS1, &status, 1);
+	if (ret) {
+		dev_err(adc->dev, "adc read status1 failed with %d\n", ret);
+		return IRQ_HANDLED;
+	}
+
+	ret = adc5_gen3_read(adc, sdam_num, ADC5_GEN3_EOC_STS, &eoc_status, 1);
+	if (ret) {
+		dev_err(adc->dev, "adc read eoc status failed with %d\n", ret);
+		return IRQ_HANDLED;
+	}
+
+	if (status & ADC5_GEN3_STATUS1_CONV_FAULT) {
+		dev_err_ratelimited(adc->dev, "Unexpected conversion fault, status:%#x, eoc_status:%#x\n",
+				status, eoc_status);
+		val = ADC5_GEN3_CONV_ERR_CLR_REQ;
+		ret = adc5_gen3_write(adc, sdam_num, ADC5_GEN3_CONV_ERR_CLR, &val, 1);
+		if (ret < 0)
+			return IRQ_HANDLED;
+
+		/* To indicate conversion request is only to clear a status */
+		val = 0;
+		ret = adc5_gen3_write(adc, sdam_num, ADC5_GEN3_PERPH_CH, &val, 1);
+		if (ret < 0)
+			return IRQ_HANDLED;
+
+		val = ADC5_GEN3_CONV_REQ_REQ;
+		ret = adc5_gen3_write(adc, sdam_num, ADC5_GEN3_CONV_REQ, &val, 1);
+
+		return IRQ_HANDLED;
+	}
+
+	/* CHAN0 is the preconfigured channel for immediate conversion */
+	if (eoc_status & ADC5_GEN3_EOC_CHAN_0)
+		complete(&adc->complete);
+
+	ret = adc5_gen3_read(adc, sdam_num, ADC5_GEN3_TM_HIGH_STS, tm_status, 2);
+	if (ret) {
+		dev_err(adc->dev, "adc read TM status failed with %d\n", ret);
+		return IRQ_HANDLED;
+	}
+
+	if (tm_status[0] || tm_status[1])
+		schedule_work(&adc->tm_handler_work);
+
+	dev_dbg(adc->dev, "Interrupt status:%#x, EOC status:%#x, high:%#x, low:%#x\n",
+			status, eoc_status, tm_status[0], tm_status[1]);
+
+	return IRQ_HANDLED;
+}
+
+static void tm_handler_work(struct work_struct *work)
+{
+	struct adc5_chip *adc = container_of(work, struct adc5_chip, tm_handler_work);
+	struct adc5_channel_prop *chan_prop;
+	u8 tm_status[2] = {0};
+	u8 buf[16] = {0};
+	u8 val;
+	int ret, i, sdam_index = -1;
+
+	for (i = 0; i < adc->nchannels; i++) {
+		bool upper_set = false, lower_set = false;
+		int temp, offset;
+		u16 code = 0;
+
+		chan_prop = &adc->chan_props[i];
+		offset = chan_prop->tm_chan_index;
+
+		if (!chan_prop->adc_tm)
+			continue;
+
+		mutex_lock(&adc->lock);
+		if (chan_prop->sdam_index != sdam_index) {
+			sdam_index = chan_prop->sdam_index;
+			ret = adc5_gen3_read(adc, sdam_index, ADC5_GEN3_TM_HIGH_STS,
+					tm_status, 2);
+			if (ret) {
+				dev_err(adc->dev, "adc read TM status failed with %d\n", ret);
+				goto out;
+			}
+
+			ret = adc5_gen3_write(adc, sdam_index, ADC5_GEN3_TM_HIGH_STS_CLR,
+					tm_status, 2);
+			if (ret) {
+				dev_err(adc->dev, "adc write TM status failed with %d\n", ret);
+				goto out;
+			}
+
+			/* To indicate conversion request is only to clear a status */
+			val = 0;
+			ret = adc5_gen3_write(adc, sdam_index, ADC5_GEN3_PERPH_CH, &val, 1);
+			if (ret) {
+				dev_err(adc->dev, "adc write status clear conv_req failed with %d\n",
+						ret);
+				goto out;
+			}
+
+			val = ADC5_GEN3_CONV_REQ_REQ;
+			ret = adc5_gen3_write(adc, sdam_index, ADC5_GEN3_CONV_REQ, &val, 1);
+			if (ret) {
+				dev_err(adc->dev, "adc write conv_req failed with %d\n", ret);
+				goto out;
+			}
+
+			ret = adc5_gen3_read(adc, sdam_index, ADC5_GEN3_CH_DATA0(0), buf,
+					sizeof(buf));
+			if (ret < 0) {
+				dev_err(adc->dev, "adc read data failed with %d\n", ret);
+				goto out;
+			}
+		}
+
+		if ((tm_status[0] & BIT(offset)) && (chan_prop->high_thr_en))
+			upper_set = true;
+
+		if ((tm_status[1] & BIT(offset)) && (chan_prop->low_thr_en))
+			lower_set = true;
+
+		mutex_unlock(&adc->lock);
+
+		if (!(upper_set || lower_set))
+			continue;
+
+		code = get_unaligned_le16(&buf[2 * offset]);
+		pr_debug("ADC_TM threshold code:%#x\n", code);
+
+		ret = qcom_adc5_hw_scale(chan_prop->scale_fn_type,
+			chan_prop->prescale, adc->data, code, &temp);
+		if (ret) {
+			dev_err(adc->dev, "Invalid temperature reading, ret = %d, code=%#x\n",
+					ret, code);
+			continue;
+		}
+
+		chan_prop->last_temp = temp;
+		chan_prop->last_temp_set = true;
+		thermal_zone_device_update(chan_prop->tzd, THERMAL_TRIP_VIOLATED);
+	}
+
+	return;
+
+out:
+	mutex_unlock(&adc->lock);
+}
+
+static int adc5_gen3_fwnode_xlate(struct iio_dev *indio_dev,
+				const struct fwnode_reference_args *iiospec)
+{
+	struct adc5_chip *adc = iio_priv(indio_dev);
+	int i, v_channel;
+
+	for (i = 0; i < adc->nchannels; i++) {
+		v_channel = V_CHAN(adc->chan_props[i]);
+		if (v_channel == iiospec->args[0])
+			return i;
+	}
+
+	return -ENOENT;
+}
+
+static int adc5_gen3_read_raw(struct iio_dev *indio_dev,
+			 struct iio_chan_spec const *chan, int *val, int *val2,
+			 long mask)
+{
+	struct adc5_chip *adc = iio_priv(indio_dev);
+	struct adc5_channel_prop *prop;
+	u16 adc_code_volt;
+	int ret;
+
+	prop = &adc->chan_props[chan->address];
+
+	switch (mask) {
+	case IIO_CHAN_INFO_PROCESSED:
+		ret = adc5_gen3_do_conversion(adc, prop,
+					&adc_code_volt);
+		if (ret)
+			return ret;
+
+		ret = qcom_adc5_hw_scale(prop->scale_fn_type,
+			prop->prescale, adc->data,
+			adc_code_volt, val);
+		if (ret)
+			return ret;
+
+		return IIO_VAL_INT;
+	case IIO_CHAN_INFO_RAW:
+		ret = adc5_gen3_do_conversion(adc, prop,
+					&adc_code_volt);
+		if (ret)
+			return ret;
+		*val = (int)adc_code_volt;
+		return IIO_VAL_INT;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int adc5_gen3_read_label(struct iio_dev *indio_dev,
+			const struct iio_chan_spec *chan, char *label)
+{
+	struct adc5_chip *adc = iio_priv(indio_dev);
+	struct adc5_channel_prop *prop;
+
+	prop = &adc->chan_props[chan->address];
+	return snprintf(label, PAGE_SIZE, "%s\n", prop->label);
+}
+
+static const struct iio_info adc5_gen3_info = {
+	.read_raw = adc5_gen3_read_raw,
+	.read_label = adc5_gen3_read_label,
+	.fwnode_xlate = adc5_gen3_fwnode_xlate,
+};
+
+static int adc_tm_gen3_get_temp(struct thermal_zone_device *tz, int *temp)
+{
+	struct adc5_channel_prop *prop = tz->devdata;
+	struct adc5_chip *adc;
+	u16 adc_code_volt;
+	int ret;
+
+	if (!prop || !prop->chip)
+		return -EINVAL;
+
+	adc = prop->chip;
+
+	if (prop->last_temp_set) {
+		pr_debug("last_temp: %d\n", prop->last_temp);
+		prop->last_temp_set = false;
+		*temp = prop->last_temp;
+		return 0;
+	}
+
+	ret = adc5_gen3_do_conversion(adc, prop, &adc_code_volt);
+	if (ret < 0)
+		return ret;
+
+	return qcom_adc5_hw_scale(prop->scale_fn_type,
+		prop->prescale, adc->data,
+		adc_code_volt, temp);
+}
+
+static int _adc_tm5_gen3_disable_channel(struct adc5_channel_prop *prop)
+{
+	struct adc5_chip *adc = prop->chip;
+	int ret;
+	u8 val;
+
+	prop->high_thr_en = false;
+	prop->low_thr_en = false;
+
+	val = MEAS_INT_DISABLE;
+	ret = adc5_gen3_write(adc, prop->sdam_index, ADC5_GEN3_TIMER_SEL, &val, 1);
+	if (ret)
+		return ret;
+
+	/* To indicate there is an actual conversion request */
+	val = ADC5_GEN3_CHAN_CONV_REQ | prop->tm_chan_index;
+	ret = adc5_gen3_write(adc, prop->sdam_index, ADC5_GEN3_PERPH_CH, &val, 1);
+	if (ret)
+		return ret;
+
+	val = ADC5_GEN3_CONV_REQ_REQ;
+	return adc5_gen3_write(adc, prop->sdam_index, ADC5_GEN3_CONV_REQ, &val, 1);
+}
+
+static int adc_tm5_gen3_disable_channel(struct adc5_channel_prop *prop)
+{
+	return _adc_tm5_gen3_disable_channel(prop);
+}
+
+# define ADC_TM5_GEN3_CONFIG_REGS 12
+
+static int adc_tm5_gen3_configure(struct adc5_channel_prop *prop,
+					int low_temp, int high_temp)
+{
+	struct adc5_chip *adc = prop->chip;
+	u8 conv_req = 0, buf[ADC_TM5_GEN3_CONFIG_REGS];
+	u16 adc_code;
+	int ret;
+
+	ret = adc5_gen3_poll_wait_hs(adc, prop->sdam_index);
+	if (ret < 0)
+		return ret;
+
+	ret = adc5_gen3_read(adc, prop->sdam_index, ADC5_GEN3_SID, buf, sizeof(buf));
+	if (ret < 0)
+		return ret;
+
+	/* Write SID */
+	buf[0] = FIELD_PREP(ADC5_GEN3_SID_MASK, prop->sid);
+
+	/*
+	 * Select TM channel and indicate there is an actual
+	 * conversion request
+	 */
+	buf[1] = ADC5_GEN3_CHAN_CONV_REQ | prop->tm_chan_index;
+
+	buf[2] = prop->timer;
+
+	/* Digital param selection */
+	adc5_gen3_update_dig_param(adc, prop, &buf[3]);
+
+	/* Update fast average sample value */
+	buf[4] &= ~ADC5_GEN3_FAST_AVG_CTL_SAMPLES_MASK;
+	buf[4] |= prop->avg_samples | ADC5_GEN3_FAST_AVG_CTL_EN;
+
+	/* Select ADC channel */
+	buf[5] = prop->channel;
+
+	/* Select HW settle delay for channel */
+	buf[6] = FIELD_PREP(ADC5_GEN3_HW_SETTLE_DELAY_MASK, prop->hw_settle_time);
+
+	/* High temperature corresponds to low voltage threshold */
+	if (high_temp != INT_MAX) {
+		prop->low_thr_en = true;
+		adc_code = qcom_adc_tm5_gen2_temp_res_scale(high_temp);
+		put_unaligned_le16(adc_code, &buf[8]);
+	} else {
+		prop->low_thr_en = false;
+	}
+
+	/* Low temperature corresponds to high voltage threshold */
+	if (low_temp != -INT_MAX) {
+		prop->high_thr_en = true;
+		adc_code = qcom_adc_tm5_gen2_temp_res_scale(low_temp);
+		put_unaligned_le16(adc_code, &buf[10]);
+	} else {
+		prop->high_thr_en = false;
+	}
+
+	buf[7] = 0;
+	if (prop->high_thr_en)
+		buf[7] |= ADC5_GEN3_HIGH_THR_INT_EN;
+	if (prop->low_thr_en)
+		buf[7] |= ADC5_GEN3_LOW_THR_INT_EN;
+
+	ret = adc5_gen3_write(adc, prop->sdam_index, ADC5_GEN3_SID, buf, sizeof(buf));
+	if (ret < 0)
+		return ret;
+
+	conv_req = ADC5_GEN3_CONV_REQ_REQ;
+	return adc5_gen3_write(adc, prop->sdam_index, ADC5_GEN3_CONV_REQ, &conv_req, 1);
+}
+
+static int adc_tm5_gen3_set_trip_temp(struct thermal_zone_device *tz,
+					int low_temp, int high_temp)
+{
+	struct adc5_channel_prop *prop = tz->devdata;
+	struct adc5_chip *adc;
+	int ret;
+
+	if (!prop || !prop->chip)
+		return -EINVAL;
+
+	adc = prop->chip;
+
+	dev_dbg(adc->dev, "channel:%s, low_temp(mdegC):%d, high_temp(mdegC):%d\n",
+		prop->label, low_temp, high_temp);
+
+	mutex_lock(&adc->lock);
+	if (high_temp == INT_MAX && low_temp <= -INT_MAX)
+		ret = adc_tm5_gen3_disable_channel(prop);
+	else
+		ret = adc_tm5_gen3_configure(prop, low_temp, high_temp);
+	mutex_unlock(&adc->lock);
+
+	return ret;
+}
+
+static const struct thermal_zone_device_ops adc_tm_ops = {
+	.get_temp = adc_tm_gen3_get_temp,
+	.set_trips = adc_tm5_gen3_set_trip_temp,
+};
+
+static int adc_tm_register_tzd(struct adc5_chip *adc)
+{
+	unsigned int i, channel;
+	struct thermal_zone_device *tzd;
+
+	for (i = 0; i < adc->nchannels; i++) {
+		channel = V_CHAN(adc->chan_props[i]);
+
+		if (!adc->chan_props[i].adc_tm)
+			continue;
+		tzd = devm_thermal_of_zone_register(adc->dev, channel,
+			&adc->chan_props[i], &adc_tm_ops);
+
+		if (IS_ERR(tzd)) {
+			if (PTR_ERR(tzd) == -ENODEV) {
+				dev_warn(adc->dev, "thermal sensor on channel %d is not used\n",
+					 channel);
+				continue;
+			}
+
+			dev_err(adc->dev, "Error registering TZ zone:%ld for channel:%d\n",
+				PTR_ERR(tzd), adc->chan_props[i].channel);
+			return PTR_ERR(tzd);
+		}
+		adc->chan_props[i].tzd = tzd;
+	}
+
+	return 0;
+}
+
+static void adc5_gen3_disable(void *data)
+{
+	struct adc5_chip *adc = data;
+	int i;
+
+	if (adc->n_tm_channels)
+		cancel_work_sync(&adc->tm_handler_work);
+
+	for (i = 0; i < adc->num_sdams; i++)
+		free_irq(adc->base[i].irq, adc);
+
+	mutex_lock(&adc->lock);
+	/* Disable all available TM channels */
+	for (i = 0; i < adc->nchannels; i++) {
+		if (!adc->chan_props[i].adc_tm)
+			continue;
+		adc5_gen3_poll_wait_hs(adc, adc->chan_props[i].sdam_index);
+		_adc_tm5_gen3_disable_channel(&adc->chan_props[i]);
+	}
+
+	mutex_unlock(&adc->lock);
+}
+
+struct adc5_channels {
+	unsigned int prescale_index;
+	enum iio_chan_type type;
+	long info_mask;
+	enum vadc_scale_fn_type scale_fn_type;
+};
+
+/* In these definitions, _pre refers to an index into adc5_prescale_ratios. */
+#define ADC5_CHAN(_type, _mask, _pre, _scale)	\
+	{						\
+		.prescale_index = _pre,			\
+		.type = _type,				\
+		.info_mask = _mask,			\
+		.scale_fn_type = _scale,		\
+	},						\
+
+#define ADC5_CHAN_TEMP(_pre, _scale)		\
+	ADC5_CHAN(IIO_TEMP, BIT(IIO_CHAN_INFO_PROCESSED), _pre, _scale)	\
+
+#define ADC5_CHAN_VOLT(_pre, _scale)		\
+	ADC5_CHAN(IIO_VOLTAGE, BIT(IIO_CHAN_INFO_PROCESSED), _pre, _scale)	\
+
+#define ADC5_CHAN_CUR(_pre, _scale)		\
+	ADC5_CHAN(IIO_CURRENT, BIT(IIO_CHAN_INFO_PROCESSED), _pre, _scale)	\
+
+static const struct adc5_channels adc5_gen3_chans_pmic[ADC5_MAX_CHANNEL] = {
+	[ADC5_GEN3_OFFSET_REF]		= ADC5_CHAN_VOLT(0, SCALE_HW_CALIB_DEFAULT)
+	[ADC5_GEN3_1P25VREF]		= ADC5_CHAN_VOLT(0, SCALE_HW_CALIB_DEFAULT)
+	[ADC5_GEN3_VPH_PWR]		= ADC5_CHAN_VOLT(1, SCALE_HW_CALIB_DEFAULT)
+	[ADC5_GEN3_VBAT_SNS_QBG]	= ADC5_CHAN_VOLT(1, SCALE_HW_CALIB_DEFAULT)
+	[ADC5_GEN3_USB_SNS_V_16]	= ADC5_CHAN_TEMP(8, SCALE_HW_CALIB_DEFAULT)
+	[ADC5_GEN3_VIN_DIV16_MUX]	= ADC5_CHAN_TEMP(8, SCALE_HW_CALIB_DEFAULT)
+	[ADC5_GEN3_DIE_TEMP]		= ADC5_CHAN_TEMP(0,
+						SCALE_HW_CALIB_PMIC_THERM_PM7)
+	[ADC5_GEN3_TEMP_ALARM_LITE]	= ADC5_CHAN_TEMP(0,
+						SCALE_HW_CALIB_PMIC_THERM_PM7)
+	[ADC5_GEN3_AMUX1_THM_100K_PU]	= ADC5_CHAN_TEMP(0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM7)
+	[ADC5_GEN3_AMUX2_THM_100K_PU]	= ADC5_CHAN_TEMP(0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM7)
+	[ADC5_GEN3_AMUX3_THM_100K_PU]	= ADC5_CHAN_TEMP(0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM7)
+	[ADC5_GEN3_AMUX4_THM_100K_PU]	= ADC5_CHAN_TEMP(0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM7)
+	[ADC5_GEN3_AMUX5_THM_100K_PU]	= ADC5_CHAN_TEMP(0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM7)
+	[ADC5_GEN3_AMUX6_THM_100K_PU]	= ADC5_CHAN_TEMP(0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM7)
+	[ADC5_GEN3_AMUX1_GPIO_100K_PU]	= ADC5_CHAN_TEMP(0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM7)
+	[ADC5_GEN3_AMUX2_GPIO_100K_PU]	= ADC5_CHAN_TEMP(0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM7)
+	[ADC5_GEN3_AMUX3_GPIO_100K_PU]	= ADC5_CHAN_TEMP(0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM7)
+	[ADC5_GEN3_AMUX4_GPIO_100K_PU]	= ADC5_CHAN_TEMP(0,
+					SCALE_HW_CALIB_THERM_100K_PU_PM7)
+};
+
+static int adc5_gen3_get_fw_channel_data(struct adc5_chip *adc,
+				    struct adc5_channel_prop *prop,
+				    struct fwnode_handle *fwnode,
+				    const struct adc5_data *data)
+{
+	const char *name = fwnode_get_name(fwnode);
+	const char *channel_name;
+	struct device *dev = adc->dev;
+	u32 chan, value, varr[2], sid = 0;
+	int ret, val;
+
+	ret = fwnode_property_read_u32(fwnode, "reg", &chan);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "invalid channel number %s\n", name);
+
+	/*
+	 * Value read from "reg" is virtual channel number
+	 * virtual channel number = sid << 8 | channel number
+	 */
+
+	sid = FIELD_GET(ADC5_GEN3_VIRTUAL_SID_MASK, chan);
+	chan = FIELD_GET(ADC5_GEN3_CHANNEL_MASK, chan);
+
+	if (chan > ADC5_OFFSET_EXT2)
+		return dev_err_probe(dev, -EINVAL, "%s invalid channel number %d\n", name, chan);
+
+	prop->channel = chan;
+	prop->sid = sid;
+
+	ret = fwnode_property_read_string(fwnode, "label", &channel_name);
+	if (ret)
+		channel_name = name;
+	prop->label = channel_name;
+
+	prop->decimation = ADC5_DECIMATION_DEFAULT;
+	ret = fwnode_property_read_u32(fwnode, "qcom,decimation", &value);
+	if (!ret) {
+		ret = qcom_adc5_decimation_from_dt(value, data->decimation);
+		if (ret < 0)
+			return dev_err_probe(dev, ret, "%#x invalid decimation %d\n",
+				chan, value);
+		prop->decimation = ret;
+	}
+
+	prop->prescale = adc->data->adc_chans[prop->channel].prescale_index;
+	ret = fwnode_property_read_u32_array(fwnode, "qcom,pre-scaling", varr, 2);
+	if (!ret) {
+		ret = qcom_adc5_prescaling_from_dt(varr[0], varr[1]);
+		if (ret < 0)
+			return dev_err_probe(dev, ret, "%#x invalid pre-scaling <%d %d>\n",
+				chan, varr[0], varr[1]);
+		prop->prescale = ret;
+	}
+
+	prop->hw_settle_time = VADC_DEF_HW_SETTLE_TIME;
+	ret = fwnode_property_read_u32(fwnode, "qcom,hw-settle-time", &value);
+	if (!ret) {
+		ret = qcom_adc5_hw_settle_time_from_dt(value,
+						data->hw_settle_1);
+		if (ret < 0)
+			return dev_err_probe(dev, ret, "%#x invalid hw-settle-time %d us\n",
+				chan, value);
+		prop->hw_settle_time = ret;
+	}
+
+	prop->avg_samples = VADC_DEF_AVG_SAMPLES;
+	ret = fwnode_property_read_u32(fwnode, "qcom,avg-samples", &value);
+	if (!ret) {
+		ret = qcom_adc5_avg_samples_from_dt(value);
+		if (ret < 0)
+			return dev_err_probe(dev, ret, "%#x invalid avg-samples %d\n",
+				chan, value);
+		prop->avg_samples = ret;
+	}
+
+	if (fwnode_property_read_bool(fwnode, "qcom,ratiometric"))
+		prop->cal_method = ADC5_RATIOMETRIC_CAL;
+	else
+		prop->cal_method = ADC5_ABSOLUTE_CAL;
+
+	prop->timer = MEAS_INT_IMMEDIATE;
+
+	prop->adc_tm = fwnode_property_read_bool(fwnode, "qcom,adc-tm");
+
+	if (prop->adc_tm) {
+		adc->n_tm_channels++;
+		if (adc->n_tm_channels > ((adc->num_sdams * 8) - 1))
+			return dev_err_probe(adc->dev, -EINVAL,
+				"Number of TM nodes %u greater than channels supported:%u\n",
+				adc->n_tm_channels, (adc->num_sdams * 8) - 1);
+
+		val = adc->n_tm_channels / 8;
+		prop->sdam_index = val;
+		prop->tm_chan_index = adc->n_tm_channels - (8*val);
+
+		prop->timer = MEAS_INT_1S;
+	}
+
+	return 0;
+}
+
+static const struct adc5_data adc5_gen3_data_pmic = {
+	.full_scale_code_volt = 0x70e4,
+	.adc_chans = adc5_gen3_chans_pmic,
+	.info = &adc5_gen3_info,
+	.decimation = (unsigned int [ADC5_DECIMATION_SAMPLES_MAX])
+				{85, 340, 1360},
+	.hw_settle_1 = (unsigned int [VADC_HW_SETTLE_SAMPLES_MAX])
+				{15, 100, 200, 300, 400, 500, 600, 700,
+				1000, 2000, 4000, 8000, 16000, 32000,
+				64000, 128000},
+};
+
+static const struct of_device_id adc5_match_table[] = {
+	{
+		.compatible = "qcom,spmi-adc5-gen3",
+		.data = &adc5_gen3_data_pmic,
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, adc5_match_table);
+
+static int adc5_get_fw_data(struct adc5_chip *adc)
+{
+	const struct adc5_channels *adc_chan;
+	struct iio_chan_spec *iio_chan;
+	struct adc5_channel_prop *chan_props;
+	struct fwnode_handle *child;
+	unsigned int index = 0;
+	int ret;
+
+	adc->nchannels = device_get_child_node_count(adc->dev);
+	if (!adc->nchannels)
+		return -EINVAL;
+
+	adc->iio_chans = devm_kcalloc(adc->dev, adc->nchannels,
+				       sizeof(*adc->iio_chans), GFP_KERNEL);
+	if (!adc->iio_chans)
+		return -ENOMEM;
+
+	adc->chan_props = devm_kcalloc(adc->dev, adc->nchannels,
+					sizeof(*adc->chan_props), GFP_KERNEL);
+	if (!adc->chan_props)
+		return -ENOMEM;
+
+	chan_props = adc->chan_props;
+	adc->n_tm_channels = 0;
+	iio_chan = adc->iio_chans;
+	adc->data = device_get_match_data(adc->dev);
+	if (!adc->data)
+		adc->data = &adc5_gen3_data_pmic;
+
+	device_for_each_child_node(adc->dev, child) {
+		ret = adc5_gen3_get_fw_channel_data(adc, chan_props, child, adc->data);
+		if (ret < 0) {
+			fwnode_handle_put(child);
+			return ret;
+		}
+
+		chan_props->chip = adc;
+		chan_props->scale_fn_type =
+			adc->data->adc_chans[chan_props->channel].scale_fn_type;
+		adc_chan = &adc->data->adc_chans[chan_props->channel];
+		iio_chan->channel = V_CHAN(*chan_props);
+		iio_chan->info_mask_separate = adc_chan->info_mask;
+		iio_chan->type = adc_chan->type;
+		iio_chan->address = index;
+		iio_chan->indexed = 1;
+		iio_chan++;
+		chan_props++;
+		index++;
+	}
+
+	return 0;
+}
+
+static int adc5_gen3_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct iio_dev *indio_dev;
+	struct adc5_chip *adc;
+	struct regmap *regmap;
+	int ret, i;
+	u32 *reg;
+
+	regmap = dev_get_regmap(dev->parent, NULL);
+	if (!regmap)
+		return -ENODEV;
+
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
+	if (!indio_dev)
+		return -ENOMEM;
+
+	adc = iio_priv(indio_dev);
+	adc->regmap = regmap;
+	adc->dev = dev;
+
+	ret = device_property_count_u32(dev, "reg");
+	if (ret < 0)
+		return ret;
+
+	adc->num_sdams = ret;
+
+	reg = kcalloc(adc->num_sdams, sizeof(u32), GFP_KERNEL);
+	if (!reg)
+		return -ENOMEM;
+
+	ret = device_property_read_u32_array(dev, "reg", reg, adc->num_sdams);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to read reg property, ret = %d\n", ret);
+
+	adc->base = devm_kcalloc(dev, adc->num_sdams, sizeof(*adc->base), GFP_KERNEL);
+	if (!adc->base)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, indio_dev);
+	init_completion(&adc->complete);
+	mutex_init(&adc->lock);
+
+	for (i = 0; i < adc->num_sdams; i++) {
+		adc->base[i].base_addr = reg[i];
+
+		adc->base[i].irq_name = devm_kasprintf(dev, GFP_KERNEL, "adc-sdam%d", i);
+		if (!adc->base[i].irq_name) {
+			kfree(reg);
+			ret = -ENOMEM;
+			goto err_irq;
+		}
+
+		ret = platform_get_irq_byname(pdev, adc->base[i].irq_name);
+		if (ret < 0) {
+			kfree(reg);
+			dev_err(dev, "Getting IRQ %d by name failed, ret = %d\n",
+					adc->base[i].irq, ret);
+			goto err_irq;
+		}
+		adc->base[i].irq = ret;
+
+		ret = request_irq(adc->base[i].irq, adc5_gen3_isr, 0, adc->base[i].irq_name, adc);
+		if (ret < 0) {
+			kfree(reg);
+			dev_err(dev, "Failed to request SDAM%d irq, ret = %d\n", i, ret);
+			goto err_irq;
+		}
+	}
+	kfree(reg);
+
+	ret = devm_add_action(dev, adc5_gen3_disable, adc);
+	if (ret < 0) {
+		dev_err(dev, "failed to register adc disablement devm action, %d\n", ret);
+		goto err_irq;
+	}
+
+	ret = adc5_get_fw_data(adc);
+	if (ret < 0) {
+		dev_err(dev, "adc get dt data failed, ret = %d\n", ret);
+		goto err_irq;
+	}
+
+	ret = adc_tm_register_tzd(adc);
+	if (ret < 0)
+		goto err_irq;
+
+	if (adc->n_tm_channels)
+		INIT_WORK(&adc->tm_handler_work, tm_handler_work);
+
+	indio_dev->name = pdev->name;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &adc5_gen3_info;
+	indio_dev->channels = adc->iio_chans;
+	indio_dev->num_channels = adc->nchannels;
+
+	ret = devm_iio_device_register(dev, indio_dev);
+	if (!ret)
+		return 0;
+
+err_irq:
+	for (i = 0; i < adc->num_sdams; i++)
+		free_irq(adc->base[i].irq, adc);
+
+	return ret;
+}
+
+static struct platform_driver adc5_gen3_driver = {
+	.driver = {
+		.name = "qcom-spmi-adc5-gen3",
+		.of_match_table = adc5_match_table,
+	},
+	.probe = adc5_gen3_probe,
+};
+module_platform_driver(adc5_gen3_driver);
+
+MODULE_DESCRIPTION("Qualcomm Technologies Inc. PMIC5 Gen3 ADC driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/iio/adc/rockchip_saradc.c
+++ linux-qcom-6.8.0/drivers/iio/adc/rockchip_saradc.c
@@ -52,7 +52,7 @@
 #define SARADC2_START			BIT(4)
 #define SARADC2_SINGLE_MODE		BIT(5)
 
-#define SARADC2_CONV_CHANNELS GENMASK(15, 0)
+#define SARADC2_CONV_CHANNELS GENMASK(3, 0)
 
 struct rockchip_saradc;
 
@@ -102,12 +102,12 @@
 	writel_relaxed(0xc, info->regs + SARADC_T_DAS_SOC);
 	writel_relaxed(0x20, info->regs + SARADC_T_PD_SOC);
 	val = FIELD_PREP(SARADC2_EN_END_INT, 1);
-	val |= val << 16;
+	val |= SARADC2_EN_END_INT << 16;
 	writel_relaxed(val, info->regs + SARADC2_END_INT_EN);
 	val = FIELD_PREP(SARADC2_START, 1) |
 	      FIELD_PREP(SARADC2_SINGLE_MODE, 1) |
 	      FIELD_PREP(SARADC2_CONV_CHANNELS, chn);
-	val |= val << 16;
+	val |= (SARADC2_START | SARADC2_SINGLE_MODE | SARADC2_CONV_CHANNELS) << 16;
 	writel(val, info->regs + SARADC2_CONV_CON);
 }
 
@@ -368,6 +368,8 @@
 	int ret;
 	int i, j = 0;
 
+	memset(&data, 0, sizeof(data));
+
 	mutex_lock(&info->lock);
 
 	for_each_set_bit(i, i_dev->active_scan_mask, i_dev->masklength) {
--- linux-qcom-6.8.0.orig/drivers/iio/adc/stm32-adc.c
+++ linux-qcom-6.8.0/drivers/iio/adc/stm32-adc.c
@@ -2234,6 +2234,7 @@
 			if (vin[0] != val || vin[1] >= adc_info->max_channels) {
 				dev_err(&indio_dev->dev, "Invalid channel in%d-in%d\n",
 					vin[0], vin[1]);
+				ret = -EINVAL;
 				goto err;
 			}
 		} else if (ret != -EINVAL) {
--- linux-qcom-6.8.0.orig/drivers/iio/adc/ti-ads124s08.c
+++ linux-qcom-6.8.0/drivers/iio/adc/ti-ads124s08.c
@@ -183,9 +183,9 @@
 	struct ads124s_private *priv = iio_priv(indio_dev);
 
 	if (priv->reset_gpio) {
-		gpiod_set_value(priv->reset_gpio, 0);
+		gpiod_set_value_cansleep(priv->reset_gpio, 0);
 		udelay(200);
-		gpiod_set_value(priv->reset_gpio, 1);
+		gpiod_set_value_cansleep(priv->reset_gpio, 1);
 	} else {
 		return ads124s_write_cmd(indio_dev, ADS124S08_CMD_RESET);
 	}
--- linux-qcom-6.8.0.orig/drivers/iio/adc/ti-ads8688.c
+++ linux-qcom-6.8.0/drivers/iio/adc/ti-ads8688.c
@@ -382,7 +382,7 @@
 	struct iio_poll_func *pf = p;
 	struct iio_dev *indio_dev = pf->indio_dev;
 	/* Ensure naturally aligned timestamp */
-	u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8);
+	u16 buffer[ADS8688_MAX_CHANNELS + sizeof(s64)/sizeof(u16)] __aligned(8) = { };
 	int i, j = 0;
 
 	for (i = 0; i < indio_dev->masklength; i++) {
--- linux-qcom-6.8.0.orig/drivers/iio/adc/ti_am335x_adc.c
+++ linux-qcom-6.8.0/drivers/iio/adc/ti_am335x_adc.c
@@ -564,13 +564,11 @@
 			  struct tiadc_device *adc_dev)
 {
 	struct device_node *node = pdev->dev.of_node;
-	struct property *prop;
-	const __be32 *cur;
 	int channels = 0;
 	u32 val;
 	int i;
 
-	of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
+	of_property_for_each_u32(node, "ti,adc-channels", val) {
 		adc_dev->channel_line[channels] = val;
 
 		/* Set Default values for optional DT parameters */
--- linux-qcom-6.8.0.orig/drivers/iio/adc/xilinx-ams.c
+++ linux-qcom-6.8.0/drivers/iio/adc/xilinx-ams.c
@@ -414,8 +414,12 @@
 
 	/* Run calibration of PS & PL as part of the sequence */
 	scan_mask = BIT(0) | BIT(AMS_PS_SEQ_MAX);
-	for (i = 0; i < indio_dev->num_channels; i++)
-		scan_mask |= BIT_ULL(indio_dev->channels[i].scan_index);
+	for (i = 0; i < indio_dev->num_channels; i++) {
+		const struct iio_chan_spec *chan = &indio_dev->channels[i];
+
+		if (chan->scan_index < AMS_CTRL_SEQ_BASE)
+			scan_mask |= BIT_ULL(chan->scan_index);
+	}
 
 	if (ams->ps_base) {
 		/* put sysmon in a soft reset to change the sequence */
--- linux-qcom-6.8.0.orig/drivers/iio/amplifiers/Kconfig
+++ linux-qcom-6.8.0/drivers/iio/amplifiers/Kconfig
@@ -27,6 +27,7 @@
 config ADA4250
 	tristate "Analog Devices ADA4250 Instrumentation Amplifier"
 	depends on SPI
+	select REGMAP_SPI
 	help
 	  Say yes here to build support for Analog Devices ADA4250
 	  SPI Amplifier's support. The driver provides direct access via
--- linux-qcom-6.8.0.orig/drivers/iio/buffer/industrialio-buffer-dmaengine.c
+++ linux-qcom-6.8.0/drivers/iio/buffer/industrialio-buffer-dmaengine.c
@@ -159,7 +159,7 @@
  * Once done using the buffer iio_dmaengine_buffer_free() should be used to
  * release it.
  */
-static struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev,
+struct iio_buffer *iio_dmaengine_buffer_alloc(struct device *dev,
 	const char *channel)
 {
 	struct dmaengine_buffer *dmaengine_buffer;
@@ -180,7 +180,7 @@
 
 	ret = dma_get_slave_caps(chan, &caps);
 	if (ret < 0)
-		goto err_free;
+		goto err_release;
 
 	/* Needs to be aligned to the maximum of the minimums */
 	if (caps.src_addr_widths)
@@ -206,10 +206,13 @@
 
 	return &dmaengine_buffer->queue.buffer;
 
+err_release:
+	dma_release_channel(chan);
 err_free:
 	kfree(dmaengine_buffer);
 	return ERR_PTR(ret);
 }
+EXPORT_SYMBOL_NS_GPL(iio_dmaengine_buffer_alloc, IIO_DMAENGINE_BUFFER);
 
 /**
  * iio_dmaengine_buffer_free() - Free dmaengine buffer
@@ -217,7 +220,7 @@
  *
  * Frees a buffer previously allocated with iio_dmaengine_buffer_alloc().
  */
-static void iio_dmaengine_buffer_free(struct iio_buffer *buffer)
+void iio_dmaengine_buffer_free(struct iio_buffer *buffer)
 {
 	struct dmaengine_buffer *dmaengine_buffer =
 		iio_buffer_to_dmaengine_buffer(buffer);
@@ -227,6 +230,7 @@
 
 	iio_buffer_put(buffer);
 }
+EXPORT_SYMBOL_NS_GPL(iio_dmaengine_buffer_free, IIO_DMAENGINE_BUFFER);
 
 static void __devm_iio_dmaengine_buffer_free(void *buffer)
 {
@@ -288,7 +292,7 @@
 
 	return iio_device_attach_buffer(indio_dev, buffer);
 }
-EXPORT_SYMBOL_GPL(devm_iio_dmaengine_buffer_setup);
+EXPORT_SYMBOL_NS_GPL(devm_iio_dmaengine_buffer_setup, IIO_DMAENGINE_BUFFER);
 
 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
 MODULE_DESCRIPTION("DMA buffer for the IIO framework");
--- linux-qcom-6.8.0.orig/drivers/iio/chemical/bme680.h
+++ linux-qcom-6.8.0/drivers/iio/chemical/bme680.h
@@ -54,7 +54,9 @@
 #define   BME680_NB_CONV_MASK			GENMASK(3, 0)
 
 #define BME680_REG_MEAS_STAT_0			0x1D
+#define   BME680_NEW_DATA_BIT			BIT(7)
 #define   BME680_GAS_MEAS_BIT			BIT(6)
+#define   BME680_MEAS_BIT			BIT(5)
 
 /* Calibration Parameters */
 #define BME680_T2_LSB_REG	0x8A
--- linux-qcom-6.8.0.orig/drivers/iio/chemical/bme680_core.c
+++ linux-qcom-6.8.0/drivers/iio/chemical/bme680_core.c
@@ -10,6 +10,8 @@
  */
 #include <linux/acpi.h>
 #include <linux/bitfield.h>
+#include <linux/cleanup.h>
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/log2.h>
@@ -38,7 +40,7 @@
 	s8  par_h3;
 	s8  par_h4;
 	s8  par_h5;
-	s8  par_h6;
+	u8  par_h6;
 	s8  par_h7;
 	s8  par_gh1;
 	s16 par_gh2;
@@ -51,6 +53,7 @@
 struct bme680_data {
 	struct regmap *regmap;
 	struct bme680_calib bme680;
+	struct mutex lock; /* Protect multiple serial R/W ops to device. */
 	u8 oversampling_temp;
 	u8 oversampling_press;
 	u8 oversampling_humid;
@@ -342,10 +345,10 @@
 	if (!calib->par_t2)
 		bme680_read_calib(data, calib);
 
-	var1 = (adc_temp >> 3) - (calib->par_t1 << 1);
+	var1 = (adc_temp >> 3) - ((s32)calib->par_t1 << 1);
 	var2 = (var1 * calib->par_t2) >> 11;
 	var3 = ((var1 >> 1) * (var1 >> 1)) >> 12;
-	var3 = (var3 * (calib->par_t3 << 4)) >> 14;
+	var3 = (var3 * ((s32)calib->par_t3 << 4)) >> 14;
 	data->t_fine = var2 + var3;
 	calc_temp = (data->t_fine * 5 + 128) >> 8;
 
@@ -368,9 +371,9 @@
 	var1 = (data->t_fine >> 1) - 64000;
 	var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * calib->par_p6) >> 2;
 	var2 = var2 + (var1 * calib->par_p5 << 1);
-	var2 = (var2 >> 2) + (calib->par_p4 << 16);
+	var2 = (var2 >> 2) + ((s32)calib->par_p4 << 16);
 	var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) *
-			(calib->par_p3 << 5)) >> 3) +
+			((s32)calib->par_p3 << 5)) >> 3) +
 			((calib->par_p2 * var1) >> 1);
 	var1 = var1 >> 18;
 	var1 = ((32768 + var1) * calib->par_p1) >> 15;
@@ -388,7 +391,7 @@
 	var3 = ((press_comp >> 8) * (press_comp >> 8) *
 			(press_comp >> 8) * calib->par_p10) >> 17;
 
-	press_comp += (var1 + var2 + var3 + (calib->par_p7 << 7)) >> 4;
+	press_comp += (var1 + var2 + var3 + ((s32)calib->par_p7 << 7)) >> 4;
 
 	return press_comp;
 }
@@ -414,7 +417,7 @@
 		 (((temp_scaled * ((temp_scaled * calib->par_h5) / 100))
 		   >> 6) / 100) + (1 << 14))) >> 10;
 	var3 = var1 * var2;
-	var4 = calib->par_h6 << 7;
+	var4 = (s32)calib->par_h6 << 7;
 	var4 = (var4 + ((temp_scaled * calib->par_h7) / 100)) >> 4;
 	var5 = ((var3 >> 14) * (var3 >> 14)) >> 10;
 	var6 = (var4 * var5) >> 1;
@@ -532,6 +535,43 @@
 	return ilog2(val) + 1;
 }
 
+/*
+ * Taken from Bosch BME680 API:
+ * https://github.com/boschsensortec/BME68x_SensorAPI/blob/v4.4.8/bme68x.c#L490
+ */
+static int bme680_wait_for_eoc(struct bme680_data *data)
+{
+	struct device *dev = regmap_get_device(data->regmap);
+	unsigned int check;
+	int ret;
+	/*
+	 * (Sum of oversampling ratios * time per oversampling) +
+	 * TPH measurement + gas measurement + wait transition from forced mode
+	 * + heater duration
+	 */
+	int wait_eoc_us = ((data->oversampling_temp + data->oversampling_press +
+			   data->oversampling_humid) * 1936) + (477 * 4) +
+			   (477 * 5) + 1000 + (data->heater_dur * 1000);
+
+	usleep_range(wait_eoc_us, wait_eoc_us + 100);
+
+	ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check);
+	if (ret) {
+		dev_err(dev, "failed to read measurement status register.\n");
+		return ret;
+	}
+	if (check & BME680_MEAS_BIT) {
+		dev_err(dev, "Device measurement cycle incomplete.\n");
+		return -EBUSY;
+	}
+	if (!(check & BME680_NEW_DATA_BIT)) {
+		dev_err(dev, "No new data available from the device.\n");
+		return -ENODATA;
+	}
+
+	return 0;
+}
+
 static int bme680_chip_config(struct bme680_data *data)
 {
 	struct device *dev = regmap_get_device(data->regmap);
@@ -622,6 +662,10 @@
 	if (ret < 0)
 		return ret;
 
+	ret = bme680_wait_for_eoc(data);
+	if (ret)
+		return ret;
+
 	ret = regmap_bulk_read(data->regmap, BME680_REG_TEMP_MSB,
 			       &tmp, 3);
 	if (ret < 0) {
@@ -678,7 +722,7 @@
 	}
 
 	*val = bme680_compensate_press(data, adc_press);
-	*val2 = 100;
+	*val2 = 1000;
 	return IIO_VAL_FRACTIONAL;
 }
 
@@ -738,6 +782,10 @@
 	if (ret < 0)
 		return ret;
 
+	ret = bme680_wait_for_eoc(data);
+	if (ret)
+		return ret;
+
 	ret = regmap_read(data->regmap, BME680_REG_MEAS_STAT_0, &check);
 	if (check & BME680_GAS_MEAS_BIT) {
 		dev_err(dev, "gas measurement incomplete\n");
@@ -781,6 +829,8 @@
 {
 	struct bme680_data *data = iio_priv(indio_dev);
 
+	guard(mutex)(&data->lock);
+
 	switch (mask) {
 	case IIO_CHAN_INFO_PROCESSED:
 		switch (chan->type) {
@@ -825,6 +875,8 @@
 {
 	struct bme680_data *data = iio_priv(indio_dev);
 
+	guard(mutex)(&data->lock);
+
 	if (val2 != 0)
 		return -EINVAL;
 
@@ -921,6 +973,7 @@
 		name = bme680_match_acpi_device(dev);
 
 	data = iio_priv(indio_dev);
+	mutex_init(&data->lock);
 	dev_set_drvdata(dev, indio_dev);
 	data->regmap = regmap;
 	indio_dev->name = name;
--- linux-qcom-6.8.0.orig/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
+++ linux-qcom-6.8.0/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
@@ -32,7 +32,7 @@
 	latency = integer * 1000 + fract / 1000;
 	ret = hid_sensor_set_report_latency(attrb, latency);
 	if (ret < 0)
-		return len;
+		return ret;
 
 	attrb->latency_ms = hid_sensor_get_report_latency(attrb);
 
--- linux-qcom-6.8.0.orig/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
+++ linux-qcom-6.8.0/drivers/iio/common/inv_sensors/inv_sensors_timestamp.c
@@ -60,11 +60,19 @@
 int inv_sensors_timestamp_update_odr(struct inv_sensors_timestamp *ts,
 				     uint32_t period, bool fifo)
 {
+	uint32_t mult;
+
 	/* when FIFO is on, prevent odr change if one is already pending */
 	if (fifo && ts->new_mult != 0)
 		return -EAGAIN;
 
-	ts->new_mult = period / ts->chip.clock_period;
+	mult = period / ts->chip.clock_period;
+	if (mult != ts->mult)
+		ts->new_mult = mult;
+
+	/* When FIFO is off, directly apply the new ODR */
+	if (!fifo)
+		inv_sensors_timestamp_apply_odr(ts, 0, 0, 0);
 
 	return 0;
 }
@@ -101,6 +109,9 @@
 
 static void inv_align_timestamp_it(struct inv_sensors_timestamp *ts)
 {
+	const int64_t period_min = ts->min_period * ts->mult;
+	const int64_t period_max = ts->max_period * ts->mult;
+	int64_t add_max, sub_max;
 	int64_t delta, jitter;
 	int64_t adjust;
 
@@ -108,11 +119,13 @@
 	delta = ts->it.lo - ts->timestamp;
 
 	/* adjust timestamp while respecting jitter */
+	add_max = period_max - (int64_t)ts->period;
+	sub_max = period_min - (int64_t)ts->period;
 	jitter = INV_SENSORS_TIMESTAMP_JITTER((int64_t)ts->period, ts->chip.jitter);
 	if (delta > jitter)
-		adjust = jitter;
+		adjust = add_max;
 	else if (delta < -jitter)
-		adjust = -jitter;
+		adjust = sub_max;
 	else
 		adjust = 0;
 
--- linux-qcom-6.8.0.orig/drivers/iio/dac/Kconfig
+++ linux-qcom-6.8.0/drivers/iio/dac/Kconfig
@@ -9,6 +9,8 @@
 config AD3552R
 	tristate "Analog Devices AD3552R DAC driver"
 	depends on SPI_MASTER
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	help
 	  Say yes here to build support for Analog Devices AD3552R
 	  Digital to Analog Converter.
@@ -214,6 +216,8 @@
 config AD5766
 	tristate "Analog Devices AD5766/AD5767 DAC driver"
 	depends on SPI_MASTER
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	help
 	  Say yes here to build support for Analog Devices AD5766, AD5767
 	  Digital to Analog Converter.
@@ -224,6 +228,7 @@
 config AD5770R
 	tristate "Analog Devices AD5770R IDAC driver"
 	depends on SPI_MASTER
+	select REGMAP_SPI
 	help
 	  Say yes here to build support for Analog Devices AD5770R Digital to
 	  Analog Converter.
@@ -315,6 +320,7 @@
 config LTC1660
 	tristate "Linear Technology LTC1660/LTC1665 DAC SPI driver"
 	depends on SPI
+	select REGMAP_SPI
 	help
 	  Say yes here to build support for Linear Technology
 	  LTC1660 and LTC1665 Digital to Analog Converters.
@@ -434,6 +440,7 @@
 
 config STM32_DAC_CORE
 	tristate
+	select REGMAP_MMIO
 
 config TI_DAC082S085
 	tristate "Texas Instruments 8/10/12-bit 2/4-channel DAC driver"
--- linux-qcom-6.8.0.orig/drivers/iio/dac/ad5592r-base.c
+++ linux-qcom-6.8.0/drivers/iio/dac/ad5592r-base.c
@@ -415,7 +415,7 @@
 			s64 tmp = *val * (3767897513LL / 25LL);
 			*val = div_s64_rem(tmp, 1000000000LL, val2);
 
-			return IIO_VAL_INT_PLUS_MICRO;
+			return IIO_VAL_INT_PLUS_NANO;
 		}
 
 		mutex_lock(&st->lock);
--- linux-qcom-6.8.0.orig/drivers/iio/dummy/iio_simple_dummy_buffer.c
+++ linux-qcom-6.8.0/drivers/iio/dummy/iio_simple_dummy_buffer.c
@@ -48,7 +48,7 @@
 	int i = 0, j;
 	u16 *data;
 
-	data = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
+	data = kzalloc(indio_dev->scan_bytes, GFP_KERNEL);
 	if (!data)
 		goto done;
 
--- linux-qcom-6.8.0.orig/drivers/iio/frequency/Kconfig
+++ linux-qcom-6.8.0/drivers/iio/frequency/Kconfig
@@ -53,6 +53,7 @@
 config ADF4377
 	tristate "Analog Devices ADF4377 Microwave Wideband Synthesizer"
 	depends on SPI && COMMON_CLK
+	select REGMAP_SPI
 	help
 	  Say yes here to build support for Analog Devices ADF4377 Microwave
 	  Wideband Synthesizer.
@@ -81,25 +82,26 @@
 	  module will be called admv1014.
 
 config ADMV4420
-       tristate "Analog Devices ADMV4420 K Band Downconverter"
-       depends on SPI
-       help
-         Say yes here to build support for Analog Devices K Band
-         Downconverter with integrated Fractional-N PLL and VCO.
+	tristate "Analog Devices ADMV4420 K Band Downconverter"
+	depends on SPI
+	select REGMAP_SPI
+	help
+	  Say yes here to build support for Analog Devices K Band
+	  Downconverter with integrated Fractional-N PLL and VCO.
 
-         To compile this driver as a module, choose M here: the
-         module will be called admv4420.
+	  To compile this driver as a module, choose M here: the
+	  module will be called admv4420.
 
 config ADRF6780
-        tristate "Analog Devices ADRF6780 Microwave Upconverter"
-        depends on SPI
-        depends on COMMON_CLK
-        help
-          Say yes here to build support for Analog Devices ADRF6780
-          5.9 GHz to 23.6 GHz, Wideband, Microwave Upconverter.
+	tristate "Analog Devices ADRF6780 Microwave Upconverter"
+	depends on SPI
+	depends on COMMON_CLK
+	help
+	  Say yes here to build support for Analog Devices ADRF6780
+	  5.9 GHz to 23.6 GHz, Wideband, Microwave Upconverter.
 
-          To compile this driver as a module, choose M here: the
-          module will be called adrf6780.
+	  To compile this driver as a module, choose M here: the
+	  module will be called adrf6780.
 
 endmenu
 endmenu
--- linux-qcom-6.8.0.orig/drivers/iio/frequency/adrf6780.c
+++ linux-qcom-6.8.0/drivers/iio/frequency/adrf6780.c
@@ -9,7 +9,6 @@
 #include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
-#include <linux/clk-provider.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/iio/iio.h>
--- linux-qcom-6.8.0.orig/drivers/iio/gyro/fxas21002c_core.c
+++ linux-qcom-6.8.0/drivers/iio/gyro/fxas21002c_core.c
@@ -730,14 +730,21 @@
 	int ret;
 
 	mutex_lock(&data->lock);
+	ret = fxas21002c_pm_get(data);
+	if (ret < 0)
+		goto out_unlock;
+
 	ret = regmap_bulk_read(data->regmap, FXAS21002C_REG_OUT_X_MSB,
 			       data->buffer, CHANNEL_SCAN_MAX * sizeof(s16));
 	if (ret < 0)
-		goto out_unlock;
+		goto out_pm_put;
 
 	iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
 					   data->timestamp);
 
+out_pm_put:
+	fxas21002c_pm_put(data);
+
 out_unlock:
 	mutex_unlock(&data->lock);
 
--- linux-qcom-6.8.0.orig/drivers/iio/imu/adis16475.c
+++ linux-qcom-6.8.0/drivers/iio/imu/adis16475.c
@@ -1289,6 +1289,7 @@
 	struct device *dev = &st->adis.spi->dev;
 	const struct adis16475_sync *sync;
 	u32 sync_mode;
+	u16 val;
 
 	/* default to internal clk */
 	st->clk_freq = st->info->int_clk * 1000;
@@ -1350,8 +1351,9 @@
 	 * I'm keeping this for simplicity and avoiding extra variables
 	 * in chip_info.
 	 */
+	val = ADIS16475_SYNC_MODE(sync->sync_mode);
 	ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL,
-				 ADIS16475_SYNC_MODE_MASK, sync->sync_mode);
+				 ADIS16475_SYNC_MODE_MASK, val);
 	if (ret)
 		return ret;
 
--- linux-qcom-6.8.0.orig/drivers/iio/imu/bmi323/bmi323_core.c
+++ linux-qcom-6.8.0/drivers/iio/imu/bmi323/bmi323_core.c
@@ -1391,7 +1391,7 @@
 				       &data->buffer.channels,
 				       ARRAY_SIZE(data->buffer.channels));
 		if (ret)
-			return IRQ_NONE;
+			goto out;
 	} else {
 		for_each_set_bit(bit, indio_dev->active_scan_mask,
 				 BMI323_CHAN_MAX) {
@@ -1400,13 +1400,14 @@
 					      &data->buffer.channels[index++],
 					      BMI323_BYTES_PER_SAMPLE);
 			if (ret)
-				return IRQ_NONE;
+				goto out;
 		}
 	}
 
 	iio_push_to_buffers_with_timestamp(indio_dev, &data->buffer,
 					   iio_get_time_ns(indio_dev));
 
+out:
 	iio_trigger_notify_done(indio_dev->trig);
 
 	return IRQ_HANDLED;
--- linux-qcom-6.8.0.orig/drivers/iio/imu/inv_icm42600/inv_icm42600.h
+++ linux-qcom-6.8.0/drivers/iio/imu/inv_icm42600/inv_icm42600.h
@@ -362,6 +362,7 @@
 typedef int (*inv_icm42600_bus_setup)(struct inv_icm42600_state *);
 
 extern const struct regmap_config inv_icm42600_regmap_config;
+extern const struct regmap_config inv_icm42600_spi_regmap_config;
 extern const struct dev_pm_ops inv_icm42600_pm_ops;
 
 const struct iio_mount_matrix *
--- linux-qcom-6.8.0.orig/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
+++ linux-qcom-6.8.0/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c
@@ -99,7 +99,6 @@
 					       const unsigned long *scan_mask)
 {
 	struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
-	struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
 	struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
 	unsigned int fifo_en = 0;
 	unsigned int sleep_temp = 0;
@@ -127,12 +126,7 @@
 	}
 
 	/* update data FIFO write */
-	inv_sensors_timestamp_apply_odr(ts, 0, 0, 0);
 	ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en);
-	if (ret)
-		goto out_unlock;
-
-	ret = inv_icm42600_buffer_update_watermark(st);
 
 out_unlock:
 	mutex_unlock(&st->lock);
--- linux-qcom-6.8.0.orig/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
+++ linux-qcom-6.8.0/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c
@@ -17,6 +17,7 @@
 #include <linux/regmap.h>
 
 #include <linux/iio/iio.h>
+#include <linux/iio/common/inv_sensors_timestamp.h>
 
 #include "inv_icm42600.h"
 #include "inv_icm42600_buffer.h"
@@ -34,15 +35,74 @@
 	},
 };
 
+static const struct regmap_range inv_icm42600_regmap_volatile_yes_ranges[] = {
+	/* Sensor data registers */
+	regmap_reg_range(0x001D, 0x002A),
+	/* INT status, FIFO, APEX data */
+	regmap_reg_range(0x002D, 0x0038),
+	/* Signal path reset */
+	regmap_reg_range(0x004B, 0x004B),
+	/* FIFO lost packets */
+	regmap_reg_range(0x006C, 0x006D),
+	/* Timestamp value */
+	regmap_reg_range(0x1062, 0x1064),
+};
+
+static const struct regmap_range inv_icm42600_regmap_volatile_no_ranges[] = {
+	regmap_reg_range(0x0000, 0x001C),
+	regmap_reg_range(0x006E, 0x1061),
+	regmap_reg_range(0x1065, 0x4FFF),
+};
+
+static const struct regmap_access_table inv_icm42600_regmap_volatile_accesses[] = {
+	{
+		.yes_ranges = inv_icm42600_regmap_volatile_yes_ranges,
+		.n_yes_ranges = ARRAY_SIZE(inv_icm42600_regmap_volatile_yes_ranges),
+		.no_ranges = inv_icm42600_regmap_volatile_no_ranges,
+		.n_no_ranges = ARRAY_SIZE(inv_icm42600_regmap_volatile_no_ranges),
+	},
+};
+
+static const struct regmap_range inv_icm42600_regmap_rd_noinc_no_ranges[] = {
+	regmap_reg_range(0x0000, INV_ICM42600_REG_FIFO_DATA - 1),
+	regmap_reg_range(INV_ICM42600_REG_FIFO_DATA + 1, 0x4FFF),
+};
+
+static const struct regmap_access_table inv_icm42600_regmap_rd_noinc_accesses[] = {
+	{
+		.no_ranges = inv_icm42600_regmap_rd_noinc_no_ranges,
+		.n_no_ranges = ARRAY_SIZE(inv_icm42600_regmap_rd_noinc_no_ranges),
+	},
+};
+
 const struct regmap_config inv_icm42600_regmap_config = {
+	.name = "inv_icm42600",
 	.reg_bits = 8,
 	.val_bits = 8,
 	.max_register = 0x4FFF,
 	.ranges = inv_icm42600_regmap_ranges,
 	.num_ranges = ARRAY_SIZE(inv_icm42600_regmap_ranges),
+	.volatile_table = inv_icm42600_regmap_volatile_accesses,
+	.rd_noinc_table = inv_icm42600_regmap_rd_noinc_accesses,
+	.cache_type = REGCACHE_RBTREE,
 };
 EXPORT_SYMBOL_NS_GPL(inv_icm42600_regmap_config, IIO_ICM42600);
 
+/* define specific regmap for SPI not supporting burst write */
+const struct regmap_config inv_icm42600_spi_regmap_config = {
+	.name = "inv_icm42600",
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = 0x4FFF,
+	.ranges = inv_icm42600_regmap_ranges,
+	.num_ranges = ARRAY_SIZE(inv_icm42600_regmap_ranges),
+	.volatile_table = inv_icm42600_regmap_volatile_accesses,
+	.rd_noinc_table = inv_icm42600_regmap_rd_noinc_accesses,
+	.cache_type = REGCACHE_RBTREE,
+	.use_single_write = true,
+};
+EXPORT_SYMBOL_NS_GPL(inv_icm42600_spi_regmap_config, IIO_ICM42600);
+
 struct inv_icm42600_hw {
 	uint8_t whoami;
 	const char *name;
@@ -725,6 +785,8 @@
 static int inv_icm42600_resume(struct device *dev)
 {
 	struct inv_icm42600_state *st = dev_get_drvdata(dev);
+	struct inv_sensors_timestamp *gyro_ts = iio_priv(st->indio_gyro);
+	struct inv_sensors_timestamp *accel_ts = iio_priv(st->indio_accel);
 	int ret;
 
 	mutex_lock(&st->lock);
@@ -745,9 +807,12 @@
 		goto out_unlock;
 
 	/* restore FIFO data streaming */
-	if (st->fifo.on)
+	if (st->fifo.on) {
+		inv_sensors_timestamp_reset(gyro_ts);
+		inv_sensors_timestamp_reset(accel_ts);
 		ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG,
 				   INV_ICM42600_FIFO_CONFIG_STREAM);
+	}
 
 out_unlock:
 	mutex_unlock(&st->lock);
--- linux-qcom-6.8.0.orig/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
+++ linux-qcom-6.8.0/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c
@@ -99,7 +99,6 @@
 					      const unsigned long *scan_mask)
 {
 	struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev);
-	struct inv_sensors_timestamp *ts = iio_priv(indio_dev);
 	struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT;
 	unsigned int fifo_en = 0;
 	unsigned int sleep_gyro = 0;
@@ -127,12 +126,7 @@
 	}
 
 	/* update data FIFO write */
-	inv_sensors_timestamp_apply_odr(ts, 0, 0, 0);
 	ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en);
-	if (ret)
-		goto out_unlock;
-
-	ret = inv_icm42600_buffer_update_watermark(st);
 
 out_unlock:
 	mutex_unlock(&st->lock);
--- linux-qcom-6.8.0.orig/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c
+++ linux-qcom-6.8.0/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c
@@ -59,7 +59,8 @@
 		return -EINVAL;
 	chip = (uintptr_t)match;
 
-	regmap = devm_regmap_init_spi(spi, &inv_icm42600_regmap_config);
+	/* use SPI specific regmap */
+	regmap = devm_regmap_init_spi(spi, &inv_icm42600_spi_regmap_config);
 	if (IS_ERR(regmap))
 		return PTR_ERR(regmap);
 
--- linux-qcom-6.8.0.orig/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
+++ linux-qcom-6.8.0/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
@@ -111,7 +111,6 @@
 	if (enable) {
 		/* reset timestamping */
 		inv_sensors_timestamp_reset(&st->timestamp);
-		inv_sensors_timestamp_apply_odr(&st->timestamp, 0, 0, 0);
 		/* reset FIFO */
 		d = st->chip_config.user_ctrl | INV_MPU6050_BIT_FIFO_RST;
 		ret = regmap_write(st->map, st->reg->user_ctrl, d);
--- linux-qcom-6.8.0.orig/drivers/iio/imu/kmx61.c
+++ linux-qcom-6.8.0/drivers/iio/imu/kmx61.c
@@ -1192,7 +1192,7 @@
 	struct kmx61_data *data = kmx61_get_data(indio_dev);
 	int bit, ret, i = 0;
 	u8 base;
-	s16 buffer[8];
+	s16 buffer[8] = { };
 
 	if (indio_dev == data->acc_indio_dev)
 		base = KMX61_ACC_XOUT_L;
--- linux-qcom-6.8.0.orig/drivers/iio/industrialio-backend.c
+++ linux-qcom-6.8.0/drivers/iio/industrialio-backend.c
@@ -0,0 +1,418 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Framework to handle complex IIO aggregate devices.
+ *
+ * The typical architecture is to have one device as the frontend device which
+ * can be "linked" against one or multiple backend devices. All the IIO and
+ * userspace interface is expected to be registers/managed by the frontend
+ * device which will callback into the backends when needed (to get/set some
+ * configuration that it does not directly control).
+ *
+ *                                           -------------------------------------------------------
+ * ------------------                        | ------------         ------------      -------  FPGA|
+ * |     ADC        |------------------------| | ADC CORE |---------| DMA CORE |------| RAM |      |
+ * | (Frontend/IIO) | Serial Data (eg: LVDS) | |(backend) |---------|          |------|     |      |
+ * |                |------------------------| ------------         ------------      -------      |
+ * ------------------                        -------------------------------------------------------
+ *
+ * The framework interface is pretty simple:
+ *   - Backends should register themselves with devm_iio_backend_register()
+ *   - Frontend devices should get backends with devm_iio_backend_get()
+ *
+ * Also to note that the primary target for this framework are converters like
+ * ADC/DACs so iio_backend_ops will have some operations typical of converter
+ * devices. On top of that, this is "generic" for all IIO which means any kind
+ * of device can make use of the framework. That said, If the iio_backend_ops
+ * struct begins to grow out of control, we can always refactor things so that
+ * the industrialio-backend.c is only left with the really generic stuff. Then,
+ * we can build on top of it depending on the needs.
+ *
+ * Copyright (C) 2023-2024 Analog Devices Inc.
+ */
+#define dev_fmt(fmt) "iio-backend: " fmt
+
+#include <linux/cleanup.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/property.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <linux/iio/backend.h>
+
+struct iio_backend {
+	struct list_head entry;
+	const struct iio_backend_ops *ops;
+	struct device *dev;
+	struct module *owner;
+	void *priv;
+};
+
+/*
+ * Helper struct for requesting buffers. This ensures that we have all data
+ * that we need to free the buffer in a device managed action.
+ */
+struct iio_backend_buffer_pair {
+	struct iio_backend *back;
+	struct iio_buffer *buffer;
+};
+
+static LIST_HEAD(iio_back_list);
+static DEFINE_MUTEX(iio_back_lock);
+
+/*
+ * Helper macros to call backend ops. Makes sure the option is supported.
+ */
+#define iio_backend_check_op(back, op) ({ \
+	struct iio_backend *____back = back;				\
+	int ____ret = 0;						\
+									\
+	if (!____back->ops->op)						\
+		____ret = -EOPNOTSUPP;					\
+									\
+	____ret;							\
+})
+
+#define iio_backend_op_call(back, op, args...) ({		\
+	struct iio_backend *__back = back;			\
+	int __ret;						\
+								\
+	__ret = iio_backend_check_op(__back, op);		\
+	if (!__ret)						\
+		__ret = __back->ops->op(__back, ##args);	\
+								\
+	__ret;							\
+})
+
+#define iio_backend_ptr_op_call(back, op, args...) ({		\
+	struct iio_backend *__back = back;			\
+	void *ptr_err;						\
+	int __ret;						\
+								\
+	__ret = iio_backend_check_op(__back, op);		\
+	if (__ret)						\
+		ptr_err = ERR_PTR(__ret);			\
+	else							\
+		ptr_err = __back->ops->op(__back, ##args);	\
+								\
+	ptr_err;						\
+})
+
+#define iio_backend_void_op_call(back, op, args...) {		\
+	struct iio_backend *__back = back;			\
+	int __ret;						\
+								\
+	__ret = iio_backend_check_op(__back, op);		\
+	if (!__ret)						\
+		__back->ops->op(__back, ##args);		\
+}
+
+/**
+ * iio_backend_chan_enable - Enable a backend channel
+ * @back:	Backend device
+ * @chan:	Channel number
+ *
+ * RETURNS:
+ * 0 on success, negative error number on failure.
+ */
+int iio_backend_chan_enable(struct iio_backend *back, unsigned int chan)
+{
+	return iio_backend_op_call(back, chan_enable, chan);
+}
+EXPORT_SYMBOL_NS_GPL(iio_backend_chan_enable, IIO_BACKEND);
+
+/**
+ * iio_backend_chan_disable - Disable a backend channel
+ * @back:	Backend device
+ * @chan:	Channel number
+ *
+ * RETURNS:
+ * 0 on success, negative error number on failure.
+ */
+int iio_backend_chan_disable(struct iio_backend *back, unsigned int chan)
+{
+	return iio_backend_op_call(back, chan_disable, chan);
+}
+EXPORT_SYMBOL_NS_GPL(iio_backend_chan_disable, IIO_BACKEND);
+
+static void __iio_backend_disable(void *back)
+{
+	iio_backend_void_op_call(back, disable);
+}
+
+/**
+ * devm_iio_backend_enable - Device managed backend enable
+ * @dev:	Consumer device for the backend
+ * @back:	Backend device
+ *
+ * RETURNS:
+ * 0 on success, negative error number on failure.
+ */
+int devm_iio_backend_enable(struct device *dev, struct iio_backend *back)
+{
+	int ret;
+
+	ret = iio_backend_op_call(back, enable);
+	if (ret)
+		return ret;
+
+	return devm_add_action_or_reset(dev, __iio_backend_disable, back);
+}
+EXPORT_SYMBOL_NS_GPL(devm_iio_backend_enable, IIO_BACKEND);
+
+/**
+ * iio_backend_data_format_set - Configure the channel data format
+ * @back:	Backend device
+ * @chan:	Channel number
+ * @data:	Data format
+ *
+ * Properly configure a channel with respect to the expected data format. A
+ * @struct iio_backend_data_fmt must be passed with the settings.
+ *
+ * RETURNS:
+ * 0 on success, negative error number on failure.
+ */
+int iio_backend_data_format_set(struct iio_backend *back, unsigned int chan,
+				const struct iio_backend_data_fmt *data)
+{
+	if (!data || data->type >= IIO_BACKEND_DATA_TYPE_MAX)
+		return -EINVAL;
+
+	return iio_backend_op_call(back, data_format_set, chan, data);
+}
+EXPORT_SYMBOL_NS_GPL(iio_backend_data_format_set, IIO_BACKEND);
+
+static void iio_backend_free_buffer(void *arg)
+{
+	struct iio_backend_buffer_pair *pair = arg;
+
+	iio_backend_void_op_call(pair->back, free_buffer, pair->buffer);
+}
+
+/**
+ * devm_iio_backend_request_buffer - Device managed buffer request
+ * @dev:	Consumer device for the backend
+ * @back:	Backend device
+ * @indio_dev:	IIO device
+ *
+ * Request an IIO buffer from the backend. The type of the buffer (typically
+ * INDIO_BUFFER_HARDWARE) is up to the backend to decide. This is because,
+ * normally, the backend dictates what kind of buffering we can get.
+ *
+ * The backend .free_buffer() hooks is automatically called on @dev detach.
+ *
+ * RETURNS:
+ * 0 on success, negative error number on failure.
+ */
+int devm_iio_backend_request_buffer(struct device *dev,
+				    struct iio_backend *back,
+				    struct iio_dev *indio_dev)
+{
+	struct iio_backend_buffer_pair *pair;
+	struct iio_buffer *buffer;
+
+	pair = devm_kzalloc(dev, sizeof(*pair), GFP_KERNEL);
+	if (!pair)
+		return -ENOMEM;
+
+	buffer = iio_backend_ptr_op_call(back, request_buffer, indio_dev);
+	if (IS_ERR(buffer))
+		return PTR_ERR(buffer);
+
+	/* weak reference should be all what we need */
+	pair->back = back;
+	pair->buffer = buffer;
+
+	return devm_add_action_or_reset(dev, iio_backend_free_buffer, pair);
+}
+EXPORT_SYMBOL_NS_GPL(devm_iio_backend_request_buffer, IIO_BACKEND);
+
+static void iio_backend_release(void *arg)
+{
+	struct iio_backend *back = arg;
+
+	module_put(back->owner);
+}
+
+static int __devm_iio_backend_get(struct device *dev, struct iio_backend *back)
+{
+	struct device_link *link;
+	int ret;
+
+	/*
+	 * Make sure the provider cannot be unloaded before the consumer module.
+	 * Note that device_links would still guarantee that nothing is
+	 * accessible (and breaks) but this makes it explicit that the consumer
+	 * module must be also unloaded.
+	 */
+	if (!try_module_get(back->owner))
+		return dev_err_probe(dev, -ENODEV,
+				     "Cannot get module reference\n");
+
+	ret = devm_add_action_or_reset(dev, iio_backend_release, back);
+	if (ret)
+		return ret;
+
+	link = device_link_add(dev, back->dev, DL_FLAG_AUTOREMOVE_CONSUMER);
+	if (!link)
+		return dev_err_probe(dev, -EINVAL,
+				     "Could not link to supplier(%s)\n",
+				     dev_name(back->dev));
+
+	dev_dbg(dev, "Found backend(%s) device\n", dev_name(back->dev));
+
+	return 0;
+}
+
+/**
+ * devm_iio_backend_get - Device managed backend device get
+ * @dev:	Consumer device for the backend
+ * @name:	Backend name
+ *
+ * Get's the backend associated with @dev.
+ *
+ * RETURNS:
+ * A backend pointer, negative error pointer otherwise.
+ */
+struct iio_backend *devm_iio_backend_get(struct device *dev, const char *name)
+{
+	struct fwnode_handle *fwnode;
+	struct iio_backend *back;
+	unsigned int index;
+	int ret;
+
+	if (name) {
+		ret = device_property_match_string(dev, "io-backend-names",
+						   name);
+		if (ret < 0)
+			return ERR_PTR(ret);
+		index = ret;
+	} else {
+		index = 0;
+	}
+
+	fwnode = fwnode_find_reference(dev_fwnode(dev), "io-backends", index);
+	if (IS_ERR(fwnode)) {
+		dev_err_probe(dev, PTR_ERR(fwnode),
+			      "Cannot get Firmware reference\n");
+		return ERR_CAST(fwnode);
+	}
+
+	guard(mutex)(&iio_back_lock);
+	list_for_each_entry(back, &iio_back_list, entry) {
+		if (!device_match_fwnode(back->dev, fwnode))
+			continue;
+
+		fwnode_handle_put(fwnode);
+		ret = __devm_iio_backend_get(dev, back);
+		if (ret)
+			return ERR_PTR(ret);
+
+		return back;
+	}
+
+	fwnode_handle_put(fwnode);
+	return ERR_PTR(-EPROBE_DEFER);
+}
+EXPORT_SYMBOL_NS_GPL(devm_iio_backend_get, IIO_BACKEND);
+
+/**
+ * __devm_iio_backend_get_from_fwnode_lookup - Device managed fwnode backend device get
+ * @dev:	Consumer device for the backend
+ * @fwnode:	Firmware node of the backend device
+ *
+ * Search the backend list for a device matching @fwnode.
+ * This API should not be used and it's only present for preventing the first
+ * user of this framework to break it's DT ABI.
+ *
+ * RETURNS:
+ * A backend pointer, negative error pointer otherwise.
+ */
+struct iio_backend *
+__devm_iio_backend_get_from_fwnode_lookup(struct device *dev,
+					  struct fwnode_handle *fwnode)
+{
+	struct iio_backend *back;
+	int ret;
+
+	guard(mutex)(&iio_back_lock);
+	list_for_each_entry(back, &iio_back_list, entry) {
+		if (!device_match_fwnode(back->dev, fwnode))
+			continue;
+
+		ret = __devm_iio_backend_get(dev, back);
+		if (ret)
+			return ERR_PTR(ret);
+
+		return back;
+	}
+
+	return ERR_PTR(-EPROBE_DEFER);
+}
+EXPORT_SYMBOL_NS_GPL(__devm_iio_backend_get_from_fwnode_lookup, IIO_BACKEND);
+
+/**
+ * iio_backend_get_priv - Get driver private data
+ * @back:	Backend device
+ */
+void *iio_backend_get_priv(const struct iio_backend *back)
+{
+	return back->priv;
+}
+EXPORT_SYMBOL_NS_GPL(iio_backend_get_priv, IIO_BACKEND);
+
+static void iio_backend_unregister(void *arg)
+{
+	struct iio_backend *back = arg;
+
+	guard(mutex)(&iio_back_lock);
+	list_del(&back->entry);
+}
+
+/**
+ * devm_iio_backend_register - Device managed backend device register
+ * @dev:	Backend device being registered
+ * @ops:	Backend ops
+ * @priv:	Device private data
+ *
+ * @ops is mandatory. Not providing it results in -EINVAL.
+ *
+ * RETURNS:
+ * 0 on success, negative error number on failure.
+ */
+int devm_iio_backend_register(struct device *dev,
+			      const struct iio_backend_ops *ops, void *priv)
+{
+	struct iio_backend *back;
+
+	if (!ops)
+		return dev_err_probe(dev, -EINVAL, "No backend ops given\n");
+
+	/*
+	 * Through device_links, we guarantee that a frontend device cannot be
+	 * bound/exist if the backend driver is not around. Hence, we can bind
+	 * the backend object lifetime with the device being passed since
+	 * removing it will tear the frontend/consumer down.
+	 */
+	back = devm_kzalloc(dev, sizeof(*back), GFP_KERNEL);
+	if (!back)
+		return -ENOMEM;
+
+	back->ops = ops;
+	back->owner = dev->driver->owner;
+	back->dev = dev;
+	back->priv = priv;
+	scoped_guard(mutex, &iio_back_lock)
+		list_add(&back->entry, &iio_back_list);
+
+	return devm_add_action_or_reset(dev, iio_backend_unregister, back);
+}
+EXPORT_SYMBOL_NS_GPL(devm_iio_backend_register, IIO_BACKEND);
+
+MODULE_AUTHOR("Nuno Sa <nuno.sa@analog.com>");
+MODULE_DESCRIPTION("Framework to handle complex IIO aggregate devices");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/iio/industrialio-core.c
+++ linux-qcom-6.8.0/drivers/iio/industrialio-core.c
@@ -759,9 +759,11 @@
 							INDIO_MAX_RAW_ELEMENTS,
 							vals, &val_len,
 							this_attr->address);
-	else
+	else if (indio_dev->info->read_raw)
 		ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
 				    &vals[0], &vals[1], this_attr->address);
+	else
+		return -EINVAL;
 
 	if (ret < 0)
 		return ret;
@@ -843,6 +845,9 @@
 	int length;
 	int type;
 
+	if (!indio_dev->info->read_avail)
+		return -EINVAL;
+
 	ret = indio_dev->info->read_avail(indio_dev, this_attr->c,
 					  &vals, &type, &length,
 					  this_attr->address);
@@ -1656,8 +1661,10 @@
 		return NULL;
 
 	indio_dev = &iio_dev_opaque->indio_dev;
-	indio_dev->priv = (char *)iio_dev_opaque +
-		ALIGN(sizeof(struct iio_dev_opaque), IIO_DMA_MINALIGN);
+
+	if (sizeof_priv)
+		indio_dev->priv = (char *)iio_dev_opaque +
+			ALIGN(sizeof(*iio_dev_opaque), IIO_DMA_MINALIGN);
 
 	indio_dev->dev.parent = parent;
 	indio_dev->dev.type = &iio_device_type;
--- linux-qcom-6.8.0.orig/drivers/iio/industrialio-event.c
+++ linux-qcom-6.8.0/drivers/iio/industrialio-event.c
@@ -285,6 +285,9 @@
 	if (ret < 0)
 		return ret;
 
+	if (!indio_dev->info->write_event_config)
+		return -EINVAL;
+
 	ret = indio_dev->info->write_event_config(indio_dev,
 		this_attr->c, iio_ev_attr_type(this_attr),
 		iio_ev_attr_dir(this_attr), val);
@@ -300,6 +303,9 @@
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int val;
 
+	if (!indio_dev->info->read_event_config)
+		return -EINVAL;
+
 	val = indio_dev->info->read_event_config(indio_dev,
 		this_attr->c, iio_ev_attr_type(this_attr),
 		iio_ev_attr_dir(this_attr));
@@ -318,6 +324,9 @@
 	int val, val2, val_arr[2];
 	int ret;
 
+	if (!indio_dev->info->read_event_value)
+		return -EINVAL;
+
 	ret = indio_dev->info->read_event_value(indio_dev,
 		this_attr->c, iio_ev_attr_type(this_attr),
 		iio_ev_attr_dir(this_attr), iio_ev_attr_info(this_attr),
--- linux-qcom-6.8.0.orig/drivers/iio/industrialio-gts-helper.c
+++ linux-qcom-6.8.0/drivers/iio/industrialio-gts-helper.c
@@ -34,24 +34,11 @@
 static int iio_gts_get_gain(const u64 max, const u64 scale)
 {
 	u64 full = max;
-	int tmp = 1;
 
 	if (scale > full || !scale)
 		return -EINVAL;
 
-	if (U64_MAX - full < scale) {
-		/* Risk of overflow */
-		if (full - scale < scale)
-			return 1;
-
-		full -= scale;
-		tmp++;
-	}
-
-	while (full > scale * (u64)tmp)
-		tmp++;
-
-	return tmp;
+	return div64_u64(full, scale);
 }
 
 /**
@@ -180,7 +167,7 @@
 
 static int gain_to_scaletables(struct iio_gts *gts, int **gains, int **scales)
 {
-	int ret, i, j, new_idx, time_idx;
+	int i, j, new_idx, time_idx, ret = 0;
 	int *all_gains;
 	size_t gain_bytes;
 
@@ -218,7 +205,7 @@
 	memcpy(all_gains, gains[time_idx], gain_bytes);
 	new_idx = gts->num_hwgain;
 
-	while (time_idx--) {
+	while (time_idx-- > 0) {
 		for (j = 0; j < gts->num_hwgain; j++) {
 			int candidate = gains[time_idx][j];
 			int chk;
@@ -320,13 +307,15 @@
 	if (ret)
 		goto err_free_out;
 
+	for (i = 0; i < gts->num_itime; i++)
+		kfree(per_time_gains[i]);
 	kfree(per_time_gains);
 	gts->per_time_avail_scale_tables = per_time_scales;
 
 	return 0;
 
 err_free_out:
-	for (i--; i; i--) {
+	for (i--; i >= 0; i--) {
 		kfree(per_time_scales[i]);
 		kfree(per_time_gains[i]);
 	}
@@ -375,17 +364,20 @@
 	for (i = gts->num_itime - 1; i >= 0; i--) {
 		int new = gts->itime_table[i].time_us;
 
-		if (times[idx] < new) {
+		if (idx == 0 || times[idx - 1] < new) {
 			times[idx++] = new;
 			continue;
 		}
 
-		for (j = 0; j <= idx; j++) {
+		for (j = 0; j < idx; j++) {
+			if (times[j] == new)
+				break;
 			if (times[j] > new) {
 				memmove(&times[j + 1], &times[j],
 					(idx - j) * sizeof(int));
 				times[j] = new;
 				idx++;
+				break;
 			}
 		}
 	}
--- linux-qcom-6.8.0.orig/drivers/iio/industrialio-trigger.c
+++ linux-qcom-6.8.0/drivers/iio/industrialio-trigger.c
@@ -322,7 +322,7 @@
 	 * this is the case if the IIO device and the trigger device share the
 	 * same parent device.
 	 */
-	if (iio_validate_own_trigger(pf->indio_dev, trig))
+	if (!iio_validate_own_trigger(pf->indio_dev, trig))
 		trig->attached_own_device = true;
 
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/iio/inkern.c
+++ linux-qcom-6.8.0/drivers/iio/inkern.c
@@ -277,7 +277,7 @@
 			return ERR_PTR(-ENODEV);
 		}
 
-		chan = __fwnode_iio_channel_get_by_name(fwnode, name);
+		chan = __fwnode_iio_channel_get_by_name(parent, name);
 		if (!IS_ERR(chan) || PTR_ERR(chan) != -ENODEV) {
 			fwnode_handle_put(parent);
  			return chan;
@@ -514,7 +514,7 @@
 	return chans;
 
 error_free_chans:
-	for (i = 0; i < nummaps; i++)
+	for (i = 0; i < mapind; i++)
 		iio_device_put(chans[i].indio_dev);
 	kfree(chans);
 error_ret:
@@ -562,6 +562,7 @@
 static int iio_channel_read(struct iio_channel *chan, int *val, int *val2,
 			    enum iio_chan_info_enum info)
 {
+	const struct iio_info *iio_info = chan->indio_dev->info;
 	int unused;
 	int vals[INDIO_MAX_RAW_ELEMENTS];
 	int ret;
@@ -573,15 +574,18 @@
 	if (!iio_channel_has_info(chan->channel, info))
 		return -EINVAL;
 
-	if (chan->indio_dev->info->read_raw_multi) {
-		ret = chan->indio_dev->info->read_raw_multi(chan->indio_dev,
-					chan->channel, INDIO_MAX_RAW_ELEMENTS,
-					vals, &val_len, info);
+	if (iio_info->read_raw_multi) {
+		ret = iio_info->read_raw_multi(chan->indio_dev,
+					       chan->channel,
+					       INDIO_MAX_RAW_ELEMENTS,
+					       vals, &val_len, info);
 		*val = vals[0];
 		*val2 = vals[1];
+	} else if (iio_info->read_raw) {
+		ret = iio_info->read_raw(chan->indio_dev,
+					 chan->channel, val, val2, info);
 	} else {
-		ret = chan->indio_dev->info->read_raw(chan->indio_dev,
-					chan->channel, val, val2, info);
+		return -EINVAL;
 	}
 
 	return ret;
@@ -676,17 +680,17 @@
 		break;
 	case IIO_VAL_INT_PLUS_MICRO:
 		if (scale_val2 < 0)
-			*processed = -raw64 * scale_val;
+			*processed = -raw64 * scale_val * scale;
 		else
-			*processed = raw64 * scale_val;
+			*processed = raw64 * scale_val * scale;
 		*processed += div_s64(raw64 * (s64)scale_val2 * scale,
 				      1000000LL);
 		break;
 	case IIO_VAL_INT_PLUS_NANO:
 		if (scale_val2 < 0)
-			*processed = -raw64 * scale_val;
+			*processed = -raw64 * scale_val * scale;
 		else
-			*processed = raw64 * scale_val;
+			*processed = raw64 * scale_val * scale;
 		*processed += div_s64(raw64 * (s64)scale_val2 * scale,
 				      1000000000LL);
 		break;
@@ -801,11 +805,15 @@
 				  const int **vals, int *type, int *length,
 				  enum iio_chan_info_enum info)
 {
+	const struct iio_info *iio_info = chan->indio_dev->info;
+
 	if (!iio_channel_has_available(chan->channel, info))
 		return -EINVAL;
 
-	return chan->indio_dev->info->read_avail(chan->indio_dev, chan->channel,
-						 vals, type, length, info);
+	if (iio_info->read_avail)
+		return iio_info->read_avail(chan->indio_dev, chan->channel,
+					    vals, type, length, info);
+	return -EINVAL;
 }
 
 int iio_read_avail_channel_attribute(struct iio_channel *chan,
@@ -995,8 +1003,12 @@
 static int iio_channel_write(struct iio_channel *chan, int val, int val2,
 			     enum iio_chan_info_enum info)
 {
-	return chan->indio_dev->info->write_raw(chan->indio_dev,
-						chan->channel, val, val2, info);
+	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);
+	return -EINVAL;
 }
 
 int iio_write_channel_attribute(struct iio_channel *chan, int val, int val2,
--- linux-qcom-6.8.0.orig/drivers/iio/light/Kconfig
+++ linux-qcom-6.8.0/drivers/iio/light/Kconfig
@@ -309,6 +309,8 @@
 	depends on I2C
 	select REGMAP_I2C
 	select IIO_GTS_HELPER
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	help
 	  Enable support for the ROHM BU27008 color sensor.
 	  The ROHM BU27008 is a sensor with 5 photodiodes (red, green,
--- linux-qcom-6.8.0.orig/drivers/iio/light/al3010.c
+++ linux-qcom-6.8.0/drivers/iio/light/al3010.c
@@ -87,7 +87,12 @@
 	int ret;
 
 	ret = al3010_set_pwr(data->client, true);
+	if (ret < 0)
+		return ret;
 
+	ret = devm_add_action_or_reset(&data->client->dev,
+				       al3010_set_pwr_off,
+				       data);
 	if (ret < 0)
 		return ret;
 
@@ -190,12 +195,6 @@
 		return ret;
 	}
 
-	ret = devm_add_action_or_reset(&client->dev,
-					al3010_set_pwr_off,
-					data);
-	if (ret < 0)
-		return ret;
-
 	return devm_iio_device_register(&client->dev, indio_dev);
 }
 
--- linux-qcom-6.8.0.orig/drivers/iio/light/as73211.c
+++ linux-qcom-6.8.0/drivers/iio/light/as73211.c
@@ -154,6 +154,12 @@
 	BIT(AS73211_SCAN_INDEX_TEMP) | \
 	AS73211_SCAN_MASK_COLOR)
 
+static const unsigned long as73211_scan_masks[] = {
+	AS73211_SCAN_MASK_COLOR,
+	AS73211_SCAN_MASK_ALL,
+	0
+};
+
 static const struct iio_chan_spec as73211_channels[] = {
 	{
 		.type = IIO_TEMP,
@@ -602,9 +608,12 @@
 
 		/* AS73211 starts reading at address 2 */
 		ret = i2c_master_recv(data->client,
-				(char *)&scan.chan[1], 3 * sizeof(scan.chan[1]));
+				(char *)&scan.chan[0], 3 * sizeof(scan.chan[0]));
 		if (ret < 0)
 			goto done;
+
+		/* Avoid pushing uninitialized data */
+		scan.chan[3] = 0;
 	}
 
 	if (data_result) {
@@ -612,9 +621,15 @@
 		 * Saturate all channels (in case of overflows). Temperature channel
 		 * is not affected by overflows.
 		 */
-		scan.chan[1] = cpu_to_le16(U16_MAX);
-		scan.chan[2] = cpu_to_le16(U16_MAX);
-		scan.chan[3] = cpu_to_le16(U16_MAX);
+		if (*indio_dev->active_scan_mask == AS73211_SCAN_MASK_ALL) {
+			scan.chan[1] = cpu_to_le16(U16_MAX);
+			scan.chan[2] = cpu_to_le16(U16_MAX);
+			scan.chan[3] = cpu_to_le16(U16_MAX);
+		} else {
+			scan.chan[0] = cpu_to_le16(U16_MAX);
+			scan.chan[1] = cpu_to_le16(U16_MAX);
+			scan.chan[2] = cpu_to_le16(U16_MAX);
+		}
 	}
 
 	iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev));
@@ -684,6 +699,7 @@
 	indio_dev->channels = as73211_channels;
 	indio_dev->num_channels = ARRAY_SIZE(as73211_channels);
 	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->available_scan_masks = as73211_scan_masks;
 
 	ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR);
 	if (ret < 0)
--- linux-qcom-6.8.0.orig/drivers/iio/light/ltr501.c
+++ linux-qcom-6.8.0/drivers/iio/light/ltr501.c
@@ -1612,6 +1612,8 @@
 	{ "LTER0501", ltr501 },
 	{ "LTER0559", ltr559 },
 	{ "LTER0301", ltr301 },
+	/* https://www.catalog.update.microsoft.com/Search.aspx?q=lter0303 */
+	{ "LTER0303", ltr303 },
 	{ },
 };
 MODULE_DEVICE_TABLE(acpi, ltr_acpi_match);
--- linux-qcom-6.8.0.orig/drivers/iio/light/opt3001.c
+++ linux-qcom-6.8.0/drivers/iio/light/opt3001.c
@@ -139,6 +139,10 @@
 		.val2 = 400000,
 	},
 	{
+		.val = 41932,
+		.val2 = 800000,
+	},
+	{
 		.val = 83865,
 		.val2 = 600000,
 	},
--- linux-qcom-6.8.0.orig/drivers/iio/light/vcnl4035.c
+++ linux-qcom-6.8.0/drivers/iio/light/vcnl4035.c
@@ -105,7 +105,7 @@
 	struct iio_dev *indio_dev = pf->indio_dev;
 	struct vcnl4035_data *data = iio_priv(indio_dev);
 	/* Ensure naturally aligned timestamp */
-	u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)]  __aligned(8);
+	u8 buffer[ALIGN(sizeof(u16), sizeof(s64)) + sizeof(s64)]  __aligned(8) = { };
 	int ret;
 
 	ret = regmap_read(data->regmap, VCNL4035_ALS_DATA, (int *)buffer);
--- linux-qcom-6.8.0.orig/drivers/iio/light/veml6030.c
+++ linux-qcom-6.8.0/drivers/iio/light/veml6030.c
@@ -99,9 +99,8 @@
 static ssize_t in_illuminance_period_available_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
+	struct veml6030_data *data = iio_priv(dev_to_iio_dev(dev));
 	int ret, reg, x;
-	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
-	struct veml6030_data *data = iio_priv(indio_dev);
 
 	ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg);
 	if (ret) {
@@ -523,7 +522,7 @@
 			}
 			if (mask == IIO_CHAN_INFO_PROCESSED) {
 				*val = (reg * data->cur_resolution) / 10000;
-				*val2 = (reg * data->cur_resolution) % 10000;
+				*val2 = (reg * data->cur_resolution) % 10000 * 100;
 				return IIO_VAL_INT_PLUS_MICRO;
 			}
 			*val = reg;
@@ -780,7 +779,7 @@
 
 	/* Cache currently active measurement parameters */
 	data->cur_gain = 3;
-	data->cur_resolution = 4608;
+	data->cur_resolution = 5376;
 	data->cur_integration_time = 3;
 
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/iio/magnetometer/ak8975.c
+++ linux-qcom-6.8.0/drivers/iio/magnetometer/ak8975.c
@@ -692,22 +692,8 @@
 	if (ret < 0)
 		return ret;
 
-	/* This will be executed only for non-interrupt based waiting case */
-	if (ret & data->def->ctrl_masks[ST1_DRDY]) {
-		ret = i2c_smbus_read_byte_data(client,
-					       data->def->ctrl_regs[ST2]);
-		if (ret < 0) {
-			dev_err(&client->dev, "Error in reading ST2\n");
-			return ret;
-		}
-		if (ret & (data->def->ctrl_masks[ST2_DERR] |
-			   data->def->ctrl_masks[ST2_HOFL])) {
-			dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
-			return -EINVAL;
-		}
-	}
-
-	return 0;
+	/* Return with zero if the data is ready. */
+	return !data->def->ctrl_regs[ST1_DRDY];
 }
 
 /* Retrieve raw flux value for one of the x, y, or z axis.  */
@@ -734,6 +720,20 @@
 	if (ret < 0)
 		goto exit;
 
+	/* Read out ST2 for release lock on measurment data. */
+	ret = i2c_smbus_read_byte_data(client, data->def->ctrl_regs[ST2]);
+	if (ret < 0) {
+		dev_err(&client->dev, "Error in reading ST2\n");
+		goto exit;
+	}
+
+	if (ret & (data->def->ctrl_masks[ST2_DERR] |
+		   data->def->ctrl_masks[ST2_HOFL])) {
+		dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
+		ret = -EINVAL;
+		goto exit;
+	}
+
 	mutex_unlock(&data->lock);
 
 	pm_runtime_mark_last_busy(&data->client->dev);
@@ -1081,7 +1081,6 @@
 	{ .compatible = "asahi-kasei,ak09912", .data = &ak_def_array[AK09912] },
 	{ .compatible = "ak09912", .data = &ak_def_array[AK09912] },
 	{ .compatible = "asahi-kasei,ak09916", .data = &ak_def_array[AK09916] },
-	{ .compatible = "ak09916", .data = &ak_def_array[AK09916] },
 	{}
 };
 MODULE_DEVICE_TABLE(of, ak8975_of_match);
--- linux-qcom-6.8.0.orig/drivers/iio/magnetometer/yamaha-yas530.c
+++ linux-qcom-6.8.0/drivers/iio/magnetometer/yamaha-yas530.c
@@ -372,6 +372,7 @@
 	u8 data[8];
 	u16 xy1y2[3];
 	s32 h[3], s[3];
+	int half_range = BIT(13);
 	int i, ret;
 
 	mutex_lock(&yas5xx->lock);
@@ -406,13 +407,13 @@
 	/* The second version of YAS537 needs to include calibration coefficients */
 	if (yas5xx->version == YAS537_VERSION_1) {
 		for (i = 0; i < 3; i++)
-			s[i] = xy1y2[i] - BIT(13);
-		h[0] = (c->k *   (128 * s[0] + c->a2 * s[1] + c->a3 * s[2])) / BIT(13);
-		h[1] = (c->k * (c->a4 * s[0] + c->a5 * s[1] + c->a6 * s[2])) / BIT(13);
-		h[2] = (c->k * (c->a7 * s[0] + c->a8 * s[1] + c->a9 * s[2])) / BIT(13);
+			s[i] = xy1y2[i] - half_range;
+		h[0] = (c->k *   (128 * s[0] + c->a2 * s[1] + c->a3 * s[2])) / half_range;
+		h[1] = (c->k * (c->a4 * s[0] + c->a5 * s[1] + c->a6 * s[2])) / half_range;
+		h[2] = (c->k * (c->a7 * s[0] + c->a8 * s[1] + c->a9 * s[2])) / half_range;
 		for (i = 0; i < 3; i++) {
-			clamp_val(h[i], -BIT(13), BIT(13) - 1);
-			xy1y2[i] = h[i] + BIT(13);
+			h[i] = clamp(h[i], -half_range, half_range - 1);
+			xy1y2[i] = h[i] + half_range;
 		}
 	}
 
--- linux-qcom-6.8.0.orig/drivers/iio/pressure/Kconfig
+++ linux-qcom-6.8.0/drivers/iio/pressure/Kconfig
@@ -19,6 +19,9 @@
 config ROHM_BM1390
 	tristate "ROHM BM1390GLV-Z pressure sensor driver"
 	depends on I2C
+	select REGMAP_I2C
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	help
 	  Support for the ROHM BM1390 pressure sensor. The BM1390GLV-Z
 	  can measure pressures ranging from 300 hPa to 1300 hPa with
--- linux-qcom-6.8.0.orig/drivers/iio/pressure/bmp280-core.c
+++ linux-qcom-6.8.0/drivers/iio/pressure/bmp280-core.c
@@ -52,7 +52,6 @@
  */
 enum { AC1, AC2, AC3, AC4, AC5, AC6, B1, B2, MB, MC, MD };
 
-
 enum bmp380_odr {
 	BMP380_ODR_200HZ,
 	BMP380_ODR_100HZ,
@@ -181,18 +180,19 @@
 	struct bmp280_calib *calib = &data->calib.bmp280;
 	int ret;
 
-
 	/* Read temperature and pressure calibration values. */
 	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_TEMP_START,
-			       data->bmp280_cal_buf, sizeof(data->bmp280_cal_buf));
+			       data->bmp280_cal_buf,
+			       sizeof(data->bmp280_cal_buf));
 	if (ret < 0) {
 		dev_err(data->dev,
-			"failed to read temperature and pressure calibration parameters\n");
+			"failed to read calibration parameters\n");
 		return ret;
 	}
 
-	/* Toss the temperature and pressure calibration data into the entropy pool */
-	add_device_randomness(data->bmp280_cal_buf, sizeof(data->bmp280_cal_buf));
+	/* Toss calibration data into the entropy pool */
+	add_device_randomness(data->bmp280_cal_buf,
+			      sizeof(data->bmp280_cal_buf));
 
 	/* Parse temperature calibration values. */
 	calib->T1 = le16_to_cpu(data->bmp280_cal_buf[T1]);
@@ -223,7 +223,7 @@
 	/* Load shared calibration params with bmp280 first */
 	ret = bmp280_read_calib(data);
 	if  (ret < 0) {
-		dev_err(dev, "failed to read common bmp280 calibration parameters\n");
+		dev_err(dev, "failed to read calibration parameters\n");
 		return ret;
 	}
 
@@ -235,14 +235,14 @@
 	 * Humidity data is only available on BME280.
 	 */
 
-	ret = regmap_read(data->regmap, BMP280_REG_COMP_H1, &tmp);
+	ret = regmap_read(data->regmap, BME280_REG_COMP_H1, &tmp);
 	if (ret < 0) {
 		dev_err(dev, "failed to read H1 comp value\n");
 		return ret;
 	}
 	calib->H1 = tmp;
 
-	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H2,
+	ret = regmap_bulk_read(data->regmap, BME280_REG_COMP_H2,
 			       &data->le16, sizeof(data->le16));
 	if (ret < 0) {
 		dev_err(dev, "failed to read H2 comp value\n");
@@ -250,14 +250,14 @@
 	}
 	calib->H2 = sign_extend32(le16_to_cpu(data->le16), 15);
 
-	ret = regmap_read(data->regmap, BMP280_REG_COMP_H3, &tmp);
+	ret = regmap_read(data->regmap, BME280_REG_COMP_H3, &tmp);
 	if (ret < 0) {
 		dev_err(dev, "failed to read H3 comp value\n");
 		return ret;
 	}
 	calib->H3 = tmp;
 
-	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H4,
+	ret = regmap_bulk_read(data->regmap, BME280_REG_COMP_H4,
 			       &data->be16, sizeof(data->be16));
 	if (ret < 0) {
 		dev_err(dev, "failed to read H4 comp value\n");
@@ -266,15 +266,15 @@
 	calib->H4 = sign_extend32(((be16_to_cpu(data->be16) >> 4) & 0xff0) |
 				  (be16_to_cpu(data->be16) & 0xf), 11);
 
-	ret = regmap_bulk_read(data->regmap, BMP280_REG_COMP_H5,
+	ret = regmap_bulk_read(data->regmap, BME280_REG_COMP_H5,
 			       &data->le16, sizeof(data->le16));
 	if (ret < 0) {
 		dev_err(dev, "failed to read H5 comp value\n");
 		return ret;
 	}
-	calib->H5 = sign_extend32(FIELD_GET(BMP280_COMP_H5_MASK, le16_to_cpu(data->le16)), 11);
+	calib->H5 = sign_extend32(FIELD_GET(BME280_COMP_H5_MASK, le16_to_cpu(data->le16)), 11);
 
-	ret = regmap_read(data->regmap, BMP280_REG_COMP_H6, &tmp);
+	ret = regmap_read(data->regmap, BME280_REG_COMP_H6, &tmp);
 	if (ret < 0) {
 		dev_err(dev, "failed to read H6 comp value\n");
 		return ret;
@@ -283,13 +283,14 @@
 
 	return 0;
 }
+
 /*
  * Returns humidity in percent, resolution is 0.01 percent. Output value of
  * "47445" represents 47445/1024 = 46.333 %RH.
  *
  * Taken from BME280 datasheet, Section 4.2.3, "Compensation formula".
  */
-static u32 bmp280_compensate_humidity(struct bmp280_data *data,
+static u32 bme280_compensate_humidity(struct bmp280_data *data,
 				      s32 adc_humidity)
 {
 	struct bmp280_calib *calib = &data->calib.bmp280;
@@ -305,7 +306,7 @@
 	var = clamp_val(var, 0, 419430400);
 
 	return var >> 12;
-};
+}
 
 /*
  * Returns temperature in DegC, resolution is 0.01 DegC.  Output value of
@@ -429,7 +430,7 @@
 	return IIO_VAL_FRACTIONAL;
 }
 
-static int bmp280_read_humid(struct bmp280_data *data, int *val, int *val2)
+static int bme280_read_humid(struct bmp280_data *data, int *val, int *val2)
 {
 	u32 comp_humidity;
 	s32 adc_humidity;
@@ -440,7 +441,7 @@
 	if (ret < 0)
 		return ret;
 
-	ret = regmap_bulk_read(data->regmap, BMP280_REG_HUMIDITY_MSB,
+	ret = regmap_bulk_read(data->regmap, BME280_REG_HUMIDITY_MSB,
 			       &data->be16, sizeof(data->be16));
 	if (ret < 0) {
 		dev_err(data->dev, "failed to read humidity\n");
@@ -453,7 +454,7 @@
 		dev_err(data->dev, "reading humidity skipped\n");
 		return -EIO;
 	}
-	comp_humidity = bmp280_compensate_humidity(data, adc_humidity);
+	comp_humidity = bme280_compensate_humidity(data, adc_humidity);
 
 	*val = comp_humidity * 1000 / 1024;
 
@@ -537,8 +538,8 @@
 	return ret;
 }
 
-static int bmp280_write_oversampling_ratio_humid(struct bmp280_data *data,
-					       int val)
+static int bme280_write_oversampling_ratio_humid(struct bmp280_data *data,
+						 int val)
 {
 	const int *avail = data->chip_info->oversampling_humid_avail;
 	const int n = data->chip_info->num_oversampling_humid_avail;
@@ -563,7 +564,7 @@
 }
 
 static int bmp280_write_oversampling_ratio_temp(struct bmp280_data *data,
-					       int val)
+						int val)
 {
 	const int *avail = data->chip_info->oversampling_temp_avail;
 	const int n = data->chip_info->num_oversampling_temp_avail;
@@ -588,7 +589,7 @@
 }
 
 static int bmp280_write_oversampling_ratio_press(struct bmp280_data *data,
-					       int val)
+						 int val)
 {
 	const int *avail = data->chip_info->oversampling_press_avail;
 	const int n = data->chip_info->num_oversampling_press_avail;
@@ -681,7 +682,7 @@
 		mutex_lock(&data->lock);
 		switch (chan->type) {
 		case IIO_HUMIDITYRELATIVE:
-			ret = bmp280_write_oversampling_ratio_humid(data, val);
+			ret = bme280_write_oversampling_ratio_humid(data, val);
 			break;
 		case IIO_PRESSURE:
 			ret = bmp280_write_oversampling_ratio_press(data, val);
@@ -772,13 +773,12 @@
 	int ret;
 
 	ret = regmap_write_bits(data->regmap, BMP280_REG_CTRL_MEAS,
-				 BMP280_OSRS_TEMP_MASK |
-				 BMP280_OSRS_PRESS_MASK |
-				 BMP280_MODE_MASK,
-				 osrs | BMP280_MODE_NORMAL);
+				BMP280_OSRS_TEMP_MASK |
+				BMP280_OSRS_PRESS_MASK |
+				BMP280_MODE_MASK,
+				osrs | BMP280_MODE_NORMAL);
 	if (ret < 0) {
-		dev_err(data->dev,
-			"failed to write ctrl_meas register\n");
+		dev_err(data->dev, "failed to write ctrl_meas register\n");
 		return ret;
 	}
 
@@ -786,8 +786,7 @@
 				 BMP280_FILTER_MASK,
 				 BMP280_FILTER_4X);
 	if (ret < 0) {
-		dev_err(data->dev,
-			"failed to write config register\n");
+		dev_err(data->dev, "failed to write config register\n");
 		return ret;
 	}
 
@@ -833,16 +832,15 @@
 
 static int bme280_chip_config(struct bmp280_data *data)
 {
-	u8 osrs = FIELD_PREP(BMP280_OSRS_HUMIDITY_MASK, data->oversampling_humid + 1);
+	u8 osrs = FIELD_PREP(BME280_OSRS_HUMIDITY_MASK, data->oversampling_humid + 1);
 	int ret;
 
 	/*
 	 * Oversampling of humidity must be set before oversampling of
 	 * temperature/pressure is set to become effective.
 	 */
-	ret = regmap_update_bits(data->regmap, BMP280_REG_CTRL_HUMIDITY,
-				  BMP280_OSRS_HUMIDITY_MASK, osrs);
-
+	ret = regmap_update_bits(data->regmap, BME280_REG_CTRL_HUMIDITY,
+				 BME280_OSRS_HUMIDITY_MASK, osrs);
 	if (ret < 0)
 		return ret;
 
@@ -855,7 +853,7 @@
 	.id_reg = BMP280_REG_ID,
 	.chip_id = bme280_chip_ids,
 	.num_chip_id = ARRAY_SIZE(bme280_chip_ids),
-	.regmap_config = &bmp280_regmap_config,
+	.regmap_config = &bme280_regmap_config,
 	.start_up_time = 2000,
 	.channels = bmp280_channels,
 	.num_channels = 3,
@@ -870,12 +868,12 @@
 
 	.oversampling_humid_avail = bmp280_oversampling_avail,
 	.num_oversampling_humid_avail = ARRAY_SIZE(bmp280_oversampling_avail),
-	.oversampling_humid_default = BMP280_OSRS_HUMIDITY_16X - 1,
+	.oversampling_humid_default = BME280_OSRS_HUMIDITY_16X - 1,
 
 	.chip_config = bme280_chip_config,
 	.read_temp = bmp280_read_temp,
 	.read_press = bmp280_read_press,
-	.read_humid = bmp280_read_humid,
+	.read_humid = bme280_read_humid,
 	.read_calib = bme280_read_calib,
 };
 EXPORT_SYMBOL_NS(bme280_chip_info, IIO_BMP280);
@@ -926,8 +924,8 @@
 }
 
 /*
- * Returns temperature in Celsius degrees, resolution is 0.01º C. Output value of
- * "5123" equals 51.2º C. t_fine carries fine temperature as global value.
+ * Returns temperature in Celsius degrees, resolution is 0.01º C. Output value
+ * of "5123" equals 51.2º C. t_fine carries fine temperature as global value.
  *
  * Taken from datasheet, Section Appendix 9, "Compensation formula" and repo
  * https://github.com/BoschSensortec/BMP3-Sensor-API.
@@ -1069,7 +1067,8 @@
 
 	/* Read temperature and pressure calibration data */
 	ret = regmap_bulk_read(data->regmap, BMP380_REG_CALIB_TEMP_START,
-			       data->bmp380_cal_buf, sizeof(data->bmp380_cal_buf));
+			       data->bmp380_cal_buf,
+			       sizeof(data->bmp380_cal_buf));
 	if (ret) {
 		dev_err(data->dev,
 			"failed to read temperature calibration parameters\n");
@@ -1077,7 +1076,8 @@
 	}
 
 	/* Toss the temperature calibration data into the entropy pool */
-	add_device_randomness(data->bmp380_cal_buf, sizeof(data->bmp380_cal_buf));
+	add_device_randomness(data->bmp380_cal_buf,
+			      sizeof(data->bmp380_cal_buf));
 
 	/* Parse calibration values */
 	calib->T1 = get_unaligned_le16(&data->bmp380_cal_buf[BMP380_T1]);
@@ -1159,7 +1159,8 @@
 
 	/* Configure output data rate */
 	ret = regmap_update_bits_check(data->regmap, BMP380_REG_ODR,
-				       BMP380_ODRS_MASK, data->sampling_freq, &aux);
+				       BMP380_ODRS_MASK, data->sampling_freq,
+				       &aux);
 	if (ret) {
 		dev_err(data->dev, "failed to write ODR selection register\n");
 		return ret;
@@ -1178,12 +1179,13 @@
 
 	if (change) {
 		/*
-		 * The configurations errors are detected on the fly during a measurement
-		 * cycle. If the sampling frequency is too low, it's faster to reset
-		 * the measurement loop than wait until the next measurement is due.
+		 * The configurations errors are detected on the fly during a
+		 * measurement cycle. If the sampling frequency is too low, it's
+		 * faster to reset the measurement loop than wait until the next
+		 * measurement is due.
 		 *
-		 * Resets sensor measurement loop toggling between sleep and normal
-		 * operating modes.
+		 * Resets sensor measurement loop toggling between sleep and
+		 * normal operating modes.
 		 */
 		ret = regmap_write_bits(data->regmap, BMP380_REG_POWER_CONTROL,
 					BMP380_MODE_MASK,
@@ -1201,22 +1203,22 @@
 			return ret;
 		}
 		/*
-		 * Waits for measurement before checking configuration error flag.
-		 * Selected longest measure time indicated in section 3.9.1
-		 * in the datasheet.
+		 * Waits for measurement before checking configuration error
+		 * flag. Selected longest measurement time, calculated from
+		 * formula in datasheet section 3.9.2 with an offset of ~+15%
+		 * as it seen as well in table 3.9.1.
 		 */
-		msleep(80);
+		msleep(150);
 
 		/* Check config error flag */
 		ret = regmap_read(data->regmap, BMP380_REG_ERROR, &tmp);
 		if (ret) {
-			dev_err(data->dev,
-				"failed to read error register\n");
+			dev_err(data->dev, "failed to read error register\n");
 			return ret;
 		}
 		if (tmp & BMP380_ERR_CONF_MASK) {
 			dev_warn(data->dev,
-				"sensor flagged configuration as incompatible\n");
+				 "sensor flagged configuration as incompatible\n");
 			return -EINVAL;
 		}
 	}
@@ -1233,6 +1235,7 @@
 	.chip_id = bmp380_chip_ids,
 	.num_chip_id = ARRAY_SIZE(bmp380_chip_ids),
 	.regmap_config = &bmp380_regmap_config,
+	.spi_read_extra_byte = true,
 	.start_up_time = 2000,
 	.channels = bmp380_channels,
 	.num_channels = 2,
@@ -1316,9 +1319,11 @@
 	}
 
 	/* Start NVM operation sequence */
-	ret = regmap_write(data->regmap, BMP580_REG_CMD, BMP580_CMD_NVM_OP_SEQ_0);
+	ret = regmap_write(data->regmap, BMP580_REG_CMD,
+			   BMP580_CMD_NVM_OP_SEQ_0);
 	if (ret) {
-		dev_err(data->dev, "failed to send nvm operation's first sequence\n");
+		dev_err(data->dev,
+			"failed to send nvm operation's first sequence\n");
 		return ret;
 	}
 	if (is_write) {
@@ -1326,7 +1331,8 @@
 		ret = regmap_write(data->regmap, BMP580_REG_CMD,
 				   BMP580_CMD_NVM_WRITE_SEQ_1);
 		if (ret) {
-			dev_err(data->dev, "failed to send nvm write sequence\n");
+			dev_err(data->dev,
+				"failed to send nvm write sequence\n");
 			return ret;
 		}
 		/* Datasheet says on 4.8.1.2 it takes approximately 10ms */
@@ -1337,7 +1343,8 @@
 		ret = regmap_write(data->regmap, BMP580_REG_CMD,
 				   BMP580_CMD_NVM_READ_SEQ_1);
 		if (ret) {
-			dev_err(data->dev, "failed to send nvm read sequence\n");
+			dev_err(data->dev,
+				"failed to send nvm read sequence\n");
 			return ret;
 		}
 		/* Datasheet says on 4.8.1.1 it takes approximately 200us */
@@ -1393,12 +1400,12 @@
 
 	/*
 	 * Temperature is returned in Celsius degrees in fractional
-	 * form down 2^16. We rescale by x1000 to return milli Celsius
-	 * to respect IIO ABI.
+	 * form down 2^16. We rescale by x1000 to return millidegrees
+	 * Celsius to respect IIO ABI.
 	 */
-	*val = raw_temp * 1000;
-	*val2 = 16;
-	return IIO_VAL_FRACTIONAL_LOG2;
+	raw_temp = sign_extend32(raw_temp, 23);
+	*val = ((s64)raw_temp * 1000) / (1 << 16);
+	return IIO_VAL_INT;
 }
 
 static int bmp580_read_press(struct bmp280_data *data, int *val, int *val2)
@@ -1500,8 +1507,8 @@
 		if (ret)
 			goto exit;
 
-		ret = regmap_bulk_read(data->regmap, BMP580_REG_NVM_DATA_LSB, &data->le16,
-				       sizeof(data->le16));
+		ret = regmap_bulk_read(data->regmap, BMP580_REG_NVM_DATA_LSB,
+				       &data->le16, sizeof(data->le16));
 		if (ret) {
 			dev_err(data->dev, "error reading nvm data regs\n");
 			goto exit;
@@ -1545,7 +1552,8 @@
 	while (bytes >= sizeof(*buf)) {
 		addr = bmp580_nvmem_addrs[offset / sizeof(*buf)];
 
-		ret = regmap_write(data->regmap, BMP580_REG_NVM_ADDR, BMP580_NVM_PROG_EN |
+		ret = regmap_write(data->regmap, BMP580_REG_NVM_ADDR,
+				   BMP580_NVM_PROG_EN |
 				   FIELD_PREP(BMP580_NVM_ROW_ADDR_MASK, addr));
 		if (ret) {
 			dev_err(data->dev, "error writing nvm address\n");
@@ -1553,8 +1561,8 @@
 		}
 		data->le16 = cpu_to_le16(*buf++);
 
-		ret = regmap_bulk_write(data->regmap, BMP580_REG_NVM_DATA_LSB, &data->le16,
-					sizeof(data->le16));
+		ret = regmap_bulk_write(data->regmap, BMP580_REG_NVM_DATA_LSB,
+					&data->le16, sizeof(data->le16));
 		if (ret) {
 			dev_err(data->dev, "error writing LSB NVM data regs\n");
 			goto exit;
@@ -1661,7 +1669,8 @@
 		  BMP580_OSR_PRESS_EN;
 
 	ret = regmap_update_bits_check(data->regmap, BMP580_REG_OSR_CONFIG,
-				       BMP580_OSR_TEMP_MASK | BMP580_OSR_PRESS_MASK |
+				       BMP580_OSR_TEMP_MASK |
+				       BMP580_OSR_PRESS_MASK |
 				       BMP580_OSR_PRESS_EN,
 				       reg_val, &aux);
 	if (ret) {
@@ -1712,7 +1721,8 @@
 		 */
 		ret = regmap_read(data->regmap, BMP580_REG_EFF_OSR, &tmp);
 		if (ret) {
-			dev_err(data->dev, "error reading effective OSR register\n");
+			dev_err(data->dev,
+				"error reading effective OSR register\n");
 			return ret;
 		}
 		if (!(tmp & BMP580_EFF_OSR_VALID_ODR)) {
@@ -1847,7 +1857,8 @@
 	}
 
 	/* Toss the calibration data into the entropy pool */
-	add_device_randomness(data->bmp180_cal_buf, sizeof(data->bmp180_cal_buf));
+	add_device_randomness(data->bmp180_cal_buf,
+			      sizeof(data->bmp180_cal_buf));
 
 	calib->AC1 = be16_to_cpu(data->bmp180_cal_buf[AC1]);
 	calib->AC2 = be16_to_cpu(data->bmp180_cal_buf[AC2]);
@@ -1962,8 +1973,7 @@
 	return p + ((x1 + x2 + 3791) >> 4);
 }
 
-static int bmp180_read_press(struct bmp280_data *data,
-			     int *val, int *val2)
+static int bmp180_read_press(struct bmp280_data *data, int *val, int *val2)
 {
 	u32 comp_press;
 	s32 adc_press;
@@ -2240,6 +2250,7 @@
 	ret = regulator_bulk_enable(BMP280_NUM_SUPPLIES, data->supplies);
 	if (ret)
 		return ret;
+
 	usleep_range(data->start_up_time, data->start_up_time + 100);
 	return data->chip_info->chip_config(data);
 }
--- linux-qcom-6.8.0.orig/drivers/iio/pressure/bmp280-regmap.c
+++ linux-qcom-6.8.0/drivers/iio/pressure/bmp280-regmap.c
@@ -41,11 +41,23 @@
 };
 EXPORT_SYMBOL_NS(bmp180_regmap_config, IIO_BMP280);
 
+static bool bme280_is_writeable_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case BMP280_REG_CONFIG:
+	case BME280_REG_CTRL_HUMIDITY:
+	case BMP280_REG_CTRL_MEAS:
+	case BMP280_REG_RESET:
+		return true;
+	default:
+		return false;
+	}
+}
+
 static bool bmp280_is_writeable_reg(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
 	case BMP280_REG_CONFIG:
-	case BMP280_REG_CTRL_HUMIDITY:
 	case BMP280_REG_CTRL_MEAS:
 	case BMP280_REG_RESET:
 		return true;
@@ -57,8 +69,6 @@
 static bool bmp280_is_volatile_reg(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
-	case BMP280_REG_HUMIDITY_LSB:
-	case BMP280_REG_HUMIDITY_MSB:
 	case BMP280_REG_TEMP_XLSB:
 	case BMP280_REG_TEMP_LSB:
 	case BMP280_REG_TEMP_MSB:
@@ -72,6 +82,23 @@
 	}
 }
 
+static bool bme280_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case BME280_REG_HUMIDITY_LSB:
+	case BME280_REG_HUMIDITY_MSB:
+	case BMP280_REG_TEMP_XLSB:
+	case BMP280_REG_TEMP_LSB:
+	case BMP280_REG_TEMP_MSB:
+	case BMP280_REG_PRESS_XLSB:
+	case BMP280_REG_PRESS_LSB:
+	case BMP280_REG_PRESS_MSB:
+	case BMP280_REG_STATUS:
+		return true;
+	default:
+		return false;
+	}
+}
 static bool bmp380_is_writeable_reg(struct device *dev, unsigned int reg)
 {
 	switch (reg) {
@@ -167,7 +194,7 @@
 	.reg_bits = 8,
 	.val_bits = 8,
 
-	.max_register = BMP280_REG_HUMIDITY_LSB,
+	.max_register = BMP280_REG_TEMP_XLSB,
 	.cache_type = REGCACHE_RBTREE,
 
 	.writeable_reg = bmp280_is_writeable_reg,
@@ -175,6 +202,18 @@
 };
 EXPORT_SYMBOL_NS(bmp280_regmap_config, IIO_BMP280);
 
+const struct regmap_config bme280_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.max_register = BME280_REG_HUMIDITY_LSB,
+	.cache_type = REGCACHE_RBTREE,
+
+	.writeable_reg = bme280_is_writeable_reg,
+	.volatile_reg = bme280_is_volatile_reg,
+};
+EXPORT_SYMBOL_NS(bme280_regmap_config, IIO_BMP280);
+
 const struct regmap_config bmp380_regmap_config = {
 	.reg_bits = 8,
 	.val_bits = 8,
--- linux-qcom-6.8.0.orig/drivers/iio/pressure/bmp280-spi.c
+++ linux-qcom-6.8.0/drivers/iio/pressure/bmp280-spi.c
@@ -13,7 +13,7 @@
 #include "bmp280.h"
 
 static int bmp280_regmap_spi_write(void *context, const void *data,
-                                   size_t count)
+				   size_t count)
 {
 	struct spi_device *spi = to_spi_device(context);
 	u8 buf[2];
@@ -29,7 +29,7 @@
 }
 
 static int bmp280_regmap_spi_read(void *context, const void *reg,
-                                  size_t reg_size, void *val, size_t val_size)
+				  size_t reg_size, void *val, size_t val_size)
 {
 	struct spi_device *spi = to_spi_device(context);
 
@@ -96,15 +96,10 @@
 
 	chip_info = spi_get_device_match_data(spi);
 
-	switch (chip_info->chip_id[0]) {
-	case BMP380_CHIP_ID:
-	case BMP390_CHIP_ID:
+	if (chip_info->spi_read_extra_byte)
 		bmp_regmap_bus = &bmp380_regmap_bus;
-		break;
-	default:
+	else
 		bmp_regmap_bus = &bmp280_regmap_bus;
-		break;
-	}
 
 	regmap = devm_regmap_init(&spi->dev,
 				  bmp_regmap_bus,
@@ -127,7 +122,7 @@
 	{ .compatible = "bosch,bmp180", .data = &bmp180_chip_info },
 	{ .compatible = "bosch,bmp181", .data = &bmp180_chip_info },
 	{ .compatible = "bosch,bmp280", .data = &bmp280_chip_info },
-	{ .compatible = "bosch,bme280", .data = &bmp280_chip_info },
+	{ .compatible = "bosch,bme280", .data = &bme280_chip_info },
 	{ .compatible = "bosch,bmp380", .data = &bmp380_chip_info },
 	{ .compatible = "bosch,bmp580", .data = &bmp580_chip_info },
 	{ },
@@ -139,7 +134,7 @@
 	{ "bmp180", (kernel_ulong_t)&bmp180_chip_info },
 	{ "bmp181", (kernel_ulong_t)&bmp180_chip_info },
 	{ "bmp280", (kernel_ulong_t)&bmp280_chip_info },
-	{ "bme280", (kernel_ulong_t)&bmp280_chip_info },
+	{ "bme280", (kernel_ulong_t)&bme280_chip_info },
 	{ "bmp380", (kernel_ulong_t)&bmp380_chip_info },
 	{ "bmp580", (kernel_ulong_t)&bmp580_chip_info },
 	{ }
--- linux-qcom-6.8.0.orig/drivers/iio/pressure/bmp280.h
+++ linux-qcom-6.8.0/drivers/iio/pressure/bmp280.h
@@ -192,8 +192,6 @@
 #define BMP380_PRESS_SKIPPED		0x800000
 
 /* BMP280 specific registers */
-#define BMP280_REG_HUMIDITY_LSB		0xFE
-#define BMP280_REG_HUMIDITY_MSB		0xFD
 #define BMP280_REG_TEMP_XLSB		0xFC
 #define BMP280_REG_TEMP_LSB		0xFB
 #define BMP280_REG_TEMP_MSB		0xFA
@@ -207,15 +205,6 @@
 #define BMP280_REG_CONFIG		0xF5
 #define BMP280_REG_CTRL_MEAS		0xF4
 #define BMP280_REG_STATUS		0xF3
-#define BMP280_REG_CTRL_HUMIDITY	0xF2
-
-/* Due to non linear mapping, and data sizes we can't do a bulk read */
-#define BMP280_REG_COMP_H1		0xA1
-#define BMP280_REG_COMP_H2		0xE1
-#define BMP280_REG_COMP_H3		0xE3
-#define BMP280_REG_COMP_H4		0xE4
-#define BMP280_REG_COMP_H5		0xE5
-#define BMP280_REG_COMP_H6		0xE7
 
 #define BMP280_REG_COMP_TEMP_START	0x88
 #define BMP280_COMP_TEMP_REG_COUNT	6
@@ -223,8 +212,6 @@
 #define BMP280_REG_COMP_PRESS_START	0x8E
 #define BMP280_COMP_PRESS_REG_COUNT	18
 
-#define BMP280_COMP_H5_MASK		GENMASK(15, 4)
-
 #define BMP280_CONTIGUOUS_CALIB_REGS	(BMP280_COMP_TEMP_REG_COUNT + \
 					 BMP280_COMP_PRESS_REG_COUNT)
 
@@ -235,14 +222,6 @@
 #define BMP280_FILTER_8X		3
 #define BMP280_FILTER_16X		4
 
-#define BMP280_OSRS_HUMIDITY_MASK	GENMASK(2, 0)
-#define BMP280_OSRS_HUMIDITY_SKIP	0
-#define BMP280_OSRS_HUMIDITY_1X		1
-#define BMP280_OSRS_HUMIDITY_2X		2
-#define BMP280_OSRS_HUMIDITY_4X		3
-#define BMP280_OSRS_HUMIDITY_8X		4
-#define BMP280_OSRS_HUMIDITY_16X	5
-
 #define BMP280_OSRS_TEMP_MASK		GENMASK(7, 5)
 #define BMP280_OSRS_TEMP_SKIP		0
 #define BMP280_OSRS_TEMP_1X		1
@@ -264,6 +243,30 @@
 #define BMP280_MODE_FORCED		1
 #define BMP280_MODE_NORMAL		3
 
+/* BME280 specific registers */
+#define BME280_REG_HUMIDITY_LSB		0xFE
+#define BME280_REG_HUMIDITY_MSB		0xFD
+
+#define BME280_REG_CTRL_HUMIDITY	0xF2
+
+/* Due to non linear mapping, and data sizes we can't do a bulk read */
+#define BME280_REG_COMP_H1		0xA1
+#define BME280_REG_COMP_H2		0xE1
+#define BME280_REG_COMP_H3		0xE3
+#define BME280_REG_COMP_H4		0xE4
+#define BME280_REG_COMP_H5		0xE5
+#define BME280_REG_COMP_H6		0xE7
+
+#define BME280_COMP_H5_MASK		GENMASK(15, 4)
+
+#define BME280_OSRS_HUMIDITY_MASK	GENMASK(2, 0)
+#define BME280_OSRS_HUMIDITY_SKIP	0
+#define BME280_OSRS_HUMIDITY_1X		1
+#define BME280_OSRS_HUMIDITY_2X		2
+#define BME280_OSRS_HUMIDITY_4X		3
+#define BME280_OSRS_HUMIDITY_8X		4
+#define BME280_OSRS_HUMIDITY_16X	5
+
 /* BMP180 specific registers */
 #define BMP180_REG_OUT_XLSB		0xF8
 #define BMP180_REG_OUT_LSB		0xF7
@@ -423,6 +426,7 @@
 	int num_chip_id;
 
 	const struct regmap_config *regmap_config;
+	bool spi_read_extra_byte;
 
 	const struct iio_chan_spec *channels;
 	int num_channels;
@@ -466,6 +470,7 @@
 /* Regmap configurations */
 extern const struct regmap_config bmp180_regmap_config;
 extern const struct regmap_config bmp280_regmap_config;
+extern const struct regmap_config bme280_regmap_config;
 extern const struct regmap_config bmp380_regmap_config;
 extern const struct regmap_config bmp580_regmap_config;
 
--- linux-qcom-6.8.0.orig/drivers/iio/pressure/dps310.c
+++ linux-qcom-6.8.0/drivers/iio/pressure/dps310.c
@@ -730,7 +730,7 @@
 	}
 }
 
-static int dps310_calculate_temp(struct dps310_data *data)
+static int dps310_calculate_temp(struct dps310_data *data, int *val)
 {
 	s64 c0;
 	s64 t;
@@ -746,7 +746,9 @@
 	t = c0 + ((s64)data->temp_raw * (s64)data->c1);
 
 	/* Convert to milliCelsius and scale the temperature */
-	return (int)div_s64(t * 1000LL, kt);
+	*val = (int)div_s64(t * 1000LL, kt);
+
+	return 0;
 }
 
 static int dps310_read_temp(struct dps310_data *data, int *val, int *val2,
@@ -768,11 +770,10 @@
 		if (rc)
 			return rc;
 
-		rc = dps310_calculate_temp(data);
-		if (rc < 0)
+		rc = dps310_calculate_temp(data, val);
+		if (rc)
 			return rc;
 
-		*val = rc;
 		return IIO_VAL_INT;
 
 	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
--- linux-qcom-6.8.0.orig/drivers/iio/pressure/mprls0025pa.c
+++ linux-qcom-6.8.0/drivers/iio/pressure/mprls0025pa.c
@@ -323,6 +323,7 @@
 	struct iio_dev *indio_dev;
 	struct device *dev = &client->dev;
 	s64 scale, offset;
+	u32 func;
 
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BYTE))
 		return dev_err_probe(dev, -EOPNOTSUPP,
@@ -362,10 +363,11 @@
 			return dev_err_probe(dev, ret,
 				"honeywell,pmax-pascal could not be read\n");
 		ret = device_property_read_u32(dev,
-				"honeywell,transfer-function", &data->function);
+				"honeywell,transfer-function", &func);
 		if (ret)
 			return dev_err_probe(dev, ret,
 				"honeywell,transfer-function could not be read\n");
+		data->function = func - 1;
 		if (data->function > MPR_FUNCTION_C)
 			return dev_err_probe(dev, -EINVAL,
 				"honeywell,transfer-function %d invalid\n",
--- linux-qcom-6.8.0.orig/drivers/iio/pressure/zpa2326.c
+++ linux-qcom-6.8.0/drivers/iio/pressure/zpa2326.c
@@ -586,6 +586,8 @@
 	}   sample;
 	int err;
 
+	memset(&sample, 0, sizeof(sample));
+
 	if (test_bit(0, indio_dev->active_scan_mask)) {
 		/* Get current pressure from hardware FIFO. */
 		err = zpa2326_dequeue_pressure(indio_dev, &sample.pressure);
--- linux-qcom-6.8.0.orig/drivers/iio/proximity/Kconfig
+++ linux-qcom-6.8.0/drivers/iio/proximity/Kconfig
@@ -72,6 +72,8 @@
 config MB1232
 	tristate "MaxSonar I2CXL family ultrasonic sensors"
 	depends on I2C
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	help
 	  Say Y to build a driver for the ultrasonic sensors I2CXL of
 	  MaxBotix which have an i2c interface. It can be used to measure
--- linux-qcom-6.8.0.orig/drivers/iio/resolver/Kconfig
+++ linux-qcom-6.8.0/drivers/iio/resolver/Kconfig
@@ -31,6 +31,9 @@
 	depends on SPI
 	depends on COMMON_CLK
 	depends on GPIOLIB || COMPILE_TEST
+	select REGMAP
+	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	help
 	  Say yes here to build support for Analog Devices spi resolver
 	  to digital converters, ad2s1210, provides direct access via sysfs.
--- linux-qcom-6.8.0.orig/drivers/iio/temperature/mcp9600.c
+++ linux-qcom-6.8.0/drivers/iio/temperature/mcp9600.c
@@ -52,7 +52,8 @@
 
 	if (ret < 0)
 		return ret;
-	*val = ret;
+
+	*val = sign_extend32(ret, 15);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/iio/temperature/mlx90635.c
+++ linux-qcom-6.8.0/drivers/iio/temperature/mlx90635.c
@@ -947,9 +947,9 @@
 				     "failed to allocate regmap\n");
 
 	regmap_ee = devm_regmap_init_i2c(client, &mlx90635_regmap_ee);
-	if (IS_ERR(regmap))
-		return dev_err_probe(&client->dev, PTR_ERR(regmap),
-				     "failed to allocate regmap\n");
+	if (IS_ERR(regmap_ee))
+		return dev_err_probe(&client->dev, PTR_ERR(regmap_ee),
+				     "failed to allocate EEPROM regmap\n");
 
 	mlx90635 = iio_priv(indio_dev);
 	i2c_set_clientdata(client, indio_dev);
--- linux-qcom-6.8.0.orig/drivers/infiniband/core/addr.c
+++ linux-qcom-6.8.0/drivers/infiniband/core/addr.c
@@ -348,16 +348,10 @@
 
 static bool has_gateway(const struct dst_entry *dst, sa_family_t family)
 {
-	struct rtable *rt;
-	struct rt6_info *rt6;
+	if (family == AF_INET)
+		return dst_rtable(dst)->rt_uses_gateway;
 
-	if (family == AF_INET) {
-		rt = container_of(dst, struct rtable, dst);
-		return rt->rt_uses_gateway;
-	}
-
-	rt6 = container_of(dst, struct rt6_info, dst);
-	return rt6->rt6i_flags & RTF_GATEWAY;
+	return dst_rt6_info(dst)->rt6i_flags & RTF_GATEWAY;
 }
 
 static int fetch_ha(const struct dst_entry *dst, struct rdma_dev_addr *dev_addr,
--- linux-qcom-6.8.0.orig/drivers/infiniband/core/cache.c
+++ linux-qcom-6.8.0/drivers/infiniband/core/cache.c
@@ -794,7 +794,6 @@
 static void release_gid_table(struct ib_device *device,
 			      struct ib_gid_table *table)
 {
-	bool leak = false;
 	int i;
 
 	if (!table)
@@ -803,15 +802,12 @@
 	for (i = 0; i < table->sz; i++) {
 		if (is_gid_entry_free(table->data_vec[i]))
 			continue;
-		if (kref_read(&table->data_vec[i]->kref) > 1) {
-			dev_err(&device->dev,
-				"GID entry ref leak for index %d ref=%u\n", i,
-				kref_read(&table->data_vec[i]->kref));
-			leak = true;
-		}
+
+		WARN_ONCE(true,
+			  "GID entry ref leak for dev %s index %d ref=%u\n",
+			  dev_name(&device->dev), i,
+			  kref_read(&table->data_vec[i]->kref));
 	}
-	if (leak)
-		return;
 
 	mutex_destroy(&table->lock);
 	kfree(table->data_vec);
@@ -1644,8 +1640,10 @@
 
 	rdma_for_each_port (device, p) {
 		err = ib_cache_update(device, p, true, true, true);
-		if (err)
+		if (err) {
+			gid_table_cleanup_one(device);
 			return err;
+		}
 	}
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/infiniband/core/cm.c
+++ linux-qcom-6.8.0/drivers/infiniband/core/cm.c
@@ -34,6 +34,7 @@
 MODULE_DESCRIPTION("InfiniBand CM");
 MODULE_LICENSE("Dual BSD/GPL");
 
+#define CM_DESTROY_ID_WAIT_TIMEOUT 10000 /* msecs */
 static const char * const ibcm_rej_reason_strs[] = {
 	[IB_CM_REJ_NO_QP]			= "no QP",
 	[IB_CM_REJ_NO_EEC]			= "no EEC",
@@ -1025,13 +1026,26 @@
 	}
 }
 
+static noinline void cm_destroy_id_wait_timeout(struct ib_cm_id *cm_id,
+						enum ib_cm_state old_state)
+{
+	struct cm_id_private *cm_id_priv;
+
+	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+	pr_err("%s: cm_id=%p timed out. state %d -> %d, refcnt=%d\n", __func__,
+	       cm_id, old_state, cm_id->state, refcount_read(&cm_id_priv->refcount));
+}
+
 static void cm_destroy_id(struct ib_cm_id *cm_id, int err)
 {
 	struct cm_id_private *cm_id_priv;
+	enum ib_cm_state old_state;
 	struct cm_work *work;
+	int ret;
 
 	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
 	spin_lock_irq(&cm_id_priv->lock);
+	old_state = cm_id->state;
 retest:
 	switch (cm_id->state) {
 	case IB_CM_LISTEN:
@@ -1135,7 +1149,14 @@
 
 	xa_erase(&cm.local_id_table, cm_local_id(cm_id->local_id));
 	cm_deref_id(cm_id_priv);
-	wait_for_completion(&cm_id_priv->comp);
+	do {
+		ret = wait_for_completion_timeout(&cm_id_priv->comp,
+						  msecs_to_jiffies(
+						  CM_DESTROY_ID_WAIT_TIMEOUT));
+		if (!ret) /* timeout happened */
+			cm_destroy_id_wait_timeout(cm_id, old_state);
+	} while (!ret);
+
 	while ((work = cm_dequeue_work(cm_id_priv)) != NULL)
 		cm_free_work(work);
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/core/cma.c
+++ linux-qcom-6.8.0/drivers/infiniband/core/cma.c
@@ -690,6 +690,7 @@
 	int bound_if_index = dev_addr->bound_dev_if;
 	int dev_type = dev_addr->dev_type;
 	struct net_device *ndev = NULL;
+	struct net_device *pdev = NULL;
 
 	if (!rdma_dev_access_netns(device, id_priv->id.route.addr.dev_addr.net))
 		goto out;
@@ -714,9 +715,26 @@
 
 		rcu_read_lock();
 		ndev = rcu_dereference(sgid_attr->ndev);
+		if (ndev->ifindex != bound_if_index) {
+			pdev = dev_get_by_index_rcu(dev_addr->net, bound_if_index);
+			if (pdev) {
+				if (is_vlan_dev(pdev)) {
+					pdev = vlan_dev_real_dev(pdev);
+					if (ndev->ifindex == pdev->ifindex)
+						bound_if_index = pdev->ifindex;
+				}
+				if (is_vlan_dev(ndev)) {
+					pdev = vlan_dev_real_dev(ndev);
+					if (bound_if_index == pdev->ifindex)
+						bound_if_index = ndev->ifindex;
+				}
+			}
+		}
 		if (!net_eq(dev_net(ndev), dev_addr->net) ||
-		    ndev->ifindex != bound_if_index)
+		    ndev->ifindex != bound_if_index) {
+			rdma_put_gid_attr(sgid_attr);
 			sgid_attr = ERR_PTR(-ENODEV);
+		}
 		rcu_read_unlock();
 		goto out;
 	}
--- linux-qcom-6.8.0.orig/drivers/infiniband/core/device.c
+++ linux-qcom-6.8.0/drivers/infiniband/core/device.c
@@ -1730,7 +1730,7 @@
 {
 	int ret;
 
-	down_write(&clients_rwsem);
+	lockdep_assert_held(&clients_rwsem);
 	/*
 	 * The add/remove callbacks must be called in FIFO/LIFO order. To
 	 * achieve this we assign client_ids so they are sorted in
@@ -1739,14 +1739,11 @@
 	client->client_id = highest_client_id;
 	ret = xa_insert(&clients, client->client_id, client, GFP_KERNEL);
 	if (ret)
-		goto out;
+		return ret;
 
 	highest_client_id++;
 	xa_set_mark(&clients, client->client_id, CLIENT_REGISTERED);
-
-out:
-	up_write(&clients_rwsem);
-	return ret;
+	return 0;
 }
 
 static void remove_client_id(struct ib_client *client)
@@ -1776,25 +1773,35 @@
 {
 	struct ib_device *device;
 	unsigned long index;
+	bool need_unreg = false;
 	int ret;
 
 	refcount_set(&client->uses, 1);
 	init_completion(&client->uses_zero);
+
+	/*
+	 * The devices_rwsem is held in write mode to ensure that a racing
+	 * ib_register_device() sees a consisent view of clients and devices.
+	 */
+	down_write(&devices_rwsem);
+	down_write(&clients_rwsem);
 	ret = assign_client_id(client);
 	if (ret)
-		return ret;
+		goto out;
 
-	down_read(&devices_rwsem);
+	need_unreg = true;
 	xa_for_each_marked (&devices, index, device, DEVICE_REGISTERED) {
 		ret = add_client_context(device, client);
-		if (ret) {
-			up_read(&devices_rwsem);
-			ib_unregister_client(client);
-			return ret;
-		}
+		if (ret)
+			goto out;
 	}
-	up_read(&devices_rwsem);
-	return 0;
+	ret = 0;
+out:
+	up_write(&clients_rwsem);
+	up_write(&devices_rwsem);
+	if (need_unreg && ret)
+		ib_unregister_client(client);
+	return ret;
 }
 EXPORT_SYMBOL(ib_register_client);
 
@@ -2139,6 +2146,9 @@
 	unsigned long flags;
 	int ret;
 
+	if (!rdma_is_port_valid(ib_dev, port))
+		return -EINVAL;
+
 	/*
 	 * Drivers wish to call this before ib_register_driver, so we have to
 	 * setup the port data early.
@@ -2147,9 +2157,6 @@
 	if (ret)
 		return ret;
 
-	if (!rdma_is_port_valid(ib_dev, port))
-		return -EINVAL;
-
 	pdata = &ib_dev->port_data[port];
 	spin_lock_irqsave(&pdata->netdev_lock, flags);
 	old_ndev = rcu_dereference_protected(
@@ -2159,17 +2166,12 @@
 		return 0;
 	}
 
-	if (old_ndev)
-		netdev_tracker_free(ndev, &pdata->netdev_tracker);
-	if (ndev)
-		netdev_hold(ndev, &pdata->netdev_tracker, GFP_ATOMIC);
 	rcu_assign_pointer(pdata->netdev, ndev);
+	netdev_put(old_ndev, &pdata->netdev_tracker);
+	netdev_hold(ndev, &pdata->netdev_tracker, GFP_ATOMIC);
 	spin_unlock_irqrestore(&pdata->netdev_lock, flags);
 
 	add_ndev_hash(pdata);
-	if (old_ndev)
-		__dev_put(old_ndev);
-
 	return 0;
 }
 EXPORT_SYMBOL(ib_device_set_netdev);
@@ -2228,8 +2230,7 @@
 		spin_lock(&pdata->netdev_lock);
 		res = rcu_dereference_protected(
 			pdata->netdev, lockdep_is_held(&pdata->netdev_lock));
-		if (res)
-			dev_hold(res);
+		dev_hold(res);
 		spin_unlock(&pdata->netdev_lock);
 	}
 
@@ -2304,9 +2305,7 @@
 
 			if (filter(ib_dev, port, idev, filter_cookie))
 				cb(ib_dev, port, idev, cookie);
-
-			if (idev)
-				dev_put(idev);
+			dev_put(idev);
 		}
 }
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/core/iwcm.c
+++ linux-qcom-6.8.0/drivers/infiniband/core/iwcm.c
@@ -368,8 +368,10 @@
  *
  * Clean up all resources associated with the connection and release
  * the initial reference taken by iw_create_cm_id.
+ *
+ * Returns true if and only if the last cm_id_priv reference has been dropped.
  */
-static void destroy_cm_id(struct iw_cm_id *cm_id)
+static bool destroy_cm_id(struct iw_cm_id *cm_id)
 {
 	struct iwcm_id_private *cm_id_priv;
 	struct ib_qp *qp;
@@ -439,7 +441,7 @@
 		iwpm_remove_mapping(&cm_id->local_addr, RDMA_NL_IWCM);
 	}
 
-	(void)iwcm_deref_id(cm_id_priv);
+	return iwcm_deref_id(cm_id_priv);
 }
 
 /*
@@ -450,7 +452,8 @@
  */
 void iw_destroy_cm_id(struct iw_cm_id *cm_id)
 {
-	destroy_cm_id(cm_id);
+	if (!destroy_cm_id(cm_id))
+		flush_workqueue(iwcm_wq);
 }
 EXPORT_SYMBOL(iw_destroy_cm_id);
 
@@ -1034,7 +1037,7 @@
 		if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) {
 			ret = process_event(cm_id_priv, &levent);
 			if (ret)
-				destroy_cm_id(&cm_id_priv->id);
+				WARN_ON_ONCE(destroy_cm_id(&cm_id_priv->id));
 		} else
 			pr_debug("dropping event %d\n", levent.event);
 		if (iwcm_deref_id(cm_id_priv))
@@ -1187,7 +1190,7 @@
 	if (ret)
 		return ret;
 
-	iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", 0);
+	iwcm_wq = alloc_ordered_workqueue("iw_cm_wq", WQ_MEM_RECLAIM);
 	if (!iwcm_wq)
 		goto err_alloc;
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/core/lag.c
+++ linux-qcom-6.8.0/drivers/infiniband/core/lag.c
@@ -93,8 +93,7 @@
 	slave = netdev_get_xmit_slave(master, skb,
 				      !!(device->lag_flags &
 					 RDMA_LAG_FLAGS_HASH_ALL_SLAVES));
-	if (slave)
-		dev_hold(slave);
+	dev_hold(slave);
 	rcu_read_unlock();
 	kfree_skb(skb);
 	return slave;
--- linux-qcom-6.8.0.orig/drivers/infiniband/core/mad.c
+++ linux-qcom-6.8.0/drivers/infiniband/core/mad.c
@@ -2616,14 +2616,16 @@
 
 static void timeout_sends(struct work_struct *work)
 {
+	struct ib_mad_send_wr_private *mad_send_wr, *n;
 	struct ib_mad_agent_private *mad_agent_priv;
-	struct ib_mad_send_wr_private *mad_send_wr;
 	struct ib_mad_send_wc mad_send_wc;
+	struct list_head local_list;
 	unsigned long flags, delay;
 
 	mad_agent_priv = container_of(work, struct ib_mad_agent_private,
 				      timed_work.work);
 	mad_send_wc.vendor_err = 0;
+	INIT_LIST_HEAD(&local_list);
 
 	spin_lock_irqsave(&mad_agent_priv->lock, flags);
 	while (!list_empty(&mad_agent_priv->wait_list)) {
@@ -2641,13 +2643,16 @@
 			break;
 		}
 
-		list_del(&mad_send_wr->agent_list);
+		list_del_init(&mad_send_wr->agent_list);
 		if (mad_send_wr->status == IB_WC_SUCCESS &&
 		    !retry_send(mad_send_wr))
 			continue;
 
-		spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
+		list_add_tail(&mad_send_wr->agent_list, &local_list);
+	}
+	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 
+	list_for_each_entry_safe(mad_send_wr, n, &local_list, agent_list) {
 		if (mad_send_wr->status == IB_WC_SUCCESS)
 			mad_send_wc.status = IB_WC_RESP_TIMEOUT_ERR;
 		else
@@ -2655,11 +2660,8 @@
 		mad_send_wc.send_buf = &mad_send_wr->send_buf;
 		mad_agent_priv->agent.send_handler(&mad_agent_priv->agent,
 						   &mad_send_wc);
-
 		deref_mad_agent(mad_agent_priv);
-		spin_lock_irqsave(&mad_agent_priv->lock, flags);
 	}
-	spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
 }
 
 /*
--- linux-qcom-6.8.0.orig/drivers/infiniband/core/restrack.c
+++ linux-qcom-6.8.0/drivers/infiniband/core/restrack.c
@@ -37,22 +37,6 @@
 	return 0;
 }
 
-static const char *type2str(enum rdma_restrack_type type)
-{
-	static const char * const names[RDMA_RESTRACK_MAX] = {
-		[RDMA_RESTRACK_PD] = "PD",
-		[RDMA_RESTRACK_CQ] = "CQ",
-		[RDMA_RESTRACK_QP] = "QP",
-		[RDMA_RESTRACK_CM_ID] = "CM_ID",
-		[RDMA_RESTRACK_MR] = "MR",
-		[RDMA_RESTRACK_CTX] = "CTX",
-		[RDMA_RESTRACK_COUNTER] = "COUNTER",
-		[RDMA_RESTRACK_SRQ] = "SRQ",
-	};
-
-	return names[type];
-};
-
 /**
  * rdma_restrack_clean() - clean resource tracking
  * @dev:  IB device
@@ -60,47 +44,14 @@
 void rdma_restrack_clean(struct ib_device *dev)
 {
 	struct rdma_restrack_root *rt = dev->res;
-	struct rdma_restrack_entry *e;
-	char buf[TASK_COMM_LEN];
-	bool found = false;
-	const char *owner;
 	int i;
 
 	for (i = 0 ; i < RDMA_RESTRACK_MAX; i++) {
 		struct xarray *xa = &dev->res[i].xa;
 
-		if (!xa_empty(xa)) {
-			unsigned long index;
-
-			if (!found) {
-				pr_err("restrack: %s", CUT_HERE);
-				dev_err(&dev->dev, "BUG: RESTRACK detected leak of resources\n");
-			}
-			xa_for_each(xa, index, e) {
-				if (rdma_is_kernel_res(e)) {
-					owner = e->kern_name;
-				} else {
-					/*
-					 * There is no need to call get_task_struct here,
-					 * because we can be here only if there are more
-					 * get_task_struct() call than put_task_struct().
-					 */
-					get_task_comm(buf, e->task);
-					owner = buf;
-				}
-
-				pr_err("restrack: %s %s object allocated by %s is not freed\n",
-				       rdma_is_kernel_res(e) ? "Kernel" :
-							       "User",
-				       type2str(e->type), owner);
-			}
-			found = true;
-		}
+		WARN_ON(!xa_empty(xa));
 		xa_destroy(xa);
 	}
-	if (found)
-		pr_err("restrack: %s", CUT_HERE);
-
 	kfree(rt);
 }
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/core/roce_gid_mgmt.c
+++ linux-qcom-6.8.0/drivers/infiniband/core/roce_gid_mgmt.c
@@ -601,8 +601,7 @@
 
 	rcu_read_lock();
 	master_ndev = netdev_master_upper_dev_get_rcu(rdma_ndev);
-	if (master_ndev)
-		dev_hold(master_ndev);
+	dev_hold(master_ndev);
 	rcu_read_unlock();
 
 	if (master_ndev) {
--- linux-qcom-6.8.0.orig/drivers/infiniband/core/user_mad.c
+++ linux-qcom-6.8.0/drivers/infiniband/core/user_mad.c
@@ -63,6 +63,8 @@
 MODULE_DESCRIPTION("InfiniBand userspace MAD packet access");
 MODULE_LICENSE("Dual BSD/GPL");
 
+#define MAX_UMAD_RECV_LIST_SIZE 200000
+
 enum {
 	IB_UMAD_MAX_PORTS  = RDMA_MAX_PORTS,
 	IB_UMAD_MAX_AGENTS = 32,
@@ -113,6 +115,7 @@
 	struct mutex		mutex;
 	struct ib_umad_port    *port;
 	struct list_head	recv_list;
+	atomic_t		recv_list_size;
 	struct list_head	send_list;
 	struct list_head	port_list;
 	spinlock_t		send_lock;
@@ -180,24 +183,28 @@
 	return file->agents_dead ? NULL : file->agent[id];
 }
 
-static int queue_packet(struct ib_umad_file *file,
-			struct ib_mad_agent *agent,
-			struct ib_umad_packet *packet)
+static int queue_packet(struct ib_umad_file *file, struct ib_mad_agent *agent,
+			struct ib_umad_packet *packet, bool is_recv_mad)
 {
 	int ret = 1;
 
 	mutex_lock(&file->mutex);
 
+	if (is_recv_mad &&
+	    atomic_read(&file->recv_list_size) > MAX_UMAD_RECV_LIST_SIZE)
+		goto unlock;
+
 	for (packet->mad.hdr.id = 0;
 	     packet->mad.hdr.id < IB_UMAD_MAX_AGENTS;
 	     packet->mad.hdr.id++)
 		if (agent == __get_agent(file, packet->mad.hdr.id)) {
 			list_add_tail(&packet->list, &file->recv_list);
+			atomic_inc(&file->recv_list_size);
 			wake_up_interruptible(&file->recv_wait);
 			ret = 0;
 			break;
 		}
-
+unlock:
 	mutex_unlock(&file->mutex);
 
 	return ret;
@@ -224,7 +231,7 @@
 	if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
 		packet->length = IB_MGMT_MAD_HDR;
 		packet->mad.hdr.status = ETIMEDOUT;
-		if (!queue_packet(file, agent, packet))
+		if (!queue_packet(file, agent, packet, false))
 			return;
 	}
 	kfree(packet);
@@ -284,7 +291,7 @@
 		rdma_destroy_ah_attr(&ah_attr);
 	}
 
-	if (queue_packet(file, agent, packet))
+	if (queue_packet(file, agent, packet, true))
 		goto err2;
 	return;
 
@@ -409,6 +416,7 @@
 
 	packet = list_entry(file->recv_list.next, struct ib_umad_packet, list);
 	list_del(&packet->list);
+	atomic_dec(&file->recv_list_size);
 
 	mutex_unlock(&file->mutex);
 
@@ -421,6 +429,7 @@
 		/* Requeue packet */
 		mutex_lock(&file->mutex);
 		list_add(&packet->list, &file->recv_list);
+		atomic_inc(&file->recv_list_size);
 		mutex_unlock(&file->mutex);
 	} else {
 		if (packet->recv_wc)
--- linux-qcom-6.8.0.orig/drivers/infiniband/core/uverbs.h
+++ linux-qcom-6.8.0/drivers/infiniband/core/uverbs.h
@@ -160,6 +160,8 @@
 	struct page *disassociate_page;
 
 	struct xarray		idr;
+
+	struct mutex disassociation_lock;
 };
 
 struct ib_uverbs_event {
--- linux-qcom-6.8.0.orig/drivers/infiniband/core/uverbs_cmd.c
+++ linux-qcom-6.8.0/drivers/infiniband/core/uverbs_cmd.c
@@ -161,7 +161,7 @@
 {
 	const void __user *res = iter->cur;
 
-	if (iter->cur + len > iter->end)
+	if (len > iter->end - iter->cur)
 		return (void __force __user *)ERR_PTR(-ENOSPC);
 	iter->cur += len;
 	return res;
@@ -2010,11 +2010,13 @@
 	ret = uverbs_request_start(attrs, &iter, &cmd, sizeof(cmd));
 	if (ret)
 		return ret;
-	wqes = uverbs_request_next_ptr(&iter, cmd.wqe_size * cmd.wr_count);
+	wqes = uverbs_request_next_ptr(&iter, size_mul(cmd.wqe_size,
+						       cmd.wr_count));
 	if (IS_ERR(wqes))
 		return PTR_ERR(wqes);
-	sgls = uverbs_request_next_ptr(
-		&iter, cmd.sge_count * sizeof(struct ib_uverbs_sge));
+	sgls = uverbs_request_next_ptr(&iter,
+				       size_mul(cmd.sge_count,
+						sizeof(struct ib_uverbs_sge)));
 	if (IS_ERR(sgls))
 		return PTR_ERR(sgls);
 	ret = uverbs_request_finish(&iter);
@@ -2200,11 +2202,11 @@
 	if (wqe_size < sizeof(struct ib_uverbs_recv_wr))
 		return ERR_PTR(-EINVAL);
 
-	wqes = uverbs_request_next_ptr(iter, wqe_size * wr_count);
+	wqes = uverbs_request_next_ptr(iter, size_mul(wqe_size, wr_count));
 	if (IS_ERR(wqes))
 		return ERR_CAST(wqes);
-	sgls = uverbs_request_next_ptr(
-		iter, sge_count * sizeof(struct ib_uverbs_sge));
+	sgls = uverbs_request_next_ptr(iter, size_mul(sge_count,
+						      sizeof(struct ib_uverbs_sge)));
 	if (IS_ERR(sgls))
 		return ERR_CAST(sgls);
 	ret = uverbs_request_finish(iter);
--- linux-qcom-6.8.0.orig/drivers/infiniband/core/uverbs_main.c
+++ linux-qcom-6.8.0/drivers/infiniband/core/uverbs_main.c
@@ -76,6 +76,7 @@
 static DEFINE_IDA(uverbs_ida);
 static int ib_uverbs_add_one(struct ib_device *device);
 static void ib_uverbs_remove_one(struct ib_device *device, void *client_data);
+static struct ib_client uverbs_client;
 
 static char *uverbs_devnode(const struct device *dev, umode_t *mode)
 {
@@ -217,6 +218,7 @@
 
 	if (file->disassociate_page)
 		__free_pages(file->disassociate_page, 0);
+	mutex_destroy(&file->disassociation_lock);
 	mutex_destroy(&file->umap_lock);
 	mutex_destroy(&file->ucontext_lock);
 	kfree(file);
@@ -700,8 +702,13 @@
 		ret = PTR_ERR(ucontext);
 		goto out;
 	}
+
+	mutex_lock(&file->disassociation_lock);
+
 	vma->vm_ops = &rdma_umap_ops;
 	ret = ucontext->device->ops.mmap(ucontext, vma);
+
+	mutex_unlock(&file->disassociation_lock);
 out:
 	srcu_read_unlock(&file->device->disassociate_srcu, srcu_key);
 	return ret;
@@ -723,6 +730,8 @@
 	/* We are racing with disassociation */
 	if (!down_read_trylock(&ufile->hw_destroy_rwsem))
 		goto out_zap;
+	mutex_lock(&ufile->disassociation_lock);
+
 	/*
 	 * Disassociation already completed, the VMA should already be zapped.
 	 */
@@ -734,10 +743,12 @@
 		goto out_unlock;
 	rdma_umap_priv_init(priv, vma, opriv->entry);
 
+	mutex_unlock(&ufile->disassociation_lock);
 	up_read(&ufile->hw_destroy_rwsem);
 	return;
 
 out_unlock:
+	mutex_unlock(&ufile->disassociation_lock);
 	up_read(&ufile->hw_destroy_rwsem);
 out_zap:
 	/*
@@ -821,7 +832,7 @@
 {
 	struct rdma_umap_priv *priv, *next_priv;
 
-	lockdep_assert_held(&ufile->hw_destroy_rwsem);
+	mutex_lock(&ufile->disassociation_lock);
 
 	while (1) {
 		struct mm_struct *mm = NULL;
@@ -847,8 +858,10 @@
 			break;
 		}
 		mutex_unlock(&ufile->umap_lock);
-		if (!mm)
+		if (!mm) {
+			mutex_unlock(&ufile->disassociation_lock);
 			return;
+		}
 
 		/*
 		 * The umap_lock is nested under mmap_lock since it used within
@@ -878,7 +891,31 @@
 		mmap_read_unlock(mm);
 		mmput(mm);
 	}
+
+	mutex_unlock(&ufile->disassociation_lock);
+}
+
+/**
+ * rdma_user_mmap_disassociate() - Revoke mmaps for a device
+ * @device: device to revoke
+ *
+ * This function should be called by drivers that need to disable mmaps for the
+ * device, for instance because it is going to be reset.
+ */
+void rdma_user_mmap_disassociate(struct ib_device *device)
+{
+	struct ib_uverbs_device *uverbs_dev =
+		ib_get_client_data(device, &uverbs_client);
+	struct ib_uverbs_file *ufile;
+
+	mutex_lock(&uverbs_dev->lists_mutex);
+	list_for_each_entry(ufile, &uverbs_dev->uverbs_file_list, list) {
+		if (ufile->ucontext)
+			uverbs_user_mmap_disassociate(ufile);
+	}
+	mutex_unlock(&uverbs_dev->lists_mutex);
 }
+EXPORT_SYMBOL(rdma_user_mmap_disassociate);
 
 /*
  * ib_uverbs_open() does not need the BKL:
@@ -949,6 +986,8 @@
 	mutex_init(&file->umap_lock);
 	INIT_LIST_HEAD(&file->umaps);
 
+	mutex_init(&file->disassociation_lock);
+
 	filp->private_data = file;
 	list_add_tail(&file->list, &dev->uverbs_file_list);
 	mutex_unlock(&dev->lists_mutex);
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/Makefile
+++ linux-qcom-6.8.0/drivers/infiniband/hw/Makefile
@@ -11,7 +11,7 @@
 obj-$(CONFIG_INFINIBAND_VMWARE_PVRDMA)	+= vmw_pvrdma/
 obj-$(CONFIG_INFINIBAND_USNIC)		+= usnic/
 obj-$(CONFIG_INFINIBAND_HFI1)		+= hfi1/
-obj-$(CONFIG_INFINIBAND_HNS)		+= hns/
+obj-$(CONFIG_INFINIBAND_HNS_HIP08)	+= hns/
 obj-$(CONFIG_INFINIBAND_QEDR)		+= qedr/
 obj-$(CONFIG_INFINIBAND_BNXT_RE)	+= bnxt_re/
 obj-$(CONFIG_INFINIBAND_ERDMA)		+= erdma/
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/bnxt_re/bnxt_re.h
+++ linux-qcom-6.8.0/drivers/infiniband/hw/bnxt_re/bnxt_re.h
@@ -107,8 +107,6 @@
 	struct	bnxt_re_sqp_entries *sqp_tbl;
 };
 
-#define BNXT_RE_MIN_MSIX		2
-#define BNXT_RE_MAX_MSIX		9
 #define BNXT_RE_AEQ_IDX			0
 #define BNXT_RE_NQ_IDX			1
 #define BNXT_RE_GEN_P5_MAX_VF		64
@@ -168,7 +166,7 @@
 	struct bnxt_qplib_rcfw		rcfw;
 
 	/* NQ */
-	struct bnxt_qplib_nq		nq[BNXT_RE_MAX_MSIX];
+	struct bnxt_qplib_nq		nq[BNXT_MAX_ROCE_MSIX];
 
 	/* Device Resources */
 	struct bnxt_qplib_dev_attr	dev_attr;
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/bnxt_re/hw_counters.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/bnxt_re/hw_counters.c
@@ -366,7 +366,7 @@
 				goto done;
 			}
 		}
-		if (rdev->pacing.dbr_pacing)
+		if (rdev->pacing.dbr_pacing && bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx))
 			bnxt_re_copy_db_pacing_stats(rdev, stats);
 	}
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/bnxt_re/ib_verbs.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/bnxt_re/ib_verbs.c
@@ -148,7 +148,7 @@
 
 	ib_attr->vendor_id = rdev->en_dev->pdev->vendor;
 	ib_attr->vendor_part_id = rdev->en_dev->pdev->device;
-	ib_attr->hw_ver = rdev->en_dev->pdev->subsystem_device;
+	ib_attr->hw_ver = rdev->en_dev->pdev->revision;
 	ib_attr->max_qp = dev_attr->max_qp;
 	ib_attr->max_qp_wr = dev_attr->max_qp_wqes;
 	ib_attr->device_cap_flags =
@@ -994,23 +994,22 @@
 	align = sizeof(struct sq_send_hdr);
 	ilsize = ALIGN(init_attr->cap.max_inline_data, align);
 
-	sq->wqe_size = bnxt_re_get_wqe_size(ilsize, sq->max_sge);
-	if (sq->wqe_size > bnxt_re_get_swqe_size(dev_attr->max_qp_sges))
-		return -EINVAL;
-	/* For gen p4 and gen p5 backward compatibility mode
-	 * wqe size is fixed to 128 bytes
+	/* For gen p4 and gen p5 fixed wqe compatibility mode
+	 * wqe size is fixed to 128 bytes - ie 6 SGEs
 	 */
-	if (sq->wqe_size < bnxt_re_get_swqe_size(dev_attr->max_qp_sges) &&
-			qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC)
-		sq->wqe_size = bnxt_re_get_swqe_size(dev_attr->max_qp_sges);
+	if (qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) {
+		sq->wqe_size = bnxt_re_get_swqe_size(BNXT_STATIC_MAX_SGE);
+		sq->max_sge = BNXT_STATIC_MAX_SGE;
+	} else {
+		sq->wqe_size = bnxt_re_get_wqe_size(ilsize, sq->max_sge);
+		if (sq->wqe_size > bnxt_re_get_swqe_size(dev_attr->max_qp_sges))
+			return -EINVAL;
+	}
 
 	if (init_attr->cap.max_inline_data) {
 		qplqp->max_inline_data = sq->wqe_size -
 			sizeof(struct sq_send_hdr);
 		init_attr->cap.max_inline_data = qplqp->max_inline_data;
-		if (qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC)
-			sq->max_sge = qplqp->max_inline_data /
-				sizeof(struct sq_sge);
 	}
 
 	return 0;
@@ -1156,6 +1155,7 @@
 	/* Shadow QP SQ depth should be same as QP1 RQ depth */
 	qp->qplib_qp.sq.wqe_size = bnxt_re_get_wqe_size(0, 6);
 	qp->qplib_qp.sq.max_wqe = qp1_qp->rq.max_wqe;
+	qp->qplib_qp.sq.max_sw_wqe = qp1_qp->rq.max_wqe;
 	qp->qplib_qp.sq.max_sge = 2;
 	/* Q full delta can be 1 since it is internal QP */
 	qp->qplib_qp.sq.q_full_delta = 1;
@@ -1167,6 +1167,7 @@
 
 	qp->qplib_qp.rq.wqe_size = bnxt_re_get_rwqe_size(6);
 	qp->qplib_qp.rq.max_wqe = qp1_qp->rq.max_wqe;
+	qp->qplib_qp.rq.max_sw_wqe = qp1_qp->rq.max_wqe;
 	qp->qplib_qp.rq.max_sge = qp1_qp->rq.max_sge;
 	/* Q full delta can be 1 since it is internal QP */
 	qp->qplib_qp.rq.q_full_delta = 1;
@@ -1228,6 +1229,7 @@
 		 */
 		entries = bnxt_re_init_depth(init_attr->cap.max_recv_wr + 1, uctx);
 		rq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + 1);
+		rq->max_sw_wqe = rq->max_wqe;
 		rq->q_full_delta = 0;
 		rq->sg_info.pgsize = PAGE_SIZE;
 		rq->sg_info.pgshft = PAGE_SHIFT;
@@ -1287,6 +1289,7 @@
 		0 : BNXT_QPLIB_RESERVED_QP_WRS;
 	entries = bnxt_re_init_depth(entries + diff + 1, uctx);
 	sq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + diff + 1);
+	sq->max_sw_wqe = bnxt_qplib_get_depth(sq, qplqp->wqe_mode, true);
 	sq->q_full_delta = diff + 1;
 	/*
 	 * Reserving one slot for Phantom WQE. Application can
@@ -2057,18 +2060,20 @@
 		}
 	}
 
-	if (qp_attr_mask & IB_QP_PATH_MTU) {
-		qp->qplib_qp.modify_flags |=
-				CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU;
-		qp->qplib_qp.path_mtu = __from_ib_mtu(qp_attr->path_mtu);
-		qp->qplib_qp.mtu = ib_mtu_enum_to_int(qp_attr->path_mtu);
-	} else if (qp_attr->qp_state == IB_QPS_RTR) {
-		qp->qplib_qp.modify_flags |=
-			CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU;
-		qp->qplib_qp.path_mtu =
-			__from_ib_mtu(iboe_get_mtu(rdev->netdev->mtu));
-		qp->qplib_qp.mtu =
-			ib_mtu_enum_to_int(iboe_get_mtu(rdev->netdev->mtu));
+	if (qp_attr->qp_state == IB_QPS_RTR) {
+		enum ib_mtu qpmtu;
+
+		qpmtu = iboe_get_mtu(rdev->netdev->mtu);
+		if (qp_attr_mask & IB_QP_PATH_MTU) {
+			if (ib_mtu_enum_to_int(qp_attr->path_mtu) >
+			    ib_mtu_enum_to_int(qpmtu))
+				return -EINVAL;
+			qpmtu = qp_attr->path_mtu;
+		}
+
+		qp->qplib_qp.modify_flags |= CMDQ_MODIFY_QP_MODIFY_MASK_PATH_MTU;
+		qp->qplib_qp.path_mtu = __from_ib_mtu(qpmtu);
+		qp->qplib_qp.mtu = ib_mtu_enum_to_int(qpmtu);
 	}
 
 	if (qp_attr_mask & IB_QP_TIMEOUT) {
@@ -2155,6 +2160,7 @@
 			entries = bnxt_re_init_depth(qp_attr->cap.max_recv_wr, uctx);
 			qp->qplib_qp.rq.max_wqe =
 				min_t(u32, entries, dev_attr->max_qp_wqes + 1);
+			qp->qplib_qp.rq.max_sw_wqe = qp->qplib_qp.rq.max_wqe;
 			qp->qplib_qp.rq.q_full_delta = qp->qplib_qp.rq.max_wqe -
 						       qp_attr->cap.max_recv_wr;
 			qp->qplib_qp.rq.max_sge = qp_attr->cap.max_recv_sge;
@@ -2216,6 +2222,7 @@
 	qp_attr->retry_cnt = qplib_qp->retry_cnt;
 	qp_attr->rnr_retry = qplib_qp->rnr_retry;
 	qp_attr->min_rnr_timer = qplib_qp->min_rnr_timer;
+	qp_attr->port_num = __to_ib_port_num(qplib_qp->port_id);
 	qp_attr->rq_psn = qplib_qp->rq.psn;
 	qp_attr->max_rd_atomic = qplib_qp->max_rd_atomic;
 	qp_attr->sq_psn = qplib_qp->sq.psn;
@@ -2479,7 +2486,7 @@
 		break;
 	case IB_WR_SEND_WITH_IMM:
 		wqe->type = BNXT_QPLIB_SWQE_TYPE_SEND_WITH_IMM;
-		wqe->send.imm_data = wr->ex.imm_data;
+		wqe->send.imm_data = be32_to_cpu(wr->ex.imm_data);
 		break;
 	case IB_WR_SEND_WITH_INV:
 		wqe->type = BNXT_QPLIB_SWQE_TYPE_SEND_WITH_INV;
@@ -2509,7 +2516,7 @@
 		break;
 	case IB_WR_RDMA_WRITE_WITH_IMM:
 		wqe->type = BNXT_QPLIB_SWQE_TYPE_RDMA_WRITE_WITH_IMM;
-		wqe->rdma.imm_data = wr->ex.imm_data;
+		wqe->rdma.imm_data = be32_to_cpu(wr->ex.imm_data);
 		break;
 	case IB_WR_RDMA_READ:
 		wqe->type = BNXT_QPLIB_SWQE_TYPE_RDMA_READ;
@@ -2712,7 +2719,8 @@
 		wr = wr->next;
 	}
 	bnxt_qplib_post_send_db(&qp->qplib_qp);
-	bnxt_ud_qp_hw_stall_workaround(qp);
+	if (!bnxt_qplib_is_chip_gen_p5_p7(qp->rdev->chip_ctx))
+		bnxt_ud_qp_hw_stall_workaround(qp);
 	spin_unlock_irqrestore(&qp->sq_lock, flags);
 	return rc;
 }
@@ -2824,7 +2832,8 @@
 		wr = wr->next;
 	}
 	bnxt_qplib_post_send_db(&qp->qplib_qp);
-	bnxt_ud_qp_hw_stall_workaround(qp);
+	if (!bnxt_qplib_is_chip_gen_p5_p7(qp->rdev->chip_ctx))
+		bnxt_ud_qp_hw_stall_workaround(qp);
 	spin_unlock_irqrestore(&qp->sq_lock, flags);
 
 	return rc;
@@ -3581,7 +3590,7 @@
 	wc->byte_len = orig_cqe->length;
 	wc->qp = &gsi_qp->ib_qp;
 
-	wc->ex.imm_data = orig_cqe->immdata;
+	wc->ex.imm_data = cpu_to_be32(orig_cqe->immdata);
 	wc->src_qp = orig_cqe->src_qp;
 	memcpy(wc->smac, orig_cqe->smac, ETH_ALEN);
 	if (bnxt_re_is_vlan_pkt(orig_cqe, &vlan_id, &sl)) {
@@ -3726,7 +3735,10 @@
 				 (unsigned long)(cqe->qp_handle),
 				 struct bnxt_re_qp, qplib_qp);
 			wc->qp = &qp->ib_qp;
-			wc->ex.imm_data = cqe->immdata;
+			if (cqe->flags & CQ_RES_RC_FLAGS_IMM)
+				wc->ex.imm_data = cpu_to_be32(cqe->immdata);
+			else
+				wc->ex.invalidate_rkey = cqe->invrkey;
 			wc->src_qp = cqe->src_qp;
 			memcpy(wc->smac, cqe->smac, ETH_ALEN);
 			wc->port_num = 1;
@@ -4186,9 +4198,6 @@
 	resp.cqe_sz = sizeof(struct cq_base);
 	resp.max_cqd = dev_attr->max_cq_wqes;
 
-	resp.comp_mask |= BNXT_RE_UCNTX_CMASK_HAVE_MODE;
-	resp.mode = rdev->chip_ctx->modes.wqe_mode;
-
 	if (rdev->chip_ctx->modes.db_push)
 		resp.comp_mask |= BNXT_RE_UCNTX_CMASK_WC_DPI_ENABLED;
 
@@ -4305,9 +4314,10 @@
 	case BNXT_RE_MMAP_TOGGLE_PAGE:
 		/* Driver doesn't expect write access for user space */
 		if (vma->vm_flags & VM_WRITE)
-			return -EFAULT;
-		ret = vm_insert_page(vma, vma->vm_start,
-				     virt_to_page((void *)bnxt_entry->mem_offset));
+			ret = -EFAULT;
+		else
+			ret = vm_insert_page(vma, vma->vm_start,
+					     virt_to_page((void *)bnxt_entry->mem_offset));
 		break;
 	default:
 		ret = -EINVAL;
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/bnxt_re/ib_verbs.h
+++ linux-qcom-6.8.0/drivers/infiniband/hw/bnxt_re/ib_verbs.h
@@ -77,6 +77,7 @@
 	struct bnxt_qplib_srq	qplib_srq;
 	struct ib_umem		*umem;
 	spinlock_t		lock;		/* protect srq */
+	void			*uctx_srq_page;
 };
 
 struct bnxt_re_qp {
@@ -248,6 +249,10 @@
 int bnxt_re_mmap(struct ib_ucontext *context, struct vm_area_struct *vma);
 void bnxt_re_mmap_free(struct rdma_user_mmap_entry *rdma_entry);
 
+static inline u32 __to_ib_port_num(u16 port_id)
+{
+	return (u32)port_id + 1;
+}
 
 unsigned long bnxt_re_lock_cqs(struct bnxt_re_qp *qp);
 void bnxt_re_unlock_cqs(struct bnxt_re_qp *qp, unsigned long flags);
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/bnxt_re/main.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/bnxt_re/main.c
@@ -129,13 +129,13 @@
 	}
 }
 
-static void bnxt_re_set_drv_mode(struct bnxt_re_dev *rdev, u8 mode)
+static void bnxt_re_set_drv_mode(struct bnxt_re_dev *rdev)
 {
 	struct bnxt_qplib_chip_ctx *cctx;
 
 	cctx = rdev->chip_ctx;
-	cctx->modes.wqe_mode = bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx) ?
-			       mode : BNXT_QPLIB_WQE_MODE_STATIC;
+	cctx->modes.wqe_mode = bnxt_qplib_is_chip_gen_p7(rdev->chip_ctx) ?
+			       BNXT_QPLIB_WQE_MODE_VARIABLE : BNXT_QPLIB_WQE_MODE_STATIC;
 	if (bnxt_re_hwrm_qcaps(rdev))
 		dev_err(rdev_to_dev(rdev),
 			"Failed to query hwrm qcaps\n");
@@ -158,7 +158,7 @@
 	kfree(chip_ctx);
 }
 
-static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev, u8 wqe_mode)
+static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev)
 {
 	struct bnxt_qplib_chip_ctx *chip_ctx;
 	struct bnxt_en_dev *en_dev;
@@ -180,12 +180,15 @@
 	rdev->qplib_res.dattr = &rdev->dev_attr;
 	rdev->qplib_res.is_vf = BNXT_EN_VF(en_dev);
 
-	bnxt_re_set_drv_mode(rdev, wqe_mode);
+	bnxt_re_set_drv_mode(rdev);
 
 	bnxt_re_set_db_offset(rdev);
 	rc = bnxt_qplib_map_db_bar(&rdev->qplib_res);
-	if (rc)
+	if (rc) {
+		kfree(rdev->chip_ctx);
+		rdev->chip_ctx = NULL;
 		return rc;
+	}
 
 	if (bnxt_qplib_determine_atomics(en_dev->pdev))
 		ibdev_info(&rdev->ibdev,
@@ -482,6 +485,8 @@
 static void __wait_for_fifo_occupancy_below_th(struct bnxt_re_dev *rdev)
 {
 	u32 read_val, fifo_occup;
+	struct bnxt_qplib_db_pacing_data *pacing_data = rdev->qplib_res.pacing_data;
+	u32 retry_fifo_check = 1000;
 
 	/* loop shouldn't run infintely as the occupancy usually goes
 	 * below pacing algo threshold as soon as pacing kicks in.
@@ -497,6 +502,14 @@
 
 		if (fifo_occup < rdev->qplib_res.pacing_data->pacing_th)
 			break;
+		if (!retry_fifo_check--) {
+			dev_info_once(rdev_to_dev(rdev),
+				      "%s: fifo_occup = 0x%xfifo_max_depth = 0x%x pacing_th = 0x%x\n",
+				      __func__, fifo_occup, pacing_data->fifo_max_depth,
+					pacing_data->pacing_th);
+			break;
+		}
+
 	}
 }
 
@@ -975,12 +988,15 @@
 static int bnxt_re_handle_qp_async_event(struct creq_qp_event *qp_event,
 					 struct bnxt_re_qp *qp)
 {
-	struct bnxt_re_srq *srq = container_of(qp->qplib_qp.srq, struct bnxt_re_srq,
-					       qplib_srq);
 	struct creq_qp_error_notification *err_event;
+	struct bnxt_re_srq *srq = NULL;
 	struct ib_event event = {};
 	unsigned int flags;
 
+	if (qp->qplib_qp.srq)
+		srq =  container_of(qp->qplib_qp.srq, struct bnxt_re_srq,
+				    qplib_srq);
+
 	if (qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR &&
 	    rdma_is_kernel_res(&qp->ib_qp.res)) {
 		flags = bnxt_re_lock_cqs(qp);
@@ -1208,15 +1224,9 @@
 {
 	struct bnxt_re_cq *cq = container_of(handle, struct bnxt_re_cq,
 					     qplib_cq);
-	u32 *cq_ptr;
 
-	if (cq->ib_cq.comp_handler) {
-		if (cq->uctx_cq_page) {
-			cq_ptr = (u32 *)cq->uctx_cq_page;
-			*cq_ptr = cq->qplib_cq.toggle;
-		}
+	if (cq->ib_cq.comp_handler)
 		(*cq->ib_cq.comp_handler)(&cq->ib_cq, cq->ib_cq.cq_context);
-	}
 
 	return 0;
 }
@@ -1384,11 +1394,8 @@
 
 static void bnxt_re_dev_stop(struct bnxt_re_dev *rdev)
 {
-	int mask = IB_QP_STATE;
-	struct ib_qp_attr qp_attr;
 	struct bnxt_re_qp *qp;
 
-	qp_attr.qp_state = IB_QPS_ERR;
 	mutex_lock(&rdev->qp_lock);
 	list_for_each_entry(qp, &rdev->qp_list, list) {
 		/* Modify the state of all QPs except QP1/Shadow QP */
@@ -1396,12 +1403,9 @@
 			if (qp->qplib_qp.state !=
 			    CMDQ_MODIFY_QP_NEW_STATE_RESET &&
 			    qp->qplib_qp.state !=
-			    CMDQ_MODIFY_QP_NEW_STATE_ERR) {
+			    CMDQ_MODIFY_QP_NEW_STATE_ERR)
 				bnxt_re_dispatch_event(&rdev->ibdev, &qp->ib_qp,
 						       1, IB_EVENT_QP_FATAL);
-				bnxt_re_modify_qp(&qp->ib_qp, &qp_attr, mask,
-						  NULL);
-			}
 		}
 	}
 	mutex_unlock(&rdev->qp_lock);
@@ -1586,7 +1590,7 @@
 	schedule_delayed_work(&rdev->worker, msecs_to_jiffies(30000));
 }
 
-static int bnxt_re_dev_init(struct bnxt_re_dev *rdev, u8 wqe_mode)
+static int bnxt_re_dev_init(struct bnxt_re_dev *rdev)
 {
 	struct bnxt_re_ring_attr rattr = {};
 	struct bnxt_qplib_creq_ctx *creq;
@@ -1604,7 +1608,7 @@
 	}
 	set_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
 
-	rc = bnxt_re_setup_chip_ctx(rdev, wqe_mode);
+	rc = bnxt_re_setup_chip_ctx(rdev);
 	if (rc) {
 		bnxt_unregister_dev(rdev->en_dev);
 		clear_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags);
@@ -1756,7 +1760,7 @@
 	return rc;
 }
 
-static int bnxt_re_add_device(struct auxiliary_device *adev, u8 wqe_mode)
+static int bnxt_re_add_device(struct auxiliary_device *adev)
 {
 	struct bnxt_aux_priv *aux_priv =
 		container_of(adev, struct bnxt_aux_priv, aux_dev);
@@ -1773,7 +1777,7 @@
 		goto exit;
 	}
 
-	rc = bnxt_re_dev_init(rdev, wqe_mode);
+	rc = bnxt_re_dev_init(rdev);
 	if (rc)
 		goto re_dev_dealloc;
 
@@ -1903,7 +1907,8 @@
 	int rc;
 
 	mutex_lock(&bnxt_re_mutex);
-	rc = bnxt_re_add_device(adev, BNXT_QPLIB_WQE_MODE_STATIC);
+
+	rc = bnxt_re_add_device(adev);
 	if (rc) {
 		mutex_unlock(&bnxt_re_mutex);
 		return rc;
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/bnxt_re/qplib_fp.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/bnxt_re/qplib_fp.c
@@ -54,6 +54,10 @@
 #include "qplib_rcfw.h"
 #include "qplib_sp.h"
 #include "qplib_fp.h"
+#include <rdma/ib_addr.h>
+#include "bnxt_ulp.h"
+#include "bnxt_re.h"
+#include "ib_verbs.h"
 
 static void __clean_cq(struct bnxt_qplib_cq *cq, u64 qp);
 
@@ -323,6 +327,7 @@
 		case NQ_BASE_TYPE_CQ_NOTIFICATION:
 		{
 			struct nq_cn *nqcne = (struct nq_cn *)nqe;
+			struct bnxt_re_cq *cq_p;
 
 			q_handle = le32_to_cpu(nqcne->cq_handle_low);
 			q_handle |= (u64)le32_to_cpu(nqcne->cq_handle_high)
@@ -333,6 +338,10 @@
 			cq->toggle = (le16_to_cpu(nqe->info10_type) &
 					NQ_CN_TOGGLE_MASK) >> NQ_CN_TOGGLE_SFT;
 			cq->dbinfo.toggle = cq->toggle;
+			cq_p = container_of(cq, struct bnxt_re_cq, qplib_cq);
+			if (cq_p->uctx_cq_page)
+				*((u32 *)cq_p->uctx_cq_page) = cq->toggle;
+
 			bnxt_qplib_armen_db(&cq->dbinfo,
 					    DBC_DBC_TYPE_CQ_ARMENA);
 			spin_lock_bh(&cq->compl_lock);
@@ -347,6 +356,7 @@
 		case NQ_BASE_TYPE_SRQ_EVENT:
 		{
 			struct bnxt_qplib_srq *srq;
+			struct bnxt_re_srq *srq_p;
 			struct nq_srq_event *nqsrqe =
 						(struct nq_srq_event *)nqe;
 
@@ -354,6 +364,12 @@
 			q_handle |= (u64)le32_to_cpu(nqsrqe->srq_handle_high)
 				     << 32;
 			srq = (struct bnxt_qplib_srq *)q_handle;
+			srq->toggle = (le16_to_cpu(nqe->info10_type) & NQ_CN_TOGGLE_MASK)
+				      >> NQ_CN_TOGGLE_SFT;
+			srq->dbinfo.toggle = srq->toggle;
+			srq_p = container_of(srq, struct bnxt_re_srq, qplib_srq);
+			if (srq_p->uctx_srq_page)
+				*((u32 *)srq_p->uctx_srq_page) = srq->toggle;
 			bnxt_qplib_armen_db(&srq->dbinfo,
 					    DBC_DBC_TYPE_SRQ_ARMENA);
 			if (nq->srqn_handler(nq,
@@ -642,13 +658,6 @@
 	rc = bnxt_qplib_alloc_init_hwq(&srq->hwq, &hwq_attr);
 	if (rc)
 		return rc;
-
-	srq->swq = kcalloc(srq->hwq.max_elements, sizeof(*srq->swq),
-			   GFP_KERNEL);
-	if (!srq->swq) {
-		rc = -ENOMEM;
-		goto fail;
-	}
 	srq->dbinfo.flags = 0;
 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
 				 CMDQ_BASE_OPCODE_CREATE_SRQ,
@@ -677,9 +686,17 @@
 	spin_lock_init(&srq->lock);
 	srq->start_idx = 0;
 	srq->last_idx = srq->hwq.max_elements - 1;
-	for (idx = 0; idx < srq->hwq.max_elements; idx++)
-		srq->swq[idx].next_idx = idx + 1;
-	srq->swq[srq->last_idx].next_idx = -1;
+	if (!srq->hwq.is_user) {
+		srq->swq = kcalloc(srq->hwq.max_elements, sizeof(*srq->swq),
+				   GFP_KERNEL);
+		if (!srq->swq) {
+			rc = -ENOMEM;
+			goto fail;
+		}
+		for (idx = 0; idx < srq->hwq.max_elements; idx++)
+			srq->swq[idx].next_idx = idx + 1;
+		srq->swq[srq->last_idx].next_idx = -1;
+	}
 
 	srq->id = le32_to_cpu(resp.xid);
 	srq->dbinfo.hwq = &srq->hwq;
@@ -809,13 +826,13 @@
 {
 	int indx;
 
-	que->swq = kcalloc(que->max_wqe, sizeof(*que->swq), GFP_KERNEL);
+	que->swq = kcalloc(que->max_sw_wqe, sizeof(*que->swq), GFP_KERNEL);
 	if (!que->swq)
 		return -ENOMEM;
 
 	que->swq_start = 0;
-	que->swq_last = que->max_wqe - 1;
-	for (indx = 0; indx < que->max_wqe; indx++)
+	que->swq_last = que->max_sw_wqe - 1;
+	for (indx = 0; indx < que->max_sw_wqe; indx++)
 		que->swq[indx].next_idx = indx + 1;
 	que->swq[que->swq_last].next_idx = 0; /* Make it circular */
 	que->swq_last = 0;
@@ -851,7 +868,7 @@
 	hwq_attr.res = res;
 	hwq_attr.sginfo = &sq->sg_info;
 	hwq_attr.stride = sizeof(struct sq_sge);
-	hwq_attr.depth = bnxt_qplib_get_depth(sq);
+	hwq_attr.depth = bnxt_qplib_get_depth(sq, qp->wqe_mode, false);
 	hwq_attr.type = HWQ_TYPE_QUEUE;
 	rc = bnxt_qplib_alloc_init_hwq(&sq->hwq, &hwq_attr);
 	if (rc)
@@ -879,7 +896,7 @@
 		hwq_attr.res = res;
 		hwq_attr.sginfo = &rq->sg_info;
 		hwq_attr.stride = sizeof(struct sq_sge);
-		hwq_attr.depth = bnxt_qplib_get_depth(rq);
+		hwq_attr.depth = bnxt_qplib_get_depth(rq, qp->wqe_mode, false);
 		hwq_attr.type = HWQ_TYPE_QUEUE;
 		rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr);
 		if (rc)
@@ -983,9 +1000,7 @@
 	u32 tbl_indx;
 	u16 nsge;
 
-	if (res->dattr)
-		qp->dev_cap_flags = res->dattr->dev_cap_flags;
-
+	qp->is_host_msn_tbl = _is_host_msn_table(res->dattr->dev_cap_flags2);
 	sq->dbinfo.flags = 0;
 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
 				 CMDQ_BASE_OPCODE_CREATE_QP,
@@ -1002,7 +1017,7 @@
 			 sizeof(struct sq_psn_search_ext) :
 			 sizeof(struct sq_psn_search);
 
-		if (BNXT_RE_HW_RETX(qp->dev_cap_flags)) {
+		if (qp->is_host_msn_tbl) {
 			psn_sz = sizeof(struct sq_msn_search);
 			qp->msn = 0;
 		}
@@ -1011,12 +1026,18 @@
 	hwq_attr.res = res;
 	hwq_attr.sginfo = &sq->sg_info;
 	hwq_attr.stride = sizeof(struct sq_sge);
-	hwq_attr.depth = bnxt_qplib_get_depth(sq);
+	hwq_attr.depth = bnxt_qplib_get_depth(sq, qp->wqe_mode, true);
 	hwq_attr.aux_stride = psn_sz;
-	hwq_attr.aux_depth = bnxt_qplib_set_sq_size(sq, qp->wqe_mode);
+	hwq_attr.aux_depth = psn_sz ? bnxt_qplib_set_sq_size(sq, qp->wqe_mode)
+				    : 0;
 	/* Update msn tbl size */
-	if (BNXT_RE_HW_RETX(qp->dev_cap_flags) && psn_sz) {
-		hwq_attr.aux_depth = roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, qp->wqe_mode));
+	if (qp->is_host_msn_tbl && psn_sz) {
+		if (qp->wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC)
+			hwq_attr.aux_depth =
+				roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, qp->wqe_mode));
+		else
+			hwq_attr.aux_depth =
+				roundup_pow_of_two(bnxt_qplib_set_sq_size(sq, qp->wqe_mode)) / 2;
 		qp->msn_tbl_sz = hwq_attr.aux_depth;
 		qp->msn = 0;
 	}
@@ -1026,13 +1047,14 @@
 	if (rc)
 		return rc;
 
-	rc = bnxt_qplib_alloc_init_swq(sq);
-	if (rc)
-		goto fail_sq;
-
-	if (psn_sz)
-		bnxt_qplib_init_psn_ptr(qp, psn_sz);
+	if (!sq->hwq.is_user) {
+		rc = bnxt_qplib_alloc_init_swq(sq);
+		if (rc)
+			goto fail_sq;
 
+		if (psn_sz)
+			bnxt_qplib_init_psn_ptr(qp, psn_sz);
+	}
 	req.sq_size = cpu_to_le32(bnxt_qplib_set_sq_size(sq, qp->wqe_mode));
 	pbl = &sq->hwq.pbl[PBL_LVL_0];
 	req.sq_pbl = cpu_to_le64(pbl->pg_map_arr[0]);
@@ -1051,16 +1073,18 @@
 		hwq_attr.res = res;
 		hwq_attr.sginfo = &rq->sg_info;
 		hwq_attr.stride = sizeof(struct sq_sge);
-		hwq_attr.depth = bnxt_qplib_get_depth(rq);
+		hwq_attr.depth = bnxt_qplib_get_depth(rq, qp->wqe_mode, false);
 		hwq_attr.aux_stride = 0;
 		hwq_attr.aux_depth = 0;
 		hwq_attr.type = HWQ_TYPE_QUEUE;
 		rc = bnxt_qplib_alloc_init_hwq(&rq->hwq, &hwq_attr);
 		if (rc)
 			goto sq_swq;
-		rc = bnxt_qplib_alloc_init_swq(rq);
-		if (rc)
-			goto fail_rq;
+		if (!rq->hwq.is_user) {
+			rc = bnxt_qplib_alloc_init_swq(rq);
+			if (rc)
+				goto fail_rq;
+		}
 
 		req.rq_size = cpu_to_le32(rq->max_wqe);
 		pbl = &rq->hwq.pbl[PBL_LVL_0];
@@ -1156,9 +1180,11 @@
 		rq->dbinfo.db = qp->dpi->dbr;
 		rq->dbinfo.max_slot = bnxt_qplib_set_rq_max_slot(rq->wqe_size);
 	}
+	spin_lock_bh(&rcfw->tbl_lock);
 	tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw);
 	rcfw->qp_tbl[tbl_indx].qp_id = qp->id;
 	rcfw->qp_tbl[tbl_indx].qp_handle = (void *)qp;
+	spin_unlock_bh(&rcfw->tbl_lock);
 
 	return 0;
 fail:
@@ -1453,6 +1479,7 @@
 	qp->dest_qpn = le32_to_cpu(sb->dest_qp_id);
 	memcpy(qp->smac, sb->src_mac, 6);
 	qp->vlan_id = le16_to_cpu(sb->vlan_pcp_vlan_dei_vlan_id);
+	qp->port_id = le16_to_cpu(sb->port_id);
 bail:
 	dma_free_coherent(&rcfw->pdev->dev, sbuf.size,
 			  sbuf.sb, sbuf.dma_addr);
@@ -1515,9 +1542,11 @@
 	u32 tbl_indx;
 	int rc;
 
+	spin_lock_bh(&rcfw->tbl_lock);
 	tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw);
 	rcfw->qp_tbl[tbl_indx].qp_id = BNXT_QPLIB_QP_ID_INVALID;
 	rcfw->qp_tbl[tbl_indx].qp_handle = NULL;
+	spin_unlock_bh(&rcfw->tbl_lock);
 
 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
 				 CMDQ_BASE_OPCODE_DESTROY_QP,
@@ -1528,8 +1557,10 @@
 				sizeof(resp), 0);
 	rc = bnxt_qplib_rcfw_send_message(rcfw, &msg);
 	if (rc) {
+		spin_lock_bh(&rcfw->tbl_lock);
 		rcfw->qp_tbl[tbl_indx].qp_id = qp->id;
 		rcfw->qp_tbl[tbl_indx].qp_handle = qp;
+		spin_unlock_bh(&rcfw->tbl_lock);
 		return rc;
 	}
 
@@ -1636,7 +1667,7 @@
 	if (!swq->psn_search)
 		return;
 	/* Handle MSN differently on cap flags  */
-	if (BNXT_RE_HW_RETX(qp->dev_cap_flags)) {
+	if (qp->is_host_msn_tbl) {
 		bnxt_qplib_fill_msn_search(qp, wqe, swq);
 		return;
 	}
@@ -1818,7 +1849,7 @@
 	}
 
 	swq = bnxt_qplib_get_swqe(sq, &wqe_idx);
-	bnxt_qplib_pull_psn_buff(qp, sq, swq, BNXT_RE_HW_RETX(qp->dev_cap_flags));
+	bnxt_qplib_pull_psn_buff(qp, sq, swq, qp->is_host_msn_tbl);
 
 	idx = 0;
 	swq->slot_idx = hwq->prod;
@@ -2008,7 +2039,7 @@
 		rc = -EINVAL;
 		goto done;
 	}
-	if (!BNXT_RE_HW_RETX(qp->dev_cap_flags) || msn_update) {
+	if (!qp->is_host_msn_tbl || msn_update) {
 		swq->next_psn = sq->psn & BTH_PSN_MASK;
 		bnxt_qplib_fill_psn_search(qp, wqe, swq);
 	}
@@ -2491,7 +2522,7 @@
 	}
 	sq = &qp->sq;
 
-	cqe_sq_cons = le16_to_cpu(hwcqe->sq_cons_idx) % sq->max_wqe;
+	cqe_sq_cons = le16_to_cpu(hwcqe->sq_cons_idx) % sq->max_sw_wqe;
 	if (qp->sq.flushed) {
 		dev_dbg(&cq->hwq.pdev->dev,
 			"%s: QP in Flush QP = %p\n", __func__, qp);
@@ -2534,10 +2565,12 @@
 			bnxt_qplib_add_flush_qp(qp);
 		} else {
 			/* Before we complete, do WA 9060 */
-			if (do_wa9060(qp, cq, cq_cons, sq->swq_last,
-				      cqe_sq_cons)) {
-				*lib_qp = qp;
-				goto out;
+			if (!bnxt_qplib_is_chip_gen_p5_p7(qp->cctx)) {
+				if (do_wa9060(qp, cq, cq_cons, sq->swq_last,
+					      cqe_sq_cons)) {
+					*lib_qp = qp;
+					goto out;
+				}
 			}
 			if (swq->flags & SQ_SEND_FLAGS_SIGNAL_COMP) {
 				cqe->status = CQ_REQ_STATUS_OK;
@@ -2881,7 +2914,7 @@
 	cqe_cons = le16_to_cpu(hwcqe->sq_cons_idx);
 	if (cqe_cons == 0xFFFF)
 		goto do_rq;
-	cqe_cons %= sq->max_wqe;
+	cqe_cons %= sq->max_sw_wqe;
 
 	if (qp->sq.flushed) {
 		dev_dbg(&cq->hwq.pdev->dev,
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/bnxt_re/qplib_fp.h
+++ linux-qcom-6.8.0/drivers/infiniband/hw/bnxt_re/qplib_fp.h
@@ -105,6 +105,7 @@
 	struct bnxt_qplib_sg_info	sg_info;
 	u16				eventq_hw_ring_id;
 	spinlock_t			lock; /* protect SRQE link list */
+	u8				toggle;
 };
 
 struct bnxt_qplib_sge {
@@ -113,7 +114,6 @@
 	u32				size;
 };
 
-#define BNXT_QPLIB_QP_MAX_SGL	6
 struct bnxt_qplib_swq {
 	u64				wr_id;
 	int				next_idx;
@@ -153,7 +153,7 @@
 #define BNXT_QPLIB_SWQE_FLAGS_UC_FENCE			BIT(2)
 #define BNXT_QPLIB_SWQE_FLAGS_SOLICIT_EVENT		BIT(3)
 #define BNXT_QPLIB_SWQE_FLAGS_INLINE			BIT(4)
-	struct bnxt_qplib_sge		sg_list[BNXT_QPLIB_QP_MAX_SGL];
+	struct bnxt_qplib_sge		sg_list[BNXT_VAR_MAX_SGE];
 	int				num_sge;
 	/* Max inline data is 96 bytes */
 	u32				inline_len;
@@ -164,12 +164,12 @@
 		/* Send, with imm, inval key */
 		struct {
 			union {
-				__be32	imm_data;
+				u32	imm_data;
 				u32	inv_key;
 			};
 			u32		q_key;
 			u32		dst_qp;
-			u16		avid;
+			u32		avid;
 		} send;
 
 		/* Send Raw Ethernet and QP1 */
@@ -182,7 +182,7 @@
 		/* RDMA write, with imm, read */
 		struct {
 			union {
-				__be32	imm_data;
+				u32	imm_data;
 				u32	inv_key;
 			};
 			u64		remote_va;
@@ -251,6 +251,7 @@
 	struct bnxt_qplib_db_info	dbinfo;
 	struct bnxt_qplib_sg_info	sg_info;
 	u32				max_wqe;
+	u32				max_sw_wqe;
 	u16				wqe_size;
 	u16				q_full_delta;
 	u16				max_sge;
@@ -297,6 +298,7 @@
 	u32				dest_qpn;
 	u8				smac[6];
 	u16				vlan_id;
+	u16				port_id;
 	u8				nw_type;
 	struct bnxt_qplib_ah		ah;
 
@@ -340,7 +342,7 @@
 	struct list_head		rq_flush;
 	u32				msn;
 	u32				msn_tbl_sz;
-	u16				dev_cap_flags;
+	bool				is_host_msn_tbl;
 };
 
 #define BNXT_QPLIB_MAX_CQE_ENTRY_SIZE	sizeof(struct cq_base)
@@ -389,7 +391,7 @@
 	u16				cfa_meta;
 	u64				wr_id;
 	union {
-		__be32			immdata;
+		u32			immdata;
 		u32			invrkey;
 	};
 	u64				qp_handle;
@@ -586,15 +588,22 @@
 	que->swq_start = que->swq[idx].next_idx;
 }
 
-static inline u32 bnxt_qplib_get_depth(struct bnxt_qplib_q *que)
+static inline u32 bnxt_qplib_get_depth(struct bnxt_qplib_q *que, u8 wqe_mode, bool is_sq)
 {
-	return (que->wqe_size * que->max_wqe) / sizeof(struct sq_sge);
+	u32 slots;
+
+	/* Queue depth is the number of slots. */
+	slots = (que->wqe_size * que->max_wqe) / sizeof(struct sq_sge);
+	/* For variable WQE mode, need to align the slots to 256 */
+	if (wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE && is_sq)
+		slots = ALIGN(slots, BNXT_VAR_MAX_SLOT_ALIGN);
+	return slots;
 }
 
 static inline u32 bnxt_qplib_set_sq_size(struct bnxt_qplib_q *que, u8 wqe_mode)
 {
 	return (wqe_mode == BNXT_QPLIB_WQE_MODE_STATIC) ?
-		que->max_wqe : bnxt_qplib_get_depth(que);
+		que->max_wqe : bnxt_qplib_get_depth(que, wqe_mode, true);
 }
 
 static inline u32 bnxt_qplib_set_sq_max_slot(u8 wqe_mode)
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c
@@ -290,7 +290,6 @@
 	struct bnxt_qplib_hwq *hwq;
 	u32 sw_prod, cmdq_prod;
 	struct pci_dev *pdev;
-	unsigned long flags;
 	u16 cookie;
 	u8 *preq;
 
@@ -301,7 +300,7 @@
 	/* Cmdq are in 16-byte units, each request can consume 1 or more
 	 * cmdqe
 	 */
-	spin_lock_irqsave(&hwq->lock, flags);
+	spin_lock_bh(&hwq->lock);
 	required_slots = bnxt_qplib_get_cmd_slots(msg->req);
 	free_slots = HWQ_FREE_SLOTS(hwq);
 	cookie = cmdq->seq_num & RCFW_MAX_COOKIE_VALUE;
@@ -311,7 +310,7 @@
 		dev_info_ratelimited(&pdev->dev,
 				     "CMDQ is full req/free %d/%d!",
 				     required_slots, free_slots);
-		spin_unlock_irqrestore(&hwq->lock, flags);
+		spin_unlock_bh(&hwq->lock);
 		return -EAGAIN;
 	}
 	if (msg->block)
@@ -367,7 +366,7 @@
 	wmb();
 	writel(cmdq_prod, cmdq->cmdq_mbox.prod);
 	writel(RCFW_CMDQ_TRIG_VAL, cmdq->cmdq_mbox.db);
-	spin_unlock_irqrestore(&hwq->lock, flags);
+	spin_unlock_bh(&hwq->lock);
 	/* Return the CREQ response pointer */
 	return 0;
 }
@@ -425,7 +424,8 @@
 
 	/* Prevent posting if f/w is not in a state to process */
 	if (test_bit(ERR_DEVICE_DETACHED, &rcfw->cmdq.flags))
-		return bnxt_qplib_map_rc(opcode);
+		return -ENXIO;
+
 	if (test_bit(FIRMWARE_STALL_DETECTED, &cmdq->flags))
 		return -ETIMEDOUT;
 
@@ -486,7 +486,6 @@
 {
 	struct creq_qp_event *evnt = (struct creq_qp_event *)msg->resp;
 	struct bnxt_qplib_crsqe *crsqe;
-	unsigned long flags;
 	u16 cookie;
 	int rc;
 	u8 opcode;
@@ -495,7 +494,7 @@
 
 	rc = __send_message_basic_sanity(rcfw, msg, opcode);
 	if (rc)
-		return rc;
+		return rc == -ENXIO ? bnxt_qplib_map_rc(opcode) : rc;
 
 	rc = __send_message(rcfw, msg, opcode);
 	if (rc)
@@ -512,12 +511,12 @@
 		rc = __poll_for_resp(rcfw, cookie);
 
 	if (rc) {
-		spin_lock_irqsave(&rcfw->cmdq.hwq.lock, flags);
+		spin_lock_bh(&rcfw->cmdq.hwq.lock);
 		crsqe = &rcfw->crsqe_tbl[cookie];
 		crsqe->is_waiter_alive = false;
 		if (rc == -ENODEV)
 			set_bit(FIRMWARE_STALL_DETECTED, &rcfw->cmdq.flags);
-		spin_unlock_irqrestore(&rcfw->cmdq.hwq.lock, flags);
+		spin_unlock_bh(&rcfw->cmdq.hwq.lock);
 		return -ETIMEDOUT;
 	}
 
@@ -525,7 +524,7 @@
 		/* failed with status */
 		dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x status %#x\n",
 			cookie, opcode, evnt->status);
-		rc = -EFAULT;
+		rc = -EIO;
 	}
 
 	return rc;
@@ -628,7 +627,6 @@
 	u16 cookie, blocked = 0;
 	bool is_waiter_alive;
 	struct pci_dev *pdev;
-	unsigned long flags;
 	u32 wait_cmds = 0;
 	int rc = 0;
 
@@ -637,17 +635,21 @@
 	case CREQ_QP_EVENT_EVENT_QP_ERROR_NOTIFICATION:
 		err_event = (struct creq_qp_error_notification *)qp_event;
 		qp_id = le32_to_cpu(err_event->xid);
+		spin_lock(&rcfw->tbl_lock);
 		tbl_indx = map_qp_id_to_tbl_indx(qp_id, rcfw);
 		qp = rcfw->qp_tbl[tbl_indx].qp_handle;
+		if (!qp) {
+			spin_unlock(&rcfw->tbl_lock);
+			break;
+		}
+		bnxt_qplib_mark_qp_error(qp);
+		rc = rcfw->creq.aeq_handler(rcfw, qp_event, qp);
+		spin_unlock(&rcfw->tbl_lock);
 		dev_dbg(&pdev->dev, "Received QP error notification\n");
 		dev_dbg(&pdev->dev,
 			"qpid 0x%x, req_err=0x%x, resp_err=0x%x\n",
 			qp_id, err_event->req_err_state_reason,
 			err_event->res_err_state_reason);
-		if (!qp)
-			break;
-		bnxt_qplib_mark_qp_error(qp);
-		rc = rcfw->creq.aeq_handler(rcfw, qp_event, qp);
 		break;
 	default:
 		/*
@@ -659,8 +661,7 @@
 		 *
 		 */
 
-		spin_lock_irqsave_nested(&hwq->lock, flags,
-					 SINGLE_DEPTH_NESTING);
+		spin_lock_nested(&hwq->lock, SINGLE_DEPTH_NESTING);
 		cookie = le16_to_cpu(qp_event->cookie);
 		blocked = cookie & RCFW_CMD_IS_BLOCKING;
 		cookie &= RCFW_MAX_COOKIE_VALUE;
@@ -672,7 +673,7 @@
 			dev_info(&pdev->dev,
 				 "rcfw timedout: cookie = %#x, free_slots = %d",
 				 cookie, crsqe->free_slots);
-			spin_unlock_irqrestore(&hwq->lock, flags);
+			spin_unlock(&hwq->lock);
 			return rc;
 		}
 
@@ -720,7 +721,7 @@
 			__destroy_timedout_ah(rcfw,
 					      (struct creq_create_ah_resp *)
 					      qp_event);
-		spin_unlock_irqrestore(&hwq->lock, flags);
+		spin_unlock(&hwq->lock);
 	}
 	*num_wait += wait_cmds;
 	return rc;
@@ -734,12 +735,11 @@
 	u32 type, budget = CREQ_ENTRY_POLL_BUDGET;
 	struct bnxt_qplib_hwq *hwq = &creq->hwq;
 	struct creq_base *creqe;
-	unsigned long flags;
 	u32 num_wakeup = 0;
 	u32 hw_polled = 0;
 
 	/* Service the CREQ until budget is over */
-	spin_lock_irqsave(&hwq->lock, flags);
+	spin_lock_bh(&hwq->lock);
 	while (budget > 0) {
 		creqe = bnxt_qplib_get_qe(hwq, hwq->cons, NULL);
 		if (!CREQ_CMP_VALID(creqe, creq->creq_db.dbinfo.flags))
@@ -782,7 +782,7 @@
 	if (hw_polled)
 		bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo,
 				      rcfw->res->cctx, true);
-	spin_unlock_irqrestore(&hwq->lock, flags);
+	spin_unlock_bh(&hwq->lock);
 	if (num_wakeup)
 		wake_up_nr(&rcfw->cmdq.waitq, num_wakeup);
 }
@@ -978,6 +978,7 @@
 			       GFP_KERNEL);
 	if (!rcfw->qp_tbl)
 		goto fail;
+	spin_lock_init(&rcfw->tbl_lock);
 
 	rcfw->max_timeout = res->cctx->hwrm_cmd_max_timeout;
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
+++ linux-qcom-6.8.0/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h
@@ -224,6 +224,8 @@
 	struct bnxt_qplib_crsqe		*crsqe_tbl;
 	int qp_tbl_size;
 	struct bnxt_qplib_qp_node *qp_tbl;
+	/* To synchronize the qp-handle hash table */
+	spinlock_t			tbl_lock;
 	u64 oos_prev;
 	u32 init_oos_stats;
 	u32 cmdq_depth;
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/bnxt_re/qplib_res.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/bnxt_re/qplib_res.c
@@ -244,6 +244,8 @@
 			sginfo.pgsize = npde * pg_size;
 			sginfo.npages = 1;
 			rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo);
+			if (rc)
+				goto fail;
 
 			/* Alloc PBL pages */
 			sginfo.npages = npbl;
@@ -255,22 +257,9 @@
 			dst_virt_ptr =
 				(dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr;
 			src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr;
-			if (hwq_attr->type == HWQ_TYPE_MR) {
-			/* For MR it is expected that we supply only 1 contigous
-			 * page i.e only 1 entry in the PDL that will contain
-			 * all the PBLs for the user supplied memory region
-			 */
-				for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count;
-				     i++)
-					dst_virt_ptr[0][i] = src_phys_ptr[i] |
-						flag;
-			} else {
-				for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count;
-				     i++)
-					dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] =
-						src_phys_ptr[i] |
-						PTU_PDE_VALID;
-			}
+			for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++)
+				dst_virt_ptr[0][i] = src_phys_ptr[i] | flag;
+
 			/* Alloc or init PTEs */
 			rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_2],
 					 hwq_attr->sginfo);
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/bnxt_re/qplib_res.h
+++ linux-qcom-6.8.0/drivers/infiniband/hw/bnxt_re/qplib_res.h
@@ -554,6 +554,12 @@
 
 #define BNXT_RE_HW_RETX(a) _is_hw_retx_supported((a))
 
+static inline bool _is_host_msn_table(u16 dev_cap_ext_flags2)
+{
+	return (dev_cap_ext_flags2 & CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_MASK) ==
+		CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_HOST_MSN_TABLE;
+}
+
 static inline u8 bnxt_qplib_dbr_pacing_en(struct bnxt_qplib_chip_ctx *cctx)
 {
 	return cctx->modes.dbr_pacing;
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/bnxt_re/qplib_sp.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/bnxt_re/qplib_sp.c
@@ -95,11 +95,13 @@
 	struct bnxt_qplib_cmdqmsg msg = {};
 	struct creq_query_func_resp_sb *sb;
 	struct bnxt_qplib_rcfw_sbuf sbuf;
+	struct bnxt_qplib_chip_ctx *cctx;
 	struct cmdq_query_func req = {};
 	u8 *tqm_alloc;
 	int i, rc;
 	u32 temp;
 
+	cctx = rcfw->res->cctx;
 	bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req,
 				 CMDQ_BASE_OPCODE_QUERY_FUNC,
 				 sizeof(req));
@@ -127,16 +129,25 @@
 	attr->max_qp_init_rd_atom =
 		sb->max_qp_init_rd_atom > BNXT_QPLIB_MAX_OUT_RD_ATOM ?
 		BNXT_QPLIB_MAX_OUT_RD_ATOM : sb->max_qp_init_rd_atom;
-	attr->max_qp_wqes = le16_to_cpu(sb->max_qp_wr);
-	/*
-	 * 128 WQEs needs to be reserved for the HW (8916). Prevent
-	 * reporting the max number
-	 */
-	attr->max_qp_wqes -= BNXT_QPLIB_RESERVED_QP_WRS + 1;
-	attr->max_qp_sges = bnxt_qplib_is_chip_gen_p5_p7(rcfw->res->cctx) ?
-			    6 : sb->max_sge;
+	attr->max_qp_wqes = le16_to_cpu(sb->max_qp_wr) - 1;
+	if (!bnxt_qplib_is_chip_gen_p5_p7(rcfw->res->cctx)) {
+		/*
+		 * 128 WQEs needs to be reserved for the HW (8916). Prevent
+		 * reporting the max number on legacy devices
+		 */
+		attr->max_qp_wqes -= BNXT_QPLIB_RESERVED_QP_WRS + 1;
+	}
+
+	/* Adjust for max_qp_wqes for variable wqe */
+	if (cctx->modes.wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE)
+		attr->max_qp_wqes = BNXT_VAR_MAX_WQE - 1;
+
+	attr->max_qp_sges = cctx->modes.wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE ?
+			    min_t(u32, sb->max_sge_var_wqe, BNXT_VAR_MAX_SGE) : 6;
 	attr->max_cq = le32_to_cpu(sb->max_cq);
 	attr->max_cq_wqes = le32_to_cpu(sb->max_cqe);
+	if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx))
+		attr->max_cq_wqes = min_t(u32, BNXT_QPLIB_MAX_CQ_WQES, attr->max_cq_wqes);
 	attr->max_cq_sges = attr->max_qp_sges;
 	attr->max_mr = le32_to_cpu(sb->max_mr);
 	attr->max_mw = le32_to_cpu(sb->max_mw);
@@ -154,8 +165,16 @@
 	if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx))
 		attr->l2_db_size = (sb->l2_db_space_size + 1) *
 				    (0x01 << RCFW_DBR_BASE_PAGE_SHIFT);
-	attr->max_sgid = BNXT_QPLIB_NUM_GIDS_SUPPORTED;
+	/*
+	 * Read the max gid supported by HW.
+	 * For each entry in HW  GID in HW table, we consume 2
+	 * GID entries in the kernel GID table.  So max_gid reported
+	 * to stack can be up to twice the value reported by the HW, up to 256 gids.
+	 */
+	attr->max_sgid = le32_to_cpu(sb->max_gid);
+	attr->max_sgid = min_t(u32, BNXT_QPLIB_NUM_GIDS_SUPPORTED, 2 * attr->max_sgid);
 	attr->dev_cap_flags = le16_to_cpu(sb->dev_cap_flags);
+	attr->dev_cap_flags2 = le16_to_cpu(sb->dev_cap_ext_flags_2);
 
 	bnxt_qplib_query_version(rcfw, attr->fw_ver);
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/bnxt_re/qplib_sp.h
+++ linux-qcom-6.8.0/drivers/infiniband/hw/bnxt_re/qplib_sp.h
@@ -40,6 +40,7 @@
 #ifndef __BNXT_QPLIB_SP_H__
 #define __BNXT_QPLIB_SP_H__
 
+#include <rdma/bnxt_re-abi.h>
 #define BNXT_QPLIB_RESERVED_QP_WRS	128
 
 struct bnxt_qplib_dev_attr {
@@ -55,6 +56,7 @@
 	u32				max_qp_wqes;
 	u32				max_qp_sges;
 	u32				max_cq;
+#define BNXT_QPLIB_MAX_CQ_WQES          0xfffff
 	u32				max_cq_wqes;
 	u32				max_cq_sges;
 	u32				max_mr;
@@ -72,6 +74,7 @@
 	u8				tqm_alloc_reqs[MAX_TQM_ALLOC_REQ];
 	bool				is_atomic;
 	u16                             dev_cap_flags;
+	u16                             dev_cap_flags2;
 	u32                             max_dpi;
 };
 
@@ -350,4 +353,11 @@
 int bnxt_qplib_modify_cc(struct bnxt_qplib_res *res,
 			 struct bnxt_qplib_cc_param *cc_param);
 
+#define BNXT_VAR_MAX_WQE       4352
+#define BNXT_VAR_MAX_SLOT_ALIGN 256
+#define BNXT_VAR_MAX_SGE        13
+#define BNXT_RE_MAX_RQ_WQES     65536
+
+#define BNXT_STATIC_MAX_SGE	6
+
 #endif /* __BNXT_QPLIB_SP_H__*/
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/bnxt_re/roce_hsi.h
+++ linux-qcom-6.8.0/drivers/infiniband/hw/bnxt_re/roce_hsi.h
@@ -2157,8 +2157,36 @@
 	__le32	tqm_alloc_reqs[12];
 	__le32	max_dpi;
 	u8	max_sge_var_wqe;
-	u8	reserved_8;
+	u8	dev_cap_ext_flags;
+	#define CREQ_QUERY_FUNC_RESP_SB_ATOMIC_OPS_NOT_SUPPORTED         0x1UL
+	#define CREQ_QUERY_FUNC_RESP_SB_DRV_VERSION_RGTR_SUPPORTED       0x2UL
+	#define CREQ_QUERY_FUNC_RESP_SB_CREATE_QP_BATCH_SUPPORTED        0x4UL
+	#define CREQ_QUERY_FUNC_RESP_SB_DESTROY_QP_BATCH_SUPPORTED       0x8UL
+	#define CREQ_QUERY_FUNC_RESP_SB_ROCE_STATS_EXT_CTX_SUPPORTED     0x10UL
+	#define CREQ_QUERY_FUNC_RESP_SB_CREATE_SRQ_SGE_SUPPORTED         0x20UL
+	#define CREQ_QUERY_FUNC_RESP_SB_FIXED_SIZE_WQE_DISABLED          0x40UL
+	#define CREQ_QUERY_FUNC_RESP_SB_DCN_SUPPORTED                    0x80UL
 	__le16	max_inline_data_var_wqe;
+	__le32	start_qid;
+	u8	max_msn_table_size;
+	u8	reserved8_1;
+	__le16	dev_cap_ext_flags_2;
+	#define CREQ_QUERY_FUNC_RESP_SB_OPTIMIZE_MODIFY_QP_SUPPORTED             0x1UL
+	#define CREQ_QUERY_FUNC_RESP_SB_CHANGE_UDP_SRC_PORT_WQE_SUPPORTED        0x2UL
+	#define CREQ_QUERY_FUNC_RESP_SB_CQ_COALESCING_SUPPORTED                  0x4UL
+	#define CREQ_QUERY_FUNC_RESP_SB_MEMORY_REGION_RO_SUPPORTED               0x8UL
+	#define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_MASK          0x30UL
+	#define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_SFT           4
+	#define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_HOST_PSN_TABLE  (0x0UL << 4)
+	#define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_HOST_MSN_TABLE  (0x1UL << 4)
+	#define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_IQM_MSN_TABLE   (0x2UL << 4)
+	#define CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_LAST	\
+			CREQ_QUERY_FUNC_RESP_SB_REQ_RETRANSMISSION_SUPPORT_IQM_MSN_TABLE
+	__le16	max_xp_qp_size;
+	__le16	create_qp_batch_size;
+	__le16	destroy_qp_batch_size;
+	__le16	reserved16;
+	__le64	reserved64;
 };
 
 /* cmdq_set_func_resources (size:448b/56B) */
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/cxgb4/cm.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/cxgb4/cm.c
@@ -1222,6 +1222,8 @@
 	int ret;
 
 	ep = lookup_atid(t, atid);
+	if (!ep)
+		return -EINVAL;
 
 	pr_debug("ep %p tid %u snd_isn %u rcv_isn %u\n", ep, tid,
 		 be32_to_cpu(req->snd_isn), be32_to_cpu(req->rcv_isn));
@@ -2084,7 +2086,7 @@
 	err = -ENOMEM;
 	if (n->dev->flags & IFF_LOOPBACK) {
 		if (iptype == 4)
-			pdev = ip_dev_find(&init_net, *(__be32 *)peer_ip);
+			pdev = __ip_dev_find(&init_net, *(__be32 *)peer_ip, false);
 		else if (IS_ENABLED(CONFIG_IPV6))
 			for_each_netdev(&init_net, pdev) {
 				if (ipv6_chk_addr(&init_net,
@@ -2099,12 +2101,12 @@
 			err = -ENODEV;
 			goto out;
 		}
+		if (is_vlan_dev(pdev))
+			pdev = vlan_dev_real_dev(pdev);
 		ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t,
 					n, pdev, rt_tos2priority(tos));
-		if (!ep->l2t) {
-			dev_put(pdev);
+		if (!ep->l2t)
 			goto out;
-		}
 		ep->mtu = pdev->mtu;
 		ep->tx_chan = cxgb4_port_chan(pdev);
 		ep->smac_idx = ((struct port_info *)netdev_priv(pdev))->smt_idx;
@@ -2117,7 +2119,6 @@
 		ep->rss_qid = cdev->rdev.lldi.rxq_ids[
 			cxgb4_port_idx(pdev) * step];
 		set_tcp_window(ep, (struct port_info *)netdev_priv(pdev));
-		dev_put(pdev);
 	} else {
 		pdev = get_real_dev(n->dev);
 		ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t,
@@ -2279,6 +2280,9 @@
 	int ret = 0;
 
 	ep = lookup_atid(t, atid);
+	if (!ep)
+		return -EINVAL;
+
 	la = (struct sockaddr_in *)&ep->com.local_addr;
 	ra = (struct sockaddr_in *)&ep->com.remote_addr;
 	la6 = (struct sockaddr_in6 *)&ep->com.local_addr;
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/cxgb4/device.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/cxgb4/device.c
@@ -1114,8 +1114,10 @@
 	 * The math here assumes sizeof cpl_pass_accept_req >= sizeof
 	 * cpl_rx_pkt.
 	 */
-	skb = alloc_skb(gl->tot_len + sizeof(struct cpl_pass_accept_req) +
-			sizeof(struct rss_header) - pktshift, GFP_ATOMIC);
+	skb = alloc_skb(size_add(gl->tot_len,
+				 sizeof(struct cpl_pass_accept_req) +
+				 sizeof(struct rss_header)) - pktshift,
+			GFP_ATOMIC);
 	if (unlikely(!skb))
 		return NULL;
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/cxgb4/provider.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/cxgb4/provider.c
@@ -474,6 +474,7 @@
 	.fill_res_cq_entry = c4iw_fill_res_cq_entry,
 	.fill_res_cm_id_entry = c4iw_fill_res_cm_id_entry,
 	.fill_res_mr_entry = c4iw_fill_res_mr_entry,
+	.fill_res_qp_entry = c4iw_fill_res_qp_entry,
 	.get_dev_fw_str = get_dev_fw_str,
 	.get_dma_mr = c4iw_get_dma_mr,
 	.get_hw_stats = c4iw_get_mib,
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/cxgb4/qp.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/cxgb4/qp.c
@@ -1599,6 +1599,7 @@
 	int count;
 	int rq_flushed = 0, sq_flushed;
 	unsigned long flag;
+	struct ib_event ev;
 
 	pr_debug("qhp %p rchp %p schp %p\n", qhp, rchp, schp);
 
@@ -1607,6 +1608,13 @@
 	if (schp != rchp)
 		spin_lock(&schp->lock);
 	spin_lock(&qhp->lock);
+	if (qhp->srq && qhp->attr.state == C4IW_QP_STATE_ERROR &&
+	    qhp->ibqp.event_handler) {
+		ev.device = qhp->ibqp.device;
+		ev.element.qp = &qhp->ibqp;
+		ev.event = IB_EVENT_QP_LAST_WQE_REACHED;
+		qhp->ibqp.event_handler(&ev, qhp->ibqp.qp_context);
+	}
 
 	if (qhp->wq.flushed) {
 		spin_unlock(&qhp->lock);
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/efa/efa_com.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/efa/efa_com.c
@@ -1,6 +1,6 @@
 // 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"
@@ -406,8 +406,8 @@
 	return comp_ctx;
 }
 
-static void efa_com_handle_single_admin_completion(struct efa_com_admin_queue *aq,
-						   struct efa_admin_acq_entry *cqe)
+static int efa_com_handle_single_admin_completion(struct efa_com_admin_queue *aq,
+						  struct efa_admin_acq_entry *cqe)
 {
 	struct efa_comp_ctx *comp_ctx;
 	u16 cmd_id;
@@ -416,11 +416,11 @@
 			 EFA_ADMIN_ACQ_COMMON_DESC_COMMAND_ID);
 
 	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,
-			  "comp_ctx is NULL. Changing the admin queue running state\n");
-		clear_bit(EFA_AQ_STATE_RUNNING_BIT, &aq->state);
-		return;
+			  "Received completion with unexpected command id[%d], sq producer: %d, sq consumer: %d, cq consumer: %d\n",
+			  cmd_id, aq->sq.pc, aq->sq.cc, aq->cq.cc);
+		return -EINVAL;
 	}
 
 	comp_ctx->status = EFA_CMD_COMPLETED;
@@ -428,14 +428,17 @@
 
 	if (!test_bit(EFA_AQ_STATE_POLLING_BIT, &aq->state))
 		complete(&comp_ctx->wait_event);
+
+	return 0;
 }
 
 static void efa_com_handle_admin_completion(struct efa_com_admin_queue *aq)
 {
 	struct efa_admin_acq_entry *cqe;
 	u16 queue_size_mask;
-	u16 comp_num = 0;
+	u16 comp_cmds = 0;
 	u8 phase;
+	int err;
 	u16 ci;
 
 	queue_size_mask = aq->depth - 1;
@@ -453,10 +456,12 @@
 		 * phase bit was validated
 		 */
 		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++;
-		comp_num++;
 		if (ci == aq->depth) {
 			ci = 0;
 			phase = !phase;
@@ -465,10 +470,9 @@
 		cqe = &aq->cq.entries[ci];
 	}
 
-	aq->cq.cc += comp_num;
 	aq->cq.phase = phase;
-	aq->sq.cc += comp_num;
-	atomic64_add(comp_num, &aq->stats.completed_cmd);
+	aq->sq.cc += comp_cmds;
+	atomic64_add(comp_cmds, &aq->stats.completed_cmd);
 }
 
 static int efa_com_comp_status_to_errno(u8 comp_status)
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/erdma/erdma_cm.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/erdma/erdma_cm.c
@@ -705,7 +705,6 @@
 		erdma_cancel_mpatimer(new_cep);
 
 		erdma_cep_put(new_cep);
-		new_cep->sock = NULL;
 	}
 
 	if (new_s) {
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/erdma/erdma_verbs.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/erdma/erdma_verbs.c
@@ -1540,11 +1540,31 @@
 	return ret;
 }
 
+static enum ib_qp_state query_qp_state(struct erdma_qp *qp)
+{
+	switch (qp->attrs.state) {
+	case ERDMA_QP_STATE_IDLE:
+		return IB_QPS_INIT;
+	case ERDMA_QP_STATE_RTR:
+		return IB_QPS_RTR;
+	case ERDMA_QP_STATE_RTS:
+		return IB_QPS_RTS;
+	case ERDMA_QP_STATE_CLOSING:
+		return IB_QPS_ERR;
+	case ERDMA_QP_STATE_TERMINATE:
+		return IB_QPS_ERR;
+	case ERDMA_QP_STATE_ERROR:
+		return IB_QPS_ERR;
+	default:
+		return IB_QPS_ERR;
+	}
+}
+
 int erdma_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
 		   int qp_attr_mask, struct ib_qp_init_attr *qp_init_attr)
 {
-	struct erdma_qp *qp;
 	struct erdma_dev *dev;
+	struct erdma_qp *qp;
 
 	if (ibqp && qp_attr && qp_init_attr) {
 		qp = to_eqp(ibqp);
@@ -1571,6 +1591,9 @@
 
 	qp_init_attr->cap = qp_attr->cap;
 
+	qp_attr->qp_state = query_qp_state(qp);
+	qp_attr->cur_qp_state = query_qp_state(qp);
+
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/Kconfig
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/Kconfig
@@ -1,21 +1,11 @@
 # SPDX-License-Identifier: GPL-2.0-only
-config INFINIBAND_HNS
-	tristate "HNS RoCE Driver"
-	depends on NET_VENDOR_HISILICON
-	depends on ARM64 || (COMPILE_TEST && 64BIT)
-	depends on (HNS_DSAF && HNS_ENET) || HNS3
-	help
-	  This is a RoCE/RDMA driver for the Hisilicon RoCE engine.
-
-	  To compile HIP08 driver as module, choose M here.
-
 config INFINIBAND_HNS_HIP08
-	bool "Hisilicon Hip08 Family RoCE support"
-	depends on INFINIBAND_HNS && PCI && HNS3
-	depends on INFINIBAND_HNS=m || HNS3=y
+	tristate "Hisilicon Hip08 Family RoCE support"
+	depends on ARM64 || (COMPILE_TEST && 64BIT)
+	depends on PCI && HNS3
 	help
 	  RoCE driver support for Hisilicon RoCE engine in Hisilicon Hip08 SoC.
 	  The RoCE engine is a PCI device.
 
-	  To compile this driver, choose Y here: if INFINIBAND_HNS is m, this
-	  module will be called hns-roce-hw-v2.
+	  To compile this driver, choose M here. This module will be called
+	  hns-roce-hw-v2.
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/Makefile
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/Makefile
@@ -5,12 +5,9 @@
 
 ccflags-y :=  -I $(srctree)/drivers/net/ethernet/hisilicon/hns3
 
-hns-roce-objs := hns_roce_main.o hns_roce_cmd.o hns_roce_pd.o \
+hns-roce-hw-v2-objs := hns_roce_main.o hns_roce_cmd.o hns_roce_pd.o \
 	hns_roce_ah.o hns_roce_hem.o hns_roce_mr.o hns_roce_qp.o \
 	hns_roce_cq.o hns_roce_alloc.o hns_roce_db.o hns_roce_srq.o hns_roce_restrack.o \
-	hns_roce_debugfs.o
+	hns_roce_debugfs.o hns_roce_hw_v2.o
 
-ifdef CONFIG_INFINIBAND_HNS_HIP08
-hns-roce-hw-v2-objs := hns_roce_hw_v2.o $(hns-roce-objs)
-obj-$(CONFIG_INFINIBAND_HNS) += hns-roce-hw-v2.o
-endif
+obj-$(CONFIG_INFINIBAND_HNS_HIP08) += hns-roce-hw-v2.o
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/hns_roce_ah.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/hns_roce_ah.c
@@ -62,8 +62,10 @@
 	int ret = 0;
 	u32 max_sl;
 
-	if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08 && udata)
-		return -EOPNOTSUPP;
+	if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08 && udata) {
+		ret = -EOPNOTSUPP;
+		goto err_out;
+	}
 
 	ah->av.port = rdma_ah_get_port_num(ah_attr);
 	ah->av.gid_index = grh->sgid_index;
@@ -82,7 +84,8 @@
 		ibdev_err_ratelimited(&hr_dev->ib_dev,
 				      "failed to set sl, sl (%u) shouldn't be larger than %u.\n",
 				      ah->av.sl, max_sl);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto err_out;
 	}
 
 	memcpy(ah->av.dgid, grh->dgid.raw, HNS_ROCE_GID_SIZE);
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/hns_roce_alloc.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/hns_roce_alloc.c
@@ -153,8 +153,7 @@
 	return total;
 }
 
-int hns_roce_get_umem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
-			   int buf_cnt, struct ib_umem *umem,
+int hns_roce_get_umem_bufs(dma_addr_t *bufs, int buf_cnt, struct ib_umem *umem,
 			   unsigned int page_shift)
 {
 	struct ib_block_iter biter;
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/hns_roce_cq.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/hns_roce_cq.c
@@ -133,14 +133,12 @@
 	struct hns_roce_cq_table *cq_table = &hr_dev->cq_table;
 	struct ib_device *ibdev = &hr_dev->ib_dev;
 	u64 mtts[MTT_MIN_COUNT] = {};
-	dma_addr_t dma_handle;
 	int ret;
 
-	ret = hns_roce_mtr_find(hr_dev, &hr_cq->mtr, 0, mtts, ARRAY_SIZE(mtts),
-				&dma_handle);
-	if (!ret) {
+	ret = hns_roce_mtr_find(hr_dev, &hr_cq->mtr, 0, mtts, ARRAY_SIZE(mtts));
+	if (ret) {
 		ibdev_err(ibdev, "failed to find CQ mtr, ret = %d.\n", ret);
-		return -EINVAL;
+		return ret;
 	}
 
 	/* Get CQC memory HEM(Hardware Entry Memory) table */
@@ -151,20 +149,21 @@
 		return ret;
 	}
 
-	ret = xa_err(xa_store(&cq_table->array, hr_cq->cqn, hr_cq, GFP_KERNEL));
+	ret = xa_err(xa_store_irq(&cq_table->array, hr_cq->cqn, hr_cq, GFP_KERNEL));
 	if (ret) {
 		ibdev_err(ibdev, "failed to xa_store CQ, ret = %d.\n", ret);
 		goto err_put;
 	}
 
-	ret = hns_roce_create_cqc(hr_dev, hr_cq, mtts, dma_handle);
+	ret = hns_roce_create_cqc(hr_dev, hr_cq, mtts,
+				  hns_roce_get_mtr_ba(&hr_cq->mtr));
 	if (ret)
 		goto err_xa;
 
 	return 0;
 
 err_xa:
-	xa_erase(&cq_table->array, hr_cq->cqn);
+	xa_erase_irq(&cq_table->array, hr_cq->cqn);
 err_put:
 	hns_roce_table_put(hr_dev, &cq_table->table, hr_cq->cqn);
 
@@ -180,10 +179,10 @@
 	ret = hns_roce_destroy_hw_ctx(hr_dev, HNS_ROCE_CMD_DESTROY_CQC,
 				      hr_cq->cqn);
 	if (ret)
-		dev_err(dev, "DESTROY_CQ failed (%d) for CQN %06lx\n", ret,
-			hr_cq->cqn);
+		dev_err_ratelimited(dev, "DESTROY_CQ failed (%d) for CQN %06lx\n",
+				    ret, hr_cq->cqn);
 
-	xa_erase(&cq_table->array, hr_cq->cqn);
+	xa_erase_irq(&cq_table->array, hr_cq->cqn);
 
 	/* Waiting interrupt process procedure carried out */
 	synchronize_irq(hr_dev->eq_table.eq[hr_cq->vector].irq);
@@ -477,13 +476,6 @@
 	struct ib_event event;
 	struct ib_cq *ibcq;
 
-	hr_cq = xa_load(&hr_dev->cq_table.array,
-			cqn & (hr_dev->caps.num_cqs - 1));
-	if (!hr_cq) {
-		dev_warn(dev, "async event for bogus CQ 0x%06x\n", cqn);
-		return;
-	}
-
 	if (event_type != HNS_ROCE_EVENT_TYPE_CQ_ID_INVALID &&
 	    event_type != HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR &&
 	    event_type != HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW) {
@@ -492,7 +484,16 @@
 		return;
 	}
 
-	refcount_inc(&hr_cq->refcount);
+	xa_lock(&hr_dev->cq_table.array);
+	hr_cq = xa_load(&hr_dev->cq_table.array,
+			cqn & (hr_dev->caps.num_cqs - 1));
+	if (hr_cq)
+		refcount_inc(&hr_cq->refcount);
+	xa_unlock(&hr_dev->cq_table.array);
+	if (!hr_cq) {
+		dev_warn(dev, "async event for bogus CQ 0x%06x\n", cqn);
+		return;
+	}
 
 	ibcq = &hr_cq->ib_cq;
 	if (ibcq->event_handler) {
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/hns_roce_debugfs.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/hns_roce_debugfs.c
@@ -5,6 +5,7 @@
 
 #include <linux/debugfs.h>
 #include <linux/device.h>
+#include <linux/pci.h>
 
 #include "hns_roce_device.h"
 
@@ -86,7 +87,7 @@
 {
 	struct hns_roce_dev_debugfs *dbgfs = &hr_dev->dbgfs;
 
-	dbgfs->root = debugfs_create_dir(dev_name(&hr_dev->ib_dev.dev),
+	dbgfs->root = debugfs_create_dir(pci_name(hr_dev->pci_dev),
 					 hns_roce_dbgfs_root);
 
 	create_sw_stat_debugfs(hr_dev, dbgfs->root);
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/hns_roce_device.h
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/hns_roce_device.h
@@ -83,6 +83,7 @@
 #define MR_TYPE_DMA				0x03
 
 #define HNS_ROCE_FRMR_MAX_PA			512
+#define HNS_ROCE_FRMR_ALIGN_SIZE		128
 
 #define PKEY_ID					0xffff
 #define NODE_DESC_SIZE				64
@@ -91,6 +92,8 @@
 /* Configure to HW for PAGE_SIZE larger than 4KB */
 #define PG_SHIFT_OFFSET				(PAGE_SHIFT - 12)
 
+#define ATOMIC_WR_LEN				8
+
 #define HNS_ROCE_IDX_QUE_ENTRY_SZ		4
 #define SRQ_DB_REG				0x230
 
@@ -183,6 +186,9 @@
 #define HNS_HW_PAGE_SHIFT			12
 #define HNS_HW_PAGE_SIZE			(1 << HNS_HW_PAGE_SHIFT)
 
+#define HNS_HW_MAX_PAGE_SHIFT			27
+#define HNS_HW_MAX_PAGE_SIZE			(1 << HNS_HW_MAX_PAGE_SHIFT)
+
 struct hns_roce_uar {
 	u64		pfn;
 	unsigned long	index;
@@ -471,12 +477,6 @@
 	u32 next; /* Next ID to allocate. */
 };
 
-struct hns_roce_idx_table {
-	u32 *spare_idx;
-	u32 head;
-	u32 tail;
-};
-
 struct hns_roce_qp_table {
 	struct hns_roce_hem_table	qp_table;
 	struct hns_roce_hem_table	irrl_table;
@@ -485,7 +485,7 @@
 	struct mutex			scc_mutex;
 	struct hns_roce_bank bank[HNS_ROCE_QP_BANK_NUM];
 	struct mutex bank_mutex;
-	struct hns_roce_idx_table	idx_table;
+	struct xarray			dip_xa;
 };
 
 struct hns_roce_cq_table {
@@ -575,6 +575,7 @@
 
 enum {
 	HNS_ROCE_FLUSH_FLAG = 0,
+	HNS_ROCE_STOP_FLUSH_FLAG = 1,
 };
 
 struct hns_roce_work {
@@ -585,6 +586,13 @@
 	u32 queue_num;
 };
 
+enum hns_roce_cong_type {
+	CONG_TYPE_DCQCN,
+	CONG_TYPE_LDCP,
+	CONG_TYPE_HC3,
+	CONG_TYPE_DIP,
+};
+
 struct hns_roce_qp {
 	struct ib_qp		ibqp;
 	struct hns_roce_wq	rq;
@@ -628,6 +636,9 @@
 	struct list_head	sq_node; /* all send qps are on a list */
 	struct hns_user_mmap_entry *dwqe_mmap_entry;
 	u32			config;
+	enum hns_roce_cong_type	cong_type;
+	spinlock_t flush_lock;
+	struct hns_roce_dip *dip;
 };
 
 struct hns_roce_ib_iboe {
@@ -699,13 +710,6 @@
 	struct hns_roce_eq	*eq;
 };
 
-enum cong_type {
-	CONG_TYPE_DCQCN,
-	CONG_TYPE_LDCP,
-	CONG_TYPE_HC3,
-	CONG_TYPE_DIP,
-};
-
 struct hns_roce_caps {
 	u64		fw_ver;
 	u8		num_ports;
@@ -835,7 +839,7 @@
 	u16		default_aeq_period;
 	u16		default_aeq_arm_st;
 	u16		default_ceq_arm_st;
-	enum cong_type	cong_type;
+	enum hns_roce_cong_type cong_type;
 };
 
 enum hns_roce_device_state {
@@ -912,8 +916,7 @@
 	int (*rereg_write_mtpt)(struct hns_roce_dev *hr_dev,
 				struct hns_roce_mr *mr, int flags,
 				void *mb_buf);
-	int (*frmr_write_mtpt)(struct hns_roce_dev *hr_dev, void *mb_buf,
-			       struct hns_roce_mr *mr);
+	int (*frmr_write_mtpt)(void *mb_buf, struct hns_roce_mr *mr);
 	int (*mw_write_mtpt)(void *mb_buf, struct hns_roce_mw *mw);
 	void (*write_cqc)(struct hns_roce_dev *hr_dev,
 			  struct hns_roce_cq *hr_cq, void *mb_buf, u64 *mtts,
@@ -957,8 +960,6 @@
 	enum hns_roce_device_state state;
 	struct list_head	qp_list; /* list of all qps on this dev */
 	spinlock_t		qp_list_lock; /* protect qp_list */
-	struct list_head	dip_list; /* list of all dest ips on this dev */
-	spinlock_t		dip_list_lock; /* protect dip_list */
 
 	struct list_head        pgdir_list;
 	struct mutex            pgdir_mutex;
@@ -1152,8 +1153,13 @@
 
 /* hns roce hw need current block and next block addr from mtt */
 #define MTT_MIN_COUNT	 2
+static inline dma_addr_t hns_roce_get_mtr_ba(struct hns_roce_mtr *mtr)
+{
+	return mtr->hem_cfg.root_ba;
+}
+
 int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
-		      u32 offset, u64 *mtt_buf, int mtt_max, u64 *base_addr);
+		      u32 offset, u64 *mtt_buf, int mtt_max);
 int hns_roce_mtr_create(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
 			struct hns_roce_buf_attr *buf_attr,
 			unsigned int page_shift, struct ib_udata *udata,
@@ -1211,7 +1217,7 @@
 int hns_roce_get_kmem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
 			   int buf_cnt, struct hns_roce_buf *buf,
 			   unsigned int page_shift);
-int hns_roce_get_umem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs,
+int hns_roce_get_umem_bufs(dma_addr_t *bufs,
 			   int buf_cnt, struct ib_umem *umem,
 			   unsigned int page_shift);
 
@@ -1259,6 +1265,7 @@
 void hns_roce_cq_event(struct hns_roce_dev *hr_dev, u32 cqn, int event_type);
 void flush_cqe(struct hns_roce_dev *dev, struct hns_roce_qp *qp);
 void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type);
+void hns_roce_flush_cqe(struct hns_roce_dev *hr_dev, u32 qpn);
 void hns_roce_srq_event(struct hns_roce_dev *hr_dev, u32 srqn, int event_type);
 void hns_roce_handle_device_err(struct hns_roce_dev *hr_dev);
 int hns_roce_init(struct hns_roce_dev *hr_dev);
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/hns_roce_hem.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/hns_roce_hem.c
@@ -337,7 +337,7 @@
 			   struct hns_roce_hem_mhop *mhop,
 			   struct hns_roce_hem_index *index)
 {
-	struct ib_device *ibdev = &hr_dev->ib_dev;
+	struct device *dev = hr_dev->dev;
 	unsigned long mhop_obj = obj;
 	u32 l0_idx, l1_idx, l2_idx;
 	u32 chunk_ba_num;
@@ -368,14 +368,14 @@
 		index->buf = l0_idx;
 		break;
 	default:
-		ibdev_err(ibdev, "table %u not support mhop.hop_num = %u!\n",
-			  table->type, mhop->hop_num);
+		dev_err(dev, "table %u not support mhop.hop_num = %u!\n",
+			table->type, mhop->hop_num);
 		return -EINVAL;
 	}
 
 	if (unlikely(index->buf >= table->num_hem)) {
-		ibdev_err(ibdev, "table %u exceed hem limt idx %llu, max %lu!\n",
-			  table->type, index->buf, table->num_hem);
+		dev_err(dev, "table %u exceed hem limt idx %llu, max %lu!\n",
+			table->type, index->buf, table->num_hem);
 		return -EINVAL;
 	}
 
@@ -487,14 +487,14 @@
 			struct hns_roce_hem_mhop *mhop,
 			struct hns_roce_hem_index *index)
 {
-	struct ib_device *ibdev = &hr_dev->ib_dev;
+	struct device *dev = hr_dev->dev;
 	u32 step_idx;
 	int ret = 0;
 
 	if (index->inited & HEM_INDEX_L0) {
 		ret = hr_dev->hw->set_hem(hr_dev, table, obj, 0);
 		if (ret) {
-			ibdev_err(ibdev, "set HEM step 0 failed!\n");
+			dev_err(dev, "set HEM step 0 failed!\n");
 			goto out;
 		}
 	}
@@ -502,7 +502,7 @@
 	if (index->inited & HEM_INDEX_L1) {
 		ret = hr_dev->hw->set_hem(hr_dev, table, obj, 1);
 		if (ret) {
-			ibdev_err(ibdev, "set HEM step 1 failed!\n");
+			dev_err(dev, "set HEM step 1 failed!\n");
 			goto out;
 		}
 	}
@@ -514,7 +514,7 @@
 			step_idx = mhop->hop_num;
 		ret = hr_dev->hw->set_hem(hr_dev, table, obj, step_idx);
 		if (ret)
-			ibdev_err(ibdev, "set HEM step last failed!\n");
+			dev_err(dev, "set HEM step last failed!\n");
 	}
 out:
 	return ret;
@@ -524,14 +524,14 @@
 				   struct hns_roce_hem_table *table,
 				   unsigned long obj)
 {
-	struct ib_device *ibdev = &hr_dev->ib_dev;
 	struct hns_roce_hem_index index = {};
 	struct hns_roce_hem_mhop mhop = {};
+	struct device *dev = hr_dev->dev;
 	int ret;
 
 	ret = calc_hem_config(hr_dev, table, obj, &mhop, &index);
 	if (ret) {
-		ibdev_err(ibdev, "calc hem config failed!\n");
+		dev_err(dev, "calc hem config failed!\n");
 		return ret;
 	}
 
@@ -543,7 +543,7 @@
 
 	ret = alloc_mhop_hem(hr_dev, table, &mhop, &index);
 	if (ret) {
-		ibdev_err(ibdev, "alloc mhop hem failed!\n");
+		dev_err(dev, "alloc mhop hem failed!\n");
 		goto out;
 	}
 
@@ -551,7 +551,7 @@
 	if (table->type < HEM_TYPE_MTT) {
 		ret = set_mhop_hem(hr_dev, table, obj, &mhop, &index);
 		if (ret) {
-			ibdev_err(ibdev, "set HEM address to HW failed!\n");
+			dev_err(dev, "set HEM address to HW failed!\n");
 			goto err_alloc;
 		}
 	}
@@ -615,7 +615,7 @@
 			   struct hns_roce_hem_mhop *mhop,
 			   struct hns_roce_hem_index *index)
 {
-	struct ib_device *ibdev = &hr_dev->ib_dev;
+	struct device *dev = hr_dev->dev;
 	u32 hop_num = mhop->hop_num;
 	u32 chunk_ba_num;
 	u32 step_idx;
@@ -645,21 +645,21 @@
 
 		ret = hr_dev->hw->clear_hem(hr_dev, table, obj, step_idx);
 		if (ret)
-			ibdev_warn(ibdev, "failed to clear hop%u HEM, ret = %d.\n",
-				   hop_num, ret);
+			dev_warn(dev, "failed to clear hop%u HEM, ret = %d.\n",
+				 hop_num, ret);
 
 		if (index->inited & HEM_INDEX_L1) {
 			ret = hr_dev->hw->clear_hem(hr_dev, table, obj, 1);
 			if (ret)
-				ibdev_warn(ibdev, "failed to clear HEM step 1, ret = %d.\n",
-					   ret);
+				dev_warn(dev, "failed to clear HEM step 1, ret = %d.\n",
+					 ret);
 		}
 
 		if (index->inited & HEM_INDEX_L0) {
 			ret = hr_dev->hw->clear_hem(hr_dev, table, obj, 0);
 			if (ret)
-				ibdev_warn(ibdev, "failed to clear HEM step 0, ret = %d.\n",
-					   ret);
+				dev_warn(dev, "failed to clear HEM step 0, ret = %d.\n",
+					 ret);
 		}
 	}
 }
@@ -669,14 +669,14 @@
 				    unsigned long obj,
 				    int check_refcount)
 {
-	struct ib_device *ibdev = &hr_dev->ib_dev;
 	struct hns_roce_hem_index index = {};
 	struct hns_roce_hem_mhop mhop = {};
+	struct device *dev = hr_dev->dev;
 	int ret;
 
 	ret = calc_hem_config(hr_dev, table, obj, &mhop, &index);
 	if (ret) {
-		ibdev_err(ibdev, "calc hem config failed!\n");
+		dev_err(dev, "calc hem config failed!\n");
 		return;
 	}
 
@@ -712,8 +712,8 @@
 
 	ret = hr_dev->hw->clear_hem(hr_dev, table, obj, HEM_HOP_STEP_DIRECT);
 	if (ret)
-		dev_warn(dev, "failed to clear HEM base address, ret = %d.\n",
-			 ret);
+		dev_warn_ratelimited(dev, "failed to clear HEM base address, ret = %d.\n",
+				     ret);
 
 	hns_roce_free_hem(hr_dev, table->hem[i]);
 	table->hem[i] = NULL;
@@ -986,6 +986,7 @@
 	size_t count; /* max ba numbers */
 	int start; /* start buf offset in this hem */
 	int end; /* end buf offset in this hem */
+	bool exist_bt;
 };
 
 /* All HEM items are linked in a tree structure */
@@ -1014,6 +1015,7 @@
 		}
 	}
 
+	hem->exist_bt = exist_bt;
 	hem->count = count;
 	hem->start = start;
 	hem->end = end;
@@ -1024,34 +1026,32 @@
 }
 
 static void hem_list_free_item(struct hns_roce_dev *hr_dev,
-			       struct hns_roce_hem_item *hem, bool exist_bt)
+			       struct hns_roce_hem_item *hem)
 {
-	if (exist_bt)
+	if (hem->exist_bt)
 		dma_free_coherent(hr_dev->dev, hem->count * BA_BYTE_LEN,
 				  hem->addr, hem->dma_addr);
 	kfree(hem);
 }
 
 static void hem_list_free_all(struct hns_roce_dev *hr_dev,
-			      struct list_head *head, bool exist_bt)
+			      struct list_head *head)
 {
 	struct hns_roce_hem_item *hem, *temp_hem;
 
 	list_for_each_entry_safe(hem, temp_hem, head, list) {
 		list_del(&hem->list);
-		hem_list_free_item(hr_dev, hem, exist_bt);
+		hem_list_free_item(hr_dev, hem);
 	}
 }
 
-static void hem_list_link_bt(struct hns_roce_dev *hr_dev, void *base_addr,
-			     u64 table_addr)
+static void hem_list_link_bt(void *base_addr, u64 table_addr)
 {
 	*(u64 *)(base_addr) = table_addr;
 }
 
 /* assign L0 table address to hem from root bt */
-static void hem_list_assign_bt(struct hns_roce_dev *hr_dev,
-			       struct hns_roce_hem_item *hem, void *cpu_addr,
+static void hem_list_assign_bt(struct hns_roce_hem_item *hem, void *cpu_addr,
 			       u64 phy_addr)
 {
 	hem->addr = cpu_addr;
@@ -1098,9 +1098,9 @@
  * @bt_level: base address table level
  * @unit: ba entries per bt page
  */
-static u32 hem_list_calc_ba_range(int hopnum, int bt_level, int unit)
+static u64 hem_list_calc_ba_range(int hopnum, int bt_level, int unit)
 {
-	u32 step;
+	u64 step;
 	int max;
 	int i;
 
@@ -1136,11 +1136,15 @@
 {
 	struct hns_roce_buf_region *r;
 	int total = 0;
-	int step;
+	u64 step;
 	int i;
 
 	for (i = 0; i < region_cnt; i++) {
 		r = (struct hns_roce_buf_region *)&regions[i];
+		/* when r->hopnum = 0, the region should not occupy root_ba. */
+		if (!r->hopnum)
+			continue;
+
 		if (r->hopnum > 1) {
 			step = hem_list_calc_ba_range(r->hopnum, 1, unit);
 			if (step > 0)
@@ -1167,7 +1171,7 @@
 	int ret = 0;
 	int max_ofs;
 	int level;
-	u32 step;
+	u64 step;
 	int end;
 
 	if (hopnum <= 1)
@@ -1191,10 +1195,12 @@
 
 	/* config L1 bt to last bt and link them to corresponding parent */
 	for (level = 1; level < hopnum; level++) {
-		cur = hem_list_search_item(&mid_bt[level], offset);
-		if (cur) {
-			hem_ptrs[level] = cur;
-			continue;
+		if (!hem_list_is_bottom_bt(hopnum, level)) {
+			cur = hem_list_search_item(&mid_bt[level], offset);
+			if (cur) {
+				hem_ptrs[level] = cur;
+				continue;
+			}
 		}
 
 		step = hem_list_calc_ba_range(hopnum, level, unit);
@@ -1204,7 +1210,7 @@
 		}
 
 		start_aligned = (distance / step) * step + r->offset;
-		end = min_t(int, start_aligned + step - 1, max_ofs);
+		end = min_t(u64, start_aligned + step - 1, max_ofs);
 		cur = hem_list_alloc_item(hr_dev, start_aligned, end, unit,
 					  true);
 		if (!cur) {
@@ -1220,8 +1226,7 @@
 		if (level > 1) {
 			pre = hem_ptrs[level - 1];
 			step = (cur->start - pre->start) / step * BA_BYTE_LEN;
-			hem_list_link_bt(hr_dev, pre->addr + step,
-					 cur->dma_addr);
+			hem_list_link_bt(pre->addr + step, cur->dma_addr);
 		}
 	}
 
@@ -1233,7 +1238,7 @@
 
 err_exit:
 	for (level = 1; level < hopnum; level++)
-		hem_list_free_all(hr_dev, &temp_list[level], true);
+		hem_list_free_all(hr_dev, &temp_list[level]);
 
 	return ret;
 }
@@ -1274,16 +1279,26 @@
 {
 	struct hns_roce_hem_item *hem;
 
+	/* This is on the has_mtt branch, if r->hopnum
+	 * is 0, there is no root_ba to reuse for the
+	 * region's fake hem, so a dma_alloc request is
+	 * necessary here.
+	 */
 	hem = hem_list_alloc_item(hr_dev, r->offset, r->offset + r->count - 1,
-				  r->count, false);
+				  r->count, !r->hopnum);
 	if (!hem)
 		return -ENOMEM;
 
-	hem_list_assign_bt(hr_dev, hem, cpu_base, phy_base);
+	/* The root_ba can be reused only when r->hopnum > 0. */
+	if (r->hopnum)
+		hem_list_assign_bt(hem, cpu_base, phy_base);
 	list_add(&hem->list, branch_head);
 	list_add(&hem->sibling, leaf_head);
 
-	return r->count;
+	/* If r->hopnum == 0, 0 is returned,
+	 * so that the root_bt entry is not occupied.
+	 */
+	return r->hopnum ? r->count : 0;
 }
 
 static int setup_middle_bt(struct hns_roce_dev *hr_dev, void *cpu_base,
@@ -1293,7 +1308,7 @@
 	struct hns_roce_hem_item *hem, *temp_hem;
 	int total = 0;
 	int offset;
-	int step;
+	u64 step;
 
 	step = hem_list_calc_ba_range(r->hopnum, 1, unit);
 	if (step < 1)
@@ -1302,7 +1317,7 @@
 	/* if exist mid bt, link L1 to L0 */
 	list_for_each_entry_safe(hem, temp_hem, branch_head, list) {
 		offset = (hem->start - r->offset) / step * BA_BYTE_LEN;
-		hem_list_link_bt(hr_dev, cpu_base + offset, hem->dma_addr);
+		hem_list_link_bt(cpu_base + offset, hem->dma_addr);
 		total++;
 	}
 
@@ -1327,7 +1342,7 @@
 		return -ENOMEM;
 
 	total = 0;
-	for (i = 0; i < region_cnt && total < max_ba_num; i++) {
+	for (i = 0; i < region_cnt && total <= max_ba_num; i++) {
 		r = &regions[i];
 		if (!r->count)
 			continue;
@@ -1393,9 +1408,9 @@
 			     region_cnt);
 	if (ret) {
 		for (i = 0; i < region_cnt; i++)
-			hem_list_free_all(hr_dev, &head.branch[i], false);
+			hem_list_free_all(hr_dev, &head.branch[i]);
 
-		hem_list_free_all(hr_dev, &head.root, true);
+		hem_list_free_all(hr_dev, &head.root);
 	}
 
 	return ret;
@@ -1458,10 +1473,9 @@
 
 	for (i = 0; i < HNS_ROCE_MAX_BT_REGION; i++)
 		for (j = 0; j < HNS_ROCE_MAX_BT_LEVEL; j++)
-			hem_list_free_all(hr_dev, &hem_list->mid_bt[i][j],
-					  j != 0);
+			hem_list_free_all(hr_dev, &hem_list->mid_bt[i][j]);
 
-	hem_list_free_all(hr_dev, &hem_list->root_bt, true);
+	hem_list_free_all(hr_dev, &hem_list->root_bt);
 	INIT_LIST_HEAD(&hem_list->btm_bt);
 	hem_list->root_ba = 0;
 }
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/hns_roce_hem.h
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/hns_roce_hem.h
@@ -61,16 +61,16 @@
 	 (sizeof(struct scatterlist) + sizeof(void *)))
 
 #define check_whether_bt_num_3(type, hop_num) \
-	(type < HEM_TYPE_MTT && hop_num == 2)
+	((type) < HEM_TYPE_MTT && (hop_num) == 2)
 
 #define check_whether_bt_num_2(type, hop_num) \
-	((type < HEM_TYPE_MTT && hop_num == 1) || \
-	(type >= HEM_TYPE_MTT && hop_num == 2))
+	(((type) < HEM_TYPE_MTT && (hop_num) == 1) || \
+	((type) >= HEM_TYPE_MTT && (hop_num) == 2))
 
 #define check_whether_bt_num_1(type, hop_num) \
-	((type < HEM_TYPE_MTT && hop_num == HNS_ROCE_HOP_NUM_0) || \
-	(type >= HEM_TYPE_MTT && hop_num == 1) || \
-	(type >= HEM_TYPE_MTT && hop_num == HNS_ROCE_HOP_NUM_0))
+	(((type) < HEM_TYPE_MTT && (hop_num) == HNS_ROCE_HOP_NUM_0) || \
+	((type) >= HEM_TYPE_MTT && (hop_num) == 1) || \
+	((type) >= HEM_TYPE_MTT && (hop_num) == HNS_ROCE_HOP_NUM_0))
 
 struct hns_roce_hem_chunk {
 	struct list_head	 list;
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
@@ -372,19 +372,12 @@
 static int check_send_valid(struct hns_roce_dev *hr_dev,
 			    struct hns_roce_qp *hr_qp)
 {
-	struct ib_device *ibdev = &hr_dev->ib_dev;
-
 	if (unlikely(hr_qp->state == IB_QPS_RESET ||
 		     hr_qp->state == IB_QPS_INIT ||
-		     hr_qp->state == IB_QPS_RTR)) {
-		ibdev_err(ibdev, "failed to post WQE, QP state %u!\n",
-			  hr_qp->state);
+		     hr_qp->state == IB_QPS_RTR))
 		return -EINVAL;
-	} else if (unlikely(hr_dev->state >= HNS_ROCE_DEVICE_STATE_RST_DOWN)) {
-		ibdev_err(ibdev, "failed to post WQE, dev state %d!\n",
-			  hr_dev->state);
+	else if (unlikely(hr_dev->state >= HNS_ROCE_DEVICE_STATE_RST_DOWN))
 		return -EIO;
-	}
 
 	return 0;
 }
@@ -478,7 +471,7 @@
 	valid_num_sge = calc_wr_sge_num(wr, &msg_len);
 
 	ret = set_ud_opcode(ud_sq_wqe, wr);
-	if (WARN_ON(ret))
+	if (WARN_ON_ONCE(ret))
 		return ret;
 
 	ud_sq_wqe->msg_len = cpu_to_le32(msg_len);
@@ -582,10 +575,10 @@
 	rc_sq_wqe->msg_len = cpu_to_le32(msg_len);
 
 	ret = set_rc_opcode(hr_dev, rc_sq_wqe, wr);
-	if (WARN_ON(ret))
+	if (WARN_ON_ONCE(ret))
 		return ret;
 
-	hr_reg_write(rc_sq_wqe, RC_SEND_WQE_FENCE,
+	hr_reg_write(rc_sq_wqe, RC_SEND_WQE_SO,
 		     (wr->send_flags & IB_SEND_FENCE) ? 1 : 0);
 
 	hr_reg_write(rc_sq_wqe, RC_SEND_WQE_SE,
@@ -595,11 +588,16 @@
 		     (wr->send_flags & IB_SEND_SIGNALED) ? 1 : 0);
 
 	if (wr->opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
-	    wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD)
+	    wr->opcode == IB_WR_ATOMIC_FETCH_AND_ADD) {
+		if (msg_len != ATOMIC_WR_LEN)
+			return -EINVAL;
 		set_atomic_seg(wr, rc_sq_wqe, valid_num_sge);
-	else if (wr->opcode != IB_WR_REG_MR)
+	} else if (wr->opcode != IB_WR_REG_MR) {
 		ret = set_rwqe_data_seg(&qp->ibqp, wr, rc_sq_wqe,
 					&curr_idx, valid_num_sge);
+		if (ret)
+			return ret;
+	}
 
 	/*
 	 * The pipeline can sequentially post all valid WQEs into WQ buffer,
@@ -675,6 +673,10 @@
 #define HNS_ROCE_SL_SHIFT 2
 	struct hns_roce_v2_rc_send_wqe *rc_sq_wqe = wqe;
 
+	if (unlikely(qp->state == IB_QPS_ERR)) {
+		flush_cqe(hr_dev, qp);
+		return;
+	}
 	/* All kinds of DirectWQE have the same header field layout */
 	hr_reg_enable(rc_sq_wqe, RC_SEND_WQE_FLAG);
 	hr_reg_write(rc_sq_wqe, RC_SEND_WQE_DB_SL_L, qp->sl);
@@ -1273,12 +1275,38 @@
 	return -EIO;
 }
 
+static u32 hns_roce_cmdq_tx_timeout(u16 opcode, u32 tx_timeout)
+{
+	static const struct hns_roce_cmdq_tx_timeout_map cmdq_tx_timeout[] = {
+		{HNS_ROCE_OPC_POST_MB, HNS_ROCE_OPC_POST_MB_TIMEOUT},
+	};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(cmdq_tx_timeout); i++)
+		if (cmdq_tx_timeout[i].opcode == opcode)
+			return cmdq_tx_timeout[i].tx_timeout;
+
+	return tx_timeout;
+}
+
+static void hns_roce_wait_csq_done(struct hns_roce_dev *hr_dev, u16 opcode)
+{
+	struct hns_roce_v2_priv *priv = hr_dev->priv;
+	u32 tx_timeout = hns_roce_cmdq_tx_timeout(opcode, priv->cmq.tx_timeout);
+	u32 timeout = 0;
+
+	do {
+		if (hns_roce_cmq_csq_done(hr_dev))
+			break;
+		udelay(1);
+	} while (++timeout < tx_timeout);
+}
+
 static int __hns_roce_cmq_send(struct hns_roce_dev *hr_dev,
 			       struct hns_roce_cmq_desc *desc, int num)
 {
 	struct hns_roce_v2_priv *priv = hr_dev->priv;
 	struct hns_roce_v2_cmq_ring *csq = &priv->cmq.csq;
-	u32 timeout = 0;
 	u16 desc_ret;
 	u32 tail;
 	int ret;
@@ -1299,12 +1327,7 @@
 
 	atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_CMDS_CNT]);
 
-	do {
-		if (hns_roce_cmq_csq_done(hr_dev))
-			break;
-		udelay(1);
-	} while (++timeout < priv->cmq.tx_timeout);
-
+	hns_roce_wait_csq_done(hr_dev, le16_to_cpu(desc->opcode));
 	if (hns_roce_cmq_csq_done(hr_dev)) {
 		ret = 0;
 		for (i = 0; i < num; i++) {
@@ -1658,8 +1681,8 @@
 
 	for (i = 0; i < HNS_ROCE_HW_CNT_TOTAL && i < *num_counters; i++) {
 		bd_idx = i / CNT_PER_DESC;
-		if (!(desc[bd_idx].flag & HNS_ROCE_CMD_FLAG_NEXT) &&
-		    bd_idx != HNS_ROCE_HW_CNT_TOTAL / CNT_PER_DESC)
+		if (bd_idx != HNS_ROCE_HW_CNT_TOTAL / CNT_PER_DESC &&
+		    !(desc[bd_idx].flag & cpu_to_le16(HNS_ROCE_CMD_FLAG_NEXT)))
 			break;
 
 		cnt_data = (__le64 *)&desc[bd_idx].data[0];
@@ -2105,7 +2128,7 @@
 					 caps->gmv_bt_num *
 					 (HNS_HW_PAGE_SIZE / caps->gmv_entry_sz));
 
-		caps->gmv_entry_num = caps->gmv_bt_num * (PAGE_SIZE /
+		caps->gmv_entry_num = caps->gmv_bt_num * (HNS_HW_PAGE_SIZE /
 							  caps->gmv_entry_sz);
 	} else {
 		u32 func_num = max_t(u32, 1, hr_dev->func_num);
@@ -2460,14 +2483,16 @@
 static struct hns_roce_link_table *
 alloc_link_table_buf(struct hns_roce_dev *hr_dev)
 {
+	u16 total_sl = hr_dev->caps.sl_num * hr_dev->func_num;
 	struct hns_roce_v2_priv *priv = hr_dev->priv;
 	struct hns_roce_link_table *link_tbl;
 	u32 pg_shift, size, min_size;
 
 	link_tbl = &priv->ext_llm;
 	pg_shift = hr_dev->caps.llm_buf_pg_sz + PAGE_SHIFT;
-	size = hr_dev->caps.num_qps * HNS_ROCE_V2_EXT_LLM_ENTRY_SZ;
-	min_size = HNS_ROCE_EXT_LLM_MIN_PAGES(hr_dev->caps.sl_num) << pg_shift;
+	size = hr_dev->caps.num_qps * hr_dev->func_num *
+	       HNS_ROCE_V2_EXT_LLM_ENTRY_SZ;
+	min_size = HNS_ROCE_EXT_LLM_MIN_PAGES(total_sl) << pg_shift;
 
 	/* Alloc data table */
 	size = max(size, min_size);
@@ -2534,20 +2559,19 @@
 	free_link_table_buf(hr_dev, &priv->ext_llm);
 }
 
-static void free_dip_list(struct hns_roce_dev *hr_dev)
+static void free_dip_entry(struct hns_roce_dev *hr_dev)
 {
 	struct hns_roce_dip *hr_dip;
-	struct hns_roce_dip *tmp;
-	unsigned long flags;
+	unsigned long idx;
 
-	spin_lock_irqsave(&hr_dev->dip_list_lock, flags);
+	xa_lock(&hr_dev->qp_table.dip_xa);
 
-	list_for_each_entry_safe(hr_dip, tmp, &hr_dev->dip_list, node) {
-		list_del(&hr_dip->node);
+	xa_for_each(&hr_dev->qp_table.dip_xa, idx, hr_dip) {
+		__xa_erase(&hr_dev->qp_table.dip_xa, hr_dip->dip_idx);
 		kfree(hr_dip);
 	}
 
-	spin_unlock_irqrestore(&hr_dev->dip_list_lock, flags);
+	xa_unlock(&hr_dev->qp_table.dip_xa);
 }
 
 static struct ib_pd *free_mr_init_pd(struct hns_roce_dev *hr_dev)
@@ -2747,8 +2771,8 @@
 	ret = hr_dev->hw->modify_qp(&hr_qp->ibqp, attr, mask, IB_QPS_INIT,
 				    IB_QPS_INIT, NULL);
 	if (ret) {
-		ibdev_err(ibdev, "failed to modify qp to init, ret = %d.\n",
-			  ret);
+		ibdev_err_ratelimited(ibdev, "failed to modify qp to init, ret = %d.\n",
+				      ret);
 		return ret;
 	}
 
@@ -2942,13 +2966,16 @@
 
 static void hns_roce_v2_exit(struct hns_roce_dev *hr_dev)
 {
+	if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08)
+		free_mr_exit(hr_dev);
+
 	hns_roce_function_clear(hr_dev);
 
 	if (!hr_dev->is_vf)
 		hns_roce_free_link_table(hr_dev);
 
 	if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP09)
-		free_dip_list(hr_dev);
+		free_dip_entry(hr_dev);
 }
 
 static int hns_roce_mbox_post(struct hns_roce_dev *hr_dev,
@@ -3195,21 +3222,22 @@
 	u64 pages[HNS_ROCE_V2_MAX_INNER_MTPT_NUM] = { 0 };
 	struct ib_device *ibdev = &hr_dev->ib_dev;
 	dma_addr_t pbl_ba;
-	int i, count;
+	int ret;
+	int i;
 
-	count = hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, pages,
-				  min_t(int, ARRAY_SIZE(pages), mr->npages),
-				  &pbl_ba);
-	if (count < 1) {
-		ibdev_err(ibdev, "failed to find PBL mtr, count = %d.\n",
-			  count);
-		return -ENOBUFS;
+	ret = hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, pages,
+				min_t(int, ARRAY_SIZE(pages), mr->npages));
+	if (ret) {
+		ibdev_err(ibdev, "failed to find PBL mtr, ret = %d.\n", ret);
+		return ret;
 	}
 
 	/* Aligned to the hardware address access unit */
-	for (i = 0; i < count; i++)
+	for (i = 0; i < ARRAY_SIZE(pages); i++)
 		pages[i] >>= 6;
 
+	pbl_ba = hns_roce_get_mtr_ba(&mr->pbl_mtr);
+
 	mpt_entry->pbl_size = cpu_to_le32(mr->npages);
 	mpt_entry->pbl_ba_l = cpu_to_le32(pbl_ba >> 3);
 	hr_reg_write(mpt_entry, MPT_PBL_BA_H, upper_32_bits(pbl_ba >> 3));
@@ -3305,21 +3333,14 @@
 	return ret;
 }
 
-static int hns_roce_v2_frmr_write_mtpt(struct hns_roce_dev *hr_dev,
-				       void *mb_buf, struct hns_roce_mr *mr)
+static int hns_roce_v2_frmr_write_mtpt(void *mb_buf, struct hns_roce_mr *mr)
 {
-	struct ib_device *ibdev = &hr_dev->ib_dev;
+	dma_addr_t pbl_ba = hns_roce_get_mtr_ba(&mr->pbl_mtr);
 	struct hns_roce_v2_mpt_entry *mpt_entry;
-	dma_addr_t pbl_ba = 0;
 
 	mpt_entry = mb_buf;
 	memset(mpt_entry, 0, sizeof(*mpt_entry));
 
-	if (hns_roce_mtr_find(hr_dev, &mr->pbl_mtr, 0, NULL, 0, &pbl_ba) < 0) {
-		ibdev_err(ibdev, "failed to find frmr mtr.\n");
-		return -ENOBUFS;
-	}
-
 	hr_reg_write(mpt_entry, MPT_ST, V2_MPT_ST_FREE);
 	hr_reg_write(mpt_entry, MPT_PD, mr->pd);
 
@@ -3391,8 +3412,8 @@
 
 	ret = hns_roce_v2_post_send(&hr_qp->ibqp, send_wr, &bad_wr);
 	if (ret) {
-		ibdev_err(ibdev, "failed to post wqe for free mr, ret = %d.\n",
-			  ret);
+		ibdev_err_ratelimited(ibdev, "failed to post wqe for free mr, ret = %d.\n",
+				      ret);
 		return ret;
 	}
 
@@ -3431,9 +3452,9 @@
 
 		ret = free_mr_post_send_lp_wqe(hr_qp);
 		if (ret) {
-			ibdev_err(ibdev,
-				  "failed to send wqe (qp:0x%lx) for free mr, ret = %d.\n",
-				  hr_qp->qpn, ret);
+			ibdev_err_ratelimited(ibdev,
+					      "failed to send wqe (qp:0x%lx) for free mr, ret = %d.\n",
+					      hr_qp->qpn, ret);
 			break;
 		}
 
@@ -3444,16 +3465,16 @@
 	while (cqe_cnt) {
 		npolled = hns_roce_v2_poll_cq(&free_mr->rsv_cq->ib_cq, cqe_cnt, wc);
 		if (npolled < 0) {
-			ibdev_err(ibdev,
-				  "failed to poll cqe for free mr, remain %d cqe.\n",
-				  cqe_cnt);
+			ibdev_err_ratelimited(ibdev,
+					      "failed to poll cqe for free mr, remain %d cqe.\n",
+					      cqe_cnt);
 			goto out;
 		}
 
 		if (time_after(jiffies, end)) {
-			ibdev_err(ibdev,
-				  "failed to poll cqe for free mr and timeout, remain %d cqe.\n",
-				  cqe_cnt);
+			ibdev_err_ratelimited(ibdev,
+					      "failed to poll cqe for free mr and timeout, remain %d cqe.\n",
+					      cqe_cnt);
 			goto out;
 		}
 		cqe_cnt -= npolled;
@@ -3715,8 +3736,9 @@
 		   wc->status == IB_WC_WR_FLUSH_ERR))
 		return;
 
-	ibdev_err(&hr_dev->ib_dev, "error cqe status 0x%x:\n", cqe_status);
-	print_hex_dump(KERN_ERR, "", DUMP_PREFIX_NONE, 16, 4, cqe,
+	ibdev_err_ratelimited(&hr_dev->ib_dev, "error cqe status 0x%x:\n",
+			      cqe_status);
+	print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE, 16, 4, cqe,
 		       cq->cqe_size, false);
 	wc->vendor_err = hr_reg_read(cqe, CQE_SUB_STATUS);
 
@@ -4226,8 +4248,7 @@
 }
 
 static void set_qpc_wqe_cnt(struct hns_roce_qp *hr_qp,
-			    struct hns_roce_v2_qp_context *context,
-			    struct hns_roce_v2_qp_context *qpc_mask)
+			    struct hns_roce_v2_qp_context *context)
 {
 	hr_reg_write(context, QPC_SGE_SHIFT,
 		     to_hr_hem_entries_shift(hr_qp->sge.sge_cnt,
@@ -4249,7 +4270,6 @@
 }
 
 static void modify_qp_reset_to_init(struct ib_qp *ibqp,
-				    const struct ib_qp_attr *attr,
 				    struct hns_roce_v2_qp_context *context,
 				    struct hns_roce_v2_qp_context *qpc_mask)
 {
@@ -4268,7 +4288,7 @@
 
 	hr_reg_write(context, QPC_RQWS, ilog2(hr_qp->rq.max_gs));
 
-	set_qpc_wqe_cnt(hr_qp, context, qpc_mask);
+	set_qpc_wqe_cnt(hr_qp, context);
 
 	/* No VLAN need to set 0xFFF */
 	hr_reg_write(context, QPC_VLAN_ID, 0xfff);
@@ -4309,7 +4329,6 @@
 }
 
 static void modify_qp_init_to_init(struct ib_qp *ibqp,
-				   const struct ib_qp_attr *attr,
 				   struct hns_roce_v2_qp_context *context,
 				   struct hns_roce_v2_qp_context *qpc_mask)
 {
@@ -4346,17 +4365,20 @@
 {
 	u64 mtts[MTT_MIN_COUNT] = { 0 };
 	u64 wqe_sge_ba;
-	int count;
+	int ret;
 
 	/* Search qp buf's mtts */
-	count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, hr_qp->rq.offset, mtts,
-				  MTT_MIN_COUNT, &wqe_sge_ba);
-	if (hr_qp->rq.wqe_cnt && count < 1) {
+	ret = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, hr_qp->rq.offset, mtts,
+				MTT_MIN_COUNT);
+	if (hr_qp->rq.wqe_cnt && ret) {
 		ibdev_err(&hr_dev->ib_dev,
-			  "failed to find RQ WQE, QPN = 0x%lx.\n", hr_qp->qpn);
-		return -EINVAL;
+			  "failed to find QP(0x%lx) RQ WQE buf, ret = %d.\n",
+			  hr_qp->qpn, ret);
+		return ret;
 	}
 
+	wqe_sge_ba = hns_roce_get_mtr_ba(&hr_qp->mtr);
+
 	context->wqe_sge_ba = cpu_to_le32(wqe_sge_ba >> 3);
 	qpc_mask->wqe_sge_ba = 0;
 
@@ -4400,12 +4422,14 @@
 		     upper_32_bits(to_hr_hw_page_addr(mtts[0])));
 	hr_reg_clear(qpc_mask, QPC_RQ_CUR_BLK_ADDR_H);
 
-	context->rq_nxt_blk_addr = cpu_to_le32(to_hr_hw_page_addr(mtts[1]));
-	qpc_mask->rq_nxt_blk_addr = 0;
-
-	hr_reg_write(context, QPC_RQ_NXT_BLK_ADDR_H,
-		     upper_32_bits(to_hr_hw_page_addr(mtts[1])));
-	hr_reg_clear(qpc_mask, QPC_RQ_NXT_BLK_ADDR_H);
+	if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) {
+		context->rq_nxt_blk_addr =
+				cpu_to_le32(to_hr_hw_page_addr(mtts[1]));
+		qpc_mask->rq_nxt_blk_addr = 0;
+		hr_reg_write(context, QPC_RQ_NXT_BLK_ADDR_H,
+			     upper_32_bits(to_hr_hw_page_addr(mtts[1])));
+		hr_reg_clear(qpc_mask, QPC_RQ_NXT_BLK_ADDR_H);
+	}
 
 	return 0;
 }
@@ -4418,23 +4442,23 @@
 	struct ib_device *ibdev = &hr_dev->ib_dev;
 	u64 sge_cur_blk = 0;
 	u64 sq_cur_blk = 0;
-	int count;
+	int ret;
 
 	/* search qp buf's mtts */
-	count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, 0, &sq_cur_blk, 1, NULL);
-	if (count < 1) {
-		ibdev_err(ibdev, "failed to find QP(0x%lx) SQ buf.\n",
-			  hr_qp->qpn);
-		return -EINVAL;
+	ret = hns_roce_mtr_find(hr_dev, &hr_qp->mtr, hr_qp->sq.offset,
+				&sq_cur_blk, 1);
+	if (ret) {
+		ibdev_err(ibdev, "failed to find QP(0x%lx) SQ WQE buf, ret = %d.\n",
+			  hr_qp->qpn, ret);
+		return ret;
 	}
 	if (hr_qp->sge.sge_cnt > 0) {
-		count = hns_roce_mtr_find(hr_dev, &hr_qp->mtr,
-					  hr_qp->sge.offset,
-					  &sge_cur_blk, 1, NULL);
-		if (count < 1) {
-			ibdev_err(ibdev, "failed to find QP(0x%lx) SGE buf.\n",
-				  hr_qp->qpn);
-			return -EINVAL;
+		ret = hns_roce_mtr_find(hr_dev, &hr_qp->mtr,
+					hr_qp->sge.offset, &sge_cur_blk, 1);
+		if (ret) {
+			ibdev_err(ibdev, "failed to find QP(0x%lx) SGE buf, ret = %d.\n",
+				  hr_qp->qpn, ret);
+			return ret;
 		}
 	}
 
@@ -4625,8 +4649,7 @@
 	return 0;
 }
 
-static int modify_qp_rtr_to_rts(struct ib_qp *ibqp,
-				const struct ib_qp_attr *attr, int attr_mask,
+static int modify_qp_rtr_to_rts(struct ib_qp *ibqp, int attr_mask,
 				struct hns_roce_v2_qp_context *context,
 				struct hns_roce_v2_qp_context *qpc_mask)
 {
@@ -4673,26 +4696,49 @@
 	return 0;
 }
 
+static int alloc_dip_entry(struct xarray *dip_xa, u32 qpn)
+{
+	struct hns_roce_dip *hr_dip;
+	int ret;
+
+	hr_dip = xa_load(dip_xa, qpn);
+	if (hr_dip)
+		return 0;
+
+	hr_dip = kzalloc(sizeof(*hr_dip), GFP_KERNEL);
+	if (!hr_dip)
+		return -ENOMEM;
+
+	ret = xa_err(xa_store(dip_xa, qpn, hr_dip, GFP_KERNEL));
+	if (ret)
+		kfree(hr_dip);
+
+	return ret;
+}
+
 static int get_dip_ctx_idx(struct ib_qp *ibqp, const struct ib_qp_attr *attr,
 			   u32 *dip_idx)
 {
 	const struct ib_global_route *grh = rdma_ah_read_grh(&attr->ah_attr);
 	struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
-	u32 *spare_idx = hr_dev->qp_table.idx_table.spare_idx;
-	u32 *head =  &hr_dev->qp_table.idx_table.head;
-	u32 *tail =  &hr_dev->qp_table.idx_table.tail;
+	struct xarray *dip_xa = &hr_dev->qp_table.dip_xa;
+	struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
 	struct hns_roce_dip *hr_dip;
-	unsigned long flags;
+	unsigned long idx;
 	int ret = 0;
 
-	spin_lock_irqsave(&hr_dev->dip_list_lock, flags);
+	ret = alloc_dip_entry(dip_xa, ibqp->qp_num);
+	if (ret)
+		return ret;
 
-	spare_idx[*tail] = ibqp->qp_num;
-	*tail = (*tail == hr_dev->caps.num_qps - 1) ? 0 : (*tail + 1);
+	xa_lock(dip_xa);
 
-	list_for_each_entry(hr_dip, &hr_dev->dip_list, node) {
-		if (!memcmp(grh->dgid.raw, hr_dip->dgid, 16)) {
+	xa_for_each(dip_xa, idx, hr_dip) {
+		if (hr_dip->qp_cnt &&
+		    !memcmp(grh->dgid.raw, hr_dip->dgid, 16)) {
 			*dip_idx = hr_dip->dip_idx;
+			hr_dip->qp_cnt++;
+			hr_qp->dip = hr_dip;
 			goto out;
 		}
 	}
@@ -4700,19 +4746,24 @@
 	/* If no dgid is found, a new dip and a mapping between dgid and
 	 * dip_idx will be created.
 	 */
-	hr_dip = kzalloc(sizeof(*hr_dip), GFP_ATOMIC);
-	if (!hr_dip) {
-		ret = -ENOMEM;
-		goto out;
+	xa_for_each(dip_xa, idx, hr_dip) {
+		if (hr_dip->qp_cnt)
+			continue;
+
+		*dip_idx = idx;
+		memcpy(hr_dip->dgid, grh->dgid.raw, sizeof(grh->dgid.raw));
+		hr_dip->dip_idx = idx;
+		hr_dip->qp_cnt++;
+		hr_qp->dip = hr_dip;
+		break;
 	}
 
-	memcpy(hr_dip->dgid, grh->dgid.raw, sizeof(grh->dgid.raw));
-	hr_dip->dip_idx = *dip_idx = spare_idx[*head];
-	*head = (*head == hr_dev->caps.num_qps - 1) ? 0 : (*head + 1);
-	list_add_tail(&hr_dip->node, &hr_dev->dip_list);
+	/* This should never happen. */
+	if (WARN_ON_ONCE(!hr_qp->dip))
+		ret = -ENOSPC;
 
 out:
-	spin_unlock_irqrestore(&hr_dev->dip_list_lock, flags);
+	xa_unlock(dip_xa);
 	return ret;
 }
 
@@ -4745,12 +4796,15 @@
 			   struct hns_roce_congestion_algorithm *cong_alg)
 {
 	struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
+	struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
 
-	if (ibqp->qp_type == IB_QPT_UD)
-		hr_dev->caps.cong_type = CONG_TYPE_DCQCN;
+	if (ibqp->qp_type == IB_QPT_UD || ibqp->qp_type == IB_QPT_GSI)
+		hr_qp->cong_type = CONG_TYPE_DCQCN;
+	else
+		hr_qp->cong_type = hr_dev->caps.cong_type;
 
 	/* different congestion types match different configurations */
-	switch (hr_dev->caps.cong_type) {
+	switch (hr_qp->cong_type) {
 	case CONG_TYPE_DCQCN:
 		cong_alg->alg_sel = CONG_DCQCN;
 		cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL;
@@ -4778,8 +4832,8 @@
 	default:
 		ibdev_warn(&hr_dev->ib_dev,
 			   "invalid type(%u) for congestion selection.\n",
-			   hr_dev->caps.cong_type);
-		hr_dev->caps.cong_type = CONG_TYPE_DCQCN;
+			   hr_qp->cong_type);
+		hr_qp->cong_type = CONG_TYPE_DCQCN;
 		cong_alg->alg_sel = CONG_DCQCN;
 		cong_alg->alg_sub_sel = UNSUPPORT_CONG_LEVEL;
 		cong_alg->dip_vld = DIP_INVALID;
@@ -4798,6 +4852,7 @@
 	struct hns_roce_congestion_algorithm cong_field;
 	struct ib_device *ibdev = ibqp->device;
 	struct hns_roce_dev *hr_dev = to_hr_dev(ibdev);
+	struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
 	u32 dip_idx = 0;
 	int ret;
 
@@ -4810,7 +4865,7 @@
 		return ret;
 
 	hr_reg_write(context, QPC_CONG_ALGO_TMPL_ID, hr_dev->cong_algo_tmpl_id +
-		     hr_dev->caps.cong_type * HNS_ROCE_CONG_SIZE);
+		     hr_qp->cong_type * HNS_ROCE_CONG_SIZE);
 	hr_reg_clear(qpc_mask, QPC_CONG_ALGO_TMPL_ID);
 	hr_reg_write(&context->ext, QPCEX_CONG_ALG_SEL, cong_field.alg_sel);
 	hr_reg_clear(&qpc_mask->ext, QPCEX_CONG_ALG_SEL);
@@ -4986,22 +5041,19 @@
 	struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
 	int ret = 0;
 
-	if (!check_qp_state(cur_state, new_state)) {
-		ibdev_err(&hr_dev->ib_dev, "Illegal state for QP!\n");
+	if (!check_qp_state(cur_state, new_state))
 		return -EINVAL;
-	}
 
 	if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT) {
 		memset(qpc_mask, 0, hr_dev->caps.qpc_sz);
-		modify_qp_reset_to_init(ibqp, attr, context, qpc_mask);
+		modify_qp_reset_to_init(ibqp, context, qpc_mask);
 	} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_INIT) {
-		modify_qp_init_to_init(ibqp, attr, context, qpc_mask);
+		modify_qp_init_to_init(ibqp, context, qpc_mask);
 	} else if (cur_state == IB_QPS_INIT && new_state == IB_QPS_RTR) {
 		ret = modify_qp_init_to_rtr(ibqp, attr, attr_mask, context,
 					    qpc_mask, udata);
 	} else if (cur_state == IB_QPS_RTR && new_state == IB_QPS_RTS) {
-		ret = modify_qp_rtr_to_rts(ibqp, attr, attr_mask, context,
-					   qpc_mask);
+		ret = modify_qp_rtr_to_rts(ibqp, attr_mask, context, qpc_mask);
 	}
 
 	return ret;
@@ -5251,7 +5303,7 @@
 	/* SW pass context to HW */
 	ret = hns_roce_v2_qp_modify(hr_dev, context, qpc_mask, hr_qp);
 	if (ret) {
-		ibdev_err(ibdev, "failed to modify QP, ret = %d.\n", ret);
+		ibdev_err_ratelimited(ibdev, "failed to modify QP, ret = %d.\n", ret);
 		goto out;
 	}
 
@@ -5365,7 +5417,9 @@
 
 	ret = hns_roce_v2_query_qpc(hr_dev, hr_qp->qpn, &context);
 	if (ret) {
-		ibdev_err(ibdev, "failed to query QPC, ret = %d.\n", ret);
+		ibdev_err_ratelimited(ibdev,
+				      "failed to query QPC, ret = %d.\n",
+				      ret);
 		ret = -EINVAL;
 		goto out;
 	}
@@ -5373,7 +5427,7 @@
 	state = hr_reg_read(&context, QPC_QP_ST);
 	tmp_qp_state = to_ib_qp_st((enum hns_roce_v2_qp_state)state);
 	if (tmp_qp_state == -1) {
-		ibdev_err(ibdev, "Illegal ib_qp_state\n");
+		ibdev_err_ratelimited(ibdev, "Illegal ib_qp_state\n");
 		ret = -EINVAL;
 		goto out;
 	}
@@ -5466,9 +5520,9 @@
 		ret = hns_roce_v2_modify_qp(&hr_qp->ibqp, NULL, 0,
 					    hr_qp->state, IB_QPS_RESET, udata);
 		if (ret)
-			ibdev_err(ibdev,
-				  "failed to modify QP to RST, ret = %d.\n",
-				  ret);
+			ibdev_err_ratelimited(ibdev,
+					      "failed to modify QP to RST, ret = %d.\n",
+					      ret);
 	}
 
 	send_cq = hr_qp->ibqp.send_cq ? to_hr_cq(hr_qp->ibqp.send_cq) : NULL;
@@ -5496,17 +5550,44 @@
 	return ret;
 }
 
+static void put_dip_ctx_idx(struct hns_roce_dev *hr_dev,
+			    struct hns_roce_qp *hr_qp)
+{
+	struct hns_roce_dip *hr_dip = hr_qp->dip;
+
+	if (!hr_dip)
+		return;
+
+	xa_lock(&hr_dev->qp_table.dip_xa);
+
+	hr_dip->qp_cnt--;
+	if (!hr_dip->qp_cnt)
+		memset(hr_dip->dgid, 0, GID_LEN_V2);
+
+	xa_unlock(&hr_dev->qp_table.dip_xa);
+}
+
 int hns_roce_v2_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
 {
 	struct hns_roce_dev *hr_dev = to_hr_dev(ibqp->device);
 	struct hns_roce_qp *hr_qp = to_hr_qp(ibqp);
+	unsigned long flags;
 	int ret;
 
+	/* Make sure flush_cqe() is completed */
+	spin_lock_irqsave(&hr_qp->flush_lock, flags);
+	set_bit(HNS_ROCE_STOP_FLUSH_FLAG, &hr_qp->flush_flag);
+	spin_unlock_irqrestore(&hr_qp->flush_lock, flags);
+	flush_work(&hr_qp->flush_work.work);
+
+	if (hr_qp->cong_type == CONG_TYPE_DIP)
+		put_dip_ctx_idx(hr_dev, hr_qp);
+
 	ret = hns_roce_v2_destroy_qp_common(hr_dev, hr_qp, udata);
 	if (ret)
-		ibdev_err(&hr_dev->ib_dev,
-			  "failed to destroy QP, QPN = 0x%06lx, ret = %d.\n",
-			  hr_qp->qpn, ret);
+		ibdev_err_ratelimited(&hr_dev->ib_dev,
+				      "failed to destroy QP, QPN = 0x%06lx, ret = %d.\n",
+				      hr_qp->qpn, ret);
 
 	hns_roce_qp_destroy(hr_dev, hr_qp, udata);
 
@@ -5581,18 +5662,20 @@
 	struct ib_device *ibdev = srq->ibsrq.device;
 	struct hns_roce_dev *hr_dev = to_hr_dev(ibdev);
 	u64 mtts_idx[MTT_MIN_COUNT] = {};
-	dma_addr_t dma_handle_idx = 0;
+	dma_addr_t dma_handle_idx;
 	int ret;
 
 	/* Get physical address of idx que buf */
 	ret = hns_roce_mtr_find(hr_dev, &idx_que->mtr, 0, mtts_idx,
-				ARRAY_SIZE(mtts_idx), &dma_handle_idx);
-	if (ret < 1) {
+				ARRAY_SIZE(mtts_idx));
+	if (ret) {
 		ibdev_err(ibdev, "failed to find mtr for SRQ idx, ret = %d.\n",
 			  ret);
-		return -ENOBUFS;
+		return ret;
 	}
 
+	dma_handle_idx = hns_roce_get_mtr_ba(&idx_que->mtr);
+
 	hr_reg_write(ctx, SRQC_IDX_HOP_NUM,
 		     to_hr_hem_hopnum(hr_dev->caps.idx_hop_num, srq->wqe_cnt));
 
@@ -5624,20 +5707,22 @@
 	struct hns_roce_dev *hr_dev = to_hr_dev(ibdev);
 	struct hns_roce_srq_context *ctx = mb_buf;
 	u64 mtts_wqe[MTT_MIN_COUNT] = {};
-	dma_addr_t dma_handle_wqe = 0;
+	dma_addr_t dma_handle_wqe;
 	int ret;
 
 	memset(ctx, 0, sizeof(*ctx));
 
 	/* Get the physical address of srq buf */
 	ret = hns_roce_mtr_find(hr_dev, &srq->buf_mtr, 0, mtts_wqe,
-				ARRAY_SIZE(mtts_wqe), &dma_handle_wqe);
-	if (ret < 1) {
+				ARRAY_SIZE(mtts_wqe));
+	if (ret) {
 		ibdev_err(ibdev, "failed to find mtr for SRQ WQE, ret = %d.\n",
 			  ret);
-		return -ENOBUFS;
+		return ret;
 	}
 
+	dma_handle_wqe = hns_roce_get_mtr_ba(&srq->buf_mtr);
+
 	hr_reg_write(ctx, SRQC_SRQ_ST, 1);
 	hr_reg_write_bool(ctx, SRQC_SRQ_TYPE,
 			  srq->ibsrq.srq_type == IB_SRQT_XRC);
@@ -5796,9 +5881,9 @@
 				HNS_ROCE_CMD_MODIFY_CQC, hr_cq->cqn);
 	hns_roce_free_cmd_mailbox(hr_dev, mailbox);
 	if (ret)
-		ibdev_err(&hr_dev->ib_dev,
-			  "failed to process cmd when modifying CQ, ret = %d.\n",
-			  ret);
+		ibdev_err_ratelimited(&hr_dev->ib_dev,
+				      "failed to process cmd when modifying CQ, ret = %d.\n",
+				      ret);
 
 err_out:
 	if (ret)
@@ -5822,9 +5907,9 @@
 	ret = hns_roce_cmd_mbox(hr_dev, 0, mailbox->dma,
 				HNS_ROCE_CMD_QUERY_CQC, cqn);
 	if (ret) {
-		ibdev_err(&hr_dev->ib_dev,
-			  "failed to process cmd when querying CQ, ret = %d.\n",
-			  ret);
+		ibdev_err_ratelimited(&hr_dev->ib_dev,
+				      "failed to process cmd when querying CQ, ret = %d.\n",
+				      ret);
 		goto err_mailbox;
 	}
 
@@ -5865,11 +5950,10 @@
 	return ret;
 }
 
-static void hns_roce_irq_work_handle(struct work_struct *work)
+static void dump_aeqe_log(struct hns_roce_work *irq_work)
 {
-	struct hns_roce_work *irq_work =
-				container_of(work, struct hns_roce_work, work);
-	struct ib_device *ibdev = &irq_work->hr_dev->ib_dev;
+	struct hns_roce_dev *hr_dev = irq_work->hr_dev;
+	struct ib_device *ibdev = &hr_dev->ib_dev;
 
 	switch (irq_work->event_type) {
 	case HNS_ROCE_EVENT_TYPE_PATH_MIG:
@@ -5913,6 +5997,8 @@
 	case HNS_ROCE_EVENT_TYPE_DB_OVERFLOW:
 		ibdev_warn(ibdev, "DB overflow.\n");
 		break;
+	case HNS_ROCE_EVENT_TYPE_MB:
+		break;
 	case HNS_ROCE_EVENT_TYPE_FLR:
 		ibdev_warn(ibdev, "function level reset.\n");
 		break;
@@ -5923,8 +6009,46 @@
 		ibdev_err(ibdev, "invalid xrceth error.\n");
 		break;
 	default:
+		ibdev_info(ibdev, "Undefined event %d.\n",
+			   irq_work->event_type);
 		break;
 	}
+}
+
+static void hns_roce_irq_work_handle(struct work_struct *work)
+{
+	struct hns_roce_work *irq_work =
+				container_of(work, struct hns_roce_work, work);
+	struct hns_roce_dev *hr_dev = irq_work->hr_dev;
+	int event_type = irq_work->event_type;
+	u32 queue_num = irq_work->queue_num;
+
+	switch (event_type) {
+	case HNS_ROCE_EVENT_TYPE_PATH_MIG:
+	case HNS_ROCE_EVENT_TYPE_PATH_MIG_FAILED:
+	case HNS_ROCE_EVENT_TYPE_COMM_EST:
+	case HNS_ROCE_EVENT_TYPE_SQ_DRAINED:
+	case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR:
+	case HNS_ROCE_EVENT_TYPE_SRQ_LAST_WQE_REACH:
+	case HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR:
+	case HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR:
+	case HNS_ROCE_EVENT_TYPE_XRCD_VIOLATION:
+	case HNS_ROCE_EVENT_TYPE_INVALID_XRCETH:
+		hns_roce_qp_event(hr_dev, queue_num, event_type);
+		break;
+	case HNS_ROCE_EVENT_TYPE_SRQ_LIMIT_REACH:
+	case HNS_ROCE_EVENT_TYPE_SRQ_CATAS_ERROR:
+		hns_roce_srq_event(hr_dev, queue_num, event_type);
+		break;
+	case HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR:
+	case HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW:
+		hns_roce_cq_event(hr_dev, queue_num, event_type);
+		break;
+	default:
+		break;
+	}
+
+	dump_aeqe_log(irq_work);
 
 	kfree(irq_work);
 }
@@ -5985,14 +6109,14 @@
 static irqreturn_t hns_roce_v2_aeq_int(struct hns_roce_dev *hr_dev,
 				       struct hns_roce_eq *eq)
 {
-	struct device *dev = hr_dev->dev;
 	struct hns_roce_aeqe *aeqe = next_aeqe_sw_v2(eq);
 	irqreturn_t aeqe_found = IRQ_NONE;
+	int num_aeqes = 0;
 	int event_type;
 	u32 queue_num;
 	int sub_type;
 
-	while (aeqe) {
+	while (aeqe && num_aeqes < HNS_AEQ_POLLING_BUDGET) {
 		/* Make sure we read AEQ entry after we have checked the
 		 * ownership bit
 		 */
@@ -6003,25 +6127,12 @@
 		queue_num = hr_reg_read(aeqe, AEQE_EVENT_QUEUE_NUM);
 
 		switch (event_type) {
-		case HNS_ROCE_EVENT_TYPE_PATH_MIG:
-		case HNS_ROCE_EVENT_TYPE_PATH_MIG_FAILED:
-		case HNS_ROCE_EVENT_TYPE_COMM_EST:
-		case HNS_ROCE_EVENT_TYPE_SQ_DRAINED:
 		case HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR:
-		case HNS_ROCE_EVENT_TYPE_SRQ_LAST_WQE_REACH:
 		case HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR:
 		case HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR:
 		case HNS_ROCE_EVENT_TYPE_XRCD_VIOLATION:
 		case HNS_ROCE_EVENT_TYPE_INVALID_XRCETH:
-			hns_roce_qp_event(hr_dev, queue_num, event_type);
-			break;
-		case HNS_ROCE_EVENT_TYPE_SRQ_LIMIT_REACH:
-		case HNS_ROCE_EVENT_TYPE_SRQ_CATAS_ERROR:
-			hns_roce_srq_event(hr_dev, queue_num, event_type);
-			break;
-		case HNS_ROCE_EVENT_TYPE_CQ_ACCESS_ERROR:
-		case HNS_ROCE_EVENT_TYPE_CQ_OVERFLOW:
-			hns_roce_cq_event(hr_dev, queue_num, event_type);
+			hns_roce_flush_cqe(hr_dev, queue_num);
 			break;
 		case HNS_ROCE_EVENT_TYPE_MB:
 			hns_roce_cmd_event(hr_dev,
@@ -6029,12 +6140,7 @@
 					aeqe->event.cmd.status,
 					le64_to_cpu(aeqe->event.cmd.out_param));
 			break;
-		case HNS_ROCE_EVENT_TYPE_DB_OVERFLOW:
-		case HNS_ROCE_EVENT_TYPE_FLR:
-			break;
 		default:
-			dev_err(dev, "unhandled event %d on EQ %d at idx %u.\n",
-				event_type, eq->eqn, eq->cons_index);
 			break;
 		}
 
@@ -6048,6 +6154,7 @@
 		hns_roce_v2_init_irq_work(hr_dev, eq, queue_num);
 
 		aeqe = next_aeqe_sw_v2(eq);
+		++num_aeqes;
 	}
 
 	update_eq_db(eq);
@@ -6118,6 +6225,7 @@
 	struct pci_dev *pdev = hr_dev->pci_dev;
 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
 	const struct hnae3_ae_ops *ops = ae_dev->ops;
+	enum hnae3_reset_type reset_type;
 	irqreturn_t int_work = IRQ_NONE;
 	u32 int_en;
 
@@ -6129,10 +6237,12 @@
 		roce_write(hr_dev, ROCEE_VF_ABN_INT_ST_REG,
 			   1 << HNS_ROCE_V2_VF_INT_ST_AEQ_OVERFLOW_S);
 
+		reset_type = hr_dev->is_vf ?
+			     HNAE3_VF_FUNC_RESET : HNAE3_FUNC_RESET;
+
 		/* Set reset level for reset_event() */
 		if (ops->set_default_reset_request)
-			ops->set_default_reset_request(ae_dev,
-						       HNAE3_FUNC_RESET);
+			ops->set_default_reset_request(ae_dev, reset_type);
 		if (ops->reset_event)
 			ops->reset_event(pdev, NULL);
 
@@ -6202,7 +6312,7 @@
 	    res_type == ECC_RESOURCE_SCCC)
 		return le64_to_cpu(*data);
 
-	return le64_to_cpu(*data) << PAGE_SHIFT;
+	return le64_to_cpu(*data) << HNS_HW_PAGE_SHIFT;
 }
 
 static int fmea_recover_others(struct hns_roce_dev *hr_dev, u32 res_type,
@@ -6316,9 +6426,16 @@
 	roce_write(hr_dev, ROCEE_VF_ABN_INT_CFG_REG, enable_flag);
 }
 
-static void hns_roce_v2_destroy_eqc(struct hns_roce_dev *hr_dev, u32 eqn)
+static void free_eq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
+{
+	hns_roce_mtr_destroy(hr_dev, &eq->mtr);
+}
+
+static void hns_roce_v2_destroy_eqc(struct hns_roce_dev *hr_dev,
+				    struct hns_roce_eq *eq)
 {
 	struct device *dev = hr_dev->dev;
+	int eqn = eq->eqn;
 	int ret;
 	u8 cmd;
 
@@ -6329,12 +6446,9 @@
 
 	ret = hns_roce_destroy_hw_ctx(hr_dev, cmd, eqn & HNS_ROCE_V2_EQN_M);
 	if (ret)
-		dev_err(dev, "[mailbox cmd] destroy eqc(%u) failed.\n", eqn);
-}
+		dev_err(dev, "[mailbox cmd] destroy eqc(%d) failed.\n", eqn);
 
-static void free_eq_buf(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
-{
-	hns_roce_mtr_destroy(hr_dev, &eq->mtr);
+	free_eq_buf(hr_dev, eq);
 }
 
 static void init_eq_config(struct hns_roce_dev *hr_dev, struct hns_roce_eq *eq)
@@ -6353,7 +6467,7 @@
 	u64 eqe_ba[MTT_MIN_COUNT] = { 0 };
 	struct hns_roce_eq_context *eqc;
 	u64 bt_ba = 0;
-	int count;
+	int ret;
 
 	eqc = mb_buf;
 	memset(eqc, 0, sizeof(struct hns_roce_eq_context));
@@ -6361,13 +6475,15 @@
 	init_eq_config(hr_dev, eq);
 
 	/* if not multi-hop, eqe buffer only use one trunk */
-	count = hns_roce_mtr_find(hr_dev, &eq->mtr, 0, eqe_ba, MTT_MIN_COUNT,
-				  &bt_ba);
-	if (count < 1) {
-		dev_err(hr_dev->dev, "failed to find EQE mtr\n");
-		return -ENOBUFS;
+	ret = hns_roce_mtr_find(hr_dev, &eq->mtr, 0, eqe_ba,
+				ARRAY_SIZE(eqe_ba));
+	if (ret) {
+		dev_err(hr_dev->dev, "failed to find EQE mtr, ret = %d\n", ret);
+		return ret;
 	}
 
+	bt_ba = hns_roce_get_mtr_ba(&eq->mtr);
+
 	hr_reg_write(eqc, EQC_EQ_ST, HNS_ROCE_V2_EQ_STATE_VALID);
 	hr_reg_write(eqc, EQC_EQE_HOP_NUM, eq->hop_num);
 	hr_reg_write(eqc, EQC_OVER_IGNORE, eq->over_ignore);
@@ -6572,6 +6688,9 @@
 	int ret;
 	int i;
 
+	if (hr_dev->caps.aeqe_depth < HNS_AEQ_POLLING_BUDGET)
+		return -EINVAL;
+
 	other_num = hr_dev->caps.num_other_vectors;
 	comp_num = hr_dev->caps.num_comp_vectors;
 	aeq_num = hr_dev->caps.num_aeq_vectors;
@@ -6641,7 +6760,7 @@
 
 err_create_eq_fail:
 	for (i -= 1; i >= 0; i--)
-		free_eq_buf(hr_dev, &eq_table->eq[i]);
+		hns_roce_v2_destroy_eqc(hr_dev, &eq_table->eq[i]);
 	kfree(eq_table->eq);
 
 	return ret;
@@ -6661,11 +6780,8 @@
 	__hns_roce_free_irq(hr_dev);
 	destroy_workqueue(hr_dev->irq_workq);
 
-	for (i = 0; i < eq_num; i++) {
-		hns_roce_v2_destroy_eqc(hr_dev, i);
-
-		free_eq_buf(hr_dev, &eq_table->eq[i]);
-	}
+	for (i = 0; i < eq_num; i++)
+		hns_roce_v2_destroy_eqc(hr_dev, &eq_table->eq[i]);
 
 	kfree(eq_table->eq);
 }
@@ -6831,9 +6947,6 @@
 	hr_dev->state = HNS_ROCE_DEVICE_STATE_UNINIT;
 	hns_roce_handle_device_err(hr_dev);
 
-	if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08)
-		free_mr_exit(hr_dev);
-
 	hns_roce_exit(hr_dev);
 	kfree(hr_dev->priv);
 	ib_dealloc_device(&hr_dev->ib_dev);
@@ -6894,6 +7007,7 @@
 
 	handle->rinfo.instance_state = HNS_ROCE_STATE_NON_INIT;
 }
+
 static int hns_roce_hw_v2_reset_notify_down(struct hnae3_handle *handle)
 {
 	struct hns_roce_dev *hr_dev;
@@ -6912,6 +7026,9 @@
 
 	hr_dev->active = false;
 	hr_dev->dis_db = true;
+
+	rdma_user_mmap_disassociate(&hr_dev->ib_dev);
+
 	hr_dev->state = HNS_ROCE_DEVICE_STATE_RST_DOWN;
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
@@ -85,6 +85,11 @@
 
 #define HNS_ROCE_V2_TABLE_CHUNK_SIZE		(1 << 18)
 
+/* budget must be smaller than aeqe_depth to guarantee that we update
+ * the ci before we polled all the entries in the EQ.
+ */
+#define HNS_AEQ_POLLING_BUDGET 64
+
 enum {
 	HNS_ROCE_CMD_FLAG_IN = BIT(0),
 	HNS_ROCE_CMD_FLAG_OUT = BIT(1),
@@ -224,6 +229,12 @@
 	HNS_SWITCH_PARAMETER_CFG			= 0x1033,
 };
 
+#define HNS_ROCE_OPC_POST_MB_TIMEOUT 35000
+struct hns_roce_cmdq_tx_timeout_map {
+	u16 opcode;
+	u32 tx_timeout;
+};
+
 enum {
 	TYPE_CRQ,
 	TYPE_CSQ,
@@ -894,6 +905,7 @@
 #define RC_SEND_WQE_OWNER RC_SEND_WQE_FIELD_LOC(7, 7)
 #define RC_SEND_WQE_CQE RC_SEND_WQE_FIELD_LOC(8, 8)
 #define RC_SEND_WQE_FENCE RC_SEND_WQE_FIELD_LOC(9, 9)
+#define RC_SEND_WQE_SO RC_SEND_WQE_FIELD_LOC(10, 10)
 #define RC_SEND_WQE_SE RC_SEND_WQE_FIELD_LOC(11, 11)
 #define RC_SEND_WQE_INLINE RC_SEND_WQE_FIELD_LOC(12, 12)
 #define RC_SEND_WQE_WQE_INDEX RC_SEND_WQE_FIELD_LOC(30, 15)
@@ -1316,7 +1328,7 @@
 struct hns_roce_dip {
 	u8 dgid[GID_LEN_V2];
 	u32 dip_idx;
-	struct list_head node; /* all dips are on a list */
+	u32 qp_cnt;
 };
 
 struct fmea_ram_ecc {
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/hns_roce_main.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/hns_roce_main.c
@@ -37,6 +37,7 @@
 #include <rdma/ib_smi.h>
 #include <rdma/ib_user_verbs.h>
 #include <rdma/ib_cache.h>
+#include "hnae3.h"
 #include "hns_roce_common.h"
 #include "hns_roce_device.h"
 #include "hns_roce_hem.h"
@@ -448,6 +449,11 @@
 	pgprot_t prot;
 	int ret;
 
+	if (hr_dev->dis_db) {
+		atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_MMAP_ERR_CNT]);
+		return -EPERM;
+	}
+
 	rdma_entry = rdma_user_mmap_entry_get_pgoff(uctx, vma->vm_pgoff);
 	if (!rdma_entry) {
 		atomic64_inc(&hr_dev->dfx_cnt[HNS_ROCE_DFX_MMAP_ERR_CNT]);
@@ -1099,8 +1105,6 @@
 
 	INIT_LIST_HEAD(&hr_dev->qp_list);
 	spin_lock_init(&hr_dev->qp_list_lock);
-	INIT_LIST_HEAD(&hr_dev->dip_list);
-	spin_lock_init(&hr_dev->dip_list_lock);
 
 	ret = hns_roce_register_device(hr_dev);
 	if (ret)
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/hns_roce_mr.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/hns_roce_mr.c
@@ -130,8 +130,8 @@
 					      key_to_hw_index(mr->key) &
 					      (hr_dev->caps.num_mtpts - 1));
 		if (ret)
-			ibdev_warn(ibdev, "failed to destroy mpt, ret = %d.\n",
-				   ret);
+			ibdev_warn_ratelimited(ibdev, "failed to destroy mpt, ret = %d.\n",
+					       ret);
 	}
 
 	free_mr_pbl(hr_dev, mr);
@@ -154,7 +154,7 @@
 	if (mr->type != MR_TYPE_FRMR)
 		ret = hr_dev->hw->write_mtpt(hr_dev, mailbox->buf, mr);
 	else
-		ret = hr_dev->hw->frmr_write_mtpt(hr_dev, mailbox->buf, mr);
+		ret = hr_dev->hw->frmr_write_mtpt(mailbox->buf, mr);
 	if (ret) {
 		dev_err(dev, "failed to write mtpt, ret = %d.\n", ret);
 		goto err_page;
@@ -427,24 +427,30 @@
 }
 
 int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents,
-		       unsigned int *sg_offset)
+		       unsigned int *sg_offset_p)
 {
+	unsigned int sg_offset = sg_offset_p ? *sg_offset_p : 0;
 	struct hns_roce_dev *hr_dev = to_hr_dev(ibmr->device);
 	struct ib_device *ibdev = &hr_dev->ib_dev;
 	struct hns_roce_mr *mr = to_hr_mr(ibmr);
 	struct hns_roce_mtr *mtr = &mr->pbl_mtr;
-	int ret = 0;
+	int ret, sg_num = 0;
+
+	if (!IS_ALIGNED(sg_offset, HNS_ROCE_FRMR_ALIGN_SIZE) ||
+	    ibmr->page_size < HNS_HW_PAGE_SIZE ||
+	    ibmr->page_size > HNS_HW_MAX_PAGE_SIZE)
+		return sg_num;
 
 	mr->npages = 0;
 	mr->page_list = kvcalloc(mr->pbl_mtr.hem_cfg.buf_pg_count,
 				 sizeof(dma_addr_t), GFP_KERNEL);
 	if (!mr->page_list)
-		return ret;
+		return sg_num;
 
-	ret = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset, hns_roce_set_page);
-	if (ret < 1) {
+	sg_num = ib_sg_to_pages(ibmr, sg, sg_nents, sg_offset_p, hns_roce_set_page);
+	if (sg_num < 1) {
 		ibdev_err(ibdev, "failed to store sg pages %u %u, cnt = %d.\n",
-			  mr->npages, mr->pbl_mtr.hem_cfg.buf_pg_count, ret);
+			  mr->npages, mr->pbl_mtr.hem_cfg.buf_pg_count, sg_num);
 		goto err_page_list;
 	}
 
@@ -455,17 +461,16 @@
 	ret = hns_roce_mtr_map(hr_dev, mtr, mr->page_list, mr->npages);
 	if (ret) {
 		ibdev_err(ibdev, "failed to map sg mtr, ret = %d.\n", ret);
-		ret = 0;
+		sg_num = 0;
 	} else {
 		mr->pbl_mtr.hem_cfg.buf_pg_shift = (u32)ilog2(ibmr->page_size);
-		ret = mr->npages;
 	}
 
 err_page_list:
 	kvfree(mr->page_list);
 	mr->page_list = NULL;
 
-	return ret;
+	return sg_num;
 }
 
 static void hns_roce_mw_free(struct hns_roce_dev *hr_dev,
@@ -721,7 +726,7 @@
 		return -ENOMEM;
 
 	if (mtr->umem)
-		npage = hns_roce_get_umem_bufs(hr_dev, pages, page_count,
+		npage = hns_roce_get_umem_bufs(pages, page_count,
 					       mtr->umem, page_shift);
 	else
 		npage = hns_roce_get_kmem_bufs(hr_dev, pages, page_count,
@@ -774,11 +779,6 @@
 	for (i = 0, mapped_cnt = 0; i < mtr->hem_cfg.region_count &&
 	     mapped_cnt < page_cnt; i++) {
 		r = &mtr->hem_cfg.region[i];
-		/* if hopnum is 0, no need to map pages in this region */
-		if (!r->hopnum) {
-			mapped_cnt += r->count;
-			continue;
-		}
 
 		if (r->offset + r->count > page_cnt) {
 			ret = -EINVAL;
@@ -809,47 +809,53 @@
 	return ret;
 }
 
-int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
-		      u32 offset, u64 *mtt_buf, int mtt_max, u64 *base_addr)
+static int hns_roce_get_direct_addr_mtt(struct hns_roce_hem_cfg *cfg,
+					u32 start_index, u64 *mtt_buf,
+					int mtt_cnt)
 {
-	struct hns_roce_hem_cfg *cfg = &mtr->hem_cfg;
-	int mtt_count, left;
-	u32 start_index;
+	int mtt_count;
 	int total = 0;
-	__le64 *mtts;
 	u32 npage;
 	u64 addr;
 
-	if (!mtt_buf || mtt_max < 1)
-		goto done;
+	if (mtt_cnt > cfg->region_count)
+		return -EINVAL;
 
-	/* no mtt memory in direct mode, so just return the buffer address */
-	if (cfg->is_direct) {
-		start_index = offset >> HNS_HW_PAGE_SHIFT;
-		for (mtt_count = 0; mtt_count < cfg->region_count &&
-		     total < mtt_max; mtt_count++) {
-			npage = cfg->region[mtt_count].offset;
-			if (npage < start_index)
-				continue;
+	for (mtt_count = 0; mtt_count < cfg->region_count && total < mtt_cnt;
+	     mtt_count++) {
+		npage = cfg->region[mtt_count].offset;
+		if (npage < start_index)
+			continue;
 
-			addr = cfg->root_ba + (npage << HNS_HW_PAGE_SHIFT);
-			mtt_buf[total] = addr;
+		addr = cfg->root_ba + (npage << HNS_HW_PAGE_SHIFT);
+		mtt_buf[total] = addr;
 
-			total++;
-		}
-
-		goto done;
+		total++;
 	}
 
-	start_index = offset >> cfg->buf_pg_shift;
-	left = mtt_max;
+	if (!total)
+		return -ENOENT;
+
+	return 0;
+}
+
+static int hns_roce_get_mhop_mtt(struct hns_roce_dev *hr_dev,
+				 struct hns_roce_mtr *mtr, u32 start_index,
+				 u64 *mtt_buf, int mtt_cnt)
+{
+	int left = mtt_cnt;
+	int total = 0;
+	int mtt_count;
+	__le64 *mtts;
+	u32 npage;
+
 	while (left > 0) {
 		mtt_count = 0;
 		mtts = hns_roce_hem_list_find_mtt(hr_dev, &mtr->hem_list,
 						  start_index + total,
 						  &mtt_count);
 		if (!mtts || !mtt_count)
-			goto done;
+			break;
 
 		npage = min(mtt_count, left);
 		left -= npage;
@@ -857,11 +863,33 @@
 			mtt_buf[total++] = le64_to_cpu(mtts[mtt_count]);
 	}
 
-done:
-	if (base_addr)
-		*base_addr = cfg->root_ba;
+	if (!total)
+		return -ENOENT;
+
+	return 0;
+}
+
+int hns_roce_mtr_find(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr,
+		      u32 offset, u64 *mtt_buf, int mtt_max)
+{
+	struct hns_roce_hem_cfg *cfg = &mtr->hem_cfg;
+	u32 start_index;
+	int ret;
+
+	if (!mtt_buf || mtt_max < 1)
+		return -EINVAL;
 
-	return total;
+	/* no mtt memory in direct mode, so just return the buffer address */
+	if (cfg->is_direct) {
+		start_index = offset >> HNS_HW_PAGE_SHIFT;
+		ret = hns_roce_get_direct_addr_mtt(cfg, start_index,
+						   mtt_buf, mtt_max);
+	} else {
+		start_index = offset >> cfg->buf_pg_shift;
+		ret = hns_roce_get_mhop_mtt(hr_dev, mtr, start_index,
+					    mtt_buf, mtt_max);
+	}
+	return ret;
 }
 
 static int mtr_init_buf_cfg(struct hns_roce_dev *hr_dev,
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/hns_roce_qp.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/hns_roce_qp.c
@@ -39,6 +39,25 @@
 #include "hns_roce_device.h"
 #include "hns_roce_hem.h"
 
+static struct hns_roce_qp *hns_roce_qp_lookup(struct hns_roce_dev *hr_dev,
+					      u32 qpn)
+{
+	struct device *dev = hr_dev->dev;
+	struct hns_roce_qp *qp;
+	unsigned long flags;
+
+	xa_lock_irqsave(&hr_dev->qp_table_xa, flags);
+	qp = __hns_roce_qp_lookup(hr_dev, qpn);
+	if (qp)
+		refcount_inc(&qp->refcount);
+	xa_unlock_irqrestore(&hr_dev->qp_table_xa, flags);
+
+	if (!qp)
+		dev_warn(dev, "async event for bogus QP %08x\n", qpn);
+
+	return qp;
+}
+
 static void flush_work_handle(struct work_struct *work)
 {
 	struct hns_roce_work *flush_work = container_of(work,
@@ -71,11 +90,18 @@
 void init_flush_work(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp)
 {
 	struct hns_roce_work *flush_work = &hr_qp->flush_work;
+	unsigned long flags;
+
+	spin_lock_irqsave(&hr_qp->flush_lock, flags);
+	/* Exit directly after destroy_qp() */
+	if (test_bit(HNS_ROCE_STOP_FLUSH_FLAG, &hr_qp->flush_flag)) {
+		spin_unlock_irqrestore(&hr_qp->flush_lock, flags);
+		return;
+	}
 
-	flush_work->hr_dev = hr_dev;
-	INIT_WORK(&flush_work->work, flush_work_handle);
 	refcount_inc(&hr_qp->refcount);
 	queue_work(hr_dev->irq_workq, &flush_work->work);
+	spin_unlock_irqrestore(&hr_qp->flush_lock, flags);
 }
 
 void flush_cqe(struct hns_roce_dev *dev, struct hns_roce_qp *qp)
@@ -95,31 +121,28 @@
 
 void hns_roce_qp_event(struct hns_roce_dev *hr_dev, u32 qpn, int event_type)
 {
-	struct device *dev = hr_dev->dev;
 	struct hns_roce_qp *qp;
 
-	xa_lock(&hr_dev->qp_table_xa);
-	qp = __hns_roce_qp_lookup(hr_dev, qpn);
-	if (qp)
-		refcount_inc(&qp->refcount);
-	xa_unlock(&hr_dev->qp_table_xa);
-
-	if (!qp) {
-		dev_warn(dev, "async event for bogus QP %08x\n", qpn);
+	qp = hns_roce_qp_lookup(hr_dev, qpn);
+	if (!qp)
 		return;
-	}
 
-	if (event_type == HNS_ROCE_EVENT_TYPE_WQ_CATAS_ERROR ||
-	    event_type == HNS_ROCE_EVENT_TYPE_INV_REQ_LOCAL_WQ_ERROR ||
-	    event_type == HNS_ROCE_EVENT_TYPE_LOCAL_WQ_ACCESS_ERROR ||
-	    event_type == HNS_ROCE_EVENT_TYPE_XRCD_VIOLATION ||
-	    event_type == HNS_ROCE_EVENT_TYPE_INVALID_XRCETH) {
-		qp->state = IB_QPS_ERR;
+	qp->event(qp, (enum hns_roce_event)event_type);
 
-		flush_cqe(hr_dev, qp);
-	}
+	if (refcount_dec_and_test(&qp->refcount))
+		complete(&qp->free);
+}
 
-	qp->event(qp, (enum hns_roce_event)event_type);
+void hns_roce_flush_cqe(struct hns_roce_dev *hr_dev, u32 qpn)
+{
+	struct hns_roce_qp *qp;
+
+	qp = hns_roce_qp_lookup(hr_dev, qpn);
+	if (!qp)
+		return;
+
+	qp->state = IB_QPS_ERR;
+	flush_cqe(hr_dev, qp);
 
 	if (refcount_dec_and_test(&qp->refcount))
 		complete(&qp->free);
@@ -531,13 +554,15 @@
 {
 	unsigned int inline_sge;
 
-	inline_sge = roundup_pow_of_two(max_inline_data) / HNS_ROCE_SGE_SIZE;
+	if (!max_inline_data)
+		return 0;
 
 	/*
 	 * if max_inline_data less than
 	 * HNS_ROCE_SGE_IN_WQE * HNS_ROCE_SGE_SIZE,
 	 * In addition to ud's mode, no need to extend sge.
 	 */
+	inline_sge = roundup_pow_of_two(max_inline_data) / HNS_ROCE_SGE_SIZE;
 	if (!is_ud_or_gsi && inline_sge <= HNS_ROCE_SGE_IN_WQE)
 		inline_sge = 0;
 
@@ -1057,11 +1082,11 @@
 }
 
 static int hns_roce_create_qp_common(struct hns_roce_dev *hr_dev,
-				     struct ib_pd *ib_pd,
 				     struct ib_qp_init_attr *init_attr,
 				     struct ib_udata *udata,
 				     struct hns_roce_qp *hr_qp)
 {
+	struct hns_roce_work *flush_work = &hr_qp->flush_work;
 	struct hns_roce_ib_create_qp_resp resp = {};
 	struct ib_device *ibdev = &hr_dev->ib_dev;
 	struct hns_roce_ib_create_qp ucmd = {};
@@ -1070,9 +1095,12 @@
 	mutex_init(&hr_qp->mutex);
 	spin_lock_init(&hr_qp->sq.lock);
 	spin_lock_init(&hr_qp->rq.lock);
+	spin_lock_init(&hr_qp->flush_lock);
 
 	hr_qp->state = IB_QPS_RESET;
 	hr_qp->flush_flag = 0;
+	flush_work->hr_dev = hr_dev;
+	INIT_WORK(&flush_work->work, flush_work_handle);
 
 	if (init_attr->create_flags)
 		return -EOPNOTSUPP;
@@ -1211,7 +1239,6 @@
 	struct ib_device *ibdev = qp->device;
 	struct hns_roce_dev *hr_dev = to_hr_dev(ibdev);
 	struct hns_roce_qp *hr_qp = to_hr_qp(qp);
-	struct ib_pd *pd = qp->pd;
 	int ret;
 
 	ret = check_qp_type(hr_dev, init_attr->qp_type, !!udata);
@@ -1226,7 +1253,7 @@
 		hr_qp->phy_port = hr_dev->iboe.phy_port[hr_qp->port];
 	}
 
-	ret = hns_roce_create_qp_common(hr_dev, pd, init_attr, udata, hr_qp);
+	ret = hns_roce_create_qp_common(hr_dev, init_attr, udata, hr_qp);
 	if (ret)
 		ibdev_err(ibdev, "create QP type 0x%x failed(%d)\n",
 			  init_attr->qp_type, ret);
@@ -1383,19 +1410,19 @@
 		__acquire(&send_cq->lock);
 		__acquire(&recv_cq->lock);
 	} else if (unlikely(send_cq != NULL && recv_cq == NULL)) {
-		spin_lock_irq(&send_cq->lock);
+		spin_lock(&send_cq->lock);
 		__acquire(&recv_cq->lock);
 	} else if (unlikely(send_cq == NULL && recv_cq != NULL)) {
-		spin_lock_irq(&recv_cq->lock);
+		spin_lock(&recv_cq->lock);
 		__acquire(&send_cq->lock);
 	} else if (send_cq == recv_cq) {
-		spin_lock_irq(&send_cq->lock);
+		spin_lock(&send_cq->lock);
 		__acquire(&recv_cq->lock);
 	} else if (send_cq->cqn < recv_cq->cqn) {
-		spin_lock_irq(&send_cq->lock);
+		spin_lock(&send_cq->lock);
 		spin_lock_nested(&recv_cq->lock, SINGLE_DEPTH_NESTING);
 	} else {
-		spin_lock_irq(&recv_cq->lock);
+		spin_lock(&recv_cq->lock);
 		spin_lock_nested(&send_cq->lock, SINGLE_DEPTH_NESTING);
 	}
 }
@@ -1415,13 +1442,13 @@
 		spin_unlock(&recv_cq->lock);
 	} else if (send_cq == recv_cq) {
 		__release(&recv_cq->lock);
-		spin_unlock_irq(&send_cq->lock);
+		spin_unlock(&send_cq->lock);
 	} else if (send_cq->cqn < recv_cq->cqn) {
 		spin_unlock(&recv_cq->lock);
-		spin_unlock_irq(&send_cq->lock);
+		spin_unlock(&send_cq->lock);
 	} else {
 		spin_unlock(&send_cq->lock);
-		spin_unlock_irq(&recv_cq->lock);
+		spin_unlock(&recv_cq->lock);
 	}
 }
 
@@ -1469,14 +1496,10 @@
 	unsigned int reserved_from_bot;
 	unsigned int i;
 
-	qp_table->idx_table.spare_idx = kcalloc(hr_dev->caps.num_qps,
-					sizeof(u32), GFP_KERNEL);
-	if (!qp_table->idx_table.spare_idx)
-		return -ENOMEM;
-
 	mutex_init(&qp_table->scc_mutex);
 	mutex_init(&qp_table->bank_mutex);
 	xa_init(&hr_dev->qp_table_xa);
+	xa_init(&qp_table->dip_xa);
 
 	reserved_from_bot = hr_dev->caps.reserved_qps;
 
@@ -1501,5 +1524,5 @@
 
 	for (i = 0; i < HNS_ROCE_QP_BANK_NUM; i++)
 		ida_destroy(&hr_dev->qp_table.bank[i].ida);
-	kfree(hr_dev->qp_table.idx_table.spare_idx);
+	xa_destroy(&hr_dev->qp_table.dip_xa);
 }
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/hns/hns_roce_srq.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/hns/hns_roce_srq.c
@@ -123,7 +123,7 @@
 		return ret;
 	}
 
-	ret = xa_err(xa_store(&srq_table->xa, srq->srqn, srq, GFP_KERNEL));
+	ret = xa_err(xa_store_irq(&srq_table->xa, srq->srqn, srq, GFP_KERNEL));
 	if (ret) {
 		ibdev_err(ibdev, "failed to store SRQC, ret = %d.\n", ret);
 		goto err_put;
@@ -136,7 +136,7 @@
 	return 0;
 
 err_xa:
-	xa_erase(&srq_table->xa, srq->srqn);
+	xa_erase_irq(&srq_table->xa, srq->srqn);
 err_put:
 	hns_roce_table_put(hr_dev, &srq_table->table, srq->srqn);
 
@@ -151,10 +151,10 @@
 	ret = hns_roce_destroy_hw_ctx(hr_dev, HNS_ROCE_CMD_DESTROY_SRQ,
 				      srq->srqn);
 	if (ret)
-		dev_err(hr_dev->dev, "DESTROY_SRQ failed (%d) for SRQN %06lx\n",
-			ret, srq->srqn);
+		dev_err_ratelimited(hr_dev->dev, "DESTROY_SRQ failed (%d) for SRQN %06lx\n",
+				    ret, srq->srqn);
 
-	xa_erase(&srq_table->xa, srq->srqn);
+	xa_erase_irq(&srq_table->xa, srq->srqn);
 
 	if (refcount_dec_and_test(&srq->refcount))
 		complete(&srq->free);
@@ -250,7 +250,7 @@
 	hns_roce_mtr_destroy(hr_dev, &srq->buf_mtr);
 }
 
-static int alloc_srq_wrid(struct hns_roce_dev *hr_dev, struct hns_roce_srq *srq)
+static int alloc_srq_wrid(struct hns_roce_srq *srq)
 {
 	srq->wrid = kvmalloc_array(srq->wqe_cnt, sizeof(u64), GFP_KERNEL);
 	if (!srq->wrid)
@@ -297,7 +297,7 @@
 
 	max_sge = proc_srq_sge(hr_dev, srq, !!udata);
 	if (attr->max_wr > hr_dev->caps.max_srq_wrs ||
-	    attr->max_sge > max_sge) {
+	    attr->max_sge > max_sge || !attr->max_sge) {
 		ibdev_err(&hr_dev->ib_dev,
 			  "invalid SRQ attr, depth = %u, sge = %u.\n",
 			  attr->max_wr, attr->max_sge);
@@ -366,7 +366,7 @@
 		goto err_idx;
 
 	if (!udata) {
-		ret = alloc_srq_wrid(hr_dev, srq);
+		ret = alloc_srq_wrid(srq);
 		if (ret)
 			goto err_wqe_buf;
 	}
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/irdma/cm.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/irdma/cm.c
@@ -3630,7 +3630,7 @@
 /**
  * irdma_accept - registered call for connection to be accepted
  * @cm_id: cm information for passive connection
- * @conn_param: accpet parameters
+ * @conn_param: accept parameters
  */
 int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 {
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/irdma/verbs.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/irdma/verbs.c
@@ -719,7 +719,6 @@
 		info->rq_pa + (ukinfo->rq_depth * IRDMA_QP_WQE_MIN_SIZE);
 	ukinfo->sq_size = ukinfo->sq_depth >> ukinfo->sq_shift;
 	ukinfo->rq_size = ukinfo->rq_depth >> ukinfo->rq_shift;
-	ukinfo->qp_id = iwqp->ibqp.qp_num;
 
 	iwqp->max_send_wr = (ukinfo->sq_depth - IRDMA_SQ_RSVD) >> ukinfo->sq_shift;
 	iwqp->max_recv_wr = (ukinfo->rq_depth - IRDMA_RQ_RSVD) >> ukinfo->rq_shift;
@@ -944,7 +943,7 @@
 	iwqp->host_ctx.size = IRDMA_QP_CTX_SIZE;
 
 	init_info.pd = &iwpd->sc_pd;
-	init_info.qp_uk_init_info.qp_id = iwqp->ibqp.qp_num;
+	init_info.qp_uk_init_info.qp_id = qp_num;
 	if (!rdma_protocol_roce(&iwdev->ibdev, 1))
 		init_info.qp_uk_init_info.first_sq_wq = 1;
 	iwqp->ctx_info.qp_compl_ctx = (uintptr_t)qp;
@@ -1348,7 +1347,7 @@
 		if (attr->max_dest_rd_atomic > dev->hw_attrs.max_hw_ird) {
 			ibdev_err(&iwdev->ibdev,
 				  "rd_atomic = %d, above max_hw_ird=%d\n",
-				   attr->max_rd_atomic,
+				   attr->max_dest_rd_atomic,
 				   dev->hw_attrs.max_hw_ird);
 			return -EINVAL;
 		}
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mana/cq.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mana/cq.c
@@ -16,7 +16,7 @@
 	int err;
 
 	mdev = container_of(ibdev, struct mana_ib_dev, ib_dev);
-	gc = mdev->gdma_dev->gdma_context;
+	gc = mdev_to_gc(mdev);
 
 	if (udata->inlen < sizeof(ucmd))
 		return -EINVAL;
@@ -39,37 +39,13 @@
 	}
 
 	cq->cqe = attr->cqe;
-	cq->umem = ib_umem_get(ibdev, ucmd.buf_addr, cq->cqe * COMP_ENTRY_SIZE,
-			       IB_ACCESS_LOCAL_WRITE);
-	if (IS_ERR(cq->umem)) {
-		err = PTR_ERR(cq->umem);
-		ibdev_dbg(ibdev, "Failed to get umem for create cq, err %d\n",
-			  err);
-		return err;
-	}
-
-	err = mana_ib_gd_create_dma_region(mdev, cq->umem, &cq->gdma_region);
+	err = mana_ib_create_queue(mdev, ucmd.buf_addr, cq->cqe * COMP_ENTRY_SIZE, &cq->queue);
 	if (err) {
-		ibdev_dbg(ibdev,
-			  "Failed to create dma region for create cq, %d\n",
-			  err);
-		goto err_release_umem;
+		ibdev_dbg(ibdev, "Failed to create queue for create cq, %d\n", err);
+		return err;
 	}
 
-	ibdev_dbg(ibdev,
-		  "mana_ib_gd_create_dma_region ret %d gdma_region 0x%llx\n",
-		  err, cq->gdma_region);
-
-	/*
-	 * The CQ ID is not known at this time. The ID is generated at create_qp
-	 */
-	cq->id = INVALID_QUEUE_ID;
-
 	return 0;
-
-err_release_umem:
-	ib_umem_release(cq->umem);
-	return err;
 }
 
 int mana_ib_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
@@ -78,32 +54,45 @@
 	struct ib_device *ibdev = ibcq->device;
 	struct mana_ib_dev *mdev;
 	struct gdma_context *gc;
-	int err;
 
 	mdev = container_of(ibdev, struct mana_ib_dev, ib_dev);
-	gc = mdev->gdma_dev->gdma_context;
+	gc = mdev_to_gc(mdev);
 
-	err = mana_ib_gd_destroy_dma_region(mdev, cq->gdma_region);
-	if (err) {
-		ibdev_dbg(ibdev,
-			  "Failed to destroy dma region, %d\n", err);
-		return err;
-	}
-
-	if (cq->id != INVALID_QUEUE_ID) {
-		kfree(gc->cq_table[cq->id]);
-		gc->cq_table[cq->id] = NULL;
+	if (cq->queue.id != INVALID_QUEUE_ID) {
+		kfree(gc->cq_table[cq->queue.id]);
+		gc->cq_table[cq->queue.id] = NULL;
 	}
 
-	ib_umem_release(cq->umem);
+	mana_ib_destroy_queue(mdev, &cq->queue);
 
 	return 0;
 }
 
-void mana_ib_cq_handler(void *ctx, struct gdma_queue *gdma_cq)
+static void mana_ib_cq_handler(void *ctx, struct gdma_queue *gdma_cq)
 {
 	struct mana_ib_cq *cq = ctx;
 
 	if (cq->ibcq.comp_handler)
 		cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
 }
+
+int mana_ib_install_cq_cb(struct mana_ib_dev *mdev, struct mana_ib_cq *cq)
+{
+	struct gdma_context *gc = mdev_to_gc(mdev);
+	struct gdma_queue *gdma_cq;
+
+	if (cq->queue.id >= gc->max_num_cqs)
+		return -EINVAL;
+	/* Create CQ table entry */
+	WARN_ON(gc->cq_table[cq->queue.id]);
+	gdma_cq = kzalloc(sizeof(*gdma_cq), GFP_KERNEL);
+	if (!gdma_cq)
+		return -ENOMEM;
+
+	gdma_cq->cq.context = cq;
+	gdma_cq->type = GDMA_CQ;
+	gdma_cq->cq.callback = mana_ib_cq_handler;
+	gdma_cq->id = cq->queue.id;
+	gc->cq_table[cq->queue.id] = gdma_cq;
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mana/device.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mana/device.c
@@ -51,6 +51,7 @@
 {
 	struct mana_adev *madev = container_of(adev, struct mana_adev, adev);
 	struct gdma_dev *mdev = madev->mdev;
+	struct net_device *upper_ndev;
 	struct mana_context *mc;
 	struct mana_ib_dev *dev;
 	int ret;
@@ -77,6 +78,20 @@
 	dev->ib_dev.num_comp_vectors = 1;
 	dev->ib_dev.dev.parent = mdev->gdma_context->dev;
 
+	rcu_read_lock(); /* required to get upper dev */
+	upper_ndev = netdev_master_upper_dev_get_rcu(mc->ports[0]);
+	if (!upper_ndev) {
+		rcu_read_unlock();
+		ibdev_err(&dev->ib_dev, "Failed to get master netdev");
+		goto free_ib_device;
+	}
+	ret = ib_device_set_netdev(&dev->ib_dev, upper_ndev, 1);
+	rcu_read_unlock();
+	if (ret) {
+		ibdev_err(&dev->ib_dev, "Failed to set ib netdev, ret %d", ret);
+		goto free_ib_device;
+	}
+
 	ret = mana_gd_register_device(&mdev->gdma_context->mana_ib);
 	if (ret) {
 		ibdev_err(&dev->ib_dev, "Failed to register device, ret %d",
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mana/main.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mana/main.c
@@ -8,13 +8,10 @@
 void mana_ib_uncfg_vport(struct mana_ib_dev *dev, struct mana_ib_pd *pd,
 			 u32 port)
 {
-	struct gdma_dev *gd = &dev->gdma_dev->gdma_context->mana;
 	struct mana_port_context *mpc;
 	struct net_device *ndev;
-	struct mana_context *mc;
 
-	mc = gd->driver_data;
-	ndev = mc->ports[port];
+	ndev = mana_ib_get_netdev(&dev->ib_dev, port);
 	mpc = netdev_priv(ndev);
 
 	mutex_lock(&pd->vport_mutex);
@@ -31,14 +28,11 @@
 int mana_ib_cfg_vport(struct mana_ib_dev *dev, u32 port, struct mana_ib_pd *pd,
 		      u32 doorbell_id)
 {
-	struct gdma_dev *mdev = &dev->gdma_dev->gdma_context->mana;
 	struct mana_port_context *mpc;
-	struct mana_context *mc;
 	struct net_device *ndev;
 	int err;
 
-	mc = mdev->driver_data;
-	ndev = mc->ports[port];
+	ndev = mana_ib_get_netdev(&dev->ib_dev, port);
 	mpc = netdev_priv(ndev);
 
 	mutex_lock(&pd->vport_mutex);
@@ -79,17 +73,17 @@
 	struct gdma_create_pd_req req = {};
 	enum gdma_pd_flags flags = 0;
 	struct mana_ib_dev *dev;
-	struct gdma_dev *mdev;
+	struct gdma_context *gc;
 	int err;
 
 	dev = container_of(ibdev, struct mana_ib_dev, ib_dev);
-	mdev = dev->gdma_dev;
+	gc = mdev_to_gc(dev);
 
 	mana_gd_init_req_hdr(&req.hdr, GDMA_CREATE_PD, sizeof(req),
 			     sizeof(resp));
 
 	req.flags = flags;
-	err = mana_gd_send_request(mdev->gdma_context, sizeof(req), &req,
+	err = mana_gd_send_request(gc, sizeof(req), &req,
 				   sizeof(resp), &resp);
 
 	if (err || resp.hdr.status) {
@@ -119,17 +113,17 @@
 	struct gdma_destory_pd_resp resp = {};
 	struct gdma_destroy_pd_req req = {};
 	struct mana_ib_dev *dev;
-	struct gdma_dev *mdev;
+	struct gdma_context *gc;
 	int err;
 
 	dev = container_of(ibdev, struct mana_ib_dev, ib_dev);
-	mdev = dev->gdma_dev;
+	gc = mdev_to_gc(dev);
 
 	mana_gd_init_req_hdr(&req.hdr, GDMA_DESTROY_PD, sizeof(req),
 			     sizeof(resp));
 
 	req.pd_handle = pd->pd_handle;
-	err = mana_gd_send_request(mdev->gdma_context, sizeof(req), &req,
+	err = mana_gd_send_request(gc, sizeof(req), &req,
 				   sizeof(resp), &resp);
 
 	if (err || resp.hdr.status) {
@@ -206,13 +200,11 @@
 	struct ib_device *ibdev = ibcontext->device;
 	struct mana_ib_dev *mdev;
 	struct gdma_context *gc;
-	struct gdma_dev *dev;
 	int doorbell_page;
 	int ret;
 
 	mdev = container_of(ibdev, struct mana_ib_dev, ib_dev);
-	dev = mdev->gdma_dev;
-	gc = dev->gdma_context;
+	gc = mdev_to_gc(mdev);
 
 	/* Allocate a doorbell page index */
 	ret = mana_gd_allocate_doorbell_page(gc, &doorbell_page);
@@ -238,13 +230,56 @@
 	int ret;
 
 	mdev = container_of(ibdev, struct mana_ib_dev, ib_dev);
-	gc = mdev->gdma_dev->gdma_context;
+	gc = mdev_to_gc(mdev);
 
 	ret = mana_gd_destroy_doorbell_page(gc, mana_ucontext->doorbell);
 	if (ret)
 		ibdev_dbg(ibdev, "Failed to destroy doorbell page %d\n", ret);
 }
 
+int mana_ib_create_queue(struct mana_ib_dev *mdev, u64 addr, u32 size,
+			 struct mana_ib_queue *queue)
+{
+	struct ib_umem *umem;
+	int err;
+
+	queue->umem = NULL;
+	queue->id = INVALID_QUEUE_ID;
+	queue->gdma_region = GDMA_INVALID_DMA_REGION;
+
+	umem = ib_umem_get(&mdev->ib_dev, addr, size, IB_ACCESS_LOCAL_WRITE);
+	if (IS_ERR(umem)) {
+		err = PTR_ERR(umem);
+		ibdev_dbg(&mdev->ib_dev, "Failed to get umem, %d\n", err);
+		return err;
+	}
+
+	err = mana_ib_create_zero_offset_dma_region(mdev, umem, &queue->gdma_region);
+	if (err) {
+		ibdev_dbg(&mdev->ib_dev, "Failed to create dma region, %d\n", err);
+		goto free_umem;
+	}
+	queue->umem = umem;
+
+	ibdev_dbg(&mdev->ib_dev,
+		  "create_dma_region ret %d gdma_region 0x%llx\n",
+		  err, queue->gdma_region);
+
+	return 0;
+free_umem:
+	ib_umem_release(umem);
+	return err;
+}
+
+void mana_ib_destroy_queue(struct mana_ib_dev *mdev, struct mana_ib_queue *queue)
+{
+	/* Ignore return code as there is not much we can do about it.
+	 * The error message is printed inside.
+	 */
+	mana_ib_gd_destroy_dma_region(mdev, queue->gdma_region);
+	ib_umem_release(queue->umem);
+}
+
 static int
 mana_ib_gd_first_dma_region(struct mana_ib_dev *dev,
 			    struct gdma_context *gc,
@@ -309,8 +344,8 @@
 	return 0;
 }
 
-int mana_ib_gd_create_dma_region(struct mana_ib_dev *dev, struct ib_umem *umem,
-				 mana_handle_t *gdma_region)
+static int mana_ib_gd_create_dma_region(struct mana_ib_dev *dev, struct ib_umem *umem,
+					mana_handle_t *gdma_region, unsigned long page_sz)
 {
 	struct gdma_dma_region_add_pages_req *add_req = NULL;
 	size_t num_pages_processed = 0, num_pages_to_handle;
@@ -322,23 +357,14 @@
 	size_t max_pgs_create_cmd;
 	struct gdma_context *gc;
 	size_t num_pages_total;
-	struct gdma_dev *mdev;
-	unsigned long page_sz;
 	unsigned int tail = 0;
 	u64 *page_addr_list;
 	void *request_buf;
 	int err;
 
-	mdev = dev->gdma_dev;
-	gc = mdev->gdma_context;
+	gc = mdev_to_gc(dev);
 	hwc = gc->hwc.driver_data;
 
-	/* Hardware requires dma region to align to chosen page size */
-	page_sz = ib_umem_find_best_pgsz(umem, PAGE_SZ_BM, 0);
-	if (!page_sz) {
-		ibdev_dbg(&dev->ib_dev, "failed to find page size.\n");
-		return -ENOMEM;
-	}
 	num_pages_total = ib_umem_num_dma_blocks(umem, page_sz);
 
 	max_pgs_create_cmd =
@@ -358,8 +384,8 @@
 			     sizeof(struct gdma_create_dma_region_resp));
 
 	create_req->length = umem->length;
-	create_req->offset_in_page = umem->address & (page_sz - 1);
-	create_req->gdma_page_type = order_base_2(page_sz) - PAGE_SHIFT;
+	create_req->offset_in_page = ib_umem_dma_offset(umem, page_sz);
+	create_req->gdma_page_type = order_base_2(page_sz) - MANA_PAGE_SHIFT;
 	create_req->page_count = num_pages_total;
 
 	ibdev_dbg(&dev->ib_dev, "size_dma_region %lu num_pages_total %lu\n",
@@ -424,12 +450,39 @@
 	return err;
 }
 
+int mana_ib_create_dma_region(struct mana_ib_dev *dev, struct ib_umem *umem,
+			      mana_handle_t *gdma_region, u64 virt)
+{
+	unsigned long page_sz;
+
+	page_sz = ib_umem_find_best_pgsz(umem, PAGE_SZ_BM, virt);
+	if (!page_sz) {
+		ibdev_dbg(&dev->ib_dev, "Failed to find page size.\n");
+		return -EINVAL;
+	}
+
+	return mana_ib_gd_create_dma_region(dev, umem, gdma_region, page_sz);
+}
+
+int mana_ib_create_zero_offset_dma_region(struct mana_ib_dev *dev, struct ib_umem *umem,
+					  mana_handle_t *gdma_region)
+{
+	unsigned long page_sz;
+
+	/* Hardware requires dma region to align to chosen page size */
+	page_sz = ib_umem_find_best_pgoff(umem, PAGE_SZ_BM, 0);
+	if (!page_sz) {
+		ibdev_dbg(&dev->ib_dev, "Failed to find page size.\n");
+		return -EINVAL;
+	}
+
+	return mana_ib_gd_create_dma_region(dev, umem, gdma_region, page_sz);
+}
+
 int mana_ib_gd_destroy_dma_region(struct mana_ib_dev *dev, u64 gdma_region)
 {
-	struct gdma_dev *mdev = dev->gdma_dev;
-	struct gdma_context *gc;
+	struct gdma_context *gc = mdev_to_gc(dev);
 
-	gc = mdev->gdma_context;
 	ibdev_dbg(&dev->ib_dev, "destroy dma region 0x%llx\n", gdma_region);
 
 	return mana_gd_destroy_dma_region(gc, gdma_region);
@@ -447,7 +500,7 @@
 	int ret;
 
 	mdev = container_of(ibdev, struct mana_ib_dev, ib_dev);
-	gc = mdev->gdma_dev->gdma_context;
+	gc = mdev_to_gc(mdev);
 
 	if (vma->vm_pgoff != 0) {
 		ibdev_dbg(ibdev, "Unexpected vm_pgoff %lu\n", vma->vm_pgoff);
@@ -460,13 +513,13 @@
 	      PAGE_SHIFT;
 	prot = pgprot_writecombine(vma->vm_page_prot);
 
-	ret = rdma_user_mmap_io(ibcontext, vma, pfn, gc->db_page_size, prot,
+	ret = rdma_user_mmap_io(ibcontext, vma, pfn, PAGE_SIZE, prot,
 				NULL);
 	if (ret)
 		ibdev_dbg(ibdev, "can't rdma_user_mmap_io ret %d\n", ret);
 	else
-		ibdev_dbg(ibdev, "mapped I/O pfn 0x%llx page_size %u, ret %d\n",
-			  pfn, gc->db_page_size, ret);
+		ibdev_dbg(ibdev, "mapped I/O pfn 0x%llx page_size %lu, ret %d\n",
+			  pfn, PAGE_SIZE, ret);
 
 	return ret;
 }
@@ -474,11 +527,18 @@
 int mana_ib_get_port_immutable(struct ib_device *ibdev, u32 port_num,
 			       struct ib_port_immutable *immutable)
 {
-	/*
-	 * This version only support RAW_PACKET
-	 * other values need to be filled for other types
-	 */
+	struct ib_port_attr attr;
+	int err;
+
+	err = ib_query_port(ibdev, port_num, &attr);
+	if (err)
+		return err;
+
+	immutable->pkey_tbl_len = attr.pkey_tbl_len;
+	immutable->gid_tbl_len = attr.gid_tbl_len;
 	immutable->core_cap_flags = RDMA_CORE_PORT_RAW_PACKET;
+	if (port_num == 1)
+		immutable->core_cap_flags |= RDMA_CORE_PORT_IBA_ROCE_UDP_ENCAP;
 
 	return 0;
 }
@@ -531,7 +591,7 @@
 	req.hdr.resp.msg_version = GDMA_MESSAGE_V3;
 	req.hdr.dev_id = dev->gdma_dev->dev_id;
 
-	err = mana_gd_send_request(dev->gdma_dev->gdma_context, sizeof(req),
+	err = mana_gd_send_request(mdev_to_gc(dev), sizeof(req),
 				   &req, sizeof(resp), &resp);
 
 	if (err) {
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mana/mana_ib.h
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mana/mana_ib.h
@@ -45,6 +45,12 @@
 	u32 max_inline_data_size;
 };
 
+struct mana_ib_queue {
+	struct ib_umem *umem;
+	u64 gdma_region;
+	u64 id;
+};
+
 struct mana_ib_dev {
 	struct ib_device ib_dev;
 	struct gdma_dev *gdma_dev;
@@ -82,10 +88,8 @@
 
 struct mana_ib_cq {
 	struct ib_cq ibcq;
-	struct ib_umem *umem;
+	struct mana_ib_queue queue;
 	int cqe;
-	u64 gdma_region;
-	u64 id;
 	u32 comp_vector;
 };
 
@@ -142,12 +146,37 @@
 	u32 max_inline_data_size;
 }; /* HW Data */
 
-int mana_ib_gd_create_dma_region(struct mana_ib_dev *dev, struct ib_umem *umem,
-				 mana_handle_t *gdma_region);
+static inline struct gdma_context *mdev_to_gc(struct mana_ib_dev *mdev)
+{
+	return mdev->gdma_dev->gdma_context;
+}
+
+static inline struct net_device *mana_ib_get_netdev(struct ib_device *ibdev, u32 port)
+{
+	struct mana_ib_dev *mdev = container_of(ibdev, struct mana_ib_dev, ib_dev);
+	struct gdma_context *gc = mdev_to_gc(mdev);
+	struct mana_context *mc = gc->mana.driver_data;
+
+	if (port < 1 || port > mc->num_ports)
+		return NULL;
+	return mc->ports[port - 1];
+}
+
+int mana_ib_install_cq_cb(struct mana_ib_dev *mdev, struct mana_ib_cq *cq);
+
+int mana_ib_create_zero_offset_dma_region(struct mana_ib_dev *dev, struct ib_umem *umem,
+					  mana_handle_t *gdma_region);
+
+int mana_ib_create_dma_region(struct mana_ib_dev *dev, struct ib_umem *umem,
+			      mana_handle_t *gdma_region, u64 virt);
 
 int mana_ib_gd_destroy_dma_region(struct mana_ib_dev *dev,
 				  mana_handle_t gdma_region);
 
+int mana_ib_create_queue(struct mana_ib_dev *mdev, u64 addr, u32 size,
+			 struct mana_ib_queue *queue);
+void mana_ib_destroy_queue(struct mana_ib_dev *mdev, struct mana_ib_queue *queue);
+
 struct ib_wq *mana_ib_create_wq(struct ib_pd *pd,
 				struct ib_wq_init_attr *init_attr,
 				struct ib_udata *udata);
@@ -210,6 +239,4 @@
 void mana_ib_disassociate_ucontext(struct ib_ucontext *ibcontext);
 
 int mana_ib_gd_query_adapter_caps(struct mana_ib_dev *mdev);
-
-void mana_ib_cq_handler(void *ctx, struct gdma_queue *gdma_cq);
 #endif
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mana/mr.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mana/mr.c
@@ -30,12 +30,9 @@
 {
 	struct gdma_create_mr_response resp = {};
 	struct gdma_create_mr_request req = {};
-	struct gdma_dev *mdev = dev->gdma_dev;
-	struct gdma_context *gc;
+	struct gdma_context *gc = mdev_to_gc(dev);
 	int err;
 
-	gc = mdev->gdma_context;
-
 	mana_gd_init_req_hdr(&req.hdr, GDMA_CREATE_MR, sizeof(req),
 			     sizeof(resp));
 	req.pd_handle = mr_params->pd_handle;
@@ -77,12 +74,9 @@
 {
 	struct gdma_destroy_mr_response resp = {};
 	struct gdma_destroy_mr_request req = {};
-	struct gdma_dev *mdev = dev->gdma_dev;
-	struct gdma_context *gc;
+	struct gdma_context *gc = mdev_to_gc(dev);
 	int err;
 
-	gc = mdev->gdma_context;
-
 	mana_gd_init_req_hdr(&req.hdr, GDMA_DESTROY_MR, sizeof(req),
 			     sizeof(resp));
 
@@ -118,6 +112,7 @@
 		  "start 0x%llx, iova 0x%llx length 0x%llx access_flags 0x%x",
 		  start, iova, length, access_flags);
 
+	access_flags &= ~IB_ACCESS_OPTIONAL;
 	if (access_flags & ~VALID_MR_FLAGS)
 		return ERR_PTR(-EINVAL);
 
@@ -133,7 +128,7 @@
 		goto err_free;
 	}
 
-	err = mana_ib_gd_create_dma_region(dev, mr->umem, &dma_region_handle);
+	err = mana_ib_create_dma_region(dev, mr->umem, &dma_region_handle, iova);
 	if (err) {
 		ibdev_dbg(ibdev, "Failed create dma region for user-mr, %d\n",
 			  err);
@@ -141,7 +136,7 @@
 	}
 
 	ibdev_dbg(ibdev,
-		  "mana_ib_gd_create_dma_region ret %d gdma_region %llx\n", err,
+		  "create_dma_region ret %d gdma_region %llx\n", err,
 		  dma_region_handle);
 
 	mr_params.pd_handle = pd->pd_handle;
@@ -164,8 +159,7 @@
 	return &mr->ibmr;
 
 err_dma_region:
-	mana_gd_destroy_dma_region(dev->gdma_dev->gdma_context,
-				   dma_region_handle);
+	mana_gd_destroy_dma_region(mdev_to_gc(dev), dma_region_handle);
 
 err_umem:
 	ib_umem_release(mr->umem);
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mana/qp.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mana/qp.c
@@ -17,12 +17,10 @@
 	struct mana_cfg_rx_steer_resp resp = {};
 	mana_handle_t *req_indir_tab;
 	struct gdma_context *gc;
-	struct gdma_dev *mdev;
 	u32 req_buf_size;
 	int i, err;
 
-	gc = dev->gdma_dev->gdma_context;
-	mdev = &gc->mana;
+	gc = mdev_to_gc(dev);
 
 	req_buf_size =
 		sizeof(*req) + sizeof(mana_handle_t) * MANA_INDIRECT_TABLE_SIZE;
@@ -39,7 +37,7 @@
 	req->rx_enable = 1;
 	req->update_default_rxobj = 1;
 	req->default_rxobj = default_rxobj;
-	req->hdr.dev_id = mdev->dev_id;
+	req->hdr.dev_id = gc->mana.dev_id;
 
 	/* If there are more than 1 entries in indirection table, enable RSS */
 	if (log_ind_tbl_size)
@@ -99,20 +97,17 @@
 	struct mana_ib_qp *qp = container_of(ibqp, struct mana_ib_qp, ibqp);
 	struct mana_ib_dev *mdev =
 		container_of(pd->device, struct mana_ib_dev, ib_dev);
+	struct gdma_context *gc = mdev_to_gc(mdev);
 	struct ib_rwq_ind_table *ind_tbl = attr->rwq_ind_tbl;
 	struct mana_ib_create_qp_rss_resp resp = {};
 	struct mana_ib_create_qp_rss ucmd = {};
 	struct gdma_queue **gdma_cq_allocated;
 	mana_handle_t *mana_ind_table;
 	struct mana_port_context *mpc;
-	struct gdma_queue *gdma_cq;
 	unsigned int ind_tbl_size;
-	struct mana_context *mc;
 	struct net_device *ndev;
-	struct gdma_context *gc;
 	struct mana_ib_cq *cq;
 	struct mana_ib_wq *wq;
-	struct gdma_dev *gd;
 	struct mana_eq *eq;
 	struct ib_cq *ibcq;
 	struct ib_wq *ibwq;
@@ -120,10 +115,6 @@
 	u32 port;
 	int ret;
 
-	gc = mdev->gdma_dev->gdma_context;
-	gd = &gc->mana;
-	mc = gd->driver_data;
-
 	if (!udata || udata->inlen < sizeof(ucmd))
 		return -EINVAL;
 
@@ -166,12 +157,12 @@
 
 	/* IB ports start with 1, MANA start with 0 */
 	port = ucmd.port;
-	if (port < 1 || port > mc->num_ports) {
+	ndev = mana_ib_get_netdev(pd->device, port);
+	if (!ndev) {
 		ibdev_dbg(&mdev->ib_dev, "Invalid port %u in creating qp\n",
 			  port);
 		return -EINVAL;
 	}
-	ndev = mc->ports[port - 1];
 	mpc = netdev_priv(ndev);
 
 	ibdev_dbg(&mdev->ib_dev, "rx_hash_function %d port %d\n",
@@ -206,10 +197,10 @@
 		wq_spec.gdma_region = wq->gdma_region;
 		wq_spec.queue_size = wq->wq_buf_size;
 
-		cq_spec.gdma_region = cq->gdma_region;
+		cq_spec.gdma_region = cq->queue.gdma_region;
 		cq_spec.queue_size = cq->cqe * COMP_ENTRY_SIZE;
 		cq_spec.modr_ctx_id = 0;
-		eq = &mc->eqs[cq->comp_vector % gc->max_num_queues];
+		eq = &mpc->ac->eqs[cq->comp_vector % gc->max_num_queues];
 		cq_spec.attached_eq = eq->eq->id;
 
 		ret = mana_create_wq_obj(mpc, mpc->port_handle, GDMA_RQ,
@@ -222,34 +213,26 @@
 
 		/* The GDMA regions are now owned by the WQ object */
 		wq->gdma_region = GDMA_INVALID_DMA_REGION;
-		cq->gdma_region = GDMA_INVALID_DMA_REGION;
+		cq->queue.gdma_region = GDMA_INVALID_DMA_REGION;
 
 		wq->id = wq_spec.queue_index;
-		cq->id = cq_spec.queue_index;
+		cq->queue.id = cq_spec.queue_index;
 
 		ibdev_dbg(&mdev->ib_dev,
 			  "ret %d rx_object 0x%llx wq id %llu cq id %llu\n",
-			  ret, wq->rx_object, wq->id, cq->id);
+			  ret, wq->rx_object, wq->id, cq->queue.id);
 
-		resp.entries[i].cqid = cq->id;
+		resp.entries[i].cqid = cq->queue.id;
 		resp.entries[i].wqid = wq->id;
 
 		mana_ind_table[i] = wq->rx_object;
 
 		/* Create CQ table entry */
-		WARN_ON(gc->cq_table[cq->id]);
-		gdma_cq = kzalloc(sizeof(*gdma_cq), GFP_KERNEL);
-		if (!gdma_cq) {
-			ret = -ENOMEM;
+		ret = mana_ib_install_cq_cb(mdev, cq);
+		if (ret)
 			goto fail;
-		}
-		gdma_cq_allocated[i] = gdma_cq;
 
-		gdma_cq->cq.context = cq;
-		gdma_cq->type = GDMA_CQ;
-		gdma_cq->cq.callback = mana_ib_cq_handler;
-		gdma_cq->id = cq->id;
-		gc->cq_table[cq->id] = gdma_cq;
+		gdma_cq_allocated[i] = gc->cq_table[cq->queue.id];
 	}
 	resp.num_entries = i;
 
@@ -281,7 +264,7 @@
 		wq = container_of(ibwq, struct mana_ib_wq, ibwq);
 		cq = container_of(ibcq, struct mana_ib_cq, ibcq);
 
-		gc->cq_table[cq->id] = NULL;
+		gc->cq_table[cq->queue.id] = NULL;
 		kfree(gdma_cq_allocated[i]);
 
 		mana_destroy_wq_obj(mpc, GDMA_RQ, wq->rx_object);
@@ -306,14 +289,13 @@
 	struct mana_ib_ucontext *mana_ucontext =
 		rdma_udata_to_drv_context(udata, struct mana_ib_ucontext,
 					  ibucontext);
-	struct gdma_dev *gd = &mdev->gdma_dev->gdma_context->mana;
+	struct gdma_context *gc = mdev_to_gc(mdev);
 	struct mana_ib_create_qp_resp resp = {};
 	struct mana_ib_create_qp ucmd = {};
 	struct gdma_queue *gdma_cq = NULL;
 	struct mana_obj_spec wq_spec = {};
 	struct mana_obj_spec cq_spec = {};
 	struct mana_port_context *mpc;
-	struct mana_context *mc;
 	struct net_device *ndev;
 	struct ib_umem *umem;
 	struct mana_eq *eq;
@@ -321,8 +303,6 @@
 	u32 port;
 	int err;
 
-	mc = gd->driver_data;
-
 	if (!mana_ucontext || udata->inlen < sizeof(ucmd))
 		return -EINVAL;
 
@@ -333,11 +313,6 @@
 		return err;
 	}
 
-	/* IB ports start with 1, MANA Ethernet ports start with 0 */
-	port = ucmd.port;
-	if (port < 1 || port > mc->num_ports)
-		return -EINVAL;
-
 	if (attr->cap.max_send_wr > mdev->adapter_caps.max_qp_wr) {
 		ibdev_dbg(&mdev->ib_dev,
 			  "Requested max_send_wr %d exceeding limit\n",
@@ -352,11 +327,17 @@
 		return -EINVAL;
 	}
 
-	ndev = mc->ports[port - 1];
+	port = ucmd.port;
+	ndev = mana_ib_get_netdev(ibpd->device, port);
+	if (!ndev) {
+		ibdev_dbg(&mdev->ib_dev, "Invalid port %u in creating qp\n",
+			  port);
+		return -EINVAL;
+	}
 	mpc = netdev_priv(ndev);
 	ibdev_dbg(&mdev->ib_dev, "port %u ndev %p mpc %p\n", port, ndev, mpc);
 
-	err = mana_ib_cfg_vport(mdev, port - 1, pd, mana_ucontext->doorbell);
+	err = mana_ib_cfg_vport(mdev, port, pd, mana_ucontext->doorbell);
 	if (err)
 		return -ENODEV;
 
@@ -376,8 +357,8 @@
 	}
 	qp->sq_umem = umem;
 
-	err = mana_ib_gd_create_dma_region(mdev, qp->sq_umem,
-					   &qp->sq_gdma_region);
+	err = mana_ib_create_zero_offset_dma_region(mdev, qp->sq_umem,
+						    &qp->sq_gdma_region);
 	if (err) {
 		ibdev_dbg(&mdev->ib_dev,
 			  "Failed to create dma region for create qp-raw, %d\n",
@@ -386,18 +367,18 @@
 	}
 
 	ibdev_dbg(&mdev->ib_dev,
-		  "mana_ib_gd_create_dma_region ret %d gdma_region 0x%llx\n",
+		  "create_dma_region ret %d gdma_region 0x%llx\n",
 		  err, qp->sq_gdma_region);
 
 	/* Create a WQ on the same port handle used by the Ethernet */
 	wq_spec.gdma_region = qp->sq_gdma_region;
 	wq_spec.queue_size = ucmd.sq_buf_size;
 
-	cq_spec.gdma_region = send_cq->gdma_region;
+	cq_spec.gdma_region = send_cq->queue.gdma_region;
 	cq_spec.queue_size = send_cq->cqe * COMP_ENTRY_SIZE;
 	cq_spec.modr_ctx_id = 0;
-	eq_vec = send_cq->comp_vector % gd->gdma_context->max_num_queues;
-	eq = &mc->eqs[eq_vec];
+	eq_vec = send_cq->comp_vector % gc->max_num_queues;
+	eq = &mpc->ac->eqs[eq_vec];
 	cq_spec.attached_eq = eq->eq->id;
 
 	err = mana_create_wq_obj(mpc, mpc->port_handle, GDMA_SQ, &wq_spec,
@@ -411,31 +392,22 @@
 
 	/* The GDMA regions are now owned by the WQ object */
 	qp->sq_gdma_region = GDMA_INVALID_DMA_REGION;
-	send_cq->gdma_region = GDMA_INVALID_DMA_REGION;
+	send_cq->queue.gdma_region = GDMA_INVALID_DMA_REGION;
 
 	qp->sq_id = wq_spec.queue_index;
-	send_cq->id = cq_spec.queue_index;
+	send_cq->queue.id = cq_spec.queue_index;
 
 	/* Create CQ table entry */
-	WARN_ON(gd->gdma_context->cq_table[send_cq->id]);
-	gdma_cq = kzalloc(sizeof(*gdma_cq), GFP_KERNEL);
-	if (!gdma_cq) {
-		err = -ENOMEM;
+	err = mana_ib_install_cq_cb(mdev, send_cq);
+	if (err)
 		goto err_destroy_wq_obj;
-	}
-
-	gdma_cq->cq.context = send_cq;
-	gdma_cq->type = GDMA_CQ;
-	gdma_cq->cq.callback = mana_ib_cq_handler;
-	gdma_cq->id = send_cq->id;
-	gd->gdma_context->cq_table[send_cq->id] = gdma_cq;
 
 	ibdev_dbg(&mdev->ib_dev,
 		  "ret %d qp->tx_object 0x%llx sq id %llu cq id %llu\n", err,
-		  qp->tx_object, qp->sq_id, send_cq->id);
+		  qp->tx_object, qp->sq_id, send_cq->queue.id);
 
 	resp.sqid = qp->sq_id;
-	resp.cqid = send_cq->id;
+	resp.cqid = send_cq->queue.id;
 	resp.tx_vp_offset = pd->tx_vp_offset;
 
 	err = ib_copy_to_udata(udata, &resp, sizeof(resp));
@@ -450,7 +422,7 @@
 
 err_release_gdma_cq:
 	kfree(gdma_cq);
-	gd->gdma_context->cq_table[send_cq->id] = NULL;
+	gc->cq_table[send_cq->queue.id] = NULL;
 
 err_destroy_wq_obj:
 	mana_destroy_wq_obj(mpc, GDMA_SQ, qp->tx_object);
@@ -462,7 +434,7 @@
 	ib_umem_release(umem);
 
 err_free_vport:
-	mana_ib_uncfg_vport(mdev, pd, port - 1);
+	mana_ib_uncfg_vport(mdev, pd, port);
 
 	return err;
 }
@@ -500,16 +472,13 @@
 {
 	struct mana_ib_dev *mdev =
 		container_of(qp->ibqp.device, struct mana_ib_dev, ib_dev);
-	struct gdma_dev *gd = &mdev->gdma_dev->gdma_context->mana;
 	struct mana_port_context *mpc;
-	struct mana_context *mc;
 	struct net_device *ndev;
 	struct mana_ib_wq *wq;
 	struct ib_wq *ibwq;
 	int i;
 
-	mc = gd->driver_data;
-	ndev = mc->ports[qp->port - 1];
+	ndev = mana_ib_get_netdev(qp->ibqp.device, qp->port);
 	mpc = netdev_priv(ndev);
 
 	for (i = 0; i < (1 << ind_tbl->log_ind_tbl_size); i++) {
@@ -527,15 +496,12 @@
 {
 	struct mana_ib_dev *mdev =
 		container_of(qp->ibqp.device, struct mana_ib_dev, ib_dev);
-	struct gdma_dev *gd = &mdev->gdma_dev->gdma_context->mana;
 	struct ib_pd *ibpd = qp->ibqp.pd;
 	struct mana_port_context *mpc;
-	struct mana_context *mc;
 	struct net_device *ndev;
 	struct mana_ib_pd *pd;
 
-	mc = gd->driver_data;
-	ndev = mc->ports[qp->port - 1];
+	ndev = mana_ib_get_netdev(qp->ibqp.device, qp->port);
 	mpc = netdev_priv(ndev);
 	pd = container_of(ibpd, struct mana_ib_pd, ibpd);
 
@@ -546,7 +512,7 @@
 		ib_umem_release(qp->sq_umem);
 	}
 
-	mana_ib_uncfg_vport(mdev, pd, qp->port - 1);
+	mana_ib_uncfg_vport(mdev, pd, qp->port);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mana/wq.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mana/wq.c
@@ -46,7 +46,7 @@
 	wq->wq_buf_size = ucmd.wq_buf_size;
 	wq->rx_object = INVALID_MANA_HANDLE;
 
-	err = mana_ib_gd_create_dma_region(mdev, wq->umem, &wq->gdma_region);
+	err = mana_ib_create_zero_offset_dma_region(mdev, wq->umem, &wq->gdma_region);
 	if (err) {
 		ibdev_dbg(&mdev->ib_dev,
 			  "Failed to create dma region for create wq, %d\n",
@@ -55,7 +55,7 @@
 	}
 
 	ibdev_dbg(&mdev->ib_dev,
-		  "mana_ib_gd_create_dma_region ret %d gdma_region 0x%llx\n",
+		  "create_dma_region ret %d gdma_region 0x%llx\n",
 		  err, wq->gdma_region);
 
 	/* WQ ID is returned at wq_create time, doesn't know the value yet */
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mlx4/alias_GUID.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mlx4/alias_GUID.c
@@ -829,7 +829,7 @@
 
 int mlx4_ib_init_alias_guid_service(struct mlx4_ib_dev *dev)
 {
-	char alias_wq_name[15];
+	char alias_wq_name[22];
 	int ret = 0;
 	int i, j;
 	union ib_gid gid;
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mlx4/mad.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mlx4/mad.c
@@ -2158,7 +2158,7 @@
 				       struct mlx4_ib_demux_ctx *ctx,
 				       int port)
 {
-	char name[12];
+	char name[21];
 	int ret = 0;
 	int i;
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mlx4/main.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mlx4/main.c
@@ -351,7 +351,7 @@
 	struct mlx4_port_gid_table   *port_gid_table;
 	int ret = 0;
 	int hw_update = 0;
-	struct gid_entry *gids;
+	struct gid_entry *gids = NULL;
 
 	if (!rdma_cap_roce_gid_table(attr->device, attr->port_num))
 		return -EINVAL;
@@ -389,10 +389,10 @@
 	}
 	spin_unlock_bh(&iboe->lock);
 
-	if (!ret && hw_update) {
+	if (gids)
 		ret = mlx4_ib_update_gids(gids, ibdev, attr->port_num);
-		kfree(gids);
-	}
+
+	kfree(gids);
 	return ret;
 }
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mlx5/mad.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mlx5/mad.c
@@ -188,7 +188,8 @@
 		mdev = dev->mdev;
 		mdev_port_num = 1;
 	}
-	if (MLX5_CAP_GEN(dev->mdev, num_ports) == 1) {
+	if (MLX5_CAP_GEN(dev->mdev, num_ports) == 1 &&
+	    !mlx5_core_mp_enabled(mdev)) {
 		/* set local port to one for Function-Per-Port HCA. */
 		mdev = dev->mdev;
 		mdev_port_num = 1;
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mlx5/main.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mlx5/main.c
@@ -543,7 +543,7 @@
 	if (!ndev)
 		goto out;
 
-	if (dev->lag_active) {
+	if (mlx5_lag_is_roce(mdev) || mlx5_lag_is_sriov(mdev)) {
 		rcu_read_lock();
 		upper = netdev_master_upper_dev_get_rcu(ndev);
 		if (upper) {
@@ -2824,37 +2824,72 @@
 	}
 }
 
-static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)
+int mlx5_ib_dev_res_cq_init(struct mlx5_ib_dev *dev)
 {
 	struct mlx5_ib_resources *devr = &dev->devr;
-	struct ib_srq_init_attr attr;
-	struct ib_device *ibdev;
 	struct ib_cq_init_attr cq_attr = {.cqe = 1};
-	int port;
+	struct ib_device *ibdev;
+	struct ib_pd *pd;
+	struct ib_cq *cq;
 	int ret = 0;
 
-	ibdev = &dev->ib_dev;
 
-	if (!MLX5_CAP_GEN(dev->mdev, xrc))
-		return -EOPNOTSUPP;
+	/*
+	 * devr->c0 is set once, never changed until device unload.
+	 * Avoid taking the mutex if initialization is already done.
+	 */
+	if (devr->c0)
+		return 0;
 
-	devr->p0 = ib_alloc_pd(ibdev, 0);
-	if (IS_ERR(devr->p0))
-		return PTR_ERR(devr->p0);
-
-	devr->c0 = ib_create_cq(ibdev, NULL, NULL, NULL, &cq_attr);
-	if (IS_ERR(devr->c0)) {
-		ret = PTR_ERR(devr->c0);
-		goto error1;
+	mutex_lock(&devr->cq_lock);
+	if (devr->c0)
+		goto unlock;
+
+	ibdev = &dev->ib_dev;
+	pd = ib_alloc_pd(ibdev, 0);
+	if (IS_ERR(pd)) {
+		ret = PTR_ERR(pd);
+		mlx5_ib_err(dev, "Couldn't allocate PD for res init, err=%d\n", ret);
+		goto unlock;
+	}
+
+	cq = ib_create_cq(ibdev, NULL, NULL, NULL, &cq_attr);
+	if (IS_ERR(cq)) {
+		ret = PTR_ERR(cq);
+		mlx5_ib_err(dev, "Couldn't create CQ for res init, err=%d\n", ret);
+		ib_dealloc_pd(pd);
+		goto unlock;
 	}
 
-	ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn0, 0);
-	if (ret)
-		goto error2;
+	devr->p0 = pd;
+	devr->c0 = cq;
 
-	ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn1, 0);
+unlock:
+	mutex_unlock(&devr->cq_lock);
+	return ret;
+}
+
+int mlx5_ib_dev_res_srq_init(struct mlx5_ib_dev *dev)
+{
+	struct mlx5_ib_resources *devr = &dev->devr;
+	struct ib_srq_init_attr attr;
+	struct ib_srq *s0, *s1;
+	int ret = 0;
+
+	/*
+	 * devr->s1 is set once, never changed until device unload.
+	 * Avoid taking the mutex if initialization is already done.
+	 */
+	if (devr->s1)
+		return 0;
+
+	mutex_lock(&devr->srq_lock);
+	if (devr->s1)
+		goto unlock;
+
+	ret = mlx5_ib_dev_res_cq_init(dev);
 	if (ret)
-		goto error3;
+		goto unlock;
 
 	memset(&attr, 0, sizeof(attr));
 	attr.attr.max_sge = 1;
@@ -2862,10 +2897,11 @@
 	attr.srq_type = IB_SRQT_XRC;
 	attr.ext.cq = devr->c0;
 
-	devr->s0 = ib_create_srq(devr->p0, &attr);
-	if (IS_ERR(devr->s0)) {
-		ret = PTR_ERR(devr->s0);
-		goto err_create;
+	s0 = ib_create_srq(devr->p0, &attr);
+	if (IS_ERR(s0)) {
+		ret = PTR_ERR(s0);
+		mlx5_ib_err(dev, "Couldn't create SRQ 0 for res init, err=%d\n", ret);
+		goto unlock;
 	}
 
 	memset(&attr, 0, sizeof(attr));
@@ -2873,51 +2909,63 @@
 	attr.attr.max_wr = 1;
 	attr.srq_type = IB_SRQT_BASIC;
 
-	devr->s1 = ib_create_srq(devr->p0, &attr);
-	if (IS_ERR(devr->s1)) {
-		ret = PTR_ERR(devr->s1);
-		goto error6;
+	s1 = ib_create_srq(devr->p0, &attr);
+	if (IS_ERR(s1)) {
+		ret = PTR_ERR(s1);
+		mlx5_ib_err(dev, "Couldn't create SRQ 1 for res init, err=%d\n", ret);
+		ib_destroy_srq(s0);
 	}
 
-	for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
-		INIT_WORK(&devr->ports[port].pkey_change_work,
-			  pkey_change_handler);
+	devr->s0 = s0;
+	devr->s1 = s1;
 
-	return 0;
-
-error6:
-	ib_destroy_srq(devr->s0);
-err_create:
-	mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn1, 0);
-error3:
-	mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn0, 0);
-error2:
-	ib_destroy_cq(devr->c0);
-error1:
-	ib_dealloc_pd(devr->p0);
+unlock:
+	mutex_unlock(&devr->srq_lock);
 	return ret;
 }
 
-static void mlx5_ib_dev_res_cleanup(struct mlx5_ib_dev *dev)
+static int mlx5_ib_dev_res_init(struct mlx5_ib_dev *dev)
 {
 	struct mlx5_ib_resources *devr = &dev->devr;
-	int port;
+	int ret;
 
-	/*
-	 * Make sure no change P_Key work items are still executing.
-	 *
-	 * At this stage, the mlx5_ib_event should be unregistered
-	 * and it ensures that no new works are added.
-	 */
-	for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
-		cancel_work_sync(&devr->ports[port].pkey_change_work);
+	if (!MLX5_CAP_GEN(dev->mdev, xrc))
+		return -EOPNOTSUPP;
 
-	ib_destroy_srq(devr->s1);
-	ib_destroy_srq(devr->s0);
+	ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn0, 0);
+	if (ret)
+		return ret;
+
+	ret = mlx5_cmd_xrcd_alloc(dev->mdev, &devr->xrcdn1, 0);
+	if (ret) {
+		mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn0, 0);
+		return ret;
+	}
+
+	mutex_init(&devr->cq_lock);
+	mutex_init(&devr->srq_lock);
+
+	return 0;
+}
+
+static void mlx5_ib_dev_res_cleanup(struct mlx5_ib_dev *dev)
+{
+	struct mlx5_ib_resources *devr = &dev->devr;
+
+	/* After s0/s1 init, they are not unset during the device lifetime. */
+	if (devr->s1) {
+		ib_destroy_srq(devr->s1);
+		ib_destroy_srq(devr->s0);
+	}
 	mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn1, 0);
 	mlx5_cmd_xrcd_dealloc(dev->mdev, devr->xrcdn0, 0);
-	ib_destroy_cq(devr->c0);
-	ib_dealloc_pd(devr->p0);
+	/* After p0/c0 init, they are not unset during the device lifetime. */
+	if (devr->c0) {
+		ib_destroy_cq(devr->c0);
+		ib_dealloc_pd(devr->p0);
+	}
+	mutex_destroy(&devr->cq_lock);
+	mutex_destroy(&devr->srq_lock);
 }
 
 static u32 get_core_cap_flags(struct ib_device *ibdev,
@@ -3352,7 +3400,8 @@
 		list_for_each_entry(mpi, &mlx5_ib_unaffiliated_port_list,
 				    list) {
 			if (dev->sys_image_guid == mpi->sys_image_guid &&
-			    (mlx5_core_native_port_num(mpi->mdev) - 1) == i) {
+			    (mlx5_core_native_port_num(mpi->mdev) - 1) == i &&
+			    mlx5_core_same_coredev_type(dev->mdev, mpi->mdev)) {
 				bound = mlx5_ib_bind_slave_port(dev, mpi);
 			}
 
@@ -3760,10 +3809,10 @@
 	spin_lock_init(&dev->dm.lock);
 	dev->dm.dev = mdev;
 	return 0;
-err:
-	mlx5r_macsec_dealloc_gids(dev);
 err_mp:
 	mlx5_ib_cleanup_multiport_master(dev);
+err:
+	mlx5r_macsec_dealloc_gids(dev);
 	return err;
 }
 
@@ -4166,6 +4215,13 @@
 
 static int mlx5_ib_stage_dev_notifier_init(struct mlx5_ib_dev *dev)
 {
+	struct mlx5_ib_resources *devr = &dev->devr;
+	int port;
+
+	for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
+		INIT_WORK(&devr->ports[port].pkey_change_work,
+			  pkey_change_handler);
+
 	dev->mdev_events.notifier_call = mlx5_ib_event;
 	mlx5_notifier_register(dev->mdev, &dev->mdev_events);
 
@@ -4176,8 +4232,14 @@
 
 static void mlx5_ib_stage_dev_notifier_cleanup(struct mlx5_ib_dev *dev)
 {
+	struct mlx5_ib_resources *devr = &dev->devr;
+	int port;
+
 	mlx5r_macsec_event_unregister(dev);
 	mlx5_notifier_unregister(dev->mdev, &dev->mdev_events);
+
+	for (port = 0; port < ARRAY_SIZE(devr->ports); ++port)
+		cancel_work_sync(&devr->ports[port].pkey_change_work);
 }
 
 void __mlx5_ib_remove(struct mlx5_ib_dev *dev,
@@ -4251,9 +4313,6 @@
 	STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
 		     mlx5_ib_dev_res_init,
 		     mlx5_ib_dev_res_cleanup),
-	STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
-		     mlx5_ib_stage_dev_notifier_init,
-		     mlx5_ib_stage_dev_notifier_cleanup),
 	STAGE_CREATE(MLX5_IB_STAGE_ODP,
 		     mlx5_ib_odp_init_one,
 		     mlx5_ib_odp_cleanup_one),
@@ -4278,6 +4337,9 @@
 	STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
 		     mlx5_ib_stage_ib_reg_init,
 		     mlx5_ib_stage_ib_reg_cleanup),
+	STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
+		     mlx5_ib_stage_dev_notifier_init,
+		     mlx5_ib_stage_dev_notifier_cleanup),
 	STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
 		     mlx5_ib_stage_post_ib_reg_umr_init,
 		     NULL),
@@ -4314,9 +4376,6 @@
 	STAGE_CREATE(MLX5_IB_STAGE_DEVICE_RESOURCES,
 		     mlx5_ib_dev_res_init,
 		     mlx5_ib_dev_res_cleanup),
-	STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
-		     mlx5_ib_stage_dev_notifier_init,
-		     mlx5_ib_stage_dev_notifier_cleanup),
 	STAGE_CREATE(MLX5_IB_STAGE_COUNTERS,
 		     mlx5_ib_counters_init,
 		     mlx5_ib_counters_cleanup),
@@ -4338,6 +4397,9 @@
 	STAGE_CREATE(MLX5_IB_STAGE_IB_REG,
 		     mlx5_ib_stage_ib_reg_init,
 		     mlx5_ib_stage_ib_reg_cleanup),
+	STAGE_CREATE(MLX5_IB_STAGE_DEVICE_NOTIFIER,
+		     mlx5_ib_stage_dev_notifier_init,
+		     mlx5_ib_stage_dev_notifier_cleanup),
 	STAGE_CREATE(MLX5_IB_STAGE_POST_IB_REG_UMR,
 		     mlx5_ib_stage_post_ib_reg_umr_init,
 		     NULL),
@@ -4373,7 +4435,8 @@
 
 	mutex_lock(&mlx5_ib_multiport_mutex);
 	list_for_each_entry(dev, &mlx5_ib_dev_list, ib_dev_list) {
-		if (dev->sys_image_guid == mpi->sys_image_guid)
+		if (dev->sys_image_guid == mpi->sys_image_guid &&
+		    mlx5_core_same_coredev_type(dev->mdev, mpi->mdev))
 			bound = mlx5_ib_bind_slave_port(dev, mpi);
 
 		if (bound) {
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mlx5/mem.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mlx5/mem.c
@@ -30,6 +30,7 @@
  * SOFTWARE.
  */
 
+#include <linux/io.h>
 #include <rdma/ib_umem_odp.h>
 #include "mlx5_ib.h"
 #include <linux/jiffies.h>
@@ -108,7 +109,6 @@
 	__be32 mmio_wqe[16] = {};
 	unsigned long flags;
 	unsigned int idx;
-	int i;
 
 	if (unlikely(dev->mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR))
 		return -EIO;
@@ -148,10 +148,8 @@
 	 * we hit doorbell
 	 */
 	wmb();
-	for (i = 0; i < 8; i++)
-		mlx5_write64(&mmio_wqe[i * 2],
-			     bf->bfreg->map + bf->offset + i * 8);
-	io_stop_wc();
+	__iowrite64_copy(bf->bfreg->map + bf->offset, mmio_wqe,
+			 sizeof(mmio_wqe) / 8);
 
 	bf->offset ^= bf->buf_size;
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -115,6 +115,19 @@
 		__mlx5_bit_sz(typ, page_offset_fld), 0, scale,                 \
 		page_offset_quantized)
 
+static inline unsigned long
+mlx5_umem_dmabuf_find_best_pgsz(struct ib_umem_dmabuf *umem_dmabuf)
+{
+	/*
+	 * mkeys used for dmabuf are fixed at PAGE_SIZE because we must be able
+	 * to hold any sgl after a move operation. Ideally the mkc page size
+	 * could be changed at runtime to be optimal, but right now the driver
+	 * cannot do that.
+	 */
+	return ib_umem_find_best_pgsz(&umem_dmabuf->umem, PAGE_SIZE,
+				      umem_dmabuf->umem.iova);
+}
+
 enum {
 	MLX5_IB_MMAP_OFFSET_START = 9,
 	MLX5_IB_MMAP_OFFSET_END = 255,
@@ -643,9 +656,10 @@
 	unsigned int ndescs;
 	struct wait_queue_head wait;
 	refcount_t usecount;
-	/* User Mkey must hold either a rb_key or a cache_ent. */
+	/* Cacheable user Mkey must hold either a rb_key or a cache_ent. */
 	struct mlx5r_cache_rb_key rb_key;
 	struct mlx5_cache_ent *cache_ent;
+	u8 cacheable : 1;
 };
 
 #define MLX5_IB_MTT_PRESENT (MLX5_IB_MTT_READ | MLX5_IB_MTT_WRITE)
@@ -781,6 +795,7 @@
 	u8 is_tmp:1;
 	u8 disabled:1;
 	u8 fill_to_high_water:1;
+	u8 tmp_cleanup_scheduled:1;
 
 	/*
 	 * - limit is the low water mark for stored mkeys, 2* limit is the
@@ -812,7 +827,6 @@
 	struct mutex		rb_lock;
 	struct dentry		*fs_root;
 	unsigned long		last_add;
-	struct delayed_work	remove_ent_dwork;
 };
 
 struct mlx5_ib_port_resources {
@@ -822,11 +836,13 @@
 
 struct mlx5_ib_resources {
 	struct ib_cq	*c0;
+	struct mutex cq_lock;
 	u32 xrcdn0;
 	u32 xrcdn1;
 	struct ib_pd	*p0;
 	struct ib_srq	*s0;
 	struct ib_srq	*s1;
+	struct mutex srq_lock;
 	struct mlx5_ib_port_resources ports[2];
 };
 
@@ -954,7 +970,6 @@
 	MLX5_IB_STAGE_QP,
 	MLX5_IB_STAGE_SRQ,
 	MLX5_IB_STAGE_DEVICE_RESOURCES,
-	MLX5_IB_STAGE_DEVICE_NOTIFIER,
 	MLX5_IB_STAGE_ODP,
 	MLX5_IB_STAGE_COUNTERS,
 	MLX5_IB_STAGE_CONG_DEBUGFS,
@@ -963,6 +978,7 @@
 	MLX5_IB_STAGE_PRE_IB_REG_UMR,
 	MLX5_IB_STAGE_WHITELIST_UID,
 	MLX5_IB_STAGE_IB_REG,
+	MLX5_IB_STAGE_DEVICE_NOTIFIER,
 	MLX5_IB_STAGE_POST_IB_REG_UMR,
 	MLX5_IB_STAGE_DELAY_DROP,
 	MLX5_IB_STAGE_RESTRACK,
@@ -1272,6 +1288,8 @@
 		struct mlx5_user_mmap_entry, rdma_entry);
 }
 
+int mlx5_ib_dev_res_cq_init(struct mlx5_ib_dev *dev);
+int mlx5_ib_dev_res_srq_init(struct mlx5_ib_dev *dev);
 int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, unsigned long virt,
 			struct mlx5_db *db);
 void mlx5_ib_db_unmap_user(struct mlx5_ib_ucontext *context, struct mlx5_db *db);
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mlx5/mr.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mlx5/mr.c
@@ -48,6 +48,7 @@
 	MAX_PENDING_REG_MR = 8,
 };
 
+#define MLX5_MR_CACHE_PERSISTENT_ENTRY_MIN_DESCS 4
 #define MLX5_UMR_ALIGN 2048
 
 static void
@@ -211,9 +212,9 @@
 
 	spin_lock_irqsave(&ent->mkeys_queue.lock, flags);
 	push_mkey_locked(ent, mkey_out->mkey);
+	ent->pending--;
 	/* If we are doing fill_to_high_water then keep going. */
 	queue_adjust_cache_locked(ent);
-	ent->pending--;
 	spin_unlock_irqrestore(&ent->mkeys_queue.lock, flags);
 	kfree(mkey_out);
 }
@@ -246,6 +247,7 @@
 	MLX5_SET(mkc, mkc, access_mode_1_0, ent->rb_key.access_mode & 0x3);
 	MLX5_SET(mkc, mkc, access_mode_4_2,
 		(ent->rb_key.access_mode >> 2) & 0x7);
+	MLX5_SET(mkc, mkc, ma_translation_mode, !!ent->rb_key.ats);
 
 	MLX5_SET(mkc, mkc, translations_octword_size,
 		 get_mkc_octo_size(ent->rb_key.access_mode,
@@ -526,6 +528,21 @@
 	}
 }
 
+static void clean_keys(struct mlx5_ib_dev *dev, struct mlx5_cache_ent *ent)
+{
+	u32 mkey;
+
+	spin_lock_irq(&ent->mkeys_queue.lock);
+	while (ent->mkeys_queue.ci) {
+		mkey = pop_mkey_locked(ent);
+		spin_unlock_irq(&ent->mkeys_queue.lock);
+		mlx5_core_destroy_mkey(dev->mdev, mkey);
+		spin_lock_irq(&ent->mkeys_queue.lock);
+	}
+	ent->tmp_cleanup_scheduled = false;
+	spin_unlock_irq(&ent->mkeys_queue.lock);
+}
+
 static void __cache_work_func(struct mlx5_cache_ent *ent)
 {
 	struct mlx5_ib_dev *dev = ent->dev;
@@ -597,7 +614,11 @@
 	struct mlx5_cache_ent *ent;
 
 	ent = container_of(work, struct mlx5_cache_ent, dwork.work);
-	__cache_work_func(ent);
+	/* temp entries are never filled, only cleaned */
+	if (ent->is_tmp)
+		clean_keys(ent->dev, ent);
+	else
+		__cache_work_func(ent);
 }
 
 static int cache_ent_key_cmp(struct mlx5r_cache_rb_key key1,
@@ -641,10 +662,8 @@
 			new = &((*new)->rb_left);
 		if (cmp < 0)
 			new = &((*new)->rb_right);
-		if (cmp == 0) {
-			mutex_unlock(&cache->rb_lock);
+		if (cmp == 0)
 			return -EEXIST;
-		}
 	}
 
 	/* Add new node and rebalance tree. */
@@ -660,6 +679,7 @@
 {
 	struct rb_node *node = dev->cache.rb_root.rb_node;
 	struct mlx5_cache_ent *cur, *smallest = NULL;
+	u64 ndescs_limit;
 	int cmp;
 
 	/*
@@ -678,10 +698,18 @@
 			return cur;
 	}
 
+	/*
+	 * Limit the usage of mkeys larger than twice the required size while
+	 * also allowing the usage of smallest cache entry for small MRs.
+	 */
+	ndescs_limit = max_t(u64, rb_key.ndescs * 2,
+			     MLX5_MR_CACHE_PERSISTENT_ENTRY_MIN_DESCS);
+
 	return (smallest &&
 		smallest->rb_key.access_mode == rb_key.access_mode &&
 		smallest->rb_key.access_flags == rb_key.access_flags &&
-		smallest->rb_key.ats == rb_key.ats) ?
+		smallest->rb_key.ats == rb_key.ats &&
+		smallest->rb_key.ndescs <= ndescs_limit) ?
 		       smallest :
 		       NULL;
 }
@@ -719,6 +747,8 @@
 	}
 	mr->mmkey.cache_ent = ent;
 	mr->mmkey.type = MLX5_MKEY_MR;
+	mr->mmkey.rb_key = ent->rb_key;
+	mr->mmkey.cacheable = true;
 	init_waitqueue_head(&mr->mmkey.wait);
 	return mr;
 }
@@ -764,21 +794,6 @@
 	return _mlx5_mr_cache_alloc(dev, ent, access_flags);
 }
 
-static void clean_keys(struct mlx5_ib_dev *dev, struct mlx5_cache_ent *ent)
-{
-	u32 mkey;
-
-	cancel_delayed_work(&ent->dwork);
-	spin_lock_irq(&ent->mkeys_queue.lock);
-	while (ent->mkeys_queue.ci) {
-		mkey = pop_mkey_locked(ent);
-		spin_unlock_irq(&ent->mkeys_queue.lock);
-		mlx5_core_destroy_mkey(dev->mdev, mkey);
-		spin_lock_irq(&ent->mkeys_queue.lock);
-	}
-	spin_unlock_irq(&ent->mkeys_queue.lock);
-}
-
 static void mlx5_mkey_cache_debugfs_cleanup(struct mlx5_ib_dev *dev)
 {
 	if (!mlx5_debugfs_root || dev->is_rep)
@@ -891,10 +906,6 @@
 			ent->limit = 0;
 
 		mlx5_mkey_cache_debugfs_add_ent(dev, ent);
-	} else {
-		mod_delayed_work(ent->dev->cache.wq,
-				 &ent->dev->cache.remove_ent_dwork,
-				 msecs_to_jiffies(30 * 1000));
 	}
 
 	return ent;
@@ -905,35 +916,6 @@
 	return ERR_PTR(ret);
 }
 
-static void remove_ent_work_func(struct work_struct *work)
-{
-	struct mlx5_mkey_cache *cache;
-	struct mlx5_cache_ent *ent;
-	struct rb_node *cur;
-
-	cache = container_of(work, struct mlx5_mkey_cache,
-			     remove_ent_dwork.work);
-	mutex_lock(&cache->rb_lock);
-	cur = rb_last(&cache->rb_root);
-	while (cur) {
-		ent = rb_entry(cur, struct mlx5_cache_ent, node);
-		cur = rb_prev(cur);
-		mutex_unlock(&cache->rb_lock);
-
-		spin_lock_irq(&ent->mkeys_queue.lock);
-		if (!ent->is_tmp) {
-			spin_unlock_irq(&ent->mkeys_queue.lock);
-			mutex_lock(&cache->rb_lock);
-			continue;
-		}
-		spin_unlock_irq(&ent->mkeys_queue.lock);
-
-		clean_keys(ent->dev, ent);
-		mutex_lock(&cache->rb_lock);
-	}
-	mutex_unlock(&cache->rb_lock);
-}
-
 int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev)
 {
 	struct mlx5_mkey_cache *cache = &dev->cache;
@@ -949,7 +931,6 @@
 	mutex_init(&dev->slow_path_mutex);
 	mutex_init(&dev->cache.rb_lock);
 	dev->cache.rb_root = RB_ROOT;
-	INIT_DELAYED_WORK(&dev->cache.remove_ent_dwork, remove_ent_work_func);
 	cache->wq = alloc_ordered_workqueue("mkey_cache", WQ_MEM_RECLAIM);
 	if (!cache->wq) {
 		mlx5_ib_warn(dev, "failed to create work queue\n");
@@ -961,7 +942,7 @@
 	mlx5_mkey_cache_debugfs_init(dev);
 	mutex_lock(&cache->rb_lock);
 	for (i = 0; i <= mkey_cache_max_order(dev); i++) {
-		rb_key.ndescs = 1 << (i + 2);
+		rb_key.ndescs = MLX5_MR_CACHE_PERSISTENT_ENTRY_MIN_DESCS << i;
 		ent = mlx5r_cache_create_ent_locked(dev, rb_key, true);
 		if (IS_ERR(ent)) {
 			ret = PTR_ERR(ent);
@@ -1000,7 +981,6 @@
 		return;
 
 	mutex_lock(&dev->cache.rb_lock);
-	cancel_delayed_work(&dev->cache.remove_ent_dwork);
 	for (node = rb_first(root); node; node = rb_next(node)) {
 		ent = rb_entry(node, struct mlx5_cache_ent, node);
 		spin_lock_irq(&ent->mkeys_queue.lock);
@@ -1158,6 +1138,7 @@
 		if (IS_ERR(mr))
 			return mr;
 		mr->mmkey.rb_key = rb_key;
+		mr->mmkey.cacheable = true;
 		return mr;
 	}
 
@@ -1570,7 +1551,8 @@
 	unsigned int diffs = current_access_flags ^ target_access_flags;
 
 	if (diffs & ~(IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_WRITE |
-		      IB_ACCESS_REMOTE_READ | IB_ACCESS_RELAXED_ORDERING))
+		      IB_ACCESS_REMOTE_READ | IB_ACCESS_RELAXED_ORDERING |
+		      IB_ACCESS_REMOTE_ATOMIC))
 		return false;
 	return mlx5r_umr_can_reconfig(dev, current_access_flags,
 				      target_access_flags);
@@ -1835,6 +1817,46 @@
 	return ret;
 }
 
+static int mlx5_revoke_mr(struct mlx5_ib_mr *mr)
+{
+	struct mlx5_ib_dev *dev = to_mdev(mr->ibmr.device);
+	struct mlx5_cache_ent *ent = mr->mmkey.cache_ent;
+	bool is_odp = is_odp_mr(mr);
+	int ret = 0;
+
+	if (is_odp)
+		mutex_lock(&to_ib_umem_odp(mr->umem)->umem_mutex);
+
+	if (mr->mmkey.cacheable && !mlx5r_umr_revoke_mr(mr) && !cache_ent_find_and_store(dev, mr)) {
+		ent = mr->mmkey.cache_ent;
+		/* upon storing to a clean temp entry - schedule its cleanup */
+		spin_lock_irq(&ent->mkeys_queue.lock);
+		if (ent->is_tmp && !ent->tmp_cleanup_scheduled) {
+			mod_delayed_work(ent->dev->cache.wq, &ent->dwork,
+					 msecs_to_jiffies(30 * 1000));
+			ent->tmp_cleanup_scheduled = true;
+		}
+		spin_unlock_irq(&ent->mkeys_queue.lock);
+		goto out;
+	}
+
+	if (ent) {
+		spin_lock_irq(&ent->mkeys_queue.lock);
+		ent->in_use--;
+		mr->mmkey.cache_ent = NULL;
+		spin_unlock_irq(&ent->mkeys_queue.lock);
+	}
+	ret = destroy_mkey(dev, mr);
+out:
+	if (is_odp) {
+		if (!ret)
+			to_ib_umem_odp(mr->umem)->private = NULL;
+		mutex_unlock(&to_ib_umem_odp(mr->umem)->umem_mutex);
+	}
+
+	return ret;
+}
+
 int mlx5_ib_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata)
 {
 	struct mlx5_ib_mr *mr = to_mmr(ibmr);
@@ -1880,16 +1902,9 @@
 	}
 
 	/* Stop DMA */
-	if (mr->umem && mlx5r_umr_can_load_pas(dev, mr->umem->length))
-		if (mlx5r_umr_revoke_mr(mr) ||
-		    cache_ent_find_and_store(dev, mr))
-			mr->mmkey.cache_ent = NULL;
-
-	if (!mr->mmkey.cache_ent) {
-		rc = destroy_mkey(to_mdev(mr->ibmr.device), mr);
-		if (rc)
-			return rc;
-	}
+	rc = mlx5_revoke_mr(mr);
+	if (rc)
+		return rc;
 
 	if (mr->umem) {
 		bool is_odp = is_odp_mr(mr);
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mlx5/odp.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mlx5/odp.c
@@ -213,10 +213,23 @@
 	unsigned long idx = ib_umem_start(odp) >> MLX5_IMR_MTT_SHIFT;
 	struct mlx5_ib_mr *imr = mr->parent;
 
+	/*
+	 * If userspace is racing freeing the parent implicit ODP MR then we can
+	 * loose the race with parent destruction. In this case
+	 * mlx5_ib_free_odp_mr() will free everything in the implicit_children
+	 * xarray so NOP is fine. This child MR cannot be destroyed here because
+	 * we are under its umem_mutex.
+	 */
 	if (!refcount_inc_not_zero(&imr->mmkey.usecount))
 		return;
 
-	xa_erase(&imr->implicit_children, idx);
+	xa_lock(&imr->implicit_children);
+	if (__xa_cmpxchg(&imr->implicit_children, idx, mr, NULL, GFP_KERNEL) !=
+	    mr) {
+		xa_unlock(&imr->implicit_children);
+		return;
+	}
+	xa_unlock(&imr->implicit_children);
 
 	/* Freeing a MR is a sleeping operation, so bounce to a work queue */
 	INIT_WORK(&mr->odp_destroy.work, free_implicit_child_mr_work);
@@ -250,6 +263,8 @@
 	if (!umem_odp->npages)
 		goto out;
 	mr = umem_odp->private;
+	if (!mr)
+		goto out;
 
 	start = max_t(u64, ib_umem_start(umem_odp), range->start);
 	end = min_t(u64, ib_umem_end(umem_odp), range->end);
@@ -705,10 +720,8 @@
 		return err;
 	}
 
-	page_size = mlx5_umem_find_best_pgsz(&umem_dmabuf->umem, mkc,
-					     log_page_size, 0,
-					     umem_dmabuf->umem.iova);
-	if (unlikely(page_size < PAGE_SIZE)) {
+	page_size = mlx5_umem_dmabuf_find_best_pgsz(umem_dmabuf);
+	if (!page_size) {
 		ib_umem_dmabuf_unmap_pages(umem_dmabuf);
 		err = -EINVAL;
 	} else {
@@ -735,24 +748,31 @@
  *  >0: Number of pages mapped
  */
 static int pagefault_mr(struct mlx5_ib_mr *mr, u64 io_virt, size_t bcnt,
-			u32 *bytes_mapped, u32 flags)
+			u32 *bytes_mapped, u32 flags, bool permissive_fault)
 {
 	struct ib_umem_odp *odp = to_ib_umem_odp(mr->umem);
 
-	if (unlikely(io_virt < mr->ibmr.iova))
+	if (unlikely(io_virt < mr->ibmr.iova) && !permissive_fault)
 		return -EFAULT;
 
 	if (mr->umem->is_dmabuf)
 		return pagefault_dmabuf_mr(mr, bcnt, bytes_mapped, flags);
 
 	if (!odp->is_implicit_odp) {
+		u64 offset = io_virt < mr->ibmr.iova ? 0 : io_virt - mr->ibmr.iova;
 		u64 user_va;
 
-		if (check_add_overflow(io_virt - mr->ibmr.iova,
-				       (u64)odp->umem.address, &user_va))
+		if (check_add_overflow(offset, (u64)odp->umem.address,
+				       &user_va))
 			return -EFAULT;
-		if (unlikely(user_va >= ib_umem_end(odp) ||
-			     ib_umem_end(odp) - user_va < bcnt))
+
+		if (permissive_fault) {
+			if (user_va < ib_umem_start(odp))
+				user_va = ib_umem_start(odp);
+			if ((user_va + bcnt) > ib_umem_end(odp))
+				bcnt = ib_umem_end(odp) - user_va;
+		} else if (unlikely(user_va >= ib_umem_end(odp) ||
+				    ib_umem_end(odp) - user_va < bcnt))
 			return -EFAULT;
 		return pagefault_real_mr(mr, odp, user_va, bcnt, bytes_mapped,
 					 flags);
@@ -802,8 +822,7 @@
 /*
  * Handle a single data segment in a page-fault WQE or RDMA region.
  *
- * Returns number of OS pages retrieved on success. The caller may continue to
- * the next data segment.
+ * Returns zero on success. The caller may continue to the next data segment.
  * Can return the following error codes:
  * -EAGAIN to designate a temporary error. The caller will abort handling the
  *  page fault and resolve it.
@@ -816,7 +835,7 @@
 					 u32 *bytes_committed,
 					 u32 *bytes_mapped)
 {
-	int npages = 0, ret, i, outlen, cur_outlen = 0, depth = 0;
+	int ret, i, outlen, cur_outlen = 0, depth = 0, pages_in_range;
 	struct pf_frame *head = NULL, *frame;
 	struct mlx5_ib_mkey *mmkey;
 	struct mlx5_ib_mr *mr;
@@ -859,13 +878,20 @@
 	case MLX5_MKEY_MR:
 		mr = container_of(mmkey, struct mlx5_ib_mr, mmkey);
 
-		ret = pagefault_mr(mr, io_virt, bcnt, bytes_mapped, 0);
+		pages_in_range = (ALIGN(io_virt + bcnt, PAGE_SIZE) -
+				  (io_virt & PAGE_MASK)) >>
+				 PAGE_SHIFT;
+		ret = pagefault_mr(mr, io_virt, bcnt, bytes_mapped, 0, false);
 		if (ret < 0)
 			goto end;
 
 		mlx5_update_odp_stats(mr, faults, ret);
 
-		npages += ret;
+		if (ret < pages_in_range) {
+			ret = -EFAULT;
+			goto end;
+		}
+
 		ret = 0;
 		break;
 
@@ -956,7 +982,7 @@
 	kfree(out);
 
 	*bytes_committed = 0;
-	return ret ? ret : npages;
+	return ret;
 }
 
 /*
@@ -975,8 +1001,7 @@
  *                   the committed bytes).
  * @receive_queue: receive WQE end of sg list
  *
- * Returns the number of pages loaded if positive, zero for an empty WQE, or a
- * negative error code.
+ * Returns zero for success or a negative error code.
  */
 static int pagefault_data_segments(struct mlx5_ib_dev *dev,
 				   struct mlx5_pagefault *pfault,
@@ -984,7 +1009,7 @@
 				   void *wqe_end, u32 *bytes_mapped,
 				   u32 *total_wqe_bytes, bool receive_queue)
 {
-	int ret = 0, npages = 0;
+	int ret = 0;
 	u64 io_virt;
 	__be32 key;
 	u32 byte_count;
@@ -1041,10 +1066,9 @@
 						    bytes_mapped);
 		if (ret < 0)
 			break;
-		npages += ret;
 	}
 
-	return ret < 0 ? ret : npages;
+	return ret;
 }
 
 /*
@@ -1280,12 +1304,6 @@
 	free_page((unsigned long)wqe_start);
 }
 
-static int pages_in_range(u64 address, u32 length)
-{
-	return (ALIGN(address + length, PAGE_SIZE) -
-		(address & PAGE_MASK)) >> PAGE_SHIFT;
-}
-
 static void mlx5_ib_mr_rdma_pfault_handler(struct mlx5_ib_dev *dev,
 					   struct mlx5_pagefault *pfault)
 {
@@ -1324,7 +1342,7 @@
 	if (ret == -EAGAIN) {
 		/* We're racing with an invalidation, don't prefetch */
 		prefetch_activated = 0;
-	} else if (ret < 0 || pages_in_range(address, length) > ret) {
+	} else if (ret < 0) {
 		mlx5_ib_page_fault_resume(dev, pfault, 1);
 		if (ret != -ENOENT)
 			mlx5_ib_dbg(dev, "PAGE FAULT error %d. QP 0x%x, type: 0x%x\n",
@@ -1712,7 +1730,7 @@
 	for (i = 0; i < work->num_sge; ++i) {
 		ret = pagefault_mr(work->frags[i].mr, work->frags[i].io_virt,
 				   work->frags[i].length, &bytes_mapped,
-				   work->pf_flags);
+				   work->pf_flags, false);
 		if (ret <= 0)
 			continue;
 		mlx5_update_odp_stats(work->frags[i].mr, prefetch, ret);
@@ -1763,7 +1781,7 @@
 		if (IS_ERR(mr))
 			return PTR_ERR(mr);
 		ret = pagefault_mr(mr, sg_list[i].addr, sg_list[i].length,
-				   &bytes_mapped, pf_flags);
+				   &bytes_mapped, pf_flags, false);
 		if (ret < 0) {
 			mlx5r_deref_odp_mkey(&mr->mmkey);
 			return ret;
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mlx5/qp.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mlx5/qp.c
@@ -3247,6 +3247,10 @@
 	enum ib_qp_type type;
 	int err;
 
+	err = mlx5_ib_dev_res_srq_init(dev);
+	if (err)
+		return err;
+
 	err = check_qp_type(dev, attr, &type);
 	if (err)
 		return err;
@@ -4272,14 +4276,14 @@
 		MLX5_SET(qpc, qpc, retry_count, attr->retry_cnt);
 
 	if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && attr->max_rd_atomic)
-		MLX5_SET(qpc, qpc, log_sra_max, ilog2(attr->max_rd_atomic));
+		MLX5_SET(qpc, qpc, log_sra_max, fls(attr->max_rd_atomic - 1));
 
 	if (attr_mask & IB_QP_SQ_PSN)
 		MLX5_SET(qpc, qpc, next_send_psn, attr->sq_psn);
 
 	if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC && attr->max_dest_rd_atomic)
 		MLX5_SET(qpc, qpc, log_rra_max,
-			 ilog2(attr->max_dest_rd_atomic));
+			 fls(attr->max_dest_rd_atomic - 1));
 
 	if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC)) {
 		err = set_qpc_atomic_flags(qp, attr, attr_mask, qpc);
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/mlx5/srq.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/mlx5/srq.c
@@ -199,20 +199,27 @@
 	int err;
 	struct mlx5_srq_attr in = {};
 	__u32 max_srq_wqes = 1 << MLX5_CAP_GEN(dev->mdev, log_max_srq_sz);
+	__u32 max_sge_sz =  MLX5_CAP_GEN(dev->mdev, max_wqe_sz_rq) /
+			    sizeof(struct mlx5_wqe_data_seg);
 
 	if (init_attr->srq_type != IB_SRQT_BASIC &&
 	    init_attr->srq_type != IB_SRQT_XRC &&
 	    init_attr->srq_type != IB_SRQT_TM)
 		return -EOPNOTSUPP;
 
-	/* Sanity check SRQ size before proceeding */
-	if (init_attr->attr.max_wr >= max_srq_wqes) {
-		mlx5_ib_dbg(dev, "max_wr %d, cap %d\n",
-			    init_attr->attr.max_wr,
-			    max_srq_wqes);
+	/* Sanity check SRQ and sge size before proceeding */
+	if (init_attr->attr.max_wr >= max_srq_wqes ||
+	    init_attr->attr.max_sge > max_sge_sz) {
+		mlx5_ib_dbg(dev, "max_wr %d,wr_cap %d,max_sge %d, sge_cap:%d\n",
+			    init_attr->attr.max_wr, max_srq_wqes,
+			    init_attr->attr.max_sge, max_sge_sz);
 		return -EINVAL;
 	}
 
+	err = mlx5_ib_dev_res_cq_init(dev);
+	if (err)
+		return err;
+
 	mutex_init(&srq->mutex);
 	spin_lock_init(&srq->lock);
 	srq->msrq.max    = roundup_pow_of_two(init_attr->attr.max_wr + 1);
--- linux-qcom-6.8.0.orig/drivers/infiniband/hw/qib/qib_fs.c
+++ linux-qcom-6.8.0/drivers/infiniband/hw/qib/qib_fs.c
@@ -439,6 +439,7 @@
 		return PTR_ERR(dir);
 	}
 	simple_recursive_removal(dir, NULL);
+	dput(dir);
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/rxe/rxe.c
+++ linux-qcom-6.8.0/drivers/infiniband/sw/rxe/rxe.c
@@ -33,6 +33,8 @@
 
 	if (rxe->tfm)
 		crypto_free_shash(rxe->tfm);
+
+	mutex_destroy(&rxe->usdev_lock);
 }
 
 /* initialize rxe device parameters */
@@ -161,7 +163,7 @@
 	port->attr.active_mtu = mtu;
 	port->mtu_cap = ib_mtu_enum_to_int(mtu);
 
-	rxe_info_dev(rxe, "Set mtu to %d", port->mtu_cap);
+	rxe_info_dev(rxe, "Set mtu to %d\n", port->mtu_cap);
 }
 
 /* called by ifc layer to create new rxe device.
@@ -181,7 +183,7 @@
 	int err = 0;
 
 	if (is_vlan_dev(ndev)) {
-		rxe_err("rxe creation allowed on top of a real device only");
+		rxe_err("rxe creation allowed on top of a real device only\n");
 		err = -EPERM;
 		goto err;
 	}
@@ -189,7 +191,7 @@
 	rxe = rxe_get_dev_from_net(ndev);
 	if (rxe) {
 		ib_device_put(&rxe->ib_dev);
-		rxe_err_dev(rxe, "already configured on %s", ndev->name);
+		rxe_err_dev(rxe, "already configured on %s\n", ndev->name);
 		err = -EEXIST;
 		goto err;
 	}
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/rxe/rxe.h
+++ linux-qcom-6.8.0/drivers/infiniband/sw/rxe/rxe.h
@@ -38,7 +38,7 @@
 
 #define RXE_ROCE_V2_SPORT		(0xc000)
 
-#define rxe_dbg(fmt, ...) pr_debug("%s: " fmt "\n", __func__, ##__VA_ARGS__)
+#define rxe_dbg(fmt, ...) pr_debug("%s: " fmt, __func__, ##__VA_ARGS__)
 #define rxe_dbg_dev(rxe, fmt, ...) ibdev_dbg(&(rxe)->ib_dev,		\
 		"%s: " fmt, __func__, ##__VA_ARGS__)
 #define rxe_dbg_uc(uc, fmt, ...) ibdev_dbg((uc)->ibuc.device,		\
@@ -58,7 +58,7 @@
 #define rxe_dbg_mw(mw, fmt, ...) ibdev_dbg((mw)->ibmw.device,		\
 		"mw#%d %s:  " fmt, (mw)->elem.index, __func__, ##__VA_ARGS__)
 
-#define rxe_err(fmt, ...) pr_err_ratelimited("%s: " fmt "\n", __func__, \
+#define rxe_err(fmt, ...) pr_err_ratelimited("%s: " fmt, __func__, \
 					##__VA_ARGS__)
 #define rxe_err_dev(rxe, fmt, ...) ibdev_err_ratelimited(&(rxe)->ib_dev, \
 		"%s: " fmt, __func__, ##__VA_ARGS__)
@@ -79,7 +79,7 @@
 #define rxe_err_mw(mw, fmt, ...) ibdev_err_ratelimited((mw)->ibmw.device, \
 		"mw#%d %s:  " fmt, (mw)->elem.index, __func__, ##__VA_ARGS__)
 
-#define rxe_info(fmt, ...) pr_info_ratelimited("%s: " fmt "\n", __func__, \
+#define rxe_info(fmt, ...) pr_info_ratelimited("%s: " fmt, __func__, \
 					##__VA_ARGS__)
 #define rxe_info_dev(rxe, fmt, ...) ibdev_info_ratelimited(&(rxe)->ib_dev, \
 		"%s: " fmt, __func__, ##__VA_ARGS__)
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/rxe/rxe_comp.c
+++ linux-qcom-6.8.0/drivers/infiniband/sw/rxe/rxe_comp.c
@@ -131,12 +131,12 @@
 {
 	int must_sched;
 
-	skb_queue_tail(&qp->resp_pkts, skb);
-
-	must_sched = skb_queue_len(&qp->resp_pkts) > 1;
+	must_sched = skb_queue_len(&qp->resp_pkts) > 0;
 	if (must_sched != 0)
 		rxe_counter_inc(SKB_TO_PKT(skb)->rxe, RXE_CNT_COMPLETER_SCHED);
 
+	skb_queue_tail(&qp->resp_pkts, skb);
+
 	if (must_sched)
 		rxe_sched_task(&qp->comp.task);
 	else
@@ -433,7 +433,7 @@
 		}
 	} else {
 		if (wqe->status != IB_WC_WR_FLUSH_ERR)
-			rxe_err_qp(qp, "non-flush error status = %d",
+			rxe_err_qp(qp, "non-flush error status = %d\n",
 				wqe->status);
 	}
 }
@@ -582,7 +582,7 @@
 
 	err = rxe_cq_post(qp->scq, &cqe, 0);
 	if (err)
-		rxe_dbg_cq(qp->scq, "post cq failed, err = %d", err);
+		rxe_dbg_cq(qp->scq, "post cq failed, err = %d\n", err);
 
 	return err;
 }
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/rxe/rxe_cq.c
+++ linux-qcom-6.8.0/drivers/infiniband/sw/rxe/rxe_cq.c
@@ -27,7 +27,7 @@
 	if (cq) {
 		count = queue_count(cq->queue, QUEUE_TYPE_TO_CLIENT);
 		if (cqe < count) {
-			rxe_dbg_cq(cq, "cqe(%d) < current # elements in queue (%d)",
+			rxe_dbg_cq(cq, "cqe(%d) < current # elements in queue (%d)\n",
 					cqe, count);
 			goto err1;
 		}
@@ -96,7 +96,7 @@
 
 	full = queue_full(cq->queue, QUEUE_TYPE_TO_CLIENT);
 	if (unlikely(full)) {
-		rxe_err_cq(cq, "queue full");
+		rxe_err_cq(cq, "queue full\n");
 		spin_unlock_irqrestore(&cq->cq_lock, flags);
 		if (cq->ibcq.event_handler) {
 			ev.device = cq->ibcq.device;
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/rxe/rxe_mr.c
+++ linux-qcom-6.8.0/drivers/infiniband/sw/rxe/rxe_mr.c
@@ -34,7 +34,7 @@
 	case IB_MR_TYPE_MEM_REG:
 		if (iova < mr->ibmr.iova ||
 		    iova + length > mr->ibmr.iova + mr->ibmr.length) {
-			rxe_dbg_mr(mr, "iova/length out of range");
+			rxe_dbg_mr(mr, "iova/length out of range\n");
 			return -EINVAL;
 		}
 		return 0;
@@ -319,7 +319,7 @@
 
 	err = mr_check_range(mr, iova, length);
 	if (unlikely(err)) {
-		rxe_dbg_mr(mr, "iova out of range");
+		rxe_dbg_mr(mr, "iova out of range\n");
 		return err;
 	}
 
@@ -477,7 +477,7 @@
 	u64 *va;
 
 	if (unlikely(mr->state != RXE_MR_STATE_VALID)) {
-		rxe_dbg_mr(mr, "mr not in valid state");
+		rxe_dbg_mr(mr, "mr not in valid state\n");
 		return RESPST_ERR_RKEY_VIOLATION;
 	}
 
@@ -490,7 +490,7 @@
 
 		err = mr_check_range(mr, iova, sizeof(value));
 		if (err) {
-			rxe_dbg_mr(mr, "iova out of range");
+			rxe_dbg_mr(mr, "iova out of range\n");
 			return RESPST_ERR_RKEY_VIOLATION;
 		}
 		page_offset = rxe_mr_iova_to_page_offset(mr, iova);
@@ -501,7 +501,7 @@
 	}
 
 	if (unlikely(page_offset & 0x7)) {
-		rxe_dbg_mr(mr, "iova not aligned");
+		rxe_dbg_mr(mr, "iova not aligned\n");
 		return RESPST_ERR_MISALIGNED_ATOMIC;
 	}
 
@@ -534,7 +534,7 @@
 
 	/* See IBA oA19-28 */
 	if (unlikely(mr->state != RXE_MR_STATE_VALID)) {
-		rxe_dbg_mr(mr, "mr not in valid state");
+		rxe_dbg_mr(mr, "mr not in valid state\n");
 		return RESPST_ERR_RKEY_VIOLATION;
 	}
 
@@ -548,7 +548,7 @@
 		/* See IBA oA19-28 */
 		err = mr_check_range(mr, iova, sizeof(value));
 		if (unlikely(err)) {
-			rxe_dbg_mr(mr, "iova out of range");
+			rxe_dbg_mr(mr, "iova out of range\n");
 			return RESPST_ERR_RKEY_VIOLATION;
 		}
 		page_offset = rxe_mr_iova_to_page_offset(mr, iova);
@@ -560,7 +560,7 @@
 
 	/* See IBA A19.4.2 */
 	if (unlikely(page_offset & 0x7)) {
-		rxe_dbg_mr(mr, "misaligned address");
+		rxe_dbg_mr(mr, "misaligned address\n");
 		return RESPST_ERR_MISALIGNED_ATOMIC;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/rxe/rxe_mw.c
+++ linux-qcom-6.8.0/drivers/infiniband/sw/rxe/rxe_mw.c
@@ -198,7 +198,7 @@
 	}
 
 	if (access & ~RXE_ACCESS_SUPPORTED_MW) {
-		rxe_err_mw(mw, "access %#x not supported", access);
+		rxe_err_mw(mw, "access %#x not supported\n", access);
 		ret = -EOPNOTSUPP;
 		goto err_drop_mr;
 	}
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/rxe/rxe_net.c
+++ linux-qcom-6.8.0/drivers/infiniband/sw/rxe/rxe_net.c
@@ -366,18 +366,10 @@
 	rxe_get(pkt->qp);
 	atomic_inc(&pkt->qp->skb_out);
 
-	if (skb->protocol == htons(ETH_P_IP)) {
+	if (skb->protocol == htons(ETH_P_IP))
 		err = ip_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb);
-	} else if (skb->protocol == htons(ETH_P_IPV6)) {
+	else
 		err = ip6_local_out(dev_net(skb_dst(skb)->dev), skb->sk, skb);
-	} else {
-		rxe_dbg_qp(pkt->qp, "Unknown layer 3 protocol: %d\n",
-				skb->protocol);
-		atomic_dec(&pkt->qp->skb_out);
-		rxe_put(pkt->qp);
-		kfree_skb(skb);
-		return -EINVAL;
-	}
 
 	if (unlikely(net_xmit_eval(err))) {
 		rxe_dbg_qp(pkt->qp, "error sending packet: %d\n", err);
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/rxe/rxe_param.h
+++ linux-qcom-6.8.0/drivers/infiniband/sw/rxe/rxe_param.h
@@ -129,7 +129,7 @@
 enum rxe_port_param {
 	RXE_PORT_GID_TBL_LEN		= 1024,
 	RXE_PORT_PORT_CAP_FLAGS		= IB_PORT_CM_SUP,
-	RXE_PORT_MAX_MSG_SZ		= 0x800000,
+	RXE_PORT_MAX_MSG_SZ		= (1UL << 31),
 	RXE_PORT_BAD_PKEY_CNTR		= 0,
 	RXE_PORT_QKEY_VIOL_CNTR		= 0,
 	RXE_PORT_LID			= 0,
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/rxe/rxe_pool.c
+++ linux-qcom-6.8.0/drivers/infiniband/sw/rxe/rxe_pool.c
@@ -178,7 +178,6 @@
 {
 	struct rxe_pool *pool = elem->pool;
 	struct xarray *xa = &pool->xa;
-	static int timeout = RXE_POOL_TIMEOUT;
 	int ret, err = 0;
 	void *xa_ret;
 
@@ -202,19 +201,19 @@
 	 * return to rdma-core
 	 */
 	if (sleepable) {
-		if (!completion_done(&elem->complete) && timeout) {
+		if (!completion_done(&elem->complete)) {
 			ret = wait_for_completion_timeout(&elem->complete,
-					timeout);
+					msecs_to_jiffies(50000));
 
 			/* Shouldn't happen. There are still references to
 			 * the object but, rather than deadlock, free the
 			 * object or pass back to rdma-core.
 			 */
 			if (WARN_ON(!ret))
-				err = -EINVAL;
+				err = -ETIMEDOUT;
 		}
 	} else {
-		unsigned long until = jiffies + timeout;
+		unsigned long until = jiffies + RXE_POOL_TIMEOUT;
 
 		/* AH objects are unique in that the destroy_ah verb
 		 * can be called in atomic context. This delay
@@ -226,7 +225,7 @@
 			mdelay(1);
 
 		if (WARN_ON(!completion_done(&elem->complete)))
-			err = -EINVAL;
+			err = -ETIMEDOUT;
 	}
 
 	if (pool->cleanup)
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/rxe/rxe_qp.c
+++ linux-qcom-6.8.0/drivers/infiniband/sw/rxe/rxe_qp.c
@@ -201,7 +201,7 @@
 	qp->sq.queue = rxe_queue_init(rxe, &qp->sq.max_wr, wqe_size,
 				      QUEUE_TYPE_FROM_CLIENT);
 	if (!qp->sq.queue) {
-		rxe_err_qp(qp, "Unable to allocate send queue");
+		rxe_err_qp(qp, "Unable to allocate send queue\n");
 		err = -ENOMEM;
 		goto err_out;
 	}
@@ -211,7 +211,7 @@
 			   qp->sq.queue->buf, qp->sq.queue->buf_size,
 			   &qp->sq.queue->ip);
 	if (err) {
-		rxe_err_qp(qp, "do_mmap_info failed, err = %d", err);
+		rxe_err_qp(qp, "do_mmap_info failed, err = %d\n", err);
 		goto err_free;
 	}
 
@@ -292,7 +292,7 @@
 	qp->rq.queue = rxe_queue_init(rxe, &qp->rq.max_wr, wqe_size,
 				      QUEUE_TYPE_FROM_CLIENT);
 	if (!qp->rq.queue) {
-		rxe_err_qp(qp, "Unable to allocate recv queue");
+		rxe_err_qp(qp, "Unable to allocate recv queue\n");
 		err = -ENOMEM;
 		goto err_out;
 	}
@@ -302,7 +302,7 @@
 			   qp->rq.queue->buf, qp->rq.queue->buf_size,
 			   &qp->rq.queue->ip);
 	if (err) {
-		rxe_err_qp(qp, "do_mmap_info failed, err = %d", err);
+		rxe_err_qp(qp, "do_mmap_info failed, err = %d\n", err);
 		goto err_free;
 	}
 
@@ -781,6 +781,7 @@
 	 * Yield the processor
 	 */
 	spin_lock_irqsave(&qp->state_lock, flags);
+	attr->cur_qp_state = qp_state(qp);
 	if (qp->attr.sq_draining) {
 		spin_unlock_irqrestore(&qp->state_lock, flags);
 		cond_resched();
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/rxe/rxe_req.c
+++ linux-qcom-6.8.0/drivers/infiniband/sw/rxe/rxe_req.c
@@ -424,7 +424,7 @@
 	int			paylen;
 	int			solicited;
 	u32			qp_num;
-	int			ack_req;
+	int			ack_req = 0;
 
 	/* length from start of bth to end of icrc */
 	paylen = rxe_opcode[opcode].length + payload + pad + RXE_ICRC_SIZE;
@@ -445,8 +445,9 @@
 	qp_num = (pkt->mask & RXE_DETH_MASK) ? ibwr->wr.ud.remote_qpn :
 					 qp->attr.dest_qp_num;
 
-	ack_req = ((pkt->mask & RXE_END_MASK) ||
-		(qp->req.noack_pkts++ > RXE_MAX_PKT_PER_ACK));
+	if (qp_type(qp) != IB_QPT_UD && qp_type(qp) != IB_QPT_UC)
+		ack_req = ((pkt->mask & RXE_END_MASK) ||
+			   (qp->req.noack_pkts++ > RXE_MAX_PKT_PER_ACK));
 	if (ack_req)
 		qp->req.noack_pkts = 0;
 
@@ -692,10 +693,12 @@
 	if (unlikely(qp_state(qp) == IB_QPS_ERR)) {
 		wqe = __req_next_wqe(qp);
 		spin_unlock_irqrestore(&qp->state_lock, flags);
-		if (wqe)
+		if (wqe) {
+			wqe->status = IB_WC_WR_FLUSH_ERR;
 			goto err;
-		else
+		} else {
 			goto exit;
+		}
 	}
 
 	if (unlikely(qp_state(qp) == IB_QPS_RESET)) {
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/rxe/rxe_resp.c
+++ linux-qcom-6.8.0/drivers/infiniband/sw/rxe/rxe_resp.c
@@ -354,6 +354,19 @@
 	 * receive buffer later. For rmda operations additional
 	 * length checks are performed in check_rkey.
 	 */
+	if ((qp_type(qp) == IB_QPT_GSI) || (qp_type(qp) == IB_QPT_UD)) {
+		unsigned int payload = payload_size(pkt);
+		unsigned int recv_buffer_len = 0;
+		int i;
+
+		for (i = 0; i < qp->resp.wqe->dma.num_sge; i++)
+			recv_buffer_len += qp->resp.wqe->dma.sge[i].length;
+		if (payload + 40 > recv_buffer_len) {
+			rxe_dbg_qp(qp, "The receive buffer is too small for this UD packet.\n");
+			return RESPST_ERR_LENGTH;
+		}
+	}
+
 	if (pkt->mask & RXE_PAYLOAD_MASK && ((qp_type(qp) == IB_QPT_RC) ||
 					     (qp_type(qp) == IB_QPT_UC))) {
 		unsigned int mtu = qp->mtu;
@@ -362,18 +375,18 @@
 		if ((pkt->mask & RXE_START_MASK) &&
 		    (pkt->mask & RXE_END_MASK)) {
 			if (unlikely(payload > mtu)) {
-				rxe_dbg_qp(qp, "only packet too long");
+				rxe_dbg_qp(qp, "only packet too long\n");
 				return RESPST_ERR_LENGTH;
 			}
 		} else if ((pkt->mask & RXE_START_MASK) ||
 			   (pkt->mask & RXE_MIDDLE_MASK)) {
 			if (unlikely(payload != mtu)) {
-				rxe_dbg_qp(qp, "first or middle packet not mtu");
+				rxe_dbg_qp(qp, "first or middle packet not mtu\n");
 				return RESPST_ERR_LENGTH;
 			}
 		} else if (pkt->mask & RXE_END_MASK) {
 			if (unlikely((payload == 0) || (payload > mtu))) {
-				rxe_dbg_qp(qp, "last packet zero or too long");
+				rxe_dbg_qp(qp, "last packet zero or too long\n");
 				return RESPST_ERR_LENGTH;
 			}
 		}
@@ -382,7 +395,7 @@
 	/* See IBA C9-94 */
 	if (pkt->mask & RXE_RETH_MASK) {
 		if (reth_len(pkt) > (1U << 31)) {
-			rxe_dbg_qp(qp, "dma length too long");
+			rxe_dbg_qp(qp, "dma length too long\n");
 			return RESPST_ERR_LENGTH;
 		}
 	}
@@ -1133,7 +1146,7 @@
 		}
 	} else {
 		if (wc->status != IB_WC_WR_FLUSH_ERR)
-			rxe_err_qp(qp, "non-flush error status = %d",
+			rxe_err_qp(qp, "non-flush error status = %d\n",
 				wc->status);
 	}
 
@@ -1442,7 +1455,7 @@
 
 	err = rxe_cq_post(qp->rcq, &cqe, 0);
 	if (err)
-		rxe_dbg_cq(qp->rcq, "post cq failed err = %d", err);
+		rxe_dbg_cq(qp->rcq, "post cq failed err = %d\n", err);
 
 	return err;
 }
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/rxe/rxe_task.c
+++ linux-qcom-6.8.0/drivers/infiniband/sw/rxe/rxe_task.c
@@ -156,7 +156,7 @@
 
 		default:
 			WARN_ON(1);
-			rxe_dbg_qp(task->qp, "unexpected task state = %d",
+			rxe_dbg_qp(task->qp, "unexpected task state = %d\n",
 				   task->state);
 			task->state = TASK_STATE_IDLE;
 		}
@@ -167,7 +167,7 @@
 			if (WARN_ON(task->num_done != task->num_sched))
 				rxe_dbg_qp(
 					task->qp,
-					"%ld tasks scheduled, %ld tasks done",
+					"%ld tasks scheduled, %ld tasks done\n",
 					task->num_sched, task->num_done);
 		}
 		spin_unlock_irqrestore(&task->lock, flags);
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ linux-qcom-6.8.0/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -23,7 +23,7 @@
 	int err;
 
 	if (udata->inlen || udata->outlen) {
-		rxe_dbg_dev(rxe, "malformed udata");
+		rxe_dbg_dev(rxe, "malformed udata\n");
 		err = -EINVAL;
 		goto err_out;
 	}
@@ -33,7 +33,7 @@
 	return 0;
 
 err_out:
-	rxe_err_dev(rxe, "returned err = %d", err);
+	rxe_err_dev(rxe, "returned err = %d\n", err);
 	return err;
 }
 
@@ -45,7 +45,7 @@
 
 	if (port_num != 1) {
 		err = -EINVAL;
-		rxe_dbg_dev(rxe, "bad port_num = %d", port_num);
+		rxe_dbg_dev(rxe, "bad port_num = %d\n", port_num);
 		goto err_out;
 	}
 
@@ -67,7 +67,7 @@
 	return ret;
 
 err_out:
-	rxe_err_dev(rxe, "returned err = %d", err);
+	rxe_err_dev(rxe, "returned err = %d\n", err);
 	return err;
 }
 
@@ -79,7 +79,7 @@
 
 	if (index != 0) {
 		err = -EINVAL;
-		rxe_dbg_dev(rxe, "bad pkey index = %d", index);
+		rxe_dbg_dev(rxe, "bad pkey index = %d\n", index);
 		goto err_out;
 	}
 
@@ -87,7 +87,7 @@
 	return 0;
 
 err_out:
-	rxe_err_dev(rxe, "returned err = %d", err);
+	rxe_err_dev(rxe, "returned err = %d\n", err);
 	return err;
 }
 
@@ -100,7 +100,7 @@
 	if (mask & ~(IB_DEVICE_MODIFY_SYS_IMAGE_GUID |
 		     IB_DEVICE_MODIFY_NODE_DESC)) {
 		err = -EOPNOTSUPP;
-		rxe_dbg_dev(rxe, "unsupported mask = 0x%x", mask);
+		rxe_dbg_dev(rxe, "unsupported mask = 0x%x\n", mask);
 		goto err_out;
 	}
 
@@ -115,7 +115,7 @@
 	return 0;
 
 err_out:
-	rxe_err_dev(rxe, "returned err = %d", err);
+	rxe_err_dev(rxe, "returned err = %d\n", err);
 	return err;
 }
 
@@ -128,14 +128,14 @@
 
 	if (port_num != 1) {
 		err = -EINVAL;
-		rxe_dbg_dev(rxe, "bad port_num = %d", port_num);
+		rxe_dbg_dev(rxe, "bad port_num = %d\n", port_num);
 		goto err_out;
 	}
 
 	//TODO is shutdown useful
 	if (mask & ~(IB_PORT_RESET_QKEY_CNTR)) {
 		err = -EOPNOTSUPP;
-		rxe_dbg_dev(rxe, "unsupported mask = 0x%x", mask);
+		rxe_dbg_dev(rxe, "unsupported mask = 0x%x\n", mask);
 		goto err_out;
 	}
 
@@ -149,7 +149,7 @@
 	return 0;
 
 err_out:
-	rxe_err_dev(rxe, "returned err = %d", err);
+	rxe_err_dev(rxe, "returned err = %d\n", err);
 	return err;
 }
 
@@ -161,14 +161,14 @@
 
 	if (port_num != 1) {
 		err = -EINVAL;
-		rxe_dbg_dev(rxe, "bad port_num = %d", port_num);
+		rxe_dbg_dev(rxe, "bad port_num = %d\n", port_num);
 		goto err_out;
 	}
 
 	return IB_LINK_LAYER_ETHERNET;
 
 err_out:
-	rxe_err_dev(rxe, "returned err = %d", err);
+	rxe_err_dev(rxe, "returned err = %d\n", err);
 	return err;
 }
 
@@ -181,7 +181,7 @@
 
 	if (port_num != 1) {
 		err = -EINVAL;
-		rxe_dbg_dev(rxe, "bad port_num = %d", port_num);
+		rxe_dbg_dev(rxe, "bad port_num = %d\n", port_num);
 		goto err_out;
 	}
 
@@ -197,7 +197,7 @@
 	return 0;
 
 err_out:
-	rxe_err_dev(rxe, "returned err = %d", err);
+	rxe_err_dev(rxe, "returned err = %d\n", err);
 	return err;
 }
 
@@ -210,7 +210,7 @@
 
 	err = rxe_add_to_pool(&rxe->uc_pool, uc);
 	if (err)
-		rxe_err_dev(rxe, "unable to create uc");
+		rxe_err_dev(rxe, "unable to create uc\n");
 
 	return err;
 }
@@ -222,7 +222,7 @@
 
 	err = rxe_cleanup(uc);
 	if (err)
-		rxe_err_uc(uc, "cleanup failed, err = %d", err);
+		rxe_err_uc(uc, "cleanup failed, err = %d\n", err);
 }
 
 /* pd */
@@ -234,14 +234,14 @@
 
 	err = rxe_add_to_pool(&rxe->pd_pool, pd);
 	if (err) {
-		rxe_dbg_dev(rxe, "unable to alloc pd");
+		rxe_dbg_dev(rxe, "unable to alloc pd\n");
 		goto err_out;
 	}
 
 	return 0;
 
 err_out:
-	rxe_err_dev(rxe, "returned err = %d", err);
+	rxe_err_dev(rxe, "returned err = %d\n", err);
 	return err;
 }
 
@@ -252,7 +252,7 @@
 
 	err = rxe_cleanup(pd);
 	if (err)
-		rxe_err_pd(pd, "cleanup failed, err = %d", err);
+		rxe_err_pd(pd, "cleanup failed, err = %d\n", err);
 
 	return 0;
 }
@@ -279,7 +279,7 @@
 	err = rxe_add_to_pool_ah(&rxe->ah_pool, ah,
 			init_attr->flags & RDMA_CREATE_AH_SLEEPABLE);
 	if (err) {
-		rxe_dbg_dev(rxe, "unable to create ah");
+		rxe_dbg_dev(rxe, "unable to create ah\n");
 		goto err_out;
 	}
 
@@ -288,7 +288,7 @@
 
 	err = rxe_ah_chk_attr(ah, init_attr->ah_attr);
 	if (err) {
-		rxe_dbg_ah(ah, "bad attr");
+		rxe_dbg_ah(ah, "bad attr\n");
 		goto err_cleanup;
 	}
 
@@ -298,7 +298,7 @@
 					 sizeof(uresp->ah_num));
 		if (err) {
 			err = -EFAULT;
-			rxe_dbg_ah(ah, "unable to copy to user");
+			rxe_dbg_ah(ah, "unable to copy to user\n");
 			goto err_cleanup;
 		}
 	} else if (ah->is_user) {
@@ -314,9 +314,9 @@
 err_cleanup:
 	cleanup_err = rxe_cleanup(ah);
 	if (cleanup_err)
-		rxe_err_ah(ah, "cleanup failed, err = %d", cleanup_err);
+		rxe_err_ah(ah, "cleanup failed, err = %d\n", cleanup_err);
 err_out:
-	rxe_err_ah(ah, "returned err = %d", err);
+	rxe_err_ah(ah, "returned err = %d\n", err);
 	return err;
 }
 
@@ -327,7 +327,7 @@
 
 	err = rxe_ah_chk_attr(ah, attr);
 	if (err) {
-		rxe_dbg_ah(ah, "bad attr");
+		rxe_dbg_ah(ah, "bad attr\n");
 		goto err_out;
 	}
 
@@ -336,7 +336,7 @@
 	return 0;
 
 err_out:
-	rxe_err_ah(ah, "returned err = %d", err);
+	rxe_err_ah(ah, "returned err = %d\n", err);
 	return err;
 }
 
@@ -358,7 +358,7 @@
 
 	err = rxe_cleanup_ah(ah, flags & RDMA_DESTROY_AH_SLEEPABLE);
 	if (err)
-		rxe_err_ah(ah, "cleanup failed, err = %d", err);
+		rxe_err_ah(ah, "cleanup failed, err = %d\n", err);
 
 	return 0;
 }
@@ -376,7 +376,7 @@
 	if (udata) {
 		if (udata->outlen < sizeof(*uresp)) {
 			err = -EINVAL;
-			rxe_err_dev(rxe, "malformed udata");
+			rxe_err_dev(rxe, "malformed udata\n");
 			goto err_out;
 		}
 		uresp = udata->outbuf;
@@ -384,20 +384,20 @@
 
 	if (init->srq_type != IB_SRQT_BASIC) {
 		err = -EOPNOTSUPP;
-		rxe_dbg_dev(rxe, "srq type = %d, not supported",
+		rxe_dbg_dev(rxe, "srq type = %d, not supported\n",
 				init->srq_type);
 		goto err_out;
 	}
 
 	err = rxe_srq_chk_init(rxe, init);
 	if (err) {
-		rxe_dbg_dev(rxe, "invalid init attributes");
+		rxe_dbg_dev(rxe, "invalid init attributes\n");
 		goto err_out;
 	}
 
 	err = rxe_add_to_pool(&rxe->srq_pool, srq);
 	if (err) {
-		rxe_dbg_dev(rxe, "unable to create srq, err = %d", err);
+		rxe_dbg_dev(rxe, "unable to create srq, err = %d\n", err);
 		goto err_out;
 	}
 
@@ -406,7 +406,7 @@
 
 	err = rxe_srq_from_init(rxe, srq, init, udata, uresp);
 	if (err) {
-		rxe_dbg_srq(srq, "create srq failed, err = %d", err);
+		rxe_dbg_srq(srq, "create srq failed, err = %d\n", err);
 		goto err_cleanup;
 	}
 
@@ -415,9 +415,9 @@
 err_cleanup:
 	cleanup_err = rxe_cleanup(srq);
 	if (cleanup_err)
-		rxe_err_srq(srq, "cleanup failed, err = %d", cleanup_err);
+		rxe_err_srq(srq, "cleanup failed, err = %d\n", cleanup_err);
 err_out:
-	rxe_err_dev(rxe, "returned err = %d", err);
+	rxe_err_dev(rxe, "returned err = %d\n", err);
 	return err;
 }
 
@@ -433,34 +433,34 @@
 	if (udata) {
 		if (udata->inlen < sizeof(cmd)) {
 			err = -EINVAL;
-			rxe_dbg_srq(srq, "malformed udata");
+			rxe_dbg_srq(srq, "malformed udata\n");
 			goto err_out;
 		}
 
 		err = ib_copy_from_udata(&cmd, udata, sizeof(cmd));
 		if (err) {
 			err = -EFAULT;
-			rxe_dbg_srq(srq, "unable to read udata");
+			rxe_dbg_srq(srq, "unable to read udata\n");
 			goto err_out;
 		}
 	}
 
 	err = rxe_srq_chk_attr(rxe, srq, attr, mask);
 	if (err) {
-		rxe_dbg_srq(srq, "bad init attributes");
+		rxe_dbg_srq(srq, "bad init attributes\n");
 		goto err_out;
 	}
 
 	err = rxe_srq_from_attr(rxe, srq, attr, mask, &cmd, udata);
 	if (err) {
-		rxe_dbg_srq(srq, "bad attr");
+		rxe_dbg_srq(srq, "bad attr\n");
 		goto err_out;
 	}
 
 	return 0;
 
 err_out:
-	rxe_err_srq(srq, "returned err = %d", err);
+	rxe_err_srq(srq, "returned err = %d\n", err);
 	return err;
 }
 
@@ -471,7 +471,7 @@
 
 	if (srq->error) {
 		err = -EINVAL;
-		rxe_dbg_srq(srq, "srq in error state");
+		rxe_dbg_srq(srq, "srq in error state\n");
 		goto err_out;
 	}
 
@@ -481,7 +481,7 @@
 	return 0;
 
 err_out:
-	rxe_err_srq(srq, "returned err = %d", err);
+	rxe_err_srq(srq, "returned err = %d\n", err);
 	return err;
 }
 
@@ -505,7 +505,7 @@
 
 	if (err) {
 		*bad_wr = wr;
-		rxe_err_srq(srq, "returned err = %d", err);
+		rxe_err_srq(srq, "returned err = %d\n", err);
 	}
 
 	return err;
@@ -518,7 +518,7 @@
 
 	err = rxe_cleanup(srq);
 	if (err)
-		rxe_err_srq(srq, "cleanup failed, err = %d", err);
+		rxe_err_srq(srq, "cleanup failed, err = %d\n", err);
 
 	return 0;
 }
@@ -536,13 +536,13 @@
 	if (udata) {
 		if (udata->inlen) {
 			err = -EINVAL;
-			rxe_dbg_dev(rxe, "malformed udata, err = %d", err);
+			rxe_dbg_dev(rxe, "malformed udata, err = %d\n", err);
 			goto err_out;
 		}
 
 		if (udata->outlen < sizeof(*uresp)) {
 			err = -EINVAL;
-			rxe_dbg_dev(rxe, "malformed udata, err = %d", err);
+			rxe_dbg_dev(rxe, "malformed udata, err = %d\n", err);
 			goto err_out;
 		}
 
@@ -554,25 +554,25 @@
 
 	if (init->create_flags) {
 		err = -EOPNOTSUPP;
-		rxe_dbg_dev(rxe, "unsupported create_flags, err = %d", err);
+		rxe_dbg_dev(rxe, "unsupported create_flags, err = %d\n", err);
 		goto err_out;
 	}
 
 	err = rxe_qp_chk_init(rxe, init);
 	if (err) {
-		rxe_dbg_dev(rxe, "bad init attr, err = %d", err);
+		rxe_dbg_dev(rxe, "bad init attr, err = %d\n", err);
 		goto err_out;
 	}
 
 	err = rxe_add_to_pool(&rxe->qp_pool, qp);
 	if (err) {
-		rxe_dbg_dev(rxe, "unable to create qp, err = %d", err);
+		rxe_dbg_dev(rxe, "unable to create qp, err = %d\n", err);
 		goto err_out;
 	}
 
 	err = rxe_qp_from_init(rxe, qp, pd, init, uresp, ibqp->pd, udata);
 	if (err) {
-		rxe_dbg_qp(qp, "create qp failed, err = %d", err);
+		rxe_dbg_qp(qp, "create qp failed, err = %d\n", err);
 		goto err_cleanup;
 	}
 
@@ -582,9 +582,9 @@
 err_cleanup:
 	cleanup_err = rxe_cleanup(qp);
 	if (cleanup_err)
-		rxe_err_qp(qp, "cleanup failed, err = %d", cleanup_err);
+		rxe_err_qp(qp, "cleanup failed, err = %d\n", cleanup_err);
 err_out:
-	rxe_err_dev(rxe, "returned err = %d", err);
+	rxe_err_dev(rxe, "returned err = %d\n", err);
 	return err;
 }
 
@@ -597,20 +597,20 @@
 
 	if (mask & ~IB_QP_ATTR_STANDARD_BITS) {
 		err = -EOPNOTSUPP;
-		rxe_dbg_qp(qp, "unsupported mask = 0x%x, err = %d",
+		rxe_dbg_qp(qp, "unsupported mask = 0x%x, err = %d\n",
 			   mask, err);
 		goto err_out;
 	}
 
 	err = rxe_qp_chk_attr(rxe, qp, attr, mask);
 	if (err) {
-		rxe_dbg_qp(qp, "bad mask/attr, err = %d", err);
+		rxe_dbg_qp(qp, "bad mask/attr, err = %d\n", err);
 		goto err_out;
 	}
 
 	err = rxe_qp_from_attr(qp, attr, mask, udata);
 	if (err) {
-		rxe_dbg_qp(qp, "modify qp failed, err = %d", err);
+		rxe_dbg_qp(qp, "modify qp failed, err = %d\n", err);
 		goto err_out;
 	}
 
@@ -622,7 +622,7 @@
 	return 0;
 
 err_out:
-	rxe_err_qp(qp, "returned err = %d", err);
+	rxe_err_qp(qp, "returned err = %d\n", err);
 	return err;
 }
 
@@ -644,18 +644,18 @@
 
 	err = rxe_qp_chk_destroy(qp);
 	if (err) {
-		rxe_dbg_qp(qp, "unable to destroy qp, err = %d", err);
+		rxe_dbg_qp(qp, "unable to destroy qp, err = %d\n", err);
 		goto err_out;
 	}
 
 	err = rxe_cleanup(qp);
 	if (err)
-		rxe_err_qp(qp, "cleanup failed, err = %d", err);
+		rxe_err_qp(qp, "cleanup failed, err = %d\n", err);
 
 	return 0;
 
 err_out:
-	rxe_err_qp(qp, "returned err = %d", err);
+	rxe_err_qp(qp, "returned err = %d\n", err);
 	return err;
 }
 
@@ -675,12 +675,12 @@
 	do {
 		mask = wr_opcode_mask(ibwr->opcode, qp);
 		if (!mask) {
-			rxe_err_qp(qp, "bad wr opcode for qp type");
+			rxe_err_qp(qp, "bad wr opcode for qp type\n");
 			break;
 		}
 
 		if (num_sge > sq->max_sge) {
-			rxe_err_qp(qp, "num_sge > max_sge");
+			rxe_err_qp(qp, "num_sge > max_sge\n");
 			break;
 		}
 
@@ -688,28 +688,28 @@
 		for (i = 0; i < ibwr->num_sge; i++)
 			length += ibwr->sg_list[i].length;
 
-		if (length > (1UL << 31)) {
-			rxe_err_qp(qp, "message length too long");
+		if (length > RXE_PORT_MAX_MSG_SZ) {
+			rxe_err_qp(qp, "message length too long\n");
 			break;
 		}
 
 		if (mask & WR_ATOMIC_MASK) {
 			if (length != 8) {
-				rxe_err_qp(qp, "atomic length != 8");
+				rxe_err_qp(qp, "atomic length != 8\n");
 				break;
 			}
 			if (atomic_wr(ibwr)->remote_addr & 0x7) {
-				rxe_err_qp(qp, "misaligned atomic address");
+				rxe_err_qp(qp, "misaligned atomic address\n");
 				break;
 			}
 		}
 		if (ibwr->send_flags & IB_SEND_INLINE) {
 			if (!(mask & WR_INLINE_MASK)) {
-				rxe_err_qp(qp, "opcode doesn't support inline data");
+				rxe_err_qp(qp, "opcode doesn't support inline data\n");
 				break;
 			}
 			if (length > sq->max_inline) {
-				rxe_err_qp(qp, "inline length too big");
+				rxe_err_qp(qp, "inline length too big\n");
 				break;
 			}
 		}
@@ -747,7 +747,7 @@
 		case IB_WR_SEND:
 			break;
 		default:
-			rxe_err_qp(qp, "bad wr opcode %d for UD/GSI QP",
+			rxe_err_qp(qp, "bad wr opcode %d for UD/GSI QP\n",
 					wr->opcode);
 			return -EINVAL;
 		}
@@ -795,7 +795,7 @@
 		case IB_WR_ATOMIC_WRITE:
 			break;
 		default:
-			rxe_err_qp(qp, "unsupported wr opcode %d",
+			rxe_err_qp(qp, "unsupported wr opcode %d\n",
 					wr->opcode);
 			return -EINVAL;
 		}
@@ -812,7 +812,7 @@
 	int i;
 
 	for (i = 0; i < ibwr->num_sge; i++, sge++) {
-		memcpy(p, ib_virt_dma_to_page(sge->addr), sge->length);
+		memcpy(p, ib_virt_dma_to_ptr(sge->addr), sge->length);
 		p += sge->length;
 	}
 }
@@ -870,7 +870,7 @@
 
 	full = queue_full(sq->queue, QUEUE_TYPE_FROM_ULP);
 	if (unlikely(full)) {
-		rxe_err_qp(qp, "send queue full");
+		rxe_err_qp(qp, "send queue full\n");
 		return -ENOMEM;
 	}
 
@@ -888,6 +888,7 @@
 {
 	int err = 0;
 	unsigned long flags;
+	int good = 0;
 
 	spin_lock_irqsave(&qp->sq.sq_lock, flags);
 	while (ibwr) {
@@ -895,12 +896,15 @@
 		if (err) {
 			*bad_wr = ibwr;
 			break;
+		} else {
+			good++;
 		}
 		ibwr = ibwr->next;
 	}
 	spin_unlock_irqrestore(&qp->sq.sq_lock, flags);
 
-	if (!err)
+	/* kickoff processing of any posted wqes */
+	if (good)
 		rxe_sched_task(&qp->req.task);
 
 	spin_lock_irqsave(&qp->state_lock, flags);
@@ -922,14 +926,14 @@
 	/* caller has already called destroy_qp */
 	if (WARN_ON_ONCE(!qp->valid)) {
 		spin_unlock_irqrestore(&qp->state_lock, flags);
-		rxe_err_qp(qp, "qp has been destroyed");
+		rxe_err_qp(qp, "qp has been destroyed\n");
 		return -EINVAL;
 	}
 
 	if (unlikely(qp_state(qp) < IB_QPS_RTS)) {
 		spin_unlock_irqrestore(&qp->state_lock, flags);
 		*bad_wr = wr;
-		rxe_err_qp(qp, "qp not ready to send");
+		rxe_err_qp(qp, "qp not ready to send\n");
 		return -EINVAL;
 	}
 	spin_unlock_irqrestore(&qp->state_lock, flags);
@@ -959,13 +963,13 @@
 	full = queue_full(rq->queue, QUEUE_TYPE_FROM_ULP);
 	if (unlikely(full)) {
 		err = -ENOMEM;
-		rxe_dbg("queue full");
+		rxe_dbg("queue full\n");
 		goto err_out;
 	}
 
 	if (unlikely(num_sge > rq->max_sge)) {
 		err = -EINVAL;
-		rxe_dbg("bad num_sge > max_sge");
+		rxe_dbg("bad num_sge > max_sge\n");
 		goto err_out;
 	}
 
@@ -973,10 +977,9 @@
 	for (i = 0; i < num_sge; i++)
 		length += ibwr->sg_list[i].length;
 
-	/* IBA max message size is 2^31 */
-	if (length >= (1UL<<31)) {
+	if (length > RXE_PORT_MAX_MSG_SZ) {
 		err = -EINVAL;
-		rxe_dbg("message length too long");
+		rxe_dbg("message length too long\n");
 		goto err_out;
 	}
 
@@ -996,7 +999,7 @@
 	return 0;
 
 err_out:
-	rxe_dbg("returned err = %d", err);
+	rxe_dbg("returned err = %d\n", err);
 	return err;
 }
 
@@ -1012,7 +1015,7 @@
 	/* caller has already called destroy_qp */
 	if (WARN_ON_ONCE(!qp->valid)) {
 		spin_unlock_irqrestore(&qp->state_lock, flags);
-		rxe_err_qp(qp, "qp has been destroyed");
+		rxe_err_qp(qp, "qp has been destroyed\n");
 		return -EINVAL;
 	}
 
@@ -1020,14 +1023,14 @@
 	if (unlikely((qp_state(qp) < IB_QPS_INIT))) {
 		spin_unlock_irqrestore(&qp->state_lock, flags);
 		*bad_wr = wr;
-		rxe_dbg_qp(qp, "qp not ready to post recv");
+		rxe_dbg_qp(qp, "qp not ready to post recv\n");
 		return -EINVAL;
 	}
 	spin_unlock_irqrestore(&qp->state_lock, flags);
 
 	if (unlikely(qp->srq)) {
 		*bad_wr = wr;
-		rxe_dbg_qp(qp, "qp has srq, use post_srq_recv instead");
+		rxe_dbg_qp(qp, "qp has srq, use post_srq_recv instead\n");
 		return -EINVAL;
 	}
 
@@ -1065,7 +1068,7 @@
 	if (udata) {
 		if (udata->outlen < sizeof(*uresp)) {
 			err = -EINVAL;
-			rxe_dbg_dev(rxe, "malformed udata, err = %d", err);
+			rxe_dbg_dev(rxe, "malformed udata, err = %d\n", err);
 			goto err_out;
 		}
 		uresp = udata->outbuf;
@@ -1073,26 +1076,26 @@
 
 	if (attr->flags) {
 		err = -EOPNOTSUPP;
-		rxe_dbg_dev(rxe, "bad attr->flags, err = %d", err);
+		rxe_dbg_dev(rxe, "bad attr->flags, err = %d\n", err);
 		goto err_out;
 	}
 
 	err = rxe_cq_chk_attr(rxe, NULL, attr->cqe, attr->comp_vector);
 	if (err) {
-		rxe_dbg_dev(rxe, "bad init attributes, err = %d", err);
+		rxe_dbg_dev(rxe, "bad init attributes, err = %d\n", err);
 		goto err_out;
 	}
 
 	err = rxe_add_to_pool(&rxe->cq_pool, cq);
 	if (err) {
-		rxe_dbg_dev(rxe, "unable to create cq, err = %d", err);
+		rxe_dbg_dev(rxe, "unable to create cq, err = %d\n", err);
 		goto err_out;
 	}
 
 	err = rxe_cq_from_init(rxe, cq, attr->cqe, attr->comp_vector, udata,
 			       uresp);
 	if (err) {
-		rxe_dbg_cq(cq, "create cq failed, err = %d", err);
+		rxe_dbg_cq(cq, "create cq failed, err = %d\n", err);
 		goto err_cleanup;
 	}
 
@@ -1101,9 +1104,9 @@
 err_cleanup:
 	cleanup_err = rxe_cleanup(cq);
 	if (cleanup_err)
-		rxe_err_cq(cq, "cleanup failed, err = %d", cleanup_err);
+		rxe_err_cq(cq, "cleanup failed, err = %d\n", cleanup_err);
 err_out:
-	rxe_err_dev(rxe, "returned err = %d", err);
+	rxe_err_dev(rxe, "returned err = %d\n", err);
 	return err;
 }
 
@@ -1117,7 +1120,7 @@
 	if (udata) {
 		if (udata->outlen < sizeof(*uresp)) {
 			err = -EINVAL;
-			rxe_dbg_cq(cq, "malformed udata");
+			rxe_dbg_cq(cq, "malformed udata\n");
 			goto err_out;
 		}
 		uresp = udata->outbuf;
@@ -1125,20 +1128,20 @@
 
 	err = rxe_cq_chk_attr(rxe, cq, cqe, 0);
 	if (err) {
-		rxe_dbg_cq(cq, "bad attr, err = %d", err);
+		rxe_dbg_cq(cq, "bad attr, err = %d\n", err);
 		goto err_out;
 	}
 
 	err = rxe_cq_resize_queue(cq, cqe, uresp, udata);
 	if (err) {
-		rxe_dbg_cq(cq, "resize cq failed, err = %d", err);
+		rxe_dbg_cq(cq, "resize cq failed, err = %d\n", err);
 		goto err_out;
 	}
 
 	return 0;
 
 err_out:
-	rxe_err_cq(cq, "returned err = %d", err);
+	rxe_err_cq(cq, "returned err = %d\n", err);
 	return err;
 }
 
@@ -1202,18 +1205,18 @@
 	 */
 	if (atomic_read(&cq->num_wq)) {
 		err = -EINVAL;
-		rxe_dbg_cq(cq, "still in use");
+		rxe_dbg_cq(cq, "still in use\n");
 		goto err_out;
 	}
 
 	err = rxe_cleanup(cq);
 	if (err)
-		rxe_err_cq(cq, "cleanup failed, err = %d", err);
+		rxe_err_cq(cq, "cleanup failed, err = %d\n", err);
 
 	return 0;
 
 err_out:
-	rxe_err_cq(cq, "returned err = %d", err);
+	rxe_err_cq(cq, "returned err = %d\n", err);
 	return err;
 }
 
@@ -1231,7 +1234,7 @@
 
 	err = rxe_add_to_pool(&rxe->mr_pool, mr);
 	if (err) {
-		rxe_dbg_dev(rxe, "unable to create mr");
+		rxe_dbg_dev(rxe, "unable to create mr\n");
 		goto err_free;
 	}
 
@@ -1245,7 +1248,7 @@
 
 err_free:
 	kfree(mr);
-	rxe_err_pd(pd, "returned err = %d", err);
+	rxe_err_pd(pd, "returned err = %d\n", err);
 	return ERR_PTR(err);
 }
 
@@ -1259,7 +1262,7 @@
 	int err, cleanup_err;
 
 	if (access & ~RXE_ACCESS_SUPPORTED_MR) {
-		rxe_err_pd(pd, "access = %#x not supported (%#x)", access,
+		rxe_err_pd(pd, "access = %#x not supported (%#x)\n", access,
 				RXE_ACCESS_SUPPORTED_MR);
 		return ERR_PTR(-EOPNOTSUPP);
 	}
@@ -1270,7 +1273,7 @@
 
 	err = rxe_add_to_pool(&rxe->mr_pool, mr);
 	if (err) {
-		rxe_dbg_pd(pd, "unable to create mr");
+		rxe_dbg_pd(pd, "unable to create mr\n");
 		goto err_free;
 	}
 
@@ -1280,7 +1283,7 @@
 
 	err = rxe_mr_init_user(rxe, start, length, iova, access, mr);
 	if (err) {
-		rxe_dbg_mr(mr, "reg_user_mr failed, err = %d", err);
+		rxe_dbg_mr(mr, "reg_user_mr failed, err = %d\n", err);
 		goto err_cleanup;
 	}
 
@@ -1290,10 +1293,10 @@
 err_cleanup:
 	cleanup_err = rxe_cleanup(mr);
 	if (cleanup_err)
-		rxe_err_mr(mr, "cleanup failed, err = %d", cleanup_err);
+		rxe_err_mr(mr, "cleanup failed, err = %d\n", cleanup_err);
 err_free:
 	kfree(mr);
-	rxe_err_pd(pd, "returned err = %d", err);
+	rxe_err_pd(pd, "returned err = %d\n", err);
 	return ERR_PTR(err);
 }
 
@@ -1310,7 +1313,7 @@
 	 * rereg_pd and rereg_access
 	 */
 	if (flags & ~RXE_MR_REREG_SUPPORTED) {
-		rxe_err_mr(mr, "flags = %#x not supported", flags);
+		rxe_err_mr(mr, "flags = %#x not supported\n", flags);
 		return ERR_PTR(-EOPNOTSUPP);
 	}
 
@@ -1322,7 +1325,7 @@
 
 	if (flags & IB_MR_REREG_ACCESS) {
 		if (access & ~RXE_ACCESS_SUPPORTED_MR) {
-			rxe_err_mr(mr, "access = %#x not supported", access);
+			rxe_err_mr(mr, "access = %#x not supported\n", access);
 			return ERR_PTR(-EOPNOTSUPP);
 		}
 		mr->access = access;
@@ -1341,7 +1344,7 @@
 
 	if (mr_type != IB_MR_TYPE_MEM_REG) {
 		err = -EINVAL;
-		rxe_dbg_pd(pd, "mr type %d not supported, err = %d",
+		rxe_dbg_pd(pd, "mr type %d not supported, err = %d\n",
 			   mr_type, err);
 		goto err_out;
 	}
@@ -1360,7 +1363,7 @@
 
 	err = rxe_mr_init_fast(max_num_sg, mr);
 	if (err) {
-		rxe_dbg_mr(mr, "alloc_mr failed, err = %d", err);
+		rxe_dbg_mr(mr, "alloc_mr failed, err = %d\n", err);
 		goto err_cleanup;
 	}
 
@@ -1370,11 +1373,11 @@
 err_cleanup:
 	cleanup_err = rxe_cleanup(mr);
 	if (cleanup_err)
-		rxe_err_mr(mr, "cleanup failed, err = %d", err);
+		rxe_err_mr(mr, "cleanup failed, err = %d\n", err);
 err_free:
 	kfree(mr);
 err_out:
-	rxe_err_pd(pd, "returned err = %d", err);
+	rxe_err_pd(pd, "returned err = %d\n", err);
 	return ERR_PTR(err);
 }
 
@@ -1386,19 +1389,19 @@
 	/* See IBA 10.6.7.2.6 */
 	if (atomic_read(&mr->num_mw) > 0) {
 		err = -EINVAL;
-		rxe_dbg_mr(mr, "mr has mw's bound");
+		rxe_dbg_mr(mr, "mr has mw's bound\n");
 		goto err_out;
 	}
 
 	cleanup_err = rxe_cleanup(mr);
 	if (cleanup_err)
-		rxe_err_mr(mr, "cleanup failed, err = %d", cleanup_err);
+		rxe_err_mr(mr, "cleanup failed, err = %d\n", cleanup_err);
 
 	kfree_rcu_mightsleep(mr);
 	return 0;
 
 err_out:
-	rxe_err_mr(mr, "returned err = %d", err);
+	rxe_err_mr(mr, "returned err = %d\n", err);
 	return err;
 }
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/sw/siw/siw_qp_tx.c
+++ linux-qcom-6.8.0/drivers/infiniband/sw/siw/siw_qp_tx.c
@@ -331,6 +331,8 @@
 			msg.msg_flags &= ~MSG_MORE;
 
 		tcp_rate_check_app_limited(sk);
+		if (!sendpage_ok(page[i]))
+			msg.msg_flags &= ~MSG_SPLICE_PAGES;
 		bvec_set_page(&bvec, page[i], bytes, offset);
 		iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size);
 
--- linux-qcom-6.8.0.orig/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ linux-qcom-6.8.0/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -184,8 +184,12 @@
 
 	ppriv = ipoib_priv(pdev);
 
-	snprintf(intf_name, sizeof(intf_name), "%s.%04x",
-		 ppriv->dev->name, pkey);
+	/* If you increase IFNAMSIZ, update snprintf below
+	 * to allow longer names.
+	 */
+	BUILD_BUG_ON(IFNAMSIZ != 16);
+	snprintf(intf_name, sizeof(intf_name), "%.10s.%04x", ppriv->dev->name,
+		 pkey);
 
 	ndev = ipoib_intf_alloc(ppriv->ca, ppriv->port, intf_name);
 	if (IS_ERR(ndev)) {
--- linux-qcom-6.8.0.orig/drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c
+++ linux-qcom-6.8.0/drivers/infiniband/ulp/rtrs/rtrs-clt-sysfs.c
@@ -133,7 +133,7 @@
 
 	/* distinguish "mi" and "min-latency" with length */
 	len = strnlen(buf, NAME_MAX);
-	if (buf[len - 1] == '\n')
+	if (len && buf[len - 1] == '\n')
 		len--;
 
 	if (!strncasecmp(buf, "round-robin", 11) ||
--- linux-qcom-6.8.0.orig/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+++ linux-qcom-6.8.0/drivers/infiniband/ulp/rtrs/rtrs-clt.c
@@ -626,6 +626,7 @@
 		 */
 		if (WARN_ON(wc->wr_cqe->done != rtrs_clt_rdma_done))
 			return;
+		clt_path->s.hb_missed_cnt = 0;
 		rtrs_from_imm(be32_to_cpu(wc->ex.imm_data),
 			       &imm_type, &imm_payload);
 		if (imm_type == RTRS_IO_RSP_IMM ||
@@ -643,7 +644,6 @@
 				return  rtrs_clt_recv_done(con, wc);
 		} else if (imm_type == RTRS_HB_ACK_IMM) {
 			WARN_ON(con->c.cid);
-			clt_path->s.hb_missed_cnt = 0;
 			clt_path->s.hb_cur_latency =
 				ktime_sub(ktime_get(), clt_path->s.hb_last_sent);
 			if (clt_path->flags & RTRS_MSG_NEW_RKEY_F)
@@ -670,6 +670,7 @@
 		/*
 		 * Key invalidations from server side
 		 */
+		clt_path->s.hb_missed_cnt = 0;
 		WARN_ON(!(wc->wc_flags & IB_WC_WITH_INVALIDATE ||
 			  wc->wc_flags & IB_WC_WITH_IMM));
 		WARN_ON(wc->wr_cqe->done != rtrs_clt_rdma_done);
@@ -2346,6 +2347,12 @@
 		if (err)
 			goto destroy;
 	}
+
+	/*
+	 * Set the cid to con_num - 1, since if we fail later, we want to stay in bounds.
+	 */
+	cid = clt_path->s.con_num - 1;
+
 	err = alloc_path_reqs(clt_path);
 	if (err)
 		goto destroy;
--- linux-qcom-6.8.0.orig/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+++ linux-qcom-6.8.0/drivers/infiniband/ulp/rtrs/rtrs-srv.c
@@ -346,6 +346,7 @@
 	struct rtrs_srv_mr *srv_mr;
 	bool need_inval = false;
 	enum ib_send_flags flags;
+	struct ib_sge list;
 	u32 imm;
 	int err;
 
@@ -398,7 +399,6 @@
 	imm = rtrs_to_io_rsp_imm(id->msg_id, errno, need_inval);
 	imm_wr.wr.next = NULL;
 	if (always_invalidate) {
-		struct ib_sge list;
 		struct rtrs_msg_rkey_rsp *msg;
 
 		srv_mr = &srv_path->mrs[id->msg_id];
@@ -931,12 +931,11 @@
 	if (err)
 		goto close;
 
-out:
 	rtrs_iu_free(iu, srv_path->s.dev->ib_dev, 1);
 	return;
 close:
+	rtrs_iu_free(iu, srv_path->s.dev->ib_dev, 1);
 	close_path(srv_path);
-	goto out;
 }
 
 static int post_recv_info_req(struct rtrs_srv_con *con)
@@ -987,6 +986,16 @@
 			q_size = SERVICE_CON_QUEUE_DEPTH;
 		else
 			q_size = srv->queue_depth;
+		if (srv_path->state != RTRS_SRV_CONNECTING) {
+			rtrs_err(s, "Path state invalid. state %s\n",
+				 rtrs_srv_state_str(srv_path->state));
+			return -EIO;
+		}
+
+		if (!srv_path->s.con[cid]) {
+			rtrs_err(s, "Conn not set for %d\n", cid);
+			return -EIO;
+		}
 
 		err = post_recv_io(to_srv_con(srv_path->s.con[cid]), q_size);
 		if (err) {
@@ -1229,6 +1238,7 @@
 		 */
 		if (WARN_ON(wc->wr_cqe != &io_comp_cqe))
 			return;
+		srv_path->s.hb_missed_cnt = 0;
 		err = rtrs_post_recv_empty(&con->c, &io_comp_cqe);
 		if (err) {
 			rtrs_err(s, "rtrs_post_recv(), err: %d\n", err);
--- linux-qcom-6.8.0.orig/drivers/infiniband/ulp/srp/ib_srp.c
+++ linux-qcom-6.8.0/drivers/infiniband/ulp/srp/ib_srp.c
@@ -3978,7 +3978,6 @@
 	return host;
 
 put_host:
-	device_del(&host->dev);
 	put_device(&host->dev);
 	return NULL;
 }
--- linux-qcom-6.8.0.orig/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ linux-qcom-6.8.0/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -68,6 +68,8 @@
 static u64 srpt_service_guid;
 static DEFINE_SPINLOCK(srpt_dev_lock);	/* Protects srpt_dev_list. */
 static LIST_HEAD(srpt_dev_list);	/* List of srpt_device structures. */
+static DEFINE_MUTEX(srpt_mc_mutex);	/* Protects srpt_memory_caches. */
+static DEFINE_XARRAY(srpt_memory_caches); /* See also srpt_memory_cache_entry */
 
 static unsigned srp_max_req_size = DEFAULT_MAX_REQ_SIZE;
 module_param(srp_max_req_size, int, 0444);
@@ -105,6 +107,63 @@
 static void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc);
 static void srpt_process_wait_list(struct srpt_rdma_ch *ch);
 
+/* Type of the entries in srpt_memory_caches. */
+struct srpt_memory_cache_entry {
+	refcount_t ref;
+	struct kmem_cache *c;
+};
+
+static struct kmem_cache *srpt_cache_get(unsigned int object_size)
+{
+	struct srpt_memory_cache_entry *e;
+	char name[32];
+	void *res;
+
+	guard(mutex)(&srpt_mc_mutex);
+	e = xa_load(&srpt_memory_caches, object_size);
+	if (e) {
+		refcount_inc(&e->ref);
+		return e->c;
+	}
+	snprintf(name, sizeof(name), "srpt-%u", object_size);
+	e = kmalloc(sizeof(*e), GFP_KERNEL);
+	if (!e)
+		return NULL;
+	refcount_set(&e->ref, 1);
+	e->c = kmem_cache_create(name, object_size, /*align=*/512, 0, NULL);
+	if (!e->c)
+		goto free_entry;
+	res = xa_store(&srpt_memory_caches, object_size, e, GFP_KERNEL);
+	if (xa_is_err(res))
+		goto destroy_cache;
+	return e->c;
+
+destroy_cache:
+	kmem_cache_destroy(e->c);
+
+free_entry:
+	kfree(e);
+	return NULL;
+}
+
+static void srpt_cache_put(struct kmem_cache *c)
+{
+	struct srpt_memory_cache_entry *e = NULL;
+	unsigned long object_size;
+
+	guard(mutex)(&srpt_mc_mutex);
+	xa_for_each(&srpt_memory_caches, object_size, e)
+		if (e->c == c)
+			break;
+	if (WARN_ON_ONCE(!e))
+		return;
+	if (!refcount_dec_and_test(&e->ref))
+		return;
+	WARN_ON_ONCE(xa_erase(&srpt_memory_caches, object_size) != e);
+	kmem_cache_destroy(e->c);
+	kfree(e);
+}
+
 /*
  * The only allowed channel state changes are those that change the channel
  * state into a state with a higher numerical value. Hence the new > prev test.
@@ -2119,13 +2178,13 @@
 			     ch->sport->sdev, ch->rq_size,
 			     ch->rsp_buf_cache, DMA_TO_DEVICE);
 
-	kmem_cache_destroy(ch->rsp_buf_cache);
+	srpt_cache_put(ch->rsp_buf_cache);
 
 	srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_recv_ring,
 			     sdev, ch->rq_size,
 			     ch->req_buf_cache, DMA_FROM_DEVICE);
 
-	kmem_cache_destroy(ch->req_buf_cache);
+	srpt_cache_put(ch->req_buf_cache);
 
 	kref_put(&ch->kref, srpt_free_ch);
 }
@@ -2245,8 +2304,7 @@
 	INIT_LIST_HEAD(&ch->cmd_wait_list);
 	ch->max_rsp_size = ch->sport->port_attrib.srp_max_rsp_size;
 
-	ch->rsp_buf_cache = kmem_cache_create("srpt-rsp-buf", ch->max_rsp_size,
-					      512, 0, NULL);
+	ch->rsp_buf_cache = srpt_cache_get(ch->max_rsp_size);
 	if (!ch->rsp_buf_cache)
 		goto free_ch;
 
@@ -2280,8 +2338,7 @@
 		alignment_offset = round_up(imm_data_offset, 512) -
 			imm_data_offset;
 		req_sz = alignment_offset + imm_data_offset + srp_max_req_size;
-		ch->req_buf_cache = kmem_cache_create("srpt-req-buf", req_sz,
-						      512, 0, NULL);
+		ch->req_buf_cache = srpt_cache_get(req_sz);
 		if (!ch->req_buf_cache)
 			goto free_rsp_ring;
 
@@ -2478,7 +2535,7 @@
 			     ch->req_buf_cache, DMA_FROM_DEVICE);
 
 free_recv_cache:
-	kmem_cache_destroy(ch->req_buf_cache);
+	srpt_cache_put(ch->req_buf_cache);
 
 free_rsp_ring:
 	srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring,
@@ -2486,7 +2543,7 @@
 			     ch->rsp_buf_cache, DMA_TO_DEVICE);
 
 free_rsp_cache:
-	kmem_cache_destroy(ch->rsp_buf_cache);
+	srpt_cache_put(ch->rsp_buf_cache);
 
 free_ch:
 	if (rdma_cm_id)
@@ -3055,7 +3112,7 @@
 	srpt_free_ioctx_ring((struct srpt_ioctx **)sdev->ioctx_ring, sdev,
 			     sdev->srq_size, sdev->req_buf_cache,
 			     DMA_FROM_DEVICE);
-	kmem_cache_destroy(sdev->req_buf_cache);
+	srpt_cache_put(sdev->req_buf_cache);
 	sdev->srq = NULL;
 }
 
@@ -3082,8 +3139,7 @@
 	pr_debug("create SRQ #wr= %d max_allow=%d dev= %s\n", sdev->srq_size,
 		 sdev->device->attrs.max_srq_wr, dev_name(&device->dev));
 
-	sdev->req_buf_cache = kmem_cache_create("srpt-srq-req-buf",
-						srp_max_req_size, 0, 0, NULL);
+	sdev->req_buf_cache = srpt_cache_get(srp_max_req_size);
 	if (!sdev->req_buf_cache)
 		goto free_srq;
 
@@ -3105,7 +3161,7 @@
 	return 0;
 
 free_cache:
-	kmem_cache_destroy(sdev->req_buf_cache);
+	srpt_cache_put(sdev->req_buf_cache);
 
 free_srq:
 	ib_destroy_srq(srq);
@@ -3209,7 +3265,6 @@
 
 	INIT_IB_EVENT_HANDLER(&sdev->event_handler, sdev->device,
 			      srpt_event_handler);
-	ib_register_event_handler(&sdev->event_handler);
 
 	for (i = 1; i <= sdev->device->phys_port_cnt; i++) {
 		sport = &sdev->port[i - 1];
@@ -3232,6 +3287,7 @@
 		}
 	}
 
+	ib_register_event_handler(&sdev->event_handler);
 	spin_lock(&srpt_dev_lock);
 	list_add_tail(&sdev->list, &srpt_dev_list);
 	spin_unlock(&srpt_dev_lock);
@@ -3242,7 +3298,6 @@
 
 err_port:
 	srpt_unregister_mad_agent(sdev, i);
-	ib_unregister_event_handler(&sdev->event_handler);
 err_cm:
 	if (sdev->cm_id)
 		ib_destroy_cm_id(sdev->cm_id);
--- linux-qcom-6.8.0.orig/drivers/input/ff-core.c
+++ linux-qcom-6.8.0/drivers/input/ff-core.c
@@ -9,8 +9,10 @@
 /* #define DEBUG */
 
 #include <linux/input.h>
+#include <linux/limits.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/overflow.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 
@@ -315,9 +317,8 @@
 		return -EINVAL;
 	}
 
-	ff_dev_size = sizeof(struct ff_device) +
-				max_effects * sizeof(struct file *);
-	if (ff_dev_size < max_effects) /* overflow */
+	ff_dev_size = struct_size(ff, effect_owners, max_effects);
+	if (ff_dev_size == SIZE_MAX) /* overflow */
 		return -EINVAL;
 
 	ff = kzalloc(ff_dev_size, GFP_KERNEL);
--- linux-qcom-6.8.0.orig/drivers/input/input-mt.c
+++ linux-qcom-6.8.0/drivers/input/input-mt.c
@@ -46,6 +46,9 @@
 		return 0;
 	if (mt)
 		return mt->num_slots != num_slots ? -EINVAL : 0;
+	/* Arbitrary limit for avoiding too large memory allocation. */
+	if (num_slots > 1024)
+		return -EINVAL;
 
 	mt = kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL);
 	if (!mt)
--- linux-qcom-6.8.0.orig/drivers/input/input.c
+++ linux-qcom-6.8.0/drivers/input/input.c
@@ -1378,19 +1378,19 @@
 				     char name, const unsigned long *bm,
 				     unsigned int min_bit, unsigned int max_bit)
 {
-	int len = 0, i;
+	int bit = min_bit;
+	int len = 0;
 
 	len += snprintf(buf, max(size, 0), "%c", name);
-	for (i = min_bit; i < max_bit; i++)
-		if (bm[BIT_WORD(i)] & BIT_MASK(i))
-			len += snprintf(buf + len, max(size - len, 0), "%X,", i);
+	for_each_set_bit_from(bit, bm, max_bit)
+		len += snprintf(buf + len, max(size - len, 0), "%X,", bit);
 	return len;
 }
 
-static int input_print_modalias(char *buf, int size, const struct input_dev *id,
-				int add_cr)
+static int input_print_modalias_parts(char *buf, int size, int full_len,
+				      const struct input_dev *id)
 {
-	int len;
+	int len, klen, remainder, space;
 
 	len = snprintf(buf, max(size, 0),
 		       "input:b%04Xv%04Xp%04Xe%04X-",
@@ -1399,8 +1399,48 @@
 
 	len += input_print_modalias_bits(buf + len, size - len,
 				'e', id->evbit, 0, EV_MAX);
-	len += input_print_modalias_bits(buf + len, size - len,
+
+	/*
+	 * Calculate the remaining space in the buffer making sure we
+	 * have place for the terminating 0.
+	 */
+	space = max(size - (len + 1), 0);
+
+	klen = input_print_modalias_bits(buf + len, size - len,
 				'k', id->keybit, KEY_MIN_INTERESTING, KEY_MAX);
+	len += klen;
+
+	/*
+	 * If we have more data than we can fit in the buffer, check
+	 * if we can trim key data to fit in the rest. We will indicate
+	 * that key data is incomplete by adding "+" sign at the end, like
+	 * this: * "k1,2,3,45,+,".
+	 *
+	 * Note that we shortest key info (if present) is "k+," so we
+	 * can only try to trim if key data is longer than that.
+	 */
+	if (full_len && size < full_len + 1 && klen > 3) {
+		remainder = full_len - len;
+		/*
+		 * We can only trim if we have space for the remainder
+		 * and also for at least "k+," which is 3 more characters.
+		 */
+		if (remainder <= space - 3) {
+			/*
+			 * We are guaranteed to have 'k' in the buffer, so
+			 * we need at least 3 additional bytes for storing
+			 * "+," in addition to the remainder.
+			 */
+			for (int i = size - 1 - remainder - 3; i >= 0; i--) {
+				if (buf[i] == 'k' || buf[i] == ',') {
+					strcpy(buf + i + 1, "+,");
+					len = i + 3; /* Not counting '\0' */
+					break;
+				}
+			}
+		}
+	}
+
 	len += input_print_modalias_bits(buf + len, size - len,
 				'r', id->relbit, 0, REL_MAX);
 	len += input_print_modalias_bits(buf + len, size - len,
@@ -1416,12 +1456,25 @@
 	len += input_print_modalias_bits(buf + len, size - len,
 				'w', id->swbit, 0, SW_MAX);
 
-	if (add_cr)
-		len += snprintf(buf + len, max(size - len, 0), "\n");
-
 	return len;
 }
 
+static int input_print_modalias(char *buf, int size, const struct input_dev *id)
+{
+	int full_len;
+
+	/*
+	 * Printing is done in 2 passes: first one figures out total length
+	 * needed for the modalias string, second one will try to trim key
+	 * data in case when buffer is too small for the entire modalias.
+	 * If the buffer is too small regardless, it will fill as much as it
+	 * can (without trimming key data) into the buffer and leave it to
+	 * the caller to figure out what to do with the result.
+	 */
+	full_len = input_print_modalias_parts(NULL, 0, 0, id);
+	return input_print_modalias_parts(buf, size, full_len, id);
+}
+
 static ssize_t input_dev_show_modalias(struct device *dev,
 				       struct device_attribute *attr,
 				       char *buf)
@@ -1429,7 +1482,9 @@
 	struct input_dev *id = to_input_dev(dev);
 	ssize_t len;
 
-	len = input_print_modalias(buf, PAGE_SIZE, id, 1);
+	len = input_print_modalias(buf, PAGE_SIZE, id);
+	if (len < PAGE_SIZE - 2)
+		len += snprintf(buf + len, PAGE_SIZE - len, "\n");
 
 	return min_t(int, len, PAGE_SIZE);
 }
@@ -1641,6 +1696,23 @@
 	return 0;
 }
 
+/*
+ * This is a pretty gross hack. When building uevent data the driver core
+ * may try adding more environment variables to kobj_uevent_env without
+ * telling us, so we have no idea how much of the buffer we can use to
+ * avoid overflows/-ENOMEM elsewhere. To work around this let's artificially
+ * reduce amount of memory we will use for the modalias environment variable.
+ *
+ * The potential additions are:
+ *
+ * SEQNUM=18446744073709551615 - (%llu - 28 bytes)
+ * HOME=/ (6 bytes)
+ * PATH=/sbin:/bin:/usr/sbin:/usr/bin (34 bytes)
+ *
+ * 68 bytes total. Allow extra buffer - 96 bytes
+ */
+#define UEVENT_ENV_EXTRA_LEN	96
+
 static int input_add_uevent_modalias_var(struct kobj_uevent_env *env,
 					 const struct input_dev *dev)
 {
@@ -1650,9 +1722,11 @@
 		return -ENOMEM;
 
 	len = input_print_modalias(&env->buf[env->buflen - 1],
-				   sizeof(env->buf) - env->buflen,
-				   dev, 0);
-	if (len >= (sizeof(env->buf) - env->buflen))
+				   (int)sizeof(env->buf) - env->buflen -
+					UEVENT_ENV_EXTRA_LEN,
+				   dev);
+	if (len >= ((int)sizeof(env->buf) - env->buflen -
+					UEVENT_ENV_EXTRA_LEN))
 		return -ENOMEM;
 
 	env->buflen += len;
--- linux-qcom-6.8.0.orig/drivers/input/joystick/xpad.c
+++ linux-qcom-6.8.0/drivers/input/joystick/xpad.c
@@ -127,6 +127,7 @@
 	u8 mapping;
 	u8 xtype;
 } xpad_device[] = {
+	/* Please keep this list sorted by vendor and product ID. */
 	{ 0x0079, 0x18d4, "GPD Win 2 X-Box Controller", 0, XTYPE_XBOX360 },
 	{ 0x03eb, 0xff01, "Wooting One (Legacy)", 0, XTYPE_XBOX360 },
 	{ 0x03eb, 0xff02, "Wooting Two (Legacy)", 0, XTYPE_XBOX360 },
@@ -149,12 +150,13 @@
 	{ 0x045e, 0x028e, "Microsoft X-Box 360 pad", 0, XTYPE_XBOX360 },
 	{ 0x045e, 0x028f, "Microsoft X-Box 360 pad v2", 0, XTYPE_XBOX360 },
 	{ 0x045e, 0x0291, "Xbox 360 Wireless Receiver (XBOX)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
+	{ 0x045e, 0x02a9, "Xbox 360 Wireless Receiver (Unofficial)", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
 	{ 0x045e, 0x02d1, "Microsoft X-Box One pad", 0, XTYPE_XBOXONE },
 	{ 0x045e, 0x02dd, "Microsoft X-Box One pad (Firmware 2015)", 0, XTYPE_XBOXONE },
 	{ 0x045e, 0x02e3, "Microsoft X-Box One Elite pad", MAP_PADDLES, XTYPE_XBOXONE },
-	{ 0x045e, 0x0b00, "Microsoft X-Box One Elite 2 pad", MAP_PADDLES, XTYPE_XBOXONE },
 	{ 0x045e, 0x02ea, "Microsoft X-Box One S pad", 0, XTYPE_XBOXONE },
 	{ 0x045e, 0x0719, "Xbox 360 Wireless Receiver", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360W },
+	{ 0x045e, 0x0b00, "Microsoft X-Box One Elite 2 pad", MAP_PADDLES, XTYPE_XBOXONE },
 	{ 0x045e, 0x0b0a, "Microsoft X-Box Adaptive Controller", MAP_PROFILE_BUTTON, XTYPE_XBOXONE },
 	{ 0x045e, 0x0b12, "Microsoft Xbox Series S|X Controller", MAP_SELECT_BUTTON, XTYPE_XBOXONE },
 	{ 0x046d, 0xc21d, "Logitech Gamepad F310", 0, XTYPE_XBOX360 },
@@ -207,6 +209,8 @@
 	{ 0x0738, 0xcb29, "Saitek Aviator Stick AV8R02", 0, XTYPE_XBOX360 },
 	{ 0x0738, 0xf738, "Super SFIV FightStick TE S", 0, XTYPE_XBOX360 },
 	{ 0x07ff, 0xffff, "Mad Catz GamePad", 0, XTYPE_XBOX360 },
+	{ 0x0b05, 0x1a38, "ASUS ROG RAIKIRI", 0, XTYPE_XBOXONE },
+	{ 0x0b05, 0x1abb, "ASUS ROG RAIKIRI PRO", 0, XTYPE_XBOXONE },
 	{ 0x0c12, 0x0005, "Intec wireless", 0, XTYPE_XBOX },
 	{ 0x0c12, 0x8801, "Nyko Xbox Controller", 0, XTYPE_XBOX },
 	{ 0x0c12, 0x8802, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
@@ -215,6 +219,7 @@
 	{ 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
 	{ 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX },
 	{ 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
+	{ 0x0db0, 0x1901, "Micro Star International Xbox360 Controller for Windows", 0, XTYPE_XBOX360 },
 	{ 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX },
 	{ 0x0e4c, 0x1103, "Radica Gamester Reflex", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX },
 	{ 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX },
@@ -301,6 +306,7 @@
 	{ 0x1689, 0xfe00, "Razer Sabertooth", 0, XTYPE_XBOX360 },
 	{ 0x17ef, 0x6182, "Lenovo Legion Controller for Windows", 0, XTYPE_XBOX360 },
 	{ 0x1949, 0x041a, "Amazon Game Controller", 0, XTYPE_XBOX360 },
+	{ 0x1a86, 0xe310, "QH Electronics Controller", 0, XTYPE_XBOX360 },
 	{ 0x1bad, 0x0002, "Harmonix Rock Band Guitar", 0, XTYPE_XBOX360 },
 	{ 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
 	{ 0x1bad, 0x0130, "Ion Drum Rocker", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 },
@@ -340,7 +346,6 @@
 	{ 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, XTYPE_XBOXONE },
 	{ 0x20d6, 0x2009, "PowerA Enhanced Wired Controller for Xbox Series X|S", 0, XTYPE_XBOXONE },
 	{ 0x20d6, 0x281f, "PowerA Wired Controller For Xbox 360", 0, XTYPE_XBOX360 },
-	{ 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE },
 	{ 0x24c6, 0x5000, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
 	{ 0x24c6, 0x5300, "PowerA MINI PROEX Controller", 0, XTYPE_XBOX360 },
 	{ 0x24c6, 0x5303, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 },
@@ -355,9 +360,9 @@
 	{ 0x24c6, 0x5502, "Hori Fighting Stick VX Alt", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
 	{ 0x24c6, 0x5503, "Hori Fighting Edge", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
 	{ 0x24c6, 0x5506, "Hori SOULCALIBUR V Stick", 0, XTYPE_XBOX360 },
-	{ 0x24c6, 0x5510, "Hori Fighting Commander ONE (Xbox 360/PC Mode)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
 	{ 0x24c6, 0x550d, "Hori GEM Xbox controller", 0, XTYPE_XBOX360 },
 	{ 0x24c6, 0x550e, "Hori Real Arcade Pro V Kai 360", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
+	{ 0x24c6, 0x5510, "Hori Fighting Commander ONE (Xbox 360/PC Mode)", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 },
 	{ 0x24c6, 0x551a, "PowerA FUSION Pro Controller", 0, XTYPE_XBOXONE },
 	{ 0x24c6, 0x561a, "PowerA FUSION Controller", 0, XTYPE_XBOXONE },
 	{ 0x24c6, 0x5b00, "ThrustMaster Ferrari 458 Racing Wheel", 0, XTYPE_XBOX360 },
@@ -366,15 +371,22 @@
 	{ 0x24c6, 0x5d04, "Razer Sabertooth", 0, XTYPE_XBOX360 },
 	{ 0x24c6, 0xfafe, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
 	{ 0x2563, 0x058d, "OneXPlayer Gamepad", 0, XTYPE_XBOX360 },
+	{ 0x294b, 0x3303, "Snakebyte GAMEPAD BASE X", 0, XTYPE_XBOXONE },
+	{ 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE },
 	{ 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE },
-	{ 0x2dc8, 0x3106, "8BitDo Pro 2 Wired Controller", 0, XTYPE_XBOX360 },
+	{ 0x2dc8, 0x3106, "8BitDo Ultimate Wireless / Pro 2 Wired Controller", 0, XTYPE_XBOX360 },
+	{ 0x2dc8, 0x310a, "8BitDo Ultimate 2C Wireless Controller", 0, XTYPE_XBOX360 },
+	{ 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE },
 	{ 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 },
 	{ 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 },
 	{ 0x31e3, 0x1210, "Wooting Lekker", 0, XTYPE_XBOX360 },
 	{ 0x31e3, 0x1220, "Wooting Two HE", 0, XTYPE_XBOX360 },
+	{ 0x31e3, 0x1230, "Wooting Two HE (ARM)", 0, XTYPE_XBOX360 },
 	{ 0x31e3, 0x1300, "Wooting 60HE (AVR)", 0, XTYPE_XBOX360 },
 	{ 0x31e3, 0x1310, "Wooting 60HE (ARM)", 0, XTYPE_XBOX360 },
 	{ 0x3285, 0x0607, "Nacon GC-100", 0, XTYPE_XBOX360 },
+	{ 0x3285, 0x0646, "Nacon Pro Compact", 0, XTYPE_XBOXONE },
+	{ 0x3285, 0x0663, "Nacon Evol-X", 0, XTYPE_XBOXONE },
 	{ 0x3537, 0x1004, "GameSir T4 Kaleid", 0, XTYPE_XBOX360 },
 	{ 0x3767, 0x0101, "Fanatec Speedster 3 Forceshock Wheel", 0, XTYPE_XBOX },
 	{ 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX },
@@ -465,6 +477,10 @@
 	{ XPAD_XBOXONE_VENDOR_PROTOCOL((vend), 208) }
 
 static const struct usb_device_id xpad_table[] = {
+	/*
+	 * Please keep this list sorted by vendor ID. Note that there are 2
+	 * macros - XPAD_XBOX360_VENDOR and XPAD_XBOXONE_VENDOR.
+	 */
 	{ USB_INTERFACE_INFO('X', 'B', 0) },	/* Xbox USB-IF not-approved class */
 	XPAD_XBOX360_VENDOR(0x0079),		/* GPD Win 2 controller */
 	XPAD_XBOX360_VENDOR(0x03eb),		/* Wooting Keyboards (Legacy) */
@@ -480,7 +496,9 @@
 	{ USB_DEVICE(0x0738, 0x4540) },		/* Mad Catz Beat Pad */
 	XPAD_XBOXONE_VENDOR(0x0738),		/* Mad Catz FightStick TE 2 */
 	XPAD_XBOX360_VENDOR(0x07ff),		/* Mad Catz Gamepad */
+	XPAD_XBOXONE_VENDOR(0x0b05),		/* ASUS controllers */
 	XPAD_XBOX360_VENDOR(0x0c12),		/* Zeroplus X-Box 360 controllers */
+	XPAD_XBOX360_VENDOR(0x0db0),		/* Micro Star International X-Box 360 controllers */
 	XPAD_XBOX360_VENDOR(0x0e6f),		/* 0x0e6f Xbox 360 controllers */
 	XPAD_XBOXONE_VENDOR(0x0e6f),		/* 0x0e6f Xbox One controllers */
 	XPAD_XBOX360_VENDOR(0x0f0d),		/* Hori controllers */
@@ -500,6 +518,7 @@
 	XPAD_XBOX360_VENDOR(0x1689),		/* Razer Onza */
 	XPAD_XBOX360_VENDOR(0x17ef),		/* Lenovo */
 	XPAD_XBOX360_VENDOR(0x1949),		/* Amazon controllers */
+	XPAD_XBOX360_VENDOR(0x1a86),		/* QH Electronics */
 	XPAD_XBOX360_VENDOR(0x1bad),		/* Harmonix Rock Band guitar and drums */
 	XPAD_XBOX360_VENDOR(0x20d6),		/* PowerA controllers */
 	XPAD_XBOXONE_VENDOR(0x20d6),		/* PowerA controllers */
@@ -507,6 +526,7 @@
 	XPAD_XBOXONE_VENDOR(0x24c6),		/* PowerA controllers */
 	XPAD_XBOX360_VENDOR(0x2563),		/* OneXPlayer Gamepad */
 	XPAD_XBOX360_VENDOR(0x260d),		/* Dareu H101 */
+       XPAD_XBOXONE_VENDOR(0x294b),            /* Snakebyte */
 	XPAD_XBOX360_VENDOR(0x2c22),		/* Qanba Controllers */
 	XPAD_XBOX360_VENDOR(0x2dc8),            /* 8BitDo Pro 2 Wired Controller */
 	XPAD_XBOXONE_VENDOR(0x2dc8),		/* 8BitDo Pro 2 Wired Controller for Xbox */
@@ -514,6 +534,7 @@
 	XPAD_XBOX360_VENDOR(0x2f24),		/* GameSir controllers */
 	XPAD_XBOX360_VENDOR(0x31e3),		/* Wooting Keyboards */
 	XPAD_XBOX360_VENDOR(0x3285),		/* Nacon GC-100 */
+	XPAD_XBOXONE_VENDOR(0x3285),		/* Nacon Evol-X */
 	XPAD_XBOX360_VENDOR(0x3537),		/* GameSir Controllers */
 	XPAD_XBOXONE_VENDOR(0x3537),		/* GameSir Controllers */
 	{ }
--- linux-qcom-6.8.0.orig/drivers/input/keyboard/adp5588-keys.c
+++ linux-qcom-6.8.0/drivers/input/keyboard/adp5588-keys.c
@@ -627,7 +627,7 @@
 
 	for (i = 0; i < KEYP_MAX_EVENT; i++) {
 		ret = adp5588_read(client, KEY_EVENTA);
-		if (ret)
+		if (ret < 0)
 			return ret;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/input/keyboard/adp5589-keys.c
+++ linux-qcom-6.8.0/drivers/input/keyboard/adp5589-keys.c
@@ -391,10 +391,17 @@
 	struct adp5589_kpad *kpad = gpiochip_get_data(chip);
 	unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
 	unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
+	int val;
 
-	return !!(adp5589_read(kpad->client,
-			       kpad->var->reg(ADP5589_GPI_STATUS_A) + bank) &
-			       bit);
+	mutex_lock(&kpad->gpio_lock);
+	if (kpad->dir[bank] & bit)
+		val = kpad->dat_out[bank];
+	else
+		val = adp5589_read(kpad->client,
+				   kpad->var->reg(ADP5589_GPI_STATUS_A) + bank);
+	mutex_unlock(&kpad->gpio_lock);
+
+	return !!(val & bit);
 }
 
 static void adp5589_gpio_set_value(struct gpio_chip *chip,
@@ -936,10 +943,9 @@
 
 static void adp5589_clear_config(void *data)
 {
-	struct i2c_client *client = data;
-	struct adp5589_kpad *kpad = i2c_get_clientdata(client);
+	struct adp5589_kpad *kpad = data;
 
-	adp5589_write(client, kpad->var->reg(ADP5589_GENERAL_CFG), 0);
+	adp5589_write(kpad->client, kpad->var->reg(ADP5589_GENERAL_CFG), 0);
 }
 
 static int adp5589_probe(struct i2c_client *client)
@@ -983,7 +989,7 @@
 	}
 
 	error = devm_add_action_or_reset(&client->dev, adp5589_clear_config,
-					 client);
+					 kpad);
 	if (error)
 		return error;
 
@@ -1010,8 +1016,6 @@
 	if (error)
 		return error;
 
-	i2c_set_clientdata(client, kpad);
-
 	dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/input/keyboard/atkbd.c
+++ linux-qcom-6.8.0/drivers/input/keyboard/atkbd.c
@@ -89,7 +89,7 @@
 	  0, 46, 45, 32, 18,  5,  4, 95,  0, 57, 47, 33, 20, 19,  6,183,
 	  0, 49, 48, 35, 34, 21,  7,184,  0,  0, 50, 36, 22,  8,  9,185,
 	  0, 51, 37, 23, 24, 11, 10,  0,  0, 52, 53, 38, 39, 25, 12,  0,
-	  0, 89, 40,  0, 26, 13,  0,  0, 58, 54, 28, 27,  0, 43,  0, 85,
+	  0, 89, 40,  0, 26, 13,  0,193, 58, 54, 28, 27,  0, 43,  0, 85,
 	  0, 86, 91, 90, 92,  0, 14, 94,  0, 79,124, 75, 71,121,  0,  0,
 	 82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99,
 
--- linux-qcom-6.8.0.orig/drivers/input/keyboard/qt1050.c
+++ linux-qcom-6.8.0/drivers/input/keyboard/qt1050.c
@@ -226,7 +226,12 @@
 	int err;
 
 	/* Read Chip ID */
-	regmap_read(ts->regmap, QT1050_CHIP_ID, &val);
+	err = regmap_read(ts->regmap, QT1050_CHIP_ID, &val);
+	if (err) {
+		dev_err(&ts->client->dev, "Failed to read chip ID: %d\n", err);
+		return false;
+	}
+
 	if (val != QT1050_CHIP_ID_VER) {
 		dev_err(&ts->client->dev, "ID %d not supported\n", val);
 		return false;
--- linux-qcom-6.8.0.orig/drivers/input/misc/ims-pcu.c
+++ linux-qcom-6.8.0/drivers/input/misc/ims-pcu.c
@@ -42,8 +42,8 @@
 #define IMS_PCU_PART_NUMBER_LEN		15
 #define IMS_PCU_SERIAL_NUMBER_LEN	8
 #define IMS_PCU_DOM_LEN			8
-#define IMS_PCU_FW_VERSION_LEN		(9 + 1)
-#define IMS_PCU_BL_VERSION_LEN		(9 + 1)
+#define IMS_PCU_FW_VERSION_LEN		16
+#define IMS_PCU_BL_VERSION_LEN		16
 #define IMS_PCU_BL_RESET_REASON_LEN	(2 + 1)
 
 #define IMS_PCU_PCU_B_DEVICE_ID		5
--- linux-qcom-6.8.0.orig/drivers/input/misc/iqs7222.c
+++ linux-qcom-6.8.0/drivers/input/misc/iqs7222.c
@@ -622,6 +622,118 @@
 	},
 	{
 		.prod_num = IQS7222_PROD_NUM_D,
+		.fw_major = 1,
+		.fw_minor = 2,
+		.touch_link = 1770,
+		.allow_offset = 9,
+		.event_offset = 10,
+		.comms_offset = 11,
+		.reg_grps = {
+			[IQS7222_REG_GRP_STAT] = {
+				.base = IQS7222_SYS_STATUS,
+				.num_row = 1,
+				.num_col = 7,
+			},
+			[IQS7222_REG_GRP_CYCLE] = {
+				.base = 0x8000,
+				.num_row = 7,
+				.num_col = 2,
+			},
+			[IQS7222_REG_GRP_GLBL] = {
+				.base = 0x8700,
+				.num_row = 1,
+				.num_col = 3,
+			},
+			[IQS7222_REG_GRP_BTN] = {
+				.base = 0x9000,
+				.num_row = 14,
+				.num_col = 3,
+			},
+			[IQS7222_REG_GRP_CHAN] = {
+				.base = 0xA000,
+				.num_row = 14,
+				.num_col = 4,
+			},
+			[IQS7222_REG_GRP_FILT] = {
+				.base = 0xAE00,
+				.num_row = 1,
+				.num_col = 2,
+			},
+			[IQS7222_REG_GRP_TPAD] = {
+				.base = 0xB000,
+				.num_row = 1,
+				.num_col = 24,
+			},
+			[IQS7222_REG_GRP_GPIO] = {
+				.base = 0xC000,
+				.num_row = 3,
+				.num_col = 3,
+			},
+			[IQS7222_REG_GRP_SYS] = {
+				.base = IQS7222_SYS_SETUP,
+				.num_row = 1,
+				.num_col = 12,
+			},
+		},
+	},
+	{
+		.prod_num = IQS7222_PROD_NUM_D,
+		.fw_major = 1,
+		.fw_minor = 1,
+		.touch_link = 1774,
+		.allow_offset = 9,
+		.event_offset = 10,
+		.comms_offset = 11,
+		.reg_grps = {
+			[IQS7222_REG_GRP_STAT] = {
+				.base = IQS7222_SYS_STATUS,
+				.num_row = 1,
+				.num_col = 7,
+			},
+			[IQS7222_REG_GRP_CYCLE] = {
+				.base = 0x8000,
+				.num_row = 7,
+				.num_col = 2,
+			},
+			[IQS7222_REG_GRP_GLBL] = {
+				.base = 0x8700,
+				.num_row = 1,
+				.num_col = 3,
+			},
+			[IQS7222_REG_GRP_BTN] = {
+				.base = 0x9000,
+				.num_row = 14,
+				.num_col = 3,
+			},
+			[IQS7222_REG_GRP_CHAN] = {
+				.base = 0xA000,
+				.num_row = 14,
+				.num_col = 4,
+			},
+			[IQS7222_REG_GRP_FILT] = {
+				.base = 0xAE00,
+				.num_row = 1,
+				.num_col = 2,
+			},
+			[IQS7222_REG_GRP_TPAD] = {
+				.base = 0xB000,
+				.num_row = 1,
+				.num_col = 24,
+			},
+			[IQS7222_REG_GRP_GPIO] = {
+				.base = 0xC000,
+				.num_row = 3,
+				.num_col = 3,
+			},
+			[IQS7222_REG_GRP_SYS] = {
+				.base = IQS7222_SYS_SETUP,
+				.num_row = 1,
+				.num_col = 12,
+			},
+		},
+	},
+	{
+		.prod_num = IQS7222_PROD_NUM_D,
 		.fw_major = 0,
 		.fw_minor = 37,
 		.touch_link = 1770,
--- linux-qcom-6.8.0.orig/drivers/input/misc/nxp-bbnsm-pwrkey.c
+++ linux-qcom-6.8.0/drivers/input/misc/nxp-bbnsm-pwrkey.c
@@ -173,6 +173,12 @@
 	return 0;
 }
 
+static void bbnsm_pwrkey_remove(struct platform_device *pdev)
+{
+	dev_pm_clear_wake_irq(&pdev->dev);
+	device_init_wakeup(&pdev->dev, false);
+}
+
 static const struct of_device_id bbnsm_pwrkey_ids[] = {
 	{ .compatible = "nxp,imx93-bbnsm-pwrkey" },
 	{ /* sentinel */ }
@@ -185,6 +191,8 @@
 		.of_match_table = bbnsm_pwrkey_ids,
 	},
 	.probe = bbnsm_pwrkey_probe,
+	.remove_new = bbnsm_pwrkey_remove,
+
 };
 module_platform_driver(bbnsm_pwrkey_driver);
 
--- linux-qcom-6.8.0.orig/drivers/input/misc/pm8xxx-vibrator.c
+++ linux-qcom-6.8.0/drivers/input/misc/pm8xxx-vibrator.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/errno.h>
@@ -11,36 +12,61 @@
 #include <linux/regmap.h>
 #include <linux/slab.h>
 
+#define SSBI_VIB_DRV_REG		0x4A
+#define SSBI_VIB_DRV_EN_MANUAL_MASK	GENMASK(7, 2)
+#define SSBI_VIB_DRV_LEVEL_MASK		GENMASK(7, 3)
+#define SSBI_VIB_DRV_SHIFT		3
+
+#define SPMI_VIB_DRV_REG		0x41
+#define SPMI_VIB_DRV_LEVEL_MASK		GENMASK(4, 0)
+#define SPMI_VIB_DRV_SHIFT		0
+
+#define SPMI_VIB_GEN2_DRV_REG		0x40
+#define SPMI_VIB_GEN2_DRV_MASK		GENMASK(7, 0)
+#define SPMI_VIB_GEN2_DRV_SHIFT		0
+#define SPMI_VIB_GEN2_DRV2_REG		0x41
+#define SPMI_VIB_GEN2_DRV2_MASK		GENMASK(3, 0)
+#define SPMI_VIB_GEN2_DRV2_SHIFT	8
+
+#define SPMI_VIB_EN_REG			0x46
+#define SPMI_VIB_EN_BIT			BIT(7)
+
 #define VIB_MAX_LEVEL_mV	(3100)
 #define VIB_MIN_LEVEL_mV	(1200)
-#define VIB_MAX_LEVELS		(VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV)
+#define VIB_PER_STEP_mV		(100)
+#define VIB_MAX_LEVELS		(VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV + VIB_PER_STEP_mV)
 
 #define MAX_FF_SPEED		0xff
 
-struct pm8xxx_regs {
-	unsigned int enable_addr;
-	unsigned int enable_mask;
-
-	unsigned int drv_addr;
-	unsigned int drv_mask;
-	unsigned int drv_shift;
-	unsigned int drv_en_manual_mask;
-};
-
-static const struct pm8xxx_regs pm8058_regs = {
-	.drv_addr = 0x4A,
-	.drv_mask = 0xf8,
-	.drv_shift = 3,
-	.drv_en_manual_mask = 0xfc,
-};
-
-static struct pm8xxx_regs pm8916_regs = {
-	.enable_addr = 0xc046,
-	.enable_mask = BIT(7),
-	.drv_addr = 0xc041,
-	.drv_mask = 0x1F,
-	.drv_shift = 0,
-	.drv_en_manual_mask = 0,
+enum vib_hw_type {
+	SSBI_VIB,
+	SPMI_VIB,
+	SPMI_VIB_GEN2
+};
+
+struct pm8xxx_vib_data {
+	enum vib_hw_type	hw_type;
+	unsigned int		enable_addr;
+	unsigned int		drv_addr;
+	unsigned int		drv2_addr;
+};
+
+static const struct pm8xxx_vib_data ssbi_vib_data = {
+	.hw_type	= SSBI_VIB,
+	.drv_addr	= SSBI_VIB_DRV_REG,
+};
+
+static const struct pm8xxx_vib_data spmi_vib_data = {
+	.hw_type	= SPMI_VIB,
+	.enable_addr	= SPMI_VIB_EN_REG,
+	.drv_addr	= SPMI_VIB_DRV_REG,
+};
+
+static const struct pm8xxx_vib_data spmi_vib_gen2_data = {
+	.hw_type	= SPMI_VIB_GEN2,
+	.enable_addr	= SPMI_VIB_EN_REG,
+	.drv_addr	= SPMI_VIB_GEN2_DRV_REG,
+	.drv2_addr	= SPMI_VIB_GEN2_DRV2_REG,
 };
 
 /**
@@ -48,7 +74,8 @@
  * @vib_input_dev: input device supporting force feedback
  * @work: work structure to set the vibration parameters
  * @regmap: regmap for register read/write
- * @regs: registers' info
+ * @data: vibrator HW info
+ * @reg_base: the register base of the module
  * @speed: speed of vibration set from userland
  * @active: state of vibrator
  * @level: level of vibration to set in the chip
@@ -58,7 +85,8 @@
 	struct input_dev *vib_input_dev;
 	struct work_struct work;
 	struct regmap *regmap;
-	const struct pm8xxx_regs *regs;
+	const struct pm8xxx_vib_data *data;
+	unsigned int reg_base;
 	int speed;
 	int level;
 	bool active;
@@ -74,24 +102,55 @@
 {
 	int rc;
 	unsigned int val = vib->reg_vib_drv;
-	const struct pm8xxx_regs *regs = vib->regs;
+	u32 mask, shift;
+
+	switch (vib->data->hw_type) {
+	case SSBI_VIB:
+		mask = SSBI_VIB_DRV_LEVEL_MASK;
+		shift = SSBI_VIB_DRV_SHIFT;
+		break;
+	case SPMI_VIB:
+		mask = SPMI_VIB_DRV_LEVEL_MASK;
+		shift = SPMI_VIB_DRV_SHIFT;
+		break;
+	case SPMI_VIB_GEN2:
+		mask = SPMI_VIB_GEN2_DRV_MASK;
+		shift = SPMI_VIB_GEN2_DRV_SHIFT;
+		break;
+	default:
+		return -EINVAL;
+	}
 
 	if (on)
-		val |= (vib->level << regs->drv_shift) & regs->drv_mask;
+		val |= (vib->level << shift) & mask;
 	else
-		val &= ~regs->drv_mask;
+		val &= ~mask;
 
-	rc = regmap_write(vib->regmap, regs->drv_addr, val);
+	rc = regmap_update_bits(vib->regmap, vib->reg_base + vib->data->drv_addr, mask, val);
 	if (rc < 0)
 		return rc;
 
 	vib->reg_vib_drv = val;
 
-	if (regs->enable_mask)
-		rc = regmap_update_bits(vib->regmap, regs->enable_addr,
-					regs->enable_mask, on ? ~0 : 0);
+	if (vib->data->hw_type == SPMI_VIB_GEN2) {
+		mask = SPMI_VIB_GEN2_DRV2_MASK;
+		shift = SPMI_VIB_GEN2_DRV2_SHIFT;
+		if (on)
+			val = (vib->level >> shift) & mask;
+		else
+			val = 0;
+		rc = regmap_update_bits(vib->regmap,
+				vib->reg_base + vib->data->drv2_addr, mask, val);
+		if (rc < 0)
+			return rc;
+	}
+
+	if (vib->data->hw_type == SSBI_VIB)
+		return 0;
 
-	return rc;
+	mask = SPMI_VIB_EN_BIT;
+	val = on ? SPMI_VIB_EN_BIT : 0;
+	return regmap_update_bits(vib->regmap, vib->reg_base + vib->data->enable_addr, mask, val);
 }
 
 /**
@@ -101,13 +160,6 @@
 static void pm8xxx_work_handler(struct work_struct *work)
 {
 	struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work);
-	const struct pm8xxx_regs *regs = vib->regs;
-	int rc;
-	unsigned int val;
-
-	rc = regmap_read(vib->regmap, regs->drv_addr, &val);
-	if (rc < 0)
-		return;
 
 	/*
 	 * pmic vibrator supports voltage ranges from 1.2 to 3.1V, so
@@ -117,10 +169,13 @@
 		vib->active = true;
 		vib->level = ((VIB_MAX_LEVELS * vib->speed) / MAX_FF_SPEED) +
 						VIB_MIN_LEVEL_mV;
-		vib->level /= 100;
+		if (vib->data->hw_type != SPMI_VIB_GEN2)
+			vib->level /= VIB_PER_STEP_mV;
 	} else {
 		vib->active = false;
-		vib->level = VIB_MIN_LEVEL_mV / 100;
+		vib->level = VIB_MIN_LEVEL_mV;
+		if (vib->data->hw_type != SPMI_VIB_GEN2)
+			vib->level /= VIB_PER_STEP_mV;
 	}
 
 	pm8xxx_vib_set(vib, vib->active);
@@ -167,9 +222,9 @@
 {
 	struct pm8xxx_vib *vib;
 	struct input_dev *input_dev;
+	const struct pm8xxx_vib_data *data;
 	int error;
-	unsigned int val;
-	const struct pm8xxx_regs *regs;
+	unsigned int val, reg_base;
 
 	vib = devm_kzalloc(&pdev->dev, sizeof(*vib), GFP_KERNEL);
 	if (!vib)
@@ -186,19 +241,33 @@
 	INIT_WORK(&vib->work, pm8xxx_work_handler);
 	vib->vib_input_dev = input_dev;
 
-	regs = of_device_get_match_data(&pdev->dev);
+	data = of_device_get_match_data(&pdev->dev);
+	if (!data)
+		return -EINVAL;
+
+	if (data->hw_type != SSBI_VIB) {
+		error = fwnode_property_read_u32(pdev->dev.fwnode, "reg", &reg_base);
+		if (error < 0) {
+			dev_err(&pdev->dev, "Failed to read reg address, rc=%d\n", error);
+			return error;
+		}
 
-	/* operate in manual mode */
-	error = regmap_read(vib->regmap, regs->drv_addr, &val);
-	if (error < 0)
-		return error;
+		vib->reg_base += reg_base;
+	}
 
-	val &= regs->drv_en_manual_mask;
-	error = regmap_write(vib->regmap, regs->drv_addr, val);
+	error = regmap_read(vib->regmap, vib->reg_base + data->drv_addr, &val);
 	if (error < 0)
 		return error;
 
-	vib->regs = regs;
+	/* operate in manual mode */
+	if (data->hw_type == SSBI_VIB) {
+		val &= SSBI_VIB_DRV_EN_MANUAL_MASK;
+		error = regmap_write(vib->regmap, vib->reg_base + data->drv_addr, val);
+		if (error < 0)
+			return error;
+	}
+
+	vib->data = data;
 	vib->reg_vib_drv = val;
 
 	input_dev->name = "pm8xxx_vib_ffmemless";
@@ -238,9 +307,10 @@
 static DEFINE_SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL);
 
 static const struct of_device_id pm8xxx_vib_id_table[] = {
-	{ .compatible = "qcom,pm8058-vib", .data = &pm8058_regs },
-	{ .compatible = "qcom,pm8921-vib", .data = &pm8058_regs },
-	{ .compatible = "qcom,pm8916-vib", .data = &pm8916_regs },
+	{ .compatible = "qcom,pm8058-vib", .data = &ssbi_vib_data },
+	{ .compatible = "qcom,pm8921-vib", .data = &ssbi_vib_data },
+	{ .compatible = "qcom,pm8916-vib", .data = &spmi_vib_data },
+	{ .compatible = "qcom,pmi632-vib", .data = &spmi_vib_gen2_data },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, pm8xxx_vib_id_table);
--- linux-qcom-6.8.0.orig/drivers/input/misc/uinput.c
+++ linux-qcom-6.8.0/drivers/input/misc/uinput.c
@@ -417,6 +417,20 @@
 		return -EINVAL;
 	}
 
+	/*
+	 * Limit number of contacts to a reasonable value (100). This
+	 * ensures that we need less than 2 pages for struct input_mt
+	 * (we are not using in-kernel slot assignment so not going to
+	 * allocate memory for the "red" table), and we should have no
+	 * trouble getting this much memory.
+	 */
+	if (code == ABS_MT_SLOT && max > 99) {
+		printk(KERN_DEBUG
+		       "%s: unreasonably large number of slots requested: %d\n",
+		       UINPUT_NAME, max);
+		return -EINVAL;
+	}
+
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/input/mouse/amimouse.c
+++ linux-qcom-6.8.0/drivers/input/mouse/amimouse.c
@@ -132,7 +132,13 @@
 	input_unregister_device(dev);
 }
 
-static struct platform_driver amimouse_driver = {
+/*
+ * amimouse_remove() lives in .exit.text. For drivers registered via
+ * module_platform_driver_probe() this is ok because they cannot get unbound at
+ * runtime. So mark the driver struct with __refdata to prevent modpost
+ * triggering a section mismatch warning.
+ */
+static struct platform_driver amimouse_driver __refdata = {
 	.remove_new = __exit_p(amimouse_remove),
 	.driver   = {
 		.name	= "amiga-mouse",
--- linux-qcom-6.8.0.orig/drivers/input/mouse/cyapa.c
+++ linux-qcom-6.8.0/drivers/input/mouse/cyapa.c
@@ -1347,10 +1347,16 @@
 	u8 power_mode;
 	int error;
 
-	error = mutex_lock_interruptible(&cyapa->state_sync_lock);
+	error = mutex_lock_interruptible(&cyapa->input->mutex);
 	if (error)
 		return error;
 
+	error = mutex_lock_interruptible(&cyapa->state_sync_lock);
+	if (error) {
+		mutex_unlock(&cyapa->input->mutex);
+		return error;
+	}
+
 	/*
 	 * Runtime PM is enable only when device is in operational mode and
 	 * users in use, so need check it before disable it to
@@ -1385,6 +1391,8 @@
 		cyapa->irq_wake = (enable_irq_wake(client->irq) == 0);
 
 	mutex_unlock(&cyapa->state_sync_lock);
+	mutex_unlock(&cyapa->input->mutex);
+
 	return 0;
 }
 
@@ -1394,6 +1402,7 @@
 	struct cyapa *cyapa = i2c_get_clientdata(client);
 	int error;
 
+	mutex_lock(&cyapa->input->mutex);
 	mutex_lock(&cyapa->state_sync_lock);
 
 	if (device_may_wakeup(dev) && cyapa->irq_wake) {
@@ -1412,6 +1421,7 @@
 	enable_irq(client->irq);
 
 	mutex_unlock(&cyapa->state_sync_lock);
+	mutex_unlock(&cyapa->input->mutex);
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/input/mouse/cypress_ps2.c
+++ linux-qcom-6.8.0/drivers/input/mouse/cypress_ps2.c
@@ -387,7 +387,9 @@
 	if (ret < 0)
 		return ret;
 
+#if ( CYPRESS_SIMULATED_MT != 1 )
 	__set_bit(INPUT_PROP_SEMI_MT, input->propbit);
+#endif
 
 	input_abs_set_res(input, ABS_X, cytp->tp_res_x);
 	input_abs_set_res(input, ABS_Y, cytp->tp_res_y);
@@ -473,6 +475,22 @@
 			((packet[5] & 0x0f) << 8) | packet[7];
 		if (cytp->mode & CYTP_BIT_ABS_PRESSURE)
 			report_data->contacts[1].z = report_data->contacts[0].z;
+#if ( CYPRESS_SIMULATED_MT == 1 )
+		/* simulate contact positions for >2 fingers */
+		if ( report_data->contact_cnt >= 3 ) {
+			int i;
+			for ( i=1; i<report_data->contact_cnt; i++ ) {
+			    report_data->contacts[i].x =
+					    report_data->contacts[0].x
+					    + 100*(i)*((i%2)?-1:1);
+			    report_data->contacts[i].y =
+					    report_data->contacts[0].y;
+			    if (cytp->mode & CYTP_BIT_ABS_PRESSURE)
+				    report_data->contacts[i].z =
+					    report_data->contacts[0].z;
+			}
+		}
+#endif
 	}
 
 	report_data->left = (header_byte & BTN_LEFT_BIT) ? 1 : 0;
--- linux-qcom-6.8.0.orig/drivers/input/mouse/cypress_ps2.h
+++ linux-qcom-6.8.0/drivers/input/mouse/cypress_ps2.h
@@ -131,7 +131,18 @@
 #define RESP_REMOTE_BIT     0x40
 #define RESP_SMBUS_BIT      0x80
 
-#define CYTP_MAX_MT_SLOTS 2
+/*
+ * CYPRESS_SIMULATED_MT
+ *   set to 1 for simulated multitouch (up to 5 contact points)
+ *   set to 0 for SEMI_MT (only 2 corner points, and count of fingers)
+ */
+#define CYPRESS_SIMULATED_MT 1
+
+#if ( CYPRESS_SIMULATED_MT == 1 )
+# define CYTP_MAX_MT_SLOTS 5
+#else
+# define CYTP_MAX_MT_SLOTS 2
+#endif
 
 struct cytp_contact {
 	int x;
--- linux-qcom-6.8.0.orig/drivers/input/mouse/elan_i2c_core.c
+++ linux-qcom-6.8.0/drivers/input/mouse/elan_i2c_core.c
@@ -1356,6 +1356,8 @@
 	}
 
 err:
+	if (ret)
+		enable_irq(client->irq);
 	mutex_unlock(&data->sysfs_mutex);
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/input/mouse/elantech.c
+++ linux-qcom-6.8.0/drivers/input/mouse/elantech.c
@@ -1477,15 +1477,46 @@
 }
 
 /*
+ * Some hw_version 4 models fail to properly activate absolute mode on
+ * resume without going through disable/enable cycle.
+ */
+static const struct dmi_system_id elantech_needs_reenable[] = {
+#if defined(CONFIG_DMI) && defined(CONFIG_X86)
+	{
+		/* Lenovo N24 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "81AF"),
+		},
+	},
+#endif
+	{ }
+};
+
+/*
  * Put the touchpad back into absolute mode when reconnecting
  */
 static int elantech_reconnect(struct psmouse *psmouse)
 {
+	int err;
+
 	psmouse_reset(psmouse);
 
 	if (elantech_detect(psmouse, 0))
 		return -1;
 
+	if (dmi_check_system(elantech_needs_reenable)) {
+		err = ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_DISABLE);
+		if (err)
+			psmouse_warn(psmouse, "failed to deactivate mouse on %s: %d\n",
+				     psmouse->ps2dev.serio->phys, err);
+
+		err = ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE);
+		if (err)
+			psmouse_warn(psmouse, "failed to reactivate mouse on %s: %d\n",
+				     psmouse->ps2dev.serio->phys, err);
+	}
+
 	if (elantech_set_absolute_mode(psmouse)) {
 		psmouse_err(psmouse,
 			    "failed to put touchpad back into absolute mode.\n");
--- linux-qcom-6.8.0.orig/drivers/input/mouse/synaptics.c
+++ linux-qcom-6.8.0/drivers/input/mouse/synaptics.c
@@ -189,6 +189,7 @@
 	"LEN2054", /* E480 */
 	"LEN2055", /* E580 */
 	"LEN2068", /* T14 Gen 1 */
+	"SYN3015", /* HP EliteBook 840 G2 */
 	"SYN3052", /* HP EliteBook 840 G4 */
 	"SYN3221", /* HP 15-ay000 */
 	"SYN323d", /* HP Spectre X360 13-w013dx */
--- linux-qcom-6.8.0.orig/drivers/input/mouse/vmmouse.c
+++ linux-qcom-6.8.0/drivers/input/mouse/vmmouse.c
@@ -21,19 +21,16 @@
 #include "psmouse.h"
 #include "vmmouse.h"
 
-#define VMMOUSE_PROTO_MAGIC			0x564D5868U
-
 /*
  * Main commands supported by the vmmouse hypervisor port.
  */
-#define VMMOUSE_PROTO_CMD_GETVERSION		10
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_DATA	39
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS	40
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND	41
-#define VMMOUSE_PROTO_CMD_ABSPOINTER_RESTRICT   86
+#define VMWARE_CMD_ABSPOINTER_DATA	39
+#define VMWARE_CMD_ABSPOINTER_STATUS	40
+#define VMWARE_CMD_ABSPOINTER_COMMAND	41
+#define VMWARE_CMD_ABSPOINTER_RESTRICT	86
 
 /*
- * Subcommands for VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND
+ * Subcommands for VMWARE_CMD_ABSPOINTER_COMMAND
  */
 #define VMMOUSE_CMD_ENABLE			0x45414552U
 #define VMMOUSE_CMD_DISABLE			0x000000f5U
@@ -76,28 +73,6 @@
 	char dev_name[128];
 };
 
-/*
- * Hypervisor-specific bi-directional communication channel
- * implementing the vmmouse protocol. Should never execute on
- * bare metal hardware.
- */
-#define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4)	\
-({							\
-	unsigned long __dummy1, __dummy2;		\
-	__asm__ __volatile__ (VMWARE_HYPERCALL :	\
-		"=a"(out1),				\
-		"=b"(out2),				\
-		"=c"(out3),				\
-		"=d"(out4),				\
-		"=S"(__dummy1),				\
-		"=D"(__dummy2) :			\
-		"a"(VMMOUSE_PROTO_MAGIC),		\
-		"b"(in1),				\
-		"c"(VMMOUSE_PROTO_CMD_##cmd),		\
-		"d"(0) :			        \
-		"memory");		                \
-})
-
 /**
  * vmmouse_report_button - report button state on the correct input device
  *
@@ -145,14 +120,12 @@
 	struct input_dev *abs_dev = priv->abs_dev;
 	struct input_dev *pref_dev;
 	u32 status, x, y, z;
-	u32 dummy1, dummy2, dummy3;
 	unsigned int queue_length;
 	unsigned int count = 255;
 
 	while (count--) {
 		/* See if we have motion data. */
-		VMMOUSE_CMD(ABSPOINTER_STATUS, 0,
-			    status, dummy1, dummy2, dummy3);
+		status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0);
 		if ((status & VMMOUSE_ERROR) == VMMOUSE_ERROR) {
 			psmouse_err(psmouse, "failed to fetch status data\n");
 			/*
@@ -172,7 +145,8 @@
 		}
 
 		/* Now get it */
-		VMMOUSE_CMD(ABSPOINTER_DATA, 4, status, x, y, z);
+		status = vmware_hypercall4(VMWARE_CMD_ABSPOINTER_DATA, 4,
+					   &x, &y, &z);
 
 		/*
 		 * And report what we've got. Prefer to report button
@@ -247,14 +221,10 @@
 static void vmmouse_disable(struct psmouse *psmouse)
 {
 	u32 status;
-	u32 dummy1, dummy2, dummy3, dummy4;
-
-	VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE,
-		    dummy1, dummy2, dummy3, dummy4);
 
-	VMMOUSE_CMD(ABSPOINTER_STATUS, 0,
-		    status, dummy1, dummy2, dummy3);
+	vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE);
 
+	status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0);
 	if ((status & VMMOUSE_ERROR) != VMMOUSE_ERROR)
 		psmouse_warn(psmouse, "failed to disable vmmouse device\n");
 }
@@ -271,26 +241,24 @@
 static int vmmouse_enable(struct psmouse *psmouse)
 {
 	u32 status, version;
-	u32 dummy1, dummy2, dummy3, dummy4;
 
 	/*
 	 * Try enabling the device. If successful, we should be able to
 	 * read valid version ID back from it.
 	 */
-	VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE,
-		    dummy1, dummy2, dummy3, dummy4);
+	vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE);
 
 	/*
 	 * See if version ID can be retrieved.
 	 */
-	VMMOUSE_CMD(ABSPOINTER_STATUS, 0, status, dummy1, dummy2, dummy3);
+	status = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_STATUS, 0);
 	if ((status & 0x0000ffff) == 0) {
 		psmouse_dbg(psmouse, "empty flags - assuming no device\n");
 		return -ENXIO;
 	}
 
-	VMMOUSE_CMD(ABSPOINTER_DATA, 1 /* single item */,
-		    version, dummy1, dummy2, dummy3);
+	version = vmware_hypercall1(VMWARE_CMD_ABSPOINTER_DATA,
+				    1 /* single item */);
 	if (version != VMMOUSE_VERSION_ID) {
 		psmouse_dbg(psmouse, "Unexpected version value: %u vs %u\n",
 			    (unsigned) version, VMMOUSE_VERSION_ID);
@@ -301,11 +269,11 @@
 	/*
 	 * Restrict ioport access, if possible.
 	 */
-	VMMOUSE_CMD(ABSPOINTER_RESTRICT, VMMOUSE_RESTRICT_CPL0,
-		    dummy1, dummy2, dummy3, dummy4);
+	vmware_hypercall1(VMWARE_CMD_ABSPOINTER_RESTRICT,
+			  VMMOUSE_RESTRICT_CPL0);
 
-	VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_REQUEST_ABSOLUTE,
-		    dummy1, dummy2, dummy3, dummy4);
+	vmware_hypercall1(VMWARE_CMD_ABSPOINTER_COMMAND,
+			  VMMOUSE_CMD_REQUEST_ABSOLUTE);
 
 	return 0;
 }
@@ -342,7 +310,7 @@
  */
 int vmmouse_detect(struct psmouse *psmouse, bool set_properties)
 {
-	u32 response, version, dummy1, dummy2;
+	u32 response, version, type;
 
 	if (!vmmouse_check_hypervisor()) {
 		psmouse_dbg(psmouse,
@@ -351,9 +319,9 @@
 	}
 
 	/* Check if the device is present */
-	response = ~VMMOUSE_PROTO_MAGIC;
-	VMMOUSE_CMD(GETVERSION, 0, version, response, dummy1, dummy2);
-	if (response != VMMOUSE_PROTO_MAGIC || version == 0xffffffffU)
+	response = ~VMWARE_HYPERVISOR_MAGIC;
+	version = vmware_hypercall3(VMWARE_CMD_GETVERSION, 0, &response, &type);
+	if (response != VMWARE_HYPERVISOR_MAGIC || version == 0xffffffffU)
 		return -ENXIO;
 
 	if (set_properties) {
--- linux-qcom-6.8.0.orig/drivers/input/rmi4/rmi_driver.c
+++ linux-qcom-6.8.0/drivers/input/rmi4/rmi_driver.c
@@ -1196,7 +1196,11 @@
 		}
 		rmi_driver_set_input_params(rmi_dev, data->input);
 		data->input->phys = devm_kasprintf(dev, GFP_KERNEL,
-						"%s/input0", dev_name(dev));
+						   "%s/input0", dev_name(dev));
+		if (!data->input->phys) {
+			retval = -ENOMEM;
+			goto err;
+		}
 	}
 
 	retval = rmi_init_functions(data);
--- linux-qcom-6.8.0.orig/drivers/input/serio/i8042-acpipnpio.h
+++ linux-qcom-6.8.0/drivers/input/serio/i8042-acpipnpio.h
@@ -76,13 +76,14 @@
 #define SERIO_QUIRK_PROBE_DEFER		BIT(5)
 #define SERIO_QUIRK_RESET_ALWAYS	BIT(6)
 #define SERIO_QUIRK_RESET_NEVER		BIT(7)
-#define SERIO_QUIRK_DIECT		BIT(8)
+#define SERIO_QUIRK_DIRECT		BIT(8)
 #define SERIO_QUIRK_DUMBKBD		BIT(9)
 #define SERIO_QUIRK_NOLOOP		BIT(10)
 #define SERIO_QUIRK_NOTIMEOUT		BIT(11)
 #define SERIO_QUIRK_KBDRESET		BIT(12)
 #define SERIO_QUIRK_DRITEK		BIT(13)
 #define SERIO_QUIRK_NOPNP		BIT(14)
+#define SERIO_QUIRK_FORCENORESTORE	BIT(15)
 
 /* Quirk table for different mainboards. Options similar or identical to i8042
  * module parameters.
@@ -627,6 +628,15 @@
 		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
 	},
 	{
+		/* Fujitsu Lifebook E756 */
+		/* https://bugzilla.suse.com/show_bug.cgi?id=1229056 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E756"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX)
+	},
+	{
 		/* Fujitsu Lifebook E5411 */
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU CLIENT COMPUTING LIMITED"),
@@ -1111,6 +1121,43 @@
 		.driver_data = (void *)(SERIO_QUIRK_NOLOOP)
 	},
 	/*
+	 * Some TongFang barebones have touchpad and/or keyboard issues after
+	 * suspend fixable with nomux + reset + noloop + nopnp. Luckily, none of
+	 * them have an external PS/2 port so this can safely be set for all of
+	 * them.
+	 * TongFang barebones come with board_vendor and/or system_vendor set to
+	 * a different value for each individual reseller. The only somewhat
+	 * universal way to identify them is by board_name.
+	 */
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "GM6XGxX"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "GMxXGxx"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "GMxXGxX"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_NAME, "GMxHGxx"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+	},
+	/*
 	 * A lot of modern Clevo barebones have touchpad and/or keyboard issues
 	 * after suspend fixable with nomux + reset + noloop + nopnp. Luckily,
 	 * none of them have an external PS/2 port so this can safely be set for
@@ -1149,18 +1196,10 @@
 					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
 	},
 	{
-		/*
-		 * Setting SERIO_QUIRK_NOMUX or SERIO_QUIRK_RESET_ALWAYS makes
-		 * the keyboard very laggy for ~5 seconds after boot and
-		 * sometimes also after resume.
-		 * However both are required for the keyboard to not fail
-		 * completely sometimes after boot or resume.
-		 */
 		.matches = {
 			DMI_MATCH(DMI_BOARD_NAME, "N150CU"),
 		},
-		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
-					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+		.driver_data = (void *)(SERIO_QUIRK_FORCENORESTORE)
 	},
 	{
 		.matches = {
@@ -1332,6 +1371,20 @@
 		.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
 					SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
 	},
+	{
+		/*
+		 * The Ayaneo Kun is a handheld device where some the buttons
+		 * are handled by an AT keyboard. The keyboard is usually
+		 * detected as raw, but sometimes, usually after a cold boot,
+		 * it is detected as translated. Make sure that the keyboard
+		 * is always in raw mode.
+		 */
+		.matches = {
+			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AYANEO"),
+			DMI_MATCH(DMI_BOARD_NAME, "KUN"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_DIRECT)
+	},
 	{ }
 };
 
@@ -1655,7 +1708,7 @@
 		if (quirks & SERIO_QUIRK_RESET_NEVER)
 			i8042_reset = I8042_RESET_NEVER;
 	}
-	if (quirks & SERIO_QUIRK_DIECT)
+	if (quirks & SERIO_QUIRK_DIRECT)
 		i8042_direct = true;
 	if (quirks & SERIO_QUIRK_DUMBKBD)
 		i8042_dumbkbd = true;
@@ -1671,6 +1724,8 @@
 	if (quirks & SERIO_QUIRK_NOPNP)
 		i8042_nopnp = true;
 #endif
+	if (quirks & SERIO_QUIRK_FORCENORESTORE)
+		i8042_forcenorestore = true;
 }
 #else
 static inline void i8042_check_quirks(void) {}
@@ -1704,7 +1759,7 @@
 
 	i8042_check_quirks();
 
-	pr_debug("Active quirks (empty means none):%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+	pr_debug("Active quirks (empty means none):%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
 		i8042_nokbd ? " nokbd" : "",
 		i8042_noaux ? " noaux" : "",
 		i8042_nomux ? " nomux" : "",
@@ -1724,10 +1779,11 @@
 		"",
 #endif
 #ifdef CONFIG_PNP
-		i8042_nopnp ? " nopnp" : "");
+		i8042_nopnp ? " nopnp" : "",
 #else
-		"");
+		"",
 #endif
+		i8042_forcenorestore ? " forcenorestore" : "");
 
 	retval = i8042_pnp_init();
 	if (retval)
--- linux-qcom-6.8.0.orig/drivers/input/serio/i8042.c
+++ linux-qcom-6.8.0/drivers/input/serio/i8042.c
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/suspend.h>
 #include <linux/property.h>
+#include <linux/dmi.h>
 
 #include <asm/io.h>
 
@@ -115,6 +116,10 @@
 MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings");
 #endif
 
+static bool i8042_forcenorestore;
+module_param_named(forcenorestore, i8042_forcenorestore, bool, 0);
+MODULE_PARM_DESC(forcenorestore, "Force no restore on s3 resume, copying s2idle behaviour");
+
 #define DEBUG
 #ifdef DEBUG
 static bool i8042_debug;
@@ -178,6 +183,24 @@
 static bool (*i8042_platform_filter)(unsigned char data, unsigned char str,
 				     struct serio *serio);
 
+static int __init i8042_set_noaux(const struct dmi_system_id *dmi)
+{
+	i8042_noaux = true;
+	return 1;
+}
+
+static const struct dmi_system_id i8042_quirks[] = {
+	{
+		.callback = i8042_set_noaux,
+		.ident = "Dell laptop",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Precision 5550"),
+		},
+	},
+	{},
+};
+
 void i8042_lock_chip(void)
 {
 	mutex_lock(&i8042_mutex);
@@ -621,7 +644,7 @@
 	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
 		i8042_ctr &= ~I8042_CTR_KBDINT;
 		i8042_ctr |= I8042_CTR_KBDDIS;
-		pr_err("Failed to enable KBD port\n");
+		pr_info("Failed to enable KBD port\n");
 		return -EIO;
 	}
 
@@ -640,7 +663,7 @@
 	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
 		i8042_ctr &= ~I8042_CTR_AUXINT;
 		i8042_ctr |= I8042_CTR_AUXDIS;
-		pr_err("Failed to enable AUX port\n");
+		pr_info("Failed to enable AUX port\n");
 		return -EIO;
 	}
 
@@ -732,7 +755,7 @@
 	i8042_ctr &= ~I8042_CTR_AUXINT;
 
 	if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) {
-		pr_err("Failed to disable AUX port, can't use MUX\n");
+		pr_info("Failed to disable AUX port, can't use MUX\n");
 		return -EIO;
 	}
 
@@ -947,25 +970,28 @@
 {
 	unsigned char param;
 	int i = 0;
+	int ret;
 
 	/*
 	 * We try this 5 times; on some really fragile systems this does not
 	 * take the first time...
 	 */
-	do {
+	while (i++ < 5) {
 
-		if (i8042_command(&param, I8042_CMD_CTL_TEST)) {
-			pr_err("i8042 controller selftest timeout\n");
-			return -ENODEV;
-		}
-
-		if (param == I8042_RET_CTL_TEST)
+		ret = i8042_command(&param, I8042_CMD_CTL_TEST);
+		if (ret)
+			pr_info("i8042 controller selftest timeout (%d/5)\n", i);
+		else if (param == I8042_RET_CTL_TEST)
 			return 0;
+		else
+			dbg("i8042 controller selftest: %#x != %#x\n",
+			    param, I8042_RET_CTL_TEST);
 
-		dbg("i8042 controller selftest: %#x != %#x\n",
-		    param, I8042_RET_CTL_TEST);
 		msleep(50);
-	} while (i++ < 5);
+	}
+
+	if (ret)
+		return -ENODEV;
 
 #ifdef CONFIG_X86
 	/*
@@ -977,7 +1003,7 @@
 	pr_info("giving up on controller selftest, continuing anyway...\n");
 	return 0;
 #else
-	pr_err("i8042 controller selftest failed\n");
+	pr_info("i8042 controller selftest failed\n");
 	return -EIO;
 #endif
 }
@@ -1232,7 +1258,7 @@
 {
 	int i;
 
-	if (pm_suspend_via_firmware())
+	if (!i8042_forcenorestore && pm_suspend_via_firmware())
 		i8042_controller_reset(true);
 
 	/* Set up serio interrupts for system wakeup. */
@@ -1248,7 +1274,7 @@
 
 static int i8042_pm_resume_noirq(struct device *dev)
 {
-	if (!pm_resume_via_firmware())
+	if (i8042_forcenorestore || !pm_resume_via_firmware())
 		i8042_interrupt(0, NULL);
 
 	return 0;
@@ -1271,7 +1297,7 @@
 	 * not restore the controller state to whatever it had been at boot
 	 * time, so we do not need to do anything.
 	 */
-	if (!pm_suspend_via_firmware())
+	if (i8042_forcenorestore || !pm_suspend_via_firmware())
 		return 0;
 
 	/*
@@ -1558,6 +1584,8 @@
 		i8042_dritek_enable();
 #endif
 
+	dmi_check_system(i8042_quirks);
+
 	if (!i8042_noaux) {
 		error = i8042_setup_aux();
 		if (error && error != -ENODEV && error != -EBUSY)
--- linux-qcom-6.8.0.orig/drivers/input/serio/ioc3kbd.c
+++ linux-qcom-6.8.0/drivers/input/serio/ioc3kbd.c
@@ -200,9 +200,16 @@
 	serio_unregister_port(d->aux);
 }
 
+static const struct platform_device_id ioc3kbd_id_table[] = {
+	{ "ioc3-kbd", },
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, ioc3kbd_id_table);
+
 static struct platform_driver ioc3kbd_driver = {
 	.probe          = ioc3kbd_probe,
 	.remove_new     = ioc3kbd_remove,
+	.id_table	= ioc3kbd_id_table,
 	.driver = {
 		.name = "ioc3-kbd",
 	},
--- linux-qcom-6.8.0.orig/drivers/input/touchscreen/Kconfig
+++ linux-qcom-6.8.0/drivers/input/touchscreen/Kconfig
@@ -416,6 +416,37 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called goodix.
 
+config TOUCHSCREEN_GOODIX_BERLIN_CORE
+	tristate
+
+config TOUCHSCREEN_GOODIX_BERLIN_I2C
+	tristate "Goodix Berlin I2C touchscreen"
+	depends on I2C
+	select REGMAP_I2C
+	select TOUCHSCREEN_GOODIX_BERLIN_CORE
+	help
+	  Say Y here if you have a Goodix Berlin IC connected to
+	  your system via I2C.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called goodix_berlin_i2c.
+
+config TOUCHSCREEN_GOODIX_BERLIN_SPI
+	tristate "Goodix Berlin SPI touchscreen"
+	depends on SPI_MASTER
+	select REGMAP
+	select TOUCHSCREEN_GOODIX_BERLIN_CORE
+	help
+	  Say Y here if you have a Goodix Berlin IC connected to
+	  your system via SPI.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called goodix_berlin_spi.
+
 config TOUCHSCREEN_HIDEEP
 	tristate "HiDeep Touch IC"
 	depends on I2C
--- linux-qcom-6.8.0.orig/drivers/input/touchscreen/Makefile
+++ linux-qcom-6.8.0/drivers/input/touchscreen/Makefile
@@ -47,6 +47,9 @@
 obj-$(CONFIG_TOUCHSCREEN_EXC3000)	+= exc3000.o
 obj-$(CONFIG_TOUCHSCREEN_FUJITSU)	+= fujitsu_ts.o
 obj-$(CONFIG_TOUCHSCREEN_GOODIX)	+= goodix_ts.o
+obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_CORE)	+= goodix_berlin_core.o
+obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_I2C)	+= goodix_berlin_i2c.o
+obj-$(CONFIG_TOUCHSCREEN_GOODIX_BERLIN_SPI)	+= goodix_berlin_spi.o
 obj-$(CONFIG_TOUCHSCREEN_HIDEEP)	+= hideep.o
 obj-$(CONFIG_TOUCHSCREEN_HYNITRON_CSTXXX)	+= hynitron_cstxxx.o
 obj-$(CONFIG_TOUCHSCREEN_ILI210X)	+= ili210x.o
--- linux-qcom-6.8.0.orig/drivers/input/touchscreen/ads7846.c
+++ linux-qcom-6.8.0/drivers/input/touchscreen/ads7846.c
@@ -805,7 +805,7 @@
 		m = &ts->msg[msg_idx];
 		error = spi_sync(ts->spi, m);
 		if (error) {
-			dev_err(&ts->spi->dev, "spi_sync --> %d\n", error);
+			dev_err_ratelimited(&ts->spi->dev, "spi_sync --> %d\n", error);
 			packet->ignore = true;
 			return;
 		}
@@ -1111,6 +1111,16 @@
 };
 MODULE_DEVICE_TABLE(of, ads7846_dt_ids);
 
+static const struct spi_device_id ads7846_spi_ids[] = {
+	{ "tsc2046", 7846 },
+	{ "ads7843", 7843 },
+	{ "ads7845", 7845 },
+	{ "ads7846", 7846 },
+	{ "ads7873", 7873 },
+	{ },
+};
+MODULE_DEVICE_TABLE(spi, ads7846_spi_ids);
+
 static const struct ads7846_platform_data *ads7846_get_props(struct device *dev)
 {
 	struct ads7846_platform_data *pdata;
@@ -1386,10 +1396,10 @@
 	},
 	.probe		= ads7846_probe,
 	.remove		= ads7846_remove,
+	.id_table	= ads7846_spi_ids,
 };
 
 module_spi_driver(ads7846_driver);
 
 MODULE_DESCRIPTION("ADS7846 TouchScreen Driver");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("spi:ads7846");
--- linux-qcom-6.8.0.orig/drivers/input/touchscreen/edt-ft5x06.c
+++ linux-qcom-6.8.0/drivers/input/touchscreen/edt-ft5x06.c
@@ -1121,6 +1121,14 @@
 	}
 }
 
+static void edt_ft5x06_exit_regmap(void *arg)
+{
+	struct edt_ft5x06_ts_data *data = arg;
+
+	if (!IS_ERR_OR_NULL(data->regmap))
+		regmap_exit(data->regmap);
+}
+
 static void edt_ft5x06_disable_regulators(void *arg)
 {
 	struct edt_ft5x06_ts_data *data = arg;
@@ -1154,6 +1162,16 @@
 		return PTR_ERR(tsdata->regmap);
 	}
 
+	/*
+	 * We are not using devm_regmap_init_i2c() and instead install a
+	 * custom action because we may replace regmap with M06-specific one
+	 * and we need to make sure that it will not be released too early.
+	 */
+	error = devm_add_action_or_reset(&client->dev, edt_ft5x06_exit_regmap,
+					 tsdata);
+	if (error)
+		return error;
+
 	chip_data = device_get_match_data(&client->dev);
 	if (!chip_data)
 		chip_data = (const struct edt_i2c_chip_data *)id->driver_data;
@@ -1347,7 +1365,6 @@
 	struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
 
 	edt_ft5x06_ts_teardown_debugfs(tsdata);
-	regmap_exit(tsdata->regmap);
 }
 
 static int edt_ft5x06_ts_suspend(struct device *dev)
@@ -1462,6 +1479,10 @@
 	.max_support_points = 5,
 };
 
+static const struct edt_i2c_chip_data edt_ft5452_data = {
+	.max_support_points = 5,
+};
+
 static const struct edt_i2c_chip_data edt_ft5506_data = {
 	.max_support_points = 10,
 };
@@ -1470,12 +1491,23 @@
 	.max_support_points = 2,
 };
 
+static const struct edt_i2c_chip_data edt_ft8201_data = {
+	.max_support_points = 10,
+};
+
+static const struct edt_i2c_chip_data edt_ft8719_data = {
+	.max_support_points = 10,
+};
+
 static const struct i2c_device_id edt_ft5x06_ts_id[] = {
 	{ .name = "edt-ft5x06", .driver_data = (long)&edt_ft5x06_data },
 	{ .name = "edt-ft5506", .driver_data = (long)&edt_ft5506_data },
 	{ .name = "ev-ft5726", .driver_data = (long)&edt_ft5506_data },
+	{ .name = "ft5452", .driver_data = (long)&edt_ft5452_data },
 	/* Note no edt- prefix for compatibility with the ft6236.c driver */
 	{ .name = "ft6236", .driver_data = (long)&edt_ft6236_data },
+	{ .name = "ft8201", .driver_data = (long)&edt_ft8201_data },
+	{ .name = "ft8719", .driver_data = (long)&edt_ft8719_data },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(i2c, edt_ft5x06_ts_id);
@@ -1486,8 +1518,11 @@
 	{ .compatible = "edt,edt-ft5406", .data = &edt_ft5x06_data },
 	{ .compatible = "edt,edt-ft5506", .data = &edt_ft5506_data },
 	{ .compatible = "evervision,ev-ft5726", .data = &edt_ft5506_data },
+	{ .compatible = "focaltech,ft5452", .data = &edt_ft5452_data },
 	/* Note focaltech vendor prefix for compatibility with ft6236.c */
 	{ .compatible = "focaltech,ft6236", .data = &edt_ft6236_data },
+	{ .compatible = "focaltech,ft8201", .data = &edt_ft8201_data },
+	{ .compatible = "focaltech,ft8719", .data = &edt_ft8719_data },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, edt_ft5x06_of_match);
--- linux-qcom-6.8.0.orig/drivers/input/touchscreen/goodix_berlin.h
+++ linux-qcom-6.8.0/drivers/input/touchscreen/goodix_berlin.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Goodix Touchscreen Driver
+ * Copyright (C) 2020 - 2021 Goodix, Inc.
+ * Copyright (C) 2023 Linaro Ltd.
+ *
+ * Based on goodix_berlin_berlin driver.
+ */
+
+#ifndef __GOODIX_BERLIN_H_
+#define __GOODIX_BERLIN_H_
+
+#include <linux/pm.h>
+
+struct device;
+struct input_id;
+struct regmap;
+
+int goodix_berlin_probe(struct device *dev, int irq, const struct input_id *id,
+			struct regmap *regmap);
+
+extern const struct dev_pm_ops goodix_berlin_pm_ops;
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/input/touchscreen/goodix_berlin_core.c
+++ linux-qcom-6.8.0/drivers/input/touchscreen/goodix_berlin_core.c
@@ -0,0 +1,755 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Goodix "Berlin" Touchscreen IC driver
+ * Copyright (C) 2020 - 2021 Goodix, Inc.
+ * Copyright (C) 2023 Linaro Ltd.
+ *
+ * Based on goodix_ts_berlin driver.
+ *
+ * This driver is distinct from goodix.c since hardware interface
+ * is different enough to require a new driver.
+ * None of the register address or data structure are close enough
+ * to the previous generations.
+ *
+ * Currently the driver only handles Multitouch events with already
+ * programmed firmware and "config" for "Revision D" Berlin IC.
+ *
+ * Support is missing for:
+ * - ESD Management
+ * - Firmware update/flashing
+ * - "Config" update/flashing
+ * - Stylus Events
+ * - Gesture Events
+ * - Support for older revisions (A & B)
+ */
+
+#include <linux/bitfield.h>
+#include <linux/gpio/consumer.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/input/touchscreen.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/sizes.h>
+#include <asm/unaligned.h>
+
+#include "goodix_berlin.h"
+
+#define GOODIX_BERLIN_MAX_TOUCH			10
+
+#define GOODIX_BERLIN_NORMAL_RESET_DELAY_MS	100
+
+#define GOODIX_BERLIN_TOUCH_EVENT		BIT(7)
+#define GOODIX_BERLIN_REQUEST_EVENT		BIT(6)
+#define GOODIX_BERLIN_TOUCH_COUNT_MASK		GENMASK(3, 0)
+
+#define GOODIX_BERLIN_REQUEST_CODE_RESET	3
+
+#define GOODIX_BERLIN_POINT_TYPE_MASK		GENMASK(3, 0)
+#define GOODIX_BERLIN_POINT_TYPE_STYLUS_HOVER	1
+#define GOODIX_BERLIN_POINT_TYPE_STYLUS		3
+
+#define GOODIX_BERLIN_TOUCH_ID_MASK		GENMASK(7, 4)
+
+#define GOODIX_BERLIN_DEV_CONFIRM_VAL		0xAA
+#define GOODIX_BERLIN_BOOTOPTION_ADDR		0x10000
+#define GOODIX_BERLIN_FW_VERSION_INFO_ADDR	0x10014
+
+#define GOODIX_BERLIN_IC_INFO_MAX_LEN		SZ_1K
+#define GOODIX_BERLIN_IC_INFO_ADDR		0x10070
+
+#define GOODIX_BERLIN_CHECKSUM_SIZE		sizeof(u16)
+
+struct goodix_berlin_fw_version {
+	u8 rom_pid[6];
+	u8 rom_vid[3];
+	u8 rom_vid_reserved;
+	u8 patch_pid[8];
+	u8 patch_vid[4];
+	u8 patch_vid_reserved;
+	u8 sensor_id;
+	u8 reserved[2];
+	__le16 checksum;
+};
+
+struct goodix_berlin_ic_info_version {
+	u8 info_customer_id;
+	u8 info_version_id;
+	u8 ic_die_id;
+	u8 ic_version_id;
+	__le32 config_id;
+	u8 config_version;
+	u8 frame_data_customer_id;
+	u8 frame_data_version_id;
+	u8 touch_data_customer_id;
+	u8 touch_data_version_id;
+	u8 reserved[3];
+} __packed;
+
+struct goodix_berlin_ic_info_feature {
+	__le16 freqhop_feature;
+	__le16 calibration_feature;
+	__le16 gesture_feature;
+	__le16 side_touch_feature;
+	__le16 stylus_feature;
+} __packed;
+
+struct goodix_berlin_ic_info_misc {
+	__le32 cmd_addr;
+	__le16 cmd_max_len;
+	__le32 cmd_reply_addr;
+	__le16 cmd_reply_len;
+	__le32 fw_state_addr;
+	__le16 fw_state_len;
+	__le32 fw_buffer_addr;
+	__le16 fw_buffer_max_len;
+	__le32 frame_data_addr;
+	__le16 frame_data_head_len;
+	__le16 fw_attr_len;
+	__le16 fw_log_len;
+	u8 pack_max_num;
+	u8 pack_compress_version;
+	__le16 stylus_struct_len;
+	__le16 mutual_struct_len;
+	__le16 self_struct_len;
+	__le16 noise_struct_len;
+	__le32 touch_data_addr;
+	__le16 touch_data_head_len;
+	__le16 point_struct_len;
+	__le16 reserved1;
+	__le16 reserved2;
+	__le32 mutual_rawdata_addr;
+	__le32 mutual_diffdata_addr;
+	__le32 mutual_refdata_addr;
+	__le32 self_rawdata_addr;
+	__le32 self_diffdata_addr;
+	__le32 self_refdata_addr;
+	__le32 iq_rawdata_addr;
+	__le32 iq_refdata_addr;
+	__le32 im_rawdata_addr;
+	__le16 im_readata_len;
+	__le32 noise_rawdata_addr;
+	__le16 noise_rawdata_len;
+	__le32 stylus_rawdata_addr;
+	__le16 stylus_rawdata_len;
+	__le32 noise_data_addr;
+	__le32 esd_addr;
+} __packed;
+
+struct goodix_berlin_touch {
+	u8 status;
+	u8 reserved;
+	__le16 x;
+	__le16 y;
+	__le16 w;
+};
+#define GOODIX_BERLIN_TOUCH_SIZE	sizeof(struct goodix_berlin_touch)
+
+struct goodix_berlin_header {
+	u8 status;
+	u8 reserved1;
+	u8 request_type;
+	u8 reserved2[3];
+	__le16 checksum;
+};
+#define GOODIX_BERLIN_HEADER_SIZE	sizeof(struct goodix_berlin_header)
+
+struct goodix_berlin_event {
+	struct goodix_berlin_header hdr;
+	/* The data below is u16/__le16 aligned */
+	u8 data[GOODIX_BERLIN_TOUCH_SIZE * GOODIX_BERLIN_MAX_TOUCH +
+		GOODIX_BERLIN_CHECKSUM_SIZE];
+};
+
+struct goodix_berlin_core {
+	struct device *dev;
+	struct regmap *regmap;
+	struct regulator *avdd;
+	struct regulator *iovdd;
+	struct gpio_desc *reset_gpio;
+	struct touchscreen_properties props;
+	struct goodix_berlin_fw_version fw_version;
+	struct input_dev *input_dev;
+	int irq;
+
+	/* Runtime parameters extracted from IC_INFO buffer  */
+	u32 touch_data_addr;
+
+	struct goodix_berlin_event event;
+};
+
+static bool goodix_berlin_checksum_valid(const u8 *data, int size)
+{
+	u32 cal_checksum = 0;
+	u16 r_checksum;
+	int i;
+
+	if (size < GOODIX_BERLIN_CHECKSUM_SIZE)
+		return false;
+
+	for (i = 0; i < size - GOODIX_BERLIN_CHECKSUM_SIZE; i++)
+		cal_checksum += data[i];
+
+	r_checksum = get_unaligned_le16(&data[i]);
+
+	return (u16)cal_checksum == r_checksum;
+}
+
+static bool goodix_berlin_is_dummy_data(struct goodix_berlin_core *cd,
+					const u8 *data, int size)
+{
+	int i;
+
+	/*
+	 * If the device is missing or doesn't respond the buffer
+	 * could be filled with bus default line state, 0x00 or 0xff,
+	 * so declare success the first time we encounter neither.
+	 */
+	for (i = 0; i < size; i++)
+		if (data[i] > 0 && data[i] < 0xff)
+			return false;
+
+	return true;
+}
+
+static int goodix_berlin_dev_confirm(struct goodix_berlin_core *cd)
+{
+	u8 tx_buf[8], rx_buf[8];
+	int retry = 3;
+	int error;
+
+	memset(tx_buf, GOODIX_BERLIN_DEV_CONFIRM_VAL, sizeof(tx_buf));
+	while (retry--) {
+		error = regmap_raw_write(cd->regmap,
+					 GOODIX_BERLIN_BOOTOPTION_ADDR,
+					 tx_buf, sizeof(tx_buf));
+		if (error)
+			return error;
+
+		error = regmap_raw_read(cd->regmap,
+					GOODIX_BERLIN_BOOTOPTION_ADDR,
+					rx_buf, sizeof(rx_buf));
+		if (error)
+			return error;
+
+		if (!memcmp(tx_buf, rx_buf, sizeof(tx_buf)))
+			return 0;
+
+		usleep_range(5000, 5100);
+	}
+
+	dev_err(cd->dev, "device confirm failed, rx_buf: %*ph\n",
+		(int)sizeof(rx_buf), rx_buf);
+
+	return -EINVAL;
+}
+
+static int goodix_berlin_power_on(struct goodix_berlin_core *cd)
+{
+	int error;
+
+	error = regulator_enable(cd->iovdd);
+	if (error) {
+		dev_err(cd->dev, "Failed to enable iovdd: %d\n", error);
+		return error;
+	}
+
+	/* Vendor waits 3ms for IOVDD to settle */
+	usleep_range(3000, 3100);
+
+	error = regulator_enable(cd->avdd);
+	if (error) {
+		dev_err(cd->dev, "Failed to enable avdd: %d\n", error);
+		goto err_iovdd_disable;
+	}
+
+	/* Vendor waits 15ms for IOVDD to settle */
+	usleep_range(15000, 15100);
+
+	gpiod_set_value_cansleep(cd->reset_gpio, 0);
+
+	/* Vendor waits 4ms for Firmware to initialize */
+	usleep_range(4000, 4100);
+
+	error = goodix_berlin_dev_confirm(cd);
+	if (error)
+		goto err_dev_reset;
+
+	/* Vendor waits 100ms for Firmware to fully boot */
+	msleep(GOODIX_BERLIN_NORMAL_RESET_DELAY_MS);
+
+	return 0;
+
+err_dev_reset:
+	gpiod_set_value_cansleep(cd->reset_gpio, 1);
+	regulator_disable(cd->avdd);
+err_iovdd_disable:
+	regulator_disable(cd->iovdd);
+	return error;
+}
+
+static void goodix_berlin_power_off(struct goodix_berlin_core *cd)
+{
+	gpiod_set_value_cansleep(cd->reset_gpio, 1);
+	regulator_disable(cd->avdd);
+	regulator_disable(cd->iovdd);
+}
+
+static int goodix_berlin_read_version(struct goodix_berlin_core *cd)
+{
+	int error;
+
+	error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_FW_VERSION_INFO_ADDR,
+				&cd->fw_version, sizeof(cd->fw_version));
+	if (error) {
+		dev_err(cd->dev, "error reading fw version, %d\n", error);
+		return error;
+	}
+
+	if (!goodix_berlin_checksum_valid((u8 *)&cd->fw_version,
+					  sizeof(cd->fw_version))) {
+		dev_err(cd->dev, "invalid fw version: checksum error\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* Only extract necessary data for runtime */
+static int goodix_berlin_parse_ic_info(struct goodix_berlin_core *cd,
+				       const u8 *data, u16 length)
+{
+	struct goodix_berlin_ic_info_misc *misc;
+	unsigned int offset = 0;
+
+	offset += sizeof(__le16); /* length */
+	offset += sizeof(struct goodix_berlin_ic_info_version);
+	offset += sizeof(struct goodix_berlin_ic_info_feature);
+
+	/* IC_INFO Parameters, variable width structure */
+	offset += 4 * sizeof(u8); /* drv_num, sen_num, button_num, force_num */
+	if (offset >= length)
+		goto invalid_offset;
+
+#define ADVANCE_LE16_PARAMS()				\
+	do {						\
+		u8 param_num = data[offset++];		\
+		offset += param_num * sizeof(__le16);	\
+		if (offset >= length)			\
+			goto invalid_offset;		\
+	} while (0)
+	ADVANCE_LE16_PARAMS(); /* active_scan_rate_num */
+	ADVANCE_LE16_PARAMS(); /* mutual_freq_num*/
+	ADVANCE_LE16_PARAMS(); /* self_tx_freq_num */
+	ADVANCE_LE16_PARAMS(); /* self_rx_freq_num */
+	ADVANCE_LE16_PARAMS(); /* stylus_freq_num */
+#undef ADVANCE_LE16_PARAMS
+
+	misc = (struct goodix_berlin_ic_info_misc *)&data[offset];
+	cd->touch_data_addr = le32_to_cpu(misc->touch_data_addr);
+
+	return 0;
+
+invalid_offset:
+	dev_err(cd->dev, "ic_info length is invalid (offset %d length %d)\n",
+		offset, length);
+	return -EINVAL;
+}
+
+static int goodix_berlin_get_ic_info(struct goodix_berlin_core *cd)
+{
+	u8 *afe_data __free(kfree) = NULL;
+	__le16 length_raw;
+	u16 length;
+	int error;
+
+	afe_data = kzalloc(GOODIX_BERLIN_IC_INFO_MAX_LEN, GFP_KERNEL);
+	if (!afe_data)
+		return -ENOMEM;
+
+	error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_IC_INFO_ADDR,
+				&length_raw, sizeof(length_raw));
+	if (error) {
+		dev_err(cd->dev, "failed get ic info length, %d\n", error);
+		return error;
+	}
+
+	length = le16_to_cpu(length_raw);
+	if (length >= GOODIX_BERLIN_IC_INFO_MAX_LEN) {
+		dev_err(cd->dev, "invalid ic info length %d\n", length);
+		return -EINVAL;
+	}
+
+	error = regmap_raw_read(cd->regmap, GOODIX_BERLIN_IC_INFO_ADDR,
+				afe_data, length);
+	if (error) {
+		dev_err(cd->dev, "failed get ic info data, %d\n", error);
+		return error;
+	}
+
+	/* check whether the data is valid (ex. bus default values) */
+	if (goodix_berlin_is_dummy_data(cd, afe_data, length)) {
+		dev_err(cd->dev, "fw info data invalid\n");
+		return -EINVAL;
+	}
+
+	if (!goodix_berlin_checksum_valid(afe_data, length)) {
+		dev_err(cd->dev, "fw info checksum error\n");
+		return -EINVAL;
+	}
+
+	error = goodix_berlin_parse_ic_info(cd, afe_data, length);
+	if (error)
+		return error;
+
+	/* check some key info */
+	if (!cd->touch_data_addr) {
+		dev_err(cd->dev, "touch_data_addr is null\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int goodix_berlin_get_remaining_contacts(struct goodix_berlin_core *cd,
+						int n)
+{
+	size_t offset = 2 * GOODIX_BERLIN_TOUCH_SIZE +
+				GOODIX_BERLIN_CHECKSUM_SIZE;
+	u32 addr = cd->touch_data_addr + GOODIX_BERLIN_HEADER_SIZE + offset;
+	int error;
+
+	error = regmap_raw_read(cd->regmap, addr,
+				&cd->event.data[offset],
+				(n - 2) * GOODIX_BERLIN_TOUCH_SIZE);
+	if (error) {
+		dev_err_ratelimited(cd->dev, "failed to get touch data, %d\n",
+				    error);
+		return error;
+	}
+
+	return 0;
+}
+
+static void goodix_berlin_report_state(struct goodix_berlin_core *cd, int n)
+{
+	struct goodix_berlin_touch *touch_data =
+			(struct goodix_berlin_touch *)cd->event.data;
+	struct goodix_berlin_touch *t;
+	int i;
+	u8 type, id;
+
+	for (i = 0; i < n; i++) {
+		t = &touch_data[i];
+
+		type = FIELD_GET(GOODIX_BERLIN_POINT_TYPE_MASK, t->status);
+		if (type == GOODIX_BERLIN_POINT_TYPE_STYLUS ||
+		    type == GOODIX_BERLIN_POINT_TYPE_STYLUS_HOVER) {
+			dev_warn_once(cd->dev, "Stylus event type not handled\n");
+			continue;
+		}
+
+		id = FIELD_GET(GOODIX_BERLIN_TOUCH_ID_MASK, t->status);
+		if (id >= GOODIX_BERLIN_MAX_TOUCH) {
+			dev_warn_ratelimited(cd->dev, "invalid finger id %d\n", id);
+			continue;
+		}
+
+		input_mt_slot(cd->input_dev, id);
+		input_mt_report_slot_state(cd->input_dev, MT_TOOL_FINGER, true);
+
+		touchscreen_report_pos(cd->input_dev, &cd->props,
+				       __le16_to_cpu(t->x), __le16_to_cpu(t->y),
+				       true);
+		input_report_abs(cd->input_dev, ABS_MT_TOUCH_MAJOR,
+				 __le16_to_cpu(t->w));
+	}
+
+	input_mt_sync_frame(cd->input_dev);
+	input_sync(cd->input_dev);
+}
+
+static void goodix_berlin_touch_handler(struct goodix_berlin_core *cd)
+{
+	u8 touch_num;
+	int error;
+
+	touch_num = FIELD_GET(GOODIX_BERLIN_TOUCH_COUNT_MASK,
+			      cd->event.hdr.request_type);
+	if (touch_num > GOODIX_BERLIN_MAX_TOUCH) {
+		dev_warn(cd->dev, "invalid touch num %d\n", touch_num);
+		return;
+	}
+
+	if (touch_num > 2) {
+		/* read additional contact data if more than 2 touch events */
+		error = goodix_berlin_get_remaining_contacts(cd, touch_num);
+		if (error)
+			return;
+	}
+
+	if (touch_num) {
+		int len = touch_num * GOODIX_BERLIN_TOUCH_SIZE +
+			  GOODIX_BERLIN_CHECKSUM_SIZE;
+		if (!goodix_berlin_checksum_valid(cd->event.data, len)) {
+			dev_err(cd->dev, "touch data checksum error: %*ph\n",
+				len, cd->event.data);
+			return;
+		}
+	}
+
+	goodix_berlin_report_state(cd, touch_num);
+}
+
+static int goodix_berlin_request_handle_reset(struct goodix_berlin_core *cd)
+{
+	gpiod_set_value_cansleep(cd->reset_gpio, 1);
+	usleep_range(2000, 2100);
+	gpiod_set_value_cansleep(cd->reset_gpio, 0);
+
+	msleep(GOODIX_BERLIN_NORMAL_RESET_DELAY_MS);
+
+	return 0;
+}
+
+static irqreturn_t goodix_berlin_irq(int irq, void *data)
+{
+	struct goodix_berlin_core *cd = data;
+	int error;
+
+	/*
+	 * First, read buffer with space for 2 touch events:
+	 * - GOODIX_BERLIN_HEADER_SIZE = 8 bytes
+	 * - GOODIX_BERLIN_TOUCH_SIZE * 2 = 16 bytes
+	 * - GOODIX_BERLIN_CHECKLSUM_SIZE = 2 bytes
+	 * For a total of 26 bytes.
+	 *
+	 * If only a single finger is reported, we will read 8 bytes more than
+	 * needed:
+	 * - bytes 0-7:   Header (GOODIX_BERLIN_HEADER_SIZE)
+	 * - bytes 8-15:  Finger 0 Data
+	 * - bytes 24-25: Checksum
+	 * - bytes 18-25: Unused 8 bytes
+	 *
+	 * If 2 fingers are reported, we would have read the exact needed
+	 * amount of data and checksum would be at the end of the buffer:
+	 * - bytes 0-7:   Header (GOODIX_BERLIN_HEADER_SIZE)
+	 * - bytes 8-15:  Finger 0 Bytes 0-7
+	 * - bytes 16-23: Finger 1 Bytes 0-7
+	 * - bytes 24-25: Checksum
+	 *
+	 * If more than 2 fingers were reported, the "Checksum" bytes would
+	 * in fact contain part of the next finger data, and then
+	 * goodix_berlin_get_remaining_contacts() would complete the buffer
+	 * with the missing bytes, including the trailing checksum.
+	 * For example, if 3 fingers are reported, then we would do:
+	 * Read 1:
+	 * - bytes 0-7:   Header (GOODIX_BERLIN_HEADER_SIZE)
+	 * - bytes 8-15:  Finger 0 Bytes 0-7
+	 * - bytes 16-23: Finger 1 Bytes 0-7
+	 * - bytes 24-25: Finger 2 Bytes 0-1
+	 * Read 2 (with length of (3 - 2) * 8 = 8 bytes):
+	 * - bytes 26-31: Finger 2 Bytes 2-7
+	 * - bytes 32-33: Checksum
+	 */
+	error = regmap_raw_read(cd->regmap, cd->touch_data_addr,
+				&cd->event,
+				GOODIX_BERLIN_HEADER_SIZE +
+					2 * GOODIX_BERLIN_TOUCH_SIZE +
+					GOODIX_BERLIN_CHECKSUM_SIZE);
+	if (error) {
+		dev_warn_ratelimited(cd->dev,
+				     "failed get event head data: %d\n", error);
+		goto out;
+	}
+
+	if (cd->event.hdr.status == 0)
+		goto out;
+
+	if (!goodix_berlin_checksum_valid((u8 *)&cd->event.hdr,
+					  GOODIX_BERLIN_HEADER_SIZE)) {
+		dev_warn_ratelimited(cd->dev,
+				     "touch head checksum error: %*ph\n",
+				     (int)GOODIX_BERLIN_HEADER_SIZE,
+				     &cd->event.hdr);
+		goto out_clear;
+	}
+
+	if (cd->event.hdr.status & GOODIX_BERLIN_TOUCH_EVENT)
+		goodix_berlin_touch_handler(cd);
+
+	if (cd->event.hdr.status & GOODIX_BERLIN_REQUEST_EVENT) {
+		switch (cd->event.hdr.request_type) {
+		case GOODIX_BERLIN_REQUEST_CODE_RESET:
+			if (cd->reset_gpio)
+				goodix_berlin_request_handle_reset(cd);
+			break;
+
+		default:
+			dev_warn(cd->dev, "unsupported request code 0x%x\n",
+				 cd->event.hdr.request_type);
+		}
+	}
+
+
+out_clear:
+	/* Clear up status field */
+	regmap_write(cd->regmap, cd->touch_data_addr, 0);
+
+out:
+	return IRQ_HANDLED;
+}
+
+static int goodix_berlin_input_dev_config(struct goodix_berlin_core *cd,
+					  const struct input_id *id)
+{
+	struct input_dev *input_dev;
+	int error;
+
+	input_dev = devm_input_allocate_device(cd->dev);
+	if (!input_dev)
+		return -ENOMEM;
+
+	cd->input_dev = input_dev;
+	input_set_drvdata(input_dev, cd);
+
+	input_dev->name = "Goodix Berlin Capacitive TouchScreen";
+	input_dev->phys = "input/ts";
+
+	input_dev->id = *id;
+
+	input_set_abs_params(cd->input_dev, ABS_MT_POSITION_X,
+			     0, SZ_64K - 1, 0, 0);
+	input_set_abs_params(cd->input_dev, ABS_MT_POSITION_Y,
+			     0, SZ_64K - 1, 0, 0);
+	input_set_abs_params(cd->input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+
+	touchscreen_parse_properties(cd->input_dev, true, &cd->props);
+
+	error = input_mt_init_slots(cd->input_dev, GOODIX_BERLIN_MAX_TOUCH,
+				    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+	if (error)
+		return error;
+
+	error = input_register_device(cd->input_dev);
+	if (error)
+		return error;
+
+	return 0;
+}
+
+static int goodix_berlin_suspend(struct device *dev)
+{
+	struct goodix_berlin_core *cd = dev_get_drvdata(dev);
+
+	disable_irq(cd->irq);
+	goodix_berlin_power_off(cd);
+
+	return 0;
+}
+
+static int goodix_berlin_resume(struct device *dev)
+{
+	struct goodix_berlin_core *cd = dev_get_drvdata(dev);
+	int error;
+
+	error = goodix_berlin_power_on(cd);
+	if (error)
+		return error;
+
+	enable_irq(cd->irq);
+
+	return 0;
+}
+
+EXPORT_GPL_SIMPLE_DEV_PM_OPS(goodix_berlin_pm_ops,
+			     goodix_berlin_suspend, goodix_berlin_resume);
+
+static void goodix_berlin_power_off_act(void *data)
+{
+	struct goodix_berlin_core *cd = data;
+
+	goodix_berlin_power_off(cd);
+}
+
+int goodix_berlin_probe(struct device *dev, int irq, const struct input_id *id,
+			struct regmap *regmap)
+{
+	struct goodix_berlin_core *cd;
+	int error;
+
+	if (irq <= 0) {
+		dev_err(dev, "Missing interrupt number\n");
+		return -EINVAL;
+	}
+
+	cd = devm_kzalloc(dev, sizeof(*cd), GFP_KERNEL);
+	if (!cd)
+		return -ENOMEM;
+
+	cd->dev = dev;
+	cd->regmap = regmap;
+	cd->irq = irq;
+
+	cd->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(cd->reset_gpio))
+		return dev_err_probe(dev, PTR_ERR(cd->reset_gpio),
+				     "Failed to request reset gpio\n");
+
+	cd->avdd = devm_regulator_get(dev, "avdd");
+	if (IS_ERR(cd->avdd))
+		return dev_err_probe(dev, PTR_ERR(cd->avdd),
+				     "Failed to request avdd regulator\n");
+
+	cd->iovdd = devm_regulator_get(dev, "iovdd");
+	if (IS_ERR(cd->iovdd))
+		return dev_err_probe(dev, PTR_ERR(cd->iovdd),
+				     "Failed to request iovdd regulator\n");
+
+	error = goodix_berlin_power_on(cd);
+	if (error) {
+		dev_err(dev, "failed power on");
+		return error;
+	}
+
+	error = devm_add_action_or_reset(dev, goodix_berlin_power_off_act, cd);
+	if (error)
+		return error;
+
+	error = goodix_berlin_read_version(cd);
+	if (error) {
+		dev_err(dev, "failed to get version info");
+		return error;
+	}
+
+	error = goodix_berlin_get_ic_info(cd);
+	if (error) {
+		dev_err(dev, "invalid ic info, abort");
+		return error;
+	}
+
+	error = goodix_berlin_input_dev_config(cd, id);
+	if (error) {
+		dev_err(dev, "failed set input device");
+		return error;
+	}
+
+	error = devm_request_threaded_irq(dev, cd->irq, NULL, goodix_berlin_irq,
+					  IRQF_ONESHOT, "goodix-berlin", cd);
+	if (error) {
+		dev_err(dev, "request threaded irq failed: %d\n", error);
+		return error;
+	}
+
+	dev_set_drvdata(dev, cd);
+
+	dev_dbg(dev, "Goodix Berlin %s Touchscreen Controller",
+		cd->fw_version.patch_pid);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(goodix_berlin_probe);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Goodix Berlin Core Touchscreen driver");
+MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>");
--- linux-qcom-6.8.0.orig/drivers/input/touchscreen/goodix_berlin_i2c.c
+++ linux-qcom-6.8.0/drivers/input/touchscreen/goodix_berlin_i2c.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Goodix Berlin Touchscreen Driver
+ *
+ * Copyright (C) 2020 - 2021 Goodix, Inc.
+ * Copyright (C) 2023 Linaro Ltd.
+ *
+ * Based on goodix_ts_berlin driver.
+ */
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/input.h>
+
+#include "goodix_berlin.h"
+
+#define I2C_MAX_TRANSFER_SIZE		256
+
+static const struct regmap_config goodix_berlin_i2c_regmap_conf = {
+	.reg_bits = 32,
+	.val_bits = 8,
+	.max_raw_read = I2C_MAX_TRANSFER_SIZE,
+	.max_raw_write = I2C_MAX_TRANSFER_SIZE,
+};
+
+/* vendor & product left unassigned here, should probably be updated from fw info */
+static const struct input_id goodix_berlin_i2c_input_id = {
+	.bustype = BUS_I2C,
+};
+
+static int goodix_berlin_i2c_probe(struct i2c_client *client)
+{
+	struct regmap *regmap;
+	int error;
+
+	regmap = devm_regmap_init_i2c(client, &goodix_berlin_i2c_regmap_conf);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	error = goodix_berlin_probe(&client->dev, client->irq,
+				    &goodix_berlin_i2c_input_id, regmap);
+	if (error)
+		return error;
+
+	return 0;
+}
+
+static const struct i2c_device_id goodix_berlin_i2c_id[] = {
+	{ "gt9916", 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(i2c, goodix_berlin_i2c_id);
+
+static const struct of_device_id goodix_berlin_i2c_of_match[] = {
+	{ .compatible = "goodix,gt9916", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, goodix_berlin_i2c_of_match);
+
+static struct i2c_driver goodix_berlin_i2c_driver = {
+	.driver = {
+		.name = "goodix-berlin-i2c",
+		.of_match_table = goodix_berlin_i2c_of_match,
+		.pm = pm_sleep_ptr(&goodix_berlin_pm_ops),
+	},
+	.probe = goodix_berlin_i2c_probe,
+	.id_table = goodix_berlin_i2c_id,
+};
+module_i2c_driver(goodix_berlin_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Goodix Berlin I2C Touchscreen driver");
+MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>");
--- linux-qcom-6.8.0.orig/drivers/input/touchscreen/goodix_berlin_spi.c
+++ linux-qcom-6.8.0/drivers/input/touchscreen/goodix_berlin_spi.c
@@ -0,0 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Goodix Berlin Touchscreen Driver
+ *
+ * Copyright (C) 2020 - 2021 Goodix, Inc.
+ * Copyright (C) 2023 Linaro Ltd.
+ *
+ * Based on goodix_ts_berlin driver.
+ */
+#include <asm/unaligned.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+#include <linux/input.h>
+
+#include "goodix_berlin.h"
+
+#define GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN	1
+#define GOODIX_BERLIN_REGISTER_WIDTH		4
+#define GOODIX_BERLIN_SPI_READ_DUMMY_LEN	3
+#define GOODIX_BERLIN_SPI_READ_PREFIX_LEN	(GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
+						 GOODIX_BERLIN_REGISTER_WIDTH + \
+						 GOODIX_BERLIN_SPI_READ_DUMMY_LEN)
+#define GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN	(GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + \
+						 GOODIX_BERLIN_REGISTER_WIDTH)
+
+#define GOODIX_BERLIN_SPI_WRITE_FLAG		0xF0
+#define GOODIX_BERLIN_SPI_READ_FLAG		0xF1
+
+static int goodix_berlin_spi_read(void *context, const void *reg_buf,
+				  size_t reg_size, void *val_buf,
+				  size_t val_size)
+{
+	struct spi_device *spi = context;
+	struct spi_transfer xfers;
+	struct spi_message spi_msg;
+	const u32 *reg = reg_buf; /* reg is stored as native u32 at start of buffer */
+	u8 *buf;
+	int error;
+
+	if (reg_size != GOODIX_BERLIN_REGISTER_WIDTH)
+		return -EINVAL;
+
+	buf = kzalloc(GOODIX_BERLIN_SPI_READ_PREFIX_LEN + val_size, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	spi_message_init(&spi_msg);
+	memset(&xfers, 0, sizeof(xfers));
+
+	/* buffer format: 0xF1 + addr(4bytes) + dummy(3bytes) + data */
+	buf[0] = GOODIX_BERLIN_SPI_READ_FLAG;
+	put_unaligned_be32(*reg, buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN);
+	memset(buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN + GOODIX_BERLIN_REGISTER_WIDTH,
+	       0xff, GOODIX_BERLIN_SPI_READ_DUMMY_LEN);
+
+	xfers.tx_buf = buf;
+	xfers.rx_buf = buf;
+	xfers.len = GOODIX_BERLIN_SPI_READ_PREFIX_LEN + val_size;
+	xfers.cs_change = 0;
+	spi_message_add_tail(&xfers, &spi_msg);
+
+	error = spi_sync(spi, &spi_msg);
+	if (error < 0)
+		dev_err(&spi->dev, "spi transfer error, %d", error);
+	else
+		memcpy(val_buf, buf + GOODIX_BERLIN_SPI_READ_PREFIX_LEN, val_size);
+
+	kfree(buf);
+	return error;
+}
+
+static int goodix_berlin_spi_write(void *context, const void *data,
+				   size_t count)
+{
+	unsigned int len = count - GOODIX_BERLIN_REGISTER_WIDTH;
+	struct spi_device *spi = context;
+	struct spi_transfer xfers;
+	struct spi_message spi_msg;
+	const u32 *reg = data; /* reg is stored as native u32 at start of buffer */
+	u8 *buf;
+	int error;
+
+	buf = kzalloc(GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN + len, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	spi_message_init(&spi_msg);
+	memset(&xfers, 0, sizeof(xfers));
+
+	buf[0] = GOODIX_BERLIN_SPI_WRITE_FLAG;
+	put_unaligned_be32(*reg, buf + GOODIX_BERLIN_SPI_TRANS_PREFIX_LEN);
+	memcpy(buf + GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN,
+	       data + GOODIX_BERLIN_REGISTER_WIDTH, len);
+
+	xfers.tx_buf = buf;
+	xfers.len = GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN + len;
+	xfers.cs_change = 0;
+	spi_message_add_tail(&xfers, &spi_msg);
+
+	error = spi_sync(spi, &spi_msg);
+	if (error < 0)
+		dev_err(&spi->dev, "spi transfer error, %d", error);
+
+	kfree(buf);
+	return error;
+}
+
+static const struct regmap_config goodix_berlin_spi_regmap_conf = {
+	.reg_bits = 32,
+	.val_bits = 8,
+	.read = goodix_berlin_spi_read,
+	.write = goodix_berlin_spi_write,
+};
+
+/* vendor & product left unassigned here, should probably be updated from fw info */
+static const struct input_id goodix_berlin_spi_input_id = {
+	.bustype = BUS_SPI,
+};
+
+static int goodix_berlin_spi_probe(struct spi_device *spi)
+{
+	struct regmap_config regmap_config;
+	struct regmap *regmap;
+	size_t max_size;
+	int error = 0;
+
+	spi->mode = SPI_MODE_0;
+	spi->bits_per_word = 8;
+	error = spi_setup(spi);
+	if (error)
+		return error;
+
+	max_size = spi_max_transfer_size(spi);
+
+	regmap_config = goodix_berlin_spi_regmap_conf;
+	regmap_config.max_raw_read = max_size - GOODIX_BERLIN_SPI_READ_PREFIX_LEN;
+	regmap_config.max_raw_write = max_size - GOODIX_BERLIN_SPI_WRITE_PREFIX_LEN;
+
+	regmap = devm_regmap_init(&spi->dev, NULL, spi, &regmap_config);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	error = goodix_berlin_probe(&spi->dev, spi->irq,
+				    &goodix_berlin_spi_input_id, regmap);
+	if (error)
+		return error;
+
+	return 0;
+}
+
+static const struct spi_device_id goodix_berlin_spi_ids[] = {
+	{ "gt9916" },
+	{ },
+};
+MODULE_DEVICE_TABLE(spi, goodix_berlin_spi_ids);
+
+static const struct of_device_id goodix_berlin_spi_of_match[] = {
+	{ .compatible = "goodix,gt9916", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, goodix_berlin_spi_of_match);
+
+static struct spi_driver goodix_berlin_spi_driver = {
+	.driver = {
+		.name = "goodix-berlin-spi",
+		.of_match_table = goodix_berlin_spi_of_match,
+		.pm = pm_sleep_ptr(&goodix_berlin_pm_ops),
+	},
+	.probe = goodix_berlin_spi_probe,
+	.id_table = goodix_berlin_spi_ids,
+};
+module_spi_driver(goodix_berlin_spi_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Goodix Berlin SPI Touchscreen driver");
+MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>");
--- linux-qcom-6.8.0.orig/drivers/input/touchscreen/ili210x.c
+++ linux-qcom-6.8.0/drivers/input/touchscreen/ili210x.c
@@ -261,8 +261,8 @@
 	if (!error && data[0] == 2) {
 		error = i2c_master_recv(client, data + ILI251X_DATA_SIZE1,
 					ILI251X_DATA_SIZE2);
-		if (error >= 0 && error != ILI251X_DATA_SIZE2)
-			error = -EIO;
+		if (error >= 0)
+			error = error == ILI251X_DATA_SIZE2 ? 0 : -EIO;
 	}
 
 	return error;
@@ -597,7 +597,7 @@
 	 * once, copy them all into this buffer at the right locations, and then
 	 * do all operations on this linear buffer.
 	 */
-	fw_buf = kzalloc(SZ_64K, GFP_KERNEL);
+	fw_buf = kvmalloc(SZ_64K, GFP_KERNEL);
 	if (!fw_buf)
 		return -ENOMEM;
 
@@ -627,7 +627,7 @@
 	return 0;
 
 err_big:
-	kfree(fw_buf);
+	kvfree(fw_buf);
 	return error;
 }
 
@@ -870,7 +870,7 @@
 	ili210x_hardware_reset(priv->reset_gpio);
 	dev_dbg(dev, "Firmware update ended, error=%i\n", error);
 	enable_irq(client->irq);
-	kfree(fwbuf);
+	kvfree(fwbuf);
 	return error;
 }
 
--- linux-qcom-6.8.0.orig/drivers/input/touchscreen/ilitek_ts_i2c.c
+++ linux-qcom-6.8.0/drivers/input/touchscreen/ilitek_ts_i2c.c
@@ -37,6 +37,8 @@
 #define ILITEK_TP_CMD_GET_MCU_VER			0x61
 #define ILITEK_TP_CMD_GET_IC_MODE			0xC0
 
+#define ILITEK_TP_I2C_REPORT_ID				0x48
+
 #define REPORT_COUNT_ADDRESS				61
 #define ILITEK_SUPPORT_MAX_POINT			40
 
@@ -160,15 +162,19 @@
 	error = ilitek_i2c_write_and_read(ts, NULL, 0, 0, buf, 64);
 	if (error) {
 		dev_err(dev, "get touch info failed, err:%d\n", error);
-		goto err_sync_frame;
+		return error;
+	}
+
+	if (buf[0] != ILITEK_TP_I2C_REPORT_ID) {
+		dev_err(dev, "get touch info failed. Wrong id: 0x%02X\n", buf[0]);
+		return -EINVAL;
 	}
 
 	report_max_point = buf[REPORT_COUNT_ADDRESS];
 	if (report_max_point > ts->max_tp) {
 		dev_err(dev, "FW report max point:%d > panel info. max:%d\n",
 			report_max_point, ts->max_tp);
-		error = -EINVAL;
-		goto err_sync_frame;
+		return -EINVAL;
 	}
 
 	count = DIV_ROUND_UP(report_max_point, packet_max_point);
@@ -178,7 +184,7 @@
 		if (error) {
 			dev_err(dev, "get touch info. failed, cnt:%d, err:%d\n",
 				count, error);
-			goto err_sync_frame;
+			return error;
 		}
 	}
 
@@ -203,10 +209,10 @@
 		ilitek_touch_down(ts, id, x, y);
 	}
 
-err_sync_frame:
 	input_mt_sync_frame(input);
 	input_sync(input);
-	return error;
+
+	return 0;
 }
 
 /* APIs of cmds for ILITEK Touch IC */
--- linux-qcom-6.8.0.orig/drivers/input/touchscreen/imagis.c
+++ linux-qcom-6.8.0/drivers/input/touchscreen/imagis.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 
+#include <linux/bitfield.h>
 #include <linux/bits.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
@@ -23,12 +24,9 @@
 #define IST3038C_I2C_RETRY_COUNT	3
 #define IST3038C_MAX_FINGER_NUM		10
 #define IST3038C_X_MASK			GENMASK(23, 12)
-#define IST3038C_X_SHIFT		12
 #define IST3038C_Y_MASK			GENMASK(11, 0)
 #define IST3038C_AREA_MASK		GENMASK(27, 24)
-#define IST3038C_AREA_SHIFT		24
 #define IST3038C_FINGER_COUNT_MASK	GENMASK(15, 12)
-#define IST3038C_FINGER_COUNT_SHIFT	12
 #define IST3038C_FINGER_STATUS_MASK	GENMASK(9, 0)
 
 struct imagis_ts {
@@ -92,8 +90,7 @@
 		goto out;
 	}
 
-	finger_count = (intr_message & IST3038C_FINGER_COUNT_MASK) >>
-				IST3038C_FINGER_COUNT_SHIFT;
+	finger_count = FIELD_GET(IST3038C_FINGER_COUNT_MASK, intr_message);
 	if (finger_count > IST3038C_MAX_FINGER_NUM) {
 		dev_err(&ts->client->dev,
 			"finger count %d is more than maximum supported\n",
@@ -101,7 +98,7 @@
 		goto out;
 	}
 
-	finger_pressed = intr_message & IST3038C_FINGER_STATUS_MASK;
+	finger_pressed = FIELD_GET(IST3038C_FINGER_STATUS_MASK, intr_message);
 
 	for (i = 0; i < finger_count; i++) {
 		error = imagis_i2c_read_reg(ts,
@@ -118,12 +115,11 @@
 		input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER,
 					   finger_pressed & BIT(i));
 		touchscreen_report_pos(ts->input_dev, &ts->prop,
-				       (finger_status & IST3038C_X_MASK) >>
-						IST3038C_X_SHIFT,
-				       finger_status & IST3038C_Y_MASK, 1);
+				       FIELD_GET(IST3038C_X_MASK, finger_status),
+				       FIELD_GET(IST3038C_Y_MASK, finger_status),
+				       true);
 		input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
-				 (finger_status & IST3038C_AREA_MASK) >>
-					IST3038C_AREA_SHIFT);
+				 FIELD_GET(IST3038C_AREA_MASK, finger_status));
 	}
 
 	input_mt_sync_frame(ts->input_dev);
@@ -210,7 +206,7 @@
 
 	input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X);
 	input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y);
-	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
+	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 16, 0, 0);
 
 	touchscreen_parse_properties(input_dev, true, &ts->prop);
 	if (!ts->prop.max_x || !ts->prop.max_y) {
--- linux-qcom-6.8.0.orig/drivers/input/touchscreen/silead.c
+++ linux-qcom-6.8.0/drivers/input/touchscreen/silead.c
@@ -71,7 +71,6 @@
 	struct regulator_bulk_data regulators[2];
 	char fw_name[64];
 	struct touchscreen_properties prop;
-	u32 max_fingers;
 	u32 chip_id;
 	struct input_mt_pos pos[SILEAD_MAX_FINGERS];
 	int slots[SILEAD_MAX_FINGERS];
@@ -136,7 +135,7 @@
 	touchscreen_parse_properties(data->input, true, &data->prop);
 	silead_apply_efi_fw_min_max(data);
 
-	input_mt_init_slots(data->input, data->max_fingers,
+	input_mt_init_slots(data->input, SILEAD_MAX_FINGERS,
 			    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED |
 			    INPUT_MT_TRACK);
 
@@ -256,10 +255,10 @@
 		return;
 	}
 
-	if (buf[0] > data->max_fingers) {
+	if (buf[0] > SILEAD_MAX_FINGERS) {
 		dev_warn(dev, "More touches reported then supported %d > %d\n",
-			 buf[0], data->max_fingers);
-		buf[0] = data->max_fingers;
+			 buf[0], SILEAD_MAX_FINGERS);
+		buf[0] = SILEAD_MAX_FINGERS;
 	}
 
 	if (silead_ts_handle_pen_data(data, buf))
@@ -315,7 +314,6 @@
 
 static int silead_ts_init(struct i2c_client *client)
 {
-	struct silead_ts_data *data = i2c_get_clientdata(client);
 	int error;
 
 	error = i2c_smbus_write_byte_data(client, SILEAD_REG_RESET,
@@ -325,7 +323,7 @@
 	usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);
 
 	error = i2c_smbus_write_byte_data(client, SILEAD_REG_TOUCH_NR,
-					data->max_fingers);
+					  SILEAD_MAX_FINGERS);
 	if (error)
 		goto i2c_write_err;
 	usleep_range(SILEAD_CMD_SLEEP_MIN, SILEAD_CMD_SLEEP_MAX);
@@ -591,13 +589,6 @@
 	const char *str;
 	int error;
 
-	error = device_property_read_u32(dev, "silead,max-fingers",
-					 &data->max_fingers);
-	if (error) {
-		dev_dbg(dev, "Max fingers read error %d\n", error);
-		data->max_fingers = 5; /* Most devices handle up-to 5 fingers */
-	}
-
 	error = device_property_read_string(dev, "firmware-name", &str);
 	if (!error)
 		snprintf(data->fw_name, sizeof(data->fw_name),
--- linux-qcom-6.8.0.orig/drivers/interconnect/core.c
+++ linux-qcom-6.8.0/drivers/interconnect/core.c
@@ -176,6 +176,8 @@
 
 	path->num_nodes = num_nodes;
 
+	mutex_lock(&icc_bw_lock);
+
 	for (i = num_nodes - 1; i >= 0; i--) {
 		node->provider->users++;
 		hlist_add_head(&path->reqs[i].req_node, &node->req_list);
@@ -186,6 +188,8 @@
 		node = node->reverse;
 	}
 
+	mutex_unlock(&icc_bw_lock);
+
 	return path;
 }
 
@@ -792,12 +796,16 @@
 		pr_err("%s: error (%d)\n", __func__, ret);
 
 	mutex_lock(&icc_lock);
+	mutex_lock(&icc_bw_lock);
+
 	for (i = 0; i < path->num_nodes; i++) {
 		node = path->reqs[i].node;
 		hlist_del(&path->reqs[i].req_node);
 		if (!WARN_ON(!node->provider->users))
 			node->provider->users--;
 	}
+
+	mutex_unlock(&icc_bw_lock);
 	mutex_unlock(&icc_lock);
 
 	kfree_const(path->name);
--- linux-qcom-6.8.0.orig/drivers/interconnect/icc-clk.c
+++ linux-qcom-6.8.0/drivers/interconnect/icc-clk.c
@@ -87,6 +87,7 @@
 	onecell = devm_kzalloc(dev, struct_size(onecell, nodes, 2 * num_clocks), GFP_KERNEL);
 	if (!onecell)
 		return ERR_PTR(-ENOMEM);
+	onecell->num_nodes = 2 * num_clocks;
 
 	qp = devm_kzalloc(dev, struct_size(qp, clocks, num_clocks), GFP_KERNEL);
 	if (!qp)
@@ -133,8 +134,6 @@
 		onecell->nodes[j++] = node;
 	}
 
-	onecell->num_nodes = j;
-
 	ret = icc_provider_register(provider);
 	if (ret)
 		goto err;
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/Kconfig
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/Kconfig
@@ -69,6 +69,26 @@
 	  This is a driver for the Qualcomm Network-on-Chip on qcs404-based
 	  platforms.
 
+config INTERCONNECT_QCOM_QCS615
+	tristate "Qualcomm QCS615 interconnect driver"
+	depends on INTERCONNECT_QCOM_RPMH_POSSIBLE
+	select INTERCONNECT_QCOM_RPMH
+	select INTERCONNECT_QCOM_BCM_VOTER
+	help
+	  This is a driver for the Qualcomm Network-on-Chip on qcs615-based
+	  platforms.
+
+config INTERCONNECT_QCOM_QCS8300
+	tristate "Qualcomm QCS8300 interconnect driver"
+	depends on INTERCONNECT_QCOM_RPMH_POSSIBLE
+	select INTERCONNECT_QCOM_RPMH
+	select INTERCONNECT_QCOM_BCM_VOTER
+	help
+	  This is a driver for the Qualcomm Technologies, Inc. Network-on-Chip
+	  on QCS8300-based platforms. The interconnect provider collects and
+	  aggreagates the cosumer bandwidth requests to satisfy constraints
+	  placed on Network-on-Chip performance states.
+
 config INTERCONNECT_QCOM_QDU1000
 	tristate "Qualcomm QDU1000/QRU1000 interconnect driver"
 	depends on INTERCONNECT_QCOM_RPMH_POSSIBLE
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/Makefile
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/Makefile
@@ -11,6 +11,8 @@
 icc-osm-l3-objs				:= osm-l3.o
 qnoc-qcm2290-objs			:= qcm2290.o
 qnoc-qcs404-objs			:= qcs404.o
+qnoc-qcs615-objs			:= qcs615.o
+qnoc-qcs8300-objs			:= qcs8300.o
 qnoc-qdu1000-objs			:= qdu1000.o
 icc-rpmh-obj				:= icc-rpmh.o
 qnoc-sa8775p-objs			:= sa8775p.o
@@ -43,6 +45,8 @@
 obj-$(CONFIG_INTERCONNECT_QCOM_OSM_L3) += icc-osm-l3.o
 obj-$(CONFIG_INTERCONNECT_QCOM_QCM2290) += qnoc-qcm2290.o
 obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o
+obj-$(CONFIG_INTERCONNECT_QCOM_QCS615) += qnoc-qcs615.o
+obj-$(CONFIG_INTERCONNECT_QCOM_QCS8300) += qnoc-qcs8300.o
 obj-$(CONFIG_INTERCONNECT_QCOM_QDU1000) += qnoc-qdu1000.o
 obj-$(CONFIG_INTERCONNECT_QCOM_RPMH) += icc-rpmh.o
 obj-$(CONFIG_INTERCONNECT_QCOM_SA8775P) += qnoc-sa8775p.o
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/bcm-voter.c
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/bcm-voter.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <asm/div64.h>
@@ -62,6 +63,7 @@
 static void bcm_aggregate_mask(struct qcom_icc_bcm *bcm)
 {
 	struct qcom_icc_node *node;
+	bool perf_mode[QCOM_ICC_NUM_BUCKETS] = {0};
 	int bucket, i;
 
 	for (bucket = 0; bucket < QCOM_ICC_NUM_BUCKETS; bucket++) {
@@ -70,11 +72,16 @@
 
 		for (i = 0; i < bcm->num_nodes; i++) {
 			node = bcm->nodes[i];
+			perf_mode[bucket] |= node->perf_mode[bucket];
 
 			/* If any vote in this bucket exists, keep the BCM enabled */
 			if (node->sum_avg[bucket] || node->max_peak[bucket]) {
 				bcm->vote_x[bucket] = 0;
 				bcm->vote_y[bucket] = bcm->enable_mask;
+
+				if (perf_mode[bucket])
+					bcm->vote_y[bucket] |= bcm->perf_mode_mask;
+
 				break;
 			}
 		}
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/icc-rpmh.c
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/icc-rpmh.c
@@ -1,8 +1,10 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
+#include <linux/clk.h>
 #include <linux/interconnect.h>
 #include <linux/interconnect-provider.h>
 #include <linux/module.h>
@@ -14,6 +16,43 @@
 #include "icc-common.h"
 #include "icc-rpmh.h"
 
+/* QNOC QoS */
+#define QOSGEN_MAINCTL_LO(p, qp)	(0x8 + (p->offsets[qp]))
+#define QOS_SLV_URG_MSG_EN_SHFT		3
+#define QOS_DFLT_PRIO_MASK		0x7
+#define QOS_DFLT_PRIO_SHFT		4
+#define QOS_DISABLE_SHIFT		24
+
+/**
+ * qcom_icc_set_qos - initialize static QoS configurations
+ * @node: qcom icc node to operate on
+ */
+static void qcom_icc_set_qos(struct qcom_icc_node *node)
+{
+	struct qcom_icc_qosbox *qos = node->qosbox;
+	int port;
+
+	if (!node->regmap)
+		return;
+
+	if (!qos)
+		return;
+
+	for (port = 0; port < qos->num_ports; port++) {
+		regmap_update_bits(node->regmap, QOSGEN_MAINCTL_LO(qos, port),
+				   BIT(QOS_DISABLE_SHIFT),
+				   qos->prio_fwd_disable << QOS_DISABLE_SHIFT);
+
+		regmap_update_bits(node->regmap, QOSGEN_MAINCTL_LO(qos, port),
+				   QOS_DFLT_PRIO_MASK << QOS_DFLT_PRIO_SHFT,
+				   qos->prio << QOS_DFLT_PRIO_SHFT);
+
+		regmap_update_bits(node->regmap, QOSGEN_MAINCTL_LO(qos, port),
+				   BIT(QOS_SLV_URG_MSG_EN_SHFT),
+				   qos->urg_fwd << QOS_SLV_URG_MSG_EN_SHFT);
+	}
+}
+
 /**
  * qcom_icc_pre_aggregate - cleans up stale values from prior icc_set
  * @node: icc node to operate on
@@ -30,6 +69,7 @@
 	for (i = 0; i < QCOM_ICC_NUM_BUCKETS; i++) {
 		qn->sum_avg[i] = 0;
 		qn->max_peak[i] = 0;
+		qn->perf_mode[i] = false;
 	}
 
 	for (i = 0; i < qn->num_bcms; i++)
@@ -61,6 +101,8 @@
 		if (tag & BIT(i)) {
 			qn->sum_avg[i] += avg_bw;
 			qn->max_peak[i] = max_t(u32, qn->max_peak[i], peak_bw);
+			if (tag & QCOM_ICC_TAG_PERF_MODE && (avg_bw || peak_bw))
+				qn->perf_mode[i] = true;
 		}
 
 		if (node->init_avg || node->init_peak) {
@@ -159,6 +201,113 @@
 }
 EXPORT_SYMBOL_GPL(qcom_icc_bcm_init);
 
+static bool bcm_needs_qos_proxy(struct qcom_icc_bcm *bcm)
+{
+	int i;
+
+	for (i = 0; i < bcm->num_nodes; i++)
+		if (bcm->nodes[i]->qosbox)
+			return true;
+
+	return false;
+}
+
+static int enable_qos_deps(struct qcom_icc_provider *qp)
+{
+	struct qcom_icc_bcm *bcm;
+	bool keepalive;
+	int ret, i;
+
+	for (i = 0; i < qp->num_bcms; i++) {
+		bcm = qp->bcms[i];
+		if (bcm_needs_qos_proxy(bcm)) {
+			keepalive = bcm->keepalive;
+			bcm->keepalive = true;
+
+			qcom_icc_bcm_voter_add(qp->voter, bcm);
+			ret = qcom_icc_bcm_voter_commit(qp->voter);
+
+			bcm->keepalive = keepalive;
+
+			if (ret) {
+				dev_err(qp->dev, "failed to vote BW to %s for QoS\n",
+					bcm->name);
+				return ret;
+			}
+		}
+	}
+
+	ret = clk_bulk_prepare_enable(qp->num_clks, qp->clks);
+	if (ret) {
+		dev_err(qp->dev, "failed to enable clocks for QoS\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void disable_qos_deps(struct qcom_icc_provider *qp)
+{
+	struct qcom_icc_bcm *bcm;
+	int i;
+
+	clk_bulk_disable_unprepare(qp->num_clks, qp->clks);
+
+	for (i = 0; i < qp->num_bcms; i++) {
+		bcm = qp->bcms[i];
+		if (bcm_needs_qos_proxy(bcm)) {
+			qcom_icc_bcm_voter_add(qp->voter, bcm);
+			qcom_icc_bcm_voter_commit(qp->voter);
+		}
+	}
+}
+
+int qcom_icc_rpmh_configure_qos(struct qcom_icc_provider *qp)
+{
+	struct qcom_icc_node *qnode;
+	size_t i;
+	int ret;
+
+	ret = enable_qos_deps(qp);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < qp->num_nodes; i++) {
+		qnode = qp->nodes[i];
+		if (!qnode)
+			continue;
+
+		if (qnode->qosbox)
+			qcom_icc_set_qos(qnode);
+	}
+
+	disable_qos_deps(qp);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_icc_rpmh_configure_qos);
+
+static struct regmap *qcom_icc_rpmh_map(struct platform_device *pdev,
+					const struct qcom_icc_desc *desc)
+{
+	void __iomem *base;
+	struct resource *res;
+	struct device *dev = &pdev->dev;
+
+	if (!desc->config)
+		return NULL;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return NULL;
+
+	base = devm_ioremap(dev, res->start, resource_size(res));
+	if (IS_ERR(base))
+		return ERR_CAST(base);
+
+	return devm_regmap_init_mmio(dev, base, desc->config);
+}
+
 int qcom_icc_rpmh_probe(struct platform_device *pdev)
 {
 	const struct qcom_icc_desc *desc;
@@ -199,12 +348,22 @@
 
 	qp->dev = dev;
 	qp->bcms = desc->bcms;
+	qp->nodes = desc->nodes;
 	qp->num_bcms = desc->num_bcms;
+	qp->num_nodes = desc->num_nodes;
 
 	qp->voter = of_bcm_voter_get(qp->dev, NULL);
 	if (IS_ERR(qp->voter))
 		return PTR_ERR(qp->voter);
 
+	qp->regmap = qcom_icc_rpmh_map(pdev, desc);
+	if (IS_ERR(qp->regmap))
+		return PTR_ERR(qp->regmap);
+
+	qp->num_clks = devm_clk_bulk_get_all(qp->dev, &qp->clks);
+	if (qp->num_clks < 0)
+		return qp->num_clks;
+
 	for (i = 0; i < qp->num_bcms; i++)
 		qcom_icc_bcm_init(qp->bcms[i], dev);
 
@@ -213,6 +372,8 @@
 		if (!qn)
 			continue;
 
+		qn->regmap = dev_get_regmap(qp->dev, NULL);
+
 		node = icc_node_create(qn->id);
 		if (IS_ERR(node)) {
 			ret = PTR_ERR(node);
@@ -229,6 +390,10 @@
 		data->nodes[i] = node;
 	}
 
+	ret = qcom_icc_rpmh_configure_qos(qp);
+	if (ret)
+		goto err_remove_nodes;
+
 	ret = icc_provider_register(provider);
 	if (ret)
 		goto err_remove_nodes;
@@ -247,6 +412,7 @@
 err_deregister_provider:
 	icc_provider_deregister(provider);
 err_remove_nodes:
+	clk_bulk_put_all(qp->num_clks, qp->clks);
 	icc_nodes_remove(provider);
 
 	return ret;
@@ -258,6 +424,7 @@
 	struct qcom_icc_provider *qp = platform_get_drvdata(pdev);
 
 	icc_provider_deregister(&qp->provider);
+	clk_bulk_put_all(qp->num_clks, qp->clks);
 	icc_nodes_remove(&qp->provider);
 }
 EXPORT_SYMBOL_GPL(qcom_icc_rpmh_remove);
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/icc-rpmh.h
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/icc-rpmh.h
@@ -1,12 +1,14 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef __DRIVERS_INTERCONNECT_QCOM_ICC_RPMH_H__
 #define __DRIVERS_INTERCONNECT_QCOM_ICC_RPMH_H__
 
 #include <dt-bindings/interconnect/qcom,icc.h>
+#include <linux/regmap.h>
 
 #define to_qcom_provider(_provider) \
 	container_of(_provider, struct qcom_icc_provider, provider)
@@ -18,6 +20,11 @@
  * @bcms: list of bcms that maps to the provider
  * @num_bcms: number of @bcms
  * @voter: bcm voter targeted by this provider
+ * @nodes: list of icc nodes that maps to the provider
+ * @num_nodes: number of @nodes
+ * @regmap: used for NOC registers access
+ * @clks : clks required for register access
+ * @num_clks: number of @clks
  */
 struct qcom_icc_provider {
 	struct icc_provider provider;
@@ -25,6 +32,11 @@
 	struct qcom_icc_bcm * const *bcms;
 	size_t num_bcms;
 	struct bcm_voter *voter;
+	struct qcom_icc_node * const *nodes;
+	size_t num_nodes;
+	struct regmap *regmap;
+	struct clk_bulk_data *clks;
+	int num_clks;
 };
 
 /**
@@ -41,6 +53,23 @@
 	u8 reserved;
 };
 
+/**
+ * struct qcom_icc_qosbox - Qualcomm Technologies, Inc specific QoS config
+ * @prio: priority value assigned to requests on the node
+ * @urg_fwd: if set, master priority is used for requests.
+ * @prio_fwd_disable: if set, master priority is ignored and NOCs default priority is used.
+ * @num_ports: number of @ports
+ * @offsets: qos register offsets
+ */
+
+struct qcom_icc_qosbox {
+	u32 prio;
+	u32 urg_fwd;
+	bool prio_fwd_disable;
+	u32 num_ports;
+	u32 offsets[];
+};
+
 #define MAX_LINKS		128
 #define MAX_BCMS		64
 #define MAX_BCM_PER_NODE	3
@@ -56,8 +85,11 @@
  * @buswidth: width of the interconnect between a node and the bus
  * @sum_avg: current sum aggregate value of all avg bw requests
  * @max_peak: current max aggregate value of all peak bw requests
+ * @perf_mode: current OR aggregate value of all QCOM_ICC_TAG_PERF_MODE votes
  * @bcms: list of bcms associated with this logical node
  * @num_bcms: num of @bcms
+ * @regmap: used for NOC registers access
+ * @qosbox: qos config data associated with node
  */
 struct qcom_icc_node {
 	const char *name;
@@ -68,8 +100,11 @@
 	u16 buswidth;
 	u64 sum_avg[QCOM_ICC_NUM_BUCKETS];
 	u64 max_peak[QCOM_ICC_NUM_BUCKETS];
+	bool perf_mode[QCOM_ICC_NUM_BUCKETS];
 	struct qcom_icc_bcm *bcms[MAX_BCM_PER_NODE];
 	size_t num_bcms;
+	struct regmap *regmap;
+	struct qcom_icc_qosbox *qosbox;
 };
 
 /**
@@ -82,6 +117,7 @@
  * @vote_y: aggregated threshold values, represents peak_bw when @type is bw bcm
  * @vote_scale: scaling factor for vote_x and vote_y
  * @enable_mask: optional mask to send as vote instead of vote_x/vote_y
+ * @perf_mode_mask: mask to OR with enable_mask when QCOM_ICC_TAG_PERF_MODE is set
  * @dirty: flag used to indicate whether the bcm needs to be committed
  * @keepalive: flag used to indicate whether a keepalive is required
  * @aux_data: auxiliary data used when calculating threshold values and
@@ -99,6 +135,7 @@
 	u64 vote_y[QCOM_ICC_NUM_BUCKETS];
 	u64 vote_scale;
 	u32 enable_mask;
+	u32 perf_mode_mask;
 	bool dirty;
 	bool keepalive;
 	struct bcm_db aux_data;
@@ -114,6 +151,7 @@
 };
 
 struct qcom_icc_desc {
+	const struct regmap_config *config;
 	struct qcom_icc_node * const *nodes;
 	size_t num_nodes;
 	struct qcom_icc_bcm * const *bcms;
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/osm-l3.c
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/osm-l3.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/args.h>
@@ -74,6 +75,11 @@
 	OSM_L3_SLAVE_NODE,
 };
 
+enum {
+	EPSS_L3_CL1_MASTER_NODE = 20000,
+	EPSS_L3_CL1_SLAVE_NODE,
+};
+
 #define DEFINE_QNODE(_name, _id, _buswidth, ...)			\
 	static const struct qcom_osm_l3_node _name = {			\
 		.name = #_name,						\
@@ -99,6 +105,14 @@
 	[SLAVE_EPSS_L3_SHARED] = &epss_l3_slave,
 };
 
+DEFINE_QNODE(epss_l3_cl1_master, EPSS_L3_CL1_MASTER_NODE, 32, EPSS_L3_CL1_SLAVE_NODE);
+DEFINE_QNODE(epss_l3_cl1_slave, EPSS_L3_CL1_SLAVE_NODE, 32);
+
+static const struct qcom_osm_l3_node * const epss_l3_cl1_nodes[] = {
+	[MASTER_EPSS_L3_APPS] = &epss_l3_cl1_master,
+	[SLAVE_EPSS_L3_SHARED] = &epss_l3_cl1_slave,
+};
+
 static const struct qcom_osm_l3_desc osm_l3 = {
 	.nodes = osm_l3_nodes,
 	.num_nodes = ARRAY_SIZE(osm_l3_nodes),
@@ -115,6 +129,14 @@
 	.reg_perf_state = EPSS_REG_PERF_STATE,
 };
 
+static const struct qcom_osm_l3_desc epss_l3_cl1_perf_state = {
+	.nodes = epss_l3_cl1_nodes,
+	.num_nodes = ARRAY_SIZE(epss_l3_cl1_nodes),
+	.lut_row_size = EPSS_LUT_ROW_SIZE,
+	.reg_freq_lut = EPSS_REG_FREQ_LUT,
+	.reg_perf_state = EPSS_REG_PERF_STATE,
+};
+
 static const struct qcom_osm_l3_desc epss_l3_l3_vote = {
 	.nodes = epss_l3_nodes,
 	.num_nodes = ARRAY_SIZE(epss_l3_nodes),
@@ -284,6 +306,8 @@
 	{ .compatible = "qcom,sm8150-osm-l3", .data = &osm_l3 },
 	{ .compatible = "qcom,sc8180x-osm-l3", .data = &osm_l3 },
 	{ .compatible = "qcom,sm8250-epss-l3", .data = &epss_l3_perf_state },
+	{ .compatible = "qcom,sa8775p-epss-l3-cl0", .data = &epss_l3_perf_state },
+	{ .compatible = "qcom,sa8775p-epss-l3-cl1", .data = &epss_l3_cl1_perf_state },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, osm_l3_of_match);
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/qcm2290.c
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/qcm2290.c
@@ -164,9 +164,9 @@
 	.name = "mas_snoc_bimc",
 	.buswidth = 16,
 	.qos.ap_owned = true,
-	.qos.qos_port = 2,
+	.qos.qos_port = 6,
 	.qos.qos_mode = NOC_QOS_MODE_BYPASS,
-	.mas_rpm_id = 164,
+	.mas_rpm_id = 3,
 	.slv_rpm_id = -1,
 	.num_links = ARRAY_SIZE(mas_snoc_bimc_links),
 	.links = mas_snoc_bimc_links,
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/qcs615.c
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/qcs615.c
@@ -0,0 +1,1563 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/interconnect.h>
+#include <linux/interconnect-provider.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <dt-bindings/interconnect/qcom,qcs615-rpmh.h>
+
+#include "bcm-voter.h"
+#include "icc-rpmh.h"
+#include "qcs615.h"
+
+static struct qcom_icc_node qhm_a1noc_cfg = {
+	.name = "qhm_a1noc_cfg",
+	.id = QCS615_MASTER_A1NOC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_SERVICE_A2NOC },
+};
+
+static struct qcom_icc_node qhm_qdss_bam = {
+	.name = "qhm_qdss_bam",
+	.id = QCS615_MASTER_QDSS_BAM,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node qhm_qspi = {
+	.name = "qhm_qspi",
+	.id = QCS615_MASTER_QSPI,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node qhm_qup0 = {
+	.name = "qhm_qup0",
+	.id = QCS615_MASTER_QUP_0,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node qhm_qup1 = {
+	.name = "qhm_qup1",
+	.id = QCS615_MASTER_BLSP_1,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node qnm_cnoc = {
+	.name = "qnm_cnoc",
+	.id = QCS615_MASTER_CNOC_A2NOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node qxm_crypto = {
+	.name = "qxm_crypto",
+	.id = QCS615_MASTER_CRYPTO,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node qxm_ipa = {
+	.name = "qxm_ipa",
+	.id = QCS615_MASTER_IPA,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_LPASS_SNOC },
+};
+
+static struct qcom_icc_node xm_emac_avb = {
+	.name = "xm_emac_avb",
+	.id = QCS615_MASTER_EMAC_EVB,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node xm_pcie = {
+	.name = "xm_pcie",
+	.id = QCS615_MASTER_PCIE,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_ANOC_PCIE_SNOC },
+};
+
+static struct qcom_icc_node xm_qdss_etr = {
+	.name = "xm_qdss_etr",
+	.id = QCS615_MASTER_QDSS_ETR,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node xm_sdc1 = {
+	.name = "xm_sdc1",
+	.id = QCS615_MASTER_SDCC_1,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node xm_sdc2 = {
+	.name = "xm_sdc2",
+	.id = QCS615_MASTER_SDCC_2,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node xm_ufs_mem = {
+	.name = "xm_ufs_mem",
+	.id = QCS615_MASTER_UFS_MEM,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node xm_usb2 = {
+	.name = "xm_usb2",
+	.id = QCS615_MASTER_USB2,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node xm_usb3_0 = {
+	.name = "xm_usb3_0",
+	.id = QCS615_MASTER_USB3_0,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node qxm_camnoc_hf0_uncomp = {
+	.name = "qxm_camnoc_hf0_uncomp",
+	.id = QCS615_MASTER_CAMNOC_HF0_UNCOMP,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_CAMNOC_UNCOMP },
+};
+
+static struct qcom_icc_node qxm_camnoc_hf1_uncomp = {
+	.name = "qxm_camnoc_hf1_uncomp",
+	.id = QCS615_MASTER_CAMNOC_HF1_UNCOMP,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_CAMNOC_UNCOMP },
+};
+
+static struct qcom_icc_node qxm_camnoc_sf_uncomp = {
+	.name = "qxm_camnoc_sf_uncomp",
+	.id = QCS615_MASTER_CAMNOC_SF_UNCOMP,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_CAMNOC_UNCOMP },
+};
+
+static struct qcom_icc_node qhm_spdm = {
+	.name = "qhm_spdm",
+	.id = QCS615_MASTER_SPDM,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_CNOC_A2NOC },
+};
+
+static struct qcom_icc_node qnm_snoc = {
+	.name = "qnm_snoc",
+	.id = QCS615_MASTER_SNOC_CNOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 39,
+	.links = { QCS615_SLAVE_A1NOC_CFG, QCS615_SLAVE_AHB2PHY_EAST,
+		   QCS615_SLAVE_AHB2PHY_WEST, QCS615_SLAVE_AOP,
+		   QCS615_SLAVE_AOSS, QCS615_SLAVE_CAMERA_CFG,
+		   QCS615_SLAVE_CLK_CTL, QCS615_SLAVE_RBCPR_CX_CFG,
+		   QCS615_SLAVE_RBCPR_MX_CFG, QCS615_SLAVE_CRYPTO_0_CFG,
+		   QCS615_SLAVE_CNOC_DDRSS, QCS615_SLAVE_DISPLAY_CFG,
+		   QCS615_SLAVE_EMAC_AVB_CFG, QCS615_SLAVE_GLM,
+		   QCS615_SLAVE_GFX3D_CFG, QCS615_SLAVE_IMEM_CFG,
+		   QCS615_SLAVE_IPA_CFG, QCS615_SLAVE_CNOC_MNOC_CFG,
+		   QCS615_SLAVE_PCIE_CFG, QCS615_SLAVE_PIMEM_CFG,
+		   QCS615_SLAVE_PRNG, QCS615_SLAVE_QDSS_CFG,
+		   QCS615_SLAVE_QSPI, QCS615_SLAVE_QUP_0,
+		   QCS615_SLAVE_QUP_1, QCS615_SLAVE_SDCC_1,
+		   QCS615_SLAVE_SDCC_2, QCS615_SLAVE_SNOC_CFG,
+		   QCS615_SLAVE_SPDM_WRAPPER, QCS615_SLAVE_TCSR,
+		   QCS615_SLAVE_TLMM_EAST, QCS615_SLAVE_TLMM_SOUTH,
+		   QCS615_SLAVE_TLMM_WEST, QCS615_SLAVE_UFS_MEM_CFG,
+		   QCS615_SLAVE_USB2, QCS615_SLAVE_USB3,
+		   QCS615_SLAVE_VENUS_CFG, QCS615_SLAVE_VSENSE_CTRL_CFG,
+		   QCS615_SLAVE_SERVICE_CNOC },
+};
+
+static struct qcom_icc_node xm_qdss_dap = {
+	.name = "xm_qdss_dap",
+	.id = QCS615_MASTER_QDSS_DAP,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 40,
+	.links = { QCS615_SLAVE_A1NOC_CFG, QCS615_SLAVE_AHB2PHY_EAST,
+		   QCS615_SLAVE_AHB2PHY_WEST, QCS615_SLAVE_AOP,
+		   QCS615_SLAVE_AOSS, QCS615_SLAVE_CAMERA_CFG,
+		   QCS615_SLAVE_CLK_CTL, QCS615_SLAVE_RBCPR_CX_CFG,
+		   QCS615_SLAVE_RBCPR_MX_CFG, QCS615_SLAVE_CRYPTO_0_CFG,
+		   QCS615_SLAVE_CNOC_DDRSS, QCS615_SLAVE_DISPLAY_CFG,
+		   QCS615_SLAVE_EMAC_AVB_CFG, QCS615_SLAVE_GLM,
+		   QCS615_SLAVE_GFX3D_CFG, QCS615_SLAVE_IMEM_CFG,
+		   QCS615_SLAVE_IPA_CFG, QCS615_SLAVE_CNOC_MNOC_CFG,
+		   QCS615_SLAVE_PCIE_CFG, QCS615_SLAVE_PIMEM_CFG,
+		   QCS615_SLAVE_PRNG, QCS615_SLAVE_QDSS_CFG,
+		   QCS615_SLAVE_QSPI, QCS615_SLAVE_QUP_0,
+		   QCS615_SLAVE_QUP_1, QCS615_SLAVE_SDCC_1,
+		   QCS615_SLAVE_SDCC_2, QCS615_SLAVE_SNOC_CFG,
+		   QCS615_SLAVE_SPDM_WRAPPER, QCS615_SLAVE_TCSR,
+		   QCS615_SLAVE_TLMM_EAST, QCS615_SLAVE_TLMM_SOUTH,
+		   QCS615_SLAVE_TLMM_WEST, QCS615_SLAVE_UFS_MEM_CFG,
+		   QCS615_SLAVE_USB2, QCS615_SLAVE_USB3,
+		   QCS615_SLAVE_VENUS_CFG, QCS615_SLAVE_VSENSE_CTRL_CFG,
+		   QCS615_SLAVE_CNOC_A2NOC, QCS615_SLAVE_SERVICE_CNOC },
+};
+
+static struct qcom_icc_node qhm_cnoc = {
+	.name = "qhm_cnoc",
+	.id = QCS615_MASTER_CNOC_DC_NOC,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 2,
+	.links = { QCS615_SLAVE_DC_NOC_GEMNOC, QCS615_SLAVE_LLCC_CFG },
+};
+
+static struct qcom_icc_node acm_apps = {
+	.name = "acm_apps",
+	.id = QCS615_MASTER_APPSS_PROC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 3,
+	.links = { QCS615_SLAVE_GEM_NOC_SNOC, QCS615_SLAVE_LLCC,
+		   QCS615_SLAVE_MEM_NOC_PCIE_SNOC },
+};
+
+static struct qcom_icc_node acm_gpu_tcu = {
+	.name = "acm_gpu_tcu",
+	.id = QCS615_MASTER_GPU_TCU,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 2,
+	.links = { QCS615_SLAVE_GEM_NOC_SNOC, QCS615_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node acm_sys_tcu = {
+	.name = "acm_sys_tcu",
+	.id = QCS615_MASTER_SYS_TCU,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 2,
+	.links = { QCS615_SLAVE_GEM_NOC_SNOC, QCS615_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node qhm_gemnoc_cfg = {
+	.name = "qhm_gemnoc_cfg",
+	.id = QCS615_MASTER_GEM_NOC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 2,
+	.links = { QCS615_SLAVE_MSS_PROC_MS_MPU_CFG, QCS615_SLAVE_SERVICE_GEM_NOC },
+};
+
+static struct qcom_icc_node qnm_gpu = {
+	.name = "qnm_gpu",
+	.id = QCS615_MASTER_GFX3D,
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 2,
+	.links = { QCS615_SLAVE_GEM_NOC_SNOC, QCS615_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node qnm_mnoc_hf = {
+	.name = "qnm_mnoc_hf",
+	.id = QCS615_MASTER_MNOC_HF_MEM_NOC,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node qnm_mnoc_sf = {
+	.name = "qnm_mnoc_sf",
+	.id = QCS615_MASTER_MNOC_SF_MEM_NOC,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 2,
+	.links = { QCS615_SLAVE_GEM_NOC_SNOC, QCS615_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node qnm_snoc_gc = {
+	.name = "qnm_snoc_gc",
+	.id = QCS615_MASTER_SNOC_GC_MEM_NOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node qnm_snoc_sf = {
+	.name = "qnm_snoc_sf",
+	.id = QCS615_MASTER_SNOC_SF_MEM_NOC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node ipa_core_master = {
+	.name = "ipa_core_master",
+	.id = QCS615_MASTER_IPA_CORE,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_IPA_CORE },
+};
+
+static struct qcom_icc_node llcc_mc = {
+	.name = "llcc_mc",
+	.id = QCS615_MASTER_LLCC,
+	.channels = 2,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_EBI1 },
+};
+
+static struct qcom_icc_node qhm_mnoc_cfg = {
+	.name = "qhm_mnoc_cfg",
+	.id = QCS615_MASTER_CNOC_MNOC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_SERVICE_MNOC },
+};
+
+static struct qcom_icc_node qxm_camnoc_hf0 = {
+	.name = "qxm_camnoc_hf0",
+	.id = QCS615_MASTER_CAMNOC_HF0,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_MNOC_HF_MEM_NOC },
+};
+
+static struct qcom_icc_node qxm_camnoc_hf1 = {
+	.name = "qxm_camnoc_hf1",
+	.id = QCS615_MASTER_CAMNOC_HF1,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_MNOC_HF_MEM_NOC },
+};
+
+static struct qcom_icc_node qxm_camnoc_sf = {
+	.name = "qxm_camnoc_sf",
+	.id = QCS615_MASTER_CAMNOC_SF,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_MNOC_SF_MEM_NOC },
+};
+
+static struct qcom_icc_node qxm_mdp0 = {
+	.name = "qxm_mdp0",
+	.id = QCS615_MASTER_MDP0,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_MNOC_HF_MEM_NOC },
+};
+
+static struct qcom_icc_node qxm_rot = {
+	.name = "qxm_rot",
+	.id = QCS615_MASTER_ROTATOR,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_MNOC_SF_MEM_NOC },
+};
+
+static struct qcom_icc_node qxm_venus0 = {
+	.name = "qxm_venus0",
+	.id = QCS615_MASTER_VIDEO_P0,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_MNOC_SF_MEM_NOC },
+};
+
+static struct qcom_icc_node qxm_venus_arm9 = {
+	.name = "qxm_venus_arm9",
+	.id = QCS615_MASTER_VIDEO_PROC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_MNOC_SF_MEM_NOC },
+};
+
+static struct qcom_icc_node qhm_snoc_cfg = {
+	.name = "qhm_snoc_cfg",
+	.id = QCS615_MASTER_SNOC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_SERVICE_SNOC },
+};
+
+static struct qcom_icc_node qnm_aggre1_noc = {
+	.name = "qnm_aggre1_noc",
+	.id = QCS615_MASTER_A1NOC_SNOC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 8,
+	.links = { QCS615_SLAVE_APPSS, QCS615_SLAVE_SNOC_CNOC,
+		   QCS615_SLAVE_SNOC_GEM_NOC_SF, QCS615_SLAVE_IMEM,
+		   QCS615_SLAVE_PIMEM, QCS615_SLAVE_PCIE_0,
+		   QCS615_SLAVE_QDSS_STM, QCS615_SLAVE_TCU },
+};
+
+static struct qcom_icc_node qnm_gemnoc = {
+	.name = "qnm_gemnoc",
+	.id = QCS615_MASTER_GEM_NOC_SNOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 6,
+	.links = { QCS615_SLAVE_APPSS, QCS615_SLAVE_SNOC_CNOC,
+		   QCS615_SLAVE_IMEM, QCS615_SLAVE_PIMEM,
+		   QCS615_SLAVE_QDSS_STM, QCS615_SLAVE_TCU },
+};
+
+static struct qcom_icc_node qnm_gemnoc_pcie = {
+	.name = "qnm_gemnoc_pcie",
+	.id = QCS615_MASTER_GEM_NOC_PCIE_SNOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_SLAVE_PCIE_0 },
+};
+
+static struct qcom_icc_node qnm_lpass_anoc = {
+	.name = "qnm_lpass_anoc",
+	.id = QCS615_MASTER_LPASS_ANOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 7,
+	.links = { QCS615_SLAVE_APPSS, QCS615_SLAVE_SNOC_CNOC,
+		   QCS615_SLAVE_SNOC_GEM_NOC_SF, QCS615_SLAVE_IMEM,
+		   QCS615_SLAVE_PIMEM, QCS615_SLAVE_PCIE_0,
+		   QCS615_SLAVE_QDSS_STM },
+};
+
+static struct qcom_icc_node qnm_pcie_anoc = {
+	.name = "qnm_pcie_anoc",
+	.id = QCS615_MASTER_ANOC_PCIE_SNOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 5,
+	.links = { QCS615_SLAVE_APPSS, QCS615_SLAVE_SNOC_CNOC,
+		   QCS615_SLAVE_SNOC_GEM_NOC_SF, QCS615_SLAVE_IMEM,
+		   QCS615_SLAVE_QDSS_STM },
+};
+
+static struct qcom_icc_node qxm_pimem = {
+	.name = "qxm_pimem",
+	.id = QCS615_MASTER_PIMEM,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 2,
+	.links = { QCS615_SLAVE_SNOC_MEM_NOC_GC, QCS615_SLAVE_IMEM },
+};
+
+static struct qcom_icc_node xm_gic = {
+	.name = "xm_gic",
+	.id = QCS615_MASTER_GIC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 2,
+	.links = { QCS615_SLAVE_SNOC_MEM_NOC_GC, QCS615_SLAVE_IMEM },
+};
+
+static struct qcom_icc_node qns_a1noc_snoc = {
+	.name = "qns_a1noc_snoc",
+	.id = QCS615_SLAVE_A1NOC_SNOC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS615_MASTER_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node qns_lpass_snoc = {
+	.name = "qns_lpass_snoc",
+	.id = QCS615_SLAVE_LPASS_SNOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_MASTER_LPASS_ANOC },
+};
+
+static struct qcom_icc_node qns_pcie_snoc = {
+	.name = "qns_pcie_snoc",
+	.id = QCS615_SLAVE_ANOC_PCIE_SNOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_MASTER_ANOC_PCIE_SNOC },
+};
+
+static struct qcom_icc_node srvc_aggre2_noc = {
+	.name = "srvc_aggre2_noc",
+	.id = QCS615_SLAVE_SERVICE_A2NOC,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns_camnoc_uncomp = {
+	.name = "qns_camnoc_uncomp",
+	.id = QCS615_SLAVE_CAMNOC_UNCOMP,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_a1_noc_cfg = {
+	.name = "qhs_a1_noc_cfg",
+	.id = QCS615_SLAVE_A1NOC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS615_MASTER_A1NOC_CFG },
+};
+
+static struct qcom_icc_node qhs_ahb2phy_east = {
+	.name = "qhs_ahb2phy_east",
+	.id = QCS615_SLAVE_AHB2PHY_EAST,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_ahb2phy_west = {
+	.name = "qhs_ahb2phy_west",
+	.id = QCS615_SLAVE_AHB2PHY_WEST,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_aop = {
+	.name = "qhs_aop",
+	.id = QCS615_SLAVE_AOP,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_aoss = {
+	.name = "qhs_aoss",
+	.id = QCS615_SLAVE_AOSS,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_camera_cfg = {
+	.name = "qhs_camera_cfg",
+	.id = QCS615_SLAVE_CAMERA_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_clk_ctl = {
+	.name = "qhs_clk_ctl",
+	.id = QCS615_SLAVE_CLK_CTL,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_cpr_cx = {
+	.name = "qhs_cpr_cx",
+	.id = QCS615_SLAVE_RBCPR_CX_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_cpr_mx = {
+	.name = "qhs_cpr_mx",
+	.id = QCS615_SLAVE_RBCPR_MX_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_crypto0_cfg = {
+	.name = "qhs_crypto0_cfg",
+	.id = QCS615_SLAVE_CRYPTO_0_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_ddrss_cfg = {
+	.name = "qhs_ddrss_cfg",
+	.id = QCS615_SLAVE_CNOC_DDRSS,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS615_MASTER_CNOC_DC_NOC },
+};
+
+static struct qcom_icc_node qhs_display_cfg = {
+	.name = "qhs_display_cfg",
+	.id = QCS615_SLAVE_DISPLAY_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_emac_avb_cfg = {
+	.name = "qhs_emac_avb_cfg",
+	.id = QCS615_SLAVE_EMAC_AVB_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_glm = {
+	.name = "qhs_glm",
+	.id = QCS615_SLAVE_GLM,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_gpuss_cfg = {
+	.name = "qhs_gpuss_cfg",
+	.id = QCS615_SLAVE_GFX3D_CFG,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_imem_cfg = {
+	.name = "qhs_imem_cfg",
+	.id = QCS615_SLAVE_IMEM_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_ipa = {
+	.name = "qhs_ipa",
+	.id = QCS615_SLAVE_IPA_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_mnoc_cfg = {
+	.name = "qhs_mnoc_cfg",
+	.id = QCS615_SLAVE_CNOC_MNOC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS615_MASTER_CNOC_MNOC_CFG },
+};
+
+static struct qcom_icc_node qhs_pcie_config = {
+	.name = "qhs_pcie_config",
+	.id = QCS615_SLAVE_PCIE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_pimem_cfg = {
+	.name = "qhs_pimem_cfg",
+	.id = QCS615_SLAVE_PIMEM_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_prng = {
+	.name = "qhs_prng",
+	.id = QCS615_SLAVE_PRNG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_qdss_cfg = {
+	.name = "qhs_qdss_cfg",
+	.id = QCS615_SLAVE_QDSS_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_qspi = {
+	.name = "qhs_qspi",
+	.id = QCS615_SLAVE_QSPI,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_qup0 = {
+	.name = "qhs_qup0",
+	.id = QCS615_SLAVE_QUP_0,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_qup1 = {
+	.name = "qhs_qup1",
+	.id = QCS615_SLAVE_QUP_1,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_sdc1 = {
+	.name = "qhs_sdc1",
+	.id = QCS615_SLAVE_SDCC_1,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_sdc2 = {
+	.name = "qhs_sdc2",
+	.id = QCS615_SLAVE_SDCC_2,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_snoc_cfg = {
+	.name = "qhs_snoc_cfg",
+	.id = QCS615_SLAVE_SNOC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS615_MASTER_SNOC_CFG },
+};
+
+static struct qcom_icc_node qhs_spdm = {
+	.name = "qhs_spdm",
+	.id = QCS615_SLAVE_SPDM_WRAPPER,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_tcsr = {
+	.name = "qhs_tcsr",
+	.id = QCS615_SLAVE_TCSR,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_tlmm_east = {
+	.name = "qhs_tlmm_east",
+	.id = QCS615_SLAVE_TLMM_EAST,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_tlmm_south = {
+	.name = "qhs_tlmm_south",
+	.id = QCS615_SLAVE_TLMM_SOUTH,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_tlmm_west = {
+	.name = "qhs_tlmm_west",
+	.id = QCS615_SLAVE_TLMM_WEST,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_ufs_mem_cfg = {
+	.name = "qhs_ufs_mem_cfg",
+	.id = QCS615_SLAVE_UFS_MEM_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_usb2 = {
+	.name = "qhs_usb2",
+	.id = QCS615_SLAVE_USB2,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_usb3 = {
+	.name = "qhs_usb3",
+	.id = QCS615_SLAVE_USB3,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_venus_cfg = {
+	.name = "qhs_venus_cfg",
+	.id = QCS615_SLAVE_VENUS_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_vsense_ctrl_cfg = {
+	.name = "qhs_vsense_ctrl_cfg",
+	.id = QCS615_SLAVE_VSENSE_CTRL_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns_cnoc_a2noc = {
+	.name = "qns_cnoc_a2noc",
+	.id = QCS615_SLAVE_CNOC_A2NOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_MASTER_CNOC_A2NOC },
+};
+
+static struct qcom_icc_node srvc_cnoc = {
+	.name = "srvc_cnoc",
+	.id = QCS615_SLAVE_SERVICE_CNOC,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_dc_noc_gemnoc = {
+	.name = "qhs_dc_noc_gemnoc",
+	.id = QCS615_SLAVE_DC_NOC_GEMNOC,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS615_MASTER_GEM_NOC_CFG },
+};
+
+static struct qcom_icc_node qhs_llcc = {
+	.name = "qhs_llcc",
+	.id = QCS615_SLAVE_LLCC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_mdsp_ms_mpu_cfg = {
+	.name = "qhs_mdsp_ms_mpu_cfg",
+	.id = QCS615_SLAVE_MSS_PROC_MS_MPU_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns_gem_noc_snoc = {
+	.name = "qns_gem_noc_snoc",
+	.id = QCS615_SLAVE_GEM_NOC_SNOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_MASTER_GEM_NOC_SNOC },
+};
+
+static struct qcom_icc_node qns_llcc = {
+	.name = "qns_llcc",
+	.id = QCS615_SLAVE_LLCC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS615_MASTER_LLCC },
+};
+
+static struct qcom_icc_node qns_sys_pcie = {
+	.name = "qns_sys_pcie",
+	.id = QCS615_SLAVE_MEM_NOC_PCIE_SNOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_MASTER_GEM_NOC_PCIE_SNOC },
+};
+
+static struct qcom_icc_node srvc_gemnoc = {
+	.name = "srvc_gemnoc",
+	.id = QCS615_SLAVE_SERVICE_GEM_NOC,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node ipa_core_slave = {
+	.name = "ipa_core_slave",
+	.id = QCS615_SLAVE_IPA_CORE,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node ebi = {
+	.name = "ebi",
+	.id = QCS615_SLAVE_EBI1,
+	.channels = 2,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns2_mem_noc = {
+	.name = "qns2_mem_noc",
+	.id = QCS615_SLAVE_MNOC_SF_MEM_NOC,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS615_MASTER_MNOC_SF_MEM_NOC },
+};
+
+static struct qcom_icc_node qns_mem_noc_hf = {
+	.name = "qns_mem_noc_hf",
+	.id = QCS615_SLAVE_MNOC_HF_MEM_NOC,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS615_MASTER_MNOC_HF_MEM_NOC },
+};
+
+static struct qcom_icc_node srvc_mnoc = {
+	.name = "srvc_mnoc",
+	.id = QCS615_SLAVE_SERVICE_MNOC,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_apss = {
+	.name = "qhs_apss",
+	.id = QCS615_SLAVE_APPSS,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns_cnoc = {
+	.name = "qns_cnoc",
+	.id = QCS615_SLAVE_SNOC_CNOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_MASTER_SNOC_CNOC },
+};
+
+static struct qcom_icc_node qns_gemnoc_sf = {
+	.name = "qns_gemnoc_sf",
+	.id = QCS615_SLAVE_SNOC_GEM_NOC_SF,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS615_MASTER_SNOC_SF_MEM_NOC },
+};
+
+static struct qcom_icc_node qns_memnoc_gc = {
+	.name = "qns_memnoc_gc",
+	.id = QCS615_SLAVE_SNOC_MEM_NOC_GC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS615_MASTER_SNOC_GC_MEM_NOC },
+};
+
+static struct qcom_icc_node qxs_imem = {
+	.name = "qxs_imem",
+	.id = QCS615_SLAVE_IMEM,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qxs_pimem = {
+	.name = "qxs_pimem",
+	.id = QCS615_SLAVE_PIMEM,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node srvc_snoc = {
+	.name = "srvc_snoc",
+	.id = QCS615_SLAVE_SERVICE_SNOC,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node xs_pcie = {
+	.name = "xs_pcie",
+	.id = QCS615_SLAVE_PCIE_0,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node xs_qdss_stm = {
+	.name = "xs_qdss_stm",
+	.id = QCS615_SLAVE_QDSS_STM,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node xs_sys_tcu_cfg = {
+	.name = "xs_sys_tcu_cfg",
+	.id = QCS615_SLAVE_TCU,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 0,
+};
+
+static struct qcom_icc_bcm bcm_acv = {
+	.name = "ACV",
+	.num_nodes = 1,
+	.nodes = { &ebi },
+};
+
+static struct qcom_icc_bcm bcm_ce0 = {
+	.name = "CE0",
+	.num_nodes = 1,
+	.nodes = { &qxm_crypto },
+};
+
+static struct qcom_icc_bcm bcm_cn0 = {
+	.name = "CN0",
+	.keepalive = true,
+	.num_nodes = 37,
+	.nodes = { &qhm_spdm, &qnm_snoc,
+		   &qhs_a1_noc_cfg, &qhs_aop,
+		   &qhs_aoss, &qhs_camera_cfg,
+		   &qhs_clk_ctl, &qhs_cpr_cx,
+		   &qhs_cpr_mx, &qhs_crypto0_cfg,
+		   &qhs_ddrss_cfg, &qhs_display_cfg,
+		   &qhs_emac_avb_cfg, &qhs_glm,
+		   &qhs_gpuss_cfg, &qhs_imem_cfg,
+		   &qhs_ipa, &qhs_mnoc_cfg,
+		   &qhs_pcie_config, &qhs_pimem_cfg,
+		   &qhs_prng, &qhs_qdss_cfg,
+		   &qhs_qup0, &qhs_qup1,
+		   &qhs_snoc_cfg, &qhs_spdm,
+		   &qhs_tcsr, &qhs_tlmm_east,
+		   &qhs_tlmm_south, &qhs_tlmm_west,
+		   &qhs_ufs_mem_cfg, &qhs_usb2,
+		   &qhs_usb3, &qhs_venus_cfg,
+		   &qhs_vsense_ctrl_cfg, &qns_cnoc_a2noc,
+		   &srvc_cnoc },
+};
+
+static struct qcom_icc_bcm bcm_cn1 = {
+	.name = "CN1",
+	.num_nodes = 8,
+	.nodes = { &qhm_qspi, &xm_sdc1,
+		   &xm_sdc2, &qhs_ahb2phy_east,
+		   &qhs_ahb2phy_west, &qhs_qspi,
+		   &qhs_sdc1, &qhs_sdc2 },
+};
+
+static struct qcom_icc_bcm bcm_ip0 = {
+	.name = "IP0",
+	.num_nodes = 1,
+	.nodes = { &ipa_core_slave },
+};
+
+static struct qcom_icc_bcm bcm_mc0 = {
+	.name = "MC0",
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &ebi },
+};
+
+static struct qcom_icc_bcm bcm_mm0 = {
+	.name = "MM0",
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &qns_mem_noc_hf },
+};
+
+static struct qcom_icc_bcm bcm_mm1 = {
+	.name = "MM1",
+	.num_nodes = 7,
+	.nodes = { &qxm_camnoc_hf0_uncomp, &qxm_camnoc_hf1_uncomp,
+		   &qxm_camnoc_sf_uncomp, &qxm_camnoc_hf0,
+		   &qxm_camnoc_hf1, &qxm_mdp0,
+		   &qxm_rot },
+};
+
+static struct qcom_icc_bcm bcm_mm2 = {
+	.name = "MM2",
+	.num_nodes = 2,
+	.nodes = { &qxm_camnoc_sf, &qns2_mem_noc },
+};
+
+static struct qcom_icc_bcm bcm_mm3 = {
+	.name = "MM3",
+	.num_nodes = 2,
+	.nodes = { &qxm_venus0, &qxm_venus_arm9 },
+};
+
+static struct qcom_icc_bcm bcm_qup0 = {
+	.name = "QUP0",
+	.keepalive = true,
+	.vote_scale = 1,
+	.num_nodes = 2,
+	.nodes = { &qhm_qup0, &qhm_qup1 },
+};
+
+static struct qcom_icc_bcm bcm_sh0 = {
+	.name = "SH0",
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &qns_llcc },
+};
+
+static struct qcom_icc_bcm bcm_sh2 = {
+	.name = "SH2",
+	.num_nodes = 1,
+	.nodes = { &acm_apps },
+};
+
+static struct qcom_icc_bcm bcm_sh3 = {
+	.name = "SH3",
+	.num_nodes = 1,
+	.nodes = { &qns_gem_noc_snoc },
+};
+
+static struct qcom_icc_bcm bcm_sn0 = {
+	.name = "SN0",
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &qns_gemnoc_sf },
+};
+
+static struct qcom_icc_bcm bcm_sn1 = {
+	.name = "SN1",
+	.num_nodes = 1,
+	.nodes = { &qxs_imem },
+};
+
+static struct qcom_icc_bcm bcm_sn2 = {
+	.name = "SN2",
+	.num_nodes = 1,
+	.nodes = { &qns_memnoc_gc },
+};
+
+static struct qcom_icc_bcm bcm_sn3 = {
+	.name = "SN3",
+	.num_nodes = 2,
+	.nodes = { &srvc_aggre2_noc, &qns_cnoc },
+};
+
+static struct qcom_icc_bcm bcm_sn4 = {
+	.name = "SN4",
+	.num_nodes = 1,
+	.nodes = { &qxs_pimem },
+};
+
+static struct qcom_icc_bcm bcm_sn5 = {
+	.name = "SN5",
+	.num_nodes = 1,
+	.nodes = { &xs_qdss_stm },
+};
+
+static struct qcom_icc_bcm bcm_sn8 = {
+	.name = "SN8",
+	.num_nodes = 2,
+	.nodes = { &qnm_gemnoc_pcie, &xs_pcie },
+};
+
+static struct qcom_icc_bcm bcm_sn9 = {
+	.name = "SN9",
+	.num_nodes = 1,
+	.nodes = { &qnm_aggre1_noc },
+};
+
+static struct qcom_icc_bcm bcm_sn12 = {
+	.name = "SN12",
+	.num_nodes = 2,
+	.nodes = { &qxm_pimem, &xm_gic },
+};
+
+static struct qcom_icc_bcm bcm_sn13 = {
+	.name = "SN13",
+	.num_nodes = 1,
+	.nodes = { &qnm_lpass_anoc },
+};
+
+static struct qcom_icc_bcm bcm_sn14 = {
+	.name = "SN14",
+	.num_nodes = 1,
+	.nodes = { &qns_pcie_snoc },
+};
+
+static struct qcom_icc_bcm bcm_sn15 = {
+	.name = "SN15",
+	.num_nodes = 1,
+	.nodes = { &qnm_gemnoc },
+};
+
+static struct qcom_icc_bcm * const aggre1_noc_bcms[] = {
+	&bcm_ce0,
+	&bcm_cn1,
+	&bcm_qup0,
+	&bcm_sn3,
+	&bcm_sn14,
+	&bcm_ip0,
+};
+
+static struct qcom_icc_node * const aggre1_noc_nodes[] = {
+	[MASTER_A1NOC_CFG] = &qhm_a1noc_cfg,
+	[MASTER_QDSS_BAM] = &qhm_qdss_bam,
+	[MASTER_QSPI] = &qhm_qspi,
+	[MASTER_QUP_0] = &qhm_qup0,
+	[MASTER_BLSP_1] = &qhm_qup1,
+	[MASTER_CNOC_A2NOC] = &qnm_cnoc,
+	[MASTER_CRYPTO] = &qxm_crypto,
+	[MASTER_IPA] = &qxm_ipa,
+	[MASTER_EMAC_EVB] = &xm_emac_avb,
+	[MASTER_PCIE] = &xm_pcie,
+	[MASTER_QDSS_ETR] = &xm_qdss_etr,
+	[MASTER_SDCC_1] = &xm_sdc1,
+	[MASTER_SDCC_2] = &xm_sdc2,
+	[MASTER_UFS_MEM] = &xm_ufs_mem,
+	[MASTER_USB2] = &xm_usb2,
+	[MASTER_USB3_0] = &xm_usb3_0,
+	[SLAVE_A1NOC_SNOC] = &qns_a1noc_snoc,
+	[SLAVE_LPASS_SNOC] = &qns_lpass_snoc,
+	[SLAVE_ANOC_PCIE_SNOC] = &qns_pcie_snoc,
+	[SLAVE_SERVICE_A2NOC] = &srvc_aggre2_noc,
+};
+
+static const struct qcom_icc_desc qcs615_aggre1_noc = {
+	.nodes = aggre1_noc_nodes,
+	.num_nodes = ARRAY_SIZE(aggre1_noc_nodes),
+	.bcms = aggre1_noc_bcms,
+	.num_bcms = ARRAY_SIZE(aggre1_noc_bcms),
+};
+
+static struct qcom_icc_bcm * const camnoc_virt_bcms[] = {
+	&bcm_mm1,
+};
+
+static struct qcom_icc_node * const camnoc_virt_nodes[] = {
+	[MASTER_CAMNOC_HF0_UNCOMP] = &qxm_camnoc_hf0_uncomp,
+	[MASTER_CAMNOC_HF1_UNCOMP] = &qxm_camnoc_hf1_uncomp,
+	[MASTER_CAMNOC_SF_UNCOMP] = &qxm_camnoc_sf_uncomp,
+	[SLAVE_CAMNOC_UNCOMP] = &qns_camnoc_uncomp,
+};
+
+static const struct qcom_icc_desc qcs615_camnoc_virt = {
+	.nodes = camnoc_virt_nodes,
+	.num_nodes = ARRAY_SIZE(camnoc_virt_nodes),
+	.bcms = camnoc_virt_bcms,
+	.num_bcms = ARRAY_SIZE(camnoc_virt_bcms),
+};
+
+static struct qcom_icc_bcm * const config_noc_bcms[] = {
+	&bcm_cn0,
+	&bcm_cn1,
+};
+
+static struct qcom_icc_node * const config_noc_nodes[] = {
+	[MASTER_SPDM] = &qhm_spdm,
+	[MASTER_SNOC_CNOC] = &qnm_snoc,
+	[MASTER_QDSS_DAP] = &xm_qdss_dap,
+	[SLAVE_A1NOC_CFG] = &qhs_a1_noc_cfg,
+	[SLAVE_AHB2PHY_EAST] = &qhs_ahb2phy_east,
+	[SLAVE_AHB2PHY_WEST] = &qhs_ahb2phy_west,
+	[SLAVE_AOP] = &qhs_aop,
+	[SLAVE_AOSS] = &qhs_aoss,
+	[SLAVE_CAMERA_CFG] = &qhs_camera_cfg,
+	[SLAVE_CLK_CTL] = &qhs_clk_ctl,
+	[SLAVE_RBCPR_CX_CFG] = &qhs_cpr_cx,
+	[SLAVE_RBCPR_MX_CFG] = &qhs_cpr_mx,
+	[SLAVE_CRYPTO_0_CFG] = &qhs_crypto0_cfg,
+	[SLAVE_CNOC_DDRSS] = &qhs_ddrss_cfg,
+	[SLAVE_DISPLAY_CFG] = &qhs_display_cfg,
+	[SLAVE_EMAC_AVB_CFG] = &qhs_emac_avb_cfg,
+	[SLAVE_GLM] = &qhs_glm,
+	[SLAVE_GFX3D_CFG] = &qhs_gpuss_cfg,
+	[SLAVE_IMEM_CFG] = &qhs_imem_cfg,
+	[SLAVE_IPA_CFG] = &qhs_ipa,
+	[SLAVE_CNOC_MNOC_CFG] = &qhs_mnoc_cfg,
+	[SLAVE_PCIE_CFG] = &qhs_pcie_config,
+	[SLAVE_PIMEM_CFG] = &qhs_pimem_cfg,
+	[SLAVE_PRNG] = &qhs_prng,
+	[SLAVE_QDSS_CFG] = &qhs_qdss_cfg,
+	[SLAVE_QSPI] = &qhs_qspi,
+	[SLAVE_QUP_0] = &qhs_qup0,
+	[SLAVE_QUP_1] = &qhs_qup1,
+	[SLAVE_SDCC_1] = &qhs_sdc1,
+	[SLAVE_SDCC_2] = &qhs_sdc2,
+	[SLAVE_SNOC_CFG] = &qhs_snoc_cfg,
+	[SLAVE_SPDM_WRAPPER] = &qhs_spdm,
+	[SLAVE_TCSR] = &qhs_tcsr,
+	[SLAVE_TLMM_EAST] = &qhs_tlmm_east,
+	[SLAVE_TLMM_SOUTH] = &qhs_tlmm_south,
+	[SLAVE_TLMM_WEST] = &qhs_tlmm_west,
+	[SLAVE_UFS_MEM_CFG] = &qhs_ufs_mem_cfg,
+	[SLAVE_USB2] = &qhs_usb2,
+	[SLAVE_USB3] = &qhs_usb3,
+	[SLAVE_VENUS_CFG] = &qhs_venus_cfg,
+	[SLAVE_VSENSE_CTRL_CFG] = &qhs_vsense_ctrl_cfg,
+	[SLAVE_CNOC_A2NOC] = &qns_cnoc_a2noc,
+	[SLAVE_SERVICE_CNOC] = &srvc_cnoc,
+};
+
+static const struct qcom_icc_desc qcs615_config_noc = {
+	.nodes = config_noc_nodes,
+	.num_nodes = ARRAY_SIZE(config_noc_nodes),
+	.bcms = config_noc_bcms,
+	.num_bcms = ARRAY_SIZE(config_noc_bcms),
+};
+
+static struct qcom_icc_node * const dc_noc_nodes[] = {
+	[MASTER_CNOC_DC_NOC] = &qhm_cnoc,
+	[SLAVE_DC_NOC_GEMNOC] = &qhs_dc_noc_gemnoc,
+	[SLAVE_LLCC_CFG] = &qhs_llcc,
+};
+
+static const struct qcom_icc_desc qcs615_dc_noc = {
+	.nodes = dc_noc_nodes,
+	.num_nodes = ARRAY_SIZE(dc_noc_nodes),
+};
+
+static struct qcom_icc_bcm * const gem_noc_bcms[] = {
+	&bcm_sh0,
+	&bcm_sh2,
+	&bcm_sh3,
+	&bcm_mm1,
+};
+
+static struct qcom_icc_node * const gem_noc_nodes[] = {
+	[MASTER_APPSS_PROC] = &acm_apps,
+	[MASTER_GPU_TCU] = &acm_gpu_tcu,
+	[MASTER_SYS_TCU] = &acm_sys_tcu,
+	[MASTER_GEM_NOC_CFG] = &qhm_gemnoc_cfg,
+	[MASTER_GFX3D] = &qnm_gpu,
+	[MASTER_MNOC_HF_MEM_NOC] = &qnm_mnoc_hf,
+	[MASTER_MNOC_SF_MEM_NOC] = &qnm_mnoc_sf,
+	[MASTER_SNOC_GC_MEM_NOC] = &qnm_snoc_gc,
+	[MASTER_SNOC_SF_MEM_NOC] = &qnm_snoc_sf,
+	[SLAVE_MSS_PROC_MS_MPU_CFG] = &qhs_mdsp_ms_mpu_cfg,
+	[SLAVE_GEM_NOC_SNOC] = &qns_gem_noc_snoc,
+	[SLAVE_LLCC] = &qns_llcc,
+	[SLAVE_MEM_NOC_PCIE_SNOC] = &qns_sys_pcie,
+	[SLAVE_SERVICE_GEM_NOC] = &srvc_gemnoc,
+};
+
+static const struct qcom_icc_desc qcs615_gem_noc = {
+	.nodes = gem_noc_nodes,
+	.num_nodes = ARRAY_SIZE(gem_noc_nodes),
+	.bcms = gem_noc_bcms,
+	.num_bcms = ARRAY_SIZE(gem_noc_bcms),
+};
+
+static struct qcom_icc_bcm * const ipa_virt_bcms[] = {
+	&bcm_ip0,
+};
+
+static struct qcom_icc_node * const ipa_virt_nodes[] = {
+	[MASTER_IPA_CORE] = &ipa_core_master,
+	[SLAVE_IPA_CORE] = &ipa_core_slave,
+};
+
+static const struct qcom_icc_desc qcs615_ipa_virt = {
+	.nodes = ipa_virt_nodes,
+	.num_nodes = ARRAY_SIZE(ipa_virt_nodes),
+	.bcms = ipa_virt_bcms,
+	.num_bcms = ARRAY_SIZE(ipa_virt_bcms),
+};
+
+static struct qcom_icc_bcm * const mc_virt_bcms[] = {
+	&bcm_acv,
+	&bcm_mc0,
+};
+
+static struct qcom_icc_node * const mc_virt_nodes[] = {
+	[MASTER_LLCC] = &llcc_mc,
+	[SLAVE_EBI1] = &ebi,
+};
+
+static const struct qcom_icc_desc qcs615_mc_virt = {
+	.nodes = mc_virt_nodes,
+	.num_nodes = ARRAY_SIZE(mc_virt_nodes),
+	.bcms = mc_virt_bcms,
+	.num_bcms = ARRAY_SIZE(mc_virt_bcms),
+};
+
+static struct qcom_icc_bcm * const mmss_noc_bcms[] = {
+	&bcm_mm0,
+	&bcm_mm1,
+	&bcm_mm2,
+	&bcm_mm3,
+};
+
+static struct qcom_icc_node * const mmss_noc_nodes[] = {
+	[MASTER_CNOC_MNOC_CFG] = &qhm_mnoc_cfg,
+	[MASTER_CAMNOC_HF0] = &qxm_camnoc_hf0,
+	[MASTER_CAMNOC_HF1] = &qxm_camnoc_hf1,
+	[MASTER_CAMNOC_SF] = &qxm_camnoc_sf,
+	[MASTER_MDP0] = &qxm_mdp0,
+	[MASTER_ROTATOR] = &qxm_rot,
+	[MASTER_VIDEO_P0] = &qxm_venus0,
+	[MASTER_VIDEO_PROC] = &qxm_venus_arm9,
+	[SLAVE_MNOC_SF_MEM_NOC] = &qns2_mem_noc,
+	[SLAVE_MNOC_HF_MEM_NOC] = &qns_mem_noc_hf,
+	[SLAVE_SERVICE_MNOC] = &srvc_mnoc,
+};
+
+static const struct qcom_icc_desc qcs615_mmss_noc = {
+	.nodes = mmss_noc_nodes,
+	.num_nodes = ARRAY_SIZE(mmss_noc_nodes),
+	.bcms = mmss_noc_bcms,
+	.num_bcms = ARRAY_SIZE(mmss_noc_bcms),
+};
+
+static struct qcom_icc_bcm * const system_noc_bcms[] = {
+	&bcm_sn0,
+	&bcm_sn1,
+	&bcm_sn2,
+	&bcm_sn3,
+	&bcm_sn4,
+	&bcm_sn5,
+	&bcm_sn8,
+	&bcm_sn9,
+	&bcm_sn12,
+	&bcm_sn13,
+	&bcm_sn15,
+};
+
+static struct qcom_icc_node * const system_noc_nodes[] = {
+	[MASTER_SNOC_CFG] = &qhm_snoc_cfg,
+	[MASTER_A1NOC_SNOC] = &qnm_aggre1_noc,
+	[MASTER_GEM_NOC_SNOC] = &qnm_gemnoc,
+	[MASTER_GEM_NOC_PCIE_SNOC] = &qnm_gemnoc_pcie,
+	[MASTER_LPASS_ANOC] = &qnm_lpass_anoc,
+	[MASTER_ANOC_PCIE_SNOC] = &qnm_pcie_anoc,
+	[MASTER_PIMEM] = &qxm_pimem,
+	[MASTER_GIC] = &xm_gic,
+	[SLAVE_APPSS] = &qhs_apss,
+	[SLAVE_SNOC_CNOC] = &qns_cnoc,
+	[SLAVE_SNOC_GEM_NOC_SF] = &qns_gemnoc_sf,
+	[SLAVE_SNOC_MEM_NOC_GC] = &qns_memnoc_gc,
+	[SLAVE_IMEM] = &qxs_imem,
+	[SLAVE_PIMEM] = &qxs_pimem,
+	[SLAVE_SERVICE_SNOC] = &srvc_snoc,
+	[SLAVE_PCIE_0] = &xs_pcie,
+	[SLAVE_QDSS_STM] = &xs_qdss_stm,
+	[SLAVE_TCU] = &xs_sys_tcu_cfg,
+};
+
+static const struct qcom_icc_desc qcs615_system_noc = {
+	.nodes = system_noc_nodes,
+	.num_nodes = ARRAY_SIZE(system_noc_nodes),
+	.bcms = system_noc_bcms,
+	.num_bcms = ARRAY_SIZE(system_noc_bcms),
+};
+
+static const struct of_device_id qnoc_of_match[] = {
+	{ .compatible = "qcom,qcs615-aggre1-noc",
+	  .data = &qcs615_aggre1_noc},
+	{ .compatible = "qcom,qcs615-camnoc-virt",
+	  .data = &qcs615_camnoc_virt},
+	{ .compatible = "qcom,qcs615-config-noc",
+	  .data = &qcs615_config_noc},
+	{ .compatible = "qcom,qcs615-dc-noc",
+	  .data = &qcs615_dc_noc},
+	{ .compatible = "qcom,qcs615-gem-noc",
+	  .data = &qcs615_gem_noc},
+	{ .compatible = "qcom,qcs615-ipa-virt",
+	  .data = &qcs615_ipa_virt},
+	{ .compatible = "qcom,qcs615-mc-virt",
+	  .data = &qcs615_mc_virt},
+	{ .compatible = "qcom,qcs615-mmss-noc",
+	  .data = &qcs615_mmss_noc},
+	{ .compatible = "qcom,qcs615-system-noc",
+	  .data = &qcs615_system_noc},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, qnoc_of_match);
+
+static struct platform_driver qnoc_driver = {
+	.probe = qcom_icc_rpmh_probe,
+	.remove_new = qcom_icc_rpmh_remove,
+	.driver = {
+		.name = "qnoc-qcs615",
+		.of_match_table = qnoc_of_match,
+		.sync_state = icc_sync_state,
+	},
+};
+
+static int __init qnoc_driver_init(void)
+{
+	return platform_driver_register(&qnoc_driver);
+}
+core_initcall(qnoc_driver_init);
+
+static void __exit qnoc_driver_exit(void)
+{
+	platform_driver_unregister(&qnoc_driver);
+}
+module_exit(qnoc_driver_exit);
+
+MODULE_DESCRIPTION("qcs615 NoC driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/qcs615.h
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/qcs615.h
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __DRIVERS_INTERCONNECT_QCOM_QCS615_H
+#define __DRIVERS_INTERCONNECT_QCOM_QCS615_H
+
+#define QCS615_MASTER_A1NOC_CFG				1
+#define QCS615_MASTER_A1NOC_SNOC			2
+#define QCS615_MASTER_ANOC_PCIE_SNOC			3
+#define QCS615_MASTER_APPSS_PROC			4
+#define QCS615_MASTER_BLSP_1				5
+#define QCS615_MASTER_CAMNOC_HF0			6
+#define QCS615_MASTER_CAMNOC_HF0_UNCOMP			7
+#define QCS615_MASTER_CAMNOC_HF1			8
+#define QCS615_MASTER_CAMNOC_HF1_UNCOMP			9
+#define QCS615_MASTER_CAMNOC_SF				10
+#define QCS615_MASTER_CAMNOC_SF_UNCOMP			11
+#define QCS615_MASTER_CNOC_A2NOC			12
+#define QCS615_MASTER_CNOC_DC_NOC			13
+#define QCS615_MASTER_CNOC_MNOC_CFG			14
+#define QCS615_MASTER_CRYPTO				15
+#define QCS615_MASTER_EMAC_EVB				16
+#define QCS615_MASTER_GEM_NOC_CFG			17
+#define QCS615_MASTER_GEM_NOC_PCIE_SNOC			18
+#define QCS615_MASTER_GEM_NOC_SNOC			19
+#define QCS615_MASTER_GFX3D				20
+#define QCS615_MASTER_GIC				21
+#define QCS615_MASTER_GPU_TCU				22
+#define QCS615_MASTER_IPA				23
+#define QCS615_MASTER_IPA_CORE				24
+#define QCS615_MASTER_LLCC				25
+#define QCS615_MASTER_LPASS_ANOC			26
+#define QCS615_MASTER_MDP0				27
+#define QCS615_MASTER_MNOC_HF_MEM_NOC			28
+#define QCS615_MASTER_MNOC_SF_MEM_NOC			29
+#define QCS615_MASTER_PCIE				30
+#define QCS615_MASTER_PIMEM				31
+#define QCS615_MASTER_QDSS_BAM				32
+#define QCS615_MASTER_QDSS_DAP				33
+#define QCS615_MASTER_QDSS_ETR				34
+#define QCS615_MASTER_QSPI				35
+#define QCS615_MASTER_QUP_0				36
+#define QCS615_MASTER_ROTATOR				37
+#define QCS615_MASTER_SDCC_1				38
+#define QCS615_MASTER_SDCC_2				39
+#define QCS615_MASTER_SNOC_CFG				40
+#define QCS615_MASTER_SNOC_CNOC				41
+#define QCS615_MASTER_SNOC_GC_MEM_NOC			42
+#define QCS615_MASTER_SNOC_SF_MEM_NOC			43
+#define QCS615_MASTER_SPDM				44
+#define QCS615_MASTER_SYS_TCU				45
+#define QCS615_MASTER_UFS_MEM				46
+#define QCS615_MASTER_USB2				47
+#define QCS615_MASTER_USB3_0				48
+#define QCS615_MASTER_VIDEO_P0				49
+#define QCS615_MASTER_VIDEO_PROC			50
+#define QCS615_SLAVE_A1NOC_CFG				51
+#define QCS615_SLAVE_A1NOC_SNOC				52
+#define QCS615_SLAVE_AHB2PHY_EAST			53
+#define QCS615_SLAVE_AHB2PHY_WEST			54
+#define QCS615_SLAVE_ANOC_PCIE_SNOC			55
+#define QCS615_SLAVE_AOP				56
+#define QCS615_SLAVE_AOSS				57
+#define QCS615_SLAVE_APPSS				58
+#define QCS615_SLAVE_CAMERA_CFG				59
+#define QCS615_SLAVE_CAMNOC_UNCOMP			60
+#define QCS615_SLAVE_CLK_CTL				61
+#define QCS615_SLAVE_CNOC_A2NOC				62
+#define QCS615_SLAVE_CNOC_DDRSS				63
+#define QCS615_SLAVE_CNOC_MNOC_CFG			64
+#define QCS615_SLAVE_CRYPTO_0_CFG			65
+#define QCS615_SLAVE_DC_NOC_GEMNOC			66
+#define QCS615_SLAVE_DISPLAY_CFG			67
+#define QCS615_SLAVE_EBI1				68
+#define QCS615_SLAVE_EMAC_AVB_CFG			69
+#define QCS615_SLAVE_GEM_NOC_SNOC			70
+#define QCS615_SLAVE_GFX3D_CFG				71
+#define QCS615_SLAVE_GLM				72
+#define QCS615_SLAVE_IMEM				73
+#define QCS615_SLAVE_IMEM_CFG				74
+#define QCS615_SLAVE_IPA_CFG				75
+#define QCS615_SLAVE_IPA_CORE				76
+#define QCS615_SLAVE_LLCC				77
+#define QCS615_SLAVE_LLCC_CFG				78
+#define QCS615_SLAVE_LPASS_SNOC				79
+#define QCS615_SLAVE_MEM_NOC_PCIE_SNOC			80
+#define QCS615_SLAVE_MNOC_HF_MEM_NOC			81
+#define QCS615_SLAVE_MNOC_SF_MEM_NOC			82
+#define QCS615_SLAVE_MSS_PROC_MS_MPU_CFG		83
+#define QCS615_SLAVE_PCIE_0				84
+#define QCS615_SLAVE_PCIE_CFG				85
+#define QCS615_SLAVE_PIMEM				86
+#define QCS615_SLAVE_PIMEM_CFG				87
+#define QCS615_SLAVE_PRNG				88
+#define QCS615_SLAVE_QDSS_CFG				89
+#define QCS615_SLAVE_QDSS_STM				90
+#define QCS615_SLAVE_QSPI				91
+#define QCS615_SLAVE_QUP_0				92
+#define QCS615_SLAVE_QUP_1				93
+#define QCS615_SLAVE_RBCPR_CX_CFG			94
+#define QCS615_SLAVE_RBCPR_MX_CFG			95
+#define QCS615_SLAVE_SDCC_1				96
+#define QCS615_SLAVE_SDCC_2				97
+#define QCS615_SLAVE_SERVICE_A2NOC			98
+#define QCS615_SLAVE_SERVICE_CNOC			99
+#define QCS615_SLAVE_SERVICE_GEM_NOC			100
+#define QCS615_SLAVE_SERVICE_MNOC			101
+#define QCS615_SLAVE_SERVICE_SNOC			102
+#define QCS615_SLAVE_SNOC_CFG				103
+#define QCS615_SLAVE_SNOC_CNOC				104
+#define QCS615_SLAVE_SNOC_GEM_NOC_SF			105
+#define QCS615_SLAVE_SNOC_MEM_NOC_GC			106
+#define QCS615_SLAVE_SPDM_WRAPPER			107
+#define QCS615_SLAVE_TCSR				108
+#define QCS615_SLAVE_TCU				109
+#define QCS615_SLAVE_TLMM_EAST				110
+#define QCS615_SLAVE_TLMM_SOUTH				111
+#define QCS615_SLAVE_TLMM_WEST				112
+#define QCS615_SLAVE_UFS_MEM_CFG			113
+#define QCS615_SLAVE_USB2				114
+#define QCS615_SLAVE_USB3				115
+#define QCS615_SLAVE_VENUS_CFG				116
+#define QCS615_SLAVE_VSENSE_CTRL_CFG			117
+
+#endif
+
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/qcs8300.c
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/qcs8300.c
@@ -0,0 +1,2088 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/interconnect.h>
+#include <linux/interconnect-provider.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <dt-bindings/interconnect/qcom,qcs8300-rpmh.h>
+
+#include "bcm-voter.h"
+#include "icc-rpmh.h"
+#include "qcs8300.h"
+
+static struct qcom_icc_node qxm_qup3 = {
+	.name = "qxm_qup3",
+	.id = QCS8300_MASTER_QUP_3,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node xm_emac_0 = {
+	.name = "xm_emac_0",
+	.id = QCS8300_MASTER_EMAC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node xm_sdc1 = {
+	.name = "xm_sdc1",
+	.id = QCS8300_MASTER_SDC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node xm_ufs_mem = {
+	.name = "xm_ufs_mem",
+	.id = QCS8300_MASTER_UFS_MEM,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node xm_usb2_2 = {
+	.name = "xm_usb2_2",
+	.id = QCS8300_MASTER_USB2,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node xm_usb3_0 = {
+	.name = "xm_usb3_0",
+	.id = QCS8300_MASTER_USB3_0,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node qhm_qdss_bam = {
+	.name = "qhm_qdss_bam",
+	.id = QCS8300_MASTER_QDSS_BAM,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A2NOC_SNOC },
+};
+
+static struct qcom_icc_node qhm_qup0 = {
+	.name = "qhm_qup0",
+	.id = QCS8300_MASTER_QUP_0,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A2NOC_SNOC },
+};
+
+static struct qcom_icc_node qhm_qup1 = {
+	.name = "qhm_qup1",
+	.id = QCS8300_MASTER_QUP_1,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A2NOC_SNOC },
+};
+
+static struct qcom_icc_node qnm_cnoc_datapath = {
+	.name = "qnm_cnoc_datapath",
+	.id = QCS8300_MASTER_CNOC_A2NOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A2NOC_SNOC },
+};
+
+static struct qcom_icc_node qxm_crypto_0 = {
+	.name = "qxm_crypto_0",
+	.id = QCS8300_MASTER_CRYPTO_CORE0,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A2NOC_SNOC },
+};
+
+static struct qcom_icc_node qxm_crypto_1 = {
+	.name = "qxm_crypto_1",
+	.id = QCS8300_MASTER_CRYPTO_CORE1,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A2NOC_SNOC },
+};
+
+static struct qcom_icc_node qxm_ipa = {
+	.name = "qxm_ipa",
+	.id = QCS8300_MASTER_IPA,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A2NOC_SNOC },
+};
+
+static struct qcom_icc_node xm_qdss_etr_0 = {
+	.name = "xm_qdss_etr_0",
+	.id = QCS8300_MASTER_QDSS_ETR_0,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A2NOC_SNOC },
+};
+
+static struct qcom_icc_node xm_qdss_etr_1 = {
+	.name = "xm_qdss_etr_1",
+	.id = QCS8300_MASTER_QDSS_ETR_1,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_A2NOC_SNOC },
+};
+
+static struct qcom_icc_node qup0_core_master = {
+	.name = "qup0_core_master",
+	.id = QCS8300_MASTER_QUP_CORE_0,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_QUP_CORE_0 },
+};
+
+static struct qcom_icc_node qup1_core_master = {
+	.name = "qup1_core_master",
+	.id = QCS8300_MASTER_QUP_CORE_1,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_QUP_CORE_1 },
+};
+
+static struct qcom_icc_node qup3_core_master = {
+	.name = "qup3_core_master",
+	.id = QCS8300_MASTER_QUP_CORE_3,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_QUP_CORE_3 },
+};
+
+static struct qcom_icc_node qnm_gemnoc_cnoc = {
+	.name = "qnm_gemnoc_cnoc",
+	.id = QCS8300_MASTER_GEM_NOC_CNOC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 71,
+	.links = { QCS8300_SLAVE_AHB2PHY_2, QCS8300_SLAVE_AHB2PHY_3,
+			   QCS8300_SLAVE_ANOC_THROTTLE_CFG, QCS8300_SLAVE_AOSS,
+			   QCS8300_SLAVE_APPSS, QCS8300_SLAVE_BOOT_ROM,
+			   QCS8300_SLAVE_CAMERA_CFG, QCS8300_SLAVE_CAMERA_NRT_THROTTLE_CFG,
+			   QCS8300_SLAVE_CAMERA_RT_THROTTLE_CFG, QCS8300_SLAVE_CLK_CTL,
+			   QCS8300_SLAVE_CDSP_CFG, QCS8300_SLAVE_RBCPR_CX_CFG,
+			   QCS8300_SLAVE_RBCPR_MMCX_CFG, QCS8300_SLAVE_RBCPR_MX_CFG,
+			   QCS8300_SLAVE_CPR_NSPCX, QCS8300_SLAVE_CPR_NSPHMX,
+			   QCS8300_SLAVE_CRYPTO_0_CFG, QCS8300_SLAVE_CX_RDPM,
+			   QCS8300_SLAVE_DISPLAY_CFG, QCS8300_SLAVE_DISPLAY_RT_THROTTLE_CFG,
+			   QCS8300_SLAVE_EMAC_CFG, QCS8300_SLAVE_GP_DSP0_CFG,
+			   QCS8300_SLAVE_GPDSP0_THROTTLE_CFG, QCS8300_SLAVE_GPU_TCU_THROTTLE_CFG,
+			   QCS8300_SLAVE_GFX3D_CFG, QCS8300_SLAVE_HWKM,
+			   QCS8300_SLAVE_IMEM_CFG, QCS8300_SLAVE_IPA_CFG,
+			   QCS8300_SLAVE_IPC_ROUTER_CFG, QCS8300_SLAVE_LPASS,
+			   QCS8300_SLAVE_LPASS_THROTTLE_CFG, QCS8300_SLAVE_MX_RDPM,
+			   QCS8300_SLAVE_MXC_RDPM, QCS8300_SLAVE_PCIE_0_CFG,
+			   QCS8300_SLAVE_PCIE_1_CFG, QCS8300_SLAVE_PCIE_TCU_THROTTLE_CFG,
+			   QCS8300_SLAVE_PCIE_THROTTLE_CFG, QCS8300_SLAVE_PDM,
+			   QCS8300_SLAVE_PIMEM_CFG, QCS8300_SLAVE_PKA_WRAPPER_CFG,
+			   QCS8300_SLAVE_QDSS_CFG, QCS8300_SLAVE_QM_CFG,
+			   QCS8300_SLAVE_QM_MPU_CFG, QCS8300_SLAVE_QUP_0,
+			   QCS8300_SLAVE_QUP_1, QCS8300_SLAVE_QUP_3,
+			   QCS8300_SLAVE_SAIL_THROTTLE_CFG, QCS8300_SLAVE_SDC1,
+			   QCS8300_SLAVE_SECURITY, QCS8300_SLAVE_SNOC_THROTTLE_CFG,
+			   QCS8300_SLAVE_TCSR, QCS8300_SLAVE_TLMM,
+			   QCS8300_SLAVE_TSC_CFG, QCS8300_SLAVE_UFS_MEM_CFG,
+			   QCS8300_SLAVE_USB2, QCS8300_SLAVE_USB3_0,
+			   QCS8300_SLAVE_VENUS_CFG, QCS8300_SLAVE_VENUS_CVP_THROTTLE_CFG,
+			   QCS8300_SLAVE_VENUS_V_CPU_THROTTLE_CFG,
+			   QCS8300_SLAVE_VENUS_VCODEC_THROTTLE_CFG,
+			   QCS8300_SLAVE_DDRSS_CFG, QCS8300_SLAVE_GPDSP_NOC_CFG,
+			   QCS8300_SLAVE_CNOC_MNOC_HF_CFG, QCS8300_SLAVE_CNOC_MNOC_SF_CFG,
+			   QCS8300_SLAVE_PCIE_ANOC_CFG, QCS8300_SLAVE_SNOC_CFG,
+			   QCS8300_SLAVE_BOOT_IMEM, QCS8300_SLAVE_IMEM,
+			   QCS8300_SLAVE_PIMEM, QCS8300_SLAVE_QDSS_STM,
+			   QCS8300_SLAVE_TCU },
+};
+
+static struct qcom_icc_node qnm_gemnoc_pcie = {
+	.name = "qnm_gemnoc_pcie",
+	.id = QCS8300_MASTER_GEM_NOC_PCIE_SNOC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 2,
+	.links = { QCS8300_SLAVE_PCIE_0, QCS8300_SLAVE_PCIE_1 },
+};
+
+static struct qcom_icc_node qnm_cnoc_dc_noc = {
+	.name = "qnm_cnoc_dc_noc",
+	.id = QCS8300_MASTER_CNOC_DC_NOC,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 2,
+	.links = { QCS8300_SLAVE_LLCC_CFG, QCS8300_SLAVE_GEM_NOC_CFG },
+};
+
+static struct qcom_icc_node alm_gpu_tcu = {
+	.name = "alm_gpu_tcu",
+	.id = QCS8300_MASTER_GPU_TCU,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 2,
+	.links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node alm_pcie_tcu = {
+	.name = "alm_pcie_tcu",
+	.id = QCS8300_MASTER_PCIE_TCU,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 2,
+	.links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node alm_sys_tcu = {
+	.name = "alm_sys_tcu",
+	.id = QCS8300_MASTER_SYS_TCU,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 2,
+	.links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node chm_apps = {
+	.name = "chm_apps",
+	.id = QCS8300_MASTER_APPSS_PROC,
+	.channels = 4,
+	.buswidth = 32,
+	.num_links = 3,
+	.links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC,
+			   QCS8300_SLAVE_GEM_NOC_PCIE_CNOC },
+};
+
+static struct qcom_icc_node qnm_cmpnoc0 = {
+	.name = "qnm_cmpnoc0",
+	.id = QCS8300_MASTER_COMPUTE_NOC,
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 2,
+	.links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node qnm_gemnoc_cfg = {
+	.name = "qnm_gemnoc_cfg",
+	.id = QCS8300_MASTER_GEM_NOC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 4,
+	.links = { QCS8300_SLAVE_SERVICE_GEM_NOC_1, QCS8300_SLAVE_SERVICE_GEM_NOC_2,
+		   QCS8300_SLAVE_SERVICE_GEM_NOC, QCS8300_SLAVE_SERVICE_GEM_NOC2 },
+};
+
+static struct qcom_icc_node qnm_gpdsp_sail = {
+	.name = "qnm_gpdsp_sail",
+	.id = QCS8300_MASTER_GPDSP_SAIL,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 2,
+	.links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node qnm_gpu = {
+	.name = "qnm_gpu",
+	.id = QCS8300_MASTER_GFX3D,
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 2,
+	.links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node qnm_mnoc_hf = {
+	.name = "qnm_mnoc_hf",
+	.id = QCS8300_MASTER_MNOC_HF_MEM_NOC,
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 2,
+	.links = { QCS8300_SLAVE_LLCC, QCS8300_SLAVE_GEM_NOC_PCIE_CNOC },
+};
+
+static struct qcom_icc_node qnm_mnoc_sf = {
+	.name = "qnm_mnoc_sf",
+	.id = QCS8300_MASTER_MNOC_SF_MEM_NOC,
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 3,
+	.links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC,
+		   QCS8300_SLAVE_GEM_NOC_PCIE_CNOC },
+};
+
+static struct qcom_icc_node qnm_pcie = {
+	.name = "qnm_pcie",
+	.id = QCS8300_MASTER_ANOC_PCIE_GEM_NOC,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 2,
+	.links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node qnm_snoc_gc = {
+	.name = "qnm_snoc_gc",
+	.id = QCS8300_MASTER_SNOC_GC_MEM_NOC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_LLCC },
+};
+
+static struct qcom_icc_node qnm_snoc_sf = {
+	.name = "qnm_snoc_sf",
+	.id = QCS8300_MASTER_SNOC_SF_MEM_NOC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 3,
+	.links = { QCS8300_SLAVE_GEM_NOC_CNOC, QCS8300_SLAVE_LLCC,
+		   QCS8300_SLAVE_GEM_NOC_PCIE_CNOC },
+};
+
+static struct qcom_icc_node qnm_sailss_md0 = {
+	.name = "qnm_sailss_md0",
+	.id = QCS8300_MASTER_SAILSS_MD0,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_GP_DSP_SAIL_NOC },
+};
+
+static struct qcom_icc_node qxm_dsp0 = {
+	.name = "qxm_dsp0",
+	.id = QCS8300_MASTER_DSP0,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_GP_DSP_SAIL_NOC },
+};
+
+static struct qcom_icc_node qhm_config_noc = {
+	.name = "qhm_config_noc",
+	.id = QCS8300_MASTER_CNOC_LPASS_AG_NOC,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 6,
+	.links = { QCS8300_SLAVE_LPASS_CORE_CFG, QCS8300_SLAVE_LPASS_LPI_CFG,
+		   QCS8300_SLAVE_LPASS_MPU_CFG, QCS8300_SLAVE_LPASS_TOP_CFG,
+		   QCS8300_SLAVE_SERVICES_LPASS_AML_NOC, QCS8300_SLAVE_SERVICE_LPASS_AG_NOC },
+};
+
+static struct qcom_icc_node qxm_lpass_dsp = {
+	.name = "qxm_lpass_dsp",
+	.id = QCS8300_MASTER_LPASS_PROC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 4,
+	.links = { QCS8300_SLAVE_LPASS_TOP_CFG, QCS8300_SLAVE_LPASS_SNOC,
+		   QCS8300_SLAVE_SERVICES_LPASS_AML_NOC, QCS8300_SLAVE_SERVICE_LPASS_AG_NOC },
+};
+
+static struct qcom_icc_node llcc_mc = {
+	.name = "llcc_mc",
+	.id = QCS8300_MASTER_LLCC,
+	.channels = 8,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_EBI1 },
+};
+
+static struct qcom_icc_node qnm_camnoc_hf = {
+	.name = "qnm_camnoc_hf",
+	.id = QCS8300_MASTER_CAMNOC_HF,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_MNOC_HF_MEM_NOC },
+};
+
+static struct qcom_icc_node qnm_camnoc_icp = {
+	.name = "qnm_camnoc_icp",
+	.id = QCS8300_MASTER_CAMNOC_ICP,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_MNOC_SF_MEM_NOC },
+};
+
+static struct qcom_icc_node qnm_camnoc_sf = {
+	.name = "qnm_camnoc_sf",
+	.id = QCS8300_MASTER_CAMNOC_SF,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_MNOC_SF_MEM_NOC },
+};
+
+static struct qcom_icc_node qnm_mdp0_0 = {
+	.name = "qnm_mdp0_0",
+	.id = QCS8300_MASTER_MDP0,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_MNOC_HF_MEM_NOC },
+};
+
+static struct qcom_icc_node qnm_mdp0_1 = {
+	.name = "qnm_mdp0_1",
+	.id = QCS8300_MASTER_MDP1,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_MNOC_HF_MEM_NOC },
+};
+
+static struct qcom_icc_node qnm_mnoc_hf_cfg = {
+	.name = "qnm_mnoc_hf_cfg",
+	.id = QCS8300_MASTER_CNOC_MNOC_HF_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_SERVICE_MNOC_HF },
+};
+
+static struct qcom_icc_node qnm_mnoc_sf_cfg = {
+	.name = "qnm_mnoc_sf_cfg",
+	.id = QCS8300_MASTER_CNOC_MNOC_SF_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_SERVICE_MNOC_SF },
+};
+
+static struct qcom_icc_node qnm_video0 = {
+	.name = "qnm_video0",
+	.id = QCS8300_MASTER_VIDEO_P0,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_MNOC_SF_MEM_NOC },
+};
+
+static struct qcom_icc_node qnm_video_cvp = {
+	.name = "qnm_video_cvp",
+	.id = QCS8300_MASTER_VIDEO_PROC,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_MNOC_SF_MEM_NOC },
+};
+
+static struct qcom_icc_node qnm_video_v_cpu = {
+	.name = "qnm_video_v_cpu",
+	.id = QCS8300_MASTER_VIDEO_V_PROC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_MNOC_SF_MEM_NOC },
+};
+
+static struct qcom_icc_node qhm_nsp_noc_config = {
+	.name = "qhm_nsp_noc_config",
+	.id = QCS8300_MASTER_CDSP_NOC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_SERVICE_NSP_NOC },
+};
+
+static struct qcom_icc_node qxm_nsp = {
+	.name = "qxm_nsp",
+	.id = QCS8300_MASTER_CDSP_PROC,
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 2,
+	.links = { QCS8300_SLAVE_HCP_A, QCS8300_SLAVE_CDSP_MEM_NOC },
+};
+
+static struct qcom_icc_node xm_pcie3_0 = {
+	.name = "xm_pcie3_0",
+	.id = QCS8300_MASTER_PCIE_0,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_ANOC_PCIE_GEM_NOC },
+};
+
+static struct qcom_icc_node xm_pcie3_1 = {
+	.name = "xm_pcie3_1",
+	.id = QCS8300_MASTER_PCIE_1,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_ANOC_PCIE_GEM_NOC },
+};
+
+static struct qcom_icc_node qhm_gic = {
+	.name = "qhm_gic",
+	.id = QCS8300_MASTER_GIC_AHB,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_SNOC_GEM_NOC_SF },
+};
+
+static struct qcom_icc_node qnm_aggre1_noc = {
+	.name = "qnm_aggre1_noc",
+	.id = QCS8300_MASTER_A1NOC_SNOC,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_SNOC_GEM_NOC_SF },
+};
+
+static struct qcom_icc_node qnm_aggre2_noc = {
+	.name = "qnm_aggre2_noc",
+	.id = QCS8300_MASTER_A2NOC_SNOC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_SNOC_GEM_NOC_SF },
+};
+
+static struct qcom_icc_node qnm_lpass_noc = {
+	.name = "qnm_lpass_noc",
+	.id = QCS8300_MASTER_LPASS_ANOC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_SNOC_GEM_NOC_SF },
+};
+
+static struct qcom_icc_node qnm_snoc_cfg = {
+	.name = "qnm_snoc_cfg",
+	.id = QCS8300_MASTER_SNOC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_SERVICE_SNOC },
+};
+
+static struct qcom_icc_node qxm_pimem = {
+	.name = "qxm_pimem",
+	.id = QCS8300_MASTER_PIMEM,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_SNOC_GEM_NOC_GC },
+};
+
+static struct qcom_icc_node xm_gic = {
+	.name = "xm_gic",
+	.id = QCS8300_MASTER_GIC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_SLAVE_SNOC_GEM_NOC_GC },
+};
+
+static struct qcom_icc_node qns_a1noc_snoc = {
+	.name = "qns_a1noc_snoc",
+	.id = QCS8300_SLAVE_A1NOC_SNOC,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_A1NOC_SNOC },
+};
+
+static struct qcom_icc_node qns_a2noc_snoc = {
+	.name = "qns_a2noc_snoc",
+	.id = QCS8300_SLAVE_A2NOC_SNOC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_A2NOC_SNOC },
+};
+
+static struct qcom_icc_node qup0_core_slave = {
+	.name = "qup0_core_slave",
+	.id = QCS8300_SLAVE_QUP_CORE_0,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qup1_core_slave = {
+	.name = "qup1_core_slave",
+	.id = QCS8300_SLAVE_QUP_CORE_1,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qup3_core_slave = {
+	.name = "qup3_core_slave",
+	.id = QCS8300_SLAVE_QUP_CORE_3,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_ahb2phy2 = {
+	.name = "qhs_ahb2phy2",
+	.id = QCS8300_SLAVE_AHB2PHY_2,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_ahb2phy3 = {
+	.name = "qhs_ahb2phy3",
+	.id = QCS8300_SLAVE_AHB2PHY_3,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_anoc_throttle_cfg = {
+	.name = "qhs_anoc_throttle_cfg",
+	.id = QCS8300_SLAVE_ANOC_THROTTLE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_aoss = {
+	.name = "qhs_aoss",
+	.id = QCS8300_SLAVE_AOSS,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_apss = {
+	.name = "qhs_apss",
+	.id = QCS8300_SLAVE_APPSS,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_boot_rom = {
+	.name = "qhs_boot_rom",
+	.id = QCS8300_SLAVE_BOOT_ROM,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_camera_cfg = {
+	.name = "qhs_camera_cfg",
+	.id = QCS8300_SLAVE_CAMERA_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_camera_nrt_throttle_cfg = {
+	.name = "qhs_camera_nrt_throttle_cfg",
+	.id = QCS8300_SLAVE_CAMERA_NRT_THROTTLE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_camera_rt_throttle_cfg = {
+	.name = "qhs_camera_rt_throttle_cfg",
+	.id = QCS8300_SLAVE_CAMERA_RT_THROTTLE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_clk_ctl = {
+	.name = "qhs_clk_ctl",
+	.id = QCS8300_SLAVE_CLK_CTL,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_compute0_cfg = {
+	.name = "qhs_compute0_cfg",
+	.id = QCS8300_SLAVE_CDSP_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_CDSP_NOC_CFG },
+};
+
+static struct qcom_icc_node qhs_cpr_cx = {
+	.name = "qhs_cpr_cx",
+	.id = QCS8300_SLAVE_RBCPR_CX_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_cpr_mmcx = {
+	.name = "qhs_cpr_mmcx",
+	.id = QCS8300_SLAVE_RBCPR_MMCX_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_cpr_mx = {
+	.name = "qhs_cpr_mx",
+	.id = QCS8300_SLAVE_RBCPR_MX_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_cpr_nspcx = {
+	.name = "qhs_cpr_nspcx",
+	.id = QCS8300_SLAVE_CPR_NSPCX,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_cpr_nsphmx = {
+	.name = "qhs_cpr_nsphmx",
+	.id = QCS8300_SLAVE_CPR_NSPHMX,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_crypto0_cfg = {
+	.name = "qhs_crypto0_cfg",
+	.id = QCS8300_SLAVE_CRYPTO_0_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_cx_rdpm = {
+	.name = "qhs_cx_rdpm",
+	.id = QCS8300_SLAVE_CX_RDPM,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_display0_cfg = {
+	.name = "qhs_display0_cfg",
+	.id = QCS8300_SLAVE_DISPLAY_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_display0_rt_throttle_cfg = {
+	.name = "qhs_display0_rt_throttle_cfg",
+	.id = QCS8300_SLAVE_DISPLAY_RT_THROTTLE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_emac0_cfg = {
+	.name = "qhs_emac0_cfg",
+	.id = QCS8300_SLAVE_EMAC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_gp_dsp0_cfg = {
+	.name = "qhs_gp_dsp0_cfg",
+	.id = QCS8300_SLAVE_GP_DSP0_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_gpdsp0_throttle_cfg = {
+	.name = "qhs_gpdsp0_throttle_cfg",
+	.id = QCS8300_SLAVE_GPDSP0_THROTTLE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_gpu_tcu_throttle_cfg = {
+	.name = "qhs_gpu_tcu_throttle_cfg",
+	.id = QCS8300_SLAVE_GPU_TCU_THROTTLE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_gpuss_cfg = {
+	.name = "qhs_gpuss_cfg",
+	.id = QCS8300_SLAVE_GFX3D_CFG,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_hwkm = {
+	.name = "qhs_hwkm",
+	.id = QCS8300_SLAVE_HWKM,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_imem_cfg = {
+	.name = "qhs_imem_cfg",
+	.id = QCS8300_SLAVE_IMEM_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_ipa = {
+	.name = "qhs_ipa",
+	.id = QCS8300_SLAVE_IPA_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_ipc_router = {
+	.name = "qhs_ipc_router",
+	.id = QCS8300_SLAVE_IPC_ROUTER_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_lpass_cfg = {
+	.name = "qhs_lpass_cfg",
+	.id = QCS8300_SLAVE_LPASS,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_CNOC_LPASS_AG_NOC },
+};
+
+static struct qcom_icc_node qhs_lpass_throttle_cfg = {
+	.name = "qhs_lpass_throttle_cfg",
+	.id = QCS8300_SLAVE_LPASS_THROTTLE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_mx_rdpm = {
+	.name = "qhs_mx_rdpm",
+	.id = QCS8300_SLAVE_MX_RDPM,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_mxc_rdpm = {
+	.name = "qhs_mxc_rdpm",
+	.id = QCS8300_SLAVE_MXC_RDPM,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_pcie0_cfg = {
+	.name = "qhs_pcie0_cfg",
+	.id = QCS8300_SLAVE_PCIE_0_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_pcie1_cfg = {
+	.name = "qhs_pcie1_cfg",
+	.id = QCS8300_SLAVE_PCIE_1_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_pcie_tcu_throttle_cfg = {
+	.name = "qhs_pcie_tcu_throttle_cfg",
+	.id = QCS8300_SLAVE_PCIE_TCU_THROTTLE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_pcie_throttle_cfg = {
+	.name = "qhs_pcie_throttle_cfg",
+	.id = QCS8300_SLAVE_PCIE_THROTTLE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_pdm = {
+	.name = "qhs_pdm",
+	.id = QCS8300_SLAVE_PDM,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_pimem_cfg = {
+	.name = "qhs_pimem_cfg",
+	.id = QCS8300_SLAVE_PIMEM_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_pke_wrapper_cfg = {
+	.name = "qhs_pke_wrapper_cfg",
+	.id = QCS8300_SLAVE_PKA_WRAPPER_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_qdss_cfg = {
+	.name = "qhs_qdss_cfg",
+	.id = QCS8300_SLAVE_QDSS_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_qm_cfg = {
+	.name = "qhs_qm_cfg",
+	.id = QCS8300_SLAVE_QM_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_qm_mpu_cfg = {
+	.name = "qhs_qm_mpu_cfg",
+	.id = QCS8300_SLAVE_QM_MPU_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_qup0 = {
+	.name = "qhs_qup0",
+	.id = QCS8300_SLAVE_QUP_0,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_qup1 = {
+	.name = "qhs_qup1",
+	.id = QCS8300_SLAVE_QUP_1,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_qup3 = {
+	.name = "qhs_qup3",
+	.id = QCS8300_SLAVE_QUP_3,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_sail_throttle_cfg = {
+	.name = "qhs_sail_throttle_cfg",
+	.id = QCS8300_SLAVE_SAIL_THROTTLE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_sdc1 = {
+	.name = "qhs_sdc1",
+	.id = QCS8300_SLAVE_SDC1,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_security = {
+	.name = "qhs_security",
+	.id = QCS8300_SLAVE_SECURITY,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_snoc_throttle_cfg = {
+	.name = "qhs_snoc_throttle_cfg",
+	.id = QCS8300_SLAVE_SNOC_THROTTLE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_tcsr = {
+	.name = "qhs_tcsr",
+	.id = QCS8300_SLAVE_TCSR,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_tlmm = {
+	.name = "qhs_tlmm",
+	.id = QCS8300_SLAVE_TLMM,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_tsc_cfg = {
+	.name = "qhs_tsc_cfg",
+	.id = QCS8300_SLAVE_TSC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_ufs_mem_cfg = {
+	.name = "qhs_ufs_mem_cfg",
+	.id = QCS8300_SLAVE_UFS_MEM_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_usb2_0 = {
+	.name = "qhs_usb2_0",
+	.id = QCS8300_SLAVE_USB2,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_usb3_0 = {
+	.name = "qhs_usb3_0",
+	.id = QCS8300_SLAVE_USB3_0,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_venus_cfg = {
+	.name = "qhs_venus_cfg",
+	.id = QCS8300_SLAVE_VENUS_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_venus_cvp_throttle_cfg = {
+	.name = "qhs_venus_cvp_throttle_cfg",
+	.id = QCS8300_SLAVE_VENUS_CVP_THROTTLE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_venus_v_cpu_throttle_cfg = {
+	.name = "qhs_venus_v_cpu_throttle_cfg",
+	.id = QCS8300_SLAVE_VENUS_V_CPU_THROTTLE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_venus_vcodec_throttle_cfg = {
+	.name = "qhs_venus_vcodec_throttle_cfg",
+	.id = QCS8300_SLAVE_VENUS_VCODEC_THROTTLE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns_ddrss_cfg = {
+	.name = "qns_ddrss_cfg",
+	.id = QCS8300_SLAVE_DDRSS_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_CNOC_DC_NOC },
+};
+
+static struct qcom_icc_node qns_gpdsp_noc_cfg = {
+	.name = "qns_gpdsp_noc_cfg",
+	.id = QCS8300_SLAVE_GPDSP_NOC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns_mnoc_hf_cfg = {
+	.name = "qns_mnoc_hf_cfg",
+	.id = QCS8300_SLAVE_CNOC_MNOC_HF_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_CNOC_MNOC_HF_CFG },
+};
+
+static struct qcom_icc_node qns_mnoc_sf_cfg = {
+	.name = "qns_mnoc_sf_cfg",
+	.id = QCS8300_SLAVE_CNOC_MNOC_SF_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_CNOC_MNOC_SF_CFG },
+};
+
+static struct qcom_icc_node qns_pcie_anoc_cfg = {
+	.name = "qns_pcie_anoc_cfg",
+	.id = QCS8300_SLAVE_PCIE_ANOC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns_snoc_cfg = {
+	.name = "qns_snoc_cfg",
+	.id = QCS8300_SLAVE_SNOC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_SNOC_CFG },
+};
+
+static struct qcom_icc_node qxs_boot_imem = {
+	.name = "qxs_boot_imem",
+	.id = QCS8300_SLAVE_BOOT_IMEM,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qxs_imem = {
+	.name = "qxs_imem",
+	.id = QCS8300_SLAVE_IMEM,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qxs_pimem = {
+	.name = "qxs_pimem",
+	.id = QCS8300_SLAVE_PIMEM,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node xs_pcie_0 = {
+	.name = "xs_pcie_0",
+	.id = QCS8300_SLAVE_PCIE_0,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node xs_pcie_1 = {
+	.name = "xs_pcie_1",
+	.id = QCS8300_SLAVE_PCIE_1,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node xs_qdss_stm = {
+	.name = "xs_qdss_stm",
+	.id = QCS8300_SLAVE_QDSS_STM,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node xs_sys_tcu_cfg = {
+	.name = "xs_sys_tcu_cfg",
+	.id = QCS8300_SLAVE_TCU,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_llcc = {
+	.name = "qhs_llcc",
+	.id = QCS8300_SLAVE_LLCC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns_gemnoc = {
+	.name = "qns_gemnoc",
+	.id = QCS8300_SLAVE_GEM_NOC_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_GEM_NOC_CFG },
+};
+
+static struct qcom_icc_node qns_gem_noc_cnoc = {
+	.name = "qns_gem_noc_cnoc",
+	.id = QCS8300_SLAVE_GEM_NOC_CNOC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_GEM_NOC_CNOC },
+};
+
+static struct qcom_icc_node qns_llcc = {
+	.name = "qns_llcc",
+	.id = QCS8300_SLAVE_LLCC,
+	.channels = 4,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_LLCC },
+};
+
+static struct qcom_icc_node qns_pcie = {
+	.name = "qns_pcie",
+	.id = QCS8300_SLAVE_GEM_NOC_PCIE_CNOC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_GEM_NOC_PCIE_SNOC },
+};
+
+static struct qcom_icc_node srvc_even_gemnoc = {
+	.name = "srvc_even_gemnoc",
+	.id = QCS8300_SLAVE_SERVICE_GEM_NOC_1,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node srvc_odd_gemnoc = {
+	.name = "srvc_odd_gemnoc",
+	.id = QCS8300_SLAVE_SERVICE_GEM_NOC_2,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node srvc_sys_gemnoc = {
+	.name = "srvc_sys_gemnoc",
+	.id = QCS8300_SLAVE_SERVICE_GEM_NOC,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node srvc_sys_gemnoc_2 = {
+	.name = "srvc_sys_gemnoc_2",
+	.id = QCS8300_SLAVE_SERVICE_GEM_NOC2,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns_gp_dsp_sail_noc = {
+	.name = "qns_gp_dsp_sail_noc",
+	.id = QCS8300_SLAVE_GP_DSP_SAIL_NOC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_GPDSP_SAIL },
+};
+
+static struct qcom_icc_node qhs_lpass_core = {
+	.name = "qhs_lpass_core",
+	.id = QCS8300_SLAVE_LPASS_CORE_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_lpass_lpi = {
+	.name = "qhs_lpass_lpi",
+	.id = QCS8300_SLAVE_LPASS_LPI_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_lpass_mpu = {
+	.name = "qhs_lpass_mpu",
+	.id = QCS8300_SLAVE_LPASS_MPU_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qhs_lpass_top = {
+	.name = "qhs_lpass_top",
+	.id = QCS8300_SLAVE_LPASS_TOP_CFG,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns_sysnoc = {
+	.name = "qns_sysnoc",
+	.id = QCS8300_SLAVE_LPASS_SNOC,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_LPASS_ANOC },
+};
+
+static struct qcom_icc_node srvc_niu_aml_noc = {
+	.name = "srvc_niu_aml_noc",
+	.id = QCS8300_SLAVE_SERVICES_LPASS_AML_NOC,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node srvc_niu_lpass_agnoc = {
+	.name = "srvc_niu_lpass_agnoc",
+	.id = QCS8300_SLAVE_SERVICE_LPASS_AG_NOC,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node ebi = {
+	.name = "ebi",
+	.id = QCS8300_SLAVE_EBI1,
+	.channels = 8,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns_mem_noc_hf = {
+	.name = "qns_mem_noc_hf",
+	.id = QCS8300_SLAVE_MNOC_HF_MEM_NOC,
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_MNOC_HF_MEM_NOC },
+};
+
+static struct qcom_icc_node qns_mem_noc_sf = {
+	.name = "qns_mem_noc_sf",
+	.id = QCS8300_SLAVE_MNOC_SF_MEM_NOC,
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_MNOC_SF_MEM_NOC },
+};
+
+static struct qcom_icc_node srvc_mnoc_hf = {
+	.name = "srvc_mnoc_hf",
+	.id = QCS8300_SLAVE_SERVICE_MNOC_HF,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node srvc_mnoc_sf = {
+	.name = "srvc_mnoc_sf",
+	.id = QCS8300_SLAVE_SERVICE_MNOC_SF,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns_hcp = {
+	.name = "qns_hcp",
+	.id = QCS8300_SLAVE_HCP_A,
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns_nsp_gemnoc = {
+	.name = "qns_nsp_gemnoc",
+	.id = QCS8300_SLAVE_CDSP_MEM_NOC,
+	.channels = 2,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_COMPUTE_NOC },
+};
+
+static struct qcom_icc_node service_nsp_noc = {
+	.name = "service_nsp_noc",
+	.id = QCS8300_SLAVE_SERVICE_NSP_NOC,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_node qns_pcie_mem_noc = {
+	.name = "qns_pcie_mem_noc",
+	.id = QCS8300_SLAVE_ANOC_PCIE_GEM_NOC,
+	.channels = 1,
+	.buswidth = 32,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_ANOC_PCIE_GEM_NOC },
+};
+
+static struct qcom_icc_node qns_gemnoc_gc = {
+	.name = "qns_gemnoc_gc",
+	.id = QCS8300_SLAVE_SNOC_GEM_NOC_GC,
+	.channels = 1,
+	.buswidth = 8,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_SNOC_GC_MEM_NOC },
+};
+
+static struct qcom_icc_node qns_gemnoc_sf = {
+	.name = "qns_gemnoc_sf",
+	.id = QCS8300_SLAVE_SNOC_GEM_NOC_SF,
+	.channels = 1,
+	.buswidth = 16,
+	.num_links = 1,
+	.links = { QCS8300_MASTER_SNOC_SF_MEM_NOC },
+};
+
+static struct qcom_icc_node srvc_snoc = {
+	.name = "srvc_snoc",
+	.id = QCS8300_SLAVE_SERVICE_SNOC,
+	.channels = 1,
+	.buswidth = 4,
+	.num_links = 0,
+};
+
+static struct qcom_icc_bcm bcm_acv = {
+	.name = "ACV",
+	.enable_mask = BIT(3),
+	.num_nodes = 1,
+	.nodes = { &ebi },
+};
+
+static struct qcom_icc_bcm bcm_ce0 = {
+	.name = "CE0",
+	.num_nodes = 2,
+	.nodes = { &qxm_crypto_0, &qxm_crypto_1 },
+};
+
+static struct qcom_icc_bcm bcm_cn0 = {
+	.name = "CN0",
+	.keepalive = true,
+	.num_nodes = 2,
+	.nodes = { &qnm_gemnoc_cnoc, &qnm_gemnoc_pcie },
+};
+
+static struct qcom_icc_bcm bcm_cn1 = {
+	.name = "CN1",
+	.num_nodes = 66,
+	.nodes = { &qhs_ahb2phy2, &qhs_ahb2phy3,
+		   &qhs_anoc_throttle_cfg, &qhs_aoss,
+		   &qhs_apss, &qhs_boot_rom,
+		   &qhs_camera_cfg, &qhs_camera_nrt_throttle_cfg,
+		   &qhs_camera_rt_throttle_cfg, &qhs_clk_ctl,
+		   &qhs_compute0_cfg, &qhs_cpr_cx,
+		   &qhs_cpr_mmcx, &qhs_cpr_mx,
+		   &qhs_cpr_nspcx, &qhs_cpr_nsphmx,
+		   &qhs_crypto0_cfg, &qhs_cx_rdpm,
+		   &qhs_display0_cfg, &qhs_display0_rt_throttle_cfg,
+		   &qhs_emac0_cfg, &qhs_gp_dsp0_cfg,
+		   &qhs_gpdsp0_throttle_cfg, &qhs_gpu_tcu_throttle_cfg,
+		   &qhs_gpuss_cfg, &qhs_hwkm,
+		   &qhs_imem_cfg, &qhs_ipa,
+		   &qhs_ipc_router, &qhs_lpass_cfg,
+		   &qhs_lpass_throttle_cfg, &qhs_mx_rdpm,
+		   &qhs_mxc_rdpm, &qhs_pcie0_cfg,
+		   &qhs_pcie1_cfg, &qhs_pcie_tcu_throttle_cfg,
+		   &qhs_pcie_throttle_cfg, &qhs_pdm,
+		   &qhs_pimem_cfg, &qhs_pke_wrapper_cfg,
+		   &qhs_qdss_cfg, &qhs_qm_cfg,
+		   &qhs_qm_mpu_cfg, &qhs_sail_throttle_cfg,
+		   &qhs_sdc1, &qhs_security,
+		   &qhs_snoc_throttle_cfg, &qhs_tcsr,
+		   &qhs_tlmm, &qhs_tsc_cfg,
+		   &qhs_ufs_mem_cfg, &qhs_usb2_0,
+		   &qhs_usb3_0, &qhs_venus_cfg,
+		   &qhs_venus_cvp_throttle_cfg, &qhs_venus_v_cpu_throttle_cfg,
+		   &qhs_venus_vcodec_throttle_cfg, &qns_ddrss_cfg,
+		   &qns_gpdsp_noc_cfg, &qns_mnoc_hf_cfg,
+		   &qns_mnoc_sf_cfg, &qns_pcie_anoc_cfg,
+		   &qns_snoc_cfg, &qxs_boot_imem,
+		   &qxs_imem, &xs_sys_tcu_cfg },
+};
+
+static struct qcom_icc_bcm bcm_cn2 = {
+	.name = "CN2",
+	.num_nodes = 3,
+	.nodes = { &qhs_qup0, &qhs_qup1,
+		   &qhs_qup3 },
+};
+
+static struct qcom_icc_bcm bcm_cn3 = {
+	.name = "CN3",
+	.num_nodes = 2,
+	.nodes = { &xs_pcie_0, &xs_pcie_1 },
+};
+
+static struct qcom_icc_bcm bcm_gna0 = {
+	.name = "GNA0",
+	.num_nodes = 1,
+	.nodes = { &qxm_dsp0 },
+};
+
+static struct qcom_icc_bcm bcm_mc0 = {
+	.name = "MC0",
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &ebi },
+};
+
+static struct qcom_icc_bcm bcm_mm0 = {
+	.name = "MM0",
+	.keepalive = true,
+	.num_nodes = 4,
+	.nodes = { &qnm_camnoc_hf, &qnm_mdp0_0,
+		   &qnm_mdp0_1, &qns_mem_noc_hf },
+};
+
+static struct qcom_icc_bcm bcm_mm1 = {
+	.name = "MM1",
+	.num_nodes = 6,
+	.nodes = { &qnm_camnoc_icp, &qnm_camnoc_sf,
+		   &qnm_video0, &qnm_video_cvp,
+		   &qnm_video_v_cpu, &qns_mem_noc_sf },
+};
+
+static struct qcom_icc_bcm bcm_nsa0 = {
+	.name = "NSA0",
+	.num_nodes = 2,
+	.nodes = { &qns_hcp, &qns_nsp_gemnoc },
+};
+
+static struct qcom_icc_bcm bcm_nsa1 = {
+	.name = "NSA1",
+	.num_nodes = 1,
+	.nodes = { &qxm_nsp },
+};
+
+static struct qcom_icc_bcm bcm_pci0 = {
+	.name = "PCI0",
+	.num_nodes = 1,
+	.nodes = { &qns_pcie_mem_noc },
+};
+
+static struct qcom_icc_bcm bcm_qup0 = {
+	.name = "QUP0",
+	.vote_scale = 1,
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &qup0_core_slave },
+};
+
+static struct qcom_icc_bcm bcm_qup1 = {
+	.name = "QUP1",
+	.vote_scale = 1,
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &qup1_core_slave },
+};
+
+static struct qcom_icc_bcm bcm_qup2 = {
+	.name = "QUP2",
+	.vote_scale = 1,
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &qup3_core_slave },
+};
+
+static struct qcom_icc_bcm bcm_sh0 = {
+	.name = "SH0",
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &qns_llcc },
+};
+
+static struct qcom_icc_bcm bcm_sh2 = {
+	.name = "SH2",
+	.num_nodes = 1,
+	.nodes = { &chm_apps },
+};
+
+static struct qcom_icc_bcm bcm_sn0 = {
+	.name = "SN0",
+	.keepalive = true,
+	.num_nodes = 1,
+	.nodes = { &qns_gemnoc_sf },
+};
+
+static struct qcom_icc_bcm bcm_sn1 = {
+	.name = "SN1",
+	.num_nodes = 1,
+	.nodes = { &qns_gemnoc_gc },
+};
+
+static struct qcom_icc_bcm bcm_sn2 = {
+	.name = "SN2",
+	.num_nodes = 1,
+	.nodes = { &qxs_pimem },
+};
+
+static struct qcom_icc_bcm bcm_sn3 = {
+	.name = "SN3",
+	.num_nodes = 2,
+	.nodes = { &qns_a1noc_snoc, &qnm_aggre1_noc },
+};
+
+static struct qcom_icc_bcm bcm_sn4 = {
+	.name = "SN4",
+	.num_nodes = 2,
+	.nodes = { &qns_a2noc_snoc, &qnm_aggre2_noc },
+};
+
+static struct qcom_icc_bcm bcm_sn9 = {
+	.name = "SN9",
+	.num_nodes = 2,
+	.nodes = { &qns_sysnoc, &qnm_lpass_noc },
+};
+
+static struct qcom_icc_bcm bcm_sn10 = {
+	.name = "SN10",
+	.num_nodes = 1,
+	.nodes = { &xs_qdss_stm },
+};
+
+static struct qcom_icc_bcm * const aggre1_noc_bcms[] = {
+	&bcm_sn3,
+};
+
+static struct qcom_icc_node * const aggre1_noc_nodes[] = {
+	[MASTER_QUP_3] = &qxm_qup3,
+	[MASTER_EMAC] = &xm_emac_0,
+	[MASTER_SDC] = &xm_sdc1,
+	[MASTER_UFS_MEM] = &xm_ufs_mem,
+	[MASTER_USB2] = &xm_usb2_2,
+	[MASTER_USB3_0] = &xm_usb3_0,
+	[SLAVE_A1NOC_SNOC] = &qns_a1noc_snoc,
+};
+
+static const struct qcom_icc_desc qcs8300_aggre1_noc = {
+	.nodes = aggre1_noc_nodes,
+	.num_nodes = ARRAY_SIZE(aggre1_noc_nodes),
+	.bcms = aggre1_noc_bcms,
+	.num_bcms = ARRAY_SIZE(aggre1_noc_bcms),
+};
+
+static struct qcom_icc_bcm * const aggre2_noc_bcms[] = {
+	&bcm_ce0,
+	&bcm_sn4,
+};
+
+static struct qcom_icc_node * const aggre2_noc_nodes[] = {
+	[MASTER_QDSS_BAM] = &qhm_qdss_bam,
+	[MASTER_QUP_0] = &qhm_qup0,
+	[MASTER_QUP_1] = &qhm_qup1,
+	[MASTER_CNOC_A2NOC] = &qnm_cnoc_datapath,
+	[MASTER_CRYPTO_CORE0] = &qxm_crypto_0,
+	[MASTER_CRYPTO_CORE1] = &qxm_crypto_1,
+	[MASTER_IPA] = &qxm_ipa,
+	[MASTER_QDSS_ETR_0] = &xm_qdss_etr_0,
+	[MASTER_QDSS_ETR_1] = &xm_qdss_etr_1,
+	[SLAVE_A2NOC_SNOC] = &qns_a2noc_snoc,
+};
+
+static const struct qcom_icc_desc qcs8300_aggre2_noc = {
+	.nodes = aggre2_noc_nodes,
+	.num_nodes = ARRAY_SIZE(aggre2_noc_nodes),
+	.bcms = aggre2_noc_bcms,
+	.num_bcms = ARRAY_SIZE(aggre2_noc_bcms),
+};
+
+static struct qcom_icc_bcm * const clk_virt_bcms[] = {
+	&bcm_qup0,
+	&bcm_qup1,
+	&bcm_qup2,
+};
+
+static struct qcom_icc_node * const clk_virt_nodes[] = {
+	[MASTER_QUP_CORE_0] = &qup0_core_master,
+	[MASTER_QUP_CORE_1] = &qup1_core_master,
+	[MASTER_QUP_CORE_3] = &qup3_core_master,
+	[SLAVE_QUP_CORE_0] = &qup0_core_slave,
+	[SLAVE_QUP_CORE_1] = &qup1_core_slave,
+	[SLAVE_QUP_CORE_3] = &qup3_core_slave,
+};
+
+static const struct qcom_icc_desc qcs8300_clk_virt = {
+	.nodes = clk_virt_nodes,
+	.num_nodes = ARRAY_SIZE(clk_virt_nodes),
+	.bcms = clk_virt_bcms,
+	.num_bcms = ARRAY_SIZE(clk_virt_bcms),
+};
+
+static struct qcom_icc_bcm * const config_noc_bcms[] = {
+	&bcm_cn0,
+	&bcm_cn1,
+	&bcm_cn2,
+	&bcm_cn3,
+	&bcm_sn2,
+	&bcm_sn10,
+};
+
+static struct qcom_icc_node * const config_noc_nodes[] = {
+	[MASTER_GEM_NOC_CNOC] = &qnm_gemnoc_cnoc,
+	[MASTER_GEM_NOC_PCIE_SNOC] = &qnm_gemnoc_pcie,
+	[SLAVE_AHB2PHY_2] = &qhs_ahb2phy2,
+	[SLAVE_AHB2PHY_3] = &qhs_ahb2phy3,
+	[SLAVE_ANOC_THROTTLE_CFG] = &qhs_anoc_throttle_cfg,
+	[SLAVE_AOSS] = &qhs_aoss,
+	[SLAVE_APPSS] = &qhs_apss,
+	[SLAVE_BOOT_ROM] = &qhs_boot_rom,
+	[SLAVE_CAMERA_CFG] = &qhs_camera_cfg,
+	[SLAVE_CAMERA_NRT_THROTTLE_CFG] = &qhs_camera_nrt_throttle_cfg,
+	[SLAVE_CAMERA_RT_THROTTLE_CFG] = &qhs_camera_rt_throttle_cfg,
+	[SLAVE_CLK_CTL] = &qhs_clk_ctl,
+	[SLAVE_CDSP_CFG] = &qhs_compute0_cfg,
+	[SLAVE_RBCPR_CX_CFG] = &qhs_cpr_cx,
+	[SLAVE_RBCPR_MMCX_CFG] = &qhs_cpr_mmcx,
+	[SLAVE_RBCPR_MX_CFG] = &qhs_cpr_mx,
+	[SLAVE_CPR_NSPCX] = &qhs_cpr_nspcx,
+	[SLAVE_CPR_NSPHMX] = &qhs_cpr_nsphmx,
+	[SLAVE_CRYPTO_0_CFG] = &qhs_crypto0_cfg,
+	[SLAVE_CX_RDPM] = &qhs_cx_rdpm,
+	[SLAVE_DISPLAY_CFG] = &qhs_display0_cfg,
+	[SLAVE_DISPLAY_RT_THROTTLE_CFG] = &qhs_display0_rt_throttle_cfg,
+	[SLAVE_EMAC_CFG] = &qhs_emac0_cfg,
+	[SLAVE_GP_DSP0_CFG] = &qhs_gp_dsp0_cfg,
+	[SLAVE_GPDSP0_THROTTLE_CFG] = &qhs_gpdsp0_throttle_cfg,
+	[SLAVE_GPU_TCU_THROTTLE_CFG] = &qhs_gpu_tcu_throttle_cfg,
+	[SLAVE_GFX3D_CFG] = &qhs_gpuss_cfg,
+	[SLAVE_HWKM] = &qhs_hwkm,
+	[SLAVE_IMEM_CFG] = &qhs_imem_cfg,
+	[SLAVE_IPA_CFG] = &qhs_ipa,
+	[SLAVE_IPC_ROUTER_CFG] = &qhs_ipc_router,
+	[SLAVE_LPASS] = &qhs_lpass_cfg,
+	[SLAVE_LPASS_THROTTLE_CFG] = &qhs_lpass_throttle_cfg,
+	[SLAVE_MX_RDPM] = &qhs_mx_rdpm,
+	[SLAVE_MXC_RDPM] = &qhs_mxc_rdpm,
+	[SLAVE_PCIE_0_CFG] = &qhs_pcie0_cfg,
+	[SLAVE_PCIE_1_CFG] = &qhs_pcie1_cfg,
+	[SLAVE_PCIE_TCU_THROTTLE_CFG] = &qhs_pcie_tcu_throttle_cfg,
+	[SLAVE_PCIE_THROTTLE_CFG] = &qhs_pcie_throttle_cfg,
+	[SLAVE_PDM] = &qhs_pdm,
+	[SLAVE_PIMEM_CFG] = &qhs_pimem_cfg,
+	[SLAVE_PKA_WRAPPER_CFG] = &qhs_pke_wrapper_cfg,
+	[SLAVE_QDSS_CFG] = &qhs_qdss_cfg,
+	[SLAVE_QM_CFG] = &qhs_qm_cfg,
+	[SLAVE_QM_MPU_CFG] = &qhs_qm_mpu_cfg,
+	[SLAVE_QUP_0] = &qhs_qup0,
+	[SLAVE_QUP_1] = &qhs_qup1,
+	[SLAVE_QUP_3] = &qhs_qup3,
+	[SLAVE_SAIL_THROTTLE_CFG] = &qhs_sail_throttle_cfg,
+	[SLAVE_SDC1] = &qhs_sdc1,
+	[SLAVE_SECURITY] = &qhs_security,
+	[SLAVE_SNOC_THROTTLE_CFG] = &qhs_snoc_throttle_cfg,
+	[SLAVE_TCSR] = &qhs_tcsr,
+	[SLAVE_TLMM] = &qhs_tlmm,
+	[SLAVE_TSC_CFG] = &qhs_tsc_cfg,
+	[SLAVE_UFS_MEM_CFG] = &qhs_ufs_mem_cfg,
+	[SLAVE_USB2] = &qhs_usb2_0,
+	[SLAVE_USB3_0] = &qhs_usb3_0,
+	[SLAVE_VENUS_CFG] = &qhs_venus_cfg,
+	[SLAVE_VENUS_CVP_THROTTLE_CFG] = &qhs_venus_cvp_throttle_cfg,
+	[SLAVE_VENUS_V_CPU_THROTTLE_CFG] = &qhs_venus_v_cpu_throttle_cfg,
+	[SLAVE_VENUS_VCODEC_THROTTLE_CFG] = &qhs_venus_vcodec_throttle_cfg,
+	[SLAVE_DDRSS_CFG] = &qns_ddrss_cfg,
+	[SLAVE_GPDSP_NOC_CFG] = &qns_gpdsp_noc_cfg,
+	[SLAVE_CNOC_MNOC_HF_CFG] = &qns_mnoc_hf_cfg,
+	[SLAVE_CNOC_MNOC_SF_CFG] = &qns_mnoc_sf_cfg,
+	[SLAVE_PCIE_ANOC_CFG] = &qns_pcie_anoc_cfg,
+	[SLAVE_SNOC_CFG] = &qns_snoc_cfg,
+	[SLAVE_BOOT_IMEM] = &qxs_boot_imem,
+	[SLAVE_IMEM] = &qxs_imem,
+	[SLAVE_PIMEM] = &qxs_pimem,
+	[SLAVE_PCIE_0] = &xs_pcie_0,
+	[SLAVE_PCIE_1] = &xs_pcie_1,
+	[SLAVE_QDSS_STM] = &xs_qdss_stm,
+	[SLAVE_TCU] = &xs_sys_tcu_cfg,
+};
+
+static const struct qcom_icc_desc qcs8300_config_noc = {
+	.nodes = config_noc_nodes,
+	.num_nodes = ARRAY_SIZE(config_noc_nodes),
+	.bcms = config_noc_bcms,
+	.num_bcms = ARRAY_SIZE(config_noc_bcms),
+};
+
+static struct qcom_icc_node * const dc_noc_nodes[] = {
+	[MASTER_CNOC_DC_NOC] = &qnm_cnoc_dc_noc,
+	[SLAVE_LLCC_CFG] = &qhs_llcc,
+	[SLAVE_GEM_NOC_CFG] = &qns_gemnoc,
+};
+
+static const struct qcom_icc_desc qcs8300_dc_noc = {
+	.nodes = dc_noc_nodes,
+	.num_nodes = ARRAY_SIZE(dc_noc_nodes),
+};
+
+static struct qcom_icc_bcm * const gem_noc_bcms[] = {
+	&bcm_sh0,
+	&bcm_sh2,
+};
+
+static struct qcom_icc_node * const gem_noc_nodes[] = {
+	[MASTER_GPU_TCU] = &alm_gpu_tcu,
+	[MASTER_PCIE_TCU] = &alm_pcie_tcu,
+	[MASTER_SYS_TCU] = &alm_sys_tcu,
+	[MASTER_APPSS_PROC] = &chm_apps,
+	[MASTER_COMPUTE_NOC] = &qnm_cmpnoc0,
+	[MASTER_GEM_NOC_CFG] = &qnm_gemnoc_cfg,
+	[MASTER_GPDSP_SAIL] = &qnm_gpdsp_sail,
+	[MASTER_GFX3D] = &qnm_gpu,
+	[MASTER_MNOC_HF_MEM_NOC] = &qnm_mnoc_hf,
+	[MASTER_MNOC_SF_MEM_NOC] = &qnm_mnoc_sf,
+	[MASTER_ANOC_PCIE_GEM_NOC] = &qnm_pcie,
+	[MASTER_SNOC_GC_MEM_NOC] = &qnm_snoc_gc,
+	[MASTER_SNOC_SF_MEM_NOC] = &qnm_snoc_sf,
+	[SLAVE_GEM_NOC_CNOC] = &qns_gem_noc_cnoc,
+	[SLAVE_LLCC] = &qns_llcc,
+	[SLAVE_GEM_NOC_PCIE_CNOC] = &qns_pcie,
+	[SLAVE_SERVICE_GEM_NOC_1] = &srvc_even_gemnoc,
+	[SLAVE_SERVICE_GEM_NOC_2] = &srvc_odd_gemnoc,
+	[SLAVE_SERVICE_GEM_NOC] = &srvc_sys_gemnoc,
+	[SLAVE_SERVICE_GEM_NOC2] = &srvc_sys_gemnoc_2,
+};
+
+static const struct qcom_icc_desc qcs8300_gem_noc = {
+	.nodes = gem_noc_nodes,
+	.num_nodes = ARRAY_SIZE(gem_noc_nodes),
+	.bcms = gem_noc_bcms,
+	.num_bcms = ARRAY_SIZE(gem_noc_bcms),
+};
+
+static struct qcom_icc_bcm * const gpdsp_anoc_bcms[] = {
+	&bcm_gna0,
+};
+
+static struct qcom_icc_node * const gpdsp_anoc_nodes[] = {
+	[MASTER_SAILSS_MD0] = &qnm_sailss_md0,
+	[MASTER_DSP0] = &qxm_dsp0,
+	[SLAVE_GP_DSP_SAIL_NOC] = &qns_gp_dsp_sail_noc,
+};
+
+static const struct qcom_icc_desc qcs8300_gpdsp_anoc = {
+	.nodes = gpdsp_anoc_nodes,
+	.num_nodes = ARRAY_SIZE(gpdsp_anoc_nodes),
+	.bcms = gpdsp_anoc_bcms,
+	.num_bcms = ARRAY_SIZE(gpdsp_anoc_bcms),
+};
+
+static struct qcom_icc_bcm * const lpass_ag_noc_bcms[] = {
+	&bcm_sn9,
+};
+
+static struct qcom_icc_node * const lpass_ag_noc_nodes[] = {
+	[MASTER_CNOC_LPASS_AG_NOC] = &qhm_config_noc,
+	[MASTER_LPASS_PROC] = &qxm_lpass_dsp,
+	[SLAVE_LPASS_CORE_CFG] = &qhs_lpass_core,
+	[SLAVE_LPASS_LPI_CFG] = &qhs_lpass_lpi,
+	[SLAVE_LPASS_MPU_CFG] = &qhs_lpass_mpu,
+	[SLAVE_LPASS_TOP_CFG] = &qhs_lpass_top,
+	[SLAVE_LPASS_SNOC] = &qns_sysnoc,
+	[SLAVE_SERVICES_LPASS_AML_NOC] = &srvc_niu_aml_noc,
+	[SLAVE_SERVICE_LPASS_AG_NOC] = &srvc_niu_lpass_agnoc,
+};
+
+static const struct qcom_icc_desc qcs8300_lpass_ag_noc = {
+	.nodes = lpass_ag_noc_nodes,
+	.num_nodes = ARRAY_SIZE(lpass_ag_noc_nodes),
+	.bcms = lpass_ag_noc_bcms,
+	.num_bcms = ARRAY_SIZE(lpass_ag_noc_bcms),
+};
+
+static struct qcom_icc_bcm * const mc_virt_bcms[] = {
+	&bcm_acv,
+	&bcm_mc0,
+};
+
+static struct qcom_icc_node * const mc_virt_nodes[] = {
+	[MASTER_LLCC] = &llcc_mc,
+	[SLAVE_EBI1] = &ebi,
+};
+
+static const struct qcom_icc_desc qcs8300_mc_virt = {
+	.nodes = mc_virt_nodes,
+	.num_nodes = ARRAY_SIZE(mc_virt_nodes),
+	.bcms = mc_virt_bcms,
+	.num_bcms = ARRAY_SIZE(mc_virt_bcms),
+};
+
+static struct qcom_icc_bcm * const mmss_noc_bcms[] = {
+	&bcm_mm0,
+	&bcm_mm1,
+};
+
+static struct qcom_icc_node * const mmss_noc_nodes[] = {
+	[MASTER_CAMNOC_HF] = &qnm_camnoc_hf,
+	[MASTER_CAMNOC_ICP] = &qnm_camnoc_icp,
+	[MASTER_CAMNOC_SF] = &qnm_camnoc_sf,
+	[MASTER_MDP0] = &qnm_mdp0_0,
+	[MASTER_MDP1] = &qnm_mdp0_1,
+	[MASTER_CNOC_MNOC_HF_CFG] = &qnm_mnoc_hf_cfg,
+	[MASTER_CNOC_MNOC_SF_CFG] = &qnm_mnoc_sf_cfg,
+	[MASTER_VIDEO_P0] = &qnm_video0,
+	[MASTER_VIDEO_PROC] = &qnm_video_cvp,
+	[MASTER_VIDEO_V_PROC] = &qnm_video_v_cpu,
+	[SLAVE_MNOC_HF_MEM_NOC] = &qns_mem_noc_hf,
+	[SLAVE_MNOC_SF_MEM_NOC] = &qns_mem_noc_sf,
+	[SLAVE_SERVICE_MNOC_HF] = &srvc_mnoc_hf,
+	[SLAVE_SERVICE_MNOC_SF] = &srvc_mnoc_sf,
+};
+
+static const struct qcom_icc_desc qcs8300_mmss_noc = {
+	.nodes = mmss_noc_nodes,
+	.num_nodes = ARRAY_SIZE(mmss_noc_nodes),
+	.bcms = mmss_noc_bcms,
+	.num_bcms = ARRAY_SIZE(mmss_noc_bcms),
+};
+
+static struct qcom_icc_bcm * const nspa_noc_bcms[] = {
+	&bcm_nsa0,
+	&bcm_nsa1,
+};
+
+static struct qcom_icc_node * const nspa_noc_nodes[] = {
+	[MASTER_CDSP_NOC_CFG] = &qhm_nsp_noc_config,
+	[MASTER_CDSP_PROC] = &qxm_nsp,
+	[SLAVE_HCP_A] = &qns_hcp,
+	[SLAVE_CDSP_MEM_NOC] = &qns_nsp_gemnoc,
+	[SLAVE_SERVICE_NSP_NOC] = &service_nsp_noc,
+};
+
+static const struct qcom_icc_desc qcs8300_nspa_noc = {
+	.nodes = nspa_noc_nodes,
+	.num_nodes = ARRAY_SIZE(nspa_noc_nodes),
+	.bcms = nspa_noc_bcms,
+	.num_bcms = ARRAY_SIZE(nspa_noc_bcms),
+};
+
+static struct qcom_icc_bcm * const pcie_anoc_bcms[] = {
+	&bcm_pci0,
+};
+
+static struct qcom_icc_node * const pcie_anoc_nodes[] = {
+	[MASTER_PCIE_0] = &xm_pcie3_0,
+	[MASTER_PCIE_1] = &xm_pcie3_1,
+	[SLAVE_ANOC_PCIE_GEM_NOC] = &qns_pcie_mem_noc,
+};
+
+static const struct qcom_icc_desc qcs8300_pcie_anoc = {
+	.nodes = pcie_anoc_nodes,
+	.num_nodes = ARRAY_SIZE(pcie_anoc_nodes),
+	.bcms = pcie_anoc_bcms,
+	.num_bcms = ARRAY_SIZE(pcie_anoc_bcms),
+};
+
+static struct qcom_icc_bcm * const system_noc_bcms[] = {
+	&bcm_sn0,
+	&bcm_sn1,
+	&bcm_sn3,
+	&bcm_sn4,
+	&bcm_sn9,
+};
+
+static struct qcom_icc_node * const system_noc_nodes[] = {
+	[MASTER_GIC_AHB] = &qhm_gic,
+	[MASTER_A1NOC_SNOC] = &qnm_aggre1_noc,
+	[MASTER_A2NOC_SNOC] = &qnm_aggre2_noc,
+	[MASTER_LPASS_ANOC] = &qnm_lpass_noc,
+	[MASTER_SNOC_CFG] = &qnm_snoc_cfg,
+	[MASTER_PIMEM] = &qxm_pimem,
+	[MASTER_GIC] = &xm_gic,
+	[SLAVE_SNOC_GEM_NOC_GC] = &qns_gemnoc_gc,
+	[SLAVE_SNOC_GEM_NOC_SF] = &qns_gemnoc_sf,
+	[SLAVE_SERVICE_SNOC] = &srvc_snoc,
+};
+
+static const struct qcom_icc_desc qcs8300_system_noc = {
+	.nodes = system_noc_nodes,
+	.num_nodes = ARRAY_SIZE(system_noc_nodes),
+	.bcms = system_noc_bcms,
+	.num_bcms = ARRAY_SIZE(system_noc_bcms),
+};
+
+static const struct of_device_id qnoc_of_match[] = {
+	{ .compatible = "qcom,qcs8300-aggre1-noc",
+	  .data = &qcs8300_aggre1_noc},
+	{ .compatible = "qcom,qcs8300-aggre2-noc",
+	  .data = &qcs8300_aggre2_noc},
+	{ .compatible = "qcom,qcs8300-clk-virt",
+	  .data = &qcs8300_clk_virt},
+	{ .compatible = "qcom,qcs8300-config-noc",
+	  .data = &qcs8300_config_noc},
+	{ .compatible = "qcom,qcs8300-dc-noc",
+	  .data = &qcs8300_dc_noc},
+	{ .compatible = "qcom,qcs8300-gem-noc",
+	  .data = &qcs8300_gem_noc},
+	{ .compatible = "qcom,qcs8300-gpdsp-anoc",
+	  .data = &qcs8300_gpdsp_anoc},
+	{ .compatible = "qcom,qcs8300-lpass-ag-noc",
+	  .data = &qcs8300_lpass_ag_noc},
+	{ .compatible = "qcom,qcs8300-mc-virt",
+	  .data = &qcs8300_mc_virt},
+	{ .compatible = "qcom,qcs8300-mmss-noc",
+	  .data = &qcs8300_mmss_noc},
+	{ .compatible = "qcom,qcs8300-nspa-noc",
+	  .data = &qcs8300_nspa_noc},
+	{ .compatible = "qcom,qcs8300-pcie-anoc",
+	  .data = &qcs8300_pcie_anoc},
+	{ .compatible = "qcom,qcs8300-system-noc",
+	  .data = &qcs8300_system_noc},
+	{ }
+};
+MODULE_DEVICE_TABLE(of, qnoc_of_match);
+
+static struct platform_driver qnoc_driver = {
+	.probe = qcom_icc_rpmh_probe,
+	.remove_new = qcom_icc_rpmh_remove,
+	.driver = {
+		.name = "qnoc-qcs8300",
+		.of_match_table = qnoc_of_match,
+		.sync_state = icc_sync_state,
+	},
+};
+
+static int __init qnoc_driver_init(void)
+{
+	return platform_driver_register(&qnoc_driver);
+}
+core_initcall(qnoc_driver_init);
+
+static void __exit qnoc_driver_exit(void)
+{
+	platform_driver_unregister(&qnoc_driver);
+}
+module_exit(qnoc_driver_exit);
+
+MODULE_DESCRIPTION("QCS8300 NoC driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/qcs8300.h
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/qcs8300.h
@@ -0,0 +1,177 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __DRIVERS_INTERCONNECT_QCOM_QCS8300_H
+#define __DRIVERS_INTERCONNECT_QCOM_QCS8300_H
+
+#define QCS8300_MASTER_GPU_TCU				0
+#define QCS8300_MASTER_PCIE_TCU				1
+#define QCS8300_MASTER_SYS_TCU				2
+#define QCS8300_MASTER_APPSS_PROC			3
+#define QCS8300_MASTER_LLCC				4
+#define QCS8300_MASTER_CNOC_LPASS_AG_NOC		5
+#define QCS8300_MASTER_GIC_AHB				6
+#define QCS8300_MASTER_CDSP_NOC_CFG			7
+#define QCS8300_MASTER_QDSS_BAM				8
+#define QCS8300_MASTER_QUP_0				9
+#define QCS8300_MASTER_QUP_1				10
+#define QCS8300_MASTER_A1NOC_SNOC			11
+#define QCS8300_MASTER_A2NOC_SNOC			12
+#define QCS8300_MASTER_CAMNOC_HF			13
+#define QCS8300_MASTER_CAMNOC_ICP			14
+#define QCS8300_MASTER_CAMNOC_SF			15
+#define QCS8300_MASTER_COMPUTE_NOC			16
+#define QCS8300_MASTER_CNOC_A2NOC			17
+#define QCS8300_MASTER_CNOC_DC_NOC			18
+#define QCS8300_MASTER_GEM_NOC_CFG			19
+#define QCS8300_MASTER_GEM_NOC_CNOC			20
+#define QCS8300_MASTER_GEM_NOC_PCIE_SNOC		21
+#define QCS8300_MASTER_GPDSP_SAIL			22
+#define QCS8300_MASTER_GFX3D				23
+#define QCS8300_MASTER_LPASS_ANOC			24
+#define QCS8300_MASTER_MDP0				25
+#define QCS8300_MASTER_MDP1				26
+#define QCS8300_MASTER_MNOC_HF_MEM_NOC			27
+#define QCS8300_MASTER_CNOC_MNOC_HF_CFG			28
+#define QCS8300_MASTER_MNOC_SF_MEM_NOC			29
+#define QCS8300_MASTER_CNOC_MNOC_SF_CFG			30
+#define QCS8300_MASTER_ANOC_PCIE_GEM_NOC		31
+#define QCS8300_MASTER_SAILSS_MD0			32
+#define QCS8300_MASTER_SNOC_CFG				33
+#define QCS8300_MASTER_SNOC_GC_MEM_NOC			34
+#define QCS8300_MASTER_SNOC_SF_MEM_NOC			35
+#define QCS8300_MASTER_VIDEO_P0				36
+#define QCS8300_MASTER_VIDEO_PROC			37
+#define QCS8300_MASTER_VIDEO_V_PROC			38
+#define QCS8300_MASTER_QUP_CORE_0			39
+#define QCS8300_MASTER_QUP_CORE_1			40
+#define QCS8300_MASTER_QUP_CORE_3			41
+#define QCS8300_MASTER_CRYPTO_CORE0			42
+#define QCS8300_MASTER_CRYPTO_CORE1			43
+#define QCS8300_MASTER_DSP0				44
+#define QCS8300_MASTER_IPA				45
+#define QCS8300_MASTER_LPASS_PROC			46
+#define QCS8300_MASTER_CDSP_PROC			47
+#define QCS8300_MASTER_PIMEM				48
+#define QCS8300_MASTER_QUP_3				49
+#define QCS8300_MASTER_EMAC				50
+#define QCS8300_MASTER_GIC				51
+#define QCS8300_MASTER_PCIE_0				52
+#define QCS8300_MASTER_PCIE_1				53
+#define QCS8300_MASTER_QDSS_ETR_0			54
+#define QCS8300_MASTER_QDSS_ETR_1			55
+#define QCS8300_MASTER_SDC				56
+#define QCS8300_MASTER_UFS_MEM				57
+#define QCS8300_MASTER_USB2				58
+#define QCS8300_MASTER_USB3_0				59
+#define QCS8300_SLAVE_EBI1				60
+#define QCS8300_SLAVE_AHB2PHY_2				61
+#define QCS8300_SLAVE_AHB2PHY_3				62
+#define QCS8300_SLAVE_ANOC_THROTTLE_CFG			63
+#define QCS8300_SLAVE_AOSS				64
+#define QCS8300_SLAVE_APPSS				65
+#define QCS8300_SLAVE_BOOT_ROM				66
+#define QCS8300_SLAVE_CAMERA_CFG			67
+#define QCS8300_SLAVE_CAMERA_NRT_THROTTLE_CFG		68
+#define QCS8300_SLAVE_CAMERA_RT_THROTTLE_CFG		69
+#define QCS8300_SLAVE_CLK_CTL				70
+#define QCS8300_SLAVE_CDSP_CFG				71
+#define QCS8300_SLAVE_RBCPR_CX_CFG			72
+#define QCS8300_SLAVE_RBCPR_MMCX_CFG			73
+#define QCS8300_SLAVE_RBCPR_MX_CFG			74
+#define QCS8300_SLAVE_CPR_NSPCX				75
+#define QCS8300_SLAVE_CPR_NSPHMX			76
+#define QCS8300_SLAVE_CRYPTO_0_CFG			77
+#define QCS8300_SLAVE_CX_RDPM				78
+#define QCS8300_SLAVE_DISPLAY_CFG			79
+#define QCS8300_SLAVE_DISPLAY_RT_THROTTLE_CFG		80
+#define QCS8300_SLAVE_EMAC_CFG				81
+#define QCS8300_SLAVE_GP_DSP0_CFG			82
+#define QCS8300_SLAVE_GPDSP0_THROTTLE_CFG		83
+#define QCS8300_SLAVE_GPU_TCU_THROTTLE_CFG		84
+#define QCS8300_SLAVE_GFX3D_CFG				85
+#define QCS8300_SLAVE_HWKM				86
+#define QCS8300_SLAVE_IMEM_CFG				87
+#define QCS8300_SLAVE_IPA_CFG				88
+#define QCS8300_SLAVE_IPC_ROUTER_CFG			89
+#define QCS8300_SLAVE_LLCC_CFG				90
+#define QCS8300_SLAVE_LPASS				91
+#define QCS8300_SLAVE_LPASS_CORE_CFG			92
+#define QCS8300_SLAVE_LPASS_LPI_CFG			93
+#define QCS8300_SLAVE_LPASS_MPU_CFG			94
+#define QCS8300_SLAVE_LPASS_THROTTLE_CFG		95
+#define QCS8300_SLAVE_LPASS_TOP_CFG			96
+#define QCS8300_SLAVE_MX_RDPM				97
+#define QCS8300_SLAVE_MXC_RDPM				98
+#define QCS8300_SLAVE_PCIE_0_CFG			99
+#define QCS8300_SLAVE_PCIE_1_CFG			100
+#define QCS8300_SLAVE_PCIE_TCU_THROTTLE_CFG		101
+#define QCS8300_SLAVE_PCIE_THROTTLE_CFG			102
+#define QCS8300_SLAVE_PDM				103
+#define QCS8300_SLAVE_PIMEM_CFG				104
+#define QCS8300_SLAVE_PKA_WRAPPER_CFG			105
+#define QCS8300_SLAVE_QDSS_CFG				106
+#define QCS8300_SLAVE_QM_CFG				107
+#define QCS8300_SLAVE_QM_MPU_CFG			108
+#define QCS8300_SLAVE_QUP_0				109
+#define QCS8300_SLAVE_QUP_1				110
+#define QCS8300_SLAVE_QUP_3				111
+#define QCS8300_SLAVE_SAIL_THROTTLE_CFG			112
+#define QCS8300_SLAVE_SDC1				113
+#define QCS8300_SLAVE_SECURITY				114
+#define QCS8300_SLAVE_SNOC_THROTTLE_CFG			115
+#define QCS8300_SLAVE_TCSR				116
+#define QCS8300_SLAVE_TLMM				117
+#define QCS8300_SLAVE_TSC_CFG				118
+#define QCS8300_SLAVE_UFS_MEM_CFG			119
+#define QCS8300_SLAVE_USB2				120
+#define QCS8300_SLAVE_USB3_0				121
+#define QCS8300_SLAVE_VENUS_CFG				122
+#define QCS8300_SLAVE_VENUS_CVP_THROTTLE_CFG		123
+#define QCS8300_SLAVE_VENUS_V_CPU_THROTTLE_CFG		124
+#define QCS8300_SLAVE_VENUS_VCODEC_THROTTLE_CFG		125
+#define QCS8300_SLAVE_A1NOC_SNOC			126
+#define QCS8300_SLAVE_A2NOC_SNOC			127
+#define QCS8300_SLAVE_DDRSS_CFG				128
+#define QCS8300_SLAVE_GEM_NOC_CNOC			129
+#define QCS8300_SLAVE_GEM_NOC_CFG			130
+#define QCS8300_SLAVE_SNOC_GEM_NOC_GC			131
+#define QCS8300_SLAVE_SNOC_GEM_NOC_SF			132
+#define QCS8300_SLAVE_GP_DSP_SAIL_NOC			133
+#define QCS8300_SLAVE_GPDSP_NOC_CFG			134
+#define QCS8300_SLAVE_HCP_A				135
+#define QCS8300_SLAVE_LLCC				136
+#define QCS8300_SLAVE_MNOC_HF_MEM_NOC			137
+#define QCS8300_SLAVE_MNOC_SF_MEM_NOC			138
+#define QCS8300_SLAVE_CNOC_MNOC_HF_CFG			139
+#define QCS8300_SLAVE_CNOC_MNOC_SF_CFG			140
+#define QCS8300_SLAVE_CDSP_MEM_NOC			141
+#define QCS8300_SLAVE_GEM_NOC_PCIE_CNOC			142
+#define QCS8300_SLAVE_PCIE_ANOC_CFG			143
+#define QCS8300_SLAVE_ANOC_PCIE_GEM_NOC			144
+#define QCS8300_SLAVE_SNOC_CFG				145
+#define QCS8300_SLAVE_LPASS_SNOC			146
+#define QCS8300_SLAVE_QUP_CORE_0			147
+#define QCS8300_SLAVE_QUP_CORE_1			148
+#define QCS8300_SLAVE_QUP_CORE_3			149
+#define QCS8300_SLAVE_BOOT_IMEM				150
+#define QCS8300_SLAVE_IMEM				151
+#define QCS8300_SLAVE_PIMEM				152
+#define QCS8300_SLAVE_SERVICE_NSP_NOC			153
+#define QCS8300_SLAVE_SERVICE_GEM_NOC_1			154
+#define QCS8300_SLAVE_SERVICE_MNOC_HF			155
+#define QCS8300_SLAVE_SERVICE_MNOC_SF			156
+#define QCS8300_SLAVE_SERVICES_LPASS_AML_NOC		157
+#define QCS8300_SLAVE_SERVICE_LPASS_AG_NOC		158
+#define QCS8300_SLAVE_SERVICE_GEM_NOC_2			159
+#define QCS8300_SLAVE_SERVICE_SNOC			160
+#define QCS8300_SLAVE_SERVICE_GEM_NOC			161
+#define QCS8300_SLAVE_SERVICE_GEM_NOC2			162
+#define QCS8300_SLAVE_PCIE_0				163
+#define QCS8300_SLAVE_PCIE_1				164
+#define QCS8300_SLAVE_QDSS_STM				165
+#define QCS8300_SLAVE_TCU				166
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/sa8775p.c
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/sa8775p.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2023, Linaro Limited
  */
 
@@ -209,173 +209,351 @@
 #define SA8775P_SLAVE_QDSS_STM				632
 #define SA8775P_SLAVE_TCU				633
 
+static const struct regmap_config icc_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+};
+
+static struct qcom_icc_qosbox qxm_qup3_qos = {
+	.num_ports = 1,
+	.offsets = { 0x11000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qxm_qup3 = {
 	.name = "qxm_qup3",
 	.id = SA8775P_MASTER_QUP_3,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qxm_qup3_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_emac_0_qos = {
+	.num_ports = 1,
+	.offsets = { 0x12000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_emac_0 = {
 	.name = "xm_emac_0",
 	.id = SA8775P_MASTER_EMAC,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_emac_0_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_emac_1_qos = {
+	.num_ports = 1,
+	.offsets = { 0x13000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_emac_1 = {
 	.name = "xm_emac_1",
 	.id = SA8775P_MASTER_EMAC_1,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_emac_1_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_sdc1_qos = {
+	.num_ports = 1,
+	.offsets = { 0x14000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_sdc1 = {
 	.name = "xm_sdc1",
 	.id = SA8775P_MASTER_SDC,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_sdc1_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_ufs_mem_qos = {
+	.num_ports = 1,
+	.offsets = { 0x15000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
+
 static struct qcom_icc_node xm_ufs_mem = {
 	.name = "xm_ufs_mem",
 	.id = SA8775P_MASTER_UFS_MEM,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_ufs_mem_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_usb2_2_qos = {
+	.num_ports = 1,
+	.offsets = { 0x16000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_usb2_2 = {
 	.name = "xm_usb2_2",
 	.id = SA8775P_MASTER_USB2,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_usb2_2_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_usb3_0_qos = {
+	.num_ports = 1,
+	.offsets = { 0x17000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_usb3_0 = {
 	.name = "xm_usb3_0",
 	.id = SA8775P_MASTER_USB3_0,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_usb3_0_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_usb3_1_qos = {
+	.num_ports = 1,
+	.offsets = { 0x18000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_usb3_1 = {
 	.name = "xm_usb3_1",
 	.id = SA8775P_MASTER_USB3_1,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_usb3_1_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qhm_qdss_bam_qos = {
+	.num_ports = 1,
+	.offsets = { 0x14000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qhm_qdss_bam = {
 	.name = "qhm_qdss_bam",
 	.id = SA8775P_MASTER_QDSS_BAM,
 	.channels = 1,
 	.buswidth = 4,
+	.qosbox = &qhm_qdss_bam_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qhm_qup0_qos = {
+	.num_ports = 1,
+	.offsets = { 0x17000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qhm_qup0 = {
 	.name = "qhm_qup0",
 	.id = SA8775P_MASTER_QUP_0,
 	.channels = 1,
 	.buswidth = 4,
+	.qosbox = &qhm_qup0_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qhm_qup1_qos = {
+	.num_ports = 1,
+	.offsets = { 0x12000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qhm_qup1 = {
 	.name = "qhm_qup1",
 	.id = SA8775P_MASTER_QUP_1,
 	.channels = 1,
 	.buswidth = 4,
+	.qosbox = &qhm_qup1_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qhm_qup2_qos = {
+	.num_ports = 1,
+	.offsets = { 0x15000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qhm_qup2 = {
 	.name = "qhm_qup2",
 	.id = SA8775P_MASTER_QUP_2,
 	.channels = 1,
 	.buswidth = 4,
+	.qosbox = &qhm_qup2_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qnm_cnoc_datapath_qos = {
+	.num_ports = 1,
+	.offsets = { 0x16000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qnm_cnoc_datapath = {
 	.name = "qnm_cnoc_datapath",
 	.id = SA8775P_MASTER_CNOC_A2NOC,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qnm_cnoc_datapath_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qxm_crypto_0_qos = {
+	.num_ports = 1,
+	.offsets = { 0x18000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qxm_crypto_0 = {
 	.name = "qxm_crypto_0",
 	.id = SA8775P_MASTER_CRYPTO_CORE0,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qxm_crypto_0_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qxm_crypto_1_qos = {
+	.num_ports = 1,
+	.offsets = { 0x1a000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qxm_crypto_1 = {
 	.name = "qxm_crypto_1",
 	.id = SA8775P_MASTER_CRYPTO_CORE1,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qxm_crypto_1_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qxm_ipa_qos = {
+	.num_ports = 1,
+	.offsets = { 0x11000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qxm_ipa = {
 	.name = "qxm_ipa",
 	.id = SA8775P_MASTER_IPA,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qxm_ipa_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_qdss_etr_0_qos = {
+	.num_ports = 1,
+	.offsets = { 0x13000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_qdss_etr_0 = {
 	.name = "xm_qdss_etr_0",
 	.id = SA8775P_MASTER_QDSS_ETR_0,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_qdss_etr_0_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_qdss_etr_1_qos = {
+	.num_ports = 1,
+	.offsets = { 0x19000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_qdss_etr_1 = {
 	.name = "xm_qdss_etr_1",
 	.id = SA8775P_MASTER_QDSS_ETR_1,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_qdss_etr_1_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_ufs_card_qos = {
+	.num_ports = 1,
+	.offsets = { 0x1b000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_ufs_card = {
 	.name = "xm_ufs_card",
 	.id = SA8775P_MASTER_UFS_CARD,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_ufs_card_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_A2NOC_SNOC },
 };
@@ -529,33 +707,60 @@
 	},
 };
 
+static struct qcom_icc_qosbox alm_gpu_tcu_qos = {
+	.num_ports = 1,
+	.offsets = { 0xb4000 },
+	.prio_fwd_disable = 1,
+	.prio = 1,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node alm_gpu_tcu = {
 	.name = "alm_gpu_tcu",
 	.id = SA8775P_MASTER_GPU_TCU,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &alm_gpu_tcu_qos,
 	.num_links = 2,
 	.links = { SA8775P_SLAVE_GEM_NOC_CNOC,
 		   SA8775P_SLAVE_LLCC
 	},
 };
 
+static struct qcom_icc_qosbox alm_pcie_tcu_qos = {
+	.num_ports = 1,
+	.offsets = { 0xb5000 },
+	.prio_fwd_disable = 1,
+	.prio = 3,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node alm_pcie_tcu = {
 	.name = "alm_pcie_tcu",
 	.id = SA8775P_MASTER_PCIE_TCU,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &alm_pcie_tcu_qos,
 	.num_links = 2,
 	.links = { SA8775P_SLAVE_GEM_NOC_CNOC,
 		   SA8775P_SLAVE_LLCC
 	},
 };
 
+static struct qcom_icc_qosbox alm_sys_tcu_qos = {
+	.num_ports = 1,
+	.offsets = { 0xb6000 },
+	.prio_fwd_disable = 1,
+	.prio = 6,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node alm_sys_tcu = {
 	.name = "alm_sys_tcu",
 	.id = SA8775P_MASTER_SYS_TCU,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &alm_sys_tcu_qos,
 	.num_links = 2,
 	.links = { SA8775P_SLAVE_GEM_NOC_CNOC,
 		   SA8775P_SLAVE_LLCC
@@ -574,22 +779,40 @@
 	},
 };
 
+static struct qcom_icc_qosbox qnm_cmpnoc0_qos = {
+	.num_ports = 2,
+	.offsets = { 0xf3000, 0xf4000 },
+	.prio_fwd_disable = 1,
+	.prio = 0,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qnm_cmpnoc0 = {
 	.name = "qnm_cmpnoc0",
 	.id = SA8775P_MASTER_COMPUTE_NOC,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_cmpnoc0_qos,
 	.num_links = 2,
 	.links = { SA8775P_SLAVE_GEM_NOC_CNOC,
 		   SA8775P_SLAVE_LLCC
 	},
 };
 
+static struct qcom_icc_qosbox qnm_cmpnoc1_qos = {
+	.num_ports = 2,
+	.offsets = { 0xf5000, 0xf6000 },
+	.prio_fwd_disable = 1,
+	.prio = 0,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qnm_cmpnoc1 = {
 	.name = "qnm_cmpnoc1",
 	.id = SA8775P_MASTER_COMPUTE_NOC_1,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_cmpnoc1_qos,
 	.num_links = 2,
 	.links = { SA8775P_SLAVE_GEM_NOC_CNOC,
 		   SA8775P_SLAVE_LLCC
@@ -620,33 +843,60 @@
 	},
 };
 
+static struct qcom_icc_qosbox qnm_gpu_qos = {
+	.num_ports = 2,
+	.offsets = { 0xed000, 0xee000 },
+	.prio_fwd_disable = 1,
+	.prio = 0,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qnm_gpu = {
 	.name = "qnm_gpu",
 	.id = SA8775P_MASTER_GFX3D,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_gpu_qos,
 	.num_links = 2,
 	.links = { SA8775P_SLAVE_GEM_NOC_CNOC,
 		   SA8775P_SLAVE_LLCC
 	},
 };
 
+static struct qcom_icc_qosbox qnm_mnoc_hf_qos = {
+	.num_ports = 2,
+	.offsets = { 0xef000, 0xf0000 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_mnoc_hf = {
 	.name = "qnm_mnoc_hf",
 	.id = SA8775P_MASTER_MNOC_HF_MEM_NOC,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_mnoc_hf_qos,
 	.num_links = 2,
 	.links = { SA8775P_SLAVE_LLCC,
 		   SA8775P_SLAVE_GEM_NOC_PCIE_CNOC
 	},
 };
 
+static struct qcom_icc_qosbox qnm_mnoc_sf_qos = {
+	.num_ports = 2,
+	.offsets = { 0xf1000, 0xf2000 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_mnoc_sf = {
 	.name = "qnm_mnoc_sf",
 	.id = SA8775P_MASTER_MNOC_SF_MEM_NOC,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_mnoc_sf_qos,
 	.num_links = 3,
 	.links = { SA8775P_SLAVE_GEM_NOC_CNOC,
 		   SA8775P_SLAVE_LLCC,
@@ -654,31 +904,58 @@
 	},
 };
 
+static struct qcom_icc_qosbox qnm_pcie_qos = {
+	.num_ports = 1,
+	.offsets = { 0xb8000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qnm_pcie = {
 	.name = "qnm_pcie",
 	.id = SA8775P_MASTER_ANOC_PCIE_GEM_NOC,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qnm_pcie_qos,
 	.num_links = 2,
 	.links = { SA8775P_SLAVE_GEM_NOC_CNOC,
 		   SA8775P_SLAVE_LLCC
 	},
 };
 
+static struct qcom_icc_qosbox qnm_snoc_gc_qos = {
+	.num_ports = 1,
+	.offsets = { 0xb9000 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_snoc_gc = {
 	.name = "qnm_snoc_gc",
 	.id = SA8775P_MASTER_SNOC_GC_MEM_NOC,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qnm_snoc_gc_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_LLCC },
 };
 
+static struct qcom_icc_qosbox qnm_snoc_sf_qos = {
+	.num_ports = 1,
+	.offsets = { 0xba000 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_snoc_sf = {
 	.name = "qnm_snoc_sf",
 	.id = SA8775P_MASTER_SNOC_SF_MEM_NOC,
 	.channels = 1,
 	.buswidth = 16,
+	.qosbox = &qnm_snoc_sf_qos,
 	.num_links = 3,
 	.links = { SA8775P_SLAVE_GEM_NOC_CNOC,
 		   SA8775P_SLAVE_LLCC,
@@ -740,65 +1017,128 @@
 	.links = { SA8775P_SLAVE_EBI1 },
 };
 
+static struct qcom_icc_qosbox qnm_camnoc_hf_qos = {
+	.num_ports = 1,
+	.offsets = { 0xa000 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_camnoc_hf = {
 	.name = "qnm_camnoc_hf",
 	.id = SA8775P_MASTER_CAMNOC_HF,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qnm_camnoc_hf_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_MNOC_HF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_camnoc_icp_qos = {
+	.num_ports = 1,
+	.offsets = { 0x2a000 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_camnoc_icp = {
 	.name = "qnm_camnoc_icp",
 	.id = SA8775P_MASTER_CAMNOC_ICP,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qnm_camnoc_icp_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_camnoc_sf_qos = {
+	.num_ports = 1,
+	.offsets = { 0x2a080 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_camnoc_sf = {
 	.name = "qnm_camnoc_sf",
 	.id = SA8775P_MASTER_CAMNOC_SF,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qnm_camnoc_sf_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_mdp0_0_qos = {
+	.num_ports = 1,
+	.offsets = { 0xa080 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_mdp0_0 = {
 	.name = "qnm_mdp0_0",
 	.id = SA8775P_MASTER_MDP0,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qnm_mdp0_0_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_MNOC_HF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_mdp0_1_qos = {
+	.num_ports = 1,
+	.offsets = { 0xa180 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_mdp0_1 = {
 	.name = "qnm_mdp0_1",
 	.id = SA8775P_MASTER_MDP1,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qnm_mdp0_1_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_MNOC_HF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_mdp1_0_qos = {
+	.num_ports = 1,
+	.offsets = { 0xa100 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_mdp1_0 = {
 	.name = "qnm_mdp1_0",
 	.id = SA8775P_MASTER_MDP_CORE1_0,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qnm_mdp1_0_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_MNOC_HF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_mdp1_1_qos = {
+	.num_ports = 1,
+	.offsets = { 0xa200 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_mdp1_1 = {
 	.name = "qnm_mdp1_1",
 	.id = SA8775P_MASTER_MDP_CORE1_1,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qnm_mdp1_1_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_MNOC_HF_MEM_NOC },
 };
@@ -821,38 +1161,74 @@
 	.links = { SA8775P_SLAVE_SERVICE_MNOC_SF },
 };
 
+static struct qcom_icc_qosbox qnm_video0_qos = {
+	.num_ports = 1,
+	.offsets = { 0x2a100 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_video0 = {
 	.name = "qnm_video0",
 	.id = SA8775P_MASTER_VIDEO_P0,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qnm_video0_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_video1_qos = {
+	.num_ports = 1,
+	.offsets = { 0x2a180 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_video1 = {
 	.name = "qnm_video1",
 	.id = SA8775P_MASTER_VIDEO_P1,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qnm_video1_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_video_cvp_qos = {
+	.num_ports = 1,
+	.offsets = { 0x2a200 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_video_cvp = {
 	.name = "qnm_video_cvp",
 	.id = SA8775P_MASTER_VIDEO_PROC,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qnm_video_cvp_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_video_v_cpu_qos = {
+	.num_ports = 1,
+	.offsets = { 0x2a280 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_video_v_cpu = {
 	.name = "qnm_video_v_cpu",
 	.id = SA8775P_MASTER_VIDEO_V_PROC,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qnm_video_v_cpu_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_MNOC_SF_MEM_NOC },
 };
@@ -893,29 +1269,56 @@
 	.links = { SA8775P_SLAVE_HCP_B, SLAVE_CDSPB_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox xm_pcie3_0_qos = {
+	.num_ports = 1,
+	.offsets = { 0xb000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_pcie3_0 = {
 	.name = "xm_pcie3_0",
 	.id = SA8775P_MASTER_PCIE_0,
 	.channels = 1,
 	.buswidth = 16,
+	.qosbox = &xm_pcie3_0_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_ANOC_PCIE_GEM_NOC },
 };
 
+static struct qcom_icc_qosbox xm_pcie3_1_qos = {
+	.num_ports = 1,
+	.offsets = { 0xc000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_pcie3_1 = {
 	.name = "xm_pcie3_1",
 	.id = SA8775P_MASTER_PCIE_1,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &xm_pcie3_1_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_ANOC_PCIE_GEM_NOC },
 };
 
+static struct qcom_icc_qosbox qhm_gic_qos = {
+	.num_ports = 1,
+	.offsets = { 0x14000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qhm_gic = {
 	.name = "qhm_gic",
 	.id = SA8775P_MASTER_GIC_AHB,
 	.channels = 1,
 	.buswidth = 4,
+	.qosbox = &qhm_gic_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_SNOC_GEM_NOC_SF },
 };
@@ -938,11 +1341,20 @@
 	.links = { SA8775P_SLAVE_SNOC_GEM_NOC_SF },
 };
 
+static struct qcom_icc_qosbox qnm_lpass_noc_qos = {
+	.num_ports = 1,
+	.offsets = { 0x12000 },
+	.prio_fwd_disable = 0,
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_lpass_noc = {
 	.name = "qnm_lpass_noc",
 	.id = SA8775P_MASTER_LPASS_ANOC,
 	.channels = 1,
 	.buswidth = 16,
+	.qosbox = &qnm_lpass_noc_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_SNOC_GEM_NOC_SF },
 };
@@ -956,20 +1368,38 @@
 	.links = { SA8775P_SLAVE_SERVICE_SNOC },
 };
 
+static struct qcom_icc_qosbox qxm_pimem_qos = {
+	.num_ports = 1,
+	.offsets = { 0x13000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qxm_pimem = {
 	.name = "qxm_pimem",
 	.id = SA8775P_MASTER_PIMEM,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qxm_pimem_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_SNOC_GEM_NOC_GC },
 };
 
+static struct qcom_icc_qosbox xm_gic_qos = {
+	.num_ports = 1,
+	.offsets = { 0x15000 },
+	.prio_fwd_disable = 1,
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_gic = {
 	.name = "xm_gic",
 	.id = SA8775P_MASTER_GIC,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_gic_qos,
 	.num_links = 1,
 	.links = { SA8775P_SLAVE_SNOC_GEM_NOC_GC },
 };
@@ -2109,6 +2539,7 @@
 };
 
 static const struct qcom_icc_desc sa8775p_aggre1_noc = {
+	.config = &icc_regmap_config,
 	.nodes = aggre1_noc_nodes,
 	.num_nodes = ARRAY_SIZE(aggre1_noc_nodes),
 	.bcms = aggre1_noc_bcms,
@@ -2136,6 +2567,7 @@
 };
 
 static const struct qcom_icc_desc sa8775p_aggre2_noc = {
+	.config = &icc_regmap_config,
 	.nodes = aggre2_noc_nodes,
 	.num_nodes = ARRAY_SIZE(aggre2_noc_nodes),
 	.bcms = aggre2_noc_bcms,
@@ -2265,6 +2697,7 @@
 };
 
 static const struct qcom_icc_desc sa8775p_config_noc = {
+	.config = &icc_regmap_config,
 	.nodes = config_noc_nodes,
 	.num_nodes = ARRAY_SIZE(config_noc_nodes),
 	.bcms = config_noc_bcms,
@@ -2281,6 +2714,7 @@
 };
 
 static const struct qcom_icc_desc sa8775p_dc_noc = {
+	.config = &icc_regmap_config,
 	.nodes = dc_noc_nodes,
 	.num_nodes = ARRAY_SIZE(dc_noc_nodes),
 	.bcms = dc_noc_bcms,
@@ -2317,6 +2751,7 @@
 };
 
 static const struct qcom_icc_desc sa8775p_gem_noc = {
+	.config = &icc_regmap_config,
 	.nodes = gem_noc_nodes,
 	.num_nodes = ARRAY_SIZE(gem_noc_nodes),
 	.bcms = gem_noc_bcms,
@@ -2335,6 +2770,7 @@
 };
 
 static const struct qcom_icc_desc sa8775p_gpdsp_anoc = {
+	.config = &icc_regmap_config,
 	.nodes = gpdsp_anoc_nodes,
 	.num_nodes = ARRAY_SIZE(gpdsp_anoc_nodes),
 	.bcms = gpdsp_anoc_bcms,
@@ -2358,6 +2794,7 @@
 };
 
 static const struct qcom_icc_desc sa8775p_lpass_ag_noc = {
+	.config = &icc_regmap_config,
 	.nodes = lpass_ag_noc_nodes,
 	.num_nodes = ARRAY_SIZE(lpass_ag_noc_nodes),
 	.bcms = lpass_ag_noc_bcms,
@@ -2407,6 +2844,7 @@
 };
 
 static const struct qcom_icc_desc sa8775p_mmss_noc = {
+	.config = &icc_regmap_config,
 	.nodes = mmss_noc_nodes,
 	.num_nodes = ARRAY_SIZE(mmss_noc_nodes),
 	.bcms = mmss_noc_bcms,
@@ -2427,6 +2865,7 @@
 };
 
 static const struct qcom_icc_desc sa8775p_nspa_noc = {
+	.config = &icc_regmap_config,
 	.nodes = nspa_noc_nodes,
 	.num_nodes = ARRAY_SIZE(nspa_noc_nodes),
 	.bcms = nspa_noc_bcms,
@@ -2447,6 +2886,7 @@
 };
 
 static const struct qcom_icc_desc sa8775p_nspb_noc = {
+	.config = &icc_regmap_config,
 	.nodes = nspb_noc_nodes,
 	.num_nodes = ARRAY_SIZE(nspb_noc_nodes),
 	.bcms = nspb_noc_bcms,
@@ -2464,6 +2904,7 @@
 };
 
 static const struct qcom_icc_desc sa8775p_pcie_anoc = {
+	.config = &icc_regmap_config,
 	.nodes = pcie_anoc_nodes,
 	.num_nodes = ARRAY_SIZE(pcie_anoc_nodes),
 	.bcms = pcie_anoc_bcms,
@@ -2492,6 +2933,7 @@
 };
 
 static const struct qcom_icc_desc sa8775p_system_noc = {
+	.config = &icc_regmap_config,
 	.nodes = system_noc_nodes,
 	.num_nodes = ARRAY_SIZE(system_noc_nodes),
 	.bcms = system_noc_bcms,
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/sc7280.c
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/sc7280.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- *
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/device.h>
@@ -16,29 +16,59 @@
 #include "icc-rpmh.h"
 #include "sc7280.h"
 
+static const struct regmap_config icc_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+};
+
+static struct qcom_icc_qosbox qhm_qspi_qos = {
+	.num_ports = 1,
+	.offsets = { 0x7000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qhm_qspi = {
 	.name = "qhm_qspi",
 	.id = SC7280_MASTER_QSPI_0,
 	.channels = 1,
 	.buswidth = 4,
+	.qosbox = &qhm_qspi_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qhm_qup0_qos = {
+	.num_ports = 1,
+	.offsets = { 0x11000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qhm_qup0 = {
 	.name = "qhm_qup0",
 	.id = SC7280_MASTER_QUP_0,
 	.channels = 1,
 	.buswidth = 4,
+	.qosbox = &qhm_qup0_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qhm_qup1_qos = {
+	.num_ports = 1,
+	.offsets = { 0x8000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qhm_qup1 = {
 	.name = "qhm_qup1",
 	.id = SC7280_MASTER_QUP_1,
 	.channels = 1,
 	.buswidth = 4,
+	.qosbox = &qhm_qup1_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_A1NOC_SNOC },
 };
@@ -52,38 +82,70 @@
 	.links = { SC7280_SLAVE_SERVICE_A1NOC },
 };
 
+static struct qcom_icc_qosbox xm_sdc1_qos = {
+	.num_ports = 1,
+	.offsets = { 0xc000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_sdc1 = {
 	.name = "xm_sdc1",
 	.id = SC7280_MASTER_SDCC_1,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_sdc1_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_sdc2_qos = {
+	.num_ports = 1,
+	.offsets = { 0xe000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_sdc2 = {
 	.name = "xm_sdc2",
 	.id = SC7280_MASTER_SDCC_2,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_sdc2_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_sdc4_qos = {
+	.num_ports = 1,
+	.offsets = { 0x9000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_sdc4 = {
 	.name = "xm_sdc4",
 	.id = SC7280_MASTER_SDCC_4,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_sdc4_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_ufs_mem_qos = {
+	.num_ports = 1,
+	.offsets = { 0xa000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_ufs_mem = {
 	.name = "xm_ufs_mem",
 	.id = SC7280_MASTER_UFS_MEM,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_ufs_mem_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_A1NOC_SNOC },
 };
@@ -97,20 +159,36 @@
 	.links = { SC7280_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_usb3_0_qos = {
+	.num_ports = 1,
+	.offsets = { 0xb000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_usb3_0 = {
 	.name = "xm_usb3_0",
 	.id = SC7280_MASTER_USB3_0,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_usb3_0_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qhm_qdss_bam_qos = {
+	.num_ports = 1,
+	.offsets = { 0x18000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qhm_qdss_bam = {
 	.name = "qhm_qdss_bam",
 	.id = SC7280_MASTER_QDSS_BAM,
 	.channels = 1,
 	.buswidth = 4,
+	.qosbox = &qhm_qdss_bam_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_A2NOC_SNOC },
 };
@@ -124,29 +202,53 @@
 	.links = { SC7280_SLAVE_SERVICE_A2NOC },
 };
 
+static struct qcom_icc_qosbox qnm_cnoc_datapath_qos = {
+	.num_ports = 1,
+	.offsets = { 0x1c000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qnm_cnoc_datapath = {
 	.name = "qnm_cnoc_datapath",
 	.id = SC7280_MASTER_CNOC_A2NOC,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qnm_cnoc_datapath_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qxm_crypto_qos = {
+	.num_ports = 1,
+	.offsets = { 0x1d000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qxm_crypto = {
 	.name = "qxm_crypto",
 	.id = SC7280_MASTER_CRYPTO,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qxm_crypto_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qxm_ipa_qos = {
+	.num_ports = 1,
+	.offsets = { 0x10000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qxm_ipa = {
 	.name = "qxm_ipa",
 	.id = SC7280_MASTER_IPA,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qxm_ipa_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_A2NOC_SNOC },
 };
@@ -168,11 +270,19 @@
 	.links = { SC7280_SLAVE_ANOC_PCIE_GEM_NOC },
 };
 
+static struct qcom_icc_qosbox xm_qdss_etr_qos = {
+	.num_ports = 1,
+	.offsets = { 0x15000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_qdss_etr = {
 	.name = "xm_qdss_etr",
 	.id = SC7280_MASTER_QDSS_ETR,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_qdss_etr_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_A2NOC_SNOC },
 };
@@ -300,20 +410,36 @@
 	.links = { SC7280_SLAVE_LLCC_CFG, SC7280_SLAVE_GEM_NOC_CFG },
 };
 
+static struct qcom_icc_qosbox alm_gpu_tcu_qos = {
+	.num_ports = 1,
+	.offsets = { 0xd7000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node alm_gpu_tcu = {
 	.name = "alm_gpu_tcu",
 	.id = SC7280_MASTER_GPU_TCU,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &alm_gpu_tcu_qos,
 	.num_links = 2,
 	.links = { SC7280_SLAVE_GEM_NOC_CNOC, SC7280_SLAVE_LLCC },
 };
 
+static struct qcom_icc_qosbox alm_sys_tcu_qos = {
+	.num_ports = 1,
+	.offsets = { 0xd6000 },
+	.prio = 6,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node alm_sys_tcu = {
 	.name = "alm_sys_tcu",
 	.id = SC7280_MASTER_SYS_TCU,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &alm_sys_tcu_qos,
 	.num_links = 2,
 	.links = { SC7280_SLAVE_GEM_NOC_CNOC, SC7280_SLAVE_LLCC },
 };
@@ -328,11 +454,19 @@
 		   SC7280_SLAVE_MEM_NOC_PCIE_SNOC },
 };
 
+static struct qcom_icc_qosbox qnm_cmpnoc_qos = {
+	.num_ports = 2,
+	.offsets = { 0x21000, 0x61000 },
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_cmpnoc = {
 	.name = "qnm_cmpnoc",
 	.id = SC7280_MASTER_COMPUTE_NOC,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_cmpnoc_qos,
 	.num_links = 2,
 	.links = { SC7280_SLAVE_GEM_NOC_CNOC, SC7280_SLAVE_LLCC },
 };
@@ -348,29 +482,53 @@
 		   SC7280_SLAVE_SERVICE_GEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_gpu_qos = {
+	.num_ports = 2,
+	.offsets = { 0x22000, 0x62000 },
+	.prio = 0,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qnm_gpu = {
 	.name = "qnm_gpu",
 	.id = SC7280_MASTER_GFX3D,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_gpu_qos,
 	.num_links = 2,
 	.links = { SC7280_SLAVE_GEM_NOC_CNOC, SC7280_SLAVE_LLCC },
 };
 
+static struct qcom_icc_qosbox qnm_mnoc_hf_qos = {
+	.num_ports = 2,
+	.offsets = { 0x23000, 0x63000 },
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_mnoc_hf = {
 	.name = "qnm_mnoc_hf",
 	.id = SC7280_MASTER_MNOC_HF_MEM_NOC,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_mnoc_hf_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_LLCC },
 };
 
+static struct qcom_icc_qosbox qnm_mnoc_sf_qos = {
+	.num_ports = 1,
+	.offsets = { 0xcf000 },
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_mnoc_sf = {
 	.name = "qnm_mnoc_sf",
 	.id = SC7280_MASTER_MNOC_SF_MEM_NOC,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qnm_mnoc_sf_qos,
 	.num_links = 2,
 	.links = { SC7280_SLAVE_GEM_NOC_CNOC, SC7280_SLAVE_LLCC },
 };
@@ -384,20 +542,36 @@
 	.links = { SC7280_SLAVE_GEM_NOC_CNOC, SC7280_SLAVE_LLCC },
 };
 
+static struct qcom_icc_qosbox qnm_snoc_gc_qos = {
+	.num_ports = 1,
+	.offsets = { 0xd3000 },
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_snoc_gc = {
 	.name = "qnm_snoc_gc",
 	.id = SC7280_MASTER_SNOC_GC_MEM_NOC,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qnm_snoc_gc_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_LLCC },
 };
 
+static struct qcom_icc_qosbox qnm_snoc_sf_qos = {
+	.num_ports = 1,
+	.offsets = { 0xd4000 },
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_snoc_sf = {
 	.name = "qnm_snoc_sf",
 	.id = SC7280_MASTER_SNOC_SF_MEM_NOC,
 	.channels = 1,
 	.buswidth = 16,
+	.qosbox = &qnm_snoc_sf_qos,
 	.num_links = 3,
 	.links = { SC7280_SLAVE_GEM_NOC_CNOC, SC7280_SLAVE_LLCC,
 		   SC7280_SLAVE_MEM_NOC_PCIE_SNOC },
@@ -432,56 +606,104 @@
 	.links = { SC7280_SLAVE_SERVICE_MNOC },
 };
 
+static struct qcom_icc_qosbox qnm_video0_qos = {
+	.num_ports = 1,
+	.offsets = { 0x14000 },
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_video0 = {
 	.name = "qnm_video0",
 	.id = SC7280_MASTER_VIDEO_P0,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qnm_video0_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_video_cpu_qos = {
+	.num_ports = 1,
+	.offsets = { 0x15000 },
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qnm_video_cpu = {
 	.name = "qnm_video_cpu",
 	.id = SC7280_MASTER_VIDEO_PROC,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qnm_video_cpu_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qxm_camnoc_hf_qos = {
+	.num_ports = 2,
+	.offsets = { 0x10000, 0x10180 },
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qxm_camnoc_hf = {
 	.name = "qxm_camnoc_hf",
 	.id = SC7280_MASTER_CAMNOC_HF,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qxm_camnoc_hf_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_MNOC_HF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qxm_camnoc_icp_qos = {
+	.num_ports = 1,
+	.offsets = { 0x11000 },
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qxm_camnoc_icp = {
 	.name = "qxm_camnoc_icp",
 	.id = SC7280_MASTER_CAMNOC_ICP,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qxm_camnoc_icp_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qxm_camnoc_sf_qos = {
+	.num_ports = 1,
+	.offsets = { 0x12000 },
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qxm_camnoc_sf = {
 	.name = "qxm_camnoc_sf",
 	.id = SC7280_MASTER_CAMNOC_SF,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qxm_camnoc_sf_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qxm_mdp0_qos = {
+	.num_ports = 1,
+	.offsets = { 0x16000 },
+	.prio = 0,
+	.urg_fwd = 1,
+};
+
 static struct qcom_icc_node qxm_mdp0 = {
 	.name = "qxm_mdp0",
 	.id = SC7280_MASTER_MDP0,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qxm_mdp0_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_MNOC_HF_MEM_NOC },
 };
@@ -531,20 +753,36 @@
 	.links = { SC7280_SLAVE_SERVICE_SNOC },
 };
 
+static struct qcom_icc_qosbox qxm_pimem_qos = {
+	.num_ports = 1,
+	.offsets = { 0x8000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node qxm_pimem = {
 	.name = "qxm_pimem",
 	.id = SC7280_MASTER_PIMEM,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qxm_pimem_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_SNOC_GEM_NOC_GC },
 };
 
+static struct qcom_icc_qosbox xm_gic_qos = {
+	.num_ports = 1,
+	.offsets = { 0xa000 },
+	.prio = 2,
+	.urg_fwd = 0,
+};
+
 static struct qcom_icc_node xm_gic = {
 	.name = "xm_gic",
 	.id = SC7280_MASTER_GIC,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_gic_qos,
 	.num_links = 1,
 	.links = { SC7280_SLAVE_SNOC_GEM_NOC_GC },
 };
@@ -1503,6 +1741,7 @@
 };
 
 static const struct qcom_icc_desc sc7280_aggre1_noc = {
+	.config = &icc_regmap_config,
 	.nodes = aggre1_noc_nodes,
 	.num_nodes = ARRAY_SIZE(aggre1_noc_nodes),
 	.bcms = aggre1_noc_bcms,
@@ -1525,6 +1764,7 @@
 };
 
 static const struct qcom_icc_desc sc7280_aggre2_noc = {
+	.config = &icc_regmap_config,
 	.nodes = aggre2_noc_nodes,
 	.num_nodes = ARRAY_SIZE(aggre2_noc_nodes),
 	.bcms = aggre2_noc_bcms,
@@ -1606,6 +1846,7 @@
 };
 
 static const struct qcom_icc_desc sc7280_cnoc2 = {
+	.config = &icc_regmap_config,
 	.nodes = cnoc2_nodes,
 	.num_nodes = ARRAY_SIZE(cnoc2_nodes),
 	.bcms = cnoc2_bcms,
@@ -1638,6 +1879,7 @@
 };
 
 static const struct qcom_icc_desc sc7280_cnoc3 = {
+	.config = &icc_regmap_config,
 	.nodes = cnoc3_nodes,
 	.num_nodes = ARRAY_SIZE(cnoc3_nodes),
 	.bcms = cnoc3_bcms,
@@ -1654,6 +1896,7 @@
 };
 
 static const struct qcom_icc_desc sc7280_dc_noc = {
+	.config = &icc_regmap_config,
 	.nodes = dc_noc_nodes,
 	.num_nodes = ARRAY_SIZE(dc_noc_nodes),
 	.bcms = dc_noc_bcms,
@@ -1690,6 +1933,7 @@
 };
 
 static const struct qcom_icc_desc sc7280_gem_noc = {
+	.config = &icc_regmap_config,
 	.nodes = gem_noc_nodes,
 	.num_nodes = ARRAY_SIZE(gem_noc_nodes),
 	.bcms = gem_noc_bcms,
@@ -1710,6 +1954,7 @@
 };
 
 static const struct qcom_icc_desc sc7280_lpass_ag_noc = {
+	.config = &icc_regmap_config,
 	.nodes = lpass_ag_noc_nodes,
 	.num_nodes = ARRAY_SIZE(lpass_ag_noc_nodes),
 	.bcms = lpass_ag_noc_bcms,
@@ -1727,6 +1972,7 @@
 };
 
 static const struct qcom_icc_desc sc7280_mc_virt = {
+	.config = &icc_regmap_config,
 	.nodes = mc_virt_nodes,
 	.num_nodes = ARRAY_SIZE(mc_virt_nodes),
 	.bcms = mc_virt_bcms,
@@ -1754,6 +2000,7 @@
 };
 
 static const struct qcom_icc_desc sc7280_mmss_noc = {
+	.config = &icc_regmap_config,
 	.nodes = mmss_noc_nodes,
 	.num_nodes = ARRAY_SIZE(mmss_noc_nodes),
 	.bcms = mmss_noc_bcms,
@@ -1773,6 +2020,7 @@
 };
 
 static const struct qcom_icc_desc sc7280_nsp_noc = {
+	.config = &icc_regmap_config,
 	.nodes = nsp_noc_nodes,
 	.num_nodes = ARRAY_SIZE(nsp_noc_nodes),
 	.bcms = nsp_noc_bcms,
@@ -1798,6 +2046,7 @@
 };
 
 static const struct qcom_icc_desc sc7280_system_noc = {
+	.config = &icc_regmap_config,
 	.nodes = system_noc_nodes,
 	.num_nodes = ARRAY_SIZE(system_noc_nodes),
 	.bcms = system_noc_bcms,
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/sm8350.c
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/sm8350.c
@@ -1965,6 +1965,7 @@
 	.driver = {
 		.name = "qnoc-sm8350",
 		.of_match_table = qnoc_of_match,
+		.sync_state = icc_sync_state,
 	},
 };
 module_platform_driver(qnoc_driver);
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/sm8550.c
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/sm8550.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2022, Linaro Limited
  *
  */
@@ -20,83 +20,170 @@
 #include "icc-rpmh.h"
 #include "sm8550.h"
 
+static const struct regmap_config icc_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+};
+
+static struct qcom_icc_qosbox qhm_qspi_qos = {
+	.num_ports = 1,
+	.offsets = { 0xb000 },
+	.prio = 2,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node qhm_qspi = {
 	.name = "qhm_qspi",
 	.id = SM8550_MASTER_QSPI_0,
 	.channels = 1,
 	.buswidth = 4,
+	.qosbox = &qhm_qspi_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qhm_qup1_qos = {
+	.num_ports = 1,
+	.offsets = { 0xc000 },
+	.prio = 2,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node qhm_qup1 = {
 	.name = "qhm_qup1",
 	.id = SM8550_MASTER_QUP_1,
 	.channels = 1,
 	.buswidth = 4,
+	.qosbox = &qhm_qup1_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_sdc4_qos = {
+	.num_ports = 1,
+	.offsets = { 0xd000 },
+	.prio = 2,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node xm_sdc4 = {
 	.name = "xm_sdc4",
 	.id = SM8550_MASTER_SDCC_4,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_sdc4_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_ufs_mem_qos = {
+	.num_ports = 1,
+	.offsets = { 0xe000 },
+	.prio = 2,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node xm_ufs_mem = {
 	.name = "xm_ufs_mem",
 	.id = SM8550_MASTER_UFS_MEM,
 	.channels = 1,
 	.buswidth = 16,
+	.qosbox = &xm_ufs_mem_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_usb3_0_qos = {
+	.num_ports = 1,
+	.offsets = { 0xf000 },
+	.prio = 2,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node xm_usb3_0 = {
 	.name = "xm_usb3_0",
 	.id = SM8550_MASTER_USB3_0,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_usb3_0_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_A1NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qhm_qdss_bam_qos = {
+	.num_ports = 1,
+	.offsets = { 0x12000 },
+	.prio = 2,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node qhm_qdss_bam = {
 	.name = "qhm_qdss_bam",
 	.id = SM8550_MASTER_QDSS_BAM,
 	.channels = 1,
 	.buswidth = 4,
+	.qosbox = &qhm_qdss_bam_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qhm_qup2_qos = {
+	.num_ports = 1,
+	.offsets = { 0x13000 },
+	.prio = 2,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node qhm_qup2 = {
 	.name = "qhm_qup2",
 	.id = SM8550_MASTER_QUP_2,
 	.channels = 1,
 	.buswidth = 4,
+	.qosbox = &qhm_qup2_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qxm_crypto_qos = {
+	.num_ports = 1,
+	.offsets = { 0x15000 },
+	.prio = 2,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node qxm_crypto = {
 	.name = "qxm_crypto",
 	.id = SM8550_MASTER_CRYPTO,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qxm_crypto_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox qxm_ipa_qos = {
+	.num_ports = 1,
+	.offsets = { 0x16000 },
+	.prio = 2,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node qxm_ipa = {
 	.name = "qxm_ipa",
 	.id = SM8550_MASTER_IPA,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qxm_ipa_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_A2NOC_SNOC },
 };
@@ -110,29 +197,56 @@
 	.links = { SM8550_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_qdss_etr_0_qos = {
+	.num_ports = 1,
+	.offsets = { 0x17000 },
+	.prio = 2,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node xm_qdss_etr_0 = {
 	.name = "xm_qdss_etr_0",
 	.id = SM8550_MASTER_QDSS_ETR,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_qdss_etr_0_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_qdss_etr_1_qos = {
+	.num_ports = 1,
+	.offsets = { 0x18000 },
+	.prio = 2,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node xm_qdss_etr_1 = {
 	.name = "xm_qdss_etr_1",
 	.id = SM8550_MASTER_QDSS_ETR_1,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_qdss_etr_1_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_A2NOC_SNOC },
 };
 
+static struct qcom_icc_qosbox xm_sdc2_qos = {
+	.num_ports = 1,
+	.offsets = { 0x19000 },
+	.prio = 2,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node xm_sdc2 = {
 	.name = "xm_sdc2",
 	.id = SM8550_MASTER_SDCC_2,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_sdc2_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_A2NOC_SNOC },
 };
@@ -214,20 +328,38 @@
 	.links = { SM8550_SLAVE_PCIE_0, SM8550_SLAVE_PCIE_1 },
 };
 
+static struct qcom_icc_qosbox alm_gpu_tcu_qos = {
+	.num_ports = 1,
+	.offsets = { 0xb1000 },
+	.prio = 1,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node alm_gpu_tcu = {
 	.name = "alm_gpu_tcu",
 	.id = SM8550_MASTER_GPU_TCU,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &alm_gpu_tcu_qos,
 	.num_links = 2,
 	.links = { SM8550_SLAVE_GEM_NOC_CNOC, SM8550_SLAVE_LLCC },
 };
 
+static struct qcom_icc_qosbox alm_sys_tcu_qos = {
+	.num_ports = 1,
+	.offsets = { 0xb3000 },
+	.prio = 6,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node alm_sys_tcu = {
 	.name = "alm_sys_tcu",
 	.id = SM8550_MASTER_SYS_TCU,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &alm_sys_tcu_qos,
 	.num_links = 2,
 	.links = { SM8550_SLAVE_GEM_NOC_CNOC, SM8550_SLAVE_LLCC },
 };
@@ -242,20 +374,38 @@
 		   SM8550_SLAVE_MEM_NOC_PCIE_SNOC },
 };
 
+static struct qcom_icc_qosbox qnm_gpu_qos = {
+	.num_ports = 2,
+	.offsets = { 0x31000, 0x71000 },
+	.prio = 0,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node qnm_gpu = {
 	.name = "qnm_gpu",
 	.id = SM8550_MASTER_GFX3D,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_gpu_qos,
 	.num_links = 2,
 	.links = { SM8550_SLAVE_GEM_NOC_CNOC, SM8550_SLAVE_LLCC },
 };
 
+static struct qcom_icc_qosbox qnm_lpass_gemnoc_qos = {
+	.num_ports = 1,
+	.offsets = { 0xb5000 },
+	.prio = 0,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 0,
+};
+
 static struct qcom_icc_node qnm_lpass_gemnoc = {
 	.name = "qnm_lpass_gemnoc",
 	.id = SM8550_MASTER_LPASS_GEM_NOC,
 	.channels = 1,
 	.buswidth = 16,
+	.qosbox = &qnm_lpass_gemnoc_qos,
 	.num_links = 3,
 	.links = { SM8550_SLAVE_GEM_NOC_CNOC, SM8550_SLAVE_LLCC,
 		   SM8550_SLAVE_MEM_NOC_PCIE_SNOC },
@@ -271,56 +421,110 @@
 		   SM8550_SLAVE_MEM_NOC_PCIE_SNOC },
 };
 
+static struct qcom_icc_qosbox qnm_mnoc_hf_qos = {
+	.num_ports = 2,
+	.offsets = { 0x33000, 0x73000 },
+	.prio = 0,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 0,
+};
+
 static struct qcom_icc_node qnm_mnoc_hf = {
 	.name = "qnm_mnoc_hf",
 	.id = SM8550_MASTER_MNOC_HF_MEM_NOC,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_mnoc_hf_qos,
 	.num_links = 2,
 	.links = { SM8550_SLAVE_GEM_NOC_CNOC, SM8550_SLAVE_LLCC },
 };
 
+static struct qcom_icc_qosbox qnm_mnoc_sf_qos = {
+	.num_ports = 2,
+	.offsets = { 0x35000, 0x75000 },
+	.prio = 0,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 0,
+};
+
 static struct qcom_icc_node qnm_mnoc_sf = {
 	.name = "qnm_mnoc_sf",
 	.id = SM8550_MASTER_MNOC_SF_MEM_NOC,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_mnoc_sf_qos,
 	.num_links = 2,
 	.links = { SM8550_SLAVE_GEM_NOC_CNOC, SM8550_SLAVE_LLCC },
 };
 
+static struct qcom_icc_qosbox qnm_nsp_gemnoc_qos = {
+	.num_ports = 2,
+	.offsets = { 0x37000, 0x77000 },
+	.prio = 0,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node qnm_nsp_gemnoc = {
 	.name = "qnm_nsp_gemnoc",
 	.id = SM8550_MASTER_COMPUTE_NOC,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_nsp_gemnoc_qos,
 	.num_links = 2,
 	.links = { SM8550_SLAVE_GEM_NOC_CNOC, SM8550_SLAVE_LLCC },
 };
 
+static struct qcom_icc_qosbox qnm_pcie_qos = {
+	.num_ports = 1,
+	.offsets = { 0xb7000 },
+	.prio = 2,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 0,
+};
+
 static struct qcom_icc_node qnm_pcie = {
 	.name = "qnm_pcie",
 	.id = SM8550_MASTER_ANOC_PCIE_GEM_NOC,
 	.channels = 1,
 	.buswidth = 16,
+	.qosbox = &qnm_pcie_qos,
 	.num_links = 2,
 	.links = { SM8550_SLAVE_GEM_NOC_CNOC, SM8550_SLAVE_LLCC },
 };
 
+static struct qcom_icc_qosbox qnm_snoc_gc_qos = {
+	.num_ports = 1,
+	.offsets = { 0xb9000 },
+	.prio = 0,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 0,
+};
+
 static struct qcom_icc_node qnm_snoc_gc = {
 	.name = "qnm_snoc_gc",
 	.id = SM8550_MASTER_SNOC_GC_MEM_NOC,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qnm_snoc_gc_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_LLCC },
 };
 
+static struct qcom_icc_qosbox qnm_snoc_sf_qos = {
+	.num_ports = 1,
+	.offsets = { 0xbb000 },
+	.prio = 0,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 0,
+};
+
 static struct qcom_icc_node qnm_snoc_sf = {
 	.name = "qnm_snoc_sf",
 	.id = SM8550_MASTER_SNOC_SF_MEM_NOC,
 	.channels = 1,
 	.buswidth = 16,
+	.qosbox = &qnm_snoc_sf_qos,
 	.num_links = 3,
 	.links = { SM8550_SLAVE_GEM_NOC_CNOC, SM8550_SLAVE_LLCC,
 		   SM8550_SLAVE_MEM_NOC_PCIE_SNOC },
@@ -362,38 +566,74 @@
 	.links = { SM8550_SLAVE_EBI1 },
 };
 
+static struct qcom_icc_qosbox qnm_camnoc_hf_qos = {
+	.num_ports = 2,
+	.offsets = { 0x28000, 0x29000 },
+	.prio = 0,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 0,
+};
+
 static struct qcom_icc_node qnm_camnoc_hf = {
 	.name = "qnm_camnoc_hf",
 	.id = SM8550_MASTER_CAMNOC_HF,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_camnoc_hf_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_MNOC_HF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_camnoc_icp_qos = {
+	.num_ports = 1,
+	.offsets = { 0x2a000 },
+	.prio = 4,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node qnm_camnoc_icp = {
 	.name = "qnm_camnoc_icp",
 	.id = SM8550_MASTER_CAMNOC_ICP,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qnm_camnoc_icp_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_camnoc_sf_qos = {
+	.num_ports = 2,
+	.offsets = { 0x2b000, 0x2c000 },
+	.prio = 0,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 0,
+};
+
 static struct qcom_icc_node qnm_camnoc_sf = {
 	.name = "qnm_camnoc_sf",
 	.id = SM8550_MASTER_CAMNOC_SF,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_camnoc_sf_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_mdp_qos = {
+	.num_ports = 2,
+	.offsets = { 0x2d000, 0x2e000 },
+	.prio = 0,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 0,
+};
+
 static struct qcom_icc_node qnm_mdp = {
 	.name = "qnm_mdp",
 	.id = SM8550_MASTER_MDP,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_mdp_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_MNOC_HF_MEM_NOC },
 };
@@ -407,38 +647,74 @@
 	.links = { SM8550_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_video_qos = {
+	.num_ports = 2,
+	.offsets = { 0x30000, 0x31000 },
+	.prio = 0,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 0,
+};
+
 static struct qcom_icc_node qnm_video = {
 	.name = "qnm_video",
 	.id = SM8550_MASTER_VIDEO,
 	.channels = 2,
 	.buswidth = 32,
+	.qosbox = &qnm_video_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_video_cv_cpu_qos = {
+	.num_ports = 1,
+	.offsets = { 0x32000 },
+	.prio = 4,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node qnm_video_cv_cpu = {
 	.name = "qnm_video_cv_cpu",
 	.id = SM8550_MASTER_VIDEO_CV_PROC,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qnm_video_cv_cpu_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_video_cvp_qos = {
+	.num_ports = 1,
+	.offsets = { 0x33000 },
+	.prio = 0,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 0,
+};
+
 static struct qcom_icc_node qnm_video_cvp = {
 	.name = "qnm_video_cvp",
 	.id = SM8550_MASTER_VIDEO_PROC,
 	.channels = 1,
 	.buswidth = 32,
+	.qosbox = &qnm_video_cvp_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_MNOC_SF_MEM_NOC },
 };
 
+static struct qcom_icc_qosbox qnm_video_v_cpu_qos = {
+	.num_ports = 1,
+	.offsets = { 0x34000 },
+	.prio = 4,
+	.urg_fwd = 1,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node qnm_video_v_cpu = {
 	.name = "qnm_video_v_cpu",
 	.id = SM8550_MASTER_VIDEO_V_PROC,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &qnm_video_v_cpu_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_MNOC_SF_MEM_NOC },
 };
@@ -470,29 +746,56 @@
 	.links = { SM8550_SLAVE_SERVICE_PCIE_ANOC },
 };
 
+static struct qcom_icc_qosbox xm_pcie3_0_qos = {
+	.num_ports = 1,
+	.offsets = { 0xb000 },
+	.prio = 3,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node xm_pcie3_0 = {
 	.name = "xm_pcie3_0",
 	.id = SM8550_MASTER_PCIE_0,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_pcie3_0_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_ANOC_PCIE_GEM_NOC },
 };
 
+static struct qcom_icc_qosbox xm_pcie3_1_qos = {
+	.num_ports = 1,
+	.offsets = { 0xc000 },
+	.prio = 2,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node xm_pcie3_1 = {
 	.name = "xm_pcie3_1",
 	.id = SM8550_MASTER_PCIE_1,
 	.channels = 1,
 	.buswidth = 16,
+	.qosbox = &xm_pcie3_1_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_ANOC_PCIE_GEM_NOC },
 };
 
+static struct qcom_icc_qosbox qhm_gic_qos = {
+	.num_ports = 1,
+	.offsets = { 0x1c000 },
+	.prio = 2,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node qhm_gic = {
 	.name = "qhm_gic",
 	.id = SM8550_MASTER_GIC_AHB,
 	.channels = 1,
 	.buswidth = 4,
+	.qosbox = &qhm_gic_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_SNOC_GEM_NOC_SF },
 };
@@ -515,11 +818,20 @@
 	.links = { SM8550_SLAVE_SNOC_GEM_NOC_SF },
 };
 
+static struct qcom_icc_qosbox xm_gic_qos = {
+	.num_ports = 1,
+	.offsets = { 0x1d000 },
+	.prio = 2,
+	.urg_fwd = 0,
+	.prio_fwd_disable = 1,
+};
+
 static struct qcom_icc_node xm_gic = {
 	.name = "xm_gic",
 	.id = SM8550_MASTER_GIC,
 	.channels = 1,
 	.buswidth = 8,
+	.qosbox = &xm_gic_qos,
 	.num_links = 1,
 	.links = { SM8550_SLAVE_SNOC_GEM_NOC_GC },
 };
@@ -1476,6 +1788,7 @@
 static struct qcom_icc_bcm bcm_acv = {
 	.name = "ACV",
 	.enable_mask = 0x8,
+	.perf_mode_mask = 0x2,
 	.num_nodes = 1,
 	.nodes = { &ebi },
 };
@@ -1642,6 +1955,7 @@
 static struct qcom_icc_bcm bcm_acv_disp = {
 	.name = "ACV",
 	.enable_mask = 0x1,
+	.perf_mode_mask = 0x2,
 	.num_nodes = 1,
 	.nodes = { &ebi_disp },
 };
@@ -1807,6 +2121,7 @@
 };
 
 static const struct qcom_icc_desc sm8550_aggre1_noc = {
+	.config = &icc_regmap_config,
 	.nodes = aggre1_noc_nodes,
 	.num_nodes = ARRAY_SIZE(aggre1_noc_nodes),
 	.bcms = aggre1_noc_bcms,
@@ -1830,6 +2145,7 @@
 };
 
 static const struct qcom_icc_desc sm8550_aggre2_noc = {
+	.config = &icc_regmap_config,
 	.nodes = aggre2_noc_nodes,
 	.num_nodes = ARRAY_SIZE(aggre2_noc_nodes),
 	.bcms = aggre2_noc_bcms,
@@ -1852,6 +2168,7 @@
 };
 
 static const struct qcom_icc_desc sm8550_clk_virt = {
+	.config = &icc_regmap_config,
 	.nodes = clk_virt_nodes,
 	.num_nodes = ARRAY_SIZE(clk_virt_nodes),
 	.bcms = clk_virt_bcms,
@@ -1912,6 +2229,7 @@
 };
 
 static const struct qcom_icc_desc sm8550_config_noc = {
+	.config = &icc_regmap_config,
 	.nodes = config_noc_nodes,
 	.num_nodes = ARRAY_SIZE(config_noc_nodes),
 	.bcms = config_noc_bcms,
@@ -1936,6 +2254,7 @@
 };
 
 static const struct qcom_icc_desc sm8550_cnoc_main = {
+	.config = &icc_regmap_config,
 	.nodes = cnoc_main_nodes,
 	.num_nodes = ARRAY_SIZE(cnoc_main_nodes),
 	.bcms = cnoc_main_bcms,
@@ -1989,6 +2308,7 @@
 };
 
 static const struct qcom_icc_desc sm8550_gem_noc = {
+	.config = &icc_regmap_config,
 	.nodes = gem_noc_nodes,
 	.num_nodes = ARRAY_SIZE(gem_noc_nodes),
 	.bcms = gem_noc_bcms,
@@ -2004,6 +2324,7 @@
 };
 
 static const struct qcom_icc_desc sm8550_lpass_ag_noc = {
+	.config = &icc_regmap_config,
 	.nodes = lpass_ag_noc_nodes,
 	.num_nodes = ARRAY_SIZE(lpass_ag_noc_nodes),
 	.bcms = lpass_ag_noc_bcms,
@@ -2020,6 +2341,7 @@
 };
 
 static const struct qcom_icc_desc sm8550_lpass_lpiaon_noc = {
+	.config = &icc_regmap_config,
 	.nodes = lpass_lpiaon_noc_nodes,
 	.num_nodes = ARRAY_SIZE(lpass_lpiaon_noc_nodes),
 	.bcms = lpass_lpiaon_noc_bcms,
@@ -2035,6 +2357,7 @@
 };
 
 static const struct qcom_icc_desc sm8550_lpass_lpicx_noc = {
+	.config = &icc_regmap_config,
 	.nodes = lpass_lpicx_noc_nodes,
 	.num_nodes = ARRAY_SIZE(lpass_lpicx_noc_nodes),
 	.bcms = lpass_lpicx_noc_bcms,
@@ -2068,6 +2391,7 @@
 };
 
 static const struct qcom_icc_desc sm8550_mc_virt = {
+	.config = &icc_regmap_config,
 	.nodes = mc_virt_nodes,
 	.num_nodes = ARRAY_SIZE(mc_virt_nodes),
 	.bcms = mc_virt_bcms,
@@ -2120,6 +2444,7 @@
 };
 
 static const struct qcom_icc_desc sm8550_mmss_noc = {
+	.config = &icc_regmap_config,
 	.nodes = mmss_noc_nodes,
 	.num_nodes = ARRAY_SIZE(mmss_noc_nodes),
 	.bcms = mmss_noc_bcms,
@@ -2136,6 +2461,7 @@
 };
 
 static const struct qcom_icc_desc sm8550_nsp_noc = {
+	.config = &icc_regmap_config,
 	.nodes = nsp_noc_nodes,
 	.num_nodes = ARRAY_SIZE(nsp_noc_nodes),
 	.bcms = nsp_noc_bcms,
@@ -2155,6 +2481,7 @@
 };
 
 static const struct qcom_icc_desc sm8550_pcie_anoc = {
+	.config = &icc_regmap_config,
 	.nodes = pcie_anoc_nodes,
 	.num_nodes = ARRAY_SIZE(pcie_anoc_nodes),
 	.bcms = pcie_anoc_bcms,
@@ -2178,6 +2505,7 @@
 };
 
 static const struct qcom_icc_desc sm8550_system_noc = {
+	.config = &icc_regmap_config,
 	.nodes = system_noc_nodes,
 	.num_nodes = ARRAY_SIZE(system_noc_nodes),
 	.bcms = system_noc_bcms,
--- linux-qcom-6.8.0.orig/drivers/interconnect/qcom/x1e80100.c
+++ linux-qcom-6.8.0/drivers/interconnect/qcom/x1e80100.c
@@ -116,15 +116,6 @@
 	.links = { X1E80100_SLAVE_A2NOC_SNOC },
 };
 
-static struct qcom_icc_node ddr_perf_mode_master = {
-	.name = "ddr_perf_mode_master",
-	.id = X1E80100_MASTER_DDR_PERF_MODE,
-	.channels = 1,
-	.buswidth = 4,
-	.num_links = 1,
-	.links = { X1E80100_SLAVE_DDR_PERF_MODE },
-};
-
 static struct qcom_icc_node qup0_core_master = {
 	.name = "qup0_core_master",
 	.id = X1E80100_MASTER_QUP_CORE_0,
@@ -832,14 +823,6 @@
 	.links = { X1E80100_MASTER_A2NOC_SNOC },
 };
 
-static struct qcom_icc_node ddr_perf_mode_slave = {
-	.name = "ddr_perf_mode_slave",
-	.id = X1E80100_SLAVE_DDR_PERF_MODE,
-	.channels = 1,
-	.buswidth = 4,
-	.num_links = 0,
-};
-
 static struct qcom_icc_node qup0_core_slave = {
 	.name = "qup0_core_slave",
 	.id = X1E80100_SLAVE_QUP_CORE_0,
@@ -1591,12 +1574,6 @@
 	.nodes = { &ebi },
 };
 
-static struct qcom_icc_bcm bcm_acv_perf = {
-	.name = "ACV_PERF",
-	.num_nodes = 1,
-	.nodes = { &ddr_perf_mode_slave },
-};
-
 static struct qcom_icc_bcm bcm_ce0 = {
 	.name = "CE0",
 	.num_nodes = 1,
@@ -1863,18 +1840,15 @@
 };
 
 static struct qcom_icc_bcm * const clk_virt_bcms[] = {
-	&bcm_acv_perf,
 	&bcm_qup0,
 	&bcm_qup1,
 	&bcm_qup2,
 };
 
 static struct qcom_icc_node * const clk_virt_nodes[] = {
-	[MASTER_DDR_PERF_MODE] = &ddr_perf_mode_master,
 	[MASTER_QUP_CORE_0] = &qup0_core_master,
 	[MASTER_QUP_CORE_1] = &qup1_core_master,
 	[MASTER_QUP_CORE_2] = &qup2_core_master,
-	[SLAVE_DDR_PERF_MODE] = &ddr_perf_mode_slave,
 	[SLAVE_QUP_CORE_0] = &qup0_core_slave,
 	[SLAVE_QUP_CORE_1] = &qup1_core_slave,
 	[SLAVE_QUP_CORE_2] = &qup2_core_slave,
--- linux-qcom-6.8.0.orig/drivers/iommu/Kconfig
+++ linux-qcom-6.8.0/drivers/iommu/Kconfig
@@ -196,7 +196,7 @@
 config IRQ_REMAP
 	bool "Support for Interrupt Remapping"
 	depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI
-	select DMAR_TABLE
+	select DMAR_TABLE if INTEL_IOMMU
 	help
 	  Supports Interrupt remapping for IO-APIC and MSI devices.
 	  To use x2apic mode in the CPU's which support x2APIC enhancements or
@@ -371,6 +371,15 @@
 	  When running on a Qualcomm platform that has the custom variant
 	  of the ARM SMMU, this needs to be built into the SMMU driver.
 
+config ARM_SMMU_QCOM_TBU
+	bool "Qualcomm Technologies, Inc. TBU driver"
+	depends on ARM_SMMU_QCOM
+	help
+	  The SMMU on Qualcomm Technologies, Inc. platform may include a
+	  Translation Buffer Units (TBUs) for each master. Enabling support
+	  for these will allow operating the TBUs to help debugging context
+	  faults.
+
 config ARM_SMMU_QCOM_DEBUG
 	bool "ARM SMMU QCOM implementation defined debug support"
 	depends on ARM_SMMU_QCOM
--- linux-qcom-6.8.0.orig/drivers/iommu/amd/amd_iommu_types.h
+++ linux-qcom-6.8.0/drivers/iommu/amd/amd_iommu_types.h
@@ -549,6 +549,11 @@
 	u64			*pgd;		/* v2 pgtable pgd pointer */
 };
 
+enum protection_domain_mode {
+	PD_MODE_V1 = 1,
+	PD_MODE_V2,
+};
+
 /*
  * This structure contains generic data for  IOMMU protection domains
  * independent of their use.
@@ -564,6 +569,7 @@
 	int nid;		/* Node ID */
 	u64 *gcr3_tbl;		/* Guest CR3 table */
 	unsigned long flags;	/* flags to find out type of domain */
+	enum protection_domain_mode pd_mode; /* Track page table type */
 	bool dirty_tracking;	/* dirty tracking is enabled in the domain */
 	unsigned dev_cnt;	/* devices assigned to this domain */
 	unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
--- linux-qcom-6.8.0.orig/drivers/iommu/amd/init.c
+++ linux-qcom-6.8.0/drivers/iommu/amd/init.c
@@ -1677,8 +1677,17 @@
 	}
 }
 
+static void __init free_sysfs(struct amd_iommu *iommu)
+{
+	if (iommu->iommu.dev) {
+		iommu_device_unregister(&iommu->iommu);
+		iommu_device_sysfs_remove(&iommu->iommu);
+	}
+}
+
 static void __init free_iommu_one(struct amd_iommu *iommu)
 {
+	free_sysfs(iommu);
 	free_cwwb_sem(iommu);
 	free_command_buffer(iommu);
 	free_event_buffer(iommu);
@@ -2068,6 +2077,9 @@
 	/* Prevent binding other PCI device drivers to IOMMU devices */
 	iommu->dev->match_driver = false;
 
+	/* ACPI _PRT won't have an IRQ for IOMMU */
+	iommu->dev->irq_managed = 1;
+
 	pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET,
 			      &iommu->cap);
 
@@ -2769,6 +2781,7 @@
 	iommu_enable_command_buffer(iommu);
 	iommu_enable_event_buffer(iommu);
 	iommu_set_exclusion_range(iommu);
+	iommu_enable_gt(iommu);
 	iommu_enable_ga(iommu);
 	iommu_enable_xt(iommu);
 	iommu_enable_irtcachedis(iommu);
--- linux-qcom-6.8.0.orig/drivers/iommu/amd/io_pgtable.c
+++ linux-qcom-6.8.0/drivers/iommu/amd/io_pgtable.c
@@ -573,23 +573,24 @@
 	       pgtable->mode > PAGE_MODE_6_LEVEL);
 
 	free_sub_pt(pgtable->root, pgtable->mode, &freelist);
+	put_pages_list(&freelist);
 
 	/* Update data structure */
 	amd_iommu_domain_clr_pt_root(dom);
-
-	/* Make changes visible to IOMMUs */
-	amd_iommu_domain_update(dom);
-
-	put_pages_list(&freelist);
 }
 
 static struct io_pgtable *v1_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
 {
 	struct amd_io_pgtable *pgtable = io_pgtable_cfg_to_data(cfg);
 
-	cfg->pgsize_bitmap  = AMD_IOMMU_PGSIZES,
-	cfg->ias            = IOMMU_IN_ADDR_BIT_SIZE,
-	cfg->oas            = IOMMU_OUT_ADDR_BIT_SIZE,
+	pgtable->root = (void *) get_zeroed_page(GFP_KERNEL);
+	if (!pgtable->root)
+		return NULL;
+	pgtable->mode = PAGE_MODE_3_LEVEL;
+
+	cfg->pgsize_bitmap  = AMD_IOMMU_PGSIZES;
+	cfg->ias            = IOMMU_IN_ADDR_BIT_SIZE;
+	cfg->oas            = IOMMU_OUT_ADDR_BIT_SIZE;
 	cfg->tlb            = &v1_flush_ops;
 
 	pgtable->iop.ops.map_pages    = iommu_v1_map_pages;
--- linux-qcom-6.8.0.orig/drivers/iommu/amd/io_pgtable_v2.c
+++ linux-qcom-6.8.0/drivers/iommu/amd/io_pgtable_v2.c
@@ -50,7 +50,7 @@
 	u64 prot;
 
 	prot = IOMMU_PAGE_PRESENT | IOMMU_PAGE_RW | IOMMU_PAGE_USER;
-	prot |= IOMMU_PAGE_ACCESS | IOMMU_PAGE_DIRTY;
+	prot |= IOMMU_PAGE_ACCESS;
 
 	return (iommu_virt_to_phys(page) | prot);
 }
@@ -270,8 +270,13 @@
 	}
 
 out:
-	if (updated)
+	if (updated) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&pdom->lock, flags);
 		amd_iommu_domain_flush_pages(pdom, o_iova, size);
+		spin_unlock_irqrestore(&pdom->lock, flags);
+	}
 
 	if (mapped)
 		*mapped += mapped_size;
@@ -374,7 +379,7 @@
 	int ret;
 	int ias = IOMMU_IN_ADDR_BIT_SIZE;
 
-	pgtable->pgd = alloc_pgtable_page(pdom->nid, GFP_ATOMIC);
+	pgtable->pgd = alloc_pgtable_page(pdom->nid, GFP_KERNEL);
 	if (!pgtable->pgd)
 		return NULL;
 
--- linux-qcom-6.8.0.orig/drivers/iommu/amd/iommu.c
+++ linux-qcom-6.8.0/drivers/iommu/amd/iommu.c
@@ -55,8 +55,6 @@
 #define HT_RANGE_START		(0xfd00000000ULL)
 #define HT_RANGE_END		(0xffffffffffULL)
 
-#define DEFAULT_PGTABLE_LEVEL	PAGE_MODE_3_LEVEL
-
 static DEFINE_SPINLOCK(pd_bitmap_lock);
 
 LIST_HEAD(ioapic_map);
@@ -2067,56 +2065,25 @@
 	if (!domain)
 		return;
 
+	WARN_ON(!list_empty(&domain->dev_list));
+
 	if (domain->iop.pgtbl_cfg.tlb)
 		free_io_pgtable_ops(&domain->iop.iop.ops);
 
 	if (domain->flags & PD_IOMMUV2_MASK)
 		free_gcr3_table(domain);
 
-	if (domain->iop.root)
-		free_page((unsigned long)domain->iop.root);
-
 	if (domain->id)
 		domain_id_free(domain->id);
 
 	kfree(domain);
 }
 
-static int protection_domain_init_v1(struct protection_domain *domain, int mode)
-{
-	u64 *pt_root = NULL;
-
-	BUG_ON(mode < PAGE_MODE_NONE || mode > PAGE_MODE_6_LEVEL);
-
-	if (mode != PAGE_MODE_NONE) {
-		pt_root = (void *)get_zeroed_page(GFP_KERNEL);
-		if (!pt_root)
-			return -ENOMEM;
-	}
-
-	amd_iommu_domain_set_pgtable(domain, pt_root, mode);
-
-	return 0;
-}
-
-static int protection_domain_init_v2(struct protection_domain *domain)
-{
-	domain->flags |= PD_GIOV_MASK;
-
-	domain->domain.pgsize_bitmap = AMD_IOMMU_PGSIZES_V2;
-
-	if (setup_gcr3_table(domain, 1))
-		return -ENOMEM;
-
-	return 0;
-}
-
 static struct protection_domain *protection_domain_alloc(unsigned int type)
 {
 	struct io_pgtable_ops *pgtbl_ops;
 	struct protection_domain *domain;
 	int pgtable;
-	int ret;
 
 	domain = kzalloc(sizeof(*domain), GFP_KERNEL);
 	if (!domain)
@@ -2150,18 +2117,18 @@
 
 	switch (pgtable) {
 	case AMD_IOMMU_V1:
-		ret = protection_domain_init_v1(domain, DEFAULT_PGTABLE_LEVEL);
+		domain->pd_mode = PD_MODE_V1;
 		break;
 	case AMD_IOMMU_V2:
-		ret = protection_domain_init_v2(domain);
+		domain->flags |= PD_GIOV_MASK;
+		domain->pd_mode = PD_MODE_V2;
+
+		if (setup_gcr3_table(domain, 1))
+			goto out_err;
 		break;
 	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	if (ret)
 		goto out_err;
+	}
 
 	pgtbl_ops = alloc_io_pgtable_ops(pgtable, &domain->iop.pgtbl_cfg, domain);
 	if (!pgtbl_ops)
@@ -2217,10 +2184,10 @@
 	domain->domain.geometry.aperture_start = 0;
 	domain->domain.geometry.aperture_end   = dma_max_address();
 	domain->domain.geometry.force_aperture = true;
+	domain->domain.pgsize_bitmap = domain->iop.iop.cfg.pgsize_bitmap;
 
 	if (iommu) {
 		domain->domain.type = type;
-		domain->domain.pgsize_bitmap = iommu->iommu.ops->pgsize_bitmap;
 		domain->domain.ops = iommu->iommu.ops->default_domain_ops;
 
 		if (dirty_tracking)
@@ -2593,6 +2560,10 @@
 	if (!dev_data)
 		return 0;
 
+	/* Always use DMA domain for untrusted device */
+	if (dev_is_pci(dev) && to_pci_dev(dev)->untrusted)
+		return IOMMU_DOMAIN_DMA;
+
 	/*
 	 * Do not identity map IOMMUv2 capable devices when:
 	 *  - memory encryption is active, because some of those devices
@@ -2630,7 +2601,6 @@
 	.device_group = amd_iommu_device_group,
 	.get_resv_regions = amd_iommu_get_resv_regions,
 	.is_attach_deferred = amd_iommu_is_attach_deferred,
-	.pgsize_bitmap	= AMD_IOMMU_PGSIZES,
 	.def_domain_type = amd_iommu_def_domain_type,
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev	= amd_iommu_attach_device,
--- linux-qcom-6.8.0.orig/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
+++ linux-qcom-6.8.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
@@ -575,6 +575,9 @@
 	int ret = 0;
 	struct mm_struct *mm = domain->mm;
 
+	if (mm_get_enqcmd_pasid(mm) != id)
+		return -EINVAL;
+
 	mutex_lock(&sva_lock);
 	ret = __arm_smmu_sva_bind(dev, id, mm);
 	mutex_unlock(&sva_lock);
--- linux-qcom-6.8.0.orig/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ linux-qcom-6.8.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -999,8 +999,8 @@
 {
 	size_t size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3);
 
-	l1_desc->l2ptr = dmam_alloc_coherent(smmu->dev, size,
-					     &l1_desc->l2ptr_dma, GFP_KERNEL);
+	l1_desc->l2ptr = dma_alloc_coherent(smmu->dev, size,
+					    &l1_desc->l2ptr_dma, GFP_KERNEL);
 	if (!l1_desc->l2ptr) {
 		dev_warn(smmu->dev,
 			 "failed to allocate context descriptor table\n");
@@ -1151,17 +1151,17 @@
 		cd_table->num_l1_ents = DIV_ROUND_UP(max_contexts,
 						  CTXDESC_L2_ENTRIES);
 
-		cd_table->l1_desc = devm_kcalloc(smmu->dev, cd_table->num_l1_ents,
-					      sizeof(*cd_table->l1_desc),
-					      GFP_KERNEL);
+		cd_table->l1_desc = kcalloc(cd_table->num_l1_ents,
+					    sizeof(*cd_table->l1_desc),
+					    GFP_KERNEL);
 		if (!cd_table->l1_desc)
 			return -ENOMEM;
 
 		l1size = cd_table->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3);
 	}
 
-	cd_table->cdtab = dmam_alloc_coherent(smmu->dev, l1size, &cd_table->cdtab_dma,
-					   GFP_KERNEL);
+	cd_table->cdtab = dma_alloc_coherent(smmu->dev, l1size,
+					     &cd_table->cdtab_dma, GFP_KERNEL);
 	if (!cd_table->cdtab) {
 		dev_warn(smmu->dev, "failed to allocate context descriptor\n");
 		ret = -ENOMEM;
@@ -1172,7 +1172,7 @@
 
 err_free_l1:
 	if (cd_table->l1_desc) {
-		devm_kfree(smmu->dev, cd_table->l1_desc);
+		kfree(cd_table->l1_desc);
 		cd_table->l1_desc = NULL;
 	}
 	return ret;
@@ -1192,21 +1192,18 @@
 			if (!cd_table->l1_desc[i].l2ptr)
 				continue;
 
-			dmam_free_coherent(smmu->dev, size,
-					   cd_table->l1_desc[i].l2ptr,
-					   cd_table->l1_desc[i].l2ptr_dma);
+			dma_free_coherent(smmu->dev, size,
+					  cd_table->l1_desc[i].l2ptr,
+					  cd_table->l1_desc[i].l2ptr_dma);
 		}
-		devm_kfree(smmu->dev, cd_table->l1_desc);
-		cd_table->l1_desc = NULL;
+		kfree(cd_table->l1_desc);
 
 		l1size = cd_table->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3);
 	} else {
 		l1size = cd_table->num_l1_ents * (CTXDESC_CD_DWORDS << 3);
 	}
 
-	dmam_free_coherent(smmu->dev, l1size, cd_table->cdtab, cd_table->cdtab_dma);
-	cd_table->cdtab_dma = 0;
-	cd_table->cdtab = NULL;
+	dma_free_coherent(smmu->dev, l1size, cd_table->cdtab, cd_table->cdtab_dma);
 }
 
 bool arm_smmu_free_asid(struct arm_smmu_ctx_desc *cd)
@@ -2398,8 +2395,6 @@
 		return -EBUSY;
 	}
 
-	arm_smmu_detach_dev(master);
-
 	mutex_lock(&smmu_domain->init_mutex);
 
 	if (!smmu_domain->smmu) {
@@ -2414,6 +2409,16 @@
 	if (ret)
 		return ret;
 
+	/*
+	 * Prevent arm_smmu_share_asid() from trying to change the ASID
+	 * of either the old or new domain while we are working on it.
+	 * This allows the STE and the smmu_domain->devices list to
+	 * be inconsistent during this routine.
+	 */
+	mutex_lock(&arm_smmu_asid_lock);
+
+	arm_smmu_detach_dev(master);
+
 	master->domain = smmu_domain;
 
 	/*
@@ -2439,13 +2444,7 @@
 			}
 		}
 
-		/*
-		 * Prevent SVA from concurrently modifying the CD or writing to
-		 * the CD entry
-		 */
-		mutex_lock(&arm_smmu_asid_lock);
 		ret = arm_smmu_write_ctx_desc(master, IOMMU_NO_PASID, &smmu_domain->cd);
-		mutex_unlock(&arm_smmu_asid_lock);
 		if (ret) {
 			master->domain = NULL;
 			goto out_list_del;
@@ -2455,13 +2454,15 @@
 	arm_smmu_install_ste_for_dev(master);
 
 	arm_smmu_enable_ats(master);
-	return 0;
+	goto out_unlock;
 
 out_list_del:
 	spin_lock_irqsave(&smmu_domain->devices_lock, flags);
 	list_del(&master->domain_head);
 	spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
 
+out_unlock:
+	mutex_unlock(&arm_smmu_asid_lock);
 	return ret;
 }
 
@@ -3177,7 +3178,7 @@
 	smmu->priq.q.irq = msi_get_virq(dev, PRIQ_MSI_INDEX);
 
 	/* Add callback to free MSIs on teardown */
-	devm_add_action(dev, arm_smmu_free_msis, dev);
+	devm_add_action_or_reset(dev, arm_smmu_free_msis, dev);
 }
 
 static void arm_smmu_setup_unique_irqs(struct arm_smmu_device *smmu)
@@ -3859,7 +3860,7 @@
 	/* Initialise in-memory data structures */
 	ret = arm_smmu_init_structures(smmu);
 	if (ret)
-		return ret;
+		goto err_free_iopf;
 
 	/* Record our private device structure */
 	platform_set_drvdata(pdev, smmu);
@@ -3870,22 +3871,29 @@
 	/* Reset the device */
 	ret = arm_smmu_device_reset(smmu, bypass);
 	if (ret)
-		return ret;
+		goto err_disable;
 
 	/* And we're up. Go go go! */
 	ret = iommu_device_sysfs_add(&smmu->iommu, dev, NULL,
 				     "smmu3.%pa", &ioaddr);
 	if (ret)
-		return ret;
+		goto err_disable;
 
 	ret = iommu_device_register(&smmu->iommu, &arm_smmu_ops, dev);
 	if (ret) {
 		dev_err(dev, "Failed to register iommu\n");
-		iommu_device_sysfs_remove(&smmu->iommu);
-		return ret;
+		goto err_free_sysfs;
 	}
 
 	return 0;
+
+err_free_sysfs:
+	iommu_device_sysfs_remove(&smmu->iommu);
+err_disable:
+	arm_smmu_device_disable(smmu);
+err_free_iopf:
+	iopf_queue_free(smmu->evtq.iopf);
+	return ret;
 }
 
 static void arm_smmu_device_remove(struct platform_device *pdev)
--- linux-qcom-6.8.0.orig/drivers/iommu/arm/arm-smmu/Makefile
+++ linux-qcom-6.8.0/drivers/iommu/arm/arm-smmu/Makefile
@@ -3,4 +3,5 @@
 obj-$(CONFIG_ARM_SMMU) += arm_smmu.o
 arm_smmu-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-nvidia.o
 arm_smmu-$(CONFIG_ARM_SMMU_QCOM) += arm-smmu-qcom.o
+arm_smmu-$(CONFIG_ARM_SMMU_QCOM_TBU) += arm-smmu-qcom-tbu.o
 arm_smmu-$(CONFIG_ARM_SMMU_QCOM_DEBUG) += arm-smmu-qcom-debug.o
--- linux-qcom-6.8.0.orig/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
+++ linux-qcom-6.8.0/drivers/iommu/arm/arm-smmu/arm-smmu-impl.c
@@ -130,7 +130,7 @@
 
 	/*
 	 * Disable MMU-500's not-particularly-beneficial next-page
-	 * prefetcher for the sake of errata #841119 and #826419.
+	 * prefetcher for the sake of at least 5 known errata.
 	 */
 	for (i = 0; i < smmu->num_context_banks; ++i) {
 		reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR);
@@ -138,7 +138,7 @@
 		arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_ACTLR, reg);
 		reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR);
 		if (reg & ARM_MMU500_ACTLR_CPRE)
-			dev_warn_once(smmu->dev, "Failed to disable prefetcher [errata #841119 and #826419], check ACR.CACHE_LOCK\n");
+			dev_warn_once(smmu->dev, "Failed to disable prefetcher for errata workarounds, check SACR.CACHE_LOCK\n");
 	}
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c
+++ linux-qcom-6.8.0/drivers/iommu/arm/arm-smmu/arm-smmu-nvidia.c
@@ -221,11 +221,9 @@
 	unsigned int inst;
 	irqreturn_t ret = IRQ_NONE;
 	struct arm_smmu_device *smmu;
-	struct iommu_domain *domain = dev;
-	struct arm_smmu_domain *smmu_domain;
+	struct arm_smmu_domain *smmu_domain = dev;
 	struct nvidia_smmu *nvidia;
 
-	smmu_domain = container_of(domain, struct arm_smmu_domain, domain);
 	smmu = smmu_domain->smmu;
 	nvidia = to_nvidia_smmu(smmu);
 
--- linux-qcom-6.8.0.orig/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
+++ linux-qcom-6.8.0/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-debug.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022,2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/device.h>
@@ -22,7 +22,7 @@
 	if (__ratelimit(&rs)) {
 		dev_err(smmu->dev, "TLB sync timed out -- SMMU may be deadlocked\n");
 
-		cfg = qsmmu->cfg;
+		cfg = qsmmu->data->cfg;
 		if (!cfg)
 			return;
 
--- linux-qcom-6.8.0.orig/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-tbu.c
+++ linux-qcom-6.8.0/drivers/iommu/arm/arm-smmu/arm-smmu-qcom-tbu.c
@@ -0,0 +1,499 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/interconnect.h>
+#include <linux/iopoll.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+
+#include "arm-smmu.h"
+#include "arm-smmu-qcom.h"
+
+#define TBU_DBG_TIMEOUT_US		100
+#define DEBUG_AXUSER_REG		0x30
+#define DEBUG_AXUSER_CDMID		GENMASK_ULL(43, 36)
+#define DEBUG_AXUSER_CDMID_VAL		0xff
+#define DEBUG_PAR_REG			0x28
+#define DEBUG_PAR_FAULT_VAL		BIT(0)
+#define DEBUG_PAR_PA			GENMASK_ULL(47, 12)
+#define DEBUG_SID_HALT_REG		0x0
+#define DEBUG_SID_HALT_VAL		BIT(16)
+#define DEBUG_SID_HALT_SID		GENMASK(9, 0)
+#define DEBUG_SR_HALT_ACK_REG		0x20
+#define DEBUG_SR_HALT_ACK_VAL		BIT(1)
+#define DEBUG_SR_ECATS_RUNNING_VAL	BIT(0)
+#define DEBUG_TXN_AXCACHE		GENMASK(5, 2)
+#define DEBUG_TXN_AXPROT		GENMASK(8, 6)
+#define DEBUG_TXN_AXPROT_PRIV		0x1
+#define DEBUG_TXN_AXPROT_NSEC		0x2
+#define DEBUG_TXN_TRIGG_REG		0x18
+#define DEBUG_TXN_TRIGGER		BIT(0)
+#define DEBUG_VA_ADDR_REG		0x8
+
+struct qsmmuv500_tbu {
+	struct device *dev;
+	struct arm_smmu_device *smmu;
+	u32 sid_range[2];
+	struct list_head list;
+	struct clk *clk;
+	struct icc_path	*path;
+	void __iomem *base;
+	spinlock_t halt_lock; /* multiple halt or resume can't execute concurrently */
+	int halt_count;
+};
+
+static DEFINE_SPINLOCK(atos_lock);
+
+static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
+{
+	return container_of(smmu, struct qcom_smmu, smmu);
+}
+
+static struct qsmmuv500_tbu *qsmmuv500_find_tbu(struct qcom_smmu *qsmmu, u32 sid)
+{
+	struct qsmmuv500_tbu *tbu = NULL;
+	u32 start, end;
+
+	mutex_lock(&qsmmu->tbu_list_lock);
+
+	if (!list_empty(&qsmmu->tbu_list)) {
+		list_for_each_entry(tbu, &qsmmu->tbu_list, list) {
+			start = tbu->sid_range[0];
+			end = start + tbu->sid_range[1];
+
+			if (start <= sid && sid < end)
+				break;
+		}
+	}
+
+	mutex_unlock(&qsmmu->tbu_list_lock);
+
+	return tbu;
+}
+
+static int qsmmuv500_tbu_halt(struct qsmmuv500_tbu *tbu, struct arm_smmu_domain *smmu_domain)
+{
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	int ret = 0, idx = smmu_domain->cfg.cbndx;
+	unsigned long flags;
+	u32 val, fsr, status;
+
+	spin_lock_irqsave(&tbu->halt_lock, flags);
+	if (tbu->halt_count) {
+		tbu->halt_count++;
+		goto out;
+	}
+
+	val = readl_relaxed(tbu->base + DEBUG_SID_HALT_REG);
+	val |= DEBUG_SID_HALT_VAL;
+	writel_relaxed(val, tbu->base + DEBUG_SID_HALT_REG);
+
+	fsr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSR);
+	if ((fsr & ARM_SMMU_FSR_FAULT) && (fsr & ARM_SMMU_FSR_SS)) {
+		u32 sctlr_orig, sctlr;
+
+		/*
+		 * We are in a fault. Our request to halt the bus will not
+		 * complete until transactions in front of us (such as the fault
+		 * itself) have completed. Disable iommu faults and terminate
+		 * any existing transactions.
+		 */
+		sctlr_orig = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_SCTLR);
+		sctlr = sctlr_orig & ~(ARM_SMMU_SCTLR_CFCFG | ARM_SMMU_SCTLR_CFIE);
+		arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, sctlr);
+		arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_FSR, fsr);
+		arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_RESUME, ARM_SMMU_RESUME_TERMINATE);
+		arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, sctlr_orig);
+	}
+
+	if (readl_poll_timeout_atomic(tbu->base + DEBUG_SR_HALT_ACK_REG, status,
+				      (status & DEBUG_SR_HALT_ACK_VAL),
+				      0, TBU_DBG_TIMEOUT_US)) {
+		dev_err(tbu->dev, "Timeout while trying to halt TBU!\n");
+		ret = -ETIMEDOUT;
+
+		val = readl_relaxed(tbu->base + DEBUG_SID_HALT_REG);
+		val &= ~DEBUG_SID_HALT_VAL;
+		writel_relaxed(val, tbu->base + DEBUG_SID_HALT_REG);
+
+		goto out;
+	}
+
+	tbu->halt_count = 1;
+
+out:
+	spin_unlock_irqrestore(&tbu->halt_lock, flags);
+	return ret;
+}
+
+static void qsmmuv500_tbu_resume(struct qsmmuv500_tbu *tbu)
+{
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&tbu->halt_lock, flags);
+	if (!tbu->halt_count) {
+		WARN(1, "%s: halt_count is 0", dev_name(tbu->dev));
+		goto out;
+	}
+
+	if (tbu->halt_count > 1) {
+		tbu->halt_count--;
+		goto out;
+	}
+
+	val = readl_relaxed(tbu->base + DEBUG_SID_HALT_REG);
+	val &= ~DEBUG_SID_HALT_VAL;
+	writel_relaxed(val, tbu->base + DEBUG_SID_HALT_REG);
+
+	tbu->halt_count = 0;
+out:
+	spin_unlock_irqrestore(&tbu->halt_lock, flags);
+}
+
+static phys_addr_t qsmmuv500_tbu_trigger_atos(struct arm_smmu_domain *smmu_domain,
+					      struct qsmmuv500_tbu *tbu, dma_addr_t iova, u32 sid)
+{
+	bool atos_timedout = false;
+	phys_addr_t phys = 0;
+	ktime_t timeout;
+	u64 val;
+
+	/* Set address and stream-id */
+	val = readq_relaxed(tbu->base + DEBUG_SID_HALT_REG);
+	val &= ~DEBUG_SID_HALT_SID;
+	val |= FIELD_PREP(DEBUG_SID_HALT_SID, sid);
+	writeq_relaxed(val, tbu->base + DEBUG_SID_HALT_REG);
+	writeq_relaxed(iova, tbu->base + DEBUG_VA_ADDR_REG);
+	val = FIELD_PREP(DEBUG_AXUSER_CDMID, DEBUG_AXUSER_CDMID_VAL);
+	writeq_relaxed(val, tbu->base + DEBUG_AXUSER_REG);
+
+	/* Write-back read and write-allocate */
+	val = FIELD_PREP(DEBUG_TXN_AXCACHE, 0xf);
+
+	/* Non-secure access */
+	val |= FIELD_PREP(DEBUG_TXN_AXPROT, DEBUG_TXN_AXPROT_NSEC);
+
+	/* Priviledged access */
+	val |= FIELD_PREP(DEBUG_TXN_AXPROT, DEBUG_TXN_AXPROT_PRIV);
+
+	val |= DEBUG_TXN_TRIGGER;
+	writeq_relaxed(val, tbu->base + DEBUG_TXN_TRIGG_REG);
+
+	timeout = ktime_add_us(ktime_get(), TBU_DBG_TIMEOUT_US);
+	for (;;) {
+		val = readl_relaxed(tbu->base + DEBUG_SR_HALT_ACK_REG);
+		if (!(val & DEBUG_SR_ECATS_RUNNING_VAL))
+			break;
+		val = readl_relaxed(tbu->base + DEBUG_PAR_REG);
+		if (val & DEBUG_PAR_FAULT_VAL)
+			break;
+		if (ktime_compare(ktime_get(), timeout) > 0) {
+			atos_timedout = true;
+			break;
+		}
+	}
+
+	val = readq_relaxed(tbu->base + DEBUG_PAR_REG);
+	if (val & DEBUG_PAR_FAULT_VAL)
+		dev_err(tbu->dev, "ATOS generated a fault interrupt! PAR = %llx, SID=0x%x\n",
+			val, sid);
+	else if (atos_timedout)
+		dev_err_ratelimited(tbu->dev, "ATOS translation timed out!\n");
+	else
+		phys = FIELD_GET(DEBUG_PAR_PA, val);
+
+	/* Reset hardware */
+	writeq_relaxed(0, tbu->base + DEBUG_TXN_TRIGG_REG);
+	writeq_relaxed(0, tbu->base + DEBUG_VA_ADDR_REG);
+	val = readl_relaxed(tbu->base + DEBUG_SID_HALT_REG);
+	val &= ~DEBUG_SID_HALT_SID;
+	writel_relaxed(val, tbu->base + DEBUG_SID_HALT_REG);
+
+	return phys;
+}
+
+static phys_addr_t qsmmuv500_iova_to_phys(struct arm_smmu_domain *smmu_domain,
+					  dma_addr_t iova, u32 sid)
+{
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+	int idx = smmu_domain->cfg.cbndx;
+	struct qsmmuv500_tbu *tbu;
+	u32 sctlr_orig, sctlr;
+	phys_addr_t phys = 0;
+	unsigned long flags;
+	int attempt = 0;
+	int ret;
+	u64 fsr;
+
+	tbu = qsmmuv500_find_tbu(qsmmu, sid);
+	if (!tbu)
+		return 0;
+
+	ret = icc_set_bw(tbu->path, 0, UINT_MAX);
+	if (ret)
+		return ret;
+
+	ret = clk_prepare_enable(tbu->clk);
+	if (ret)
+		goto disable_icc;
+
+	ret = qsmmuv500_tbu_halt(tbu, smmu_domain);
+	if (ret)
+		goto disable_clk;
+
+	/*
+	 * ATOS/ECATS can trigger the fault interrupt, so disable it temporarily
+	 * and check for an interrupt manually.
+	 */
+	sctlr_orig = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_SCTLR);
+	sctlr = sctlr_orig & ~(ARM_SMMU_SCTLR_CFCFG | ARM_SMMU_SCTLR_CFIE);
+	arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, sctlr);
+
+	fsr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSR);
+	if (fsr & ARM_SMMU_FSR_FAULT) {
+		/* Clear pending interrupts */
+		arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_FSR, fsr);
+
+		/*
+		 * TBU halt takes care of resuming any stalled transcation.
+		 * Kept it here for completeness sake.
+		 */
+		if (fsr & ARM_SMMU_FSR_SS)
+			arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_RESUME,
+					  ARM_SMMU_RESUME_TERMINATE);
+	}
+
+	/* Only one concurrent atos operation */
+	spin_lock_irqsave(&atos_lock, flags);
+
+	/*
+	 * If the translation fails, attempt the lookup more time."
+	 */
+	do {
+		phys = qsmmuv500_tbu_trigger_atos(smmu_domain, tbu, iova, sid);
+
+		fsr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSR);
+		if (fsr & ARM_SMMU_FSR_FAULT) {
+			/* Clear pending interrupts */
+			arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_FSR, fsr);
+
+			if (fsr & ARM_SMMU_FSR_SS)
+				arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_RESUME,
+						  ARM_SMMU_RESUME_TERMINATE);
+		}
+	} while (!phys && attempt++ < 2);
+
+	arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, sctlr_orig);
+	spin_unlock_irqrestore(&atos_lock, flags);
+	qsmmuv500_tbu_resume(tbu);
+
+	/* Read to complete prior write transcations */
+	readl_relaxed(tbu->base + DEBUG_SR_HALT_ACK_REG);
+
+disable_clk:
+	clk_disable_unprepare(tbu->clk);
+disable_icc:
+	icc_set_bw(tbu->path, 0, 0);
+
+	return phys;
+}
+
+static phys_addr_t qcom_smmu_iova_to_phys_hard(struct arm_smmu_domain *smmu_domain, dma_addr_t iova)
+{
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	int idx = smmu_domain->cfg.cbndx;
+	u32 frsynra;
+	u16 sid;
+
+	frsynra = arm_smmu_gr1_read(smmu, ARM_SMMU_GR1_CBFRSYNRA(idx));
+	sid = FIELD_GET(ARM_SMMU_CBFRSYNRA_SID, frsynra);
+
+	return qsmmuv500_iova_to_phys(smmu_domain, iova, sid);
+}
+
+static phys_addr_t qcom_smmu_verify_fault(struct arm_smmu_domain *smmu_domain, dma_addr_t iova, u32 fsr)
+{
+	struct io_pgtable *iop = io_pgtable_ops_to_pgtable(smmu_domain->pgtbl_ops);
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	phys_addr_t phys_post_tlbiall;
+	phys_addr_t phys;
+
+	phys = qcom_smmu_iova_to_phys_hard(smmu_domain, iova);
+	io_pgtable_tlb_flush_all(iop);
+	phys_post_tlbiall = qcom_smmu_iova_to_phys_hard(smmu_domain, iova);
+
+	if (phys != phys_post_tlbiall) {
+		dev_err(smmu->dev,
+			"ATOS results differed across TLBIALL... (before: %pa after: %pa)\n",
+			&phys, &phys_post_tlbiall);
+	}
+
+	return (phys == 0 ? phys_post_tlbiall : phys);
+}
+
+irqreturn_t qcom_smmu_context_fault(int irq, void *dev)
+{
+	struct arm_smmu_domain *smmu_domain = dev;
+	struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	u32 fsr, fsynr, cbfrsynra, resume = 0;
+	int idx = smmu_domain->cfg.cbndx;
+	phys_addr_t phys_soft;
+	unsigned long iova;
+	int ret, tmp;
+
+	static DEFINE_RATELIMIT_STATE(_rs,
+				      DEFAULT_RATELIMIT_INTERVAL,
+				      DEFAULT_RATELIMIT_BURST);
+
+	fsr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSR);
+	if (!(fsr & ARM_SMMU_FSR_FAULT))
+		return IRQ_NONE;
+
+	fsynr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSYNR0);
+	iova = arm_smmu_cb_readq(smmu, idx, ARM_SMMU_CB_FAR);
+	cbfrsynra = arm_smmu_gr1_read(smmu, ARM_SMMU_GR1_CBFRSYNRA(idx));
+
+	phys_soft = ops->iova_to_phys(ops, iova);
+
+	tmp = report_iommu_fault(&smmu_domain->domain, NULL, iova,
+				 fsynr & ARM_SMMU_FSYNR0_WNR ?
+				 IOMMU_FAULT_WRITE : IOMMU_FAULT_READ);
+	if (!tmp || tmp == -EBUSY) {
+		dev_dbg(smmu->dev,
+			"Context fault handled by client: iova=0x%08lx, fsr=0x%x, fsynr=0x%x, cb=%d\n",
+			iova, fsr, fsynr, idx);
+		dev_dbg(smmu->dev, "soft iova-to-phys=%pa\n", &phys_soft);
+		ret = IRQ_HANDLED;
+		resume = ARM_SMMU_RESUME_TERMINATE;
+	} else {
+		phys_addr_t phys_atos = qcom_smmu_verify_fault(smmu_domain, iova, fsr);
+
+		if (__ratelimit(&_rs)) {
+			dev_err(smmu->dev,
+				"Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, cbfrsynra=0x%x, cb=%d\n",
+				fsr, iova, fsynr, cbfrsynra, idx);
+			dev_err(smmu->dev,
+				"FSR    = %08x [%s%s%s%s%s%s%s%s%s], SID=0x%x\n",
+				fsr,
+				(fsr & 0x02) ? "TF " : "",
+				(fsr & 0x04) ? "AFF " : "",
+				(fsr & 0x08) ? "PF " : "",
+				(fsr & 0x10) ? "EF " : "",
+				(fsr & 0x20) ? "TLBMCF " : "",
+				(fsr & 0x40) ? "TLBLKF " : "",
+				(fsr & 0x80) ? "MHF " : "",
+				(fsr & 0x40000000) ? "SS " : "",
+				(fsr & 0x80000000) ? "MULTI " : "",
+				cbfrsynra);
+
+			dev_err(smmu->dev,
+				"soft iova-to-phys=%pa\n", &phys_soft);
+			if (!phys_soft)
+				dev_err(smmu->dev,
+					"SOFTWARE TABLE WALK FAILED! Looks like %s accessed an unmapped address!\n",
+					dev_name(smmu->dev));
+			if (phys_atos)
+				dev_err(smmu->dev, "hard iova-to-phys (ATOS)=%pa\n",
+					&phys_atos);
+			else
+				dev_err(smmu->dev, "hard iova-to-phys (ATOS) failed\n");
+		}
+		ret = IRQ_NONE;
+		resume = ARM_SMMU_RESUME_TERMINATE;
+	}
+
+	/*
+	 * If the client returns -EBUSY, do not clear FSR and do not RESUME
+	 * if stalled. This is required to keep the IOMMU client stalled on
+	 * the outstanding fault. This gives the client a chance to take any
+	 * debug action and then terminate the stalled transaction.
+	 * So, the sequence in case of stall on fault should be:
+	 * 1) Do not clear FSR or write to RESUME here
+	 * 2) Client takes any debug action
+	 * 3) Client terminates the stalled transaction and resumes the IOMMU
+	 * 4) Client clears FSR. The FSR should only be cleared after 3) and
+	 *    not before so that the fault remains outstanding. This ensures
+	 *    SCTLR.HUPCF has the desired effect if subsequent transactions also
+	 *    need to be terminated.
+	 */
+	if (tmp != -EBUSY) {
+		/* Clear the faulting FSR */
+		arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_FSR, fsr);
+
+		/* Retry or terminate any stalled transactions */
+		if (fsr & ARM_SMMU_FSR_SS)
+			arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_RESUME, resume);
+	}
+
+	return ret;
+}
+
+static int qsmmuv500_tbu_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct device *dev = &pdev->dev;
+	struct arm_smmu_device *smmu;
+	struct qsmmuv500_tbu *tbu;
+	struct qcom_smmu *qsmmu;
+	int ret;
+
+	smmu = dev_get_drvdata(dev->parent);
+	if (!smmu)
+		return -EPROBE_DEFER;
+
+	qsmmu = to_qcom_smmu(smmu);
+
+	tbu = devm_kzalloc(dev, sizeof(*tbu), GFP_KERNEL);
+	if (!tbu)
+		return -ENOMEM;
+
+	tbu->dev = dev;
+	INIT_LIST_HEAD(&tbu->list);
+	spin_lock_init(&tbu->halt_lock);
+
+	tbu->base = devm_of_iomap(dev, np, 0, NULL);
+	if (IS_ERR(tbu->base))
+		return PTR_ERR(tbu->base);
+
+	ret = of_property_read_u32_array(np, "qcom,stream-id-range", tbu->sid_range, 2);
+	if (ret) {
+		dev_err(dev, "The DT property 'qcom,stream-id-range' is mandatory\n");
+		return ret;
+	}
+
+	tbu->clk = devm_clk_get_optional(dev, NULL);
+	if (IS_ERR(tbu->clk))
+		return PTR_ERR(tbu->clk);
+
+	tbu->path = devm_of_icc_get(dev, NULL);
+	if (IS_ERR(tbu->path))
+		return PTR_ERR(tbu->path);
+
+	mutex_lock(&qsmmu->tbu_list_lock);
+	list_add_tail(&tbu->list, &qsmmu->tbu_list);
+	mutex_unlock(&qsmmu->tbu_list_lock);
+
+	dev_set_drvdata(dev, tbu);
+
+	return 0;
+}
+
+static const struct of_device_id qsmmuv500_tbu_of_match[] = {
+	{ .compatible = "qcom,qsmmuv500-tbu" },
+	{ }
+};
+
+static struct platform_driver qsmmuv500_tbu_driver = {
+	.driver = {
+		.name           = "qsmmuv500-tbu",
+		.of_match_table = qsmmuv500_tbu_of_match,
+	},
+	.probe = qsmmuv500_tbu_probe,
+};
+builtin_platform_driver(qsmmuv500_tbu_driver);
--- linux-qcom-6.8.0.orig/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
+++ linux-qcom-6.8.0/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c
@@ -4,9 +4,11 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/dev_printk.h>
 #include <linux/adreno-smmu-priv.h>
 #include <linux/delay.h>
 #include <linux/of_device.h>
+#include <linux/of_platform.h>
 #include <linux/firmware/qcom/qcom_scm.h>
 
 #include "arm-smmu.h"
@@ -14,11 +16,468 @@
 
 #define QCOM_DUMMY_VAL	-1
 
+struct actlr_config {
+	u16 sid;
+	u16 mask;
+	u32 actlr;
+};
+
+#define PREFETCH_DISABLE	0
+#define PREFETCH_SHALLOW	BIT(8)
+#define PREFETCH_DEEP		(BIT(9) | BIT(8))
+#define PREFETCH_DEEP_GFX	(BIT(9) | BIT(8) | BIT(5) | BIT(3))
+#define CPRE			BIT(1)		/* Enable context caching in the prefetch buffer */
+#define CMTLB			BIT(0)		/* Enable context caching in the macro TLB */
+
+static const struct actlr_config sc7280_apps_actlr_cfg[] = {
+	{ 0x0800, 0x24E1, PREFETCH_DISABLE | CMTLB },
+	{ 0x2000, 0x0163, PREFETCH_DISABLE | CMTLB },
+	{ 0x2080, 0x0461, PREFETCH_DISABLE | CMTLB },
+	{ 0x2100, 0x0161, PREFETCH_DISABLE | CMTLB },
+	{ 0x0900, 0x0407, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x2180, 0x0027, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x1000, 0x07ff, PREFETCH_DEEP | CPRE | CMTLB },
+};
+
+static const struct actlr_config sc7280_gfx_actlr_cfg[] = {
+	{ 0x0000, 0x07ff, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+};
+
+static const struct actlr_config sa7255p_apps_actlr_cfg[] = {
+	{ 0x0800, 0x0400, PREFETCH_DISABLE | CMTLB },
+	{ 0x0801, 0x0400, PREFETCH_DISABLE | CMTLB },
+	{ 0x0802, 0x0400, PREFETCH_DISABLE | CMTLB },
+	{ 0x0803, 0x0400, PREFETCH_DISABLE | CMTLB },
+	{ 0x0840, 0x0480, PREFETCH_DISABLE | CMTLB },
+	{ 0x0860, 0x0400, PREFETCH_DISABLE | CMTLB },
+	{ 0x2400, 0x0020, PREFETCH_DISABLE | CMTLB },
+	{ 0x2401, 0x0020, PREFETCH_DISABLE | CMTLB },
+	{ 0x2402, 0x0020, PREFETCH_DISABLE | CMTLB },
+	{ 0x2403, 0x0020, PREFETCH_DISABLE | CMTLB },
+	{ 0x1000, 0x0402, PREFETCH_DISABLE | CMTLB },
+	{ 0x1001, 0x0400, PREFETCH_DISABLE | CMTLB },
+	{ 0x0880, 0x0400, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0881, 0x0404, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0883, 0x0400, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0884, 0x0400, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0887, 0x0400, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x1961, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1962, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1963, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1964, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1981, 0x0440, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1982, 0x0440, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1983, 0x0440, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1984, 0x0440, PREFETCH_DEEP | CPRE | CMTLB },
+};
+
+static const struct actlr_config sa7255p_gfx_actlr_cfg[] = {
+	{ 0x0000, 0x0c00, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0001, 0x0c00, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0002, 0x0c00, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0004, 0x0c00, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0005, 0x0c00, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0007, 0x0c00, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+};
+
+static const struct actlr_config sa8775p_apps_actlr_cfg[] = {
+	{ 0x0800, 0x0400, PREFETCH_DISABLE | CMTLB },
+	{ 0x0801, 0x0400, PREFETCH_DISABLE | CMTLB },
+	{ 0x0802, 0x0400, PREFETCH_DISABLE | CMTLB },
+	{ 0x0803, 0x0400, PREFETCH_DISABLE | CMTLB },
+	{ 0x0840, 0x0480, PREFETCH_DISABLE | CMTLB },
+	{ 0x0860, 0x0400, PREFETCH_DISABLE | CMTLB },
+	{ 0x3400, 0x0020, PREFETCH_DISABLE | CMTLB },
+	{ 0x3401, 0x0020, PREFETCH_DISABLE | CMTLB },
+	{ 0x3402, 0x0020, PREFETCH_DISABLE | CMTLB },
+	{ 0x3403, 0x0020, PREFETCH_DISABLE | CMTLB },
+	{ 0x1000, 0x0402, PREFETCH_DISABLE | CMTLB },
+	{ 0x1001, 0x0400, PREFETCH_DISABLE | CMTLB },
+	{ 0x1800, 0x0402, PREFETCH_DISABLE | CMTLB },
+	{ 0x1801, 0x0400, PREFETCH_DISABLE | CMTLB },
+	{ 0x0880, 0x0400, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0881, 0x0404, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0883, 0x0400, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0884, 0x0400, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0887, 0x0400, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x2141, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2142, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2143, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2144, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2145, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2146, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2147, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2148, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2149, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x214a, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x214b, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x214c, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x214d, 0x0420, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2181, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2182, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2183, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2184, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2185, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2186, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2187, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2188, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2189, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x218a, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x218b, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x218c, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x218d, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x21ed, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x25cd, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2941, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2942, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2943, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2944, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2945, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2946, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2947, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2948, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2949, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x294a, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x294b, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x294c, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x294d, 0x04a0, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2981, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2982, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2983, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2984, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2985, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2986, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2987, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2988, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x2989, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x298a, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x298b, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x298c, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x298d, 0x0400, PREFETCH_DEEP | CPRE | CMTLB },
+};
+
+static const struct actlr_config sa8775p_gfx_actlr_cfg[] = {
+	{ 0x0000, 0x0c00, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0001, 0x0c00, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0002, 0x0c00, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0004, 0x0c00, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0005, 0x0c00, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0007, 0x0c00, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+};
+
+static const struct actlr_config sm8550_apps_actlr_cfg[] = {
+	{ 0x18a0, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x18e0, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0800, 0x0020, PREFETCH_DISABLE | CMTLB },
+	{ 0x1800, 0x00c0, PREFETCH_DISABLE | CMTLB },
+	{ 0x1820, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x1860, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0c01, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0c02, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0c03, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0c04, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0c05, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0c06, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0c07, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0c08, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0c09, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0c0c, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0c0d, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0c0e, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0c0f, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1961, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1962, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1963, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1964, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1965, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1966, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1967, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1968, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1969, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x196c, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x196d, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x196e, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x196f, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x19c1, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x19c2, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x19c3, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x19c4, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x19c5, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x19c6, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x19c7, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x19c8, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x19c9, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x19cc, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x19cd, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x19ce, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x19cf, 0x0010, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x1c00, 0x0002, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x1c01, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x1920, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x1923, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x1924, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x1940, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x1941, 0x0004, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x1943, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x1944, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x1947, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+};
+
+static const struct actlr_config sm8550_gfx_actlr_cfg[] = {
+	{ 0x0000, 0x03ff, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+};
+
+static const struct actlr_config sa8797p_apps_actlr_cfg[] = {
+	{ 0x0800, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0801, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0802, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0803, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0808, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0809, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x080a, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x080b, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0840, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0860, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x08c0, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x08c3, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0980, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0983, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x03e0, 0x0002, PREFETCH_DISABLE | CMTLB },
+	{ 0x03e1, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x03e4, 0x0002, PREFETCH_DISABLE | CMTLB },
+	{ 0x03e5, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x03e8, 0x0002, PREFETCH_DISABLE | CMTLB },
+	{ 0x03e9, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x03ec, 0x0002, PREFETCH_DISABLE | CMTLB },
+	{ 0x03ed, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0400, 0x0002, PREFETCH_DISABLE | CMTLB },
+	{ 0x0401, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0404, 0x0002, PREFETCH_DISABLE | CMTLB },
+	{ 0x0405, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0408, 0x0002, PREFETCH_DISABLE | CMTLB },
+	{ 0x0409, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x040c, 0x0002, PREFETCH_DISABLE | CMTLB },
+	{ 0x040d, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0900, 0x0020, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0904, 0x0020, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0923, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0940, 0x0020, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0941, 0x0020, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0943, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0944, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0945, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0946, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0948, 0x0020, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0949, 0x0020, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x094b, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x094c, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x094d, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x094e, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0950, 0x0020, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0951, 0x0020, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0953, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0954, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0955, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0956, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0958, 0x0020, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x0959, 0x0020, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x095b, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x095c, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x095d, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x095e, 0x0000, PREFETCH_SHALLOW | CPRE | CMTLB },
+	{ 0x1401, 0x0020, PREFETCH_DISABLE | CMTLB },
+	{ 0x1402, 0x0020, PREFETCH_DISABLE | CMTLB },
+	{ 0x1403, 0x0020, PREFETCH_DISABLE | CMTLB },
+	{ 0x1404, 0x0020, PREFETCH_DISABLE | CMTLB },
+	{ 0x1460, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x1461, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x1462, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x1463, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x1480, 0x0000, PREFETCH_DISABLE | CMTLB },
+	{ 0x0301, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0302, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0303, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0304, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0305, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0306, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0307, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0308, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0309, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x030a, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x030b, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x030c, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x030d, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0345, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x034d, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0361, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0362, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0363, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0364, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0366, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0367, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0368, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0369, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x036a, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x036b, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x036c, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0701, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0702, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0703, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0704, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0705, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0706, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0707, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0708, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0709, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x070a, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x070b, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x070c, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x070d, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0745, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x074d, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0761, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0762, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0763, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0764, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0766, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0767, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0768, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0769, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x076a, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x076b, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x076c, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b01, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b02, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b03, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b04, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b05, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b06, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b07, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b08, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b09, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b0a, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b0b, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b0c, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b0d, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b45, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b4d, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b61, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b62, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b63, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b64, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b66, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b67, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b68, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b69, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b6a, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b6b, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0b6c, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f01, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f02, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f03, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f04, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f05, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f06, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f07, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f08, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f09, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f0a, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f0b, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f0c, 0x0040, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f0d, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f45, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f4d, 0x0020, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f61, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f62, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f63, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f64, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f66, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f67, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f68, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f69, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f6a, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f6b, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+	{ 0x0f6c, 0x0000, PREFETCH_DEEP | CPRE | CMTLB },
+};
+
+static const struct actlr_config sa8797p_gfx_actlr_cfg[] = {
+	{ 0x0000, 0x0000, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0001, 0x0000, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0002, 0x0000, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0004, 0x0000, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0005, 0x0000, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0007, 0x0000, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0008, 0x0000, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x0009, 0x0000, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x000a, 0x0000, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+	{ 0x000b, 0x0000, PREFETCH_DEEP_GFX | CPRE | CMTLB },
+};
+
 static struct qcom_smmu *to_qcom_smmu(struct arm_smmu_device *smmu)
 {
 	return container_of(smmu, struct qcom_smmu, smmu);
 }
 
+static void *qcom_alloc_pages(void *cookie, size_t size, gfp_t gfp)
+{
+	struct page *p;
+	struct qcom_scm_vmperm perms[2];
+	u64 src  = BIT(QCOM_SCM_VMID_HLOS);
+	int ret;
+
+	struct arm_smmu_domain *domain = (void *)cookie;
+
+	p = alloc_page(gfp);
+	if (!p)
+		return NULL;
+
+	perms[0].vmid = QCOM_SCM_VMID_HLOS;
+	perms[0].perm = QCOM_SCM_PERM_RW;
+	perms[1].vmid = domain->secure_vmid;
+	perms[1].perm = QCOM_SCM_PERM_READ;
+	ret = qcom_scm_assign_mem(page_to_phys(p), PAGE_SIZE,
+				  &src, perms, 2);
+	if (ret < 0) {
+		dev_err(domain->smmu->dev,
+			"assign memory failed for vmid=%x ret=%d\n",
+			domain->secure_vmid, ret);
+		__free_page(p);
+		return NULL;
+	}
+
+	return page_address(p);
+}
+
+static void qcom_free_pages(void *cookie, void *pages, size_t size)
+{
+	struct qcom_scm_vmperm perms;
+	struct page *p;
+	u64 src;
+	int ret;
+
+	struct arm_smmu_domain *domain = (void *)cookie;
+
+	p = virt_to_page(pages);
+
+	perms.vmid = QCOM_SCM_VMID_HLOS;
+	perms.perm = QCOM_SCM_PERM_RWX;
+	src = BIT(domain->secure_vmid) | BIT(QCOM_SCM_VMID_HLOS);
+	ret = qcom_scm_assign_mem(page_to_phys(p), PAGE_SIZE,
+				  &src, &perms, 1);
+	/*
+	 * For assign failure scenario, it is not safe to use these pages by HLOS.
+	 * So returning from here instead of freeing the page.
+	 */
+	if (ret < 0) {
+		dev_err(domain->smmu->dev,
+			"assign memory failed to HLOS for vmid=%x ret=%d\n",
+			domain->secure_vmid, ret);
+		return;
+	}
+
+	__free_page(p);
+}
+
 static void qcom_smmu_tlb_sync(struct arm_smmu_device *smmu, int page,
 				int sync, int status)
 {
@@ -205,13 +664,60 @@
 	return true;
 }
 
+static void arm_smmu_set_actlr(struct device *dev, struct arm_smmu_device *smmu, int cbndx,
+		const struct actlr_config *actlrcfg, size_t actlrcfg_size)
+{
+	struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+	struct arm_smmu_master_cfg *cfg = dev_iommu_priv_get(dev);
+	struct arm_smmu_smr *smr;
+	int i;
+	int j;
+	u16 id;
+	u16 mask;
+	int idx;
+
+	for (i = 0; i < actlrcfg_size; ++i) {
+		id = (actlrcfg + i)->sid;
+		mask = (actlrcfg + i)->mask;
+
+		for_each_cfg_sme(cfg, fwspec, j, idx) {
+			smr = &smmu->smrs[idx];
+			if (smr_is_subset(*smr, id, mask))
+				arm_smmu_cb_write(smmu, cbndx, ARM_SMMU_CB_ACTLR,
+						(actlrcfg + i)->actlr);
+		}
+	}
+}
+
 static int qcom_adreno_smmu_init_context(struct arm_smmu_domain *smmu_domain,
 		struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
 {
 	struct adreno_smmu_priv *priv;
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+	const struct actlr_config *actlrcfg;
+	size_t actlrcfg_size;
+	int cbndx = smmu_domain->cfg.cbndx;
+	u32 val;
 
 	smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
 
+	/*
+	 * For those client where qcom,iommu-vmid is not defined, default arm-smmu pgtable
+	 * alloc/free handler will be used.
+	 */
+	if (of_property_read_u32(dev->of_node, "qcom,iommu-vmid", &val) == 0) {
+		smmu_domain->secure_vmid = val;
+		pgtbl_cfg->alloc = qcom_alloc_pages;
+		pgtbl_cfg->free = qcom_free_pages;
+	}
+
+	if (qsmmu->data->actlrcfg_gfx) {
+		actlrcfg = qsmmu->data->actlrcfg_gfx;
+		actlrcfg_size = qsmmu->data->actlrcfg_gfx_size;
+		arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
+	}
+
 	/* Only enable split pagetables for the GPU device (SID 0) */
 	if (!qcom_adreno_smmu_is_gpu_device(dev))
 		return 0;
@@ -231,6 +737,8 @@
 	 */
 
 	priv = dev_get_drvdata(dev);
+	if (!priv)
+		return -ENODATA;
 	priv->cookie = smmu_domain;
 	priv->get_ttbr1_cfg = qcom_adreno_smmu_get_ttbr1_cfg;
 	priv->set_ttbr0_cfg = qcom_adreno_smmu_set_ttbr0_cfg;
@@ -266,8 +774,31 @@
 static int qcom_smmu_init_context(struct arm_smmu_domain *smmu_domain,
 		struct io_pgtable_cfg *pgtbl_cfg, struct device *dev)
 {
+	u32 val;
+	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	struct qcom_smmu *qsmmu = to_qcom_smmu(smmu);
+	const struct actlr_config *actlrcfg;
+	size_t actlrcfg_size;
+	int cbndx = smmu_domain->cfg.cbndx;
+
+	if (qsmmu->data->actlrcfg) {
+		actlrcfg = qsmmu->data->actlrcfg;
+		actlrcfg_size = qsmmu->data->actlrcfg_size;
+		arm_smmu_set_actlr(dev, smmu, cbndx, actlrcfg, actlrcfg_size);
+	}
+
 	smmu_domain->cfg.flush_walk_prefer_tlbiasid = true;
 
+	/*
+	 * For those client where qcom,iommu-vmid is not defined, default arm-smmu pgtable
+	 * alloc/free handler will be used.
+	 */
+	if (of_property_read_u32(dev->of_node, "qcom,iommu-vmid", &val) == 0) {
+		smmu_domain->secure_vmid = val;
+		pgtbl_cfg->alloc = qcom_alloc_pages;
+		pgtbl_cfg->free = qcom_free_pages;
+	}
+
 	return 0;
 }
 
@@ -280,6 +811,20 @@
 	int i;
 
 	/*
+	 * MSM8998 LPASS SMMU reports 13 context banks, but accessing
+	 * the last context bank crashes the system.
+	 */
+	if (of_device_is_compatible(smmu->dev->of_node, "qcom,msm8998-smmu-v2") &&
+	    smmu->num_context_banks == 13) {
+		smmu->num_context_banks = 12;
+	} else if (of_device_is_compatible(smmu->dev->of_node, "qcom,sdm630-smmu-v2")) {
+		if (smmu->num_context_banks == 21) /* SDM630 / SDM660 A2NOC SMMU */
+			smmu->num_context_banks = 7;
+		else if (smmu->num_context_banks == 14) /* SDM630 / SDM660 LPASS SMMU */
+			smmu->num_context_banks = 13;
+	}
+
+	/*
 	 * Some platforms support more than the Arm SMMU architected maximum of
 	 * 128 stream matching groups. For unknown reasons, the additional
 	 * groups don't exhibit the same behavior as the architected registers,
@@ -335,6 +880,19 @@
 	return 0;
 }
 
+static int qcom_adreno_smmuv2_cfg_probe(struct arm_smmu_device *smmu)
+{
+	/* Support for 16K pages is advertised on some SoCs, but it doesn't seem to work */
+	smmu->features &= ~ARM_SMMU_FEAT_FMT_AARCH64_16K;
+
+	/* TZ protects several last context banks, hide them from Linux */
+	if (of_device_is_compatible(smmu->dev->of_node, "qcom,sdm630-smmu-v2") &&
+	    smmu->num_context_banks == 5)
+		smmu->num_context_banks = 2;
+
+	return 0;
+}
+
 static void qcom_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
 {
 	struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx;
@@ -378,11 +936,28 @@
 	return match ? IOMMU_DOMAIN_IDENTITY : 0;
 }
 
+static int qcom_smmu500_reset(struct arm_smmu_device *smmu)
+{
+	int i;
+	u32 reg;
+
+	arm_mmu500_reset(smmu);
+
+	/* Re-enable context caching after reset */
+	for (i = 0; i < smmu->num_context_banks; ++i) {
+		reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR);
+		reg |= CPRE;
+		arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_ACTLR, reg);
+	}
+
+	return 0;
+}
+
 static int qcom_sdm845_smmu500_reset(struct arm_smmu_device *smmu)
 {
 	int ret;
 
-	arm_mmu500_reset(smmu);
+	qcom_smmu500_reset(smmu);
 
 	/*
 	 * To address performance degradation in non-real time clients,
@@ -409,9 +984,13 @@
 	.init_context = qcom_smmu_init_context,
 	.cfg_probe = qcom_smmu_cfg_probe,
 	.def_domain_type = qcom_smmu_def_domain_type,
-	.reset = arm_mmu500_reset,
+	.reset = qcom_smmu500_reset,
 	.write_s2cr = qcom_smmu_write_s2cr,
 	.tlb_sync = qcom_smmu_tlb_sync,
+#ifdef CONFIG_ARM_SMMU_QCOM_TBU
+	.context_fault = qcom_smmu_context_fault,
+	.context_fault_needs_threaded_irq = true,
+#endif
 };
 
 static const struct arm_smmu_impl sdm845_smmu_500_impl = {
@@ -421,10 +1000,15 @@
 	.reset = qcom_sdm845_smmu500_reset,
 	.write_s2cr = qcom_smmu_write_s2cr,
 	.tlb_sync = qcom_smmu_tlb_sync,
+#ifdef CONFIG_ARM_SMMU_QCOM_TBU
+	.context_fault = qcom_smmu_context_fault,
+	.context_fault_needs_threaded_irq = true,
+#endif
 };
 
 static const struct arm_smmu_impl qcom_adreno_smmu_v2_impl = {
 	.init_context = qcom_adreno_smmu_init_context,
+	.cfg_probe = qcom_adreno_smmuv2_cfg_probe,
 	.def_domain_type = qcom_smmu_def_domain_type,
 	.alloc_context_bank = qcom_adreno_smmu_alloc_context_bank,
 	.write_sctlr = qcom_adreno_smmu_write_sctlr,
@@ -434,10 +1018,14 @@
 static const struct arm_smmu_impl qcom_adreno_smmu_500_impl = {
 	.init_context = qcom_adreno_smmu_init_context,
 	.def_domain_type = qcom_smmu_def_domain_type,
-	.reset = arm_mmu500_reset,
+	.reset = qcom_smmu500_reset,
 	.alloc_context_bank = qcom_adreno_smmu_alloc_context_bank,
 	.write_sctlr = qcom_adreno_smmu_write_sctlr,
 	.tlb_sync = qcom_smmu_tlb_sync,
+#ifdef CONFIG_ARM_SMMU_QCOM_TBU
+	.context_fault = qcom_smmu_context_fault,
+	.context_fault_needs_threaded_irq = true,
+#endif
 };
 
 static struct arm_smmu_device *qcom_smmu_create(struct arm_smmu_device *smmu,
@@ -446,6 +1034,7 @@
 	const struct device_node *np = smmu->dev->of_node;
 	const struct arm_smmu_impl *impl;
 	struct qcom_smmu *qsmmu;
+	int ret;
 
 	if (!data)
 		return ERR_PTR(-EINVAL);
@@ -465,11 +1054,17 @@
 	qsmmu = devm_krealloc(smmu->dev, smmu, sizeof(*qsmmu), GFP_KERNEL);
 	if (!qsmmu)
 		return ERR_PTR(-ENOMEM);
+	smmu = &qsmmu->smmu;
 
 	qsmmu->smmu.impl = impl;
-	qsmmu->cfg = data->cfg;
+	qsmmu->data = data;
+
+	INIT_LIST_HEAD(&qsmmu->tbu_list);
+	ret = devm_of_platform_populate(smmu->dev);
+	if (ret)
+		return ERR_PTR(ret);
 
-	return &qsmmu->smmu;
+	return smmu;
 }
 
 /* Implementation Defined Register Space 0 register offsets */
@@ -506,6 +1101,56 @@
 	/* Also no debug configuration. */
 };
 
+static const struct qcom_smmu_match_data sc7280_smmu_500_impl0_data = {
+	.impl = &qcom_smmu_500_impl,
+	.adreno_impl = &qcom_adreno_smmu_500_impl,
+	.cfg = &qcom_smmu_impl0_cfg,
+	.actlrcfg = sc7280_apps_actlr_cfg,
+	.actlrcfg_size = ARRAY_SIZE(sc7280_apps_actlr_cfg),
+	.actlrcfg_gfx = sc7280_gfx_actlr_cfg,
+	.actlrcfg_gfx_size = ARRAY_SIZE(sc7280_gfx_actlr_cfg),
+};
+
+static const struct qcom_smmu_match_data sa7255p_smmu_500_impl0_data = {
+	.impl = &qcom_smmu_500_impl,
+	.adreno_impl = &qcom_adreno_smmu_500_impl,
+	.cfg = &qcom_smmu_impl0_cfg,
+	.actlrcfg = sa7255p_apps_actlr_cfg,
+	.actlrcfg_size = ARRAY_SIZE(sa7255p_apps_actlr_cfg),
+	.actlrcfg_gfx = sa7255p_gfx_actlr_cfg,
+	.actlrcfg_gfx_size = ARRAY_SIZE(sa7255p_gfx_actlr_cfg),
+};
+
+static const struct qcom_smmu_match_data sa8775p_smmu_500_impl0_data = {
+	.impl = &qcom_smmu_500_impl,
+	.adreno_impl = &qcom_adreno_smmu_500_impl,
+	.cfg = &qcom_smmu_impl0_cfg,
+	.actlrcfg = sa8775p_apps_actlr_cfg,
+	.actlrcfg_size = ARRAY_SIZE(sa8775p_apps_actlr_cfg),
+	.actlrcfg_gfx = sa8775p_gfx_actlr_cfg,
+	.actlrcfg_gfx_size = ARRAY_SIZE(sa8775p_gfx_actlr_cfg),
+};
+
+static const struct qcom_smmu_match_data sa8797p_smmu_500_impl0_data = {
+	.impl = &qcom_smmu_500_impl,
+	.adreno_impl = &qcom_adreno_smmu_500_impl,
+	.cfg = &qcom_smmu_impl0_cfg,
+	.actlrcfg = sa8797p_apps_actlr_cfg,
+	.actlrcfg_size = ARRAY_SIZE(sa8797p_apps_actlr_cfg),
+	.actlrcfg_gfx = sa8797p_gfx_actlr_cfg,
+	.actlrcfg_gfx_size = ARRAY_SIZE(sa8797p_gfx_actlr_cfg),
+};
+
+static const struct qcom_smmu_match_data sm8550_smmu_500_impl0_data = {
+	.impl = &qcom_smmu_500_impl,
+	.adreno_impl = &qcom_adreno_smmu_500_impl,
+	.cfg = &qcom_smmu_impl0_cfg,
+	.actlrcfg = sm8550_apps_actlr_cfg,
+	.actlrcfg_size = ARRAY_SIZE(sm8550_apps_actlr_cfg),
+	.actlrcfg_gfx = sm8550_gfx_actlr_cfg,
+	.actlrcfg_gfx_size = ARRAY_SIZE(sm8550_gfx_actlr_cfg),
+};
+
 static const struct qcom_smmu_match_data qcom_smmu_500_impl0_data = {
 	.impl = &qcom_smmu_500_impl,
 	.adreno_impl = &qcom_adreno_smmu_500_impl,
@@ -523,10 +1168,15 @@
 	{ .compatible = "qcom,qdu1000-smmu-500", .data = &qcom_smmu_500_impl0_data  },
 	{ .compatible = "qcom,sc7180-smmu-500", .data = &qcom_smmu_500_impl0_data },
 	{ .compatible = "qcom,sc7180-smmu-v2", .data = &qcom_smmu_v2_data },
-	{ .compatible = "qcom,sc7280-smmu-500", .data = &qcom_smmu_500_impl0_data },
+	{ .compatible = "qcom,sc7280-smmu-500", .data = &sc7280_smmu_500_impl0_data },
+	{ .compatible = "qcom,sa7255p-smmu-500", .data = &sa7255p_smmu_500_impl0_data },
+	{ .compatible = "qcom,sa8255p-smmu-500", .data = &sa8775p_smmu_500_impl0_data },
+	{ .compatible = "qcom,sa8775p-smmu-500", .data = &sa8775p_smmu_500_impl0_data },
+	{ .compatible = "qcom,sa8797p-smmu-500", .data = &sa8797p_smmu_500_impl0_data },
 	{ .compatible = "qcom,sc8180x-smmu-500", .data = &qcom_smmu_500_impl0_data },
 	{ .compatible = "qcom,sc8280xp-smmu-500", .data = &qcom_smmu_500_impl0_data },
 	{ .compatible = "qcom,sdm630-smmu-v2", .data = &qcom_smmu_v2_data },
+	{ .compatible = "qcom,sdm670-smmu-v2", .data = &qcom_smmu_v2_data },
 	{ .compatible = "qcom,sdm845-smmu-v2", .data = &qcom_smmu_v2_data },
 	{ .compatible = "qcom,sdm845-smmu-500", .data = &sdm845_smmu_500_data },
 	{ .compatible = "qcom,sm6115-smmu-500", .data = &qcom_smmu_500_impl0_data},
@@ -540,6 +1190,7 @@
 	{ .compatible = "qcom,sm8250-smmu-500", .data = &qcom_smmu_500_impl0_data },
 	{ .compatible = "qcom,sm8350-smmu-500", .data = &qcom_smmu_500_impl0_data },
 	{ .compatible = "qcom,sm8450-smmu-500", .data = &qcom_smmu_500_impl0_data },
+	{ .compatible = "qcom,sm8550-smmu-500", .data = &sm8550_smmu_500_impl0_data },
 	{ .compatible = "qcom,smmu-500", .data = &qcom_smmu_500_impl0_data },
 	{ }
 };
--- linux-qcom-6.8.0.orig/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
+++ linux-qcom-6.8.0/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _ARM_SMMU_QCOM_H
@@ -8,10 +8,12 @@
 
 struct qcom_smmu {
 	struct arm_smmu_device smmu;
-	const struct qcom_smmu_config *cfg;
+	const struct qcom_smmu_match_data *data;
 	bool bypass_quirk;
 	u8 bypass_cbndx;
 	u32 stall_enabled;
+	struct mutex tbu_list_lock;  /* protects tbu_list */
+	struct list_head tbu_list;
 };
 
 enum qcom_smmu_impl_reg_offset {
@@ -25,11 +27,17 @@
 };
 
 struct qcom_smmu_match_data {
+	const struct actlr_config *actlrcfg;
+	size_t actlrcfg_size;
+	const struct actlr_config *actlrcfg_gfx;
+	size_t actlrcfg_gfx_size;
 	const struct qcom_smmu_config *cfg;
 	const struct arm_smmu_impl *impl;
 	const struct arm_smmu_impl *adreno_impl;
 };
 
+irqreturn_t qcom_smmu_context_fault(int irq, void *dev);
+
 #ifdef CONFIG_ARM_SMMU_QCOM_DEBUG
 void qcom_smmu_tlb_sync_debug(struct arm_smmu_device *smmu);
 #else
--- linux-qcom-6.8.0.orig/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ linux-qcom-6.8.0/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -414,6 +414,10 @@
 	int idx = smmu_domain->cfg.cbndx;
 	int ret;
 
+	ret = arm_smmu_rpm_get(smmu);
+	if (ret < 0)
+		return IRQ_NONE;
+
 	fsr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSR);
 	if (!(fsr & ARM_SMMU_FSR_FAULT))
 		return IRQ_NONE;
@@ -431,7 +435,11 @@
 			    fsr, iova, fsynr, cbfrsynra, idx);
 
 	arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_FSR, fsr);
-	return IRQ_HANDLED;
+
+	ret = IRQ_HANDLED;
+out_power_off:
+	arm_smmu_rpm_put(smmu);
+	return ret;
 }
 
 static irqreturn_t arm_smmu_global_fault(int irq, void *dev)
@@ -440,6 +448,11 @@
 	struct arm_smmu_device *smmu = dev;
 	static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL,
 				      DEFAULT_RATELIMIT_BURST);
+	int ret;
+
+	ret = arm_smmu_rpm_get(smmu);
+	if (ret < 0)
+		return IRQ_NONE;
 
 	gfsr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sGFSR);
 	gfsynr0 = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sGFSYNR0);
@@ -464,6 +477,7 @@
 	}
 
 	arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sGFSR, gfsr);
+	arm_smmu_rpm_put(smmu);
 	return IRQ_HANDLED;
 }
 
@@ -806,8 +820,16 @@
 	else
 		context_fault = arm_smmu_context_fault;
 
-	ret = devm_request_irq(smmu->dev, irq, context_fault, IRQF_SHARED,
-			       "arm-smmu-context-fault", smmu_domain);
+	if (smmu->impl && smmu->impl->context_fault_needs_threaded_irq)
+		ret = devm_request_threaded_irq(smmu->dev, irq, NULL,
+						context_fault,
+						IRQF_ONESHOT | IRQF_SHARED,
+						"arm-smmu-context-fault",
+						smmu_domain);
+	else
+		ret = devm_request_irq(smmu->dev, irq, context_fault,
+				       IRQF_SHARED, "arm-smmu-context-fault", smmu_domain);
+
 	if (ret < 0) {
 		dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n",
 			cfg->irptndx, irq);
@@ -999,9 +1021,10 @@
 		 * expect simply identical entries for this case, but there's
 		 * no harm in accommodating the generalisation.
 		 */
-		if ((mask & smrs[i].mask) == mask &&
-		    !((id ^ smrs[i].id) & ~smrs[i].mask))
+
+		if (smr_is_subset(smrs[i], id, mask))
 			return i;
+
 		/*
 		 * If the new entry has any other overlap with an existing one,
 		 * though, then there always exists at least one stream ID
@@ -1394,6 +1417,17 @@
 			goto out_free;
 	} else {
 		smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
+
+		/*
+		 * Defer probe if the relevant SMMU instance hasn't finished
+		 * probing yet. This is a fragile hack and we'd ideally
+		 * avoid this race in the core code. Until that's ironed
+		 * out, however, this is the most pragmatic option on the
+		 * table.
+		 */
+		if (!smmu)
+			return ERR_PTR(dev_err_probe(dev, -EPROBE_DEFER,
+						"smmu dev has not bound yet\n"));
 	}
 
 	ret = -EINVAL;
--- linux-qcom-6.8.0.orig/drivers/iommu/arm/arm-smmu/arm-smmu.h
+++ linux-qcom-6.8.0/drivers/iommu/arm/arm-smmu/arm-smmu.h
@@ -136,6 +136,7 @@
 #define ARM_SMMU_CBAR_VMID		GENMASK(7, 0)
 
 #define ARM_SMMU_GR1_CBFRSYNRA(n)	(0x400 + ((n) << 2))
+#define ARM_SMMU_CBFRSYNRA_SID		GENMASK(15, 0)
 
 #define ARM_SMMU_GR1_CBA2R(n)		(0x800 + ((n) << 2))
 #define ARM_SMMU_CBA2R_VMID16		GENMASK(31, 16)
@@ -238,6 +239,7 @@
 #define ARM_SMMU_CB_ATSR		0x8f0
 #define ARM_SMMU_ATSR_ACTIVE		BIT(0)
 
+#define ARM_SMMU_RESUME_TERMINATE	BIT(0)
 
 /* Maximum number of context banks per SMMU */
 #define ARM_SMMU_MAX_CBS		128
@@ -373,6 +375,14 @@
 	struct mutex			init_mutex; /* Protects smmu pointer */
 	spinlock_t			cb_lock; /* Serialises ATS1* ops and TLB syncs */
 	struct iommu_domain		domain;
+	/*
+	 * Use to store parse vmid value for those clients which want HLOS
+	 * to share pgtable to different entity(VMID).
+	 * Fix Me: Ideally this should be implemented on arm-smmu vendor implementation
+	 * driver, but as per current design of arm_smmu_domain_alloc there is no way
+	 * to call implementation callbacks.
+	 */
+	u32				secure_vmid;
 };
 
 struct arm_smmu_master_cfg {
@@ -436,6 +446,7 @@
 	int (*def_domain_type)(struct device *dev);
 	irqreturn_t (*global_fault)(int irq, void *dev);
 	irqreturn_t (*context_fault)(int irq, void *dev);
+	bool context_fault_needs_threaded_irq;
 	int (*alloc_context_bank)(struct arm_smmu_domain *smmu_domain,
 				  struct arm_smmu_device *smmu,
 				  struct device *dev, int start);
@@ -500,6 +511,11 @@
 		writeq_relaxed(val, arm_smmu_page(smmu, page) + offset);
 }
 
+static inline bool smr_is_subset(struct arm_smmu_smr smrs, u16 id, u16 mask)
+{
+	return (mask & smrs.mask) == mask && !((id ^ smrs.id) & ~smrs.mask);
+}
+
 #define ARM_SMMU_GR0		0
 #define ARM_SMMU_GR1		1
 #define ARM_SMMU_CB(s, n)	((s)->numpage + (n))
--- linux-qcom-6.8.0.orig/drivers/iommu/dma-iommu.c
+++ linux-qcom-6.8.0/drivers/iommu/dma-iommu.c
@@ -1706,6 +1706,14 @@
 	return iova_rcache_range();
 }
 
+static size_t iommu_dma_max_mapping_size(struct device *dev)
+{
+	if (dev_is_untrusted(dev))
+		return swiotlb_max_mapping_size(dev);
+
+	return SIZE_MAX;
+}
+
 static const struct dma_map_ops iommu_dma_ops = {
 	.flags			= DMA_F_PCI_P2PDMA_SUPPORTED,
 	.alloc			= iommu_dma_alloc,
@@ -1728,6 +1736,7 @@
 	.unmap_resource		= iommu_dma_unmap_resource,
 	.get_merge_boundary	= iommu_dma_get_merge_boundary,
 	.opt_mapping_size	= iommu_dma_opt_mapping_size,
+	.max_mapping_size       = iommu_dma_max_mapping_size,
 };
 
 /*
--- linux-qcom-6.8.0.orig/drivers/iommu/intel/Makefile
+++ linux-qcom-6.8.0/drivers/iommu/intel/Makefile
@@ -5,5 +5,7 @@
 obj-$(CONFIG_DMAR_PERF) += perf.o
 obj-$(CONFIG_INTEL_IOMMU_DEBUGFS) += debugfs.o
 obj-$(CONFIG_INTEL_IOMMU_SVM) += svm.o
+ifdef CONFIG_INTEL_IOMMU
 obj-$(CONFIG_IRQ_REMAP) += irq_remapping.o
+endif
 obj-$(CONFIG_INTEL_IOMMU_PERF_EVENTS) += perfmon.o
--- linux-qcom-6.8.0.orig/drivers/iommu/intel/dmar.c
+++ linux-qcom-6.8.0/drivers/iommu/intel/dmar.c
@@ -1095,7 +1095,9 @@
 	iommu->agaw = agaw;
 	iommu->msagaw = msagaw;
 	iommu->segment = drhd->segment;
-
+	iommu->device_rbtree = RB_ROOT;
+	spin_lock_init(&iommu->device_rbtree_lock);
+	mutex_init(&iommu->iopf_lock);
 	iommu->node = NUMA_NO_NODE;
 
 	ver = readl(iommu->reg + DMAR_VER_REG);
@@ -1202,9 +1204,7 @@
  */
 static inline void reclaim_free_desc(struct q_inval *qi)
 {
-	while (qi->desc_status[qi->free_tail] == QI_DONE ||
-	       qi->desc_status[qi->free_tail] == QI_ABORT) {
-		qi->desc_status[qi->free_tail] = QI_FREE;
+	while (qi->desc_status[qi->free_tail] == QI_FREE && qi->free_tail != qi->free_head) {
 		qi->free_tail = (qi->free_tail + 1) % QI_LENGTH;
 		qi->free_cnt++;
 	}
@@ -1271,6 +1271,8 @@
 {
 	u32 fault;
 	int head, tail;
+	struct device *dev;
+	u64 iqe_err, ite_sid;
 	struct q_inval *qi = iommu->qi;
 	int shift = qi_shift(iommu);
 
@@ -1315,6 +1317,13 @@
 		tail = readl(iommu->reg + DMAR_IQT_REG);
 		tail = ((tail >> shift) - 1 + QI_LENGTH) % QI_LENGTH;
 
+		/*
+		 * SID field is valid only when the ITE field is Set in FSTS_REG
+		 * see Intel VT-d spec r4.1, section 11.4.9.9
+		 */
+		iqe_err = dmar_readq(iommu->reg + DMAR_IQER_REG);
+		ite_sid = DMAR_IQER_REG_ITESID(iqe_err);
+
 		writel(DMA_FSTS_ITE, iommu->reg + DMAR_FSTS_REG);
 		pr_info("Invalidation Time-out Error (ITE) cleared\n");
 
@@ -1324,6 +1333,19 @@
 			head = (head - 2 + QI_LENGTH) % QI_LENGTH;
 		} while (head != tail);
 
+		/*
+		 * If device was released or isn't present, no need to retry
+		 * the ATS invalidate request anymore.
+		 *
+		 * 0 value of ite_sid means old VT-d device, no ite_sid value.
+		 * see Intel VT-d spec r4.1, section 11.4.9.9
+		 */
+		if (ite_sid) {
+			dev = device_rbtree_find(iommu, ite_sid);
+			if (!dev || !dev_is_pci(dev) ||
+			    !pci_device_is_present(to_pci_dev(dev)))
+				return -ETIMEDOUT;
+		}
 		if (qi->desc_status[wait_index] == QI_ABORT)
 			return -EAGAIN;
 	}
@@ -1422,7 +1444,7 @@
 	 */
 	writel(qi->free_head << shift, iommu->reg + DMAR_IQT_REG);
 
-	while (qi->desc_status[wait_index] != QI_DONE) {
+	while (READ_ONCE(qi->desc_status[wait_index]) != QI_DONE) {
 		/*
 		 * We will leave the interrupts disabled, to prevent interrupt
 		 * context to queue another cmd while a cmd is already submitted
@@ -1439,8 +1461,16 @@
 		raw_spin_lock(&qi->q_lock);
 	}
 
-	for (i = 0; i < count; i++)
-		qi->desc_status[(index + i) % QI_LENGTH] = QI_DONE;
+	/*
+	 * The reclaim code can free descriptors from multiple submissions
+	 * starting from the tail of the queue. When count == 0, the
+	 * status of the standalone wait descriptor at the tail of the queue
+	 * must be set to QI_FREE to allow the reclaim code to proceed.
+	 * It is also possible that descriptors from one of the previous
+	 * submissions has to be reclaimed by a subsequent submission.
+	 */
+	for (i = 0; i <= count; i++)
+		qi->desc_status[(index + i) % QI_LENGTH] = QI_FREE;
 
 	reclaim_free_desc(qi);
 	raw_spin_unlock_irqrestore(&qi->q_lock, flags);
--- linux-qcom-6.8.0.orig/drivers/iommu/intel/iommu.c
+++ linux-qcom-6.8.0/drivers/iommu/intel/iommu.c
@@ -38,6 +38,14 @@
 #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
 #define IS_USB_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_SERIAL_USB)
 #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
+#define IS_INTEL_IPU(pdev) ((pdev)->vendor == PCI_VENDOR_ID_INTEL &&	\
+			   ((pdev)->device == 0xa75d ||		\
+			    (pdev)->device == 0x9a19 ||		\
+			    (pdev)->device == 0x9a39 ||		\
+			    (pdev)->device == 0x7d19 ||		\
+			    (pdev)->device == 0x4e19 ||		\
+			    (pdev)->device == 0x465d ||		\
+			    (pdev)->device == 0x1919))
 #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
 
 #define IOAPIC_RANGE_START	(0xfee00000)
@@ -97,6 +105,81 @@
 	return re->hi & VTD_PAGE_MASK;
 }
 
+static int device_rid_cmp_key(const void *key, const struct rb_node *node)
+{
+	struct device_domain_info *info =
+		rb_entry(node, struct device_domain_info, node);
+	const u16 *rid_lhs = key;
+
+	if (*rid_lhs < PCI_DEVID(info->bus, info->devfn))
+		return -1;
+
+	if (*rid_lhs > PCI_DEVID(info->bus, info->devfn))
+		return 1;
+
+	return 0;
+}
+
+static int device_rid_cmp(struct rb_node *lhs, const struct rb_node *rhs)
+{
+	struct device_domain_info *info =
+		rb_entry(lhs, struct device_domain_info, node);
+	u16 key = PCI_DEVID(info->bus, info->devfn);
+
+	return device_rid_cmp_key(&key, rhs);
+}
+
+/*
+ * Looks up an IOMMU-probed device using its source ID.
+ *
+ * Returns the pointer to the device if there is a match. Otherwise,
+ * returns NULL.
+ *
+ * Note that this helper doesn't guarantee that the device won't be
+ * released by the iommu subsystem after being returned. The caller
+ * should use its own synchronization mechanism to avoid the device
+ * being released during its use if its possibly the case.
+ */
+struct device *device_rbtree_find(struct intel_iommu *iommu, u16 rid)
+{
+	struct device_domain_info *info = NULL;
+	struct rb_node *node;
+	unsigned long flags;
+
+	spin_lock_irqsave(&iommu->device_rbtree_lock, flags);
+	node = rb_find(&rid, &iommu->device_rbtree, device_rid_cmp_key);
+	if (node)
+		info = rb_entry(node, struct device_domain_info, node);
+	spin_unlock_irqrestore(&iommu->device_rbtree_lock, flags);
+
+	return info ? info->dev : NULL;
+}
+
+static int device_rbtree_insert(struct intel_iommu *iommu,
+				struct device_domain_info *info)
+{
+	struct rb_node *curr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&iommu->device_rbtree_lock, flags);
+	curr = rb_find_add(&info->node, &iommu->device_rbtree, device_rid_cmp);
+	spin_unlock_irqrestore(&iommu->device_rbtree_lock, flags);
+	if (WARN_ON(curr))
+		return -EEXIST;
+
+	return 0;
+}
+
+static void device_rbtree_remove(struct device_domain_info *info)
+{
+	struct intel_iommu *iommu = info->iommu;
+	unsigned long flags;
+
+	spin_lock_irqsave(&iommu->device_rbtree_lock, flags);
+	rb_erase(&info->node, &iommu->device_rbtree);
+	spin_unlock_irqrestore(&iommu->device_rbtree_lock, flags);
+}
+
 /*
  * This domain is a statically identity mapping domain.
  *	1. This domain creats a static 1:1 mapping to all usable memory.
@@ -148,12 +231,14 @@
 EXPORT_SYMBOL_GPL(intel_iommu_enabled);
 
 static int dmar_map_gfx = 1;
+static int dmar_map_ipu = 1;
 static int intel_iommu_superpage = 1;
 static int iommu_identity_mapping;
 static int iommu_skip_te_disable;
 
 #define IDENTMAP_GFX		2
 #define IDENTMAP_AZALIA		4
+#define IDENTMAP_IPU		8
 
 const struct iommu_ops intel_iommu_ops;
 static const struct iommu_dirty_ops intel_dirty_ops;
@@ -669,14 +754,15 @@
 	while (1) {
 		offset = pfn_level_offset(pfn, level);
 		pte = &parent[offset];
-		if (!pte || (dma_pte_superpage(pte) || !dma_pte_present(pte))) {
-			pr_info("PTE not present at level %d\n", level);
-			break;
-		}
 
 		pr_info("pte level: %d, pte value: 0x%016llx\n", level, pte->val);
 
-		if (level == 1)
+		if (!dma_pte_present(pte)) {
+			pr_info("page table not present at level %d\n", level - 1);
+			break;
+		}
+
+		if (level == 1 || dma_pte_superpage(pte))
 			break;
 
 		parent = phys_to_virt(dma_pte_addr(pte));
@@ -699,11 +785,11 @@
 	pr_info("Dump %s table entries for IOVA 0x%llx\n", iommu->name, addr);
 
 	/* root entry dump */
-	rt_entry = &iommu->root_entry[bus];
-	if (!rt_entry) {
-		pr_info("root table entry is not present\n");
+	if (!iommu->root_entry) {
+		pr_info("root table is not present\n");
 		return;
 	}
+	rt_entry = &iommu->root_entry[bus];
 
 	if (sm_supported(iommu))
 		pr_info("scalable mode root entry: hi 0x%016llx, low 0x%016llx\n",
@@ -714,7 +800,7 @@
 	/* context entry dump */
 	ctx_entry = iommu_context_addr(iommu, bus, devfn, 0);
 	if (!ctx_entry) {
-		pr_info("context table entry is not present\n");
+		pr_info("context table is not present\n");
 		return;
 	}
 
@@ -723,17 +809,23 @@
 
 	/* legacy mode does not require PASID entries */
 	if (!sm_supported(iommu)) {
+		if (!context_present(ctx_entry)) {
+			pr_info("legacy mode page table is not present\n");
+			return;
+		}
 		level = agaw_to_level(ctx_entry->hi & 7);
 		pgtable = phys_to_virt(ctx_entry->lo & VTD_PAGE_MASK);
 		goto pgtable_walk;
 	}
 
-	/* get the pointer to pasid directory entry */
-	dir = phys_to_virt(ctx_entry->lo & VTD_PAGE_MASK);
-	if (!dir) {
-		pr_info("pasid directory entry is not present\n");
+	if (!context_present(ctx_entry)) {
+		pr_info("pasid directory table is not present\n");
 		return;
 	}
+
+	/* get the pointer to pasid directory entry */
+	dir = phys_to_virt(ctx_entry->lo & VTD_PAGE_MASK);
+
 	/* For request-without-pasid, get the pasid from context entry */
 	if (intel_iommu_sm && pasid == IOMMU_PASID_INVALID)
 		pasid = IOMMU_NO_PASID;
@@ -745,7 +837,7 @@
 	/* get the pointer to the pasid table entry */
 	entries = get_pasid_table_from_pde(pde);
 	if (!entries) {
-		pr_info("pasid table entry is not present\n");
+		pr_info("pasid table is not present\n");
 		return;
 	}
 	index = pasid & PASID_PTE_MASK;
@@ -753,6 +845,11 @@
 	for (i = 0; i < ARRAY_SIZE(pte->val); i++)
 		pr_info("pasid table entry[%d]: 0x%016llx\n", i, pte->val[i]);
 
+	if (!pasid_pte_is_present(pte)) {
+		pr_info("scalable mode page table is not present\n");
+		return;
+	}
+
 	if (pasid_pte_get_pgtt(pte) == PASID_ENTRY_PGTT_FL_ONLY) {
 		level = pte->val[2] & BIT_ULL(2) ? 5 : 4;
 		pgtable = phys_to_virt(pte->val[2] & VTD_PAGE_MASK);
@@ -801,7 +898,7 @@
 			domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
 			pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
 			if (domain->use_first_level)
-				pteval |= DMA_FL_PTE_XD | DMA_FL_PTE_US | DMA_FL_PTE_ACCESS;
+				pteval |= DMA_FL_PTE_US | DMA_FL_PTE_ACCESS;
 
 			if (cmpxchg64(&pte->val, 0ULL, pteval))
 				/* Someone else set it while we were thinking; use theirs. */
@@ -1596,10 +1693,10 @@
 	 * entry for first-level or pass-through translation modes should
 	 * be programmed with a domain id different from those used for
 	 * second-level or nested translation. We reserve a domain id for
-	 * this purpose.
+	 * this purpose. This domain id is also used for identity domain
+	 * in legacy mode.
 	 */
-	if (sm_supported(iommu))
-		set_bit(FLPT_DEFAULT_DID, iommu->domain_ids);
+	set_bit(FLPT_DEFAULT_DID, iommu->domain_ids);
 
 	return 0;
 }
@@ -2071,7 +2168,7 @@
 	attr = prot & (DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP);
 	attr |= DMA_FL_PTE_PRESENT;
 	if (domain->use_first_level) {
-		attr |= DMA_FL_PTE_XD | DMA_FL_PTE_US | DMA_FL_PTE_ACCESS;
+		attr |= DMA_FL_PTE_US | DMA_FL_PTE_ACCESS;
 		if (prot & DMA_PTE_WRITE)
 			attr |= DMA_FL_PTE_DIRTY;
 	}
@@ -2283,7 +2380,7 @@
 		for_each_mem_pfn_range(i, nid, &start_pfn, &end_pfn, NULL) {
 			ret = iommu_domain_identity_map(si_domain,
 					mm_to_dma_pfn_start(start_pfn),
-					mm_to_dma_pfn_end(end_pfn));
+					mm_to_dma_pfn_end(end_pfn-1));
 			if (ret)
 				return ret;
 		}
@@ -2412,6 +2509,9 @@
 
 		if ((iommu_identity_mapping & IDENTMAP_GFX) && IS_GFX_DEVICE(pdev))
 			return IOMMU_DOMAIN_IDENTITY;
+
+		if ((iommu_identity_mapping & IDENTMAP_IPU) && IS_INTEL_IPU(pdev))
+			return IOMMU_DOMAIN_IDENTITY;
 	}
 
 	return 0;
@@ -2719,6 +2819,9 @@
 	if (!dmar_map_gfx)
 		iommu_identity_mapping |= IDENTMAP_GFX;
 
+	if (!dmar_map_ipu)
+		iommu_identity_mapping |= IDENTMAP_IPU;
+
 	check_tylersburg_isoch();
 
 	ret = si_domain_init(hw_pass_through);
@@ -3792,37 +3895,15 @@
  */
 static void domain_context_clear(struct device_domain_info *info)
 {
-	if (!dev_is_pci(info->dev))
+	if (!dev_is_pci(info->dev)) {
 		domain_context_clear_one(info, info->bus, info->devfn);
+		return;
+	}
 
 	pci_for_each_dma_alias(to_pci_dev(info->dev),
 			       &domain_context_clear_one_cb, info);
 }
 
-static void dmar_remove_one_dev_info(struct device *dev)
-{
-	struct device_domain_info *info = dev_iommu_priv_get(dev);
-	struct dmar_domain *domain = info->domain;
-	struct intel_iommu *iommu = info->iommu;
-	unsigned long flags;
-
-	if (!dev_is_real_dma_subdevice(info->dev)) {
-		if (dev_is_pci(info->dev) && sm_supported(iommu))
-			intel_pasid_tear_down_entry(iommu, info->dev,
-					IOMMU_NO_PASID, false);
-
-		iommu_disable_pci_caps(info);
-		domain_context_clear(info);
-	}
-
-	spin_lock_irqsave(&domain->lock, flags);
-	list_del(&info->link);
-	spin_unlock_irqrestore(&domain->lock, flags);
-
-	domain_detach_iommu(domain, iommu);
-	info->domain = NULL;
-}
-
 /*
  * Clear the page table pointer in context or pasid table entries so that
  * all DMA requests without PASID from the device are blocked. If the page
@@ -4330,26 +4411,45 @@
 	}
 
 	dev_iommu_priv_set(dev, info);
+	if (pdev && pci_ats_supported(pdev)) {
+		ret = device_rbtree_insert(iommu, info);
+		if (ret)
+			goto free;
+	}
 
 	if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) {
 		ret = intel_pasid_alloc_table(dev);
 		if (ret) {
 			dev_err(dev, "PASID table allocation failed\n");
-			kfree(info);
-			return ERR_PTR(ret);
+			goto clear_rbtree;
 		}
 	}
 
 	intel_iommu_debugfs_create_dev(info);
 
 	return &iommu->iommu;
+clear_rbtree:
+	device_rbtree_remove(info);
+free:
+	kfree(info);
+
+	return ERR_PTR(ret);
 }
 
 static void intel_iommu_release_device(struct device *dev)
 {
 	struct device_domain_info *info = dev_iommu_priv_get(dev);
+	struct intel_iommu *iommu = info->iommu;
+
+	mutex_lock(&iommu->iopf_lock);
+	if (dev_is_pci(dev) && pci_ats_supported(to_pci_dev(dev)))
+		device_rbtree_remove(info);
+	mutex_unlock(&iommu->iopf_lock);
+
+	if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev) &&
+	    !context_copied(iommu, info->bus, info->devfn))
+		intel_pasid_teardown_sm_context(dev);
 
-	dmar_remove_one_dev_info(dev);
 	intel_pasid_free_table(dev);
 	intel_iommu_debugfs_remove_dev(info);
 	kfree(info);
@@ -4855,6 +4955,7 @@
 
 const struct iommu_ops intel_iommu_ops = {
 	.blocked_domain		= &blocking_domain,
+	.release_domain		= &blocking_domain,
 	.capable		= intel_iommu_capable,
 	.hw_info		= intel_iommu_hw_info,
 	.domain_alloc		= intel_iommu_domain_alloc,
@@ -4896,6 +4997,18 @@
 	dmar_map_gfx = 0;
 }
 
+static void quirk_iommu_ipu(struct pci_dev *dev)
+{
+	if (!IS_INTEL_IPU(dev))
+		return;
+
+	if (risky_device(dev))
+		return;
+
+	pci_info(dev, "Passthrough IOMMU for integrated Intel IPU\n");
+	dmar_map_ipu = 0;
+}
+
 /* G4x/GM45 integrated gfx dmar support is totally busted. */
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx);
@@ -4931,6 +5044,77 @@
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx);
 
+/* SKL */
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1906, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1913, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x190E, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1915, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1902, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x190A, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x190B, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1917, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1916, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1921, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x191E, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1912, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x191A, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x191B, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x191D, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1923, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1926, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1927, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x192A, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x192B, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x192D, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1932, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x193A, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x193B, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x193D, quirk_iommu_igfx);
+
+/* KBL */
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5902, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5906, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5908, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x590A, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x590B, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x590E, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5912, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5913, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5915, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5916, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5917, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x591A, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x591B, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x591D, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x591E, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5921, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5923, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5926, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x5927, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x593B, quirk_iommu_igfx);
+
+/* CML */
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9B21, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BA2, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BA4, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BA5, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BA8, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BAA, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BAC, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BC2, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BC4, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BC5, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BC6, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BC8, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BE6, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BF6, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9B41, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BCA, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9BCC, quirk_iommu_igfx);
+
+/* disable IPU dmar support */
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_iommu_ipu);
+
 static void quirk_iommu_rwbf(struct pci_dev *dev)
 {
 	if (risky_device(dev))
--- linux-qcom-6.8.0.orig/drivers/iommu/intel/iommu.h
+++ linux-qcom-6.8.0/drivers/iommu/intel/iommu.h
@@ -47,7 +47,6 @@
 #define DMA_FL_PTE_US		BIT_ULL(2)
 #define DMA_FL_PTE_ACCESS	BIT_ULL(5)
 #define DMA_FL_PTE_DIRTY	BIT_ULL(6)
-#define DMA_FL_PTE_XD		BIT_ULL(63)
 
 #define DMA_SL_PTE_DIRTY_BIT	9
 #define DMA_SL_PTE_DIRTY	BIT_ULL(DMA_SL_PTE_DIRTY_BIT)
@@ -719,9 +718,16 @@
 #endif
 	struct iopf_queue *iopf_queue;
 	unsigned char iopfq_name[16];
+	/* Synchronization between fault report and iommu device release. */
+	struct mutex iopf_lock;
 	struct q_inval  *qi;            /* Queued invalidation info */
 	u32 iommu_state[MAX_SR_DMAR_REGS]; /* Store iommu states between suspend and resume.*/
 
+	/* rb tree for all probed devices */
+	struct rb_root device_rbtree;
+	/* protect the device_rbtree */
+	spinlock_t device_rbtree_lock;
+
 #ifdef CONFIG_IRQ_REMAP
 	struct ir_table *ir_table;	/* Interrupt remapping info */
 	struct irq_domain *ir_domain;
@@ -755,6 +761,8 @@
 	struct intel_iommu *iommu; /* IOMMU used by this device */
 	struct dmar_domain *domain; /* pointer to domain */
 	struct pasid_table *pasid_table; /* pasid table */
+	/* device tracking node(lookup by PCI RID) */
+	struct rb_node node;
 #ifdef CONFIG_INTEL_IOMMU_DEBUGFS
 	struct dentry *debugfs_dentry; /* pointer to device directory dentry */
 #endif
@@ -813,11 +821,10 @@
 static inline u64 dma_pte_addr(struct dma_pte *pte)
 {
 #ifdef CONFIG_64BIT
-	return pte->val & VTD_PAGE_MASK & (~DMA_FL_PTE_XD);
+	return pte->val & VTD_PAGE_MASK;
 #else
 	/* Must have a full atomic 64-bit read */
-	return  __cmpxchg64(&pte->val, 0ULL, 0ULL) &
-			VTD_PAGE_MASK & (~DMA_FL_PTE_XD);
+	return  __cmpxchg64(&pte->val, 0ULL, 0ULL) & VTD_PAGE_MASK;
 #endif
 }
 
@@ -1081,6 +1088,7 @@
 void iommu_flush_write_buffer(struct intel_iommu *iommu);
 struct iommu_domain *intel_nested_domain_alloc(struct iommu_domain *parent,
 					       const struct iommu_user_data *user_data);
+struct device *device_rbtree_find(struct intel_iommu *iommu, u16 rid);
 
 #ifdef CONFIG_INTEL_IOMMU_SVM
 void intel_svm_check(struct intel_iommu *iommu);
--- linux-qcom-6.8.0.orig/drivers/iommu/intel/pasid.c
+++ linux-qcom-6.8.0/drivers/iommu/intel/pasid.c
@@ -214,6 +214,9 @@
 	if (!info || !info->ats_enabled)
 		return;
 
+	if (pci_dev_is_disconnected(to_pci_dev(dev)))
+		return;
+
 	sid = info->bus << 8 | info->devfn;
 	qdep = info->ats_qdep;
 	pfsid = info->pfsid;
@@ -258,9 +261,7 @@
 	else
 		iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
 
-	/* Device IOTLB doesn't need to be flushed in caching mode. */
-	if (!cap_caching_mode(iommu->cap))
-		devtlb_invalidation_with_pasid(iommu, dev, pasid);
+	devtlb_invalidation_with_pasid(iommu, dev, pasid);
 }
 
 /*
@@ -330,7 +331,6 @@
 	pasid_set_domain_id(pte, did);
 	pasid_set_address_width(pte, iommu->agaw);
 	pasid_set_page_snoop(pte, !!ecap_smpwc(iommu->ecap));
-	pasid_set_nxe(pte);
 
 	/* Setup Present and PASID Granular Transfer Type: */
 	pasid_set_translation_type(pte, PASID_ENTRY_PGTT_FL_ONLY);
@@ -488,9 +488,7 @@
 
 	iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
 
-	/* Device IOTLB doesn't need to be flushed in caching mode. */
-	if (!cap_caching_mode(iommu->cap))
-		devtlb_invalidation_with_pasid(iommu, dev, pasid);
+	devtlb_invalidation_with_pasid(iommu, dev, pasid);
 
 	return 0;
 }
@@ -567,9 +565,7 @@
 	pasid_cache_invalidation_with_pasid(iommu, did, pasid);
 	qi_flush_piotlb(iommu, did, pasid, 0, -1, 0);
 
-	/* Device IOTLB doesn't need to be flushed in caching mode. */
-	if (!cap_caching_mode(iommu->cap))
-		devtlb_invalidation_with_pasid(iommu, dev, pasid);
+	devtlb_invalidation_with_pasid(iommu, dev, pasid);
 }
 
 /**
@@ -667,3 +663,67 @@
 
 	return 0;
 }
+
+/*
+ * Interfaces to setup or teardown a pasid table to the scalable-mode
+ * context table entry:
+ */
+
+static void device_pasid_table_teardown(struct device *dev, u8 bus, u8 devfn)
+{
+	struct device_domain_info *info = dev_iommu_priv_get(dev);
+	struct intel_iommu *iommu = info->iommu;
+	struct context_entry *context;
+
+	spin_lock(&iommu->lock);
+	context = iommu_context_addr(iommu, bus, devfn, false);
+	if (!context) {
+		spin_unlock(&iommu->lock);
+		return;
+	}
+
+	context_clear_entry(context);
+	__iommu_flush_cache(iommu, context, sizeof(*context));
+	spin_unlock(&iommu->lock);
+
+	/*
+	 * Cache invalidation for changes to a scalable-mode context table
+	 * entry.
+	 *
+	 * Section 6.5.3.3 of the VT-d spec:
+	 * - Device-selective context-cache invalidation;
+	 * - Domain-selective PASID-cache invalidation to affected domains
+	 *   (can be skipped if all PASID entries were not-present);
+	 * - Domain-selective IOTLB invalidation to affected domains;
+	 * - Global Device-TLB invalidation to affected functions.
+	 *
+	 * The iommu has been parked in the blocking state. All domains have
+	 * been detached from the device or PASID. The PASID and IOTLB caches
+	 * have been invalidated during the domain detach path.
+	 */
+	iommu->flush.flush_context(iommu, 0, PCI_DEVID(bus, devfn),
+				   DMA_CCMD_MASK_NOBIT, DMA_CCMD_DEVICE_INVL);
+	devtlb_invalidation_with_pasid(iommu, dev, IOMMU_NO_PASID);
+}
+
+static int pci_pasid_table_teardown(struct pci_dev *pdev, u16 alias, void *data)
+{
+	struct device *dev = data;
+
+	if (dev == &pdev->dev)
+		device_pasid_table_teardown(dev, PCI_BUS_NUM(alias), alias & 0xff);
+
+	return 0;
+}
+
+void intel_pasid_teardown_sm_context(struct device *dev)
+{
+	struct device_domain_info *info = dev_iommu_priv_get(dev);
+
+	if (!dev_is_pci(dev)) {
+		device_pasid_table_teardown(dev, info->bus, info->devfn);
+		return;
+	}
+
+	pci_for_each_dma_alias(to_pci_dev(dev), pci_pasid_table_teardown, dev);
+}
--- linux-qcom-6.8.0.orig/drivers/iommu/intel/pasid.h
+++ linux-qcom-6.8.0/drivers/iommu/intel/pasid.h
@@ -248,16 +248,6 @@
 }
 
 /*
- * Setup No Execute Enable bit (Bit 133) of a scalable mode PASID
- * entry. It is required when XD bit of the first level page table
- * entry is about to be set.
- */
-static inline void pasid_set_nxe(struct pasid_entry *pe)
-{
-	pasid_set_bits(&pe->val[2], 1 << 5, 1 << 5);
-}
-
-/*
  * Setup the Page Snoop (PGSNP) field (Bit 88) of a scalable mode
  * PASID entry.
  */
@@ -318,4 +308,5 @@
 				 bool fault_ignore);
 void intel_pasid_setup_page_snoop_control(struct intel_iommu *iommu,
 					  struct device *dev, u32 pasid);
+void intel_pasid_teardown_sm_context(struct device *dev);
 #endif /* __INTEL_PASID_H */
--- linux-qcom-6.8.0.orig/drivers/iommu/intel/perfmon.c
+++ linux-qcom-6.8.0/drivers/iommu/intel/perfmon.c
@@ -438,7 +438,7 @@
 	iommu_pmu_set_filter(domain, event->attr.config1,
 			     IOMMU_PMU_FILTER_DOMAIN, idx,
 			     event->attr.config1);
-	iommu_pmu_set_filter(pasid, event->attr.config1,
+	iommu_pmu_set_filter(pasid, event->attr.config2,
 			     IOMMU_PMU_FILTER_PASID, idx,
 			     event->attr.config1);
 	iommu_pmu_set_filter(ats, event->attr.config2,
--- linux-qcom-6.8.0.orig/drivers/iommu/intel/svm.c
+++ linux-qcom-6.8.0/drivers/iommu/intel/svm.c
@@ -67,7 +67,7 @@
 	struct page *pages;
 	int irq, ret;
 
-	pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, PRQ_ORDER);
+	pages = alloc_pages_node(iommu->node, GFP_KERNEL | __GFP_ZERO, PRQ_ORDER);
 	if (!pages) {
 		pr_warn("IOMMU: %s: Failed to allocate page request queue\n",
 			iommu->name);
@@ -650,7 +650,7 @@
 	struct intel_iommu *iommu = d;
 	struct page_req_dsc *req;
 	int head, tail, handled;
-	struct pci_dev *pdev;
+	struct device *dev;
 	u64 address;
 
 	/*
@@ -696,23 +696,24 @@
 		if (unlikely(req->lpig && !req->rd_req && !req->wr_req))
 			goto prq_advance;
 
-		pdev = pci_get_domain_bus_and_slot(iommu->segment,
-						   PCI_BUS_NUM(req->rid),
-						   req->rid & 0xff);
 		/*
 		 * If prq is to be handled outside iommu driver via receiver of
 		 * the fault notifiers, we skip the page response here.
 		 */
-		if (!pdev)
+		mutex_lock(&iommu->iopf_lock);
+		dev = device_rbtree_find(iommu, req->rid);
+		if (!dev) {
+			mutex_unlock(&iommu->iopf_lock);
 			goto bad_req;
+		}
 
-		if (intel_svm_prq_report(iommu, &pdev->dev, req))
+		if (intel_svm_prq_report(iommu, dev, req))
 			handle_bad_prq_event(iommu, req, QI_RESP_INVALID);
 		else
-			trace_prq_report(iommu, &pdev->dev, req->qw_0, req->qw_1,
+			trace_prq_report(iommu, dev, req->qw_0, req->qw_1,
 					 req->priv_data[0], req->priv_data[1],
 					 iommu->prq_seq_number++);
-		pci_dev_put(pdev);
+		mutex_unlock(&iommu->iopf_lock);
 prq_advance:
 		head = (head + sizeof(*req)) & PRQ_RING_MASK;
 	}
--- linux-qcom-6.8.0.orig/drivers/iommu/io-pgtable-arm-v7s.c
+++ linux-qcom-6.8.0/drivers/iommu/io-pgtable-arm-v7s.c
@@ -552,9 +552,8 @@
 		    paddr >= (1ULL << data->iop.cfg.oas)))
 		return -ERANGE;
 
-	/* If no access, then nothing to do */
 	if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
-		return 0;
+		return -EINVAL;
 
 	while (pgcount--) {
 		ret = __arm_v7s_map(data, iova, paddr, pgsize, prot, 1, data->pgd,
--- linux-qcom-6.8.0.orig/drivers/iommu/io-pgtable-arm.c
+++ linux-qcom-6.8.0/drivers/iommu/io-pgtable-arm.c
@@ -180,6 +180,18 @@
 	return (paddr | (paddr << (48 - 12))) & (ARM_LPAE_PTE_ADDR_MASK << 4);
 }
 
+/*
+ * Convert an index returned by ARM_LPAE_PGD_IDX(), which can point into
+ * a concatenated PGD, into the maximum number of entries that can be
+ * mapped in the same table page.
+ */
+static inline int arm_lpae_max_entries(int i, struct arm_lpae_io_pgtable *data)
+{
+	int ptes_per_table = ARM_LPAE_PTES_PER_TABLE(data);
+
+	return ptes_per_table - (i & (ptes_per_table - 1));
+}
+
 static bool selftest_running = false;
 
 static dma_addr_t __arm_lpae_dma_addr(void *pages)
@@ -375,7 +387,7 @@
 
 	/* If we can install a leaf entry at this level, then do so */
 	if (size == block_size) {
-		max_entries = ARM_LPAE_PTES_PER_TABLE(data) - map_idx_start;
+		max_entries = arm_lpae_max_entries(map_idx_start, data);
 		num_entries = min_t(int, pgcount, max_entries);
 		ret = arm_lpae_init_pte(data, iova, paddr, prot, lvl, num_entries, ptep);
 		if (!ret)
@@ -498,9 +510,8 @@
 	if (WARN_ON(iaext || paddr >> cfg->oas))
 		return -ERANGE;
 
-	/* If no access, then nothing to do */
 	if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
-		return 0;
+		return -EINVAL;
 
 	prot = arm_lpae_prot_to_pte(data, iommu_prot);
 	ret = __arm_lpae_map(data, iova, paddr, pgsize, pgcount, prot, lvl,
@@ -576,7 +587,7 @@
 
 	if (size == split_sz) {
 		unmap_idx_start = ARM_LPAE_LVL_IDX(iova, lvl, data);
-		max_entries = ptes_per_table - unmap_idx_start;
+		max_entries = arm_lpae_max_entries(unmap_idx_start, data);
 		num_entries = min_t(int, pgcount, max_entries);
 	}
 
@@ -634,7 +645,7 @@
 
 	/* If the size matches this level, we're in the right place */
 	if (size == ARM_LPAE_BLOCK_SIZE(lvl, data)) {
-		max_entries = ARM_LPAE_PTES_PER_TABLE(data) - unmap_idx_start;
+		max_entries = arm_lpae_max_entries(unmap_idx_start, data);
 		num_entries = min_t(int, pgcount, max_entries);
 
 		while (i < num_entries) {
--- linux-qcom-6.8.0.orig/drivers/iommu/io-pgtable-dart.c
+++ linux-qcom-6.8.0/drivers/iommu/io-pgtable-dart.c
@@ -250,9 +250,8 @@
 	if (WARN_ON(paddr >> cfg->oas))
 		return -ERANGE;
 
-	/* If no access, then nothing to do */
 	if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
-		return 0;
+		return -EINVAL;
 
 	tbl = dart_get_table(data, iova);
 
--- linux-qcom-6.8.0.orig/drivers/iommu/iommu.c
+++ linux-qcom-6.8.0/drivers/iommu/iommu.c
@@ -463,13 +463,24 @@
 
 	/*
 	 * release_device() must stop using any attached domain on the device.
-	 * If there are still other devices in the group they are not effected
+	 * If there are still other devices in the group, they are not affected
 	 * by this callback.
 	 *
-	 * The IOMMU driver must set the device to either an identity or
-	 * blocking translation and stop using any domain pointer, as it is
-	 * going to be freed.
+	 * If the iommu driver provides release_domain, the core code ensures
+	 * that domain is attached prior to calling release_device. Drivers can
+	 * use this to enforce a translation on the idle iommu. Typically, the
+	 * global static blocked_domain is a good choice.
+	 *
+	 * Otherwise, the iommu driver must set the device to either an identity
+	 * or a blocking translation in release_device() and stop using any
+	 * domain pointer, as it is going to be freed.
+	 *
+	 * Regardless, if a delayed attach never occurred, then the release
+	 * should still avoid touching any hardware configuration either.
 	 */
+	if (!dev->iommu->attach_deferred && ops->release_domain)
+		ops->release_domain->ops->attach_dev(ops->release_domain, dev);
+
 	if (ops->release_device)
 		ops->release_device(dev);
 
@@ -3499,15 +3510,26 @@
 static int __iommu_set_group_pasid(struct iommu_domain *domain,
 				   struct iommu_group *group, ioasid_t pasid)
 {
-	struct group_device *device;
-	int ret = 0;
+	struct group_device *device, *last_gdev;
+	int ret;
 
 	for_each_group_device(group, device) {
 		ret = domain->ops->set_dev_pasid(domain, device->dev, pasid);
 		if (ret)
-			break;
+			goto err_revert;
 	}
 
+	return 0;
+
+err_revert:
+	last_gdev = device;
+	for_each_group_device(group, device) {
+		const struct iommu_ops *ops = dev_iommu_ops(device->dev);
+
+		if (device == last_gdev)
+			break;
+		ops->remove_dev_pasid(device->dev, pasid);
+	}
 	return ret;
 }
 
@@ -3536,6 +3558,7 @@
 {
 	/* Caller must be a probed driver on dev */
 	struct iommu_group *group = dev->iommu_group;
+	struct group_device *device;
 	void *curr;
 	int ret;
 
@@ -3545,10 +3568,18 @@
 	if (!group)
 		return -ENODEV;
 
-	if (!dev_has_iommu(dev) || dev_iommu_ops(dev) != domain->owner)
+	if (!dev_has_iommu(dev) || dev_iommu_ops(dev) != domain->owner ||
+	    pasid == IOMMU_NO_PASID)
 		return -EINVAL;
 
 	mutex_lock(&group->mutex);
+	for_each_group_device(group, device) {
+		if (pasid >= device->dev->iommu->max_pasids) {
+			ret = -EINVAL;
+			goto out_unlock;
+		}
+	}
+
 	curr = xa_cmpxchg(&group->pasid_array, pasid, NULL, domain, GFP_KERNEL);
 	if (curr) {
 		ret = xa_err(curr) ? : -EBUSY;
@@ -3556,10 +3587,8 @@
 	}
 
 	ret = __iommu_set_group_pasid(domain, group, pasid);
-	if (ret) {
-		__iommu_remove_group_pasid(group, pasid);
+	if (ret)
 		xa_erase(&group->pasid_array, pasid);
-	}
 out_unlock:
 	mutex_unlock(&group->mutex);
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/iommu/iommufd/Kconfig
+++ linux-qcom-6.8.0/drivers/iommu/iommufd/Kconfig
@@ -37,6 +37,7 @@
 	depends on DEBUG_KERNEL
 	depends on FAULT_INJECTION
 	depends on RUNTIME_TESTING_MENU
+	select IOMMUFD_DRIVER
 	default n
 	help
 	  This is dangerous, do not enable unless running
--- linux-qcom-6.8.0.orig/drivers/iommu/iommufd/device.c
+++ linux-qcom-6.8.0/drivers/iommu/iommufd/device.c
@@ -525,7 +525,7 @@
 err_unresv:
 	if (hwpt_is_paging(hwpt))
 		iommufd_group_remove_reserved_iova(igroup,
-						   to_hwpt_paging(old_hwpt));
+						   to_hwpt_paging(hwpt));
 err_unlock:
 	mutex_unlock(&idev->igroup->lock);
 	return ERR_PTR(rc);
--- linux-qcom-6.8.0.orig/drivers/iommu/iommufd/hw_pagetable.c
+++ linux-qcom-6.8.0/drivers/iommu/iommufd/hw_pagetable.c
@@ -215,7 +215,8 @@
 
 	if (flags || !user_data->len || !ops->domain_alloc_user)
 		return ERR_PTR(-EOPNOTSUPP);
-	if (parent->auto_domain || !parent->nest_parent)
+	if (parent->auto_domain || !parent->nest_parent ||
+	    parent->common.domain->owner != ops)
 		return ERR_PTR(-EINVAL);
 
 	hwpt_nested = __iommufd_object_alloc(
@@ -236,7 +237,8 @@
 	}
 	hwpt->domain->owner = ops;
 
-	if (WARN_ON_ONCE(hwpt->domain->type != IOMMU_DOMAIN_NESTED)) {
+	if (WARN_ON_ONCE(hwpt->domain->type != IOMMU_DOMAIN_NESTED ||
+			 !hwpt->domain->ops->cache_invalidate_user)) {
 		rc = -EINVAL;
 		goto out_abort;
 	}
--- linux-qcom-6.8.0.orig/drivers/iommu/iommufd/io_pagetable.c
+++ linux-qcom-6.8.0/drivers/iommu/iommufd/io_pagetable.c
@@ -112,6 +112,7 @@
 	unsigned long page_offset = uptr % PAGE_SIZE;
 	struct interval_tree_double_span_iter used_span;
 	struct interval_tree_span_iter allowed_span;
+	unsigned long max_alignment = PAGE_SIZE;
 	unsigned long iova_alignment;
 
 	lockdep_assert_held(&iopt->iova_rwsem);
@@ -131,6 +132,13 @@
 				       roundup_pow_of_two(length),
 				       1UL << __ffs64(uptr));
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+	max_alignment = HPAGE_SIZE;
+#endif
+	/* Protect against ALIGN() overflow */
+	if (iova_alignment >= max_alignment)
+		iova_alignment = max_alignment;
+
 	if (iova_alignment < iopt->iova_alignment)
 		return -EINVAL;
 
--- linux-qcom-6.8.0.orig/drivers/iommu/iommufd/ioas.c
+++ linux-qcom-6.8.0/drivers/iommu/iommufd/ioas.c
@@ -213,6 +213,10 @@
 	if (cmd->iova >= ULONG_MAX || cmd->length >= ULONG_MAX)
 		return -EOVERFLOW;
 
+	if (!(cmd->flags &
+	      (IOMMU_IOAS_MAP_WRITEABLE | IOMMU_IOAS_MAP_READABLE)))
+		return -EINVAL;
+
 	ioas = iommufd_get_ioas(ucmd->ictx, cmd->ioas_id);
 	if (IS_ERR(ioas))
 		return PTR_ERR(ioas);
@@ -253,6 +257,10 @@
 	    cmd->dst_iova >= ULONG_MAX)
 		return -EOVERFLOW;
 
+	if (!(cmd->flags &
+	      (IOMMU_IOAS_MAP_WRITEABLE | IOMMU_IOAS_MAP_READABLE)))
+		return -EINVAL;
+
 	src_ioas = iommufd_get_ioas(ucmd->ictx, cmd->src_ioas_id);
 	if (IS_ERR(src_ioas))
 		return PTR_ERR(src_ioas);
--- linux-qcom-6.8.0.orig/drivers/iommu/iommufd/iova_bitmap.c
+++ linux-qcom-6.8.0/drivers/iommu/iommufd/iova_bitmap.c
@@ -130,7 +130,7 @@
 static unsigned long iova_bitmap_offset_to_index(struct iova_bitmap *bitmap,
 						 unsigned long iova)
 {
-	unsigned long pgsize = 1 << bitmap->mapped.pgshift;
+	unsigned long pgsize = 1UL << bitmap->mapped.pgshift;
 
 	return iova / (BITS_PER_TYPE(*bitmap->bitmap) * pgsize);
 }
@@ -384,8 +384,6 @@
 	bitmap->mapped_base_index += count;
 
 	iova_bitmap_put(bitmap);
-	if (iova_bitmap_done(bitmap))
-		return 0;
 
 	/* Iterate, set and skip any bits requested for next iteration */
 	if (bitmap->set_ahead_length) {
@@ -396,6 +394,9 @@
 			return ret;
 	}
 
+	if (iova_bitmap_done(bitmap))
+		return 0;
+
 	/* When advancing the index we pin the next set of bitmap pages */
 	return iova_bitmap_get(bitmap);
 }
--- linux-qcom-6.8.0.orig/drivers/iommu/iommufd/main.c
+++ linux-qcom-6.8.0/drivers/iommu/iommufd/main.c
@@ -130,7 +130,7 @@
 	if (wait_event_timeout(ictx->destroy_wait,
 				refcount_read(&to_destroy->shortterm_users) ==
 					0,
-				msecs_to_jiffies(10000)))
+				msecs_to_jiffies(60000)))
 		return 0;
 
 	pr_crit("Time out waiting for iommufd object to become free\n");
--- linux-qcom-6.8.0.orig/drivers/iommu/iommufd/selftest.c
+++ linux-qcom-6.8.0/drivers/iommu/iommufd/selftest.c
@@ -1313,7 +1313,7 @@
 			      unsigned long page_size, void __user *uptr,
 			      u32 flags)
 {
-	unsigned long bitmap_size, i, max;
+	unsigned long i, max;
 	struct iommu_test_cmd *cmd = ucmd->cmd;
 	struct iommufd_hw_pagetable *hwpt;
 	struct mock_iommu_domain *mock;
@@ -1334,15 +1334,14 @@
 	}
 
 	max = length / page_size;
-	bitmap_size = max / BITS_PER_BYTE;
-
-	tmp = kvzalloc(bitmap_size, GFP_KERNEL_ACCOUNT);
+	tmp = kvzalloc(DIV_ROUND_UP(max, BITS_PER_LONG) * sizeof(unsigned long),
+		       GFP_KERNEL_ACCOUNT);
 	if (!tmp) {
 		rc = -ENOMEM;
 		goto out_put;
 	}
 
-	if (copy_from_user(tmp, uptr, bitmap_size)) {
+	if (copy_from_user(tmp, uptr,DIV_ROUND_UP(max, BITS_PER_BYTE))) {
 		rc = -EFAULT;
 		goto out_free;
 	}
--- linux-qcom-6.8.0.orig/drivers/iommu/irq_remapping.c
+++ linux-qcom-6.8.0/drivers/iommu/irq_remapping.c
@@ -99,7 +99,8 @@
 	if (disable_irq_remap)
 		return -ENOSYS;
 
-	if (intel_irq_remap_ops.prepare() == 0)
+	if (IS_ENABLED(CONFIG_INTEL_IOMMU) &&
+	    intel_irq_remap_ops.prepare() == 0)
 		remap_ops = &intel_irq_remap_ops;
 	else if (IS_ENABLED(CONFIG_AMD_IOMMU) &&
 		 amd_iommu_irq_ops.prepare() == 0)
--- linux-qcom-6.8.0.orig/drivers/iommu/mtk_iommu.c
+++ linux-qcom-6.8.0/drivers/iommu/mtk_iommu.c
@@ -1789,6 +1789,7 @@
 	{ .compatible = "mediatek,mt8365-m4u", .data = &mt8365_data},
 	{}
 };
+MODULE_DEVICE_TABLE(of, mtk_iommu_of_ids);
 
 static struct platform_driver mtk_iommu_driver = {
 	.probe	= mtk_iommu_probe,
--- linux-qcom-6.8.0.orig/drivers/iommu/mtk_iommu_v1.c
+++ linux-qcom-6.8.0/drivers/iommu/mtk_iommu_v1.c
@@ -599,6 +599,7 @@
 	{ .compatible = "mediatek,mt2701-m4u", },
 	{}
 };
+MODULE_DEVICE_TABLE(of, mtk_iommu_v1_of_ids);
 
 static const struct component_master_ops mtk_iommu_v1_com_ops = {
 	.bind		= mtk_iommu_v1_bind,
--- linux-qcom-6.8.0.orig/drivers/iommu/s390-iommu.c
+++ linux-qcom-6.8.0/drivers/iommu/s390-iommu.c
@@ -33,6 +33,8 @@
 	struct rcu_head		rcu;
 };
 
+static struct iommu_domain blocking_domain;
+
 static inline unsigned int calc_rtx(dma_addr_t ptr)
 {
 	return ((unsigned long)ptr >> ZPCI_RT_SHIFT) & ZPCI_INDEX_MASK;
@@ -369,20 +371,36 @@
 	call_rcu(&s390_domain->rcu, s390_iommu_rcu_free_domain);
 }
 
-static void s390_iommu_detach_device(struct iommu_domain *domain,
-				     struct device *dev)
+static void zdev_s390_domain_update(struct zpci_dev *zdev,
+				    struct iommu_domain *domain)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&zdev->dom_lock, flags);
+	zdev->s390_domain = domain;
+	spin_unlock_irqrestore(&zdev->dom_lock, flags);
+}
+
+static int blocking_domain_attach_device(struct iommu_domain *domain,
+					 struct device *dev)
 {
-	struct s390_domain *s390_domain = to_s390_domain(domain);
 	struct zpci_dev *zdev = to_zpci_dev(dev);
+	struct s390_domain *s390_domain;
 	unsigned long flags;
 
+	if (zdev->s390_domain->type == IOMMU_DOMAIN_BLOCKED)
+		return 0;
+
+	s390_domain = to_s390_domain(zdev->s390_domain);
 	spin_lock_irqsave(&s390_domain->list_lock, flags);
 	list_del_rcu(&zdev->iommu_list);
 	spin_unlock_irqrestore(&s390_domain->list_lock, flags);
 
 	zpci_unregister_ioat(zdev, 0);
-	zdev->s390_domain = NULL;
 	zdev->dma_table = NULL;
+	zdev_s390_domain_update(zdev, domain);
+
+	return 0;
 }
 
 static int s390_iommu_attach_device(struct iommu_domain *domain,
@@ -401,20 +419,15 @@
 		domain->geometry.aperture_end < zdev->start_dma))
 		return -EINVAL;
 
-	if (zdev->s390_domain)
-		s390_iommu_detach_device(&zdev->s390_domain->domain, dev);
+	blocking_domain_attach_device(&blocking_domain, dev);
 
+	/* If we fail now DMA remains blocked via blocking domain */
 	cc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
 				virt_to_phys(s390_domain->dma_table), &status);
-	/*
-	 * If the device is undergoing error recovery the reset code
-	 * will re-establish the new domain.
-	 */
 	if (cc && status != ZPCI_PCI_ST_FUNC_NOT_AVAIL)
 		return -EIO;
-
 	zdev->dma_table = s390_domain->dma_table;
-	zdev->s390_domain = s390_domain;
+	zdev_s390_domain_update(zdev, domain);
 
 	spin_lock_irqsave(&s390_domain->list_lock, flags);
 	list_add_rcu(&zdev->iommu_list, &s390_domain->devices);
@@ -466,19 +479,11 @@
 	if (zdev->tlb_refresh)
 		dev->iommu->shadow_on_flush = 1;
 
-	return &zdev->iommu_dev;
-}
+	/* Start with DMA blocked */
+	spin_lock_init(&zdev->dom_lock);
+	zdev_s390_domain_update(zdev, &blocking_domain);
 
-static void s390_iommu_release_device(struct device *dev)
-{
-	struct zpci_dev *zdev = to_zpci_dev(dev);
-
-	/*
-	 * release_device is expected to detach any domain currently attached
-	 * to the device, but keep it attached to other devices in the group.
-	 */
-	if (zdev)
-		s390_iommu_detach_device(&zdev->s390_domain->domain, dev);
+	return &zdev->iommu_dev;
 }
 
 static int zpci_refresh_all(struct zpci_dev *zdev)
@@ -702,9 +707,15 @@
 
 struct zpci_iommu_ctrs *zpci_get_iommu_ctrs(struct zpci_dev *zdev)
 {
-	if (!zdev || !zdev->s390_domain)
+	struct s390_domain *s390_domain;
+
+	lockdep_assert_held(&zdev->dom_lock);
+
+	if (zdev->s390_domain->type == IOMMU_DOMAIN_BLOCKED)
 		return NULL;
-	return &zdev->s390_domain->ctrs;
+
+	s390_domain = to_s390_domain(zdev->s390_domain);
+	return &s390_domain->ctrs;
 }
 
 int zpci_init_iommu(struct zpci_dev *zdev)
@@ -781,12 +792,20 @@
 }
 subsys_initcall(s390_iommu_init);
 
+static struct iommu_domain blocking_domain = {
+	.type = IOMMU_DOMAIN_BLOCKED,
+	.ops = &(const struct iommu_domain_ops) {
+		.attach_dev	= blocking_domain_attach_device,
+	}
+};
+
 static const struct iommu_ops s390_iommu_ops = {
+	.blocked_domain		= &blocking_domain,
+	.release_domain		= &blocking_domain,
 	.capable = s390_iommu_capable,
 	.domain_alloc_paging = s390_domain_alloc_paging,
 	.probe_device = s390_iommu_probe_device,
 	.probe_finalize = s390_iommu_probe_finalize,
-	.release_device = s390_iommu_release_device,
 	.device_group = generic_device_group,
 	.pgsize_bitmap = SZ_4K,
 	.get_resv_regions = s390_iommu_get_resv_regions,
--- linux-qcom-6.8.0.orig/drivers/iommu/sprd-iommu.c
+++ linux-qcom-6.8.0/drivers/iommu/sprd-iommu.c
@@ -232,8 +232,8 @@
 
 	pgt_size = sprd_iommu_pgt_size(&dom->domain);
 	dma_free_coherent(dom->sdev->dev, pgt_size, dom->pgt_va, dom->pgt_pa);
-	dom->sdev = NULL;
 	sprd_iommu_hw_en(dom->sdev, false);
+	dom->sdev = NULL;
 }
 
 static void sprd_iommu_domain_free(struct iommu_domain *domain)
--- linux-qcom-6.8.0.orig/drivers/iommu/sun50i-iommu.c
+++ linux-qcom-6.8.0/drivers/iommu/sun50i-iommu.c
@@ -450,6 +450,7 @@
 		    IOMMU_TLB_PREFETCH_MASTER_ENABLE(3) |
 		    IOMMU_TLB_PREFETCH_MASTER_ENABLE(4) |
 		    IOMMU_TLB_PREFETCH_MASTER_ENABLE(5));
+	iommu_write(iommu, IOMMU_BYPASS_REG, 0);
 	iommu_write(iommu, IOMMU_INT_ENABLE_REG, IOMMU_INT_MASK);
 	iommu_write(iommu, IOMMU_DM_AUT_CTRL_REG(SUN50I_IOMMU_ACI_NONE),
 		    IOMMU_DM_AUT_CTRL_RD_UNAVAIL(SUN50I_IOMMU_ACI_NONE, 0) |
--- linux-qcom-6.8.0.orig/drivers/irqchip/Kconfig
+++ linux-qcom-6.8.0/drivers/irqchip/Kconfig
@@ -557,7 +557,7 @@
 	bool
 	select GENERIC_IRQ_CHIP
 	select IRQ_DOMAIN
-	select GENERIC_IRQ_EFFECTIVE_AFF_MASK
+	select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
 	select LOONGSON_HTVEC
 	select LOONGSON_LIOINTC
 	select LOONGSON_EIOINTC
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-alpine-msi.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-alpine-msi.c
@@ -165,7 +165,7 @@
 	return 0;
 
 err_sgi:
-	irq_domain_free_irqs_parent(domain, virq, i - 1);
+	irq_domain_free_irqs_parent(domain, virq, i);
 	alpine_msix_free_sgi(priv, sgi, nr_irqs);
 	return err;
 }
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-apple-aic.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-apple-aic.c
@@ -563,7 +563,8 @@
 						  AIC_FIQ_HWIRQ(AIC_TMR_EL02_VIRT));
 	}
 
-	if (read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & PMCR0_IACT) {
+	if ((read_sysreg_s(SYS_IMP_APL_PMCR0_EL1) & (PMCR0_IMODE | PMCR0_IACT)) ==
+			(FIELD_PREP(PMCR0_IMODE, PMCR0_IMODE_FIQ) | PMCR0_IACT)) {
 		int irq;
 		if (cpumask_test_cpu(smp_processor_id(),
 				     &aic_irqc->fiq_aff[AIC_CPU_PMU_P]->aff))
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-armada-370-xp.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-armada-370-xp.c
@@ -566,6 +566,10 @@
 static int armada_370_xp_mpic_irq_map(struct irq_domain *h,
 				      unsigned int virq, irq_hw_number_t hw)
 {
+	/* IRQs 0 and 1 cannot be mapped, they are handled internally */
+	if (hw <= 1)
+		return -EINVAL;
+
 	armada_370_xp_irq_mask(irq_get_irq_data(virq));
 	if (!is_percpu_irq(hw))
 		writel(hw, per_cpu_int_base +
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-atmel-aic-common.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-atmel-aic-common.c
@@ -111,8 +111,6 @@
 	struct device_node *node = irq_domain_get_of_node(domain);
 	struct irq_chip_generic *gc;
 	struct aic_chip_data *aic;
-	struct property *prop;
-	const __be32 *p;
 	u32 hwirq;
 
 	gc = irq_get_domain_generic_chip(domain, 0);
@@ -120,7 +118,7 @@
 	aic = gc->private;
 	aic->ext_irqs |= 1;
 
-	of_property_for_each_u32(node, "atmel,external-irqs", prop, p, hwirq) {
+	of_property_for_each_u32(node, "atmel,external-irqs", hwirq) {
 		gc = irq_get_domain_generic_chip(domain, hwirq);
 		if (!gc) {
 			pr_warn("AIC: external irq %d >= %d skip it\n",
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-gic-v2m.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-gic-v2m.c
@@ -438,12 +438,12 @@
 
 		ret = gicv2m_init_one(&child->fwnode, spi_start, nr_spis,
 				      &res, 0);
-		if (ret) {
-			of_node_put(child);
+		if (ret)
 			break;
-		}
 	}
 
+	if (ret && child)
+		of_node_put(child);
 	if (!ret)
 		ret = gicv2m_allocate_domains(parent);
 	if (ret)
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-gic-v3-its.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-gic-v3-its.c
@@ -43,6 +43,7 @@
 #define ITS_FLAGS_WORKAROUND_CAVIUM_22375	(1ULL << 1)
 #define ITS_FLAGS_WORKAROUND_CAVIUM_23144	(1ULL << 2)
 #define ITS_FLAGS_FORCE_NON_SHAREABLE		(1ULL << 3)
+#define ITS_FLAGS_WORKAROUND_HISILICON_162100801	(1ULL << 4)
 
 #define RD_LOCAL_LPI_ENABLED                    BIT(0)
 #define RD_LOCAL_PENDTABLE_PREALLOCATED         BIT(1)
@@ -61,6 +62,8 @@
 
 #define LPI_PROP_DEFAULT_PRIO	GICD_INT_DEF_PRI
 
+static struct its_node *find_4_1_its(void);
+
 /*
  * Collection structure - just an ID, and a redistributor address to
  * ping. We use one per CPU as a bag of interrupts assigned to this
@@ -786,6 +789,7 @@
 					   struct its_cmd_block *cmd,
 					   struct its_cmd_desc *desc)
 {
+	struct its_vpe *vpe = valid_vpe(its, desc->its_vmapp_cmd.vpe);
 	unsigned long vpt_addr, vconf_addr;
 	u64 target;
 	bool alloc;
@@ -795,9 +799,14 @@
 	its_encode_valid(cmd, desc->its_vmapp_cmd.valid);
 
 	if (!desc->its_vmapp_cmd.valid) {
+		alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count);
 		if (is_v4_1(its)) {
-			alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count);
 			its_encode_alloc(cmd, alloc);
+			/*
+			 * Unmapping a VPE is self-synchronizing on GICv4.1,
+			 * no need to issue a VSYNC.
+			 */
+			vpe = NULL;
 		}
 
 		goto out;
@@ -810,13 +819,13 @@
 	its_encode_vpt_addr(cmd, vpt_addr);
 	its_encode_vpt_size(cmd, LPI_NRBITS - 1);
 
+	alloc = !atomic_fetch_inc(&desc->its_vmapp_cmd.vpe->vmapp_count);
+
 	if (!is_v4_1(its))
 		goto out;
 
 	vconf_addr = virt_to_phys(page_address(desc->its_vmapp_cmd.vpe->its_vm->vprop_page));
 
-	alloc = !atomic_fetch_inc(&desc->its_vmapp_cmd.vpe->vmapp_count);
-
 	its_encode_alloc(cmd, alloc);
 
 	/*
@@ -832,7 +841,7 @@
 out:
 	its_fixup_cmd(cmd);
 
-	return valid_vpe(its, desc->its_vmapp_cmd.vpe);
+	return vpe;
 }
 
 static struct its_vpe *its_build_vmapti_cmd(struct its_node *its,
@@ -1840,28 +1849,22 @@
 {
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	u32 event = its_get_event_id(d);
-	int ret = 0;
 
 	if (!info->map)
 		return -EINVAL;
 
-	raw_spin_lock(&its_dev->event_map.vlpi_lock);
-
 	if (!its_dev->event_map.vm) {
 		struct its_vlpi_map *maps;
 
 		maps = kcalloc(its_dev->event_map.nr_lpis, sizeof(*maps),
 			       GFP_ATOMIC);
-		if (!maps) {
-			ret = -ENOMEM;
-			goto out;
-		}
+		if (!maps)
+			return -ENOMEM;
 
 		its_dev->event_map.vm = info->map->vm;
 		its_dev->event_map.vlpi_maps = maps;
 	} else if (its_dev->event_map.vm != info->map->vm) {
-		ret = -EINVAL;
-		goto out;
+		return -EINVAL;
 	}
 
 	/* Get our private copy of the mapping information */
@@ -1893,46 +1896,32 @@
 		its_dev->event_map.nr_vlpis++;
 	}
 
-out:
-	raw_spin_unlock(&its_dev->event_map.vlpi_lock);
-	return ret;
+	return 0;
 }
 
 static int its_vlpi_get(struct irq_data *d, struct its_cmd_info *info)
 {
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	struct its_vlpi_map *map;
-	int ret = 0;
-
-	raw_spin_lock(&its_dev->event_map.vlpi_lock);
 
 	map = get_vlpi_map(d);
 
-	if (!its_dev->event_map.vm || !map) {
-		ret = -EINVAL;
-		goto out;
-	}
+	if (!its_dev->event_map.vm || !map)
+		return -EINVAL;
 
 	/* Copy our mapping information to the incoming request */
 	*info->map = *map;
 
-out:
-	raw_spin_unlock(&its_dev->event_map.vlpi_lock);
-	return ret;
+	return 0;
 }
 
 static int its_vlpi_unmap(struct irq_data *d)
 {
 	struct its_device *its_dev = irq_data_get_irq_chip_data(d);
 	u32 event = its_get_event_id(d);
-	int ret = 0;
 
-	raw_spin_lock(&its_dev->event_map.vlpi_lock);
-
-	if (!its_dev->event_map.vm || !irqd_is_forwarded_to_vcpu(d)) {
-		ret = -EINVAL;
-		goto out;
-	}
+	if (!its_dev->event_map.vm || !irqd_is_forwarded_to_vcpu(d))
+		return -EINVAL;
 
 	/* Drop the virtual mapping */
 	its_send_discard(its_dev, event);
@@ -1956,9 +1945,7 @@
 		kfree(its_dev->event_map.vlpi_maps);
 	}
 
-out:
-	raw_spin_unlock(&its_dev->event_map.vlpi_lock);
-	return ret;
+	return 0;
 }
 
 static int its_vlpi_prop_update(struct irq_data *d, struct its_cmd_info *info)
@@ -1986,6 +1973,8 @@
 	if (!is_v4(its_dev->its))
 		return -EINVAL;
 
+	guard(raw_spinlock)(&its_dev->event_map.vlpi_lock);
+
 	/* Unmap request? */
 	if (!info)
 		return its_vlpi_unmap(d);
@@ -3821,14 +3810,36 @@
 	raw_spin_unlock_irqrestore(&vpe_proxy.lock, flags);
 }
 
+static void its_vpe_4_1_invall_locked(int cpu, struct its_vpe *vpe)
+{
+	void __iomem *rdbase;
+	u64 val;
+
+	val  = GICR_INVALLR_V;
+	val |= FIELD_PREP(GICR_INVALLR_VPEID, vpe->vpe_id);
+
+	guard(raw_spinlock)(&gic_data_rdist_cpu(cpu)->rd_lock);
+	rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base;
+	gic_write_lpir(val, rdbase + GICR_INVALLR);
+	wait_for_syncr(rdbase);
+}
+
 static int its_vpe_set_affinity(struct irq_data *d,
 				const struct cpumask *mask_val,
 				bool force)
 {
 	struct its_vpe *vpe = irq_data_get_irq_chip_data(d);
-	struct cpumask common, *table_mask;
+	unsigned int from, cpu = nr_cpu_ids;
+	struct cpumask *table_mask;
+	struct its_node *its;
 	unsigned long flags;
-	int from, cpu;
+
+	/*
+	 * Check if we're racing against a VPE being destroyed, for
+	 * which we don't want to allow a VMOVP.
+	 */
+	if (!atomic_read(&vpe->vmapp_count))
+		return -EINVAL;
 
 	/*
 	 * Changing affinity is mega expensive, so let's be as lazy as
@@ -3850,10 +3861,15 @@
 	 * If we are offered another CPU in the same GICv4.1 ITS
 	 * affinity, pick this one. Otherwise, any CPU will do.
 	 */
-	if (table_mask && cpumask_and(&common, mask_val, table_mask))
-		cpu = cpumask_test_cpu(from, &common) ? from : cpumask_first(&common);
-	else
+	if (table_mask)
+		cpu = cpumask_any_and(mask_val, table_mask);
+	if (cpu < nr_cpu_ids) {
+		if (cpumask_test_cpu(from, mask_val) &&
+		    cpumask_test_cpu(from, table_mask))
+			cpu = from;
+	} else {
 		cpu = cpumask_first(mask_val);
+	}
 
 	if (from == cpu)
 		goto out;
@@ -3861,6 +3877,11 @@
 	vpe->col_idx = cpu;
 
 	its_send_vmovp(vpe);
+
+	its = find_4_1_its();
+	if (its && its->flags & ITS_FLAGS_WORKAROUND_HISILICON_162100801)
+		its_vpe_4_1_invall_locked(cpu, vpe);
+
 	its_vpe_db_proxy_move(vpe, from, cpu);
 
 out:
@@ -4163,22 +4184,12 @@
 
 static void its_vpe_4_1_invall(struct its_vpe *vpe)
 {
-	void __iomem *rdbase;
 	unsigned long flags;
-	u64 val;
 	int cpu;
 
-	val  = GICR_INVALLR_V;
-	val |= FIELD_PREP(GICR_INVALLR_VPEID, vpe->vpe_id);
-
 	/* Target the redistributor this vPE is currently known on */
 	cpu = vpe_to_cpuid_lock(vpe, &flags);
-	raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock);
-	rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base;
-	gic_write_lpir(val, rdbase + GICR_INVALLR);
-
-	wait_for_syncr(rdbase);
-	raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock);
+	its_vpe_4_1_invall_locked(cpu, vpe);
 	vpe_to_cpuid_unlock(vpe, flags);
 }
 
@@ -4470,9 +4481,8 @@
 	raw_spin_lock_init(&vpe->vpe_lock);
 	vpe->vpe_id = vpe_id;
 	vpe->vpt_page = vpt_page;
-	if (gic_rdists->has_rvpeid)
-		atomic_set(&vpe->vmapp_count, 0);
-	else
+	atomic_set(&vpe->vmapp_count, 0);
+	if (!gic_rdists->has_rvpeid)
 		vpe->vpe_proxy_event = -1;
 
 	return 0;
@@ -4521,8 +4531,6 @@
 	struct page *vprop_page;
 	int base, nr_ids, i, err = 0;
 
-	BUG_ON(!vm);
-
 	bitmap = its_lpi_alloc(roundup_pow_of_two(nr_irqs), &base, &nr_ids);
 	if (!bitmap)
 		return -ENOMEM;
@@ -4561,13 +4569,8 @@
 		irqd_set_resend_when_in_progress(irq_get_irq_data(virq + i));
 	}
 
-	if (err) {
-		if (i > 0)
-			its_vpe_irq_domain_free(domain, virq, i);
-
-		its_lpi_free(bitmap, base, nr_ids);
-		its_free_prop_table(vprop_page);
-	}
+	if (err)
+		its_vpe_irq_domain_free(domain, virq, i);
 
 	return err;
 }
@@ -4779,6 +4782,14 @@
 	return true;
 }
 
+static bool __maybe_unused its_enable_quirk_hip09_162100801(void *data)
+{
+	struct its_node *its = data;
+
+	its->flags |= ITS_FLAGS_WORKAROUND_HISILICON_162100801;
+	return true;
+}
+
 static const struct gic_quirk its_quirks[] = {
 #ifdef CONFIG_CAVIUM_ERRATUM_22375
 	{
@@ -4825,6 +4836,14 @@
 		.init	= its_enable_quirk_hip07_161600802,
 	},
 #endif
+#ifdef CONFIG_HISILICON_ERRATUM_162100801
+	{
+		.desc	= "ITS: Hip09 erratum 162100801",
+		.iidr	= 0x00051736,
+		.mask	= 0xffffffff,
+		.init	= its_enable_quirk_hip09_162100801,
+	},
+#endif
 #ifdef CONFIG_ROCKCHIP_ERRATUM_3588001
 	{
 		.desc   = "ITS: Rockchip erratum RK3588001",
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-gic-v3.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-gic-v3.c
@@ -463,6 +463,13 @@
 	}
 
 	gic_poke_irq(d, reg);
+
+	/*
+	 * Force read-back to guarantee that the active state has taken
+	 * effect, and won't race with a guest-driven deactivation.
+	 */
+	if (reg == GICD_ISACTIVER)
+		gic_peek_irq(d, reg);
 	return 0;
 }
 
@@ -1464,7 +1471,7 @@
 static int gic_cpu_pm_notifier(struct notifier_block *self,
 			       unsigned long cmd, void *v)
 {
-	if (cmd == CPU_PM_EXIT) {
+	if (cmd == CPU_PM_EXIT || cmd == CPU_PM_ENTER_FAILED) {
 		if (gic_dist_security_disabled())
 			gic_enable_redist(true);
 		gic_cpu_sys_reg_init();
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-gic.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-gic.c
@@ -64,7 +64,7 @@
 
 union gic_base {
 	void __iomem *common_base;
-	void __percpu * __iomem *percpu_base;
+	void __iomem * __percpu *percpu_base;
 };
 
 struct gic_chip_data {
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-imx-irqsteer.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-imx-irqsteer.c
@@ -36,6 +36,7 @@
 	int			channel;
 	struct irq_domain	*domain;
 	u32			*saved_reg;
+	struct device		*dev;
 };
 
 static int imx_irqsteer_get_reg_index(struct irqsteer_data *data,
@@ -72,10 +73,26 @@
 	raw_spin_unlock_irqrestore(&data->lock, flags);
 }
 
+static void imx_irqsteer_irq_bus_lock(struct irq_data *d)
+{
+	struct irqsteer_data *data = d->chip_data;
+
+	pm_runtime_get_sync(data->dev);
+}
+
+static void imx_irqsteer_irq_bus_sync_unlock(struct irq_data *d)
+{
+	struct irqsteer_data *data = d->chip_data;
+
+	pm_runtime_put_autosuspend(data->dev);
+}
+
 static const struct irq_chip imx_irqsteer_irq_chip = {
-	.name		= "irqsteer",
-	.irq_mask	= imx_irqsteer_irq_mask,
-	.irq_unmask	= imx_irqsteer_irq_unmask,
+	.name			= "irqsteer",
+	.irq_mask		= imx_irqsteer_irq_mask,
+	.irq_unmask		= imx_irqsteer_irq_unmask,
+	.irq_bus_lock		= imx_irqsteer_irq_bus_lock,
+	.irq_bus_sync_unlock	= imx_irqsteer_irq_bus_sync_unlock,
 };
 
 static int imx_irqsteer_irq_map(struct irq_domain *h, unsigned int irq,
@@ -150,6 +167,7 @@
 	if (!data)
 		return -ENOMEM;
 
+	data->dev = &pdev->dev;
 	data->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->regs)) {
 		dev_err(&pdev->dev, "failed to initialize reg\n");
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-loongarch-cpu.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-loongarch-cpu.c
@@ -18,11 +18,13 @@
 
 static u32 lpic_gsi_to_irq(u32 gsi)
 {
+	int irq = 0;
+
 	/* Only pch irqdomain transferring is required for LoongArch. */
 	if (gsi >= GSI_MIN_PCH_IRQ && gsi <= GSI_MAX_PCH_IRQ)
-		return acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH);
+		irq = acpi_register_gsi(NULL, gsi, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_HIGH);
 
-	return 0;
+	return (irq > 0) ? irq : 0;
 }
 
 static struct fwnode_handle *lpic_get_gsi_domain_id(u32 gsi)
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-loongson-eiointc.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-loongson-eiointc.c
@@ -15,6 +15,7 @@
 #include <linux/irqchip/chained_irq.h>
 #include <linux/kernel.h>
 #include <linux/syscore_ops.h>
+#include <asm/numa.h>
 
 #define EIOINTC_REG_NODEMAP	0x14a0
 #define EIOINTC_REG_IPMAP	0x14c0
@@ -349,7 +350,7 @@
 	int node;
 
 	if (cpu_has_flatmode)
-		node = cpu_to_node(eiointc_priv[nr_pics - 1]->node * CORES_PER_EIO_NODE);
+		node = early_cpu_to_node(eiointc_priv[nr_pics - 1]->node * CORES_PER_EIO_NODE);
 	else
 		node = eiointc_priv[nr_pics - 1]->node;
 
@@ -441,7 +442,7 @@
 		goto out_free_handle;
 
 	if (cpu_has_flatmode)
-		node = cpu_to_node(acpi_eiointc->node * CORES_PER_EIO_NODE);
+		node = early_cpu_to_node(acpi_eiointc->node * CORES_PER_EIO_NODE);
 	else
 		node = acpi_eiointc->node;
 	acpi_set_vec_parent(node, priv->eiointc_domain, pch_group);
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-loongson-liointc.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-loongson-liointc.c
@@ -28,7 +28,7 @@
 
 #define LIOINTC_INTC_CHIP_START	0x20
 
-#define LIOINTC_REG_INTC_STATUS	(LIOINTC_INTC_CHIP_START + 0x20)
+#define LIOINTC_REG_INTC_STATUS(core)	(LIOINTC_INTC_CHIP_START + 0x20 + (core) * 8)
 #define LIOINTC_REG_INTC_EN_STATUS	(LIOINTC_INTC_CHIP_START + 0x04)
 #define LIOINTC_REG_INTC_ENABLE	(LIOINTC_INTC_CHIP_START + 0x08)
 #define LIOINTC_REG_INTC_DISABLE	(LIOINTC_INTC_CHIP_START + 0x0c)
@@ -217,7 +217,7 @@
 		goto out_free_priv;
 
 	for (i = 0; i < LIOINTC_NUM_CORES; i++)
-		priv->core_isr[i] = base + LIOINTC_REG_INTC_STATUS;
+		priv->core_isr[i] = base + LIOINTC_REG_INTC_STATUS(i);
 
 	for (i = 0; i < LIOINTC_NUM_PARENT; i++)
 		priv->handler[i].parent_int_map = parent_int_map[i];
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-loongson-pch-msi.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-loongson-pch-msi.c
@@ -136,7 +136,7 @@
 
 err_hwirq:
 	pch_msi_free_hwirq(priv, hwirq, nr_irqs);
-	irq_domain_free_irqs_parent(domain, virq, i - 1);
+	irq_domain_free_irqs_parent(domain, virq, i);
 
 	return err;
 }
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-mbigen.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-mbigen.c
@@ -64,6 +64,20 @@
 	void __iomem		*base;
 };
 
+static inline unsigned int get_mbigen_node_offset(unsigned int nid)
+{
+	unsigned int offset = nid * MBIGEN_NODE_OFFSET;
+
+	/*
+	 * To avoid touched clear register in unexpected way, we need to directly
+	 * skip clear register when access to more than 10 mbigen nodes.
+	 */
+	if (nid >= (REG_MBIGEN_CLEAR_OFFSET / MBIGEN_NODE_OFFSET))
+		offset += MBIGEN_NODE_OFFSET;
+
+	return offset;
+}
+
 static inline unsigned int get_mbigen_vec_reg(irq_hw_number_t hwirq)
 {
 	unsigned int nid, pin;
@@ -72,8 +86,7 @@
 	nid = hwirq / IRQS_PER_MBIGEN_NODE + 1;
 	pin = hwirq % IRQS_PER_MBIGEN_NODE;
 
-	return pin * 4 + nid * MBIGEN_NODE_OFFSET
-			+ REG_MBIGEN_VEC_OFFSET;
+	return pin * 4 + get_mbigen_node_offset(nid) + REG_MBIGEN_VEC_OFFSET;
 }
 
 static inline void get_mbigen_type_reg(irq_hw_number_t hwirq,
@@ -88,8 +101,7 @@
 	*mask = 1 << (irq_ofst % 32);
 	ofst = irq_ofst / 32 * 4;
 
-	*addr = ofst + nid * MBIGEN_NODE_OFFSET
-		+ REG_MBIGEN_TYPE_OFFSET;
+	*addr = ofst + get_mbigen_node_offset(nid) + REG_MBIGEN_TYPE_OFFSET;
 }
 
 static inline void get_mbigen_clear_reg(irq_hw_number_t hwirq,
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-meson-gpio.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-meson-gpio.c
@@ -173,7 +173,7 @@
 	void __iomem *base;
 	u32 channel_irqs[MAX_NUM_CHANNEL];
 	DECLARE_BITMAP(channel_map, MAX_NUM_CHANNEL);
-	spinlock_t lock;
+	raw_spinlock_t lock;
 };
 
 static void meson_gpio_irq_update_bits(struct meson_gpio_irq_controller *ctl,
@@ -182,14 +182,14 @@
 	unsigned long flags;
 	u32 tmp;
 
-	spin_lock_irqsave(&ctl->lock, flags);
+	raw_spin_lock_irqsave(&ctl->lock, flags);
 
 	tmp = readl_relaxed(ctl->base + reg);
 	tmp &= ~mask;
 	tmp |= val;
 	writel_relaxed(tmp, ctl->base + reg);
 
-	spin_unlock_irqrestore(&ctl->lock, flags);
+	raw_spin_unlock_irqrestore(&ctl->lock, flags);
 }
 
 static void meson_gpio_irq_init_dummy(struct meson_gpio_irq_controller *ctl)
@@ -239,12 +239,12 @@
 	unsigned long flags;
 	unsigned int idx;
 
-	spin_lock_irqsave(&ctl->lock, flags);
+	raw_spin_lock_irqsave(&ctl->lock, flags);
 
 	/* Find a free channel */
 	idx = find_first_zero_bit(ctl->channel_map, ctl->params->nr_channels);
 	if (idx >= ctl->params->nr_channels) {
-		spin_unlock_irqrestore(&ctl->lock, flags);
+		raw_spin_unlock_irqrestore(&ctl->lock, flags);
 		pr_err("No channel available\n");
 		return -ENOSPC;
 	}
@@ -252,7 +252,7 @@
 	/* Mark the channel as used */
 	set_bit(idx, ctl->channel_map);
 
-	spin_unlock_irqrestore(&ctl->lock, flags);
+	raw_spin_unlock_irqrestore(&ctl->lock, flags);
 
 	/*
 	 * Setup the mux of the channel to route the signal of the pad
@@ -562,7 +562,7 @@
 	if (!ctl)
 		return -ENOMEM;
 
-	spin_lock_init(&ctl->lock);
+	raw_spin_lock_init(&ctl->lock);
 
 	ctl->base = of_iomap(node, 0);
 	if (!ctl->base) {
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-mscc-ocelot.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-mscc-ocelot.c
@@ -37,7 +37,7 @@
 	.reg_off_ena_clr	= 0x1c,
 	.reg_off_ena_set	= 0x20,
 	.reg_off_ident		= 0x38,
-	.reg_off_trigger	= 0x5c,
+	.reg_off_trigger	= 0x4,
 	.n_irq			= 24,
 };
 
@@ -70,7 +70,7 @@
 	.reg_off_ena_clr	= 0x1c,
 	.reg_off_ena_set	= 0x20,
 	.reg_off_ident		= 0x38,
-	.reg_off_trigger	= 0x5c,
+	.reg_off_trigger	= 0x4,
 	.n_irq			= 29,
 };
 
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-pic32-evic.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-pic32-evic.c
@@ -190,13 +190,11 @@
 {
 	struct device_node *node = irq_domain_get_of_node(domain);
 	struct evic_chip_data *priv = domain->host_data;
-	struct property *prop;
-	const __le32 *p;
 	u32 hwirq;
 	int i = 0;
 	const char *pname = "microchip,external-irqs";
 
-	of_property_for_each_u32(node, pname, prop, p, hwirq) {
+	of_property_for_each_u32(node, pname, hwirq) {
 		if (i >= ARRAY_SIZE(priv->ext_irqs)) {
 			pr_warn("More than %d external irq, skip rest\n",
 				ARRAY_SIZE(priv->ext_irqs));
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-renesas-rzg2l.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-renesas-rzg2l.c
@@ -8,6 +8,7 @@
  */
 
 #include <linux/bitfield.h>
+#include <linux/cleanup.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/io.h>
@@ -85,10 +86,9 @@
 	return data->domain->host_data;
 }
 
-static void rzg2l_irq_eoi(struct irq_data *d)
+static void rzg2l_clear_irq_int(struct rzg2l_irqc_priv *priv, unsigned int hwirq)
 {
-	unsigned int hw_irq = irqd_to_hwirq(d) - IRQC_IRQ_START;
-	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
+	unsigned int hw_irq = hwirq - IRQC_IRQ_START;
 	u32 bit = BIT(hw_irq);
 	u32 iitsr, iscr;
 
@@ -99,20 +99,30 @@
 	 * ISCR can only be cleared if the type is falling-edge, rising-edge or
 	 * falling/rising-edge.
 	 */
-	if ((iscr & bit) && (iitsr & IITSR_IITSEL_MASK(hw_irq)))
+	if ((iscr & bit) && (iitsr & IITSR_IITSEL_MASK(hw_irq))) {
 		writel_relaxed(iscr & ~bit, priv->base + ISCR);
+		/*
+		 * Enforce that the posted write is flushed to prevent that the
+		 * just handled interrupt is raised again.
+		 */
+		readl_relaxed(priv->base + ISCR);
+	}
 }
 
-static void rzg2l_tint_eoi(struct irq_data *d)
+static void rzg2l_clear_tint_int(struct rzg2l_irqc_priv *priv, unsigned int hwirq)
 {
-	unsigned int hw_irq = irqd_to_hwirq(d) - IRQC_TINT_START;
-	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
-	u32 bit = BIT(hw_irq);
+	u32 bit = BIT(hwirq - IRQC_TINT_START);
 	u32 reg;
 
 	reg = readl_relaxed(priv->base + TSCR);
-	if (reg & bit)
+	if (reg & bit) {
 		writel_relaxed(reg & ~bit, priv->base + TSCR);
+		/*
+		 * Enforce that the posted write is flushed to prevent that the
+		 * just handled interrupt is raised again.
+		 */
+		readl_relaxed(priv->base + TSCR);
+	}
 }
 
 static void rzg2l_irqc_eoi(struct irq_data *d)
@@ -122,9 +132,9 @@
 
 	raw_spin_lock(&priv->lock);
 	if (hw_irq >= IRQC_IRQ_START && hw_irq <= IRQC_IRQ_COUNT)
-		rzg2l_irq_eoi(d);
+		rzg2l_clear_irq_int(priv, hw_irq);
 	else if (hw_irq >= IRQC_TINT_START && hw_irq < IRQC_NUM_IRQ)
-		rzg2l_tint_eoi(d);
+		rzg2l_clear_tint_int(priv, hw_irq);
 	raw_spin_unlock(&priv->lock);
 	irq_chip_eoi_parent(d);
 }
@@ -142,7 +152,7 @@
 
 		raw_spin_lock(&priv->lock);
 		reg = readl_relaxed(priv->base + TSSR(tssr_index));
-		reg &= ~(TSSEL_MASK << TSSEL_SHIFT(tssr_offset));
+		reg &= ~(TIEN << TSSEL_SHIFT(tssr_offset));
 		writel_relaxed(reg, priv->base + TSSR(tssr_index));
 		raw_spin_unlock(&priv->lock);
 	}
@@ -154,7 +164,6 @@
 	unsigned int hw_irq = irqd_to_hwirq(d);
 
 	if (hw_irq >= IRQC_TINT_START && hw_irq < IRQC_NUM_IRQ) {
-		unsigned long tint = (uintptr_t)irq_data_get_irq_chip_data(d);
 		struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
 		u32 offset = hw_irq - IRQC_TINT_START;
 		u32 tssr_offset = TSSR_OFFSET(offset);
@@ -163,7 +172,7 @@
 
 		raw_spin_lock(&priv->lock);
 		reg = readl_relaxed(priv->base + TSSR(tssr_index));
-		reg |= (TIEN | tint) << TSSEL_SHIFT(tssr_offset);
+		reg |= TIEN << TSSEL_SHIFT(tssr_offset);
 		writel_relaxed(reg, priv->base + TSSR(tssr_index));
 		raw_spin_unlock(&priv->lock);
 	}
@@ -172,8 +181,10 @@
 
 static int rzg2l_irq_set_type(struct irq_data *d, unsigned int type)
 {
-	unsigned int hw_irq = irqd_to_hwirq(d) - IRQC_IRQ_START;
 	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
+	unsigned int hwirq = irqd_to_hwirq(d);
+	u32 iitseln = hwirq - IRQC_IRQ_START;
+	bool clear_irq_int = false;
 	u16 sense, tmp;
 
 	switch (type & IRQ_TYPE_SENSE_MASK) {
@@ -183,14 +194,17 @@
 
 	case IRQ_TYPE_EDGE_FALLING:
 		sense = IITSR_IITSEL_EDGE_FALLING;
+		clear_irq_int = true;
 		break;
 
 	case IRQ_TYPE_EDGE_RISING:
 		sense = IITSR_IITSEL_EDGE_RISING;
+		clear_irq_int = true;
 		break;
 
 	case IRQ_TYPE_EDGE_BOTH:
 		sense = IITSR_IITSEL_EDGE_BOTH;
+		clear_irq_int = true;
 		break;
 
 	default:
@@ -199,21 +213,40 @@
 
 	raw_spin_lock(&priv->lock);
 	tmp = readl_relaxed(priv->base + IITSR);
-	tmp &= ~IITSR_IITSEL_MASK(hw_irq);
-	tmp |= IITSR_IITSEL(hw_irq, sense);
+	tmp &= ~IITSR_IITSEL_MASK(iitseln);
+	tmp |= IITSR_IITSEL(iitseln, sense);
+	if (clear_irq_int)
+		rzg2l_clear_irq_int(priv, hwirq);
 	writel_relaxed(tmp, priv->base + IITSR);
 	raw_spin_unlock(&priv->lock);
 
 	return 0;
 }
 
+static u32 rzg2l_disable_tint_and_set_tint_source(struct irq_data *d, struct rzg2l_irqc_priv *priv,
+						  u32 reg, u32 tssr_offset, u8 tssr_index)
+{
+	u32 tint = (u32)(uintptr_t)irq_data_get_irq_chip_data(d);
+	u32 tien = reg & (TIEN << TSSEL_SHIFT(tssr_offset));
+
+	/* Clear the relevant byte in reg */
+	reg &= ~(TSSEL_MASK << TSSEL_SHIFT(tssr_offset));
+	/* Set TINT and leave TIEN clear */
+	reg |= tint << TSSEL_SHIFT(tssr_offset);
+	writel_relaxed(reg, priv->base + TSSR(tssr_index));
+
+	return reg | tien;
+}
+
 static int rzg2l_tint_set_edge(struct irq_data *d, unsigned int type)
 {
 	struct rzg2l_irqc_priv *priv = irq_data_to_priv(d);
 	unsigned int hwirq = irqd_to_hwirq(d);
 	u32 titseln = hwirq - IRQC_TINT_START;
+	u32 tssr_offset = TSSR_OFFSET(titseln);
+	u8 tssr_index = TSSR_INDEX(titseln);
 	u8 index, sense;
-	u32 reg;
+	u32 reg, tssr;
 
 	switch (type & IRQ_TYPE_SENSE_MASK) {
 	case IRQ_TYPE_EDGE_RISING:
@@ -235,10 +268,14 @@
 	}
 
 	raw_spin_lock(&priv->lock);
+	tssr = readl_relaxed(priv->base + TSSR(tssr_index));
+	tssr = rzg2l_disable_tint_and_set_tint_source(d, priv, tssr, tssr_offset, tssr_index);
 	reg = readl_relaxed(priv->base + TITSR(index));
 	reg &= ~(IRQ_MASK << (titseln * TITSEL_WIDTH));
 	reg |= sense << (titseln * TITSEL_WIDTH);
 	writel_relaxed(reg, priv->base + TITSR(index));
+	rzg2l_clear_tint_int(priv, hwirq);
+	writel_relaxed(tssr, priv->base + TSSR(tssr_index));
 	raw_spin_unlock(&priv->lock);
 
 	return 0;
@@ -373,12 +410,12 @@
 
 static int rzg2l_irqc_init(struct device_node *node, struct device_node *parent)
 {
+	struct platform_device *pdev = of_find_device_by_node(node);
+	struct device *dev __free(put_device) = pdev ? &pdev->dev : NULL;
 	struct irq_domain *irq_domain, *parent_domain;
-	struct platform_device *pdev;
 	struct reset_control *resetn;
 	int ret;
 
-	pdev = of_find_device_by_node(node);
 	if (!pdev)
 		return -ENODEV;
 
@@ -432,6 +469,17 @@
 
 	register_syscore_ops(&rzg2l_irqc_syscore_ops);
 
+	/*
+	 * Prevent the cleanup function from invoking put_device by assigning
+	 * NULL to dev.
+	 *
+	 * make coccicheck will complain about missing put_device calls, but
+	 * those are false positives, as dev will be automatically "put" via
+	 * __free_put_device on the failing path.
+	 * On the successful path we don't actually want to "put" dev.
+	 */
+	dev = NULL;
+
 	return 0;
 
 pm_put:
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-riscv-intc.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-riscv-intc.c
@@ -17,17 +17,19 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/smp.h>
+#include <linux/soc/andes/irq.h>
 
 static struct irq_domain *intc_domain;
+static unsigned int riscv_intc_nr_irqs __ro_after_init = BITS_PER_LONG;
+static unsigned int riscv_intc_custom_base __ro_after_init = BITS_PER_LONG;
+static unsigned int riscv_intc_custom_nr_irqs __ro_after_init;
 
 static asmlinkage void riscv_intc_irq(struct pt_regs *regs)
 {
 	unsigned long cause = regs->cause & ~CAUSE_IRQ_FLAG;
 
-	if (unlikely(cause >= BITS_PER_LONG))
-		panic("unexpected interrupt cause");
-
-	generic_handle_domain_irq(intc_domain, cause);
+	if (generic_handle_domain_irq(intc_domain, cause))
+		pr_warn_ratelimited("Failed to handle interrupt (cause: %ld)\n", cause);
 }
 
 /*
@@ -47,6 +49,31 @@
 	csr_set(CSR_IE, BIT(d->hwirq));
 }
 
+static void andes_intc_irq_mask(struct irq_data *d)
+{
+	/*
+	 * Andes specific S-mode local interrupt causes (hwirq)
+	 * are defined as (256 + n) and controlled by n-th bit
+	 * of SLIE.
+	 */
+	unsigned int mask = BIT(d->hwirq % BITS_PER_LONG);
+
+	if (d->hwirq < ANDES_SLI_CAUSE_BASE)
+		csr_clear(CSR_IE, mask);
+	else
+		csr_clear(ANDES_CSR_SLIE, mask);
+}
+
+static void andes_intc_irq_unmask(struct irq_data *d)
+{
+	unsigned int mask = BIT(d->hwirq % BITS_PER_LONG);
+
+	if (d->hwirq < ANDES_SLI_CAUSE_BASE)
+		csr_set(CSR_IE, mask);
+	else
+		csr_set(ANDES_CSR_SLIE, mask);
+}
+
 static void riscv_intc_irq_eoi(struct irq_data *d)
 {
 	/*
@@ -70,12 +97,21 @@
 	.irq_eoi = riscv_intc_irq_eoi,
 };
 
+static struct irq_chip andes_intc_chip = {
+	.name		= "RISC-V INTC",
+	.irq_mask	= andes_intc_irq_mask,
+	.irq_unmask	= andes_intc_irq_unmask,
+	.irq_eoi	= riscv_intc_irq_eoi,
+};
+
 static int riscv_intc_domain_map(struct irq_domain *d, unsigned int irq,
 				 irq_hw_number_t hwirq)
 {
+	struct irq_chip *chip = d->host_data;
+
 	irq_set_percpu_devid(irq);
-	irq_domain_set_info(d, irq, hwirq, &riscv_intc_chip, d->host_data,
-			    handle_percpu_devid_irq, NULL, NULL);
+	irq_domain_set_info(d, irq, hwirq, chip, NULL, handle_percpu_devid_irq,
+			    NULL, NULL);
 
 	return 0;
 }
@@ -93,6 +129,14 @@
 	if (ret)
 		return ret;
 
+	/*
+	 * Only allow hwirq for which we have corresponding standard or
+	 * custom interrupt enable register.
+	 */
+	if ((hwirq >= riscv_intc_nr_irqs && hwirq < riscv_intc_custom_base) ||
+	    (hwirq >= riscv_intc_custom_base + riscv_intc_custom_nr_irqs))
+		return -EINVAL;
+
 	for (i = 0; i < nr_irqs; i++) {
 		ret = riscv_intc_domain_map(domain, virq + i, hwirq + i);
 		if (ret)
@@ -113,12 +157,12 @@
 	return intc_domain->fwnode;
 }
 
-static int __init riscv_intc_init_common(struct fwnode_handle *fn)
+static int __init riscv_intc_init_common(struct fwnode_handle *fn,
+					 struct irq_chip *chip)
 {
 	int rc;
 
-	intc_domain = irq_domain_create_linear(fn, BITS_PER_LONG,
-					       &riscv_intc_domain_ops, NULL);
+	intc_domain = irq_domain_create_tree(fn, &riscv_intc_domain_ops, chip);
 	if (!intc_domain) {
 		pr_err("unable to add IRQ domain\n");
 		return -ENXIO;
@@ -132,7 +176,11 @@
 
 	riscv_set_intc_hwnode_fn(riscv_intc_hwnode);
 
-	pr_info("%d local interrupts mapped\n", BITS_PER_LONG);
+	pr_info("%d local interrupts mapped\n", riscv_intc_nr_irqs);
+	if (riscv_intc_custom_nr_irqs) {
+		pr_info("%d custom local interrupts mapped\n",
+			riscv_intc_custom_nr_irqs);
+	}
 
 	return 0;
 }
@@ -140,8 +188,9 @@
 static int __init riscv_intc_init(struct device_node *node,
 				  struct device_node *parent)
 {
-	int rc;
+	struct irq_chip *chip = &riscv_intc_chip;
 	unsigned long hartid;
+	int rc;
 
 	rc = riscv_of_parent_hartid(node, &hartid);
 	if (rc < 0) {
@@ -166,18 +215,26 @@
 		return 0;
 	}
 
-	return riscv_intc_init_common(of_node_to_fwnode(node));
+	if (of_device_is_compatible(node, "andestech,cpu-intc")) {
+		riscv_intc_custom_base = ANDES_SLI_CAUSE_BASE;
+		riscv_intc_custom_nr_irqs = ANDES_RV_IRQ_LAST;
+		chip = &andes_intc_chip;
+	}
+
+	return riscv_intc_init_common(of_node_to_fwnode(node), chip);
 }
 
 IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init);
+IRQCHIP_DECLARE(andes, "andestech,cpu-intc", riscv_intc_init);
 
 #ifdef CONFIG_ACPI
 
 static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header,
 				       const unsigned long end)
 {
-	struct fwnode_handle *fn;
 	struct acpi_madt_rintc *rintc;
+	struct fwnode_handle *fn;
+	int rc;
 
 	rintc = (struct acpi_madt_rintc *)header;
 
@@ -196,7 +253,11 @@
 		return -ENOMEM;
 	}
 
-	return riscv_intc_init_common(fn);
+	rc = riscv_intc_init_common(fn, &riscv_intc_chip);
+	if (rc)
+		irq_domain_free_fwnode(fn);
+
+	return rc;
 }
 
 IRQCHIP_ACPI_DECLARE(riscv_intc, ACPI_MADT_TYPE_RINTC, NULL,
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-sifive-plic.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-sifive-plic.c
@@ -120,16 +120,6 @@
 	}
 }
 
-static void plic_irq_enable(struct irq_data *d)
-{
-	plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 1);
-}
-
-static void plic_irq_disable(struct irq_data *d)
-{
-	plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 0);
-}
-
 static void plic_irq_unmask(struct irq_data *d)
 {
 	struct plic_priv *priv = irq_data_get_irq_chip_data(d);
@@ -144,6 +134,17 @@
 	writel(0, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID);
 }
 
+static void plic_irq_enable(struct irq_data *d)
+{
+	plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 1);
+	plic_irq_unmask(d);
+}
+
+static void plic_irq_disable(struct irq_data *d)
+{
+	plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 0);
+}
+
 static void plic_irq_eoi(struct irq_data *d)
 {
 	struct plic_handler *handler = this_cpu_ptr(&plic_handlers);
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-sunxi-nmi.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-sunxi-nmi.c
@@ -186,7 +186,8 @@
 	gc->chip_types[0].chip.irq_unmask	= irq_gc_mask_set_bit;
 	gc->chip_types[0].chip.irq_eoi		= irq_gc_ack_set_bit;
 	gc->chip_types[0].chip.irq_set_type	= sunxi_sc_nmi_set_type;
-	gc->chip_types[0].chip.flags		= IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED;
+	gc->chip_types[0].chip.flags		= IRQCHIP_EOI_THREADED | IRQCHIP_EOI_IF_HANDLED |
+						  IRQCHIP_SKIP_SET_WAKE;
 	gc->chip_types[0].regs.ack		= reg_offs->pend;
 	gc->chip_types[0].regs.mask		= reg_offs->enable;
 	gc->chip_types[0].regs.type		= reg_offs->ctrl;
--- linux-qcom-6.8.0.orig/drivers/irqchip/irq-xilinx-intc.c
+++ linux-qcom-6.8.0/drivers/irqchip/irq-xilinx-intc.c
@@ -189,7 +189,7 @@
 		irqc->intr_mask = 0;
 	}
 
-	if (irqc->intr_mask >> irqc->nr_irq)
+	if ((u64)irqc->intr_mask >> irqc->nr_irq)
 		pr_warn("irq-xilinx: mismatch in kind-of-intr param\n");
 
 	pr_info("irq-xilinx: %pOF: num_irq=%d, edge=0x%x\n",
--- linux-qcom-6.8.0.orig/drivers/irqchip/irqchip.c
+++ linux-qcom-6.8.0/drivers/irqchip/irqchip.c
@@ -35,11 +35,10 @@
 int platform_irqchip_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
-	struct device_node *par_np = of_irq_find_parent(np);
+	struct device_node *par_np __free(device_node) = of_irq_find_parent(np);
 	of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev);
 
 	if (!irq_init_cb) {
-		of_node_put(par_np);
 		return -EINVAL;
 	}
 
@@ -55,7 +54,6 @@
 	 * interrupt controller can check for specific domains as necessary.
 	 */
 	if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) {
-		of_node_put(par_np);
 		return -EPROBE_DEFER;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ linux-qcom-6.8.0/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -1900,7 +1900,7 @@
 static void
 hfcmulti_tx(struct hfc_multi *hc, int ch)
 {
-	int i, ii, temp, len = 0;
+	int i, ii, temp, tmp_len, len = 0;
 	int Zspace, z1, z2; /* must be int for calculation */
 	int Fspace, f1, f2;
 	u_char *d;
@@ -2121,14 +2121,15 @@
 		HFC_wait_nodebug(hc);
 	}
 
+	tmp_len = (*sp)->len;
 	dev_kfree_skb(*sp);
 	/* check for next frame */
 	if (bch && get_next_bframe(bch)) {
-		len = (*sp)->len;
+		len = tmp_len;
 		goto next_frame;
 	}
 	if (dch && get_next_dframe(dch)) {
-		len = (*sp)->len;
+		len = tmp_len;
 		goto next_frame;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/isdn/mISDN/socket.c
+++ linux-qcom-6.8.0/drivers/isdn/mISDN/socket.c
@@ -401,23 +401,23 @@
 }
 
 static int data_sock_setsockopt(struct socket *sock, int level, int optname,
-				sockptr_t optval, unsigned int len)
+				sockptr_t optval, unsigned int optlen)
 {
 	struct sock *sk = sock->sk;
 	int err = 0, opt = 0;
 
 	if (*debug & DEBUG_SOCKET)
 		printk(KERN_DEBUG "%s(%p, %d, %x, optval, %d)\n", __func__, sock,
-		       level, optname, len);
+		       level, optname, optlen);
 
 	lock_sock(sk);
 
 	switch (optname) {
 	case MISDN_TIME_STAMP:
-		if (copy_from_sockptr(&opt, optval, sizeof(int))) {
-			err = -EFAULT;
+		err = copy_safe_from_sockptr(&opt, sizeof(opt),
+					     optval, optlen);
+		if (err)
 			break;
-		}
 
 		if (opt)
 			_pms(sk)->cmask |= MISDN_TIME_STAMP;
--- linux-qcom-6.8.0.orig/drivers/leds/Kconfig
+++ linux-qcom-6.8.0/drivers/leds/Kconfig
@@ -59,6 +59,18 @@
 	  This option enables support for on-chip LED drivers found on Marvell
 	  Semiconductor 88PM8606 PMIC.
 
+config LEDS_AAEON
+	tristate "AAEON LED driver"
+	depends on X86
+	depends on UBUNTU_ODM_DRIVERS
+	select MFD_AAEON
+	help
+	  This led driver adds support for LED brightness control on Single
+	  Board Computers produced by AAEON.
+
+	  This driver leverages the ASUS WMI interface to access device
+	  resources.
+
 config LEDS_AN30259A
 	tristate "LED support for Panasonic AN30259A"
 	depends on LEDS_CLASS && I2C && OF
@@ -410,7 +422,6 @@
 	depends on OF
 	depends on I2C
 	select FW_LOADER
-	select FW_LOADER_USER_HELPER
 	help
 	  This option supports common operations for LP5521/5523/55231/5562/8501
 	  devices.
--- linux-qcom-6.8.0.orig/drivers/leds/Makefile
+++ linux-qcom-6.8.0/drivers/leds/Makefile
@@ -9,6 +9,7 @@
 
 # LED Platform Drivers (keep this sorted, M-| sort)
 obj-$(CONFIG_LEDS_88PM860X)		+= leds-88pm860x.o
+obj-$(CONFIG_LEDS_AAEON)		+= leds-aaeon.o
 obj-$(CONFIG_LEDS_ACER_A500)		+= leds-acer-a500.o
 obj-$(CONFIG_LEDS_ADP5520)		+= leds-adp5520.o
 obj-$(CONFIG_LEDS_AN30259A)		+= leds-an30259a.o
--- linux-qcom-6.8.0.orig/drivers/leds/flash/leds-mt6360.c
+++ linux-qcom-6.8.0/drivers/leds/flash/leds-mt6360.c
@@ -633,14 +633,17 @@
 
 			ret = fwnode_property_read_u32(child, "reg", &reg);
 			if (ret || reg > MT6360_LED_ISNK3 ||
-			    priv->leds_active & BIT(reg))
+			    priv->leds_active & BIT(reg)) {
+				fwnode_handle_put(child);
 				return -EINVAL;
+			}
 
 			ret = fwnode_property_read_u32(child, "color", &color);
 			if (ret) {
 				dev_err(priv->dev,
 					"led %d, no color specified\n",
 					led->led_no);
+				fwnode_handle_put(child);
 				return ret;
 			}
 
@@ -771,7 +774,6 @@
 static int mt6360_led_probe(struct platform_device *pdev)
 {
 	struct mt6360_priv *priv;
-	struct fwnode_handle *child;
 	size_t count;
 	int i = 0, ret;
 
@@ -798,7 +800,7 @@
 		return -ENODEV;
 	}
 
-	device_for_each_child_node(&pdev->dev, child) {
+	device_for_each_child_node_scoped(&pdev->dev, child) {
 		struct mt6360_led *led = priv->leds + i;
 		struct led_init_data init_data = { .fwnode = child, };
 		u32 reg, led_color;
--- linux-qcom-6.8.0.orig/drivers/leds/flash/leds-qcom-flash.c
+++ linux-qcom-6.8.0/drivers/leds/flash/leds-qcom-flash.c
@@ -505,6 +505,7 @@
 	struct qcom_flash_data *flash_data = led->flash_data;
 	struct v4l2_flash_config v4l2_cfg = { 0 };
 	struct led_flash_setting *intensity = &v4l2_cfg.intensity;
+	struct v4l2_flash *v4l2_flash;
 
 	if (!(led->flash.led_cdev.flags & LED_DEV_CAP_FLASH))
 		return 0;
@@ -523,9 +524,12 @@
 				LED_FAULT_OVER_TEMPERATURE |
 				LED_FAULT_TIMEOUT;
 
-	flash_data->v4l2_flash[flash_data->leds_count] =
-		v4l2_flash_init(dev, fwnode, &led->flash, &qcom_v4l2_flash_ops, &v4l2_cfg);
-	return PTR_ERR_OR_ZERO(flash_data->v4l2_flash);
+	v4l2_flash = v4l2_flash_init(dev, fwnode, &led->flash, &qcom_v4l2_flash_ops, &v4l2_cfg);
+	if (IS_ERR(v4l2_flash))
+		return PTR_ERR(v4l2_flash);
+
+	flash_data->v4l2_flash[flash_data->leds_count] = v4l2_flash;
+	return 0;
 }
 # else
 static int
--- linux-qcom-6.8.0.orig/drivers/leds/flash/leds-sgm3140.c
+++ linux-qcom-6.8.0/drivers/leds/flash/leds-sgm3140.c
@@ -114,8 +114,11 @@
 				"failed to enable regulator: %d\n", ret);
 			return ret;
 		}
+		gpiod_set_value_cansleep(priv->flash_gpio, 0);
 		gpiod_set_value_cansleep(priv->enable_gpio, 1);
 	} else {
+		del_timer_sync(&priv->powerdown_timer);
+		gpiod_set_value_cansleep(priv->flash_gpio, 0);
 		gpiod_set_value_cansleep(priv->enable_gpio, 0);
 		ret = regulator_disable(priv->vin_regulator);
 		if (ret) {
--- linux-qcom-6.8.0.orig/drivers/leds/led-class.c
+++ linux-qcom-6.8.0/drivers/leds/led-class.c
@@ -29,11 +29,14 @@
 		struct device_attribute *attr, char *buf)
 {
 	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+	unsigned int brightness;
 
-	/* no lock needed for this */
+	mutex_lock(&led_cdev->led_access);
 	led_update_brightness(led_cdev);
+	brightness = led_cdev->brightness;
+	mutex_unlock(&led_cdev->led_access);
 
-	return sprintf(buf, "%u\n", led_cdev->brightness);
+	return sprintf(buf, "%u\n", brightness);
 }
 
 static ssize_t brightness_store(struct device *dev,
@@ -70,8 +73,13 @@
 		struct device_attribute *attr, char *buf)
 {
 	struct led_classdev *led_cdev = dev_get_drvdata(dev);
+	unsigned int max_brightness;
+
+	mutex_lock(&led_cdev->led_access);
+	max_brightness = led_cdev->max_brightness;
+	mutex_unlock(&led_cdev->led_access);
 
-	return sprintf(buf, "%u\n", led_cdev->max_brightness);
+	return sprintf(buf, "%u\n", max_brightness);
 }
 static DEVICE_ATTR_RO(max_brightness);
 
@@ -258,7 +266,6 @@
 
 	led_dev = class_find_device_by_of_node(&leds_class, led_node);
 	of_node_put(led_node);
-	put_device(led_dev);
 
 	return led_module_get(led_dev);
 }
--- linux-qcom-6.8.0.orig/drivers/leds/led-triggers.c
+++ linux-qcom-6.8.0/drivers/leds/led-triggers.c
@@ -179,9 +179,9 @@
 
 		cancel_work_sync(&led_cdev->set_brightness_work);
 		led_stop_software_blink(led_cdev);
+		device_remove_groups(led_cdev->dev, led_cdev->trigger->groups);
 		if (led_cdev->trigger->deactivate)
 			led_cdev->trigger->deactivate(led_cdev);
-		device_remove_groups(led_cdev->dev, led_cdev->trigger->groups);
 		led_cdev->trigger = NULL;
 		led_cdev->trigger_data = NULL;
 		led_cdev->activated = false;
@@ -194,11 +194,24 @@
 		spin_unlock(&trig->leddev_list_lock);
 		led_cdev->trigger = trig;
 
+		/*
+		 * If "set brightness to 0" is pending in workqueue,
+		 * we don't want that to be reordered after ->activate()
+		 */
+		flush_work(&led_cdev->set_brightness_work);
+
+		/*
+		 * Some activate() calls use led_trigger_event() to initialize
+		 * the brightness of the LED for which the trigger is being set.
+		 * Ensure the led_cdev is visible on trig->led_cdevs for this.
+		 */
+		synchronize_rcu();
+
+		ret = 0;
 		if (trig->activate)
 			ret = trig->activate(led_cdev);
 		else
-			ret = 0;
-
+			led_set_brightness(led_cdev, trig->brightness);
 		if (ret)
 			goto err_activate;
 
@@ -373,6 +386,8 @@
 	if (!trig)
 		return;
 
+	trig->brightness = brightness;
+
 	rcu_read_lock();
 	list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list)
 		led_set_brightness(led_cdev, brightness);
--- linux-qcom-6.8.0.orig/drivers/leds/leds-aaeon.c
+++ linux-qcom-6.8.0/drivers/leds/leds-aaeon.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * AAEON LED driver
+ *
+ * Copyright (c) 2021, AAEON Ltd.
+ *
+ * Author: Kunyang Fan <kunyang_fan@aaeon.com.tw>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/acpi.h>
+#include <linux/bitops.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/platform_data/x86/asus-wmi.h>
+#include <linux/platform_device.h>
+
+#define DRVNAME "led_aaeon"
+#define ASUS_NB_WMI_EVENT_GUID   "0B3CBB35-E3C2-45ED-91C2-4C5A6D195D1C"
+#define AAEON_WMI_MGMT_GUID      "97845ED0-4E6D-11DE-8A39-0800200C9A66"
+
+#define GET_LED_NUMBER_ID        0x00060000
+#define GET_LED_METHOD_ID        0x00060001
+#define SET_LED_METHOD_ID        0x00060002
+#define GET_LED_NUMBER_METHOD_ID 0x10
+
+
+struct aaeon_led_data {
+	int id;
+	struct led_classdev cdev;
+};
+
+static int aaeon_led_get_number(void)
+{
+	int err, retval;
+
+	err = asus_wmi_evaluate_method(GET_LED_NUMBER_ID,
+				       GET_LED_NUMBER_METHOD_ID,
+				       0, &retval);
+	if (err)
+		return err;
+
+	return retval;
+}
+
+static enum led_brightness aaeon_led_brightness_get(struct led_classdev
+						      *cdev)
+{
+	int err, brightness;
+	struct aaeon_led_data *led =
+			container_of(cdev, struct aaeon_led_data, cdev);
+	u32 arg0;
+
+	arg0 = (u32)(led->id & 0xF);
+	err = asus_wmi_evaluate_method(GET_LED_METHOD_ID, arg0, 0, &brightness);
+	if (err)
+		return err;
+
+	return brightness;
+};
+
+static void aaeon_led_brightness_set(struct led_classdev *cdev,
+				       enum led_brightness brightness)
+{
+	int err, retval;
+	struct aaeon_led_data *led =
+			container_of(cdev, struct aaeon_led_data, cdev);
+	u32 arg0;
+
+	arg0 = (u32)(led->id & 0xF);
+	if (brightness != LED_OFF)
+		arg0 |= BIT(16);
+
+	err = asus_wmi_evaluate_method(SET_LED_METHOD_ID, arg0, 0, &retval);
+};
+
+static int __init aaeon_add_led_device(struct platform_device *pdev,
+					   int id)
+{
+	struct aaeon_led_data *led;
+
+	led = devm_kzalloc(&pdev->dev, sizeof(struct aaeon_led_data), GFP_KERNEL);
+	if (!led)
+		return -ENOMEM;
+
+	led->id = id;
+	led->cdev.brightness_get = aaeon_led_brightness_get;
+	led->cdev.brightness_set = aaeon_led_brightness_set;
+	led->cdev.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "led:%d:", id);
+
+	if (!led->cdev.name)
+		return -ENOMEM;
+
+	return devm_led_classdev_register(&pdev->dev, &led->cdev);
+}
+
+static int aaeon_led_probe(struct platform_device *pdev)
+{
+	int err = -ENODEV, i;
+	int led_number = 0;
+
+	pr_debug("aaeon led device probe!\n");
+	/* Prevent other drivers adding this platfom device */
+	if (!wmi_has_guid(AAEON_WMI_MGMT_GUID)) {
+		pr_debug("AAEON Management GUID not found\n");
+		return -ENODEV;
+	}
+
+	/* Query the number of led devices board support */
+	led_number = aaeon_led_get_number();
+
+	/*
+	 * If the number is 0 or can't get the number of leds,
+	 * no need to register any led device node.
+	 */
+	if (led_number <= 0)
+		return -ENODEV;
+
+	for (i = 0; i < led_number; i++) {
+		err = aaeon_add_led_device(pdev, i);
+		if (err)
+			break;
+	}
+
+	return err;
+}
+
+static struct platform_driver aaeon_led_driver = {
+	.driver = {
+		.name = "leds-aaeon",
+	},
+};
+
+module_platform_driver_probe(aaeon_led_driver, aaeon_led_probe);
+
+MODULE_ALIAS("platform:leds-aaeon");
+MODULE_DESCRIPTION("AAEON LED Driver");
+MODULE_AUTHOR("Kunyang Fan <kunyang_fan@asus.com>");
+MODULE_LICENSE("GPL v2");
--- linux-qcom-6.8.0.orig/drivers/leds/leds-an30259a.c
+++ linux-qcom-6.8.0/drivers/leds/leds-an30259a.c
@@ -283,7 +283,10 @@
 	if (err < 0)
 		return err;
 
-	mutex_init(&chip->mutex);
+	err = devm_mutex_init(&client->dev, &chip->mutex);
+	if (err)
+		return err;
+
 	chip->client = client;
 	i2c_set_clientdata(client, chip);
 
@@ -317,17 +320,9 @@
 	return 0;
 
 exit:
-	mutex_destroy(&chip->mutex);
 	return err;
 }
 
-static void an30259a_remove(struct i2c_client *client)
-{
-	struct an30259a *chip = i2c_get_clientdata(client);
-
-	mutex_destroy(&chip->mutex);
-}
-
 static const struct of_device_id an30259a_match_table[] = {
 	{ .compatible = "panasonic,an30259a", },
 	{ /* sentinel */ },
@@ -347,7 +342,6 @@
 		.of_match_table = an30259a_match_table,
 	},
 	.probe = an30259a_probe,
-	.remove = an30259a_remove,
 	.id_table = an30259a_id,
 };
 
--- linux-qcom-6.8.0.orig/drivers/leds/leds-aw2013.c
+++ linux-qcom-6.8.0/drivers/leds/leds-aw2013.c
@@ -405,6 +405,7 @@
 			       chip->regulators);
 
 error:
+	mutex_unlock(&chip->mutex);
 	mutex_destroy(&chip->mutex);
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/leds/leds-bd2606mvv.c
+++ linux-qcom-6.8.0/drivers/leds/leds-bd2606mvv.c
@@ -69,16 +69,14 @@
 
 static int bd2606mvv_probe(struct i2c_client *client)
 {
-	struct fwnode_handle *np, *child;
 	struct device *dev = &client->dev;
 	struct bd2606mvv_priv *priv;
 	struct fwnode_handle *led_fwnodes[BD2606_MAX_LEDS] = { 0 };
 	int active_pairs[BD2606_MAX_LEDS / 2] = { 0 };
 	int err, reg;
-	int i;
+	int i, j;
 
-	np = dev_fwnode(dev);
-	if (!np)
+	if (!dev_fwnode(dev))
 		return -ENODEV;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -94,20 +92,18 @@
 
 	i2c_set_clientdata(client, priv);
 
-	fwnode_for_each_available_child_node(np, child) {
+	device_for_each_child_node_scoped(dev, child) {
 		struct bd2606mvv_led *led;
 
 		err = fwnode_property_read_u32(child, "reg", &reg);
-		if (err) {
-			fwnode_handle_put(child);
+		if (err)
 			return err;
-		}
-		if (reg < 0 || reg >= BD2606_MAX_LEDS || led_fwnodes[reg]) {
-			fwnode_handle_put(child);
+
+		if (reg < 0 || reg >= BD2606_MAX_LEDS || led_fwnodes[reg])
 			return -EINVAL;
-		}
+
 		led = &priv->leds[reg];
-		led_fwnodes[reg] = child;
+		led_fwnodes[reg] = fwnode_handle_get(child);
 		active_pairs[reg / 2]++;
 		led->priv = priv;
 		led->led_no = reg;
@@ -130,7 +126,8 @@
 						     &priv->leds[i].ldev,
 						     &init_data);
 		if (err < 0) {
-			fwnode_handle_put(child);
+			for (j = i; j < BD2606_MAX_LEDS; j++)
+				fwnode_handle_put(led_fwnodes[j]);
 			return dev_err_probe(dev, err,
 					     "couldn't register LED %s\n",
 					     priv->leds[i].ldev.name);
--- linux-qcom-6.8.0.orig/drivers/leds/leds-cht-wcove.c
+++ linux-qcom-6.8.0/drivers/leds/leds-cht-wcove.c
@@ -394,7 +394,7 @@
 		led->cdev.pattern_clear = cht_wc_leds_pattern_clear;
 		led->cdev.max_brightness = 255;
 
-		ret = led_classdev_register(&pdev->dev, &led->cdev);
+		ret = devm_led_classdev_register(&pdev->dev, &led->cdev);
 		if (ret < 0)
 			return ret;
 	}
@@ -406,10 +406,6 @@
 static void cht_wc_leds_remove(struct platform_device *pdev)
 {
 	struct cht_wc_leds *leds = platform_get_drvdata(pdev);
-	int i;
-
-	for (i = 0; i < CHT_WC_LED_COUNT; i++)
-		led_classdev_unregister(&leds->leds[i].cdev);
 
 	/* Restore LED1 regs if hw-control was active else leave LED1 off */
 	if (!(leds->led1_initial_regs.ctrl & CHT_WC_LED1_SWCTL))
--- linux-qcom-6.8.0.orig/drivers/leds/leds-gpio.c
+++ linux-qcom-6.8.0/drivers/leds/leds-gpio.c
@@ -150,7 +150,7 @@
 {
 	struct fwnode_handle *child;
 	struct gpio_leds_priv *priv;
-	int count, ret;
+	int count, used, ret;
 
 	count = device_get_child_node_count(dev);
 	if (!count)
@@ -159,9 +159,11 @@
 	priv = devm_kzalloc(dev, struct_size(priv, leds, count), GFP_KERNEL);
 	if (!priv)
 		return ERR_PTR(-ENOMEM);
+	priv->num_leds = count;
+	used = 0;
 
 	device_for_each_child_node(dev, child) {
-		struct gpio_led_data *led_dat = &priv->leds[priv->num_leds];
+		struct gpio_led_data *led_dat = &priv->leds[used];
 		struct gpio_led led = {};
 
 		/*
@@ -197,8 +199,9 @@
 		/* Set gpiod label to match the corresponding LED name. */
 		gpiod_set_consumer_name(led_dat->gpiod,
 					led_dat->cdev.dev->kobj.name);
-		priv->num_leds++;
+		used++;
 	}
+	priv->num_leds = used;
 
 	return priv;
 }
--- linux-qcom-6.8.0.orig/drivers/leds/leds-lp55xx-common.c
+++ linux-qcom-6.8.0/drivers/leds/leds-lp55xx-common.c
@@ -580,9 +580,6 @@
 	if (ret)
 		return ret;
 
-	if (*chan_nr < 0 || *chan_nr > cfg->max_channel)
-		return -EINVAL;
-
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/leds/leds-lp8860.c
+++ linux-qcom-6.8.0/drivers/leds/leds-lp8860.c
@@ -265,7 +265,7 @@
 		goto out;
 	}
 
-	reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs) / sizeof(lp8860_eeprom_disp_regs[0]);
+	reg_count = ARRAY_SIZE(lp8860_eeprom_disp_regs);
 	for (i = 0; i < reg_count; i++) {
 		ret = regmap_write(led->eeprom_regmap,
 				lp8860_eeprom_disp_regs[i].reg,
--- linux-qcom-6.8.0.orig/drivers/leds/leds-max5970.c
+++ linux-qcom-6.8.0/drivers/leds/leds-max5970.c
@@ -45,7 +45,7 @@
 
 static int max5970_led_probe(struct platform_device *pdev)
 {
-	struct fwnode_handle *led_node, *child;
+	struct fwnode_handle *child;
 	struct device *dev = &pdev->dev;
 	struct regmap *regmap;
 	struct max5970_led *ddata;
@@ -55,7 +55,8 @@
 	if (!regmap)
 		return -ENODEV;
 
-	led_node = device_get_named_child_node(dev->parent, "leds");
+	struct fwnode_handle *led_node __free(fwnode_handle) =
+		device_get_named_child_node(dev->parent, "leds");
 	if (!led_node)
 		return -ENODEV;
 
--- linux-qcom-6.8.0.orig/drivers/leds/leds-mlxreg.c
+++ linux-qcom-6.8.0/drivers/leds/leds-mlxreg.c
@@ -257,6 +257,7 @@
 {
 	struct mlxreg_core_platform_data *led_pdata;
 	struct mlxreg_led_priv_data *priv;
+	int err;
 
 	led_pdata = dev_get_platdata(&pdev->dev);
 	if (!led_pdata) {
@@ -268,26 +269,21 @@
 	if (!priv)
 		return -ENOMEM;
 
-	mutex_init(&priv->access_lock);
+	err = devm_mutex_init(&pdev->dev, &priv->access_lock);
+	if (err)
+		return err;
+
 	priv->pdev = pdev;
 	priv->pdata = led_pdata;
 
 	return mlxreg_led_config(priv);
 }
 
-static void mlxreg_led_remove(struct platform_device *pdev)
-{
-	struct mlxreg_led_priv_data *priv = dev_get_drvdata(&pdev->dev);
-
-	mutex_destroy(&priv->access_lock);
-}
-
 static struct platform_driver mlxreg_led_driver = {
 	.driver = {
 	    .name = "leds-mlxreg",
 	},
 	.probe = mlxreg_led_probe,
-	.remove_new = mlxreg_led_remove,
 };
 
 module_platform_driver(mlxreg_led_driver);
--- linux-qcom-6.8.0.orig/drivers/leds/leds-netxbig.c
+++ linux-qcom-6.8.0/drivers/leds/leds-netxbig.c
@@ -440,6 +440,7 @@
 	}
 	gpio_ext_pdev = of_find_device_by_node(gpio_ext_np);
 	if (!gpio_ext_pdev) {
+		of_node_put(gpio_ext_np);
 		dev_err(dev, "Failed to find platform device for gpio-ext\n");
 		return -ENODEV;
 	}
--- linux-qcom-6.8.0.orig/drivers/leds/leds-pca995x.c
+++ linux-qcom-6.8.0/drivers/leds/leds-pca995x.c
@@ -19,10 +19,6 @@
 #define PCA995X_MODE1			0x00
 #define PCA995X_MODE2			0x01
 #define PCA995X_LEDOUT0			0x02
-#define PCA9955B_PWM0			0x08
-#define PCA9952_PWM0			0x0A
-#define PCA9952_IREFALL			0x43
-#define PCA9955B_IREFALL		0x45
 
 /* Auto-increment disabled. Normal mode */
 #define PCA995X_MODE1_CFG		0x00
@@ -34,17 +30,38 @@
 #define PCA995X_LDRX_MASK		0x3
 #define PCA995X_LDRX_BITS		2
 
-#define PCA995X_MAX_OUTPUTS		16
+#define PCA995X_MAX_OUTPUTS		24
 #define PCA995X_OUTPUTS_PER_REG		4
 
 #define PCA995X_IREFALL_FULL_CFG	0xFF
 #define PCA995X_IREFALL_HALF_CFG	(PCA995X_IREFALL_FULL_CFG / 2)
 
-#define PCA995X_TYPE_NON_B		0
-#define PCA995X_TYPE_B			1
-
 #define ldev_to_led(c)	container_of(c, struct pca995x_led, ldev)
 
+struct pca995x_chipdef {
+	unsigned int num_leds;
+	u8 pwm_base;
+	u8 irefall;
+};
+
+static const struct pca995x_chipdef pca9952_chipdef = {
+	.num_leds	= 16,
+	.pwm_base	= 0x0a,
+	.irefall	= 0x43,
+};
+
+static const struct pca995x_chipdef pca9955b_chipdef = {
+	.num_leds	= 16,
+	.pwm_base	= 0x08,
+	.irefall	= 0x45,
+};
+
+static const struct pca995x_chipdef pca9956b_chipdef = {
+	.num_leds	= 24,
+	.pwm_base	= 0x0a,
+	.irefall	= 0x40,
+};
+
 struct pca995x_led {
 	unsigned int led_no;
 	struct led_classdev ldev;
@@ -54,7 +71,7 @@
 struct pca995x_chip {
 	struct regmap *regmap;
 	struct pca995x_led leds[PCA995X_MAX_OUTPUTS];
-	int btype;
+	const struct pca995x_chipdef *chipdef;
 };
 
 static int pca995x_brightness_set(struct led_classdev *led_cdev,
@@ -62,10 +79,11 @@
 {
 	struct pca995x_led *led = ldev_to_led(led_cdev);
 	struct pca995x_chip *chip = led->chip;
+	const struct pca995x_chipdef *chipdef = chip->chipdef;
 	u8 ledout_addr, pwmout_addr;
 	int shift, ret;
 
-	pwmout_addr = (chip->btype ? PCA9955B_PWM0 : PCA9952_PWM0) + led->led_no;
+	pwmout_addr = chipdef->pwm_base + led->led_no;
 	ledout_addr = PCA995X_LEDOUT0 + (led->led_no / PCA995X_OUTPUTS_PER_REG);
 	shift = PCA995X_LDRX_BITS * (led->led_no % PCA995X_OUTPUTS_PER_REG);
 
@@ -102,43 +120,38 @@
 static int pca995x_probe(struct i2c_client *client)
 {
 	struct fwnode_handle *led_fwnodes[PCA995X_MAX_OUTPUTS] = { 0 };
-	struct fwnode_handle *np, *child;
 	struct device *dev = &client->dev;
+	const struct pca995x_chipdef *chipdef;
 	struct pca995x_chip *chip;
 	struct pca995x_led *led;
-	int i, btype, reg, ret;
+	int i, j, reg, ret;
 
-	btype = (unsigned long)device_get_match_data(&client->dev);
+	chipdef = device_get_match_data(&client->dev);
 
-	np = dev_fwnode(dev);
-	if (!np)
+	if (!dev_fwnode(dev))
 		return -ENODEV;
 
 	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
 	if (!chip)
 		return -ENOMEM;
 
-	chip->btype = btype;
+	chip->chipdef = chipdef;
 	chip->regmap = devm_regmap_init_i2c(client, &pca995x_regmap);
 	if (IS_ERR(chip->regmap))
 		return PTR_ERR(chip->regmap);
 
 	i2c_set_clientdata(client, chip);
 
-	fwnode_for_each_available_child_node(np, child) {
+	device_for_each_child_node_scoped(dev, child) {
 		ret = fwnode_property_read_u32(child, "reg", &reg);
-		if (ret) {
-			fwnode_handle_put(child);
+		if (ret)
 			return ret;
-		}
 
-		if (reg < 0 || reg >= PCA995X_MAX_OUTPUTS || led_fwnodes[reg]) {
-			fwnode_handle_put(child);
+		if (reg < 0 || reg >= PCA995X_MAX_OUTPUTS || led_fwnodes[reg])
 			return -EINVAL;
-		}
 
 		led = &chip->leds[reg];
-		led_fwnodes[reg] = child;
+		led_fwnodes[reg] = fwnode_handle_get(child);
 		led->chip = chip;
 		led->led_no = reg;
 		led->ldev.brightness_set_blocking = pca995x_brightness_set;
@@ -157,7 +170,8 @@
 						     &chip->leds[i].ldev,
 						     &init_data);
 		if (ret < 0) {
-			fwnode_handle_put(child);
+			for (j = i; j < PCA995X_MAX_OUTPUTS; j++)
+				fwnode_handle_put(led_fwnodes[j]);
 			return dev_err_probe(dev, ret,
 					     "Could not register LED %s\n",
 					     chip->leds[i].ldev.name);
@@ -170,21 +184,21 @@
 		return ret;
 
 	/* IREF Output current value for all LEDn outputs */
-	return regmap_write(chip->regmap,
-			    btype ? PCA9955B_IREFALL : PCA9952_IREFALL,
-			    PCA995X_IREFALL_HALF_CFG);
+	return regmap_write(chip->regmap, chipdef->irefall, PCA995X_IREFALL_HALF_CFG);
 }
 
 static const struct i2c_device_id pca995x_id[] = {
-	{ "pca9952", .driver_data = (kernel_ulong_t)PCA995X_TYPE_NON_B },
-	{ "pca9955b", .driver_data = (kernel_ulong_t)PCA995X_TYPE_B },
+	{ "pca9952", .driver_data = (kernel_ulong_t)&pca9952_chipdef },
+	{ "pca9955b", .driver_data = (kernel_ulong_t)&pca9955b_chipdef },
+	{ "pca9956b", .driver_data = (kernel_ulong_t)&pca9956b_chipdef },
 	{}
 };
 MODULE_DEVICE_TABLE(i2c, pca995x_id);
 
 static const struct of_device_id pca995x_of_match[] = {
-	{ .compatible = "nxp,pca9952",  .data = (void *)PCA995X_TYPE_NON_B },
-	{ .compatible = "nxp,pca9955b", .data = (void *)PCA995X_TYPE_B },
+	{ .compatible = "nxp,pca9952", .data = &pca9952_chipdef },
+	{ .compatible = "nxp,pca9955b", . data = &pca9955b_chipdef },
+	{ .compatible = "nxp,pca9956b", .data = &pca9956b_chipdef },
 	{},
 };
 MODULE_DEVICE_TABLE(of, pca995x_of_match);
--- linux-qcom-6.8.0.orig/drivers/leds/leds-pwm.c
+++ linux-qcom-6.8.0/drivers/leds/leds-pwm.c
@@ -53,7 +53,13 @@
 		duty = led_dat->pwmstate.period - duty;
 
 	led_dat->pwmstate.duty_cycle = duty;
-	led_dat->pwmstate.enabled = true;
+	/*
+	 * Disabling a PWM doesn't guarantee that it emits the inactive level.
+	 * So keep it on. Only for suspending the PWM should be disabled because
+	 * otherwise it refuses to suspend. The possible downside is that the
+	 * LED might stay (or even go) on.
+	 */
+	led_dat->pwmstate.enabled = !(led_cdev->flags & LED_SUSPENDED);
 	return pwm_apply_might_sleep(led_dat->pwm, &led_dat->pwmstate);
 }
 
--- linux-qcom-6.8.0.orig/drivers/leds/leds-spi-byte.c
+++ linux-qcom-6.8.0/drivers/leds/leds-spi-byte.c
@@ -91,7 +91,6 @@
 		dev_err(dev, "Device must have exactly one LED sub-node.");
 		return -EINVAL;
 	}
-	child = of_get_next_available_child(dev_of_node(dev), NULL);
 
 	led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
 	if (!led)
@@ -107,11 +106,13 @@
 	led->ldev.max_brightness = led->cdef->max_value - led->cdef->off_value;
 	led->ldev.brightness_set_blocking = spi_byte_brightness_set_blocking;
 
+	child = of_get_next_available_child(dev_of_node(dev), NULL);
 	state = of_get_property(child, "default-state", NULL);
 	if (state) {
 		if (!strcmp(state, "on")) {
 			led->ldev.brightness = led->ldev.max_brightness;
 		} else if (strcmp(state, "off")) {
+			of_node_put(child);
 			/* all other cases except "off" */
 			dev_err(dev, "default-state can only be 'on' or 'off'");
 			return -EINVAL;
@@ -122,9 +123,12 @@
 
 	ret = devm_led_classdev_register(&spi->dev, &led->ldev);
 	if (ret) {
+		of_node_put(child);
 		mutex_destroy(&led->mutex);
 		return ret;
 	}
+
+	of_node_put(child);
 	spi_set_drvdata(spi, led);
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/leds/leds-ss4200.c
+++ linux-qcom-6.8.0/drivers/leds/leds-ss4200.c
@@ -356,8 +356,10 @@
 
 	nas_gpio_pci_dev = dev;
 	status = pci_read_config_dword(dev, PMBASE, &g_pm_io_base);
-	if (status)
+	if (status) {
+		status = pcibios_err_to_errno(status);
 		goto out;
+	}
 	g_pm_io_base &= 0x00000ff80;
 
 	status = pci_read_config_dword(dev, GPIO_CTRL, &gc);
@@ -369,8 +371,9 @@
 	}
 
 	status = pci_read_config_dword(dev, GPIO_BASE, &nas_gpio_io_base);
-	if (0 > status) {
+	if (status) {
 		dev_info(&dev->dev, "Unable to read GPIOBASE.\n");
+		status = pcibios_err_to_errno(status);
 		goto out;
 	}
 	dev_dbg(&dev->dev, ": GPIOBASE = 0x%08x\n", nas_gpio_io_base);
--- linux-qcom-6.8.0.orig/drivers/leds/trigger/ledtrig-netdev.c
+++ linux-qcom-6.8.0/drivers/leds/trigger/ledtrig-netdev.c
@@ -504,12 +504,12 @@
 	trigger_data->duplex = DUPLEX_UNKNOWN;
 	switch (evt) {
 	case NETDEV_CHANGENAME:
-		get_device_state(trigger_data);
-		fallthrough;
 	case NETDEV_REGISTER:
 		dev_put(trigger_data->net_dev);
 		dev_hold(dev);
 		trigger_data->net_dev = dev;
+		if (evt == NETDEV_CHANGENAME)
+			get_device_state(trigger_data);
 		break;
 	case NETDEV_UNREGISTER:
 		dev_put(trigger_data->net_dev);
--- linux-qcom-6.8.0.orig/drivers/leds/trigger/ledtrig-timer.c
+++ linux-qcom-6.8.0/drivers/leds/trigger/ledtrig-timer.c
@@ -110,11 +110,6 @@
 		led_cdev->flags &= ~LED_INIT_DEFAULT_TRIGGER;
 	}
 
-	/*
-	 * If "set brightness to 0" is pending in workqueue, we don't
-	 * want that to be reordered after blink_set()
-	 */
-	flush_work(&led_cdev->set_brightness_work);
 	led_blink_set(led_cdev, &led_cdev->blink_delay_on,
 		      &led_cdev->blink_delay_off);
 
--- linux-qcom-6.8.0.orig/drivers/macintosh/therm_windtunnel.c
+++ linux-qcom-6.8.0/drivers/macintosh/therm_windtunnel.c
@@ -551,7 +551,7 @@
 	platform_driver_unregister( &therm_of_driver );
 
 	if( x.of_dev )
-		of_device_unregister( x.of_dev );
+		of_platform_device_destroy(&x.of_dev->dev, NULL);
 }
 
 module_init(g4fan_init);
--- linux-qcom-6.8.0.orig/drivers/macintosh/via-macii.c
+++ linux-qcom-6.8.0/drivers/macintosh/via-macii.c
@@ -140,24 +140,19 @@
 /* Initialize the driver */
 static int macii_init(void)
 {
-	unsigned long flags;
 	int err;
 
-	local_irq_save(flags);
-
 	err = macii_init_via();
 	if (err)
-		goto out;
+		return err;
 
 	err = request_irq(IRQ_MAC_ADB, macii_interrupt, 0, "ADB",
 			  macii_interrupt);
 	if (err)
-		goto out;
+		return err;
 
 	macii_state = idle;
-out:
-	local_irq_restore(flags);
-	return err;
+	return 0;
 }
 
 /* initialize the hardware */
--- linux-qcom-6.8.0.orig/drivers/mailbox/Kconfig
+++ linux-qcom-6.8.0/drivers/mailbox/Kconfig
@@ -273,6 +273,14 @@
 	  to send message between application processors and MCU. Say Y here if
 	  you want to build the Spreatrum mailbox controller driver.
 
+config QCOM_CPUCP_MBOX
+	tristate "Qualcomm Technologies, Inc. CPUCP mailbox driver"
+	depends on ARCH_QCOM || (COMPILE_TEST && 64BIT)
+	help
+	  Qualcomm Technologies, Inc. CPUSS Control Processor (CPUCP) mailbox
+	  controller driver enables communication between AP and CPUCP. Say
+	  Y here if you want to build this driver.
+
 config QCOM_IPCC
 	tristate "Qualcomm Technologies, Inc. IPCC driver"
 	depends on ARCH_QCOM || COMPILE_TEST
--- linux-qcom-6.8.0.orig/drivers/mailbox/Makefile
+++ linux-qcom-6.8.0/drivers/mailbox/Makefile
@@ -55,8 +55,12 @@
 
 obj-$(CONFIG_ZYNQMP_IPI_MBOX)	+= zynqmp-ipi-mailbox.o
 
+obj-$(CONFIG_GUNYAH)		+= gunyah-msgq.o
+
 obj-$(CONFIG_SUN6I_MSGBOX)	+= sun6i-msgbox.o
 
 obj-$(CONFIG_SPRD_MBOX)		+= sprd-mailbox.o
 
+obj-$(CONFIG_QCOM_CPUCP_MBOX)	+= qcom-cpucp-mbox.o
+
 obj-$(CONFIG_QCOM_IPCC)		+= qcom-ipcc.o
--- linux-qcom-6.8.0.orig/drivers/mailbox/arm_mhuv2.c
+++ linux-qcom-6.8.0/drivers/mailbox/arm_mhuv2.c
@@ -500,7 +500,7 @@
 static struct mbox_chan *get_irq_chan_comb(struct mhuv2 *mhu, u32 __iomem *reg)
 {
 	struct mbox_chan *chans = mhu->mbox.chans;
-	int channel = 0, i, offset = 0, windows, protocol, ch_wn;
+	int channel = 0, i, j, offset = 0, windows, protocol, ch_wn;
 	u32 stat;
 
 	for (i = 0; i < MHUV2_CMB_INT_ST_REG_CNT; i++) {
@@ -510,9 +510,9 @@
 
 		ch_wn = i * MHUV2_STAT_BITS + __builtin_ctz(stat);
 
-		for (i = 0; i < mhu->length; i += 2) {
-			protocol = mhu->protocols[i];
-			windows = mhu->protocols[i + 1];
+		for (j = 0; j < mhu->length; j += 2) {
+			protocol = mhu->protocols[j];
+			windows = mhu->protocols[j + 1];
 
 			if (ch_wn >= offset + windows) {
 				if (protocol == DOORBELL)
--- linux-qcom-6.8.0.orig/drivers/mailbox/bcm2835-mailbox.c
+++ linux-qcom-6.8.0/drivers/mailbox/bcm2835-mailbox.c
@@ -145,7 +145,8 @@
 	spin_lock_init(&mbox->lock);
 
 	ret = devm_request_irq(dev, irq_of_parse_and_map(dev->of_node, 0),
-			       bcm2835_mbox_irq, 0, dev_name(dev), mbox);
+			       bcm2835_mbox_irq, IRQF_NO_SUSPEND, dev_name(dev),
+			       mbox);
 	if (ret) {
 		dev_err(dev, "Failed to register a mailbox IRQ handler: %d\n",
 			ret);
--- linux-qcom-6.8.0.orig/drivers/mailbox/gunyah-msgq.c
+++ linux-qcom-6.8.0/drivers/mailbox/gunyah-msgq.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/gunyah.h>
+#include <linux/printk.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/wait.h>
+
+#define mbox_chan_to_msgq(chan) (container_of(chan->mbox, struct gh_msgq, mbox))
+
+static irqreturn_t gh_msgq_rx_irq_handler(int irq, void *data)
+{
+	struct gh_msgq *msgq = data;
+	struct gh_msgq_rx_data rx_data;
+	enum gh_error gh_error;
+	bool ready = true;
+
+	while (ready) {
+		gh_error = gh_hypercall_msgq_recv(msgq->rx_ghrsc->capid,
+				&rx_data.data, sizeof(rx_data.data),
+				&rx_data.length, &ready);
+		if (gh_error != GH_ERROR_OK) {
+			if (gh_error != GH_ERROR_MSGQUEUE_EMPTY)
+				dev_warn(msgq->mbox.dev, "Failed to receive data: %d\n", gh_error);
+			break;
+		}
+		if (likely(gh_msgq_chan(msgq)->cl))
+			mbox_chan_received_data(gh_msgq_chan(msgq), &rx_data);
+	}
+
+	return IRQ_HANDLED;
+}
+
+/* Fired when message queue transitions from "full" to "space available" to send messages */
+static irqreturn_t gh_msgq_tx_irq_handler(int irq, void *data)
+{
+	struct gh_msgq *msgq = data;
+
+	mbox_chan_txdone(gh_msgq_chan(msgq), 0);
+
+	return IRQ_HANDLED;
+}
+
+/* Fired after sending message and hypercall told us there was more space available. */
+static void gh_msgq_txdone_tasklet(struct tasklet_struct *tasklet)
+{
+	struct gh_msgq *msgq = container_of(tasklet, struct gh_msgq, txdone_tasklet);
+
+	mbox_chan_txdone(gh_msgq_chan(msgq), msgq->last_ret);
+}
+
+static int gh_msgq_send_data(struct mbox_chan *chan, void *data)
+{
+	struct gh_msgq *msgq = mbox_chan_to_msgq(chan);
+	struct gh_msgq_tx_data *msgq_data = data;
+	u64 tx_flags = 0;
+	enum gh_error gh_error;
+	bool ready;
+
+	if (!msgq->tx_ghrsc)
+		return -EOPNOTSUPP;
+
+	if (msgq_data->push)
+		tx_flags |= GH_HYPERCALL_MSGQ_TX_FLAGS_PUSH;
+
+	gh_error = gh_hypercall_msgq_send(msgq->tx_ghrsc->capid, msgq_data->length, msgq_data->data,
+						tx_flags, &ready);
+
+	/**
+	 * unlikely because Linux tracks state of msgq and should not try to
+	 * send message when msgq is full.
+	 */
+	if (unlikely(gh_error == GH_ERROR_MSGQUEUE_FULL))
+		return -EAGAIN;
+
+	/**
+	 * Propagate all other errors to client. If we return error to mailbox
+	 * framework, then no other messages can be sent and nobody will know
+	 * to retry this message.
+	 */
+	msgq->last_ret = gh_error_remap(gh_error);
+
+	/**
+	 * This message was successfully sent, but message queue isn't ready to
+	 * accept more messages because it's now full. Mailbox framework
+	 * requires that we only report that message was transmitted when
+	 * we're ready to transmit another message. We'll get that in the form
+	 * of tx IRQ once the other side starts to drain the msgq.
+	 */
+	if (gh_error == GH_ERROR_OK) {
+		if (!ready)
+			return 0;
+	} else {
+		dev_err(msgq->mbox.dev, "Failed to send data: %d (%d)\n", gh_error, msgq->last_ret);
+	}
+
+	/**
+	 * We can send more messages. Mailbox framework requires that tx done
+	 * happens asynchronously to sending the message. Gunyah message queues
+	 * tell us right away on the hypercall return whether we can send more
+	 * messages. To work around this, defer the txdone to a tasklet.
+	 */
+	tasklet_schedule(&msgq->txdone_tasklet);
+
+	return 0;
+}
+
+static struct mbox_chan_ops gh_msgq_ops = {
+	.send_data = gh_msgq_send_data,
+};
+
+/**
+ * gh_msgq_init() - Initialize a Gunyah message queue with an mbox_client
+ * @parent: device parent used for the mailbox controller
+ * @msgq: Pointer to the gh_msgq to initialize
+ * @cl: A mailbox client to bind to the mailbox channel that the message queue creates
+ * @tx_ghrsc: optional, the transmission side of the message queue
+ * @rx_ghrsc: optional, the receiving side of the message queue
+ *
+ * At least one of tx_ghrsc and rx_ghrsc must be not NULL. Most message queue use cases come with
+ * a pair of message queues to facilitate bidirectional communication. When tx_ghrsc is set,
+ * the client can send messages with mbox_send_message(gh_msgq_chan(msgq), msg). When rx_ghrsc
+ * is set, the mbox_client must register an .rx_callback() and the message queue driver will
+ * deliver all available messages upon receiving the RX ready interrupt. The messages should be
+ * consumed or copied by the client right away as the gh_msgq_rx_data will be replaced/destroyed
+ * after the callback.
+ *
+ * Returns - 0 on success, negative otherwise
+ */
+int gh_msgq_init(struct device *parent, struct gh_msgq *msgq, struct mbox_client *cl,
+		 struct gh_resource *tx_ghrsc, struct gh_resource *rx_ghrsc)
+{
+	int ret;
+
+	/* Must have at least a tx_ghrsc or rx_ghrsc and that they are the right device types */
+	if ((!tx_ghrsc && !rx_ghrsc) ||
+	    (tx_ghrsc && tx_ghrsc->type != GH_RESOURCE_TYPE_MSGQ_TX) ||
+	    (rx_ghrsc && rx_ghrsc->type != GH_RESOURCE_TYPE_MSGQ_RX))
+		return -EINVAL;
+
+	msgq->mbox.dev = parent;
+	msgq->mbox.ops = &gh_msgq_ops;
+	msgq->mbox.num_chans = 1;
+	msgq->mbox.txdone_irq = true;
+	msgq->mbox.chans = &msgq->mbox_chan;
+
+	ret = mbox_controller_register(&msgq->mbox);
+	if (ret)
+		return ret;
+
+	ret = mbox_bind_client(gh_msgq_chan(msgq), cl);
+	if (ret)
+		goto err_mbox;
+
+	if (tx_ghrsc) {
+		msgq->tx_ghrsc = tx_ghrsc;
+
+		ret = request_irq(msgq->tx_ghrsc->irq, gh_msgq_tx_irq_handler, 0, "gh_msgq_tx",
+				msgq);
+		if (ret)
+			goto err_tx_ghrsc;
+
+		enable_irq_wake(msgq->tx_ghrsc->irq);
+
+		tasklet_setup(&msgq->txdone_tasklet, gh_msgq_txdone_tasklet);
+	}
+
+	if (rx_ghrsc) {
+		msgq->rx_ghrsc = rx_ghrsc;
+
+		ret = request_threaded_irq(msgq->rx_ghrsc->irq, NULL, gh_msgq_rx_irq_handler,
+						IRQF_ONESHOT, "gh_msgq_rx", msgq);
+		if (ret)
+			goto err_tx_irq;
+
+		enable_irq_wake(msgq->rx_ghrsc->irq);
+	}
+
+	return 0;
+err_tx_irq:
+	if (msgq->tx_ghrsc)
+		free_irq(msgq->tx_ghrsc->irq, msgq);
+
+	msgq->rx_ghrsc = NULL;
+err_tx_ghrsc:
+	msgq->tx_ghrsc = NULL;
+err_mbox:
+	mbox_controller_unregister(&msgq->mbox);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(gh_msgq_init);
+
+void gh_msgq_remove(struct gh_msgq *msgq)
+{
+	mbox_free_channel(gh_msgq_chan(msgq));
+
+	if (msgq->rx_ghrsc)
+		free_irq(msgq->rx_ghrsc->irq, msgq);
+
+	if (msgq->tx_ghrsc) {
+		tasklet_kill(&msgq->txdone_tasklet);
+		free_irq(msgq->tx_ghrsc->irq, msgq);
+	}
+
+	mbox_controller_unregister(&msgq->mbox);
+
+	msgq->rx_ghrsc = NULL;
+	msgq->tx_ghrsc = NULL;
+}
+EXPORT_SYMBOL_GPL(gh_msgq_remove);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Gunyah Message Queue Driver");
--- linux-qcom-6.8.0.orig/drivers/mailbox/imx-mailbox.c
+++ linux-qcom-6.8.0/drivers/mailbox/imx-mailbox.c
@@ -219,6 +219,8 @@
 			     void *data)
 {
 	u32 *arg = data;
+	u32 val;
+	int ret;
 
 	switch (cp->type) {
 	case IMX_MU_TYPE_TX:
@@ -230,7 +232,13 @@
 		tasklet_schedule(&cp->txdb_tasklet);
 		break;
 	case IMX_MU_TYPE_TXDB_V2:
-		imx_mu_xcr_rmw(priv, IMX_MU_GCR, IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx), 0);
+		imx_mu_write(priv, IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx),
+			     priv->dcfg->xCR[IMX_MU_GCR]);
+		ret = readl_poll_timeout(priv->base + priv->dcfg->xCR[IMX_MU_GCR], val,
+					 !(val & IMX_MU_xCR_GIRn(priv->dcfg->type, cp->idx)),
+					 0, 1000);
+		if (ret)
+			dev_warn_ratelimited(priv->dev, "channel type: %d failure\n", cp->type);
 		break;
 	default:
 		dev_warn_ratelimited(priv->dev, "Send data on wrong channel type: %d\n", cp->type);
--- linux-qcom-6.8.0.orig/drivers/mailbox/mtk-cmdq-mailbox.c
+++ linux-qcom-6.8.0/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -465,7 +465,7 @@
 	struct cmdq_task *task, *tmp;
 	unsigned long flags;
 
-	WARN_ON(pm_runtime_get_sync(cmdq->mbox.dev));
+	WARN_ON(pm_runtime_get_sync(cmdq->mbox.dev) < 0);
 
 	spin_lock_irqsave(&thread->chan->lock, flags);
 	if (list_empty(&thread->task_busy_list))
@@ -662,12 +662,6 @@
 		cmdq->mbox.chans[i].con_priv = (void *)&cmdq->thread[i];
 	}
 
-	err = devm_mbox_controller_register(dev, &cmdq->mbox);
-	if (err < 0) {
-		dev_err(dev, "failed to register mailbox: %d\n", err);
-		return err;
-	}
-
 	platform_set_drvdata(pdev, cmdq);
 
 	WARN_ON(clk_bulk_prepare(cmdq->pdata->gce_num, cmdq->clocks));
@@ -695,6 +689,12 @@
 	pm_runtime_set_autosuspend_delay(dev, CMDQ_MBOX_AUTOSUSPEND_DELAY_MS);
 	pm_runtime_use_autosuspend(dev);
 
+	err = devm_mbox_controller_register(dev, &cmdq->mbox);
+	if (err < 0) {
+		dev_err(dev, "failed to register mailbox: %d\n", err);
+		return err;
+	}
+
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/mailbox/pcc.c
+++ linux-qcom-6.8.0/drivers/mailbox/pcc.c
@@ -269,6 +269,35 @@
 	return !!val;
 }
 
+static void check_and_ack(struct pcc_chan_info *pchan, struct mbox_chan *chan)
+{
+	struct acpi_pcct_ext_pcc_shared_memory pcc_hdr;
+
+	if (pchan->type != ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
+		return;
+	/* If the memory region has not been mapped, we cannot
+	 * determine if we need to send the message, but we still
+	 * need to set the cmd_update flag before returning.
+	 */
+	if (pchan->chan.shmem == NULL) {
+		pcc_chan_reg_read_modify_write(&pchan->cmd_update);
+		return;
+	}
+	memcpy_fromio(&pcc_hdr, pchan->chan.shmem,
+		      sizeof(struct acpi_pcct_ext_pcc_shared_memory));
+	/*
+	 * The PCC slave subspace channel needs to set the command complete bit
+	 * after processing message. If the PCC_ACK_FLAG is set, it should also
+	 * ring the doorbell.
+	 *
+	 * The PCC master subspace channel clears chan_in_use to free channel.
+	 */
+	if (le32_to_cpup(&pcc_hdr.flags) & PCC_ACK_FLAG_MASK)
+		pcc_send_data(chan, NULL);
+	else
+		pcc_chan_reg_read_modify_write(&pchan->cmd_update);
+}
+
 /**
  * pcc_mbox_irq - PCC mailbox interrupt handler
  * @irq:	interrupt number
@@ -306,14 +335,7 @@
 
 	mbox_chan_received_data(chan, NULL);
 
-	/*
-	 * The PCC slave subspace channel needs to set the command complete bit
-	 * and ring doorbell after processing message.
-	 *
-	 * The PCC master subspace channel clears chan_in_use to free channel.
-	 */
-	if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE)
-		pcc_send_data(chan, NULL);
+	check_and_ack(pchan, chan);
 	pchan->chan_in_use = false;
 
 	return IRQ_HANDLED;
@@ -365,14 +387,37 @@
 void pcc_mbox_free_channel(struct pcc_mbox_chan *pchan)
 {
 	struct mbox_chan *chan = pchan->mchan;
+	struct pcc_chan_info *pchan_info;
+	struct pcc_mbox_chan *pcc_mbox_chan;
 
 	if (!chan || !chan->cl)
 		return;
+	pchan_info = chan->con_priv;
+	pcc_mbox_chan = &pchan_info->chan;
+	if (pcc_mbox_chan->shmem) {
+		iounmap(pcc_mbox_chan->shmem);
+		pcc_mbox_chan->shmem = NULL;
+	}
 
 	mbox_free_channel(chan);
 }
 EXPORT_SYMBOL_GPL(pcc_mbox_free_channel);
 
+int pcc_mbox_ioremap(struct mbox_chan *chan)
+{
+	struct pcc_chan_info *pchan_info;
+	struct pcc_mbox_chan *pcc_mbox_chan;
+
+	if (!chan || !chan->cl)
+		return -1;
+	pchan_info = chan->con_priv;
+	pcc_mbox_chan = &pchan_info->chan;
+	pcc_mbox_chan->shmem = ioremap(pcc_mbox_chan->shmem_base_addr,
+				       pcc_mbox_chan->shmem_size);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pcc_mbox_ioremap);
+
 /**
  * pcc_send_data - Called from Mailbox Controller code. Used
  *		here only to ring the channel doorbell. The PCC client
--- linux-qcom-6.8.0.orig/drivers/mailbox/qcom-cpucp-mbox.c
+++ linux-qcom-6.8.0/drivers/mailbox/qcom-cpucp-mbox.c
@@ -0,0 +1,187 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#define APSS_CPUCP_IPC_CHAN_SUPPORTED		3
+#define APSS_CPUCP_MBOX_CMD_OFF			0x4
+
+/* Tx Registers */
+#define APSS_CPUCP_TX_MBOX_CMD(i)		(0x100 + ((i) * 8))
+
+/* Rx Registers */
+#define APSS_CPUCP_RX_MBOX_CMD(i)		(0x100 + ((i) * 8))
+#define APSS_CPUCP_RX_MBOX_MAP			0x4000
+#define APSS_CPUCP_RX_MBOX_STAT			0x4400
+#define APSS_CPUCP_RX_MBOX_CLEAR		0x4800
+#define APSS_CPUCP_RX_MBOX_EN			0x4c00
+#define APSS_CPUCP_RX_MBOX_CMD_MASK		GENMASK_ULL(63, 0)
+
+/**
+ * struct qcom_cpucp_mbox - Holder for the mailbox driver
+ * @chans:			The mailbox channel
+ * @mbox:			The mailbox controller
+ * @tx_base:			Base address of the CPUCP tx registers
+ * @rx_base:			Base address of the CPUCP rx registers
+ */
+struct qcom_cpucp_mbox {
+	struct mbox_chan chans[APSS_CPUCP_IPC_CHAN_SUPPORTED];
+	struct mbox_controller mbox;
+	void __iomem *tx_base;
+	void __iomem *rx_base;
+};
+
+static inline int channel_number(struct mbox_chan *chan)
+{
+	return chan - chan->mbox->chans;
+}
+
+static irqreturn_t qcom_cpucp_mbox_irq_fn(int irq, void *data)
+{
+	struct qcom_cpucp_mbox *cpucp = data;
+	u64 status;
+	int i;
+
+	status = readq(cpucp->rx_base + APSS_CPUCP_RX_MBOX_STAT);
+
+	for_each_set_bit(i, (unsigned long *)&status, APSS_CPUCP_IPC_CHAN_SUPPORTED) {
+		u32 val = readl(cpucp->rx_base + APSS_CPUCP_RX_MBOX_CMD(i) + APSS_CPUCP_MBOX_CMD_OFF);
+		struct mbox_chan *chan = &cpucp->chans[i];
+		unsigned long flags;
+
+		/* Provide mutual exclusion with changes to chan->cl */
+		spin_lock_irqsave(&chan->lock, flags);
+		if (chan->cl)
+			mbox_chan_received_data(chan, &val);
+		writeq(BIT(i), cpucp->rx_base + APSS_CPUCP_RX_MBOX_CLEAR);
+		spin_unlock_irqrestore(&chan->lock, flags);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int qcom_cpucp_mbox_startup(struct mbox_chan *chan)
+{
+	struct qcom_cpucp_mbox *cpucp = container_of(chan->mbox, struct qcom_cpucp_mbox, mbox);
+	unsigned long chan_id = channel_number(chan);
+	u64 val;
+
+	val = readq(cpucp->rx_base + APSS_CPUCP_RX_MBOX_EN);
+	val |= BIT(chan_id);
+	writeq(val, cpucp->rx_base + APSS_CPUCP_RX_MBOX_EN);
+
+	return 0;
+}
+
+static void qcom_cpucp_mbox_shutdown(struct mbox_chan *chan)
+{
+	struct qcom_cpucp_mbox *cpucp = container_of(chan->mbox, struct qcom_cpucp_mbox, mbox);
+	unsigned long chan_id = channel_number(chan);
+	u64 val;
+
+	val = readq(cpucp->rx_base + APSS_CPUCP_RX_MBOX_EN);
+	val &= ~BIT(chan_id);
+	writeq(val, cpucp->rx_base + APSS_CPUCP_RX_MBOX_EN);
+}
+
+static int qcom_cpucp_mbox_send_data(struct mbox_chan *chan, void *data)
+{
+	struct qcom_cpucp_mbox *cpucp = container_of(chan->mbox, struct qcom_cpucp_mbox, mbox);
+	unsigned long chan_id = channel_number(chan);
+	u32 *val = data;
+
+	writel(*val, cpucp->tx_base + APSS_CPUCP_TX_MBOX_CMD(chan_id) + APSS_CPUCP_MBOX_CMD_OFF);
+
+	return 0;
+}
+
+static const struct mbox_chan_ops qcom_cpucp_mbox_chan_ops = {
+	.startup = qcom_cpucp_mbox_startup,
+	.send_data = qcom_cpucp_mbox_send_data,
+	.shutdown = qcom_cpucp_mbox_shutdown
+};
+
+static int qcom_cpucp_mbox_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct qcom_cpucp_mbox *cpucp;
+	struct mbox_controller *mbox;
+	int irq, ret;
+
+	cpucp = devm_kzalloc(dev, sizeof(*cpucp), GFP_KERNEL);
+	if (!cpucp)
+		return -ENOMEM;
+
+	cpucp->rx_base = devm_of_iomap(dev, dev->of_node, 0, NULL);
+	if (IS_ERR(cpucp->rx_base))
+		return PTR_ERR(cpucp->rx_base);
+
+	cpucp->tx_base = devm_of_iomap(dev, dev->of_node, 1, NULL);
+	if (IS_ERR(cpucp->tx_base))
+		return PTR_ERR(cpucp->tx_base);
+
+	writeq(0, cpucp->rx_base + APSS_CPUCP_RX_MBOX_EN);
+	writeq(0, cpucp->rx_base + APSS_CPUCP_RX_MBOX_CLEAR);
+	writeq(0, cpucp->rx_base + APSS_CPUCP_RX_MBOX_MAP);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	ret = devm_request_irq(dev, irq, qcom_cpucp_mbox_irq_fn,
+			       IRQF_TRIGGER_HIGH, "apss_cpucp_mbox", cpucp);
+	if (ret < 0)
+		return dev_err_probe(dev, ret, "Failed to register irq: %d\n", irq);
+
+	writeq(APSS_CPUCP_RX_MBOX_CMD_MASK, cpucp->rx_base + APSS_CPUCP_RX_MBOX_MAP);
+
+	mbox = &cpucp->mbox;
+	mbox->dev = dev;
+	mbox->num_chans = APSS_CPUCP_IPC_CHAN_SUPPORTED;
+	mbox->chans = cpucp->chans;
+	mbox->ops = &qcom_cpucp_mbox_chan_ops;
+
+	ret = devm_mbox_controller_register(dev, mbox);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to create mailbox\n");
+
+	return 0;
+}
+
+static const struct of_device_id qcom_cpucp_mbox_of_match[] = {
+	{ .compatible = "qcom,x1e80100-cpucp-mbox" },
+	{}
+};
+MODULE_DEVICE_TABLE(of, qcom_cpucp_mbox_of_match);
+
+static struct platform_driver qcom_cpucp_mbox_driver = {
+	.probe = qcom_cpucp_mbox_probe,
+	.driver = {
+		.name = "qcom_cpucp_mbox",
+		.of_match_table = qcom_cpucp_mbox_of_match,
+	},
+};
+
+static int __init qcom_cpucp_mbox_init(void)
+{
+	return platform_driver_register(&qcom_cpucp_mbox_driver);
+}
+core_initcall(qcom_cpucp_mbox_init);
+
+static void __exit qcom_cpucp_mbox_exit(void)
+{
+	platform_driver_unregister(&qcom_cpucp_mbox_driver);
+}
+module_exit(qcom_cpucp_mbox_exit);
+
+MODULE_DESCRIPTION("QTI CPUCP MBOX Driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/mailbox/qcom-ipcc.c
+++ linux-qcom-6.8.0/drivers/mailbox/qcom-ipcc.c
@@ -10,6 +10,7 @@
 #include <linux/mailbox_controller.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/suspend.h>
 
 #include <dt-bindings/mailbox/qcom-ipcc.h>
 
@@ -30,10 +31,12 @@
  * struct qcom_ipcc_chan_info - Per-mailbox-channel info
  * @client_id:	The client-id to which the interrupt has to be triggered
  * @signal_id:	The signal-id to which the interrupt has to be triggered
+ * @enabled:	Flag to track status of interrupt
  */
 struct qcom_ipcc_chan_info {
 	u16 client_id;
 	u16 signal_id;
+	u16 enabled;
 };
 
 /**
@@ -88,11 +91,31 @@
 	return IRQ_HANDLED;
 }
 
+static void qcom_ipcc_update_irq_status(struct qcom_ipcc *ipcc,
+		irq_hw_number_t hwirq, bool is_enabled)
+{
+	struct qcom_ipcc_chan_info *qcom_ipcc_chan_info;
+	int chan_id;
+
+	for (chan_id = 0; chan_id < ipcc->num_chans; chan_id++) {
+		qcom_ipcc_chan_info = ipcc->chans[chan_id].con_priv;
+		if (!qcom_ipcc_chan_info)
+			break;
+
+		if (qcom_ipcc_chan_info->client_id == FIELD_GET(IPCC_CLIENT_ID_MASK, hwirq) &&
+		    qcom_ipcc_chan_info->signal_id == FIELD_GET(IPCC_SIGNAL_ID_MASK, hwirq)) {
+			qcom_ipcc_chan_info->enabled = is_enabled;
+			break;
+		}
+	}
+}
+
 static void qcom_ipcc_mask_irq(struct irq_data *irqd)
 {
 	struct qcom_ipcc *ipcc = irq_data_get_irq_chip_data(irqd);
 	irq_hw_number_t hwirq = irqd_to_hwirq(irqd);
 
+	qcom_ipcc_update_irq_status(ipcc, hwirq, 0);
 	writel(hwirq, ipcc->base + IPCC_REG_RECV_SIGNAL_DISABLE);
 }
 
@@ -101,6 +124,7 @@
 	struct qcom_ipcc *ipcc = irq_data_get_irq_chip_data(irqd);
 	irq_hw_number_t hwirq = irqd_to_hwirq(irqd);
 
+	qcom_ipcc_update_irq_status(ipcc, hwirq, 1);
 	writel(hwirq, ipcc->base + IPCC_REG_RECV_SIGNAL_ENABLE);
 }
 
@@ -253,12 +277,43 @@
 	return devm_mbox_controller_register(dev, mbox);
 }
 
+static void qcom_ipcc_restore_unmask_irq(struct device *dev)
+{
+	struct qcom_ipcc_chan_info *qcom_ipcc_chan_info;
+	struct qcom_ipcc *ipcc = dev_get_drvdata(dev);
+	u32 packed_id;
+	int chan_id;
+
+	if (!ipcc || !ipcc->num_chans)
+		return;
+
+	for (chan_id = 0; chan_id < ipcc->num_chans; chan_id++) {
+		qcom_ipcc_chan_info = ipcc->chans[chan_id].con_priv;
+		if (!qcom_ipcc_chan_info)
+			break;
+
+		packed_id = qcom_ipcc_get_hwirq(qcom_ipcc_chan_info->client_id,
+						qcom_ipcc_chan_info->signal_id);
+		if (qcom_ipcc_chan_info->enabled) {
+			dev_dbg(dev,
+				"%s: restore 0x%lx for client_id: %u signal_id: %u\n",
+				__func__, packed_id, qcom_ipcc_chan_info->client_id,
+				qcom_ipcc_chan_info->signal_id);
+			writel(packed_id, ipcc->base + IPCC_REG_RECV_SIGNAL_ENABLE);
+		}
+	}
+}
+
 static int qcom_ipcc_pm_resume(struct device *dev)
 {
 	struct qcom_ipcc *ipcc = dev_get_drvdata(dev);
 	u32 hwirq;
 	int virq;
 
+	if (pm_suspend_target_state == PM_SUSPEND_MEM
+		|| pm_suspend_target_state == PM_SUSPEND_TO_IDLE)
+		qcom_ipcc_restore_unmask_irq(dev);
+
 	hwirq = readl(ipcc->base + IPCC_REG_RECV_ID);
 	if (hwirq == IPCC_NO_PENDING_IRQ)
 		return 0;
--- linux-qcom-6.8.0.orig/drivers/mailbox/rockchip-mailbox.c
+++ linux-qcom-6.8.0/drivers/mailbox/rockchip-mailbox.c
@@ -159,7 +159,7 @@
 	{ .compatible = "rockchip,rk3368-mailbox", .data = &rk3368_drv_data},
 	{ },
 };
-MODULE_DEVICE_TABLE(of, rockchp_mbox_of_match);
+MODULE_DEVICE_TABLE(of, rockchip_mbox_of_match);
 
 static int rockchip_mbox_probe(struct platform_device *pdev)
 {
--- linux-qcom-6.8.0.orig/drivers/mailbox/tegra-hsp.c
+++ linux-qcom-6.8.0/drivers/mailbox/tegra-hsp.c
@@ -388,7 +388,6 @@
 	value = tegra_hsp_channel_readl(channel, HSP_SM_SHRD_MBOX);
 	value &= ~HSP_SM_SHRD_MBOX_FULL;
 	msg = (void *)(unsigned long)value;
-	mbox_chan_received_data(channel->chan, msg);
 
 	/*
 	 * Need to clear all bits here since some producers, such as TCU, depend
@@ -398,6 +397,8 @@
 	 * explicitly, so we have to make sure we cover all possible cases.
 	 */
 	tegra_hsp_channel_writel(channel, 0x0, HSP_SM_SHRD_MBOX);
+
+	mbox_chan_received_data(channel->chan, msg);
 }
 
 static const struct tegra_hsp_sm_ops tegra_hsp_sm_32bit_ops = {
@@ -433,7 +434,6 @@
 	value[3] = tegra_hsp_channel_readl(channel, HSP_SHRD_MBOX_TYPE1_DATA3);
 
 	msg = (void *)(unsigned long)value;
-	mbox_chan_received_data(channel->chan, msg);
 
 	/*
 	 * Clear data registers and tag.
@@ -443,6 +443,8 @@
 	tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_DATA2);
 	tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_DATA3);
 	tegra_hsp_channel_writel(channel, 0x0, HSP_SHRD_MBOX_TYPE1_TAG);
+
+	mbox_chan_received_data(channel->chan, msg);
 }
 
 static const struct tegra_hsp_sm_ops tegra_hsp_sm_128bit_ops = {
--- linux-qcom-6.8.0.orig/drivers/md/bcache/bset.c
+++ linux-qcom-6.8.0/drivers/md/bcache/bset.c
@@ -54,7 +54,7 @@
 int __bch_count_data(struct btree_keys *b)
 {
 	unsigned int ret = 0;
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 	struct bkey *k;
 
 	if (b->ops->is_extents)
@@ -67,7 +67,7 @@
 {
 	va_list args;
 	struct bkey *k, *p = NULL;
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 	const char *err;
 
 	for_each_key(b, k, &iter) {
@@ -879,7 +879,7 @@
 	unsigned int status = BTREE_INSERT_STATUS_NO_INSERT;
 	struct bset *i = bset_tree_last(b)->data;
 	struct bkey *m, *prev = NULL;
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 	struct bkey preceding_key_on_stack = ZERO_KEY;
 	struct bkey *preceding_key_p = &preceding_key_on_stack;
 
@@ -895,9 +895,9 @@
 	else
 		preceding_key(k, &preceding_key_p);
 
-	m = bch_btree_iter_init(b, &iter, preceding_key_p);
+	m = bch_btree_iter_stack_init(b, &iter, preceding_key_p);
 
-	if (b->ops->insert_fixup(b, k, &iter, replace_key))
+	if (b->ops->insert_fixup(b, k, &iter.iter, replace_key))
 		return status;
 
 	status = BTREE_INSERT_STATUS_INSERT;
@@ -1100,33 +1100,33 @@
 				 btree_iter_cmp));
 }
 
-static struct bkey *__bch_btree_iter_init(struct btree_keys *b,
-					  struct btree_iter *iter,
-					  struct bkey *search,
-					  struct bset_tree *start)
+static struct bkey *__bch_btree_iter_stack_init(struct btree_keys *b,
+						struct btree_iter_stack *iter,
+						struct bkey *search,
+						struct bset_tree *start)
 {
 	struct bkey *ret = NULL;
 
-	iter->size = ARRAY_SIZE(iter->data);
-	iter->used = 0;
+	iter->iter.size = ARRAY_SIZE(iter->stack_data);
+	iter->iter.used = 0;
 
 #ifdef CONFIG_BCACHE_DEBUG
-	iter->b = b;
+	iter->iter.b = b;
 #endif
 
 	for (; start <= bset_tree_last(b); start++) {
 		ret = bch_bset_search(b, start, search);
-		bch_btree_iter_push(iter, ret, bset_bkey_last(start->data));
+		bch_btree_iter_push(&iter->iter, ret, bset_bkey_last(start->data));
 	}
 
 	return ret;
 }
 
-struct bkey *bch_btree_iter_init(struct btree_keys *b,
-				 struct btree_iter *iter,
+struct bkey *bch_btree_iter_stack_init(struct btree_keys *b,
+				 struct btree_iter_stack *iter,
 				 struct bkey *search)
 {
-	return __bch_btree_iter_init(b, iter, search, b->set);
+	return __bch_btree_iter_stack_init(b, iter, search, b->set);
 }
 
 static inline struct bkey *__bch_btree_iter_next(struct btree_iter *iter,
@@ -1293,10 +1293,10 @@
 			    struct bset_sort_state *state)
 {
 	size_t order = b->page_order, keys = 0;
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 	int oldsize = bch_count_data(b);
 
-	__bch_btree_iter_init(b, &iter, NULL, &b->set[start]);
+	__bch_btree_iter_stack_init(b, &iter, NULL, &b->set[start]);
 
 	if (start) {
 		unsigned int i;
@@ -1307,7 +1307,7 @@
 		order = get_order(__set_bytes(b->set->data, keys));
 	}
 
-	__btree_sort(b, &iter, start, order, false, state);
+	__btree_sort(b, &iter.iter, start, order, false, state);
 
 	EBUG_ON(oldsize >= 0 && bch_count_data(b) != oldsize);
 }
@@ -1323,11 +1323,11 @@
 			 struct bset_sort_state *state)
 {
 	uint64_t start_time = local_clock();
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 
-	bch_btree_iter_init(b, &iter, NULL);
+	bch_btree_iter_stack_init(b, &iter, NULL);
 
-	btree_mergesort(b, new->set->data, &iter, false, true);
+	btree_mergesort(b, new->set->data, &iter.iter, false, true);
 
 	bch_time_stats_update(&state->time, start_time);
 
--- linux-qcom-6.8.0.orig/drivers/md/bcache/bset.h
+++ linux-qcom-6.8.0/drivers/md/bcache/bset.h
@@ -321,7 +321,14 @@
 #endif
 	struct btree_iter_set {
 		struct bkey *k, *end;
-	} data[MAX_BSETS];
+	} data[];
+};
+
+/* Fixed-size btree_iter that can be allocated on the stack */
+
+struct btree_iter_stack {
+	struct btree_iter iter;
+	struct btree_iter_set stack_data[MAX_BSETS];
 };
 
 typedef bool (*ptr_filter_fn)(struct btree_keys *b, const struct bkey *k);
@@ -333,9 +340,9 @@
 
 void bch_btree_iter_push(struct btree_iter *iter, struct bkey *k,
 			 struct bkey *end);
-struct bkey *bch_btree_iter_init(struct btree_keys *b,
-				 struct btree_iter *iter,
-				 struct bkey *search);
+struct bkey *bch_btree_iter_stack_init(struct btree_keys *b,
+				       struct btree_iter_stack *iter,
+				       struct bkey *search);
 
 struct bkey *__bch_bset_search(struct btree_keys *b, struct bset_tree *t,
 			       const struct bkey *search);
@@ -350,13 +357,14 @@
 	return search ? __bch_bset_search(b, t, search) : t->data->start;
 }
 
-#define for_each_key_filter(b, k, iter, filter)				\
-	for (bch_btree_iter_init((b), (iter), NULL);			\
-	     ((k) = bch_btree_iter_next_filter((iter), (b), filter));)
-
-#define for_each_key(b, k, iter)					\
-	for (bch_btree_iter_init((b), (iter), NULL);			\
-	     ((k) = bch_btree_iter_next(iter));)
+#define for_each_key_filter(b, k, stack_iter, filter)                      \
+	for (bch_btree_iter_stack_init((b), (stack_iter), NULL);           \
+	     ((k) = bch_btree_iter_next_filter(&((stack_iter)->iter), (b), \
+					       filter));)
+
+#define for_each_key(b, k, stack_iter)                           \
+	for (bch_btree_iter_stack_init((b), (stack_iter), NULL); \
+	     ((k) = bch_btree_iter_next(&((stack_iter)->iter)));)
 
 /* Sorting */
 
--- linux-qcom-6.8.0.orig/drivers/md/bcache/btree.c
+++ linux-qcom-6.8.0/drivers/md/bcache/btree.c
@@ -1309,7 +1309,7 @@
 	uint8_t stale = 0;
 	unsigned int keys = 0, good_keys = 0;
 	struct bkey *k;
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 	struct bset_tree *t;
 
 	gc->nodes++;
@@ -1570,7 +1570,7 @@
 static unsigned int btree_gc_count_keys(struct btree *b)
 {
 	struct bkey *k;
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 	unsigned int ret = 0;
 
 	for_each_key_filter(&b->keys, k, &iter, bch_ptr_bad)
@@ -1611,17 +1611,18 @@
 	int ret = 0;
 	bool should_rewrite;
 	struct bkey *k;
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 	struct gc_merge_info r[GC_MERGE_NODES];
 	struct gc_merge_info *i, *last = r + ARRAY_SIZE(r) - 1;
 
-	bch_btree_iter_init(&b->keys, &iter, &b->c->gc_done);
+	bch_btree_iter_stack_init(&b->keys, &iter, &b->c->gc_done);
 
 	for (i = r; i < r + ARRAY_SIZE(r); i++)
 		i->b = ERR_PTR(-EINTR);
 
 	while (1) {
-		k = bch_btree_iter_next_filter(&iter, &b->keys, bch_ptr_bad);
+		k = bch_btree_iter_next_filter(&iter.iter, &b->keys,
+					       bch_ptr_bad);
 		if (k) {
 			r->b = bch_btree_node_get(b->c, op, k, b->level - 1,
 						  true, b);
@@ -1911,7 +1912,7 @@
 {
 	int ret = 0;
 	struct bkey *k, *p = NULL;
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 
 	for_each_key_filter(&b->keys, k, &iter, bch_ptr_invalid)
 		bch_initial_mark_key(b->c, b->level, k);
@@ -1919,10 +1920,10 @@
 	bch_initial_mark_key(b->c, b->level + 1, &b->key);
 
 	if (b->level) {
-		bch_btree_iter_init(&b->keys, &iter, NULL);
+		bch_btree_iter_stack_init(&b->keys, &iter, NULL);
 
 		do {
-			k = bch_btree_iter_next_filter(&iter, &b->keys,
+			k = bch_btree_iter_next_filter(&iter.iter, &b->keys,
 						       bch_ptr_bad);
 			if (k) {
 				btree_node_prefetch(b, k);
@@ -1950,7 +1951,7 @@
 	struct btree_check_info *info = arg;
 	struct btree_check_state *check_state = info->state;
 	struct cache_set *c = check_state->c;
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 	struct bkey *k, *p;
 	int cur_idx, prev_idx, skip_nr;
 
@@ -1959,8 +1960,8 @@
 	ret = 0;
 
 	/* root node keys are checked before thread created */
-	bch_btree_iter_init(&c->root->keys, &iter, NULL);
-	k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad);
+	bch_btree_iter_stack_init(&c->root->keys, &iter, NULL);
+	k = bch_btree_iter_next_filter(&iter.iter, &c->root->keys, bch_ptr_bad);
 	BUG_ON(!k);
 
 	p = k;
@@ -1978,7 +1979,7 @@
 		skip_nr = cur_idx - prev_idx;
 
 		while (skip_nr) {
-			k = bch_btree_iter_next_filter(&iter,
+			k = bch_btree_iter_next_filter(&iter.iter,
 						       &c->root->keys,
 						       bch_ptr_bad);
 			if (k)
@@ -2051,7 +2052,7 @@
 	int ret = 0;
 	int i;
 	struct bkey *k = NULL;
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 	struct btree_check_state check_state;
 
 	/* check and mark root node keys */
@@ -2547,11 +2548,11 @@
 
 	if (b->level) {
 		struct bkey *k;
-		struct btree_iter iter;
+		struct btree_iter_stack iter;
 
-		bch_btree_iter_init(&b->keys, &iter, from);
+		bch_btree_iter_stack_init(&b->keys, &iter, from);
 
-		while ((k = bch_btree_iter_next_filter(&iter, &b->keys,
+		while ((k = bch_btree_iter_next_filter(&iter.iter, &b->keys,
 						       bch_ptr_bad))) {
 			ret = bcache_btree(map_nodes_recurse, k, b,
 				    op, from, fn, flags);
@@ -2580,11 +2581,12 @@
 {
 	int ret = MAP_CONTINUE;
 	struct bkey *k;
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 
-	bch_btree_iter_init(&b->keys, &iter, from);
+	bch_btree_iter_stack_init(&b->keys, &iter, from);
 
-	while ((k = bch_btree_iter_next_filter(&iter, &b->keys, bch_ptr_bad))) {
+	while ((k = bch_btree_iter_next_filter(&iter.iter, &b->keys,
+					       bch_ptr_bad))) {
 		ret = !b->level
 			? fn(op, b, k)
 			: bcache_btree(map_keys_recurse, k,
--- linux-qcom-6.8.0.orig/drivers/md/bcache/super.c
+++ linux-qcom-6.8.0/drivers/md/bcache/super.c
@@ -1724,7 +1724,7 @@
 	if (!IS_ERR_OR_NULL(c->gc_thread))
 		kthread_stop(c->gc_thread);
 
-	if (!IS_ERR(c->root))
+	if (!IS_ERR_OR_NULL(c->root))
 		list_add(&c->root->list, &c->btree_cache);
 
 	/*
@@ -1913,8 +1913,9 @@
 	INIT_LIST_HEAD(&c->btree_cache_freed);
 	INIT_LIST_HEAD(&c->data_buckets);
 
-	iter_size = ((meta_bucket_pages(sb) * PAGE_SECTORS) / sb->block_size + 1) *
-		sizeof(struct btree_iter_set);
+	iter_size = sizeof(struct btree_iter) +
+		    ((meta_bucket_pages(sb) * PAGE_SECTORS) / sb->block_size) *
+			    sizeof(struct btree_iter_set);
 
 	c->devices = kcalloc(c->nr_uuids, sizeof(void *), GFP_KERNEL);
 	if (!c->devices)
--- linux-qcom-6.8.0.orig/drivers/md/bcache/sysfs.c
+++ linux-qcom-6.8.0/drivers/md/bcache/sysfs.c
@@ -660,7 +660,7 @@
 	unsigned int bytes = 0;
 	struct bkey *k;
 	struct btree *b;
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 
 	goto lock_root;
 
--- linux-qcom-6.8.0.orig/drivers/md/bcache/writeback.c
+++ linux-qcom-6.8.0/drivers/md/bcache/writeback.c
@@ -908,15 +908,15 @@
 	struct dirty_init_thrd_info *info = arg;
 	struct bch_dirty_init_state *state = info->state;
 	struct cache_set *c = state->c;
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 	struct bkey *k, *p;
 	int cur_idx, prev_idx, skip_nr;
 
 	k = p = NULL;
 	prev_idx = 0;
 
-	bch_btree_iter_init(&c->root->keys, &iter, NULL);
-	k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad);
+	bch_btree_iter_stack_init(&c->root->keys, &iter, NULL);
+	k = bch_btree_iter_next_filter(&iter.iter, &c->root->keys, bch_ptr_bad);
 	BUG_ON(!k);
 
 	p = k;
@@ -930,7 +930,7 @@
 		skip_nr = cur_idx - prev_idx;
 
 		while (skip_nr) {
-			k = bch_btree_iter_next_filter(&iter,
+			k = bch_btree_iter_next_filter(&iter.iter,
 						       &c->root->keys,
 						       bch_ptr_bad);
 			if (k)
@@ -979,7 +979,7 @@
 	int i;
 	struct btree *b = NULL;
 	struct bkey *k = NULL;
-	struct btree_iter iter;
+	struct btree_iter_stack iter;
 	struct sectors_dirty_init op;
 	struct cache_set *c = d->c;
 	struct bch_dirty_init_state state;
--- linux-qcom-6.8.0.orig/drivers/md/dm-bufio.c
+++ linux-qcom-6.8.0/drivers/md/dm-bufio.c
@@ -1315,7 +1315,7 @@
 		io_req.mem.ptr.vma = (char *)b->data + offset;
 	}
 
-	r = dm_io(&io_req, 1, &region, NULL);
+	r = dm_io(&io_req, 1, &region, NULL, IOPRIO_DEFAULT);
 	if (unlikely(r))
 		b->end_io(b, errno_to_blk_status(r));
 }
@@ -2167,7 +2167,7 @@
 	if (WARN_ON_ONCE(dm_bufio_in_request()))
 		return -EINVAL;
 
-	return dm_io(&io_req, 1, &io_reg, NULL);
+	return dm_io(&io_req, 1, &io_reg, NULL, IOPRIO_DEFAULT);
 }
 EXPORT_SYMBOL_GPL(dm_bufio_issue_flush);
 
@@ -2191,7 +2191,7 @@
 	if (WARN_ON_ONCE(dm_bufio_in_request()))
 		return -EINVAL; /* discards are optional */
 
-	return dm_io(&io_req, 1, &io_reg, NULL);
+	return dm_io(&io_req, 1, &io_reg, NULL, IOPRIO_DEFAULT);
 }
 EXPORT_SYMBOL_GPL(dm_bufio_issue_discard);
 
--- linux-qcom-6.8.0.orig/drivers/md/dm-cache-target.c
+++ linux-qcom-6.8.0/drivers/md/dm-cache-target.c
@@ -1909,16 +1909,13 @@
  * This function gets called on the error paths of the constructor, so we
  * have to cope with a partially initialised struct.
  */
-static void destroy(struct cache *cache)
+static void __destroy(struct cache *cache)
 {
-	unsigned int i;
-
 	mempool_exit(&cache->migration_pool);
 
 	if (cache->prison)
 		dm_bio_prison_destroy_v2(cache->prison);
 
-	cancel_delayed_work_sync(&cache->waker);
 	if (cache->wq)
 		destroy_workqueue(cache->wq);
 
@@ -1946,13 +1943,22 @@
 	if (cache->policy)
 		dm_cache_policy_destroy(cache->policy);
 
+	bioset_exit(&cache->bs);
+
+	kfree(cache);
+}
+
+static void destroy(struct cache *cache)
+{
+	unsigned int i;
+
+	cancel_delayed_work_sync(&cache->waker);
+
 	for (i = 0; i < cache->nr_ctr_args ; i++)
 		kfree(cache->ctr_args[i]);
 	kfree(cache->ctr_args);
 
-	bioset_exit(&cache->bs);
-
-	kfree(cache);
+	__destroy(cache);
 }
 
 static void cache_dtr(struct dm_target *ti)
@@ -2007,7 +2013,6 @@
 	sector_t cache_sectors;
 
 	struct dm_dev *origin_dev;
-	sector_t origin_sectors;
 
 	uint32_t block_size;
 
@@ -2088,6 +2093,7 @@
 static int parse_origin_dev(struct cache_args *ca, struct dm_arg_set *as,
 			    char **error)
 {
+	sector_t origin_sectors;
 	int r;
 
 	if (!at_least_one_arg(as, error))
@@ -2100,8 +2106,8 @@
 		return r;
 	}
 
-	ca->origin_sectors = get_dev_size(ca->origin_dev);
-	if (ca->ti->len > ca->origin_sectors) {
+	origin_sectors = get_dev_size(ca->origin_dev);
+	if (ca->ti->len > origin_sectors) {
 		*error = "Device size larger than cached device";
 		return -EINVAL;
 	}
@@ -2411,7 +2417,7 @@
 
 	ca->metadata_dev = ca->origin_dev = ca->cache_dev = NULL;
 
-	origin_blocks = cache->origin_sectors = ca->origin_sectors;
+	origin_blocks = cache->origin_sectors = ti->len;
 	origin_blocks = block_div(origin_blocks, ca->block_size);
 	cache->origin_blocks = to_oblock(origin_blocks);
 
@@ -2565,7 +2571,7 @@
 	*result = cache;
 	return 0;
 bad:
-	destroy(cache);
+	__destroy(cache);
 	return r;
 }
 
@@ -2616,7 +2622,7 @@
 
 	r = copy_ctr_args(cache, argc - 3, (const char **)argv + 3);
 	if (r) {
-		destroy(cache);
+		__destroy(cache);
 		goto out;
 	}
 
@@ -2899,19 +2905,19 @@
 static bool can_resize(struct cache *cache, dm_cblock_t new_size)
 {
 	if (from_cblock(new_size) > from_cblock(cache->cache_size)) {
-		if (cache->sized) {
-			DMERR("%s: unable to extend cache due to missing cache table reload",
-			      cache_device_name(cache));
-			return false;
-		}
+		DMERR("%s: unable to extend cache due to missing cache table reload",
+		      cache_device_name(cache));
+		return false;
 	}
 
 	/*
 	 * We can't drop a dirty block when shrinking the cache.
 	 */
-	while (from_cblock(new_size) < from_cblock(cache->cache_size)) {
-		new_size = to_cblock(from_cblock(new_size) + 1);
-		if (is_dirty(cache, new_size)) {
+	if (cache->loaded_mappings) {
+		new_size = to_cblock(find_next_bit(cache->dirty_bitset,
+						   from_cblock(cache->cache_size),
+						   from_cblock(new_size)));
+		if (new_size != cache->cache_size) {
 			DMERR("%s: unable to shrink cache; cache block %llu is dirty",
 			      cache_device_name(cache),
 			      (unsigned long long) from_cblock(new_size));
@@ -2947,20 +2953,15 @@
 	/*
 	 * Check to see if the cache has resized.
 	 */
-	if (!cache->sized) {
-		r = resize_cache_dev(cache, csize);
-		if (r)
-			return r;
-
-		cache->sized = true;
-
-	} else if (csize != cache->cache_size) {
+	if (!cache->sized || csize != cache->cache_size) {
 		if (!can_resize(cache, csize))
 			return -EINVAL;
 
 		r = resize_cache_dev(cache, csize);
 		if (r)
 			return r;
+
+		cache->sized = true;
 	}
 
 	if (!cache->loaded_mappings) {
--- linux-qcom-6.8.0.orig/drivers/md/dm-clone-metadata.c
+++ linux-qcom-6.8.0/drivers/md/dm-clone-metadata.c
@@ -465,11 +465,6 @@
 
 /*---------------------------------------------------------------------------*/
 
-static size_t bitmap_size(unsigned long nr_bits)
-{
-	return BITS_TO_LONGS(nr_bits) * sizeof(long);
-}
-
 static int __dirty_map_init(struct dirty_map *dmap, unsigned long nr_words,
 			    unsigned long nr_regions)
 {
--- linux-qcom-6.8.0.orig/drivers/md/dm-crypt.c
+++ linux-qcom-6.8.0/drivers/md/dm-crypt.c
@@ -57,6 +57,7 @@
 	struct bio *bio_out;
 	struct bvec_iter iter_out;
 	atomic_t cc_pending;
+	unsigned int tag_offset;
 	u64 cc_sector;
 	union {
 		struct skcipher_request *req;
@@ -1226,6 +1227,7 @@
 	if (bio_out)
 		ctx->iter_out = bio_out->bi_iter;
 	ctx->cc_sector = sector + cc->iv_offset;
+	ctx->tag_offset = 0;
 	init_completion(&ctx->restart);
 }
 
@@ -1558,7 +1560,6 @@
 static blk_status_t crypt_convert(struct crypt_config *cc,
 			 struct convert_context *ctx, bool atomic, bool reset_pending)
 {
-	unsigned int tag_offset = 0;
 	unsigned int sector_step = cc->sector_size >> SECTOR_SHIFT;
 	int r;
 
@@ -1581,9 +1582,9 @@
 		atomic_inc(&ctx->cc_pending);
 
 		if (crypt_integrity_aead(cc))
-			r = crypt_convert_block_aead(cc, ctx, ctx->r.req_aead, tag_offset);
+			r = crypt_convert_block_aead(cc, ctx, ctx->r.req_aead, ctx->tag_offset);
 		else
-			r = crypt_convert_block_skcipher(cc, ctx, ctx->r.req, tag_offset);
+			r = crypt_convert_block_skcipher(cc, ctx, ctx->r.req, ctx->tag_offset);
 
 		switch (r) {
 		/*
@@ -1603,8 +1604,8 @@
 					 * exit and continue processing in a workqueue
 					 */
 					ctx->r.req = NULL;
+					ctx->tag_offset++;
 					ctx->cc_sector += sector_step;
-					tag_offset++;
 					return BLK_STS_DEV_RESOURCE;
 				}
 			} else {
@@ -1618,8 +1619,8 @@
 		 */
 		case -EINPROGRESS:
 			ctx->r.req = NULL;
+			ctx->tag_offset++;
 			ctx->cc_sector += sector_step;
-			tag_offset++;
 			continue;
 		/*
 		 * The request was already processed (synchronously).
@@ -1627,7 +1628,7 @@
 		case 0:
 			atomic_dec(&ctx->cc_pending);
 			ctx->cc_sector += sector_step;
-			tag_offset++;
+			ctx->tag_offset++;
 			if (!atomic)
 				cond_resched();
 			continue;
@@ -2062,7 +2063,6 @@
 	struct crypt_config *cc = io->cc;
 	struct convert_context *ctx = &io->ctx;
 	int crypt_finished;
-	sector_t sector = io->sector;
 	blk_status_t r;
 
 	wait_for_completion(&ctx->restart);
@@ -2079,10 +2079,8 @@
 	}
 
 	/* Encryption was already finished, submit io now */
-	if (crypt_finished) {
+	if (crypt_finished)
 		kcryptd_crypt_write_io_submit(io, 0);
-		io->sector = sector;
-	}
 
 	crypt_dec_pending(io);
 }
@@ -2093,14 +2091,13 @@
 	struct convert_context *ctx = &io->ctx;
 	struct bio *clone;
 	int crypt_finished;
-	sector_t sector = io->sector;
 	blk_status_t r;
 
 	/*
 	 * Prevent io from disappearing until this function completes.
 	 */
 	crypt_inc_pending(io);
-	crypt_convert_init(cc, ctx, NULL, io->base_bio, sector);
+	crypt_convert_init(cc, ctx, NULL, io->base_bio, io->sector);
 
 	clone = crypt_alloc_buffer(io, io->base_bio->bi_iter.bi_size);
 	if (unlikely(!clone)) {
@@ -2117,8 +2114,6 @@
 		io->ctx.iter_in = clone->bi_iter;
 	}
 
-	sector += bio_sectors(clone);
-
 	crypt_inc_pending(io);
 	r = crypt_convert(cc, ctx,
 			  test_bit(DM_CRYPT_NO_WRITE_WORKQUEUE, &cc->flags), true);
@@ -2142,10 +2137,8 @@
 	}
 
 	/* Encryption was already finished, submit io now */
-	if (crypt_finished) {
+	if (crypt_finished)
 		kcryptd_crypt_write_io_submit(io, 0);
-		io->sector = sector;
-	}
 
 dec:
 	crypt_dec_pending(io);
--- linux-qcom-6.8.0.orig/drivers/md/dm-delay.c
+++ linux-qcom-6.8.0/drivers/md/dm-delay.c
@@ -154,8 +154,10 @@
 {
 	struct delay_c *dc = ti->private;
 
-	if (dc->kdelayd_wq)
+	if (dc->kdelayd_wq) {
+		timer_shutdown_sync(&dc->delay_timer);
 		destroy_workqueue(dc->kdelayd_wq);
+	}
 
 	if (dc->read.dev)
 		dm_put_device(ti, dc->read.dev);
@@ -240,19 +242,18 @@
 		ret = delay_class_ctr(ti, &dc->flush, argv);
 		if (ret)
 			goto bad;
-		max_delay = max(max_delay, dc->write.delay);
-		max_delay = max(max_delay, dc->flush.delay);
 		goto out;
 	}
 
 	ret = delay_class_ctr(ti, &dc->write, argv + 3);
 	if (ret)
 		goto bad;
+	max_delay = max(max_delay, dc->write.delay);
+
 	if (argc == 6) {
 		ret = delay_class_ctr(ti, &dc->flush, argv + 3);
 		if (ret)
 			goto bad;
-		max_delay = max(max_delay, dc->flush.delay);
 		goto out;
 	}
 
@@ -267,8 +268,7 @@
 		 * In case of small requested delays, use kthread instead of
 		 * timers and workqueue to achieve better latency.
 		 */
-		dc->worker = kthread_create(&flush_worker_fn, dc,
-					    "dm-delay-flush-worker");
+		dc->worker = kthread_run(&flush_worker_fn, dc, "dm-delay-flush-worker");
 		if (IS_ERR(dc->worker)) {
 			ret = PTR_ERR(dc->worker);
 			dc->worker = NULL;
@@ -335,7 +335,7 @@
 	mutex_unlock(&delayed_bios_lock);
 
 	if (!delay_is_fast(dc))
-		del_timer_sync(&dc->delay_timer);
+		timer_delete(&dc->delay_timer);
 	flush_delayed_bios(dc, true);
 }
 
--- linux-qcom-6.8.0.orig/drivers/md/dm-ebs-target.c
+++ linux-qcom-6.8.0/drivers/md/dm-ebs-target.c
@@ -442,7 +442,7 @@
 static struct target_type ebs_target = {
 	.name		 = "ebs",
 	.version	 = {1, 0, 1},
-	.features	 = DM_TARGET_PASSES_INTEGRITY,
+	.features	 = 0,
 	.module		 = THIS_MODULE,
 	.ctr		 = ebs_ctr,
 	.dtr		 = ebs_dtr,
--- linux-qcom-6.8.0.orig/drivers/md/dm-init.c
+++ linux-qcom-6.8.0/drivers/md/dm-init.c
@@ -212,8 +212,10 @@
 	strscpy(dev->dmi.uuid, field[1], sizeof(dev->dmi.uuid));
 	/* minor */
 	if (strlen(field[2])) {
-		if (kstrtoull(field[2], 0, &dev->dmi.dev))
+		if (kstrtoull(field[2], 0, &dev->dmi.dev) ||
+		    dev->dmi.dev >= (1 << MINORBITS))
 			return ERR_PTR(-EINVAL);
+		dev->dmi.dev = huge_encode_dev((dev_t)dev->dmi.dev);
 		dev->dmi.flags |= DM_PERSISTENT_DEV_FLAG;
 	}
 	/* flags */
--- linux-qcom-6.8.0.orig/drivers/md/dm-integrity.c
+++ linux-qcom-6.8.0/drivers/md/dm-integrity.c
@@ -555,7 +555,7 @@
 		}
 	}
 
-	r = dm_io(&io_req, 1, &io_loc, NULL);
+	r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT);
 	if (unlikely(r))
 		return r;
 
@@ -1073,7 +1073,7 @@
 	io_loc.sector = ic->start + SB_SECTORS + sector;
 	io_loc.count = n_sectors;
 
-	r = dm_io(&io_req, 1, &io_loc, NULL);
+	r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT);
 	if (unlikely(r)) {
 		dm_integrity_io_error(ic, (opf & REQ_OP_MASK) == REQ_OP_READ ?
 				      "reading journal" : "writing journal", r);
@@ -1190,7 +1190,7 @@
 	io_loc.sector = target;
 	io_loc.count = n_sectors;
 
-	r = dm_io(&io_req, 1, &io_loc, NULL);
+	r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT);
 	if (unlikely(r)) {
 		WARN_ONCE(1, "asynchronous dm_io failed: %d", r);
 		fn(-1UL, data);
@@ -1519,7 +1519,7 @@
 		fr.io_reg.count = 0,
 		fr.ic = ic;
 		init_completion(&fr.comp);
-		r = dm_io(&fr.io_req, 1, &fr.io_reg, NULL);
+		r = dm_io(&fr.io_req, 1, &fr.io_reg, NULL, IOPRIO_DEFAULT);
 		BUG_ON(r);
 	}
 
@@ -1699,7 +1699,6 @@
 	struct bio_vec bv;
 	sector_t sector, logical_sector, area, offset;
 	struct page *page;
-	void *buffer;
 
 	get_area_and_offset(ic, dio->range.logical_sector, &area, &offset);
 	dio->metadata_block = get_metadata_sector_and_offset(ic, area, offset,
@@ -1708,13 +1707,14 @@
 	logical_sector = dio->range.logical_sector;
 
 	page = mempool_alloc(&ic->recheck_pool, GFP_NOIO);
-	buffer = page_to_virt(page);
 
 	__bio_for_each_segment(bv, bio, iter, dio->bio_details.bi_iter) {
 		unsigned pos = 0;
 
 		do {
+			sector_t alignment;
 			char *mem;
+			char *buffer = page_to_virt(page);
 			int r;
 			struct dm_io_request io_req;
 			struct dm_io_region io_loc;
@@ -1727,7 +1727,15 @@
 			io_loc.sector = sector;
 			io_loc.count = ic->sectors_per_block;
 
-			r = dm_io(&io_req, 1, &io_loc, NULL);
+			/* Align the bio to logical block size */
+			alignment = dio->range.logical_sector | bio_sectors(bio) | (PAGE_SIZE >> SECTOR_SHIFT);
+			alignment &= -alignment;
+			io_loc.sector = round_down(io_loc.sector, alignment);
+			io_loc.count += sector - io_loc.sector;
+			buffer += (sector - io_loc.sector) << SECTOR_SHIFT;
+			io_loc.count = round_up(io_loc.count, alignment);
+
+			r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT);
 			if (unlikely(r)) {
 				dio->bi_status = errno_to_blk_status(r);
 				goto free_ret;
@@ -1848,12 +1856,12 @@
 			r = dm_integrity_rw_tag(ic, checksums, &dio->metadata_block, &dio->metadata_offset,
 						checksums_ptr - checksums, dio->op == REQ_OP_READ ? TAG_CMP : TAG_WRITE);
 			if (unlikely(r)) {
+				if (likely(checksums != checksums_onstack))
+					kfree(checksums);
 				if (r > 0) {
-					integrity_recheck(dio, checksums);
+					integrity_recheck(dio, checksums_onstack);
 					goto skip_io;
 				}
-				if (likely(checksums != checksums_onstack))
-					kfree(checksums);
 				goto error;
 			}
 
@@ -2165,6 +2173,7 @@
 	struct bio *bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io));
 	unsigned int journal_section, journal_entry;
 	unsigned int journal_read_pos;
+	sector_t recalc_sector;
 	struct completion read_comp;
 	bool discard_retried = false;
 	bool need_sync_io = ic->internal_hash && dio->op == REQ_OP_READ;
@@ -2305,6 +2314,7 @@
 			goto lock_retry;
 		}
 	}
+	recalc_sector = le64_to_cpu(ic->sb->recalc_sector);
 	spin_unlock_irq(&ic->endio_wait.lock);
 
 	if (unlikely(journal_read_pos != NOT_FOUND)) {
@@ -2359,7 +2369,7 @@
 	if (need_sync_io) {
 		wait_for_completion_io(&read_comp);
 		if (ic->sb->flags & cpu_to_le32(SB_FLAG_RECALCULATING) &&
-		    dio->range.logical_sector + dio->range.n_sectors > le64_to_cpu(ic->sb->recalc_sector))
+		    dio->range.logical_sector + dio->range.n_sectors > recalc_sector)
 			goto skip_check;
 		if (ic->mode == 'B') {
 			if (!block_bitmap_op(ic, ic->recalc_bitmap, dio->range.logical_sector,
@@ -2806,7 +2816,7 @@
 	io_loc.sector = get_data_sector(ic, area, offset);
 	io_loc.count = n_sectors;
 
-	r = dm_io(&io_req, 1, &io_loc, NULL);
+	r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT);
 	if (unlikely(r)) {
 		dm_integrity_io_error(ic, "reading data", r);
 		goto err;
@@ -3484,6 +3494,7 @@
 		limits->physical_block_size = ic->sectors_per_block << SECTOR_SHIFT;
 		blk_limits_io_min(limits, ic->sectors_per_block << SECTOR_SHIFT);
 		limits->dma_alignment = limits->logical_block_size - 1;
+		limits->discard_granularity = ic->sectors_per_block << SECTOR_SHIFT;
 	}
 }
 
@@ -4213,7 +4224,7 @@
 		} else if (sscanf(opt_string, "sectors_per_bit:%llu%c", &llval, &dummy) == 1) {
 			log2_sectors_per_bitmap_bit = !llval ? 0 : __ilog2_u64(llval);
 		} else if (sscanf(opt_string, "bitmap_flush_interval:%u%c", &val, &dummy) == 1) {
-			if (val >= (uint64_t)UINT_MAX * 1000 / HZ) {
+			if ((uint64_t)val >= (uint64_t)UINT_MAX * 1000 / HZ) {
 				r = -EINVAL;
 				ti->error = "Invalid bitmap_flush_interval argument";
 				goto bad;
--- linux-qcom-6.8.0.orig/drivers/md/dm-io.c
+++ linux-qcom-6.8.0/drivers/md/dm-io.c
@@ -305,7 +305,7 @@
  */
 static void do_region(const blk_opf_t opf, unsigned int region,
 		      struct dm_io_region *where, struct dpages *dp,
-		      struct io *io)
+		      struct io *io, unsigned short ioprio)
 {
 	struct bio *bio;
 	struct page *page;
@@ -354,6 +354,7 @@
 				       &io->client->bios);
 		bio->bi_iter.bi_sector = where->sector + (where->count - remaining);
 		bio->bi_end_io = endio;
+		bio->bi_ioprio = ioprio;
 		store_io_and_region_in_bio(bio, io, region);
 
 		if (op == REQ_OP_DISCARD || op == REQ_OP_WRITE_ZEROES) {
@@ -383,7 +384,7 @@
 
 static void dispatch_io(blk_opf_t opf, unsigned int num_regions,
 			struct dm_io_region *where, struct dpages *dp,
-			struct io *io, int sync)
+			struct io *io, int sync, unsigned short ioprio)
 {
 	int i;
 	struct dpages old_pages = *dp;
@@ -400,7 +401,7 @@
 	for (i = 0; i < num_regions; i++) {
 		*dp = old_pages;
 		if (where[i].count || (opf & REQ_PREFLUSH))
-			do_region(opf, i, where + i, dp, io);
+			do_region(opf, i, where + i, dp, io, ioprio);
 	}
 
 	/*
@@ -425,7 +426,7 @@
 
 static int sync_io(struct dm_io_client *client, unsigned int num_regions,
 		   struct dm_io_region *where, blk_opf_t opf, struct dpages *dp,
-		   unsigned long *error_bits)
+		   unsigned long *error_bits, unsigned short ioprio)
 {
 	struct io *io;
 	struct sync_io sio;
@@ -447,7 +448,7 @@
 	io->vma_invalidate_address = dp->vma_invalidate_address;
 	io->vma_invalidate_size = dp->vma_invalidate_size;
 
-	dispatch_io(opf, num_regions, where, dp, io, 1);
+	dispatch_io(opf, num_regions, where, dp, io, 1, ioprio);
 
 	wait_for_completion_io(&sio.wait);
 
@@ -459,7 +460,8 @@
 
 static int async_io(struct dm_io_client *client, unsigned int num_regions,
 		    struct dm_io_region *where, blk_opf_t opf,
-		    struct dpages *dp, io_notify_fn fn, void *context)
+		    struct dpages *dp, io_notify_fn fn, void *context,
+		    unsigned short ioprio)
 {
 	struct io *io;
 
@@ -479,7 +481,7 @@
 	io->vma_invalidate_address = dp->vma_invalidate_address;
 	io->vma_invalidate_size = dp->vma_invalidate_size;
 
-	dispatch_io(opf, num_regions, where, dp, io, 0);
+	dispatch_io(opf, num_regions, where, dp, io, 0, ioprio);
 	return 0;
 }
 
@@ -521,7 +523,8 @@
 }
 
 int dm_io(struct dm_io_request *io_req, unsigned int num_regions,
-	  struct dm_io_region *where, unsigned long *sync_error_bits)
+	  struct dm_io_region *where, unsigned long *sync_error_bits,
+	  unsigned short ioprio)
 {
 	int r;
 	struct dpages dp;
@@ -532,11 +535,11 @@
 
 	if (!io_req->notify.fn)
 		return sync_io(io_req->client, num_regions, where,
-			       io_req->bi_opf, &dp, sync_error_bits);
+			       io_req->bi_opf, &dp, sync_error_bits, ioprio);
 
 	return async_io(io_req->client, num_regions, where,
 			io_req->bi_opf, &dp, io_req->notify.fn,
-			io_req->notify.context);
+			io_req->notify.context, ioprio);
 }
 EXPORT_SYMBOL(dm_io);
 
--- linux-qcom-6.8.0.orig/drivers/md/dm-ioctl.c
+++ linux-qcom-6.8.0/drivers/md/dm-ioctl.c
@@ -1181,8 +1181,26 @@
 			suspend_flags &= ~DM_SUSPEND_LOCKFS_FLAG;
 		if (param->flags & DM_NOFLUSH_FLAG)
 			suspend_flags |= DM_SUSPEND_NOFLUSH_FLAG;
-		if (!dm_suspended_md(md))
-			dm_suspend(md, suspend_flags);
+		if (!dm_suspended_md(md)) {
+			r = dm_suspend(md, suspend_flags);
+			if (r) {
+				down_write(&_hash_lock);
+				hc = dm_get_mdptr(md);
+				if (hc && !hc->new_map) {
+					hc->new_map = new_map;
+					new_map = NULL;
+				} else {
+					r = -ENXIO;
+				}
+				up_write(&_hash_lock);
+				if (new_map) {
+					dm_sync_table(md);
+					dm_table_destroy(new_map);
+				}
+				dm_put(md);
+				return r;
+			}
+		}
 
 		old_size = dm_get_size(md);
 		old_map = dm_swap_table(md, new_map);
--- linux-qcom-6.8.0.orig/drivers/md/dm-kcopyd.c
+++ linux-qcom-6.8.0/drivers/md/dm-kcopyd.c
@@ -578,9 +578,9 @@
 	io_job_start(job->kc->throttle);
 
 	if (job->op == REQ_OP_READ)
-		r = dm_io(&io_req, 1, &job->source, NULL);
+		r = dm_io(&io_req, 1, &job->source, NULL, IOPRIO_DEFAULT);
 	else
-		r = dm_io(&io_req, job->num_dests, job->dests, NULL);
+		r = dm_io(&io_req, job->num_dests, job->dests, NULL, IOPRIO_DEFAULT);
 
 	return r;
 }
--- linux-qcom-6.8.0.orig/drivers/md/dm-log.c
+++ linux-qcom-6.8.0/drivers/md/dm-log.c
@@ -300,7 +300,7 @@
 {
 	lc->io_req.bi_opf = op;
 
-	return dm_io(&lc->io_req, 1, &lc->header_location, NULL);
+	return dm_io(&lc->io_req, 1, &lc->header_location, NULL, IOPRIO_DEFAULT);
 }
 
 static int flush_header(struct log_c *lc)
@@ -313,7 +313,7 @@
 
 	lc->io_req.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
 
-	return dm_io(&lc->io_req, 1, &null_location, NULL);
+	return dm_io(&lc->io_req, 1, &null_location, NULL, IOPRIO_DEFAULT);
 }
 
 static int read_header(struct log_c *log)
--- linux-qcom-6.8.0.orig/drivers/md/dm-raid.c
+++ linux-qcom-6.8.0/drivers/md/dm-raid.c
@@ -213,6 +213,7 @@
 #define RT_FLAG_RS_IN_SYNC		6
 #define RT_FLAG_RS_RESYNCING		7
 #define RT_FLAG_RS_GROW			8
+#define RT_FLAG_RS_FROZEN		9
 
 /* Array elements of 64 bit needed for rebuild/failed disk bits */
 #define DISKS_ARRAY_ELEMS ((MAX_RAID_DEVICES + (sizeof(uint64_t) * 8 - 1)) / sizeof(uint64_t) / 8)
@@ -3240,11 +3241,12 @@
 	rs->md.ro = 1;
 	rs->md.in_sync = 1;
 
-	/* Keep array frozen until resume. */
-	set_bit(MD_RECOVERY_FROZEN, &rs->md.recovery);
-
 	/* Has to be held on running the array */
 	mddev_suspend_and_lock_nointr(&rs->md);
+
+	/* Keep array frozen until resume. */
+	md_frozen_sync_thread(&rs->md);
+
 	r = md_run(&rs->md);
 	rs->md.in_sync = 0; /* Assume already marked dirty */
 	if (r) {
@@ -3329,17 +3331,18 @@
 	struct mddev *mddev = &rs->md;
 
 	/*
-	 * If we're reshaping to add disk(s)), ti->len and
+	 * If we're reshaping to add disk(s), ti->len and
 	 * mddev->array_sectors will differ during the process
 	 * (ti->len > mddev->array_sectors), so we have to requeue
 	 * bios with addresses > mddev->array_sectors here or
 	 * there will occur accesses past EOD of the component
 	 * data images thus erroring the raid set.
 	 */
-	if (unlikely(bio_end_sector(bio) > mddev->array_sectors))
+	if (unlikely(bio_has_data(bio) && bio_end_sector(bio) > mddev->array_sectors))
 		return DM_MAPIO_REQUEUE;
 
-	md_handle_request(mddev, bio);
+	if (unlikely(!md_handle_request(mddev, bio)))
+		return DM_MAPIO_REQUEUE;
 
 	return DM_MAPIO_SUBMITTED;
 }
@@ -3718,21 +3721,33 @@
 {
 	struct raid_set *rs = ti->private;
 	struct mddev *mddev = &rs->md;
+	int ret = 0;
 
 	if (!mddev->pers || !mddev->pers->sync_request)
 		return -EINVAL;
 
-	if (!strcasecmp(argv[0], "frozen"))
-		set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
-	else
-		clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+	if (test_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags) ||
+	    test_bit(RT_FLAG_RS_FROZEN, &rs->runtime_flags))
+		return -EBUSY;
 
-	if (!strcasecmp(argv[0], "idle") || !strcasecmp(argv[0], "frozen")) {
-		if (mddev->sync_thread) {
-			set_bit(MD_RECOVERY_INTR, &mddev->recovery);
-			md_reap_sync_thread(mddev);
-		}
-	} else if (decipher_sync_action(mddev, mddev->recovery) != st_idle)
+	if (!strcasecmp(argv[0], "frozen")) {
+		ret = mddev_lock(mddev);
+		if (ret)
+			return ret;
+
+		md_frozen_sync_thread(mddev);
+		mddev_unlock(mddev);
+	} else if (!strcasecmp(argv[0], "idle")) {
+		ret = mddev_lock(mddev);
+		if (ret)
+			return ret;
+
+		md_idle_sync_thread(mddev);
+		mddev_unlock(mddev);
+	}
+
+	clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+	if (decipher_sync_action(mddev, mddev->recovery) != st_idle)
 		return -EBUSY;
 	else if (!strcasecmp(argv[0], "resync"))
 		; /* MD_RECOVERY_NEEDED set below */
@@ -3791,15 +3806,46 @@
 	blk_limits_io_opt(limits, chunk_size_bytes * mddev_data_stripes(rs));
 }
 
+static void raid_presuspend(struct dm_target *ti)
+{
+	struct raid_set *rs = ti->private;
+	struct mddev *mddev = &rs->md;
+
+	/*
+	 * From now on, disallow raid_message() to change sync_thread until
+	 * resume, raid_postsuspend() is too late.
+	 */
+	set_bit(RT_FLAG_RS_FROZEN, &rs->runtime_flags);
+
+	if (!reshape_interrupted(mddev))
+		return;
+
+	/*
+	 * For raid456, if reshape is interrupted, IO across reshape position
+	 * will never make progress, while caller will wait for IO to be done.
+	 * Inform raid456 to handle those IO to prevent deadlock.
+	 */
+	if (mddev->pers && mddev->pers->prepare_suspend)
+		mddev->pers->prepare_suspend(mddev);
+}
+
+static void raid_presuspend_undo(struct dm_target *ti)
+{
+	struct raid_set *rs = ti->private;
+
+	clear_bit(RT_FLAG_RS_FROZEN, &rs->runtime_flags);
+}
+
 static void raid_postsuspend(struct dm_target *ti)
 {
 	struct raid_set *rs = ti->private;
 
 	if (!test_and_set_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) {
-		/* Writes have to be stopped before suspending to avoid deadlocks. */
-		if (!test_bit(MD_RECOVERY_FROZEN, &rs->md.recovery))
-			md_stop_writes(&rs->md);
-
+		/*
+		 * sync_thread must be stopped during suspend, and writes have
+		 * to be stopped before suspending to avoid deadlocks.
+		 */
+		md_stop_writes(&rs->md);
 		mddev_suspend(&rs->md, false);
 	}
 }
@@ -4012,8 +4058,6 @@
 	}
 
 	/* Check for any resize/reshape on @rs and adjust/initiate */
-	/* Be prepared for mddev_resume() in raid_resume() */
-	set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
 	if (mddev->recovery_cp && mddev->recovery_cp < MaxSector) {
 		set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
 		mddev->resync_min = mddev->recovery_cp;
@@ -4047,7 +4091,9 @@
 		 * Take this opportunity to check whether any failed
 		 * devices are reachable again.
 		 */
+		mddev_lock_nointr(mddev);
 		attempt_restore_of_faulty_devices(rs);
+		mddev_unlock(mddev);
 	}
 
 	if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) {
@@ -4056,9 +4102,13 @@
 			rs_set_capacity(rs);
 
 		mddev_lock_nointr(mddev);
-		clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+		WARN_ON_ONCE(!test_bit(MD_RECOVERY_FROZEN, &mddev->recovery));
+		WARN_ON_ONCE(rcu_dereference_protected(mddev->sync_thread,
+						       lockdep_is_held(&mddev->reconfig_mutex)));
+		clear_bit(RT_FLAG_RS_FROZEN, &rs->runtime_flags);
 		mddev->ro = 0;
 		mddev->in_sync = 0;
+		md_unfrozen_sync_thread(mddev);
 		mddev_unlock_and_resume(mddev);
 	}
 }
@@ -4074,6 +4124,8 @@
 	.message = raid_message,
 	.iterate_devices = raid_iterate_devices,
 	.io_hints = raid_io_hints,
+	.presuspend = raid_presuspend,
+	.presuspend_undo = raid_presuspend_undo,
 	.postsuspend = raid_postsuspend,
 	.preresume = raid_preresume,
 	.resume = raid_resume,
--- linux-qcom-6.8.0.orig/drivers/md/dm-raid1.c
+++ linux-qcom-6.8.0/drivers/md/dm-raid1.c
@@ -278,7 +278,7 @@
 	}
 
 	error_bits = -1;
-	dm_io(&io_req, ms->nr_mirrors, io, &error_bits);
+	dm_io(&io_req, ms->nr_mirrors, io, &error_bits, IOPRIO_DEFAULT);
 	if (unlikely(error_bits != 0)) {
 		for (i = 0; i < ms->nr_mirrors; i++)
 			if (test_bit(i, &error_bits))
@@ -554,7 +554,7 @@
 
 	map_region(&io, m, bio);
 	bio_set_m(bio, m);
-	BUG_ON(dm_io(&io_req, 1, &io, NULL));
+	BUG_ON(dm_io(&io_req, 1, &io, NULL, IOPRIO_DEFAULT));
 }
 
 static inline int region_in_sync(struct mirror_set *ms, region_t region,
@@ -681,7 +681,7 @@
 	 */
 	bio_set_m(bio, get_default_mirror(ms));
 
-	BUG_ON(dm_io(&io_req, ms->nr_mirrors, io, NULL));
+	BUG_ON(dm_io(&io_req, ms->nr_mirrors, io, NULL, IOPRIO_DEFAULT));
 }
 
 static void do_writes(struct mirror_set *ms, struct bio_list *writes)
--- linux-qcom-6.8.0.orig/drivers/md/dm-rq.c
+++ linux-qcom-6.8.0/drivers/md/dm-rq.c
@@ -496,8 +496,10 @@
 
 		map = dm_get_live_table(md, &srcu_idx);
 		if (unlikely(!map)) {
+			DMERR_LIMIT("%s: mapping table unavailable, erroring io",
+				    dm_device_name(md));
 			dm_put_live_table(md, srcu_idx);
-			return BLK_STS_RESOURCE;
+			return BLK_STS_IOERR;
 		}
 		ti = dm_table_find_target(map, 0);
 		dm_put_live_table(md, srcu_idx);
--- linux-qcom-6.8.0.orig/drivers/md/dm-snap-persistent.c
+++ linux-qcom-6.8.0/drivers/md/dm-snap-persistent.c
@@ -223,7 +223,7 @@
 {
 	struct mdata_req *req = container_of(work, struct mdata_req, work);
 
-	req->result = dm_io(req->io_req, 1, req->where, NULL);
+	req->result = dm_io(req->io_req, 1, req->where, NULL, IOPRIO_DEFAULT);
 }
 
 /*
@@ -247,7 +247,7 @@
 	struct mdata_req req;
 
 	if (!metadata)
-		return dm_io(&io_req, 1, &where, NULL);
+		return dm_io(&io_req, 1, &where, NULL, IOPRIO_DEFAULT);
 
 	req.where = &where;
 	req.io_req = &io_req;
--- linux-qcom-6.8.0.orig/drivers/md/dm-snap.c
+++ linux-qcom-6.8.0/drivers/md/dm-snap.c
@@ -684,8 +684,10 @@
 	for (i = 0; i < size; i++) {
 		slot = et->table + i;
 
-		hlist_bl_for_each_entry_safe(ex, pos, n, slot, hash_list)
+		hlist_bl_for_each_entry_safe(ex, pos, n, slot, hash_list) {
 			kmem_cache_free(mem, ex);
+			cond_resched();
+		}
 	}
 
 	kvfree(et->table);
--- linux-qcom-6.8.0.orig/drivers/md/dm-table.c
+++ linux-qcom-6.8.0/drivers/md/dm-table.c
@@ -1315,6 +1315,7 @@
 	profile->max_dun_bytes_supported = UINT_MAX;
 	memset(profile->modes_supported, 0xFF,
 	       sizeof(profile->modes_supported));
+	profile->key_types_supported = ~0;
 
 	for (i = 0; i < t->num_targets; i++) {
 		struct dm_target *ti = dm_table_get_target(t, i);
--- linux-qcom-6.8.0.orig/drivers/md/dm-thin.c
+++ linux-qcom-6.8.0/drivers/md/dm-thin.c
@@ -2334,10 +2334,9 @@
 	struct thin_c *tc = NULL;
 
 	rcu_read_lock();
-	if (!list_empty(&pool->active_thins)) {
-		tc = list_entry_rcu(pool->active_thins.next, struct thin_c, list);
+	tc = list_first_or_null_rcu(&pool->active_thins, struct thin_c, list);
+	if (tc)
 		thin_get(tc);
-	}
 	rcu_read_unlock();
 
 	return tc;
@@ -2486,6 +2485,7 @@
 	init_completion(&pw->complete);
 	queue_work(pool->wq, &pw->worker);
 	wait_for_completion(&pw->complete);
+	destroy_work_on_stack(&pw->worker);
 }
 
 /*----------------------------------------------------------------*/
--- linux-qcom-6.8.0.orig/drivers/md/dm-unstripe.c
+++ linux-qcom-6.8.0/drivers/md/dm-unstripe.c
@@ -85,8 +85,8 @@
 	}
 	uc->physical_start = start;
 
-	uc->unstripe_offset = uc->unstripe * uc->chunk_size;
-	uc->unstripe_width = (uc->stripes - 1) * uc->chunk_size;
+	uc->unstripe_offset = (sector_t)uc->unstripe * uc->chunk_size;
+	uc->unstripe_width = (sector_t)(uc->stripes - 1) * uc->chunk_size;
 	uc->chunk_shift = is_power_of_2(uc->chunk_size) ? fls(uc->chunk_size) - 1 : 0;
 
 	tmp_len = ti->len;
--- linux-qcom-6.8.0.orig/drivers/md/dm-verity-fec.c
+++ linux-qcom-6.8.0/drivers/md/dm-verity-fec.c
@@ -60,14 +60,19 @@
  * to the data block. Caller is responsible for releasing buf.
  */
 static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int index,
-			   unsigned int *offset, struct dm_buffer **buf)
+			   unsigned int *offset, unsigned int par_buf_offset,
+			  struct dm_buffer **buf)
 {
 	u64 position, block, rem;
 	u8 *res;
 
+	/* We have already part of parity bytes read, skip to the next block */
+	if (par_buf_offset)
+		index++;
+
 	position = (index + rsb) * v->fec->roots;
 	block = div64_u64_rem(position, v->fec->io_size, &rem);
-	*offset = (unsigned int)rem;
+	*offset = par_buf_offset ? 0 : (unsigned int)rem;
 
 	res = dm_bufio_read(v->fec->bufio, block, buf);
 	if (IS_ERR(res)) {
@@ -127,10 +132,11 @@
 {
 	int r, corrected = 0, res;
 	struct dm_buffer *buf;
-	unsigned int n, i, offset;
-	u8 *par, *block;
+	unsigned int n, i, offset, par_buf_offset = 0;
+	u8 *par, *block, par_buf[DM_VERITY_FEC_RSM - DM_VERITY_FEC_MIN_RSN];
 
-	par = fec_read_parity(v, rsb, block_offset, &offset, &buf);
+	par = fec_read_parity(v, rsb, block_offset, &offset,
+			      par_buf_offset, &buf);
 	if (IS_ERR(par))
 		return PTR_ERR(par);
 
@@ -140,7 +146,8 @@
 	 */
 	fec_for_each_buffer_rs_block(fio, n, i) {
 		block = fec_buffer_rs_block(v, fio, n, i);
-		res = fec_decode_rs8(v, fio, block, &par[offset], neras);
+		memcpy(&par_buf[par_buf_offset], &par[offset], v->fec->roots - par_buf_offset);
+		res = fec_decode_rs8(v, fio, block, par_buf, neras);
 		if (res < 0) {
 			r = res;
 			goto error;
@@ -153,12 +160,21 @@
 		if (block_offset >= 1 << v->data_dev_block_bits)
 			goto done;
 
-		/* read the next block when we run out of parity bytes */
-		offset += v->fec->roots;
+		/* Read the next block when we run out of parity bytes */
+		offset += (v->fec->roots - par_buf_offset);
+		/* Check if parity bytes are split between blocks */
+		if (offset < v->fec->io_size && (offset + v->fec->roots) > v->fec->io_size) {
+			par_buf_offset = v->fec->io_size - offset;
+			memcpy(par_buf, &par[offset], par_buf_offset);
+			offset += par_buf_offset;
+		} else
+			par_buf_offset = 0;
+
 		if (offset >= v->fec->io_size) {
 			dm_bufio_release(buf);
 
-			par = fec_read_parity(v, rsb, block_offset, &offset, &buf);
+			par = fec_read_parity(v, rsb, block_offset, &offset,
+					      par_buf_offset, &buf);
 			if (IS_ERR(par))
 				return PTR_ERR(par);
 		}
@@ -743,10 +759,7 @@
 		return -E2BIG;
 	}
 
-	if ((f->roots << SECTOR_SHIFT) & ((1 << v->data_dev_block_bits) - 1))
-		f->io_size = 1 << v->data_dev_block_bits;
-	else
-		f->io_size = v->fec->roots << SECTOR_SHIFT;
+	f->io_size = 1 << v->data_dev_block_bits;
 
 	f->bufio = dm_bufio_client_create(f->dev->bdev,
 					  f->io_size,
--- linux-qcom-6.8.0.orig/drivers/md/dm-verity-target.c
+++ linux-qcom-6.8.0/drivers/md/dm-verity-target.c
@@ -511,7 +511,7 @@
 	io_loc.bdev = v->data_dev->bdev;
 	io_loc.sector = cur_block << (v->data_dev_block_bits - SECTOR_SHIFT);
 	io_loc.count = 1 << (v->data_dev_block_bits - SECTOR_SHIFT);
-	r = dm_io(&io_req, 1, &io_loc, NULL);
+	r = dm_io(&io_req, 1, &io_loc, NULL, IOPRIO_DEFAULT);
 	if (unlikely(r))
 		goto free_ret;
 
@@ -1512,14 +1512,6 @@
 }
 
 /*
- * Check whether a DM target is a verity target.
- */
-bool dm_is_verity_target(struct dm_target *ti)
-{
-	return ti->type->module == THIS_MODULE;
-}
-
-/*
  * Get the verity mode (error behavior) of a verity target.
  *
  * Returns the verity mode of the target, or -EINVAL if 'ti' is not a verity
@@ -1572,6 +1564,14 @@
 };
 module_dm(verity);
 
+/*
+ * Check whether a DM target is a verity target.
+ */
+bool dm_is_verity_target(struct dm_target *ti)
+{
+	return ti->type == &verity_target;
+}
+
 MODULE_AUTHOR("Mikulas Patocka <mpatocka@redhat.com>");
 MODULE_AUTHOR("Mandeep Baines <msb@chromium.org>");
 MODULE_AUTHOR("Will Drewry <wad@chromium.org>");
--- linux-qcom-6.8.0.orig/drivers/md/dm-writecache.c
+++ linux-qcom-6.8.0/drivers/md/dm-writecache.c
@@ -531,7 +531,7 @@
 		req.notify.context = &endio;
 
 		/* writing via async dm-io (implied by notify.fn above) won't return an error */
-		(void) dm_io(&req, 1, &region, NULL);
+		(void) dm_io(&req, 1, &region, NULL, IOPRIO_DEFAULT);
 		i = j;
 	}
 
@@ -568,7 +568,7 @@
 	req.notify.fn = NULL;
 	req.notify.context = NULL;
 
-	r = dm_io(&req, 1, &region, NULL);
+	r = dm_io(&req, 1, &region, NULL, IOPRIO_DEFAULT);
 	if (unlikely(r))
 		writecache_error(wc, r, "error writing superblock");
 }
@@ -596,7 +596,7 @@
 	req.client = wc->dm_io;
 	req.notify.fn = NULL;
 
-	r = dm_io(&req, 1, &region, NULL);
+	r = dm_io(&req, 1, &region, NULL, IOPRIO_DEFAULT);
 	if (unlikely(r))
 		writecache_error(wc, r, "error flushing metadata: %d", r);
 }
@@ -990,7 +990,7 @@
 	req.client = wc->dm_io;
 	req.notify.fn = NULL;
 
-	return dm_io(&req, 1, &region, NULL);
+	return dm_io(&req, 1, &region, NULL, IOPRIO_DEFAULT);
 }
 
 static void writecache_resume(struct dm_target *ti)
--- linux-qcom-6.8.0.orig/drivers/md/dm.c
+++ linux-qcom-6.8.0/drivers/md/dm.c
@@ -1844,10 +1844,15 @@
 	struct dm_table *map;
 
 	map = dm_get_live_table(md, &srcu_idx);
+	if (unlikely(!map)) {
+		DMERR_LIMIT("%s: mapping table unavailable, erroring io",
+			    dm_device_name(md));
+		bio_io_error(bio);
+		goto out;
+	}
 
-	/* If suspended, or map not yet available, queue this IO for later */
-	if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) ||
-	    unlikely(!map)) {
+	/* If suspended, queue this IO for later */
+	if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags))) {
 		if (bio->bi_opf & REQ_NOWAIT)
 			bio_wouldblock_error(bio);
 		else if (bio->bi_opf & REQ_RAHEAD)
@@ -2558,7 +2563,7 @@
 			break;
 
 		if (signal_pending_state(task_state, current)) {
-			r = -EINTR;
+			r = -ERESTARTSYS;
 			break;
 		}
 
@@ -2583,7 +2588,7 @@
 			break;
 
 		if (signal_pending_state(task_state, current)) {
-			r = -EINTR;
+			r = -ERESTARTSYS;
 			break;
 		}
 
@@ -2945,6 +2950,9 @@
 
 static void __dm_internal_resume(struct mapped_device *md)
 {
+	int r;
+	struct dm_table *map;
+
 	BUG_ON(!md->internal_suspend_count);
 
 	if (--md->internal_suspend_count)
@@ -2953,12 +2961,23 @@
 	if (dm_suspended_md(md))
 		goto done; /* resume from nested suspend */
 
-	/*
-	 * NOTE: existing callers don't need to call dm_table_resume_targets
-	 * (which may fail -- so best to avoid it for now by passing NULL map)
-	 */
-	(void) __dm_resume(md, NULL);
-
+	map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock));
+	r = __dm_resume(md, map);
+	if (r) {
+		/*
+		 * If a preresume method of some target failed, we are in a
+		 * tricky situation. We can't return an error to the caller. We
+		 * can't fake success because then the "resume" and
+		 * "postsuspend" methods would not be paired correctly, and it
+		 * would break various targets, for example it would cause list
+		 * corruption in the "origin" target.
+		 *
+		 * So, we fake normal suspend here, to make sure that the
+		 * "resume" and "postsuspend" methods will be paired correctly.
+		 */
+		DMERR("Preresume method failed: %d", r);
+		set_bit(DMF_SUSPENDED, &md->flags);
+	}
 done:
 	clear_bit(DMF_SUSPENDED_INTERNALLY, &md->flags);
 	smp_mb__after_atomic();
--- linux-qcom-6.8.0.orig/drivers/md/md-bitmap.c
+++ linux-qcom-6.8.0/drivers/md/md-bitmap.c
@@ -227,6 +227,8 @@
 	struct block_device *bdev;
 	struct mddev *mddev = bitmap->mddev;
 	struct bitmap_storage *store = &bitmap->storage;
+	unsigned int bitmap_limit = (bitmap->storage.file_pages - pg_index) <<
+		PAGE_SHIFT;
 	loff_t sboff, offset = mddev->bitmap_info.offset;
 	sector_t ps = pg_index * PAGE_SIZE / SECTOR_SIZE;
 	unsigned int size = PAGE_SIZE;
@@ -234,7 +236,8 @@
 	sector_t doff;
 
 	bdev = (rdev->meta_bdev) ? rdev->meta_bdev : rdev->bdev;
-	if (pg_index == store->file_pages - 1) {
+	/* we compare length (page numbers), not page offset. */
+	if ((pg_index - store->sb_index) == store->file_pages - 1) {
 		unsigned int last_page_size = store->bytes & (PAGE_SIZE - 1);
 
 		if (last_page_size == 0)
@@ -268,11 +271,9 @@
 		if (size == 0)
 			/* bitmap runs in to data */
 			return -EINVAL;
-	} else {
-		/* DATA METADATA BITMAP - no problems */
 	}
 
-	md_super_write(mddev, rdev, sboff + ps, (int) size, page);
+	md_super_write(mddev, rdev, sboff + ps, (int)min(size, bitmap_limit), page);
 	return 0;
 }
 
@@ -438,8 +439,8 @@
 	struct page *page = store->filemap[pg_index];
 
 	if (mddev_is_clustered(bitmap->mddev)) {
-		pg_index += bitmap->cluster_slot *
-			DIV_ROUND_UP(store->bytes, PAGE_SIZE);
+		/* go to node bitmap area starting point */
+		pg_index += store->sb_index;
 	}
 
 	if (store->file)
@@ -952,6 +953,7 @@
 	unsigned long index = file_page_index(store, chunk);
 	unsigned long node_offset = 0;
 
+	index += store->sb_index;
 	if (mddev_is_clustered(bitmap->mddev))
 		node_offset = bitmap->cluster_slot * store->file_pages;
 
@@ -982,6 +984,7 @@
 	unsigned long index = file_page_index(store, chunk);
 	unsigned long node_offset = 0;
 
+	index += store->sb_index;
 	if (mddev_is_clustered(bitmap->mddev))
 		node_offset = bitmap->cluster_slot * store->file_pages;
 
@@ -1086,6 +1089,7 @@
 
 	queue_work(md_bitmap_wq, &unplug_work.work);
 	wait_for_completion(&done);
+	destroy_work_on_stack(&unplug_work.work);
 }
 EXPORT_SYMBOL(md_bitmap_unplug_async);
 
@@ -1424,7 +1428,7 @@
 	sector_t chunk = offset >> bitmap->chunkshift;
 	unsigned long page = chunk >> PAGE_COUNTER_SHIFT;
 	unsigned long pageoff = (chunk & PAGE_COUNTER_MASK) << COUNTER_BYTE_SHIFT;
-	sector_t csize;
+	sector_t csize = ((sector_t)1) << bitmap->chunkshift;
 	int err;
 
 	if (page >= bitmap->pages) {
@@ -1433,6 +1437,7 @@
 		 * End-of-device while looking for a whole page or
 		 * user set a huge number to sysfs bitmap_set_bits.
 		 */
+		*blocks = csize - (offset & (csize - 1));
 		return NULL;
 	}
 	err = md_bitmap_checkpage(bitmap, page, create, 0);
@@ -1441,8 +1446,7 @@
 	    bitmap->bp[page].map == NULL)
 		csize = ((sector_t)1) << (bitmap->chunkshift +
 					  PAGE_COUNTER_SHIFT);
-	else
-		csize = ((sector_t)1) << bitmap->chunkshift;
+
 	*blocks = csize - (offset & (csize - 1));
 
 	if (err < 0)
--- linux-qcom-6.8.0.orig/drivers/md/md-cluster.c
+++ linux-qcom-6.8.0/drivers/md/md-cluster.c
@@ -15,6 +15,7 @@
 
 #define LVB_SIZE	64
 #define NEW_DEV_TIMEOUT 5000
+#define WAIT_DLM_LOCK_TIMEOUT (30 * HZ)
 
 struct dlm_lock_resource {
 	dlm_lockspace_t *ls;
@@ -130,8 +131,13 @@
 			0, sync_ast, res, res->bast);
 	if (ret)
 		return ret;
-	wait_event(res->sync_locking, res->sync_locking_done);
+	ret = wait_event_timeout(res->sync_locking, res->sync_locking_done,
+				WAIT_DLM_LOCK_TIMEOUT);
 	res->sync_locking_done = false;
+	if (!ret) {
+		pr_err("locking DLM '%s' timeout!\n", res->name);
+		return -EBUSY;
+	}
 	if (res->lksb.sb_status == 0)
 		res->mode = mode;
 	return res->lksb.sb_status;
@@ -743,7 +749,7 @@
  */
 static int __sendmsg(struct md_cluster_info *cinfo, struct cluster_msg *cmsg)
 {
-	int error;
+	int error, unlock_error;
 	int slot = cinfo->slot_number - 1;
 
 	cmsg->slot = cpu_to_le32(slot);
@@ -751,7 +757,7 @@
 	error = dlm_lock_sync(cinfo->message_lockres, DLM_LOCK_EX);
 	if (error) {
 		pr_err("md-cluster: failed to get EX on MESSAGE (%d)\n", error);
-		goto failed_message;
+		return error;
 	}
 
 	memcpy(cinfo->message_lockres->lksb.sb_lvbptr, (void *)cmsg,
@@ -781,14 +787,10 @@
 	}
 
 failed_ack:
-	error = dlm_unlock_sync(cinfo->message_lockres);
-	if (unlikely(error != 0)) {
+	while ((unlock_error = dlm_unlock_sync(cinfo->message_lockres)))
 		pr_err("md-cluster: failed convert to NL on MESSAGE(%d)\n",
-			error);
-		/* in case the message can't be released due to some reason */
-		goto failed_ack;
-	}
-failed_message:
+			unlock_error);
+
 	return error;
 }
 
--- linux-qcom-6.8.0.orig/drivers/md/md.c
+++ linux-qcom-6.8.0/drivers/md/md.c
@@ -99,18 +99,6 @@
 static void export_rdev(struct md_rdev *rdev, struct mddev *mddev);
 static void md_wakeup_thread_directly(struct md_thread __rcu *thread);
 
-enum md_ro_state {
-	MD_RDWR,
-	MD_RDONLY,
-	MD_AUTO_READ,
-	MD_MAX_STATE
-};
-
-static bool md_is_rdwr(struct mddev *mddev)
-{
-	return (mddev->ro == MD_RDWR);
-}
-
 /*
  * Default number of read corrections we'll attempt on an rdev
  * before ejecting it from the array. We divide the read error
@@ -378,7 +366,7 @@
 	return true;
 }
 
-void md_handle_request(struct mddev *mddev, struct bio *bio)
+bool md_handle_request(struct mddev *mddev, struct bio *bio)
 {
 check_suspended:
 	if (is_suspended(mddev, bio)) {
@@ -386,7 +374,7 @@
 		/* Bail out if REQ_NOWAIT is set for the bio */
 		if (bio->bi_opf & REQ_NOWAIT) {
 			bio_wouldblock_error(bio);
-			return;
+			return true;
 		}
 		for (;;) {
 			prepare_to_wait(&mddev->sb_wait, &__wait,
@@ -402,10 +390,13 @@
 
 	if (!mddev->pers->make_request(mddev, bio)) {
 		percpu_ref_put(&mddev->active_io);
+		if (!mddev->gendisk && mddev->pers->prepare_suspend)
+			return false;
 		goto check_suspended;
 	}
 
 	percpu_ref_put(&mddev->active_io);
+	return true;
 }
 EXPORT_SYMBOL(md_handle_request);
 
@@ -489,7 +480,6 @@
 	 */
 	WRITE_ONCE(mddev->suspended, mddev->suspended + 1);
 
-	del_timer_sync(&mddev->safemode_timer);
 	/* restrict memory reclaim I/O during raid array is suspend */
 	mddev->noio_flag = memalloc_noio_save();
 
@@ -542,13 +532,9 @@
 
 	rdev_dec_pending(rdev, mddev);
 
-	if (atomic_dec_and_test(&mddev->flush_pending)) {
-		/* The pair is percpu_ref_get() from md_flush_request() */
-		percpu_ref_put(&mddev->active_io);
-
+	if (atomic_dec_and_test(&mddev->flush_pending))
 		/* The pre-request flush has finished */
 		queue_work(md_wq, &mddev->flush_work);
-	}
 }
 
 static void md_submit_flush_data(struct work_struct *ws);
@@ -579,12 +565,8 @@
 			rcu_read_lock();
 		}
 	rcu_read_unlock();
-	if (atomic_dec_and_test(&mddev->flush_pending)) {
-		/* The pair is percpu_ref_get() from md_flush_request() */
-		percpu_ref_put(&mddev->active_io);
-
+	if (atomic_dec_and_test(&mddev->flush_pending))
 		queue_work(md_wq, &mddev->flush_work);
-	}
 }
 
 static void md_submit_flush_data(struct work_struct *ws)
@@ -609,8 +591,20 @@
 		bio_endio(bio);
 	} else {
 		bio->bi_opf &= ~REQ_PREFLUSH;
-		md_handle_request(mddev, bio);
+
+		/*
+		 * make_requst() will never return error here, it only
+		 * returns error in raid5_make_request() by dm-raid.
+		 * Since dm always splits data and flush operation into
+		 * two separate io, io size of flush submitted by dm
+		 * always is 0, make_request() will not be called here.
+		 */
+		if (WARN_ON_ONCE(!mddev->pers->make_request(mddev, bio)))
+			bio_io_error(bio);;
 	}
+
+	/* The pair is percpu_ref_get() from md_flush_request() */
+	percpu_ref_put(&mddev->active_io);
 }
 
 /*
@@ -2566,6 +2560,7 @@
  fail:
 	pr_warn("md: failed to register dev-%s for %s\n",
 		b, mdname(mddev));
+	mddev_destroy_serial_pool(mddev, rdev);
 	return err;
 }
 
@@ -4919,6 +4914,35 @@
 		mddev_lock_nointr(mddev);
 }
 
+void md_idle_sync_thread(struct mddev *mddev)
+{
+	lockdep_assert_held(&mddev->reconfig_mutex);
+
+	clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+	stop_sync_thread(mddev, true, true);
+}
+EXPORT_SYMBOL_GPL(md_idle_sync_thread);
+
+void md_frozen_sync_thread(struct mddev *mddev)
+{
+	lockdep_assert_held(&mddev->reconfig_mutex);
+
+	set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+	stop_sync_thread(mddev, true, false);
+}
+EXPORT_SYMBOL_GPL(md_frozen_sync_thread);
+
+void md_unfrozen_sync_thread(struct mddev *mddev)
+{
+	lockdep_assert_held(&mddev->reconfig_mutex);
+
+	clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+	set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+	md_wakeup_thread(mddev->thread);
+	sysfs_notify_dirent_safe(mddev->sysfs_action);
+}
+EXPORT_SYMBOL_GPL(md_unfrozen_sync_thread);
+
 static void idle_sync_thread(struct mddev *mddev)
 {
 	mutex_lock(&mddev->sync_mutex);
@@ -6038,7 +6062,10 @@
 			pr_warn("True protection against single-disk failure might be compromised.\n");
 	}
 
-	mddev->recovery = 0;
+	/* dm-raid expect sync_thread to be frozen until resume */
+	if (mddev->gendisk)
+		mddev->recovery = 0;
+
 	/* may be over-ridden by personality */
 	mddev->resync_max_sectors = mddev->dev_sectors;
 
@@ -6278,7 +6305,15 @@
 	mddev->persistent = 0;
 	mddev->level = LEVEL_NONE;
 	mddev->clevel[0] = 0;
-	mddev->flags = 0;
+	/*
+	 * Don't clear MD_CLOSING, or mddev can be opened again.
+	 * 'hold_active != 0' means mddev is still in the creation
+	 * process and will be used later.
+	 */
+	if (mddev->hold_active)
+		mddev->flags = 0;
+	else
+		mddev->flags &= BIT_ULL_MASK(MD_CLOSING);
 	mddev->sb_flags = 0;
 	mddev->ro = MD_RDWR;
 	mddev->metadata_type[0] = 0;
@@ -6315,7 +6350,6 @@
 
 static void __md_stop_writes(struct mddev *mddev)
 {
-	stop_sync_thread(mddev, true, false);
 	del_timer_sync(&mddev->safemode_timer);
 
 	if (mddev->pers && mddev->pers->quiesce) {
@@ -6340,6 +6374,8 @@
 void md_stop_writes(struct mddev *mddev)
 {
 	mddev_lock_nointr(mddev);
+	set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+	stop_sync_thread(mddev, true, false);
 	__md_stop_writes(mddev);
 	mddev_unlock(mddev);
 }
@@ -7624,7 +7660,6 @@
 	int err = 0;
 	void __user *argp = (void __user *)arg;
 	struct mddev *mddev = NULL;
-	bool did_set_md_closing = false;
 
 	if (!md_ioctl_valid(cmd))
 		return -ENOTTY;
@@ -7656,11 +7691,6 @@
 
 	mddev = bdev->bd_disk->private_data;
 
-	if (!mddev) {
-		BUG();
-		goto out;
-	}
-
 	/* Some actions do not requires the mutex */
 	switch (cmd) {
 	case GET_ARRAY_INFO:
@@ -7687,12 +7717,6 @@
 
 	}
 
-	if (cmd == HOT_REMOVE_DISK)
-		/* need to ensure recovery thread has run */
-		wait_event_interruptible_timeout(mddev->sb_wait,
-						 !test_bit(MD_RECOVERY_NEEDED,
-							   &mddev->recovery),
-						 msecs_to_jiffies(5000));
 	if (cmd == STOP_ARRAY || cmd == STOP_ARRAY_RO) {
 		/* Need to flush page cache, and ensure no-one else opens
 		 * and writes
@@ -7708,7 +7732,6 @@
 			err = -EBUSY;
 			goto out;
 		}
-		did_set_md_closing = true;
 		mutex_unlock(&mddev->open_mutex);
 		sync_blockdev(bdev);
 	}
@@ -7850,7 +7873,7 @@
 				     mddev_unlock(mddev);
 
 out:
-	if(did_set_md_closing)
+	if (cmd == STOP_ARRAY_RO || (err && cmd == STOP_ARRAY))
 		clear_bit(MD_CLOSING, &mddev->flags);
 	return err;
 }
@@ -8591,17 +8614,16 @@
  * A return value of 'false' means that the write wasn't recorded
  * and cannot proceed as the array is being suspend.
  */
-bool md_write_start(struct mddev *mddev, struct bio *bi)
+void md_write_start(struct mddev *mddev, struct bio *bi)
 {
 	int did_change = 0;
 
 	if (bio_data_dir(bi) != WRITE)
-		return true;
+		return;
 
 	BUG_ON(mddev->ro == MD_RDONLY);
 	if (mddev->ro == MD_AUTO_READ) {
 		/* need to switch to read/write */
-		flush_work(&mddev->sync_work);
 		mddev->ro = MD_RDWR;
 		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 		md_wakeup_thread(mddev->thread);
@@ -8629,15 +8651,9 @@
 	if (did_change)
 		sysfs_notify_dirent_safe(mddev->sysfs_state);
 	if (!mddev->has_superblocks)
-		return true;
+		return;
 	wait_event(mddev->sb_wait,
-		   !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags) ||
-		   is_md_suspended(mddev));
-	if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) {
-		percpu_ref_put(&mddev->writes_pending);
-		return false;
-	}
-	return true;
+		   !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags));
 }
 EXPORT_SYMBOL(md_write_start);
 
@@ -8737,6 +8753,23 @@
 }
 EXPORT_SYMBOL_GPL(md_account_bio);
 
+void md_free_cloned_bio(struct bio *bio)
+{
+	struct md_io_clone *md_io_clone = bio->bi_private;
+	struct bio *orig_bio = md_io_clone->orig_bio;
+	struct mddev *mddev = md_io_clone->mddev;
+
+	if (bio->bi_status && !orig_bio->bi_status)
+		orig_bio->bi_status = bio->bi_status;
+
+	if (md_io_clone->start_time)
+		bio_end_io_acct(orig_bio, md_io_clone->start_time);
+
+	bio_put(bio);
+	percpu_ref_put(&mddev->active_io);
+}
+EXPORT_SYMBOL_GPL(md_free_cloned_bio);
+
 /* md_allow_write(mddev)
  * Calling this ensures that the array is marked 'active' so that writes
  * may proceed without blocking.  It is important to call this before
@@ -9270,9 +9303,14 @@
 {
 	struct md_rdev *rdev;
 
-	rdev_for_each(rdev, mddev)
-		if (rdev_removeable(rdev) || rdev_addable(rdev))
+	rcu_read_lock();
+	rdev_for_each_rcu(rdev, mddev) {
+		if (rdev_removeable(rdev) || rdev_addable(rdev)) {
+			rcu_read_unlock();
 			return true;
+		}
+	}
+	rcu_read_unlock();
 	return false;
 }
 
--- linux-qcom-6.8.0.orig/drivers/md/md.h
+++ linux-qcom-6.8.0/drivers/md/md.h
@@ -207,6 +207,7 @@
 				 * check if there is collision between raid1
 				 * serial bios.
 				 */
+	Nonrot,			/* non-rotational device (SSD) */
 };
 
 static inline int is_badblock(struct md_rdev *rdev, sector_t s, int sectors,
@@ -558,6 +559,37 @@
 	MD_RESYNCING_REMOTE,	/* remote node is running resync thread */
 };
 
+enum md_ro_state {
+	MD_RDWR,
+	MD_RDONLY,
+	MD_AUTO_READ,
+	MD_MAX_STATE
+};
+
+static inline bool md_is_rdwr(struct mddev *mddev)
+{
+	return (mddev->ro == MD_RDWR);
+}
+
+static inline bool reshape_interrupted(struct mddev *mddev)
+{
+	/* reshape never start */
+	if (mddev->reshape_position == MaxSector)
+		return false;
+
+	/* interrupted */
+	if (!test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
+		return true;
+
+	/* running reshape will be interrupted soon. */
+	if (test_bit(MD_RECOVERY_WAIT, &mddev->recovery) ||
+	    test_bit(MD_RECOVERY_INTR, &mddev->recovery) ||
+	    test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
+		return true;
+
+	return false;
+}
+
 static inline int __must_check mddev_lock(struct mddev *mddev)
 {
 	return mutex_lock_interruptible(&mddev->reconfig_mutex);
@@ -617,6 +649,7 @@
 	int (*start_reshape) (struct mddev *mddev);
 	void (*finish_reshape) (struct mddev *mddev);
 	void (*update_reshape_pos) (struct mddev *mddev);
+	void (*prepare_suspend) (struct mddev *mddev);
 	/* quiesce suspends or resumes internal processing.
 	 * 1 - stop new actions and wait for action io to complete
 	 * 0 - return to normal behaviour
@@ -634,6 +667,9 @@
 	void *(*takeover) (struct mddev *mddev);
 	/* Changes the consistency policy of an active array. */
 	int (*change_consistency_policy)(struct mddev *mddev, const char *buf);
+	/* convert io ranges from array to bitmap */
+	void (*bitmap_sector)(struct mddev *mddev, sector_t *offset,
+			      unsigned long *sectors);
 };
 
 struct md_sysfs_entry {
@@ -741,7 +777,7 @@
 extern void md_wakeup_thread(struct md_thread __rcu *thread);
 extern void md_check_recovery(struct mddev *mddev);
 extern void md_reap_sync_thread(struct mddev *mddev);
-extern bool md_write_start(struct mddev *mddev, struct bio *bi);
+extern void md_write_start(struct mddev *mddev, struct bio *bi);
 extern void md_write_inc(struct mddev *mddev, struct bio *bi);
 extern void md_write_end(struct mddev *mddev);
 extern void md_done_sync(struct mddev *mddev, int blocks, int ok);
@@ -750,6 +786,7 @@
 void md_submit_discard_bio(struct mddev *mddev, struct md_rdev *rdev,
 			struct bio *bio, sector_t start, sector_t size);
 void md_account_bio(struct mddev *mddev, struct bio **bio);
+void md_free_cloned_bio(struct bio *bio);
 
 extern bool __must_check md_flush_request(struct mddev *mddev, struct bio *bio);
 extern void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
@@ -778,9 +815,12 @@
 extern int md_rdev_init(struct md_rdev *rdev);
 extern void md_rdev_clear(struct md_rdev *rdev);
 
-extern void md_handle_request(struct mddev *mddev, struct bio *bio);
+extern bool md_handle_request(struct mddev *mddev, struct bio *bio);
 extern int mddev_suspend(struct mddev *mddev, bool interruptible);
 extern void mddev_resume(struct mddev *mddev);
+extern void md_idle_sync_thread(struct mddev *mddev);
+extern void md_frozen_sync_thread(struct mddev *mddev);
+extern void md_unfrozen_sync_thread(struct mddev *mddev);
 
 extern void md_reload_sb(struct mddev *mddev, int raid_disk);
 extern void md_update_sb(struct mddev *mddev, int force);
--- linux-qcom-6.8.0.orig/drivers/md/persistent-data/dm-array.c
+++ linux-qcom-6.8.0/drivers/md/persistent-data/dm-array.c
@@ -917,23 +917,27 @@
 	if (c->block)
 		unlock_ablock(c->info, c->block);
 
-	c->block = NULL;
-	c->ab = NULL;
 	c->index = 0;
 
 	r = dm_btree_cursor_get_value(&c->cursor, &key, &value_le);
 	if (r) {
 		DMERR("dm_btree_cursor_get_value failed");
-		dm_btree_cursor_end(&c->cursor);
+		goto out;
 
 	} else {
 		r = get_ablock(c->info, le64_to_cpu(value_le), &c->block, &c->ab);
 		if (r) {
 			DMERR("get_ablock failed");
-			dm_btree_cursor_end(&c->cursor);
+			goto out;
 		}
 	}
 
+	return 0;
+
+out:
+	dm_btree_cursor_end(&c->cursor);
+	c->block = NULL;
+	c->ab = NULL;
 	return r;
 }
 
@@ -956,10 +960,10 @@
 
 void dm_array_cursor_end(struct dm_array_cursor *c)
 {
-	if (c->block) {
+	if (c->block)
 		unlock_ablock(c->info, c->block);
-		dm_btree_cursor_end(&c->cursor);
-	}
+
+	dm_btree_cursor_end(&c->cursor);
 }
 EXPORT_SYMBOL_GPL(dm_array_cursor_end);
 
@@ -999,6 +1003,7 @@
 		}
 
 		count -= remaining;
+		c->index += (remaining - 1);
 		r = dm_array_cursor_next(c);
 
 	} while (!r);
--- linux-qcom-6.8.0.orig/drivers/md/persistent-data/dm-space-map-common.c
+++ linux-qcom-6.8.0/drivers/md/persistent-data/dm-space-map-common.c
@@ -51,7 +51,7 @@
 					       block_size - sizeof(__le32),
 					       INDEX_CSUM_XOR));
 	if (csum_disk != mi_le->csum) {
-		DMERR_LIMIT("i%s failed: csum %u != wanted %u", __func__,
+		DMERR_LIMIT("%s failed: csum %u != wanted %u", __func__,
 			    le32_to_cpu(csum_disk), le32_to_cpu(mi_le->csum));
 		return -EILSEQ;
 	}
--- linux-qcom-6.8.0.orig/drivers/md/persistent-data/dm-space-map-metadata.c
+++ linux-qcom-6.8.0/drivers/md/persistent-data/dm-space-map-metadata.c
@@ -277,7 +277,7 @@
 {
 	struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
 
-	kfree(smm);
+	kvfree(smm);
 }
 
 static int sm_metadata_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count)
@@ -772,7 +772,7 @@
 {
 	struct sm_metadata *smm;
 
-	smm = kmalloc(sizeof(*smm), GFP_KERNEL);
+	smm = kvmalloc(sizeof(*smm), GFP_KERNEL);
 	if (!smm)
 		return ERR_PTR(-ENOMEM);
 
--- linux-qcom-6.8.0.orig/drivers/md/raid0.c
+++ linux-qcom-6.8.0/drivers/md/raid0.c
@@ -263,11 +263,12 @@
 		   default_layout == RAID0_ALT_MULTIZONE_LAYOUT) {
 		conf->layout = default_layout;
 	} else {
-		pr_err("md/raid0:%s: cannot assemble multi-zone RAID0 with default_layout setting\n",
-		       mdname(mddev));
-		pr_err("md/raid0: please set raid0.default_layout to 1 or 2\n");
-		err = -EOPNOTSUPP;
-		goto abort;
+		conf->layout = RAID0_ALT_MULTIZONE_LAYOUT;
+		pr_warn("md/raid0:%s: !!! DEFAULTING TO ALTERNATE LAYOUT !!!\n",
+			mdname(mddev));
+		pr_warn("md/raid0: Please set raid0.default_layout to 1 or 2\n");
+		pr_warn("md/raid0: Read the following page for more information:\n");
+		pr_warn("md/raid0: https://wiki.ubuntu.com/Kernel/Raid0LayoutMigration\n");
 	}
 
 	if (conf->layout == RAID0_ORIG_LAYOUT) {
@@ -365,18 +366,13 @@
 	return array_sectors;
 }
 
-static void free_conf(struct mddev *mddev, struct r0conf *conf)
-{
-	kfree(conf->strip_zone);
-	kfree(conf->devlist);
-	kfree(conf);
-}
-
 static void raid0_free(struct mddev *mddev, void *priv)
 {
 	struct r0conf *conf = priv;
 
-	free_conf(mddev, conf);
+	kfree(conf->strip_zone);
+	kfree(conf->devlist);
+	kfree(conf);
 }
 
 static int raid0_run(struct mddev *mddev)
@@ -424,11 +420,7 @@
 
 	dump_zones(mddev);
 
-	ret = md_integrity_register(mddev);
-	if (ret)
-		free_conf(mddev, conf);
-
-	return ret;
+	return md_integrity_register(mddev);
 }
 
 /*
--- linux-qcom-6.8.0.orig/drivers/md/raid1.c
+++ linux-qcom-6.8.0/drivers/md/raid1.c
@@ -601,14 +601,12 @@
 	const sector_t this_sector = r1_bio->sector;
 	int sectors;
 	int best_good_sectors;
-	int best_disk, best_dist_disk, best_pending_disk;
-	int has_nonrot_disk;
+	int best_disk, best_dist_disk, best_pending_disk, sequential_disk;
 	int disk;
 	sector_t best_dist;
 	unsigned int min_pending;
 	struct md_rdev *rdev;
 	int choose_first;
-	int choose_next_idle;
 
 	/*
 	 * Check if we can balance. We can balance on the whole
@@ -619,12 +617,11 @@
 	sectors = r1_bio->sectors;
 	best_disk = -1;
 	best_dist_disk = -1;
+	sequential_disk = -1;
 	best_dist = MaxSector;
 	best_pending_disk = -1;
 	min_pending = UINT_MAX;
 	best_good_sectors = 0;
-	has_nonrot_disk = 0;
-	choose_next_idle = 0;
 	clear_bit(R1BIO_FailFast, &r1_bio->state);
 
 	if ((conf->mddev->recovery_cp < this_sector + sectors) ||
@@ -640,7 +637,6 @@
 		sector_t first_bad;
 		int bad_sectors;
 		unsigned int pending;
-		bool nonrot;
 
 		rdev = conf->mirrors[disk].rdev;
 		if (r1_bio->bios[disk] == IO_BLOCKED
@@ -706,8 +702,6 @@
 			/* At least two disks to choose from so failfast is OK */
 			set_bit(R1BIO_FailFast, &r1_bio->state);
 
-		nonrot = bdev_nonrot(rdev->bdev);
-		has_nonrot_disk |= nonrot;
 		pending = atomic_read(&rdev->nr_pending);
 		dist = abs(this_sector - conf->mirrors[disk].head_position);
 		if (choose_first) {
@@ -720,7 +714,6 @@
 			int opt_iosize = bdev_io_opt(rdev->bdev) >> 9;
 			struct raid1_info *mirror = &conf->mirrors[disk];
 
-			best_disk = disk;
 			/*
 			 * If buffered sequential IO size exceeds optimal
 			 * iosize, check if there is idle disk. If yes, choose
@@ -734,20 +727,27 @@
 			 * small, but not a big deal since when the second disk
 			 * starts IO, the first disk is likely still busy.
 			 */
-			if (nonrot && opt_iosize > 0 &&
+			if (test_bit(Nonrot, &rdev->flags) && opt_iosize > 0 &&
 			    mirror->seq_start != MaxSector &&
 			    mirror->next_seq_sect > opt_iosize &&
 			    mirror->next_seq_sect - opt_iosize >=
 			    mirror->seq_start) {
-				choose_next_idle = 1;
-				continue;
+				/*
+				 * Add 'pending' to avoid choosing this disk if
+				 * there is other idle disk.
+				 */
+				pending++;
+				/*
+				 * If there is no other idle disk, this disk
+				 * will be chosen.
+				 */
+				sequential_disk = disk;
+			} else {
+				best_disk = disk;
+				break;
 			}
-			break;
 		}
 
-		if (choose_next_idle)
-			continue;
-
 		if (min_pending > pending) {
 			min_pending = pending;
 			best_pending_disk = disk;
@@ -760,13 +760,20 @@
 	}
 
 	/*
+	 * sequential IO size exceeds optimal iosize, however, there is no other
+	 * idle disk, so choose the sequential disk.
+	 */
+	if (best_disk == -1 && min_pending != 0)
+		best_disk = sequential_disk;
+
+	/*
 	 * If all disks are rotational, choose the closest disk. If any disk is
 	 * non-rotational, choose the disk with less pending request even the
 	 * disk is rotational, which might/might not be optimal for raids with
 	 * mixed ratation/non-rotational disks depending on workload.
 	 */
 	if (best_disk == -1) {
-		if (has_nonrot_disk || min_pending == 0)
+		if (READ_ONCE(conf->nonrot_disks) || min_pending == 0)
 			best_disk = best_pending_disk;
 		else
 			best_disk = best_dist_disk;
@@ -1467,7 +1474,7 @@
 		for (j = 0; j < i; j++)
 			if (r1_bio->bios[j])
 				rdev_dec_pending(conf->mirrors[j].rdev, mddev);
-		free_r1bio(r1_bio);
+		mempool_free(r1_bio, &conf->r1bio_pool);
 		allow_barrier(conf, bio->bi_iter.bi_sector);
 
 		if (bio->bi_opf & REQ_NOWAIT) {
@@ -1598,8 +1605,7 @@
 	if (bio_data_dir(bio) == READ)
 		raid1_read_request(mddev, bio, sectors, NULL);
 	else {
-		if (!md_write_start(mddev,bio))
-			return false;
+		md_write_start(mddev,bio);
 		raid1_write_request(mddev, bio, sectors);
 	}
 	return true;
@@ -1760,6 +1766,52 @@
 	return count;
 }
 
+static bool raid1_add_conf(struct r1conf *conf, struct md_rdev *rdev, int disk,
+			   bool replacement)
+{
+	struct raid1_info *info = conf->mirrors + disk;
+
+	if (replacement)
+		info += conf->raid_disks;
+
+	if (info->rdev)
+		return false;
+
+	if (bdev_nonrot(rdev->bdev)) {
+		set_bit(Nonrot, &rdev->flags);
+		WRITE_ONCE(conf->nonrot_disks, conf->nonrot_disks + 1);
+	}
+
+	rdev->raid_disk = disk;
+	info->head_position = 0;
+	info->seq_start = MaxSector;
+	WRITE_ONCE(info->rdev, rdev);
+
+	return true;
+}
+
+static bool raid1_remove_conf(struct r1conf *conf, int disk)
+{
+	struct raid1_info *info = conf->mirrors + disk;
+	struct md_rdev *rdev = info->rdev;
+
+	if (!rdev || test_bit(In_sync, &rdev->flags) ||
+	    atomic_read(&rdev->nr_pending))
+		return false;
+
+	/* Only remove non-faulty devices if recovery is not possible. */
+	if (!test_bit(Faulty, &rdev->flags) &&
+	    rdev->mddev->recovery_disabled != conf->recovery_disabled &&
+	    rdev->mddev->degraded < conf->raid_disks)
+		return false;
+
+	if (test_and_clear_bit(Nonrot, &rdev->flags))
+		WRITE_ONCE(conf->nonrot_disks, conf->nonrot_disks - 1);
+
+	WRITE_ONCE(info->rdev, NULL);
+	return true;
+}
+
 static int raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
 {
 	struct r1conf *conf = mddev->private;
@@ -1795,15 +1847,13 @@
 				disk_stack_limits(mddev->gendisk, rdev->bdev,
 						  rdev->data_offset << 9);
 
-			p->head_position = 0;
-			rdev->raid_disk = mirror;
+			raid1_add_conf(conf, rdev, mirror, false);
 			err = 0;
 			/* As all devices are equivalent, we don't need a full recovery
 			 * if this was recently any drive of the array
 			 */
 			if (rdev->saved_raid_disk < 0)
 				conf->fullsync = 1;
-			WRITE_ONCE(p->rdev, rdev);
 			break;
 		}
 		if (test_bit(WantReplacement, &p->rdev->flags) &&
@@ -1813,13 +1863,11 @@
 
 	if (err && repl_slot >= 0) {
 		/* Add this device as a replacement */
-		p = conf->mirrors + repl_slot;
 		clear_bit(In_sync, &rdev->flags);
 		set_bit(Replacement, &rdev->flags);
-		rdev->raid_disk = repl_slot;
+		raid1_add_conf(conf, rdev, repl_slot, true);
 		err = 0;
 		conf->fullsync = 1;
-		WRITE_ONCE(p[conf->raid_disks].rdev, rdev);
 	}
 
 	print_conf(conf);
@@ -1836,27 +1884,20 @@
 	if (unlikely(number >= conf->raid_disks))
 		goto abort;
 
-	if (rdev != p->rdev)
-		p = conf->mirrors + conf->raid_disks + number;
+	if (rdev != p->rdev) {
+		number += conf->raid_disks;
+		p = conf->mirrors + number;
+	}
 
 	print_conf(conf);
 	if (rdev == p->rdev) {
-		if (test_bit(In_sync, &rdev->flags) ||
-		    atomic_read(&rdev->nr_pending)) {
-			err = -EBUSY;
-			goto abort;
-		}
-		/* Only remove non-faulty devices if recovery
-		 * is not possible.
-		 */
-		if (!test_bit(Faulty, &rdev->flags) &&
-		    mddev->recovery_disabled != conf->recovery_disabled &&
-		    mddev->degraded < conf->raid_disks) {
+		if (!raid1_remove_conf(conf, number)) {
 			err = -EBUSY;
 			goto abort;
 		}
-		WRITE_ONCE(p->rdev, NULL);
-		if (conf->mirrors[conf->raid_disks + number].rdev) {
+
+		if (number < conf->raid_disks &&
+		    conf->mirrors[conf->raid_disks + number].rdev) {
 			/* We just removed a device that is being replaced.
 			 * Move down the replacement.  We drain all IO before
 			 * doing this to avoid confusion.
@@ -2064,14 +2105,9 @@
 				if (!rdev_set_badblocks(rdev, sect, s, 0))
 					abort = 1;
 			}
-			if (abort) {
-				conf->recovery_disabled =
-					mddev->recovery_disabled;
-				set_bit(MD_RECOVERY_INTR, &mddev->recovery);
-				md_done_sync(mddev, r1_bio->sectors, 0);
-				put_buf(r1_bio);
+			if (abort)
 				return 0;
-			}
+
 			/* Try next page */
 			sectors -= s;
 			sect += s;
@@ -2210,10 +2246,21 @@
 	int disks = conf->raid_disks * 2;
 	struct bio *wbio;
 
-	if (!test_bit(R1BIO_Uptodate, &r1_bio->state))
-		/* ouch - failed to read all of that. */
-		if (!fix_sync_read_error(r1_bio))
+	if (!test_bit(R1BIO_Uptodate, &r1_bio->state)) {
+		/*
+		 * ouch - failed to read all of that.
+		 * No need to fix read error for check/repair
+		 * because all member disks are read.
+		 */
+		if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) ||
+		    !fix_sync_read_error(r1_bio)) {
+			conf->recovery_disabled = mddev->recovery_disabled;
+			set_bit(MD_RECOVERY_INTR, &mddev->recovery);
+			md_done_sync(mddev, r1_bio->sectors, 0);
+			put_buf(r1_bio);
 			return;
+		}
+	}
 
 	if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
 		process_checks(r1_bio);
@@ -3006,23 +3053,17 @@
 
 	err = -EINVAL;
 	spin_lock_init(&conf->device_lock);
+	conf->raid_disks = mddev->raid_disks;
 	rdev_for_each(rdev, mddev) {
 		int disk_idx = rdev->raid_disk;
-		if (disk_idx >= mddev->raid_disks
-		    || disk_idx < 0)
+
+		if (disk_idx >= conf->raid_disks || disk_idx < 0)
 			continue;
-		if (test_bit(Replacement, &rdev->flags))
-			disk = conf->mirrors + mddev->raid_disks + disk_idx;
-		else
-			disk = conf->mirrors + disk_idx;
 
-		if (disk->rdev)
+		if (!raid1_add_conf(conf, rdev, disk_idx,
+				    test_bit(Replacement, &rdev->flags)))
 			goto abort;
-		disk->rdev = rdev;
-		disk->head_position = 0;
-		disk->seq_start = MaxSector;
 	}
-	conf->raid_disks = mddev->raid_disks;
 	conf->mddev = mddev;
 	INIT_LIST_HEAD(&conf->retry_list);
 	INIT_LIST_HEAD(&conf->bio_end_io_list);
@@ -3086,7 +3127,6 @@
 	return ERR_PTR(err);
 }
 
-static void raid1_free(struct mddev *mddev, void *priv);
 static int raid1_run(struct mddev *mddev)
 {
 	struct r1conf *conf;
@@ -3139,8 +3179,7 @@
 	 */
 	if (conf->raid_disks - mddev->degraded < 1) {
 		md_unregister_thread(mddev, &conf->thread);
-		ret = -EINVAL;
-		goto abort;
+		return -EINVAL;
 	}
 
 	if (conf->raid_disks - mddev->degraded == 1)
@@ -3164,14 +3203,8 @@
 	md_set_array_sectors(mddev, raid1_size(mddev, 0, 0));
 
 	ret = md_integrity_register(mddev);
-	if (ret) {
+	if (ret)
 		md_unregister_thread(mddev, &mddev->thread);
-		goto abort;
-	}
-	return 0;
-
-abort:
-	raid1_free(mddev, conf);
 	return ret;
 }
 
--- linux-qcom-6.8.0.orig/drivers/md/raid1.h
+++ linux-qcom-6.8.0/drivers/md/raid1.h
@@ -71,6 +71,7 @@
 						 * allow for replacements.
 						 */
 	int			raid_disks;
+	int			nonrot_disks;
 
 	spinlock_t		device_lock;
 
--- linux-qcom-6.8.0.orig/drivers/md/raid10.c
+++ linux-qcom-6.8.0/drivers/md/raid10.c
@@ -1861,8 +1861,7 @@
 	    && md_flush_request(mddev, bio))
 		return true;
 
-	if (!md_write_start(mddev, bio))
-		return false;
+	md_write_start(mddev, bio);
 
 	if (unlikely(bio_op(bio) == REQ_OP_DISCARD))
 		if (!raid10_handle_discard(mddev, bio))
--- linux-qcom-6.8.0.orig/drivers/md/raid5.c
+++ linux-qcom-6.8.0/drivers/md/raid5.c
@@ -155,7 +155,7 @@
 	return slot;
 }
 
-static void print_raid5_conf (struct r5conf *conf);
+static void print_raid5_conf(struct r5conf *conf);
 
 static int stripe_operations_active(struct stripe_head *sh)
 {
@@ -760,6 +760,7 @@
 	STRIPE_RETRY,
 	STRIPE_SCHEDULE_AND_RETRY,
 	STRIPE_FAIL,
+	STRIPE_WAIT_RESHAPE,
 };
 
 struct stripe_request_ctx {
@@ -2412,7 +2413,7 @@
 	atomic_inc(&conf->active_stripes);
 
 	raid5_release_stripe(sh);
-	conf->max_nr_stripes++;
+	WRITE_ONCE(conf->max_nr_stripes, conf->max_nr_stripes + 1);
 	return 1;
 }
 
@@ -2707,7 +2708,7 @@
 	shrink_buffers(sh);
 	free_stripe(conf->slab_cache, sh);
 	atomic_dec(&conf->active_stripes);
-	conf->max_nr_stripes--;
+	WRITE_ONCE(conf->max_nr_stripes, conf->max_nr_stripes - 1);
 	return 1;
 }
 
@@ -5915,6 +5916,87 @@
 	return ret;
 }
 
+enum reshape_loc {
+	LOC_NO_RESHAPE,
+	LOC_AHEAD_OF_RESHAPE,
+	LOC_INSIDE_RESHAPE,
+	LOC_BEHIND_RESHAPE,
+};
+
+static enum reshape_loc get_reshape_loc(struct mddev *mddev,
+		struct r5conf *conf, sector_t logical_sector)
+{
+	sector_t reshape_progress, reshape_safe;
+	/*
+	 * Spinlock is needed as reshape_progress may be
+	 * 64bit on a 32bit platform, and so it might be
+	 * possible to see a half-updated value
+	 * Of course reshape_progress could change after
+	 * the lock is dropped, so once we get a reference
+	 * to the stripe that we think it is, we will have
+	 * to check again.
+	 */
+	spin_lock_irq(&conf->device_lock);
+	reshape_progress = conf->reshape_progress;
+	reshape_safe = conf->reshape_safe;
+	spin_unlock_irq(&conf->device_lock);
+	if (reshape_progress == MaxSector)
+		return LOC_NO_RESHAPE;
+	if (ahead_of_reshape(mddev, logical_sector, reshape_progress))
+		return LOC_AHEAD_OF_RESHAPE;
+	if (ahead_of_reshape(mddev, logical_sector, reshape_safe))
+		return LOC_INSIDE_RESHAPE;
+	return LOC_BEHIND_RESHAPE;
+}
+
+static void raid5_bitmap_sector(struct mddev *mddev, sector_t *offset,
+				unsigned long *sectors)
+{
+	struct r5conf *conf = mddev->private;
+	sector_t start = *offset;
+	sector_t end = start + *sectors;
+	sector_t prev_start = start;
+	sector_t prev_end = end;
+	int sectors_per_chunk;
+	enum reshape_loc loc;
+	int dd_idx;
+
+	sectors_per_chunk = conf->chunk_sectors *
+		(conf->raid_disks - conf->max_degraded);
+	start = round_down(start, sectors_per_chunk);
+	end = round_up(end, sectors_per_chunk);
+
+	start = raid5_compute_sector(conf, start, 0, &dd_idx, NULL);
+	end = raid5_compute_sector(conf, end, 0, &dd_idx, NULL);
+
+	/*
+	 * For LOC_INSIDE_RESHAPE, this IO will wait for reshape to make
+	 * progress, hence it's the same as LOC_BEHIND_RESHAPE.
+	 */
+	loc = get_reshape_loc(mddev, conf, prev_start);
+	if (likely(loc != LOC_AHEAD_OF_RESHAPE)) {
+		*offset = start;
+		*sectors = end - start;
+		return;
+	}
+
+	sectors_per_chunk = conf->prev_chunk_sectors *
+		(conf->previous_raid_disks - conf->max_degraded);
+	prev_start = round_down(prev_start, sectors_per_chunk);
+	prev_end = round_down(prev_end, sectors_per_chunk);
+
+	prev_start = raid5_compute_sector(conf, prev_start, 1, &dd_idx, NULL);
+	prev_end = raid5_compute_sector(conf, prev_end, 1, &dd_idx, NULL);
+
+	/*
+	 * for LOC_AHEAD_OF_RESHAPE, reshape can make progress before this IO
+	 * is handled in make_stripe_request(), we can't know this here hence
+	 * we set bits for both.
+	 */
+	*offset = min(start, prev_start);
+	*sectors = max(end, prev_end) - *offset;
+}
+
 static enum stripe_result make_stripe_request(struct mddev *mddev,
 		struct r5conf *conf, struct stripe_request_ctx *ctx,
 		sector_t logical_sector, struct bio *bi)
@@ -5929,27 +6011,14 @@
 	seq = read_seqcount_begin(&conf->gen_lock);
 
 	if (unlikely(conf->reshape_progress != MaxSector)) {
-		/*
-		 * Spinlock is needed as reshape_progress may be
-		 * 64bit on a 32bit platform, and so it might be
-		 * possible to see a half-updated value
-		 * Of course reshape_progress could change after
-		 * the lock is dropped, so once we get a reference
-		 * to the stripe that we think it is, we will have
-		 * to check again.
-		 */
-		spin_lock_irq(&conf->device_lock);
-		if (ahead_of_reshape(mddev, logical_sector,
-				     conf->reshape_progress)) {
-			previous = 1;
-		} else {
-			if (ahead_of_reshape(mddev, logical_sector,
-					     conf->reshape_safe)) {
-				spin_unlock_irq(&conf->device_lock);
-				return STRIPE_SCHEDULE_AND_RETRY;
-			}
+		enum reshape_loc loc = get_reshape_loc(mddev, conf,
+						       logical_sector);
+		if (loc == LOC_INSIDE_RESHAPE) {
+			ret = STRIPE_SCHEDULE_AND_RETRY;
+			goto out;
 		}
-		spin_unlock_irq(&conf->device_lock);
+		if (loc == LOC_AHEAD_OF_RESHAPE)
+			previous = 1;
 	}
 
 	new_sector = raid5_compute_sector(conf, logical_sector, previous,
@@ -6025,6 +6094,12 @@
 
 out_release:
 	raid5_release_stripe(sh);
+out:
+	if (ret == STRIPE_SCHEDULE_AND_RETRY && reshape_interrupted(mddev)) {
+		bi->bi_status = BLK_STS_RESOURCE;
+		ret = STRIPE_WAIT_RESHAPE;
+		pr_err_ratelimited("dm-raid456: io across reshape position while reshape can't make progress");
+	}
 	return ret;
 }
 
@@ -6087,8 +6162,7 @@
 		ctx.do_flush = bi->bi_opf & REQ_PREFLUSH;
 	}
 
-	if (!md_write_start(mddev, bi))
-		return false;
+	md_write_start(mddev, bi);
 	/*
 	 * If array is degraded, better not do chunk aligned read because
 	 * later we might have to read it again in order to reconstruct
@@ -6122,8 +6196,7 @@
 	/* Bail out if conflicts with reshape and REQ_NOWAIT is set */
 	if ((bi->bi_opf & REQ_NOWAIT) &&
 	    (conf->reshape_progress != MaxSector) &&
-	    !ahead_of_reshape(mddev, logical_sector, conf->reshape_progress) &&
-	    ahead_of_reshape(mddev, logical_sector, conf->reshape_safe)) {
+	    get_reshape_loc(mddev, conf, logical_sector) == LOC_INSIDE_RESHAPE) {
 		bio_wouldblock_error(bi);
 		if (rw == WRITE)
 			md_write_end(mddev);
@@ -6146,7 +6219,7 @@
 	while (1) {
 		res = make_stripe_request(mddev, conf, &ctx, logical_sector,
 					  bi);
-		if (res == STRIPE_FAIL)
+		if (res == STRIPE_FAIL || res == STRIPE_WAIT_RESHAPE)
 			break;
 
 		if (res == STRIPE_RETRY)
@@ -6184,6 +6257,11 @@
 
 	if (rw == WRITE)
 		md_write_end(mddev);
+	if (res == STRIPE_WAIT_RESHAPE) {
+		md_free_cloned_bio(bi);
+		return false;
+	}
+
 	bio_endio(bi);
 	return true;
 }
@@ -6259,7 +6337,9 @@
 	safepos = conf->reshape_safe;
 	sector_div(safepos, data_disks);
 	if (mddev->reshape_backwards) {
-		BUG_ON(writepos < reshape_sectors);
+		if (WARN_ON(writepos < reshape_sectors))
+			return MaxSector;
+
 		writepos -= reshape_sectors;
 		readpos += reshape_sectors;
 		safepos += reshape_sectors;
@@ -6277,14 +6357,18 @@
 	 * to set 'stripe_addr' which is where we will write to.
 	 */
 	if (mddev->reshape_backwards) {
-		BUG_ON(conf->reshape_progress == 0);
+		if (WARN_ON(conf->reshape_progress == 0))
+			return MaxSector;
+
 		stripe_addr = writepos;
-		BUG_ON((mddev->dev_sectors &
-			~((sector_t)reshape_sectors - 1))
-		       - reshape_sectors - stripe_addr
-		       != sector_nr);
+		if (WARN_ON((mddev->dev_sectors &
+		    ~((sector_t)reshape_sectors - 1)) -
+		    reshape_sectors - stripe_addr != sector_nr))
+			return MaxSector;
 	} else {
-		BUG_ON(writepos != sector_nr + reshape_sectors);
+		if (WARN_ON(writepos != sector_nr + reshape_sectors))
+			return MaxSector;
+
 		stripe_addr = sector_nr;
 	}
 
@@ -6737,6 +6821,9 @@
 		int batch_size, released;
 		unsigned int offset;
 
+		if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags))
+			break;
+
 		released = release_stripe_list(conf, conf->temp_inactive_list);
 		if (released)
 			clear_bit(R5_DID_ALLOC, &conf->cache_state);
@@ -6820,7 +6907,7 @@
 	if (size <= 16 || size > 32768)
 		return -EINVAL;
 
-	conf->min_nr_stripes = size;
+	WRITE_ONCE(conf->min_nr_stripes, size);
 	mutex_lock(&conf->cache_size_mutex);
 	while (size < conf->max_nr_stripes &&
 	       drop_one_stripe(conf))
@@ -6832,7 +6919,7 @@
 	mutex_lock(&conf->cache_size_mutex);
 	while (size > conf->max_nr_stripes)
 		if (!grow_one_stripe(conf, GFP_KERNEL)) {
-			conf->min_nr_stripes = conf->max_nr_stripes;
+			WRITE_ONCE(conf->min_nr_stripes, conf->max_nr_stripes);
 			result = -ENOMEM;
 			break;
 		}
@@ -7150,6 +7237,8 @@
 	err = mddev_suspend_and_lock(mddev);
 	if (err)
 		return err;
+	raid5_quiesce(mddev, true);
+
 	conf = mddev->private;
 	if (!conf)
 		err = -ENODEV;
@@ -7171,6 +7260,8 @@
 			kfree(old_groups);
 		}
 	}
+
+	raid5_quiesce(mddev, false);
 	mddev_unlock_and_resume(mddev);
 
 	return err ?: len;
@@ -7390,11 +7481,13 @@
 				       struct shrink_control *sc)
 {
 	struct r5conf *conf = shrink->private_data;
+	int max_stripes = READ_ONCE(conf->max_nr_stripes);
+	int min_stripes = READ_ONCE(conf->min_nr_stripes);
 
-	if (conf->max_nr_stripes < conf->min_nr_stripes)
+	if (max_stripes < min_stripes)
 		/* unlikely, but not impossible */
 		return 0;
-	return conf->max_nr_stripes - conf->min_nr_stripes;
+	return max_stripes - min_stripes;
 }
 
 static struct r5conf *setup_conf(struct mddev *mddev)
@@ -7563,11 +7656,11 @@
 		if (test_bit(Replacement, &rdev->flags)) {
 			if (disk->replacement)
 				goto abort;
-			RCU_INIT_POINTER(disk->replacement, rdev);
+			disk->replacement = rdev;
 		} else {
 			if (disk->rdev)
 				goto abort;
-			RCU_INIT_POINTER(disk->rdev, rdev);
+			disk->rdev = rdev;
 		}
 
 		if (test_bit(In_sync, &rdev->flags)) {
@@ -8049,7 +8142,7 @@
 	seq_printf (seq, "]");
 }
 
-static void print_raid5_conf (struct r5conf *conf)
+static void print_raid5_conf(struct r5conf *conf)
 {
 	struct md_rdev *rdev;
 	int i;
@@ -8063,15 +8156,13 @@
 	       conf->raid_disks,
 	       conf->raid_disks - conf->mddev->degraded);
 
-	rcu_read_lock();
 	for (i = 0; i < conf->raid_disks; i++) {
-		rdev = rcu_dereference(conf->disks[i].rdev);
+		rdev = conf->disks[i].rdev;
 		if (rdev)
 			pr_debug(" disk %d, o:%d, dev:%pg\n",
 			       i, !test_bit(Faulty, &rdev->flags),
 			       rdev->bdev);
 	}
-	rcu_read_unlock();
 }
 
 static int raid5_spare_active(struct mddev *mddev)
@@ -8909,6 +9000,18 @@
 	return r5l_start(conf->log);
 }
 
+/*
+ * This is only used for dm-raid456, caller already frozen sync_thread, hence
+ * if rehsape is still in progress, io that is waiting for reshape can never be
+ * done now, hence wake up and handle those IO.
+ */
+static void raid5_prepare_suspend(struct mddev *mddev)
+{
+	struct r5conf *conf = mddev->private;
+
+	wake_up(&conf->wait_for_overlap);
+}
+
 static struct md_personality raid6_personality =
 {
 	.name		= "raid6",
@@ -8932,6 +9035,8 @@
 	.quiesce	= raid5_quiesce,
 	.takeover	= raid6_takeover,
 	.change_consistency_policy = raid5_change_consistency_policy,
+	.prepare_suspend = raid5_prepare_suspend,
+	.bitmap_sector	= raid5_bitmap_sector,
 };
 static struct md_personality raid5_personality =
 {
@@ -8956,6 +9061,8 @@
 	.quiesce	= raid5_quiesce,
 	.takeover	= raid5_takeover,
 	.change_consistency_policy = raid5_change_consistency_policy,
+	.prepare_suspend = raid5_prepare_suspend,
+	.bitmap_sector	= raid5_bitmap_sector,
 };
 
 static struct md_personality raid4_personality =
@@ -8981,6 +9088,8 @@
 	.quiesce	= raid5_quiesce,
 	.takeover	= raid4_takeover,
 	.change_consistency_policy = raid5_change_consistency_policy,
+	.prepare_suspend = raid5_prepare_suspend,
+	.bitmap_sector	= raid5_bitmap_sector,
 };
 
 static int __init raid5_init(void)
--- linux-qcom-6.8.0.orig/drivers/media/cec/core/cec-adap.c
+++ linux-qcom-6.8.0/drivers/media/cec/core/cec-adap.c
@@ -490,6 +490,15 @@
 			goto unlock;
 		}
 
+		if (adap->transmit_in_progress &&
+		    adap->transmit_in_progress_aborted) {
+			if (adap->transmitting)
+				cec_data_cancel(adap->transmitting,
+						CEC_TX_STATUS_ABORTED, 0);
+			adap->transmit_in_progress = false;
+			adap->transmit_in_progress_aborted = false;
+			goto unlock;
+		}
 		if (adap->transmit_in_progress && timeout) {
 			/*
 			 * If we timeout, then log that. Normally this does
@@ -771,6 +780,7 @@
 {
 	struct cec_data *data;
 	bool is_raw = msg_is_raw(msg);
+	int err;
 
 	if (adap->devnode.unregistered)
 		return -ENODEV;
@@ -935,11 +945,13 @@
 	 * Release the lock and wait, retake the lock afterwards.
 	 */
 	mutex_unlock(&adap->lock);
-	wait_for_completion_killable(&data->c);
-	if (!data->completed)
-		cancel_delayed_work_sync(&data->work);
+	err = wait_for_completion_killable(&data->c);
+	cancel_delayed_work_sync(&data->work);
 	mutex_lock(&adap->lock);
 
+	if (err)
+		adap->transmit_in_progress_aborted = true;
+
 	/* Cancel the transmit if it was interrupted */
 	if (!data->completed) {
 		if (data->msg.tx_status & CEC_TX_STATUS_OK)
@@ -1151,20 +1163,6 @@
 	if (valid_la && min_len) {
 		/* These messages have special length requirements */
 		switch (cmd) {
-		case CEC_MSG_TIMER_STATUS:
-			if (msg->msg[2] & 0x10) {
-				switch (msg->msg[2] & 0xf) {
-				case CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE:
-				case CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE:
-					if (msg->len < 5)
-						valid_la = false;
-					break;
-				}
-			} else if ((msg->msg[2] & 0xf) == CEC_OP_PROG_ERROR_DUPLICATE) {
-				if (msg->len < 5)
-					valid_la = false;
-			}
-			break;
 		case CEC_MSG_RECORD_ON:
 			switch (msg->msg[2]) {
 			case CEC_OP_RECORD_SRC_OWN:
@@ -1589,9 +1587,12 @@
  */
 static void cec_claim_log_addrs(struct cec_adapter *adap, bool block)
 {
-	if (WARN_ON(adap->is_configuring || adap->is_configured))
+	if (WARN_ON(adap->is_claiming_log_addrs ||
+		    adap->is_configuring || adap->is_configured))
 		return;
 
+	adap->is_claiming_log_addrs = true;
+
 	init_completion(&adap->config_completion);
 
 	/* Ready to kick off the thread */
@@ -1606,6 +1607,7 @@
 		wait_for_completion(&adap->config_completion);
 		mutex_lock(&adap->lock);
 	}
+	adap->is_claiming_log_addrs = false;
 }
 
 /*
--- linux-qcom-6.8.0.orig/drivers/media/cec/core/cec-api.c
+++ linux-qcom-6.8.0/drivers/media/cec/core/cec-api.c
@@ -178,7 +178,7 @@
 			   CEC_LOG_ADDRS_FL_ALLOW_RC_PASSTHRU |
 			   CEC_LOG_ADDRS_FL_CDC_ONLY;
 	mutex_lock(&adap->lock);
-	if (!adap->is_configuring &&
+	if (!adap->is_claiming_log_addrs && !adap->is_configuring &&
 	    (!log_addrs.num_log_addrs || !adap->is_configured) &&
 	    !cec_is_busy(adap, fh)) {
 		err = __cec_s_log_addrs(adap, &log_addrs, block);
@@ -664,6 +664,8 @@
 		list_del_init(&data->xfer_list);
 	}
 	mutex_unlock(&adap->lock);
+
+	mutex_lock(&fh->lock);
 	while (!list_empty(&fh->msgs)) {
 		struct cec_msg_entry *entry =
 			list_first_entry(&fh->msgs, struct cec_msg_entry, list);
@@ -681,6 +683,7 @@
 			kfree(entry);
 		}
 	}
+	mutex_unlock(&fh->lock);
 	kfree(fh);
 
 	cec_put_device(devnode);
--- linux-qcom-6.8.0.orig/drivers/media/cec/usb/pulse8/pulse8-cec.c
+++ linux-qcom-6.8.0/drivers/media/cec/usb/pulse8/pulse8-cec.c
@@ -685,7 +685,7 @@
 	err = pulse8_send_and_wait(pulse8, cmd, 1, cmd[0], 4);
 	if (err)
 		return err;
-	date = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
+	date = ((unsigned)data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
 	dev_info(pulse8->dev, "Firmware build date %ptT\n", &date);
 
 	dev_dbg(pulse8->dev, "Persistent config:\n");
--- linux-qcom-6.8.0.orig/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
+++ linux-qcom-6.8.0/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c
@@ -113,6 +113,7 @@
 {
 	unsigned pat;
 	unsigned plane;
+	int ret = 0;
 
 	tpg->max_line_width = max_w;
 	for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) {
@@ -121,14 +122,18 @@
 
 			tpg->lines[pat][plane] =
 				vzalloc(array3_size(max_w, 2, pixelsz));
-			if (!tpg->lines[pat][plane])
-				return -ENOMEM;
+			if (!tpg->lines[pat][plane]) {
+				ret = -ENOMEM;
+				goto free_lines;
+			}
 			if (plane == 0)
 				continue;
 			tpg->downsampled_lines[pat][plane] =
 				vzalloc(array3_size(max_w, 2, pixelsz));
-			if (!tpg->downsampled_lines[pat][plane])
-				return -ENOMEM;
+			if (!tpg->downsampled_lines[pat][plane]) {
+				ret = -ENOMEM;
+				goto free_lines;
+			}
 		}
 	}
 	for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
@@ -136,18 +141,45 @@
 
 		tpg->contrast_line[plane] =
 			vzalloc(array_size(pixelsz, max_w));
-		if (!tpg->contrast_line[plane])
-			return -ENOMEM;
+		if (!tpg->contrast_line[plane]) {
+			ret = -ENOMEM;
+			goto free_contrast_line;
+		}
 		tpg->black_line[plane] =
 			vzalloc(array_size(pixelsz, max_w));
-		if (!tpg->black_line[plane])
-			return -ENOMEM;
+		if (!tpg->black_line[plane]) {
+			ret = -ENOMEM;
+			goto free_contrast_line;
+		}
 		tpg->random_line[plane] =
 			vzalloc(array3_size(max_w, 2, pixelsz));
-		if (!tpg->random_line[plane])
-			return -ENOMEM;
+		if (!tpg->random_line[plane]) {
+			ret = -ENOMEM;
+			goto free_contrast_line;
+		}
 	}
 	return 0;
+
+free_contrast_line:
+	for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
+		vfree(tpg->contrast_line[plane]);
+		vfree(tpg->black_line[plane]);
+		vfree(tpg->random_line[plane]);
+		tpg->contrast_line[plane] = NULL;
+		tpg->black_line[plane] = NULL;
+		tpg->random_line[plane] = NULL;
+	}
+free_lines:
+	for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++)
+		for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
+			vfree(tpg->lines[pat][plane]);
+			tpg->lines[pat][plane] = NULL;
+			if (plane == 0)
+				continue;
+			vfree(tpg->downsampled_lines[pat][plane]);
+			tpg->downsampled_lines[pat][plane] = NULL;
+		}
+	return ret;
 }
 EXPORT_SYMBOL_GPL(tpg_alloc);
 
@@ -1763,6 +1795,9 @@
 	unsigned p;
 	unsigned x;
 
+	if (WARN_ON_ONCE(!tpg->src_width || !tpg->scaled_width))
+		return;
+
 	switch (tpg->pattern) {
 	case TPG_PAT_GREEN:
 		contrast = TPG_COLOR_100_RED;
--- linux-qcom-6.8.0.orig/drivers/media/common/videobuf2/videobuf2-core.c
+++ linux-qcom-6.8.0/drivers/media/common/videobuf2/videobuf2-core.c
@@ -312,6 +312,10 @@
 	p->mem_priv = NULL;
 	p->dbuf = NULL;
 	p->dbuf_mapped = 0;
+	p->bytesused = 0;
+	p->length = 0;
+	p->m.fd = 0;
+	p->data_offset = 0;
 }
 
 /*
@@ -1378,10 +1382,6 @@
 
 		/* Release previously acquired memory if present */
 		__vb2_plane_dmabuf_put(vb, &vb->planes[plane]);
-		vb->planes[plane].bytesused = 0;
-		vb->planes[plane].length = 0;
-		vb->planes[plane].m.fd = 0;
-		vb->planes[plane].data_offset = 0;
 
 		/* Acquire each plane's memory */
 		mem_priv = call_ptr_memop(attach_dmabuf,
--- linux-qcom-6.8.0.orig/drivers/media/dvb-core/dvb_frontend.c
+++ linux-qcom-6.8.0/drivers/media/dvb-core/dvb_frontend.c
@@ -443,8 +443,8 @@
 
 		default:
 			fepriv->auto_step++;
-			fepriv->auto_sub_step = -1; /* it'll be incremented to 0 in a moment */
-			break;
+			fepriv->auto_sub_step = 0;
+			continue;
 		}
 
 		if (!ready) fepriv->auto_sub_step++;
@@ -2168,7 +2168,8 @@
 		if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
 			return -EINVAL;
 
-		tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp));
+		tvp = memdup_array_user(compat_ptr(tvps->props),
+					tvps->num, sizeof(*tvp));
 		if (IS_ERR(tvp))
 			return PTR_ERR(tvp);
 
@@ -2199,7 +2200,8 @@
 		if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
 			return -EINVAL;
 
-		tvp = memdup_user(compat_ptr(tvps->props), tvps->num * sizeof(*tvp));
+		tvp = memdup_array_user(compat_ptr(tvps->props),
+					tvps->num, sizeof(*tvp));
 		if (IS_ERR(tvp))
 			return PTR_ERR(tvp);
 
@@ -2379,7 +2381,8 @@
 	if (!tvps->num || tvps->num > DTV_IOCTL_MAX_MSGS)
 		return -EINVAL;
 
-	tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp));
+	tvp = memdup_array_user((void __user *)tvps->props,
+				tvps->num, sizeof(*tvp));
 	if (IS_ERR(tvp))
 		return PTR_ERR(tvp);
 
@@ -2457,7 +2460,8 @@
 		if (!tvps->num || (tvps->num > DTV_IOCTL_MAX_MSGS))
 			return -EINVAL;
 
-		tvp = memdup_user((void __user *)tvps->props, tvps->num * sizeof(*tvp));
+		tvp = memdup_array_user((void __user *)tvps->props,
+					tvps->num, sizeof(*tvp));
 		if (IS_ERR(tvp))
 			return PTR_ERR(tvp);
 
--- linux-qcom-6.8.0.orig/drivers/media/dvb-core/dvb_vb2.c
+++ linux-qcom-6.8.0/drivers/media/dvb-core/dvb_vb2.c
@@ -366,9 +366,15 @@
 int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp)
 {
 	struct vb2_queue *q = &ctx->vb_q;
+	struct vb2_buffer *vb2 = vb2_get_buffer(q, exp->index);
 	int ret;
 
-	ret = vb2_core_expbuf(&ctx->vb_q, &exp->fd, q->type, q->bufs[exp->index],
+	if (!vb2) {
+		dprintk(1, "[%s] invalid buffer index\n", ctx->name);
+		return -EINVAL;
+	}
+
+	ret = vb2_core_expbuf(&ctx->vb_q, &exp->fd, q->type, vb2,
 			      0, exp->flags);
 	if (ret) {
 		dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
--- linux-qcom-6.8.0.orig/drivers/media/dvb-core/dvbdev.c
+++ linux-qcom-6.8.0/drivers/media/dvb-core/dvbdev.c
@@ -86,10 +86,15 @@
 static int dvb_device_open(struct inode *inode, struct file *file)
 {
 	struct dvb_device *dvbdev;
+	unsigned int minor = iminor(inode);
+
+	if (minor >= MAX_DVB_MINORS)
+		return -ENODEV;
 
 	mutex_lock(&dvbdev_mutex);
 	down_read(&minor_rwsem);
-	dvbdev = dvb_minors[iminor(inode)];
+
+	dvbdev = dvb_minors[minor];
 
 	if (dvbdev && dvbdev->fops) {
 		int err = 0;
@@ -490,6 +495,7 @@
 		dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL);
 		if (!dvbdevfops) {
 			kfree(dvbdev);
+			*pdvbdev = NULL;
 			mutex_unlock(&dvbdev_register_lock);
 			return -ENOMEM;
 		}
@@ -498,6 +504,7 @@
 		if (!new_node) {
 			kfree(dvbdevfops);
 			kfree(dvbdev);
+			*pdvbdev = NULL;
 			mutex_unlock(&dvbdev_register_lock);
 			return -ENOMEM;
 		}
@@ -523,7 +530,10 @@
 	for (minor = 0; minor < MAX_DVB_MINORS; minor++)
 		if (!dvb_minors[minor])
 			break;
-	if (minor == MAX_DVB_MINORS) {
+#else
+	minor = nums2minor(adap->num, type, id);
+#endif
+	if (minor >= MAX_DVB_MINORS) {
 		if (new_node) {
 			list_del(&new_node->list_head);
 			kfree(dvbdevfops);
@@ -531,13 +541,12 @@
 		}
 		list_del(&dvbdev->list_head);
 		kfree(dvbdev);
+		*pdvbdev = NULL;
 		up_write(&minor_rwsem);
 		mutex_unlock(&dvbdev_register_lock);
 		return -EINVAL;
 	}
-#else
-	minor = nums2minor(adap->num, type, id);
-#endif
+
 	dvbdev->minor = minor;
 	dvb_minors[minor] = dvb_device_get(dvbdev);
 	up_write(&minor_rwsem);
@@ -553,6 +562,7 @@
 		dvb_media_device_free(dvbdev);
 		list_del(&dvbdev->list_head);
 		kfree(dvbdev);
+		*pdvbdev = NULL;
 		mutex_unlock(&dvbdev_register_lock);
 		return ret;
 	}
@@ -571,6 +581,7 @@
 		dvb_media_device_free(dvbdev);
 		list_del(&dvbdev->list_head);
 		kfree(dvbdev);
+		*pdvbdev = NULL;
 		mutex_unlock(&dvbdev_register_lock);
 		return PTR_ERR(clsdev);
 	}
@@ -951,7 +962,7 @@
 		 int (*func)(struct file *file,
 			     unsigned int cmd, void *arg))
 {
-	char    sbuf[128];
+	char    sbuf[128] = {};
 	void    *mbuf = NULL;
 	void    *parg = NULL;
 	int     err  = -EINVAL;
--- linux-qcom-6.8.0.orig/drivers/media/dvb-frontends/as102_fe_types.h
+++ linux-qcom-6.8.0/drivers/media/dvb-frontends/as102_fe_types.h
@@ -174,6 +174,6 @@
 	uint32_t addr;
 	/* register mode access */
 	uint8_t mode;
-};
+} __packed;
 
 #endif
--- linux-qcom-6.8.0.orig/drivers/media/dvb-frontends/cx24116.c
+++ linux-qcom-6.8.0/drivers/media/dvb-frontends/cx24116.c
@@ -741,6 +741,7 @@
 {
 	struct cx24116_state *state = fe->demodulator_priv;
 	u8 snr_reading;
+	int ret;
 	static const u32 snr_tab[] = { /* 10 x Table (rounded up) */
 		0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667,
 		0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667,
@@ -749,7 +750,11 @@
 
 	dprintk("%s()\n", __func__);
 
-	snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0);
+	ret = cx24116_readreg(state, CX24116_REG_QUALITY0);
+	if (ret  < 0)
+		return ret;
+
+	snr_reading = ret;
 
 	if (snr_reading >= 0xa0 /* 100% */)
 		*snr = 0xffff;
--- linux-qcom-6.8.0.orig/drivers/media/dvb-frontends/dib3000mb.c
+++ linux-qcom-6.8.0/drivers/media/dvb-frontends/dib3000mb.c
@@ -51,7 +51,7 @@
 static int dib3000_read_reg(struct dib3000_state *state, u16 reg)
 {
 	u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
-	u8 rb[2];
+	u8 rb[2] = {};
 	struct i2c_msg msg[] = {
 		{ .addr = state->config.demod_address, .flags = 0,        .buf = wb, .len = 2 },
 		{ .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
--- linux-qcom-6.8.0.orig/drivers/media/dvb-frontends/lgdt3306a.c
+++ linux-qcom-6.8.0/drivers/media/dvb-frontends/lgdt3306a.c
@@ -2176,6 +2176,11 @@
 	struct dvb_frontend *fe;
 	int ret;
 
+	if (!client->dev.platform_data) {
+		dev_err(&client->dev, "platform data is mandatory\n");
+		return -EINVAL;
+	}
+
 	config = kmemdup(client->dev.platform_data,
 			 sizeof(struct lgdt3306a_config), GFP_KERNEL);
 	if (config == NULL) {
--- linux-qcom-6.8.0.orig/drivers/media/dvb-frontends/mxl5xx.c
+++ linux-qcom-6.8.0/drivers/media/dvb-frontends/mxl5xx.c
@@ -1381,57 +1381,57 @@
 	u32 nco_count_min = 0;
 	u32 clk_type = 0;
 
-	struct MXL_REG_FIELD_T xpt_sync_polarity[MXL_HYDRA_DEMOD_MAX] = {
+	static const struct MXL_REG_FIELD_T xpt_sync_polarity[MXL_HYDRA_DEMOD_MAX] = {
 		{0x90700010, 8, 1}, {0x90700010, 9, 1},
 		{0x90700010, 10, 1}, {0x90700010, 11, 1},
 		{0x90700010, 12, 1}, {0x90700010, 13, 1},
 		{0x90700010, 14, 1}, {0x90700010, 15, 1} };
-	struct MXL_REG_FIELD_T xpt_clock_polarity[MXL_HYDRA_DEMOD_MAX] = {
+	static const struct MXL_REG_FIELD_T xpt_clock_polarity[MXL_HYDRA_DEMOD_MAX] = {
 		{0x90700010, 16, 1}, {0x90700010, 17, 1},
 		{0x90700010, 18, 1}, {0x90700010, 19, 1},
 		{0x90700010, 20, 1}, {0x90700010, 21, 1},
 		{0x90700010, 22, 1}, {0x90700010, 23, 1} };
-	struct MXL_REG_FIELD_T xpt_valid_polarity[MXL_HYDRA_DEMOD_MAX] = {
+	static const struct MXL_REG_FIELD_T xpt_valid_polarity[MXL_HYDRA_DEMOD_MAX] = {
 		{0x90700014, 0, 1}, {0x90700014, 1, 1},
 		{0x90700014, 2, 1}, {0x90700014, 3, 1},
 		{0x90700014, 4, 1}, {0x90700014, 5, 1},
 		{0x90700014, 6, 1}, {0x90700014, 7, 1} };
-	struct MXL_REG_FIELD_T xpt_ts_clock_phase[MXL_HYDRA_DEMOD_MAX] = {
+	static const struct MXL_REG_FIELD_T xpt_ts_clock_phase[MXL_HYDRA_DEMOD_MAX] = {
 		{0x90700018, 0, 3}, {0x90700018, 4, 3},
 		{0x90700018, 8, 3}, {0x90700018, 12, 3},
 		{0x90700018, 16, 3}, {0x90700018, 20, 3},
 		{0x90700018, 24, 3}, {0x90700018, 28, 3} };
-	struct MXL_REG_FIELD_T xpt_lsb_first[MXL_HYDRA_DEMOD_MAX] = {
+	static const struct MXL_REG_FIELD_T xpt_lsb_first[MXL_HYDRA_DEMOD_MAX] = {
 		{0x9070000C, 16, 1}, {0x9070000C, 17, 1},
 		{0x9070000C, 18, 1}, {0x9070000C, 19, 1},
 		{0x9070000C, 20, 1}, {0x9070000C, 21, 1},
 		{0x9070000C, 22, 1}, {0x9070000C, 23, 1} };
-	struct MXL_REG_FIELD_T xpt_sync_byte[MXL_HYDRA_DEMOD_MAX] = {
+	static const struct MXL_REG_FIELD_T xpt_sync_byte[MXL_HYDRA_DEMOD_MAX] = {
 		{0x90700010, 0, 1}, {0x90700010, 1, 1},
 		{0x90700010, 2, 1}, {0x90700010, 3, 1},
 		{0x90700010, 4, 1}, {0x90700010, 5, 1},
 		{0x90700010, 6, 1}, {0x90700010, 7, 1} };
-	struct MXL_REG_FIELD_T xpt_enable_output[MXL_HYDRA_DEMOD_MAX] = {
+	static const struct MXL_REG_FIELD_T xpt_enable_output[MXL_HYDRA_DEMOD_MAX] = {
 		{0x9070000C, 0, 1}, {0x9070000C, 1, 1},
 		{0x9070000C, 2, 1}, {0x9070000C, 3, 1},
 		{0x9070000C, 4, 1}, {0x9070000C, 5, 1},
 		{0x9070000C, 6, 1}, {0x9070000C, 7, 1} };
-	struct MXL_REG_FIELD_T xpt_err_replace_sync[MXL_HYDRA_DEMOD_MAX] = {
+	static const struct MXL_REG_FIELD_T xpt_err_replace_sync[MXL_HYDRA_DEMOD_MAX] = {
 		{0x9070000C, 24, 1}, {0x9070000C, 25, 1},
 		{0x9070000C, 26, 1}, {0x9070000C, 27, 1},
 		{0x9070000C, 28, 1}, {0x9070000C, 29, 1},
 		{0x9070000C, 30, 1}, {0x9070000C, 31, 1} };
-	struct MXL_REG_FIELD_T xpt_err_replace_valid[MXL_HYDRA_DEMOD_MAX] = {
+	static const struct MXL_REG_FIELD_T xpt_err_replace_valid[MXL_HYDRA_DEMOD_MAX] = {
 		{0x90700014, 8, 1}, {0x90700014, 9, 1},
 		{0x90700014, 10, 1}, {0x90700014, 11, 1},
 		{0x90700014, 12, 1}, {0x90700014, 13, 1},
 		{0x90700014, 14, 1}, {0x90700014, 15, 1} };
-	struct MXL_REG_FIELD_T xpt_continuous_clock[MXL_HYDRA_DEMOD_MAX] = {
+	static const struct MXL_REG_FIELD_T xpt_continuous_clock[MXL_HYDRA_DEMOD_MAX] = {
 		{0x907001D4, 0, 1}, {0x907001D4, 1, 1},
 		{0x907001D4, 2, 1}, {0x907001D4, 3, 1},
 		{0x907001D4, 4, 1}, {0x907001D4, 5, 1},
 		{0x907001D4, 6, 1}, {0x907001D4, 7, 1} };
-	struct MXL_REG_FIELD_T xpt_nco_clock_rate[MXL_HYDRA_DEMOD_MAX] = {
+	static const struct MXL_REG_FIELD_T xpt_nco_clock_rate[MXL_HYDRA_DEMOD_MAX] = {
 		{0x90700044, 16, 80}, {0x90700044, 16, 81},
 		{0x90700044, 16, 82}, {0x90700044, 16, 83},
 		{0x90700044, 16, 84}, {0x90700044, 16, 85},
--- linux-qcom-6.8.0.orig/drivers/media/dvb-frontends/rtl2830.c
+++ linux-qcom-6.8.0/drivers/media/dvb-frontends/rtl2830.c
@@ -609,7 +609,7 @@
 		index, pid, onoff);
 
 	/* skip invalid PIDs (0x2000) */
-	if (pid > 0x1fff || index > 32)
+	if (pid > 0x1fff || index >= 32)
 		return 0;
 
 	if (onoff)
--- linux-qcom-6.8.0.orig/drivers/media/dvb-frontends/rtl2832.c
+++ linux-qcom-6.8.0/drivers/media/dvb-frontends/rtl2832.c
@@ -983,7 +983,7 @@
 		index, pid, onoff, dev->slave_ts);
 
 	/* skip invalid PIDs (0x2000) */
-	if (pid > 0x1fff || index > 32)
+	if (pid > 0x1fff || index >= 32)
 		return 0;
 
 	if (onoff)
--- linux-qcom-6.8.0.orig/drivers/media/dvb-frontends/stb0899_algo.c
+++ linux-qcom-6.8.0/drivers/media/dvb-frontends/stb0899_algo.c
@@ -269,7 +269,7 @@
 
 	short int derot_freq = 0, last_derot_freq = 0, derot_limit, next_loop = 3;
 	int index = 0;
-	u8 cfr[2];
+	u8 cfr[2] = {0};
 	u8 reg;
 
 	internal->status = NOCARRIER;
--- linux-qcom-6.8.0.orig/drivers/media/dvb-frontends/stv0367.c
+++ linux-qcom-6.8.0/drivers/media/dvb-frontends/stv0367.c
@@ -118,50 +118,32 @@
 	}
 };
 
-static
-int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
+static noinline_for_stack
+int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
 {
-	u8 buf[MAX_XFER_SIZE];
+	u8 buf[3] = { MSB(reg), LSB(reg), data };
 	struct i2c_msg msg = {
 		.addr = state->config->demod_address,
 		.flags = 0,
 		.buf = buf,
-		.len = len + 2
+		.len = 3,
 	};
 	int ret;
 
-	if (2 + len > sizeof(buf)) {
-		printk(KERN_WARNING
-		       "%s: i2c wr reg=%04x: len=%d is too big!\n",
-		       KBUILD_MODNAME, reg, len);
-		return -EINVAL;
-	}
-
-
-	buf[0] = MSB(reg);
-	buf[1] = LSB(reg);
-	memcpy(buf + 2, data, len);
-
 	if (i2cdebug)
 		printk(KERN_DEBUG "%s: [%02x] %02x: %02x\n", __func__,
-			state->config->demod_address, reg, buf[2]);
+			state->config->demod_address, reg, data);
 
 	ret = i2c_transfer(state->i2c, &msg, 1);
 	if (ret != 1)
 		printk(KERN_ERR "%s: i2c write error! ([%02x] %02x: %02x)\n",
-			__func__, state->config->demod_address, reg, buf[2]);
+			__func__, state->config->demod_address, reg, data);
 
 	return (ret != 1) ? -EREMOTEIO : 0;
 }
 
-static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
-{
-	u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
-
-	return stv0367_writeregs(state, reg, &tmp, 1);
-}
-
-static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
+static noinline_for_stack
+u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
 {
 	u8 b0[] = { 0, 0 };
 	u8 b1[] = { 0 };
--- linux-qcom-6.8.0.orig/drivers/media/dvb-frontends/tda10048.c
+++ linux-qcom-6.8.0/drivers/media/dvb-frontends/tda10048.c
@@ -410,6 +410,7 @@
 	struct tda10048_config *config = &state->config;
 	int i;
 	u32 if_freq_khz;
+	u64 sample_freq;
 
 	dprintk(1, "%s(bw = %d)\n", __func__, bw);
 
@@ -451,9 +452,11 @@
 	dprintk(1, "- pll_pfactor = %d\n", state->pll_pfactor);
 
 	/* Calculate the sample frequency */
-	state->sample_freq = state->xtal_hz * (state->pll_mfactor + 45);
-	state->sample_freq /= (state->pll_nfactor + 1);
-	state->sample_freq /= (state->pll_pfactor + 4);
+	sample_freq = state->xtal_hz;
+	sample_freq *= state->pll_mfactor + 45;
+	do_div(sample_freq, state->pll_nfactor + 1);
+	do_div(sample_freq, state->pll_pfactor + 4);
+	state->sample_freq = sample_freq;
 	dprintk(1, "- sample_freq = %d\n", state->sample_freq);
 
 	/* Update the I/F */
--- linux-qcom-6.8.0.orig/drivers/media/dvb-frontends/tda18271c2dd.c
+++ linux-qcom-6.8.0/drivers/media/dvb-frontends/tda18271c2dd.c
@@ -328,7 +328,7 @@
 
 	OscFreq = (u64) freq * (u64) Div;
 	OscFreq *= (u64) 16384;
-	do_div(OscFreq, (u64)16000000);
+	do_div(OscFreq, 16000000);
 	MainDiv = OscFreq;
 
 	state->m_Regs[MPD] = PostDiv & 0x77;
@@ -352,7 +352,7 @@
 	OscFreq = (u64)freq * (u64)Div;
 	/* CalDiv = u32( OscFreq * 16384 / 16000000 ); */
 	OscFreq *= (u64)16384;
-	do_div(OscFreq, (u64)16000000);
+	do_div(OscFreq, 16000000);
 	CalDiv = OscFreq;
 
 	state->m_Regs[CPD] = PostDiv;
--- linux-qcom-6.8.0.orig/drivers/media/dvb-frontends/ts2020.c
+++ linux-qcom-6.8.0/drivers/media/dvb-frontends/ts2020.c
@@ -553,13 +553,19 @@
 static int ts2020_probe(struct i2c_client *client)
 {
 	struct ts2020_config *pdata = client->dev.platform_data;
-	struct dvb_frontend *fe = pdata->fe;
+	struct dvb_frontend *fe;
 	struct ts2020_priv *dev;
 	int ret;
 	u8 u8tmp;
 	unsigned int utmp;
 	char *chip_str;
 
+	if (!pdata) {
+		dev_err(&client->dev, "platform data is mandatory\n");
+		return -EINVAL;
+	}
+
+	fe = pdata->fe;
 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
 	if (!dev) {
 		ret = -ENOMEM;
--- linux-qcom-6.8.0.orig/drivers/media/i2c/Kconfig
+++ linux-qcom-6.8.0/drivers/media/i2c/Kconfig
@@ -675,6 +675,7 @@
 	tristate "THine THP7312 support"
 	depends on I2C
 	select FW_LOADER
+	select FW_UPLOAD
 	select MEDIA_CONTROLLER
 	select V4L2_CCI_I2C
 	select V4L2_FWNODE
--- linux-qcom-6.8.0.orig/drivers/media/i2c/adv7604.c
+++ linux-qcom-6.8.0/drivers/media/i2c/adv7604.c
@@ -1405,12 +1405,13 @@
 	if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs, 0,
 			(stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
 			(stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
-			false, timings))
+			false, adv76xx_get_dv_timings_cap(sd, -1), timings))
 		return 0;
 	if (v4l2_detect_gtf(stdi->lcf + 1, hfreq, stdi->lcvs,
 			(stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
 			(stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
-			false, state->aspect_ratio, timings))
+			false, state->aspect_ratio,
+			adv76xx_get_dv_timings_cap(sd, -1), timings))
 		return 0;
 
 	v4l2_dbg(2, debug, sd,
@@ -2519,10 +2520,10 @@
 	const struct adv76xx_chip_info *info = state->info;
 	struct v4l2_dv_timings timings;
 	struct stdi_readback stdi;
-	u8 reg_io_0x02 = io_read(sd, 0x02);
+	int ret;
+	u8 reg_io_0x02;
 	u8 edid_enabled;
 	u8 cable_det;
-
 	static const char * const csc_coeff_sel_rb[16] = {
 		"bypassed", "YPbPr601 -> RGB", "reserved", "YPbPr709 -> RGB",
 		"reserved", "RGB -> YPbPr601", "reserved", "RGB -> YPbPr709",
@@ -2621,13 +2622,21 @@
 	v4l2_info(sd, "-----Color space-----\n");
 	v4l2_info(sd, "RGB quantization range ctrl: %s\n",
 			rgb_quantization_range_txt[state->rgb_quantization_range]);
-	v4l2_info(sd, "Input color space: %s\n",
-			input_color_space_txt[reg_io_0x02 >> 4]);
-	v4l2_info(sd, "Output color space: %s %s, alt-gamma %s\n",
-			(reg_io_0x02 & 0x02) ? "RGB" : "YCbCr",
-			(((reg_io_0x02 >> 2) & 0x01) ^ (reg_io_0x02 & 0x01)) ?
-				"(16-235)" : "(0-255)",
-			(reg_io_0x02 & 0x08) ? "enabled" : "disabled");
+
+	ret = io_read(sd, 0x02);
+	if (ret < 0) {
+		v4l2_info(sd, "Can't read Input/Output color space\n");
+	} else {
+		reg_io_0x02 = ret;
+
+		v4l2_info(sd, "Input color space: %s\n",
+				input_color_space_txt[reg_io_0x02 >> 4]);
+		v4l2_info(sd, "Output color space: %s %s, alt-gamma %s\n",
+				(reg_io_0x02 & 0x02) ? "RGB" : "YCbCr",
+				(((reg_io_0x02 >> 2) & 0x01) ^ (reg_io_0x02 & 0x01)) ?
+					"(16-235)" : "(0-255)",
+				(reg_io_0x02 & 0x08) ? "enabled" : "disabled");
+	}
 	v4l2_info(sd, "Color space conversion: %s\n",
 			csc_coeff_sel_rb[cp_read(sd, info->cp_csc) >> 4]);
 
--- linux-qcom-6.8.0.orig/drivers/media/i2c/adv7842.c
+++ linux-qcom-6.8.0/drivers/media/i2c/adv7842.c
@@ -1431,14 +1431,15 @@
 	}
 
 	if (v4l2_detect_cvt(stdi->lcf + 1, hfreq, stdi->lcvs, 0,
-			(stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
-			(stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
-			false, timings))
+			    (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
+			    (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
+			    false, adv7842_get_dv_timings_cap(sd), timings))
 		return 0;
 	if (v4l2_detect_gtf(stdi->lcf + 1, hfreq, stdi->lcvs,
-			(stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
-			(stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
-			false, state->aspect_ratio, timings))
+			    (stdi->hs_pol == '+' ? V4L2_DV_HSYNC_POS_POL : 0) |
+			    (stdi->vs_pol == '+' ? V4L2_DV_VSYNC_POS_POL : 0),
+			    false, state->aspect_ratio,
+			    adv7842_get_dv_timings_cap(sd), timings))
 		return 0;
 
 	v4l2_dbg(2, debug, sd,
--- linux-qcom-6.8.0.orig/drivers/media/i2c/alvium-csi2.c
+++ linux-qcom-6.8.0/drivers/media/i2c/alvium-csi2.c
@@ -2002,7 +2002,7 @@
 	int val;
 
 	switch (ctrl->id) {
-	case V4L2_CID_GAIN:
+	case V4L2_CID_ANALOGUE_GAIN:
 		val = alvium_get_gain(alvium);
 		if (val < 0)
 			return val;
@@ -2034,7 +2034,7 @@
 		return 0;
 
 	switch (ctrl->id) {
-	case V4L2_CID_GAIN:
+	case V4L2_CID_ANALOGUE_GAIN:
 		ret = alvium_set_ctrl_gain(alvium, ctrl->val);
 		break;
 	case V4L2_CID_AUTOGAIN:
@@ -2163,7 +2163,7 @@
 
 	if (alvium->avail_ft.gain) {
 		ctrls->gain = v4l2_ctrl_new_std(hdl, ops,
-						V4L2_CID_GAIN,
+						V4L2_CID_ANALOGUE_GAIN,
 						alvium->min_gain,
 						alvium->max_gain,
 						alvium->inc_gain,
--- linux-qcom-6.8.0.orig/drivers/media/i2c/ar0521.c
+++ linux-qcom-6.8.0/drivers/media/i2c/ar0521.c
@@ -255,10 +255,10 @@
 			continue; /* Minimum value */
 		if (new_mult > 254)
 			break; /* Maximum, larger pre won't work either */
-		if (sensor->extclk_freq * (u64)new_mult < AR0521_PLL_MIN *
+		if (sensor->extclk_freq * (u64)new_mult < (u64)AR0521_PLL_MIN *
 		    new_pre)
 			continue;
-		if (sensor->extclk_freq * (u64)new_mult > AR0521_PLL_MAX *
+		if (sensor->extclk_freq * (u64)new_mult > (u64)AR0521_PLL_MAX *
 		    new_pre)
 			break; /* Larger pre won't work either */
 		new_pll = div64_round_up(sensor->extclk_freq * (u64)new_mult,
@@ -844,7 +844,8 @@
 	clk_disable_unprepare(sensor->extclk);
 
 	if (sensor->reset_gpio)
-		gpiod_set_value(sensor->reset_gpio, 1); /* assert RESET signal */
+		/* assert RESET signal */
+		gpiod_set_value_cansleep(sensor->reset_gpio, 1);
 
 	for (i = ARRAY_SIZE(ar0521_supply_names) - 1; i >= 0; i--) {
 		if (sensor->supplies[i])
@@ -878,7 +879,7 @@
 
 	if (sensor->reset_gpio)
 		/* deassert RESET signal */
-		gpiod_set_value(sensor->reset_gpio, 0);
+		gpiod_set_value_cansleep(sensor->reset_gpio, 0);
 	usleep_range(4500, 5000); /* min 45000 clocks */
 
 	for (cnt = 0; cnt < ARRAY_SIZE(initial_regs); cnt++) {
--- linux-qcom-6.8.0.orig/drivers/media/i2c/ccs/ccs-core.c
+++ linux-qcom-6.8.0/drivers/media/i2c/ccs/ccs-core.c
@@ -674,7 +674,7 @@
 		break;
 	}
 
-	pm_status = pm_runtime_get_if_active(&client->dev, true);
+	pm_status = pm_runtime_get_if_active(&client->dev);
 	if (!pm_status)
 		return 0;
 
@@ -3566,15 +3566,15 @@
 out_cleanup:
 	ccs_cleanup(sensor);
 
+out_free_ccs_limits:
+	kfree(sensor->ccs_limits);
+
 out_release_mdata:
 	kvfree(sensor->mdata.backing);
 
 out_release_sdata:
 	kvfree(sensor->sdata.backing);
 
-out_free_ccs_limits:
-	kfree(sensor->ccs_limits);
-
 out_power_off:
 	ccs_power_off(&client->dev);
 	mutex_destroy(&sensor->mutex);
--- linux-qcom-6.8.0.orig/drivers/media/i2c/ccs/ccs-data.c
+++ linux-qcom-6.8.0/drivers/media/i2c/ccs/ccs-data.c
@@ -10,6 +10,7 @@
 #include <linux/limits.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 
 #include "ccs-data-defs.h"
 
@@ -97,7 +98,7 @@
 		plen = ((size_t)
 			(__len3->length[0] &
 			 ((1 << CCS_DATA_LENGTH_SPECIFIER_SIZE_SHIFT) - 1))
-			<< 16) + (__len3->length[0] << 8) + __len3->length[1];
+			<< 16) + (__len3->length[1] << 8) + __len3->length[2];
 		break;
 	}
 	default:
@@ -948,15 +949,15 @@
 
 	rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, verbose);
 	if (rval)
-		return rval;
+		goto out_cleanup;
 
 	rval = bin_backing_alloc(&bin);
 	if (rval)
-		return rval;
+		goto out_cleanup;
 
 	rval = __ccs_data_parse(&bin, ccsdata, data, len, dev, false);
 	if (rval)
-		goto out_free;
+		goto out_cleanup;
 
 	if (verbose && ccsdata->version)
 		print_ccs_data_version(dev, ccsdata->version);
@@ -965,15 +966,16 @@
 		rval = -EPROTO;
 		dev_dbg(dev, "parsing mismatch; base %p; now %p; end %p\n",
 			bin.base, bin.now, bin.end);
-		goto out_free;
+		goto out_cleanup;
 	}
 
 	ccsdata->backing = bin.base;
 
 	return 0;
 
-out_free:
+out_cleanup:
 	kvfree(bin.base);
+	memset(ccsdata, 0, sizeof(*ccsdata));
 
 	return rval;
 }
--- linux-qcom-6.8.0.orig/drivers/media/i2c/ds90ub913.c
+++ linux-qcom-6.8.0/drivers/media/i2c/ds90ub913.c
@@ -793,7 +793,6 @@
 	v4l2_async_unregister_subdev(&priv->sd);
 	ub913_v4l2_nf_unregister(priv);
 	v4l2_subdev_cleanup(&priv->sd);
-	fwnode_handle_put(priv->sd.fwnode);
 	media_entity_cleanup(&priv->sd.entity);
 }
 
--- linux-qcom-6.8.0.orig/drivers/media/i2c/ds90ub953.c
+++ linux-qcom-6.8.0/drivers/media/i2c/ds90ub953.c
@@ -1291,7 +1291,6 @@
 	v4l2_async_unregister_subdev(&priv->sd);
 	ub953_v4l2_notifier_unregister(priv);
 	v4l2_subdev_cleanup(&priv->sd);
-	fwnode_handle_put(priv->sd.fwnode);
 	media_entity_cleanup(&priv->sd.entity);
 }
 
--- linux-qcom-6.8.0.orig/drivers/media/i2c/ds90ub960.c
+++ linux-qcom-6.8.0/drivers/media/i2c/ds90ub960.c
@@ -352,6 +352,8 @@
 
 #define UB960_SR_I2C_RX_ID(n)			(0xf8 + (n)) /* < UB960_FPD_RX_NPORTS */
 
+#define UB9702_SR_REFCLK_FREQ			0x3d
+
 /* Indirect register blocks */
 #define UB960_IND_TARGET_PAT_GEN		0x00
 #define UB960_IND_TARGET_RX_ANA(n)		(0x01 + (n))
@@ -1286,7 +1288,7 @@
 
 	clk_delay += v & UB960_IR_RX_ANA_STROBE_SET_CLK_DELAY_MASK;
 
-	ub960_rxport_read(priv, nport, UB960_RR_SFILTER_STS_1, &v);
+	ret = ub960_rxport_read(priv, nport, UB960_RR_SFILTER_STS_1, &v);
 	if (ret)
 		return ret;
 
@@ -1575,16 +1577,24 @@
 
 		ub960_rxport_read16(priv, nport, UB960_RR_RX_FREQ_HIGH, &v);
 
-		ret = ub960_rxport_get_strobe_pos(priv, nport, &strobe_pos);
-		if (ret)
-			return ret;
+		if (priv->hw_data->is_ub9702) {
+			dev_dbg(dev, "\trx%u: locked, freq %llu Hz\n",
+				nport, (v * 1000000ULL) >> 8);
+		} else {
+			ret = ub960_rxport_get_strobe_pos(priv, nport,
+							  &strobe_pos);
+			if (ret)
+				return ret;
 
-		ret = ub960_rxport_get_eq_level(priv, nport, &eq_level);
-		if (ret)
-			return ret;
+			ret = ub960_rxport_get_eq_level(priv, nport, &eq_level);
+			if (ret)
+				return ret;
 
-		dev_dbg(dev, "\trx%u: locked, SP: %d, EQ: %u, freq %llu Hz\n",
-			nport, strobe_pos, eq_level, (v * 1000000ULL) >> 8);
+			dev_dbg(dev,
+				"\trx%u: locked, SP: %d, EQ: %u, freq %llu Hz\n",
+				nport, strobe_pos, eq_level,
+				(v * 1000000ULL) >> 8);
+		}
 	}
 
 	return 0;
@@ -2523,7 +2533,7 @@
 				for (i = 0; i < 8; i++)
 					ub960_rxport_write(priv, nport,
 							   UB960_RR_VC_ID_MAP(i),
-							   nport);
+							   (nport << 4) | nport);
 			}
 
 			break;
@@ -2940,6 +2950,54 @@
 	.set_fmt = ub960_set_fmt,
 };
 
+static void ub960_log_status_ub960_sp_eq(struct ub960_data *priv,
+					 unsigned int nport)
+{
+	struct device *dev = &priv->client->dev;
+	u8 eq_level;
+	s8 strobe_pos;
+	u8 v = 0;
+
+	/* Strobe */
+
+	ub960_read(priv, UB960_XR_AEQ_CTL1, &v);
+
+	dev_info(dev, "\t%s strobe\n",
+		 (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) ? "Adaptive" :
+							  "Manual");
+
+	if (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) {
+		ub960_read(priv, UB960_XR_SFILTER_CFG, &v);
+
+		dev_info(dev, "\tStrobe range [%d, %d]\n",
+			 ((v >> UB960_XR_SFILTER_CFG_SFILTER_MIN_SHIFT) & 0xf) - 7,
+			 ((v >> UB960_XR_SFILTER_CFG_SFILTER_MAX_SHIFT) & 0xf) - 7);
+	}
+
+	ub960_rxport_get_strobe_pos(priv, nport, &strobe_pos);
+
+	dev_info(dev, "\tStrobe pos %d\n", strobe_pos);
+
+	/* EQ */
+
+	ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v);
+
+	dev_info(dev, "\t%s EQ\n",
+		 (v & UB960_RR_AEQ_BYPASS_ENABLE) ? "Manual" :
+						    "Adaptive");
+
+	if (!(v & UB960_RR_AEQ_BYPASS_ENABLE)) {
+		ub960_rxport_read(priv, nport, UB960_RR_AEQ_MIN_MAX, &v);
+
+		dev_info(dev, "\tEQ range [%u, %u]\n",
+			 (v >> UB960_RR_AEQ_MIN_MAX_AEQ_FLOOR_SHIFT) & 0xf,
+			 (v >> UB960_RR_AEQ_MIN_MAX_AEQ_MAX_SHIFT) & 0xf);
+	}
+
+	if (ub960_rxport_get_eq_level(priv, nport, &eq_level) == 0)
+		dev_info(dev, "\tEQ level %u\n", eq_level);
+}
+
 static int ub960_log_status(struct v4l2_subdev *sd)
 {
 	struct ub960_data *priv = sd_to_ub960(sd);
@@ -2987,8 +3045,6 @@
 
 	for (nport = 0; nport < priv->hw_data->num_rxports; nport++) {
 		struct ub960_rxport *rxport = priv->rxports[nport];
-		u8 eq_level;
-		s8 strobe_pos;
 		unsigned int i;
 
 		dev_info(dev, "RX %u\n", nport);
@@ -3024,44 +3080,8 @@
 		ub960_rxport_read(priv, nport, UB960_RR_CSI_ERR_COUNTER, &v);
 		dev_info(dev, "\tcsi_err_counter %u\n", v);
 
-		/* Strobe */
-
-		ub960_read(priv, UB960_XR_AEQ_CTL1, &v);
-
-		dev_info(dev, "\t%s strobe\n",
-			 (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) ? "Adaptive" :
-								  "Manual");
-
-		if (v & UB960_XR_AEQ_CTL1_AEQ_SFILTER_EN) {
-			ub960_read(priv, UB960_XR_SFILTER_CFG, &v);
-
-			dev_info(dev, "\tStrobe range [%d, %d]\n",
-				 ((v >> UB960_XR_SFILTER_CFG_SFILTER_MIN_SHIFT) & 0xf) - 7,
-				 ((v >> UB960_XR_SFILTER_CFG_SFILTER_MAX_SHIFT) & 0xf) - 7);
-		}
-
-		ub960_rxport_get_strobe_pos(priv, nport, &strobe_pos);
-
-		dev_info(dev, "\tStrobe pos %d\n", strobe_pos);
-
-		/* EQ */
-
-		ub960_rxport_read(priv, nport, UB960_RR_AEQ_BYPASS, &v);
-
-		dev_info(dev, "\t%s EQ\n",
-			 (v & UB960_RR_AEQ_BYPASS_ENABLE) ? "Manual" :
-							    "Adaptive");
-
-		if (!(v & UB960_RR_AEQ_BYPASS_ENABLE)) {
-			ub960_rxport_read(priv, nport, UB960_RR_AEQ_MIN_MAX, &v);
-
-			dev_info(dev, "\tEQ range [%u, %u]\n",
-				 (v >> UB960_RR_AEQ_MIN_MAX_AEQ_FLOOR_SHIFT) & 0xf,
-				 (v >> UB960_RR_AEQ_MIN_MAX_AEQ_MAX_SHIFT) & 0xf);
-		}
-
-		if (ub960_rxport_get_eq_level(priv, nport, &eq_level) == 0)
-			dev_info(dev, "\tEQ level %u\n", eq_level);
+		if (!priv->hw_data->is_ub9702)
+			ub960_log_status_ub960_sp_eq(priv, nport);
 
 		/* GPIOs */
 		for (i = 0; i < UB960_NUM_BC_GPIOS; i++) {
@@ -3837,7 +3857,10 @@
 	if (ret)
 		goto err_pd_gpio;
 
-	ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq);
+	if (priv->hw_data->is_ub9702)
+		ret = ub960_read(priv, UB9702_SR_REFCLK_FREQ, &refclk_freq);
+	else
+		ret = ub960_read(priv, UB960_XR_REFCLK_FREQ, &refclk_freq);
 	if (ret)
 		goto err_pd_gpio;
 
--- linux-qcom-6.8.0.orig/drivers/media/i2c/dw9768.c
+++ linux-qcom-6.8.0/drivers/media/i2c/dw9768.c
@@ -476,10 +476,9 @@
 	 * to be powered on in an ACPI system. Similarly for power off in
 	 * remove.
 	 */
-	pm_runtime_enable(dev);
 	full_power = (is_acpi_node(dev_fwnode(dev)) &&
 		      acpi_dev_state_d0(dev)) ||
-		     (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev));
+		     (is_of_node(dev_fwnode(dev)) && !IS_ENABLED(CONFIG_PM));
 	if (full_power) {
 		ret = dw9768_runtime_resume(dev);
 		if (ret < 0) {
@@ -489,6 +488,7 @@
 		pm_runtime_set_active(dev);
 	}
 
+	pm_runtime_enable(dev);
 	ret = v4l2_async_register_subdev(&dw9768->sd);
 	if (ret < 0) {
 		dev_err(dev, "failed to register V4L2 subdev: %d", ret);
@@ -500,12 +500,12 @@
 	return 0;
 
 err_power_off:
+	pm_runtime_disable(dev);
 	if (full_power) {
 		dw9768_runtime_suspend(dev);
 		pm_runtime_set_suspended(dev);
 	}
 err_clean_entity:
-	pm_runtime_disable(dev);
 	media_entity_cleanup(&dw9768->sd.entity);
 err_free_handler:
 	v4l2_ctrl_handler_free(&dw9768->ctrls);
@@ -522,12 +522,12 @@
 	v4l2_async_unregister_subdev(&dw9768->sd);
 	v4l2_ctrl_handler_free(&dw9768->ctrls);
 	media_entity_cleanup(&dw9768->sd.entity);
+	pm_runtime_disable(dev);
 	if ((is_acpi_node(dev_fwnode(dev)) && acpi_dev_state_d0(dev)) ||
-	    (is_of_node(dev_fwnode(dev)) && !pm_runtime_enabled(dev))) {
+	    (is_of_node(dev_fwnode(dev)) && !IS_ENABLED(CONFIG_PM))) {
 		dw9768_runtime_suspend(dev);
 		pm_runtime_set_suspended(dev);
 	}
-	pm_runtime_disable(dev);
 }
 
 static const struct of_device_id dw9768_of_table[] = {
--- linux-qcom-6.8.0.orig/drivers/media/i2c/et8ek8/et8ek8_driver.c
+++ linux-qcom-6.8.0/drivers/media/i2c/et8ek8/et8ek8_driver.c
@@ -1475,7 +1475,7 @@
 	return ret;
 }
 
-static void __exit et8ek8_remove(struct i2c_client *client)
+static void et8ek8_remove(struct i2c_client *client)
 {
 	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
 	struct et8ek8_sensor *sensor = to_et8ek8_sensor(subdev);
@@ -1517,7 +1517,7 @@
 		.of_match_table	= et8ek8_of_table,
 	},
 	.probe		= et8ek8_probe,
-	.remove		= __exit_p(et8ek8_remove),
+	.remove		= et8ek8_remove,
 	.id_table	= et8ek8_id_table,
 };
 
--- linux-qcom-6.8.0.orig/drivers/media/i2c/hi846.c
+++ linux-qcom-6.8.0/drivers/media/i2c/hi846.c
@@ -1851,7 +1851,7 @@
 		mutex_lock(&hi846->mutex);
 		switch (sel->which) {
 		case V4L2_SUBDEV_FORMAT_TRY:
-			v4l2_subdev_state_get_crop(sd_state, sel->pad);
+			sel->r = *v4l2_subdev_state_get_crop(sd_state, sel->pad);
 			break;
 		case V4L2_SUBDEV_FORMAT_ACTIVE:
 			sel->r = hi846->cur_mode->crop;
--- linux-qcom-6.8.0.orig/drivers/media/i2c/imx219.c
+++ linux-qcom-6.8.0/drivers/media/i2c/imx219.c
@@ -162,8 +162,8 @@
 	{ IMX219_REG_MODE_SELECT, 0x00 },	/* Mode Select */
 
 	/* To Access Addresses 3000-5fff, send the following commands */
-	{ CCI_REG8(0x30eb), 0x0c },
 	{ CCI_REG8(0x30eb), 0x05 },
+	{ CCI_REG8(0x30eb), 0x0c },
 	{ CCI_REG8(0x300a), 0xff },
 	{ CCI_REG8(0x300b), 0xff },
 	{ CCI_REG8(0x30eb), 0x05 },
--- linux-qcom-6.8.0.orig/drivers/media/i2c/imx290.c
+++ linux-qcom-6.8.0/drivers/media/i2c/imx290.c
@@ -150,10 +150,10 @@
 
 #define IMX290_PIXEL_ARRAY_WIDTH			1945
 #define IMX290_PIXEL_ARRAY_HEIGHT			1097
-#define IMX920_PIXEL_ARRAY_MARGIN_LEFT			12
-#define IMX920_PIXEL_ARRAY_MARGIN_RIGHT			13
-#define IMX920_PIXEL_ARRAY_MARGIN_TOP			8
-#define IMX920_PIXEL_ARRAY_MARGIN_BOTTOM		9
+#define IMX290_PIXEL_ARRAY_MARGIN_LEFT			12
+#define IMX290_PIXEL_ARRAY_MARGIN_RIGHT			13
+#define IMX290_PIXEL_ARRAY_MARGIN_TOP			8
+#define IMX290_PIXEL_ARRAY_MARGIN_BOTTOM		9
 #define IMX290_PIXEL_ARRAY_RECORDING_WIDTH		1920
 #define IMX290_PIXEL_ARRAY_RECORDING_HEIGHT		1080
 
@@ -269,7 +269,6 @@
 	{ IMX290_WINWV, 1097 },
 	{ IMX290_XSOUTSEL, IMX290_XSOUTSEL_XVSOUTSEL_VSYNC |
 			   IMX290_XSOUTSEL_XHSOUTSEL_HSYNC },
-	{ CCI_REG8(0x3011), 0x02 },
 	{ CCI_REG8(0x3012), 0x64 },
 	{ CCI_REG8(0x3013), 0x00 },
 };
@@ -277,6 +276,7 @@
 static const struct cci_reg_sequence imx290_global_init_settings_290[] = {
 	{ CCI_REG8(0x300f), 0x00 },
 	{ CCI_REG8(0x3010), 0x21 },
+	{ CCI_REG8(0x3011), 0x00 },
 	{ CCI_REG8(0x3016), 0x09 },
 	{ CCI_REG8(0x3070), 0x02 },
 	{ CCI_REG8(0x3071), 0x11 },
@@ -330,6 +330,7 @@
 };
 
 static const struct cci_reg_sequence imx290_global_init_settings_327[] = {
+	{ CCI_REG8(0x3011), 0x02 },
 	{ CCI_REG8(0x309e), 0x4A },
 	{ CCI_REG8(0x309f), 0x4A },
 	{ CCI_REG8(0x313b), 0x61 },
@@ -1161,10 +1162,10 @@
 		 * The sensor moves the readout by 1 pixel based on flips to
 		 * keep the Bayer order the same.
 		 */
-		sel->r.top = IMX920_PIXEL_ARRAY_MARGIN_TOP
+		sel->r.top = IMX290_PIXEL_ARRAY_MARGIN_TOP
 			   + (IMX290_PIXEL_ARRAY_RECORDING_HEIGHT - format->height) / 2
 			   + imx290->vflip->val;
-		sel->r.left = IMX920_PIXEL_ARRAY_MARGIN_LEFT
+		sel->r.left = IMX290_PIXEL_ARRAY_MARGIN_LEFT
 			    + (IMX290_PIXEL_ARRAY_RECORDING_WIDTH - format->width) / 2
 			    + imx290->hflip->val;
 		sel->r.width = format->width;
@@ -1183,8 +1184,8 @@
 		return 0;
 
 	case V4L2_SEL_TGT_CROP_DEFAULT:
-		sel->r.top = IMX920_PIXEL_ARRAY_MARGIN_TOP;
-		sel->r.left = IMX920_PIXEL_ARRAY_MARGIN_LEFT;
+		sel->r.top = IMX290_PIXEL_ARRAY_MARGIN_TOP;
+		sel->r.left = IMX290_PIXEL_ARRAY_MARGIN_LEFT;
 		sel->r.width = IMX290_PIXEL_ARRAY_RECORDING_WIDTH;
 		sel->r.height = IMX290_PIXEL_ARRAY_RECORDING_HEIGHT;
 
--- linux-qcom-6.8.0.orig/drivers/media/i2c/imx296.c
+++ linux-qcom-6.8.0/drivers/media/i2c/imx296.c
@@ -954,6 +954,8 @@
 		return ret;
 	}
 
+	usleep_range(2000, 5000);
+
 	ret = imx296_read(sensor, IMX296_SENSOR_INFO);
 	if (ret < 0) {
 		dev_err(sensor->dev, "failed to read sensor information (%d)\n",
--- linux-qcom-6.8.0.orig/drivers/media/i2c/imx335.c
+++ linux-qcom-6.8.0/drivers/media/i2c/imx335.c
@@ -889,7 +889,7 @@
 
 	/* Request optional reset pin */
 	imx335->reset_gpio = devm_gpiod_get_optional(imx335->dev, "reset",
-						     GPIOD_OUT_LOW);
+						     GPIOD_OUT_HIGH);
 	if (IS_ERR(imx335->reset_gpio)) {
 		dev_err(imx335->dev, "failed to get reset gpio %ld\n",
 			PTR_ERR(imx335->reset_gpio));
@@ -1004,8 +1004,7 @@
 
 	usleep_range(500, 550); /* Tlow */
 
-	/* Set XCLR */
-	gpiod_set_value_cansleep(imx335->reset_gpio, 1);
+	gpiod_set_value_cansleep(imx335->reset_gpio, 0);
 
 	ret = clk_prepare_enable(imx335->inclk);
 	if (ret) {
@@ -1018,7 +1017,7 @@
 	return 0;
 
 error_reset:
-	gpiod_set_value_cansleep(imx335->reset_gpio, 0);
+	gpiod_set_value_cansleep(imx335->reset_gpio, 1);
 	regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies);
 
 	return ret;
@@ -1035,7 +1034,7 @@
 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
 	struct imx335 *imx335 = to_imx335(sd);
 
-	gpiod_set_value_cansleep(imx335->reset_gpio, 0);
+	gpiod_set_value_cansleep(imx335->reset_gpio, 1);
 	clk_disable_unprepare(imx335->inclk);
 	regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies);
 
--- linux-qcom-6.8.0.orig/drivers/media/i2c/imx412.c
+++ linux-qcom-6.8.0/drivers/media/i2c/imx412.c
@@ -542,14 +542,13 @@
  */
 static int imx412_update_exp_gain(struct imx412 *imx412, u32 exposure, u32 gain)
 {
-	u32 lpfr, shutter;
+	u32 lpfr;
 	int ret;
 
 	lpfr = imx412->vblank + imx412->cur_mode->height;
-	shutter = lpfr - exposure;
 
-	dev_dbg(imx412->dev, "Set exp %u, analog gain %u, shutter %u, lpfr %u",
-		exposure, gain, shutter, lpfr);
+	dev_dbg(imx412->dev, "Set exp %u, analog gain %u, lpfr %u\n",
+		exposure, gain, lpfr);
 
 	ret = imx412_write_reg(imx412, IMX412_REG_HOLD, 1, 1);
 	if (ret)
@@ -559,7 +558,7 @@
 	if (ret)
 		goto error_release_group_hold;
 
-	ret = imx412_write_reg(imx412, IMX412_REG_EXPOSURE_CIT, 2, shutter);
+	ret = imx412_write_reg(imx412, IMX412_REG_EXPOSURE_CIT, 2, exposure);
 	if (ret)
 		goto error_release_group_hold;
 
@@ -595,7 +594,7 @@
 	case V4L2_CID_VBLANK:
 		imx412->vblank = imx412->vblank_ctrl->val;
 
-		dev_dbg(imx412->dev, "Received vblank %u, new lpfr %u",
+		dev_dbg(imx412->dev, "Received vblank %u, new lpfr %u\n",
 			imx412->vblank,
 			imx412->vblank + imx412->cur_mode->height);
 
@@ -614,7 +613,7 @@
 		exposure = ctrl->val;
 		analog_gain = imx412->again_ctrl->val;
 
-		dev_dbg(imx412->dev, "Received exp %u, analog gain %u",
+		dev_dbg(imx412->dev, "Received exp %u, analog gain %u\n",
 			exposure, analog_gain);
 
 		ret = imx412_update_exp_gain(imx412, exposure, analog_gain);
@@ -623,7 +622,7 @@
 
 		break;
 	default:
-		dev_err(imx412->dev, "Invalid control %d", ctrl->id);
+		dev_err(imx412->dev, "Invalid control %d\n", ctrl->id);
 		ret = -EINVAL;
 	}
 
@@ -804,14 +803,14 @@
 	ret = imx412_write_regs(imx412, reg_list->regs,
 				reg_list->num_of_regs);
 	if (ret) {
-		dev_err(imx412->dev, "fail to write initial registers");
+		dev_err(imx412->dev, "fail to write initial registers\n");
 		return ret;
 	}
 
 	/* Setup handler will write actual exposure and gain */
 	ret =  __v4l2_ctrl_handler_setup(imx412->sd.ctrl_handler);
 	if (ret) {
-		dev_err(imx412->dev, "fail to setup handler");
+		dev_err(imx412->dev, "fail to setup handler\n");
 		return ret;
 	}
 
@@ -822,7 +821,7 @@
 	ret = imx412_write_reg(imx412, IMX412_REG_MODE_SELECT,
 			       1, IMX412_MODE_STREAMING);
 	if (ret) {
-		dev_err(imx412->dev, "fail to start streaming");
+		dev_err(imx412->dev, "fail to start streaming\n");
 		return ret;
 	}
 
@@ -896,7 +895,7 @@
 		return ret;
 
 	if (val != IMX412_ID) {
-		dev_err(imx412->dev, "chip id mismatch: %x!=%x",
+		dev_err(imx412->dev, "chip id mismatch: %x!=%x\n",
 			IMX412_ID, val);
 		return -ENXIO;
 	}
@@ -928,7 +927,7 @@
 	imx412->reset_gpio = devm_gpiod_get_optional(imx412->dev, "reset",
 						     GPIOD_OUT_LOW);
 	if (IS_ERR(imx412->reset_gpio)) {
-		dev_err(imx412->dev, "failed to get reset gpio %ld",
+		dev_err(imx412->dev, "failed to get reset gpio %ld\n",
 			PTR_ERR(imx412->reset_gpio));
 		return PTR_ERR(imx412->reset_gpio);
 	}
@@ -936,13 +935,13 @@
 	/* Get sensor input clock */
 	imx412->inclk = devm_clk_get(imx412->dev, NULL);
 	if (IS_ERR(imx412->inclk)) {
-		dev_err(imx412->dev, "could not get inclk");
+		dev_err(imx412->dev, "could not get inclk\n");
 		return PTR_ERR(imx412->inclk);
 	}
 
 	rate = clk_get_rate(imx412->inclk);
 	if (rate != IMX412_INCLK_RATE) {
-		dev_err(imx412->dev, "inclk frequency mismatch");
+		dev_err(imx412->dev, "inclk frequency mismatch\n");
 		return -EINVAL;
 	}
 
@@ -967,14 +966,14 @@
 
 	if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX412_NUM_DATA_LANES) {
 		dev_err(imx412->dev,
-			"number of CSI2 data lanes %d is not supported",
+			"number of CSI2 data lanes %d is not supported\n",
 			bus_cfg.bus.mipi_csi2.num_data_lanes);
 		ret = -EINVAL;
 		goto done_endpoint_free;
 	}
 
 	if (!bus_cfg.nr_of_link_frequencies) {
-		dev_err(imx412->dev, "no link frequencies defined");
+		dev_err(imx412->dev, "no link frequencies defined\n");
 		ret = -EINVAL;
 		goto done_endpoint_free;
 	}
@@ -1035,7 +1034,7 @@
 
 	ret = clk_prepare_enable(imx412->inclk);
 	if (ret) {
-		dev_err(imx412->dev, "fail to enable inclk");
+		dev_err(imx412->dev, "fail to enable inclk\n");
 		goto error_reset;
 	}
 
@@ -1146,7 +1145,7 @@
 		imx412->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 
 	if (ctrl_hdlr->error) {
-		dev_err(imx412->dev, "control init failed: %d",
+		dev_err(imx412->dev, "control init failed: %d\n",
 			ctrl_hdlr->error);
 		v4l2_ctrl_handler_free(ctrl_hdlr);
 		return ctrl_hdlr->error;
@@ -1184,7 +1183,7 @@
 
 	ret = imx412_parse_hw_config(imx412);
 	if (ret) {
-		dev_err(imx412->dev, "HW configuration is not supported");
+		dev_err(imx412->dev, "HW configuration is not supported\n");
 		return ret;
 	}
 
@@ -1192,14 +1191,14 @@
 
 	ret = imx412_power_on(imx412->dev);
 	if (ret) {
-		dev_err(imx412->dev, "failed to power-on the sensor");
+		dev_err(imx412->dev, "failed to power-on the sensor\n");
 		goto error_mutex_destroy;
 	}
 
 	/* Check module identity */
 	ret = imx412_detect(imx412);
 	if (ret) {
-		dev_err(imx412->dev, "failed to find sensor: %d", ret);
+		dev_err(imx412->dev, "failed to find sensor: %d\n", ret);
 		goto error_power_off;
 	}
 
@@ -1209,7 +1208,7 @@
 
 	ret = imx412_init_controls(imx412);
 	if (ret) {
-		dev_err(imx412->dev, "failed to init controls: %d", ret);
+		dev_err(imx412->dev, "failed to init controls: %d\n", ret);
 		goto error_power_off;
 	}
 
@@ -1223,14 +1222,14 @@
 	imx412->pad.flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_pads_init(&imx412->sd.entity, 1, &imx412->pad);
 	if (ret) {
-		dev_err(imx412->dev, "failed to init entity pads: %d", ret);
+		dev_err(imx412->dev, "failed to init entity pads: %d\n", ret);
 		goto error_handler_free;
 	}
 
 	ret = v4l2_async_register_subdev_sensor(&imx412->sd);
 	if (ret < 0) {
 		dev_err(imx412->dev,
-			"failed to register async subdev: %d", ret);
+			"failed to register async subdev: %d\n", ret);
 		goto error_media_entity;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/media/i2c/ov2680.c
+++ linux-qcom-6.8.0/drivers/media/i2c/ov2680.c
@@ -1116,25 +1116,24 @@
 	sensor->pixel_rate = sensor->link_freq[0] * 2;
 	do_div(sensor->pixel_rate, 10);
 
-	/* Verify bus cfg */
-	if (bus_cfg.bus.mipi_csi2.num_data_lanes != 1) {
-		ret = dev_err_probe(dev, -EINVAL,
-				    "only a 1-lane CSI2 config is supported");
-		goto out_free_bus_cfg;
+	if (!bus_cfg.nr_of_link_frequencies) {
+		dev_warn(dev, "Consider passing 'link-frequencies' in DT\n");
+		goto skip_link_freq_validation;
 	}
 
 	for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++)
 		if (bus_cfg.link_frequencies[i] == sensor->link_freq[0])
 			break;
 
-	if (bus_cfg.nr_of_link_frequencies == 0 ||
-	    bus_cfg.nr_of_link_frequencies == i) {
+	if (bus_cfg.nr_of_link_frequencies == i) {
 		ret = dev_err_probe(dev, -EINVAL,
 				    "supported link freq %lld not found\n",
 				    sensor->link_freq[0]);
 		goto out_free_bus_cfg;
 	}
 
+skip_link_freq_validation:
+	ret = 0;
 out_free_bus_cfg:
 	v4l2_fwnode_endpoint_free(&bus_cfg);
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/media/i2c/ov2740.c
+++ linux-qcom-6.8.0/drivers/media/i2c/ov2740.c
@@ -768,14 +768,15 @@
 	cur_mode = ov2740->cur_mode;
 	size = ARRAY_SIZE(link_freq_menu_items);
 
-	ov2740->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov2740_ctrl_ops,
-						   V4L2_CID_LINK_FREQ,
-						   size - 1, 0,
-						   link_freq_menu_items);
+	ov2740->link_freq =
+		v4l2_ctrl_new_int_menu(ctrl_hdlr, &ov2740_ctrl_ops,
+				       V4L2_CID_LINK_FREQ, size - 1,
+				       ov2740->supported_modes->link_freq_index,
+				       link_freq_menu_items);
 	if (ov2740->link_freq)
 		ov2740->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 
-	pixel_rate = to_pixel_rate(OV2740_LINK_FREQ_360MHZ_INDEX);
+	pixel_rate = to_pixel_rate(ov2740->supported_modes->link_freq_index);
 	ov2740->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov2740_ctrl_ops,
 					       V4L2_CID_PIXEL_RATE, 0,
 					       pixel_rate, 1, pixel_rate);
--- linux-qcom-6.8.0.orig/drivers/media/i2c/ov5640.c
+++ linux-qcom-6.8.0/drivers/media/i2c/ov5640.c
@@ -1982,6 +1982,7 @@
 			light_freq = 50;
 		} else {
 			/* 60Hz */
+			light_freq = 60;
 		}
 	}
 
--- linux-qcom-6.8.0.orig/drivers/media/i2c/ov5647.c
+++ linux-qcom-6.8.0/drivers/media/i2c/ov5647.c
@@ -1360,24 +1360,21 @@
 	struct v4l2_fwnode_endpoint bus_cfg = {
 		.bus_type = V4L2_MBUS_CSI2_DPHY,
 	};
-	struct device_node *ep;
+	struct device_node *ep __free(device_node) =
+		of_graph_get_endpoint_by_regs(np, 0, -1);
 	int ret;
 
-	ep = of_graph_get_next_endpoint(np, NULL);
 	if (!ep)
 		return -EINVAL;
 
 	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &bus_cfg);
 	if (ret)
-		goto out;
+		return ret;
 
 	sensor->clock_ncont = bus_cfg.bus.mipi_csi2.flags &
 			      V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK;
 
-out:
-	of_node_put(ep);
-
-	return ret;
+	return 0;
 }
 
 static int ov5647_probe(struct i2c_client *client)
--- linux-qcom-6.8.0.orig/drivers/media/i2c/ov5675.c
+++ linux-qcom-6.8.0/drivers/media/i2c/ov5675.c
@@ -972,12 +972,10 @@
 
 static int ov5675_power_off(struct device *dev)
 {
-	/* 512 xvclk cycles after the last SCCB transation or MIPI frame end */
-	u32 delay_us = DIV_ROUND_UP(512, OV5675_XVCLK_19_2 / 1000 / 1000);
 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
 	struct ov5675 *ov5675 = to_ov5675(sd);
 
-	usleep_range(delay_us, delay_us * 2);
+	usleep_range(90, 100);
 
 	clk_disable_unprepare(ov5675->xvclk);
 	gpiod_set_value_cansleep(ov5675->reset_gpio, 1);
@@ -988,7 +986,6 @@
 
 static int ov5675_power_on(struct device *dev)
 {
-	u32 delay_us = DIV_ROUND_UP(8192, OV5675_XVCLK_19_2 / 1000 / 1000);
 	struct v4l2_subdev *sd = dev_get_drvdata(dev);
 	struct ov5675 *ov5675 = to_ov5675(sd);
 	int ret;
@@ -1014,8 +1011,11 @@
 
 	gpiod_set_value_cansleep(ov5675->reset_gpio, 0);
 
-	/* 8192 xvclk cycles prior to the first SCCB transation */
-	usleep_range(delay_us, delay_us * 2);
+	/* Worst case quiesence gap is 1.365 milliseconds @ 6MHz XVCLK
+	 * Add an additional threshold grace period to ensure reset
+	 * completion before initiating our first I2C transaction.
+	 */
+	usleep_range(1500, 1600);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/media/i2c/ov64a40.c
+++ linux-qcom-6.8.0/drivers/media/i2c/ov64a40.c
@@ -3287,7 +3287,7 @@
 					 exp_max, 1, exp_val);
 	}
 
-	pm_status = pm_runtime_get_if_active(ov64a40->dev, true);
+	pm_status = pm_runtime_get_if_active(ov64a40->dev);
 	if (!pm_status)
 		return 0;
 
--- linux-qcom-6.8.0.orig/drivers/media/i2c/ov9282.c
+++ linux-qcom-6.8.0/drivers/media/i2c/ov9282.c
@@ -40,7 +40,7 @@
 /* Exposure control */
 #define OV9282_REG_EXPOSURE	0x3500
 #define OV9282_EXPOSURE_MIN	1
-#define OV9282_EXPOSURE_OFFSET	12
+#define OV9282_EXPOSURE_OFFSET	25
 #define OV9282_EXPOSURE_STEP	1
 #define OV9282_EXPOSURE_DEFAULT	0x0282
 
--- linux-qcom-6.8.0.orig/drivers/media/i2c/st-mipid02.c
+++ linux-qcom-6.8.0/drivers/media/i2c/st-mipid02.c
@@ -326,7 +326,7 @@
 	}
 
 	dev_dbg(&client->dev, "detect link_freq = %lld Hz", link_freq);
-	do_div(ui_4, link_freq);
+	ui_4 = div64_u64(ui_4, link_freq);
 	bridge->r.clk_lane_reg1 |= ui_4 << 2;
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/media/i2c/tc358743.c
+++ linux-qcom-6.8.0/drivers/media/i2c/tc358743.c
@@ -2091,9 +2091,6 @@
 	state->mbus_fmt_code = MEDIA_BUS_FMT_RGB888_1X24;
 
 	sd->dev = &client->dev;
-	err = v4l2_async_register_subdev(sd);
-	if (err < 0)
-		goto err_hdl;
 
 	mutex_init(&state->confctl_mutex);
 
@@ -2151,6 +2148,10 @@
 	if (err)
 		goto err_work_queues;
 
+	err = v4l2_async_register_subdev(sd);
+	if (err < 0)
+		goto err_work_queues;
+
 	v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
 		  client->addr << 1, client->adapter->name);
 
@@ -2158,8 +2159,10 @@
 
 err_work_queues:
 	cec_unregister_adapter(state->cec_adap);
-	if (!state->i2c_client->irq)
+	if (!state->i2c_client->irq) {
+		del_timer(&state->timer);
 		flush_work(&state->work_i2c_poll);
+	}
 	cancel_delayed_work(&state->delayed_work_enable_hotplug);
 	mutex_destroy(&state->confctl_mutex);
 err_hdl:
--- linux-qcom-6.8.0.orig/drivers/media/i2c/tc358746.c
+++ linux-qcom-6.8.0/drivers/media/i2c/tc358746.c
@@ -844,8 +844,7 @@
 			continue;
 
 		tmp = fout * p * postdiv;
-		do_div(tmp, fin);
-		mul = tmp;
+		mul = div64_ul(tmp, fin);
 		if (mul > 511)
 			continue;
 
--- linux-qcom-6.8.0.orig/drivers/media/i2c/thp7312.c
+++ linux-qcom-6.8.0/drivers/media/i2c/thp7312.c
@@ -1052,7 +1052,7 @@
 	if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
 		return -EINVAL;
 
-	if (!pm_runtime_get_if_active(thp7312->dev, true))
+	if (!pm_runtime_get_if_active(thp7312->dev))
 		return 0;
 
 	switch (ctrl->id) {
--- linux-qcom-6.8.0.orig/drivers/media/mc/mc-devnode.c
+++ linux-qcom-6.8.0/drivers/media/mc/mc-devnode.c
@@ -246,15 +246,14 @@
 	kobject_set_name(&devnode->cdev.kobj, "media%d", devnode->minor);
 
 	/* Part 3: Add the media and char device */
+	set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags);
 	ret = cdev_device_add(&devnode->cdev, &devnode->dev);
 	if (ret < 0) {
+		clear_bit(MEDIA_FLAG_REGISTERED, &devnode->flags);
 		pr_err("%s: cdev_device_add failed\n", __func__);
 		goto cdev_add_error;
 	}
 
-	/* Part 4: Activate this minor. The char device can now be used. */
-	set_bit(MEDIA_FLAG_REGISTERED, &devnode->flags);
-
 	return 0;
 
 cdev_add_error:
--- linux-qcom-6.8.0.orig/drivers/media/mc/mc-entity.c
+++ linux-qcom-6.8.0/drivers/media/mc/mc-entity.c
@@ -535,14 +535,15 @@
 
 /*
  * Move the top entry link cursor to the next link. If all links of the entry
- * have been visited, pop the entry itself.
+ * have been visited, pop the entry itself. Return true if the entry has been
+ * popped.
  */
-static void media_pipeline_walk_pop(struct media_pipeline_walk *walk)
+static bool media_pipeline_walk_pop(struct media_pipeline_walk *walk)
 {
 	struct media_pipeline_walk_entry *entry;
 
 	if (WARN_ON(walk->stack.top < 0))
-		return;
+		return false;
 
 	entry = media_pipeline_walk_top(walk);
 
@@ -552,7 +553,7 @@
 			walk->stack.top);
 
 		walk->stack.top--;
-		return;
+		return true;
 	}
 
 	entry->links = entry->links->next;
@@ -560,6 +561,8 @@
 	dev_dbg(walk->mdev->dev,
 		"media pipeline: moved entry %u to next link\n",
 		walk->stack.top);
+
+	return false;
 }
 
 /* Free all memory allocated while walking the pipeline. */
@@ -605,30 +608,30 @@
 					    struct media_pipeline_walk *walk)
 {
 	struct media_pipeline_walk_entry *entry = media_pipeline_walk_top(walk);
-	struct media_pad *pad;
+	struct media_pad *origin;
 	struct media_link *link;
 	struct media_pad *local;
 	struct media_pad *remote;
+	bool last_link;
 	int ret;
 
-	pad = entry->pad;
+	origin = entry->pad;
 	link = list_entry(entry->links, typeof(*link), list);
-	media_pipeline_walk_pop(walk);
+	last_link = media_pipeline_walk_pop(walk);
+
+	if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) != MEDIA_LNK_FL_DATA_LINK) {
+		dev_dbg(walk->mdev->dev,
+			"media pipeline: skipping link (not data-link)\n");
+		return 0;
+	}
 
 	dev_dbg(walk->mdev->dev,
 		"media pipeline: exploring link '%s':%u -> '%s':%u\n",
 		link->source->entity->name, link->source->index,
 		link->sink->entity->name, link->sink->index);
 
-	/* Skip links that are not enabled. */
-	if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
-		dev_dbg(walk->mdev->dev,
-			"media pipeline: skipping link (disabled)\n");
-		return 0;
-	}
-
 	/* Get the local pad and remote pad. */
-	if (link->source->entity == pad->entity) {
+	if (link->source->entity == origin->entity) {
 		local = link->source;
 		remote = link->sink;
 	} else {
@@ -640,25 +643,64 @@
 	 * Skip links that originate from a different pad than the incoming pad
 	 * that is not connected internally in the entity to the incoming pad.
 	 */
-	if (pad != local &&
-	    !media_entity_has_pad_interdep(pad->entity, pad->index, local->index)) {
+	if (origin != local &&
+	    !media_entity_has_pad_interdep(origin->entity, origin->index,
+					   local->index)) {
 		dev_dbg(walk->mdev->dev,
 			"media pipeline: skipping link (no route)\n");
-		return 0;
+		goto done;
 	}
 
 	/*
-	 * Add the local and remote pads of the link to the pipeline and push
-	 * them to the stack, if they're not already present.
+	 * Add the local pad of the link to the pipeline and push it to the
+	 * stack, if not already present.
 	 */
 	ret = media_pipeline_add_pad(pipe, walk, local);
 	if (ret)
 		return ret;
 
+	/* Similarly, add the remote pad, but only if the link is enabled. */
+	if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
+		dev_dbg(walk->mdev->dev,
+			"media pipeline: skipping link (disabled)\n");
+		goto done;
+	}
+
 	ret = media_pipeline_add_pad(pipe, walk, remote);
 	if (ret)
 		return ret;
 
+done:
+	/*
+	 * If we're done iterating over links, iterate over pads of the entity.
+	 * This is necessary to discover pads that are not connected with any
+	 * link. Those are dead ends from a pipeline exploration point of view,
+	 * but are still part of the pipeline and need to be added to enable
+	 * proper validation.
+	 */
+	if (!last_link)
+		return 0;
+
+	dev_dbg(walk->mdev->dev,
+		"media pipeline: adding unconnected pads of '%s'\n",
+		local->entity->name);
+
+	media_entity_for_each_pad(origin->entity, local) {
+		/*
+		 * Skip the origin pad (already handled), pad that have links
+		 * (already discovered through iterating over links) and pads
+		 * not internally connected.
+		 */
+		if (origin == local || !local->num_links ||
+		    !media_entity_has_pad_interdep(origin->entity, origin->index,
+						   local->index))
+			continue;
+
+		ret = media_pipeline_add_pad(pipe, walk, local);
+		if (ret)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -770,7 +812,6 @@
 		struct media_pad *pad = ppad->pad;
 		struct media_entity *entity = pad->entity;
 		bool has_enabled_link = false;
-		bool has_link = false;
 		struct media_link *link;
 
 		dev_dbg(mdev->dev, "Validating pad '%s':%u\n", pad->entity->name,
@@ -800,7 +841,6 @@
 			/* Record if the pad has links and enabled links. */
 			if (link->flags & MEDIA_LNK_FL_ENABLED)
 				has_enabled_link = true;
-			has_link = true;
 
 			/*
 			 * Validate the link if it's enabled and has the
@@ -838,7 +878,7 @@
 		 * 3. If the pad has the MEDIA_PAD_FL_MUST_CONNECT flag set,
 		 * ensure that it has either no link or an enabled link.
 		 */
-		if ((pad->flags & MEDIA_PAD_FL_MUST_CONNECT) && has_link &&
+		if ((pad->flags & MEDIA_PAD_FL_MUST_CONNECT) &&
 		    !has_enabled_link) {
 			dev_dbg(mdev->dev,
 				"Pad '%s':%u must be connected by an enabled link\n",
@@ -1038,6 +1078,9 @@
 
 	/* Remove the reverse links for a data link. */
 	if ((link->flags & MEDIA_LNK_FL_LINK_TYPE) == MEDIA_LNK_FL_DATA_LINK) {
+		link->source->num_links--;
+		link->sink->num_links--;
+
 		if (link->source->entity == entity)
 			remote = link->sink->entity;
 		else
@@ -1092,6 +1135,11 @@
 	struct media_link *link;
 	struct media_link *backlink;
 
+	if (flags & MEDIA_LNK_FL_LINK_TYPE)
+		return -EINVAL;
+
+	flags |= MEDIA_LNK_FL_DATA_LINK;
+
 	if (WARN_ON(!source || !sink) ||
 	    WARN_ON(source_pad >= source->num_pads) ||
 	    WARN_ON(sink_pad >= sink->num_pads))
@@ -1107,7 +1155,7 @@
 
 	link->source = &source->pads[source_pad];
 	link->sink = &sink->pads[sink_pad];
-	link->flags = flags & ~MEDIA_LNK_FL_INTERFACE_LINK;
+	link->flags = flags;
 
 	/* Initialize graph object embedded at the new link */
 	media_gobj_create(source->graph_obj.mdev, MEDIA_GRAPH_LINK,
@@ -1138,6 +1186,9 @@
 	sink->num_links++;
 	source->num_links++;
 
+	link->source->num_links++;
+	link->sink->num_links++;
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(media_create_pad_link);
--- linux-qcom-6.8.0.orig/drivers/media/pci/cx23885/cx23885-video.c
+++ linux-qcom-6.8.0/drivers/media/pci/cx23885/cx23885-video.c
@@ -1354,6 +1354,10 @@
 	/* register Video device */
 	dev->video_dev = cx23885_vdev_init(dev, dev->pci,
 		&cx23885_video_template, "video");
+	if (!dev->video_dev) {
+		err = -ENOMEM;
+		goto fail_unreg;
+	}
 	dev->video_dev->queue = &dev->vb2_vidq;
 	dev->video_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
 				      V4L2_CAP_AUDIO | V4L2_CAP_VIDEO_CAPTURE;
@@ -1382,6 +1386,10 @@
 	/* register VBI device */
 	dev->vbi_dev = cx23885_vdev_init(dev, dev->pci,
 		&cx23885_vbi_template, "vbi");
+	if (!dev->vbi_dev) {
+		err = -ENOMEM;
+		goto fail_unreg;
+	}
 	dev->vbi_dev->queue = &dev->vb2_vbiq;
 	dev->vbi_dev->device_caps = V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
 				    V4L2_CAP_AUDIO | V4L2_CAP_VBI_CAPTURE;
--- linux-qcom-6.8.0.orig/drivers/media/pci/intel/ipu-bridge.c
+++ linux-qcom-6.8.0/drivers/media/pci/intel/ipu-bridge.c
@@ -14,6 +14,8 @@
 #include <media/ipu-bridge.h>
 #include <media/v4l2-fwnode.h>
 
+#define ADEV_DEV(adev) ACPI_PTR(&((adev)->dev))
+
 /*
  * 92335fcf-3203-4472-af93-7b4453ac29da
  *
@@ -58,8 +60,27 @@
 	IPU_SENSOR_CONFIG("INT3537", 1, 437000000),
 	/* Omnivision ov13b10 */
 	IPU_SENSOR_CONFIG("OVTIDB10", 1, 560000000),
+	IPU_SENSOR_CONFIG("OVTI13B1", 1, 560000000),
 	/* GalaxyCore GC0310 */
 	IPU_SENSOR_CONFIG("INT0310", 0),
+	/* Omnivision ov01a10 */
+	IPU_SENSOR_CONFIG("OVTI01A0", 1, 400000000),
+	/* Omnivision ov08x40 */
+	IPU_SENSOR_CONFIG("OVTI08F4", 1, 400000000),
+	/* Himax hm11b1 */
+	IPU_SENSOR_CONFIG("HIMX11B1", 1, 384000000),
+	/* Himax hm2170 */
+	IPU_SENSOR_CONFIG("HIMX2170", 1, 384000000),
+	/* Himax hm2172 */
+	IPU_SENSOR_CONFIG("HIMX2172", 1, 384000000),
+	/* Omnivision ov01a1s */
+	IPU_SENSOR_CONFIG("OVTI01AS", 1, 400000000),
+	/* Omnivision ov02c10 */
+	IPU_SENSOR_CONFIG("OVTI02C1", 1, 400000000),
+	/* Omnivision ov02e10 */
+	IPU_SENSOR_CONFIG("OVTI02E1", 1, 360000000),
+	/* Omnivision ov08a10 */
+	IPU_SENSOR_CONFIG("OVTI08A1", 1, 500000000),
 };
 
 static const struct ipu_property_names prop_names = {
@@ -84,6 +105,7 @@
 	"lc898212axb",
 };
 
+#if IS_ENABLED(CONFIG_ACPI)
 /*
  * Used to figure out IVSC acpi device by ipu_bridge_get_ivsc_acpi_dev()
  * instead of device and driver match to probe IVSC device.
@@ -97,13 +119,13 @@
 
 static struct acpi_device *ipu_bridge_get_ivsc_acpi_dev(struct acpi_device *adev)
 {
-	acpi_handle handle = acpi_device_handle(adev);
-	struct acpi_device *consumer, *ivsc_adev;
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(ivsc_acpi_ids); i++) {
 		const struct acpi_device_id *acpi_id = &ivsc_acpi_ids[i];
+		struct acpi_device *consumer, *ivsc_adev;
 
+		acpi_handle handle = acpi_device_handle(adev);
 		for_each_acpi_dev_match(ivsc_adev, acpi_id->id, NULL, -1)
 			/* camera sensor depends on IVSC in DSDT if exist */
 			for_each_acpi_consumer_dev(ivsc_adev, consumer)
@@ -115,6 +137,12 @@
 
 	return NULL;
 }
+#else
+static struct acpi_device *ipu_bridge_get_ivsc_acpi_dev(struct acpi_device *adev)
+{
+	return NULL;
+}
+#endif
 
 static int ipu_bridge_match_ivsc_dev(struct device *dev, const void *adev)
 {
@@ -160,7 +188,7 @@
 		csi_dev = ipu_bridge_get_ivsc_csi_dev(adev);
 		if (!csi_dev) {
 			acpi_dev_put(adev);
-			dev_err(&adev->dev, "Failed to find MEI CSI dev\n");
+			dev_err(ADEV_DEV(adev), "Failed to find MEI CSI dev\n");
 			return -ENODEV;
 		}
 
@@ -179,24 +207,25 @@
 	acpi_status status;
 	int ret = 0;
 
-	status = acpi_evaluate_object(adev->handle, id, NULL, &buffer);
+	status = acpi_evaluate_object(ACPI_PTR(adev->handle),
+				      id, NULL, &buffer);
 	if (ACPI_FAILURE(status))
 		return -ENODEV;
 
 	obj = buffer.pointer;
 	if (!obj) {
-		dev_err(&adev->dev, "Couldn't locate ACPI buffer\n");
+		dev_err(ADEV_DEV(adev), "Couldn't locate ACPI buffer\n");
 		return -ENODEV;
 	}
 
 	if (obj->type != ACPI_TYPE_BUFFER) {
-		dev_err(&adev->dev, "Not an ACPI buffer\n");
+		dev_err(ADEV_DEV(adev), "Not an ACPI buffer\n");
 		ret = -ENODEV;
 		goto out_free_buff;
 	}
 
 	if (obj->buffer.length > size) {
-		dev_err(&adev->dev, "Given buffer is too small\n");
+		dev_err(ADEV_DEV(adev), "Given buffer is too small\n");
 		ret = -EINVAL;
 		goto out_free_buff;
 	}
@@ -217,7 +246,7 @@
 	case IPU_SENSOR_ROTATION_INVERTED:
 		return 180;
 	default:
-		dev_warn(&adev->dev,
+		dev_warn(ADEV_DEV(adev),
 			 "Unknown rotation %d. Assume 0 degree rotation\n",
 			 ssdb->degree);
 		return 0;
@@ -227,12 +256,14 @@
 static enum v4l2_fwnode_orientation ipu_bridge_parse_orientation(struct acpi_device *adev)
 {
 	enum v4l2_fwnode_orientation orientation;
-	struct acpi_pld_info *pld;
-	acpi_status status;
+	struct acpi_pld_info *pld = NULL;
+	acpi_status status = AE_ERROR;
 
+#if IS_ENABLED(CONFIG_ACPI)
 	status = acpi_get_physical_device_location(adev->handle, &pld);
+#endif
 	if (ACPI_FAILURE(status)) {
-		dev_warn(&adev->dev, "_PLD call failed, using default orientation\n");
+		dev_warn(ADEV_DEV(adev), "_PLD call failed, using default orientation\n");
 		return V4L2_FWNODE_ORIENTATION_EXTERNAL;
 	}
 
@@ -250,7 +281,8 @@
 		orientation = V4L2_FWNODE_ORIENTATION_EXTERNAL;
 		break;
 	default:
-		dev_warn(&adev->dev, "Unknown _PLD panel val %d\n", pld->panel);
+		dev_warn(ADEV_DEV(adev), "Unknown _PLD panel val %d\n",
+			 pld->panel);
 		orientation = V4L2_FWNODE_ORIENTATION_EXTERNAL;
 		break;
 	}
@@ -269,12 +301,12 @@
 		return ret;
 
 	if (ssdb.vcmtype > ARRAY_SIZE(ipu_vcm_types)) {
-		dev_warn(&adev->dev, "Unknown VCM type %d\n", ssdb.vcmtype);
+		dev_warn(ADEV_DEV(adev), "Unknown VCM type %d\n", ssdb.vcmtype);
 		ssdb.vcmtype = 0;
 	}
 
 	if (ssdb.lanes > IPU_MAX_LANES) {
-		dev_err(&adev->dev, "Number of lanes in SSDB is invalid\n");
+		dev_err(ADEV_DEV(adev), "Number of lanes in SSDB is invalid\n");
 		return -EINVAL;
 	}
 
@@ -462,8 +494,14 @@
 						sensor->ipu_properties);
 
 	if (sensor->csi_dev) {
+		const char *device_hid = "";
+
+#if IS_ENABLED(CONFIG_ACPI)
+		device_hid = acpi_device_hid(sensor->ivsc_adev);
+#endif
+
 		snprintf(sensor->ivsc_name, sizeof(sensor->ivsc_name), "%s-%u",
-			 acpi_device_hid(sensor->ivsc_adev), sensor->link);
+			 device_hid, sensor->link);
 
 		nodes[SWNODE_IVSC_HID] = NODE_SENSOR(sensor->ivsc_name,
 						     sensor->ivsc_properties);
@@ -628,11 +666,15 @@
 {
 	struct fwnode_handle *fwnode, *primary;
 	struct ipu_sensor *sensor;
-	struct acpi_device *adev;
+	struct acpi_device *adev = NULL;
 	int ret;
 
+#if IS_ENABLED(CONFIG_ACPI)
 	for_each_acpi_dev_match(adev, cfg->hid, NULL, -1) {
-		if (!adev->status.enabled)
+#else
+	while (true) {
+#endif
+		if (!ACPI_PTR(adev->status.enabled))
 			continue;
 
 		if (bridge->n_sensors >= IPU_MAX_PORTS) {
@@ -668,7 +710,7 @@
 			goto err_free_swnodes;
 		}
 
-		sensor->adev = acpi_dev_get(adev);
+		sensor->adev = ACPI_PTR(acpi_dev_get(adev));
 
 		primary = acpi_fwnode_handle(adev);
 		primary->secondary = fwnode;
@@ -724,11 +766,16 @@
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_SIZE(ipu_supported_sensors); i++) {
+#if IS_ENABLED(CONFIG_ACPI)
 		const struct ipu_sensor_config *cfg =
 			&ipu_supported_sensors[i];
 
 		for_each_acpi_dev_match(sensor_adev, cfg->hid, NULL, -1) {
-			if (!sensor_adev->status.enabled)
+#else
+		while (true) {
+			sensor_adev = NULL;
+#endif
+			if (!ACPI_PTR(sensor_adev->status.enabled))
 				continue;
 
 			adev = ipu_bridge_get_ivsc_acpi_dev(sensor_adev);
--- linux-qcom-6.8.0.orig/drivers/media/pci/intel/ipu3/ipu3-cio2.c
+++ linux-qcom-6.8.0/drivers/media/pci/intel/ipu3/ipu3-cio2.c
@@ -1789,11 +1789,6 @@
 
 	v4l2_async_nf_init(&cio2->notifier, &cio2->v4l2_dev);
 
-	/* Register notifier for subdevices we care */
-	r = cio2_parse_firmware(cio2);
-	if (r)
-		goto fail_clean_notifier;
-
 	r = devm_request_irq(dev, pci_dev->irq, cio2_irq, IRQF_SHARED,
 			     CIO2_NAME, cio2);
 	if (r) {
@@ -1801,6 +1796,11 @@
 		goto fail_clean_notifier;
 	}
 
+	/* Register notifier for subdevices we care */
+	r = cio2_parse_firmware(cio2);
+	if (r)
+		goto fail_clean_notifier;
+
 	pm_runtime_put_noidle(dev);
 	pm_runtime_allow(dev);
 
--- linux-qcom-6.8.0.orig/drivers/media/pci/intel/ivsc/mei_csi.c
+++ linux-qcom-6.8.0/drivers/media/pci/intel/ivsc/mei_csi.c
@@ -71,8 +71,8 @@
 };
 
 enum csi_pads {
-	CSI_PAD_SOURCE,
 	CSI_PAD_SINK,
+	CSI_PAD_SOURCE,
 	CSI_NUM_PADS
 };
 
@@ -123,6 +123,8 @@
 	struct v4l2_ctrl_handler ctrl_handler;
 	struct v4l2_ctrl *freq_ctrl;
 	struct v4l2_ctrl *privacy_ctrl;
+	/* lock for v4l2 controls */
+	struct mutex ctrl_lock;
 	unsigned int remote_pad;
 	/* start streaming or not */
 	int streaming;
@@ -134,9 +136,6 @@
 	u32 nr_of_lanes;
 	/* frequency of the CSI-2 link */
 	u64 link_freq;
-
-	/* privacy status */
-	enum ivsc_privacy_status status;
 };
 
 static const struct v4l2_mbus_framefmt mei_csi_format_mbus_default = {
@@ -188,7 +187,11 @@
 
 	/* command response status */
 	ret = csi->cmd_response.status;
-	if (ret) {
+	if (ret == -1) {
+		/* notify privacy on instead of reporting error */
+		ret = 0;
+		v4l2_ctrl_s_ctrl(csi->privacy_ctrl, 1);
+	} else if (ret) {
 		ret = -EINVAL;
 		goto out;
 	}
@@ -263,10 +266,9 @@
 
 	switch (notif.cmd_id) {
 	case CSI_PRIVACY_NOTIF:
-		if (notif.cont.cont < CSI_PRIVACY_MAX) {
-			csi->status = notif.cont.cont;
-			v4l2_ctrl_s_ctrl(csi->privacy_ctrl, csi->status);
-		}
+		if (notif.cont.cont < CSI_PRIVACY_MAX)
+			v4l2_ctrl_s_ctrl(csi->privacy_ctrl,
+					 notif.cont.cont == CSI_PRIVACY_ON);
 		break;
 	case CSI_SET_OWNER:
 	case CSI_SET_CONF:
@@ -587,7 +589,7 @@
 	csi->remote_pad = pad;
 
 	return media_create_pad_link(&subdev->entity, pad,
-				     &csi->subdev.entity, 1,
+				     &csi->subdev.entity, CSI_PAD_SINK,
 				     MEDIA_LNK_FL_ENABLED |
 				     MEDIA_LNK_FL_IMMUTABLE);
 }
@@ -611,11 +613,13 @@
 	u32 max;
 	int ret;
 
+	mutex_init(&csi->ctrl_lock);
+
 	ret = v4l2_ctrl_handler_init(&csi->ctrl_handler, 2);
 	if (ret)
 		return ret;
 
-	csi->ctrl_handler.lock = &csi->lock;
+	csi->ctrl_handler.lock = &csi->ctrl_lock;
 
 	max = ARRAY_SIZE(link_freq_menu_items) - 1;
 	csi->freq_ctrl = v4l2_ctrl_new_int_menu(&csi->ctrl_handler,
@@ -794,6 +798,7 @@
 
 err_ctrl_handler:
 	v4l2_ctrl_handler_free(&csi->ctrl_handler);
+	mutex_destroy(&csi->ctrl_lock);
 	v4l2_async_nf_unregister(&csi->notifier);
 	v4l2_async_nf_cleanup(&csi->notifier);
 
@@ -813,6 +818,7 @@
 	v4l2_async_nf_unregister(&csi->notifier);
 	v4l2_async_nf_cleanup(&csi->notifier);
 	v4l2_ctrl_handler_free(&csi->ctrl_handler);
+	mutex_destroy(&csi->ctrl_lock);
 	v4l2_async_unregister_subdev(&csi->subdev);
 	v4l2_subdev_cleanup(&csi->subdev);
 	media_entity_cleanup(&csi->subdev.entity);
--- linux-qcom-6.8.0.orig/drivers/media/pci/ivtv/ivtv-udma.c
+++ linux-qcom-6.8.0/drivers/media/pci/ivtv/ivtv-udma.c
@@ -131,6 +131,8 @@
 
 	/* Fill SG List with new values */
 	if (ivtv_udma_fill_sg_list(dma, &user_dma, 0) < 0) {
+		IVTV_DEBUG_WARN("%s: could not allocate bounce buffers for highmem userspace buffers\n",
+				__func__);
 		unpin_user_pages(dma->map, dma->page_count);
 		dma->page_count = 0;
 		return -ENOMEM;
@@ -139,6 +141,12 @@
 	/* Map SG List */
 	dma->SG_length = dma_map_sg(&itv->pdev->dev, dma->SGlist,
 				    dma->page_count, DMA_TO_DEVICE);
+	if (!dma->SG_length) {
+		IVTV_DEBUG_WARN("%s: DMA map error, SG_length is 0\n", __func__);
+		unpin_user_pages(dma->map, dma->page_count);
+		dma->page_count = 0;
+		return -EINVAL;
+	}
 
 	/* Fill SG Array with new values */
 	ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1);
--- linux-qcom-6.8.0.orig/drivers/media/pci/ivtv/ivtv-yuv.c
+++ linux-qcom-6.8.0/drivers/media/pci/ivtv/ivtv-yuv.c
@@ -114,6 +114,12 @@
 	}
 	dma->SG_length = dma_map_sg(&itv->pdev->dev, dma->SGlist,
 				    dma->page_count, DMA_TO_DEVICE);
+	if (!dma->SG_length) {
+		IVTV_DEBUG_WARN("%s: DMA map error, SG_length is 0\n", __func__);
+		unpin_user_pages(dma->map, dma->page_count);
+		dma->page_count = 0;
+		return -EINVAL;
+	}
 
 	/* Fill SG Array with new values */
 	ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
--- linux-qcom-6.8.0.orig/drivers/media/pci/ivtv/ivtvfb.c
+++ linux-qcom-6.8.0/drivers/media/pci/ivtv/ivtvfb.c
@@ -281,10 +281,10 @@
 	/* Map User DMA */
 	if (ivtv_udma_setup(itv, ivtv_dest_addr, userbuf, size_in_bytes) <= 0) {
 		mutex_unlock(&itv->udma.lock);
-		IVTVFB_WARN("ivtvfb_prep_dec_dma_to_device, Error with pin_user_pages: %d bytes, %d pages returned\n",
-			       size_in_bytes, itv->udma.page_count);
+		IVTVFB_WARN("%s, Error in ivtv_udma_setup: %d bytes, %d pages returned\n",
+			       __func__, size_in_bytes, itv->udma.page_count);
 
-		/* pin_user_pages must have failed completely */
+		/* pin_user_pages or DMA must have failed completely */
 		return -EIO;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/media/pci/mgb4/mgb4_cmt.c
+++ linux-qcom-6.8.0/drivers/media/pci/mgb4/mgb4_cmt.c
@@ -12,6 +12,7 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/nospec.h>
 #include "mgb4_core.h"
 #include "mgb4_cmt.h"
 
@@ -227,6 +228,8 @@
 	u32 config;
 	size_t i;
 
+	freq_range = array_index_nospec(freq_range, ARRAY_SIZE(cmt_vals_in));
+
 	addr = cmt_addrs_in[vindev->config->id];
 	reg_set = cmt_vals_in[freq_range];
 
--- linux-qcom-6.8.0.orig/drivers/media/pci/mgb4/mgb4_core.c
+++ linux-qcom-6.8.0/drivers/media/pci/mgb4/mgb4_core.c
@@ -642,9 +642,6 @@
 	struct mgb4_dev *mgbdev = pci_get_drvdata(pdev);
 	int i;
 
-#ifdef CONFIG_DEBUG_FS
-	debugfs_remove_recursive(mgbdev->debugfs);
-#endif
 #if IS_REACHABLE(CONFIG_HWMON)
 	hwmon_device_unregister(mgbdev->hwmon_dev);
 #endif
@@ -659,6 +656,10 @@
 		if (mgbdev->vin[i])
 			mgb4_vin_free(mgbdev->vin[i]);
 
+#ifdef CONFIG_DEBUG_FS
+	debugfs_remove_recursive(mgbdev->debugfs);
+#endif
+
 	device_remove_groups(&mgbdev->pdev->dev, mgb4_pci_groups);
 	free_spi(mgbdev);
 	free_i2c(mgbdev);
--- linux-qcom-6.8.0.orig/drivers/media/pci/ngene/ngene-core.c
+++ linux-qcom-6.8.0/drivers/media/pci/ngene/ngene-core.c
@@ -1488,7 +1488,9 @@
 	}
 
 	if (dev->ci.en && (io & NGENE_IO_TSOUT)) {
-		dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1);
+		ret = dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1);
+		if (ret != 0)
+			goto err;
 		set_transfer(chan, 1);
 		chan->dev->channel[2].DataFormatFlags = DF_SWAP32;
 		set_transfer(&chan->dev->channel[2], 1);
--- linux-qcom-6.8.0.orig/drivers/media/pci/saa7134/saa7134-dvb.c
+++ linux-qcom-6.8.0/drivers/media/pci/saa7134/saa7134-dvb.c
@@ -466,7 +466,9 @@
 	/* switch the board to analog mode */
 	if (fe->ops.i2c_gate_ctrl)
 		fe->ops.i2c_gate_ctrl(fe, 1);
-	i2c_transfer(&dev->i2c_adap, &analog_msg, 1);
+	if (i2c_transfer(&dev->i2c_adap, &analog_msg, 1) != 1)
+		return -EIO;
+
 	return 0;
 }
 
@@ -1018,7 +1020,9 @@
 	else
 		wbuf[1] = rbuf & 0xef;
 	msg[0].len = 2;
-	i2c_transfer(&dev->i2c_adap, msg, 1);
+	if (i2c_transfer(&dev->i2c_adap, msg, 1) != 1)
+		return -EIO;
+
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/media/pci/sta2x11/sta2x11_vip.c
+++ linux-qcom-6.8.0/drivers/media/pci/sta2x11/sta2x11_vip.c
@@ -757,7 +757,7 @@
 /**
  * vip_irq - interrupt routine
  * @irq: Number of interrupt ( not used, correct number is assumed )
- * @vip: local data structure containing all information
+ * @data: local data structure containing all information
  *
  * check for both frame interrupts set ( top and bottom ).
  * check FIFO overflow, but limit number of log messages after open.
@@ -767,8 +767,9 @@
  *
  * IRQ_HANDLED, interrupt done.
  */
-static irqreturn_t vip_irq(int irq, struct sta2x11_vip *vip)
+static irqreturn_t vip_irq(int irq, void *data)
 {
+	struct sta2x11_vip *vip = data;
 	unsigned int status;
 
 	status = reg_read(vip, DVP_ITS);
@@ -1053,9 +1054,7 @@
 
 	spin_lock_init(&vip->slock);
 
-	ret = request_irq(pdev->irq,
-			  (irq_handler_t) vip_irq,
-			  IRQF_SHARED, KBUILD_MODNAME, vip);
+	ret = request_irq(pdev->irq, vip_irq, IRQF_SHARED, KBUILD_MODNAME, vip);
 	if (ret) {
 		dev_err(&pdev->dev, "request_irq failed\n");
 		ret = -ENODEV;
--- linux-qcom-6.8.0.orig/drivers/media/pci/ttpci/budget-av.c
+++ linux-qcom-6.8.0/drivers/media/pci/ttpci/budget-av.c
@@ -1463,7 +1463,8 @@
 		budget_av->has_saa7113 = 1;
 		err = saa7146_vv_init(dev, &vv_data);
 		if (err != 0) {
-			/* fixme: proper cleanup here */
+			ttpci_budget_deinit(&budget_av->budget);
+			kfree(budget_av);
 			ERR("cannot init vv subsystem\n");
 			return err;
 		}
@@ -1472,9 +1473,10 @@
 		vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
 
 		if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_VIDEO))) {
-			/* fixme: proper cleanup here */
-			ERR("cannot register capture v4l2 device\n");
 			saa7146_vv_release(dev);
+			ttpci_budget_deinit(&budget_av->budget);
+			kfree(budget_av);
+			ERR("cannot register capture v4l2 device\n");
 			return err;
 		}
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/allegro-dvt/allegro-core.c
+++ linux-qcom-6.8.0/drivers/media/platform/allegro-dvt/allegro-core.c
@@ -1509,8 +1509,10 @@
 		INIT_LIST_HEAD(&buffer->head);
 
 		err = allegro_alloc_buffer(dev, buffer, size);
-		if (err)
+		if (err) {
+			kfree(buffer);
 			goto err;
+		}
 		list_add(&buffer->head, list);
 	}
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/amphion/vdec.c
+++ linux-qcom-6.8.0/drivers/media/platform/amphion/vdec.c
@@ -195,7 +195,6 @@
 	struct vdec_t *vdec = inst->priv;
 	int ret = 0;
 
-	vpu_inst_lock(inst);
 	switch (ctrl->id) {
 	case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE:
 		vdec->params.display_delay_enable = ctrl->val;
@@ -207,7 +206,6 @@
 		ret = -EINVAL;
 		break;
 	}
-	vpu_inst_unlock(inst);
 
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/media/platform/amphion/venc.c
+++ linux-qcom-6.8.0/drivers/media/platform/amphion/venc.c
@@ -518,7 +518,6 @@
 	struct venc_t *venc = inst->priv;
 	int ret = 0;
 
-	vpu_inst_lock(inst);
 	switch (ctrl->id) {
 	case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
 		venc->params.profile = ctrl->val;
@@ -579,7 +578,6 @@
 		ret = -EINVAL;
 		break;
 	}
-	vpu_inst_unlock(inst);
 
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/media/platform/amphion/vpu_drv.c
+++ linux-qcom-6.8.0/drivers/media/platform/amphion/vpu_drv.c
@@ -151,8 +151,8 @@
 	media_device_cleanup(&vpu->mdev);
 	v4l2_device_unregister(&vpu->v4l2_dev);
 err_vpu_deinit:
-	pm_runtime_set_suspended(dev);
 	pm_runtime_disable(dev);
+	pm_runtime_set_suspended(dev);
 
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/media/platform/amphion/vpu_v4l2.c
+++ linux-qcom-6.8.0/drivers/media/platform/amphion/vpu_v4l2.c
@@ -825,6 +825,7 @@
 		vfd->fops = vdec_get_fops();
 		vfd->ioctl_ops = vdec_get_ioctl_ops();
 	}
+	video_set_drvdata(vfd, vpu);
 
 	ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
 	if (ret) {
@@ -832,7 +833,6 @@
 		v4l2_m2m_release(func->m2m_dev);
 		return ret;
 	}
-	video_set_drvdata(vfd, vpu);
 	func->vfd = vfd;
 
 	ret = v4l2_m2m_register_media_controller(func->m2m_dev, func->vfd, func->function);
--- linux-qcom-6.8.0.orig/drivers/media/platform/cadence/cdns-csi2rx.c
+++ linux-qcom-6.8.0/drivers/media/platform/cadence/cdns-csi2rx.c
@@ -235,10 +235,6 @@
 
 	writel(reg, csi2rx->base + CSI2RX_STATIC_CFG_REG);
 
-	ret = v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, true);
-	if (ret)
-		goto err_disable_pclk;
-
 	/* Enable DPHY clk and data lanes. */
 	if (csi2rx->dphy) {
 		reg = CSI2RX_DPHY_CL_EN | CSI2RX_DPHY_CL_RST;
@@ -248,6 +244,13 @@
 		}
 
 		writel(reg, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
+
+		ret = csi2rx_configure_ext_dphy(csi2rx);
+		if (ret) {
+			dev_err(csi2rx->dev,
+				"Failed to configure external DPHY: %d\n", ret);
+			goto err_disable_pclk;
+		}
 	}
 
 	/*
@@ -287,14 +290,9 @@
 
 	reset_control_deassert(csi2rx->sys_rst);
 
-	if (csi2rx->dphy) {
-		ret = csi2rx_configure_ext_dphy(csi2rx);
-		if (ret) {
-			dev_err(csi2rx->dev,
-				"Failed to configure external DPHY: %d\n", ret);
-			goto err_disable_sysclk;
-		}
-	}
+	ret = v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, true);
+	if (ret)
+		goto err_disable_sysclk;
 
 	clk_disable_unprepare(csi2rx->p_clk);
 
@@ -308,6 +306,10 @@
 		clk_disable_unprepare(csi2rx->pixel_clk[i - 1]);
 	}
 
+	if (csi2rx->dphy) {
+		writel(0, csi2rx->base + CSI2RX_DPHY_LANE_CTRL_REG);
+		phy_power_off(csi2rx->dphy);
+	}
 err_disable_pclk:
 	clk_disable_unprepare(csi2rx->p_clk);
 
@@ -468,7 +470,7 @@
 	struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev);
 
 	csi2rx->source_pad = media_entity_get_fwnode_pad(&s_subdev->entity,
-							 s_subdev->fwnode,
+							 asd->match.fwnode,
 							 MEDIA_PAD_FL_SOURCE);
 	if (csi2rx->source_pad < 0) {
 		dev_err(csi2rx->dev, "Couldn't find output pad for subdev %s\n",
--- linux-qcom-6.8.0.orig/drivers/media/platform/marvell/mcam-core.c
+++ linux-qcom-6.8.0/drivers/media/platform/marvell/mcam-core.c
@@ -935,7 +935,12 @@
 	ret = pm_runtime_resume_and_get(cam->dev);
 	if (ret < 0)
 		return ret;
-	clk_enable(cam->clk[0]);
+	ret = clk_enable(cam->clk[0]);
+	if (ret) {
+		pm_runtime_put(cam->dev);
+		return ret;
+	}
+
 	mcam_reg_write(cam, REG_CLKCTRL, (mclk_src << 29) | mclk_div);
 	mcam_ctlr_power_up(cam);
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/marvell/mmp-driver.c
+++ linux-qcom-6.8.0/drivers/media/platform/marvell/mmp-driver.c
@@ -231,12 +231,22 @@
 	mcam_init_clk(mcam);
 
 	/*
+	 * Register with V4L.
+	 */
+
+	ret = v4l2_device_register(mcam->dev, &mcam->v4l2_dev);
+	if (ret)
+		return ret;
+
+	/*
 	 * Create a match of the sensor against its OF node.
 	 */
 	ep = fwnode_graph_get_next_endpoint(of_fwnode_handle(pdev->dev.of_node),
 					    NULL);
-	if (!ep)
-		return -ENODEV;
+	if (!ep) {
+		ret = -ENODEV;
+		goto out_v4l2_device_unregister;
+	}
 
 	v4l2_async_nf_init(&mcam->notifier, &mcam->v4l2_dev);
 
@@ -245,7 +255,7 @@
 	fwnode_handle_put(ep);
 	if (IS_ERR(asd)) {
 		ret = PTR_ERR(asd);
-		goto out;
+		goto out_v4l2_device_unregister;
 	}
 
 	/*
@@ -253,7 +263,7 @@
 	 */
 	ret = mccic_register(mcam);
 	if (ret)
-		goto out;
+		goto out_v4l2_device_unregister;
 
 	/*
 	 * Add OF clock provider.
@@ -282,6 +292,8 @@
 	return 0;
 out:
 	mccic_shutdown(mcam);
+out_v4l2_device_unregister:
+	v4l2_device_unregister(&mcam->v4l2_dev);
 
 	return ret;
 }
@@ -292,6 +304,7 @@
 	struct mcam_camera *mcam = &cam->mcam;
 
 	mccic_shutdown(mcam);
+	v4l2_device_unregister(&mcam->v4l2_dev);
 	pm_runtime_force_suspend(mcam->dev);
 }
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1293,6 +1293,11 @@
 	return 0;
 }
 
+static void mtk_jpeg_destroy_workqueue(void *data)
+{
+	destroy_workqueue(data);
+}
+
 static int mtk_jpeg_probe(struct platform_device *pdev)
 {
 	struct mtk_jpeg_dev *jpeg;
@@ -1337,6 +1342,11 @@
 							  | WQ_FREEZABLE);
 		if (!jpeg->workqueue)
 			return -EINVAL;
+		ret = devm_add_action_or_reset(&pdev->dev,
+					       mtk_jpeg_destroy_workqueue,
+					       jpeg->workqueue);
+		if (ret)
+			return ret;
 	}
 
 	ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c
@@ -578,11 +578,6 @@
 	return 0;
 }
 
-static void mtk_jpegdec_destroy_workqueue(void *data)
-{
-	destroy_workqueue(data);
-}
-
 static int mtk_jpegdec_hw_probe(struct platform_device *pdev)
 {
 	struct mtk_jpegdec_clk *jpegdec_clk;
@@ -606,12 +601,6 @@
 	dev->plat_dev = pdev;
 	dev->dev = &pdev->dev;
 
-	ret = devm_add_action_or_reset(&pdev->dev,
-				       mtk_jpegdec_destroy_workqueue,
-				       master_dev->workqueue);
-	if (ret)
-		return ret;
-
 	spin_lock_init(&dev->hw_lock);
 	dev->hw_state = MTK_JPEG_HW_IDLE;
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/mdp/mtk_mdp_vpu.c
@@ -26,7 +26,7 @@
 	vpu->inst_addr = msg->vpu_inst_addr;
 }
 
-static void mtk_mdp_vpu_ipi_handler(const void *data, unsigned int len,
+static void mtk_mdp_vpu_ipi_handler(void *data, unsigned int len,
 				    void *priv)
 {
 	const struct mdp_ipi_comm_ack *msg = data;
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_scp.c
@@ -79,6 +79,8 @@
 	}
 
 	fw = devm_kzalloc(&plat_dev->dev, sizeof(*fw), GFP_KERNEL);
+	if (!fw)
+		return ERR_PTR(-ENOMEM);
 	fw->type = SCP;
 	fw->ops = &mtk_vcodec_rproc_msg;
 	fw->scp = scp;
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_fw_vpu.c
@@ -29,15 +29,7 @@
 					   mtk_vcodec_ipi_handler handler,
 					   const char *name, void *priv)
 {
-	/*
-	 * The handler we receive takes a void * as its first argument. We
-	 * cannot change this because it needs to be passed down to the rproc
-	 * subsystem when SCP is used. VPU takes a const argument, which is
-	 * more constrained, so the conversion below is safe.
-	 */
-	ipi_handler_t handler_const = (ipi_handler_t)handler;
-
-	return vpu_ipi_register(fw->pdev, id, handler_const, name, priv);
+	return vpu_ipi_register(fw->pdev, id, handler, name, priv);
 }
 
 static int mtk_vcodec_vpu_ipi_send(struct mtk_vcodec_fw *fw, int id, void *buf,
@@ -58,12 +50,12 @@
 
 	dev_err(&dev->plat_dev->dev, "Watchdog timeout!!");
 
-	mutex_lock(&dev->dev_mutex);
+	mutex_lock(&dev->dev_ctx_lock);
 	list_for_each_entry(ctx, &dev->ctx_list, list) {
 		ctx->state = MTK_STATE_ABORT;
 		mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id);
 	}
-	mutex_unlock(&dev->dev_mutex);
+	mutex_unlock(&dev->dev_ctx_lock);
 }
 
 static void mtk_vcodec_vpu_reset_enc_handler(void *priv)
@@ -73,12 +65,12 @@
 
 	dev_err(&dev->plat_dev->dev, "Watchdog timeout!!");
 
-	mutex_lock(&dev->dev_mutex);
+	mutex_lock(&dev->dev_ctx_lock);
 	list_for_each_entry(ctx, &dev->ctx_list, list) {
 		ctx->state = MTK_STATE_ABORT;
 		mtk_v4l2_vdec_dbg(0, ctx, "[%d] Change to state MTK_STATE_ABORT", ctx->id);
 	}
-	mutex_unlock(&dev->dev_mutex);
+	mutex_unlock(&dev->dev_ctx_lock);
 }
 
 static const struct mtk_vcodec_fw_ops mtk_vcodec_vpu_msg = {
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c
@@ -268,7 +268,9 @@
 
 	ctx->dev->vdec_pdata->init_vdec_params(ctx);
 
+	mutex_lock(&dev->dev_ctx_lock);
 	list_add(&ctx->list, &dev->ctx_list);
+	mutex_unlock(&dev->dev_ctx_lock);
 	mtk_vcodec_dbgfs_create(ctx);
 
 	mutex_unlock(&dev->dev_mutex);
@@ -311,7 +313,9 @@
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 
 	mtk_vcodec_dbgfs_remove(dev, ctx->id);
+	mutex_lock(&dev->dev_ctx_lock);
 	list_del_init(&ctx->list);
+	mutex_unlock(&dev->dev_ctx_lock);
 	kfree(ctx);
 	mutex_unlock(&dev->dev_mutex);
 	return 0;
@@ -404,6 +408,7 @@
 	for (i = 0; i < MTK_VDEC_HW_MAX; i++)
 		mutex_init(&dev->dec_mutex[i]);
 	mutex_init(&dev->dev_mutex);
+	mutex_init(&dev->dev_ctx_lock);
 	spin_lock_init(&dev->irqlock);
 
 	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.h
@@ -241,6 +241,7 @@
  *
  * @dec_mutex: decoder hardware lock
  * @dev_mutex: video_device lock
+ * @dev_ctx_lock: the lock of context list
  * @decode_workqueue: decode work queue
  *
  * @irqlock: protect data access by irq handler and work thread
@@ -282,6 +283,7 @@
 	/* decoder hardware mutex lock */
 	struct mutex dec_mutex[MTK_VDEC_HW_MAX];
 	struct mutex dev_mutex;
+	struct mutex dev_ctx_lock;
 	struct workqueue_struct *decode_workqueue;
 
 	spinlock_t irqlock;
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
@@ -1023,18 +1023,26 @@
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(instance->mv); i++)
-		mtk_vcodec_mem_free(ctx, &instance->mv[i]);
+		if (instance->mv[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->mv[i]);
 
 	for (i = 0; i < ARRAY_SIZE(instance->seg); i++)
-		mtk_vcodec_mem_free(ctx, &instance->seg[i]);
+		if (instance->seg[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->seg[i]);
 
 	for (i = 0; i < ARRAY_SIZE(instance->cdf); i++)
-		mtk_vcodec_mem_free(ctx, &instance->cdf[i]);
+		if (instance->cdf[i].va)
+			mtk_vcodec_mem_free(ctx, &instance->cdf[i]);
 
-	mtk_vcodec_mem_free(ctx, &instance->tile);
-	mtk_vcodec_mem_free(ctx, &instance->cdf_temp);
-	mtk_vcodec_mem_free(ctx, &instance->cdf_table);
-	mtk_vcodec_mem_free(ctx, &instance->iq_table);
+
+	if (instance->tile.va)
+		mtk_vcodec_mem_free(ctx, &instance->tile);
+	if (instance->cdf_temp.va)
+		mtk_vcodec_mem_free(ctx, &instance->cdf_temp);
+	if (instance->cdf_table.va)
+		mtk_vcodec_mem_free(ctx, &instance->cdf_table);
+	if (instance->iq_table.va)
+		mtk_vcodec_mem_free(ctx, &instance->iq_table);
 
 	instance->level = AV1_RES_NONE;
 }
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c
@@ -347,11 +347,16 @@
 		return vpu_dec_reset(vpu);
 
 	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
+	if (!fb) {
+		mtk_vdec_err(inst->ctx, "fb buffer is NULL");
+		return -ENOMEM;
+	}
+
 	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
 	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
 
-	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
-	c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
+	y_fb_dma = fb->base_y.dma_addr;
+	c_fb_dma = fb->base_c.dma_addr;
 
 	mtk_vdec_debug(inst->ctx, "+ [%d] FB y_dma=%llx c_dma=%llx va=%p",
 		       inst->num_nalu, y_fb_dma, c_fb_dma, fb);
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c
@@ -724,11 +724,16 @@
 		return vpu_dec_reset(vpu);
 
 	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
+	if (!fb) {
+		mtk_vdec_err(inst->ctx, "fb buffer is NULL");
+		return -ENOMEM;
+	}
+
 	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
 	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
 
-	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
-	c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
+	y_fb_dma = fb->base_y.dma_addr;
+	c_fb_dma = fb->base_c.dma_addr;
 	mtk_vdec_debug(inst->ctx, "[h264-dec] [%d] y_dma=%llx c_dma=%llx",
 		       inst->ctx->decoded_frame_cnt, y_fb_dma, c_fb_dma);
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c
@@ -869,7 +869,6 @@
 	inst->vpu.codec_type = ctx->current_codec;
 	inst->vpu.capture_type = ctx->capture_fourcc;
 
-	ctx->drv_handle = inst;
 	err = vpu_dec_init(&inst->vpu);
 	if (err) {
 		mtk_vdec_err(ctx, "vdec_hevc init err=%d", err);
@@ -898,6 +897,7 @@
 	mtk_vdec_debug(ctx, "lat hevc instance >> %p, codec_type = 0x%x",
 		       inst, inst->vpu.codec_type);
 
+	ctx->drv_handle = inst;
 	return 0;
 error_free_inst:
 	kfree(inst);
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c
@@ -335,14 +335,18 @@
 	src_buf_info = container_of(bs, struct mtk_video_dec_buf, bs_buffer);
 
 	fb = inst->ctx->dev->vdec_pdata->get_cap_buffer(inst->ctx);
-	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
+	if (!fb) {
+		mtk_vdec_err(inst->ctx, "fb buffer is NULL");
+		return -ENOMEM;
+	}
 
-	y_fb_dma = fb ? (u64)fb->base_y.dma_addr : 0;
+	dst_buf_info = container_of(fb, struct mtk_video_dec_buf, frame_buffer);
+	y_fb_dma = fb->base_y.dma_addr;
 	if (inst->ctx->q_data[MTK_Q_DATA_DST].fmt->num_planes == 1)
 		c_fb_dma = y_fb_dma +
 			inst->ctx->picinfo.buf_w * inst->ctx->picinfo.buf_h;
 	else
-		c_fb_dma = fb ? (u64)fb->base_c.dma_addr : 0;
+		c_fb_dma = fb->base_c.dma_addr;
 
 	inst->vsi->dec.bs_dma = (u64)bs->dma_addr;
 	inst->vsi->dec.bs_sz = bs->size;
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/decoder/vdec_vpu_if.c
@@ -77,12 +77,14 @@
 	struct mtk_vcodec_dec_ctx *ctx;
 	int ret = false;
 
+	mutex_lock(&dec_dev->dev_ctx_lock);
 	list_for_each_entry(ctx, &dec_dev->ctx_list, list) {
 		if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) {
 			ret = true;
 			break;
 		}
 	}
+	mutex_unlock(&dec_dev->dev_ctx_lock);
 
 	return ret;
 }
@@ -231,6 +233,12 @@
 	mtk_vdec_debug(vpu->ctx, "vdec_inst=%p", vpu);
 
 	err = vcodec_vpu_send_msg(vpu, (void *)&msg, sizeof(msg));
+
+	if (IS_ERR_OR_NULL(vpu->vsi)) {
+		mtk_vdec_err(vpu->ctx, "invalid vdec vsi, status=%d", err);
+		return -EINVAL;
+	}
+
 	mtk_vdec_debug(vpu->ctx, "- ret=%d", err);
 	return err;
 }
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c
@@ -177,7 +177,9 @@
 	mtk_v4l2_venc_dbg(2, ctx, "Create instance [%d]@%p m2m_ctx=%p ",
 			  ctx->id, ctx, ctx->m2m_ctx);
 
+	mutex_lock(&dev->dev_ctx_lock);
 	list_add(&ctx->list, &dev->ctx_list);
+	mutex_unlock(&dev->dev_ctx_lock);
 
 	mutex_unlock(&dev->dev_mutex);
 	mtk_v4l2_venc_dbg(0, ctx, "%s encoder [%d]", dev_name(&dev->plat_dev->dev),
@@ -212,7 +214,9 @@
 	v4l2_fh_exit(&ctx->fh);
 	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
 
+	mutex_lock(&dev->dev_ctx_lock);
 	list_del_init(&ctx->list);
+	mutex_unlock(&dev->dev_ctx_lock);
 	kfree(ctx);
 	mutex_unlock(&dev->dev_mutex);
 	return 0;
@@ -294,6 +298,7 @@
 
 	mutex_init(&dev->enc_mutex);
 	mutex_init(&dev->dev_mutex);
+	mutex_init(&dev->dev_ctx_lock);
 	spin_lock_init(&dev->irqlock);
 
 	snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s",
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.h
@@ -178,6 +178,7 @@
  *
  * @enc_mutex: encoder hardware lock.
  * @dev_mutex: video_device lock
+ * @dev_ctx_lock: the lock of context list
  * @encode_workqueue: encode work queue
  *
  * @enc_irq: h264 encoder irq resource
@@ -205,6 +206,7 @@
 	/* encoder hardware mutex lock */
 	struct mutex enc_mutex;
 	struct mutex dev_mutex;
+	struct mutex dev_ctx_lock;
 	struct workqueue_struct *encode_workqueue;
 
 	int enc_irq;
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.c
@@ -58,13 +58,15 @@
 	return 0;
 }
 
-void mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm)
+int mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm)
 {
 	int ret;
 
 	ret = pm_runtime_resume_and_get(pm->dev);
 	if (ret)
 		dev_err(pm->dev, "pm_runtime_resume_and_get fail: %d", ret);
+
+	return ret;
 }
 
 void mtk_vcodec_enc_pw_off(struct mtk_vcodec_pm *pm)
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_pm.h
@@ -10,7 +10,7 @@
 #include "mtk_vcodec_enc_drv.h"
 
 int mtk_vcodec_init_enc_clk(struct mtk_vcodec_enc_dev *dev);
-void mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm);
+int mtk_vcodec_enc_pw_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_pw_off(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_on(struct mtk_vcodec_pm *pm);
 void mtk_vcodec_enc_clock_off(struct mtk_vcodec_pm *pm);
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c
@@ -301,11 +301,12 @@
 	 * other buffers need to be freed by AP.
 	 */
 	for (i = 0; i < VENC_H264_VPU_WORK_BUF_MAX; i++) {
-		if (i != VENC_H264_VPU_WORK_BUF_SKIP_FRAME)
+		if (i != VENC_H264_VPU_WORK_BUF_SKIP_FRAME && inst->work_bufs[i].va)
 			mtk_vcodec_mem_free(inst->ctx, &inst->work_bufs[i]);
 	}
 
-	mtk_vcodec_mem_free(inst->ctx, &inst->pps_buf);
+	if (inst->pps_buf.va)
+		mtk_vcodec_mem_free(inst->ctx, &inst->pps_buf);
 }
 
 static int h264_enc_alloc_work_buf(struct venc_h264_inst *inst, bool is_34bit)
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/encoder/venc_drv_if.c
@@ -64,7 +64,9 @@
 	ctx->dev->curr_ctx = ctx;
 	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
 
-	mtk_vcodec_enc_pw_on(&ctx->dev->pm);
+	ret = mtk_vcodec_enc_pw_on(&ctx->dev->pm);
+	if (ret)
+		goto venc_if_encode_pw_on_err;
 	mtk_vcodec_enc_clock_on(&ctx->dev->pm);
 	ret = ctx->enc_if->encode(ctx->drv_handle, opt, frm_buf,
 				  bs_buf, result);
@@ -75,6 +77,7 @@
 	ctx->dev->curr_ctx = NULL;
 	spin_unlock_irqrestore(&ctx->dev->irqlock, flags);
 
+venc_if_encode_pw_on_err:
 	mtk_venc_unlock(ctx);
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vcodec/encoder/venc_vpu_if.c
@@ -47,12 +47,14 @@
 	struct mtk_vcodec_enc_ctx *ctx;
 	int ret = false;
 
+	mutex_lock(&enc_dev->dev_ctx_lock);
 	list_for_each_entry(ctx, &enc_dev->ctx_list, list) {
 		if (!IS_ERR_OR_NULL(ctx) && ctx->vpu_inst == vpu) {
 			ret = true;
 			break;
 		}
 	}
+	mutex_unlock(&enc_dev->dev_ctx_lock);
 
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vpu/mtk_vpu.c
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vpu/mtk_vpu.c
@@ -635,7 +635,7 @@
 }
 EXPORT_SYMBOL_GPL(vpu_load_firmware);
 
-static void vpu_init_ipi_handler(const void *data, unsigned int len, void *priv)
+static void vpu_init_ipi_handler(void *data, unsigned int len, void *priv)
 {
 	struct mtk_vpu *vpu = priv;
 	const struct vpu_run *run = data;
--- linux-qcom-6.8.0.orig/drivers/media/platform/mediatek/vpu/mtk_vpu.h
+++ linux-qcom-6.8.0/drivers/media/platform/mediatek/vpu/mtk_vpu.h
@@ -17,7 +17,7 @@
  * VPU interfaces with other blocks by share memory and interrupt.
  */
 
-typedef void (*ipi_handler_t) (const void *data,
+typedef void (*ipi_handler_t) (void *data,
 			       unsigned int len,
 			       void *priv);
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/nuvoton/npcm-video.c
+++ linux-qcom-6.8.0/drivers/media/platform/nuvoton/npcm-video.c
@@ -1667,9 +1667,9 @@
 		dev_info(dev, "Support HEXTILE pixel format\n");
 
 		ece_pdev = of_find_device_by_node(ece_node);
-		if (IS_ERR(ece_pdev)) {
+		if (!ece_pdev) {
 			dev_err(dev, "Failed to find ECE device\n");
-			return PTR_ERR(ece_pdev);
+			return -ENODEV;
 		}
 		of_node_put(ece_node);
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
+++ linux-qcom-6.8.0/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c
@@ -1632,6 +1632,9 @@
 	dev_dbg(ctx->mxc_jpeg->dev, "Start streaming ctx=%p", ctx);
 	q_data->sequence = 0;
 
+	if (V4L2_TYPE_IS_CAPTURE(q->type))
+		ctx->need_initial_source_change_evt = false;
+
 	ret = pm_runtime_resume_and_get(ctx->mxc_jpeg->dev);
 	if (ret < 0) {
 		dev_err(ctx->mxc_jpeg->dev, "Failed to power up jpeg\n");
@@ -2671,9 +2674,12 @@
 	int i;
 
 	for (i = 0; i < jpeg->num_domains; i++) {
-		if (jpeg->pd_link[i] && !IS_ERR(jpeg->pd_link[i]))
+		if (!IS_ERR_OR_NULL(jpeg->pd_dev[i]) &&
+		    !pm_runtime_suspended(jpeg->pd_dev[i]))
+			pm_runtime_force_suspend(jpeg->pd_dev[i]);
+		if (!IS_ERR_OR_NULL(jpeg->pd_link[i]))
 			device_link_del(jpeg->pd_link[i]);
-		if (jpeg->pd_dev[i] && !IS_ERR(jpeg->pd_dev[i]))
+		if (!IS_ERR_OR_NULL(jpeg->pd_dev[i]))
 			dev_pm_domain_detach(jpeg->pd_dev[i], true);
 		jpeg->pd_dev[i] = NULL;
 		jpeg->pd_link[i] = NULL;
@@ -2834,6 +2840,7 @@
 	jpeg->dec_vdev->vfl_dir = VFL_DIR_M2M;
 	jpeg->dec_vdev->device_caps = V4L2_CAP_STREAMING |
 					V4L2_CAP_VIDEO_M2M_MPLANE;
+	video_set_drvdata(jpeg->dec_vdev, jpeg);
 	if (mode == MXC_JPEG_ENCODE) {
 		v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_DECODER_CMD);
 		v4l2_disable_ioctl(jpeg->dec_vdev, VIDIOC_TRY_DECODER_CMD);
@@ -2846,7 +2853,6 @@
 		dev_err(dev, "failed to register video device\n");
 		goto err_vdev_register;
 	}
-	video_set_drvdata(jpeg->dec_vdev, jpeg);
 	if (mode == MXC_JPEG_ENCODE)
 		v4l2_info(&jpeg->v4l2_dev,
 			  "encoder device registered as /dev/video%d (%d,%d)\n",
--- linux-qcom-6.8.0.orig/drivers/media/platform/nxp/imx-pxp.c
+++ linux-qcom-6.8.0/drivers/media/platform/nxp/imx-pxp.c
@@ -1805,6 +1805,9 @@
 		return PTR_ERR(mmio);
 	dev->regmap = devm_regmap_init_mmio(&pdev->dev, mmio,
 					    &pxp_regmap_config);
+	if (IS_ERR(dev->regmap))
+		return dev_err_probe(&pdev->dev, PTR_ERR(dev->regmap),
+				     "Failed to init regmap\n");
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
--- linux-qcom-6.8.0.orig/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c
+++ linux-qcom-6.8.0/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c
@@ -161,7 +161,6 @@
 
 	pad = media_pad_remote_pad_first(&xbar->pads[sink_pad]);
 	sd = media_entity_to_v4l2_subdev(pad->entity);
-
 	if (!sd) {
 		dev_dbg(xbar->isi->dev,
 			"no entity connected to crossbar input %u\n",
@@ -469,7 +468,8 @@
 	}
 
 	for (i = 0; i < xbar->num_sinks; ++i)
-		xbar->pads[i].flags = MEDIA_PAD_FL_SINK;
+		xbar->pads[i].flags = MEDIA_PAD_FL_SINK
+				    | MEDIA_PAD_FL_MUST_CONNECT;
 	for (i = 0; i < xbar->num_sources; ++i)
 		xbar->pads[i + xbar->num_sinks].flags = MEDIA_PAD_FL_SOURCE;
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c
+++ linux-qcom-6.8.0/drivers/media/platform/nxp/imx8-isi/imx8-isi-video.c
@@ -861,6 +861,7 @@
 				 const struct mxc_isi_format_info *info,
 				 const struct v4l2_pix_format_mplane *pix)
 {
+	struct vb2_v4l2_buffer *v4l2_buf = to_vb2_v4l2_buffer(vb2);
 	unsigned int i;
 
 	for (i = 0; i < info->mem_planes; i++) {
@@ -875,6 +876,8 @@
 		vb2_set_plane_payload(vb2, i, size);
 	}
 
+	v4l2_buf->field = pix->field;
+
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/Kconfig
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/Kconfig
@@ -4,3 +4,4 @@
 
 source "drivers/media/platform/qcom/camss/Kconfig"
 source "drivers/media/platform/qcom/venus/Kconfig"
+source "drivers/media/platform/qcom/iris/Kconfig"
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/Makefile
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y += camss/
 obj-y += venus/
+obj-y += iris/
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/Makefile
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/Makefile
@@ -7,6 +7,7 @@
 		camss-csid-4-1.o \
 		camss-csid-4-7.o \
 		camss-csid-gen2.o \
+		camss-csid-gen3.o \
 		camss-csiphy-2ph-1-0.o \
 		camss-csiphy-3ph-1-0.o \
 		camss-csiphy.o \
@@ -14,10 +15,14 @@
 		camss-vfe-4-1.o \
 		camss-vfe-4-7.o \
 		camss-vfe-4-8.o \
-		camss-vfe-170.o \
+		camss-vfe-17x.o \
 		camss-vfe-480.o \
+		camss-vfe-690.o \
 		camss-vfe-gen1.o \
 		camss-vfe.o \
 		camss-video.o \
+		camss-format.o \
+		camss-tpg.o \
+		camss-tpg-gen1.o
 
 obj-$(CONFIG_VIDEO_QCOM_CAMSS) += qcom-camss.o
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-csid-4-1.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-csid-4-1.c
@@ -45,128 +45,6 @@
 #define CAMSS_CSID_TG_DT_n_CGG_1(n)	(0x0b0 + 0xc * (n))
 #define CAMSS_CSID_TG_DT_n_CGG_2(n)	(0x0b4 + 0xc * (n))
 
-static const struct csid_format csid_formats[] = {
-	{
-		MEDIA_BUS_FMT_UYVY8_1X16,
-		DATA_TYPE_YUV422_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		2,
-	},
-	{
-		MEDIA_BUS_FMT_VYUY8_1X16,
-		DATA_TYPE_YUV422_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		2,
-	},
-	{
-		MEDIA_BUS_FMT_YUYV8_1X16,
-		DATA_TYPE_YUV422_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		2,
-	},
-	{
-		MEDIA_BUS_FMT_YVYU8_1X16,
-		DATA_TYPE_YUV422_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		2,
-	},
-	{
-		MEDIA_BUS_FMT_SBGGR8_1X8,
-		DATA_TYPE_RAW_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGBRG8_1X8,
-		DATA_TYPE_RAW_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGRBG8_1X8,
-		DATA_TYPE_RAW_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SRGGB8_1X8,
-		DATA_TYPE_RAW_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SBGGR10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGBRG10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGRBG10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SRGGB10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SBGGR12_1X12,
-		DATA_TYPE_RAW_12BIT,
-		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
-		12,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGBRG12_1X12,
-		DATA_TYPE_RAW_12BIT,
-		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
-		12,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGRBG12_1X12,
-		DATA_TYPE_RAW_12BIT,
-		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
-		12,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SRGGB12_1X12,
-		DATA_TYPE_RAW_12BIT,
-		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
-		12,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_Y10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-};
-
 static void csid_configure_stream(struct csid_device *csid, u8 enable)
 {
 	struct csid_testgen_config *tg = &csid->testgen;
@@ -174,7 +52,7 @@
 
 	if (enable) {
 		struct v4l2_mbus_framefmt *input_format;
-		const struct csid_format *format;
+		const struct csid_format_info *format;
 		u8 vc = 0; /* Virtual Channel 0 */
 		u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */
 		u8 dt_shift;
@@ -184,7 +62,8 @@
 			u32 num_lines, num_bytes_per_line;
 
 			input_format = &csid->fmt[MSM_CSID_PAD_SRC];
-			format = csid_get_fmt_entry(csid->formats, csid->nformats,
+			format = csid_get_fmt_entry(csid->res->formats->formats,
+						    csid->res->formats->nformats,
 						    input_format->code);
 			num_bytes_per_line = input_format->width * format->bpp * format->spp / 8;
 			num_lines = input_format->height;
@@ -211,7 +90,8 @@
 			struct csid_phy_config *phy = &csid->phy;
 
 			input_format = &csid->fmt[MSM_CSID_PAD_SINK];
-			format = csid_get_fmt_entry(csid->formats, csid->nformats,
+			format = csid_get_fmt_entry(csid->res->formats->formats,
+						    csid->res->formats->nformats,
 						    input_format->code);
 
 			val = phy->lane_cnt - 1;
@@ -311,8 +191,6 @@
 
 static void csid_subdev_init(struct csid_device *csid)
 {
-	csid->formats = csid_formats;
-	csid->nformats = ARRAY_SIZE(csid_formats);
 	csid->testgen.modes = csid_testgen_modes;
 	csid->testgen.nmodes = CSID_PAYLOAD_MODE_NUM_SUPPORTED_GEN1;
 }
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-csid-4-7.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-csid-4-7.c
@@ -44,156 +44,6 @@
 #define CAMSS_CSID_TG_DT_n_CGG_1(n)	(0x0b8 + 0xc * (n))
 #define CAMSS_CSID_TG_DT_n_CGG_2(n)	(0x0bc + 0xc * (n))
 
-static const struct csid_format csid_formats[] = {
-	{
-		MEDIA_BUS_FMT_UYVY8_1X16,
-		DATA_TYPE_YUV422_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		2,
-	},
-	{
-		MEDIA_BUS_FMT_VYUY8_1X16,
-		DATA_TYPE_YUV422_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		2,
-	},
-	{
-		MEDIA_BUS_FMT_YUYV8_1X16,
-		DATA_TYPE_YUV422_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		2,
-	},
-	{
-		MEDIA_BUS_FMT_YVYU8_1X16,
-		DATA_TYPE_YUV422_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		2,
-	},
-	{
-		MEDIA_BUS_FMT_SBGGR8_1X8,
-		DATA_TYPE_RAW_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGBRG8_1X8,
-		DATA_TYPE_RAW_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGRBG8_1X8,
-		DATA_TYPE_RAW_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SRGGB8_1X8,
-		DATA_TYPE_RAW_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SBGGR10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGBRG10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGRBG10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SRGGB10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SBGGR12_1X12,
-		DATA_TYPE_RAW_12BIT,
-		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
-		12,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGBRG12_1X12,
-		DATA_TYPE_RAW_12BIT,
-		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
-		12,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGRBG12_1X12,
-		DATA_TYPE_RAW_12BIT,
-		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
-		12,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SRGGB12_1X12,
-		DATA_TYPE_RAW_12BIT,
-		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
-		12,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SBGGR14_1X14,
-		DATA_TYPE_RAW_14BIT,
-		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
-		14,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGBRG14_1X14,
-		DATA_TYPE_RAW_14BIT,
-		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
-		14,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGRBG14_1X14,
-		DATA_TYPE_RAW_14BIT,
-		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
-		14,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SRGGB14_1X14,
-		DATA_TYPE_RAW_14BIT,
-		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
-		14,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_Y10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-};
-
 static void csid_configure_stream(struct csid_device *csid, u8 enable)
 {
 	struct csid_testgen_config *tg = &csid->testgen;
@@ -203,7 +53,7 @@
 
 	if (enable) {
 		struct v4l2_mbus_framefmt *input_format;
-		const struct csid_format *format;
+		const struct csid_format_info *format;
 		u8 vc = 0; /* Virtual Channel 0 */
 		u8 cid = vc * 4; /* id of Virtual Channel and Data Type set */
 		u8 dt_shift;
@@ -213,7 +63,8 @@
 			u32 num_bytes_per_line, num_lines;
 
 			input_format = &csid->fmt[MSM_CSID_PAD_SRC];
-			format = csid_get_fmt_entry(csid->formats, csid->nformats,
+			format = csid_get_fmt_entry(csid->res->formats->formats,
+						    csid->res->formats->nformats,
 						    input_format->code);
 			num_bytes_per_line = input_format->width * format->bpp * format->spp / 8;
 			num_lines = input_format->height;
@@ -240,7 +91,8 @@
 			struct csid_phy_config *phy = &csid->phy;
 
 			input_format = &csid->fmt[MSM_CSID_PAD_SINK];
-			format = csid_get_fmt_entry(csid->formats, csid->nformats,
+			format = csid_get_fmt_entry(csid->res->formats->formats,
+						    csid->res->formats->nformats,
 						    input_format->code);
 
 			val = phy->lane_cnt - 1;
@@ -387,8 +239,6 @@
 
 static void csid_subdev_init(struct csid_device *csid)
 {
-	csid->formats = csid_formats;
-	csid->nformats = ARRAY_SIZE(csid_formats);
 	csid->testgen.modes = csid_testgen_modes;
 	csid->testgen.nmodes = CSID_PAYLOAD_MODE_NUM_SUPPORTED_GEN1;
 }
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-csid-gen2.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-csid-gen2.c
@@ -21,6 +21,7 @@
  * interface support. As a result of that it has an
  * alternate register layout.
  */
+#define IS_LITE		(csid->res->is_lite)
 
 #define CSID_HW_VERSION		0x0
 #define		HW_VERSION_STEPPING	0
@@ -176,284 +177,18 @@
 #define		TPG_COLOR_BOX_CFG_MODE		0
 #define		TPG_COLOR_BOX_PATTERN_SEL	2
 
-static const struct csid_format csid_formats[] = {
-	{
-		MEDIA_BUS_FMT_UYVY8_1X16,
-		DATA_TYPE_YUV422_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		2,
-	},
-	{
-		MEDIA_BUS_FMT_VYUY8_1X16,
-		DATA_TYPE_YUV422_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		2,
-	},
-	{
-		MEDIA_BUS_FMT_YUYV8_1X16,
-		DATA_TYPE_YUV422_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		2,
-	},
-	{
-		MEDIA_BUS_FMT_YVYU8_1X16,
-		DATA_TYPE_YUV422_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		2,
-	},
-	{
-		MEDIA_BUS_FMT_SBGGR8_1X8,
-		DATA_TYPE_RAW_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGBRG8_1X8,
-		DATA_TYPE_RAW_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGRBG8_1X8,
-		DATA_TYPE_RAW_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SRGGB8_1X8,
-		DATA_TYPE_RAW_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SBGGR10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGBRG10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGRBG10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SRGGB10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_Y8_1X8,
-		DATA_TYPE_RAW_8BIT,
-		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
-		8,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_Y10_1X10,
-		DATA_TYPE_RAW_10BIT,
-		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
-		10,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SBGGR12_1X12,
-		DATA_TYPE_RAW_12BIT,
-		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
-		12,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGBRG12_1X12,
-		DATA_TYPE_RAW_12BIT,
-		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
-		12,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGRBG12_1X12,
-		DATA_TYPE_RAW_12BIT,
-		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
-		12,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SRGGB12_1X12,
-		DATA_TYPE_RAW_12BIT,
-		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
-		12,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SBGGR14_1X14,
-		DATA_TYPE_RAW_14BIT,
-		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
-		14,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGBRG14_1X14,
-		DATA_TYPE_RAW_14BIT,
-		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
-		14,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SGRBG14_1X14,
-		DATA_TYPE_RAW_14BIT,
-		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
-		14,
-		1,
-	},
-	{
-		MEDIA_BUS_FMT_SRGGB14_1X14,
-		DATA_TYPE_RAW_14BIT,
-		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
-		14,
-		1,
-	},
-};
-
-static void __csid_configure_stream(struct csid_device *csid, u8 enable, u8 vc)
+static void __csid_configure_rx(struct csid_device *csid,
+				struct csid_phy_config *phy, int vc)
 {
-	struct csid_testgen_config *tg = &csid->testgen;
-	u32 val;
-	u32 phy_sel = 0;
 	u8 lane_cnt = csid->phy.lane_cnt;
-	/* Source pads matching RDI channels on hardware. Pad 1 -> RDI0, Pad 2 -> RDI1, etc. */
-	struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + vc];
-	const struct csid_format *format = csid_get_fmt_entry(csid->formats, csid->nformats,
-							      input_format->code);
+	int val;
 
 	if (!lane_cnt)
 		lane_cnt = 4;
 
-	if (!tg->enabled)
-		phy_sel = csid->phy.csiphy_id;
-
-	if (enable) {
-		/*
-		 * DT_ID is a two bit bitfield that is concatenated with
-		 * the four least significant bits of the five bit VC
-		 * bitfield to generate an internal CID value.
-		 *
-		 * CSID_RDI_CFG0(vc)
-		 * DT_ID : 28:27
-		 * VC    : 26:22
-		 * DT    : 21:16
-		 *
-		 * CID   : VC 3:0 << 2 | DT_ID 1:0
-		 */
-		u8 dt_id = vc & 0x03;
-
-		if (tg->enabled) {
-			/* configure one DT, infinite frames */
-			val = vc << TPG_VC_CFG0_VC_NUM;
-			val |= INTELEAVING_MODE_ONE_SHOT << TPG_VC_CFG0_LINE_INTERLEAVING_MODE;
-			val |= 0 << TPG_VC_CFG0_NUM_FRAMES;
-			writel_relaxed(val, csid->base + CSID_TPG_VC_CFG0);
-
-			val = 0x740 << TPG_VC_CFG1_H_BLANKING_COUNT;
-			val |= 0x3ff << TPG_VC_CFG1_V_BLANKING_COUNT;
-			writel_relaxed(val, csid->base + CSID_TPG_VC_CFG1);
-
-			writel_relaxed(0x12345678, csid->base + CSID_TPG_LFSR_SEED);
-
-			val = (input_format->height & 0x1fff) << TPG_DT_n_CFG_0_FRAME_HEIGHT;
-			val |= (input_format->width & 0x1fff) << TPG_DT_n_CFG_0_FRAME_WIDTH;
-			writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_0(0));
-
-			val = format->data_type << TPG_DT_n_CFG_1_DATA_TYPE;
-			writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_1(0));
-
-			val = (tg->mode - 1) << TPG_DT_n_CFG_2_PAYLOAD_MODE;
-			val |= 0xBE << TPG_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD;
-			val |= format->decode_format << TPG_DT_n_CFG_2_ENCODE_FORMAT;
-			writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_2(0));
-
-			writel_relaxed(0, csid->base + CSID_TPG_COLOR_BARS_CFG);
-
-			writel_relaxed(0, csid->base + CSID_TPG_COLOR_BOX_CFG);
-		}
-
-		val = 1 << RDI_CFG0_BYTE_CNTR_EN;
-		val |= 1 << RDI_CFG0_FORMAT_MEASURE_EN;
-		val |= 1 << RDI_CFG0_TIMESTAMP_EN;
-		/* note: for non-RDI path, this should be format->decode_format */
-		val |= DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT;
-		val |= format->data_type << RDI_CFG0_DATA_TYPE;
-		val |= vc << RDI_CFG0_VIRTUAL_CHANNEL;
-		val |= dt_id << RDI_CFG0_DT_ID;
-		writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc));
-
-		/* CSID_TIMESTAMP_STB_POST_IRQ */
-		val = 2 << RDI_CFG1_TIMESTAMP_STB_SEL;
-		writel_relaxed(val, csid->base + CSID_RDI_CFG1(vc));
-
-		val = 1;
-		writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PERIOD(vc));
-
-		val = 0;
-		writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PATTERN(vc));
-
-		val = 1;
-		writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PERIOD(vc));
-
-		val = 0;
-		writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PATTERN(vc));
-
-		val = 1;
-		writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PERIOD(vc));
-
-		val = 0;
-		writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PATTERN(vc));
-
-		val = 1;
-		writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PERIOD(vc));
-
-		val = 0;
-		writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PATTERN(vc));
-
-		val = 0;
-		writel_relaxed(val, csid->base + CSID_RDI_CTRL(vc));
-
-		val = readl_relaxed(csid->base + CSID_RDI_CFG0(vc));
-		val |=  1 << RDI_CFG0_ENABLE;
-		writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc));
-	}
-
-	if (tg->enabled) {
-		val = enable << TPG_CTRL_TEST_EN;
-		val |= 1 << TPG_CTRL_FS_PKT_EN;
-		val |= 1 << TPG_CTRL_FE_PKT_EN;
-		val |= (lane_cnt - 1) << TPG_CTRL_NUM_ACTIVE_LANES;
-		val |= 0x64 << TPG_CTRL_CYCLES_BETWEEN_PKTS;
-		val |= 0xA << TPG_CTRL_NUM_TRAIL_BYTES;
-		writel_relaxed(val, csid->base + CSID_TPG_CTRL);
-	}
-
 	val = (lane_cnt - 1) << CSI2_RX_CFG0_NUM_ACTIVE_LANES;
-	val |= csid->phy.lane_assign << CSI2_RX_CFG0_DL0_INPUT_SEL;
-	val |= phy_sel << CSI2_RX_CFG0_PHY_NUM_SEL;
+	val |= phy->lane_assign << CSI2_RX_CFG0_DL0_INPUT_SEL;
+	val |= phy->csiphy_id << CSI2_RX_CFG0_PHY_NUM_SEL;
 	writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG0);
 
 	val = 1 << CSI2_RX_CFG1_PACKET_ECC_CORRECTION_EN;
@@ -461,21 +196,152 @@
 		val |= 1 << CSI2_RX_CFG1_VC_MODE;
 	val |= 1 << CSI2_RX_CFG1_MISR_EN;
 	writel_relaxed(val, csid->base + CSID_CSI2_RX_CFG1);
+}
+
+static void __csid_ctrl_rdi(struct csid_device *csid, int enable, u8 rdi)
+{
+	int val;
 
 	if (enable)
 		val = HALT_CMD_RESUME_AT_FRAME_BOUNDARY << RDI_CTRL_HALT_CMD;
 	else
 		val = HALT_CMD_HALT_AT_FRAME_BOUNDARY << RDI_CTRL_HALT_CMD;
+	writel_relaxed(val, csid->base + CSID_RDI_CTRL(rdi));
+}
+
+static void __csid_configure_testgen(struct csid_device *csid, u8 enable, u8 vc)
+{
+	struct csid_testgen_config *tg = &csid->testgen;
+	struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + vc];
+	const struct csid_format_info *format = csid_get_fmt_entry(csid->res->formats->formats,
+								   csid->res->formats->nformats,
+								   input_format->code);
+	u8 lane_cnt = csid->phy.lane_cnt;
+	u32 val;
+
+	if (!lane_cnt)
+		lane_cnt = 4;
+
+	/* configure one DT, infinite frames */
+	val = vc << TPG_VC_CFG0_VC_NUM;
+	val |= INTELEAVING_MODE_ONE_SHOT << TPG_VC_CFG0_LINE_INTERLEAVING_MODE;
+	val |= 0 << TPG_VC_CFG0_NUM_FRAMES;
+	writel_relaxed(val, csid->base + CSID_TPG_VC_CFG0);
+
+	val = 0x740 << TPG_VC_CFG1_H_BLANKING_COUNT;
+	val |= 0x3ff << TPG_VC_CFG1_V_BLANKING_COUNT;
+	writel_relaxed(val, csid->base + CSID_TPG_VC_CFG1);
+
+	writel_relaxed(0x12345678, csid->base + CSID_TPG_LFSR_SEED);
+
+	val = (input_format->height & 0x1fff) << TPG_DT_n_CFG_0_FRAME_HEIGHT;
+	val |= (input_format->width & 0x1fff) << TPG_DT_n_CFG_0_FRAME_WIDTH;
+	writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_0(0));
+
+	val = format->data_type << TPG_DT_n_CFG_1_DATA_TYPE;
+	writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_1(0));
+
+	val = (tg->mode - 1) << TPG_DT_n_CFG_2_PAYLOAD_MODE;
+	val |= 0xBE << TPG_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD;
+	val |= format->decode_format << TPG_DT_n_CFG_2_ENCODE_FORMAT;
+	writel_relaxed(val, csid->base + CSID_TPG_DT_n_CFG_2(0));
+
+	writel_relaxed(0, csid->base + CSID_TPG_COLOR_BARS_CFG);
+
+	writel_relaxed(0, csid->base + CSID_TPG_COLOR_BOX_CFG);
+
+	val = enable << TPG_CTRL_TEST_EN;
+	val |= 1 << TPG_CTRL_FS_PKT_EN;
+	val |= 1 << TPG_CTRL_FE_PKT_EN;
+	val |= (lane_cnt - 1) << TPG_CTRL_NUM_ACTIVE_LANES;
+	val |= 0x64 << TPG_CTRL_CYCLES_BETWEEN_PKTS;
+	val |= 0xA << TPG_CTRL_NUM_TRAIL_BYTES;
+	writel_relaxed(val, csid->base + CSID_TPG_CTRL);
+}
+
+static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8 vc)
+{
+	/* Source pads matching RDI channels on hardware. Pad 1 -> RDI0, Pad 2 -> RDI1, etc. */
+	struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + vc];
+	const struct csid_format_info *format = csid_get_fmt_entry(csid->res->formats->formats,
+								   csid->res->formats->nformats,
+								   input_format->code);
+	u32 val;
+
+	/*
+	 * DT_ID is a two bit bitfield that is concatenated with
+	 * the four least significant bits of the five bit VC
+	 * bitfield to generate an internal CID value.
+	 *
+	 * CSID_RDI_CFG0(vc)
+	 * DT_ID : 28:27
+	 * VC    : 26:22
+	 * DT    : 21:16
+	 *
+	 * CID   : VC 3:0 << 2 | DT_ID 1:0
+	 */
+	u8 dt_id = vc & 0x03;
+
+	val = 1 << RDI_CFG0_BYTE_CNTR_EN;
+	val |= 1 << RDI_CFG0_FORMAT_MEASURE_EN;
+	val |= 1 << RDI_CFG0_TIMESTAMP_EN;
+	/* note: for non-RDI path, this should be format->decode_format */
+	val |= DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT;
+	val |= format->data_type << RDI_CFG0_DATA_TYPE;
+	val |= vc << RDI_CFG0_VIRTUAL_CHANNEL;
+	val |= dt_id << RDI_CFG0_DT_ID;
+	writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc));
+
+	/* CSID_TIMESTAMP_STB_POST_IRQ */
+	val = 2 << RDI_CFG1_TIMESTAMP_STB_SEL;
+	writel_relaxed(val, csid->base + CSID_RDI_CFG1(vc));
+
+	val = 1;
+	writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PERIOD(vc));
+
+	val = 0;
+	writel_relaxed(val, csid->base + CSID_RDI_FRM_DROP_PATTERN(vc));
+
+	val = 1;
+	writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PERIOD(vc));
+
+	val = 0;
+	writel_relaxed(val, csid->base + CSID_RDI_IRQ_SUBSAMPLE_PATTERN(vc));
+
+	val = 1;
+	writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PERIOD(vc));
+
+	val = 0;
+	writel_relaxed(val, csid->base + CSID_RDI_RPP_PIX_DROP_PATTERN(vc));
+
+	val = 1;
+	writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PERIOD(vc));
+
+	val = 0;
+	writel_relaxed(val, csid->base + CSID_RDI_RPP_LINE_DROP_PATTERN(vc));
+
+	val = 0;
 	writel_relaxed(val, csid->base + CSID_RDI_CTRL(vc));
+
+	val = readl_relaxed(csid->base + CSID_RDI_CFG0(vc));
+	val |=  enable << RDI_CFG0_ENABLE;
+	writel_relaxed(val, csid->base + CSID_RDI_CFG0(vc));
 }
 
 static void csid_configure_stream(struct csid_device *csid, u8 enable)
 {
+	struct csid_testgen_config *tg = &csid->testgen;
 	u8 i;
 	/* Loop through all enabled VCs and configure stream for each */
 	for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
-		if (csid->phy.en_vc & BIT(i))
-			__csid_configure_stream(csid, enable, i);
+		if (csid->phy.en_vc & BIT(i)) {
+			if (tg->enabled)
+				__csid_configure_testgen(csid, enable, i);
+
+			__csid_configure_rdi_stream(csid, enable, i);
+			__csid_configure_rx(csid, &csid->phy, i);
+			__csid_ctrl_rdi(csid, enable, i);
+		}
 }
 
 static int csid_configure_testgen_pattern(struct csid_device *csid, s32 val)
@@ -612,8 +478,6 @@
 
 static void csid_subdev_init(struct csid_device *csid)
 {
-	csid->formats = csid_formats;
-	csid->nformats = ARRAY_SIZE(csid_formats);
 	csid->testgen.modes = csid_testgen_modes;
 	csid->testgen.nmodes = CSID_PAYLOAD_MODE_NUM_SUPPORTED_GEN2;
 }
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-csid-gen3.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-csid-gen3.c
@@ -0,0 +1,430 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-csid-gen3.c
+ *
+ * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module
+ *
+ * Copyright (C) 2020 Linaro Ltd.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+#include "camss.h"
+#include "camss-csid.h"
+#include "camss-csid-gen3.h"
+
+#define CSID_HW_VERSION                 0x0
+#define HW_VERSION_STEPPING             0x0
+#define HW_VERSION_REVISION             0x10
+#define HW_VERSION_GENERATION           0x1C
+
+#define CSID_TOP_IO_PATH_CFG0(csid)	(0x4 * (csid))
+#define		OUTPUT_IFE_EN			0x100
+#define		INTERNAL_CSID			1
+
+#define CSID_RST_CFG			0xC
+#define		RST_MODE			0
+#define		RST_LOCATION			4
+
+#define CSID_RST_CMD			0x10
+#define		SELECT_HW_RST			0
+#define		SELECT_SW_RST			1
+#define		SELECT_IRQ_RST			2
+
+#define CSID_CSI2_RX_IRQ_STATUS		0x9C
+#define CSID_CSI2_RX_IRQ_MASK		0xA0
+#define CSID_CSI2_RX_IRQ_CLEAR		0xA4
+#define CSID_CSI2_RX_IRQ_SET		0xA8
+
+#define CSID_CSI2_RDIN_IRQ_STATUS(rdi)	(0xEC + 0x10 * (rdi))
+
+#define CSID_CSI2_RDIN_IRQ_CLEAR(rdi)	(0xF4 + 0x10 * (rdi))
+#define CSID_CSI2_RDIN_IRQ_SET(rdi)	(0xF8 + 0x10 * (rdi))
+
+#define CSID_TOP_IRQ_STATUS		0x7C
+#define		 TOP_IRQ_STATUS_RESET_DONE	0
+
+#define CSID_TOP_IRQ_MASK		0x80
+#define CSID_TOP_IRQ_CLEAR		0x84
+#define CSID_TOP_IRQ_SET		0x88
+
+#define CSID_IRQ_CMD			0x14
+#define		IRQ_CMD_CLEAR			0
+#define		IRQ_CMD_SET			4
+
+#define CSID_REG_UPDATE_CMD		0x18
+
+#define CSID_BUF_DONE_IRQ_STATUS	0x8C
+#define		BUF_DONE_IRQ_STATUS_RDI_OFFSET	(csid_is_lite(csid) ? 1 : 13)
+#define CSID_BUF_DONE_IRQ_MASK		0x90
+#define CSID_BUF_DONE_IRQ_CLEAR		0x94
+#define CSID_BUF_DONE_IRQ_SET		0x98
+
+#define CSID_RDI0_IRQ_MASK	0xF0
+
+#define CSID_CSI2_RX_CFG0		0x200
+#define		CSI2_RX_CFG0_NUM_ACTIVE_LANES	0
+#define		CSI2_RX_CFG0_VC_MODE		3
+#define		CSI2_RX_CFG0_DL0_INPUT_SEL	4
+#define		CSI2_RX_CFG0_PHY_NUM_SEL	20
+#define		CSI2_RX_CFG0_PHY_SEL_BASE_IDX	1
+#define		CSI2_RX_CFG0_TPG_NUM_EN		27
+#define		CSI2_RX_CFG0_TPG_NUM_SEL	28
+
+#define CSID_CSI2_RX_CFG1		0x204
+#define		CSI2_RX_CFG1_ECC_CORRECTION_EN	0
+
+#define CSID_RDI_CFG0(rdi)	(csid_is_lite(csid) ? (0x300 + 0x100 * (rdi)) :\
+					(0x500 + 0x100 * (rdi)))
+#define		RDI_CFG0_DECODE_FORMAT		12
+#define		RDI_CFG0_DT			16
+#define		RDI_CFG0_VC			22
+#define		RDI_CFG0_DT_ID			27
+#define		RDI_CFG0_EN			31
+
+#define CSID_RDI_CTRL(rdi)	(csid_is_lite(csid) ? (0x304 + 0x100 * (rdi)) :\
+					(0x504 + 0x100 * (rdi)))
+#define		RDI_CTRL_START_CMD		0
+
+#define CSID_RDI_CFG1(rdi)	(csid_is_lite(csid) ? (0x310 + 0x100 * (rdi)) :\
+					(0x510 + 0x100 * (rdi)))
+#define		RDI_CFG1_DROP_H_EN		5
+#define		RDI_CFG1_DROP_V_EN		6
+#define		RDI_CFG1_CROP_H_EN		7
+#define		RDI_CFG1_CROP_V_EN		8
+#define		RDI_CFG1_PACKING_FORMAT		15
+
+#define CSID_RDI_IRQ_SUBSAMPLE_PATTERN(rdi)	(0x548 + 0x100 * (rdi))
+#define CSID_RDI_IRQ_SUBSAMPLE_PERIOD(rdi)	(0x54C + 0x100 * (rdi))
+
+#define REG_UPDATE_RDI			reg_update_rdi
+
+static inline int reg_update_rdi(struct csid_device *csid, int n)
+{
+	return BIT(n + 4) + BIT(20 + n);
+}
+
+/*
+ * csid_hw_version - CSID hardware version query
+ * @csid: CSID device
+ *
+ * Return HW version or error
+ */
+static u32 csid_hw_version(struct csid_device *csid)
+{
+	u32 hw_version;
+	u32 hw_gen;
+	u32 hw_rev;
+	u32 hw_step;
+
+	hw_version = readl_relaxed(csid->base + CSID_HW_VERSION);
+	hw_gen = (hw_version >> HW_VERSION_GENERATION) & 0xF;
+	hw_rev = (hw_version >> HW_VERSION_REVISION) & 0xFFF;
+	hw_step = (hw_version >> HW_VERSION_STEPPING) & 0xFFFF;
+	dev_info(csid->camss->dev, "CSID:%d HW Version = %u.%u.%u\n",
+		csid->id, hw_gen, hw_rev, hw_step);
+
+	return hw_version;
+}
+
+/*
+ * csid_src_pad_code - Pick an output/src format based on the input/sink format
+ * @csid: CSID device
+ * @sink_code: The sink format of the input
+ * @match_format_idx: Request preferred index, as defined by subdevice csid
+ *                    format. Set @match_code to 0 if used.
+ * @match_code: Request preferred code, set @match_format_idx to 0 if used
+ *
+ * Return 0 on failure or src format code otherwise
+ */
+static u32 csid_src_pad_code(struct csid_device *csid, u32 sink_code,
+		      unsigned int match_format_idx, u32 match_code)
+{
+	if (csid->camss->res->version == CAMSS_8x16) {
+		if (match_format_idx > 0)
+			return 0;
+
+		return sink_code;
+	}
+
+	switch (sink_code) {
+	case MEDIA_BUS_FMT_SBGGR10_1X10:
+	{
+		u32 src_code[] = {
+			MEDIA_BUS_FMT_SBGGR10_1X10,
+			MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE,
+		};
+
+		return csid_find_code(src_code, ARRAY_SIZE(src_code),
+				      match_format_idx, match_code);
+	}
+	case MEDIA_BUS_FMT_Y10_1X10:
+	{
+		u32 src_code[] = {
+			MEDIA_BUS_FMT_Y10_1X10,
+			MEDIA_BUS_FMT_Y10_2X8_PADHI_LE,
+		};
+
+		return csid_find_code(src_code, ARRAY_SIZE(src_code),
+				      match_format_idx, match_code);
+	}
+	default:
+		if (match_format_idx > 0)
+			return 0;
+
+		return sink_code;
+	}
+}
+
+static void __csid_configure_rx(struct csid_device *csid,
+				struct csid_phy_config *phy, int vc)
+{
+	int val;
+	struct camss *camss;
+	struct tpg_device *tpg;
+
+	camss = csid->camss;
+	val = (phy->lane_cnt - 1) << CSI2_RX_CFG0_NUM_ACTIVE_LANES;
+	val |= phy->lane_assign << CSI2_RX_CFG0_DL0_INPUT_SEL;
+	val |= (phy->csiphy_id + CSI2_RX_CFG0_PHY_SEL_BASE_IDX) << CSI2_RX_CFG0_PHY_NUM_SEL;
+	if (vc > 3)
+		val |= 1 << CSI2_RX_CFG0_VC_MODE;
+
+	if (camss->tpg) {
+		tpg = &camss->tpg[phy->csiphy_id];
+
+		if (tpg->testgen.mode > 0) {
+			val |= (phy->csiphy_id + 1) << CSI2_RX_CFG0_TPG_NUM_SEL;
+			val |= 1 << CSI2_RX_CFG0_TPG_NUM_EN;
+		} else {
+			val |= 0 << CSI2_RX_CFG0_TPG_NUM_SEL;
+			val |= 0 << CSI2_RX_CFG0_TPG_NUM_EN;
+		}
+	}
+
+	writel(val, csid->base + CSID_CSI2_RX_CFG0);
+
+	val = 1 << CSI2_RX_CFG1_ECC_CORRECTION_EN;
+	writel(val, csid->base + CSID_CSI2_RX_CFG1);
+}
+
+static void __csid_ctrl_rdi(struct csid_device *csid, int enable, u8 rdi)
+{
+	int val = 0;
+
+	if (enable)
+		val = 1 << RDI_CTRL_START_CMD;
+
+	writel(val, csid->base + CSID_RDI_CTRL(rdi));
+}
+
+static void __csid_configure_top(struct csid_device *csid)
+{
+	u32 val;
+
+	/* csid lite doesn't need to configure top register */
+	if (csid->res->is_lite)
+		return;
+
+	/* CSID top is a new function.
+	 * CSID can connect to VFE & SFE(Sensor Front End).
+	 * This connection is controlled by CSID top.
+	 * Only enable VFE path in current driver.
+	 */
+	val = OUTPUT_IFE_EN | INTERNAL_CSID;
+	writel(val, csid->camss->csid_top_base + CSID_TOP_IO_PATH_CFG0(csid->id));
+}
+
+static void __csid_configure_rdi_stream(struct csid_device *csid, u8 enable, u8 vc)
+{
+	u32 val;
+	u8 lane_cnt = csid->phy.lane_cnt;
+	/* Source pads matching RDI channels on hardware. Pad 1 -> RDI0, Pad 2 -> RDI1, etc. */
+	struct v4l2_mbus_framefmt *input_format = &csid->fmt[MSM_CSID_PAD_FIRST_SRC + vc];
+	const struct csid_format_info *format = csid_get_fmt_entry(csid->res->formats->formats,
+								   csid->res->formats->nformats,
+								   input_format->code);
+	if (!lane_cnt)
+		lane_cnt = 4;
+
+	/*
+	 * DT_ID is a two bit bitfield that is concatenated with
+	 * the four least significant bits of the five bit VC
+	 * bitfield to generate an internal CID value.
+	 *
+	 * CSID_RDI_CFG0(vc)
+	 * DT_ID : 28:27
+	 * VC    : 26:22
+	 * DT    : 21:16
+	 *
+	 * CID   : VC 3:0 << 2 | DT_ID 1:0
+	 */
+	u8 dt_id = vc & 0x03;
+
+	/* note: for non-RDI path, this should be format->decode_format */
+	val = DECODE_FORMAT_PAYLOAD_ONLY << RDI_CFG0_DECODE_FORMAT;
+	val |= vc << RDI_CFG0_VC;
+	val |= format->data_type << RDI_CFG0_DT;
+	val |= dt_id << RDI_CFG0_DT_ID;
+
+	writel(val, csid->base + CSID_RDI_CFG0(vc));
+
+	val = readl(csid->base + CSID_RDI_CFG1(vc));
+	val |= 1 << RDI_CFG1_PACKING_FORMAT;
+	val |= 1 << RDI_CFG1_DROP_H_EN;
+	val |= 1 << RDI_CFG1_DROP_V_EN;
+	val |= 1 << RDI_CFG1_CROP_H_EN;
+	val |= 1 << RDI_CFG1_CROP_V_EN;
+
+	writel(val, csid->base + CSID_RDI_CFG1(vc));
+
+	val = 0;
+	writel(val, csid->base + CSID_RDI_CTRL(vc));
+
+	val = readl(csid->base + CSID_RDI_CFG0(vc));
+
+	if (enable)
+		val |= 1 << RDI_CFG0_EN;
+	writel(val, csid->base + CSID_RDI_CFG0(vc));
+}
+
+static void csid_configure_stream(struct csid_device *csid, u8 enable)
+{
+	u8 i;
+
+	/* Loop through all enabled VCs and configure stream for each */
+	for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
+		if (csid->phy.en_vc & BIT(i)) {
+			if (!csid->res->is_lite)
+				__csid_configure_top(csid);
+			__csid_configure_rdi_stream(csid, enable, i);
+			__csid_configure_rx(csid, &csid->phy, i);
+			__csid_ctrl_rdi(csid, enable, i);
+		}
+}
+
+/*
+ * csid_isr - CSID module interrupt service routine
+ * @irq: Interrupt line
+ * @dev: CSID device
+ *
+ * Return IRQ_HANDLED on success
+ */
+static irqreturn_t csid_isr(int irq, void *dev)
+{
+	struct csid_device *csid = dev;
+	struct vfe_device *vfe = csid->camss->vfe;
+	u32 rx_irq_status, val, buf_done_val;
+	u8 reset_done;
+	int i;
+
+	val = readl(csid->base + CSID_TOP_IRQ_STATUS);
+	writel(val, csid->base + CSID_TOP_IRQ_CLEAR);
+	reset_done = val & BIT(TOP_IRQ_STATUS_RESET_DONE);
+
+	val = readl(csid->base + CSID_CSI2_RX_IRQ_STATUS);
+	rx_irq_status = val;
+	writel(val, csid->base + CSID_CSI2_RX_IRQ_CLEAR);
+
+	buf_done_val = readl(csid->base + CSID_BUF_DONE_IRQ_STATUS);
+	writel(buf_done_val, csid->base + CSID_BUF_DONE_IRQ_CLEAR);
+
+	/* Read and clear IRQ status for each enabled RDI channel */
+	for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
+		if (csid->phy.en_vc & BIT(i)) {
+			val = readl(csid->base + CSID_CSI2_RDIN_IRQ_STATUS(i));
+			writel(val, csid->base + CSID_CSI2_RDIN_IRQ_CLEAR(i));
+
+			if (buf_done_val & BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i)) {
+				/* For Titan 690, Buf Done IRQ&REG has been moved to CSID from VFE.
+				 * Once CSID received Buf Done, need notify this event to VFE.
+				 * Trigger VFE to handle Buf Done process.
+				 */
+				camss_buf_done(csid->camss, csid->id, i);
+			}
+		}
+
+	val = 1 << IRQ_CMD_CLEAR;
+	writel(val, csid->base + CSID_IRQ_CMD);
+
+	if (reset_done)
+		complete(&csid->reset_complete);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * csid_reset - Trigger reset on CSID module and wait to complete
+ * @csid: CSID device
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int csid_reset(struct csid_device *csid)
+{
+	unsigned long time;
+	u32 val;
+	int i;
+
+	reinit_completion(&csid->reset_complete);
+
+	writel(1, csid->base + CSID_TOP_IRQ_CLEAR);
+	writel(1, csid->base + CSID_IRQ_CMD);
+
+	/* preserve registers */
+	val = (0x1 << RST_LOCATION) | (0x1 << RST_MODE);
+	writel(val, csid->base + CSID_RST_CFG);
+
+	val = (0x1 << SELECT_SW_RST) | (0x1 << SELECT_IRQ_RST);
+	writel(val, csid->base + CSID_RST_CMD);
+
+	time = wait_for_completion_timeout(&csid->reset_complete,
+		   msecs_to_jiffies(CSID_RESET_TIMEOUT_MS));
+	if (!time) {
+		dev_err(csid->camss->dev, "CSID reset timeout\n");
+		return -EIO;
+	}
+
+	/* Buf done mask */
+	for (i = 0; i < MSM_CSID_MAX_SRC_STREAMS; i++)
+		if (csid->phy.en_vc & BIT(i)) {
+			writel(BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i),
+						csid->base + CSID_BUF_DONE_IRQ_CLEAR);
+			writel(0x1 << IRQ_CMD_CLEAR, csid->base + CSID_IRQ_CMD);
+			writel(BIT(BUF_DONE_IRQ_STATUS_RDI_OFFSET + i),
+						csid->base + CSID_BUF_DONE_IRQ_MASK);
+		}
+
+	return 0;
+}
+
+static void csid_subdev_reg_update(struct csid_device *csid, int port_id, bool is_clear)
+{
+	if (is_clear) {
+		csid->reg_update &= ~REG_UPDATE_RDI(csid, port_id);
+	} else {
+		csid->reg_update |= REG_UPDATE_RDI(csid, port_id);
+		writel(csid->reg_update, csid->base + CSID_REG_UPDATE_CMD);
+	}
+}
+
+static void csid_subdev_init(struct csid_device *csid)
+{
+	/* nop */
+}
+
+const struct csid_hw_ops csid_ops_gen3 = {
+	/* No testgen pattern hw in csid gen3 HW */
+	.configure_testgen_pattern = NULL,
+	.configure_stream = csid_configure_stream,
+	.hw_version = csid_hw_version,
+	.isr = csid_isr,
+	.reset = csid_reset,
+	.src_pad_code = csid_src_pad_code,
+	.subdev_init = csid_subdev_init,
+	.reg_update = csid_subdev_reg_update,
+};
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-csid-gen3.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-csid-gen3.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * camss-csid-gen3.h
+ *
+ * Qualcomm MSM Camera Subsystem - CSID (CSI Decoder) Module Generation 3
+ *
+ * Copyright (C) 2021 Linaro Ltd.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#ifndef QC_MSM_CAMSS_CSID_GEN3_H
+#define QC_MSM_CAMSS_CSID_GEN3_H
+
+#define DECODE_FORMAT_UNCOMPRESSED_8_BIT	0x1
+#define DECODE_FORMAT_UNCOMPRESSED_10_BIT	0x2
+#define DECODE_FORMAT_UNCOMPRESSED_12_BIT	0x3
+#define DECODE_FORMAT_UNCOMPRESSED_14_BIT	0x4
+#define DECODE_FORMAT_UNCOMPRESSED_16_BIT	0x5
+#define DECODE_FORMAT_UNCOMPRESSED_20_BIT	0x6
+#define DECODE_FORMAT_UNCOMPRESSED_24_BIT	0x7
+#define DECODE_FORMAT_PAYLOAD_ONLY		0xf
+
+
+#define PLAIN_FORMAT_PLAIN8	0x0 /* supports DPCM, UNCOMPRESSED_6/8_BIT */
+#define PLAIN_FORMAT_PLAIN16	0x1 /* supports DPCM, UNCOMPRESSED_10/16_BIT */
+#define PLAIN_FORMAT_PLAIN32	0x2 /* supports UNCOMPRESSED_20_BIT */
+
+#endif /* QC_MSM_CAMSS_CSID_GEN3_H */
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-csid.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-csid.c
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/pm_domain.h>
 #include <linux/pm_runtime.h>
 #include <linux/regulator/consumer.h>
 #include <media/media-entity.h>
@@ -45,6 +46,450 @@
 	NULL
 };
 
+static const struct csid_format_info formats_4_1[] = {
+	{
+		MEDIA_BUS_FMT_UYVY8_1X16,
+		DATA_TYPE_YUV422_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		2,
+	},
+	{
+		MEDIA_BUS_FMT_VYUY8_1X16,
+		DATA_TYPE_YUV422_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		2,
+	},
+	{
+		MEDIA_BUS_FMT_YUYV8_1X16,
+		DATA_TYPE_YUV422_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		2,
+	},
+	{
+		MEDIA_BUS_FMT_YVYU8_1X16,
+		DATA_TYPE_YUV422_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		2,
+	},
+	{
+		MEDIA_BUS_FMT_SBGGR8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGBRG8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGRBG8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SRGGB8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SBGGR10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGBRG10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGRBG10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SRGGB10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SBGGR12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+		12,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGBRG12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+		12,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGRBG12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+		12,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SRGGB12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+		12,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_Y10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+};
+
+static const struct csid_format_info formats_4_7[] = {
+	{
+		MEDIA_BUS_FMT_UYVY8_1X16,
+		DATA_TYPE_YUV422_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		2,
+	},
+	{
+		MEDIA_BUS_FMT_VYUY8_1X16,
+		DATA_TYPE_YUV422_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		2,
+	},
+	{
+		MEDIA_BUS_FMT_YUYV8_1X16,
+		DATA_TYPE_YUV422_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		2,
+	},
+	{
+		MEDIA_BUS_FMT_YVYU8_1X16,
+		DATA_TYPE_YUV422_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		2,
+	},
+	{
+		MEDIA_BUS_FMT_SBGGR8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGBRG8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGRBG8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SRGGB8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SBGGR10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGBRG10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGRBG10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SRGGB10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SBGGR12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+		12,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGBRG12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+		12,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGRBG12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+		12,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SRGGB12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+		12,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SBGGR14_1X14,
+		DATA_TYPE_RAW_14BIT,
+		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+		14,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGBRG14_1X14,
+		DATA_TYPE_RAW_14BIT,
+		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+		14,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGRBG14_1X14,
+		DATA_TYPE_RAW_14BIT,
+		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+		14,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SRGGB14_1X14,
+		DATA_TYPE_RAW_14BIT,
+		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+		14,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_Y10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+};
+
+static const struct csid_format_info formats_gen2[] = {
+	{
+		MEDIA_BUS_FMT_UYVY8_1X16,
+		DATA_TYPE_YUV422_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		2,
+	},
+	{
+		MEDIA_BUS_FMT_VYUY8_1X16,
+		DATA_TYPE_YUV422_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		2,
+	},
+	{
+		MEDIA_BUS_FMT_YUYV8_1X16,
+		DATA_TYPE_YUV422_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		2,
+	},
+	{
+		MEDIA_BUS_FMT_YVYU8_1X16,
+		DATA_TYPE_YUV422_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		2,
+	},
+	{
+		MEDIA_BUS_FMT_SBGGR8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGBRG8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGRBG8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SRGGB8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SBGGR10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGBRG10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGRBG10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SRGGB10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_Y8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		DECODE_FORMAT_UNCOMPRESSED_8_BIT,
+		8,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_Y10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		DECODE_FORMAT_UNCOMPRESSED_10_BIT,
+		10,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SBGGR12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+		12,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGBRG12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+		12,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGRBG12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+		12,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SRGGB12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		DECODE_FORMAT_UNCOMPRESSED_12_BIT,
+		12,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SBGGR14_1X14,
+		DATA_TYPE_RAW_14BIT,
+		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+		14,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGBRG14_1X14,
+		DATA_TYPE_RAW_14BIT,
+		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+		14,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SGRBG14_1X14,
+		DATA_TYPE_RAW_14BIT,
+		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+		14,
+		1,
+	},
+	{
+		MEDIA_BUS_FMT_SRGGB14_1X14,
+		DATA_TYPE_RAW_14BIT,
+		DECODE_FORMAT_UNCOMPRESSED_14_BIT,
+		14,
+		1,
+	},
+};
+
+const struct csid_formats csid_formats_4_1 = {
+	.nformats = ARRAY_SIZE(formats_4_1),
+	.formats = formats_4_1
+};
+
+const struct csid_formats csid_formats_4_7 = {
+	.nformats = ARRAY_SIZE(formats_4_7),
+	.formats = formats_4_7
+};
+
+const struct csid_formats csid_formats_gen2 = {
+	.nformats = ARRAY_SIZE(formats_gen2),
+	.formats = formats_gen2
+};
+
 u32 csid_find_code(u32 *codes, unsigned int ncodes,
 		   unsigned int match_format_idx, u32 match_code)
 {
@@ -65,9 +510,9 @@
 	return codes[0];
 }
 
-const struct csid_format *csid_get_fmt_entry(const struct csid_format *formats,
-					     unsigned int nformats,
-					     u32 code)
+const struct csid_format_info *csid_get_fmt_entry(const struct csid_format_info *formats,
+						  unsigned int nformats,
+						  u32 code)
 {
 	unsigned int i;
 
@@ -87,12 +532,12 @@
 static int csid_set_clock_rates(struct csid_device *csid)
 {
 	struct device *dev = csid->camss->dev;
-	const struct csid_format *fmt;
+	const struct csid_format_info *fmt;
 	s64 link_freq;
 	int i, j;
 	int ret;
 
-	fmt = csid_get_fmt_entry(csid->formats, csid->nformats,
+	fmt = csid_get_fmt_entry(csid->res->formats->formats, csid->res->formats->nformats,
 				 csid->fmt[MSM_CSIPHY_PAD_SINK].code);
 	link_freq = camss_get_link_freq(&csid->subdev.entity, fmt->bpp,
 					csid->phy.lane_cnt);
@@ -158,7 +603,6 @@
 	struct csid_device *csid = v4l2_get_subdevdata(sd);
 	struct camss *camss = csid->camss;
 	struct device *dev = camss->dev;
-	struct vfe_device *vfe = &camss->vfe[csid->id];
 	int ret = 0;
 
 	if (on) {
@@ -167,10 +611,11 @@
 		 * switching on the CSID. Do so unconditionally, as there is no
 		 * drawback in following the same powering order on older SoCs.
 		 */
-		ret = vfe_get(vfe);
+		ret = csid->res->parent_dev_ops->get(camss, csid->id);
 		if (ret < 0)
 			return ret;
 
+		dev_pm_genpd_set_performance_state(dev, RPMP_PERF_STATE_NOM);
 		ret = pm_runtime_resume_and_get(dev);
 		if (ret < 0)
 			return ret;
@@ -202,7 +647,7 @@
 
 		enable_irq(csid->irq);
 
-		ret = csid->ops->reset(csid);
+		ret = csid->res->hw_ops->reset(csid);
 		if (ret < 0) {
 			disable_irq(csid->irq);
 			camss_disable_clocks(csid->nclocks, csid->clock);
@@ -212,14 +657,14 @@
 			return ret;
 		}
 
-		csid->ops->hw_version(csid);
+		csid->res->hw_ops->hw_version(csid);
 	} else {
 		disable_irq(csid->irq);
 		camss_disable_clocks(csid->nclocks, csid->clock);
 		regulator_bulk_disable(csid->num_supplies,
 				       csid->supplies);
 		pm_runtime_put_sync(dev);
-		vfe_put(vfe);
+		csid->res->parent_dev_ops->put(camss, csid->id);
 	}
 
 	return ret;
@@ -253,7 +698,7 @@
 	}
 
 	if (csid->phy.need_vc_update) {
-		csid->ops->configure_stream(csid, enable);
+		csid->res->hw_ops->configure_stream(csid, enable);
 		csid->phy.need_vc_update = false;
 	}
 
@@ -301,12 +746,12 @@
 	case MSM_CSID_PAD_SINK:
 		/* Set format on sink pad */
 
-		for (i = 0; i < csid->nformats; i++)
-			if (fmt->code == csid->formats[i].code)
+		for (i = 0; i < csid->res->formats->nformats; i++)
+			if (fmt->code == csid->res->formats->formats[i].code)
 				break;
 
 		/* If not found, use UYVY as default */
-		if (i >= csid->nformats)
+		if (i >= csid->res->formats->nformats)
 			fmt->code = MEDIA_BUS_FMT_UYVY8_1X16;
 
 		fmt->width = clamp_t(u32, fmt->width, 1, 8191);
@@ -318,24 +763,24 @@
 		break;
 
 	case MSM_CSID_PAD_SRC:
-		if (csid->testgen_mode->cur.val == 0) {
+		if (!csid->testgen_mode || csid->testgen_mode->cur.val == 0) {
 			/* Test generator is disabled, */
 			/* keep pad formats in sync */
 			u32 code = fmt->code;
 
 			*fmt = *__csid_get_format(csid, sd_state,
 						      MSM_CSID_PAD_SINK, which);
-			fmt->code = csid->ops->src_pad_code(csid, fmt->code, 0, code);
+			fmt->code = csid->res->hw_ops->src_pad_code(csid, fmt->code, 0, code);
 		} else {
 			/* Test generator is enabled, set format on source */
 			/* pad to allow test generator usage */
 
-			for (i = 0; i < csid->nformats; i++)
-				if (csid->formats[i].code == fmt->code)
+			for (i = 0; i < csid->res->formats->nformats; i++)
+				if (csid->res->formats->formats[i].code == fmt->code)
 					break;
 
 			/* If not found, use UYVY as default */
-			if (i >= csid->nformats)
+			if (i >= csid->res->formats->nformats)
 				fmt->code = MEDIA_BUS_FMT_UYVY8_1X16;
 
 			fmt->width = clamp_t(u32, fmt->width, 1, 8191);
@@ -363,27 +808,27 @@
 	struct csid_device *csid = v4l2_get_subdevdata(sd);
 
 	if (code->pad == MSM_CSID_PAD_SINK) {
-		if (code->index >= csid->nformats)
+		if (code->index >= csid->res->formats->nformats)
 			return -EINVAL;
 
-		code->code = csid->formats[code->index].code;
+		code->code = csid->res->formats->formats[code->index].code;
 	} else {
-		if (csid->testgen_mode->cur.val == 0) {
+		if (!csid->testgen_mode || csid->testgen_mode->cur.val == 0) {
 			struct v4l2_mbus_framefmt *sink_fmt;
 
 			sink_fmt = __csid_get_format(csid, sd_state,
 						     MSM_CSID_PAD_SINK,
 						     code->which);
 
-			code->code = csid->ops->src_pad_code(csid, sink_fmt->code,
-						       code->index, 0);
+			code->code = csid->res->hw_ops->src_pad_code(csid, sink_fmt->code,
+								     code->index, 0);
 			if (!code->code)
 				return -EINVAL;
 		} else {
-			if (code->index >= csid->nformats)
+			if (code->index >= csid->res->formats->nformats)
 				return -EINVAL;
 
-			code->code = csid->formats[code->index].code;
+			code->code = csid->res->formats->formats[code->index].code;
 		}
 	}
 
@@ -522,6 +967,7 @@
 static int csid_set_test_pattern(struct csid_device *csid, s32 value)
 {
 	struct csid_testgen_config *tg = &csid->testgen;
+	const struct csid_hw_ops *hw_ops = csid->res->hw_ops;
 
 	/* If CSID is linked to CSIPHY, do not allow to enable test generator */
 	if (value && media_pad_remote_pad_first(&csid->pads[MSM_CSID_PAD_SINK]))
@@ -529,7 +975,7 @@
 
 	tg->enabled = !!value;
 
-	return csid->ops->configure_testgen_pattern(csid, value);
+	return csid->res->hw_ops->configure_testgen_pattern(csid, value);
 }
 
 /*
@@ -575,25 +1021,44 @@
 
 	csid->camss = camss;
 	csid->id = id;
-	csid->ops = res->ops;
+	csid->res = &res->csid;
 
-	csid->ops->subdev_init(csid);
+	if (dev_WARN_ONCE(dev, !csid->res->parent_dev_ops,
+			  "Error: CSID depends on VFE/IFE device ops!\n")) {
+		return -EINVAL;
+	}
 
-	/* Memory */
+	csid->res->hw_ops->subdev_init(csid);
 
+	/* Memory */
 	if (camss->res->version == CAMSS_8250) {
 		/* for titan 480, CSID registers are inside the VFE region,
 		 * between the VFE "top" and "bus" registers. this requires
 		 * VFE to be initialized before CSID
 		 */
 		if (id >= 2) /* VFE/CSID lite */
-			csid->base = camss->vfe[id].base + VFE_480_LITE_CSID_OFFSET;
+			csid->base = csid->res->parent_dev_ops->get_base_address(camss, id)
+				+ VFE_480_LITE_CSID_OFFSET;
 		else
-			csid->base = camss->vfe[id].base + VFE_480_CSID_OFFSET;
+			csid->base = csid->res->parent_dev_ops->get_base_address(camss, id)
+				 + VFE_480_CSID_OFFSET;
 	} else {
 		csid->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]);
 		if (IS_ERR(csid->base))
 			return PTR_ERR(csid->base);
+
+		/* CSID "top" is a new function in new version HW,
+		 * CSID can connect to VFE & SFE(Sensor Front End).
+		 * this connection is controlled by CSID "top" registers.
+		 * There is only one CSID "top" region for all CSIDs.
+		 */
+		if (!csid_is_lite(csid) && res->reg[1] && !camss->csid_top_base) {
+			camss->csid_top_base =
+				devm_platform_ioremap_resource_byname(pdev, res->reg[1]);
+
+			if (IS_ERR(camss->csid_top_base))
+				return PTR_ERR(camss->csid_top_base);
+		}
 	}
 
 	/* Interrupt */
@@ -605,7 +1070,7 @@
 	csid->irq = ret;
 	snprintf(csid->irq_name, sizeof(csid->irq_name), "%s_%s%d",
 		 dev_name(dev), MSM_CSID_NAME, csid->id);
-	ret = devm_request_irq(dev, csid->irq, csid->ops->isr,
+	ret = devm_request_irq(dev, csid->irq, csid->res->hw_ops->isr,
 			       IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN,
 			       csid->irq_name, csid);
 	if (ret < 0) {
@@ -695,6 +1160,23 @@
 }
 
 /*
+ * csid_get_csiphy_tpg_lane_assign - Calculate lane assign by tpg lane num
+ * @num - tpg lane num
+ *
+ * Return lane assign
+ */
+static u32 csid_get_csiphy_tpg_lane_assign(int num)
+{
+	u32 lane_assign = 0;
+	int i;
+
+	for (i = (num - 1); i >= 0; i--)
+		lane_assign |= i << (i * 4);
+
+	return lane_assign;
+}
+
+/*
  * csid_get_lane_assign - Calculate CSI2 lane assign configuration parameter
  * @lane_cfg - CSI2 lane configuration
  *
@@ -734,28 +1216,37 @@
 		struct csid_device *csid;
 		struct csiphy_device *csiphy;
 		struct csiphy_lanes_cfg *lane_cfg;
+		struct tpg_device *tpg;
 
 		sd = media_entity_to_v4l2_subdev(entity);
 		csid = v4l2_get_subdevdata(sd);
 
 		/* If test generator is enabled */
 		/* do not allow a link from CSIPHY to CSID */
-		if (csid->testgen_mode->cur.val != 0)
+		if (csid->testgen_mode && csid->testgen_mode->cur.val != 0)
 			return -EBUSY;
 
 		sd = media_entity_to_v4l2_subdev(remote->entity);
-		csiphy = v4l2_get_subdevdata(sd);
+		if (strnstr(sd->name, MSM_TPG_NAME, strlen(MSM_TPG_NAME))) {
+			tpg = v4l2_get_subdevdata(sd);
+
+			csid->phy.lane_cnt = tpg->res->lane_cnt;
+			csid->phy.csiphy_id = tpg->id;
+			csid->phy.lane_assign = csid_get_csiphy_tpg_lane_assign(csid->phy.lane_cnt);
+		} else {
+			csiphy = v4l2_get_subdevdata(sd);
 
-		/* If a sensor is not linked to CSIPHY */
-		/* do no allow a link from CSIPHY to CSID */
-		if (!csiphy->cfg.csi2)
-			return -EPERM;
-
-		csid->phy.csiphy_id = csiphy->id;
-
-		lane_cfg = &csiphy->cfg.csi2->lane_cfg;
-		csid->phy.lane_cnt = lane_cfg->num_data;
-		csid->phy.lane_assign = csid_get_lane_assign(lane_cfg);
+			/* If a sensor is not linked to CSIPHY */
+			/* do no allow a link from CSIPHY to CSID */
+			if (!csiphy->cfg.csi2)
+				return -EPERM;
+
+			csid->phy.csiphy_id = csiphy->id;
+
+			lane_cfg = &csiphy->cfg.csi2->lane_cfg;
+			csid->phy.lane_cnt = lane_cfg->num_data;
+			csid->phy.lane_assign = csid_get_lane_assign(lane_cfg);
+		}
 	}
 	/* Decide which virtual channels to enable based on which source pads are enabled */
 	if (local->flags & MEDIA_PAD_FL_SOURCE) {
@@ -839,15 +1330,16 @@
 		return ret;
 	}
 
-	csid->testgen_mode = v4l2_ctrl_new_std_menu_items(&csid->ctrls,
+	if (csid->res->hw_ops->configure_testgen_pattern) {
+		csid->testgen_mode = v4l2_ctrl_new_std_menu_items(&csid->ctrls,
 				&csid_ctrl_ops, V4L2_CID_TEST_PATTERN,
 				csid->testgen.nmodes, 0, 0,
 				csid->testgen.modes);
-
-	if (csid->ctrls.error) {
-		dev_err(dev, "Failed to init ctrl: %d\n", csid->ctrls.error);
-		ret = csid->ctrls.error;
-		goto free_ctrl;
+		if (csid->ctrls.error) {
+			dev_err(dev, "Failed to init ctrl: %d\n", csid->ctrls.error);
+			ret = csid->ctrls.error;
+			goto free_ctrl;
+		}
 	}
 
 	csid->subdev.ctrl_handler = &csid->ctrls;
@@ -899,5 +1391,5 @@
 
 inline bool csid_is_lite(struct csid_device *csid)
 {
-	return csid->camss->res->csid_res[csid->id].is_lite;
+	return csid->camss->res->csid_res[csid->id].csid.is_lite;
 }
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-csid.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-csid.h
@@ -67,7 +67,7 @@
 	CSID_PAYLOAD_MODE_NUM_SUPPORTED_GEN2 = 9, /* excluding disabled */
 };
 
-struct csid_format {
+struct csid_format_info {
 	u32 code;
 	u8 data_type;
 	u8 decode_format;
@@ -75,6 +75,11 @@
 	u8 spp; /* bus samples per pixel */
 };
 
+struct csid_formats {
+	unsigned int nformats;
+	const struct csid_format_info *formats;
+};
+
 struct csid_testgen_config {
 	enum csid_testgen_mode mode;
 	const char * const*modes;
@@ -147,6 +152,21 @@
 	 * @csid: CSID device
 	 */
 	void (*subdev_init)(struct csid_device *csid);
+
+	/*
+	 * reg_update - receive message from other sub device
+	 * @csid: CSID device
+	 * @port_id: Port id
+	 * @is_clear: Indicate if it is clearing reg update or setting reg update
+	 */
+	void (*reg_update)(struct csid_device *csid, int port_id, bool is_clear);
+};
+
+struct csid_subdev_resources {
+	bool is_lite;
+	const struct csid_hw_ops *hw_ops;
+	const struct parent_dev_ops *parent_dev_ops;
+	const struct csid_formats *formats;
 };
 
 struct csid_device {
@@ -156,8 +176,8 @@
 	struct media_pad pads[MSM_CSID_PADS_NUM];
 	void __iomem *base;
 	u32 irq;
+	u32 reg_update;
 	char irq_name[30];
-	struct camss_clock *clock;
 	int nclocks;
 	struct regulator_bulk_data *supplies;
 	int num_supplies;
@@ -167,9 +187,8 @@
 	struct v4l2_mbus_framefmt fmt[MSM_CSID_PADS_NUM];
 	struct v4l2_ctrl_handler ctrls;
 	struct v4l2_ctrl *testgen_mode;
-	const struct csid_format *formats;
-	unsigned int nformats;
-	const struct csid_hw_ops *ops;
+	const struct csid_subdev_resources *res;
+	struct camss_clock *clock;
 };
 
 struct camss_subdev_resources;
@@ -188,16 +207,16 @@
 		   unsigned int match_format_idx, u32 match_code);
 
 /*
- * csid_get_fmt_entry - Find csid_format entry with matching format code
- * @formats: Array of format csid_format entries
+ * csid_get_fmt_entry - Find csid_format_info entry with matching format code
+ * @formats: Array of format csid_format_info entries
  * @nformats: Length of @nformats array
  * @code: Desired format code
  *
  * Return formats[0] on failure to find code
  */
-const struct csid_format *csid_get_fmt_entry(const struct csid_format *formats,
-					     unsigned int nformats,
-					     u32 code);
+const struct csid_format_info *csid_get_fmt_entry(const struct csid_format_info *formats,
+						  unsigned int nformats,
+						  u32 code);
 
 int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
 			 const struct camss_subdev_resources *res, u8 id);
@@ -211,9 +230,14 @@
 
 extern const char * const csid_testgen_modes[];
 
+extern const struct csid_formats csid_formats_4_1;
+extern const struct csid_formats csid_formats_4_7;
+extern const struct csid_formats csid_formats_gen2;
+
 extern const struct csid_hw_ops csid_ops_4_1;
 extern const struct csid_hw_ops csid_ops_4_7;
 extern const struct csid_hw_ops csid_ops_gen2;
+extern const struct csid_hw_ops csid_ops_gen3;
 
 /*
  * csid_is_lite - Check if CSID is CSID lite.
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
@@ -148,6 +148,91 @@
 	},
 };
 
+/* GEN2 1.1 2PH */
+static const struct
+csiphy_reg_t lane_regs_sc8280xp[5][14] = {
+	{
+		{0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0034, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x001C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x003C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0000, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0008, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x000C, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0060, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0064, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+	},
+	{
+		{0x0704, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0734, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x071C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0714, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0728, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x073C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0700, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0708, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x070C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0710, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0760, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0764, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+	},
+	{
+		{0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0234, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x021C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x023C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0200, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0208, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x020C, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0210, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0260, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0264, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+	},
+	{
+		{0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0434, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x041C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0428, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x043C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0400, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0408, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x040C, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0460, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0464, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+	},
+	{
+		{0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0634, 0x0F, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x061C, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0628, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x063C, 0xB8, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0600, 0x90, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0608, 0x0E, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
+		{0x060C, 0x00, 0x00, CSIPHY_DNP_PARAMS},
+		{0x0610, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0660, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
+		{0x0664, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
+	},
+};
+
 /* GEN2 1.2.1 2PH */
 static const struct
 csiphy_reg_t lane_regs_sm8250[5][20] = {
@@ -420,14 +505,22 @@
 	u32 val;
 
 	switch (csiphy->camss->res->version) {
-	case CAMSS_845:
-		r = &lane_regs_sdm845[0][0];
-		array_size = ARRAY_SIZE(lane_regs_sdm845[0]);
+	case CAMSS_7280:
+		r = &lane_regs_sm8250[0][0];
+		array_size = ARRAY_SIZE(lane_regs_sm8250[0]);
 		break;
 	case CAMSS_8250:
 		r = &lane_regs_sm8250[0][0];
 		array_size = ARRAY_SIZE(lane_regs_sm8250[0]);
 		break;
+	case CAMSS_8280XP:
+		r = &lane_regs_sc8280xp[0][0];
+		array_size = ARRAY_SIZE(lane_regs_sc8280xp[0]);
+		break;
+	case CAMSS_845:
+		r = &lane_regs_sdm845[0][0];
+		array_size = ARRAY_SIZE(lane_regs_sdm845[0]);
+		break;
 	default:
 		WARN(1, "unknown cspi version\n");
 		return;
@@ -463,13 +556,27 @@
 	return lane_mask;
 }
 
+static bool csiphy_is_gen2(u32 version)
+{
+	bool ret = false;
+
+	switch (version) {
+	case CAMSS_7280:
+	case CAMSS_8250:
+	case CAMSS_8280XP:
+	case CAMSS_845:
+		ret = true;
+		break;
+	}
+
+	return ret;
+}
+
 static void csiphy_lanes_enable(struct csiphy_device *csiphy,
 				struct csiphy_config *cfg,
 				s64 link_freq, u8 lane_mask)
 {
 	struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg;
-	bool is_gen2 = (csiphy->camss->res->version == CAMSS_845 ||
-			csiphy->camss->res->version == CAMSS_8250);
 	u8 settle_cnt;
 	u8 val;
 	int i;
@@ -491,7 +598,7 @@
 	val = 0x00;
 	writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(0));
 
-	if (is_gen2)
+	if (csiphy_is_gen2(csiphy->camss->res->version))
 		csiphy_gen2_config_lanes(csiphy, settle_cnt);
 	else
 		csiphy_gen1_config_lanes(csiphy, cfg, settle_cnt);
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -24,12 +24,7 @@
 
 #define MSM_CSIPHY_NAME "msm_csiphy"
 
-struct csiphy_format {
-	u32 code;
-	u8 bpp;
-};
-
-static const struct csiphy_format csiphy_formats_8x16[] = {
+static const struct csiphy_format_info formats_8x16[] = {
 	{ MEDIA_BUS_FMT_UYVY8_1X16, 8 },
 	{ MEDIA_BUS_FMT_VYUY8_1X16, 8 },
 	{ MEDIA_BUS_FMT_YUYV8_1X16, 8 },
@@ -49,7 +44,7 @@
 	{ MEDIA_BUS_FMT_Y10_1X10, 10 },
 };
 
-static const struct csiphy_format csiphy_formats_8x96[] = {
+static const struct csiphy_format_info formats_8x96[] = {
 	{ MEDIA_BUS_FMT_UYVY8_1X16, 8 },
 	{ MEDIA_BUS_FMT_VYUY8_1X16, 8 },
 	{ MEDIA_BUS_FMT_YUYV8_1X16, 8 },
@@ -73,7 +68,7 @@
 	{ MEDIA_BUS_FMT_Y10_1X10, 10 },
 };
 
-static const struct csiphy_format csiphy_formats_sdm845[] = {
+static const struct csiphy_format_info formats_sdm845[] = {
 	{ MEDIA_BUS_FMT_UYVY8_1X16, 8 },
 	{ MEDIA_BUS_FMT_VYUY8_1X16, 8 },
 	{ MEDIA_BUS_FMT_YUYV8_1X16, 8 },
@@ -98,6 +93,31 @@
 	{ MEDIA_BUS_FMT_Y10_1X10, 10 },
 };
 
+const struct csiphy_formats csiphy_formats_8x16 = {
+	.nformats = ARRAY_SIZE(formats_8x16),
+	.formats = formats_8x16
+};
+
+const struct csiphy_formats csiphy_formats_8x96 = {
+	.nformats = ARRAY_SIZE(formats_8x96),
+	.formats = formats_8x96
+};
+
+const struct csiphy_formats csiphy_formats_sa8775p = {
+	.nformats = ARRAY_SIZE(formats_sdm845),
+	.formats = formats_sdm845
+};
+
+const struct csiphy_formats csiphy_formats_sdm845 = {
+	.nformats = ARRAY_SIZE(formats_sdm845),
+	.formats = formats_sdm845
+};
+
+const struct csiphy_formats csiphy_formats_sc7280 = {
+	.nformats = ARRAY_SIZE(formats_sdm845),
+	.formats = formats_sdm845
+};
+
 /*
  * csiphy_get_bpp - map media bus format to bits per pixel
  * @formats: supported media bus formats array
@@ -106,7 +126,7 @@
  *
  * Return number of bits per pixel
  */
-static u8 csiphy_get_bpp(const struct csiphy_format *formats,
+static u8 csiphy_get_bpp(const struct csiphy_format_info *formats,
 			 unsigned int nformats, u32 code)
 {
 	unsigned int i;
@@ -131,7 +151,7 @@
 	int i, j;
 	int ret;
 
-	u8 bpp = csiphy_get_bpp(csiphy->formats, csiphy->nformats,
+	u8 bpp = csiphy_get_bpp(csiphy->res->formats->formats, csiphy->res->formats->nformats,
 				csiphy->fmt[MSM_CSIPHY_PAD_SINK].code);
 	u8 num_lanes = csiphy->cfg.csi2->lane_cfg.num_data;
 
@@ -216,9 +236,9 @@
 
 		enable_irq(csiphy->irq);
 
-		csiphy->ops->reset(csiphy);
+		csiphy->res->hw_ops->reset(csiphy);
 
-		csiphy->ops->hw_version_read(csiphy, dev);
+		csiphy->res->hw_ops->hw_version_read(csiphy, dev);
 	} else {
 		disable_irq(csiphy->irq);
 
@@ -243,8 +263,8 @@
 {
 	struct csiphy_config *cfg = &csiphy->cfg;
 	s64 link_freq;
-	u8 lane_mask = csiphy->ops->get_lane_mask(&cfg->csi2->lane_cfg);
-	u8 bpp = csiphy_get_bpp(csiphy->formats, csiphy->nformats,
+	u8 lane_mask = csiphy->res->hw_ops->get_lane_mask(&cfg->csi2->lane_cfg);
+	u8 bpp = csiphy_get_bpp(csiphy->res->formats->formats, csiphy->res->formats->nformats,
 				csiphy->fmt[MSM_CSIPHY_PAD_SINK].code);
 	u8 num_lanes = csiphy->cfg.csi2->lane_cfg.num_data;
 	u8 val;
@@ -272,7 +292,7 @@
 		wmb();
 	}
 
-	csiphy->ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
+	csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask);
 
 	return 0;
 }
@@ -285,7 +305,7 @@
  */
 static void csiphy_stream_off(struct csiphy_device *csiphy)
 {
-	csiphy->ops->lanes_disable(csiphy, &csiphy->cfg);
+	csiphy->res->hw_ops->lanes_disable(csiphy, &csiphy->cfg);
 }
 
 
@@ -350,12 +370,12 @@
 	case MSM_CSIPHY_PAD_SINK:
 		/* Set format on sink pad */
 
-		for (i = 0; i < csiphy->nformats; i++)
-			if (fmt->code == csiphy->formats[i].code)
+		for (i = 0; i < csiphy->res->formats->nformats; i++)
+			if (fmt->code == csiphy->res->formats->formats[i].code)
 				break;
 
 		/* If not found, use UYVY as default */
-		if (i >= csiphy->nformats)
+		if (i >= csiphy->res->formats->nformats)
 			fmt->code = MEDIA_BUS_FMT_UYVY8_1X16;
 
 		fmt->width = clamp_t(u32, fmt->width, 1, 8191);
@@ -392,10 +412,10 @@
 	struct v4l2_mbus_framefmt *format;
 
 	if (code->pad == MSM_CSIPHY_PAD_SINK) {
-		if (code->index >= csiphy->nformats)
+		if (code->index >= csiphy->res->formats->nformats)
 			return -EINVAL;
 
-		code->code = csiphy->formats[code->index].code;
+		code->code = csiphy->res->formats->formats[code->index].code;
 	} else {
 		if (code->index > 0)
 			return -EINVAL;
@@ -564,24 +584,7 @@
 	csiphy->camss = camss;
 	csiphy->id = id;
 	csiphy->cfg.combo_mode = 0;
-	csiphy->ops = res->ops;
-
-	switch (camss->res->version) {
-	case CAMSS_8x16:
-		csiphy->formats = csiphy_formats_8x16;
-		csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x16);
-		break;
-	case CAMSS_8x96:
-	case CAMSS_660:
-		csiphy->formats = csiphy_formats_8x96;
-		csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x96);
-		break;
-	case CAMSS_845:
-	case CAMSS_8250:
-		csiphy->formats = csiphy_formats_sdm845;
-		csiphy->nformats = ARRAY_SIZE(csiphy_formats_sdm845);
-		break;
-	}
+	csiphy->res = &res->csiphy;
 
 	/* Memory */
 
@@ -609,7 +612,7 @@
 	snprintf(csiphy->irq_name, sizeof(csiphy->irq_name), "%s_%s%d",
 		 dev_name(dev), MSM_CSIPHY_NAME, csiphy->id);
 
-	ret = devm_request_irq(dev, csiphy->irq, csiphy->ops->isr,
+	ret = devm_request_irq(dev, csiphy->irq, csiphy->res->hw_ops->isr,
 			       IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN,
 			       csiphy->irq_name, csiphy);
 	if (ret < 0) {
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-csiphy.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-csiphy.h
@@ -42,6 +42,16 @@
 	struct csiphy_csi2_cfg *csi2;
 };
 
+struct csiphy_format_info {
+	u32 code;
+	u8 bpp;
+};
+
+struct csiphy_formats {
+	unsigned int nformats;
+	const struct csiphy_format_info *formats;
+};
+
 struct csiphy_device;
 
 struct csiphy_hw_ops {
@@ -63,6 +73,11 @@
 	irqreturn_t (*isr)(int irq, void *dev);
 };
 
+struct csiphy_subdev_resources {
+	const struct csiphy_hw_ops *hw_ops;
+	const struct csiphy_formats *formats;
+};
+
 struct csiphy_device {
 	struct camss *camss;
 	u8 id;
@@ -78,9 +93,7 @@
 	u32 timer_clk_rate;
 	struct csiphy_config cfg;
 	struct v4l2_mbus_framefmt fmt[MSM_CSIPHY_PADS_NUM];
-	const struct csiphy_hw_ops *ops;
-	const struct csiphy_format *formats;
-	unsigned int nformats;
+	const struct csiphy_subdev_resources *res;
 };
 
 struct camss_subdev_resources;
@@ -94,6 +107,12 @@
 
 void msm_csiphy_unregister_entity(struct csiphy_device *csiphy);
 
+extern const struct csiphy_formats csiphy_formats_8x16;
+extern const struct csiphy_formats csiphy_formats_8x96;
+extern const struct csiphy_formats csiphy_formats_sa8775p;
+extern const struct csiphy_formats csiphy_formats_sdm845;
+extern const struct csiphy_formats csiphy_formats_sc7280;
+
 extern const struct csiphy_hw_ops csiphy_ops_2ph_1_0;
 extern const struct csiphy_hw_ops csiphy_ops_3ph_1_0;
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-format.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-format.c
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-format.c
+ *
+ * Qualcomm MSM Camera Subsystem - Format helpers
+ *
+ * Copyright (c) 2023, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Technologies, Inc.
+ */
+#include <linux/bug.h>
+#include <linux/errno.h>
+
+#include "camss-format.h"
+
+/*
+ * camss_format_get_bpp - Map media bus format to bits per pixel
+ * @formats: supported media bus formats array
+ * @nformats: size of @formats array
+ * @code: media bus format code
+ *
+ * Return number of bits per pixel
+ */
+u8 camss_format_get_bpp(const struct camss_format_info *formats, unsigned int nformats, u32 code)
+{
+	unsigned int i;
+
+	for (i = 0; i < nformats; i++)
+		if (code == formats[i].code)
+			return formats[i].mbus_bpp;
+
+	WARN(1, "Unknown format\n");
+
+	return formats[0].mbus_bpp;
+}
+
+/*
+ * camss_format_find_code - Find a format code in an array
+ * @code: a pointer to media bus format codes array
+ * @n_code: size of @code array
+ * @index: index of code in the array
+ * @req_code: required code
+ *
+ * Return media bus format code
+ */
+u32 camss_format_find_code(u32 *code, unsigned int n_code, unsigned int index, u32 req_code)
+{
+	unsigned int i;
+
+	if (!req_code && index >= n_code)
+		return 0;
+
+	for (i = 0; i < n_code; i++) {
+		if (req_code) {
+			if (req_code == code[i])
+				return req_code;
+		} else {
+			if (i == index)
+				return code[i];
+		}
+	}
+
+	return code[0];
+}
+
+/*
+ * camss_format_find_format - Find a format in an array
+ * @code: media bus format code
+ * @pixelformat: V4L2 pixel format FCC identifier
+ * @formats: a pointer to formats array
+ * @nformats: size of @formats array
+ *
+ * Return index of a format or a negative error code otherwise
+ */
+int camss_format_find_format(u32 code, u32 pixelformat, const struct camss_format_info *formats,
+			     unsigned int nformats)
+{
+	unsigned int i;
+
+	for (i = 0; i < nformats; i++) {
+		if (formats[i].code == code &&
+		    formats[i].pixelformat == pixelformat)
+			return i;
+	}
+
+	for (i = 0; i < nformats; i++) {
+		if (formats[i].code == code)
+			return i;
+	}
+
+	return -EINVAL;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-format.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-format.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * camss-format.h
+ *
+ * Qualcomm MSM Camera Subsystem - Format helpers
+ *
+ * Copyright (c) 2023, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Technologies, Inc.
+ */
+#ifndef __CAMSS_FORMAT_H__
+#define __CAMSS_FORMAT_H__
+
+#include <linux/types.h>
+
+#define PER_PLANE_DATA(plane, h_fract_num, h_fract_den, v_fract_num, v_fract_den, _bpp)         \
+	.hsub[(plane)].numerator	= (h_fract_num),                                        \
+	.hsub[(plane)].denominator	= (h_fract_den),                                        \
+	.vsub[(plane)].numerator	= (v_fract_num),                                        \
+	.vsub[(plane)].denominator	= (v_fract_den),                                        \
+	.bpp[(plane)]			= (_bpp)
+
+/*
+ * struct fract - Represents a fraction
+ * @numerator: Store the numerator part of the fraction
+ * @denominator: Store the denominator part of the fraction
+ */
+struct fract {
+	u8 numerator;
+	u8 denominator;
+};
+
+/*
+ * struct camss_format_info - ISP media bus format information
+ * @code: V4L2 media bus format code
+ * @mbus_bpp: Media bus bits per pixel
+ * @pixelformat: V4L2 pixel format FCC identifier
+ * @planes: Number of planes
+ * @hsub: Horizontal subsampling (for each plane)
+ * @vsub: Vertical subsampling (for each plane)
+ * @bpp: Bits per pixel when stored in memory (for each plane)
+ */
+struct camss_format_info {
+	u32 code;
+	u32 mbus_bpp;
+	u32 pixelformat;
+	u8 planes;
+	struct fract hsub[3];
+	struct fract vsub[3];
+	unsigned int bpp[3];
+};
+
+struct camss_formats {
+	unsigned int nformats;
+	const struct camss_format_info *formats;
+};
+
+u8 camss_format_get_bpp(const struct camss_format_info *formats, unsigned int nformats, u32 code);
+u32 camss_format_find_code(u32 *code, unsigned int n_code, unsigned int index, u32 req_code);
+int camss_format_find_format(u32 code, u32 pixelformat, const struct camss_format_info *formats,
+			     unsigned int nformats);
+
+#endif /* __CAMSS_FORMAT_H__ */
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-tpg-gen1.c
@@ -0,0 +1,245 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-tpg-gen1.c
+ *
+ * Qualcomm MSM Camera Subsystem - TPG (Test Patter Generator) Module
+ *
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+
+#include "camss-tpg.h"
+#include "camss.h"
+
+#define TPG_HW_VERSION		0x0
+#define		HW_VERSION_STEPPING		0
+#define		HW_VERSION_REVISION		16
+#define		HW_VERSION_GENERATION		28
+
+#define TPG_HW_STATUS		0x4
+
+#define TPG_VC_n_GAIN_CFG(n)	(0x60 + (n) * 0x60)
+
+#define TPG_CTRL	0x64
+#define		TPG_CTRL_TEST_EN		0
+#define		TPG_CTRL_PHY_SEL		3
+#define		TPG_CTRL_NUM_ACTIVE_LANES	4
+#define		TPG_CTRL_VC_DT_PATTERN_ID	6
+#define		TPG_CTRL_OVERLAP_SHDR_EN	10
+#define		TPG_CTRL_NUM_ACTIVE_VC		30
+#define			NUM_ACTIVE_VC_0_ENABLED		0
+#define			NUM_ACTIVE_VC_0_1_ENABLED	1
+#define			NUM_ACTIVE_VC_0_1_2_ENABLED	2
+#define			NUM_ACTIVE_VC_0_1_3_ENABLED	3
+
+#define TPG_VC_n_CFG0(n)	(0x68 + (n) * 0x60)
+#define		TPG_VC_n_CFG0_VC_NUM		0
+#define		TPG_VC_n_CFG0_NUM_ACTIVE_DT	8
+#define			NUM_ACTIVE_SLOTS_0_ENABLED		0
+#define			NUM_ACTIVE_SLOTS_0_1_ENABLED		1
+#define			NUM_ACTIVE_SLOTS_0_1_2_ENABLED		2
+#define			NUM_ACTIVE_SLOTS_0_1_3_ENABLED		3
+#define		TPG_VC_n_CFG0_NUM_BATCH		12
+#define		TPG_VC_n_CFG0_NUM_FRAMES	16
+
+#define TPG_VC_n_LSFR_SEED(n)		(0x6C + (n) * 0x60)
+
+#define TPG_VC_n_HBI_CFG(n)		(0x70 + (n) * 0x60)
+
+#define TPG_VC_n_VBI_CFG(n)		(0x74 + (n) * 0x60)
+
+#define TPG_VC_n_COLOR_BARS_CFG(n)		(0x78 + (n) * 0x60)
+#define		TPG_VC_n_COLOR_BARS_CFG_PIX_PATTERN		0
+#define		TPG_VC_n_COLOR_BARS_CFG_QCFA_EN			3
+#define		TPG_VC_n_COLOR_BARS_CFG_SPLIT_EN		4
+#define		TPG_VC_n_COLOR_BARS_CFG_NOISE_EN		5
+#define		TPG_VC_n_COLOR_BARS_CFG_ROTATE_PERIOD		8
+#define		TPG_VC_n_COLOR_BARS_CFG_XCFA_EN			16
+#define		TPG_VC_n_COLOR_BARS_CFG_SIZE_X			24
+#define		TPG_VC_n_COLOR_BARS_CFG_SIZE_Y			28
+
+#define TPG_VC_m_DT_n_CFG_0(m, n)	(0x7C + (m) * 0x60 + (n) * 0xC)
+#define		TPG_VC_m_DT_n_CFG_0_FRAME_HEIGHT	0
+#define		TPG_VC_m_DT_n_CFG_0_FRAME_WIDTH		16
+
+#define TPG_VC_m_DT_n_CFG_1(m, n)	(0x80 + (m) * 0x60 + (n) * 0xC)
+#define		TPG_VC_m_DT_n_CFG_1_DATA_TYPE		0
+#define		TPG_VC_m_DT_n_CFG_1_ECC_XOR_MASK	8
+#define		TPG_VC_m_DT_n_CFG_1_CRC_XOR_MASK	16
+
+#define TPG_VC_m_DT_n_CFG_2(m, n)	(0x84 + (m) * 0x60 + (n) * 0xC)
+#define		TPG_VC_m_DT_n_CFG_2_PAYLOAD_MODE		0
+#define		TPG_VC_m_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD	4
+#define		TPG_VC_m_DT_n_CFG_2_ENCODE_FORMAT		28
+
+#define TPG_VC_n_COLOR_BAR_CFA_COLOR0(n)	(0xB0 + (n) * 0x60)
+#define TPG_VC_n_COLOR_BAR_CFA_COLOR1(n)	(0xB4 + (n) * 0x60)
+#define TPG_VC_n_COLOR_BAR_CFA_COLOR2(n)	(0xB8 + (n) * 0x60)
+#define TPG_VC_n_COLOR_BAR_CFA_COLOR3(n)	(0xBC + (n) * 0x60)
+
+/* Line offset between VC(n) and VC(n-1), n form 1 to 3 */
+#define TPG_VC_n_SHDR_CFG	(0x84 + (n) * 0x60)
+
+#define TPG_TOP_IRQ_STATUS	0x1E0
+#define TPG_TOP_IRQ_MASK	0x1E4
+#define TPG_TOP_IRQ_CLEAR	0x1E8
+#define TPG_TOP_IRQ_SET		0x1EC
+#define TPG_IRQ_CMD		0x1F0
+#define TPG_CLEAR		0x1F4
+
+static int tpg_stream_on(struct tpg_device *tpg)
+{
+	struct tpg_testgen_config *tg = &tpg->testgen;
+	struct v4l2_mbus_framefmt *input_format;
+	const struct tpg_format_info *format;
+	u8 lane_cnt = tpg->res->lane_cnt;
+	u8 i;
+	u8 dt_cnt = 0;
+	u32 val;
+
+	/* Loop through all enabled VCs and configure stream for each */
+	for (i = 0; i < tpg->res->vc_cnt; i++) {
+		input_format = &tpg->fmt[MSM_TPG_PAD_SRC + i];
+		format = tpg_get_fmt_entry(tpg->res->formats->formats,
+					   tpg->res->formats->nformats,
+					   input_format->code);
+
+		val = (input_format->height & 0xffff) << TPG_VC_m_DT_n_CFG_0_FRAME_HEIGHT;
+		val |= (input_format->width & 0xffff) << TPG_VC_m_DT_n_CFG_0_FRAME_WIDTH;
+		writel_relaxed(val, tpg->base + TPG_VC_m_DT_n_CFG_0(i, dt_cnt));
+
+		val = format->data_type << TPG_VC_m_DT_n_CFG_1_DATA_TYPE;
+		writel_relaxed(val, tpg->base + TPG_VC_m_DT_n_CFG_1(i, dt_cnt));
+
+		val = (tg->mode - 1) << TPG_VC_m_DT_n_CFG_2_PAYLOAD_MODE;
+		val |= 0xBE << TPG_VC_m_DT_n_CFG_2_USER_SPECIFIED_PAYLOAD;
+		val |= format->encode_format << TPG_VC_m_DT_n_CFG_2_ENCODE_FORMAT;
+		writel_relaxed(val, tpg->base + TPG_VC_m_DT_n_CFG_2(i, dt_cnt));
+
+		writel_relaxed(0xA00, tpg->base + TPG_VC_n_COLOR_BARS_CFG(i));
+
+		writel_relaxed(0x4701, tpg->base + TPG_VC_n_HBI_CFG(i));
+		writel_relaxed(0x438, tpg->base + TPG_VC_n_VBI_CFG(i));
+
+		writel_relaxed(0x12345678, tpg->base + TPG_VC_n_LSFR_SEED(i));
+
+		/* configure one DT, infinite frames */
+		val = i << TPG_VC_n_CFG0_VC_NUM;
+		val |= 0 << TPG_VC_n_CFG0_NUM_FRAMES;
+		writel_relaxed(val, tpg->base + TPG_VC_n_CFG0(i));
+	}
+
+	writel_relaxed(1, tpg->base + TPG_TOP_IRQ_MASK);
+
+	val = 1 << TPG_CTRL_TEST_EN;
+	val |= 0 << TPG_CTRL_PHY_SEL;
+	val |= (lane_cnt - 1) << TPG_CTRL_NUM_ACTIVE_LANES;
+	val |= 0 << TPG_CTRL_VC_DT_PATTERN_ID;
+	val |= (tpg->res->vc_cnt - 1) << TPG_CTRL_NUM_ACTIVE_VC;
+	writel_relaxed(val, tpg->base + TPG_CTRL);
+
+	return 0;
+}
+
+static void tpg_stream_off(struct tpg_device *tpg)
+{
+	writel_relaxed(0, tpg->base + TPG_CTRL);
+	writel_relaxed(0, tpg->base + TPG_TOP_IRQ_MASK);
+	writel_relaxed(1, tpg->base + TPG_TOP_IRQ_CLEAR);
+	writel_relaxed(1, tpg->base + TPG_IRQ_CMD);
+	writel_relaxed(1, tpg->base + TPG_CLEAR);
+}
+
+static void tpg_configure_stream(struct tpg_device *tpg, u8 enable)
+{
+	if (enable)
+		tpg_stream_on(tpg);
+	else
+		tpg_stream_off(tpg);
+}
+
+static int tpg_configure_testgen_pattern(struct tpg_device *tpg, s32 val)
+{
+	if (val > 0 && val <= TPG_PAYLOAD_MODE_COLOR_BARS)
+		tpg->testgen.mode = val;
+
+	return 0;
+}
+
+/*
+ * tpg_hw_version - tpg hardware version query
+ * @tpg: tpg device
+ *
+ * Return HW version or error
+ */
+static u32 tpg_hw_version(struct tpg_device *tpg)
+{
+	u32 hw_version;
+	u32 hw_gen;
+	u32 hw_rev;
+	u32 hw_step;
+
+	hw_version = readl_relaxed(tpg->base + TPG_HW_VERSION);
+	hw_gen = (hw_version >> HW_VERSION_GENERATION) & 0xF;
+	hw_rev = (hw_version >> HW_VERSION_REVISION) & 0xFFF;
+	hw_step = (hw_version >> HW_VERSION_STEPPING) & 0xFFFF;
+	dev_dbg(tpg->camss->dev, "tpg HW Version = %u.%u.%u\n",
+		hw_gen, hw_rev, hw_step);
+
+	return hw_version;
+}
+
+/*
+ * tpg_isr - tpg module interrupt service routine
+ * @irq: Interrupt line
+ * @dev: tpg device
+ *
+ * Return IRQ_HANDLED on success
+ */
+static irqreturn_t tpg_isr(int irq, void *dev)
+{
+	struct tpg_device *tpg = dev;
+	u32 val;
+
+	val = readl_relaxed(tpg->base + TPG_TOP_IRQ_STATUS);
+	writel_relaxed(val, tpg->base + TPG_TOP_IRQ_CLEAR);
+	writel_relaxed(1, tpg->base + TPG_IRQ_CMD);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * tpg_reset - Trigger reset on tpg module and wait to complete
+ * @tpg: tpg device
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int tpg_reset(struct tpg_device *tpg)
+{
+	writel_relaxed(0, tpg->base + TPG_CTRL);
+	writel_relaxed(0, tpg->base + TPG_TOP_IRQ_MASK);
+	writel_relaxed(1, tpg->base + TPG_TOP_IRQ_CLEAR);
+	writel_relaxed(1, tpg->base + TPG_IRQ_CMD);
+	writel_relaxed(1, tpg->base + TPG_CLEAR);
+
+	return 0;
+}
+
+static void tpg_subdev_init(struct tpg_device *tpg)
+{
+	tpg->testgen.modes = testgen_payload_modes;
+	tpg->testgen.nmodes = TPG_PAYLOAD_MODE_DISABLED;
+}
+
+const struct tpg_hw_ops tpg_ops_gen1 = {
+	.configure_stream = tpg_configure_stream,
+	.configure_testgen_pattern = tpg_configure_testgen_pattern,
+	.hw_version = tpg_hw_version,
+	.isr = tpg_isr,
+	.reset = tpg_reset,
+	.subdev_init = tpg_subdev_init,
+};
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-tpg.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-tpg.c
@@ -0,0 +1,738 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-tpg.c
+ *
+ * Qualcomm MSM Camera Subsystem - TPG Module
+ *
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <media/media-entity.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+
+#include "camss-tpg.h"
+#include "camss.h"
+
+const char * const testgen_payload_modes[] = {
+	"Disabled",
+	"Incrementing",
+	"Alternating 0x55/0xAA",
+	NULL,
+	NULL,
+	"Pseudo-random Data",
+	"User Specified",
+	NULL,
+	NULL,
+	"Color bars",
+	NULL
+};
+
+static const struct tpg_format_info formats_gen1[] = {
+	{
+		MEDIA_BUS_FMT_SBGGR8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		ENCODE_FORMAT_UNCOMPRESSED_8_BIT,
+	},
+	{
+		MEDIA_BUS_FMT_SGBRG8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		ENCODE_FORMAT_UNCOMPRESSED_8_BIT,
+	},
+	{
+		MEDIA_BUS_FMT_SGRBG8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		ENCODE_FORMAT_UNCOMPRESSED_8_BIT,
+	},
+	{
+		MEDIA_BUS_FMT_SRGGB8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		ENCODE_FORMAT_UNCOMPRESSED_8_BIT,
+	},
+	{
+		MEDIA_BUS_FMT_SBGGR10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		ENCODE_FORMAT_UNCOMPRESSED_10_BIT,
+	},
+	{
+		MEDIA_BUS_FMT_SGBRG10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		ENCODE_FORMAT_UNCOMPRESSED_10_BIT,
+	},
+	{
+		MEDIA_BUS_FMT_SGRBG10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		ENCODE_FORMAT_UNCOMPRESSED_10_BIT,
+	},
+	{
+		MEDIA_BUS_FMT_SRGGB10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		ENCODE_FORMAT_UNCOMPRESSED_10_BIT,
+	},
+	{
+		MEDIA_BUS_FMT_SBGGR12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		ENCODE_FORMAT_UNCOMPRESSED_12_BIT,
+	},
+	{
+		MEDIA_BUS_FMT_SGBRG12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		ENCODE_FORMAT_UNCOMPRESSED_12_BIT,
+	},
+	{
+		MEDIA_BUS_FMT_SGRBG12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		ENCODE_FORMAT_UNCOMPRESSED_12_BIT,
+	},
+	{
+		MEDIA_BUS_FMT_SRGGB12_1X12,
+		DATA_TYPE_RAW_12BIT,
+		ENCODE_FORMAT_UNCOMPRESSED_12_BIT,
+	},
+	{
+		MEDIA_BUS_FMT_Y8_1X8,
+		DATA_TYPE_RAW_8BIT,
+		ENCODE_FORMAT_UNCOMPRESSED_8_BIT,
+	},
+	{
+		MEDIA_BUS_FMT_Y10_1X10,
+		DATA_TYPE_RAW_10BIT,
+		ENCODE_FORMAT_UNCOMPRESSED_10_BIT,
+	},
+};
+
+const struct tpg_formats tpg_formats_gen1 = {
+	.nformats = ARRAY_SIZE(formats_gen1),
+	.formats = formats_gen1
+};
+
+
+const struct tpg_format_info *tpg_get_fmt_entry(const struct tpg_format_info *formats,
+						unsigned int nformats,
+						u32 code)
+{
+	unsigned int i;
+
+	for (i = 0; i < nformats; i++)
+		if (code == formats[i].code)
+			return &formats[i];
+
+	WARN(1, "Unknown format\n");
+
+	return &formats[0];
+}
+
+/*
+ * tpg_set_clock_rates - Calculate and set clock rates on tpg module
+ * @tpg: tpg device
+ */
+static int tpg_set_clock_rates(struct tpg_device *tpg)
+{
+	struct device *dev = tpg->camss->dev;
+	int i, j;
+	int ret;
+
+	for (i = 0; i < tpg->nclocks; i++) {
+		struct camss_clock *clock = &tpg->clock[i];
+		u64 min_rate = 0;
+		long round_rate;
+
+		camss_add_clock_margin(&min_rate);
+
+		for (j = 0; j < clock->nfreqs; j++)
+			if (min_rate < clock->freq[j])
+				break;
+
+		if (j == clock->nfreqs) {
+			dev_err(dev,
+				"clock is too high for TPG\n");
+			return -EINVAL;
+		}
+
+		/* if clock is not available */
+		/* set highest possible tpg clock rate */
+		if (min_rate == 0)
+			j = clock->nfreqs - 1;
+
+		round_rate = clk_round_rate(clock->clk, clock->freq[j]);
+		if (round_rate < 0) {
+			dev_err(dev, "clk round rate failed: %ld\n",
+				round_rate);
+			return -EINVAL;
+		}
+
+		tpg->timer_clk_rate = round_rate;
+
+		ret = clk_set_rate(clock->clk, tpg->timer_clk_rate);
+		if (ret < 0) {
+			dev_err(dev, "clk set rate failed: %d\n", ret);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * tpg_set_power - Power on/off tpg module
+ * @sd: tpg V4L2 subdevice
+ * @on: Requested power state
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int tpg_set_power(struct v4l2_subdev *sd, int on)
+{
+	struct tpg_device *tpg = v4l2_get_subdevdata(sd);
+	struct device *dev = tpg->camss->dev;
+
+	if (on) {
+		int ret;
+
+		ret = pm_runtime_resume_and_get(dev);
+		if (ret < 0)
+			return ret;
+
+		ret = tpg_set_clock_rates(tpg);
+		if (ret < 0) {
+			pm_runtime_put_sync(dev);
+			return ret;
+		}
+
+		ret = camss_enable_clocks(tpg->nclocks, tpg->clock, dev);
+		if (ret < 0) {
+			pm_runtime_put_sync(dev);
+			return ret;
+		}
+
+		enable_irq(tpg->irq);
+
+		tpg->res->hw_ops->reset(tpg);
+
+		tpg->res->hw_ops->hw_version(tpg);
+	} else {
+		disable_irq(tpg->irq);
+
+		camss_disable_clocks(tpg->nclocks, tpg->clock);
+
+		pm_runtime_put_sync(dev);
+	}
+
+	return 0;
+}
+
+
+/*
+ * tpg_set_stream - Enable/disable streaming on tpg module
+ * @sd: tpg V4L2 subdevice
+ * @enable: Requested streaming state
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int tpg_set_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct tpg_device *tpg = v4l2_get_subdevdata(sd);
+	int ret = 0;
+
+	if (enable) {
+		ret = v4l2_ctrl_handler_setup(&tpg->ctrls);
+		if (ret < 0) {
+			dev_err(tpg->camss->dev,
+				"could not sync v4l2 controls: %d\n", ret);
+			return ret;
+		}
+	}
+
+	tpg->res->hw_ops->configure_stream(tpg, enable);
+
+	return 0;
+}
+
+/*
+ * __tpg_get_format - Get pointer to format structure
+ * @tpg: tpg device
+ * @cfg: V4L2 subdev pad configuration
+ * @pad: pad from which format is requested
+ * @which: TRY or ACTIVE format
+ *
+ * Return pointer to TRY or ACTIVE format structure
+ */
+static struct v4l2_mbus_framefmt *
+__tpg_get_format(struct tpg_device *tpg,
+		 struct v4l2_subdev_state *sd_state,
+		 unsigned int pad,
+		 enum v4l2_subdev_format_whence which)
+{
+	if (which == V4L2_SUBDEV_FORMAT_TRY)
+		return v4l2_subdev_state_get_format(sd_state, pad);
+
+	return &tpg->fmt[pad];
+}
+
+/*
+ * tpg_try_format - Handle try format by pad subdev method
+ * @tpg: tpg device
+ * @cfg: V4L2 subdev pad configuration
+ * @pad: pad on which format is requested
+ * @fmt: pointer to v4l2 format structure
+ * @which: wanted subdev format
+ */
+static void tpg_try_format(struct tpg_device *tpg,
+			   struct v4l2_subdev_state *sd_state,
+			   unsigned int pad,
+			   struct v4l2_mbus_framefmt *fmt,
+			   enum v4l2_subdev_format_whence which)
+{
+	unsigned int i;
+
+	switch (pad) {
+	case MSM_TPG_PAD_SINK:
+		/* Test generator is enabled, set format on source */
+		/* pad to allow test generator usage */
+
+		for (i = 0; i < tpg->res->formats->nformats; i++)
+			if (tpg->res->formats->formats[i].code == fmt->code)
+				break;
+
+		/* If not found, use SBGGR8 as default */
+		if (i >= tpg->res->formats->nformats)
+			fmt->code = MEDIA_BUS_FMT_SBGGR8_1X8;
+
+		fmt->width = clamp_t(u32, fmt->width, 1, 8191);
+		fmt->height = clamp_t(u32, fmt->height, 1, 8191);
+
+		fmt->field = V4L2_FIELD_NONE;
+		fmt->colorspace = V4L2_COLORSPACE_SRGB;
+
+		break;
+	case MSM_TPG_PAD_SRC:
+		/* Set and return a format same as sink pad */
+
+		*fmt = *__tpg_get_format(tpg, sd_state,
+					    MSM_TPG_PAD_SINK,
+					    which);
+
+		break;
+	}
+}
+
+/*
+ * tpg_enum_mbus_code - Handle format enumeration
+ * @sd: tpg V4L2 subdevice
+ * @cfg: V4L2 subdev pad configuration
+ * @code: pointer to v4l2_subdev_mbus_code_enum structure
+ * return -EINVAL or zero on success
+ */
+static int tpg_enum_mbus_code(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_state *sd_state,
+			      struct v4l2_subdev_mbus_code_enum *code)
+{
+	struct tpg_device *tpg = v4l2_get_subdevdata(sd);
+	struct v4l2_mbus_framefmt *format;
+
+	if (code->pad == MSM_TPG_PAD_SINK) {
+		if (code->index >= tpg->res->formats->nformats)
+			return -EINVAL;
+
+		code->code = tpg->res->formats->formats[code->index].code;
+	} else {
+		if (code->index > 0)
+			return -EINVAL;
+
+		format = __tpg_get_format(tpg, sd_state,
+					     MSM_TPG_PAD_SINK,
+					     code->which);
+
+		code->code = format->code;
+	}
+
+	return 0;
+}
+
+/*
+ * tpg_enum_frame_size - Handle frame size enumeration
+ * @sd: tpg V4L2 subdevice
+ * @cfg: V4L2 subdev pad configuration
+ * @fse: pointer to v4l2_subdev_frame_size_enum structure
+ * return -EINVAL or zero on success
+ */
+static int tpg_enum_frame_size(struct v4l2_subdev *sd,
+			       struct v4l2_subdev_state *sd_state,
+			       struct v4l2_subdev_frame_size_enum *fse)
+{
+	struct tpg_device *tpg = v4l2_get_subdevdata(sd);
+	struct v4l2_mbus_framefmt format;
+
+	if (fse->index != 0)
+		return -EINVAL;
+
+	format.code = fse->code;
+	format.width = 1;
+	format.height = 1;
+	tpg_try_format(tpg, sd_state, fse->pad, &format, fse->which);
+	fse->min_width = format.width;
+	fse->min_height = format.height;
+
+	if (format.code != fse->code)
+		return -EINVAL;
+
+	format.code = fse->code;
+	format.width = -1;
+	format.height = -1;
+	tpg_try_format(tpg, sd_state, fse->pad, &format, fse->which);
+	fse->max_width = format.width;
+	fse->max_height = format.height;
+
+	return 0;
+}
+
+/*
+ * tpg_get_format - Handle get format by pads subdev method
+ * @sd: tpg V4L2 subdevice
+ * @cfg: V4L2 subdev pad configuration
+ * @fmt: pointer to v4l2 subdev format structure
+ *
+ * Return -EINVAL or zero on success
+ */
+static int tpg_get_format(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_state *sd_state,
+			  struct v4l2_subdev_format *fmt)
+{
+	struct tpg_device *tpg = v4l2_get_subdevdata(sd);
+	struct v4l2_mbus_framefmt *format;
+
+	format = __tpg_get_format(tpg, sd_state, fmt->pad, fmt->which);
+	if (format == NULL)
+		return -EINVAL;
+
+	fmt->format = *format;
+
+	return 0;
+}
+
+/*
+ * tpg_set_format - Handle set format by pads subdev method
+ * @sd: tpg V4L2 subdevice
+ * @cfg: V4L2 subdev pad configuration
+ * @fmt: pointer to v4l2 subdev format structure
+ *
+ * Return -EINVAL or zero on success
+ */
+static int tpg_set_format(struct v4l2_subdev *sd,
+			  struct v4l2_subdev_state *sd_state,
+			  struct v4l2_subdev_format *fmt)
+{
+	struct tpg_device *tpg = v4l2_get_subdevdata(sd);
+	struct v4l2_mbus_framefmt *format;
+
+	format = __tpg_get_format(tpg, sd_state, fmt->pad, fmt->which);
+	if (format == NULL)
+		return -EINVAL;
+
+	tpg_try_format(tpg, sd_state, fmt->pad, &fmt->format,
+			  fmt->which);
+	*format = fmt->format;
+
+	if (fmt->pad == MSM_TPG_PAD_SINK) {
+		format = __tpg_get_format(tpg, sd_state,
+					     MSM_TPG_PAD_SRC,
+					     fmt->which);
+
+		*format = fmt->format;
+		tpg_try_format(tpg, sd_state, MSM_TPG_PAD_SRC,
+				  format,
+				  fmt->which);
+	}
+	return 0;
+}
+
+/*
+ * tpg_init_formats - Initialize formats on all pads
+ * @sd: tpg V4L2 subdevice
+ * @fh: V4L2 subdev file handle
+ *
+ * Initialize all pad formats with default values.
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int tpg_init_formats(struct v4l2_subdev *sd,
+			    struct v4l2_subdev_fh *fh)
+{
+	struct v4l2_subdev_format format = {
+		.pad = MSM_TPG_PAD_SINK,
+		.which = fh ? V4L2_SUBDEV_FORMAT_TRY :
+			      V4L2_SUBDEV_FORMAT_ACTIVE,
+		.format = {
+			.code = MEDIA_BUS_FMT_SBGGR8_1X8,
+			.width = 1920,
+			.height = 1080
+		}
+	};
+
+	return tpg_set_format(sd, fh ? fh->state : NULL, &format);
+}
+
+/*
+ * tpg_set_test_pattern - Set test generator's pattern mode
+ * @tpg: TPG device
+ * @value: desired test pattern mode
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int tpg_set_test_pattern(struct tpg_device *tpg, s32 value)
+{
+	return tpg->res->hw_ops->configure_testgen_pattern(tpg, value);
+}
+
+/*
+ * tpg_s_ctrl - Handle set control subdev method
+ * @ctrl: pointer to v4l2 control structure
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int tpg_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct tpg_device *tpg = container_of(ctrl->handler,
+					      struct tpg_device, ctrls);
+	int ret = -EINVAL;
+
+	switch (ctrl->id) {
+	case V4L2_CID_TEST_PATTERN:
+		ret = tpg_set_test_pattern(tpg, ctrl->val);
+		break;
+	}
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops tpg_ctrl_ops = {
+	.s_ctrl = tpg_s_ctrl,
+};
+
+/*
+ * msm_tpg_subdev_init - Initialize tpg device structure and resources
+ * @tpg: tpg device
+ * @res: tpg module resources table
+ * @id: tpg module id
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+int msm_tpg_subdev_init(struct camss *camss,
+			struct tpg_device *tpg,
+			const struct camss_subdev_resources *res, u8 id)
+{
+	struct device *dev = camss->dev;
+	struct platform_device *pdev = to_platform_device(dev);
+	int i, j;
+	int ret;
+
+	tpg->camss = camss;
+	tpg->id = id;
+	tpg->res = &res->tpg;
+	tpg->res->hw_ops->subdev_init(tpg);
+
+	/* Memory */
+	tpg->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]);
+	if (IS_ERR(tpg->base))
+		return PTR_ERR(tpg->base);
+
+	/* Interrupt */
+	ret = platform_get_irq_byname(pdev, res->interrupt[0]);
+	if (ret < 0)
+		return ret;
+
+	tpg->irq = ret;
+	snprintf(tpg->irq_name, sizeof(tpg->irq_name), "%s_%s%d",
+		 dev_name(dev), MSM_TPG_NAME, tpg->id);
+
+	ret = devm_request_irq(dev, tpg->irq, tpg->res->hw_ops->isr,
+			       IRQF_TRIGGER_RISING | IRQF_NO_AUTOEN,
+			       tpg->irq_name, tpg);
+	if (ret < 0) {
+		dev_err(dev, "request_irq failed: %d\n", ret);
+		return ret;
+	}
+
+	/* Clocks */
+	tpg->nclocks = 0;
+	while (res->clock[tpg->nclocks])
+		tpg->nclocks++;
+
+	tpg->clock = devm_kcalloc(dev,
+				  tpg->nclocks, sizeof(*tpg->clock),
+				  GFP_KERNEL);
+	if (!tpg->clock)
+		return -ENOMEM;
+
+	for (i = 0; i < tpg->nclocks; i++) {
+		struct camss_clock *clock = &tpg->clock[i];
+
+		clock->clk = devm_clk_get(dev, res->clock[i]);
+		if (IS_ERR(clock->clk))
+			return PTR_ERR(clock->clk);
+
+		clock->name = res->clock[i];
+
+		clock->nfreqs = 0;
+		while (res->clock_rate[i][clock->nfreqs])
+			clock->nfreqs++;
+
+		if (!clock->nfreqs) {
+			clock->freq = NULL;
+			continue;
+		}
+
+		clock->freq = devm_kcalloc(dev,
+					   clock->nfreqs,
+					   sizeof(*clock->freq),
+					   GFP_KERNEL);
+		if (!clock->freq)
+			return -ENOMEM;
+
+		for (j = 0; j < clock->nfreqs; j++)
+			clock->freq[j] = res->clock_rate[i][j];
+	}
+
+	return 0;
+}
+
+/*
+ * tpg_link_setup - Setup tpg connections
+ * @entity: Pointer to media entity structure
+ * @local: Pointer to local pad
+ * @remote: Pointer to remote pad
+ * @flags: Link flags
+ *
+ * Rreturn 0 on success
+ */
+static int tpg_link_setup(struct media_entity *entity,
+			  const struct media_pad *local,
+			  const struct media_pad *remote, u32 flags)
+{
+	if (flags & MEDIA_LNK_FL_ENABLED)
+		if (media_pad_remote_pad_first(local))
+			return -EBUSY;
+
+	return 0;
+}
+
+static const struct v4l2_subdev_core_ops tpg_core_ops = {
+	.s_power = tpg_set_power,
+};
+
+static const struct v4l2_subdev_video_ops tpg_video_ops = {
+	.s_stream = tpg_set_stream,
+};
+
+static const struct v4l2_subdev_pad_ops tpg_pad_ops = {
+	.enum_mbus_code = tpg_enum_mbus_code,
+	.enum_frame_size = tpg_enum_frame_size,
+	.get_fmt = tpg_get_format,
+	.set_fmt = tpg_set_format,
+};
+
+static const struct v4l2_subdev_ops tpg_v4l2_ops = {
+	.core = &tpg_core_ops,
+	.video = &tpg_video_ops,
+	.pad = &tpg_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops tpg_v4l2_internal_ops = {
+	.open = tpg_init_formats,
+};
+
+static const struct media_entity_operations tpg_media_ops = {
+	.link_setup = tpg_link_setup,
+	.link_validate = v4l2_subdev_link_validate,
+};
+
+/*
+ * msm_tpg_register_entity - Register subdev node for tpg module
+ * @tpg: tpg device
+ * @v4l2_dev: V4L2 device
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+int msm_tpg_register_entity(struct tpg_device *tpg,
+			    struct v4l2_device *v4l2_dev)
+{
+	struct v4l2_subdev *sd = &tpg->subdev;
+	struct media_pad *pads = tpg->pads;
+	struct device *dev = tpg->camss->dev;
+	int ret;
+
+	v4l2_subdev_init(sd, &tpg_v4l2_ops);
+	sd->internal_ops = &tpg_v4l2_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+		     V4L2_SUBDEV_FL_HAS_EVENTS;
+	snprintf(sd->name, ARRAY_SIZE(sd->name), "%s%d",
+		 MSM_TPG_NAME, tpg->id);
+	v4l2_set_subdevdata(sd, tpg);
+
+	ret = v4l2_ctrl_handler_init(&tpg->ctrls, 1);
+	if (ret < 0) {
+		dev_err(dev, "Failed to init ctrl handler: %d\n", ret);
+		return ret;
+	}
+
+	tpg->testgen_mode = v4l2_ctrl_new_std_menu_items(&tpg->ctrls,
+							 &tpg_ctrl_ops, V4L2_CID_TEST_PATTERN,
+							 TPG_PAYLOAD_MODE_COLOR_BARS, 0, 0,
+							 tpg->testgen.modes);
+
+	if (tpg->ctrls.error) {
+		dev_err(dev, "Failed to init ctrl: %d\n", tpg->ctrls.error);
+		ret = tpg->ctrls.error;
+		goto free_ctrl;
+	}
+
+	tpg->subdev.ctrl_handler = &tpg->ctrls;
+
+	ret = tpg_init_formats(sd, NULL);
+	if (ret < 0) {
+		dev_err(dev, "Failed to init format: %d\n", ret);
+		goto free_ctrl;
+	}
+
+	pads[MSM_TPG_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+	pads[MSM_TPG_PAD_SRC].flags = MEDIA_PAD_FL_SOURCE;
+
+	sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
+	sd->entity.ops = &tpg_media_ops;
+	ret = media_entity_pads_init(&sd->entity, MSM_TPG_PADS_NUM, pads);
+	if (ret < 0) {
+		dev_err(dev, "Failed to init media entity: %d\n", ret);
+		goto free_ctrl;
+	}
+
+	ret = v4l2_device_register_subdev(v4l2_dev, sd);
+	if (ret < 0) {
+		dev_err(dev, "Failed to register subdev: %d\n", ret);
+		media_entity_cleanup(&sd->entity);
+		goto free_ctrl;
+	}
+
+	return 0;
+
+free_ctrl:
+	v4l2_ctrl_handler_free(&tpg->ctrls);
+
+	return ret;
+}
+
+/*
+ * msm_tpg_unregister_entity - Unregister tpg module subdev node
+ * @tpg: tpg device
+ */
+void msm_tpg_unregister_entity(struct tpg_device *tpg)
+{
+	v4l2_device_unregister_subdev(&tpg->subdev);
+	media_entity_cleanup(&tpg->subdev.entity);
+	v4l2_ctrl_handler_free(&tpg->ctrls);
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-tpg.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-tpg.h
@@ -0,0 +1,130 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * camss-tpg.h
+ *
+ * Qualcomm MSM Camera Subsystem - TPG Module
+ *
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#ifndef QC_MSM_CAMSS_TPG_H
+#define QC_MSM_CAMSS_TPG_H
+
+#include <linux/clk.h>
+#include <linux/interrupt.h>
+#include <media/media-entity.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-mediabus.h>
+#include <media/v4l2-subdev.h>
+
+#define MSM_TPG_PAD_SINK 0
+#define MSM_TPG_PAD_SRC 1
+#define MSM_TPG_PADS_NUM 2
+
+#define DATA_TYPE_RAW_8BIT		0x2a
+#define DATA_TYPE_RAW_10BIT		0x2b
+#define DATA_TYPE_RAW_12BIT		0x2c
+
+#define ENCODE_FORMAT_UNCOMPRESSED_8_BIT	0x1
+#define ENCODE_FORMAT_UNCOMPRESSED_10_BIT	0x2
+#define ENCODE_FORMAT_UNCOMPRESSED_12_BIT	0x3
+#define ENCODE_FORMAT_UNCOMPRESSED_14_BIT	0x4
+#define ENCODE_FORMAT_UNCOMPRESSED_16_BIT	0x5
+#define ENCODE_FORMAT_UNCOMPRESSED_20_BIT	0x6
+#define ENCODE_FORMAT_UNCOMPRESSED_24_BIT	0x7
+
+#define MSM_TPG_NAME "msm_tpg"
+
+enum tpg_testgen_mode {
+	TPG_PAYLOAD_MODE_DISABLED = 0,
+	TPG_PAYLOAD_MODE_INCREMENTING = 1,
+	TPG_PAYLOAD_MODE_ALTERNATING_55_AA = 2,
+	TPG_PAYLOAD_MODE_RANDOM = 5,
+	TPG_PAYLOAD_MODE_USER_SPECIFIED = 6,
+	TPG_PAYLOAD_MODE_COLOR_BARS = 9,
+};
+
+struct tpg_testgen_config {
+	enum tpg_testgen_mode mode;
+	const char * const*modes;
+	u8 nmodes;
+};
+
+struct tpg_format_info {
+	u32 code;
+	u8 data_type;
+	u8 encode_format;
+};
+
+struct tpg_formats {
+	unsigned int nformats;
+	const struct tpg_format_info *formats;
+};
+
+struct tpg_device;
+
+struct tpg_hw_ops {
+
+	void (*configure_stream)(struct tpg_device *tpg, u8 enable);
+
+	int (*configure_testgen_pattern)(struct tpg_device *tpg, s32 val);
+
+	u32 (*hw_version)(struct tpg_device *tpg);
+
+	irqreturn_t (*isr)(int irq, void *dev);
+
+	int (*reset)(struct tpg_device *tpg);
+
+	void (*subdev_init)(struct tpg_device *tpg);
+};
+
+struct tpg_subdev_resources {
+	u8 lane_cnt;
+	u8 vc_cnt;
+	const struct tpg_formats *formats;
+	const struct tpg_hw_ops *hw_ops;
+};
+
+struct tpg_device {
+	struct camss *camss;
+	u8 id;
+	struct v4l2_subdev subdev;
+	struct media_pad pads[MSM_TPG_PADS_NUM];
+	void __iomem *base;
+	void __iomem *base_clk_mux;
+	u32 irq;
+	char irq_name[30];
+	struct camss_clock *clock;
+	int nclocks;
+	u32 timer_clk_rate;
+	struct tpg_testgen_config testgen;
+	struct v4l2_mbus_framefmt fmt[MSM_TPG_PADS_NUM];
+	struct v4l2_ctrl_handler ctrls;
+	struct v4l2_ctrl *testgen_mode;
+	const struct tpg_subdev_resources *res;
+	const struct tpg_format *formats;
+	unsigned int nformats;
+};
+
+struct camss_subdev_resources;
+
+const struct tpg_format_info *tpg_get_fmt_entry(const struct tpg_format_info *formats,
+						unsigned int nformats,
+						u32 code);
+
+int msm_tpg_subdev_init(struct camss *camss,
+			struct tpg_device *tpg,
+			const struct camss_subdev_resources *res, u8 id);
+
+int msm_tpg_register_entity(struct tpg_device *tpg,
+			    struct v4l2_device *v4l2_dev);
+
+void msm_tpg_unregister_entity(struct tpg_device *tpg);
+
+extern const char * const testgen_payload_modes[];
+
+extern const struct tpg_formats tpg_formats_gen1;
+
+extern const struct tpg_hw_ops tpg_ops_gen1;
+
+#endif /* QC_MSM_CAMSS_TPG_H */
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-vfe-17x.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-vfe-17x.c
@@ -0,0 +1,699 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-vfe-170.c
+ *
+ * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v170
+ *
+ * Copyright (C) 2020-2021 Linaro Ltd.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+
+#include "camss.h"
+#include "camss-vfe.h"
+
+#define VFE_HW_VERSION				(0x000)
+
+#define VFE_GLOBAL_RESET_CMD			(0x018)
+#define		GLOBAL_RESET_CMD_CORE		BIT(0)
+#define		GLOBAL_RESET_CMD_CAMIF		BIT(1)
+#define		GLOBAL_RESET_CMD_BUS		BIT(2)
+#define		GLOBAL_RESET_CMD_BUS_BDG	BIT(3)
+#define		GLOBAL_RESET_CMD_REGISTER	BIT(4)
+#define		GLOBAL_RESET_CMD_PM		BIT(5)
+#define		GLOBAL_RESET_CMD_BUS_MISR	BIT(6)
+#define		GLOBAL_RESET_CMD_TESTGEN	BIT(7)
+#define		GLOBAL_RESET_CMD_DSP		BIT(8)
+#define		GLOBAL_RESET_CMD_IDLE_CGC	BIT(9)
+#define		GLOBAL_RESET_CMD_RDI0		BIT(10)
+#define		GLOBAL_RESET_CMD_RDI1		BIT(11)
+#define		GLOBAL_RESET_CMD_RDI2		BIT(12)
+#define		GLOBAL_RESET_CMD_RDI3		BIT(13)
+#define		GLOBAL_RESET_CMD_VFE_DOMAIN	BIT(30)
+#define		GLOBAL_RESET_CMD_RESET_BYPASS	BIT(31)
+
+#define VFE_CORE_CFG				(0x050)
+#define		CFG_PIXEL_PATTERN_YCBYCR	(0x4)
+#define		CFG_PIXEL_PATTERN_YCRYCB	(0x5)
+#define		CFG_PIXEL_PATTERN_CBYCRY	(0x6)
+#define		CFG_PIXEL_PATTERN_CRYCBY	(0x7)
+#define		CFG_COMPOSITE_REG_UPDATE_EN	BIT(4)
+
+#define VFE_IRQ_CMD				(0x058)
+#define		CMD_GLOBAL_CLEAR		BIT(0)
+
+#define VFE_IRQ_MASK_0					(0x05c)
+#define		MASK_0_CAMIF_SOF			BIT(0)
+#define		MASK_0_CAMIF_EOF			BIT(1)
+#define		MASK_0_RDI_REG_UPDATE(n)		BIT((n) + 5)
+#define		MASK_0_IMAGE_MASTER_n_PING_PONG(n)	BIT((n) + 8)
+#define		MASK_0_IMAGE_COMPOSITE_DONE_n(n)	BIT((n) + 25)
+#define		MASK_0_RESET_ACK			BIT(31)
+
+#define VFE_IRQ_MASK_1					(0x060)
+#define		MASK_1_CAMIF_ERROR			BIT(0)
+#define		MASK_1_VIOLATION			BIT(7)
+#define		MASK_1_BUS_BDG_HALT_ACK			BIT(8)
+#define		MASK_1_IMAGE_MASTER_n_BUS_OVERFLOW(n)	BIT((n) + 9)
+#define		MASK_1_RDI_SOF(n)			BIT((n) + 29)
+
+#define VFE_IRQ_CLEAR_0					(0x064)
+#define VFE_IRQ_CLEAR_1					(0x068)
+
+#define VFE_IRQ_STATUS_0				(0x06c)
+#define		STATUS_0_CAMIF_SOF			BIT(0)
+#define		STATUS_0_RDI_REG_UPDATE(n)		BIT((n) + 5)
+#define		STATUS_0_IMAGE_MASTER_PING_PONG(n)	BIT((n) + 8)
+#define		STATUS_0_IMAGE_COMPOSITE_DONE(n)	BIT((n) + 25)
+#define		STATUS_0_RESET_ACK			BIT(31)
+
+#define VFE_IRQ_STATUS_1				(0x070)
+#define		STATUS_1_VIOLATION			BIT(7)
+#define		STATUS_1_BUS_BDG_HALT_ACK		BIT(8)
+#define		STATUS_1_RDI_SOF(n)			BIT((n) + 27)
+
+#define VFE_VIOLATION_STATUS			(0x07c)
+
+#define VFE_CAMIF_CMD				(0x478)
+#define		CMD_CLEAR_CAMIF_STATUS		BIT(2)
+
+#define VFE_CAMIF_CFG				(0x47c)
+#define		CFG_VSYNC_SYNC_EDGE		(0)
+#define			VSYNC_ACTIVE_HIGH	(0)
+#define			VSYNC_ACTIVE_LOW	(1)
+#define		CFG_HSYNC_SYNC_EDGE		(1)
+#define			HSYNC_ACTIVE_HIGH	(0)
+#define			HSYNC_ACTIVE_LOW	(1)
+#define		CFG_VFE_SUBSAMPLE_ENABLE	BIT(4)
+#define		CFG_BUS_SUBSAMPLE_ENABLE	BIT(5)
+#define		CFG_VFE_OUTPUT_EN		BIT(6)
+#define		CFG_BUS_OUTPUT_EN		BIT(7)
+#define		CFG_BINNING_EN			BIT(9)
+#define		CFG_FRAME_BASED_EN		BIT(10)
+#define		CFG_RAW_CROP_EN			BIT(22)
+
+#define VFE_REG_UPDATE_CMD			(0x4ac)
+#define		REG_UPDATE_RDI(n)		BIT(1 + (n))
+
+#define VFE_BUS_IRQ_MASK(n)		(0x2044 + (n) * 4)
+#define VFE_BUS_IRQ_CLEAR(n)		(0x2050 + (n) * 4)
+#define VFE_BUS_IRQ_STATUS(n)		(0x205c + (n) * 4)
+#define		STATUS0_COMP_RESET_DONE		BIT(0)
+#define		STATUS0_COMP_REG_UPDATE0_DONE	BIT(1)
+#define		STATUS0_COMP_REG_UPDATE1_DONE	BIT(2)
+#define		STATUS0_COMP_REG_UPDATE2_DONE	BIT(3)
+#define		STATUS0_COMP_REG_UPDATE3_DONE	BIT(4)
+#define		STATUS0_COMP_REG_UPDATE_DONE(n)	BIT((n) + 1)
+#define		STATUS0_COMP0_BUF_DONE		BIT(5)
+#define		STATUS0_COMP1_BUF_DONE		BIT(6)
+#define		STATUS0_COMP2_BUF_DONE		BIT(7)
+#define		STATUS0_COMP3_BUF_DONE		BIT(8)
+#define		STATUS0_COMP4_BUF_DONE		BIT(9)
+#define		STATUS0_COMP5_BUF_DONE		BIT(10)
+#define		STATUS0_COMP_BUF_DONE(n)	BIT((n) + 5)
+#define		STATUS0_COMP_ERROR		BIT(11)
+#define		STATUS0_COMP_OVERWRITE		BIT(12)
+#define		STATUS0_OVERFLOW		BIT(13)
+#define		STATUS0_VIOLATION		BIT(14)
+/* WM_CLIENT_BUF_DONE defined for buffers 0:19 */
+#define		STATUS1_WM_CLIENT_BUF_DONE(n)		BIT(n)
+#define		STATUS1_EARLY_DONE			BIT(24)
+#define		STATUS2_DUAL_COMP0_BUF_DONE		BIT(0)
+#define		STATUS2_DUAL_COMP1_BUF_DONE		BIT(1)
+#define		STATUS2_DUAL_COMP2_BUF_DONE		BIT(2)
+#define		STATUS2_DUAL_COMP3_BUF_DONE		BIT(3)
+#define		STATUS2_DUAL_COMP4_BUF_DONE		BIT(4)
+#define		STATUS2_DUAL_COMP5_BUF_DONE		BIT(5)
+#define		STATUS2_DUAL_COMP_BUF_DONE(n)		BIT(n)
+#define		STATUS2_DUAL_COMP_ERROR			BIT(6)
+#define		STATUS2_DUAL_COMP_OVERWRITE		BIT(7)
+
+#define VFE_BUS_IRQ_CLEAR_GLOBAL		(0x2068)
+
+#define VFE_BUS_WM_DEBUG_STATUS_CFG		(0x226c)
+#define		DEBUG_STATUS_CFG_STATUS0(n)	BIT(n)
+#define		DEBUG_STATUS_CFG_STATUS1(n)	BIT(8 + (n))
+
+#define VFE_BUS_WM_ADDR_SYNC_FRAME_HEADER	(0x2080)
+
+#define VFE_BUS_WM_ADDR_SYNC_NO_SYNC		(0x2084)
+#define		BUS_VER2_MAX_CLIENTS (24)
+#define		WM_ADDR_NO_SYNC_DEFAULT_VAL \
+				((1 << BUS_VER2_MAX_CLIENTS) - 1)
+
+#define VFE_BUS_WM_CGC_OVERRIDE			(0x200c)
+#define		WM_CGC_OVERRIDE_ALL		(0xFFFFF)
+
+#define VFE_BUS_WM_TEST_BUS_CTRL		(0x211c)
+
+#define VFE_BUS_WM_STATUS0(n)			(0x2200 + (n) * 0x100)
+#define VFE_BUS_WM_STATUS1(n)			(0x2204 + (n) * 0x100)
+#define VFE_BUS_WM_CFG(n)			(0x2208 + (n) * 0x100)
+#define		WM_CFG_EN			(0)
+#define		WM_CFG_MODE			(1)
+#define			MODE_QCOM_PLAIN	(0)
+#define			MODE_MIPI_RAW	(1)
+#define		WM_CFG_VIRTUALFRAME		(2)
+#define VFE_BUS_WM_HEADER_ADDR(n)		(0x220c + (n) * 0x100)
+#define VFE_BUS_WM_HEADER_CFG(n)		(0x2210 + (n) * 0x100)
+#define VFE_BUS_WM_IMAGE_ADDR(n)		(0x2214 + (n) * 0x100)
+#define VFE_BUS_WM_IMAGE_ADDR_OFFSET(n)		(0x2218 + (n) * 0x100)
+#define VFE_BUS_WM_BUFFER_WIDTH_CFG(n)		(0x221c + (n) * 0x100)
+#define		WM_BUFFER_DEFAULT_WIDTH		(0xFF01)
+
+#define VFE_BUS_WM_BUFFER_HEIGHT_CFG(n)		(0x2220 + (n) * 0x100)
+#define VFE_BUS_WM_PACKER_CFG(n)		(0x2224 + (n) * 0x100)
+
+#define VFE_BUS_WM_STRIDE(n)			(0x2228 + (n) * 0x100)
+#define		WM_STRIDE_DEFAULT_STRIDE	(0xFF01)
+
+#define VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(n)	(0x2248 + (n) * 0x100)
+#define VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(n)	(0x224c + (n) * 0x100)
+#define VFE_BUS_WM_FRAMEDROP_PERIOD(n)		(0x2250 + (n) * 0x100)
+#define VFE_BUS_WM_FRAMEDROP_PATTERN(n)		(0x2254 + (n) * 0x100)
+#define VFE_BUS_WM_FRAME_INC(n)			(0x2258 + (n) * 0x100)
+#define VFE_BUS_WM_BURST_LIMIT(n)		(0x225c + (n) * 0x100)
+
+static u32 vfe_hw_version(struct vfe_device *vfe)
+{
+	u32 hw_version = readl_relaxed(vfe->base + VFE_HW_VERSION);
+
+	u32 gen = (hw_version >> 28) & 0xF;
+	u32 rev = (hw_version >> 16) & 0xFFF;
+	u32 step = hw_version & 0xFFFF;
+
+	dev_dbg(vfe->camss->dev, "VFE HW Version = %u.%u.%u\n",
+		gen, rev, step);
+
+	return hw_version;
+}
+
+static inline void vfe_reg_set(struct vfe_device *vfe, u32 reg, u32 set_bits)
+{
+	u32 bits = readl_relaxed(vfe->base + reg);
+
+	writel_relaxed(bits | set_bits, vfe->base + reg);
+}
+
+static void vfe_global_reset(struct vfe_device *vfe)
+{
+	u32 reset_bits = GLOBAL_RESET_CMD_CORE		|
+			 GLOBAL_RESET_CMD_CAMIF		|
+			 GLOBAL_RESET_CMD_BUS		|
+			 GLOBAL_RESET_CMD_BUS_BDG	|
+			 GLOBAL_RESET_CMD_REGISTER	|
+			 GLOBAL_RESET_CMD_TESTGEN	|
+			 GLOBAL_RESET_CMD_DSP		|
+			 GLOBAL_RESET_CMD_IDLE_CGC	|
+			 GLOBAL_RESET_CMD_RDI0		|
+			 GLOBAL_RESET_CMD_RDI1		|
+			 GLOBAL_RESET_CMD_RDI2		|
+			 GLOBAL_RESET_CMD_RDI3;
+
+	writel_relaxed(BIT(31), vfe->base + VFE_IRQ_MASK_0);
+
+	/* Make sure IRQ mask has been written before resetting */
+	wmb();
+
+	writel_relaxed(reset_bits, vfe->base + VFE_GLOBAL_RESET_CMD);
+}
+
+static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line)
+{
+	u32 val;
+
+	/*Set Debug Registers*/
+	val = DEBUG_STATUS_CFG_STATUS0(1) |
+	      DEBUG_STATUS_CFG_STATUS0(7);
+	writel_relaxed(val, vfe->base + VFE_BUS_WM_DEBUG_STATUS_CFG);
+
+	/* BUS_WM_INPUT_IF_ADDR_SYNC_FRAME_HEADER */
+	writel_relaxed(0, vfe->base + VFE_BUS_WM_ADDR_SYNC_FRAME_HEADER);
+
+	/* no clock gating at bus input */
+	val = WM_CGC_OVERRIDE_ALL;
+	writel_relaxed(val, vfe->base + VFE_BUS_WM_CGC_OVERRIDE);
+
+	writel_relaxed(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL);
+
+	/* if addr_no_sync has default value then config the addr no sync reg */
+	val = WM_ADDR_NO_SYNC_DEFAULT_VAL;
+	writel_relaxed(val, vfe->base + VFE_BUS_WM_ADDR_SYNC_NO_SYNC);
+
+	writel_relaxed(0xf, vfe->base + VFE_BUS_WM_BURST_LIMIT(wm));
+
+	val = WM_BUFFER_DEFAULT_WIDTH;
+	writel_relaxed(val, vfe->base + VFE_BUS_WM_BUFFER_WIDTH_CFG(wm));
+
+	val = 0;
+	writel_relaxed(val, vfe->base + VFE_BUS_WM_BUFFER_HEIGHT_CFG(wm));
+
+	val = 0;
+	writel_relaxed(val, vfe->base + VFE_BUS_WM_PACKER_CFG(wm)); // XXX 1 for PLAIN8?
+
+	/* Configure stride for RDIs */
+	val = WM_STRIDE_DEFAULT_STRIDE;
+	writel_relaxed(val, vfe->base + VFE_BUS_WM_STRIDE(wm));
+
+	/* Enable WM */
+	val = 1 << WM_CFG_EN |
+	      MODE_MIPI_RAW << WM_CFG_MODE;
+	writel_relaxed(val, vfe->base + VFE_BUS_WM_CFG(wm));
+}
+
+static void vfe_wm_stop(struct vfe_device *vfe, u8 wm)
+{
+	/* Disable WM */
+	writel_relaxed(0, vfe->base + VFE_BUS_WM_CFG(wm));
+}
+
+static void vfe_wm_update(struct vfe_device *vfe, u8 wm, u32 addr,
+			  struct vfe_line *line)
+{
+	struct v4l2_pix_format_mplane *pix =
+		&line->video_out.active_fmt.fmt.pix_mp;
+	u32 stride = pix->plane_fmt[0].bytesperline;
+
+	writel_relaxed(addr, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm));
+	writel_relaxed(stride * pix->height, vfe->base + VFE_BUS_WM_FRAME_INC(wm));
+}
+
+static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+	vfe->reg_update |= REG_UPDATE_RDI(line_id);
+
+	/* Enforce ordering between previous reg writes and reg update */
+	wmb();
+
+	writel_relaxed(vfe->reg_update, vfe->base + VFE_REG_UPDATE_CMD);
+
+	/* Enforce ordering between reg update and subsequent reg writes */
+	wmb();
+}
+
+static inline void vfe_reg_update_clear(struct vfe_device *vfe,
+					enum vfe_line_id line_id)
+{
+	vfe->reg_update &= ~REG_UPDATE_RDI(line_id);
+}
+
+static void vfe_enable_irq_common(struct vfe_device *vfe)
+{
+	vfe_reg_set(vfe, VFE_IRQ_MASK_0, ~0u);
+	vfe_reg_set(vfe, VFE_IRQ_MASK_1, ~0u);
+
+	writel_relaxed(~0u, vfe->base + VFE_BUS_IRQ_MASK(0));
+	writel_relaxed(~0u, vfe->base + VFE_BUS_IRQ_MASK(1));
+	writel_relaxed(~0u, vfe->base + VFE_BUS_IRQ_MASK(2));
+}
+
+static void vfe_isr_halt_ack(struct vfe_device *vfe)
+{
+	complete(&vfe->halt_complete);
+}
+
+static void vfe_isr_read(struct vfe_device *vfe, u32 *status0, u32 *status1)
+{
+	*status0 = readl_relaxed(vfe->base + VFE_IRQ_STATUS_0);
+	*status1 = readl_relaxed(vfe->base + VFE_IRQ_STATUS_1);
+
+	writel_relaxed(*status0, vfe->base + VFE_IRQ_CLEAR_0);
+	writel_relaxed(*status1, vfe->base + VFE_IRQ_CLEAR_1);
+
+	/* Enforce ordering between IRQ Clear and Global IRQ Clear */
+	wmb();
+	writel_relaxed(CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD);
+}
+
+static void vfe_violation_read(struct vfe_device *vfe)
+{
+	u32 violation = readl_relaxed(vfe->base + VFE_VIOLATION_STATUS);
+
+	pr_err_ratelimited("VFE: violation = 0x%08x\n", violation);
+}
+
+/*
+ * vfe_isr - VFE module interrupt handler
+ * @irq: Interrupt line
+ * @dev: VFE device
+ *
+ * Return IRQ_HANDLED on success
+ */
+static irqreturn_t vfe_isr(int irq, void *dev)
+{
+	struct vfe_device *vfe = dev;
+	u32 status0, status1, vfe_bus_status[VFE_LINE_NUM_MAX];
+	int i, wm;
+
+	status0 = readl_relaxed(vfe->base + VFE_IRQ_STATUS_0);
+	status1 = readl_relaxed(vfe->base + VFE_IRQ_STATUS_1);
+
+	writel_relaxed(status0, vfe->base + VFE_IRQ_CLEAR_0);
+	writel_relaxed(status1, vfe->base + VFE_IRQ_CLEAR_1);
+
+	for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) {
+		vfe_bus_status[i] = readl_relaxed(vfe->base + VFE_BUS_IRQ_STATUS(i));
+		writel_relaxed(vfe_bus_status[i], vfe->base + VFE_BUS_IRQ_CLEAR(i));
+	}
+
+	/* Enforce ordering between IRQ reading and interpretation */
+	wmb();
+
+	writel_relaxed(CMD_GLOBAL_CLEAR, vfe->base + VFE_IRQ_CMD);
+	writel_relaxed(1, vfe->base + VFE_BUS_IRQ_CLEAR_GLOBAL);
+
+	if (status0 & STATUS_0_RESET_ACK)
+		vfe->isr_ops.reset_ack(vfe);
+
+	for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++)
+		if (status0 & STATUS_0_RDI_REG_UPDATE(i))
+			vfe->isr_ops.reg_update(vfe, i);
+
+	for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++)
+		if (status0 & STATUS_1_RDI_SOF(i))
+			vfe->isr_ops.sof(vfe, i);
+
+	for (i = 0; i < MSM_VFE_COMPOSITE_IRQ_NUM; i++)
+		if (vfe_bus_status[0] & STATUS0_COMP_BUF_DONE(i))
+			vfe->isr_ops.comp_done(vfe, i);
+
+	for (wm = 0; wm < MSM_VFE_IMAGE_MASTERS_NUM; wm++)
+		if (status0 & BIT(9))
+			if (vfe_bus_status[1] & STATUS1_WM_CLIENT_BUF_DONE(wm))
+				vfe->isr_ops.wm_done(vfe, wm);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * vfe_halt - Trigger halt on VFE module and wait to complete
+ * @vfe: VFE device
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int vfe_halt(struct vfe_device *vfe)
+{
+	/* rely on vfe_disable_output() to stop the VFE */
+	return 0;
+}
+
+static int vfe_get_output(struct vfe_line *line)
+{
+	struct vfe_device *vfe = to_vfe(line);
+	struct vfe_output *output;
+	unsigned long flags;
+	int wm_idx;
+
+	spin_lock_irqsave(&vfe->output_lock, flags);
+
+	output = &line->output;
+	if (output->state > VFE_OUTPUT_RESERVED) {
+		dev_err(vfe->camss->dev, "Output is running\n");
+		goto error;
+	}
+
+	output->wm_num = 1;
+
+	wm_idx = vfe_reserve_wm(vfe, line->id);
+	if (wm_idx < 0) {
+		dev_err(vfe->camss->dev, "Can not reserve wm\n");
+		goto error_get_wm;
+	}
+	output->wm_idx[0] = wm_idx;
+
+	output->drop_update_idx = 0;
+
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+	return 0;
+
+error_get_wm:
+	vfe_release_wm(vfe, output->wm_idx[0]);
+	output->state = VFE_OUTPUT_OFF;
+error:
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+	return -EINVAL;
+}
+
+static int vfe_enable_output(struct vfe_line *line)
+{
+	struct vfe_device *vfe = to_vfe(line);
+	struct vfe_output *output = &line->output;
+	const struct vfe_hw_ops *ops = vfe->res->hw_ops;
+	struct media_entity *sensor;
+	unsigned long flags;
+	unsigned int frame_skip = 0;
+	unsigned int i;
+
+	sensor = camss_find_sensor(&line->subdev.entity);
+	if (sensor) {
+		struct v4l2_subdev *subdev = media_entity_to_v4l2_subdev(sensor);
+
+		v4l2_subdev_call(subdev, sensor, g_skip_frames, &frame_skip);
+		/* Max frame skip is 29 frames */
+		if (frame_skip > VFE_FRAME_DROP_VAL - 1)
+			frame_skip = VFE_FRAME_DROP_VAL - 1;
+	}
+
+	spin_lock_irqsave(&vfe->output_lock, flags);
+
+	ops->reg_update_clear(vfe, line->id);
+
+	if (output->state > VFE_OUTPUT_RESERVED) {
+		dev_err(vfe->camss->dev, "Output is not in reserved state %d\n",
+			output->state);
+		spin_unlock_irqrestore(&vfe->output_lock, flags);
+		return -EINVAL;
+	}
+
+	WARN_ON(output->gen2.active_num);
+
+	output->state = VFE_OUTPUT_ON;
+
+	output->sequence = 0;
+	output->wait_reg_update = 0;
+	reinit_completion(&output->reg_update);
+
+	vfe_wm_start(vfe, output->wm_idx[0], line);
+
+	for (i = 0; i < 2; i++) {
+		output->buf[i] = vfe_buf_get_pending(output);
+		if (!output->buf[i])
+			break;
+		output->gen2.active_num++;
+		vfe_wm_update(vfe, output->wm_idx[0], output->buf[i]->addr[0], line);
+	}
+
+	ops->reg_update(vfe, line->id);
+
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+	return 0;
+}
+
+/*
+ * vfe_enable - Enable streaming on VFE line
+ * @line: VFE line
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int vfe_enable(struct vfe_line *line)
+{
+	struct vfe_device *vfe = to_vfe(line);
+	int ret;
+
+	mutex_lock(&vfe->stream_lock);
+
+	if (!vfe->stream_count)
+		vfe_enable_irq_common(vfe);
+
+	vfe->stream_count++;
+
+	mutex_unlock(&vfe->stream_lock);
+
+	ret = vfe_get_output(line);
+	if (ret < 0)
+		goto error_get_output;
+
+	ret = vfe_enable_output(line);
+	if (ret < 0)
+		goto error_enable_output;
+
+	vfe->was_streaming = 1;
+
+	return 0;
+
+error_enable_output:
+	vfe_put_output(line);
+
+error_get_output:
+	mutex_lock(&vfe->stream_lock);
+
+	vfe->stream_count--;
+
+	mutex_unlock(&vfe->stream_lock);
+
+	return ret;
+}
+
+/*
+ * vfe_isr_sof - Process start of frame interrupt
+ * @vfe: VFE Device
+ * @line_id: VFE line
+ */
+static void vfe_isr_sof(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+	/* nop */
+}
+
+/*
+ * vfe_isr_reg_update - Process reg update interrupt
+ * @vfe: VFE Device
+ * @line_id: VFE line
+ */
+static void vfe_isr_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+	struct vfe_output *output;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vfe->output_lock, flags);
+	vfe->res->hw_ops->reg_update_clear(vfe, line_id);
+
+	output = &vfe->line[line_id].output;
+
+	if (output->wait_reg_update) {
+		output->wait_reg_update = 0;
+		complete(&output->reg_update);
+	}
+
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+}
+
+/*
+ * vfe_isr_wm_done - Process write master done interrupt
+ * @vfe: VFE Device
+ * @wm: Write master id
+ */
+static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm)
+{
+	struct vfe_line *line = &vfe->line[vfe->wm_output_map[wm]];
+	struct camss_buffer *ready_buf;
+	struct vfe_output *output;
+	unsigned long flags;
+	u32 index;
+	u64 ts = ktime_get_ns();
+
+	spin_lock_irqsave(&vfe->output_lock, flags);
+
+	if (vfe->wm_output_map[wm] == VFE_LINE_NONE) {
+		dev_err_ratelimited(vfe->camss->dev,
+				    "Received wm done for unmapped index\n");
+		goto out_unlock;
+	}
+	output = &vfe->line[vfe->wm_output_map[wm]].output;
+
+	ready_buf = output->buf[0];
+	if (!ready_buf) {
+		dev_err_ratelimited(vfe->camss->dev,
+				    "Missing ready buf %d!\n", output->state);
+		goto out_unlock;
+	}
+
+	ready_buf->vb.vb2_buf.timestamp = ts;
+	ready_buf->vb.sequence = output->sequence++;
+
+	index = 0;
+	output->buf[0] = output->buf[1];
+	if (output->buf[0])
+		index = 1;
+
+	output->buf[index] = vfe_buf_get_pending(output);
+
+	if (output->buf[index])
+		vfe_wm_update(vfe, output->wm_idx[0], output->buf[index]->addr[0], line);
+	else
+		output->gen2.active_num--;
+
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+	vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+
+	return;
+
+out_unlock:
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+}
+
+/*
+ * vfe_queue_buffer - Add empty buffer
+ * @vid: Video device structure
+ * @buf: Buffer to be enqueued
+ *
+ * Add an empty buffer - depending on the current number of buffers it will be
+ * put in pending buffer queue or directly given to the hardware to be filled.
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int vfe_queue_buffer(struct camss_video *vid,
+			    struct camss_buffer *buf)
+{
+	struct vfe_line *line = container_of(vid, struct vfe_line, video_out);
+	struct vfe_device *vfe = to_vfe(line);
+	struct vfe_output *output;
+	unsigned long flags;
+
+	output = &line->output;
+
+	spin_lock_irqsave(&vfe->output_lock, flags);
+
+	if (output->state == VFE_OUTPUT_ON && output->gen2.active_num < 2) {
+		output->buf[output->gen2.active_num++] = buf;
+		vfe_wm_update(vfe, output->wm_idx[0], buf->addr[0], line);
+	} else {
+		vfe_buf_add_pending(output, buf);
+	}
+
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+	return 0;
+}
+
+static const struct vfe_isr_ops vfe_isr_ops_170 = {
+	.reset_ack = vfe_isr_reset_ack,
+	.halt_ack = vfe_isr_halt_ack,
+	.reg_update = vfe_isr_reg_update,
+	.sof = vfe_isr_sof,
+	.comp_done = vfe_isr_comp_done,
+	.wm_done = vfe_isr_wm_done,
+};
+
+static const struct camss_video_ops vfe_video_ops_170 = {
+	.queue_buffer = vfe_queue_buffer,
+	.flush_buffers = vfe_flush_buffers,
+};
+
+static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
+{
+	vfe->isr_ops = vfe_isr_ops_170;
+	vfe->video_ops = vfe_video_ops_170;
+}
+
+const struct vfe_hw_ops vfe_ops_170 = {
+	.global_reset = vfe_global_reset,
+	.hw_version = vfe_hw_version,
+	.isr_read = vfe_isr_read,
+	.isr = vfe_isr,
+	.pm_domain_off = vfe_pm_domain_off,
+	.pm_domain_on = vfe_pm_domain_on,
+	.reg_update_clear = vfe_reg_update_clear,
+	.reg_update = vfe_reg_update,
+	.subdev_init = vfe_subdev_init,
+	.vfe_disable = vfe_disable,
+	.vfe_enable = vfe_enable,
+	.vfe_halt = vfe_halt,
+	.violation_read = vfe_violation_read,
+	.vfe_wm_stop = vfe_wm_stop,
+};
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
@@ -892,7 +892,7 @@
 	u32 value0, value1;
 	int i, j;
 
-	vfe->ops->isr_read(vfe, &value0, &value1);
+	vfe->res->hw_ops->isr_read(vfe, &value0, &value1);
 
 	dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
 		value0, value1);
@@ -901,7 +901,7 @@
 		vfe->isr_ops.reset_ack(vfe);
 
 	if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
-		vfe->ops->violation_read(vfe);
+		vfe->res->hw_ops->violation_read(vfe);
 
 	if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
 		vfe->isr_ops.halt_ack(vfe);
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
@@ -1050,7 +1050,7 @@
 	u32 value0, value1;
 	int i, j;
 
-	vfe->ops->isr_read(vfe, &value0, &value1);
+	vfe->res->hw_ops->isr_read(vfe, &value0, &value1);
 
 	dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
 		value0, value1);
@@ -1059,12 +1059,12 @@
 		vfe->isr_ops.reset_ack(vfe);
 
 	if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
-		vfe->ops->violation_read(vfe);
+		vfe->res->hw_ops->violation_read(vfe);
 
 	if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
 		vfe->isr_ops.halt_ack(vfe);
 
-	for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
+	for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++)
 		if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
 			vfe->isr_ops.reg_update(vfe, i);
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
@@ -980,7 +980,7 @@
 	u32 value0, value1;
 	int i, j;
 
-	vfe->ops->isr_read(vfe, &value0, &value1);
+	vfe->res->hw_ops->isr_read(vfe, &value0, &value1);
 
 	dev_dbg(vfe->camss->dev, "VFE: status0 = 0x%08x, status1 = 0x%08x\n",
 		value0, value1);
@@ -989,12 +989,12 @@
 		vfe->isr_ops.reset_ack(vfe);
 
 	if (value1 & VFE_0_IRQ_STATUS_1_VIOLATION)
-		vfe->ops->violation_read(vfe);
+		vfe->res->hw_ops->violation_read(vfe);
 
 	if (value1 & VFE_0_IRQ_STATUS_1_BUS_BDG_HALT_ACK)
 		vfe->isr_ops.halt_ack(vfe);
 
-	for (i = VFE_LINE_RDI0; i < vfe->line_num; i++)
+	for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++)
 		if (value0 & VFE_0_IRQ_STATUS_0_line_n_REG_UPDATE(i))
 			vfe->isr_ops.reg_update(vfe, i);
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-vfe-480.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-vfe-480.c
@@ -15,6 +15,9 @@
 #include "camss.h"
 #include "camss-vfe.h"
 
+/* VFE 2/3 are lite and have a different register layout */
+#define IS_LITE		(vfe->res->is_lite)
+
 #define VFE_HW_VERSION			(0x00)
 
 #define VFE_GLOBAL_RESET_CMD		(vfe_is_lite(vfe) ? 0x0c : 0x1c)
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-vfe-690.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-vfe-690.c
@@ -0,0 +1,410 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * camss-vfe-690.c
+ *
+ * Qualcomm MSM Camera Subsystem - VFE (Video Front End) Module v690 (SA8755P)
+ *
+ * Copyright (C) 2020-2021 Linaro Ltd.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+
+#include "camss.h"
+#include "camss-vfe.h"
+
+#define VFE_HW_VERSION                  (0x0)
+#define HW_VERSION_STEPPING		(0x0)
+#define HW_VERSION_REVISION		(0x10)
+#define HW_VERSION_GENERATION		(0x1C)
+#define VFE_TOP_CORE_CFG		(0x24)
+
+#define BUS_REG_BASE			(vfe_is_lite(vfe) ? 0x480 : 0x400)
+
+#define VFE_BUS_WM_CGC_OVERRIDE		(BUS_REG_BASE + 0x08)
+#define	WM_CGC_OVERRIDE_ALL		(0x7FFFFFF)
+
+#define VFE_BUS_WM_TEST_BUS_CTRL	(BUS_REG_BASE + 0xFC)
+
+#define VFE_BUS_WM_CFG(n)		(BUS_REG_BASE + 0x200 + (n) * 0x100)
+#define		WM_CFG_EN			BIT(0)
+#define		WM_CFG_MODE			BIT(16)
+#define VFE_BUS_WM_IMAGE_ADDR(n)	(BUS_REG_BASE + 0x204 + (n) * 0x100)
+#define VFE_BUS_WM_FRAME_INCR(n)	(BUS_REG_BASE + 0x208 + (n) * 0x100)
+#define VFE_BUS_WM_IMAGE_CFG_0(n)	(BUS_REG_BASE + 0x20c + (n) * 0x100)
+#define		WM_IMAGE_CFG_0_DEFAULT_WIDTH	(0xFFFF)
+#define		WM_IMAGE_CFG_0_DEFAULT_HEIGHT	(0xFFFF)
+#define VFE_BUS_WM_IMAGE_CFG_1(n)	(BUS_REG_BASE + 0x210 + (n) * 0x100)
+#define VFE_BUS_WM_IMAGE_CFG_2(n)	(BUS_REG_BASE + 0x214 + (n) * 0x100)
+#define		WM_IMAGE_CFG_2_DEFAULT_STRIDE	(0xFFFF)
+#define VFE_BUS_WM_PACKER_CFG(n)	(BUS_REG_BASE + 0x218 + (n) * 0x100)
+#define VFE_BUS_WM_HEADER_ADDR(n)	(BUS_REG_BASE + 0x220 + (n) * 0x100)
+#define VFE_BUS_WM_HEADER_INCR(n)	(BUS_REG_BASE + 0x224 + (n) * 0x100)
+#define VFE_BUS_WM_HEADER_CFG(n)	(BUS_REG_BASE + 0x228 + (n) * 0x100)
+
+#define VFE_BUS_WM_IRQ_SUBSAMPLE_PERIOD(n)	(BUS_REG_BASE + 0x230 + (n) * 0x100)
+#define VFE_BUS_WM_IRQ_SUBSAMPLE_PATTERN(n)	(BUS_REG_BASE + 0x234 + (n) * 0x100)
+#define VFE_BUS_WM_FRAMEDROP_PERIOD(n)		(BUS_REG_BASE + 0x238 + (n) * 0x100)
+#define VFE_BUS_WM_FRAMEDROP_PATTERN(n)		(BUS_REG_BASE + 0x23c + (n) * 0x100)
+
+#define VFE_BUS_WM_MMU_PREFETCH_CFG(n)		(BUS_REG_BASE + 0x260 + (n) * 0x100)
+#define VFE_BUS_WM_MMU_PREFETCH_MAX_OFFSET(n)	(BUS_REG_BASE + 0x264 + (n) * 0x100)
+#define VFE_BUS_WM_SYSTEM_CACHE_CFG(n)		(BUS_REG_BASE + 0x268 + (n) * 0x100)
+
+#define VFE_BUS_WM_STATUS_DEBUG_CFG(n)		(BUS_REG_BASE + 0x280 + (n) * 0x100)
+
+/* for titan 690, each bus client is hardcoded to a specific path */
+#define RDI_WM(n)			((vfe_is_lite(vfe) ? 0x0 : 0x10) + (n))
+
+static void vfe_wm_start(struct vfe_device *vfe, u8 wm, struct vfe_line *line)
+{
+	struct v4l2_pix_format_mplane *pix =
+		&line->video_out.active_fmt.fmt.pix_mp;
+
+	wm = RDI_WM(wm);
+
+	writel(WM_CGC_OVERRIDE_ALL, vfe->base + VFE_BUS_WM_CGC_OVERRIDE);
+	/* no clock gating at bus input */
+	writel(0x0, vfe->base + VFE_BUS_WM_TEST_BUS_CTRL);
+
+	writel(ALIGN(pix->plane_fmt[0].bytesperline, 16) * pix->height,
+	       vfe->base + VFE_BUS_WM_FRAME_INCR(wm));
+	writel(WM_IMAGE_CFG_0_DEFAULT_WIDTH & 0xFFFF,
+	       vfe->base + VFE_BUS_WM_IMAGE_CFG_0(wm));
+	writel(WM_IMAGE_CFG_2_DEFAULT_STRIDE,
+	       vfe->base + VFE_BUS_WM_IMAGE_CFG_2(wm));
+
+	writel(0x0, vfe->base + VFE_BUS_WM_PACKER_CFG(wm));
+
+	/* TOP CORE CFG */
+	writel(0x600000, vfe->base + VFE_TOP_CORE_CFG);
+
+	/* Enable WM in frame based mode */
+	writel(WM_CFG_EN | WM_CFG_MODE, vfe->base + VFE_BUS_WM_CFG(wm));
+}
+
+static void vfe_wm_stop(struct vfe_device *vfe, u8 wm)
+{
+	wm = RDI_WM(wm); /* map to actual WM used (from wm=RDI index) */
+	writel(0, vfe->base + VFE_BUS_WM_CFG(wm));
+}
+
+static void vfe_wm_update(struct vfe_device *vfe, u8 wm, u32 addr,
+			  struct vfe_line *line)
+{
+	wm = RDI_WM(wm); /* map to actual WM used (from wm=RDI index) */
+	writel(addr, vfe->base + VFE_BUS_WM_IMAGE_ADDR(wm));
+}
+
+static void vfe_reg_update(struct vfe_device *vfe, enum vfe_line_id line_id)
+{
+	int port_id = line_id;
+
+	/* RUP(register update) registers has beem moved to CSID in Titan 690.
+	 * Notify the event of trigger RUP.
+	 */
+	camss_reg_update(vfe->camss, vfe->id, port_id, false);
+}
+
+static inline void vfe_reg_update_clear(struct vfe_device *vfe,
+					enum vfe_line_id line_id)
+{
+	int port_id = line_id;
+
+	/* RUP(register update) registers has beem moved to CSID in Titan 690.
+	 * Notify the event of trigger RUP clear.
+	 */
+	camss_reg_update(vfe->camss, vfe->id, port_id, true);
+}
+
+
+/*
+ * vfe_hw_version - Process write master done interrupt
+ * @vfe: VFE Device
+ *
+ * Return vfe hw version
+ */
+static u32 vfe_hw_version(struct vfe_device *vfe)
+{
+	u32 hw_version = readl_relaxed(vfe->base + VFE_HW_VERSION);
+
+	u32 gen = (hw_version >> HW_VERSION_GENERATION) & 0xF;
+	u32 rev = (hw_version >> HW_VERSION_REVISION) & 0xFFF;
+	u32 step = (hw_version >> HW_VERSION_STEPPING) & 0xFFFF;
+
+	dev_info(vfe->camss->dev, "VFE:%d HW Version = %u.%u.%u\n",
+		 vfe->id, gen, rev, step);
+
+	return hw_version;
+}
+
+/*
+ * vfe_buf_done - Process write master done interrupt
+ * @vfe: VFE Device
+ * @wm: Write master id
+ */
+static void vfe_buf_done(struct vfe_device *vfe, int wm)
+{
+	struct vfe_line *line = &vfe->line[vfe->wm_output_map[wm]];
+	struct camss_buffer *ready_buf;
+	struct vfe_output *output;
+	unsigned long flags;
+	u32 index;
+	u64 ts = ktime_get_ns();
+
+	spin_lock_irqsave(&vfe->output_lock, flags);
+
+	if (vfe->wm_output_map[wm] == VFE_LINE_NONE) {
+		dev_err_ratelimited(vfe->camss->dev,
+				    "Received wm done for unmapped index\n");
+		goto out_unlock;
+	}
+	output = &vfe->line[vfe->wm_output_map[wm]].output;
+
+	ready_buf = output->buf[0];
+	if (!ready_buf) {
+		dev_err_ratelimited(vfe->camss->dev,
+				    "Missing ready buf %d!\n", output->state);
+		goto out_unlock;
+	}
+
+	ready_buf->vb.vb2_buf.timestamp = ts;
+	ready_buf->vb.sequence = output->sequence++;
+
+	index = 0;
+	output->buf[0] = output->buf[1];
+	if (output->buf[0])
+		index = 1;
+
+	output->buf[index] = vfe_buf_get_pending(output);
+
+	if (output->buf[index]) {
+		vfe->res->hw_ops->vfe_wm_update(vfe, output->wm_idx[0],
+						output->buf[index]->addr[0],
+						line);
+		vfe->res->hw_ops->reg_update(vfe, line->id);
+	} else
+		output->gen2.active_num--;
+
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+	vb2_buffer_done(&ready_buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
+
+	return;
+
+out_unlock:
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+}
+
+static int vfe_enable_output_v2(struct vfe_line *line)
+{
+	struct vfe_device *vfe = to_vfe(line);
+	struct vfe_output *output = &line->output;
+	const struct vfe_hw_ops *ops = vfe->res->hw_ops;
+	struct media_entity *sensor;
+	unsigned long flags;
+	unsigned int frame_skip = 0;
+	unsigned int i;
+
+	sensor = camss_find_sensor(&line->subdev.entity);
+	if (sensor) {
+		struct v4l2_subdev *subdev = media_entity_to_v4l2_subdev(sensor);
+
+		v4l2_subdev_call(subdev, sensor, g_skip_frames, &frame_skip);
+		/* Max frame skip is 29 frames */
+		if (frame_skip > VFE_FRAME_DROP_VAL - 1)
+			frame_skip = VFE_FRAME_DROP_VAL - 1;
+	}
+
+	spin_lock_irqsave(&vfe->output_lock, flags);
+
+	ops->reg_update_clear(vfe, line->id);
+
+	if (output->state > VFE_OUTPUT_RESERVED) {
+		dev_err(vfe->camss->dev,
+			"Output is not in reserved state %d\n",
+			output->state);
+		spin_unlock_irqrestore(&vfe->output_lock, flags);
+		return -EINVAL;
+	}
+
+	WARN_ON(output->gen2.active_num);
+
+	output->state = VFE_OUTPUT_ON;
+
+	output->sequence = 0;
+	output->wait_reg_update = 0;
+	reinit_completion(&output->reg_update);
+
+	ops->vfe_wm_start(vfe, output->wm_idx[0], line);
+
+	for (i = 0; i < 2; i++) {
+		output->buf[i] = vfe_buf_get_pending(output);
+		if (!output->buf[i])
+			break;
+		output->gen2.active_num++;
+		ops->vfe_wm_update(vfe, output->wm_idx[0],
+				   output->buf[i]->addr[0], line);
+		ops->reg_update(vfe, line->id);
+	}
+
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+	return 0;
+}
+
+/*
+ * vfe_queue_buffer_v2 - Add empty buffer
+ * @vid: Video device structure
+ * @buf: Buffer to be enqueued
+ *
+ * Add an empty buffer - depending on the current number of buffers it will be
+ * put in pending buffer queue or directly given to the hardware to be filled.
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int vfe_queue_buffer_v2(struct camss_video *vid,
+			struct camss_buffer *buf)
+{
+	struct vfe_line *line = container_of(vid, struct vfe_line, video_out);
+	struct vfe_device *vfe = to_vfe(line);
+	struct vfe_output *output;
+	unsigned long flags;
+
+	output = &line->output;
+
+	spin_lock_irqsave(&vfe->output_lock, flags);
+
+	if (output->state == VFE_OUTPUT_ON &&
+		output->gen2.active_num < 2) {
+		output->buf[output->gen2.active_num++] = buf;
+		vfe->res->hw_ops->vfe_wm_update(vfe, output->wm_idx[0],
+						buf->addr[0], line);
+		vfe->res->hw_ops->reg_update(vfe, line->id);
+	} else {
+		vfe_buf_add_pending(output, buf);
+	}
+
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+	return 0;
+}
+
+/*
+ * vfe_get_output_v2 - Get vfe output port for corresponding VFE line
+ * @line: VFE line
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int vfe_get_output_v2(struct vfe_line *line)
+{
+	struct vfe_device *vfe = to_vfe(line);
+	struct vfe_output *output;
+	unsigned long flags;
+
+	spin_lock_irqsave(&vfe->output_lock, flags);
+
+	output = &line->output;
+	if (output->state > VFE_OUTPUT_RESERVED) {
+		dev_err(vfe->camss->dev, "Output is running\n");
+		goto error;
+	}
+
+	output->wm_num = 1;
+
+	/* Correspondence between VFE line number and WM number.
+	 * line 0 -> RDI 0, line 1 -> RDI1, line 2 -> RDI2, line 3 -> PIX/RDI3
+	 * Note this 1:1 mapping will not work for PIX streams.
+	 */
+	output->wm_idx[0] = line->id;
+	vfe->wm_output_map[line->id] = line->id;
+
+	output->drop_update_idx = 0;
+
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+
+	return 0;
+
+error:
+	spin_unlock_irqrestore(&vfe->output_lock, flags);
+	output->state = VFE_OUTPUT_OFF;
+
+	return -EINVAL;
+}
+
+/*
+ * vfe_enable_v2 - Enable streaming on VFE line
+ * @line: VFE line
+ *
+ * Return 0 on success or a negative error code otherwise
+ */
+static int vfe_enable_v2(struct vfe_line *line)
+{
+	struct vfe_device *vfe = to_vfe(line);
+	int ret;
+
+	mutex_lock(&vfe->stream_lock);
+
+	if (vfe->res->hw_ops->enable_irq_common)
+		vfe->res->hw_ops->enable_irq_common(vfe);
+
+	vfe->stream_count++;
+
+	mutex_unlock(&vfe->stream_lock);
+
+	ret = vfe_get_output_v2(line);
+	if (ret < 0)
+		goto error_get_output;
+
+	ret = vfe_enable_output_v2(line);
+	if (ret < 0)
+		goto error_enable_output;
+
+	vfe->was_streaming = 1;
+
+	return 0;
+
+error_enable_output:
+	vfe_put_output(line);
+
+error_get_output:
+	mutex_lock(&vfe->stream_lock);
+
+	vfe->stream_count--;
+
+	mutex_unlock(&vfe->stream_lock);
+
+	return ret;
+}
+
+
+static const struct camss_video_ops vfe_video_ops_690 = {
+	.queue_buffer = vfe_queue_buffer_v2,
+	.flush_buffers = vfe_flush_buffers,
+};
+
+static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
+{
+	vfe->video_ops = vfe_video_ops_690;
+}
+
+const struct vfe_hw_ops vfe_ops_690 = {
+	.enable_irq_common = NULL,
+	.global_reset = NULL,
+	.hw_version = vfe_hw_version,
+	.isr = NULL,
+	.pm_domain_off = vfe_pm_domain_off,
+	.pm_domain_on = vfe_pm_domain_on,
+	.reg_update = vfe_reg_update,
+	.reg_update_clear = vfe_reg_update_clear,
+	.subdev_init = vfe_subdev_init,
+	.vfe_disable = vfe_disable,
+	.vfe_enable = vfe_enable_v2,
+	.vfe_halt = NULL,
+	.vfe_wm_start = vfe_wm_start,
+	.vfe_wm_stop = vfe_wm_stop,
+	.vfe_buf_done = vfe_buf_done,
+	.vfe_wm_update = vfe_wm_update,
+};
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-vfe-gen1.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-vfe-gen1.c
@@ -37,7 +37,7 @@
 {
 	struct vfe_device *vfe = to_vfe(line);
 	struct vfe_output *output = &line->output;
-	const struct vfe_hw_ops *ops = vfe->ops;
+	const struct vfe_hw_ops *ops = vfe->res->hw_ops;
 	unsigned long flags;
 	unsigned long time;
 	unsigned int i;
@@ -162,14 +162,14 @@
 		vfe->ops_gen1->wm_set_framedrop_pattern(vfe, output->wm_idx[i], drop_pattern);
 	}
 
-	vfe->ops->reg_update(vfe, container_of(output, struct vfe_line, output)->id);
+	vfe->res->hw_ops->reg_update(vfe, container_of(output, struct vfe_line, output)->id);
 }
 
 static int vfe_enable_output(struct vfe_line *line)
 {
 	struct vfe_device *vfe = to_vfe(line);
 	struct vfe_output *output = &line->output;
-	const struct vfe_hw_ops *ops = vfe->ops;
+	const struct vfe_hw_ops *ops = vfe->res->hw_ops;
 	struct media_entity *sensor;
 	unsigned long flags;
 	unsigned int frame_skip = 0;
@@ -545,7 +545,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&vfe->output_lock, flags);
-	vfe->ops->reg_update_clear(vfe, line_id);
+	vfe->res->hw_ops->reg_update_clear(vfe, line_id);
 
 	output = &line->output;
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-vfe.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -32,139 +32,251 @@
 
 #define SCALER_RATIO_MAX 16
 
-struct vfe_format {
-	u32 code;
-	u8 bpp;
+static const struct camss_format_info formats_rdi_8x16[] = {
+	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_UYVY, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_VYUY, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_YUYV, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_YVYU, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_SBGGR8_1X8, 8, V4L2_PIX_FMT_SBGGR8, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
+	{ MEDIA_BUS_FMT_SGBRG8_1X8, 8, V4L2_PIX_FMT_SGBRG8, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
+	{ MEDIA_BUS_FMT_SGRBG8_1X8, 8, V4L2_PIX_FMT_SGRBG8, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
+	{ MEDIA_BUS_FMT_SRGGB8_1X8, 8, V4L2_PIX_FMT_SRGGB8, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
+	{ MEDIA_BUS_FMT_SBGGR10_1X10, 10, V4L2_PIX_FMT_SBGGR10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
+	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10, V4L2_PIX_FMT_SGBRG10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
+	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10, V4L2_PIX_FMT_SGRBG10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
+	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10, V4L2_PIX_FMT_SRGGB10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
+	{ MEDIA_BUS_FMT_SBGGR12_1X12, 12, V4L2_PIX_FMT_SBGGR12P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
+	{ MEDIA_BUS_FMT_SGBRG12_1X12, 12, V4L2_PIX_FMT_SGBRG12P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
+	{ MEDIA_BUS_FMT_SGRBG12_1X12, 12, V4L2_PIX_FMT_SGRBG12P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
+	{ MEDIA_BUS_FMT_SRGGB12_1X12, 12, V4L2_PIX_FMT_SRGGB12P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
+	{ MEDIA_BUS_FMT_Y10_1X10, 10, V4L2_PIX_FMT_Y10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
 };
 
-static const struct vfe_format formats_rdi_8x16[] = {
-	{ MEDIA_BUS_FMT_UYVY8_1X16, 8 },
-	{ MEDIA_BUS_FMT_VYUY8_1X16, 8 },
-	{ MEDIA_BUS_FMT_YUYV8_1X16, 8 },
-	{ MEDIA_BUS_FMT_YVYU8_1X16, 8 },
-	{ MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
-	{ MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
-	{ MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
-	{ MEDIA_BUS_FMT_SRGGB8_1X8, 8 },
-	{ MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
-	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
-	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
-	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
-	{ MEDIA_BUS_FMT_SBGGR12_1X12, 12 },
-	{ MEDIA_BUS_FMT_SGBRG12_1X12, 12 },
-	{ MEDIA_BUS_FMT_SGRBG12_1X12, 12 },
-	{ MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
-	{ MEDIA_BUS_FMT_Y10_1X10, 10 },
+static const struct camss_format_info formats_rdi_8x96[] = {
+	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_UYVY, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_VYUY, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_YUYV, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_YVYU, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_SBGGR8_1X8, 8, V4L2_PIX_FMT_SBGGR8, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
+	{ MEDIA_BUS_FMT_SGBRG8_1X8, 8, V4L2_PIX_FMT_SGBRG8, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
+	{ MEDIA_BUS_FMT_SGRBG8_1X8, 8, V4L2_PIX_FMT_SGRBG8, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
+	{ MEDIA_BUS_FMT_SRGGB8_1X8, 8, V4L2_PIX_FMT_SRGGB8, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
+	{ MEDIA_BUS_FMT_SBGGR10_1X10, 10, V4L2_PIX_FMT_SBGGR10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
+	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10, V4L2_PIX_FMT_SGBRG10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
+	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10, V4L2_PIX_FMT_SGRBG10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
+	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10, V4L2_PIX_FMT_SRGGB10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
+	{ MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16, V4L2_PIX_FMT_SBGGR10, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_SBGGR12_1X12, 12, V4L2_PIX_FMT_SBGGR12P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
+	{ MEDIA_BUS_FMT_SGBRG12_1X12, 12, V4L2_PIX_FMT_SGBRG12P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
+	{ MEDIA_BUS_FMT_SGRBG12_1X12, 12, V4L2_PIX_FMT_SGRBG12P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
+	{ MEDIA_BUS_FMT_SRGGB12_1X12, 12, V4L2_PIX_FMT_SRGGB12P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
+	{ MEDIA_BUS_FMT_SBGGR14_1X14, 14, V4L2_PIX_FMT_SBGGR14P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
+	{ MEDIA_BUS_FMT_SGBRG14_1X14, 14, V4L2_PIX_FMT_SGBRG14P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
+	{ MEDIA_BUS_FMT_SGRBG14_1X14, 14, V4L2_PIX_FMT_SGRBG14P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
+	{ MEDIA_BUS_FMT_SRGGB14_1X14, 14, V4L2_PIX_FMT_SRGGB14P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
+	{ MEDIA_BUS_FMT_Y10_1X10, 10, V4L2_PIX_FMT_Y10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
+	{ MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16, V4L2_PIX_FMT_Y10, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
 };
 
-static const struct vfe_format formats_pix_8x16[] = {
-	{ MEDIA_BUS_FMT_UYVY8_1X16, 8 },
-	{ MEDIA_BUS_FMT_VYUY8_1X16, 8 },
-	{ MEDIA_BUS_FMT_YUYV8_1X16, 8 },
-	{ MEDIA_BUS_FMT_YVYU8_1X16, 8 },
+static const struct camss_format_info formats_rdi_845[] = {
+	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_UYVY, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_VYUY, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_YUYV, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_YVYU, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_SBGGR8_1X8, 8, V4L2_PIX_FMT_SBGGR8, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
+	{ MEDIA_BUS_FMT_SGBRG8_1X8, 8, V4L2_PIX_FMT_SGBRG8, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
+	{ MEDIA_BUS_FMT_SGRBG8_1X8, 8, V4L2_PIX_FMT_SGRBG8, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
+	{ MEDIA_BUS_FMT_SRGGB8_1X8, 8, V4L2_PIX_FMT_SRGGB8, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
+	{ MEDIA_BUS_FMT_SBGGR10_1X10, 10, V4L2_PIX_FMT_SBGGR10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
+	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10, V4L2_PIX_FMT_SGBRG10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
+	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10, V4L2_PIX_FMT_SGRBG10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
+	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10, V4L2_PIX_FMT_SRGGB10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
+	{ MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16, V4L2_PIX_FMT_SBGGR10, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_SBGGR12_1X12, 12, V4L2_PIX_FMT_SBGGR12P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
+	{ MEDIA_BUS_FMT_SGBRG12_1X12, 12, V4L2_PIX_FMT_SGBRG12P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
+	{ MEDIA_BUS_FMT_SGRBG12_1X12, 12, V4L2_PIX_FMT_SGRBG12P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
+	{ MEDIA_BUS_FMT_SRGGB12_1X12, 12, V4L2_PIX_FMT_SRGGB12P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 12) },
+	{ MEDIA_BUS_FMT_SBGGR14_1X14, 14, V4L2_PIX_FMT_SBGGR14P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
+	{ MEDIA_BUS_FMT_SGBRG14_1X14, 14, V4L2_PIX_FMT_SGBRG14P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
+	{ MEDIA_BUS_FMT_SGRBG14_1X14, 14, V4L2_PIX_FMT_SGRBG14P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
+	{ MEDIA_BUS_FMT_SRGGB14_1X14, 14, V4L2_PIX_FMT_SRGGB14P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 14) },
+	{ MEDIA_BUS_FMT_Y8_1X8, 8, V4L2_PIX_FMT_GREY, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 8) },
+	{ MEDIA_BUS_FMT_Y10_1X10, 10, V4L2_PIX_FMT_Y10P, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 10) },
+	{ MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16, V4L2_PIX_FMT_Y10, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
 };
 
-static const struct vfe_format formats_rdi_8x96[] = {
-	{ MEDIA_BUS_FMT_UYVY8_1X16, 8 },
-	{ MEDIA_BUS_FMT_VYUY8_1X16, 8 },
-	{ MEDIA_BUS_FMT_YUYV8_1X16, 8 },
-	{ MEDIA_BUS_FMT_YVYU8_1X16, 8 },
-	{ MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
-	{ MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
-	{ MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
-	{ MEDIA_BUS_FMT_SRGGB8_1X8, 8 },
-	{ MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
-	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
-	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
-	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
-	{ MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16 },
-	{ MEDIA_BUS_FMT_SBGGR12_1X12, 12 },
-	{ MEDIA_BUS_FMT_SGBRG12_1X12, 12 },
-	{ MEDIA_BUS_FMT_SGRBG12_1X12, 12 },
-	{ MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
-	{ MEDIA_BUS_FMT_SBGGR14_1X14, 14 },
-	{ MEDIA_BUS_FMT_SGBRG14_1X14, 14 },
-	{ MEDIA_BUS_FMT_SGRBG14_1X14, 14 },
-	{ MEDIA_BUS_FMT_SRGGB14_1X14, 14 },
-	{ MEDIA_BUS_FMT_Y10_1X10, 10 },
-	{ MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16 },
+static const struct camss_format_info formats_pix_8x16[] = {
+	{ MEDIA_BUS_FMT_YUYV8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_YVYU8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_UYVY8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_VYUY8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_YUYV8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_YVYU8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_UYVY8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_VYUY8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
 };
 
-static const struct vfe_format formats_pix_8x96[] = {
-	{ MEDIA_BUS_FMT_UYVY8_1X16, 8 },
-	{ MEDIA_BUS_FMT_VYUY8_1X16, 8 },
-	{ MEDIA_BUS_FMT_YUYV8_1X16, 8 },
-	{ MEDIA_BUS_FMT_YVYU8_1X16, 8 },
+static const struct camss_format_info formats_pix_8x96[] = {
+	{ MEDIA_BUS_FMT_YUYV8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_YVYU8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_UYVY8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_VYUY8_1_5X8, 8, V4L2_PIX_FMT_NV12, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_YUYV8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_YVYU8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_UYVY8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_VYUY8_1_5X8, 8, V4L2_PIX_FMT_NV21, 1,
+	  PER_PLANE_DATA(0, 1, 1, 2, 3, 8) },
+	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_NV16, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_NV61, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 2, 8) },
+	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, V4L2_PIX_FMT_UYVY, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_VYUY8_1X16, 8, V4L2_PIX_FMT_VYUY, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, V4L2_PIX_FMT_YUYV, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
+	{ MEDIA_BUS_FMT_YVYU8_1X16, 8, V4L2_PIX_FMT_YVYU, 1,
+	  PER_PLANE_DATA(0, 1, 1, 1, 1, 16) },
 };
 
-static const struct vfe_format formats_rdi_845[] = {
-	{ MEDIA_BUS_FMT_UYVY8_1X16, 8 },
-	{ MEDIA_BUS_FMT_VYUY8_1X16, 8 },
-	{ MEDIA_BUS_FMT_YUYV8_1X16, 8 },
-	{ MEDIA_BUS_FMT_YVYU8_1X16, 8 },
-	{ MEDIA_BUS_FMT_SBGGR8_1X8, 8 },
-	{ MEDIA_BUS_FMT_SGBRG8_1X8, 8 },
-	{ MEDIA_BUS_FMT_SGRBG8_1X8, 8 },
-	{ MEDIA_BUS_FMT_SRGGB8_1X8, 8 },
-	{ MEDIA_BUS_FMT_SBGGR10_1X10, 10 },
-	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10 },
-	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10 },
-	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10 },
-	{ MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, 16 },
-	{ MEDIA_BUS_FMT_SBGGR12_1X12, 12 },
-	{ MEDIA_BUS_FMT_SGBRG12_1X12, 12 },
-	{ MEDIA_BUS_FMT_SGRBG12_1X12, 12 },
-	{ MEDIA_BUS_FMT_SRGGB12_1X12, 12 },
-	{ MEDIA_BUS_FMT_SBGGR14_1X14, 14 },
-	{ MEDIA_BUS_FMT_SGBRG14_1X14, 14 },
-	{ MEDIA_BUS_FMT_SGRBG14_1X14, 14 },
-	{ MEDIA_BUS_FMT_SRGGB14_1X14, 14 },
-	{ MEDIA_BUS_FMT_Y8_1X8, 8 },
-	{ MEDIA_BUS_FMT_Y10_1X10, 10 },
-	{ MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, 16 },
+const struct camss_formats vfe_formats_rdi_8x16 = {
+	.nformats = ARRAY_SIZE(formats_rdi_8x16),
+	.formats = formats_rdi_8x16
 };
 
-/*
- * vfe_get_bpp - map media bus format to bits per pixel
- * @formats: supported media bus formats array
- * @nformats: size of @formats array
- * @code: media bus format code
- *
- * Return number of bits per pixel
- */
-static u8 vfe_get_bpp(const struct vfe_format *formats,
-		      unsigned int nformats, u32 code)
-{
-	unsigned int i;
-
-	for (i = 0; i < nformats; i++)
-		if (code == formats[i].code)
-			return formats[i].bpp;
-
-	WARN(1, "Unknown format\n");
-
-	return formats[0].bpp;
-}
+const struct camss_formats vfe_formats_pix_8x16 = {
+	.nformats = ARRAY_SIZE(formats_pix_8x16),
+	.formats = formats_pix_8x16
+};
 
-static u32 vfe_find_code(u32 *code, unsigned int n_code,
-			 unsigned int index, u32 req_code)
-{
-	int i;
+const struct camss_formats vfe_formats_rdi_8x96 = {
+	.nformats = ARRAY_SIZE(formats_rdi_8x96),
+	.formats = formats_rdi_8x96
+};
 
-	if (!req_code && (index >= n_code))
-		return 0;
+const struct camss_formats vfe_formats_pix_8x96 = {
+	.nformats = ARRAY_SIZE(formats_pix_8x96),
+	.formats = formats_pix_8x96
+};
 
-	for (i = 0; i < n_code; i++)
-		if (req_code) {
-			if (req_code == code[i])
-				return req_code;
-		} else {
-			if (i == index)
-				return code[i];
-		}
+const struct camss_formats vfe_formats_rdi_845 = {
+	.nformats = ARRAY_SIZE(formats_rdi_845),
+	.formats = formats_rdi_845
+};
 
-	return code[0];
-}
+/* TODO: Replace with pix formats */
+const struct camss_formats vfe_formats_pix_845 = {
+	.nformats = ARRAY_SIZE(formats_rdi_845),
+	.formats = formats_rdi_845
+};
 
 static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
 			    unsigned int index, u32 src_req_code)
@@ -181,8 +293,8 @@
 				MEDIA_BUS_FMT_YUYV8_1_5X8,
 			};
 
-			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
-					     index, src_req_code);
+			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
+						      index, src_req_code);
 		}
 		case MEDIA_BUS_FMT_YVYU8_1X16:
 		{
@@ -191,8 +303,8 @@
 				MEDIA_BUS_FMT_YVYU8_1_5X8,
 			};
 
-			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
-					     index, src_req_code);
+			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
+						      index, src_req_code);
 		}
 		case MEDIA_BUS_FMT_UYVY8_1X16:
 		{
@@ -201,8 +313,8 @@
 				MEDIA_BUS_FMT_UYVY8_1_5X8,
 			};
 
-			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
-					     index, src_req_code);
+			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
+						      index, src_req_code);
 		}
 		case MEDIA_BUS_FMT_VYUY8_1X16:
 		{
@@ -211,8 +323,8 @@
 				MEDIA_BUS_FMT_VYUY8_1_5X8,
 			};
 
-			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
-					     index, src_req_code);
+			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
+						      index, src_req_code);
 		}
 		default:
 			if (index > 0)
@@ -221,10 +333,14 @@
 			return sink_code;
 		}
 		break;
-	case CAMSS_8x96:
 	case CAMSS_660:
-	case CAMSS_845:
+	case CAMSS_7280:
+	case CAMSS_8x96:
 	case CAMSS_8250:
+	case CAMSS_8280XP:
+	case CAMSS_845:
+	case CAMSS_8775P:
+	case CAMSS_8300:
 		switch (sink_code) {
 		case MEDIA_BUS_FMT_YUYV8_1X16:
 		{
@@ -236,8 +352,8 @@
 				MEDIA_BUS_FMT_YUYV8_1_5X8,
 			};
 
-			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
-					     index, src_req_code);
+			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
+						      index, src_req_code);
 		}
 		case MEDIA_BUS_FMT_YVYU8_1X16:
 		{
@@ -249,8 +365,8 @@
 				MEDIA_BUS_FMT_YVYU8_1_5X8,
 			};
 
-			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
-					     index, src_req_code);
+			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
+						      index, src_req_code);
 		}
 		case MEDIA_BUS_FMT_UYVY8_1X16:
 		{
@@ -262,8 +378,8 @@
 				MEDIA_BUS_FMT_UYVY8_1_5X8,
 			};
 
-			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
-					     index, src_req_code);
+			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
+						      index, src_req_code);
 		}
 		case MEDIA_BUS_FMT_VYUY8_1X16:
 		{
@@ -275,8 +391,8 @@
 				MEDIA_BUS_FMT_VYUY8_1_5X8,
 			};
 
-			return vfe_find_code(src_code, ARRAY_SIZE(src_code),
-					     index, src_req_code);
+			return camss_format_find_code(src_code, ARRAY_SIZE(src_code),
+						      index, src_req_code);
 		}
 		default:
 			if (index > 0)
@@ -293,15 +409,17 @@
 {
 	unsigned long time;
 
-	reinit_completion(&vfe->reset_complete);
+	if (vfe->res->hw_ops->global_reset) {
+		reinit_completion(&vfe->reset_complete);
 
-	vfe->ops->global_reset(vfe);
+		vfe->res->hw_ops->global_reset(vfe);
 
-	time = wait_for_completion_timeout(&vfe->reset_complete,
-		msecs_to_jiffies(VFE_RESET_TIMEOUT_MS));
-	if (!time) {
-		dev_err(vfe->camss->dev, "VFE reset timeout\n");
-		return -EIO;
+		time = wait_for_completion_timeout(&vfe->reset_complete,
+			msecs_to_jiffies(VFE_RESET_TIMEOUT_MS));
+		if (!time) {
+			dev_err(vfe->camss->dev, "VFE reset timeout\n");
+			return -EIO;
+		}
 	}
 
 	return 0;
@@ -311,7 +429,7 @@
 {
 	int i;
 
-	for (i = 0; i < vfe->line_num; i++) {
+	for (i = 0; i < vfe->res->line_num; i++) {
 		struct vfe_output *output = &vfe->line[i].output;
 
 		output->state = VFE_OUTPUT_OFF;
@@ -420,7 +538,7 @@
 
 	spin_lock_irqsave(&vfe->output_lock, flags);
 	for (i = 0; i < output->wm_num; i++)
-		vfe->ops->vfe_wm_stop(vfe, output->wm_idx[i]);
+		vfe->res->hw_ops->vfe_wm_stop(vfe, output->wm_idx[i]);
 	output->gen2.active_num = 0;
 	spin_unlock_irqrestore(&vfe->output_lock, flags);
 
@@ -520,7 +638,8 @@
 
 	return (!strcmp(clock->name, vfe_name) ||
 		!strcmp(clock->name, vfe_lite_name) ||
-		!strcmp(clock->name, "vfe_lite"));
+		!strcmp(clock->name, "vfe_lite") ||
+		!strcmp(clock->name, "camnoc_axi"));
 }
 
 /*
@@ -536,7 +655,7 @@
 	int i, j;
 	int ret;
 
-	for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
+	for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) {
 		ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity,
 					    &pixel_clock[i]);
 		if (ret)
@@ -550,7 +669,7 @@
 			u64 min_rate = 0;
 			long rate;
 
-			for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) {
+			for (j = VFE_LINE_RDI0; j < vfe->res->line_num; j++) {
 				u32 tmp;
 				u8 bpp;
 
@@ -559,9 +678,9 @@
 				} else {
 					struct vfe_line *l = &vfe->line[j];
 
-					bpp = vfe_get_bpp(l->formats,
-						l->nformats,
-						l->fmt[MSM_VFE_PAD_SINK].code);
+					bpp = camss_format_get_bpp(l->formats,
+								   l->nformats,
+								   l->fmt[MSM_VFE_PAD_SINK].code);
 					tmp = pixel_clock[j] * bpp / 64;
 				}
 
@@ -617,7 +736,7 @@
 	int i, j;
 	int ret;
 
-	for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
+	for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) {
 		ret = camss_get_pixel_clock(&vfe->line[i].subdev.entity,
 					    &pixel_clock[i]);
 		if (ret)
@@ -631,7 +750,7 @@
 			u64 min_rate = 0;
 			unsigned long rate;
 
-			for (j = VFE_LINE_RDI0; j < vfe->line_num; j++) {
+			for (j = VFE_LINE_RDI0; j < vfe->res->line_num; j++) {
 				u32 tmp;
 				u8 bpp;
 
@@ -640,9 +759,9 @@
 				} else {
 					struct vfe_line *l = &vfe->line[j];
 
-					bpp = vfe_get_bpp(l->formats,
-						l->nformats,
-						l->fmt[MSM_VFE_PAD_SINK].code);
+					bpp = camss_format_get_bpp(l->formats,
+								   l->nformats,
+								   l->fmt[MSM_VFE_PAD_SINK].code);
 					tmp = pixel_clock[j] * bpp / 64;
 				}
 
@@ -674,10 +793,11 @@
 	mutex_lock(&vfe->power_lock);
 
 	if (vfe->power_count == 0) {
-		ret = vfe->ops->pm_domain_on(vfe);
+		ret = vfe->res->hw_ops->pm_domain_on(vfe);
 		if (ret < 0)
 			goto error_pm_domain;
 
+		dev_pm_genpd_set_performance_state(vfe->camss->dev, RPMP_PERF_STATE_NOM);
 		ret = pm_runtime_resume_and_get(vfe->camss->dev);
 		if (ret < 0)
 			goto error_domain_off;
@@ -699,7 +819,7 @@
 
 		vfe_init_outputs(vfe);
 
-		vfe->ops->hw_version(vfe);
+		vfe->res->hw_ops->hw_version(vfe);
 	} else {
 		ret = vfe_check_clock_rates(vfe);
 		if (ret < 0)
@@ -717,7 +837,7 @@
 error_pm_runtime_get:
 	pm_runtime_put_sync(vfe->camss->dev);
 error_domain_off:
-	vfe->ops->pm_domain_off(vfe);
+	vfe->res->hw_ops->pm_domain_off(vfe);
 
 error_pm_domain:
 	mutex_unlock(&vfe->power_lock);
@@ -739,11 +859,12 @@
 	} else if (vfe->power_count == 1) {
 		if (vfe->was_streaming) {
 			vfe->was_streaming = 0;
-			vfe->ops->vfe_halt(vfe);
+			if (vfe->res->hw_ops->vfe_halt)
+				vfe->res->hw_ops->vfe_halt(vfe);
 		}
 		camss_disable_clocks(vfe->nclocks, vfe->clock);
 		pm_runtime_put_sync(vfe->camss->dev);
-		vfe->ops->pm_domain_off(vfe);
+		vfe->res->hw_ops->pm_domain_off(vfe);
 	}
 
 	vfe->power_count--;
@@ -833,12 +954,12 @@
 
 	if (enable) {
 		line->output.state = VFE_OUTPUT_RESERVED;
-		ret = vfe->ops->vfe_enable(line);
+		ret = vfe->res->hw_ops->vfe_enable(line);
 		if (ret < 0)
 			dev_err(vfe->camss->dev,
 				"Failed to enable vfe outputs\n");
 	} else {
-		ret = vfe->ops->vfe_disable(line);
+		ret = vfe->res->hw_ops->vfe_disable(line);
 		if (ret < 0)
 			dev_err(vfe->camss->dev,
 				"Failed to disable vfe outputs\n");
@@ -1375,23 +1496,24 @@
 	int i, j;
 	int ret;
 
-	vfe->ops = res->ops;
-
-	if (!res->line_num)
+	if (!res->vfe.line_num)
 		return -EINVAL;
 
+	vfe->res = &res->vfe;
+	vfe->res->hw_ops->subdev_init(dev, vfe);
+
 	/* Power domain */
 
-	if (res->pd_name) {
+	if (res->vfe.pd_name) {
 		vfe->genpd = dev_pm_domain_attach_by_name(camss->dev,
-							  res->pd_name);
+							  res->vfe.pd_name);
 		if (IS_ERR(vfe->genpd)) {
 			ret = PTR_ERR(vfe->genpd);
 			return ret;
 		}
 	}
 
-	if (!vfe->genpd && res->has_pd) {
+	if (!vfe->genpd && res->vfe.has_pd) {
 		/*
 		 * Legacy magic index.
 		 * Requires
@@ -1408,9 +1530,6 @@
 			return PTR_ERR(vfe->genpd);
 	}
 
-	vfe->line_num = res->line_num;
-	vfe->ops->subdev_init(dev, vfe);
-
 	/* Memory */
 
 	vfe->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]);
@@ -1428,11 +1547,13 @@
 	vfe->irq = ret;
 	snprintf(vfe->irq_name, sizeof(vfe->irq_name), "%s_%s%d",
 		 dev_name(dev), MSM_VFE_NAME, id);
-	ret = devm_request_irq(dev, vfe->irq, vfe->ops->isr,
-			       IRQF_TRIGGER_RISING, vfe->irq_name, vfe);
-	if (ret < 0) {
-		dev_err(dev, "request_irq failed: %d\n", ret);
-		return ret;
+	if (vfe->res->hw_ops->isr) {
+		ret = devm_request_irq(dev, vfe->irq, vfe->res->hw_ops->isr,
+				       IRQF_TRIGGER_RISING, vfe->irq_name, vfe);
+		if (ret < 0) {
+			dev_err(dev, "request_irq failed: %d\n", ret);
+			return ret;
+		}
 	}
 
 	/* Clocks */
@@ -1487,7 +1608,7 @@
 	vfe->id = id;
 	vfe->reg_update = 0;
 
-	for (i = VFE_LINE_RDI0; i < vfe->line_num; i++) {
+	for (i = VFE_LINE_RDI0; i < vfe->res->line_num; i++) {
 		struct vfe_line *l = &vfe->line[i];
 
 		l->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
@@ -1496,31 +1617,12 @@
 		init_completion(&l->output.sof);
 		init_completion(&l->output.reg_update);
 
-		switch (camss->res->version) {
-		case CAMSS_8x16:
-			if (i == VFE_LINE_PIX) {
-				l->formats = formats_pix_8x16;
-				l->nformats = ARRAY_SIZE(formats_pix_8x16);
-			} else {
-				l->formats = formats_rdi_8x16;
-				l->nformats = ARRAY_SIZE(formats_rdi_8x16);
-			}
-			break;
-		case CAMSS_8x96:
-		case CAMSS_660:
-			if (i == VFE_LINE_PIX) {
-				l->formats = formats_pix_8x96;
-				l->nformats = ARRAY_SIZE(formats_pix_8x96);
-			} else {
-				l->formats = formats_rdi_8x96;
-				l->nformats = ARRAY_SIZE(formats_rdi_8x96);
-			}
-			break;
-		case CAMSS_845:
-		case CAMSS_8250:
-			l->formats = formats_rdi_845;
-			l->nformats = ARRAY_SIZE(formats_rdi_845);
-			break;
+		if (i == VFE_LINE_PIX) {
+			l->nformats = res->vfe.formats_pix->nformats;
+			l->formats = res->vfe.formats_pix->formats;
+		} else {
+			l->nformats = res->vfe.formats_rdi->nformats;
+			l->formats = res->vfe.formats_rdi->formats;
 		}
 	}
 
@@ -1595,6 +1697,26 @@
 	.link_validate = v4l2_subdev_link_validate,
 };
 
+static int vfe_bpl_align(struct vfe_device *vfe)
+{
+	int ret = 8;
+
+	switch (vfe->camss->res->version) {
+	case CAMSS_7280:
+	case CAMSS_8250:
+	case CAMSS_8280XP:
+	case CAMSS_845:
+	case CAMSS_8775P:
+	case CAMSS_8300:
+		ret = 16;
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
 /*
  * msm_vfe_register_entities - Register subdev node for VFE module
  * @vfe: VFE device
@@ -1617,7 +1739,7 @@
 	int ret;
 	int i;
 
-	for (i = 0; i < vfe->line_num; i++) {
+	for (i = 0; i < vfe->res->line_num; i++) {
 		char name[32];
 
 		sd = &vfe->line[i].subdev;
@@ -1661,20 +1783,19 @@
 		}
 
 		video_out->ops = &vfe->video_ops;
-		if (vfe->camss->res->version == CAMSS_845 ||
-		    vfe->camss->res->version == CAMSS_8250)
-			video_out->bpl_alignment = 16;
-		else
-			video_out->bpl_alignment = 8;
+		video_out->bpl_alignment = vfe_bpl_align(vfe);
 		video_out->line_based = 0;
 		if (i == VFE_LINE_PIX) {
 			video_out->bpl_alignment = 16;
 			video_out->line_based = 1;
 		}
+
+		video_out->nformats = vfe->line[i].nformats;
+		video_out->formats = vfe->line[i].formats;
+
 		snprintf(name, ARRAY_SIZE(name), "%s%d_%s%d",
 			 MSM_VFE_NAME, vfe->id, "video", i);
-		ret = msm_video_register(video_out, v4l2_dev, name,
-					 i == VFE_LINE_PIX ? 1 : 0);
+		ret = msm_video_register(video_out, v4l2_dev, name);
 		if (ret < 0) {
 			dev_err(dev, "Failed to register video node: %d\n",
 				ret);
@@ -1728,7 +1849,7 @@
 	mutex_destroy(&vfe->power_lock);
 	mutex_destroy(&vfe->stream_lock);
 
-	for (i = 0; i < vfe->line_num; i++) {
+	for (i = 0; i < vfe->res->line_num; i++) {
 		struct v4l2_subdev *sd = &vfe->line[i].subdev;
 		struct camss_video *video_out = &vfe->line[i].video_out;
 
@@ -1740,5 +1861,5 @@
 
 bool vfe_is_lite(struct vfe_device *vfe)
 {
-	return vfe->camss->res->vfe_res[vfe->id].is_lite;
+	return vfe->camss->res->vfe_res[vfe->id].vfe.is_lite;
 }
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-vfe.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -92,7 +92,7 @@
 	struct v4l2_rect crop;
 	struct camss_video video_out;
 	struct vfe_output output;
-	const struct vfe_format *formats;
+	const struct camss_format_info *formats;
 	unsigned int nformats;
 };
 
@@ -114,7 +114,12 @@
 	int (*vfe_enable)(struct vfe_line *line);
 	int (*vfe_halt)(struct vfe_device *vfe);
 	void (*violation_read)(struct vfe_device *vfe);
+	void (*vfe_wm_start)(struct vfe_device *vfe, u8 wm,
+			     struct vfe_line *line);
 	void (*vfe_wm_stop)(struct vfe_device *vfe, u8 wm);
+	void (*vfe_buf_done)(struct vfe_device *vfe, int port_id);
+	void (*vfe_wm_update)(struct vfe_device *vfe, u8 wm, u32 addr,
+			      struct vfe_line *line);
 };
 
 struct vfe_isr_ops {
@@ -126,6 +131,16 @@
 	void (*wm_done)(struct vfe_device *vfe, u8 wm);
 };
 
+struct vfe_subdev_resources {
+	bool is_lite;
+	u8 line_num;
+	bool has_pd;
+	char *pd_name;
+	const struct vfe_hw_ops *hw_ops;
+	const struct camss_formats *formats_rdi;
+	const struct camss_formats *formats_pix;
+};
+
 struct vfe_device {
 	struct camss *camss;
 	u8 id;
@@ -143,10 +158,9 @@
 	spinlock_t output_lock;
 	enum vfe_line_id wm_output_map[MSM_VFE_IMAGE_MASTERS_NUM];
 	struct vfe_line line[VFE_LINE_NUM_MAX];
-	u8 line_num;
 	u32 reg_update;
 	u8 was_streaming;
-	const struct vfe_hw_ops *ops;
+	const struct vfe_subdev_resources *res;
 	const struct vfe_hw_ops_gen1 *ops_gen1;
 	struct vfe_isr_ops isr_ops;
 	struct camss_video_ops video_ops;
@@ -217,11 +231,19 @@
  */
 int vfe_pm_domain_on(struct vfe_device *vfe);
 
+extern const struct camss_formats vfe_formats_rdi_8x16;
+extern const struct camss_formats vfe_formats_pix_8x16;
+extern const struct camss_formats vfe_formats_rdi_8x96;
+extern const struct camss_formats vfe_formats_pix_8x96;
+extern const struct camss_formats vfe_formats_rdi_845;
+extern const struct camss_formats vfe_formats_pix_845;
+
 extern const struct vfe_hw_ops vfe_ops_4_1;
 extern const struct vfe_hw_ops vfe_ops_4_7;
 extern const struct vfe_hw_ops vfe_ops_4_8;
 extern const struct vfe_hw_ops vfe_ops_170;
 extern const struct vfe_hw_ops vfe_ops_480;
+extern const struct vfe_hw_ops vfe_ops_690;
 
 int vfe_get(struct vfe_device *vfe);
 void vfe_put(struct vfe_device *vfe);
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-video.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-video.c
@@ -24,269 +24,10 @@
 #define CAMSS_FRAME_MAX_HEIGHT_RDI	8191
 #define CAMSS_FRAME_MAX_HEIGHT_PIX	4096
 
-struct fract {
-	u8 numerator;
-	u8 denominator;
-};
-
-/*
- * struct camss_format_info - ISP media bus format information
- * @code: V4L2 media bus format code
- * @pixelformat: V4L2 pixel format FCC identifier
- * @planes: Number of planes
- * @hsub: Horizontal subsampling (for each plane)
- * @vsub: Vertical subsampling (for each plane)
- * @bpp: Bits per pixel when stored in memory (for each plane)
- */
-struct camss_format_info {
-	u32 code;
-	u32 pixelformat;
-	u8 planes;
-	struct fract hsub[3];
-	struct fract vsub[3];
-	unsigned int bpp[3];
-};
-
-static const struct camss_format_info formats_rdi_8x16[] = {
-	{ MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_VYUY, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_YVYU, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 8 } },
-	{ MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 8 } },
-	{ MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 8 } },
-	{ MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 8 } },
-	{ MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-	{ MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-	{ MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-	{ MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-	{ MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 12 } },
-	{ MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 12 } },
-	{ MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 12 } },
-	{ MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 12 } },
-	{ MEDIA_BUS_FMT_Y10_1X10, V4L2_PIX_FMT_Y10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-};
-
-static const struct camss_format_info formats_rdi_8x96[] = {
-	{ MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_VYUY, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_YVYU, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 8 } },
-	{ MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 8 } },
-	{ MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 8 } },
-	{ MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 8 } },
-	{ MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-	{ MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-	{ MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-	{ MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-	{ MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_PIX_FMT_SBGGR10, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 12 } },
-	{ MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 12 } },
-	{ MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 12 } },
-	{ MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 12 } },
-	{ MEDIA_BUS_FMT_SBGGR14_1X14, V4L2_PIX_FMT_SBGGR14P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 14 } },
-	{ MEDIA_BUS_FMT_SGBRG14_1X14, V4L2_PIX_FMT_SGBRG14P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 14 } },
-	{ MEDIA_BUS_FMT_SGRBG14_1X14, V4L2_PIX_FMT_SGRBG14P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 14 } },
-	{ MEDIA_BUS_FMT_SRGGB14_1X14, V4L2_PIX_FMT_SRGGB14P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 14 } },
-	{ MEDIA_BUS_FMT_Y10_1X10, V4L2_PIX_FMT_Y10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-	{ MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, V4L2_PIX_FMT_Y10, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-};
-
-static const struct camss_format_info formats_rdi_845[] = {
-	{ MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_VYUY, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_YVYU, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_SBGGR8_1X8, V4L2_PIX_FMT_SBGGR8, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 8 } },
-	{ MEDIA_BUS_FMT_SGBRG8_1X8, V4L2_PIX_FMT_SGBRG8, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 8 } },
-	{ MEDIA_BUS_FMT_SGRBG8_1X8, V4L2_PIX_FMT_SGRBG8, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 8 } },
-	{ MEDIA_BUS_FMT_SRGGB8_1X8, V4L2_PIX_FMT_SRGGB8, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 8 } },
-	{ MEDIA_BUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-	{ MEDIA_BUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-	{ MEDIA_BUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-	{ MEDIA_BUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-	{ MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, V4L2_PIX_FMT_SBGGR10, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 12 } },
-	{ MEDIA_BUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 12 } },
-	{ MEDIA_BUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 12 } },
-	{ MEDIA_BUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 12 } },
-	{ MEDIA_BUS_FMT_SBGGR14_1X14, V4L2_PIX_FMT_SBGGR14P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 14 } },
-	{ MEDIA_BUS_FMT_SGBRG14_1X14, V4L2_PIX_FMT_SGBRG14P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 14 } },
-	{ MEDIA_BUS_FMT_SGRBG14_1X14, V4L2_PIX_FMT_SGRBG14P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 14 } },
-	{ MEDIA_BUS_FMT_SRGGB14_1X14, V4L2_PIX_FMT_SRGGB14P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 14 } },
-	{ MEDIA_BUS_FMT_Y8_1X8, V4L2_PIX_FMT_GREY, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 8 } },
-	{ MEDIA_BUS_FMT_Y10_1X10, V4L2_PIX_FMT_Y10P, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 10 } },
-	{ MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, V4L2_PIX_FMT_Y10, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-};
-
-static const struct camss_format_info formats_pix_8x16[] = {
-	{ MEDIA_BUS_FMT_YUYV8_1_5X8, V4L2_PIX_FMT_NV12, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_YVYU8_1_5X8, V4L2_PIX_FMT_NV12, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_UYVY8_1_5X8, V4L2_PIX_FMT_NV12, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_VYUY8_1_5X8, V4L2_PIX_FMT_NV12, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_YUYV8_1_5X8, V4L2_PIX_FMT_NV21, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_YVYU8_1_5X8, V4L2_PIX_FMT_NV21, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_UYVY8_1_5X8, V4L2_PIX_FMT_NV21, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_VYUY8_1_5X8, V4L2_PIX_FMT_NV21, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_NV16, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_NV16, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_NV16, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_NV16, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_NV61, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_NV61, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_NV61, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_NV61, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-};
-
-static const struct camss_format_info formats_pix_8x96[] = {
-	{ MEDIA_BUS_FMT_YUYV8_1_5X8, V4L2_PIX_FMT_NV12, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_YVYU8_1_5X8, V4L2_PIX_FMT_NV12, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_UYVY8_1_5X8, V4L2_PIX_FMT_NV12, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_VYUY8_1_5X8, V4L2_PIX_FMT_NV12, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_YUYV8_1_5X8, V4L2_PIX_FMT_NV21, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_YVYU8_1_5X8, V4L2_PIX_FMT_NV21, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_UYVY8_1_5X8, V4L2_PIX_FMT_NV21, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_VYUY8_1_5X8, V4L2_PIX_FMT_NV21, 1,
-	  { { 1, 1 } }, { { 2, 3 } }, { 8 } },
-	{ MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_NV16, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_NV16, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_NV16, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_NV16, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_NV61, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_NV61, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_NV61, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_NV61, 1,
-	  { { 1, 1 } }, { { 1, 2 } }, { 8 } },
-	{ MEDIA_BUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_VYUY8_1X16, V4L2_PIX_FMT_VYUY, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-	{ MEDIA_BUS_FMT_YVYU8_1X16, V4L2_PIX_FMT_YVYU, 1,
-	  { { 1, 1 } }, { { 1, 1 } }, { 16 } },
-};
-
 /* -----------------------------------------------------------------------------
  * Helper functions
  */
 
-static int video_find_format(u32 code, u32 pixelformat,
-			     const struct camss_format_info *formats,
-			     unsigned int nformats)
-{
-	int i;
-
-	for (i = 0; i < nformats; i++) {
-		if (formats[i].code == code &&
-		    formats[i].pixelformat == pixelformat)
-			return i;
-	}
-
-	for (i = 0; i < nformats; i++)
-		if (formats[i].code == code)
-			return i;
-
-	WARN_ON(1);
-
-	return -EINVAL;
-}
-
 /*
  * video_mbus_to_pix_mp - Convert v4l2_mbus_framefmt to v4l2_pix_format_mplane
  * @mbus: v4l2_mbus_framefmt format (input)
@@ -359,9 +100,8 @@
 	if (ret)
 		return ret;
 
-	ret = video_find_format(fmt.format.code,
-				format->fmt.pix_mp.pixelformat,
-				video->formats, video->nformats);
+	ret = camss_format_find_format(fmt.format.code, format->fmt.pix_mp.pixelformat,
+				       video->formats, video->nformats);
 	if (ret < 0)
 		return ret;
 
@@ -557,12 +297,6 @@
 
 		ret = v4l2_subdev_call(subdev, video, s_stream, 0);
 
-		if (entity->use_count > 1) {
-			/* Don't stop if other instances of the pipeline are still running */
-			dev_dbg(video->camss->dev, "Video pipeline still used, don't stop streaming.\n");
-			return;
-		}
-
 		if (ret) {
 			dev_err(video->camss->dev, "Video pipeline stop failed: %d\n", ret);
 			return;
@@ -969,7 +703,7 @@
  */
 
 int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,
-		       const char *name, int is_pix)
+		       const char *name)
 {
 	struct media_pad *pad = &video->pad;
 	struct video_device *vdev;
@@ -1006,33 +740,6 @@
 
 	mutex_init(&video->lock);
 
-	switch (video->camss->res->version) {
-	case CAMSS_8x16:
-		if (is_pix) {
-			video->formats = formats_pix_8x16;
-			video->nformats = ARRAY_SIZE(formats_pix_8x16);
-		} else {
-			video->formats = formats_rdi_8x16;
-			video->nformats = ARRAY_SIZE(formats_rdi_8x16);
-		}
-		break;
-	case CAMSS_8x96:
-	case CAMSS_660:
-		if (is_pix) {
-			video->formats = formats_pix_8x96;
-			video->nformats = ARRAY_SIZE(formats_pix_8x96);
-		} else {
-			video->formats = formats_rdi_8x96;
-			video->nformats = ARRAY_SIZE(formats_rdi_8x96);
-		}
-		break;
-	case CAMSS_845:
-	case CAMSS_8250:
-		video->formats = formats_rdi_845;
-		video->nformats = ARRAY_SIZE(formats_rdi_845);
-		break;
-	}
-
 	ret = msm_video_init_format(video);
 	if (ret < 0) {
 		dev_err(v4l2_dev->dev, "Failed to init format: %d\n", ret);
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss-video.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss-video.h
@@ -33,8 +33,6 @@
 			     enum vb2_buffer_state state);
 };
 
-struct camss_format_info;
-
 struct camss_video {
 	struct camss *camss;
 	struct vb2_queue vb2_q;
@@ -53,7 +51,7 @@
 };
 
 int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,
-		       const char *name, int is_pix);
+		       const char *name);
 
 void msm_video_unregister(struct camss_video *video);
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss.c
@@ -18,6 +18,7 @@
 #include <linux/of_graph.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
 #include <linux/slab.h>
 #include <linux/videodev2.h>
 
@@ -32,6 +33,8 @@
 #define CAMSS_CLOCK_MARGIN_NUMERATOR 105
 #define CAMSS_CLOCK_MARGIN_DENOMINATOR 100
 
+static const struct parent_dev_ops vfe_parent_dev_ops;
+
 static const struct camss_subdev_resources csiphy_res_8x16[] = {
 	/* CSIPHY0 */
 	{
@@ -43,7 +46,10 @@
 				{ 100000000, 200000000 } },
 		.reg = { "csiphy0", "csiphy0_clk_mux" },
 		.interrupt = { "csiphy0" },
-		.ops = &csiphy_ops_2ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_2ph_1_0,
+			.formats = &csiphy_formats_8x16
+		}
 	},
 
 	/* CSIPHY1 */
@@ -56,7 +62,10 @@
 				{ 100000000, 200000000 } },
 		.reg = { "csiphy1", "csiphy1_clk_mux" },
 		.interrupt = { "csiphy1" },
-		.ops = &csiphy_ops_2ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_2ph_1_0,
+			.formats = &csiphy_formats_8x16
+		}
 	}
 };
 
@@ -76,7 +85,11 @@
 				{ 0 } },
 		.reg = { "csid0" },
 		.interrupt = { "csid0" },
-		.ops = &csid_ops_4_1,
+		.csid = {
+			.hw_ops = &csid_ops_4_1,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_4_1
+		}
 	},
 
 	/* CSID1 */
@@ -94,7 +107,11 @@
 				{ 0 } },
 		.reg = { "csid1" },
 		.interrupt = { "csid1" },
-		.ops = &csid_ops_4_1,
+		.csid = {
+			.hw_ops = &csid_ops_4_1,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_4_1
+		}
 	},
 };
 
@@ -105,8 +122,7 @@
 		   "csi1", "csi1_pix", "csi1_rdi" },
 	.clock_for_reset = { "vfe0", "csi_vfe0" },
 	.reg = { "ispif", "csi_clk_mux" },
-	.interrupt = { "ispif" }
-
+	.interrupt = { "ispif" },
 };
 
 static const struct camss_subdev_resources vfe_res_8x16[] = {
@@ -128,8 +144,12 @@
 				{ 0 } },
 		.reg = { "vfe0" },
 		.interrupt = { "vfe0" },
-		.line_num = 3,
-		.ops = &vfe_ops_4_1
+		.vfe = {
+			.line_num = 3,
+			.hw_ops = &vfe_ops_4_1,
+			.formats_rdi = &vfe_formats_rdi_8x16,
+			.formats_pix = &vfe_formats_pix_8x16
+		}
 	}
 };
 
@@ -144,7 +164,10 @@
 				{ 100000000, 200000000, 266666667 } },
 		.reg = { "csiphy0", "csiphy0_clk_mux" },
 		.interrupt = { "csiphy0" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_8x96
+		}
 	},
 
 	/* CSIPHY1 */
@@ -157,7 +180,10 @@
 				{ 100000000, 200000000, 266666667 } },
 		.reg = { "csiphy1", "csiphy1_clk_mux" },
 		.interrupt = { "csiphy1" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_8x96
+		}
 	},
 
 	/* CSIPHY2 */
@@ -170,7 +196,10 @@
 				{ 100000000, 200000000, 266666667 } },
 		.reg = { "csiphy2", "csiphy2_clk_mux" },
 		.interrupt = { "csiphy2" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_8x96
+		}
 	}
 };
 
@@ -190,7 +219,11 @@
 				{ 0 } },
 		.reg = { "csid0" },
 		.interrupt = { "csid0" },
-		.ops = &csid_ops_4_7,
+		.csid = {
+			.hw_ops = &csid_ops_4_7,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_4_7
+		}
 	},
 
 	/* CSID1 */
@@ -208,7 +241,11 @@
 				{ 0 } },
 		.reg = { "csid1" },
 		.interrupt = { "csid1" },
-		.ops = &csid_ops_4_7,
+		.csid = {
+			.hw_ops = &csid_ops_4_7,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_4_7
+		}
 	},
 
 	/* CSID2 */
@@ -226,7 +263,11 @@
 				{ 0 } },
 		.reg = { "csid2" },
 		.interrupt = { "csid2" },
-		.ops = &csid_ops_4_7,
+		.csid = {
+			.hw_ops = &csid_ops_4_7,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_4_7
+		}
 	},
 
 	/* CSID3 */
@@ -244,7 +285,11 @@
 				{ 0 } },
 		.reg = { "csid3" },
 		.interrupt = { "csid3" },
-		.ops = &csid_ops_4_7,
+		.csid = {
+			.hw_ops = &csid_ops_4_7,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_4_7
+		}
 	}
 };
 
@@ -257,7 +302,7 @@
 		   "csi3", "csi3_pix", "csi3_rdi" },
 	.clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
 	.reg = { "ispif", "csi_clk_mux" },
-	.interrupt = { "ispif" }
+	.interrupt = { "ispif" },
 };
 
 static const struct camss_subdev_resources vfe_res_8x96[] = {
@@ -277,9 +322,13 @@
 				{ 0 } },
 		.reg = { "vfe0" },
 		.interrupt = { "vfe0" },
-		.line_num = 3,
-		.has_pd = true,
-		.ops = &vfe_ops_4_7
+		.vfe = {
+			.line_num = 3,
+			.has_pd = true,
+			.hw_ops = &vfe_ops_4_7,
+			.formats_rdi = &vfe_formats_rdi_8x96,
+			.formats_pix = &vfe_formats_pix_8x96
+		}
 	},
 
 	/* VFE1 */
@@ -298,9 +347,13 @@
 				{ 0 } },
 		.reg = { "vfe1" },
 		.interrupt = { "vfe1" },
-		.line_num = 3,
-		.has_pd = true,
-		.ops = &vfe_ops_4_7
+		.vfe = {
+			.line_num = 3,
+			.has_pd = true,
+			.hw_ops = &vfe_ops_4_7,
+			.formats_rdi = &vfe_formats_rdi_8x96,
+			.formats_pix = &vfe_formats_pix_8x96
+		}
 	}
 };
 
@@ -317,7 +370,10 @@
 				{ 0 } },
 		.reg = { "csiphy0", "csiphy0_clk_mux" },
 		.interrupt = { "csiphy0" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_8x96
+		}
 	},
 
 	/* CSIPHY1 */
@@ -332,7 +388,10 @@
 				{ 0 } },
 		.reg = { "csiphy1", "csiphy1_clk_mux" },
 		.interrupt = { "csiphy1" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_8x96
+		}
 	},
 
 	/* CSIPHY2 */
@@ -347,7 +406,10 @@
 				{ 0 } },
 		.reg = { "csiphy2", "csiphy2_clk_mux" },
 		.interrupt = { "csiphy2" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_8x96
+		}
 	}
 };
 
@@ -370,7 +432,11 @@
 				{ 0 } },
 		.reg = { "csid0" },
 		.interrupt = { "csid0" },
-		.ops = &csid_ops_4_7,
+		.csid = {
+			.hw_ops = &csid_ops_4_7,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_4_7
+		}
 	},
 
 	/* CSID1 */
@@ -391,7 +457,11 @@
 				{ 0 } },
 		.reg = { "csid1" },
 		.interrupt = { "csid1" },
-		.ops = &csid_ops_4_7,
+		.csid = {
+			.hw_ops = &csid_ops_4_7,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_4_7
+		}
 	},
 
 	/* CSID2 */
@@ -412,7 +482,11 @@
 				{ 0 } },
 		.reg = { "csid2" },
 		.interrupt = { "csid2" },
-		.ops = &csid_ops_4_7,
+		.csid = {
+			.hw_ops = &csid_ops_4_7,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_4_7
+		}
 	},
 
 	/* CSID3 */
@@ -433,7 +507,11 @@
 				{ 0 } },
 		.reg = { "csid3" },
 		.interrupt = { "csid3" },
-		.ops = &csid_ops_4_7,
+		.csid = {
+			.hw_ops = &csid_ops_4_7,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_4_7
+		}
 	}
 };
 
@@ -446,7 +524,7 @@
 		   "csi3", "csi3_pix", "csi3_rdi" },
 	.clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
 	.reg = { "ispif", "csi_clk_mux" },
-	.interrupt = { "ispif" }
+	.interrupt = { "ispif" },
 };
 
 static const struct camss_subdev_resources vfe_res_660[] = {
@@ -469,9 +547,13 @@
 				{ 0 } },
 		.reg = { "vfe0" },
 		.interrupt = { "vfe0" },
-		.line_num = 3,
-		.has_pd = true,
-		.ops = &vfe_ops_4_8
+		.vfe = {
+			.line_num = 3,
+			.has_pd = true,
+			.hw_ops = &vfe_ops_4_8,
+			.formats_rdi = &vfe_formats_rdi_8x96,
+			.formats_pix = &vfe_formats_pix_8x96
+		}
 	},
 
 	/* VFE1 */
@@ -493,9 +575,13 @@
 				{ 0 } },
 		.reg = { "vfe1" },
 		.interrupt = { "vfe1" },
-		.line_num = 3,
-		.has_pd = true,
-		.ops = &vfe_ops_4_8
+		.vfe = {
+			.line_num = 3,
+			.has_pd = true,
+			.hw_ops = &vfe_ops_4_8,
+			.formats_rdi = &vfe_formats_rdi_8x96,
+			.formats_pix = &vfe_formats_pix_8x96
+		}
 	}
 };
 
@@ -516,7 +602,10 @@
 				{ 19200000, 240000000, 269333333 } },
 		.reg = { "csiphy0" },
 		.interrupt = { "csiphy0" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
 	},
 
 	/* CSIPHY1 */
@@ -535,7 +624,10 @@
 				{ 19200000, 240000000, 269333333 } },
 		.reg = { "csiphy1" },
 		.interrupt = { "csiphy1" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
 	},
 
 	/* CSIPHY2 */
@@ -554,7 +646,10 @@
 				{ 19200000, 240000000, 269333333 } },
 		.reg = { "csiphy2" },
 		.interrupt = { "csiphy2" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
 	},
 
 	/* CSIPHY3 */
@@ -573,7 +668,10 @@
 				{ 19200000, 240000000, 269333333 } },
 		.reg = { "csiphy3" },
 		.interrupt = { "csiphy3" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
 	}
 };
 
@@ -596,7 +694,11 @@
 				{ 384000000 } },
 		.reg = { "csid0" },
 		.interrupt = { "csid0" },
-		.ops = &csid_ops_gen2
+		.csid = {
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
 	},
 
 	/* CSID1 */
@@ -617,7 +719,11 @@
 				{ 384000000 } },
 		.reg = { "csid1" },
 		.interrupt = { "csid1" },
-		.ops = &csid_ops_gen2
+		.csid = {
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
 	},
 
 	/* CSID2 */
@@ -638,8 +744,12 @@
 				{ 384000000 } },
 		.reg = { "csid2" },
 		.interrupt = { "csid2" },
-		.is_lite = true,
-		.ops = &csid_ops_gen2
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
 	}
 };
 
@@ -662,9 +772,13 @@
 				{ 384000000 } },
 		.reg = { "vfe0" },
 		.interrupt = { "vfe0" },
-		.line_num = 4,
-		.has_pd = true,
-		.ops = &vfe_ops_170
+		.vfe = {
+			.line_num = 4,
+			.has_pd = true,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
 	},
 
 	/* VFE1 */
@@ -685,9 +799,13 @@
 				{ 384000000 } },
 		.reg = { "vfe1" },
 		.interrupt = { "vfe1" },
-		.line_num = 4,
-		.has_pd = true,
-		.ops = &vfe_ops_170
+		.vfe = {
+			.line_num = 4,
+			.has_pd = true,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
 	},
 
 	/* VFE-lite */
@@ -707,9 +825,13 @@
 				{ 384000000 } },
 		.reg = { "vfe_lite" },
 		.interrupt = { "vfe_lite" },
-		.is_lite = true,
-		.line_num = 4,
-		.ops = &vfe_ops_170
+		.vfe = {
+			.is_lite = true,
+			.line_num = 4,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
 	}
 };
 
@@ -722,7 +844,10 @@
 				{ 300000000 } },
 		.reg = { "csiphy0" },
 		.interrupt = { "csiphy0" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
 	},
 	/* CSIPHY1 */
 	{
@@ -732,7 +857,10 @@
 				{ 300000000 } },
 		.reg = { "csiphy1" },
 		.interrupt = { "csiphy1" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
 	},
 	/* CSIPHY2 */
 	{
@@ -742,7 +870,10 @@
 				{ 300000000 } },
 		.reg = { "csiphy2" },
 		.interrupt = { "csiphy2" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
 	},
 	/* CSIPHY3 */
 	{
@@ -752,7 +883,10 @@
 				{ 300000000 } },
 		.reg = { "csiphy3" },
 		.interrupt = { "csiphy3" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
 	},
 	/* CSIPHY4 */
 	{
@@ -762,7 +896,10 @@
 				{ 300000000 } },
 		.reg = { "csiphy4" },
 		.interrupt = { "csiphy4" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
 	},
 	/* CSIPHY5 */
 	{
@@ -772,7 +909,10 @@
 				{ 300000000 } },
 		.reg = { "csiphy5" },
 		.interrupt = { "csiphy5" },
-		.ops = &csiphy_ops_3ph_1_0
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
 	}
 };
 
@@ -788,7 +928,11 @@
 				{ 0 } },
 		.reg = { "csid0" },
 		.interrupt = { "csid0" },
-		.ops = &csid_ops_gen2
+		.csid = {
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
 	},
 	/* CSID1 */
 	{
@@ -801,7 +945,11 @@
 				{ 0 } },
 		.reg = { "csid1" },
 		.interrupt = { "csid1" },
-		.ops = &csid_ops_gen2
+		.csid = {
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
 	},
 	/* CSID2 */
 	{
@@ -813,8 +961,12 @@
 				{ 0 } },
 		.reg = { "csid2" },
 		.interrupt = { "csid2" },
-		.is_lite = true,
-		.ops = &csid_ops_gen2
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
 	},
 	/* CSID3 */
 	{
@@ -826,8 +978,12 @@
 				{ 0 } },
 		.reg = { "csid3" },
 		.interrupt = { "csid3" },
-		.is_lite = true,
-		.ops = &csid_ops_gen2
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
 	}
 };
 
@@ -849,10 +1005,14 @@
 				{ 0 } },
 		.reg = { "vfe0" },
 		.interrupt = { "vfe0" },
-		.pd_name = "ife0",
-		.line_num = 3,
-		.has_pd = true,
-		.ops = &vfe_ops_480
+		.vfe = {
+			.line_num = 3,
+			.has_pd = true,
+			.pd_name = "ife0",
+			.hw_ops = &vfe_ops_480,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
 	},
 	/* VFE1 */
 	{
@@ -871,10 +1031,14 @@
 				{ 0 } },
 		.reg = { "vfe1" },
 		.interrupt = { "vfe1" },
-		.pd_name = "ife1",
-		.line_num = 3,
-		.has_pd = true,
-		.ops = &vfe_ops_480
+		.vfe = {
+			.line_num = 3,
+			.has_pd = true,
+			.pd_name = "ife1",
+			.hw_ops = &vfe_ops_480,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
 	},
 	/* VFE2 (lite) */
 	{
@@ -892,9 +1056,13 @@
 				{ 0 } },
 		.reg = { "vfe_lite0" },
 		.interrupt = { "vfe_lite0" },
-		.is_lite = true,
-		.line_num = 4,
-		.ops = &vfe_ops_480
+		.vfe = {
+			.is_lite = true,
+			.line_num = 4,
+			.hw_ops = &vfe_ops_480,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
 	},
 	/* VFE3 (lite) */
 	{
@@ -912,9 +1080,13 @@
 				{ 0 } },
 		.reg = { "vfe_lite1" },
 		.interrupt = { "vfe_lite1" },
-		.is_lite = true,
-		.line_num = 4,
-		.ops = &vfe_ops_480
+		.vfe = {
+			.is_lite = true,
+			.line_num = 4,
+			.hw_ops = &vfe_ops_480,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
 	},
 };
 
@@ -941,6 +1113,1603 @@
 	},
 };
 
+static const struct camss_subdev_resources csiphy_res_sc8280xp[] = {
+	/* CSIPHY0 */
+	{
+		.regulators = {},
+		.clock = { "csiphy0", "csiphy0_timer" },
+		.clock_rate = { { 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy0" },
+		.interrupt = { "csiphy0" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
+	},
+	/* CSIPHY1 */
+	{
+		.regulators = {},
+		.clock = { "csiphy1", "csiphy1_timer" },
+		.clock_rate = { { 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy1" },
+		.interrupt = { "csiphy1" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
+	},
+	/* CSIPHY2 */
+	{
+		.regulators = {},
+		.clock = { "csiphy2", "csiphy2_timer" },
+		.clock_rate = { { 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy2" },
+		.interrupt = { "csiphy2" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
+	},
+	/* CSIPHY3 */
+	{
+		.regulators = {},
+		.clock = { "csiphy3", "csiphy3_timer" },
+		.clock_rate = { { 400000000 },
+				{ 300000000 } },
+		.reg = { "csiphy3" },
+		.interrupt = { "csiphy3" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sdm845
+		}
+	},
+};
+
+static const struct camss_subdev_resources csid_res_sc8280xp[] = {
+	/* CSID0 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+		.clock = { "vfe0_csid", "vfe0_cphy_rx", "vfe0", "vfe0_axi" },
+		.clock_rate = { { 400000000, 480000000, 600000000 },
+				{ 0 },
+				{ 0 },
+				{ 0 } },
+		.reg = { "csid0" },
+		.interrupt = { "csid0" },
+		.csid = {
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID1 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+		.clock = { "vfe1_csid", "vfe1_cphy_rx", "vfe1", "vfe1_axi" },
+		.clock_rate = { { 400000000, 480000000, 600000000 },
+				{ 0 },
+				{ 0 },
+				{ 0 } },
+		.reg = { "csid1" },
+		.interrupt = { "csid1" },
+		.csid = {
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID2 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+		.clock = { "vfe2_csid", "vfe2_cphy_rx", "vfe2", "vfe2_axi" },
+		.clock_rate = { { 400000000, 480000000, 600000000 },
+				{ 0 },
+				{ 0 },
+				{ 0 } },
+		.reg = { "csid2" },
+		.interrupt = { "csid2" },
+		.csid = {
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID3 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+		.clock = { "vfe3_csid", "vfe3_cphy_rx", "vfe3", "vfe3_axi" },
+		.clock_rate = { { 400000000, 480000000, 600000000 },
+				{ 0 },
+				{ 0 },
+				{ 0 } },
+		.reg = { "csid3" },
+		.interrupt = { "csid3" },
+		.csid = {
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID_LITE0 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+		.clock = { "vfe_lite0_csid", "vfe_lite0_cphy_rx", "vfe_lite0" },
+		.clock_rate = { { 400000000, 480000000, 600000000 },
+				{ 0 },
+				{ 0 }, },
+		.reg = { "csid0_lite" },
+		.interrupt = { "csid0_lite" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID_LITE1 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+		.clock = { "vfe_lite1_csid", "vfe_lite1_cphy_rx", "vfe_lite1" },
+		.clock_rate = { { 400000000, 480000000, 600000000 },
+				{ 0 },
+				{ 0 }, },
+		.reg = { "csid1_lite" },
+		.interrupt = { "csid1_lite" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID_LITE2 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+		.clock = { "vfe_lite2_csid", "vfe_lite2_cphy_rx", "vfe_lite2" },
+		.clock_rate = { { 400000000, 480000000, 600000000 },
+				{ 0 },
+				{ 0 }, },
+		.reg = { "csid2_lite" },
+		.interrupt = { "csid2_lite" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID_LITE3 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+		.clock = { "vfe_lite3_csid", "vfe_lite3_cphy_rx", "vfe_lite3" },
+		.clock_rate = { { 400000000, 480000000, 600000000 },
+				{ 0 },
+				{ 0 }, },
+		.reg = { "csid3_lite" },
+		.interrupt = { "csid3_lite" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	}
+};
+
+static const struct camss_subdev_resources vfe_res_sc8280xp[] = {
+	/* VFE0 */
+	{
+		.regulators = {},
+		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe0", "vfe0_axi" },
+		.clock_rate = { { 0 },
+				{ 0 },
+				{ 19200000, 80000000},
+				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
+				{ 400000000, 558000000, 637000000, 760000000 },
+				{ 0 }, },
+		.reg = { "vfe0" },
+		.interrupt = { "vfe0" },
+		.vfe = {
+			.line_num = 4,
+			.pd_name = "ife0",
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE1 */
+	{
+		.regulators = {},
+		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe1", "vfe1_axi" },
+		.clock_rate = { { 0 },
+				{ 0 },
+				{ 19200000, 80000000},
+				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
+				{ 400000000, 558000000, 637000000, 760000000 },
+				{ 0 }, },
+		.reg = { "vfe1" },
+		.interrupt = { "vfe1" },
+		.vfe = {
+			.line_num = 4,
+			.pd_name = "ife1",
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE2 */
+	{
+		.regulators = {},
+		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe2", "vfe2_axi" },
+		.clock_rate = { { 0 },
+				{ 0 },
+				{ 19200000, 80000000},
+				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
+				{ 400000000, 558000000, 637000000, 760000000 },
+				{ 0 }, },
+		.reg = { "vfe2" },
+		.interrupt = { "vfe2" },
+		.vfe = {
+			.line_num = 4,
+			.pd_name = "ife2",
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE3 */
+	{
+		.regulators = {},
+		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe3", "vfe3_axi" },
+		.clock_rate = { { 0 },
+				{ 0 },
+				{ 19200000, 80000000},
+				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
+				{ 400000000, 558000000, 637000000, 760000000 },
+				{ 0 }, },
+		.reg = { "vfe3" },
+		.interrupt = { "vfe3" },
+		.vfe = {
+			.line_num = 4,
+			.pd_name = "ife3",
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE_LITE_0 */
+	{
+		.regulators = {},
+		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite0" },
+		.clock_rate = { { 0 },
+				{ 0 },
+				{ 19200000, 80000000},
+				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
+				{ 320000000, 400000000, 480000000, 600000000 }, },
+		.reg = { "vfe_lite0" },
+		.interrupt = { "vfe_lite0" },
+		.vfe = {
+			.is_lite = true,
+			.line_num = 4,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE_LITE_1 */
+	{
+		.regulators = {},
+		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite1" },
+		.clock_rate = { { 0 },
+				{ 0 },
+				{ 19200000, 80000000},
+				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
+				{ 320000000, 400000000, 480000000, 600000000 }, },
+		.reg = { "vfe_lite1" },
+		.interrupt = { "vfe_lite1" },
+		.vfe = {
+			.is_lite = true,
+			.line_num = 4,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE_LITE_2 */
+	{
+		.regulators = {},
+		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite2" },
+		.clock_rate = { { 0 },
+				{ 0 },
+				{ 19200000, 80000000},
+				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
+				{ 320000000, 400000000, 480000000, 600000000, }, },
+		.reg = { "vfe_lite2" },
+		.interrupt = { "vfe_lite2" },
+		.vfe = {
+			.is_lite = true,
+			.line_num = 4,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE_LITE_3 */
+	{
+		.regulators = {},
+		.clock = { "gcc_axi_hf", "gcc_axi_sf", "cpas_ahb", "camnoc_axi", "vfe_lite3" },
+		.clock_rate = { { 0 },
+				{ 0 },
+				{ 19200000, 80000000},
+				{ 19200000, 150000000, 266666667, 320000000, 400000000, 480000000 },
+				{ 320000000, 400000000, 480000000, 600000000 }, },
+		.reg = { "vfe_lite3" },
+		.interrupt = { "vfe_lite3" },
+		.vfe = {
+			.is_lite = true,
+			.line_num = 4,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+};
+
+static const struct resources_icc icc_res_sc8280xp[] = {
+	{
+		.name = "cam_ahb",
+		.icc_bw_tbl.avg = 150000,
+		.icc_bw_tbl.peak = 300000,
+	},
+	{
+		.name = "cam_hf_mnoc",
+		.icc_bw_tbl.avg = 2097152,
+		.icc_bw_tbl.peak = 2097152,
+	},
+	{
+		.name = "cam_sf_mnoc",
+		.icc_bw_tbl.avg = 2097152,
+		.icc_bw_tbl.peak = 2097152,
+	},
+	{
+		.name = "cam_sf_icp_mnoc",
+		.icc_bw_tbl.avg = 2097152,
+		.icc_bw_tbl.peak = 2097152,
+	},
+};
+
+static const struct camss_subdev_resources csiphy_res_7280[] = {
+	/* CSIPHY0 */
+	{
+		.regulators = {},
+		.clock = { "csiphy0", "csiphy0_timer"},
+		.clock_rate = {
+			{ 300000000 },
+			{ 300000000 }
+		},
+		.reg = { "csiphy0" },
+		.interrupt = { "csiphy0" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+	/* CSIPHY1 */
+	{
+		.regulators = {},
+		.clock = { "csiphy1", "csiphy1_timer"},
+		.clock_rate = {
+			{ 300000000 },
+			{ 300000000 }
+		},
+		.reg = { "csiphy1" },
+		.interrupt = { "csiphy1" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+	/* CSIPHY2 */
+	{
+		.regulators = {},
+		.clock = { "csiphy2", "csiphy2_timer"},
+		.clock_rate = {
+			{ 300000000 },
+			{ 300000000 }
+		},
+		.reg = { "csiphy2" },
+		.interrupt = { "csiphy2" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+	/* CSIPHY3 */
+	{
+		.regulators = {},
+		.clock = { "csiphy3", "csiphy3_timer"},
+		.clock_rate = {
+			{ 300000000 },
+			{ 300000000 }
+		},
+		.reg = { "csiphy3" },
+		.interrupt = { "csiphy3" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+	/* CSIPHY4 */
+	{
+		.regulators = {},
+		.clock = { "csiphy4", "csiphy4_timer"},
+		.clock_rate = {
+			{ 300000000 },
+			{ 300000000 }
+		},
+		.reg = { "csiphy4" },
+		.interrupt = { "csiphy4" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sc7280
+		}
+	},
+};
+
+static const struct camss_subdev_resources csid_res_7280[] = {
+	/* CSID0 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csi0", "vfe0_cphy_rx", "vfe0", "soc_ahb"},
+		.clock_rate = {
+			{ 300000000, 0, 380000000, 0},
+			{ 400000000, 0, 510000000, 0},
+			{ 400000000, 0, 637000000, 0},
+			{ 400000000, 0, 760000000, 0}
+		},
+
+		.reg = { "csid0" },
+		.interrupt = { "csid0" },
+		.csid = {
+			.is_lite = false,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID1 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csi1", "vfe1_cphy_rx", "vfe1", "soc_ahb"},
+		.clock_rate = {
+			{ 300000000, 0, 380000000, 0},
+			{ 400000000, 0, 510000000, 0},
+			{ 400000000, 0, 637000000, 0},
+			{ 400000000, 0, 760000000, 0}
+		},
+
+		.reg = { "csid1" },
+		.interrupt = { "csid1" },
+		.csid = {
+			.is_lite = false,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID2 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csi2", "vfe2_cphy_rx", "vfe2", "soc_ahb"},
+		.clock_rate = {
+			{ 300000000, 0, 380000000, 0},
+			{ 400000000, 0, 510000000, 0},
+			{ 400000000, 0, 637000000, 0},
+			{ 400000000, 0, 760000000, 0}
+		},
+
+		.reg = { "csid2" },
+		.interrupt = { "csid2" },
+		.csid = {
+			.is_lite = false,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID3 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csi3", "vfe0_lite_cphy_rx", "vfe0_lite", "soc_ahb"},
+		.clock_rate = {
+			{ 300000000, 0, 320000000, 0},
+			{ 400000000, 0, 400000000, 0},
+			{ 400000000, 0, 480000000, 0},
+			{ 400000000, 0, 600000000, 0}
+		},
+
+		.reg = { "csid_lite0" },
+		.interrupt = { "csid_lite0" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID4 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csi3", "vfe0_lite_cphy_rx", "vfe0_lite", "soc_ahb"},
+		.clock_rate = {
+			{ 300000000, 0, 320000000, 0},
+			{ 400000000, 0, 400000000, 0},
+			{ 400000000, 0, 480000000, 0},
+			{ 400000000, 0, 600000000, 0}
+		},
+
+		.reg = { "csid_lite1" },
+		.interrupt = { "csid_lite1" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen2,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+};
+
+static const struct camss_subdev_resources vfe_res_7280[] = {
+	/* VFE0 */
+	{
+		.regulators = {},
+
+		.clock = { "vfe0", "vfe0_axi", "soc_ahb",
+			   "cpas_ahb", "camnoc_axi",
+			   "gcc_camera_axi"},
+		.clock_rate = {
+			{ 380000000, 0, 80000000, 0, 150000000, 0},
+			{ 510000000, 0, 80000000, 0, 240000000, 0},
+			{ 637000000, 0, 80000000, 0, 320000000, 0},
+			{ 760000000, 0, 80000000, 0, 400000000, 0},
+			{ 760000000, 0, 80000000, 0, 480000000, 0},
+		},
+
+		.reg = { "vfe0" },
+		.interrupt = { "vfe0" },
+		.vfe = {
+			.line_num = 3,
+			.is_lite = false,
+			.has_pd = true,
+			.pd_name = "ife0",
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE1 */
+	{
+		.regulators = {},
+
+		.clock = { "vfe1", "vfe1_axi", "soc_ahb",
+			   "cpas_ahb", "camnoc_axi",
+			   "gcc_camera_axi"},
+		.clock_rate = {
+			{ 380000000, 0, 80000000, 0, 150000000, 0},
+			{ 510000000, 0, 80000000, 0, 240000000, 0},
+			{ 637000000, 0, 80000000, 0, 320000000, 0},
+			{ 760000000, 0, 80000000, 0, 400000000, 0},
+			{ 760000000, 0, 80000000, 0, 480000000, 0},
+		},
+
+		.reg = { "vfe1" },
+		.interrupt = { "vfe1" },
+		.vfe = {
+			.line_num = 3,
+			.is_lite = false,
+			.has_pd = true,
+			.pd_name = "ife1",
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE2 */
+	{
+		.regulators = {},
+
+		.clock = { "vfe2", "vfe2_axi", "soc_ahb",
+			   "cpas_ahb", "camnoc_axi",
+			   "gcc_camera_axi"},
+		.clock_rate = {
+			{ 380000000, 0, 80000000, 0, 150000000, 0},
+			{ 510000000, 0, 80000000, 0, 240000000, 0},
+			{ 637000000, 0, 80000000, 0, 320000000, 0},
+			{ 760000000, 0, 80000000, 0, 400000000, 0},
+			{ 760000000, 0, 80000000, 0, 480000000, 0},
+		},
+
+		.reg = { "vfe2" },
+		.interrupt = { "vfe2" },
+		.vfe = {
+			.line_num = 3,
+			.is_lite = false,
+			.hw_ops = &vfe_ops_170,
+			.has_pd = true,
+			.pd_name = "ife2",
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE3 (lite) */
+	{
+		.clock = { "vfe0_lite", "soc_ahb", "cpas_ahb",
+			   "camnoc_axi", "gcc_camera_axi"},
+		.clock_rate = {
+			{ 320000000, 80000000, 0, 150000000, 0},
+			{ 400000000, 80000000, 0, 240000000, 0},
+			{ 480000000, 80000000, 0, 320000000, 0},
+			{ 600000000, 80000000, 0, 400000000, 0},
+		},
+
+		.regulators = {},
+		.reg = { "vfe_lite0" },
+		.interrupt = { "vfe_lite0" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE4 (lite) */
+	{
+		.clock = { "vfe1_lite", "soc_ahb", "cpas_ahb",
+			   "camnoc_axi", "gcc_camera_axi"},
+		.clock_rate = {
+			{ 320000000, 80000000, 0, 150000000, 0},
+			{ 400000000, 80000000, 0, 240000000, 0},
+			{ 480000000, 80000000, 0, 320000000, 0},
+			{ 600000000, 80000000, 0, 400000000, 0},
+		},
+
+		.regulators = {},
+		.reg = { "vfe_lite1" },
+		.interrupt = { "vfe_lite1" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_170,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+};
+
+static const struct resources_icc icc_res_sc7280[] = {
+	{
+		.name = "ahb",
+		.icc_bw_tbl.avg = 38400,
+		.icc_bw_tbl.peak = 76800,
+	},
+	{
+		.name = "hf_0",
+		.icc_bw_tbl.avg = 2097152,
+		.icc_bw_tbl.peak = 2097152,
+	},
+};
+
+static const struct camss_subdev_resources csiphy_res_8300[] = {
+	/* CSIPHY0 */
+	{
+		.regulators = {},
+		.clock = { "csid_csiphy_rx", "csiphy0", "csiphy0_timer"},
+		.clock_rate = {
+			{ 400000000, 0, 400000000}
+		},
+		.reg = { "csiphy0" },
+		.interrupt = { "csiphy0" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sa8775p
+		}
+	},
+	/* CSIPHY1 */
+	{
+		.regulators = {},
+		.clock = { "csid_csiphy_rx", "csiphy1", "csiphy1_timer"},
+		.clock_rate = {
+			{ 400000000, 0, 400000000}
+		},
+		.reg = { "csiphy1" },
+		.interrupt = { "csiphy1" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sa8775p
+		}
+	},
+	/* CSIPHY2 */
+	{
+		.regulators = {},
+		.clock = { "csid_csiphy_rx", "csiphy2", "csiphy2_timer"},
+		.clock_rate = {
+			{ 400000000, 0, 400000000}
+		},
+		.reg = { "csiphy2" },
+		.interrupt = { "csiphy2" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sa8775p
+		}
+	},
+};
+
+static const struct camss_subdev_resources tpg_res_8300[] = {
+	/* TPG0 */
+	{
+		.regulators = {  },
+		.clock = { "cphy_rx_clk" },
+		.clock_rate = { { 400000000 } },
+		.reg = { "tpg0" },
+		.interrupt = { "tpg0" },
+		.tpg = {
+			.lane_cnt = 4,
+			.vc_cnt = 1,
+			.formats = &tpg_formats_gen1,
+			.hw_ops = &tpg_ops_gen1
+		}
+	},
+
+	/* TPG1 */
+	{
+		.regulators = {  },
+		.clock = { "cphy_rx_clk" },
+		.clock_rate = { { 400000000 } },
+		.reg = { "tpg1" },
+		.interrupt = { "tpg1" },
+		.tpg = {
+			.lane_cnt = 4,
+			.vc_cnt = 1,
+			.formats = &tpg_formats_gen1,
+			.hw_ops = &tpg_ops_gen1
+		}
+	},
+
+	/* TPG2 */
+	{
+		.regulators = {  },
+		.clock = { "cphy_rx_clk" },
+		.clock_rate = { { 400000000 } },
+		.reg = { "tpg2" },
+		.interrupt = { "tpg2" },
+		.tpg = {
+			.lane_cnt = 4,
+			.vc_cnt = 1,
+			.formats = &tpg_formats_gen1,
+			.hw_ops = &tpg_ops_gen1
+		}
+	},
+};
+
+static const struct camss_subdev_resources csid_res_8300[] = {
+	/* CSID0 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csid", "csid_csiphy_rx"},
+		.clock_rate = {
+			{ 400000000, 400000000},
+			{ 400000000, 400000000}
+		},
+
+		.reg = { "csid0" },
+		.interrupt = { "csid0", "csid_top" },
+		.csid = {
+			.is_lite = false,
+			.hw_ops = &csid_ops_gen3,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID1 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csid", "csid_csiphy_rx"},
+		.clock_rate = {
+			{ 400000000, 400000000},
+			{ 400000000, 400000000}
+		},
+
+		.reg = { "csid1", "csid_top" },
+		.interrupt = { "csid1" },
+		.csid = {
+			.is_lite = false,
+			.hw_ops = &csid_ops_gen3,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+
+	/* CSID2 (lite) */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 400000000, 400000000, 0},
+			{ 0, 0, 400000000, 480000000, 0}
+		},
+
+		.reg = { "csid_lite0" },
+		.interrupt = { "csid-lite0" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen3,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID3 (lite) */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 400000000, 400000000, 0},
+			{ 0, 0, 400000000, 480000000, 0}
+		},
+
+		.reg = { "csid_lite1" },
+		.interrupt = { "csid-lite1" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen3,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID4 (lite) */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 400000000, 400000000, 0},
+			{ 0, 0, 400000000, 480000000, 0}
+		},
+
+		.reg = { "csid_lite2" },
+		.interrupt = { "csid-lite2" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen3,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID5 (lite) */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 400000000, 400000000, 0},
+			{ 0, 0, 400000000, 480000000, 0}
+		},
+
+		.reg = { "csid_lite3" },
+		.interrupt = { "csid-lite3" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen3,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID6 (lite) */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 400000000, 400000000, 0},
+			{ 0, 0, 400000000, 480000000, 0}
+		},
+
+		.reg = { "csid_lite4" },
+		.interrupt = { "csid-lite4" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen3,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+};
+
+static const struct camss_subdev_resources vfe_res_8300[] = {
+	/* VFE0 */
+	{
+		.regulators = {},
+
+		.clock = { "cpas_vfe0", "vfe0", "vfe0_fast_ahb",
+			   "cpas_ahb", "gcc_camera_ahb", "gcc_axi_hf", "gcc_axi_sf",
+			   "core_ahb", "cpas_fast_ahb_clk", "camnoc_axi",
+			   "icp_ahb"},
+		.clock_rate = {
+			{ 0, 0, 0, 0  },
+			{ 480000000, 480000000, 480000000, 480000000 },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 0, 0, 0, 80000000 },
+			{ 37500000, 75000000, 75000000, 75000000 },
+			{ 403200000, 533000000, 600000000, 600000000 },
+			{ 403200000, 533000000, 600000000, 600000000 },
+			{ 0, 0, 0, 80000000 },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 0 },
+		},
+
+		.reg = { "vfe0" },
+		.interrupt = { "vfe0" },
+		.vfe = {
+			.line_num = 3,
+			.is_lite = false,
+			.has_pd = false,
+			.pd_name = NULL,
+			.hw_ops = &vfe_ops_690,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE1 */
+	{
+		.regulators = {},
+
+		.clock = { "cpas_vfe1", "vfe1", "vfe1_fast_ahb",
+			   "cpas_ahb", "gcc_camera_ahb", "gcc_axi_hf", "gcc_axi_sf",
+			   "core_ahb", "cpas_fast_ahb_clk", "camnoc_axi",
+			   "icp_ahb"},
+		.clock_rate = {
+			{ 0, 0, 0, 0  },
+			{ 480000000, 480000000, 480000000, 480000000 },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 0, 0, 0, 80000000 },
+			{ 37500000, 75000000, 75000000, 75000000 },
+			{ 403200000, 533000000, 600000000, 600000000 },
+			{ 403200000, 533000000, 600000000, 600000000 },
+			{ 0, 0, 0, 80000000 },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 0 },
+		},
+
+		.reg = { "vfe1" },
+		.interrupt = { "vfe1" },
+		.vfe = {
+			.line_num = 3,
+			.is_lite = false,
+			.has_pd = false,
+			.pd_name = NULL,
+			.hw_ops = &vfe_ops_690,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+
+	/* VFE2 (lite) */
+	{
+		.regulators = {},
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 0, 0  },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 480000000, 600000000, 600000000, 600000000 },
+		},
+		.reg = { "vfe_lite0" },
+		.interrupt = { "vfe-lite0" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_690,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE3 (lite) */
+	{
+		.regulators = {},
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 0, 0  },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 480000000, 600000000, 600000000, 600000000 },
+		},
+		.reg = { "vfe_lite1" },
+		.interrupt = { "vfe-lite1" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_690,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE4 (lite) */
+	{
+		.regulators = {},
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 0, 0  },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 480000000, 600000000, 600000000, 600000000 },
+		},
+		.reg = { "vfe_lite2" },
+		.interrupt = { "vfe-lite2" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_690,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE5 (lite) */
+	{
+		.regulators = {},
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 0, 0  },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 480000000, 600000000, 600000000, 600000000 },
+		},
+		.reg = { "vfe_lite3" },
+		.interrupt = { "vfe-lite3" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_690,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE6 (lite) */
+	{
+		.regulators = {},
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 0, 0  },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 480000000, 600000000, 600000000, 600000000 },
+		},
+		.reg = { "vfe_lite4" },
+		.interrupt = { "vfe-lite4" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_690,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+};
+
+static const struct resources_icc icc_res_qcs8300[] = {
+	{
+		.name = "ahb",
+		.icc_bw_tbl.avg = 38400,
+		.icc_bw_tbl.peak = 76800,
+	},
+	{
+		.name = "hf_0",
+		.icc_bw_tbl.avg = 2097152,
+		.icc_bw_tbl.peak = 2097152,
+	},
+};
+
+static const struct camss_subdev_resources csiphy_res_8775p[] = {
+	/* CSIPHY0 */
+	{
+		.regulators = {},
+		.clock = { "csid_csiphy_rx", "csiphy0", "csiphy0_timer"},
+		.clock_rate = {
+			{ 400000000, 0, 400000000}
+		},
+		.reg = { "csiphy0" },
+		.interrupt = { "csiphy0" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sa8775p
+		}
+	},
+	/* CSIPHY1 */
+	{
+		.regulators = {},
+		.clock = { "csid_csiphy_rx", "csiphy1", "csiphy1_timer"},
+		.clock_rate = {
+			{ 400000000, 0, 400000000}
+		},
+		.reg = { "csiphy1" },
+		.interrupt = { "csiphy1" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sa8775p
+		}
+	},
+	/* CSIPHY2 */
+	{
+		.regulators = {},
+		.clock = { "csid_csiphy_rx", "csiphy2", "csiphy2_timer"},
+		.clock_rate = {
+			{ 400000000, 0, 400000000}
+		},
+		.reg = { "csiphy2" },
+		.interrupt = { "csiphy2" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sa8775p
+		}
+	},
+	/* CSIPHY3 */
+	{
+		.regulators = {},
+		.clock = { "csid_csiphy_rx", "csiphy3", "csiphy3_timer"},
+		.clock_rate = {
+			{ 400000000, 0, 400000000}
+		},
+		.reg = { "csiphy3" },
+		.interrupt = { "csiphy3" },
+		.csiphy = {
+			.hw_ops = &csiphy_ops_3ph_1_0,
+			.formats = &csiphy_formats_sa8775p
+		}
+	},
+};
+
+static const struct camss_subdev_resources tpg_res_8775p[] = {
+	/* TPG0 */
+	{
+		.regulators = {  },
+		.clock = { "cphy_rx_clk" },
+		.clock_rate = { { 400000000 } },
+		.reg = { "tpg0" },
+		.interrupt = { "tpg0" },
+		.tpg = {
+			.lane_cnt = 4,
+			.vc_cnt = 1,
+			.formats = &tpg_formats_gen1,
+			.hw_ops = &tpg_ops_gen1
+		}
+	},
+
+	/* TPG1 */
+	{
+		.regulators = {  },
+		.clock = { "cphy_rx_clk" },
+		.clock_rate = { { 400000000 } },
+		.reg = { "tpg1" },
+		.interrupt = { "tpg1" },
+		.tpg = {
+			.lane_cnt = 4,
+			.vc_cnt = 1,
+			.formats = &tpg_formats_gen1,
+			.hw_ops = &tpg_ops_gen1
+		}
+	},
+
+	/* TPG2 */
+	{
+		.regulators = {  },
+		.clock = { "cphy_rx_clk" },
+		.clock_rate = { { 400000000 } },
+		.reg = { "tpg2" },
+		.interrupt = { "tpg2" },
+		.tpg = {
+			.lane_cnt = 4,
+			.vc_cnt = 1,
+			.formats = &tpg_formats_gen1,
+			.hw_ops = &tpg_ops_gen1
+		}
+	},
+};
+
+static const struct camss_subdev_resources csid_res_8775p[] = {
+	/* CSID0 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csid", "csid_csiphy_rx"},
+		.clock_rate = {
+			{ 400000000, 400000000},
+			{ 400000000, 400000000}
+		},
+
+		.reg = { "csid0" },
+		.interrupt = { "csid0", "csid_top" },
+		.csid = {
+			.is_lite = false,
+			.hw_ops = &csid_ops_gen3,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID1 */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "csid", "csid_csiphy_rx"},
+		.clock_rate = {
+			{ 400000000, 400000000},
+			{ 400000000, 400000000}
+		},
+
+		.reg = { "csid1", "csid_top" },
+		.interrupt = { "csid1" },
+		.csid = {
+			.is_lite = false,
+			.hw_ops = &csid_ops_gen3,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+
+	/* CSID2 (lite) */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 400000000, 400000000, 0},
+			{ 0, 0, 400000000, 480000000, 0}
+		},
+
+		.reg = { "csid_lite0" },
+		.interrupt = { "csid-lite0" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen3,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID3 (lite) */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 400000000, 400000000, 0},
+			{ 0, 0, 400000000, 480000000, 0}
+		},
+
+		.reg = { "csid_lite1" },
+		.interrupt = { "csid-lite1" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen3,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID4 (lite) */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 400000000, 400000000, 0},
+			{ 0, 0, 400000000, 480000000, 0}
+		},
+
+		.reg = { "csid_lite2" },
+		.interrupt = { "csid-lite2" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen3,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID5 (lite) */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 400000000, 400000000, 0},
+			{ 0, 0, 400000000, 480000000, 0}
+		},
+
+		.reg = { "csid_lite3" },
+		.interrupt = { "csid-lite3" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen3,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+	/* CSID6 (lite) */
+	{
+		.regulators = { "vdda-phy", "vdda-pll" },
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 400000000, 400000000, 0},
+			{ 0, 0, 400000000, 480000000, 0}
+		},
+
+		.reg = { "csid_lite4" },
+		.interrupt = { "csid-lite4" },
+		.csid = {
+			.is_lite = true,
+			.hw_ops = &csid_ops_gen3,
+			.parent_dev_ops = &vfe_parent_dev_ops,
+			.formats = &csid_formats_gen2
+		}
+	},
+};
+
+static const struct camss_subdev_resources vfe_res_8775p[] = {
+	/* VFE0 */
+	{
+		.regulators = {},
+
+		.clock = { "cpas_vfe0", "vfe0", "vfe0_fast_ahb",
+			   "cpas_ahb", "gcc_camera_ahb", "gcc_axi_hf", "gcc_axi_sf",
+			   "core_ahb", "cpas_fast_ahb_clk", "camnoc_axi",
+			   "icp_ahb"},
+		.clock_rate = {
+			{ 0, 0, 0, 0  },
+			{ 480000000, 480000000, 480000000, 480000000 },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 0, 0, 0, 80000000 },
+			{ 37500000, 75000000, 75000000, 75000000 },
+			{ 403200000, 533000000, 600000000, 600000000 },
+			{ 403200000, 533000000, 600000000, 600000000 },
+			{ 0, 0, 0, 80000000 },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 0 },
+		},
+
+		.reg = { "vfe0" },
+		.interrupt = { "vfe0" },
+		.vfe = {
+			.line_num = 3,
+			.is_lite = false,
+			.has_pd = false,
+			.pd_name = NULL,
+			.hw_ops = &vfe_ops_690,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE1 */
+	{
+		.regulators = {},
+
+		.clock = { "cpas_vfe1", "vfe1", "vfe1_fast_ahb",
+			   "cpas_ahb", "gcc_camera_ahb", "gcc_axi_hf", "gcc_axi_sf",
+			   "core_ahb", "cpas_fast_ahb_clk", "camnoc_axi",
+			   "icp_ahb"},
+		.clock_rate = {
+			{ 0, 0, 0, 0  },
+			{ 480000000, 480000000, 480000000, 480000000 },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 0, 0, 0, 80000000 },
+			{ 37500000, 75000000, 75000000, 75000000 },
+			{ 403200000, 533000000, 600000000, 600000000 },
+			{ 403200000, 533000000, 600000000, 600000000 },
+			{ 0, 0, 0, 80000000 },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 0 },
+		},
+
+		.reg = { "vfe1" },
+		.interrupt = { "vfe1" },
+		.vfe = {
+			.line_num = 3,
+			.is_lite = false,
+			.has_pd = false,
+			.pd_name = NULL,
+			.hw_ops = &vfe_ops_690,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+
+	/* VFE2 (lite) */
+	{
+		.regulators = {},
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 0, 0  },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 480000000, 600000000, 600000000, 600000000 },
+		},
+		.reg = { "vfe_lite0" },
+		.interrupt = { "vfe-lite0" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_690,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE3 (lite) */
+	{
+		.regulators = {},
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 0, 0  },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 480000000, 600000000, 600000000, 600000000 },
+		},
+		.reg = { "vfe_lite1" },
+		.interrupt = { "vfe-lite1" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_690,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE4 (lite) */
+	{
+		.regulators = {},
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 0, 0  },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 480000000, 600000000, 600000000, 600000000 },
+		},
+		.reg = { "vfe_lite2" },
+		.interrupt = { "vfe-lite2" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_690,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE5 (lite) */
+	{
+		.regulators = {},
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 0, 0  },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 480000000, 600000000, 600000000, 600000000 },
+		},
+		.reg = { "vfe_lite3" },
+		.interrupt = { "vfe-lite3" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_690,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+	/* VFE6 (lite) */
+	{
+		.regulators = {},
+
+		.clock = { "cpas_vfe_lite", "vfe_lite_ahb",
+			   "vfe_lite_csid", "vfe_lite_cphy_rx",
+			   "vfe_lite"},
+		.clock_rate = {
+			{ 0, 0, 0, 0  },
+			{ 300000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 400000000, 400000000, 400000000, 400000000 },
+			{ 480000000, 600000000, 600000000, 600000000 },
+		},
+		.reg = { "vfe_lite4" },
+		.interrupt = { "vfe-lite4" },
+		.vfe = {
+			.line_num = 4,
+			.is_lite = true,
+			.hw_ops = &vfe_ops_690,
+			.formats_rdi = &vfe_formats_rdi_845,
+			.formats_pix = &vfe_formats_pix_845
+		}
+	},
+};
+
+static const struct resources_icc icc_res_sa8775p[] = {
+	{
+		.name = "ahb",
+		.icc_bw_tbl.avg = 38400,
+		.icc_bw_tbl.peak = 76800,
+	},
+	{
+		.name = "hf_0",
+		.icc_bw_tbl.avg = 2097152,
+		.icc_bw_tbl.peak = 2097152,
+	},
+};
+
 /*
  * camss_add_clock_margin - Add margin to clock frequency rate
  * @rate: Clock frequency rate
@@ -1083,7 +2852,7 @@
 	if (id < camss->res->vfe_num) {
 		struct vfe_device *vfe = &camss->vfe[id];
 
-		ret = vfe->ops->pm_domain_on(vfe);
+		ret = vfe->res->hw_ops->pm_domain_on(vfe);
 	}
 
 	return ret;
@@ -1094,10 +2863,72 @@
 	if (id < camss->res->vfe_num) {
 		struct vfe_device *vfe = &camss->vfe[id];
 
-		vfe->ops->pm_domain_off(vfe);
+		vfe->res->hw_ops->pm_domain_off(vfe);
 	}
 }
 
+void camss_reg_update(struct camss *camss, int hw_id, int port_id, bool is_clear)
+{
+	struct csid_device *csid;
+
+	if (hw_id < camss->res->csid_num) {
+		csid = &(camss->csid[hw_id]);
+		csid->res->hw_ops->reg_update(csid, port_id, is_clear);
+	}
+}
+
+void camss_buf_done(struct camss *camss, int hw_id, int port_id)
+{
+	struct vfe_device *vfe;
+
+	if (hw_id < camss->res->vfe_num) {
+		vfe = &(camss->vfe[hw_id]);
+		vfe->res->hw_ops->vfe_buf_done(vfe, port_id);
+	}
+}
+
+static int vfe_parent_dev_ops_get(struct camss *camss, int id)
+{
+	int ret = -EINVAL;
+
+	if (id < camss->res->vfe_num) {
+		struct vfe_device *vfe = &camss->vfe[id];
+
+		ret = vfe_get(vfe);
+	}
+
+	return ret;
+}
+
+static int vfe_parent_dev_ops_put(struct camss *camss, int id)
+{
+	if (id < camss->res->vfe_num) {
+		struct vfe_device *vfe = &camss->vfe[id];
+
+		vfe_put(vfe);
+	}
+
+	return 0;
+}
+
+static void __iomem
+*vfe_parent_dev_ops_get_base_address(struct camss *camss, int id)
+{
+	if (id < camss->res->vfe_num) {
+		struct vfe_device *vfe = &camss->vfe[id];
+
+		return vfe->base;
+	}
+
+	return NULL;
+}
+
+static const struct parent_dev_ops vfe_parent_dev_ops = {
+	.get = vfe_parent_dev_ops_get,
+	.put = vfe_parent_dev_ops_put,
+	.get_base_address = vfe_parent_dev_ops_get_base_address
+};
+
 /*
  * camss_of_parse_endpoint_node - Parse port endpoint node
  * @dev: Device
@@ -1114,8 +2945,11 @@
 	struct v4l2_mbus_config_mipi_csi2 *mipi_csi2;
 	struct v4l2_fwnode_endpoint vep = { { 0 } };
 	unsigned int i;
+	int ret;
 
-	v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
+	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &vep);
+	if (ret)
+		return ret;
 
 	csd->interface.csiphy_id = vep.base.port;
 
@@ -1240,76 +3074,135 @@
 		return ret;
 	}
 
+	if (camss->tpg) {
+		for (i = 0; i < camss->res->tpg_num; i++) {
+			ret = msm_tpg_subdev_init(camss, &camss->tpg[i],
+						  &res->tpg_res[i], i);
+			if (ret < 0) {
+				dev_err(camss->dev,
+					"Failed to init tpg%d sub-device: %d\n",
+					i, ret);
+				return ret;
+			}
+		}
+	}
+
 	return 0;
 }
 
 /*
- * camss_register_entities - Register subdev nodes and create links
+ * camss_link_entities_tpg - Register subdev nodes and create links
  * @camss: CAMSS device
  *
  * Return 0 on success or a negative error code on failure
  */
-static int camss_register_entities(struct camss *camss)
+static int camss_link_entities_tpg(struct camss *camss)
 {
-	int i, j, k;
+	int i, j;
 	int ret;
 
-	for (i = 0; i < camss->res->csiphy_num; i++) {
-		ret = msm_csiphy_register_entity(&camss->csiphy[i],
-						 &camss->v4l2_dev);
-		if (ret < 0) {
-			dev_err(camss->dev,
-				"Failed to register csiphy%d entity: %d\n",
-				i, ret);
-			goto err_reg_csiphy;
+	for (i = 0; i < camss->res->tpg_num; i++) {
+		for (j = 0; j < camss->res->csid_num; j++) {
+			ret = media_create_pad_link(&camss->tpg[i].subdev.entity,
+						    MSM_TPG_PAD_SRC,
+						    &camss->csid[j].subdev.entity,
+						    MSM_CSID_PAD_SINK,
+						    0);
+			if (ret < 0) {
+				dev_err(camss->dev,
+					"Failed to link %s->%s entities: %d\n",
+					camss->tpg[i].subdev.entity.name,
+					camss->csid[j].subdev.entity.name,
+					ret);
+				return ret;
+			}
 		}
 	}
+	return 0;
+}
 
-	for (i = 0; i < camss->res->csid_num; i++) {
-		ret = msm_csid_register_entity(&camss->csid[i],
-					       &camss->v4l2_dev);
-		if (ret < 0) {
-			dev_err(camss->dev,
-				"Failed to register csid%d entity: %d\n",
-				i, ret);
-			goto err_reg_csid;
-		}
-	}
+/*
+ * camss_link_entities_v2 - Register subdev nodes and create links
+ * @camss: CAMSS device
+ *
+ * Return 0 on success or a negative error code on failure
+ */
+static int camss_link_entities_v2(struct camss *camss)
+{
+	int i, j;
+	int ret;
 
-	ret = msm_ispif_register_entities(camss->ispif,
-					  &camss->v4l2_dev);
-	if (ret < 0) {
-		dev_err(camss->dev, "Failed to register ispif entities: %d\n",
-		ret);
-		goto err_reg_ispif;
+	for (i = 0; i < camss->res->csiphy_num; i++) {
+		for (j = 0; j < camss->res->csid_num; j++) {
+			ret = media_create_pad_link(&camss->csiphy[i].subdev.entity,
+						    MSM_CSIPHY_PAD_SRC,
+						    &camss->csid[j].subdev.entity,
+						    MSM_CSID_PAD_SINK,
+						    0);
+			if (ret < 0) {
+				dev_err(camss->dev,
+					"Failed to link %s->%s entities: %d\n",
+					camss->csiphy[i].subdev.entity.name,
+					camss->csid[j].subdev.entity.name,
+					ret);
+				return ret;
+			}
+		}
 	}
 
-	for (i = 0; i < camss->res->vfe_num; i++) {
-		ret = msm_vfe_register_entities(&camss->vfe[i],
-						&camss->v4l2_dev);
-		if (ret < 0) {
-			dev_err(camss->dev,
-				"Failed to register vfe%d entities: %d\n",
-				i, ret);
-			goto err_reg_vfe;
+	for (i = 0; i < camss->res->csid_num; i++)
+		for (j = 0; j < camss->vfe[i].res->line_num; j++) {
+			struct v4l2_subdev *csid = &camss->csid[i].subdev;
+			struct v4l2_subdev *vfe = &camss->vfe[i].line[j].subdev;
+
+			ret = media_create_pad_link(&csid->entity,
+						    MSM_CSID_PAD_FIRST_SRC + j,
+						    &vfe->entity,
+						    MSM_VFE_PAD_SINK,
+						    0);
+			if (ret < 0) {
+				dev_err(camss->dev,
+					"Failed to link %s->%s entities: %d\n",
+					csid->entity.name,
+					vfe->entity.name,
+					ret);
+				return ret;
+			}
 		}
+	return 0;
+}
+
+/*
+ * camss_link_entities - Register subdev nodes and create links
+ * @camss: CAMSS device
+ *
+ * Return 0 on success or a negative error code on failure
+ */
+static int camss_link_entities(struct camss *camss)
+{
+	int i, j, k;
+	int ret;
+
+	if (camss->tpg) {
+		ret = camss_link_entities_tpg(camss);
+		if (ret < 0)
+			return ret;
 	}
 
 	for (i = 0; i < camss->res->csiphy_num; i++) {
 		for (j = 0; j < camss->res->csid_num; j++) {
-			ret = media_create_pad_link(
-				&camss->csiphy[i].subdev.entity,
-				MSM_CSIPHY_PAD_SRC,
-				&camss->csid[j].subdev.entity,
-				MSM_CSID_PAD_SINK,
-				0);
+			ret = media_create_pad_link(&camss->csiphy[i].subdev.entity,
+						    MSM_CSIPHY_PAD_SRC,
+						    &camss->csid[j].subdev.entity,
+						    MSM_CSID_PAD_SINK,
+						    0);
 			if (ret < 0) {
 				dev_err(camss->dev,
 					"Failed to link %s->%s entities: %d\n",
 					camss->csiphy[i].subdev.entity.name,
 					camss->csid[j].subdev.entity.name,
 					ret);
-				goto err_link;
+				return ret;
 			}
 		}
 	}
@@ -1317,26 +3210,25 @@
 	if (camss->ispif) {
 		for (i = 0; i < camss->res->csid_num; i++) {
 			for (j = 0; j < camss->ispif->line_num; j++) {
-				ret = media_create_pad_link(
-					&camss->csid[i].subdev.entity,
-					MSM_CSID_PAD_SRC,
-					&camss->ispif->line[j].subdev.entity,
-					MSM_ISPIF_PAD_SINK,
-					0);
+				ret = media_create_pad_link(&camss->csid[i].subdev.entity,
+							    MSM_CSID_PAD_SRC,
+							    &camss->ispif->line[j].subdev.entity,
+							    MSM_ISPIF_PAD_SINK,
+							    0);
 				if (ret < 0) {
 					dev_err(camss->dev,
 						"Failed to link %s->%s entities: %d\n",
 						camss->csid[i].subdev.entity.name,
 						camss->ispif->line[j].subdev.entity.name,
 						ret);
-					goto err_link;
+					return ret;
 				}
 			}
 		}
 
 		for (i = 0; i < camss->ispif->line_num; i++)
 			for (k = 0; k < camss->res->vfe_num; k++)
-				for (j = 0; j < camss->vfe[k].line_num; j++) {
+				for (j = 0; j < camss->vfe[k].res->line_num; j++) {
 					struct v4l2_subdev *ispif = &camss->ispif->line[i].subdev;
 					struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
 
@@ -1351,13 +3243,13 @@
 							ispif->entity.name,
 							vfe->entity.name,
 							ret);
-						goto err_link;
+						return ret;
 					}
 				}
 	} else {
 		for (i = 0; i < camss->res->csid_num; i++)
 			for (k = 0; k < camss->res->vfe_num; k++)
-				for (j = 0; j < camss->vfe[k].line_num; j++) {
+				for (j = 0; j < camss->vfe[k].res->line_num; j++) {
 					struct v4l2_subdev *csid = &camss->csid[i].subdev;
 					struct v4l2_subdev *vfe = &camss->vfe[k].line[j].subdev;
 
@@ -1372,15 +3264,80 @@
 							csid->entity.name,
 							vfe->entity.name,
 							ret);
-						goto err_link;
+						return ret;
 					}
 				}
 	}
 
 	return 0;
+}
+
+/*
+ * camss_register_entities - Register subdev nodes and create links
+ * @camss: CAMSS device
+ *
+ * Return 0 on success or a negative error code on failure
+ */
+static int camss_register_entities(struct camss *camss)
+{
+	int i;
+	int ret;
+
+	if (camss->tpg) {
+		for (i = 0; i < camss->res->tpg_num; i++) {
+			ret = msm_tpg_register_entity(&camss->tpg[i],
+						      &camss->v4l2_dev);
+			if (ret < 0) {
+				dev_err(camss->dev,
+					"Failed to register tpg%d entity: %d\n",
+					i, ret);
+				goto err_reg_tpg;
+			}
+		}
+	}
+
+	for (i = 0; i < camss->res->csiphy_num; i++) {
+		ret = msm_csiphy_register_entity(&camss->csiphy[i],
+						 &camss->v4l2_dev);
+		if (ret < 0) {
+			dev_err(camss->dev,
+				"Failed to register csiphy%d entity: %d\n",
+				i, ret);
+			goto err_reg_csiphy;
+		}
+	}
+
+	for (i = 0; i < camss->res->csid_num; i++) {
+		ret = msm_csid_register_entity(&camss->csid[i],
+					       &camss->v4l2_dev);
+		if (ret < 0) {
+			dev_err(camss->dev,
+				"Failed to register csid%d entity: %d\n",
+				i, ret);
+			goto err_reg_csid;
+		}
+	}
+
+	ret = msm_ispif_register_entities(camss->ispif,
+					  &camss->v4l2_dev);
+	if (ret < 0) {
+		dev_err(camss->dev, "Failed to register ispif entities: %d\n", ret);
+		goto err_reg_ispif;
+	}
+
+	for (i = 0; i < camss->res->vfe_num; i++) {
+		ret = msm_vfe_register_entities(&camss->vfe[i],
+						&camss->v4l2_dev);
+		if (ret < 0) {
+			dev_err(camss->dev,
+				"Failed to register vfe%d entities: %d\n",
+				i, ret);
+			goto err_reg_vfe;
+		}
+	}
+
+	return 0;
 
-err_link:
-	i = camss->res->vfe_num;
 err_reg_vfe:
 	for (i--; i >= 0; i--)
 		msm_vfe_unregister_entities(&camss->vfe[i]);
@@ -1398,6 +3355,11 @@
 	for (i--; i >= 0; i--)
 		msm_csiphy_unregister_entity(&camss->csiphy[i]);
 
+	i = camss->res->tpg_num;
+err_reg_tpg:
+	for (i--; i >= 0; i--)
+		msm_tpg_unregister_entity(&camss->tpg[i]);
+
 	return ret;
 }
 
@@ -1410,6 +3372,8 @@
 static void camss_unregister_entities(struct camss *camss)
 {
 	unsigned int i;
+	for (i = 0; i < camss->res->tpg_num; i++)
+		msm_tpg_unregister_entity(&camss->tpg[i]);
 
 	for (i = 0; i < camss->res->csiphy_num; i++)
 		msm_csiphy_unregister_entity(&camss->csiphy[i]);
@@ -1518,7 +3482,7 @@
 
 	/* count the # of VFEs which have flagged power-domain */
 	for (vfepd_num = i = 0; i < camss->res->vfe_num; i++) {
-		if (res->vfe_res[i].has_pd)
+		if (res->vfe_res[i].vfe.has_pd)
 			vfepd_num++;
 	}
 
@@ -1537,10 +3501,8 @@
 	if (camss->res->pd_name) {
 		camss->genpd = dev_pm_domain_attach_by_name(camss->dev,
 							    camss->res->pd_name);
-		if (IS_ERR(camss->genpd)) {
-			ret = PTR_ERR(camss->genpd);
-			goto fail_pm;
-		}
+		if (IS_ERR(camss->genpd))
+			return PTR_ERR(camss->genpd);
 	}
 
 	if (!camss->genpd) {
@@ -1550,22 +3512,35 @@
 		 */
 		camss->genpd = dev_pm_domain_attach_by_id(camss->dev,
 							  camss->genpd_num - 1);
+		if (IS_ERR(camss->genpd))
+			return PTR_ERR(camss->genpd);
 	}
-	if (IS_ERR_OR_NULL(camss->genpd)) {
-		if (!camss->genpd)
-			ret = -ENODEV;
-		else
-			ret = PTR_ERR(camss->genpd);
-		goto fail_pm;
+
+	if (!camss->genpd)
+		return -ENODEV;
+
+	ret = devm_pm_opp_set_clkname(camss->dev, "vfe0");
+	if (ret) {
+		dev_err(dev, "devm_pm_opp_set_clkname failed %d\n", ret);
+		return ret;
 	}
+
 	camss->genpd_link = device_link_add(camss->dev, camss->genpd,
 					    DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
 					    DL_FLAG_RPM_ACTIVE);
 	if (!camss->genpd_link) {
+		dev_err(dev, "device_link_add failed %d\n", ret);
 		ret = -EINVAL;
 		goto fail_pm;
 	}
 
+	ret = devm_pm_opp_of_add_table(camss->dev);
+	if (ret) {
+		dev_err(dev, "devm_pm_opp_of_add_table failed %d\n", ret);
+		device_link_del(camss->genpd_link);
+		goto fail_pm;
+	}
+
 	return 0;
 
 fail_pm:
@@ -1640,6 +3615,14 @@
 	if (!camss->csiphy)
 		return -ENOMEM;
 
+	if (camss->res->version == CAMSS_8775P ||
+	    camss->res->version == CAMSS_8300) {
+		camss->tpg = devm_kcalloc(dev, camss->res->tpg_num,
+					  sizeof(*camss->tpg), GFP_KERNEL);
+		if (!camss->tpg)
+			return -ENOMEM;
+	}
+
 	camss->csid = devm_kcalloc(dev, camss->res->csid_num, sizeof(*camss->csid),
 				   GFP_KERNEL);
 	if (!camss->csid)
@@ -1690,6 +3673,8 @@
 
 	v4l2_async_nf_init(&camss->notifier, &camss->v4l2_dev);
 
+	pm_runtime_enable(dev);
+
 	num_subdevs = camss_of_parse_ports(camss);
 	if (num_subdevs < 0) {
 		ret = num_subdevs;
@@ -1700,6 +3685,10 @@
 	if (ret < 0)
 		goto err_v4l2_device_unregister;
 
+	ret = camss->res->link_entities(camss);
+	if (ret < 0)
+		goto err_register_subdevs;
+
 	if (num_subdevs) {
 		camss->notifier.ops = &camss_subdev_notifier_ops;
 
@@ -1726,8 +3715,6 @@
 		}
 	}
 
-	pm_runtime_enable(dev);
-
 	return 0;
 
 err_register_subdevs:
@@ -1735,6 +3722,7 @@
 err_v4l2_device_unregister:
 	v4l2_device_unregister(&camss->v4l2_dev);
 	v4l2_async_nf_cleanup(&camss->notifier);
+	pm_runtime_disable(dev);
 err_genpd_cleanup:
 	camss_genpd_cleanup(camss);
 
@@ -1779,6 +3767,7 @@
 	.csiphy_num = ARRAY_SIZE(csiphy_res_8x16),
 	.csid_num = ARRAY_SIZE(csid_res_8x16),
 	.vfe_num = ARRAY_SIZE(vfe_res_8x16),
+	.link_entities = camss_link_entities
 };
 
 static const struct camss_resources msm8996_resources = {
@@ -1790,6 +3779,7 @@
 	.csiphy_num = ARRAY_SIZE(csiphy_res_8x96),
 	.csid_num = ARRAY_SIZE(csid_res_8x96),
 	.vfe_num = ARRAY_SIZE(vfe_res_8x96),
+	.link_entities = camss_link_entities
 };
 
 static const struct camss_resources sdm660_resources = {
@@ -1801,6 +3791,7 @@
 	.csiphy_num = ARRAY_SIZE(csiphy_res_660),
 	.csid_num = ARRAY_SIZE(csid_res_660),
 	.vfe_num = ARRAY_SIZE(vfe_res_660),
+	.link_entities = camss_link_entities
 };
 
 static const struct camss_resources sdm845_resources = {
@@ -1811,6 +3802,7 @@
 	.csiphy_num = ARRAY_SIZE(csiphy_res_845),
 	.csid_num = ARRAY_SIZE(csid_res_845),
 	.vfe_num = ARRAY_SIZE(vfe_res_845),
+	.link_entities = camss_link_entities
 };
 
 static const struct camss_resources sm8250_resources = {
@@ -1824,11 +3816,77 @@
 	.csiphy_num = ARRAY_SIZE(csiphy_res_8250),
 	.csid_num = ARRAY_SIZE(csid_res_8250),
 	.vfe_num = ARRAY_SIZE(vfe_res_8250),
+	.link_entities = camss_link_entities
+};
+
+static const struct camss_resources sc8280xp_resources = {
+	.version = CAMSS_8280XP,
+	.pd_name = "top",
+	.csiphy_res = csiphy_res_sc8280xp,
+	.csid_res = csid_res_sc8280xp,
+	.ispif_res = NULL,
+	.vfe_res = vfe_res_sc8280xp,
+	.icc_res = icc_res_sc8280xp,
+	.icc_path_num = ARRAY_SIZE(icc_res_sc8280xp),
+	.csiphy_num = ARRAY_SIZE(csiphy_res_sc8280xp),
+	.csid_num = ARRAY_SIZE(csid_res_sc8280xp),
+	.vfe_num = ARRAY_SIZE(vfe_res_sc8280xp),
+	.link_entities = camss_link_entities_v2
+};
+
+static const struct camss_resources sc7280_resources = {
+	.version = CAMSS_7280,
+	.pd_name = "top",
+	.csiphy_res = csiphy_res_7280,
+	.csid_res = csid_res_7280,
+	.vfe_res = vfe_res_7280,
+	.icc_res = icc_res_sc7280,
+	.icc_path_num = ARRAY_SIZE(icc_res_sc7280),
+	.csiphy_num = ARRAY_SIZE(csiphy_res_7280),
+	.csid_num = ARRAY_SIZE(csid_res_7280),
+	.vfe_num = ARRAY_SIZE(vfe_res_7280),
+	.link_entities = camss_link_entities
+};
+
+static const struct camss_resources sa8775p_resources = {
+	.version = CAMSS_8775P,
+	.pd_name = "top",
+	.csiphy_res = csiphy_res_8775p,
+	.tpg_res = tpg_res_8775p,
+	.csid_res = csid_res_8775p,
+	.vfe_res = vfe_res_8775p,
+	.icc_res = icc_res_sa8775p,
+	.icc_path_num = ARRAY_SIZE(icc_res_sa8775p),
+	.csiphy_num = ARRAY_SIZE(csiphy_res_8775p),
+	.tpg_num = ARRAY_SIZE(tpg_res_8775p),
+	.csid_num = ARRAY_SIZE(csid_res_8775p),
+	.vfe_num = ARRAY_SIZE(vfe_res_8775p),
+	.link_entities = camss_link_entities
+};
+
+static const struct camss_resources qcs8300_resources = {
+	.version = CAMSS_8300,
+	.pd_name = "top",
+	.csiphy_res = csiphy_res_8300,
+	.tpg_res = tpg_res_8300,
+	.csid_res = csid_res_8300,
+	.vfe_res = vfe_res_8300,
+	.icc_res = icc_res_qcs8300,
+	.icc_path_num = ARRAY_SIZE(icc_res_qcs8300),
+	.csiphy_num = ARRAY_SIZE(csiphy_res_8300),
+	.tpg_num = ARRAY_SIZE(tpg_res_8300),
+	.csid_num = ARRAY_SIZE(csid_res_8300),
+	.vfe_num = ARRAY_SIZE(vfe_res_8300),
+	.link_entities = camss_link_entities
 };
 
 static const struct of_device_id camss_dt_match[] = {
 	{ .compatible = "qcom,msm8916-camss", .data = &msm8916_resources },
 	{ .compatible = "qcom,msm8996-camss", .data = &msm8996_resources },
+	{ .compatible = "qcom,qcs8300-camss", .data = &qcs8300_resources },
+	{ .compatible = "qcom,sa8775p-camss", .data = &sa8775p_resources },
+	{ .compatible = "qcom,sc7280-camss", .data = &sc7280_resources },
+	{ .compatible = "qcom,sc8280xp-camss", .data = &sc8280xp_resources },
 	{ .compatible = "qcom,sdm660-camss", .data = &sdm660_resources },
 	{ .compatible = "qcom,sdm845-camss", .data = &sdm845_resources },
 	{ .compatible = "qcom,sm8250-camss", .data = &sm8250_resources },
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/camss/camss.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/camss/camss.h
@@ -20,8 +20,10 @@
 
 #include "camss-csid.h"
 #include "camss-csiphy.h"
+#include "camss-tpg.h"
 #include "camss-ispif.h"
 #include "camss-vfe.h"
+#include "camss-format.h"
 
 #define to_camss(ptr_module)	\
 	container_of(ptr_module, struct camss, ptr_module)
@@ -40,6 +42,7 @@
 	(to_camss_index(ptr_module, index)->dev)
 
 #define CAMSS_RES_MAX 17
+#define RPMP_PERF_STATE_NOM 256
 
 struct camss_subdev_resources {
 	char *regulators[CAMSS_RES_MAX];
@@ -48,11 +51,12 @@
 	u32 clock_rate[CAMSS_RES_MAX][CAMSS_RES_MAX];
 	char *reg[CAMSS_RES_MAX];
 	char *interrupt[CAMSS_RES_MAX];
-	char *pd_name;
-	u8 line_num;
-	bool has_pd;
-	bool is_lite;
-	const void *ops;
+	union {
+		struct csiphy_subdev_resources csiphy;
+		struct tpg_subdev_resources tpg;
+		struct csid_subdev_resources csid;
+		struct vfe_subdev_resources vfe;
+	};
 };
 
 struct icc_bw_tbl {
@@ -75,8 +79,12 @@
 	CAMSS_8x16,
 	CAMSS_8x96,
 	CAMSS_660,
+	CAMSS_7280,
 	CAMSS_845,
 	CAMSS_8250,
+	CAMSS_8280XP,
+	CAMSS_8775P,
+	CAMSS_8300,
 };
 
 enum icc_count {
@@ -88,14 +96,17 @@
 	enum camss_version version;
 	const char *pd_name;
 	const struct camss_subdev_resources *csiphy_res;
+	const struct camss_subdev_resources *tpg_res;
 	const struct camss_subdev_resources *csid_res;
 	const struct camss_subdev_resources *ispif_res;
 	const struct camss_subdev_resources *vfe_res;
 	const struct resources_icc *icc_res;
 	const unsigned int icc_path_num;
 	const unsigned int csiphy_num;
+	const unsigned int tpg_num;
 	const unsigned int csid_num;
 	const unsigned int vfe_num;
+	int (*link_entities)(struct camss *camss);
 };
 
 struct camss {
@@ -104,6 +115,7 @@
 	struct media_device media_dev;
 	struct device *dev;
 	struct csiphy_device *csiphy;
+	struct tpg_device *tpg;
 	struct csid_device *csid;
 	struct ispif_device *ispif;
 	struct vfe_device *vfe;
@@ -113,6 +125,7 @@
 	struct device_link *genpd_link;
 	struct icc_path *icc_path[ICC_SM8250_COUNT];
 	const struct camss_resources *res;
+	void __iomem *csid_top_base;
 };
 
 struct camss_camera_interface {
@@ -132,6 +145,12 @@
 	u32 nfreqs;
 };
 
+struct parent_dev_ops {
+	int (*get)(struct camss *camss, int id);
+	int (*put)(struct camss *camss, int id);
+	void __iomem *(*get_base_address)(struct camss *camss, int id);
+};
+
 void camss_add_clock_margin(u64 *rate);
 int camss_enable_clocks(int nclocks, struct camss_clock *clock,
 			struct device *dev);
@@ -142,6 +161,10 @@
 int camss_get_pixel_clock(struct media_entity *entity, u64 *pixel_clock);
 int camss_pm_domain_on(struct camss *camss, int id);
 void camss_pm_domain_off(struct camss *camss, int id);
+int camss_vfe_get(struct camss *camss, int id);
+void camss_vfe_put(struct camss *camss, int id);
 void camss_delete(struct camss *camss);
-
+void camss_buf_done(struct camss *camss, int hw_id, int port_id);
+void camss_reg_update(struct camss *camss, int hw_id,
+			int port_id, bool is_clear);
 #endif /* QC_MSM_CAMSS_H */
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/Kconfig
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/Kconfig
@@ -0,0 +1,15 @@
+config VIDEO_QCOM_IRIS
+        tristate "Qualcomm Iris V4L2 encoder/decoder driver"
+        depends on V4L_MEM2MEM_DRIVERS
+        depends on VIDEO_DEV && QCOM_SMEM
+        depends on (ARCH_QCOM && IOMMU_DMA) || COMPILE_TEST
+        select QCOM_MDT_LOADER if ARCH_QCOM
+        select QCOM_SCM
+        select VIDEOBUF2_DMA_CONTIG
+        select V4L2_MEM2MEM_DEV
+        select DMABUF_HEAPS
+        help
+          This is a V4L2 driver for Qualcomm Iris video accelerator
+          hardware. It accelerates encoding and decoding operations
+          on various Qualcomm SoCs.
+          To compile this driver as a module choose m here.
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/Makefile
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/Makefile
@@ -0,0 +1,30 @@
+iris-objs += iris_probe.o \
+             iris_core.o \
+             iris_vidc.o \
+             iris_vb2.o \
+             iris_vdec.o \
+             iris_venc.o \
+             iris_state.o \
+             iris_ctrls.o \
+             iris_helpers.o \
+             iris_hfi.o \
+             iris_hfi_response.o \
+             iris_hfi_queue.o \
+             iris_hfi_packet.o \
+             iris_buffer.o \
+             iris_power.o \
+             resources.o \
+             firmware.o \
+             memory.o \
+             vpu_common.o \
+             vpu_iris3.o \
+             vpu_iris3_buffer.o \
+             vpu_iris3_power.o \
+             vpu_iris2.o \
+             vpu_iris2_buffer.o \
+             vpu_iris2_power.o \
+             platform_common.o \
+             platform_sm8550.o \
+             platform_qcm6490.o
+
+obj-$(CONFIG_VIDEO_QCOM_IRIS) += iris.o
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/firmware.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/firmware.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/firmware.h>
+#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/of_address.h>
+#include <linux/soc/qcom/mdt_loader.h>
+
+#include "firmware.h"
+#include "iris_core.h"
+
+#define MAX_FIRMWARE_NAME_SIZE	128
+
+struct tzbsp_memprot {
+	u32 cp_start;
+	u32 cp_size;
+	u32 cp_nonpixel_start;
+	u32 cp_nonpixel_size;
+};
+
+static int __protect_cp_mem(struct iris_core *core)
+{
+	struct tzbsp_memprot memprot;
+	int ret;
+
+	memprot.cp_start = core->cap[CP_START].value;
+	memprot.cp_size = core->cap[CP_SIZE].value;
+	memprot.cp_nonpixel_start = core->cap[CP_NONPIXEL_START].value;
+	memprot.cp_nonpixel_size = core->cap[CP_NONPIXEL_SIZE].value;
+
+	ret = qcom_scm_mem_protect_video_var(memprot.cp_start,
+					     memprot.cp_size,
+					     memprot.cp_nonpixel_start,
+					     memprot.cp_nonpixel_size);
+	if (ret)
+		dev_err(core->dev, "Failed to protect memory(%d)\n", ret);
+
+	return ret;
+}
+
+static int __load_fw_to_memory(struct iris_core *core,
+			       const char *fw_name)
+{
+	char firmware_name[MAX_FIRMWARE_NAME_SIZE] = { 0 };
+	const struct firmware *firmware = NULL;
+	struct device_node *node = NULL;
+	struct resource res = { 0 };
+	phys_addr_t mem_phys = 0;
+	void *mem_virt = NULL;
+	size_t res_size = 0;
+	ssize_t fw_size = 0;
+	struct device *dev;
+	int pas_id = 0;
+	int ret;
+
+	if (!fw_name || !(*fw_name) || !core)
+		return -EINVAL;
+
+	dev = core->dev;
+
+	if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4)
+		return -EINVAL;
+
+	scnprintf(firmware_name, ARRAY_SIZE(firmware_name), "%s.mbn", fw_name);
+
+	pas_id = core->platform_data->pas_id;
+
+	node = of_parse_phandle(dev->of_node, "memory-region", 0);
+	if (!node)
+		return -EINVAL;
+
+	ret = of_address_to_resource(node, 0, &res);
+	if (ret)
+		goto err_put_node;
+
+	mem_phys = res.start;
+	res_size = (size_t)resource_size(&res);
+
+	ret = request_firmware(&firmware, firmware_name, dev);
+	if (ret) {
+		dev_err(core->dev, "%s: failed to request fw \"%s\", error %d\n",
+			__func__, firmware_name, ret);
+		goto err_put_node;
+	}
+
+	fw_size = qcom_mdt_get_size(firmware);
+	if (fw_size < 0 || res_size < (size_t)fw_size) {
+		ret = -EINVAL;
+		dev_err(core->dev, "%s: out of bound fw image fw size: %ld, res_size: %lu\n",
+			__func__, fw_size, res_size);
+		goto err_release_fw;
+	}
+
+	mem_virt = memremap(mem_phys, res_size, MEMREMAP_WC);
+	if (!mem_virt) {
+		dev_err(core->dev, "%s: failed to remap fw memory phys %pa[p]\n",
+			__func__, &mem_phys);
+		goto err_release_fw;
+	}
+
+	ret = qcom_mdt_load(dev, firmware, firmware_name,
+			    pas_id, mem_virt, mem_phys, res_size, NULL);
+	if (ret) {
+		dev_err(core->dev, "%s: error %d loading fw \"%s\"\n",
+			__func__, ret, firmware_name);
+		goto err_mem_unmap;
+	}
+	ret = qcom_scm_pas_auth_and_reset(pas_id);
+	if (ret) {
+		dev_err(core->dev, "%s: error %d authenticating fw \"%s\"\n",
+			__func__, ret, firmware_name);
+		goto err_mem_unmap;
+	}
+
+	return ret;
+
+err_mem_unmap:
+	memunmap(mem_virt);
+err_release_fw:
+	release_firmware(firmware);
+err_put_node:
+	of_node_put(node);
+	return ret;
+}
+
+int iris_fw_load(struct iris_core *core)
+{
+	int ret;
+
+	ret = __load_fw_to_memory(core, core->platform_data->fwname);
+	if (ret) {
+		dev_err(core->dev, "%s: firmware download failed\n", __func__);
+		return -ENOMEM;
+	}
+
+	ret = __protect_cp_mem(core);
+	if (ret) {
+		dev_err(core->dev, "%s: protect memory failed\n", __func__);
+		qcom_scm_pas_shutdown(core->platform_data->pas_id);
+		return ret;
+	}
+
+	return ret;
+}
+
+int iris_fw_unload(struct iris_core *core)
+{
+	int ret;
+
+	ret = qcom_scm_pas_shutdown(core->platform_data->pas_id);
+	if (ret)
+		dev_err(core->dev, "%s: Firmware unload failed with ret %d\n", __func__, ret);
+
+	return ret;
+}
+
+int iris_set_hw_state(struct iris_core *core, bool resume)
+{
+	return qcom_scm_set_remote_state(resume, 0);
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/firmware.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/firmware.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _FIRMWARE_H_
+#define _FIRMWARE_H_
+
+#include "iris_core.h"
+
+int iris_fw_load(struct iris_core *core);
+int iris_fw_unload(struct iris_core *core);
+int iris_set_hw_state(struct iris_core *core, bool resume);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/hfi_defines.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/hfi_defines.h
@@ -0,0 +1,388 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _HFI_DEFINES_H_
+#define _HFI_DEFINES_H_
+
+#include <linux/types.h>
+
+#define HFI_VIDEO_ARCH_LX			0x1
+
+#define HFI_CMD_BEGIN				0x01000000
+#define HFI_CMD_INIT				0x01000001
+#define HFI_CMD_POWER_COLLAPSE			0x01000002
+#define HFI_CMD_OPEN				0x01000003
+#define HFI_CMD_CLOSE				0x01000004
+#define HFI_CMD_START				0x01000005
+#define HFI_CMD_STOP				0x01000006
+#define HFI_CMD_DRAIN				0x01000007
+#define HFI_CMD_RESUME				0x01000008
+#define HFI_CMD_BUFFER				0x01000009
+#define HFI_CMD_PAUSE				0x01000011
+
+#define HFI_PROP_IMAGE_VERSION			0x03000001
+
+#define HFI_PROP_UBWC_MAX_CHANNELS		0x03000003
+#define HFI_PROP_UBWC_MAL_LENGTH		0x03000004
+#define HFI_PROP_UBWC_HBB			0x03000005
+#define HFI_PROP_UBWC_BANK_SWZL_LEVEL1		0x03000006
+#define HFI_PROP_UBWC_BANK_SWZL_LEVEL2		0x03000007
+#define HFI_PROP_UBWC_BANK_SWZL_LEVEL3		0x03000008
+#define HFI_PROP_UBWC_BANK_SPREADING		0x03000009
+
+enum hfi_property_mode_type {
+	HFI_MODE_NONE					= 0x00000000,
+	HFI_MODE_PORT_SETTINGS_CHANGE			= 0x00000001,
+	HFI_MODE_PROPERTY				= 0x00000002,
+};
+
+#define HFI_CMD_SUBSCRIBE_MODE			0x0100000B
+#define HFI_CMD_SETTINGS_CHANGE			0x0100000C
+#define HFI_CMD_END				0x01FFFFFF
+
+#define HFI_BITMASK_BITSTREAM_WIDTH		0xffff0000
+#define HFI_BITMASK_BITSTREAM_HEIGHT		0x0000ffff
+
+#define HFI_LEVEL_NONE				0xFFFFFFFF
+
+#define HFI_BITMASK_FRAME_MBS_ONLY_FLAG		0x00000001
+
+#define HFI_TRUE				0x00000001
+
+#define HFI_FALSE				0x00000000
+
+#define HFI_PROP_BEGIN				0x03000000
+
+#define HFI_PROP_IMAGE_VERSION			0x03000001
+
+#define HFI_PROP_INTRA_FRAME_POWER_COLLAPSE	0x03000002
+
+enum hfi_codec_type {
+	HFI_CODEC_DECODE_AVC	= 1,
+	HFI_CODEC_ENCODE_AVC	= 2,
+	HFI_CODEC_DECODE_HEVC	= 3,
+	HFI_CODEC_ENCODE_HEVC	= 4,
+	HFI_CODEC_DECODE_VP9	= 5,
+};
+
+#define HFI_PROP_CODEC				0x03000100
+
+enum hfi_color_format {
+	HFI_COLOR_FMT_OPAQUE		= 0,
+	HFI_COLOR_FMT_NV12		= 1,
+	HFI_COLOR_FMT_NV12_UBWC		= 2,
+	HFI_COLOR_FMT_P010		= 3,
+	HFI_COLOR_FMT_TP10_UBWC		= 4,
+	HFI_COLOR_FMT_RGBA8888		= 5,
+	HFI_COLOR_FMT_RGBA8888_UBWC	= 6,
+};
+
+#define HFI_PROP_COLOR_FORMAT			0x03000101
+
+#define HFI_PROP_BITSTREAM_RESOLUTION		0x03000103
+
+#define HFI_PROP_LINEAR_STRIDE_SCANLINE		0x03000104
+
+#define HFI_PROP_CROP_OFFSETS			0x03000105
+
+#define HFI_PROP_PROFILE			0x03000107
+
+#define HFI_PROP_LEVEL				0x03000108
+
+#define HFI_PROP_TIER				0x03000109
+
+#define HFI_PROP_STAGE				0x0300010a
+
+#define HFI_PROP_PIPE				0x0300010b
+
+#define HFI_PROP_FRAME_RATE			0x0300010c
+
+#define HFI_PROP_LUMA_CHROMA_BIT_DEPTH		0x0300010f
+
+#define HFI_PROP_CODED_FRAMES			0x03000120
+
+#define HFI_PROP_CABAC_SESSION			0x03000121
+
+#define HFI_PROP_8X8_TRANSFORM			0x03000122
+
+#define HFI_PROP_BUFFER_HOST_MAX_COUNT		0x03000123
+
+#define HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT	0x03000124
+
+#define HFI_PROP_PIC_ORDER_CNT_TYPE		0x03000128
+
+enum hfi_syncframe_request_mode {
+	HFI_SYNC_FRAME_REQUEST_WITHOUT_SEQ_HDR		= 0x00000001,
+	HFI_SYNC_FRAME_REQUEST_WITH_PREFIX_SEQ_HDR	= 0x00000002,
+};
+
+enum hfi_rate_control {
+	HFI_RC_VBR_CFR		= 0x00000000,
+	HFI_RC_CBR_CFR		= 0x00000001,
+	HFI_RC_CQ		= 0x00000002,
+	HFI_RC_OFF		= 0x00000003,
+	HFI_RC_CBR_VFR		= 0x00000004,
+	HFI_RC_LOSSLESS		= 0x00000005,
+	HFI_RC_MBR              = 0x00000006,
+};
+
+#define HFI_PROP_RATE_CONTROL			0x0300012a
+
+#define HFI_PROP_TIME_DELTA_BASED_RATE_CONTROL                  0x0300012b
+
+#define HFI_PROP_QP_PACKED			0x0300012e
+
+#define HFI_PROP_MIN_QP_PACKED			0x0300012f
+
+#define HFI_PROP_MAX_QP_PACKED			0x03000130
+
+enum hfi_layer_enc_type {
+	HFI_HIER_P_SLIDING_WINDOW	= 0x1,
+	HFI_HIER_P_HYBRID_LTR		= 0x2,
+	HFI_HIER_B			= 0x3,
+};
+
+#define HFI_PROP_IR_RANDOM_PERIOD		0x03000131
+
+#define HFI_PROP_MULTI_SLICE_MB_COUNT		0x03000132
+
+#define HFI_PROP_MULTI_SLICE_BYTES_COUNT	0x03000133
+
+#define HFI_PROP_LTR_COUNT			0x03000134
+
+#define HFI_PROP_LTR_MARK			0x03000135
+
+#define HFI_PROP_LTR_USE			0x03000136
+
+#define HFI_PROP_LAYER_ENCODING_TYPE		0x03000138
+
+#define HFI_PROP_LAYER_COUNT			0x03000139
+
+#define HFI_PROP_TOTAL_BITRATE			0x0300013b
+
+#define HFI_PROP_BITRATE_LAYER1			0x0300013c
+
+#define HFI_PROP_BITRATE_LAYER2			0x0300013d
+
+#define HFI_PROP_BITRATE_LAYER3			0x0300013e
+
+#define HFI_PROP_BITRATE_LAYER4			0x0300013f
+
+#define HFI_PROP_BITRATE_LAYER5			0x03000140
+
+#define HFI_PROP_BITRATE_LAYER6			0x03000141
+
+#define HFI_PROP_BASELAYER_PRIORITYID		0x03000142
+
+#define HFI_PROP_REQUEST_SYNC_FRAME		0x03000145
+
+#define HFI_PROP_MAX_GOP_FRAMES			0x03000146
+
+#define HFI_PROP_MAX_B_FRAMES			0x03000147
+
+#define HFI_PROP_QUALITY_MODE			0x03000148
+
+enum hfi_seq_header_mode {
+	HFI_SEQ_HEADER_SEPERATE_FRAME		= 0x00000001,
+	HFI_SEQ_HEADER_JOINED_WITH_1ST_FRAME	= 0x00000002,
+	HFI_SEQ_HEADER_PREFIX_WITH_SYNC_FRAME	= 0x00000004,
+	HFI_SEQ_HEADER_METADATA			= 0x00000008,
+};
+
+#define HFI_PROP_SEQ_HEADER_MODE		0x03000149
+
+enum hfi_rotation {
+	HFI_ROTATION_NONE	= 0x00000000,
+	HFI_ROTATION_90		= 0x00000001,
+	HFI_ROTATION_180	= 0x00000002,
+	HFI_ROTATION_270	= 0x00000003,
+};
+
+#define HFI_PROP_ROTATION			0x0300014b
+
+enum hfi_flip {
+	HFI_DISABLE_FLIP	= 0x00000000,
+	HFI_HORIZONTAL_FLIP	= 0x00000001,
+	HFI_VERTICAL_FLIP	= 0x00000002,
+};
+
+#define HFI_PROP_FLIP				0x0300014c
+
+enum hfi_color_primaries {
+	HFI_PRIMARIES_RESERVED		= 0,
+	HFI_PRIMARIES_BT709		= 1,
+	HFI_PRIMARIES_UNSPECIFIED	= 2,
+	HFI_PRIMARIES_BT470_SYSTEM_M	= 4,
+	HFI_PRIMARIES_BT470_SYSTEM_BG	= 5,
+	HFI_PRIMARIES_BT601_525		= 6,
+	HFI_PRIMARIES_SMPTE_ST240M	= 7,
+	HFI_PRIMARIES_GENERIC_FILM	= 8,
+	HFI_PRIMARIES_BT2020		= 9,
+	HFI_PRIMARIES_SMPTE_ST428_1	= 10,
+	HFI_PRIMARIES_SMPTE_RP431_2	= 11,
+	HFI_PRIMARIES_SMPTE_EG431_1	= 12,
+	HFI_PRIMARIES_SMPTE_EBU_TECH	= 22,
+};
+
+enum hfi_transfer_characteristics {
+	HFI_TRANSFER_RESERVED		= 0,
+	HFI_TRANSFER_BT709		= 1,
+	HFI_TRANSFER_UNSPECIFIED	= 2,
+	HFI_TRANSFER_BT470_SYSTEM_M	= 4,
+	HFI_TRANSFER_BT470_SYSTEM_BG	= 5,
+	HFI_TRANSFER_BT601_525_OR_625	= 6,
+	HFI_TRANSFER_SMPTE_ST240M	= 7,
+	HFI_TRANSFER_LINEAR		= 8,
+	HFI_TRANSFER_LOG_100_1		= 9,
+	HFI_TRANSFER_LOG_SQRT		= 10,
+	HFI_TRANSFER_XVYCC		= 11,
+	HFI_TRANSFER_BT1361_0		= 12,
+	HFI_TRANSFER_SRGB_SYCC		= 13,
+	HFI_TRANSFER_BT2020_14		= 14,
+	HFI_TRANSFER_BT2020_15		= 15,
+	HFI_TRANSFER_SMPTE_ST2084_PQ	= 16,
+	HFI_TRANSFER_SMPTE_ST428_1	= 17,
+	HFI_TRANSFER_BT2100_2_HLG	= 18,
+};
+
+enum hfi_matrix_coefficients {
+	HFI_MATRIX_COEFF_SRGB_SMPTE_ST428_1		= 0,
+	HFI_MATRIX_COEFF_BT709				= 1,
+	HFI_MATRIX_COEFF_UNSPECIFIED			= 2,
+	HFI_MATRIX_COEFF_RESERVED			= 3,
+	HFI_MATRIX_COEFF_FCC_TITLE_47			= 4,
+	HFI_MATRIX_COEFF_BT470_SYS_BG_OR_BT601_625	= 5,
+	HFI_MATRIX_COEFF_BT601_525_BT1358_525_OR_625	= 6,
+	HFI_MATRIX_COEFF_SMPTE_ST240			= 7,
+	HFI_MATRIX_COEFF_YCGCO				= 8,
+	HFI_MATRIX_COEFF_BT2020_NON_CONSTANT		= 9,
+	HFI_MATRIX_COEFF_BT2020_CONSTANT		= 10,
+	HFI_MATRIX_COEFF_SMPTE_ST2085			= 11,
+	HFI_MATRIX_COEFF_SMPTE_CHROM_DERV_NON_CONSTANT	= 12,
+	HFI_MATRIX_COEFF_SMPTE_CHROM_DERV_CONSTANT	= 13,
+	HFI_MATRIX_COEFF_BT2100				= 14,
+};
+
+#define HFI_PROP_SIGNAL_COLOR_INFO		0x03000155
+
+#define HFI_PROP_DECODE_ORDER_OUTPUT		0x0300015b
+
+enum hfi_picture_type {
+	HFI_PICTURE_IDR	= 0x00000001,
+	HFI_PICTURE_P	= 0x00000002,
+	HFI_PICTURE_B	= 0x00000004,
+	HFI_PICTURE_I	= 0x00000008,
+	HFI_PICTURE_CRA	= 0x00000010,
+	HFI_PICTURE_BLA	= 0x00000020,
+};
+
+#define HFI_PROP_PICTURE_TYPE			0x03000162
+
+#define HFI_PROP_DEC_DEFAULT_HEADER		0x03000168
+
+#define HFI_PROP_DEC_START_FROM_RAP_FRAME	0x03000169
+
+#define HFI_PROP_NO_OUTPUT			0x0300016a
+
+#define HFI_PROP_BUFFER_MARK			0x0300016c
+
+#define HFI_PROP_RAW_RESOLUTION			0x03000178
+
+#define HFI_PROP_DPB_LIST			0x0300017A
+
+#define HFI_PROP_TOTAL_PEAK_BITRATE		0x0300017C
+
+#define HFI_PROP_MAINTAIN_MIN_QUALITY		0x0300017D
+
+#define HFI_PROP_IR_CYCLIC_PERIOD		0x0300017E
+
+#define HFI_PROP_UBWC_STRIDE_SCANLINE		0x03000190
+
+#define HFI_PROP_COMV_BUFFER_COUNT		0x03000193
+
+#define HFI_PROP_END				0x03FFFFFF
+
+#define HFI_SESSION_ERROR_BEGIN			0x04000000
+
+#define HFI_ERROR_UNKNOWN_SESSION		0x04000001
+
+#define HFI_ERROR_MAX_SESSIONS			0x04000002
+
+#define HFI_ERROR_FATAL				0x04000003
+
+#define HFI_ERROR_INVALID_STATE			0x04000004
+
+#define HFI_ERROR_INSUFFICIENT_RESOURCES	0x04000005
+
+#define HFI_ERROR_BUFFER_NOT_SET		0x04000006
+
+#define HFI_SESSION_ERROR_END			0x04FFFFFF
+
+#define HFI_SYSTEM_ERROR_BEGIN			0x05000000
+
+#define HFI_SYS_ERROR_WD_TIMEOUT		0x05000001
+
+#define HFI_SYSTEM_ERROR_END			0x05FFFFFF
+
+#define HFI_INFORMATION_BEGIN			0x06000000
+
+#define HFI_INFO_UNSUPPORTED			0x06000001
+
+#define HFI_INFO_DATA_CORRUPT			0x06000002
+
+#define HFI_INFO_BUFFER_OVERFLOW		0x06000004
+
+#define HFI_INFO_HFI_FLAG_DRAIN_LAST		0x06000006
+
+#define HFI_INFO_HFI_FLAG_PSC_LAST		0x06000007
+
+#define HFI_INFORMATION_END			0x06FFFFFF
+
+struct hfi_debug_header {
+	u32 size;
+	u32 debug_level;
+	u32 reserved[2];
+};
+
+enum hfi_buffer_type {
+	HFI_BUFFER_BITSTREAM		= 0x00000001,
+	HFI_BUFFER_RAW			= 0x00000002,
+	HFI_BUFFER_METADATA		= 0x00000003,
+	HFI_BUFFER_SUBCACHE		= 0x00000004,
+	HFI_BUFFER_PARTIAL_DATA		= 0x00000005,
+	HFI_BUFFER_DPB			= 0x00000006,
+	HFI_BUFFER_BIN			= 0x00000007,
+	HFI_BUFFER_LINE			= 0x00000008,
+	HFI_BUFFER_ARP			= 0x00000009,
+	HFI_BUFFER_COMV			= 0x0000000A,
+	HFI_BUFFER_NON_COMV		= 0x0000000B,
+	HFI_BUFFER_PERSIST		= 0x0000000C,
+	HFI_BUFFER_VPSS			= 0x0000000D,
+};
+
+enum hfi_buffer_host_flags {
+	HFI_BUF_HOST_FLAG_NONE			= 0x00000000,
+	HFI_BUF_HOST_FLAG_RELEASE		= 0x00000001,
+	HFI_BUF_HOST_FLAG_READONLY		= 0x00000010,
+	HFI_BUF_HOST_FLAG_CODEC_CONFIG		= 0x00000100,
+	HFI_BUF_HOST_FLAGS_CB_NON_SECURE	= 0x00000200,
+};
+
+enum hfi_buffer_firmware_flags {
+	HFI_BUF_FW_FLAG_NONE		= 0x00000000,
+	HFI_BUF_FW_FLAG_RELEASE_DONE	= 0x00000001,
+	HFI_BUF_FW_FLAG_READONLY	= 0x00000010,
+	HFI_BUF_FW_FLAG_LAST		= 0x10000000,
+	HFI_BUF_FW_FLAG_PSC_LAST	= 0x20000000,
+};
+
+enum hfi_hevc_profile_type {
+	HFI_H265_PROFILE_MAIN			= 0,
+	HFI_H265_PROFILE_MAIN_STILL_PICTURE	= 1,
+	HFI_H265_PROFILE_MAIN_10		= 2,
+	HFI_H265_PROFILE_MAIN_10_STILL_PICTURE	= 3,
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_buffer.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_buffer.c
@@ -0,0 +1,863 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "iris_buffer.h"
+#include "iris_helpers.h"
+#include "iris_hfi.h"
+#include "hfi_defines.h"
+#include "iris_hfi_packet.h"
+#include "iris_instance.h"
+#include "memory.h"
+#include "vpu_iris3_buffer.h"
+
+static const u32 dec_ip_int_buf_type[] = {
+	BUF_BIN,
+	BUF_COMV,
+	BUF_NON_COMV,
+	BUF_LINE,
+};
+
+static const u32 dec_op_int_buf_type[] = {
+	BUF_DPB,
+};
+
+static const u32 enc_ip_int_buf_type[] = {
+	BUF_VPSS,
+};
+
+static const u32 enc_op_int_buf_type[] = {
+	BUF_BIN,
+	BUF_COMV,
+	BUF_NON_COMV,
+	BUF_LINE,
+	BUF_DPB,
+};
+
+static u32 video_buffer_size(u32 colorformat,
+			     u32 pix_width,
+			     u32 pix_height)
+{
+	u32 size = 0;
+	u32 y_plane, uv_plane, y_stride,
+		uv_stride, y_sclines, uv_sclines;
+	u32 y_ubwc_plane = 0, uv_ubwc_plane = 0;
+	u32 y_meta_stride = 0, y_meta_scanlines = 0;
+	u32 uv_meta_stride = 0, uv_meta_scanlines = 0;
+	u32 y_meta_plane = 0, uv_meta_plane = 0;
+
+	if (!pix_width || !pix_height)
+		goto invalid_input;
+
+	switch (colorformat) {
+	case V4L2_PIX_FMT_NV12:
+		y_stride = ALIGN(pix_width, 128);
+		uv_stride = ALIGN(pix_width, 128);
+		y_sclines = ALIGN(pix_height, 32);
+		uv_sclines = ALIGN((pix_height + 1) >> 1, 16);
+		y_plane = y_stride * y_sclines;
+		uv_plane = uv_stride * uv_sclines;
+		size = y_plane + uv_plane;
+		break;
+	case V4L2_PIX_FMT_QC08C:
+		y_stride = ALIGN(pix_width, 128);
+		uv_stride = ALIGN(pix_width, 128);
+		y_sclines = ALIGN(pix_height, 32);
+		uv_sclines = ALIGN((pix_height + 1) >> 1, 32);
+		y_meta_stride = ALIGN(DIV_ROUND_UP(pix_width, 32), 64);
+		uv_meta_stride = ALIGN(DIV_ROUND_UP((pix_width + 1) >> 1, 16), 64);
+		y_ubwc_plane =
+			ALIGN(y_stride * y_sclines, 4096);
+		uv_ubwc_plane =
+			ALIGN(uv_stride * uv_sclines, 4096);
+		y_meta_scanlines =
+			ALIGN(DIV_ROUND_UP(pix_height, 8), 16);
+		y_meta_plane =
+			ALIGN(y_meta_stride * y_meta_scanlines, 4096);
+		uv_meta_scanlines =
+			ALIGN(DIV_ROUND_UP((pix_height + 1) >> 1, 8), 16);
+		uv_meta_plane =
+			ALIGN(uv_meta_stride * uv_meta_scanlines, 4096);
+		size = (y_ubwc_plane + uv_ubwc_plane + y_meta_plane +
+			uv_meta_plane);
+		break;
+	case V4L2_PIX_FMT_QC10C:
+		y_stride =
+			ALIGN(ALIGN(pix_width, 192) * 4 / 3, 256);
+		uv_stride =
+			ALIGN(ALIGN(pix_width, 192) * 4 / 3, 256);
+		y_sclines =
+			ALIGN(pix_height, 16);
+		uv_sclines =
+			ALIGN((pix_height + 1) >> 1, 16);
+		y_ubwc_plane =
+			ALIGN(y_stride * y_sclines, 4096);
+		uv_ubwc_plane =
+			ALIGN(uv_stride * uv_sclines, 4096);
+		y_meta_stride =
+			ALIGN(DIV_ROUND_UP(pix_width, 48), 64);
+		y_meta_scanlines =
+			ALIGN(DIV_ROUND_UP(pix_height, 4), 16);
+		y_meta_plane =
+			ALIGN(y_meta_stride * y_meta_scanlines, 4096);
+		uv_meta_stride =
+			ALIGN(DIV_ROUND_UP((pix_width + 1) >> 1, 24), 64);
+		uv_meta_scanlines =
+			ALIGN(DIV_ROUND_UP((pix_height + 1) >> 1, 4), 16);
+		uv_meta_plane =
+			ALIGN(uv_meta_stride * uv_meta_scanlines, 4096);
+
+		size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane +
+			uv_meta_plane;
+		break;
+	default:
+		break;
+	}
+
+invalid_input:
+
+	return ALIGN(size, 4096);
+}
+
+static int input_min_count(struct iris_inst *inst)
+{
+	u32 input_min_count = 0;
+	u32 total_hb_layer = 0;
+
+	if (inst->domain == DECODER) {
+		input_min_count = MIN_BUFFERS;
+	} else if (inst->domain == ENCODER) {
+		total_hb_layer = is_hierb_type_requested(inst) ?
+			inst->cap[ENH_LAYER_COUNT].value + 1 : 0;
+		if (inst->codec == H264 &&
+		    !inst->cap[LAYER_ENABLE].value) {
+			total_hb_layer = 0;
+		}
+		input_min_count =
+			hfi_iris3_enc_min_input_buf_count(total_hb_layer);
+	} else {
+		return 0;
+	}
+
+	return input_min_count;
+}
+
+static int output_min_count(struct iris_inst *inst)
+{
+	int output_min_count;
+
+	if (inst->domain != DECODER && inst->domain != ENCODER)
+		return 0;
+
+	if (inst->domain == ENCODER)
+		return MIN_BUFFERS;
+
+	/* fw_min_count > 0 indicates reconfig event has already arrived */
+	if (inst->fw_min_count) {
+		if (is_split_mode_enabled(inst) && inst->codec == VP9)
+			return min_t(u32, 4, inst->fw_min_count);
+		else
+			return inst->fw_min_count;
+	}
+
+	switch (inst->codec) {
+	case H264:
+	case HEVC:
+		output_min_count = 4;
+		break;
+	case VP9:
+		output_min_count = 9;
+		break;
+	default:
+		output_min_count = 4;
+		break;
+	}
+
+	return output_min_count;
+}
+
+int update_buffer_count(struct iris_inst *inst, u32 plane)
+{
+	switch (plane) {
+	case INPUT_MPLANE:
+		inst->buffers.input.min_count = input_min_count(inst);
+		if (inst->buffers.input.actual_count < inst->buffers.input.min_count)
+			inst->buffers.input.actual_count = inst->buffers.input.min_count;
+
+		break;
+	case OUTPUT_MPLANE:
+		if (!inst->vb2q_src->streaming)
+			inst->buffers.output.min_count = output_min_count(inst);
+		if (inst->buffers.output.actual_count < inst->buffers.output.min_count)
+			inst->buffers.output.actual_count = inst->buffers.output.min_count;
+
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static u32 internal_buffer_count(struct iris_inst *inst,
+				 enum iris_buffer_type buffer_type)
+{
+	u32 count = 0;
+
+	if (inst->domain == ENCODER)
+		return 1;
+
+	if (inst->domain == DECODER) {
+		if (buffer_type == BUF_BIN || buffer_type == BUF_LINE ||
+		    buffer_type == BUF_PERSIST) {
+			count = 1;
+		} else if (buffer_type == BUF_COMV || buffer_type == BUF_NON_COMV) {
+			if (inst->codec == H264 || inst->codec == HEVC)
+				count = 1;
+			else
+				count = 0;
+		} else {
+			count = 0;
+		}
+	}
+
+	return count;
+}
+
+static int dpb_count(struct iris_inst *inst)
+{
+	int count = 0;
+
+	if (inst->domain == ENCODER)
+		return get_recon_buf_count(inst);
+
+	if (is_split_mode_enabled(inst)) {
+		count = inst->fw_min_count ?
+			inst->fw_min_count : inst->buffers.output.min_count;
+	}
+
+	return count;
+}
+
+int iris_get_buf_min_count(struct iris_inst *inst,
+			   enum iris_buffer_type buffer_type)
+{
+	switch (buffer_type) {
+	case BUF_INPUT:
+		return input_min_count(inst);
+	case BUF_OUTPUT:
+		return output_min_count(inst);
+	case BUF_BIN:
+	case BUF_COMV:
+	case BUF_NON_COMV:
+	case BUF_LINE:
+	case BUF_PERSIST:
+	case BUF_ARP:
+		return internal_buffer_count(inst, buffer_type);
+	case BUF_DPB:
+		return dpb_count(inst);
+	default:
+		return 0;
+	}
+}
+
+static u32 dec_input_buffer_size(struct iris_inst *inst)
+{
+	u32 base_res_mbs = NUM_MBS_4k;
+	u32 frame_size, num_mbs;
+	struct v4l2_format *f;
+	u32 div_factor = 1;
+	u32 codec;
+
+	f = inst->fmt_src;
+	codec = f->fmt.pix_mp.pixelformat;
+
+	num_mbs = get_mbpf(inst);
+	if (num_mbs > NUM_MBS_4k) {
+		div_factor = 4;
+		base_res_mbs = inst->cap[MBPF].value;
+	} else {
+		base_res_mbs = NUM_MBS_4k;
+		if (codec == V4L2_PIX_FMT_VP9)
+			div_factor = 1;
+		else
+			div_factor = 2;
+	}
+
+	frame_size = base_res_mbs * MB_IN_PIXEL * 3 / 2 / div_factor;
+
+	 /* multiply by 10/8 (1.25) to get size for 10 bit case */
+	if (codec == V4L2_PIX_FMT_VP9 || codec == V4L2_PIX_FMT_HEVC)
+		frame_size = frame_size + (frame_size >> 2);
+
+	return ALIGN(frame_size, SZ_4K);
+}
+
+static u32 dec_output_buffer_size(struct iris_inst *inst)
+{
+	struct v4l2_format *f;
+	u32 size;
+
+	f = inst->fmt_dst;
+
+	size = video_buffer_size(f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width,
+				 f->fmt.pix_mp.height);
+	return size;
+}
+
+static u32 enc_input_buffer_size(struct iris_inst *inst)
+{
+	struct v4l2_format *f;
+	u32 size;
+
+	f = inst->fmt_src;
+
+	size = video_buffer_size(f->fmt.pix_mp.pixelformat, f->fmt.pix_mp.width,
+				 f->fmt.pix_mp.height);
+	return size;
+}
+
+int iris_get_buffer_size(struct iris_inst *inst,
+			 enum iris_buffer_type buffer_type)
+{
+	if (inst->domain == DECODER) {
+		switch (buffer_type) {
+		case BUF_INPUT:
+			return dec_input_buffer_size(inst);
+		case BUF_OUTPUT:
+			return dec_output_buffer_size(inst);
+		default:
+			break;
+		}
+	} else if (inst->domain == ENCODER) {
+		switch (buffer_type) {
+		case BUF_INPUT:
+			return enc_input_buffer_size(inst);
+		case BUF_OUTPUT:
+			return enc_output_buffer_size_iris3(inst);
+		default:
+			break;
+		}
+	}
+
+	return 0;
+}
+
+struct iris_buffers *iris_get_buffer_list(struct iris_inst *inst,
+					  enum iris_buffer_type buffer_type)
+{
+	switch (buffer_type) {
+	case BUF_INPUT:
+		return &inst->buffers.input;
+	case BUF_OUTPUT:
+		return &inst->buffers.output;
+	case BUF_READ_ONLY:
+		return &inst->buffers.read_only;
+	case BUF_BIN:
+		return &inst->buffers.bin;
+	case BUF_ARP:
+		return &inst->buffers.arp;
+	case BUF_COMV:
+		return &inst->buffers.comv;
+	case BUF_NON_COMV:
+		return &inst->buffers.non_comv;
+	case BUF_LINE:
+		return &inst->buffers.line;
+	case BUF_DPB:
+		return &inst->buffers.dpb;
+	case BUF_PERSIST:
+		return &inst->buffers.persist;
+	case BUF_VPSS:
+		return &inst->buffers.vpss;
+	default:
+		return NULL;
+	}
+}
+
+int iris_allocate_buffers(struct iris_inst *inst,
+			  enum iris_buffer_type buf_type,
+			  u32 num_buffers)
+{
+	struct iris_buffer *buf = NULL;
+	struct iris_buffers *buffers;
+	int idx = 0;
+
+	buffers = iris_get_buffer_list(inst, buf_type);
+	if (!buffers)
+		return -EINVAL;
+
+	for (idx = 0; idx < num_buffers; idx++) {
+		buf = iris_get_buffer_from_pool(inst);
+		if (!buf)
+			return -EINVAL;
+
+		INIT_LIST_HEAD(&buf->list);
+		list_add_tail(&buf->list, &buffers->list);
+		buf->type = buf_type;
+		buf->index = idx;
+	}
+
+	return 0;
+}
+
+int iris_free_buffers(struct iris_inst *inst,
+		      enum iris_buffer_type buf_type)
+{
+	struct iris_buffer *buf, *dummy;
+	struct iris_buffers *buffers;
+
+	buffers = iris_get_buffer_list(inst, buf_type);
+	if (!buffers)
+		return -EINVAL;
+
+	list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
+		list_del_init(&buf->list);
+		iris_return_buffer_to_pool(inst, buf);
+	}
+
+	return 0;
+}
+
+static int iris_get_internal_buf_info(struct iris_inst *inst,
+				      enum iris_buffer_type buffer_type)
+{
+	struct iris_buffers *buffers;
+	struct iris_core *core;
+	u32 buf_count;
+	u32 buf_size;
+
+	core = inst->core;
+
+	buf_size = call_session_op(core, int_buf_size,
+				   inst, buffer_type);
+
+	buf_count = iris_get_buf_min_count(inst, buffer_type);
+
+	buffers = iris_get_buffer_list(inst, buffer_type);
+	if (!buffers)
+		return -EINVAL;
+
+	if (buf_size && buf_size <= buffers->size &&
+	    buf_count && buf_count <= buffers->min_count) {
+		buffers->reuse = true;
+	} else {
+		buffers->reuse = false;
+		buffers->size = buf_size;
+		buffers->min_count = buf_count;
+	}
+
+	return 0;
+}
+
+int iris_get_internal_buffers(struct iris_inst *inst,
+			      u32 plane)
+{
+	int ret = 0;
+	u32 i = 0;
+
+	if (inst->domain == DECODER) {
+		if (plane == INPUT_MPLANE) {
+			for (i = 0; i < ARRAY_SIZE(dec_ip_int_buf_type); i++) {
+				ret = iris_get_internal_buf_info(inst, dec_ip_int_buf_type[i]);
+				if (ret)
+					return ret;
+			}
+		} else {
+			return iris_get_internal_buf_info(inst, BUF_DPB);
+		}
+	} else if (inst->domain == ENCODER) {
+		if (plane == INPUT_MPLANE) {
+			for (i = 0; i < ARRAY_SIZE(enc_ip_int_buf_type); i++) {
+				ret = iris_get_internal_buf_info(inst, enc_ip_int_buf_type[i]);
+				if (ret)
+					return ret;
+			}
+		} else {
+			for (i = 0; i < ARRAY_SIZE(enc_op_int_buf_type); i++) {
+				ret = iris_get_internal_buf_info(inst, enc_op_int_buf_type[i]);
+				if (ret)
+					return ret;
+			}
+		}
+	}
+
+	return ret;
+}
+
+static int iris_create_internal_buffer(struct iris_inst *inst,
+				       enum iris_buffer_type buffer_type, u32 index)
+{
+	struct iris_buffers *buffers;
+	struct iris_buffer *buffer;
+	struct iris_core *core;
+
+	core = inst->core;
+
+	buffers = iris_get_buffer_list(inst, buffer_type);
+	if (!buffers)
+		return -EINVAL;
+
+	if (!buffers->size)
+		return 0;
+
+	buffer = iris_get_buffer_from_pool(inst);
+	if (!buffer)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&buffer->list);
+	buffer->type = buffer_type;
+	buffer->index = index;
+	buffer->buffer_size = buffers->size;
+	buffer->dma_attrs = DMA_ATTR_WRITE_COMBINE | DMA_ATTR_NO_KERNEL_MAPPING;
+	list_add_tail(&buffer->list, &buffers->list);
+
+	buffer->kvaddr = dma_alloc_attrs(core->dev, buffer->buffer_size,
+					 &buffer->device_addr, GFP_KERNEL, buffer->dma_attrs);
+
+	if (!buffer->kvaddr)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int iris_create_internal_buffers(struct iris_inst *inst,
+					enum iris_buffer_type buffer_type)
+{
+	struct iris_buffers *buffers;
+	int ret = 0;
+	int i;
+
+	buffers = iris_get_buffer_list(inst, buffer_type);
+	if (!buffers)
+		return -EINVAL;
+
+	if (buffers->reuse)
+		return 0;
+
+	for (i = 0; i < buffers->min_count; i++) {
+		ret = iris_create_internal_buffer(inst, buffer_type, i);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+int iris_create_input_internal_buffers(struct iris_inst *inst)
+{
+	int ret = 0;
+	u32 i = 0;
+
+	if (inst->domain == DECODER) {
+		for (i = 0; i < ARRAY_SIZE(dec_ip_int_buf_type); i++) {
+			ret = iris_create_internal_buffers(inst, dec_ip_int_buf_type[i]);
+			if (ret)
+				return ret;
+		}
+	} else if (inst->domain == ENCODER) {
+		for (i = 0; i < ARRAY_SIZE(enc_ip_int_buf_type); i++) {
+			ret = iris_create_internal_buffers(inst, enc_ip_int_buf_type[i]);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+int iris_create_output_internal_buffers(struct iris_inst *inst)
+{
+	int ret = 0;
+	u32 i = 0;
+
+	if (inst->domain == DECODER) {
+		return iris_create_internal_buffers(inst, BUF_DPB);
+	} else if (inst->domain == ENCODER) {
+		for (i = 0; i < ARRAY_SIZE(enc_op_int_buf_type); i++) {
+			ret = iris_create_internal_buffers(inst, enc_op_int_buf_type[i]);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+static int set_num_comv(struct iris_inst *inst)
+{
+	u32 num_comv;
+
+	num_comv = inst->cap[NUM_COMV].value;
+
+	return iris_hfi_set_property(inst,
+					HFI_PROP_COMV_BUFFER_COUNT,
+					HFI_HOST_FLAGS_NONE,
+					HFI_PORT_BITSTREAM,
+					HFI_PAYLOAD_U32,
+					&num_comv,
+					sizeof(u32));
+}
+
+static int iris_queue_internal_buffers(struct iris_inst *inst,
+				       enum iris_buffer_type buffer_type)
+{
+	struct iris_buffer *buffer, *dummy;
+	struct iris_buffers *buffers;
+	int ret = 0;
+
+	if (inst->domain == DECODER && buffer_type == BUF_COMV) {
+		ret = set_num_comv(inst);
+		if (ret)
+			return ret;
+	}
+
+	buffers = iris_get_buffer_list(inst, buffer_type);
+	if (!buffers)
+		return -EINVAL;
+
+	list_for_each_entry_safe(buffer, dummy, &buffers->list, list) {
+		if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
+			continue;
+		if (buffer->attr & BUF_ATTR_QUEUED)
+			continue;
+		ret = iris_hfi_queue_buffer(inst, buffer);
+		if (ret)
+			return ret;
+		buffer->attr |= BUF_ATTR_QUEUED;
+	}
+
+	return ret;
+}
+
+int iris_queue_input_internal_buffers(struct iris_inst *inst)
+{
+	int ret = 0;
+	u32 i;
+
+	if (inst->domain == DECODER) {
+		for (i = 0; i < ARRAY_SIZE(dec_ip_int_buf_type); i++) {
+			ret = iris_queue_internal_buffers(inst, dec_ip_int_buf_type[i]);
+			if (ret)
+				return ret;
+		}
+	} else if (inst->domain == ENCODER) {
+		for (i = 0; i < ARRAY_SIZE(enc_ip_int_buf_type); i++) {
+			ret = iris_queue_internal_buffers(inst, enc_ip_int_buf_type[i]);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+int iris_queue_output_internal_buffers(struct iris_inst *inst)
+{
+	int ret = 0;
+	u32 i = 0;
+
+	if (inst->domain == DECODER) {
+		return iris_queue_internal_buffers(inst, BUF_DPB);
+	} else if (inst->domain == ENCODER) {
+		for (i = 0; i < ARRAY_SIZE(enc_op_int_buf_type); i++) {
+			ret = iris_queue_internal_buffers(inst, enc_op_int_buf_type[i]);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+int iris_destroy_internal_buffer(struct iris_inst *inst,
+				 struct iris_buffer *buffer)
+{
+	struct iris_buffer *buf, *dummy;
+	struct iris_buffers *buffers;
+	struct iris_core *core;
+
+	core = inst->core;
+
+	buffers = iris_get_buffer_list(inst, buffer->type);
+	if (!buffers)
+		return -EINVAL;
+
+	list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
+		if (buf->device_addr == buffer->device_addr) {
+			list_del(&buf->list);
+			dma_free_attrs(core->dev, buf->buffer_size, buf->kvaddr,
+				       buf->device_addr, buf->dma_attrs);
+			buf->kvaddr = NULL;
+			buf->device_addr = 0;
+			iris_return_buffer_to_pool(inst, buf);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+int iris_destroy_internal_buffers(struct iris_inst *inst,
+				  u32 plane)
+{
+	struct iris_buffer *buf, *dummy;
+	struct iris_buffers *buffers;
+	const u32 *internal_buf_type = NULL;
+	int ret = 0;
+	u32 i, len = 0;
+
+	if (inst->domain == DECODER) {
+		if (plane == INPUT_MPLANE) {
+			internal_buf_type = dec_ip_int_buf_type;
+			len = ARRAY_SIZE(dec_ip_int_buf_type);
+		} else {
+			internal_buf_type = dec_op_int_buf_type;
+			len = ARRAY_SIZE(dec_op_int_buf_type);
+		}
+	} else if (inst->domain == ENCODER) {
+		if (plane == INPUT_MPLANE) {
+			internal_buf_type = enc_ip_int_buf_type;
+			len = ARRAY_SIZE(enc_ip_int_buf_type);
+		} else {
+			internal_buf_type = enc_op_int_buf_type;
+			len = ARRAY_SIZE(enc_op_int_buf_type);
+		}
+	}
+
+	for (i = 0; i < len; i++) {
+		buffers = iris_get_buffer_list(inst, internal_buf_type[i]);
+		if (!buffers)
+			return -EINVAL;
+
+		if (buffers->reuse)
+			continue;
+
+		list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
+			ret = iris_destroy_internal_buffer(inst, buf);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+static int iris_release_internal_buffers(struct iris_inst *inst,
+					 enum iris_buffer_type buffer_type)
+{
+	struct iris_buffer *buffer, *dummy;
+	struct iris_buffers *buffers;
+	int ret = 0;
+
+	buffers = iris_get_buffer_list(inst, buffer_type);
+	if (!buffers)
+		return -EINVAL;
+
+	if (buffers->reuse)
+		return 0;
+
+	list_for_each_entry_safe(buffer, dummy, &buffers->list, list) {
+		if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
+			continue;
+		if (!(buffer->attr & BUF_ATTR_QUEUED))
+			continue;
+		ret = iris_hfi_release_buffer(inst, buffer);
+		if (ret)
+			return ret;
+		buffer->attr |= BUF_ATTR_PENDING_RELEASE;
+	}
+
+	return ret;
+}
+
+static int iris_release_input_internal_buffers(struct iris_inst *inst)
+{
+	int ret = 0;
+	u32 i = 0;
+
+	if (inst->domain == DECODER) {
+		for (i = 0; i < ARRAY_SIZE(dec_ip_int_buf_type); i++) {
+			ret = iris_release_internal_buffers(inst, dec_ip_int_buf_type[i]);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+int iris_alloc_and_queue_session_int_bufs(struct iris_inst *inst,
+					  enum iris_buffer_type buffer_type)
+{
+	int ret;
+
+	if (buffer_type != BUF_ARP && buffer_type != BUF_PERSIST)
+		return -EINVAL;
+
+	ret = iris_get_internal_buf_info(inst, buffer_type);
+	if (ret)
+		return ret;
+
+	ret = iris_create_internal_buffers(inst, buffer_type);
+	if (ret)
+		return ret;
+
+	ret = iris_queue_internal_buffers(inst, buffer_type);
+
+	return ret;
+}
+
+int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst)
+{
+	int ret;
+
+	ret = iris_get_internal_buffers(inst, INPUT_MPLANE);
+	if (ret)
+		return ret;
+
+	ret = iris_release_input_internal_buffers(inst);
+	if (ret)
+		return ret;
+
+	ret = iris_create_input_internal_buffers(inst);
+	if (ret)
+		return ret;
+
+	ret = iris_queue_input_internal_buffers(inst);
+
+	return ret;
+}
+
+int iris_alloc_and_queue_additional_dpb_buffers(struct iris_inst *inst)
+{
+	struct iris_buffers *buffers;
+	struct iris_buffer *buffer;
+	int cur_min_count = 0;
+	int ret;
+	int i;
+
+	ret = iris_get_internal_buf_info(inst, BUF_DPB);
+	if (ret)
+		return ret;
+
+	buffers = iris_get_buffer_list(inst, BUF_DPB);
+	if (!buffers)
+		return -EINVAL;
+
+	list_for_each_entry(buffer, &buffers->list, list)
+		cur_min_count++;
+
+	if (cur_min_count >= buffers->min_count)
+		return 0;
+
+	for (i = cur_min_count; i < buffers->min_count; i++) {
+		ret = iris_create_internal_buffers(inst, BUF_DPB);
+		if (ret)
+			return ret;
+	}
+
+	ret = iris_queue_internal_buffers(inst, BUF_DPB);
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_buffer.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_buffer.h
@@ -0,0 +1,65 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_BUFFER_H_
+#define _IRIS_BUFFER_H_
+
+#define MIN_BUFFERS  4
+
+#include "iris_common.h"
+
+struct iris_inst;
+
+struct iris_buffers {
+	struct list_head	list; // list of "struct iris_buffer"
+	u32			min_count;
+	u32			actual_count;
+	u32			size;
+	bool			reuse;
+};
+
+struct iris_buffers_info {
+	struct iris_buffers	input;
+	struct iris_buffers	output;
+	struct iris_buffers	read_only;
+	struct iris_buffers	bin;
+	struct iris_buffers	arp;
+	struct iris_buffers	comv;
+	struct iris_buffers	non_comv;
+	struct iris_buffers	line;
+	struct iris_buffers	dpb;
+	struct iris_buffers	persist;
+	struct iris_buffers	vpss;
+};
+
+int update_buffer_count(struct iris_inst *inst, u32 plane);
+int iris_get_buf_min_count(struct iris_inst *inst,
+			   enum iris_buffer_type buffer_type);
+int iris_get_buffer_size(struct iris_inst *inst,
+			 enum iris_buffer_type buffer_type);
+struct iris_buffers *iris_get_buffer_list(struct iris_inst *inst,
+					  enum iris_buffer_type buffer_type);
+int iris_allocate_buffers(struct iris_inst *inst,
+			  enum iris_buffer_type buf_type,
+			  u32 num_buffers);
+int iris_free_buffers(struct iris_inst *inst,
+		      enum iris_buffer_type buf_type);
+
+int iris_get_internal_buffers(struct iris_inst *inst,
+			      u32 plane);
+int iris_create_input_internal_buffers(struct iris_inst *inst);
+int iris_create_output_internal_buffers(struct iris_inst *inst);
+int iris_queue_input_internal_buffers(struct iris_inst *inst);
+int iris_queue_output_internal_buffers(struct iris_inst *inst);
+int iris_destroy_internal_buffer(struct iris_inst *inst,
+				 struct iris_buffer *buffer);
+int iris_destroy_internal_buffers(struct iris_inst *inst,
+				  u32 plane);
+int iris_alloc_and_queue_session_int_bufs(struct iris_inst *inst,
+					  enum iris_buffer_type buffer_type);
+int iris_alloc_and_queue_input_int_bufs(struct iris_inst *inst);
+int iris_alloc_and_queue_additional_dpb_buffers(struct iris_inst *inst);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_common.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_common.h
@@ -0,0 +1,148 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#ifndef _IRIS_COMMON_H_
+#define _IRIS_COMMON_H_
+
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-event.h>
+#include <media/videobuf2-v4l2.h>
+
+struct iris_inst;
+
+#define INPUT_MPLANE V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
+#define OUTPUT_MPLANE V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
+#define DEFAULT_WIDTH 320
+#define DEFAULT_HEIGHT 240
+#define DEFAULT_BSE_VPP_DELAY    2
+#define IRIS_VERSION_LENGTH   128
+
+#define MAX_EVENTS   30
+
+#define MB_IN_PIXEL (16 * 16)
+
+#define NUM_MBS_4k (((4096 + 15) >> 4) * ((2304 + 15) >> 4))
+
+#define MAX_DPB_COUNT 32
+
+#define MAX_DPB_LIST_ARRAY_SIZE (16 * 4)
+#define MAX_DPB_LIST_PAYLOAD_SIZE (16 * 4 * 4)
+
+#define INPUT_TIMER_LIST_SIZE 30
+
+#define CABAC_MAX_BITRATE 160000000
+
+#define CAVLC_MAX_BITRATE 220000000
+
+enum domain_type {
+	ENCODER	= BIT(0),
+	DECODER	= BIT(1),
+};
+
+enum codec_type {
+	H264	= BIT(0),
+	HEVC	= BIT(1),
+	VP9	= BIT(2),
+};
+
+enum colorformat_type {
+	FMT_NONE	= 0,
+	FMT_NV12C	= BIT(0),
+	FMT_NV12	= BIT(1),
+	FMT_TP10C	= BIT(2),
+};
+
+struct rect_desc {
+	u32 left;
+	u32 top;
+	u32 width;
+	u32 height;
+};
+
+enum signal_session_response {
+	SIGNAL_CMD_STOP_INPUT = 0,
+	SIGNAL_CMD_STOP_OUTPUT,
+	SIGNAL_CMD_CLOSE,
+	MAX_SIGNAL,
+};
+
+enum iris_buffer_type {
+	BUF_NONE,
+	BUF_INPUT,
+	BUF_OUTPUT,
+	BUF_READ_ONLY,
+	BUF_BIN,
+	BUF_ARP,
+	BUF_COMV,
+	BUF_NON_COMV,
+	BUF_LINE,
+	BUF_DPB,
+	BUF_PERSIST,
+	BUF_VPSS,
+};
+
+enum iris_buffer_flags {
+	BUF_FLAG_KEYFRAME	= 0x00000008,
+	BUF_FLAG_PFRAME		= 0x00000010,
+	BUF_FLAG_BFRAME		= 0x00000020,
+	BUF_FLAG_ERROR		= 0x00000040,
+	BUF_FLAG_LAST		= 0x00100000,
+};
+
+enum iris_buffer_attributes {
+	BUF_ATTR_DEFERRED		= BIT(0),
+	BUF_ATTR_READ_ONLY		= BIT(1),
+	BUF_ATTR_PENDING_RELEASE	= BIT(2),
+	BUF_ATTR_QUEUED			= BIT(3),
+	BUF_ATTR_DEQUEUED		= BIT(4),
+	BUF_ATTR_BUFFER_DONE		= BIT(5),
+};
+
+struct iris_buffer {
+	struct list_head		list;
+	struct iris_inst		*inst;
+	enum iris_buffer_type		type;
+	u32				index;
+	int				fd;
+	u32				buffer_size;
+	u32				data_offset;
+	u32				data_size;
+	u64				device_addr;
+	void				*kvaddr;
+	unsigned long			dma_attrs;
+	u32				flags;
+	u64				timestamp;
+	enum iris_buffer_attributes	attr;
+	void				*dmabuf;
+	struct sg_table			*sg_table;
+	struct dma_buf_attachment	*attach;
+};
+
+struct subscription_params {
+	u32	bitstream_resolution;
+	u32	crop_offsets[2];
+	u32	bit_depth;
+	u32	coded_frames;
+	u32	fw_min_count;
+	u32	pic_order_cnt;
+	u32	color_info;
+	u32	profile;
+	u32	level;
+	u32	tier;
+};
+
+struct iris_hfi_frame_info {
+	u32	picture_type;
+	u32	no_output;
+	u32	data_corrupt;
+	u32	overflow;
+};
+
+struct iris_input_timer {
+	struct list_head	list;
+	u64			time_us;
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_core.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_core.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/delay.h>
+
+#include "iris_core.h"
+#include "iris_helpers.h"
+#include "iris_hfi.h"
+#include "iris_state.h"
+
+int iris_core_deinit_locked(struct iris_core *core)
+{
+	int ret;
+
+	ret = check_core_lock(core);
+	if (ret)
+		return ret;
+
+	if (core->state == IRIS_CORE_DEINIT)
+		return 0;
+
+	iris_hfi_core_deinit(core);
+
+	iris_change_core_state(core, IRIS_CORE_DEINIT);
+
+	return ret;
+}
+
+int iris_core_deinit(struct iris_core *core)
+{
+	int ret;
+
+	mutex_lock(&core->lock);
+	ret = iris_core_deinit_locked(core);
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_core_init(struct iris_core *core)
+{
+	int ret = 0;
+
+	mutex_lock(&core->lock);
+	if (core_in_valid_state(core)) {
+		goto unlock;
+	} else if (core->state == IRIS_CORE_ERROR) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (iris_change_core_state(core, IRIS_CORE_INIT_WAIT))
+		iris_change_core_state(core, IRIS_CORE_ERROR);
+
+	ret = iris_hfi_core_init(core);
+	if (ret) {
+		iris_change_core_state(core, IRIS_CORE_ERROR);
+		dev_err(core->dev, "%s: core init failed\n", __func__);
+		iris_core_deinit_locked(core);
+		goto unlock;
+	}
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_core_init_wait(struct iris_core *core)
+{
+	const int interval = 10;
+	int max_tries, count = 0, ret = 0;
+
+	mutex_lock(&core->lock);
+	if (!core_in_valid_state(core)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (core->state == IRIS_CORE_INIT)
+		goto unlock;
+
+	max_tries = core->cap[HW_RESPONSE_TIMEOUT].value / interval;
+	while (count < max_tries) {
+		if (core->state != IRIS_CORE_INIT_WAIT)
+			break;
+		msleep(interval);
+		count++;
+	}
+
+	if (core->state == IRIS_CORE_INIT) {
+		ret = 0;
+		goto unlock;
+	} else {
+		iris_change_core_state(core, IRIS_CORE_ERROR);
+		iris_core_deinit_locked(core);
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_core.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_core.h
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_CORE_H_
+#define _IRIS_CORE_H_
+
+#include <linux/types.h>
+#include <media/v4l2-device.h>
+
+#include "iris_hfi_queue.h"
+#include "iris_state.h"
+#include "platform_common.h"
+#include "resources.h"
+#include "vpu_common.h"
+
+/**
+ * struct iris_core - holds core parameters valid for all instances
+ *
+ * @dev: reference to device structure
+ * @reg_base: IO memory base address
+ * @irq: iris irq
+ * @v4l2_dev: a holder for v4l2 device structure
+ * @vdev_dec: iris video device structure for decoder
+ * @vdev_enc: iris video device structure for encoder
+ * @v4l2_file_ops: iris v4l2 file ops
+ * @v4l2_ioctl_ops_dec: iris v4l2 ioctl ops for decoder
+ * @v4l2_ioctl_ops_enc: iris v4l2 ioctl ops for encoder
+ * @bus_tbl: table of iris buses
+ * @bus_count: count of iris buses
+ * @power_domain_tbl: table of iris power domains
+ * @pd_count: count of iris power domains
+ * @clock_tbl: table of iris clocks
+ * @clk_count: count of iris clocks
+ * @reset_tbl: table of iris reset clocks
+ * @reset_count: count of iris reset clocks
+ * @vb2_ops: iris vb2 ops
+ * @vb2_mem_ops: iris vb2 memory ops
+ * @state: current state of core
+ * @iface_q_table: Interface queue table memory
+ * @command_queue: shared interface queue to send commands to firmware
+ * @message_queue: shared interface queue to receive responses from firmware
+ * @debug_queue: shared interface queue to receive debug info from firmware
+ * @sfr: SFR register memory
+ * @lock: a lock for this strucure
+ * @packet: pointer to packet from driver to fw
+ * @packet_size: size of packet
+ * @response_packet: a pointer to response packet from fw to driver
+ * @sys_init_id: id of sys init packet
+ * @header_id: id of packet header
+ * @packet_id: id of packet
+ * @vpu_ops: a pointer to vpu ops
+ * @session_ops: a pointer to session level ops
+ * @enc_codecs_count: supported codec count for encoder
+ * @dec_codecs_count: supported codec count for decoder
+ * @platform_data: a structure for platform data
+ * @cap: an array for supported core capabilities
+ * @inst_caps: a pointer to supported instance capabilities
+ * @instances: a list_head of all instances
+ * @intr_status: interrupt status
+ * @spur_count: counter for spurious interrupt
+ * @reg_count: counter for interrupts
+ * @fw_version: firmware version
+ * @skip_pc_count: a counter to retry power collapse
+ * @power_enabled: a boolean to check if power is on or off
+ * @power: a structure for clock and bw information
+ * @num_pending_requests: a reference counter for calling pm operations
+ */
+
+struct iris_core {
+	struct device				*dev;
+	void __iomem				*reg_base;
+	int					irq;
+	struct v4l2_device			v4l2_dev;
+	struct video_device			*vdev_dec;
+	struct video_device			*vdev_enc;
+	const struct v4l2_file_operations	*v4l2_file_ops;
+	const struct v4l2_ioctl_ops		*v4l2_ioctl_ops_dec;
+	const struct v4l2_ioctl_ops		*v4l2_ioctl_ops_enc;
+	struct bus_info				*bus_tbl;
+	u32					bus_count;
+	struct power_domain_info		*power_domain_tbl;
+	u32					pd_count;
+	struct clock_info			*clock_tbl;
+	u32					clk_count;
+	struct reset_info			*reset_tbl;
+	u32					reset_count;
+	const struct vb2_ops			*vb2_ops;
+	struct vb2_mem_ops			*vb2_mem_ops;
+	enum iris_core_state			state;
+	struct mem_desc				iface_q_table;
+	struct iface_q_info			command_queue;
+	struct iface_q_info			message_queue;
+	struct iface_q_info			debug_queue;
+	struct mem_desc				sfr;
+	struct mutex				lock; /* lock for core structure */
+	u8					*packet;
+	u32					packet_size;
+	u8					*response_packet;
+	u32					sys_init_id;
+	u32					header_id;
+	u32					packet_id;
+	const struct vpu_ops			*vpu_ops;
+	const struct vpu_session_ops		*session_ops;
+	u32					dec_codecs_count;
+	u32					enc_codecs_count;
+	struct platform_data			*platform_data;
+	struct plat_core_cap			cap[CORE_CAP_MAX + 1];
+	struct plat_inst_caps			*inst_caps;
+	struct list_head			instances;
+	u32					intr_status;
+	u32					spur_count;
+	u32					reg_count;
+	char					fw_version[IRIS_VERSION_LENGTH];
+	u32					skip_pc_count;
+	bool					power_enabled;
+	struct iris_core_power			power;
+	s32					num_pending_requests;
+};
+
+int iris_core_init(struct iris_core *core);
+int iris_core_init_wait(struct iris_core *core);
+int iris_core_deinit(struct iris_core *core);
+int iris_core_deinit_locked(struct iris_core *core);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_ctrls.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_ctrls.c
@@ -0,0 +1,1793 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/vmalloc.h>
+#include <linux/types.h>
+#include <linux/list.h>
+
+#include "platform_common.h"
+#include "iris_helpers.h"
+#include "iris_hfi_packet.h"
+#include "iris_hfi.h"
+#include "iris_ctrls.h"
+
+#define MIN_CAPTURE_BUFFERS 4
+#define MIN_OUTPUT_BUFFERS 4
+
+static inline bool is_all_childrens_visited(struct plat_inst_cap *cap,
+					    bool lookup[INST_CAP_MAX])
+{
+	bool found = true;
+	int i;
+
+	for (i = 0; i < MAX_NUM_CHILD; i++) {
+		if (cap->children[i] == INST_CAP_NONE)
+			continue;
+
+		if (!lookup[cap->children[i]]) {
+			found = false;
+			break;
+		}
+	}
+
+	return found;
+}
+
+static bool is_valid_cap_id(enum plat_inst_cap_type cap_id)
+{
+	return cap_id > INST_CAP_NONE && cap_id < INST_CAP_MAX;
+}
+
+static enum plat_inst_cap_type get_cap_id(struct iris_inst *inst, u32 id)
+{
+	enum plat_inst_cap_type iter = INST_CAP_NONE;
+	enum plat_inst_cap_type cap_id = INST_CAP_NONE;
+
+	do {
+		if (inst->cap[iter].v4l2_id == id) {
+			cap_id = inst->cap[iter].cap_id;
+			break;
+		}
+		iter++;
+	} while (iter < INST_CAP_MAX);
+
+	return cap_id;
+}
+
+static int add_node_list(struct list_head *list, enum plat_inst_cap_type cap_id)
+{
+	struct cap_entry *entry = NULL;
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&entry->list);
+	entry->cap_id = cap_id;
+	list_add(&entry->list, list);
+
+	return 0;
+}
+
+static int add_children(struct list_head *list,
+			struct iris_inst *inst,
+			enum plat_inst_cap_type cap_id)
+{
+	struct plat_inst_cap *cap;
+	int i, ret = 0;
+
+	cap = &inst->cap[cap_id];
+
+	for (i = 0; i < MAX_NUM_CHILD; i++) {
+		if (!cap->children[i])
+			break;
+
+		if (!is_valid_cap_id(cap->children[i]))
+			continue;
+
+		ret = add_node_list(list, cap->children[i]);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static int adjust_cap(struct iris_inst *inst,
+		      enum plat_inst_cap_type cap_id,
+		      struct v4l2_ctrl *ctrl)
+{
+	struct plat_inst_cap *cap;
+
+	cap = &inst->cap[cap_id];
+	if (!inst->cap[cap_id].cap_id)
+		return 0;
+
+	if (!cap->adjust) {
+		if (ctrl)
+			inst->cap[cap_id].value = ctrl->val;
+		return 0;
+	}
+
+	return cap->adjust(inst, ctrl);
+}
+
+static int set_cap(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	struct plat_inst_cap *cap;
+
+	cap = &inst->cap[cap_id];
+	if (!inst->cap[cap_id].cap_id)
+		return 0;
+
+	if (!cap->set)
+		return 0;
+
+	return cap->set(inst, cap_id);
+}
+
+static int adjust_dynamic_property(struct iris_inst *inst,
+				   enum plat_inst_cap_type cap_id,
+				   struct v4l2_ctrl *ctrl,
+				   struct list_head *firmware_list,
+				   struct list_head *children_list,
+				   bool cap_present[INST_CAP_MAX])
+{
+	struct cap_entry *entry = NULL, *temp = NULL;
+	struct plat_inst_cap *cap;
+	s32 prev_value;
+	int ret;
+
+	cap = &inst->cap[0];
+
+	if (!(cap[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED))
+		return -EBUSY;
+
+	prev_value = cap[cap_id].value;
+	ret = adjust_cap(inst, cap_id, ctrl);
+	if (ret)
+		return ret;
+
+	ret = add_node_list(firmware_list, cap_id);
+	if (ret)
+		return ret;
+	cap_present[cap->cap_id] = true;
+
+	if (cap[cap_id].value == prev_value)
+		return 0;
+
+	ret = add_children(children_list, inst, cap_id);
+	if (ret)
+		return ret;
+
+	list_for_each_entry_safe(entry, temp, children_list, list) {
+		if (!cap[entry->cap_id].adjust) {
+			list_del_init(&entry->list);
+			kfree(entry);
+			continue;
+		}
+
+		prev_value = cap[entry->cap_id].value;
+		ret = adjust_cap(inst, entry->cap_id, NULL);
+		if (ret)
+			return ret;
+
+		if (cap[entry->cap_id].value != prev_value) {
+			if (!cap_present[cap->cap_id]) {
+				ret = add_node_list(firmware_list, cap_id);
+				if (ret)
+					return ret;
+				cap_present[cap->cap_id] = true;
+			}
+
+			ret = add_children(children_list, inst, entry->cap_id);
+			if (ret)
+				return ret;
+		}
+
+		list_del_init(&entry->list);
+		kfree(entry);
+	}
+
+	if (!list_empty(children_list))
+		return -EINVAL;
+
+	return ret;
+}
+
+static int set_dynamic_property(struct iris_inst *inst,
+				struct list_head *firmware_list)
+{
+	struct cap_entry *entry = NULL, *temp = NULL;
+	struct plat_inst_cap *cap;
+	int ret = 0;
+
+	list_for_each_entry_safe(entry, temp, firmware_list, list) {
+		cap = &inst->cap[entry->cap_id];
+		if (cap->set) {
+			ret = cap->set(inst, entry->cap_id);
+			if (ret)
+				return -EINVAL;
+		}
+		list_del_init(&entry->list);
+		kfree(entry);
+	}
+
+	return ret;
+}
+
+static int iris_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+	enum plat_inst_cap_type cap_id;
+	struct iris_inst *inst = NULL;
+	int ret = 0;
+
+	inst = container_of(ctrl->handler, struct iris_inst, ctrl_handler);
+	switch (ctrl->id) {
+	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
+		ctrl->val = inst->buffers.output.min_count;
+		break;
+	case V4L2_CID_MIN_BUFFERS_FOR_OUTPUT:
+		ctrl->val = inst->buffers.input.min_count;
+		break;
+	default:
+		cap_id = get_cap_id(inst, ctrl->id);
+		if (is_valid_cap_id(cap_id))
+			ctrl->val = inst->cap[cap_id].value;
+		else
+			ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int iris_op_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct cap_entry *entry = NULL, *temp = NULL;
+	struct list_head children_list, firmware_list;
+	struct ctrl_data *priv_ctrl_data;
+	enum plat_inst_cap_type cap_id;
+	bool cap_present[INST_CAP_MAX];
+	struct plat_inst_cap *cap;
+	struct iris_inst *inst;
+	int ret = 0;
+
+	priv_ctrl_data = ctrl->priv ? ctrl->priv : NULL;
+	if (priv_ctrl_data && priv_ctrl_data->skip_s_ctrl)
+		return 0;
+
+	inst = container_of(ctrl->handler, struct iris_inst, ctrl_handler);
+	cap = &inst->cap[0];
+
+	INIT_LIST_HEAD(&firmware_list);
+	INIT_LIST_HEAD(&children_list);
+	memset(&cap_present, 0, sizeof(cap_present));
+
+	cap_id = get_cap_id(inst, ctrl->id);
+	if (!is_valid_cap_id(cap_id))
+		return -EINVAL;
+
+	if (!allow_s_ctrl(inst, cap_id))
+		return -EBUSY;
+
+	cap[cap_id].flags |= CAP_FLAG_CLIENT_SET;
+
+	if ((inst->domain == ENCODER && !inst->vb2q_dst->streaming) ||
+	    (inst->domain == DECODER && !inst->vb2q_src->streaming)) {
+		inst->cap[cap_id].value = ctrl->val;
+	} else {
+		ret = adjust_dynamic_property(inst, cap_id, ctrl,
+					      &firmware_list, &children_list,
+					      cap_present);
+		if (ret)
+			goto free_list;
+
+		ret = set_dynamic_property(inst, &firmware_list);
+	}
+
+free_list:
+	list_for_each_entry_safe(entry, temp, &children_list, list) {
+		list_del_init(&entry->list);
+		kfree(entry);
+	}
+
+	list_for_each_entry_safe(entry, temp, &firmware_list, list) {
+		list_del_init(&entry->list);
+		kfree(entry);
+	}
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops ctrl_ops = {
+	.s_ctrl = iris_op_s_ctrl,
+	.g_volatile_ctrl = iris_op_g_volatile_ctrl,
+};
+
+int ctrls_init(struct iris_inst *inst, bool init)
+{
+	int num_ctrls = 0, ctrl_idx = 0;
+	u64 codecs_count, step_or_mask;
+	struct plat_inst_cap *cap;
+	struct iris_core *core;
+	int idx = 0;
+	int ret = 0;
+
+	core = inst->core;
+	cap = &inst->cap[0];
+
+	for (idx = 0; idx < INST_CAP_MAX; idx++) {
+		if (cap[idx].v4l2_id)
+			num_ctrls++;
+	}
+	if (!num_ctrls)
+		return -EINVAL;
+
+	if (init) {
+		codecs_count = inst->domain == ENCODER ?
+			core->enc_codecs_count :
+			core->dec_codecs_count;
+		ret = v4l2_ctrl_handler_init(&inst->ctrl_handler,
+					     INST_CAP_MAX * codecs_count);
+		if (ret)
+			return ret;
+	}
+
+	for (idx = 0; idx < INST_CAP_MAX; idx++) {
+		struct v4l2_ctrl *ctrl;
+
+		if (!cap[idx].v4l2_id)
+			continue;
+
+		if (ctrl_idx >= num_ctrls) {
+			ret = -EINVAL;
+			goto error;
+		}
+
+		if (!init) {
+			struct ctrl_data ctrl_priv_data;
+
+			ctrl = v4l2_ctrl_find(&inst->ctrl_handler, cap[idx].v4l2_id);
+			if (ctrl) {
+				step_or_mask = (cap[idx].flags & CAP_FLAG_MENU) ?
+					~(cap[idx].step_or_mask) :
+					cap[idx].step_or_mask;
+				memset(&ctrl_priv_data, 0, sizeof(ctrl_priv_data));
+				ctrl_priv_data.skip_s_ctrl = true;
+				ctrl->priv = &ctrl_priv_data;
+				v4l2_ctrl_modify_range(ctrl,
+						       cap[idx].min,
+						       cap[idx].max,
+						       step_or_mask,
+						       cap[idx].value);
+				ctrl->priv = NULL;
+				continue;
+			}
+		}
+
+		if (cap[idx].flags & CAP_FLAG_MENU) {
+			ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler,
+						      &ctrl_ops,
+						      cap[idx].v4l2_id,
+						      cap[idx].max,
+						      ~(cap[idx].step_or_mask),
+						      cap[idx].value);
+		} else {
+			ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler,
+						 &ctrl_ops,
+						 cap[idx].v4l2_id,
+						 cap[idx].min,
+						 cap[idx].max,
+						 cap[idx].step_or_mask,
+						 cap[idx].value);
+		}
+		if (!ctrl) {
+			ret = -EINVAL;
+			goto error;
+		}
+
+		ret = inst->ctrl_handler.error;
+		if (ret)
+			goto error;
+
+		if ((cap[idx].flags & CAP_FLAG_VOLATILE) ||
+		    (ctrl->id == V4L2_CID_MIN_BUFFERS_FOR_CAPTURE ||
+		     ctrl->id == V4L2_CID_MIN_BUFFERS_FOR_OUTPUT))
+			ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
+		ctrl->flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
+		ctrl_idx++;
+	}
+	inst->num_ctrls = num_ctrls;
+
+	return 0;
+error:
+	v4l2_ctrl_handler_free(&inst->ctrl_handler);
+
+	return ret;
+}
+
+int iris_init_core_caps(struct iris_core *core)
+{
+	struct plat_core_cap *core_platform_data;
+	int i, num_core_caps;
+
+	core_platform_data = core->platform_data->core_data;
+	if (!core_platform_data)
+		return -EINVAL;
+
+	num_core_caps = core->platform_data->core_data_size;
+
+	for (i = 0; i < num_core_caps && i < CORE_CAP_MAX; i++) {
+		core->cap[core_platform_data[i].type].type = core_platform_data[i].type;
+		core->cap[core_platform_data[i].type].value = core_platform_data[i].value;
+	}
+
+	return 0;
+}
+
+static int update_inst_capability(struct plat_inst_cap *in,
+				  struct plat_inst_caps *capability)
+{
+	if (!in || !capability)
+		return -EINVAL;
+
+	if (in->cap_id >= INST_CAP_MAX)
+		return -EINVAL;
+
+	capability->cap[in->cap_id].cap_id = in->cap_id;
+	capability->cap[in->cap_id].min = in->min;
+	capability->cap[in->cap_id].max = in->max;
+	capability->cap[in->cap_id].step_or_mask = in->step_or_mask;
+	capability->cap[in->cap_id].value = in->value;
+	capability->cap[in->cap_id].flags = in->flags;
+	capability->cap[in->cap_id].v4l2_id = in->v4l2_id;
+	capability->cap[in->cap_id].hfi_id = in->hfi_id;
+	memcpy(capability->cap[in->cap_id].children, in->children,
+	       sizeof(capability->cap[in->cap_id].children));
+	capability->cap[in->cap_id].adjust = in->adjust;
+	capability->cap[in->cap_id].set = in->set;
+
+	return 0;
+}
+
+int iris_init_instance_caps(struct iris_core *core)
+{
+	struct plat_inst_cap *inst_plat_cap_data = NULL;
+	u8 enc_codecs_count = 0, dec_codecs_count = 0;
+	u32 enc_valid_codecs, dec_valid_codecs;
+	int i, j, check_bit = 0;
+	u8 codecs_count = 0;
+	int num_inst_cap;
+	int ret = 0;
+
+	inst_plat_cap_data = core->platform_data->inst_cap_data;
+	if (!inst_plat_cap_data)
+		return -EINVAL;
+
+	enc_valid_codecs = core->cap[ENC_CODECS].value;
+	enc_codecs_count = hweight32(enc_valid_codecs);
+	core->enc_codecs_count = enc_codecs_count;
+
+	dec_valid_codecs = core->cap[DEC_CODECS].value;
+	dec_codecs_count = hweight32(dec_valid_codecs);
+	core->dec_codecs_count = dec_codecs_count;
+
+	codecs_count = enc_codecs_count + dec_codecs_count;
+	core->inst_caps = devm_kzalloc(core->dev,
+				       codecs_count * sizeof(struct plat_inst_caps),
+				       GFP_KERNEL);
+	if (!core->inst_caps)
+		return -ENOMEM;
+
+	for (i = 0; i < enc_codecs_count; i++) {
+		while (check_bit < (sizeof(enc_valid_codecs) * 8)) {
+			if (enc_valid_codecs & BIT(check_bit)) {
+				core->inst_caps[i].domain = ENCODER;
+				core->inst_caps[i].codec = enc_valid_codecs &
+						BIT(check_bit);
+				check_bit++;
+				break;
+			}
+			check_bit++;
+		}
+	}
+
+	check_bit = 0;
+
+	for (; i < codecs_count; i++) {
+		while (check_bit < (sizeof(dec_valid_codecs) * 8)) {
+			if (dec_valid_codecs & BIT(check_bit)) {
+				core->inst_caps[i].domain = DECODER;
+				core->inst_caps[i].codec = dec_valid_codecs &
+						BIT(check_bit);
+				check_bit++;
+				break;
+			}
+			check_bit++;
+		}
+	}
+
+	num_inst_cap = core->platform_data->inst_cap_data_size;
+
+	for (i = 0; i < num_inst_cap; i++) {
+		for (j = 0; j < codecs_count; j++) {
+			if ((inst_plat_cap_data[i].domain & core->inst_caps[j].domain) &&
+			    (inst_plat_cap_data[i].codec & core->inst_caps[j].codec)) {
+				ret = update_inst_capability(&inst_plat_cap_data[i],
+							     &core->inst_caps[j]);
+				if (ret)
+					return ret;
+			}
+		}
+	}
+
+	return ret;
+}
+
+int get_inst_capability(struct iris_inst *inst)
+{
+	struct iris_core *core;
+	u32 codecs_count = 0;
+	int i;
+
+	core = inst->core;
+
+	codecs_count = core->enc_codecs_count + core->dec_codecs_count;
+
+	for (i = 0; i < codecs_count; i++) {
+		if (core->inst_caps[i].domain == inst->domain &&
+			core->inst_caps[i].codec == inst->codec) {
+			memcpy(&inst->cap[0], &core->inst_caps[i].cap[0],
+			       (INST_CAP_MAX + 1) * sizeof(struct plat_inst_cap));
+		}
+	}
+
+	return 0;
+}
+
+int prepare_dependency_list(struct iris_inst *inst)
+{
+	struct cap_entry *entry = NULL, *temp = NULL;
+	struct plat_inst_cap *cap, *temp_cap;
+	int caps_to_prepare, pending_list_counter,
+		pending_at_start = 0;
+	struct list_head prepared_list, pending_list;
+	bool is_prepared[INST_CAP_MAX];
+	bool is_pending[INST_CAP_MAX];
+	int i, ret = 0;
+
+	cap = &inst->cap[0];
+
+	if (!list_empty(&inst->caps_list))
+		return 0;
+
+	INIT_LIST_HEAD(&prepared_list);
+	INIT_LIST_HEAD(&pending_list);
+	memset(&is_prepared, 0, sizeof(is_prepared));
+	memset(&is_pending, 0, sizeof(is_pending));
+
+	for (i = 1; i < INST_CAP_MAX; i++) {
+		temp_cap = &cap[i];
+		if (!is_valid_cap_id(temp_cap->cap_id))
+			continue;
+
+		if (!temp_cap->children[0]) {
+			if (!is_prepared[temp_cap->cap_id]) {
+				ret = add_node_list(&prepared_list, temp_cap->cap_id);
+				if (ret)
+					goto free_list;
+				is_prepared[temp_cap->cap_id] = true;
+			}
+		} else {
+			if (!is_pending[temp_cap->cap_id]) {
+				ret = add_node_list(&pending_list, temp_cap->cap_id);
+				if (ret)
+					goto free_list;
+				is_pending[temp_cap->cap_id] = true;
+			}
+		}
+	}
+
+	list_for_each_entry(entry, &pending_list, list)
+		pending_at_start++;
+
+	caps_to_prepare = pending_at_start;
+	pending_list_counter = pending_at_start;
+
+	list_for_each_entry_safe(entry, temp, &pending_list, list) {
+		list_del_init(&entry->list);
+		is_pending[entry->cap_id] = false;
+		pending_list_counter--;
+		temp_cap = &cap[entry->cap_id];
+
+		if (is_all_childrens_visited(temp_cap, is_prepared)) {
+			list_add(&entry->list, &prepared_list);
+			is_prepared[entry->cap_id] = true;
+			caps_to_prepare--;
+		} else {
+			list_add_tail(&entry->list, &pending_list);
+			is_pending[entry->cap_id] = true;
+		}
+
+		if (!pending_list_counter) {
+			if (pending_at_start == caps_to_prepare) {
+				ret = -EINVAL;
+				goto free_list;
+			}
+			pending_at_start = caps_to_prepare;
+			pending_list_counter = caps_to_prepare;
+		}
+	}
+
+	if (!list_empty(&pending_list)) {
+		ret = -EINVAL;
+		goto free_list;
+	}
+
+	list_replace_init(&prepared_list, &inst->caps_list);
+
+free_list:
+	list_for_each_entry_safe(entry, temp, &pending_list, list) {
+		list_del_init(&entry->list);
+		kfree(entry);
+	}
+	list_for_each_entry_safe(entry, temp, &prepared_list, list) {
+		list_del_init(&entry->list);
+		kfree(entry);
+	}
+
+	return ret;
+}
+
+static inline bool is_layer_bitrate_set(struct iris_inst *inst)
+{
+	u32 layer_br_caps[6] = {L0_BR, L1_BR, L2_BR, L3_BR, L4_BR, L5_BR};
+	u32 cap_id = 0, i, enh_layer_count;
+
+	enh_layer_count = inst->cap[ENH_LAYER_COUNT].value;
+
+	for (i = 0; i <= enh_layer_count; i++) {
+		if (i >= ARRAY_SIZE(layer_br_caps))
+			break;
+
+		cap_id = layer_br_caps[i];
+		if (!(inst->cap[cap_id].flags & CAP_FLAG_CLIENT_SET))
+			return false;
+	}
+
+	return true;
+}
+
+static inline u32 get_cumulative_bitrate(struct iris_inst *inst)
+{
+	u32 layer_br_caps[6] = {L0_BR, L1_BR, L2_BR, L3_BR, L4_BR, L5_BR};
+	u32 cumulative_br = 0;
+	s32 enh_layer_count;
+	u32 cap_id = 0;
+	int i;
+
+	enh_layer_count = inst->cap[ENH_LAYER_COUNT].value;
+
+	for (i = 0; i <= enh_layer_count; i++) {
+		if (i >= ARRAY_SIZE(layer_br_caps))
+			break;
+		cap_id = layer_br_caps[i];
+		cumulative_br += inst->cap[cap_id].value;
+	}
+
+	return cumulative_br;
+}
+
+int set_u32_enum(struct iris_inst *inst,
+		 enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_value = inst->cap[cap_id].value;
+	u32 hfi_id = inst->cap[cap_id].hfi_id;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_U32_ENUM,
+				     &hfi_value, sizeof(u32));
+}
+
+int set_u32(struct iris_inst *inst,
+	    enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_value = inst->cap[cap_id].value;
+	u32 hfi_id = inst->cap[cap_id].hfi_id;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_U32,
+				     &hfi_value, sizeof(u32));
+}
+
+int set_q16(struct iris_inst *inst,
+	    enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_value = inst->cap[cap_id].value;
+	u32 hfi_id = inst->cap[cap_id].hfi_id;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_Q16,
+				     &hfi_value, sizeof(u32));
+}
+
+int set_stage(struct iris_inst *inst,
+	      enum plat_inst_cap_type cap_id)
+{
+	struct v4l2_format *inp_f;
+	u32 work_mode = STAGE_2;
+	u32 width, height;
+	u32 hfi_id;
+
+	hfi_id = inst->cap[cap_id].hfi_id;
+
+	if (inst->domain == DECODER) {
+		inp_f = inst->fmt_src;
+		height = inp_f->fmt.pix_mp.height;
+		width = inp_f->fmt.pix_mp.width;
+		if (res_is_less_than(width, height, 1280, 720))
+			work_mode = STAGE_1;
+	} else if (inst->domain == ENCODER) {
+		if (inst->cap[SLICE_MODE].value ==
+		    V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES)
+			work_mode = STAGE_1;
+
+		if (inst->hfi_rc_type == HFI_RC_CBR_CFR ||
+		    inst->hfi_rc_type == HFI_RC_CBR_VFR)
+			work_mode = STAGE_1;
+
+		if (!inst->cap[GOP_SIZE].value)
+			work_mode = STAGE_2;
+	}
+
+	inst->cap[cap_id].value = work_mode;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_U32,
+				     &work_mode, sizeof(u32));
+}
+
+int set_pipe(struct iris_inst *inst,
+	     enum plat_inst_cap_type cap_id)
+{
+	u32 work_route, hfi_id;
+
+	work_route = inst->cap[cap_id].value;
+	hfi_id = inst->cap[cap_id].hfi_id;
+
+	if (inst->domain == ENCODER) {
+		if (inst->cap[SLICE_MODE].value ==
+		    V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES)
+			work_route = PIPE_1;
+	}
+
+	inst->cap[cap_id].value = work_route;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_U32,
+				     &work_route, sizeof(u32));
+}
+
+int set_level(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_value = inst->cap[cap_id].value;
+	u32 hfi_id = inst->cap[cap_id].hfi_id;
+
+	if (!(inst->cap[cap_id].flags & CAP_FLAG_CLIENT_SET))
+		hfi_value = HFI_LEVEL_NONE;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+					 get_port_info(inst, cap_id),
+					 HFI_PAYLOAD_U32_ENUM,
+					 &hfi_value, sizeof(u32));
+}
+
+int decide_quality_mode(struct iris_inst *inst)
+{
+	u32 fps, mbpf, mbps, max_hq_mbpf, max_hq_mbps;
+	u32 mode = POWER_SAVE_MODE;
+	struct iris_core *core;
+
+	if (inst->domain != ENCODER)
+		return 0;
+
+	mbpf = NUM_MBS_PER_FRAME(inst->crop.height, inst->crop.width);
+	fps = max3(inst->cap[QUEUED_RATE].value >> 16,
+		   inst->cap[FRAME_RATE].value >> 16,
+		   inst->cap[OPERATING_RATE].value >> 16);
+	mbps = mbpf * fps;
+	core = inst->core;
+	max_hq_mbpf = core->cap[MAX_MBPF_HQ].value;
+	max_hq_mbps = core->cap[MAX_MBPS_HQ].value;
+
+	if (mbpf <= max_hq_mbpf && mbps <= max_hq_mbps)
+		mode = MAX_QUALITY_MODE;
+
+	inst->cap[QUALITY_MODE].value = mode;
+
+	return mode;
+}
+
+int set_req_sync_frame(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_id, hfi_val;
+	s32 prepend_sps_pps;
+
+	prepend_sps_pps = inst->cap[PREPEND_SPSPPS_TO_IDR].value;
+	hfi_id = inst->cap[cap_id].hfi_id;
+
+	if (prepend_sps_pps)
+		hfi_val = HFI_SYNC_FRAME_REQUEST_WITH_PREFIX_SEQ_HDR;
+	else
+		hfi_val = HFI_SYNC_FRAME_REQUEST_WITHOUT_SEQ_HDR;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_U32_ENUM,
+				     &hfi_val, sizeof(u32));
+}
+
+int set_flip(struct iris_inst *inst,
+	     enum plat_inst_cap_type cap_id)
+{
+	u32 hflip, vflip, ret = 0;
+
+	u32 hfi_value = HFI_DISABLE_FLIP;
+	u32 hfi_id = inst->cap[cap_id].hfi_id;
+
+	hflip = inst->cap[HFLIP].value;
+	vflip = inst->cap[VFLIP].value;
+
+	if (hflip)
+		hfi_value |= HFI_HORIZONTAL_FLIP;
+
+	if (vflip)
+		hfi_value |= HFI_VERTICAL_FLIP;
+
+	if (inst->vb2q_dst->streaming) {
+		if (hfi_value != HFI_DISABLE_FLIP) {
+			ret = set_req_sync_frame(inst, REQUEST_I_FRAME);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_U32_ENUM,
+				     &hfi_value, sizeof(u32));
+}
+
+int set_rotation(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_id, hfi_val;
+
+	hfi_id = inst->cap[cap_id].hfi_id;
+	v4l2_to_hfi_enum(inst, cap_id, &hfi_val);
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_U32,
+				     &hfi_val, sizeof(u32));
+}
+
+int set_header_mode(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	u32 header_mode, hfi_id, hfi_val;
+	s32 prepend_sps_pps;
+
+	prepend_sps_pps = inst->cap[PREPEND_SPSPPS_TO_IDR].value;
+	header_mode = inst->cap[cap_id].value;
+	hfi_id = inst->cap[cap_id].hfi_id;
+
+	if (prepend_sps_pps)
+		hfi_val = HFI_SEQ_HEADER_PREFIX_WITH_SYNC_FRAME;
+	else if (header_mode == V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME)
+		hfi_val = HFI_SEQ_HEADER_JOINED_WITH_1ST_FRAME;
+	else
+		hfi_val = HFI_SEQ_HEADER_SEPERATE_FRAME;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_U32_ENUM,
+				     &hfi_val, sizeof(u32));
+}
+
+int set_gop_size(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_value, hfi_id;
+
+	if (inst->vb2q_dst->streaming) {
+		if (inst->hfi_layer_type == HFI_HIER_B)
+			return 0;
+	}
+
+	hfi_value = inst->cap[GOP_SIZE].value;
+	hfi_id = inst->cap[cap_id].hfi_id;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_U32,
+				     &hfi_value, sizeof(u32));
+}
+
+int set_bitrate(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_id, hfi_val;
+
+	if (inst->cap[BIT_RATE].flags & CAP_FLAG_CLIENT_SET)
+		goto set_total_bitrate;
+
+	if (inst->vb2q_dst->streaming)
+		return 0;
+
+set_total_bitrate:
+	hfi_id = inst->cap[cap_id].hfi_id;
+	hfi_val = inst->cap[cap_id].value;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_U32,
+				     &hfi_val, sizeof(u32));
+}
+
+int set_layer_bitrate(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_value = 0;
+	u32 hfi_id;
+
+	if (!inst->vb2q_dst->streaming)
+		return 0;
+
+	if (inst->cap[BIT_RATE].flags & CAP_FLAG_CLIENT_SET)
+		return 0;
+
+	if (!inst->cap[ENH_LAYER_COUNT].max ||
+	    !is_layer_bitrate_set(inst))
+		return 0;
+
+	hfi_value = inst->cap[BIT_RATE].value;
+	hfi_id = inst->cap[BIT_RATE].hfi_id;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_U32,
+				     &hfi_value, sizeof(u32));
+}
+
+int set_peak_bitrate(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_id, hfi_val;
+	s32 rc_mode;
+
+	hfi_id = inst->cap[cap_id].hfi_id;
+	hfi_val = inst->cap[cap_id].value;
+
+	rc_mode = inst->cap[BITRATE_MODE].value;
+	if (rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+		return 0;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_U32,
+				     &hfi_val, sizeof(u32));
+}
+
+int set_bitrate_mode(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_value, hfi_id;
+
+	hfi_id = inst->cap[cap_id].hfi_id;
+	hfi_value = inst->hfi_rc_type;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+			get_port_info(inst, cap_id),
+			HFI_PAYLOAD_U32_ENUM,
+			&hfi_value, sizeof(u32));
+}
+
+int set_use_and_mark_ltr(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_id, hfi_val;
+
+	hfi_id = inst->cap[cap_id].hfi_id;
+	hfi_val = inst->cap[cap_id].value;
+
+	if (!inst->cap[LTR_COUNT].value ||
+	    inst->cap[cap_id].value == INVALID_DEFAULT_MARK_OR_USE_LTR)
+		return 0;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_U32,
+				     &hfi_val, sizeof(u32));
+}
+
+int set_ir_period(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_id = 0, hfi_val;
+
+	hfi_val = inst->cap[cap_id].value;
+
+	if (inst->cap[IR_TYPE].value ==
+	    V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM) {
+		hfi_id = HFI_PROP_IR_RANDOM_PERIOD;
+	} else if (inst->cap[IR_TYPE].value ==
+		   V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC) {
+		hfi_id = HFI_PROP_IR_CYCLIC_PERIOD;
+	}
+
+	return iris_hfi_set_ir_period(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				      get_port_info(inst, cap_id),
+				      HFI_PAYLOAD_U32,
+				      &hfi_val, sizeof(u32));
+}
+
+int set_min_qp(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	s32 i_frame_qp = 0, p_frame_qp = 0, b_frame_qp = 0, min_qp_enable = 0;
+	u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0;
+	u32 client_qp_enable = 0, hfi_value = 0;
+	u32 hfi_id;
+
+	if (inst->cap[MIN_FRAME_QP].flags & CAP_FLAG_CLIENT_SET)
+		min_qp_enable = 1;
+
+	if (min_qp_enable ||
+	    (inst->cap[I_FRAME_MIN_QP].flags & CAP_FLAG_CLIENT_SET))
+		i_qp_enable = 1;
+	if (min_qp_enable ||
+	    (inst->cap[P_FRAME_MIN_QP].flags & CAP_FLAG_CLIENT_SET))
+		p_qp_enable = 1;
+	if (min_qp_enable ||
+	    (inst->cap[B_FRAME_MIN_QP].flags & CAP_FLAG_CLIENT_SET))
+		b_qp_enable = 1;
+
+	client_qp_enable = i_qp_enable | p_qp_enable << 1 | b_qp_enable << 2;
+	if (!client_qp_enable)
+		return 0;
+
+	i_frame_qp = max(inst->cap[I_FRAME_MIN_QP].value, inst->cap[MIN_FRAME_QP].value);
+	p_frame_qp = max(inst->cap[P_FRAME_MIN_QP].value, inst->cap[MIN_FRAME_QP].value);
+	b_frame_qp = max(inst->cap[B_FRAME_MIN_QP].value, inst->cap[MIN_FRAME_QP].value);
+
+	hfi_id = inst->cap[cap_id].hfi_id;
+	hfi_value = i_frame_qp | p_frame_qp << 8 | b_frame_qp << 16 |
+		client_qp_enable << 24;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_32_PACKED,
+				     &hfi_value, sizeof(u32));
+}
+
+int set_max_qp(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	s32 i_frame_qp = 0, p_frame_qp = 0, b_frame_qp = 0, max_qp_enable = 0;
+	u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0;
+	u32 client_qp_enable = 0, hfi_value = 0;
+	u32 hfi_id;
+
+	if (inst->cap[MAX_FRAME_QP].flags & CAP_FLAG_CLIENT_SET)
+		max_qp_enable = 1;
+
+	if (max_qp_enable ||
+	    (inst->cap[I_FRAME_MAX_QP].flags & CAP_FLAG_CLIENT_SET))
+		i_qp_enable = 1;
+	if (max_qp_enable ||
+	    (inst->cap[P_FRAME_MAX_QP].flags & CAP_FLAG_CLIENT_SET))
+		p_qp_enable = 1;
+	if (max_qp_enable ||
+	    (inst->cap[B_FRAME_MAX_QP].flags & CAP_FLAG_CLIENT_SET))
+		b_qp_enable = 1;
+
+	client_qp_enable = i_qp_enable | p_qp_enable << 1 | b_qp_enable << 2;
+	if (!client_qp_enable)
+		return 0;
+
+	i_frame_qp = min(inst->cap[I_FRAME_MAX_QP].value, inst->cap[MAX_FRAME_QP].value);
+	p_frame_qp = min(inst->cap[P_FRAME_MAX_QP].value, inst->cap[MAX_FRAME_QP].value);
+	b_frame_qp = min(inst->cap[B_FRAME_MAX_QP].value, inst->cap[MAX_FRAME_QP].value);
+
+	hfi_id = inst->cap[cap_id].hfi_id;
+	hfi_value = i_frame_qp | p_frame_qp << 8 | b_frame_qp << 16 |
+		client_qp_enable << 24;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_32_PACKED,
+				     &hfi_value, sizeof(u32));
+}
+
+int set_frame_qp(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	u32 i_qp_enable = 0, p_qp_enable = 0, b_qp_enable = 0;
+	u32 client_qp_enable = 0, hfi_value = 0;
+	s32 i_frame_qp = 0, p_frame_qp = 0, b_frame_qp = 0;
+	s32 rc_type = -1;
+	u32 hfi_id;
+
+	rc_type = inst->hfi_rc_type;
+	if (inst->vb2q_dst->streaming) {
+		if (rc_type != HFI_RC_OFF)
+			return 0;
+	}
+
+	if (rc_type == HFI_RC_OFF) {
+		i_qp_enable = 1;
+		p_qp_enable = 1;
+		b_qp_enable = 1;
+	} else {
+		if (inst->cap[I_FRAME_QP].flags & CAP_FLAG_CLIENT_SET)
+			i_qp_enable = 1;
+		if (inst->cap[P_FRAME_QP].flags & CAP_FLAG_CLIENT_SET)
+			p_qp_enable = 1;
+		if (inst->cap[B_FRAME_QP].flags & CAP_FLAG_CLIENT_SET)
+			b_qp_enable = 1;
+	}
+
+	client_qp_enable = i_qp_enable | p_qp_enable << 1 | b_qp_enable << 2;
+	if (!client_qp_enable)
+		return 0;
+
+	i_frame_qp = inst->cap[I_FRAME_QP].value;
+	p_frame_qp = inst->cap[P_FRAME_QP].value;
+	b_frame_qp = inst->cap[B_FRAME_QP].value;
+
+	hfi_id = inst->cap[cap_id].hfi_id;
+	hfi_value = i_frame_qp | p_frame_qp << 8 | b_frame_qp << 16 |
+		client_qp_enable << 24;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, cap_id),
+				     HFI_PAYLOAD_32_PACKED,
+				     &hfi_value, sizeof(u32));
+}
+
+int set_layer_count_and_type(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_layer_count, hfi_layer_type = 0;
+	int ret, hfi_id;
+
+	if (!inst->vb2q_dst->streaming) {
+		hfi_layer_type = inst->hfi_layer_type;
+		hfi_id = inst->cap[LAYER_TYPE].hfi_id;
+
+		ret = iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+					    get_port_info(inst, LAYER_TYPE),
+					    HFI_PAYLOAD_U32_ENUM,
+					    &hfi_layer_type, sizeof(u32));
+		if (ret)
+			return ret;
+	} else {
+		if (inst->hfi_layer_type == HFI_HIER_B)
+			return 0;
+	}
+
+	hfi_id = inst->cap[ENH_LAYER_COUNT].hfi_id;
+	hfi_layer_count = inst->cap[ENH_LAYER_COUNT].value + 1;
+
+	ret = iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				    get_port_info(inst, ENH_LAYER_COUNT),
+				    HFI_PAYLOAD_U32,
+				    &hfi_layer_count, sizeof(u32));
+
+	return ret;
+}
+
+int set_slice_count(struct iris_inst *inst, enum plat_inst_cap_type cap_id)
+{
+	u32 hfi_value = 0, set_cap_id = 0, hfi_id;
+	s32 slice_mode = -1;
+
+	slice_mode = inst->cap[SLICE_MODE].value;
+
+	if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE)
+		return 0;
+
+	if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {
+		hfi_value = (inst->codec == HEVC) ?
+			(inst->cap[SLICE_MAX_MB].value + 3) / 4 :
+			inst->cap[SLICE_MAX_MB].value;
+		set_cap_id = SLICE_MAX_MB;
+	} else if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) {
+		hfi_value = inst->cap[SLICE_MAX_BYTES].value;
+		set_cap_id = SLICE_MAX_BYTES;
+	}
+
+	hfi_id = inst->cap[set_cap_id].hfi_id;
+
+	return iris_hfi_set_property(inst, hfi_id, HFI_HOST_FLAGS_NONE,
+				     get_port_info(inst, set_cap_id),
+				     HFI_PAYLOAD_U32,
+				     &hfi_value, sizeof(u32));
+}
+
+int set_v4l2_properties(struct iris_inst *inst)
+{
+	struct cap_entry *entry = NULL, *temp = NULL;
+	int ret = 0;
+
+	list_for_each_entry_safe(entry, temp, &inst->caps_list, list) {
+		ret = set_cap(inst, entry->cap_id);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+int adjust_v4l2_properties(struct iris_inst *inst)
+{
+	struct cap_entry *entry = NULL, *temp = NULL;
+	int ret = 0;
+
+	list_for_each_entry_safe(entry, temp, &inst->caps_list, list) {
+		ret = adjust_cap(inst, entry->cap_id, NULL);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+int adjust_output_order(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	s32 display_delay = -1, display_delay_enable = -1;
+	u32 adjusted_value;
+
+	adjusted_value = ctrl ? ctrl->val :
+		inst->cap[OUTPUT_ORDER].value;
+
+	display_delay = inst->cap[DISPLAY_DELAY].value;
+	display_delay_enable = inst->cap[DISPLAY_DELAY_ENABLE].value;
+
+	if (display_delay_enable && !display_delay)
+		adjusted_value = 1;
+
+	inst->cap[OUTPUT_ORDER].value = adjusted_value;
+
+	return 0;
+}
+
+int adjust_profile(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	u32 adjusted_value;
+	s32 pix_fmt = -1;
+
+	adjusted_value = ctrl ? ctrl->val : inst->cap[PROFILE].value;
+
+	pix_fmt = inst->cap[PIX_FMTS].value;
+
+	if (pix_fmt == FMT_TP10C)
+		adjusted_value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10;
+	else
+		adjusted_value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN;
+
+	inst->cap[PROFILE].value = adjusted_value;
+
+	return 0;
+}
+
+int adjust_bitrate(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	u32 layer_br_caps[6] = {L0_BR, L1_BR, L2_BR, L3_BR, L4_BR, L5_BR};
+	u32 adjusted_value, cumulative_bitrate, cap_id, cap_val, i;
+	s32 layer_count, max_bitrate = 0, entropy_mode;
+
+	adjusted_value = ctrl ? ctrl->val : inst->cap[BIT_RATE].value;
+
+	if (inst->cap[BIT_RATE].flags & CAP_FLAG_CLIENT_SET) {
+		inst->cap[BIT_RATE].value = adjusted_value;
+		return 0;
+	}
+
+	entropy_mode = inst->cap[ENTROPY_MODE].value;
+
+	if (inst->codec == HEVC)
+		max_bitrate = CABAC_MAX_BITRATE;
+
+	if (inst->codec == H264) {
+		if (entropy_mode == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC)
+			max_bitrate = CABAC_MAX_BITRATE;
+		else
+			max_bitrate = CAVLC_MAX_BITRATE;
+	}
+
+	if (inst->cap[BIT_RATE].value > max_bitrate)
+		inst->cap[BIT_RATE].value = max_bitrate;
+
+	layer_count = inst->cap[ENH_LAYER_COUNT].value;
+	if (!layer_count)
+		return 0;
+
+	if (!is_layer_bitrate_set(inst))
+		return 0;
+
+	cumulative_bitrate = get_cumulative_bitrate(inst);
+
+	if (cumulative_bitrate > max_bitrate) {
+		u32 decrement_in_value = 0;
+		u32 decrement_in_percent = ((cumulative_bitrate - max_bitrate) * 100) /
+				max_bitrate;
+
+		cumulative_bitrate = 0;
+		for (i = 0; i <= layer_count; i++) {
+			if (i >= ARRAY_SIZE(layer_br_caps))
+				break;
+			cap_id = layer_br_caps[i];
+			cap_val = inst->cap[cap_id].value;
+			decrement_in_value = (cap_val * decrement_in_percent) / 100;
+			cumulative_bitrate += (cap_val - decrement_in_value);
+			inst->cap[cap_id].value = cap_val - decrement_in_value;
+		}
+		inst->cap[BIT_RATE].value = cumulative_bitrate;
+	}
+
+	return 0;
+}
+
+int adjust_layer_bitrate(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	u32 old_br = 0, new_br = 0, exceeded_br = 0;
+	u32 client_set_cap_id = INST_CAP_NONE;
+	u32 cumulative_bitrate = 0;
+	s32 max_bitrate;
+
+	if (!ctrl)
+		return 0;
+
+	if (inst->cap[BIT_RATE].flags & CAP_FLAG_CLIENT_SET ||
+	    !inst->vb2q_dst->streaming)
+		return 0;
+
+	if (!inst->cap[ENH_LAYER_COUNT].max)
+		return -EINVAL;
+
+	if (!is_layer_bitrate_set(inst))
+		return 0;
+
+	client_set_cap_id = get_cap_id(inst, ctrl->id);
+	if (!is_valid_cap_id(client_set_cap_id))
+		return -EINVAL;
+
+	cumulative_bitrate = get_cumulative_bitrate(inst);
+	max_bitrate = inst->cap[BIT_RATE].max;
+	old_br = inst->cap[client_set_cap_id].value;
+	new_br = ctrl->val;
+
+	if ((cumulative_bitrate - old_br + new_br) > max_bitrate) {
+		exceeded_br = (cumulative_bitrate - old_br + new_br) - max_bitrate;
+		new_br = ctrl->val - exceeded_br;
+	}
+	inst->cap[client_set_cap_id].value = new_br;
+
+	inst->cap[BIT_RATE].value = get_cumulative_bitrate(inst);
+
+	return 0;
+}
+
+int adjust_peak_bitrate(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	u32 adjusted_value;
+	s32 rc_mode, bitrate;
+
+	adjusted_value = ctrl ? ctrl->val : inst->cap[PEAK_BITRATE].value;
+
+	rc_mode = inst->cap[BITRATE_MODE].value;
+
+	if (rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+		return 0;
+
+	bitrate = inst->cap[BIT_RATE].value;
+
+	if (inst->cap[PEAK_BITRATE].flags & CAP_FLAG_CLIENT_SET) {
+		if (adjusted_value < bitrate)
+			adjusted_value = bitrate;
+	} else {
+		adjusted_value = inst->cap[BIT_RATE].value;
+	}
+
+	inst->cap[PEAK_BITRATE].value = adjusted_value;
+
+	return 0;
+}
+
+int adjust_bitrate_mode(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	s32 frame_rc, bitrate_mode, frame_skip;
+
+	bitrate_mode = inst->cap[BITRATE_MODE].value;
+	frame_rc = inst->cap[FRAME_RC_ENABLE].value;
+	frame_skip = inst->cap[FRAME_SKIP_MODE].value;
+
+	if (!frame_rc) {
+		inst->hfi_rc_type = HFI_RC_OFF;
+		return 0;
+	}
+
+	if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) {
+		inst->hfi_rc_type = HFI_RC_VBR_CFR;
+	} else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) {
+		if (frame_skip)
+			inst->hfi_rc_type = HFI_RC_CBR_VFR;
+		else
+			inst->hfi_rc_type = HFI_RC_CBR_CFR;
+	} else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ) {
+		inst->hfi_rc_type = HFI_RC_CQ;
+	} else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_MBR) {
+		inst->hfi_rc_type = HFI_RC_MBR;
+	}
+
+	return 0;
+}
+
+int adjust_gop_size(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	s32 adjusted_value, enh_layer_count;
+	u32 min_gop_size, num_subgops;
+
+	adjusted_value = ctrl ? ctrl->val : inst->cap[GOP_SIZE].value;
+
+	enh_layer_count = inst->cap[ENH_LAYER_COUNT].value;
+
+	if (!enh_layer_count)
+		goto exit;
+
+	/*
+	 * Layer encoding needs GOP size to be multiple of subgop size
+	 * And subgop size is 2 ^ number of enhancement layers.
+	 */
+	min_gop_size = 1 << enh_layer_count;
+	num_subgops = (adjusted_value + (min_gop_size >> 1)) / min_gop_size;
+	if (num_subgops)
+		adjusted_value = num_subgops * min_gop_size;
+	else
+		adjusted_value = min_gop_size;
+
+exit:
+	inst->cap[GOP_SIZE].value = adjusted_value;
+
+	return 0;
+}
+
+int adjust_b_frame(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	s32 adjusted_value, enh_layer_count = -1;
+	const u32 max_bframe_size = inst->cap[B_FRAME].max;
+
+	adjusted_value = ctrl ? ctrl->val : inst->cap[B_FRAME].value;
+
+	enh_layer_count = inst->cap[ENH_LAYER_COUNT].value;
+
+	if (!enh_layer_count || inst->hfi_layer_type != HFI_HIER_B) {
+		adjusted_value = 0;
+		goto exit;
+	}
+
+	adjusted_value = (1 << enh_layer_count) - 1;
+
+	if (adjusted_value > max_bframe_size)
+		adjusted_value = max_bframe_size;
+
+exit:
+	inst->cap[B_FRAME].value = adjusted_value;
+
+	return 0;
+}
+
+int adjust_ltr_count(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	s32 adjusted_value, rc_mode, pix_fmt;
+
+	adjusted_value = ctrl ? ctrl->val : inst->cap[LTR_COUNT].value;
+
+	rc_mode = inst->cap[BITRATE_MODE].value;
+
+	if (rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR &&
+	    inst->hfi_rc_type != HFI_RC_OFF)
+		adjusted_value = 0;
+
+	pix_fmt = inst->cap[PIX_FMTS].value;
+	if (is_10bit_colorformat(pix_fmt))
+		adjusted_value = 0;
+
+	inst->cap[LTR_COUNT].value = adjusted_value;
+
+	return 0;
+}
+
+int adjust_use_ltr(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	s32 adjusted_value, ltr_count;
+
+	adjusted_value = ctrl ? ctrl->val : inst->cap[USE_LTR].value;
+
+	ltr_count = inst->cap[LTR_COUNT].value;
+	if (!ltr_count)
+		return 0;
+
+	/*
+	 * USE_LTR is bitmask value, hence should be
+	 * > 0 and <= (2 ^ LTR_COUNT) - 1
+	 */
+	if (adjusted_value <= 0 ||
+	    adjusted_value > (1 << ltr_count) - 1)
+		return 0;
+
+	inst->cap[USE_LTR].value = adjusted_value;
+
+	return 0;
+}
+
+int adjust_mark_ltr(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	s32 adjusted_value, ltr_count;
+
+	adjusted_value = ctrl ? ctrl->val : inst->cap[MARK_LTR].value;
+
+	ltr_count = inst->cap[LTR_COUNT].value;
+	if (!ltr_count)
+		return 0;
+
+	if (adjusted_value < 0 || adjusted_value > ltr_count - 1)
+		return 0;
+
+	inst->cap[MARK_LTR].value = adjusted_value;
+
+	return 0;
+}
+
+int adjust_ir_period(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	s32 adjusted_value, pix_fmt, rc_mode;
+
+	adjusted_value = ctrl ? ctrl->val : inst->cap[IR_PERIOD].value;
+
+	pix_fmt = inst->cap[PIX_FMTS].value;
+	if (is_10bit_colorformat(pix_fmt))
+		adjusted_value = 0;
+
+	rc_mode = inst->cap[BITRATE_MODE].value;
+	if (rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
+		adjusted_value = 0;
+
+	inst->cap[IR_PERIOD].value = adjusted_value;
+
+	return 0;
+}
+
+int adjust_min_quality(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	s32 adjusted_value, pix_fmt, rc_mode, layer_count;
+	u32 width, height, frame_rate;
+	struct v4l2_format *f;
+
+	if (inst->vb2q_dst->streaming)
+		return 0;
+
+	adjusted_value = MAX_SUPPORTED_MIN_QUALITY;
+
+	rc_mode = inst->cap[BITRATE_MODE].value;
+	if (rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
+		adjusted_value = 0;
+
+	layer_count = inst->cap[ENH_LAYER_COUNT].value;
+	if (layer_count && inst->hfi_layer_type != HFI_HIER_B)
+		adjusted_value = 0;
+
+	pix_fmt = inst->cap[PIX_FMTS].value;
+	if (is_10bit_colorformat(pix_fmt))
+		adjusted_value = 0;
+
+	frame_rate = inst->cap[FRAME_RATE].value >> 16;
+	f = inst->fmt_dst;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	if (!res_is_less_than(width, height, 1920, 1080))
+		adjusted_value = 0;
+
+	if (frame_rate > 60)
+		adjusted_value = 0;
+
+	inst->cap[MIN_QUALITY].value = adjusted_value;
+
+	return 0;
+}
+
+static int adjust_static_layer_count_and_type(struct iris_inst *inst, s32 layer_count)
+{
+	bool hb_requested = false;
+	s32 max_enh_count = 0;
+
+	if (!layer_count)
+		goto exit;
+
+	if (inst->hfi_rc_type == HFI_RC_CQ) {
+		layer_count = 0;
+		goto exit;
+	}
+
+	if (inst->codec == H264) {
+		if (!inst->cap[LAYER_ENABLE].value) {
+			layer_count = 0;
+			goto exit;
+		}
+		hb_requested = inst->cap[LAYER_TYPE].value ==
+				V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B;
+	} else if (inst->codec == HEVC) {
+		hb_requested = inst->cap[LAYER_TYPE].value ==
+				V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B;
+	}
+
+	if (hb_requested && inst->hfi_rc_type != HFI_RC_VBR_CFR) {
+		layer_count = 0;
+		goto exit;
+	}
+
+	inst->hfi_layer_type = hb_requested ? HFI_HIER_B :
+		(inst->codec == H264 && inst->hfi_rc_type == HFI_RC_VBR_CFR) ?
+		HFI_HIER_P_HYBRID_LTR : HFI_HIER_P_SLIDING_WINDOW;
+
+	max_enh_count = inst->hfi_layer_type == HFI_HIER_B ? MAX_ENH_LAYER_HB :
+		inst->hfi_layer_type == HFI_HIER_P_HYBRID_LTR ? MAX_AVC_ENH_LAYER_HYBRID_HP :
+		inst->hfi_layer_type == HFI_HIER_P_SLIDING_WINDOW ?
+		(inst->codec == H264 ? MAX_AVC_ENH_LAYER_SLIDING_WINDOW :
+		 (inst->codec == HEVC && inst->hfi_rc_type == HFI_RC_VBR_CFR) ?
+		 MAX_HEVC_VBR_ENH_LAYER_SLIDING_WINDOW :
+		 MAX_HEVC_NON_VBR_ENH_LAYER_SLIDING_WINDOW) :
+		layer_count;
+
+	layer_count = min(layer_count, max_enh_count);
+
+exit:
+	inst->cap[ENH_LAYER_COUNT].value = layer_count;
+	inst->cap[ENH_LAYER_COUNT].max = layer_count;
+
+	return 0;
+}
+
+int adjust_layer_count(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	s32 client_layer_count;
+	int ret = 0;
+
+	client_layer_count = ctrl ? ctrl->val : inst->cap[ENH_LAYER_COUNT].value;
+
+	if (!inst->vb2q_dst->streaming) {
+		ret = adjust_static_layer_count_and_type(inst, client_layer_count);
+		if (ret)
+			return ret;
+	} else {
+		if (inst->hfi_rc_type == HFI_RC_CBR_CFR ||
+		    inst->hfi_rc_type == HFI_RC_CBR_VFR)
+			return ret;
+
+		if (inst->hfi_layer_type == HFI_HIER_P_HYBRID_LTR ||
+		    inst->hfi_layer_type == HFI_HIER_P_SLIDING_WINDOW)
+			inst->cap[ENH_LAYER_COUNT].value =
+				min(client_layer_count, inst->cap[ENH_LAYER_COUNT].max);
+	}
+
+	return ret;
+}
+
+int adjust_entropy_mode(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	s32 adjusted_value;
+	s32 profile = -1;
+
+	adjusted_value = ctrl ? ctrl->val : inst->cap[ENTROPY_MODE].value;
+
+	profile = inst->cap[PROFILE].value;
+	if (profile == V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE ||
+	    profile == V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE)
+		adjusted_value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
+
+	inst->cap[ENTROPY_MODE].value = adjusted_value;
+
+	return 0;
+}
+
+int adjust_slice_count(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	s32 adjusted_value, rc_type = -1, slice_mode, enh_layer_count = 0;
+	u32 slice_val, mbpf = 0, mbps = 0, max_mbpf = 0, max_mbps = 0, bitrate = 0;
+	u32 update_cap, max_avg_slicesize, output_width, output_height;
+	u32 min_width, min_height, max_width, max_height, fps;
+
+	slice_mode = ctrl ? ctrl->val : inst->cap[SLICE_MODE].value;
+	if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE)
+		return 0;
+
+	bitrate = inst->cap[BIT_RATE].value;
+	enh_layer_count = inst->cap[ENH_LAYER_COUNT].value;
+	if (enh_layer_count && is_layer_bitrate_set(inst))
+		bitrate = get_cumulative_bitrate(inst);
+
+	rc_type = inst->hfi_rc_type;
+	fps = inst->cap[FRAME_RATE].value >> 16;
+	if (fps > MAX_SLICES_FRAME_RATE ||
+	    (rc_type != HFI_RC_OFF && rc_type != HFI_RC_CBR_CFR &&
+	     rc_type != HFI_RC_CBR_VFR)) {
+		adjusted_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
+		update_cap = SLICE_MODE;
+		goto exit;
+	}
+
+	output_width = inst->fmt_dst->fmt.pix_mp.width;
+	output_height = inst->fmt_dst->fmt.pix_mp.height;
+
+	max_width = (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) ?
+		MAX_MB_SLICE_WIDTH : MAX_BYTES_SLICE_WIDTH;
+	max_height = (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) ?
+		MAX_MB_SLICE_HEIGHT : MAX_BYTES_SLICE_HEIGHT;
+	min_width = (inst->codec == HEVC) ?
+		MIN_HEVC_SLICE_WIDTH : MIN_AVC_SLICE_WIDTH;
+	min_height = MIN_SLICE_HEIGHT;
+
+	if (output_width < min_width || output_height < min_height ||
+	    output_width > max_width || output_height > max_width) {
+		adjusted_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
+		update_cap = SLICE_MODE;
+		goto exit;
+	}
+
+	mbpf = NUM_MBS_PER_FRAME(output_height, output_width);
+	mbps = mbpf * fps;
+	max_mbpf = NUM_MBS_PER_FRAME(max_height, max_width);
+	max_mbps = max_mbpf * MAX_SLICES_FRAME_RATE;
+
+	if (mbpf > max_mbpf || mbps > max_mbps) {
+		adjusted_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
+		update_cap = SLICE_MODE;
+		goto exit;
+	}
+
+	if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {
+		update_cap = SLICE_MAX_MB;
+		slice_val = inst->cap[SLICE_MAX_MB].value;
+		slice_val = max(slice_val, mbpf / MAX_SLICES_PER_FRAME);
+	} else {
+		slice_val = inst->cap[SLICE_MAX_BYTES].value;
+		update_cap = SLICE_MAX_BYTES;
+		if (rc_type != HFI_RC_OFF) {
+			max_avg_slicesize =
+				((bitrate / fps) / 8) / MAX_SLICES_PER_FRAME;
+			slice_val = max(slice_val, max_avg_slicesize);
+		}
+	}
+	adjusted_value = slice_val;
+
+exit:
+	inst->cap[update_cap].value = adjusted_value;
+
+	return 0;
+}
+
+int adjust_transform_8x8(struct iris_inst *inst, struct v4l2_ctrl *ctrl)
+{
+	s32 adjusted_value;
+	s32 profile = -1;
+
+	adjusted_value = ctrl ? ctrl->val : inst->cap[TRANSFORM_8X8].value;
+
+	profile = inst->cap[PROFILE].value;
+	if (profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH &&
+	    profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH)
+		adjusted_value = 0;
+
+	inst->cap[TRANSFORM_8X8].value = adjusted_value;
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_ctrls.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_ctrls.h
@@ -0,0 +1,72 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_CTRLS_H_
+#define _IRIS_CTRLS_H_
+
+#include "iris_instance.h"
+
+struct cap_entry {
+	struct list_head list;
+	enum plat_inst_cap_type cap_id;
+};
+
+struct ctrl_data {
+	bool skip_s_ctrl;
+};
+
+int set_u32_enum(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_stage(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_pipe(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_u32(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int adjust_output_order(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_profile(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int vidc_ctrl_handler_deinit(struct iris_inst *inst);
+int prepare_dependency_list(struct iris_inst *inst);
+int iris_init_instance_caps(struct iris_core *core);
+int iris_init_core_caps(struct iris_core *core);
+int get_inst_capability(struct iris_inst *inst);
+int set_v4l2_properties(struct iris_inst *inst);
+int adjust_v4l2_properties(struct iris_inst *inst);
+int ctrls_init(struct iris_inst *inst, bool init);
+int set_q16(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_level(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int decide_quality_mode(struct iris_inst *inst);
+int set_req_sync_frame(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_flip(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_rotation(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_header_mode(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_gop_size(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_bitrate(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_layer_bitrate(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_peak_bitrate(struct iris_inst *inst,
+		     enum plat_inst_cap_type cap_id);
+int set_bitrate_mode(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_use_and_mark_ltr(struct iris_inst *inst,
+			 enum plat_inst_cap_type cap_id);
+int set_ir_period(struct iris_inst *inst,
+		  enum plat_inst_cap_type cap_id);
+int set_min_qp(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_max_qp(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_frame_qp(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_layer_count_and_type(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int set_slice_count(struct iris_inst *inst, enum plat_inst_cap_type cap_id);
+int adjust_bitrate(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_layer_bitrate(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_peak_bitrate(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_bitrate_mode(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_gop_size(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_b_frame(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_ltr_count(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_use_ltr(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_mark_ltr(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_ir_period(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_min_quality(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_layer_count(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_entropy_mode(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_slice_count(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+int adjust_transform_8x8(struct iris_inst *inst, struct v4l2_ctrl *ctrl);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_helpers.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_helpers.c
@@ -0,0 +1,1153 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/pm_runtime.h>
+
+#include "hfi_defines.h"
+#include "iris_core.h"
+#include "iris_ctrls.h"
+#include "iris_helpers.h"
+#include "iris_hfi.h"
+#include "iris_hfi_packet.h"
+#include "iris_instance.h"
+#include "iris_power.h"
+#include "iris_vidc.h"
+#include "memory.h"
+
+int check_core_lock(struct iris_core *core)
+{
+	bool fatal = !mutex_is_locked(&core->lock);
+
+	WARN_ON(fatal);
+
+	return fatal ? -EINVAL : 0;
+}
+
+bool res_is_less_than(u32 width, u32 height,
+		      u32 ref_width, u32 ref_height)
+{
+	u32 num_mbs = NUM_MBS_PER_FRAME(height, width);
+	u32 max_side = max(ref_width, ref_height);
+
+	if (num_mbs < NUM_MBS_PER_FRAME(ref_height, ref_width) &&
+	    width < max_side &&
+	    height < max_side)
+		return true;
+
+	return false;
+}
+
+u32 get_port_info(struct iris_inst *inst,
+		  enum plat_inst_cap_type cap_id)
+{
+	if (inst->cap[cap_id].flags & CAP_FLAG_INPUT_PORT &&
+	    inst->cap[cap_id].flags & CAP_FLAG_OUTPUT_PORT) {
+		if (inst->vb2q_dst->streaming)
+			return get_hfi_port(inst, INPUT_MPLANE);
+		else
+			return get_hfi_port(inst, OUTPUT_MPLANE);
+	}
+
+	if (inst->cap[cap_id].flags & CAP_FLAG_INPUT_PORT)
+		return get_hfi_port(inst, INPUT_MPLANE);
+	else if (inst->cap[cap_id].flags & CAP_FLAG_OUTPUT_PORT)
+		return get_hfi_port(inst, OUTPUT_MPLANE);
+	else
+		return HFI_PORT_NONE;
+}
+
+enum iris_buffer_type v4l2_type_to_driver(u32 type)
+{
+	switch (type) {
+	case INPUT_MPLANE:
+		return BUF_INPUT;
+	case OUTPUT_MPLANE:
+		return BUF_OUTPUT;
+	default:
+		return 0;
+	}
+}
+
+u32 v4l2_type_from_driver(enum iris_buffer_type buffer_type)
+{
+	switch (buffer_type) {
+	case BUF_INPUT:
+		return INPUT_MPLANE;
+	case BUF_OUTPUT:
+		return OUTPUT_MPLANE;
+	default:
+		return 0;
+	}
+}
+
+void v4l2_to_hfi_enum(struct iris_inst *inst,
+		      enum plat_inst_cap_type cap_id, u32 *value)
+{
+	switch (cap_id) {
+	case ROTATION:
+		switch (inst->cap[cap_id].value) {
+		case 0:
+			*value = HFI_ROTATION_NONE;
+			break;
+		case 90:
+			*value = HFI_ROTATION_90;
+			break;
+		case 180:
+			*value = HFI_ROTATION_180;
+			break;
+		case 270:
+			*value = HFI_ROTATION_270;
+			break;
+		default:
+			*value = HFI_ROTATION_NONE;
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+int get_mbpf(struct iris_inst *inst)
+{
+	int height = 0, width = 0;
+	struct v4l2_format *inp_f;
+
+	if (inst->domain == DECODER) {
+		inp_f = inst->fmt_src;
+		width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
+		height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
+	} else if (inst->domain == ENCODER) {
+		width = inst->crop.width;
+		height = inst->crop.height;
+	}
+
+	return NUM_MBS_PER_FRAME(height, width);
+}
+
+inline bool is_linear_colorformat(u32 colorformat)
+{
+	return colorformat == V4L2_PIX_FMT_NV12;
+}
+
+bool is_split_mode_enabled(struct iris_inst *inst)
+{
+	if (inst->domain != DECODER)
+		return false;
+
+	if (is_linear_colorformat(inst->fmt_dst->fmt.pix_mp.pixelformat))
+		return true;
+
+	return false;
+}
+
+inline bool is_10bit_colorformat(enum colorformat_type colorformat)
+{
+	return colorformat == FMT_TP10C;
+}
+
+inline bool is_8bit_colorformat(enum colorformat_type colorformat)
+{
+	return colorformat == FMT_NV12 ||
+		colorformat == FMT_NV12C;
+}
+
+inline bool is_scaling_enabled(struct iris_inst *inst)
+{
+	return inst->crop.left != inst->compose.left ||
+		inst->crop.top != inst->compose.top ||
+		inst->crop.width != inst->compose.width ||
+		inst->crop.height != inst->compose.height;
+}
+
+inline bool is_hierb_type_requested(struct iris_inst *inst)
+{
+	return (inst->codec == H264 &&
+		inst->cap[LAYER_TYPE].value ==
+				V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B) ||
+		(inst->codec == HEVC &&
+		inst->cap[LAYER_TYPE].value ==
+				V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B);
+}
+
+u32 v4l2_codec_from_driver(struct iris_inst *inst, enum codec_type codec)
+{
+	const struct codec_info *codec_info;
+	struct iris_core *core;
+	u32 v4l2_codec = 0;
+	u32 i, size;
+
+	core = inst->core;
+	codec_info = core->platform_data->format_data->codec_info;
+	size = core->platform_data->format_data->codec_info_size;
+
+	for (i = 0; i < size; i++) {
+		if (codec_info[i].codec == codec)
+			return codec_info[i].v4l2_codec;
+	}
+
+	return v4l2_codec;
+}
+
+enum codec_type v4l2_codec_to_driver(struct iris_inst *inst, u32 v4l2_codec)
+{
+	const struct codec_info *codec_info;
+	enum codec_type codec = 0;
+	struct iris_core *core;
+	u32 i, size;
+
+	core = inst->core;
+	codec_info = core->platform_data->format_data->codec_info;
+	size = core->platform_data->format_data->codec_info_size;
+
+	for (i = 0; i < size; i++) {
+		if (codec_info[i].v4l2_codec == v4l2_codec)
+			return codec_info[i].codec;
+	}
+
+	return codec;
+}
+
+u32 v4l2_colorformat_from_driver(struct iris_inst *inst, enum colorformat_type colorformat)
+{
+	const struct color_format_info *color_format_info;
+	u32 v4l2_colorformat = 0;
+	struct iris_core *core;
+	u32 i, size;
+
+	core = inst->core;
+	color_format_info = core->platform_data->format_data->color_format_info;
+	size = core->platform_data->format_data->color_format_info_size;
+
+	for (i = 0; i < size; i++) {
+		if (color_format_info[i].color_format == colorformat)
+			return color_format_info[i].v4l2_color_format;
+	}
+
+	return v4l2_colorformat;
+}
+
+enum colorformat_type v4l2_colorformat_to_driver(struct iris_inst *inst, u32 v4l2_colorformat)
+{
+	const struct color_format_info *color_format_info;
+	enum colorformat_type colorformat = 0;
+	struct iris_core *core;
+	u32 i, size;
+
+	core = inst->core;
+	color_format_info = core->platform_data->format_data->color_format_info;
+	size = core->platform_data->format_data->color_format_info_size;
+
+	for (i = 0; i < size; i++) {
+		if (color_format_info[i].v4l2_color_format == v4l2_colorformat)
+			return color_format_info[i].color_format;
+	}
+
+	return colorformat;
+}
+
+struct vb2_queue *get_vb2q(struct iris_inst *inst, u32 type)
+{
+	struct vb2_queue *vb2q = NULL;
+
+	switch (type) {
+	case INPUT_MPLANE:
+		vb2q = inst->vb2q_src;
+		break;
+	case OUTPUT_MPLANE:
+		vb2q = inst->vb2q_dst;
+		break;
+	default:
+		return NULL;
+	}
+
+	return vb2q;
+}
+
+static int process_inst_timeout(struct iris_inst *inst)
+{
+	struct iris_inst *instance;
+	struct iris_core *core;
+	bool found = false;
+	int ret = 0;
+
+	core = inst->core;
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(instance, &core->instances, list) {
+		if (instance == inst) {
+			found = true;
+			break;
+		}
+	}
+	if (!found) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	iris_change_core_state(core, IRIS_CORE_ERROR);
+
+	iris_core_deinit_locked(core);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int close_session(struct iris_inst *inst)
+{
+	u32 hw_response_timeout_val;
+	bool wait_for_response;
+	struct iris_core *core;
+	int ret;
+
+	core = inst->core;
+	hw_response_timeout_val = core->cap[HW_RESPONSE_TIMEOUT].value;
+	wait_for_response = true;
+	ret = iris_hfi_session_close(inst);
+	if (ret)
+		wait_for_response = false;
+
+	kfree(inst->packet);
+	inst->packet = NULL;
+
+	if (wait_for_response) {
+		mutex_unlock(&inst->lock);
+		ret = wait_for_completion_timeout(&inst->completions[SIGNAL_CMD_CLOSE],
+						  msecs_to_jiffies(hw_response_timeout_val));
+		if (!ret) {
+			ret = -ETIMEDOUT;
+			process_inst_timeout(inst);
+		}
+		mutex_lock(&inst->lock);
+	}
+
+	return ret;
+}
+
+int check_core_mbps_mbpf(struct iris_inst *inst)
+{
+	u32 mbpf = 0, mbps = 0, total_mbpf = 0, total_mbps = 0;
+	struct iris_core *core;
+	struct iris_inst *instance;
+	u32 fps;
+
+	core = inst->core;
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(instance, &core->instances, list) {
+		fps = max3(inst->cap[QUEUED_RATE].value >> 16,
+			   inst->cap[FRAME_RATE].value >> 16,
+			   inst->cap[OPERATING_RATE].value >> 16);
+		mbpf = get_mbpf(inst);
+		mbps = mbpf * fps;
+		total_mbpf += mbpf;
+		total_mbps += mbps;
+	}
+	mutex_unlock(&core->lock);
+
+	if (total_mbps > core->cap[MAX_MBPS].value ||
+	    total_mbpf > core->cap[MAX_MBPF].value)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int check_inst_mbpf(struct iris_inst *inst)
+{
+	u32 mbpf = 0, max_mbpf = 0;
+
+	max_mbpf = inst->cap[MBPF].max;
+	mbpf = get_mbpf(inst);
+	if (mbpf > max_mbpf)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int check_resolution_supported(struct iris_inst *inst)
+{
+	u32 width = 0, height = 0, min_width, min_height,
+		max_width, max_height;
+
+	if (inst->domain == DECODER) {
+		width = inst->fmt_src->fmt.pix_mp.width;
+		height = inst->fmt_src->fmt.pix_mp.height;
+	} else if (inst->domain == ENCODER) {
+		width = inst->crop.width;
+		height = inst->crop.height;
+	}
+
+	min_width = inst->cap[FRAME_WIDTH].min;
+	max_width = inst->cap[FRAME_WIDTH].max;
+	min_height = inst->cap[FRAME_HEIGHT].min;
+	max_height = inst->cap[FRAME_HEIGHT].max;
+
+	if (inst->domain == DECODER || inst->domain == ENCODER) {
+		if (!(min_width <= width && width <= max_width) ||
+		    !(min_height <= height && height <= max_height))
+			return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int check_max_sessions(struct iris_inst *inst)
+{
+	struct iris_core *core;
+	u32 num_sessions = 0;
+	struct iris_inst *i;
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+	list_for_each_entry(i, &core->instances, list) {
+		num_sessions++;
+	}
+	mutex_unlock(&core->lock);
+
+	if (num_sessions > core->cap[MAX_SESSION_COUNT].value)
+		return -ENOMEM;
+
+	return 0;
+}
+
+int check_session_supported(struct iris_inst *inst)
+{
+	int ret;
+
+	ret = check_core_mbps_mbpf(inst);
+	if (ret)
+		goto exit;
+
+	ret = check_inst_mbpf(inst);
+	if (ret)
+		goto exit;
+
+	ret = check_resolution_supported(inst);
+	if (ret)
+		goto exit;
+
+	ret = check_max_sessions(inst);
+	if (ret)
+		goto exit;
+
+	return ret;
+exit:
+	dev_err(inst->core->dev, "current session not supported(%d)\n", ret);
+
+	return ret;
+}
+
+int signal_session_msg_receipt(struct iris_inst *inst,
+			       enum signal_session_response cmd)
+{
+	if (cmd < MAX_SIGNAL)
+		complete(&inst->completions[cmd]);
+
+	return 0;
+}
+
+struct iris_inst *to_instance(struct iris_core *core, u32 session_id)
+{
+	struct iris_inst *inst = NULL;
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(inst, &core->instances, list) {
+		if (inst->session_id == session_id) {
+			mutex_unlock(&core->lock);
+			return inst;
+		}
+	}
+	mutex_unlock(&core->lock);
+
+	return NULL;
+}
+
+static int kill_session(struct iris_inst *inst)
+{
+	if (!inst->session_id)
+		return 0;
+
+	close_session(inst);
+	iris_inst_change_state(inst, IRIS_INST_ERROR);
+
+	return 0;
+}
+
+struct iris_buffer *get_driver_buf(struct iris_inst *inst, u32 plane, u32 index)
+{
+	struct iris_buffer *iter = NULL;
+	struct iris_buffer *buf = NULL;
+	enum iris_buffer_type buf_type;
+	struct iris_buffers *buffers;
+
+	bool found = false;
+
+	buf_type = v4l2_type_to_driver(plane);
+	if (!buf_type)
+		return NULL;
+
+	buffers = iris_get_buffer_list(inst, buf_type);
+	if (!buffers)
+		return NULL;
+
+	list_for_each_entry(iter, &buffers->list, list) {
+		if (iter->index == index) {
+			found = true;
+			buf = iter;
+			break;
+		}
+	}
+
+	if (!found)
+		return NULL;
+
+	return buf;
+}
+
+static void process_requeued_readonly_buffers(struct iris_inst *inst,
+					      struct iris_buffer *buf)
+{
+	struct iris_buffer *ro_buf, *dummy;
+
+	list_for_each_entry_safe(ro_buf, dummy, &inst->buffers.read_only.list, list) {
+		if (ro_buf->device_addr != buf->device_addr)
+			continue;
+		if (ro_buf->attr & BUF_ATTR_READ_ONLY &&
+		    !(ro_buf->attr & BUF_ATTR_PENDING_RELEASE)) {
+			buf->attr |= BUF_ATTR_READ_ONLY;
+
+			list_del_init(&ro_buf->list);
+			iris_return_buffer_to_pool(inst, ro_buf);
+			break;
+		}
+	}
+}
+
+int queue_buffer(struct iris_inst *inst, struct iris_buffer *buf)
+{
+	int ret;
+
+	if (inst->domain == DECODER && buf->type == BUF_OUTPUT)
+		process_requeued_readonly_buffers(inst, buf);
+
+	ret = iris_hfi_queue_buffer(inst, buf);
+	if (ret)
+		return ret;
+
+	buf->attr &= ~BUF_ATTR_DEFERRED;
+	buf->attr |= BUF_ATTR_QUEUED;
+
+	return ret;
+}
+
+int queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buf_type)
+{
+	struct iris_buffers *buffers;
+	struct iris_buffer *buf;
+	int ret = 0;
+
+	buffers = iris_get_buffer_list(inst, buf_type);
+	if (!buffers)
+		return -EINVAL;
+
+	iris_scale_power(inst);
+
+	list_for_each_entry(buf, &buffers->list, list) {
+		if (!(buf->attr & BUF_ATTR_DEFERRED))
+			continue;
+		ret = queue_buffer(inst, buf);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+int iris_release_nonref_buffers(struct iris_inst *inst)
+{
+	u32 fw_ro_count = 0, nonref_ro_count = 0;
+	struct iris_buffer *ro_buf;
+	bool found = false;
+	int ret = 0;
+	int i = 0;
+
+	list_for_each_entry(ro_buf, &inst->buffers.read_only.list, list) {
+		if (!(ro_buf->attr & BUF_ATTR_READ_ONLY))
+			continue;
+		if (ro_buf->attr & BUF_ATTR_PENDING_RELEASE)
+			continue;
+		fw_ro_count++;
+	}
+
+	if (fw_ro_count <= MAX_DPB_COUNT)
+		return 0;
+
+	/*
+	 * Mark the read only buffers present in read_only list as
+	 * non-reference if it's not part of dpb_list_payload.
+	 * dpb_list_payload details:
+	 * payload[0-1]           : 64 bits base_address of DPB-1
+	 * payload[2]             : 32 bits addr_offset  of DPB-1
+	 * payload[3]             : 32 bits data_offset  of DPB-1
+	 */
+	list_for_each_entry(ro_buf, &inst->buffers.read_only.list, list) {
+		found = false;
+		if (!(ro_buf->attr & BUF_ATTR_READ_ONLY))
+			continue;
+		if (ro_buf->attr & BUF_ATTR_PENDING_RELEASE)
+			continue;
+		for (i = 0; (i + 3) < MAX_DPB_LIST_ARRAY_SIZE; i = i + 4) {
+			if (ro_buf->device_addr == inst->dpb_list_payload[i] &&
+			    ro_buf->data_offset == inst->dpb_list_payload[i + 3]) {
+				found = true;
+				break;
+			}
+		}
+		if (!found)
+			nonref_ro_count++;
+	}
+
+	if (nonref_ro_count <= inst->buffers.output.min_count)
+		return 0;
+
+	list_for_each_entry(ro_buf, &inst->buffers.read_only.list, list) {
+		found = false;
+		if (!(ro_buf->attr & BUF_ATTR_READ_ONLY))
+			continue;
+		if (ro_buf->attr & BUF_ATTR_PENDING_RELEASE)
+			continue;
+		for (i = 0; (i + 3) < MAX_DPB_LIST_ARRAY_SIZE; i = i + 4) {
+			if (ro_buf->device_addr == inst->dpb_list_payload[i] &&
+			    ro_buf->data_offset == inst->dpb_list_payload[i + 3]) {
+				found = true;
+				break;
+			}
+		}
+		if (!found) {
+			ro_buf->attr |= BUF_ATTR_PENDING_RELEASE;
+			ret = iris_hfi_release_buffer(inst, ro_buf);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+int iris_vb2_buffer_done(struct iris_inst *inst,
+			 struct iris_buffer *buf)
+{
+	struct vb2_v4l2_buffer *vbuf;
+	struct vb2_queue *q = NULL;
+	struct vb2_buffer *iter;
+	struct vb2_buffer *vb2;
+	int type, state;
+	bool found;
+
+	type = v4l2_type_from_driver(buf->type);
+	if (!type)
+		return -EINVAL;
+
+	if (type == INPUT_MPLANE)
+		q = inst->vb2q_src;
+	else if (type == OUTPUT_MPLANE)
+		q = inst->vb2q_dst;
+	if (!q || !q->streaming)
+		return -EINVAL;
+
+	found = false;
+	list_for_each_entry(iter, &q->queued_list, queued_entry) {
+		if (iter->state != VB2_BUF_STATE_ACTIVE)
+			continue;
+		if (iter->index == buf->index) {
+			found = true;
+			vb2 = iter;
+			break;
+		}
+	}
+	if (!found)
+		return -EINVAL;
+
+	if (buf->flags & BUF_FLAG_ERROR)
+		state = VB2_BUF_STATE_ERROR;
+	else
+		state = VB2_BUF_STATE_DONE;
+
+	vbuf = to_vb2_v4l2_buffer(vb2);
+	vbuf->flags = buf->flags;
+	vb2->timestamp = buf->timestamp;
+	vb2->planes[0].bytesused = buf->data_size + vb2->planes[0].data_offset;
+	vb2_buffer_done(vb2, state);
+
+	return 0;
+}
+
+static int iris_flush_deferred_buffers(struct iris_inst *inst,
+				       enum iris_buffer_type type)
+{
+	struct iris_buffer *buf, *dummy;
+	struct iris_buffers *buffers;
+
+	buffers = iris_get_buffer_list(inst, type);
+	if (!buffers)
+		return -EINVAL;
+
+	list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
+		if (buf->attr & BUF_ATTR_DEFERRED) {
+			if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
+				buf->attr |= BUF_ATTR_BUFFER_DONE;
+				buf->data_size = 0;
+				iris_vb2_buffer_done(inst, buf);
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int iris_flush_read_only_buffers(struct iris_inst *inst,
+					enum iris_buffer_type type)
+{
+	struct iris_buffer *ro_buf, *dummy;
+
+	if (inst->domain != DECODER || type != BUF_OUTPUT)
+		return 0;
+
+	list_for_each_entry_safe(ro_buf, dummy, &inst->buffers.read_only.list, list) {
+		if (ro_buf->attr & BUF_ATTR_READ_ONLY)
+			continue;
+		if (ro_buf->attach && ro_buf->sg_table)
+			dma_buf_unmap_attachment(ro_buf->attach, ro_buf->sg_table,
+						 DMA_BIDIRECTIONAL);
+		if (ro_buf->attach && ro_buf->dmabuf)
+			dma_buf_detach(ro_buf->dmabuf, ro_buf->attach);
+		ro_buf->attach = NULL;
+		ro_buf->sg_table = NULL;
+		ro_buf->dmabuf = NULL;
+		ro_buf->device_addr = 0x0;
+		list_del_init(&ro_buf->list);
+		iris_return_buffer_to_pool(inst, ro_buf);
+	}
+
+	return 0;
+}
+
+void iris_destroy_buffers(struct iris_inst *inst)
+{
+	struct iris_buffer *buf, *dummy;
+	struct iris_buffers *buffers;
+
+	static const enum iris_buffer_type ext_buf_types[] = {
+		BUF_INPUT,
+		BUF_OUTPUT,
+	};
+	static const enum iris_buffer_type internal_buf_types[] = {
+		BUF_BIN,
+		BUF_COMV,
+		BUF_NON_COMV,
+		BUF_LINE,
+		BUF_DPB,
+		BUF_PERSIST,
+	};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(internal_buf_types); i++) {
+		buffers = iris_get_buffer_list(inst, internal_buf_types[i]);
+		if (!buffers)
+			continue;
+		list_for_each_entry_safe(buf, dummy, &buffers->list, list)
+			iris_destroy_internal_buffer(inst, buf);
+	}
+
+	list_for_each_entry_safe(buf, dummy, &inst->buffers.read_only.list, list) {
+		if (buf->attach && buf->sg_table)
+			dma_buf_unmap_attachment(buf->attach, buf->sg_table, DMA_BIDIRECTIONAL);
+		if (buf->attach && buf->dmabuf)
+			dma_buf_detach(buf->dmabuf, buf->attach);
+		list_del_init(&buf->list);
+		iris_return_buffer_to_pool(inst, buf);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(ext_buf_types); i++) {
+		buffers = iris_get_buffer_list(inst, ext_buf_types[i]);
+		if (!buffers)
+			continue;
+		list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
+			if (buf->attach && buf->sg_table)
+				dma_buf_unmap_attachment(buf->attach, buf->sg_table,
+							 DMA_BIDIRECTIONAL);
+			if (buf->attach && buf->dmabuf)
+				dma_buf_detach(buf->dmabuf, buf->attach);
+			list_del_init(&buf->list);
+			iris_return_buffer_to_pool(inst, buf);
+		}
+	}
+
+	iris_mem_pool_deinit(inst);
+}
+
+static int get_num_queued_buffers(struct iris_inst *inst,
+				  enum iris_buffer_type type)
+{
+	struct iris_buffers *buffers;
+	struct iris_buffer *vbuf;
+	int count = 0;
+
+	if (type == BUF_INPUT)
+		buffers = &inst->buffers.input;
+	else if (type == BUF_OUTPUT)
+		buffers = &inst->buffers.output;
+	else
+		return count;
+
+	list_for_each_entry(vbuf, &buffers->list, list) {
+		if (vbuf->type != type)
+			continue;
+		if (!(vbuf->attr & BUF_ATTR_QUEUED))
+			continue;
+		count++;
+	}
+
+	return count;
+}
+
+int session_streamoff(struct iris_inst *inst, u32 plane)
+{
+	enum signal_session_response signal_type;
+	enum iris_buffer_type buffer_type;
+	u32 hw_response_timeout_val;
+	struct iris_core *core;
+	int count = 0;
+	int ret;
+
+	if (plane == INPUT_MPLANE) {
+		signal_type = SIGNAL_CMD_STOP_INPUT;
+		buffer_type = BUF_INPUT;
+	} else if (plane == OUTPUT_MPLANE) {
+		signal_type = SIGNAL_CMD_STOP_OUTPUT;
+		buffer_type = BUF_OUTPUT;
+	} else {
+		return -EINVAL;
+	}
+
+	ret = iris_hfi_stop(inst, plane);
+	if (ret)
+		goto error;
+
+	core = inst->core;
+	hw_response_timeout_val = core->cap[HW_RESPONSE_TIMEOUT].value;
+	mutex_unlock(&inst->lock);
+	ret = wait_for_completion_timeout(&inst->completions[signal_type],
+					  msecs_to_jiffies(hw_response_timeout_val));
+	if (!ret) {
+		ret = -ETIMEDOUT;
+		process_inst_timeout(inst);
+	} else {
+		ret = 0;
+	}
+	mutex_lock(&inst->lock);
+
+	if (ret)
+		goto error;
+
+	if (plane == INPUT_MPLANE)
+		iris_flush_input_timer(inst);
+
+	/* no more queued buffers after streamoff */
+	count = get_num_queued_buffers(inst, buffer_type);
+	if (count) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = iris_inst_state_change_streamoff(inst, plane);
+	if (ret)
+		goto error;
+
+	iris_flush_deferred_buffers(inst, buffer_type);
+	iris_flush_read_only_buffers(inst, buffer_type);
+	return 0;
+
+error:
+	kill_session(inst);
+	iris_flush_deferred_buffers(inst, buffer_type);
+	iris_flush_read_only_buffers(inst, buffer_type);
+
+	return ret;
+}
+
+int process_resume(struct iris_inst *inst)
+{
+	enum iris_inst_sub_state clear_sub_state = IRIS_INST_SUB_NONE;
+	int ret;
+
+	if (inst->sub_state & IRIS_INST_SUB_DRC &&
+	    inst->sub_state & IRIS_INST_SUB_DRC_LAST) {
+		clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST;
+
+		if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
+			ret = iris_hfi_resume(inst, INPUT_MPLANE, HFI_CMD_SETTINGS_CHANGE);
+			if (ret)
+				return ret;
+			clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
+		}
+		if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) {
+			ret = iris_hfi_resume(inst, OUTPUT_MPLANE, HFI_CMD_SETTINGS_CHANGE);
+			if (ret)
+				return ret;
+			clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
+		}
+	} else if (inst->sub_state & IRIS_INST_SUB_DRAIN &&
+		   inst->sub_state & IRIS_INST_SUB_DRAIN_LAST) {
+		clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST;
+		if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
+			ret = iris_hfi_resume(inst, INPUT_MPLANE, HFI_CMD_DRAIN);
+			if (ret)
+				return ret;
+			clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
+		}
+		if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE) {
+			ret = iris_hfi_resume(inst, OUTPUT_MPLANE, HFI_CMD_DRAIN);
+			if (ret)
+				return ret;
+			clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
+		}
+	}
+
+	ret = iris_inst_change_sub_state(inst, clear_sub_state, 0);
+
+	return ret;
+}
+
+int codec_change(struct iris_inst *inst, u32 v4l2_codec)
+{
+	bool session_init = false;
+	int ret;
+
+	if (!inst->codec)
+		session_init = true;
+
+	if (inst->codec &&
+	    ((inst->domain == DECODER && inst->fmt_src->fmt.pix_mp.pixelformat == v4l2_codec) ||
+	     (inst->domain == ENCODER && inst->fmt_dst->fmt.pix_mp.pixelformat == v4l2_codec)))
+		return 0;
+
+	inst->codec = v4l2_codec_to_driver(inst, v4l2_codec);
+	if (!inst->codec)
+		return -EINVAL;
+
+	if (inst->domain == DECODER)
+		inst->fmt_src->fmt.pix_mp.pixelformat = v4l2_codec;
+	else if (inst->domain == ENCODER)
+		inst->fmt_dst->fmt.pix_mp.pixelformat = v4l2_codec;
+
+	ret = get_inst_capability(inst);
+	if (ret)
+		return ret;
+
+	ret = ctrls_init(inst, session_init);
+	if (ret)
+		return ret;
+
+	ret = update_buffer_count(inst, INPUT_MPLANE);
+	if (ret)
+		return ret;
+
+	ret = update_buffer_count(inst, OUTPUT_MPLANE);
+
+	return ret;
+}
+
+int process_streamon_input(struct iris_inst *inst)
+{
+	enum iris_inst_sub_state set_sub_state = IRIS_INST_SUB_NONE;
+	int ret;
+
+	iris_scale_power(inst);
+
+	ret = iris_hfi_start(inst, INPUT_MPLANE);
+	if (ret)
+		return ret;
+
+	if (inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
+		ret = iris_inst_change_sub_state(inst, IRIS_INST_SUB_INPUT_PAUSE, 0);
+		if (ret)
+			return ret;
+	}
+
+	if (inst->sub_state & IRIS_INST_SUB_DRC ||
+	    inst->sub_state & IRIS_INST_SUB_DRAIN) {
+		if (!(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE)) {
+			ret = iris_hfi_pause(inst, INPUT_MPLANE);
+			if (ret)
+				return ret;
+			set_sub_state = IRIS_INST_SUB_INPUT_PAUSE;
+		}
+	}
+
+	ret = iris_inst_state_change_streamon(inst, INPUT_MPLANE);
+	if (ret)
+		return ret;
+
+	ret = iris_inst_change_sub_state(inst, 0, set_sub_state);
+
+	return ret;
+}
+
+int process_streamon_output(struct iris_inst *inst)
+{
+	enum iris_inst_sub_state clear_sub_state = IRIS_INST_SUB_NONE;
+	bool drain_pending = false;
+	bool drc_pending = false;
+	int ret;
+
+	iris_scale_power(inst);
+
+	drc_pending = inst->sub_state & IRIS_INST_SUB_DRC &&
+	    inst->sub_state & IRIS_INST_SUB_DRC_LAST;
+
+	drain_pending = inst->sub_state & IRIS_INST_SUB_DRAIN &&
+		inst->sub_state & IRIS_INST_SUB_DRAIN_LAST;
+
+	if (drc_pending) {
+		clear_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_DRC_LAST;
+	} else if (drain_pending) {
+		clear_sub_state = IRIS_INST_SUB_DRAIN_LAST | IRIS_INST_SUB_DRAIN;
+	}
+
+	if (inst->domain == DECODER && inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
+		ret = iris_alloc_and_queue_input_int_bufs(inst);
+		if (ret)
+			return ret;
+		ret = set_stage(inst, STAGE);
+		if (ret)
+			return ret;
+		ret = set_pipe(inst, PIPE);
+		if (ret)
+			return ret;
+	}
+
+	if ((inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) &&
+		(inst->state == IRIS_INST_INPUT_STREAMING)) {
+		if (!drain_pending) {
+			ret = iris_hfi_resume(inst, INPUT_MPLANE, HFI_CMD_SETTINGS_CHANGE);
+			if (ret)
+				return ret;
+		} else {
+			ret = iris_hfi_resume(inst, INPUT_MPLANE, HFI_CMD_DRAIN);
+			if (ret)
+				return ret;
+		}
+		clear_sub_state |= IRIS_INST_SUB_INPUT_PAUSE;
+	}
+
+	ret = iris_hfi_start(inst, OUTPUT_MPLANE);
+	if (ret)
+		return ret;
+
+	if (inst->sub_state & IRIS_INST_SUB_OUTPUT_PAUSE)
+		clear_sub_state |= IRIS_INST_SUB_OUTPUT_PAUSE;
+
+	ret = iris_inst_state_change_streamon(inst, OUTPUT_MPLANE);
+	if (ret)
+		return ret;
+
+	ret = iris_inst_change_sub_state(inst, clear_sub_state, 0);
+
+	return ret;
+}
+
+int vb2_buffer_to_driver(struct vb2_buffer *vb2, struct iris_buffer *buf)
+{
+	struct vb2_v4l2_buffer *vbuf;
+
+	if (!vb2 || !buf)
+		return -EINVAL;
+
+	vbuf = to_vb2_v4l2_buffer(vb2);
+
+	buf->fd = vb2->planes[0].m.fd;
+	buf->data_offset = vb2->planes[0].data_offset;
+	buf->data_size = vb2->planes[0].bytesused - vb2->planes[0].data_offset;
+	buf->buffer_size = vb2->planes[0].length;
+	buf->timestamp = vb2->timestamp;
+	buf->flags = vbuf->flags;
+	buf->attr = 0;
+
+	return 0;
+}
+
+int iris_pm_get(struct iris_core *core)
+{
+	int ret = 0;
+
+	mutex_lock(&core->lock);
+	if (core->num_pending_requests++ == 0)
+		ret = pm_runtime_resume_and_get(core->dev);
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_pm_put(struct iris_core *core, bool autosuspend)
+{
+	int ret = 0;
+
+	mutex_lock(&core->lock);
+
+	if (--core->num_pending_requests == 0) {
+		if (autosuspend) {
+			pm_runtime_mark_last_busy(core->dev);
+			ret = pm_runtime_put_autosuspend(core->dev);
+		} else {
+			ret = pm_runtime_put_sync(core->dev);
+		}
+	}
+	if (ret > 0)
+		ret = 0;
+
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_pm_get_put(struct iris_core *core)
+{
+	int ret = 0;
+
+	mutex_lock(&core->lock);
+
+	if (pm_runtime_suspended(core->dev)) {
+		if (core->num_pending_requests++ == 0) {
+			ret = pm_runtime_resume_and_get(core->dev);
+			if (ret < 0)
+				goto error;
+		}
+
+		if (--core->num_pending_requests == 0)
+			ret = pm_runtime_put_autosuspend(core->dev);
+	}
+	if (ret > 0)
+		ret = 0;
+
+error:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+void iris_pm_touch(struct iris_core *core)
+{
+	mutex_lock(&core->lock);
+	iris_pm_touch_unlocked(core);
+	mutex_unlock(&core->lock);
+}
+
+void iris_pm_touch_unlocked(struct iris_core *core)
+{
+	pm_runtime_mark_last_busy(core->dev);
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_helpers.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_helpers.h
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_HELPERS_H_
+#define _IRIS_HELPERS_H_
+
+#include <linux/align.h>
+#include <linux/types.h>
+
+#include "iris_instance.h"
+#include "iris_buffer.h"
+#include "iris_instance.h"
+#include "platform_common.h"
+
+#define NUM_MBS_PER_FRAME(__height, __width) \
+	((ALIGN(__height, 16) / 16) * (ALIGN(__width, 16) / 16))
+
+int check_core_lock(struct iris_core *core);
+bool res_is_less_than(u32 width, u32 height,
+		      u32 ref_width, u32 ref_height);
+u32 get_port_info(struct iris_inst *inst,
+		  enum plat_inst_cap_type cap_id);
+enum iris_buffer_type v4l2_type_to_driver(u32 type);
+u32 v4l2_type_from_driver(enum iris_buffer_type buffer_type);
+void v4l2_to_hfi_enum(struct iris_inst *inst,
+		      enum plat_inst_cap_type cap_id, u32 *value);
+int get_mbpf(struct iris_inst *inst);
+int close_session(struct iris_inst *inst);
+
+bool is_linear_colorformat(u32 colorformat);
+bool is_10bit_colorformat(enum colorformat_type colorformat);
+bool is_8bit_colorformat(enum colorformat_type colorformat);
+bool is_scaling_enabled(struct iris_inst *inst);
+bool is_split_mode_enabled(struct iris_inst *inst);
+bool is_hierb_type_requested(struct iris_inst *inst);
+int signal_session_msg_receipt(struct iris_inst *inst,
+			       enum signal_session_response cmd);
+struct iris_inst *to_instance(struct iris_core *core, u32 session_id);
+
+u32 v4l2_codec_from_driver(struct iris_inst *inst, enum codec_type codec);
+enum codec_type v4l2_codec_to_driver(struct iris_inst *inst, u32 v4l2_codec);
+u32 v4l2_colorformat_from_driver(struct iris_inst *inst, enum colorformat_type colorformat);
+enum colorformat_type v4l2_colorformat_to_driver(struct iris_inst *inst, u32 v4l2_colorformat);
+struct vb2_queue *get_vb2q(struct iris_inst *inst, u32 type);
+int check_core_mbps_mbpf(struct iris_inst *inst);
+int check_session_supported(struct iris_inst *inst);
+
+struct iris_buffer *get_driver_buf(struct iris_inst *inst, u32 plane, u32 index);
+int queue_buffer(struct iris_inst *inst, struct iris_buffer *buf);
+int queue_deferred_buffers(struct iris_inst *inst, enum iris_buffer_type buf_type);
+int iris_vb2_buffer_done(struct iris_inst *inst,
+			 struct iris_buffer *buf);
+int iris_release_nonref_buffers(struct iris_inst *inst);
+void iris_destroy_buffers(struct iris_inst *inst);
+int session_streamoff(struct iris_inst *inst, u32 plane);
+int process_resume(struct iris_inst *inst);
+int codec_change(struct iris_inst *inst, u32 v4l2_codec);
+int process_streamon_input(struct iris_inst *inst);
+int process_streamon_output(struct iris_inst *inst);
+int vb2_buffer_to_driver(struct vb2_buffer *vb2,
+			 struct iris_buffer *buf);
+int iris_pm_get(struct iris_core *core);
+int iris_pm_put(struct iris_core *core, bool autosuspend);
+int iris_pm_get_put(struct iris_core *core);
+void iris_pm_touch(struct iris_core *core);
+void iris_pm_touch_unlocked(struct iris_core *core);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_hfi.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_hfi.c
@@ -0,0 +1,884 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "firmware.h"
+#include "hfi_defines.h"
+#include "iris_helpers.h"
+#include "iris_hfi.h"
+#include "iris_hfi_packet.h"
+#include "iris_hfi_response.h"
+#include "iris_helpers.h"
+#include "vpu_common.h"
+
+static bool __valdiate_session(struct iris_core *core,
+			       struct iris_inst *inst)
+{
+	struct iris_inst *temp;
+	bool valid = false;
+	int ret;
+
+	ret = check_core_lock(core);
+	if (ret)
+		return false;
+
+	list_for_each_entry(temp, &core->instances, list) {
+		if (temp == inst) {
+			valid = true;
+			break;
+		}
+	}
+
+	return valid;
+}
+
+static int iris_power_off(struct iris_core *core)
+{
+	int ret;
+
+	if (!core->power_enabled)
+		return 0;
+
+	ret = call_vpu_op(core, power_off, core);
+	if (ret) {
+		dev_err(core->dev, "Failed to power off, err: %d\n", ret);
+		return ret;
+	}
+	core->power_enabled = false;
+
+	return ret;
+}
+
+static int iris_power_on(struct iris_core *core)
+{
+	int ret;
+
+	if (core->power_enabled)
+		return 0;
+
+	ret = call_vpu_op(core, power_on, core);
+	if (ret) {
+		dev_err(core->dev, "Failed to power on, err: %d\n", ret);
+		return ret;
+	}
+
+	core->power_enabled = true;
+
+	return ret;
+}
+
+static int sys_init(struct iris_core *core)
+{
+	int ret;
+
+	ret = hfi_packet_sys_init(core, core->packet, core->packet_size);
+	if (ret)
+		return ret;
+
+	ret = iris_hfi_queue_cmd_write(core, core->packet);
+
+	return ret;
+}
+
+static int sys_image_version(struct iris_core *core)
+{
+	int ret;
+
+	ret = hfi_packet_image_version(core, core->packet, core->packet_size);
+	if (ret)
+		return ret;
+
+	ret = iris_hfi_queue_cmd_write(core, core->packet);
+
+	return ret;
+}
+
+static int cache_operation_qbuf(struct iris_buffer *buffer)
+{
+	int ret = 0;
+
+	if (buffer->type == BUF_INPUT && buffer->dmabuf) {
+		ret = dma_buf_begin_cpu_access(buffer->dmabuf, DMA_TO_DEVICE);
+		if (ret)
+			return ret;
+
+		ret = dma_buf_end_cpu_access(buffer->dmabuf, DMA_FROM_DEVICE);
+		if (ret)
+			return ret;
+	} else if (buffer->type == BUF_OUTPUT && buffer->dmabuf) {
+		ret = dma_buf_begin_cpu_access(buffer->dmabuf, DMA_FROM_DEVICE);
+		if (ret)
+			return ret;
+
+		ret = dma_buf_end_cpu_access(buffer->dmabuf, DMA_FROM_DEVICE);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+int iris_hfi_core_init(struct iris_core *core)
+{
+	int ret;
+
+	ret = check_core_lock(core);
+	if (ret)
+		return ret;
+
+	ret = iris_hfi_queue_init(core);
+	if (ret)
+		goto error;
+
+	ret = iris_power_on(core);
+	if (ret)
+		goto error;
+
+	ret = iris_fw_load(core);
+	if (ret)
+		goto error_power_off;
+
+	ret = call_vpu_op(core, boot_firmware, core);
+	if (ret)
+		goto error_power_off;
+
+	ret = sys_init(core);
+	if (ret)
+		goto error_power_off;
+
+	ret = sys_image_version(core);
+	if (ret)
+		goto error_power_off;
+
+	return ret;
+
+error_power_off:
+	iris_power_off(core);
+error:
+	dev_err(core->dev, "%s(): failed\n", __func__);
+
+	return ret;
+}
+
+int iris_hfi_core_deinit(struct iris_core *core)
+{
+	int ret;
+
+	ret = check_core_lock(core);
+	if (ret)
+		return ret;
+
+	if (core->state == IRIS_CORE_DEINIT)
+		return 0;
+
+	iris_fw_unload(core);
+	iris_power_off(core);
+
+	return ret;
+}
+
+int iris_hfi_session_open(struct iris_inst *inst)
+{
+	struct iris_core *core;
+	int ret;
+
+	inst->packet_size = 4096;
+	inst->packet = kzalloc(inst->packet_size, GFP_KERNEL);
+	if (!inst->packet)
+		return -ENOMEM;
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+
+	if (!__valdiate_session(core, inst)) {
+		ret = -EINVAL;
+		goto fail_free_packet;
+	}
+
+	ret = hfi_packet_session_command(inst,
+					 HFI_CMD_OPEN,
+					 HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					 HFI_HOST_FLAGS_INTR_REQUIRED,
+					 HFI_PORT_NONE,
+					 0,
+					 HFI_PAYLOAD_U32,
+					 &inst->session_id,
+					 sizeof(u32));
+	if (ret)
+		goto fail_free_packet;
+
+	ret = iris_hfi_queue_cmd_write(core, inst->packet);
+	if (ret)
+		goto fail_free_packet;
+
+	mutex_unlock(&core->lock);
+
+	return ret;
+
+fail_free_packet:
+	kfree(inst->packet);
+	inst->packet = NULL;
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_hfi_session_close(struct iris_inst *inst)
+{
+	struct iris_core *core;
+	int ret;
+
+	if (!inst->packet)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+
+	if (!__valdiate_session(core, inst)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	ret = hfi_packet_session_command(inst,
+					 HFI_CMD_CLOSE,
+					 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					 HFI_HOST_FLAGS_INTR_REQUIRED |
+					 HFI_HOST_FLAGS_NON_DISCARDABLE),
+					 HFI_PORT_NONE,
+					 inst->session_id,
+					 HFI_PAYLOAD_NONE,
+					 NULL,
+					 0);
+	if (ret)
+		goto unlock;
+
+	ret = iris_hfi_queue_cmd_write(inst->core, inst->packet);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_hfi_session_set_codec(struct iris_inst *inst)
+{
+	struct iris_core *core;
+	int ret;
+	u32 codec;
+
+	if (!inst->packet)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+
+	if (!__valdiate_session(core, inst)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	codec = get_hfi_codec(inst);
+	ret = hfi_packet_session_property(inst,
+					  HFI_PROP_CODEC,
+					  HFI_HOST_FLAGS_NONE,
+					  HFI_PORT_NONE,
+					  HFI_PAYLOAD_U32_ENUM,
+					  &codec,
+					  sizeof(u32));
+	if (ret)
+		goto unlock;
+
+	ret = iris_hfi_queue_cmd_write(inst->core, inst->packet);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_hfi_session_set_default_header(struct iris_inst *inst)
+{
+	struct iris_core *core;
+	u32 default_header = false;
+	int ret;
+
+	if (!inst->packet)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+
+	if (!__valdiate_session(core, inst)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	default_header = inst->cap[DEFAULT_HEADER].value;
+	ret = hfi_packet_session_property(inst,
+					  HFI_PROP_DEC_DEFAULT_HEADER,
+					  HFI_HOST_FLAGS_NONE,
+					  get_hfi_port(inst, INPUT_MPLANE),
+					  HFI_PAYLOAD_U32,
+					  &default_header,
+					  sizeof(u32));
+	if (ret)
+		goto unlock;
+
+	ret = iris_hfi_queue_cmd_write(inst->core, inst->packet);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_hfi_start(struct iris_inst *inst, u32 plane)
+{
+	struct iris_core *core;
+	int ret = 0;
+
+	if (!inst->packet)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+
+	if (!__valdiate_session(core, inst)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (plane != INPUT_MPLANE && plane != OUTPUT_MPLANE)
+		goto unlock;
+
+	ret = hfi_packet_session_command(inst,
+					 HFI_CMD_START,
+					 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					 HFI_HOST_FLAGS_INTR_REQUIRED),
+					 get_hfi_port(inst, plane),
+					 inst->session_id,
+					 HFI_PAYLOAD_NONE,
+					 NULL,
+					 0);
+	if (ret)
+		goto unlock;
+
+	ret = iris_hfi_queue_cmd_write(inst->core, inst->packet);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_hfi_stop(struct iris_inst *inst, u32 plane)
+{
+	struct iris_core *core;
+	int ret = 0;
+
+	if (!inst->packet)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+
+	if (!__valdiate_session(core, inst)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (plane != INPUT_MPLANE && plane != OUTPUT_MPLANE)
+		goto unlock;
+
+	ret = hfi_packet_session_command(inst,
+					 HFI_CMD_STOP,
+					 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					 HFI_HOST_FLAGS_INTR_REQUIRED |
+					 HFI_HOST_FLAGS_NON_DISCARDABLE),
+					 get_hfi_port(inst, plane),
+					 inst->session_id,
+					 HFI_PAYLOAD_NONE,
+					 NULL,
+					 0);
+	if (ret)
+		goto unlock;
+
+	ret = iris_hfi_queue_cmd_write(inst->core, inst->packet);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_hfi_session_subscribe_mode(struct iris_inst *inst,
+				    u32 cmd, u32 plane, u32 payload_type,
+				    void *payload, u32 payload_size)
+{
+	struct iris_core *core;
+	int ret;
+
+	if (!inst->packet)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+
+	if (!__valdiate_session(core, inst)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	ret = hfi_packet_session_command(inst,
+					 cmd,
+					 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					 HFI_HOST_FLAGS_INTR_REQUIRED),
+					 get_hfi_port(inst, plane),
+					 inst->session_id,
+					 payload_type,
+					 payload,
+					 payload_size);
+	if (ret)
+		goto unlock;
+
+	ret = iris_hfi_queue_cmd_write(inst->core, inst->packet);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_hfi_pause(struct iris_inst *inst, u32 plane)
+{
+	struct iris_core *core;
+	int ret = 0;
+
+	if (!inst->packet)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+
+	if (!__valdiate_session(core, inst)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (plane != INPUT_MPLANE && plane != OUTPUT_MPLANE)
+		goto unlock;
+
+	ret = hfi_packet_session_command(inst,
+					 HFI_CMD_PAUSE,
+					 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					 HFI_HOST_FLAGS_INTR_REQUIRED),
+					 get_hfi_port(inst, plane),
+					 inst->session_id,
+					 HFI_PAYLOAD_NONE,
+					 NULL,
+					 0);
+	if (ret)
+		goto unlock;
+
+	ret = iris_hfi_queue_cmd_write(inst->core, inst->packet);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_hfi_resume(struct iris_inst *inst, u32 plane, u32 payload)
+{
+	struct iris_core *core;
+	int ret = 0;
+
+	if (!inst->packet)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+
+	if (!__valdiate_session(core, inst)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (plane != INPUT_MPLANE && plane != OUTPUT_MPLANE)
+		goto unlock;
+
+	ret = hfi_packet_session_command(inst,
+					 HFI_CMD_RESUME,
+					 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					 HFI_HOST_FLAGS_INTR_REQUIRED),
+					 get_hfi_port(inst, plane),
+					 inst->session_id,
+					 HFI_PAYLOAD_U32,
+					 &payload,
+					 sizeof(u32));
+	if (ret)
+		goto unlock;
+
+	ret = iris_hfi_queue_cmd_write(inst->core, inst->packet);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_hfi_drain(struct iris_inst *inst, u32 plane)
+{
+	struct iris_core *core;
+	int ret = 0;
+
+	if (!inst->packet)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+
+	if (!__valdiate_session(core, inst)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (plane != INPUT_MPLANE)
+		goto unlock;
+
+	ret = hfi_packet_session_command(inst,
+					 HFI_CMD_DRAIN,
+					 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					 HFI_HOST_FLAGS_INTR_REQUIRED |
+					 HFI_HOST_FLAGS_NON_DISCARDABLE),
+					 get_hfi_port(inst, plane),
+					 inst->session_id,
+					 HFI_PAYLOAD_NONE,
+					 NULL,
+					 0);
+	if (ret)
+		goto unlock;
+
+	ret = iris_hfi_queue_cmd_write(inst->core, inst->packet);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+irqreturn_t iris_hfi_isr(int irq, void *data)
+{
+	disable_irq_nosync(irq);
+
+	return IRQ_WAKE_THREAD;
+}
+
+irqreturn_t iris_hfi_isr_handler(int irq, void *data)
+{
+	struct iris_core *core = data;
+	int ret;
+
+	if (!core)
+		return IRQ_NONE;
+
+	iris_pm_touch(core);
+	ret = iris_pm_get(core);
+	if (ret)
+		goto exit;
+
+	mutex_lock(&core->lock);
+	call_vpu_op(core, clear_interrupt, core);
+	mutex_unlock(&core->lock);
+
+	__response_handler(core);
+
+	iris_pm_put(core, true);
+
+exit:
+	if (!call_vpu_op(core, watchdog, core, core->intr_status))
+		enable_irq(irq);
+
+	return IRQ_HANDLED;
+}
+
+int iris_hfi_set_property(struct iris_inst *inst,
+			  u32 packet_type, u32 flag, u32 plane, u32 payload_type,
+			  void *payload, u32 payload_size)
+{
+	struct iris_core *core;
+	int ret;
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+
+	ret = hfi_packet_session_property(inst,
+					  packet_type,
+					  flag,
+					  plane,
+					  payload_type,
+					  payload,
+					  payload_size);
+	if (ret)
+		goto unlock;
+
+	ret = iris_hfi_queue_cmd_write(core, inst->packet);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_hfi_set_ir_period(struct iris_inst *inst,
+			   u32 packet_type, u32 flag, u32 plane, u32 payload_type,
+			   void *payload, u32 payload_size)
+{
+	u32 sync_frame_req = 0;
+	struct iris_core *core;
+	int ret;
+
+	core = inst->core;
+
+	mutex_lock(&core->lock);
+
+	ret = hfi_create_header(inst->packet, inst->packet_size,
+				inst->session_id, core->header_id++);
+	if (ret)
+		goto exit;
+
+	if (!inst->ir_enabled) {
+		inst->ir_enabled = ((*(u32 *)payload > 0) ? true : false);
+		if (inst->ir_enabled && inst->vb2q_dst->streaming) {
+			sync_frame_req = HFI_SYNC_FRAME_REQUEST_WITH_PREFIX_SEQ_HDR;
+			ret = hfi_create_packet(inst->packet, inst->packet_size,
+						HFI_PROP_REQUEST_SYNC_FRAME,
+						HFI_HOST_FLAGS_NONE,
+						HFI_PAYLOAD_U32_ENUM,
+						HFI_PORT_BITSTREAM,
+						core->packet_id++,
+						&sync_frame_req,
+						sizeof(u32));
+			if (ret)
+				goto exit;
+		}
+	}
+
+	ret = hfi_create_packet(inst->packet, inst->packet_size,
+				packet_type,
+				HFI_HOST_FLAGS_NONE,
+				HFI_PAYLOAD_U32,
+				plane,
+				core->packet_id++,
+				payload,
+				sizeof(u32));
+	if (ret)
+		goto exit;
+
+	ret = iris_hfi_queue_cmd_write(inst->core, inst->packet);
+
+exit:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_hfi_queue_buffer(struct iris_inst *inst,
+			  struct iris_buffer *buffer)
+{
+	struct hfi_buffer hfi_buffer;
+	struct iris_core *core;
+	int ret;
+
+	if (!inst->packet)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+
+	if (!__valdiate_session(core, inst)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	ret = get_hfi_buffer(inst, buffer, &hfi_buffer);
+	if (ret)
+		goto unlock;
+
+	ret = cache_operation_qbuf(buffer);
+	if (ret)
+		goto unlock;
+
+	ret = hfi_packet_session_command(inst,
+					 HFI_CMD_BUFFER,
+					 HFI_HOST_FLAGS_INTR_REQUIRED,
+					 get_hfi_port_from_buffer_type(inst, buffer->type),
+					 inst->session_id,
+					 HFI_PAYLOAD_STRUCTURE,
+					 &hfi_buffer,
+					 sizeof(hfi_buffer));
+	if (ret)
+		goto unlock;
+
+	ret = iris_hfi_queue_cmd_write(inst->core, inst->packet);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int iris_hfi_release_buffer(struct iris_inst *inst,
+			    struct iris_buffer *buffer)
+{
+	struct hfi_buffer hfi_buffer;
+	struct iris_core *core;
+	int ret;
+
+	if (!inst->packet || !buffer)
+		return -EINVAL;
+
+	core = inst->core;
+	mutex_lock(&core->lock);
+
+	if (!__valdiate_session(core, inst)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	ret = get_hfi_buffer(inst, buffer, &hfi_buffer);
+	if (ret)
+		goto unlock;
+
+	hfi_buffer.flags |= HFI_BUF_HOST_FLAG_RELEASE;
+
+	ret = hfi_packet_session_command(inst,
+					 HFI_CMD_BUFFER,
+					 (HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+					 HFI_HOST_FLAGS_INTR_REQUIRED),
+					 get_hfi_port_from_buffer_type(inst, buffer->type),
+					 inst->session_id,
+					 HFI_PAYLOAD_STRUCTURE,
+					 &hfi_buffer,
+					 sizeof(hfi_buffer));
+	if (ret)
+		goto unlock;
+
+	ret = iris_hfi_queue_cmd_write(inst->core, inst->packet);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+int prepare_pc(struct iris_core *core)
+{
+	int ret;
+
+	ret = hfi_packet_sys_pc_prep(core, core->packet, core->packet_size);
+	if (ret)
+		goto err_pc_prep;
+
+	ret = iris_hfi_queue_cmd_write(core, core->packet);
+	if (ret)
+		goto err_pc_prep;
+
+	return ret;
+
+err_pc_prep:
+	dev_err(core->dev, "Failed to prepare venus for power off\n");
+
+	return ret;
+}
+
+int iris_hfi_pm_suspend(struct iris_core *core)
+{
+	int ret;
+
+	ret = check_core_lock(core);
+	if (ret)
+		return ret;
+
+	if (!core_in_valid_state(core))
+		return -EINVAL;
+
+	if (!core->power_enabled)
+		return 0;
+
+	if (core->skip_pc_count >= MAX_PC_SKIP_COUNT) {
+		dev_err(core->dev, "Failed to PC for %d times\n", core->skip_pc_count);
+		core->skip_pc_count = 0;
+		iris_change_core_state(core, IRIS_CORE_ERROR);
+		iris_core_deinit_locked(core);
+		return -EINVAL;
+	}
+
+	iris_flush_debug_queue(core, core->packet, core->packet_size);
+
+	ret = call_vpu_op(core, prepare_pc, core);
+	if (ret) {
+		core->skip_pc_count++;
+		iris_pm_touch_unlocked(core);
+		return -EAGAIN;
+	}
+
+	ret = iris_set_hw_state(core, false);
+	if (ret)
+		return ret;
+
+	ret = iris_power_off(core);
+	if (ret)
+		return ret;
+
+	core->skip_pc_count = 0;
+
+	return ret;
+}
+
+int iris_hfi_pm_resume(struct iris_core *core)
+{
+	int ret;
+
+	ret = check_core_lock(core);
+	if (ret)
+		return ret;
+
+	if (!core_in_valid_state(core))
+		return -EINVAL;
+
+	if (core->power_enabled)
+		return 0;
+
+	ret = iris_power_on(core);
+	if (ret)
+		goto error;
+
+	ret = iris_set_hw_state(core, true);
+	if (ret)
+		goto err_power_off;
+
+	ret = call_vpu_op(core, boot_firmware, core);
+	if (ret)
+		goto err_suspend_hw;
+
+	ret = hfi_packet_sys_interframe_powercollapse(core, core->packet, core->packet_size);
+	if (ret)
+		goto err_suspend_hw;
+
+	ret = iris_hfi_queue_cmd_write(core, core->packet);
+	if (ret)
+		goto err_suspend_hw;
+
+	return ret;
+
+err_suspend_hw:
+	iris_set_hw_state(core, false);
+err_power_off:
+	iris_power_off(core);
+error:
+	dev_err(core->dev, "Failed to Resume\n");
+
+	return -EBUSY;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_hfi.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_hfi.h
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_HFI_H_
+#define _IRIS_HFI_H_
+
+#include "iris_instance.h"
+#include "iris_core.h"
+
+#define MAX_PC_SKIP_COUNT 10
+
+int iris_hfi_core_init(struct iris_core *core);
+int iris_hfi_core_deinit(struct iris_core *core);
+int iris_hfi_session_open(struct iris_inst *inst);
+int iris_hfi_session_close(struct iris_inst *inst);
+int iris_hfi_session_subscribe_mode(struct iris_inst *inst,
+				    u32 cmd, u32 plane, u32 payload_type,
+				    void *payload, u32 payload_size);
+int iris_hfi_set_property(struct iris_inst *inst,
+			  u32 packet_type, u32 flag, u32 plane, u32 payload_type,
+			  void *payload, u32 payload_size);
+
+int iris_hfi_session_set_codec(struct iris_inst *inst);
+int iris_hfi_session_set_default_header(struct iris_inst *inst);
+
+int iris_hfi_start(struct iris_inst *inst, u32 plane);
+int iris_hfi_stop(struct iris_inst *inst, u32 plane);
+int iris_hfi_drain(struct iris_inst *inst, u32 plane);
+int iris_hfi_pause(struct iris_inst *inst, u32 plane);
+int iris_hfi_resume(struct iris_inst *inst, u32 plane, u32 cmd);
+int iris_hfi_queue_buffer(struct iris_inst *inst,
+			  struct iris_buffer *buffer);
+int iris_hfi_release_buffer(struct iris_inst *inst,
+			    struct iris_buffer *buffer);
+int iris_hfi_pm_suspend(struct iris_core *core);
+int iris_hfi_pm_resume(struct iris_core *core);
+int prepare_pc(struct iris_core *core);
+
+irqreturn_t iris_hfi_isr(int irq, void *data);
+irqreturn_t iris_hfi_isr_handler(int irq, void *data);
+int iris_hfi_set_ir_period(struct iris_inst *inst,
+			   u32 packet_type, u32 flag, u32 plane, u32 payload_type,
+			   void *payload, u32 payload_size);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_hfi_packet.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_hfi_packet.c
@@ -0,0 +1,726 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "iris_common.h"
+#include "iris_core.h"
+#include "iris_helpers.h"
+#include "iris_hfi_packet.h"
+#include "hfi_defines.h"
+
+u32 get_hfi_port_from_buffer_type(struct iris_inst *inst, enum iris_buffer_type buffer_type)
+{
+	u32 hfi_port = HFI_PORT_NONE;
+
+	if (inst->domain == DECODER) {
+		switch (buffer_type) {
+		case BUF_INPUT:
+		case BUF_BIN:
+		case BUF_COMV:
+		case BUF_NON_COMV:
+		case BUF_LINE:
+			hfi_port = HFI_PORT_BITSTREAM;
+			break;
+		case BUF_OUTPUT:
+		case BUF_DPB:
+			hfi_port = HFI_PORT_RAW;
+			break;
+		case BUF_PERSIST:
+			hfi_port = HFI_PORT_NONE;
+			break;
+		default:
+			break;
+		}
+	} else if (inst->domain == ENCODER) {
+		switch (buffer_type) {
+		case BUF_INPUT:
+		case BUF_VPSS:
+			hfi_port = HFI_PORT_RAW;
+			break;
+		case BUF_OUTPUT:
+		case BUF_BIN:
+		case BUF_COMV:
+		case BUF_NON_COMV:
+		case BUF_LINE:
+		case BUF_DPB:
+			hfi_port = HFI_PORT_BITSTREAM;
+			break;
+		case BUF_ARP:
+			hfi_port = HFI_PORT_NONE;
+			break;
+		default:
+			break;
+		}
+	}
+
+	return hfi_port;
+}
+
+u32 get_hfi_port(struct iris_inst *inst, u32 plane)
+{
+	u32 hfi_port = HFI_PORT_NONE;
+
+	if (inst->domain == DECODER) {
+		switch (plane) {
+		case INPUT_MPLANE:
+			hfi_port = HFI_PORT_BITSTREAM;
+			break;
+		case OUTPUT_MPLANE:
+			hfi_port = HFI_PORT_RAW;
+			break;
+		default:
+			break;
+		}
+	} else if (inst->domain == ENCODER) {
+		switch (plane) {
+		case INPUT_MPLANE:
+			hfi_port = HFI_PORT_RAW;
+			break;
+		case OUTPUT_MPLANE:
+			hfi_port = HFI_PORT_BITSTREAM;
+			break;
+		default:
+			break;
+		}
+	}
+
+	return hfi_port;
+}
+
+static u32 hfi_buf_type_from_driver(enum domain_type domain, enum iris_buffer_type buffer_type)
+{
+	switch (buffer_type) {
+	case BUF_INPUT:
+		if (domain == DECODER)
+			return HFI_BUFFER_BITSTREAM;
+		else
+			return HFI_BUFFER_RAW;
+	case BUF_OUTPUT:
+		if (domain == DECODER)
+			return HFI_BUFFER_RAW;
+		else
+			return HFI_BUFFER_BITSTREAM;
+	case BUF_BIN:
+		return HFI_BUFFER_BIN;
+	case BUF_ARP:
+		return HFI_BUFFER_ARP;
+	case BUF_COMV:
+		return HFI_BUFFER_COMV;
+	case BUF_NON_COMV:
+		return HFI_BUFFER_NON_COMV;
+	case BUF_LINE:
+		return HFI_BUFFER_LINE;
+	case BUF_DPB:
+		return HFI_BUFFER_DPB;
+	case BUF_PERSIST:
+		return HFI_BUFFER_PERSIST;
+	default:
+		return 0;
+	}
+}
+
+u32 hfi_buf_type_to_driver(enum domain_type domain, enum hfi_buffer_type buf_type)
+{
+	switch (buf_type) {
+	case HFI_BUFFER_BITSTREAM:
+		if (domain == DECODER)
+			return BUF_INPUT;
+		else
+			return BUF_OUTPUT;
+	case HFI_BUFFER_RAW:
+		if (domain == DECODER)
+			return BUF_OUTPUT;
+		else
+			return BUF_INPUT;
+	case HFI_BUFFER_BIN:
+		return BUF_BIN;
+	case HFI_BUFFER_ARP:
+		return BUF_ARP;
+	case HFI_BUFFER_COMV:
+		return BUF_COMV;
+	case HFI_BUFFER_NON_COMV:
+		return BUF_NON_COMV;
+	case HFI_BUFFER_LINE:
+		return BUF_LINE;
+	case HFI_BUFFER_DPB:
+		return BUF_DPB;
+	case HFI_BUFFER_PERSIST:
+		return BUF_PERSIST;
+	case HFI_BUFFER_VPSS:
+		return BUF_VPSS;
+	default:
+		return 0;
+	}
+}
+
+u32 get_hfi_codec(struct iris_inst *inst)
+{
+	switch (inst->codec) {
+	case H264:
+		if (inst->domain == ENCODER)
+			return HFI_CODEC_ENCODE_AVC;
+		else
+			return HFI_CODEC_DECODE_AVC;
+	case HEVC:
+		if (inst->domain == ENCODER)
+			return HFI_CODEC_ENCODE_HEVC;
+		else
+			return HFI_CODEC_DECODE_HEVC;
+	case VP9:
+		return HFI_CODEC_DECODE_VP9;
+	default:
+		return 0;
+	}
+}
+
+u32 get_hfi_colorformat(u32 colorformat)
+{
+	u32 hfi_colorformat = HFI_COLOR_FMT_NV12_UBWC;
+
+	switch (colorformat) {
+	case V4L2_PIX_FMT_NV12:
+		hfi_colorformat = HFI_COLOR_FMT_NV12;
+		break;
+	case V4L2_PIX_FMT_QC08C:
+		hfi_colorformat = HFI_COLOR_FMT_NV12_UBWC;
+		break;
+	case V4L2_PIX_FMT_QC10C:
+		hfi_colorformat = HFI_COLOR_FMT_TP10_UBWC;
+		break;
+	default:
+		break;
+	}
+
+	return hfi_colorformat;
+}
+
+u32 get_hfi_color_primaries(u32 primaries)
+{
+	u32 hfi_primaries = HFI_PRIMARIES_RESERVED;
+
+	switch (primaries) {
+	case V4L2_COLORSPACE_DEFAULT:
+		hfi_primaries = HFI_PRIMARIES_RESERVED;
+		break;
+	case V4L2_COLORSPACE_REC709:
+		hfi_primaries = HFI_PRIMARIES_BT709;
+		break;
+	case V4L2_COLORSPACE_470_SYSTEM_M:
+		hfi_primaries = HFI_PRIMARIES_BT470_SYSTEM_M;
+		break;
+	case V4L2_COLORSPACE_470_SYSTEM_BG:
+		hfi_primaries = HFI_PRIMARIES_BT470_SYSTEM_BG;
+		break;
+	case V4L2_COLORSPACE_SMPTE170M:
+		hfi_primaries = HFI_PRIMARIES_BT601_525;
+		break;
+	case V4L2_COLORSPACE_SMPTE240M:
+		hfi_primaries = HFI_PRIMARIES_SMPTE_ST240M;
+		break;
+	case V4L2_COLORSPACE_BT2020:
+		hfi_primaries = HFI_PRIMARIES_BT2020;
+		break;
+	case V4L2_COLORSPACE_DCI_P3:
+		hfi_primaries = HFI_PRIMARIES_SMPTE_RP431_2;
+		break;
+	default:
+		break;
+	}
+
+	return hfi_primaries;
+}
+
+u32 get_hfi_transer_char(u32 characterstics)
+{
+	u32 hfi_characterstics = HFI_TRANSFER_RESERVED;
+
+	switch (characterstics) {
+	case V4L2_XFER_FUNC_DEFAULT:
+		hfi_characterstics = HFI_TRANSFER_RESERVED;
+		break;
+	case V4L2_XFER_FUNC_709:
+		hfi_characterstics = HFI_TRANSFER_BT709;
+		break;
+	case V4L2_XFER_FUNC_SMPTE240M:
+		hfi_characterstics = HFI_TRANSFER_SMPTE_ST240M;
+		break;
+	case V4L2_XFER_FUNC_SRGB:
+		hfi_characterstics = HFI_TRANSFER_SRGB_SYCC;
+		break;
+	case V4L2_XFER_FUNC_SMPTE2084:
+		hfi_characterstics = HFI_TRANSFER_SMPTE_ST2084_PQ;
+		break;
+	default:
+		break;
+	}
+
+	return hfi_characterstics;
+}
+
+u32 get_hfi_matrix_coefficients(u32 coefficients)
+{
+	u32 hfi_coefficients = HFI_MATRIX_COEFF_RESERVED;
+
+	switch (coefficients) {
+	case V4L2_YCBCR_ENC_DEFAULT:
+		hfi_coefficients = HFI_MATRIX_COEFF_RESERVED;
+		break;
+	case V4L2_YCBCR_ENC_709:
+		hfi_coefficients = HFI_MATRIX_COEFF_BT709;
+		break;
+	case V4L2_YCBCR_ENC_XV709:
+		hfi_coefficients = HFI_MATRIX_COEFF_BT709;
+		break;
+	case V4L2_YCBCR_ENC_XV601:
+		hfi_coefficients = HFI_MATRIX_COEFF_BT470_SYS_BG_OR_BT601_625;
+		break;
+	case V4L2_YCBCR_ENC_601:
+		hfi_coefficients = HFI_MATRIX_COEFF_BT601_525_BT1358_525_OR_625;
+		break;
+	case V4L2_YCBCR_ENC_SMPTE240M:
+		hfi_coefficients = HFI_MATRIX_COEFF_SMPTE_ST240;
+		break;
+	case V4L2_YCBCR_ENC_BT2020:
+		hfi_coefficients = HFI_MATRIX_COEFF_BT2020_NON_CONSTANT;
+		break;
+	case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
+		hfi_coefficients = HFI_MATRIX_COEFF_BT2020_CONSTANT;
+		break;
+	default:
+		break;
+	}
+
+	return hfi_coefficients;
+}
+
+u32 get_v4l2_color_primaries(u32 hfi_primaries)
+{
+	u32 primaries = V4L2_COLORSPACE_DEFAULT;
+
+	switch (hfi_primaries) {
+	case HFI_PRIMARIES_RESERVED:
+		primaries = V4L2_COLORSPACE_DEFAULT;
+		break;
+	case HFI_PRIMARIES_BT709:
+		primaries = V4L2_COLORSPACE_REC709;
+		break;
+	case HFI_PRIMARIES_BT470_SYSTEM_M:
+		primaries = V4L2_COLORSPACE_470_SYSTEM_M;
+		break;
+	case HFI_PRIMARIES_BT470_SYSTEM_BG:
+		primaries = V4L2_COLORSPACE_470_SYSTEM_BG;
+		break;
+	case HFI_PRIMARIES_BT601_525:
+		primaries = V4L2_COLORSPACE_SMPTE170M;
+		break;
+	case HFI_PRIMARIES_SMPTE_ST240M:
+		primaries = V4L2_COLORSPACE_SMPTE240M;
+		break;
+	case HFI_PRIMARIES_BT2020:
+		primaries = V4L2_COLORSPACE_BT2020;
+		break;
+	case V4L2_COLORSPACE_DCI_P3:
+		primaries = HFI_PRIMARIES_SMPTE_RP431_2;
+		break;
+	default:
+		break;
+	}
+
+	return primaries;
+}
+
+u32 get_v4l2_transer_char(u32 hfi_characterstics)
+{
+	u32 characterstics = V4L2_XFER_FUNC_DEFAULT;
+
+	switch (hfi_characterstics) {
+	case HFI_TRANSFER_RESERVED:
+		characterstics = V4L2_XFER_FUNC_DEFAULT;
+		break;
+	case HFI_TRANSFER_BT709:
+		characterstics = V4L2_XFER_FUNC_709;
+		break;
+	case HFI_TRANSFER_SMPTE_ST240M:
+		characterstics = V4L2_XFER_FUNC_SMPTE240M;
+		break;
+	case HFI_TRANSFER_SRGB_SYCC:
+		characterstics = V4L2_XFER_FUNC_SRGB;
+		break;
+	case HFI_TRANSFER_SMPTE_ST2084_PQ:
+		characterstics = V4L2_XFER_FUNC_SMPTE2084;
+		break;
+	default:
+		break;
+	}
+
+	return characterstics;
+}
+
+u32 get_v4l2_matrix_coefficients(u32 hfi_coefficients)
+{
+	u32 coefficients = V4L2_YCBCR_ENC_DEFAULT;
+
+	switch (hfi_coefficients) {
+	case HFI_MATRIX_COEFF_RESERVED:
+		coefficients = V4L2_YCBCR_ENC_DEFAULT;
+		break;
+	case HFI_MATRIX_COEFF_BT709:
+		coefficients = V4L2_YCBCR_ENC_709;
+		break;
+	case HFI_MATRIX_COEFF_BT470_SYS_BG_OR_BT601_625:
+		coefficients = V4L2_YCBCR_ENC_XV601;
+		break;
+	case HFI_MATRIX_COEFF_BT601_525_BT1358_525_OR_625:
+		coefficients = V4L2_YCBCR_ENC_601;
+		break;
+	case HFI_MATRIX_COEFF_SMPTE_ST240:
+		coefficients = V4L2_YCBCR_ENC_SMPTE240M;
+		break;
+	case HFI_MATRIX_COEFF_BT2020_NON_CONSTANT:
+		coefficients = V4L2_YCBCR_ENC_BT2020;
+		break;
+	case HFI_MATRIX_COEFF_BT2020_CONSTANT:
+		coefficients = V4L2_YCBCR_ENC_BT2020_CONST_LUM;
+		break;
+	default:
+		break;
+	}
+
+	return coefficients;
+}
+
+int get_hfi_buffer(struct iris_inst *inst,
+		   struct iris_buffer *buffer, struct hfi_buffer *buf)
+{
+	memset(buf, 0, sizeof(struct hfi_buffer));
+	buf->type = hfi_buf_type_from_driver(inst->domain, buffer->type);
+	buf->index = buffer->index;
+	buf->base_address = buffer->device_addr;
+	buf->addr_offset = 0;
+	buf->buffer_size = buffer->buffer_size;
+	/*
+	 * for decoder input buffers, firmware (BSE HW) needs 256 aligned
+	 * buffer size otherwise it will truncate or ignore the data after 256
+	 * aligned size which may lead to error concealment
+	 */
+	if (inst->domain == DECODER && buffer->type == BUF_INPUT)
+		buf->buffer_size = ALIGN(buffer->buffer_size, 256);
+	buf->data_offset = buffer->data_offset;
+	buf->data_size = buffer->data_size;
+	if (buffer->attr & BUF_ATTR_READ_ONLY)
+		buf->flags |= HFI_BUF_HOST_FLAG_READONLY;
+	if (buffer->attr & BUF_ATTR_PENDING_RELEASE)
+		buf->flags |= HFI_BUF_HOST_FLAG_RELEASE;
+	buf->flags |= HFI_BUF_HOST_FLAGS_CB_NON_SECURE;
+	buf->timestamp = buffer->timestamp;
+
+	return 0;
+}
+
+int hfi_create_header(u8 *packet, u32 packet_size, u32 session_id,
+		      u32 header_id)
+{
+	struct hfi_header *hdr = (struct hfi_header *)packet;
+
+	if (!packet || packet_size < sizeof(*hdr))
+		return -EINVAL;
+
+	memset(hdr, 0, sizeof(*hdr));
+
+	hdr->size = sizeof(*hdr);
+	hdr->session_id = session_id;
+	hdr->header_id = header_id;
+	hdr->num_packets = 0;
+
+	return 0;
+}
+
+int hfi_create_packet(u8 *packet, u32 packet_size, u32 pkt_type,
+		      u32 pkt_flags, u32 payload_type, u32 port,
+		      u32 packet_id, void *payload, u32 payload_size)
+{
+	struct hfi_header *hdr;
+	struct hfi_packet *pkt;
+	u32 pkt_size;
+
+	if (!packet)
+		return -EINVAL;
+
+	hdr = (struct hfi_header *)packet;
+	if (hdr->size < sizeof(*hdr))
+		return -EINVAL;
+
+	pkt = (struct hfi_packet *)(packet + hdr->size);
+	pkt_size = sizeof(*pkt) + payload_size;
+	if (packet_size < hdr->size  + pkt_size)
+		return -EINVAL;
+
+	memset(pkt, 0, pkt_size);
+	pkt->size = pkt_size;
+	pkt->type = pkt_type;
+	pkt->flags = pkt_flags;
+	pkt->payload_info = payload_type;
+	pkt->port = port;
+	pkt->packet_id = packet_id;
+	if (payload_size)
+		memcpy((u8 *)pkt + sizeof(*pkt),
+		       payload, payload_size);
+
+	hdr->num_packets++;
+	hdr->size += pkt->size;
+
+	return 0;
+}
+
+int hfi_packet_sys_init(struct iris_core *core,
+			u8 *pkt, u32 pkt_size)
+{
+	u32 payload = 0;
+	int ret;
+
+	ret = hfi_create_header(pkt, pkt_size,
+				0,
+				core->header_id++);
+	if (ret)
+		goto error;
+
+	payload = HFI_VIDEO_ARCH_LX;
+	core->sys_init_id = core->packet_id++;
+	ret = hfi_create_packet(pkt, pkt_size,
+				HFI_CMD_INIT,
+				(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+				HFI_HOST_FLAGS_INTR_REQUIRED |
+				HFI_HOST_FLAGS_NON_DISCARDABLE),
+				HFI_PAYLOAD_U32,
+				HFI_PORT_NONE,
+				core->sys_init_id,
+				&payload,
+				sizeof(u32));
+	if (ret)
+		goto error;
+
+	payload = core->platform_data->ubwc_config->max_channels;
+	ret = hfi_create_packet(pkt, pkt_size,
+				HFI_PROP_UBWC_MAX_CHANNELS,
+				HFI_HOST_FLAGS_NONE,
+				HFI_PAYLOAD_U32,
+				HFI_PORT_NONE,
+				core->packet_id++,
+				&payload,
+				sizeof(u32));
+	if (ret)
+		goto error;
+
+	payload = core->platform_data->ubwc_config->mal_length;
+	ret = hfi_create_packet(pkt, pkt_size,
+				HFI_PROP_UBWC_MAL_LENGTH,
+				HFI_HOST_FLAGS_NONE,
+				HFI_PAYLOAD_U32,
+				HFI_PORT_NONE,
+				core->packet_id++,
+				&payload,
+				sizeof(u32));
+	if (ret)
+		goto error;
+
+	payload = core->platform_data->ubwc_config->highest_bank_bit;
+	ret = hfi_create_packet(pkt, pkt_size,
+				HFI_PROP_UBWC_HBB,
+				HFI_HOST_FLAGS_NONE,
+				HFI_PAYLOAD_U32,
+				HFI_PORT_NONE,
+				core->packet_id++,
+				&payload,
+				sizeof(u32));
+	if (ret)
+		goto error;
+
+	payload = core->platform_data->ubwc_config->bank_swzl_level;
+	ret = hfi_create_packet(pkt, pkt_size,
+				HFI_PROP_UBWC_BANK_SWZL_LEVEL1,
+				HFI_HOST_FLAGS_NONE,
+				HFI_PAYLOAD_U32,
+				HFI_PORT_NONE,
+				core->packet_id++,
+				&payload,
+				sizeof(u32));
+	if (ret)
+		goto error;
+
+	payload = core->platform_data->ubwc_config->bank_swz2_level;
+	ret = hfi_create_packet(pkt, pkt_size,
+				HFI_PROP_UBWC_BANK_SWZL_LEVEL2,
+				HFI_HOST_FLAGS_NONE,
+				HFI_PAYLOAD_U32,
+				HFI_PORT_NONE,
+				core->packet_id++,
+				&payload,
+				sizeof(u32));
+	if (ret)
+		goto error;
+
+	payload = core->platform_data->ubwc_config->bank_swz3_level;
+	ret = hfi_create_packet(pkt, pkt_size,
+				HFI_PROP_UBWC_BANK_SWZL_LEVEL3,
+				HFI_HOST_FLAGS_NONE,
+				HFI_PAYLOAD_U32,
+				HFI_PORT_NONE,
+				core->packet_id++,
+				&payload,
+				sizeof(u32));
+	if (ret)
+		goto error;
+
+	payload = core->platform_data->ubwc_config->bank_spreading;
+	ret = hfi_create_packet(pkt, pkt_size,
+				HFI_PROP_UBWC_BANK_SPREADING,
+				HFI_HOST_FLAGS_NONE,
+				HFI_PAYLOAD_U32,
+				HFI_PORT_NONE,
+				core->packet_id++,
+				&payload,
+				sizeof(u32));
+	if (ret)
+		goto error;
+
+	return ret;
+
+error:
+	dev_err(core->dev, "%s: create sys init packet failed\n", __func__);
+
+	return ret;
+}
+
+int hfi_packet_image_version(struct iris_core *core,
+			     u8 *pkt, u32 pkt_size)
+{
+	int ret;
+
+	ret = hfi_create_header(pkt, pkt_size,
+				0,
+				core->header_id++);
+	if (ret)
+		goto error;
+
+	ret = hfi_create_packet(pkt, pkt_size,
+				HFI_PROP_IMAGE_VERSION,
+				(HFI_HOST_FLAGS_RESPONSE_REQUIRED |
+				HFI_HOST_FLAGS_INTR_REQUIRED |
+				HFI_HOST_FLAGS_GET_PROPERTY),
+				HFI_PAYLOAD_NONE,
+				HFI_PORT_NONE,
+				core->packet_id++,
+				NULL, 0);
+	if (ret)
+		goto error;
+
+	return ret;
+
+error:
+	dev_err(core->dev, "%s: create image version packet failed\n", __func__);
+
+	return ret;
+}
+
+int hfi_packet_session_command(struct iris_inst *inst, u32 pkt_type,
+			       u32 flags, u32 port, u32 session_id,
+			       u32 payload_type, void *payload,
+			       u32 payload_size)
+{
+	struct iris_core *core;
+	int ret;
+
+	core = inst->core;
+
+	ret = hfi_create_header(inst->packet, inst->packet_size,
+				session_id, core->header_id++);
+	if (ret)
+		return ret;
+
+	ret = hfi_create_packet(inst->packet,
+				inst->packet_size,
+				pkt_type,
+				flags,
+				payload_type,
+				port,
+				core->packet_id++,
+				payload,
+				payload_size);
+
+	return ret;
+}
+
+int hfi_packet_session_property(struct iris_inst *inst,
+				u32 pkt_type, u32 flags, u32 port,
+				u32 payload_type, void *payload, u32 payload_size)
+{
+	struct iris_core *core;
+	int ret;
+
+	core = inst->core;
+
+	ret = hfi_create_header(inst->packet, inst->packet_size,
+				inst->session_id, core->header_id++);
+	if (ret)
+		return ret;
+
+	ret = hfi_create_packet(inst->packet, inst->packet_size,
+				pkt_type,
+				flags,
+				payload_type,
+				port,
+				core->packet_id++,
+				payload,
+				payload_size);
+
+	return ret;
+}
+
+int hfi_packet_sys_interframe_powercollapse(struct iris_core *core,
+					    u8 *pkt, u32 pkt_size)
+{
+	u32 payload = 0;
+	int ret;
+
+	ret = hfi_create_header(pkt, pkt_size,
+				0 /*session_id*/,
+				core->header_id++);
+	if (ret)
+		return ret;
+
+	payload = HFI_TRUE;
+
+	ret = hfi_create_packet(pkt, pkt_size,
+				HFI_PROP_INTRA_FRAME_POWER_COLLAPSE,
+				HFI_HOST_FLAGS_NONE,
+				HFI_PAYLOAD_U32,
+				HFI_PORT_NONE,
+				core->packet_id++,
+				&payload,
+				sizeof(u32));
+
+	return ret;
+}
+
+int hfi_packet_sys_pc_prep(struct iris_core *core,
+			   u8 *pkt, u32 pkt_size)
+{
+	int ret;
+
+	ret = hfi_create_header(pkt, pkt_size,
+				0 /*session_id*/,
+				core->header_id++);
+	if (ret)
+		return ret;
+
+	ret = hfi_create_packet(pkt, pkt_size,
+				HFI_CMD_POWER_COLLAPSE,
+				HFI_HOST_FLAGS_NONE,
+				HFI_PAYLOAD_NONE,
+				HFI_PORT_NONE,
+				core->packet_id++,
+				NULL, 0);
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_hfi_packet.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_hfi_packet.h
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_HFI_PACKET_H_
+#define _IRIS_HFI_PACKET_H_
+
+#include "hfi_defines.h"
+#include "iris_core.h"
+#include "iris_instance.h"
+
+struct hfi_header {
+	u32 size;
+	u32 session_id;
+	u32 header_id;
+	u32 reserved[4];
+	u32 num_packets;
+};
+
+struct hfi_packet {
+	u32 size;
+	u32 type;
+	u32 flags;
+	u32 payload_info;
+	u32 port;
+	u32 packet_id;
+	u32 reserved[2];
+};
+
+struct hfi_buffer {
+	u32 type;
+	u32 index;
+	u64 base_address;
+	u32 addr_offset;
+	u32 buffer_size;
+	u32 data_offset;
+	u32 data_size;
+	u64 timestamp;
+	u32 flags;
+	u32 reserved[5];
+};
+
+enum hfi_packet_host_flags {
+	HFI_HOST_FLAGS_NONE			= 0x00000000,
+	HFI_HOST_FLAGS_INTR_REQUIRED		= 0x00000001,
+	HFI_HOST_FLAGS_RESPONSE_REQUIRED	= 0x00000002,
+	HFI_HOST_FLAGS_NON_DISCARDABLE		= 0x00000004,
+	HFI_HOST_FLAGS_GET_PROPERTY		= 0x00000008,
+};
+
+enum hfi_packet_firmware_flags {
+	HFI_FW_FLAGS_NONE		= 0x00000000,
+	HFI_FW_FLAGS_SUCCESS		= 0x00000001,
+	HFI_FW_FLAGS_INFORMATION	= 0x00000002,
+	HFI_FW_FLAGS_SESSION_ERROR	= 0x00000004,
+	HFI_FW_FLAGS_SYSTEM_ERROR	= 0x00000008,
+};
+
+enum hfi_packet_payload_info {
+	HFI_PAYLOAD_NONE	= 0x00000000,
+	HFI_PAYLOAD_U32		= 0x00000001,
+	HFI_PAYLOAD_S32		= 0x00000002,
+	HFI_PAYLOAD_U64		= 0x00000003,
+	HFI_PAYLOAD_S64		= 0x00000004,
+	HFI_PAYLOAD_STRUCTURE	= 0x00000005,
+	HFI_PAYLOAD_BLOB	= 0x00000006,
+	HFI_PAYLOAD_STRING	= 0x00000007,
+	HFI_PAYLOAD_Q16		= 0x00000008,
+	HFI_PAYLOAD_U32_ENUM	= 0x00000009,
+	HFI_PAYLOAD_32_PACKED	= 0x0000000a,
+	HFI_PAYLOAD_U32_ARRAY	= 0x0000000b,
+	HFI_PAYLOAD_S32_ARRAY	= 0x0000000c,
+	HFI_PAYLOAD_64_PACKED	= 0x0000000d,
+};
+
+enum hfi_packet_port_type {
+	HFI_PORT_NONE		= 0x00000000,
+	HFI_PORT_BITSTREAM	= 0x00000001,
+	HFI_PORT_RAW		= 0x00000002,
+};
+
+u32 get_hfi_port_from_buffer_type(struct iris_inst *inst, enum iris_buffer_type buffer_type);
+u32 get_hfi_port(struct iris_inst *inst, u32 plane);
+u32 get_hfi_colorformat(u32 colorformat);
+u32 get_hfi_codec(struct iris_inst *inst);
+u32 get_hfi_color_primaries(u32 primaries);
+u32 get_hfi_transer_char(u32 characterstics);
+u32 get_hfi_matrix_coefficients(u32 coefficients);
+u32 get_v4l2_color_primaries(u32 hfi_primaries);
+u32 get_v4l2_transer_char(u32 hfi_characterstics);
+u32 get_v4l2_matrix_coefficients(u32 hfi_coefficients);
+u32 hfi_buf_type_to_driver(enum domain_type domain, enum hfi_buffer_type buf_type);
+int get_hfi_buffer(struct iris_inst *inst,
+		   struct iris_buffer *buffer, struct hfi_buffer *buf);
+
+int hfi_packet_sys_init(struct iris_core *core,
+			u8 *pkt, u32 pkt_size);
+int hfi_packet_image_version(struct iris_core *core,
+			     u8 *pkt, u32 pkt_size);
+int hfi_packet_session_command(struct iris_inst *inst, u32 pkt_type,
+			       u32 flags, u32 port, u32 session_id,
+			       u32 payload_type, void *payload,
+			       u32 payload_size);
+int hfi_packet_session_property(struct iris_inst *inst,
+				u32 pkt_type, u32 flags, u32 port,
+				u32 payload_type, void *payload, u32 payload_size);
+int hfi_packet_sys_interframe_powercollapse(struct iris_core *core,
+					    u8 *pkt, u32 pkt_size);
+int hfi_packet_sys_pc_prep(struct iris_core *core,
+			   u8 *pkt, u32 pkt_size);
+int hfi_create_header(u8 *packet, u32 packet_size, u32 session_id,
+		      u32 header_id);
+int hfi_create_packet(u8 *packet, u32 packet_size, u32 pkt_type,
+		      u32 pkt_flags, u32 payload_type, u32 port,
+		      u32 packet_id, void *payload, u32 payload_size);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_hfi_queue.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_hfi_queue.c
@@ -0,0 +1,355 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "hfi_defines.h"
+#include "iris_core.h"
+#include "iris_helpers.h"
+#include "iris_hfi_packet.h"
+#include "iris_hfi_queue.h"
+
+static void __set_queue_hdr_defaults(struct hfi_queue_header *q_hdr)
+{
+	q_hdr->qhdr_status = 0x1;
+	q_hdr->qhdr_type = IFACEQ_DFLT_QHDR;
+	q_hdr->qhdr_q_size = IFACEQ_QUEUE_SIZE / 4;
+	q_hdr->qhdr_pkt_size = 0;
+	q_hdr->qhdr_rx_wm = 0x1;
+	q_hdr->qhdr_tx_wm = 0x1;
+	q_hdr->qhdr_rx_req = 0x1;
+	q_hdr->qhdr_tx_req = 0x0;
+	q_hdr->qhdr_rx_irq_status = 0x0;
+	q_hdr->qhdr_tx_irq_status = 0x0;
+	q_hdr->qhdr_read_idx = 0x0;
+	q_hdr->qhdr_write_idx = 0x0;
+}
+
+static int __write_queue(struct iface_q_info *qinfo, void *packet)
+{
+	u32 empty_space, read_idx, write_idx, new_write_idx;
+	struct hfi_queue_header *queue;
+	struct hfi_header *header;
+	u32 packet_size, residue;
+	u32 *write_ptr;
+
+	queue = qinfo->qhdr;
+	if (!queue)
+		return -EINVAL;
+
+	header = packet;
+	packet_size = header->size;
+
+	if (!packet_size || packet_size > qinfo->q_array.size)
+		return -EINVAL;
+
+	read_idx = queue->qhdr_read_idx * sizeof(u32);
+	write_idx = queue->qhdr_write_idx * sizeof(u32);
+
+	empty_space = (write_idx >=  read_idx) ?
+		(qinfo->q_array.size - (write_idx -  read_idx)) :
+		(read_idx - write_idx);
+	if (empty_space <= packet_size) {
+		queue->qhdr_tx_req = 1;
+		return -ENOSPC;
+	}
+
+	queue->qhdr_tx_req =  0;
+
+	new_write_idx = write_idx + packet_size;
+	write_ptr = (u32 *)((u8 *)qinfo->q_array.kernel_vaddr + write_idx);
+
+	if (write_ptr < (u32 *)qinfo->q_array.kernel_vaddr ||
+	    write_ptr > (u32 *)(qinfo->q_array.kernel_vaddr +
+	    qinfo->q_array.size))
+		return -EINVAL;
+
+	if (new_write_idx < qinfo->q_array.size) {
+		memcpy(write_ptr, packet, packet_size);
+	} else {
+		residue = new_write_idx - qinfo->q_array.size;
+		memcpy(write_ptr, packet, (packet_size - residue));
+		memcpy(qinfo->q_array.kernel_vaddr,
+		       packet + (packet_size - residue), residue);
+		new_write_idx = residue;
+	}
+
+	/* Make sure packet is written before updating the write index */
+	mb();
+	queue->qhdr_write_idx = new_write_idx / sizeof(u32);
+
+	/* Make sure write index is updated before an interrupt is raised */
+	mb();
+
+	return 0;
+}
+
+static int __read_queue(struct iface_q_info *qinfo, void *packet)
+{
+	u32 read_idx, write_idx, new_read_idx;
+	struct hfi_queue_header *queue;
+	u32 receive_request = 0;
+	u32 packet_size, residue;
+	u32 *read_ptr;
+	int ret = 0;
+
+	/* Make sure data is valid before reading it */
+	mb();
+	queue = qinfo->qhdr;
+	if (!queue)
+		return -EINVAL;
+
+	if (queue->qhdr_type & IFACEQ_MSGQ_ID)
+		receive_request = 1;
+
+	read_idx = queue->qhdr_read_idx * sizeof(u32);
+	write_idx = queue->qhdr_write_idx * sizeof(u32);
+
+	if (read_idx == write_idx) {
+		queue->qhdr_rx_req = receive_request;
+		/* Ensure qhdr is updated in main memory */
+		mb();
+		return -ENODATA;
+	}
+
+	read_ptr = (u32 *)(qinfo->q_array.kernel_vaddr + read_idx);
+	if (read_ptr < (u32 *)qinfo->q_array.kernel_vaddr ||
+	    read_ptr > (u32 *)(qinfo->q_array.kernel_vaddr +
+	    qinfo->q_array.size - sizeof(*read_ptr)))
+		return -ENODATA;
+
+	packet_size = *read_ptr;
+	if (!packet_size)
+		return -EINVAL;
+
+	new_read_idx = read_idx + packet_size;
+	if (packet_size <= IFACEQ_CORE_PKT_SIZE &&
+	    read_idx <= qinfo->q_array.size) {
+		if (new_read_idx < qinfo->q_array.size) {
+			memcpy(packet, read_ptr, packet_size);
+		} else {
+			residue = new_read_idx - qinfo->q_array.size;
+			memcpy(packet, read_ptr, (packet_size - residue));
+			memcpy((packet + (packet_size - residue)),
+			       qinfo->q_array.kernel_vaddr, residue);
+			new_read_idx = residue;
+		}
+	} else {
+		new_read_idx = write_idx;
+		ret = -EBADMSG;
+	}
+
+	queue->qhdr_rx_req = receive_request;
+
+	queue->qhdr_read_idx = new_read_idx / sizeof(u32);
+	/* Ensure qhdr is updated in main memory */
+	mb();
+
+	return ret;
+}
+
+int iris_hfi_queue_cmd_write(struct iris_core *core, void *pkt)
+{
+	struct iface_q_info *q_info;
+	int ret;
+
+	ret = check_core_lock(core);
+	if (ret)
+		return ret;
+
+	if (!core_in_valid_state(core))
+		return -EINVAL;
+
+	q_info = &core->command_queue;
+	if (!q_info || !q_info->q_array.kernel_vaddr || !pkt) {
+		dev_err(core->dev, "cannot write to shared CMD Q's\n");
+		return -ENODATA;
+	}
+
+	if (!__write_queue(q_info, pkt)) {
+		call_vpu_op(core, raise_interrupt, core);
+	} else {
+		dev_err(core->dev, "queue full\n");
+		return -ENODATA;
+	}
+
+	return ret;
+}
+
+int iris_hfi_queue_msg_read(struct iris_core *core, void *pkt)
+{
+	struct iface_q_info *q_info;
+
+	if (!core_in_valid_state(core))
+		return -EINVAL;
+
+	q_info = &core->message_queue;
+	if (!q_info || !q_info->q_array.kernel_vaddr || !pkt) {
+		dev_err(core->dev, "cannot read from shared MSG Q's\n");
+		return -ENODATA;
+	}
+
+	if (__read_queue(q_info, pkt))
+		return -ENODATA;
+
+	return 0;
+}
+
+int iris_hfi_queue_dbg_read(struct iris_core *core, void *pkt)
+{
+	struct iface_q_info *q_info;
+
+	q_info = &core->debug_queue;
+	if (!q_info || !q_info->q_array.kernel_vaddr || !pkt) {
+		dev_err(core->dev, "cannot read from shared DBG Q's\n");
+		return -ENODATA;
+	}
+
+	if (__read_queue(q_info, pkt))
+		return -ENODATA;
+
+	return 0;
+}
+
+static void iris_hfi_set_queue_header(struct iris_core *core, u32 queue_id,
+				      struct iface_q_info *iface_q)
+{
+	__set_queue_hdr_defaults(iface_q->qhdr);
+	iface_q->qhdr->qhdr_start_addr = iface_q->q_array.device_addr;
+	iface_q->qhdr->qhdr_type |= queue_id;
+
+	/*
+	 * Set receive request to zero on debug queue as there is no
+	 * need of interrupt from video hardware for debug messages
+	 */
+	if (queue_id == IFACEQ_DBGQ_ID)
+		iface_q->qhdr->qhdr_rx_req = 0;
+}
+
+static void __queue_init(struct iris_core *core, u32 queue_id, struct iface_q_info *iface_q)
+{
+	unsigned int offset = 0;
+
+	offset = core->iface_q_table.size + (queue_id * IFACEQ_QUEUE_SIZE);
+	iface_q->q_array.device_addr = core->iface_q_table.device_addr + offset;
+	iface_q->q_array.kernel_vaddr =
+			(void *)((char *)core->iface_q_table.kernel_vaddr + offset);
+	iface_q->q_array.size = IFACEQ_QUEUE_SIZE;
+	iface_q->qhdr =
+		IFACEQ_GET_QHDR_START_ADDR(core->iface_q_table.kernel_vaddr, queue_id);
+
+	iris_hfi_set_queue_header(core, queue_id, iface_q);
+}
+
+int iris_hfi_queue_init(struct iris_core *core)
+{
+	struct hfi_queue_table_header *q_tbl_hdr;
+
+	if (core->iface_q_table.kernel_vaddr) {
+		iris_hfi_set_queue_header(core, IFACEQ_CMDQ_ID, &core->command_queue);
+		iris_hfi_set_queue_header(core, IFACEQ_MSGQ_ID, &core->message_queue);
+		iris_hfi_set_queue_header(core, IFACEQ_DBGQ_ID, &core->debug_queue);
+		return 0;
+	}
+
+	core->iface_q_table.kernel_vaddr = dma_alloc_attrs(core->dev, ALIGNED_QUEUE_SIZE,
+							   &core->iface_q_table.device_addr,
+							   GFP_KERNEL, DMA_ATTR_WRITE_COMBINE);
+	if (!core->iface_q_table.kernel_vaddr) {
+		dev_err(core->dev, "%s: queues alloc and map failed\n", __func__);
+		return -ENOMEM;
+	}
+	core->iface_q_table.size = IFACEQ_TABLE_SIZE;
+
+	__queue_init(core, IFACEQ_CMDQ_ID, &core->command_queue);
+	__queue_init(core, IFACEQ_MSGQ_ID, &core->message_queue);
+	__queue_init(core, IFACEQ_DBGQ_ID, &core->debug_queue);
+
+	q_tbl_hdr = (struct hfi_queue_table_header *)
+			core->iface_q_table.kernel_vaddr;
+	q_tbl_hdr->qtbl_version = 0;
+	q_tbl_hdr->device_addr = (void *)core;
+	strscpy(q_tbl_hdr->name, "iris-hfi-queues", sizeof(q_tbl_hdr->name));
+	q_tbl_hdr->qtbl_size = IFACEQ_TABLE_SIZE;
+	q_tbl_hdr->qtbl_qhdr0_offset = sizeof(*q_tbl_hdr);
+	q_tbl_hdr->qtbl_qhdr_size = sizeof(struct hfi_queue_header);
+	q_tbl_hdr->qtbl_num_q = IFACEQ_NUMQ;
+	q_tbl_hdr->qtbl_num_active_q = IFACEQ_NUMQ;
+
+	core->sfr.kernel_vaddr = dma_alloc_attrs(core->dev, ALIGNED_SFR_SIZE,
+						 &core->sfr.device_addr,
+						 GFP_KERNEL, DMA_ATTR_WRITE_COMBINE);
+	if (!core->sfr.kernel_vaddr) {
+		dev_err(core->dev, "%s: sfr alloc and map failed\n", __func__);
+		return -ENOMEM;
+	}
+	core->sfr.size = ALIGNED_SFR_SIZE;
+	 /* Write sfr size in first word to be used by firmware */
+	*((u32 *)core->sfr.kernel_vaddr) = core->sfr.size;
+
+	return 0;
+}
+
+static void __queue_deinit(struct iface_q_info *iface_q)
+{
+	iface_q->qhdr = NULL;
+	iface_q->q_array.kernel_vaddr = NULL;
+	iface_q->q_array.device_addr = 0;
+}
+
+void iris_hfi_queue_deinit(struct iris_core *core)
+{
+	if (!core->iface_q_table.kernel_vaddr)
+		return;
+
+	dma_free_attrs(core->dev, core->iface_q_table.size, core->iface_q_table.kernel_vaddr,
+		       core->iface_q_table.device_addr, core->iface_q_table.attrs);
+
+	dma_free_attrs(core->dev, core->sfr.size, core->sfr.kernel_vaddr,
+		       core->sfr.device_addr, core->sfr.attrs);
+
+	__queue_deinit(&core->command_queue);
+	__queue_deinit(&core->message_queue);
+	__queue_deinit(&core->debug_queue);
+
+	core->iface_q_table.kernel_vaddr = NULL;
+	core->iface_q_table.device_addr = 0;
+
+	core->sfr.kernel_vaddr = NULL;
+	core->sfr.device_addr = 0;
+}
+
+void iris_flush_debug_queue(struct iris_core *core,
+			    u8 *packet, u32 packet_size)
+{
+	struct hfi_debug_header *pkt;
+	bool local_packet = false;
+	u8 *log;
+
+	if (!packet || !packet_size) {
+		packet = kzalloc(IFACEQ_CORE_PKT_SIZE, GFP_KERNEL);
+		if (!packet)
+			return;
+
+		packet_size = IFACEQ_CORE_PKT_SIZE;
+
+		local_packet = true;
+	}
+
+	while (!iris_hfi_queue_dbg_read(core, packet)) {
+		pkt = (struct hfi_debug_header *)packet;
+
+		if (pkt->size < sizeof(*pkt))
+			continue;
+
+		if (pkt->size >= packet_size)
+			continue;
+
+		packet[pkt->size] = '\0';
+		log = (u8 *)packet + sizeof(*pkt) + 1;
+		dev_dbg(core->dev, "%s", log);
+	}
+
+	if (local_packet)
+		kfree(packet);
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_hfi_queue.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_hfi_queue.h
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_HFI_QUEUE_H_
+#define _IRIS_HFI_QUEUE_H_
+
+struct iris_core;
+
+/*
+ * Shared queues are used for communication between driver and firmware.
+ * There are 3 types of queues:
+ * Command queue - driver to write any command to firmware.
+ * Message queue - firmware to send any response to driver.
+ * Debug queue - firmware to write debug message.
+ */
+
+/* Host-firmware shared queue ids */
+enum iris_iface_queue {
+	IFACEQ_CMDQ_ID	= 0,
+	IFACEQ_MSGQ_ID,
+	IFACEQ_DBGQ_ID,
+	IFACEQ_NUMQ, /* not an index */
+};
+
+#define IFACEQ_MAX_BUF_COUNT		50
+/*
+ * Max session supported are 16.
+ * this value is used to calcualte the size of
+ * individual shared queue.
+ */
+#define IFACE_MAX_PARALLEL_CLNTS	16
+#define IFACEQ_DFLT_QHDR		0x01010000
+
+#define IFACEQ_MAX_PKT_SIZE		1024
+#define IFACEQ_CORE_PKT_SIZE	(1024 * 4)
+
+struct hfi_queue_table_header {
+	u32 qtbl_version;
+	u32 qtbl_size;
+	u32 qtbl_qhdr0_offset;
+	u32 qtbl_qhdr_size;
+	u32 qtbl_num_q;
+	u32 qtbl_num_active_q;
+	void *device_addr;
+	char name[256];
+};
+
+struct hfi_queue_header {
+	u32 qhdr_status;
+	u32 qhdr_start_addr;
+	u32 qhdr_type;
+	u32 qhdr_q_size;
+	u32 qhdr_pkt_size;
+	u32 qhdr_pkt_drop_cnt;
+	u32 qhdr_rx_wm;
+	u32 qhdr_tx_wm;
+	u32 qhdr_rx_req;
+	u32 qhdr_tx_req;
+	u32 qhdr_rx_irq_status;
+	u32 qhdr_tx_irq_status;
+	u32 qhdr_read_idx;
+	u32 qhdr_write_idx;
+};
+
+#define IFACEQ_TABLE_SIZE	(sizeof(struct hfi_queue_table_header) + \
+			sizeof(struct hfi_queue_header) * IFACEQ_NUMQ)
+
+#define IFACEQ_QUEUE_SIZE	(IFACEQ_MAX_PKT_SIZE *  \
+	IFACEQ_MAX_BUF_COUNT * IFACE_MAX_PARALLEL_CLNTS)
+
+#define IFACEQ_GET_QHDR_START_ADDR(ptr, i)     \
+	((void *)(((ptr) + sizeof(struct hfi_queue_table_header)) + \
+		((i) * sizeof(struct hfi_queue_header))))
+
+#define SFR_SIZE	SZ_4K
+#define QUEUE_SIZE	(IFACEQ_TABLE_SIZE + \
+			(IFACEQ_QUEUE_SIZE * IFACEQ_NUMQ))
+
+#define ALIGNED_SFR_SIZE	ALIGN(SFR_SIZE, SZ_4K)
+#define ALIGNED_QUEUE_SIZE	ALIGN(QUEUE_SIZE, SZ_4K)
+#define SHARED_QSIZE		ALIGN(ALIGNED_SFR_SIZE + ALIGNED_QUEUE_SIZE, SZ_1M)
+
+struct mem_desc {
+	dma_addr_t		device_addr;
+	void			*kernel_vaddr;
+	u32				size;
+	unsigned long	attrs;
+};
+
+struct iface_q_info {
+	struct hfi_queue_header *qhdr;
+	struct mem_desc q_array;
+};
+
+int iris_hfi_queue_init(struct iris_core *core);
+void iris_hfi_queue_deinit(struct iris_core *core);
+int iris_hfi_queue_cmd_write(struct iris_core *core, void *pkt);
+int iris_hfi_queue_msg_read(struct iris_core *core, void *pkt);
+int iris_hfi_queue_dbg_read(struct iris_core *core, void *pkt);
+void iris_flush_debug_queue(struct iris_core *core,
+			    u8 *packet, u32 packet_size);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_hfi_response.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_hfi_response.c
@@ -0,0 +1,1061 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "hfi_defines.h"
+#include "iris_buffer.h"
+#include "iris_helpers.h"
+#include "iris_hfi_packet.h"
+#include "iris_hfi_queue.h"
+#include "iris_hfi_response.h"
+#include "iris_vdec.h"
+#include "memory.h"
+
+struct iris_core_hfi_range {
+	u32 begin;
+	u32 end;
+	int (*handle)(struct iris_core *core, struct hfi_packet *pkt);
+};
+
+struct iris_inst_hfi_range {
+	u32 begin;
+	u32 end;
+	int (*handle)(struct iris_inst *inst, struct hfi_packet *pkt);
+};
+
+struct iris_hfi_buffer_handle {
+	enum hfi_buffer_type type;
+	int (*handle)(struct iris_inst *inst, struct hfi_buffer *buffer);
+};
+
+struct iris_hfi_packet_handle {
+	enum hfi_buffer_type type;
+	int (*handle)(struct iris_inst *inst, struct hfi_packet *pkt);
+};
+
+static void print_sfr_message(struct iris_core *core)
+{
+	struct sfr_buffer *vsfr = NULL;
+	u32 vsfr_size = 0;
+	void *p = NULL;
+
+	vsfr = (struct sfr_buffer *)core->sfr.kernel_vaddr;
+	if (vsfr) {
+		if (vsfr->bufsize != core->sfr.size)
+			return;
+		vsfr_size = vsfr->bufsize - sizeof(u32);
+		p = memchr(vsfr->rg_data, '\0', vsfr_size);
+	/* SFR isn't guaranteed to be NULL terminated */
+		if (!p)
+			vsfr->rg_data[vsfr_size - 1] = '\0';
+
+		dev_err(core->dev, "SFR Message from FW: %s\n", vsfr->rg_data);
+	}
+}
+
+static bool is_valid_hfi_buffer_type(u32 buffer_type)
+{
+	if (buffer_type != HFI_BUFFER_BITSTREAM &&
+	    buffer_type != HFI_BUFFER_RAW &&
+	    buffer_type != HFI_BUFFER_BIN &&
+	    buffer_type != HFI_BUFFER_ARP &&
+	    buffer_type != HFI_BUFFER_COMV &&
+	    buffer_type != HFI_BUFFER_NON_COMV &&
+	    buffer_type != HFI_BUFFER_LINE &&
+	    buffer_type != HFI_BUFFER_DPB &&
+	    buffer_type != HFI_BUFFER_PERSIST &&
+	    buffer_type != HFI_BUFFER_VPSS) {
+		return false;
+	}
+
+	return true;
+}
+
+static bool is_valid_hfi_port(u32 port, u32 buffer_type)
+{
+	if (port == HFI_PORT_NONE &&
+	    buffer_type != HFI_BUFFER_ARP &&
+		buffer_type != HFI_BUFFER_PERSIST)
+		return false;
+
+	if (port != HFI_PORT_BITSTREAM && port != HFI_PORT_RAW)
+		return false;
+
+	return true;
+}
+
+static void cache_operation_dqbuf(struct iris_buffer *buf)
+{
+	if  (buf->type == BUF_OUTPUT && buf->dmabuf) {
+		dma_buf_begin_cpu_access(buf->dmabuf, DMA_FROM_DEVICE);
+		dma_buf_end_cpu_access(buf->dmabuf, DMA_FROM_DEVICE);
+	}
+}
+
+static int get_driver_buffer_flags(struct iris_inst *inst, u32 hfi_flags)
+{
+	u32 driver_flags = 0;
+
+	if (inst->hfi_frame_info.picture_type & HFI_PICTURE_IDR)
+		driver_flags |= BUF_FLAG_KEYFRAME;
+	else if (inst->hfi_frame_info.picture_type & HFI_PICTURE_P)
+		driver_flags |= BUF_FLAG_PFRAME;
+	else if (inst->hfi_frame_info.picture_type & HFI_PICTURE_B)
+		driver_flags |= BUF_FLAG_BFRAME;
+	else if (inst->hfi_frame_info.picture_type & HFI_PICTURE_I)
+		driver_flags |= BUF_FLAG_KEYFRAME;
+	else if (inst->hfi_frame_info.picture_type & HFI_PICTURE_CRA)
+		driver_flags |= BUF_FLAG_KEYFRAME;
+	else if (inst->hfi_frame_info.picture_type & HFI_PICTURE_BLA)
+		driver_flags |= BUF_FLAG_KEYFRAME;
+
+	if (inst->hfi_frame_info.data_corrupt)
+		driver_flags |= BUF_FLAG_ERROR;
+
+	if (inst->hfi_frame_info.overflow)
+		driver_flags |= BUF_FLAG_ERROR;
+
+	if ((inst->domain == ENCODER && (hfi_flags & HFI_BUF_FW_FLAG_LAST)) ||
+	    (inst->domain == DECODER && (hfi_flags & HFI_BUF_FW_FLAG_LAST ||
+					 hfi_flags & HFI_BUF_FW_FLAG_PSC_LAST)))
+		driver_flags |= BUF_FLAG_LAST;
+
+	return driver_flags;
+}
+
+static bool validate_packet_payload(struct hfi_packet *pkt)
+{
+	u32 payload_size = 0;
+
+	switch (pkt->payload_info) {
+	case HFI_PAYLOAD_U32:
+	case HFI_PAYLOAD_S32:
+	case HFI_PAYLOAD_Q16:
+	case HFI_PAYLOAD_U32_ENUM:
+	case HFI_PAYLOAD_32_PACKED:
+		payload_size = 4;
+		break;
+	case HFI_PAYLOAD_U64:
+	case HFI_PAYLOAD_S64:
+	case HFI_PAYLOAD_64_PACKED:
+		payload_size = 8;
+		break;
+	case HFI_PAYLOAD_STRUCTURE:
+		if (pkt->type == HFI_CMD_BUFFER)
+			payload_size = sizeof(struct hfi_buffer);
+		break;
+	default:
+		payload_size = 0;
+		break;
+	}
+
+	if (pkt->size < sizeof(struct hfi_packet) + payload_size)
+		return false;
+
+	return true;
+}
+
+static int validate_packet(u8 *response_pkt, u8 *core_resp_pkt, u32 core_resp_pkt_size)
+{
+	u32 response_pkt_size = 0;
+	u8 *response_limit;
+
+	if (!response_pkt || !core_resp_pkt || !core_resp_pkt_size)
+		return -EINVAL;
+
+	response_limit = core_resp_pkt + core_resp_pkt_size;
+
+	if (response_pkt < core_resp_pkt || response_pkt > response_limit)
+		return -EINVAL;
+
+	response_pkt_size = *(u32 *)response_pkt;
+	if (!response_pkt_size)
+		return -EINVAL;
+
+	if (response_pkt_size < sizeof(struct hfi_packet))
+		return -EINVAL;
+
+	if (response_pkt + response_pkt_size > response_limit)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int validate_hdr_packet(struct iris_core *core, struct hfi_header *hdr)
+{
+	struct hfi_packet *packet;
+	int i, ret = 0;
+	u8 *pkt;
+
+	if (hdr->size < sizeof(*hdr) + sizeof(*packet))
+		return -EINVAL;
+
+	pkt = (u8 *)((u8 *)hdr + sizeof(*hdr));
+
+	for (i = 0; i < hdr->num_packets; i++) {
+		packet = (struct hfi_packet *)pkt;
+		ret = validate_packet(pkt, core->response_packet, core->packet_size);
+		if (ret)
+			return ret;
+
+		pkt += packet->size;
+	}
+
+	return ret;
+}
+
+static int handle_session_info(struct iris_inst *inst,
+			       struct hfi_packet *pkt)
+{
+	struct iris_core *core;
+	int ret = 0;
+	char *info;
+
+	core = inst->core;
+
+	switch (pkt->type) {
+	case HFI_INFO_UNSUPPORTED:
+		info = "unsupported";
+		break;
+	case HFI_INFO_DATA_CORRUPT:
+		info = "data corrupt";
+		inst->hfi_frame_info.data_corrupt = 1;
+		break;
+	case HFI_INFO_BUFFER_OVERFLOW:
+		info = "buffer overflow";
+		inst->hfi_frame_info.overflow = 1;
+		break;
+	case HFI_INFO_HFI_FLAG_DRAIN_LAST:
+		info = "drain last flag";
+		ret = iris_inst_sub_state_change_drain_last(inst);
+		break;
+	case HFI_INFO_HFI_FLAG_PSC_LAST:
+		info = "drc last flag";
+		ret = iris_inst_sub_state_change_drc_last(inst);
+		break;
+	default:
+		info = "unknown";
+		break;
+	}
+
+	dev_dbg(core->dev, "session info received %#x: %s\n",
+		pkt->type, info);
+
+	return ret;
+}
+
+static int handle_session_error(struct iris_inst *inst,
+				struct hfi_packet *pkt)
+{
+	struct iris_core *core;
+	char *error;
+
+	core = inst->core;
+
+	switch (pkt->type) {
+	case HFI_ERROR_MAX_SESSIONS:
+		error = "exceeded max sessions";
+		break;
+	case HFI_ERROR_UNKNOWN_SESSION:
+		error = "unknown session id";
+		break;
+	case HFI_ERROR_INVALID_STATE:
+		error = "invalid operation for current state";
+		break;
+	case HFI_ERROR_INSUFFICIENT_RESOURCES:
+		error = "insufficient resources";
+		break;
+	case HFI_ERROR_BUFFER_NOT_SET:
+		error = "internal buffers not set";
+		break;
+	case HFI_ERROR_FATAL:
+		error = "fatal error";
+		break;
+	default:
+		error = "unknown";
+		break;
+	}
+
+	dev_err(core->dev, "session error received %#x: %s\n",
+		pkt->type, error);
+	iris_inst_change_state(inst, IRIS_INST_ERROR);
+
+	return 0;
+}
+
+static int handle_system_error(struct iris_core *core,
+			       struct hfi_packet *pkt)
+{
+	print_sfr_message(core);
+
+	iris_core_deinit(core);
+
+	return 0;
+}
+
+static int handle_system_init(struct iris_core *core,
+			      struct hfi_packet *pkt)
+{
+	if (!(pkt->flags & HFI_FW_FLAGS_SUCCESS))
+		return 0;
+
+	mutex_lock(&core->lock);
+	if (pkt->packet_id != core->sys_init_id)
+		goto unlock;
+
+	iris_change_core_state(core, IRIS_CORE_INIT);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return 0;
+}
+
+static int handle_session_close(struct iris_inst *inst,
+				struct hfi_packet *pkt)
+{
+	signal_session_msg_receipt(inst, SIGNAL_CMD_CLOSE);
+
+	return 0;
+}
+
+static int handle_read_only_buffer(struct iris_inst *inst,
+				   struct iris_buffer *buf)
+{
+	struct iris_buffer *ro_buf, *iter = NULL;
+	bool found = false;
+
+	if (inst->domain != DECODER && inst->domain != ENCODER)
+		return 0;
+
+	list_for_each_entry(iter, &inst->buffers.read_only.list, list) {
+		if (iter->device_addr == buf->device_addr) {
+			found = true;
+			ro_buf = iter;
+			break;
+		}
+	}
+
+	if (!found) {
+		ro_buf = iris_get_buffer_from_pool(inst);
+		if (!ro_buf)
+			return -ENOMEM;
+		ro_buf->index = -1;
+		ro_buf->inst = inst;
+		ro_buf->type = buf->type;
+		ro_buf->fd = buf->fd;
+		ro_buf->dmabuf = buf->dmabuf;
+		ro_buf->device_addr = buf->device_addr;
+		ro_buf->data_offset = buf->data_offset;
+		INIT_LIST_HEAD(&ro_buf->list);
+		list_add_tail(&ro_buf->list, &inst->buffers.read_only.list);
+	}
+	ro_buf->attr |= BUF_ATTR_READ_ONLY;
+
+	return 0;
+}
+
+static int handle_non_read_only_buffer(struct iris_inst *inst,
+				       struct hfi_buffer *buffer)
+{
+	struct iris_buffer *ro_buf;
+
+	if (inst->domain != DECODER && inst->domain != ENCODER)
+		return 0;
+
+	list_for_each_entry(ro_buf, &inst->buffers.read_only.list, list) {
+		if (ro_buf->device_addr == buffer->base_address) {
+			ro_buf->attr &= ~BUF_ATTR_READ_ONLY;
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static int handle_release_output_buffer(struct iris_inst *inst,
+					struct hfi_buffer *buffer)
+{
+	struct iris_buffer *buf, *iter;
+	bool found = false;
+
+	list_for_each_entry(iter, &inst->buffers.read_only.list, list) {
+		if (iter->device_addr == buffer->base_address &&
+		    iter->attr & BUF_ATTR_PENDING_RELEASE) {
+			found = true;
+			buf = iter;
+			break;
+		}
+	}
+	if (!found)
+		return -EINVAL;
+
+	buf->attr &= ~BUF_ATTR_READ_ONLY;
+	buf->attr &= ~BUF_ATTR_PENDING_RELEASE;
+
+	return 0;
+}
+
+static int handle_input_buffer(struct iris_inst *inst,
+			       struct hfi_buffer *buffer)
+{
+	struct iris_buffers *buffers;
+	struct iris_buffer *buf, *iter;
+	bool found;
+
+	buffers = iris_get_buffer_list(inst, BUF_INPUT);
+	if (!buffers)
+		return -EINVAL;
+
+	found = false;
+	list_for_each_entry(iter, &buffers->list, list) {
+		if (iter->index == buffer->index) {
+			found = true;
+			buf = iter;
+			break;
+		}
+	}
+	if (!found)
+		return -EINVAL;
+
+	if (!(buf->attr & BUF_ATTR_QUEUED))
+		return 0;
+
+	buf->data_size = buffer->data_size;
+	buf->attr &= ~BUF_ATTR_QUEUED;
+	buf->attr |= BUF_ATTR_DEQUEUED;
+
+	buf->flags = get_driver_buffer_flags(inst, buffer->flags);
+
+	return 0;
+}
+
+static int handle_output_buffer(struct iris_inst *inst,
+				struct hfi_buffer *hfi_buffer)
+{
+	struct iris_buffer *buf, *iter;
+	struct iris_buffers *buffers;
+	bool found, fatal = false;
+	int ret = 0;
+
+	if (hfi_buffer->flags & HFI_BUF_FW_FLAG_LAST) {
+		ret = iris_inst_sub_state_change_drain_last(inst);
+		if (ret)
+			return ret;
+	}
+
+	if (inst->domain == DECODER) {
+		if (hfi_buffer->flags & HFI_BUF_FW_FLAG_RELEASE_DONE)
+			return handle_release_output_buffer(inst, hfi_buffer);
+
+		if (hfi_buffer->flags & HFI_BUF_FW_FLAG_PSC_LAST) {
+			ret = iris_inst_sub_state_change_drc_last(inst);
+			if (ret)
+				return ret;
+		}
+
+		if (!(hfi_buffer->flags & HFI_BUF_FW_FLAG_READONLY))
+			ret = handle_non_read_only_buffer(inst, hfi_buffer);
+	}
+
+	buffers = iris_get_buffer_list(inst, BUF_OUTPUT);
+	if (!buffers)
+		return -EINVAL;
+
+	found = false;
+	list_for_each_entry(iter, &buffers->list, list) {
+		if (!(iter->attr & BUF_ATTR_QUEUED))
+			continue;
+
+		if (inst->domain == DECODER)
+			found = (iter->index == hfi_buffer->index &&
+				 iter->device_addr == hfi_buffer->base_address &&
+				 iter->data_offset == hfi_buffer->data_offset);
+		else
+			found = iter->index == hfi_buffer->index;
+
+		if (found) {
+			buf = iter;
+			break;
+		}
+	}
+	if (!found)
+		return 0;
+
+	buf->data_offset = hfi_buffer->data_offset;
+	buf->data_size = hfi_buffer->data_size;
+	buf->timestamp = hfi_buffer->timestamp;
+
+	buf->attr &= ~BUF_ATTR_QUEUED;
+	buf->attr |= BUF_ATTR_DEQUEUED;
+
+	if (inst->domain == ENCODER) {
+		if (inst->hfi_frame_info.data_corrupt)
+			fatal = true;
+		if (inst->hfi_frame_info.overflow) {
+			if (!hfi_buffer->data_size && inst->hfi_rc_type == HFI_RC_CBR_CFR)
+				fatal = true;
+		}
+		if (fatal)
+			iris_inst_change_state(inst, IRIS_INST_ERROR);
+	}
+
+	if (inst->domain == DECODER) {
+		if (inst->buffers.dpb.size && hfi_buffer->flags & HFI_BUF_FW_FLAG_READONLY)
+			iris_inst_change_state(inst, IRIS_INST_ERROR);
+
+		if (hfi_buffer->flags & HFI_BUF_FW_FLAG_READONLY) {
+			buf->attr |= BUF_ATTR_READ_ONLY;
+			ret = handle_read_only_buffer(inst, buf);
+		} else {
+			buf->attr &= ~BUF_ATTR_READ_ONLY;
+		}
+	}
+
+	buf->flags = get_driver_buffer_flags(inst, hfi_buffer->flags);
+
+	return ret;
+}
+
+static int handle_dequeue_buffers(struct iris_inst *inst)
+{
+	struct iris_buffers *buffers;
+	struct iris_buffer *dummy;
+	struct iris_buffer *buf;
+	int ret = 0;
+	int i;
+	static const enum iris_buffer_type buffer_type[] = {
+		BUF_INPUT,
+		BUF_OUTPUT,
+	};
+
+	for (i = 0; i < ARRAY_SIZE(buffer_type); i++) {
+		buffers = iris_get_buffer_list(inst, buffer_type[i]);
+		if (!buffers)
+			return -EINVAL;
+
+		list_for_each_entry_safe(buf, dummy, &buffers->list, list) {
+			if (buf->attr & BUF_ATTR_DEQUEUED) {
+				buf->attr &= ~BUF_ATTR_DEQUEUED;
+				if (!(buf->attr & BUF_ATTR_BUFFER_DONE)) {
+					buf->attr |= BUF_ATTR_BUFFER_DONE;
+
+					cache_operation_dqbuf(buf);
+
+					ret = iris_vb2_buffer_done(inst, buf);
+					if (ret)
+						ret = 0;
+				}
+			}
+		}
+	}
+
+	return ret;
+}
+
+static int handle_release_internal_buffer(struct iris_inst *inst,
+					  struct hfi_buffer *buffer)
+{
+	struct iris_buffers *buffers;
+	struct iris_buffer *buf, *iter;
+	int ret = 0;
+	bool found;
+
+	buffers = iris_get_buffer_list(inst, hfi_buf_type_to_driver(inst->domain, buffer->type));
+	if (!buffers)
+		return -EINVAL;
+
+	found = false;
+	list_for_each_entry(iter, &buffers->list, list) {
+		if (iter->device_addr == buffer->base_address) {
+			found = true;
+			buf = iter;
+			break;
+		}
+	}
+	if (!found)
+		return -EINVAL;
+
+	buf->attr &= ~BUF_ATTR_QUEUED;
+
+	if (buf->attr & BUF_ATTR_PENDING_RELEASE)
+		ret = iris_destroy_internal_buffer(inst, buf);
+
+	return ret;
+}
+
+static int handle_session_stop(struct iris_inst *inst,
+			       struct hfi_packet *pkt)
+{
+	int ret = 0;
+	enum signal_session_response signal_type = -1;
+
+	if (inst->domain == DECODER) {
+		if (pkt->port == HFI_PORT_RAW) {
+			signal_type = SIGNAL_CMD_STOP_OUTPUT;
+			ret = iris_inst_sub_state_change_pause(inst, OUTPUT_MPLANE);
+		} else if (pkt->port == HFI_PORT_BITSTREAM) {
+			signal_type = SIGNAL_CMD_STOP_INPUT;
+			ret = iris_inst_sub_state_change_pause(inst, INPUT_MPLANE);
+		}
+	} else if (inst->domain == ENCODER) {
+		if (pkt->port == HFI_PORT_RAW) {
+			signal_type = SIGNAL_CMD_STOP_INPUT;
+			ret = iris_inst_sub_state_change_pause(inst, INPUT_MPLANE);
+		} else if (pkt->port == HFI_PORT_BITSTREAM) {
+			signal_type = SIGNAL_CMD_STOP_OUTPUT;
+			ret = iris_inst_sub_state_change_pause(inst, OUTPUT_MPLANE);
+		}
+	}
+
+	if (signal_type != -1)
+		signal_session_msg_receipt(inst, signal_type);
+
+	return ret;
+}
+
+static int handle_session_buffer(struct iris_inst *inst,
+				 struct hfi_packet *pkt)
+{
+	struct hfi_buffer *buffer;
+	u32 hfi_handle_size = 0;
+	int i, ret = 0;
+	const struct iris_hfi_buffer_handle *hfi_handle_arr = NULL;
+	static const struct iris_hfi_buffer_handle dec_input_hfi_handle[] = {
+		{HFI_BUFFER_BITSTREAM,      handle_input_buffer               },
+		{HFI_BUFFER_BIN,            handle_release_internal_buffer    },
+		{HFI_BUFFER_COMV,           handle_release_internal_buffer    },
+		{HFI_BUFFER_NON_COMV,       handle_release_internal_buffer    },
+		{HFI_BUFFER_LINE,           handle_release_internal_buffer    },
+		{HFI_BUFFER_PERSIST,        handle_release_internal_buffer    },
+	};
+	static const struct iris_hfi_buffer_handle dec_output_hfi_handle[] = {
+		{HFI_BUFFER_RAW,            handle_output_buffer              },
+		{HFI_BUFFER_DPB,            handle_release_internal_buffer    },
+	};
+	static const struct iris_hfi_buffer_handle enc_input_hfi_handle[] = {
+		{HFI_BUFFER_RAW,            handle_input_buffer               },
+		{HFI_BUFFER_VPSS,           handle_release_internal_buffer    },
+	};
+	static const struct iris_hfi_buffer_handle enc_output_hfi_handle[] = {
+		{HFI_BUFFER_BITSTREAM,      handle_output_buffer              },
+		{HFI_BUFFER_BIN,            handle_release_internal_buffer    },
+		{HFI_BUFFER_COMV,           handle_release_internal_buffer    },
+		{HFI_BUFFER_NON_COMV,       handle_release_internal_buffer    },
+		{HFI_BUFFER_LINE,           handle_release_internal_buffer    },
+		{HFI_BUFFER_ARP,            handle_release_internal_buffer    },
+		{HFI_BUFFER_DPB,            handle_release_internal_buffer    },
+	};
+
+
+	if (pkt->payload_info == HFI_PAYLOAD_NONE)
+		return 0;
+
+	if (!validate_packet_payload(pkt)) {
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
+		return 0;
+	}
+
+	buffer = (struct hfi_buffer *)((u8 *)pkt + sizeof(*pkt));
+	if (!is_valid_hfi_buffer_type(buffer->type))
+		return 0;
+
+	if (!is_valid_hfi_port(pkt->port, buffer->type))
+		return 0;
+
+	if (inst->domain == DECODER) {
+		if (pkt->port == HFI_PORT_BITSTREAM) {
+			hfi_handle_size = ARRAY_SIZE(dec_input_hfi_handle);
+			hfi_handle_arr = dec_input_hfi_handle;
+		} else if (pkt->port == HFI_PORT_RAW) {
+			hfi_handle_size = ARRAY_SIZE(dec_output_hfi_handle);
+			hfi_handle_arr = dec_output_hfi_handle;
+		}
+	} else if (inst->domain == ENCODER) {
+		if (pkt->port == HFI_PORT_RAW) {
+			hfi_handle_size = ARRAY_SIZE(enc_input_hfi_handle);
+			hfi_handle_arr = enc_input_hfi_handle;
+		} else if (pkt->port == HFI_PORT_BITSTREAM) {
+			hfi_handle_size = ARRAY_SIZE(enc_output_hfi_handle);
+			hfi_handle_arr = enc_output_hfi_handle;
+		}
+	}
+
+	if (!hfi_handle_arr || !hfi_handle_size)
+		return -EINVAL;
+
+	for (i = 0; i < hfi_handle_size; i++) {
+		if (hfi_handle_arr[i].type == buffer->type) {
+			ret = hfi_handle_arr[i].handle(inst, buffer);
+			if (ret)
+				return ret;
+			break;
+		}
+	}
+
+	if (i == hfi_handle_size)
+		return -EINVAL;
+
+	return ret;
+}
+
+static int handle_session_drain(struct iris_inst *inst,
+				struct hfi_packet *pkt)
+{
+	int ret = 0;
+
+	if (inst->sub_state & IRIS_INST_SUB_DRAIN)
+		ret = iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_INPUT_PAUSE);
+
+	return ret;
+}
+
+static int handle_src_change(struct iris_inst *inst,
+			     struct hfi_packet *pkt)
+{
+	int ret;
+
+	if (pkt->port != HFI_PORT_BITSTREAM)
+		return 0;
+
+	ret = iris_inst_sub_state_change_drc(inst);
+	if (ret)
+		return ret;
+
+	ret = vdec_src_change(inst);
+
+	return ret;
+}
+
+static int handle_session_command(struct iris_inst *inst,
+				  struct hfi_packet *pkt)
+{
+	int i, ret = 0;
+	static const struct iris_hfi_packet_handle hfi_pkt_handle[] = {
+		{HFI_CMD_OPEN,              NULL                    },
+		{HFI_CMD_CLOSE,             handle_session_close    },
+		{HFI_CMD_START,             NULL                    },
+		{HFI_CMD_STOP,              handle_session_stop     },
+		{HFI_CMD_DRAIN,             handle_session_drain    },
+		{HFI_CMD_BUFFER,            handle_session_buffer   },
+		{HFI_CMD_SETTINGS_CHANGE,   handle_src_change       },
+		{HFI_CMD_SUBSCRIBE_MODE,    NULL                    },
+		{HFI_CMD_PAUSE,             NULL                    },
+		{HFI_CMD_RESUME,            NULL                    },
+	};
+
+	for (i = 0; i < ARRAY_SIZE(hfi_pkt_handle); i++) {
+		if (hfi_pkt_handle[i].type == pkt->type) {
+			if (hfi_pkt_handle[i].handle) {
+				ret = hfi_pkt_handle[i].handle(inst, pkt);
+				if (ret)
+					return ret;
+			}
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(hfi_pkt_handle))
+		return -EINVAL;
+
+	return ret;
+}
+
+static int handle_dpb_list_property(struct iris_inst *inst,
+				    struct hfi_packet *pkt)
+{
+	u8 *payload_start;
+	u32 payload_size;
+
+	if (inst->domain != DECODER)
+		return -EINVAL;
+
+	payload_size = pkt->size - sizeof(*pkt);
+	payload_start = (u8 *)((u8 *)pkt + sizeof(*pkt));
+	memset(inst->dpb_list_payload, 0, MAX_DPB_LIST_ARRAY_SIZE);
+
+	if (payload_size > MAX_DPB_LIST_PAYLOAD_SIZE) {
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
+		return -EINVAL;
+	}
+
+	memcpy(inst->dpb_list_payload, payload_start, payload_size);
+
+	return 0;
+}
+
+static int handle_session_property(struct iris_inst *inst,
+				   struct hfi_packet *pkt)
+{
+	u32 *payload_ptr = NULL;
+	int ret = 0;
+
+	if (pkt->flags & HFI_FW_FLAGS_INFORMATION)
+		return 0;
+
+	payload_ptr = (u32 *)((u8 *)pkt + sizeof(*pkt));
+	if (!payload_ptr)
+		return -EINVAL;
+
+	switch (pkt->type) {
+	case HFI_PROP_BITSTREAM_RESOLUTION:
+		inst->src_subcr_params.bitstream_resolution = payload_ptr[0];
+		break;
+	case HFI_PROP_CROP_OFFSETS:
+		inst->src_subcr_params.crop_offsets[0] = payload_ptr[0];
+		inst->src_subcr_params.crop_offsets[1] = payload_ptr[1];
+		break;
+	case HFI_PROP_LUMA_CHROMA_BIT_DEPTH:
+		inst->src_subcr_params.bit_depth = payload_ptr[0];
+		break;
+	case HFI_PROP_CODED_FRAMES:
+		inst->src_subcr_params.coded_frames = payload_ptr[0];
+		break;
+	case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
+		inst->src_subcr_params.fw_min_count = payload_ptr[0];
+		break;
+	case HFI_PROP_PIC_ORDER_CNT_TYPE:
+		inst->src_subcr_params.pic_order_cnt = payload_ptr[0];
+		break;
+	case HFI_PROP_SIGNAL_COLOR_INFO:
+		inst->src_subcr_params.color_info = payload_ptr[0];
+		break;
+	case HFI_PROP_PROFILE:
+		inst->src_subcr_params.profile = payload_ptr[0];
+		break;
+	case HFI_PROP_LEVEL:
+		inst->src_subcr_params.level = payload_ptr[0];
+		break;
+	case HFI_PROP_TIER:
+		inst->src_subcr_params.tier = payload_ptr[0];
+		break;
+	case HFI_PROP_PICTURE_TYPE:
+		inst->hfi_frame_info.picture_type = payload_ptr[0];
+		if (inst->hfi_frame_info.picture_type & HFI_PICTURE_B)
+			inst->has_bframe = true;
+		if (inst->hfi_frame_info.picture_type & HFI_PICTURE_IDR)
+			inst->iframe = true;
+		else
+			inst->iframe = false;
+		break;
+	case HFI_PROP_CABAC_SESSION:
+		if (payload_ptr[0] == 1)
+			inst->cap[ENTROPY_MODE].value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC;
+		else
+			inst->cap[ENTROPY_MODE].value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC;
+		break;
+	case HFI_PROP_DPB_LIST:
+		ret = handle_dpb_list_property(inst, pkt);
+		if (ret)
+			break;
+		break;
+	case HFI_PROP_NO_OUTPUT:
+		inst->hfi_frame_info.no_output = 1;
+		break;
+	case HFI_PROP_QUALITY_MODE:
+	case HFI_PROP_STAGE:
+	case HFI_PROP_PIPE:
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int handle_image_version_property(struct iris_core *core,
+					 struct hfi_packet *pkt)
+{
+	u8 *str_image_version;
+	u32 req_bytes;
+	u32 i = 0;
+
+	req_bytes = pkt->size - sizeof(*pkt);
+	if (req_bytes < IRIS_VERSION_LENGTH - 1)
+		return -EINVAL;
+
+	str_image_version = (u8 *)pkt + sizeof(*pkt);
+
+	for (i = 0; i < IRIS_VERSION_LENGTH - 1; i++) {
+		if (str_image_version[i] != '\0')
+			core->fw_version[i] = str_image_version[i];
+		else
+			core->fw_version[i] = ' ';
+	}
+	core->fw_version[i] = '\0';
+
+	return 0;
+}
+
+static int handle_system_property(struct iris_core *core,
+				  struct hfi_packet *pkt)
+{
+	int ret = 0;
+
+	switch (pkt->type) {
+	case HFI_PROP_IMAGE_VERSION:
+		ret = handle_image_version_property(core, pkt);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static int handle_system_response(struct iris_core *core,
+				  struct hfi_header *hdr)
+{
+	struct hfi_packet *packet;
+	u8 *pkt, *start_pkt;
+	int ret = 0;
+	int i, j;
+	static const struct iris_core_hfi_range be[] = {
+		{HFI_SYSTEM_ERROR_BEGIN,   HFI_SYSTEM_ERROR_END,   handle_system_error     },
+		{HFI_PROP_BEGIN,           HFI_PROP_END,           handle_system_property  },
+		{HFI_CMD_BEGIN,            HFI_CMD_END,            handle_system_init      },
+	};
+
+	start_pkt = (u8 *)((u8 *)hdr + sizeof(*hdr));
+	for (i = 0; i < ARRAY_SIZE(be); i++) {
+		pkt = start_pkt;
+		for (j = 0; j < hdr->num_packets; j++) {
+			packet = (struct hfi_packet *)pkt;
+			if (packet->flags & HFI_FW_FLAGS_SYSTEM_ERROR) {
+				ret = handle_system_error(core, packet);
+				return ret;
+			}
+
+			if (packet->type > be[i].begin && packet->type < be[i].end) {
+				ret = be[i].handle(core, packet);
+				if (ret)
+					return ret;
+
+				if (packet->type >  HFI_SYSTEM_ERROR_BEGIN &&
+				    packet->type < HFI_SYSTEM_ERROR_END)
+					return 0;
+			}
+			pkt += packet->size;
+		}
+	}
+
+	return ret;
+}
+
+static int handle_session_response(struct iris_core *core,
+				   struct hfi_header *hdr)
+{
+	struct hfi_packet *packet;
+	struct iris_inst *inst;
+	bool dequeue = false;
+	u8 *pkt, *start_pkt;
+	int ret = 0;
+	int i, j;
+	static const struct iris_inst_hfi_range be[] = {
+		{HFI_SESSION_ERROR_BEGIN,  HFI_SESSION_ERROR_END,  handle_session_error    },
+		{HFI_INFORMATION_BEGIN,    HFI_INFORMATION_END,    handle_session_info     },
+		{HFI_PROP_BEGIN,           HFI_PROP_END,           handle_session_property },
+		{HFI_CMD_BEGIN,            HFI_CMD_END,            handle_session_command  },
+	};
+
+	inst = to_instance(core, hdr->session_id);
+	if (!inst)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	memset(&inst->hfi_frame_info, 0, sizeof(struct iris_hfi_frame_info));
+
+	pkt = (u8 *)((u8 *)hdr + sizeof(*hdr));
+	for (i = 0; i < hdr->num_packets; i++) {
+		packet = (struct hfi_packet *)pkt;
+		if (packet->type == HFI_CMD_SETTINGS_CHANGE) {
+			if (packet->port == HFI_PORT_BITSTREAM) {
+				vdec_init_src_change_param(inst);
+				break;
+			}
+		}
+		pkt += packet->size;
+	}
+
+	start_pkt = (u8 *)((u8 *)hdr + sizeof(*hdr));
+	for (i = 0; i < ARRAY_SIZE(be); i++) {
+		pkt = start_pkt;
+		for (j = 0; j < hdr->num_packets; j++) {
+			packet = (struct hfi_packet *)pkt;
+			if (packet->flags & HFI_FW_FLAGS_SESSION_ERROR)
+				handle_session_error(inst, packet);
+
+			if (packet->type > be[i].begin && packet->type < be[i].end) {
+				dequeue |= (packet->type == HFI_CMD_BUFFER);
+				ret = be[i].handle(inst, packet);
+				if (ret)
+					iris_inst_change_state(inst, IRIS_INST_ERROR);
+			}
+			pkt += packet->size;
+		}
+	}
+
+	if (dequeue) {
+		ret = handle_dequeue_buffers(inst);
+		if (ret)
+			goto unlock;
+	}
+
+	memset(&inst->hfi_frame_info, 0, sizeof(struct iris_hfi_frame_info));
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int handle_response(struct iris_core *core, void *response)
+{
+	struct hfi_header *hdr;
+	int ret;
+
+	iris_pm_touch(core);
+
+	hdr = (struct hfi_header *)response;
+	ret = validate_hdr_packet(core, hdr);
+	if (ret)
+		return handle_system_error(core, NULL);
+
+	if (!hdr->session_id)
+		return handle_system_response(core, hdr);
+	else
+		return handle_session_response(core, hdr);
+
+	return ret;
+}
+
+int __response_handler(struct iris_core *core)
+{
+	int ret = 0;
+
+	if (call_vpu_op(core, watchdog, core, core->intr_status)) {
+		struct hfi_packet pkt = {.type = HFI_SYS_ERROR_WD_TIMEOUT};
+
+		mutex_lock(&core->lock);
+		iris_change_core_state(core, IRIS_CORE_ERROR);
+		dev_err(core->dev, "%s: CPU WD error received\n", __func__);
+		mutex_unlock(&core->lock);
+
+		return handle_system_error(core, &pkt);
+	}
+
+	memset(core->response_packet, 0, core->packet_size);
+	while (!iris_hfi_queue_msg_read(core, core->response_packet)) {
+		ret = handle_response(core, core->response_packet);
+		if (ret)
+			continue;
+		if (core->state != IRIS_CORE_INIT)
+			break;
+		memset(core->response_packet, 0, core->packet_size);
+	}
+
+	iris_flush_debug_queue(core, core->response_packet, core->packet_size);
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_hfi_response.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_hfi_response.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_HFI_RESPONSE_H_
+#define _IRIS_HFI_RESPONSE_H_
+
+#include "iris_core.h"
+
+struct sfr_buffer {
+	u32 bufsize;
+	u8 rg_data[];
+};
+
+int __response_handler(struct iris_core *core);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_instance.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_instance.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_INSTANCE_H_
+#define _IRIS_INSTANCE_H_
+
+#include <media/v4l2-ctrls.h>
+
+#include "hfi_defines.h"
+#include "iris_buffer.h"
+#include "iris_common.h"
+#include "iris_core.h"
+#include "iris_common.h"
+#include "platform_common.h"
+
+/**
+ * struct iris_inst - holds per video instance parameters
+ *
+ * @list: used for attach an instance to the core
+ * @core: pointer to core structure
+ * @session_id: id of current video session
+ * @vb2q_src: source vb2 queue
+ * @vb2q_dst: destination vb2 queue
+ * @ctx_q_lock: lock to serialize queues related ioctls
+ * @lock: lock to seralise forward and reverse threads
+ * @fh: reference of v4l2 file handler
+ * @fmt_src: structure of v4l2_format for source
+ * @fmt_dst: structure of v4l2_format for destination
+ * @ctrl_handler: reference of v4l2 ctrl handler
+ * @crop: structure of crop info
+ * @compose: structure of compose info
+ * @packet: HFI packet
+ * @packet_size: HFI packet size
+ * @completions: structure of signal completions
+ * @cap: array of supported instance capabilities
+ * @num_ctrls: supported number of controls
+ * @caps_list: list head of capability
+ * @codec: codec type
+ * @domain: domain type: encoder or decoder
+ * @mem_pool: pointer to memory pool of buffers
+ * @buffers: structure of buffer info
+ * @fw_min_count: minimnum count of buffers needed by fw
+ * @state: instance state
+ * @sub_state: instance sub state
+ * @ipsc_properties_set: boolean to set ipsc properties to fw
+ * @opsc_properties_set: boolean to set opsc properties to fw
+ * @hfi_frame_info: structure of frame info
+ * @src_subcr_params: subscription params to fw on input port
+ * @dst_subcr_params: subscription params to fw on output port
+ * @dpb_list_payload: array of dpb buffers
+ * @once_per_session_set: boolean to set once per session property
+ * @max_rate: max input rate
+ * @max_input_data_size: max size of input data
+ * @power: structure of power info
+ * @bus_data: structure of bus data
+ * @input_timer_list: list head of input timer
+ * @ir_enabled: boolean for intra refresh
+ * @hfi_rc_type: rate control type
+ * @hfi_layer_type: type of HFI layer encoding
+ * @has_bframe: boolean to set if bitstream contains B frame
+ * @iframe: boolean to set if bitstream contains I frame
+ */
+
+struct iris_inst {
+	struct list_head		list;
+	struct iris_core		*core;
+	u32				session_id;
+	struct vb2_queue		*vb2q_src;
+	struct vb2_queue		*vb2q_dst;
+	struct mutex			ctx_q_lock;/* lock to serialize queues related ioctls */
+	struct mutex			lock;
+	struct v4l2_fh			fh;
+	struct v4l2_format		*fmt_src;
+	struct v4l2_format		*fmt_dst;
+	struct v4l2_ctrl_handler	ctrl_handler;
+	struct rect_desc		crop;
+	struct rect_desc		compose;
+	void				*packet;
+	u32				packet_size;
+	struct completion		completions[MAX_SIGNAL];
+	struct plat_inst_cap		cap[INST_CAP_MAX + 1];
+	u32				num_ctrls;
+	struct list_head		caps_list;
+	enum codec_type			codec;
+	enum domain_type		domain;
+	struct iris_mem_pool		*mem_pool;
+	struct iris_buffers_info	buffers;
+	u32				fw_min_count;
+	enum iris_inst_state		state;
+	enum iris_inst_sub_state	sub_state;
+	bool				ipsc_properties_set;
+	bool				opsc_properties_set;
+	struct iris_hfi_frame_info	hfi_frame_info;
+	struct subscription_params	src_subcr_params;
+	struct subscription_params	dst_subcr_params;
+	u32				dpb_list_payload[MAX_DPB_LIST_ARRAY_SIZE];
+	bool				once_per_session_set;
+	u32				max_rate;
+	u32				max_input_data_size;
+	struct iris_inst_power		power;
+	struct bus_vote_data		bus_data;
+	struct list_head		input_timer_list;
+	bool				ir_enabled;
+	u32				hfi_rc_type;
+	u32				hfi_layer_type;
+	bool				has_bframe;
+	bool				iframe;
+};
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_power.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_power.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "iris_power.h"
+#include "iris_helpers.h"
+#include "resources.h"
+
+static int iris_set_buses(struct iris_inst *inst)
+{
+	struct iris_inst *instance;
+	struct iris_core *core;
+	u64 total_bw_ddr = 0;
+	int ret;
+
+	core = inst->core;
+
+	mutex_lock(&core->lock);
+	list_for_each_entry(instance, &core->instances, list) {
+		if (!instance->max_input_data_size)
+			continue;
+
+		total_bw_ddr += instance->power.bus_bw;
+	}
+
+	ret = vote_buses(core, total_bw_ddr);
+
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+static int iris_vote_buses(struct iris_inst *inst)
+{
+	struct v4l2_format *out_f, *inp_f;
+	struct bus_vote_data *vote_data;
+	struct iris_core *core;
+
+	core = inst->core;
+
+	vote_data = &inst->bus_data;
+
+	out_f = inst->fmt_dst;
+	inp_f = inst->fmt_src;
+
+	vote_data->width = inp_f->fmt.pix_mp.width;
+	vote_data->height = inp_f->fmt.pix_mp.height;
+	vote_data->fps = inst->max_rate;
+
+	if (inst->domain == ENCODER) {
+		vote_data->color_formats[0] =
+			v4l2_colorformat_to_driver(inst, inst->fmt_src->fmt.pix_mp.pixelformat);
+	} else if (inst->domain == DECODER) {
+		if (is_linear_colorformat(out_f->fmt.pix_mp.pixelformat)) {
+			vote_data->color_formats[0] = V4L2_PIX_FMT_NV12;
+			vote_data->color_formats[1] = out_f->fmt.pix_mp.pixelformat;
+		} else {
+			vote_data->color_formats[0] = out_f->fmt.pix_mp.pixelformat;
+		}
+	}
+
+	call_session_op(core, calc_bw, inst, vote_data);
+
+	inst->power.bus_bw = vote_data->bus_bw;
+
+	return iris_set_buses(inst);
+}
+
+static int iris_set_clocks(struct iris_inst *inst)
+{
+	struct iris_inst *instance;
+	struct iris_core *core;
+	int ret = 0;
+	u64 freq;
+
+	core = inst->core;
+
+	mutex_lock(&core->lock);
+
+	freq = 0;
+	list_for_each_entry(instance, &core->instances, list) {
+		if (!instance->max_input_data_size)
+			continue;
+
+		freq += instance->power.min_freq;
+	}
+
+	core->power.clk_freq = freq;
+
+	ret = opp_set_rate(core, freq);
+
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+static int iris_scale_clocks(struct iris_inst *inst)
+{
+	struct iris_buffer *vbuf;
+	struct iris_core *core;
+	u32 data_size = 0;
+
+	core = inst->core;
+
+	list_for_each_entry(vbuf, &inst->buffers.input.list, list)
+		data_size = max(data_size, vbuf->data_size);
+
+	inst->max_input_data_size = data_size;
+
+	if (inst->domain == ENCODER) {
+		inst->max_rate = max((inst->cap[OPERATING_RATE].value >> 16),
+			(inst->cap[FRAME_RATE].value >> 16));
+	} else if (inst->domain == DECODER) {
+		inst->max_rate = inst->cap[QUEUED_RATE].value >> 16;
+	}
+
+	if (!inst->max_input_data_size)
+		return 0;
+
+	inst->power.min_freq = call_session_op(core, calc_freq, inst,
+					       inst->max_input_data_size);
+	iris_set_clocks(inst);
+
+	return 0;
+}
+
+int iris_scale_power(struct iris_inst *inst)
+{
+	iris_scale_clocks(inst);
+	iris_vote_buses(inst);
+
+	return 0;
+}
+
+int iris_update_input_rate(struct iris_inst *inst, u64 time_us)
+{
+	struct iris_input_timer *prev_timer = NULL;
+	struct iris_input_timer *input_timer;
+	u64 input_timer_sum_us = 0;
+	u64 counter = 0;
+
+	input_timer = kzalloc(sizeof(*input_timer), GFP_KERNEL);
+	if (!input_timer)
+		return -ENOMEM;
+
+	input_timer->time_us = time_us;
+	INIT_LIST_HEAD(&input_timer->list);
+	list_add_tail(&input_timer->list, &inst->input_timer_list);
+	list_for_each_entry(input_timer, &inst->input_timer_list, list) {
+		if (prev_timer) {
+			input_timer_sum_us += input_timer->time_us - prev_timer->time_us;
+			counter++;
+		}
+		prev_timer = input_timer;
+	}
+
+	if (input_timer_sum_us && counter >= INPUT_TIMER_LIST_SIZE)
+		inst->cap[QUEUED_RATE].value =
+			(s32)(DIV64_U64_ROUND_CLOSEST(counter * 1000000,
+				input_timer_sum_us) << 16);
+
+	if (counter >= INPUT_TIMER_LIST_SIZE) {
+		input_timer = list_first_entry(&inst->input_timer_list,
+					       struct iris_input_timer, list);
+		list_del_init(&input_timer->list);
+		kfree(input_timer);
+	}
+
+	return 0;
+}
+
+int iris_flush_input_timer(struct iris_inst *inst)
+{
+	struct iris_input_timer *input_timer, *dummy_timer;
+
+	list_for_each_entry_safe(input_timer, dummy_timer, &inst->input_timer_list, list) {
+		list_del_init(&input_timer->list);
+		kfree(input_timer);
+	}
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_power.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_power.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_POWER_H_
+#define _IRIS_POWER_H_
+
+#include "iris_instance.h"
+
+int iris_scale_power(struct iris_inst *inst);
+int iris_update_input_rate(struct iris_inst *inst, u64 time_us);
+int iris_flush_input_timer(struct iris_inst *inst);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_probe.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_probe.c
@@ -0,0 +1,367 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include "iris_core.h"
+#include "iris_ctrls.h"
+#include "iris_helpers.h"
+#include "iris_hfi.h"
+#include "iris_hfi_queue.h"
+#include "iris_vidc.h"
+#include "resources.h"
+
+static int init_iris_isr(struct iris_core *core)
+{
+	int ret;
+
+	ret = devm_request_threaded_irq(core->dev, core->irq, iris_hfi_isr,
+					iris_hfi_isr_handler, IRQF_TRIGGER_HIGH, "iris", core);
+	if (ret) {
+		dev_err(core->dev, "%s: Failed to allocate iris IRQ\n", __func__);
+		return ret;
+	}
+	disable_irq_nosync(core->irq);
+
+	return ret;
+}
+
+static void iris_unregister_video_device(struct iris_core *core, enum domain_type type)
+{
+	if (type == DECODER)
+		video_unregister_device(core->vdev_dec);
+	else if (type == ENCODER)
+		video_unregister_device(core->vdev_enc);
+}
+
+static int iris_register_video_device(struct iris_core *core, enum domain_type type)
+{
+	struct video_device *vdev;
+	int ret = 0;
+
+	vdev = video_device_alloc();
+	if (!vdev)
+		return -ENOMEM;
+
+	vdev->release = video_device_release;
+	vdev->fops = core->v4l2_file_ops;
+	vdev->vfl_dir = VFL_DIR_M2M;
+	vdev->v4l2_dev = &core->v4l2_dev;
+	vdev->device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING;
+
+	if (type == DECODER) {
+		strscpy(vdev->name, "qcom-iris-decoder", sizeof(vdev->name));
+		vdev->ioctl_ops = core->v4l2_ioctl_ops_dec;
+
+		ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+		if (ret)
+			goto err_vdev_release;
+
+		core->vdev_dec = vdev;
+	} else if (type == ENCODER) {
+		strscpy(vdev->name, "qcom-iris-encoder", sizeof(vdev->name));
+		vdev->ioctl_ops = core->v4l2_ioctl_ops_enc;
+
+		ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
+		if (ret)
+			goto err_vdev_release;
+
+		core->vdev_enc = vdev;
+	}
+
+	video_set_drvdata(vdev, core);
+
+	return ret;
+
+err_vdev_release:
+	video_device_release(vdev);
+
+	return ret;
+}
+
+static void iris_remove(struct platform_device *pdev)
+{
+	struct iris_core *core;
+
+	core = platform_get_drvdata(pdev);
+	if (!core)
+		return;
+
+	iris_pm_get(core);
+
+	iris_core_deinit(core);
+	iris_hfi_queue_deinit(core);
+
+	iris_unregister_video_device(core, DECODER);
+
+	iris_unregister_video_device(core, ENCODER);
+
+	v4l2_device_unregister(&core->v4l2_dev);
+
+	iris_pm_put(core, false);
+
+	mutex_destroy(&core->lock);
+	core->state = IRIS_CORE_DEINIT;
+}
+
+static int iris_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct iris_core *core;
+	u64 dma_mask;
+	int ret;
+
+	core = devm_kzalloc(&pdev->dev, sizeof(*core), GFP_KERNEL);
+	if (!core)
+		return -ENOMEM;
+	core->dev = dev;
+
+	core->state = IRIS_CORE_DEINIT;
+	mutex_init(&core->lock);
+
+	core->packet_size = IFACEQ_CORE_PKT_SIZE;
+	core->packet = devm_kzalloc(core->dev, core->packet_size, GFP_KERNEL);
+	if (!core->packet)
+		return -ENOMEM;
+
+	core->response_packet = devm_kzalloc(core->dev, core->packet_size, GFP_KERNEL);
+	if (!core->response_packet)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&core->instances);
+
+	core->reg_base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(core->reg_base))
+		return PTR_ERR(core->reg_base);
+
+	core->irq = platform_get_irq(pdev, 0);
+	if (core->irq < 0)
+		return core->irq;
+
+	pm_runtime_set_autosuspend_delay(core->dev, AUTOSUSPEND_DELAY_VALUE);
+	pm_runtime_use_autosuspend(core->dev);
+	ret = devm_pm_runtime_enable(core->dev);
+	if (ret) {
+		dev_err(core->dev, "failed to enable runtime pm\n");
+		goto err_runtime_disable;
+	}
+
+	ret = init_iris_isr(core);
+	if (ret) {
+		dev_err_probe(core->dev, ret,
+			      "%s: Failed to init isr with %d\n", __func__, ret);
+		goto err_runtime_disable;
+	}
+
+	ret = init_platform(core);
+	if (ret) {
+		dev_err_probe(core->dev, ret,
+			      "%s: init platform failed with %d\n", __func__, ret);
+		goto err_runtime_disable;
+	}
+
+	ret = init_vpu(core);
+	if (ret) {
+		dev_err_probe(core->dev, ret,
+			      "%s: init vpu failed with %d\n", __func__, ret);
+		goto err_runtime_disable;
+	}
+
+	ret = init_ops(core);
+	if (ret) {
+		dev_err_probe(core->dev, ret,
+			      "%s: init ops failed with %d\n", __func__, ret);
+		goto err_runtime_disable;
+	}
+
+	ret = init_resources(core);
+	if (ret) {
+		dev_err_probe(core->dev, ret,
+			      "%s: init resource failed with %d\n", __func__, ret);
+		goto err_runtime_disable;
+	}
+
+	ret = iris_init_core_caps(core);
+	if (ret) {
+		dev_err_probe(core->dev, ret,
+			      "%s: init core caps failed with %d\n", __func__, ret);
+		goto err_runtime_disable;
+	}
+
+	ret = iris_init_instance_caps(core);
+	if (ret) {
+		dev_err_probe(core->dev, ret,
+			      "%s: init inst caps failed with %d\n", __func__, ret);
+		goto err_runtime_disable;
+	}
+
+	ret = v4l2_device_register(dev, &core->v4l2_dev);
+	if (ret)
+		goto err_runtime_disable;
+
+	ret = iris_register_video_device(core, DECODER);
+	if (ret)
+		goto err_v4l2_unreg;
+
+	ret = iris_register_video_device(core, ENCODER);
+	if (ret)
+		goto err_vdev_unreg_dec;
+
+	platform_set_drvdata(pdev, core);
+
+	dma_mask = core->cap[DMA_MASK].value;
+
+	ret = dma_set_mask_and_coherent(dev, dma_mask);
+	if (ret)
+		goto err_vdev_unreg_enc;
+
+	dma_set_max_seg_size(&pdev->dev, (unsigned int)DMA_BIT_MASK(32));
+	dma_set_seg_boundary(&pdev->dev, (unsigned long)DMA_BIT_MASK(64));
+
+	ret = iris_hfi_queue_init(core);
+	if (ret) {
+		dev_err_probe(core->dev, ret,
+			      "%s: interface queues init failed\n", __func__);
+		goto err_vdev_unreg_enc;
+	}
+
+	ret = iris_pm_get(core);
+	if (ret) {
+		dev_err_probe(core->dev, ret, "%s: failed to get runtime pm\n", __func__);
+		goto err_queue_deinit;
+	}
+
+	ret = iris_core_init(core);
+	if (ret) {
+		dev_err_probe(core->dev, ret, "%s: core init failed\n", __func__);
+		goto err_queue_deinit;
+	}
+
+	ret = iris_pm_put(core, false);
+	if (ret) {
+		pm_runtime_get_noresume(core->dev);
+		dev_err_probe(core->dev, ret, "%s: failed to put runtime pm\n", __func__);
+		goto err_core_deinit;
+	}
+
+	return ret;
+
+err_core_deinit:
+	iris_core_deinit(core);
+err_queue_deinit:
+	iris_hfi_queue_deinit(core);
+err_vdev_unreg_enc:
+	iris_unregister_video_device(core, ENCODER);
+err_vdev_unreg_dec:
+	iris_unregister_video_device(core, DECODER);
+err_v4l2_unreg:
+	v4l2_device_unregister(&core->v4l2_dev);
+err_runtime_disable:
+	pm_runtime_put_noidle(core->dev);
+	pm_runtime_set_suspended(core->dev);
+
+	return ret;
+}
+
+static int iris_pm_suspend(struct device *dev)
+{
+	struct iris_core *core;
+	int ret;
+
+	if (!dev || !dev->driver)
+		return 0;
+
+	core = dev_get_drvdata(dev);
+
+	mutex_lock(&core->lock);
+
+	if (core->num_pending_requests > 0) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (!core_in_valid_state(core)) {
+		ret = 0;
+		goto unlock;
+	}
+
+	if (!core->power_enabled) {
+		ret = 0;
+		goto unlock;
+	}
+
+	ret = iris_hfi_pm_suspend(core);
+
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+static int iris_pm_resume(struct device *dev)
+{
+	struct iris_core *core;
+	int ret;
+
+	if (!dev || !dev->driver)
+		return 0;
+
+	core = dev_get_drvdata(dev);
+
+	if (!core_in_valid_state(core)) {
+		ret = 0;
+		goto exit;
+	}
+
+	if (core->power_enabled) {
+		ret = 0;
+		goto exit;
+	}
+
+	ret = iris_hfi_pm_resume(core);
+
+	iris_pm_touch_unlocked(core);
+
+exit:
+
+	return ret;
+}
+
+static const struct dev_pm_ops iris_pm_ops = {
+	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+				pm_runtime_force_resume)
+	SET_RUNTIME_PM_OPS(iris_pm_suspend, iris_pm_resume, NULL)
+};
+
+static const struct of_device_id iris_dt_match[] = {
+	{
+		.compatible = "qcom,sm8550-iris",
+		.data = &sm8550_data,
+	},
+	{
+		.compatible = "qcom,qcm6490-iris",
+		.data = &qcm6490_data,
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, iris_dt_match);
+
+static struct platform_driver qcom_iris_driver = {
+	.probe = iris_probe,
+	.remove_new = iris_remove,
+	.driver = {
+		.name = "qcom-iris",
+		.of_match_table = iris_dt_match,
+		.pm = &iris_pm_ops,
+	},
+};
+
+module_platform_driver(qcom_iris_driver);
+MODULE_IMPORT_NS(DMA_BUF);
+MODULE_DESCRIPTION("Qualcomm Iris video driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_state.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_state.c
@@ -0,0 +1,453 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "iris_core.h"
+#include "iris_helpers.h"
+#include "iris_state.h"
+
+#define IRIS_STATE(name)[IRIS_CORE_##name] = "CORE_"#name
+
+static const char * const core_state_names[] = {
+	IRIS_STATE(DEINIT),
+	IRIS_STATE(INIT_WAIT),
+	IRIS_STATE(INIT),
+	IRIS_STATE(ERROR),
+};
+
+#undef IRIS_STATE
+
+bool core_in_valid_state(struct iris_core *core)
+{
+	return core->state == IRIS_CORE_INIT ||
+		core->state == IRIS_CORE_INIT_WAIT;
+}
+
+static const char *core_state_name(enum iris_core_state state)
+{
+	if ((unsigned int)state < ARRAY_SIZE(core_state_names))
+		return core_state_names[state];
+
+	return "UNKNOWN_STATE";
+}
+
+static bool iris_allow_core_state_change(struct iris_core *core,
+					 enum iris_core_state req_state)
+{
+	if (core->state == IRIS_CORE_DEINIT)
+		return req_state == IRIS_CORE_INIT_WAIT || req_state == IRIS_CORE_ERROR;
+	else if (core->state == IRIS_CORE_INIT_WAIT)
+		return req_state == IRIS_CORE_INIT || req_state == IRIS_CORE_ERROR;
+	else if (core->state == IRIS_CORE_INIT)
+		return req_state == IRIS_CORE_DEINIT || req_state == IRIS_CORE_ERROR;
+	else if (core->state == IRIS_CORE_ERROR)
+		return req_state == IRIS_CORE_DEINIT;
+
+	dev_warn(core->dev, "core state change %s -> %s is not allowed\n",
+		 core_state_name(core->state), core_state_name(req_state));
+
+	return false;
+}
+
+int iris_change_core_state(struct iris_core *core,
+			   enum iris_core_state request_state)
+{
+	int ret;
+
+	ret = check_core_lock(core);
+	if (ret)
+		return ret;
+
+	if (core->state == request_state)
+		return 0;
+
+	if (!iris_allow_core_state_change(core, request_state))
+		return -EINVAL;
+
+	core->state = request_state;
+
+	return ret;
+}
+
+struct iris_inst_state_change_allow {
+	enum iris_inst_state        from;
+	enum iris_inst_state        to;
+	enum state_change           allow;
+};
+
+static enum state_change iris_allow_inst_state_change(struct iris_inst *inst,
+						      enum iris_inst_state req_state)
+{
+	enum state_change allow = STATE_CHANGE_ALLOW;
+	int cnt;
+	static struct iris_inst_state_change_allow state[] = {
+		/* from, to, allow */
+		{IRIS_INST_OPEN,             IRIS_INST_OPEN,               STATE_CHANGE_IGNORE    },
+		{IRIS_INST_OPEN,             IRIS_INST_INPUT_STREAMING,    STATE_CHANGE_ALLOW     },
+		{IRIS_INST_OPEN,             IRIS_INST_OUTPUT_STREAMING,   STATE_CHANGE_ALLOW     },
+		{IRIS_INST_OPEN,             IRIS_INST_STREAMING,          STATE_CHANGE_DISALLOW  },
+		{IRIS_INST_OPEN,             IRIS_INST_CLOSE,              STATE_CHANGE_ALLOW     },
+		{IRIS_INST_OPEN,             IRIS_INST_ERROR,              STATE_CHANGE_ALLOW     },
+
+		{IRIS_INST_INPUT_STREAMING,  IRIS_INST_OPEN,               STATE_CHANGE_ALLOW     },
+		{IRIS_INST_INPUT_STREAMING,  IRIS_INST_INPUT_STREAMING,    STATE_CHANGE_IGNORE    },
+		{IRIS_INST_INPUT_STREAMING,  IRIS_INST_OUTPUT_STREAMING,   STATE_CHANGE_DISALLOW  },
+		{IRIS_INST_INPUT_STREAMING,  IRIS_INST_STREAMING,          STATE_CHANGE_ALLOW     },
+		{IRIS_INST_INPUT_STREAMING,  IRIS_INST_CLOSE,              STATE_CHANGE_ALLOW     },
+		{IRIS_INST_INPUT_STREAMING,  IRIS_INST_ERROR,              STATE_CHANGE_ALLOW     },
+
+		{IRIS_INST_OUTPUT_STREAMING, IRIS_INST_OPEN,               STATE_CHANGE_ALLOW     },
+		{IRIS_INST_OUTPUT_STREAMING, IRIS_INST_INPUT_STREAMING,    STATE_CHANGE_DISALLOW  },
+		{IRIS_INST_OUTPUT_STREAMING, IRIS_INST_OUTPUT_STREAMING,   STATE_CHANGE_IGNORE    },
+		{IRIS_INST_OUTPUT_STREAMING, IRIS_INST_STREAMING,          STATE_CHANGE_ALLOW     },
+		{IRIS_INST_OUTPUT_STREAMING, IRIS_INST_CLOSE,              STATE_CHANGE_ALLOW     },
+		{IRIS_INST_OUTPUT_STREAMING, IRIS_INST_ERROR,              STATE_CHANGE_ALLOW     },
+
+		{IRIS_INST_STREAMING,        IRIS_INST_OPEN,               STATE_CHANGE_DISALLOW  },
+		{IRIS_INST_STREAMING,        IRIS_INST_INPUT_STREAMING,    STATE_CHANGE_ALLOW     },
+		{IRIS_INST_STREAMING,        IRIS_INST_OUTPUT_STREAMING,   STATE_CHANGE_ALLOW     },
+		{IRIS_INST_STREAMING,        IRIS_INST_STREAMING,          STATE_CHANGE_IGNORE    },
+		{IRIS_INST_STREAMING,        IRIS_INST_CLOSE,              STATE_CHANGE_ALLOW     },
+		{IRIS_INST_STREAMING,        IRIS_INST_ERROR,              STATE_CHANGE_ALLOW     },
+
+		{IRIS_INST_CLOSE,            IRIS_INST_OPEN,               STATE_CHANGE_DISALLOW  },
+		{IRIS_INST_CLOSE,            IRIS_INST_INPUT_STREAMING,    STATE_CHANGE_DISALLOW  },
+		{IRIS_INST_CLOSE,            IRIS_INST_OUTPUT_STREAMING,   STATE_CHANGE_DISALLOW  },
+		{IRIS_INST_CLOSE,            IRIS_INST_STREAMING,          STATE_CHANGE_DISALLOW  },
+		{IRIS_INST_CLOSE,            IRIS_INST_CLOSE,              STATE_CHANGE_IGNORE    },
+		{IRIS_INST_CLOSE,            IRIS_INST_ERROR,              STATE_CHANGE_IGNORE    },
+
+		{IRIS_INST_ERROR,            IRIS_INST_OPEN,               STATE_CHANGE_IGNORE    },
+		{IRIS_INST_ERROR,            IRIS_INST_INPUT_STREAMING,    STATE_CHANGE_IGNORE    },
+		{IRIS_INST_ERROR,            IRIS_INST_OUTPUT_STREAMING,   STATE_CHANGE_IGNORE    },
+		{IRIS_INST_ERROR,            IRIS_INST_STREAMING,          STATE_CHANGE_IGNORE    },
+		{IRIS_INST_ERROR,            IRIS_INST_CLOSE,              STATE_CHANGE_IGNORE    },
+		{IRIS_INST_ERROR,            IRIS_INST_ERROR,              STATE_CHANGE_IGNORE    },
+	};
+
+	for (cnt = 0; cnt < ARRAY_SIZE(state); cnt++) {
+		if (state[cnt].from == inst->state && state[cnt].to == req_state) {
+			allow = state[cnt].allow;
+			break;
+		}
+	}
+
+	return allow;
+}
+
+int iris_inst_change_state(struct iris_inst *inst,
+			   enum iris_inst_state request_state)
+{
+	enum state_change allow;
+
+	if (IS_SESSION_ERROR(inst))
+		return 0;
+
+	if (inst->state == request_state)
+		return 0;
+
+	allow = iris_allow_inst_state_change(inst, request_state);
+	if (allow != STATE_CHANGE_ALLOW)
+		return (allow == STATE_CHANGE_DISALLOW ? -EINVAL : 0);
+
+	inst->state = request_state;
+
+	return 0;
+}
+
+bool allow_s_fmt(struct iris_inst *inst, u32 type)
+{
+	return (inst->state == IRIS_INST_OPEN) ||
+		(type == OUTPUT_MPLANE && inst->state == IRIS_INST_INPUT_STREAMING) ||
+		(type == INPUT_MPLANE && inst->state == IRIS_INST_OUTPUT_STREAMING);
+}
+
+bool allow_reqbufs(struct iris_inst *inst, u32 type)
+{
+	return (inst->state == IRIS_INST_OPEN) ||
+		(type == OUTPUT_MPLANE && inst->state == IRIS_INST_INPUT_STREAMING) ||
+		(type == INPUT_MPLANE && inst->state == IRIS_INST_OUTPUT_STREAMING);
+}
+
+bool allow_qbuf(struct iris_inst *inst, u32 type)
+{
+	return (type == INPUT_MPLANE && inst->state == IRIS_INST_INPUT_STREAMING) ||
+		(type == INPUT_MPLANE && inst->state == IRIS_INST_STREAMING) ||
+		(type == OUTPUT_MPLANE && inst->state == IRIS_INST_OUTPUT_STREAMING) ||
+		(type == OUTPUT_MPLANE && inst->state == IRIS_INST_STREAMING);
+}
+
+bool allow_streamon(struct iris_inst *inst, u32 type)
+{
+	return (type == INPUT_MPLANE && inst->state == IRIS_INST_OPEN) ||
+		(type == INPUT_MPLANE && inst->state == IRIS_INST_OUTPUT_STREAMING) ||
+		(type == OUTPUT_MPLANE && inst->state == IRIS_INST_OPEN) ||
+		(type == OUTPUT_MPLANE && inst->state == IRIS_INST_INPUT_STREAMING);
+}
+
+bool allow_streamoff(struct iris_inst *inst, u32 type)
+{
+	return (type == INPUT_MPLANE && inst->state == IRIS_INST_INPUT_STREAMING) ||
+		(type == INPUT_MPLANE && inst->state == IRIS_INST_STREAMING) ||
+		(type == OUTPUT_MPLANE && inst->state == IRIS_INST_OUTPUT_STREAMING) ||
+		(type == OUTPUT_MPLANE && inst->state == IRIS_INST_STREAMING);
+}
+
+bool allow_s_ctrl(struct iris_inst *inst, u32 cap_id)
+{
+	return ((inst->state == IRIS_INST_OPEN) ||
+		((inst->cap[cap_id].flags & CAP_FLAG_DYNAMIC_ALLOWED) &&
+		 ((inst->state == IRIS_INST_INPUT_STREAMING && inst->domain == DECODER) ||
+		  (inst->state == IRIS_INST_OUTPUT_STREAMING && inst->domain == ENCODER) ||
+		  (inst->state == IRIS_INST_STREAMING))));
+}
+
+int iris_inst_state_change_streamon(struct iris_inst *inst, u32 plane)
+{
+	enum iris_inst_state new_state = IRIS_INST_ERROR;
+
+	if (plane == INPUT_MPLANE) {
+		if (inst->state == IRIS_INST_OPEN)
+			new_state = IRIS_INST_INPUT_STREAMING;
+		else if (inst->state == IRIS_INST_OUTPUT_STREAMING)
+			new_state = IRIS_INST_STREAMING;
+	} else if (plane == OUTPUT_MPLANE) {
+		if (inst->state == IRIS_INST_OPEN)
+			new_state = IRIS_INST_OUTPUT_STREAMING;
+		else if (inst->state == IRIS_INST_INPUT_STREAMING)
+			new_state = IRIS_INST_STREAMING;
+	}
+
+	return iris_inst_change_state(inst, new_state);
+}
+
+int iris_inst_state_change_streamoff(struct iris_inst *inst, u32 plane)
+{
+	enum iris_inst_state new_state = IRIS_INST_ERROR;
+
+	if (plane == INPUT_MPLANE) {
+		if (inst->state == IRIS_INST_INPUT_STREAMING)
+			new_state = IRIS_INST_OPEN;
+		else if (inst->state == IRIS_INST_STREAMING)
+			new_state = IRIS_INST_OUTPUT_STREAMING;
+	} else if (plane == OUTPUT_MPLANE) {
+		if (inst->state == IRIS_INST_OUTPUT_STREAMING)
+			new_state = IRIS_INST_OPEN;
+		else if (inst->state == IRIS_INST_STREAMING)
+			new_state = IRIS_INST_INPUT_STREAMING;
+	}
+
+	return iris_inst_change_state(inst, new_state);
+}
+
+struct iris_inst_sub_state_change_allow {
+	enum iris_inst_state state;
+	enum state_change allow;
+	u32 sub_state_mask;
+};
+
+static int iris_inst_allow_sub_state(struct iris_inst *inst, enum iris_inst_sub_state sub_state)
+{
+	int i;
+	static struct iris_inst_sub_state_change_allow sub_state_allow[] = {
+		{IRIS_INST_OPEN,              STATE_CHANGE_DISALLOW,    IRIS_INST_SUB_DRC         |
+									IRIS_INST_SUB_DRAIN       |
+									IRIS_INST_SUB_DRC_LAST    |
+									IRIS_INST_SUB_DRAIN_LAST  |
+									IRIS_INST_SUB_INPUT_PAUSE |
+									IRIS_INST_SUB_OUTPUT_PAUSE},
+
+		{IRIS_INST_INPUT_STREAMING,   STATE_CHANGE_DISALLOW,    IRIS_INST_SUB_DRC_LAST    |
+									IRIS_INST_SUB_DRAIN_LAST  |
+									IRIS_INST_SUB_OUTPUT_PAUSE},
+
+		{IRIS_INST_INPUT_STREAMING,   STATE_CHANGE_ALLOW,       IRIS_INST_SUB_DRC         |
+									IRIS_INST_SUB_DRAIN       |
+									IRIS_INST_SUB_INPUT_PAUSE },
+
+		{IRIS_INST_OUTPUT_STREAMING,  STATE_CHANGE_DISALLOW,    IRIS_INST_SUB_DRC         |
+									IRIS_INST_SUB_DRAIN       |
+									IRIS_INST_SUB_INPUT_PAUSE },
+
+		{IRIS_INST_OUTPUT_STREAMING,  STATE_CHANGE_ALLOW,       IRIS_INST_SUB_DRC_LAST    |
+									IRIS_INST_SUB_DRAIN_LAST  |
+									IRIS_INST_SUB_OUTPUT_PAUSE},
+
+		{IRIS_INST_STREAMING,         STATE_CHANGE_ALLOW,       IRIS_INST_SUB_DRC         |
+									IRIS_INST_SUB_DRAIN       |
+									IRIS_INST_SUB_DRC_LAST    |
+									IRIS_INST_SUB_DRAIN_LAST  |
+									IRIS_INST_SUB_INPUT_PAUSE |
+									IRIS_INST_SUB_OUTPUT_PAUSE},
+
+		{IRIS_INST_CLOSE,             STATE_CHANGE_ALLOW,       IRIS_INST_SUB_DRC         |
+									IRIS_INST_SUB_DRAIN       |
+									IRIS_INST_SUB_DRC_LAST    |
+									IRIS_INST_SUB_DRAIN_LAST  |
+									IRIS_INST_SUB_INPUT_PAUSE |
+									IRIS_INST_SUB_OUTPUT_PAUSE},
+
+		{IRIS_INST_ERROR,             STATE_CHANGE_ALLOW,       IRIS_INST_SUB_DRC         |
+									IRIS_INST_SUB_DRAIN       |
+									IRIS_INST_SUB_DRC_LAST    |
+									IRIS_INST_SUB_DRAIN_LAST  |
+									IRIS_INST_SUB_INPUT_PAUSE |
+									IRIS_INST_SUB_OUTPUT_PAUSE},
+	};
+
+	if (!sub_state)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(sub_state_allow); i++) {
+		if (sub_state_allow[i].state != inst->state)
+			continue;
+
+		if (sub_state_allow[i].allow == STATE_CHANGE_DISALLOW)
+			if (sub_state_allow[i].sub_state_mask & sub_state) {
+				dev_dbg(inst->core->dev, "state %d with disallowed sub state %x\n",
+					inst->state, sub_state);
+				return -EINVAL;
+			}
+
+		if (sub_state_allow[i].allow == STATE_CHANGE_ALLOW) {
+			if ((sub_state_allow[i].sub_state_mask & sub_state) != sub_state)
+				return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+int iris_inst_change_sub_state(struct iris_inst *inst,
+			       enum iris_inst_sub_state clear_sub_state,
+			       enum iris_inst_sub_state set_sub_state)
+{
+	enum iris_inst_sub_state prev_sub_state;
+	int ret;
+
+	if (IS_SESSION_ERROR(inst))
+		return 0;
+
+	if (!clear_sub_state && !set_sub_state)
+		return 0;
+
+	if ((clear_sub_state & set_sub_state) ||
+	    set_sub_state > IRIS_INST_MAX_SUB_STATE_VALUE ||
+	    clear_sub_state > IRIS_INST_MAX_SUB_STATE_VALUE)
+		return -EINVAL;
+
+	prev_sub_state = inst->sub_state;
+
+	ret = iris_inst_allow_sub_state(inst, set_sub_state);
+	if (ret)
+		return ret;
+
+	inst->sub_state |= set_sub_state;
+	inst->sub_state &= ~clear_sub_state;
+
+	if (inst->sub_state != prev_sub_state)
+		dev_dbg(inst->core->dev, "state %d and sub state changed to %x\n",
+			inst->sub_state, inst->sub_state);
+
+	return 0;
+}
+
+int iris_inst_sub_state_change_drc(struct iris_inst *inst)
+{
+	enum iris_inst_sub_state set_sub_state = 0;
+
+	if (inst->sub_state & IRIS_INST_SUB_DRC)
+		return STATE_CHANGE_DISALLOW;
+
+	if (inst->state == IRIS_INST_INPUT_STREAMING ||
+	    inst->state == IRIS_INST_OPEN)
+		set_sub_state = IRIS_INST_SUB_INPUT_PAUSE;
+	else
+		set_sub_state = IRIS_INST_SUB_DRC | IRIS_INST_SUB_INPUT_PAUSE;
+
+	return iris_inst_change_sub_state(inst, 0, set_sub_state);
+}
+
+int iris_inst_sub_state_change_drain_last(struct iris_inst *inst)
+{
+	enum iris_inst_sub_state set_sub_state = IRIS_INST_SUB_NONE;
+
+	if (inst->sub_state & IRIS_INST_SUB_DRAIN_LAST)
+		return STATE_CHANGE_DISALLOW;
+
+	if (!(inst->sub_state & IRIS_INST_SUB_DRAIN) ||
+	    !(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE))
+		return STATE_CHANGE_DISALLOW;
+
+	set_sub_state = IRIS_INST_SUB_DRAIN_LAST | IRIS_INST_SUB_OUTPUT_PAUSE;
+
+	return iris_inst_change_sub_state(inst, 0, set_sub_state);
+}
+
+int iris_inst_sub_state_change_drc_last(struct iris_inst *inst)
+{
+	enum iris_inst_sub_state set_sub_state = IRIS_INST_SUB_NONE;
+
+	if (inst->sub_state & IRIS_INST_SUB_DRC_LAST)
+		return STATE_CHANGE_DISALLOW;
+
+	if (!(inst->sub_state & IRIS_INST_SUB_DRC) ||
+	    !(inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE))
+		return STATE_CHANGE_DISALLOW;
+
+	set_sub_state = IRIS_INST_SUB_DRC_LAST | IRIS_INST_SUB_OUTPUT_PAUSE;
+
+	return iris_inst_change_sub_state(inst, 0, set_sub_state);
+}
+
+int iris_inst_sub_state_change_pause(struct iris_inst *inst, u32 plane)
+{
+	enum iris_inst_sub_state set_sub_state = IRIS_INST_SUB_NONE;
+
+	if (plane == INPUT_MPLANE) {
+		if (inst->sub_state & IRIS_INST_SUB_DRC &&
+		    !(inst->sub_state & IRIS_INST_SUB_DRC_LAST))
+			return STATE_CHANGE_DISALLOW;
+
+		if (inst->sub_state & IRIS_INST_SUB_DRAIN &&
+		    !(inst->sub_state & IRIS_INST_SUB_DRAIN_LAST))
+			return STATE_CHANGE_DISALLOW;
+
+		set_sub_state = IRIS_INST_SUB_INPUT_PAUSE;
+	} else {
+		set_sub_state = IRIS_INST_SUB_OUTPUT_PAUSE;
+	}
+
+	return iris_inst_change_sub_state(inst, 0, set_sub_state);
+}
+
+bool is_drc_pending(struct iris_inst *inst)
+{
+	return inst->sub_state & IRIS_INST_SUB_DRC &&
+		inst->sub_state & IRIS_INST_SUB_DRC_LAST;
+}
+
+bool is_drain_pending(struct iris_inst *inst)
+{
+	return inst->sub_state & IRIS_INST_SUB_DRAIN &&
+		inst->sub_state & IRIS_INST_SUB_DRAIN_LAST;
+}
+
+bool allow_cmd(struct iris_inst *inst, u32 cmd)
+{
+	if (cmd == V4L2_DEC_CMD_START) {
+		if (inst->state == IRIS_INST_INPUT_STREAMING ||
+		    inst->state == IRIS_INST_OUTPUT_STREAMING ||
+		    inst->state == IRIS_INST_STREAMING)
+			if (is_drc_pending(inst) || is_drain_pending(inst))
+				return true;
+	} else if (cmd == V4L2_DEC_CMD_STOP) {
+		if (inst->state == IRIS_INST_INPUT_STREAMING ||
+		    inst->state == IRIS_INST_STREAMING)
+			if (inst->sub_state != IRIS_INST_SUB_DRAIN)
+				return true;
+	}
+
+	return false;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_state.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_state.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_STATE_H_
+#define _IRIS_STATE_H_
+
+struct iris_core;
+struct iris_inst;
+
+enum iris_core_state {
+	IRIS_CORE_DEINIT,
+	IRIS_CORE_INIT_WAIT,
+	IRIS_CORE_INIT,
+	IRIS_CORE_ERROR,
+};
+
+enum iris_inst_state {
+	IRIS_INST_OPEN,
+	IRIS_INST_INPUT_STREAMING,
+	IRIS_INST_OUTPUT_STREAMING,
+	IRIS_INST_STREAMING,
+	IRIS_INST_CLOSE,
+	IRIS_INST_ERROR,
+};
+
+#define IRIS_INST_SUB_NONE		0
+#define IRIS_INST_SUB_STATES		6
+#define IRIS_INST_MAX_SUB_STATE_VALUE	((1 << IRIS_INST_SUB_STATES) - 1)
+
+enum iris_inst_sub_state {
+	IRIS_INST_SUB_DRAIN		= BIT(0),
+	IRIS_INST_SUB_DRC		= BIT(1),
+	IRIS_INST_SUB_DRAIN_LAST	= BIT(2),
+	IRIS_INST_SUB_DRC_LAST		= BIT(3),
+	IRIS_INST_SUB_INPUT_PAUSE	= BIT(4),
+	IRIS_INST_SUB_OUTPUT_PAUSE	= BIT(5),
+};
+
+enum state_change {
+	STATE_CHANGE_ALLOW,
+	STATE_CHANGE_DISALLOW,
+	STATE_CHANGE_IGNORE,
+};
+
+#define IS_SESSION_ERROR(inst) \
+((inst)->state == IRIS_INST_ERROR)
+
+bool core_in_valid_state(struct iris_core *core);
+int iris_change_core_state(struct iris_core *core,
+			   enum iris_core_state request_state);
+
+int iris_inst_change_state(struct iris_inst *inst,
+			   enum iris_inst_state request_state);
+int iris_inst_change_sub_state(struct iris_inst *inst,
+			       enum iris_inst_sub_state clear_sub_state,
+			       enum iris_inst_sub_state set_sub_state);
+
+bool allow_s_fmt(struct iris_inst *inst, u32 type);
+bool allow_reqbufs(struct iris_inst *inst, u32 type);
+bool allow_qbuf(struct iris_inst *inst, u32 type);
+bool allow_streamon(struct iris_inst *inst, u32 type);
+bool allow_streamoff(struct iris_inst *inst, u32 type);
+bool allow_s_ctrl(struct iris_inst *inst, u32 cap_id);
+
+int iris_inst_state_change_streamon(struct iris_inst *inst, u32 plane);
+int iris_inst_state_change_streamoff(struct iris_inst *inst, u32 plane);
+
+int iris_inst_sub_state_change_drc(struct iris_inst *inst);
+int iris_inst_sub_state_change_drain_last(struct iris_inst *inst);
+int iris_inst_sub_state_change_drc_last(struct iris_inst *inst);
+int iris_inst_sub_state_change_pause(struct iris_inst *inst, u32 plane);
+bool is_drc_pending(struct iris_inst *inst);
+bool is_drain_pending(struct iris_inst *inst);
+bool allow_cmd(struct iris_inst *inst, u32 cmd);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_vb2.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_vb2.c
@@ -0,0 +1,457 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "iris_buffer.h"
+#include "iris_ctrls.h"
+#include "iris_core.h"
+#include "iris_ctrls.h"
+#include "iris_helpers.h"
+#include "iris_hfi.h"
+#include "iris_instance.h"
+#include "iris_power.h"
+#include "iris_vb2.h"
+#include "iris_vdec.h"
+#include "iris_venc.h"
+
+int iris_vb2_queue_setup(struct vb2_queue *q,
+			 unsigned int *num_buffers, unsigned int *num_planes,
+			 unsigned int sizes[], struct device *alloc_devs[])
+{
+	enum iris_buffer_type buffer_type = 0;
+	struct iris_buffers *buffers;
+	struct iris_inst *inst;
+	struct iris_core *core;
+	struct v4l2_format *f;
+	int ret;
+
+	if (!q || !num_buffers || !num_planes || !sizes)
+		return -EINVAL;
+
+	inst = vb2_get_drv_priv(q);
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	core = inst->core;
+
+	if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
+		f = inst->fmt_src;
+	else
+		f = inst->fmt_dst;
+
+	if (inst->state == IRIS_INST_STREAMING)
+		return -EINVAL;
+
+	if (*num_planes) {
+		if (*num_planes != f->fmt.pix_mp.num_planes ||
+		    sizes[0] < f->fmt.pix_mp.plane_fmt[0].sizeimage)
+			return -EINVAL;
+	}
+
+	buffer_type = v4l2_type_to_driver(q->type);
+	if (!buffer_type)
+		return -EINVAL;
+
+	if (list_empty(&inst->caps_list)) {
+		ret = prepare_dependency_list(inst);
+		if (ret)
+			return ret;
+	}
+
+	if ((inst->domain == DECODER && q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ||
+	    (inst->domain == ENCODER && q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) {
+		ret = adjust_v4l2_properties(inst);
+		if (ret)
+			return ret;
+	}
+
+	ret = check_session_supported(inst);
+	if (ret)
+		return ret;
+
+	ret = iris_free_buffers(inst, buffer_type);
+	if (ret)
+		return ret;
+
+	buffers = iris_get_buffer_list(inst, buffer_type);
+	if (!buffers)
+		return -EINVAL;
+
+	buffers->min_count = iris_get_buf_min_count(inst, buffer_type);
+	if (*num_buffers < buffers->min_count)
+		*num_buffers = buffers->min_count;
+	buffers->actual_count = *num_buffers;
+	*num_planes = 1;
+
+	buffers->size = iris_get_buffer_size(inst, buffer_type);
+
+	f->fmt.pix_mp.plane_fmt[0].sizeimage = buffers->size;
+	sizes[0] = f->fmt.pix_mp.plane_fmt[0].sizeimage;
+
+	ret = iris_allocate_buffers(inst, buffer_type, *num_buffers);
+
+	q->dev = core->dev;
+
+	return ret;
+}
+
+int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count)
+{
+	enum iris_buffer_type buf_type;
+	struct iris_inst *inst;
+	int ret = 0;
+
+	if (!q)
+		return -EINVAL;
+
+	inst = vb2_get_drv_priv(q);
+	if (!inst || !inst->core)
+		return -EINVAL;
+
+	if (q->type != INPUT_MPLANE && q->type != OUTPUT_MPLANE) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	if (inst->domain != DECODER && inst->domain != ENCODER) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = iris_pm_get(inst->core);
+	if (ret)
+		goto error;
+
+	if (!inst->once_per_session_set) {
+		inst->once_per_session_set = true;
+		ret = iris_hfi_session_set_codec(inst);
+		if (ret)
+			goto err_pm_get;
+
+		if (inst->domain == ENCODER)  {
+			ret = iris_alloc_and_queue_session_int_bufs(inst, BUF_ARP);
+			if (ret)
+				goto err_pm_get;
+		} else if (inst->domain == DECODER) {
+			ret = iris_hfi_session_set_default_header(inst);
+			if (ret)
+				goto err_pm_get;
+
+			ret = iris_alloc_and_queue_session_int_bufs(inst, BUF_PERSIST);
+			if (ret)
+				goto err_pm_get;
+		}
+	}
+
+	iris_scale_power(inst);
+
+	if (q->type == INPUT_MPLANE) {
+		if (inst->domain == DECODER)
+			ret = vdec_streamon_input(inst);
+		else if (inst->domain == ENCODER)
+			ret = venc_streamon_input(inst);
+	} else if (q->type == OUTPUT_MPLANE) {
+		if (inst->domain == DECODER)
+			ret = vdec_streamon_output(inst);
+		else if (inst->domain == ENCODER)
+			ret = venc_streamon_output(inst);
+	}
+	if (ret)
+		goto err_pm_get;
+
+	buf_type = v4l2_type_to_driver(q->type);
+	if (!buf_type) {
+		ret = -EINVAL;
+		goto err_pm_get;
+	}
+
+	ret = queue_deferred_buffers(inst, buf_type);
+	if (ret)
+		goto err_pm_get;
+
+	ret = iris_pm_put(inst->core, true);
+	if (ret)
+		goto error;
+
+	return ret;
+
+err_pm_get:
+	iris_pm_put(inst->core, false);
+error:
+	iris_inst_change_state(inst, IRIS_INST_ERROR);
+
+	return ret;
+}
+
+void iris_vb2_stop_streaming(struct vb2_queue *q)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	if (!q)
+		return;
+
+	inst = vb2_get_drv_priv(q);
+	if (!inst)
+		return;
+
+	if (q->type != INPUT_MPLANE && q->type != OUTPUT_MPLANE)
+		goto error;
+
+	if (inst->domain != DECODER && inst->domain != ENCODER) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = iris_pm_get_put(inst->core);
+	if (ret)
+		goto error;
+
+	if (q->type == INPUT_MPLANE)
+		ret = session_streamoff(inst, INPUT_MPLANE);
+	else if (q->type == OUTPUT_MPLANE)
+		ret = session_streamoff(inst, OUTPUT_MPLANE);
+
+	if (ret)
+		goto error;
+
+	return;
+
+error:
+	iris_inst_change_state(inst, IRIS_INST_ERROR);
+}
+
+void iris_vb2_buf_queue(struct vb2_buffer *vb2)
+{
+	u64 ktime_ns = ktime_get_ns();
+	struct iris_core *core;
+	struct iris_inst *inst;
+	int ret;
+
+	inst = vb2_get_drv_priv(vb2->vb2_queue);
+	if (!inst || !inst->core)
+		return;
+
+	core = inst->core;
+
+	if (!vb2->planes[0].bytesused && vb2->type == INPUT_MPLANE) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	if (vb2->type == INPUT_MPLANE) {
+		ret = iris_update_input_rate(inst, div_u64(ktime_ns, 1000));
+		if (ret)
+			goto exit;
+	}
+
+	ret = iris_pm_get_put(core);
+	if (ret)
+		goto exit;
+
+	if (inst->domain == DECODER)
+		ret = vdec_qbuf(inst, vb2);
+	else if (inst->domain == ENCODER)
+		ret = venc_qbuf(inst, vb2);
+
+exit:
+	if (ret) {
+		iris_inst_change_state(inst, IRIS_INST_ERROR);
+		vb2_buffer_done(vb2, VB2_BUF_STATE_ERROR);
+	}
+}
+
+void *iris_vb2_attach_dmabuf(struct vb2_buffer *vb, struct device *dev,
+			     struct dma_buf *dbuf, unsigned long size)
+{
+	struct iris_buffer *ro_buf, *dummy;
+	enum iris_buffer_type buf_type;
+	struct iris_buffers *buffers;
+	struct iris_buffer *iter;
+	struct iris_buffer *buf;
+	struct iris_inst *inst;
+	bool found = false;
+
+	if (!vb || !dev || !dbuf || !vb->vb2_queue)
+		return ERR_PTR(-EINVAL);
+
+	inst = vb->vb2_queue->drv_priv;
+
+	buf_type = v4l2_type_to_driver(vb->type);
+
+	buffers = iris_get_buffer_list(inst, buf_type);
+	if (!buffers)
+		return NULL;
+
+	list_for_each_entry(iter, &buffers->list, list) {
+		if (iter->index == vb->index) {
+			found = true;
+			buf = iter;
+			break;
+		}
+	}
+
+	if (!found)
+		return NULL;
+
+	buf->inst = inst;
+	buf->dmabuf = dbuf;
+
+	if (inst->domain == DECODER && buf->type == BUF_OUTPUT) {
+		list_for_each_entry_safe(ro_buf, dummy, &inst->buffers.read_only.list, list) {
+			if (ro_buf->dmabuf != buf->dmabuf)
+				continue;
+			buf->attach = ro_buf->attach;
+			ro_buf->attach = NULL;
+			return buf;
+		}
+	}
+
+	buf->attach = dma_buf_attach(dbuf, dev);
+	if (IS_ERR(buf->attach)) {
+		buf->attach = NULL;
+		return NULL;
+	}
+
+	return buf;
+}
+
+int iris_vb2_map_dmabuf(void *buf_priv)
+{
+	struct iris_buffer *ro_buf, *dummy;
+	struct iris_buffer *buf = buf_priv;
+	struct iris_core *core;
+	struct iris_inst *inst;
+
+	if (!buf || !buf->inst)
+		return -EINVAL;
+
+	inst = buf->inst;
+	core = inst->core;
+
+	if (!buf->attach) {
+		dev_err(core->dev, "trying to map a non attached buffer\n");
+		return -EINVAL;
+	}
+
+	if (inst->domain == DECODER && buf->type == BUF_OUTPUT) {
+		list_for_each_entry_safe(ro_buf, dummy, &inst->buffers.read_only.list, list) {
+			if (ro_buf->dmabuf != buf->dmabuf)
+				continue;
+			buf->sg_table = ro_buf->sg_table;
+			buf->device_addr = ro_buf->device_addr;
+			ro_buf->sg_table = NULL;
+			return 0;
+		}
+	}
+
+	buf->sg_table = dma_buf_map_attachment(buf->attach, DMA_BIDIRECTIONAL);
+	if (IS_ERR(buf->sg_table))
+		return -EINVAL;
+
+	if (!buf->sg_table->sgl) {
+		dma_buf_unmap_attachment(buf->attach, buf->sg_table, DMA_BIDIRECTIONAL);
+		buf->sg_table = NULL;
+		return -EINVAL;
+	}
+
+	buf->device_addr = sg_dma_address(buf->sg_table->sgl);
+
+	return 0;
+}
+
+void iris_vb2_unmap_dmabuf(void *buf_priv)
+{
+	struct iris_buffer *ro_buf, *dummy;
+	struct iris_buffer *buf = buf_priv;
+	struct iris_core *core;
+	struct iris_inst *inst;
+
+	if (!buf || !buf->inst)
+		return;
+
+	inst = buf->inst;
+	core = inst->core;
+
+	if (!buf->attach) {
+		dev_err(core->dev, "trying to unmap a non attached buffer\n");
+		return;
+	}
+
+	if (!buf->sg_table) {
+		dev_err(core->dev, "dmabuf buffer is already unmapped\n");
+		return;
+	}
+
+	if (inst->domain == DECODER && buf->type == BUF_OUTPUT) {
+		list_for_each_entry_safe(ro_buf, dummy, &inst->buffers.read_only.list, list) {
+			if (ro_buf->dmabuf != buf->dmabuf)
+				continue;
+			ro_buf->sg_table = buf->sg_table;
+			buf->sg_table = NULL;
+			buf->device_addr = 0x0;
+			return;
+		}
+	}
+
+	if (buf->attach && buf->sg_table) {
+		dma_buf_unmap_attachment(buf->attach, buf->sg_table, DMA_BIDIRECTIONAL);
+		buf->sg_table = NULL;
+		buf->device_addr = 0x0;
+	}
+}
+
+void iris_vb2_detach_dmabuf(void *buf_priv)
+{
+	struct iris_buffer *ro_buf, *dummy;
+	struct iris_buffer *buf = buf_priv;
+	struct iris_core *core;
+	struct iris_inst *inst;
+
+	if (!buf || !buf->inst)
+		return;
+
+	inst = buf->inst;
+	core = inst->core;
+
+	if (buf->sg_table) {
+		dev_err(core->dev, "trying to detach an unmapped buffer\n");
+		dma_buf_unmap_attachment(buf->attach, buf->sg_table, DMA_BIDIRECTIONAL);
+		buf->sg_table = NULL;
+	}
+
+	if (inst->domain == DECODER && buf->type == BUF_OUTPUT) {
+		list_for_each_entry_safe(ro_buf, dummy, &inst->buffers.read_only.list, list) {
+			if (ro_buf->dmabuf != buf->dmabuf)
+				continue;
+			ro_buf->attach = buf->attach;
+			buf->attach = NULL;
+			goto exit;
+		}
+	}
+
+	if (buf->attach && buf->dmabuf) {
+		dma_buf_detach(buf->dmabuf, buf->attach);
+		buf->attach = NULL;
+	}
+
+exit:
+	buf->dmabuf = NULL;
+	buf->inst = NULL;
+}
+
+void *iris_vb2_alloc(struct vb2_buffer *vb, struct device *dev,
+		     unsigned long size)
+{
+	return (void *)0xdeadbeef;
+}
+
+void iris_vb2_put(void *buf_priv)
+{
+}
+
+int iris_vb2_mmap(void *buf_priv, struct vm_area_struct *vma)
+{
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_vb2.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_vb2.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_VB2_H_
+#define _IRIS_VB2_H_
+
+#include <media/videobuf2-v4l2.h>
+
+int iris_vb2_queue_setup(struct vb2_queue *q,
+			 unsigned int *num_buffers, unsigned int *num_planes,
+			 unsigned int sizes[], struct device *alloc_devs[]);
+int iris_vb2_start_streaming(struct vb2_queue *q, unsigned int count);
+void iris_vb2_stop_streaming(struct vb2_queue *q);
+void iris_vb2_buf_queue(struct vb2_buffer *vb2);
+
+/* vb2_mem_ops */
+void *iris_vb2_alloc(struct vb2_buffer *vb, struct device *dev, unsigned long size);
+void *iris_vb2_attach_dmabuf(struct vb2_buffer *vb, struct device *dev, struct dma_buf *dbuf,
+			     unsigned long size);
+void iris_vb2_put(void *buf_priv);
+int iris_vb2_mmap(void *buf_priv, struct vm_area_struct *vma);
+void iris_vb2_detach_dmabuf(void *buf_priv);
+int iris_vb2_map_dmabuf(void *buf_priv);
+void iris_vb2_unmap_dmabuf(void *buf_priv);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_vdec.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_vdec.c
@@ -0,0 +1,1211 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <media/v4l2-event.h>
+
+#include "hfi_defines.h"
+#include "iris_buffer.h"
+#include "iris_common.h"
+#include "iris_ctrls.h"
+#include "iris_helpers.h"
+#include "iris_hfi.h"
+#include "iris_hfi_packet.h"
+#include "iris_power.h"
+#include "iris_vdec.h"
+
+#define UNSPECIFIED_COLOR_FORMAT 5
+
+struct vdec_prop_type_handle {
+	u32 type;
+	int (*handle)(struct iris_inst *inst);
+};
+
+int vdec_inst_init(struct iris_inst *inst)
+{
+	struct v4l2_format *f;
+	int ret;
+
+	inst->fmt_src  = kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL);
+	inst->fmt_dst  = kzalloc(sizeof(*inst->fmt_dst), GFP_KERNEL);
+	inst->vb2q_src = kzalloc(sizeof(*inst->vb2q_src), GFP_KERNEL);
+	inst->vb2q_dst = kzalloc(sizeof(*inst->vb2q_dst), GFP_KERNEL);
+
+	f = inst->fmt_src;
+	f->type = INPUT_MPLANE;
+	f->fmt.pix_mp.width = DEFAULT_WIDTH;
+	f->fmt.pix_mp.height = DEFAULT_HEIGHT;
+	f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+	f->fmt.pix_mp.num_planes = 1;
+	f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
+	f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
+	f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+
+	f = inst->fmt_dst;
+	f->type = OUTPUT_MPLANE;
+	f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_QC08C;
+	f->fmt.pix_mp.width = ALIGN(DEFAULT_WIDTH, 128);
+	f->fmt.pix_mp.height = ALIGN(DEFAULT_HEIGHT, 32);
+	f->fmt.pix_mp.num_planes = 1;
+	f->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(DEFAULT_WIDTH, 128);
+	f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
+	f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+	f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
+	f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+	f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+	f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
+	inst->buffers.output.min_count = iris_get_buf_min_count(inst, BUF_OUTPUT);
+	inst->buffers.output.actual_count = inst->buffers.output.min_count;
+	inst->buffers.output.size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
+	inst->fw_min_count = 0;
+
+	ret = codec_change(inst, inst->fmt_src->fmt.pix_mp.pixelformat);
+
+	return ret;
+}
+
+void vdec_inst_deinit(struct iris_inst *inst)
+{
+	kfree(inst->fmt_dst);
+	kfree(inst->fmt_src);
+}
+
+static int vdec_check_colorformat_supported(struct iris_inst *inst,
+					    enum colorformat_type colorformat)
+{
+	bool supported = true;
+
+	if (!inst->vb2q_src->streaming)
+		return true;
+
+	if (inst->cap[BIT_DEPTH].value == BIT_DEPTH_8 &&
+	    !is_8bit_colorformat(colorformat))
+		supported = false;
+	if (inst->cap[BIT_DEPTH].value == BIT_DEPTH_10 &&
+	    !is_10bit_colorformat(colorformat))
+		supported = false;
+	if (inst->cap[CODED_FRAMES].value == CODED_FRAMES_INTERLACE)
+		supported = false;
+
+	return supported;
+}
+
+int vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
+{
+	struct iris_core *core;
+	u32 array[32] = {0};
+	u32 i = 0;
+
+	if (f->index >= ARRAY_SIZE(array))
+		return -EINVAL;
+
+	core = inst->core;
+	if (f->type == INPUT_MPLANE) {
+		u32 codecs = core->cap[DEC_CODECS].value;
+		u32 codecs_count = hweight32(codecs);
+		u32 idx = 0;
+
+		for (i = 0; i <= codecs_count; i++) {
+			if (codecs & BIT(i)) {
+				if (idx >= ARRAY_SIZE(array))
+					break;
+				array[idx] = codecs & BIT(i);
+				idx++;
+			}
+		}
+		if (!array[f->index])
+			return -EINVAL;
+		f->pixelformat = v4l2_codec_from_driver(inst, array[f->index]);
+		f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION;
+		strscpy(f->description, "codec", sizeof(f->description));
+	} else if (f->type == OUTPUT_MPLANE) {
+		u32 formats = inst->cap[PIX_FMTS].step_or_mask;
+		u32 idx = 0;
+
+		for (i = 0; i <= 31; i++) {
+			if (formats & BIT(i)) {
+				if (idx >= ARRAY_SIZE(array))
+					break;
+				if (vdec_check_colorformat_supported(inst, formats & BIT(i))) {
+					array[idx] = formats & BIT(i);
+					idx++;
+				}
+			}
+		}
+		if (!array[f->index])
+			return -EINVAL;
+		f->pixelformat = v4l2_colorformat_from_driver(inst, array[f->index]);
+		strscpy(f->description, "colorformat", sizeof(f->description));
+	}
+
+	if (!f->pixelformat)
+		return -EINVAL;
+
+	memset(f->reserved, 0, sizeof(f->reserved));
+
+	return 0;
+}
+
+int vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	struct v4l2_format *f_inst;
+	u32 pix_fmt;
+
+	memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
+	if (f->type == INPUT_MPLANE) {
+		pix_fmt = v4l2_codec_to_driver(inst, f->fmt.pix_mp.pixelformat);
+		if (!pix_fmt) {
+			f_inst = inst->fmt_src;
+			f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
+			f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
+			f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
+			pix_fmt = v4l2_codec_to_driver(inst, f->fmt.pix_mp.pixelformat);
+		}
+	} else if (f->type == OUTPUT_MPLANE) {
+		pix_fmt = v4l2_colorformat_to_driver(inst, f->fmt.pix_mp.pixelformat);
+		if (!pix_fmt) {
+			f_inst = inst->fmt_dst;
+			f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat;
+			f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
+			f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
+		}
+		if (inst->vb2q_src->streaming) {
+			f_inst = inst->fmt_src;
+			f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height;
+			f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width;
+		}
+	} else {
+		return -EINVAL;
+	}
+
+	if (pixmp->field == V4L2_FIELD_ANY)
+		pixmp->field = V4L2_FIELD_NONE;
+
+	pixmp->num_planes = 1;
+
+	return 0;
+}
+
+int vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
+{
+	struct v4l2_format *fmt, *output_fmt;
+	enum colorformat_type colorformat;
+	u32 codec_align, stride = 0;
+	int ret = 0;
+
+	vdec_try_fmt(inst, f);
+
+	if (f->type == INPUT_MPLANE) {
+		if (inst->fmt_src->fmt.pix_mp.pixelformat !=
+			f->fmt.pix_mp.pixelformat) {
+			ret = codec_change(inst, f->fmt.pix_mp.pixelformat);
+			if (ret)
+				return ret;
+		}
+
+		fmt = inst->fmt_src;
+		fmt->type = INPUT_MPLANE;
+
+		codec_align = inst->fmt_src->fmt.pix_mp.pixelformat ==
+			V4L2_PIX_FMT_HEVC ? 32 : 16;
+		fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align);
+		fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align);
+		fmt->fmt.pix_mp.num_planes = 1;
+		fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
+		fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
+		inst->buffers.input.min_count = iris_get_buf_min_count(inst, BUF_INPUT);
+		if (inst->buffers.input.actual_count <
+			inst->buffers.input.min_count) {
+			inst->buffers.input.actual_count =
+				inst->buffers.input.min_count;
+		}
+		inst->buffers.input.size =
+			fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
+
+		fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
+		fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
+		fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
+		fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
+
+		output_fmt = inst->fmt_dst;
+		output_fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
+		output_fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
+		output_fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
+		output_fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
+
+		inst->crop.left = 0;
+		inst->crop.top = 0;
+		inst->crop.width = f->fmt.pix_mp.width;
+		inst->crop.height = f->fmt.pix_mp.height;
+	} else if (f->type == OUTPUT_MPLANE) {
+		fmt = inst->fmt_dst;
+		fmt->type = OUTPUT_MPLANE;
+		if (inst->vb2q_src->streaming) {
+			f->fmt.pix_mp.height = inst->fmt_src->fmt.pix_mp.height;
+			f->fmt.pix_mp.width = inst->fmt_src->fmt.pix_mp.width;
+		}
+		fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
+		codec_align = f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC10C ? 192 : 128;
+		fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, codec_align);
+		codec_align = f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC10C ? 16 : 32;
+		fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, codec_align);
+		fmt->fmt.pix_mp.num_planes = 1;
+		if (f->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC10C) {
+			stride = ALIGN(f->fmt.pix_mp.width, 192);
+			fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(stride * 4 / 3, 256);
+		} else {
+			fmt->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(f->fmt.pix_mp.width, 128);
+		}
+		fmt->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
+
+		if (!inst->vb2q_src->streaming)
+			inst->buffers.output.min_count = iris_get_buf_min_count(inst, BUF_OUTPUT);
+		if (inst->buffers.output.actual_count <
+			inst->buffers.output.min_count) {
+			inst->buffers.output.actual_count =
+				inst->buffers.output.min_count;
+		}
+
+		colorformat = v4l2_colorformat_to_driver(inst, fmt->fmt.pix_mp.pixelformat);
+		inst->buffers.output.size =
+			fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
+		inst->cap[PIX_FMTS].value = colorformat;
+
+		if (!inst->vb2q_src->streaming) {
+			inst->crop.top = 0;
+			inst->crop.left = 0;
+			inst->crop.width = f->fmt.pix_mp.width;
+			inst->crop.height = f->fmt.pix_mp.height;
+		}
+	} else {
+		return -EINVAL;
+	}
+	memcpy(f, fmt, sizeof(*fmt));
+
+	return ret;
+}
+
+int vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub)
+{
+	int ret = 0;
+
+	switch (sub->type) {
+	case V4L2_EVENT_EOS:
+		ret = v4l2_event_subscribe(&inst->fh, sub, MAX_EVENTS, NULL);
+		break;
+	case V4L2_EVENT_SOURCE_CHANGE:
+		ret = v4l2_src_change_event_subscribe(&inst->fh, sub);
+		break;
+	case V4L2_EVENT_CTRL:
+		ret = v4l2_ctrl_subscribe_event(&inst->fh, sub);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+static int vdec_subscribe_property(struct iris_inst *inst, u32 plane)
+{
+	const u32 *subcribe_prop = NULL;
+	u32 subscribe_prop_size = 0;
+	struct iris_core *core;
+	u32 payload[32] = {0};
+	u32 i;
+
+	core = inst->core;
+
+	payload[0] = HFI_MODE_PROPERTY;
+
+	if (plane == INPUT_MPLANE) {
+		subscribe_prop_size = core->platform_data->dec_input_prop_size;
+		subcribe_prop = core->platform_data->dec_input_prop;
+	} else if (plane == OUTPUT_MPLANE) {
+		if (inst->codec == H264) {
+			subscribe_prop_size = core->platform_data->dec_output_prop_size_avc;
+			subcribe_prop = core->platform_data->dec_output_prop_avc;
+		} else if (inst->codec == HEVC) {
+			subscribe_prop_size = core->platform_data->dec_output_prop_size_hevc;
+			subcribe_prop = core->platform_data->dec_output_prop_hevc;
+		} else if (inst->codec == VP9) {
+			subscribe_prop_size = core->platform_data->dec_output_prop_size_vp9;
+			subcribe_prop = core->platform_data->dec_output_prop_vp9;
+		} else {
+			return -EINVAL;
+		}
+	} else {
+		return -EINVAL;
+	}
+
+	for (i = 0; i < subscribe_prop_size; i++)
+		payload[i + 1] = subcribe_prop[i];
+
+	return iris_hfi_session_subscribe_mode(inst,
+					HFI_CMD_SUBSCRIBE_MODE,
+					plane,
+					HFI_PAYLOAD_U32_ARRAY,
+					&payload[0],
+					(subscribe_prop_size + 1) * sizeof(u32));
+}
+
+static int vdec_set_bitstream_resolution(struct iris_inst *inst)
+{
+	u32 resolution;
+
+	resolution = inst->fmt_src->fmt.pix_mp.width << 16 |
+		inst->fmt_src->fmt.pix_mp.height;
+	inst->src_subcr_params.bitstream_resolution = resolution;
+
+	return iris_hfi_set_property(inst,
+					HFI_PROP_BITSTREAM_RESOLUTION,
+					HFI_HOST_FLAGS_NONE,
+					get_hfi_port(inst, INPUT_MPLANE),
+					HFI_PAYLOAD_U32,
+					&resolution,
+					sizeof(u32));
+}
+
+static int vdec_set_crop_offsets(struct iris_inst *inst)
+{
+	u32 left_offset, top_offset, right_offset, bottom_offset;
+	u32 payload[2] = {0};
+
+	left_offset = inst->crop.left;
+	top_offset = inst->crop.top;
+	right_offset = (inst->fmt_src->fmt.pix_mp.width -
+		inst->crop.width);
+	bottom_offset = (inst->fmt_src->fmt.pix_mp.height -
+		inst->crop.height);
+
+	payload[0] = left_offset << 16 | top_offset;
+	payload[1] = right_offset << 16 | bottom_offset;
+	inst->src_subcr_params.crop_offsets[0] = payload[0];
+	inst->src_subcr_params.crop_offsets[1] = payload[1];
+
+	return iris_hfi_set_property(inst,
+					HFI_PROP_CROP_OFFSETS,
+					HFI_HOST_FLAGS_NONE,
+					get_hfi_port(inst, INPUT_MPLANE),
+					HFI_PAYLOAD_64_PACKED,
+					&payload,
+					sizeof(u64));
+}
+
+static int vdec_set_bit_depth(struct iris_inst *inst)
+{
+	u32 bitdepth = 8 << 16 | 8;
+	u32 pix_fmt;
+
+	pix_fmt = inst->fmt_dst->fmt.pix_mp.pixelformat;
+	if (is_10bit_colorformat(pix_fmt))
+		bitdepth = 10 << 16 | 10;
+
+	inst->src_subcr_params.bit_depth = bitdepth;
+	inst->cap[BIT_DEPTH].value = bitdepth;
+
+	return iris_hfi_set_property(inst,
+					HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
+					HFI_HOST_FLAGS_NONE,
+					get_hfi_port(inst, INPUT_MPLANE),
+					HFI_PAYLOAD_U32,
+					&bitdepth,
+					sizeof(u32));
+}
+
+static int vdec_set_coded_frames(struct iris_inst *inst)
+{
+	u32 coded_frames = 0;
+
+	if (inst->cap[CODED_FRAMES].value == CODED_FRAMES_PROGRESSIVE)
+		coded_frames = HFI_BITMASK_FRAME_MBS_ONLY_FLAG;
+	inst->src_subcr_params.coded_frames = coded_frames;
+
+	return iris_hfi_set_property(inst,
+					HFI_PROP_CODED_FRAMES,
+					HFI_HOST_FLAGS_NONE,
+					get_hfi_port(inst, INPUT_MPLANE),
+					HFI_PAYLOAD_U32,
+					&coded_frames,
+					sizeof(u32));
+}
+
+static int vdec_set_min_output_count(struct iris_inst *inst)
+{
+	u32 min_output;
+
+	min_output = inst->buffers.output.min_count;
+	inst->src_subcr_params.fw_min_count = min_output;
+
+	return iris_hfi_set_property(inst,
+					HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
+					HFI_HOST_FLAGS_NONE,
+					get_hfi_port(inst, INPUT_MPLANE),
+					HFI_PAYLOAD_U32,
+					&min_output,
+					sizeof(u32));
+}
+
+static int vdec_set_picture_order_count(struct iris_inst *inst)
+{
+	u32 poc = 0;
+
+	inst->src_subcr_params.pic_order_cnt = poc;
+
+	return iris_hfi_set_property(inst,
+					HFI_PROP_PIC_ORDER_CNT_TYPE,
+					HFI_HOST_FLAGS_NONE,
+					get_hfi_port(inst, INPUT_MPLANE),
+					HFI_PAYLOAD_U32,
+					&poc,
+					sizeof(u32));
+}
+
+static int vdec_set_colorspace(struct iris_inst *inst)
+{
+	u32 video_signal_type_present_flag = 0, color_info = 0;
+	u32 matrix_coeff = HFI_MATRIX_COEFF_RESERVED;
+	u32 video_format = UNSPECIFIED_COLOR_FORMAT;
+	struct v4l2_pix_format_mplane *pixmp = NULL;
+	u32 full_range = V4L2_QUANTIZATION_DEFAULT;
+	u32 transfer_char = HFI_TRANSFER_RESERVED;
+	u32 colour_description_present_flag = 0;
+	u32 primaries = HFI_PRIMARIES_RESERVED;
+
+	int ret;
+
+	if (inst->codec == VP9)
+		return 0;
+
+	pixmp = &inst->fmt_src->fmt.pix_mp;
+	if (pixmp->colorspace != V4L2_COLORSPACE_DEFAULT ||
+	    pixmp->ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT ||
+	    pixmp->xfer_func != V4L2_XFER_FUNC_DEFAULT) {
+		colour_description_present_flag = 1;
+		video_signal_type_present_flag = 1;
+		primaries = get_hfi_color_primaries(pixmp->colorspace);
+		matrix_coeff = get_hfi_matrix_coefficients(pixmp->ycbcr_enc);
+		transfer_char = get_hfi_transer_char(pixmp->xfer_func);
+	}
+
+	if (pixmp->quantization != V4L2_QUANTIZATION_DEFAULT) {
+		video_signal_type_present_flag = 1;
+		full_range = pixmp->quantization ==
+			V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0;
+	}
+
+	color_info = (matrix_coeff & 0xFF) |
+		((transfer_char << 8) & 0xFF00) |
+		((primaries << 16) & 0xFF0000) |
+		((colour_description_present_flag << 24) & 0x1000000) |
+		((full_range << 25) & 0x2000000) |
+		((video_format << 26) & 0x1C000000) |
+		((video_signal_type_present_flag << 29) & 0x20000000);
+
+	inst->src_subcr_params.color_info = color_info;
+
+	ret = iris_hfi_set_property(inst,
+				    HFI_PROP_SIGNAL_COLOR_INFO,
+				    HFI_HOST_FLAGS_NONE,
+				    get_hfi_port(inst, INPUT_MPLANE),
+				    HFI_PAYLOAD_32_PACKED,
+				    &color_info,
+				    sizeof(u32));
+
+	return ret;
+}
+
+static int vdec_set_profile(struct iris_inst *inst)
+{
+	u32 profile;
+
+	profile = inst->cap[PROFILE].value;
+	inst->src_subcr_params.profile = profile;
+
+	return iris_hfi_set_property(inst,
+				     HFI_PROP_PROFILE,
+				     HFI_HOST_FLAGS_NONE,
+				     get_hfi_port(inst, INPUT_MPLANE),
+				     HFI_PAYLOAD_U32_ENUM,
+				     &profile,
+				     sizeof(u32));
+}
+
+static int vdec_set_level(struct iris_inst *inst)
+{
+	u32 level;
+
+	level = inst->cap[LEVEL].value;
+	inst->src_subcr_params.level = level;
+
+	return iris_hfi_set_property(inst,
+				     HFI_PROP_LEVEL,
+				     HFI_HOST_FLAGS_NONE,
+				     get_hfi_port(inst, INPUT_MPLANE),
+				     HFI_PAYLOAD_U32_ENUM,
+				     &level,
+				     sizeof(u32));
+}
+
+static int vdec_set_tier(struct iris_inst *inst)
+{
+	u32 tier;
+
+	tier = inst->cap[HEVC_TIER].value;
+	inst->src_subcr_params.tier = tier;
+
+	return iris_hfi_set_property(inst,
+				     HFI_PROP_TIER,
+				     HFI_HOST_FLAGS_NONE,
+				     get_hfi_port(inst, INPUT_MPLANE),
+				     HFI_PAYLOAD_U32_ENUM,
+				     &tier,
+				     sizeof(u32));
+}
+
+static int vdec_subscribe_src_change_param(struct iris_inst *inst)
+{
+	const u32 *src_change_param;
+	u32 src_change_param_size;
+	struct iris_core *core;
+	u32 payload[32] = {0};
+	int ret;
+	u32 i, j;
+
+	static const struct vdec_prop_type_handle prop_type_handle_arr[] = {
+		{HFI_PROP_BITSTREAM_RESOLUTION,          vdec_set_bitstream_resolution   },
+		{HFI_PROP_CROP_OFFSETS,                  vdec_set_crop_offsets           },
+		{HFI_PROP_LUMA_CHROMA_BIT_DEPTH,         vdec_set_bit_depth              },
+		{HFI_PROP_CODED_FRAMES,                  vdec_set_coded_frames           },
+		{HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,    vdec_set_min_output_count       },
+		{HFI_PROP_PIC_ORDER_CNT_TYPE,            vdec_set_picture_order_count    },
+		{HFI_PROP_SIGNAL_COLOR_INFO,             vdec_set_colorspace             },
+		{HFI_PROP_PROFILE,                       vdec_set_profile                },
+		{HFI_PROP_LEVEL,                         vdec_set_level                  },
+		{HFI_PROP_TIER,                          vdec_set_tier                   },
+	};
+
+	core = inst->core;
+
+	payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
+	if (inst->codec == H264) {
+		src_change_param_size = core->platform_data->avc_subscribe_param_size;
+		src_change_param = core->platform_data->avc_subscribe_param;
+	} else if (inst->codec == HEVC) {
+		src_change_param_size = core->platform_data->hevc_subscribe_param_size;
+		src_change_param = core->platform_data->hevc_subscribe_param;
+	} else if (inst->codec == VP9) {
+		src_change_param_size = core->platform_data->vp9_subscribe_param_size;
+		src_change_param = core->platform_data->vp9_subscribe_param;
+	} else {
+		src_change_param = NULL;
+		return -EINVAL;
+	}
+
+	if (!src_change_param || !src_change_param_size)
+		return -EINVAL;
+
+	for (i = 0; i < src_change_param_size; i++)
+		payload[i + 1] = src_change_param[i];
+
+	ret = iris_hfi_session_subscribe_mode(inst,
+					      HFI_CMD_SUBSCRIBE_MODE,
+					      INPUT_MPLANE,
+					      HFI_PAYLOAD_U32_ARRAY,
+					      &payload[0],
+					      ((src_change_param_size + 1) * sizeof(u32)));
+	if (ret)
+		return ret;
+
+	for (i = 0; i < src_change_param_size; i++) {
+		for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) {
+			if (prop_type_handle_arr[j].type == src_change_param[i]) {
+				ret = prop_type_handle_arr[j].handle(inst);
+				if (ret)
+					return ret;
+				break;
+			}
+		}
+	}
+
+	return ret;
+}
+
+int vdec_init_src_change_param(struct iris_inst *inst)
+{
+	u32 left_offset, top_offset, right_offset, bottom_offset;
+	struct v4l2_pix_format_mplane *pixmp_ip, *pixmp_op;
+	u32 primaries, matrix_coeff, transfer_char;
+	struct subscription_params *subsc_params;
+	u32 colour_description_present_flag = 0;
+	u32 video_signal_type_present_flag = 0;
+	u32 full_range = 0, video_format = 0;
+
+	subsc_params = &inst->src_subcr_params;
+	pixmp_ip = &inst->fmt_src->fmt.pix_mp;
+	pixmp_op = &inst->fmt_dst->fmt.pix_mp;
+
+	subsc_params->bitstream_resolution =
+		pixmp_ip->width << 16 | pixmp_ip->height;
+
+	left_offset = inst->crop.left;
+	top_offset = inst->crop.top;
+	right_offset = (pixmp_ip->width - inst->crop.width);
+	bottom_offset = (pixmp_ip->height - inst->crop.height);
+	subsc_params->crop_offsets[0] =
+			left_offset << 16 | top_offset;
+	subsc_params->crop_offsets[1] =
+			right_offset << 16 | bottom_offset;
+
+	subsc_params->fw_min_count = inst->buffers.output.min_count;
+
+	primaries = get_hfi_color_primaries(pixmp_op->colorspace);
+	matrix_coeff = get_hfi_matrix_coefficients(pixmp_op->ycbcr_enc);
+	transfer_char = get_hfi_transer_char(pixmp_op->xfer_func);
+	full_range = pixmp_op->quantization == V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0;
+	subsc_params->color_info =
+		(matrix_coeff & 0xFF) |
+		((transfer_char << 8) & 0xFF00) |
+		((primaries << 16) & 0xFF0000) |
+		((colour_description_present_flag << 24) & 0x1000000) |
+		((full_range << 25) & 0x2000000) |
+		((video_format << 26) & 0x1C000000) |
+		((video_signal_type_present_flag << 29) & 0x20000000);
+
+	subsc_params->profile = inst->cap[PROFILE].value;
+	subsc_params->level = inst->cap[LEVEL].value;
+	subsc_params->tier = inst->cap[HEVC_TIER].value;
+	subsc_params->pic_order_cnt = inst->cap[POC].value;
+	subsc_params->bit_depth = inst->cap[BIT_DEPTH].value;
+	if (inst->cap[CODED_FRAMES].value ==
+			CODED_FRAMES_PROGRESSIVE)
+		subsc_params->coded_frames = HFI_BITMASK_FRAME_MBS_ONLY_FLAG;
+	else
+		subsc_params->coded_frames = 0;
+
+	return 0;
+}
+
+static int vdec_read_input_subcr_params(struct iris_inst *inst)
+{
+	struct v4l2_pix_format_mplane *pixmp_ip, *pixmp_op;
+	u32 primaries, matrix_coeff, transfer_char;
+	struct subscription_params subsc_params;
+	u32 colour_description_present_flag = 0;
+	u32 video_signal_type_present_flag = 0;
+	u32 full_range = 0;
+	u32 width, height;
+
+	subsc_params = inst->src_subcr_params;
+	pixmp_ip = &inst->fmt_src->fmt.pix_mp;
+	pixmp_op = &inst->fmt_dst->fmt.pix_mp;
+	width = (subsc_params.bitstream_resolution &
+		HFI_BITMASK_BITSTREAM_WIDTH) >> 16;
+	height = subsc_params.bitstream_resolution &
+		HFI_BITMASK_BITSTREAM_HEIGHT;
+
+	pixmp_ip->width = width;
+	pixmp_ip->height = height;
+
+	pixmp_op->width = pixmp_op->pixelformat == V4L2_PIX_FMT_QC10C ?
+		ALIGN(width, 192) : ALIGN(width, 128);
+	pixmp_op->height = pixmp_op->pixelformat == V4L2_PIX_FMT_QC10C ?
+		ALIGN(height, 16) : ALIGN(height, 32);
+	pixmp_op->plane_fmt[0].bytesperline =
+		pixmp_op->pixelformat == V4L2_PIX_FMT_QC10C ?
+		ALIGN(ALIGN(width, 192) * 4 / 3, 256) :
+		ALIGN(width, 128);
+	pixmp_op->plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
+
+	matrix_coeff = subsc_params.color_info & 0xFF;
+	transfer_char = (subsc_params.color_info & 0xFF00) >> 8;
+	primaries = (subsc_params.color_info & 0xFF0000) >> 16;
+	colour_description_present_flag =
+		(subsc_params.color_info & 0x1000000) >> 24;
+	full_range = (subsc_params.color_info & 0x2000000) >> 25;
+	video_signal_type_present_flag =
+		(subsc_params.color_info & 0x20000000) >> 29;
+
+	pixmp_op->colorspace = V4L2_COLORSPACE_DEFAULT;
+	pixmp_op->xfer_func = V4L2_XFER_FUNC_DEFAULT;
+	pixmp_op->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+	pixmp_op->quantization = V4L2_QUANTIZATION_DEFAULT;
+
+	if (video_signal_type_present_flag) {
+		pixmp_op->quantization =
+			full_range ?
+			V4L2_QUANTIZATION_FULL_RANGE :
+			V4L2_QUANTIZATION_LIM_RANGE;
+		if (colour_description_present_flag) {
+			pixmp_op->colorspace =
+				get_v4l2_color_primaries(primaries);
+			pixmp_op->xfer_func =
+				get_v4l2_transer_char(transfer_char);
+			pixmp_op->ycbcr_enc =
+				get_v4l2_matrix_coefficients(matrix_coeff);
+		}
+	}
+
+	pixmp_ip->colorspace = pixmp_op->colorspace;
+	pixmp_ip->xfer_func = pixmp_op->xfer_func;
+	pixmp_ip->ycbcr_enc = pixmp_op->ycbcr_enc;
+	pixmp_ip->quantization = pixmp_op->quantization;
+
+	inst->crop.top = subsc_params.crop_offsets[0] & 0xFFFF;
+	inst->crop.left = (subsc_params.crop_offsets[0] >> 16) & 0xFFFF;
+	inst->crop.height = pixmp_ip->height -
+		(subsc_params.crop_offsets[1] & 0xFFFF) - inst->crop.top;
+	inst->crop.width = pixmp_ip->width -
+		((subsc_params.crop_offsets[1] >> 16) & 0xFFFF) - inst->crop.left;
+
+	inst->cap[PROFILE].value = subsc_params.profile;
+	inst->cap[LEVEL].value = subsc_params.level;
+	inst->cap[HEVC_TIER].value = subsc_params.tier;
+	inst->cap[POC].value = subsc_params.pic_order_cnt;
+
+	if (subsc_params.bit_depth == BIT_DEPTH_8)
+		inst->cap[BIT_DEPTH].value = BIT_DEPTH_8;
+	else
+		inst->cap[BIT_DEPTH].value = BIT_DEPTH_10;
+
+	if (subsc_params.coded_frames & HFI_BITMASK_FRAME_MBS_ONLY_FLAG)
+		inst->cap[CODED_FRAMES].value = CODED_FRAMES_PROGRESSIVE;
+	else
+		inst->cap[CODED_FRAMES].value = CODED_FRAMES_INTERLACE;
+
+	inst->fw_min_count = subsc_params.fw_min_count;
+	inst->buffers.output.min_count = iris_get_buf_min_count(inst, BUF_OUTPUT);
+
+	return 0;
+}
+
+int vdec_src_change(struct iris_inst *inst)
+{
+	struct v4l2_event event = {0};
+	u32 ret;
+
+	if (!inst->vb2q_src->streaming)
+		return 0;
+
+	ret = vdec_read_input_subcr_params(inst);
+	if (ret)
+		return ret;
+
+	event.type = V4L2_EVENT_SOURCE_CHANGE;
+	event.u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION;
+	v4l2_event_queue_fh(&inst->fh, &event);
+
+	return ret;
+}
+
+static int vdec_set_colorformat(struct iris_inst *inst)
+{
+	u32 hfi_colorformat;
+	u32 pixelformat;
+
+	pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
+	hfi_colorformat = get_hfi_colorformat(pixelformat);
+
+	return iris_hfi_set_property(inst,
+					 HFI_PROP_COLOR_FORMAT,
+					 HFI_HOST_FLAGS_NONE,
+					 get_hfi_port(inst, OUTPUT_MPLANE),
+					 HFI_PAYLOAD_U32,
+					 &hfi_colorformat,
+					 sizeof(u32));
+}
+
+static int vdec_set_linear_stride_scanline(struct iris_inst *inst)
+{
+	u32 stride_y, scanline_y, stride_uv, scanline_uv;
+	u32 pixelformat;
+	u32 payload[2];
+
+	pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
+
+	if (!is_linear_colorformat(pixelformat))
+		return 0;
+
+	stride_y = inst->fmt_dst->fmt.pix_mp.width;
+	scanline_y = inst->fmt_dst->fmt.pix_mp.height;
+	stride_uv = stride_y;
+	scanline_uv = scanline_y / 2;
+
+	payload[0] = stride_y << 16 | scanline_y;
+	payload[1] = stride_uv << 16 | scanline_uv;
+
+	return iris_hfi_set_property(inst,
+					 HFI_PROP_LINEAR_STRIDE_SCANLINE,
+					 HFI_HOST_FLAGS_NONE,
+					 get_hfi_port(inst, OUTPUT_MPLANE),
+					 HFI_PAYLOAD_U64,
+					 &payload,
+					 sizeof(u64));
+}
+
+static int vdec_set_ubwc_stride_scanline(struct iris_inst *inst)
+{
+	u32 meta_stride_y, meta_scanline_y, meta_stride_uv, meta_scanline_uv;
+	u32 stride_y, scanline_y, stride_uv, scanline_uv;
+	u32 pix_fmt, width, height;
+	u32 payload[4];
+
+	pix_fmt = inst->fmt_dst->fmt.pix_mp.pixelformat;
+	width = inst->fmt_dst->fmt.pix_mp.width;
+	height = inst->fmt_dst->fmt.pix_mp.height;
+
+	if (is_linear_colorformat(pix_fmt))
+		return 0;
+
+	if (pix_fmt == V4L2_PIX_FMT_QC08C) {
+		stride_y = ALIGN(width, 128);
+		scanline_y = ALIGN(height, 32);
+		stride_uv = ALIGN(width, 128);
+		scanline_uv = ALIGN((height + 1) >> 1, 32);
+		meta_stride_y = ALIGN(DIV_ROUND_UP(width, 32), 64);
+		meta_scanline_y = ALIGN(DIV_ROUND_UP(height, 8), 16);
+		meta_stride_uv = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 16), 64);
+		meta_scanline_uv = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 8), 16);
+	} else {
+		stride_y = ALIGN(ALIGN(width, 192) * 4 / 3, 256);
+		scanline_y = ALIGN(height, 16);
+		stride_uv = ALIGN(ALIGN(width, 192) * 4 / 3, 256);
+		scanline_uv = ALIGN((height + 1) >> 1, 16);
+		meta_stride_y = ALIGN(DIV_ROUND_UP(width, 48), 64);
+		meta_scanline_y = ALIGN(DIV_ROUND_UP(height, 4), 16);
+		meta_stride_uv = ALIGN(DIV_ROUND_UP((width + 1) >> 1, 24), 64);
+		meta_scanline_uv = ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16);
+	}
+
+	payload[0] = stride_y << 16 | scanline_y;
+	payload[1] = stride_uv << 16 | scanline_uv;
+	payload[2] = meta_stride_y << 16 | meta_scanline_y;
+	payload[3] = meta_stride_uv << 16 | meta_scanline_uv;
+
+	return iris_hfi_set_property(inst,
+				     HFI_PROP_UBWC_STRIDE_SCANLINE,
+				     HFI_HOST_FLAGS_NONE,
+				     get_hfi_port(inst, OUTPUT_MPLANE),
+				     HFI_PAYLOAD_U32_ARRAY,
+				     &payload[0],
+				     sizeof(u32) * 4);
+}
+
+static int vdec_set_output_property(struct iris_inst *inst)
+{
+	int ret;
+
+	ret = vdec_set_colorformat(inst);
+	if (ret)
+		return ret;
+
+	ret = vdec_set_linear_stride_scanline(inst);
+	if (ret)
+		return ret;
+
+	return vdec_set_ubwc_stride_scanline(inst);
+}
+
+static int vdec_subscribe_dst_change_param(struct iris_inst *inst)
+{
+	u32 prop_type, payload_size, payload_type;
+	struct subscription_params subsc_params;
+	const u32 *dst_change_param = NULL;
+	u32 dst_change_param_size = 0;
+	struct iris_core *core;
+	u32 payload[32] = {0};
+	int ret;
+	u32 i;
+
+	core = inst->core;
+
+	payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
+	if (inst->codec == H264) {
+		dst_change_param_size = core->platform_data->avc_subscribe_param_size;
+		dst_change_param = core->platform_data->avc_subscribe_param;
+	} else if (inst->codec == HEVC) {
+		dst_change_param_size = core->platform_data->hevc_subscribe_param_size;
+		dst_change_param = core->platform_data->hevc_subscribe_param;
+	} else if (inst->codec == VP9) {
+		dst_change_param_size = core->platform_data->vp9_subscribe_param_size;
+		dst_change_param = core->platform_data->vp9_subscribe_param;
+	} else {
+		dst_change_param = NULL;
+		return -EINVAL;
+	}
+
+	if (!dst_change_param || !dst_change_param_size)
+		return -EINVAL;
+
+	payload[0] = HFI_MODE_PORT_SETTINGS_CHANGE;
+	for (i = 0; i < dst_change_param_size; i++)
+		payload[i + 1] = dst_change_param[i];
+
+	ret = iris_hfi_session_subscribe_mode(inst,
+					      HFI_CMD_SUBSCRIBE_MODE,
+					      OUTPUT_MPLANE,
+					      HFI_PAYLOAD_U32_ARRAY,
+					      &payload[0],
+					      ((dst_change_param_size + 1) * sizeof(u32)));
+	if (ret)
+		return ret;
+
+	subsc_params = inst->dst_subcr_params;
+	for (i = 0; i < dst_change_param_size; i++) {
+		payload[0] = 0;
+		payload[1] = 0;
+		payload_size = 0;
+		payload_type = 0;
+		prop_type = dst_change_param[i];
+		switch (prop_type) {
+		case HFI_PROP_BITSTREAM_RESOLUTION:
+			payload[0] = subsc_params.bitstream_resolution;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_CROP_OFFSETS:
+			payload[0] = subsc_params.crop_offsets[0];
+			payload[1] = subsc_params.crop_offsets[1];
+			payload_size = sizeof(u64);
+			payload_type = HFI_PAYLOAD_64_PACKED;
+			break;
+		case HFI_PROP_LUMA_CHROMA_BIT_DEPTH:
+			payload[0] = subsc_params.bit_depth;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_CODED_FRAMES:
+			payload[0] = subsc_params.coded_frames;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT:
+			payload[0] = subsc_params.fw_min_count;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_PIC_ORDER_CNT_TYPE:
+			payload[0] = subsc_params.pic_order_cnt;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_SIGNAL_COLOR_INFO:
+			payload[0] = subsc_params.color_info;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_PROFILE:
+			payload[0] = subsc_params.profile;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_LEVEL:
+			payload[0] = subsc_params.level;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		case HFI_PROP_TIER:
+			payload[0] = subsc_params.tier;
+			payload_size = sizeof(u32);
+			payload_type = HFI_PAYLOAD_U32;
+			break;
+		default:
+			prop_type = 0;
+			ret = -EINVAL;
+			break;
+		}
+		if (prop_type) {
+			ret = iris_hfi_set_property(inst,
+						    prop_type,
+						    HFI_HOST_FLAGS_NONE,
+						    get_hfi_port(inst, OUTPUT_MPLANE),
+						    payload_type,
+						    &payload,
+						    payload_size);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+int vdec_streamon_input(struct iris_inst *inst)
+{
+	int ret;
+
+	ret = check_session_supported(inst);
+	if (ret)
+		return ret;
+
+	ret = set_v4l2_properties(inst);
+	if (ret)
+		return ret;
+
+	ret = iris_get_internal_buffers(inst, INPUT_MPLANE);
+	if (ret)
+		return ret;
+
+	ret = iris_destroy_internal_buffers(inst, INPUT_MPLANE);
+	if (ret)
+		return ret;
+
+	ret = iris_create_input_internal_buffers(inst);
+	if (ret)
+		return ret;
+
+	ret = iris_queue_input_internal_buffers(inst);
+	if (ret)
+		return ret;
+
+	if (!inst->ipsc_properties_set) {
+		ret = vdec_subscribe_src_change_param(inst);
+		if (ret)
+			return ret;
+		inst->ipsc_properties_set = true;
+	}
+
+	ret = vdec_subscribe_property(inst, INPUT_MPLANE);
+	if (ret)
+		return ret;
+
+	ret = process_streamon_input(inst);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+
+int vdec_streamon_output(struct iris_inst *inst)
+{
+	int ret;
+
+	ret = check_session_supported(inst);
+	if (ret)
+		return ret;
+
+	ret = vdec_set_output_property(inst);
+	if (ret)
+		goto error;
+
+	if (!inst->opsc_properties_set) {
+		memcpy(&inst->dst_subcr_params,
+		       &inst->src_subcr_params,
+		       sizeof(inst->src_subcr_params));
+		ret = vdec_subscribe_dst_change_param(inst);
+		if (ret)
+			goto error;
+		inst->opsc_properties_set = true;
+	}
+
+	ret = vdec_subscribe_property(inst, OUTPUT_MPLANE);
+	if (ret)
+		goto error;
+
+	ret = iris_get_internal_buffers(inst, OUTPUT_MPLANE);
+	if (ret)
+		goto error;
+
+	ret = iris_destroy_internal_buffers(inst, OUTPUT_MPLANE);
+	if (ret)
+		goto error;
+
+	ret = iris_create_output_internal_buffers(inst);
+	if (ret)
+		goto error;
+
+	ret = process_streamon_output(inst);
+	if (ret)
+		goto error;
+
+	ret = iris_queue_output_internal_buffers(inst);
+	if (ret)
+		goto error;
+
+	return ret;
+
+error:
+	session_streamoff(inst, OUTPUT_MPLANE);
+
+	return ret;
+}
+
+int vdec_qbuf(struct iris_inst *inst, struct vb2_buffer *vb2)
+{
+	struct iris_buffer *buf = NULL;
+	int ret;
+
+	buf = get_driver_buf(inst, vb2->type, vb2->index);
+	if (!buf)
+		return -EINVAL;
+
+	ret = vb2_buffer_to_driver(vb2, buf);
+	if (ret)
+		return ret;
+
+	if (!allow_qbuf(inst, vb2->type)) {
+		buf->attr |= BUF_ATTR_DEFERRED;
+		return 0;
+	}
+
+	iris_scale_power(inst);
+
+	ret = queue_buffer(inst, buf);
+	if (ret)
+		return ret;
+
+	if (vb2->type == OUTPUT_MPLANE)
+		ret = iris_release_nonref_buffers(inst);
+
+	return ret;
+}
+
+int vdec_start_cmd(struct iris_inst *inst)
+{
+	int ret;
+
+	vb2_clear_last_buffer_dequeued(inst->vb2q_dst);
+
+	if (inst->sub_state & IRIS_INST_SUB_DRC &&
+	    inst->sub_state & IRIS_INST_SUB_DRC_LAST &&
+	    inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) {
+		ret = iris_alloc_and_queue_input_int_bufs(inst);
+		if (ret)
+			return ret;
+
+		ret = set_stage(inst, STAGE);
+		if (ret)
+			return ret;
+
+		ret = set_pipe(inst, PIPE);
+		if (ret)
+			return ret;
+	}
+
+	ret = iris_alloc_and_queue_additional_dpb_buffers(inst);
+	if (ret)
+		return ret;
+
+	ret = queue_deferred_buffers(inst, BUF_OUTPUT);
+	if (ret)
+		return ret;
+
+	ret = process_resume(inst);
+
+	return ret;
+}
+
+int vdec_stop_cmd(struct iris_inst *inst)
+{
+	int ret;
+
+	ret = iris_hfi_drain(inst, INPUT_MPLANE);
+	if (ret)
+		return ret;
+
+	ret = iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN);
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_vdec.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_vdec.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_VDEC_H_
+#define _IRIS_VDEC_H_
+
+#include "iris_instance.h"
+
+int vdec_inst_init(struct iris_inst *inst);
+void vdec_inst_deinit(struct iris_inst *inst);
+int vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);
+int vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
+int vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f);
+int vdec_subscribe_event(struct iris_inst *inst, const struct v4l2_event_subscription *sub);
+int vdec_init_src_change_param(struct iris_inst *inst);
+int vdec_src_change(struct iris_inst *inst);
+int vdec_streamon_input(struct iris_inst *inst);
+int vdec_streamon_output(struct iris_inst *inst);
+int vdec_qbuf(struct iris_inst *inst, struct vb2_buffer *vb2);
+int vdec_start_cmd(struct iris_inst *inst);
+int vdec_stop_cmd(struct iris_inst *inst);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_venc.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_venc.c
@@ -0,0 +1,947 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "hfi_defines.h"
+#include "iris_buffer.h"
+#include "iris_common.h"
+#include "iris_ctrls.h"
+#include "iris_helpers.h"
+#include "iris_hfi.h"
+#include "iris_hfi_packet.h"
+#include "iris_power.h"
+#include "iris_venc.h"
+
+#define SCALE_FACTOR 8
+#define UNSPECIFIED_COLOR_FORMAT 5
+
+static const u32 enc_input_properties[] = {
+	HFI_PROP_NO_OUTPUT,
+};
+
+static const u32 enc_output_properties[] = {
+	HFI_PROP_PICTURE_TYPE,
+	HFI_PROP_BUFFER_MARK,
+};
+
+struct venc_prop_type_handle {
+	u32 type;
+	int (*handle)(struct iris_inst *inst);
+};
+
+int venc_inst_init(struct iris_inst *inst)
+{
+	struct v4l2_format *f;
+	int ret;
+
+	inst->fmt_src = kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL);
+	if (!inst->fmt_src)
+		return -ENOMEM;
+
+	inst->fmt_dst  = kzalloc(sizeof(*inst->fmt_dst), GFP_KERNEL);
+	if (!inst->fmt_dst)
+		return -ENOMEM;
+
+	inst->vb2q_src = kzalloc(sizeof(*inst->vb2q_src), GFP_KERNEL);
+	if (!inst->vb2q_src)
+		return -ENOMEM;
+
+	inst->vb2q_dst = kzalloc(sizeof(*inst->vb2q_dst), GFP_KERNEL);
+	if (!inst->vb2q_dst)
+		return -ENOMEM;
+
+	f = inst->fmt_dst;
+	f->type = OUTPUT_MPLANE;
+	f->fmt.pix_mp.width = DEFAULT_WIDTH;
+	f->fmt.pix_mp.height = DEFAULT_HEIGHT;
+	f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_H264;
+	f->fmt.pix_mp.num_planes = 1;
+	f->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
+	f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_OUTPUT);
+	f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+	f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
+	f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+	f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+	f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
+	inst->buffers.output.min_count = iris_get_buf_min_count(inst, BUF_OUTPUT);
+	inst->buffers.output.actual_count = inst->buffers.output.min_count;
+	inst->buffers.output.size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
+
+	inst->crop.left = 0;
+	inst->crop.top = 0;
+	inst->crop.width = f->fmt.pix_mp.width;
+	inst->crop.height = f->fmt.pix_mp.height;
+
+	inst->compose.left = 0;
+	inst->compose.top = 0;
+	inst->compose.width = f->fmt.pix_mp.width;
+	inst->compose.height = f->fmt.pix_mp.height;
+
+	f = inst->fmt_src;
+	f->type = INPUT_MPLANE;
+	f->fmt.pix_mp.pixelformat = V4L2_PIX_FMT_QC08C;
+	f->fmt.pix_mp.width = DEFAULT_WIDTH;
+	f->fmt.pix_mp.height = DEFAULT_HEIGHT;
+	f->fmt.pix_mp.num_planes = 1;
+	f->fmt.pix_mp.plane_fmt[0].bytesperline = ALIGN(DEFAULT_WIDTH, 128);
+	f->fmt.pix_mp.plane_fmt[0].sizeimage = iris_get_buffer_size(inst, BUF_INPUT);
+	f->fmt.pix_mp.field = V4L2_FIELD_NONE;
+	f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
+	f->fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_DEFAULT;
+	f->fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
+	f->fmt.pix_mp.quantization = V4L2_QUANTIZATION_DEFAULT;
+	inst->buffers.input.min_count = iris_get_buf_min_count(inst, BUF_INPUT);
+	inst->buffers.input.actual_count = inst->buffers.input.min_count;
+	inst->buffers.input.size = f->fmt.pix_mp.plane_fmt[0].sizeimage;
+
+	inst->hfi_rc_type = HFI_RC_VBR_CFR;
+	inst->hfi_layer_type = HFI_HIER_P_SLIDING_WINDOW;
+
+	ret = codec_change(inst, inst->fmt_dst->fmt.pix_mp.pixelformat);
+
+	return ret;
+}
+
+void venc_inst_deinit(struct iris_inst *inst)
+{
+	kfree(inst->fmt_dst);
+	kfree(inst->fmt_src);
+}
+
+int venc_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f)
+{
+	struct iris_core *core;
+	u32 array[32] = {0};
+	u32 i = 0;
+
+	core = inst->core;
+
+	if (f->type == OUTPUT_MPLANE) {
+		u32 codecs = core->cap[ENC_CODECS].value;
+		u32 idx = 0;
+
+		for (i = 0; i <= 31; i++) {
+			if (codecs & BIT(i)) {
+				if (idx >= ARRAY_SIZE(array))
+					break;
+				array[idx] = codecs & BIT(i);
+				idx++;
+			}
+		}
+		if (!array[f->index])
+			return -EINVAL;
+		f->pixelformat = v4l2_codec_from_driver(inst, array[f->index]);
+		if (!f->pixelformat)
+			return -EINVAL;
+		f->flags = V4L2_FMT_FLAG_COMPRESSED;
+		strscpy(f->description, "codec", sizeof(f->description));
+	} else if (f->type == INPUT_MPLANE) {
+		u32 formats = inst->cap[PIX_FMTS].step_or_mask;
+		u32 idx = 0;
+
+		for (i = 0; i <= 31; i++) {
+			if (formats & BIT(i)) {
+				if (idx >= ARRAY_SIZE(array))
+					break;
+				array[idx] = formats & BIT(i);
+				idx++;
+			}
+		}
+		if (!array[f->index])
+			return -EINVAL;
+		f->pixelformat = v4l2_colorformat_from_driver(inst, array[f->index]);
+		if (!f->pixelformat)
+			return -EINVAL;
+		strscpy(f->description, "colorformat", sizeof(f->description));
+	}
+
+	memset(f->reserved, 0, sizeof(f->reserved));
+
+	return 0;
+}
+
+int venc_try_fmt(struct iris_inst *inst, struct v4l2_format *f)
+{
+	struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
+	u32 pix_fmt;
+
+	memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
+
+	if (f->type == INPUT_MPLANE) {
+		pix_fmt = v4l2_colorformat_to_driver(inst, f->fmt.pix_mp.pixelformat);
+		if (!pix_fmt) {
+			f->fmt.pix_mp.pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
+			f->fmt.pix_mp.width = inst->fmt_src->fmt.pix_mp.width;
+			f->fmt.pix_mp.height = inst->fmt_src->fmt.pix_mp.height;
+		}
+	} else if (f->type == OUTPUT_MPLANE) {
+		pix_fmt = v4l2_codec_to_driver(inst, f->fmt.pix_mp.pixelformat);
+		if (!pix_fmt) {
+			f->fmt.pix_mp.width = inst->fmt_dst->fmt.pix_mp.width;
+			f->fmt.pix_mp.height = inst->fmt_dst->fmt.pix_mp.height;
+			f->fmt.pix_mp.pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat;
+		}
+	} else {
+		return -EINVAL;
+	}
+
+	if (pixmp->field == V4L2_FIELD_ANY)
+		pixmp->field = V4L2_FIELD_NONE;
+	pixmp->num_planes = 1;
+
+	return 0;
+}
+
+static int venc_s_fmt_output(struct iris_inst *inst, struct v4l2_format *f)
+{
+	struct v4l2_format *fmt;
+	enum codec_type codec;
+	u32 codec_align;
+	u32 width, height;
+	int ret = 0;
+
+	venc_try_fmt(inst, f);
+
+	fmt = inst->fmt_dst;
+	if (fmt->fmt.pix_mp.pixelformat != f->fmt.pix_mp.pixelformat) {
+		ret = codec_change(inst, f->fmt.pix_mp.pixelformat);
+		if (ret)
+			return ret;
+	}
+	fmt->type = OUTPUT_MPLANE;
+
+	codec = v4l2_codec_to_driver(inst, f->fmt.pix_mp.pixelformat);
+
+	codec_align = (codec == HEVC) ? 32 : 16;
+	width = inst->compose.width;
+	height = inst->compose.height;
+	if (inst->cap[ROTATION].value == 90 || inst->cap[ROTATION].value == 270) {
+		width = inst->compose.height;
+		height = inst->compose.width;
+	}
+	fmt->fmt.pix_mp.width = ALIGN(width, codec_align);
+	fmt->fmt.pix_mp.height = ALIGN(height, codec_align);
+	fmt->fmt.pix_mp.num_planes = 1;
+	fmt->fmt.pix_mp.plane_fmt[0].bytesperline = 0;
+	fmt->fmt.pix_mp.plane_fmt[0].sizeimage =
+		iris_get_buffer_size(inst, BUF_OUTPUT);
+	if (f->fmt.pix_mp.colorspace != V4L2_COLORSPACE_DEFAULT &&
+	    f->fmt.pix_mp.colorspace != V4L2_COLORSPACE_REC709)
+		f->fmt.pix_mp.colorspace = V4L2_COLORSPACE_DEFAULT;
+	fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
+	fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
+	fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
+	fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
+	inst->buffers.output.min_count = iris_get_buf_min_count(inst, BUF_OUTPUT);
+	if (inst->buffers.output.actual_count <
+		inst->buffers.output.min_count) {
+		inst->buffers.output.actual_count =
+			inst->buffers.output.min_count;
+	}
+	inst->buffers.output.size =
+		fmt->fmt.pix_mp.plane_fmt[0].sizeimage;
+
+	memcpy(f, fmt, sizeof(struct v4l2_format));
+
+	return ret;
+}
+
+static int venc_s_fmt_input(struct iris_inst *inst, struct v4l2_format *f)
+{
+	u32 pix_fmt, width, height, size, bytesperline;
+	struct v4l2_format *fmt, *output_fmt;
+	int ret = 0;
+
+	venc_try_fmt(inst, f);
+
+	pix_fmt = v4l2_colorformat_to_driver(inst, f->fmt.pix_mp.pixelformat);
+	inst->cap[PIX_FMTS].value = pix_fmt;
+
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	bytesperline = pix_fmt == FMT_TP10C ?
+		ALIGN(ALIGN(f->fmt.pix_mp.width, 192) * 4 / 3, 256) :
+		ALIGN(f->fmt.pix_mp.width, 128);
+
+	fmt = inst->fmt_src;
+	fmt->type = INPUT_MPLANE;
+	fmt->fmt.pix_mp.width = width;
+	fmt->fmt.pix_mp.height = height;
+	fmt->fmt.pix_mp.num_planes = 1;
+	fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat;
+	fmt->fmt.pix_mp.plane_fmt[0].bytesperline = bytesperline;
+	size = iris_get_buffer_size(inst, BUF_INPUT);
+	fmt->fmt.pix_mp.plane_fmt[0].sizeimage = size;
+	fmt->fmt.pix_mp.colorspace = f->fmt.pix_mp.colorspace;
+	fmt->fmt.pix_mp.xfer_func = f->fmt.pix_mp.xfer_func;
+	fmt->fmt.pix_mp.ycbcr_enc = f->fmt.pix_mp.ycbcr_enc;
+	fmt->fmt.pix_mp.quantization = f->fmt.pix_mp.quantization;
+
+	output_fmt = inst->fmt_dst;
+	output_fmt->fmt.pix_mp.colorspace = fmt->fmt.pix_mp.colorspace;
+	output_fmt->fmt.pix_mp.xfer_func = fmt->fmt.pix_mp.xfer_func;
+	output_fmt->fmt.pix_mp.ycbcr_enc = fmt->fmt.pix_mp.ycbcr_enc;
+	output_fmt->fmt.pix_mp.quantization = fmt->fmt.pix_mp.quantization;
+
+	inst->buffers.input.min_count = iris_get_buf_min_count(inst, BUF_INPUT);
+	if (inst->buffers.input.actual_count <
+	    inst->buffers.input.min_count) {
+		inst->buffers.input.actual_count =
+			inst->buffers.input.min_count;
+	}
+	inst->buffers.input.size = size;
+
+	if (f->fmt.pix_mp.width != inst->crop.width ||
+	    f->fmt.pix_mp.height != inst->crop.height) {
+		inst->crop.top = 0;
+		inst->crop.left = 0;
+		inst->crop.width = f->fmt.pix_mp.width;
+		inst->crop.height = f->fmt.pix_mp.height;
+
+		inst->compose.top = 0;
+		inst->compose.left = 0;
+		inst->compose.width = f->fmt.pix_mp.width;
+		inst->compose.height = f->fmt.pix_mp.height;
+
+		ret = venc_s_fmt_output(inst, output_fmt);
+		if (ret)
+			return ret;
+	}
+
+	memcpy(f, fmt, sizeof(struct v4l2_format));
+
+	return ret;
+}
+
+int venc_s_fmt(struct iris_inst *inst, struct v4l2_format *f)
+{
+	int ret;
+
+	if (f->type == INPUT_MPLANE)
+		ret = venc_s_fmt_input(inst, f);
+	else if (f->type == OUTPUT_MPLANE)
+		ret = venc_s_fmt_output(inst, f);
+	else
+		ret = -EINVAL;
+
+	return ret;
+}
+
+int venc_s_selection(struct iris_inst *inst, struct v4l2_selection *s)
+{
+	struct v4l2_format *output_fmt;
+	int ret;
+
+	if (s->type != INPUT_MPLANE && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
+		return -EINVAL;
+
+	switch (s->target) {
+	case V4L2_SEL_TGT_CROP:
+		if (s->r.left || s->r.top) {
+			s->r.left = 0;
+			s->r.top = 0;
+		}
+		if (s->r.width > inst->fmt_src->fmt.pix_mp.width)
+			s->r.width = inst->fmt_src->fmt.pix_mp.width;
+
+		if (s->r.height > inst->fmt_src->fmt.pix_mp.height)
+			s->r.height = inst->fmt_src->fmt.pix_mp.height;
+
+		inst->crop.left = s->r.left;
+		inst->crop.top = s->r.top;
+		inst->crop.width = s->r.width;
+		inst->crop.height = s->r.height;
+		inst->compose.left = inst->crop.left;
+		inst->compose.top = inst->crop.top;
+		inst->compose.width = inst->crop.width;
+		inst->compose.height = inst->crop.height;
+		output_fmt = inst->fmt_dst;
+		ret = venc_s_fmt_output(inst, output_fmt);
+		if (ret)
+			return ret;
+		break;
+	case V4L2_SEL_TGT_COMPOSE:
+		if (s->r.left < inst->crop.left)
+			s->r.left = inst->crop.left;
+
+		if (s->r.top < inst->crop.top)
+			s->r.top = inst->crop.top;
+
+		if (s->r.width > inst->crop.width)
+			s->r.width = inst->crop.width;
+
+		if (s->r.height > inst->crop.height)
+			s->r.height = inst->crop.height;
+		inst->compose.left = s->r.left;
+		inst->compose.top = s->r.top;
+		inst->compose.width = s->r.width;
+		inst->compose.height = s->r.height;
+
+		output_fmt = inst->fmt_dst;
+		ret = venc_s_fmt_output(inst, output_fmt);
+		if (ret)
+			return ret;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+int venc_s_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm)
+{
+	struct v4l2_fract *timeperframe = NULL;
+	u32 q16_rate, max_rate, default_rate;
+	u64 us_per_frame = 0, input_rate = 0;
+	bool is_frame_rate = false;
+	int ret = 0;
+
+	if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		timeperframe = &s_parm->parm.output.timeperframe;
+		max_rate = inst->cap[OPERATING_RATE].max >> 16;
+		default_rate = inst->cap[OPERATING_RATE].value >> 16;
+		s_parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
+	} else {
+		timeperframe = &s_parm->parm.capture.timeperframe;
+		is_frame_rate = true;
+		max_rate = inst->cap[FRAME_RATE].max >> 16;
+		default_rate = inst->cap[FRAME_RATE].value >> 16;
+		s_parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+	}
+
+	if (!timeperframe->denominator || !timeperframe->numerator) {
+		if (!timeperframe->numerator)
+			timeperframe->numerator = 1;
+		if (!timeperframe->denominator)
+			timeperframe->denominator = default_rate;
+	}
+
+	us_per_frame = timeperframe->numerator * (u64)USEC_PER_SEC;
+	us_per_frame = div64_u64(us_per_frame, timeperframe->denominator);
+
+	if (!us_per_frame) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	input_rate = (u64)USEC_PER_SEC;
+	input_rate = div64_u64(input_rate, us_per_frame);
+
+	q16_rate = (u32)input_rate << 16;
+	if (is_frame_rate)
+		inst->cap[FRAME_RATE].value = q16_rate;
+	else
+		inst->cap[OPERATING_RATE].value = q16_rate;
+
+	if ((s_parm->type == INPUT_MPLANE && inst->vb2q_src->streaming) ||
+	    (s_parm->type == OUTPUT_MPLANE && inst->vb2q_dst->streaming)) {
+		ret = check_core_mbps_mbpf(inst);
+		if (ret)
+			goto reset_rate;
+		ret = input_rate > max_rate;
+		if (ret) {
+			ret = -ENOMEM;
+			goto reset_rate;
+		}
+	}
+
+	if (is_frame_rate)
+		inst->cap[FRAME_RATE].flags |= CAP_FLAG_CLIENT_SET;
+	else
+		inst->cap[OPERATING_RATE].flags |= CAP_FLAG_CLIENT_SET;
+
+	if (inst->vb2q_dst->streaming) {
+		ret = iris_hfi_set_property(inst,
+					    HFI_PROP_FRAME_RATE,
+					    HFI_HOST_FLAGS_NONE,
+					    HFI_PORT_BITSTREAM,
+					    HFI_PAYLOAD_Q16,
+					    &q16_rate,
+					    sizeof(u32));
+		if (ret)
+			goto exit;
+	}
+
+	return ret;
+
+reset_rate:
+	if (ret) {
+		if (is_frame_rate)
+			inst->cap[FRAME_RATE].value = default_rate << 16;
+		else
+			inst->cap[OPERATING_RATE].value = default_rate << 16;
+	}
+exit:
+	return ret;
+}
+
+int venc_g_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm)
+{
+	struct v4l2_fract *timeperframe = NULL;
+
+	if (s_parm->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		timeperframe = &s_parm->parm.output.timeperframe;
+		timeperframe->numerator = 1;
+		timeperframe->denominator =
+			inst->cap[OPERATING_RATE].value >> 16;
+		s_parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
+	} else {
+		timeperframe = &s_parm->parm.capture.timeperframe;
+		timeperframe->numerator = 1;
+		timeperframe->denominator =
+			inst->cap[FRAME_RATE].value >> 16;
+		s_parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
+	}
+
+	return 0;
+}
+
+int venc_subscribe_event(struct iris_inst *inst,
+			 const struct v4l2_event_subscription *sub)
+{
+	int ret;
+
+	switch (sub->type) {
+	case V4L2_EVENT_EOS:
+		ret = v4l2_event_subscribe(&inst->fh, sub, MAX_EVENTS, NULL);
+		break;
+	case V4L2_EVENT_CTRL:
+		ret = v4l2_ctrl_subscribe_event(&inst->fh, sub);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return ret;
+}
+
+int venc_start_cmd(struct iris_inst *inst)
+{
+	vb2_clear_last_buffer_dequeued(inst->vb2q_dst);
+
+	return process_resume(inst);
+}
+
+int venc_stop_cmd(struct iris_inst *inst)
+{
+	int ret;
+
+	ret = iris_hfi_drain(inst, INPUT_MPLANE);
+	if (ret)
+		return ret;
+
+	ret = iris_inst_change_sub_state(inst, 0, IRIS_INST_SUB_DRAIN);
+
+	iris_scale_power(inst);
+
+	return ret;
+}
+
+int venc_qbuf(struct iris_inst *inst, struct vb2_buffer *vb2)
+{
+	struct iris_buffer *buf = NULL;
+	int ret;
+
+	buf = get_driver_buf(inst, vb2->type, vb2->index);
+	if (!buf)
+		return -EINVAL;
+
+	ret = vb2_buffer_to_driver(vb2, buf);
+	if (ret)
+		return ret;
+
+	if (!allow_qbuf(inst, vb2->type)) {
+		buf->attr |= BUF_ATTR_DEFERRED;
+		return 0;
+	}
+
+	iris_scale_power(inst);
+
+	return queue_buffer(inst, buf);
+}
+
+static int check_scaling_supported(struct iris_inst *inst)
+{
+	u32 iwidth, owidth, iheight, oheight;
+
+	if (!(inst->crop.left != inst->compose.left ||
+	      inst->crop.top != inst->compose.top ||
+	      inst->crop.width != inst->compose.width ||
+	      inst->crop.height != inst->compose.height))
+		return 0;
+
+	iwidth = inst->crop.width;
+	iheight = inst->crop.height;
+	owidth = inst->compose.width;
+	oheight = inst->compose.height;
+
+	if (owidth > iwidth || oheight > iheight)
+		return -EINVAL;
+
+	if (iwidth > owidth * SCALE_FACTOR || iheight > oheight * SCALE_FACTOR)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int venc_set_colorformat(struct iris_inst *inst)
+{
+	u32 hfi_colorformat;
+	u32 pixelformat;
+
+	pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat;
+	hfi_colorformat = get_hfi_colorformat(pixelformat);
+
+	return iris_hfi_set_property(inst,
+				     HFI_PROP_COLOR_FORMAT,
+				     HFI_HOST_FLAGS_NONE,
+				     get_hfi_port(inst, INPUT_MPLANE),
+				     HFI_PAYLOAD_U32_ENUM,
+				     &hfi_colorformat,
+				     sizeof(u32));
+}
+
+static int venc_set_stride_scanline(struct iris_inst *inst)
+{
+	u32 color_format, stride_y, scanline_y;
+	u32 stride_uv = 0, scanline_uv = 0;
+	u32 payload[2];
+
+	color_format = inst->cap[PIX_FMTS].value;
+	if (!is_linear_colorformat(color_format))
+		return 0;
+
+	stride_y = color_format == FMT_TP10C ?
+		ALIGN(inst->fmt_src->fmt.pix_mp.width, 192) :
+		ALIGN(inst->fmt_src->fmt.pix_mp.width, 128);
+	scanline_y = color_format == FMT_TP10C ?
+		ALIGN(inst->fmt_src->fmt.pix_mp.height, 16) :
+		ALIGN(inst->fmt_src->fmt.pix_mp.height, 32);
+
+	if (color_format == FMT_NV12) {
+		stride_uv = stride_y;
+		scanline_uv = scanline_y / 2;
+	}
+
+	payload[0] = stride_y << 16 | scanline_y;
+	payload[1] = stride_uv << 16 | scanline_uv;
+
+	return iris_hfi_set_property(inst,
+				     HFI_PROP_LINEAR_STRIDE_SCANLINE,
+				     HFI_HOST_FLAGS_NONE,
+				     get_hfi_port(inst, INPUT_MPLANE),
+				     HFI_PAYLOAD_64_PACKED,
+				     &payload,
+				     sizeof(u64));
+}
+
+static int venc_set_raw_resolution(struct iris_inst *inst)
+{
+	u32 resolution;
+
+	resolution = (inst->fmt_src->fmt.pix_mp.width << 16) |
+		inst->fmt_src->fmt.pix_mp.height;
+
+	return iris_hfi_set_property(inst,
+				     HFI_PROP_RAW_RESOLUTION,
+				     HFI_HOST_FLAGS_NONE,
+				     get_hfi_port(inst, INPUT_MPLANE),
+				     HFI_PAYLOAD_32_PACKED,
+				     &resolution,
+				     sizeof(u32));
+}
+
+static int venc_set_bitstream_resolution(struct iris_inst *inst)
+{
+	u32 resolution;
+
+	resolution = (inst->fmt_dst->fmt.pix_mp.width << 16) |
+		inst->fmt_dst->fmt.pix_mp.height;
+
+	return iris_hfi_set_property(inst,
+				     HFI_PROP_BITSTREAM_RESOLUTION,
+				     HFI_HOST_FLAGS_NONE,
+				     get_hfi_port(inst, OUTPUT_MPLANE),
+				     HFI_PAYLOAD_32_PACKED,
+				     &resolution,
+				     sizeof(u32));
+}
+
+static int venc_set_inp_crop_offsets(struct iris_inst *inst)
+{
+	u32 left_offset, top_offset, right_offset, bottom_offset;
+	u32 crop[2] = {0};
+	u32 width, height;
+
+	left_offset = inst->crop.left;
+	top_offset = inst->crop.top;
+	width = inst->crop.width;
+	height = inst->crop.height;
+
+	right_offset = (inst->fmt_src->fmt.pix_mp.width - width);
+	bottom_offset = (inst->fmt_src->fmt.pix_mp.height - height);
+
+	crop[0] = left_offset << 16 | top_offset;
+	crop[1] = right_offset << 16 | bottom_offset;
+
+	return iris_hfi_set_property(inst,
+				     HFI_PROP_CROP_OFFSETS,
+				     HFI_HOST_FLAGS_NONE,
+				     get_hfi_port(inst, INPUT_MPLANE),
+				     HFI_PAYLOAD_64_PACKED,
+				     &crop,
+				     sizeof(u64));
+}
+
+static int venc_set_out_crop_offsets(struct iris_inst *inst)
+{
+	u32 left_offset, top_offset, right_offset, bottom_offset;
+	u32 crop[2] = {0};
+	u32 width, height;
+
+	left_offset = inst->compose.left;
+	top_offset = inst->compose.top;
+	width = inst->compose.width;
+	height = inst->compose.height;
+	if (inst->cap[ROTATION].value == 90 || inst->cap[ROTATION].value == 270) {
+		width = inst->compose.height;
+		height = inst->compose.width;
+	}
+
+	right_offset = (inst->fmt_dst->fmt.pix_mp.width - width);
+	bottom_offset = (inst->fmt_dst->fmt.pix_mp.height - height);
+
+	crop[0] = left_offset << 16 | top_offset;
+	crop[1] = right_offset << 16 | bottom_offset;
+
+	return iris_hfi_set_property(inst,
+				     HFI_PROP_CROP_OFFSETS,
+				     HFI_HOST_FLAGS_NONE,
+				     get_hfi_port(inst, OUTPUT_MPLANE),
+				     HFI_PAYLOAD_64_PACKED,
+				     &crop,
+				     sizeof(u64));
+}
+
+static int venc_set_colorspace(struct iris_inst *inst)
+{
+	u32 video_signal_type_present_flag = 0, payload = 0;
+	u32 matrix_coeff = HFI_MATRIX_COEFF_RESERVED;
+	u32 video_format = UNSPECIFIED_COLOR_FORMAT;
+	struct v4l2_pix_format_mplane *pixmp = NULL;
+	u32 transfer_char = HFI_TRANSFER_RESERVED;
+	u32 colour_description_present_flag = 0;
+	u32 primaries = HFI_PRIMARIES_RESERVED;
+	u32 full_range = 0;
+
+	pixmp = &inst->fmt_src->fmt.pix_mp;
+	if (pixmp->colorspace != V4L2_COLORSPACE_DEFAULT ||
+	    pixmp->ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT ||
+	    pixmp->xfer_func != V4L2_XFER_FUNC_DEFAULT) {
+		colour_description_present_flag = 1;
+		video_signal_type_present_flag = 1;
+		primaries = get_hfi_color_primaries(pixmp->colorspace);
+		matrix_coeff = get_hfi_matrix_coefficients(pixmp->ycbcr_enc);
+		transfer_char = get_hfi_transer_char(pixmp->xfer_func);
+	}
+
+	if (pixmp->quantization != V4L2_QUANTIZATION_DEFAULT) {
+		video_signal_type_present_flag = 1;
+		full_range = pixmp->quantization ==
+			V4L2_QUANTIZATION_FULL_RANGE ? 1 : 0;
+	}
+
+	payload = (matrix_coeff & 0xFF) |
+		((transfer_char << 8) & 0xFF00) |
+		((primaries << 16) & 0xFF0000) |
+		((colour_description_present_flag << 24) & 0x1000000) |
+		((full_range << 25) & 0x2000000) |
+		((video_format << 26) & 0x1C000000) |
+		((video_signal_type_present_flag << 29) & 0x20000000);
+
+	return iris_hfi_set_property(inst,
+				     HFI_PROP_SIGNAL_COLOR_INFO,
+				     HFI_HOST_FLAGS_NONE,
+				     get_hfi_port(inst, INPUT_MPLANE),
+				     HFI_PAYLOAD_32_PACKED,
+				     &payload,
+				     sizeof(u32));
+}
+
+static int venc_set_quality_mode(struct iris_inst *inst)
+{
+	u32 mode;
+
+	mode = decide_quality_mode(inst);
+	return iris_hfi_set_property(inst,
+				     HFI_PROP_QUALITY_MODE,
+				     HFI_HOST_FLAGS_NONE,
+				     HFI_PORT_BITSTREAM,
+				     HFI_PAYLOAD_U32_ENUM,
+				     &mode,
+				     sizeof(u32));
+}
+
+static int venc_set_input_properties(struct iris_inst *inst)
+{
+	int j, ret;
+	static const struct venc_prop_type_handle prop_type_handle_arr[] = {
+		{HFI_PROP_COLOR_FORMAT,               venc_set_colorformat                 },
+		{HFI_PROP_RAW_RESOLUTION,             venc_set_raw_resolution              },
+		{HFI_PROP_CROP_OFFSETS,               venc_set_inp_crop_offsets            },
+		{HFI_PROP_LINEAR_STRIDE_SCANLINE,     venc_set_stride_scanline             },
+		{HFI_PROP_SIGNAL_COLOR_INFO,          venc_set_colorspace                  },
+	};
+
+	for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) {
+		ret = prop_type_handle_arr[j].handle(inst);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static int venc_property_subscription(struct iris_inst *inst, u32 plane)
+{
+	u32 payload[32] = {0};
+	u32 payload_size = 0;
+	u32 i;
+
+	payload[0] = HFI_MODE_PROPERTY;
+	if (plane == INPUT_MPLANE) {
+		for (i = 0; i < ARRAY_SIZE(enc_input_properties); i++)
+			payload[i + 1] = enc_input_properties[i];
+		payload_size = (ARRAY_SIZE(enc_input_properties) + 1) *
+				sizeof(u32);
+	} else if (plane == OUTPUT_MPLANE) {
+		for (i = 0; i < ARRAY_SIZE(enc_output_properties); i++)
+			payload[i + 1] = enc_output_properties[i];
+		payload_size = (ARRAY_SIZE(enc_output_properties) + 1) *
+				sizeof(u32);
+	} else {
+		return -EINVAL;
+	}
+
+	return iris_hfi_session_subscribe_mode(inst,
+					       HFI_CMD_SUBSCRIBE_MODE,
+					       plane,
+					       HFI_PAYLOAD_U32_ARRAY,
+					       &payload[0],
+					       payload_size);
+}
+
+int venc_streamon_input(struct iris_inst *inst)
+{
+	int ret;
+
+	ret = check_session_supported(inst);
+	if (ret)
+		goto error;
+
+	ret = check_scaling_supported(inst);
+	if (ret)
+		goto error;
+
+	ret = venc_set_input_properties(inst);
+	if (ret)
+		goto error;
+
+	ret = iris_get_internal_buffers(inst, INPUT_MPLANE);
+	if (ret)
+		goto error;
+
+	ret = iris_destroy_internal_buffers(inst, INPUT_MPLANE);
+	if (ret)
+		goto error;
+
+	ret = iris_create_input_internal_buffers(inst);
+	if (ret)
+		goto error;
+
+	ret = iris_queue_input_internal_buffers(inst);
+	if (ret)
+		goto error;
+
+	ret = venc_property_subscription(inst, INPUT_MPLANE);
+	if (ret)
+		goto error;
+
+	ret = process_streamon_input(inst);
+	if (ret)
+		goto error;
+
+	return ret;
+
+error:
+	return ret;
+}
+
+static int venc_set_output_properties(struct iris_inst *inst)
+{
+	int j, ret;
+	static const struct venc_prop_type_handle prop_type_handle_arr[] = {
+		{HFI_PROP_BITSTREAM_RESOLUTION,       venc_set_bitstream_resolution    },
+		{HFI_PROP_CROP_OFFSETS,               venc_set_out_crop_offsets        },
+	};
+
+	for (j = 0; j < ARRAY_SIZE(prop_type_handle_arr); j++) {
+		ret = prop_type_handle_arr[j].handle(inst);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+int venc_streamon_output(struct iris_inst *inst)
+{
+	int ret;
+
+	ret = venc_set_output_properties(inst);
+	if (ret)
+		goto error;
+
+	ret = set_v4l2_properties(inst);
+	if (ret)
+		goto error;
+
+	ret = venc_set_quality_mode(inst);
+	if (ret)
+		goto error;
+
+	ret = iris_get_internal_buffers(inst, OUTPUT_MPLANE);
+	if (ret)
+		goto error;
+
+	ret = iris_destroy_internal_buffers(inst, OUTPUT_MPLANE);
+	if (ret)
+		goto error;
+
+	ret = iris_create_output_internal_buffers(inst);
+	if (ret)
+		goto error;
+
+	ret = iris_queue_output_internal_buffers(inst);
+	if (ret)
+		goto error;
+
+	ret = venc_property_subscription(inst, OUTPUT_MPLANE);
+	if (ret)
+		goto error;
+
+	ret = process_streamon_output(inst);
+	if (ret)
+		goto error;
+
+	return ret;
+
+error:
+	session_streamoff(inst, OUTPUT_MPLANE);
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_venc.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_venc.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_VENC_H_
+#define _IRIS_VENC_H_
+
+#include "iris_instance.h"
+
+int venc_inst_init(struct iris_inst *inst);
+void venc_inst_deinit(struct iris_inst *inst);
+int venc_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f);
+int venc_try_fmt(struct iris_inst *inst, struct v4l2_format *f);
+int venc_s_fmt(struct iris_inst *inst, struct v4l2_format *f);
+int venc_s_selection(struct iris_inst *inst, struct v4l2_selection *s);
+int venc_s_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm);
+int venc_g_param(struct iris_inst *inst, struct v4l2_streamparm *s_parm);
+int venc_subscribe_event(struct iris_inst *inst,
+			 const struct v4l2_event_subscription *sub);
+int venc_start_cmd(struct iris_inst *inst);
+int venc_stop_cmd(struct iris_inst *inst);
+int venc_qbuf(struct iris_inst *inst, struct vb2_buffer *vb2);
+int venc_streamon_input(struct iris_inst *inst);
+int venc_streamon_output(struct iris_inst *inst);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_vidc.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_vidc.c
@@ -0,0 +1,1429 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/videodev2.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-ioctl.h>
+
+#include "iris_buffer.h"
+#include "iris_common.h"
+#include "iris_ctrls.h"
+#include "iris_helpers.h"
+#include "iris_hfi.h"
+#include "iris_instance.h"
+#include "iris_power.h"
+#include "iris_vdec.h"
+#include "iris_venc.h"
+#include "iris_vidc.h"
+#include "iris_vb2.h"
+#include "memory.h"
+
+#define VIDC_DRV_NAME "iris_driver"
+#define VIDC_BUS_NAME "platform:iris_bus"
+
+static int vidc_v4l2_fh_init(struct iris_inst *inst)
+{
+	struct iris_core *core;
+
+	core = inst->core;
+
+	if (inst->fh.vdev)
+		return -EINVAL;
+
+	if (inst->domain == ENCODER)
+		v4l2_fh_init(&inst->fh, core->vdev_enc);
+	else if (inst->domain == DECODER)
+		v4l2_fh_init(&inst->fh, core->vdev_dec);
+
+	inst->fh.ctrl_handler = &inst->ctrl_handler;
+	v4l2_fh_add(&inst->fh);
+
+	return 0;
+}
+
+static int vidc_v4l2_fh_deinit(struct iris_inst *inst)
+{
+	if (!inst->fh.vdev)
+		return 0;
+
+	v4l2_fh_del(&inst->fh);
+	inst->fh.ctrl_handler = NULL;
+	v4l2_fh_exit(&inst->fh);
+
+	return 0;
+}
+
+static int vb2q_init(struct iris_inst *inst,
+		     struct vb2_queue *q, enum v4l2_buf_type type)
+{
+	struct iris_core *core;
+
+	core = inst->core;
+
+	q->lock = &inst->ctx_q_lock;
+	q->type = type;
+	q->io_modes = VB2_MMAP | VB2_DMABUF;
+	q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
+	q->ops = core->vb2_ops;
+	q->mem_ops = core->vb2_mem_ops;
+	q->drv_priv = inst;
+	q->copy_timestamp = 1;
+	q->min_queued_buffers = 0;
+	return vb2_queue_init(q);
+}
+
+static int vidc_vb2_queue_init(struct iris_inst *inst)
+{
+	int ret;
+
+	ret = vb2q_init(inst, inst->vb2q_src, INPUT_MPLANE);
+	if (ret)
+		return ret;
+
+	ret = vb2q_init(inst, inst->vb2q_dst, OUTPUT_MPLANE);
+	if (ret)
+		goto fail_vb2q_src_deinit;
+
+	return ret;
+
+fail_vb2q_src_deinit:
+	vb2_queue_release(inst->vb2q_src);
+
+	return ret;
+}
+
+static int vidc_vb2_queue_deinit(struct iris_inst *inst)
+{
+	vb2_queue_release(inst->vb2q_src);
+	kfree(inst->vb2q_src);
+	inst->vb2q_src = NULL;
+
+	vb2_queue_release(inst->vb2q_dst);
+	kfree(inst->vb2q_dst);
+	inst->vb2q_dst = NULL;
+
+	return 0;
+}
+
+static int vidc_add_session(struct iris_inst *inst)
+{
+	struct iris_core *core;
+	struct iris_inst *i;
+	u32 count = 0;
+	int ret = 0;
+
+	core = inst->core;
+
+	mutex_lock(&core->lock);
+	if (core->state != IRIS_CORE_INIT) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+	list_for_each_entry(i, &core->instances, list)
+		count++;
+
+	if (count < core->cap[MAX_SESSION_COUNT].value)
+		list_add_tail(&inst->list, &core->instances);
+	else
+		ret = -EAGAIN;
+unlock:
+	mutex_unlock(&core->lock);
+
+	return ret;
+}
+
+static int vidc_remove_session(struct iris_inst *inst)
+{
+	struct iris_inst *i, *temp;
+	struct iris_core *core;
+
+	core = inst->core;
+
+	mutex_lock(&core->lock);
+	list_for_each_entry_safe(i, temp, &core->instances, list) {
+		if (i->session_id == inst->session_id) {
+			list_del_init(&i->list);
+			break;
+		}
+	}
+	mutex_unlock(&core->lock);
+
+	return 0;
+}
+
+static struct iris_inst *get_vidc_inst(struct file *filp, void *fh)
+{
+	if (!filp || !filp->private_data)
+		return NULL;
+
+	return container_of(filp->private_data,
+					struct iris_inst, fh);
+}
+
+int vidc_open(struct file *filp)
+{
+	struct iris_core *core = video_drvdata(filp);
+	struct iris_inst *inst = NULL;
+	struct video_device *vdev;
+	u32 session_type = 0;
+	int i = 0;
+	int ret;
+
+	vdev = video_devdata(filp);
+	if (strcmp(vdev->name, "qcom-iris-decoder") == 0)
+		session_type = DECODER;
+	else if (strcmp(vdev->name, "qcom-iris-encoder") == 0)
+		session_type = ENCODER;
+
+	if (session_type != DECODER && session_type != ENCODER)
+		return -EINVAL;
+
+	ret = iris_pm_get(core);
+	if (ret)
+		return ret;
+
+	ret = iris_core_init(core);
+	if (ret)
+		goto fail_pm_put;
+
+	ret = iris_core_init_wait(core);
+	if (ret)
+		goto fail_pm_put;
+
+	inst = kzalloc(sizeof(*inst), GFP_KERNEL);
+	if (!inst) {
+		ret = -ENOMEM;
+		goto fail_pm_put;
+	}
+
+	inst->core = core;
+	inst->domain = session_type;
+	inst->session_id = hash32_ptr(inst);
+	inst->ipsc_properties_set = false;
+	inst->opsc_properties_set = false;
+	inst->has_bframe = false;
+	inst->iframe = false;
+	iris_inst_change_state(inst, IRIS_INST_OPEN);
+	mutex_init(&inst->lock);
+	mutex_init(&inst->ctx_q_lock);
+
+	ret = vidc_add_session(inst);
+	if (ret)
+		goto fail_free_inst;
+
+	ret = iris_mem_pool_init(inst);
+	if (ret)
+		goto fail_remove_session;
+
+	INIT_LIST_HEAD(&inst->buffers.input.list);
+	INIT_LIST_HEAD(&inst->buffers.output.list);
+	INIT_LIST_HEAD(&inst->buffers.read_only.list);
+	INIT_LIST_HEAD(&inst->buffers.bin.list);
+	INIT_LIST_HEAD(&inst->buffers.arp.list);
+	INIT_LIST_HEAD(&inst->buffers.comv.list);
+	INIT_LIST_HEAD(&inst->buffers.non_comv.list);
+	INIT_LIST_HEAD(&inst->buffers.line.list);
+	INIT_LIST_HEAD(&inst->buffers.dpb.list);
+	INIT_LIST_HEAD(&inst->buffers.persist.list);
+	INIT_LIST_HEAD(&inst->buffers.vpss.list);
+	INIT_LIST_HEAD(&inst->caps_list);
+	INIT_LIST_HEAD(&inst->input_timer_list);
+	for (i = 0; i < MAX_SIGNAL; i++)
+		init_completion(&inst->completions[i]);
+
+	ret = vidc_v4l2_fh_init(inst);
+	if (ret)
+		goto fail_mem_pool_deinit;
+
+	if (inst->domain == DECODER)
+		ret = vdec_inst_init(inst);
+	else if (inst->domain == ENCODER)
+		ret = venc_inst_init(inst);
+	if (ret)
+		goto fail_fh_deinit;
+
+	ret = vidc_vb2_queue_init(inst);
+	if (ret)
+		goto fail_inst_deinit;
+
+	iris_scale_power(inst);
+
+	ret = iris_hfi_session_open(inst);
+	if (ret) {
+		dev_err(core->dev, "%s: session open failed\n", __func__);
+		goto fail_core_deinit;
+	}
+
+	iris_pm_put(core, true);
+
+	filp->private_data = &inst->fh;
+
+	return 0;
+
+fail_core_deinit:
+	v4l2_ctrl_handler_free(&inst->ctrl_handler);
+	iris_core_deinit(core);
+	vidc_vb2_queue_deinit(inst);
+fail_inst_deinit:
+	if (inst->domain == DECODER)
+		vdec_inst_deinit(inst);
+	else if (inst->domain == ENCODER)
+		venc_inst_deinit(inst);
+fail_fh_deinit:
+	vidc_v4l2_fh_deinit(inst);
+fail_mem_pool_deinit:
+	iris_mem_pool_deinit(inst);
+fail_remove_session:
+	vidc_remove_session(inst);
+fail_free_inst:
+	mutex_destroy(&inst->ctx_q_lock);
+	mutex_destroy(&inst->lock);
+	kfree(inst);
+fail_pm_put:
+	iris_pm_put(core, false);
+
+	return ret;
+}
+
+int vidc_close(struct file *filp)
+{
+	struct iris_inst *inst;
+	struct iris_core *core;
+
+	inst = get_vidc_inst(filp, NULL);
+	if (!inst)
+		return -EINVAL;
+
+	core = inst->core;
+
+	v4l2_ctrl_handler_free(&inst->ctrl_handler);
+	if (inst->domain == DECODER)
+		vdec_inst_deinit(inst);
+	else if (inst->domain == ENCODER)
+		venc_inst_deinit(inst);
+
+	mutex_lock(&inst->lock);
+	iris_pm_get(core);
+	close_session(inst);
+	iris_inst_change_state(inst, IRIS_INST_CLOSE);
+	vidc_vb2_queue_deinit(inst);
+	vidc_v4l2_fh_deinit(inst);
+	iris_destroy_buffers(inst);
+	vidc_remove_session(inst);
+	iris_pm_put(core, false);
+	mutex_unlock(&inst->lock);
+	mutex_destroy(&inst->ctx_q_lock);
+	mutex_destroy(&inst->lock);
+	kfree(inst);
+	filp->private_data = NULL;
+
+	return 0;
+}
+
+static __poll_t get_poll_flags(struct iris_inst *inst, u32 plane)
+{
+	struct vb2_buffer *vb = NULL;
+	struct vb2_queue *q = NULL;
+	unsigned long flags = 0;
+	__poll_t poll = 0;
+
+	if (plane == INPUT_MPLANE)
+		q = inst->vb2q_src;
+	else if (plane == OUTPUT_MPLANE)
+		q = inst->vb2q_dst;
+
+	if (!q)
+		return EPOLLERR;
+
+	spin_lock_irqsave(&q->done_lock, flags);
+	if (!list_empty(&q->done_list))
+		vb = list_first_entry(&q->done_list, struct vb2_buffer,
+				      done_entry);
+	if (vb && (vb->state == VB2_BUF_STATE_DONE ||
+		   vb->state == VB2_BUF_STATE_ERROR)) {
+		if (plane == OUTPUT_MPLANE)
+			poll |= EPOLLIN | EPOLLRDNORM;
+		else if (plane == INPUT_MPLANE)
+			poll |= EPOLLOUT | EPOLLWRNORM;
+	}
+	spin_unlock_irqrestore(&q->done_lock, flags);
+
+	return poll;
+}
+
+static __poll_t vidc_poll(struct file *filp, struct poll_table_struct *pt)
+{
+	struct iris_inst *inst;
+	__poll_t poll = 0;
+
+	inst = get_vidc_inst(filp, NULL);
+	if (!inst)
+		return EPOLLERR;
+
+	if (IS_SESSION_ERROR(inst))
+		return EPOLLERR;
+
+	poll_wait(filp, &inst->fh.wait, pt);
+	poll_wait(filp, &inst->vb2q_src->done_wq, pt);
+	poll_wait(filp, &inst->vb2q_dst->done_wq, pt);
+
+	if (v4l2_event_pending(&inst->fh))
+		poll |= EPOLLPRI;
+
+	poll |= get_poll_flags(inst, INPUT_MPLANE);
+	poll |= get_poll_flags(inst, OUTPUT_MPLANE);
+
+	return poll;
+}
+
+static int vidc_enum_fmt(struct file *filp, void *fh, struct v4l2_fmtdesc *f)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (inst->domain == DECODER)
+		ret = vdec_enum_fmt(inst, f);
+	else if (inst->domain == ENCODER)
+		ret = venc_enum_fmt(inst, f);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_try_fmt(struct file *filp, void *fh, struct v4l2_format *f)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (!allow_s_fmt(inst, f->type)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (inst->domain == DECODER)
+		ret = vdec_try_fmt(inst, f);
+	else if (inst->domain == ENCODER)
+		ret = venc_try_fmt(inst, f);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_s_fmt(struct file *filp, void *fh, struct v4l2_format *f)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (!allow_s_fmt(inst, f->type)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (inst->domain == DECODER)
+		ret = vdec_s_fmt(inst, f);
+	else if (inst->domain == ENCODER)
+		ret = venc_s_fmt(inst, f);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_g_fmt(struct file *filp, void *fh, struct v4l2_format *f)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (f->type == INPUT_MPLANE)
+		memcpy(f, inst->fmt_src, sizeof(*f));
+	else if (f->type == OUTPUT_MPLANE)
+		memcpy(f, inst->fmt_dst, sizeof(*f));
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_enum_framesizes(struct file *filp, void *fh,
+				struct v4l2_frmsizeenum *fsize)
+{
+	enum colorformat_type colorfmt;
+	struct iris_inst *inst;
+	enum codec_type codec;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !fsize)
+		return -EINVAL;
+
+	if (fsize->index)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	codec = v4l2_codec_to_driver(inst, fsize->pixel_format);
+	if (!codec) {
+		colorfmt = v4l2_colorformat_to_driver(inst, fsize->pixel_format);
+		if (colorfmt == FMT_NONE) {
+			ret = -EINVAL;
+			goto unlock;
+		}
+	}
+
+	fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+	fsize->stepwise.min_width = inst->cap[FRAME_WIDTH].min;
+	fsize->stepwise.max_width = inst->cap[FRAME_WIDTH].max;
+	fsize->stepwise.step_width = inst->cap[FRAME_WIDTH].step_or_mask;
+	fsize->stepwise.min_height = inst->cap[FRAME_HEIGHT].min;
+	fsize->stepwise.max_height = inst->cap[FRAME_HEIGHT].max;
+	fsize->stepwise.step_height = inst->cap[FRAME_HEIGHT].step_or_mask;
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_enum_frameintervals(struct file *filp, void *fh,
+				    struct v4l2_frmivalenum *fival)
+
+{
+	enum colorformat_type colorfmt;
+	struct iris_inst *inst;
+	struct iris_core *core;
+	u32 fps, mbpf;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !fival)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (inst->domain == DECODER) {
+		ret = -ENOTTY;
+		goto unlock;
+	}
+
+	core = inst->core;
+
+	if (fival->index) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	colorfmt = v4l2_colorformat_to_driver(inst, fival->pixel_format);
+	if (colorfmt == FMT_NONE) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (fival->width > inst->cap[FRAME_WIDTH].max ||
+	    fival->width < inst->cap[FRAME_WIDTH].min ||
+	    fival->height > inst->cap[FRAME_HEIGHT].max ||
+	    fival->height < inst->cap[FRAME_HEIGHT].min) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	mbpf = NUM_MBS_PER_FRAME(fival->height, fival->width);
+	fps = core->cap[MAX_MBPS].value / mbpf;
+
+	fival->type = V4L2_FRMIVAL_TYPE_STEPWISE;
+	fival->stepwise.min.numerator = 1;
+	fival->stepwise.min.denominator = 1;
+
+	fival->stepwise.max.numerator = 1;
+	fival->stepwise.max.denominator =
+			min_t(u32, fps, inst->cap[FRAME_RATE].max);
+	fival->stepwise.step.numerator = 1;
+	fival->stepwise.step.denominator = inst->cap[FRAME_RATE].max;
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_reqbufs(struct file *filp, void *fh, struct v4l2_requestbuffers *b)
+{
+	struct vb2_queue *vb2q = NULL;
+	struct iris_inst *inst;
+	int ret;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !b)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (!allow_reqbufs(inst, b->type)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	vb2q = get_vb2q(inst, b->type);
+	if (!vb2q) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	ret = vb2_reqbufs(vb2q, b);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_querybuf(struct file *filp, void *fh, struct v4l2_buffer *b)
+{
+	struct vb2_queue *vb2q = NULL;
+	struct iris_inst *inst;
+	int ret;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !b)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	vb2q = get_vb2q(inst, b->type);
+	if (!vb2q) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	ret = vb2_querybuf(vb2q, b);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_create_bufs(struct file *filp, void *fh, struct v4l2_create_buffers *b)
+{
+	struct iris_inst *inst;
+	struct vb2_queue *vb2q;
+	struct v4l2_format *f;
+	int ret;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !b)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	f = &b->format;
+	vb2q = get_vb2q(inst, f->type);
+	if (!vb2q) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	ret = vb2_create_bufs(vb2q, b);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_prepare_buf(struct file *filp, void *fh, struct v4l2_buffer *b)
+{
+	struct video_device *vdev;
+	struct iris_inst *inst;
+	struct vb2_queue *vb2q;
+	int ret;
+
+	inst = get_vidc_inst(filp, fh);
+	vdev = video_devdata(filp);
+	if (!inst || !vdev || !vdev->v4l2_dev->mdev)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	vb2q = get_vb2q(inst, b->type);
+	if (!vb2q) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	ret = vb2_prepare_buf(vb2q, vdev->v4l2_dev->mdev, b);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_qbuf(struct file *filp, void *fh, struct v4l2_buffer *b)
+{
+	struct video_device *vdev;
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	vdev = video_devdata(filp);
+	if (!inst || !b)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (b->type == INPUT_MPLANE)
+		ret = vb2_qbuf(inst->vb2q_src, vdev->v4l2_dev->mdev, b);
+	else if (b->type == OUTPUT_MPLANE)
+		ret = vb2_qbuf(inst->vb2q_dst, vdev->v4l2_dev->mdev, b);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_dqbuf(struct file *filp, void *fh, struct v4l2_buffer *b)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !b)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (b->type == INPUT_MPLANE)
+		ret = vb2_dqbuf(inst->vb2q_src, b, true);
+	else if (b->type == OUTPUT_MPLANE)
+		ret = vb2_dqbuf(inst->vb2q_dst, b, true);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_streamon(struct file *filp, void *fh, enum v4l2_buf_type type)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (!allow_streamon(inst, type)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (type == INPUT_MPLANE)
+		ret = vb2_streamon(inst->vb2q_src, type);
+	else if (type == OUTPUT_MPLANE)
+		ret = vb2_streamon(inst->vb2q_dst, type);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_streamoff(struct file *filp, void *fh, enum v4l2_buf_type type)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (!allow_streamoff(inst, type)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (type == INPUT_MPLANE)
+		ret = vb2_streamoff(inst->vb2q_src, type);
+	else if (type == OUTPUT_MPLANE)
+		ret = vb2_streamoff(inst->vb2q_dst, type);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_querycap(struct file *filp, void *fh, struct v4l2_capability *cap)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	strscpy(cap->driver, VIDC_DRV_NAME, sizeof(cap->driver));
+	strscpy(cap->bus_info, VIDC_BUS_NAME, sizeof(cap->bus_info));
+	memset(cap->reserved, 0, sizeof(cap->reserved));
+
+	if (inst->domain == DECODER)
+		strscpy(cap->card, "iris_decoder", sizeof(cap->card));
+	else if (inst->domain == ENCODER)
+		strscpy(cap->card, "iris_encoder", sizeof(cap->card));
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_queryctrl(struct file *filp, void *fh, struct v4l2_queryctrl *q_ctrl)
+{
+	struct v4l2_ctrl *ctrl;
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !q_ctrl)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	ctrl = v4l2_ctrl_find(&inst->ctrl_handler, q_ctrl->id);
+	if (!ctrl) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	q_ctrl->minimum = ctrl->minimum;
+	q_ctrl->maximum = ctrl->maximum;
+	q_ctrl->default_value = ctrl->default_value;
+	q_ctrl->flags = 0;
+	q_ctrl->step = ctrl->step;
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_querymenu(struct file *filp, void *fh, struct v4l2_querymenu *qmenu)
+{
+	struct v4l2_ctrl *ctrl;
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !qmenu)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	ctrl = v4l2_ctrl_find(&inst->ctrl_handler, qmenu->id);
+	if (!ctrl) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (ctrl->type != V4L2_CTRL_TYPE_MENU) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (qmenu->index < ctrl->minimum || qmenu->index > ctrl->maximum) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (ctrl->menu_skip_mask & (1 << qmenu->index)) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = container_of(fh, struct iris_inst, fh);
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (inst->domain == DECODER)
+		ret = vdec_subscribe_event(inst, sub);
+	else if (inst->domain == ENCODER)
+		ret = venc_subscribe_event(inst, sub);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_unsubscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
+{
+	struct iris_inst *inst;
+	int ret;
+
+	inst = container_of(fh, struct iris_inst, fh);
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	ret = v4l2_event_unsubscribe(&inst->fh, sub);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_g_selection(struct file *filp, void *fh, struct v4l2_selection *s)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !s)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (s->type != OUTPUT_MPLANE && s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+	    inst->domain == DECODER) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (s->type != INPUT_MPLANE && s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+	    inst->domain == ENCODER) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (inst->domain == DECODER) {
+		switch (s->target) {
+		case V4L2_SEL_TGT_CROP_BOUNDS:
+		case V4L2_SEL_TGT_CROP_DEFAULT:
+		case V4L2_SEL_TGT_CROP:
+		case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+		case V4L2_SEL_TGT_COMPOSE_PADDED:
+		case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+		case V4L2_SEL_TGT_COMPOSE:
+			s->r.left = inst->crop.left;
+			s->r.top = inst->crop.top;
+			s->r.width = inst->crop.width;
+			s->r.height = inst->crop.height;
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+	} else if (inst->domain == ENCODER) {
+		switch (s->target) {
+		case V4L2_SEL_TGT_CROP_BOUNDS:
+		case V4L2_SEL_TGT_CROP_DEFAULT:
+		case V4L2_SEL_TGT_CROP:
+			s->r.left = inst->crop.left;
+			s->r.top = inst->crop.top;
+			s->r.width = inst->crop.width;
+			s->r.height = inst->crop.height;
+			break;
+		case V4L2_SEL_TGT_COMPOSE_BOUNDS:
+		case V4L2_SEL_TGT_COMPOSE_PADDED:
+		case V4L2_SEL_TGT_COMPOSE_DEFAULT:
+		case V4L2_SEL_TGT_COMPOSE:
+			s->r.left = inst->compose.left;
+			s->r.top = inst->compose.top;
+			s->r.width = inst->compose.width;
+			s->r.height = inst->compose.height;
+			break;
+		default:
+			ret = -EINVAL;
+			break;
+		}
+	}
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_s_selection(struct file *filp, void *fh, struct v4l2_selection *s)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !s)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+	if (inst->domain == DECODER) {
+		ret = -EINVAL;
+		goto unlock;
+	} else if (inst->domain == ENCODER) {
+		ret = venc_s_selection(inst, s);
+	}
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_s_parm(struct file *filp, void *fh, struct v4l2_streamparm *a)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !a)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
+	    a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (inst->domain == ENCODER)
+		ret = venc_s_param(inst, a);
+	else
+		ret = -EINVAL;
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_g_parm(struct file *filp, void *fh, struct v4l2_streamparm *a)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !a)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
+	    a->type != V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (inst->domain == ENCODER)
+		ret = venc_g_param(inst, a);
+	else
+		ret = -EINVAL;
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_try_dec_cmd(struct file *filp, void *fh,
+			    struct v4l2_decoder_cmd *dec)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !dec)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (dec->cmd != V4L2_DEC_CMD_STOP && dec->cmd != V4L2_DEC_CMD_START) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+	dec->flags = 0;
+	if (dec->cmd == V4L2_DEC_CMD_STOP) {
+		dec->stop.pts = 0;
+	} else if (dec->cmd == V4L2_DEC_CMD_START) {
+		dec->start.speed = 0;
+		dec->start.format = V4L2_DEC_START_FMT_NONE;
+	}
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_try_enc_cmd(struct file *filp, void *fh,
+			    struct v4l2_encoder_cmd *enc)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !enc)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (inst->domain != ENCODER) {
+		ret = -ENOTTY;
+		goto unlock;
+	}
+
+	if (enc->cmd != V4L2_ENC_CMD_STOP && enc->cmd != V4L2_ENC_CMD_START) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+	enc->flags = 0;
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_dec_cmd(struct file *filp, void *fh,
+			struct v4l2_decoder_cmd *dec)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !dec)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (dec->cmd != V4L2_DEC_CMD_START &&
+	    dec->cmd != V4L2_DEC_CMD_STOP) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (inst->state == IRIS_INST_OPEN)
+		goto unlock;
+
+	if (!allow_cmd(inst, dec->cmd)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	ret = iris_pm_get(inst->core);
+	if (ret)
+		goto unlock;
+
+	if (dec->cmd == V4L2_DEC_CMD_START)
+		ret = vdec_start_cmd(inst);
+	else if (dec->cmd == V4L2_DEC_CMD_STOP)
+		ret = vdec_stop_cmd(inst);
+
+	iris_pm_put(inst->core, true);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static int vidc_enc_cmd(struct file *filp, void *fh,
+			struct v4l2_encoder_cmd *enc)
+{
+	struct iris_inst *inst;
+	int ret = 0;
+
+	inst = get_vidc_inst(filp, fh);
+	if (!inst || !enc)
+		return -EINVAL;
+
+	mutex_lock(&inst->lock);
+	if (IS_SESSION_ERROR(inst)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	if (inst->domain != ENCODER) {
+		ret = -ENOTTY;
+		goto unlock;
+	}
+
+	if (enc->cmd != V4L2_ENC_CMD_START &&
+	    enc->cmd != V4L2_ENC_CMD_STOP) {
+		ret = -EINVAL;
+		goto unlock;
+	}
+
+	if (enc->cmd == V4L2_ENC_CMD_STOP && inst->state == IRIS_INST_OPEN) {
+		ret = 0;
+		goto unlock;
+	}
+
+	if (!allow_cmd(inst, enc->cmd)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	ret = iris_pm_get(inst->core);
+	if (ret)
+		goto unlock;
+
+	if (enc->cmd == V4L2_ENC_CMD_START)
+		ret = venc_start_cmd(inst);
+	else if (enc->cmd == V4L2_ENC_CMD_STOP)
+		ret = venc_stop_cmd(inst);
+
+	iris_pm_put(inst->core, true);
+
+unlock:
+	mutex_unlock(&inst->lock);
+
+	return ret;
+}
+
+static struct v4l2_file_operations v4l2_file_ops = {
+	.owner                          = THIS_MODULE,
+	.open                           = vidc_open,
+	.release                        = vidc_close,
+	.unlocked_ioctl                 = video_ioctl2,
+	.poll                           = vidc_poll,
+};
+
+static const struct vb2_ops iris_vb2_ops = {
+	.queue_setup                    = iris_vb2_queue_setup,
+	.start_streaming                = iris_vb2_start_streaming,
+	.stop_streaming                 = iris_vb2_stop_streaming,
+	.buf_queue                      = iris_vb2_buf_queue,
+};
+
+static struct vb2_mem_ops iris_vb2_mem_ops = {
+	.alloc                          = iris_vb2_alloc,
+	.put                            = iris_vb2_put,
+	.mmap                           = iris_vb2_mmap,
+	.attach_dmabuf                  = iris_vb2_attach_dmabuf,
+	.detach_dmabuf                  = iris_vb2_detach_dmabuf,
+	.map_dmabuf                     = iris_vb2_map_dmabuf,
+	.unmap_dmabuf                   = iris_vb2_unmap_dmabuf,
+};
+
+static const struct v4l2_ioctl_ops v4l2_ioctl_ops_dec = {
+	.vidioc_enum_fmt_vid_cap        = vidc_enum_fmt,
+	.vidioc_enum_fmt_vid_out        = vidc_enum_fmt,
+	.vidioc_try_fmt_vid_cap_mplane  = vidc_try_fmt,
+	.vidioc_try_fmt_vid_out_mplane  = vidc_try_fmt,
+	.vidioc_s_fmt_vid_cap_mplane    = vidc_s_fmt,
+	.vidioc_s_fmt_vid_out_mplane    = vidc_s_fmt,
+	.vidioc_g_fmt_vid_cap_mplane    = vidc_g_fmt,
+	.vidioc_g_fmt_vid_out_mplane    = vidc_g_fmt,
+	.vidioc_enum_framesizes         = vidc_enum_framesizes,
+	.vidioc_reqbufs                 = vidc_reqbufs,
+	.vidioc_querybuf                = vidc_querybuf,
+	.vidioc_create_bufs             = vidc_create_bufs,
+	.vidioc_prepare_buf             = vidc_prepare_buf,
+	.vidioc_qbuf                    = vidc_qbuf,
+	.vidioc_dqbuf                   = vidc_dqbuf,
+	.vidioc_streamon                = vidc_streamon,
+	.vidioc_streamoff               = vidc_streamoff,
+	.vidioc_querycap                = vidc_querycap,
+	.vidioc_queryctrl               = vidc_queryctrl,
+	.vidioc_querymenu               = vidc_querymenu,
+	.vidioc_subscribe_event         = vidc_subscribe_event,
+	.vidioc_unsubscribe_event       = vidc_unsubscribe_event,
+	.vidioc_g_selection             = vidc_g_selection,
+	.vidioc_try_decoder_cmd         = vidc_try_dec_cmd,
+	.vidioc_decoder_cmd             = vidc_dec_cmd,
+};
+
+static const struct v4l2_ioctl_ops v4l2_ioctl_ops_enc = {
+	.vidioc_enum_fmt_vid_cap        = vidc_enum_fmt,
+	.vidioc_enum_fmt_vid_out        = vidc_enum_fmt,
+	.vidioc_try_fmt_vid_cap_mplane  = vidc_try_fmt,
+	.vidioc_try_fmt_vid_out_mplane  = vidc_try_fmt,
+	.vidioc_s_fmt_vid_cap_mplane    = vidc_s_fmt,
+	.vidioc_s_fmt_vid_out_mplane    = vidc_s_fmt,
+	.vidioc_g_fmt_vid_cap_mplane    = vidc_g_fmt,
+	.vidioc_g_fmt_vid_out_mplane    = vidc_g_fmt,
+	.vidioc_enum_framesizes         = vidc_enum_framesizes,
+	.vidioc_enum_frameintervals     = vidc_enum_frameintervals,
+	.vidioc_reqbufs                 = vidc_reqbufs,
+	.vidioc_querybuf                = vidc_querybuf,
+	.vidioc_create_bufs             = vidc_create_bufs,
+	.vidioc_prepare_buf             = vidc_prepare_buf,
+	.vidioc_qbuf                    = vidc_qbuf,
+	.vidioc_dqbuf                   = vidc_dqbuf,
+	.vidioc_streamon                = vidc_streamon,
+	.vidioc_streamoff               = vidc_streamoff,
+	.vidioc_querycap                = vidc_querycap,
+	.vidioc_queryctrl               = vidc_queryctrl,
+	.vidioc_querymenu               = vidc_querymenu,
+	.vidioc_subscribe_event         = vidc_subscribe_event,
+	.vidioc_unsubscribe_event       = vidc_unsubscribe_event,
+	.vidioc_g_selection             = vidc_g_selection,
+	.vidioc_s_selection             = vidc_s_selection,
+	.vidioc_s_parm                  = vidc_s_parm,
+	.vidioc_g_parm                  = vidc_g_parm,
+	.vidioc_try_encoder_cmd         = vidc_try_enc_cmd,
+	.vidioc_encoder_cmd             = vidc_enc_cmd,
+};
+
+int init_ops(struct iris_core *core)
+{
+	core->v4l2_file_ops = &v4l2_file_ops;
+	core->vb2_ops = &iris_vb2_ops;
+	core->vb2_mem_ops = &iris_vb2_mem_ops;
+	core->v4l2_ioctl_ops_dec = &v4l2_ioctl_ops_dec;
+	core->v4l2_ioctl_ops_enc = &v4l2_ioctl_ops_enc;
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/iris_vidc.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/iris_vidc.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _IRIS_VIDC_H_
+#define _IRIS_VIDC_H_
+
+#include "iris_core.h"
+
+int init_ops(struct iris_core *core);
+int vidc_open(struct file *filp);
+int vidc_close(struct file *filp);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/memory.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/memory.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "memory.h"
+#include "iris_common.h"
+#include "iris_instance.h"
+
+void *iris_get_buffer_from_pool(struct iris_inst *inst)
+{
+	struct iris_mem_pool_header *hdr = NULL;
+	struct iris_mem_pool *pool;
+
+	pool = inst->mem_pool;
+
+	if (!list_empty(&pool->free_hdr_list)) {
+		hdr = list_first_entry(&pool->free_hdr_list, struct iris_mem_pool_header, list);
+		list_move_tail(&hdr->list, &pool->busy_hdr_list);
+
+		memset((char *)hdr->buf, 0, pool->size);
+		/* Catch double-free request */
+		hdr->busy = true;
+
+		return hdr->buf;
+	}
+
+	hdr = kzalloc(pool->size + sizeof(*hdr), GFP_KERNEL);
+	if (!hdr)
+		return NULL;
+
+	INIT_LIST_HEAD(&hdr->list);
+	hdr->busy = true;
+	hdr->buf = (void *)(hdr + 1);
+	list_add_tail(&hdr->list, &pool->busy_hdr_list);
+
+	return hdr->buf;
+}
+
+void iris_return_buffer_to_pool(struct iris_inst *inst, void *vidc_buf)
+{
+	struct iris_mem_pool_header *hdr;
+	struct iris_mem_pool *pool;
+
+	if (!vidc_buf)
+		return;
+
+	hdr = (struct iris_mem_pool_header *)vidc_buf - 1;
+
+	if (hdr->buf != vidc_buf)
+		return;
+
+	pool = inst->mem_pool;
+
+	/* Catch double-free request */
+	if (!hdr->busy)
+		return;
+	hdr->busy = false;
+
+	list_move_tail(&hdr->list, &pool->free_hdr_list);
+}
+
+int iris_mem_pool_init(struct iris_inst *inst)
+{
+	inst->mem_pool = devm_kzalloc(inst->core->dev, sizeof(struct iris_mem_pool),
+				      GFP_KERNEL);
+
+	if (!inst->mem_pool)
+		return -ENOMEM;
+
+	inst->mem_pool->size = sizeof(struct iris_buffer);
+	INIT_LIST_HEAD(&inst->mem_pool->free_hdr_list);
+	INIT_LIST_HEAD(&inst->mem_pool->busy_hdr_list);
+
+	return 0;
+}
+
+void iris_mem_pool_deinit(struct iris_inst *inst)
+{
+	struct iris_mem_pool_header *hdr, *dummy;
+	struct iris_mem_pool *pool;
+
+	pool = inst->mem_pool;
+
+	list_for_each_entry_safe(hdr, dummy, &pool->free_hdr_list, list) {
+		list_del(&hdr->list);
+		kfree(hdr);
+	}
+
+	list_for_each_entry_safe(hdr, dummy, &pool->busy_hdr_list, list) {
+		list_del(&hdr->list);
+		kfree(hdr);
+	}
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/memory.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/memory.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _MEMORY_H_
+#define _MEMORY_H_
+
+#include "iris_core.h"
+
+struct iris_inst;
+
+struct iris_mem_pool_header {
+	struct list_head	list;
+	bool			busy;
+	void			*buf;
+};
+
+struct iris_mem_pool {
+	u32			size;
+	struct list_head	free_hdr_list; /* list of struct iris_mem_pool_header */
+	struct list_head	busy_hdr_list; /* list of struct iris_mem_pool_header */
+};
+
+int iris_mem_pool_init(struct iris_inst *inst);
+void iris_mem_pool_deinit(struct iris_inst *inst);
+void *iris_get_buffer_from_pool(struct iris_inst *inst);
+void iris_return_buffer_to_pool(struct iris_inst *inst, void *vidc_buf);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/platform_common.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/platform_common.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+#include "iris_core.h"
+#include "platform_common.h"
+
+int init_platform(struct iris_core *core)
+{
+	struct platform_data *platform = NULL;
+
+	platform = devm_kzalloc(core->dev, sizeof(*platform),
+				GFP_KERNEL);
+	if (!platform)
+		return -ENOMEM;
+
+	core->platform_data = platform;
+
+	core->platform_data = (struct platform_data *)of_device_get_match_data(core->dev);
+	if (!core->platform_data)
+		return -ENODEV;
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/platform_common.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/platform_common.h
@@ -0,0 +1,324 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _PLATFORM_COMMON_H_
+#define _PLATFORM_COMMON_H_
+
+#include <linux/bits.h>
+#include <media/v4l2-ctrls.h>
+
+#include "iris_common.h"
+
+struct iris_core;
+struct iris_inst;
+
+#define HW_RESPONSE_TIMEOUT_VALUE     (1000)
+#define AUTOSUSPEND_DELAY_VALUE       (HW_RESPONSE_TIMEOUT_VALUE + 500)
+
+#define BIT_DEPTH_8 (8 << 16 | 8)
+#define BIT_DEPTH_10 (10 << 16 | 10)
+
+#define CODED_FRAMES_PROGRESSIVE			0x0
+#define CODED_FRAMES_INTERLACE				0x1
+#define MAX_NUM_CHILD					10
+#define MAX_ENH_LAYER_HB				3
+#define MAX_HEVC_VBR_ENH_LAYER_SLIDING_WINDOW		5
+#define MAX_HEVC_NON_VBR_ENH_LAYER_SLIDING_WINDOW	3
+#define MAX_AVC_ENH_LAYER_SLIDING_WINDOW		3
+#define MAX_AVC_ENH_LAYER_HYBRID_HP			5
+#define MAX_SLICES_FRAME_RATE				60
+#define MAX_MB_SLICE_WIDTH				4096
+#define MAX_MB_SLICE_HEIGHT				2160
+#define MAX_BYTES_SLICE_WIDTH				1920
+#define MAX_BYTES_SLICE_HEIGHT				1088
+#define MIN_HEVC_SLICE_WIDTH				384
+#define MIN_AVC_SLICE_WIDTH				192
+#define MIN_SLICE_HEIGHT				128
+#define MAX_SLICES_PER_FRAME				128
+#define MIN_QP_8BIT					1
+#define MIN_SLICE_BYTE_SIZE				512
+#define MAX_SLICE_BYTE_SIZE				((MAX_BITRATE) >> 3)
+#define MAX_SLICE_MB_SIZE				(((4096 + 15) >> 4) * ((2304 + 15) >> 4))
+#define INVALID_DEFAULT_MARK_OR_USE_LTR			-1
+#define MAX_SUPPORTED_MIN_QUALITY			70
+#define DEFAULT_MAX_HOST_BUF_COUNT			64
+#define DEFAULT_MAX_HOST_BURST_BUF_COUNT		256
+
+#define UBWC_CONFIG(mc, ml, hbb, bs1, bs2, bs3, bsp) \
+{	                                                 \
+	.max_channels = mc,                              \
+	.mal_length = ml,                                \
+	.highest_bank_bit = hbb,                         \
+	.bank_swzl_level = bs1,                          \
+	.bank_swz2_level = bs2,                          \
+	.bank_swz3_level = bs3,                          \
+	.bank_spreading = bsp,                           \
+}
+
+enum stage_type {
+	STAGE_NONE = 0,
+	STAGE_1 = 1,
+	STAGE_2 = 2,
+};
+
+enum pipe_type {
+	PIPE_NONE = 0,
+	PIPE_1 = 1,
+	PIPE_2 = 2,
+	PIPE_4 = 4,
+};
+
+enum quality_mode {
+	MAX_QUALITY_MODE = 0x1,
+	POWER_SAVE_MODE = 0x2,
+};
+
+extern struct platform_data qcm6490_data;
+extern struct platform_data sm8550_data;
+
+struct bw_info {
+	u32 mbs_per_sec;
+	u32 bw_ddr;
+	u32 bw_ddr_10bit;
+};
+
+struct reg_preset_info {
+	u32              reg;
+	u32              value;
+	u32              mask;
+};
+
+struct iris_core_power {
+	u64 clk_freq;
+	u64 bus_bw;
+};
+
+struct ubwc_config_data {
+	u32	max_channels;
+	u32	mal_length;
+	u32	highest_bank_bit;
+	u32	bank_swzl_level;
+	u32	bank_swz2_level;
+	u32	bank_swz3_level;
+	u32	bank_spreading;
+};
+
+struct bus_vote_data {
+	u32 color_formats[2];
+	int height, width;
+	u32 fps;
+	u64 bus_bw;
+};
+
+struct iris_inst_power {
+	u64 min_freq;
+	u32 bus_bw;
+};
+
+enum plat_core_cap_type {
+	CORE_CAP_NONE = 0,
+	DEC_CODECS,
+	ENC_CODECS,
+	MAX_SESSION_COUNT,
+	MAX_MBPF,
+	MAX_MBPS,
+	MAX_MBPF_HQ,
+	MAX_MBPS_HQ,
+	MAX_MBPF_B_FRAME,
+	MAX_MBPS_B_FRAME,
+	MAX_ENH_LAYER_COUNT,
+	NUM_VPP_PIPE,
+	FW_UNLOAD,
+	FW_UNLOAD_DELAY,
+	HW_RESPONSE_TIMEOUT,
+	NON_FATAL_FAULTS,
+	DMA_MASK,
+	CP_START,
+	CP_SIZE,
+	CP_NONPIXEL_START,
+	CP_NONPIXEL_SIZE,
+	CORE_CAP_MAX,
+};
+
+struct plat_core_cap {
+	enum plat_core_cap_type type;
+	u32 value;
+};
+
+enum plat_inst_cap_type {
+	INST_CAP_NONE = 0,
+	FRAME_WIDTH,
+	FRAME_HEIGHT,
+	PIX_FMTS,
+	MBPF,
+	QUEUED_RATE,
+	FRAME_RATE,
+	OPERATING_RATE,
+	MB_CYCLES_VSP,
+	MB_CYCLES_VPP,
+	MB_CYCLES_LP,
+	MB_CYCLES_FW,
+	MB_CYCLES_FW_VPP,
+	NUM_COMV,
+	ENTROPY_MODE,
+	BASELAYER_PRIORITY,
+	IR_TYPE,
+	PROFILE,
+	LEVEL,
+	HEVC_TIER,
+	DISPLAY_DELAY_ENABLE,
+	DISPLAY_DELAY,
+	OUTPUT_ORDER,
+	INPUT_BUF_HOST_MAX_COUNT,
+	STAGE,
+	PIPE,
+	QUALITY_MODE,
+	POC,
+	CODED_FRAMES,
+	BIT_DEPTH,
+	DEFAULT_HEADER,
+	RAP_FRAME,
+	MIN_FRAME_QP,
+	MAX_FRAME_QP,
+	B_FRAME,
+	I_FRAME_QP,
+	P_FRAME_QP,
+	B_FRAME_QP,
+	BIT_RATE,
+	PEAK_BITRATE,
+	BITRATE_MODE,
+	FRAME_SKIP_MODE,
+	FRAME_RC_ENABLE,
+	GOP_SIZE,
+	MIN_QUALITY,
+	TIME_DELTA_BASED_RC,
+	IR_PERIOD,
+	LTR_COUNT,
+	USE_LTR,
+	MARK_LTR,
+	I_FRAME_MIN_QP,
+	P_FRAME_MIN_QP,
+	B_FRAME_MIN_QP,
+	I_FRAME_MAX_QP,
+	P_FRAME_MAX_QP,
+	B_FRAME_MAX_QP,
+	LAYER_TYPE,
+	LAYER_ENABLE,
+	L0_BR,
+	L1_BR,
+	L2_BR,
+	L3_BR,
+	L4_BR,
+	L5_BR,
+	ENH_LAYER_COUNT,
+	TRANSFORM_8X8,
+	SLICE_MODE,
+	SLICE_MAX_MB,
+	SLICE_MAX_BYTES,
+	HFLIP,
+	VFLIP,
+	ROTATION,
+	HEADER_MODE,
+	PREPEND_SPSPPS_TO_IDR,
+	REQUEST_I_FRAME,
+	INST_CAP_MAX,
+};
+
+enum plat_inst_cap_flags {
+	CAP_FLAG_NONE			= 0,
+	CAP_FLAG_DYNAMIC_ALLOWED	= BIT(0),
+	CAP_FLAG_MENU			= BIT(1),
+	CAP_FLAG_INPUT_PORT		= BIT(2),
+	CAP_FLAG_OUTPUT_PORT		= BIT(3),
+	CAP_FLAG_CLIENT_SET		= BIT(4),
+	CAP_FLAG_BITMASK		= BIT(5),
+	CAP_FLAG_VOLATILE		= BIT(6),
+};
+
+struct plat_inst_cap {
+	enum plat_inst_cap_type cap_id;
+	enum domain_type domain;
+	enum codec_type codec;
+	s32 min;
+	s32 max;
+	u32 step_or_mask;
+	s32 value;
+	u32 v4l2_id;
+	u32 hfi_id;
+	enum plat_inst_cap_flags flags;
+	enum plat_inst_cap_type children[MAX_NUM_CHILD];
+	int (*adjust)(struct iris_inst *inst,
+		      struct v4l2_ctrl *ctrl);
+	int (*set)(struct iris_inst *inst,
+		   enum plat_inst_cap_type cap_id);
+};
+
+struct plat_inst_caps {
+	enum codec_type codec;
+	enum domain_type domain;
+	struct plat_inst_cap cap[INST_CAP_MAX + 1];
+};
+
+struct codec_info {
+	u32 v4l2_codec;
+	enum codec_type codec;
+};
+
+struct color_format_info {
+	u32 v4l2_color_format;
+	enum colorformat_type color_format;
+};
+
+struct format_capability {
+	struct codec_info *codec_info;
+	u32 codec_info_size;
+	struct color_format_info *color_format_info;
+	u32 color_format_info_size;
+};
+
+struct platform_data {
+	const struct bus_info *bus_tbl;
+	unsigned int bus_tbl_size;
+	const struct bw_info *bw_tbl_enc;
+	unsigned int bw_tbl_enc_size;
+	const struct bw_info *bw_tbl_dec;
+	unsigned int bw_tbl_dec_size;
+	const char * const *pd_tbl;
+	unsigned int pd_tbl_size;
+	const char * const *opp_pd_tbl;
+	unsigned int opp_pd_tbl_size;
+	const struct clock_info *clk_tbl;
+	unsigned int clk_tbl_size;
+	const char * const *clk_rst_tbl;
+	unsigned int clk_rst_tbl_size;
+	const struct reg_preset_info *reg_prst_tbl;
+	unsigned int reg_prst_tbl_size;
+	struct ubwc_config_data *ubwc_config;
+	struct format_capability *format_data;
+	const char *fwname;
+	u32 pas_id;
+	struct plat_core_cap *core_data;
+	u32 core_data_size;
+	struct plat_inst_cap *inst_cap_data;
+	u32 inst_cap_data_size;
+	const u32 *avc_subscribe_param;
+	unsigned int avc_subscribe_param_size;
+	const u32 *hevc_subscribe_param;
+	unsigned int hevc_subscribe_param_size;
+	const u32 *vp9_subscribe_param;
+	unsigned int vp9_subscribe_param_size;
+	const u32 *dec_input_prop;
+	unsigned int dec_input_prop_size;
+	const u32 *dec_output_prop_avc;
+	unsigned int dec_output_prop_size_avc;
+	const u32 *dec_output_prop_hevc;
+	unsigned int dec_output_prop_size_hevc;
+	const u32 *dec_output_prop_vp9;
+	unsigned int dec_output_prop_size_vp9;
+};
+
+int init_platform(struct iris_core *core);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/platform_qcm6490.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/platform_qcm6490.c
@@ -0,0 +1,1165 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/clock/qcom,gcc-sc7280.h>
+#include <dt-bindings/clock/qcom,videocc-sc7280.h>
+
+#include <media/v4l2-ctrls.h>
+
+#include "hfi_defines.h"
+#include "iris_ctrls.h"
+#include "platform_common.h"
+#include "resources.h"
+
+#define CODECS_ALL	(H264 | HEVC | VP9)
+#define ENC		ENCODER
+#define DEC		DECODER
+
+#define DEFAULT_FPS                 30
+#define MINIMUM_FPS                 1
+#define MAXIMUM_ENCODE_FPS          240
+#define MAX_BITRATE                 100000000
+#define DEFAULT_BITRATE             20000000
+#define MAX_LTR_FRAME_COUNT         2
+#define MAX_BASE_LAYER_PRIORITY_ID  63
+#define MAX_QP                      51
+#define DEFAULT_QP                  20
+
+static struct codec_info codec_data_qcm6490[] = {
+	{
+		.v4l2_codec  = V4L2_PIX_FMT_H264,
+		.codec  = H264,
+	},
+	{
+		.v4l2_codec  = V4L2_PIX_FMT_HEVC,
+		.codec  = HEVC,
+	},
+	{
+		.v4l2_codec  = V4L2_PIX_FMT_VP9,
+		.codec  = VP9,
+	},
+};
+
+static struct color_format_info color_format_data_qcm6490[] = {
+	{
+		.v4l2_color_format = V4L2_PIX_FMT_NV12,
+		.color_format = FMT_NV12,
+	},
+	{
+		.v4l2_color_format = V4L2_PIX_FMT_QC08C,
+		.color_format = FMT_NV12C,
+	},
+	{
+		.v4l2_color_format = V4L2_PIX_FMT_QC10C,
+		.color_format = FMT_TP10C,
+	},
+};
+
+static struct plat_core_cap core_data_qcm6490[] = {
+	{DEC_CODECS, H264 | HEVC | VP9},
+	{ENC_CODECS, H264 | HEVC},
+	{MAX_SESSION_COUNT, 16},
+	{MAX_MBPF, 77522}, /* ((4096x2176)/256) x 2 + (1920x1088)/256 */
+	{MAX_MBPS, 2088960}, /* max_load 4096x2176@60fps */
+	{NUM_VPP_PIPE, 1},
+	{HW_RESPONSE_TIMEOUT, HW_RESPONSE_TIMEOUT_VALUE},
+	{DMA_MASK, 0xe0000000 - 1},
+	{CP_START, 0},
+	{CP_SIZE, 0x25800000},
+	{CP_NONPIXEL_START, 0x01000000},
+	{CP_NONPIXEL_SIZE, 0x24800000},
+	{MAX_MBPF_HQ, 8160}, /* ((1920x1088)/256) */
+	{MAX_MBPS_HQ, 244800}, /* ((1920x1088)/256)@30fps */
+};
+
+static struct plat_inst_cap instance_cap_data_qcm6490[] = {
+	{FRAME_WIDTH, DEC, CODECS_ALL, 96, 4096, 1, 1920},
+
+	{FRAME_WIDTH, ENC, CODECS_ALL, 128, 4096, 1, 1920},
+
+	{FRAME_HEIGHT, DEC, CODECS_ALL, 96, 4096, 1, 1080},
+
+	{FRAME_HEIGHT, ENC, CODECS_ALL, 128, 4096, 1, 1080},
+
+	{PIX_FMTS, DEC, H264,
+		FMT_NV12,
+		FMT_NV12C,
+		FMT_NV12 | FMT_NV12C,
+		FMT_NV12C},
+
+	{PIX_FMTS, ENC, H264,
+		FMT_NV12,
+		FMT_NV12C,
+		FMT_NV12 | FMT_NV12C,
+		FMT_NV12C,
+		0, 0,
+		CAP_FLAG_NONE},
+
+	{PIX_FMTS, DEC, HEVC,
+		FMT_NV12,
+		FMT_TP10C,
+		FMT_NV12 | FMT_NV12C | FMT_TP10C,
+		FMT_NV12C,
+		0, 0,
+		CAP_FLAG_NONE,
+		{PROFILE}},
+
+	{PIX_FMTS, ENC, HEVC,
+		FMT_NV12,
+		FMT_TP10C,
+		FMT_NV12 | FMT_NV12C | FMT_TP10C,
+		FMT_NV12C,
+		0, 0,
+		CAP_FLAG_NONE,
+		{PROFILE, MIN_QUALITY, IR_PERIOD, LTR_COUNT}},
+
+	{PIX_FMTS, DEC, VP9,
+		FMT_NV12,
+		FMT_TP10C,
+		FMT_NV12 | FMT_NV12C | FMT_TP10C,
+		FMT_NV12C},
+
+	/* (4096 * 2176) / 256 */
+	{MBPF, DEC, CODECS_ALL, 36, 34816, 1, 34816},
+
+	/* (4096 * 2176) / 256 */
+	{MBPF, ENC, CODECS_ALL, 64, 34816, 1, 34816},
+
+	{QUEUED_RATE, DEC, CODECS_ALL,
+		(MINIMUM_FPS << 16), INT_MAX,
+		1, (DEFAULT_FPS << 16)},
+
+	{FRAME_RATE, ENC, CODECS_ALL,
+		(MINIMUM_FPS << 16), (MAXIMUM_ENCODE_FPS << 16),
+		1, (DEFAULT_FPS << 16),
+		0,
+		HFI_PROP_FRAME_RATE,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		NULL,
+		set_q16},
+
+	{OPERATING_RATE, ENC, CODECS_ALL,
+		(MINIMUM_FPS << 16), (MAXIMUM_ENCODE_FPS << 16),
+		1, (DEFAULT_FPS << 16)},
+
+	{MB_CYCLES_VSP, DEC, CODECS_ALL, 25, 25, 1, 25},
+
+	{MB_CYCLES_VSP, DEC, VP9, 60, 60, 1, 60},
+
+	{MB_CYCLES_VSP, ENC, CODECS_ALL, 25, 25, 1, 25},
+
+	{MB_CYCLES_VPP, DEC, CODECS_ALL, 200, 200, 1, 200},
+
+	{MB_CYCLES_VPP, ENC, CODECS_ALL, 675, 675, 1, 675},
+
+	{MB_CYCLES_LP, DEC, CODECS_ALL, 200, 200, 1, 200},
+
+	{MB_CYCLES_LP, ENC, CODECS_ALL, 320, 320, 1, 320},
+
+	{MB_CYCLES_FW, ENC | DEC, CODECS_ALL, 436000, 436000, 1, 436000},
+
+	{MB_CYCLES_FW_VPP, ENC | DEC, CODECS_ALL, 166667, 166667, 1, 166667},
+
+	{NUM_COMV, DEC, CODECS_ALL,
+		0, INT_MAX, 1, 0},
+
+	{PROFILE, DEC, H264,
+		V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+		V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH),
+		V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+		V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+		HFI_PROP_PROFILE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_u32_enum},
+
+	{PROFILE, ENC, H264,
+		V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+		V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH),
+		V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+		V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+		HFI_PROP_PROFILE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{ENTROPY_MODE, TRANSFORM_8X8},
+		NULL,
+		set_u32_enum},
+
+	{PROFILE, ENC | DEC, HEVC,
+		V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+		V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
+		BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10),
+		V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+		V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
+		HFI_PROP_PROFILE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		adjust_profile,
+		set_u32_enum},
+
+	{PROFILE, DEC, VP9,
+		V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+		V4L2_MPEG_VIDEO_VP9_PROFILE_2,
+		BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_0) |
+		BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_2),
+		V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+		V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
+		HFI_PROP_PROFILE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_u32_enum},
+
+	{LEVEL, DEC, H264,
+		V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+		V4L2_MPEG_VIDEO_H264_LEVEL_5_2,
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2),
+		V4L2_MPEG_VIDEO_H264_LEVEL_5_2,
+		V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+		HFI_PROP_LEVEL,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_u32_enum},
+
+	{LEVEL, ENC, H264,
+		V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+		V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1),
+		V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
+		V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+		HFI_PROP_LEVEL,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_level},
+
+	{LEVEL, DEC, HEVC,
+		V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
+		V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1,
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1),
+		V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1,
+		V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
+		HFI_PROP_LEVEL,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_u32_enum},
+
+	{LEVEL, ENC, HEVC,
+		V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
+		V4L2_MPEG_VIDEO_HEVC_LEVEL_5,
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5),
+		V4L2_MPEG_VIDEO_HEVC_LEVEL_5,
+		V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
+		HFI_PROP_LEVEL,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_level},
+
+	{LEVEL, DEC, VP9,
+		V4L2_MPEG_VIDEO_VP9_LEVEL_1_0,
+		V4L2_MPEG_VIDEO_VP9_LEVEL_5_1,
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_0) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_1) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_0) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_1) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_0) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_1) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_0) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_1) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_0) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_1),
+		V4L2_MPEG_VIDEO_VP9_LEVEL_5_1,
+		V4L2_CID_MPEG_VIDEO_VP9_LEVEL,
+		HFI_PROP_LEVEL,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_u32_enum},
+
+	{HEVC_TIER, DEC | ENC, HEVC,
+		V4L2_MPEG_VIDEO_HEVC_TIER_MAIN,
+		V4L2_MPEG_VIDEO_HEVC_TIER_HIGH,
+		BIT(V4L2_MPEG_VIDEO_HEVC_TIER_MAIN) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_TIER_HIGH),
+		V4L2_MPEG_VIDEO_HEVC_TIER_HIGH,
+		V4L2_CID_MPEG_VIDEO_HEVC_TIER,
+		HFI_PROP_TIER,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_u32_enum},
+
+	{HFLIP, ENC, CODECS_ALL,
+		0, 1, 1, 0,
+		V4L2_CID_HFLIP,
+		HFI_PROP_FLIP,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_flip},
+
+	{VFLIP, ENC, CODECS_ALL,
+		0, 1, 1, 0,
+		V4L2_CID_VFLIP,
+		HFI_PROP_FLIP,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_flip},
+
+	{ROTATION, ENC, CODECS_ALL,
+		0, 270, 90, 0,
+		V4L2_CID_ROTATE,
+		HFI_PROP_ROTATION,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		NULL,
+		set_rotation},
+
+	{HEADER_MODE, ENC, CODECS_ALL,
+		V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
+		V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+		BIT(V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) |
+		BIT(V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME),
+		V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+		V4L2_CID_MPEG_VIDEO_HEADER_MODE,
+		HFI_PROP_SEQ_HEADER_MODE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_header_mode},
+
+	{PREPEND_SPSPPS_TO_IDR, ENC, CODECS_ALL,
+		0, 1, 1, 0,
+		V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR},
+
+	{REQUEST_I_FRAME, ENC, H264 | HEVC,
+		0, 0, 0, 0,
+		V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME,
+		HFI_PROP_REQUEST_SYNC_FRAME,
+		CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_req_sync_frame},
+
+	{BIT_RATE, ENC, H264 | HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_BITRATE,
+		HFI_PROP_TOTAL_BITRATE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{PEAK_BITRATE, L0_BR},
+		adjust_bitrate,
+		set_bitrate},
+
+	{PEAK_BITRATE, ENC, H264 | HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+		HFI_PROP_TOTAL_PEAK_BITRATE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		adjust_peak_bitrate,
+		set_peak_bitrate},
+
+	{BITRATE_MODE, ENC, H264 | HEVC,
+		V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+		V4L2_MPEG_VIDEO_BITRATE_MODE_MBR,
+		BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
+		BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_CBR) |
+		BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_MBR),
+		V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+		V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+		HFI_PROP_RATE_CONTROL,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{LTR_COUNT, IR_PERIOD, I_FRAME_QP, P_FRAME_QP,
+		 B_FRAME_QP, ENH_LAYER_COUNT, BIT_RATE,
+		 MIN_QUALITY, PEAK_BITRATE, SLICE_MODE},
+		adjust_bitrate_mode,
+		set_bitrate_mode},
+
+	{FRAME_SKIP_MODE, ENC, H264 | HEVC,
+		V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED,
+		V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT,
+		BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED) |
+		BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT) |
+		BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT),
+		V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED,
+		V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE,
+		0,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU},
+
+	{FRAME_RC_ENABLE, ENC, H264 | HEVC,
+		0, 1, 1, 1,
+		V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE},
+
+	{GOP_SIZE, ENC, CODECS_ALL,
+		0, INT_MAX, 1, 2 * DEFAULT_FPS - 1,
+		V4L2_CID_MPEG_VIDEO_GOP_SIZE,
+		HFI_PROP_MAX_GOP_FRAMES,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		adjust_gop_size,
+		set_gop_size},
+
+	{B_FRAME, ENC, H264 | HEVC,
+		0, 1, 1, 0,
+		V4L2_CID_MPEG_VIDEO_B_FRAMES,
+		HFI_PROP_MAX_B_FRAMES,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		adjust_b_frame,
+		set_u32},
+
+	{LTR_COUNT, ENC, H264 | HEVC,
+		0, MAX_LTR_FRAME_COUNT, 1, 0,
+		V4L2_CID_MPEG_VIDEO_LTR_COUNT,
+		HFI_PROP_LTR_COUNT,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		adjust_ltr_count,
+		set_u32},
+
+	{USE_LTR, ENC, H264 | HEVC,
+		0,
+		((1 << MAX_LTR_FRAME_COUNT) - 1),
+		0, 0,
+		V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES,
+		HFI_PROP_LTR_USE,
+		CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		adjust_use_ltr,
+		set_use_and_mark_ltr},
+
+	{MARK_LTR, ENC, H264 | HEVC,
+		INVALID_DEFAULT_MARK_OR_USE_LTR,
+		(MAX_LTR_FRAME_COUNT - 1),
+		1, INVALID_DEFAULT_MARK_OR_USE_LTR,
+		V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX,
+		HFI_PROP_LTR_MARK,
+		CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		adjust_mark_ltr,
+		set_use_and_mark_ltr},
+
+	{BASELAYER_PRIORITY, ENC, H264,
+		0, MAX_BASE_LAYER_PRIORITY_ID, 1, 0,
+		V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID,
+		HFI_PROP_BASELAYER_PRIORITYID,
+		CAP_FLAG_OUTPUT_PORT},
+
+	{IR_TYPE, ENC, H264 | HEVC,
+		V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM,
+		V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC,
+		BIT(V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM) |
+		BIT(V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC),
+		V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM,
+		V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE,
+		0,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU},
+
+	{IR_PERIOD, ENC, H264 | HEVC,
+		0, INT_MAX, 1, 0,
+		V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD,
+		0,
+		CAP_FLAG_INPUT_PORT | CAP_FLAG_OUTPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		adjust_ir_period,
+		set_ir_period},
+
+	{MIN_QUALITY, ENC, H264 | HEVC,
+		0, MAX_SUPPORTED_MIN_QUALITY, 70, MAX_SUPPORTED_MIN_QUALITY,
+		0,
+		HFI_PROP_MAINTAIN_MIN_QUALITY,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		adjust_min_quality,
+		set_u32},
+
+	{TIME_DELTA_BASED_RC, ENC, H264 | HEVC,
+		0, 1, 1, 0,
+		0,
+		HFI_PROP_TIME_DELTA_BASED_RATE_CONTROL,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		NULL,
+		set_u32},
+
+	{MIN_FRAME_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
+		HFI_PROP_MIN_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		NULL,
+		set_min_qp},
+
+	{MIN_FRAME_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+		HFI_PROP_MIN_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		NULL,
+		set_min_qp},
+
+	{MAX_FRAME_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
+		HFI_PROP_MAX_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		NULL,
+		set_max_qp},
+
+	{MAX_FRAME_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
+		HFI_PROP_MAX_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		NULL,
+		set_max_qp},
+
+	{I_FRAME_MIN_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP},
+
+	{I_FRAME_MIN_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP},
+
+	{P_FRAME_MIN_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP},
+
+	{P_FRAME_MIN_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP},
+
+	{B_FRAME_MIN_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP},
+
+	{B_FRAME_MIN_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP},
+
+	{I_FRAME_MAX_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP},
+
+	{I_FRAME_MAX_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP},
+
+	{P_FRAME_MAX_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP},
+
+	{P_FRAME_MAX_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP},
+
+	{B_FRAME_MAX_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP},
+
+	{B_FRAME_MAX_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP},
+
+	{I_FRAME_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP,
+		HFI_PROP_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_frame_qp},
+
+	{I_FRAME_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
+		HFI_PROP_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_frame_qp},
+
+	{P_FRAME_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP,
+		HFI_PROP_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_frame_qp},
+
+	{P_FRAME_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
+		HFI_PROP_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_frame_qp},
+
+	{B_FRAME_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP,
+		HFI_PROP_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_frame_qp},
+
+	{B_FRAME_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
+		HFI_PROP_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_frame_qp},
+
+	{LAYER_TYPE, ENC, HEVC,
+		V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B,
+		V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,
+		BIT(V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P),
+		V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE,
+		HFI_PROP_LAYER_ENCODING_TYPE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{LTR_COUNT}},
+
+	{LAYER_TYPE, ENC, H264,
+		V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B,
+		V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
+		BIT(V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B) |
+		BIT(V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P),
+		V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
+		V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE,
+		HFI_PROP_LAYER_ENCODING_TYPE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{LTR_COUNT}},
+
+	{LAYER_ENABLE, ENC, H264,
+		0, 1, 1, 0,
+		V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING,
+		HFI_PROP_LAYER_ENCODING_TYPE,
+		CAP_FLAG_OUTPUT_PORT},
+
+	{LAYER_ENABLE, ENC, HEVC,
+		0, 1, 1, 0,
+		0,
+		0,
+		CAP_FLAG_OUTPUT_PORT},
+
+	{ENH_LAYER_COUNT, ENC, HEVC,
+		0, 5, 1, 0,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER,
+		HFI_PROP_LAYER_COUNT,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{GOP_SIZE, B_FRAME, BIT_RATE, MIN_QUALITY, SLICE_MODE,
+		 LTR_COUNT},
+		adjust_layer_count,
+		set_layer_count_and_type},
+
+	{ENH_LAYER_COUNT, ENC, H264,
+		0, 5, 1, 0,
+		V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER,
+		HFI_PROP_LAYER_COUNT,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{GOP_SIZE, B_FRAME, BIT_RATE, MIN_QUALITY, SLICE_MODE,
+		 LTR_COUNT},
+		adjust_layer_count,
+		set_layer_count_and_type},
+
+	{L0_BR, ENC, H264,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L0_BR,
+		HFI_PROP_BITRATE_LAYER1,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L1_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L0_BR, ENC, HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR,
+		HFI_PROP_BITRATE_LAYER1,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L1_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L1_BR, ENC, H264,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L1_BR,
+		HFI_PROP_BITRATE_LAYER2,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L2_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L1_BR, ENC, HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR,
+		HFI_PROP_BITRATE_LAYER2,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L2_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L2_BR, ENC, H264,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L2_BR,
+		HFI_PROP_BITRATE_LAYER3,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L3_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L2_BR, ENC, HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR,
+		HFI_PROP_BITRATE_LAYER3,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L3_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L3_BR, ENC, H264,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L3_BR,
+		HFI_PROP_BITRATE_LAYER4,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L4_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L3_BR, ENC, HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR,
+		HFI_PROP_BITRATE_LAYER4,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L4_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L4_BR, ENC, H264,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L4_BR,
+		HFI_PROP_BITRATE_LAYER5,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L5_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L4_BR, ENC, HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR,
+		HFI_PROP_BITRATE_LAYER5,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L5_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L5_BR, ENC, H264,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L5_BR,
+		HFI_PROP_BITRATE_LAYER6,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L5_BR, ENC, HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR,
+		HFI_PROP_BITRATE_LAYER6,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{ENTROPY_MODE, ENC, H264,
+		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
+		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+		BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) |
+		BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC),
+		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+		V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
+		HFI_PROP_CABAC_SESSION,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{BIT_RATE},
+		adjust_entropy_mode,
+		set_u32},
+
+	{SLICE_MODE, ENC, H264 | HEVC,
+		V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+		V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES,
+		BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) |
+		BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) |
+		BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES),
+		V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+		V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
+		0,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{STAGE},
+		adjust_slice_count,
+		set_slice_count},
+
+	{SLICE_MAX_BYTES, ENC, H264 | HEVC,
+		MIN_SLICE_BYTE_SIZE, MAX_SLICE_BYTE_SIZE,
+		1, MIN_SLICE_BYTE_SIZE,
+		V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
+		HFI_PROP_MULTI_SLICE_BYTES_COUNT,
+		CAP_FLAG_OUTPUT_PORT},
+
+	{SLICE_MAX_MB, ENC, H264 | HEVC,
+		1, MAX_SLICE_MB_SIZE, 1, 1,
+		V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
+		HFI_PROP_MULTI_SLICE_MB_COUNT,
+		CAP_FLAG_OUTPUT_PORT},
+
+	{TRANSFORM_8X8, ENC, H264,
+		0, 1, 1, 1,
+		V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM,
+		HFI_PROP_8X8_TRANSFORM,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		adjust_transform_8x8,
+		set_u32},
+
+	{DISPLAY_DELAY_ENABLE, DEC, CODECS_ALL,
+		0, 1, 1, 0,
+		V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE,
+		HFI_PROP_DECODE_ORDER_OUTPUT,
+		CAP_FLAG_INPUT_PORT,
+		{OUTPUT_ORDER},
+		NULL,
+		NULL},
+
+	{DISPLAY_DELAY, DEC, CODECS_ALL,
+		0, 1, 1, 0,
+		V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY,
+		HFI_PROP_DECODE_ORDER_OUTPUT,
+		CAP_FLAG_INPUT_PORT,
+		{OUTPUT_ORDER},
+		NULL,
+		NULL},
+
+	{OUTPUT_ORDER, DEC, CODECS_ALL,
+		0, 1, 1, 0,
+		0,
+		HFI_PROP_DECODE_ORDER_OUTPUT,
+		CAP_FLAG_INPUT_PORT,
+		{0},
+		adjust_output_order,
+		set_u32},
+
+	{INPUT_BUF_HOST_MAX_COUNT, ENC | DEC, CODECS_ALL,
+		DEFAULT_MAX_HOST_BUF_COUNT, DEFAULT_MAX_HOST_BURST_BUF_COUNT,
+		1, DEFAULT_MAX_HOST_BUF_COUNT,
+		0,
+		HFI_PROP_BUFFER_HOST_MAX_COUNT,
+		CAP_FLAG_INPUT_PORT,
+		{0},
+		NULL,
+		set_u32},
+
+	{STAGE, ENC | DEC, CODECS_ALL,
+		STAGE_1,
+		STAGE_2, 1,
+		STAGE_2,
+		0,
+		HFI_PROP_STAGE,
+		CAP_FLAG_NONE,
+		{0},
+		NULL,
+		set_stage},
+
+	{PIPE, ENC | DEC, CODECS_ALL,
+		PIPE_1,
+		PIPE_1, 1,
+		PIPE_1,
+		0,
+		HFI_PROP_PIPE,
+		CAP_FLAG_NONE,
+		{0},
+		NULL,
+		set_pipe},
+
+	{QUALITY_MODE, ENC, CODECS_ALL,
+		MAX_QUALITY_MODE,
+		POWER_SAVE_MODE, 1,
+		POWER_SAVE_MODE},
+
+	{POC, DEC, H264, 0, 2, 1, 1,
+		0,
+		HFI_PROP_PIC_ORDER_CNT_TYPE},
+
+	{CODED_FRAMES, DEC, H264 | HEVC,
+		CODED_FRAMES_PROGRESSIVE, CODED_FRAMES_PROGRESSIVE,
+		0, CODED_FRAMES_PROGRESSIVE,
+		0,
+		HFI_PROP_CODED_FRAMES},
+
+	{BIT_DEPTH, DEC, CODECS_ALL, BIT_DEPTH_8, BIT_DEPTH_10, 1, BIT_DEPTH_8,
+		0,
+		HFI_PROP_LUMA_CHROMA_BIT_DEPTH},
+
+	{DEFAULT_HEADER, DEC, CODECS_ALL,
+		0, 1, 1, 0,
+		0,
+		HFI_PROP_DEC_DEFAULT_HEADER},
+
+	{RAP_FRAME, DEC, CODECS_ALL,
+		0, 1, 1, 1,
+		0,
+		HFI_PROP_DEC_START_FROM_RAP_FRAME,
+		CAP_FLAG_INPUT_PORT,
+		{0},
+		NULL,
+		set_u32},
+};
+
+static const struct bus_info qcm6490_bus_table[] = {
+		{ NULL, "iris-cnoc", 1000, 1000    },
+		{ NULL, "iris-ddr",  1000, 8000000 },
+};
+
+static const struct clock_info qcm6490_clk_table[] = {
+		{ NULL, "core",              VIDEO_CC_MVSC_CORE_CLK,     1 },
+		{ NULL, "bus",               VIDEO_CC_MVSC_CTL_AXI_CLK,  0 },
+		{ NULL, "iface",             VIDEO_CC_VENUS_AHB_CLK,     0 },
+		{ NULL, "vcodec_bus",        VIDEO_CC_MVS0_AXI_CLK,      0 },
+		{ NULL, "vcodec_core",       VIDEO_CC_MVS0_CORE_CLK,     1 },
+};
+
+static const char * const qcm6490_pd_table[] = { "venus", "vcodec0", NULL };
+
+static const char * const qcm6490_opp_pd_table[] = {"cx", NULL };
+
+static const struct bw_info qcm6490_bw_table_enc[] = {
+	{  972000,  808000, 1350000 },	/* 3840x2160@30 */
+	{  489600,  547000,  732000 },	/* 1920x1080@60 */
+	{  244800,  283000,  375000 },	/* 1920x1080@30 */
+};
+
+static const struct bw_info qcm6490_bw_table_dec[] = {
+	{ 2073600, 2266000, 4317000 },	/* 4096x2160@60 */
+	{ 1036800, 1156000, 2181000 },	/* 4096x2160@30 */
+	{  489600,  731000,  998000 },	/* 1920x1080@60 */
+	{  244800,  376000,  534000 },	/* 1920x1080@30 */
+};
+
+static const struct reg_preset_info qcm6490_reg_preset_table[] = {
+	{ 0xB0088, 0x0, 0x11 },
+};
+
+static struct ubwc_config_data ubwc_config_qcm6490[] = {
+	UBWC_CONFIG(8, 32, 15, 0, 1, 1, 1),
+};
+
+static struct format_capability format_data_qcm6490 = {
+	.codec_info = codec_data_qcm6490,
+	.codec_info_size = ARRAY_SIZE(codec_data_qcm6490),
+	.color_format_info = color_format_data_qcm6490,
+	.color_format_info_size = ARRAY_SIZE(color_format_data_qcm6490),
+};
+
+static const u32 qcm6490_vdec_src_change_param_avc[] = {
+	HFI_PROP_BITSTREAM_RESOLUTION,
+	HFI_PROP_CROP_OFFSETS,
+	HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
+	HFI_PROP_CODED_FRAMES,
+	HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
+	HFI_PROP_PIC_ORDER_CNT_TYPE,
+	HFI_PROP_PROFILE,
+	HFI_PROP_LEVEL,
+	HFI_PROP_SIGNAL_COLOR_INFO,
+};
+
+static const u32 qcm6490_vdec_src_change_param_hevc[] = {
+	HFI_PROP_BITSTREAM_RESOLUTION,
+	HFI_PROP_CROP_OFFSETS,
+	HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
+	HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
+	HFI_PROP_PROFILE,
+	HFI_PROP_LEVEL,
+	HFI_PROP_TIER,
+	HFI_PROP_SIGNAL_COLOR_INFO,
+};
+
+static const u32 qcm6490_vdec_src_change_param_vp9[] = {
+	HFI_PROP_BITSTREAM_RESOLUTION,
+	HFI_PROP_CROP_OFFSETS,
+	HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
+	HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
+	HFI_PROP_PROFILE,
+	HFI_PROP_LEVEL,
+};
+
+static const u32 qcm6490_vdec_input_properties[] = {
+	HFI_PROP_NO_OUTPUT,
+};
+
+static const u32 qcm6490_vdec_output_properties_avc[] = {
+	HFI_PROP_PICTURE_TYPE,
+	HFI_PROP_DPB_LIST,
+	HFI_PROP_CABAC_SESSION,
+};
+
+static const u32 qcm6490_vdec_output_properties_hevc[] = {
+	HFI_PROP_PICTURE_TYPE,
+	HFI_PROP_DPB_LIST,
+};
+
+static const u32 qcm6490_vdec_output_properties_vp9[] = {
+	HFI_PROP_PICTURE_TYPE,
+	HFI_PROP_DPB_LIST,
+};
+
+struct platform_data qcm6490_data = {
+	.bus_tbl = qcm6490_bus_table,
+	.bus_tbl_size = ARRAY_SIZE(qcm6490_bus_table),
+	.clk_tbl = qcm6490_clk_table,
+	.clk_tbl_size = ARRAY_SIZE(qcm6490_clk_table),
+	.clk_rst_tbl = NULL,
+	.clk_rst_tbl_size = 0,
+
+	.bw_tbl_enc = qcm6490_bw_table_enc,
+	.bw_tbl_enc_size = ARRAY_SIZE(qcm6490_bw_table_enc),
+	.bw_tbl_dec = qcm6490_bw_table_dec,
+	.bw_tbl_dec_size = ARRAY_SIZE(qcm6490_bw_table_dec),
+
+	.pd_tbl = qcm6490_pd_table,
+	.pd_tbl_size = ARRAY_SIZE(qcm6490_pd_table),
+	.opp_pd_tbl = qcm6490_opp_pd_table,
+	.opp_pd_tbl_size = ARRAY_SIZE(qcm6490_opp_pd_table),
+
+	.reg_prst_tbl = qcm6490_reg_preset_table,
+	.reg_prst_tbl_size = ARRAY_SIZE(qcm6490_reg_preset_table),
+	.fwname = "qcom/vpu-2.0/vpu20_1v",
+	.pas_id = 9,
+
+	.core_data = core_data_qcm6490,
+	.core_data_size = ARRAY_SIZE(core_data_qcm6490),
+	.inst_cap_data = instance_cap_data_qcm6490,
+	.inst_cap_data_size = ARRAY_SIZE(instance_cap_data_qcm6490),
+	.ubwc_config = ubwc_config_qcm6490,
+	.format_data = &format_data_qcm6490,
+
+	.avc_subscribe_param =
+		qcm6490_vdec_src_change_param_avc,
+	.avc_subscribe_param_size =
+		ARRAY_SIZE(qcm6490_vdec_src_change_param_avc),
+	.hevc_subscribe_param =
+		qcm6490_vdec_src_change_param_hevc,
+	.hevc_subscribe_param_size =
+		ARRAY_SIZE(qcm6490_vdec_src_change_param_hevc),
+	.vp9_subscribe_param =
+		qcm6490_vdec_src_change_param_vp9,
+	.vp9_subscribe_param_size =
+		ARRAY_SIZE(qcm6490_vdec_src_change_param_vp9),
+	.dec_input_prop = qcm6490_vdec_input_properties,
+	.dec_input_prop_size = ARRAY_SIZE(qcm6490_vdec_input_properties),
+	.dec_output_prop_avc = qcm6490_vdec_output_properties_avc,
+	.dec_output_prop_size_avc = ARRAY_SIZE(qcm6490_vdec_output_properties_avc),
+	.dec_output_prop_hevc = qcm6490_vdec_output_properties_hevc,
+	.dec_output_prop_size_hevc = ARRAY_SIZE(qcm6490_vdec_output_properties_hevc),
+	.dec_output_prop_vp9 = qcm6490_vdec_output_properties_vp9,
+	.dec_output_prop_size_vp9 = ARRAY_SIZE(qcm6490_vdec_output_properties_vp9),
+};
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/platform_sm8550.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/platform_sm8550.c
@@ -0,0 +1,1195 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/clock/qcom,sm8550-gcc.h>
+#include <dt-bindings/clock/qcom,sm8450-videocc.h>
+
+#include <media/v4l2-ctrls.h>
+
+#include "hfi_defines.h"
+#include "iris_ctrls.h"
+#include "platform_common.h"
+#include "resources.h"
+
+#define CODECS_ALL	(H264 | HEVC | VP9)
+#define ENC		ENCODER
+#define DEC		DECODER
+
+#define DEFAULT_FPS			30
+#define MINIMUM_FPS			1
+#define MAXIMUM_FPS			480
+#define MAX_BITRATE			245000000
+#define DEFAULT_BITRATE			20000000
+#define MAX_LTR_FRAME_COUNT		2
+#define MAX_BASE_LAYER_PRIORITY_ID	63
+#define MAX_QP				51
+#define DEFAULT_QP			20
+
+static struct codec_info codec_data_sm8550[] = {
+	{
+		.v4l2_codec  = V4L2_PIX_FMT_H264,
+		.codec  = H264,
+	},
+	{
+		.v4l2_codec  = V4L2_PIX_FMT_HEVC,
+		.codec  = HEVC,
+	},
+	{
+		.v4l2_codec  = V4L2_PIX_FMT_VP9,
+		.codec  = VP9,
+	},
+};
+
+static struct color_format_info color_format_data_sm8550[] = {
+	{
+		.v4l2_color_format = V4L2_PIX_FMT_NV12,
+		.color_format = FMT_NV12,
+	},
+	{
+		.v4l2_color_format = V4L2_PIX_FMT_QC08C,
+		.color_format = FMT_NV12C,
+	},
+	{
+		.v4l2_color_format = V4L2_PIX_FMT_QC10C,
+		.color_format = FMT_TP10C,
+	},
+};
+
+static struct plat_core_cap core_data_sm8550[] = {
+	{DEC_CODECS, H264 | HEVC | VP9},
+	{ENC_CODECS, H264 | HEVC},
+	{MAX_SESSION_COUNT, 16},
+	{MAX_MBPF, 278528}, /* ((8192x4352)/256) * 2 */
+	{MAX_MBPS, 7833600}, /* max_load 7680x4320@60fps */
+	{NUM_VPP_PIPE, 4},
+	{HW_RESPONSE_TIMEOUT, HW_RESPONSE_TIMEOUT_VALUE},
+	{DMA_MASK, GENMASK(31, 29) - 1},
+	{CP_START, 0},
+	{CP_SIZE, 0x25800000},
+	{CP_NONPIXEL_START, 0x01000000},
+	{CP_NONPIXEL_SIZE, 0x24800000},
+	{MAX_MBPF_HQ, 8160}, /* ((1920x1088)/256) */
+	{MAX_MBPS_HQ, 489600}, /* ((1920x1088)/256)@60fps */
+};
+
+static struct plat_inst_cap instance_cap_data_sm8550[] = {
+	{FRAME_WIDTH, DEC, CODECS_ALL, 96, 8192, 1, 1920},
+
+	{FRAME_WIDTH, DEC, VP9, 96, 4096, 1, 1920},
+
+	{FRAME_WIDTH, ENC, CODECS_ALL, 128, 8192, 1, 1920},
+
+	{FRAME_WIDTH, ENC, HEVC, 96, 8192, 1, 1920},
+
+	{FRAME_HEIGHT, DEC, CODECS_ALL, 96, 8192, 1, 1080},
+
+	{FRAME_HEIGHT, DEC, VP9, 96, 4096, 1, 1080},
+
+	{FRAME_HEIGHT, ENC, CODECS_ALL, 128, 8192, 1, 1080},
+
+	{FRAME_HEIGHT, ENC, HEVC, 96, 8192, 1, 1080},
+
+	{PIX_FMTS, DEC, H264,
+		FMT_NV12,
+		FMT_NV12C,
+		FMT_NV12 | FMT_NV12C,
+		FMT_NV12C},
+
+	{PIX_FMTS, ENC, H264,
+		FMT_NV12,
+		FMT_NV12C,
+		FMT_NV12 | FMT_NV12C,
+		FMT_NV12C,
+		0, 0,
+		CAP_FLAG_NONE},
+
+	{PIX_FMTS, DEC, HEVC,
+		FMT_NV12,
+		FMT_TP10C,
+		FMT_NV12 | FMT_NV12C | FMT_TP10C,
+		FMT_NV12C,
+		0, 0,
+		CAP_FLAG_NONE,
+		{PROFILE}},
+
+	{PIX_FMTS, ENC, HEVC,
+		FMT_NV12,
+		FMT_TP10C,
+		FMT_NV12 | FMT_NV12C | FMT_TP10C,
+		FMT_NV12C,
+		0, 0,
+		CAP_FLAG_NONE,
+		{PROFILE, MIN_QUALITY, IR_PERIOD, LTR_COUNT}},
+
+	{PIX_FMTS, DEC, VP9,
+		FMT_NV12,
+		FMT_TP10C,
+		FMT_NV12 | FMT_NV12C | FMT_TP10C,
+		FMT_NV12C},
+
+	{MBPF, DEC, CODECS_ALL, 36, 138240, 1, 138240},
+
+	/* (4096 * 2304) / 256 */
+	{MBPF, DEC, VP9, 36, 36864, 1, 36864},
+
+	/* (8192 * 4320) / 256 */
+	{MBPF, ENC, CODECS_ALL, 64, 138240, 1, 138240},
+
+	{MBPF, ENC, HEVC, 36, 138240, 1, 138240},
+
+	{QUEUED_RATE, DEC | ENC, CODECS_ALL,
+		(MINIMUM_FPS << 16), INT_MAX,
+		1, (DEFAULT_FPS << 16)},
+
+	{FRAME_RATE, ENC, CODECS_ALL,
+		(MINIMUM_FPS << 16), (MAXIMUM_FPS << 16),
+		1, (DEFAULT_FPS << 16),
+		0,
+		HFI_PROP_FRAME_RATE,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		NULL,
+		set_q16},
+
+	{OPERATING_RATE, ENC, CODECS_ALL,
+		(MINIMUM_FPS << 16), (MAXIMUM_FPS << 16),
+		1, (DEFAULT_FPS << 16)},
+
+	{MB_CYCLES_VSP, DEC, CODECS_ALL, 25, 25, 1, 25},
+
+	{MB_CYCLES_VSP, DEC, VP9, 60, 60, 1, 60},
+
+	{MB_CYCLES_VSP, ENC, CODECS_ALL, 25, 25, 1, 25},
+
+	{MB_CYCLES_VPP, DEC, CODECS_ALL, 200, 200, 1, 200},
+
+	{MB_CYCLES_VPP, ENC, CODECS_ALL, 675, 675, 1, 675},
+
+	{MB_CYCLES_LP, DEC, CODECS_ALL, 200, 200, 1, 200},
+
+	{MB_CYCLES_LP, ENC, CODECS_ALL, 320, 320, 1, 320},
+
+	{MB_CYCLES_FW, DEC | ENC, CODECS_ALL, 489583, 489583, 1, 489583},
+
+	{MB_CYCLES_FW_VPP, DEC, CODECS_ALL, 66234, 66234, 1, 66234},
+
+	{MB_CYCLES_FW_VPP, ENC, CODECS_ALL, 48405, 48405, 1, 48405},
+
+	{NUM_COMV, DEC, CODECS_ALL,
+		0, INT_MAX, 1, 0},
+
+	{PROFILE, DEC, H264,
+		V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+		V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH),
+		V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+		V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+		HFI_PROP_PROFILE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_u32_enum},
+
+	{PROFILE, ENC, H264,
+		V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+		V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+		BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH),
+		V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+		V4L2_CID_MPEG_VIDEO_H264_PROFILE,
+		HFI_PROP_PROFILE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{ENTROPY_MODE, TRANSFORM_8X8},
+		NULL,
+		set_u32_enum},
+
+	{PROFILE, ENC | DEC, HEVC,
+		V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+		V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10,
+		BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10),
+		V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN,
+		V4L2_CID_MPEG_VIDEO_HEVC_PROFILE,
+		HFI_PROP_PROFILE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		adjust_profile,
+		set_u32_enum},
+
+	{PROFILE, DEC, VP9,
+		V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+		V4L2_MPEG_VIDEO_VP9_PROFILE_2,
+		BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_0) |
+		BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_2),
+		V4L2_MPEG_VIDEO_VP9_PROFILE_0,
+		V4L2_CID_MPEG_VIDEO_VP9_PROFILE,
+		HFI_PROP_PROFILE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_u32_enum},
+
+	{LEVEL, DEC, H264,
+		V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+		V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
+		V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
+		V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+		HFI_PROP_LEVEL,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_u32_enum},
+
+	{LEVEL, ENC, H264,
+		V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+		V4L2_MPEG_VIDEO_H264_LEVEL_6_0,
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
+		BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0),
+		V4L2_MPEG_VIDEO_H264_LEVEL_5_0,
+		V4L2_CID_MPEG_VIDEO_H264_LEVEL,
+		HFI_PROP_LEVEL,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_level},
+
+	{LEVEL, DEC, HEVC,
+		V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
+		V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2),
+		V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1,
+		V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
+		HFI_PROP_LEVEL,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_u32_enum},
+
+	{LEVEL, ENC, HEVC,
+		V4L2_MPEG_VIDEO_HEVC_LEVEL_1,
+		V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2,
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2),
+		V4L2_MPEG_VIDEO_HEVC_LEVEL_5,
+		V4L2_CID_MPEG_VIDEO_HEVC_LEVEL,
+		HFI_PROP_LEVEL,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_level},
+
+	{LEVEL, DEC, VP9,
+		V4L2_MPEG_VIDEO_VP9_LEVEL_1_0,
+		V4L2_MPEG_VIDEO_VP9_LEVEL_6_0,
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_0) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_1) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_0) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_1) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_0) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_1) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_0) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_1) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_0) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_1) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_2) |
+		BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_6_0),
+		V4L2_MPEG_VIDEO_VP9_LEVEL_6_0,
+		V4L2_CID_MPEG_VIDEO_VP9_LEVEL,
+		HFI_PROP_LEVEL,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_u32_enum},
+
+	{HEVC_TIER, DEC | ENC, HEVC,
+		V4L2_MPEG_VIDEO_HEVC_TIER_MAIN,
+		V4L2_MPEG_VIDEO_HEVC_TIER_HIGH,
+		BIT(V4L2_MPEG_VIDEO_HEVC_TIER_MAIN) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_TIER_HIGH),
+		V4L2_MPEG_VIDEO_HEVC_TIER_HIGH,
+		V4L2_CID_MPEG_VIDEO_HEVC_TIER,
+		HFI_PROP_TIER,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_u32_enum},
+
+	{HFLIP, ENC, CODECS_ALL,
+		0, 1, 1, 0,
+		V4L2_CID_HFLIP,
+		HFI_PROP_FLIP,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_flip},
+
+	{VFLIP, ENC, CODECS_ALL,
+		0, 1, 1, 0,
+		V4L2_CID_VFLIP,
+		HFI_PROP_FLIP,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_flip},
+
+	{ROTATION, ENC, CODECS_ALL,
+		0, 270, 90, 0,
+		V4L2_CID_ROTATE,
+		HFI_PROP_ROTATION,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		NULL,
+		set_rotation},
+
+	{HEADER_MODE, ENC, CODECS_ALL,
+		V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE,
+		V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+		BIT(V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) |
+		BIT(V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME),
+		V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME,
+		V4L2_CID_MPEG_VIDEO_HEADER_MODE,
+		HFI_PROP_SEQ_HEADER_MODE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{0},
+		NULL,
+		set_header_mode},
+
+	{PREPEND_SPSPPS_TO_IDR, ENC, CODECS_ALL,
+		0, 1, 1, 0,
+		V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR},
+
+	{REQUEST_I_FRAME, ENC, H264 | HEVC,
+		0, 0, 0, 0,
+		V4L2_CID_MPEG_VIDEO_FORCE_KEY_FRAME,
+		HFI_PROP_REQUEST_SYNC_FRAME,
+		CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_req_sync_frame},
+
+	{BIT_RATE, ENC, H264 | HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_BITRATE,
+		HFI_PROP_TOTAL_BITRATE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{PEAK_BITRATE, L0_BR},
+		adjust_bitrate,
+		set_bitrate},
+
+	{PEAK_BITRATE, ENC, H264 | HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+		HFI_PROP_TOTAL_PEAK_BITRATE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		adjust_peak_bitrate,
+		set_peak_bitrate},
+
+	{BITRATE_MODE, ENC, H264 | HEVC,
+		V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+		V4L2_MPEG_VIDEO_BITRATE_MODE_CBR,
+		BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) |
+		BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_CBR),
+		V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+		V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+		HFI_PROP_RATE_CONTROL,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{LTR_COUNT, IR_PERIOD, I_FRAME_QP, P_FRAME_QP,
+		 B_FRAME_QP, ENH_LAYER_COUNT, BIT_RATE,
+		 MIN_QUALITY, PEAK_BITRATE, SLICE_MODE},
+		adjust_bitrate_mode,
+		set_bitrate_mode},
+
+	{FRAME_SKIP_MODE, ENC, H264 | HEVC,
+		V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED,
+		V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT,
+		BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED) |
+		BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT) |
+		BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT),
+		V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED,
+		V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE,
+		0,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU},
+
+	{FRAME_RC_ENABLE, ENC, H264 | HEVC,
+		0, 1, 1, 1,
+		V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE},
+
+	{GOP_SIZE, ENC, CODECS_ALL,
+		0, INT_MAX, 1, 2 * DEFAULT_FPS - 1,
+		V4L2_CID_MPEG_VIDEO_GOP_SIZE,
+		HFI_PROP_MAX_GOP_FRAMES,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		adjust_gop_size,
+		set_gop_size},
+
+	{B_FRAME, ENC, H264 | HEVC,
+		0, 1, 1, 0,
+		V4L2_CID_MPEG_VIDEO_B_FRAMES,
+		HFI_PROP_MAX_B_FRAMES,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		adjust_b_frame,
+		set_u32},
+
+	{LTR_COUNT, ENC, H264 | HEVC,
+		0, MAX_LTR_FRAME_COUNT, 1, 0,
+		V4L2_CID_MPEG_VIDEO_LTR_COUNT,
+		HFI_PROP_LTR_COUNT,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		adjust_ltr_count,
+		set_u32},
+
+	{USE_LTR, ENC, H264 | HEVC,
+		0,
+		((1 << MAX_LTR_FRAME_COUNT) - 1),
+		0, 0,
+		V4L2_CID_MPEG_VIDEO_USE_LTR_FRAMES,
+		HFI_PROP_LTR_USE,
+		CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		adjust_use_ltr,
+		set_use_and_mark_ltr},
+
+	{MARK_LTR, ENC, H264 | HEVC,
+		INVALID_DEFAULT_MARK_OR_USE_LTR,
+		(MAX_LTR_FRAME_COUNT - 1),
+		1, INVALID_DEFAULT_MARK_OR_USE_LTR,
+		V4L2_CID_MPEG_VIDEO_FRAME_LTR_INDEX,
+		HFI_PROP_LTR_MARK,
+		CAP_FLAG_INPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		adjust_mark_ltr,
+		set_use_and_mark_ltr},
+
+	{BASELAYER_PRIORITY, ENC, H264,
+		0, MAX_BASE_LAYER_PRIORITY_ID, 1, 0,
+		V4L2_CID_MPEG_VIDEO_BASELAYER_PRIORITY_ID,
+		HFI_PROP_BASELAYER_PRIORITYID,
+		CAP_FLAG_OUTPUT_PORT},
+
+	{IR_TYPE, ENC, H264 | HEVC,
+		V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM,
+		V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC,
+		BIT(V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM) |
+		BIT(V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_CYCLIC),
+		V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE_RANDOM,
+		V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD_TYPE,
+		0,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU},
+
+	{IR_PERIOD, ENC, H264 | HEVC,
+		0, INT_MAX, 1, 0,
+		V4L2_CID_MPEG_VIDEO_INTRA_REFRESH_PERIOD,
+		0,
+		CAP_FLAG_INPUT_PORT | CAP_FLAG_OUTPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		adjust_ir_period,
+		set_ir_period},
+
+	{MIN_QUALITY, ENC, H264 | HEVC,
+		0, MAX_SUPPORTED_MIN_QUALITY, 70, MAX_SUPPORTED_MIN_QUALITY,
+		0,
+		HFI_PROP_MAINTAIN_MIN_QUALITY,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		adjust_min_quality,
+		set_u32},
+
+	{TIME_DELTA_BASED_RC, ENC, H264 | HEVC,
+		0, 1, 1, 0,
+		0,
+		HFI_PROP_TIME_DELTA_BASED_RATE_CONTROL,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		NULL,
+		set_u32},
+
+	{MIN_FRAME_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_H264_MIN_QP,
+		HFI_PROP_MIN_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		NULL,
+		set_min_qp},
+
+	{MIN_FRAME_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_HEVC_MIN_QP,
+		HFI_PROP_MIN_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		NULL,
+		set_min_qp},
+
+	{MAX_FRAME_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_H264_MAX_QP,
+		HFI_PROP_MAX_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		NULL,
+		set_max_qp},
+
+	{MAX_FRAME_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_MAX_QP,
+		HFI_PROP_MAX_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		NULL,
+		set_max_qp},
+
+	{I_FRAME_MIN_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MIN_QP},
+
+	{I_FRAME_MIN_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MIN_QP},
+
+	{P_FRAME_MIN_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MIN_QP},
+
+	{P_FRAME_MIN_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MIN_QP},
+
+	{B_FRAME_MIN_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MIN_QP},
+
+	{B_FRAME_MIN_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MIN_QP_8BIT,
+		V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MIN_QP},
+
+	{I_FRAME_MAX_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_H264_I_FRAME_MAX_QP},
+
+	{I_FRAME_MAX_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_MAX_QP},
+
+	{P_FRAME_MAX_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_H264_P_FRAME_MAX_QP},
+
+	{P_FRAME_MAX_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_MAX_QP},
+
+	{B_FRAME_MAX_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_H264_B_FRAME_MAX_QP},
+
+	{B_FRAME_MAX_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, MAX_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_MAX_QP},
+
+	{I_FRAME_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP,
+		HFI_PROP_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_frame_qp},
+
+	{I_FRAME_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP,
+		HFI_PROP_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_frame_qp},
+
+	{P_FRAME_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_P_FRAME_QP,
+		HFI_PROP_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_frame_qp},
+
+	{P_FRAME_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP,
+		HFI_PROP_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_frame_qp},
+
+	{B_FRAME_QP, ENC, HEVC,
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_HEVC_B_FRAME_QP,
+		HFI_PROP_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_frame_qp},
+
+	{B_FRAME_QP, ENC, H264,
+		MIN_QP_8BIT, MAX_QP, 1, DEFAULT_QP,
+		V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP,
+		HFI_PROP_QP_PACKED,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		NULL,
+		set_frame_qp},
+
+	{LAYER_TYPE, ENC, HEVC,
+		V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B,
+		V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,
+		BIT(V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) |
+		BIT(V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P),
+		V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE,
+		HFI_PROP_LAYER_ENCODING_TYPE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{LTR_COUNT}},
+
+	{LAYER_TYPE, ENC, H264,
+		V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B,
+		V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
+		BIT(V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B) |
+		BIT(V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P),
+		V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
+		V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE,
+		HFI_PROP_LAYER_ENCODING_TYPE,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{LTR_COUNT}},
+
+	{LAYER_ENABLE, ENC, H264,
+		0, 1, 1, 0,
+		V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING,
+		HFI_PROP_LAYER_ENCODING_TYPE,
+		CAP_FLAG_OUTPUT_PORT},
+
+	{LAYER_ENABLE, ENC, HEVC,
+		0, 1, 1, 0,
+		0,
+		0,
+		CAP_FLAG_OUTPUT_PORT},
+
+	{ENH_LAYER_COUNT, ENC, HEVC,
+		0, 5, 1, 0,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER,
+		HFI_PROP_LAYER_COUNT,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{GOP_SIZE, B_FRAME, BIT_RATE, MIN_QUALITY, SLICE_MODE,
+		 LTR_COUNT},
+		adjust_layer_count,
+		set_layer_count_and_type},
+
+	{ENH_LAYER_COUNT, ENC, H264,
+		0, 5, 1, 0,
+		V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER,
+		HFI_PROP_LAYER_COUNT,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{GOP_SIZE, B_FRAME, BIT_RATE, MIN_QUALITY, SLICE_MODE,
+		 LTR_COUNT},
+		adjust_layer_count,
+		set_layer_count_and_type},
+
+	{L0_BR, ENC, H264,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L0_BR,
+		HFI_PROP_BITRATE_LAYER1,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L1_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L0_BR, ENC, HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR,
+		HFI_PROP_BITRATE_LAYER1,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L1_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L1_BR, ENC, H264,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L1_BR,
+		HFI_PROP_BITRATE_LAYER2,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L2_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L1_BR, ENC, HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR,
+		HFI_PROP_BITRATE_LAYER2,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L2_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L2_BR, ENC, H264,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L2_BR,
+		HFI_PROP_BITRATE_LAYER3,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L3_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L2_BR, ENC, HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR,
+		HFI_PROP_BITRATE_LAYER3,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L3_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L3_BR, ENC, H264,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L3_BR,
+		HFI_PROP_BITRATE_LAYER4,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L4_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L3_BR, ENC, HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L3_BR,
+		HFI_PROP_BITRATE_LAYER4,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L4_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L4_BR, ENC, H264,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L4_BR,
+		HFI_PROP_BITRATE_LAYER5,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L5_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L4_BR, ENC, HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L4_BR,
+		HFI_PROP_BITRATE_LAYER5,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{L5_BR},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L5_BR, ENC, H264,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_H264_HIER_CODING_L5_BR,
+		HFI_PROP_BITRATE_LAYER6,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{L5_BR, ENC, HEVC,
+		1, MAX_BITRATE, 1, DEFAULT_BITRATE,
+		V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L5_BR,
+		HFI_PROP_BITRATE_LAYER6,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT |
+		CAP_FLAG_DYNAMIC_ALLOWED,
+		{0},
+		adjust_layer_bitrate,
+		set_layer_bitrate},
+
+	{ENTROPY_MODE, ENC, H264,
+		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC,
+		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+		BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) |
+		BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC),
+		V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC,
+		V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE,
+		HFI_PROP_CABAC_SESSION,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{BIT_RATE},
+		adjust_entropy_mode,
+		set_u32},
+
+	{SLICE_MODE, ENC, H264 | HEVC,
+		V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+		V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES,
+		BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) |
+		BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) |
+		BIT(V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES),
+		V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
+		V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
+		0,
+		CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+		{STAGE},
+		adjust_slice_count,
+		set_slice_count},
+
+	{SLICE_MAX_BYTES, ENC, H264 | HEVC,
+		MIN_SLICE_BYTE_SIZE, MAX_SLICE_BYTE_SIZE,
+		1, MIN_SLICE_BYTE_SIZE,
+		V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
+		HFI_PROP_MULTI_SLICE_BYTES_COUNT,
+		CAP_FLAG_OUTPUT_PORT},
+
+	{SLICE_MAX_MB, ENC, H264 | HEVC,
+		1, MAX_SLICE_MB_SIZE, 1, 1,
+		V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
+		HFI_PROP_MULTI_SLICE_MB_COUNT,
+		CAP_FLAG_OUTPUT_PORT},
+
+	{TRANSFORM_8X8, ENC, H264,
+		0, 1, 1, 1,
+		V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM,
+		HFI_PROP_8X8_TRANSFORM,
+		CAP_FLAG_OUTPUT_PORT,
+		{0},
+		adjust_transform_8x8,
+		set_u32},
+
+	{DISPLAY_DELAY_ENABLE, DEC, CODECS_ALL,
+		0, 1, 1, 0,
+		V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE,
+		HFI_PROP_DECODE_ORDER_OUTPUT,
+		CAP_FLAG_INPUT_PORT,
+		{OUTPUT_ORDER},
+		NULL,
+		NULL},
+
+	{DISPLAY_DELAY, DEC, CODECS_ALL,
+		0, 1, 1, 0,
+		V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY,
+		HFI_PROP_DECODE_ORDER_OUTPUT,
+		CAP_FLAG_INPUT_PORT,
+		{OUTPUT_ORDER},
+		NULL,
+		NULL},
+
+	{OUTPUT_ORDER, DEC, CODECS_ALL,
+		0, 1, 1, 0,
+		0,
+		HFI_PROP_DECODE_ORDER_OUTPUT,
+		CAP_FLAG_INPUT_PORT,
+		{0},
+		adjust_output_order,
+		set_u32},
+
+	{INPUT_BUF_HOST_MAX_COUNT, ENC | DEC, CODECS_ALL,
+		DEFAULT_MAX_HOST_BUF_COUNT, DEFAULT_MAX_HOST_BURST_BUF_COUNT,
+		1, DEFAULT_MAX_HOST_BUF_COUNT,
+		0,
+		HFI_PROP_BUFFER_HOST_MAX_COUNT,
+		CAP_FLAG_INPUT_PORT,
+		{0},
+		NULL,
+		set_u32},
+
+	{STAGE, ENC | DEC, CODECS_ALL,
+		STAGE_1,
+		STAGE_2, 1,
+		STAGE_2,
+		0,
+		HFI_PROP_STAGE,
+		CAP_FLAG_NONE,
+		{0},
+		NULL,
+		set_stage},
+
+	{PIPE, ENC | DEC, CODECS_ALL,
+		PIPE_1,
+		PIPE_4, 1,
+		PIPE_4,
+		0,
+		HFI_PROP_PIPE,
+		CAP_FLAG_NONE,
+		{0},
+		NULL,
+		set_pipe},
+
+	{QUALITY_MODE, ENC, CODECS_ALL,
+		MAX_QUALITY_MODE,
+		POWER_SAVE_MODE, 1,
+		POWER_SAVE_MODE},
+
+	{POC, DEC, H264, 0, 2, 1, 1,
+		0,
+		HFI_PROP_PIC_ORDER_CNT_TYPE},
+
+	{CODED_FRAMES, DEC, H264 | HEVC,
+		CODED_FRAMES_PROGRESSIVE, CODED_FRAMES_PROGRESSIVE,
+		0, CODED_FRAMES_PROGRESSIVE,
+		0,
+		HFI_PROP_CODED_FRAMES},
+
+	{BIT_DEPTH, DEC, CODECS_ALL, BIT_DEPTH_8, BIT_DEPTH_10, 1, BIT_DEPTH_8,
+		0,
+		HFI_PROP_LUMA_CHROMA_BIT_DEPTH},
+
+	{DEFAULT_HEADER, DEC, CODECS_ALL,
+		0, 1, 1, 0,
+		0,
+		HFI_PROP_DEC_DEFAULT_HEADER},
+
+	{RAP_FRAME, DEC, CODECS_ALL,
+		0, 1, 1, 1,
+		0,
+		HFI_PROP_DEC_START_FROM_RAP_FRAME,
+		CAP_FLAG_INPUT_PORT,
+		{0},
+		NULL,
+		set_u32},
+};
+
+static const struct bus_info sm8550_bus_table[] = {
+	{ NULL, "iris-cnoc", 1000, 1000     },
+	{ NULL, "iris-ddr",  1000, 15000000 },
+};
+
+static const struct clock_info sm8550_clk_table[] = {
+	{ NULL, "gcc_video_axi0", GCC_VIDEO_AXI0_CLK, 0 },
+	{ NULL, "core_clk",       VIDEO_CC_MVS0C_CLK, 0 },
+	{ NULL, "vcodec_core",    VIDEO_CC_MVS0_CLK,  1 },
+};
+
+static const char * const sm8550_clk_reset_table[] = { "video_axi_reset", NULL };
+
+static const char * const sm8550_pd_table[] = { "iris-ctl", "vcodec", NULL };
+
+static const char * const sm8550_opp_pd_table[] = { "mxc", "mmcx", NULL };
+
+static const struct bw_info sm8550_bw_table_enc[] = {
+	{ 1944000, 1491000, 2693000 },	/* 3840x2160@60 */
+	{  972000,  765000, 1366000 },	/* 3840x2160@30 */
+	{  489600,  557000, 780000 },	/* 1920x1080@60 */
+	{  244800,  288000, 399000 },	/* 1920x1080@30 */
+};
+
+static const struct bw_info sm8550_bw_table_dec[] = {
+	{ 2073600, 1608000, 2742000 },	/* 4096x2160@60 */
+	{ 1036800,  826000, 1393000 },	/* 4096x2160@30 */
+	{  489600,  567000,  723000 },	/* 1920x1080@60 */
+	{  244800,  294000,  372000 },	/* 1920x1080@30 */
+};
+
+static const struct reg_preset_info sm8550_reg_preset_table[] = {
+	{ 0xB0088, 0x0, 0x11 },
+};
+
+static struct ubwc_config_data ubwc_config_sm8550[] = {
+	UBWC_CONFIG(8, 32, 16, 0, 1, 1, 1),
+};
+
+static struct format_capability format_data_sm8550 = {
+	.codec_info = codec_data_sm8550,
+	.codec_info_size = ARRAY_SIZE(codec_data_sm8550),
+	.color_format_info = color_format_data_sm8550,
+	.color_format_info_size = ARRAY_SIZE(color_format_data_sm8550),
+};
+
+static const u32 sm8550_vdec_src_change_param_avc[] = {
+	HFI_PROP_BITSTREAM_RESOLUTION,
+	HFI_PROP_CROP_OFFSETS,
+	HFI_PROP_CODED_FRAMES,
+	HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
+	HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
+	HFI_PROP_PIC_ORDER_CNT_TYPE,
+	HFI_PROP_PROFILE,
+	HFI_PROP_LEVEL,
+	HFI_PROP_SIGNAL_COLOR_INFO,
+};
+
+static const u32 sm8550_vdec_src_change_param_hevc[] = {
+	HFI_PROP_BITSTREAM_RESOLUTION,
+	HFI_PROP_CROP_OFFSETS,
+	HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
+	HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
+	HFI_PROP_PROFILE,
+	HFI_PROP_LEVEL,
+	HFI_PROP_TIER,
+	HFI_PROP_SIGNAL_COLOR_INFO,
+};
+
+static const u32 sm8550_vdec_src_change_param_vp9[] = {
+	HFI_PROP_BITSTREAM_RESOLUTION,
+	HFI_PROP_CROP_OFFSETS,
+	HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
+	HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
+	HFI_PROP_PROFILE,
+	HFI_PROP_LEVEL,
+};
+
+static const u32 sm8550_vdec_input_properties[] = {
+	HFI_PROP_NO_OUTPUT,
+};
+
+static const u32 sm8550_vdec_output_properties_avc[] = {
+	HFI_PROP_PICTURE_TYPE,
+	HFI_PROP_DPB_LIST,
+	HFI_PROP_CABAC_SESSION,
+};
+
+static const u32 sm8550_vdec_output_properties_hevc[] = {
+	HFI_PROP_PICTURE_TYPE,
+	HFI_PROP_DPB_LIST,
+};
+
+static const u32 sm8550_vdec_output_properties_vp9[] = {
+	HFI_PROP_PICTURE_TYPE,
+	HFI_PROP_DPB_LIST,
+};
+
+struct platform_data sm8550_data = {
+	.bus_tbl = sm8550_bus_table,
+	.bus_tbl_size = ARRAY_SIZE(sm8550_bus_table),
+	.clk_tbl = sm8550_clk_table,
+	.clk_tbl_size = ARRAY_SIZE(sm8550_clk_table),
+	.clk_rst_tbl = sm8550_clk_reset_table,
+	.clk_rst_tbl_size = ARRAY_SIZE(sm8550_clk_reset_table),
+
+	.bw_tbl_enc = sm8550_bw_table_enc,
+	.bw_tbl_enc_size = ARRAY_SIZE(sm8550_bw_table_enc),
+	.bw_tbl_dec = sm8550_bw_table_dec,
+	.bw_tbl_dec_size = ARRAY_SIZE(sm8550_bw_table_dec),
+
+	.pd_tbl = sm8550_pd_table,
+	.pd_tbl_size = ARRAY_SIZE(sm8550_pd_table),
+	.opp_pd_tbl = sm8550_opp_pd_table,
+	.opp_pd_tbl_size = ARRAY_SIZE(sm8550_opp_pd_table),
+
+	.reg_prst_tbl = sm8550_reg_preset_table,
+	.reg_prst_tbl_size = ARRAY_SIZE(sm8550_reg_preset_table),
+	.fwname = "qcom/vpu-3.0/vpu30_4v",
+	.pas_id = 9,
+
+	.core_data = core_data_sm8550,
+	.core_data_size = ARRAY_SIZE(core_data_sm8550),
+	.inst_cap_data = instance_cap_data_sm8550,
+	.inst_cap_data_size = ARRAY_SIZE(instance_cap_data_sm8550),
+	.ubwc_config = ubwc_config_sm8550,
+	.format_data = &format_data_sm8550,
+
+	.avc_subscribe_param =
+		sm8550_vdec_src_change_param_avc,
+	.avc_subscribe_param_size =
+		ARRAY_SIZE(sm8550_vdec_src_change_param_avc),
+	.hevc_subscribe_param =
+		sm8550_vdec_src_change_param_hevc,
+	.hevc_subscribe_param_size =
+		ARRAY_SIZE(sm8550_vdec_src_change_param_hevc),
+	.vp9_subscribe_param =
+		sm8550_vdec_src_change_param_vp9,
+	.vp9_subscribe_param_size =
+		ARRAY_SIZE(sm8550_vdec_src_change_param_vp9),
+	.dec_input_prop = sm8550_vdec_input_properties,
+	.dec_input_prop_size = ARRAY_SIZE(sm8550_vdec_input_properties),
+	.dec_output_prop_avc = sm8550_vdec_output_properties_avc,
+	.dec_output_prop_size_avc = ARRAY_SIZE(sm8550_vdec_output_properties_avc),
+	.dec_output_prop_hevc = sm8550_vdec_output_properties_hevc,
+	.dec_output_prop_size_hevc = ARRAY_SIZE(sm8550_vdec_output_properties_hevc),
+	.dec_output_prop_vp9 = sm8550_vdec_output_properties_vp9,
+	.dec_output_prop_size_vp9 = ARRAY_SIZE(sm8550_vdec_output_properties_vp9),
+};
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/resources.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/resources.c
@@ -0,0 +1,517 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/interconnect.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/sort.h>
+
+#include "iris_core.h"
+#include "platform_common.h"
+#include "resources.h"
+
+#define BW_THRESHOLD 50000
+
+static void iris_pd_release(void *res)
+{
+	struct device *pd = (struct device *)res;
+
+	dev_pm_domain_detach(pd, true);
+}
+
+static int iris_pd_get(struct iris_core *core, struct power_domain_info *pdinfo)
+{
+	int ret;
+
+	pdinfo->genpd_dev = dev_pm_domain_attach_by_name(core->dev, pdinfo->name);
+	if (IS_ERR_OR_NULL(pdinfo->genpd_dev))
+		ret = PTR_ERR(pdinfo->genpd_dev) ? : -ENODATA;
+
+	ret = devm_add_action_or_reset(core->dev, iris_pd_release, (void *)pdinfo->genpd_dev);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+
+static void iris_opp_dl_release(void *res)
+{
+	struct device_link *link = (struct device_link *)res;
+
+	device_link_del(link);
+}
+
+static int iris_opp_dl_get(struct device *dev, struct device *supplier)
+{
+	u32 flag = DL_FLAG_RPM_ACTIVE | DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS;
+	struct device_link *link = NULL;
+	int ret;
+
+	link = device_link_add(dev, supplier, flag);
+	if (!link)
+		return -EINVAL;
+
+	ret = devm_add_action_or_reset(dev, iris_opp_dl_release, (void *)link);
+
+	return ret;
+}
+
+int opp_set_rate(struct iris_core *core, u64 freq)
+{
+	unsigned long opp_freq = 0;
+	struct dev_pm_opp *opp;
+	int ret;
+
+	opp_freq = freq;
+
+	opp = dev_pm_opp_find_freq_ceil(core->dev, &opp_freq);
+	if (IS_ERR(opp)) {
+		opp = dev_pm_opp_find_freq_floor(core->dev, &opp_freq);
+		if (IS_ERR(opp)) {
+			dev_err(core->dev,
+				"unable to find freq %lld in opp table\n", freq);
+			return -EINVAL;
+		}
+	}
+	dev_pm_opp_put(opp);
+
+	ret = dev_pm_opp_set_rate(core->dev, opp_freq);
+	if (ret) {
+		dev_err(core->dev, "failed to set rate\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+static int init_bus(struct iris_core *core)
+{
+	const struct bus_info *bus_tbl;
+	struct bus_info *binfo = NULL;
+	u32 i = 0;
+
+	bus_tbl = core->platform_data->bus_tbl;
+
+	core->bus_count = core->platform_data->bus_tbl_size;
+	core->bus_tbl = devm_kzalloc(core->dev,
+				     sizeof(struct bus_info) * core->bus_count,
+				     GFP_KERNEL);
+	if (!core->bus_tbl)
+		return -ENOMEM;
+
+	for (i = 0; i < core->bus_count; i++) {
+		binfo = &core->bus_tbl[i];
+		binfo->name = bus_tbl[i].name;
+		binfo->bw_min_kbps = bus_tbl[i].bw_min_kbps;
+		binfo->bw_max_kbps = bus_tbl[i].bw_max_kbps;
+		binfo->icc = devm_of_icc_get(core->dev, binfo->name);
+		if (IS_ERR(binfo->icc)) {
+			dev_err(core->dev,
+				"%s: failed to get bus: %s\n", __func__, binfo->name);
+			return PTR_ERR(binfo->icc);
+		}
+	}
+
+	return 0;
+}
+
+static int init_power_domains(struct iris_core *core)
+{
+	struct power_domain_info *pdinfo = NULL;
+	const char * const *opp_pd_tbl;
+	const char * const *pd_tbl;
+	struct device **opp_vdevs = NULL;
+	u32 opp_pd_cnt, i;
+	int ret;
+
+	pd_tbl = core->platform_data->pd_tbl;
+
+	core->pd_count = core->platform_data->pd_tbl_size;
+	core->power_domain_tbl = devm_kzalloc(core->dev,
+					      sizeof(struct power_domain_info) * core->pd_count,
+					      GFP_KERNEL);
+	if (!core->power_domain_tbl)
+		return -ENOMEM;
+
+	for (i = 0; i < (core->pd_count - 1); i++) {
+		pdinfo = &core->power_domain_tbl[i];
+		pdinfo->name = pd_tbl[i];
+		ret = iris_pd_get(core, pdinfo);
+		if (ret) {
+			dev_err(core->dev,
+				"%s: failed to get pd: %s\n", __func__, pdinfo->name);
+			return ret;
+		}
+	}
+
+	opp_pd_tbl = core->platform_data->opp_pd_tbl;
+	opp_pd_cnt = core->platform_data->opp_pd_tbl_size;
+
+	ret = devm_pm_opp_attach_genpd(core->dev, opp_pd_tbl, &opp_vdevs);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < (opp_pd_cnt - 1) ; i++) {
+		ret = iris_opp_dl_get(core->dev, opp_vdevs[i]);
+		if (ret) {
+			dev_err(core->dev, "%s: failed to create dl: %s\n",
+				__func__, dev_name(opp_vdevs[i]));
+			return ret;
+		}
+	}
+
+	ret = devm_pm_opp_set_clkname(core->dev, "vcodec_core");
+	if (ret)
+		return ret;
+
+	ret = devm_pm_opp_of_add_table(core->dev);
+	if (ret) {
+		dev_err(core->dev, "%s: failed to add opp table\n", __func__);
+		return ret;
+	}
+
+	return ret;
+}
+
+int enable_power_domains(struct iris_core *core, const char *name)
+{
+	struct power_domain_info *pdinfo = NULL;
+	int ret;
+	u32 i;
+
+	ret = opp_set_rate(core, ULONG_MAX);
+	if (ret)
+		return ret;
+
+	core->pd_count = core->platform_data->pd_tbl_size;
+	for (i = 0; i < (core->pd_count - 1); i++) {
+		pdinfo = &core->power_domain_tbl[i];
+		if (strcmp(pdinfo->name, name))
+			continue;
+		ret = pm_runtime_get_sync(pdinfo->genpd_dev);
+		if (ret < 0)
+			return ret;
+	}
+
+	ret = opp_set_rate(core, ULONG_MAX);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+
+int disable_power_domains(struct iris_core *core, const char *name)
+{
+	struct power_domain_info *pdinfo = NULL;
+	int ret;
+	u32 i;
+
+	ret = opp_set_rate(core, 0);
+	if (ret)
+		return ret;
+
+	core->pd_count = core->platform_data->pd_tbl_size;
+	for (i = 0; i < (core->pd_count - 1); i++) {
+		pdinfo = &core->power_domain_tbl[i];
+		if (strcmp(pdinfo->name, name))
+			continue;
+		ret = pm_runtime_put_sync(pdinfo->genpd_dev);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static int init_clocks(struct iris_core *core)
+{
+	const struct clock_info *clk_tbl;
+	struct clock_info *cinfo = NULL;
+	u32 i;
+
+	clk_tbl = core->platform_data->clk_tbl;
+
+	core->clk_count = core->platform_data->clk_tbl_size;
+	core->clock_tbl = devm_kzalloc(core->dev,
+				       sizeof(struct clock_info) * core->clk_count,
+				       GFP_KERNEL);
+	if (!core->clock_tbl)
+		return -ENOMEM;
+
+	for (i = 0; i < core->clk_count; i++) {
+		cinfo = &core->clock_tbl[i];
+		cinfo->name = clk_tbl[i].name;
+		cinfo->clk_id = clk_tbl[i].clk_id;
+		cinfo->has_scaling = clk_tbl[i].has_scaling;
+		cinfo->clk = devm_clk_get(core->dev, cinfo->name);
+		if (IS_ERR(cinfo->clk)) {
+			dev_err(core->dev,
+				"%s: failed to get clock: %s\n", __func__, cinfo->name);
+			return PTR_ERR(cinfo->clk);
+		}
+	}
+
+	return 0;
+}
+
+static int init_reset_clocks(struct iris_core *core)
+{
+	struct reset_info *rinfo = NULL;
+	const char * const *rst_tbl;
+	u32 i = 0;
+
+	rst_tbl = core->platform_data->clk_rst_tbl;
+
+	if (!rst_tbl) {
+		dev_info(core->dev, "no reset clocks found\n");
+		return 0;
+	}
+
+	core->reset_count = core->platform_data->clk_rst_tbl_size;
+	core->reset_tbl = devm_kzalloc(core->dev,
+				       sizeof(struct reset_info) * core->reset_count,
+				       GFP_KERNEL);
+	if (!core->reset_tbl)
+		return -ENOMEM;
+
+	for (i = 0; i < (core->reset_count - 1); i++) {
+		rinfo = &core->reset_tbl[i];
+		rinfo->name = rst_tbl[i];
+		rinfo->rst = devm_reset_control_get(core->dev, rinfo->name);
+		if (IS_ERR(rinfo->rst)) {
+			dev_err(core->dev,
+				"%s: failed to get reset clock: %s\n", __func__, rinfo->name);
+			return PTR_ERR(rinfo->rst);
+		}
+	}
+
+	return 0;
+}
+
+int unvote_buses(struct iris_core *core)
+{
+	struct bus_info *bus = NULL;
+	int ret = 0;
+	u32 i;
+
+	core->power.bus_bw = 0;
+	core->bus_count = core->platform_data->bus_tbl_size;
+
+	for (i = 0; i < core->bus_count; i++) {
+		bus = &core->bus_tbl[i];
+		if (!bus->icc)
+			return -EINVAL;
+
+		ret = icc_set_bw(bus->icc, 0, 0);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+int vote_buses(struct iris_core *core, unsigned long bus_bw)
+{
+	unsigned long bw_kbps = 0, bw_prev = 0;
+	struct bus_info *bus = NULL;
+	int ret = 0;
+	u32 i;
+
+	core->bus_count = core->platform_data->bus_tbl_size;
+
+	for (i = 0; i < core->bus_count; i++) {
+		bus = &core->bus_tbl[i];
+		if (bus && bus->icc) {
+			if (!strcmp(bus->name, "iris-ddr")) {
+				bw_kbps = bus_bw;
+				bw_prev = core->power.bus_bw;
+			} else {
+				bw_kbps = bus->bw_max_kbps;
+				bw_prev = core->power.bus_bw ?
+						bw_kbps : 0;
+			}
+
+			bw_kbps = clamp_t(typeof(bw_kbps), bw_kbps,
+					  bus->bw_min_kbps, bus->bw_max_kbps);
+
+			if (abs(bw_kbps - bw_prev) < BW_THRESHOLD && bw_prev)
+				continue;
+
+			ret = icc_set_bw(bus->icc, bw_kbps, 0);
+			if (ret)
+				return ret;
+
+			if (!strcmp(bus->name, "iris-ddr"))
+				core->power.bus_bw = bw_kbps;
+		}
+	}
+
+	return ret;
+}
+
+static int deassert_reset_control(struct iris_core *core)
+{
+	struct reset_info *rcinfo = NULL;
+	int ret = 0;
+	u32 i;
+
+	core->reset_count = core->platform_data->clk_rst_tbl_size;
+
+	if (!core->reset_count)
+		return ret;
+
+	for (i = 0; i < (core->reset_count - 1); i++) {
+		rcinfo = &core->reset_tbl[i];
+		ret = reset_control_deassert(rcinfo->rst);
+		if (ret) {
+			dev_err(core->dev, "deassert reset control failed. ret = %d\n", ret);
+			continue;
+		}
+	}
+
+	return ret;
+}
+
+static int assert_reset_control(struct iris_core *core)
+{
+	struct reset_info *rcinfo = NULL;
+	int ret = 0, cnt = 0;
+	u32 i;
+
+	core->reset_count = core->platform_data->clk_rst_tbl_size;
+
+	if (!core->reset_count)
+		return ret;
+
+	for (i = 0; i < (core->reset_count - 1); i++) {
+		rcinfo = &core->reset_tbl[i];
+		if (!rcinfo->rst)
+			return -EINVAL;
+
+		ret = reset_control_assert(rcinfo->rst);
+		if (ret) {
+			dev_err(core->dev, "failed to assert reset control %s, ret = %d\n",
+				rcinfo->name, ret);
+			goto deassert_reset_control;
+		}
+		cnt++;
+
+		usleep_range(1000, 1100);
+	}
+
+	return ret;
+deassert_reset_control:
+	for (i = 0; i < cnt; i++) {
+		rcinfo = &core->reset_tbl[i];
+		reset_control_deassert(rcinfo->rst);
+	}
+
+	return ret;
+}
+
+int reset_ahb2axi_bridge(struct iris_core *core)
+{
+	int ret;
+
+	ret = assert_reset_control(core);
+	if (ret)
+		return ret;
+
+	ret = deassert_reset_control(core);
+
+	return ret;
+}
+
+int disable_unprepare_clock(struct iris_core *core, const char *clk_name)
+{
+	struct clock_info *cl;
+	bool found = false;
+	u32 i;
+
+	core->clk_count = core->platform_data->clk_tbl_size;
+
+	for (i = 0; i < core->clk_count; i++) {
+		cl = &core->clock_tbl[i];
+		if (!cl->clk)
+			return -EINVAL;
+
+		if (strcmp(cl->name, clk_name))
+			continue;
+
+		found = true;
+		clk_disable_unprepare(cl->clk);
+		cl->prev = 0;
+		break;
+	}
+
+	if (!found)
+		return -EINVAL;
+
+	return 0;
+}
+
+int prepare_enable_clock(struct iris_core *core, const char *clk_name)
+{
+	struct clock_info *cl;
+	bool found = false;
+	int ret = 0;
+	u32 i;
+
+	core->clk_count = core->platform_data->clk_tbl_size;
+
+	for (i = 0; i < core->clk_count; i++) {
+		cl = &core->clock_tbl[i];
+		if (!cl->clk)
+			return -EINVAL;
+
+		if (strcmp(cl->name, clk_name))
+			continue;
+
+		found = true;
+
+		ret = clk_prepare_enable(cl->clk);
+		if (ret) {
+			dev_err(core->dev, "failed to enable clock %s\n", cl->name);
+			return ret;
+		}
+
+		if (!__clk_is_enabled(cl->clk)) {
+			clk_disable_unprepare(cl->clk);
+			return -EINVAL;
+		}
+		break;
+	}
+
+	if (!found)
+		return -EINVAL;
+
+	return ret;
+}
+
+int init_resources(struct iris_core *core)
+{
+	int ret;
+
+	ret = init_bus(core);
+	if (ret)
+		return ret;
+
+	ret = init_power_domains(core);
+	if (ret)
+		return ret;
+
+	ret = init_clocks(core);
+	if (ret)
+		return ret;
+
+	ret = init_reset_clocks(core);
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/resources.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/resources.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _RESOURCES_H_
+#define _RESOURCES_H_
+
+struct bus_info {
+	struct icc_path		*icc;
+	const char		*name;
+	u32			bw_min_kbps;
+	u32			bw_max_kbps;
+};
+
+struct power_domain_info {
+	struct device	*genpd_dev;
+	const char	*name;
+};
+
+struct clock_info {
+	struct clk	*clk;
+	const char	*name;
+	u32		clk_id;
+	bool		has_scaling;
+	u64		prev;
+};
+
+struct reset_info {
+	struct reset_control	*rst;
+	const char		*name;
+};
+
+int enable_power_domains(struct iris_core *core, const char *name);
+int disable_power_domains(struct iris_core *core, const char *name);
+int unvote_buses(struct iris_core *core);
+int vote_buses(struct iris_core *core, unsigned long bus_bw);
+int reset_ahb2axi_bridge(struct iris_core *core);
+int opp_set_rate(struct iris_core *core, u64 freq);
+int disable_unprepare_clock(struct iris_core *core, const char *clk_name);
+int prepare_enable_clock(struct iris_core *core, const char *clk_name);
+int init_resources(struct iris_core *core);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/vpu_common.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/vpu_common.c
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/iopoll.h>
+
+#include "vpu_iris2.h"
+#include "vpu_iris3.h"
+#include "iris_core.h"
+#include "iris_helpers.h"
+#include "vpu_common.h"
+
+int write_register(struct iris_core *core, u32 reg, u32 value)
+{
+	void __iomem *base_addr;
+	int ret;
+
+	ret = check_core_lock(core);
+	if (ret)
+		return ret;
+
+	if (!core->power_enabled)
+		return -EINVAL;
+
+	base_addr = core->reg_base;
+	base_addr += reg;
+	writel_relaxed(value, base_addr);
+
+	/* Make sure value is written into the register */
+	wmb();
+
+	return ret;
+}
+
+int write_register_masked(struct iris_core *core, u32 reg, u32 value, u32 mask)
+{
+	void __iomem *base_addr;
+	u32 prev_val, new_val;
+	int ret;
+
+	ret = check_core_lock(core);
+	if (ret)
+		return ret;
+
+	if (!core->power_enabled)
+		return -EINVAL;
+
+	base_addr = core->reg_base;
+	base_addr += reg;
+
+	prev_val = readl_relaxed(base_addr);
+	/*
+	 * Memory barrier to ensure register read is correct
+	 */
+	rmb();
+
+	new_val = (prev_val & ~mask) | (value & mask);
+
+	writel_relaxed(new_val, base_addr);
+	/*
+	 * Memory barrier to make sure value is written into the register.
+	 */
+	wmb();
+
+	return ret;
+}
+
+int read_register(struct iris_core *core, u32 reg, u32 *value)
+{
+	void __iomem *base_addr;
+
+	if (!core->power_enabled)
+		return -EINVAL;
+
+	base_addr = core->reg_base;
+
+	*value = readl_relaxed(base_addr + reg);
+
+	/* Make sure value is read correctly from the register */
+	rmb();
+
+	return 0;
+}
+
+int read_register_with_poll_timeout(struct iris_core *core, u32 reg,
+				    u32 mask, u32 exp_val, u32 sleep_us,
+				    u32 timeout_us)
+{
+	void __iomem *base_addr;
+	u32 val = 0;
+	int ret;
+
+	if (!core->power_enabled)
+		return -EINVAL;
+
+	base_addr = core->reg_base;
+
+	ret = readl_relaxed_poll_timeout(base_addr + reg, val, ((val & mask) == exp_val),
+					 sleep_us, timeout_us);
+	/*
+	 * Memory barrier to make sure value is read correctly from the
+	 * register.
+	 */
+	rmb();
+
+	return ret;
+}
+
+int set_preset_registers(struct iris_core *core)
+{
+	const struct reg_preset_info *reg_prst;
+	unsigned int prst_count;
+	int cnt, ret = 0;
+
+	reg_prst = core->platform_data->reg_prst_tbl;
+	prst_count = core->platform_data->reg_prst_tbl_size;
+
+	if (!reg_prst || !prst_count)
+		return 0;
+
+	for (cnt = 0; cnt < prst_count; cnt++) {
+		ret = write_register_masked(core, reg_prst[cnt].reg,
+					    reg_prst[cnt].value, reg_prst[cnt].mask);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static const struct compat_handle compat_handle[] = {
+	{
+		.compat                  = "qcom,sm8550-iris",
+		.init                    = init_iris3,
+	},
+	{
+		.compat                  = "qcom,qcm6490-iris",
+		.init                    = init_iris2,
+	},
+};
+
+int init_vpu(struct iris_core *core)
+{
+	struct device *dev = NULL;
+	int i, ret = 0;
+
+	dev = core->dev;
+
+	for (i = 0; i < ARRAY_SIZE(compat_handle); i++) {
+		if (of_device_is_compatible(dev->of_node, compat_handle[i].compat)) {
+			ret = compat_handle[i].init(core);
+			if (ret)
+				return ret;
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(compat_handle))
+		return -EINVAL;
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/vpu_common.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/vpu_common.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _VPU_COMMON_H_
+#define _VPU_COMMON_H_
+
+#include <linux/types.h>
+
+struct iris_core;
+
+#define call_vpu_op(d, op, ...)			\
+	(((d) && (d)->vpu_ops && (d)->vpu_ops->op) ? \
+	((d)->vpu_ops->op(__VA_ARGS__)) : 0)
+
+struct compat_handle {
+	const char *compat;
+	int (*init)(struct iris_core *core);
+};
+
+struct vpu_ops {
+	int (*boot_firmware)(struct iris_core *core);
+	int (*raise_interrupt)(struct iris_core *core);
+	int (*clear_interrupt)(struct iris_core *core);
+	int (*watchdog)(struct iris_core *core, u32 intr_status);
+	int (*power_on)(struct iris_core *core);
+	int (*power_off)(struct iris_core *core);
+	int (*prepare_pc)(struct iris_core *core);
+};
+
+#define call_session_op(c, op, ...)			\
+	(((c) && (c)->session_ops && (c)->session_ops->op) ? \
+	((c)->session_ops->op(__VA_ARGS__)) : 0)
+
+struct vpu_session_ops {
+	int (*int_buf_size)(struct iris_inst *inst, enum iris_buffer_type type);
+	u64 (*calc_freq)(struct iris_inst *inst, u32 data_size);
+	int (*calc_bw)(struct iris_inst *inst, struct bus_vote_data *data);
+};
+
+int init_vpu(struct iris_core *core);
+
+int write_register(struct iris_core *core, u32 reg, u32 value);
+int write_register_masked(struct iris_core *core, u32 reg, u32 value, u32 mask);
+int read_register(struct iris_core *core, u32 reg, u32 *value);
+int read_register_with_poll_timeout(struct iris_core *core, u32 reg,
+				    u32 mask, u32 exp_val, u32 sleep_us,
+				    u32 timeout_us);
+int set_preset_registers(struct iris_core *core);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/vpu_iris2.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/vpu_iris2.c
@@ -0,0 +1,604 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+
+#include "iris_hfi.h"
+#include "vpu_iris2.h"
+#include "vpu_iris2_buffer.h"
+#include "vpu_iris2_power.h"
+
+#define VIDEO_ARCH_LX 1
+
+#define VCODEC_BASE_OFFS_IRIS2                 0x00000000
+#define AON_MVP_NOC_RESET                      0x0001F000
+#define CPU_BASE_OFFS_IRIS2                    0x000A0000
+#define AON_BASE_OFFS                          0x000E0000
+#define CPU_CS_BASE_OFFS_IRIS2                 (CPU_BASE_OFFS_IRIS2)
+#define CPU_IC_BASE_OFFS_IRIS2                 (CPU_BASE_OFFS_IRIS2)
+
+#define CPU_CS_A2HSOFTINTCLR_IRIS2             (CPU_CS_BASE_OFFS_IRIS2 + 0x1C)
+#define CPU_CS_VCICMDARG0_IRIS2                (CPU_CS_BASE_OFFS_IRIS2 + 0x24)
+#define CPU_CS_VCICMDARG1_IRIS2                (CPU_CS_BASE_OFFS_IRIS2 + 0x28)
+/* HFI_CTRL_INIT */
+#define CPU_CS_SCIACMD_IRIS2                   (CPU_CS_BASE_OFFS_IRIS2 + 0x48)
+/* HFI_CTRL_STATUS */
+#define CPU_CS_SCIACMDARG0_IRIS2               (CPU_CS_BASE_OFFS_IRIS2 + 0x4C)
+
+/* HFI_QTBL_INFO */
+#define CPU_CS_SCIACMDARG1_IRIS2               (CPU_CS_BASE_OFFS_IRIS2 + 0x50)
+
+/* HFI_QTBL_ADDR */
+#define CPU_CS_SCIACMDARG2_IRIS2               (CPU_CS_BASE_OFFS_IRIS2 + 0x54)
+
+/* SFR_ADDR */
+#define CPU_CS_SCIBCMD_IRIS2                   (CPU_CS_BASE_OFFS_IRIS2 + 0x5C)
+#define CPU_CS_SCIBCMDARG0_IRIS2               (CPU_CS_BASE_OFFS_IRIS2 + 0x60)
+
+/* UC_REGION_ADDR */
+#define CPU_CS_SCIBARG1_IRIS2                  (CPU_CS_BASE_OFFS_IRIS2 + 0x64)
+
+/* UC_REGION_ADDR */
+#define CPU_CS_SCIBARG2_IRIS2                  (CPU_CS_BASE_OFFS_IRIS2 + 0x68)
+#define CPU_CS_H2XSOFTINTEN_IRIS2              (CPU_CS_BASE_OFFS_IRIS2 + 0x148)
+#define CPU_CS_AHB_BRIDGE_SYNC_RESET           (CPU_CS_BASE_OFFS_IRIS2 + 0x160)
+#define CPU_CS_X2RPMH_IRIS2                    (CPU_CS_BASE_OFFS_IRIS2 + 0x168)
+
+#define CPU_IC_SOFTINT_IRIS2                   (CPU_IC_BASE_OFFS_IRIS2 + 0x150)
+#define CPU_IC_SOFTINT_H2A_SHFT_IRIS2          0x0
+
+#define CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_IRIS2     0x40000000
+#define CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS2      0xfe
+#define CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_IRIS2               0x100
+
+#define AON_WRAPPER_MVP_NOC_RESET_REQ          (AON_MVP_NOC_RESET + 0x000)
+#define AON_WRAPPER_MVP_NOC_RESET_ACK          (AON_MVP_NOC_RESET + 0x004)
+
+#define WRAPPER_BASE_OFFS_IRIS2                0x000B0000
+#define WRAPPER_CORE_POWER_STATUS              (WRAPPER_BASE_OFFS_IRIS2 + 0x80)
+#define WRAPPER_INTR_STATUS_IRIS2              (WRAPPER_BASE_OFFS_IRIS2 + 0x0C)
+#define WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2   0x8
+#define WRAPPER_INTR_STATUS_A2H_BMSK_IRIS2     0x4
+
+#define WRAPPER_INTR_MASK_IRIS2                (WRAPPER_BASE_OFFS_IRIS2 + 0x10)
+#define WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS2     0x8
+#define WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS2    0x4
+
+#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2 (WRAPPER_BASE_OFFS_IRIS2 + 0x54)
+#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2  (WRAPPER_BASE_OFFS_IRIS2 + 0x58)
+#define WRAPPER_CORE_CLOCK_CONFIG_IRIS2        (WRAPPER_BASE_OFFS_IRIS2 + 0x88)
+
+#define WRAPPER_TZ_BASE_OFFS                   0x000C0000
+#define WRAPPER_TZ_CPU_STATUS                  (WRAPPER_TZ_BASE_OFFS + 0x10)
+
+#define CTRL_INIT_IRIS2                        CPU_CS_SCIACMD_IRIS2
+#define CTRL_STATUS_IRIS2                      CPU_CS_SCIACMDARG0_IRIS2
+#define CTRL_ERROR_STATUS__M_IRIS2             CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS2
+#define CTRL_INIT_IDLE_MSG_BMSK_IRIS2          CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_IRIS2
+#define CTRL_STATUS_PC_READY_IRIS2             CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_IRIS2
+
+#define QTBL_INFO_IRIS2                        CPU_CS_SCIACMDARG1_IRIS2
+#define QTBL_ADDR_IRIS2                        CPU_CS_SCIACMDARG2_IRIS2
+#define SFR_ADDR_IRIS2                         CPU_CS_SCIBCMD_IRIS2
+#define UC_REGION_ADDR_IRIS2                   CPU_CS_SCIBARG1_IRIS2
+#define UC_REGION_SIZE_IRIS2                   CPU_CS_SCIBARG2_IRIS2
+#define WRAPPER_CORE_POWER_STATUS              0xB0080
+#define WRAPPER_CORE_POWER_CONTROL             0xB0084
+
+#define VCODEC_SS_IDLE_STATUSN                 (VCODEC_BASE_OFFS_IRIS2 + 0x70)
+
+static int interrupt_init_iris2(struct iris_core *core)
+{
+	u32 mask_val;
+	int ret;
+
+	ret = read_register(core, WRAPPER_INTR_MASK_IRIS2, &mask_val);
+	if (ret)
+		return ret;
+
+	mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS2 |
+			WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS2);
+	ret = write_register(core, WRAPPER_INTR_MASK_IRIS2, mask_val);
+
+	return ret;
+}
+
+static int setup_ucregion_memory_map_iris2(struct iris_core *core)
+{
+	int ret;
+	u32 value;
+
+	value = (u32)core->iface_q_table.device_addr;
+	ret = write_register(core, UC_REGION_ADDR_IRIS2, value);
+	if (ret)
+		return ret;
+
+	value = SHARED_QSIZE;
+	ret = write_register(core, UC_REGION_SIZE_IRIS2, value);
+	if (ret)
+		return ret;
+
+	value = (u32)core->iface_q_table.device_addr;
+	ret = write_register(core, QTBL_ADDR_IRIS2, value);
+	if (ret)
+		return ret;
+
+	ret = write_register(core, QTBL_INFO_IRIS2, 0x01);
+	if (ret)
+		return ret;
+
+	value = (u32)((u64)core->iface_q_table.kernel_vaddr);
+	ret = write_register(core, CPU_CS_VCICMDARG0_IRIS2, value);
+	if (ret)
+		return ret;
+
+	value = (u32)((u64)core->iface_q_table.kernel_vaddr >> 32);
+	ret = write_register(core, CPU_CS_VCICMDARG1_IRIS2, value);
+	if (ret)
+		return ret;
+
+	if (core->sfr.device_addr) {
+		value = (u32)core->sfr.device_addr + VIDEO_ARCH_LX;
+		ret = write_register(core, SFR_ADDR_IRIS2, value);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static int switch_vcodec_gdsc_mode(struct iris_core *core, bool sw_mode)
+{
+	void __iomem *base_addr;
+	u32 val = 0;
+	int ret;
+
+	base_addr = core->reg_base;
+
+	if (sw_mode) {
+		writel_relaxed(0, base_addr + WRAPPER_CORE_POWER_CONTROL);
+		ret = readl_relaxed_poll_timeout(base_addr + WRAPPER_CORE_POWER_STATUS, val,
+						 val & BIT(1), 1, 200);
+		if (ret)
+			return ret;
+	} else {
+		writel_relaxed(1, base_addr + WRAPPER_CORE_POWER_CONTROL);
+		ret = readl_relaxed_poll_timeout(base_addr + WRAPPER_CORE_POWER_STATUS, val,
+						 !(val & BIT(1)), 1, 200);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int boot_firmware_iris2(struct iris_core *core)
+{
+	u32 ctrl_init = 0, ctrl_status = 0, count = 0, max_tries = 1000;
+	int ret;
+
+	ret = setup_ucregion_memory_map_iris2(core);
+	if (ret)
+		return ret;
+
+	ctrl_init = BIT(0);
+
+	ret = write_register(core, CTRL_INIT_IRIS2, ctrl_init);
+	if (ret)
+		return ret;
+
+	while (!ctrl_status && count < max_tries) {
+		ret = read_register(core, CTRL_STATUS_IRIS2, &ctrl_status);
+		if (ret)
+			return ret;
+
+		if ((ctrl_status & CTRL_ERROR_STATUS__M_IRIS2) == 0x4) {
+			dev_err(core->dev, "invalid setting for UC_REGION\n");
+			break;
+		}
+
+		usleep_range(50, 100);
+		count++;
+	}
+
+	if (count >= max_tries) {
+		dev_err(core->dev, "Error booting up vidc firmware\n");
+		return -ETIME;
+	}
+
+	ret = write_register(core, CPU_CS_H2XSOFTINTEN_IRIS2, 0x1);
+	if (ret)
+		return ret;
+
+	ret = write_register(core, CPU_CS_X2RPMH_IRIS2, 0x0);
+
+	return ret;
+}
+
+static int raise_interrupt_iris2(struct iris_core *core)
+{
+	return write_register(core, CPU_IC_SOFTINT_IRIS2, 1 << CPU_IC_SOFTINT_H2A_SHFT_IRIS2);
+}
+
+static int clear_interrupt_iris2(struct iris_core *core)
+{
+	u32 intr_status = 0, mask = 0;
+	int ret;
+
+	ret = read_register(core, WRAPPER_INTR_STATUS_IRIS2, &intr_status);
+	if (ret)
+		return ret;
+
+	mask = (WRAPPER_INTR_STATUS_A2H_BMSK_IRIS2 |
+		WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2 |
+		CTRL_INIT_IDLE_MSG_BMSK_IRIS2);
+
+	if (intr_status & mask) {
+		core->intr_status |= intr_status;
+		core->reg_count++;
+	} else {
+		core->spur_count++;
+	}
+
+	ret = write_register(core, CPU_CS_A2HSOFTINTCLR_IRIS2, 1);
+
+	return ret;
+}
+
+static int watchdog_iris2(struct iris_core *core, u32 intr_status)
+{
+	if (intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS2) {
+		dev_err(core->dev, "%s: received watchdog interrupt\n", __func__);
+		return -ETIME;
+	}
+
+	return 0;
+}
+
+static bool is_iris2_hw_power_collapsed(struct iris_core *core)
+{
+	u32 value = 0, pwr_status = 0;
+	int ret;
+
+	ret = read_register(core, WRAPPER_CORE_POWER_STATUS, &value);
+	if (ret)
+		return false;
+
+	pwr_status = value & BIT(1);
+
+	return pwr_status ? false : true;
+}
+
+static int power_off_iris2_hardware(struct iris_core *core)
+{
+	u32 value = 0;
+	int ret, i;
+
+	if (is_iris2_hw_power_collapsed(core))
+		goto disable_power;
+
+	dev_err(core->dev, "Video hw is power ON\n");
+
+	ret = read_register(core, WRAPPER_CORE_CLOCK_CONFIG_IRIS2, &value);
+	if (ret)
+		goto disable_power;
+
+	if (value) {
+		ret = write_register(core, WRAPPER_CORE_CLOCK_CONFIG_IRIS2, 0);
+		if (ret)
+			goto disable_power;
+	}
+
+	for (i = 0; i < core->cap[NUM_VPP_PIPE].value; i++) {
+		ret = read_register_with_poll_timeout(core, VCODEC_SS_IDLE_STATUSN + 4 * i,
+						      0x400000, 0x400000, 2000, 20000);
+	}
+
+	ret = write_register(core, CPU_CS_AHB_BRIDGE_SYNC_RESET, 0x3);
+	if (ret)
+		goto disable_power;
+	ret = write_register(core, CPU_CS_AHB_BRIDGE_SYNC_RESET, 0x2);
+	if (ret)
+		goto disable_power;
+	ret = write_register(core, CPU_CS_AHB_BRIDGE_SYNC_RESET, 0x0);
+	if (ret)
+		goto disable_power;
+
+disable_power:
+	ret = disable_power_domains(core, "vcodec0");
+	if (ret) {
+		dev_err(core->dev, "disable power domain vcodec failed\n");
+		ret = 0;
+	}
+
+	disable_unprepare_clock(core, "vcodec_bus");
+	if (ret) {
+		dev_err(core->dev, "disable unprepare vcodec_bus failed\n");
+		ret = 0;
+	}
+
+	disable_unprepare_clock(core, "vcodec_core");
+	if (ret) {
+		dev_err(core->dev, "disable unprepare vcodec_core failed\n");
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static int power_off_iris2_controller(struct iris_core *core)
+{
+	int ret;
+
+	ret = write_register(core, CPU_CS_X2RPMH_IRIS2, 0x3);
+	if (ret)
+		goto disable_power;
+
+	ret = write_register(core, WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x7);
+	if (ret)
+		goto disable_power;
+
+	ret = read_register_with_poll_timeout(core, WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2,
+					      0x7, 0x7, 200, 2000);
+
+	ret = write_register(core, WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS2, 0x0);
+	if (ret)
+		goto disable_power;
+
+	ret = read_register_with_poll_timeout(core, WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS2,
+					      0xffffffff, 0x0, 200, 2000);
+
+disable_power:
+	ret = disable_unprepare_clock(core, "core");
+	if (ret) {
+		dev_err(core->dev, "disable unprepare core_clk failed\n");
+		ret = 0;
+	}
+
+	ret = disable_unprepare_clock(core, "iface");
+	if (ret) {
+		dev_err(core->dev, "disable unprepare iface failed\n");
+		ret = 0;
+	}
+
+	ret = disable_unprepare_clock(core, "bus");
+	if (ret) {
+		dev_err(core->dev, "disable unprepare bus failed\n");
+		ret = 0;
+	}
+
+	reset_ahb2axi_bridge(core);
+
+	ret = disable_power_domains(core, "venus");
+
+	if (ret) {
+		dev_err(core->dev, "%s: disable power domain venus failed\n", __func__);
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static int power_off_iris2(struct iris_core *core)
+{
+	if (!core->power_enabled)
+		return 0;
+
+	opp_set_rate(core, 0);
+	power_off_iris2_hardware(core);
+	power_off_iris2_controller(core);
+	unvote_buses(core);
+
+	if (!call_vpu_op(core, watchdog, core, core->intr_status))
+		disable_irq_nosync(core->irq);
+
+	core->power_enabled = false;
+
+	return 0;
+}
+
+static int power_on_iris2_controller(struct iris_core *core)
+{
+	int ret;
+
+	ret = enable_power_domains(core, "venus");
+	if (ret)
+		return ret;
+
+	ret = reset_ahb2axi_bridge(core);
+	if (ret)
+		goto err_disable_power;
+
+	ret = prepare_enable_clock(core, "bus");
+	if (ret)
+		goto err_disable_power;
+
+	ret = prepare_enable_clock(core, "iface");
+	if (ret)
+		goto err_disable_bus;
+
+	ret = prepare_enable_clock(core, "core");
+	if (ret)
+		goto err_disable_iface;
+
+	return ret;
+
+err_disable_iface:
+	disable_unprepare_clock(core, "iface");
+err_disable_bus:
+	disable_unprepare_clock(core, "bus");
+err_disable_power:
+	disable_power_domains(core, "venus");
+
+	return ret;
+}
+
+static int power_on_iris2_hardware(struct iris_core *core)
+{
+	int ret;
+
+	ret = enable_power_domains(core, "vcodec0");
+	if (ret)
+		return ret;
+
+	ret = switch_vcodec_gdsc_mode(core, true);
+	if (ret)
+		goto err_disable_power;
+
+	ret = prepare_enable_clock(core, "vcodec_bus");
+	if (ret)
+		goto err_gdsc_switch;
+
+	ret = prepare_enable_clock(core, "vcodec_core");
+	if (ret)
+		goto err_disable_bus;
+
+	ret = switch_vcodec_gdsc_mode(core, false);
+	if (ret)
+		goto err_disable_clock;
+
+	return ret;
+
+err_disable_clock:
+	disable_unprepare_clock(core, "vcodec_core");
+err_disable_bus:
+	disable_unprepare_clock(core, "vcodec_bus");
+err_gdsc_switch:
+	switch_vcodec_gdsc_mode(core, false);
+err_disable_power:
+	disable_power_domains(core, "vcodec0");
+
+	return ret;
+}
+
+static int power_on_iris2(struct iris_core *core)
+{
+	u32 freq = 0;
+	int ret;
+
+	if (core->power_enabled)
+		return 0;
+
+	if (!core_in_valid_state(core))
+		return -EINVAL;
+
+	ret = vote_buses(core, INT_MAX);
+	if (ret)
+		goto err;
+
+	ret = power_on_iris2_controller(core);
+	if (ret)
+		goto err_unvote_bus;
+
+	ret = power_on_iris2_hardware(core);
+	if (ret)
+		goto err_power_off_ctrl;
+
+	core->power_enabled = true;
+
+	freq = core->power.clk_freq ? core->power.clk_freq :
+				      (u32)ULONG_MAX;
+
+	opp_set_rate(core, freq);
+
+	set_preset_registers(core);
+
+	interrupt_init_iris2(core);
+	core->intr_status = 0;
+	enable_irq(core->irq);
+
+	return ret;
+
+err_power_off_ctrl:
+	power_off_iris2_controller(core);
+err_unvote_bus:
+	unvote_buses(core);
+err:
+	core->power_enabled = false;
+
+	return ret;
+}
+
+static int prepare_pc_iris2(struct iris_core *core)
+{
+	u32 wfi_status = 0, idle_status = 0, pc_ready = 0;
+	u32 ctrl_status = 0;
+	int ret;
+
+	ret = read_register(core, CTRL_STATUS_IRIS2, &ctrl_status);
+	if (ret)
+		return ret;
+
+	pc_ready = ctrl_status & CTRL_STATUS_PC_READY_IRIS2;
+	idle_status = ctrl_status & BIT(30);
+
+	if (pc_ready)
+		return 0;
+
+	ret = read_register(core, WRAPPER_TZ_CPU_STATUS, &wfi_status);
+	if (ret)
+		return ret;
+
+	wfi_status &= BIT(0);
+	if (!wfi_status || !idle_status)
+		goto skip_power_off;
+
+	ret = prepare_pc(core);
+	if (ret)
+		goto skip_power_off;
+
+	ret = read_register_with_poll_timeout(core, CTRL_STATUS_IRIS2,
+					      CTRL_STATUS_PC_READY_IRIS2,
+					      CTRL_STATUS_PC_READY_IRIS2, 250, 2500);
+	if (ret)
+		goto skip_power_off;
+
+	ret = read_register_with_poll_timeout(core, WRAPPER_TZ_CPU_STATUS,
+					      BIT(0), 0x1, 250, 2500);
+	if (ret)
+		goto skip_power_off;
+
+	return ret;
+
+skip_power_off:
+	ret = read_register(core, CTRL_STATUS_IRIS2, &ctrl_status);
+	if (ret)
+		return ret;
+
+	ret = read_register(core, WRAPPER_TZ_CPU_STATUS, &wfi_status);
+	if (ret)
+		return ret;
+
+	wfi_status &= BIT(0);
+	dev_err(core->dev, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n",
+		wfi_status, idle_status, pc_ready, ctrl_status);
+
+	return -EAGAIN;
+}
+
+static const struct vpu_ops iris2_ops = {
+	.boot_firmware = boot_firmware_iris2,
+	.raise_interrupt = raise_interrupt_iris2,
+	.clear_interrupt = clear_interrupt_iris2,
+	.watchdog = watchdog_iris2,
+	.power_on = power_on_iris2,
+	.power_off = power_off_iris2,
+	.prepare_pc = prepare_pc_iris2,
+};
+
+static const struct vpu_session_ops iris2_session_ops = {
+	.int_buf_size = iris_int_buf_size_iris2,
+	.calc_freq = iris_calc_freq_iris2,
+	.calc_bw = iris_calc_bw_iris2,
+};
+
+int init_iris2(struct iris_core *core)
+{
+	core->vpu_ops = &iris2_ops;
+	core->session_ops = &iris2_session_ops;
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/vpu_iris2.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/vpu_iris2.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _VPU_IRIS2_H_
+#define _VPU_IRIS2_H_
+
+#include "iris_core.h"
+
+int init_iris2(struct iris_core *core);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/vpu_iris2_buffer.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/vpu_iris2_buffer.c
@@ -0,0 +1,423 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "iris_core.h"
+#include "iris_helpers.h"
+#include "iris_instance.h"
+#include "vpu_iris2_buffer.h"
+
+static u32 dec_bin_size_iris2(struct iris_inst *inst)
+{
+	u32 width, height, num_vpp_pipes;
+	struct iris_core *core;
+	struct v4l2_format *f;
+	u32 size = 0;
+
+	core = inst->core;
+
+	num_vpp_pipes = core->cap[NUM_VPP_PIPE].value;
+
+	f = inst->fmt_src;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	if (inst->codec == H264)
+		size = hfi_buffer_bin_h264d(width, height, DEFAULT_BSE_VPP_DELAY, num_vpp_pipes);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_bin_h265d(width, height, DEFAULT_BSE_VPP_DELAY, num_vpp_pipes);
+	else if (inst->codec == VP9)
+		size = hfi_buffer_bin_vp9d(width, height,
+					   num_vpp_pipes);
+	return size;
+}
+
+static u32 dec_comv_size_iris2(struct iris_inst *inst)
+{
+	u32 width, height, num_comv;
+	struct v4l2_format *f;
+	u32 size = 0;
+
+	f = inst->fmt_src;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	num_comv = inst->buffers.output.min_count;
+
+	if (inst->codec == H264)
+		size = hfi_buffer_comv_h264d(width, height, num_comv);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_comv_h265d(width, height, num_comv);
+
+	inst->cap[NUM_COMV].value = num_comv;
+
+	return size;
+}
+
+static u32 dec_non_comv_size_iris2(struct iris_inst *inst)
+{
+	u32 width, height, num_vpp_pipes;
+	struct iris_core *core;
+	struct v4l2_format *f;
+	u32 size = 0;
+
+	core = inst->core;
+
+	num_vpp_pipes = core->cap[NUM_VPP_PIPE].value;
+
+	f = inst->fmt_src;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	if (inst->codec == H264)
+		size = hfi_buffer_non_comv_h264d(width, height, num_vpp_pipes);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_non_comv_h265d(width, height, num_vpp_pipes);
+
+	return size;
+}
+
+static u32 dec_line_size_iris2(struct iris_inst *inst)
+{
+	u32 width, height, out_min_count, num_vpp_pipes;
+	struct iris_core *core;
+	struct v4l2_format *f;
+	u32 size = 0;
+	bool is_opb;
+
+	core = inst->core;
+	num_vpp_pipes = core->cap[NUM_VPP_PIPE].value;
+
+	is_opb = true;
+
+	f = inst->fmt_src;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+	out_min_count = inst->buffers.output.min_count;
+	if (inst->codec == H264)
+		size = hfi_buffer_line_h264d(width, height, is_opb,
+					     num_vpp_pipes);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_line_h265d(width, height, is_opb,
+					     num_vpp_pipes);
+	else if (inst->codec == VP9)
+		size = hfi_buffer_line_vp9d(width, height, out_min_count,
+					    is_opb, num_vpp_pipes);
+	return size;
+}
+
+static u32 dec_persist_size_iris2(struct iris_inst *inst)
+{
+	u32 size = 0;
+
+	if (inst->codec == H264)
+		size = hfi_buffer_persist_h264d(0);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_persist_h265d(0);
+	else if (inst->codec == VP9)
+		size = hfi_buffer_persist_vp9d();
+
+	return size;
+}
+
+static u32 dec_dpb_size_iris2(struct iris_inst *inst)
+{
+	struct v4l2_format *f;
+	u32 width, height;
+	u32 color_fmt;
+	u32 size = 0;
+
+	f = inst->fmt_dst;
+	color_fmt = f->fmt.pix_mp.pixelformat;
+	if (!is_linear_colorformat(color_fmt))
+		return size;
+
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	if (color_fmt == V4L2_PIX_FMT_NV12 ||
+	    color_fmt == V4L2_PIX_FMT_QC08C) {
+		size =
+		hfi_nv12_ubwc_il_calc_buf_size_v2(width, height,
+						  ALIGN(width, 128),
+						  ALIGN(height, 32),
+						  ALIGN(width, 128),
+						  ALIGN((height + 1) >> 1, 32),
+						  ALIGN(DIV_ROUND_UP(width, 32), 64),
+						  ALIGN(DIV_ROUND_UP(height, 8), 16),
+						  ALIGN(DIV_ROUND_UP((width + 1) >> 1, 16), 64),
+						  ALIGN(DIV_ROUND_UP((height + 1) >> 1, 8), 16));
+	} else if (color_fmt == V4L2_PIX_FMT_QC10C) {
+		size =
+		hfi_yuv420_tp10_ubwc_calc_buf_size(ALIGN(ALIGN(width, 192) * 4 / 3, 256),
+						   ALIGN(height, 16),
+						   ALIGN(ALIGN(width, 192) * 4 / 3, 256),
+						   ALIGN((height + 1) >> 1, 16),
+						   ALIGN(DIV_ROUND_UP(width, 48), 64),
+						   ALIGN(DIV_ROUND_UP(height, 4), 16),
+						   ALIGN(DIV_ROUND_UP((width + 1) >> 1, 24), 64),
+						   ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16));
+	}
+
+	return size;
+}
+
+static u32 enc_bin_size_iris2(struct iris_inst *inst)
+{
+	u32 width, height, num_vpp_pipes, stage, profile;
+	struct iris_core *core;
+	struct v4l2_format *f;
+	u32 size = 0;
+
+	core = inst->core;
+
+	num_vpp_pipes = core->cap[NUM_VPP_PIPE].value;
+	stage = inst->cap[STAGE].value;
+	f = inst->fmt_dst;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+	profile = inst->cap[PROFILE].value;
+
+	if (inst->codec == H264)
+		size = hfi_buffer_bin_h264e(inst->hfi_rc_type, width, height,
+					    stage, num_vpp_pipes);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_bin_h265e(inst->hfi_rc_type, width, height,
+					    stage, num_vpp_pipes);
+
+	return size;
+}
+
+u32 get_recon_buf_count_iris2(struct iris_inst *inst)
+{
+	s32 n_bframe, ltr_count, hp_layers = 0, hb_layers = 0;
+	bool is_hybrid_hp = false;
+	u32 num_buf_recon = 0;
+	u32 hfi_codec = 0;
+
+	n_bframe = inst->cap[B_FRAME].value;
+	ltr_count = inst->cap[LTR_COUNT].value;
+
+	if (inst->hfi_layer_type == HFI_HIER_B) {
+		hb_layers = inst->cap[ENH_LAYER_COUNT].value + 1;
+	} else {
+		hp_layers = inst->cap[ENH_LAYER_COUNT].value + 1;
+		if (inst->hfi_layer_type == HFI_HIER_P_HYBRID_LTR)
+			is_hybrid_hp = true;
+	}
+
+	if (inst->codec == H264)
+		hfi_codec = HFI_CODEC_ENCODE_AVC;
+	else if (inst->codec == HEVC)
+		hfi_codec = HFI_CODEC_ENCODE_HEVC;
+
+	num_buf_recon = hfi_iris2_enc_recon_buf_count(n_bframe, ltr_count,
+						      hp_layers, hb_layers,
+						      is_hybrid_hp, hfi_codec);
+
+	return num_buf_recon;
+}
+
+static u32 enc_comv_size_iris2(struct iris_inst *inst)
+{
+	u32 width, height, num_recon = 0;
+	struct v4l2_format *f;
+	u32 size = 0;
+
+	f = inst->fmt_dst;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	num_recon = get_recon_buf_count_iris2(inst);
+	if (inst->codec == H264)
+		size = hfi_buffer_comv_h264e(width, height, num_recon);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_comv_h265e(width, height, num_recon);
+
+	return size;
+}
+
+static u32 enc_non_comv_size_iris2(struct iris_inst *inst)
+{
+	u32 width, height, num_vpp_pipes;
+	struct iris_core *core;
+	struct v4l2_format *f;
+	u32 size = 0;
+
+	core = inst->core;
+
+	num_vpp_pipes = core->cap[NUM_VPP_PIPE].value;
+	f = inst->fmt_dst;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	if (inst->codec == H264)
+		size = hfi_buffer_non_comv_h264e(width, height, num_vpp_pipes);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_non_comv_h265e(width, height, num_vpp_pipes);
+
+	return size;
+}
+
+static u32 enc_line_size_iris2(struct iris_inst *inst)
+{
+	u32 width, height, pixfmt, num_vpp_pipes;
+	struct iris_core *core;
+	bool is_tenbit = false;
+	struct v4l2_format *f;
+	u32 size = 0;
+
+	core = inst->core;
+	num_vpp_pipes = core->cap[NUM_VPP_PIPE].value;
+	pixfmt = inst->cap[PIX_FMTS].value;
+
+	f = inst->fmt_dst;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+	is_tenbit = (pixfmt == FMT_TP10C);
+
+	if (inst->codec == H264)
+		size = hfi_buffer_line_h264e(width, height, is_tenbit, num_vpp_pipes);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_line_h265e(width, height, is_tenbit, num_vpp_pipes);
+
+	return size;
+}
+
+static u32 enc_dpb_size_iris2(struct iris_inst *inst)
+{
+	u32 width, height, pixfmt;
+	struct v4l2_format *f;
+	bool is_tenbit;
+	u32 size = 0;
+
+	f = inst->fmt_dst;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	pixfmt = inst->cap[PIX_FMTS].value;
+	is_tenbit = (pixfmt == FMT_TP10C);
+
+	if (inst->codec == H264)
+		size = hfi_buffer_dpb_h264e(width, height);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_dpb_h265e(width, height, is_tenbit);
+
+	return size;
+}
+
+static u32 enc_arp_size_iris2(struct iris_inst *inst)
+{
+	u32 size = 0;
+
+	HFI_BUFFER_ARP_ENC(size);
+
+	return size;
+}
+
+static u32 enc_vpss_size_iris2(struct iris_inst *inst)
+{
+	bool ds_enable = false, is_tenbit = false;
+	struct v4l2_format *f;
+	u32 width, height;
+	u32 size = 0;
+
+	ds_enable = is_scaling_enabled(inst);
+
+	f = inst->fmt_dst;
+	if (inst->cap[ROTATION].value == 90 ||
+	    inst->cap[ROTATION].value == 270) {
+		width = f->fmt.pix_mp.height;
+		height = f->fmt.pix_mp.width;
+	} else {
+		width = f->fmt.pix_mp.width;
+		height = f->fmt.pix_mp.height;
+	}
+
+	f = inst->fmt_src;
+	is_tenbit = is_10bit_colorformat(f->fmt.pix_mp.pixelformat);
+
+	size = hfi_buffer_vpss_enc(width, height, ds_enable, 0, is_tenbit);
+
+	return size;
+}
+
+u32 enc_output_buffer_size_iris2(struct iris_inst *inst)
+{
+	u32 hfi_rc_type = HFI_RC_VBR_CFR;
+	enum codec_type codec;
+	int bitrate_mode, frame_rc;
+	bool is_ten_bit = false;
+	struct v4l2_format *f;
+	u32 frame_size;
+
+	f = inst->fmt_dst;
+	codec = v4l2_codec_to_driver(inst, f->fmt.pix_mp.pixelformat);
+	if (codec == HEVC)
+		is_ten_bit = true;
+
+	bitrate_mode = inst->cap[BITRATE_MODE].value;
+	frame_rc = inst->cap[FRAME_RC_ENABLE].value;
+	if (!frame_rc)
+		hfi_rc_type = HFI_RC_OFF;
+	else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)
+		hfi_rc_type = HFI_RC_CQ;
+
+	frame_size = hfi_buffer_bitstream_enc_iris2(f->fmt.pix_mp.width,
+						    f->fmt.pix_mp.height,
+						    hfi_rc_type, is_ten_bit);
+
+	return frame_size;
+}
+
+struct iris_buf_type_handle {
+	enum iris_buffer_type type;
+	u32 (*handle)(struct iris_inst *inst);
+};
+
+int iris_int_buf_size_iris2(struct iris_inst *inst,
+			    enum iris_buffer_type buffer_type)
+{
+	const struct iris_buf_type_handle *buf_type_handle_arr = NULL;
+	u32 size = 0, buf_type_handle_size = 0;
+	int i;
+
+	static const struct iris_buf_type_handle dec_internal_buf_type_handle[] = {
+		{BUF_BIN,             dec_bin_size_iris2          },
+		{BUF_COMV,            dec_comv_size_iris2         },
+		{BUF_NON_COMV,        dec_non_comv_size_iris2     },
+		{BUF_LINE,            dec_line_size_iris2         },
+		{BUF_PERSIST,         dec_persist_size_iris2      },
+		{BUF_DPB,             dec_dpb_size_iris2          },
+	};
+	static const struct iris_buf_type_handle enc_internal_buf_type_handle[] = {
+		{BUF_BIN,             enc_bin_size_iris2          },
+		{BUF_COMV,            enc_comv_size_iris2         },
+		{BUF_NON_COMV,        enc_non_comv_size_iris2     },
+		{BUF_LINE,            enc_line_size_iris2         },
+		{BUF_DPB,             enc_dpb_size_iris2          },
+		{BUF_ARP,             enc_arp_size_iris2          },
+		{BUF_VPSS,            enc_vpss_size_iris2         },
+	};
+
+	if (inst->domain == DECODER) {
+		buf_type_handle_size = ARRAY_SIZE(dec_internal_buf_type_handle);
+		buf_type_handle_arr = dec_internal_buf_type_handle;
+	} else if (inst->domain == ENCODER) {
+		buf_type_handle_size = ARRAY_SIZE(enc_internal_buf_type_handle);
+		buf_type_handle_arr = enc_internal_buf_type_handle;
+	}
+
+	if (!buf_type_handle_arr || !buf_type_handle_size)
+		return size;
+
+	for (i = 0; i < buf_type_handle_size; i++) {
+		if (buf_type_handle_arr[i].type == buffer_type) {
+			size = buf_type_handle_arr[i].handle(inst);
+			break;
+		}
+	}
+
+	return size;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/vpu_iris2_buffer.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/vpu_iris2_buffer.h
@@ -0,0 +1,1494 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _VPU_IRIS2_BUFFER_H_
+#define _VPU_IRIS2_BUFFER_H_
+
+#include <linux/types.h>
+#include <linux/minmax.h>
+#include <linux/align.h>
+
+#include "iris_instance.h"
+
+#define DMA_ALIGNMENT 256
+
+#define BUFFER_ALIGNMENT_4096_BYTES 4096
+#define BUFFER_ALIGNMENT_512_BYTES 512
+#define BUFFER_ALIGNMENT_256_BYTES 256
+#define BUFFER_ALIGNMENT_128_BYTES 128
+#define BUFFER_ALIGNMENT_64_BYTES 64
+#define BUFFER_ALIGNMENT_32_BYTES 32
+#define BUFFER_ALIGNMENT_16_BYTES 16
+
+#define HFI_ALIGNMENT_4096 (4096)
+
+#define HFI_COL_FMT_NV12C_Y_TILE_HEIGHT (8)
+#define HFI_COL_FMT_NV12C_Y_TILE_WIDTH (32)
+#define HFI_COL_FMT_NV12C_UV_TILE_HEIGHT (8)
+#define HFI_COL_FMT_NV12C_UV_TILE_WIDTH (16)
+#define HFI_COL_FMT_TP10C_Y_TILE_HEIGHT (4)
+#define HFI_COL_FMT_TP10C_Y_TILE_WIDTH (48)
+
+#define NUM_HW_PIC_BUF 32
+#define SIZE_HW_PIC(size_per_buf) (NUM_HW_PIC_BUF * (size_per_buf))
+
+#define MAX_TILE_COLUMNS 32
+
+#define LCU_MAX_SIZE_PELS 64
+#define LCU_MIN_SIZE_PELS 16
+
+#define HDR10_HIST_EXTRADATA_SIZE (4 * 1024)
+
+#define BIN_BUFFER_THRESHOLD (1280 * 736)
+
+#define VPP_CMD_MAX_SIZE (BIT(20))
+
+#define H264D_MAX_SLICE 1800
+
+#define SIZE_H264D_BUFTAB_T (256)
+#define SIZE_H264D_HW_PIC_T (BIT(11))
+#define SIZE_H264D_BSE_CMD_PER_BUF (32 * 4)
+#define SIZE_H264D_VPP_CMD_PER_BUF (512)
+
+#define NUM_SLIST_BUF_H264 (256 + 32)
+#define SIZE_SLIST_BUF_H264 (512)
+#define H264_DISPLAY_BUF_SIZE (3328)
+#define H264_NUM_FRM_INFO (66)
+
+#define H265_NUM_TILE_COL 32
+#define H265_NUM_TILE_ROW 128
+#define H265_NUM_TILE (H265_NUM_TILE_ROW * H265_NUM_TILE_COL + 1)
+#define SIZE_H265D_BSE_CMD_PER_BUF (16 * sizeof(u32))
+
+#define NUM_SLIST_BUF_H265 (80 + 20)
+#define SIZE_SLIST_BUF_H265 (BIT(10))
+#define H265_DISPLAY_BUF_SIZE (3072)
+#define H265_NUM_FRM_INFO (48)
+
+#define VP9_NUM_FRAME_INFO_BUF 32
+#define VP9_NUM_PROBABILITY_TABLE_BUF (VP9_NUM_FRAME_INFO_BUF + 4)
+#define VP9_PROB_TABLE_SIZE (3840)
+#define VP9_FRAME_INFO_BUF_SIZE (6144)
+
+#define VP9_UDC_HEADER_BUF_SIZE (3 * 128)
+#define MAX_SUPERFRAME_HEADER_LEN (34)
+#define CCE_TILE_OFFSET_SIZE ALIGN(32 * 4 * 4, BUFFER_ALIGNMENT_32_BYTES)
+
+#define SIZE_SEI_USERDATA (4096)
+#define SIZE_DOLBY_RPU_METADATA (41 * 1024)
+
+#define H264_CABAC_HDR_RATIO_HD_TOT 1
+#define H264_CABAC_RES_RATIO_HD_TOT 3
+
+#define H265D_MAX_SLICE 1200
+#define SIZE_H265D_HW_PIC_T SIZE_H264D_HW_PIC_T
+#define H265_CABAC_HDR_RATIO_HD_TOT 2
+#define H265_CABAC_RES_RATIO_HD_TOT 2
+#define SIZE_H265D_VPP_CMD_PER_BUF (256)
+
+#define VPX_DECODER_FRAME_CONCURENCY_LVL (2)
+#define VPX_DECODER_FRAME_BIN_HDR_BUDGET 1
+#define VPX_DECODER_FRAME_BIN_RES_BUDGET 3
+#define VPX_DECODER_FRAME_BIN_DENOMINATOR 2
+
+#define VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO (3 / 2)
+
+#define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 64
+#define MAX_FE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE 64
+#define MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE 64
+
+#define MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE (128 / 8)
+#define MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE (128 / 8)
+#define MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE (128 / 8)
+
+#define MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE (64 * 2 * 3)
+#define MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE 640
+
+#define HFI_BUFFER_ARP_ENC(size) (size = 204800)
+
+#define HFI_MAX_COL_FRAME 6
+#define HFI_VENUS_WIDTH_ALIGNMENT 128
+#define HFI_VENUS_HEIGHT_ALIGNMENT 32
+#define VENUS_METADATA_STRIDE_MULTIPLE 64
+#define VENUS_METADATA_HEIGHT_MULTIPLE 16
+
+#ifndef SYSTEM_LAL_TILE10
+#define SYSTEM_LAL_TILE10 192
+#endif
+
+#define SIZE_SLICE_CMD_BUFFER (ALIGN(20480, BUFFER_ALIGNMENT_256_BYTES))
+#define SIZE_SPS_PPS_SLICE_HDR (2048 + 4096)
+
+#define SIZE_BSE_SLICE_CMD_BUF ((((8192 << 2) + 7) & (~7)) * 3)
+#define SIZE_LAMBDA_LUT (256 * 11)
+
+#define HFI_WORKMODE_1 1
+#define HFI_WORKMODE_2 2
+
+static inline
+u32 size_h264d_hw_bin_buffer(u32 frame_width, u32 frame_height,
+			     u32 delay, u32 num_vpp_pipes)
+{
+	u32 size_yuv, size_bin_hdr, size_bin_res;
+
+	size_yuv = ((frame_width * frame_height) <= BIN_BUFFER_THRESHOLD) ?
+			((BIN_BUFFER_THRESHOLD * 3) >> 1) :
+			((frame_width * frame_height * 3) >> 1);
+	size_bin_hdr = size_yuv * H264_CABAC_HDR_RATIO_HD_TOT;
+	size_bin_res = size_yuv * H264_CABAC_RES_RATIO_HD_TOT;
+	size_bin_hdr = size_bin_hdr * (((((u32)(delay)) & 31) / 10) + 2) / 2;
+	size_bin_res = size_bin_res * (((((u32)(delay)) & 31) / 10) + 2) / 2;
+	size_bin_hdr = ALIGN(size_bin_hdr / num_vpp_pipes,
+			     DMA_ALIGNMENT) * num_vpp_pipes;
+	size_bin_res = ALIGN(size_bin_res / num_vpp_pipes,
+			     DMA_ALIGNMENT) * num_vpp_pipes;
+
+	return size_bin_hdr + size_bin_res;
+}
+
+static inline
+u32 hfi_buffer_bin_h264d(u32 frame_width, u32 frame_height,
+			 u32 delay, u32 num_vpp_pipes)
+{
+	u32 n_aligned_w, n_aligned_h;
+
+	n_aligned_w =
+		ALIGN(frame_width, BUFFER_ALIGNMENT_16_BYTES);
+	n_aligned_h =
+		ALIGN(frame_height, BUFFER_ALIGNMENT_16_BYTES);
+
+	return size_h264d_hw_bin_buffer(n_aligned_w, n_aligned_h,
+					delay, num_vpp_pipes);
+}
+
+static inline
+u32 size_h265d_hw_bin_buffer(u32 frame_width, u32 frame_height,
+			     u32 delay, u32 num_vpp_pipes)
+{
+	u32 size_yuv, size_bin_hdr, size_bin_res;
+
+	size_yuv = ((frame_width * frame_height) <= BIN_BUFFER_THRESHOLD) ?
+		((BIN_BUFFER_THRESHOLD * 3) >> 1) :
+		((frame_width * frame_height * 3) >> 1);
+	size_bin_hdr = size_yuv * H265_CABAC_HDR_RATIO_HD_TOT;
+	size_bin_res = size_yuv * H265_CABAC_RES_RATIO_HD_TOT;
+	size_bin_hdr = size_bin_hdr *
+		(((((u32)(delay)) & 31) / 10) + 2) / 2;
+	size_bin_res = size_bin_res *
+		(((((u32)(delay)) & 31) / 10) + 2) / 2;
+	size_bin_hdr = ALIGN(size_bin_hdr / num_vpp_pipes, DMA_ALIGNMENT) *
+			num_vpp_pipes;
+	size_bin_res = ALIGN(size_bin_res / num_vpp_pipes, DMA_ALIGNMENT) *
+			num_vpp_pipes;
+
+	return size_bin_hdr + size_bin_res;
+}
+
+static inline
+u32 hfi_buffer_bin_h265d(u32 frame_width, u32 frame_height,
+			 u32 delay, u32 num_vpp_pipes)
+{
+	u32 n_aligned_w, n_aligned_h;
+
+	n_aligned_w = ALIGN(frame_width, BUFFER_ALIGNMENT_16_BYTES);
+	n_aligned_h = ALIGN(frame_height, BUFFER_ALIGNMENT_16_BYTES);
+	return size_h265d_hw_bin_buffer(n_aligned_w, n_aligned_h,
+					delay, num_vpp_pipes);
+}
+
+static inline
+u32 hfi_buffer_bin_vp9d(u32 frame_width, u32 frame_height,
+			u32 num_vpp_pipes)
+{
+	u32 _size_yuv, _size;
+
+	_size_yuv = ALIGN(frame_width, BUFFER_ALIGNMENT_16_BYTES) *
+		ALIGN(frame_height, BUFFER_ALIGNMENT_16_BYTES) * 3 / 2;
+	_size = ALIGN(((max_t(u32, _size_yuv, ((BIN_BUFFER_THRESHOLD * 3) >> 1)) *
+			VPX_DECODER_FRAME_BIN_HDR_BUDGET / VPX_DECODER_FRAME_BIN_DENOMINATOR *
+			VPX_DECODER_FRAME_CONCURENCY_LVL) / num_vpp_pipes),
+		      DMA_ALIGNMENT) +
+		ALIGN(((max_t(u32, _size_yuv, ((BIN_BUFFER_THRESHOLD * 3) >> 1)) *
+			VPX_DECODER_FRAME_BIN_RES_BUDGET / VPX_DECODER_FRAME_BIN_DENOMINATOR *
+			VPX_DECODER_FRAME_CONCURENCY_LVL) / num_vpp_pipes),
+		      DMA_ALIGNMENT);
+
+	return _size * num_vpp_pipes;
+}
+
+static inline
+u32 hfi_buffer_comv_h264d(u32 frame_width, u32 frame_height,
+			  u32 _yuv_bufcount_min)
+{
+	u32 frame_width_in_mbs = ((frame_width + 15) >> 4);
+	u32 frame_height_in_mbs = ((frame_height + 15) >> 4);
+	u32 col_mv_aligned_width = (frame_width_in_mbs << 7);
+	u32 col_zero_aligned_width = (frame_width_in_mbs << 2);
+	u32 col_zero_size = 0, size_colloc = 0;
+
+	col_mv_aligned_width =
+		ALIGN(col_mv_aligned_width, BUFFER_ALIGNMENT_16_BYTES);
+	col_zero_aligned_width =
+		ALIGN(col_zero_aligned_width, BUFFER_ALIGNMENT_16_BYTES);
+	col_zero_size = col_zero_aligned_width *
+			((frame_height_in_mbs + 1) >> 1);
+	col_zero_size =
+		ALIGN(col_zero_size, BUFFER_ALIGNMENT_64_BYTES);
+	col_zero_size <<= 1;
+	col_zero_size =
+		ALIGN(col_zero_size, BUFFER_ALIGNMENT_512_BYTES);
+	size_colloc = col_mv_aligned_width *
+			((frame_height_in_mbs + 1) >> 1);
+	size_colloc =
+		ALIGN(size_colloc, BUFFER_ALIGNMENT_64_BYTES);
+	size_colloc <<= 1;
+	size_colloc =
+		ALIGN(size_colloc, BUFFER_ALIGNMENT_512_BYTES);
+	size_colloc += (col_zero_size + SIZE_H264D_BUFTAB_T * 2);
+
+	return (size_colloc * (_yuv_bufcount_min)) +
+		BUFFER_ALIGNMENT_512_BYTES;
+}
+
+static inline
+u32 hfi_buffer_comv_h265d(u32 frame_width, u32 frame_height,
+			  u32 _yuv_bufcount_min)
+{
+	u32 _size;
+
+	_size = ALIGN(((((frame_width + 15) >> 4) *
+		       ((frame_height + 15) >> 4)) << 8),
+		     BUFFER_ALIGNMENT_512_BYTES);
+	_size *= _yuv_bufcount_min;
+	_size += BUFFER_ALIGNMENT_512_BYTES;
+
+	return _size;
+}
+
+static inline
+u32 size_h264d_bse_cmd_buf(u32 frame_width, u32 frame_height)
+{
+	u32 _height = ALIGN(frame_height,
+			    BUFFER_ALIGNMENT_32_BYTES);
+	return min_t(u32, (((_height + 15) >> 4) * 3 * 4), H264D_MAX_SLICE) *
+		SIZE_H264D_BSE_CMD_PER_BUF;
+}
+
+static inline
+u32 size_h264d_vpp_cmd_buf(u32 frame_width, u32 frame_height)
+{
+	u32 _size, _height;
+
+	_height = ALIGN(frame_height, BUFFER_ALIGNMENT_32_BYTES);
+	_size = min_t(u32, (((_height + 15) >> 4) * 3 * 4), H264D_MAX_SLICE) *
+			SIZE_H264D_VPP_CMD_PER_BUF;
+
+	if (_size > VPP_CMD_MAX_SIZE)
+		_size = VPP_CMD_MAX_SIZE;
+
+	return _size;
+}
+
+static inline
+u32 hfi_buffer_non_comv_h264d(u32 frame_width, u32 frame_height,
+			      u32 num_vpp_pipes)
+{
+	u32 _size_bse, _size_vpp, _size;
+
+	_size_bse = size_h264d_bse_cmd_buf(frame_width, frame_height);
+	_size_vpp = size_h264d_vpp_cmd_buf(frame_width, frame_height);
+	_size = ALIGN(_size_bse, DMA_ALIGNMENT) +
+		ALIGN(_size_vpp, DMA_ALIGNMENT) +
+		ALIGN(SIZE_HW_PIC(SIZE_H264D_HW_PIC_T), DMA_ALIGNMENT);
+
+	return ALIGN(_size, DMA_ALIGNMENT);
+}
+
+static inline
+u32 size_h265d_bse_cmd_buf(u32 frame_width, u32 frame_height)
+{
+	u32 _size;
+
+	_size = ALIGN(((ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) *
+		      (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) *
+		     NUM_HW_PIC_BUF, DMA_ALIGNMENT);
+	_size = min_t(u32, _size, H265D_MAX_SLICE + 1);
+	_size = 2 * _size * SIZE_H265D_BSE_CMD_PER_BUF;
+
+	return _size;
+}
+
+static inline
+u32 size_h265d_vpp_cmd_buf(u32 frame_width, u32 frame_height)
+{
+	u32 _size;
+
+	_size = ALIGN(((ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) *
+		      (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) *
+		     NUM_HW_PIC_BUF, DMA_ALIGNMENT);
+	_size = min_t(u32, _size, H265D_MAX_SLICE + 1);
+	_size = ALIGN(_size, 4);
+	_size = 2 * _size * SIZE_H265D_VPP_CMD_PER_BUF;
+	if (_size > VPP_CMD_MAX_SIZE)
+		_size = VPP_CMD_MAX_SIZE;
+
+	return _size;
+}
+
+static inline
+u32 hfi_buffer_non_comv_h265d(u32 frame_width, u32 frame_height,
+			      u32 num_vpp_pipes)
+{
+	u32 _size_bse, _size_vpp, _size;
+
+	_size_bse = size_h265d_bse_cmd_buf(frame_width, frame_height);
+	_size_vpp = size_h265d_vpp_cmd_buf(frame_width, frame_height);
+	_size = ALIGN(_size_bse, DMA_ALIGNMENT) +
+		ALIGN(_size_vpp, DMA_ALIGNMENT) +
+		ALIGN(NUM_HW_PIC_BUF * 20 * 22 * 4, DMA_ALIGNMENT) +
+		ALIGN(2 * sizeof(u16) *
+		      (ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) *
+		      (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS),
+		      DMA_ALIGNMENT) +
+		ALIGN(SIZE_HW_PIC(SIZE_H265D_HW_PIC_T),
+		      DMA_ALIGNMENT) +
+		HDR10_HIST_EXTRADATA_SIZE;
+
+	return ALIGN(_size, DMA_ALIGNMENT);
+}
+
+static inline u32 size_h264d_lb_fe_top_data(u32 frame_width, u32 frame_height)
+{
+	return MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE * ALIGN(frame_width, 16) * 3;
+}
+
+static inline u32 size_h264d_lb_fe_top_ctrl(u32 frame_width, u32 frame_height)
+{
+	return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * ((frame_width + 15) >> 4);
+}
+
+static inline u32 size_h264d_lb_fe_left_ctrl(u32 frame_width, u32 frame_height)
+{
+	return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * ((frame_height + 15) >> 4);
+}
+
+static inline u32 size_h264d_lb_se_top_ctrl(u32 frame_width, u32 frame_height)
+{
+	return MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * ((frame_width + 15) >> 4);
+}
+
+static inline u32 size_h264d_lb_se_left_ctrl(u32 frame_width, u32 frame_height)
+{
+	return MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * ((frame_height + 15) >> 4);
+}
+
+static inline u32 size_h264d_lb_pe_top_data(u32 frame_width, u32 frame_height)
+{
+	return MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE *  ((frame_width + 15) >> 4);
+}
+
+static inline u32 size_h264d_lb_vsp_top(u32 frame_width, u32 frame_height)
+{
+	return (((frame_width + 15) >> 4) << 7);
+}
+
+static inline u32 size_h264d_lb_recon_dma_metadata_wr(u32 frame_width, u32 frame_height)
+{
+	return ALIGN(frame_height, 16) * 32;
+}
+
+static inline u32 size_h264d_qp(u32 frame_width, u32 frame_height)
+{
+	return ((frame_width + 63) >> 6) * ((frame_height + 63) >> 6) * 128;
+}
+
+static inline
+u32 size_vpss_lb(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
+{
+	u32 vpss_4tap_left_buffer_size = 0, vpss_div2_left_buffer_size = 0;
+	u32 vpss_4tap_top_buffer_size = 0, vpss_div2_top_buffer_size = 0;
+	u32 opb_lb_wr_llb_y_buffer_size, opb_lb_wr_llb_uv_buffer_size;
+	u32 opb_wr_top_line_chroma_buffer_size;
+	u32 opb_wr_top_line_luma_buffer_size;
+	u32 macrotiling_size = 32, size;
+
+	opb_wr_top_line_luma_buffer_size =
+		ALIGN(frame_width, macrotiling_size) /
+		macrotiling_size * 256;
+	opb_wr_top_line_luma_buffer_size =
+		ALIGN(opb_wr_top_line_luma_buffer_size, DMA_ALIGNMENT) +
+		(MAX_TILE_COLUMNS - 1) * 256;
+	opb_wr_top_line_luma_buffer_size =
+		max_t(u32, opb_wr_top_line_luma_buffer_size,
+		      (32 * ALIGN(frame_height, 8)));
+	opb_wr_top_line_chroma_buffer_size =
+		opb_wr_top_line_luma_buffer_size;
+	opb_lb_wr_llb_uv_buffer_size =
+		ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64,
+		      BUFFER_ALIGNMENT_32_BYTES);
+	opb_lb_wr_llb_y_buffer_size =
+		ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64,
+		      BUFFER_ALIGNMENT_32_BYTES);
+	size = num_vpp_pipes * 2 *
+		(vpss_4tap_top_buffer_size + vpss_div2_top_buffer_size) +
+		2 * (vpss_4tap_left_buffer_size + vpss_div2_left_buffer_size) +
+		opb_wr_top_line_luma_buffer_size +
+		opb_wr_top_line_chroma_buffer_size +
+		opb_lb_wr_llb_uv_buffer_size +
+		opb_lb_wr_llb_y_buffer_size;
+
+	return size;
+}
+
+static inline
+u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height,
+			  bool is_opb, u32 num_vpp_pipes)
+{
+	u32 vpss_lb_size = 0;
+	u32 _size;
+
+	_size = ALIGN(size_h264d_lb_fe_top_data(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_fe_top_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_fe_left_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) * num_vpp_pipes +
+		ALIGN(size_h264d_lb_se_top_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_se_left_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) * num_vpp_pipes +
+		ALIGN(size_h264d_lb_pe_top_data(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_vsp_top(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_recon_dma_metadata_wr(frame_width, frame_height),
+		      DMA_ALIGNMENT) * 2 +
+		ALIGN(size_h264d_qp(frame_width, frame_height),
+		      DMA_ALIGNMENT);
+	_size = ALIGN(_size, DMA_ALIGNMENT);
+	if (is_opb)
+		vpss_lb_size = size_vpss_lb(frame_width, frame_height,
+					    num_vpp_pipes);
+
+	_size = ALIGN((_size + vpss_lb_size),
+		      DMA_ALIGNMENT);
+
+	return _size;
+}
+
+static inline
+u32 size_h265d_lb_fe_top_data(u32 frame_width, u32 frame_height)
+{
+	return MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE *
+		(ALIGN(frame_width, 64) + 8) * 2;
+}
+
+static inline
+u32 size_h265d_lb_fe_top_ctrl(u32 frame_width, u32 frame_height)
+{
+	return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE *
+		(ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS);
+}
+
+static inline
+u32 size_h265d_lb_fe_left_ctrl(u32 frame_width, u32 frame_height)
+{
+	return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE *
+		(ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS);
+}
+
+static inline
+u32 size_h265d_lb_se_top_ctrl(u32 frame_width, u32 frame_height)
+{
+	return (LCU_MAX_SIZE_PELS / 8 * (128 / 8)) * ((frame_width + 15) >> 4);
+}
+
+static inline
+u32 size_h265d_lb_se_left_ctrl(u32 frame_width, u32 frame_height)
+{
+	return max_t(u32, ((frame_height + 16 - 1) / 8) *
+		     MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE,
+		     max_t(u32, ((frame_height + 32 - 1) / 8) *
+			   MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE,
+			   ((frame_height + 64 - 1) / 8) *
+			   MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE));
+}
+
+static inline
+u32 size_h265d_lb_pe_top_data(u32 frame_width, u32 frame_height)
+{
+	return MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE *
+		(ALIGN(frame_width, LCU_MIN_SIZE_PELS) / LCU_MIN_SIZE_PELS);
+}
+
+static inline
+u32 size_h265d_lb_vsp_top(u32 frame_width, u32 frame_height)
+{
+	return ((frame_width + 63) >> 6) * 128;
+}
+
+static inline
+u32 size_h265d_lb_vsp_left(u32 frame_width, u32 frame_height)
+{
+	return ((frame_height + 63) >> 6) * 128;
+}
+
+static inline
+u32 size_h265d_lb_recon_dma_metadata_wr(u32 frame_width, u32 frame_height)
+{
+	return size_h264d_lb_recon_dma_metadata_wr(frame_width, frame_height);
+}
+
+static inline
+u32 size_h265d_qp(u32 frame_width, u32 frame_height)
+{
+	return size_h264d_qp(frame_width, frame_height);
+}
+
+static inline
+u32 hfi_buffer_line_h265d(u32 frame_width, u32 frame_height,
+			  bool is_opb, u32 num_vpp_pipes)
+{
+	u32 vpss_lb_size = 0, _size;
+
+	_size = ALIGN(size_h265d_lb_fe_top_data(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h265d_lb_fe_top_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h265d_lb_fe_left_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) * num_vpp_pipes +
+		ALIGN(size_h265d_lb_se_left_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) * num_vpp_pipes +
+		ALIGN(size_h265d_lb_se_top_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h265d_lb_pe_top_data(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h265d_lb_vsp_top(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h265d_lb_vsp_left(frame_width, frame_height),
+		      DMA_ALIGNMENT) * num_vpp_pipes +
+		ALIGN(size_h265d_lb_recon_dma_metadata_wr(frame_width, frame_height),
+		      DMA_ALIGNMENT) * 4 +
+		ALIGN(size_h265d_qp(frame_width, frame_height),
+		      DMA_ALIGNMENT);
+	if (is_opb)
+		vpss_lb_size = size_vpss_lb(frame_width, frame_height, num_vpp_pipes);
+
+	return ALIGN((_size + vpss_lb_size), DMA_ALIGNMENT);
+}
+
+static inline
+u32 size_vpxd_lb_fe_left_ctrl(u32 frame_width, u32 frame_height)
+{
+	return max_t(u32, ((frame_height + 15) >> 4) * MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE,
+		     max_t(u32, ((frame_height + 31) >> 5) * MAX_FE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE,
+			   ((frame_height + 63) >> 6) * MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE));
+}
+
+static inline
+u32 size_vpxd_lb_fe_top_ctrl(u32 frame_width, u32 frame_height)
+{
+	return ((ALIGN(frame_width, 64) + 8) * 10 * 2);
+}
+
+static inline
+u32 size_vpxd_lb_se_top_ctrl(u32 frame_width, u32 frame_height)
+{
+	return ((frame_width + 15) >> 4) * MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE;
+}
+
+static inline
+u32 size_vpxd_lb_se_left_ctrl(u32 frame_width, u32 frame_height)
+{
+	return max_t(u32, ((frame_height + 15) >> 4) * MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE,
+		     max_t(u32, ((frame_height + 31) >> 5) * MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE,
+			   ((frame_height + 63) >> 6) * MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE));
+}
+
+static inline
+u32 size_vpxd_lb_recon_dma_metadata_wr(u32 frame_width, u32 frame_height)
+{
+	return ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64,
+		     BUFFER_ALIGNMENT_32_BYTES);
+}
+
+static inline
+u32 size_mp2d_lb_fe_top_data(u32 frame_width, u32 frame_height)
+{
+	return ((ALIGN(frame_width, 16) + 8) * 10 * 2);
+}
+
+static inline
+u32 size_vp9d_lb_fe_top_data(u32 frame_width, u32 frame_height)
+{
+	return (ALIGN(ALIGN(frame_width, 8), 64) + 8) * 10 * 2;
+}
+
+static inline
+u32 size_vp9d_lb_pe_top_data(u32 frame_width, u32 frame_height)
+{
+	return ((ALIGN(ALIGN(frame_width, 8), 64) >> 6) * 176);
+}
+
+static inline
+u32 size_vp9d_lb_vsp_top(u32 frame_width, u32 frame_height)
+{
+	return (((ALIGN(ALIGN(frame_width, 8), 64) >> 6) * 64 * 8) + 256);
+}
+
+static inline u32 hfi_iris2_vp9d_comv_size(void)
+{
+	return (((8192 + 63) >> 6) * ((4320 + 63) >> 6) * 8 * 8 * 2 * 8);
+}
+
+static inline
+u32 size_vp9d_qp(u32 frame_width, u32 frame_height)
+{
+	return size_h264d_qp(frame_width, frame_height);
+}
+
+static inline
+u32 hfi_iris2_vp9d_lb_size(u32 frame_width, u32 frame_height,
+			   u32 num_vpp_pipes)
+{
+	return ALIGN(size_vpxd_lb_fe_left_ctrl(frame_width, frame_height),
+		     DMA_ALIGNMENT) * num_vpp_pipes +
+		ALIGN(size_vpxd_lb_se_left_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) * num_vpp_pipes +
+		ALIGN(size_vp9d_lb_vsp_top(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_vpxd_lb_fe_top_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		2 * ALIGN(size_vpxd_lb_recon_dma_metadata_wr(frame_width, frame_height),
+			  DMA_ALIGNMENT) +
+		ALIGN(size_vpxd_lb_se_top_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_vp9d_lb_pe_top_data(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_vp9d_lb_fe_top_data(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_vp9d_qp(frame_width, frame_height),
+		      DMA_ALIGNMENT);
+}
+
+static inline
+u32 hfi_buffer_line_vp9d(u32 frame_width, u32 frame_height,
+			 u32 _yuv_bufcount_min, bool is_opb,
+			 u32 num_vpp_pipes)
+{
+	u32 vpss_lb_size = 0;
+	u32 _lb_size = 0;
+
+	_lb_size = hfi_iris2_vp9d_lb_size(frame_width, frame_height,
+					  num_vpp_pipes);
+
+	if (is_opb)
+		vpss_lb_size = size_vpss_lb(frame_width, frame_height,
+					    num_vpp_pipes);
+
+	return _lb_size + vpss_lb_size;
+}
+
+static inline u32 hfi_buffer_persist_h264d(u32 rpu_enabled)
+{
+	return ALIGN(SIZE_SLIST_BUF_H264 * NUM_SLIST_BUF_H264 +
+		    NUM_HW_PIC_BUF * SIZE_SEI_USERDATA,
+		    DMA_ALIGNMENT);
+}
+
+static inline
+u32 hfi_buffer_persist_h265d(u32 rpu_enabled)
+{
+	return ALIGN(SIZE_SLIST_BUF_H265 * NUM_SLIST_BUF_H265 +
+		      H265_NUM_TILE * sizeof(u32) +
+		      NUM_HW_PIC_BUF * SIZE_SEI_USERDATA,
+		     DMA_ALIGNMENT);
+}
+
+static inline u32 hfi_buffer_persist_vp9d(void)
+{
+	return ALIGN(VP9_NUM_PROBABILITY_TABLE_BUF * VP9_PROB_TABLE_SIZE,
+		     DMA_ALIGNMENT) +
+		ALIGN(hfi_iris2_vp9d_comv_size(), DMA_ALIGNMENT) +
+		ALIGN(MAX_SUPERFRAME_HEADER_LEN, DMA_ALIGNMENT) +
+		ALIGN(VP9_UDC_HEADER_BUF_SIZE, DMA_ALIGNMENT) +
+		ALIGN(VP9_NUM_FRAME_INFO_BUF * CCE_TILE_OFFSET_SIZE,
+		      DMA_ALIGNMENT) +
+		HDR10_HIST_EXTRADATA_SIZE;
+}
+
+static inline
+u32 hfi_nv12_ubwc_il_calc_y_buf_size(u32 frame_width, u32 frame_height,
+				     u32 stride_multiple,
+				     u32 min_buf_height_multiple)
+{
+	u32 stride, buf_height;
+
+	stride = ALIGN(frame_width, stride_multiple);
+	buf_height = ALIGN(frame_height, min_buf_height_multiple);
+
+	return ALIGN(stride * buf_height, HFI_ALIGNMENT_4096);
+}
+
+static inline
+u32 hfi_nv12_ubwc_il_calc_uv_buf_size(u32 frame_width, u32 frame_height,
+				      u32 stride_multiple,
+				      u32 min_buf_height_multiple)
+{
+	u32 uv_stride, uv_buf_height;
+
+	uv_stride = ALIGN(frame_width, stride_multiple);
+	uv_buf_height = ALIGN(((frame_height + 1) >> 1),
+			      min_buf_height_multiple);
+
+	return ALIGN(uv_stride * uv_buf_height, HFI_ALIGNMENT_4096);
+}
+
+static inline
+u32 hfi_ubwc_calc_metadata_plane_stride(u32 frame_width,
+					u32 metadata_stride_multiple,
+					u32 tile_width_in_pels)
+{
+	return ALIGN(((frame_width + (tile_width_in_pels - 1)) / tile_width_in_pels),
+		     metadata_stride_multiple);
+}
+
+static inline
+u32 hfi_ubwc_metadata_plane_bufheight(u32 frame_height,
+				      u32 metadata_height_multiple,
+				      u32 tile_height_in_pels)
+{
+	return ALIGN(((frame_height + (tile_height_in_pels - 1)) / tile_height_in_pels),
+		     metadata_height_multiple);
+}
+
+static inline
+u32 hfi_ubwc_uv_metadata_plane_stride(u32 frame_width,
+				      u32 metadata_stride_multiple,
+				      u32 tile_width_in_pels)
+{
+	return ALIGN(((((frame_width + 1) >> 1) + tile_width_in_pels - 1) /
+		      tile_width_in_pels), metadata_stride_multiple);
+}
+
+static inline
+u32 hfi_ubwc_uv_metadata_plane_bufheight(u32 frame_height,
+					 u32 metadata_height_multiple,
+					 u32 tile_height_in_pels)
+{
+	return ALIGN(((((frame_height + 1) >> 1) + tile_height_in_pels - 1) /
+		      tile_height_in_pels), metadata_height_multiple);
+}
+
+static inline
+u32 hfi_ubwc_metadata_plane_buffer_size(u32 _metadata_tride, u32 _metadata_buf_height)
+{
+	return ALIGN(_metadata_tride * _metadata_buf_height, HFI_ALIGNMENT_4096);
+}
+
+static inline
+u32 hfi_nv12_ubwc_il_calc_buf_size_v2(u32 frame_width,
+				      u32 frame_height,
+				      u32 y_stride_multiple,
+				      u32 y_buffer_height_multiple,
+				      u32 uv_stride_multiple,
+				      u32 uv_buffer_height_multiple,
+				      u32 y_metadata_stride_multiple,
+				      u32 y_metadata_buffer_height_multiple,
+				      u32 uv_metadata_stride_multiple,
+				      u32 uv_metadata_buffer_height_multiple)
+{
+	u32 y_buf_size, uv_buf_size, y_meta_size, uv_meta_size;
+	u32 half_height = (frame_height + 1) >> 1;
+	u32 stride, _height;
+
+	y_buf_size =
+		hfi_nv12_ubwc_il_calc_y_buf_size(frame_width, half_height,
+						 y_stride_multiple,
+						 y_buffer_height_multiple);
+	uv_buf_size =
+		hfi_nv12_ubwc_il_calc_uv_buf_size(frame_width, half_height,
+						  uv_stride_multiple,
+						  uv_buffer_height_multiple);
+	stride =
+		hfi_ubwc_calc_metadata_plane_stride(frame_width,
+						    y_metadata_stride_multiple,
+						    HFI_COL_FMT_NV12C_Y_TILE_WIDTH);
+	_height =
+		hfi_ubwc_metadata_plane_bufheight(half_height,
+						  y_metadata_buffer_height_multiple,
+						  HFI_COL_FMT_NV12C_Y_TILE_HEIGHT);
+	y_meta_size = hfi_ubwc_metadata_plane_buffer_size(stride, _height);
+	stride =
+		hfi_ubwc_uv_metadata_plane_stride(frame_width,
+						  uv_metadata_stride_multiple,
+						  HFI_COL_FMT_NV12C_UV_TILE_WIDTH);
+	_height =
+		hfi_ubwc_uv_metadata_plane_bufheight(half_height,
+						     uv_metadata_buffer_height_multiple,
+						     HFI_COL_FMT_NV12C_UV_TILE_HEIGHT);
+	uv_meta_size = hfi_ubwc_metadata_plane_buffer_size(stride, _height);
+
+	return (y_buf_size + uv_buf_size + y_meta_size + uv_meta_size) << 1;
+}
+
+static inline
+u32 hfi_yuv420_tp10_ubwc_calc_y_buf_size(u32 y_stride,
+					 u32 y_buf_height)
+{
+	return ALIGN(y_stride * y_buf_height, HFI_ALIGNMENT_4096);
+}
+
+static inline
+u32 hfi_yuv420_tp10_ubwc_calc_uv_buf_size(u32 uv_stride,
+					  u32 uv_buf_height)
+{
+	return ALIGN(uv_stride * uv_buf_height, HFI_ALIGNMENT_4096);
+}
+
+static inline
+u32 hfi_yuv420_tp10_ubwc_calc_buf_size(u32 y_stride, u32 y_buf_height,
+				       u32 uv_stride, u32 uv_buf_height,
+				       u32 y_md_stride, u32 y_md_height,
+				       u32 uv_md_stride, u32 uv_md_height)
+{
+	u32 y_data_size, uv_data_size, y_md_size, uv_md_size;
+
+	y_data_size = hfi_yuv420_tp10_ubwc_calc_y_buf_size(y_stride, y_buf_height);
+	uv_data_size = hfi_yuv420_tp10_ubwc_calc_uv_buf_size(uv_stride, uv_buf_height);
+	y_md_size = hfi_ubwc_metadata_plane_buffer_size(y_md_stride, y_md_height);
+	uv_md_size = hfi_ubwc_metadata_plane_buffer_size(uv_md_stride, uv_md_height);
+
+	return y_data_size + uv_data_size + y_md_size + uv_md_size;
+}
+
+int iris_int_buf_size_iris2(struct iris_inst *inst,
+			    enum iris_buffer_type buffer_type);
+
+static inline
+u32 hfi_buffer_bitstream_enc_iris2(u32 frame_width, u32 frame_height,
+				   u32 rc_type, bool is_ten_bit)
+{
+	u32 aligned_width, aligned_height, bitstream_size;
+
+	aligned_width = ALIGN(frame_width, 32);
+	aligned_height = ALIGN(frame_height, 32);
+	bitstream_size = aligned_width * aligned_height * 3;
+
+	if (aligned_width * aligned_height > (4096 * 2176))
+		bitstream_size = (bitstream_size >> 3);
+	else if (bitstream_size > (1280 * 720))
+		bitstream_size = (bitstream_size >> 2);
+	else
+		bitstream_size = (bitstream_size << 1);
+
+	if ((rc_type == HFI_RC_CQ || rc_type == HFI_RC_OFF))
+		bitstream_size = (bitstream_size << 1);
+
+	if (is_ten_bit)
+		bitstream_size = (bitstream_size) + (bitstream_size >> 2);
+
+	return ALIGN(bitstream_size, HFI_ALIGNMENT_4096);
+}
+
+static inline
+u32 hfi_iris2_enc_recon_buf_count(s32 n_bframe, s32 ltr_count,
+				  s32 _total_hp_layers,
+				  s32 _total_hb_layers,
+				  bool hybrid_hp,
+				  u32 codec_standard)
+{
+	u32 num_ref = 1;
+
+	if (n_bframe)
+		num_ref = 2;
+
+	if (_total_hp_layers > 1) {
+		if (hybrid_hp)
+			num_ref = (_total_hp_layers + 1) >> 1;
+		else if (codec_standard == HFI_CODEC_ENCODE_HEVC)
+			num_ref = (_total_hp_layers + 1) >> 1;
+		else if (codec_standard == HFI_CODEC_ENCODE_AVC &&
+			 _total_hp_layers < 4)
+			num_ref = (_total_hp_layers - 1);
+		else
+			num_ref = _total_hp_layers;
+	}
+
+	if (ltr_count)
+		num_ref = num_ref + ltr_count;
+
+	if (_total_hb_layers > 1) {
+		if (codec_standard == HFI_CODEC_ENCODE_HEVC)
+			num_ref = (_total_hb_layers);
+		else if (codec_standard == HFI_CODEC_ENCODE_AVC)
+			num_ref = (1 << (_total_hb_layers - 2)) + 1;
+	}
+
+	return num_ref + 1;
+}
+
+static inline
+u32 size_bin_bitstream_enc(u32 rc_type, u32 frame_width, u32 frame_height,
+			   u32 work_mode, u32 lcu_size)
+{
+	u32 size_aligned_width = 0, size_aligned_height = 0;
+	u32 bitstream_size_eval = 0;
+
+	size_aligned_width = ALIGN((frame_width), lcu_size);
+	size_aligned_height = ALIGN((frame_height), lcu_size);
+	if (work_mode == HFI_WORKMODE_2) {
+		if (rc_type == HFI_RC_CQ || rc_type == HFI_RC_OFF) {
+			bitstream_size_eval = (((size_aligned_width) *
+						(size_aligned_height) * 3) >> 1);
+		} else {
+			bitstream_size_eval = ((size_aligned_width) *
+					       (size_aligned_height) * 3);
+			if ((size_aligned_width * size_aligned_height) > (4096 * 2176))
+				bitstream_size_eval >>= 3;
+			else if ((size_aligned_width * size_aligned_height) > (480 * 320))
+				bitstream_size_eval >>= 2;
+
+			if (lcu_size == 32)
+				bitstream_size_eval = (bitstream_size_eval * 5 >> 2);
+		}
+	} else {
+		bitstream_size_eval = size_aligned_width * size_aligned_height * 3;
+	}
+
+	return ALIGN(bitstream_size_eval, BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline
+u32 size_enc_single_pipe(u32 rc_type, u32 bitbin_size, u32 num_vpp_pipes,
+			 u32 frame_width, u32 frame_height, u32 lcu_size)
+{
+	u32 size_single_pipe_eval = 0, sao_bin_buffer_size = 0;
+	u32 size_aligned_width = 0, size_aligned_height = 0;
+	u32 _padded_bin_sz = 0;
+
+	size_aligned_width = ALIGN((frame_width), lcu_size);
+	size_aligned_height = ALIGN((frame_height), lcu_size);
+	if ((size_aligned_width * size_aligned_height) > (3840 * 2160))
+		size_single_pipe_eval = (bitbin_size / num_vpp_pipes);
+	else if (num_vpp_pipes > 2)
+		size_single_pipe_eval = bitbin_size / 2;
+	else
+		size_single_pipe_eval = bitbin_size;
+
+	sao_bin_buffer_size =
+		(64 * ((((frame_width) + BUFFER_ALIGNMENT_32_BYTES) *
+			((frame_height) + BUFFER_ALIGNMENT_32_BYTES)) >> 10)) + 384;
+	_padded_bin_sz = ALIGN(size_single_pipe_eval, BUFFER_ALIGNMENT_256_BYTES);
+	size_single_pipe_eval = sao_bin_buffer_size + _padded_bin_sz;
+	size_single_pipe_eval = ALIGN(size_single_pipe_eval, BUFFER_ALIGNMENT_256_BYTES);
+
+	return size_single_pipe_eval;
+}
+
+static inline
+u32 hfi_buffer_bin_enc(u32 rc_type, u32 frame_width, u32 frame_height, u32 lcu_size,
+		       u32 work_mode, u32 num_vpp_pipes)
+{
+	u32 bitstream_size = 0, total_bitbin_buffers = 0;
+	u32 size_single_pipe = 0, bitbin_size = 0;
+	u32 _size = 0;
+
+	bitstream_size = size_bin_bitstream_enc(rc_type, frame_width,
+						frame_height, work_mode,
+						lcu_size);
+
+	if (work_mode == HFI_WORKMODE_2) {
+		total_bitbin_buffers = 3;
+		bitbin_size = bitstream_size * 17 / 10;
+		bitbin_size = ALIGN(bitbin_size, DMA_ALIGNMENT);
+	} else if ((lcu_size == 16) || (num_vpp_pipes > 1)) {
+		total_bitbin_buffers = 1;
+		bitbin_size = bitstream_size;
+	}
+
+	if (total_bitbin_buffers > 0) {
+		size_single_pipe = size_enc_single_pipe(rc_type, bitbin_size,
+							num_vpp_pipes, frame_width,
+							frame_height, lcu_size);
+		bitbin_size = size_single_pipe * num_vpp_pipes;
+		_size = ALIGN(bitbin_size, BUFFER_ALIGNMENT_256_BYTES) *
+			      total_bitbin_buffers + 512;
+	} else {
+		/* Avoid 512 Bytes allocation in case of 1Pipe HEVC Direct Mode*/
+		_size = 0;
+	}
+
+	return _size;
+}
+
+static inline
+u32 hfi_buffer_bin_h264e(u32 rc_type, u32 frame_width, u32 frame_height,
+			 u32 work_mode, u32 num_vpp_pipes)
+{
+	return hfi_buffer_bin_enc(rc_type, frame_width, frame_height, 16,
+				  work_mode, num_vpp_pipes);
+}
+
+static inline
+u32 hfi_buffer_bin_h265e(u32 rc_type, u32 frame_width, u32 frame_height,
+			 u32 work_mode, u32 num_vpp_pipes)
+{
+	return hfi_buffer_bin_enc(rc_type, frame_width, frame_height, 32,
+				  work_mode, num_vpp_pipes);
+}
+
+static inline
+u32 size_enc_slice_info_buf(u32 num_lcu_in_frame)
+{
+	return ALIGN((256 + (num_lcu_in_frame << 4)), DMA_ALIGNMENT);
+}
+
+static inline
+u32 size_line_buf_ctrl(u32 frame_width_coded)
+{
+	return ALIGN(frame_width_coded, DMA_ALIGNMENT);
+}
+
+static inline
+u32 size_line_buf_ctrl_id2(u32 frame_width_coded)
+{
+	return ALIGN(frame_width_coded, DMA_ALIGNMENT);
+}
+
+static inline
+u32 size_linebuff_data(bool is_ten_bit, u32 frame_width_coded)
+{
+	u32 _size = 0;
+
+	_size = is_ten_bit ?
+		(((((10 * (frame_width_coded) + 1024) + (DMA_ALIGNMENT - 1)) &
+		   (~(DMA_ALIGNMENT - 1))) * 1) +
+		 (((((10 * (frame_width_coded) + 1024) >> 1) + (DMA_ALIGNMENT - 1)) &
+		   (~(DMA_ALIGNMENT - 1))) * 2)) :
+		(((((8 * (frame_width_coded) + 1024) + (DMA_ALIGNMENT - 1)) &
+		   (~(DMA_ALIGNMENT - 1))) * 1) +
+		 (((((8 * (frame_width_coded) + 1024) >> 1) + (DMA_ALIGNMENT - 1)) &
+		   (~(DMA_ALIGNMENT - 1))) * 2));
+
+	return _size;
+}
+
+static inline
+u32 size_left_linebuff_ctrl(u32 standard, u32 frame_height_coded,
+			    u32 num_vpp_pipes_enc)
+{
+	u32 _size = 0;
+
+	_size = standard == HFI_CODEC_ENCODE_HEVC ?
+		(((frame_height_coded) +
+		 (BUFFER_ALIGNMENT_32_BYTES)) / BUFFER_ALIGNMENT_32_BYTES * 4 * 16) :
+		(((frame_height_coded) + 15) / 16 * 5 * 16);
+
+	if ((num_vpp_pipes_enc) > 1) {
+		_size += BUFFER_ALIGNMENT_512_BYTES;
+		_size = ALIGN(_size, BUFFER_ALIGNMENT_512_BYTES) *
+			num_vpp_pipes_enc;
+	}
+
+	return ALIGN(_size, BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline
+u32 size_left_linebuff_recon_pix(bool is_ten_bit, u32 frame_height_coded,
+				 u32 num_vpp_pipes_enc)
+{
+	return (((is_ten_bit + 1) * 2 * (frame_height_coded) + BUFFER_ALIGNMENT_256_BYTES) +
+		(BUFFER_ALIGNMENT_256_BYTES << (num_vpp_pipes_enc - 1)) - 1) &
+		(~((BUFFER_ALIGNMENT_256_BYTES << (num_vpp_pipes_enc - 1)) - 1)) * 1;
+}
+
+static inline
+u32 size_top_linebuff_ctrl_fe(u32 frame_width_coded, u32 standard)
+{
+	u32 _size = 0;
+
+	_size = standard == HFI_CODEC_ENCODE_HEVC ?
+		(64 * ((frame_width_coded) >> 5)) :
+		(BUFFER_ALIGNMENT_256_BYTES + 16 * ((frame_width_coded) >> 4));
+
+	return ALIGN(_size, BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline
+u32 size_left_linebuff_ctrl_fe(u32 frame_height_coded, u32 num_vpp_pipes_enc)
+{
+	return (((BUFFER_ALIGNMENT_256_BYTES + 64 * ((frame_height_coded) >> 4)) +
+		 (BUFFER_ALIGNMENT_256_BYTES << (num_vpp_pipes_enc - 1)) - 1) &
+		 (~((BUFFER_ALIGNMENT_256_BYTES << (num_vpp_pipes_enc - 1)) - 1)) * 1) *
+		num_vpp_pipes_enc;
+}
+
+static inline
+u32 size_left_linebuff_metadata_recon_y(u32 frame_height_coded,
+					bool is_ten_bit,
+					u32 num_vpp_pipes_enc)
+{
+	u32 _size = 0;
+
+	_size = ((DMA_ALIGNMENT + 64 * ((frame_height_coded) /
+		  (8 * (is_ten_bit ? 4 : 8)))));
+	_size = ALIGN(_size, DMA_ALIGNMENT);
+
+	return (_size * num_vpp_pipes_enc);
+}
+
+static inline
+u32 size_left_linebuff_metadata_recon_uv(u32 frame_height_coded,
+					 bool is_ten_bit,
+					 u32 num_vpp_pipes_enc)
+{
+	u32 _size = 0;
+
+	_size = ((DMA_ALIGNMENT + 64 * ((frame_height_coded) /
+		  (4 * (is_ten_bit ? 4 : 8)))));
+	_size = ALIGN(_size, DMA_ALIGNMENT);
+
+	return (_size * num_vpp_pipes_enc);
+}
+
+static inline
+u32 size_linebuff_recon_pix(bool is_ten_bit, u32 frame_width_coded)
+{
+	return ALIGN(((is_ten_bit ? 3 : 2) * (frame_width_coded)),
+		     DMA_ALIGNMENT);
+}
+
+static inline
+u32 size_frame_rc_buf_size(u32 standard, u32 frame_height_coded,
+			   u32 num_vpp_pipes_enc)
+{
+	u32 _size = 0;
+
+	_size = (standard == HFI_CODEC_ENCODE_HEVC) ?
+		(256 + 16 * (14 + ((((frame_height_coded) >> 5) + 7) >> 3))) :
+		(256 + 16 * (14 + ((((frame_height_coded) >> 4) + 7) >> 3)));
+	_size *= 11;
+	if (num_vpp_pipes_enc > 1)
+		_size = ALIGN(_size, BUFFER_ALIGNMENT_256_BYTES) * num_vpp_pipes_enc;
+
+	return ALIGN(_size, BUFFER_ALIGNMENT_512_BYTES) * HFI_MAX_COL_FRAME;
+}
+
+static inline u32 enc_bitcnt_buf_size(u32 num_lcu_in_frame)
+{
+	return ALIGN((256 + (4 * (num_lcu_in_frame))), DMA_ALIGNMENT);
+}
+
+static inline u32 enc_bitmap_buf_size(u32 num_lcu_in_frame)
+{
+	return ALIGN((256 + ((num_lcu_in_frame) >> 3)), DMA_ALIGNMENT);
+}
+
+static inline u32 size_line_buf_sde(u32 frame_width_coded)
+{
+	return ALIGN((256 + (16 * ((frame_width_coded) >> 4))), DMA_ALIGNMENT);
+}
+
+static inline u32 size_override_buf(u32 num_lcumb)
+{
+	return ALIGN(((16 * (((num_lcumb) + 7) >> 3))), DMA_ALIGNMENT) * 2;
+}
+
+static inline u32 size_ir_buf(u32 num_lcu_in_frame)
+{
+	return ALIGN((((((num_lcu_in_frame) << 1) + 7) & (~7)) * 3), DMA_ALIGNMENT);
+}
+
+static inline
+u32 size_vpss_line_buf(u32 num_vpp_pipes_enc, u32 frame_height_coded,
+		       u32 frame_width_coded)
+{
+	return ALIGN(((((((8192) >> 2) << 5) * (num_vpp_pipes_enc)) + 64) +
+		      (((((max_t(u32, (frame_width_coded),
+				 (frame_height_coded)) + 3) >> 2) << 5) + 256) * 16)),
+		     DMA_ALIGNMENT);
+}
+
+static inline
+u32 size_top_line_buf_first_stg_sao(u32 frame_width_coded)
+{
+	return ALIGN((16 * ((frame_width_coded) >> 5)), DMA_ALIGNMENT);
+}
+
+static inline
+u32 hfi_buffer_line_enc(u32 frame_width, u32 frame_height, bool is_ten_bit,
+			u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard)
+{
+	u32 line_buff_data_size = 0, left_line_buff_ctrl_size = 0;
+	u32 frame_width_coded = 0, frame_height_coded = 0;
+	u32 left_line_buff_metadata_recon__uv__size = 0;
+	u32 left_line_buff_metadata_recon__y__size = 0;
+	u32 width_in_lcus = 0, height_in_lcus = 0;
+	u32 left_line_buff_recon_pix_size = 0;
+	u32 top_line_buff_ctrl_fe_size = 0;
+	u32 line_buff_recon_pix_size = 0;
+
+	width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size);
+	height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size);
+	frame_width_coded = width_in_lcus * (lcu_size);
+	frame_height_coded = height_in_lcus * (lcu_size);
+	line_buff_data_size = size_linebuff_data(is_ten_bit, frame_width_coded);
+	left_line_buff_ctrl_size =
+		size_left_linebuff_ctrl(standard, frame_height_coded, num_vpp_pipes_enc);
+	left_line_buff_recon_pix_size =
+		size_left_linebuff_recon_pix(is_ten_bit, frame_height_coded,
+					     num_vpp_pipes_enc);
+	top_line_buff_ctrl_fe_size =
+		size_top_linebuff_ctrl_fe(frame_width_coded, standard);
+	left_line_buff_metadata_recon__y__size =
+		size_left_linebuff_metadata_recon_y(frame_height_coded, is_ten_bit,
+						    num_vpp_pipes_enc);
+	left_line_buff_metadata_recon__uv__size =
+		size_left_linebuff_metadata_recon_uv(frame_height_coded, is_ten_bit,
+						     num_vpp_pipes_enc);
+	line_buff_recon_pix_size = size_linebuff_recon_pix(is_ten_bit, frame_width_coded);
+
+	return size_line_buf_ctrl(frame_width_coded) +
+		size_line_buf_ctrl_id2(frame_width_coded) +
+		line_buff_data_size +
+		left_line_buff_ctrl_size +
+		left_line_buff_recon_pix_size +
+		top_line_buff_ctrl_fe_size +
+		left_line_buff_metadata_recon__y__size +
+		left_line_buff_metadata_recon__uv__size +
+		line_buff_recon_pix_size +
+		size_left_linebuff_ctrl_fe(frame_height_coded,
+					   num_vpp_pipes_enc) +
+		size_line_buf_sde(frame_width_coded) +
+		size_vpss_line_buf(num_vpp_pipes_enc, frame_height_coded,
+				   frame_width_coded) +
+		size_top_line_buf_first_stg_sao(frame_width_coded);
+}
+
+static inline
+u32 hfi_buffer_line_h264e(u32 frame_width, u32 frame_height, bool is_ten_bit,
+			  u32 num_vpp_pipes)
+{
+	return hfi_buffer_line_enc(frame_width, frame_height, 0,
+				   num_vpp_pipes, 16,
+				   HFI_CODEC_ENCODE_AVC);
+}
+
+static inline
+u32 hfi_buffer_line_h265e(u32 frame_width, u32 frame_height, bool is_ten_bit,
+			  u32 num_vpp_pipes)
+{
+	return hfi_buffer_line_enc(frame_width, frame_height,
+				   is_ten_bit, num_vpp_pipes, 32,
+				   HFI_CODEC_ENCODE_HEVC);
+}
+
+static inline
+u32 hfi_buffer_comv_enc(u32 frame_width, u32 frame_height, u32 lcu_size,
+			u32 num_recon, u32 standard)
+{
+	u32 width_in_lcus, height_in_lcus, num_lcu_in_frame;
+	u32 size_colloc_mv = 0, size_colloc_rc = 0;
+	u32 mb_height = ((frame_height) + 15) >> 4;
+	u32 mb_width = ((frame_width) + 15) >> 4;
+
+	width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size);
+	height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size);
+	num_lcu_in_frame = width_in_lcus * height_in_lcus;
+	size_colloc_mv = (standard == HFI_CODEC_ENCODE_HEVC) ?
+		(16 * ((num_lcu_in_frame << 2) + BUFFER_ALIGNMENT_32_BYTES)) :
+		(3 * 16 * (width_in_lcus * height_in_lcus + BUFFER_ALIGNMENT_32_BYTES));
+	size_colloc_mv = ALIGN(size_colloc_mv, BUFFER_ALIGNMENT_256_BYTES) * num_recon;
+	size_colloc_rc = (((mb_width + 7) >> 3) * 16 * 2 * mb_height);
+	size_colloc_rc = ALIGN(size_colloc_rc, BUFFER_ALIGNMENT_256_BYTES) * HFI_MAX_COL_FRAME;
+
+	return size_colloc_mv + size_colloc_rc;
+}
+
+static inline
+u32 hfi_buffer_comv_h264e(u32 frame_width, u32 frame_height, u32 num_recon)
+{
+	return hfi_buffer_comv_enc(frame_width, frame_height, 16,
+				   num_recon, HFI_CODEC_ENCODE_AVC);
+}
+
+static inline
+u32 hfi_buffer_comv_h265e(u32 frame_width, u32 frame_height, u32 num_recon)
+{
+	return hfi_buffer_comv_enc(frame_width, frame_height, 32,
+				   num_recon, HFI_CODEC_ENCODE_HEVC);
+}
+
+static inline
+u32 hfi_buffer_non_comv_enc(u32 frame_width, u32 frame_height,
+			    u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard)
+{
+	u32 frame_width_coded = 0, frame_height_coded = 0;
+	u32 width_in_lcus = 0, height_in_lcus = 0;
+	u32 num_lcu_in_frame = 0, num_lcumb = 0;
+	u32 frame_rc_buf_size = 0;
+
+	width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size);
+	height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size);
+	num_lcu_in_frame = width_in_lcus * height_in_lcus;
+	frame_width_coded = width_in_lcus * (lcu_size);
+	frame_height_coded = height_in_lcus * (lcu_size);
+	num_lcumb = (frame_height_coded / lcu_size) *
+		((frame_width_coded + lcu_size * 8) / lcu_size);
+	frame_rc_buf_size =
+		size_frame_rc_buf_size(standard, frame_height_coded,
+				       num_vpp_pipes_enc);
+	return size_enc_slice_info_buf(num_lcu_in_frame) +
+		   SIZE_SLICE_CMD_BUFFER +
+		   SIZE_SPS_PPS_SLICE_HDR +
+		   frame_rc_buf_size +
+		   enc_bitcnt_buf_size(num_lcu_in_frame) +
+		   enc_bitmap_buf_size(num_lcu_in_frame) +
+		   SIZE_BSE_SLICE_CMD_BUF +
+		   SIZE_LAMBDA_LUT +
+		   size_override_buf(num_lcumb) +
+		   size_ir_buf(num_lcu_in_frame);
+}
+
+static inline
+u32 hfi_buffer_non_comv_h264e(u32 frame_width, u32 frame_height,
+			      u32 num_vpp_pipes_enc)
+{
+	return hfi_buffer_non_comv_enc(frame_width, frame_height,
+				       num_vpp_pipes_enc, 16,
+				       HFI_CODEC_ENCODE_AVC);
+}
+
+static inline
+u32 hfi_buffer_non_comv_h265e(u32 frame_width, u32 frame_height,
+			      u32 num_vpp_pipes_enc)
+{
+	return hfi_buffer_non_comv_enc(frame_width, frame_height,
+				       num_vpp_pipes_enc, 32,
+				       HFI_CODEC_ENCODE_HEVC);
+}
+
+static inline
+u32 size_enc_ref_buffer(u32 frame_width, u32 frame_height)
+{
+	u32 u_buffer_width = 0, u_buffer_height = 0;
+	u32 u_chroma_buffer_height = 0;
+
+	u_buffer_height = ALIGN(frame_height, HFI_VENUS_HEIGHT_ALIGNMENT);
+	u_chroma_buffer_height = frame_height >> 1;
+	u_chroma_buffer_height = ALIGN(u_chroma_buffer_height, HFI_VENUS_HEIGHT_ALIGNMENT);
+	u_buffer_width = ALIGN(frame_width, HFI_VENUS_WIDTH_ALIGNMENT);
+
+	return (u_buffer_height + u_chroma_buffer_height) * u_buffer_width;
+}
+
+static inline
+u32 size_enc_ten_bit_ref_buffer(u32 frame_width, u32 frame_height)
+{
+	u32 ref_buf_height = 0, ref_luma_stride_in_bytes = 0;
+	u32 chroma_size = 0, ref_buf_size = 0;
+	u32 u_ref_stride = 0, luma_size = 0;
+	u32 ref_chrm_height_in_bytes = 0;
+
+	ref_buf_height = (frame_height + (HFI_VENUS_HEIGHT_ALIGNMENT - 1)) &
+			(~(HFI_VENUS_HEIGHT_ALIGNMENT - 1));
+	ref_luma_stride_in_bytes = ((frame_width + SYSTEM_LAL_TILE10 - 1) / SYSTEM_LAL_TILE10) *
+		SYSTEM_LAL_TILE10;
+	u_ref_stride = 4 * (ref_luma_stride_in_bytes / 3);
+	u_ref_stride = (u_ref_stride + (BUFFER_ALIGNMENT_128_BYTES - 1)) &
+		(~(BUFFER_ALIGNMENT_128_BYTES - 1));
+	luma_size = ref_buf_height * u_ref_stride;
+	ref_chrm_height_in_bytes = (((frame_height + 1) >> 1) + (BUFFER_ALIGNMENT_32_BYTES - 1)) &
+		(~(BUFFER_ALIGNMENT_32_BYTES - 1));
+	chroma_size = u_ref_stride * ref_chrm_height_in_bytes;
+	luma_size = (luma_size + (BUFFER_ALIGNMENT_4096_BYTES - 1)) &
+		(~(BUFFER_ALIGNMENT_4096_BYTES - 1));
+	chroma_size = (chroma_size + (BUFFER_ALIGNMENT_4096_BYTES - 1)) &
+		(~(BUFFER_ALIGNMENT_4096_BYTES - 1));
+	ref_buf_size = luma_size + chroma_size;
+
+	return ref_buf_size;
+}
+
+static inline
+u32 hfi_buffer_dpb_enc(u32 frame_width, u32 frame_height, bool is_ten_bit)
+{
+	u32 metadata_stride, metadata_buf_height, meta_size_y, meta_size_c;
+	u32 ten_bit_ref_buf_size = 0, ref_buf_size = 0;
+	u32 _size = 0;
+
+	if (!is_ten_bit) {
+		ref_buf_size = size_enc_ref_buffer(frame_width, frame_height);
+		metadata_stride =
+			hfi_ubwc_calc_metadata_plane_stride(frame_width, 64,
+							    HFI_COL_FMT_NV12C_Y_TILE_WIDTH);
+		metadata_buf_height =
+			hfi_ubwc_metadata_plane_bufheight(frame_height, 16,
+							  HFI_COL_FMT_NV12C_Y_TILE_HEIGHT);
+		meta_size_y =
+			hfi_ubwc_metadata_plane_buffer_size(metadata_stride, metadata_buf_height);
+		meta_size_c =
+			hfi_ubwc_metadata_plane_buffer_size(metadata_stride, metadata_buf_height);
+		_size = ref_buf_size + meta_size_y + meta_size_c;
+	} else {
+		ten_bit_ref_buf_size = size_enc_ten_bit_ref_buffer(frame_width, frame_height);
+		metadata_stride =
+			hfi_ubwc_calc_metadata_plane_stride(frame_width,
+							    VENUS_METADATA_STRIDE_MULTIPLE,
+							    HFI_COL_FMT_TP10C_Y_TILE_WIDTH);
+		metadata_buf_height =
+			hfi_ubwc_metadata_plane_bufheight(frame_height,
+							  VENUS_METADATA_HEIGHT_MULTIPLE,
+							  HFI_COL_FMT_TP10C_Y_TILE_HEIGHT);
+		meta_size_y =
+			hfi_ubwc_metadata_plane_buffer_size(metadata_stride, metadata_buf_height);
+		meta_size_c =
+			hfi_ubwc_metadata_plane_buffer_size(metadata_stride, metadata_buf_height);
+		_size = ten_bit_ref_buf_size + meta_size_y + meta_size_c;
+	}
+
+	return _size;
+}
+
+static inline
+u32 hfi_buffer_dpb_h264e(u32 frame_width, u32 frame_height)
+{
+	return hfi_buffer_dpb_enc(frame_width, frame_height, 0);
+}
+
+static inline
+u32 hfi_buffer_dpb_h265e(u32 frame_width, u32 frame_height, bool is_ten_bit)
+{
+	return hfi_buffer_dpb_enc(frame_width, frame_height, is_ten_bit);
+}
+
+static inline
+u32 hfi_buffer_vpss_enc(u32 dswidth, u32 dsheight, bool ds_enable,
+			u32 blur, bool is_ten_bit)
+{
+	u32 vpss_size = 0;
+
+	if (ds_enable || blur)
+		vpss_size = hfi_buffer_dpb_enc(dswidth, dsheight, is_ten_bit);
+
+	return vpss_size;
+}
+
+static inline
+u32 hfi_iris2_enc_min_input_buf_count(u32 totalhblayers)
+{
+	u32 numinput = 3;
+
+	if (totalhblayers >= 2)
+		numinput = (1 << (totalhblayers - 1)) + 2;
+
+	return numinput;
+}
+
+u32 enc_output_buffer_size_iris3(struct iris_inst *inst);
+u32 get_recon_buf_count_iris2(struct iris_inst *inst);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/vpu_iris2_power.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/vpu_iris2_power.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "iris_core.h"
+#include "iris_instance.h"
+#include "iris_helpers.h"
+#include "platform_common.h"
+#include "vpu_iris2_power.h"
+
+u64 iris_calc_freq_iris2(struct iris_inst *inst, u32 data_size)
+{
+	u32 operating_rate, vsp_factor_num = 1, vsp_factor_den = 1;
+	u64 vsp_cycles = 0, vpp_cycles = 0, fw_cycles = 0;
+	u64 fw_vpp_cycles = 0, bitrate = 0, freq = 0;
+	u32 vpp_cycles_per_mb, mbs_per_second;
+	u32 base_cycles = 0, fps, mbpf;
+	u32 height = 0, width = 0;
+	struct v4l2_format *inp_f;
+
+	inp_f = inst->fmt_src;
+	width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
+	height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
+
+	mbpf = NUM_MBS_PER_FRAME(height, width);
+	fps = inst->max_rate;
+	mbs_per_second = mbpf * fps;
+
+	fw_cycles = fps * inst->cap[MB_CYCLES_FW].value;
+	fw_vpp_cycles = fps * inst->cap[MB_CYCLES_FW_VPP].value;
+
+	if (inst->domain == ENCODER) {
+		vpp_cycles_per_mb =
+			inst->cap[QUALITY_MODE].value == POWER_SAVE_MODE ?
+			inst->cap[MB_CYCLES_LP].value :
+			inst->cap[MB_CYCLES_VPP].value;
+
+		vpp_cycles = mbs_per_second * vpp_cycles_per_mb / inst->cap[PIPE].value;
+
+		if (inst->cap[B_FRAME].value > 1)
+			vpp_cycles += (vpp_cycles / 4) + (vpp_cycles / 8);
+		else if (inst->cap[B_FRAME].value)
+			vpp_cycles += vpp_cycles / 4;
+
+		vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles);
+		if (inst->cap[PIPE].value > 1)
+			vpp_cycles += div_u64(vpp_cycles, 100);
+
+		operating_rate = inst->cap[OPERATING_RATE].value >> 16;
+		if (operating_rate > (inst->cap[FRAME_RATE].value >> 16) &&
+		    (inst->cap[FRAME_RATE].value >> 16)) {
+			vsp_factor_num = operating_rate;
+			vsp_factor_den = inst->cap[FRAME_RATE].value >> 16;
+		}
+		vsp_cycles = div_u64(((u64)inst->cap[BIT_RATE].value * vsp_factor_num),
+				     vsp_factor_den);
+
+		base_cycles = inst->cap[MB_CYCLES_VSP].value;
+		if (inst->cap[ENTROPY_MODE].value ==
+			V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC) {
+			vsp_cycles = div_u64(vsp_cycles * 135, 100);
+		} else {
+			base_cycles = 0;
+			vsp_cycles = div_u64(vsp_cycles, 2);
+		}
+		vsp_cycles = div_u64(vsp_cycles * 21, 20);
+
+		if (inst->cap[STAGE].value == STAGE_1)
+			vsp_cycles = vsp_cycles * 3;
+
+		vsp_cycles += mbs_per_second * base_cycles;
+	} else if (inst->domain == DECODER) {
+		vpp_cycles = mbs_per_second * inst->cap[MB_CYCLES_VPP].value /
+			inst->cap[PIPE].value;
+		vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles);
+
+		if (inst->cap[PIPE].value > 1)
+			vpp_cycles += div_u64(vpp_cycles * 59, 1000);
+
+		base_cycles = inst->has_bframe ?
+			80 : inst->cap[MB_CYCLES_VSP].value;
+
+		bitrate = fps * data_size * 8;
+		vsp_cycles = bitrate;
+
+		if (inst->codec == VP9) {
+			vsp_cycles = div_u64(vsp_cycles * 170, 100);
+		} else if (inst->cap[ENTROPY_MODE].value ==
+				V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC) {
+			vsp_cycles = div_u64(vsp_cycles * 135, 100);
+		} else {
+			base_cycles = 0;
+			vsp_cycles = div_u64(vsp_cycles, 2);
+		}
+		vsp_cycles = div_u64(vsp_cycles * 21, 20);
+
+		if (inst->cap[STAGE].value == STAGE_1)
+			vsp_cycles = vsp_cycles * 3;
+
+		vsp_cycles += mbs_per_second * base_cycles;
+	}
+
+	freq = max3(vpp_cycles, vsp_cycles, fw_cycles);
+
+	return freq;
+}
+
+int iris_calc_bw_iris2(struct iris_inst *inst, struct bus_vote_data *data)
+{
+	const struct bw_info *bw_tbl = NULL;
+	unsigned int num_rows = 0;
+	unsigned int i, mbs, mbps;
+	struct iris_core *core;
+
+	if (!data)
+		return 0;
+
+	core = inst->core;
+
+	mbs = (ALIGN(data->height, 16) / 16) * (ALIGN(data->width, 16) / 16);
+	mbps = mbs * data->fps;
+	if (mbps == 0)
+		return 0;
+
+	if (inst->domain == DECODER) {
+		bw_tbl = core->platform_data->bw_tbl_dec;
+		num_rows = core->platform_data->bw_tbl_dec_size;
+	} else if (inst->domain == ENCODER) {
+		bw_tbl = core->platform_data->bw_tbl_enc;
+		num_rows = core->platform_data->bw_tbl_enc_size;
+	}
+
+	if (!bw_tbl || num_rows == 0)
+		return 0;
+
+	for (i = 0; i < num_rows; i++) {
+		if (i != 0 && mbps > bw_tbl[i].mbs_per_sec)
+			break;
+
+		if (is_10bit_colorformat(data->color_formats[0]))
+			data->bus_bw = bw_tbl[i].bw_ddr_10bit;
+		else
+			data->bus_bw = bw_tbl[i].bw_ddr;
+	}
+
+	dev_dbg(core->dev, "bus_bw %llu\n", data->bus_bw);
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/vpu_iris2_power.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/vpu_iris2_power.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __H_VPU_IRIS2_POWER_H__
+#define __H_VPU_IRIS2_POWER_H__
+
+u64 iris_calc_freq_iris2(struct iris_inst *inst, u32 data_size);
+int iris_calc_bw_iris2(struct iris_inst *inst,
+		       struct bus_vote_data *vote_data);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/vpu_iris3.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/vpu_iris3.c
@@ -0,0 +1,572 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/delay.h>
+
+#include "iris_hfi.h"
+#include "vpu_iris3.h"
+#include "vpu_iris3_buffer.h"
+#include "vpu_iris3_power.h"
+
+#define VIDEO_ARCH_LX 1
+
+#define VCODEC_BASE_OFFS_IRIS3                 0x00000000
+#define AON_MVP_NOC_RESET                      0x0001F000
+#define CPU_BASE_OFFS_IRIS3                    0x000A0000
+#define AON_BASE_OFFS                          0x000E0000
+#define CPU_CS_BASE_OFFS_IRIS3                 (CPU_BASE_OFFS_IRIS3)
+#define CPU_IC_BASE_OFFS_IRIS3                 (CPU_BASE_OFFS_IRIS3)
+
+#define CPU_CS_A2HSOFTINTCLR_IRIS3             (CPU_CS_BASE_OFFS_IRIS3 + 0x1C)
+#define CPU_CS_VCICMDARG0_IRIS3                (CPU_CS_BASE_OFFS_IRIS3 + 0x24)
+#define CPU_CS_VCICMDARG1_IRIS3                (CPU_CS_BASE_OFFS_IRIS3 + 0x28)
+/* HFI_CTRL_INIT */
+#define CPU_CS_SCIACMD_IRIS3                   (CPU_CS_BASE_OFFS_IRIS3 + 0x48)
+/* HFI_CTRL_STATUS */
+#define CPU_CS_SCIACMDARG0_IRIS3               (CPU_CS_BASE_OFFS_IRIS3 + 0x4C)
+/* HFI_QTBL_INFO */
+#define CPU_CS_SCIACMDARG1_IRIS3               (CPU_CS_BASE_OFFS_IRIS3 + 0x50)
+/* HFI_QTBL_ADDR */
+#define CPU_CS_SCIACMDARG2_IRIS3               (CPU_CS_BASE_OFFS_IRIS3 + 0x54)
+/* SFR_ADDR */
+#define CPU_CS_SCIBCMD_IRIS3                   (CPU_CS_BASE_OFFS_IRIS3 + 0x5C)
+#define CPU_CS_SCIBCMDARG0_IRIS3               (CPU_CS_BASE_OFFS_IRIS3 + 0x60)
+/* UC_REGION_ADDR */
+#define CPU_CS_SCIBARG1_IRIS3                  (CPU_CS_BASE_OFFS_IRIS3 + 0x64)
+/* UC_REGION_ADDR */
+#define CPU_CS_SCIBARG2_IRIS3                  (CPU_CS_BASE_OFFS_IRIS3 + 0x68)
+#define CPU_CS_H2XSOFTINTEN_IRIS3              (CPU_CS_BASE_OFFS_IRIS3 + 0x148)
+#define CPU_CS_AHB_BRIDGE_SYNC_RESET           (CPU_CS_BASE_OFFS_IRIS3 + 0x160)
+#define CPU_CS_X2RPMH_IRIS3                    (CPU_CS_BASE_OFFS_IRIS3 + 0x168)
+
+#define CPU_IC_SOFTINT_IRIS3                   (CPU_IC_BASE_OFFS_IRIS3 + 0x150)
+#define CPU_IC_SOFTINT_H2A_SHFT_IRIS3          0x0
+
+#define CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_IRIS3     0x40000000
+#define CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS3	     0xfe
+#define CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_IRIS3               0x100
+
+#define AON_WRAPPER_MVP_NOC_RESET_REQ          (AON_MVP_NOC_RESET + 0x000)
+#define AON_WRAPPER_MVP_NOC_RESET_ACK          (AON_MVP_NOC_RESET + 0x004)
+
+#define WRAPPER_BASE_OFFS_IRIS3                0x000B0000
+#define WRAPPER_INTR_STATUS_IRIS3              (WRAPPER_BASE_OFFS_IRIS3 + 0x0C)
+#define WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS3   0x8
+#define WRAPPER_INTR_STATUS_A2H_BMSK_IRIS3     0x4
+
+#define WRAPPER_INTR_MASK_IRIS3	               (WRAPPER_BASE_OFFS_IRIS3 + 0x10)
+#define WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS3     0x8
+#define WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS3    0x4
+
+#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS3 (WRAPPER_BASE_OFFS_IRIS3 + 0x54)
+#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS3  (WRAPPER_BASE_OFFS_IRIS3 + 0x58)
+#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL       (WRAPPER_BASE_OFFS_IRIS3 + 0x5C)
+#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS	       (WRAPPER_BASE_OFFS_IRIS3 + 0x60)
+#define WRAPPER_CORE_POWER_STATUS              (WRAPPER_BASE_OFFS_IRIS3 + 0x80)
+#define WRAPPER_CORE_CLOCK_CONFIG_IRIS3        (WRAPPER_BASE_OFFS_IRIS3 + 0x88)
+
+#define WRAPPER_TZ_BASE_OFFS                   0x000C0000
+#define WRAPPER_TZ_CPU_STATUS                  (WRAPPER_TZ_BASE_OFFS + 0x10)
+#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG        (WRAPPER_TZ_BASE_OFFS + 0x14)
+#define WRAPPER_TZ_QNS4PDXFIFO_RESET           (WRAPPER_TZ_BASE_OFFS + 0x18)
+
+#define CTRL_INIT_IRIS3                        CPU_CS_SCIACMD_IRIS3
+#define CTRL_STATUS_IRIS3                      CPU_CS_SCIACMDARG0_IRIS3
+#define CTRL_ERROR_STATUS__M_IRIS3             CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK_IRIS3
+#define CTRL_INIT_IDLE_MSG_BMSK_IRIS3          CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK_IRIS3
+#define CTRL_STATUS_PC_READY_IRIS3             CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY_IRIS3
+
+#define QTBL_INFO_IRIS3                        CPU_CS_SCIACMDARG1_IRIS3
+#define QTBL_ADDR_IRIS3                        CPU_CS_SCIACMDARG2_IRIS3
+#define SFR_ADDR_IRIS3                         CPU_CS_SCIBCMD_IRIS3
+#define UC_REGION_ADDR_IRIS3                   CPU_CS_SCIBARG1_IRIS3
+#define UC_REGION_SIZE_IRIS3                   CPU_CS_SCIBARG2_IRIS3
+
+#define AON_WRAPPER_MVP_NOC_LPI_CONTROL        (AON_BASE_OFFS)
+#define AON_WRAPPER_MVP_NOC_LPI_STATUS         (AON_BASE_OFFS + 0x4)
+
+#define VCODEC_SS_IDLE_STATUSN                 (VCODEC_BASE_OFFS_IRIS3 + 0x70)
+
+static int interrupt_init_iris3(struct iris_core *core)
+{
+	u32 mask_val;
+	int ret;
+
+	ret = read_register(core, WRAPPER_INTR_MASK_IRIS3, &mask_val);
+	if (ret)
+		return ret;
+
+	mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BMSK_IRIS3 |
+		      WRAPPER_INTR_MASK_A2HCPU_BMSK_IRIS3);
+	ret = write_register(core, WRAPPER_INTR_MASK_IRIS3, mask_val);
+
+	return ret;
+}
+
+static int setup_ucregion_memory_map_iris3(struct iris_core *core)
+{
+	int ret;
+	u32 value;
+
+	value = (u32)core->iface_q_table.device_addr;
+	ret = write_register(core, UC_REGION_ADDR_IRIS3, value);
+	if (ret)
+		return ret;
+
+	value = SHARED_QSIZE;
+	ret = write_register(core, UC_REGION_SIZE_IRIS3, value);
+	if (ret)
+		return ret;
+
+	value = (u32)core->iface_q_table.device_addr;
+	ret = write_register(core, QTBL_ADDR_IRIS3, value);
+	if (ret)
+		return ret;
+
+	ret = write_register(core, QTBL_INFO_IRIS3, 0x01);
+	if (ret)
+		return ret;
+
+	value = (u32)((u64)core->iface_q_table.kernel_vaddr);
+	ret = write_register(core, CPU_CS_VCICMDARG0_IRIS3, value);
+	if (ret)
+		return ret;
+
+	value = (u32)((u64)core->iface_q_table.kernel_vaddr >> 32);
+	ret = write_register(core, CPU_CS_VCICMDARG1_IRIS3, value);
+	if (ret)
+		return ret;
+
+	if (core->sfr.device_addr) {
+		value = (u32)core->sfr.device_addr + VIDEO_ARCH_LX;
+		ret = write_register(core, SFR_ADDR_IRIS3, value);
+		if (ret)
+			return ret;
+	}
+
+	return ret;
+}
+
+static int boot_firmware_iris3(struct iris_core *core)
+{
+	u32 ctrl_init = 0, ctrl_status = 0, count = 0, max_tries = 1000;
+	int ret;
+
+	ret = setup_ucregion_memory_map_iris3(core);
+	if (ret)
+		return ret;
+
+	ctrl_init = BIT(0);
+
+	ret = write_register(core, CTRL_INIT_IRIS3, ctrl_init);
+	if (ret)
+		return ret;
+
+	while (!ctrl_status && count < max_tries) {
+		ret = read_register(core, CTRL_STATUS_IRIS3, &ctrl_status);
+		if (ret)
+			return ret;
+
+		if ((ctrl_status & CTRL_ERROR_STATUS__M_IRIS3) == 0x4) {
+			dev_err(core->dev, "invalid setting for UC_REGION\n");
+			break;
+		}
+
+		usleep_range(50, 100);
+		count++;
+	}
+
+	if (count >= max_tries) {
+		dev_err(core->dev, "Error booting up vidc firmware\n");
+		return -ETIME;
+	}
+
+	ret = write_register(core, CPU_CS_H2XSOFTINTEN_IRIS3, 0x1);
+	if (ret)
+		return ret;
+
+	ret = write_register(core, CPU_CS_X2RPMH_IRIS3, 0x0);
+
+	return ret;
+}
+
+static int raise_interrupt_iris3(struct iris_core *core)
+{
+	return write_register(core, CPU_IC_SOFTINT_IRIS3, 1 << CPU_IC_SOFTINT_H2A_SHFT_IRIS3);
+}
+
+static int clear_interrupt_iris3(struct iris_core *core)
+{
+	u32 intr_status = 0, mask = 0;
+	int ret;
+
+	ret = read_register(core, WRAPPER_INTR_STATUS_IRIS3, &intr_status);
+	if (ret)
+		return ret;
+
+	mask = (WRAPPER_INTR_STATUS_A2H_BMSK_IRIS3 |
+		WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS3 |
+		CTRL_INIT_IDLE_MSG_BMSK_IRIS3);
+
+	if (intr_status & mask) {
+		core->intr_status |= intr_status;
+		core->reg_count++;
+	} else {
+		core->spur_count++;
+	}
+
+	ret = write_register(core, CPU_CS_A2HSOFTINTCLR_IRIS3, 1);
+
+	return ret;
+}
+
+static int watchdog_iris3(struct iris_core *core, u32 intr_status)
+{
+	if (intr_status & WRAPPER_INTR_STATUS_A2HWD_BMSK_IRIS3) {
+		dev_err(core->dev, "%s: received watchdog interrupt\n", __func__);
+		return -ETIME;
+	}
+
+	return 0;
+}
+
+static bool is_iris3_hw_power_collapsed(struct iris_core *core)
+{
+	u32 value = 0, pwr_status = 0;
+	int ret;
+
+	ret = read_register(core, WRAPPER_CORE_POWER_STATUS, &value);
+	if (ret)
+		return false;
+
+	pwr_status = value & BIT(1);
+
+	return pwr_status ? false : true;
+}
+
+static int power_off_iris3_hardware(struct iris_core *core)
+{
+	u32 value = 0;
+	int ret, i;
+
+	if (is_iris3_hw_power_collapsed(core))
+		goto disable_power;
+
+	dev_err(core->dev, "Video hw is power ON\n");
+
+	ret = read_register(core, WRAPPER_CORE_CLOCK_CONFIG_IRIS3, &value);
+	if (ret)
+		goto disable_power;
+
+	if (value) {
+		ret = write_register(core, WRAPPER_CORE_CLOCK_CONFIG_IRIS3, 0);
+		if (ret)
+			goto disable_power;
+	}
+
+	for (i = 0; i < core->cap[NUM_VPP_PIPE].value; i++) {
+		ret = read_register_with_poll_timeout(core, VCODEC_SS_IDLE_STATUSN + 4 * i,
+						      0x400000, 0x400000, 2000, 20000);
+	}
+
+	ret = write_register(core, AON_WRAPPER_MVP_NOC_RESET_REQ, 0x3);
+	if (ret)
+		goto disable_power;
+
+	ret = read_register_with_poll_timeout(core, AON_WRAPPER_MVP_NOC_RESET_ACK,
+					      0x3, 0x3, 200, 2000);
+	ret = write_register(core, AON_WRAPPER_MVP_NOC_RESET_REQ, 0x0);
+	if (ret)
+		goto disable_power;
+
+	ret = read_register_with_poll_timeout(core, AON_WRAPPER_MVP_NOC_RESET_ACK,
+					      0x3, 0x0, 200, 2000);
+
+	ret = write_register(core, CPU_CS_AHB_BRIDGE_SYNC_RESET, 0x3);
+	if (ret)
+		goto disable_power;
+	ret = write_register(core, CPU_CS_AHB_BRIDGE_SYNC_RESET, 0x2);
+	if (ret)
+		goto disable_power;
+	ret = write_register(core, CPU_CS_AHB_BRIDGE_SYNC_RESET, 0x0);
+	if (ret)
+		goto disable_power;
+
+disable_power:
+	ret = disable_power_domains(core, "vcodec");
+	if (ret) {
+		dev_err(core->dev, "disable power domain vcodec failed\n");
+		ret = 0;
+	}
+
+	disable_unprepare_clock(core, "vcodec_core");
+	if (ret) {
+		dev_err(core->dev, "disable unprepare vcodec_core failed\n");
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static int power_off_iris3_controller(struct iris_core *core)
+{
+	int ret;
+
+	ret = write_register(core, CPU_CS_X2RPMH_IRIS3, 0x3);
+	if (ret)
+		goto disable_power;
+
+	ret = write_register_masked(core, AON_WRAPPER_MVP_NOC_LPI_CONTROL,
+				    0x1, BIT(0));
+	if (ret)
+		goto disable_power;
+
+	ret = read_register_with_poll_timeout(core, AON_WRAPPER_MVP_NOC_LPI_STATUS,
+					      0x1, 0x1, 200, 2000);
+
+	ret = write_register_masked(core, WRAPPER_IRIS_CPU_NOC_LPI_CONTROL,
+				    0x1, BIT(0));
+	if (ret)
+		goto disable_power;
+
+	ret = read_register_with_poll_timeout(core, WRAPPER_IRIS_CPU_NOC_LPI_STATUS,
+					      0x1, 0x1, 200, 2000);
+
+	ret = write_register(core, WRAPPER_DEBUG_BRIDGE_LPI_CONTROL_IRIS3, 0x0);
+	if (ret)
+		goto disable_power;
+
+	ret = read_register_with_poll_timeout(core, WRAPPER_DEBUG_BRIDGE_LPI_STATUS_IRIS3,
+					      0xffffffff, 0x0, 200, 2000);
+
+	ret = write_register(core, WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG, 0x3);
+	if (ret)
+		goto disable_power;
+
+	ret = write_register(core, WRAPPER_TZ_QNS4PDXFIFO_RESET, 0x1);
+	if (ret)
+		goto disable_power;
+
+	ret = write_register(core, WRAPPER_TZ_QNS4PDXFIFO_RESET, 0x0);
+	if (ret)
+		goto disable_power;
+
+	ret = write_register(core, WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG, 0x0);
+	if (ret)
+		goto disable_power;
+
+disable_power:
+	disable_unprepare_clock(core, "core_clk");
+	if (ret) {
+		dev_err(core->dev, "disable unprepare core_clk failed\n");
+		ret = 0;
+	}
+
+	/* power down process */
+	ret = disable_power_domains(core, "iris-ctl");
+	if (ret) {
+		dev_err(core->dev, "disable power domain iris-ctl failed\n");
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static int power_off_iris3(struct iris_core *core)
+{
+	if (!core->power_enabled)
+		return 0;
+
+	opp_set_rate(core, 0);
+	power_off_iris3_hardware(core);
+	power_off_iris3_controller(core);
+	unvote_buses(core);
+
+	if (!call_vpu_op(core, watchdog, core, core->intr_status))
+		disable_irq_nosync(core->irq);
+
+	core->power_enabled = false;
+
+	return 0;
+}
+
+static int power_on_iris3_controller(struct iris_core *core)
+{
+	int ret;
+
+	ret = enable_power_domains(core, "iris-ctl");
+	if (ret)
+		return ret;
+
+	ret = reset_ahb2axi_bridge(core);
+	if (ret)
+		goto err_disable_power;
+
+	ret = prepare_enable_clock(core, "gcc_video_axi0");
+	if (ret)
+		goto err_disable_power;
+
+	ret = prepare_enable_clock(core, "core_clk");
+	if (ret)
+		goto err_disable_clock;
+
+	return ret;
+
+err_disable_clock:
+	disable_unprepare_clock(core, "gcc_video_axi0");
+err_disable_power:
+	disable_power_domains(core, "iris-ctl");
+
+	return ret;
+}
+
+static int power_on_iris3_hardware(struct iris_core *core)
+{
+	int ret;
+
+	ret = enable_power_domains(core, "vcodec");
+	if (ret)
+		return ret;
+
+	ret = prepare_enable_clock(core, "vcodec_core");
+	if (ret)
+		goto err_disable_power;
+
+	return ret;
+
+err_disable_power:
+	disable_power_domains(core, "vcodec");
+
+	return ret;
+}
+
+static int power_on_iris3(struct iris_core *core)
+{
+	u32 freq = 0;
+	int ret;
+
+	if (core->power_enabled)
+		return 0;
+
+	if (!core_in_valid_state(core))
+		return -EINVAL;
+
+	ret = vote_buses(core, INT_MAX);
+	if (ret)
+		goto err;
+
+	ret = power_on_iris3_controller(core);
+	if (ret)
+		goto err_unvote_bus;
+
+	ret = power_on_iris3_hardware(core);
+	if (ret)
+		goto err_power_off_ctrl;
+
+	core->power_enabled = true;
+
+	freq = core->power.clk_freq ? core->power.clk_freq :
+				      (u32)ULONG_MAX;
+
+	opp_set_rate(core, freq);
+
+	set_preset_registers(core);
+
+	interrupt_init_iris3(core);
+	core->intr_status = 0;
+	enable_irq(core->irq);
+
+	return ret;
+
+err_power_off_ctrl:
+	power_off_iris3_controller(core);
+err_unvote_bus:
+	unvote_buses(core);
+err:
+	core->power_enabled = false;
+
+	return ret;
+}
+
+static int prepare_pc_iris3(struct iris_core *core)
+{
+	u32 wfi_status = 0, idle_status = 0, pc_ready = 0;
+	u32 ctrl_status = 0;
+	int ret;
+
+	ret = read_register(core, CTRL_STATUS_IRIS3, &ctrl_status);
+	if (ret)
+		return ret;
+
+	pc_ready = ctrl_status & CTRL_STATUS_PC_READY_IRIS3;
+	idle_status = ctrl_status & BIT(30);
+
+	if (pc_ready)
+		return 0;
+
+	ret = read_register(core, WRAPPER_TZ_CPU_STATUS, &wfi_status);
+	if (ret)
+		return ret;
+
+	wfi_status &= BIT(0);
+	if (!wfi_status || !idle_status)
+		goto skip_power_off;
+
+	ret = prepare_pc(core);
+	if (ret)
+		goto skip_power_off;
+
+	ret = read_register_with_poll_timeout(core, CTRL_STATUS_IRIS3,
+					      CTRL_STATUS_PC_READY_IRIS3,
+					      CTRL_STATUS_PC_READY_IRIS3, 250, 2500);
+	if (ret)
+		goto skip_power_off;
+
+	ret = read_register_with_poll_timeout(core, WRAPPER_TZ_CPU_STATUS,
+					      BIT(0), 0x1, 250, 2500);
+	if (ret)
+		goto skip_power_off;
+
+	return ret;
+
+skip_power_off:
+	ret = read_register(core, CTRL_STATUS_IRIS3, &ctrl_status);
+	if (ret)
+		return ret;
+
+	ret = read_register(core, WRAPPER_TZ_CPU_STATUS, &wfi_status);
+	if (ret)
+		return ret;
+
+	wfi_status &= BIT(0);
+	dev_err(core->dev, "Skip PC, wfi=%#x, idle=%#x, pcr=%#x, ctrl=%#x)\n",
+		wfi_status, idle_status, pc_ready, ctrl_status);
+
+	return -EAGAIN;
+}
+
+static const struct vpu_ops iris3_ops = {
+	.boot_firmware = boot_firmware_iris3,
+	.raise_interrupt = raise_interrupt_iris3,
+	.clear_interrupt = clear_interrupt_iris3,
+	.watchdog = watchdog_iris3,
+	.power_on = power_on_iris3,
+	.power_off = power_off_iris3,
+	.prepare_pc = prepare_pc_iris3,
+};
+
+static const struct vpu_session_ops iris3_session_ops = {
+	.int_buf_size = iris_int_buf_size_iris3,
+	.calc_freq = iris_calc_freq_iris3,
+	.calc_bw = iris_calc_bw_iris3,
+};
+
+int init_iris3(struct iris_core *core)
+{
+	core->vpu_ops = &iris3_ops;
+	core->session_ops = &iris3_session_ops;
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/vpu_iris3.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/vpu_iris3.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _VPU_IRIS3_H_
+#define _VPU_IRIS3_H_
+
+#include "iris_core.h"
+
+int init_iris3(struct iris_core *core);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/vpu_iris3_buffer.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/vpu_iris3_buffer.c
@@ -0,0 +1,423 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "iris_core.h"
+#include "iris_helpers.h"
+#include "iris_instance.h"
+#include "vpu_iris3_buffer.h"
+
+static u32 dec_bin_size_iris3(struct iris_inst *inst)
+{
+	u32 width, height, num_vpp_pipes;
+	struct iris_core *core;
+	struct v4l2_format *f;
+	u32 size = 0;
+
+	core = inst->core;
+
+	num_vpp_pipes = core->cap[NUM_VPP_PIPE].value;
+
+	f = inst->fmt_src;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	if (inst->codec == H264)
+		size = hfi_buffer_bin_h264d(width, height, num_vpp_pipes);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_bin_h265d(width, height, num_vpp_pipes);
+	else if (inst->codec == VP9)
+		size = hfi_buffer_bin_vp9d(width, height,
+					   num_vpp_pipes);
+	return size;
+}
+
+static u32 dec_comv_size_iris3(struct iris_inst *inst)
+{
+	u32 width, height, num_comv;
+	struct v4l2_format *f;
+	u32 size = 0;
+
+	f = inst->fmt_src;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	num_comv = inst->buffers.output.min_count;
+
+	if (inst->codec == H264)
+		size = hfi_buffer_comv_h264d(width, height, num_comv);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_comv_h265d(width, height, num_comv);
+
+	inst->cap[NUM_COMV].value = num_comv;
+
+	return size;
+}
+
+static u32 dec_non_comv_size_iris3(struct iris_inst *inst)
+{
+	u32 width, height, num_vpp_pipes;
+	struct iris_core *core;
+	struct v4l2_format *f;
+	u32 size = 0;
+
+	core = inst->core;
+
+	num_vpp_pipes = core->cap[NUM_VPP_PIPE].value;
+
+	f = inst->fmt_src;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	if (inst->codec == H264)
+		size = hfi_buffer_non_comv_h264d(width, height, num_vpp_pipes);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_non_comv_h265d(width, height, num_vpp_pipes);
+
+	return size;
+}
+
+static u32 dec_line_size_iris3(struct iris_inst *inst)
+{
+	u32 width, height, out_min_count, num_vpp_pipes;
+	struct iris_core *core;
+	struct v4l2_format *f;
+	u32 size = 0;
+	bool is_opb;
+
+	core = inst->core;
+	num_vpp_pipes = core->cap[NUM_VPP_PIPE].value;
+
+	is_opb = true;
+
+	f = inst->fmt_src;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+	out_min_count = inst->buffers.output.min_count;
+	if (inst->codec == H264)
+		size = hfi_buffer_line_h264d(width, height, is_opb,
+					     num_vpp_pipes);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_line_h265d(width, height, is_opb,
+					     num_vpp_pipes);
+	else if (inst->codec == VP9)
+		size = hfi_buffer_line_vp9d(width, height, out_min_count,
+					    is_opb, num_vpp_pipes);
+	return size;
+}
+
+static u32 dec_persist_size_iris3(struct iris_inst *inst)
+{
+	u32 size = 0;
+
+	if (inst->codec == H264)
+		size = hfi_buffer_persist_h264d(0);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_persist_h265d(0);
+	else if (inst->codec == VP9)
+		size = hfi_buffer_persist_vp9d();
+
+	return size;
+}
+
+static u32 dec_dpb_size_iris3(struct iris_inst *inst)
+{
+	struct v4l2_format *f;
+	u32 width, height;
+	u32 color_fmt;
+	u32 size = 0;
+
+	f = inst->fmt_dst;
+	color_fmt = f->fmt.pix_mp.pixelformat;
+	if (!is_linear_colorformat(color_fmt))
+		return size;
+
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	if (color_fmt == V4L2_PIX_FMT_NV12 ||
+	    color_fmt == V4L2_PIX_FMT_QC08C) {
+		size =
+		hfi_nv12_ubwc_il_calc_buf_size_v2(width, height,
+						  ALIGN(width, 128),
+						  ALIGN(height, 32),
+						  ALIGN(width, 128),
+						  ALIGN((height + 1) >> 1, 32),
+						  ALIGN(DIV_ROUND_UP(width, 32), 64),
+						  ALIGN(DIV_ROUND_UP(height, 8), 16),
+						  ALIGN(DIV_ROUND_UP((width + 1) >> 1, 16), 64),
+						  ALIGN(DIV_ROUND_UP((height + 1) >> 1, 8), 16));
+	} else if (color_fmt == V4L2_PIX_FMT_QC10C) {
+		size =
+		hfi_yuv420_tp10_ubwc_calc_buf_size(ALIGN(ALIGN(width, 192) * 4 / 3, 256),
+						   ALIGN(height, 16),
+						   ALIGN(ALIGN(width, 192) * 4 / 3, 256),
+						   ALIGN((height + 1) >> 1, 16),
+						   ALIGN(DIV_ROUND_UP(width, 48), 64),
+						   ALIGN(DIV_ROUND_UP(height, 4), 16),
+						   ALIGN(DIV_ROUND_UP((width + 1) >> 1, 24), 64),
+						   ALIGN(DIV_ROUND_UP((height + 1) >> 1, 4), 16));
+	}
+
+	return size;
+}
+
+static u32 enc_bin_size_iris3(struct iris_inst *inst)
+{
+	u32 width, height, num_vpp_pipes, stage, profile;
+	struct iris_core *core;
+	struct v4l2_format *f;
+	u32 size = 0;
+
+	core = inst->core;
+
+	num_vpp_pipes = core->cap[NUM_VPP_PIPE].value;
+	stage = inst->cap[STAGE].value;
+	f = inst->fmt_dst;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+	profile = inst->cap[PROFILE].value;
+
+	if (inst->codec == H264)
+		size = hfi_buffer_bin_h264e(inst->hfi_rc_type, width, height,
+					    stage, num_vpp_pipes, profile);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_bin_h265e(inst->hfi_rc_type, width, height,
+					    stage, num_vpp_pipes, profile);
+
+	return size;
+}
+
+u32 get_recon_buf_count(struct iris_inst *inst)
+{
+	s32 n_bframe, ltr_count, hp_layers = 0, hb_layers = 0;
+	bool is_hybrid_hp = false;
+	u32 num_buf_recon = 0;
+	u32 hfi_codec = 0;
+
+	n_bframe = inst->cap[B_FRAME].value;
+	ltr_count = inst->cap[LTR_COUNT].value;
+
+	if (inst->hfi_layer_type == HFI_HIER_B) {
+		hb_layers = inst->cap[ENH_LAYER_COUNT].value + 1;
+	} else {
+		hp_layers = inst->cap[ENH_LAYER_COUNT].value + 1;
+		if (inst->hfi_layer_type == HFI_HIER_P_HYBRID_LTR)
+			is_hybrid_hp = true;
+	}
+
+	if (inst->codec == H264)
+		hfi_codec = HFI_CODEC_ENCODE_AVC;
+	else if (inst->codec == HEVC)
+		hfi_codec = HFI_CODEC_ENCODE_HEVC;
+
+	num_buf_recon = hfi_iris3_enc_recon_buf_count(n_bframe, ltr_count,
+						      hp_layers, hb_layers,
+						      is_hybrid_hp, hfi_codec);
+
+	return num_buf_recon;
+}
+
+static u32 enc_comv_size_iris3(struct iris_inst *inst)
+{
+	u32 width, height, num_recon = 0;
+	struct v4l2_format *f;
+	u32 size = 0;
+
+	f = inst->fmt_dst;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	num_recon = get_recon_buf_count(inst);
+	if (inst->codec == H264)
+		size = hfi_buffer_comv_h264e(width, height, num_recon);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_comv_h265e(width, height, num_recon);
+
+	return size;
+}
+
+static u32 enc_non_comv_size_iris3(struct iris_inst *inst)
+{
+	u32 width, height, num_vpp_pipes;
+	struct iris_core *core;
+	struct v4l2_format *f;
+	u32 size = 0;
+
+	core = inst->core;
+
+	num_vpp_pipes = core->cap[NUM_VPP_PIPE].value;
+	f = inst->fmt_dst;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	if (inst->codec == H264)
+		size = hfi_buffer_non_comv_h264e(width, height, num_vpp_pipes);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_non_comv_h265e(width, height, num_vpp_pipes);
+
+	return size;
+}
+
+static u32 enc_line_size_iris3(struct iris_inst *inst)
+{
+	u32 width, height, pixfmt, num_vpp_pipes;
+	struct iris_core *core;
+	bool is_tenbit = false;
+	struct v4l2_format *f;
+	u32 size = 0;
+
+	core = inst->core;
+	num_vpp_pipes = core->cap[NUM_VPP_PIPE].value;
+	pixfmt = inst->cap[PIX_FMTS].value;
+
+	f = inst->fmt_dst;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+	is_tenbit = (pixfmt == FMT_TP10C);
+
+	if (inst->codec == H264)
+		size = hfi_buffer_line_h264e(width, height, is_tenbit, num_vpp_pipes);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_line_h265e(width, height, is_tenbit, num_vpp_pipes);
+
+	return size;
+}
+
+static u32 enc_dpb_size_iris3(struct iris_inst *inst)
+{
+	u32 width, height, pixfmt;
+	struct v4l2_format *f;
+	bool is_tenbit;
+	u32 size = 0;
+
+	f = inst->fmt_dst;
+	width = f->fmt.pix_mp.width;
+	height = f->fmt.pix_mp.height;
+
+	pixfmt = inst->cap[PIX_FMTS].value;
+	is_tenbit = (pixfmt == FMT_TP10C);
+
+	if (inst->codec == H264)
+		size = hfi_buffer_dpb_h264e(width, height);
+	else if (inst->codec == HEVC)
+		size = hfi_buffer_dpb_h265e(width, height, is_tenbit);
+
+	return size;
+}
+
+static u32 enc_arp_size_iris3(struct iris_inst *inst)
+{
+	u32 size = 0;
+
+	HFI_BUFFER_ARP_ENC(size);
+
+	return size;
+}
+
+static u32 enc_vpss_size_iris3(struct iris_inst *inst)
+{
+	bool ds_enable = false, is_tenbit = false;
+	struct v4l2_format *f;
+	u32 width, height;
+	u32 size = 0;
+
+	ds_enable = is_scaling_enabled(inst);
+
+	f = inst->fmt_dst;
+	if (inst->cap[ROTATION].value == 90 ||
+	    inst->cap[ROTATION].value == 270) {
+		width = f->fmt.pix_mp.height;
+		height = f->fmt.pix_mp.width;
+	} else {
+		width = f->fmt.pix_mp.width;
+		height = f->fmt.pix_mp.height;
+	}
+
+	f = inst->fmt_src;
+	is_tenbit = is_10bit_colorformat(f->fmt.pix_mp.pixelformat);
+
+	size = hfi_buffer_vpss_enc(width, height, ds_enable, 0, is_tenbit);
+
+	return size;
+}
+
+u32 enc_output_buffer_size_iris3(struct iris_inst *inst)
+{
+	u32 hfi_rc_type = HFI_RC_VBR_CFR;
+	enum codec_type codec;
+	int bitrate_mode, frame_rc;
+	bool is_ten_bit = false;
+	struct v4l2_format *f;
+	u32 frame_size;
+
+	f = inst->fmt_dst;
+	codec = v4l2_codec_to_driver(inst, f->fmt.pix_mp.pixelformat);
+	if (codec == HEVC)
+		is_ten_bit = true;
+
+	bitrate_mode = inst->cap[BITRATE_MODE].value;
+	frame_rc = inst->cap[FRAME_RC_ENABLE].value;
+	if (!frame_rc)
+		hfi_rc_type = HFI_RC_OFF;
+	else if (bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CQ)
+		hfi_rc_type = HFI_RC_CQ;
+
+	frame_size = hfi_buffer_bitstream_enc(f->fmt.pix_mp.width,
+					      f->fmt.pix_mp.height,
+					      hfi_rc_type, is_ten_bit);
+
+	return frame_size;
+}
+
+struct iris_buf_type_handle {
+	enum iris_buffer_type type;
+	u32 (*handle)(struct iris_inst *inst);
+};
+
+int iris_int_buf_size_iris3(struct iris_inst *inst,
+			    enum iris_buffer_type buffer_type)
+{
+	const struct iris_buf_type_handle *buf_type_handle_arr = NULL;
+	u32 size = 0, buf_type_handle_size = 0;
+	int i;
+
+	static const struct iris_buf_type_handle dec_internal_buf_type_handle[] = {
+		{BUF_BIN,             dec_bin_size_iris3          },
+		{BUF_COMV,            dec_comv_size_iris3         },
+		{BUF_NON_COMV,        dec_non_comv_size_iris3     },
+		{BUF_LINE,            dec_line_size_iris3         },
+		{BUF_PERSIST,         dec_persist_size_iris3      },
+		{BUF_DPB,             dec_dpb_size_iris3          },
+	};
+	static const struct iris_buf_type_handle enc_internal_buf_type_handle[] = {
+		{BUF_BIN,             enc_bin_size_iris3          },
+		{BUF_COMV,            enc_comv_size_iris3         },
+		{BUF_NON_COMV,        enc_non_comv_size_iris3     },
+		{BUF_LINE,            enc_line_size_iris3         },
+		{BUF_DPB,             enc_dpb_size_iris3          },
+		{BUF_ARP,             enc_arp_size_iris3          },
+		{BUF_VPSS,            enc_vpss_size_iris3         },
+	};
+
+	if (inst->domain == DECODER) {
+		buf_type_handle_size = ARRAY_SIZE(dec_internal_buf_type_handle);
+		buf_type_handle_arr = dec_internal_buf_type_handle;
+	} else if (inst->domain == ENCODER) {
+		buf_type_handle_size = ARRAY_SIZE(enc_internal_buf_type_handle);
+		buf_type_handle_arr = enc_internal_buf_type_handle;
+	}
+
+	if (!buf_type_handle_arr || !buf_type_handle_size)
+		return size;
+
+	for (i = 0; i < buf_type_handle_size; i++) {
+		if (buf_type_handle_arr[i].type == buffer_type) {
+			size = buf_type_handle_arr[i].handle(inst);
+			break;
+		}
+	}
+
+	return size;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/vpu_iris3_buffer.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/vpu_iris3_buffer.h
@@ -0,0 +1,1496 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _VPU_IRIS3_BUFFER_H_
+#define _VPU_IRIS3_BUFFER_H_
+
+#include <linux/types.h>
+#include <linux/minmax.h>
+#include <linux/align.h>
+
+#include "iris_instance.h"
+
+#define DMA_ALIGNMENT 256
+
+#define BUFFER_ALIGNMENT_4096_BYTES 4096
+#define BUFFER_ALIGNMENT_512_BYTES 512
+#define BUFFER_ALIGNMENT_256_BYTES 256
+#define BUFFER_ALIGNMENT_128_BYTES 128
+#define BUFFER_ALIGNMENT_64_BYTES 64
+#define BUFFER_ALIGNMENT_32_BYTES 32
+#define BUFFER_ALIGNMENT_16_BYTES 16
+
+#define HFI_ALIGNMENT_4096 (4096)
+
+#define HFI_COL_FMT_NV12C_Y_TILE_HEIGHT (8)
+#define HFI_COL_FMT_NV12C_Y_TILE_WIDTH (32)
+#define HFI_COL_FMT_NV12C_UV_TILE_HEIGHT (8)
+#define HFI_COL_FMT_NV12C_UV_TILE_WIDTH (16)
+#define HFI_COL_FMT_TP10C_Y_TILE_HEIGHT (4)
+#define HFI_COL_FMT_TP10C_Y_TILE_WIDTH (48)
+
+#define NUM_HW_PIC_BUF 32
+#define SIZE_HW_PIC(size_per_buf) (NUM_HW_PIC_BUF * (size_per_buf))
+
+#define MAX_TILE_COLUMNS 32
+
+#define LCU_MAX_SIZE_PELS 64
+#define LCU_MIN_SIZE_PELS 16
+
+#define HDR10_HIST_EXTRADATA_SIZE (4 * 1024)
+
+#define BIN_BUFFER_THRESHOLD (1280 * 736)
+
+#define VPP_CMD_MAX_SIZE (BIT(20))
+
+#define H264D_MAX_SLICE 1800
+
+#define SIZE_H264D_BUFTAB_T (256)
+#define SIZE_H264D_HW_PIC_T (BIT(11))
+#define SIZE_H264D_BSE_CMD_PER_BUF (32 * 4)
+#define SIZE_H264D_VPP_CMD_PER_BUF (512)
+
+#define NUM_SLIST_BUF_H264 (256 + 32)
+#define SIZE_SLIST_BUF_H264 (512)
+#define H264_DISPLAY_BUF_SIZE (3328)
+#define H264_NUM_FRM_INFO (66)
+
+#define H265_NUM_TILE_COL 32
+#define H265_NUM_TILE_ROW 128
+#define H265_NUM_TILE (H265_NUM_TILE_ROW * H265_NUM_TILE_COL + 1)
+#define SIZE_H265D_BSE_CMD_PER_BUF (16 * sizeof(u32))
+
+#define NUM_SLIST_BUF_H265 (80 + 20)
+#define SIZE_SLIST_BUF_H265 (BIT(10))
+#define H265_DISPLAY_BUF_SIZE (3072)
+#define H265_NUM_FRM_INFO (48)
+
+#define VP9_NUM_FRAME_INFO_BUF 32
+#define VP9_NUM_PROBABILITY_TABLE_BUF (VP9_NUM_FRAME_INFO_BUF + 4)
+#define VP9_PROB_TABLE_SIZE (3840)
+#define VP9_FRAME_INFO_BUF_SIZE (6144)
+
+#define VP9_UDC_HEADER_BUF_SIZE (3 * 128)
+#define MAX_SUPERFRAME_HEADER_LEN (34)
+#define CCE_TILE_OFFSET_SIZE ALIGN(32 * 4 * 4, BUFFER_ALIGNMENT_32_BYTES)
+
+#define SIZE_SEI_USERDATA (4096)
+#define SIZE_DOLBY_RPU_METADATA (41 * 1024)
+
+#define H264_CABAC_HDR_RATIO_HD_TOT 1
+#define H264_CABAC_RES_RATIO_HD_TOT 3
+
+#define H265D_MAX_SLICE 1200
+#define SIZE_H265D_HW_PIC_T SIZE_H264D_HW_PIC_T
+#define H265_CABAC_HDR_RATIO_HD_TOT 2
+#define H265_CABAC_RES_RATIO_HD_TOT 2
+#define SIZE_H265D_VPP_CMD_PER_BUF (256)
+
+#define VPX_DECODER_FRAME_CONCURENCY_LVL (2)
+#define VPX_DECODER_FRAME_BIN_HDR_BUDGET 1
+#define VPX_DECODER_FRAME_BIN_RES_BUDGET 3
+#define VPX_DECODER_FRAME_BIN_DENOMINATOR 2
+
+#define VPX_DECODER_FRAME_BIN_RES_BUDGET_RATIO (3 / 2)
+
+#define MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE 64
+#define MAX_FE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE 64
+#define MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE 64
+
+#define MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE (128 / 8)
+#define MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE (128 / 8)
+#define MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE (128 / 8)
+
+#define MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE (64 * 2 * 3)
+#define MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE 640
+
+#define HFI_BUFFER_ARP_ENC(size) (size = 204800)
+
+#define HFI_MAX_COL_FRAME 6
+#define HFI_VENUS_WIDTH_ALIGNMENT 128
+#define HFI_VENUS_HEIGHT_ALIGNMENT 32
+#define VENUS_METADATA_STRIDE_MULTIPLE 64
+#define VENUS_METADATA_HEIGHT_MULTIPLE 16
+
+#ifndef SYSTEM_LAL_TILE10
+#define SYSTEM_LAL_TILE10 192
+#endif
+
+#define SIZE_SLICE_CMD_BUFFER (ALIGN(20480, BUFFER_ALIGNMENT_256_BYTES))
+#define SIZE_SPS_PPS_SLICE_HDR (2048 + 4096)
+
+#define SIZE_BSE_SLICE_CMD_BUF ((((8192 << 2) + 7) & (~7)) * 3)
+#define SIZE_LAMBDA_LUT (256 * 11)
+
+#define HFI_WORKMODE_1 1
+#define HFI_WORKMODE_2 2
+
+static inline
+u32 size_h264d_hw_bin_buffer(u32 frame_width, u32 frame_height,
+			     u32 num_vpp_pipes)
+{
+	u32 size_yuv, size_bin_hdr, size_bin_res;
+
+	size_yuv = ((frame_width * frame_height) <= BIN_BUFFER_THRESHOLD) ?
+			((BIN_BUFFER_THRESHOLD * 3) >> 1) :
+			((frame_width * frame_height * 3) >> 1);
+	size_bin_hdr = size_yuv * H264_CABAC_HDR_RATIO_HD_TOT;
+	size_bin_res = size_yuv * H264_CABAC_RES_RATIO_HD_TOT;
+	size_bin_hdr = ALIGN(size_bin_hdr / num_vpp_pipes,
+			     DMA_ALIGNMENT) * num_vpp_pipes;
+	size_bin_res = ALIGN(size_bin_res / num_vpp_pipes,
+			     DMA_ALIGNMENT) * num_vpp_pipes;
+
+	return size_bin_hdr + size_bin_res;
+}
+
+static inline
+u32 hfi_buffer_bin_h264d(u32 frame_width, u32 frame_height,
+			 u32 num_vpp_pipes)
+{
+	u32 n_aligned_w, n_aligned_h;
+
+	n_aligned_w =
+		ALIGN(frame_width, BUFFER_ALIGNMENT_16_BYTES);
+	n_aligned_h =
+		ALIGN(frame_height, BUFFER_ALIGNMENT_16_BYTES);
+
+	return size_h264d_hw_bin_buffer(n_aligned_w, n_aligned_h,
+					num_vpp_pipes);
+}
+
+static inline
+u32 size_h265d_hw_bin_buffer(u32 frame_width, u32 frame_height,
+			     u32 num_vpp_pipes)
+{
+	u32 size_yuv, size_bin_hdr, size_bin_res;
+
+	size_yuv = ((frame_width * frame_height) <= BIN_BUFFER_THRESHOLD) ?
+		((BIN_BUFFER_THRESHOLD * 3) >> 1) :
+		((frame_width * frame_height * 3) >> 1);
+	size_bin_hdr = size_yuv * H265_CABAC_HDR_RATIO_HD_TOT;
+	size_bin_res = size_yuv * H265_CABAC_RES_RATIO_HD_TOT;
+	size_bin_hdr = ALIGN(size_bin_hdr / num_vpp_pipes, DMA_ALIGNMENT) *
+			num_vpp_pipes;
+	size_bin_res = ALIGN(size_bin_res / num_vpp_pipes, DMA_ALIGNMENT) *
+			num_vpp_pipes;
+
+	return size_bin_hdr + size_bin_res;
+}
+
+static inline
+u32 hfi_buffer_bin_h265d(u32 frame_width, u32 frame_height,
+			 u32 num_vpp_pipes)
+{
+	u32 n_aligned_w, n_aligned_h;
+
+	n_aligned_w = ALIGN(frame_width, BUFFER_ALIGNMENT_16_BYTES);
+	n_aligned_h = ALIGN(frame_height, BUFFER_ALIGNMENT_16_BYTES);
+	return size_h265d_hw_bin_buffer(n_aligned_w, n_aligned_h,
+					num_vpp_pipes);
+}
+
+static inline
+u32 hfi_buffer_bin_vp9d(u32 frame_width, u32 frame_height,
+			u32 num_vpp_pipes)
+{
+	u32 _size_yuv, _size;
+
+	_size_yuv = ALIGN(frame_width, BUFFER_ALIGNMENT_16_BYTES) *
+		ALIGN(frame_height, BUFFER_ALIGNMENT_16_BYTES) * 3 / 2;
+	_size = ALIGN(((max_t(u32, _size_yuv, ((BIN_BUFFER_THRESHOLD * 3) >> 1)) *
+			VPX_DECODER_FRAME_BIN_HDR_BUDGET / VPX_DECODER_FRAME_BIN_DENOMINATOR *
+			VPX_DECODER_FRAME_CONCURENCY_LVL) / num_vpp_pipes),
+		      DMA_ALIGNMENT) +
+		ALIGN(((max_t(u32, _size_yuv, ((BIN_BUFFER_THRESHOLD * 3) >> 1)) *
+			VPX_DECODER_FRAME_BIN_RES_BUDGET / VPX_DECODER_FRAME_BIN_DENOMINATOR *
+			VPX_DECODER_FRAME_CONCURENCY_LVL) / num_vpp_pipes),
+		      DMA_ALIGNMENT);
+
+	return _size * num_vpp_pipes;
+}
+
+static inline
+u32 hfi_buffer_comv_h264d(u32 frame_width, u32 frame_height,
+			  u32 _comv_bufcount)
+{
+	u32 frame_width_in_mbs = ((frame_width + 15) >> 4);
+	u32 frame_height_in_mbs = ((frame_height + 15) >> 4);
+	u32 col_mv_aligned_width = (frame_width_in_mbs << 7);
+	u32 col_zero_aligned_width = (frame_width_in_mbs << 2);
+	u32 col_zero_size = 0, size_colloc = 0;
+
+	col_mv_aligned_width =
+		ALIGN(col_mv_aligned_width, BUFFER_ALIGNMENT_16_BYTES);
+	col_zero_aligned_width =
+		ALIGN(col_zero_aligned_width, BUFFER_ALIGNMENT_16_BYTES);
+	col_zero_size = col_zero_aligned_width *
+			((frame_height_in_mbs + 1) >> 1);
+	col_zero_size =
+		ALIGN(col_zero_size, BUFFER_ALIGNMENT_64_BYTES);
+	col_zero_size <<= 1;
+	col_zero_size =
+		ALIGN(col_zero_size, BUFFER_ALIGNMENT_512_BYTES);
+	size_colloc = col_mv_aligned_width *
+			((frame_height_in_mbs + 1) >> 1);
+	size_colloc =
+		ALIGN(size_colloc, BUFFER_ALIGNMENT_64_BYTES);
+	size_colloc <<= 1;
+	size_colloc =
+		ALIGN(size_colloc, BUFFER_ALIGNMENT_512_BYTES);
+	size_colloc += (col_zero_size + SIZE_H264D_BUFTAB_T * 2);
+
+	return (size_colloc * (_comv_bufcount)) +
+		BUFFER_ALIGNMENT_512_BYTES;
+}
+
+static inline
+u32 hfi_buffer_comv_h265d(u32 frame_width, u32 frame_height,
+			  u32 _comv_bufcount)
+{
+	u32 _size;
+
+	_size = ALIGN(((((frame_width + 15) >> 4) *
+		       ((frame_height + 15) >> 4)) << 8),
+		     BUFFER_ALIGNMENT_512_BYTES);
+	_size *= _comv_bufcount;
+	_size += BUFFER_ALIGNMENT_512_BYTES;
+
+	return _size;
+}
+
+static inline
+u32 size_h264d_bse_cmd_buf(u32 frame_width, u32 frame_height)
+{
+	u32 _height = ALIGN(frame_height,
+			    BUFFER_ALIGNMENT_32_BYTES);
+	return min_t(u32, (((_height + 15) >> 4) * 48), H264D_MAX_SLICE) *
+		SIZE_H264D_BSE_CMD_PER_BUF;
+}
+
+static inline
+u32 size_h264d_vpp_cmd_buf(u32 frame_width, u32 frame_height)
+{
+	u32 _size, _height;
+
+	_height = ALIGN(frame_height, BUFFER_ALIGNMENT_32_BYTES);
+	_size = min_t(u32, (((_height + 15) >> 4) * 48), H264D_MAX_SLICE) *
+			SIZE_H264D_VPP_CMD_PER_BUF;
+
+	if (_size > VPP_CMD_MAX_SIZE)
+		_size = VPP_CMD_MAX_SIZE;
+
+	return _size;
+}
+
+static inline
+u32 hfi_buffer_non_comv_h264d(u32 frame_width, u32 frame_height,
+			      u32 num_vpp_pipes)
+{
+	u32 _size_bse, _size_vpp, _size;
+
+	_size_bse = size_h264d_bse_cmd_buf(frame_width, frame_height);
+	_size_vpp = size_h264d_vpp_cmd_buf(frame_width, frame_height);
+	_size = ALIGN(_size_bse, DMA_ALIGNMENT) +
+		ALIGN(_size_vpp, DMA_ALIGNMENT) +
+		ALIGN(SIZE_HW_PIC(SIZE_H264D_HW_PIC_T), DMA_ALIGNMENT);
+
+	return ALIGN(_size, DMA_ALIGNMENT);
+}
+
+static inline
+u32 size_h265d_bse_cmd_buf(u32 frame_width, u32 frame_height)
+{
+	u32 _size;
+
+	_size = ALIGN(((ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) *
+		      (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) *
+		     NUM_HW_PIC_BUF, DMA_ALIGNMENT);
+	_size = min_t(u32, _size, H265D_MAX_SLICE + 1);
+	_size = 2 * _size * SIZE_H265D_BSE_CMD_PER_BUF;
+
+	return _size;
+}
+
+static inline
+u32 size_h265d_vpp_cmd_buf(u32 frame_width, u32 frame_height)
+{
+	u32 _size;
+
+	_size = ALIGN(((ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) *
+		      (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS)) *
+		     NUM_HW_PIC_BUF, DMA_ALIGNMENT);
+	_size = min_t(u32, _size, H265D_MAX_SLICE + 1);
+	_size = ALIGN(_size, 4);
+	_size = 2 * _size * SIZE_H265D_VPP_CMD_PER_BUF;
+	if (_size > VPP_CMD_MAX_SIZE)
+		_size = VPP_CMD_MAX_SIZE;
+
+	return _size;
+}
+
+static inline
+u32 hfi_buffer_non_comv_h265d(u32 frame_width, u32 frame_height,
+			      u32 num_vpp_pipes)
+{
+	u32 _size_bse, _size_vpp, _size;
+
+	_size_bse = size_h265d_bse_cmd_buf(frame_width, frame_height);
+	_size_vpp = size_h265d_vpp_cmd_buf(frame_width, frame_height);
+	_size = ALIGN(_size_bse, DMA_ALIGNMENT) +
+		ALIGN(_size_vpp, DMA_ALIGNMENT) +
+		ALIGN(NUM_HW_PIC_BUF * 20 * 22 * 4, DMA_ALIGNMENT) +
+		ALIGN(2 * sizeof(u16) *
+		      (ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS) *
+		      (ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS),
+		      DMA_ALIGNMENT) +
+		ALIGN(SIZE_HW_PIC(SIZE_H265D_HW_PIC_T),
+		      DMA_ALIGNMENT) +
+		HDR10_HIST_EXTRADATA_SIZE;
+
+	return ALIGN(_size, DMA_ALIGNMENT);
+}
+
+static inline u32 size_h264d_lb_fe_top_data(u32 frame_width, u32 frame_height)
+{
+	return MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE * ALIGN(frame_width, 16) * 3;
+}
+
+static inline u32 size_h264d_lb_fe_top_ctrl(u32 frame_width, u32 frame_height)
+{
+	return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * ((frame_width + 15) >> 4);
+}
+
+static inline u32 size_h264d_lb_fe_left_ctrl(u32 frame_width, u32 frame_height)
+{
+	return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * ((frame_height + 15) >> 4);
+}
+
+static inline u32 size_h264d_lb_se_top_ctrl(u32 frame_width, u32 frame_height)
+{
+	return MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * ((frame_width + 15) >> 4);
+}
+
+static inline u32 size_h264d_lb_se_left_ctrl(u32 frame_width, u32 frame_height)
+{
+	return MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE * ((frame_height + 15) >> 4);
+}
+
+static inline u32 size_h264d_lb_pe_top_data(u32 frame_width, u32 frame_height)
+{
+	return MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE *  ((frame_width + 15) >> 4);
+}
+
+static inline u32 size_h264d_lb_vsp_top(u32 frame_width, u32 frame_height)
+{
+	return (((frame_width + 15) >> 4) << 7);
+}
+
+static inline u32 size_h264d_lb_recon_dma_metadata_wr(u32 frame_width, u32 frame_height)
+{
+	return ALIGN(frame_height, 16) * 32;
+}
+
+static inline u32 size_h264d_qp(u32 frame_width, u32 frame_height)
+{
+	return ((frame_width + 63) >> 6) * ((frame_height + 63) >> 6) * 128;
+}
+
+static inline
+u32 size_vpss_lb(u32 frame_width, u32 frame_height, u32 num_vpp_pipes)
+{
+	u32 vpss_4tap_left_buffer_size = 0, vpss_div2_left_buffer_size = 0;
+	u32 vpss_4tap_top_buffer_size = 0, vpss_div2_top_buffer_size = 0;
+	u32 opb_lb_wr_llb_y_buffer_size, opb_lb_wr_llb_uv_buffer_size;
+	u32 opb_wr_top_line_chroma_buffer_size;
+	u32 opb_wr_top_line_luma_buffer_size;
+	u32 macrotiling_size = 32, size;
+
+	opb_wr_top_line_luma_buffer_size =
+		ALIGN(frame_width, macrotiling_size) /
+		macrotiling_size * 256;
+	opb_wr_top_line_luma_buffer_size =
+		ALIGN(opb_wr_top_line_luma_buffer_size, DMA_ALIGNMENT) +
+		(MAX_TILE_COLUMNS - 1) * 256;
+	opb_wr_top_line_luma_buffer_size =
+		max_t(u32, opb_wr_top_line_luma_buffer_size,
+		      (32 * ALIGN(frame_height, 8)));
+	opb_wr_top_line_chroma_buffer_size =
+		opb_wr_top_line_luma_buffer_size;
+	opb_lb_wr_llb_uv_buffer_size =
+		ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64,
+		      BUFFER_ALIGNMENT_32_BYTES);
+	opb_lb_wr_llb_y_buffer_size =
+		ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64,
+		      BUFFER_ALIGNMENT_32_BYTES);
+	size = num_vpp_pipes * 2 *
+		(vpss_4tap_top_buffer_size + vpss_div2_top_buffer_size) +
+		2 * (vpss_4tap_left_buffer_size + vpss_div2_left_buffer_size) +
+		opb_wr_top_line_luma_buffer_size +
+		opb_wr_top_line_chroma_buffer_size +
+		opb_lb_wr_llb_uv_buffer_size +
+		opb_lb_wr_llb_y_buffer_size;
+
+	return size;
+}
+
+static inline
+u32 hfi_buffer_line_h264d(u32 frame_width, u32 frame_height,
+			  bool is_opb, u32 num_vpp_pipes)
+{
+	u32 vpss_lb_size = 0;
+	u32 _size;
+
+	_size = ALIGN(size_h264d_lb_fe_top_data(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_fe_top_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_fe_left_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) * num_vpp_pipes +
+		ALIGN(size_h264d_lb_se_top_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_se_left_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) * num_vpp_pipes +
+		ALIGN(size_h264d_lb_pe_top_data(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_vsp_top(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h264d_lb_recon_dma_metadata_wr(frame_width, frame_height),
+		      DMA_ALIGNMENT) * 2 +
+		ALIGN(size_h264d_qp(frame_width, frame_height),
+		      DMA_ALIGNMENT);
+	_size = ALIGN(_size, DMA_ALIGNMENT);
+	if (is_opb)
+		vpss_lb_size = size_vpss_lb(frame_width, frame_height,
+					    num_vpp_pipes);
+
+	_size = ALIGN((_size + vpss_lb_size),
+		      DMA_ALIGNMENT);
+
+	return _size;
+}
+
+static inline
+u32 size_h265d_lb_fe_top_data(u32 frame_width, u32 frame_height)
+{
+	return MAX_FE_NBR_DATA_LUMA_LINE_BUFFER_SIZE *
+		(ALIGN(frame_width, 64) + 8) * 2;
+}
+
+static inline
+u32 size_h265d_lb_fe_top_ctrl(u32 frame_width, u32 frame_height)
+{
+	return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE *
+		(ALIGN(frame_width, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS);
+}
+
+static inline
+u32 size_h265d_lb_fe_left_ctrl(u32 frame_width, u32 frame_height)
+{
+	return MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE *
+		(ALIGN(frame_height, LCU_MAX_SIZE_PELS) / LCU_MIN_SIZE_PELS);
+}
+
+static inline
+u32 size_h265d_lb_se_top_ctrl(u32 frame_width, u32 frame_height)
+{
+	return (LCU_MAX_SIZE_PELS / 8 * (128 / 8)) * ((frame_width + 15) >> 4);
+}
+
+static inline
+u32 size_h265d_lb_se_left_ctrl(u32 frame_width, u32 frame_height)
+{
+	return max_t(u32, ((frame_height + 16 - 1) / 8) *
+		     MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE,
+		     max_t(u32, ((frame_height + 32 - 1) / 8) *
+			   MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE,
+			   ((frame_height + 64 - 1) / 8) *
+			   MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE));
+}
+
+static inline
+u32 size_h265d_lb_pe_top_data(u32 frame_width, u32 frame_height)
+{
+	return MAX_PE_NBR_DATA_LCU64_LINE_BUFFER_SIZE *
+		(ALIGN(frame_width, LCU_MIN_SIZE_PELS) / LCU_MIN_SIZE_PELS);
+}
+
+static inline
+u32 size_h265d_lb_vsp_top(u32 frame_width, u32 frame_height)
+{
+	return ((frame_width + 63) >> 6) * 128;
+}
+
+static inline
+u32 size_h265d_lb_vsp_left(u32 frame_width, u32 frame_height)
+{
+	return ((frame_height + 63) >> 6) * 128;
+}
+
+static inline
+u32 size_h265d_lb_recon_dma_metadata_wr(u32 frame_width, u32 frame_height)
+{
+	return size_h264d_lb_recon_dma_metadata_wr(frame_width, frame_height);
+}
+
+static inline
+u32 size_h265d_qp(u32 frame_width, u32 frame_height)
+{
+	return size_h264d_qp(frame_width, frame_height);
+}
+
+static inline
+u32 hfi_buffer_line_h265d(u32 frame_width, u32 frame_height,
+			  bool is_opb, u32 num_vpp_pipes)
+{
+	u32 vpss_lb_size = 0, _size;
+
+	_size = ALIGN(size_h265d_lb_fe_top_data(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h265d_lb_fe_top_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h265d_lb_fe_left_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) * num_vpp_pipes +
+		ALIGN(size_h265d_lb_se_left_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) * num_vpp_pipes +
+		ALIGN(size_h265d_lb_se_top_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h265d_lb_pe_top_data(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h265d_lb_vsp_top(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_h265d_lb_vsp_left(frame_width, frame_height),
+		      DMA_ALIGNMENT) * num_vpp_pipes +
+		ALIGN(size_h265d_lb_recon_dma_metadata_wr(frame_width, frame_height),
+		      DMA_ALIGNMENT) * 4 +
+		ALIGN(size_h265d_qp(frame_width, frame_height),
+		      DMA_ALIGNMENT);
+	if (is_opb)
+		vpss_lb_size = size_vpss_lb(frame_width, frame_height, num_vpp_pipes);
+
+	return ALIGN((_size + vpss_lb_size), DMA_ALIGNMENT);
+}
+
+static inline
+u32 size_vpxd_lb_fe_left_ctrl(u32 frame_width, u32 frame_height)
+{
+	return max_t(u32, ((frame_height + 15) >> 4) * MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE,
+		     max_t(u32, ((frame_height + 31) >> 5) * MAX_FE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE,
+			   ((frame_height + 63) >> 6) * MAX_FE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE));
+}
+
+static inline
+u32 size_vpxd_lb_fe_top_ctrl(u32 frame_width, u32 frame_height)
+{
+	return ((ALIGN(frame_width, 64) + 8) * 10 * 2);
+}
+
+static inline
+u32 size_vpxd_lb_se_top_ctrl(u32 frame_width, u32 frame_height)
+{
+	return ((frame_width + 15) >> 4) * MAX_FE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE;
+}
+
+static inline
+u32 size_vpxd_lb_se_left_ctrl(u32 frame_width, u32 frame_height)
+{
+	return max_t(u32, ((frame_height + 15) >> 4) * MAX_SE_NBR_CTRL_LCU16_LINE_BUFFER_SIZE,
+		     max_t(u32, ((frame_height + 31) >> 5) * MAX_SE_NBR_CTRL_LCU32_LINE_BUFFER_SIZE,
+			   ((frame_height + 63) >> 6) * MAX_SE_NBR_CTRL_LCU64_LINE_BUFFER_SIZE));
+}
+
+static inline
+u32 size_vpxd_lb_recon_dma_metadata_wr(u32 frame_width, u32 frame_height)
+{
+	return ALIGN((ALIGN(frame_height, 8) / (4 / 2)) * 64,
+		     BUFFER_ALIGNMENT_32_BYTES);
+}
+
+static inline
+u32 size_mp2d_lb_fe_top_data(u32 frame_width, u32 frame_height)
+{
+	return ((ALIGN(frame_width, 16) + 8) * 10 * 2);
+}
+
+static inline
+u32 size_vp9d_lb_fe_top_data(u32 frame_width, u32 frame_height)
+{
+	return (ALIGN(ALIGN(frame_width, 8), 64) + 8) * 10 * 2;
+}
+
+static inline
+u32 size_vp9d_lb_pe_top_data(u32 frame_width, u32 frame_height)
+{
+	return ((ALIGN(ALIGN(frame_width, 8), 64) >> 6) * 176);
+}
+
+static inline
+u32 size_vp9d_lb_vsp_top(u32 frame_width, u32 frame_height)
+{
+	return (((ALIGN(ALIGN(frame_width, 8), 64) >> 6) * 64 * 8) + 256);
+}
+
+static inline u32 hfi_iris3_vp9d_comv_size(void)
+{
+	return (((8192 + 63) >> 6) * ((4320 + 63) >> 6) * 8 * 8 * 2 * 8);
+}
+
+static inline
+u32 size_vp9d_qp(u32 frame_width, u32 frame_height)
+{
+	return size_h264d_qp(frame_width, frame_height);
+}
+
+static inline
+u32 hfi_iris3_vp9d_lb_size(u32 frame_width, u32 frame_height,
+			   u32 num_vpp_pipes)
+{
+	return ALIGN(size_vpxd_lb_fe_left_ctrl(frame_width, frame_height),
+		     DMA_ALIGNMENT) * num_vpp_pipes +
+		ALIGN(size_vpxd_lb_se_left_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) * num_vpp_pipes +
+		ALIGN(size_vp9d_lb_vsp_top(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_vpxd_lb_fe_top_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		2 * ALIGN(size_vpxd_lb_recon_dma_metadata_wr(frame_width, frame_height),
+			  DMA_ALIGNMENT) +
+		ALIGN(size_vpxd_lb_se_top_ctrl(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_vp9d_lb_pe_top_data(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_vp9d_lb_fe_top_data(frame_width, frame_height),
+		      DMA_ALIGNMENT) +
+		ALIGN(size_vp9d_qp(frame_width, frame_height),
+		      DMA_ALIGNMENT);
+}
+
+static inline
+u32 hfi_buffer_line_vp9d(u32 frame_width, u32 frame_height,
+			 u32 _yuv_bufcount_min, bool is_opb,
+			 u32 num_vpp_pipes)
+{
+	u32 vpss_lb_size = 0;
+	u32 _lb_size = 0;
+
+	_lb_size = hfi_iris3_vp9d_lb_size(frame_width, frame_height,
+					  num_vpp_pipes);
+
+	if (is_opb)
+		vpss_lb_size = size_vpss_lb(frame_width, frame_height,
+					    num_vpp_pipes);
+
+	return _lb_size + vpss_lb_size;
+}
+
+static inline u32 hfi_buffer_persist_h264d(u32 rpu_enabled)
+{
+	return ALIGN(SIZE_SLIST_BUF_H264 * NUM_SLIST_BUF_H264 +
+		    H264_DISPLAY_BUF_SIZE * H264_NUM_FRM_INFO +
+		    NUM_HW_PIC_BUF * SIZE_SEI_USERDATA +
+		    (rpu_enabled) * NUM_HW_PIC_BUF * SIZE_DOLBY_RPU_METADATA,
+		    DMA_ALIGNMENT);
+}
+
+static inline
+u32 hfi_buffer_persist_h265d(u32 rpu_enabled)
+{
+	return ALIGN((SIZE_SLIST_BUF_H265 * NUM_SLIST_BUF_H265 +
+		      H265_NUM_FRM_INFO * H265_DISPLAY_BUF_SIZE +
+		      H265_NUM_TILE * sizeof(u32) +
+		      NUM_HW_PIC_BUF * SIZE_SEI_USERDATA +
+		      rpu_enabled * NUM_HW_PIC_BUF * SIZE_DOLBY_RPU_METADATA),
+		     DMA_ALIGNMENT);
+}
+
+static inline u32 hfi_buffer_persist_vp9d(void)
+{
+	return ALIGN(VP9_NUM_PROBABILITY_TABLE_BUF * VP9_PROB_TABLE_SIZE,
+		     DMA_ALIGNMENT) +
+		ALIGN(hfi_iris3_vp9d_comv_size(), DMA_ALIGNMENT) +
+		ALIGN(MAX_SUPERFRAME_HEADER_LEN, DMA_ALIGNMENT) +
+		ALIGN(VP9_UDC_HEADER_BUF_SIZE, DMA_ALIGNMENT) +
+		ALIGN(VP9_NUM_FRAME_INFO_BUF * CCE_TILE_OFFSET_SIZE,
+		      DMA_ALIGNMENT) +
+		ALIGN(VP9_NUM_FRAME_INFO_BUF * VP9_FRAME_INFO_BUF_SIZE,
+		      DMA_ALIGNMENT) +
+		HDR10_HIST_EXTRADATA_SIZE;
+}
+
+static inline
+u32 hfi_nv12_ubwc_il_calc_y_buf_size(u32 frame_width, u32 frame_height,
+				     u32 stride_multiple,
+				     u32 min_buf_height_multiple)
+{
+	u32 stride, buf_height;
+
+	stride = ALIGN(frame_width, stride_multiple);
+	buf_height = ALIGN(frame_height, min_buf_height_multiple);
+
+	return ALIGN(stride * buf_height, HFI_ALIGNMENT_4096);
+}
+
+static inline
+u32 hfi_nv12_ubwc_il_calc_uv_buf_size(u32 frame_width, u32 frame_height,
+				      u32 stride_multiple,
+				      u32 min_buf_height_multiple)
+{
+	u32 uv_stride, uv_buf_height;
+
+	uv_stride = ALIGN(frame_width, stride_multiple);
+	uv_buf_height = ALIGN(((frame_height + 1) >> 1),
+			      min_buf_height_multiple);
+
+	return ALIGN(uv_stride * uv_buf_height, HFI_ALIGNMENT_4096);
+}
+
+static inline
+u32 hfi_ubwc_calc_metadata_plane_stride(u32 frame_width,
+					u32 metadata_stride_multiple,
+					u32 tile_width_in_pels)
+{
+	return ALIGN(((frame_width + (tile_width_in_pels - 1)) / tile_width_in_pels),
+		     metadata_stride_multiple);
+}
+
+static inline
+u32 hfi_ubwc_metadata_plane_bufheight(u32 frame_height,
+				      u32 metadata_height_multiple,
+				      u32 tile_height_in_pels)
+{
+	return ALIGN(((frame_height + (tile_height_in_pels - 1)) / tile_height_in_pels),
+		     metadata_height_multiple);
+}
+
+static inline
+u32 hfi_ubwc_uv_metadata_plane_stride(u32 frame_width,
+				      u32 metadata_stride_multiple,
+				      u32 tile_width_in_pels)
+{
+	return ALIGN(((((frame_width + 1) >> 1) + tile_width_in_pels - 1) /
+		      tile_width_in_pels), metadata_stride_multiple);
+}
+
+static inline
+u32 hfi_ubwc_uv_metadata_plane_bufheight(u32 frame_height,
+					 u32 metadata_height_multiple,
+					 u32 tile_height_in_pels)
+{
+	return ALIGN(((((frame_height + 1) >> 1) + tile_height_in_pels - 1) /
+		      tile_height_in_pels), metadata_height_multiple);
+}
+
+static inline
+u32 hfi_ubwc_metadata_plane_buffer_size(u32 _metadata_tride, u32 _metadata_buf_height)
+{
+	return ALIGN(_metadata_tride * _metadata_buf_height, HFI_ALIGNMENT_4096);
+}
+
+static inline
+u32 hfi_nv12_ubwc_il_calc_buf_size_v2(u32 frame_width,
+				      u32 frame_height,
+				      u32 y_stride_multiple,
+				      u32 y_buffer_height_multiple,
+				      u32 uv_stride_multiple,
+				      u32 uv_buffer_height_multiple,
+				      u32 y_metadata_stride_multiple,
+				      u32 y_metadata_buffer_height_multiple,
+				      u32 uv_metadata_stride_multiple,
+				      u32 uv_metadata_buffer_height_multiple)
+{
+	u32 y_buf_size, uv_buf_size, y_meta_size, uv_meta_size;
+	u32 half_height = (frame_height + 1) >> 1;
+	u32 stride, _height;
+
+	y_buf_size =
+		hfi_nv12_ubwc_il_calc_y_buf_size(frame_width, half_height,
+						 y_stride_multiple,
+						 y_buffer_height_multiple);
+	uv_buf_size =
+		hfi_nv12_ubwc_il_calc_uv_buf_size(frame_width, half_height,
+						  uv_stride_multiple,
+						  uv_buffer_height_multiple);
+	stride =
+		hfi_ubwc_calc_metadata_plane_stride(frame_width,
+						    y_metadata_stride_multiple,
+						    HFI_COL_FMT_NV12C_Y_TILE_WIDTH);
+	_height =
+		hfi_ubwc_metadata_plane_bufheight(half_height,
+						  y_metadata_buffer_height_multiple,
+						  HFI_COL_FMT_NV12C_Y_TILE_HEIGHT);
+	y_meta_size = hfi_ubwc_metadata_plane_buffer_size(stride, _height);
+	stride =
+		hfi_ubwc_uv_metadata_plane_stride(frame_width,
+						  uv_metadata_stride_multiple,
+						  HFI_COL_FMT_NV12C_UV_TILE_WIDTH);
+	_height =
+		hfi_ubwc_uv_metadata_plane_bufheight(half_height,
+						     uv_metadata_buffer_height_multiple,
+						     HFI_COL_FMT_NV12C_UV_TILE_HEIGHT);
+	uv_meta_size = hfi_ubwc_metadata_plane_buffer_size(stride, _height);
+
+	return (y_buf_size + uv_buf_size + y_meta_size + uv_meta_size) << 1;
+}
+
+static inline
+u32 hfi_yuv420_tp10_ubwc_calc_y_buf_size(u32 y_stride,
+					 u32 y_buf_height)
+{
+	return ALIGN(y_stride * y_buf_height, HFI_ALIGNMENT_4096);
+}
+
+static inline
+u32 hfi_yuv420_tp10_ubwc_calc_uv_buf_size(u32 uv_stride,
+					  u32 uv_buf_height)
+{
+	return ALIGN(uv_stride * uv_buf_height, HFI_ALIGNMENT_4096);
+}
+
+static inline
+u32 hfi_yuv420_tp10_ubwc_calc_buf_size(u32 y_stride, u32 y_buf_height,
+				       u32 uv_stride, u32 uv_buf_height,
+				       u32 y_md_stride, u32 y_md_height,
+				       u32 uv_md_stride, u32 uv_md_height)
+{
+	u32 y_data_size, uv_data_size, y_md_size, uv_md_size;
+
+	y_data_size = hfi_yuv420_tp10_ubwc_calc_y_buf_size(y_stride, y_buf_height);
+	uv_data_size = hfi_yuv420_tp10_ubwc_calc_uv_buf_size(uv_stride, uv_buf_height);
+	y_md_size = hfi_ubwc_metadata_plane_buffer_size(y_md_stride, y_md_height);
+	uv_md_size = hfi_ubwc_metadata_plane_buffer_size(uv_md_stride, uv_md_height);
+
+	return y_data_size + uv_data_size + y_md_size + uv_md_size;
+}
+
+int iris_int_buf_size_iris3(struct iris_inst *inst,
+			    enum iris_buffer_type buffer_type);
+
+static inline
+u32 hfi_buffer_bitstream_enc(u32 frame_width, u32 frame_height,
+			     u32 rc_type, bool is_ten_bit)
+{
+	u32 aligned_width, aligned_height, bitstream_size, yuv_size;
+
+	aligned_width = ALIGN(frame_width, 32);
+	aligned_height = ALIGN(frame_height, 32);
+	bitstream_size = aligned_width * aligned_height * 3;
+	yuv_size = (aligned_width * aligned_height * 3) >> 1;
+	if (aligned_width * aligned_height > (4096 * 2176))
+		/* bitstream_size = 0.25 * yuv_size; */
+		bitstream_size = (bitstream_size >> 3);
+	else if (aligned_width * aligned_height > (1280 * 720))
+		/* bitstream_size = 0.5 * yuv_size; */
+		bitstream_size = (bitstream_size >> 2);
+
+	if ((rc_type == HFI_RC_CQ || rc_type == HFI_RC_OFF) &&
+	    bitstream_size < yuv_size)
+		bitstream_size = (bitstream_size << 1);
+
+	if (is_ten_bit)
+		bitstream_size = (bitstream_size) + (bitstream_size >> 2);
+
+	return ALIGN(bitstream_size, HFI_ALIGNMENT_4096);
+}
+
+static inline
+u32 hfi_iris3_enc_recon_buf_count(s32 n_bframe, s32 ltr_count,
+				  s32 _total_hp_layers,
+				  s32 _total_hb_layers,
+				  bool hybrid_hp,
+				  u32 codec_standard)
+{
+	u32 num_ref = 1;
+
+	if (n_bframe)
+		num_ref = 2;
+
+	if (_total_hp_layers > 1) {
+		if (hybrid_hp)
+			num_ref = (_total_hp_layers + 1) >> 1;
+		else if (codec_standard == HFI_CODEC_ENCODE_HEVC)
+			num_ref = (_total_hp_layers + 1) >> 1;
+		else if (codec_standard == HFI_CODEC_ENCODE_AVC &&
+			 _total_hp_layers < 4)
+			num_ref = (_total_hp_layers - 1);
+		else
+			num_ref = _total_hp_layers;
+	}
+
+	if (ltr_count)
+		num_ref = num_ref + ltr_count;
+
+	if (_total_hb_layers > 1) {
+		if (codec_standard == HFI_CODEC_ENCODE_HEVC)
+			num_ref = (_total_hb_layers);
+		else if (codec_standard == HFI_CODEC_ENCODE_AVC)
+			num_ref = (1 << (_total_hb_layers - 2)) + 1;
+	}
+
+	return num_ref + 1;
+}
+
+static inline
+u32 size_bin_bitstream_enc(u32 rc_type, u32 frame_width, u32 frame_height,
+			   u32 work_mode, u32 lcu_size, u32 profile)
+{
+	u32 size_aligned_width = 0, size_aligned_height = 0;
+	u32 bitstream_size_eval = 0;
+
+	size_aligned_width = ALIGN((frame_width), lcu_size);
+	size_aligned_height = ALIGN((frame_height), lcu_size);
+	if (work_mode == HFI_WORKMODE_2) {
+		if (rc_type == HFI_RC_CQ || rc_type == HFI_RC_OFF) {
+			bitstream_size_eval = (((size_aligned_width) *
+						(size_aligned_height) * 3) >> 1);
+		} else {
+			bitstream_size_eval = ((size_aligned_width) *
+					       (size_aligned_height) * 3);
+			if ((size_aligned_width * size_aligned_height) > (4096 * 2176))
+				bitstream_size_eval >>= 3;
+			else if ((size_aligned_width * size_aligned_height) > (480 * 320))
+				bitstream_size_eval >>= 2;
+
+			if (profile == HFI_H265_PROFILE_MAIN_10 ||
+			    profile == HFI_H265_PROFILE_MAIN_10_STILL_PICTURE)
+				bitstream_size_eval = (bitstream_size_eval * 5 >> 2);
+		}
+	} else {
+		bitstream_size_eval = size_aligned_width * size_aligned_height * 3;
+	}
+
+	return ALIGN(bitstream_size_eval, BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline
+u32 size_enc_single_pipe(u32 rc_type, u32 bitbin_size, u32 num_vpp_pipes,
+			 u32 frame_width, u32 frame_height, u32 lcu_size)
+{
+	u32 size_single_pipe_eval = 0, sao_bin_buffer_size = 0;
+	u32 size_aligned_width = 0, size_aligned_height = 0;
+	u32 _padded_bin_sz = 0;
+
+	size_aligned_width = ALIGN((frame_width), lcu_size);
+	size_aligned_height = ALIGN((frame_height), lcu_size);
+	if ((size_aligned_width * size_aligned_height) > (3840 * 2160))
+		size_single_pipe_eval = (bitbin_size / num_vpp_pipes);
+	else if (num_vpp_pipes > 2)
+		size_single_pipe_eval = bitbin_size / 2;
+	else
+		size_single_pipe_eval = bitbin_size;
+
+	sao_bin_buffer_size =
+		(64 * ((((frame_width) + BUFFER_ALIGNMENT_32_BYTES) *
+			((frame_height) + BUFFER_ALIGNMENT_32_BYTES)) >> 10)) + 384;
+	_padded_bin_sz = ALIGN(size_single_pipe_eval, BUFFER_ALIGNMENT_256_BYTES);
+	size_single_pipe_eval = sao_bin_buffer_size + _padded_bin_sz;
+	size_single_pipe_eval = ALIGN(size_single_pipe_eval, BUFFER_ALIGNMENT_256_BYTES);
+
+	return size_single_pipe_eval;
+}
+
+static inline
+u32 hfi_buffer_bin_enc(u32 rc_type, u32 frame_width, u32 frame_height, u32 lcu_size,
+		       u32 work_mode, u32 num_vpp_pipes, u32 profile)
+{
+	u32 bitstream_size = 0, total_bitbin_buffers = 0;
+	u32 size_single_pipe = 0, bitbin_size = 0;
+	u32 _size = 0;
+
+	bitstream_size = size_bin_bitstream_enc(rc_type, frame_width,
+						frame_height, work_mode,
+						lcu_size, profile);
+
+	if (work_mode == HFI_WORKMODE_2) {
+		total_bitbin_buffers = 3;
+		bitbin_size = bitstream_size * 12 / 10;
+		bitbin_size = ALIGN(bitbin_size, BUFFER_ALIGNMENT_256_BYTES);
+	} else if ((lcu_size == 16) || (num_vpp_pipes > 1)) {
+		total_bitbin_buffers = 1;
+		bitbin_size = bitstream_size;
+	}
+
+	if (total_bitbin_buffers > 0) {
+		size_single_pipe = size_enc_single_pipe(rc_type, bitbin_size,
+							num_vpp_pipes, frame_width,
+							frame_height, lcu_size);
+		bitbin_size = size_single_pipe * num_vpp_pipes;
+		_size = ALIGN(bitbin_size, BUFFER_ALIGNMENT_256_BYTES) *
+			      total_bitbin_buffers + 512;
+	} else {
+		/* Avoid 512 Bytes allocation in case of 1Pipe HEVC Direct Mode*/
+		_size = 0;
+	}
+
+	return _size;
+}
+
+static inline
+u32 hfi_buffer_bin_h264e(u32 rc_type, u32 frame_width, u32 frame_height,
+			 u32 work_mode, u32 num_vpp_pipes, u32 profile)
+{
+	return hfi_buffer_bin_enc(rc_type, frame_width, frame_height, 16,
+				  work_mode, num_vpp_pipes, profile);
+}
+
+static inline
+u32 hfi_buffer_bin_h265e(u32 rc_type, u32 frame_width, u32 frame_height,
+			 u32 work_mode, u32 num_vpp_pipes, u32 profile)
+{
+	return hfi_buffer_bin_enc(rc_type, frame_width, frame_height, 32,
+				  work_mode, num_vpp_pipes, profile);
+}
+
+static inline
+u32 size_enc_slice_info_buf(u32 num_lcu_in_frame)
+{
+	return ALIGN((256 + (num_lcu_in_frame << 4)), BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline
+u32 size_line_buf_ctrl(u32 frame_width_coded)
+{
+	return ALIGN(frame_width_coded, BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline
+u32 size_line_buf_ctrl_id2(u32 frame_width_coded)
+{
+	return ALIGN(frame_width_coded, BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline
+u32 size_linebuff_data(bool is_ten_bit, u32 frame_width_coded)
+{
+	u32 _size = 0;
+
+	_size = is_ten_bit ?
+		(((((10 * (frame_width_coded) + 1024) + (BUFFER_ALIGNMENT_256_BYTES - 1)) &
+		   (~(BUFFER_ALIGNMENT_256_BYTES - 1))) * 1) +
+		 (((((10 * (frame_width_coded) + 1024) >> 1) + (BUFFER_ALIGNMENT_256_BYTES - 1)) &
+		   (~(BUFFER_ALIGNMENT_256_BYTES - 1))) * 2)) :
+		(((((8 * (frame_width_coded) + 1024) + (BUFFER_ALIGNMENT_256_BYTES - 1)) &
+		   (~(BUFFER_ALIGNMENT_256_BYTES - 1))) * 1) +
+		 (((((8 * (frame_width_coded) + 1024) >> 1) + (BUFFER_ALIGNMENT_256_BYTES - 1)) &
+		   (~(BUFFER_ALIGNMENT_256_BYTES - 1))) * 2));
+
+	return _size;
+}
+
+static inline
+u32 size_left_linebuff_ctrl(u32 standard, u32 frame_height_coded,
+			    u32 num_vpp_pipes_enc)
+{
+	u32 _size = 0;
+
+	_size = standard == HFI_CODEC_ENCODE_HEVC ?
+		(((frame_height_coded) +
+		 (BUFFER_ALIGNMENT_32_BYTES)) / BUFFER_ALIGNMENT_32_BYTES * 4 * 16) :
+		(((frame_height_coded) + 15) / 16 * 5 * 16);
+
+	if ((num_vpp_pipes_enc) > 1) {
+		_size += BUFFER_ALIGNMENT_512_BYTES;
+		_size = ALIGN(_size, BUFFER_ALIGNMENT_512_BYTES) *
+			num_vpp_pipes_enc;
+	}
+
+	return ALIGN(_size, BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline
+u32 size_left_linebuff_recon_pix(bool is_ten_bit, u32 frame_height_coded,
+				 u32 num_vpp_pipes_enc)
+{
+	return (((is_ten_bit + 1) * 2 * (frame_height_coded) + BUFFER_ALIGNMENT_256_BYTES) +
+		(BUFFER_ALIGNMENT_256_BYTES << (num_vpp_pipes_enc - 1)) - 1) &
+		(~((BUFFER_ALIGNMENT_256_BYTES << (num_vpp_pipes_enc - 1)) - 1)) * 1;
+}
+
+static inline
+u32 size_top_linebuff_ctrl_fe(u32 frame_width_coded, u32 standard)
+{
+	u32 _size = 0;
+
+	_size = standard == HFI_CODEC_ENCODE_HEVC ?
+		(64 * ((frame_width_coded) >> 5)) :
+		(BUFFER_ALIGNMENT_256_BYTES + 16 * ((frame_width_coded) >> 4));
+
+	return ALIGN(_size, BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline
+u32 size_left_linebuff_ctrl_fe(u32 frame_height_coded, u32 num_vpp_pipes_enc)
+{
+	return (((BUFFER_ALIGNMENT_256_BYTES + 64 * ((frame_height_coded) >> 4)) +
+		 (BUFFER_ALIGNMENT_256_BYTES << (num_vpp_pipes_enc - 1)) - 1) &
+		 (~((BUFFER_ALIGNMENT_256_BYTES << (num_vpp_pipes_enc - 1)) - 1)) * 1) *
+		num_vpp_pipes_enc;
+}
+
+static inline
+u32 size_left_linebuff_metadata_recon_y(u32 frame_height_coded,
+					bool is_ten_bit,
+					u32 num_vpp_pipes_enc)
+{
+	u32 _size = 0;
+
+	_size = ((BUFFER_ALIGNMENT_256_BYTES + 64 * ((frame_height_coded) /
+		  (8 * (is_ten_bit ? 4 : 8)))));
+	_size = ALIGN(_size, BUFFER_ALIGNMENT_256_BYTES);
+
+	return (_size * num_vpp_pipes_enc);
+}
+
+static inline
+u32 size_left_linebuff_metadata_recon_uv(u32 frame_height_coded,
+					 bool is_ten_bit,
+					 u32 num_vpp_pipes_enc)
+{
+	u32 _size = 0;
+
+	_size = ((BUFFER_ALIGNMENT_256_BYTES + 64 * ((frame_height_coded) /
+		  (4 * (is_ten_bit ? 4 : 8)))));
+	_size = ALIGN(_size, BUFFER_ALIGNMENT_256_BYTES);
+
+	return (_size * num_vpp_pipes_enc);
+}
+
+static inline
+u32 size_linebuff_recon_pix(bool is_ten_bit, u32 frame_width_coded)
+{
+	return ALIGN(((is_ten_bit ? 3 : 2) * (frame_width_coded)),
+		     BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline
+u32 size_frame_rc_buf_size(u32 standard, u32 frame_height_coded,
+			   u32 num_vpp_pipes_enc)
+{
+	u32 _size = 0;
+
+	_size = (standard == HFI_CODEC_ENCODE_HEVC) ?
+		(256 + 16 * (14 + ((((frame_height_coded) >> 5) + 7) >> 3))) :
+		(256 + 16 * (14 + ((((frame_height_coded) >> 4) + 7) >> 3)));
+	_size *= 11;
+	if (num_vpp_pipes_enc > 1)
+		_size = ALIGN(_size, BUFFER_ALIGNMENT_256_BYTES) * num_vpp_pipes_enc;
+
+	return ALIGN(_size, BUFFER_ALIGNMENT_512_BYTES) * HFI_MAX_COL_FRAME;
+}
+
+static inline u32 enc_bitcnt_buf_size(u32 num_lcu_in_frame)
+{
+	return ALIGN((256 + (4 * (num_lcu_in_frame))), BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline u32 enc_bitmap_buf_size(u32 num_lcu_in_frame)
+{
+	return ALIGN((256 + ((num_lcu_in_frame) >> 3)), BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline u32 size_line_buf_sde(u32 frame_width_coded)
+{
+	return ALIGN((256 + (16 * ((frame_width_coded) >> 4))), BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline u32 size_override_buf(u32 num_lcumb)
+{
+	return ALIGN(((16 * (((num_lcumb) + 7) >> 3))), BUFFER_ALIGNMENT_256_BYTES) * 2;
+}
+
+static inline u32 size_ir_buf(u32 num_lcu_in_frame)
+{
+	return ALIGN((((((num_lcu_in_frame) << 1) + 7) & (~7)) * 3), BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline
+u32 size_vpss_line_buf(u32 num_vpp_pipes_enc, u32 frame_height_coded,
+		       u32 frame_width_coded)
+{
+	return ALIGN(((((((8192) >> 2) << 5) * (num_vpp_pipes_enc)) + 64) +
+		      (((((max_t(u32, (frame_width_coded),
+				 (frame_height_coded)) + 3) >> 2) << 5) + 256) * 16)),
+		     BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline
+u32 size_top_line_buf_first_stg_sao(u32 frame_width_coded)
+{
+	return ALIGN((16 * ((frame_width_coded) >> 5)), BUFFER_ALIGNMENT_256_BYTES);
+}
+
+static inline
+u32 hfi_buffer_line_enc(u32 frame_width, u32 frame_height, bool is_ten_bit,
+			u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard)
+{
+	u32 line_buff_data_size = 0, left_line_buff_ctrl_size = 0;
+	u32 frame_width_coded = 0, frame_height_coded = 0;
+	u32 left_line_buff_metadata_recon__uv__size = 0;
+	u32 left_line_buff_metadata_recon__y__size = 0;
+	u32 width_in_lcus = 0, height_in_lcus = 0;
+	u32 left_line_buff_recon_pix_size = 0;
+	u32 top_line_buff_ctrl_fe_size = 0;
+	u32 line_buff_recon_pix_size = 0;
+
+	width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size);
+	height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size);
+	frame_width_coded = width_in_lcus * (lcu_size);
+	frame_height_coded = height_in_lcus * (lcu_size);
+	line_buff_data_size = size_linebuff_data(is_ten_bit, frame_width_coded);
+	left_line_buff_ctrl_size =
+		size_left_linebuff_ctrl(standard, frame_height_coded, num_vpp_pipes_enc);
+	left_line_buff_recon_pix_size =
+		size_left_linebuff_recon_pix(is_ten_bit, frame_height_coded,
+					     num_vpp_pipes_enc);
+	top_line_buff_ctrl_fe_size =
+		size_top_linebuff_ctrl_fe(frame_width_coded, standard);
+	left_line_buff_metadata_recon__y__size =
+		size_left_linebuff_metadata_recon_y(frame_height_coded, is_ten_bit,
+						    num_vpp_pipes_enc);
+	left_line_buff_metadata_recon__uv__size =
+		size_left_linebuff_metadata_recon_uv(frame_height_coded, is_ten_bit,
+						     num_vpp_pipes_enc);
+	line_buff_recon_pix_size = size_linebuff_recon_pix(is_ten_bit, frame_width_coded);
+
+	return size_line_buf_ctrl(frame_width_coded) +
+		size_line_buf_ctrl_id2(frame_width_coded) +
+		line_buff_data_size +
+		left_line_buff_ctrl_size +
+		left_line_buff_recon_pix_size +
+		top_line_buff_ctrl_fe_size +
+		left_line_buff_metadata_recon__y__size +
+		left_line_buff_metadata_recon__uv__size +
+		line_buff_recon_pix_size +
+		size_left_linebuff_ctrl_fe(frame_height_coded,
+					   num_vpp_pipes_enc) +
+		size_line_buf_sde(frame_width_coded) +
+		size_vpss_line_buf(num_vpp_pipes_enc, frame_height_coded,
+				   frame_width_coded) +
+		size_top_line_buf_first_stg_sao(frame_width_coded);
+}
+
+static inline
+u32 hfi_buffer_line_h264e(u32 frame_width, u32 frame_height, bool is_ten_bit,
+			  u32 num_vpp_pipes)
+{
+	return hfi_buffer_line_enc(frame_width, frame_height, 0,
+				   num_vpp_pipes, 16,
+				   HFI_CODEC_ENCODE_AVC);
+}
+
+static inline
+u32 hfi_buffer_line_h265e(u32 frame_width, u32 frame_height, bool is_ten_bit,
+			  u32 num_vpp_pipes)
+{
+	return hfi_buffer_line_enc(frame_width, frame_height,
+				   is_ten_bit, num_vpp_pipes, 32,
+				   HFI_CODEC_ENCODE_HEVC);
+}
+
+static inline
+u32 hfi_buffer_comv_enc(u32 frame_width, u32 frame_height, u32 lcu_size,
+			u32 num_recon, u32 standard)
+{
+	u32 width_in_lcus, height_in_lcus, num_lcu_in_frame;
+	u32 size_colloc_mv = 0, size_colloc_rc = 0;
+	u32 mb_height = ((frame_height) + 15) >> 4;
+	u32 mb_width = ((frame_width) + 15) >> 4;
+
+	width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size);
+	height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size);
+	num_lcu_in_frame = width_in_lcus * height_in_lcus;
+	size_colloc_mv = (standard == HFI_CODEC_ENCODE_HEVC) ?
+		(16 * ((num_lcu_in_frame << 2) + BUFFER_ALIGNMENT_32_BYTES)) :
+		(3 * 16 * (width_in_lcus * height_in_lcus + BUFFER_ALIGNMENT_32_BYTES));
+	size_colloc_mv = ALIGN(size_colloc_mv, BUFFER_ALIGNMENT_256_BYTES) * num_recon;
+	size_colloc_rc = (((mb_width + 7) >> 3) * 16 * 2 * mb_height);
+	size_colloc_rc = ALIGN(size_colloc_rc, BUFFER_ALIGNMENT_256_BYTES) * HFI_MAX_COL_FRAME;
+
+	return size_colloc_mv + size_colloc_rc;
+}
+
+static inline
+u32 hfi_buffer_comv_h264e(u32 frame_width, u32 frame_height, u32 num_recon)
+{
+	return hfi_buffer_comv_enc(frame_width, frame_height, 16,
+				   num_recon, HFI_CODEC_ENCODE_AVC);
+}
+
+static inline
+u32 hfi_buffer_comv_h265e(u32 frame_width, u32 frame_height, u32 num_recon)
+{
+	return hfi_buffer_comv_enc(frame_width, frame_height, 32,
+				   num_recon, HFI_CODEC_ENCODE_HEVC);
+}
+
+static inline
+u32 hfi_buffer_non_comv_enc(u32 frame_width, u32 frame_height,
+			    u32 num_vpp_pipes_enc, u32 lcu_size, u32 standard)
+{
+	u32 frame_width_coded = 0, frame_height_coded = 0;
+	u32 width_in_lcus = 0, height_in_lcus = 0;
+	u32 num_lcu_in_frame = 0, num_lcumb = 0;
+	u32 frame_rc_buf_size = 0;
+
+	width_in_lcus = ((frame_width) + (lcu_size) - 1) / (lcu_size);
+	height_in_lcus = ((frame_height) + (lcu_size) - 1) / (lcu_size);
+	num_lcu_in_frame = width_in_lcus * height_in_lcus;
+	frame_width_coded = width_in_lcus * (lcu_size);
+	frame_height_coded = height_in_lcus * (lcu_size);
+	num_lcumb = (frame_height_coded / lcu_size) *
+		((frame_width_coded + lcu_size * 8) / lcu_size);
+	frame_rc_buf_size =
+		size_frame_rc_buf_size(standard, frame_height_coded,
+				       num_vpp_pipes_enc);
+	return size_enc_slice_info_buf(num_lcu_in_frame) +
+		   SIZE_SLICE_CMD_BUFFER +
+		   SIZE_SPS_PPS_SLICE_HDR +
+		   frame_rc_buf_size +
+		   enc_bitcnt_buf_size(num_lcu_in_frame) +
+		   enc_bitmap_buf_size(num_lcu_in_frame) +
+		   SIZE_BSE_SLICE_CMD_BUF +
+		   SIZE_LAMBDA_LUT +
+		   size_override_buf(num_lcumb) +
+		   size_ir_buf(num_lcu_in_frame);
+}
+
+static inline
+u32 hfi_buffer_non_comv_h264e(u32 frame_width, u32 frame_height,
+			      u32 num_vpp_pipes_enc)
+{
+	return hfi_buffer_non_comv_enc(frame_width, frame_height,
+				       num_vpp_pipes_enc, 16,
+				       HFI_CODEC_ENCODE_AVC);
+}
+
+static inline
+u32 hfi_buffer_non_comv_h265e(u32 frame_width, u32 frame_height,
+			      u32 num_vpp_pipes_enc)
+{
+	return hfi_buffer_non_comv_enc(frame_width, frame_height,
+				       num_vpp_pipes_enc, 32,
+				       HFI_CODEC_ENCODE_HEVC);
+}
+
+static inline
+u32 size_enc_ref_buffer(u32 frame_width, u32 frame_height)
+{
+	u32 u_buffer_width = 0, u_buffer_height = 0;
+	u32 u_chroma_buffer_height = 0;
+
+	u_buffer_height = ALIGN(frame_height, HFI_VENUS_HEIGHT_ALIGNMENT);
+	u_chroma_buffer_height = frame_height >> 1;
+	u_chroma_buffer_height = ALIGN(u_chroma_buffer_height, HFI_VENUS_HEIGHT_ALIGNMENT);
+	u_buffer_width = ALIGN(frame_width, HFI_VENUS_WIDTH_ALIGNMENT);
+
+	return (u_buffer_height + u_chroma_buffer_height) * u_buffer_width;
+}
+
+static inline
+u32 size_enc_ten_bit_ref_buffer(u32 frame_width, u32 frame_height)
+{
+	u32 ref_buf_height = 0, ref_luma_stride_in_bytes = 0;
+	u32 chroma_size = 0, ref_buf_size = 0;
+	u32 u_ref_stride = 0, luma_size = 0;
+	u32 ref_chrm_height_in_bytes = 0;
+
+	ref_buf_height = (frame_height + (HFI_VENUS_HEIGHT_ALIGNMENT - 1)) &
+			(~(HFI_VENUS_HEIGHT_ALIGNMENT - 1));
+	ref_luma_stride_in_bytes = ((frame_width + SYSTEM_LAL_TILE10 - 1) / SYSTEM_LAL_TILE10) *
+		SYSTEM_LAL_TILE10;
+	u_ref_stride = 4 * (ref_luma_stride_in_bytes / 3);
+	u_ref_stride = (u_ref_stride + (BUFFER_ALIGNMENT_128_BYTES - 1)) &
+		(~(BUFFER_ALIGNMENT_128_BYTES - 1));
+	luma_size = ref_buf_height * u_ref_stride;
+	ref_chrm_height_in_bytes = (((frame_height + 1) >> 1) + (BUFFER_ALIGNMENT_32_BYTES - 1)) &
+		(~(BUFFER_ALIGNMENT_32_BYTES - 1));
+	chroma_size = u_ref_stride * ref_chrm_height_in_bytes;
+	luma_size = (luma_size + (BUFFER_ALIGNMENT_4096_BYTES - 1)) &
+		(~(BUFFER_ALIGNMENT_4096_BYTES - 1));
+	chroma_size = (chroma_size + (BUFFER_ALIGNMENT_4096_BYTES - 1)) &
+		(~(BUFFER_ALIGNMENT_4096_BYTES - 1));
+	ref_buf_size = luma_size + chroma_size;
+
+	return ref_buf_size;
+}
+
+static inline
+u32 hfi_buffer_dpb_enc(u32 frame_width, u32 frame_height, bool is_ten_bit)
+{
+	u32 metadata_stride, metadata_buf_height, meta_size_y, meta_size_c;
+	u32 ten_bit_ref_buf_size = 0, ref_buf_size = 0;
+	u32 _size = 0;
+
+	if (!is_ten_bit) {
+		ref_buf_size = size_enc_ref_buffer(frame_width, frame_height);
+		metadata_stride =
+			hfi_ubwc_calc_metadata_plane_stride(frame_width, 64,
+							    HFI_COL_FMT_NV12C_Y_TILE_WIDTH);
+		metadata_buf_height =
+			hfi_ubwc_metadata_plane_bufheight(frame_height, 16,
+							  HFI_COL_FMT_NV12C_Y_TILE_HEIGHT);
+		meta_size_y =
+			hfi_ubwc_metadata_plane_buffer_size(metadata_stride, metadata_buf_height);
+		meta_size_c =
+			hfi_ubwc_metadata_plane_buffer_size(metadata_stride, metadata_buf_height);
+		_size = ref_buf_size + meta_size_y + meta_size_c;
+	} else {
+		ten_bit_ref_buf_size = size_enc_ten_bit_ref_buffer(frame_width, frame_height);
+		metadata_stride =
+			hfi_ubwc_calc_metadata_plane_stride(frame_width,
+							    VENUS_METADATA_STRIDE_MULTIPLE,
+							    HFI_COL_FMT_TP10C_Y_TILE_WIDTH);
+		metadata_buf_height =
+			hfi_ubwc_metadata_plane_bufheight(frame_height,
+							  VENUS_METADATA_HEIGHT_MULTIPLE,
+							  HFI_COL_FMT_TP10C_Y_TILE_HEIGHT);
+		meta_size_y =
+			hfi_ubwc_metadata_plane_buffer_size(metadata_stride, metadata_buf_height);
+		meta_size_c =
+			hfi_ubwc_metadata_plane_buffer_size(metadata_stride, metadata_buf_height);
+		_size = ten_bit_ref_buf_size + meta_size_y + meta_size_c;
+	}
+
+	return _size;
+}
+
+static inline
+u32 hfi_buffer_dpb_h264e(u32 frame_width, u32 frame_height)
+{
+	return hfi_buffer_dpb_enc(frame_width, frame_height, 0);
+}
+
+static inline
+u32 hfi_buffer_dpb_h265e(u32 frame_width, u32 frame_height, bool is_ten_bit)
+{
+	return hfi_buffer_dpb_enc(frame_width, frame_height, is_ten_bit);
+}
+
+static inline
+u32 hfi_buffer_vpss_enc(u32 dswidth, u32 dsheight, bool ds_enable,
+			u32 blur, bool is_ten_bit)
+{
+	u32 vpss_size = 0;
+
+	if (ds_enable || blur)
+		vpss_size = hfi_buffer_dpb_enc(dswidth, dsheight, is_ten_bit);
+
+	return vpss_size;
+}
+
+static inline
+u32 hfi_iris3_enc_min_input_buf_count(u32 totalhblayers)
+{
+	u32 numinput = 3;
+
+	if (totalhblayers >= 2)
+		numinput = (1 << (totalhblayers - 1)) + 2;
+
+	return numinput;
+}
+
+u32 enc_output_buffer_size_iris3(struct iris_inst *inst);
+u32 get_recon_buf_count(struct iris_inst *inst);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/vpu_iris3_power.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/vpu_iris3_power.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "iris_core.h"
+#include "iris_instance.h"
+#include "iris_helpers.h"
+#include "platform_common.h"
+#include "vpu_iris3_power.h"
+
+u64 iris_calc_freq_iris3(struct iris_inst *inst, u32 data_size)
+{
+	u32 operating_rate, vsp_factor_num = 1, vsp_factor_den = 1;
+	u64 vsp_cycles = 0, vpp_cycles = 0, fw_cycles = 0;
+	u64 fw_vpp_cycles = 0, bitrate = 0, freq = 0;
+	u32 vpp_cycles_per_mb, mbs_per_second;
+	u32 base_cycles = 0, fps, mbpf;
+	u32 height = 0, width = 0;
+	struct v4l2_format *inp_f;
+
+	inp_f = inst->fmt_src;
+	width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
+	height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
+
+	mbpf = NUM_MBS_PER_FRAME(height, width);
+	fps = inst->max_rate;
+	mbs_per_second = mbpf * fps;
+
+	fw_cycles = fps * inst->cap[MB_CYCLES_FW].value;
+	fw_vpp_cycles = fps * inst->cap[MB_CYCLES_FW_VPP].value;
+
+	if (inst->domain == ENCODER) {
+		vpp_cycles_per_mb =
+			inst->cap[QUALITY_MODE].value == POWER_SAVE_MODE ?
+			inst->cap[MB_CYCLES_LP].value :
+			inst->cap[MB_CYCLES_VPP].value;
+
+		vpp_cycles = mbs_per_second * vpp_cycles_per_mb / inst->cap[PIPE].value;
+
+		if (inst->cap[B_FRAME].value > 1)
+			vpp_cycles += (vpp_cycles / 4) + (vpp_cycles / 8);
+		else if (inst->cap[B_FRAME].value)
+			vpp_cycles += vpp_cycles / 4;
+
+		vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles);
+		if (inst->cap[PIPE].value > 1)
+			vpp_cycles += div_u64(vpp_cycles, 100);
+
+		operating_rate = inst->cap[OPERATING_RATE].value >> 16;
+		if (operating_rate > (inst->cap[FRAME_RATE].value >> 16) &&
+		    (inst->cap[FRAME_RATE].value >> 16)) {
+			vsp_factor_num = operating_rate;
+			vsp_factor_den = inst->cap[FRAME_RATE].value >> 16;
+		}
+		vsp_cycles = div_u64(((u64)inst->cap[BIT_RATE].value * vsp_factor_num),
+				     vsp_factor_den);
+
+		base_cycles = inst->cap[MB_CYCLES_VSP].value;
+		if (inst->cap[ENTROPY_MODE].value ==
+			V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC) {
+			vsp_cycles = div_u64(vsp_cycles * 135, 100);
+		} else {
+			base_cycles = 0;
+			vsp_cycles = div_u64(vsp_cycles, 2);
+		}
+		vsp_cycles = div_u64(vsp_cycles * 21, 20);
+
+		if (inst->cap[STAGE].value == STAGE_1)
+			vsp_cycles = vsp_cycles * 3;
+
+		vsp_cycles += mbs_per_second * base_cycles;
+	} else if (inst->domain == DECODER) {
+		vpp_cycles = mbs_per_second * inst->cap[MB_CYCLES_VPP].value /
+			inst->cap[PIPE].value;
+		vpp_cycles += max(vpp_cycles / 20, fw_vpp_cycles);
+
+		if (inst->cap[PIPE].value > 1)
+			vpp_cycles += div_u64(vpp_cycles * 59, 1000);
+
+		base_cycles = inst->has_bframe ?
+			80 : inst->cap[MB_CYCLES_VSP].value;
+		bitrate = fps * data_size * 8;
+		vsp_cycles = bitrate;
+
+		if (inst->codec == VP9) {
+			vsp_cycles = div_u64(vsp_cycles * 170, 100);
+		} else if (inst->cap[ENTROPY_MODE].value ==
+				V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC) {
+			vsp_cycles = div_u64(vsp_cycles * 135, 100);
+		} else {
+			base_cycles = 0;
+			vsp_cycles = div_u64(vsp_cycles, 2);
+		}
+		vsp_cycles = div_u64(vsp_cycles * 21, 20);
+
+		if (inst->cap[STAGE].value == STAGE_1)
+			vsp_cycles = vsp_cycles * 3;
+
+		vsp_cycles += mbs_per_second * base_cycles;
+
+		/* Add 25 percent extra for HEVC 10bit all intra use case */
+		if (inst->iframe && inst->codec == HEVC &&
+			is_10bit_colorformat(inst->fmt_dst->fmt.pix_mp.pixelformat))
+			vsp_cycles += div_u64(vsp_cycles * 25, 100);
+	}
+
+	freq = max3(vpp_cycles, vsp_cycles, fw_cycles);
+
+	return freq;
+}
+
+int iris_calc_bw_iris3(struct iris_inst *inst, struct bus_vote_data *data)
+{
+	const struct bw_info *bw_tbl = NULL;
+	unsigned int num_rows = 0;
+	unsigned int i, mbs, mbps;
+	struct iris_core *core;
+
+	if (!data)
+		return 0;
+
+	core = inst->core;
+
+	mbs = (ALIGN(data->height, 16) / 16) * (ALIGN(data->width, 16) / 16);
+	mbps = mbs * data->fps;
+	if (mbps == 0)
+		return 0;
+
+	if (inst->domain == DECODER) {
+		bw_tbl = core->platform_data->bw_tbl_dec;
+		num_rows = core->platform_data->bw_tbl_dec_size;
+	} else if (inst->domain == ENCODER) {
+		bw_tbl = core->platform_data->bw_tbl_enc;
+		num_rows = core->platform_data->bw_tbl_enc_size;
+	}
+
+	if (!bw_tbl || num_rows == 0)
+		return 0;
+
+	for (i = 0; i < num_rows; i++) {
+		if (i != 0 && mbps > bw_tbl[i].mbs_per_sec)
+			break;
+
+		if (is_10bit_colorformat(data->color_formats[0]))
+			data->bus_bw = bw_tbl[i].bw_ddr_10bit;
+		else
+			data->bus_bw = bw_tbl[i].bw_ddr;
+	}
+
+	dev_dbg(core->dev, "bus_bw %llu\n", data->bus_bw);
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/iris/vpu_iris3_power.h
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/iris/vpu_iris3_power.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef __H_VPU_IRIS3_POWER_H__
+#define __H_VPU_IRIS3_POWER_H__
+
+u64 iris_calc_freq_iris3(struct iris_inst *inst, u32 data_size);
+int iris_calc_bw_iris3(struct iris_inst *inst,
+		       struct bus_vote_data *vote_data);
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/venus/core.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/venus/core.c
@@ -406,8 +406,8 @@
 	of_platform_depopulate(dev);
 err_runtime_disable:
 	pm_runtime_put_noidle(dev);
-	pm_runtime_set_suspended(dev);
 	pm_runtime_disable(dev);
+	pm_runtime_set_suspended(dev);
 	hfi_destroy(core);
 err_core_deinit:
 	hfi_core_deinit(core, false);
@@ -424,6 +424,7 @@
 	struct device *dev = core->dev;
 	int ret;
 
+	cancel_delayed_work_sync(&core->work);
 	ret = pm_runtime_get_sync(dev);
 	WARN_ON(ret < 0);
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/venus/hfi_parser.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/venus/hfi_parser.c
@@ -19,6 +19,8 @@
 	struct hfi_plat_caps *caps = core->caps, *cap;
 	unsigned long bit;
 
+	core->codecs_count = 0;
+
 	if (hweight_long(core->dec_codecs) + hweight_long(core->enc_codecs) > MAX_CODEC_NUM)
 		return;
 
@@ -62,7 +64,7 @@
 		cap->cap_bufs_mode_dynamic = true;
 }
 
-static void
+static int
 parse_alloc_mode(struct venus_core *core, u32 codecs, u32 domain, void *data)
 {
 	struct hfi_buffer_alloc_mode_supported *mode = data;
@@ -70,7 +72,7 @@
 	u32 *type;
 
 	if (num_entries > MAX_ALLOC_MODE_ENTRIES)
-		return;
+		return -EINVAL;
 
 	type = mode->data;
 
@@ -82,6 +84,8 @@
 
 		type++;
 	}
+
+	return sizeof(*mode);
 }
 
 static void fill_profile_level(struct hfi_plat_caps *cap, const void *data,
@@ -96,7 +100,7 @@
 	cap->num_pl += num;
 }
 
-static void
+static int
 parse_profile_level(struct venus_core *core, u32 codecs, u32 domain, void *data)
 {
 	struct hfi_profile_level_supported *pl = data;
@@ -104,12 +108,14 @@
 	struct hfi_profile_level pl_arr[HFI_MAX_PROFILE_COUNT] = {};
 
 	if (pl->profile_count > HFI_MAX_PROFILE_COUNT)
-		return;
+		return -EINVAL;
 
 	memcpy(pl_arr, proflevel, pl->profile_count * sizeof(*proflevel));
 
 	for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain,
 		       fill_profile_level, pl_arr, pl->profile_count);
+
+	return pl->profile_count * sizeof(*proflevel) + sizeof(u32);
 }
 
 static void
@@ -124,7 +130,7 @@
 	cap->num_caps += num;
 }
 
-static void
+static int
 parse_caps(struct venus_core *core, u32 codecs, u32 domain, void *data)
 {
 	struct hfi_capabilities *caps = data;
@@ -133,12 +139,14 @@
 	struct hfi_capability caps_arr[MAX_CAP_ENTRIES] = {};
 
 	if (num_caps > MAX_CAP_ENTRIES)
-		return;
+		return -EINVAL;
 
 	memcpy(caps_arr, cap, num_caps * sizeof(*cap));
 
 	for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain,
 		       fill_caps, caps_arr, num_caps);
+
+	return sizeof(*caps);
 }
 
 static void fill_raw_fmts(struct hfi_plat_caps *cap, const void *fmts,
@@ -153,7 +161,7 @@
 	cap->num_fmts += num_fmts;
 }
 
-static void
+static int
 parse_raw_formats(struct venus_core *core, u32 codecs, u32 domain, void *data)
 {
 	struct hfi_uncompressed_format_supported *fmt = data;
@@ -162,7 +170,8 @@
 	struct raw_formats rawfmts[MAX_FMT_ENTRIES] = {};
 	u32 entries = fmt->format_entries;
 	unsigned int i = 0;
-	u32 num_planes;
+	u32 num_planes = 0;
+	u32 size;
 
 	while (entries) {
 		num_planes = pinfo->num_planes;
@@ -172,7 +181,7 @@
 		i++;
 
 		if (i >= MAX_FMT_ENTRIES)
-			return;
+			return -EINVAL;
 
 		if (pinfo->num_planes > MAX_PLANES)
 			break;
@@ -184,9 +193,13 @@
 
 	for_each_codec(core->caps, ARRAY_SIZE(core->caps), codecs, domain,
 		       fill_raw_fmts, rawfmts, i);
+	size = fmt->format_entries * (sizeof(*constr) * num_planes + 2 * sizeof(u32))
+		+ 2 * sizeof(u32);
+
+	return size;
 }
 
-static void parse_codecs(struct venus_core *core, void *data)
+static int parse_codecs(struct venus_core *core, void *data)
 {
 	struct hfi_codec_supported *codecs = data;
 
@@ -198,21 +211,27 @@
 		core->dec_codecs &= ~HFI_VIDEO_CODEC_SPARK;
 		core->enc_codecs &= ~HFI_VIDEO_CODEC_HEVC;
 	}
+
+	return sizeof(*codecs);
 }
 
-static void parse_max_sessions(struct venus_core *core, const void *data)
+static int parse_max_sessions(struct venus_core *core, const void *data)
 {
 	const struct hfi_max_sessions_supported *sessions = data;
 
 	core->max_sessions_supported = sessions->max_sessions;
+
+	return sizeof(*sessions);
 }
 
-static void parse_codecs_mask(u32 *codecs, u32 *domain, void *data)
+static int parse_codecs_mask(u32 *codecs, u32 *domain, void *data)
 {
 	struct hfi_codec_mask_supported *mask = data;
 
 	*codecs = mask->codecs;
 	*domain = mask->video_domains;
+
+	return sizeof(*mask);
 }
 
 static void parser_init(struct venus_inst *inst, u32 *codecs, u32 *domain)
@@ -281,8 +300,9 @@
 u32 hfi_parser(struct venus_core *core, struct venus_inst *inst, void *buf,
 	       u32 size)
 {
-	unsigned int words_count = size >> 2;
-	u32 *word = buf, *data, codecs = 0, domain = 0;
+	u32 *words = buf, *payload, codecs = 0, domain = 0;
+	u32 *frame_size = buf + size;
+	u32 rem_bytes = size;
 	int ret;
 
 	ret = hfi_platform_parser(core, inst);
@@ -299,38 +319,66 @@
 		memset(core->caps, 0, sizeof(core->caps));
 	}
 
-	while (words_count) {
-		data = word + 1;
+	while (words < frame_size) {
+		payload = words + 1;
 
-		switch (*word) {
+		switch (*words) {
 		case HFI_PROPERTY_PARAM_CODEC_SUPPORTED:
-			parse_codecs(core, data);
+			if (rem_bytes <= sizeof(struct hfi_codec_supported))
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+			ret = parse_codecs(core, payload);
+			if (ret < 0)
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
 			init_codecs(core);
 			break;
 		case HFI_PROPERTY_PARAM_MAX_SESSIONS_SUPPORTED:
-			parse_max_sessions(core, data);
+			if (rem_bytes <= sizeof(struct hfi_max_sessions_supported))
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+			ret = parse_max_sessions(core, payload);
 			break;
 		case HFI_PROPERTY_PARAM_CODEC_MASK_SUPPORTED:
-			parse_codecs_mask(&codecs, &domain, data);
+			if (rem_bytes <= sizeof(struct hfi_codec_mask_supported))
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+			ret = parse_codecs_mask(&codecs, &domain, payload);
 			break;
 		case HFI_PROPERTY_PARAM_UNCOMPRESSED_FORMAT_SUPPORTED:
-			parse_raw_formats(core, codecs, domain, data);
+			if (rem_bytes <= sizeof(struct hfi_uncompressed_format_supported))
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+			ret = parse_raw_formats(core, codecs, domain, payload);
 			break;
 		case HFI_PROPERTY_PARAM_CAPABILITY_SUPPORTED:
-			parse_caps(core, codecs, domain, data);
+			if (rem_bytes <= sizeof(struct hfi_capabilities))
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+			ret = parse_caps(core, codecs, domain, payload);
 			break;
 		case HFI_PROPERTY_PARAM_PROFILE_LEVEL_SUPPORTED:
-			parse_profile_level(core, codecs, domain, data);
+			if (rem_bytes <= sizeof(struct hfi_profile_level_supported))
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+			ret = parse_profile_level(core, codecs, domain, payload);
 			break;
 		case HFI_PROPERTY_PARAM_BUFFER_ALLOC_MODE_SUPPORTED:
-			parse_alloc_mode(core, codecs, domain, data);
+			if (rem_bytes <= sizeof(struct hfi_buffer_alloc_mode_supported))
+				return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+			ret = parse_alloc_mode(core, codecs, domain, payload);
 			break;
 		default:
+			ret = sizeof(u32);
 			break;
 		}
 
-		word++;
-		words_count--;
+		if (ret < 0)
+			return HFI_ERR_SYS_INSUFFICIENT_RESOURCES;
+
+		words += ret / sizeof(u32);
+		rem_bytes -= ret;
 	}
 
 	if (!core->max_sessions_supported)
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/venus/hfi_venus.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -187,6 +187,9 @@
 	/* ensure rd/wr indices's are read from memory */
 	rmb();
 
+	if (qsize > IFACEQ_QUEUE_SIZE / 4)
+		return -EINVAL;
+
 	if (wr_idx >= rd_idx)
 		empty_space = qsize - (wr_idx - rd_idx);
 	else
@@ -255,6 +258,9 @@
 	wr_idx = qhdr->write_idx;
 	qsize = qhdr->q_size;
 
+	if (qsize > IFACEQ_QUEUE_SIZE / 4)
+		return -EINVAL;
+
 	/* make sure data is valid before using it */
 	rmb();
 
@@ -1035,18 +1041,26 @@
 {
 	struct device *dev = hdev->core->dev;
 	struct hfi_sfr *sfr = hdev->sfr.kva;
+	u32 size;
 	void *p;
 
 	if (!sfr)
 		return;
 
-	p = memchr(sfr->data, '\0', sfr->buf_size);
+	size = sfr->buf_size;
+	if (!size)
+		return;
+
+	if (size > ALIGNED_SFR_SIZE)
+		size = ALIGNED_SFR_SIZE;
+
+	p = memchr(sfr->data, '\0', size);
 	/*
 	 * SFR isn't guaranteed to be NULL terminated since SYS_ERROR indicates
 	 * that Venus is in the process of crashing.
 	 */
 	if (!p)
-		sfr->data[sfr->buf_size - 1] = '\0';
+		sfr->data[size - 1] = '\0';
 
 	dev_err_ratelimited(dev, "SFR message from FW: %s\n", sfr->data);
 }
--- linux-qcom-6.8.0.orig/drivers/media/platform/qcom/venus/vdec.c
+++ linux-qcom-6.8.0/drivers/media/platform/qcom/venus/vdec.c
@@ -1255,7 +1255,7 @@
 		break;
 	case VENUS_DEC_STATE_INIT:
 	case VENUS_DEC_STATE_CAPTURE_SETUP:
-		ret = hfi_session_flush(inst, HFI_FLUSH_INPUT, true);
+		ret = hfi_session_flush(inst, HFI_FLUSH_ALL, true);
 		break;
 	default:
 		break;
@@ -1747,6 +1747,7 @@
 
 	vdec_pm_get(inst);
 
+	cancel_work_sync(&inst->delayed_process_work);
 	v4l2_m2m_ctx_release(inst->m2m_ctx);
 	v4l2_m2m_release(inst->m2m_dev);
 	vdec_ctrl_deinit(inst);
--- linux-qcom-6.8.0.orig/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c
+++ linux-qcom-6.8.0/drivers/media/platform/renesas/rcar-vin/rcar-csi2.c
@@ -1914,12 +1914,14 @@
 
 	ret = v4l2_async_register_subdev(&priv->subdev);
 	if (ret < 0)
-		goto error_async;
+		goto error_pm_runtime;
 
 	dev_info(priv->dev, "%d lanes found\n", priv->lanes);
 
 	return 0;
 
+error_pm_runtime:
+	pm_runtime_disable(&pdev->dev);
 error_async:
 	v4l2_async_nf_unregister(&priv->notifier);
 	v4l2_async_nf_cleanup(&priv->notifier);
@@ -1936,6 +1938,7 @@
 	v4l2_async_nf_unregister(&priv->notifier);
 	v4l2_async_nf_cleanup(&priv->notifier);
 	v4l2_async_unregister_subdev(&priv->subdev);
+	v4l2_subdev_cleanup(&priv->subdev);
 
 	pm_runtime_disable(&pdev->dev);
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/renesas/rcar-vin/rcar-dma.c
+++ linux-qcom-6.8.0/drivers/media/platform/renesas/rcar-vin/rcar-dma.c
@@ -742,12 +742,22 @@
 	 */
 	switch (vin->mbus_code) {
 	case MEDIA_BUS_FMT_YUYV8_1X16:
-		/* BT.601/BT.1358 16bit YCbCr422 */
-		vnmc |= VNMC_INF_YUV16;
+		if (vin->is_csi)
+			/* YCbCr422 8-bit */
+			vnmc |= VNMC_INF_YUV8_BT601;
+		else
+			/* BT.601/BT.1358 16bit YCbCr422 */
+			vnmc |= VNMC_INF_YUV16;
 		input_is_yuv = true;
 		break;
 	case MEDIA_BUS_FMT_UYVY8_1X16:
-		vnmc |= VNMC_INF_YUV16 | VNMC_YCAL;
+		if (vin->is_csi)
+			/* YCbCr422 8-bit */
+			vnmc |= VNMC_INF_YUV8_BT601;
+		else
+			/* BT.601/BT.1358 16bit YCbCr422 */
+			vnmc |= VNMC_INF_YUV16;
+		vnmc |= VNMC_YCAL;
 		input_is_yuv = true;
 		break;
 	case MEDIA_BUS_FMT_UYVY8_2X8:
--- linux-qcom-6.8.0.orig/drivers/media/platform/renesas/rcar-vin/rcar-vin.h
+++ linux-qcom-6.8.0/drivers/media/platform/renesas/rcar-vin/rcar-vin.h
@@ -59,7 +59,7 @@
 
 #define RVIN_REMOTES_MAX \
 	(((unsigned int)RVIN_CSI_MAX) > ((unsigned int)RVIN_ISP_MAX) ? \
-	 RVIN_CSI_MAX : RVIN_ISP_MAX)
+	 (unsigned int)RVIN_CSI_MAX : (unsigned int)RVIN_ISP_MAX)
 
 /**
  * enum rvin_dma_state - DMA states
--- linux-qcom-6.8.0.orig/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
+++ linux-qcom-6.8.0/drivers/media/platform/renesas/rzg2l-cru/rzg2l-csi2.c
@@ -858,6 +858,7 @@
 	{ .compatible = "renesas,rzg2l-csi2", },
 	{ /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, rzg2l_csi2_of_table);
 
 static struct platform_driver rzg2l_csi2_pdrv = {
 	.remove_new = rzg2l_csi2_remove,
--- linux-qcom-6.8.0.orig/drivers/media/platform/renesas/vsp1/vsp1_histo.c
+++ linux-qcom-6.8.0/drivers/media/platform/renesas/vsp1/vsp1_histo.c
@@ -36,9 +36,8 @@
 vsp1_histogram_buffer_get(struct vsp1_histogram *histo)
 {
 	struct vsp1_histogram_buffer *buf = NULL;
-	unsigned long flags;
 
-	spin_lock_irqsave(&histo->irqlock, flags);
+	spin_lock(&histo->irqlock);
 
 	if (list_empty(&histo->irqqueue))
 		goto done;
@@ -49,7 +48,7 @@
 	histo->readout = true;
 
 done:
-	spin_unlock_irqrestore(&histo->irqlock, flags);
+	spin_unlock(&histo->irqlock);
 	return buf;
 }
 
@@ -58,7 +57,6 @@
 				    size_t size)
 {
 	struct vsp1_pipeline *pipe = histo->entity.pipe;
-	unsigned long flags;
 
 	/*
 	 * The pipeline pointer is guaranteed to be valid as this function is
@@ -70,10 +68,10 @@
 	vb2_set_plane_payload(&buf->buf.vb2_buf, 0, size);
 	vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
 
-	spin_lock_irqsave(&histo->irqlock, flags);
+	spin_lock(&histo->irqlock);
 	histo->readout = false;
 	wake_up(&histo->wait_queue);
-	spin_unlock_irqrestore(&histo->irqlock, flags);
+	spin_unlock(&histo->irqlock);
 }
 
 /* -----------------------------------------------------------------------------
@@ -124,11 +122,10 @@
 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
 	struct vsp1_histogram *histo = vb2_get_drv_priv(vb->vb2_queue);
 	struct vsp1_histogram_buffer *buf = to_vsp1_histogram_buffer(vbuf);
-	unsigned long flags;
 
-	spin_lock_irqsave(&histo->irqlock, flags);
+	spin_lock_irq(&histo->irqlock);
 	list_add_tail(&buf->queue, &histo->irqqueue);
-	spin_unlock_irqrestore(&histo->irqlock, flags);
+	spin_unlock_irq(&histo->irqlock);
 }
 
 static int histo_start_streaming(struct vb2_queue *vq, unsigned int count)
@@ -140,9 +137,8 @@
 {
 	struct vsp1_histogram *histo = vb2_get_drv_priv(vq);
 	struct vsp1_histogram_buffer *buffer;
-	unsigned long flags;
 
-	spin_lock_irqsave(&histo->irqlock, flags);
+	spin_lock_irq(&histo->irqlock);
 
 	/* Remove all buffers from the IRQ queue. */
 	list_for_each_entry(buffer, &histo->irqqueue, queue)
@@ -152,7 +148,7 @@
 	/* Wait for the buffer being read out (if any) to complete. */
 	wait_event_lock_irq(histo->wait_queue, !histo->readout, histo->irqlock);
 
-	spin_unlock_irqrestore(&histo->irqlock, flags);
+	spin_unlock_irq(&histo->irqlock);
 }
 
 static const struct vb2_ops histo_video_queue_qops = {
--- linux-qcom-6.8.0.orig/drivers/media/platform/renesas/vsp1/vsp1_pipe.h
+++ linux-qcom-6.8.0/drivers/media/platform/renesas/vsp1/vsp1_pipe.h
@@ -73,7 +73,7 @@
  * @wpf: The WPF partition window configuration
  */
 struct vsp1_partition {
-	struct vsp1_partition_window rpf;
+	struct vsp1_partition_window rpf[VSP1_MAX_RPF];
 	struct vsp1_partition_window uds_sink;
 	struct vsp1_partition_window uds_source;
 	struct vsp1_partition_window sru;
--- linux-qcom-6.8.0.orig/drivers/media/platform/renesas/vsp1/vsp1_rpf.c
+++ linux-qcom-6.8.0/drivers/media/platform/renesas/vsp1/vsp1_rpf.c
@@ -315,8 +315,8 @@
 	 * 'width' need to be adjusted.
 	 */
 	if (pipe->partitions > 1) {
-		crop.width = pipe->partition->rpf.width;
-		crop.left += pipe->partition->rpf.left;
+		crop.width = pipe->partition->rpf[rpf->entity.index].width;
+		crop.left += pipe->partition->rpf[rpf->entity.index].left;
 	}
 
 	if (pipe->interlaced) {
@@ -371,7 +371,9 @@
 			  unsigned int partition_idx,
 			  struct vsp1_partition_window *window)
 {
-	partition->rpf = *window;
+	struct vsp1_rwpf *rpf = to_rwpf(&entity->subdev);
+
+	partition->rpf[rpf->entity.index] = *window;
 }
 
 static const struct vsp1_entity_operations rpf_entity_ops = {
--- linux-qcom-6.8.0.orig/drivers/media/platform/rockchip/rga/rga.c
+++ linux-qcom-6.8.0/drivers/media/platform/rockchip/rga/rga.c
@@ -98,7 +98,7 @@
 	src_vq->drv_priv = ctx;
 	src_vq->ops = &rga_qops;
 	src_vq->mem_ops = &vb2_dma_sg_memops;
-	dst_vq->gfp_flags = __GFP_DMA32;
+	src_vq->gfp_flags = __GFP_DMA32;
 	src_vq->buf_struct_size = sizeof(struct rga_vb_buffer);
 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
 	src_vq->lock = &ctx->rga->mutex;
--- linux-qcom-6.8.0.orig/drivers/media/platform/samsung/exynos4-is/media-dev.h
+++ linux-qcom-6.8.0/drivers/media/platform/samsung/exynos4-is/media-dev.h
@@ -178,8 +178,9 @@
 #ifdef CONFIG_OF
 static inline bool fimc_md_is_isp_available(struct device_node *node)
 {
-	node = of_get_child_by_name(node, FIMC_IS_OF_NODE_NAME);
-	return node ? of_device_is_available(node) : false;
+	struct device_node *child __free(device_node) =
+		of_get_child_by_name(node, FIMC_IS_OF_NODE_NAME);
+	return child ? of_device_is_available(child) : false;
 }
 #else
 #define fimc_md_is_isp_available(node) (false)
--- linux-qcom-6.8.0.orig/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
+++ linux-qcom-6.8.0/drivers/media/platform/samsung/exynos4-is/mipi-csis.c
@@ -939,13 +939,19 @@
 					       state->supplies);
 			goto unlock;
 		}
-		clk_enable(state->clock[CSIS_CLK_GATE]);
+		ret = clk_enable(state->clock[CSIS_CLK_GATE]);
+		if (ret) {
+			phy_power_off(state->phy);
+			regulator_bulk_disable(CSIS_NUM_SUPPLIES,
+					       state->supplies);
+			goto unlock;
+		}
 	}
 	if (state->flags & ST_STREAMING)
 		s5pcsis_start_stream(state);
 
 	state->flags &= ~ST_SUSPENDED;
- unlock:
+unlock:
 	mutex_unlock(&state->lock);
 	return ret ? -EAGAIN : 0;
 }
--- linux-qcom-6.8.0.orig/drivers/media/platform/samsung/s3c-camif/camif-core.c
+++ linux-qcom-6.8.0/drivers/media/platform/samsung/s3c-camif/camif-core.c
@@ -527,10 +527,19 @@
 static int s3c_camif_runtime_resume(struct device *dev)
 {
 	struct camif_dev *camif = dev_get_drvdata(dev);
+	int ret;
+
+	ret = clk_enable(camif->clock[CLK_GATE]);
+	if (ret)
+		return ret;
 
-	clk_enable(camif->clock[CLK_GATE]);
 	/* null op on s3c244x */
-	clk_enable(camif->clock[CLK_CAM]);
+	ret = clk_enable(camif->clock[CLK_CAM]);
+	if (ret) {
+		clk_disable(camif->clock[CLK_GATE]);
+		return ret;
+	}
+
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c
+++ linux-qcom-6.8.0/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c
@@ -775,11 +775,14 @@
 		(unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.sos + 2;
 	jpeg_buffer.curr = 0;
 
-	word = 0;
-
 	if (get_word_be(&jpeg_buffer, &word))
 		return;
-	jpeg_buffer.size = (long)word - 2;
+
+	if (word < 2)
+		jpeg_buffer.size = 0;
+	else
+		jpeg_buffer.size = (long)word - 2;
+
 	jpeg_buffer.data += 2;
 	jpeg_buffer.curr = 0;
 
@@ -1058,6 +1061,7 @@
 	if (byte == -1)
 		return -1;
 	*word = (unsigned int)byte | temp;
+
 	return 0;
 }
 
@@ -1145,7 +1149,7 @@
 			if (get_word_be(&jpeg_buffer, &word))
 				break;
 			length = (long)word - 2;
-			if (!length)
+			if (length <= 0)
 				return false;
 			sof = jpeg_buffer.curr; /* after 0xffc0 */
 			sof_len = length;
@@ -1176,7 +1180,7 @@
 			if (get_word_be(&jpeg_buffer, &word))
 				break;
 			length = (long)word - 2;
-			if (!length)
+			if (length <= 0)
 				return false;
 			if (n_dqt >= S5P_JPEG_MAX_MARKER)
 				return false;
@@ -1189,7 +1193,7 @@
 			if (get_word_be(&jpeg_buffer, &word))
 				break;
 			length = (long)word - 2;
-			if (!length)
+			if (length <= 0)
 				return false;
 			if (n_dht >= S5P_JPEG_MAX_MARKER)
 				return false;
@@ -1214,6 +1218,7 @@
 			if (get_word_be(&jpeg_buffer, &word))
 				break;
 			length = (long)word - 2;
+			/* No need to check underflows as skip() does it  */
 			skip(&jpeg_buffer, length);
 			break;
 		}
--- linux-qcom-6.8.0.orig/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
+++ linux-qcom-6.8.0/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c
@@ -893,7 +893,7 @@
 	q->dev = dev;
 
 	/* DCMIPP requires 16 bytes aligned buffers */
-	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32) & ~0x0f);
+	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
 	if (ret) {
 		dev_err(dev, "Failed to set DMA mask\n");
 		goto err_mutex_destroy;
--- linux-qcom-6.8.0.orig/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
+++ linux-qcom-6.8.0/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-core.c
@@ -202,8 +202,8 @@
 	return 0;
 
 err_init_entity:
-	while (i > 0)
-		dcmipp->pipe_cfg->ents[i - 1].release(dcmipp->entity[i - 1]);
+	while (i-- > 0)
+		dcmipp->pipe_cfg->ents[i].release(dcmipp->entity[i]);
 	return ret;
 }
 
--- linux-qcom-6.8.0.orig/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
+++ linux-qcom-6.8.0/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c
@@ -39,6 +39,10 @@
 	.link_validate = v4l2_subdev_link_validate,
 };
 
+static const struct media_entity_operations sun4i_csi_subdev_entity_ops = {
+	.link_validate = v4l2_subdev_link_validate,
+};
+
 static int sun4i_csi_notify_bound(struct v4l2_async_notifier *notifier,
 				  struct v4l2_subdev *subdev,
 				  struct v4l2_async_connection *asd)
@@ -214,6 +218,7 @@
 	subdev->internal_ops = &sun4i_csi_subdev_internal_ops;
 	subdev->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
 	subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
+	subdev->entity.ops = &sun4i_csi_subdev_entity_ops;
 	subdev->owner = THIS_MODULE;
 	snprintf(subdev->name, sizeof(subdev->name), "sun4i-csi-0");
 	v4l2_set_subdevdata(subdev, csi);
--- linux-qcom-6.8.0.orig/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig
+++ linux-qcom-6.8.0/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/Kconfig
@@ -8,6 +8,7 @@
 	select VIDEO_V4L2_SUBDEV_API
 	select V4L2_FWNODE
 	select REGMAP_MMIO
+	select GENERIC_PHY
 	select GENERIC_PHY_MIPI_DPHY
 	help
 	   Support for the Allwinner A83T MIPI CSI-2 controller and D-PHY.
--- linux-qcom-6.8.0.orig/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
+++ linux-qcom-6.8.0/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c
@@ -66,6 +66,7 @@
 	struct vb2_v4l2_buffer *src, *dst;
 	unsigned int hstep, vstep;
 	dma_addr_t addr;
+	int i;
 
 	src = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
 	dst = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
@@ -160,6 +161,26 @@
 	deinterlace_write(dev, DEINTERLACE_CH1_HORZ_FACT, hstep);
 	deinterlace_write(dev, DEINTERLACE_CH1_VERT_FACT, vstep);
 
+	/* neutral filter coefficients */
+	deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL,
+			     DEINTERLACE_FRM_CTRL_COEF_ACCESS);
+	readl_poll_timeout(dev->base + DEINTERLACE_STATUS, val,
+			   val & DEINTERLACE_STATUS_COEF_STATUS, 2, 40);
+
+	for (i = 0; i < 32; i++) {
+		deinterlace_write(dev, DEINTERLACE_CH0_HORZ_COEF0 + i * 4,
+				  DEINTERLACE_IDENTITY_COEF);
+		deinterlace_write(dev, DEINTERLACE_CH0_VERT_COEF + i * 4,
+				  DEINTERLACE_IDENTITY_COEF);
+		deinterlace_write(dev, DEINTERLACE_CH1_HORZ_COEF0 + i * 4,
+				  DEINTERLACE_IDENTITY_COEF);
+		deinterlace_write(dev, DEINTERLACE_CH1_VERT_COEF + i * 4,
+				  DEINTERLACE_IDENTITY_COEF);
+	}
+
+	deinterlace_clr_set_bits(dev, DEINTERLACE_FRM_CTRL,
+				 DEINTERLACE_FRM_CTRL_COEF_ACCESS, 0);
+
 	deinterlace_clr_set_bits(dev, DEINTERLACE_FIELD_CTRL,
 				 DEINTERLACE_FIELD_CTRL_FIELD_CNT_MSK,
 				 DEINTERLACE_FIELD_CTRL_FIELD_CNT(ctx->field));
@@ -248,7 +269,6 @@
 static void deinterlace_init(struct deinterlace_dev *dev)
 {
 	u32 val;
-	int i;
 
 	deinterlace_write(dev, DEINTERLACE_BYPASS,
 			  DEINTERLACE_BYPASS_CSC);
@@ -284,27 +304,7 @@
 
 	deinterlace_clr_set_bits(dev, DEINTERLACE_CHROMA_DIFF,
 				 DEINTERLACE_CHROMA_DIFF_TH_MSK,
-				 DEINTERLACE_CHROMA_DIFF_TH(5));
-
-	/* neutral filter coefficients */
-	deinterlace_set_bits(dev, DEINTERLACE_FRM_CTRL,
-			     DEINTERLACE_FRM_CTRL_COEF_ACCESS);
-	readl_poll_timeout(dev->base + DEINTERLACE_STATUS, val,
-			   val & DEINTERLACE_STATUS_COEF_STATUS, 2, 40);
-
-	for (i = 0; i < 32; i++) {
-		deinterlace_write(dev, DEINTERLACE_CH0_HORZ_COEF0 + i * 4,
-				  DEINTERLACE_IDENTITY_COEF);
-		deinterlace_write(dev, DEINTERLACE_CH0_VERT_COEF + i * 4,
-				  DEINTERLACE_IDENTITY_COEF);
-		deinterlace_write(dev, DEINTERLACE_CH1_HORZ_COEF0 + i * 4,
-				  DEINTERLACE_IDENTITY_COEF);
-		deinterlace_write(dev, DEINTERLACE_CH1_VERT_COEF + i * 4,
-				  DEINTERLACE_IDENTITY_COEF);
-	}
-
-	deinterlace_clr_set_bits(dev, DEINTERLACE_FRM_CTRL,
-				 DEINTERLACE_FRM_CTRL_COEF_ACCESS, 0);
+				 DEINTERLACE_CHROMA_DIFF_TH(31));
 }
 
 static inline struct deinterlace_ctx *deinterlace_file2ctx(struct file *file)
@@ -929,11 +929,18 @@
 		return ret;
 	}
 
+	ret = reset_control_deassert(dev->rstc);
+	if (ret) {
+		dev_err(dev->dev, "Failed to apply reset\n");
+
+		goto err_exclusive_rate;
+	}
+
 	ret = clk_prepare_enable(dev->bus_clk);
 	if (ret) {
 		dev_err(dev->dev, "Failed to enable bus clock\n");
 
-		goto err_exclusive_rate;
+		goto err_rst;
 	}
 
 	ret = clk_prepare_enable(dev->mod_clk);
@@ -950,23 +957,16 @@
 		goto err_mod_clk;
 	}
 
-	ret = reset_control_deassert(dev->rstc);
-	if (ret) {
-		dev_err(dev->dev, "Failed to apply reset\n");
-
-		goto err_ram_clk;
-	}
-
 	deinterlace_init(dev);
 
 	return 0;
 
-err_ram_clk:
-	clk_disable_unprepare(dev->ram_clk);
 err_mod_clk:
 	clk_disable_unprepare(dev->mod_clk);
 err_bus_clk:
 	clk_disable_unprepare(dev->bus_clk);
+err_rst:
+	reset_control_assert(dev->rstc);
 err_exclusive_rate:
 	clk_rate_exclusive_put(dev->mod_clk);
 
@@ -977,11 +977,12 @@
 {
 	struct deinterlace_dev *dev = dev_get_drvdata(device);
 
-	reset_control_assert(dev->rstc);
-
 	clk_disable_unprepare(dev->ram_clk);
 	clk_disable_unprepare(dev->mod_clk);
 	clk_disable_unprepare(dev->bus_clk);
+
+	reset_control_assert(dev->rstc);
+
 	clk_rate_exclusive_put(dev->mod_clk);
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
+++ linux-qcom-6.8.0/drivers/media/platform/ti/j721e-csi2rx/j721e-csi2rx.c
@@ -762,15 +762,14 @@
 			dev_warn(csi->dev,
 				 "Failed to drain DMA. Next frame might be bogus\n");
 
+		spin_lock_irqsave(&dma->lock, flags);
 		ret = ti_csi2rx_start_dma(csi, buf);
 		if (ret) {
-			dev_err(csi->dev, "Failed to start DMA: %d\n", ret);
-			spin_lock_irqsave(&dma->lock, flags);
 			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
 			dma->state = TI_CSI2RX_DMA_IDLE;
 			spin_unlock_irqrestore(&dma->lock, flags);
+			dev_err(csi->dev, "Failed to start DMA: %d\n", ret);
 		} else {
-			spin_lock_irqsave(&dma->lock, flags);
 			list_add_tail(&buf->list, &dma->submitted);
 			spin_unlock_irqrestore(&dma->lock, flags);
 		}
--- linux-qcom-6.8.0.orig/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
+++ linux-qcom-6.8.0/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
@@ -161,8 +161,7 @@
 		av1_dec->frame_refs[i].timestamp = timestamp;
 		av1_dec->frame_refs[i].frame_type = frame->frame_type;
 		av1_dec->frame_refs[i].order_hint = frame->order_hint;
-		if (!av1_dec->frame_refs[i].vb2_ref)
-			av1_dec->frame_refs[i].vb2_ref = hantro_get_dst_buf(ctx);
+		av1_dec->frame_refs[i].vb2_ref = hantro_get_dst_buf(ctx);
 
 		for (j = 0; j < V4L2_AV1_TOTAL_REFS_PER_FRAME; j++)
 			av1_dec->frame_refs[i].order_hints[j] = frame->order_hints[j];
--- linux-qcom-6.8.0.orig/drivers/media/radio/radio-shark2.c
+++ linux-qcom-6.8.0/drivers/media/radio/radio-shark2.c
@@ -62,7 +62,7 @@
 #ifdef SHARK_USE_LEDS
 	struct work_struct led_work;
 	struct led_classdev leds[NO_LEDS];
-	char led_names[NO_LEDS][32];
+	char led_names[NO_LEDS][64];
 	atomic_t brightness[NO_LEDS];
 	unsigned long brightness_new;
 #endif
--- linux-qcom-6.8.0.orig/drivers/media/radio/wl128x/fmdrv_common.c
+++ linux-qcom-6.8.0/drivers/media/radio/wl128x/fmdrv_common.c
@@ -466,11 +466,12 @@
 			   jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
 		return -ETIMEDOUT;
 	}
+	spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
 	if (!fmdev->resp_skb) {
+		spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
 		fmerr("Response SKB is missing\n");
 		return -EFAULT;
 	}
-	spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
 	skb = fmdev->resp_skb;
 	fmdev->resp_skb = NULL;
 	spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
--- linux-qcom-6.8.0.orig/drivers/media/rc/iguanair.c
+++ linux-qcom-6.8.0/drivers/media/rc/iguanair.c
@@ -194,8 +194,10 @@
 	if (rc)
 		return rc;
 
-	if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0)
+	if (wait_for_completion_timeout(&ir->completion, TIMEOUT) == 0) {
+		usb_kill_urb(ir->urb_out);
 		return -ETIMEDOUT;
+	}
 
 	return rc;
 }
--- linux-qcom-6.8.0.orig/drivers/media/rc/imon.c
+++ linux-qcom-6.8.0/drivers/media/rc/imon.c
@@ -1148,10 +1148,7 @@
 
 	memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet));
 
-	if (!mutex_is_locked(&ictx->lock)) {
-		unlock = true;
-		mutex_lock(&ictx->lock);
-	}
+	unlock = mutex_trylock(&ictx->lock);
 
 	retval = send_packet(ictx);
 	if (retval)
--- linux-qcom-6.8.0.orig/drivers/media/rc/lirc_dev.c
+++ linux-qcom-6.8.0/drivers/media/rc/lirc_dev.c
@@ -828,8 +828,10 @@
 		return ERR_PTR(-EINVAL);
 	}
 
-	if (write && !(f.file->f_mode & FMODE_WRITE))
+	if (write && !(f.file->f_mode & FMODE_WRITE)) {
+		fdput(f);
 		return ERR_PTR(-EPERM);
+	}
 
 	fh = f.file->private_data;
 	dev = fh->rc;
--- linux-qcom-6.8.0.orig/drivers/media/test-drivers/vivid/vivid-core.c
+++ linux-qcom-6.8.0/drivers/media/test-drivers/vivid/vivid-core.c
@@ -884,7 +884,7 @@
 	 * videobuf2-core.c to MAX_BUFFER_INDEX.
 	 */
 	if (buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-		q->max_num_buffers = 64;
+		q->max_num_buffers = MAX_VID_CAP_BUFFERS;
 	if (buf_type == V4L2_BUF_TYPE_SDR_CAPTURE)
 		q->max_num_buffers = 1024;
 	if (buf_type == V4L2_BUF_TYPE_VBI_CAPTURE)
--- linux-qcom-6.8.0.orig/drivers/media/test-drivers/vivid/vivid-core.h
+++ linux-qcom-6.8.0/drivers/media/test-drivers/vivid/vivid-core.h
@@ -26,6 +26,8 @@
 #define MAX_INPUTS 16
 /* The maximum number of outputs */
 #define MAX_OUTPUTS 16
+/* The maximum number of video capture buffers */
+#define MAX_VID_CAP_BUFFERS 64
 /* The maximum up or down scaling factor is 4 */
 #define MAX_ZOOM  4
 /* The maximum image width/height are set to 4K DMT */
@@ -377,7 +379,7 @@
 	/* video capture */
 	struct tpg_data			tpg;
 	unsigned			ms_vid_cap;
-	bool				must_blank[VIDEO_MAX_FRAME];
+	bool				must_blank[MAX_VID_CAP_BUFFERS];
 
 	const struct vivid_fmt		*fmt_cap;
 	struct v4l2_fract		timeperframe_vid_cap;
--- linux-qcom-6.8.0.orig/drivers/media/test-drivers/vivid/vivid-ctrls.c
+++ linux-qcom-6.8.0/drivers/media/test-drivers/vivid/vivid-ctrls.c
@@ -519,7 +519,7 @@
 		break;
 	case VIVID_CID_PERCENTAGE_FILL:
 		tpg_s_perc_fill(&dev->tpg, ctrl->val);
-		for (i = 0; i < VIDEO_MAX_FRAME; i++)
+		for (i = 0; i < MAX_VID_CAP_BUFFERS; i++)
 			dev->must_blank[i] = ctrl->val < 100;
 		break;
 	case VIVID_CID_INSERT_SAV:
--- linux-qcom-6.8.0.orig/drivers/media/test-drivers/vivid/vivid-vid-cap.c
+++ linux-qcom-6.8.0/drivers/media/test-drivers/vivid/vivid-vid-cap.c
@@ -106,8 +106,9 @@
 		if (*nplanes != buffers)
 			return -EINVAL;
 		for (p = 0; p < buffers; p++) {
-			if (sizes[p] < tpg_g_line_width(&dev->tpg, p) * h +
-						dev->fmt_cap->data_offset[p])
+			if (sizes[p] < tpg_g_line_width(&dev->tpg, p) * h /
+					dev->fmt_cap->vdownsampling[p] +
+					dev->fmt_cap->data_offset[p])
 				return -EINVAL;
 		}
 	} else {
@@ -215,7 +216,7 @@
 
 	dev->vid_cap_seq_count = 0;
 	dprintk(dev, 1, "%s\n", __func__);
-	for (i = 0; i < VIDEO_MAX_FRAME; i++)
+	for (i = 0; i < MAX_VID_CAP_BUFFERS; i++)
 		dev->must_blank[i] = tpg_g_perc_fill(&dev->tpg) < 100;
 	if (dev->start_streaming_error) {
 		dev->start_streaming_error = false;
@@ -1462,12 +1463,19 @@
 	h_freq = (u32)bt->pixelclock / total_h_pixel;
 
 	if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_CVT)) {
+		struct v4l2_dv_timings cvt = {};
+
 		if (v4l2_detect_cvt(total_v_lines, h_freq, bt->vsync, bt->width,
-				    bt->polarities, bt->interlaced, timings))
+				    bt->polarities, bt->interlaced,
+				    &vivid_dv_timings_cap, &cvt) &&
+		    cvt.bt.width == bt->width && cvt.bt.height == bt->height) {
+			*timings = cvt;
 			return true;
+		}
 	}
 
 	if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_GTF)) {
+		struct v4l2_dv_timings gtf = {};
 		struct v4l2_fract aspect_ratio;
 
 		find_aspect_ratio(bt->width, bt->height,
@@ -1475,8 +1483,12 @@
 				  &aspect_ratio.denominator);
 		if (v4l2_detect_gtf(total_v_lines, h_freq, bt->vsync,
 				    bt->polarities, bt->interlaced,
-				    aspect_ratio, timings))
+				    aspect_ratio, &vivid_dv_timings_cap,
+				    &gtf) &&
+		    gtf.bt.width == bt->width && gtf.bt.height == bt->height) {
+			*timings = gtf;
 			return true;
+		}
 	}
 	return false;
 }
@@ -1553,8 +1565,10 @@
 		return -EINVAL;
 	if (edid->blocks == 0) {
 		dev->edid_blocks = 0;
-		v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, 0);
-		v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, 0);
+		if (dev->num_outputs) {
+			v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, 0);
+			v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, 0);
+		}
 		phys_addr = CEC_PHYS_ADDR_INVALID;
 		goto set_phys_addr;
 	}
@@ -1578,8 +1592,10 @@
 			display_present |=
 				dev->display_present[i] << j++;
 
-	v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, display_present);
-	v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, display_present);
+	if (dev->num_outputs) {
+		v4l2_ctrl_s_ctrl(dev->ctrl_tx_edid_present, display_present);
+		v4l2_ctrl_s_ctrl(dev->ctrl_tx_hotplug, display_present);
+	}
 
 set_phys_addr:
 	/* TODO: a proper hotplug detect cycle should be emulated here */
--- linux-qcom-6.8.0.orig/drivers/media/test-drivers/vivid/vivid-vid-out.c
+++ linux-qcom-6.8.0/drivers/media/test-drivers/vivid/vivid-vid-out.c
@@ -63,14 +63,16 @@
 		if (sizes[0] < size)
 			return -EINVAL;
 		for (p = 1; p < planes; p++) {
-			if (sizes[p] < dev->bytesperline_out[p] * h +
-				       vfmt->data_offset[p])
+			if (sizes[p] < dev->bytesperline_out[p] * h /
+					vfmt->vdownsampling[p] +
+					vfmt->data_offset[p])
 				return -EINVAL;
 		}
 	} else {
 		for (p = 0; p < planes; p++)
-			sizes[p] = p ? dev->bytesperline_out[p] * h +
-				       vfmt->data_offset[p] : size;
+			sizes[p] = p ? dev->bytesperline_out[p] * h /
+					vfmt->vdownsampling[p] +
+					vfmt->data_offset[p] : size;
 	}
 
 	*nplanes = planes;
@@ -124,7 +126,7 @@
 
 	for (p = 0; p < planes; p++) {
 		if (p)
-			size = dev->bytesperline_out[p] * h;
+			size = dev->bytesperline_out[p] * h / vfmt->vdownsampling[p];
 		size += vb->planes[p].data_offset;
 
 		if (vb2_get_plane_payload(vb, p) < size) {
@@ -331,8 +333,8 @@
 	for (p = 0; p < mp->num_planes; p++) {
 		mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p];
 		mp->plane_fmt[p].sizeimage =
-			mp->plane_fmt[p].bytesperline * mp->height +
-			fmt->data_offset[p];
+			mp->plane_fmt[p].bytesperline * mp->height /
+			fmt->vdownsampling[p] + fmt->data_offset[p];
 	}
 	for (p = fmt->buffers; p < fmt->planes; p++) {
 		unsigned stride = dev->bytesperline_out[p];
--- linux-qcom-6.8.0.orig/drivers/media/tuners/tuner-i2c.h
+++ linux-qcom-6.8.0/drivers/media/tuners/tuner-i2c.h
@@ -133,10 +133,8 @@
 	}								\
 	if (0 == __ret) {						\
 		state = kzalloc(sizeof(type), GFP_KERNEL);		\
-		if (!state) {						\
-			__ret = -ENOMEM;				\
+		if (NULL == state)					\
 			goto __fail;					\
-		}							\
 		state->i2c_props.addr = i2caddr;			\
 		state->i2c_props.adap = i2cadap;			\
 		state->i2c_props.name = devname;			\
--- linux-qcom-6.8.0.orig/drivers/media/tuners/xc2028.c
+++ linux-qcom-6.8.0/drivers/media/tuners/xc2028.c
@@ -1361,9 +1361,16 @@
 			     void *context)
 {
 	struct dvb_frontend *fe = context;
-	struct xc2028_data *priv = fe->tuner_priv;
+	struct xc2028_data *priv;
 	int rc;
 
+	if (!fe) {
+		pr_warn("xc2028: No frontend in %s\n", __func__);
+		return;
+	}
+
+	priv = fe->tuner_priv;
+
 	tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error");
 	if (!fw) {
 		tuner_err("Could not load firmware %s.\n", priv->fname);
--- linux-qcom-6.8.0.orig/drivers/media/tuners/xc4000.c
+++ linux-qcom-6.8.0/drivers/media/tuners/xc4000.c
@@ -1515,10 +1515,10 @@
 {
 	struct xc4000_priv *priv = fe->tuner_priv;
 
+	mutex_lock(&priv->lock);
 	*freq = priv->freq_hz + priv->freq_offset;
 
 	if (debug) {
-		mutex_lock(&priv->lock);
 		if ((priv->cur_fw.type
 		     & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
 			u16	snr = 0;
@@ -1529,8 +1529,8 @@
 				return 0;
 			}
 		}
-		mutex_unlock(&priv->lock);
 	}
+	mutex_unlock(&priv->lock);
 
 	dprintk(1, "%s()\n", __func__);
 
--- linux-qcom-6.8.0.orig/drivers/media/usb/b2c2/flexcop-usb.c
+++ linux-qcom-6.8.0/drivers/media/usb/b2c2/flexcop-usb.c
@@ -179,7 +179,7 @@
 		flexcop_usb_request_t req, flexcop_usb_mem_page_t page_start,
 		u32 addr, int extended, u8 *buf, u32 len)
 {
-	int i, ret = 0;
+	int ret = 0;
 	u16 wMax;
 	u32 pagechunk = 0;
 
@@ -196,7 +196,7 @@
 	default:
 		return -EINVAL;
 	}
-	for (i = 0; i < len;) {
+	while (len) {
 		pagechunk =
 			wMax < bytes_left_to_read_on_page(addr, len) ?
 				wMax :
@@ -209,11 +209,12 @@
 			page_start + (addr / V8_MEMORY_PAGE_SIZE),
 			(addr & V8_MEMORY_PAGE_MASK) |
 				(V8_MEMORY_EXTENDED*extended),
-			&buf[i], pagechunk);
+			buf, pagechunk);
 
 		if (ret < 0)
 			return ret;
 		addr += pagechunk;
+		buf += pagechunk;
 		len -= pagechunk;
 	}
 	return 0;
@@ -515,7 +516,7 @@
 
 	alt = fc_usb->uintf->cur_altsetting;
 
-	if (alt->desc.bNumEndpoints < 1)
+	if (alt->desc.bNumEndpoints < 2)
 		return -ENODEV;
 	if (!usb_endpoint_is_isoc_in(&alt->endpoint[0].desc))
 		return -ENODEV;
--- linux-qcom-6.8.0.orig/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ linux-qcom-6.8.0/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -994,6 +994,8 @@
 
 /* table of devices that work with this driver */
 struct usb_device_id cx231xx_id_table[] = {
+	{USB_DEVICE(0x1D19, 0x6108),
+	.driver_info = CX231XX_BOARD_PV_XCAPTURE_USB},
 	{USB_DEVICE(0x1D19, 0x6109),
 	.driver_info = CX231XX_BOARD_PV_XCAPTURE_USB},
 	{USB_DEVICE(0x0572, 0x5A3C),
--- linux-qcom-6.8.0.orig/drivers/media/usb/dvb-usb-v2/af9035.c
+++ linux-qcom-6.8.0/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -322,13 +322,16 @@
 			ret = -EOPNOTSUPP;
 		} else if ((msg[0].addr == state->af9033_i2c_addr[0]) ||
 			   (msg[0].addr == state->af9033_i2c_addr[1])) {
+			/* demod access via firmware interface */
+			u32 reg;
+
 			if (msg[0].len < 3 || msg[1].len < 1) {
 				ret = -EOPNOTSUPP;
 				goto unlock;
 			}
-			/* demod access via firmware interface */
-			u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
-					msg[0].buf[2];
+
+			reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
+				msg[0].buf[2];
 
 			if (msg[0].addr == state->af9033_i2c_addr[1])
 				reg |= 0x100000;
@@ -385,13 +388,16 @@
 			ret = -EOPNOTSUPP;
 		} else if ((msg[0].addr == state->af9033_i2c_addr[0]) ||
 			   (msg[0].addr == state->af9033_i2c_addr[1])) {
+			/* demod access via firmware interface */
+			u32 reg;
+
 			if (msg[0].len < 3) {
 				ret = -EOPNOTSUPP;
 				goto unlock;
 			}
-			/* demod access via firmware interface */
-			u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
-					msg[0].buf[2];
+
+			reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
+				msg[0].buf[2];
 
 			if (msg[0].addr == state->af9033_i2c_addr[1])
 				reg |= 0x100000;
--- linux-qcom-6.8.0.orig/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ linux-qcom-6.8.0/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -373,6 +373,7 @@
 	struct dvb_usb_device *d = adap_to_d(adap);
 	struct lme2510_state *lme_int = adap_to_priv(adap);
 	struct usb_host_endpoint *ep;
+	int ret;
 
 	lme_int->lme_urb = usb_alloc_urb(0, GFP_KERNEL);
 
@@ -390,11 +391,20 @@
 
 	/* Quirk of pipe reporting PIPE_BULK but behaves as interrupt */
 	ep = usb_pipe_endpoint(d->udev, lme_int->lme_urb->pipe);
+	if (!ep) {
+		usb_free_urb(lme_int->lme_urb);
+		return -ENODEV;
+	}
 
 	if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_BULK)
 		lme_int->lme_urb->pipe = usb_rcvbulkpipe(d->udev, 0xa);
 
-	usb_submit_urb(lme_int->lme_urb, GFP_KERNEL);
+	ret = usb_submit_urb(lme_int->lme_urb, GFP_KERNEL);
+	if (ret) {
+		usb_free_urb(lme_int->lme_urb);
+		return ret;
+	}
+
 	info("INT Interrupt Service Started");
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/media/usb/dvb-usb/dib0700_devices.c
+++ linux-qcom-6.8.0/drivers/media/usb/dvb-usb/dib0700_devices.c
@@ -2412,7 +2412,12 @@
 
 	adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config);
 
-	return adap->fe_adap[0].fe == NULL ?  -ENODEV : 0;
+	if (!adap->fe_adap[0].fe) {
+		release_firmware(state->frontend_firmware);
+		return -ENODEV;
+	}
+
+	return 0;
 }
 
 static int dib9090_tuner_attach(struct dvb_usb_adapter *adap)
@@ -2485,8 +2490,10 @@
 	dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80);
 	adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]);
 
-	if (adap->fe_adap[0].fe == NULL)
+	if (!adap->fe_adap[0].fe) {
+		release_firmware(state->frontend_firmware);
 		return -ENODEV;
+	}
 
 	i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0);
 	dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82);
@@ -2494,7 +2501,12 @@
 	fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]);
 	dib9000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave);
 
-	return fe_slave == NULL ?  -ENODEV : 0;
+	if (!fe_slave) {
+		release_firmware(state->frontend_firmware);
+		return -ENODEV;
+	}
+
+	return 0;
 }
 
 static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap)
--- linux-qcom-6.8.0.orig/drivers/media/usb/dvb-usb/dw2102.c
+++ linux-qcom-6.8.0/drivers/media/usb/dvb-usb/dw2102.c
@@ -716,6 +716,7 @@
 {
 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
 	struct dw2102_state *state;
+	int j;
 
 	if (!d)
 		return -ENODEV;
@@ -729,11 +730,11 @@
 		return -EAGAIN;
 	}
 
-	switch (num) {
-	case 1:
-		switch (msg[0].addr) {
+	j = 0;
+	while (j < num) {
+		switch (msg[j].addr) {
 		case SU3000_STREAM_CTRL:
-			state->data[0] = msg[0].buf[0] + 0x36;
+			state->data[0] = msg[j].buf[0] + 0x36;
 			state->data[1] = 3;
 			state->data[2] = 0;
 			if (dvb_usb_generic_rw(d, state->data, 3,
@@ -745,61 +746,86 @@
 			if (dvb_usb_generic_rw(d, state->data, 1,
 					state->data, 2, 0) < 0)
 				err("i2c transfer failed.");
-			msg[0].buf[1] = state->data[0];
-			msg[0].buf[0] = state->data[1];
+			msg[j].buf[1] = state->data[0];
+			msg[j].buf[0] = state->data[1];
 			break;
 		default:
-			if (3 + msg[0].len > sizeof(state->data)) {
-				warn("i2c wr: len=%d is too big!\n",
-				     msg[0].len);
+			/* if the current write msg is followed by a another
+			 * read msg to/from the same address
+			 */
+			if ((j+1 < num) && (msg[j+1].flags & I2C_M_RD) &&
+			    (msg[j].addr == msg[j+1].addr)) {
+				/* join both i2c msgs to one usb read command */
+				if (4 + msg[j].len > sizeof(state->data)) {
+					warn("i2c combined wr/rd: write len=%d is too big!\n",
+					    msg[j].len);
+					num = -EOPNOTSUPP;
+					break;
+				}
+				if (1 + msg[j+1].len > sizeof(state->data)) {
+					warn("i2c combined wr/rd: read len=%d is too big!\n",
+					    msg[j+1].len);
+					num = -EOPNOTSUPP;
+					break;
+				}
+
+				state->data[0] = 0x09;
+				state->data[1] = msg[j].len;
+				state->data[2] = msg[j+1].len;
+				state->data[3] = msg[j].addr;
+				memcpy(&state->data[4], msg[j].buf, msg[j].len);
+
+				if (dvb_usb_generic_rw(d, state->data, msg[j].len + 4,
+					state->data, msg[j+1].len + 1, 0) < 0)
+					err("i2c transfer failed.");
+
+				memcpy(msg[j+1].buf, &state->data[1], msg[j+1].len);
+				j++;
+				break;
+			}
+
+			if (msg[j].flags & I2C_M_RD) {
+				/* single read */
+				if (4 + msg[j].len > sizeof(state->data)) {
+					warn("i2c rd: len=%d is too big!\n", msg[j].len);
+					num = -EOPNOTSUPP;
+					break;
+				}
+
+				state->data[0] = 0x09;
+				state->data[1] = 0;
+				state->data[2] = msg[j].len;
+				state->data[3] = msg[j].addr;
+				memcpy(&state->data[4], msg[j].buf, msg[j].len);
+
+				if (dvb_usb_generic_rw(d, state->data, 4,
+					state->data, msg[j].len + 1, 0) < 0)
+					err("i2c transfer failed.");
+
+				memcpy(msg[j].buf, &state->data[1], msg[j].len);
+				break;
+			}
+
+			/* single write */
+			if (3 + msg[j].len > sizeof(state->data)) {
+				warn("i2c wr: len=%d is too big!\n", msg[j].len);
 				num = -EOPNOTSUPP;
 				break;
 			}
 
-			/* always i2c write*/
 			state->data[0] = 0x08;
-			state->data[1] = msg[0].addr;
-			state->data[2] = msg[0].len;
+			state->data[1] = msg[j].addr;
+			state->data[2] = msg[j].len;
 
-			memcpy(&state->data[3], msg[0].buf, msg[0].len);
+			memcpy(&state->data[3], msg[j].buf, msg[j].len);
 
-			if (dvb_usb_generic_rw(d, state->data, msg[0].len + 3,
+			if (dvb_usb_generic_rw(d, state->data, msg[j].len + 3,
 						state->data, 1, 0) < 0)
 				err("i2c transfer failed.");
+		} // switch
+		j++;
 
-		}
-		break;
-	case 2:
-		/* always i2c read */
-		if (4 + msg[0].len > sizeof(state->data)) {
-			warn("i2c rd: len=%d is too big!\n",
-			     msg[0].len);
-			num = -EOPNOTSUPP;
-			break;
-		}
-		if (1 + msg[1].len > sizeof(state->data)) {
-			warn("i2c rd: len=%d is too big!\n",
-			     msg[1].len);
-			num = -EOPNOTSUPP;
-			break;
-		}
-
-		state->data[0] = 0x09;
-		state->data[1] = msg[0].len;
-		state->data[2] = msg[1].len;
-		state->data[3] = msg[0].addr;
-		memcpy(&state->data[4], msg[0].buf, msg[0].len);
-
-		if (dvb_usb_generic_rw(d, state->data, msg[0].len + 4,
-					state->data, msg[1].len + 1, 0) < 0)
-			err("i2c transfer failed.");
-
-		memcpy(msg[1].buf, &state->data[1], msg[1].len);
-		break;
-	default:
-		warn("more than 2 i2c messages at a time is not handled yet.");
-		break;
-	}
+	} // while
 	mutex_unlock(&d->data_mutex);
 	mutex_unlock(&d->i2c_mutex);
 	return num;
--- linux-qcom-6.8.0.orig/drivers/media/usb/em28xx/em28xx-cards.c
+++ linux-qcom-6.8.0/drivers/media/usb/em28xx/em28xx-cards.c
@@ -4094,6 +4094,10 @@
 	 * topology will likely change after the load of the em28xx subdrivers.
 	 */
 #ifdef CONFIG_MEDIA_CONTROLLER
+	/*
+	 * No need to check the return value, the device will still be
+	 * usable without media controller API.
+	 */
 	retval = media_device_register(dev->media_dev);
 #endif
 
--- linux-qcom-6.8.0.orig/drivers/media/usb/go7007/go7007-driver.c
+++ linux-qcom-6.8.0/drivers/media/usb/go7007/go7007-driver.c
@@ -80,7 +80,7 @@
 	const struct firmware *fw_entry;
 	char fw_name[] = "go7007/go7007fw.bin";
 	void *bounce;
-	int fw_len, rv = 0;
+	int fw_len;
 	u16 intr_val, intr_data;
 
 	if (go->boot_fw == NULL) {
@@ -109,9 +109,11 @@
 	    go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
 			(intr_val & ~0x1) != 0x5a5a) {
 		v4l2_err(go, "error transferring firmware\n");
-		rv = -1;
+		kfree(go->boot_fw);
+		go->boot_fw = NULL;
+		return -1;
 	}
-	return rv;
+	return 0;
 }
 
 MODULE_FIRMWARE("go7007/go7007fw.bin");
--- linux-qcom-6.8.0.orig/drivers/media/usb/go7007/go7007-usb.c
+++ linux-qcom-6.8.0/drivers/media/usb/go7007/go7007-usb.c
@@ -1201,7 +1201,9 @@
 				u16 channel;
 
 				/* read channel number from GPIO[1:0] */
-				go7007_read_addr(go, 0x3c81, &channel);
+				if (go7007_read_addr(go, 0x3c81, &channel))
+					goto allocfail;
+
 				channel &= 0x3;
 				go->board_id = GO7007_BOARDID_ADLINK_MPG24;
 				usb->board = board = &board_adlink_mpg24;
--- linux-qcom-6.8.0.orig/drivers/media/usb/gspca/ov534.c
+++ linux-qcom-6.8.0/drivers/media/usb/gspca/ov534.c
@@ -847,7 +847,7 @@
 		r = rate_1;
 		i = ARRAY_SIZE(rate_1);
 	}
-	while (--i > 0) {
+	while (--i >= 0) {
 		if (sd->frame_rate >= r->fps)
 			break;
 		r++;
--- linux-qcom-6.8.0.orig/drivers/media/usb/pvrusb2/pvrusb2-context.c
+++ linux-qcom-6.8.0/drivers/media/usb/pvrusb2/pvrusb2-context.c
@@ -90,8 +90,10 @@
 }
 
 
-static void pvr2_context_notify(struct pvr2_context *mp)
+static void pvr2_context_notify(void *ptr)
 {
+	struct pvr2_context *mp = ptr;
+
 	pvr2_context_set_notify(mp,!0);
 }
 
@@ -106,9 +108,7 @@
 		pvr2_trace(PVR2_TRACE_CTXT,
 			   "pvr2_context %p (initialize)", mp);
 		/* Finish hardware initialization */
-		if (pvr2_hdw_initialize(mp->hdw,
-					(void (*)(void *))pvr2_context_notify,
-					mp)) {
+		if (pvr2_hdw_initialize(mp->hdw, pvr2_context_notify, mp)) {
 			mp->video_stream.stream =
 				pvr2_hdw_get_video_stream(mp->hdw);
 			/* Trigger interface initialization.  By doing this
@@ -267,9 +267,9 @@
 void pvr2_context_disconnect(struct pvr2_context *mp)
 {
 	pvr2_hdw_disconnect(mp->hdw);
-	mp->disconnect_flag = !0;
 	if (!pvr2_context_shutok())
 		pvr2_context_notify(mp);
+	mp->disconnect_flag = !0;
 }
 
 
--- linux-qcom-6.8.0.orig/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
+++ linux-qcom-6.8.0/drivers/media/usb/pvrusb2/pvrusb2-dvb.c
@@ -88,8 +88,10 @@
 	return stat;
 }
 
-static void pvr2_dvb_notify(struct pvr2_dvb_adapter *adap)
+static void pvr2_dvb_notify(void *ptr)
 {
+	struct pvr2_dvb_adapter *adap = ptr;
+
 	wake_up(&adap->buffer_wait_data);
 }
 
@@ -149,7 +151,7 @@
 	}
 
 	pvr2_stream_set_callback(pvr->video_stream.stream,
-				 (pvr2_stream_callback) pvr2_dvb_notify, adap);
+				 pvr2_dvb_notify, adap);
 
 	ret = pvr2_stream_set_buffer_count(stream, PVR2_DVB_BUFFER_COUNT);
 	if (ret < 0) return ret;
--- linux-qcom-6.8.0.orig/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
+++ linux-qcom-6.8.0/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c
@@ -1033,8 +1033,10 @@
 }
 
 
-static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
+static void pvr2_v4l2_notify(void *ptr)
 {
+	struct pvr2_v4l2_fh *fhp = ptr;
+
 	wake_up(&fhp->wait_data);
 }
 
@@ -1067,7 +1069,7 @@
 
 	hdw = fh->channel.mc_head->hdw;
 	sp = fh->pdi->stream->stream;
-	pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
+	pvr2_stream_set_callback(sp, pvr2_v4l2_notify, fh);
 	pvr2_hdw_set_stream_type(hdw,fh->pdi->config);
 	if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret;
 	return pvr2_ioread_set_enabled(fh->rhp,!0);
@@ -1198,11 +1200,6 @@
 		dip->minor_type = pvr2_v4l_type_video;
 		nr_ptr = video_nr;
 		caps |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO;
-		if (!dip->stream) {
-			pr_err(KBUILD_MODNAME
-				": Failed to set up pvrusb2 v4l video dev due to missing stream instance\n");
-			return;
-		}
 		break;
 	case VFL_TYPE_VBI:
 		dip->config = pvr2_config_vbi;
--- linux-qcom-6.8.0.orig/drivers/media/usb/s2255/s2255drv.c
+++ linux-qcom-6.8.0/drivers/media/usb/s2255/s2255drv.c
@@ -247,7 +247,7 @@
 struct s2255_dev {
 	struct s2255_vc         vc[MAX_CHANNELS];
 	struct v4l2_device      v4l2_dev;
-	atomic_t                num_channels;
+	refcount_t		num_channels;
 	int			frames;
 	struct mutex		lock;	/* channels[].vdev.lock */
 	struct mutex		cmdlock; /* protects cmdbuf */
@@ -1550,11 +1550,11 @@
 		container_of(vdev, struct s2255_vc, vdev);
 
 	dprintk(dev, 4, "%s, chnls: %d\n", __func__,
-		atomic_read(&dev->num_channels));
+		refcount_read(&dev->num_channels));
 
 	v4l2_ctrl_handler_free(&vc->hdl);
 
-	if (atomic_dec_and_test(&dev->num_channels))
+	if (refcount_dec_and_test(&dev->num_channels))
 		s2255_destroy(dev);
 	return;
 }
@@ -1659,7 +1659,7 @@
 				"failed to register video device!\n");
 			break;
 		}
-		atomic_inc(&dev->num_channels);
+		refcount_inc(&dev->num_channels);
 		v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
 			  video_device_node_name(&vc->vdev));
 
@@ -1667,11 +1667,11 @@
 	pr_info("Sensoray 2255 V4L driver Revision: %s\n",
 		S2255_VERSION);
 	/* if no channels registered, return error and probe will fail*/
-	if (atomic_read(&dev->num_channels) == 0) {
+	if (refcount_read(&dev->num_channels) == 0) {
 		v4l2_device_unregister(&dev->v4l2_dev);
 		return ret;
 	}
-	if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
+	if (refcount_read(&dev->num_channels) != MAX_CHANNELS)
 		pr_warn("s2255: Not all channels available.\n");
 	return 0;
 }
@@ -2220,7 +2220,7 @@
 		goto errorFWDATA1;
 	}
 
-	atomic_set(&dev->num_channels, 0);
+	refcount_set(&dev->num_channels, 0);
 	dev->pid = id->idProduct;
 	dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
 	if (!dev->fw_data)
@@ -2340,12 +2340,12 @@
 {
 	struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
 	int i;
-	int channels = atomic_read(&dev->num_channels);
+	int channels = refcount_read(&dev->num_channels);
 	mutex_lock(&dev->lock);
 	v4l2_device_disconnect(&dev->v4l2_dev);
 	mutex_unlock(&dev->lock);
 	/*see comments in the uvc_driver.c usb disconnect function */
-	atomic_inc(&dev->num_channels);
+	refcount_inc(&dev->num_channels);
 	/* unregister each video device. */
 	for (i = 0; i < channels; i++)
 		video_unregister_device(&dev->vc[i].vdev);
@@ -2358,7 +2358,7 @@
 		dev->vc[i].vidstatus_ready = 1;
 		wake_up(&dev->vc[i].wait_vidstatus);
 	}
-	if (atomic_dec_and_test(&dev->num_channels))
+	if (refcount_dec_and_test(&dev->num_channels))
 		s2255_destroy(dev);
 	dev_info(&interface->dev, "%s\n", __func__);
 }
--- linux-qcom-6.8.0.orig/drivers/media/usb/stk1160/stk1160-video.c
+++ linux-qcom-6.8.0/drivers/media/usb/stk1160/stk1160-video.c
@@ -99,7 +99,7 @@
 static inline
 void stk1160_copy_video(struct stk1160 *dev, u8 *src, int len)
 {
-	int linesdone, lineoff, lencopy;
+	int linesdone, lineoff, lencopy, offset;
 	int bytesperline = dev->width * 2;
 	struct stk1160_buffer *buf = dev->isoc_ctl.buf;
 	u8 *dst = buf->mem;
@@ -139,8 +139,13 @@
 	 * Check if we have enough space left in the buffer.
 	 * In that case, we force loop exit after copy.
 	 */
-	if (lencopy > buf->bytesused - buf->length) {
-		lencopy = buf->bytesused - buf->length;
+	offset = dst - (u8 *)buf->mem;
+	if (offset > buf->length) {
+		dev_warn_ratelimited(dev->dev, "out of bounds offset\n");
+		return;
+	}
+	if (lencopy > buf->length - offset) {
+		lencopy = buf->length - offset;
 		remain = lencopy;
 	}
 
@@ -182,8 +187,13 @@
 		 * Check if we have enough space left in the buffer.
 		 * In that case, we force loop exit after copy.
 		 */
-		if (lencopy > buf->bytesused - buf->length) {
-			lencopy = buf->bytesused - buf->length;
+		offset = dst - (u8 *)buf->mem;
+		if (offset > buf->length) {
+			dev_warn_ratelimited(dev->dev, "offset out of bounds\n");
+			return;
+		}
+		if (lencopy > buf->length - offset) {
+			lencopy = buf->length - offset;
 			remain = lencopy;
 		}
 
--- linux-qcom-6.8.0.orig/drivers/media/usb/usbtv/usbtv-video.c
+++ linux-qcom-6.8.0/drivers/media/usb/usbtv/usbtv-video.c
@@ -963,15 +963,8 @@
 
 void usbtv_video_free(struct usbtv *usbtv)
 {
-	mutex_lock(&usbtv->vb2q_lock);
-	mutex_lock(&usbtv->v4l2_lock);
-
-	usbtv_stop(usbtv);
 	vb2_video_unregister_device(&usbtv->vdev);
 	v4l2_device_disconnect(&usbtv->v4l2_dev);
 
-	mutex_unlock(&usbtv->v4l2_lock);
-	mutex_unlock(&usbtv->vb2q_lock);
-
 	v4l2_device_put(&usbtv->v4l2_dev);
 }
--- linux-qcom-6.8.0.orig/drivers/media/usb/uvc/uvc_ctrl.c
+++ linux-qcom-6.8.0/drivers/media/usb/uvc/uvc_ctrl.c
@@ -1532,6 +1532,40 @@
 	uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes);
 }
 
+static void uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl,
+				struct uvc_fh *new_handle)
+{
+	lockdep_assert_held(&handle->chain->ctrl_mutex);
+
+	if (new_handle) {
+		if (ctrl->handle)
+			dev_warn_ratelimited(&handle->stream->dev->udev->dev,
+					     "UVC non compliance: Setting an async control with a pending operation.");
+
+		if (new_handle == ctrl->handle)
+			return;
+
+		if (ctrl->handle) {
+			WARN_ON(!ctrl->handle->pending_async_ctrls);
+			if (ctrl->handle->pending_async_ctrls)
+				ctrl->handle->pending_async_ctrls--;
+		}
+
+		ctrl->handle = new_handle;
+		handle->pending_async_ctrls++;
+		return;
+	}
+
+	/* Cannot clear the handle for a control not owned by us.*/
+	if (WARN_ON(ctrl->handle != handle))
+		return;
+
+	ctrl->handle = NULL;
+	if (WARN_ON(!handle->pending_async_ctrls))
+		return;
+	handle->pending_async_ctrls--;
+}
+
 void uvc_ctrl_status_event(struct uvc_video_chain *chain,
 			   struct uvc_control *ctrl, const u8 *data)
 {
@@ -1542,7 +1576,8 @@
 	mutex_lock(&chain->ctrl_mutex);
 
 	handle = ctrl->handle;
-	ctrl->handle = NULL;
+	if (handle)
+		uvc_ctrl_set_handle(handle, ctrl, NULL);
 
 	list_for_each_entry(mapping, &ctrl->info.mappings, list) {
 		s32 value = __uvc_ctrl_get_value(mapping, data);
@@ -1593,10 +1628,8 @@
 	struct uvc_device *dev = chain->dev;
 	struct uvc_ctrl_work *w = &dev->async_ctrl;
 
-	if (list_empty(&ctrl->info.mappings)) {
-		ctrl->handle = NULL;
+	if (list_empty(&ctrl->info.mappings))
 		return false;
-	}
 
 	w->data = data;
 	w->urb = urb;
@@ -1626,13 +1659,13 @@
 {
 	struct uvc_control_mapping *mapping;
 	struct uvc_control *ctrl;
-	u32 changes = V4L2_EVENT_CTRL_CH_VALUE;
 	unsigned int i;
 	unsigned int j;
 
 	for (i = 0; i < xctrls_count; ++i) {
-		ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping);
+		u32 changes = V4L2_EVENT_CTRL_CH_VALUE;
 
+		ctrl = uvc_find_control(handle->chain, xctrls[i].id, &mapping);
 		if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
 			/* Notification will be sent from an Interrupt event. */
 			continue;
@@ -1764,7 +1797,10 @@
 }
 
 static int uvc_ctrl_commit_entity(struct uvc_device *dev,
-	struct uvc_entity *entity, int rollback, struct uvc_control **err_ctrl)
+				  struct uvc_fh *handle,
+				  struct uvc_entity *entity,
+				  int rollback,
+				  struct uvc_control **err_ctrl)
 {
 	struct uvc_control *ctrl;
 	unsigned int i;
@@ -1812,6 +1848,10 @@
 				*err_ctrl = ctrl;
 			return ret;
 		}
+
+		if (!rollback && handle &&
+		    ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
+			uvc_ctrl_set_handle(handle, ctrl, handle);
 	}
 
 	return 0;
@@ -1848,18 +1888,20 @@
 
 	/* Find the control. */
 	list_for_each_entry(entity, &chain->entities, chain) {
-		ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback,
-					     &err_ctrl);
-		if (ret < 0)
+		ret = uvc_ctrl_commit_entity(chain->dev, handle, entity,
+					     rollback, &err_ctrl);
+		if (ret < 0) {
+			if (ctrls)
+				ctrls->error_idx =
+					uvc_ctrl_find_ctrl_idx(entity, ctrls,
+							       err_ctrl);
 			goto done;
+		}
 	}
 
 	if (!rollback)
 		uvc_ctrl_send_events(handle, ctrls->controls, ctrls->count);
 done:
-	if (ret < 0 && ctrls)
-		ctrls->error_idx = uvc_ctrl_find_ctrl_idx(entity, ctrls,
-							  err_ctrl);
 	mutex_unlock(&chain->ctrl_mutex);
 	return ret;
 }
@@ -1997,9 +2039,6 @@
 	mapping->set(mapping, value,
 		uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
 
-	if (ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS)
-		ctrl->handle = handle;
-
 	ctrl->dirty = 1;
 	ctrl->modified = 1;
 	return 0;
@@ -2029,7 +2068,13 @@
 	else
 		ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id,
 				     dev->intfnum, info->selector, data, 1);
-	if (!ret)
+
+	if (!ret) {
+		info->flags &= ~(UVC_CTRL_FLAG_GET_CUR |
+				 UVC_CTRL_FLAG_SET_CUR |
+				 UVC_CTRL_FLAG_AUTO_UPDATE |
+				 UVC_CTRL_FLAG_ASYNCHRONOUS);
+
 		info->flags |= (data[0] & UVC_CONTROL_CAP_GET ?
 				UVC_CTRL_FLAG_GET_CUR : 0)
 			    |  (data[0] & UVC_CONTROL_CAP_SET ?
@@ -2038,6 +2083,7 @@
 				UVC_CTRL_FLAG_AUTO_UPDATE : 0)
 			    |  (data[0] & UVC_CONTROL_CAP_ASYNCHRONOUS ?
 				UVC_CTRL_FLAG_ASYNCHRONOUS : 0);
+	}
 
 	kfree(data);
 	return ret;
@@ -2165,7 +2211,7 @@
 int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
 	struct uvc_xu_control_query *xqry)
 {
-	struct uvc_entity *entity;
+	struct uvc_entity *entity, *iter;
 	struct uvc_control *ctrl;
 	unsigned int i;
 	bool found;
@@ -2175,16 +2221,16 @@
 	int ret;
 
 	/* Find the extension unit. */
-	found = false;
-	list_for_each_entry(entity, &chain->entities, chain) {
-		if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
-		    entity->id == xqry->unit) {
-			found = true;
+	entity = NULL;
+	list_for_each_entry(iter, &chain->entities, chain) {
+		if (UVC_ENTITY_TYPE(iter) == UVC_VC_EXTENSION_UNIT &&
+		    iter->id == xqry->unit) {
+			entity = iter;
 			break;
 		}
 	}
 
-	if (!found) {
+	if (!entity) {
 		uvc_dbg(chain->dev, CONTROL, "Extension unit %u not found\n",
 			xqry->unit);
 		return -ENOENT;
@@ -2321,7 +2367,7 @@
 			ctrl->dirty = 1;
 		}
 
-		ret = uvc_ctrl_commit_entity(dev, entity, 0, NULL);
+		ret = uvc_ctrl_commit_entity(dev, NULL, entity, 0, NULL);
 		if (ret < 0)
 			return ret;
 	}
@@ -2743,6 +2789,26 @@
 	return 0;
 }
 
+void uvc_ctrl_cleanup_fh(struct uvc_fh *handle)
+{
+	struct uvc_entity *entity;
+
+	guard(mutex)(&handle->chain->ctrl_mutex);
+
+	if (!handle->pending_async_ctrls)
+		return;
+
+	list_for_each_entry(entity, &handle->chain->dev->entities, list) {
+		for (unsigned int i = 0; i < entity->ncontrols; ++i) {
+			if (entity->controls[i].handle != handle)
+				continue;
+			uvc_ctrl_set_handle(handle, &entity->controls[i], NULL);
+		}
+	}
+
+	WARN_ON(handle->pending_async_ctrls);
+}
+
 /*
  * Cleanup device controls.
  */
--- linux-qcom-6.8.0.orig/drivers/media/usb/uvc/uvc_driver.c
+++ linux-qcom-6.8.0/drivers/media/usb/uvc/uvc_driver.c
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/usb.h>
+#include <linux/usb/quirks.h>
 #include <linux/usb/uvc.h>
 #include <linux/videodev2.h>
 #include <linux/vmalloc.h>
@@ -370,7 +371,7 @@
 	 * Parse the frame descriptors. Only uncompressed, MJPEG and frame
 	 * based formats have frame descriptors.
 	 */
-	while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
+	while (ftype && buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
 	       buffer[2] == ftype) {
 		unsigned int maxIntervalIndex;
 
@@ -686,16 +687,26 @@
 		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);
+
 	format = kzalloc(size, GFP_KERNEL);
-	if (format == NULL) {
+	if (!format) {
 		ret = -ENOMEM;
 		goto error;
 	}
 
-	frame = (struct uvc_frame *)&format[nformats];
-	interval = (u32 *)&frame[nframes];
+	frame = (void *)format + nformats * sizeof(*format);
+	frame = PTR_ALIGN(frame, __alignof__(*frame));
+	interval = (void *)frame + nframes * sizeof(*frame);
+	interval = PTR_ALIGN(interval, __alignof__(*interval));
 
 	streaming->formats = format;
 	streaming->nformats = 0;
@@ -1269,14 +1280,14 @@
 	struct gpio_desc *gpio_privacy;
 	int irq;
 
-	gpio_privacy = devm_gpiod_get_optional(&dev->udev->dev, "privacy",
+	gpio_privacy = devm_gpiod_get_optional(&dev->intf->dev, "privacy",
 					       GPIOD_IN);
 	if (IS_ERR_OR_NULL(gpio_privacy))
 		return PTR_ERR_OR_ZERO(gpio_privacy);
 
 	irq = gpiod_to_irq(gpio_privacy);
 	if (irq < 0)
-		return dev_err_probe(&dev->udev->dev, irq,
+		return dev_err_probe(&dev->intf->dev, irq,
 				     "No IRQ for privacy GPIO\n");
 
 	unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1);
@@ -1302,15 +1313,27 @@
 static int uvc_gpio_init_irq(struct uvc_device *dev)
 {
 	struct uvc_entity *unit = dev->gpio_unit;
+	int ret;
 
 	if (!unit || unit->gpio.irq < 0)
 		return 0;
 
-	return devm_request_threaded_irq(&dev->udev->dev, unit->gpio.irq, NULL,
-					 uvc_gpio_irq,
-					 IRQF_ONESHOT | IRQF_TRIGGER_FALLING |
-					 IRQF_TRIGGER_RISING,
-					 "uvc_privacy_gpio", dev);
+	ret = request_threaded_irq(unit->gpio.irq, NULL, uvc_gpio_irq,
+				   IRQF_ONESHOT | IRQF_TRIGGER_FALLING |
+				   IRQF_TRIGGER_RISING,
+				   "uvc_privacy_gpio", dev);
+
+	unit->gpio.initialized = !ret;
+
+	return ret;
+}
+
+static void uvc_gpio_deinit(struct uvc_device *dev)
+{
+	if (!dev->gpio_unit || !dev->gpio_unit->gpio.initialized)
+		return;
+
+	free_irq(dev->gpio_unit->gpio.irq, dev);
 }
 
 /* ------------------------------------------------------------------------
@@ -1907,12 +1930,44 @@
 {
 	struct uvc_streaming *stream;
 
+	uvc_gpio_deinit(dev);
+
 	list_for_each_entry(stream, &dev->streams, list) {
+		/* Nothing to do here, continue. */
 		if (!video_is_registered(&stream->vdev))
 			continue;
 
+		/*
+		 * For stream->vdev we follow the same logic as:
+		 * vb2_video_unregister_device().
+		 */
+
+		/* 1. Take a reference to vdev */
+		get_device(&stream->vdev.dev);
+
+		/* 2. Ensure that no new ioctls can be called. */
 		video_unregister_device(&stream->vdev);
-		video_unregister_device(&stream->meta.vdev);
+
+		/* 3. Wait for old ioctls to finish. */
+		mutex_lock(&stream->mutex);
+
+		/* 4. Stop streaming. */
+		uvc_queue_release(&stream->queue);
+
+		mutex_unlock(&stream->mutex);
+
+		put_device(&stream->vdev.dev);
+
+		/*
+		 * For stream->meta.vdev we can directly call:
+		 * vb2_video_unregister_device().
+		 */
+		vb2_video_unregister_device(&stream->meta.vdev);
+
+		/*
+		 * Now both vdevs are not streaming and all the ioctls will
+		 * return -ENODEV.
+		 */
 
 		uvc_debugfs_cleanup_stream(stream);
 	}
@@ -2232,8 +2287,14 @@
 		goto error;
 	}
 
+	if (dev->quirks & UVC_QUIRK_NO_RESET_RESUME)
+		udev->quirks &= ~USB_QUIRK_RESET_RESUME;
+
+	if (!(dev->quirks & UVC_QUIRK_DISABLE_AUTOSUSPEND))
+		usb_enable_autosuspend(udev);
+
 	uvc_dbg(dev, PROBE, "UVC device initialized\n");
-	usb_enable_autosuspend(udev);
+
 	return 0;
 
 error:
@@ -2425,6 +2486,8 @@
  * The Logitech cameras listed below have their interface class set to
  * VENDOR_SPEC because they don't announce themselves as UVC devices, even
  * though they are compliant.
+ *
+ * Sort these by vendor/product ID.
  */
 static const struct usb_device_id uvc_ids[] = {
 	/* Quanta USB2.0 HD UVC Webcam */
@@ -2454,6 +2517,39 @@
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= UVC_PC_PROTOCOL_15,
 	  .driver_info		= (kernel_ulong_t)&uvc_ctrl_power_line_limited },
+	/* Quanta ACER HD User Facing */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x0408,
+	  .idProduct		= 0x4033,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= UVC_PC_PROTOCOL_15,
+	  .driver_info		= (kernel_ulong_t)&(const struct uvc_device_info){
+		.uvc_version = 0x010a,
+	  } },
+	/* Quanta ACER HD User Facing */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x0408,
+	  .idProduct		= 0x4033,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= UVC_PC_PROTOCOL_15,
+	  .driver_info		= (kernel_ulong_t)&(const struct uvc_device_info){
+		.uvc_version = 0x010a,
+	  } },
+	/* Quanta ACER HD User Facing */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x0408,
+	  .idProduct		= 0x4035,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= UVC_PC_PROTOCOL_15,
+	  .driver_info		= (kernel_ulong_t)&(const struct uvc_device_info){
+		.uvc_version = 0x010a,
+	  } },
 	/* LogiLink Wireless Webcam */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2573,7 +2669,44 @@
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
-	  .driver_info		= UVC_INFO_QUIRK(UVC_QUIRK_RESTORE_CTRLS_ON_INIT) },
+	  .driver_info		= UVC_INFO_QUIRK(UVC_QUIRK_RESTORE_CTRLS_ON_INIT
+					       | UVC_QUIRK_INVALID_DEVICE_SOF) },
+	/* Logitech HD Pro Webcam C922 */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x046d,
+	  .idProduct		= 0x085c,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_INFO_QUIRK(UVC_QUIRK_INVALID_DEVICE_SOF) },
+	/* Logitech Rally Bar Huddle */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x046d,
+	  .idProduct		= 0x087c,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_INFO_QUIRK(UVC_QUIRK_NO_RESET_RESUME) },
+	/* Logitech Rally Bar */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x046d,
+	  .idProduct		= 0x089b,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_INFO_QUIRK(UVC_QUIRK_NO_RESET_RESUME) },
+	/* Logitech Rally Bar Mini */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x046d,
+	  .idProduct		= 0x08d3,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_INFO_QUIRK(UVC_QUIRK_NO_RESET_RESUME) },
 	/* Chicony CNF7129 (Asus EEE 100HE) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2976,6 +3109,15 @@
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
 					| UVC_QUIRK_IGNORE_SELECTOR_UNIT) },
+	/* NXP Semiconductors IR VIDEO */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x1fc9,
+	  .idProduct		= 0x009b,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= (kernel_ulong_t)&uvc_quirk_probe_minmax },
 	/* Oculus VR Positional Tracker DK2 */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -3012,6 +3154,15 @@
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= UVC_PC_PROTOCOL_15,
 	  .driver_info		= (kernel_ulong_t)&uvc_ctrl_power_line_uvc11 },
+	/* Insta360 Link */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x2e1a,
+	  .idProduct		= 0x4c01,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_INFO_QUIRK(UVC_QUIRK_DISABLE_AUTOSUSPEND) },
 	/* Lenovo Integrated Camera */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -3119,6 +3270,15 @@
 	  .bInterfaceClass	= USB_CLASS_VIDEO,
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_INFO_META(V4L2_META_FMT_D4XX) },
+	/* Intel D421 Depth Module */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x8086,
+	  .idProduct		= 0x1155,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_INFO_META(V4L2_META_FMT_D4XX) },
 	/* Generic USB Video Class */
 	{ USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
--- linux-qcom-6.8.0.orig/drivers/media/usb/uvc/uvc_queue.c
+++ linux-qcom-6.8.0/drivers/media/usb/uvc/uvc_queue.c
@@ -483,7 +483,8 @@
 
 	buf->state = buf->error ? UVC_BUF_STATE_ERROR : UVC_BUF_STATE_DONE;
 	vb2_set_plane_payload(&buf->buf.vb2_buf, 0, buf->bytesused);
-	vb2_buffer_done(&buf->buf.vb2_buf, VB2_BUF_STATE_DONE);
+	vb2_buffer_done(&buf->buf.vb2_buf, buf->error ? VB2_BUF_STATE_ERROR :
+							VB2_BUF_STATE_DONE);
 }
 
 /*
--- linux-qcom-6.8.0.orig/drivers/media/usb/uvc/uvc_status.c
+++ linux-qcom-6.8.0/drivers/media/usb/uvc/uvc_status.c
@@ -269,6 +269,7 @@
 	dev->int_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!dev->int_urb) {
 		kfree(dev->status);
+		dev->status = NULL;
 		return -ENOMEM;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/media/usb/uvc/uvc_v4l2.c
+++ linux-qcom-6.8.0/drivers/media/usb/uvc/uvc_v4l2.c
@@ -659,6 +659,8 @@
 
 	uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
 
+	uvc_ctrl_cleanup_fh(handle);
+
 	/* Only free resources if this is a privileged handle. */
 	if (uvc_has_privileges(handle))
 		uvc_queue_release(&stream->queue);
--- linux-qcom-6.8.0.orig/drivers/media/usb/uvc/uvc_video.c
+++ linux-qcom-6.8.0/drivers/media/usb/uvc/uvc_video.c
@@ -79,6 +79,27 @@
 	if (likely(ret == size))
 		return 0;
 
+	/*
+	 * Some devices return shorter USB control packets than expected if the
+	 * returned value can fit in less bytes. Zero all the bytes that the
+	 * device has not written.
+	 *
+	 * This quirk is applied to all controls, regardless of their data type.
+	 * Most controls are little-endian integers, in which case the missing
+	 * bytes become 0 MSBs. For other data types, a different heuristic
+	 * could be implemented if a device is found needing it.
+	 *
+	 * We exclude UVC_GET_INFO from the quirk. UVC_GET_LEN does not need
+	 * to be excluded because its size is always 1.
+	 */
+	if (ret > 0 && query != UVC_GET_INFO) {
+		memset(data + ret, 0, size - ret);
+		dev_warn_once(&dev->udev->dev,
+			      "UVC non compliance: %s control %u on unit %u returned %d bytes when we expected %u.\n",
+			      uvc_query_name(query), cs, unit, ret, size);
+		return 0;
+	}
+
 	if (ret != -EPIPE) {
 		dev_err(&dev->udev->dev,
 			"Failed to query (%s) UVC control %u on unit %u: %d (exp. %u).\n",
@@ -214,13 +235,13 @@
 		 * Compute a bandwidth estimation by multiplying the frame
 		 * size by the number of video frames per second, divide the
 		 * result by the number of USB frames (or micro-frames for
-		 * high-speed devices) per second and add the UVC header size
-		 * (assumed to be 12 bytes long).
+		 * high- and super-speed devices) per second and add the UVC
+		 * header size (assumed to be 12 bytes long).
 		 */
 		bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp;
 		bandwidth *= 10000000 / interval + 1;
 		bandwidth /= 1000;
-		if (stream->dev->udev->speed == USB_SPEED_HIGH)
+		if (stream->dev->udev->speed >= USB_SPEED_HIGH)
 			bandwidth /= 8;
 		bandwidth += 12;
 
@@ -478,6 +499,7 @@
 	ktime_t time;
 	u16 host_sof;
 	u16 dev_sof;
+	u32 dev_stc;
 
 	switch (data[1] & (UVC_STREAM_PTS | UVC_STREAM_SCR)) {
 	case UVC_STREAM_PTS | UVC_STREAM_SCR:
@@ -526,9 +548,48 @@
 	if (dev_sof == stream->clock.last_sof)
 		return;
 
+	dev_stc = get_unaligned_le32(&data[header_size - 6]);
+
+	/*
+	 * STC (Source Time Clock) is the clock used by the camera. The UVC 1.5
+	 * standard states that it "must be captured when the first video data
+	 * of a video frame is put on the USB bus". This is generally understood
+	 * as requiring devices to clear the payload header's SCR bit before
+	 * the first packet containing video data.
+	 *
+	 * Most vendors follow that interpretation, but some (namely SunplusIT
+	 * on some devices) always set the `UVC_STREAM_SCR` bit, fill the SCR
+	 * field with 0's,and expect that the driver only processes the SCR if
+	 * there is data in the packet.
+	 *
+	 * Ignore all the hardware timestamp information if we haven't received
+	 * any data for this frame yet, the packet contains no data, and both
+	 * STC and SOF are zero. This heuristics should be safe on compliant
+	 * devices. This should be safe with compliant devices, as in the very
+	 * unlikely case where a UVC 1.1 device would send timing information
+	 * only before the first packet containing data, and both STC and SOF
+	 * happen to be zero for a particular frame, we would only miss one
+	 * clock sample from many and the clock recovery algorithm wouldn't
+	 * suffer from this condition.
+	 */
+	if (buf && buf->bytesused == 0 && len == header_size &&
+	    dev_stc == 0 && dev_sof == 0)
+		return;
+
 	stream->clock.last_sof = dev_sof;
 
 	host_sof = usb_get_current_frame_number(stream->dev->udev);
+
+	/*
+	 * On some devices, like the Logitech C922, the device SOF does not run
+	 * at a stable rate of 1kHz. For those devices use the host SOF instead.
+	 * In the tests performed so far, this improves the timestamp precision.
+	 * This is probably explained by a small packet handling jitter from the
+	 * host, but the exact reason hasn't been fully determined.
+	 */
+	if (stream->dev->quirks & UVC_QUIRK_INVALID_DEVICE_SOF)
+		dev_sof = host_sof;
+
 	time = uvc_video_get_time();
 
 	/*
@@ -564,7 +625,7 @@
 	spin_lock_irqsave(&stream->clock.lock, flags);
 
 	sample = &stream->clock.samples[stream->clock.head];
-	sample->dev_stc = get_unaligned_le32(&data[header_size - 6]);
+	sample->dev_stc = dev_stc;
 	sample->dev_sof = dev_sof;
 	sample->host_sof = host_sof;
 	sample->host_time = time;
@@ -709,11 +770,11 @@
 	unsigned long flags;
 	u64 timestamp;
 	u32 delta_stc;
-	u32 y1, y2;
+	u32 y1;
 	u32 x1, x2;
 	u32 mean;
 	u32 sof;
-	u64 y;
+	u64 y, y2;
 
 	if (!uvc_hw_timestamps_param)
 		return;
@@ -753,7 +814,7 @@
 	sof = y;
 
 	uvc_dbg(stream->dev, CLOCK,
-		"%s: PTS %u y %llu.%06llu SOF %u.%06llu (x1 %u x2 %u y1 %u y2 %u SOF offset %u)\n",
+		"%s: PTS %u y %llu.%06llu SOF %u.%06llu (x1 %u x2 %u y1 %u y2 %llu SOF offset %u)\n",
 		stream->dev->name, buf->pts,
 		y >> 16, div_u64((y & 0xffff) * 1000000, 65536),
 		sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536),
@@ -768,7 +829,7 @@
 		goto done;
 
 	y1 = NSEC_PER_SEC;
-	y2 = (u32)ktime_to_ns(ktime_sub(last->host_time, first->host_time)) + y1;
+	y2 = ktime_to_ns(ktime_sub(last->host_time, first->host_time)) + y1;
 
 	/*
 	 * Interpolated and host SOF timestamps can wrap around at slightly
@@ -789,7 +850,7 @@
 	timestamp = ktime_to_ns(first->host_time) + y - y1;
 
 	uvc_dbg(stream->dev, CLOCK,
-		"%s: SOF %u.%06llu y %llu ts %llu buf ts %llu (x1 %u/%u/%u x2 %u/%u/%u y1 %u y2 %u)\n",
+		"%s: SOF %u.%06llu y %llu ts %llu buf ts %llu (x1 %u/%u/%u x2 %u/%u/%u y1 %u y2 %llu)\n",
 		stream->dev->name,
 		sof >> 16, div_u64(((u64)sof & 0xffff) * 1000000LLU, 65536),
 		y, timestamp, vbuf->vb2_buf.timestamp,
--- linux-qcom-6.8.0.orig/drivers/media/usb/uvc/uvcvideo.h
+++ linux-qcom-6.8.0/drivers/media/usb/uvc/uvcvideo.h
@@ -73,6 +73,9 @@
 #define UVC_QUIRK_FORCE_Y8		0x00000800
 #define UVC_QUIRK_FORCE_BPP		0x00001000
 #define UVC_QUIRK_WAKE_AUTOSUSPEND	0x00002000
+#define UVC_QUIRK_NO_RESET_RESUME	0x00004000
+#define UVC_QUIRK_DISABLE_AUTOSUSPEND	0x00008000
+#define UVC_QUIRK_INVALID_DEVICE_SOF	0x00010000
 
 /* Format flags */
 #define UVC_FMT_FLAG_COMPRESSED		0x00000001
@@ -226,6 +229,7 @@
 			u8  *bmControls;
 			struct gpio_desc *gpio_privacy;
 			int irq;
+			bool initialized;
 		} gpio;
 	};
 
@@ -329,7 +333,11 @@
 	struct uvc_entity *processing;		/* Processing unit */
 	struct uvc_entity *selector;		/* Selector unit */
 
-	struct mutex ctrl_mutex;		/* Protects ctrl.info */
+	struct mutex ctrl_mutex;		/*
+						 * Protects ctrl.info,
+						 * ctrl.handle and
+						 * uvc_fh.pending_async_ctrls
+						 */
 
 	struct v4l2_prio_state prio;		/* V4L2 priority state */
 	u32 caps;				/* V4L2 chain-wide caps */
@@ -604,6 +612,7 @@
 	struct uvc_video_chain *chain;
 	struct uvc_streaming *stream;
 	enum uvc_handle_state state;
+	unsigned int pending_async_ctrls;
 };
 
 struct uvc_driver {
@@ -789,6 +798,8 @@
 int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
 		      struct uvc_xu_control_query *xqry);
 
+void uvc_ctrl_cleanup_fh(struct uvc_fh *handle);
+
 /* Utility functions */
 struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts,
 					    u8 epaddr);
--- linux-qcom-6.8.0.orig/drivers/media/v4l2-core/v4l2-async.c
+++ linux-qcom-6.8.0/drivers/media/v4l2-core/v4l2-async.c
@@ -324,6 +324,9 @@
 	    sd->entity.function != MEDIA_ENT_F_FLASH)
 		return 0;
 
+	if (!n->sd)
+		return 0;
+
 	link = media_create_ancillary_link(&n->sd->entity, &sd->entity);
 
 #endif
@@ -563,6 +566,7 @@
 {
 	INIT_LIST_HEAD(&notifier->waiting_list);
 	INIT_LIST_HEAD(&notifier->done_list);
+	INIT_LIST_HEAD(&notifier->notifier_entry);
 	notifier->v4l2_dev = v4l2_dev;
 }
 EXPORT_SYMBOL(v4l2_async_nf_init);
@@ -572,6 +576,7 @@
 {
 	INIT_LIST_HEAD(&notifier->waiting_list);
 	INIT_LIST_HEAD(&notifier->done_list);
+	INIT_LIST_HEAD(&notifier->notifier_entry);
 	notifier->sd = sd;
 }
 EXPORT_SYMBOL_GPL(v4l2_async_subdev_nf_init);
@@ -618,16 +623,10 @@
 
 int v4l2_async_nf_register(struct v4l2_async_notifier *notifier)
 {
-	int ret;
-
 	if (WARN_ON(!notifier->v4l2_dev == !notifier->sd))
 		return -EINVAL;
 
-	ret = __v4l2_async_nf_register(notifier);
-	if (ret)
-		notifier->v4l2_dev = NULL;
-
-	return ret;
+	return __v4l2_async_nf_register(notifier);
 }
 EXPORT_SYMBOL(v4l2_async_nf_register);
 
@@ -639,7 +638,7 @@
 
 	v4l2_async_nf_unbind_all_subdevs(notifier);
 
-	list_del(&notifier->notifier_entry);
+	list_del_init(&notifier->notifier_entry);
 }
 
 void v4l2_async_nf_unregister(struct v4l2_async_notifier *notifier)
--- linux-qcom-6.8.0.orig/drivers/media/v4l2-core/v4l2-cci.c
+++ linux-qcom-6.8.0/drivers/media/v4l2-core/v4l2-cci.c
@@ -23,6 +23,15 @@
 	u8 buf[8];
 	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)
 		return *err;
 
@@ -32,7 +41,7 @@
 
 	ret = regmap_bulk_read(map, reg, buf, len);
 	if (ret) {
-		dev_err(regmap_get_device(map), "Error reading reg 0x%4x: %d\n",
+		dev_err(regmap_get_device(map), "Error reading reg 0x%04x: %d\n",
 			reg, ret);
 		goto out;
 	}
@@ -131,7 +140,7 @@
 
 	ret = regmap_bulk_write(map, reg, buf, len);
 	if (ret)
-		dev_err(regmap_get_device(map), "Error writing reg 0x%4x: %d\n",
+		dev_err(regmap_get_device(map), "Error writing reg 0x%04x: %d\n",
 			reg, ret);
 
 out:
--- linux-qcom-6.8.0.orig/drivers/media/v4l2-core/v4l2-ctrls-api.c
+++ linux-qcom-6.8.0/drivers/media/v4l2-core/v4l2-ctrls-api.c
@@ -753,9 +753,10 @@
 		for (i = 0; i < master->ncontrols; i++)
 			cur_to_new(master->cluster[i]);
 		ret = call_op(master, g_volatile_ctrl);
-		new_to_user(c, ctrl);
+		if (!ret)
+			ret = new_to_user(c, ctrl);
 	} else {
-		cur_to_user(c, ctrl);
+		ret = cur_to_user(c, ctrl);
 	}
 	v4l2_ctrl_unlock(master);
 	return ret;
@@ -770,7 +771,10 @@
 	if (!ctrl || !ctrl->is_int)
 		return -EINVAL;
 	ret = get_ctrl(ctrl, &c);
-	control->value = c.value;
+
+	if (!ret)
+		control->value = c.value;
+
 	return ret;
 }
 EXPORT_SYMBOL(v4l2_g_ctrl);
@@ -811,10 +815,11 @@
 	int ret;
 
 	v4l2_ctrl_lock(ctrl);
-	user_to_new(c, ctrl);
-	ret = set_ctrl(fh, ctrl, 0);
+	ret = user_to_new(c, ctrl);
+	if (!ret)
+		ret = set_ctrl(fh, ctrl, 0);
 	if (!ret)
-		cur_to_user(c, ctrl);
+		ret = cur_to_user(c, ctrl);
 	v4l2_ctrl_unlock(ctrl);
 	return ret;
 }
--- linux-qcom-6.8.0.orig/drivers/media/v4l2-core/v4l2-ctrls-defs.c
+++ linux-qcom-6.8.0/drivers/media/v4l2-core/v4l2-ctrls-defs.c
@@ -154,6 +154,7 @@
 		"Variable Bitrate",
 		"Constant Bitrate",
 		"Constant Quality",
+		"Maximum Bitrate",
 		NULL
 	};
 	static const char * const mpeg_stream_type[] = {
--- linux-qcom-6.8.0.orig/drivers/media/v4l2-core/v4l2-dev.c
+++ linux-qcom-6.8.0/drivers/media/v4l2-core/v4l2-dev.c
@@ -1036,8 +1036,10 @@
 	vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
 	vdev->dev.parent = vdev->dev_parent;
 	dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
+	mutex_lock(&videodev_lock);
 	ret = device_register(&vdev->dev);
 	if (ret < 0) {
+		mutex_unlock(&videodev_lock);
 		pr_err("%s: device_register failed\n", __func__);
 		goto cleanup;
 	}
@@ -1057,6 +1059,7 @@
 
 	/* Part 6: Activate this minor. The char device can now be used. */
 	set_bit(V4L2_FL_REGISTERED, &vdev->flags);
+	mutex_unlock(&videodev_lock);
 
 	return 0;
 
--- linux-qcom-6.8.0.orig/drivers/media/v4l2-core/v4l2-dv-timings.c
+++ linux-qcom-6.8.0/drivers/media/v4l2-core/v4l2-dv-timings.c
@@ -481,25 +481,28 @@
  * @polarities - the horizontal and vertical polarities (same as struct
  *		v4l2_bt_timings polarities).
  * @interlaced - if this flag is true, it indicates interlaced format
- * @fmt - the resulting timings.
+ * @cap - the v4l2_dv_timings_cap capabilities.
+ * @timings - the resulting timings.
  *
  * This function will attempt to detect if the given values correspond to a
  * valid CVT format. If so, then it will return true, and fmt will be filled
  * in with the found CVT timings.
  */
-bool v4l2_detect_cvt(unsigned frame_height,
-		     unsigned hfreq,
-		     unsigned vsync,
-		     unsigned active_width,
+bool v4l2_detect_cvt(unsigned int frame_height,
+		     unsigned int hfreq,
+		     unsigned int vsync,
+		     unsigned int active_width,
 		     u32 polarities,
 		     bool interlaced,
-		     struct v4l2_dv_timings *fmt)
+		     const struct v4l2_dv_timings_cap *cap,
+		     struct v4l2_dv_timings *timings)
 {
-	int  v_fp, v_bp, h_fp, h_bp, hsync;
-	int  frame_width, image_height, image_width;
+	struct v4l2_dv_timings t = {};
+	int v_fp, v_bp, h_fp, h_bp, hsync;
+	int frame_width, image_height, image_width;
 	bool reduced_blanking;
 	bool rb_v2 = false;
-	unsigned pix_clk;
+	unsigned int pix_clk;
 
 	if (vsync < 4 || vsync > 8)
 		return false;
@@ -625,36 +628,39 @@
 		h_fp = h_blank - hsync - h_bp;
 	}
 
-	fmt->type = V4L2_DV_BT_656_1120;
-	fmt->bt.polarities = polarities;
-	fmt->bt.width = image_width;
-	fmt->bt.height = image_height;
-	fmt->bt.hfrontporch = h_fp;
-	fmt->bt.vfrontporch = v_fp;
-	fmt->bt.hsync = hsync;
-	fmt->bt.vsync = vsync;
-	fmt->bt.hbackporch = frame_width - image_width - h_fp - hsync;
+	t.type = V4L2_DV_BT_656_1120;
+	t.bt.polarities = polarities;
+	t.bt.width = image_width;
+	t.bt.height = image_height;
+	t.bt.hfrontporch = h_fp;
+	t.bt.vfrontporch = v_fp;
+	t.bt.hsync = hsync;
+	t.bt.vsync = vsync;
+	t.bt.hbackporch = frame_width - image_width - h_fp - hsync;
 
 	if (!interlaced) {
-		fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync;
-		fmt->bt.interlaced = V4L2_DV_PROGRESSIVE;
+		t.bt.vbackporch = frame_height - image_height - v_fp - vsync;
+		t.bt.interlaced = V4L2_DV_PROGRESSIVE;
 	} else {
-		fmt->bt.vbackporch = (frame_height - image_height - 2 * v_fp -
+		t.bt.vbackporch = (frame_height - image_height - 2 * v_fp -
 				      2 * vsync) / 2;
-		fmt->bt.il_vbackporch = frame_height - image_height - 2 * v_fp -
-					2 * vsync - fmt->bt.vbackporch;
-		fmt->bt.il_vfrontporch = v_fp;
-		fmt->bt.il_vsync = vsync;
-		fmt->bt.flags |= V4L2_DV_FL_HALF_LINE;
-		fmt->bt.interlaced = V4L2_DV_INTERLACED;
+		t.bt.il_vbackporch = frame_height - image_height - 2 * v_fp -
+					2 * vsync - t.bt.vbackporch;
+		t.bt.il_vfrontporch = v_fp;
+		t.bt.il_vsync = vsync;
+		t.bt.flags |= V4L2_DV_FL_HALF_LINE;
+		t.bt.interlaced = V4L2_DV_INTERLACED;
 	}
 
-	fmt->bt.pixelclock = pix_clk;
-	fmt->bt.standards = V4L2_DV_BT_STD_CVT;
+	t.bt.pixelclock = pix_clk;
+	t.bt.standards = V4L2_DV_BT_STD_CVT;
 
 	if (reduced_blanking)
-		fmt->bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
+		t.bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
 
+	if (!v4l2_valid_dv_timings(&t, cap, NULL, NULL))
+		return false;
+	*timings = t;
 	return true;
 }
 EXPORT_SYMBOL_GPL(v4l2_detect_cvt);
@@ -699,22 +705,25 @@
  *		image height, so it has to be passed explicitly. Usually
  *		the native screen aspect ratio is used for this. If it
  *		is not filled in correctly, then 16:9 will be assumed.
- * @fmt - the resulting timings.
+ * @cap - the v4l2_dv_timings_cap capabilities.
+ * @timings - the resulting timings.
  *
  * This function will attempt to detect if the given values correspond to a
  * valid GTF format. If so, then it will return true, and fmt will be filled
  * in with the found GTF timings.
  */
-bool v4l2_detect_gtf(unsigned frame_height,
-		unsigned hfreq,
-		unsigned vsync,
-		u32 polarities,
-		bool interlaced,
-		struct v4l2_fract aspect,
-		struct v4l2_dv_timings *fmt)
+bool v4l2_detect_gtf(unsigned int frame_height,
+		     unsigned int hfreq,
+		     unsigned int vsync,
+		     u32 polarities,
+		     bool interlaced,
+		     struct v4l2_fract aspect,
+		     const struct v4l2_dv_timings_cap *cap,
+		     struct v4l2_dv_timings *timings)
 {
+	struct v4l2_dv_timings t = {};
 	int pix_clk;
-	int  v_fp, v_bp, h_fp, hsync;
+	int v_fp, v_bp, h_fp, hsync;
 	int frame_width, image_height, image_width;
 	bool default_gtf;
 	int h_blank;
@@ -783,36 +792,39 @@
 
 	h_fp = h_blank / 2 - hsync;
 
-	fmt->type = V4L2_DV_BT_656_1120;
-	fmt->bt.polarities = polarities;
-	fmt->bt.width = image_width;
-	fmt->bt.height = image_height;
-	fmt->bt.hfrontporch = h_fp;
-	fmt->bt.vfrontporch = v_fp;
-	fmt->bt.hsync = hsync;
-	fmt->bt.vsync = vsync;
-	fmt->bt.hbackporch = frame_width - image_width - h_fp - hsync;
+	t.type = V4L2_DV_BT_656_1120;
+	t.bt.polarities = polarities;
+	t.bt.width = image_width;
+	t.bt.height = image_height;
+	t.bt.hfrontporch = h_fp;
+	t.bt.vfrontporch = v_fp;
+	t.bt.hsync = hsync;
+	t.bt.vsync = vsync;
+	t.bt.hbackporch = frame_width - image_width - h_fp - hsync;
 
 	if (!interlaced) {
-		fmt->bt.vbackporch = frame_height - image_height - v_fp - vsync;
-		fmt->bt.interlaced = V4L2_DV_PROGRESSIVE;
+		t.bt.vbackporch = frame_height - image_height - v_fp - vsync;
+		t.bt.interlaced = V4L2_DV_PROGRESSIVE;
 	} else {
-		fmt->bt.vbackporch = (frame_height - image_height - 2 * v_fp -
+		t.bt.vbackporch = (frame_height - image_height - 2 * v_fp -
 				      2 * vsync) / 2;
-		fmt->bt.il_vbackporch = frame_height - image_height - 2 * v_fp -
-					2 * vsync - fmt->bt.vbackporch;
-		fmt->bt.il_vfrontporch = v_fp;
-		fmt->bt.il_vsync = vsync;
-		fmt->bt.flags |= V4L2_DV_FL_HALF_LINE;
-		fmt->bt.interlaced = V4L2_DV_INTERLACED;
+		t.bt.il_vbackporch = frame_height - image_height - 2 * v_fp -
+					2 * vsync - t.bt.vbackporch;
+		t.bt.il_vfrontporch = v_fp;
+		t.bt.il_vsync = vsync;
+		t.bt.flags |= V4L2_DV_FL_HALF_LINE;
+		t.bt.interlaced = V4L2_DV_INTERLACED;
 	}
 
-	fmt->bt.pixelclock = pix_clk;
-	fmt->bt.standards = V4L2_DV_BT_STD_GTF;
+	t.bt.pixelclock = pix_clk;
+	t.bt.standards = V4L2_DV_BT_STD_GTF;
 
 	if (!default_gtf)
-		fmt->bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
+		t.bt.flags |= V4L2_DV_FL_REDUCED_BLANKING;
 
+	if (!v4l2_valid_dv_timings(&t, cap, NULL, NULL))
+		return false;
+	*timings = t;
 	return true;
 }
 EXPORT_SYMBOL_GPL(v4l2_detect_gtf);
--- linux-qcom-6.8.0.orig/drivers/media/v4l2-core/v4l2-mc.c
+++ linux-qcom-6.8.0/drivers/media/v4l2-core/v4l2-mc.c
@@ -329,7 +329,7 @@
 	if (!(sink->flags & MEDIA_PAD_FL_SINK))
 		return -EINVAL;
 
-	fwnode_graph_for_each_endpoint(dev_fwnode(src_sd->dev), endpoint) {
+	fwnode_graph_for_each_endpoint(src_sd->fwnode, endpoint) {
 		struct fwnode_handle *remote_ep;
 		int src_idx, sink_idx, ret;
 		struct media_pad *src;
--- linux-qcom-6.8.0.orig/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ linux-qcom-6.8.0/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -1087,11 +1087,17 @@
 	entity->function = function;
 
 	ret = media_entity_pads_init(entity, num_pads, pads);
-	if (ret)
+	if (ret) {
+		kfree(entity->name);
+		entity->name = NULL;
 		return ret;
+	}
 	ret = media_device_register_entity(mdev, entity);
-	if (ret)
+	if (ret) {
+		kfree(entity->name);
+		entity->name = NULL;
 		return ret;
+	}
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/media/v4l2-core/v4l2-subdev.c
+++ linux-qcom-6.8.0/drivers/media/v4l2-core/v4l2-subdev.c
@@ -412,15 +412,6 @@
 	if (WARN_ON(!!sd->enabled_streams == !!enable))
 		return 0;
 
-#if IS_REACHABLE(CONFIG_LEDS_CLASS)
-	if (!IS_ERR_OR_NULL(sd->privacy_led)) {
-		if (enable)
-			led_set_brightness(sd->privacy_led,
-					   sd->privacy_led->max_brightness);
-		else
-			led_set_brightness(sd->privacy_led, 0);
-	}
-#endif
 	ret = sd->ops->video->s_stream(sd, enable);
 
 	if (!enable && ret < 0) {
@@ -428,9 +419,20 @@
 		ret = 0;
 	}
 
-	if (!ret)
+	if (!ret) {
 		sd->enabled_streams = enable ? BIT(0) : 0;
 
+#if IS_REACHABLE(CONFIG_LEDS_CLASS)
+		if (!IS_ERR_OR_NULL(sd->privacy_led)) {
+			if (enable)
+				led_set_brightness(sd->privacy_led,
+						   sd->privacy_led->max_brightness);
+			else
+				led_set_brightness(sd->privacy_led, 0);
+		}
+#endif
+	}
+
 	return ret;
 }
 
@@ -732,6 +734,7 @@
 		memset(&sel, 0, sizeof(sel));
 		sel.which = crop->which;
 		sel.pad = crop->pad;
+		sel.stream = crop->stream;
 		sel.target = V4L2_SEL_TGT_CROP;
 
 		rval = v4l2_subdev_call(
@@ -756,6 +759,7 @@
 		memset(&sel, 0, sizeof(sel));
 		sel.which = crop->which;
 		sel.pad = crop->pad;
+		sel.stream = crop->stream;
 		sel.target = V4L2_SEL_TGT_CROP;
 		sel.r = crop->rect;
 
--- linux-qcom-6.8.0.orig/drivers/memory/Kconfig
+++ linux-qcom-6.8.0/drivers/memory/Kconfig
@@ -167,7 +167,7 @@
 	  represents a coherency violation.
 
 config FSL_IFC
-	bool "Freescale IFC driver" if COMPILE_TEST
+	bool "Freescale IFC driver"
 	depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A || COMPILE_TEST
 	depends on HAS_IOMEM
 
--- linux-qcom-6.8.0.orig/drivers/memory/stm32-fmc2-ebi.c
+++ linux-qcom-6.8.0/drivers/memory/stm32-fmc2-ebi.c
@@ -181,8 +181,11 @@
 				    int cs)
 {
 	u32 bcr;
+	int ret;
 
-	regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+	ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+	if (ret)
+		return ret;
 
 	if (bcr & FMC2_BCR_MTYP)
 		return 0;
@@ -195,8 +198,11 @@
 					int cs)
 {
 	u32 bcr, val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR);
+	int ret;
 
-	regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+	ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+	if (ret)
+		return ret;
 
 	if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN)
 		return 0;
@@ -209,8 +215,11 @@
 					   int cs)
 {
 	u32 bcr;
+	int ret;
 
-	regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+	ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+	if (ret)
+		return ret;
 
 	if (bcr & FMC2_BCR_BURSTEN)
 		return 0;
@@ -223,8 +232,11 @@
 					    int cs)
 {
 	u32 bcr;
+	int ret;
 
-	regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+	ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+	if (ret)
+		return ret;
 
 	if (!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW))
 		return 0;
@@ -237,8 +249,11 @@
 				       int cs)
 {
 	u32 bcr, val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM);
+	int ret;
 
-	regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+	ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+	if (ret)
+		return ret;
 
 	if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN)
 		return 0;
@@ -251,12 +266,18 @@
 					     int cs)
 {
 	u32 bcr, bxtr, val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D);
+	int ret;
+
+	ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+	if (ret)
+		return ret;
 
-	regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
 	if (prop->reg_type == FMC2_REG_BWTR)
-		regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr);
+		ret = regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr);
 	else
-		regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr);
+		ret = regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr);
+	if (ret)
+		return ret;
 
 	if ((!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) &&
 	    ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN))
@@ -270,12 +291,19 @@
 					   int cs)
 {
 	u32 bcr, bcr1;
+	int ret;
 
-	regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
-	if (cs)
-		regmap_read(ebi->regmap, FMC2_BCR1, &bcr1);
-	else
+	ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+	if (ret)
+		return ret;
+
+	if (cs) {
+		ret = regmap_read(ebi->regmap, FMC2_BCR1, &bcr1);
+		if (ret)
+			return ret;
+	} else {
 		bcr1 = bcr;
+	}
 
 	if (bcr & FMC2_BCR_BURSTEN && (!cs || !(bcr1 & FMC2_BCR1_CCLKEN)))
 		return 0;
@@ -307,12 +335,18 @@
 {
 	u32 nb_clk_cycles = stm32_fmc2_ebi_ns_to_clock_cycles(ebi, cs, setup);
 	u32 bcr, btr, clk_period;
+	int ret;
+
+	ret = regmap_read(ebi->regmap, FMC2_BCR1, &bcr);
+	if (ret)
+		return ret;
 
-	regmap_read(ebi->regmap, FMC2_BCR1, &bcr);
 	if (bcr & FMC2_BCR1_CCLKEN || !cs)
-		regmap_read(ebi->regmap, FMC2_BTR1, &btr);
+		ret = regmap_read(ebi->regmap, FMC2_BTR1, &btr);
 	else
-		regmap_read(ebi->regmap, FMC2_BTR(cs), &btr);
+		ret = regmap_read(ebi->regmap, FMC2_BTR(cs), &btr);
+	if (ret)
+		return ret;
 
 	clk_period = FIELD_GET(FMC2_BTR_CLKDIV, btr) + 1;
 
@@ -571,11 +605,16 @@
 	if (ret)
 		return ret;
 
-	regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+	ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+	if (ret)
+		return ret;
+
 	if (prop->reg_type == FMC2_REG_BWTR)
-		regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr);
+		ret = regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr);
 	else
-		regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr);
+		ret = regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr);
+	if (ret)
+		return ret;
 
 	if ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN)
 		val = clamp_val(setup, 1, FMC2_BXTR_ADDSET_MAX);
@@ -693,11 +732,14 @@
 					    int cs, u32 setup)
 {
 	u32 old_val, new_val, pcscntr;
+	int ret;
 
 	if (setup < 1)
 		return 0;
 
-	regmap_read(ebi->regmap, FMC2_PCSCNTR, &pcscntr);
+	ret = regmap_read(ebi->regmap, FMC2_PCSCNTR, &pcscntr);
+	if (ret)
+		return ret;
 
 	/* Enable counter for the bank */
 	regmap_update_bits(ebi->regmap, FMC2_PCSCNTR,
@@ -944,17 +986,20 @@
 	regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_MBKEN, 0);
 }
 
-static void stm32_fmc2_ebi_save_setup(struct stm32_fmc2_ebi *ebi)
+static int stm32_fmc2_ebi_save_setup(struct stm32_fmc2_ebi *ebi)
 {
 	unsigned int cs;
+	int ret;
 
 	for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) {
-		regmap_read(ebi->regmap, FMC2_BCR(cs), &ebi->bcr[cs]);
-		regmap_read(ebi->regmap, FMC2_BTR(cs), &ebi->btr[cs]);
-		regmap_read(ebi->regmap, FMC2_BWTR(cs), &ebi->bwtr[cs]);
+		ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &ebi->bcr[cs]);
+		ret |= regmap_read(ebi->regmap, FMC2_BTR(cs), &ebi->btr[cs]);
+		ret |= regmap_read(ebi->regmap, FMC2_BWTR(cs), &ebi->bwtr[cs]);
+		if (ret)
+			return ret;
 	}
 
-	regmap_read(ebi->regmap, FMC2_PCSCNTR, &ebi->pcscntr);
+	return regmap_read(ebi->regmap, FMC2_PCSCNTR, &ebi->pcscntr);
 }
 
 static void stm32_fmc2_ebi_set_setup(struct stm32_fmc2_ebi *ebi)
@@ -983,22 +1028,29 @@
 }
 
 /* NWAIT signal can not be connected to EBI controller and NAND controller */
-static bool stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi)
+static int stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi)
 {
+	struct device *dev = ebi->dev;
 	unsigned int cs;
 	u32 bcr;
+	int ret;
 
 	for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) {
 		if (!(ebi->bank_assigned & BIT(cs)))
 			continue;
 
-		regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+		ret = regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr);
+		if (ret)
+			return ret;
+
 		if ((bcr & FMC2_BCR_WAITEN || bcr & FMC2_BCR_ASYNCWAIT) &&
-		    ebi->bank_assigned & BIT(FMC2_NAND))
-			return true;
+		    ebi->bank_assigned & BIT(FMC2_NAND)) {
+			dev_err(dev, "NWAIT signal connected to EBI and NAND controllers\n");
+			return -EINVAL;
+		}
 	}
 
-	return false;
+	return 0;
 }
 
 static void stm32_fmc2_ebi_enable(struct stm32_fmc2_ebi *ebi)
@@ -1085,10 +1137,9 @@
 		return -ENODEV;
 	}
 
-	if (stm32_fmc2_ebi_nwait_used_by_ctrls(ebi)) {
-		dev_err(dev, "NWAIT signal connected to EBI and NAND controllers\n");
-		return -EINVAL;
-	}
+	ret = stm32_fmc2_ebi_nwait_used_by_ctrls(ebi);
+	if (ret)
+		return ret;
 
 	stm32_fmc2_ebi_enable(ebi);
 
@@ -1133,7 +1184,10 @@
 	if (ret)
 		goto err_release;
 
-	stm32_fmc2_ebi_save_setup(ebi);
+	ret = stm32_fmc2_ebi_save_setup(ebi);
+	if (ret)
+		goto err_release;
+
 	platform_set_drvdata(pdev, ebi);
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/memory/tegra/tegra186-emc.c
+++ linux-qcom-6.8.0/drivers/memory/tegra/tegra186-emc.c
@@ -35,11 +35,6 @@
 	struct icc_provider provider;
 };
 
-static inline struct tegra186_emc *to_tegra186_emc(struct icc_provider *provider)
-{
-	return container_of(provider, struct tegra186_emc, provider);
-}
-
 /*
  * debugfs interface
  *
--- linux-qcom-6.8.0.orig/drivers/memory/tegra/tegra20-emc.c
+++ linux-qcom-6.8.0/drivers/memory/tegra/tegra20-emc.c
@@ -477,14 +477,15 @@
 
 	ram_code = tegra_read_ram_code();
 
-	for (np = of_find_node_by_name(dev->of_node, "emc-tables"); np;
-	     np = of_find_node_by_name(np, "emc-tables")) {
+	for_each_child_of_node(dev->of_node, np) {
+		if (!of_node_name_eq(np, "emc-tables"))
+			continue;
 		err = of_property_read_u32(np, "nvidia,ram-code", &value);
 		if (err || value != ram_code) {
 			struct device_node *lpddr2_np;
 			bool cfg_mismatches = false;
 
-			lpddr2_np = of_find_node_by_name(np, "lpddr2");
+			lpddr2_np = of_get_child_by_name(np, "lpddr2");
 			if (lpddr2_np) {
 				const struct lpddr2_info *info;
 
@@ -521,7 +522,6 @@
 			}
 
 			if (cfg_mismatches) {
-				of_node_put(np);
 				continue;
 			}
 		}
--- linux-qcom-6.8.0.orig/drivers/memory/tegra/tegra234.c
+++ linux-qcom-6.8.0/drivers/memory/tegra/tegra234.c
@@ -121,7 +121,7 @@
 		},
 	}, {
 		.id = TEGRA234_MEMORY_CLIENT_DLA1RDB,
-		.name = "dla0rdb",
+		.name = "dla1rdb",
 		.sid = TEGRA234_SID_NVDLA1,
 		.regs = {
 			.sid = {
@@ -407,7 +407,7 @@
 		},
 	}, {
 		.id = TEGRA234_MEMORY_CLIENT_DLA1RDB1,
-		.name = "dla0rdb1",
+		.name = "dla1rdb1",
 		.sid = TEGRA234_SID_NVDLA1,
 		.regs = {
 			.sid = {
@@ -417,7 +417,7 @@
 		},
 	}, {
 		.id = TEGRA234_MEMORY_CLIENT_DLA1WRB,
-		.name = "dla0wrb",
+		.name = "dla1wrb",
 		.sid = TEGRA234_SID_NVDLA1,
 		.regs = {
 			.sid = {
@@ -699,7 +699,7 @@
 		},
 	}, {
 		.id = TEGRA234_MEMORY_CLIENT_DLA1RDA,
-		.name = "dla0rda",
+		.name = "dla1rda",
 		.sid = TEGRA234_SID_NVDLA1,
 		.regs = {
 			.sid = {
@@ -709,7 +709,7 @@
 		},
 	}, {
 		.id = TEGRA234_MEMORY_CLIENT_DLA1FALRDB,
-		.name = "dla0falrdb",
+		.name = "dla1falrdb",
 		.sid = TEGRA234_SID_NVDLA1,
 		.regs = {
 			.sid = {
@@ -719,7 +719,7 @@
 		},
 	}, {
 		.id = TEGRA234_MEMORY_CLIENT_DLA1WRA,
-		.name = "dla0wra",
+		.name = "dla1wra",
 		.sid = TEGRA234_SID_NVDLA1,
 		.regs = {
 			.sid = {
@@ -729,7 +729,7 @@
 		},
 	}, {
 		.id = TEGRA234_MEMORY_CLIENT_DLA1FALWRB,
-		.name = "dla0falwrb",
+		.name = "dla1falwrb",
 		.sid = TEGRA234_SID_NVDLA1,
 		.regs = {
 			.sid = {
@@ -917,7 +917,7 @@
 		},
 	}, {
 		.id = TEGRA234_MEMORY_CLIENT_DLA1RDA1,
-		.name = "dla0rda1",
+		.name = "dla1rda1",
 		.sid = TEGRA234_SID_NVDLA1,
 		.regs = {
 			.sid = {
--- linux-qcom-6.8.0.orig/drivers/message/fusion/mptsas.c
+++ linux-qcom-6.8.0/drivers/message/fusion/mptsas.c
@@ -4234,10 +4234,8 @@
 static void
 mptsas_reprobe_lun(struct scsi_device *sdev, void *data)
 {
-	int rc;
-
 	sdev->no_uld_attach = data ? 1 : 0;
-	rc = scsi_device_reprobe(sdev);
+	WARN_ON(scsi_device_reprobe(sdev));
 }
 
 static void
--- linux-qcom-6.8.0.orig/drivers/mfd/Kconfig
+++ linux-qcom-6.8.0/drivers/mfd/Kconfig
@@ -1107,6 +1107,17 @@
 	  Say yes here if you want to include support GPIO for pins on
 	  the PCF50633 chip.
 
+config MFD_I2C_PMIC
+	tristate "QTI I2C PMIC support"
+	depends on I2C && OF
+	select IRQ_DOMAIN
+	select REGMAP_I2C
+	help
+	 This enables support for controlling Qualcomm Technologies, Inc.
+	 PMICs over I2C. The driver controls interrupts, and provides register
+	 access for all of the device's peripherals.  Some QTI PMIC chips
+	 support communication over both I2C and SPMI.
+
 config MFD_PM8XXX
 	tristate "Qualcomm PM8xxx PMIC chips driver"
 	depends on (ARM || HEXAGON || COMPILE_TEST)
@@ -1773,6 +1784,7 @@
 	bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 Support"
 	depends on I2C=y
 	select IRQ_DOMAIN
+	select MFD_CORE
 	select REGMAP_I2C
 	help
 	  Say yes here if you have TWL4030 / TWL6030 family chip on your board.
@@ -2218,6 +2230,18 @@
 	  under it in the device tree. Additional drivers must be enabled in
 	  order to use the functionality of the device.
 
+config MFD_AAEON
+	tristate "AAEON WMI MFD devices"
+	depends on ASUS_WMI
+	depends on UBUNTU_ODM_DRIVERS
+	help
+	  Say yes here to support mltiple IO devices on Single Board Computers
+	  produced by AAEON.
+
+	  This driver leverages the ASUS WMI interface to access device
+	  resources.
+
+
 menu "Multimedia Capabilities Port drivers"
 	depends on ARCH_SA1100
 
--- linux-qcom-6.8.0.orig/drivers/mfd/Makefile
+++ linux-qcom-6.8.0/drivers/mfd/Makefile
@@ -203,6 +203,7 @@
 
 obj-$(CONFIG_MFD_CS5535)	+= cs5535-mfd.o
 obj-$(CONFIG_MFD_OMAP_USB_HOST)	+= omap-usb-host.o omap-usb-tll.o
+obj-$(CONFIG_MFD_I2C_PMIC)      += qcom-i2c-pmic.o
 obj-$(CONFIG_MFD_PM8XXX) 	+= qcom-pm8xxx.o ssbi.o
 obj-$(CONFIG_MFD_QCOM_RPM)	+= qcom_rpm.o
 obj-$(CONFIG_MFD_SPMI_PMIC)	+= qcom-spmi-pmic.o
@@ -279,8 +280,7 @@
 
 obj-$(CONFIG_MFD_ATC260X)	+= atc260x-core.o
 obj-$(CONFIG_MFD_ATC260X_I2C)	+= atc260x-i2c.o
+obj-$(CONFIG_MFD_AAEON)		+= mfd-aaeon.o
 
-rsmu-i2c-objs			:= rsmu_core.o rsmu_i2c.o
-rsmu-spi-objs			:= rsmu_core.o rsmu_spi.o
-obj-$(CONFIG_MFD_RSMU_I2C)	+= rsmu-i2c.o
-obj-$(CONFIG_MFD_RSMU_SPI)	+= rsmu-spi.o
+obj-$(CONFIG_MFD_RSMU_I2C)	+= rsmu_i2c.o rsmu_core.o
+obj-$(CONFIG_MFD_RSMU_SPI)	+= rsmu_spi.o rsmu_core.o
--- linux-qcom-6.8.0.orig/drivers/mfd/altera-sysmgr.c
+++ linux-qcom-6.8.0/drivers/mfd/altera-sysmgr.c
@@ -109,7 +109,9 @@
 
 	dev = driver_find_device_by_of_node(&altr_sysmgr_driver.driver,
 					    (void *)sysmgr_np);
-	of_node_put(sysmgr_np);
+	if (property)
+		of_node_put(sysmgr_np);
+
 	if (!dev)
 		return ERR_PTR(-EPROBE_DEFER);
 
--- linux-qcom-6.8.0.orig/drivers/mfd/cs42l43.c
+++ linux-qcom-6.8.0/drivers/mfd/cs42l43.c
@@ -84,7 +84,7 @@
 	{ CS42L43_DRV_CTRL_5,				0x136C00C0 },
 	{ CS42L43_GPIO_CTRL1,				0x00000707 },
 	{ CS42L43_GPIO_CTRL2,				0x00000000 },
-	{ CS42L43_GPIO_FN_SEL,				0x00000000 },
+	{ CS42L43_GPIO_FN_SEL,				0x00000004 },
 	{ CS42L43_MCLK_SRC_SEL,				0x00000000 },
 	{ CS42L43_SAMPLE_RATE1,				0x00000003 },
 	{ CS42L43_SAMPLE_RATE2,				0x00000003 },
@@ -131,38 +131,38 @@
 	{ CS42L43_ASP_TX_CH4_CTRL,			0x00170091 },
 	{ CS42L43_ASP_TX_CH5_CTRL,			0x001700C1 },
 	{ CS42L43_ASP_TX_CH6_CTRL,			0x001700F1 },
-	{ CS42L43_ASPTX1_INPUT,				0x00800000 },
-	{ CS42L43_ASPTX2_INPUT,				0x00800000 },
-	{ CS42L43_ASPTX3_INPUT,				0x00800000 },
-	{ CS42L43_ASPTX4_INPUT,				0x00800000 },
-	{ CS42L43_ASPTX5_INPUT,				0x00800000 },
-	{ CS42L43_ASPTX6_INPUT,				0x00800000 },
-	{ CS42L43_SWIRE_DP1_CH1_INPUT,			0x00800000 },
-	{ CS42L43_SWIRE_DP1_CH2_INPUT,			0x00800000 },
-	{ CS42L43_SWIRE_DP1_CH3_INPUT,			0x00800000 },
-	{ CS42L43_SWIRE_DP1_CH4_INPUT,			0x00800000 },
-	{ CS42L43_SWIRE_DP2_CH1_INPUT,			0x00800000 },
-	{ CS42L43_SWIRE_DP2_CH2_INPUT,			0x00800000 },
-	{ CS42L43_SWIRE_DP3_CH1_INPUT,			0x00800000 },
-	{ CS42L43_SWIRE_DP3_CH2_INPUT,			0x00800000 },
-	{ CS42L43_SWIRE_DP4_CH1_INPUT,			0x00800000 },
-	{ CS42L43_SWIRE_DP4_CH2_INPUT,			0x00800000 },
-	{ CS42L43_ASRC_INT1_INPUT1,			0x00800000 },
-	{ CS42L43_ASRC_INT2_INPUT1,			0x00800000 },
-	{ CS42L43_ASRC_INT3_INPUT1,			0x00800000 },
-	{ CS42L43_ASRC_INT4_INPUT1,			0x00800000 },
-	{ CS42L43_ASRC_DEC1_INPUT1,			0x00800000 },
-	{ CS42L43_ASRC_DEC2_INPUT1,			0x00800000 },
-	{ CS42L43_ASRC_DEC3_INPUT1,			0x00800000 },
-	{ CS42L43_ASRC_DEC4_INPUT1,			0x00800000 },
-	{ CS42L43_ISRC1INT1_INPUT1,			0x00800000 },
-	{ CS42L43_ISRC1INT2_INPUT1,			0x00800000 },
-	{ CS42L43_ISRC1DEC1_INPUT1,			0x00800000 },
-	{ CS42L43_ISRC1DEC2_INPUT1,			0x00800000 },
-	{ CS42L43_ISRC2INT1_INPUT1,			0x00800000 },
-	{ CS42L43_ISRC2INT2_INPUT1,			0x00800000 },
-	{ CS42L43_ISRC2DEC1_INPUT1,			0x00800000 },
-	{ CS42L43_ISRC2DEC2_INPUT1,			0x00800000 },
+	{ CS42L43_ASPTX1_INPUT,				0x00000000 },
+	{ CS42L43_ASPTX2_INPUT,				0x00000000 },
+	{ CS42L43_ASPTX3_INPUT,				0x00000000 },
+	{ CS42L43_ASPTX4_INPUT,				0x00000000 },
+	{ CS42L43_ASPTX5_INPUT,				0x00000000 },
+	{ CS42L43_ASPTX6_INPUT,				0x00000000 },
+	{ CS42L43_SWIRE_DP1_CH1_INPUT,			0x00000000 },
+	{ CS42L43_SWIRE_DP1_CH2_INPUT,			0x00000000 },
+	{ CS42L43_SWIRE_DP1_CH3_INPUT,			0x00000000 },
+	{ CS42L43_SWIRE_DP1_CH4_INPUT,			0x00000000 },
+	{ CS42L43_SWIRE_DP2_CH1_INPUT,			0x00000000 },
+	{ CS42L43_SWIRE_DP2_CH2_INPUT,			0x00000000 },
+	{ CS42L43_SWIRE_DP3_CH1_INPUT,			0x00000000 },
+	{ CS42L43_SWIRE_DP3_CH2_INPUT,			0x00000000 },
+	{ CS42L43_SWIRE_DP4_CH1_INPUT,			0x00000000 },
+	{ CS42L43_SWIRE_DP4_CH2_INPUT,			0x00000000 },
+	{ CS42L43_ASRC_INT1_INPUT1,			0x00000000 },
+	{ CS42L43_ASRC_INT2_INPUT1,			0x00000000 },
+	{ CS42L43_ASRC_INT3_INPUT1,			0x00000000 },
+	{ CS42L43_ASRC_INT4_INPUT1,			0x00000000 },
+	{ CS42L43_ASRC_DEC1_INPUT1,			0x00000000 },
+	{ CS42L43_ASRC_DEC2_INPUT1,			0x00000000 },
+	{ CS42L43_ASRC_DEC3_INPUT1,			0x00000000 },
+	{ CS42L43_ASRC_DEC4_INPUT1,			0x00000000 },
+	{ CS42L43_ISRC1INT1_INPUT1,			0x00000000 },
+	{ CS42L43_ISRC1INT2_INPUT1,			0x00000000 },
+	{ CS42L43_ISRC1DEC1_INPUT1,			0x00000000 },
+	{ CS42L43_ISRC1DEC2_INPUT1,			0x00000000 },
+	{ CS42L43_ISRC2INT1_INPUT1,			0x00000000 },
+	{ CS42L43_ISRC2INT2_INPUT1,			0x00000000 },
+	{ CS42L43_ISRC2DEC1_INPUT1,			0x00000000 },
+	{ CS42L43_ISRC2DEC2_INPUT1,			0x00000000 },
 	{ CS42L43_EQ1MIX_INPUT1,			0x00800000 },
 	{ CS42L43_EQ1MIX_INPUT2,			0x00800000 },
 	{ CS42L43_EQ1MIX_INPUT3,			0x00800000 },
@@ -171,8 +171,8 @@
 	{ CS42L43_EQ2MIX_INPUT2,			0x00800000 },
 	{ CS42L43_EQ2MIX_INPUT3,			0x00800000 },
 	{ CS42L43_EQ2MIX_INPUT4,			0x00800000 },
-	{ CS42L43_SPDIF1_INPUT1,			0x00800000 },
-	{ CS42L43_SPDIF2_INPUT1,			0x00800000 },
+	{ CS42L43_SPDIF1_INPUT1,			0x00000000 },
+	{ CS42L43_SPDIF2_INPUT1,			0x00000000 },
 	{ CS42L43_AMP1MIX_INPUT1,			0x00800000 },
 	{ CS42L43_AMP1MIX_INPUT2,			0x00800000 },
 	{ CS42L43_AMP1MIX_INPUT3,			0x00800000 },
@@ -217,7 +217,7 @@
 	{ CS42L43_CTRL_REG,				0x00000006 },
 	{ CS42L43_FDIV_FRAC,				0x40000000 },
 	{ CS42L43_CAL_RATIO,				0x00000080 },
-	{ CS42L43_SPI_CLK_CONFIG1,			0x00000000 },
+	{ CS42L43_SPI_CLK_CONFIG1,			0x00000001 },
 	{ CS42L43_SPI_CONFIG1,				0x00000000 },
 	{ CS42L43_SPI_CONFIG2,				0x00000000 },
 	{ CS42L43_SPI_CONFIG3,				0x00000001 },
--- linux-qcom-6.8.0.orig/drivers/mfd/da9052-spi.c
+++ linux-qcom-6.8.0/drivers/mfd/da9052-spi.c
@@ -37,7 +37,7 @@
 	spi_set_drvdata(spi, da9052);
 
 	config = da9052_regmap_config;
-	config.read_flag_mask = 1;
+	config.write_flag_mask = 1;
 	config.reg_bits = 7;
 	config.pad_bits = 1;
 	config.val_bits = 8;
--- linux-qcom-6.8.0.orig/drivers/mfd/intel-lpss-pci.c
+++ linux-qcom-6.8.0/drivers/mfd/intel-lpss-pci.c
@@ -23,12 +23,22 @@
 
 #include "intel-lpss.h"
 
-/* Some DSDTs have an unused GEXP ACPI device conflicting with I2C4 resources */
-static const struct pci_device_id ignore_resource_conflicts_ids[] = {
-	/* Microsoft Surface Go (version 1) I2C4 */
-	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, 0x9d64, 0x152d, 0x1182), },
-	/* Microsoft Surface Go 2 I2C4 */
-	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, 0x9d64, 0x152d, 0x1237), },
+static const struct pci_device_id quirk_ids[] = {
+	{
+		/* Microsoft Surface Go (version 1) I2C4 */
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, 0x9d64, 0x152d, 0x1182),
+		.driver_data = QUIRK_IGNORE_RESOURCE_CONFLICTS,
+	},
+	{
+		/* Microsoft Surface Go 2 I2C4 */
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, 0x9d64, 0x152d, 0x1237),
+		.driver_data = QUIRK_IGNORE_RESOURCE_CONFLICTS,
+	},
+	{
+		/* Dell XPS 9530 (2023) */
+		PCI_DEVICE_SUB(PCI_VENDOR_ID_INTEL, 0x51fb, 0x1028, 0x0beb),
+		.driver_data = QUIRK_CLOCK_DIVIDER_UNITY,
+	},
 	{ }
 };
 
@@ -36,6 +46,7 @@
 				const struct pci_device_id *id)
 {
 	const struct intel_lpss_platform_info *data = (void *)id->driver_data;
+	const struct pci_device_id *quirk_pci_info;
 	struct intel_lpss_platform_info *info;
 	int ret;
 
@@ -55,8 +66,9 @@
 	info->mem = pci_resource_n(pdev, 0);
 	info->irq = pci_irq_vector(pdev, 0);
 
-	if (pci_match_id(ignore_resource_conflicts_ids, pdev))
-		info->ignore_resource_conflicts = true;
+	quirk_pci_info = pci_match_id(quirk_ids, pdev);
+	if (quirk_pci_info)
+		info->quirks = quirk_pci_info->driver_data;
 
 	pdev->d3cold_delay = 0;
 
@@ -91,7 +103,7 @@
 	.properties = spt_spi_properties,
 };
 
-static const struct intel_lpss_platform_info spt_info = {
+static const struct intel_lpss_platform_info spt_spi_info = {
 	.clk_rate = 120000000,
 	.swnode = &spt_spi_node,
 };
@@ -136,7 +148,7 @@
 	.properties = bxt_spi_properties,
 };
 
-static const struct intel_lpss_platform_info bxt_info = {
+static const struct intel_lpss_platform_info bxt_spi_info = {
 	.clk_rate = 100000000,
 	.swnode = &bxt_spi_node,
 };
@@ -204,7 +216,7 @@
 	.properties = cnl_spi_properties,
 };
 
-static const struct intel_lpss_platform_info cnl_info = {
+static const struct intel_lpss_platform_info cnl_spi_info = {
 	.clk_rate = 120000000,
 	.swnode = &cnl_spi_node,
 };
@@ -228,7 +240,7 @@
 	.properties = tgl_spi_properties,
 };
 
-static const struct intel_lpss_platform_info tgl_info = {
+static const struct intel_lpss_platform_info tgl_spi_info = {
 	.clk_rate = 100000000,
 	.swnode = &tgl_spi_node,
 };
@@ -237,8 +249,8 @@
 	/* CML-LP */
 	{ PCI_VDEVICE(INTEL, 0x02a8), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x02a9), (kernel_ulong_t)&spt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x02aa), (kernel_ulong_t)&cnl_info },
-	{ PCI_VDEVICE(INTEL, 0x02ab), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0x02aa), (kernel_ulong_t)&cnl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x02ab), (kernel_ulong_t)&cnl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x02c5), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x02c6), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x02c7), (kernel_ulong_t)&spt_uart_info },
@@ -246,18 +258,18 @@
 	{ PCI_VDEVICE(INTEL, 0x02e9), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x02ea), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x02eb), (kernel_ulong_t)&cnl_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0x02fb), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0x02fb), (kernel_ulong_t)&cnl_spi_info },
 	/* CML-H */
 	{ PCI_VDEVICE(INTEL, 0x06a8), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x06a9), (kernel_ulong_t)&spt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x06aa), (kernel_ulong_t)&cnl_info },
-	{ PCI_VDEVICE(INTEL, 0x06ab), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0x06aa), (kernel_ulong_t)&cnl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x06ab), (kernel_ulong_t)&cnl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x06c7), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x06e8), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x06e9), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x06ea), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x06eb), (kernel_ulong_t)&cnl_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0x06fb), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0x06fb), (kernel_ulong_t)&cnl_spi_info },
 	/* BXT A-Step */
 	{ PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x0aae), (kernel_ulong_t)&bxt_i2c_info },
@@ -270,9 +282,9 @@
 	{ PCI_VDEVICE(INTEL, 0x0abc), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x0abe), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x0ac0), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x0ac2), (kernel_ulong_t)&bxt_info },
-	{ PCI_VDEVICE(INTEL, 0x0ac4), (kernel_ulong_t)&bxt_info },
-	{ PCI_VDEVICE(INTEL, 0x0ac6), (kernel_ulong_t)&bxt_info },
+	{ PCI_VDEVICE(INTEL, 0x0ac2), (kernel_ulong_t)&bxt_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x0ac4), (kernel_ulong_t)&bxt_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x0ac6), (kernel_ulong_t)&bxt_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x0aee), (kernel_ulong_t)&bxt_uart_info },
 	/* BXT B-Step */
 	{ PCI_VDEVICE(INTEL, 0x1aac), (kernel_ulong_t)&bxt_i2c_info },
@@ -286,9 +298,9 @@
 	{ PCI_VDEVICE(INTEL, 0x1abc), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x1abe), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x1ac0), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x1ac2), (kernel_ulong_t)&bxt_info },
-	{ PCI_VDEVICE(INTEL, 0x1ac4), (kernel_ulong_t)&bxt_info },
-	{ PCI_VDEVICE(INTEL, 0x1ac6), (kernel_ulong_t)&bxt_info },
+	{ PCI_VDEVICE(INTEL, 0x1ac2), (kernel_ulong_t)&bxt_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x1ac4), (kernel_ulong_t)&bxt_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x1ac6), (kernel_ulong_t)&bxt_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x1aee), (kernel_ulong_t)&bxt_uart_info },
 	/* EBG */
 	{ PCI_VDEVICE(INTEL, 0x1bad), (kernel_ulong_t)&bxt_uart_info },
@@ -305,15 +317,15 @@
 	{ PCI_VDEVICE(INTEL, 0x31bc), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x31be), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x31c0), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x31c2), (kernel_ulong_t)&bxt_info },
-	{ PCI_VDEVICE(INTEL, 0x31c4), (kernel_ulong_t)&bxt_info },
-	{ PCI_VDEVICE(INTEL, 0x31c6), (kernel_ulong_t)&bxt_info },
+	{ PCI_VDEVICE(INTEL, 0x31c2), (kernel_ulong_t)&bxt_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x31c4), (kernel_ulong_t)&bxt_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x31c6), (kernel_ulong_t)&bxt_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x31ee), (kernel_ulong_t)&bxt_uart_info },
 	/* ICL-LP */
 	{ PCI_VDEVICE(INTEL, 0x34a8), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x34a9), (kernel_ulong_t)&spt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x34aa), (kernel_ulong_t)&cnl_info },
-	{ PCI_VDEVICE(INTEL, 0x34ab), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0x34aa), (kernel_ulong_t)&cnl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x34ab), (kernel_ulong_t)&cnl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x34c5), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x34c6), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x34c7), (kernel_ulong_t)&spt_uart_info },
@@ -321,15 +333,15 @@
 	{ PCI_VDEVICE(INTEL, 0x34e9), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x34ea), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x34eb), (kernel_ulong_t)&bxt_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0x34fb), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0x34fb), (kernel_ulong_t)&cnl_spi_info },
 	/* ICL-N */
 	{ PCI_VDEVICE(INTEL, 0x38a8), (kernel_ulong_t)&spt_uart_info },
 	/* TGL-H */
 	{ PCI_VDEVICE(INTEL, 0x43a7), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x43a8), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x43a9), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x43aa), (kernel_ulong_t)&tgl_info },
-	{ PCI_VDEVICE(INTEL, 0x43ab), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0x43aa), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x43ab), (kernel_ulong_t)&tgl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x43ad), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x43ae), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x43d8), (kernel_ulong_t)&bxt_i2c_info },
@@ -338,14 +350,14 @@
 	{ PCI_VDEVICE(INTEL, 0x43e9), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x43ea), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x43eb), (kernel_ulong_t)&bxt_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0x43fb), (kernel_ulong_t)&tgl_info },
-	{ PCI_VDEVICE(INTEL, 0x43fd), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0x43fb), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x43fd), (kernel_ulong_t)&tgl_spi_info },
 	/* EHL */
 	{ PCI_VDEVICE(INTEL, 0x4b28), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x4b29), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x4b2a), (kernel_ulong_t)&bxt_info },
-	{ PCI_VDEVICE(INTEL, 0x4b2b), (kernel_ulong_t)&bxt_info },
-	{ PCI_VDEVICE(INTEL, 0x4b37), (kernel_ulong_t)&bxt_info },
+	{ PCI_VDEVICE(INTEL, 0x4b2a), (kernel_ulong_t)&bxt_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x4b2b), (kernel_ulong_t)&bxt_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x4b37), (kernel_ulong_t)&bxt_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x4b44), (kernel_ulong_t)&ehl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x4b45), (kernel_ulong_t)&ehl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x4b4b), (kernel_ulong_t)&ehl_i2c_info },
@@ -358,8 +370,8 @@
 	/* JSL */
 	{ PCI_VDEVICE(INTEL, 0x4da8), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x4da9), (kernel_ulong_t)&spt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x4daa), (kernel_ulong_t)&cnl_info },
-	{ PCI_VDEVICE(INTEL, 0x4dab), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0x4daa), (kernel_ulong_t)&cnl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x4dab), (kernel_ulong_t)&cnl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x4dc5), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x4dc6), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x4dc7), (kernel_ulong_t)&spt_uart_info },
@@ -367,12 +379,12 @@
 	{ PCI_VDEVICE(INTEL, 0x4de9), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x4dea), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x4deb), (kernel_ulong_t)&bxt_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0x4dfb), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0x4dfb), (kernel_ulong_t)&cnl_spi_info },
 	/* ADL-P */
 	{ PCI_VDEVICE(INTEL, 0x51a8), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x51a9), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x51aa), (kernel_ulong_t)&tgl_info },
-	{ PCI_VDEVICE(INTEL, 0x51ab), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0x51aa), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x51ab), (kernel_ulong_t)&tgl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x51c5), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x51c6), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x51c7), (kernel_ulong_t)&bxt_uart_info },
@@ -382,12 +394,12 @@
 	{ PCI_VDEVICE(INTEL, 0x51e9), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x51ea), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x51eb), (kernel_ulong_t)&bxt_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0x51fb), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0x51fb), (kernel_ulong_t)&tgl_spi_info },
 	/* ADL-M */
 	{ PCI_VDEVICE(INTEL, 0x54a8), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x54a9), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x54aa), (kernel_ulong_t)&tgl_info },
-	{ PCI_VDEVICE(INTEL, 0x54ab), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0x54aa), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x54ab), (kernel_ulong_t)&tgl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x54c5), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x54c6), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x54c7), (kernel_ulong_t)&bxt_uart_info },
@@ -395,7 +407,7 @@
 	{ PCI_VDEVICE(INTEL, 0x54e9), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x54ea), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x54eb), (kernel_ulong_t)&bxt_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0x54fb), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0x54fb), (kernel_ulong_t)&tgl_spi_info },
 	/* APL */
 	{ PCI_VDEVICE(INTEL, 0x5aac), (kernel_ulong_t)&apl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x5aae), (kernel_ulong_t)&apl_i2c_info },
@@ -408,46 +420,59 @@
 	{ PCI_VDEVICE(INTEL, 0x5abc), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x5abe), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x5ac0), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x5ac2), (kernel_ulong_t)&bxt_info },
-	{ PCI_VDEVICE(INTEL, 0x5ac4), (kernel_ulong_t)&bxt_info },
-	{ PCI_VDEVICE(INTEL, 0x5ac6), (kernel_ulong_t)&bxt_info },
+	{ PCI_VDEVICE(INTEL, 0x5ac2), (kernel_ulong_t)&bxt_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x5ac4), (kernel_ulong_t)&bxt_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x5ac6), (kernel_ulong_t)&bxt_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x5aee), (kernel_ulong_t)&bxt_uart_info },
+	/* ARL-H */
+	{ PCI_VDEVICE(INTEL, 0x7725), (kernel_ulong_t)&bxt_uart_info },
+	{ PCI_VDEVICE(INTEL, 0x7726), (kernel_ulong_t)&bxt_uart_info },
+	{ PCI_VDEVICE(INTEL, 0x7727), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x7730), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x7746), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x7750), (kernel_ulong_t)&bxt_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x7751), (kernel_ulong_t)&bxt_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x7752), (kernel_ulong_t)&bxt_uart_info },
+	{ PCI_VDEVICE(INTEL, 0x7778), (kernel_ulong_t)&bxt_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x7779), (kernel_ulong_t)&bxt_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x777a), (kernel_ulong_t)&bxt_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0x777b), (kernel_ulong_t)&bxt_i2c_info },
 	/* RPL-S */
 	{ PCI_VDEVICE(INTEL, 0x7a28), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x7a29), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x7a2a), (kernel_ulong_t)&tgl_info },
-	{ PCI_VDEVICE(INTEL, 0x7a2b), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0x7a2a), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x7a2b), (kernel_ulong_t)&tgl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x7a4c), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7a4d), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7a4e), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7a4f), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7a5c), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x7a79), (kernel_ulong_t)&tgl_info },
-	{ PCI_VDEVICE(INTEL, 0x7a7b), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0x7a79), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x7a7b), (kernel_ulong_t)&tgl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x7a7c), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7a7d), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7a7e), (kernel_ulong_t)&bxt_uart_info },
 	/* ADL-S */
 	{ PCI_VDEVICE(INTEL, 0x7aa8), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x7aa9), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x7aaa), (kernel_ulong_t)&tgl_info },
-	{ PCI_VDEVICE(INTEL, 0x7aab), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0x7aaa), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x7aab), (kernel_ulong_t)&tgl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x7acc), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7acd), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7ace), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7acf), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7adc), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x7af9), (kernel_ulong_t)&tgl_info },
-	{ PCI_VDEVICE(INTEL, 0x7afb), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0x7af9), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x7afb), (kernel_ulong_t)&tgl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x7afc), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7afd), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7afe), (kernel_ulong_t)&bxt_uart_info },
 	/* MTL-P */
 	{ PCI_VDEVICE(INTEL, 0x7e25), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x7e26), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x7e27), (kernel_ulong_t)&tgl_info },
-	{ PCI_VDEVICE(INTEL, 0x7e30), (kernel_ulong_t)&tgl_info },
-	{ PCI_VDEVICE(INTEL, 0x7e46), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0x7e27), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x7e30), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x7e46), (kernel_ulong_t)&tgl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x7e50), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7e51), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7e52), (kernel_ulong_t)&bxt_uart_info },
@@ -458,22 +483,22 @@
 	/* MTP-S */
 	{ PCI_VDEVICE(INTEL, 0x7f28), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x7f29), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x7f2a), (kernel_ulong_t)&tgl_info },
-	{ PCI_VDEVICE(INTEL, 0x7f2b), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0x7f2a), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x7f2b), (kernel_ulong_t)&tgl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x7f4c), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7f4d), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7f4e), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7f4f), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7f5c), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x7f5d), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x7f5e), (kernel_ulong_t)&tgl_info },
-	{ PCI_VDEVICE(INTEL, 0x7f5f), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0x7f5e), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x7f5f), (kernel_ulong_t)&tgl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x7f7a), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x7f7b), (kernel_ulong_t)&bxt_i2c_info },
 	/* LKF */
 	{ PCI_VDEVICE(INTEL, 0x98a8), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x98a9), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x98aa), (kernel_ulong_t)&bxt_info },
+	{ PCI_VDEVICE(INTEL, 0x98aa), (kernel_ulong_t)&bxt_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x98c5), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x98c6), (kernel_ulong_t)&bxt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x98c7), (kernel_ulong_t)&bxt_uart_info },
@@ -484,8 +509,8 @@
 	/* SPT-LP */
 	{ PCI_VDEVICE(INTEL, 0x9d27), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x9d28), (kernel_ulong_t)&spt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x9d29), (kernel_ulong_t)&spt_info },
-	{ PCI_VDEVICE(INTEL, 0x9d2a), (kernel_ulong_t)&spt_info },
+	{ PCI_VDEVICE(INTEL, 0x9d29), (kernel_ulong_t)&spt_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x9d2a), (kernel_ulong_t)&spt_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x9d60), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x9d61), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x9d62), (kernel_ulong_t)&spt_i2c_info },
@@ -496,8 +521,8 @@
 	/* CNL-LP */
 	{ PCI_VDEVICE(INTEL, 0x9da8), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0x9da9), (kernel_ulong_t)&spt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0x9daa), (kernel_ulong_t)&cnl_info },
-	{ PCI_VDEVICE(INTEL, 0x9dab), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0x9daa), (kernel_ulong_t)&cnl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0x9dab), (kernel_ulong_t)&cnl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0x9dc5), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x9dc6), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x9dc7), (kernel_ulong_t)&spt_uart_info },
@@ -505,12 +530,12 @@
 	{ PCI_VDEVICE(INTEL, 0x9de9), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x9dea), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0x9deb), (kernel_ulong_t)&cnl_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0x9dfb), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0x9dfb), (kernel_ulong_t)&cnl_spi_info },
 	/* TGL-LP */
 	{ PCI_VDEVICE(INTEL, 0xa0a8), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa0a9), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0xa0aa), (kernel_ulong_t)&cnl_info },
-	{ PCI_VDEVICE(INTEL, 0xa0ab), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0xa0aa), (kernel_ulong_t)&cnl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xa0ab), (kernel_ulong_t)&cnl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0xa0c5), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa0c6), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa0c7), (kernel_ulong_t)&bxt_uart_info },
@@ -520,20 +545,20 @@
 	{ PCI_VDEVICE(INTEL, 0xa0db), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa0dc), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa0dd), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0xa0de), (kernel_ulong_t)&cnl_info },
-	{ PCI_VDEVICE(INTEL, 0xa0df), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0xa0de), (kernel_ulong_t)&cnl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xa0df), (kernel_ulong_t)&cnl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0xa0e8), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa0e9), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa0ea), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa0eb), (kernel_ulong_t)&spt_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0xa0fb), (kernel_ulong_t)&cnl_info },
-	{ PCI_VDEVICE(INTEL, 0xa0fd), (kernel_ulong_t)&cnl_info },
-	{ PCI_VDEVICE(INTEL, 0xa0fe), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0xa0fb), (kernel_ulong_t)&cnl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xa0fd), (kernel_ulong_t)&cnl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xa0fe), (kernel_ulong_t)&cnl_spi_info },
 	/* SPT-H */
 	{ PCI_VDEVICE(INTEL, 0xa127), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa128), (kernel_ulong_t)&spt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0xa129), (kernel_ulong_t)&spt_info },
-	{ PCI_VDEVICE(INTEL, 0xa12a), (kernel_ulong_t)&spt_info },
+	{ PCI_VDEVICE(INTEL, 0xa129), (kernel_ulong_t)&spt_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xa12a), (kernel_ulong_t)&spt_spi_info },
 	{ PCI_VDEVICE(INTEL, 0xa160), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa161), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa162), (kernel_ulong_t)&spt_i2c_info },
@@ -541,8 +566,8 @@
 	/* KBL-H */
 	{ PCI_VDEVICE(INTEL, 0xa2a7), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa2a8), (kernel_ulong_t)&spt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0xa2a9), (kernel_ulong_t)&spt_info },
-	{ PCI_VDEVICE(INTEL, 0xa2aa), (kernel_ulong_t)&spt_info },
+	{ PCI_VDEVICE(INTEL, 0xa2a9), (kernel_ulong_t)&spt_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xa2aa), (kernel_ulong_t)&spt_spi_info },
 	{ PCI_VDEVICE(INTEL, 0xa2e0), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa2e1), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa2e2), (kernel_ulong_t)&spt_i2c_info },
@@ -551,19 +576,19 @@
 	/* CNL-H */
 	{ PCI_VDEVICE(INTEL, 0xa328), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa329), (kernel_ulong_t)&spt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0xa32a), (kernel_ulong_t)&cnl_info },
-	{ PCI_VDEVICE(INTEL, 0xa32b), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0xa32a), (kernel_ulong_t)&cnl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xa32b), (kernel_ulong_t)&cnl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0xa347), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa368), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa369), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa36a), (kernel_ulong_t)&cnl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa36b), (kernel_ulong_t)&cnl_i2c_info },
-	{ PCI_VDEVICE(INTEL, 0xa37b), (kernel_ulong_t)&cnl_info },
+	{ PCI_VDEVICE(INTEL, 0xa37b), (kernel_ulong_t)&cnl_spi_info },
 	/* CML-V */
 	{ PCI_VDEVICE(INTEL, 0xa3a7), (kernel_ulong_t)&spt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa3a8), (kernel_ulong_t)&spt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0xa3a9), (kernel_ulong_t)&spt_info },
-	{ PCI_VDEVICE(INTEL, 0xa3aa), (kernel_ulong_t)&spt_info },
+	{ PCI_VDEVICE(INTEL, 0xa3a9), (kernel_ulong_t)&spt_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xa3aa), (kernel_ulong_t)&spt_spi_info },
 	{ PCI_VDEVICE(INTEL, 0xa3e0), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa3e1), (kernel_ulong_t)&spt_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa3e2), (kernel_ulong_t)&spt_i2c_info },
@@ -572,9 +597,9 @@
 	/* LNL-M */
 	{ PCI_VDEVICE(INTEL, 0xa825), (kernel_ulong_t)&bxt_uart_info },
 	{ PCI_VDEVICE(INTEL, 0xa826), (kernel_ulong_t)&bxt_uart_info },
-	{ PCI_VDEVICE(INTEL, 0xa827), (kernel_ulong_t)&tgl_info },
-	{ PCI_VDEVICE(INTEL, 0xa830), (kernel_ulong_t)&tgl_info },
-	{ PCI_VDEVICE(INTEL, 0xa846), (kernel_ulong_t)&tgl_info },
+	{ PCI_VDEVICE(INTEL, 0xa827), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xa830), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xa846), (kernel_ulong_t)&tgl_spi_info },
 	{ PCI_VDEVICE(INTEL, 0xa850), (kernel_ulong_t)&ehl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa851), (kernel_ulong_t)&ehl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa852), (kernel_ulong_t)&bxt_uart_info },
@@ -582,6 +607,32 @@
 	{ PCI_VDEVICE(INTEL, 0xa879), (kernel_ulong_t)&ehl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa87a), (kernel_ulong_t)&ehl_i2c_info },
 	{ PCI_VDEVICE(INTEL, 0xa87b), (kernel_ulong_t)&ehl_i2c_info },
+	/* PTL-H */
+	{ PCI_VDEVICE(INTEL, 0xe325), (kernel_ulong_t)&bxt_uart_info },
+	{ PCI_VDEVICE(INTEL, 0xe326), (kernel_ulong_t)&bxt_uart_info },
+	{ PCI_VDEVICE(INTEL, 0xe327), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xe330), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xe346), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xe350), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xe351), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xe352), (kernel_ulong_t)&bxt_uart_info },
+	{ PCI_VDEVICE(INTEL, 0xe378), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xe379), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xe37a), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xe37b), (kernel_ulong_t)&ehl_i2c_info },
+	/* PTL-P */
+	{ PCI_VDEVICE(INTEL, 0xe425), (kernel_ulong_t)&bxt_uart_info },
+	{ PCI_VDEVICE(INTEL, 0xe426), (kernel_ulong_t)&bxt_uart_info },
+	{ PCI_VDEVICE(INTEL, 0xe427), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xe430), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xe446), (kernel_ulong_t)&tgl_spi_info },
+	{ PCI_VDEVICE(INTEL, 0xe450), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xe451), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xe452), (kernel_ulong_t)&bxt_uart_info },
+	{ PCI_VDEVICE(INTEL, 0xe478), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xe479), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xe47a), (kernel_ulong_t)&ehl_i2c_info },
+	{ PCI_VDEVICE(INTEL, 0xe47b), (kernel_ulong_t)&ehl_i2c_info },
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids);
--- linux-qcom-6.8.0.orig/drivers/mfd/intel-lpss.c
+++ linux-qcom-6.8.0/drivers/mfd/intel-lpss.c
@@ -300,6 +300,7 @@
 {
 	char name[32];
 	struct clk *tmp = *clk;
+	int ret;
 
 	snprintf(name, sizeof(name), "%s-enable", devname);
 	tmp = clk_register_gate(NULL, name, __clk_get_name(tmp), 0,
@@ -316,6 +317,12 @@
 		return PTR_ERR(tmp);
 	*clk = tmp;
 
+	if (lpss->info->quirks & QUIRK_CLOCK_DIVIDER_UNITY) {
+		ret = clk_set_rate(tmp, lpss->info->clk_rate);
+		if (ret)
+			return ret;
+	}
+
 	snprintf(name, sizeof(name), "%s-update", devname);
 	tmp = clk_register_gate(NULL, name, __clk_get_name(tmp),
 				CLK_SET_RATE_PARENT, lpss->priv, 31, 0, NULL);
@@ -412,7 +419,7 @@
 		return ret;
 
 	lpss->cell->swnode = info->swnode;
-	lpss->cell->ignore_resource_conflicts = info->ignore_resource_conflicts;
+	lpss->cell->ignore_resource_conflicts = info->quirks & QUIRK_IGNORE_RESOURCE_CONFLICTS;
 
 	intel_lpss_init_dev(lpss);
 
--- linux-qcom-6.8.0.orig/drivers/mfd/intel-lpss.h
+++ linux-qcom-6.8.0/drivers/mfd/intel-lpss.h
@@ -11,16 +11,28 @@
 #ifndef __MFD_INTEL_LPSS_H
 #define __MFD_INTEL_LPSS_H
 
+#include <linux/bits.h>
 #include <linux/pm.h>
 
+/*
+ * Some DSDTs have an unused GEXP ACPI device conflicting with I2C4 resources.
+ * Set to ignore resource conflicts with ACPI declared SystemMemory regions.
+ */
+#define QUIRK_IGNORE_RESOURCE_CONFLICTS BIT(0)
+/*
+ * Some devices have misconfigured clock divider due to a firmware bug.
+ * Set this to force the clock divider to 1:1 ratio.
+ */
+#define QUIRK_CLOCK_DIVIDER_UNITY		BIT(1)
+
 struct device;
 struct resource;
 struct software_node;
 
 struct intel_lpss_platform_info {
 	struct resource *mem;
-	bool ignore_resource_conflicts;
 	int irq;
+	unsigned int quirks;
 	unsigned long clk_rate;
 	const char *clk_con_id;
 	const struct software_node *swnode;
--- linux-qcom-6.8.0.orig/drivers/mfd/intel_soc_pmic_bxtwc.c
+++ linux-qcom-6.8.0/drivers/mfd/intel_soc_pmic_bxtwc.c
@@ -232,43 +232,54 @@
 
 static struct mfd_cell bxt_wc_dev[] = {
 	{
-		.name = "bxt_wcove_gpadc",
-		.num_resources = ARRAY_SIZE(adc_resources),
-		.resources = adc_resources,
-	},
-	{
 		.name = "bxt_wcove_thermal",
 		.num_resources = ARRAY_SIZE(thermal_resources),
 		.resources = thermal_resources,
 	},
 	{
-		.name = "bxt_wcove_usbc",
-		.num_resources = ARRAY_SIZE(usbc_resources),
-		.resources = usbc_resources,
+		.name = "bxt_wcove_gpio",
+		.num_resources = ARRAY_SIZE(gpio_resources),
+		.resources = gpio_resources,
 	},
 	{
-		.name = "bxt_wcove_ext_charger",
-		.num_resources = ARRAY_SIZE(charger_resources),
-		.resources = charger_resources,
+		.name = "bxt_wcove_region",
+	},
+};
+
+static const struct mfd_cell bxt_wc_tmu_dev[] = {
+	{
+		.name = "bxt_wcove_tmu",
+		.num_resources = ARRAY_SIZE(tmu_resources),
+		.resources = tmu_resources,
 	},
+};
+
+static const struct mfd_cell bxt_wc_bcu_dev[] = {
 	{
 		.name = "bxt_wcove_bcu",
 		.num_resources = ARRAY_SIZE(bcu_resources),
 		.resources = bcu_resources,
 	},
+};
+
+static const struct mfd_cell bxt_wc_adc_dev[] = {
 	{
-		.name = "bxt_wcove_tmu",
-		.num_resources = ARRAY_SIZE(tmu_resources),
-		.resources = tmu_resources,
+		.name = "bxt_wcove_gpadc",
+		.num_resources = ARRAY_SIZE(adc_resources),
+		.resources = adc_resources,
 	},
+};
 
+static struct mfd_cell bxt_wc_chgr_dev[] = {
 	{
-		.name = "bxt_wcove_gpio",
-		.num_resources = ARRAY_SIZE(gpio_resources),
-		.resources = gpio_resources,
+		.name = "bxt_wcove_usbc",
+		.num_resources = ARRAY_SIZE(usbc_resources),
+		.resources = usbc_resources,
 	},
 	{
-		.name = "bxt_wcove_region",
+		.name = "bxt_wcove_ext_charger",
+		.num_resources = ARRAY_SIZE(charger_resources),
+		.resources = charger_resources,
 	},
 };
 
@@ -426,6 +437,26 @@
 					0, chip, data);
 }
 
+static int bxtwc_add_chained_devices(struct intel_soc_pmic *pmic,
+				     const struct mfd_cell *cells, int n_devs,
+				     struct regmap_irq_chip_data *pdata,
+				     int pirq, int irq_flags,
+				     const struct regmap_irq_chip *chip,
+				     struct regmap_irq_chip_data **data)
+{
+	struct device *dev = pmic->dev;
+	struct irq_domain *domain;
+	int ret;
+
+	ret = bxtwc_add_chained_irq_chip(pmic, pdata, pirq, irq_flags, chip, data);
+	if (ret)
+		return dev_err_probe(dev, ret, "Failed to add %s IRQ chip\n", chip->name);
+
+	domain = regmap_irq_get_domain(*data);
+
+	return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, cells, n_devs, NULL, 0, domain);
+}
+
 static int bxtwc_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -467,6 +498,15 @@
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to add IRQ chip\n");
 
+	ret = bxtwc_add_chained_devices(pmic, bxt_wc_tmu_dev, ARRAY_SIZE(bxt_wc_tmu_dev),
+					pmic->irq_chip_data,
+					BXTWC_TMU_LVL1_IRQ,
+					IRQF_ONESHOT,
+					&bxtwc_regmap_irq_chip_tmu,
+					&pmic->irq_chip_data_tmu);
+	if (ret)
+		return ret;
+
 	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
 					 BXTWC_PWRBTN_LVL1_IRQ,
 					 IRQF_ONESHOT,
@@ -475,40 +515,32 @@
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to add PWRBTN IRQ chip\n");
 
-	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
-					 BXTWC_TMU_LVL1_IRQ,
-					 IRQF_ONESHOT,
-					 &bxtwc_regmap_irq_chip_tmu,
-					 &pmic->irq_chip_data_tmu);
-	if (ret)
-		return dev_err_probe(dev, ret, "Failed to add TMU IRQ chip\n");
-
-	/* Add chained IRQ handler for BCU IRQs */
-	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
-					 BXTWC_BCU_LVL1_IRQ,
-					 IRQF_ONESHOT,
-					 &bxtwc_regmap_irq_chip_bcu,
-					 &pmic->irq_chip_data_bcu);
+	ret = bxtwc_add_chained_devices(pmic, bxt_wc_bcu_dev, ARRAY_SIZE(bxt_wc_bcu_dev),
+					pmic->irq_chip_data,
+					BXTWC_BCU_LVL1_IRQ,
+					IRQF_ONESHOT,
+					&bxtwc_regmap_irq_chip_bcu,
+					&pmic->irq_chip_data_bcu);
 	if (ret)
-		return dev_err_probe(dev, ret, "Failed to add BUC IRQ chip\n");
+		return ret;
 
-	/* Add chained IRQ handler for ADC IRQs */
-	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
-					 BXTWC_ADC_LVL1_IRQ,
-					 IRQF_ONESHOT,
-					 &bxtwc_regmap_irq_chip_adc,
-					 &pmic->irq_chip_data_adc);
+	ret = bxtwc_add_chained_devices(pmic, bxt_wc_adc_dev, ARRAY_SIZE(bxt_wc_adc_dev),
+					pmic->irq_chip_data,
+					BXTWC_ADC_LVL1_IRQ,
+					IRQF_ONESHOT,
+					&bxtwc_regmap_irq_chip_adc,
+					&pmic->irq_chip_data_adc);
 	if (ret)
-		return dev_err_probe(dev, ret, "Failed to add ADC IRQ chip\n");
+		return ret;
 
-	/* Add chained IRQ handler for CHGR IRQs */
-	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
-					 BXTWC_CHGR_LVL1_IRQ,
-					 IRQF_ONESHOT,
-					 &bxtwc_regmap_irq_chip_chgr,
-					 &pmic->irq_chip_data_chgr);
+	ret = bxtwc_add_chained_devices(pmic, bxt_wc_chgr_dev, ARRAY_SIZE(bxt_wc_chgr_dev),
+					pmic->irq_chip_data,
+					BXTWC_CHGR_LVL1_IRQ,
+					IRQF_ONESHOT,
+					&bxtwc_regmap_irq_chip_chgr,
+					&pmic->irq_chip_data_chgr);
 	if (ret)
-		return dev_err_probe(dev, ret, "Failed to add CHGR IRQ chip\n");
+		return ret;
 
 	/* Add chained IRQ handler for CRIT IRQs */
 	ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data,
--- linux-qcom-6.8.0.orig/drivers/mfd/intel_soc_pmic_chtwc.c
+++ linux-qcom-6.8.0/drivers/mfd/intel_soc_pmic_chtwc.c
@@ -178,7 +178,6 @@
 		.driver_data = (void *)(long)INTEL_CHT_WC_LENOVO_YT3_X90,
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"),
 			DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"),
 		},
 	},
--- linux-qcom-6.8.0.orig/drivers/mfd/lpc_ich.c
+++ linux-qcom-6.8.0/drivers/mfd/lpc_ich.c
@@ -833,8 +833,9 @@
 	{ PCI_VDEVICE(INTEL, 0x2917), LPC_ICH9ME},
 	{ PCI_VDEVICE(INTEL, 0x2918), LPC_ICH9},
 	{ PCI_VDEVICE(INTEL, 0x2919), LPC_ICH9M},
-	{ PCI_VDEVICE(INTEL, 0x3197), LPC_GLK},
 	{ PCI_VDEVICE(INTEL, 0x2b9c), LPC_COUGARMOUNTAIN},
+	{ PCI_VDEVICE(INTEL, 0x3197), LPC_GLK},
+	{ PCI_VDEVICE(INTEL, 0x31e8), LPC_GLK},
 	{ PCI_VDEVICE(INTEL, 0x3a14), LPC_ICH10DO},
 	{ PCI_VDEVICE(INTEL, 0x3a16), LPC_ICH10R},
 	{ PCI_VDEVICE(INTEL, 0x3a18), LPC_ICH10},
--- linux-qcom-6.8.0.orig/drivers/mfd/mfd-aaeon.c
+++ linux-qcom-6.8.0/drivers/mfd/mfd-aaeon.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * UP Board main platform driver and FPGA configuration support
+ *
+ * Copyright (c) 2021, AAEON Ltd.
+ *
+ * Author: Kunyang_Fan <knuyang_fan@aaeon.com.tw>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/acpi.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/platform_data/x86/asus-wmi.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/wmi.h>
+
+#define AAEON_WMI_MGMT_GUID      "97845ED0-4E6D-11DE-8A39-0800200C9A66"
+
+#define WMI_REPORT_CAPABILITY_METHOD	0x00000000
+#define MAX_BFPI_VERSION		255
+#define GET_REVISION_ID			0x00
+
+struct aaeon_wmi_priv {
+	const struct mfd_cell *cells;
+	size_t ncells;
+};
+
+static const struct mfd_cell aaeon_mfd_cells[] = {
+	{ .name = "gpio-aaeon" },
+	{ .name = "hwmon-aaeon"},
+	{ .name = "leds-aaeon"},
+	{ .name = "wdt-aaeon"},
+};
+
+static const struct aaeon_wmi_priv aaeon_wmi_priv_data = {
+	.cells = aaeon_mfd_cells,
+	.ncells = ARRAY_SIZE(aaeon_mfd_cells),
+};
+
+static int aaeon_wmi_check_device(void)
+{
+	int err;
+	int retval;
+
+	err = asus_wmi_evaluate_method(WMI_REPORT_CAPABILITY_METHOD, GET_REVISION_ID, 0,
+				       &retval);
+	if (err)
+		return -ENODEV;
+	if (retval < 3 || retval > MAX_BFPI_VERSION)
+		return -ENODEV;
+
+	return 0;
+}
+
+static int aaeon_wmi_probe(struct wmi_device *wdev, const void *context)
+{
+	struct aaeon_wmi_priv *priv;
+
+	if (!wmi_has_guid(AAEON_WMI_MGMT_GUID)) {
+		dev_info(&wdev->dev, "AAEON Management GUID not found\n");
+		return -ENODEV;
+	}
+
+	if (aaeon_wmi_check_device())
+		return -ENODEV;
+
+	priv = (struct aaeon_wmi_priv *)context;
+	dev_set_drvdata(&wdev->dev, priv);
+
+	return devm_mfd_add_devices(&wdev->dev, 0, priv->cells,
+				    priv->ncells, NULL, 0, NULL);
+}
+
+static const struct wmi_device_id aaeon_wmi_id_table[] = {
+	{ AAEON_WMI_MGMT_GUID, (void *)&aaeon_wmi_priv_data },
+	{}
+};
+
+static struct wmi_driver aaeon_wmi_driver = {
+	.driver = {
+		.name = "mfd-aaeon",
+	},
+	.id_table = aaeon_wmi_id_table,
+	.probe = aaeon_wmi_probe,
+};
+
+module_wmi_driver(aaeon_wmi_driver);
+
+MODULE_DEVICE_TABLE(wmi, aaeon_wmi_id_table);
+MODULE_AUTHOR("Kunyang Fan <kunyang_fan@aaeon.com.tw>");
+MODULE_DESCRIPTION("AAEON Board WMI driver");
+MODULE_LICENSE("GPL v2");
--- linux-qcom-6.8.0.orig/drivers/mfd/omap-usb-tll.c
+++ linux-qcom-6.8.0/drivers/mfd/omap-usb-tll.c
@@ -230,8 +230,7 @@
 		break;
 	}
 
-	tll = devm_kzalloc(dev, sizeof(*tll) + sizeof(tll->ch_clk[nch]),
-			   GFP_KERNEL);
+	tll = devm_kzalloc(dev, struct_size(tll, ch_clk, nch), GFP_KERNEL);
 	if (!tll) {
 		pm_runtime_put_sync(dev);
 		pm_runtime_disable(dev);
--- linux-qcom-6.8.0.orig/drivers/mfd/qcom-i2c-pmic.c
+++ linux-qcom-6.8.0/drivers/mfd/qcom-i2c-pmic.c
@@ -0,0 +1,816 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#define pr_fmt(fmt) "I2C PMIC: %s: " fmt, __func__
+
+#include <linux/bitops.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+#define I2C_INTR_STATUS_BASE	0x0550
+#define INT_RT_STS_OFFSET	0x10
+#define INT_SET_TYPE_OFFSET	0x11
+#define INT_POL_HIGH_OFFSET	0x12
+#define INT_POL_LOW_OFFSET	0x13
+#define INT_LATCHED_CLR_OFFSET	0x14
+#define INT_EN_SET_OFFSET	0x15
+#define INT_EN_CLR_OFFSET	0x16
+#define INT_LATCHED_STS_OFFSET	0x18
+#define INT_PENDING_STS_OFFSET	0x19
+#define INT_MID_SEL_OFFSET	0x1A
+#define INT_MID_SEL_MASK	GENMASK(1, 0)
+#define INT_PRIORITY_OFFSET	0x1B
+#define INT_PRIORITY_BIT	BIT(0)
+
+enum {
+	IRQ_SET_TYPE = 0,
+	IRQ_POL_HIGH,
+	IRQ_POL_LOW,
+	IRQ_LATCHED_CLR, /* not needed but makes life easy */
+	IRQ_EN_SET,
+	IRQ_MAX_REGS,
+};
+
+struct i2c_pmic_periph {
+	void		*data;
+	u16		addr;
+	u8		cached[IRQ_MAX_REGS];
+	u8		synced[IRQ_MAX_REGS];
+	u8		wake;
+	struct mutex	lock;
+};
+
+struct i2c_pmic {
+	struct device		*dev;
+	struct regmap		*regmap;
+	struct irq_domain	*domain;
+	struct i2c_pmic_periph	*periph;
+	struct pinctrl		*pinctrl;
+	struct mutex		irq_complete;
+	const char		*pinctrl_name;
+	int			num_periphs;
+	int			summary_irq;
+	bool			resume_completed;
+	bool			irq_waiting;
+	bool			toggle_stat;
+};
+
+static void i2c_pmic_irq_bus_lock(struct irq_data *d)
+{
+	struct i2c_pmic_periph *periph = irq_data_get_irq_chip_data(d);
+
+	mutex_lock(&periph->lock);
+}
+
+static void i2c_pmic_sync_type_polarity(struct i2c_pmic *chip,
+			       struct i2c_pmic_periph *periph)
+{
+	int rc;
+
+	/* did any irq type change? */
+	if (periph->cached[IRQ_SET_TYPE] ^ periph->synced[IRQ_SET_TYPE]) {
+		rc = regmap_write(chip->regmap,
+				  periph->addr | INT_SET_TYPE_OFFSET,
+				  periph->cached[IRQ_SET_TYPE]);
+		if (rc < 0) {
+			pr_err("Couldn't set periph 0x%04x irqs 0x%02x type rc=%d\n",
+				periph->addr, periph->cached[IRQ_SET_TYPE], rc);
+			return;
+		}
+
+		periph->synced[IRQ_SET_TYPE] = periph->cached[IRQ_SET_TYPE];
+	}
+
+	/* did any polarity high change? */
+	if (periph->cached[IRQ_POL_HIGH] ^ periph->synced[IRQ_POL_HIGH]) {
+		rc = regmap_write(chip->regmap,
+				  periph->addr | INT_POL_HIGH_OFFSET,
+				  periph->cached[IRQ_POL_HIGH]);
+		if (rc < 0) {
+			pr_err("Couldn't set periph 0x%04x irqs 0x%02x polarity high rc=%d\n",
+				periph->addr, periph->cached[IRQ_POL_HIGH], rc);
+			return;
+		}
+
+		periph->synced[IRQ_POL_HIGH] = periph->cached[IRQ_POL_HIGH];
+	}
+
+	/* did any polarity low change? */
+	if (periph->cached[IRQ_POL_LOW] ^ periph->synced[IRQ_POL_LOW]) {
+		rc = regmap_write(chip->regmap,
+				  periph->addr | INT_POL_LOW_OFFSET,
+				  periph->cached[IRQ_POL_LOW]);
+		if (rc < 0) {
+			pr_err("Couldn't set periph 0x%04x irqs 0x%02x polarity low rc=%d\n",
+				periph->addr, periph->cached[IRQ_POL_LOW], rc);
+			return;
+		}
+
+		periph->synced[IRQ_POL_LOW] = periph->cached[IRQ_POL_LOW];
+	}
+}
+
+static void i2c_pmic_sync_enable(struct i2c_pmic *chip,
+				 struct i2c_pmic_periph *periph)
+{
+	u8 en_set, en_clr;
+	int rc;
+
+	/* determine which irqs were enabled and which were disabled */
+	en_clr = periph->synced[IRQ_EN_SET] & ~periph->cached[IRQ_EN_SET];
+	en_set = ~periph->synced[IRQ_EN_SET] & periph->cached[IRQ_EN_SET];
+
+	/* were any irqs disabled? */
+	if (en_clr) {
+		rc = regmap_write(chip->regmap,
+				  periph->addr | INT_EN_CLR_OFFSET, en_clr);
+		if (rc < 0) {
+			pr_err("Couldn't disable periph 0x%04x irqs 0x%02x rc=%d\n",
+				periph->addr, en_clr, rc);
+			return;
+		}
+	}
+
+	/* were any irqs enabled? */
+	if (en_set) {
+		rc = regmap_write(chip->regmap,
+				  periph->addr | INT_EN_SET_OFFSET, en_set);
+		if (rc < 0) {
+			pr_err("Couldn't enable periph 0x%04x irqs 0x%02x rc=%d\n",
+				periph->addr, en_set, rc);
+			return;
+		}
+	}
+
+	/* irq enabled status was written to hardware */
+	periph->synced[IRQ_EN_SET] = periph->cached[IRQ_EN_SET];
+}
+
+static void i2c_pmic_irq_bus_sync_unlock(struct irq_data *d)
+{
+	struct i2c_pmic_periph *periph = irq_data_get_irq_chip_data(d);
+	struct i2c_pmic *chip = periph->data;
+
+	i2c_pmic_sync_type_polarity(chip, periph);
+	i2c_pmic_sync_enable(chip, periph);
+	mutex_unlock(&periph->lock);
+}
+
+static void i2c_pmic_irq_disable(struct irq_data *d)
+{
+	struct i2c_pmic_periph *periph = irq_data_get_irq_chip_data(d);
+
+	periph->cached[IRQ_EN_SET] &= ~d->hwirq & 0xFF;
+}
+
+static void i2c_pmic_irq_enable(struct irq_data *d)
+{
+	struct i2c_pmic_periph *periph = irq_data_get_irq_chip_data(d);
+
+	periph->cached[IRQ_EN_SET] |= d->hwirq & 0xFF;
+}
+
+static int i2c_pmic_irq_set_type(struct irq_data *d, unsigned int irq_type)
+{
+	struct i2c_pmic_periph *periph = irq_data_get_irq_chip_data(d);
+
+	switch (irq_type) {
+	case IRQ_TYPE_EDGE_RISING:
+		periph->cached[IRQ_SET_TYPE] |= d->hwirq & 0xFF;
+		periph->cached[IRQ_POL_HIGH] |= d->hwirq & 0xFF;
+		periph->cached[IRQ_POL_LOW] &= ~d->hwirq & 0xFF;
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		periph->cached[IRQ_SET_TYPE] |= d->hwirq & 0xFF;
+		periph->cached[IRQ_POL_HIGH] &= ~d->hwirq & 0xFF;
+		periph->cached[IRQ_POL_LOW] |= d->hwirq & 0xFF;
+		break;
+	case IRQ_TYPE_EDGE_BOTH:
+		periph->cached[IRQ_SET_TYPE] |= d->hwirq & 0xFF;
+		periph->cached[IRQ_POL_HIGH] |= d->hwirq & 0xFF;
+		periph->cached[IRQ_POL_LOW] |= d->hwirq & 0xFF;
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		periph->cached[IRQ_SET_TYPE] &= ~d->hwirq & 0xFF;
+		periph->cached[IRQ_POL_HIGH] |= d->hwirq & 0xFF;
+		periph->cached[IRQ_POL_LOW] &= ~d->hwirq & 0xFF;
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		periph->cached[IRQ_SET_TYPE] &= ~d->hwirq & 0xFF;
+		periph->cached[IRQ_POL_HIGH] &= ~d->hwirq & 0xFF;
+		periph->cached[IRQ_POL_LOW] |= d->hwirq & 0xFF;
+		break;
+	default:
+		pr_err("irq type 0x%04x is not supported\n", irq_type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int i2c_pmic_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+	struct i2c_pmic_periph *periph = irq_data_get_irq_chip_data(d);
+
+	if (on)
+		periph->wake |= d->hwirq & 0xFF;
+	else
+		periph->wake &= ~d->hwirq & 0xFF;
+
+	return 0;
+}
+#else
+#define i2c_pmic_irq_set_wake NULL
+#endif
+
+static struct irq_chip i2c_pmic_irq_chip = {
+	.name			= "i2c_pmic_irq_chip",
+	.irq_bus_lock		= i2c_pmic_irq_bus_lock,
+	.irq_bus_sync_unlock	= i2c_pmic_irq_bus_sync_unlock,
+	.irq_disable		= i2c_pmic_irq_disable,
+	.irq_enable		= i2c_pmic_irq_enable,
+	.irq_set_type		= i2c_pmic_irq_set_type,
+	.irq_set_wake		= i2c_pmic_irq_set_wake,
+};
+
+static struct i2c_pmic_periph *i2c_pmic_find_periph(struct i2c_pmic *chip,
+						    irq_hw_number_t hwirq)
+{
+	int i;
+
+	for (i = 0; i < chip->num_periphs; i++)
+		if (chip->periph[i].addr == (hwirq & 0xFF00))
+			return &chip->periph[i];
+
+	pr_err_ratelimited("Couldn't find periph struct for hwirq 0x%04lx\n",
+			   hwirq);
+	return NULL;
+}
+
+static int i2c_pmic_domain_map(struct irq_domain *d, unsigned int virq,
+			irq_hw_number_t hwirq)
+{
+	struct i2c_pmic *chip = d->host_data;
+	struct i2c_pmic_periph *periph = i2c_pmic_find_periph(chip, hwirq);
+
+	if (!periph)
+		return -ENODEV;
+
+	irq_set_chip_data(virq, periph);
+	irq_set_chip_and_handler(virq, &i2c_pmic_irq_chip, handle_level_irq);
+	irq_set_nested_thread(virq, 1);
+	irq_set_noprobe(virq);
+	return 0;
+}
+
+static int i2c_pmic_domain_xlate(struct irq_domain *d,
+				 struct device_node *ctrlr, const u32 *intspec,
+				 unsigned int intsize, unsigned long *out_hwirq,
+				 unsigned int *out_type)
+{
+	if (intsize != 3)
+		return -EINVAL;
+
+	if (intspec[0] > 0xFF || intspec[1] > 0x7 ||
+					intspec[2] > IRQ_TYPE_SENSE_MASK)
+		return -EINVAL;
+
+	/*
+	 * Interrupt specifiers are triplets
+	 * <peripheral-address, irq-number, IRQ_TYPE_*>
+	 *
+	 * peripheral-address - The base address of the peripheral
+	 * irq-number	      - The zero based bit position of the peripheral's
+	 *			interrupt registers corresponding to the irq
+	 *			where the LSB is 0 and the MSB is 7
+	 * IRQ_TYPE_*	      - Please refer to linux/irq.h
+	 */
+	*out_hwirq = intspec[0] << 8 | BIT(intspec[1]);
+	*out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
+
+	return 0;
+}
+
+static const struct irq_domain_ops i2c_pmic_domain_ops = {
+	.map	= i2c_pmic_domain_map,
+	.xlate	= i2c_pmic_domain_xlate,
+};
+
+static void i2c_pmic_irq_ack_now(struct i2c_pmic *chip, u16 hwirq)
+{
+	int rc;
+
+	rc = regmap_write(chip->regmap,
+			  (hwirq & 0xFF00) | INT_LATCHED_CLR_OFFSET,
+			  hwirq & 0xFF);
+	if (rc < 0)
+		pr_err_ratelimited("Couldn't ack 0x%04x rc=%d\n", hwirq, rc);
+}
+
+static void i2c_pmic_irq_disable_now(struct i2c_pmic *chip, u16 hwirq)
+{
+	struct i2c_pmic_periph *periph = i2c_pmic_find_periph(chip, hwirq);
+	int rc;
+
+	if (!periph)
+		return;
+
+	mutex_lock(&periph->lock);
+	periph->cached[IRQ_EN_SET] &= ~hwirq & 0xFF;
+
+	rc = regmap_write(chip->regmap,
+			  (hwirq & 0xFF00) | INT_EN_CLR_OFFSET,
+			  hwirq & 0xFF);
+	if (rc < 0) {
+		pr_err_ratelimited("Couldn't disable irq 0x%04x rc=%d\n",
+				   hwirq, rc);
+		goto unlock;
+	}
+
+	periph->synced[IRQ_EN_SET] = periph->cached[IRQ_EN_SET];
+
+unlock:
+	mutex_unlock(&periph->lock);
+}
+
+static void i2c_pmic_periph_status_handler(struct i2c_pmic *chip,
+					   u16 periph_address, u8 periph_status)
+{
+	unsigned int hwirq, virq;
+	int i;
+
+	while (periph_status) {
+		i = ffs(periph_status) - 1;
+		periph_status &= ~BIT(i);
+		hwirq = periph_address | BIT(i);
+		virq = irq_find_mapping(chip->domain, hwirq);
+		if (virq == 0) {
+			pr_err_ratelimited("Couldn't find mapping; disabling 0x%04x\n",
+					   hwirq);
+			i2c_pmic_irq_disable_now(chip, hwirq);
+			continue;
+		}
+
+		handle_nested_irq(virq);
+		i2c_pmic_irq_ack_now(chip, hwirq);
+	}
+}
+
+static void i2c_pmic_summary_status_handler(struct i2c_pmic *chip,
+					    struct i2c_pmic_periph *periph,
+					    u8 summary_status)
+{
+	unsigned int periph_status;
+	int rc, i;
+
+	while (summary_status) {
+		i = ffs(summary_status) - 1;
+		summary_status &= ~BIT(i);
+
+		rc = regmap_read(chip->regmap,
+				 periph[i].addr | INT_LATCHED_STS_OFFSET,
+				 &periph_status);
+		if (rc < 0) {
+			pr_err_ratelimited("Couldn't read 0x%04x | INT_LATCHED_STS rc=%d\n",
+					   periph[i].addr, rc);
+			continue;
+		}
+
+		i2c_pmic_periph_status_handler(chip, periph[i].addr,
+					       periph_status);
+	}
+}
+
+static irqreturn_t i2c_pmic_irq_handler(int irq, void *dev_id)
+{
+	struct i2c_pmic *chip = dev_id;
+	struct i2c_pmic_periph *periph;
+	unsigned int summary_status;
+	int rc, i;
+
+	mutex_lock(&chip->irq_complete);
+	chip->irq_waiting = true;
+	if (!chip->resume_completed) {
+		pr_debug("IRQ triggered before device-resume\n");
+		disable_irq_nosync(irq);
+		mutex_unlock(&chip->irq_complete);
+		return IRQ_HANDLED;
+	}
+	chip->irq_waiting = false;
+
+	for (i = 0; i < DIV_ROUND_UP(chip->num_periphs, BITS_PER_BYTE); i++) {
+		rc = regmap_read(chip->regmap, I2C_INTR_STATUS_BASE + i,
+				&summary_status);
+		if (rc < 0) {
+			pr_err_ratelimited("Couldn't read I2C_INTR_STATUS%d rc=%d\n",
+					   i, rc);
+			continue;
+		}
+
+		if (summary_status == 0)
+			continue;
+
+		periph = &chip->periph[i * 8];
+		i2c_pmic_summary_status_handler(chip, periph, summary_status);
+	}
+
+	mutex_unlock(&chip->irq_complete);
+
+	return IRQ_HANDLED;
+}
+
+static int i2c_pmic_parse_dt(struct i2c_pmic *chip)
+{
+	struct device_node *node = chip->dev->of_node;
+	int rc, i;
+	u32 temp;
+
+	if (!node) {
+		pr_err("missing device tree\n");
+		return -EINVAL;
+	}
+
+	chip->num_periphs = of_property_count_u32_elems(node,
+							"qcom,periph-map");
+	if (chip->num_periphs < 0) {
+		pr_err("missing qcom,periph-map property rc=%d\n",
+			chip->num_periphs);
+		return chip->num_periphs;
+	}
+
+	if (chip->num_periphs == 0) {
+		pr_err("qcom,periph-map must contain at least one address\n");
+		return -EINVAL;
+	}
+
+	chip->periph = devm_kcalloc(chip->dev, chip->num_periphs,
+				     sizeof(*chip->periph), GFP_KERNEL);
+	if (!chip->periph)
+		return -ENOMEM;
+
+	for (i = 0; i < chip->num_periphs; i++) {
+		rc = of_property_read_u32_index(node, "qcom,periph-map",
+						i, &temp);
+		if (rc < 0) {
+			pr_err("Couldn't read qcom,periph-map[%d] rc=%d\n",
+			       i, rc);
+			return rc;
+		}
+
+		chip->periph[i].addr = (u16)(temp << 8);
+		chip->periph[i].data = chip;
+		mutex_init(&chip->periph[i].lock);
+	}
+
+	of_property_read_string(node, "pinctrl-names", &chip->pinctrl_name);
+
+	chip->toggle_stat = of_property_read_bool(node,
+				"qcom,enable-toggle-stat");
+
+	return rc;
+}
+
+#define MAX_I2C_RETRIES	3
+static int i2c_pmic_read(struct regmap *map, unsigned int reg, void *val,
+			size_t val_count)
+{
+	int rc, retries = 0;
+
+	do {
+		rc = regmap_bulk_read(map, reg, val, val_count);
+	} while (rc == -ENOTCONN && retries++ < MAX_I2C_RETRIES);
+
+	if (retries > 1)
+		pr_err("i2c_pmic_read failed for %d retries, rc = %d\n",
+			retries - 1, rc);
+
+	return rc;
+}
+
+static int i2c_pmic_determine_initial_status(struct i2c_pmic *chip)
+{
+	int rc, i;
+
+	for (i = 0; i < chip->num_periphs; i++) {
+		rc = i2c_pmic_read(chip->regmap,
+				chip->periph[i].addr | INT_SET_TYPE_OFFSET,
+				chip->periph[i].cached, IRQ_MAX_REGS);
+		if (rc < 0) {
+			pr_err("Couldn't read irq data rc=%d\n", rc);
+			return rc;
+		}
+
+		memcpy(chip->periph[i].synced, chip->periph[i].cached,
+		       IRQ_MAX_REGS * sizeof(*chip->periph[i].synced));
+	}
+
+	return 0;
+}
+
+#define INT_TEST_OFFSET			0xE0
+#define INT_TEST_MODE_EN_BIT		BIT(7)
+#define INT_TEST_VAL_OFFSET		0xE1
+#define INT_0_BIT			BIT(0)
+static int i2c_pmic_toggle_stat(struct i2c_pmic *chip)
+{
+	int rc = 0, i;
+
+	if (!chip->toggle_stat || !chip->num_periphs)
+		return 0;
+
+	rc = regmap_write(chip->regmap,
+				chip->periph[0].addr | INT_EN_SET_OFFSET,
+				INT_0_BIT);
+	if (rc < 0) {
+		pr_err("Couldn't write to int_en_set rc=%d\n", rc);
+		return rc;
+	}
+
+	rc = regmap_write(chip->regmap, chip->periph[0].addr | INT_TEST_OFFSET,
+				INT_TEST_MODE_EN_BIT);
+	if (rc < 0) {
+		pr_err("Couldn't write to int_test rc=%d\n", rc);
+		return rc;
+	}
+
+	for (i = 0; i < 5; i++) {
+		rc = regmap_write(chip->regmap,
+				chip->periph[0].addr | INT_TEST_VAL_OFFSET,
+				INT_0_BIT);
+		if (rc < 0) {
+			pr_err("Couldn't write to int_test_val rc=%d\n", rc);
+			goto exit;
+		}
+
+		usleep_range(5000, 5500);
+
+		rc = regmap_write(chip->regmap,
+				chip->periph[0].addr | INT_TEST_VAL_OFFSET,
+				0);
+		if (rc < 0) {
+			pr_err("Couldn't write to int_test_val rc=%d\n", rc);
+			goto exit;
+		}
+
+		rc = regmap_write(chip->regmap,
+				chip->periph[0].addr | INT_LATCHED_CLR_OFFSET,
+				INT_0_BIT);
+		if (rc < 0) {
+			pr_err("Couldn't write to int_latched_clr rc=%d\n", rc);
+			goto exit;
+		}
+
+		usleep_range(5000, 5500);
+	}
+exit:
+	regmap_write(chip->regmap, chip->periph[0].addr | INT_TEST_OFFSET, 0);
+	regmap_write(chip->regmap, chip->periph[0].addr | INT_EN_CLR_OFFSET,
+							INT_0_BIT);
+
+	return rc;
+}
+
+static struct regmap_config i2c_pmic_regmap_config = {
+	.reg_bits	= 16,
+	.val_bits	= 8,
+	.max_register	= 0xFFFF,
+};
+
+static int i2c_pmic_probe(struct i2c_client *client)
+{
+	struct i2c_pmic *chip;
+	int rc = 0;
+
+	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->dev = &client->dev;
+	chip->regmap = devm_regmap_init_i2c(client, &i2c_pmic_regmap_config);
+	if (!chip->regmap)
+		return -ENODEV;
+
+	i2c_set_clientdata(client, chip);
+	chip->summary_irq = -EINVAL;
+	if (!of_property_read_bool(chip->dev->of_node, "interrupt-controller"))
+		goto probe_children;
+
+	chip->domain = irq_domain_add_tree(client->dev.of_node,
+					   &i2c_pmic_domain_ops, chip);
+	if (!chip->domain) {
+		rc = -ENOMEM;
+		goto cleanup;
+	}
+
+	rc = i2c_pmic_parse_dt(chip);
+	if (rc < 0) {
+		pr_err("Couldn't parse device tree rc=%d\n", rc);
+		goto cleanup;
+	}
+
+	rc = i2c_pmic_determine_initial_status(chip);
+	if (rc < 0) {
+		pr_err("Couldn't determine initial status rc=%d\n", rc);
+		goto cleanup;
+	}
+
+	if (chip->pinctrl_name) {
+		chip->pinctrl = devm_pinctrl_get_select(chip->dev,
+							chip->pinctrl_name);
+		if (IS_ERR(chip->pinctrl)) {
+			pr_err("Couldn't select %s pinctrl rc=%ld\n",
+				chip->pinctrl_name, PTR_ERR(chip->pinctrl));
+			rc = PTR_ERR(chip->pinctrl);
+			goto cleanup;
+		}
+	}
+
+	chip->resume_completed = true;
+	mutex_init(&chip->irq_complete);
+
+	rc = i2c_pmic_toggle_stat(chip);
+	if (rc < 0) {
+		pr_err("Couldn't toggle stat rc=%d\n", rc);
+		goto cleanup;
+	}
+
+	rc = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+				       i2c_pmic_irq_handler,
+				       IRQF_ONESHOT | IRQF_SHARED,
+				       "i2c_pmic_stat_irq", chip);
+	if (rc < 0) {
+		pr_err("Couldn't request irq %d rc=%d\n", client->irq, rc);
+		goto cleanup;
+	}
+
+	chip->summary_irq = client->irq;
+	enable_irq_wake(client->irq);
+
+probe_children:
+	of_platform_populate(chip->dev->of_node, NULL, NULL, chip->dev);
+	pr_info("I2C PMIC probe successful\n");
+	return rc;
+
+cleanup:
+	if (chip->domain)
+		irq_domain_remove(chip->domain);
+	i2c_set_clientdata(client, NULL);
+	return rc;
+}
+
+static void i2c_pmic_remove(struct i2c_client *client)
+{
+	struct i2c_pmic *chip = i2c_get_clientdata(client);
+
+	of_platform_depopulate(chip->dev);
+	if (chip->domain)
+		irq_domain_remove(chip->domain);
+	i2c_set_clientdata(client, NULL);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int i2c_pmic_suspend_noirq(struct device *dev)
+{
+	struct i2c_pmic *chip = dev_get_drvdata(dev);
+
+	if (chip->irq_waiting) {
+		pr_err_ratelimited("Aborting suspend, an interrupt was detected while suspending\n");
+		return -EBUSY;
+	}
+	return 0;
+}
+
+static int i2c_pmic_suspend(struct device *dev)
+{
+	struct i2c_pmic *chip = dev_get_drvdata(dev);
+	struct i2c_pmic_periph *periph;
+	int rc = 0, i;
+
+	if (chip->summary_irq < 0)
+		return 0;
+
+	for (i = 0; i < chip->num_periphs; i++) {
+		periph = &chip->periph[i];
+
+		rc = regmap_write(chip->regmap,
+				  periph->addr | INT_EN_CLR_OFFSET, 0xFF);
+		if (rc < 0) {
+			pr_err_ratelimited("Couldn't clear 0x%04x irqs rc=%d\n",
+				periph->addr, rc);
+			continue;
+		}
+
+		rc = regmap_write(chip->regmap,
+				  periph->addr | INT_EN_SET_OFFSET,
+				  periph->wake);
+		if (rc < 0)
+			pr_err_ratelimited("Couldn't enable 0x%04x wake irqs 0x%02x rc=%d\n",
+			       periph->addr, periph->wake, rc);
+	}
+	if (!rc) {
+		mutex_lock(&chip->irq_complete);
+		chip->resume_completed = false;
+		mutex_unlock(&chip->irq_complete);
+	}
+
+	return rc;
+}
+
+static int i2c_pmic_resume(struct device *dev)
+{
+	struct i2c_pmic *chip = dev_get_drvdata(dev);
+	struct i2c_pmic_periph *periph;
+	int rc = 0, i;
+
+	if (chip->summary_irq < 0)
+		return 0;
+
+	for (i = 0; i < chip->num_periphs; i++) {
+		periph = &chip->periph[i];
+
+		rc = regmap_write(chip->regmap,
+				  periph->addr | INT_EN_CLR_OFFSET, 0xFF);
+		if (rc < 0) {
+			pr_err("Couldn't clear 0x%04x irqs rc=%d\n",
+				periph->addr, rc);
+			continue;
+		}
+
+		rc = regmap_write(chip->regmap,
+				  periph->addr | INT_EN_SET_OFFSET,
+				  periph->synced[IRQ_EN_SET]);
+		if (rc < 0)
+			pr_err("Couldn't restore 0x%04x synced irqs 0x%02x rc=%d\n",
+			       periph->addr, periph->synced[IRQ_EN_SET], rc);
+	}
+
+	mutex_lock(&chip->irq_complete);
+	chip->resume_completed = true;
+	if (chip->irq_waiting) {
+		mutex_unlock(&chip->irq_complete);
+		/* irq was pending, call the handler */
+		i2c_pmic_irq_handler(chip->summary_irq, chip);
+		enable_irq(chip->summary_irq);
+	} else {
+		mutex_unlock(&chip->irq_complete);
+	}
+
+	return rc;
+}
+#else
+static int i2c_pmic_suspend(struct device *dev)
+{
+	return 0;
+}
+static int i2c_pmic_resume(struct device *dev)
+{
+	return 0;
+}
+static int i2c_pmic_suspend_noirq(struct device *dev)
+{
+	return 0
+}
+#endif
+static const struct dev_pm_ops i2c_pmic_pm_ops = {
+	.suspend	= i2c_pmic_suspend,
+	.suspend_noirq	= i2c_pmic_suspend_noirq,
+	.resume		= i2c_pmic_resume,
+};
+
+static const struct of_device_id i2c_pmic_match_table[] = {
+	{ .compatible = "qcom,i2c-pmic", },
+	{ },
+};
+
+static const struct i2c_device_id i2c_pmic_id[] = {
+	{ "i2c-pmic", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, i2c_pmic_id);
+
+static struct i2c_driver i2c_pmic_driver = {
+	.driver		= {
+		.name		= "i2c_pmic",
+		.pm		= &i2c_pmic_pm_ops,
+		.of_match_table	= i2c_pmic_match_table,
+	},
+	.probe		= i2c_pmic_probe,
+	.remove		= i2c_pmic_remove,
+	.id_table	= i2c_pmic_id,
+};
+
+module_i2c_driver(i2c_pmic_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("i2c:i2c_pmic");
--- linux-qcom-6.8.0.orig/drivers/mfd/rsmu_core.c
+++ linux-qcom-6.8.0/drivers/mfd/rsmu_core.c
@@ -78,11 +78,13 @@
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(rsmu_core_init);
 
 void rsmu_core_exit(struct rsmu_ddata *rsmu)
 {
 	mutex_destroy(&rsmu->lock);
 }
+EXPORT_SYMBOL_GPL(rsmu_core_exit);
 
 MODULE_DESCRIPTION("Renesas SMU core driver");
 MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/mfd/rt5033.c
+++ linux-qcom-6.8.0/drivers/mfd/rt5033.c
@@ -81,8 +81,8 @@
 	chip_rev = dev_id & RT5033_CHIP_REV_MASK;
 	dev_info(&i2c->dev, "Device found (rev. %d)\n", chip_rev);
 
-	ret = regmap_add_irq_chip(rt5033->regmap, rt5033->irq,
-			IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+	ret = devm_regmap_add_irq_chip(rt5033->dev, rt5033->regmap,
+			rt5033->irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 			0, &rt5033_irq_chip, &rt5033->irq_data);
 	if (ret) {
 		dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
--- linux-qcom-6.8.0.orig/drivers/mfd/syscon.c
+++ linux-qcom-6.8.0/drivers/mfd/syscon.c
@@ -8,12 +8,14 @@
  * Author: Dong Aisheng <dong.aisheng@linaro.org>
  */
 
+#include <linux/cleanup.h>
 #include <linux/clk.h>
 #include <linux/err.h>
 #include <linux/hwspinlock.h>
 #include <linux/io.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/mutex.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
@@ -26,7 +28,7 @@
 
 static struct platform_driver syscon_driver;
 
-static DEFINE_SPINLOCK(syscon_list_slock);
+static DEFINE_MUTEX(syscon_list_lock);
 static LIST_HEAD(syscon_list);
 
 struct syscon {
@@ -45,7 +47,6 @@
 static struct syscon *of_syscon_register(struct device_node *np, bool check_res)
 {
 	struct clk *clk;
-	struct syscon *syscon;
 	struct regmap *regmap;
 	void __iomem *base;
 	u32 reg_io_width;
@@ -54,20 +55,18 @@
 	struct resource res;
 	struct reset_control *reset;
 
-	syscon = kzalloc(sizeof(*syscon), GFP_KERNEL);
+	WARN_ON(!mutex_is_locked(&syscon_list_lock));
+
+	struct syscon *syscon __free(kfree) = kzalloc(sizeof(*syscon), GFP_KERNEL);
 	if (!syscon)
 		return ERR_PTR(-ENOMEM);
 
-	if (of_address_to_resource(np, 0, &res)) {
-		ret = -ENOMEM;
-		goto err_map;
-	}
+	if (of_address_to_resource(np, 0, &res))
+		return ERR_PTR(-ENOMEM);
 
 	base = of_iomap(np, 0);
-	if (!base) {
-		ret = -ENOMEM;
-		goto err_map;
-	}
+	if (!base)
+		return ERR_PTR(-ENOMEM);
 
 	/* Parse the device's DT node for an endianness specification */
 	if (of_property_read_bool(np, "big-endian"))
@@ -148,11 +147,9 @@
 	syscon->regmap = regmap;
 	syscon->np = np;
 
-	spin_lock(&syscon_list_slock);
 	list_add_tail(&syscon->list, &syscon_list);
-	spin_unlock(&syscon_list_slock);
 
-	return syscon;
+	return_ptr(syscon);
 
 err_reset:
 	reset_control_put(reset);
@@ -163,8 +160,6 @@
 	regmap_exit(regmap);
 err_regmap:
 	iounmap(base);
-err_map:
-	kfree(syscon);
 	return ERR_PTR(ret);
 }
 
@@ -173,7 +168,7 @@
 {
 	struct syscon *entry, *syscon = NULL;
 
-	spin_lock(&syscon_list_slock);
+	mutex_lock(&syscon_list_lock);
 
 	list_for_each_entry(entry, &syscon_list, list)
 		if (entry->np == np) {
@@ -181,17 +176,65 @@
 			break;
 		}
 
-	spin_unlock(&syscon_list_slock);
-
 	if (!syscon)
 		syscon = of_syscon_register(np, check_res);
 
+	mutex_unlock(&syscon_list_lock);
+
 	if (IS_ERR(syscon))
 		return ERR_CAST(syscon);
 
 	return syscon->regmap;
 }
 
+/**
+ * of_syscon_register_regmap() - Register regmap for specified device node
+ * @np: Device tree node
+ * @regmap: Pointer to regmap object
+ *
+ * Register an externally created regmap object with syscon for the specified
+ * device tree node. This regmap will then be returned to client drivers using
+ * the syscon_regmap_lookup_by_phandle() API.
+ *
+ * Return: 0 on success, negative error code on failure.
+ */
+int of_syscon_register_regmap(struct device_node *np, struct regmap *regmap)
+{
+	struct syscon *entry, *syscon = NULL;
+	int ret;
+
+	if (!np || !regmap)
+		return -EINVAL;
+
+	syscon = kzalloc(sizeof(*syscon), GFP_KERNEL);
+	if (!syscon)
+		return -ENOMEM;
+
+	/* check if syscon entry already exists */
+	mutex_lock(&syscon_list_lock);
+
+	list_for_each_entry(entry, &syscon_list, list)
+		if (entry->np == np) {
+			ret = -EEXIST;
+			goto err_unlock;
+		}
+
+	syscon->regmap = regmap;
+	syscon->np = np;
+
+	/* register the regmap in syscon list */
+	list_add_tail(&syscon->list, &syscon_list);
+	mutex_unlock(&syscon_list_lock);
+
+	return 0;
+
+err_unlock:
+	mutex_unlock(&syscon_list_lock);
+	kfree(syscon);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(of_syscon_register_regmap);
+
 struct regmap *device_node_to_regmap(struct device_node *np)
 {
 	return device_node_get_regmap(np, false);
@@ -238,7 +281,9 @@
 		return ERR_PTR(-ENODEV);
 
 	regmap = syscon_node_to_regmap(syscon_np);
-	of_node_put(syscon_np);
+
+	if (property)
+		of_node_put(syscon_np);
 
 	return regmap;
 }
--- linux-qcom-6.8.0.orig/drivers/mfd/ti_am335x_tscadc.c
+++ linux-qcom-6.8.0/drivers/mfd/ti_am335x_tscadc.c
@@ -119,8 +119,6 @@
 	struct clk *clk;
 	struct device_node *node;
 	struct mfd_cell *cell;
-	struct property *prop;
-	const __be32 *cur;
 	bool use_tsc = false, use_mag = false;
 	u32 val;
 	int err;
@@ -167,7 +165,7 @@
 	}
 
 	node = of_get_child_by_name(pdev->dev.of_node, "adc");
-	of_property_for_each_u32(node, "ti,adc-channels", prop, cur, val) {
+	of_property_for_each_u32(node, "ti,adc-channels", val) {
 		adc_channels++;
 		if (val > 7) {
 			dev_err(&pdev->dev, " PIN numbers are 0..7 (not %d)\n",
--- linux-qcom-6.8.0.orig/drivers/mfd/tps65010.c
+++ linux-qcom-6.8.0/drivers/mfd/tps65010.c
@@ -544,17 +544,13 @@
 	 */
 	if (client->irq > 0) {
 		status = request_irq(client->irq, tps65010_irq,
-				     IRQF_TRIGGER_FALLING, DRIVER_NAME, tps);
+				     IRQF_TRIGGER_FALLING | IRQF_NO_AUTOEN,
+				     DRIVER_NAME, tps);
 		if (status < 0) {
 			dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
 					client->irq, status);
 			return status;
 		}
-		/* annoying race here, ideally we'd have an option
-		 * to claim the irq now and enable it later.
-		 * FIXME genirq IRQF_NOAUTOEN now solves that ...
-		 */
-		disable_irq(client->irq);
 		set_bit(FLAG_IRQ_ENABLE, &tps->flags);
 	} else
 		dev_warn(&client->dev, "IRQ not configured!\n");
--- linux-qcom-6.8.0.orig/drivers/misc/Kconfig
+++ linux-qcom-6.8.0/drivers/misc/Kconfig
@@ -276,6 +276,14 @@
 	  to maintain PMIC register and RTC state in the absence of
 	  external power.
 
+config QCOM_DCC
+	tristate "Qualcomm Technologies, Inc. Data Capture and Compare (DCC) engine driver"
+	depends on ARCH_QCOM || COMPILE_TEST
+	help
+	  This option enables the driver for the Data Capture and Compare engine. DCC
+	  driver provides interfaces to configure DCC block and read back the captured
+	  data from the DCC's internal SRAM. The module name for this is qcom-dcc.
+
 config QCOM_FASTRPC
 	tristate "Qualcomm FastRPC"
 	depends on ARCH_QCOM || COMPILE_TEST
--- linux-qcom-6.8.0.orig/drivers/misc/Makefile
+++ linux-qcom-6.8.0/drivers/misc/Makefile
@@ -16,6 +16,7 @@
 obj-$(CONFIG_TIFM_7XX1)       	+= tifm_7xx1.o
 obj-$(CONFIG_PHANTOM)		+= phantom.o
 obj-$(CONFIG_QCOM_COINCELL)	+= qcom-coincell.o
+obj-$(CONFIG_QCOM_DCC)		+= qcom-dcc.o
 obj-$(CONFIG_QCOM_FASTRPC)	+= fastrpc.o
 obj-$(CONFIG_SENSORS_BH1770)	+= bh1770glc.o
 obj-$(CONFIG_SENSORS_APDS990X)	+= apds990x.o
--- linux-qcom-6.8.0.orig/drivers/misc/apds990x.c
+++ linux-qcom-6.8.0/drivers/misc/apds990x.c
@@ -1147,7 +1147,7 @@
 		err = chip->pdata->setup_resources();
 		if (err) {
 			err = -EINVAL;
-			goto fail3;
+			goto fail4;
 		}
 	}
 
@@ -1155,7 +1155,7 @@
 				apds990x_attribute_group);
 	if (err < 0) {
 		dev_err(&chip->client->dev, "Sysfs registration failed\n");
-		goto fail4;
+		goto fail5;
 	}
 
 	err = request_threaded_irq(client->irq, NULL,
@@ -1166,15 +1166,17 @@
 	if (err) {
 		dev_err(&client->dev, "could not get IRQ %d\n",
 			client->irq);
-		goto fail5;
+		goto fail6;
 	}
 	return err;
-fail5:
+fail6:
 	sysfs_remove_group(&chip->client->dev.kobj,
 			&apds990x_attribute_group[0]);
-fail4:
+fail5:
 	if (chip->pdata && chip->pdata->release_resources)
 		chip->pdata->release_resources();
+fail4:
+	pm_runtime_disable(&client->dev);
 fail3:
 	regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
 fail2:
--- linux-qcom-6.8.0.orig/drivers/misc/cardreader/rtsx_pcr.c
+++ linux-qcom-6.8.0/drivers/misc/cardreader/rtsx_pcr.c
@@ -1002,7 +1002,7 @@
 		} else {
 			pcr->card_removed |= SD_EXIST;
 			pcr->card_inserted &= ~SD_EXIST;
-			if (PCI_PID(pcr) == PID_5261) {
+			if ((PCI_PID(pcr) == PID_5261) || (PCI_PID(pcr) == PID_5264)) {
 				rtsx_pci_write_register(pcr, RTS5261_FW_STATUS,
 					RTS5261_EXPRESS_LINK_FAIL_MASK, 0);
 				pcr->extra_caps |= EXTRA_CAPS_SD_EXPRESS;
--- linux-qcom-6.8.0.orig/drivers/misc/eeprom/at24.c
+++ linux-qcom-6.8.0/drivers/misc/eeprom/at24.c
@@ -758,15 +758,6 @@
 	}
 	pm_runtime_enable(dev);
 
-	at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
-	if (IS_ERR(at24->nvmem)) {
-		pm_runtime_disable(dev);
-		if (!pm_runtime_status_suspended(dev))
-			regulator_disable(at24->vcc_reg);
-		return dev_err_probe(dev, PTR_ERR(at24->nvmem),
-				     "failed to register nvmem\n");
-	}
-
 	/*
 	 * Perform a one-byte test read to verify that the chip is functional,
 	 * unless powering on the device is to be avoided during probe (i.e.
@@ -782,6 +773,15 @@
 		}
 	}
 
+	at24->nvmem = devm_nvmem_register(dev, &nvmem_config);
+	if (IS_ERR(at24->nvmem)) {
+		pm_runtime_disable(dev);
+		if (!pm_runtime_status_suspended(dev))
+			regulator_disable(at24->vcc_reg);
+		return dev_err_probe(dev, PTR_ERR(at24->nvmem),
+				     "failed to register nvmem\n");
+	}
+
 	/* If this a SPD EEPROM, probe for DDR3 thermal sensor */
 	if (cdata == &at24_data_spd)
 		at24_probe_temp_sensor(client);
--- linux-qcom-6.8.0.orig/drivers/misc/eeprom/digsy_mtc_eeprom.c
+++ linux-qcom-6.8.0/drivers/misc/eeprom/digsy_mtc_eeprom.c
@@ -42,7 +42,7 @@
 }
 
 struct eeprom_93xx46_platform_data digsy_mtc_eeprom_data = {
-	.flags		= EE_ADDR8,
+	.flags		= EE_ADDR8 | EE_SIZE1K,
 	.prepare	= digsy_mtc_op_prepare,
 	.finish		= digsy_mtc_op_finish,
 };
--- linux-qcom-6.8.0.orig/drivers/misc/eeprom/ee1004.c
+++ linux-qcom-6.8.0/drivers/misc/eeprom/ee1004.c
@@ -185,6 +185,8 @@
 static void ee1004_probe_temp_sensor(struct i2c_client *client)
 {
 	struct i2c_board_info info = { .type = "jc42" };
+	unsigned short addr = 0x18 | (client->addr & 7);
+	unsigned short addr_list[] = { addr, I2C_CLIENT_END };
 	u8 byte14;
 	int ret;
 
@@ -193,9 +195,7 @@
 	if (ret != 1 || !(byte14 & BIT(7)))
 		return;
 
-	info.addr = 0x18 | (client->addr & 7);
-
-	i2c_new_client_device(client->adapter, &info);
+	i2c_new_scanned_device(client->adapter, &info, addr_list, NULL);
 }
 
 static void ee1004_cleanup(int idx, struct ee1004_bus_data *bd)
--- linux-qcom-6.8.0.orig/drivers/misc/eeprom/eeprom_93cx6.c
+++ linux-qcom-6.8.0/drivers/misc/eeprom/eeprom_93cx6.c
@@ -186,6 +186,11 @@
 	eeprom_93cx6_write_bits(eeprom, command,
 		PCI_EEPROM_WIDTH_OPCODE + eeprom->width);
 
+	if (has_quirk_extra_read_cycle(eeprom)) {
+		eeprom_93cx6_pulse_high(eeprom);
+		eeprom_93cx6_pulse_low(eeprom);
+	}
+
 	/*
 	 * Read the requested 16 bits.
 	 */
@@ -252,6 +257,11 @@
 	eeprom_93cx6_write_bits(eeprom, command,
 		PCI_EEPROM_WIDTH_OPCODE + eeprom->width + 1);
 
+	if (has_quirk_extra_read_cycle(eeprom)) {
+		eeprom_93cx6_pulse_high(eeprom);
+		eeprom_93cx6_pulse_low(eeprom);
+	}
+
 	/*
 	 * Read the requested 8 bits.
 	 */
--- linux-qcom-6.8.0.orig/drivers/misc/fastrpc.c
+++ linux-qcom-6.8.0/drivers/misc/fastrpc.c
@@ -19,16 +19,24 @@
 #include <linux/rpmsg.h>
 #include <linux/scatterlist.h>
 #include <linux/slab.h>
+#include <linux/delay.h>
 #include <linux/firmware/qcom/qcom_scm.h>
 #include <uapi/misc/fastrpc.h>
 #include <linux/of_reserved_mem.h>
+#include <linux/soc/qcom/pdr.h>
+
+#define FASTRPC_IOCTL_INVOKEV2		_IOWR('R', 14, struct fastrpc_invoke_v2)
 
 #define ADSP_DOMAIN_ID (0)
 #define MDSP_DOMAIN_ID (1)
 #define SDSP_DOMAIN_ID (2)
 #define CDSP_DOMAIN_ID (3)
-#define FASTRPC_DEV_MAX		4 /* adsp, mdsp, slpi, cdsp*/
+#define CDSP1_DOMAIN_ID (4)
+#define GDSP0_DOMAIN_ID (5)
+#define GDSP1_DOMAIN_ID (6)
+#define FASTRPC_DEV_MAX		7 /* adsp, mdsp, slpi, cdsp, cdsp1, gdsp0, gdsp1 */
 #define FASTRPC_MAX_SESSIONS	14
+#define FASTRPC_MAX_SPD		4
 #define FASTRPC_MAX_VMIDS	16
 #define FASTRPC_ALIGN		128
 #define FASTRPC_MAX_FDLIST	16
@@ -37,8 +45,10 @@
 #define FASTRPC_CTX_MAX (256)
 #define FASTRPC_INIT_HANDLE	1
 #define FASTRPC_DSP_UTILITIES_HANDLE	2
-#define FASTRPC_CTXID_MASK (0xFF0)
-#define INIT_FILELEN_MAX (2 * 1024 * 1024)
+#define FASTRPC_MAX_STATIC_HANDLE (20)
+#define FASTRPC_CTXID_MASK (0xFF0000)
+#define FASTRPC_CLIENTID_MASK (16)
+#define INIT_FILELEN_MAX (5 * 1024 * 1024)
 #define INIT_FILE_NAMELEN_MAX (128)
 #define FASTRPC_DEVICE_NAME	"fastrpc"
 
@@ -98,6 +108,9 @@
 #define FASTRPC_RMID_INIT_MEM_MAP      10
 #define FASTRPC_RMID_INIT_MEM_UNMAP    11
 
+/* Fastrpc attribute for no mapping of fd  */
+#define FASTRPC_ATTR_NOMAP (16)
+
 /* Protection Domain(PD) ids */
 #define ROOT_PD		(0)
 #define USER_PD		(1)
@@ -105,8 +118,48 @@
 
 #define miscdev_to_fdevice(d) container_of(d, struct fastrpc_device, miscdev)
 
+#define AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME   "audio_pdr_adsp"
+#define AUDIO_PDR_ADSP_SERVICE_NAME              "avs/audio"
+#define ADSP_AUDIOPD_NAME                        "msm/adsp/audio_pd"
+
+#define SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME   "sensors_pdr_adsp"
+#define SENSORS_PDR_ADSP_SERVICE_NAME              "tms/servreg"
+#define ADSP_SENSORPD_NAME                       "msm/adsp/sensor_pd"
+
+#define SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME "sensors_pdr_slpi"
+#define SENSORS_PDR_SLPI_SERVICE_NAME            SENSORS_PDR_ADSP_SERVICE_NAME
+#define SLPI_SENSORPD_NAME                       "msm/slpi/sensor_pd"
+
+#define FASTRPC_KERNEL_PERF_LIST (PERF_KEY_MAX)
+#define FASTRPC_DSP_PERF_LIST 12
+
+/* Poll response number from remote processor for call completion */
+#define FASTRPC_POLL_RESPONSE (0xdecaf)
+/* timeout in us for polling until memory barrier */
+#define FASTRPC_POLL_TIME_MEM_UPDATE (500)
+
+/* Response types supported for RPC calls */
+enum fastrpc_response_flags {
+	/* normal job completion glink response */
+	NORMAL_RESPONSE = 0,
+	/* process updates poll memory instead of glink response */
+	POLL_MODE = 1,
+};
+
 static const char *domains[FASTRPC_DEV_MAX] = { "adsp", "mdsp",
-						"sdsp", "cdsp"};
+						"sdsp", "cdsp",
+						"cdsp1", "gdsp0",
+						"gdsp1"};
+
+struct fastrpc_invoke_v2 {
+	struct fastrpc_invoke inv;
+	__u64 crc;
+	__u64 perf_kernel;
+	__u64 perf_dsp;
+	__u64 poll_timeout;
+	__u32 reserved[18];
+};
+
 struct fastrpc_phy_page {
 	u64 addr;		/* physical address */
 	u64 size;		/* size of contiguous region */
@@ -196,6 +249,7 @@
 	struct dma_buf *dmabuf;
 	struct device *dev;
 	void *virt;
+	u32 flag;
 	u64 phys;
 	u64 size;
 	/* Lock for dma buf attachments */
@@ -228,6 +282,18 @@
 	struct kref refcount;
 };
 
+struct fastrpc_perf {
+	u64 count;
+	u64 flush;
+	u64 map;
+	u64 copy;
+	u64 link;
+	u64 getargs;
+	u64 putargs;
+	u64 invargs;
+	u64 invoke;
+};
+
 struct fastrpc_invoke_ctx {
 	int nscalars;
 	int nbufs;
@@ -236,12 +302,19 @@
 	int tgid;
 	u32 sc;
 	u32 *crc;
+	u64 *perf_kernel;
+	u64 *perf_dsp;
 	u64 ctxid;
 	u64 msg_sz;
+	/* Threads poll for specified timeout and fall back to glink wait */
+	u64 poll_timeout;
+	/* work done status flag */
+	bool is_work_done;
+	/* response flags from remote processor */
+	enum fastrpc_response_flags rsp_flags;
 	struct kref refcount;
 	struct list_head node; /* list of ctxs */
 	struct completion work;
-	struct work_struct put_work;
 	struct fastrpc_msg msg;
 	struct fastrpc_user *fl;
 	union fastrpc_remote_arg *rpra;
@@ -250,6 +323,7 @@
 	struct fastrpc_invoke_args *args;
 	struct fastrpc_buf_overlap *olaps;
 	struct fastrpc_channel_ctx *cctx;
+	struct fastrpc_perf *perf;
 };
 
 struct fastrpc_session_ctx {
@@ -257,6 +331,18 @@
 	int sid;
 	bool used;
 	bool valid;
+	struct mutex map_mutex;
+};
+
+struct fastrpc_static_pd {
+	char *servloc_name;
+	char *spdname;
+	void *pdrhandle;
+	u64 pdrcount;
+	u64 prevpdrcount;
+	atomic_t ispdup;
+	int domain;
+	struct fastrpc_channel_ctx *cctx;
 };
 
 struct fastrpc_channel_ctx {
@@ -266,17 +352,18 @@
 	struct qcom_scm_vmperm vmperms[FASTRPC_MAX_VMIDS];
 	struct rpmsg_device *rpdev;
 	struct fastrpc_session_ctx session[FASTRPC_MAX_SESSIONS];
+	struct fastrpc_static_pd spd[FASTRPC_MAX_SPD];
 	spinlock_t lock;
 	struct idr ctx_idr;
 	struct list_head users;
 	struct kref refcount;
 	/* Flag if dsp attributes are cached */
 	bool valid_attributes;
+	bool staticpd_status;
 	u32 dsp_attributes[FASTRPC_MAX_DSP_ATTRIBUTES];
 	struct fastrpc_device *secure_fdevice;
 	struct fastrpc_device *fdevice;
-	struct fastrpc_buf *remote_heap;
-	struct list_head invoke_interrupted_mmaps;
+	struct list_head rhmaps;
 	bool secure;
 	bool unsigned_support;
 	u64 dma_mask;
@@ -298,42 +385,100 @@
 	struct fastrpc_session_ctx *sctx;
 	struct fastrpc_buf *init_mem;
 
-	int tgid;
+	int client_id;
 	int pd;
 	bool is_secure_dev;
+	bool is_unsigned_pd;
+	char *servloc_name;
 	/* Lock for lists */
 	spinlock_t lock;
 	/* lock for allocations */
 	struct mutex mutex;
 };
 
+enum fastrpc_perfkeys {
+	PERF_COUNT = 0,
+	PERF_FLUSH = 1,
+	PERF_MAP = 2,
+	PERF_COPY = 3,
+	PERF_LINK = 4,
+	PERF_GETARGS = 5,
+	PERF_PUTARGS = 6,
+	PERF_INVARGS = 7,
+	PERF_INVOKE = 8,
+	PERF_KEY_MAX = 9,
+};
+
+#define PERF_END ((void)0)
+
+#define PERF(enb, cnt, ff) \
+	{\
+		struct timespec64 startT = {0};\
+		u64 *counter = cnt;\
+		if (enb && counter) {\
+			ktime_get_boottime_ts64(&startT);\
+		} \
+		ff ;\
+		if (enb && counter) {\
+			*counter += getnstimediff(&startT);\
+		} \
+	}
+
+#define GET_COUNTER(perf_ptr, offset)  \
+	(perf_ptr != NULL ?\
+		(((offset >= 0) && (offset < PERF_KEY_MAX)) ?\
+			(u64 *)(perf_ptr + offset)\
+				: (u64 *)NULL) : (u64 *)NULL)
+
+static inline int64_t getnstimediff(struct timespec64 *start)
+{
+	int64_t ns;
+	struct timespec64 ts, b;
+
+	ktime_get_boottime_ts64(&ts);
+	b = timespec64_sub(ts, *start);
+	ns = timespec64_to_ns(&b);
+	return ns;
+}
+
 static void fastrpc_free_map(struct kref *ref)
 {
 	struct fastrpc_map *map;
+	struct fastrpc_user *fl;
 
 	map = container_of(ref, struct fastrpc_map, refcount);
 
+	fl = map->fl;
+	if (!fl)
+		return;
+
 	if (map->table) {
 		if (map->attr & FASTRPC_ATTR_SECUREMAP) {
 			struct qcom_scm_vmperm perm;
-			int vmid = map->fl->cctx->vmperms[0].vmid;
+			int vmid = fl->cctx->vmperms[0].vmid;
 			u64 src_perms = BIT(QCOM_SCM_VMID_HLOS) | BIT(vmid);
 			int err = 0;
 
 			perm.vmid = QCOM_SCM_VMID_HLOS;
 			perm.perm = QCOM_SCM_PERM_RWX;
-			err = qcom_scm_assign_mem(map->phys, map->size,
+			err = qcom_scm_assign_mem(map->phys, map->len,
 				&src_perms, &perm, 1);
 			if (err) {
-				dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d",
-						map->phys, map->size, err);
+				dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n",
+						map->phys, map->len, err);
 				return;
 			}
 		}
+		mutex_lock(&fl->sctx->map_mutex);
+		if (!fl->sctx->dev) {
+			mutex_unlock(&fl->sctx->map_mutex);
+			return;
+		}
 		dma_buf_unmap_attachment_unlocked(map->attach, map->table,
 						  DMA_BIDIRECTIONAL);
 		dma_buf_detach(map->buf, map->attach);
 		dma_buf_put(map->buf);
+		mutex_unlock(&fl->sctx->map_mutex);
 	}
 
 	if (map->fl) {
@@ -362,7 +507,7 @@
 
 
 static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd,
-			    struct fastrpc_map **ppmap, bool take_ref)
+			u64 va, u64 len, struct fastrpc_map **ppmap, bool take_ref)
 {
 	struct fastrpc_session_ctx *sess = fl->sctx;
 	struct fastrpc_map *map = NULL;
@@ -370,7 +515,8 @@
 
 	spin_lock(&fl->lock);
 	list_for_each_entry(map, &fl->maps, node) {
-		if (map->fd != fd)
+		if (map->fd != fd || va < (u64)map->va ||
+				va + len > (u64)map->va + map->size)
 			continue;
 
 		if (take_ref) {
@@ -391,13 +537,26 @@
 	return ret;
 }
 
-static void fastrpc_buf_free(struct fastrpc_buf *buf)
+static void __fastrpc_buf_free(struct fastrpc_buf *buf)
 {
 	dma_free_coherent(buf->dev, buf->size, buf->virt,
 			  FASTRPC_PHYS(buf->phys));
 	kfree(buf);
 }
 
+static void fastrpc_buf_free(struct fastrpc_buf *buf)
+{
+	struct fastrpc_user *fl = buf->fl;
+
+	if (!fl)
+		return;
+
+	mutex_lock(&fl->sctx->map_mutex);
+	if (fl->sctx->dev)
+		__fastrpc_buf_free(buf);
+	mutex_unlock(&fl->sctx->map_mutex);
+}
+
 static int __fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev,
 			     u64 size, struct fastrpc_buf **obuf)
 {
@@ -418,8 +577,11 @@
 	buf->dev = dev;
 	buf->raddr = 0;
 
-	buf->virt = dma_alloc_coherent(dev, buf->size, (dma_addr_t *)&buf->phys,
-				       GFP_KERNEL);
+	mutex_lock(&fl->sctx->map_mutex);
+	if (fl->sctx->dev)
+		buf->virt = dma_alloc_coherent(dev, buf->size, (dma_addr_t *)&buf->phys,
+						   GFP_KERNEL);
+	mutex_unlock(&fl->sctx->map_mutex);
 	if (!buf->virt) {
 		mutex_destroy(&buf->lock);
 		kfree(buf);
@@ -460,8 +622,11 @@
 static void fastrpc_channel_ctx_free(struct kref *ref)
 {
 	struct fastrpc_channel_ctx *cctx;
+	int i;
 
 	cctx = container_of(ref, struct fastrpc_channel_ctx, refcount);
+	for (i = 0; i < FASTRPC_MAX_SESSIONS; i++)
+		mutex_destroy(&cctx->session[i].map_mutex);
 
 	kfree(cctx);
 }
@@ -493,9 +658,10 @@
 		fastrpc_buf_free(ctx->buf);
 
 	spin_lock_irqsave(&cctx->lock, flags);
-	idr_remove(&cctx->ctx_idr, ctx->ctxid >> 4);
+	idr_remove(&cctx->ctx_idr, ctx->ctxid >> 16);
 	spin_unlock_irqrestore(&cctx->lock, flags);
 
+	kfree(ctx->perf);
 	kfree(ctx->maps);
 	kfree(ctx->olaps);
 	kfree(ctx);
@@ -503,24 +669,11 @@
 	fastrpc_channel_ctx_put(cctx);
 }
 
-static void fastrpc_context_get(struct fastrpc_invoke_ctx *ctx)
-{
-	kref_get(&ctx->refcount);
-}
-
 static void fastrpc_context_put(struct fastrpc_invoke_ctx *ctx)
 {
 	kref_put(&ctx->refcount, fastrpc_context_free);
 }
 
-static void fastrpc_context_put_wq(struct work_struct *work)
-{
-	struct fastrpc_invoke_ctx *ctx =
-			container_of(work, struct fastrpc_invoke_ctx, put_work);
-
-	fastrpc_context_put(ctx);
-}
-
 #define CMP(aa, bb) ((aa) == (bb) ? 0 : (aa) < (bb) ? -1 : 1)
 static int olaps_cmp(const void *a, const void *b)
 {
@@ -572,13 +725,15 @@
 
 static struct fastrpc_invoke_ctx *fastrpc_context_alloc(
 			struct fastrpc_user *user, u32 kernel, u32 sc,
-			struct fastrpc_invoke_args *args)
+			struct fastrpc_invoke_v2 *inv2)
 {
 	struct fastrpc_channel_ctx *cctx = user->cctx;
 	struct fastrpc_invoke_ctx *ctx = NULL;
+	struct fastrpc_invoke_args *args = NULL;
 	unsigned long flags;
 	int ret;
 
+	args = (struct fastrpc_invoke_args *)inv2->inv.args;
 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
 	if (!ctx)
 		return ERR_PTR(-ENOMEM);
@@ -610,13 +765,23 @@
 	/* Released in fastrpc_context_put() */
 	fastrpc_channel_ctx_get(cctx);
 
+	ctx->crc = (u32 *)(uintptr_t)inv2->crc;
+	ctx->perf_dsp = (u64 *)(uintptr_t)inv2->perf_dsp;
+	ctx->perf_kernel = (u64 *)(uintptr_t)inv2->perf_kernel;
+	ctx->poll_timeout = (u64)inv2->poll_timeout;
+	if (ctx->perf_kernel) {
+		ctx->perf = kzalloc(sizeof(*(ctx->perf)), GFP_KERNEL);
+		if (!ctx->perf)
+			return ERR_PTR(-ENOMEM);
+	}
 	ctx->sc = sc;
 	ctx->retval = -1;
 	ctx->pid = current->pid;
-	ctx->tgid = user->tgid;
+	ctx->tgid = user->client_id;
 	ctx->cctx = cctx;
+	ctx->rsp_flags = NORMAL_RESPONSE;
+	ctx->is_work_done = false;
 	init_completion(&ctx->work);
-	INIT_WORK(&ctx->put_work, fastrpc_context_put_wq);
 
 	spin_lock(&user->lock);
 	list_add_tail(&ctx->node, &user->pending);
@@ -629,7 +794,7 @@
 		spin_unlock_irqrestore(&cctx->lock, flags);
 		goto err_idr;
 	}
-	ctx->ctxid = ret << 4;
+	ctx->ctxid = ret << 16;
 	spin_unlock_irqrestore(&cctx->lock, flags);
 
 	kref_init(&ctx->refcount);
@@ -752,14 +917,17 @@
 };
 
 static int fastrpc_map_create(struct fastrpc_user *fl, int fd,
-			      u64 len, u32 attr, struct fastrpc_map **ppmap)
+				u64 va, u64 len, u32 attr,
+				struct fastrpc_map **ppmap, bool take_ref)
 {
 	struct fastrpc_session_ctx *sess = fl->sctx;
 	struct fastrpc_map *map = NULL;
 	struct sg_table *table;
-	int err = 0;
+	struct scatterlist *sgl = NULL;
+	struct device *dev = NULL;
+	int err = 0, sgl_index = 0;
 
-	if (!fastrpc_map_lookup(fl, fd, ppmap, true))
+	if (!fastrpc_map_lookup(fl, fd, va, len, ppmap, take_ref))
 		return 0;
 
 	map = kzalloc(sizeof(*map), GFP_KERNEL);
@@ -777,28 +945,46 @@
 		goto get_err;
 	}
 
-	map->attach = dma_buf_attach(map->buf, sess->dev);
+	if (attr & FASTRPC_ATTR_NOMAP)
+		dev = &fl->cctx->rpdev->dev;
+	else
+		dev = sess->dev;
+
+	mutex_lock(&fl->sctx->map_mutex);
+	if (!fl->sctx->dev) {
+		err = -ENODEV;
+		mutex_unlock(&fl->sctx->map_mutex);
+		goto attach_err;
+	}
+
+	map->attach = dma_buf_attach(map->buf, dev);
 	if (IS_ERR(map->attach)) {
-		dev_err(sess->dev, "Failed to attach dmabuf\n");
+		dev_err(dev, "Failed to attach dmabuf\n");
 		err = PTR_ERR(map->attach);
+		mutex_unlock(&fl->sctx->map_mutex);
 		goto attach_err;
 	}
 
 	table = dma_buf_map_attachment_unlocked(map->attach, DMA_BIDIRECTIONAL);
 	if (IS_ERR(table)) {
 		err = PTR_ERR(table);
+		mutex_unlock(&fl->sctx->map_mutex);
 		goto map_err;
 	}
 	map->table = table;
+	mutex_unlock(&fl->sctx->map_mutex);
 
 	if (attr & FASTRPC_ATTR_SECUREMAP) {
 		map->phys = sg_phys(map->table->sgl);
 	} else {
 		map->phys = sg_dma_address(map->table->sgl);
-		map->phys += ((u64)fl->sctx->sid << 32);
+		if (!(attr & FASTRPC_ATTR_NOMAP))
+			map->phys += ((u64)fl->sctx->sid << 32);
 	}
-	map->size = len;
-	map->va = sg_virt(map->table->sgl);
+	for_each_sg(map->table->sgl, sgl, map->table->nents,
+		sgl_index)
+		map->size += sg_dma_len(sgl);
+	map->va = (void *)(uintptr_t)va;
 	map->len = len;
 
 	if (attr & FASTRPC_ATTR_SECUREMAP) {
@@ -814,10 +1000,10 @@
 		dst_perms[1].vmid = fl->cctx->vmperms[0].vmid;
 		dst_perms[1].perm = QCOM_SCM_PERM_RWX;
 		map->attr = attr;
-		err = qcom_scm_assign_mem(map->phys, (u64)map->size, &src_perms, dst_perms, 2);
+		err = qcom_scm_assign_mem(map->phys, (u64)map->len, &src_perms, dst_perms, 2);
 		if (err) {
-			dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d",
-					map->phys, map->size, err);
+			dev_err(dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n",
+					map->phys, map->len, err);
 			goto map_err;
 		}
 	}
@@ -873,7 +1059,8 @@
 		sizeof(struct fastrpc_invoke_buf) +
 		sizeof(struct fastrpc_phy_page)) * ctx->nscalars +
 		sizeof(u64) * FASTRPC_MAX_FDLIST +
-		sizeof(u32) * FASTRPC_MAX_CRCLIST;
+		sizeof(u32) * FASTRPC_MAX_CRCLIST +
+		sizeof(u32) + sizeof(u64) * FASTRPC_DSP_PERF_LIST;
 
 	return size;
 }
@@ -905,13 +1092,17 @@
 	int i, err;
 
 	for (i = 0; i < ctx->nscalars; ++i) {
+		bool take_ref = true;
 
 		if (ctx->args[i].fd == 0 || ctx->args[i].fd == -1 ||
 		    ctx->args[i].length == 0)
 			continue;
 
+		if (i >= ctx->nbufs)
+			take_ref = false;
 		err = fastrpc_map_create(ctx->fl, ctx->args[i].fd,
-			 ctx->args[i].length, ctx->args[i].attr, &ctx->maps[i]);
+			 (u64)ctx->args[i].ptr, ctx->args[i].length,
+			 ctx->args[i].attr, &ctx->maps[i], take_ref);
 		if (err) {
 			dev_err(dev, "Error Creating map %d\n", err);
 			return -EINVAL;
@@ -947,7 +1138,9 @@
 	metalen = fastrpc_get_meta_size(ctx);
 	pkt_size = fastrpc_get_payload_size(ctx, metalen);
 
+	PERF(ctx->perf_kernel, GET_COUNTER((u64 *)ctx->perf, PERF_MAP),
 	err = fastrpc_create_maps(ctx);
+	PERF_END);
 	if (err)
 		return err;
 
@@ -980,6 +1173,7 @@
 			continue;
 
 		if (ctx->maps[i]) {
+			PERF(ctx->perf_kernel, GET_COUNTER((u64 *)ctx->perf, PERF_MAP),
 			struct vm_area_struct *vma = NULL;
 
 			rpra[i].buf.pv = (u64) ctx->args[i].ptr;
@@ -988,7 +1182,7 @@
 			mmap_read_lock(current->mm);
 			vma = find_vma(current->mm, ctx->args[i].ptr);
 			if (vma)
-				pages[i].addr += ctx->args[i].ptr -
+				pages[i].addr += (ctx->args[i].ptr & PAGE_MASK) -
 						 vma->vm_start;
 			mmap_read_unlock(current->mm);
 
@@ -996,9 +1190,9 @@
 			pg_end = ((ctx->args[i].ptr + len - 1) & PAGE_MASK) >>
 				  PAGE_SHIFT;
 			pages[i].size = (pg_end - pg_start + 1) * PAGE_SIZE;
-
+			PERF_END);
 		} else {
-
+			PERF(ctx->perf_kernel, GET_COUNTER((u64 *)ctx->perf, PERF_COPY),
 			if (ctx->olaps[oix].offset == 0) {
 				rlen -= ALIGN(args, FASTRPC_ALIGN) - args;
 				args = ALIGN(args, FASTRPC_ALIGN);
@@ -1015,17 +1209,19 @@
 					(pkt_size - rlen);
 			pages[i].addr = pages[i].addr &	PAGE_MASK;
 
-			pg_start = (args & PAGE_MASK) >> PAGE_SHIFT;
-			pg_end = ((args + len - 1) & PAGE_MASK) >> PAGE_SHIFT;
+			pg_start = (rpra[i].buf.pv & PAGE_MASK) >> PAGE_SHIFT;
+			pg_end = ((rpra[i].buf.pv + len - 1) & PAGE_MASK) >> PAGE_SHIFT;
 			pages[i].size = (pg_end - pg_start + 1) * PAGE_SIZE;
 			args = args + mlen;
 			rlen -= mlen;
+			PERF_END);
 		}
 
 		if (i < inbufs && !ctx->maps[i]) {
 			void *dst = (void *)(uintptr_t)rpra[i].buf.pv;
 			void *src = (void *)(uintptr_t)ctx->args[i].ptr;
 
+			PERF(ctx->perf_kernel, GET_COUNTER((u64 *)ctx->perf, PERF_COPY),
 			if (!kernel) {
 				if (copy_from_user(dst, (void __user *)src,
 						   len)) {
@@ -1035,6 +1231,7 @@
 			} else {
 				memcpy(dst, src, len);
 			}
+			PERF_END);
 		}
 	}
 
@@ -1065,8 +1262,9 @@
 	struct fastrpc_map *mmap = NULL;
 	struct fastrpc_invoke_buf *list;
 	struct fastrpc_phy_page *pages;
-	u64 *fdlist;
-	int i, inbufs, outbufs, handles;
+	u64 *fdlist, *perf_dsp_list;
+	u32 *crclist, *poll;
+	int i, inbufs, outbufs, handles, perferr;
 
 	inbufs = REMOTE_SCALARS_INBUFS(ctx->sc);
 	outbufs = REMOTE_SCALARS_OUTBUFS(ctx->sc);
@@ -1074,6 +1272,9 @@
 	list = fastrpc_invoke_buf_start(rpra, ctx->nscalars);
 	pages = fastrpc_phy_page_start(list, ctx->nscalars);
 	fdlist = (uint64_t *)(pages + inbufs + outbufs + handles);
+	crclist = (u32 *)(fdlist + FASTRPC_MAX_FDLIST);
+	poll = (u32 *)(crclist + FASTRPC_MAX_CRCLIST);
+	perf_dsp_list = (u64 *)(poll + 1);
 
 	for (i = inbufs; i < ctx->nbufs; ++i) {
 		if (!ctx->maps[i]) {
@@ -1094,10 +1295,23 @@
 	for (i = 0; i < FASTRPC_MAX_FDLIST; i++) {
 		if (!fdlist[i])
 			break;
-		if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap, false))
+		if (!fastrpc_map_lookup(fl, (int)fdlist[i], 0, 0, &mmap, false))
 			fastrpc_map_put(mmap);
 	}
 
+	if (ctx->crc && crclist && rpra) {
+		if (copy_to_user((void __user *)ctx->crc, crclist,
+				FASTRPC_MAX_CRCLIST * sizeof(u32)))
+			return -EFAULT;
+	}
+
+	if (ctx->perf_dsp && perf_dsp_list) {
+		perferr = copy_to_user((void __user *)ctx->perf_dsp,
+				perf_dsp_list, FASTRPC_DSP_PERF_LIST * sizeof(u64));
+		if (perferr)
+			dev_info(fl->sctx->dev, "Warning: failed to copy perf data %d\n", perferr);
+	}
+
 	return 0;
 }
 
@@ -1111,7 +1325,7 @@
 	int ret;
 
 	cctx = fl->cctx;
-	msg->pid = fl->tgid;
+	msg->pid = fl->client_id;
 	msg->tid = current->pid;
 
 	if (kernel)
@@ -1122,66 +1336,200 @@
 	msg->sc = ctx->sc;
 	msg->addr = ctx->buf ? ctx->buf->phys : 0;
 	msg->size = roundup(ctx->msg_sz, PAGE_SIZE);
-	fastrpc_context_get(ctx);
 
-	ret = rpmsg_send(cctx->rpdev->ept, (void *)msg, sizeof(*msg));
+	if (cctx->rpdev == NULL)
+		return -EPIPE;
 
-	if (ret)
-		fastrpc_context_put(ctx);
+	ret = rpmsg_send(cctx->rpdev->ept, (void *)msg, sizeof(*msg));
 
 	return ret;
 
 }
 
-static int fastrpc_internal_invoke(struct fastrpc_user *fl,  u32 kernel,
-				   u32 handle, u32 sc,
-				   struct fastrpc_invoke_args *args)
+static int fastrpc_get_spd_session(struct fastrpc_channel_ctx *cctx,
+				char *servloc_name)
 {
-	struct fastrpc_invoke_ctx *ctx = NULL;
-	struct fastrpc_buf *buf, *b;
+	int i, session = -1;
 
+	for (i = 0; i < FASTRPC_MAX_SPD ; i++) {
+		if (!cctx->spd[i].servloc_name)
+			continue;
+		if (!strcmp(servloc_name, cctx->spd[i].servloc_name)) {
+			session = i;
+			break;
+		}
+	}
+
+	return session;
+}
+
+static void fastrpc_update_invoke_count(u32 handle, u64 *perf_counter,
+					struct timespec64 *invoket)
+{
+	/* update invoke count for dynamic handles */
+	u64 *invcount, *count;
+
+	if (handle <= FASTRPC_MAX_STATIC_HANDLE)
+		return;
+
+	invcount = GET_COUNTER(perf_counter, PERF_INVOKE);
+	if (invcount)
+		*invcount += getnstimediff(invoket);
+
+	count = GET_COUNTER(perf_counter, PERF_COUNT);
+	if (count)
+		*count++;
+}
+
+static int poll_for_remote_response(struct fastrpc_invoke_ctx *ctx, u64 timeout)
+{
+	int err = -EIO, i, j;
+	u32 sc = ctx->sc;
+	struct fastrpc_invoke_buf *list;
+	struct fastrpc_phy_page *pages;
+	u64 *fdlist = NULL;
+	u32 *crclist = NULL, *poll = NULL;
+	unsigned int inbufs, outbufs, handles;
+
+	/* calculate poll memory location */
+	inbufs = REMOTE_SCALARS_INBUFS(sc);
+	outbufs = REMOTE_SCALARS_OUTBUFS(sc);
+	handles = REMOTE_SCALARS_INHANDLES(sc) + REMOTE_SCALARS_OUTHANDLES(sc);
+	list = fastrpc_invoke_buf_start(ctx->rpra, ctx->nscalars);
+	pages = fastrpc_phy_page_start(list, ctx->nscalars);
+	fdlist = (u64 *)(pages + inbufs + outbufs + handles);
+	crclist = (u32 *)(fdlist + FASTRPC_MAX_FDLIST);
+	poll = (u32 *)(crclist + FASTRPC_MAX_CRCLIST);
+
+	/* poll on memory for DSP response. Return failure on timeout */
+	for (i = 0, j = 0; i < timeout; i++, j++) {
+		if (*poll == FASTRPC_POLL_RESPONSE) {
+			err = 0;
+			ctx->is_work_done = true;
+			ctx->retval = 0;
+			break;
+		}
+		if (j == FASTRPC_POLL_TIME_MEM_UPDATE) {
+			/* make sure that all poll memory writes by DSP are seen by CPU */
+			dma_rmb();
+			j = 0;
+		}
+		udelay(1);
+	}
+	return err;
+}
+
+static inline int fastrpc_wait_for_response(struct fastrpc_invoke_ctx *ctx,
+						u32 kernel)
+{
 	int err = 0;
 
+	if (kernel) {
+		if (!wait_for_completion_timeout(&ctx->work, 10 * HZ))
+			err = -ETIMEDOUT;
+	} else {
+		err = wait_for_completion_interruptible(&ctx->work);
+	}
+
+	return err;
+}
+
+static int fastrpc_wait_for_completion(struct fastrpc_invoke_ctx *ctx,
+										u32 kernel)
+{
+	int err;
+
+	do {
+		switch (ctx->rsp_flags) {
+		case NORMAL_RESPONSE:
+			err = fastrpc_wait_for_response(ctx, kernel);
+			if (err || ctx->is_work_done)
+				return err;
+			break;
+		case POLL_MODE:
+			err = poll_for_remote_response(ctx, ctx->poll_timeout);
+			/* If polling timed out, move to normal response mode */
+			if (err)
+				ctx->rsp_flags = NORMAL_RESPONSE;
+			break;
+		default:
+			err = -EBADR;
+			dev_dbg(ctx->fl->sctx->dev,
+				"unsupported response type:0x%x\n", ctx->rsp_flags);
+			break;
+		}
+	} while (!ctx->is_work_done);
+
+	return err;
+}
+
+static int fastrpc_internal_invoke(struct fastrpc_user *fl,
+			u32 kernel, struct fastrpc_invoke_v2 *inv2)
+{
+	struct fastrpc_invoke_ctx *ctx = NULL;
+	struct fastrpc_invoke inv;
+	u32 handle, sc;
+	int err = 0, perferr = 0;
+	struct timespec64 invoket = {0};
+
+	if (inv2->perf_kernel)
+		ktime_get_boottime_ts64(&invoket);
+
 	if (!fl->sctx)
 		return -EINVAL;
 
 	if (!fl->cctx->rpdev)
 		return -EPIPE;
 
+	inv = inv2->inv;
+	handle = inv.handle;
+	sc = inv.sc;
 	if (handle == FASTRPC_INIT_HANDLE && !kernel) {
 		dev_warn_ratelimited(fl->sctx->dev, "user app trying to send a kernel RPC message (%d)\n",  handle);
 		return -EPERM;
 	}
 
-	ctx = fastrpc_context_alloc(fl, kernel, sc, args);
+	ctx = fastrpc_context_alloc(fl, kernel, sc, inv2);
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
+	PERF(ctx->perf_kernel, GET_COUNTER((u64 *)ctx->perf, PERF_GETARGS),
 	err = fastrpc_get_args(kernel, ctx);
+	PERF_END);
 	if (err)
 		goto bail;
 
 	/* make sure that all CPU memory writes are seen by DSP */
 	dma_wmb();
+	PERF(ctx->perf_kernel, GET_COUNTER((u64 *)ctx->perf, PERF_LINK),
 	/* Send invoke buffer to remote dsp */
 	err = fastrpc_invoke_send(fl->sctx, ctx, kernel, handle);
+	PERF_END);
 	if (err)
 		goto bail;
 
-	if (kernel) {
-		if (!wait_for_completion_timeout(&ctx->work, 10 * HZ))
-			err = -ETIMEDOUT;
-	} else {
-		err = wait_for_completion_interruptible(&ctx->work);
-	}
+	if (ctx->poll_timeout != 0 && handle > FASTRPC_MAX_STATIC_HANDLE &&
+		fl->cctx->domain_id == CDSP_DOMAIN_ID &&
+		fl->pd == USER_PD)
+		ctx->rsp_flags = POLL_MODE;
 
+	err = fastrpc_wait_for_completion(ctx, kernel);
 	if (err)
 		goto bail;
 
+	if (!ctx->is_work_done) {
+		err = -ETIMEDOUT;
+		dev_dbg(fl->sctx->dev, "Invalid workdone state for handle 0x%x, sc 0x%x\n",
+			handle, sc);
+		goto bail;
+	}
+
 	/* make sure that all memory writes by DSP are seen by CPU */
 	dma_rmb();
+	PERF(ctx->perf_kernel, GET_COUNTER((u64 *)ctx->perf, PERF_PUTARGS),
 	/* populate all the output buffers with results */
 	err = fastrpc_put_args(ctx, kernel);
+	PERF_END);
 	if (err)
 		goto bail;
 
@@ -1192,6 +1540,17 @@
 
 bail:
 	if (err != -ERESTARTSYS && err != -ETIMEDOUT) {
+		if (ctx) {
+			if (ctx->perf_kernel && !err)
+				fastrpc_update_invoke_count(handle, (u64 *)ctx->perf, &invoket);
+			if (ctx->perf_kernel && ctx->perf) {
+				perferr = copy_to_user((void __user *)ctx->perf_kernel,
+						ctx->perf, FASTRPC_KERNEL_PERF_LIST * sizeof(u64));
+				if (perferr)
+					dev_info(fl->sctx->dev,
+						"Warning: failed to copy perf data %d\n", perferr);
+			}
+		}
 		/* We are done with this compute context */
 		spin_lock(&fl->lock);
 		list_del(&ctx->node);
@@ -1199,13 +1558,6 @@
 		fastrpc_context_put(ctx);
 	}
 
-	if (err == -ERESTARTSYS) {
-		list_for_each_entry_safe(buf, b, &fl->mmaps, node) {
-			list_del(&buf->node);
-			list_add_tail(&buf->node, &fl->cctx->invoke_interrupted_mmaps);
-		}
-	}
-
 	if (err)
 		dev_dbg(fl->sctx->dev, "Error: Invoke Failed %d\n", err);
 
@@ -1230,20 +1582,81 @@
 	return false;
 }
 
+static int fastrpc_mmap_remove_ssr(struct fastrpc_channel_ctx *cctx)
+{
+	struct fastrpc_buf *buf, *b;
+	int err = 0;
+
+	list_for_each_entry_safe(buf, b, &cctx->rhmaps, node) {
+		if (cctx->vmcount) {
+			u64 src_perms = 0;
+			struct qcom_scm_vmperm dst_perms;
+			u32 i;
+
+			for (i = 0; i < cctx->vmcount; i++)
+				src_perms |= BIT(cctx->vmperms[i].vmid);
+
+			dst_perms.vmid = QCOM_SCM_VMID_HLOS;
+			dst_perms.perm = QCOM_SCM_PERM_RWX;
+			err = qcom_scm_assign_mem(buf->phys, (u64)buf->size,
+				&src_perms, &dst_perms, 1);
+			if (err) {
+				pr_err("%s: Failed to assign memory phys 0x%llx size 0x%llx err %d\n",
+					__func__, buf->phys, buf->size, err);
+				return err;
+			}
+		}
+		list_del(&buf->node);
+		__fastrpc_buf_free(buf);
+	}
+
+	return 0;
+}
+
+static int fastrpc_mmap_remove_pdr(struct fastrpc_user *fl)
+{
+	int err = 0, session = -1;
+
+	if (!fl)
+		return -EBADF;
+
+	session = fastrpc_get_spd_session(fl->cctx, fl->servloc_name);
+	if (session < 0)
+		return -EUSERS;
+
+	if (atomic_read(&fl->cctx->spd[session].ispdup) == 0)
+		return -ENOTCONN;
+
+	if (fl->cctx->spd[session].pdrcount !=
+		fl->cctx->spd[session].prevpdrcount) {
+		err = fastrpc_mmap_remove_ssr(fl->cctx);
+		if (err)
+			dev_info(&fl->cctx->rpdev->dev,
+				"failed to unmap remote heap (err %d)\n", err);
+		fl->cctx->spd[session].prevpdrcount =
+				fl->cctx->spd[session].pdrcount;
+	}
+
+	return err;
+}
+
 static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
 					      char __user *argp)
 {
 	struct fastrpc_init_create_static init;
 	struct fastrpc_invoke_args *args;
+	struct fastrpc_invoke_v2 ioctl = {0};
 	struct fastrpc_phy_page pages[1];
+	struct fastrpc_buf *buf = NULL;
+	u64 phys = 0, size = 0;
 	char *name;
 	int err;
+	bool scm_done = false;
 	struct {
 		int pgid;
 		u32 namelen;
 		u32 pageslen;
 	} inbuf;
-	u32 sc;
 
 	args = kcalloc(FASTRPC_CREATE_STATIC_PROCESS_NARGS, sizeof(*args), GFP_KERNEL);
 	if (!args)
@@ -1270,29 +1683,46 @@
 		goto err_name;
 	}
 
-	if (!fl->cctx->remote_heap) {
-		err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen,
-						&fl->cctx->remote_heap);
+	fl->servloc_name = AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME;
+
+	if (!strcmp(name, "audiopd")) {
+		/*
+		 * Remove any previous mappings in case process is trying
+		 * to reconnect after a PD restart on remote subsystem.
+		 */
+		err = fastrpc_mmap_remove_pdr(fl);
 		if (err)
 			goto err_name;
+	}
 
+	if (!fl->cctx->staticpd_status) {
+		err = fastrpc_remote_heap_alloc(fl, fl->sctx->dev, init.memlen, &buf);
+		if (err)
+			goto err_name;
+
+		phys = buf->phys;
+		size = buf->size;
 		/* Map if we have any heap VMIDs associated with this ADSP Static Process. */
 		if (fl->cctx->vmcount) {
 			u64 src_perms = BIT(QCOM_SCM_VMID_HLOS);
 
-			err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys,
-							(u64)fl->cctx->remote_heap->size,
+			err = qcom_scm_assign_mem(phys, (u64)size,
 							&src_perms,
 							fl->cctx->vmperms, fl->cctx->vmcount);
 			if (err) {
 				dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d",
-					fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err);
+					phys, size, err);
 				goto err_map;
 			}
+			scm_done = true;
 		}
+		fl->cctx->staticpd_status = true;
+		spin_lock(&fl->lock);
+		list_add_tail(&buf->node, &fl->cctx->rhmaps);
+		spin_unlock(&fl->lock);
 	}
 
-	inbuf.pgid = fl->tgid;
+	inbuf.pgid = fl->client_id;
 	inbuf.namelen = init.namelen;
 	inbuf.pageslen = 0;
 	fl->pd = USER_PD;
@@ -1305,25 +1735,26 @@
 	args[1].length = inbuf.namelen;
 	args[1].fd = -1;
 
-	pages[0].addr = fl->cctx->remote_heap->phys;
-	pages[0].size = fl->cctx->remote_heap->size;
+	pages[0].addr = phys;
+	pages[0].size = size;
 
 	args[2].ptr = (u64)(uintptr_t) pages;
 	args[2].length = sizeof(*pages);
 	args[2].fd = -1;
 
-	sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_STATIC, 3, 0);
-
-	err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
-				      sc, args);
+	ioctl.inv.handle = FASTRPC_INIT_HANDLE;
+	ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_STATIC, 3, 0);
+	ioctl.inv.args = (u64)args;
+	err = fastrpc_internal_invoke(fl, true, &ioctl);
 	if (err)
 		goto err_invoke;
 
 	kfree(args);
+	kfree(name);
 
 	return 0;
 err_invoke:
-	if (fl->cctx->vmcount) {
+	if (fl->cctx->vmcount && scm_done) {
 		u64 src_perms = 0;
 		struct qcom_scm_vmperm dst_perms;
 		u32 i;
@@ -1333,15 +1764,18 @@
 
 		dst_perms.vmid = QCOM_SCM_VMID_HLOS;
 		dst_perms.perm = QCOM_SCM_PERM_RWX;
-		err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys,
-						(u64)fl->cctx->remote_heap->size,
+		err = qcom_scm_assign_mem(phys, (u64)size,
 						&src_perms, &dst_perms, 1);
 		if (err)
 			dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d",
-				fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err);
+				phys, size, err);
 	}
 err_map:
-	fastrpc_buf_free(fl->cctx->remote_heap);
+	fl->cctx->staticpd_status = false;
+	spin_lock(&fl->lock);
+	list_del(&buf->node);
+	spin_unlock(&fl->lock);
+	__fastrpc_buf_free(buf);
 err_name:
 	kfree(name);
 err:
@@ -1355,6 +1789,7 @@
 {
 	struct fastrpc_init_create init;
 	struct fastrpc_invoke_args *args;
+	struct fastrpc_invoke_v2 ioctl = {0};
 	struct fastrpc_phy_page pages[1];
 	struct fastrpc_map *map = NULL;
 	struct fastrpc_buf *imem = NULL;
@@ -1368,8 +1803,6 @@
 		u32 attrs;
 		u32 siglen;
 	} inbuf;
-	u32 sc;
-	bool unsigned_module = false;
 
 	args = kcalloc(FASTRPC_CREATE_PROCESS_NARGS, sizeof(*args), GFP_KERNEL);
 	if (!args)
@@ -1381,9 +1814,9 @@
 	}
 
 	if (init.attrs & FASTRPC_MODE_UNSIGNED_MODULE)
-		unsigned_module = true;
+		fl->is_unsigned_pd = true;
 
-	if (is_session_rejected(fl, unsigned_module)) {
+	if (is_session_rejected(fl, fl->is_unsigned_pd)) {
 		err = -ECONNREFUSED;
 		goto err;
 	}
@@ -1393,7 +1826,7 @@
 		goto err;
 	}
 
-	inbuf.pgid = fl->tgid;
+	inbuf.pgid = fl->client_id;
 	inbuf.namelen = strlen(current->comm) + 1;
 	inbuf.filelen = init.filelen;
 	inbuf.pageslen = 1;
@@ -1402,7 +1835,8 @@
 	fl->pd = USER_PD;
 
 	if (init.filelen && init.filefd) {
-		err = fastrpc_map_create(fl, init.filefd, init.filelen, 0, &map);
+		err = fastrpc_map_create(fl, init.filefd, init.file,
+				init.filelen, 0, &map, true);
 		if (err)
 			goto err;
 	}
@@ -1442,16 +1876,17 @@
 	args[5].length = sizeof(inbuf.siglen);
 	args[5].fd = -1;
 
-	sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE, 4, 0);
+	ioctl.inv.handle = FASTRPC_INIT_HANDLE;
+	ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE, 4, 0);
 	if (init.attrs)
-		sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 4, 0);
-
-	err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
-				      sc, args);
+		ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 4, 0);
+	ioctl.inv.args = (u64)args;
+	err = fastrpc_internal_invoke(fl, true, &ioctl);
 	if (err)
 		goto err_invoke;
 
 	kfree(args);
+	fastrpc_map_put(map);
 
 	return 0;
 
@@ -1467,8 +1902,9 @@
 }
 
 static struct fastrpc_session_ctx *fastrpc_session_alloc(
-					struct fastrpc_channel_ctx *cctx)
+					struct fastrpc_user *fl)
 {
+	struct fastrpc_channel_ctx *cctx = fl->cctx;
 	struct fastrpc_session_ctx *session = NULL;
 	unsigned long flags;
 	int i;
@@ -1478,6 +1914,7 @@
 		if (!cctx->session[i].used && cctx->session[i].valid) {
 			cctx->session[i].used = true;
 			session = &cctx->session[i];
+			fl->client_id = FASTRPC_CLIENTID_MASK | i;
 			break;
 		}
 	}
@@ -1499,17 +1936,18 @@
 static int fastrpc_release_current_dsp_process(struct fastrpc_user *fl)
 {
 	struct fastrpc_invoke_args args[1];
+	struct fastrpc_invoke_v2 ioctl = {0};
 	int tgid = 0;
-	u32 sc;
 
-	tgid = fl->tgid;
+	tgid = fl->client_id;
 	args[0].ptr = (u64)(uintptr_t) &tgid;
 	args[0].length = sizeof(tgid);
 	args[0].fd = -1;
-	sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_RELEASE, 1, 0);
 
-	return fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
-				       sc, &args[0]);
+	ioctl.inv.handle = FASTRPC_INIT_HANDLE;
+	ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_RELEASE, 1, 0);
+	ioctl.inv.args = (u64)args;
+	return fastrpc_internal_invoke(fl, true, &ioctl);
 }
 
 static int fastrpc_device_release(struct inode *inode, struct file *file)
@@ -1563,6 +2001,9 @@
 	fdevice = miscdev_to_fdevice(filp->private_data);
 	cctx = fdevice->cctx;
 
+	if (!cctx->rpdev)
+		return -ENODEV;
+
 	fl = kzalloc(sizeof(*fl), GFP_KERNEL);
 	if (!fl)
 		return -ENOMEM;
@@ -1577,11 +2018,10 @@
 	INIT_LIST_HEAD(&fl->maps);
 	INIT_LIST_HEAD(&fl->mmaps);
 	INIT_LIST_HEAD(&fl->user);
-	fl->tgid = current->tgid;
 	fl->cctx = cctx;
 	fl->is_secure_dev = fdevice->secure;
 
-	fl->sctx = fastrpc_session_alloc(cctx);
+	fl->sctx = fastrpc_session_alloc(fl);
 	if (!fl->sctx) {
 		dev_err(&cctx->rpdev->dev, "No session available\n");
 		mutex_destroy(&fl->mutex);
@@ -1645,45 +2085,84 @@
 static int fastrpc_init_attach(struct fastrpc_user *fl, int pd)
 {
 	struct fastrpc_invoke_args args[1];
-	int tgid = fl->tgid;
-	u32 sc;
+	struct fastrpc_invoke_v2 ioctl = {0};
+	int tgid = fl->client_id;
 
 	args[0].ptr = (u64)(uintptr_t) &tgid;
 	args[0].length = sizeof(tgid);
 	args[0].fd = -1;
-	sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_ATTACH, 1, 0);
 	fl->pd = pd;
+	if (pd == SENSORS_PD) {
+		if (fl->cctx->domain_id == ADSP_DOMAIN_ID)
+			fl->servloc_name = SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME;
+		else if (fl->cctx->domain_id == SDSP_DOMAIN_ID)
+			fl->servloc_name = SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME;
+	}
 
-	return fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE,
-				       sc, &args[0]);
+	ioctl.inv.handle = FASTRPC_INIT_HANDLE;
+	ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_ATTACH, 1, 0);
+	ioctl.inv.args = (u64)args;
+	return fastrpc_internal_invoke(fl, true, &ioctl);
 }
 
-static int fastrpc_invoke(struct fastrpc_user *fl, char __user *argp)
+static int fastrpc_copy_args(struct fastrpc_invoke *inv)
 {
 	struct fastrpc_invoke_args *args = NULL;
-	struct fastrpc_invoke inv;
 	u32 nscalars;
-	int err;
-
-	if (copy_from_user(&inv, argp, sizeof(inv)))
-		return -EFAULT;
 
 	/* nscalars is truncated here to max supported value */
-	nscalars = REMOTE_SCALARS_LENGTH(inv.sc);
+	nscalars = REMOTE_SCALARS_LENGTH(inv->sc);
 	if (nscalars) {
 		args = kcalloc(nscalars, sizeof(*args), GFP_KERNEL);
 		if (!args)
 			return -ENOMEM;
 
-		if (copy_from_user(args, (void __user *)(uintptr_t)inv.args,
+		if (copy_from_user(args, (void __user *)(uintptr_t)inv->args,
 				   nscalars * sizeof(*args))) {
 			kfree(args);
 			return -EFAULT;
 		}
 	}
+	inv->args = args;
 
-	err = fastrpc_internal_invoke(fl, false, inv.handle, inv.sc, args);
-	kfree(args);
+	return 0;
+}
+
+static int fastrpc_invoke(struct fastrpc_user *fl, char __user *argp)
+{
+	struct fastrpc_invoke_v2 ioctl = {0};
+	struct fastrpc_invoke inv;
+	u32 nscalars;
+	int err;
+
+	if (copy_from_user(&inv, argp, sizeof(inv)))
+		return -EFAULT;
+
+	err = fastrpc_copy_args(&inv);
+	if (err)
+		return err;
+
+	ioctl.inv = inv;
+	err = fastrpc_internal_invoke(fl, false, &ioctl);
+	kfree(inv.args);
+
+	return err;
+}
+
+static int fastrpc_invokev2(struct fastrpc_user *fl, char __user *argp)
+{
+	struct fastrpc_invoke_v2 inv2 = {0};
+	int err;
+
+	if (copy_from_user(&inv2, argp, sizeof(inv2)))
+		return -EFAULT;
+
+	err = fastrpc_copy_args(&inv2.inv);
+	if (err)
+		return err;
+
+	err = fastrpc_internal_invoke(fl, false, &inv2);
+	kfree(inv2.inv.args);
 
 	return err;
 }
@@ -1692,20 +2171,27 @@
 				     uint32_t dsp_attr_buf_len)
 {
 	struct fastrpc_invoke_args args[2] = { 0 };
+	struct fastrpc_invoke_v2 ioctl = {0};
 
-	/* Capability filled in userspace */
+	/*
+	 * Capability filled in userspace. This carries the information
+	 * about the remoteproc support which is fetched from the remoteproc
+	 * sysfs node by userspace.
+	 */
 	dsp_attr_buf[0] = 0;
+	dsp_attr_buf_len -= 1;
 
 	args[0].ptr = (u64)(uintptr_t)&dsp_attr_buf_len;
 	args[0].length = sizeof(dsp_attr_buf_len);
 	args[0].fd = -1;
 	args[1].ptr = (u64)(uintptr_t)&dsp_attr_buf[1];
-	args[1].length = dsp_attr_buf_len;
+	args[1].length = dsp_attr_buf_len * sizeof(u32);
 	args[1].fd = -1;
-	fl->pd = USER_PD;
 
-	return fastrpc_internal_invoke(fl, true, FASTRPC_DSP_UTILITIES_HANDLE,
-				       FASTRPC_SCALARS(0, 1, 1), args);
+	ioctl.inv.handle = FASTRPC_DSP_UTILITIES_HANDLE;
+	ioctl.inv.sc = FASTRPC_SCALARS(0, 1, 1);
+	ioctl.inv.args = (u64)args;
+	return fastrpc_internal_invoke(fl, true, &ioctl);
 }
 
 static int fastrpc_get_info_from_kernel(struct fastrpc_ioctl_capability *cap,
@@ -1730,7 +2216,7 @@
 	if (!dsp_attributes)
 		return -ENOMEM;
 
-	err = fastrpc_get_info_from_dsp(fl, dsp_attributes, FASTRPC_MAX_DSP_ATTRIBUTES_LEN);
+	err = fastrpc_get_info_from_dsp(fl, dsp_attributes, FASTRPC_MAX_DSP_ATTRIBUTES);
 	if (err == DSP_UNSUPPORTED_API) {
 		dev_info(&cctx->rpdev->dev,
 			 "Warning: DSP capabilities not supported on domain: %d\n", domain);
@@ -1783,7 +2269,7 @@
 	if (err)
 		return err;
 
-	if (copy_to_user(argp, &cap.capability, sizeof(cap.capability)))
+	if (copy_to_user(argp, &cap, sizeof(cap)))
 		return -EFAULT;
 
 	return 0;
@@ -1792,22 +2278,43 @@
 static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *buf)
 {
 	struct fastrpc_invoke_args args[1] = { [0] = { 0 } };
+	struct fastrpc_invoke_v2 ioctl = {0};
 	struct fastrpc_munmap_req_msg req_msg;
 	struct device *dev = fl->sctx->dev;
 	int err;
-	u32 sc;
 
-	req_msg.pgid = fl->tgid;
+	req_msg.pgid = fl->client_id;
 	req_msg.size = buf->size;
 	req_msg.vaddr = buf->raddr;
 
 	args[0].ptr = (u64) (uintptr_t) &req_msg;
 	args[0].length = sizeof(req_msg);
 
-	sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MUNMAP, 1, 0);
-	err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc,
-				      &args[0]);
+	ioctl.inv.handle = FASTRPC_INIT_HANDLE;
+	ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MUNMAP, 1, 0);
+	ioctl.inv.args = (u64)args;
+	err = fastrpc_internal_invoke(fl, true, &ioctl);
 	if (!err) {
+		if (buf->flag == ADSP_MMAP_REMOTE_HEAP_ADDR) {
+			if (fl->cctx->vmcount) {
+				u64 src_perms = 0;
+				struct qcom_scm_vmperm dst_perms;
+				u32 i;
+
+				for (i = 0; i < fl->cctx->vmcount; i++)
+					src_perms |= BIT(fl->cctx->vmperms[i].vmid);
+
+				dst_perms.vmid = QCOM_SCM_VMID_HLOS;
+				dst_perms.perm = QCOM_SCM_PERM_RWX;
+				err = qcom_scm_assign_mem(buf->phys, (u64)buf->size,
+								&src_perms, &dst_perms, 1);
+				if (err) {
+					dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n",
+						buf->phys, buf->size, err);
+					return err;
+				}
+			}
+		}
 		dev_dbg(dev, "unmmap\tpt 0x%09lx OK\n", buf->raddr);
 		spin_lock(&fl->lock);
 		list_del(&buf->node);
@@ -1824,7 +2331,12 @@
 {
 	struct fastrpc_buf *buf = NULL, *iter, *b;
 	struct fastrpc_req_munmap req;
+	struct fastrpc_munmap_req_msg req_msg;
+	struct fastrpc_map *map = NULL, *iterm, *m;
 	struct device *dev = fl->sctx->dev;
+	struct fastrpc_invoke_args args[1] = { [0] = { 0 } };
+	struct fastrpc_invoke_v2 ioctl = {0};
+	int err = 0;
 
 	if (copy_from_user(&req, argp, sizeof(req)))
 		return -EFAULT;
@@ -1838,113 +2350,209 @@
 	}
 	spin_unlock(&fl->lock);
 
-	if (!buf) {
-		dev_err(dev, "mmap\t\tpt 0x%09llx [len 0x%08llx] not in list\n",
-			req.vaddrout, req.size);
+	if (buf) {
+		err = fastrpc_req_munmap_impl(fl, buf);
+		return err;
+	}
+
+	spin_lock(&fl->lock);
+	list_for_each_entry_safe(iter, b, &fl->cctx->rhmaps, node) {
+		if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) {
+			buf = iter;
+			break;
+		}
+	}
+	spin_unlock(&fl->lock);
+	if (buf) {
+		err = fastrpc_req_munmap_impl(fl, buf);
+		return err;
+	}
+	spin_lock(&fl->lock);
+	list_for_each_entry_safe(iterm, m, &fl->maps, node) {
+		if (iterm->raddr == req.vaddrout) {
+			map = iterm;
+			break;
+		}
+	}
+	spin_unlock(&fl->lock);
+	if (!map) {
+		dev_err(dev, "map not in list\n");
 		return -EINVAL;
 	}
 
-	return fastrpc_req_munmap_impl(fl, buf);
+	req_msg.pgid = fl->client_id;
+	req_msg.size = map->len;
+	req_msg.vaddr = map->raddr;
+
+	args[0].ptr = (u64) (uintptr_t) &req_msg;
+	args[0].length = sizeof(req_msg);
+
+	ioctl.inv.handle = FASTRPC_INIT_HANDLE;
+	ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MUNMAP, 1, 0);
+	ioctl.inv.args = (u64)args;
+	err = fastrpc_internal_invoke(fl, true, &ioctl);
+	if (err)
+		dev_err(dev, "unmmap\tpt fd = %d, 0x%09llx error\n",  map->fd, map->raddr);
+	else
+		fastrpc_map_put(map);
+
+	return err;
 }
 
 static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
 {
 	struct fastrpc_invoke_args args[3] = { [0 ... 2] = { 0 } };
+	struct fastrpc_invoke_v2 ioctl = {0};
 	struct fastrpc_buf *buf = NULL;
 	struct fastrpc_mmap_req_msg req_msg;
 	struct fastrpc_mmap_rsp_msg rsp_msg;
 	struct fastrpc_phy_page pages;
 	struct fastrpc_req_mmap req;
+	struct fastrpc_map *map = NULL;
 	struct device *dev = fl->sctx->dev;
 	int err;
-	u32 sc;
+	unsigned long flags;
 
 	if (copy_from_user(&req, argp, sizeof(req)))
 		return -EFAULT;
 
-	if (req.flags != ADSP_MMAP_ADD_PAGES && req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR) {
-		dev_err(dev, "flag not supported 0x%x\n", req.flags);
+	if (req.flags == ADSP_MMAP_ADD_PAGES || req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
+		if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->is_unsigned_pd) {
+			dev_err(dev, "secure memory allocation is not supported in unsigned PD\n");
+			return -EINVAL;
+		}
+		if (req.vaddrin && !fl->is_unsigned_pd) {
+			dev_err(dev, "adding user allocated pages is not supported\n");
+			return -EINVAL;
+		}
 
-		return -EINVAL;
-	}
+		if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR)
+			err = fastrpc_remote_heap_alloc(fl, dev, req.size, &buf);
+		else
+			err = fastrpc_buf_alloc(fl, dev, req.size, &buf);
 
-	if (req.vaddrin) {
-		dev_err(dev, "adding user allocated pages is not supported\n");
-		return -EINVAL;
-	}
+		if (err) {
+			dev_err(dev, "failed to allocate buffer\n");
+			return err;
+		}
 
-	if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR)
-		err = fastrpc_remote_heap_alloc(fl, dev, req.size, &buf);
-	else
-		err = fastrpc_buf_alloc(fl, dev, req.size, &buf);
+		req_msg.pgid = fl->client_id;
+		req_msg.flags = req.flags;
+		req_msg.vaddr = req.vaddrin;
+		req_msg.num = sizeof(pages);
 
-	if (err) {
-		dev_err(dev, "failed to allocate buffer\n");
-		return err;
-	}
+		args[0].ptr = (u64) (uintptr_t) &req_msg;
+		args[0].length = sizeof(req_msg);
 
-	req_msg.pgid = fl->tgid;
-	req_msg.flags = req.flags;
-	req_msg.vaddr = req.vaddrin;
-	req_msg.num = sizeof(pages);
+		pages.addr = buf->phys;
+		pages.size = buf->size;
 
-	args[0].ptr = (u64) (uintptr_t) &req_msg;
-	args[0].length = sizeof(req_msg);
+		args[1].ptr = (u64) (uintptr_t) &pages;
+		args[1].length = sizeof(pages);
 
-	pages.addr = buf->phys;
-	pages.size = buf->size;
+		args[2].ptr = (u64) (uintptr_t) &rsp_msg;
+		args[2].length = sizeof(rsp_msg);
 
-	args[1].ptr = (u64) (uintptr_t) &pages;
-	args[1].length = sizeof(pages);
+		ioctl.inv.handle = FASTRPC_INIT_HANDLE;
+		ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MMAP, 2, 1);
+		ioctl.inv.args = (u64)args;
+		err = fastrpc_internal_invoke(fl, true, &ioctl);
+		if (err) {
+			dev_err(dev, "mmap error (len 0x%08llx)\n", buf->size);
+			fastrpc_buf_free(buf);
+			return err;
+		}
 
-	args[2].ptr = (u64) (uintptr_t) &rsp_msg;
-	args[2].length = sizeof(rsp_msg);
+		/* update the buffer to be able to deallocate the memory on the DSP */
+		buf->raddr = (uintptr_t) rsp_msg.vaddr;
+		buf->flag = req.flags;
 
-	sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MMAP, 2, 1);
-	err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc,
-				      &args[0]);
-	if (err) {
-		dev_err(dev, "mmap error (len 0x%08llx)\n", buf->size);
-		goto err_invoke;
-	}
+		/* let the client know the address to use */
+		req.vaddrout = rsp_msg.vaddr;
 
-	/* update the buffer to be able to deallocate the memory on the DSP */
-	buf->raddr = (uintptr_t) rsp_msg.vaddr;
+		/* Add memory to static PD pool, protection thru hypervisor */
+		if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) {
+			u64 src_perms = BIT(QCOM_SCM_VMID_HLOS);
 
-	/* let the client know the address to use */
-	req.vaddrout = rsp_msg.vaddr;
+			err = qcom_scm_assign_mem(buf->phys, (u64)buf->size,
+				&src_perms, fl->cctx->vmperms, fl->cctx->vmcount);
+			if (err) {
+				dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n",
+						buf->phys, buf->size, err);
+				goto err_assign;
+			}
+		}
 
-	/* Add memory to static PD pool, protection thru hypervisor */
-	if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) {
-		u64 src_perms = BIT(QCOM_SCM_VMID_HLOS);
+		if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR) {
+			spin_lock_irqsave(&fl->cctx->lock, flags);
+			list_add_tail(&buf->node, &fl->cctx->rhmaps);
+			spin_unlock_irqrestore(&fl->cctx->lock, flags);
+		} else {
+			spin_lock(&fl->lock);
+			list_add_tail(&buf->node, &fl->mmaps);
+			spin_unlock(&fl->lock);
+		}
 
-		err = qcom_scm_assign_mem(buf->phys, (u64)buf->size,
-			&src_perms, fl->cctx->vmperms, fl->cctx->vmcount);
-		if (err) {
-			dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d",
-					buf->phys, buf->size, err);
+		if (copy_to_user((void __user *)argp, &req, sizeof(req))) {
+			err = -EFAULT;
 			goto err_assign;
 		}
-	}
+	} else {
+		err = fastrpc_map_create(fl, req.fd, req.vaddrin, req.size,
+				0, &map, true);
+		if (err) {
+			dev_err(dev, "failed to map buffer, fd = %d\n", req.fd);
+			return err;
+		}
 
-	spin_lock(&fl->lock);
-	list_add_tail(&buf->node, &fl->mmaps);
-	spin_unlock(&fl->lock);
+		req_msg.pgid = fl->client_id;
+		req_msg.flags = req.flags;
+		req_msg.vaddr = req.vaddrin;
+		req_msg.num = sizeof(pages);
 
-	if (copy_to_user((void __user *)argp, &req, sizeof(req))) {
-		err = -EFAULT;
-		goto err_assign;
-	}
+		args[0].ptr = (u64) (uintptr_t) &req_msg;
+		args[0].length = sizeof(req_msg);
+
+		pages.addr = map->phys;
+		pages.size = map->len;
 
-	dev_dbg(dev, "mmap\t\tpt 0x%09lx OK [len 0x%08llx]\n",
-		buf->raddr, buf->size);
+		args[1].ptr = (u64) (uintptr_t) &pages;
+		args[1].length = sizeof(pages);
 
+		args[2].ptr = (u64) (uintptr_t) &rsp_msg;
+		args[2].length = sizeof(rsp_msg);
+
+		ioctl.inv.handle = FASTRPC_INIT_HANDLE;
+		ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MMAP, 2, 1);
+		ioctl.inv.args = (u64)args;
+		err = fastrpc_internal_invoke(fl, true, &ioctl);
+		if (err) {
+			dev_err(dev, "mmap error (len 0x%08llx)\n", map->len);
+			goto err_invoke;
+		}
+
+		/* update the buffer to be able to deallocate the memory on the DSP */
+		map->raddr = (uintptr_t) rsp_msg.vaddr;
+
+		/* let the client know the address to use */
+		req.vaddrout = rsp_msg.vaddr;
+
+		if (copy_to_user((void __user *)argp, &req, sizeof(req))) {
+			err = -EFAULT;
+			goto err_assign;
+		}
+	}
 	return 0;
 
 err_assign:
-	fastrpc_req_munmap_impl(fl, buf);
+	if (req.flags != ADSP_MMAP_ADD_PAGES && req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR)
+		fastrpc_map_put(map);
+	else
+		fastrpc_req_munmap_impl(fl, buf);
+
 err_invoke:
-	fastrpc_buf_free(buf);
+	if (map)
+		fastrpc_map_put(map);
 
 	return err;
 }
@@ -1952,10 +2560,10 @@
 static int fastrpc_req_mem_unmap_impl(struct fastrpc_user *fl, struct fastrpc_mem_unmap *req)
 {
 	struct fastrpc_invoke_args args[1] = { [0] = { 0 } };
+	struct fastrpc_invoke_v2 ioctl = {0};
 	struct fastrpc_map *map = NULL, *iter, *m;
 	struct fastrpc_mem_unmap_req_msg req_msg = { 0 };
 	int err = 0;
-	u32 sc;
 	struct device *dev = fl->sctx->dev;
 
 	spin_lock(&fl->lock);
@@ -1973,7 +2581,7 @@
 		return -EINVAL;
 	}
 
-	req_msg.pgid = fl->tgid;
+	req_msg.pgid = fl->client_id;
 	req_msg.len = map->len;
 	req_msg.vaddrin = map->raddr;
 	req_msg.fd = map->fd;
@@ -1981,9 +2589,10 @@
 	args[0].ptr = (u64) (uintptr_t) &req_msg;
 	args[0].length = sizeof(req_msg);
 
-	sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_UNMAP, 1, 0);
-	err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc,
-				      &args[0]);
+	ioctl.inv.handle = FASTRPC_INIT_HANDLE;
+	ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_UNMAP, 1, 0);
+	ioctl.inv.args = (u64)args;
+	err = fastrpc_internal_invoke(fl, true, &ioctl);
 	if (err) {
 		dev_err(dev, "unmmap\tpt fd = %d, 0x%09llx error\n",  map->fd, map->raddr);
 		return err;
@@ -2006,6 +2615,7 @@
 static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
 {
 	struct fastrpc_invoke_args args[4] = { [0 ... 3] = { 0 } };
+	struct fastrpc_invoke_v2 ioctl = {0};
 	struct fastrpc_mem_map_req_msg req_msg = { 0 };
 	struct fastrpc_mmap_rsp_msg rsp_msg = { 0 };
 	struct fastrpc_mem_unmap req_unmap = { 0 };
@@ -2014,19 +2624,19 @@
 	struct device *dev = fl->sctx->dev;
 	struct fastrpc_map *map = NULL;
 	int err;
-	u32 sc;
 
 	if (copy_from_user(&req, argp, sizeof(req)))
 		return -EFAULT;
 
 	/* create SMMU mapping */
-	err = fastrpc_map_create(fl, req.fd, req.length, 0, &map);
+	err = fastrpc_map_create(fl, req.fd, req.vaddrin, req.length,
+			0, &map, true);
 	if (err) {
 		dev_err(dev, "failed to map buffer, fd = %d\n", req.fd);
 		return err;
 	}
 
-	req_msg.pgid = fl->tgid;
+	req_msg.pgid = fl->client_id;
 	req_msg.fd = req.fd;
 	req_msg.offset = req.offset;
 	req_msg.vaddrin = req.vaddrin;
@@ -2039,7 +2649,7 @@
 	args[0].length = sizeof(req_msg);
 
 	pages.addr = map->phys;
-	pages.size = map->size;
+	pages.size = map->len;
 
 	args[1].ptr = (u64) (uintptr_t) &pages;
 	args[1].length = sizeof(pages);
@@ -2050,11 +2660,13 @@
 	args[3].ptr = (u64) (uintptr_t) &rsp_msg;
 	args[3].length = sizeof(rsp_msg);
 
-	sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_MAP, 3, 1);
-	err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, &args[0]);
+	ioctl.inv.handle = FASTRPC_INIT_HANDLE;
+	ioctl.inv.sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_MEM_MAP, 3, 1);
+	ioctl.inv.args = (u64)args;
+	err = fastrpc_internal_invoke(fl, true, &ioctl);
 	if (err) {
 		dev_err(dev, "mem mmap error, fd %d, vaddr %llx, size %lld\n",
-			req.fd, req.vaddrin, map->size);
+			req.fd, req.vaddrin, map->len);
 		goto err_invoke;
 	}
 
@@ -2067,7 +2679,7 @@
 	if (copy_to_user((void __user *)argp, &req, sizeof(req))) {
 		/* unmap the memory and release the buffer */
 		req_unmap.vaddr = (uintptr_t) rsp_msg.vaddr;
-		req_unmap.length = map->size;
+		req_unmap.length = map->len;
 		fastrpc_req_mem_unmap_impl(fl, &req_unmap);
 		return -EFAULT;
 	}
@@ -2087,10 +2699,14 @@
 	char __user *argp = (char __user *)arg;
 	int err;
 
+	fastrpc_channel_ctx_get(fl->cctx);
 	switch (cmd) {
 	case FASTRPC_IOCTL_INVOKE:
 		err = fastrpc_invoke(fl, argp);
 		break;
+	case FASTRPC_IOCTL_INVOKEV2:
+		err = fastrpc_invokev2(fl, argp);
+		break;
 	case FASTRPC_IOCTL_INIT_ATTACH:
 		err = fastrpc_init_attach(fl, ROOT_PD);
 		break;
@@ -2110,7 +2726,9 @@
 		err = fastrpc_req_mmap(fl, argp);
 		break;
 	case FASTRPC_IOCTL_MUNMAP:
+		mutex_lock(&fl->mutex);
 		err = fastrpc_req_munmap(fl, argp);
+		mutex_unlock(&fl->mutex);
 		break;
 	case FASTRPC_IOCTL_MEM_MAP:
 		err = fastrpc_req_mem_map(fl, argp);
@@ -2125,10 +2743,76 @@
 		err = -ENOTTY;
 		break;
 	}
+	fastrpc_channel_ctx_put(fl->cctx);
 
 	return err;
 }
 
+static void fastrpc_notify_users(struct fastrpc_user *user)
+{
+	struct fastrpc_invoke_ctx *ctx;
+
+	spin_lock(&user->lock);
+	list_for_each_entry(ctx, &user->pending, node) {
+		ctx->retval = -EPIPE;
+		ctx->is_work_done = true;
+		complete(&ctx->work);
+	}
+	spin_unlock(&user->lock);
+}
+
+static void fastrpc_notify_pdr_drivers(struct fastrpc_channel_ctx *cctx,
+		char *servloc_name)
+{
+	struct fastrpc_user *fl;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cctx->lock, flags);
+	list_for_each_entry(fl, &cctx->users, user) {
+		if (fl->servloc_name && !strcmp(servloc_name, fl->servloc_name))
+			fastrpc_notify_users(fl);
+	}
+	spin_unlock_irqrestore(&cctx->lock, flags);
+}
+
+static void fastrpc_pdr_cb(int state, char *service_path, void *priv)
+{
+	struct fastrpc_static_pd *spd = (struct fastrpc_static_pd *)priv;
+	unsigned long flags;
+
+	if (!spd)
+		return;
+
+	switch (state) {
+	case SERVREG_SERVICE_STATE_DOWN:
+		dev_info(&spd->cctx->rpdev->dev,
+			"%s: %s (%s) is down for PDR on %s\n",
+			__func__, spd->spdname,
+			spd->servloc_name,
+			domains[spd->domain]);
+		spin_lock_irqsave(&spd->cctx->lock, flags);
+		spd->pdrcount++;
+		atomic_set(&spd->ispdup, 0);
+		spin_unlock_irqrestore(&spd->cctx->lock, flags);
+		if (!strcmp(spd->servloc_name,
+				AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME))
+			spd->cctx->staticpd_status = false;
+
+		fastrpc_notify_pdr_drivers(spd->cctx, spd->servloc_name);
+		break;
+	case SERVREG_SERVICE_STATE_UP:
+		dev_info(&spd->cctx->rpdev->dev,
+			"%s: %s (%s) is up for PDR on %s\n",
+			__func__, spd->spdname,
+			spd->servloc_name,
+			domains[spd->domain]);
+		atomic_set(&spd->ispdup, 1);
+		break;
+	default:
+		break;
+	}
+}
+
 static const struct file_operations fastrpc_fops = {
 	.open = fastrpc_device_open,
 	.release = fastrpc_device_release,
@@ -2161,6 +2845,7 @@
 	sess->used = false;
 	sess->valid = true;
 	sess->dev = dev;
+	mutex_init(&sess->map_mutex);
 	dev_set_drvdata(dev, sess);
 
 	if (of_property_read_u32(dev->of_node, "reg", &sess->sid))
@@ -2174,6 +2859,7 @@
 				break;
 			dup_sess = &cctx->session[cctx->sesscount++];
 			memcpy(dup_sess, sess, sizeof(*dup_sess));
+			mutex_init(&dup_sess->map_mutex);
 		}
 	}
 	spin_unlock_irqrestore(&cctx->lock, flags);
@@ -2196,6 +2882,11 @@
 	spin_lock_irqsave(&cctx->lock, flags);
 	for (i = 0; i < FASTRPC_MAX_SESSIONS; i++) {
 		if (cctx->session[i].sid == sess->sid) {
+			spin_unlock_irqrestore(&cctx->lock, flags);
+			mutex_lock(&cctx->session[i].map_mutex);
+			cctx->session[i].dev = NULL;
+			mutex_unlock(&cctx->session[i].map_mutex);
+			spin_lock_irqsave(&cctx->lock, flags);
 			cctx->session[i].valid = false;
 			cctx->sesscount--;
 		}
@@ -2250,6 +2941,40 @@
 	return err;
 }
 
+static int fastrpc_setup_service_locator(struct fastrpc_channel_ctx *cctx, char *client_name,
+			char *service_name, char *service_path, int domain, int spd_session)
+{
+	int err = 0;
+	struct pdr_handle *handle = NULL;
+	struct pdr_service *service = NULL;
+
+	/* Register the service locator's callback function */
+	handle = pdr_handle_alloc(fastrpc_pdr_cb, &cctx->spd[spd_session]);
+	if (IS_ERR(handle)) {
+		err = PTR_ERR(handle);
+		goto bail;
+	}
+	cctx->spd[spd_session].domain = domain;
+	cctx->spd[spd_session].pdrhandle = handle;
+	cctx->spd[spd_session].servloc_name = client_name;
+	cctx->spd[spd_session].spdname = service_path;
+	cctx->spd[spd_session].cctx = cctx;
+	service = pdr_add_lookup(handle, service_name, service_path);
+	if (IS_ERR(service)) {
+		err = PTR_ERR(service);
+		goto bail;
+	}
+	pr_info("fastrpc: %s: pdr_add_lookup enabled for %s (%s, %s)\n",
+		__func__, service_name, client_name, service_path);
+
+bail:
+	if (err) {
+		pr_warn("fastrpc: %s: failed for %s (%s, %s)with err %d\n",
+				__func__, service_name, client_name, service_path, err);
+	}
+	return err;
+}
+
 static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
 {
 	struct device *rdev = &rpdev->dev;
@@ -2265,7 +2990,7 @@
 		return err;
 	}
 
-	for (i = 0; i <= CDSP_DOMAIN_ID; i++) {
+	for (i = 0; i < FASTRPC_DEV_MAX; i++) {
 		if (!strcmp(domains[i], domain)) {
 			domain_id = i;
 			break;
@@ -2306,13 +3031,16 @@
 	case ADSP_DOMAIN_ID:
 	case MDSP_DOMAIN_ID:
 	case SDSP_DOMAIN_ID:
-		/* Unsigned PD offloading is only supported on CDSP*/
+		/* Unsigned PD offloading is only supported on CDSP and CDSP1 */
 		data->unsigned_support = false;
 		err = fastrpc_device_register(rdev, data, secure_dsp, domains[domain_id]);
 		if (err)
 			goto fdev_error;
 		break;
 	case CDSP_DOMAIN_ID:
+	case CDSP1_DOMAIN_ID:
+	case GDSP0_DOMAIN_ID:
+	case GDSP1_DOMAIN_ID:
 		data->unsigned_support = true;
 		/* Create both device nodes so that we can allow both Signed and Unsigned PD */
 		err = fastrpc_device_register(rdev, data, true, domains[domain_id]);
@@ -2321,29 +3049,49 @@
 
 		err = fastrpc_device_register(rdev, data, false, domains[domain_id]);
 		if (err)
-			goto fdev_error;
+			goto populate_error;
 		break;
 	default:
 		err = -EINVAL;
 		goto fdev_error;
 	}
 
+	if (domain_id == ADSP_DOMAIN_ID) {
+		err = fastrpc_setup_service_locator(data, AUDIO_PDR_SERVICE_LOCATION_CLIENT_NAME,
+			AUDIO_PDR_ADSP_SERVICE_NAME, ADSP_AUDIOPD_NAME, domain_id, 0);
+		if (err)
+			return err;
+
+		err = fastrpc_setup_service_locator(data,
+			SENSORS_PDR_ADSP_SERVICE_LOCATION_CLIENT_NAME,
+			SENSORS_PDR_ADSP_SERVICE_NAME, ADSP_SENSORPD_NAME, domain_id, 1);
+		if (err)
+			return err;
+	} else if (domain_id == SDSP_DOMAIN_ID) {
+		err = fastrpc_setup_service_locator(data,
+			SENSORS_PDR_SLPI_SERVICE_LOCATION_CLIENT_NAME,
+			SENSORS_PDR_SLPI_SERVICE_NAME, SLPI_SENSORPD_NAME, domain_id, 0);
+		if (err)
+			return err;
+	}
+
 	kref_init(&data->refcount);
 
 	dev_set_drvdata(&rpdev->dev, data);
 	rdev->dma_mask = &data->dma_mask;
 	dma_set_mask_and_coherent(rdev, DMA_BIT_MASK(32));
 	INIT_LIST_HEAD(&data->users);
-	INIT_LIST_HEAD(&data->invoke_interrupted_mmaps);
+	INIT_LIST_HEAD(&data->rhmaps);
 	spin_lock_init(&data->lock);
 	idr_init(&data->ctx_idr);
 	data->domain_id = domain_id;
-	data->rpdev = rpdev;
 
 	err = of_platform_populate(rdev->of_node, NULL, NULL, rdev);
 	if (err)
 		goto populate_error;
 
+	data->rpdev = rpdev;
+
 	return 0;
 
 populate_error:
@@ -2357,46 +3105,35 @@
 	return err;
 }
 
-static void fastrpc_notify_users(struct fastrpc_user *user)
-{
-	struct fastrpc_invoke_ctx *ctx;
-
-	spin_lock(&user->lock);
-	list_for_each_entry(ctx, &user->pending, node) {
-		ctx->retval = -EPIPE;
-		complete(&ctx->work);
-	}
-	spin_unlock(&user->lock);
-}
-
 static void fastrpc_rpmsg_remove(struct rpmsg_device *rpdev)
 {
 	struct fastrpc_channel_ctx *cctx = dev_get_drvdata(&rpdev->dev);
-	struct fastrpc_buf *buf, *b;
 	struct fastrpc_user *user;
 	unsigned long flags;
 
 	/* No invocations past this point */
 	spin_lock_irqsave(&cctx->lock, flags);
 	cctx->rpdev = NULL;
+	cctx->staticpd_status = false;
 	list_for_each_entry(user, &cctx->users, user)
 		fastrpc_notify_users(user);
 	spin_unlock_irqrestore(&cctx->lock, flags);
 
+	if (cctx->domain_id == ADSP_DOMAIN_ID) {
+		pdr_handle_release(cctx->spd[0].pdrhandle);
+		pdr_handle_release(cctx->spd[1].pdrhandle);
+	} else if (cctx->domain_id == SDSP_DOMAIN_ID) {
+		pdr_handle_release(cctx->spd[0].pdrhandle);
+	}
+
 	if (cctx->fdevice)
 		misc_deregister(&cctx->fdevice->miscdev);
 
 	if (cctx->secure_fdevice)
 		misc_deregister(&cctx->secure_fdevice->miscdev);
 
-	list_for_each_entry_safe(buf, b, &cctx->invoke_interrupted_mmaps, node)
-		list_del(&buf->node);
-
-	if (cctx->remote_heap)
-		fastrpc_buf_free(cctx->remote_heap);
-
 	of_platform_depopulate(&rpdev->dev);
-
+	fastrpc_mmap_remove_ssr(cctx);
 	fastrpc_channel_ctx_put(cctx);
 }
 
@@ -2412,27 +3149,21 @@
 	if (len < sizeof(*rsp))
 		return -EINVAL;
 
-	ctxid = ((rsp->ctx & FASTRPC_CTXID_MASK) >> 4);
+	ctxid = ((rsp->ctx & FASTRPC_CTXID_MASK) >> 16);
 
 	spin_lock_irqsave(&cctx->lock, flags);
 	ctx = idr_find(&cctx->ctx_idr, ctxid);
 	spin_unlock_irqrestore(&cctx->lock, flags);
 
 	if (!ctx) {
-		dev_err(&rpdev->dev, "No context ID matches response\n");
-		return -ENOENT;
+		dev_dbg(&rpdev->dev, "No context ID matches response\n");
+		return 0;
 	}
 
 	ctx->retval = rsp->retval;
+	ctx->is_work_done = true;
 	complete(&ctx->work);
 
-	/*
-	 * The DMA buffer associated with the context cannot be freed in
-	 * interrupt context so schedule it through a worker thread to
-	 * avoid a kernel BUG.
-	 */
-	schedule_work(&ctx->put_work);
-
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/misc/lkdtm/Makefile
+++ linux-qcom-6.8.0/drivers/misc/lkdtm/Makefile
@@ -19,7 +19,7 @@
 KCSAN_SANITIZE_rodata.o			:= n
 KCOV_INSTRUMENT_rodata.o		:= n
 OBJECT_FILES_NON_STANDARD_rodata.o	:= y
-CFLAGS_REMOVE_rodata.o			+= $(CC_FLAGS_LTO) $(RETHUNK_CFLAGS)
+CFLAGS_REMOVE_rodata.o			+= $(CC_FLAGS_LTO) $(RETHUNK_CFLAGS) $(CC_FLAGS_CFI)
 
 OBJCOPYFLAGS :=
 OBJCOPYFLAGS_rodata_objcopy.o	:= \
--- linux-qcom-6.8.0.orig/drivers/misc/lkdtm/bugs.c
+++ linux-qcom-6.8.0/drivers/misc/lkdtm/bugs.c
@@ -415,8 +415,8 @@
 
 	pr_err("FAIL: survived access of invalid flexible array member index!\n");
 
-	if (!__has_attribute(__counted_by__))
-		pr_warn("This is expected since this %s was built a compiler supporting __counted_by\n",
+	if (!IS_ENABLED(CONFIG_CC_HAS_COUNTED_BY))
+		pr_warn("This is expected since this %s was built with a compiler that does not support __counted_by\n",
 			lkdtm_kernel_info);
 	else if (IS_ENABLED(CONFIG_UBSAN_BOUNDS))
 		pr_expected_config(CONFIG_UBSAN_TRAP);
--- linux-qcom-6.8.0.orig/drivers/misc/lkdtm/perms.c
+++ linux-qcom-6.8.0/drivers/misc/lkdtm/perms.c
@@ -61,7 +61,7 @@
 	return fdesc;
 }
 
-static noinline void execute_location(void *dst, bool write)
+static noinline __nocfi void execute_location(void *dst, bool write)
 {
 	void (*func)(void);
 	func_desc_t fdesc;
--- linux-qcom-6.8.0.orig/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c
+++ linux-qcom-6.8.0/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c
@@ -69,8 +69,10 @@
 
 	aux_bus->aux_device_wrapper[1] = kzalloc(sizeof(*aux_bus->aux_device_wrapper[1]),
 						 GFP_KERNEL);
-	if (!aux_bus->aux_device_wrapper[1])
-		return -ENOMEM;
+	if (!aux_bus->aux_device_wrapper[1]) {
+		retval =  -ENOMEM;
+		goto err_aux_dev_add_0;
+	}
 
 	retval = ida_alloc(&gp_client_ida, GFP_KERNEL);
 	if (retval < 0)
@@ -111,6 +113,7 @@
 
 err_aux_dev_add_1:
 	auxiliary_device_uninit(&aux_bus->aux_device_wrapper[1]->aux_dev);
+	goto err_aux_dev_add_0;
 
 err_aux_dev_init_1:
 	ida_free(&gp_client_ida, aux_bus->aux_device_wrapper[1]->aux_dev.id);
@@ -120,6 +123,7 @@
 
 err_aux_dev_add_0:
 	auxiliary_device_uninit(&aux_bus->aux_device_wrapper[0]->aux_dev);
+	goto err_ret;
 
 err_aux_dev_init_0:
 	ida_free(&gp_client_ida, aux_bus->aux_device_wrapper[0]->aux_dev.id);
@@ -127,6 +131,7 @@
 err_ida_alloc_0:
 	kfree(aux_bus->aux_device_wrapper[0]);
 
+err_ret:
 	return retval;
 }
 
--- linux-qcom-6.8.0.orig/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c
+++ linux-qcom-6.8.0/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c
@@ -148,7 +148,7 @@
 		pci1xxx_assign_bit(priv->reg_base, OPENDRAIN_OFFSET(offset), (offset % 32), true);
 		break;
 	default:
-		ret = -EOPNOTSUPP;
+		ret = -ENOTSUPP;
 		break;
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
@@ -277,7 +277,7 @@
 			writel(BIT(bit), priv->reg_base + INTR_STATUS_OFFSET(gpiobank));
 			spin_unlock_irqrestore(&priv->lock, flags);
 			irq = irq_find_mapping(gc->irq.domain, (bit + (gpiobank * 32)));
-			generic_handle_irq(irq);
+			handle_nested_irq(irq);
 		}
 	}
 	spin_lock_irqsave(&priv->lock, flags);
--- linux-qcom-6.8.0.orig/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_otpe2p.c
+++ linux-qcom-6.8.0/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_otpe2p.c
@@ -153,7 +153,6 @@
 
 		buf[byte] = readl(rb + MMAP_EEPROM_OFFSET(EEPROM_DATA_REG));
 	}
-	ret = byte;
 error:
 	release_sys_lock(priv);
 	return ret;
@@ -197,7 +196,6 @@
 			goto error;
 		}
 	}
-	ret = byte;
 error:
 	release_sys_lock(priv);
 	return ret;
@@ -258,7 +256,6 @@
 
 		buf[byte] = readl(rb + MMAP_OTP_OFFSET(OTP_RD_DATA_OFFSET));
 	}
-	ret = byte;
 error:
 	release_sys_lock(priv);
 	return ret;
@@ -315,7 +312,6 @@
 			goto error;
 		}
 	}
-	ret = byte;
 error:
 	release_sys_lock(priv);
 	return ret;
@@ -368,6 +364,7 @@
 	if (is_eeprom_responsive(priv)) {
 		priv->nvmem_config_eeprom.type = NVMEM_TYPE_EEPROM;
 		priv->nvmem_config_eeprom.name = EEPROM_NAME;
+		priv->nvmem_config_eeprom.id = NVMEM_DEVID_AUTO;
 		priv->nvmem_config_eeprom.dev = &aux_dev->dev;
 		priv->nvmem_config_eeprom.owner = THIS_MODULE;
 		priv->nvmem_config_eeprom.reg_read = pci1xxxx_eeprom_read;
@@ -387,6 +384,7 @@
 
 	priv->nvmem_config_otp.type = NVMEM_TYPE_OTP;
 	priv->nvmem_config_otp.name = OTP_NAME;
+	priv->nvmem_config_otp.id = NVMEM_DEVID_AUTO;
 	priv->nvmem_config_otp.dev = &aux_dev->dev;
 	priv->nvmem_config_otp.owner = THIS_MODULE;
 	priv->nvmem_config_otp.reg_read = pci1xxxx_otp_read;
--- linux-qcom-6.8.0.orig/drivers/misc/mei/client.c
+++ linux-qcom-6.8.0/drivers/misc/mei/client.c
@@ -321,7 +321,7 @@
 		return;
 
 	list_del(&cb->list);
-	kfree(cb->buf.data);
+	kvfree(cb->buf.data);
 	kfree(cb->ext_hdr);
 	kfree(cb);
 }
@@ -497,7 +497,7 @@
 	if (length == 0)
 		return cb;
 
-	cb->buf.data = kmalloc(roundup(length, MEI_SLOT_SIZE), GFP_KERNEL);
+	cb->buf.data = kvmalloc(roundup(length, MEI_SLOT_SIZE), GFP_KERNEL);
 	if (!cb->buf.data) {
 		mei_io_cb_free(cb);
 		return NULL;
--- linux-qcom-6.8.0.orig/drivers/misc/mei/hw-me-regs.h
+++ linux-qcom-6.8.0/drivers/misc/mei/hw-me-regs.h
@@ -115,6 +115,8 @@
 #define MEI_DEV_ID_ARL_S      0x7F68  /* Arrow Lake Point S */
 #define MEI_DEV_ID_ARL_H      0x7770  /* Arrow Lake Point H */
 
+#define MEI_DEV_ID_LNL_M      0xA870  /* Lunar Lake Point M */
+
 /*
  * MEI HW Section
  */
--- linux-qcom-6.8.0.orig/drivers/misc/mei/main.c
+++ linux-qcom-6.8.0/drivers/misc/mei/main.c
@@ -329,7 +329,7 @@
 	}
 
 	if (!mei_cl_is_connected(cl)) {
-		cl_err(dev, cl, "is not connected");
+		cl_dbg(dev, cl, "is not connected");
 		rets = -ENODEV;
 		goto out;
 	}
--- linux-qcom-6.8.0.orig/drivers/misc/mei/pci-me.c
+++ linux-qcom-6.8.0/drivers/misc/mei/pci-me.c
@@ -24,6 +24,9 @@
 #include "hw-me-regs.h"
 #include "hw-me.h"
 
+static bool disable_msi;
+module_param(disable_msi, bool, 0);
+
 /* mei_pci_tbl - PCI Device ID Table */
 static const struct pci_device_id mei_me_pci_tbl[] = {
 	{MEI_PCI_DEVICE(MEI_DEV_ID_82946GZ, MEI_ME_ICH_CFG)},
@@ -116,12 +119,14 @@
 	{MEI_PCI_DEVICE(MEI_DEV_ID_ADP_P, MEI_ME_PCH15_CFG)},
 	{MEI_PCI_DEVICE(MEI_DEV_ID_ADP_N, MEI_ME_PCH15_CFG)},
 
-	{MEI_PCI_DEVICE(MEI_DEV_ID_RPL_S, MEI_ME_PCH15_CFG)},
+	{MEI_PCI_DEVICE(MEI_DEV_ID_RPL_S, MEI_ME_PCH15_SPS_CFG)},
 
 	{MEI_PCI_DEVICE(MEI_DEV_ID_MTL_M, MEI_ME_PCH15_CFG)},
 	{MEI_PCI_DEVICE(MEI_DEV_ID_ARL_S, MEI_ME_PCH15_CFG)},
 	{MEI_PCI_DEVICE(MEI_DEV_ID_ARL_H, MEI_ME_PCH15_CFG)},
 
+	{MEI_PCI_DEVICE(MEI_DEV_ID_LNL_M, MEI_ME_PCH15_CFG)},
+
 	/* required last entry */
 	{0, }
 };
@@ -216,7 +221,8 @@
 	hw->mem_addr = pcim_iomap_table(pdev)[0];
 	hw->read_fws = mei_me_read_fws;
 
-	pci_enable_msi(pdev);
+	if (!disable_msi)
+		pci_enable_msi(pdev);
 
 	hw->irq = pdev->irq;
 
@@ -398,8 +404,10 @@
 	}
 
 	err = mei_restart(dev);
-	if (err)
+	if (err) {
+		free_irq(pdev->irq, dev);
 		return err;
+	}
 
 	/* Start timer if stopped in suspend */
 	schedule_delayed_work(&dev->timer_work, HZ);
--- linux-qcom-6.8.0.orig/drivers/misc/mei/platform-vsc.c
+++ linux-qcom-6.8.0/drivers/misc/mei/platform-vsc.c
@@ -28,8 +28,8 @@
 
 #define MEI_VSC_MAX_MSG_SIZE		512
 
-#define MEI_VSC_POLL_DELAY_US		(50 * USEC_PER_MSEC)
-#define MEI_VSC_POLL_TIMEOUT_US		(200 * USEC_PER_MSEC)
+#define MEI_VSC_POLL_DELAY_US		(100 * USEC_PER_MSEC)
+#define MEI_VSC_POLL_TIMEOUT_US		(400 * USEC_PER_MSEC)
 
 #define mei_dev_to_vsc_hw(dev)		((struct mei_vsc_hw *)((dev)->hw))
 
@@ -401,24 +401,30 @@
 
 static int mei_vsc_suspend(struct device *dev)
 {
-	struct mei_device *mei_dev = dev_get_drvdata(dev);
+	struct mei_device *mei_dev;
+	int ret = 0;
 
-	mei_stop(mei_dev);
+	mei_dev = dev_get_drvdata(dev);
+	if (!mei_dev)
+		return -ENODEV;
 
-	return 0;
+	mutex_lock(&mei_dev->device_lock);
+
+	if (!mei_write_is_idle(mei_dev))
+		ret = -EAGAIN;
+
+	mutex_unlock(&mei_dev->device_lock);
+
+	return ret;
 }
 
 static int mei_vsc_resume(struct device *dev)
 {
-	struct mei_device *mei_dev = dev_get_drvdata(dev);
-	int ret;
-
-	ret = mei_restart(mei_dev);
-	if (ret)
-		return ret;
+	struct mei_device *mei_dev;
 
-	/* start timer if stopped in suspend */
-	schedule_delayed_work(&mei_dev->timer_work, HZ);
+	mei_dev = dev_get_drvdata(dev);
+	if (!mei_dev)
+		return -ENODEV;
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/misc/mei/vsc-fw-loader.c
+++ linux-qcom-6.8.0/drivers/misc/mei/vsc-fw-loader.c
@@ -252,7 +252,7 @@
 {
 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER };
 	union acpi_object obj = {
-		.type = ACPI_TYPE_INTEGER,
+		.integer.type = ACPI_TYPE_INTEGER,
 		.integer.value = 1,
 	};
 	struct acpi_object_list arg_list = {
--- linux-qcom-6.8.0.orig/drivers/misc/mei/vsc-tp.c
+++ linux-qcom-6.8.0/drivers/misc/mei/vsc-tp.c
@@ -25,7 +25,8 @@
 #define VSC_TP_ROM_BOOTUP_DELAY_MS		10
 #define VSC_TP_ROM_XFER_POLL_TIMEOUT_US		(500 * USEC_PER_MSEC)
 #define VSC_TP_ROM_XFER_POLL_DELAY_US		(20 * USEC_PER_MSEC)
-#define VSC_TP_WAIT_FW_ASSERTED_TIMEOUT		(2 * HZ)
+#define VSC_TP_WAIT_FW_POLL_TIMEOUT		(2 * HZ)
+#define VSC_TP_WAIT_FW_POLL_DELAY_US		(20 * USEC_PER_MSEC)
 #define VSC_TP_MAX_XFER_COUNT			5
 
 #define VSC_TP_PACKET_SYNC			0x31
@@ -93,6 +94,27 @@
 	{}
 };
 
+static irqreturn_t vsc_tp_isr(int irq, void *data)
+{
+	struct vsc_tp *tp = data;
+
+	atomic_inc(&tp->assert_cnt);
+
+	wake_up(&tp->xfer_wait);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t vsc_tp_thread_isr(int irq, void *data)
+{
+	struct vsc_tp *tp = data;
+
+	if (tp->event_notify)
+		tp->event_notify(tp->event_notify_context);
+
+	return IRQ_HANDLED;
+}
+
 /* wakeup firmware and wait for response */
 static int vsc_tp_wakeup_request(struct vsc_tp *tp)
 {
@@ -101,13 +123,15 @@
 	gpiod_set_value_cansleep(tp->wakeupfw, 0);
 
 	ret = wait_event_timeout(tp->xfer_wait,
-				 atomic_read(&tp->assert_cnt) &&
-				 gpiod_get_value_cansleep(tp->wakeuphost),
-				 VSC_TP_WAIT_FW_ASSERTED_TIMEOUT);
+				 atomic_read(&tp->assert_cnt),
+				 VSC_TP_WAIT_FW_POLL_TIMEOUT);
 	if (!ret)
 		return -ETIMEDOUT;
 
-	return 0;
+	return read_poll_timeout(gpiod_get_value_cansleep, ret, ret,
+				 VSC_TP_WAIT_FW_POLL_DELAY_US,
+				 VSC_TP_WAIT_FW_POLL_TIMEOUT, false,
+				 tp->wakeuphost);
 }
 
 static void vsc_tp_wakeup_release(struct vsc_tp *tp)
@@ -307,12 +331,12 @@
 		return ret;
 	}
 
-	ret = vsc_tp_dev_xfer(tp, tp->tx_buf, tp->rx_buf, len);
+	ret = vsc_tp_dev_xfer(tp, tp->tx_buf, ibuf ? tp->rx_buf : ibuf, len);
 	if (ret)
 		return ret;
 
 	if (ibuf)
-		cpu_to_be32_array(ibuf, tp->rx_buf, words);
+		be32_to_cpu_array(ibuf, tp->rx_buf, words);
 
 	return ret;
 }
@@ -381,6 +405,37 @@
 EXPORT_SYMBOL_NS_GPL(vsc_tp_register_event_cb, VSC_TP);
 
 /**
+ * vsc_tp_request_irq - request irq for vsc_tp device
+ * @tp: vsc_tp device handle
+ */
+int vsc_tp_request_irq(struct vsc_tp *tp)
+{
+	struct spi_device *spi = tp->spi;
+	struct device *dev = &spi->dev;
+	int ret;
+
+	irq_set_status_flags(spi->irq, IRQ_DISABLE_UNLAZY);
+	ret = request_threaded_irq(spi->irq, vsc_tp_isr, vsc_tp_thread_isr,
+				   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+				   dev_name(dev), tp);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+EXPORT_SYMBOL_NS_GPL(vsc_tp_request_irq, VSC_TP);
+
+/**
+ * vsc_tp_free_irq - free irq for vsc_tp device
+ * @tp: vsc_tp device handle
+ */
+void vsc_tp_free_irq(struct vsc_tp *tp)
+{
+	free_irq(tp->spi->irq, tp);
+}
+EXPORT_SYMBOL_NS_GPL(vsc_tp_free_irq, VSC_TP);
+
+/**
  * vsc_tp_intr_synchronize - synchronize vsc_tp interrupt
  * @tp: vsc_tp device handle
  */
@@ -410,27 +465,6 @@
 }
 EXPORT_SYMBOL_NS_GPL(vsc_tp_intr_disable, VSC_TP);
 
-static irqreturn_t vsc_tp_isr(int irq, void *data)
-{
-	struct vsc_tp *tp = data;
-
-	atomic_inc(&tp->assert_cnt);
-
-	wake_up(&tp->xfer_wait);
-
-	return IRQ_WAKE_THREAD;
-}
-
-static irqreturn_t vsc_tp_thread_isr(int irq, void *data)
-{
-	struct vsc_tp *tp = data;
-
-	if (tp->event_notify)
-		tp->event_notify(tp->event_notify_context);
-
-	return IRQ_HANDLED;
-}
-
 static int vsc_tp_match_any(struct acpi_device *adev, void *data)
 {
 	struct acpi_device **__adev = data;
@@ -482,10 +516,9 @@
 	tp->spi = spi;
 
 	irq_set_status_flags(spi->irq, IRQ_DISABLE_UNLAZY);
-	ret = devm_request_threaded_irq(dev, spi->irq, vsc_tp_isr,
-					vsc_tp_thread_isr,
-					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
-					dev_name(dev), tp);
+	ret = request_threaded_irq(spi->irq, vsc_tp_isr, vsc_tp_thread_isr,
+				   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+				   dev_name(dev), tp);
 	if (ret)
 		return ret;
 
@@ -519,6 +552,8 @@
 err_destroy_lock:
 	mutex_destroy(&tp->mutex);
 
+	free_irq(spi->irq, tp);
+
 	return ret;
 }
 
@@ -529,6 +564,21 @@
 	platform_device_unregister(tp->pdev);
 
 	mutex_destroy(&tp->mutex);
+
+	free_irq(spi->irq, tp);
+}
+
+static void vsc_tp_shutdown(struct spi_device *spi)
+{
+	struct vsc_tp *tp = spi_get_drvdata(spi);
+
+	platform_device_unregister(tp->pdev);
+
+	mutex_destroy(&tp->mutex);
+
+	vsc_tp_reset(tp);
+
+	free_irq(spi->irq, tp);
 }
 
 static const struct acpi_device_id vsc_tp_acpi_ids[] = {
@@ -543,6 +593,7 @@
 static struct spi_driver vsc_tp_driver = {
 	.probe = vsc_tp_probe,
 	.remove = vsc_tp_remove,
+	.shutdown = vsc_tp_shutdown,
 	.driver = {
 		.name = "vsc-tp",
 		.acpi_match_table = vsc_tp_acpi_ids,
--- linux-qcom-6.8.0.orig/drivers/misc/mei/vsc-tp.h
+++ linux-qcom-6.8.0/drivers/misc/mei/vsc-tp.h
@@ -37,6 +37,9 @@
 int vsc_tp_register_event_cb(struct vsc_tp *tp, vsc_tp_event_cb_t event_cb,
 			     void *context);
 
+int vsc_tp_request_irq(struct vsc_tp *tp);
+void vsc_tp_free_irq(struct vsc_tp *tp);
+
 void vsc_tp_intr_enable(struct vsc_tp *tp);
 void vsc_tp_intr_disable(struct vsc_tp *tp);
 void vsc_tp_intr_synchronize(struct vsc_tp *tp);
--- linux-qcom-6.8.0.orig/drivers/misc/pvpanic/pvpanic-pci.c
+++ linux-qcom-6.8.0/drivers/misc/pvpanic/pvpanic-pci.c
@@ -44,8 +44,6 @@
 	.name =         "pvpanic-pci",
 	.id_table =     pvpanic_pci_id_tbl,
 	.probe =        pvpanic_pci_probe,
-	.driver = {
-		.dev_groups = pvpanic_dev_groups,
-	},
+	.dev_groups =   pvpanic_dev_groups,
 };
 module_pci_driver(pvpanic_pci_driver);
--- linux-qcom-6.8.0.orig/drivers/misc/qcom-dcc.c
+++ linux-qcom-6.8.0/drivers/misc/qcom-dcc.c
@@ -0,0 +1,1716 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022-2025, Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+/*
+ * DCC(Data Capture and Compare) is a DMA engine designed for debugging
+ * purposes.
+ * In case of a system crash or manual software triggers by the user the
+ * DCC hardware stores the value at the register addresses which can be
+ * used for debugging purposes.
+ * The DCC driver provides the user with debugfs interface to configure the
+ * register addresses. The options that the DCC hardware provides include
+ * reading from registers, writing to registers, first reading and then
+ * writing to registers and looping through the values of the same
+ * register.
+ *
+ * In certain cases a register write needs to be executed for accessing the
+ * rest of the registers, also the user might want to record the changing
+ * values of a register with time for which he has the option to use the
+ * loop feature.
+ *
+ * The options mentioned above are exposed to the user by debugfs files
+ * once the driver is probed. The details and usage of this debugfs files
+ * are documented in Documentation/ABI/testing/debugfs-driver-dcc.
+ *
+ * As an example let us consider a couple of debug scenarios where DCC has
+ * been proved to be effective for debugging purposes:-
+ *
+ * i)TimeStamp Related Issue
+ *
+ * On SC7180, there was a coresight timestamp issue where it would
+ * occasionally be all 0 instead of proper timestamp values.
+ *
+ * Proper timestamp:
+ * Idx:3373; ID:10; I_TIMESTAMP : Timestamp.; Updated val =
+ * 0x13004d8f5b7aa; CC=0x9e
+ *
+ * Zero timestamp:
+ * Idx:3387; ID:10; I_TIMESTAMP : Timestamp.; Updated val = 0x0; CC=0xa2
+ *
+ * Now this is a non-fatal issue and doesn't need a system reset, but still
+ * needs to be rootcaused and fixed for those who do care about coresight
+ * etm traces.
+ * Since this is a timestamp issue, we would be looking for any timestamp
+ * related clocks and such.
+ *
+ * We get all the clk register details from IP documentation and configure
+ * it via DCC config debugfs node. Before that we set the current
+ * linked list.
+ *
+ * Program the linked list with the addresses
+ * echo R 0x10c004 > /sys/kernel/debug/qcom-dcc/../3/config
+ * echo R 0x10c008 > /sys/kernel/debug/qcom-dcc/../3/config
+ * echo R 0x10c00c > /sys/kernel/debug/qcom-dcc/../3/config
+ * echo R 0x10c010 > /sys/kernel/debug/qcom-dcc/../3/config
+ * ..... and so on for other timestamp related clk registers
+ *
+ * Other way of specifying is in "addr len" pair, in below case it
+ * specifies to capture 4 words starting 0x10C004
+ *
+ * echo R 0x10C004 4 > /sys/kernel/debug/qcom-dcc/../3/config
+ *
+ * Configuration can be saved to a file and reuse it later.
+ * cat /sys/kernel/debug/qcom-dcc/../3/config > config_3
+ * Post reboot, write the file to config.
+ * echo config_3 > /sys/kernel/debug/qcom-dcc/../3/config
+ *
+ * Enable DCC
+ * echo 1 > /sys/kernel/debug/qcom-dcc/../3/enable
+ *
+ * Run the timestamp test for working case
+ *
+ * Send SW trigger
+ * echo 1 > /sys/kernel/debug/qcom-dcc/../trigger
+ *
+ * Read SRAM
+ * cat /dev/dcc_sram > dcc_sram1.bin
+ *
+ * Run the timestamp test for non-working case
+ *
+ * Send SW trigger
+ * echo 1 > /sys/kernel/debug/qcom-dcc/../trigger
+ *
+ * Read SRAM
+ * cat /dev/dcc_sram > dcc_sram2.bin
+ *
+ * Get the parser from
+ * https://git.codelinaro.org/clo/le/platform/vendor/qcom-opensource/tools/-/tree/opensource-tools.lnx.1.0.r176-rel/dcc_parser
+ *
+ * Parse the SRAM bin
+ * python dcc_parser.py -s dcc_sram1.bin --v2 -o output/ python
+ * dcc_parser.py -s dcc_sram2.bin --v2 -o output/
+ *
+ * Sample parsed output of dcc_sram1.bin:
+ *
+ * <hwioDump version="1">
+ *        <timestamp>03/14/21</timestamp>
+ *            <generator>Linux DCC Parser</generator>
+ *                <chip name="None" version="None">
+ *                <register address="0x0010c004" value="0x80000000" />
+ *                <register address="0x0010c008" value="0x00000008" />
+ *                <register address="0x0010c00c" value="0x80004220" />
+ *                <register address="0x0010c010" value="0x80000000" />
+ *            </chip>
+ *    <next_ll_offset>next_ll_offset : 0x1c </next_ll_offset> </hwioDump>
+ *
+ * ii)NOC register errors
+ *
+ * A particular class of registers called NOC which are functional
+ * registers was reporting errors while logging the values.To trace these
+ * errors the DCC has been used effectively.
+ * The steps followed were similar to the ones mentioned above.
+ * In addition to NOC registers a few other dependent registers were
+ * configured in DCC to monitor it's values during a crash. A look at the
+ * dependent register values revealed that the crash was happening due to a
+ * secured access to one of these dependent registers.
+ * All these debugging activity and finding the root cause was achieved
+ * using DCC.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/debugfs.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/pm.h>
+#include <linux/suspend.h>
+
+#define STATUS_READY_TIMEOUT		5000  /* microseconds */
+
+/* DCC registers */
+#define DCC_HW_INFO			0x04
+#define DCC_LL_NUM_INFO			0x10
+#define DCC_LL_LOCK			0x00
+#define DCC_LL_CFG			0x04
+#define DCC_LL_BASE			0x08
+#define DCC_FD_BASE			0x0c
+#define DCC_LL_OFFSET                   0x80
+#define DCC_LL_TIMEOUT			0x10
+#define DCC_LL_INT_ENABLE		0x18
+#define DCC_LL_INT_STATUS		0x1c
+#define DCC_LL_SW_TRIGGER		0x2c
+#define DCC_LL_BUS_ACCESS_STATUS	0x30
+
+/* Default value used if a bit 6 in the HW_INFO register is set. */
+#define DCC_FIX_LOOP_OFFSET		16
+
+/* Mask to find version info from HW_Info register */
+#define DCC_VER_INFO_MASK		BIT(9)
+
+#define MAX_DCC_OFFSET			GENMASK(9, 2)
+#define MAX_DCC_LEN			GENMASK(6, 0)
+#define MAX_LOOP_CNT			GENMASK(7, 0)
+#define MAX_LOOP_ADDR			10
+
+#define DCC_ADDR_DESCRIPTOR		0x00
+#define DCC_ADDR_LIMIT			27
+#define DCC_WORD_SIZE			sizeof(u32)
+#define DCC_ADDR_RANGE_MASK		GENMASK(31, 4)
+#define DCC_LOOP_DESCRIPTOR		BIT(30)
+#define DCC_RD_MOD_WR_DESCRIPTOR	BIT(31)
+#define DCC_LINK_DESCRIPTOR		GENMASK(31, 30)
+#define DCC_STATUS_MASK			GENMASK(1, 0)
+#define DCC_LOCK_MASK			BIT(0)
+#define DCC_LOOP_OFFSET_MASK		BIT(6)
+#define DCC_TRIGGER_MASK		BIT(9)
+
+#define DCC_WRITE_MASK			BIT(15)
+#define DCC_WRITE_OFF_MASK		GENMASK(7, 0)
+#define DCC_WRITE_LEN_MASK		GENMASK(14, 8)
+
+#define DCC_READ_IND			0x00
+#define DCC_WRITE_IND			(BIT(28))
+
+#define DCC_AHB_IND			0x00
+#define DCC_APB_IND			BIT(29)
+
+#define DCC_MAX_LINK_LIST		8
+
+#define DCC_VER_MASK2			GENMASK(5, 0)
+
+#define DCC_SRAM_WORD_LENGTH		4
+
+#define DCC_RD_MOD_WR_ADDR              0xC105E
+
+#define MEM_MAP_VER1			0x1
+#define MEM_MAP_VER2			0x2
+#define MEM_MAP_VER3			0x3
+
+#define LINE_BUFFER_MAX_SZ		50
+#define REGISTERS_PER_LL		8
+
+enum dcc_descriptor_type {
+	DCC_READ_TYPE,
+	DCC_LOOP_TYPE,
+	DCC_READ_WRITE_TYPE,
+	DCC_WRITE_TYPE
+};
+
+/*
+ * struct reg_state
+ * offset: the offset of the reg to be preserved when dcc is without power
+ * val   : the val of the reg to be preserved when dcc is without power
+ */
+struct reg_state {
+	u32	offset;
+	u32	val;
+};
+
+/*
+ * Offset for the registers to be stored for deep sleep support
+ */
+static int reg_offset[REGISTERS_PER_LL] = {
+	DCC_LL_LOCK,
+	DCC_LL_CFG,
+	DCC_LL_BASE,
+	DCC_FD_BASE,
+	DCC_LL_TIMEOUT,
+	DCC_LL_INT_ENABLE,
+	DCC_LL_INT_STATUS,
+	DCC_LL_SW_TRIGGER
+};
+
+/**
+ * struct dcc_config_entry - configuration information related to each dcc instruction
+ * @base:                    Base address of the register to be configured in dcc
+ * @offset:                  Offset to the base address to be configured in dcc
+ * @len:                     Length of the address in words of 4 bytes to be configured in dcc
+ * @loop_cnt:                The number of times to loop on the register address in case
+				of loop instructions
+ * @write_val:               The value to be written on the register address in case of
+				write instructions
+ * @mask:                    Mask corresponding to the value to be written in case of
+				write instructions
+ * @apb_bus:                 Type of bus to be used for the instruction, can be either
+				'apb' if 1 or 'ahb' if 0
+ * @desc_type:               Stores the type of dcc instruction
+ * @list:                    This is used to append this instruction to the list of
+				instructions
+ */
+struct dcc_config_entry {
+	u32				base;
+	u32				offset;
+	u32				len;
+	u32				loop_cnt;
+	u32				write_val;
+	u32				mask;
+	bool				apb_bus;
+	enum dcc_descriptor_type	desc_type;
+	struct list_head		list;
+};
+
+/**
+ * struct dcc_drvdata - configuration information related to a dcc device
+ * @base:		Base Address of the dcc device
+ * @dev:		The device attached to the driver data
+ * @mutex:		Lock to protect access and manipulation of dcc_drvdata
+ * @ram_base:		Base address for the SRAM dedicated for the dcc device
+ * @ram_size:		Total size of the SRAM dedicated for the dcc device
+ * @ram_offset:		Offset to the SRAM dedicated for dcc device
+ * @ram_cfg:		Used for address limit calculation for dcc
+ * @ram_start:		Starting address of DCC SRAM
+ * @mem_map_ver:        Memory map version of DCC hardware
+ * @sram_dev:		Miscellaneous device equivalent of dcc SRAM
+ * @cfg_head:		Points to the head of the linked list of addresses
+ * @dbg_dir:		The dcc debugfs directory under which all the debugfs files are placed
+ * @max_link_list:	Total number of linkedlists supported by the DCC configuration
+ * @loop_shift:		Loop offset bits range for the addresses
+ * @enable_bitmap:	Bitmap to capture the enabled status of each linked list of addresses
+ * @ll_state:		Stores register offset and value
+ * @sram_state		Points to the start of sram content stored for deep sleep support
+ */
+struct dcc_drvdata {
+	void __iomem		*base;
+	void __iomem            *ram_base;
+	struct device		*dev;
+	/* Lock to protect access and manipulation of dcc_drvdata */
+	struct mutex		mutex;
+	size_t			ram_size;
+	u32			ram_offset;
+	unsigned int		ram_cfg;
+	unsigned int		ram_start;
+	u64			mem_map_ver;
+	struct miscdevice	sram_dev;
+	struct list_head	*cfg_head;
+	struct dentry		*dbg_dir;
+	size_t			max_link_list;
+	u8			loop_shift;
+	unsigned long		*enable_bitmap;
+	char			**temp_buff_ptr;
+	struct reg_state	*ll_state;
+	void			*sram_state;
+};
+
+struct dcc_cfg_attr {
+	u32	addr;
+	u32	prev_addr;
+	u32	prev_off;
+	u32	link;
+	u32	sram_offset;
+};
+
+struct dcc_cfg_loop_attr {
+	u32	loop_cnt;
+	u32	loop_len;
+	u32	loop_off;
+	bool    loop_start;
+};
+
+static inline u32 dcc_status(int version)
+{
+	return version == 1 ? 0x0c : 0x1c;
+}
+
+static inline u32 dcc_list_offset(int version)
+{
+	if (version == 1)
+		return 0x1c;
+	else if (version == 2)
+		return 0x2c;
+	else
+		return 0x34;
+}
+
+static inline void dcc_list_writel(struct dcc_drvdata *drvdata,
+				   u32 val, u32 ll, u32 off)
+{
+	u32 offset = dcc_list_offset(drvdata->mem_map_ver) + off;
+
+	writel(val, drvdata->base + ll * DCC_LL_OFFSET + offset);
+}
+
+static inline u32 dcc_list_readl(struct dcc_drvdata *drvdata, u32 ll, u32 off)
+{
+	u32 offset = dcc_list_offset(drvdata->mem_map_ver) + off;
+
+	return readl(drvdata->base + ll * DCC_LL_OFFSET + offset);
+}
+
+static void dcc_sram_write_auto(struct dcc_drvdata *drvdata,
+				u32 val, u32 *off)
+{
+	/* If the overflow condition is met increment the offset
+	 * and return to indicate that overflow has occurred
+	 */
+	if (*off > drvdata->ram_size - 4) {
+		*off += 4;
+		return;
+	}
+
+	writel(val, drvdata->ram_base + *off);
+
+	*off += 4;
+}
+
+static int dcc_sw_trigger(struct dcc_drvdata *drvdata)
+{
+	void __iomem *addr;
+	int i;
+	u32 status;
+	u32 ll_cfg;
+	u32 tmp_ll_cfg;
+	u32 val;
+	int ret = 0;
+
+	mutex_lock(&drvdata->mutex);
+
+	for (i = 0; i < drvdata->max_link_list; i++) {
+		if (!test_bit(i, drvdata->enable_bitmap))
+			continue;
+		ll_cfg = dcc_list_readl(drvdata, i, DCC_LL_CFG);
+		if (drvdata->mem_map_ver == MEM_MAP_VER3)
+			tmp_ll_cfg = ll_cfg & ~BIT(8);
+		else
+			tmp_ll_cfg = ll_cfg & ~DCC_TRIGGER_MASK;
+
+		dcc_list_writel(drvdata, tmp_ll_cfg, i, DCC_LL_CFG);
+		dcc_list_writel(drvdata, 1, i, DCC_LL_SW_TRIGGER);
+		dcc_list_writel(drvdata, ll_cfg, i, DCC_LL_CFG);
+	}
+
+	addr = drvdata->base + dcc_status(drvdata->mem_map_ver);
+	if (readl_poll_timeout(addr, val, !FIELD_GET(DCC_STATUS_MASK, val),
+			       1, STATUS_READY_TIMEOUT)) {
+		dev_err(drvdata->dev, "DCC is busy after receiving sw trigger\n");
+		ret = -EBUSY;
+		goto out_unlock;
+	}
+
+	for (i = 0; i < drvdata->max_link_list; i++) {
+		if (!test_bit(i, drvdata->enable_bitmap))
+			continue;
+
+		status = dcc_list_readl(drvdata, i, DCC_LL_BUS_ACCESS_STATUS);
+		if (!status)
+			continue;
+
+		dev_err(drvdata->dev, "Read access error for list %d err: 0x%x\n",
+			i, status);
+		ll_cfg = dcc_list_readl(drvdata, i, DCC_LL_CFG);
+		if (drvdata->mem_map_ver == MEM_MAP_VER3)
+			tmp_ll_cfg = ll_cfg & ~BIT(8);
+		else
+			tmp_ll_cfg = ll_cfg & ~DCC_TRIGGER_MASK;
+
+		dcc_list_writel(drvdata, tmp_ll_cfg, i, DCC_LL_CFG);
+		dcc_list_writel(drvdata, DCC_STATUS_MASK, i, DCC_LL_BUS_ACCESS_STATUS);
+		dcc_list_writel(drvdata, ll_cfg, i, DCC_LL_CFG);
+		ret = -ENODATA;
+		break;
+	}
+
+out_unlock:
+	mutex_unlock(&drvdata->mutex);
+	return ret;
+}
+
+static void dcc_ll_cfg_reset_link(struct dcc_cfg_attr *cfg)
+{
+	cfg->addr = 0x00;
+	cfg->link = 0;
+	cfg->prev_off = 0;
+	cfg->prev_addr = cfg->addr;
+}
+
+static void dcc_emit_read_write(struct dcc_drvdata *drvdata,
+				struct dcc_config_entry *entry,
+				struct dcc_cfg_attr *cfg)
+{
+	if (cfg->link) {
+		/*
+		 * write new offset = 1 to continue
+		 * processing the list
+		 */
+
+		dcc_sram_write_auto(drvdata, cfg->link, &cfg->sram_offset);
+
+		/* Reset link and prev_off */
+		dcc_ll_cfg_reset_link(cfg);
+	}
+
+	cfg->addr = DCC_RD_MOD_WR_DESCRIPTOR;
+	dcc_sram_write_auto(drvdata, cfg->addr, &cfg->sram_offset);
+
+	dcc_sram_write_auto(drvdata, entry->mask, &cfg->sram_offset);
+
+	dcc_sram_write_auto(drvdata, entry->write_val, &cfg->sram_offset);
+
+	cfg->addr = 0;
+}
+
+static void dcc_emit_loop(struct dcc_drvdata *drvdata, struct dcc_config_entry *entry,
+			  struct dcc_cfg_attr *cfg,
+			  struct dcc_cfg_loop_attr *cfg_loop,
+			  u32 *total_len)
+{
+	int loop;
+
+	/* Check if we need to write link of prev entry */
+	if (cfg->link)
+		dcc_sram_write_auto(drvdata, cfg->link, &cfg->sram_offset);
+
+	if (cfg_loop->loop_start) {
+		loop = (cfg->sram_offset - cfg_loop->loop_off) / 4;
+		loop |= (cfg_loop->loop_cnt << drvdata->loop_shift) &
+				   GENMASK(DCC_ADDR_LIMIT, drvdata->loop_shift);
+		loop |= DCC_LOOP_DESCRIPTOR;
+		*total_len += (*total_len - cfg_loop->loop_len) * cfg_loop->loop_cnt;
+
+		dcc_sram_write_auto(drvdata, loop, &cfg->sram_offset);
+
+		cfg_loop->loop_start = false;
+		cfg_loop->loop_len = 0;
+		cfg_loop->loop_off = 0;
+	} else {
+		cfg_loop->loop_start = true;
+		cfg_loop->loop_cnt = entry->loop_cnt - 1;
+		cfg_loop->loop_len = *total_len;
+		cfg_loop->loop_off = cfg->sram_offset;
+	}
+
+	/* Reset link and prev_off */
+	dcc_ll_cfg_reset_link(cfg);
+}
+
+static void dcc_emit_write(struct dcc_drvdata *drvdata,
+			   struct dcc_config_entry *entry,
+			   struct dcc_cfg_attr *cfg)
+{
+	u32 off;
+
+	if (cfg->link) {
+		/*
+		 * write new offset = 1 to continue
+		 * processing the list
+		 */
+		dcc_sram_write_auto(drvdata, cfg->link, &cfg->sram_offset);
+
+		/* Reset link and prev_off */
+		cfg->addr = 0x00;
+		cfg->prev_off = 0;
+		cfg->prev_addr = cfg->addr;
+	}
+
+	off = entry->offset / 4;
+	/* write new offset-length pair to correct position */
+	cfg->link |= ((off & DCC_WRITE_OFF_MASK) | DCC_WRITE_MASK |
+		      FIELD_PREP(DCC_WRITE_LEN_MASK, entry->len));
+	cfg->link |= DCC_LINK_DESCRIPTOR;
+
+	/* Address type */
+	cfg->addr = (entry->base >> 4) & GENMASK(DCC_ADDR_LIMIT, 0);
+	if (entry->apb_bus)
+		cfg->addr |= DCC_ADDR_DESCRIPTOR | DCC_WRITE_IND | DCC_APB_IND;
+	else
+		cfg->addr |= DCC_ADDR_DESCRIPTOR | DCC_WRITE_IND | DCC_AHB_IND;
+	dcc_sram_write_auto(drvdata, cfg->addr, &cfg->sram_offset);
+
+	dcc_sram_write_auto(drvdata, cfg->link, &cfg->sram_offset);
+
+	dcc_sram_write_auto(drvdata, entry->write_val, &cfg->sram_offset);
+
+	cfg->addr = 0x00;
+	cfg->link = 0;
+}
+
+static int dcc_emit_read(struct dcc_drvdata *drvdata,
+			 struct dcc_config_entry *entry,
+			 struct dcc_cfg_attr *cfg,
+			 u32 *pos, u32 *total_len)
+{
+	u32 off;
+	u32 temp_off;
+
+	cfg->addr = (entry->base >> 4) & GENMASK(27, 0);
+
+	if (entry->apb_bus)
+		cfg->addr |= DCC_ADDR_DESCRIPTOR | DCC_READ_IND | DCC_APB_IND;
+	else
+		cfg->addr |= DCC_ADDR_DESCRIPTOR | DCC_READ_IND | DCC_AHB_IND;
+
+	off = entry->offset / 4;
+
+	*total_len += entry->len * 4;
+
+	if (!cfg->prev_addr || cfg->prev_addr != cfg->addr || cfg->prev_off > off) {
+		/* Check if we need to write prev link entry */
+		if (cfg->link)
+			dcc_sram_write_auto(drvdata, cfg->link, &cfg->sram_offset);
+		dev_dbg(drvdata->dev, "DCC: sram address 0x%x\n", cfg->sram_offset);
+
+		/* Write address */
+		dcc_sram_write_auto(drvdata, cfg->addr, &cfg->sram_offset);
+
+		/* Reset link and prev_off */
+		cfg->link = 0;
+		cfg->prev_off = 0;
+	}
+
+	if ((off - cfg->prev_off) > 0xff || entry->len > MAX_DCC_LEN) {
+		dev_err(drvdata->dev, "DCC: Programming error Base: 0x%x, offset 0x%x\n",
+			entry->base, entry->offset);
+		return -EINVAL;
+	}
+
+	if (cfg->link) {
+		/*
+		 * link already has one offset-length so new
+		 * offset-length needs to be placed at
+		 * bits [29:15]
+		 */
+		*pos = 15;
+
+		/* Clear bits [31:16] */
+		cfg->link &= GENMASK(14, 0);
+	} else {
+		/*
+		 * link is empty, so new offset-length needs
+		 * to be placed at bits [15:0]
+		 */
+		*pos = 0;
+		cfg->link = 1 << 15;
+	}
+
+	/* write new offset-length pair to correct position */
+	temp_off = (off - cfg->prev_off) & GENMASK(7, 0);
+	cfg->link |= (temp_off | ((entry->len << 8) & GENMASK(14, 8))) << *pos;
+
+	cfg->link |= DCC_LINK_DESCRIPTOR;
+
+	if (*pos) {
+		dcc_sram_write_auto(drvdata, cfg->link, &cfg->sram_offset);
+		cfg->link = 0;
+	}
+
+	cfg->prev_off  = off + entry->len - 1;
+	cfg->prev_addr = cfg->addr;
+	return 0;
+}
+
+static int dcc_emit_config(struct dcc_drvdata *drvdata, unsigned int curr_list)
+{
+	int ret;
+	u32 total_len, pos;
+	struct dcc_config_entry *entry;
+	struct dcc_cfg_attr cfg = {0};
+	struct dcc_cfg_loop_attr cfg_loop = {0};
+
+	cfg.sram_offset = drvdata->ram_cfg * 4;
+	total_len = 0;
+
+	list_for_each_entry(entry, &drvdata->cfg_head[curr_list], list) {
+		switch (entry->desc_type) {
+		case DCC_READ_WRITE_TYPE:
+			dcc_emit_read_write(drvdata, entry, &cfg);
+			break;
+
+		case DCC_LOOP_TYPE:
+			dcc_emit_loop(drvdata, entry, &cfg, &cfg_loop, &total_len);
+			break;
+
+		case DCC_WRITE_TYPE:
+			dcc_emit_write(drvdata, entry, &cfg);
+			break;
+
+		case DCC_READ_TYPE:
+			ret = dcc_emit_read(drvdata, entry, &cfg, &pos, &total_len);
+			if (ret)
+				goto err;
+			break;
+		}
+	}
+
+	if (cfg.link)
+		dcc_sram_write_auto(drvdata, cfg.link, &cfg.sram_offset);
+
+	if (cfg_loop.loop_start) {
+		dev_err(drvdata->dev, "DCC: Programming error: Loop unterminated\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	/* Handling special case of list ending with a rd_mod_wr */
+	if (cfg.addr == DCC_RD_MOD_WR_DESCRIPTOR) {
+		cfg.addr = (DCC_RD_MOD_WR_ADDR) & GENMASK(27, 0);
+		cfg.addr |= DCC_ADDR_DESCRIPTOR;
+		dcc_sram_write_auto(drvdata, cfg.addr, &cfg.sram_offset);
+	}
+
+	/* Setting zero to indicate end of the list */
+	cfg.link = DCC_LINK_DESCRIPTOR;
+	dcc_sram_write_auto(drvdata, cfg.link, &cfg.sram_offset);
+
+	/* Check if sram offset exceeds the ram size */
+	if (cfg.sram_offset > drvdata->ram_size)
+		goto overstep;
+
+	/* Update ram_cfg and check if the data will overstep */
+	drvdata->ram_cfg = (cfg.sram_offset + total_len) / 4;
+
+	if (cfg.sram_offset + total_len > drvdata->ram_size) {
+		cfg.sram_offset += total_len;
+		goto overstep;
+	}
+
+	drvdata->ram_start = cfg.sram_offset / 4;
+	return 0;
+overstep:
+	ret = -EINVAL;
+	memset_io(drvdata->ram_base, 0, drvdata->ram_size);
+
+err:
+	return ret;
+}
+
+static bool dcc_valid_list(struct dcc_drvdata *drvdata, unsigned int curr_list)
+{
+	u32 lock_reg;
+
+	if (list_empty(&drvdata->cfg_head[curr_list]))
+		return false;
+
+	if (test_bit(curr_list, drvdata->enable_bitmap)) {
+		dev_err(drvdata->dev, "List %d is already enabled\n", curr_list);
+		return false;
+	}
+
+	lock_reg = dcc_list_readl(drvdata, curr_list, DCC_LL_LOCK);
+	if (lock_reg & DCC_LOCK_MASK) {
+		dev_err(drvdata->dev, "List %d is already locked\n", curr_list);
+		return false;
+	}
+
+	return true;
+}
+
+static bool is_dcc_enabled(struct dcc_drvdata *drvdata)
+{
+	int list;
+
+	for (list = 0; list < drvdata->max_link_list; list++)
+		if (test_bit(list, drvdata->enable_bitmap))
+			return true;
+
+	return false;
+}
+
+static int dcc_enable(struct dcc_drvdata *drvdata, unsigned int curr_list)
+{
+	int ret;
+	u32 ram_cfg_base;
+
+	mutex_lock(&drvdata->mutex);
+
+	if (!dcc_valid_list(drvdata, curr_list)) {
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	/* Fill dcc sram with the poison value.
+	 * This helps in understanding bus
+	 * hang from registers returning a zero
+	 */
+	if (!is_dcc_enabled(drvdata))
+		memset_io(drvdata->ram_base, 0xde, drvdata->ram_size);
+
+	/* 1. Take ownership of the list */
+	dcc_list_writel(drvdata, DCC_LOCK_MASK, curr_list, DCC_LL_LOCK);
+
+	/* 2. Program linked-list in the SRAM */
+	ram_cfg_base = drvdata->ram_cfg;
+	ret = dcc_emit_config(drvdata, curr_list);
+	if (ret) {
+		dcc_list_writel(drvdata, 0, curr_list, DCC_LL_LOCK);
+		goto out_unlock;
+	}
+
+	/* 3. Program DCC_RAM_CFG reg */
+	dcc_list_writel(drvdata, ram_cfg_base +
+			drvdata->ram_offset / 4, curr_list, DCC_LL_BASE);
+	dcc_list_writel(drvdata, drvdata->ram_start +
+			drvdata->ram_offset / 4, curr_list, DCC_FD_BASE);
+	dcc_list_writel(drvdata, 0xFFF, curr_list, DCC_LL_TIMEOUT);
+
+	/* 4. Clears interrupt status register */
+	dcc_list_writel(drvdata, 0, curr_list, DCC_LL_INT_ENABLE);
+	dcc_list_writel(drvdata, (BIT(0) | BIT(1) | BIT(2)),
+			curr_list, DCC_LL_INT_STATUS);
+
+	set_bit(curr_list, drvdata->enable_bitmap);
+
+	/* 5. Configure trigger */
+	if (drvdata->mem_map_ver == MEM_MAP_VER3)
+		dcc_list_writel(drvdata, BIT(8),
+				curr_list, DCC_LL_CFG);
+	else
+		dcc_list_writel(drvdata, DCC_TRIGGER_MASK,
+				curr_list, DCC_LL_CFG);
+
+out_unlock:
+	mutex_unlock(&drvdata->mutex);
+	return ret;
+}
+
+static void dcc_disable(struct dcc_drvdata *drvdata, int curr_list)
+{
+	mutex_lock(&drvdata->mutex);
+
+	if (!test_bit(curr_list, drvdata->enable_bitmap))
+		goto out_unlock;
+	dcc_list_writel(drvdata, 0, curr_list, DCC_LL_CFG);
+	dcc_list_writel(drvdata, 0, curr_list, DCC_LL_BASE);
+	dcc_list_writel(drvdata, 0, curr_list, DCC_FD_BASE);
+	dcc_list_writel(drvdata, 0, curr_list, DCC_LL_LOCK);
+	clear_bit(curr_list, drvdata->enable_bitmap);
+out_unlock:
+	mutex_unlock(&drvdata->mutex);
+}
+
+static u32 dcc_filp_curr_list(const struct file *filp)
+{
+	struct dentry *dentry = file_dentry(filp);
+	int curr_list, ret;
+
+	ret = kstrtoint(dentry->d_parent->d_name.name, 0, &curr_list);
+	if (ret)
+		return ret;
+
+	return curr_list;
+}
+
+static ssize_t enable_read(struct file *filp, char __user *userbuf,
+			   size_t count, loff_t *ppos)
+{
+	char *buf;
+	int curr_list = dcc_filp_curr_list(filp);
+	struct dcc_drvdata *drvdata = filp->private_data;
+
+	if (curr_list < 0)
+		return curr_list;
+
+	mutex_lock(&drvdata->mutex);
+	if (test_bit(curr_list, drvdata->enable_bitmap))
+		buf = "Y\n";
+	else
+		buf = "N\n";
+	mutex_unlock(&drvdata->mutex);
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf));
+}
+
+static ssize_t enable_write(struct file *filp, const char __user *userbuf,
+			    size_t count, loff_t *ppos)
+{
+	int ret = 0, curr_list;
+	bool val;
+	struct dcc_drvdata *drvdata = filp->private_data;
+
+	curr_list = dcc_filp_curr_list(filp);
+	if (curr_list < 0)
+		return curr_list;
+
+	ret = kstrtobool_from_user(userbuf, count, &val);
+	if (ret < 0)
+		return ret;
+
+	if (val) {
+		ret = dcc_enable(drvdata, curr_list);
+		if (ret)
+			return ret;
+	} else {
+		dcc_disable(drvdata, curr_list);
+	}
+
+	return count;
+}
+
+static const struct file_operations enable_fops = {
+	.read = enable_read,
+	.write = enable_write,
+	.open = simple_open,
+	.llseek = generic_file_llseek,
+};
+
+static ssize_t trigger_write(struct file *filp,
+			     const char __user *user_buf, size_t count,
+			     loff_t *ppos)
+{
+	int ret;
+	unsigned int val;
+	struct dcc_drvdata *drvdata = filp->private_data;
+
+	ret = kstrtouint_from_user(user_buf, count, 0, &val);
+	if (ret < 0)
+		return ret;
+
+	if (val != 1)
+		return -EINVAL;
+
+	ret = dcc_sw_trigger(drvdata);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static const struct file_operations trigger_fops = {
+	.write = trigger_write,
+	.open = simple_open,
+	.llseek = generic_file_llseek,
+};
+
+static int dcc_config_add(struct dcc_drvdata *drvdata, unsigned int addr,
+			  unsigned int len, bool apb_bus, int curr_list)
+{
+	int ret = 0;
+	struct dcc_config_entry *entry, *pentry;
+	unsigned int base, offset;
+
+	mutex_lock(&drvdata->mutex);
+
+	if (!len || len > drvdata->ram_size / DCC_WORD_SIZE) {
+		dev_err(drvdata->dev, "DCC: Invalid length\n");
+		ret = -EINVAL;
+		goto out_unlock;
+	}
+
+	base = addr & DCC_ADDR_RANGE_MASK;
+
+	if (!list_empty(&drvdata->cfg_head[curr_list])) {
+		pentry = list_last_entry(&drvdata->cfg_head[curr_list],
+					 struct dcc_config_entry, list);
+
+		if (pentry->desc_type == DCC_READ_TYPE &&
+		    addr >= (pentry->base + pentry->offset) &&
+		    addr <= (pentry->base + pentry->offset + MAX_DCC_OFFSET)) {
+			/* Re-use base address from last entry */
+			base = pentry->base;
+
+			if ((pentry->len * 4 + pentry->base + pentry->offset)
+					== addr) {
+				len += pentry->len;
+
+				if (len > MAX_DCC_LEN)
+					pentry->len = MAX_DCC_LEN;
+				else
+					pentry->len = len;
+
+				addr = pentry->base + pentry->offset +
+					pentry->len * 4;
+				len -= pentry->len;
+			}
+		}
+	}
+
+	offset = addr - base;
+
+	while (len) {
+		entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+		if (!entry) {
+			ret = -ENOMEM;
+			goto out_unlock;
+		}
+
+		entry->base = base;
+		entry->offset = offset;
+		entry->len = min_t(u32, len, MAX_DCC_LEN);
+		entry->desc_type = DCC_READ_TYPE;
+		entry->apb_bus = apb_bus;
+		INIT_LIST_HEAD(&entry->list);
+		list_add_tail(&entry->list,
+			      &drvdata->cfg_head[curr_list]);
+
+		len -= entry->len;
+		offset += MAX_DCC_LEN * 4;
+	}
+
+out_unlock:
+	mutex_unlock(&drvdata->mutex);
+	return ret;
+}
+
+static ssize_t dcc_config_add_read(struct dcc_drvdata *drvdata, char *buf, int curr_list)
+{
+	bool bus;
+	int len, nval;
+	unsigned int base;
+	char apb_bus[4];
+
+	nval = sscanf(buf, "%x %i %3s", &base, &len, apb_bus);
+	if (nval <= 0 || nval > 3)
+		return -EINVAL;
+
+	if (nval == 1) {
+		len = 1;
+		bus = false;
+	} else if (nval == 2) {
+		bus = false;
+	} else if (!strcmp("apb", apb_bus)) {
+		bus = true;
+	} else if (!strcmp("ahb", apb_bus)) {
+		bus = false;
+	} else {
+		return -EINVAL;
+	}
+
+	return dcc_config_add(drvdata, base, len, bus, curr_list);
+}
+
+static void dcc_config_reset(struct dcc_drvdata *drvdata)
+{
+	struct dcc_config_entry *entry, *temp;
+	int curr_list;
+
+	mutex_lock(&drvdata->mutex);
+
+	for (curr_list = 0; curr_list < drvdata->max_link_list; curr_list++) {
+		list_for_each_entry_safe(entry, temp,
+					 &drvdata->cfg_head[curr_list], list) {
+			list_del(&entry->list);
+		}
+	}
+	drvdata->ram_start = 0;
+	drvdata->ram_cfg = 0;
+	mutex_unlock(&drvdata->mutex);
+}
+
+static ssize_t config_reset_write(struct file *filp,
+				  const char __user *user_buf, size_t count,
+				  loff_t *ppos)
+{
+	unsigned int val;
+	int ret;
+	struct dcc_drvdata *drvdata = filp->private_data;
+
+	ret = kstrtouint_from_user(user_buf, count, 0, &val);
+	if (ret < 0)
+		return ret;
+
+	if (val)
+		dcc_config_reset(drvdata);
+
+	return count;
+}
+
+static const struct file_operations config_reset_fops = {
+	.write = config_reset_write,
+	.open = simple_open,
+	.llseek = generic_file_llseek,
+};
+
+static ssize_t ready_read(struct file *filp, char __user *userbuf,
+			  size_t count, loff_t *ppos)
+{
+	char *buf;
+	struct dcc_drvdata *drvdata = filp->private_data;
+
+	if (!is_dcc_enabled(drvdata))
+		return -EINVAL;
+
+	if (!FIELD_GET(BIT(1), readl(drvdata->base + dcc_status(drvdata->mem_map_ver))))
+		buf = "Y\n";
+	else
+		buf = "N\n";
+
+	return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf) + 1);
+}
+
+static const struct file_operations ready_fops = {
+	.read = ready_read,
+	.open = simple_open,
+	.llseek = generic_file_llseek,
+};
+
+static ssize_t loop_offset_read(struct file *filp, char __user *userbuf,
+			  size_t count, loff_t *ppos)
+{
+	char buf[4];
+	struct dcc_drvdata *drvdata = filp->private_data;
+
+	snprintf(buf, sizeof(buf), "%d", drvdata->loop_shift);
+	return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf) + 1);
+}
+
+static const struct file_operations loop_offset_fops = {
+	.read = loop_offset_read,
+	.open = simple_open,
+	.llseek = generic_file_llseek,
+};
+static int dcc_add_loop(struct dcc_drvdata *drvdata, unsigned long loop_cnt, int curr_list)
+{
+	struct dcc_config_entry *entry;
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	entry->loop_cnt = min_t(u32, loop_cnt, MAX_LOOP_CNT);
+	entry->desc_type = DCC_LOOP_TYPE;
+	INIT_LIST_HEAD(&entry->list);
+	list_add_tail(&entry->list, &drvdata->cfg_head[curr_list]);
+
+	return 0;
+}
+
+static ssize_t dcc_config_add_loop(struct dcc_drvdata *drvdata, char *buf, int curr_list)
+{
+	int ret, i = 0;
+	char *token, *input;
+	char delim[2] = " ";
+	unsigned int val[MAX_LOOP_ADDR];
+
+	input = buf;
+
+	while ((token = strsep(&input, delim)) && i < MAX_LOOP_ADDR) {
+		ret = kstrtouint(token, 0, &val[i++]);
+		if (ret)
+			return ret;
+	}
+
+	if (token) {
+		dev_err(drvdata->dev, "Max limit %u of loop address exceeded\n",
+			MAX_LOOP_ADDR);
+		return -EINVAL;
+	}
+
+	if (val[1] < 1 || val[1] > 8 || val[1] > (i - 2))
+		return -EINVAL;
+
+	ret = dcc_add_loop(drvdata, val[0], curr_list);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < val[1]; i++)
+		dcc_config_add(drvdata, val[i + 2], 1, false, curr_list);
+
+	return dcc_add_loop(drvdata, 1, curr_list);
+}
+
+static int dcc_rd_mod_wr_add(struct dcc_drvdata *drvdata, unsigned int mask,
+			     unsigned int val, int curr_list)
+{
+	int ret = 0;
+	struct dcc_config_entry *entry;
+
+	mutex_lock(&drvdata->mutex);
+
+	if (list_empty(&drvdata->cfg_head[curr_list])) {
+		dev_err(drvdata->dev, "DCC: No read address programmed\n");
+		ret = -EPERM;
+		goto out_unlock;
+	}
+
+	entry = devm_kzalloc(drvdata->dev, sizeof(*entry), GFP_KERNEL);
+	if (!entry) {
+		ret = -ENOMEM;
+		goto out_unlock;
+	}
+
+	entry->desc_type = DCC_READ_WRITE_TYPE;
+	entry->mask = mask;
+	entry->write_val = val;
+	list_add_tail(&entry->list, &drvdata->cfg_head[curr_list]);
+out_unlock:
+	mutex_unlock(&drvdata->mutex);
+	return ret;
+}
+
+static ssize_t dcc_config_add_read_write(struct dcc_drvdata *drvdata, char *buf, int curr_list)
+{
+	int ret;
+	int nval;
+	unsigned int addr, mask, val;
+
+	nval = sscanf(buf, "%x %x %x", &addr, &mask, &val);
+
+	if (nval <= 1 || nval > 3)
+		return -EINVAL;
+
+	ret = dcc_config_add(drvdata, addr, 1, false, curr_list);
+	if (ret)
+		return ret;
+
+	return dcc_rd_mod_wr_add(drvdata, mask, val, curr_list);
+}
+
+static int dcc_add_write(struct dcc_drvdata *drvdata, unsigned int addr,
+			 unsigned int write_val, int apb_bus, int curr_list)
+{
+	struct dcc_config_entry *entry;
+
+	entry = devm_kzalloc(drvdata->dev, sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+
+	entry->desc_type = DCC_WRITE_TYPE;
+	entry->base = addr & GENMASK(31, 4);
+	entry->offset = addr - entry->base;
+	entry->write_val = write_val;
+	entry->len = 1;
+	entry->apb_bus = apb_bus;
+	list_add_tail(&entry->list, &drvdata->cfg_head[curr_list]);
+
+	return 0;
+}
+
+static ssize_t dcc_config_add_write(struct dcc_drvdata *drvdata, char *buf, int curr_list)
+{
+	bool bus;
+	int nval;
+	unsigned int addr, write_val;
+	char apb_bus[4];
+
+	nval = sscanf(buf, "%x %x %3s", &addr, &write_val, apb_bus);
+
+	if (nval <= 1 || nval > 3)
+		return -EINVAL;
+
+	if (nval == 2)
+		bus = false;
+
+	if (nval == 3) {
+		if (!strcmp("apb", apb_bus))
+			bus = true;
+		else if (!strcmp("ahb", apb_bus))
+			bus = false;
+		else
+			return -EINVAL;
+	}
+
+	return dcc_add_write(drvdata, addr, write_val, bus, curr_list);
+}
+
+static int config_show(struct seq_file *m, void *data)
+{
+	struct dcc_drvdata *drvdata = m->private;
+	struct dcc_config_entry *entry, *next_entry, *prev_entry, *loop_entry;
+	int index = 0, curr_list, i;
+	unsigned int loop_val[MAX_LOOP_ADDR];
+
+	curr_list = dcc_filp_curr_list(m->file);
+	if (curr_list < 0)
+		return curr_list;
+
+	mutex_lock(&drvdata->mutex);
+
+	list_for_each_entry(entry, &drvdata->cfg_head[curr_list], list) {
+		index++;
+		switch (entry->desc_type) {
+		case DCC_READ_WRITE_TYPE:
+			prev_entry = list_prev_entry(entry, list);
+			seq_printf(m, "RW 0x%x 0x%x 0x%x\n",
+				   prev_entry->base + prev_entry->offset,
+				   entry->mask,
+				   entry->write_val);
+			break;
+		case DCC_LOOP_TYPE:
+			loop_entry = entry;
+			loop_val[0] = loop_entry->loop_cnt;
+			loop_entry = list_next_entry(loop_entry, list);
+			for (i = 0; i < (MAX_LOOP_ADDR-2);
+					i++, loop_entry = list_next_entry(loop_entry, list)) {
+				if (loop_entry->desc_type == DCC_READ_TYPE) {
+					loop_val[i+2] = loop_entry->base + loop_entry->offset;
+				} else if (loop_entry->desc_type == DCC_LOOP_TYPE) {
+					loop_val[i+2] = loop_entry->loop_cnt;
+					loop_val[1] = i;
+					entry = loop_entry;
+					break;
+				}
+			}
+			seq_printf(m, "L 0x%x 0x%x", loop_val[0], loop_val[1]);
+			for (i = 0; i < loop_val[1]; i++)
+				seq_printf(m, " 0x%x", loop_val[i+2]);
+			seq_puts(m, "\n");
+			break;
+		case DCC_WRITE_TYPE:
+			seq_printf(m, "W 0x%x 0x%x %s\n",
+				   entry->base + entry->offset,
+				   entry->write_val,
+				   entry->apb_bus ? "apb":"ahb");
+			break;
+		case DCC_READ_TYPE:
+			if (entry->len == 1) {
+				next_entry = list_next_entry(entry, list);
+				if (next_entry && next_entry->desc_type == DCC_READ_WRITE_TYPE)
+					continue;
+			}
+			seq_printf(m, "R 0x%x 0x%x %s\n",
+				   entry->base + entry->offset,
+				   entry->len,
+				   entry->apb_bus ? "apb":"ahb");
+		}
+	}
+	mutex_unlock(&drvdata->mutex);
+	return 0;
+}
+
+static int config_open(struct inode *inode, struct file *file)
+{
+	struct dcc_drvdata *drvdata = inode->i_private;
+
+	return single_open(file, config_show, drvdata);
+}
+
+static ssize_t config_write(struct file *filp,
+			    const char __user *user_buf, size_t count,
+			    loff_t *ppos)
+{
+	int ret, curr_list;
+	char *token, *line;
+	char *buf, *bufp, *temp_buff;
+	char *delim = " ";
+	struct dcc_drvdata *drvdata = filp->f_inode->i_private;
+	ssize_t processed_len = 0;
+
+	if (count == 0)
+		return -EINVAL;
+	buf = kzalloc(count+1, GFP_KERNEL);
+	if (buf)
+		bufp = buf;
+	else
+		return -ENOMEM;
+
+	ret = copy_from_user(buf, user_buf, count);
+	if (ret)
+		goto err;
+
+	curr_list = dcc_filp_curr_list(filp);
+	if (curr_list < 0) {
+		ret = curr_list;
+		goto err;
+	}
+
+	while (bufp[0] != '\0') {
+		/* Parse line by line */
+		line = strsep(&bufp, "\n");
+		/* When one complete line could be parsed */
+		if (line && bufp) {
+			processed_len += strlen(line) + 1;
+			if (drvdata->temp_buff_ptr && drvdata->temp_buff_ptr[curr_list]) {
+				temp_buff = drvdata->temp_buff_ptr[curr_list];
+				/* Size of combined string must not be greater than
+				 * allowed line size.
+				 */
+				if (strlen(line) + strlen(temp_buff) + 1 > LINE_BUFFER_MAX_SZ) {
+					dev_err(drvdata->dev, "Invalid input\n");
+					ret = -EINVAL;
+					goto err;
+				}
+				strlcat(temp_buff, line, PAGE_SIZE);
+				line = temp_buff;
+				kfree(temp_buff);
+				drvdata->temp_buff_ptr[curr_list] = NULL;
+			}
+
+			token = strsep(&line, delim);
+
+			if (!strcmp("R", token)) {
+				ret = dcc_config_add_read(drvdata, line, curr_list);
+			} else if (!strcmp("W", token)) {
+				ret = dcc_config_add_write(drvdata, line, curr_list);
+			} else if (!strcmp("RW", token)) {
+				ret = dcc_config_add_read_write(drvdata, line, curr_list);
+			} else if (!strcmp("L", token)) {
+				ret = dcc_config_add_loop(drvdata, line, curr_list);
+			} else {
+				dev_err(drvdata->dev, "%s is not a correct input\n", token);
+				ret = -EINVAL;
+			}
+
+			if (ret)
+				goto err;
+		} else {
+			/* Save the incomplete line to a temporary buffer and rejoin it later */
+			if (!drvdata->temp_buff_ptr) {
+				drvdata->temp_buff_ptr = devm_kcalloc(drvdata->dev,
+									drvdata->max_link_list,
+									sizeof(char *),
+									GFP_KERNEL);
+				if (!drvdata->temp_buff_ptr) {
+					ret = -ENOMEM;
+					goto err;
+				}
+			}
+			drvdata->temp_buff_ptr[curr_list] = kzalloc(LINE_BUFFER_MAX_SZ,
+										GFP_KERNEL);
+			temp_buff = drvdata->temp_buff_ptr[curr_list];
+			if (!temp_buff) {
+				ret = -ENOMEM;
+				goto err;
+			}
+			if ((count - processed_len) >= LINE_BUFFER_MAX_SZ) {
+				dev_err(drvdata->dev, "Invalid input\n");
+				ret = -EINVAL;
+				goto err;
+			}
+			memcpy(temp_buff, line, count - processed_len);
+			temp_buff[count - processed_len + 1] = '\0';
+			processed_len += (strlen(temp_buff) + 1);
+			break;
+		}
+	}
+
+	kfree(buf);
+	return processed_len;
+
+err:
+	kfree(buf);
+	if (drvdata->temp_buff_ptr && drvdata->temp_buff_ptr[curr_list]) {
+		kfree(drvdata->temp_buff_ptr[curr_list]);
+		drvdata->temp_buff_ptr[curr_list] = NULL;
+	}
+	return ret;
+}
+
+static const struct file_operations config_fops = {
+	.open = config_open,
+	.read = seq_read,
+	.write = config_write,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static void dcc_delete_debug_dir(struct dcc_drvdata *drvdata)
+{
+	 debugfs_remove_recursive(drvdata->dbg_dir);
+};
+
+static void dcc_create_debug_dir(struct dcc_drvdata *drvdata)
+{
+	int i;
+	char list_num[10];
+	struct dentry *dcc_dev, *list;
+	struct device *dev = drvdata->dev;
+
+	drvdata->dbg_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+	dcc_dev = debugfs_create_dir(dev_name(dev), drvdata->dbg_dir);
+
+	for (i = 0; i < drvdata->max_link_list; i++) {
+		snprintf(list_num, sizeof(list_num), "%d", i);
+		list = debugfs_create_dir(list_num, dcc_dev);
+		debugfs_create_file("enable", 0600, list, drvdata, &enable_fops);
+		debugfs_create_file("config", 0600, list, drvdata, &config_fops);
+	}
+
+	debugfs_create_file("trigger", 0200, drvdata->dbg_dir, drvdata, &trigger_fops);
+	debugfs_create_file("ready", 0400, drvdata->dbg_dir, drvdata, &ready_fops);
+	debugfs_create_file("config_reset", 0200, drvdata->dbg_dir, drvdata, &config_reset_fops);
+	debugfs_create_file("loop_offset", 0400, drvdata->dbg_dir, drvdata, &loop_offset_fops);
+}
+
+static ssize_t dcc_sram_read(struct file *file, char __user *data,
+			     size_t len, loff_t *ppos)
+{
+	unsigned char *buf;
+	struct dcc_drvdata *drvdata;
+
+	drvdata = container_of(file->private_data, struct dcc_drvdata,
+			       sram_dev);
+
+	/* EOF check */
+	if (*ppos >= drvdata->ram_size)
+		return 0;
+
+	if ((*ppos + len) > drvdata->ram_size)
+		len = (drvdata->ram_size - *ppos);
+
+	buf = kzalloc(len, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	memcpy_fromio(buf, drvdata->ram_base + *ppos, len);
+
+	if (copy_to_user(data, buf, len)) {
+		kfree(buf);
+		return -EFAULT;
+	}
+
+	*ppos += len;
+
+	kfree(buf);
+
+	return len;
+}
+
+static const struct file_operations dcc_sram_fops = {
+	.owner		= THIS_MODULE,
+	.read		= dcc_sram_read,
+	.llseek		= no_llseek,
+};
+
+static int dcc_sram_dev_init(struct dcc_drvdata *drvdata)
+{
+	drvdata->sram_dev.minor = MISC_DYNAMIC_MINOR;
+	drvdata->sram_dev.name = "dcc_sram";
+	drvdata->sram_dev.fops = &dcc_sram_fops;
+
+	return misc_register(&drvdata->sram_dev);
+}
+
+static void dcc_sram_dev_exit(struct dcc_drvdata *drvdata)
+{
+	misc_deregister(&drvdata->sram_dev);
+}
+
+static int dcc_probe(struct platform_device *pdev)
+{
+	u32 val;
+	int ret = 0, i;
+	struct device *dev = &pdev->dev;
+	struct dcc_drvdata *drvdata;
+	struct resource *res;
+
+	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+	if (!drvdata)
+		return -ENOMEM;
+
+	drvdata->dev = &pdev->dev;
+	platform_set_drvdata(pdev, drvdata);
+
+	drvdata->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(drvdata->base))
+		return PTR_ERR(drvdata->base);
+
+	drvdata->ram_base = devm_platform_get_and_ioremap_resource(pdev, 1, &res);
+	if (IS_ERR(drvdata->ram_base))
+		return PTR_ERR(drvdata->ram_base);
+
+	drvdata->ram_size = resource_size(res);
+	ret = of_property_read_u32(pdev->dev.of_node, "qcom,dcc-offset",
+				   &drvdata->ram_offset);
+	if (ret)
+		return -EINVAL;
+
+	drvdata->mem_map_ver = (u64)of_device_get_match_data(&pdev->dev);
+
+	switch (drvdata->mem_map_ver) {
+	case MEM_MAP_VER3:
+	case MEM_MAP_VER2:
+		drvdata->max_link_list = readl(drvdata->base + DCC_LL_NUM_INFO);
+		if (!drvdata->max_link_list)
+			return  -EINVAL;
+		break;
+	case MEM_MAP_VER1:
+		drvdata->max_link_list = DCC_MAX_LINK_LIST;
+		break;
+	default:
+		dev_err(drvdata->dev, "Unsupported memory map version.\n");
+		return -EINVAL;
+	}
+
+	val = readl(drvdata->base + DCC_HW_INFO);
+	/* Either set the fixed loop offset or calculate
+	 * it from the total number of words in dcc_sram.
+	 * Max consecutive addresses dcc can loop is
+	 * equivalent to the words in dcc_sram.
+	 */
+	if (val & DCC_LOOP_OFFSET_MASK)
+		drvdata->loop_shift = DCC_FIX_LOOP_OFFSET;
+	else
+		drvdata->loop_shift = get_bitmask_order((drvdata->ram_offset +
+					drvdata->ram_size) / DCC_SRAM_WORD_LENGTH - 1);
+
+	mutex_init(&drvdata->mutex);
+
+	drvdata->enable_bitmap = devm_kcalloc(dev, BITS_TO_LONGS(drvdata->max_link_list),
+					      sizeof(*drvdata->enable_bitmap), GFP_KERNEL);
+	if (!drvdata->enable_bitmap)
+		return -ENOMEM;
+
+	drvdata->cfg_head = devm_kcalloc(dev, drvdata->max_link_list,
+					 sizeof(*drvdata->cfg_head), GFP_KERNEL);
+	if (!drvdata->cfg_head)
+		return -ENOMEM;
+
+	for (i = 0; i < drvdata->max_link_list; i++)
+		INIT_LIST_HEAD(&drvdata->cfg_head[i]);
+
+	ret = dcc_sram_dev_init(drvdata);
+	if (ret) {
+		dev_err(drvdata->dev, "DCC: sram node not registered.\n");
+		return ret;
+	}
+
+	dcc_create_debug_dir(drvdata);
+
+	return 0;
+}
+
+static int dcc_remove(struct platform_device *pdev)
+{
+	struct dcc_drvdata *drvdata = platform_get_drvdata(pdev);
+
+	dcc_delete_debug_dir(drvdata);
+	dcc_sram_dev_exit(drvdata);
+	dcc_config_reset(drvdata);
+
+	return 0;
+}
+
+static int dcc_state_restore(struct device *dev)
+{
+	struct dcc_drvdata *drvdata = dev_get_drvdata(dev);
+	u32 i, j, num_of_reg, ram_cpy_wlen;
+	int *sram_state, ret = 0;
+
+	if (!drvdata) {
+		dev_err(dev, "Invalid drvdata\n");
+		return -EINVAL;
+	}
+
+	if (!is_dcc_enabled(drvdata)) {
+		dev_err(dev, "DCC is not enabled.\n");
+		return 0;
+	}
+
+	if (!drvdata->sram_state || !drvdata->ll_state) {
+		dev_err(dev, "Err: Restore state is NULL\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	num_of_reg = drvdata->max_link_list * REGISTERS_PER_LL;
+	ram_cpy_wlen = drvdata->ram_cfg;
+	sram_state = drvdata->sram_state;
+
+	for (i = 0; i < ram_cpy_wlen; i++) {
+		j = i * DCC_WORD_SIZE;
+		dcc_sram_write_auto(drvdata, sram_state[i], &j);
+	}
+
+	mutex_lock(&drvdata->mutex);
+
+	for (i = 0; i < num_of_reg; i++)
+		writel(drvdata->ll_state[i].val, drvdata->base + drvdata->ll_state[i].offset);
+
+	mutex_unlock(&drvdata->mutex);
+out:
+	kfree(drvdata->sram_state);
+	drvdata->sram_state = NULL;
+
+	kfree(drvdata->ll_state);
+	drvdata->ll_state = NULL;
+
+	return 0;
+}
+
+static int dcc_state_store(struct device *dev)
+{
+	u32 i, offset, num_of_regs, ram_cpy_len, reg_index;
+	struct dcc_drvdata *drvdata = dev_get_drvdata(dev);
+	u32 ll_index = 0;
+	int ret  = 0;
+
+	if (!drvdata) {
+		dev_err(dev, "Invalid drvdata\n");
+		return -EINVAL;
+	}
+
+	if (!is_dcc_enabled(drvdata)) {
+		dev_err(dev, "DCC is not enabled.\n");
+		return 0;
+	}
+
+	num_of_regs = drvdata->max_link_list * REGISTERS_PER_LL;
+
+	drvdata->ll_state = kcalloc(num_of_regs, sizeof(struct reg_state), GFP_KERNEL);
+	if (!drvdata->ll_state)
+		return -ENOMEM;
+
+	drvdata->sram_state = kzalloc(drvdata->ram_size, GFP_KERNEL);
+	if (!drvdata->sram_state) {
+		ret = -ENOMEM;
+		goto sram_alloc_err;
+	}
+
+	ram_cpy_len = drvdata->ram_cfg * 4;
+	memcpy_fromio(drvdata->sram_state, drvdata->ram_base, ram_cpy_len);
+
+	mutex_lock(&drvdata->mutex);
+
+	for (i = 0; i < num_of_regs; i++) {
+		reg_index = i % REGISTERS_PER_LL;
+		if (reg_index == 0)
+			ll_index++;
+
+		offset = dcc_list_offset(drvdata->mem_map_ver) + reg_offset[reg_index];
+		drvdata->ll_state[i].offset = (ll_index - 1) * DCC_LL_OFFSET + offset;
+		drvdata->ll_state[i].val = readl(drvdata->base +
+							drvdata->ll_state[i].offset);
+	}
+
+	mutex_unlock(&drvdata->mutex);
+
+	return 0;
+
+sram_alloc_err:
+	kfree(drvdata->ll_state);
+	drvdata->ll_state = NULL;
+	return ret;
+}
+
+static int dcc_suspend(struct device *dev)
+{
+	if (pm_suspend_target_state == PM_SUSPEND_MEM
+		|| pm_suspend_target_state == PM_SUSPEND_TO_IDLE)
+		return dcc_state_store(dev);
+
+	return 0;
+}
+
+static int dcc_resume(struct device *dev)
+{
+	if (pm_suspend_target_state == PM_SUSPEND_MEM
+		|| pm_suspend_target_state == PM_SUSPEND_TO_IDLE)
+		return dcc_state_restore(dev);
+
+	return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(dcc_pm_ops, dcc_suspend, dcc_resume);
+
+static const struct of_device_id dcc_match_table[] = {
+	{ .compatible = "qcom,dcc-v1", .data = (void *)MEM_MAP_VER1 },
+	{ .compatible = "qcom,dcc-v2", .data = (void *)MEM_MAP_VER2 },
+	{ .compatible = "qcom,dcc-v3", .data = (void *)MEM_MAP_VER3 },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, dcc_match_table);
+
+static struct platform_driver dcc_driver = {
+	.probe = dcc_probe,
+	.remove	= dcc_remove,
+	.driver	= {
+		.name = "qcom-dcc",
+		.of_match_table	= dcc_match_table,
+		.pm = &dcc_pm_ops,
+	},
+};
+
+module_platform_driver(dcc_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Qualcomm Technologies Inc. DCC driver");
--- linux-qcom-6.8.0.orig/drivers/misc/sgi-gru/grukservices.c
+++ linux-qcom-6.8.0/drivers/misc/sgi-gru/grukservices.c
@@ -258,7 +258,6 @@
 	int lcpu;
 
 	BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES);
-	preempt_disable();
 	bs = gru_lock_kernel_context(-1);
 	lcpu = uv_blade_processor_id();
 	*cb = bs->kernel_cb + lcpu * GRU_HANDLE_STRIDE;
@@ -272,7 +271,6 @@
 static void gru_free_cpu_resources(void *cb, void *dsr)
 {
 	gru_unlock_kernel_context(uv_numa_blade_id());
-	preempt_enable();
 }
 
 /*
--- linux-qcom-6.8.0.orig/drivers/misc/sgi-gru/grumain.c
+++ linux-qcom-6.8.0/drivers/misc/sgi-gru/grumain.c
@@ -937,10 +937,8 @@
 
 again:
 	mutex_lock(&gts->ts_ctxlock);
-	preempt_disable();
 
 	if (gru_check_context_placement(gts)) {
-		preempt_enable();
 		mutex_unlock(&gts->ts_ctxlock);
 		gru_unload_context(gts, 1);
 		return VM_FAULT_NOPAGE;
@@ -949,7 +947,6 @@
 	if (!gts->ts_gru) {
 		STAT(load_user_context);
 		if (!gru_assign_gru_context(gts)) {
-			preempt_enable();
 			mutex_unlock(&gts->ts_ctxlock);
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(GRU_ASSIGN_DELAY);  /* true hack ZZZ */
@@ -965,7 +962,6 @@
 				vma->vm_page_prot);
 	}
 
-	preempt_enable();
 	mutex_unlock(&gts->ts_ctxlock);
 
 	return VM_FAULT_NOPAGE;
--- linux-qcom-6.8.0.orig/drivers/misc/sgi-gru/grutlbpurge.c
+++ linux-qcom-6.8.0/drivers/misc/sgi-gru/grutlbpurge.c
@@ -65,7 +65,6 @@
 	struct gru_tlb_global_handle *tgh;
 	int n;
 
-	preempt_disable();
 	if (uv_numa_blade_id() == gru->gs_blade_id)
 		n = get_on_blade_tgh(gru);
 	else
@@ -79,7 +78,6 @@
 static void get_unlock_tgh_handle(struct gru_tlb_global_handle *tgh)
 {
 	unlock_tgh_handle(tgh);
-	preempt_enable();
 }
 
 /*
--- linux-qcom-6.8.0.orig/drivers/misc/vmw_vmci/vmci_datagram.c
+++ linux-qcom-6.8.0/drivers/misc/vmw_vmci/vmci_datagram.c
@@ -234,7 +234,8 @@
 
 			dg_info->in_dg_host_queue = true;
 			dg_info->entry = dst_entry;
-			memcpy(&dg_info->msg, dg, dg_size);
+			dg_info->msg = *dg;
+			memcpy(&dg_info->msg_payload, dg + 1, dg->payload_size);
 
 			INIT_WORK(&dg_info->work, dg_delayed_dispatch);
 			schedule_work(&dg_info->work);
@@ -377,7 +378,8 @@
 
 		dg_info->in_dg_host_queue = false;
 		dg_info->entry = dst_entry;
-		memcpy(&dg_info->msg, dg, VMCI_DG_SIZE(dg));
+		dg_info->msg = *dg;
+		memcpy(&dg_info->msg_payload, dg + 1, dg->payload_size);
 
 		INIT_WORK(&dg_info->work, dg_delayed_dispatch);
 		schedule_work(&dg_info->work);
--- linux-qcom-6.8.0.orig/drivers/misc/vmw_vmci/vmci_event.c
+++ linux-qcom-6.8.0/drivers/misc/vmw_vmci/vmci_event.c
@@ -9,6 +9,7 @@
 #include <linux/vmw_vmci_api.h>
 #include <linux/list.h>
 #include <linux/module.h>
+#include <linux/nospec.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/rculist.h>
@@ -86,9 +87,12 @@
 {
 	struct vmci_subscription *cur;
 	struct list_head *subscriber_list;
+	u32 sanitized_event, max_vmci_event;
 
 	rcu_read_lock();
-	subscriber_list = &subscriber_array[event_msg->event_data.event];
+	max_vmci_event = ARRAY_SIZE(subscriber_array);
+	sanitized_event = array_index_nospec(event_msg->event_data.event, max_vmci_event);
+	subscriber_list = &subscriber_array[sanitized_event];
 	list_for_each_entry_rcu(cur, subscriber_list, node) {
 		cur->callback(cur->id, &event_msg->event_data,
 			      cur->callback_data);
--- linux-qcom-6.8.0.orig/drivers/misc/vmw_vmci/vmci_guest.c
+++ linux-qcom-6.8.0/drivers/misc/vmw_vmci/vmci_guest.c
@@ -625,7 +625,8 @@
 	if (!vmci_dev) {
 		dev_err(&pdev->dev,
 			"Can't allocate memory for VMCI device\n");
-		return -ENOMEM;
+		error = -ENOMEM;
+		goto err_unmap_mmio_base;
 	}
 
 	vmci_dev->dev = &pdev->dev;
@@ -642,7 +643,8 @@
 		if (!vmci_dev->tx_buffer) {
 			dev_err(&pdev->dev,
 				"Can't allocate memory for datagram tx buffer\n");
-			return -ENOMEM;
+			error = -ENOMEM;
+			goto err_unmap_mmio_base;
 		}
 
 		vmci_dev->data_buffer = dma_alloc_coherent(&pdev->dev, VMCI_DMA_DG_BUFFER_SIZE,
@@ -893,6 +895,10 @@
 err_free_data_buffers:
 	vmci_free_dg_buffers(vmci_dev);
 
+err_unmap_mmio_base:
+	if (mmio_base != NULL)
+		pci_iounmap(pdev, mmio_base);
+
 	/* The rest are managed resources and will be freed by PCI core */
 	return error;
 }
--- linux-qcom-6.8.0.orig/drivers/misc/vmw_vmci/vmci_resource.c
+++ linux-qcom-6.8.0/drivers/misc/vmw_vmci/vmci_resource.c
@@ -144,7 +144,8 @@
 	spin_lock(&vmci_resource_table.lock);
 
 	hlist_for_each_entry(r, &vmci_resource_table.entries[idx], node) {
-		if (vmci_handle_is_equal(r->handle, resource->handle)) {
+		if (vmci_handle_is_equal(r->handle, resource->handle) &&
+		    resource->type == r->type) {
 			hlist_del_init_rcu(&r->node);
 			break;
 		}
--- linux-qcom-6.8.0.orig/drivers/mmc/core/block.c
+++ linux-qcom-6.8.0/drivers/mmc/core/block.c
@@ -48,6 +48,7 @@
 #include <linux/mmc/sd.h>
 
 #include <linux/uaccess.h>
+#include <asm/unaligned.h>
 
 #include "queue.h"
 #include "block.h"
@@ -413,7 +414,7 @@
 	struct mmc_blk_ioc_data *idata;
 	int err;
 
-	idata = kmalloc(sizeof(*idata), GFP_KERNEL);
+	idata = kzalloc(sizeof(*idata), GFP_KERNEL);
 	if (!idata) {
 		err = -ENOMEM;
 		goto out;
@@ -488,7 +489,7 @@
 	if (idata->flags & MMC_BLK_IOC_DROP)
 		return 0;
 
-	if (idata->flags & MMC_BLK_IOC_SBC)
+	if (idata->flags & MMC_BLK_IOC_SBC && i > 0)
 		prev_idata = idatas[i - 1];
 
 	/*
@@ -874,10 +875,11 @@
 static int mmc_blk_part_switch_pre(struct mmc_card *card,
 				   unsigned int part_type)
 {
-	const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB;
+	const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_MASK;
+	const unsigned int rpmb = EXT_CSD_PART_CONFIG_ACC_RPMB;
 	int ret = 0;
 
-	if ((part_type & mask) == mask) {
+	if ((part_type & mask) == rpmb) {
 		if (card->ext_csd.cmdq_en) {
 			ret = mmc_cmdq_disable(card);
 			if (ret)
@@ -892,10 +894,11 @@
 static int mmc_blk_part_switch_post(struct mmc_card *card,
 				    unsigned int part_type)
 {
-	const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_RPMB;
+	const unsigned int mask = EXT_CSD_PART_CONFIG_ACC_MASK;
+	const unsigned int rpmb = EXT_CSD_PART_CONFIG_ACC_RPMB;
 	int ret = 0;
 
-	if ((part_type & mask) == mask) {
+	if ((part_type & mask) == rpmb) {
 		mmc_retune_unpause(card->host);
 		if (card->reenable_cmdq && !card->ext_csd.cmdq_en)
 			ret = mmc_cmdq_enable(card);
@@ -945,11 +948,12 @@
 	int err;
 	u32 result;
 	__be32 *blocks;
+	u8 resp_sz = mmc_card_ult_capacity(card) ? 8 : 4;
+	unsigned int noio_flag;
 
 	struct mmc_request mrq = {};
 	struct mmc_command cmd = {};
 	struct mmc_data data = {};
-
 	struct scatterlist sg;
 
 	err = mmc_app_cmd(card->host, card);
@@ -960,7 +964,7 @@
 	cmd.arg = 0;
 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
 
-	data.blksz = 4;
+	data.blksz = resp_sz;
 	data.blocks = 1;
 	data.flags = MMC_DATA_READ;
 	data.sg = &sg;
@@ -970,15 +974,29 @@
 	mrq.cmd = &cmd;
 	mrq.data = &data;
 
-	blocks = kmalloc(4, GFP_KERNEL);
+	noio_flag = memalloc_noio_save();
+	blocks = kmalloc(resp_sz, GFP_KERNEL);
+	memalloc_noio_restore(noio_flag);
 	if (!blocks)
 		return -ENOMEM;
 
-	sg_init_one(&sg, blocks, 4);
+	sg_init_one(&sg, blocks, resp_sz);
 
 	mmc_wait_for_req(card->host, &mrq);
 
-	result = ntohl(*blocks);
+	if (mmc_card_ult_capacity(card)) {
+		/*
+		 * Normally, ACMD22 returns the number of written sectors as
+		 * u32. SDUC, however, returns it as u64.  This is not a
+		 * superfluous requirement, because SDUC writes may exceed 2TB.
+		 * For Linux mmc however, the previously write operation could
+		 * not be more than the block layer limits, thus just make room
+		 * for a u64 and cast the response back to u32.
+		 */
+		result = clamp_val(get_unaligned_be64(blocks), 0, UINT_MAX);
+	} else {
+		result = ntohl(*blocks);
+	}
 	kfree(blocks);
 
 	if (cmd.error || data.error)
--- linux-qcom-6.8.0.orig/drivers/mmc/core/bus.c
+++ linux-qcom-6.8.0/drivers/mmc/core/bus.c
@@ -149,6 +149,8 @@
 	if (dev->driver && drv->shutdown)
 		drv->shutdown(card);
 
+	__mmc_stop_host(host);
+
 	if (host->bus_ops->shutdown) {
 		ret = host->bus_ops->shutdown(host);
 		if (ret)
@@ -321,7 +323,9 @@
 	case MMC_TYPE_SD:
 		type = "SD";
 		if (mmc_card_blockaddr(card)) {
-			if (mmc_card_ext_capacity(card))
+			if (mmc_card_ult_capacity(card))
+				type = "SDUC";
+			else if (mmc_card_ext_capacity(card))
 				type = "SDXC";
 			else
 				type = "SDHC";
--- linux-qcom-6.8.0.orig/drivers/mmc/core/card.h
+++ linux-qcom-6.8.0/drivers/mmc/core/card.h
@@ -23,6 +23,7 @@
 #define MMC_CARD_SDXC		(1<<3)		/* card is SDXC */
 #define MMC_CARD_REMOVED	(1<<4)		/* card has been removed */
 #define MMC_STATE_SUSPENDED	(1<<5)		/* card is suspended */
+#define MMC_CARD_SDUC		(1<<6)		/* card is SDUC */
 
 #define mmc_card_present(c)	((c)->state & MMC_STATE_PRESENT)
 #define mmc_card_readonly(c)	((c)->state & MMC_STATE_READONLY)
@@ -30,11 +31,13 @@
 #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
 #define mmc_card_removed(c)	((c) && ((c)->state & MMC_CARD_REMOVED))
 #define mmc_card_suspended(c)	((c)->state & MMC_STATE_SUSPENDED)
+#define mmc_card_ult_capacity(c) ((c)->state & MMC_CARD_SDUC)
 
 #define mmc_card_set_present(c)	((c)->state |= MMC_STATE_PRESENT)
 #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
 #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR)
 #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
+#define mmc_card_set_ult_capacity(c) ((c)->state |= MMC_CARD_SDUC)
 #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
 #define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED)
 #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED)
@@ -82,6 +85,7 @@
 #define CID_MANFID_SANDISK_SD   0x3
 #define CID_MANFID_ATP          0x9
 #define CID_MANFID_TOSHIBA      0x11
+#define CID_MANFID_GIGASTONE    0x12
 #define CID_MANFID_MICRON       0x13
 #define CID_MANFID_SAMSUNG      0x15
 #define CID_MANFID_APACER       0x27
@@ -284,4 +288,10 @@
 {
 	return c->quirks & MMC_QUIRK_BROKEN_CACHE_FLUSH;
 }
+
+static inline int mmc_card_broken_sd_poweroff_notify(const struct mmc_card *c)
+{
+	return c->quirks & MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY;
+}
+
 #endif
--- linux-qcom-6.8.0.orig/drivers/mmc/core/core.c
+++ linux-qcom-6.8.0/drivers/mmc/core/core.c
@@ -2296,6 +2296,9 @@
 
 void __mmc_stop_host(struct mmc_host *host)
 {
+	if (host->rescan_disable)
+		return;
+
 	if (host->slot.cd_irq >= 0) {
 		mmc_gpio_set_cd_wake(host, false);
 		disable_irq(host->slot.cd_irq);
--- linux-qcom-6.8.0.orig/drivers/mmc/core/mmc.c
+++ linux-qcom-6.8.0/drivers/mmc/core/mmc.c
@@ -51,20 +51,6 @@
 	35,	40,	45,	50,	55,	60,	70,	80,
 };
 
-#define UNSTUFF_BITS(resp,start,size)					\
-	({								\
-		const int __size = size;				\
-		const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1;	\
-		const int __off = 3 - ((start) / 32);			\
-		const int __shft = (start) & 31;			\
-		u32 __res;						\
-									\
-		__res = resp[__off] >> __shft;				\
-		if (__size + __shft > 32)				\
-			__res |= resp[__off-1] << ((32 - __shft) % 32);	\
-		__res & __mask;						\
-	})
-
 /*
  * Given the decoded CSD structure, decode the raw CID to our CID structure.
  */
@@ -85,36 +71,36 @@
 	switch (card->csd.mmca_vsn) {
 	case 0: /* MMC v1.0 - v1.2 */
 	case 1: /* MMC v1.4 */
-		card->cid.manfid	= UNSTUFF_BITS(resp, 104, 24);
-		card->cid.prod_name[0]	= UNSTUFF_BITS(resp, 96, 8);
-		card->cid.prod_name[1]	= UNSTUFF_BITS(resp, 88, 8);
-		card->cid.prod_name[2]	= UNSTUFF_BITS(resp, 80, 8);
-		card->cid.prod_name[3]	= UNSTUFF_BITS(resp, 72, 8);
-		card->cid.prod_name[4]	= UNSTUFF_BITS(resp, 64, 8);
-		card->cid.prod_name[5]	= UNSTUFF_BITS(resp, 56, 8);
-		card->cid.prod_name[6]	= UNSTUFF_BITS(resp, 48, 8);
-		card->cid.hwrev		= UNSTUFF_BITS(resp, 44, 4);
-		card->cid.fwrev		= UNSTUFF_BITS(resp, 40, 4);
-		card->cid.serial	= UNSTUFF_BITS(resp, 16, 24);
-		card->cid.month		= UNSTUFF_BITS(resp, 12, 4);
-		card->cid.year		= UNSTUFF_BITS(resp, 8, 4) + 1997;
+		card->cid.manfid	= unstuff_bits(resp, 104, 24);
+		card->cid.prod_name[0]	= unstuff_bits(resp, 96, 8);
+		card->cid.prod_name[1]	= unstuff_bits(resp, 88, 8);
+		card->cid.prod_name[2]	= unstuff_bits(resp, 80, 8);
+		card->cid.prod_name[3]	= unstuff_bits(resp, 72, 8);
+		card->cid.prod_name[4]	= unstuff_bits(resp, 64, 8);
+		card->cid.prod_name[5]	= unstuff_bits(resp, 56, 8);
+		card->cid.prod_name[6]	= unstuff_bits(resp, 48, 8);
+		card->cid.hwrev		= unstuff_bits(resp, 44, 4);
+		card->cid.fwrev		= unstuff_bits(resp, 40, 4);
+		card->cid.serial	= unstuff_bits(resp, 16, 24);
+		card->cid.month		= unstuff_bits(resp, 12, 4);
+		card->cid.year		= unstuff_bits(resp, 8, 4) + 1997;
 		break;
 
 	case 2: /* MMC v2.0 - v2.2 */
 	case 3: /* MMC v3.1 - v3.3 */
 	case 4: /* MMC v4 */
-		card->cid.manfid	= UNSTUFF_BITS(resp, 120, 8);
-		card->cid.oemid		= UNSTUFF_BITS(resp, 104, 16);
-		card->cid.prod_name[0]	= UNSTUFF_BITS(resp, 96, 8);
-		card->cid.prod_name[1]	= UNSTUFF_BITS(resp, 88, 8);
-		card->cid.prod_name[2]	= UNSTUFF_BITS(resp, 80, 8);
-		card->cid.prod_name[3]	= UNSTUFF_BITS(resp, 72, 8);
-		card->cid.prod_name[4]	= UNSTUFF_BITS(resp, 64, 8);
-		card->cid.prod_name[5]	= UNSTUFF_BITS(resp, 56, 8);
-		card->cid.prv		= UNSTUFF_BITS(resp, 48, 8);
-		card->cid.serial	= UNSTUFF_BITS(resp, 16, 32);
-		card->cid.month		= UNSTUFF_BITS(resp, 12, 4);
-		card->cid.year		= UNSTUFF_BITS(resp, 8, 4) + 1997;
+		card->cid.manfid	= unstuff_bits(resp, 120, 8);
+		card->cid.oemid		= unstuff_bits(resp, 104, 16);
+		card->cid.prod_name[0]	= unstuff_bits(resp, 96, 8);
+		card->cid.prod_name[1]	= unstuff_bits(resp, 88, 8);
+		card->cid.prod_name[2]	= unstuff_bits(resp, 80, 8);
+		card->cid.prod_name[3]	= unstuff_bits(resp, 72, 8);
+		card->cid.prod_name[4]	= unstuff_bits(resp, 64, 8);
+		card->cid.prod_name[5]	= unstuff_bits(resp, 56, 8);
+		card->cid.prv		= unstuff_bits(resp, 48, 8);
+		card->cid.serial	= unstuff_bits(resp, 16, 32);
+		card->cid.month		= unstuff_bits(resp, 12, 4);
+		card->cid.year		= unstuff_bits(resp, 8, 4) + 1997;
 		break;
 
 	default:
@@ -161,43 +147,43 @@
 	 * v1.2 has extra information in bits 15, 11 and 10.
 	 * We also support eMMC v4.4 & v4.41.
 	 */
-	csd->structure = UNSTUFF_BITS(resp, 126, 2);
+	csd->structure = unstuff_bits(resp, 126, 2);
 	if (csd->structure == 0) {
 		pr_err("%s: unrecognised CSD structure version %d\n",
 			mmc_hostname(card->host), csd->structure);
 		return -EINVAL;
 	}
 
-	csd->mmca_vsn	 = UNSTUFF_BITS(resp, 122, 4);
-	m = UNSTUFF_BITS(resp, 115, 4);
-	e = UNSTUFF_BITS(resp, 112, 3);
+	csd->mmca_vsn	 = unstuff_bits(resp, 122, 4);
+	m = unstuff_bits(resp, 115, 4);
+	e = unstuff_bits(resp, 112, 3);
 	csd->taac_ns	 = (taac_exp[e] * taac_mant[m] + 9) / 10;
-	csd->taac_clks	 = UNSTUFF_BITS(resp, 104, 8) * 100;
+	csd->taac_clks	 = unstuff_bits(resp, 104, 8) * 100;
 
-	m = UNSTUFF_BITS(resp, 99, 4);
-	e = UNSTUFF_BITS(resp, 96, 3);
+	m = unstuff_bits(resp, 99, 4);
+	e = unstuff_bits(resp, 96, 3);
 	csd->max_dtr	  = tran_exp[e] * tran_mant[m];
-	csd->cmdclass	  = UNSTUFF_BITS(resp, 84, 12);
+	csd->cmdclass	  = unstuff_bits(resp, 84, 12);
 
-	e = UNSTUFF_BITS(resp, 47, 3);
-	m = UNSTUFF_BITS(resp, 62, 12);
+	e = unstuff_bits(resp, 47, 3);
+	m = unstuff_bits(resp, 62, 12);
 	csd->capacity	  = (1 + m) << (e + 2);
 
-	csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
-	csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
-	csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
-	csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
-	csd->dsr_imp = UNSTUFF_BITS(resp, 76, 1);
-	csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
-	csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
-	csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
+	csd->read_blkbits = unstuff_bits(resp, 80, 4);
+	csd->read_partial = unstuff_bits(resp, 79, 1);
+	csd->write_misalign = unstuff_bits(resp, 78, 1);
+	csd->read_misalign = unstuff_bits(resp, 77, 1);
+	csd->dsr_imp = unstuff_bits(resp, 76, 1);
+	csd->r2w_factor = unstuff_bits(resp, 26, 3);
+	csd->write_blkbits = unstuff_bits(resp, 22, 4);
+	csd->write_partial = unstuff_bits(resp, 21, 1);
 
 	if (csd->write_blkbits >= 9) {
-		a = UNSTUFF_BITS(resp, 42, 5);
-		b = UNSTUFF_BITS(resp, 37, 5);
+		a = unstuff_bits(resp, 42, 5);
+		b = unstuff_bits(resp, 37, 5);
 		csd->erase_size = (a + 1) * (b + 1);
 		csd->erase_size <<= csd->write_blkbits - 9;
-		csd->wp_grp_size = UNSTUFF_BITS(resp, 32, 5);
+		csd->wp_grp_size = unstuff_bits(resp, 32, 5);
 	}
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/mmc/core/mmc_ops.h
+++ linux-qcom-6.8.0/drivers/mmc/core/mmc_ops.h
@@ -56,5 +56,19 @@
 int mmc_cmdq_disable(struct mmc_card *card);
 int mmc_sanitize(struct mmc_card *card, unsigned int timeout_ms);
 
+static inline u32 unstuff_bits(const u32 *resp, int start, int size)
+{
+	const int __size = size;
+	const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1;
+	const int __off = 3 - (start / 32);
+	const int __shft = start & 31;
+	u32 __res = resp[__off] >> __shft;
+
+	if (__size + __shft > 32)
+		__res |= resp[__off - 1] << ((32 - __shft) % 32);
+
+	return __res & __mask;
+}
+
 #endif
 
--- linux-qcom-6.8.0.orig/drivers/mmc/core/mmc_test.c
+++ linux-qcom-6.8.0/drivers/mmc/core/mmc_test.c
@@ -3125,13 +3125,13 @@
 	test->buffer = kzalloc(BUFFER_SIZE, GFP_KERNEL);
 #ifdef CONFIG_HIGHMEM
 	test->highmem = alloc_pages(GFP_KERNEL | __GFP_HIGHMEM, BUFFER_ORDER);
+	if (!test->highmem) {
+		count = -ENOMEM;
+		goto free_test_buffer;
+	}
 #endif
 
-#ifdef CONFIG_HIGHMEM
-	if (test->buffer && test->highmem) {
-#else
 	if (test->buffer) {
-#endif
 		mutex_lock(&mmc_test_lock);
 		mmc_test_run(test, testcase);
 		mutex_unlock(&mmc_test_lock);
@@ -3139,6 +3139,7 @@
 
 #ifdef CONFIG_HIGHMEM
 	__free_pages(test->highmem, BUFFER_ORDER);
+free_test_buffer:
 #endif
 	kfree(test->buffer);
 	kfree(test);
--- linux-qcom-6.8.0.orig/drivers/mmc/core/quirks.h
+++ linux-qcom-6.8.0/drivers/mmc/core/quirks.h
@@ -15,6 +15,28 @@
 
 #include "card.h"
 
+static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = {
+	/*
+	 * Kingston Canvas Go! Plus microSD cards never finish SD cache flush.
+	 * This has so far only been observed on cards from 11/2019, while new
+	 * cards from 2023/05 do not exhibit this behavior.
+	 */
+	_FIXUP_EXT("SD64G", CID_MANFID_KINGSTON_SD, 0x5449, 2019, 11,
+		   0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
+		   MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),
+
+	/*
+	 * GIGASTONE Gaming Plus microSD cards manufactured on 02/2022 never
+	 * clear Flush Cache bit and set Poweroff Notification Ready bit.
+	 */
+	_FIXUP_EXT("ASTC", CID_MANFID_GIGASTONE, 0x3456, 2022, 2,
+		   0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
+		   MMC_QUIRK_BROKEN_SD_CACHE | MMC_QUIRK_BROKEN_SD_POWEROFF_NOTIFY,
+		   EXT_CSD_REV_ANY),
+
+	END_FIXUP
+};
+
 static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = {
 #define INAND_CMD38_ARG_EXT_CSD  113
 #define INAND_CMD38_ARG_ERASE    0x00
@@ -54,15 +76,6 @@
 		  MMC_QUIRK_BLK_NO_CMD23),
 
 	/*
-	 * Kingston Canvas Go! Plus microSD cards never finish SD cache flush.
-	 * This has so far only been observed on cards from 11/2019, while new
-	 * cards from 2023/05 do not exhibit this behavior.
-	 */
-	_FIXUP_EXT("SD64G", CID_MANFID_KINGSTON_SD, 0x5449, 2019, 11,
-		   0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
-		   MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),
-
-	/*
 	 * Some SD cards lockup while using CMD23 multiblock transfers.
 	 */
 	MMC_FIXUP("AF SD", CID_MANFID_ATP, CID_OEMID_ANY, add_quirk_sd,
--- linux-qcom-6.8.0.orig/drivers/mmc/core/sd.c
+++ linux-qcom-6.8.0/drivers/mmc/core/sd.c
@@ -26,6 +26,7 @@
 #include "host.h"
 #include "bus.h"
 #include "mmc_ops.h"
+#include "quirks.h"
 #include "sd.h"
 #include "sd_ops.h"
 
@@ -55,20 +56,6 @@
 	SZ_16M / 512,	(SZ_16M + SZ_8M) / 512,	SZ_32M / 512,	SZ_64M / 512,
 };
 
-#define UNSTUFF_BITS(resp,start,size)					\
-	({								\
-		const int __size = size;				\
-		const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1;	\
-		const int __off = 3 - ((start) / 32);			\
-		const int __shft = (start) & 31;			\
-		u32 __res;						\
-									\
-		__res = resp[__off] >> __shft;				\
-		if (__size + __shft > 32)				\
-			__res |= resp[__off-1] << ((32 - __shft) % 32);	\
-		__res & __mask;						\
-	})
-
 #define SD_POWEROFF_NOTIFY_TIMEOUT_MS 1000
 #define SD_WRITE_EXTR_SINGLE_TIMEOUT_MS 1000
 
@@ -94,18 +81,18 @@
 	 * SD doesn't currently have a version field so we will
 	 * have to assume we can parse this.
 	 */
-	card->cid.manfid		= UNSTUFF_BITS(resp, 120, 8);
-	card->cid.oemid			= UNSTUFF_BITS(resp, 104, 16);
-	card->cid.prod_name[0]		= UNSTUFF_BITS(resp, 96, 8);
-	card->cid.prod_name[1]		= UNSTUFF_BITS(resp, 88, 8);
-	card->cid.prod_name[2]		= UNSTUFF_BITS(resp, 80, 8);
-	card->cid.prod_name[3]		= UNSTUFF_BITS(resp, 72, 8);
-	card->cid.prod_name[4]		= UNSTUFF_BITS(resp, 64, 8);
-	card->cid.hwrev			= UNSTUFF_BITS(resp, 60, 4);
-	card->cid.fwrev			= UNSTUFF_BITS(resp, 56, 4);
-	card->cid.serial		= UNSTUFF_BITS(resp, 24, 32);
-	card->cid.year			= UNSTUFF_BITS(resp, 12, 8);
-	card->cid.month			= UNSTUFF_BITS(resp, 8, 4);
+	card->cid.manfid		= unstuff_bits(resp, 120, 8);
+	card->cid.oemid			= unstuff_bits(resp, 104, 16);
+	card->cid.prod_name[0]		= unstuff_bits(resp, 96, 8);
+	card->cid.prod_name[1]		= unstuff_bits(resp, 88, 8);
+	card->cid.prod_name[2]		= unstuff_bits(resp, 80, 8);
+	card->cid.prod_name[3]		= unstuff_bits(resp, 72, 8);
+	card->cid.prod_name[4]		= unstuff_bits(resp, 64, 8);
+	card->cid.hwrev			= unstuff_bits(resp, 60, 4);
+	card->cid.fwrev			= unstuff_bits(resp, 56, 4);
+	card->cid.serial		= unstuff_bits(resp, 24, 32);
+	card->cid.year			= unstuff_bits(resp, 12, 8);
+	card->cid.month			= unstuff_bits(resp, 8, 4);
 
 	card->cid.year += 2000; /* SD cards year offset */
 }
@@ -113,53 +100,54 @@
 /*
  * Given a 128-bit response, decode to our card CSD structure.
  */
-static int mmc_decode_csd(struct mmc_card *card)
+static int mmc_decode_csd(struct mmc_card *card, bool is_sduc)
 {
 	struct mmc_csd *csd = &card->csd;
 	unsigned int e, m, csd_struct;
 	u32 *resp = card->raw_csd;
 
-	csd_struct = UNSTUFF_BITS(resp, 126, 2);
+	csd_struct = unstuff_bits(resp, 126, 2);
 
 	switch (csd_struct) {
 	case 0:
-		m = UNSTUFF_BITS(resp, 115, 4);
-		e = UNSTUFF_BITS(resp, 112, 3);
+		m = unstuff_bits(resp, 115, 4);
+		e = unstuff_bits(resp, 112, 3);
 		csd->taac_ns	 = (taac_exp[e] * taac_mant[m] + 9) / 10;
-		csd->taac_clks	 = UNSTUFF_BITS(resp, 104, 8) * 100;
+		csd->taac_clks	 = unstuff_bits(resp, 104, 8) * 100;
 
-		m = UNSTUFF_BITS(resp, 99, 4);
-		e = UNSTUFF_BITS(resp, 96, 3);
+		m = unstuff_bits(resp, 99, 4);
+		e = unstuff_bits(resp, 96, 3);
 		csd->max_dtr	  = tran_exp[e] * tran_mant[m];
-		csd->cmdclass	  = UNSTUFF_BITS(resp, 84, 12);
+		csd->cmdclass	  = unstuff_bits(resp, 84, 12);
 
-		e = UNSTUFF_BITS(resp, 47, 3);
-		m = UNSTUFF_BITS(resp, 62, 12);
+		e = unstuff_bits(resp, 47, 3);
+		m = unstuff_bits(resp, 62, 12);
 		csd->capacity	  = (1 + m) << (e + 2);
 
-		csd->read_blkbits = UNSTUFF_BITS(resp, 80, 4);
-		csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
-		csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
-		csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
-		csd->dsr_imp = UNSTUFF_BITS(resp, 76, 1);
-		csd->r2w_factor = UNSTUFF_BITS(resp, 26, 3);
-		csd->write_blkbits = UNSTUFF_BITS(resp, 22, 4);
-		csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
+		csd->read_blkbits = unstuff_bits(resp, 80, 4);
+		csd->read_partial = unstuff_bits(resp, 79, 1);
+		csd->write_misalign = unstuff_bits(resp, 78, 1);
+		csd->read_misalign = unstuff_bits(resp, 77, 1);
+		csd->dsr_imp = unstuff_bits(resp, 76, 1);
+		csd->r2w_factor = unstuff_bits(resp, 26, 3);
+		csd->write_blkbits = unstuff_bits(resp, 22, 4);
+		csd->write_partial = unstuff_bits(resp, 21, 1);
 
-		if (UNSTUFF_BITS(resp, 46, 1)) {
+		if (unstuff_bits(resp, 46, 1)) {
 			csd->erase_size = 1;
 		} else if (csd->write_blkbits >= 9) {
-			csd->erase_size = UNSTUFF_BITS(resp, 39, 7) + 1;
+			csd->erase_size = unstuff_bits(resp, 39, 7) + 1;
 			csd->erase_size <<= csd->write_blkbits - 9;
 		}
 
-		if (UNSTUFF_BITS(resp, 13, 1))
+		if (unstuff_bits(resp, 13, 1))
 			mmc_card_set_readonly(card);
 		break;
 	case 1:
+	case 2:
 		/*
-		 * This is a block-addressed SDHC or SDXC card. Most
-		 * interesting fields are unused and have fixed
+		 * This is a block-addressed SDHC, SDXC or SDUC card.
+		 * Most interesting fields are unused and have fixed
 		 * values. To avoid getting tripped by buggy cards,
 		 * we assume those fixed values ourselves.
 		 */
@@ -168,18 +156,23 @@
 		csd->taac_ns	 = 0; /* Unused */
 		csd->taac_clks	 = 0; /* Unused */
 
-		m = UNSTUFF_BITS(resp, 99, 4);
-		e = UNSTUFF_BITS(resp, 96, 3);
+		m = unstuff_bits(resp, 99, 4);
+		e = unstuff_bits(resp, 96, 3);
 		csd->max_dtr	  = tran_exp[e] * tran_mant[m];
-		csd->cmdclass	  = UNSTUFF_BITS(resp, 84, 12);
-		csd->c_size	  = UNSTUFF_BITS(resp, 48, 22);
+		csd->cmdclass	  = unstuff_bits(resp, 84, 12);
 
-		/* SDXC cards have a minimum C_SIZE of 0x00FFFF */
-		if (csd->c_size >= 0xFFFF)
+		if (csd_struct == 1)
+			m = unstuff_bits(resp, 48, 22);
+		else
+			m = unstuff_bits(resp, 48, 28);
+		csd->c_size = m;
+
+		if (csd->c_size >= 0x400000 && is_sduc)
+			mmc_card_set_ult_capacity(card);
+		else if (csd->c_size >= 0xFFFF)
 			mmc_card_set_ext_capacity(card);
 
-		m = UNSTUFF_BITS(resp, 48, 22);
-		csd->capacity     = (1 + m) << 10;
+		csd->capacity     = (1 + (typeof(sector_t))m) << 10;
 
 		csd->read_blkbits = 9;
 		csd->read_partial = 0;
@@ -190,7 +183,7 @@
 		csd->write_partial = 0;
 		csd->erase_size = 1;
 
-		if (UNSTUFF_BITS(resp, 13, 1))
+		if (unstuff_bits(resp, 13, 1))
 			mmc_card_set_readonly(card);
 		break;
 	default:
@@ -216,33 +209,33 @@
 	resp[3] = card->raw_scr[1];
 	resp[2] = card->raw_scr[0];
 
-	scr_struct = UNSTUFF_BITS(resp, 60, 4);
+	scr_struct = unstuff_bits(resp, 60, 4);
 	if (scr_struct != 0) {
 		pr_err("%s: unrecognised SCR structure version %d\n",
 			mmc_hostname(card->host), scr_struct);
 		return -EINVAL;
 	}
 
-	scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4);
-	scr->bus_widths = UNSTUFF_BITS(resp, 48, 4);
+	scr->sda_vsn = unstuff_bits(resp, 56, 4);
+	scr->bus_widths = unstuff_bits(resp, 48, 4);
 	if (scr->sda_vsn == SCR_SPEC_VER_2)
 		/* Check if Physical Layer Spec v3.0 is supported */
-		scr->sda_spec3 = UNSTUFF_BITS(resp, 47, 1);
+		scr->sda_spec3 = unstuff_bits(resp, 47, 1);
 
 	if (scr->sda_spec3) {
-		scr->sda_spec4 = UNSTUFF_BITS(resp, 42, 1);
-		scr->sda_specx = UNSTUFF_BITS(resp, 38, 4);
+		scr->sda_spec4 = unstuff_bits(resp, 42, 1);
+		scr->sda_specx = unstuff_bits(resp, 38, 4);
 	}
 
-	if (UNSTUFF_BITS(resp, 55, 1))
+	if (unstuff_bits(resp, 55, 1))
 		card->erased_byte = 0xFF;
 	else
 		card->erased_byte = 0x0;
 
 	if (scr->sda_spec4)
-		scr->cmds = UNSTUFF_BITS(resp, 32, 4);
+		scr->cmds = unstuff_bits(resp, 32, 4);
 	else if (scr->sda_spec3)
-		scr->cmds = UNSTUFF_BITS(resp, 32, 2);
+		scr->cmds = unstuff_bits(resp, 32, 2);
 
 	/* SD Spec says: any SD Card shall set at least bits 0 and 2 */
 	if (!(scr->bus_widths & SD_SCR_BUS_WIDTH_1) ||
@@ -288,17 +281,17 @@
 	kfree(raw_ssr);
 
 	/*
-	 * UNSTUFF_BITS only works with four u32s so we have to offset the
+	 * unstuff_bits only works with four u32s so we have to offset the
 	 * bitfield positions accordingly.
 	 */
-	au = UNSTUFF_BITS(card->raw_ssr, 428 - 384, 4);
+	au = unstuff_bits(card->raw_ssr, 428 - 384, 4);
 	if (au) {
 		if (au <= 9 || card->scr.sda_spec3) {
 			card->ssr.au = sd_au_size[au];
-			es = UNSTUFF_BITS(card->raw_ssr, 408 - 384, 16);
-			et = UNSTUFF_BITS(card->raw_ssr, 402 - 384, 6);
+			es = unstuff_bits(card->raw_ssr, 408 - 384, 16);
+			et = unstuff_bits(card->raw_ssr, 402 - 384, 6);
 			if (es && et) {
-				eo = UNSTUFF_BITS(card->raw_ssr, 400 - 384, 2);
+				eo = unstuff_bits(card->raw_ssr, 400 - 384, 2);
 				card->ssr.erase_timeout = (et * 1000) / es;
 				card->ssr.erase_offset = eo * 1000;
 			}
@@ -312,7 +305,7 @@
 	 * starting SD5.1 discard is supported if DISCARD_SUPPORT (b313) is set
 	 */
 	resp[3] = card->raw_ssr[6];
-	discard_support = UNSTUFF_BITS(resp, 313 - 288, 1);
+	discard_support = unstuff_bits(resp, 313 - 288, 1);
 	card->erase_arg = (card->scr.sda_specx && discard_support) ?
 			    SD_DISCARD_ARG : SD_ERASE_ARG;
 
@@ -886,7 +879,7 @@
 	return err;
 }
 
-int mmc_sd_get_csd(struct mmc_card *card)
+int mmc_sd_get_csd(struct mmc_card *card, bool is_sduc)
 {
 	int err;
 
@@ -897,7 +890,7 @@
 	if (err)
 		return err;
 
-	err = mmc_decode_csd(card);
+	err = mmc_decode_csd(card, is_sduc);
 	if (err)
 		return err;
 
@@ -1117,7 +1110,7 @@
 	card->ext_power.rev = reg_buf[0] & 0xf;
 
 	/* Power Off Notification support at bit 4. */
-	if (reg_buf[1] & BIT(4))
+	if ((reg_buf[1] & BIT(4)) && !mmc_card_broken_sd_poweroff_notify(card))
 		card->ext_power.feature_support |= SD_EXT_POWER_OFF_NOTIFY;
 
 	/* Power Sustenance support at bit 5. */
@@ -1452,7 +1445,7 @@
 	}
 
 	if (!oldcard) {
-		err = mmc_sd_get_csd(card);
+		err = mmc_sd_get_csd(card, false);
 		if (err)
 			goto free_card;
 
@@ -1475,6 +1468,9 @@
 			goto free_card;
 	}
 
+	/* Apply quirks prior to card setup */
+	mmc_fixup_device(card, mmc_sd_fixups);
+
 	err = mmc_sd_setup_card(host, card, oldcard != NULL);
 	if (err)
 		goto free_card;
--- linux-qcom-6.8.0.orig/drivers/mmc/core/sd.h
+++ linux-qcom-6.8.0/drivers/mmc/core/sd.h
@@ -10,7 +10,7 @@
 struct mmc_card;
 
 int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr);
-int mmc_sd_get_csd(struct mmc_card *card);
+int mmc_sd_get_csd(struct mmc_card *card, bool is_sduc);
 void mmc_decode_cid(struct mmc_card *card);
 int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
 	bool reinit);
--- linux-qcom-6.8.0.orig/drivers/mmc/core/sdio.c
+++ linux-qcom-6.8.0/drivers/mmc/core/sdio.c
@@ -458,6 +458,8 @@
 	if (mmc_card_sd_combo(card))
 		max_dtr = min(max_dtr, mmc_sd_get_max_clock(card));
 
+	max_dtr = min_not_zero(max_dtr, card->quirk_max_rate);
+
 	return max_dtr;
 }
 
@@ -769,7 +771,7 @@
 	 * Read CSD, before selecting the card
 	 */
 	if (!oldcard && mmc_card_sd_combo(card)) {
-		err = mmc_sd_get_csd(card);
+		err = mmc_sd_get_csd(card, false);
 		if (err)
 			goto remove;
 
--- linux-qcom-6.8.0.orig/drivers/mmc/core/slot-gpio.c
+++ linux-qcom-6.8.0/drivers/mmc/core/slot-gpio.c
@@ -221,6 +221,26 @@
 }
 EXPORT_SYMBOL(mmc_gpiod_request_cd);
 
+/**
+ * mmc_gpiod_set_cd_config - set config for card-detection GPIO
+ * @host: mmc host
+ * @config: Generic pinconf config (from pinconf_to_config_packed())
+ *
+ * This can be used by mmc host drivers to fixup a card-detection GPIO's config
+ * (e.g. set PIN_CONFIG_BIAS_PULL_UP) after acquiring the GPIO descriptor
+ * through mmc_gpiod_request_cd().
+ *
+ * Returns:
+ * 0 on success, or a negative errno value on error.
+ */
+int mmc_gpiod_set_cd_config(struct mmc_host *host, unsigned long config)
+{
+	struct mmc_gpio *ctx = host->slot.handler_priv;
+
+	return gpiod_set_config(ctx->cd_gpio, config);
+}
+EXPORT_SYMBOL(mmc_gpiod_set_cd_config);
+
 bool mmc_can_gpio_cd(struct mmc_host *host)
 {
 	struct mmc_gpio *ctx = host->slot.handler_priv;
--- linux-qcom-6.8.0.orig/drivers/mmc/host/cqhci-core.c
+++ linux-qcom-6.8.0/drivers/mmc/host/cqhci-core.c
@@ -612,7 +612,7 @@
 		cqhci_writel(cq_host, 0, CQHCI_CTL);
 		mmc->cqe_on = true;
 		pr_debug("%s: cqhci: CQE on\n", mmc_hostname(mmc));
-		if (cqhci_readl(cq_host, CQHCI_CTL) && CQHCI_HALT) {
+		if (cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT) {
 			pr_err("%s: cqhci: CQE failed to exit halt state\n",
 			       mmc_hostname(mmc));
 		}
--- linux-qcom-6.8.0.orig/drivers/mmc/host/cqhci-crypto.c
+++ linux-qcom-6.8.0/drivers/mmc/host/cqhci-crypto.c
@@ -32,6 +32,7 @@
 }
 
 static int cqhci_crypto_program_key(struct cqhci_host *cq_host,
+				    const struct blk_crypto_key *bkey,
 				    const union cqhci_crypto_cfg_entry *cfg,
 				    int slot)
 {
@@ -39,7 +40,7 @@
 	int i;
 
 	if (cq_host->ops->program_key)
-		return cq_host->ops->program_key(cq_host, cfg, slot);
+		return cq_host->ops->program_key(cq_host, bkey, cfg, slot);
 
 	/* Clear CFGE */
 	cqhci_writel(cq_host, 0, slot_offset + 16 * sizeof(cfg->reg_val[0]));
@@ -90,16 +91,18 @@
 	cfg.crypto_cap_idx = cap_idx;
 	cfg.config_enable = CQHCI_CRYPTO_CONFIGURATION_ENABLE;
 
-	if (ccap_array[cap_idx].algorithm_id == CQHCI_CRYPTO_ALG_AES_XTS) {
-		/* In XTS mode, the blk_crypto_key's size is already doubled */
-		memcpy(cfg.crypto_key, key->raw, key->size/2);
-		memcpy(cfg.crypto_key + CQHCI_CRYPTO_KEY_MAX_SIZE/2,
-		       key->raw + key->size/2, key->size/2);
-	} else {
-		memcpy(cfg.crypto_key, key->raw, key->size);
+	if (key->crypto_cfg.key_type != BLK_CRYPTO_KEY_TYPE_HW_WRAPPED) {
+		if (ccap_array[cap_idx].algorithm_id == CQHCI_CRYPTO_ALG_AES_XTS) {
+			/* In XTS mode, the blk_crypto_key's size is already doubled */
+			memcpy(cfg.crypto_key, key->raw, key->size/2);
+			memcpy(cfg.crypto_key + CQHCI_CRYPTO_KEY_MAX_SIZE/2,
+			       key->raw + key->size/2, key->size/2);
+		} else {
+			memcpy(cfg.crypto_key, key->raw, key->size);
+		}
 	}
 
-	err = cqhci_crypto_program_key(cq_host, &cfg, slot);
+	err = cqhci_crypto_program_key(cq_host, key, &cfg, slot);
 
 	memzero_explicit(&cfg, sizeof(cfg));
 	return err;
@@ -113,7 +116,7 @@
 	 */
 	union cqhci_crypto_cfg_entry cfg = {};
 
-	return cqhci_crypto_program_key(cq_host, &cfg, slot);
+	return cqhci_crypto_program_key(cq_host, NULL, &cfg, slot);
 }
 
 static int cqhci_crypto_keyslot_evict(struct blk_crypto_profile *profile,
@@ -125,6 +128,58 @@
 	return cqhci_crypto_clear_keyslot(cq_host, slot);
 }
 
+static int cqhci_crypto_derive_sw_secret(struct blk_crypto_profile *profile,
+					  const u8 wkey[], size_t wkey_size,
+					  u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE])
+{
+	struct cqhci_host *cq_host = cqhci_host_from_crypto_profile(profile);
+
+	if (cq_host->ops && cq_host->ops->derive_sw_secret)
+		return  cq_host->ops->derive_sw_secret(cq_host, wkey, wkey_size,
+						       sw_secret);
+
+	return -EOPNOTSUPP;
+}
+
+static int cqhci_crypto_generate_key(struct blk_crypto_profile *profile,
+				     u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE])
+{
+	struct cqhci_host *cq_host = cqhci_host_from_crypto_profile(profile);
+
+	if (cq_host->ops && cq_host->ops->generate_key)
+		return  cq_host->ops->generate_key(cq_host, lt_key);
+
+	return -EOPNOTSUPP;
+}
+
+static int cqhci_crypto_prepare_key(struct blk_crypto_profile *profile,
+				    const u8 *lt_key, size_t lt_key_size,
+				    u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE])
+{
+
+	struct cqhci_host *cq_host = cqhci_host_from_crypto_profile(profile);
+
+	if (cq_host->ops && cq_host->ops->prepare_key)
+		return  cq_host->ops->prepare_key(cq_host, lt_key,
+						  lt_key_size, eph_key);
+
+	return -EOPNOTSUPP;
+}
+
+static int cqhci_crypto_import_key(struct blk_crypto_profile *profile,
+				   const u8 *imp_key, size_t imp_key_size,
+				   u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE])
+{
+
+	struct cqhci_host *cq_host = cqhci_host_from_crypto_profile(profile);
+
+	if (cq_host->ops && cq_host->ops->import_key)
+		return  cq_host->ops->import_key(cq_host, imp_key,
+						 imp_key_size, lt_key);
+
+	return -EOPNOTSUPP;
+}
+
 /*
  * The keyslot management operations for CQHCI crypto.
  *
@@ -136,6 +191,10 @@
 static const struct blk_crypto_ll_ops cqhci_crypto_ops = {
 	.keyslot_program	= cqhci_crypto_keyslot_program,
 	.keyslot_evict		= cqhci_crypto_keyslot_evict,
+	.derive_sw_secret	= cqhci_crypto_derive_sw_secret,
+	.generate_key		= cqhci_crypto_generate_key,
+	.prepare_key		= cqhci_crypto_prepare_key,
+	.import_key		= cqhci_crypto_import_key,
 };
 
 static enum blk_crypto_mode_num
@@ -210,6 +269,13 @@
 	/* Unfortunately, CQHCI crypto only supports 32 DUN bits. */
 	profile->max_dun_bytes_supported = 4;
 
+	if (cq_host->quirks & CQHCI_QUIRK_USES_WRAPPED_CRYPTO_KEYS)
+		profile->key_types_supported =
+			BLK_CRYPTO_KEY_TYPE_HW_WRAPPED;
+	else
+		profile->key_types_supported =
+			BLK_CRYPTO_KEY_TYPE_STANDARD;
+
 	/*
 	 * Cache all the crypto capabilities and advertise the supported crypto
 	 * modes and data unit sizes to the block layer.
--- linux-qcom-6.8.0.orig/drivers/mmc/host/cqhci.h
+++ linux-qcom-6.8.0/drivers/mmc/host/cqhci.h
@@ -12,6 +12,7 @@
 #include <linux/completion.h>
 #include <linux/wait.h>
 #include <linux/irqreturn.h>
+#include <linux/blk-crypto.h>
 #include <asm/io.h>
 
 /* registers */
@@ -240,6 +241,12 @@
 	u32 quirks;
 #define CQHCI_QUIRK_SHORT_TXFR_DESC_SZ	0x1
 
+	/*
+	 * This quirk indicates that EMMC will be using HW wrapped keys
+	 * when using inline encryption.
+	 */
+#define CQHCI_QUIRK_USES_WRAPPED_CRYPTO_KEYS	0x2
+
 	bool enabled;
 	bool halted;
 	bool init_done;
@@ -279,6 +286,11 @@
 #endif
 };
 
+/* @derive_sw_secret: derive sw secret from a wrapped key
+ * @generate_key: generate a storage key and return longterm wrapped key
+ * @prepare_key: unwrap longterm key and return ephemeral wrapped key
+ * @import_key: import sw storage key and return longterm wrapped key
+ */
 struct cqhci_host_ops {
 	void (*dumpregs)(struct mmc_host *mmc);
 	void (*write_l)(struct cqhci_host *host, u32 val, int reg);
@@ -291,7 +303,19 @@
 	void (*post_disable)(struct mmc_host *mmc);
 #ifdef CONFIG_MMC_CRYPTO
 	int (*program_key)(struct cqhci_host *cq_host,
+			   const struct blk_crypto_key *bkey,
 			   const union cqhci_crypto_cfg_entry *cfg, int slot);
+	int (*derive_sw_secret)(struct cqhci_host *cq_host, const u8 wkey[],
+				unsigned int wkey_size,
+				u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE]);
+	int (*generate_key)(struct cqhci_host *cq_host,
+			    u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]);
+	int (*prepare_key)(struct cqhci_host *cq_host,
+			   const u8 *lt_key, size_t lt_key_size,
+			   u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]);
+	int (*import_key)(struct cqhci_host *cq_host, const u8 *imp_key,
+			  size_t imp_key_size,
+			  u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE]);
 #endif
 };
 
--- linux-qcom-6.8.0.orig/drivers/mmc/host/davinci_mmc.c
+++ linux-qcom-6.8.0/drivers/mmc/host/davinci_mmc.c
@@ -238,6 +238,9 @@
 	host->buffer_bytes_left -= n;
 	host->bytes_left -= n;
 
+	if (n > sgm->length)
+		n = sgm->length;
+
 	/* NOTE:  we never transfer more than rw_threshold bytes
 	 * to/from the fifo here; there's no I/O overlap.
 	 * This also assumes that access width( i.e. ACCWD) is 4 bytes
@@ -1344,7 +1347,7 @@
 	return ret;
 }
 
-static void __exit davinci_mmcsd_remove(struct platform_device *pdev)
+static void davinci_mmcsd_remove(struct platform_device *pdev)
 {
 	struct mmc_davinci_host *host = platform_get_drvdata(pdev);
 
@@ -1399,7 +1402,7 @@
 		.of_match_table = davinci_mmc_dt_ids,
 	},
 	.probe		= davinci_mmcsd_probe,
-	.remove_new	= __exit_p(davinci_mmcsd_remove),
+	.remove_new	= davinci_mmcsd_remove,
 	.id_table	= davinci_mmc_devtype,
 };
 
--- linux-qcom-6.8.0.orig/drivers/mmc/host/dw_mmc.c
+++ linux-qcom-6.8.0/drivers/mmc/host/dw_mmc.c
@@ -3294,6 +3294,10 @@
 	host->biu_clk = devm_clk_get(host->dev, "biu");
 	if (IS_ERR(host->biu_clk)) {
 		dev_dbg(host->dev, "biu clock not available\n");
+		ret = PTR_ERR(host->biu_clk);
+		if (ret == -EPROBE_DEFER)
+			return ret;
+
 	} else {
 		ret = clk_prepare_enable(host->biu_clk);
 		if (ret) {
@@ -3305,6 +3309,10 @@
 	host->ciu_clk = devm_clk_get(host->dev, "ciu");
 	if (IS_ERR(host->ciu_clk)) {
 		dev_dbg(host->dev, "ciu clock not available\n");
+		ret = PTR_ERR(host->ciu_clk);
+		if (ret == -EPROBE_DEFER)
+			goto err_clk_biu;
+
 		host->bus_hz = host->pdata->bus_hz;
 	} else {
 		ret = clk_prepare_enable(host->ciu_clk);
--- linux-qcom-6.8.0.orig/drivers/mmc/host/mmc_spi.c
+++ linux-qcom-6.8.0/drivers/mmc/host/mmc_spi.c
@@ -223,10 +223,6 @@
 	u8 	leftover = 0;
 	unsigned short rotator;
 	int 	i;
-	char	tag[32];
-
-	snprintf(tag, sizeof(tag), "  ... CMD%d response SPI_%s",
-		cmd->opcode, maptype(cmd));
 
 	/* Except for data block reads, the whole response will already
 	 * be stored in the scratch buffer.  It's somewhere after the
@@ -379,8 +375,9 @@
 	}
 
 	if (value < 0)
-		dev_dbg(&host->spi->dev, "%s: resp %04x %08x\n",
-			tag, cmd->resp[0], cmd->resp[1]);
+		dev_dbg(&host->spi->dev,
+			"  ... CMD%d response SPI_%s: resp %04x %08x\n",
+			cmd->opcode, maptype(cmd), cmd->resp[0], cmd->resp[1]);
 
 	/* disable chipselect on errors and some success cases */
 	if (value >= 0 && cs_on)
--- linux-qcom-6.8.0.orig/drivers/mmc/host/mtk-sd.c
+++ linux-qcom-6.8.0/drivers/mmc/host/mtk-sd.c
@@ -1231,7 +1231,7 @@
 	}
 
 	if (!sbc_error && !(events & MSDC_INT_CMDRDY)) {
-		if (events & MSDC_INT_CMDTMO ||
+		if ((events & MSDC_INT_CMDTMO && !host->hs400_tuning) ||
 		    (!mmc_op_tuning(cmd->opcode) && !host->hs400_tuning))
 			/*
 			 * should not clear fifo/interrupt as the tune data
@@ -1324,9 +1324,9 @@
 static void msdc_cmd_next(struct msdc_host *host,
 		struct mmc_request *mrq, struct mmc_command *cmd)
 {
-	if ((cmd->error &&
-	    !(cmd->error == -EILSEQ &&
-	      (mmc_op_tuning(cmd->opcode) || host->hs400_tuning))) ||
+	if ((cmd->error && !host->hs400_tuning &&
+	     !(cmd->error == -EILSEQ &&
+	     mmc_op_tuning(cmd->opcode))) ||
 	    (mrq->sbc && mrq->sbc->error))
 		msdc_request_done(host, mrq);
 	else if (cmd == mrq->sbc)
@@ -2738,20 +2738,18 @@
 	}
 
 	/* Allocate MMC host for this device */
-	mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev);
+	mmc = devm_mmc_alloc_host(&pdev->dev, sizeof(struct msdc_host));
 	if (!mmc)
 		return -ENOMEM;
 
 	host = mmc_priv(mmc);
 	ret = mmc_of_parse(mmc);
 	if (ret)
-		goto host_free;
+		return ret;
 
 	host->base = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(host->base)) {
-		ret = PTR_ERR(host->base);
-		goto host_free;
-	}
+	if (IS_ERR(host->base))
+		return PTR_ERR(host->base);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	if (res) {
@@ -2762,53 +2760,45 @@
 
 	ret = mmc_regulator_get_supply(mmc);
 	if (ret)
-		goto host_free;
+		return ret;
 
 	ret = msdc_of_clock_parse(pdev, host);
 	if (ret)
-		goto host_free;
+		return ret;
 
 	host->reset = devm_reset_control_get_optional_exclusive(&pdev->dev,
 								"hrst");
-	if (IS_ERR(host->reset)) {
-		ret = PTR_ERR(host->reset);
-		goto host_free;
-	}
+	if (IS_ERR(host->reset))
+		return PTR_ERR(host->reset);
 
 	/* only eMMC has crypto property */
 	if (!(mmc->caps2 & MMC_CAP2_NO_MMC)) {
 		host->crypto_clk = devm_clk_get_optional(&pdev->dev, "crypto");
 		if (IS_ERR(host->crypto_clk))
-			host->crypto_clk = NULL;
-		else
+			return PTR_ERR(host->crypto_clk);
+		else if (host->crypto_clk)
 			mmc->caps2 |= MMC_CAP2_CRYPTO;
 	}
 
 	host->irq = platform_get_irq(pdev, 0);
-	if (host->irq < 0) {
-		ret = host->irq;
-		goto host_free;
-	}
+	if (host->irq < 0)
+		return host->irq;
 
 	host->pinctrl = devm_pinctrl_get(&pdev->dev);
-	if (IS_ERR(host->pinctrl)) {
-		ret = PTR_ERR(host->pinctrl);
-		dev_err(&pdev->dev, "Cannot find pinctrl!\n");
-		goto host_free;
-	}
+	if (IS_ERR(host->pinctrl))
+		return dev_err_probe(&pdev->dev, PTR_ERR(host->pinctrl),
+				     "Cannot find pinctrl");
 
 	host->pins_default = pinctrl_lookup_state(host->pinctrl, "default");
 	if (IS_ERR(host->pins_default)) {
-		ret = PTR_ERR(host->pins_default);
 		dev_err(&pdev->dev, "Cannot find pinctrl default!\n");
-		goto host_free;
+		return PTR_ERR(host->pins_default);
 	}
 
 	host->pins_uhs = pinctrl_lookup_state(host->pinctrl, "state_uhs");
 	if (IS_ERR(host->pins_uhs)) {
-		ret = PTR_ERR(host->pins_uhs);
 		dev_err(&pdev->dev, "Cannot find pinctrl uhs!\n");
-		goto host_free;
+		return PTR_ERR(host->pins_uhs);
 	}
 
 	/* Support for SDIO eint irq ? */
@@ -2887,7 +2877,7 @@
 	ret = msdc_ungate_clock(host);
 	if (ret) {
 		dev_err(&pdev->dev, "Cannot ungate clocks!\n");
-		goto release_mem;
+		goto release_clk;
 	}
 	msdc_init_hw(host);
 
@@ -2897,14 +2887,14 @@
 					     GFP_KERNEL);
 		if (!host->cq_host) {
 			ret = -ENOMEM;
-			goto host_free;
+			goto release;
 		}
 		host->cq_host->caps |= CQHCI_TASK_DESC_SZ_128;
 		host->cq_host->mmio = host->base + 0x800;
 		host->cq_host->ops = &msdc_cmdq_ops;
 		ret = cqhci_init(host->cq_host, mmc, true);
 		if (ret)
-			goto host_free;
+			goto release;
 		mmc->max_segs = 128;
 		/* cqhci 16bit length */
 		/* 0 size, means 65536 so we don't have to -1 here */
@@ -2931,21 +2921,20 @@
 end:
 	pm_runtime_disable(host->dev);
 release:
-	platform_set_drvdata(pdev, NULL);
 	msdc_deinit_hw(host);
+release_clk:
 	msdc_gate_clock(host);
+	platform_set_drvdata(pdev, NULL);
 release_mem:
+	device_init_wakeup(&pdev->dev, false);
 	if (host->dma.gpd)
 		dma_free_coherent(&pdev->dev,
 			2 * sizeof(struct mt_gpdma_desc),
 			host->dma.gpd, host->dma.gpd_addr);
 	if (host->dma.bd)
 		dma_free_coherent(&pdev->dev,
-			MAX_BD_NUM * sizeof(struct mt_bdma_desc),
-			host->dma.bd, host->dma.bd_addr);
-host_free:
-	mmc_free_host(mmc);
-
+				  MAX_BD_NUM * sizeof(struct mt_bdma_desc),
+				  host->dma.bd, host->dma.bd_addr);
 	return ret;
 }
 
@@ -2970,9 +2959,8 @@
 			2 * sizeof(struct mt_gpdma_desc),
 			host->dma.gpd, host->dma.gpd_addr);
 	dma_free_coherent(&pdev->dev, MAX_BD_NUM * sizeof(struct mt_bdma_desc),
-			host->dma.bd, host->dma.bd_addr);
-
-	mmc_free_host(mmc);
+			  host->dma.bd, host->dma.bd_addr);
+	device_init_wakeup(&pdev->dev, false);
 }
 
 static void msdc_save_reg(struct msdc_host *host)
--- linux-qcom-6.8.0.orig/drivers/mmc/host/omap.c
+++ linux-qcom-6.8.0/drivers/mmc/host/omap.c
@@ -1119,10 +1119,25 @@
 
 	host = slot->host;
 
-	if (slot->vsd)
-		gpiod_set_value(slot->vsd, power_on);
-	if (slot->vio)
-		gpiod_set_value(slot->vio, power_on);
+	if (power_on) {
+		if (slot->vsd) {
+			gpiod_set_value(slot->vsd, power_on);
+			msleep(1);
+		}
+		if (slot->vio) {
+			gpiod_set_value(slot->vio, power_on);
+			msleep(1);
+		}
+	} else {
+		if (slot->vio) {
+			gpiod_set_value(slot->vio, power_on);
+			msleep(50);
+		}
+		if (slot->vsd) {
+			gpiod_set_value(slot->vsd, power_on);
+			msleep(50);
+		}
+	}
 
 	if (slot->pdata->set_power != NULL)
 		slot->pdata->set_power(mmc_dev(slot->mmc), slot->id, power_on,
@@ -1259,18 +1274,18 @@
 	slot->pdata = &host->pdata->slots[id];
 
 	/* Check for some optional GPIO controls */
-	slot->vsd = gpiod_get_index_optional(host->dev, "vsd",
-					     id, GPIOD_OUT_LOW);
+	slot->vsd = devm_gpiod_get_index_optional(host->dev, "vsd",
+						  id, GPIOD_OUT_LOW);
 	if (IS_ERR(slot->vsd))
 		return dev_err_probe(host->dev, PTR_ERR(slot->vsd),
 				     "error looking up VSD GPIO\n");
-	slot->vio = gpiod_get_index_optional(host->dev, "vio",
-					     id, GPIOD_OUT_LOW);
+	slot->vio = devm_gpiod_get_index_optional(host->dev, "vio",
+						  id, GPIOD_OUT_LOW);
 	if (IS_ERR(slot->vio))
 		return dev_err_probe(host->dev, PTR_ERR(slot->vio),
 				     "error looking up VIO GPIO\n");
-	slot->cover = gpiod_get_index_optional(host->dev, "cover",
-						id, GPIOD_IN);
+	slot->cover = devm_gpiod_get_index_optional(host->dev, "cover",
+						    id, GPIOD_IN);
 	if (IS_ERR(slot->cover))
 		return dev_err_probe(host->dev, PTR_ERR(slot->cover),
 				     "error looking up cover switch GPIO\n");
@@ -1384,13 +1399,6 @@
 	if (IS_ERR(host->virt_base))
 		return PTR_ERR(host->virt_base);
 
-	host->slot_switch = gpiod_get_optional(host->dev, "switch",
-					       GPIOD_OUT_LOW);
-	if (IS_ERR(host->slot_switch))
-		return dev_err_probe(host->dev, PTR_ERR(host->slot_switch),
-				     "error looking up slot switch GPIO\n");
-
-
 	INIT_WORK(&host->slot_release_work, mmc_omap_slot_release_work);
 	INIT_WORK(&host->send_stop_work, mmc_omap_send_stop_work);
 
@@ -1409,6 +1417,12 @@
 	host->dev = &pdev->dev;
 	platform_set_drvdata(pdev, host);
 
+	host->slot_switch = devm_gpiod_get_optional(host->dev, "switch",
+						    GPIOD_OUT_LOW);
+	if (IS_ERR(host->slot_switch))
+		return dev_err_probe(host->dev, PTR_ERR(host->slot_switch),
+				     "error looking up slot switch GPIO\n");
+
 	host->id = pdev->id;
 	host->irq = irq;
 	host->phys_base = res->start;
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci-acpi.c
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci-acpi.c
@@ -10,6 +10,7 @@
 #include <linux/export.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/pinctrl/pinconf-generic.h>
 #include <linux/platform_device.h>
 #include <linux/ioport.h>
 #include <linux/io.h>
@@ -80,6 +81,8 @@
 enum {
 	DMI_QUIRK_RESET_SD_SIGNAL_VOLT_ON_SUSP			= BIT(0),
 	DMI_QUIRK_SD_NO_WRITE_PROTECT				= BIT(1),
+	DMI_QUIRK_SD_CD_ACTIVE_HIGH				= BIT(2),
+	DMI_QUIRK_SD_CD_ENABLE_PULL_UP				= BIT(3),
 };
 
 static inline void *sdhci_acpi_priv(struct sdhci_acpi_host *c)
@@ -719,9 +722,30 @@
 };
 MODULE_DEVICE_TABLE(acpi, sdhci_acpi_ids);
 
+/* Please keep this list sorted alphabetically */
 static const struct dmi_system_id sdhci_acpi_quirks[] = {
 	{
 		/*
+		 * The Acer Aspire Switch 10 (SW5-012) microSD slot always
+		 * reports the card being write-protected even though microSD
+		 * cards do not have a write-protect switch at all.
+		 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
+		},
+		.driver_data = (void *)DMI_QUIRK_SD_NO_WRITE_PROTECT,
+	},
+	{
+		/* Asus T100TA, needs pull-up for cd but DSDT GpioInt has NoPull set */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"),
+		},
+		.driver_data = (void *)DMI_QUIRK_SD_CD_ENABLE_PULL_UP,
+	},
+	{
+		/*
 		 * The Lenovo Miix 320-10ICR has a bug in the _PS0 method of
 		 * the SHC1 ACPI device, this bug causes it to reprogram the
 		 * wrong LDO (DLDO3) to 1.8V if 1.8V modes are used and the
@@ -736,15 +760,23 @@
 	},
 	{
 		/*
-		 * The Acer Aspire Switch 10 (SW5-012) microSD slot always
-		 * reports the card being write-protected even though microSD
-		 * cards do not have a write-protect switch at all.
+		 * Lenovo Yoga Tablet 2 Pro 1380F/L (13" Android version) this
+		 * has broken WP reporting and an inverted CD signal.
+		 * Note this has more or less the same BIOS as the Lenovo Yoga
+		 * Tablet 2 830F/L or 1050F/L (8" and 10" Android), but unlike
+		 * the 830 / 1050 models which share the same mainboard this
+		 * model has a different mainboard and the inverted CD and
+		 * broken WP are unique to this board.
 		 */
 		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
+			DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"),
+			DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"),
+			/* Full match so as to NOT match the 830/1050 BIOS */
+			DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21.X64.0005.R00.1504101516"),
 		},
-		.driver_data = (void *)DMI_QUIRK_SD_NO_WRITE_PROTECT,
+		.driver_data = (void *)(DMI_QUIRK_SD_NO_WRITE_PROTECT |
+					DMI_QUIRK_SD_CD_ACTIVE_HIGH),
 	},
 	{
 		/*
@@ -757,6 +789,17 @@
 		},
 		.driver_data = (void *)DMI_QUIRK_SD_NO_WRITE_PROTECT,
 	},
+	{
+		/*
+		 * The Toshiba WT10-A's microSD slot always reports the card being
+		 * write-protected.
+		 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "TOSHIBA WT10-A"),
+		},
+		.driver_data = (void *)DMI_QUIRK_SD_NO_WRITE_PROTECT,
+	},
 	{} /* Terminating entry */
 };
 
@@ -866,12 +909,18 @@
 	if (sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD)) {
 		bool v = sdhci_acpi_flag(c, SDHCI_ACPI_SD_CD_OVERRIDE_LEVEL);
 
+		if (quirks & DMI_QUIRK_SD_CD_ACTIVE_HIGH)
+			host->mmc->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
+
 		err = mmc_gpiod_request_cd(host->mmc, NULL, 0, v, 0);
 		if (err) {
 			if (err == -EPROBE_DEFER)
 				goto err_free;
 			dev_warn(dev, "failed to setup card detect gpio\n");
 			c->use_runtime_pm = false;
+		} else if (quirks & DMI_QUIRK_SD_CD_ENABLE_PULL_UP) {
+			mmc_gpiod_set_cd_config(host->mmc,
+						PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 20000));
 		}
 
 		if (quirks & DMI_QUIRK_RESET_SD_SIGNAL_VOLT_ON_SUSP)
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci-brcmstb.c
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci-brcmstb.c
@@ -24,6 +24,7 @@
 #define BRCMSTB_MATCH_FLAGS_NO_64BIT		BIT(0)
 #define BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT	BIT(1)
 #define BRCMSTB_MATCH_FLAGS_HAS_CLOCK_GATE	BIT(2)
+#define BRCMSTB_MATCH_FLAGS_USE_CARD_BUSY	BIT(4)
 
 #define BRCMSTB_PRIV_FLAGS_HAS_CQE		BIT(0)
 #define BRCMSTB_PRIV_FLAGS_GATE_CLOCK		BIT(1)
@@ -384,6 +385,9 @@
 	if (match_priv->flags & BRCMSTB_MATCH_FLAGS_BROKEN_TIMEOUT)
 		host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
 
+	if (!(match_priv->flags & BRCMSTB_MATCH_FLAGS_USE_CARD_BUSY))
+		host->mmc_host_ops.card_busy = NULL;
+
 	/* Change the base clock frequency if the DT property exists */
 	if (device_property_read_u32(&pdev->dev, "clock-frequency",
 				     &priv->base_freq_hz) != 0)
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci-esdhc-imx.c
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -235,6 +235,7 @@
 
 struct esdhc_soc_data {
 	u32 flags;
+	u32 quirks;
 };
 
 static const struct esdhc_soc_data esdhc_imx25_data = {
@@ -299,6 +300,7 @@
 			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
 			| ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES
 			| ESDHC_FLAG_SKIP_ERR004536,
+	.quirks = SDHCI_QUIRK_NO_LED,
 };
 
 static struct esdhc_soc_data usdhc_imx7ulp_data = {
@@ -306,10 +308,12 @@
 			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
 			| ESDHC_FLAG_PMQOS | ESDHC_FLAG_HS400
 			| ESDHC_FLAG_STATE_LOST_IN_LPMODE,
+	.quirks = SDHCI_QUIRK_NO_LED,
 };
 static struct esdhc_soc_data usdhc_imxrt1050_data = {
 	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
 			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,
+	.quirks = SDHCI_QUIRK_NO_LED,
 };
 
 static struct esdhc_soc_data usdhc_imx8qxp_data = {
@@ -318,6 +322,7 @@
 			| ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES
 			| ESDHC_FLAG_STATE_LOST_IN_LPMODE
 			| ESDHC_FLAG_CLK_RATE_LOST_IN_PM_RUNTIME,
+	.quirks = SDHCI_QUIRK_NO_LED,
 };
 
 static struct esdhc_soc_data usdhc_imx8mm_data = {
@@ -325,6 +330,7 @@
 			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
 			| ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES
 			| ESDHC_FLAG_STATE_LOST_IN_LPMODE,
+	.quirks = SDHCI_QUIRK_NO_LED,
 };
 
 struct pltfm_imx_data {
@@ -1684,6 +1690,7 @@
 
 	imx_data->socdata = device_get_match_data(&pdev->dev);
 
+	host->quirks |= imx_data->socdata->quirks;
 	if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS)
 		cpu_latency_qos_add_request(&imx_data->pm_qos_req, 0);
 
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci-msm.c
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci-msm.c
@@ -134,9 +134,18 @@
 /* Timeout value to avoid infinite waiting for pwr_irq */
 #define MSM_PWR_IRQ_TIMEOUT_MS 5000
 
+/* Max load for eMMC Vdd supply */
+#define MMC_VMMC_MAX_LOAD_UA	570000
+
 /* Max load for eMMC Vdd-io supply */
 #define MMC_VQMMC_MAX_LOAD_UA	325000
 
+/* Max load for SD Vdd supply */
+#define SD_VMMC_MAX_LOAD_UA	800000
+
+/* Max load for SD Vdd-io supply */
+#define SD_VQMMC_MAX_LOAD_UA	22000
+
 #define msm_host_readl(msm_host, host, offset) \
 	msm_host->var_ops->msm_readl_relaxed(host, offset)
 
@@ -1403,11 +1412,48 @@
 	return ret;
 }
 
-static int sdhci_msm_set_vmmc(struct mmc_host *mmc)
+static void msm_config_vmmc_regulator(struct mmc_host *mmc, bool hpm)
+{
+	int load;
+
+	if (!hpm)
+		load = 0;
+	else if (!mmc->card)
+		load = max(MMC_VMMC_MAX_LOAD_UA, SD_VMMC_MAX_LOAD_UA);
+	else if (mmc_card_mmc(mmc->card))
+		load = MMC_VMMC_MAX_LOAD_UA;
+	else if (mmc_card_sd(mmc->card))
+		load = SD_VMMC_MAX_LOAD_UA;
+	else
+		return;
+
+	regulator_set_load(mmc->supply.vmmc, load);
+}
+
+static void msm_config_vqmmc_regulator(struct mmc_host *mmc, bool hpm)
+{
+	int load;
+
+	if (!hpm)
+		load = 0;
+	else if (!mmc->card)
+		load = max(MMC_VQMMC_MAX_LOAD_UA, SD_VQMMC_MAX_LOAD_UA);
+	else if (mmc_card_sd(mmc->card))
+		load = SD_VQMMC_MAX_LOAD_UA;
+	else
+		return;
+
+	regulator_set_load(mmc->supply.vqmmc, load);
+}
+
+static int sdhci_msm_set_vmmc(struct sdhci_msm_host *msm_host,
+			      struct mmc_host *mmc, bool hpm)
 {
 	if (IS_ERR(mmc->supply.vmmc))
 		return 0;
 
+	msm_config_vmmc_regulator(mmc, hpm);
+
 	return mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, mmc->ios.vdd);
 }
 
@@ -1420,6 +1466,8 @@
 	if (msm_host->vqmmc_enabled == level)
 		return 0;
 
+	msm_config_vqmmc_regulator(mmc, level);
+
 	if (level) {
 		/* Set the IO voltage regulator to default voltage level */
 		if (msm_host->caps_0 & CORE_3_0V_SUPPORT)
@@ -1642,7 +1690,8 @@
 	}
 
 	if (pwr_state) {
-		ret = sdhci_msm_set_vmmc(mmc);
+		ret = sdhci_msm_set_vmmc(msm_host, mmc,
+					 pwr_state & REQ_BUS_ON);
 		if (!ret)
 			ret = sdhci_msm_set_vqmmc(msm_host, mmc,
 					pwr_state & REQ_BUS_ON);
@@ -1829,6 +1878,9 @@
 	msm_host->ice = ice;
 	mmc->caps2 |= MMC_CAP2_CRYPTO;
 
+	if (qcom_ice_hwkm_supported(msm_host->ice))
+		cq_host->quirks |= CQHCI_QUIRK_USES_WRAPPED_CRYPTO_KEYS;
+
 	return 0;
 }
 
@@ -1859,6 +1911,7 @@
  * vendor-specific SCM calls for this; it doesn't support the standard way.
  */
 static int sdhci_msm_program_key(struct cqhci_host *cq_host,
+				 const struct blk_crypto_key *bkey,
 				 const union cqhci_crypto_cfg_entry *cfg,
 				 int slot)
 {
@@ -1866,6 +1919,10 @@
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
 	union cqhci_crypto_cap_entry cap;
+	u8 ice_key_size;
+
+	if (!(cfg->config_enable & CQHCI_CRYPTO_CONFIGURATION_ENABLE))
+		return qcom_ice_evict_key(msm_host->ice, slot);
 
 	/* Only AES-256-XTS has been tested so far. */
 	cap = cq_host->crypto_cap_array[cfg->crypto_cap_idx];
@@ -1873,16 +1930,63 @@
 		cap.key_size != CQHCI_CRYPTO_KEY_SIZE_256)
 		return -EINVAL;
 
-	if (cfg->config_enable & CQHCI_CRYPTO_CONFIGURATION_ENABLE)
-		return qcom_ice_program_key(msm_host->ice,
-					    QCOM_ICE_CRYPTO_ALG_AES_XTS,
-					    QCOM_ICE_CRYPTO_KEY_SIZE_256,
-					    cfg->crypto_key,
-					    cfg->data_unit_size, slot);
+	if (bkey->crypto_cfg.key_type == BLK_CRYPTO_KEY_TYPE_HW_WRAPPED)
+		ice_key_size = QCOM_ICE_CRYPTO_KEY_SIZE_WRAPPED;
 	else
-		return qcom_ice_evict_key(msm_host->ice, slot);
+		ice_key_size = QCOM_ICE_CRYPTO_KEY_SIZE_256;
+
+	return qcom_ice_program_key(msm_host->ice,
+				    QCOM_ICE_CRYPTO_ALG_AES_XTS,
+				    ice_key_size, bkey,
+				    cfg->data_unit_size, slot);
+}
+
+/*
+ * Derive a software secret from a hardware wrapped key. The key is unwrapped in
+ * hardware from trustzone and a software key/secret is then derived from it.
+ */
+static int sdhci_msm_ice_derive_sw_secret(struct cqhci_host *cq_host, const u8 wkey[],
+					  unsigned int wkey_size,
+					  u8 sw_secret[BLK_CRYPTO_SW_SECRET_SIZE])
+{
+	struct sdhci_host *host = mmc_priv(cq_host->mmc);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+
+	return qcom_ice_derive_sw_secret(msm_host->ice, wkey, wkey_size, sw_secret);
 }
 
+static int sdhci_msm_generate_key(struct cqhci_host *cq_host,
+				  u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE])
+{
+	struct sdhci_host *host = mmc_priv(cq_host->mmc);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+
+	return qcom_ice_generate_key(msm_host->ice, lt_key);
+}
+
+static int sdhci_msm_prepare_key(struct cqhci_host *cq_host,
+			  const u8 *lt_key, size_t lt_key_size,
+			  u8 eph_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE])
+{
+	struct sdhci_host *host = mmc_priv(cq_host->mmc);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+
+	return qcom_ice_prepare_key(msm_host->ice, lt_key, lt_key_size, eph_key);
+}
+
+static int sdhci_msm_import_key(struct cqhci_host *cq_host,
+				const u8 *imp_key, size_t imp_key_size,
+				u8 lt_key[BLK_CRYPTO_MAX_HW_WRAPPED_KEY_SIZE])
+{
+	struct sdhci_host *host = mmc_priv(cq_host->mmc);
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+
+	return qcom_ice_import_key(msm_host->ice, imp_key, imp_key_size, lt_key);
+}
 #else /* CONFIG_MMC_CRYPTO */
 
 static inline int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host,
@@ -1989,6 +2093,10 @@
 	.disable	= sdhci_msm_cqe_disable,
 #ifdef CONFIG_MMC_CRYPTO
 	.program_key	= sdhci_msm_program_key,
+	.derive_sw_secret	= sdhci_msm_ice_derive_sw_secret,
+	.generate_key	= sdhci_msm_generate_key,
+	.prepare_key	= sdhci_msm_prepare_key,
+	.import_key	= sdhci_msm_import_key,
 #endif
 };
 
@@ -2626,6 +2734,7 @@
 		goto clk_disable;
 	}
 
+	msm_host->mmc->caps |= MMC_CAP_AGGRESSIVE_PM;
 	msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY;
 
 	/* Set the timeout value to max possible */
@@ -2694,6 +2803,11 @@
 	struct sdhci_host *host = dev_get_drvdata(dev);
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	host->runtime_suspended = true;
+	spin_unlock_irqrestore(&host->lock, flags);
 
 	/* Drop the performance vote */
 	dev_pm_opp_set_rate(dev, 0);
@@ -2708,6 +2822,7 @@
 	struct sdhci_host *host = dev_get_drvdata(dev);
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
+	unsigned long flags;
 	int ret;
 
 	ret = clk_bulk_prepare_enable(ARRAY_SIZE(msm_host->bulk_clks),
@@ -2726,7 +2841,15 @@
 
 	dev_pm_opp_set_rate(dev, msm_host->clk_rate);
 
-	return sdhci_msm_ice_resume(msm_host);
+	ret = sdhci_msm_ice_resume(msm_host);
+	if (ret)
+		return ret;
+
+	spin_lock_irqsave(&host->lock, flags);
+	host->runtime_suspended = false;
+	spin_unlock_irqrestore(&host->lock, flags);
+
+	return ret;
 }
 
 static const struct dev_pm_ops sdhci_msm_pm_ops = {
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci-of-aspeed.c
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci-of-aspeed.c
@@ -510,6 +510,7 @@
 	{ .compatible = "aspeed,ast2600-sdhci", .data = &ast2600_sdhci_pdata, },
 	{ }
 };
+MODULE_DEVICE_TABLE(of, aspeed_sdhci_of_match);
 
 static struct platform_driver aspeed_sdhci_driver = {
 	.driver		= {
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci-of-dwcmshc.c
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci-of-dwcmshc.c
@@ -612,6 +612,7 @@
 
 	/* perform tuning */
 	sdhci_start_tuning(host);
+	host->tuning_loop_count = 128;
 	host->tuning_err = __sdhci_execute_tuning(host, opcode);
 	if (host->tuning_err) {
 		/* disable auto-tuning upon tuning error */
@@ -633,6 +634,14 @@
 
 	sdhci_reset(host, mask);
 
+	/* The T-Head 1520 SoC does not comply with the SDHCI specification
+	 * regarding the "Software Reset for CMD line should clear 'Command
+	 * Complete' in the Normal Interrupt Status Register." Clear the bit
+	 * here to compensate for this quirk.
+	 */
+	if (mask & SDHCI_RESET_CMD)
+		sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS);
+
 	if (priv->flags & FLAG_IO_FIXED_1V8) {
 		ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
 		if (!(ctrl_2 & SDHCI_CTRL_VDD_180)) {
@@ -933,6 +942,17 @@
 	return err;
 }
 
+static void dwcmshc_disable_card_clk(struct sdhci_host *host)
+{
+	u16 ctrl;
+
+	ctrl = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+	if (ctrl & SDHCI_CLOCK_CARD_EN) {
+		ctrl &= ~SDHCI_CLOCK_CARD_EN;
+		sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL);
+	}
+}
+
 static void dwcmshc_remove(struct platform_device *pdev)
 {
 	struct sdhci_host *host = platform_get_drvdata(pdev);
@@ -940,8 +960,14 @@
 	struct dwcmshc_priv *priv = sdhci_pltfm_priv(pltfm_host);
 	struct rk35xx_priv *rk_priv = priv->priv;
 
+	pm_runtime_get_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_put_noidle(&pdev->dev);
+
 	sdhci_remove_host(host, 0);
 
+	dwcmshc_disable_card_clk(host);
+
 	clk_disable_unprepare(pltfm_host->clk);
 	clk_disable_unprepare(priv->bus_clk);
 	if (rk_priv)
@@ -1032,17 +1058,6 @@
 		sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL);
 	}
 }
-
-static void dwcmshc_disable_card_clk(struct sdhci_host *host)
-{
-	u16 ctrl;
-
-	ctrl = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
-	if (ctrl & SDHCI_CLOCK_CARD_EN) {
-		ctrl &= ~SDHCI_CLOCK_CARD_EN;
-		sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL);
-	}
-}
 
 static int dwcmshc_runtime_suspend(struct device *dev)
 {
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci-omap.c
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci-omap.c
@@ -1439,6 +1439,9 @@
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
 
+	if (host->tuning_mode != SDHCI_TUNING_MODE_3)
+		mmc_retune_needed(host->mmc);
+
 	if (omap_host->con != -EINVAL)
 		sdhci_runtime_suspend_host(host);
 
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci-pci-core.c
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci-pci-core.c
@@ -21,6 +21,7 @@
 #include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/gpio.h>
+#include <linux/gpio/machine.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_qos.h>
 #include <linux/debugfs.h>
@@ -1235,6 +1236,29 @@
 	.priv_size	= sizeof(struct intel_host),
 };
 
+/* DMI quirks for devices with missing or broken CD GPIO info */
+static const struct gpiod_lookup_table vexia_edu_atla10_cd_gpios = {
+	.dev_id = "0000:00:12.0",
+	.table = {
+		GPIO_LOOKUP("INT33FC:00", 38, "cd", GPIO_ACTIVE_HIGH),
+		{ }
+	},
+};
+
+static const struct dmi_system_id sdhci_intel_byt_cd_gpio_override[] = {
+	{
+		/* Vexia Edu Atla 10 tablet 9V version */
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+			DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
+			/* Above strings are too generic, also match on BIOS date */
+			DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"),
+		},
+		.driver_data = (void *)&vexia_edu_atla10_cd_gpios,
+	},
+	{ }
+};
+
 static const struct sdhci_pci_fixes sdhci_intel_byt_sd = {
 #ifdef CONFIG_PM_SLEEP
 	.resume		= byt_resume,
@@ -1253,6 +1277,7 @@
 	.add_host	= byt_add_host,
 	.remove_slot	= byt_remove_slot,
 	.ops		= &sdhci_intel_byt_ops,
+	.cd_gpio_override = sdhci_intel_byt_cd_gpio_override,
 	.priv_size	= sizeof(struct intel_host),
 };
 
@@ -1326,7 +1351,7 @@
 
 	ret = pci_read_config_byte(chip->pdev, 0xAE, &scratch);
 	if (ret)
-		return ret;
+		goto fail;
 
 	/*
 	 * Turn PMOS on [bit 0], set over current detection to 2.4 V
@@ -1337,7 +1362,10 @@
 	else
 		scratch &= ~0x47;
 
-	return pci_write_config_byte(chip->pdev, 0xAE, scratch);
+	ret = pci_write_config_byte(chip->pdev, 0xAE, scratch);
+
+fail:
+	return pcibios_err_to_errno(ret);
 }
 
 static int jmicron_probe(struct sdhci_pci_chip *chip)
@@ -2034,6 +2062,42 @@
  *                                                                           *
 \*****************************************************************************/
 
+static struct gpiod_lookup_table *sdhci_pci_add_gpio_lookup_table(
+	struct sdhci_pci_chip *chip)
+{
+	struct gpiod_lookup_table *cd_gpio_lookup_table;
+	const struct dmi_system_id *dmi_id = NULL;
+	size_t count;
+
+	if (chip->fixes && chip->fixes->cd_gpio_override)
+		dmi_id = dmi_first_match(chip->fixes->cd_gpio_override);
+
+	if (!dmi_id)
+		return NULL;
+
+	cd_gpio_lookup_table = dmi_id->driver_data;
+	for (count = 0; cd_gpio_lookup_table->table[count].key; count++)
+		;
+
+	cd_gpio_lookup_table = kmemdup(dmi_id->driver_data,
+				       /* count + 1 terminating entry */
+				       struct_size(cd_gpio_lookup_table, table, count + 1),
+				       GFP_KERNEL);
+	if (!cd_gpio_lookup_table)
+		return ERR_PTR(-ENOMEM);
+
+	gpiod_add_lookup_table(cd_gpio_lookup_table);
+	return cd_gpio_lookup_table;
+}
+
+static void sdhci_pci_remove_gpio_lookup_table(struct gpiod_lookup_table *lookup_table)
+{
+	if (lookup_table) {
+		gpiod_remove_lookup_table(lookup_table);
+		kfree(lookup_table);
+	}
+}
+
 static struct sdhci_pci_slot *sdhci_pci_probe_slot(
 	struct pci_dev *pdev, struct sdhci_pci_chip *chip, int first_bar,
 	int slotno)
@@ -2109,8 +2173,19 @@
 		device_init_wakeup(&pdev->dev, true);
 
 	if (slot->cd_idx >= 0) {
+		struct gpiod_lookup_table *cd_gpio_lookup_table;
+
+		cd_gpio_lookup_table = sdhci_pci_add_gpio_lookup_table(chip);
+		if (IS_ERR(cd_gpio_lookup_table)) {
+			ret = PTR_ERR(cd_gpio_lookup_table);
+			goto remove;
+		}
+
 		ret = mmc_gpiod_request_cd(host->mmc, "cd", slot->cd_idx,
 					   slot->cd_override_level, 0);
+
+		sdhci_pci_remove_gpio_lookup_table(cd_gpio_lookup_table);
+
 		if (ret && ret != -EPROBE_DEFER)
 			ret = mmc_gpiod_request_cd(host->mmc, NULL,
 						   slot->cd_idx,
@@ -2202,7 +2277,7 @@
 
 	ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots);
 	if (ret)
-		return ret;
+		return pcibios_err_to_errno(ret);
 
 	slots = PCI_SLOT_INFO_SLOTS(slots) + 1;
 	dev_dbg(&pdev->dev, "found %d slot(s)\n", slots);
@@ -2211,7 +2286,7 @@
 
 	ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &first_bar);
 	if (ret)
-		return ret;
+		return pcibios_err_to_errno(ret);
 
 	first_bar &= PCI_SLOT_INFO_FIRST_BAR_MASK;
 
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci-pci-gli.c
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci-pci-gli.c
@@ -902,28 +902,40 @@
 	gl9767_vhs_read(pdev);
 }
 
+static void gl9767_set_low_power_negotiation(struct pci_dev *pdev, bool enable)
+{
+	u32 value;
+
+	gl9767_vhs_write(pdev);
+
+	pci_read_config_dword(pdev, PCIE_GLI_9767_CFG, &value);
+	if (enable)
+		value &= ~PCIE_GLI_9767_CFG_LOW_PWR_OFF;
+	else
+		value |= PCIE_GLI_9767_CFG_LOW_PWR_OFF;
+	pci_write_config_dword(pdev, PCIE_GLI_9767_CFG, value);
+
+	gl9767_vhs_read(pdev);
+}
+
 static void sdhci_gl9767_set_clock(struct sdhci_host *host, unsigned int clock)
 {
 	struct sdhci_pci_slot *slot = sdhci_priv(host);
 	struct mmc_ios *ios = &host->mmc->ios;
 	struct pci_dev *pdev;
-	u32 value;
 	u16 clk;
 
 	pdev = slot->chip->pdev;
 	host->mmc->actual_clock = 0;
 
-	gl9767_vhs_write(pdev);
-
-	pci_read_config_dword(pdev, PCIE_GLI_9767_CFG, &value);
-	value |= PCIE_GLI_9767_CFG_LOW_PWR_OFF;
-	pci_write_config_dword(pdev, PCIE_GLI_9767_CFG, value);
-
+	gl9767_set_low_power_negotiation(pdev, false);
 	gl9767_disable_ssc_pll(pdev);
 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
-	if (clock == 0)
+	if (clock == 0) {
+		gl9767_set_low_power_negotiation(pdev, true);
 		return;
+	}
 
 	clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock);
 	if (clock == 200000000 && ios->timing == MMC_TIMING_UHS_SDR104) {
@@ -932,12 +944,7 @@
 	}
 
 	sdhci_enable_clk(host, clk);
-
-	pci_read_config_dword(pdev, PCIE_GLI_9767_CFG, &value);
-	value &= ~PCIE_GLI_9767_CFG_LOW_PWR_OFF;
-	pci_write_config_dword(pdev, PCIE_GLI_9767_CFG, value);
-
-	gl9767_vhs_read(pdev);
+	gl9767_set_low_power_negotiation(pdev, true);
 }
 
 static void gli_set_9767(struct sdhci_host *host)
@@ -1071,6 +1078,9 @@
 		sdhci_writew(host, value, SDHCI_CLOCK_CONTROL);
 	}
 
+	pci_read_config_dword(pdev, PCIE_GLI_9767_CFG, &value);
+	value &= ~PCIE_GLI_9767_CFG_LOW_PWR_OFF;
+	pci_write_config_dword(pdev, PCIE_GLI_9767_CFG, value);
 	gl9767_vhs_read(pdev);
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci-pci-o2micro.c
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci-pci-o2micro.c
@@ -823,7 +823,7 @@
 		ret = pci_read_config_byte(chip->pdev,
 				O2_SD_LOCK_WP, &scratch);
 		if (ret)
-			return ret;
+			goto read_fail;
 		scratch &= 0x7f;
 		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 
@@ -834,7 +834,7 @@
 		ret = pci_read_config_byte(chip->pdev,
 				O2_SD_CLKREQ, &scratch);
 		if (ret)
-			return ret;
+			goto read_fail;
 		scratch |= 0x20;
 		pci_write_config_byte(chip->pdev, O2_SD_CLKREQ, scratch);
 
@@ -843,7 +843,7 @@
 		 */
 		ret = pci_read_config_byte(chip->pdev, O2_SD_CAPS, &scratch);
 		if (ret)
-			return ret;
+			goto read_fail;
 		scratch |= 0x01;
 		pci_write_config_byte(chip->pdev, O2_SD_CAPS, scratch);
 		pci_write_config_byte(chip->pdev, O2_SD_CAPS, 0x73);
@@ -856,7 +856,7 @@
 		ret = pci_read_config_byte(chip->pdev,
 				O2_SD_INF_MOD, &scratch);
 		if (ret)
-			return ret;
+			goto read_fail;
 		scratch |= 0x08;
 		pci_write_config_byte(chip->pdev, O2_SD_INF_MOD, scratch);
 
@@ -864,7 +864,7 @@
 		ret = pci_read_config_byte(chip->pdev,
 				O2_SD_LOCK_WP, &scratch);
 		if (ret)
-			return ret;
+			goto read_fail;
 		scratch |= 0x80;
 		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 		break;
@@ -875,7 +875,7 @@
 		ret = pci_read_config_byte(chip->pdev,
 				O2_SD_LOCK_WP, &scratch);
 		if (ret)
-			return ret;
+			goto read_fail;
 
 		scratch &= 0x7f;
 		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
@@ -886,7 +886,7 @@
 						    O2_SD_FUNC_REG0,
 						    &scratch_32);
 			if (ret)
-				return ret;
+				goto read_fail;
 			scratch_32 = ((scratch_32 & 0xFF000000) >> 24);
 
 			/* Check Whether subId is 0x11 or 0x12 */
@@ -898,7 +898,7 @@
 							    O2_SD_FUNC_REG4,
 							    &scratch_32);
 				if (ret)
-					return ret;
+					goto read_fail;
 
 				/* Enable Base Clk setting change */
 				scratch_32 |= O2_SD_FREG4_ENABLE_CLK_SET;
@@ -921,7 +921,7 @@
 		ret = pci_read_config_dword(chip->pdev,
 					    O2_SD_CLK_SETTING, &scratch_32);
 		if (ret)
-			return ret;
+			goto read_fail;
 
 		scratch_32 &= ~(0xFF00);
 		scratch_32 |= 0x07E0C800;
@@ -931,14 +931,14 @@
 		ret = pci_read_config_dword(chip->pdev,
 					    O2_SD_CLKREQ, &scratch_32);
 		if (ret)
-			return ret;
+			goto read_fail;
 		scratch_32 |= 0x3;
 		pci_write_config_dword(chip->pdev, O2_SD_CLKREQ, scratch_32);
 
 		ret = pci_read_config_dword(chip->pdev,
 					    O2_SD_PLL_SETTING, &scratch_32);
 		if (ret)
-			return ret;
+			goto read_fail;
 
 		scratch_32 &= ~(0x1F3F070E);
 		scratch_32 |= 0x18270106;
@@ -949,7 +949,7 @@
 		ret = pci_read_config_dword(chip->pdev,
 					    O2_SD_CAP_REG2, &scratch_32);
 		if (ret)
-			return ret;
+			goto read_fail;
 		scratch_32 &= ~(0xE0);
 		pci_write_config_dword(chip->pdev,
 				       O2_SD_CAP_REG2, scratch_32);
@@ -961,7 +961,7 @@
 		ret = pci_read_config_byte(chip->pdev,
 					   O2_SD_LOCK_WP, &scratch);
 		if (ret)
-			return ret;
+			goto read_fail;
 		scratch |= 0x80;
 		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 		break;
@@ -971,7 +971,7 @@
 		ret = pci_read_config_byte(chip->pdev,
 				O2_SD_LOCK_WP, &scratch);
 		if (ret)
-			return ret;
+			goto read_fail;
 
 		scratch &= 0x7f;
 		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
@@ -979,7 +979,7 @@
 		ret = pci_read_config_dword(chip->pdev,
 					    O2_SD_PLL_SETTING, &scratch_32);
 		if (ret)
-			return ret;
+			goto read_fail;
 
 		if ((scratch_32 & 0xff000000) == 0x01000000) {
 			scratch_32 &= 0x0000FFFF;
@@ -998,7 +998,7 @@
 						    O2_SD_FUNC_REG4,
 						    &scratch_32);
 			if (ret)
-				return ret;
+				goto read_fail;
 			scratch_32 |= (1 << 22);
 			pci_write_config_dword(chip->pdev,
 					       O2_SD_FUNC_REG4, scratch_32);
@@ -1017,7 +1017,7 @@
 		ret = pci_read_config_byte(chip->pdev,
 					   O2_SD_LOCK_WP, &scratch);
 		if (ret)
-			return ret;
+			goto read_fail;
 		scratch |= 0x80;
 		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 		break;
@@ -1028,7 +1028,7 @@
 		/* UnLock WP */
 		ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
 		if (ret)
-			return ret;
+			goto read_fail;
 		scratch &= 0x7f;
 		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 
@@ -1057,13 +1057,16 @@
 		/* Lock WP */
 		ret = pci_read_config_byte(chip->pdev, O2_SD_LOCK_WP, &scratch);
 		if (ret)
-			return ret;
+			goto read_fail;
 		scratch |= 0x80;
 		pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
 		break;
 	}
 
 	return 0;
+
+read_fail:
+	return pcibios_err_to_errno(ret);
 }
 
 #ifdef CONFIG_PM_SLEEP
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci-pci.h
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci-pci.h
@@ -156,6 +156,7 @@
 #endif
 
 	const struct sdhci_ops	*ops;
+	const struct dmi_system_id *cd_gpio_override;
 	size_t			priv_size;
 };
 
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci-tegra.c
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci-tegra.c
@@ -1525,7 +1525,6 @@
 	.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
 		  SDHCI_QUIRK_SINGLE_POWER_WRITE |
 		  SDHCI_QUIRK_NO_HISPD_BIT |
-		  SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC |
 		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN,
 	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN |
 		   SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER,
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci.c
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci.c
@@ -2515,26 +2515,29 @@
 
 static int sdhci_check_ro(struct sdhci_host *host)
 {
-	unsigned long flags;
+	bool allow_invert = false;
 	int is_readonly;
 
-	spin_lock_irqsave(&host->lock, flags);
-
-	if (host->flags & SDHCI_DEVICE_DEAD)
+	if (host->flags & SDHCI_DEVICE_DEAD) {
 		is_readonly = 0;
-	else if (host->ops->get_ro)
+	} else if (host->ops->get_ro) {
 		is_readonly = host->ops->get_ro(host);
-	else if (mmc_can_gpio_ro(host->mmc))
+	} else if (mmc_can_gpio_ro(host->mmc)) {
 		is_readonly = mmc_gpio_get_ro(host->mmc);
-	else
+		/* Do not invert twice */
+		allow_invert = !(host->mmc->caps2 & MMC_CAP2_RO_ACTIVE_HIGH);
+	} else {
 		is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
 				& SDHCI_WRITE_PROTECT);
+		allow_invert = true;
+	}
 
-	spin_unlock_irqrestore(&host->lock, flags);
+	if (is_readonly >= 0 &&
+	    allow_invert &&
+	    (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT))
+		is_readonly = !is_readonly;
 
-	/* This quirk needs to be replaced by a callback-function later */
-	return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ?
-		!is_readonly : is_readonly;
+	return is_readonly;
 }
 
 #define SAMPLE_COUNT	5
@@ -3439,12 +3442,18 @@
 		host->data->error = -EILSEQ;
 		if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))))
 			sdhci_err_stats_inc(host, DAT_CRC);
-	} else if ((intmask & SDHCI_INT_DATA_CRC) &&
+	} else if ((intmask & (SDHCI_INT_DATA_CRC | SDHCI_INT_TUNING_ERROR)) &&
 		SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))
 			!= MMC_BUS_TEST_R) {
 		host->data->error = -EILSEQ;
 		if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))))
 			sdhci_err_stats_inc(host, DAT_CRC);
+		if (intmask & SDHCI_INT_TUNING_ERROR) {
+			u16 ctrl2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+
+			ctrl2 &= ~SDHCI_CTRL_TUNED_CLK;
+			sdhci_writew(host, ctrl2, SDHCI_HOST_CONTROL2);
+		}
 	} else if (intmask & SDHCI_INT_ADMA_ERROR) {
 		pr_err("%s: ADMA error: 0x%08x\n", mmc_hostname(host->mmc),
 		       intmask);
@@ -3979,7 +3988,7 @@
 	} else
 		*cmd_error = 0;
 
-	if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC)) {
+	if (intmask & (SDHCI_INT_DATA_END_BIT | SDHCI_INT_DATA_CRC | SDHCI_INT_TUNING_ERROR)) {
 		*data_error = -EILSEQ;
 		if (!mmc_op_tuning(SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND))))
 			sdhci_err_stats_inc(host, DAT_CRC);
@@ -4718,6 +4727,21 @@
 		if (host->quirks & SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC) {
 			host->max_adma = 65532; /* 32-bit alignment */
 			mmc->max_seg_size = 65535;
+			/*
+			 * sdhci_adma_table_pre() expects to define 1 DMA
+			 * descriptor per segment, so the maximum segment size
+			 * is set accordingly. SDHCI allows up to 64KiB per DMA
+			 * descriptor (16-bit field), but some controllers do
+			 * not support "zero means 65536" reducing the maximum
+			 * for them to 65535. That is a problem if PAGE_SIZE is
+			 * 64KiB because the block layer does not support
+			 * max_seg_size < PAGE_SIZE, however
+			 * sdhci_adma_table_pre() has a workaround to handle
+			 * that case, and split the descriptor. Refer also
+			 * comment in sdhci_adma_table_pre().
+			 */
+			if (mmc->max_seg_size < PAGE_SIZE)
+				mmc->max_seg_size = PAGE_SIZE;
 		} else {
 			mmc->max_seg_size = 65536;
 		}
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci.h
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci.h
@@ -158,6 +158,7 @@
 #define  SDHCI_INT_BUS_POWER	0x00800000
 #define  SDHCI_INT_AUTO_CMD_ERR	0x01000000
 #define  SDHCI_INT_ADMA_ERROR	0x02000000
+#define  SDHCI_INT_TUNING_ERROR	0x04000000
 
 #define  SDHCI_INT_NORMAL_MASK	0x00007FFF
 #define  SDHCI_INT_ERROR_MASK	0xFFFF8000
@@ -169,7 +170,7 @@
 		SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
 		SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
 		SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR | \
-		SDHCI_INT_BLK_GAP)
+		SDHCI_INT_BLK_GAP | SDHCI_INT_TUNING_ERROR)
 #define SDHCI_INT_ALL_MASK	((unsigned int)-1)
 
 #define SDHCI_CQE_INT_ERR_MASK ( \
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sdhci_am654.c
+++ linux-qcom-6.8.0/drivers/mmc/host/sdhci_am654.c
@@ -143,16 +143,24 @@
 	struct regmap *base;
 	int otap_del_sel[ARRAY_SIZE(td)];
 	int itap_del_sel[ARRAY_SIZE(td)];
+	u32 itap_del_ena[ARRAY_SIZE(td)];
 	int clkbuf_sel;
 	int trm_icp;
 	int drv_strength;
 	int strb_sel;
 	u32 flags;
 	u32 quirks;
+	bool dll_enable;
 
 #define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0)
 };
 
+struct window {
+	u8 start;
+	u8 end;
+	u8 length;
+};
+
 struct sdhci_am654_driver_data {
 	const struct sdhci_pltfm_data *pdata;
 	u32 flags;
@@ -232,11 +240,13 @@
 }
 
 static void sdhci_am654_write_itapdly(struct sdhci_am654_data *sdhci_am654,
-				      u32 itapdly)
+				      u32 itapdly, u32 enable)
 {
 	/* Set ITAPCHGWIN before writing to ITAPDLY */
 	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, ITAPCHGWIN_MASK,
 			   1 << ITAPCHGWIN_SHIFT);
+	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, ITAPDLYENA_MASK,
+			   enable << ITAPDLYENA_SHIFT);
 	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, ITAPDLYSEL_MASK,
 			   itapdly << ITAPDLYSEL_SHIFT);
 	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, ITAPCHGWIN_MASK, 0);
@@ -253,8 +263,8 @@
 	mask = SELDLYTXCLK_MASK | SELDLYRXCLK_MASK;
 	regmap_update_bits(sdhci_am654->base, PHY_CTRL5, mask, val);
 
-	sdhci_am654_write_itapdly(sdhci_am654,
-				  sdhci_am654->itap_del_sel[timing]);
+	sdhci_am654_write_itapdly(sdhci_am654, sdhci_am654->itap_del_sel[timing],
+				  sdhci_am654->itap_del_ena[timing]);
 }
 
 static void sdhci_am654_set_clock(struct sdhci_host *host, unsigned int clock)
@@ -263,7 +273,6 @@
 	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
 	unsigned char timing = host->mmc->ios.timing;
 	u32 otap_del_sel;
-	u32 otap_del_ena;
 	u32 mask, val;
 
 	regmap_update_bits(sdhci_am654->base, PHY_CTRL1, ENDLL_MASK, 0);
@@ -272,10 +281,9 @@
 
 	/* Setup DLL Output TAP delay */
 	otap_del_sel = sdhci_am654->otap_del_sel[timing];
-	otap_del_ena = (timing > MMC_TIMING_UHS_SDR25) ? 1 : 0;
 
 	mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
-	val = (otap_del_ena << OTAPDLYENA_SHIFT) |
+	val = (0x1 << OTAPDLYENA_SHIFT) |
 	      (otap_del_sel << OTAPDLYSEL_SHIFT);
 
 	/* Write to STRBSEL for HS400 speed mode */
@@ -290,10 +298,21 @@
 
 	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, val);
 
-	if (timing > MMC_TIMING_UHS_SDR25 && clock >= CLOCK_TOO_SLOW_HZ)
+	if (timing > MMC_TIMING_UHS_SDR25 && clock >= CLOCK_TOO_SLOW_HZ) {
 		sdhci_am654_setup_dll(host, clock);
-	else
+		sdhci_am654->dll_enable = true;
+
+		if (timing == MMC_TIMING_MMC_HS400) {
+			sdhci_am654->itap_del_ena[timing] = 0x1;
+			sdhci_am654->itap_del_sel[timing] = sdhci_am654->itap_del_sel[timing - 1];
+		}
+
+		sdhci_am654_write_itapdly(sdhci_am654, sdhci_am654->itap_del_sel[timing],
+					  sdhci_am654->itap_del_ena[timing]);
+	} else {
 		sdhci_am654_setup_delay_chain(sdhci_am654, timing);
+		sdhci_am654->dll_enable = false;
+	}
 
 	regmap_update_bits(sdhci_am654->base, PHY_CTRL5, CLKBUFSEL_MASK,
 			   sdhci_am654->clkbuf_sel);
@@ -306,6 +325,8 @@
 	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
 	unsigned char timing = host->mmc->ios.timing;
 	u32 otap_del_sel;
+	u32 itap_del_ena;
+	u32 itap_del_sel;
 	u32 mask, val;
 
 	/* Setup DLL Output TAP delay */
@@ -314,8 +335,19 @@
 	mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
 	val = (0x1 << OTAPDLYENA_SHIFT) |
 	      (otap_del_sel << OTAPDLYSEL_SHIFT);
-	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, val);
 
+	/* Setup Input TAP delay */
+	itap_del_ena = sdhci_am654->itap_del_ena[timing];
+	itap_del_sel = sdhci_am654->itap_del_sel[timing];
+
+	mask |= ITAPDLYENA_MASK | ITAPDLYSEL_MASK;
+	val |= (itap_del_ena << ITAPDLYENA_SHIFT) |
+	       (itap_del_sel << ITAPDLYSEL_SHIFT);
+
+	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, ITAPCHGWIN_MASK,
+			   1 << ITAPCHGWIN_SHIFT);
+	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, mask, val);
+	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, ITAPCHGWIN_MASK, 0);
 	regmap_update_bits(sdhci_am654->base, PHY_CTRL5, CLKBUFSEL_MASK,
 			   sdhci_am654->clkbuf_sel);
 
@@ -408,40 +440,105 @@
 	return 0;
 }
 
-#define ITAP_MAX	32
+#define ITAPDLY_LENGTH 32
+#define ITAPDLY_LAST_INDEX (ITAPDLY_LENGTH - 1)
+
+static u32 sdhci_am654_calculate_itap(struct sdhci_host *host, struct window
+			  *fail_window, u8 num_fails, bool circular_buffer)
+{
+	u8 itap = 0, start_fail = 0, end_fail = 0, pass_length = 0;
+	u8 first_fail_start = 0, last_fail_end = 0;
+	struct device *dev = mmc_dev(host->mmc);
+	struct window pass_window = {0, 0, 0};
+	int prev_fail_end = -1;
+	u8 i;
+
+	if (!num_fails)
+		return ITAPDLY_LAST_INDEX >> 1;
+
+	if (fail_window->length == ITAPDLY_LENGTH) {
+		dev_err(dev, "No passing ITAPDLY, return 0\n");
+		return 0;
+	}
+
+	first_fail_start = fail_window->start;
+	last_fail_end = fail_window[num_fails - 1].end;
+
+	for (i = 0; i < num_fails; i++) {
+		start_fail = fail_window[i].start;
+		end_fail = fail_window[i].end;
+		pass_length = start_fail - (prev_fail_end + 1);
+
+		if (pass_length > pass_window.length) {
+			pass_window.start = prev_fail_end + 1;
+			pass_window.length = pass_length;
+		}
+		prev_fail_end = end_fail;
+	}
+
+	if (!circular_buffer)
+		pass_length = ITAPDLY_LAST_INDEX - last_fail_end;
+	else
+		pass_length = ITAPDLY_LAST_INDEX - last_fail_end + first_fail_start;
+
+	if (pass_length > pass_window.length) {
+		pass_window.start = last_fail_end + 1;
+		pass_window.length = pass_length;
+	}
+
+	if (!circular_buffer)
+		itap = pass_window.start + (pass_window.length >> 1);
+	else
+		itap = (pass_window.start + (pass_window.length >> 1)) % ITAPDLY_LENGTH;
+
+	return (itap > ITAPDLY_LAST_INDEX) ? ITAPDLY_LAST_INDEX >> 1 : itap;
+}
+
 static int sdhci_am654_platform_execute_tuning(struct sdhci_host *host,
 					       u32 opcode)
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
-	int cur_val, prev_val = 1, fail_len = 0, pass_window = 0, pass_len;
-	u32 itap;
+	unsigned char timing = host->mmc->ios.timing;
+	struct window fail_window[ITAPDLY_LENGTH];
+	u8 curr_pass, itap;
+	u8 fail_index = 0;
+	u8 prev_pass = 1;
+
+	memset(fail_window, 0, sizeof(fail_window));
 
 	/* Enable ITAPDLY */
-	regmap_update_bits(sdhci_am654->base, PHY_CTRL4, ITAPDLYENA_MASK,
-			   1 << ITAPDLYENA_SHIFT);
+	sdhci_am654->itap_del_ena[timing] = 0x1;
+
+	for (itap = 0; itap < ITAPDLY_LENGTH; itap++) {
+		sdhci_am654_write_itapdly(sdhci_am654, itap, sdhci_am654->itap_del_ena[timing]);
+
+		curr_pass = !mmc_send_tuning(host->mmc, opcode, NULL);
 
-	for (itap = 0; itap < ITAP_MAX; itap++) {
-		sdhci_am654_write_itapdly(sdhci_am654, itap);
+		if (!curr_pass && prev_pass)
+			fail_window[fail_index].start = itap;
 
-		cur_val = !mmc_send_tuning(host->mmc, opcode, NULL);
-		if (cur_val && !prev_val)
-			pass_window = itap;
+		if (!curr_pass) {
+			fail_window[fail_index].end = itap;
+			fail_window[fail_index].length++;
+		}
 
-		if (!cur_val)
-			fail_len++;
+		if (curr_pass && !prev_pass)
+			fail_index++;
 
-		prev_val = cur_val;
+		prev_pass = curr_pass;
 	}
-	/*
-	 * Having determined the length of the failing window and start of
-	 * the passing window calculate the length of the passing window and
-	 * set the final value halfway through it considering the range as a
-	 * circular buffer
-	 */
-	pass_len = ITAP_MAX - fail_len;
-	itap = (pass_window + (pass_len >> 1)) % ITAP_MAX;
-	sdhci_am654_write_itapdly(sdhci_am654, itap);
+
+	if (fail_window[fail_index].length != 0)
+		fail_index++;
+
+	itap = sdhci_am654_calculate_itap(host, fail_window, fail_index,
+					  sdhci_am654->dll_enable);
+
+	sdhci_am654_write_itapdly(sdhci_am654, itap, sdhci_am654->itap_del_ena[timing]);
+
+	/* Save ITAPDLY */
+	sdhci_am654->itap_del_sel[timing] = itap;
 
 	return 0;
 }
@@ -590,9 +687,12 @@
 				host->mmc->caps2 &= ~td[i].capability;
 		}
 
-		if (td[i].itap_binding)
-			device_property_read_u32(dev, td[i].itap_binding,
-						 &sdhci_am654->itap_del_sel[i]);
+		if (td[i].itap_binding) {
+			ret = device_property_read_u32(dev, td[i].itap_binding,
+						       &sdhci_am654->itap_del_sel[i]);
+			if (!ret)
+				sdhci_am654->itap_del_ena[i] = 0x1;
+		}
 	}
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/mmc/host/sunxi-mmc.c
+++ linux-qcom-6.8.0/drivers/mmc/host/sunxi-mmc.c
@@ -1191,10 +1191,9 @@
 	.needs_new_timings = true,
 };
 
-static const struct sunxi_mmc_cfg sun50i_a100_cfg = {
+static const struct sunxi_mmc_cfg sun50i_h616_cfg = {
 	.idma_des_size_bits = 16,
 	.idma_des_shift = 2,
-	.clk_delays = NULL,
 	.can_calibrate = true,
 	.mask_data0 = true,
 	.needs_new_timings = true,
@@ -1217,8 +1216,9 @@
 	{ .compatible = "allwinner,sun20i-d1-mmc", .data = &sun20i_d1_cfg },
 	{ .compatible = "allwinner,sun50i-a64-mmc", .data = &sun50i_a64_cfg },
 	{ .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg },
-	{ .compatible = "allwinner,sun50i-a100-mmc", .data = &sun50i_a100_cfg },
+	{ .compatible = "allwinner,sun50i-a100-mmc", .data = &sun20i_d1_cfg },
 	{ .compatible = "allwinner,sun50i-a100-emmc", .data = &sun50i_a100_emmc_cfg },
+	{ .compatible = "allwinner,sun50i-h616-mmc", .data = &sun50i_h616_cfg },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match);
--- linux-qcom-6.8.0.orig/drivers/mmc/host/tmio_mmc_core.c
+++ linux-qcom-6.8.0/drivers/mmc/host/tmio_mmc_core.c
@@ -259,6 +259,8 @@
 	else
 		mrq->cmd->error = -ETIMEDOUT;
 
+	/* No new calls yet, but disallow concurrent tmio_mmc_done_work() */
+	host->mrq = ERR_PTR(-EBUSY);
 	host->cmd = NULL;
 	host->data = NULL;
 
--- linux-qcom-6.8.0.orig/drivers/mmc/host/wmt-sdmmc.c
+++ linux-qcom-6.8.0/drivers/mmc/host/wmt-sdmmc.c
@@ -883,7 +883,6 @@
 {
 	struct mmc_host *mmc;
 	struct wmt_mci_priv *priv;
-	struct resource *res;
 	u32 reg_tmp;
 
 	mmc = platform_get_drvdata(pdev);
@@ -911,9 +910,6 @@
 	clk_disable_unprepare(priv->clk_sdmmc);
 	clk_put(priv->clk_sdmmc);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	release_mem_region(res->start, resource_size(res));
-
 	mmc_free_host(mmc);
 
 	dev_info(&pdev->dev, "WMT MCI device removed\n");
--- linux-qcom-6.8.0.orig/drivers/mtd/devices/powernv_flash.c
+++ linux-qcom-6.8.0/drivers/mtd/devices/powernv_flash.c
@@ -207,6 +207,9 @@
 	 * get them
 	 */
 	mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node);
+	if (!mtd->name)
+		return -ENOMEM;
+
 	mtd->type = MTD_NORFLASH;
 	mtd->flags = MTD_WRITEABLE;
 	mtd->size = size;
--- linux-qcom-6.8.0.orig/drivers/mtd/devices/slram.c
+++ linux-qcom-6.8.0/drivers/mtd/devices/slram.c
@@ -296,10 +296,12 @@
 		T("slram: devname = %s\n", devname);
 		if ((!map) || (!(devstart = strsep(&map, ",")))) {
 			E("slram: No devicestart specified.\n");
+			break;
 		}
 		T("slram: devstart = %s\n", devstart);
 		if ((!map) || (!(devlength = strsep(&map, ",")))) {
 			E("slram: No devicelength / -end specified.\n");
+			break;
 		}
 		T("slram: devlength = %s\n", devlength);
 		if (parse_cmdline(devname, devstart, devlength) != 0) {
--- linux-qcom-6.8.0.orig/drivers/mtd/hyperbus/hbmc-am654.c
+++ linux-qcom-6.8.0/drivers/mtd/hyperbus/hbmc-am654.c
@@ -174,26 +174,30 @@
 	priv->hbdev.np = of_get_next_child(np, NULL);
 	ret = of_address_to_resource(priv->hbdev.np, 0, &res);
 	if (ret)
-		return ret;
+		goto put_node;
 
 	if (of_property_read_bool(dev->of_node, "mux-controls")) {
 		struct mux_control *control = devm_mux_control_get(dev, NULL);
 
-		if (IS_ERR(control))
-			return PTR_ERR(control);
+		if (IS_ERR(control)) {
+			ret = PTR_ERR(control);
+			goto put_node;
+		}
 
 		ret = mux_control_select(control, 1);
 		if (ret) {
 			dev_err(dev, "Failed to select HBMC mux\n");
-			return ret;
+			goto put_node;
 		}
 		priv->mux_ctrl = control;
 	}
 
 	priv->hbdev.map.size = resource_size(&res);
 	priv->hbdev.map.virt = devm_ioremap_resource(dev, &res);
-	if (IS_ERR(priv->hbdev.map.virt))
-		return PTR_ERR(priv->hbdev.map.virt);
+	if (IS_ERR(priv->hbdev.map.virt)) {
+		ret = PTR_ERR(priv->hbdev.map.virt);
+		goto disable_mux;
+	}
 
 	priv->ctlr.dev = dev;
 	priv->ctlr.ops = &am654_hbmc_ops;
@@ -226,6 +230,8 @@
 disable_mux:
 	if (priv->mux_ctrl)
 		mux_control_deselect(priv->mux_ctrl);
+put_node:
+	of_node_put(priv->hbdev.np);
 	return ret;
 }
 
@@ -241,6 +247,7 @@
 
 	if (dev_priv->rx_chan)
 		dma_release_channel(dev_priv->rx_chan);
+	of_node_put(priv->hbdev.np);
 }
 
 static const struct of_device_id am654_hbmc_dt_ids[] = {
--- linux-qcom-6.8.0.orig/drivers/mtd/hyperbus/rpc-if.c
+++ linux-qcom-6.8.0/drivers/mtd/hyperbus/rpc-if.c
@@ -163,9 +163,16 @@
 	pm_runtime_disable(hyperbus->rpc.dev);
 }
 
+static const struct platform_device_id rpc_if_hyperflash_id_table[] = {
+	{ .name = "rpc-if-hyperflash" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(platform, rpc_if_hyperflash_id_table);
+
 static struct platform_driver rpcif_platform_driver = {
 	.probe	= rpcif_hb_probe,
 	.remove_new = rpcif_hb_remove,
+	.id_table = rpc_if_hyperflash_id_table,
 	.driver	= {
 		.name	= "rpc-if-hyperflash",
 	},
--- linux-qcom-6.8.0.orig/drivers/mtd/maps/physmap-core.c
+++ linux-qcom-6.8.0/drivers/mtd/maps/physmap-core.c
@@ -518,7 +518,7 @@
 		if (!info->maps[i].phys)
 			info->maps[i].phys = res->start;
 
-		info->win_order = get_bitmask_order(resource_size(res)) - 1;
+		info->win_order = fls64(resource_size(res)) - 1;
 		info->maps[i].size = BIT(info->win_order +
 					 (info->gpios ?
 					  info->gpios->ndescs : 0));
--- linux-qcom-6.8.0.orig/drivers/mtd/maps/sun_uflash.c
+++ linux-qcom-6.8.0/drivers/mtd/maps/sun_uflash.c
@@ -47,7 +47,7 @@
 	.bankwidth =	UFLASH_BUSWIDTH,
 };
 
-int uflash_devinit(struct platform_device *op, struct device_node *dp)
+static int uflash_devinit(struct platform_device *op, struct device_node *dp)
 {
 	struct uflash_dev *up;
 
--- linux-qcom-6.8.0.orig/drivers/mtd/mtdcore.c
+++ linux-qcom-6.8.0/drivers/mtd/mtdcore.c
@@ -900,7 +900,7 @@
 	config.name = compatible;
 	config.id = NVMEM_DEVID_AUTO;
 	config.owner = THIS_MODULE;
-	config.add_legacy_fixed_of_cells = true;
+	config.add_legacy_fixed_of_cells = !mtd_type_is_nand(mtd);
 	config.type = NVMEM_TYPE_OTP;
 	config.root_only = true;
 	config.ignore_wp = true;
@@ -956,8 +956,10 @@
 
 	if (mtd->_get_user_prot_info && mtd->_read_user_prot_reg) {
 		size = mtd_otp_size(mtd, true);
-		if (size < 0)
-			return size;
+		if (size < 0) {
+			err = size;
+			goto err;
+		}
 
 		if (size > 0) {
 			nvmem = mtd_otp_nvmem_register(mtd, "user-otp", size,
@@ -1012,6 +1014,9 @@
 
 err:
 	nvmem_unregister(mtd->otp_user_nvmem);
+	/* Don't report error if OTP is not supported. */
+	if (err == -EOPNOTSUPP)
+		return 0;
 	return dev_err_probe(dev, err, "Failed to register OTP NVMEM device\n");
 }
 
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/onenand/onenand_base.c
+++ linux-qcom-6.8.0/drivers/mtd/nand/onenand/onenand_base.c
@@ -2923,6 +2923,7 @@
 	ret = ONENAND_IS_4KB_PAGE(this) ?
 		onenand_mlc_read_ops_nolock(mtd, from, &ops) :
 		onenand_read_ops_nolock(mtd, from, &ops);
+	*retlen = ops.retlen;
 
 	/* Exit OTP access mode */
 	this->command(mtd, ONENAND_CMD_RESET, 0, 0);
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/raw/Kconfig
+++ linux-qcom-6.8.0/drivers/mtd/nand/raw/Kconfig
@@ -234,8 +234,7 @@
 	tristate "Freescale IFC NAND controller"
 	depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A || COMPILE_TEST
 	depends on HAS_IOMEM
-	select FSL_IFC
-	select MEMORY
+	depends on FSL_IFC
 	help
 	  Various Freescale chips e.g P1010, include a NAND Flash machine
 	  with built-in hardware ECC capabilities.
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/raw/arasan-nand-controller.c
+++ linux-qcom-6.8.0/drivers/mtd/nand/raw/arasan-nand-controller.c
@@ -1410,8 +1410,8 @@
 	 * case, the "not" chosen CS is assigned to nfc->spare_cs and selected
 	 * whenever a GPIO CS must be asserted.
 	 */
-	if (nfc->cs_array && nfc->ncs > 2) {
-		if (!nfc->cs_array[0] && !nfc->cs_array[1]) {
+	if (nfc->cs_array) {
+		if (nfc->ncs > 2 && !nfc->cs_array[0] && !nfc->cs_array[1]) {
 			dev_err(nfc->dev,
 				"Assign a single native CS when using GPIOs\n");
 			return -EINVAL;
@@ -1479,8 +1479,15 @@
 
 static void anfc_remove(struct platform_device *pdev)
 {
+	int i;
 	struct arasan_nfc *nfc = platform_get_drvdata(pdev);
 
+	for (i = 0; i < nfc->ncs; i++) {
+		if (nfc->cs_array[i]) {
+			gpiod_put(nfc->cs_array[i]);
+		}
+	}
+
 	anfc_chips_cleanup(nfc);
 }
 
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/raw/atmel/pmecc.c
+++ linux-qcom-6.8.0/drivers/mtd/nand/raw/atmel/pmecc.c
@@ -362,7 +362,7 @@
 	size = ALIGN(size, sizeof(s32));
 	size += (req->ecc.strength + 1) * sizeof(s32) * 3;
 
-	user = kzalloc(size, GFP_KERNEL);
+	user = devm_kzalloc(pmecc->dev, size, GFP_KERNEL);
 	if (!user)
 		return ERR_PTR(-ENOMEM);
 
@@ -380,10 +380,8 @@
 	user->delta = user->dmu + req->ecc.strength + 1;
 
 	gf_tables = atmel_pmecc_get_gf_tables(req);
-	if (IS_ERR(gf_tables)) {
-		kfree(user);
+	if (IS_ERR(gf_tables))
 		return ERR_CAST(gf_tables);
-	}
 
 	user->gf_tables = gf_tables;
 
@@ -408,12 +406,6 @@
 }
 EXPORT_SYMBOL_GPL(atmel_pmecc_create_user);
 
-void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user)
-{
-	kfree(user);
-}
-EXPORT_SYMBOL_GPL(atmel_pmecc_destroy_user);
-
 static int get_strength(struct atmel_pmecc_user *user)
 {
 	const int *strengths = user->pmecc->caps->strengths;
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/raw/atmel/pmecc.h
+++ linux-qcom-6.8.0/drivers/mtd/nand/raw/atmel/pmecc.h
@@ -55,8 +55,6 @@
 struct atmel_pmecc_user *
 atmel_pmecc_create_user(struct atmel_pmecc *pmecc,
 			struct atmel_pmecc_user_req *req);
-void atmel_pmecc_destroy_user(struct atmel_pmecc_user *user);
-
 void atmel_pmecc_reset(struct atmel_pmecc *pmecc);
 int atmel_pmecc_enable(struct atmel_pmecc_user *user, int op);
 void atmel_pmecc_disable(struct atmel_pmecc_user *user);
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ linux-qcom-6.8.0/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -625,7 +625,7 @@
 /* Only for v7.2 */
 #define	ACC_CONTROL_ECC_EXT_SHIFT		13
 
-static u8 brcmnand_status(struct brcmnand_host *host);
+static int brcmnand_status(struct brcmnand_host *host);
 
 static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl)
 {
@@ -1690,7 +1690,7 @@
 				 INTFC_FLASH_STATUS;
 }
 
-static u8 brcmnand_status(struct brcmnand_host *host)
+static int brcmnand_status(struct brcmnand_host *host)
 {
 	struct nand_chip *chip = &host->chip;
 	struct mtd_info *mtd = nand_to_mtd(chip);
@@ -1701,7 +1701,7 @@
 	return brcmnand_waitfunc(chip);
 }
 
-static u8 brcmnand_reset(struct brcmnand_host *host)
+static int brcmnand_reset(struct brcmnand_host *host)
 {
 	struct nand_chip *chip = &host->chip;
 
@@ -2275,6 +2275,11 @@
 		brcmnand_send_cmd(host, CMD_PROGRAM_PAGE);
 		status = brcmnand_waitfunc(chip);
 
+		if (status < 0) {
+			ret = status;
+			goto out;
+		}
+
 		if (status & NAND_STATUS_FAIL) {
 			dev_info(ctrl->dev, "program failed at %llx\n",
 				(unsigned long long)addr);
@@ -2433,7 +2438,11 @@
 
 	if (brcmnand_op_is_status(op)) {
 		status = op->instrs[1].ctx.data.buf.in;
-		*status = brcmnand_status(host);
+		ret = brcmnand_status(host);
+		if (ret < 0)
+			return ret;
+
+		*status = ret & 0xFF;
 
 		return 0;
 	}
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/raw/diskonchip.c
+++ linux-qcom-6.8.0/drivers/mtd/nand/raw/diskonchip.c
@@ -53,7 +53,7 @@
 	0xe8000, 0xea000, 0xec000, 0xee000,
 #endif
 #endif
-	0xffffffff };
+};
 
 static struct mtd_info *doclist = NULL;
 
@@ -1098,7 +1098,7 @@
 		    (i == 0) && (ip->firstUnit > 0)) {
 			parts[0].name = " DiskOnChip IPL / Media Header partition";
 			parts[0].offset = 0;
-			parts[0].size = mtd->erasesize * ip->firstUnit;
+			parts[0].size = (uint64_t)mtd->erasesize * ip->firstUnit;
 			numparts = 1;
 		}
 
@@ -1554,7 +1554,7 @@
 		if (ret < 0)
 			return ret;
 	} else {
-		for (i = 0; (doc_locations[i] != 0xffffffff); i++) {
+		for (i = 0; i < ARRAY_SIZE(doc_locations); i++) {
 			doc_probe(doc_locations[i]);
 		}
 	}
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/raw/lpc32xx_mlc.c
+++ linux-qcom-6.8.0/drivers/mtd/nand/raw/lpc32xx_mlc.c
@@ -303,8 +303,9 @@
 	return 0;
 }
 
-static irqreturn_t lpc3xxx_nand_irq(int irq, struct lpc32xx_nand_host *host)
+static irqreturn_t lpc3xxx_nand_irq(int irq, void *data)
 {
+	struct lpc32xx_nand_host *host = data;
 	uint8_t sr;
 
 	/* Clear interrupt flag by reading status */
@@ -780,7 +781,7 @@
 		goto release_dma_chan;
 	}
 
-	if (request_irq(host->irq, (irq_handler_t)&lpc3xxx_nand_irq,
+	if (request_irq(host->irq, &lpc3xxx_nand_irq,
 			IRQF_TRIGGER_HIGH, DRV_NAME, host)) {
 		dev_err(&pdev->dev, "Error requesting NAND IRQ\n");
 		res = -ENXIO;
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/raw/meson_nand.c
+++ linux-qcom-6.8.0/drivers/mtd/nand/raw/meson_nand.c
@@ -63,7 +63,7 @@
 #define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages)	\
 	(								\
 		(cmd_dir)			|			\
-		((ran) << 19)			|			\
+		(ran)				|			\
 		((bch) << 14)			|			\
 		((short_mode) << 13)		|			\
 		(((page_size) & 0x7f) << 6)	|			\
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/raw/mtk_nand.c
+++ linux-qcom-6.8.0/drivers/mtd/nand/raw/mtk_nand.c
@@ -1429,16 +1429,32 @@
 	return 0;
 }
 
+static void mtk_nfc_nand_chips_cleanup(struct mtk_nfc *nfc)
+{
+	struct mtk_nfc_nand_chip *mtk_chip;
+	struct nand_chip *chip;
+	int ret;
+
+	while (!list_empty(&nfc->chips)) {
+		mtk_chip = list_first_entry(&nfc->chips,
+					    struct mtk_nfc_nand_chip, node);
+		chip = &mtk_chip->nand;
+		ret = mtd_device_unregister(nand_to_mtd(chip));
+		WARN_ON(ret);
+		nand_cleanup(chip);
+		list_del(&mtk_chip->node);
+	}
+}
+
 static int mtk_nfc_nand_chips_init(struct device *dev, struct mtk_nfc *nfc)
 {
 	struct device_node *np = dev->of_node;
-	struct device_node *nand_np;
 	int ret;
 
-	for_each_child_of_node(np, nand_np) {
+	for_each_child_of_node_scoped(np, nand_np) {
 		ret = mtk_nfc_nand_chip_init(dev, nfc, nand_np);
 		if (ret) {
-			of_node_put(nand_np);
+			mtk_nfc_nand_chips_cleanup(nfc);
 			return ret;
 		}
 	}
@@ -1570,20 +1586,8 @@
 static void mtk_nfc_remove(struct platform_device *pdev)
 {
 	struct mtk_nfc *nfc = platform_get_drvdata(pdev);
-	struct mtk_nfc_nand_chip *mtk_chip;
-	struct nand_chip *chip;
-	int ret;
-
-	while (!list_empty(&nfc->chips)) {
-		mtk_chip = list_first_entry(&nfc->chips,
-					    struct mtk_nfc_nand_chip, node);
-		chip = &mtk_chip->nand;
-		ret = mtd_device_unregister(nand_to_mtd(chip));
-		WARN_ON(ret);
-		nand_cleanup(chip);
-		list_del(&mtk_chip->node);
-	}
 
+	mtk_nfc_nand_chips_cleanup(nfc);
 	mtk_ecc_release(nfc->ecc);
 }
 
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/raw/nand_base.c
+++ linux-qcom-6.8.0/drivers/mtd/nand/raw/nand_base.c
@@ -1093,28 +1093,32 @@
 				   unsigned int offset_in_page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	bool ident_stage = !mtd->writesize;
 
-	/* Make sure the offset is less than the actual page size. */
-	if (offset_in_page > mtd->writesize + mtd->oobsize)
-		return -EINVAL;
+	/* Bypass all checks during NAND identification */
+	if (likely(!ident_stage)) {
+		/* Make sure the offset is less than the actual page size. */
+		if (offset_in_page > mtd->writesize + mtd->oobsize)
+			return -EINVAL;
 
-	/*
-	 * On small page NANDs, there's a dedicated command to access the OOB
-	 * area, and the column address is relative to the start of the OOB
-	 * area, not the start of the page. Asjust the address accordingly.
-	 */
-	if (mtd->writesize <= 512 && offset_in_page >= mtd->writesize)
-		offset_in_page -= mtd->writesize;
+		/*
+		 * On small page NANDs, there's a dedicated command to access the OOB
+		 * area, and the column address is relative to the start of the OOB
+		 * area, not the start of the page. Asjust the address accordingly.
+		 */
+		if (mtd->writesize <= 512 && offset_in_page >= mtd->writesize)
+			offset_in_page -= mtd->writesize;
 
-	/*
-	 * The offset in page is expressed in bytes, if the NAND bus is 16-bit
-	 * wide, then it must be divided by 2.
-	 */
-	if (chip->options & NAND_BUSWIDTH_16) {
-		if (WARN_ON(offset_in_page % 2))
-			return -EINVAL;
+		/*
+		 * The offset in page is expressed in bytes, if the NAND bus is 16-bit
+		 * wide, then it must be divided by 2.
+		 */
+		if (chip->options & NAND_BUSWIDTH_16) {
+			if (WARN_ON(offset_in_page % 2))
+				return -EINVAL;
 
-		offset_in_page /= 2;
+			offset_in_page /= 2;
+		}
 	}
 
 	addrs[0] = offset_in_page;
@@ -1123,7 +1127,7 @@
 	 * Small page NANDs use 1 cycle for the columns, while large page NANDs
 	 * need 2
 	 */
-	if (mtd->writesize <= 512)
+	if (!ident_stage && mtd->writesize <= 512)
 		return 1;
 
 	addrs[1] = offset_in_page >> 8;
@@ -1211,21 +1215,36 @@
 	return nand_exec_op(chip, &op);
 }
 
+static unsigned int rawnand_last_page_of_lun(unsigned int pages_per_lun, unsigned int lun)
+{
+	/* lun is expected to be very small */
+	return (lun * pages_per_lun) + pages_per_lun - 1;
+}
+
 static void rawnand_cap_cont_reads(struct nand_chip *chip)
 {
 	struct nand_memory_organization *memorg;
-	unsigned int pages_per_lun, first_lun, last_lun;
+	unsigned int ppl, first_lun, last_lun;
 
 	memorg = nanddev_get_memorg(&chip->base);
-	pages_per_lun = memorg->pages_per_eraseblock * memorg->eraseblocks_per_lun;
-	first_lun = chip->cont_read.first_page / pages_per_lun;
-	last_lun = chip->cont_read.last_page / pages_per_lun;
+	ppl = memorg->pages_per_eraseblock * memorg->eraseblocks_per_lun;
+	first_lun = chip->cont_read.first_page / ppl;
+	last_lun = chip->cont_read.last_page / ppl;
 
 	/* Prevent sequential cache reads across LUN boundaries */
 	if (first_lun != last_lun)
-		chip->cont_read.pause_page = first_lun * pages_per_lun + pages_per_lun - 1;
+		chip->cont_read.pause_page = rawnand_last_page_of_lun(ppl, first_lun);
 	else
 		chip->cont_read.pause_page = chip->cont_read.last_page;
+
+	if (chip->cont_read.first_page == chip->cont_read.pause_page) {
+		chip->cont_read.first_page++;
+		chip->cont_read.pause_page = min(chip->cont_read.last_page,
+						 rawnand_last_page_of_lun(ppl, first_lun + 1));
+	}
+
+	if (chip->cont_read.first_page >= chip->cont_read.last_page)
+		chip->cont_read.ongoing = false;
 }
 
 static int nand_lp_exec_cont_read_page_op(struct nand_chip *chip, unsigned int page,
@@ -1292,12 +1311,11 @@
 	if (!chip->cont_read.ongoing)
 		return 0;
 
-	if (page == chip->cont_read.pause_page &&
-	    page != chip->cont_read.last_page) {
-		chip->cont_read.first_page = chip->cont_read.pause_page + 1;
-		rawnand_cap_cont_reads(chip);
-	} else if (page == chip->cont_read.last_page) {
+	if (page == chip->cont_read.last_page) {
 		chip->cont_read.ongoing = false;
+	} else if (page == chip->cont_read.pause_page) {
+		chip->cont_read.first_page++;
+		rawnand_cap_cont_reads(chip);
 	}
 
 	return 0;
@@ -1422,16 +1440,19 @@
 			       unsigned int len, bool force_8bit)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	bool ident_stage = !mtd->writesize;
 
 	if (len && !buf)
 		return -EINVAL;
 
-	if (offset_in_page + len > mtd->writesize + mtd->oobsize)
-		return -EINVAL;
+	if (!ident_stage) {
+		if (offset_in_page + len > mtd->writesize + mtd->oobsize)
+			return -EINVAL;
 
-	/* Small page NANDs do not support column change. */
-	if (mtd->writesize <= 512)
-		return -ENOTSUPP;
+		/* Small page NANDs do not support column change. */
+		if (mtd->writesize <= 512)
+			return -ENOTSUPP;
+	}
 
 	if (nand_has_exec_op(chip)) {
 		const struct nand_interface_config *conf =
@@ -2159,7 +2180,7 @@
 int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len,
 		      bool force_8bit, bool check_only)
 {
-	if (!len || !buf)
+	if (!len || (!check_only && !buf))
 		return -EINVAL;
 
 	if (nand_has_exec_op(chip)) {
@@ -3466,30 +3487,36 @@
 				      u32 readlen, int col)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
-	unsigned int end_page, end_col;
+	unsigned int first_page, last_page;
 
 	chip->cont_read.ongoing = false;
 
 	if (!chip->controller->supported_op.cont_read)
 		return;
 
-	end_page = DIV_ROUND_UP(col + readlen, mtd->writesize);
-	end_col = (col + readlen) % mtd->writesize;
+	/*
+	 * Don't bother making any calculations if the length is too small.
+	 * Side effect: avoids possible integer underflows below.
+	 */
+	if (readlen < (2 * mtd->writesize))
+		return;
 
+	/* Derive the page where continuous read should start (the first full page read) */
+	first_page = page;
 	if (col)
-		page++;
-
-	if (end_col && end_page)
-		end_page--;
-
-	if (page + 1 > end_page)
-		return;
+		first_page++;
 
-	chip->cont_read.first_page = page;
-	chip->cont_read.last_page = end_page;
-	chip->cont_read.ongoing = true;
+	/* Derive the page where continuous read should stop (the last full page read) */
+	last_page = page + ((col + readlen) / mtd->writesize) - 1;
 
-	rawnand_cap_cont_reads(chip);
+	/* Configure and enable continuous read when suitable */
+	if (first_page < last_page) {
+		chip->cont_read.first_page = first_page;
+		chip->cont_read.last_page = last_page;
+		chip->cont_read.ongoing = true;
+		/* May reset the ongoing flag */
+		rawnand_cap_cont_reads(chip);
+	}
 }
 
 static void rawnand_cont_read_skip_first_page(struct nand_chip *chip, unsigned int page)
@@ -3498,10 +3525,7 @@
 		return;
 
 	chip->cont_read.first_page++;
-	if (chip->cont_read.first_page == chip->cont_read.pause_page)
-		chip->cont_read.first_page++;
-	if (chip->cont_read.first_page >= chip->cont_read.last_page)
-		chip->cont_read.ongoing = false;
+	rawnand_cap_cont_reads(chip);
 }
 
 /**
@@ -3577,7 +3601,8 @@
 	oob = ops->oobbuf;
 	oob_required = oob ? 1 : 0;
 
-	rawnand_enable_cont_reads(chip, page, readlen, col);
+	if (likely(ops->mode != MTD_OPS_RAW))
+		rawnand_enable_cont_reads(chip, page, readlen, col);
 
 	while (1) {
 		struct mtd_ecc_stats ecc_stats = mtd->ecc_stats;
@@ -5195,6 +5220,15 @@
 	if (!nand_has_exec_op(chip))
 		return;
 
+	/*
+	 * For now, continuous reads can only be used with the core page helpers.
+	 * This can be extended later.
+	 */
+	if (!(chip->ecc.read_page == nand_read_page_hwecc ||
+	      chip->ecc.read_page == nand_read_page_syndrome ||
+	      chip->ecc.read_page == nand_read_page_swecc))
+		return;
+
 	rawnand_check_cont_read_support(chip);
 }
 
@@ -6271,6 +6305,7 @@
 static int nand_scan_tail(struct nand_chip *chip)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	struct nand_device *base = &chip->base;
 	struct nand_ecc_ctrl *ecc = &chip->ecc;
 	int ret, i;
 
@@ -6415,9 +6450,13 @@
 	if (!ecc->write_oob_raw)
 		ecc->write_oob_raw = ecc->write_oob;
 
-	/* propagate ecc info to mtd_info */
+	/* Propagate ECC info to the generic NAND and MTD layers */
 	mtd->ecc_strength = ecc->strength;
+	if (!base->ecc.ctx.conf.strength)
+		base->ecc.ctx.conf.strength = ecc->strength;
 	mtd->ecc_step_size = ecc->size;
+	if (!base->ecc.ctx.conf.step_size)
+		base->ecc.ctx.conf.step_size = ecc->size;
 
 	/*
 	 * Set the number of read / write steps for one page depending on ECC
@@ -6425,6 +6464,8 @@
 	 */
 	if (!ecc->steps)
 		ecc->steps = mtd->writesize / ecc->size;
+	if (!base->ecc.ctx.nsteps)
+		base->ecc.ctx.nsteps = ecc->steps;
 	if (ecc->steps * ecc->size != mtd->writesize) {
 		WARN(1, "Invalid ECC parameters\n");
 		ret = -EINVAL;
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/raw/nand_hynix.c
+++ linux-qcom-6.8.0/drivers/mtd/nand/raw/nand_hynix.c
@@ -402,7 +402,7 @@
 	if (ret)
 		pr_warn("failed to initialize read-retry infrastructure");
 
-	return 0;
+	return ret;
 }
 
 static void hynix_nand_extract_oobsize(struct nand_chip *chip,
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/raw/qcom_nandc.c
+++ linux-qcom-6.8.0/drivers/mtd/nand/raw/qcom_nandc.c
@@ -2815,7 +2815,7 @@
 			      host->cfg0_raw & ~(7 << CW_PER_PAGE));
 		nandc_set_reg(chip, NAND_DEV0_CFG1, host->cfg1_raw);
 		instrs = 3;
-	} else {
+	} else if (q_op.cmd_reg != OP_RESET_DEVICE) {
 		return 0;
 	}
 
@@ -2830,9 +2830,8 @@
 	nandc_set_reg(chip, NAND_EXEC_CMD, 1);
 
 	write_reg_dma(nandc, NAND_FLASH_CMD, instrs, NAND_BAM_NEXT_SGL);
-	(q_op.cmd_reg == OP_BLOCK_ERASE) ? write_reg_dma(nandc, NAND_DEV0_CFG0,
-	2, NAND_BAM_NEXT_SGL) : read_reg_dma(nandc,
-	NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
+	if (q_op.cmd_reg == OP_BLOCK_ERASE)
+		write_reg_dma(nandc, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL);
 
 	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 	read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/raw/rockchip-nand-controller.c
+++ linux-qcom-6.8.0/drivers/mtd/nand/raw/rockchip-nand-controller.c
@@ -420,13 +420,13 @@
 	u32 rate, tc2rw, trwpw, trw2c;
 	u32 temp;
 
-	if (target < 0)
-		return 0;
-
 	timings = nand_get_sdr_timings(conf);
 	if (IS_ERR(timings))
 		return -EOPNOTSUPP;
 
+	if (target < 0)
+		return 0;
+
 	if (IS_ERR(nfc->nfc_clk))
 		rate = clk_get_rate(nfc->ahb_clk);
 	else
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/spi/esmt.c
+++ linux-qcom-6.8.0/drivers/mtd/nand/spi/esmt.c
@@ -104,7 +104,8 @@
 
 static const struct spinand_info esmt_c8_spinand_table[] = {
 	SPINAND_INFO("F50L1G41LB",
-		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01),
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x01, 0x7f,
+				0x7f, 0x7f),
 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
 		     NAND_ECCREQ(1, 512),
 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
@@ -113,7 +114,8 @@
 		     0,
 		     SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)),
 	SPINAND_INFO("F50D1G41LB",
-		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x11),
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x11, 0x7f,
+				0x7f, 0x7f),
 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
 		     NAND_ECCREQ(1, 512),
 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
@@ -122,7 +124,8 @@
 		     0,
 		     SPINAND_ECCINFO(&f50l1g41lb_ooblayout, NULL)),
 	SPINAND_INFO("F50D2G41KA",
-		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x51),
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x51, 0x7f,
+				0x7f, 0x7f),
 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
 		     NAND_ECCREQ(8, 512),
 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
--- linux-qcom-6.8.0.orig/drivers/mtd/nand/spi/winbond.c
+++ linux-qcom-6.8.0/drivers/mtd/nand/spi/winbond.c
@@ -172,30 +172,30 @@
 	SPINAND_INFO("W25N01JW",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbc, 0x21),
 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-		     NAND_ECCREQ(4, 512),
+		     NAND_ECCREQ(1, 512),
 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25m02gv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
 	SPINAND_INFO("W25N02JWZEIF",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbf, 0x22),
 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 2, 1),
-		     NAND_ECCREQ(4, 512),
+		     NAND_ECCREQ(1, 512),
 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
 	SPINAND_INFO("W25N512GW",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x20),
 		     NAND_MEMORG(1, 2048, 64, 64, 512, 10, 1, 1, 1),
-		     NAND_ECCREQ(4, 512),
+		     NAND_ECCREQ(1, 512),
 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
 	SPINAND_INFO("W25N02KWZEIR",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x22),
 		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
@@ -208,12 +208,12 @@
 	SPINAND_INFO("W25N01GWZEIG",
 		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x21),
 		     NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
-		     NAND_ECCREQ(4, 512),
+		     NAND_ECCREQ(1, 512),
 		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
 					      &write_cache_variants,
 					      &update_cache_variants),
 		     0,
-		     SPINAND_ECCINFO(&w25m02gv_ooblayout, w25n02kv_ecc_get_status)),
+		     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
 };
 
 static int winbond_spinand_init(struct spinand_device *spinand)
--- linux-qcom-6.8.0.orig/drivers/mtd/parsers/redboot.c
+++ linux-qcom-6.8.0/drivers/mtd/parsers/redboot.c
@@ -102,7 +102,7 @@
 			offset -= master->erasesize;
 		}
 	} else {
-		offset = directory * master->erasesize;
+		offset = (unsigned long) directory * master->erasesize;
 		while (mtd_block_isbad(master, offset)) {
 			offset += master->erasesize;
 			if (offset == master->size)
--- linux-qcom-6.8.0.orig/drivers/mtd/spi-nor/spansion.c
+++ linux-qcom-6.8.0/drivers/mtd/spi-nor/spansion.c
@@ -106,6 +106,7 @@
 	int ret;
 
 	if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) {
+		op.addr.nbytes = nor->addr_nbytes;
 		op.dummy.nbytes = params->rdsr_dummy;
 		op.data.nbytes = 2;
 	}
--- linux-qcom-6.8.0.orig/drivers/mtd/spi-nor/winbond.c
+++ linux-qcom-6.8.0/drivers/mtd/spi-nor/winbond.c
@@ -105,7 +105,9 @@
 	}, {
 		.id = SNOR_ID(0xef, 0x40, 0x18),
 		.name = "w25q128",
+		.size = SZ_16M,
 		.flags = SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB,
+		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 	}, {
 		.id = SNOR_ID(0xef, 0x40, 0x19),
 		.name = "w25q256",
--- linux-qcom-6.8.0.orig/drivers/mtd/tests/Makefile
+++ linux-qcom-6.8.0/drivers/mtd/tests/Makefile
@@ -1,19 +1,19 @@
 # SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_MTD_TESTS) += mtd_oobtest.o
-obj-$(CONFIG_MTD_TESTS) += mtd_pagetest.o
-obj-$(CONFIG_MTD_TESTS) += mtd_readtest.o
-obj-$(CONFIG_MTD_TESTS) += mtd_speedtest.o
-obj-$(CONFIG_MTD_TESTS) += mtd_stresstest.o
-obj-$(CONFIG_MTD_TESTS) += mtd_subpagetest.o
-obj-$(CONFIG_MTD_TESTS) += mtd_torturetest.o
-obj-$(CONFIG_MTD_TESTS) += mtd_nandecctest.o
-obj-$(CONFIG_MTD_TESTS) += mtd_nandbiterrs.o
+obj-$(CONFIG_MTD_TESTS) += mtd_oobtest.o mtd_test.o
+obj-$(CONFIG_MTD_TESTS) += mtd_pagetest.o mtd_test.o
+obj-$(CONFIG_MTD_TESTS) += mtd_readtest.o mtd_test.o
+obj-$(CONFIG_MTD_TESTS) += mtd_speedtest.o mtd_test.o
+obj-$(CONFIG_MTD_TESTS) += mtd_stresstest.o mtd_test.o
+obj-$(CONFIG_MTD_TESTS) += mtd_subpagetest.o mtd_test.o
+obj-$(CONFIG_MTD_TESTS) += mtd_torturetest.o mtd_test.o
+obj-$(CONFIG_MTD_TESTS) += mtd_nandecctest.o mtd_test.o
+obj-$(CONFIG_MTD_TESTS) += mtd_nandbiterrs.o mtd_test.o
 
-mtd_oobtest-objs := oobtest.o mtd_test.o
-mtd_pagetest-objs := pagetest.o mtd_test.o
-mtd_readtest-objs := readtest.o mtd_test.o
-mtd_speedtest-objs := speedtest.o mtd_test.o
-mtd_stresstest-objs := stresstest.o mtd_test.o
-mtd_subpagetest-objs := subpagetest.o mtd_test.o
-mtd_torturetest-objs := torturetest.o mtd_test.o
-mtd_nandbiterrs-objs := nandbiterrs.o mtd_test.o
+mtd_oobtest-objs := oobtest.o
+mtd_pagetest-objs := pagetest.o
+mtd_readtest-objs := readtest.o
+mtd_speedtest-objs := speedtest.o
+mtd_stresstest-objs := stresstest.o
+mtd_subpagetest-objs := subpagetest.o
+mtd_torturetest-objs := torturetest.o
+mtd_nandbiterrs-objs := nandbiterrs.o
--- linux-qcom-6.8.0.orig/drivers/mtd/tests/mtd_test.c
+++ linux-qcom-6.8.0/drivers/mtd/tests/mtd_test.c
@@ -25,6 +25,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtdtest_erase_eraseblock);
 
 static int is_block_bad(struct mtd_info *mtd, unsigned int ebnum)
 {
@@ -57,6 +58,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtdtest_scan_for_bad_eraseblocks);
 
 int mtdtest_erase_good_eraseblocks(struct mtd_info *mtd, unsigned char *bbt,
 				unsigned int eb, int ebcnt)
@@ -75,6 +77,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mtdtest_erase_good_eraseblocks);
 
 int mtdtest_read(struct mtd_info *mtd, loff_t addr, size_t size, void *buf)
 {
@@ -92,6 +95,7 @@
 
 	return err;
 }
+EXPORT_SYMBOL_GPL(mtdtest_read);
 
 int mtdtest_write(struct mtd_info *mtd, loff_t addr, size_t size,
 		const void *buf)
@@ -107,3 +111,8 @@
 
 	return err;
 }
+EXPORT_SYMBOL_GPL(mtdtest_write);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MTD function test helpers");
+MODULE_AUTHOR("Akinobu Mita");
--- linux-qcom-6.8.0.orig/drivers/mtd/ubi/attach.c
+++ linux-qcom-6.8.0/drivers/mtd/ubi/attach.c
@@ -1447,7 +1447,7 @@
 	return err;
 }
 
-static struct ubi_attach_info *alloc_ai(void)
+static struct ubi_attach_info *alloc_ai(const char *slab_name)
 {
 	struct ubi_attach_info *ai;
 
@@ -1461,7 +1461,7 @@
 	INIT_LIST_HEAD(&ai->alien);
 	INIT_LIST_HEAD(&ai->fastmap);
 	ai->volumes = RB_ROOT;
-	ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache",
+	ai->aeb_slab_cache = kmem_cache_create(slab_name,
 					       sizeof(struct ubi_ainf_peb),
 					       0, 0, NULL);
 	if (!ai->aeb_slab_cache) {
@@ -1491,7 +1491,7 @@
 
 	err = -ENOMEM;
 
-	scan_ai = alloc_ai();
+	scan_ai = alloc_ai("ubi_aeb_slab_cache_fastmap");
 	if (!scan_ai)
 		goto out;
 
@@ -1557,7 +1557,7 @@
 	int err;
 	struct ubi_attach_info *ai;
 
-	ai = alloc_ai();
+	ai = alloc_ai("ubi_aeb_slab_cache");
 	if (!ai)
 		return -ENOMEM;
 
@@ -1575,7 +1575,7 @@
 		if (err > 0 || mtd_is_eccerr(err)) {
 			if (err != UBI_NO_FASTMAP) {
 				destroy_ai(ai);
-				ai = alloc_ai();
+				ai = alloc_ai("ubi_aeb_slab_cache");
 				if (!ai)
 					return -ENOMEM;
 
@@ -1614,7 +1614,7 @@
 	if (ubi->fm && ubi_dbg_chk_fastmap(ubi)) {
 		struct ubi_attach_info *scan_ai;
 
-		scan_ai = alloc_ai();
+		scan_ai = alloc_ai("ubi_aeb_slab_cache_dbg_chk_fastmap");
 		if (!scan_ai) {
 			err = -ENOMEM;
 			goto out_wl;
--- linux-qcom-6.8.0.orig/drivers/mtd/ubi/build.c
+++ linux-qcom-6.8.0/drivers/mtd/ubi/build.c
@@ -1468,7 +1468,7 @@
 	if (token) {
 		int err = kstrtoint(token, 10, &p->ubi_num);
 
-		if (err) {
+		if (err || p->ubi_num < UBI_DEV_NUM_AUTO) {
 			pr_err("UBI error: bad value for ubi_num parameter: %s\n",
 			       token);
 			return -EINVAL;
--- linux-qcom-6.8.0.orig/drivers/mtd/ubi/eba.c
+++ linux-qcom-6.8.0/drivers/mtd/ubi/eba.c
@@ -1557,6 +1557,7 @@
 					  GFP_KERNEL);
 		if (!fm_eba[i]) {
 			ret = -ENOMEM;
+			kfree(scan_eba[i]);
 			goto out_free;
 		}
 
@@ -1592,7 +1593,7 @@
 	}
 
 out_free:
-	for (i = 0; i < num_volumes; i++) {
+	while (--i >= 0) {
 		if (!ubi->volumes[i])
 			continue;
 
--- linux-qcom-6.8.0.orig/drivers/mtd/ubi/fastmap-wl.c
+++ linux-qcom-6.8.0/drivers/mtd/ubi/fastmap-wl.c
@@ -346,14 +346,27 @@
  * WL sub-system.
  *
  * @ubi: UBI device description object
+ * @need_fill: whether to fill wear-leveling pool when no PEBs are found
  */
-static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi)
+static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi,
+					    bool need_fill)
 {
 	struct ubi_fm_pool *pool = &ubi->fm_wl_pool;
 	int pnum;
 
-	if (pool->used == pool->size)
+	if (pool->used == pool->size) {
+		if (need_fill && !ubi->fm_work_scheduled) {
+			/*
+			 * We cannot update the fastmap here because this
+			 * function is called in atomic context.
+			 * Let's fail here and refill/update it as soon as
+			 * possible.
+			 */
+			ubi->fm_work_scheduled = 1;
+			schedule_work(&ubi->fm_work);
+		}
 		return NULL;
+	}
 
 	pnum = pool->pebs[pool->used];
 	return ubi->lookuptbl[pnum];
@@ -375,7 +388,7 @@
 	if (!ubi->used.rb_node)
 		return false;
 
-	e = next_peb_for_wl(ubi);
+	e = next_peb_for_wl(ubi, false);
 	if (!e) {
 		if (!ubi->free.rb_node)
 			return false;
--- linux-qcom-6.8.0.orig/drivers/mtd/ubi/fastmap.c
+++ linux-qcom-6.8.0/drivers/mtd/ubi/fastmap.c
@@ -85,9 +85,10 @@
 		sizeof(struct ubi_fm_scan_pool) +
 		sizeof(struct ubi_fm_scan_pool) +
 		(ubi->peb_count * sizeof(struct ubi_fm_ec)) +
-		(sizeof(struct ubi_fm_eba) +
-		(ubi->peb_count * sizeof(__be32))) +
-		sizeof(struct ubi_fm_volhdr) * UBI_MAX_VOLUMES;
+		((sizeof(struct ubi_fm_eba) +
+		  sizeof(struct ubi_fm_volhdr)) *
+		 (UBI_MAX_VOLUMES + UBI_INT_VOL_COUNT)) +
+		(ubi->peb_count * sizeof(__be32));
 	return roundup(size, ubi->leb_size);
 }
 
--- linux-qcom-6.8.0.orig/drivers/mtd/ubi/vtbl.c
+++ linux-qcom-6.8.0/drivers/mtd/ubi/vtbl.c
@@ -791,6 +791,12 @@
 	 * The number of supported volumes is limited by the eraseblock size
 	 * and by the UBI_MAX_VOLUMES constant.
 	 */
+
+	if (ubi->leb_size < UBI_VTBL_RECORD_SIZE) {
+		ubi_err(ubi, "LEB size too small for a volume record");
+		return -EINVAL;
+	}
+
 	ubi->vtbl_slots = ubi->leb_size / UBI_VTBL_RECORD_SIZE;
 	if (ubi->vtbl_slots > UBI_MAX_VOLUMES)
 		ubi->vtbl_slots = UBI_MAX_VOLUMES;
--- linux-qcom-6.8.0.orig/drivers/mtd/ubi/wl.c
+++ linux-qcom-6.8.0/drivers/mtd/ubi/wl.c
@@ -683,7 +683,7 @@
 	ubi_assert(!ubi->move_to_put);
 
 #ifdef CONFIG_MTD_UBI_FASTMAP
-	if (!next_peb_for_wl(ubi) ||
+	if (!next_peb_for_wl(ubi, true) ||
 #else
 	if (!ubi->free.rb_node ||
 #endif
@@ -846,7 +846,14 @@
 			goto out_not_moved;
 		}
 		if (err == MOVE_RETRY) {
-			scrubbing = 1;
+			/*
+			 * For source PEB:
+			 * 1. The scrubbing is set for scrub type PEB, it will
+			 *    be put back into ubi->scrub list.
+			 * 2. Non-scrub type PEB will be put back into ubi->used
+			 *    list.
+			 */
+			keep = 1;
 			dst_leb_clean = 1;
 			goto out_not_moved;
 		}
--- linux-qcom-6.8.0.orig/drivers/mtd/ubi/wl.h
+++ linux-qcom-6.8.0/drivers/mtd/ubi/wl.h
@@ -5,7 +5,8 @@
 static void update_fastmap_work_fn(struct work_struct *wrk);
 static struct ubi_wl_entry *find_anchor_wl_entry(struct rb_root *root);
 static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi);
-static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi);
+static struct ubi_wl_entry *next_peb_for_wl(struct ubi_device *ubi,
+					    bool need_fill);
 static bool need_wear_leveling(struct ubi_device *ubi);
 static void ubi_fastmap_close(struct ubi_device *ubi);
 static inline void ubi_fastmap_init(struct ubi_device *ubi, int *count)
--- linux-qcom-6.8.0.orig/drivers/net/Kconfig
+++ linux-qcom-6.8.0/drivers/net/Kconfig
@@ -484,6 +484,15 @@
 	  QCOM based WWAN modems for IP or QMAP/rmnet protocol (like SDX55).
 	  Say Y or M.
 
+ config MHI_EP_NET
+	tristate "MHI Endpoint network driver"
+	depends on MHI_BUS_EP
+	help
+	  This is the network driver for MHI bus implementation in endpoint
+	  devices. It is used provide the network interface for QCOM modems
+	  such as SDX55.
+	  Say Y or M.
+
 endif # NET_CORE
 
 config SUNGEM_PHY
--- linux-qcom-6.8.0.orig/drivers/net/Makefile
+++ linux-qcom-6.8.0/drivers/net/Makefile
@@ -41,6 +41,7 @@
 obj-$(CONFIG_NET_VRF) += vrf.o
 obj-$(CONFIG_VSOCKMON) += vsockmon.o
 obj-$(CONFIG_MHI_NET) += mhi_net.o
+obj-$(CONFIG_MHI_EP_NET) += mhi_ep_net.o
 
 #
 # Networking Drivers
@@ -48,7 +49,9 @@
 obj-$(CONFIG_ARCNET) += arcnet/
 obj-$(CONFIG_CAIF) += caif/
 obj-$(CONFIG_CAN) += can/
-obj-$(CONFIG_NET_DSA) += dsa/
+ifdef CONFIG_NET_DSA
+obj-y += dsa/
+endif
 obj-$(CONFIG_ETHERNET) += ethernet/
 obj-$(CONFIG_FDDI) += fddi/
 obj-$(CONFIG_HIPPI) += hippi/
--- linux-qcom-6.8.0.orig/drivers/net/bareudp.c
+++ linux-qcom-6.8.0/drivers/net/bareudp.c
@@ -67,6 +67,7 @@
 	__be16 proto;
 	void *oiph;
 	int err;
+	int nh;
 
 	bareudp = rcu_dereference_sk_user_data(sk);
 	if (!bareudp)
@@ -82,7 +83,7 @@
 
 		if (skb_copy_bits(skb, BAREUDP_BASE_HLEN, &ipversion,
 				  sizeof(ipversion))) {
-			bareudp->dev->stats.rx_dropped++;
+			DEV_STATS_INC(bareudp->dev, rx_dropped);
 			goto drop;
 		}
 		ipversion >>= 4;
@@ -92,7 +93,7 @@
 		} else if (ipversion == 6 && bareudp->multi_proto_mode) {
 			proto = htons(ETH_P_IPV6);
 		} else {
-			bareudp->dev->stats.rx_dropped++;
+			DEV_STATS_INC(bareudp->dev, rx_dropped);
 			goto drop;
 		}
 	} else if (bareudp->ethertype == htons(ETH_P_MPLS_UC)) {
@@ -106,7 +107,7 @@
 				   ipv4_is_multicast(tunnel_hdr->daddr)) {
 				proto = htons(ETH_P_MPLS_MC);
 			} else {
-				bareudp->dev->stats.rx_dropped++;
+				DEV_STATS_INC(bareudp->dev, rx_dropped);
 				goto drop;
 			}
 		} else {
@@ -122,7 +123,7 @@
 				   (addr_type & IPV6_ADDR_MULTICAST)) {
 				proto = htons(ETH_P_MPLS_MC);
 			} else {
-				bareudp->dev->stats.rx_dropped++;
+				DEV_STATS_INC(bareudp->dev, rx_dropped);
 				goto drop;
 			}
 		}
@@ -134,20 +135,35 @@
 				 proto,
 				 !net_eq(bareudp->net,
 				 dev_net(bareudp->dev)))) {
-		bareudp->dev->stats.rx_dropped++;
+		DEV_STATS_INC(bareudp->dev, rx_dropped);
 		goto drop;
 	}
 	tun_dst = udp_tun_rx_dst(skb, family, TUNNEL_KEY, 0, 0);
 	if (!tun_dst) {
-		bareudp->dev->stats.rx_dropped++;
+		DEV_STATS_INC(bareudp->dev, rx_dropped);
 		goto drop;
 	}
 	skb_dst_set(skb, &tun_dst->dst);
 	skb->dev = bareudp->dev;
-	oiph = skb_network_header(skb);
-	skb_reset_network_header(skb);
 	skb_reset_mac_header(skb);
 
+	/* Save offset of outer header relative to skb->head,
+	 * because we are going to reset the network header to the inner header
+	 * and might change skb->head.
+	 */
+	nh = skb_network_header(skb) - skb->head;
+
+	skb_reset_network_header(skb);
+
+	if (!pskb_inet_may_pull(skb)) {
+		DEV_STATS_INC(bareudp->dev, rx_length_errors);
+		DEV_STATS_INC(bareudp->dev, rx_errors);
+		goto drop;
+	}
+
+	/* Get the outer header. */
+	oiph = skb->head + nh;
+
 	if (!ipv6_mod_enabled() || family == AF_INET)
 		err = IP_ECN_decapsulate(oiph, skb);
 	else
@@ -165,8 +181,8 @@
 						     &((struct ipv6hdr *)oiph)->saddr);
 		}
 		if (err > 1) {
-			++bareudp->dev->stats.rx_frame_errors;
-			++bareudp->dev->stats.rx_errors;
+			DEV_STATS_INC(bareudp->dev, rx_frame_errors);
+			DEV_STATS_INC(bareudp->dev, rx_errors);
 			goto drop;
 		}
 	}
@@ -303,6 +319,9 @@
 	__be32 saddr;
 	int err;
 
+	if (!skb_vlan_inet_prepare(skb, skb->protocol != htons(ETH_P_TEB)))
+		return -EINVAL;
+
 	if (!sock)
 		return -ESHUTDOWN;
 
@@ -368,6 +387,9 @@
 	__be16 sport;
 	int err;
 
+	if (!skb_vlan_inet_prepare(skb, skb->protocol != htons(ETH_P_TEB)))
+		return -EINVAL;
+
 	if (!sock)
 		return -ESHUTDOWN;
 
@@ -466,11 +488,11 @@
 	dev_kfree_skb(skb);
 
 	if (err == -ELOOP)
-		dev->stats.collisions++;
+		DEV_STATS_INC(dev, collisions);
 	else if (err == -ENETUNREACH)
-		dev->stats.tx_carrier_errors++;
+		DEV_STATS_INC(dev, tx_carrier_errors);
 
-	dev->stats.tx_errors++;
+	DEV_STATS_INC(dev, tx_errors);
 	return NETDEV_TX_OK;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/bonding/bond_main.c
+++ linux-qcom-6.8.0/drivers/net/bonding/bond_main.c
@@ -427,6 +427,8 @@
 			     struct netlink_ext_ack *extack)
 {
 	struct net_device *bond_dev = xs->xso.dev;
+	struct net_device *real_dev;
+	netdevice_tracker tracker;
 	struct bond_ipsec *ipsec;
 	struct bonding *bond;
 	struct slave *slave;
@@ -438,74 +440,80 @@
 	rcu_read_lock();
 	bond = netdev_priv(bond_dev);
 	slave = rcu_dereference(bond->curr_active_slave);
-	if (!slave) {
-		rcu_read_unlock();
-		return -ENODEV;
+	real_dev = slave ? slave->dev : NULL;
+	netdev_hold(real_dev, &tracker, GFP_ATOMIC);
+	rcu_read_unlock();
+	if (!real_dev) {
+		err = -ENODEV;
+		goto out;
 	}
 
-	if (!slave->dev->xfrmdev_ops ||
-	    !slave->dev->xfrmdev_ops->xdo_dev_state_add ||
-	    netif_is_bond_master(slave->dev)) {
+	if (!real_dev->xfrmdev_ops ||
+	    !real_dev->xfrmdev_ops->xdo_dev_state_add ||
+	    netif_is_bond_master(real_dev)) {
 		NL_SET_ERR_MSG_MOD(extack, "Slave does not support ipsec offload");
-		rcu_read_unlock();
-		return -EINVAL;
+		err = -EINVAL;
+		goto out;
 	}
 
-	ipsec = kmalloc(sizeof(*ipsec), GFP_ATOMIC);
+	ipsec = kmalloc(sizeof(*ipsec), GFP_KERNEL);
 	if (!ipsec) {
-		rcu_read_unlock();
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto out;
 	}
-	xs->xso.real_dev = slave->dev;
 
-	err = slave->dev->xfrmdev_ops->xdo_dev_state_add(xs, extack);
+	xs->xso.real_dev = real_dev;
+	err = real_dev->xfrmdev_ops->xdo_dev_state_add(xs, extack);
 	if (!err) {
 		ipsec->xs = xs;
 		INIT_LIST_HEAD(&ipsec->list);
-		spin_lock_bh(&bond->ipsec_lock);
+		mutex_lock(&bond->ipsec_lock);
 		list_add(&ipsec->list, &bond->ipsec_list);
-		spin_unlock_bh(&bond->ipsec_lock);
+		mutex_unlock(&bond->ipsec_lock);
 	} else {
 		kfree(ipsec);
 	}
-	rcu_read_unlock();
+out:
+	netdev_put(real_dev, &tracker);
 	return err;
 }
 
 static void bond_ipsec_add_sa_all(struct bonding *bond)
 {
 	struct net_device *bond_dev = bond->dev;
+	struct net_device *real_dev;
 	struct bond_ipsec *ipsec;
 	struct slave *slave;
 
-	rcu_read_lock();
-	slave = rcu_dereference(bond->curr_active_slave);
-	if (!slave)
-		goto out;
+	slave = rtnl_dereference(bond->curr_active_slave);
+	real_dev = slave ? slave->dev : NULL;
+	if (!real_dev)
+		return;
 
-	if (!slave->dev->xfrmdev_ops ||
-	    !slave->dev->xfrmdev_ops->xdo_dev_state_add ||
-	    netif_is_bond_master(slave->dev)) {
-		spin_lock_bh(&bond->ipsec_lock);
+	mutex_lock(&bond->ipsec_lock);
+	if (!real_dev->xfrmdev_ops ||
+	    !real_dev->xfrmdev_ops->xdo_dev_state_add ||
+	    netif_is_bond_master(real_dev)) {
 		if (!list_empty(&bond->ipsec_list))
-			slave_warn(bond_dev, slave->dev,
+			slave_warn(bond_dev, real_dev,
 				   "%s: no slave xdo_dev_state_add\n",
 				   __func__);
-		spin_unlock_bh(&bond->ipsec_lock);
 		goto out;
 	}
 
-	spin_lock_bh(&bond->ipsec_lock);
 	list_for_each_entry(ipsec, &bond->ipsec_list, list) {
-		ipsec->xs->xso.real_dev = slave->dev;
-		if (slave->dev->xfrmdev_ops->xdo_dev_state_add(ipsec->xs, NULL)) {
-			slave_warn(bond_dev, slave->dev, "%s: failed to add SA\n", __func__);
+		/* If new state is added before ipsec_lock acquired */
+		if (ipsec->xs->xso.real_dev == real_dev)
+			continue;
+
+		ipsec->xs->xso.real_dev = real_dev;
+		if (real_dev->xfrmdev_ops->xdo_dev_state_add(ipsec->xs, NULL)) {
+			slave_warn(bond_dev, real_dev, "%s: failed to add SA\n", __func__);
 			ipsec->xs->xso.real_dev = NULL;
 		}
 	}
-	spin_unlock_bh(&bond->ipsec_lock);
 out:
-	rcu_read_unlock();
+	mutex_unlock(&bond->ipsec_lock);
 }
 
 /**
@@ -515,6 +523,8 @@
 static void bond_ipsec_del_sa(struct xfrm_state *xs)
 {
 	struct net_device *bond_dev = xs->xso.dev;
+	struct net_device *real_dev;
+	netdevice_tracker tracker;
 	struct bond_ipsec *ipsec;
 	struct bonding *bond;
 	struct slave *slave;
@@ -525,6 +535,9 @@
 	rcu_read_lock();
 	bond = netdev_priv(bond_dev);
 	slave = rcu_dereference(bond->curr_active_slave);
+	real_dev = slave ? slave->dev : NULL;
+	netdev_hold(real_dev, &tracker, GFP_ATOMIC);
+	rcu_read_unlock();
 
 	if (!slave)
 		goto out;
@@ -532,18 +545,19 @@
 	if (!xs->xso.real_dev)
 		goto out;
 
-	WARN_ON(xs->xso.real_dev != slave->dev);
+	WARN_ON(xs->xso.real_dev != real_dev);
 
-	if (!slave->dev->xfrmdev_ops ||
-	    !slave->dev->xfrmdev_ops->xdo_dev_state_delete ||
-	    netif_is_bond_master(slave->dev)) {
-		slave_warn(bond_dev, slave->dev, "%s: no slave xdo_dev_state_delete\n", __func__);
+	if (!real_dev->xfrmdev_ops ||
+	    !real_dev->xfrmdev_ops->xdo_dev_state_delete ||
+	    netif_is_bond_master(real_dev)) {
+		slave_warn(bond_dev, real_dev, "%s: no slave xdo_dev_state_delete\n", __func__);
 		goto out;
 	}
 
-	slave->dev->xfrmdev_ops->xdo_dev_state_delete(xs);
+	real_dev->xfrmdev_ops->xdo_dev_state_delete(xs);
 out:
-	spin_lock_bh(&bond->ipsec_lock);
+	netdev_put(real_dev, &tracker);
+	mutex_lock(&bond->ipsec_lock);
 	list_for_each_entry(ipsec, &bond->ipsec_list, list) {
 		if (ipsec->xs == xs) {
 			list_del(&ipsec->list);
@@ -551,41 +565,72 @@
 			break;
 		}
 	}
-	spin_unlock_bh(&bond->ipsec_lock);
-	rcu_read_unlock();
+	mutex_unlock(&bond->ipsec_lock);
 }
 
 static void bond_ipsec_del_sa_all(struct bonding *bond)
 {
 	struct net_device *bond_dev = bond->dev;
+	struct net_device *real_dev;
 	struct bond_ipsec *ipsec;
 	struct slave *slave;
 
-	rcu_read_lock();
-	slave = rcu_dereference(bond->curr_active_slave);
-	if (!slave) {
-		rcu_read_unlock();
+	slave = rtnl_dereference(bond->curr_active_slave);
+	real_dev = slave ? slave->dev : NULL;
+	if (!real_dev)
 		return;
-	}
 
-	spin_lock_bh(&bond->ipsec_lock);
+	mutex_lock(&bond->ipsec_lock);
 	list_for_each_entry(ipsec, &bond->ipsec_list, list) {
 		if (!ipsec->xs->xso.real_dev)
 			continue;
 
-		if (!slave->dev->xfrmdev_ops ||
-		    !slave->dev->xfrmdev_ops->xdo_dev_state_delete ||
-		    netif_is_bond_master(slave->dev)) {
-			slave_warn(bond_dev, slave->dev,
+		if (!real_dev->xfrmdev_ops ||
+		    !real_dev->xfrmdev_ops->xdo_dev_state_delete ||
+		    netif_is_bond_master(real_dev)) {
+			slave_warn(bond_dev, real_dev,
 				   "%s: no slave xdo_dev_state_delete\n",
 				   __func__);
 		} else {
-			slave->dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs);
+			real_dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs);
+			if (real_dev->xfrmdev_ops->xdo_dev_state_free)
+				real_dev->xfrmdev_ops->xdo_dev_state_free(ipsec->xs);
 		}
-		ipsec->xs->xso.real_dev = NULL;
 	}
-	spin_unlock_bh(&bond->ipsec_lock);
+	mutex_unlock(&bond->ipsec_lock);
+}
+
+static void bond_ipsec_free_sa(struct xfrm_state *xs)
+{
+	struct net_device *bond_dev = xs->xso.dev;
+	struct net_device *real_dev;
+	netdevice_tracker tracker;
+	struct bonding *bond;
+	struct slave *slave;
+
+	if (!bond_dev)
+		return;
+
+	rcu_read_lock();
+	bond = netdev_priv(bond_dev);
+	slave = rcu_dereference(bond->curr_active_slave);
+	real_dev = slave ? slave->dev : NULL;
+	netdev_hold(real_dev, &tracker, GFP_ATOMIC);
 	rcu_read_unlock();
+
+	if (!slave)
+		goto out;
+
+	if (!xs->xso.real_dev)
+		goto out;
+
+	WARN_ON(xs->xso.real_dev != real_dev);
+
+	if (real_dev && real_dev->xfrmdev_ops &&
+	    real_dev->xfrmdev_ops->xdo_dev_state_free)
+		real_dev->xfrmdev_ops->xdo_dev_state_free(xs);
+out:
+	netdev_put(real_dev, &tracker);
 }
 
 /**
@@ -599,39 +644,36 @@
 	struct net_device *real_dev;
 	struct slave *curr_active;
 	struct bonding *bond;
-	int err;
+	bool ok = false;
 
 	bond = netdev_priv(bond_dev);
 	rcu_read_lock();
 	curr_active = rcu_dereference(bond->curr_active_slave);
+	if (!curr_active)
+		goto out;
 	real_dev = curr_active->dev;
 
-	if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
-		err = false;
+	if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP)
 		goto out;
-	}
 
-	if (!xs->xso.real_dev) {
-		err = false;
+	if (!xs->xso.real_dev)
 		goto out;
-	}
 
 	if (!real_dev->xfrmdev_ops ||
 	    !real_dev->xfrmdev_ops->xdo_dev_offload_ok ||
-	    netif_is_bond_master(real_dev)) {
-		err = false;
+	    netif_is_bond_master(real_dev))
 		goto out;
-	}
 
-	err = real_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
+	ok = real_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
 out:
 	rcu_read_unlock();
-	return err;
+	return ok;
 }
 
 static const struct xfrmdev_ops bond_xfrmdev_ops = {
 	.xdo_dev_state_add = bond_ipsec_add_sa,
 	.xdo_dev_state_delete = bond_ipsec_del_sa,
+	.xdo_dev_state_free = bond_ipsec_free_sa,
 	.xdo_dev_offload_ok = bond_ipsec_offload_ok,
 };
 #endif /* CONFIG_XFRM_OFFLOAD */
@@ -892,6 +934,8 @@
 
 		if (bond->dev->flags & IFF_UP)
 			bond_hw_addr_flush(bond->dev, old_active->dev);
+
+		bond_slave_ns_maddrs_add(bond, old_active);
 	}
 
 	if (new_active) {
@@ -908,6 +952,8 @@
 			dev_mc_sync(new_active->dev, bond->dev);
 			netif_addr_unlock_bh(bond->dev);
 		}
+
+		bond_slave_ns_maddrs_del(bond, new_active);
 	}
 }
 
@@ -1121,13 +1167,10 @@
 	return bestslave;
 }
 
+/* must be called in RCU critical section or with RTNL held */
 static bool bond_should_notify_peers(struct bonding *bond)
 {
-	struct slave *slave;
-
-	rcu_read_lock();
-	slave = rcu_dereference(bond->curr_active_slave);
-	rcu_read_unlock();
+	struct slave *slave = rcu_dereference_rtnl(bond->curr_active_slave);
 
 	if (!slave || !bond->send_peer_notif ||
 	    bond->send_peer_notif %
@@ -1403,9 +1446,7 @@
 	struct slave *slave;
 
 	mask = features;
-
-	features &= ~NETIF_F_ONE_FOR_ALL;
-	features |= NETIF_F_ALL_FOR_ALL;
+	features = netdev_base_features(features);
 
 	bond_for_each_slave(bond, slave, iter) {
 		features = netdev_increment_features(features,
@@ -1419,6 +1460,7 @@
 
 #define BOND_VLAN_FEATURES	(NETIF_F_HW_CSUM | NETIF_F_SG | \
 				 NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | \
+				 NETIF_F_GSO_ENCAP_ALL | \
 				 NETIF_F_HIGHDMA | NETIF_F_LRO)
 
 #define BOND_ENC_FEATURES	(NETIF_F_HW_CSUM | NETIF_F_SG | \
@@ -1447,8 +1489,9 @@
 
 	if (!bond_has_slaves(bond))
 		goto done;
-	vlan_features &= NETIF_F_ALL_FOR_ALL;
-	mpls_features &= NETIF_F_ALL_FOR_ALL;
+
+	vlan_features = netdev_base_features(vlan_features);
+	mpls_features = netdev_base_features(mpls_features);
 
 	bond_for_each_slave(bond, slave, iter) {
 		vlan_features = netdev_increment_features(vlan_features,
@@ -2228,6 +2271,11 @@
 	bond_compute_features(bond);
 	bond_set_carrier(bond);
 
+	/* Needs to be called before bond_select_active_slave(), which will
+	 * remove the maddrs if the slave is selected as active slave.
+	 */
+	bond_slave_ns_maddrs_add(bond, new_slave);
+
 	if (bond_uses_primary(bond)) {
 		block_netpoll_tx();
 		bond_select_active_slave(bond);
@@ -2237,7 +2285,6 @@
 	if (bond_mode_can_use_xmit_hash(bond))
 		bond_update_slave_arr(bond, NULL);
 
-
 	if (!slave_dev->netdev_ops->ndo_bpf ||
 	    !slave_dev->netdev_ops->ndo_xdp_xmit) {
 		if (bond->xdp_prog) {
@@ -2435,6 +2482,12 @@
 	if (oldcurrent == slave)
 		bond_change_active_slave(bond, NULL);
 
+	/* Must be called after bond_change_active_slave () as the slave
+	 * might change from an active slave to a backup slave. Then it is
+	 * necessary to clear the maddrs on the backup slave.
+	 */
+	bond_slave_ns_maddrs_del(bond, slave);
+
 	if (bond_is_lb(bond)) {
 		/* Must be called only after the slave has been
 		 * detached from the list and the curr_active_slave
@@ -5495,9 +5548,9 @@
 		break;
 
 	default:
-		/* Should never happen. Mode guarded by bond_xdp_check() */
-		netdev_err(bond_dev, "Unknown bonding mode %d for xdp xmit\n", BOND_MODE(bond));
-		WARN_ON_ONCE(1);
+		if (net_ratelimit())
+			netdev_err(bond_dev, "Unknown bonding mode %d for xdp xmit\n",
+				   BOND_MODE(bond));
 		return NULL;
 	}
 
@@ -5771,6 +5824,9 @@
 	if (real_dev) {
 		ret = ethtool_get_ts_info_by_layer(real_dev, info);
 	} else {
+		info->phc_index = -1;
+		info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
+					SOF_TIMESTAMPING_SOFTWARE;
 		/* Check if all slaves support software tx timestamping */
 		rcu_read_lock();
 		bond_for_each_slave_rcu(bond, slave, iter) {
@@ -5880,7 +5936,7 @@
 	/* set up xfrm device ops (only supported in active-backup right now) */
 	bond_dev->xfrmdev_ops = &bond_xfrmdev_ops;
 	INIT_LIST_HEAD(&bond->ipsec_list);
-	spin_lock_init(&bond->ipsec_lock);
+	mutex_init(&bond->ipsec_lock);
 #endif /* CONFIG_XFRM_OFFLOAD */
 
 	/* don't acquire bond device's netif_tx_lock when transmitting */
@@ -5929,6 +5985,10 @@
 		__bond_release_one(bond_dev, slave->dev, true, true);
 	netdev_info(bond_dev, "Released all slaves\n");
 
+#ifdef CONFIG_XFRM_OFFLOAD
+	mutex_destroy(&bond->ipsec_lock);
+#endif /* CONFIG_XFRM_OFFLOAD */
+
 	bond_set_slave_arr(bond, NULL, NULL);
 
 	list_del(&bond->bond_list);
@@ -6459,16 +6519,16 @@
 	if (res)
 		goto out;
 
+	bond_create_debugfs();
+
 	res = register_pernet_subsys(&bond_net_ops);
 	if (res)
-		goto out;
+		goto err_net_ops;
 
 	res = bond_netlink_init();
 	if (res)
 		goto err_link;
 
-	bond_create_debugfs();
-
 	for (i = 0; i < max_bonds; i++) {
 		res = bond_create(&init_net, NULL);
 		if (res)
@@ -6483,10 +6543,11 @@
 out:
 	return res;
 err:
-	bond_destroy_debugfs();
 	bond_netlink_fini();
 err_link:
 	unregister_pernet_subsys(&bond_net_ops);
+err_net_ops:
+	bond_destroy_debugfs();
 	goto out;
 
 }
@@ -6495,11 +6556,11 @@
 {
 	unregister_netdevice_notifier(&bond_netdev_notifier);
 
-	bond_destroy_debugfs();
-
 	bond_netlink_fini();
 	unregister_pernet_subsys(&bond_net_ops);
 
+	bond_destroy_debugfs();
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	/* Make sure we don't have an imbalance on our netpoll blocking */
 	WARN_ON(atomic_read(&netpoll_block_tx));
--- linux-qcom-6.8.0.orig/drivers/net/bonding/bond_options.c
+++ linux-qcom-6.8.0/drivers/net/bonding/bond_options.c
@@ -15,6 +15,7 @@
 #include <linux/sched/signal.h>
 
 #include <net/bonding.h>
+#include <net/ndisc.h>
 
 static int bond_option_active_slave_set(struct bonding *bond,
 					const struct bond_opt_value *newval);
@@ -920,7 +921,7 @@
 	/* check to see if we are clearing active */
 	if (!slave_dev) {
 		netdev_dbg(bond->dev, "Clearing current active slave\n");
-		RCU_INIT_POINTER(bond->curr_active_slave, NULL);
+		bond_change_active_slave(bond, NULL);
 		bond_select_active_slave(bond);
 	} else {
 		struct slave *old_active = rtnl_dereference(bond->curr_active_slave);
@@ -1198,9 +1199,9 @@
 	__be32 target;
 
 	if (newval->string) {
-		if (!in4_pton(newval->string+1, -1, (u8 *)&target, -1, NULL)) {
-			netdev_err(bond->dev, "invalid ARP target %pI4 specified\n",
-				   &target);
+		if (strlen(newval->string) < 1 ||
+		    !in4_pton(newval->string + 1, -1, (u8 *)&target, -1, NULL)) {
+			netdev_err(bond->dev, "invalid ARP target specified\n");
 			return ret;
 		}
 		if (newval->string[0] == '+')
@@ -1218,6 +1219,68 @@
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
+static bool slave_can_set_ns_maddr(const struct bonding *bond, struct slave *slave)
+{
+	return BOND_MODE(bond) == BOND_MODE_ACTIVEBACKUP &&
+	       !bond_is_active_slave(slave) &&
+	       slave->dev->flags & IFF_MULTICAST;
+}
+
+static void slave_set_ns_maddrs(struct bonding *bond, struct slave *slave, bool add)
+{
+	struct in6_addr *targets = bond->params.ns_targets;
+	char slot_maddr[MAX_ADDR_LEN];
+	int i;
+
+	if (!slave_can_set_ns_maddr(bond, slave))
+		return;
+
+	for (i = 0; i < BOND_MAX_NS_TARGETS; i++) {
+		if (ipv6_addr_any(&targets[i]))
+			break;
+
+		if (!ndisc_mc_map(&targets[i], slot_maddr, slave->dev, 0)) {
+			if (add)
+				dev_mc_add(slave->dev, slot_maddr);
+			else
+				dev_mc_del(slave->dev, slot_maddr);
+		}
+	}
+}
+
+void bond_slave_ns_maddrs_add(struct bonding *bond, struct slave *slave)
+{
+	if (!bond->params.arp_validate)
+		return;
+	slave_set_ns_maddrs(bond, slave, true);
+}
+
+void bond_slave_ns_maddrs_del(struct bonding *bond, struct slave *slave)
+{
+	if (!bond->params.arp_validate)
+		return;
+	slave_set_ns_maddrs(bond, slave, false);
+}
+
+static void slave_set_ns_maddr(struct bonding *bond, struct slave *slave,
+			       struct in6_addr *target, struct in6_addr *slot)
+{
+	char target_maddr[MAX_ADDR_LEN], slot_maddr[MAX_ADDR_LEN];
+
+	if (!bond->params.arp_validate || !slave_can_set_ns_maddr(bond, slave))
+		return;
+
+	/* remove the previous maddr from slave */
+	if (!ipv6_addr_any(slot) &&
+	    !ndisc_mc_map(slot, slot_maddr, slave->dev, 0))
+		dev_mc_del(slave->dev, slot_maddr);
+
+	/* add new maddr on slave if target is set */
+	if (!ipv6_addr_any(target) &&
+	    !ndisc_mc_map(target, target_maddr, slave->dev, 0))
+		dev_mc_add(slave->dev, target_maddr);
+}
+
 static void _bond_options_ns_ip6_target_set(struct bonding *bond, int slot,
 					    struct in6_addr *target,
 					    unsigned long last_rx)
@@ -1227,8 +1290,10 @@
 	struct slave *slave;
 
 	if (slot >= 0 && slot < BOND_MAX_NS_TARGETS) {
-		bond_for_each_slave(bond, slave, iter)
+		bond_for_each_slave(bond, slave, iter) {
 			slave->target_last_arp_rx[slot] = last_rx;
+			slave_set_ns_maddr(bond, slave, target, &targets[slot]);
+		}
 		targets[slot] = *target;
 	}
 }
@@ -1280,15 +1345,30 @@
 {
 	return -EPERM;
 }
+
+static void slave_set_ns_maddrs(struct bonding *bond, struct slave *slave, bool add) {}
+
+void bond_slave_ns_maddrs_add(struct bonding *bond, struct slave *slave) {}
+
+void bond_slave_ns_maddrs_del(struct bonding *bond, struct slave *slave) {}
 #endif
 
 static int bond_option_arp_validate_set(struct bonding *bond,
 					const struct bond_opt_value *newval)
 {
+	bool changed = !!bond->params.arp_validate != !!newval->value;
+	struct list_head *iter;
+	struct slave *slave;
+
 	netdev_dbg(bond->dev, "Setting arp_validate to %s (%llu)\n",
 		   newval->string, newval->value);
 	bond->params.arp_validate = newval->value;
 
+	if (changed) {
+		bond_for_each_slave(bond, slave, iter)
+			slave_set_ns_maddrs(bond, slave, !!bond->params.arp_validate);
+	}
+
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/can/c_can/c_can_main.c
+++ linux-qcom-6.8.0/drivers/net/can/c_can/c_can_main.c
@@ -1011,47 +1011,60 @@
 
 	/* common for all type of bus errors */
 	priv->can.can_stats.bus_error++;
-	stats->rx_errors++;
 
 	/* propagate the error condition to the CAN stack */
 	skb = alloc_can_err_skb(dev, &cf);
-	if (unlikely(!skb))
-		return 0;
 
 	/* check for 'last error code' which tells us the
 	 * type of the last error to occur on the CAN bus
 	 */
-	cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+	if (likely(skb))
+		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
 	switch (lec_type) {
 	case LEC_STUFF_ERROR:
 		netdev_dbg(dev, "stuff error\n");
-		cf->data[2] |= CAN_ERR_PROT_STUFF;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_STUFF;
+		stats->rx_errors++;
 		break;
 	case LEC_FORM_ERROR:
 		netdev_dbg(dev, "form error\n");
-		cf->data[2] |= CAN_ERR_PROT_FORM;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_FORM;
+		stats->rx_errors++;
 		break;
 	case LEC_ACK_ERROR:
 		netdev_dbg(dev, "ack error\n");
-		cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+		if (likely(skb))
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+		stats->tx_errors++;
 		break;
 	case LEC_BIT1_ERROR:
 		netdev_dbg(dev, "bit1 error\n");
-		cf->data[2] |= CAN_ERR_PROT_BIT1;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_BIT1;
+		stats->tx_errors++;
 		break;
 	case LEC_BIT0_ERROR:
 		netdev_dbg(dev, "bit0 error\n");
-		cf->data[2] |= CAN_ERR_PROT_BIT0;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_BIT0;
+		stats->tx_errors++;
 		break;
 	case LEC_CRC_ERROR:
 		netdev_dbg(dev, "CRC error\n");
-		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		if (likely(skb))
+			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		stats->rx_errors++;
 		break;
 	default:
 		break;
 	}
 
+	if (unlikely(!skb))
+		return 0;
+
 	netif_receive_skb(skb);
 	return 1;
 }
--- linux-qcom-6.8.0.orig/drivers/net/can/dev/dev.c
+++ linux-qcom-6.8.0/drivers/net/can/dev/dev.c
@@ -471,7 +471,7 @@
 	else
 		set = 0;
 
-	gpiod_set_value(priv->termination_gpio, set);
+	gpiod_set_value_cansleep(priv->termination_gpio, set);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/net/can/dev/netlink.c
+++ linux-qcom-6.8.0/drivers/net/can/dev/netlink.c
@@ -65,15 +65,6 @@
 	if (!data)
 		return 0;
 
-	if (data[IFLA_CAN_BITTIMING]) {
-		struct can_bittiming bt;
-
-		memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
-		err = can_validate_bittiming(&bt, extack);
-		if (err)
-			return err;
-	}
-
 	if (data[IFLA_CAN_CTRLMODE]) {
 		struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]);
 		u32 tdc_flags = cm->flags & CAN_CTRLMODE_TDC_MASK;
@@ -114,6 +105,15 @@
 		}
 	}
 
+	if (data[IFLA_CAN_BITTIMING]) {
+		struct can_bittiming bt;
+
+		memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
+		err = can_validate_bittiming(&bt, extack);
+		if (err)
+			return err;
+	}
+
 	if (is_can_fd) {
 		if (!data[IFLA_CAN_BITTIMING] || !data[IFLA_CAN_DATA_BITTIMING])
 			return -EOPNOTSUPP;
@@ -195,48 +195,6 @@
 	/* We need synchronization with dev->stop() */
 	ASSERT_RTNL();
 
-	if (data[IFLA_CAN_BITTIMING]) {
-		struct can_bittiming bt;
-
-		/* Do not allow changing bittiming while running */
-		if (dev->flags & IFF_UP)
-			return -EBUSY;
-
-		/* Calculate bittiming parameters based on
-		 * bittiming_const if set, otherwise pass bitrate
-		 * directly via do_set_bitrate(). Bail out if neither
-		 * is given.
-		 */
-		if (!priv->bittiming_const && !priv->do_set_bittiming &&
-		    !priv->bitrate_const)
-			return -EOPNOTSUPP;
-
-		memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
-		err = can_get_bittiming(dev, &bt,
-					priv->bittiming_const,
-					priv->bitrate_const,
-					priv->bitrate_const_cnt,
-					extack);
-		if (err)
-			return err;
-
-		if (priv->bitrate_max && bt.bitrate > priv->bitrate_max) {
-			NL_SET_ERR_MSG_FMT(extack,
-					   "arbitration bitrate %u bps surpasses transceiver capabilities of %u bps",
-					   bt.bitrate, priv->bitrate_max);
-			return -EINVAL;
-		}
-
-		memcpy(&priv->bittiming, &bt, sizeof(bt));
-
-		if (priv->do_set_bittiming) {
-			/* Finally, set the bit-timing registers */
-			err = priv->do_set_bittiming(dev);
-			if (err)
-				return err;
-		}
-	}
-
 	if (data[IFLA_CAN_CTRLMODE]) {
 		struct can_ctrlmode *cm;
 		u32 ctrlstatic;
@@ -284,6 +242,48 @@
 			priv->ctrlmode &= cm->flags | ~CAN_CTRLMODE_TDC_MASK;
 	}
 
+	if (data[IFLA_CAN_BITTIMING]) {
+		struct can_bittiming bt;
+
+		/* Do not allow changing bittiming while running */
+		if (dev->flags & IFF_UP)
+			return -EBUSY;
+
+		/* Calculate bittiming parameters based on
+		 * bittiming_const if set, otherwise pass bitrate
+		 * directly via do_set_bitrate(). Bail out if neither
+		 * is given.
+		 */
+		if (!priv->bittiming_const && !priv->do_set_bittiming &&
+		    !priv->bitrate_const)
+			return -EOPNOTSUPP;
+
+		memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
+		err = can_get_bittiming(dev, &bt,
+					priv->bittiming_const,
+					priv->bitrate_const,
+					priv->bitrate_const_cnt,
+					extack);
+		if (err)
+			return err;
+
+		if (priv->bitrate_max && bt.bitrate > priv->bitrate_max) {
+			NL_SET_ERR_MSG_FMT(extack,
+					   "arbitration bitrate %u bps surpasses transceiver capabilities of %u bps",
+					   bt.bitrate, priv->bitrate_max);
+			return -EINVAL;
+		}
+
+		memcpy(&priv->bittiming, &bt, sizeof(bt));
+
+		if (priv->do_set_bittiming) {
+			/* Finally, set the bit-timing registers */
+			err = priv->do_set_bittiming(dev);
+			if (err)
+				return err;
+		}
+	}
+
 	if (data[IFLA_CAN_RESTART_MS]) {
 		/* Do not allow changing restart delay while running */
 		if (dev->flags & IFF_UP)
--- linux-qcom-6.8.0.orig/drivers/net/can/ifi_canfd/ifi_canfd.c
+++ linux-qcom-6.8.0/drivers/net/can/ifi_canfd/ifi_canfd.c
@@ -390,36 +390,55 @@
 		return 0;
 
 	priv->can.can_stats.bus_error++;
-	stats->rx_errors++;
 
 	/* Propagate the error condition to the CAN stack. */
 	skb = alloc_can_err_skb(ndev, &cf);
-	if (unlikely(!skb))
-		return 0;
 
 	/* Read the error counter register and check for new errors. */
-	cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
-
-	if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST)
-		cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
-
-	if (errctr & IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST)
-		cf->data[3] = CAN_ERR_PROT_LOC_ACK;
-
-	if (errctr & IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST)
-		cf->data[2] |= CAN_ERR_PROT_BIT0;
-
-	if (errctr & IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST)
-		cf->data[2] |= CAN_ERR_PROT_BIT1;
+	if (likely(skb))
+		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
-	if (errctr & IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST)
-		cf->data[2] |= CAN_ERR_PROT_STUFF;
-
-	if (errctr & IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST)
-		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
-
-	if (errctr & IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST)
-		cf->data[2] |= CAN_ERR_PROT_FORM;
+	if (errctr & IFI_CANFD_ERROR_CTR_OVERLOAD_FIRST) {
+		stats->rx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_OVERLOAD;
+	}
+
+	if (errctr & IFI_CANFD_ERROR_CTR_ACK_ERROR_FIRST) {
+		stats->tx_errors++;
+		if (likely(skb))
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+	}
+
+	if (errctr & IFI_CANFD_ERROR_CTR_BIT0_ERROR_FIRST) {
+		stats->tx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_BIT0;
+	}
+
+	if (errctr & IFI_CANFD_ERROR_CTR_BIT1_ERROR_FIRST) {
+		stats->tx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_BIT1;
+	}
+
+	if (errctr & IFI_CANFD_ERROR_CTR_STUFF_ERROR_FIRST) {
+		stats->rx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_STUFF;
+	}
+
+	if (errctr & IFI_CANFD_ERROR_CTR_CRC_ERROR_FIRST) {
+		stats->rx_errors++;
+		if (likely(skb))
+			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+	}
+
+	if (errctr & IFI_CANFD_ERROR_CTR_FORM_ERROR_FIRST) {
+		stats->rx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_FORM;
+	}
 
 	/* Reset the error counter, ack the IRQ and re-enable the counter. */
 	writel(IFI_CANFD_ERROR_CTR_ER_RESET, priv->base + IFI_CANFD_ERROR_CTR);
@@ -427,6 +446,9 @@
 	       priv->base + IFI_CANFD_INTERRUPT);
 	writel(IFI_CANFD_ERROR_CTR_ER_ENABLE, priv->base + IFI_CANFD_ERROR_CTR);
 
+	if (unlikely(!skb))
+		return 0;
+
 	netif_receive_skb(skb);
 
 	return 1;
--- linux-qcom-6.8.0.orig/drivers/net/can/kvaser_pciefd.c
+++ linux-qcom-6.8.0/drivers/net/can/kvaser_pciefd.c
@@ -1580,23 +1580,15 @@
 	return res;
 }
 
-static void kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie)
+static u32 kvaser_pciefd_receive_irq(struct kvaser_pciefd *pcie)
 {
 	u32 irq = ioread32(KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);
 
-	if (irq & KVASER_PCIEFD_SRB_IRQ_DPD0) {
+	if (irq & KVASER_PCIEFD_SRB_IRQ_DPD0)
 		kvaser_pciefd_read_buffer(pcie, 0);
-		/* Reset DMA buffer 0 */
-		iowrite32(KVASER_PCIEFD_SRB_CMD_RDB0,
-			  KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
-	}
 
-	if (irq & KVASER_PCIEFD_SRB_IRQ_DPD1) {
+	if (irq & KVASER_PCIEFD_SRB_IRQ_DPD1)
 		kvaser_pciefd_read_buffer(pcie, 1);
-		/* Reset DMA buffer 1 */
-		iowrite32(KVASER_PCIEFD_SRB_CMD_RDB1,
-			  KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
-	}
 
 	if (irq & KVASER_PCIEFD_SRB_IRQ_DOF0 ||
 	    irq & KVASER_PCIEFD_SRB_IRQ_DOF1 ||
@@ -1605,6 +1597,7 @@
 		dev_err(&pcie->pci->dev, "DMA IRQ error 0x%08X\n", irq);
 
 	iowrite32(irq, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_IRQ_REG);
+	return irq;
 }
 
 static void kvaser_pciefd_transmit_irq(struct kvaser_pciefd_can *can)
@@ -1631,27 +1624,31 @@
 {
 	struct kvaser_pciefd *pcie = (struct kvaser_pciefd *)dev;
 	const struct kvaser_pciefd_irq_mask *irq_mask = pcie->driver_data->irq_mask;
-	u32 board_irq = ioread32(KVASER_PCIEFD_PCI_IRQ_ADDR(pcie));
+	u32 pci_irq = ioread32(KVASER_PCIEFD_PCI_IRQ_ADDR(pcie));
+	u32 srb_irq = 0;
+	u32 srb_release = 0;
 	int i;
 
-	if (!(board_irq & irq_mask->all))
+	if (!(pci_irq & irq_mask->all))
 		return IRQ_NONE;
 
-	if (board_irq & irq_mask->kcan_rx0)
-		kvaser_pciefd_receive_irq(pcie);
+	if (pci_irq & irq_mask->kcan_rx0)
+		srb_irq = kvaser_pciefd_receive_irq(pcie);
 
 	for (i = 0; i < pcie->nr_channels; i++) {
-		if (!pcie->can[i]) {
-			dev_err(&pcie->pci->dev,
-				"IRQ mask points to unallocated controller\n");
-			break;
-		}
-
-		/* Check that mask matches channel (i) IRQ mask */
-		if (board_irq & irq_mask->kcan_tx[i])
+		if (pci_irq & irq_mask->kcan_tx[i])
 			kvaser_pciefd_transmit_irq(pcie->can[i]);
 	}
 
+	if (srb_irq & KVASER_PCIEFD_SRB_IRQ_DPD0)
+		srb_release |= KVASER_PCIEFD_SRB_CMD_RDB0;
+
+	if (srb_irq & KVASER_PCIEFD_SRB_IRQ_DPD1)
+		srb_release |= KVASER_PCIEFD_SRB_CMD_RDB1;
+
+	if (srb_release)
+		iowrite32(srb_release, KVASER_PCIEFD_SRB_ADDR(pcie) + KVASER_PCIEFD_SRB_CMD_REG);
+
 	return IRQ_HANDLED;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/can/m_can/m_can.c
+++ linux-qcom-6.8.0/drivers/net/can/m_can/m_can.c
@@ -418,6 +418,13 @@
 
 static inline void m_can_enable_all_interrupts(struct m_can_classdev *cdev)
 {
+	if (!cdev->net->irq) {
+		dev_dbg(cdev->dev, "Start hrtimer\n");
+		hrtimer_start(&cdev->hrtimer,
+			      ms_to_ktime(HRTIMER_POLL_INTERVAL_MS),
+			      HRTIMER_MODE_REL_PINNED);
+	}
+
 	/* Only interrupt line 0 is used in this driver */
 	m_can_write(cdev, M_CAN_ILE, ILE_EINT0);
 }
@@ -425,6 +432,11 @@
 static inline void m_can_disable_all_interrupts(struct m_can_classdev *cdev)
 {
 	m_can_write(cdev, M_CAN_ILE, 0x0);
+
+	if (!cdev->net->irq) {
+		dev_dbg(cdev->dev, "Stop hrtimer\n");
+		hrtimer_try_to_cancel(&cdev->hrtimer);
+	}
 }
 
 /* Retrieve internal timestamp counter from TSCV.TSC, and shift it to 32-bit
@@ -624,47 +636,60 @@
 	u32 timestamp = 0;
 
 	cdev->can.can_stats.bus_error++;
-	stats->rx_errors++;
 
 	/* propagate the error condition to the CAN stack */
 	skb = alloc_can_err_skb(dev, &cf);
-	if (unlikely(!skb))
-		return 0;
 
 	/* check for 'last error code' which tells us the
 	 * type of the last error to occur on the CAN bus
 	 */
-	cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+	if (likely(skb))
+		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
 	switch (lec_type) {
 	case LEC_STUFF_ERROR:
 		netdev_dbg(dev, "stuff error\n");
-		cf->data[2] |= CAN_ERR_PROT_STUFF;
+		stats->rx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_STUFF;
 		break;
 	case LEC_FORM_ERROR:
 		netdev_dbg(dev, "form error\n");
-		cf->data[2] |= CAN_ERR_PROT_FORM;
+		stats->rx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_FORM;
 		break;
 	case LEC_ACK_ERROR:
 		netdev_dbg(dev, "ack error\n");
-		cf->data[3] = CAN_ERR_PROT_LOC_ACK;
+		stats->tx_errors++;
+		if (likely(skb))
+			cf->data[3] = CAN_ERR_PROT_LOC_ACK;
 		break;
 	case LEC_BIT1_ERROR:
 		netdev_dbg(dev, "bit1 error\n");
-		cf->data[2] |= CAN_ERR_PROT_BIT1;
+		stats->tx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_BIT1;
 		break;
 	case LEC_BIT0_ERROR:
 		netdev_dbg(dev, "bit0 error\n");
-		cf->data[2] |= CAN_ERR_PROT_BIT0;
+		stats->tx_errors++;
+		if (likely(skb))
+			cf->data[2] |= CAN_ERR_PROT_BIT0;
 		break;
 	case LEC_CRC_ERROR:
 		netdev_dbg(dev, "CRC error\n");
-		cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
+		stats->rx_errors++;
+		if (likely(skb))
+			cf->data[3] = CAN_ERR_PROT_LOC_CRC_SEQ;
 		break;
 	default:
 		break;
 	}
 
+	if (unlikely(!skb))
+		return 0;
+
 	if (cdev->is_peripheral)
 		timestamp = m_can_get_timestamp(cdev);
 
@@ -965,22 +990,6 @@
 	return work_done;
 }
 
-static int m_can_rx_peripheral(struct net_device *dev, u32 irqstatus)
-{
-	struct m_can_classdev *cdev = netdev_priv(dev);
-	int work_done;
-
-	work_done = m_can_rx_handler(dev, NAPI_POLL_WEIGHT, irqstatus);
-
-	/* Don't re-enable interrupts if the driver had a fatal error
-	 * (e.g., FIFO read failure).
-	 */
-	if (work_done < 0)
-		m_can_disable_all_interrupts(cdev);
-
-	return work_done;
-}
-
 static int m_can_poll(struct napi_struct *napi, int quota)
 {
 	struct net_device *dev = napi->dev;
@@ -1073,21 +1082,38 @@
 	return err;
 }
 
-static irqreturn_t m_can_isr(int irq, void *dev_id)
+/* This interrupt handler is called either from the interrupt thread or a
+ * hrtimer. This has implications like cancelling a timer won't be possible
+ * blocking.
+ */
+static int m_can_interrupt_handler(struct m_can_classdev *cdev)
 {
-	struct net_device *dev = (struct net_device *)dev_id;
-	struct m_can_classdev *cdev = netdev_priv(dev);
-	u32 ir;
+	struct net_device *dev = cdev->net;
+	u32 ir = 0, ir_read;
+	int ret;
 
 	if (pm_runtime_suspended(cdev->dev))
 		return IRQ_NONE;
-	ir = m_can_read(cdev, M_CAN_IR);
+
+	/* The m_can controller signals its interrupt status as a level, but
+	 * depending in the integration the CPU may interpret the signal as
+	 * edge-triggered (for example with m_can_pci). For these
+	 * edge-triggered integrations, we must observe that IR is 0 at least
+	 * once to be sure that the next interrupt will generate an edge.
+	 */
+	while ((ir_read = m_can_read(cdev, M_CAN_IR)) != 0) {
+		ir |= ir_read;
+
+		/* ACK all irqs */
+		m_can_write(cdev, M_CAN_IR, ir);
+
+		if (!cdev->irq_edge_triggered)
+			break;
+	}
+
 	if (!ir)
 		return IRQ_NONE;
 
-	/* ACK all irqs */
-	m_can_write(cdev, M_CAN_IR, ir);
-
 	if (cdev->ops->clear_interrupts)
 		cdev->ops->clear_interrupts(cdev);
 
@@ -1101,8 +1127,10 @@
 		if (!cdev->is_peripheral) {
 			m_can_disable_all_interrupts(cdev);
 			napi_schedule(&cdev->napi);
-		} else if (m_can_rx_peripheral(dev, ir) < 0) {
-			goto out_fail;
+		} else {
+			ret = m_can_rx_handler(dev, NAPI_POLL_WEIGHT, ir);
+			if (ret < 0)
+				return ret;
 		}
 	}
 
@@ -1119,8 +1147,9 @@
 	} else  {
 		if (ir & IR_TEFN) {
 			/* New TX FIFO Element arrived */
-			if (m_can_echo_tx_event(dev) != 0)
-				goto out_fail;
+			ret = m_can_echo_tx_event(dev);
+			if (ret != 0)
+				return ret;
 
 			if (netif_queue_stopped(dev) &&
 			    !m_can_tx_fifo_full(cdev))
@@ -1132,10 +1161,21 @@
 		can_rx_offload_threaded_irq_finish(&cdev->offload);
 
 	return IRQ_HANDLED;
+}
 
-out_fail:
-	m_can_disable_all_interrupts(cdev);
-	return IRQ_HANDLED;
+static irqreturn_t m_can_isr(int irq, void *dev_id)
+{
+	struct net_device *dev = (struct net_device *)dev_id;
+	struct m_can_classdev *cdev = netdev_priv(dev);
+	int ret;
+
+	ret =  m_can_interrupt_handler(cdev);
+	if (ret < 0) {
+		m_can_disable_all_interrupts(cdev);
+		return IRQ_HANDLED;
+	}
+
+	return ret;
 }
 
 static const struct can_bittiming_const m_can_bittiming_const_30X = {
@@ -1417,12 +1457,6 @@
 
 	m_can_enable_all_interrupts(cdev);
 
-	if (!dev->irq) {
-		dev_dbg(cdev->dev, "Start hrtimer\n");
-		hrtimer_start(&cdev->hrtimer, ms_to_ktime(HRTIMER_POLL_INTERVAL_MS),
-			      HRTIMER_MODE_REL_PINNED);
-	}
-
 	return 0;
 }
 
@@ -1577,11 +1611,6 @@
 {
 	struct m_can_classdev *cdev = netdev_priv(dev);
 
-	if (!dev->irq) {
-		dev_dbg(cdev->dev, "Stop hrtimer\n");
-		hrtimer_cancel(&cdev->hrtimer);
-	}
-
 	/* disable all interrupts */
 	m_can_disable_all_interrupts(cdev);
 
@@ -1598,22 +1627,22 @@
 
 	netif_stop_queue(dev);
 
-	if (!cdev->is_peripheral)
-		napi_disable(&cdev->napi);
-
 	m_can_stop(dev);
-	m_can_clk_stop(cdev);
-	free_irq(dev->irq, dev);
+	if (dev->irq)
+		free_irq(dev->irq, dev);
 
 	if (cdev->is_peripheral) {
 		cdev->tx_skb = NULL;
 		destroy_workqueue(cdev->tx_wq);
 		cdev->tx_wq = NULL;
 		can_rx_offload_disable(&cdev->offload);
+	} else {
+		napi_disable(&cdev->napi);
 	}
 
 	close_candev(dev);
 
+	m_can_clk_stop(cdev);
 	phy_power_off(cdev->transceiver);
 
 	return 0;
@@ -1811,8 +1840,17 @@
 {
 	struct m_can_classdev *cdev = container_of(timer, struct
 						   m_can_classdev, hrtimer);
+	int ret;
 
-	m_can_isr(0, cdev->net);
+	if (cdev->can.state == CAN_STATE_BUS_OFF ||
+	    cdev->can.state == CAN_STATE_STOPPED)
+		return HRTIMER_NORESTART;
+
+	ret = m_can_interrupt_handler(cdev);
+
+	/* On error or if napi is scheduled to read, stop the timer */
+	if (ret < 0 || napi_is_scheduled(&cdev->napi))
+		return HRTIMER_NORESTART;
 
 	hrtimer_forward_now(timer, ms_to_ktime(HRTIMER_POLL_INTERVAL_MS));
 
@@ -1841,6 +1879,8 @@
 
 	if (cdev->is_peripheral)
 		can_rx_offload_enable(&cdev->offload);
+	else
+		napi_enable(&cdev->napi);
 
 	/* register interrupt handler */
 	if (cdev->is_peripheral) {
@@ -1870,21 +1910,23 @@
 	/* start the m_can controller */
 	err = m_can_start(dev);
 	if (err)
-		goto exit_irq_fail;
-
-	if (!cdev->is_peripheral)
-		napi_enable(&cdev->napi);
+		goto exit_start_fail;
 
 	netif_start_queue(dev);
 
 	return 0;
 
+exit_start_fail:
+	if (cdev->is_peripheral || dev->irq)
+		free_irq(dev->irq, dev);
 exit_irq_fail:
 	if (cdev->is_peripheral)
 		destroy_workqueue(cdev->tx_wq);
 out_wq_fail:
 	if (cdev->is_peripheral)
 		can_rx_offload_disable(&cdev->offload);
+	else
+		napi_disable(&cdev->napi);
 	close_candev(dev);
 exit_disable_clks:
 	m_can_clk_stop(cdev);
--- linux-qcom-6.8.0.orig/drivers/net/can/m_can/m_can.h
+++ linux-qcom-6.8.0/drivers/net/can/m_can/m_can.h
@@ -91,6 +91,7 @@
 
 	int pm_clock_support;
 	int is_peripheral;
+	bool irq_edge_triggered;
 
 	struct mram_cfg mcfg[MRAM_CFG_NUM];
 
--- linux-qcom-6.8.0.orig/drivers/net/can/m_can/m_can_pci.c
+++ linux-qcom-6.8.0/drivers/net/can/m_can/m_can_pci.c
@@ -126,6 +126,7 @@
 	mcan_class->net->irq = pci_irq_vector(pci, 0);
 	mcan_class->pm_clock_support = 1;
 	mcan_class->can.clock.freq = id->driver_data;
+	mcan_class->irq_edge_triggered = true;
 	mcan_class->ops = &m_can_pci_ops;
 
 	pci_set_drvdata(pci, mcan_class);
--- linux-qcom-6.8.0.orig/drivers/net/can/sja1000/sja1000.c
+++ linux-qcom-6.8.0/drivers/net/can/sja1000/sja1000.c
@@ -416,8 +416,6 @@
 	int ret = 0;
 
 	skb = alloc_can_err_skb(dev, &cf);
-	if (skb == NULL)
-		return -ENOMEM;
 
 	txerr = priv->read_reg(priv, SJA1000_TXERR);
 	rxerr = priv->read_reg(priv, SJA1000_RXERR);
@@ -425,8 +423,11 @@
 	if (isrc & IRQ_DOI) {
 		/* data overrun interrupt */
 		netdev_dbg(dev, "data overrun interrupt\n");
-		cf->can_id |= CAN_ERR_CRTL;
-		cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+		if (skb) {
+			cf->can_id |= CAN_ERR_CRTL;
+			cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+		}
+
 		stats->rx_over_errors++;
 		stats->rx_errors++;
 		sja1000_write_cmdreg(priv, CMD_CDO);	/* clear bit */
@@ -452,7 +453,7 @@
 		else
 			state = CAN_STATE_ERROR_ACTIVE;
 	}
-	if (state != CAN_STATE_BUS_OFF) {
+	if (state != CAN_STATE_BUS_OFF && skb) {
 		cf->can_id |= CAN_ERR_CNT;
 		cf->data[6] = txerr;
 		cf->data[7] = rxerr;
@@ -460,33 +461,38 @@
 	if (isrc & IRQ_BEI) {
 		/* bus error interrupt */
 		priv->can.can_stats.bus_error++;
-		stats->rx_errors++;
 
 		ecc = priv->read_reg(priv, SJA1000_ECC);
+		if (skb) {
+			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
-		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+			/* set error type */
+			switch (ecc & ECC_MASK) {
+			case ECC_BIT:
+				cf->data[2] |= CAN_ERR_PROT_BIT;
+				break;
+			case ECC_FORM:
+				cf->data[2] |= CAN_ERR_PROT_FORM;
+				break;
+			case ECC_STUFF:
+				cf->data[2] |= CAN_ERR_PROT_STUFF;
+				break;
+			default:
+				break;
+			}
 
-		/* set error type */
-		switch (ecc & ECC_MASK) {
-		case ECC_BIT:
-			cf->data[2] |= CAN_ERR_PROT_BIT;
-			break;
-		case ECC_FORM:
-			cf->data[2] |= CAN_ERR_PROT_FORM;
-			break;
-		case ECC_STUFF:
-			cf->data[2] |= CAN_ERR_PROT_STUFF;
-			break;
-		default:
-			break;
+			/* set error location */
+			cf->data[3] = ecc & ECC_SEG;
 		}
 
-		/* set error location */
-		cf->data[3] = ecc & ECC_SEG;
-
 		/* Error occurred during transmission? */
-		if ((ecc & ECC_DIR) == 0)
-			cf->data[2] |= CAN_ERR_PROT_TX;
+		if ((ecc & ECC_DIR) == 0) {
+			stats->tx_errors++;
+			if (skb)
+				cf->data[2] |= CAN_ERR_PROT_TX;
+		} else {
+			stats->rx_errors++;
+		}
 	}
 	if (isrc & IRQ_EPI) {
 		/* error passive interrupt */
@@ -502,8 +508,10 @@
 		netdev_dbg(dev, "arbitration lost interrupt\n");
 		alc = priv->read_reg(priv, SJA1000_ALC);
 		priv->can.can_stats.arbitration_lost++;
-		cf->can_id |= CAN_ERR_LOSTARB;
-		cf->data[0] = alc & 0x1f;
+		if (skb) {
+			cf->can_id |= CAN_ERR_LOSTARB;
+			cf->data[0] = alc & 0x1f;
+		}
 	}
 
 	if (state != priv->can.state) {
@@ -516,6 +524,9 @@
 			can_bus_off(dev);
 	}
 
+	if (!skb)
+		return -ENOMEM;
+
 	netif_rx(skb);
 
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/net/can/spi/hi311x.c
+++ linux-qcom-6.8.0/drivers/net/can/spi/hi311x.c
@@ -671,9 +671,9 @@
 			tx_state = txerr >= rxerr ? new_state : 0;
 			rx_state = txerr <= rxerr ? new_state : 0;
 			can_change_state(net, cf, tx_state, rx_state);
-			netif_rx(skb);
 
 			if (new_state == CAN_STATE_BUS_OFF) {
+				netif_rx(skb);
 				can_bus_off(net);
 				if (priv->can.restart_ms == 0) {
 					priv->force_quit = 1;
@@ -684,6 +684,7 @@
 				cf->can_id |= CAN_ERR_CNT;
 				cf->data[6] = txerr;
 				cf->data[7] = rxerr;
+				netif_rx(skb);
 			}
 		}
 
@@ -696,27 +697,38 @@
 			/* Check for protocol errors */
 			if (eflag & HI3110_ERR_PROTOCOL_MASK) {
 				skb = alloc_can_err_skb(net, &cf);
-				if (!skb)
-					break;
+				if (skb)
+					cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
-				cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 				priv->can.can_stats.bus_error++;
-				priv->net->stats.rx_errors++;
-				if (eflag & HI3110_ERR_BITERR)
-					cf->data[2] |= CAN_ERR_PROT_BIT;
-				else if (eflag & HI3110_ERR_FRMERR)
-					cf->data[2] |= CAN_ERR_PROT_FORM;
-				else if (eflag & HI3110_ERR_STUFERR)
-					cf->data[2] |= CAN_ERR_PROT_STUFF;
-				else if (eflag & HI3110_ERR_CRCERR)
-					cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
-				else if (eflag & HI3110_ERR_ACKERR)
-					cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
+				if (eflag & HI3110_ERR_BITERR) {
+					priv->net->stats.tx_errors++;
+					if (skb)
+						cf->data[2] |= CAN_ERR_PROT_BIT;
+				} else if (eflag & HI3110_ERR_FRMERR) {
+					priv->net->stats.rx_errors++;
+					if (skb)
+						cf->data[2] |= CAN_ERR_PROT_FORM;
+				} else if (eflag & HI3110_ERR_STUFERR) {
+					priv->net->stats.rx_errors++;
+					if (skb)
+						cf->data[2] |= CAN_ERR_PROT_STUFF;
+				} else if (eflag & HI3110_ERR_CRCERR) {
+					priv->net->stats.rx_errors++;
+					if (skb)
+						cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
+				} else if (eflag & HI3110_ERR_ACKERR) {
+					priv->net->stats.tx_errors++;
+					if (skb)
+						cf->data[3] |= CAN_ERR_PROT_LOC_ACK;
+				}
 
-				cf->data[6] = hi3110_read(spi, HI3110_READ_TEC);
-				cf->data[7] = hi3110_read(spi, HI3110_READ_REC);
 				netdev_dbg(priv->net, "Bus Error\n");
-				netif_rx(skb);
+				if (skb) {
+					cf->data[6] = hi3110_read(spi, HI3110_READ_TEC);
+					cf->data[7] = hi3110_read(spi, HI3110_READ_REC);
+					netif_rx(skb);
+				}
 			}
 		}
 
--- linux-qcom-6.8.0.orig/drivers/net/can/spi/mcp251x.c
+++ linux-qcom-6.8.0/drivers/net/can/spi/mcp251x.c
@@ -753,7 +753,7 @@
 	int ret;
 
 	/* Force wakeup interrupt to wake device, but don't execute IST */
-	disable_irq(spi->irq);
+	disable_irq_nosync(spi->irq);
 	mcp251x_write_2regs(spi, CANINTE, CANINTE_WAKIE, CANINTF_WAKIF);
 
 	/* Wait for oscillator startup timer after wake up */
--- linux-qcom-6.8.0.orig/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
+++ linux-qcom-6.8.0/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c
@@ -2,7 +2,7 @@
 //
 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
 //
-// Copyright (c) 2019, 2020, 2021 Pengutronix,
+// Copyright (c) 2019, 2020, 2021, 2023 Pengutronix,
 //               Marc Kleine-Budde <kernel@pengutronix.de>
 //
 // Based on:
@@ -153,6 +153,21 @@
 	return regulator_disable(priv->reg_vdd);
 }
 
+static int
+mcp251xfd_transceiver_mode(const struct mcp251xfd_priv *priv,
+			   const enum mcp251xfd_xceiver_mode mode)
+{
+	int val;
+
+	if (mode == MCP251XFD_XCVR_NORMAL_MODE)
+		val = MCP251XFD_REG_IOCON_PM0;
+	else if (mode == MCP251XFD_XCVR_STBY_MODE)
+		val = (MCP251XFD_REG_IOCON_TRIS0 | MCP251XFD_REG_IOCON_PM0 |
+		MCP251XFD_REG_IOCON_LAT0);
+
+	return regmap_write(priv->map_reg, MCP251XFD_REG_IOCON, val);
+}
+
 static inline int
 mcp251xfd_transceiver_enable(const struct mcp251xfd_priv *priv)
 {
@@ -744,6 +759,7 @@
 
 	mcp251xfd_chip_interrupts_disable(priv);
 	mcp251xfd_chip_rx_int_disable(priv);
+	mcp251xfd_timestamp_stop(priv);
 	mcp251xfd_chip_sleep(priv);
 }
 
@@ -763,6 +779,8 @@
 	if (err)
 		goto out_chip_stop;
 
+	mcp251xfd_timestamp_start(priv);
+
 	err = mcp251xfd_set_bittiming(priv);
 	if (err)
 		goto out_chip_stop;
@@ -791,7 +809,7 @@
 
 	return 0;
 
- out_chip_stop:
+out_chip_stop:
 	mcp251xfd_dump(priv);
 	mcp251xfd_chip_stop(priv, CAN_STATE_STOPPED);
 
@@ -867,18 +885,18 @@
 
 static struct sk_buff *
 mcp251xfd_alloc_can_err_skb(struct mcp251xfd_priv *priv,
-			    struct can_frame **cf, u32 *timestamp)
+			    struct can_frame **cf, u32 *ts_raw)
 {
 	struct sk_buff *skb;
 	int err;
 
-	err = mcp251xfd_get_timestamp(priv, timestamp);
+	err = mcp251xfd_get_timestamp_raw(priv, ts_raw);
 	if (err)
 		return NULL;
 
 	skb = alloc_can_err_skb(priv->ndev, cf);
 	if (skb)
-		mcp251xfd_skb_set_timestamp(priv, skb, *timestamp);
+		mcp251xfd_skb_set_timestamp_raw(priv, skb, *ts_raw);
 
 	return skb;
 }
@@ -889,7 +907,7 @@
 	struct mcp251xfd_rx_ring *ring;
 	struct sk_buff *skb;
 	struct can_frame *cf;
-	u32 timestamp, rxovif;
+	u32 ts_raw, rxovif;
 	int err, i;
 
 	stats->rx_over_errors++;
@@ -924,14 +942,14 @@
 			return err;
 	}
 
-	skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &timestamp);
+	skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &ts_raw);
 	if (!skb)
 		return 0;
 
 	cf->can_id |= CAN_ERR_CRTL;
 	cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
 
-	err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
+	err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw);
 	if (err)
 		stats->rx_fifo_errors++;
 
@@ -948,12 +966,12 @@
 static int mcp251xfd_handle_ivmif(struct mcp251xfd_priv *priv)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
-	u32 bdiag1, timestamp;
+	u32 bdiag1, ts_raw;
 	struct sk_buff *skb;
 	struct can_frame *cf = NULL;
 	int err;
 
-	err = mcp251xfd_get_timestamp(priv, &timestamp);
+	err = mcp251xfd_get_timestamp_raw(priv, &ts_raw);
 	if (err)
 		return err;
 
@@ -1035,8 +1053,8 @@
 	if (!cf)
 		return 0;
 
-	mcp251xfd_skb_set_timestamp(priv, skb, timestamp);
-	err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
+	mcp251xfd_skb_set_timestamp_raw(priv, skb, ts_raw);
+	err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw);
 	if (err)
 		stats->rx_fifo_errors++;
 
@@ -1049,7 +1067,7 @@
 	struct sk_buff *skb;
 	struct can_frame *cf = NULL;
 	enum can_state new_state, rx_state, tx_state;
-	u32 trec, timestamp;
+	u32 trec, ts_raw;
 	int err;
 
 	err = regmap_read(priv->map_reg, MCP251XFD_REG_TREC, &trec);
@@ -1079,7 +1097,7 @@
 	/* The skb allocation might fail, but can_change_state()
 	 * handles cf == NULL.
 	 */
-	skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &timestamp);
+	skb = mcp251xfd_alloc_can_err_skb(priv, &cf, &ts_raw);
 	can_change_state(priv->ndev, cf, tx_state, rx_state);
 
 	if (new_state == CAN_STATE_BUS_OFF) {
@@ -1110,7 +1128,7 @@
 		cf->data[7] = bec.rxerr;
 	}
 
-	err = can_rx_offload_queue_timestamp(&priv->offload, skb, timestamp);
+	err = can_rx_offload_queue_timestamp(&priv->offload, skb, ts_raw);
 	if (err)
 		stats->rx_fifo_errors++;
 
@@ -1576,7 +1594,7 @@
 		handled = IRQ_HANDLED;
 	} while (1);
 
- out_fail:
+out_fail:
 	can_rx_offload_threaded_irq_finish(&priv->offload);
 
 	netdev_err(priv->ndev, "IRQ handler returned %d (intf=0x%08x).\n",
@@ -1610,19 +1628,33 @@
 	if (err)
 		goto out_mcp251xfd_ring_free;
 
+	mcp251xfd_timestamp_init(priv);
+
 	err = mcp251xfd_chip_start(priv);
 	if (err)
 		goto out_transceiver_disable;
 
-	mcp251xfd_timestamp_init(priv);
+	err = mcp251xfd_transceiver_mode(priv, MCP251XFD_XCVR_NORMAL_MODE);
+	if (err)
+		goto out_transceiver_disable;
+
 	clear_bit(MCP251XFD_FLAGS_DOWN, priv->flags);
 	can_rx_offload_enable(&priv->offload);
 
+	priv->wq = alloc_ordered_workqueue("%s-mcp251xfd_wq",
+					   WQ_FREEZABLE | WQ_MEM_RECLAIM,
+					   dev_name(&spi->dev));
+	if (!priv->wq) {
+		err = -ENOMEM;
+		goto out_can_rx_offload_disable;
+	}
+	INIT_WORK(&priv->tx_work, mcp251xfd_tx_obj_write_sync);
+
 	err = request_threaded_irq(spi->irq, NULL, mcp251xfd_irq,
 				   IRQF_SHARED | IRQF_ONESHOT,
 				   dev_name(&spi->dev), priv);
 	if (err)
-		goto out_can_rx_offload_disable;
+		goto out_destroy_workqueue;
 
 	err = mcp251xfd_chip_interrupts_enable(priv);
 	if (err)
@@ -1632,20 +1664,21 @@
 
 	return 0;
 
- out_free_irq:
+out_free_irq:
 	free_irq(spi->irq, priv);
- out_can_rx_offload_disable:
+out_destroy_workqueue:
+	destroy_workqueue(priv->wq);
+out_can_rx_offload_disable:
 	can_rx_offload_disable(&priv->offload);
 	set_bit(MCP251XFD_FLAGS_DOWN, priv->flags);
-	mcp251xfd_timestamp_stop(priv);
- out_transceiver_disable:
+out_transceiver_disable:
 	mcp251xfd_transceiver_disable(priv);
- out_mcp251xfd_ring_free:
+out_mcp251xfd_ring_free:
 	mcp251xfd_ring_free(priv);
- out_pm_runtime_put:
+out_pm_runtime_put:
 	mcp251xfd_chip_stop(priv, CAN_STATE_STOPPED);
 	pm_runtime_put(ndev->dev.parent);
- out_close_candev:
+out_close_candev:
 	close_candev(ndev);
 
 	return err;
@@ -1653,6 +1686,7 @@
 
 static int mcp251xfd_stop(struct net_device *ndev)
 {
+	int err;
 	struct mcp251xfd_priv *priv = netdev_priv(ndev);
 
 	netif_stop_queue(ndev);
@@ -1661,8 +1695,12 @@
 	hrtimer_cancel(&priv->tx_irq_timer);
 	mcp251xfd_chip_interrupts_disable(priv);
 	free_irq(ndev->irq, priv);
+	destroy_workqueue(priv->wq);
 	can_rx_offload_disable(&priv->offload);
-	mcp251xfd_timestamp_stop(priv);
+
+	err = mcp251xfd_transceiver_mode(priv, MCP251XFD_XCVR_STBY_MODE);
+	if (err)
+		return err;
 	mcp251xfd_chip_stop(priv, CAN_STATE_STOPPED);
 	mcp251xfd_transceiver_disable(priv);
 	mcp251xfd_ring_free(priv);
@@ -1808,9 +1846,9 @@
 	*effective_speed_hz_slow = xfer[0].effective_speed_hz;
 	*effective_speed_hz_fast = xfer[1].effective_speed_hz;
 
- out_kfree_buf_tx:
+out_kfree_buf_tx:
 	kfree(buf_tx);
- out_kfree_buf_rx:
+out_kfree_buf_rx:
 	kfree(buf_rx);
 
 	return err;
@@ -1924,13 +1962,13 @@
 
 	return 0;
 
- out_unregister_candev:
+out_unregister_candev:
 	unregister_candev(ndev);
- out_chip_sleep:
+out_chip_sleep:
 	mcp251xfd_chip_sleep(priv);
- out_runtime_disable:
+out_runtime_disable:
 	pm_runtime_disable(ndev->dev.parent);
- out_runtime_put_noidle:
+out_runtime_put_noidle:
 	pm_runtime_put_noidle(ndev->dev.parent);
 	mcp251xfd_clks_and_vdd_disable(priv);
 
@@ -2150,9 +2188,9 @@
 
 	return 0;
 
- out_can_rx_offload_del:
+out_can_rx_offload_del:
 	can_rx_offload_del(&priv->offload);
- out_free_candev:
+out_free_candev:
 	spi->max_speed_hz = priv->spi_max_speed_hz_orig;
 
 	free_candev(ndev);
--- linux-qcom-6.8.0.orig/drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c
+++ linux-qcom-6.8.0/drivers/net/can/spi/mcp251xfd/mcp251xfd-dump.c
@@ -94,7 +94,7 @@
 		kfree(buf);
 	}
 
- out:
+out:
 	mcp251xfd_dump_header(iter, MCP251XFD_DUMP_OBJECT_TYPE_REG, reg);
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/can/spi/mcp251xfd/mcp251xfd-ram.c
+++ linux-qcom-6.8.0/drivers/net/can/spi/mcp251xfd/mcp251xfd-ram.c
@@ -97,7 +97,16 @@
 	if (ring) {
 		u8 num_rx_coalesce = 0, num_tx_coalesce = 0;
 
-		num_rx = can_ram_rounddown_pow_of_two(config, &config->rx, 0, ring->rx_pending);
+		/* If the ring parameters have been configured in
+		 * CAN-CC mode, but and we are in CAN-FD mode now,
+		 * they might be to big. Use the default CAN-FD values
+		 * in this case.
+		 */
+		num_rx = ring->rx_pending;
+		if (num_rx > layout->max_rx)
+			num_rx = layout->default_rx;
+
+		num_rx = can_ram_rounddown_pow_of_two(config, &config->rx, 0, num_rx);
 
 		/* The ethtool doc says:
 		 * To disable coalescing, set usecs = 0 and max_frames = 1.
--- linux-qcom-6.8.0.orig/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
+++ linux-qcom-6.8.0/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c
@@ -397,7 +397,7 @@
 
 		return err;
 	}
- out:
+out:
 	memcpy(val_buf, buf_rx->data, val_len);
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
+++ linux-qcom-6.8.0/drivers/net/can/spi/mcp251xfd/mcp251xfd-ring.c
@@ -2,7 +2,7 @@
 //
 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
 //
-// Copyright (c) 2019, 2020, 2021 Pengutronix,
+// Copyright (c) 2019, 2020, 2021, 2024 Pengutronix,
 //               Marc Kleine-Budde <kernel@pengutronix.de>
 //
 // Based on:
@@ -206,6 +206,7 @@
 	int i, j;
 
 	mcp251xfd_for_each_rx_ring(priv, rx_ring, i) {
+		rx_ring->last_valid = timecounter_read(&priv->tc);
 		rx_ring->head = 0;
 		rx_ring->tail = 0;
 		rx_ring->base = *base;
@@ -289,7 +290,7 @@
 	const struct mcp251xfd_rx_ring *rx_ring;
 	u16 base = 0, ram_used;
 	u8 fifo_nr = 1;
-	int i;
+	int err = 0, i;
 
 	netdev_reset_queue(priv->ndev);
 
@@ -385,10 +386,18 @@
 		netdev_err(priv->ndev,
 			   "Error during ring configuration, using more RAM (%u bytes) than available (%u bytes).\n",
 			   ram_used, MCP251XFD_RAM_SIZE);
-		return -ENOMEM;
+		err = -ENOMEM;
+	}
+
+	if (priv->tx_obj_num_coalesce_irq &&
+	    priv->tx_obj_num_coalesce_irq * 2 != priv->tx->obj_num) {
+		netdev_err(priv->ndev,
+			   "Error during ring configuration, number of TEF coalescing buffers (%u) must be half of TEF buffers (%u).\n",
+			   priv->tx_obj_num_coalesce_irq, priv->tx->obj_num);
+		err = -EINVAL;
 	}
 
-	return 0;
+	return err;
 }
 
 void mcp251xfd_ring_free(struct mcp251xfd_priv *priv)
@@ -468,11 +477,27 @@
 
 	/* switching from CAN-2.0 to CAN-FD mode or vice versa */
 	if (fd_mode != test_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags)) {
+		const struct ethtool_ringparam ring = {
+			.rx_pending = priv->rx_obj_num,
+			.tx_pending = priv->tx->obj_num,
+		};
+		const struct ethtool_coalesce ec = {
+			.rx_coalesce_usecs_irq = priv->rx_coalesce_usecs_irq,
+			.rx_max_coalesced_frames_irq = priv->rx_obj_num_coalesce_irq == 0 ?
+				1 : priv->rx_obj_num_coalesce_irq,
+			.tx_coalesce_usecs_irq = priv->tx_coalesce_usecs_irq,
+			.tx_max_coalesced_frames_irq = priv->tx_obj_num_coalesce_irq == 0 ?
+				1 : priv->tx_obj_num_coalesce_irq,
+		};
 		struct can_ram_layout layout;
 
-		can_ram_get_layout(&layout, &mcp251xfd_ram_config, NULL, NULL, fd_mode);
-		priv->rx_obj_num = layout.default_rx;
-		tx_ring->obj_num = layout.default_tx;
+		can_ram_get_layout(&layout, &mcp251xfd_ram_config, &ring, &ec, fd_mode);
+
+		priv->rx_obj_num = layout.cur_rx;
+		priv->rx_obj_num_coalesce_irq = layout.rx_coalesce;
+
+		tx_ring->obj_num = layout.cur_tx;
+		priv->tx_obj_num_coalesce_irq = layout.tx_coalesce;
 	}
 
 	if (fd_mode) {
@@ -485,6 +510,8 @@
 		clear_bit(MCP251XFD_FLAGS_FD_MODE, priv->flags);
 	}
 
+	tx_ring->obj_num_shift_to_u8 = BITS_PER_TYPE(tx_ring->obj_num) -
+		ilog2(tx_ring->obj_num);
 	tx_ring->obj_size = tx_obj_size;
 
 	rem = priv->rx_obj_num;
@@ -507,6 +534,8 @@
 		}
 
 		rx_ring->obj_num = rx_obj_num;
+		rx_ring->obj_num_shift_to_u8 = BITS_PER_TYPE(rx_ring->obj_num_shift_to_u8) -
+			ilog2(rx_obj_num);
 		rx_ring->obj_size = rx_obj_size;
 		priv->rx[i] = rx_ring;
 	}
--- linux-qcom-6.8.0.orig/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
+++ linux-qcom-6.8.0/drivers/net/can/spi/mcp251xfd/mcp251xfd-rx.c
@@ -2,7 +2,7 @@
 //
 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
 //
-// Copyright (c) 2019, 2020, 2021 Pengutronix,
+// Copyright (c) 2019, 2020, 2021, 2023 Pengutronix,
 //               Marc Kleine-Budde <kernel@pengutronix.de>
 //
 // Based on:
@@ -16,23 +16,14 @@
 
 #include "mcp251xfd.h"
 
-static inline int
-mcp251xfd_rx_head_get_from_chip(const struct mcp251xfd_priv *priv,
-				const struct mcp251xfd_rx_ring *ring,
-				u8 *rx_head, bool *fifo_empty)
+static inline bool mcp251xfd_rx_fifo_sta_empty(const u32 fifo_sta)
 {
-	u32 fifo_sta;
-	int err;
-
-	err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(ring->fifo_nr),
-			  &fifo_sta);
-	if (err)
-		return err;
-
-	*rx_head = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta);
-	*fifo_empty = !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF);
+	return !(fifo_sta & MCP251XFD_REG_FIFOSTA_TFNRFNIF);
+}
 
-	return 0;
+static inline bool mcp251xfd_rx_fifo_sta_full(const u32 fifo_sta)
+{
+	return fifo_sta & MCP251XFD_REG_FIFOSTA_TFERFFIF;
 }
 
 static inline int
@@ -80,29 +71,49 @@
 }
 
 static int
-mcp251xfd_rx_ring_update(const struct mcp251xfd_priv *priv,
-			 struct mcp251xfd_rx_ring *ring)
+mcp251xfd_get_rx_len(const struct mcp251xfd_priv *priv,
+		     const struct mcp251xfd_rx_ring *ring,
+		     u8 *len_p)
 {
-	u32 new_head;
-	u8 chip_rx_head;
-	bool fifo_empty;
+	const u8 shift = ring->obj_num_shift_to_u8;
+	u8 chip_head, tail, len;
+	u32 fifo_sta;
 	int err;
 
-	err = mcp251xfd_rx_head_get_from_chip(priv, ring, &chip_rx_head,
-					      &fifo_empty);
-	if (err || fifo_empty)
+	err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(ring->fifo_nr),
+			  &fifo_sta);
+	if (err)
 		return err;
 
-	/* chip_rx_head, is the next RX-Object filled by the HW.
-	 * The new RX head must be >= the old head.
+	if (mcp251xfd_rx_fifo_sta_empty(fifo_sta)) {
+		*len_p = 0;
+		return 0;
+	}
+
+	if (mcp251xfd_rx_fifo_sta_full(fifo_sta)) {
+		*len_p = ring->obj_num;
+		return 0;
+	}
+
+	chip_head = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta);
+
+	err =  mcp251xfd_check_rx_tail(priv, ring);
+	if (err)
+		return err;
+	tail = mcp251xfd_get_rx_tail(ring);
+
+	/* First shift to full u8. The subtraction works on signed
+	 * values, that keeps the difference steady around the u8
+	 * overflow. The right shift acts on len, which is an u8.
 	 */
-	new_head = round_down(ring->head, ring->obj_num) + chip_rx_head;
-	if (new_head <= ring->head)
-		new_head += ring->obj_num;
+	BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(chip_head));
+	BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(tail));
+	BUILD_BUG_ON(sizeof(ring->obj_num) != sizeof(len));
 
-	ring->head = new_head;
+	len = (chip_head << shift) - (tail << shift);
+	*len_p = len >> shift;
 
-	return mcp251xfd_check_rx_tail(priv, ring);
+	return 0;
 }
 
 static void
@@ -148,8 +159,6 @@
 
 	if (!(hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_RTR))
 		memcpy(cfd->data, hw_rx_obj->data, cfd->len);
-
-	mcp251xfd_skb_set_timestamp(priv, skb, hw_rx_obj->ts);
 }
 
 static int
@@ -160,8 +169,26 @@
 	struct net_device_stats *stats = &priv->ndev->stats;
 	struct sk_buff *skb;
 	struct canfd_frame *cfd;
+	u64 timestamp;
 	int err;
 
+	/* According to mcp2518fd erratum DS80000789E 6. the FIFOCI
+	 * bits of a FIFOSTA register, here the RX FIFO head index
+	 * might be corrupted and we might process past the RX FIFO's
+	 * head into old CAN frames.
+	 *
+	 * Compare the timestamp of currently processed CAN frame with
+	 * last valid frame received. Abort with -EBADMSG if an old
+	 * CAN frame is detected.
+	 */
+	timestamp = timecounter_cyc2time(&priv->tc, hw_rx_obj->ts);
+	if (timestamp <= ring->last_valid) {
+		stats->rx_fifo_errors++;
+
+		return -EBADMSG;
+	}
+	ring->last_valid = timestamp;
+
 	if (hw_rx_obj->flags & MCP251XFD_OBJ_FLAGS_FDF)
 		skb = alloc_canfd_skb(priv->ndev, &cfd);
 	else
@@ -172,6 +199,7 @@
 		return 0;
 	}
 
+	mcp251xfd_skb_set_timestamp(skb, timestamp);
 	mcp251xfd_hw_rx_obj_to_skb(priv, hw_rx_obj, skb);
 	err = can_rx_offload_queue_timestamp(&priv->offload, skb, hw_rx_obj->ts);
 	if (err)
@@ -198,51 +226,80 @@
 }
 
 static int
+mcp251xfd_handle_rxif_ring_uinc(const struct mcp251xfd_priv *priv,
+				struct mcp251xfd_rx_ring *ring,
+				u8 len)
+{
+	int offset;
+	int err;
+
+	if (!len)
+		return 0;
+
+	ring->head += len;
+
+	/* Increment the RX FIFO tail pointer 'len' times in a
+	 * single SPI message.
+	 *
+	 * Note:
+	 * Calculate offset, so that the SPI transfer ends on
+	 * the last message of the uinc_xfer array, which has
+	 * "cs_change == 0", to properly deactivate the chip
+	 * select.
+	 */
+	offset = ARRAY_SIZE(ring->uinc_xfer) - len;
+	err = spi_sync_transfer(priv->spi,
+				ring->uinc_xfer + offset, len);
+	if (err)
+		return err;
+
+	ring->tail += len;
+
+	return 0;
+}
+
+static int
 mcp251xfd_handle_rxif_ring(struct mcp251xfd_priv *priv,
 			   struct mcp251xfd_rx_ring *ring)
 {
 	struct mcp251xfd_hw_rx_obj_canfd *hw_rx_obj = ring->obj;
-	u8 rx_tail, len;
+	u8 rx_tail, len, l;
 	int err, i;
 
-	err = mcp251xfd_rx_ring_update(priv, ring);
+	err = mcp251xfd_get_rx_len(priv, ring, &len);
 	if (err)
 		return err;
 
-	while ((len = mcp251xfd_get_rx_linear_len(ring))) {
-		int offset;
-
+	while ((l = mcp251xfd_get_rx_linear_len(ring, len))) {
 		rx_tail = mcp251xfd_get_rx_tail(ring);
 
 		err = mcp251xfd_rx_obj_read(priv, ring, hw_rx_obj,
-					    rx_tail, len);
+					    rx_tail, l);
 		if (err)
 			return err;
 
-		for (i = 0; i < len; i++) {
+		for (i = 0; i < l; i++) {
 			err = mcp251xfd_handle_rxif_one(priv, ring,
 							(void *)hw_rx_obj +
 							i * ring->obj_size);
-			if (err)
+
+			/* -EBADMSG means we're affected by mcp2518fd
+			 * erratum DS80000789E 6., i.e. the timestamp
+			 * in the RX object is older that the last
+			 * valid received CAN frame. Don't process any
+			 * further and mark processed frames as good.
+			 */
+			if (err == -EBADMSG)
+				return mcp251xfd_handle_rxif_ring_uinc(priv, ring, i);
+			else if (err)
 				return err;
 		}
 
-		/* Increment the RX FIFO tail pointer 'len' times in a
-		 * single SPI message.
-		 *
-		 * Note:
-		 * Calculate offset, so that the SPI transfer ends on
-		 * the last message of the uinc_xfer array, which has
-		 * "cs_change == 0", to properly deactivate the chip
-		 * select.
-		 */
-		offset = ARRAY_SIZE(ring->uinc_xfer) - len;
-		err = spi_sync_transfer(priv->spi,
-					ring->uinc_xfer + offset, len);
+		err = mcp251xfd_handle_rxif_ring_uinc(priv, ring, l);
 		if (err)
 			return err;
 
-		ring->tail += len;
+		len -= l;
 	}
 
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c
+++ linux-qcom-6.8.0/drivers/net/can/spi/mcp251xfd/mcp251xfd-tef.c
@@ -2,7 +2,7 @@
 //
 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
 //
-// Copyright (c) 2019, 2020, 2021 Pengutronix,
+// Copyright (c) 2019, 2020, 2021, 2023 Pengutronix,
 //               Marc Kleine-Budde <kernel@pengutronix.de>
 //
 // Based on:
@@ -16,6 +16,16 @@
 
 #include "mcp251xfd.h"
 
+static inline bool mcp251xfd_tx_fifo_sta_empty(u32 fifo_sta)
+{
+	return fifo_sta & MCP251XFD_REG_FIFOSTA_TFERFFIF;
+}
+
+static inline bool mcp251xfd_tx_fifo_sta_less_than_half_full(u32 fifo_sta)
+{
+	return fifo_sta & MCP251XFD_REG_FIFOSTA_TFHRFHIF;
+}
+
 static inline int
 mcp251xfd_tef_tail_get_from_chip(const struct mcp251xfd_priv *priv,
 				 u8 *tef_tail)
@@ -56,60 +66,43 @@
 }
 
 static int
-mcp251xfd_handle_tefif_recover(const struct mcp251xfd_priv *priv, const u32 seq)
-{
-	const struct mcp251xfd_tx_ring *tx_ring = priv->tx;
-	u32 tef_sta;
-	int err;
-
-	err = regmap_read(priv->map_reg, MCP251XFD_REG_TEFSTA, &tef_sta);
-	if (err)
-		return err;
-
-	if (tef_sta & MCP251XFD_REG_TEFSTA_TEFOVIF) {
-		netdev_err(priv->ndev,
-			   "Transmit Event FIFO buffer overflow.\n");
-		return -ENOBUFS;
-	}
-
-	netdev_info(priv->ndev,
-		    "Transmit Event FIFO buffer %s. (seq=0x%08x, tef_tail=0x%08x, tef_head=0x%08x, tx_head=0x%08x).\n",
-		    tef_sta & MCP251XFD_REG_TEFSTA_TEFFIF ?
-		    "full" : tef_sta & MCP251XFD_REG_TEFSTA_TEFNEIF ?
-		    "not empty" : "empty",
-		    seq, priv->tef->tail, priv->tef->head, tx_ring->head);
-
-	/* The Sequence Number in the TEF doesn't match our tef_tail. */
-	return -EAGAIN;
-}
-
-static int
 mcp251xfd_handle_tefif_one(struct mcp251xfd_priv *priv,
 			   const struct mcp251xfd_hw_tef_obj *hw_tef_obj,
 			   unsigned int *frame_len_ptr)
 {
 	struct net_device_stats *stats = &priv->ndev->stats;
+	u32 seq, tef_tail_masked, tef_tail;
 	struct sk_buff *skb;
-	u32 seq, seq_masked, tef_tail_masked, tef_tail;
 
-	seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK,
+	 /* Use the MCP2517FD mask on the MCP2518FD, too. We only
+	  * compare 7 bits, this is enough to detect old TEF objects.
+	  */
+	seq = FIELD_GET(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK,
 			hw_tef_obj->flags);
-
-	/* Use the MCP2517FD mask on the MCP2518FD, too. We only
-	 * compare 7 bits, this should be enough to detect
-	 * net-yet-completed, i.e. old TEF objects.
-	 */
-	seq_masked = seq &
-		field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK);
 	tef_tail_masked = priv->tef->tail &
 		field_mask(MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK);
-	if (seq_masked != tef_tail_masked)
-		return mcp251xfd_handle_tefif_recover(priv, seq);
+
+	/* According to mcp2518fd erratum DS80000789E 6. the FIFOCI
+	 * bits of a FIFOSTA register, here the TX FIFO tail index
+	 * might be corrupted and we might process past the TEF FIFO's
+	 * head into old CAN frames.
+	 *
+	 * Compare the sequence number of the currently processed CAN
+	 * frame with the expected sequence number. Abort with
+	 * -EBADMSG if an old CAN frame is detected.
+	 */
+	if (seq != tef_tail_masked) {
+		netdev_dbg(priv->ndev, "%s: chip=0x%02x ring=0x%02x\n", __func__,
+			   seq, tef_tail_masked);
+		stats->tx_fifo_errors++;
+
+		return -EBADMSG;
+	}
 
 	tef_tail = mcp251xfd_get_tef_tail(priv);
 	skb = priv->can.echo_skb[tef_tail];
 	if (skb)
-		mcp251xfd_skb_set_timestamp(priv, skb, hw_tef_obj->ts);
+		mcp251xfd_skb_set_timestamp_raw(priv, skb, hw_tef_obj->ts);
 	stats->tx_bytes +=
 		can_rx_offload_get_echo_skb_queue_timestamp(&priv->offload,
 							    tef_tail, hw_tef_obj->ts,
@@ -120,28 +113,70 @@
 	return 0;
 }
 
-static int mcp251xfd_tef_ring_update(struct mcp251xfd_priv *priv)
+static int
+mcp251xfd_get_tef_len(struct mcp251xfd_priv *priv, u8 *len_p)
 {
 	const struct mcp251xfd_tx_ring *tx_ring = priv->tx;
-	unsigned int new_head;
-	u8 chip_tx_tail;
+	const u8 shift = tx_ring->obj_num_shift_to_u8;
+	u8 chip_tx_tail, tail, len;
+	u32 fifo_sta;
 	int err;
 
-	err = mcp251xfd_tx_tail_get_from_chip(priv, &chip_tx_tail);
+	err = regmap_read(priv->map_reg, MCP251XFD_REG_FIFOSTA(priv->tx->fifo_nr),
+			  &fifo_sta);
 	if (err)
 		return err;
 
-	/* chip_tx_tail, is the next TX-Object send by the HW.
-	 * The new TEF head must be >= the old head, ...
+	/* If the chip says the TX-FIFO is empty, but there are no TX
+	 * buffers free in the ring, we assume all have been sent.
 	 */
-	new_head = round_down(priv->tef->head, tx_ring->obj_num) + chip_tx_tail;
-	if (new_head <= priv->tef->head)
-		new_head += tx_ring->obj_num;
+	if (mcp251xfd_tx_fifo_sta_empty(fifo_sta) &&
+	    mcp251xfd_get_tx_free(tx_ring) == 0) {
+		*len_p = tx_ring->obj_num;
+		return 0;
+	}
 
-	/* ... but it cannot exceed the TX head. */
-	priv->tef->head = min(new_head, tx_ring->head);
+	chip_tx_tail = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta);
 
-	return mcp251xfd_check_tef_tail(priv);
+	err =  mcp251xfd_check_tef_tail(priv);
+	if (err)
+		return err;
+	tail = mcp251xfd_get_tef_tail(priv);
+
+	/* First shift to full u8. The subtraction works on signed
+	 * values, that keeps the difference steady around the u8
+	 * overflow. The right shift acts on len, which is an u8.
+	 */
+	BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(chip_tx_tail));
+	BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(tail));
+	BUILD_BUG_ON(sizeof(tx_ring->obj_num) != sizeof(len));
+
+	len = (chip_tx_tail << shift) - (tail << shift);
+	len >>= shift;
+
+	/* According to mcp2518fd erratum DS80000789E 6. the FIFOCI
+	 * bits of a FIFOSTA register, here the TX-FIFO tail index
+	 * might be corrupted.
+	 *
+	 * However here it seems the bit indicating that the TX-FIFO
+	 * is empty (MCP251XFD_REG_FIFOSTA_TFERFFIF) is not correct
+	 * while the TX-FIFO tail index is.
+	 *
+	 * We assume the TX-FIFO is empty, i.e. all pending CAN frames
+	 * haven been send, if:
+	 * - Chip's head and tail index are equal (len == 0).
+	 * - The TX-FIFO is less than half full.
+	 *   (The TX-FIFO empty case has already been checked at the
+	 *    beginning of this function.)
+	 * - No free buffers in the TX ring.
+	 */
+	if (len == 0 && mcp251xfd_tx_fifo_sta_less_than_half_full(fifo_sta) &&
+	    mcp251xfd_get_tx_free(tx_ring) == 0)
+		len = tx_ring->obj_num;
+
+	*len_p = len;
+
+	return 0;
 }
 
 static inline int
@@ -182,13 +217,12 @@
 	u8 tef_tail, len, l;
 	int err, i;
 
-	err = mcp251xfd_tef_ring_update(priv);
+	err = mcp251xfd_get_tef_len(priv, &len);
 	if (err)
 		return err;
 
 	tef_tail = mcp251xfd_get_tef_tail(priv);
-	len = mcp251xfd_get_tef_len(priv);
-	l = mcp251xfd_get_tef_linear_len(priv);
+	l = mcp251xfd_get_tef_linear_len(priv, len);
 	err = mcp251xfd_tef_obj_read(priv, hw_tef_obj, tef_tail, l);
 	if (err)
 		return err;
@@ -203,12 +237,12 @@
 		unsigned int frame_len = 0;
 
 		err = mcp251xfd_handle_tefif_one(priv, &hw_tef_obj[i], &frame_len);
-		/* -EAGAIN means the Sequence Number in the TEF
-		 * doesn't match our tef_tail. This can happen if we
-		 * read the TEF objects too early. Leave loop let the
-		 * interrupt handler call us again.
+		/* -EBADMSG means we're affected by mcp2518fd erratum
+		 * DS80000789E 6., i.e. the Sequence Number in the TEF
+		 * doesn't match our tef_tail. Don't process any
+		 * further and mark processed frames as good.
 		 */
-		if (err == -EAGAIN)
+		if (err == -EBADMSG)
 			goto out_netif_wake_queue;
 		if (err)
 			return err;
@@ -216,13 +250,15 @@
 		total_frame_len += frame_len;
 	}
 
- out_netif_wake_queue:
+out_netif_wake_queue:
 	len = i;	/* number of handled goods TEFs */
 	if (len) {
 		struct mcp251xfd_tef_ring *ring = priv->tef;
 		struct mcp251xfd_tx_ring *tx_ring = priv->tx;
 		int offset;
 
+		ring->head += len;
+
 		/* Increment the TEF FIFO tail pointer 'len' times in
 		 * a single SPI message.
 		 *
--- linux-qcom-6.8.0.orig/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c
+++ linux-qcom-6.8.0/drivers/net/can/spi/mcp251xfd/mcp251xfd-timestamp.c
@@ -2,7 +2,7 @@
 //
 // mcp251xfd - Microchip MCP251xFD Family CAN controller driver
 //
-// Copyright (c) 2021 Pengutronix,
+// Copyright (c) 2021, 2023 Pengutronix,
 //               Marc Kleine-Budde <kernel@pengutronix.de>
 //
 
@@ -11,20 +11,20 @@
 
 #include "mcp251xfd.h"
 
-static u64 mcp251xfd_timestamp_read(const struct cyclecounter *cc)
+static u64 mcp251xfd_timestamp_raw_read(const struct cyclecounter *cc)
 {
 	const struct mcp251xfd_priv *priv;
-	u32 timestamp = 0;
+	u32 ts_raw = 0;
 	int err;
 
 	priv = container_of(cc, struct mcp251xfd_priv, cc);
-	err = mcp251xfd_get_timestamp(priv, &timestamp);
+	err = mcp251xfd_get_timestamp_raw(priv, &ts_raw);
 	if (err)
 		netdev_err(priv->ndev,
 			   "Error %d while reading timestamp. HW timestamps may be inaccurate.",
 			   err);
 
-	return timestamp;
+	return ts_raw;
 }
 
 static void mcp251xfd_timestamp_work(struct work_struct *work)
@@ -39,28 +39,21 @@
 			      MCP251XFD_TIMESTAMP_WORK_DELAY_SEC * HZ);
 }
 
-void mcp251xfd_skb_set_timestamp(const struct mcp251xfd_priv *priv,
-				 struct sk_buff *skb, u32 timestamp)
-{
-	struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb);
-	u64 ns;
-
-	ns = timecounter_cyc2time(&priv->tc, timestamp);
-	hwtstamps->hwtstamp = ns_to_ktime(ns);
-}
-
 void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv)
 {
 	struct cyclecounter *cc = &priv->cc;
 
-	cc->read = mcp251xfd_timestamp_read;
+	cc->read = mcp251xfd_timestamp_raw_read;
 	cc->mask = CYCLECOUNTER_MASK(32);
 	cc->shift = 1;
 	cc->mult = clocksource_hz2mult(priv->can.clock.freq, cc->shift);
 
-	timecounter_init(&priv->tc, &priv->cc, ktime_get_real_ns());
-
 	INIT_DELAYED_WORK(&priv->timestamp, mcp251xfd_timestamp_work);
+}
+
+void mcp251xfd_timestamp_start(struct mcp251xfd_priv *priv)
+{
+	timecounter_init(&priv->tc, &priv->cc, ktime_get_real_ns());
 	schedule_delayed_work(&priv->timestamp,
 			      MCP251XFD_TIMESTAMP_WORK_DELAY_SEC * HZ);
 }
--- linux-qcom-6.8.0.orig/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c
+++ linux-qcom-6.8.0/drivers/net/can/spi/mcp251xfd/mcp251xfd-tx.c
@@ -131,6 +131,39 @@
 	tx_obj->xfer[0].len = len;
 }
 
+static void mcp251xfd_tx_failure_drop(const struct mcp251xfd_priv *priv,
+				      struct mcp251xfd_tx_ring *tx_ring,
+				      int err)
+{
+	struct net_device *ndev = priv->ndev;
+	struct net_device_stats *stats = &ndev->stats;
+	unsigned int frame_len = 0;
+	u8 tx_head;
+
+	tx_ring->head--;
+	stats->tx_dropped++;
+	tx_head = mcp251xfd_get_tx_head(tx_ring);
+	can_free_echo_skb(ndev, tx_head, &frame_len);
+	netdev_completed_queue(ndev, 1, frame_len);
+	netif_wake_queue(ndev);
+
+	if (net_ratelimit())
+		netdev_err(priv->ndev, "ERROR in %s: %d\n", __func__, err);
+}
+
+void mcp251xfd_tx_obj_write_sync(struct work_struct *work)
+{
+	struct mcp251xfd_priv *priv = container_of(work, struct mcp251xfd_priv,
+						   tx_work);
+	struct mcp251xfd_tx_obj *tx_obj = priv->tx_work_obj;
+	struct mcp251xfd_tx_ring *tx_ring = priv->tx;
+	int err;
+
+	err = spi_sync(priv->spi, &tx_obj->msg);
+	if (err)
+		mcp251xfd_tx_failure_drop(priv, tx_ring, err);
+}
+
 static int mcp251xfd_tx_obj_write(const struct mcp251xfd_priv *priv,
 				  struct mcp251xfd_tx_obj *tx_obj)
 {
@@ -162,6 +195,11 @@
 	return false;
 }
 
+static bool mcp251xfd_work_busy(struct work_struct *work)
+{
+	return work_busy(work);
+}
+
 netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb,
 				 struct net_device *ndev)
 {
@@ -175,7 +213,8 @@
 	if (can_dev_dropped_skb(ndev, skb))
 		return NETDEV_TX_OK;
 
-	if (mcp251xfd_tx_busy(priv, tx_ring))
+	if (mcp251xfd_tx_busy(priv, tx_ring) ||
+	    mcp251xfd_work_busy(&priv->tx_work))
 		return NETDEV_TX_BUSY;
 
 	tx_obj = mcp251xfd_get_tx_obj_next(tx_ring);
@@ -193,13 +232,13 @@
 		netdev_sent_queue(priv->ndev, frame_len);
 
 	err = mcp251xfd_tx_obj_write(priv, tx_obj);
-	if (err)
-		goto out_err;
-
-	return NETDEV_TX_OK;
-
- out_err:
-	netdev_err(priv->ndev, "ERROR in %s: %d\n", __func__, err);
+	if (err == -EBUSY) {
+		netif_stop_queue(ndev);
+		priv->tx_work_obj = tx_obj;
+		queue_work(priv->wq, &priv->tx_work);
+	} else if (err) {
+		mcp251xfd_tx_failure_drop(priv, tx_ring, err);
+	}
 
 	return NETDEV_TX_OK;
 }
--- linux-qcom-6.8.0.orig/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
+++ linux-qcom-6.8.0/drivers/net/can/spi/mcp251xfd/mcp251xfd.h
@@ -2,7 +2,7 @@
  *
  * mcp251xfd - Microchip MCP251xFD Family CAN controller driver
  *
- * Copyright (c) 2019, 2020, 2021 Pengutronix,
+ * Copyright (c) 2019, 2020, 2021, 2023 Pengutronix,
  *               Marc Kleine-Budde <kernel@pengutronix.de>
  * Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org>
  */
@@ -524,6 +524,7 @@
 
 	/* u8 obj_num equals tx_ring->obj_num */
 	/* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */
+	/* u8 obj_num_shift_to_u8 equals tx_ring->obj_num_shift_to_u8 */
 
 	union mcp251xfd_write_reg_buf irq_enable_buf;
 	struct spi_transfer irq_enable_xfer;
@@ -542,6 +543,7 @@
 	u8 nr;
 	u8 fifo_nr;
 	u8 obj_num;
+	u8 obj_num_shift_to_u8;
 	u8 obj_size;
 
 	struct mcp251xfd_tx_obj obj[MCP251XFD_TX_OBJ_NUM_MAX];
@@ -552,10 +554,14 @@
 	unsigned int head;
 	unsigned int tail;
 
+	/* timestamp of the last valid received CAN frame */
+	u64 last_valid;
+
 	u16 base;
 	u8 nr;
 	u8 fifo_nr;
 	u8 obj_num;
+	u8 obj_num_shift_to_u8;
 	u8 obj_size;
 
 	union mcp251xfd_write_reg_buf irq_enable_buf;
@@ -608,6 +614,12 @@
 	__MCP251XFD_FLAGS_SIZE__
 };
 
+enum mcp251xfd_xceiver_mode {
+	MCP251XFD_XCVR_NORMAL_MODE,
+	MCP251XFD_XCVR_STBY_MODE,
+	MCP251XFD_XCVR_MODE_NONE
+};
+
 struct mcp251xfd_priv {
 	struct can_priv can;
 	struct can_rx_offload offload;
@@ -633,6 +645,10 @@
 	struct mcp251xfd_rx_ring *rx[MCP251XFD_FIFO_RX_NUM];
 	struct mcp251xfd_tx_ring tx[MCP251XFD_FIFO_TX_NUM];
 
+	struct workqueue_struct *wq;
+	struct work_struct tx_work;
+	struct mcp251xfd_tx_obj *tx_work_obj;
+
 	DECLARE_BITMAP(flags, __MCP251XFD_FLAGS_SIZE__);
 
 	u8 rx_ring_num;
@@ -805,10 +821,27 @@
 	return data;
 }
 
-static inline int mcp251xfd_get_timestamp(const struct mcp251xfd_priv *priv,
-					  u32 *timestamp)
+static inline int mcp251xfd_get_timestamp_raw(const struct mcp251xfd_priv *priv,
+					      u32 *ts_raw)
+{
+	return regmap_read(priv->map_reg, MCP251XFD_REG_TBC, ts_raw);
+}
+
+static inline void mcp251xfd_skb_set_timestamp(struct sk_buff *skb, u64 ns)
+{
+	struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb);
+
+	hwtstamps->hwtstamp = ns_to_ktime(ns);
+}
+
+static inline
+void mcp251xfd_skb_set_timestamp_raw(const struct mcp251xfd_priv *priv,
+				     struct sk_buff *skb, u32 ts_raw)
 {
-	return regmap_read(priv->map_reg, MCP251XFD_REG_TBC, timestamp);
+	u64 ns;
+
+	ns = timecounter_cyc2time(&priv->tc, ts_raw);
+	mcp251xfd_skb_set_timestamp(skb, ns);
 }
 
 static inline u16 mcp251xfd_get_tef_obj_addr(u8 n)
@@ -857,17 +890,8 @@
 	return priv->tef->tail & (priv->tx->obj_num - 1);
 }
 
-static inline u8 mcp251xfd_get_tef_len(const struct mcp251xfd_priv *priv)
+static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv, u8 len)
 {
-	return priv->tef->head - priv->tef->tail;
-}
-
-static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv)
-{
-	u8 len;
-
-	len = mcp251xfd_get_tef_len(priv);
-
 	return min_t(u8, len, priv->tx->obj_num - mcp251xfd_get_tef_tail(priv));
 }
 
@@ -910,18 +934,9 @@
 	return ring->tail & (ring->obj_num - 1);
 }
 
-static inline u8 mcp251xfd_get_rx_len(const struct mcp251xfd_rx_ring *ring)
-{
-	return ring->head - ring->tail;
-}
-
 static inline u8
-mcp251xfd_get_rx_linear_len(const struct mcp251xfd_rx_ring *ring)
+mcp251xfd_get_rx_linear_len(const struct mcp251xfd_rx_ring *ring, u8 len)
 {
-	u8 len;
-
-	len = mcp251xfd_get_rx_len(ring);
-
 	return min_t(u8, len, ring->obj_num - mcp251xfd_get_rx_tail(ring));
 }
 
@@ -947,11 +962,11 @@
 int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv);
 int mcp251xfd_handle_rxif(struct mcp251xfd_priv *priv);
 int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv);
-void mcp251xfd_skb_set_timestamp(const struct mcp251xfd_priv *priv,
-				 struct sk_buff *skb, u32 timestamp);
 void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv);
+void mcp251xfd_timestamp_start(struct mcp251xfd_priv *priv);
 void mcp251xfd_timestamp_stop(struct mcp251xfd_priv *priv);
 
+void mcp251xfd_tx_obj_write_sync(struct work_struct *work);
 netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb,
 				 struct net_device *ndev);
 
--- linux-qcom-6.8.0.orig/drivers/net/can/sun4i_can.c
+++ linux-qcom-6.8.0/drivers/net/can/sun4i_can.c
@@ -579,11 +579,9 @@
 		/* bus error interrupt */
 		netdev_dbg(dev, "bus error interrupt\n");
 		priv->can.can_stats.bus_error++;
-		stats->rx_errors++;
+		ecc = readl(priv->base + SUN4I_REG_STA_ADDR);
 
 		if (likely(skb)) {
-			ecc = readl(priv->base + SUN4I_REG_STA_ADDR);
-
 			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
 			switch (ecc & SUN4I_STA_MASK_ERR) {
@@ -601,9 +599,15 @@
 					       >> 16;
 				break;
 			}
-			/* error occurred during transmission? */
-			if ((ecc & SUN4I_STA_ERR_DIR) == 0)
+		}
+
+		/* error occurred during transmission? */
+		if ((ecc & SUN4I_STA_ERR_DIR) == 0) {
+			if (likely(skb))
 				cf->data[2] |= CAN_ERR_PROT_TX;
+			stats->tx_errors++;
+		} else {
+			stats->rx_errors++;
 		}
 	}
 	if (isrc & SUN4I_INT_ERR_PASSIVE) {
@@ -629,10 +633,10 @@
 		tx_state = txerr >= rxerr ? state : 0;
 		rx_state = txerr <= rxerr ? state : 0;
 
-		if (likely(skb))
-			can_change_state(dev, cf, tx_state, rx_state);
-		else
-			priv->can.state = state;
+		/* The skb allocation might fail, but can_change_state()
+		 * handles cf == NULL.
+		 */
+		can_change_state(dev, cf, tx_state, rx_state);
 		if (state == CAN_STATE_BUS_OFF)
 			can_bus_off(dev);
 	}
--- linux-qcom-6.8.0.orig/drivers/net/can/usb/ems_usb.c
+++ linux-qcom-6.8.0/drivers/net/can/usb/ems_usb.c
@@ -335,15 +335,14 @@
 	struct net_device_stats *stats = &dev->netdev->stats;
 
 	skb = alloc_can_err_skb(dev->netdev, &cf);
-	if (skb == NULL)
-		return;
 
 	if (msg->type == CPC_MSG_TYPE_CAN_STATE) {
 		u8 state = msg->msg.can_state;
 
 		if (state & SJA1000_SR_BS) {
 			dev->can.state = CAN_STATE_BUS_OFF;
-			cf->can_id |= CAN_ERR_BUSOFF;
+			if (skb)
+				cf->can_id |= CAN_ERR_BUSOFF;
 
 			dev->can.can_stats.bus_off++;
 			can_bus_off(dev->netdev);
@@ -361,44 +360,53 @@
 
 		/* bus error interrupt */
 		dev->can.can_stats.bus_error++;
-		stats->rx_errors++;
 
-		cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+		if (skb) {
+			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
 
-		switch (ecc & SJA1000_ECC_MASK) {
-		case SJA1000_ECC_BIT:
-			cf->data[2] |= CAN_ERR_PROT_BIT;
-			break;
-		case SJA1000_ECC_FORM:
-			cf->data[2] |= CAN_ERR_PROT_FORM;
-			break;
-		case SJA1000_ECC_STUFF:
-			cf->data[2] |= CAN_ERR_PROT_STUFF;
-			break;
-		default:
-			cf->data[3] = ecc & SJA1000_ECC_SEG;
-			break;
+			switch (ecc & SJA1000_ECC_MASK) {
+			case SJA1000_ECC_BIT:
+				cf->data[2] |= CAN_ERR_PROT_BIT;
+				break;
+			case SJA1000_ECC_FORM:
+				cf->data[2] |= CAN_ERR_PROT_FORM;
+				break;
+			case SJA1000_ECC_STUFF:
+				cf->data[2] |= CAN_ERR_PROT_STUFF;
+				break;
+			default:
+				cf->data[3] = ecc & SJA1000_ECC_SEG;
+				break;
+			}
 		}
 
 		/* Error occurred during transmission? */
-		if ((ecc & SJA1000_ECC_DIR) == 0)
-			cf->data[2] |= CAN_ERR_PROT_TX;
+		if ((ecc & SJA1000_ECC_DIR) == 0) {
+			stats->tx_errors++;
+			if (skb)
+				cf->data[2] |= CAN_ERR_PROT_TX;
+		} else {
+			stats->rx_errors++;
+		}
 
-		if (dev->can.state == CAN_STATE_ERROR_WARNING ||
-		    dev->can.state == CAN_STATE_ERROR_PASSIVE) {
+		if (skb && (dev->can.state == CAN_STATE_ERROR_WARNING ||
+			    dev->can.state == CAN_STATE_ERROR_PASSIVE)) {
 			cf->can_id |= CAN_ERR_CRTL;
 			cf->data[1] = (txerr > rxerr) ?
 			    CAN_ERR_CRTL_TX_PASSIVE : CAN_ERR_CRTL_RX_PASSIVE;
 		}
 	} else if (msg->type == CPC_MSG_TYPE_OVERRUN) {
-		cf->can_id |= CAN_ERR_CRTL;
-		cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+		if (skb) {
+			cf->can_id |= CAN_ERR_CRTL;
+			cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+		}
 
 		stats->rx_over_errors++;
 		stats->rx_errors++;
 	}
 
-	netif_rx(skb);
+	if (skb)
+		netif_rx(skb);
 }
 
 /*
--- linux-qcom-6.8.0.orig/drivers/net/can/usb/esd_usb.c
+++ linux-qcom-6.8.0/drivers/net/can/usb/esd_usb.c
@@ -3,7 +3,7 @@
  * CAN driver for esd electronics gmbh CAN-USB/2, CAN-USB/3 and CAN-USB/Micro
  *
  * Copyright (C) 2010-2012 esd electronic system design gmbh, Matthias Fuchs <socketcan@esd.eu>
- * Copyright (C) 2022-2023 esd electronics gmbh, Frank Jungclaus <frank.jungclaus@esd.eu>
+ * Copyright (C) 2022-2024 esd electronics gmbh, Frank Jungclaus <frank.jungclaus@esd.eu>
  */
 
 #include <linux/can.h>
@@ -1116,9 +1116,6 @@
 	if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
 		flags |= ESD_USB_3_BAUDRATE_FLAG_LOM;
 
-	if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
-		flags |= ESD_USB_3_BAUDRATE_FLAG_TRS;
-
 	baud_x->nom.brp = cpu_to_le16(nom_bt->brp & (nom_btc->brp_max - 1));
 	baud_x->nom.sjw = cpu_to_le16(nom_bt->sjw & (nom_btc->sjw_max - 1));
 	baud_x->nom.tseg1 = cpu_to_le16((nom_bt->prop_seg + nom_bt->phase_seg1)
@@ -1219,7 +1216,6 @@
 	switch (le16_to_cpu(dev->udev->descriptor.idProduct)) {
 	case ESD_USB_CANUSB3_PRODUCT_ID:
 		priv->can.clock.freq = ESD_USB_3_CAN_CLOCK;
-		priv->can.ctrlmode_supported |= CAN_CTRLMODE_3_SAMPLES;
 		priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD;
 		priv->can.bittiming_const = &esd_usb_3_nom_bittiming_const;
 		priv->can.data_bittiming_const = &esd_usb_3_data_bittiming_const;
--- linux-qcom-6.8.0.orig/drivers/net/can/usb/f81604.c
+++ linux-qcom-6.8.0/drivers/net/can/usb/f81604.c
@@ -526,7 +526,6 @@
 		netdev_dbg(netdev, "bus error interrupt\n");
 
 		priv->can.can_stats.bus_error++;
-		stats->rx_errors++;
 
 		if (skb) {
 			cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
@@ -548,10 +547,15 @@
 
 			/* set error location */
 			cf->data[3] = data->ecc & F81604_SJA1000_ECC_SEG;
+		}
 
-			/* Error occurred during transmission? */
-			if ((data->ecc & F81604_SJA1000_ECC_DIR) == 0)
+		/* Error occurred during transmission? */
+		if ((data->ecc & F81604_SJA1000_ECC_DIR) == 0) {
+			stats->tx_errors++;
+			if (skb)
 				cf->data[2] |= CAN_ERR_PROT_TX;
+		} else {
+			stats->rx_errors++;
 		}
 
 		set_bit(F81604_CLEAR_ECC, &priv->clear_flags);
--- linux-qcom-6.8.0.orig/drivers/net/can/usb/gs_usb.c
+++ linux-qcom-6.8.0/drivers/net/can/usb/gs_usb.c
@@ -40,8 +40,8 @@
 #define USB_ABE_CANDEBUGGER_FD_VENDOR_ID 0x16d0
 #define USB_ABE_CANDEBUGGER_FD_PRODUCT_ID 0x10b8
 
-#define GS_USB_ENDPOINT_IN 1
-#define GS_USB_ENDPOINT_OUT 2
+#define USB_XYLANTA_SAINT3_VENDOR_ID 0x16d0
+#define USB_XYLANTA_SAINT3_PRODUCT_ID 0x0f30
 
 /* Timestamp 32 bit timer runs at 1 MHz (1 µs tick). Worker accounts
  * for timer overflow (will be after ~71 minutes)
@@ -333,6 +333,9 @@
 
 	unsigned int hf_size_rx;
 	u8 active_channels;
+
+	unsigned int pipe_in;
+	unsigned int pipe_out;
 };
 
 /* 'allocate' a tx context.
@@ -684,7 +687,7 @@
 
 resubmit_urb:
 	usb_fill_bulk_urb(urb, parent->udev,
-			  usb_rcvbulkpipe(parent->udev, GS_USB_ENDPOINT_IN),
+			  parent->pipe_in,
 			  hf, dev->parent->hf_size_rx,
 			  gs_usb_receive_bulk_callback, parent);
 
@@ -816,7 +819,7 @@
 	}
 
 	usb_fill_bulk_urb(urb, dev->udev,
-			  usb_sndbulkpipe(dev->udev, GS_USB_ENDPOINT_OUT),
+			  dev->parent->pipe_out,
 			  hf, dev->hf_size_tx,
 			  gs_usb_xmit_callback, txc);
 
@@ -922,8 +925,7 @@
 			/* fill, anchor, and submit rx urb */
 			usb_fill_bulk_urb(urb,
 					  dev->udev,
-					  usb_rcvbulkpipe(dev->udev,
-							  GS_USB_ENDPOINT_IN),
+					  dev->parent->pipe_in,
 					  buf,
 					  dev->parent->hf_size_rx,
 					  gs_usb_receive_bulk_callback, parent);
@@ -1410,6 +1412,7 @@
 			const struct usb_device_id *id)
 {
 	struct usb_device *udev = interface_to_usbdev(intf);
+	struct usb_endpoint_descriptor *ep_in, *ep_out;
 	struct gs_host_frame *hf;
 	struct gs_usb *parent;
 	struct gs_host_config hconf = {
@@ -1419,6 +1422,13 @@
 	unsigned int icount, i;
 	int rc;
 
+	rc = usb_find_common_endpoints(intf->cur_altsetting,
+				       &ep_in, &ep_out, NULL, NULL);
+	if (rc) {
+		dev_err(&intf->dev, "Required endpoints not found\n");
+		return rc;
+	}
+
 	/* send host config */
 	rc = usb_control_msg_send(udev, 0,
 				  GS_USB_BREQ_HOST_FORMAT,
@@ -1463,6 +1473,10 @@
 	usb_set_intfdata(intf, parent);
 	parent->udev = udev;
 
+	/* store the detected endpoints */
+	parent->pipe_in = usb_rcvbulkpipe(parent->udev, ep_in->bEndpointAddress);
+	parent->pipe_out = usb_sndbulkpipe(parent->udev, ep_out->bEndpointAddress);
+
 	for (i = 0; i < icount; i++) {
 		unsigned int hf_size_rx = 0;
 
@@ -1530,6 +1544,8 @@
 				      USB_CES_CANEXT_FD_PRODUCT_ID, 0) },
 	{ USB_DEVICE_INTERFACE_NUMBER(USB_ABE_CANDEBUGGER_FD_VENDOR_ID,
 				      USB_ABE_CANDEBUGGER_FD_PRODUCT_ID, 0) },
+	{ USB_DEVICE_INTERFACE_NUMBER(USB_XYLANTA_SAINT3_VENDOR_ID,
+				      USB_XYLANTA_SAINT3_PRODUCT_ID, 0) },
 	{} /* Terminating entry */
 };
 
--- linux-qcom-6.8.0.orig/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
+++ linux-qcom-6.8.0/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c
@@ -124,6 +124,7 @@
 
 static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leafimx = {
 	.quirks = 0,
+	.family = KVASER_LEAF,
 	.ops = &kvaser_usb_leaf_dev_ops,
 };
 
@@ -291,7 +292,7 @@
 	}
 	usb_free_urb(urb);
 
-	return 0;
+	return err;
 }
 
 int kvaser_usb_can_rx_over_error(struct net_device *netdev)
--- linux-qcom-6.8.0.orig/drivers/net/dsa/b53/b53_common.c
+++ linux-qcom-6.8.0/drivers/net/dsa/b53/b53_common.c
@@ -27,6 +27,7 @@
 #include <linux/phylink.h>
 #include <linux/etherdevice.h>
 #include <linux/if_bridge.h>
+#include <linux/if_vlan.h>
 #include <net/dsa.h>
 
 #include "b53_regs.h"
@@ -224,6 +225,9 @@
 
 #define B53_MIBS_58XX_SIZE	ARRAY_SIZE(b53_mibs_58xx)
 
+#define B53_MAX_MTU_25		(1536 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN)
+#define B53_MAX_MTU		(9720 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN)
+
 static int b53_do_vlan_op(struct b53_device *dev, u8 op)
 {
 	unsigned int i;
@@ -2263,17 +2267,25 @@
 	bool allow_10_100;
 
 	if (is5325(dev) || is5365(dev))
-		return -EOPNOTSUPP;
+		return 0;
+
+	if (!dsa_is_cpu_port(ds, port))
+		return 0;
 
-	enable_jumbo = (mtu >= JMS_MIN_SIZE);
-	allow_10_100 = (dev->chip_id == BCM583XX_DEVICE_ID);
+	enable_jumbo = (mtu > ETH_DATA_LEN);
+	allow_10_100 = !is63xx(dev);
 
 	return b53_set_jumbo(dev, enable_jumbo, allow_10_100);
 }
 
 static int b53_get_max_mtu(struct dsa_switch *ds, int port)
 {
-	return JMS_MAX_SIZE;
+	struct b53_device *dev = ds->priv;
+
+	if (is5325(dev) || is5365(dev))
+		return B53_MAX_MTU_25;
+
+	return B53_MAX_MTU;
 }
 
 static const struct dsa_switch_ops b53_switch_ops = {
--- linux-qcom-6.8.0.orig/drivers/net/dsa/bcm_sf2.c
+++ linux-qcom-6.8.0/drivers/net/dsa/bcm_sf2.c
@@ -675,8 +675,10 @@
 			of_remove_property(child, prop);
 
 		phydev = of_phy_find_device(child);
-		if (phydev)
+		if (phydev) {
 			phy_device_remove(phydev);
+			phy_device_free(phydev);
+		}
 	}
 
 	err = mdiobus_register(priv->user_mii_bus);
--- linux-qcom-6.8.0.orig/drivers/net/dsa/lan9303-core.c
+++ linux-qcom-6.8.0/drivers/net/dsa/lan9303-core.c
@@ -6,6 +6,7 @@
 #include <linux/module.h>
 #include <linux/gpio/consumer.h>
 #include <linux/regmap.h>
+#include <linux/iopoll.h>
 #include <linux/mutex.h>
 #include <linux/mii.h>
 #include <linux/of.h>
@@ -839,6 +840,8 @@
 	if (!chip->reset_gpio)
 		return;
 
+	gpiod_set_value_cansleep(chip->reset_gpio, 1);
+
 	if (chip->reset_duration != 0)
 		msleep(chip->reset_duration);
 
@@ -864,8 +867,34 @@
 static int lan9303_check_device(struct lan9303 *chip)
 {
 	int ret;
+	int err;
 	u32 reg;
 
+	/* In I2C-managed configurations this polling loop will clash with
+	 * switch's reading of EEPROM right after reset and this behaviour is
+	 * not configurable. While lan9303_read() already has quite long retry
+	 * timeout, seems not all cases are being detected as arbitration error.
+	 *
+	 * According to datasheet, EEPROM loader has 30ms timeout (in case of
+	 * missing EEPROM).
+	 *
+	 * Loading of the largest supported EEPROM is expected to take at least
+	 * 5.9s.
+	 */
+	err = read_poll_timeout(lan9303_read, ret,
+				!ret && reg & LAN9303_HW_CFG_READY,
+				20000, 6000000, false,
+				chip->regmap, LAN9303_HW_CFG, &reg);
+	if (ret) {
+		dev_err(chip->dev, "failed to read HW_CFG reg: %pe\n",
+			ERR_PTR(ret));
+		return ret;
+	}
+	if (err) {
+		dev_err(chip->dev, "HW_CFG not ready: 0x%08x\n", reg);
+		return err;
+	}
+
 	ret = lan9303_read(chip->regmap, LAN9303_CHIP_REV, &reg);
 	if (ret) {
 		dev_err(chip->dev, "failed to read chip revision register: %d\n",
@@ -1048,31 +1077,31 @@
 	return ARRAY_SIZE(lan9303_mib);
 }
 
-static int lan9303_phy_read(struct dsa_switch *ds, int phy, int regnum)
+static int lan9303_phy_read(struct dsa_switch *ds, int port, int regnum)
 {
 	struct lan9303 *chip = ds->priv;
 	int phy_base = chip->phy_addr_base;
 
-	if (phy == phy_base)
+	if (port == 0)
 		return lan9303_virt_phy_reg_read(chip, regnum);
-	if (phy > phy_base + 2)
+	if (port > 2)
 		return -ENODEV;
 
-	return chip->ops->phy_read(chip, phy, regnum);
+	return chip->ops->phy_read(chip, phy_base + port, regnum);
 }
 
-static int lan9303_phy_write(struct dsa_switch *ds, int phy, int regnum,
+static int lan9303_phy_write(struct dsa_switch *ds, int port, int regnum,
 			     u16 val)
 {
 	struct lan9303 *chip = ds->priv;
 	int phy_base = chip->phy_addr_base;
 
-	if (phy == phy_base)
+	if (port == 0)
 		return lan9303_virt_phy_reg_write(chip, regnum, val);
-	if (phy > phy_base + 2)
+	if (port > 2)
 		return -ENODEV;
 
-	return chip->ops->phy_write(chip, phy, regnum, val);
+	return chip->ops->phy_write(chip, phy_base + port, regnum, val);
 }
 
 static int lan9303_port_enable(struct dsa_switch *ds, int port,
@@ -1100,7 +1129,7 @@
 	vlan_vid_del(dsa_port_to_conduit(dp), htons(ETH_P_8021Q), port);
 
 	lan9303_disable_processing_port(chip, port);
-	lan9303_phy_write(ds, chip->phy_addr_base + port, MII_BMCR, BMCR_PDOWN);
+	lan9303_phy_write(ds, port, MII_BMCR, BMCR_PDOWN);
 }
 
 static int lan9303_port_bridge_join(struct dsa_switch *ds, int port,
@@ -1355,8 +1384,6 @@
 
 static int lan9303_register_switch(struct lan9303 *chip)
 {
-	int base;
-
 	chip->ds = devm_kzalloc(chip->dev, sizeof(*chip->ds), GFP_KERNEL);
 	if (!chip->ds)
 		return -ENOMEM;
@@ -1365,8 +1392,7 @@
 	chip->ds->num_ports = LAN9303_NUM_PORTS;
 	chip->ds->priv = chip;
 	chip->ds->ops = &lan9303_switch_ops;
-	base = chip->phy_addr_base;
-	chip->ds->phys_mii_mask = GENMASK(LAN9303_NUM_PORTS - 1 + base, base);
+	chip->ds->phys_mii_mask = GENMASK(LAN9303_NUM_PORTS - 1, 0);
 
 	return dsa_register_switch(chip->ds);
 }
--- linux-qcom-6.8.0.orig/drivers/net/dsa/microchip/ksz9477.c
+++ linux-qcom-6.8.0/drivers/net/dsa/microchip/ksz9477.c
@@ -2,7 +2,7 @@
 /*
  * Microchip KSZ9477 switch driver main logic
  *
- * Copyright (C) 2017-2019 Microchip Technology Inc.
+ * Copyright (C) 2017-2024 Microchip Technology Inc.
  */
 
 #include <linux/kernel.h>
@@ -355,10 +355,8 @@
 			   SPI_AUTO_EDGE_DETECTION, 0);
 
 	/* default configuration */
-	ksz_read8(dev, REG_SW_LUE_CTRL_1, &data8);
-	data8 = SW_AGING_ENABLE | SW_LINK_AUTO_AGING |
-	      SW_SRC_ADDR_FILTER | SW_FLUSH_STP_TABLE | SW_FLUSH_MSTP_TABLE;
-	ksz_write8(dev, REG_SW_LUE_CTRL_1, data8);
+	ksz_write8(dev, REG_SW_LUE_CTRL_1,
+		   SW_AGING_ENABLE | SW_LINK_AUTO_AGING | SW_SRC_ADDR_FILTER);
 
 	/* disable interrupts */
 	ksz_write32(dev, REG_SW_INT_MASK__4, SWITCH_INT_MASK);
@@ -1099,26 +1097,51 @@
 int ksz9477_set_ageing_time(struct ksz_device *dev, unsigned int msecs)
 {
 	u32 secs = msecs / 1000;
-	u8 value;
-	u8 data;
+	u8 data, mult, value;
+	u32 max_val;
 	int ret;
 
-	value = FIELD_GET(SW_AGE_PERIOD_7_0_M, secs);
+#define MAX_TIMER_VAL	((1 << 8) - 1)
 
-	ret = ksz_write8(dev, REG_SW_LUE_CTRL_3, value);
-	if (ret < 0)
-		return ret;
+	/* The aging timer comprises a 3-bit multiplier and an 8-bit second
+	 * value.  Either of them cannot be zero.  The maximum timer is then
+	 * 7 * 255 = 1785 seconds.
+	 */
+	if (!secs)
+		secs = 1;
 
-	data = FIELD_GET(SW_AGE_PERIOD_10_8_M, secs);
+	/* Return error if too large. */
+	else if (secs > 7 * MAX_TIMER_VAL)
+		return -EINVAL;
 
 	ret = ksz_read8(dev, REG_SW_LUE_CTRL_0, &value);
 	if (ret < 0)
 		return ret;
 
-	value &= ~SW_AGE_CNT_M;
-	value |= FIELD_PREP(SW_AGE_CNT_M, data);
+	/* Check whether there is need to update the multiplier. */
+	mult = FIELD_GET(SW_AGE_CNT_M, value);
+	max_val = MAX_TIMER_VAL;
+	if (mult > 0) {
+		/* Try to use the same multiplier already in the register as
+		 * the hardware default uses multiplier 4 and 75 seconds for
+		 * 300 seconds.
+		 */
+		max_val = DIV_ROUND_UP(secs, mult);
+		if (max_val > MAX_TIMER_VAL || max_val * mult != secs)
+			max_val = MAX_TIMER_VAL;
+	}
 
-	return ksz_write8(dev, REG_SW_LUE_CTRL_0, value);
+	data = DIV_ROUND_UP(secs, max_val);
+	if (mult != data) {
+		value &= ~SW_AGE_CNT_M;
+		value |= FIELD_PREP(SW_AGE_CNT_M, data);
+		ret = ksz_write8(dev, REG_SW_LUE_CTRL_0, value);
+		if (ret < 0)
+			return ret;
+	}
+
+	value = DIV_ROUND_UP(secs, data);
+	return ksz_write8(dev, REG_SW_LUE_CTRL_3, value);
 }
 
 void ksz9477_port_queue_split(struct ksz_device *dev, int port)
@@ -1305,6 +1328,10 @@
 	/* Enable REG_SW_MTU__2 reg by setting SW_JUMBO_PACKET */
 	ksz_cfg(dev, REG_SW_MAC_CTRL_1, SW_JUMBO_PACKET, true);
 
+	/* Use collision based back pressure mode. */
+	ksz_cfg(dev, REG_SW_MAC_CTRL_1, SW_BACK_PRESSURE,
+		SW_BACK_PRESSURE_COLLISION);
+
 	/* Now we can configure default MTU value */
 	ret = regmap_update_bits(ksz_regmap_16(dev), REG_SW_MTU__2, REG_SW_MTU_MASK,
 				 VLAN_ETH_FRAME_LEN + ETH_FCS_LEN);
--- linux-qcom-6.8.0.orig/drivers/net/dsa/microchip/ksz9477_reg.h
+++ linux-qcom-6.8.0/drivers/net/dsa/microchip/ksz9477_reg.h
@@ -2,7 +2,7 @@
 /*
  * Microchip KSZ9477 register definitions
  *
- * Copyright (C) 2017-2018 Microchip Technology Inc.
+ * Copyright (C) 2017-2024 Microchip Technology Inc.
  */
 
 #ifndef __KSZ9477_REGS_H
@@ -170,8 +170,6 @@
 #define SW_VLAN_ENABLE			BIT(7)
 #define SW_DROP_INVALID_VID		BIT(6)
 #define SW_AGE_CNT_M			GENMASK(5, 3)
-#define SW_AGE_CNT_S			3
-#define SW_AGE_PERIOD_10_8_M		GENMASK(10, 8)
 #define SW_RESV_MCAST_ENABLE		BIT(2)
 #define SW_HASH_OPTION_M		0x03
 #define SW_HASH_OPTION_CRC		1
@@ -247,6 +245,7 @@
 #define REG_SW_MAC_CTRL_1		0x0331
 
 #define SW_BACK_PRESSURE		BIT(5)
+#define SW_BACK_PRESSURE_COLLISION	0
 #define FAIR_FLOW_CTRL			BIT(4)
 #define NO_EXC_COLLISION_DROP		BIT(3)
 #define SW_JUMBO_PACKET			BIT(2)
--- linux-qcom-6.8.0.orig/drivers/net/dsa/microchip/ksz_common.c
+++ linux-qcom-6.8.0/drivers/net/dsa/microchip/ksz_common.c
@@ -966,10 +966,9 @@
 	regmap_reg_range(0x1030, 0x1030),
 	regmap_reg_range(0x1100, 0x1115),
 	regmap_reg_range(0x111a, 0x111f),
-	regmap_reg_range(0x1122, 0x1127),
-	regmap_reg_range(0x112a, 0x112b),
-	regmap_reg_range(0x1136, 0x1139),
-	regmap_reg_range(0x113e, 0x113f),
+	regmap_reg_range(0x1120, 0x112b),
+	regmap_reg_range(0x1134, 0x113b),
+	regmap_reg_range(0x113c, 0x113f),
 	regmap_reg_range(0x1400, 0x1401),
 	regmap_reg_range(0x1403, 0x1403),
 	regmap_reg_range(0x1410, 0x1417),
@@ -996,10 +995,9 @@
 	regmap_reg_range(0x2030, 0x2030),
 	regmap_reg_range(0x2100, 0x2115),
 	regmap_reg_range(0x211a, 0x211f),
-	regmap_reg_range(0x2122, 0x2127),
-	regmap_reg_range(0x212a, 0x212b),
-	regmap_reg_range(0x2136, 0x2139),
-	regmap_reg_range(0x213e, 0x213f),
+	regmap_reg_range(0x2120, 0x212b),
+	regmap_reg_range(0x2134, 0x213b),
+	regmap_reg_range(0x213c, 0x213f),
 	regmap_reg_range(0x2400, 0x2401),
 	regmap_reg_range(0x2403, 0x2403),
 	regmap_reg_range(0x2410, 0x2417),
@@ -1026,10 +1024,9 @@
 	regmap_reg_range(0x3030, 0x3030),
 	regmap_reg_range(0x3100, 0x3115),
 	regmap_reg_range(0x311a, 0x311f),
-	regmap_reg_range(0x3122, 0x3127),
-	regmap_reg_range(0x312a, 0x312b),
-	regmap_reg_range(0x3136, 0x3139),
-	regmap_reg_range(0x313e, 0x313f),
+	regmap_reg_range(0x3120, 0x312b),
+	regmap_reg_range(0x3134, 0x313b),
+	regmap_reg_range(0x313c, 0x313f),
 	regmap_reg_range(0x3400, 0x3401),
 	regmap_reg_range(0x3403, 0x3403),
 	regmap_reg_range(0x3410, 0x3417),
@@ -1056,10 +1053,9 @@
 	regmap_reg_range(0x4030, 0x4030),
 	regmap_reg_range(0x4100, 0x4115),
 	regmap_reg_range(0x411a, 0x411f),
-	regmap_reg_range(0x4122, 0x4127),
-	regmap_reg_range(0x412a, 0x412b),
-	regmap_reg_range(0x4136, 0x4139),
-	regmap_reg_range(0x413e, 0x413f),
+	regmap_reg_range(0x4120, 0x412b),
+	regmap_reg_range(0x4134, 0x413b),
+	regmap_reg_range(0x413c, 0x413f),
 	regmap_reg_range(0x4400, 0x4401),
 	regmap_reg_range(0x4403, 0x4403),
 	regmap_reg_range(0x4410, 0x4417),
@@ -1086,10 +1082,9 @@
 	regmap_reg_range(0x5030, 0x5030),
 	regmap_reg_range(0x5100, 0x5115),
 	regmap_reg_range(0x511a, 0x511f),
-	regmap_reg_range(0x5122, 0x5127),
-	regmap_reg_range(0x512a, 0x512b),
-	regmap_reg_range(0x5136, 0x5139),
-	regmap_reg_range(0x513e, 0x513f),
+	regmap_reg_range(0x5120, 0x512b),
+	regmap_reg_range(0x5134, 0x513b),
+	regmap_reg_range(0x513c, 0x513f),
 	regmap_reg_range(0x5400, 0x5401),
 	regmap_reg_range(0x5403, 0x5403),
 	regmap_reg_range(0x5410, 0x5417),
@@ -1116,10 +1111,9 @@
 	regmap_reg_range(0x6030, 0x6030),
 	regmap_reg_range(0x6100, 0x6115),
 	regmap_reg_range(0x611a, 0x611f),
-	regmap_reg_range(0x6122, 0x6127),
-	regmap_reg_range(0x612a, 0x612b),
-	regmap_reg_range(0x6136, 0x6139),
-	regmap_reg_range(0x613e, 0x613f),
+	regmap_reg_range(0x6120, 0x612b),
+	regmap_reg_range(0x6134, 0x613b),
+	regmap_reg_range(0x613c, 0x613f),
 	regmap_reg_range(0x6300, 0x6301),
 	regmap_reg_range(0x6400, 0x6401),
 	regmap_reg_range(0x6403, 0x6403),
@@ -2055,7 +2049,7 @@
 	struct ksz_device *dev = kirq->dev;
 	int ret;
 
-	ret = ksz_write32(dev, kirq->reg_mask, kirq->masked);
+	ret = ksz_write8(dev, kirq->reg_mask, kirq->masked);
 	if (ret)
 		dev_err(dev->dev, "failed to change IRQ mask\n");
 
@@ -2185,6 +2179,8 @@
 	return ksz_irq_common_setup(dev, pirq);
 }
 
+static int ksz_parse_drive_strength(struct ksz_device *dev);
+
 static int ksz_setup(struct dsa_switch *ds)
 {
 	struct ksz_device *dev = ds->priv;
@@ -2206,6 +2202,10 @@
 		return ret;
 	}
 
+	ret = ksz_parse_drive_strength(dev);
+	if (ret)
+		return ret;
+
 	/* set broadcast storm protection 10% rate */
 	regmap_update_bits(ksz_regmap_16(dev), regs[S_BROADCAST_CTRL],
 			   BROADCAST_STORM_RATE,
@@ -2426,16 +2426,26 @@
 		if (!port)
 			return MICREL_KSZ8_P1_ERRATA;
 		break;
+	case KSZ8765_CHIP_ID:
+	case KSZ8794_CHIP_ID:
+	case KSZ8795_CHIP_ID:
+		/* KSZ879x/KSZ877x/KSZ876x Errata DS80000687C Module 2 */
 	case KSZ9477_CHIP_ID:
-		/* KSZ9477 Errata DS80000754C
-		 *
-		 * Module 4: Energy Efficient Ethernet (EEE) feature select must
-		 * be manually disabled
+		/* KSZ9477S Errata DS80000754A Module 4 */
+	case KSZ9567_CHIP_ID:
+		/* KSZ9567S Errata DS80000756A Module 4 */
+	case KSZ9896_CHIP_ID:
+		/* KSZ9896C Errata DS80000757A Module 3 */
+	case KSZ9897_CHIP_ID:
+		/* KSZ9897R Errata DS80000758C Module 4 */
+		/* Energy Efficient Ethernet (EEE) feature select must be manually disabled
 		 *   The EEE feature is enabled by default, but it is not fully
 		 *   operational. It must be manually disabled through register
 		 *   controls. If not disabled, the PHY ports can auto-negotiate
 		 *   to enable EEE, and this feature can cause link drops when
 		 *   linked to another device supporting EEE.
+		 *
+		 * The same item appears in the errata for all switches above.
 		 */
 		return MICREL_NO_EEE;
 	}
@@ -2962,7 +2972,7 @@
 		else
 			interface = PHY_INTERFACE_MODE_MII;
 	} else if (val == bitval[P_RMII_SEL]) {
-		interface = PHY_INTERFACE_MODE_RGMII;
+		interface = PHY_INTERFACE_MODE_RMII;
 	} else {
 		interface = PHY_INTERFACE_MODE_RGMII;
 		if (data8 & P_RGMII_ID_EG_ENABLE)
@@ -3596,6 +3606,11 @@
 		return -EBUSY;
 	}
 
+	/* Need to initialize variable as the code to fill in settings may
+	 * not be executed.
+	 */
+	wol.wolopts = 0;
+
 	ksz_get_wol(ds, dp->index, &wol);
 	if (wol.wolopts & WAKE_MAGIC) {
 		dev_err(ds->dev,
@@ -3750,6 +3765,13 @@
 		return -EOPNOTSUPP;
 	}
 
+	/* KSZ9477 can only perform HSR offloading for up to two ports */
+	if (hweight8(dev->hsr_ports) >= 2) {
+		NL_SET_ERR_MSG_MOD(extack,
+				   "Cannot offload more than two ports - using software HSR");
+		return -EOPNOTSUPP;
+	}
+
 	/* Self MAC address filtering, to avoid frames traversing
 	 * the HSR ring more than once.
 	 */
@@ -4242,10 +4264,6 @@
 	for (port_num = 0; port_num < dev->info->port_cnt; ++port_num)
 		dev->ports[port_num].interface = PHY_INTERFACE_MODE_NA;
 	if (dev->dev->of_node) {
-		ret = ksz_parse_drive_strength(dev);
-		if (ret)
-			return ret;
-
 		ret = of_get_phy_mode(dev->dev->of_node, &interface);
 		if (ret == 0)
 			dev->compat_interface = interface;
--- linux-qcom-6.8.0.orig/drivers/net/dsa/microchip/ksz_ptp.c
+++ linux-qcom-6.8.0/drivers/net/dsa/microchip/ksz_ptp.c
@@ -266,7 +266,6 @@
 	struct ksz_port *prt;
 	struct dsa_port *dp;
 	bool tag_en = false;
-	int ret;
 
 	dsa_switch_for_each_user_port(dp, dev->ds) {
 		prt = &dev->ports[dp->index];
@@ -277,9 +276,7 @@
 	}
 
 	if (tag_en) {
-		ret = ptp_schedule_worker(ptp_data->clock, 0);
-		if (ret)
-			return ret;
+		ptp_schedule_worker(ptp_data->clock, 0);
 	} else {
 		ptp_cancel_worker_sync(ptp_data->clock);
 	}
--- linux-qcom-6.8.0.orig/drivers/net/dsa/microchip/lan937x_main.c
+++ linux-qcom-6.8.0/drivers/net/dsa/microchip/lan937x_main.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /* Microchip LAN937X switch driver main logic
- * Copyright (C) 2019-2022 Microchip Technology Inc.
+ * Copyright (C) 2019-2024 Microchip Technology Inc.
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -257,10 +257,66 @@
 
 int lan937x_set_ageing_time(struct ksz_device *dev, unsigned int msecs)
 {
-	u32 secs = msecs / 1000;
-	u32 value;
+	u8 data, mult, value8;
+	bool in_msec = false;
+	u32 max_val, value;
+	u32 secs = msecs;
 	int ret;
 
+#define MAX_TIMER_VAL	((1 << 20) - 1)
+
+	/* The aging timer comprises a 3-bit multiplier and a 20-bit second
+	 * value.  Either of them cannot be zero.  The maximum timer is then
+	 * 7 * 1048575 = 7340025 seconds.  As this value is too large for
+	 * practical use it can be interpreted as microseconds, making the
+	 * maximum timer 7340 seconds with finer control.  This allows for
+	 * maximum 122 minutes compared to 29 minutes in KSZ9477 switch.
+	 */
+	if (msecs % 1000)
+		in_msec = true;
+	else
+		secs /= 1000;
+	if (!secs)
+		secs = 1;
+
+	/* Return error if too large. */
+	else if (secs > 7 * MAX_TIMER_VAL)
+		return -EINVAL;
+
+	/* Configure how to interpret the number value. */
+	ret = ksz_rmw8(dev, REG_SW_LUE_CTRL_2, SW_AGE_CNT_IN_MICROSEC,
+		       in_msec ? SW_AGE_CNT_IN_MICROSEC : 0);
+	if (ret < 0)
+		return ret;
+
+	ret = ksz_read8(dev, REG_SW_LUE_CTRL_0, &value8);
+	if (ret < 0)
+		return ret;
+
+	/* Check whether there is need to update the multiplier. */
+	mult = FIELD_GET(SW_AGE_CNT_M, value8);
+	max_val = MAX_TIMER_VAL;
+	if (mult > 0) {
+		/* Try to use the same multiplier already in the register as
+		 * the hardware default uses multiplier 4 and 75 seconds for
+		 * 300 seconds.
+		 */
+		max_val = DIV_ROUND_UP(secs, mult);
+		if (max_val > MAX_TIMER_VAL || max_val * mult != secs)
+			max_val = MAX_TIMER_VAL;
+	}
+
+	data = DIV_ROUND_UP(secs, max_val);
+	if (mult != data) {
+		value8 &= ~SW_AGE_CNT_M;
+		value8 |= FIELD_PREP(SW_AGE_CNT_M, data);
+		ret = ksz_write8(dev, REG_SW_LUE_CTRL_0, value8);
+		if (ret < 0)
+			return ret;
+	}
+
+	secs = DIV_ROUND_UP(secs, data);
+
 	value = FIELD_GET(SW_AGE_PERIOD_7_0_M, secs);
 
 	ret = ksz_write8(dev, REG_SW_AGE_PERIOD__1, value);
--- linux-qcom-6.8.0.orig/drivers/net/dsa/microchip/lan937x_reg.h
+++ linux-qcom-6.8.0/drivers/net/dsa/microchip/lan937x_reg.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /* Microchip LAN937X switch register definitions
- * Copyright (C) 2019-2021 Microchip Technology Inc.
+ * Copyright (C) 2019-2024 Microchip Technology Inc.
  */
 #ifndef __LAN937X_REG_H
 #define __LAN937X_REG_H
@@ -48,8 +48,7 @@
 
 #define SW_VLAN_ENABLE			BIT(7)
 #define SW_DROP_INVALID_VID		BIT(6)
-#define SW_AGE_CNT_M			0x7
-#define SW_AGE_CNT_S			3
+#define SW_AGE_CNT_M			GENMASK(5, 3)
 #define SW_RESV_MCAST_ENABLE		BIT(2)
 
 #define REG_SW_LUE_CTRL_1		0x0311
@@ -62,6 +61,10 @@
 #define SW_FAST_AGING			BIT(1)
 #define SW_LINK_AUTO_AGING		BIT(0)
 
+#define REG_SW_LUE_CTRL_2		0x0312
+
+#define SW_AGE_CNT_IN_MICROSEC		BIT(7)
+
 #define REG_SW_AGE_PERIOD__1		0x0313
 #define SW_AGE_PERIOD_7_0_M		GENMASK(7, 0)
 
--- linux-qcom-6.8.0.orig/drivers/net/dsa/mt7530.c
+++ linux-qcom-6.8.0/drivers/net/dsa/mt7530.c
@@ -998,20 +998,217 @@
 	mutex_unlock(&priv->reg_mutex);
 }
 
+/* In Clause 5 of IEEE Std 802-2014, two sublayers of the data link layer (DLL)
+ * of the Open Systems Interconnection basic reference model (OSI/RM) are
+ * described; the medium access control (MAC) and logical link control (LLC)
+ * sublayers. The MAC sublayer is the one facing the physical layer.
+ *
+ * In 8.2 of IEEE Std 802.1Q-2022, the Bridge architecture is described. A
+ * Bridge component comprises a MAC Relay Entity for interconnecting the Ports
+ * of the Bridge, at least two Ports, and higher layer entities with at least a
+ * Spanning Tree Protocol Entity included.
+ *
+ * Each Bridge Port also functions as an end station and shall provide the MAC
+ * Service to an LLC Entity. Each instance of the MAC Service is provided to a
+ * distinct LLC Entity that supports protocol identification, multiplexing, and
+ * demultiplexing, for protocol data unit (PDU) transmission and reception by
+ * one or more higher layer entities.
+ *
+ * It is described in 8.13.9 of IEEE Std 802.1Q-2022 that in a Bridge, the LLC
+ * Entity associated with each Bridge Port is modeled as being directly
+ * connected to the attached Local Area Network (LAN).
+ *
+ * On the switch with CPU port architecture, CPU port functions as Management
+ * Port, and the Management Port functionality is provided by software which
+ * functions as an end station. Software is connected to an IEEE 802 LAN that is
+ * wholly contained within the system that incorporates the Bridge. Software
+ * provides access to the LLC Entity associated with each Bridge Port by the
+ * value of the source port field on the special tag on the frame received by
+ * software.
+ *
+ * We call frames that carry control information to determine the active
+ * topology and current extent of each Virtual Local Area Network (VLAN), i.e.,
+ * spanning tree or Shortest Path Bridging (SPB) and Multiple VLAN Registration
+ * Protocol Data Units (MVRPDUs), and frames from other link constrained
+ * protocols, such as Extensible Authentication Protocol over LAN (EAPOL) and
+ * Link Layer Discovery Protocol (LLDP), link-local frames. They are not
+ * forwarded by a Bridge. Permanently configured entries in the filtering
+ * database (FDB) ensure that such frames are discarded by the Forwarding
+ * Process. In 8.6.3 of IEEE Std 802.1Q-2022, this is described in detail:
+ *
+ * Each of the reserved MAC addresses specified in Table 8-1
+ * (01-80-C2-00-00-[00,01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F]) shall be
+ * permanently configured in the FDB in C-VLAN components and ERs.
+ *
+ * Each of the reserved MAC addresses specified in Table 8-2
+ * (01-80-C2-00-00-[01,02,03,04,05,06,07,08,09,0A,0E]) shall be permanently
+ * configured in the FDB in S-VLAN components.
+ *
+ * Each of the reserved MAC addresses specified in Table 8-3
+ * (01-80-C2-00-00-[01,02,04,0E]) shall be permanently configured in the FDB in
+ * TPMR components.
+ *
+ * The FDB entries for reserved MAC addresses shall specify filtering for all
+ * Bridge Ports and all VIDs. Management shall not provide the capability to
+ * modify or remove entries for reserved MAC addresses.
+ *
+ * The addresses in Table 8-1, Table 8-2, and Table 8-3 determine the scope of
+ * propagation of PDUs within a Bridged Network, as follows:
+ *
+ *   The Nearest Bridge group address (01-80-C2-00-00-0E) is an address that no
+ *   conformant Two-Port MAC Relay (TPMR) component, Service VLAN (S-VLAN)
+ *   component, Customer VLAN (C-VLAN) component, or MAC Bridge can forward.
+ *   PDUs transmitted using this destination address, or any other addresses
+ *   that appear in Table 8-1, Table 8-2, and Table 8-3
+ *   (01-80-C2-00-00-[00,01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F]), can
+ *   therefore travel no further than those stations that can be reached via a
+ *   single individual LAN from the originating station.
+ *
+ *   The Nearest non-TPMR Bridge group address (01-80-C2-00-00-03), is an
+ *   address that no conformant S-VLAN component, C-VLAN component, or MAC
+ *   Bridge can forward; however, this address is relayed by a TPMR component.
+ *   PDUs using this destination address, or any of the other addresses that
+ *   appear in both Table 8-1 and Table 8-2 but not in Table 8-3
+ *   (01-80-C2-00-00-[00,03,05,06,07,08,09,0A,0B,0C,0D,0F]), will be relayed by
+ *   any TPMRs but will propagate no further than the nearest S-VLAN component,
+ *   C-VLAN component, or MAC Bridge.
+ *
+ *   The Nearest Customer Bridge group address (01-80-C2-00-00-00) is an address
+ *   that no conformant C-VLAN component, MAC Bridge can forward; however, it is
+ *   relayed by TPMR components and S-VLAN components. PDUs using this
+ *   destination address, or any of the other addresses that appear in Table 8-1
+ *   but not in either Table 8-2 or Table 8-3 (01-80-C2-00-00-[00,0B,0C,0D,0F]),
+ *   will be relayed by TPMR components and S-VLAN components but will propagate
+ *   no further than the nearest C-VLAN component or MAC Bridge.
+ *
+ * Because the LLC Entity associated with each Bridge Port is provided via CPU
+ * port, we must not filter these frames but forward them to CPU port.
+ *
+ * In a Bridge, the transmission Port is majorly decided by ingress and egress
+ * rules, FDB, and spanning tree Port State functions of the Forwarding Process.
+ * For link-local frames, only CPU port should be designated as destination port
+ * in the FDB, and the other functions of the Forwarding Process must not
+ * interfere with the decision of the transmission Port. We call this process
+ * trapping frames to CPU port.
+ *
+ * Therefore, on the switch with CPU port architecture, link-local frames must
+ * be trapped to CPU port, and certain link-local frames received by a Port of a
+ * Bridge comprising a TPMR component or an S-VLAN component must be excluded
+ * from it.
+ *
+ * A Bridge of the switch with CPU port architecture cannot comprise a Two-Port
+ * MAC Relay (TPMR) component as a TPMR component supports only a subset of the
+ * functionality of a MAC Bridge. A Bridge comprising two Ports (Management Port
+ * doesn't count) of this architecture will either function as a standard MAC
+ * Bridge or a standard VLAN Bridge.
+ *
+ * Therefore, a Bridge of this architecture can only comprise S-VLAN components,
+ * C-VLAN components, or MAC Bridge components. Since there's no TPMR component,
+ * we don't need to relay PDUs using the destination addresses specified on the
+ * Nearest non-TPMR section, and the proportion of the Nearest Customer Bridge
+ * section where they must be relayed by TPMR components.
+ *
+ * One option to trap link-local frames to CPU port is to add static FDB entries
+ * with CPU port designated as destination port. However, because that
+ * Independent VLAN Learning (IVL) is being used on every VID, each entry only
+ * applies to a single VLAN Identifier (VID). For a Bridge comprising a MAC
+ * Bridge component or a C-VLAN component, there would have to be 16 times 4096
+ * entries. This switch intellectual property can only hold a maximum of 2048
+ * entries. Using this option, there also isn't a mechanism to prevent
+ * link-local frames from being discarded when the spanning tree Port State of
+ * the reception Port is discarding.
+ *
+ * The remaining option is to utilise the BPC, RGAC1, RGAC2, RGAC3, and RGAC4
+ * registers. Whilst this applies to every VID, it doesn't contain all of the
+ * reserved MAC addresses without affecting the remaining Standard Group MAC
+ * Addresses. The REV_UN frame tag utilised using the RGAC4 register covers the
+ * remaining 01-80-C2-00-00-[04,05,06,07,08,09,0A,0B,0C,0D,0F] destination
+ * addresses. It also includes the 01-80-C2-00-00-22 to 01-80-C2-00-00-FF
+ * destination addresses which may be relayed by MAC Bridges or VLAN Bridges.
+ * The latter option provides better but not complete conformance.
+ *
+ * This switch intellectual property also does not provide a mechanism to trap
+ * link-local frames with specific destination addresses to CPU port by Bridge,
+ * to conform to the filtering rules for the distinct Bridge components.
+ *
+ * Therefore, regardless of the type of the Bridge component, link-local frames
+ * with these destination addresses will be trapped to CPU port:
+ *
+ * 01-80-C2-00-00-[00,01,02,03,0E]
+ *
+ * In a Bridge comprising a MAC Bridge component or a C-VLAN component:
+ *
+ *   Link-local frames with these destination addresses won't be trapped to CPU
+ *   port which won't conform to IEEE Std 802.1Q-2022:
+ *
+ *   01-80-C2-00-00-[04,05,06,07,08,09,0A,0B,0C,0D,0F]
+ *
+ * In a Bridge comprising an S-VLAN component:
+ *
+ *   Link-local frames with these destination addresses will be trapped to CPU
+ *   port which won't conform to IEEE Std 802.1Q-2022:
+ *
+ *   01-80-C2-00-00-00
+ *
+ *   Link-local frames with these destination addresses won't be trapped to CPU
+ *   port which won't conform to IEEE Std 802.1Q-2022:
+ *
+ *   01-80-C2-00-00-[04,05,06,07,08,09,0A]
+ *
+ * To trap link-local frames to CPU port as conformant as this switch
+ * intellectual property can allow, link-local frames are made to be regarded as
+ * Bridge Protocol Data Units (BPDUs). This is because this switch intellectual
+ * property only lets the frames regarded as BPDUs bypass the spanning tree Port
+ * State function of the Forwarding Process.
+ *
+ * The only remaining interference is the ingress rules. When the reception Port
+ * has no PVID assigned on software, VLAN-untagged frames won't be allowed in.
+ * There doesn't seem to be a mechanism on the switch intellectual property to
+ * have link-local frames bypass this function of the Forwarding Process.
+ */
 static void
 mt753x_trap_frames(struct mt7530_priv *priv)
 {
-	/* Trap BPDUs to the CPU port(s) */
-	mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
-		   MT753X_BPDU_CPU_ONLY);
-
-	/* Trap 802.1X PAE frames to the CPU port(s) */
-	mt7530_rmw(priv, MT753X_BPC, MT753X_PAE_PORT_FW_MASK,
-		   MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY));
-
-	/* Trap LLDP frames with :0E MAC DA to the CPU port(s) */
-	mt7530_rmw(priv, MT753X_RGAC2, MT753X_R0E_PORT_FW_MASK,
-		   MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY));
+	/* Trap 802.1X PAE frames and BPDUs to the CPU port(s) and egress them
+	 * VLAN-untagged.
+	 */
+	mt7530_rmw(priv, MT753X_BPC,
+		   MT753X_PAE_BPDU_FR | MT753X_PAE_EG_TAG_MASK |
+			   MT753X_PAE_PORT_FW_MASK | MT753X_BPDU_EG_TAG_MASK |
+			   MT753X_BPDU_PORT_FW_MASK,
+		   MT753X_PAE_BPDU_FR |
+			   MT753X_PAE_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
+			   MT753X_PAE_PORT_FW(MT753X_BPDU_CPU_ONLY) |
+			   MT753X_BPDU_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
+			   MT753X_BPDU_CPU_ONLY);
+
+	/* Trap frames with :01 and :02 MAC DAs to the CPU port(s) and egress
+	 * them VLAN-untagged.
+	 */
+	mt7530_rmw(priv, MT753X_RGAC1,
+		   MT753X_R02_BPDU_FR | MT753X_R02_EG_TAG_MASK |
+			   MT753X_R02_PORT_FW_MASK | MT753X_R01_BPDU_FR |
+			   MT753X_R01_EG_TAG_MASK | MT753X_R01_PORT_FW_MASK,
+		   MT753X_R02_BPDU_FR |
+			   MT753X_R02_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
+			   MT753X_R02_PORT_FW(MT753X_BPDU_CPU_ONLY) |
+			   MT753X_R01_BPDU_FR |
+			   MT753X_R01_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
+			   MT753X_BPDU_CPU_ONLY);
+
+	/* Trap frames with :03 and :0E MAC DAs to the CPU port(s) and egress
+	 * them VLAN-untagged.
+	 */
+	mt7530_rmw(priv, MT753X_RGAC2,
+		   MT753X_R0E_BPDU_FR | MT753X_R0E_EG_TAG_MASK |
+			   MT753X_R0E_PORT_FW_MASK | MT753X_R03_BPDU_FR |
+			   MT753X_R03_EG_TAG_MASK | MT753X_R03_PORT_FW_MASK,
+		   MT753X_R0E_BPDU_FR |
+			   MT753X_R0E_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
+			   MT753X_R0E_PORT_FW(MT753X_BPDU_CPU_ONLY) |
+			   MT753X_R03_BPDU_FR |
+			   MT753X_R03_EG_TAG(MT7530_VLAN_EG_UNTAGGED) |
+			   MT753X_BPDU_CPU_ONLY);
 }
 
 static int
@@ -1750,14 +1947,16 @@
 
 static int mt753x_mirror_port_get(unsigned int id, u32 val)
 {
-	return (id == ID_MT7531) ? MT7531_MIRROR_PORT_GET(val) :
-				   MIRROR_PORT(val);
+	return (id == ID_MT7531 || id == ID_MT7988) ?
+		       MT7531_MIRROR_PORT_GET(val) :
+		       MIRROR_PORT(val);
 }
 
 static int mt753x_mirror_port_set(unsigned int id, u32 val)
 {
-	return (id == ID_MT7531) ? MT7531_MIRROR_PORT_SET(val) :
-				   MIRROR_PORT(val);
+	return (id == ID_MT7531 || id == ID_MT7988) ?
+		       MT7531_MIRROR_PORT_SET(val) :
+		       MIRROR_PORT(val);
 }
 
 static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
@@ -2243,11 +2442,11 @@
 	 */
 	if (priv->mcm) {
 		reset_control_assert(priv->rstc);
-		usleep_range(1000, 1100);
+		usleep_range(5000, 5100);
 		reset_control_deassert(priv->rstc);
 	} else {
 		gpiod_set_value_cansleep(priv->reset, 0);
-		usleep_range(1000, 1100);
+		usleep_range(5000, 5100);
 		gpiod_set_value_cansleep(priv->reset, 1);
 	}
 
@@ -2272,8 +2471,6 @@
 		     SYS_CTRL_PHY_RST | SYS_CTRL_SW_RST |
 		     SYS_CTRL_REG_RST);
 
-	mt7530_pll_setup(priv);
-
 	/* Lower Tx driving for TRGMII path */
 	for (i = 0; i < NUM_TRGMII_CTRL; i++)
 		mt7530_write(priv, MT7530_TRGMII_TD_ODT(i),
@@ -2291,6 +2488,9 @@
 
 	priv->p6_interface = PHY_INTERFACE_MODE_NA;
 
+	if ((val & HWTRAP_XTAL_MASK) == HWTRAP_XTAL_40MHZ)
+		mt7530_pll_setup(priv);
+
 	mt753x_trap_frames(priv);
 
 	/* Enable and reset MIB counters */
@@ -2320,6 +2520,9 @@
 			   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
 	}
 
+	/* Allow mirroring frames received on the local port (monitor port). */
+	mt7530_set(priv, MT753X_AGC, LOCAL_EN);
+
 	/* Setup VLAN ID 0 for VLAN-unaware bridges */
 	ret = mt7530_setup_vlan0(priv);
 	if (ret)
@@ -2428,6 +2631,9 @@
 			   PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
 	}
 
+	/* Allow mirroring frames received on the local port (monitor port). */
+	mt7530_set(priv, MT753X_AGC, LOCAL_EN);
+
 	/* Flush the FDB table */
 	ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
 	if (ret < 0)
@@ -2449,11 +2655,11 @@
 	 */
 	if (priv->mcm) {
 		reset_control_assert(priv->rstc);
-		usleep_range(1000, 1100);
+		usleep_range(5000, 5100);
 		reset_control_deassert(priv->rstc);
 	} else {
 		gpiod_set_value_cansleep(priv->reset, 0);
-		usleep_range(1000, 1100);
+		usleep_range(5000, 5100);
 		gpiod_set_value_cansleep(priv->reset, 1);
 	}
 
@@ -2506,18 +2712,25 @@
 	priv->p5_interface = PHY_INTERFACE_MODE_NA;
 	priv->p6_interface = PHY_INTERFACE_MODE_NA;
 
-	/* Enable PHY core PLL, since phy_device has not yet been created
-	 * provided for phy_[read,write]_mmd_indirect is called, we provide
-	 * our own mt7531_ind_mmd_phy_[read,write] to complete this
-	 * function.
+	/* Enable Energy-Efficient Ethernet (EEE) and PHY core PLL, since
+	 * phy_device has not yet been created provided for
+	 * phy_[read,write]_mmd_indirect is called, we provide our own
+	 * mt7531_ind_mmd_phy_[read,write] to complete this function.
 	 */
 	val = mt7531_ind_c45_phy_read(priv, MT753X_CTRL_PHY_ADDR,
 				      MDIO_MMD_VEND2, CORE_PLL_GROUP4);
-	val |= MT7531_PHY_PLL_BYPASS_MODE;
+	val |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE;
 	val &= ~MT7531_PHY_PLL_OFF;
 	mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2,
 				 CORE_PLL_GROUP4, val);
 
+	/* Disable EEE advertisement on the switch PHYs. */
+	for (i = MT753X_CTRL_PHY_ADDR;
+	     i < MT753X_CTRL_PHY_ADDR + MT7530_NUM_PHYS; i++) {
+		mt7531_ind_c45_phy_write(priv, i, MDIO_MMD_AN, MDIO_AN_EEE_ADV,
+					 0);
+	}
+
 	mt7531_setup_common(ds);
 
 	/* Setup VLAN ID 0 for VLAN-unaware bridges */
--- linux-qcom-6.8.0.orig/drivers/net/dsa/mt7530.h
+++ linux-qcom-6.8.0/drivers/net/dsa/mt7530.h
@@ -32,6 +32,10 @@
 #define SYSC_REG_RSTCTRL		0x34
 #define  RESET_MCM			BIT(2)
 
+/* Register for ARL global control */
+#define MT753X_AGC			0xc
+#define  LOCAL_EN			BIT(7)
+
 /* Registers to mac forward control for unknown frames */
 #define MT7530_MFC			0x10
 #define  BC_FFP(x)			(((x) & 0xff) << 24)
@@ -65,14 +69,38 @@
 
 /* Registers for BPDU and PAE frame control*/
 #define MT753X_BPC			0x24
-#define  MT753X_BPDU_PORT_FW_MASK	GENMASK(2, 0)
+#define  MT753X_PAE_BPDU_FR		BIT(25)
+#define  MT753X_PAE_EG_TAG_MASK		GENMASK(24, 22)
+#define  MT753X_PAE_EG_TAG(x)		FIELD_PREP(MT753X_PAE_EG_TAG_MASK, x)
 #define  MT753X_PAE_PORT_FW_MASK	GENMASK(18, 16)
 #define  MT753X_PAE_PORT_FW(x)		FIELD_PREP(MT753X_PAE_PORT_FW_MASK, x)
+#define  MT753X_BPDU_EG_TAG_MASK	GENMASK(8, 6)
+#define  MT753X_BPDU_EG_TAG(x)		FIELD_PREP(MT753X_BPDU_EG_TAG_MASK, x)
+#define  MT753X_BPDU_PORT_FW_MASK	GENMASK(2, 0)
+
+/* Register for :01 and :02 MAC DA frame control */
+#define MT753X_RGAC1			0x28
+#define  MT753X_R02_BPDU_FR		BIT(25)
+#define  MT753X_R02_EG_TAG_MASK		GENMASK(24, 22)
+#define  MT753X_R02_EG_TAG(x)		FIELD_PREP(MT753X_R02_EG_TAG_MASK, x)
+#define  MT753X_R02_PORT_FW_MASK	GENMASK(18, 16)
+#define  MT753X_R02_PORT_FW(x)		FIELD_PREP(MT753X_R02_PORT_FW_MASK, x)
+#define  MT753X_R01_BPDU_FR		BIT(9)
+#define  MT753X_R01_EG_TAG_MASK		GENMASK(8, 6)
+#define  MT753X_R01_EG_TAG(x)		FIELD_PREP(MT753X_R01_EG_TAG_MASK, x)
+#define  MT753X_R01_PORT_FW_MASK	GENMASK(2, 0)
 
 /* Register for :03 and :0E MAC DA frame control */
 #define MT753X_RGAC2			0x2c
+#define  MT753X_R0E_BPDU_FR		BIT(25)
+#define  MT753X_R0E_EG_TAG_MASK		GENMASK(24, 22)
+#define  MT753X_R0E_EG_TAG(x)		FIELD_PREP(MT753X_R0E_EG_TAG_MASK, x)
 #define  MT753X_R0E_PORT_FW_MASK	GENMASK(18, 16)
 #define  MT753X_R0E_PORT_FW(x)		FIELD_PREP(MT753X_R0E_PORT_FW_MASK, x)
+#define  MT753X_R03_BPDU_FR		BIT(9)
+#define  MT753X_R03_EG_TAG_MASK		GENMASK(8, 6)
+#define  MT753X_R03_EG_TAG(x)		FIELD_PREP(MT753X_R03_EG_TAG_MASK, x)
+#define  MT753X_R03_PORT_FW_MASK	GENMASK(2, 0)
 
 enum mt753x_bpdu_port_fw {
 	MT753X_BPDU_FOLLOW_MFC,
@@ -253,6 +281,7 @@
 enum mt7530_vlan_port_eg_tag {
 	MT7530_VLAN_EG_DISABLED = 0,
 	MT7530_VLAN_EG_CONSISTENT = 1,
+	MT7530_VLAN_EG_UNTAGGED = 4,
 };
 
 enum mt7530_vlan_port_attr {
@@ -605,6 +634,7 @@
 #define  RG_SYSPLL_DDSFBK_EN		BIT(12)
 #define  RG_SYSPLL_BIAS_EN		BIT(11)
 #define  RG_SYSPLL_BIAS_LPF_EN		BIT(10)
+#define  MT7531_RG_SYSPLL_DMY2		BIT(6)
 #define  MT7531_PHY_PLL_OFF		BIT(5)
 #define  MT7531_PHY_PLL_BYPASS_MODE	BIT(4)
 
--- linux-qcom-6.8.0.orig/drivers/net/dsa/mv88e6xxx/chip.c
+++ linux-qcom-6.8.0/drivers/net/dsa/mv88e6xxx/chip.c
@@ -131,8 +131,8 @@
 {
 	struct mv88e6xxx_mdio_bus *mdio_bus;
 
-	mdio_bus = list_first_entry(&chip->mdios, struct mv88e6xxx_mdio_bus,
-				    list);
+	mdio_bus = list_first_entry_or_null(&chip->mdios,
+					    struct mv88e6xxx_mdio_bus, list);
 	if (!mdio_bus)
 		return NULL;
 
@@ -566,13 +566,61 @@
 		phy_interface_set_rgmii(supported);
 }
 
-static void mv88e6250_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
-				       struct phylink_config *config)
+static void
+mv88e6250_setup_supported_interfaces(struct mv88e6xxx_chip *chip, int port,
+				     struct phylink_config *config)
 {
 	unsigned long *supported = config->supported_interfaces;
+	int err;
+	u16 reg;
 
-	/* Translate the default cmode */
-	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
+	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &reg);
+	if (err) {
+		dev_err(chip->dev, "p%d: failed to read port status\n", port);
+		return;
+	}
+
+	switch (reg & MV88E6250_PORT_STS_PORTMODE_MASK) {
+	case MV88E6250_PORT_STS_PORTMODE_MII_10_HALF_PHY:
+	case MV88E6250_PORT_STS_PORTMODE_MII_100_HALF_PHY:
+	case MV88E6250_PORT_STS_PORTMODE_MII_10_FULL_PHY:
+	case MV88E6250_PORT_STS_PORTMODE_MII_100_FULL_PHY:
+		__set_bit(PHY_INTERFACE_MODE_REVMII, supported);
+		break;
+
+	case MV88E6250_PORT_STS_PORTMODE_MII_HALF:
+	case MV88E6250_PORT_STS_PORTMODE_MII_FULL:
+		__set_bit(PHY_INTERFACE_MODE_MII, supported);
+		break;
+
+	case MV88E6250_PORT_STS_PORTMODE_MII_DUAL_100_RMII_FULL_PHY:
+	case MV88E6250_PORT_STS_PORTMODE_MII_200_RMII_FULL_PHY:
+	case MV88E6250_PORT_STS_PORTMODE_MII_10_100_RMII_HALF_PHY:
+	case MV88E6250_PORT_STS_PORTMODE_MII_10_100_RMII_FULL_PHY:
+		__set_bit(PHY_INTERFACE_MODE_REVRMII, supported);
+		break;
+
+	case MV88E6250_PORT_STS_PORTMODE_MII_DUAL_100_RMII_FULL:
+	case MV88E6250_PORT_STS_PORTMODE_MII_10_100_RMII_FULL:
+		__set_bit(PHY_INTERFACE_MODE_RMII, supported);
+		break;
+
+	case MV88E6250_PORT_STS_PORTMODE_MII_100_RGMII:
+		__set_bit(PHY_INTERFACE_MODE_RGMII, supported);
+		break;
+
+	default:
+		dev_err(chip->dev,
+			"p%d: invalid port mode in status register: %04x\n",
+			port, reg);
+	}
+}
+
+static void mv88e6250_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
+				       struct phylink_config *config)
+{
+	if (!mv88e6xxx_phy_is_internal(chip, port))
+		mv88e6250_setup_supported_interfaces(chip, port, config);
 
 	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100;
 }
@@ -649,6 +697,18 @@
 	}
 }
 
+static void mv88e632x_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
+				       struct phylink_config *config)
+{
+	unsigned long *supported = config->supported_interfaces;
+
+	/* Translate the default cmode */
+	mv88e6xxx_translate_cmode(chip->ports[port].cmode, supported);
+
+	config->mac_capabilities = MAC_SYM_PAUSE | MAC_10 | MAC_100 |
+				   MAC_1000FD;
+}
+
 static void mv88e6341_phylink_get_caps(struct mv88e6xxx_chip *chip, int port,
 				       struct phylink_config *config)
 {
@@ -3075,6 +3135,7 @@
 static void mv88e6xxx_hardware_reset(struct mv88e6xxx_chip *chip)
 {
 	struct gpio_desc *gpiod = chip->reset;
+	int err;
 
 	/* If there is a GPIO connected to the reset pin, toggle it */
 	if (gpiod) {
@@ -3083,17 +3144,26 @@
 		 * mid-byte, causing the first EEPROM read after the reset
 		 * from the wrong location resulting in the switch booting
 		 * to wrong mode and inoperable.
+		 * For this reason, switch families with EEPROM support
+		 * generally wait for EEPROM loads to complete as their pre-
+		 * and post-reset handlers.
 		 */
-		if (chip->info->ops->get_eeprom)
-			mv88e6xxx_g2_eeprom_wait(chip);
+		if (chip->info->ops->hardware_reset_pre) {
+			err = chip->info->ops->hardware_reset_pre(chip);
+			if (err)
+				dev_err(chip->dev, "pre-reset error: %d\n", err);
+		}
 
 		gpiod_set_value_cansleep(gpiod, 1);
 		usleep_range(10000, 20000);
 		gpiod_set_value_cansleep(gpiod, 0);
 		usleep_range(10000, 20000);
 
-		if (chip->info->ops->get_eeprom)
-			mv88e6xxx_g2_eeprom_wait(chip);
+		if (chip->info->ops->hardware_reset_post) {
+			err = chip->info->ops->hardware_reset_post(chip);
+			if (err)
+				dev_err(chip->dev, "post-reset error: %d\n", err);
+		}
 	}
 }
 
@@ -3534,7 +3604,8 @@
 	mv88e6xxx_reg_lock(chip);
 	if (chip->info->ops->port_set_jumbo_size)
 		ret = chip->info->ops->port_set_jumbo_size(chip, port, new_mtu);
-	else if (chip->info->ops->set_max_frame_size)
+	else if (chip->info->ops->set_max_frame_size &&
+		 dsa_is_cpu_port(ds, port))
 		ret = chip->info->ops->set_max_frame_size(chip, new_mtu);
 	mv88e6xxx_reg_unlock(chip);
 
@@ -4320,6 +4391,8 @@
 	.watchdog_ops = &mv88e6390_watchdog_ops,
 	.mgmt_rsvd2cpu =  mv88e6390_g1_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -4510,6 +4583,8 @@
 	.watchdog_ops = &mv88e6097_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6352_g1_rmu_disable,
 	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -4610,6 +4685,8 @@
 	.watchdog_ops = &mv88e6097_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6352_g1_rmu_disable,
 	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -4704,6 +4781,8 @@
 	.watchdog_ops = &mv88e6390_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -4762,6 +4841,8 @@
 	.watchdog_ops = &mv88e6390_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -4818,6 +4899,8 @@
 	.watchdog_ops = &mv88e6390_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -4877,6 +4960,8 @@
 	.watchdog_ops = &mv88e6097_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6352_g1_rmu_disable,
 	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -4930,6 +5015,8 @@
 	.watchdog_ops = &mv88e6250_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6250_g1_wait_eeprom_done_prereset,
+	.hardware_reset_post = mv88e6xxx_g1_wait_eeprom_done,
 	.reset = mv88e6250_g1_reset,
 	.vtu_getnext = mv88e6185_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
@@ -4977,6 +5064,8 @@
 	.watchdog_ops = &mv88e6390_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -5036,13 +5125,15 @@
 	.watchdog_ops = &mv88e6390_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.vtu_getnext = mv88e6185_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
 	.gpio_ops = &mv88e6352_gpio_ops,
 	.avb_ops = &mv88e6352_avb_ops,
 	.ptp_ops = &mv88e6352_ptp_ops,
-	.phylink_get_caps = mv88e6185_phylink_get_caps,
+	.phylink_get_caps = mv88e632x_phylink_get_caps,
 };
 
 static const struct mv88e6xxx_ops mv88e6321_ops = {
@@ -5082,13 +5173,15 @@
 	.set_egress_port = mv88e6095_g1_set_egress_port,
 	.watchdog_ops = &mv88e6390_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.vtu_getnext = mv88e6185_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
 	.gpio_ops = &mv88e6352_gpio_ops,
 	.avb_ops = &mv88e6352_avb_ops,
 	.ptp_ops = &mv88e6352_ptp_ops,
-	.phylink_get_caps = mv88e6185_phylink_get_caps,
+	.phylink_get_caps = mv88e632x_phylink_get_caps,
 };
 
 static const struct mv88e6xxx_ops mv88e6341_ops = {
@@ -5132,6 +5225,8 @@
 	.watchdog_ops = &mv88e6390_watchdog_ops,
 	.mgmt_rsvd2cpu =  mv88e6390_g1_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -5287,6 +5382,8 @@
 	.watchdog_ops = &mv88e6097_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6352_g1_rmu_disable,
 	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -5349,6 +5446,8 @@
 	.watchdog_ops = &mv88e6390_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -5411,6 +5510,8 @@
 	.watchdog_ops = &mv88e6390_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -5476,6 +5577,8 @@
 	.watchdog_ops = &mv88e6393x_watchdog_ops,
 	.mgmt_rsvd2cpu = mv88e6393x_port_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
+	.hardware_reset_pre = mv88e6xxx_g2_eeprom_wait,
+	.hardware_reset_post = mv88e6xxx_g2_eeprom_wait,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
 	.atu_get_hash = mv88e6165_g1_atu_get_hash,
@@ -5500,8 +5603,12 @@
 		.family = MV88E6XXX_FAMILY_6250,
 		.name = "Marvell 88E6020",
 		.num_databases = 64,
-		.num_ports = 4,
+		/* Ports 2-4 are not routed to pins
+		 * => usable ports 0, 1, 5, 6
+		 */
+		.num_ports = 7,
 		.num_internal_phys = 2,
+		.invalid_port_mask = BIT(2) | BIT(3) | BIT(4),
 		.max_vid = 4095,
 		.port_base_addr = 0x8,
 		.phy_base_addr = 0x0,
@@ -5650,7 +5757,7 @@
 		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6141,
 		.family = MV88E6XXX_FAMILY_6341,
 		.name = "Marvell 88E6141",
-		.num_databases = 4096,
+		.num_databases = 256,
 		.num_macs = 2048,
 		.num_ports = 6,
 		.num_internal_phys = 5,
@@ -6109,7 +6216,7 @@
 		.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
 		.family = MV88E6XXX_FAMILY_6341,
 		.name = "Marvell 88E6341",
-		.num_databases = 4096,
+		.num_databases = 256,
 		.num_macs = 2048,
 		.num_internal_phys = 5,
 		.num_ports = 6,
@@ -6215,7 +6322,7 @@
 		.invalid_port_mask = BIT(1) | BIT(2) | BIT(8),
 		.num_internal_phys = 5,
 		.internal_phys_offset = 3,
-		.max_vid = 4095,
+		.max_vid = 8191,
 		.max_sid = 63,
 		.port_base_addr = 0x0,
 		.phy_base_addr = 0x0,
--- linux-qcom-6.8.0.orig/drivers/net/dsa/mv88e6xxx/chip.h
+++ linux-qcom-6.8.0/drivers/net/dsa/mv88e6xxx/chip.h
@@ -206,6 +206,7 @@
 struct mv88e6xxx_avb_ops;
 struct mv88e6xxx_ptp_ops;
 struct mv88e6xxx_pcs_ops;
+struct mv88e6xxx_cc_coeffs;
 
 struct mv88e6xxx_irq {
 	u16 masked;
@@ -408,6 +409,7 @@
 	struct cyclecounter	tstamp_cc;
 	struct timecounter	tstamp_tc;
 	struct delayed_work	overflow_work;
+	const struct mv88e6xxx_cc_coeffs *cc_coeffs;
 
 	struct ptp_clock	*ptp_clock;
 	struct ptp_clock_info	ptp_clock_info;
@@ -487,6 +489,12 @@
 	int (*ppu_enable)(struct mv88e6xxx_chip *chip);
 	int (*ppu_disable)(struct mv88e6xxx_chip *chip);
 
+	/* Additional handlers to run before and after hard reset, to make sure
+	 * that the switch and EEPROM are in a good state.
+	 */
+	int (*hardware_reset_pre)(struct mv88e6xxx_chip *chip);
+	int (*hardware_reset_post)(struct mv88e6xxx_chip *chip);
+
 	/* Switch Software Reset */
 	int (*reset)(struct mv88e6xxx_chip *chip);
 
@@ -725,10 +733,6 @@
 	int arr1_sts_reg;
 	int dep_sts_reg;
 	u32 rx_filters;
-	u32 cc_shift;
-	u32 cc_mult;
-	u32 cc_mult_num;
-	u32 cc_mult_dem;
 };
 
 struct mv88e6xxx_pcs_ops {
--- linux-qcom-6.8.0.orig/drivers/net/dsa/mv88e6xxx/global1.c
+++ linux-qcom-6.8.0/drivers/net/dsa/mv88e6xxx/global1.c
@@ -75,6 +75,95 @@
 	return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1);
 }
 
+static int mv88e6250_g1_eeprom_reload(struct mv88e6xxx_chip *chip)
+{
+	/* MV88E6185_G1_CTL1_RELOAD_EEPROM is also valid for 88E6250 */
+	int bit = __bf_shf(MV88E6185_G1_CTL1_RELOAD_EEPROM);
+	u16 val;
+	int err;
+
+	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &val);
+	if (err)
+		return err;
+
+	val |= MV88E6185_G1_CTL1_RELOAD_EEPROM;
+
+	err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, val);
+	if (err)
+		return err;
+
+	return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_CTL1, bit, 0);
+}
+
+/* Returns 0 when done, -EBUSY when waiting, other negative codes on error */
+static int mv88e6xxx_g1_is_eeprom_done(struct mv88e6xxx_chip *chip)
+{
+	u16 val;
+	int err;
+
+	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &val);
+	if (err < 0) {
+		dev_err(chip->dev, "Error reading status");
+		return err;
+	}
+
+	/* If the switch is still resetting, it may not
+	 * respond on the bus, and so MDIO read returns
+	 * 0xffff. Differentiate between that, and waiting for
+	 * the EEPROM to be done by bit 0 being set.
+	 */
+	if (val == 0xffff || !(val & BIT(MV88E6XXX_G1_STS_IRQ_EEPROM_DONE)))
+		return -EBUSY;
+
+	return 0;
+}
+
+/* As the EEInt (EEPROM done) flag clears on read if the status register, this
+ * function must be called directly after a hard reset or EEPROM ReLoad request,
+ * or the done condition may have been missed
+ */
+int mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip)
+{
+	const unsigned long timeout = jiffies + 1 * HZ;
+	int ret;
+
+	/* Wait up to 1 second for the switch to finish reading the
+	 * EEPROM.
+	 */
+	while (time_before(jiffies, timeout)) {
+		ret = mv88e6xxx_g1_is_eeprom_done(chip);
+		if (ret != -EBUSY)
+			return ret;
+	}
+
+	dev_err(chip->dev, "Timeout waiting for EEPROM done");
+	return -ETIMEDOUT;
+}
+
+int mv88e6250_g1_wait_eeprom_done_prereset(struct mv88e6xxx_chip *chip)
+{
+	int ret;
+
+	ret = mv88e6xxx_g1_is_eeprom_done(chip);
+	if (ret != -EBUSY)
+		return ret;
+
+	/* Pre-reset, we don't know the state of the switch - when
+	 * mv88e6xxx_g1_is_eeprom_done() returns -EBUSY, that may be because
+	 * the switch is actually busy reading the EEPROM, or because
+	 * MV88E6XXX_G1_STS_IRQ_EEPROM_DONE has been cleared by an unrelated
+	 * status register read already.
+	 *
+	 * To account for the latter case, trigger another EEPROM reload for
+	 * another chance at seeing the done flag.
+	 */
+	ret = mv88e6250_g1_eeprom_reload(chip);
+	if (ret)
+		return ret;
+
+	return mv88e6xxx_g1_wait_eeprom_done(chip);
+}
+
 /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1
  * Offset 0x02: Switch MAC Address Register Bytes 2 & 3
  * Offset 0x03: Switch MAC Address Register Bytes 4 & 5
--- linux-qcom-6.8.0.orig/drivers/net/dsa/mv88e6xxx/global1.h
+++ linux-qcom-6.8.0/drivers/net/dsa/mv88e6xxx/global1.h
@@ -282,6 +282,8 @@
 int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip);
 int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip);
 int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip);
+int mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip);
+int mv88e6250_g1_wait_eeprom_done_prereset(struct mv88e6xxx_chip *chip);
 
 int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip);
 int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip);
--- linux-qcom-6.8.0.orig/drivers/net/dsa/mv88e6xxx/global1_atu.c
+++ linux-qcom-6.8.0/drivers/net/dsa/mv88e6xxx/global1_atu.c
@@ -457,7 +457,8 @@
 		trace_mv88e6xxx_atu_full_violation(chip->dev, spid,
 						   entry.portvec, entry.mac,
 						   fid);
-		chip->ports[spid].atu_full_violation++;
+		if (spid < ARRAY_SIZE(chip->ports))
+			chip->ports[spid].atu_full_violation++;
 	}
 
 	return IRQ_HANDLED;
--- linux-qcom-6.8.0.orig/drivers/net/dsa/mv88e6xxx/port.c
+++ linux-qcom-6.8.0/drivers/net/dsa/mv88e6xxx/port.c
@@ -1713,6 +1713,7 @@
 	ptr = shift / 8;
 	shift %= 8;
 	mask >>= ptr * 8;
+	ptr <<= 8;
 
 	err = mv88e6393x_port_policy_read(chip, port, ptr, &reg);
 	if (err)
--- linux-qcom-6.8.0.orig/drivers/net/dsa/mv88e6xxx/port.h
+++ linux-qcom-6.8.0/drivers/net/dsa/mv88e6xxx/port.h
@@ -25,10 +25,25 @@
 #define MV88E6250_PORT_STS_PORTMODE_PHY_100_HALF	0x0900
 #define MV88E6250_PORT_STS_PORTMODE_PHY_10_FULL		0x0a00
 #define MV88E6250_PORT_STS_PORTMODE_PHY_100_FULL	0x0b00
-#define MV88E6250_PORT_STS_PORTMODE_MII_10_HALF		0x0c00
-#define MV88E6250_PORT_STS_PORTMODE_MII_100_HALF	0x0d00
-#define MV88E6250_PORT_STS_PORTMODE_MII_10_FULL		0x0e00
-#define MV88E6250_PORT_STS_PORTMODE_MII_100_FULL	0x0f00
+/* - Modes with PHY suffix use output instead of input clock
+ * - Modes without RMII or RGMII use MII
+ * - Modes without speed do not have a fixed speed specified in the manual
+ *   ("DC to x MHz" - variable clock support?)
+ */
+#define MV88E6250_PORT_STS_PORTMODE_MII_DISABLED		0x0000
+#define MV88E6250_PORT_STS_PORTMODE_MII_100_RGMII		0x0100
+#define MV88E6250_PORT_STS_PORTMODE_MII_DUAL_100_RMII_FULL_PHY	0x0200
+#define MV88E6250_PORT_STS_PORTMODE_MII_200_RMII_FULL_PHY	0x0400
+#define MV88E6250_PORT_STS_PORTMODE_MII_DUAL_100_RMII_FULL	0x0600
+#define MV88E6250_PORT_STS_PORTMODE_MII_10_100_RMII_FULL	0x0700
+#define MV88E6250_PORT_STS_PORTMODE_MII_HALF			0x0800
+#define MV88E6250_PORT_STS_PORTMODE_MII_10_100_RMII_HALF_PHY	0x0900
+#define MV88E6250_PORT_STS_PORTMODE_MII_FULL			0x0a00
+#define MV88E6250_PORT_STS_PORTMODE_MII_10_100_RMII_FULL_PHY	0x0b00
+#define MV88E6250_PORT_STS_PORTMODE_MII_10_HALF_PHY		0x0c00
+#define MV88E6250_PORT_STS_PORTMODE_MII_100_HALF_PHY		0x0d00
+#define MV88E6250_PORT_STS_PORTMODE_MII_10_FULL_PHY		0x0e00
+#define MV88E6250_PORT_STS_PORTMODE_MII_100_FULL_PHY		0x0f00
 #define MV88E6XXX_PORT_STS_LINK			0x0800
 #define MV88E6XXX_PORT_STS_DUPLEX		0x0400
 #define MV88E6XXX_PORT_STS_SPEED_MASK		0x0300
--- linux-qcom-6.8.0.orig/drivers/net/dsa/mv88e6xxx/ptp.c
+++ linux-qcom-6.8.0/drivers/net/dsa/mv88e6xxx/ptp.c
@@ -18,6 +18,13 @@
 
 #define MV88E6XXX_MAX_ADJ_PPB	1000000
 
+struct mv88e6xxx_cc_coeffs {
+	u32 cc_shift;
+	u32 cc_mult;
+	u32 cc_mult_num;
+	u32 cc_mult_dem;
+};
+
 /* Family MV88E6250:
  * Raw timestamps are in units of 10-ns clock periods.
  *
@@ -25,22 +32,43 @@
  * simplifies to
  * clkadj = scaled_ppm * 2^7 / 5^5
  */
-#define MV88E6250_CC_SHIFT	28
-#define MV88E6250_CC_MULT	(10 << MV88E6250_CC_SHIFT)
-#define MV88E6250_CC_MULT_NUM	(1 << 7)
-#define MV88E6250_CC_MULT_DEM	3125ULL
+#define MV88E6XXX_CC_10NS_SHIFT 28
+static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_10ns_coeffs = {
+	.cc_shift = MV88E6XXX_CC_10NS_SHIFT,
+	.cc_mult = 10 << MV88E6XXX_CC_10NS_SHIFT,
+	.cc_mult_num = 1 << 7,
+	.cc_mult_dem = 3125ULL,
+};
 
-/* Other families:
+/* Other families except MV88E6393X in internal clock mode:
  * Raw timestamps are in units of 8-ns clock periods.
  *
  * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16)
  * simplifies to
  * clkadj = scaled_ppm * 2^9 / 5^6
  */
-#define MV88E6XXX_CC_SHIFT	28
-#define MV88E6XXX_CC_MULT	(8 << MV88E6XXX_CC_SHIFT)
-#define MV88E6XXX_CC_MULT_NUM	(1 << 9)
-#define MV88E6XXX_CC_MULT_DEM	15625ULL
+#define MV88E6XXX_CC_8NS_SHIFT 28
+static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_8ns_coeffs = {
+	.cc_shift = MV88E6XXX_CC_8NS_SHIFT,
+	.cc_mult = 8 << MV88E6XXX_CC_8NS_SHIFT,
+	.cc_mult_num = 1 << 9,
+	.cc_mult_dem = 15625ULL
+};
+
+/* Family MV88E6393X using internal clock:
+ * Raw timestamps are in units of 4-ns clock periods.
+ *
+ * clkadj = scaled_ppm * 4*2^28 / (10^6 * 2^16)
+ * simplifies to
+ * clkadj = scaled_ppm * 2^8 / 5^6
+ */
+#define MV88E6XXX_CC_4NS_SHIFT 28
+static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_4ns_coeffs = {
+	.cc_shift = MV88E6XXX_CC_4NS_SHIFT,
+	.cc_mult = 4 << MV88E6XXX_CC_4NS_SHIFT,
+	.cc_mult_num = 1 << 8,
+	.cc_mult_dem = 15625ULL
+};
 
 #define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100)
 
@@ -83,6 +111,33 @@
 	return chip->info->ops->gpio_ops->set_pctl(chip, pin, func);
 }
 
+static const struct mv88e6xxx_cc_coeffs *
+mv88e6xxx_cc_coeff_get(struct mv88e6xxx_chip *chip)
+{
+	u16 period_ps;
+	int err;
+
+	err = mv88e6xxx_tai_read(chip, MV88E6XXX_TAI_CLOCK_PERIOD, &period_ps, 1);
+	if (err) {
+		dev_err(chip->dev, "failed to read cycle counter period: %d\n",
+			err);
+		return ERR_PTR(err);
+	}
+
+	switch (period_ps) {
+	case 4000:
+		return &mv88e6xxx_cc_4ns_coeffs;
+	case 8000:
+		return &mv88e6xxx_cc_8ns_coeffs;
+	case 10000:
+		return &mv88e6xxx_cc_10ns_coeffs;
+	default:
+		dev_err(chip->dev, "unexpected cycle counter period of %u ps\n",
+			period_ps);
+		return ERR_PTR(-ENODEV);
+	}
+}
+
 static u64 mv88e6352_ptp_clock_read(const struct cyclecounter *cc)
 {
 	struct mv88e6xxx_chip *chip = cc_to_chip(cc);
@@ -204,7 +259,6 @@
 static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
 {
 	struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
-	const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
 	int neg_adj = 0;
 	u32 diff, mult;
 	u64 adj;
@@ -214,10 +268,10 @@
 		scaled_ppm = -scaled_ppm;
 	}
 
-	mult = ptp_ops->cc_mult;
-	adj = ptp_ops->cc_mult_num;
+	mult = chip->cc_coeffs->cc_mult;
+	adj = chip->cc_coeffs->cc_mult_num;
 	adj *= scaled_ppm;
-	diff = div_u64(adj, ptp_ops->cc_mult_dem);
+	diff = div_u64(adj, chip->cc_coeffs->cc_mult_dem);
 
 	mv88e6xxx_reg_lock(chip);
 
@@ -364,10 +418,6 @@
 		(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
 		(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
 		(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
-	.cc_shift = MV88E6XXX_CC_SHIFT,
-	.cc_mult = MV88E6XXX_CC_MULT,
-	.cc_mult_num = MV88E6XXX_CC_MULT_NUM,
-	.cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
 };
 
 const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = {
@@ -391,10 +441,6 @@
 		(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
 		(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
 		(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
-	.cc_shift = MV88E6250_CC_SHIFT,
-	.cc_mult = MV88E6250_CC_MULT,
-	.cc_mult_num = MV88E6250_CC_MULT_NUM,
-	.cc_mult_dem = MV88E6250_CC_MULT_DEM,
 };
 
 const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
@@ -418,10 +464,6 @@
 		(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
 		(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
 		(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
-	.cc_shift = MV88E6XXX_CC_SHIFT,
-	.cc_mult = MV88E6XXX_CC_MULT,
-	.cc_mult_num = MV88E6XXX_CC_MULT_NUM,
-	.cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
 };
 
 const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = {
@@ -446,10 +488,6 @@
 		(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
 		(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
 		(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
-	.cc_shift = MV88E6XXX_CC_SHIFT,
-	.cc_mult = MV88E6XXX_CC_MULT,
-	.cc_mult_num = MV88E6XXX_CC_MULT_NUM,
-	.cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
 };
 
 static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
@@ -462,10 +500,10 @@
 	return 0;
 }
 
-/* With a 125MHz input clock, the 32-bit timestamp counter overflows in ~34.3
+/* With a 250MHz input clock, the 32-bit timestamp counter overflows in ~17.2
  * seconds; this task forces periodic reads so that we don't miss any.
  */
-#define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 16)
+#define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 8)
 static void mv88e6xxx_ptp_overflow_check(struct work_struct *work)
 {
 	struct delayed_work *dw = to_delayed_work(work);
@@ -484,11 +522,15 @@
 	int i;
 
 	/* Set up the cycle counter */
+	chip->cc_coeffs = mv88e6xxx_cc_coeff_get(chip);
+	if (IS_ERR(chip->cc_coeffs))
+		return PTR_ERR(chip->cc_coeffs);
+
 	memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc));
 	chip->tstamp_cc.read	= mv88e6xxx_ptp_clock_read;
 	chip->tstamp_cc.mask	= CYCLECOUNTER_MASK(32);
-	chip->tstamp_cc.mult	= ptp_ops->cc_mult;
-	chip->tstamp_cc.shift	= ptp_ops->cc_shift;
+	chip->tstamp_cc.mult	= chip->cc_coeffs->cc_mult;
+	chip->tstamp_cc.shift	= chip->cc_coeffs->cc_shift;
 
 	timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc,
 			 ktime_to_ns(ktime_get_real()));
--- linux-qcom-6.8.0.orig/drivers/net/dsa/ocelot/felix.c
+++ linux-qcom-6.8.0/drivers/net/dsa/ocelot/felix.c
@@ -528,7 +528,9 @@
 	 * so we need to be careful that there are no extra frames to be
 	 * dequeued over MMIO, since we would never know to discard them.
 	 */
+	ocelot_lock_xtr_grp_bh(ocelot, 0);
 	ocelot_drain_cpu_queue(ocelot, 0);
+	ocelot_unlock_xtr_grp_bh(ocelot, 0);
 
 	return 0;
 }
@@ -1504,6 +1506,8 @@
 	int port = xmit_work->dp->index;
 	int retries = 10;
 
+	ocelot_lock_inj_grp(ocelot, 0);
+
 	do {
 		if (ocelot_can_inject(ocelot, 0))
 			break;
@@ -1512,6 +1516,7 @@
 	} while (--retries);
 
 	if (!retries) {
+		ocelot_unlock_inj_grp(ocelot, 0);
 		dev_err(ocelot->dev, "port %d failed to inject skb\n",
 			port);
 		ocelot_port_purge_txtstamp_skb(ocelot, port, skb);
@@ -1521,6 +1526,8 @@
 
 	ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb);
 
+	ocelot_unlock_inj_grp(ocelot, 0);
+
 	consume_skb(skb);
 	kfree(xmit_work);
 }
@@ -1671,6 +1678,8 @@
 	if (!felix->info->quirk_no_xtr_irq)
 		return false;
 
+	ocelot_lock_xtr_grp(ocelot, grp);
+
 	while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)) {
 		struct sk_buff *skb;
 		unsigned int type;
@@ -1707,6 +1716,8 @@
 		ocelot_drain_cpu_queue(ocelot, 0);
 	}
 
+	ocelot_unlock_xtr_grp(ocelot, grp);
+
 	return true;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/dsa/ocelot/felix_vsc9959.c
+++ linux-qcom-6.8.0/drivers/net/dsa/ocelot/felix_vsc9959.c
@@ -24,7 +24,7 @@
 #define VSC9959_NUM_PORTS		6
 
 #define VSC9959_TAS_GCL_ENTRY_MAX	63
-#define VSC9959_TAS_MIN_GATE_LEN_NS	33
+#define VSC9959_TAS_MIN_GATE_LEN_NS	35
 #define VSC9959_VCAP_POLICER_BASE	63
 #define VSC9959_VCAP_POLICER_MAX	383
 #define VSC9959_SWITCH_PCI_BAR		4
@@ -1056,11 +1056,15 @@
 	mdiobus_free(felix->imdio);
 }
 
-/* The switch considers any frame (regardless of size) as eligible for
- * transmission if the traffic class gate is open for at least 33 ns.
+/* The switch considers any frame (regardless of size) as eligible
+ * for transmission if the traffic class gate is open for at least
+ * VSC9959_TAS_MIN_GATE_LEN_NS.
+ *
  * Overruns are prevented by cropping an interval at the end of the gate time
- * slot for which egress scheduling is blocked, but we need to still keep 33 ns
- * available for one packet to be transmitted, otherwise the port tc will hang.
+ * slot for which egress scheduling is blocked, but we need to still keep
+ * VSC9959_TAS_MIN_GATE_LEN_NS available for one packet to be transmitted,
+ * otherwise the port tc will hang.
+ *
  * This function returns the size of a gate interval that remains available for
  * setting the guard band, after reserving the space for one egress frame.
  */
@@ -1303,7 +1307,8 @@
 			 * per-tc static guard band lengths, so it reduces the
 			 * useful gate interval length. Therefore, be careful
 			 * to calculate a guard band (and therefore max_sdu)
-			 * that still leaves 33 ns available in the time slot.
+			 * that still leaves VSC9959_TAS_MIN_GATE_LEN_NS
+			 * available in the time slot.
 			 */
 			max_sdu = div_u64(remaining_gate_len_ps, picos_per_byte);
 			/* A TC gate may be completely closed, which is a
@@ -1474,10 +1479,13 @@
 	/* Hardware errata -  Admin config could not be overwritten if
 	 * config is pending, need reset the TAS module
 	 */
-	val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_8);
-	if (val & QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING) {
-		ret = -EBUSY;
-		goto err_reset_tc;
+	val = ocelot_read_rix(ocelot, QSYS_TAG_CONFIG, port);
+	if (val & QSYS_TAG_CONFIG_ENABLE) {
+		val = ocelot_read(ocelot, QSYS_PARAM_STATUS_REG_8);
+		if (val & QSYS_PARAM_STATUS_REG_8_CONFIG_PENDING) {
+			ret = -EBUSY;
+			goto err_reset_tc;
+		}
 	}
 
 	ocelot_rmw_rix(ocelot,
--- linux-qcom-6.8.0.orig/drivers/net/dsa/qca/qca8k-8xxx.c
+++ linux-qcom-6.8.0/drivers/net/dsa/qca/qca8k-8xxx.c
@@ -673,7 +673,7 @@
 	 * We therefore need to lock the MDIO bus onto which the switch is
 	 * connected.
 	 */
-	mutex_lock(&priv->bus->mdio_lock);
+	mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
 
 	/* Actually start the request:
 	 * 1. Send mdio master packet
@@ -954,7 +954,7 @@
 
 	mdio = of_get_child_by_name(dev->of_node, "mdio");
 	if (mdio && !of_device_is_available(mdio))
-		goto out;
+		goto out_put_node;
 
 	bus = devm_mdiobus_alloc(dev);
 	if (!bus) {
@@ -988,7 +988,6 @@
 
 out_put_node:
 	of_node_put(mdio);
-out:
 	return err;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/dsa/qca/qca8k-leds.c
+++ linux-qcom-6.8.0/drivers/net/dsa/qca/qca8k-leds.c
@@ -431,8 +431,11 @@
 		init_data.devicename = kasprintf(GFP_KERNEL, "%s:0%d",
 						 priv->internal_mdio_bus->id,
 						 port_num);
-		if (!init_data.devicename)
+		if (!init_data.devicename) {
+			fwnode_handle_put(led);
+			fwnode_handle_put(leds);
 			return -ENOMEM;
+		}
 
 		ret = devm_led_classdev_register_ext(priv->dev, &port_led->cdev, &init_data);
 		if (ret)
@@ -441,6 +444,7 @@
 		kfree(init_data.devicename);
 	}
 
+	fwnode_handle_put(leds);
 	return 0;
 }
 
@@ -471,9 +475,13 @@
 		 * the correct port for LED setup.
 		 */
 		ret = qca8k_parse_port_leds(priv, port, qca8k_port_to_phy(port_num));
-		if (ret)
+		if (ret) {
+			fwnode_handle_put(port);
+			fwnode_handle_put(ports);
 			return ret;
+		}
 	}
 
+	fwnode_handle_put(ports);
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/net/dsa/realtek/rtl8366rb.c
+++ linux-qcom-6.8.0/drivers/net/dsa/realtek/rtl8366rb.c
@@ -182,7 +182,12 @@
 #define RTL8366RB_LED_BLINKRATE_222MS		0x0004
 #define RTL8366RB_LED_BLINKRATE_446MS		0x0005
 
+/* LED trigger event for each group */
 #define RTL8366RB_LED_CTRL_REG			0x0431
+#define RTL8366RB_LED_CTRL_OFFSET(led_group)	\
+	(4 * (led_group))
+#define RTL8366RB_LED_CTRL_MASK(led_group)	\
+	(0xf << RTL8366RB_LED_CTRL_OFFSET(led_group))
 #define RTL8366RB_LED_OFF			0x0
 #define RTL8366RB_LED_DUP_COL			0x1
 #define RTL8366RB_LED_LINK_ACT			0x2
@@ -199,6 +204,11 @@
 #define RTL8366RB_LED_LINK_TX			0xd
 #define RTL8366RB_LED_MASTER			0xe
 #define RTL8366RB_LED_FORCE			0xf
+
+/* The RTL8366RB_LED_X_X registers are used to manually set the LED state only
+ * when the corresponding LED group in RTL8366RB_LED_CTRL_REG is
+ * RTL8366RB_LED_FORCE. Otherwise, it is ignored.
+ */
 #define RTL8366RB_LED_0_1_CTRL_REG		0x0432
 #define RTL8366RB_LED_1_OFFSET			6
 #define RTL8366RB_LED_2_3_CTRL_REG		0x0433
@@ -999,27 +1009,19 @@
 	if (priv->leds_disabled) {
 		/* Turn everything off */
 		regmap_update_bits(priv->map,
-				   RTL8366RB_LED_0_1_CTRL_REG,
-				   0x0FFF, 0);
-		regmap_update_bits(priv->map,
-				   RTL8366RB_LED_2_3_CTRL_REG,
-				   0x0FFF, 0);
-		regmap_update_bits(priv->map,
 				   RTL8366RB_INTERRUPT_CONTROL_REG,
 				   RTL8366RB_P4_RGMII_LED,
 				   0);
-		val = RTL8366RB_LED_OFF;
-	} else {
-		/* TODO: make this configurable per LED */
-		val = RTL8366RB_LED_FORCE;
-	}
-	for (i = 0; i < 4; i++) {
-		ret = regmap_update_bits(priv->map,
-					 RTL8366RB_LED_CTRL_REG,
-					 0xf << (i * 4),
-					 val << (i * 4));
-		if (ret)
-			return ret;
+
+		for (i = 0; i < RTL8366RB_NUM_LEDGROUPS; i++) {
+			val = RTL8366RB_LED_OFF << RTL8366RB_LED_CTRL_OFFSET(i);
+			ret = regmap_update_bits(priv->map,
+						 RTL8366RB_LED_CTRL_REG,
+						 RTL8366RB_LED_CTRL_MASK(i),
+						 val);
+			if (ret)
+				return ret;
+		}
 	}
 
 	ret = rtl8366_reset_vlan(priv);
@@ -1166,52 +1168,6 @@
 	}
 }
 
-static void rb8366rb_set_port_led(struct realtek_priv *priv,
-				  int port, bool enable)
-{
-	u16 val = enable ? 0x3f : 0;
-	int ret;
-
-	if (priv->leds_disabled)
-		return;
-
-	switch (port) {
-	case 0:
-		ret = regmap_update_bits(priv->map,
-					 RTL8366RB_LED_0_1_CTRL_REG,
-					 0x3F, val);
-		break;
-	case 1:
-		ret = regmap_update_bits(priv->map,
-					 RTL8366RB_LED_0_1_CTRL_REG,
-					 0x3F << RTL8366RB_LED_1_OFFSET,
-					 val << RTL8366RB_LED_1_OFFSET);
-		break;
-	case 2:
-		ret = regmap_update_bits(priv->map,
-					 RTL8366RB_LED_2_3_CTRL_REG,
-					 0x3F, val);
-		break;
-	case 3:
-		ret = regmap_update_bits(priv->map,
-					 RTL8366RB_LED_2_3_CTRL_REG,
-					 0x3F << RTL8366RB_LED_3_OFFSET,
-					 val << RTL8366RB_LED_3_OFFSET);
-		break;
-	case 4:
-		ret = regmap_update_bits(priv->map,
-					 RTL8366RB_INTERRUPT_CONTROL_REG,
-					 RTL8366RB_P4_RGMII_LED,
-					 enable ? RTL8366RB_P4_RGMII_LED : 0);
-		break;
-	default:
-		dev_err(priv->dev, "no LED for port %d\n", port);
-		return;
-	}
-	if (ret)
-		dev_err(priv->dev, "error updating LED on port %d\n", port);
-}
-
 static int
 rtl8366rb_port_enable(struct dsa_switch *ds, int port,
 		      struct phy_device *phy)
@@ -1225,7 +1181,6 @@
 	if (ret)
 		return ret;
 
-	rb8366rb_set_port_led(priv, port, true);
 	return 0;
 }
 
@@ -1240,8 +1195,6 @@
 				 BIT(port));
 	if (ret)
 		return;
-
-	rb8366rb_set_port_led(priv, port, false);
 }
 
 static int
--- linux-qcom-6.8.0.orig/drivers/net/dsa/sja1105/sja1105_mdio.c
+++ linux-qcom-6.8.0/drivers/net/dsa/sja1105/sja1105_mdio.c
@@ -94,7 +94,7 @@
 	return tmp & 0xffff;
 }
 
-int sja1110_pcs_mdio_write_c45(struct mii_bus *bus, int phy, int reg, int mmd,
+int sja1110_pcs_mdio_write_c45(struct mii_bus *bus, int phy, int mmd, int reg,
 			       u16 val)
 {
 	struct sja1105_mdio_private *mdio_priv = bus->priv;
--- linux-qcom-6.8.0.orig/drivers/net/dsa/vitesse-vsc73xx-core.c
+++ linux-qcom-6.8.0/drivers/net/dsa/vitesse-vsc73xx-core.c
@@ -17,6 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/device.h>
+#include <linux/iopoll.h>
 #include <linux/of.h>
 #include <linux/of_mdio.h>
 #include <linux/bitops.h>
@@ -33,10 +34,14 @@
 #define VSC73XX_BLOCK_ANALYZER	0x2 /* Only subblock 0 */
 #define VSC73XX_BLOCK_MII	0x3 /* Subblocks 0 and 1 */
 #define VSC73XX_BLOCK_MEMINIT	0x3 /* Only subblock 2 */
-#define VSC73XX_BLOCK_CAPTURE	0x4 /* Only subblock 2 */
+#define VSC73XX_BLOCK_CAPTURE	0x4 /* Subblocks 0-4, 6, 7 */
 #define VSC73XX_BLOCK_ARBITER	0x5 /* Only subblock 0 */
 #define VSC73XX_BLOCK_SYSTEM	0x7 /* Only subblock 0 */
 
+/* MII Block subblock */
+#define VSC73XX_BLOCK_MII_INTERNAL	0x0 /* Internal MDIO subblock */
+#define VSC73XX_BLOCK_MII_EXTERNAL	0x1 /* External MDIO subblock */
+
 #define CPU_PORT	6 /* CPU port */
 
 /* MAC Block registers */
@@ -195,6 +200,8 @@
 #define VSC73XX_MII_CMD		0x1
 #define VSC73XX_MII_DATA	0x2
 
+#define VSC73XX_MII_STAT_BUSY	BIT(3)
+
 /* Arbiter block 5 registers */
 #define VSC73XX_ARBEMPTY		0x0c
 #define VSC73XX_ARBDISC			0x0e
@@ -268,6 +275,10 @@
 #define IS_7398(a) ((a)->chipid == VSC73XX_CHIPID_ID_7398)
 #define IS_739X(a) (IS_7395(a) || IS_7398(a))
 
+#define VSC73XX_POLL_SLEEP_US		1000
+#define VSC73XX_MDIO_POLL_SLEEP_US	5
+#define VSC73XX_POLL_TIMEOUT_US		10000
+
 struct vsc73xx_counter {
 	u8 counter;
 	const char *name;
@@ -359,13 +370,19 @@
 		break;
 
 	case VSC73XX_BLOCK_MII:
-	case VSC73XX_BLOCK_CAPTURE:
 	case VSC73XX_BLOCK_ARBITER:
 		switch (subblock) {
 		case 0 ... 1:
 			return 1;
 		}
 		break;
+	case VSC73XX_BLOCK_CAPTURE:
+		switch (subblock) {
+		case 0 ... 4:
+		case 6 ... 7:
+			return 1;
+		}
+		break;
 	}
 
 	return 0;
@@ -483,6 +500,22 @@
 	return 0;
 }
 
+static int vsc73xx_mdio_busy_check(struct vsc73xx *vsc)
+{
+	int ret, err;
+	u32 val;
+
+	ret = read_poll_timeout(vsc73xx_read, err,
+				err < 0 || !(val & VSC73XX_MII_STAT_BUSY),
+				VSC73XX_MDIO_POLL_SLEEP_US,
+				VSC73XX_POLL_TIMEOUT_US, false, vsc,
+				VSC73XX_BLOCK_MII, VSC73XX_BLOCK_MII_INTERNAL,
+				VSC73XX_MII_STAT, &val);
+	if (ret)
+		return ret;
+	return err;
+}
+
 static int vsc73xx_phy_read(struct dsa_switch *ds, int phy, int regnum)
 {
 	struct vsc73xx *vsc = ds->priv;
@@ -490,12 +523,20 @@
 	u32 val;
 	int ret;
 
+	ret = vsc73xx_mdio_busy_check(vsc);
+	if (ret)
+		return ret;
+
 	/* Setting bit 26 means "read" */
 	cmd = BIT(26) | (phy << 21) | (regnum << 16);
 	ret = vsc73xx_write(vsc, VSC73XX_BLOCK_MII, 0, 1, cmd);
 	if (ret)
 		return ret;
-	msleep(2);
+
+	ret = vsc73xx_mdio_busy_check(vsc);
+	if (ret)
+		return ret;
+
 	ret = vsc73xx_read(vsc, VSC73XX_BLOCK_MII, 0, 2, &val);
 	if (ret)
 		return ret;
@@ -519,6 +560,10 @@
 	u32 cmd;
 	int ret;
 
+	ret = vsc73xx_mdio_busy_check(vsc);
+	if (ret)
+		return ret;
+
 	/* It was found through tedious experiments that this router
 	 * chip really hates to have it's PHYs reset. They
 	 * never recover if that happens: autonegotiation stops
@@ -530,7 +575,7 @@
 		return 0;
 	}
 
-	cmd = (phy << 21) | (regnum << 16);
+	cmd = (phy << 21) | (regnum << 16) | val;
 	ret = vsc73xx_write(vsc, VSC73XX_BLOCK_MII, 0, 1, cmd);
 	if (ret)
 		return ret;
@@ -779,7 +824,7 @@
 	 * after a PHY or the CPU port comes up or down.
 	 */
 	if (!phydev->link) {
-		int maxloop = 10;
+		int ret, err;
 
 		dev_dbg(vsc->dev, "port %d: went down\n",
 			port);
@@ -794,19 +839,17 @@
 				    VSC73XX_ARBDISC, BIT(port), BIT(port));
 
 		/* Wait until queue is empty */
-		vsc73xx_read(vsc, VSC73XX_BLOCK_ARBITER, 0,
-			     VSC73XX_ARBEMPTY, &val);
-		while (!(val & BIT(port))) {
-			msleep(1);
-			vsc73xx_read(vsc, VSC73XX_BLOCK_ARBITER, 0,
-				     VSC73XX_ARBEMPTY, &val);
-			if (--maxloop == 0) {
-				dev_err(vsc->dev,
-					"timeout waiting for block arbiter\n");
-				/* Continue anyway */
-				break;
-			}
-		}
+		ret = read_poll_timeout(vsc73xx_read, err,
+					err < 0 || (val & BIT(port)),
+					VSC73XX_POLL_SLEEP_US,
+					VSC73XX_POLL_TIMEOUT_US, false,
+					vsc, VSC73XX_BLOCK_ARBITER, 0,
+					VSC73XX_ARBEMPTY, &val);
+		if (ret)
+			dev_err(vsc->dev,
+				"timeout waiting for block arbiter\n");
+		else if (err < 0)
+			dev_err(vsc->dev, "error reading arbiter\n");
 
 		/* Put this port into reset */
 		vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_MAC_CFG,
--- linux-qcom-6.8.0.orig/drivers/net/dummy.c
+++ linux-qcom-6.8.0/drivers/net/dummy.c
@@ -71,6 +71,7 @@
 	if (!dev->lstats)
 		return -ENOMEM;
 
+	netdev_lockdep_set_classes(dev);
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/adi/adin1110.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/adi/adin1110.c
@@ -318,11 +318,11 @@
 	 * from the  ADIN1110 frame header.
 	 */
 	if (frame_size < ADIN1110_FRAME_HEADER_LEN + ADIN1110_FEC_LEN)
-		return ret;
+		return -EINVAL;
 
 	round_len = adin1110_round_len(frame_size);
 	if (round_len < 0)
-		return ret;
+		return -EINVAL;
 
 	frame_size_no_fcs = frame_size - ADIN1110_FRAME_HEADER_LEN - ADIN1110_FEC_LEN;
 	memset(priv->data, 0, ADIN1110_RD_HEADER_LEN);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/aeroflex/greth.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/aeroflex/greth.c
@@ -484,7 +484,7 @@
 
 	if (unlikely(skb->len > MAX_FRAME_SIZE)) {
 		dev->stats.tx_errors++;
-		goto out;
+		goto len_error;
 	}
 
 	/* Save skb pointer. */
@@ -575,6 +575,7 @@
 map_error:
 	if (net_ratelimit())
 		dev_warn(greth->dev, "Could not create TX DMA mapping\n");
+len_error:
 	dev_kfree_skb(skb);
 out:
 	return err;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/amazon/ena/ena_com.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -90,8 +90,7 @@
 	struct ena_com_admin_sq *sq = &admin_queue->sq;
 	u16 size = ADMIN_SQ_SIZE(admin_queue->q_depth);
 
-	sq->entries = dma_alloc_coherent(admin_queue->q_dmadev, size,
-					 &sq->dma_addr, GFP_KERNEL);
+	sq->entries = dma_alloc_coherent(admin_queue->q_dmadev, size, &sq->dma_addr, GFP_KERNEL);
 
 	if (!sq->entries) {
 		netdev_err(ena_dev->net_device, "Memory allocation failed\n");
@@ -113,8 +112,7 @@
 	struct ena_com_admin_cq *cq = &admin_queue->cq;
 	u16 size = ADMIN_CQ_SIZE(admin_queue->q_depth);
 
-	cq->entries = dma_alloc_coherent(admin_queue->q_dmadev, size,
-					 &cq->dma_addr, GFP_KERNEL);
+	cq->entries = dma_alloc_coherent(admin_queue->q_dmadev, size, &cq->dma_addr, GFP_KERNEL);
 
 	if (!cq->entries) {
 		netdev_err(ena_dev->net_device, "Memory allocation failed\n");
@@ -136,8 +134,7 @@
 
 	ena_dev->aenq.q_depth = ENA_ASYNC_QUEUE_DEPTH;
 	size = ADMIN_AENQ_SIZE(ENA_ASYNC_QUEUE_DEPTH);
-	aenq->entries = dma_alloc_coherent(ena_dev->dmadev, size,
-					   &aenq->dma_addr, GFP_KERNEL);
+	aenq->entries = dma_alloc_coherent(ena_dev->dmadev, size, &aenq->dma_addr, GFP_KERNEL);
 
 	if (!aenq->entries) {
 		netdev_err(ena_dev->net_device, "Memory allocation failed\n");
@@ -155,14 +152,13 @@
 
 	aenq_caps = 0;
 	aenq_caps |= ena_dev->aenq.q_depth & ENA_REGS_AENQ_CAPS_AENQ_DEPTH_MASK;
-	aenq_caps |= (sizeof(struct ena_admin_aenq_entry)
-		      << ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_SHIFT) &
-		     ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_MASK;
+	aenq_caps |=
+		(sizeof(struct ena_admin_aenq_entry) << ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_SHIFT) &
+		ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_MASK;
 	writel(aenq_caps, ena_dev->reg_bar + ENA_REGS_AENQ_CAPS_OFF);
 
 	if (unlikely(!aenq_handlers)) {
-		netdev_err(ena_dev->net_device,
-			   "AENQ handlers pointer is NULL\n");
+		netdev_err(ena_dev->net_device, "AENQ handlers pointer is NULL\n");
 		return -EINVAL;
 	}
 
@@ -189,14 +185,12 @@
 	}
 
 	if (unlikely(!admin_queue->comp_ctx)) {
-		netdev_err(admin_queue->ena_dev->net_device,
-			   "Completion context is NULL\n");
+		netdev_err(admin_queue->ena_dev->net_device, "Completion context is NULL\n");
 		return NULL;
 	}
 
 	if (unlikely(admin_queue->comp_ctx[command_id].occupied && capture)) {
-		netdev_err(admin_queue->ena_dev->net_device,
-			   "Completion context is occupied\n");
+		netdev_err(admin_queue->ena_dev->net_device, "Completion context is occupied\n");
 		return NULL;
 	}
 
@@ -226,8 +220,7 @@
 	/* In case of queue FULL */
 	cnt = (u16)atomic_read(&admin_queue->outstanding_cmds);
 	if (cnt >= admin_queue->q_depth) {
-		netdev_dbg(admin_queue->ena_dev->net_device,
-			   "Admin queue is full.\n");
+		netdev_dbg(admin_queue->ena_dev->net_device, "Admin queue is full.\n");
 		admin_queue->stats.out_of_space++;
 		return ERR_PTR(-ENOSPC);
 	}
@@ -274,8 +267,7 @@
 	struct ena_comp_ctx *comp_ctx;
 	u16 i;
 
-	admin_queue->comp_ctx =
-		devm_kzalloc(admin_queue->q_dmadev, size, GFP_KERNEL);
+	admin_queue->comp_ctx = devm_kzalloc(admin_queue->q_dmadev, size, GFP_KERNEL);
 	if (unlikely(!admin_queue->comp_ctx)) {
 		netdev_err(ena_dev->net_device, "Memory allocation failed\n");
 		return -ENOMEM;
@@ -320,7 +312,6 @@
 			      struct ena_com_io_sq *io_sq)
 {
 	size_t size;
-	int dev_node = 0;
 
 	memset(&io_sq->desc_addr, 0x0, sizeof(io_sq->desc_addr));
 
@@ -333,23 +324,17 @@
 	size = io_sq->desc_entry_size * io_sq->q_depth;
 
 	if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) {
-		dev_node = dev_to_node(ena_dev->dmadev);
-		set_dev_node(ena_dev->dmadev, ctx->numa_node);
 		io_sq->desc_addr.virt_addr =
-			dma_alloc_coherent(ena_dev->dmadev, size,
-					   &io_sq->desc_addr.phys_addr,
+			dma_alloc_coherent(ena_dev->dmadev, size, &io_sq->desc_addr.phys_addr,
 					   GFP_KERNEL);
-		set_dev_node(ena_dev->dmadev, dev_node);
 		if (!io_sq->desc_addr.virt_addr) {
 			io_sq->desc_addr.virt_addr =
 				dma_alloc_coherent(ena_dev->dmadev, size,
-						   &io_sq->desc_addr.phys_addr,
-						   GFP_KERNEL);
+						   &io_sq->desc_addr.phys_addr, GFP_KERNEL);
 		}
 
 		if (!io_sq->desc_addr.virt_addr) {
-			netdev_err(ena_dev->net_device,
-				   "Memory allocation failed\n");
+			netdev_err(ena_dev->net_device, "Memory allocation failed\n");
 			return -ENOMEM;
 		}
 	}
@@ -362,21 +347,16 @@
 			ENA_COM_BOUNCE_BUFFER_CNTRL_CNT;
 		io_sq->bounce_buf_ctrl.next_to_use = 0;
 
-		size = io_sq->bounce_buf_ctrl.buffer_size *
+		size = (size_t)io_sq->bounce_buf_ctrl.buffer_size *
 			io_sq->bounce_buf_ctrl.buffers_num;
 
-		dev_node = dev_to_node(ena_dev->dmadev);
-		set_dev_node(ena_dev->dmadev, ctx->numa_node);
-		io_sq->bounce_buf_ctrl.base_buffer =
-			devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL);
-		set_dev_node(ena_dev->dmadev, dev_node);
+		io_sq->bounce_buf_ctrl.base_buffer = devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL);
 		if (!io_sq->bounce_buf_ctrl.base_buffer)
 			io_sq->bounce_buf_ctrl.base_buffer =
 				devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL);
 
 		if (!io_sq->bounce_buf_ctrl.base_buffer) {
-			netdev_err(ena_dev->net_device,
-				   "Bounce buffer memory allocation failed\n");
+			netdev_err(ena_dev->net_device, "Bounce buffer memory allocation failed\n");
 			return -ENOMEM;
 		}
 
@@ -410,7 +390,6 @@
 			      struct ena_com_io_cq *io_cq)
 {
 	size_t size;
-	int prev_node = 0;
 
 	memset(&io_cq->cdesc_addr, 0x0, sizeof(io_cq->cdesc_addr));
 
@@ -422,16 +401,11 @@
 
 	size = io_cq->cdesc_entry_size_in_bytes * io_cq->q_depth;
 
-	prev_node = dev_to_node(ena_dev->dmadev);
-	set_dev_node(ena_dev->dmadev, ctx->numa_node);
 	io_cq->cdesc_addr.virt_addr =
-		dma_alloc_coherent(ena_dev->dmadev, size,
-				   &io_cq->cdesc_addr.phys_addr, GFP_KERNEL);
-	set_dev_node(ena_dev->dmadev, prev_node);
+		dma_alloc_coherent(ena_dev->dmadev, size, &io_cq->cdesc_addr.phys_addr, GFP_KERNEL);
 	if (!io_cq->cdesc_addr.virt_addr) {
 		io_cq->cdesc_addr.virt_addr =
-			dma_alloc_coherent(ena_dev->dmadev, size,
-					   &io_cq->cdesc_addr.phys_addr,
+			dma_alloc_coherent(ena_dev->dmadev, size, &io_cq->cdesc_addr.phys_addr,
 					   GFP_KERNEL);
 	}
 
@@ -514,8 +488,8 @@
 					u8 comp_status)
 {
 	if (unlikely(comp_status != 0))
-		netdev_err(admin_queue->ena_dev->net_device,
-			   "Admin command failed[%u]\n", comp_status);
+		netdev_err(admin_queue->ena_dev->net_device, "Admin command failed[%u]\n",
+			   comp_status);
 
 	switch (comp_status) {
 	case ENA_ADMIN_SUCCESS:
@@ -580,8 +554,7 @@
 	}
 
 	if (unlikely(comp_ctx->status == ENA_CMD_ABORTED)) {
-		netdev_err(admin_queue->ena_dev->net_device,
-			   "Command was aborted\n");
+		netdev_err(admin_queue->ena_dev->net_device, "Command was aborted\n");
 		spin_lock_irqsave(&admin_queue->q_lock, flags);
 		admin_queue->stats.aborted_cmd++;
 		spin_unlock_irqrestore(&admin_queue->q_lock, flags);
@@ -589,8 +562,7 @@
 		goto err;
 	}
 
-	WARN(comp_ctx->status != ENA_CMD_COMPLETED, "Invalid comp status %d\n",
-	     comp_ctx->status);
+	WARN(comp_ctx->status != ENA_CMD_COMPLETED, "Invalid comp status %d\n", comp_ctx->status);
 
 	ret = ena_com_comp_status_to_errno(admin_queue, comp_ctx->comp_status);
 err:
@@ -634,8 +606,7 @@
 					    sizeof(resp));
 
 	if (unlikely(ret))
-		netdev_err(ena_dev->net_device,
-			   "Failed to set LLQ configurations: %d\n", ret);
+		netdev_err(ena_dev->net_device, "Failed to set LLQ configurations: %d\n", ret);
 
 	return ret;
 }
@@ -658,8 +629,7 @@
 			llq_default_cfg->llq_header_location;
 	} else {
 		netdev_err(ena_dev->net_device,
-			   "Invalid header location control, supported: 0x%x\n",
-			   supported_feat);
+			   "Invalid header location control, supported: 0x%x\n", supported_feat);
 		return -EINVAL;
 	}
 
@@ -681,8 +651,8 @@
 
 			netdev_err(ena_dev->net_device,
 				   "Default llq stride ctrl is not supported, performing fallback, default: 0x%x, supported: 0x%x, used: 0x%x\n",
-				   llq_default_cfg->llq_stride_ctrl,
-				   supported_feat, llq_info->desc_stride_ctrl);
+				   llq_default_cfg->llq_stride_ctrl, supported_feat,
+				   llq_info->desc_stride_ctrl);
 		}
 	} else {
 		llq_info->desc_stride_ctrl = 0;
@@ -704,8 +674,7 @@
 			llq_info->desc_list_entry_size = 256;
 		} else {
 			netdev_err(ena_dev->net_device,
-				   "Invalid entry_size_ctrl, supported: 0x%x\n",
-				   supported_feat);
+				   "Invalid entry_size_ctrl, supported: 0x%x\n", supported_feat);
 			return -EINVAL;
 		}
 
@@ -750,8 +719,8 @@
 
 		netdev_err(ena_dev->net_device,
 			   "Default llq num descs before header is not supported, performing fallback, default: 0x%x, supported: 0x%x, used: 0x%x\n",
-			   llq_default_cfg->llq_num_decs_before_header,
-			   supported_feat, llq_info->descs_num_before_header);
+			   llq_default_cfg->llq_num_decs_before_header, supported_feat,
+			   llq_info->descs_num_before_header);
 	}
 	/* Check for accelerated queue supported */
 	llq_accel_mode_get = llq_features->accel_mode.u.get;
@@ -767,8 +736,7 @@
 
 	rc = ena_com_set_llq(ena_dev);
 	if (rc)
-		netdev_err(ena_dev->net_device,
-			   "Cannot set LLQ configuration: %d\n", rc);
+		netdev_err(ena_dev->net_device, "Cannot set LLQ configuration: %d\n", rc);
 
 	return rc;
 }
@@ -780,8 +748,7 @@
 	int ret;
 
 	wait_for_completion_timeout(&comp_ctx->wait_event,
-				    usecs_to_jiffies(
-					    admin_queue->completion_timeout));
+				    usecs_to_jiffies(admin_queue->completion_timeout));
 
 	/* In case the command wasn't completed find out the root cause.
 	 * There might be 2 kinds of errors
@@ -797,8 +764,7 @@
 		if (comp_ctx->status == ENA_CMD_COMPLETED) {
 			netdev_err(admin_queue->ena_dev->net_device,
 				   "The ena device sent a completion but the driver didn't receive a MSI-X interrupt (cmd %d), autopolling mode is %s\n",
-				   comp_ctx->cmd_opcode,
-				   admin_queue->auto_polling ? "ON" : "OFF");
+				   comp_ctx->cmd_opcode, admin_queue->auto_polling ? "ON" : "OFF");
 			/* Check if fallback to polling is enabled */
 			if (admin_queue->auto_polling)
 				admin_queue->polling = true;
@@ -867,15 +833,13 @@
 	if (unlikely(i == timeout)) {
 		netdev_err(ena_dev->net_device,
 			   "Reading reg failed for timeout. expected: req id[%u] offset[%u] actual: req id[%u] offset[%u]\n",
-			   mmio_read->seq_num, offset, read_resp->req_id,
-			   read_resp->reg_off);
+			   mmio_read->seq_num, offset, read_resp->req_id, read_resp->reg_off);
 		ret = ENA_MMIO_READ_TIMEOUT;
 		goto err;
 	}
 
 	if (read_resp->reg_off != offset) {
-		netdev_err(ena_dev->net_device,
-			   "Read failure: wrong offset provided\n");
+		netdev_err(ena_dev->net_device, "Read failure: wrong offset provided\n");
 		ret = ENA_MMIO_READ_TIMEOUT;
 	} else {
 		ret = read_resp->reg_val;
@@ -934,8 +898,7 @@
 					    sizeof(destroy_resp));
 
 	if (unlikely(ret && (ret != -ENODEV)))
-		netdev_err(ena_dev->net_device,
-			   "Failed to destroy io sq error: %d\n", ret);
+		netdev_err(ena_dev->net_device, "Failed to destroy io sq error: %d\n", ret);
 
 	return ret;
 }
@@ -949,8 +912,7 @@
 	if (io_cq->cdesc_addr.virt_addr) {
 		size = io_cq->cdesc_entry_size_in_bytes * io_cq->q_depth;
 
-		dma_free_coherent(ena_dev->dmadev, size,
-				  io_cq->cdesc_addr.virt_addr,
+		dma_free_coherent(ena_dev->dmadev, size, io_cq->cdesc_addr.virt_addr,
 				  io_cq->cdesc_addr.phys_addr);
 
 		io_cq->cdesc_addr.virt_addr = NULL;
@@ -959,8 +921,7 @@
 	if (io_sq->desc_addr.virt_addr) {
 		size = io_sq->desc_entry_size * io_sq->q_depth;
 
-		dma_free_coherent(ena_dev->dmadev, size,
-				  io_sq->desc_addr.virt_addr,
+		dma_free_coherent(ena_dev->dmadev, size, io_sq->desc_addr.virt_addr,
 				  io_sq->desc_addr.phys_addr);
 
 		io_sq->desc_addr.virt_addr = NULL;
@@ -985,8 +946,7 @@
 		val = ena_com_reg_bar_read32(ena_dev, ENA_REGS_DEV_STS_OFF);
 
 		if (unlikely(val == ENA_MMIO_READ_TIMEOUT)) {
-			netdev_err(ena_dev->net_device,
-				   "Reg read timeout occurred\n");
+			netdev_err(ena_dev->net_device, "Reg read timeout occurred\n");
 			return -ETIME;
 		}
 
@@ -1026,8 +986,7 @@
 	int ret;
 
 	if (!ena_com_check_supported_feature_id(ena_dev, feature_id)) {
-		netdev_dbg(ena_dev->net_device, "Feature %d isn't supported\n",
-			   feature_id);
+		netdev_dbg(ena_dev->net_device, "Feature %d isn't supported\n", feature_id);
 		return -EOPNOTSUPP;
 	}
 
@@ -1064,8 +1023,7 @@
 
 	if (unlikely(ret))
 		netdev_err(ena_dev->net_device,
-			   "Failed to submit get_feature command %d error: %d\n",
-			   feature_id, ret);
+			   "Failed to submit get_feature command %d error: %d\n", feature_id, ret);
 
 	return ret;
 }
@@ -1104,13 +1062,11 @@
 {
 	struct ena_rss *rss = &ena_dev->rss;
 
-	if (!ena_com_check_supported_feature_id(ena_dev,
-						ENA_ADMIN_RSS_HASH_FUNCTION))
+	if (!ena_com_check_supported_feature_id(ena_dev, ENA_ADMIN_RSS_HASH_FUNCTION))
 		return -EOPNOTSUPP;
 
-	rss->hash_key =
-		dma_alloc_coherent(ena_dev->dmadev, sizeof(*rss->hash_key),
-				   &rss->hash_key_dma_addr, GFP_KERNEL);
+	rss->hash_key = dma_alloc_coherent(ena_dev->dmadev, sizeof(*rss->hash_key),
+					   &rss->hash_key_dma_addr, GFP_KERNEL);
 
 	if (unlikely(!rss->hash_key))
 		return -ENOMEM;
@@ -1123,8 +1079,8 @@
 	struct ena_rss *rss = &ena_dev->rss;
 
 	if (rss->hash_key)
-		dma_free_coherent(ena_dev->dmadev, sizeof(*rss->hash_key),
-				  rss->hash_key, rss->hash_key_dma_addr);
+		dma_free_coherent(ena_dev->dmadev, sizeof(*rss->hash_key), rss->hash_key,
+				  rss->hash_key_dma_addr);
 	rss->hash_key = NULL;
 }
 
@@ -1132,9 +1088,8 @@
 {
 	struct ena_rss *rss = &ena_dev->rss;
 
-	rss->hash_ctrl =
-		dma_alloc_coherent(ena_dev->dmadev, sizeof(*rss->hash_ctrl),
-				   &rss->hash_ctrl_dma_addr, GFP_KERNEL);
+	rss->hash_ctrl = dma_alloc_coherent(ena_dev->dmadev, sizeof(*rss->hash_ctrl),
+					    &rss->hash_ctrl_dma_addr, GFP_KERNEL);
 
 	if (unlikely(!rss->hash_ctrl))
 		return -ENOMEM;
@@ -1147,8 +1102,8 @@
 	struct ena_rss *rss = &ena_dev->rss;
 
 	if (rss->hash_ctrl)
-		dma_free_coherent(ena_dev->dmadev, sizeof(*rss->hash_ctrl),
-				  rss->hash_ctrl, rss->hash_ctrl_dma_addr);
+		dma_free_coherent(ena_dev->dmadev, sizeof(*rss->hash_ctrl), rss->hash_ctrl,
+				  rss->hash_ctrl_dma_addr);
 	rss->hash_ctrl = NULL;
 }
 
@@ -1177,15 +1132,13 @@
 	tbl_size = (1ULL << log_size) *
 		sizeof(struct ena_admin_rss_ind_table_entry);
 
-	rss->rss_ind_tbl =
-		dma_alloc_coherent(ena_dev->dmadev, tbl_size,
-				   &rss->rss_ind_tbl_dma_addr, GFP_KERNEL);
+	rss->rss_ind_tbl = dma_alloc_coherent(ena_dev->dmadev, tbl_size, &rss->rss_ind_tbl_dma_addr,
+					      GFP_KERNEL);
 	if (unlikely(!rss->rss_ind_tbl))
 		goto mem_err1;
 
 	tbl_size = (1ULL << log_size) * sizeof(u16);
-	rss->host_rss_ind_tbl =
-		devm_kzalloc(ena_dev->dmadev, tbl_size, GFP_KERNEL);
+	rss->host_rss_ind_tbl = devm_kzalloc(ena_dev->dmadev, tbl_size, GFP_KERNEL);
 	if (unlikely(!rss->host_rss_ind_tbl))
 		goto mem_err2;
 
@@ -1197,8 +1150,7 @@
 	tbl_size = (1ULL << log_size) *
 		sizeof(struct ena_admin_rss_ind_table_entry);
 
-	dma_free_coherent(ena_dev->dmadev, tbl_size, rss->rss_ind_tbl,
-			  rss->rss_ind_tbl_dma_addr);
+	dma_free_coherent(ena_dev->dmadev, tbl_size, rss->rss_ind_tbl, rss->rss_ind_tbl_dma_addr);
 	rss->rss_ind_tbl = NULL;
 mem_err1:
 	rss->tbl_log_size = 0;
@@ -1261,8 +1213,7 @@
 					   &create_cmd.sq_ba,
 					   io_sq->desc_addr.phys_addr);
 		if (unlikely(ret)) {
-			netdev_err(ena_dev->net_device,
-				   "Memory address set failed\n");
+			netdev_err(ena_dev->net_device, "Memory address set failed\n");
 			return ret;
 		}
 	}
@@ -1273,8 +1224,7 @@
 					    (struct ena_admin_acq_entry *)&cmd_completion,
 					    sizeof(cmd_completion));
 	if (unlikely(ret)) {
-		netdev_err(ena_dev->net_device,
-			   "Failed to create IO SQ. error: %d\n", ret);
+		netdev_err(ena_dev->net_device, "Failed to create IO SQ. error: %d\n", ret);
 		return ret;
 	}
 
@@ -1292,8 +1242,7 @@
 			cmd_completion.llq_descriptors_offset);
 	}
 
-	netdev_dbg(ena_dev->net_device, "Created sq[%u], depth[%u]\n",
-		   io_sq->idx, io_sq->q_depth);
+	netdev_dbg(ena_dev->net_device, "Created sq[%u], depth[%u]\n", io_sq->idx, io_sq->q_depth);
 
 	return ret;
 }
@@ -1420,8 +1369,7 @@
 					    (struct ena_admin_acq_entry *)&cmd_completion,
 					    sizeof(cmd_completion));
 	if (unlikely(ret)) {
-		netdev_err(ena_dev->net_device,
-			   "Failed to create IO CQ. error: %d\n", ret);
+		netdev_err(ena_dev->net_device, "Failed to create IO CQ. error: %d\n", ret);
 		return ret;
 	}
 
@@ -1440,8 +1388,7 @@
 			(u32 __iomem *)((uintptr_t)ena_dev->reg_bar +
 			cmd_completion.numa_node_register_offset);
 
-	netdev_dbg(ena_dev->net_device, "Created cq[%u], depth[%u]\n",
-		   io_cq->idx, io_cq->q_depth);
+	netdev_dbg(ena_dev->net_device, "Created cq[%u], depth[%u]\n", io_cq->idx, io_cq->q_depth);
 
 	return ret;
 }
@@ -1451,8 +1398,7 @@
 			    struct ena_com_io_cq **io_cq)
 {
 	if (qid >= ENA_TOTAL_NUM_QUEUES) {
-		netdev_err(ena_dev->net_device,
-			   "Invalid queue number %d but the max is %d\n", qid,
+		netdev_err(ena_dev->net_device, "Invalid queue number %d but the max is %d\n", qid,
 			   ENA_TOTAL_NUM_QUEUES);
 		return -EINVAL;
 	}
@@ -1492,8 +1438,7 @@
 	spin_lock_irqsave(&admin_queue->q_lock, flags);
 	while (atomic_read(&admin_queue->outstanding_cmds) != 0) {
 		spin_unlock_irqrestore(&admin_queue->q_lock, flags);
-		ena_delay_exponential_backoff_us(exp++,
-						 ena_dev->ena_min_poll_delay_us);
+		ena_delay_exponential_backoff_us(exp++, ena_dev->ena_min_poll_delay_us);
 		spin_lock_irqsave(&admin_queue->q_lock, flags);
 	}
 	spin_unlock_irqrestore(&admin_queue->q_lock, flags);
@@ -1519,8 +1464,7 @@
 					    sizeof(destroy_resp));
 
 	if (unlikely(ret && (ret != -ENODEV)))
-		netdev_err(ena_dev->net_device,
-			   "Failed to destroy IO CQ. error: %d\n", ret);
+		netdev_err(ena_dev->net_device, "Failed to destroy IO CQ. error: %d\n", ret);
 
 	return ret;
 }
@@ -1588,8 +1532,7 @@
 					    sizeof(resp));
 
 	if (unlikely(ret))
-		netdev_err(ena_dev->net_device,
-			   "Failed to config AENQ ret: %d\n", ret);
+		netdev_err(ena_dev->net_device, "Failed to config AENQ ret: %d\n", ret);
 
 	return ret;
 }
@@ -1610,8 +1553,7 @@
 	netdev_dbg(ena_dev->net_device, "ENA dma width: %d\n", width);
 
 	if ((width < 32) || width > ENA_MAX_PHYS_ADDR_SIZE_BITS) {
-		netdev_err(ena_dev->net_device, "DMA width illegal value: %d\n",
-			   width);
+		netdev_err(ena_dev->net_device, "DMA width illegal value: %d\n", width);
 		return -EINVAL;
 	}
 
@@ -1633,19 +1575,16 @@
 	ctrl_ver = ena_com_reg_bar_read32(ena_dev,
 					  ENA_REGS_CONTROLLER_VERSION_OFF);
 
-	if (unlikely((ver == ENA_MMIO_READ_TIMEOUT) ||
-		     (ctrl_ver == ENA_MMIO_READ_TIMEOUT))) {
+	if (unlikely((ver == ENA_MMIO_READ_TIMEOUT) || (ctrl_ver == ENA_MMIO_READ_TIMEOUT))) {
 		netdev_err(ena_dev->net_device, "Reg read timeout occurred\n");
 		return -ETIME;
 	}
 
 	dev_info(ena_dev->dmadev, "ENA device version: %d.%d\n",
-		 (ver & ENA_REGS_VERSION_MAJOR_VERSION_MASK) >>
-			 ENA_REGS_VERSION_MAJOR_VERSION_SHIFT,
+		 (ver & ENA_REGS_VERSION_MAJOR_VERSION_MASK) >> ENA_REGS_VERSION_MAJOR_VERSION_SHIFT,
 		 ver & ENA_REGS_VERSION_MINOR_VERSION_MASK);
 
-	dev_info(ena_dev->dmadev,
-		 "ENA controller version: %d.%d.%d implementation version %d\n",
+	dev_info(ena_dev->dmadev, "ENA controller version: %d.%d.%d implementation version %d\n",
 		 (ctrl_ver & ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_MASK) >>
 			 ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_SHIFT,
 		 (ctrl_ver & ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_MASK) >>
@@ -1694,20 +1633,17 @@
 
 	size = ADMIN_SQ_SIZE(admin_queue->q_depth);
 	if (sq->entries)
-		dma_free_coherent(ena_dev->dmadev, size, sq->entries,
-				  sq->dma_addr);
+		dma_free_coherent(ena_dev->dmadev, size, sq->entries, sq->dma_addr);
 	sq->entries = NULL;
 
 	size = ADMIN_CQ_SIZE(admin_queue->q_depth);
 	if (cq->entries)
-		dma_free_coherent(ena_dev->dmadev, size, cq->entries,
-				  cq->dma_addr);
+		dma_free_coherent(ena_dev->dmadev, size, cq->entries, cq->dma_addr);
 	cq->entries = NULL;
 
 	size = ADMIN_AENQ_SIZE(aenq->q_depth);
 	if (ena_dev->aenq.entries)
-		dma_free_coherent(ena_dev->dmadev, size, aenq->entries,
-				  aenq->dma_addr);
+		dma_free_coherent(ena_dev->dmadev, size, aenq->entries, aenq->dma_addr);
 	aenq->entries = NULL;
 }
 
@@ -1733,10 +1669,8 @@
 	struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
 
 	spin_lock_init(&mmio_read->lock);
-	mmio_read->read_resp =
-		dma_alloc_coherent(ena_dev->dmadev,
-				   sizeof(*mmio_read->read_resp),
-				   &mmio_read->read_resp_dma_addr, GFP_KERNEL);
+	mmio_read->read_resp = dma_alloc_coherent(ena_dev->dmadev, sizeof(*mmio_read->read_resp),
+						  &mmio_read->read_resp_dma_addr, GFP_KERNEL);
 	if (unlikely(!mmio_read->read_resp))
 		goto err;
 
@@ -1767,8 +1701,8 @@
 	writel(0x0, ena_dev->reg_bar + ENA_REGS_MMIO_RESP_LO_OFF);
 	writel(0x0, ena_dev->reg_bar + ENA_REGS_MMIO_RESP_HI_OFF);
 
-	dma_free_coherent(ena_dev->dmadev, sizeof(*mmio_read->read_resp),
-			  mmio_read->read_resp, mmio_read->read_resp_dma_addr);
+	dma_free_coherent(ena_dev->dmadev, sizeof(*mmio_read->read_resp), mmio_read->read_resp,
+			  mmio_read->read_resp_dma_addr);
 
 	mmio_read->read_resp = NULL;
 }
@@ -1800,8 +1734,7 @@
 	}
 
 	if (!(dev_sts & ENA_REGS_DEV_STS_READY_MASK)) {
-		netdev_err(ena_dev->net_device,
-			   "Device isn't ready, abort com init\n");
+		netdev_err(ena_dev->net_device, "Device isn't ready, abort com init\n");
 		return -ENODEV;
 	}
 
@@ -1878,8 +1811,7 @@
 	int ret;
 
 	if (ctx->qid >= ENA_TOTAL_NUM_QUEUES) {
-		netdev_err(ena_dev->net_device,
-			   "Qid (%d) is bigger than max num of queues (%d)\n",
+		netdev_err(ena_dev->net_device, "Qid (%d) is bigger than max num of queues (%d)\n",
 			   ctx->qid, ENA_TOTAL_NUM_QUEUES);
 		return -EINVAL;
 	}
@@ -1905,8 +1837,7 @@
 
 	if (ctx->direction == ENA_COM_IO_QUEUE_DIRECTION_TX)
 		/* header length is limited to 8 bits */
-		io_sq->tx_max_header_size =
-			min_t(u32, ena_dev->tx_max_header_size, SZ_256);
+		io_sq->tx_max_header_size = min_t(u32, ena_dev->tx_max_header_size, SZ_256);
 
 	ret = ena_com_init_io_sq(ena_dev, ctx, io_sq);
 	if (ret)
@@ -1938,8 +1869,7 @@
 	struct ena_com_io_cq *io_cq;
 
 	if (qid >= ENA_TOTAL_NUM_QUEUES) {
-		netdev_err(ena_dev->net_device,
-			   "Qid (%d) is bigger than max num of queues (%d)\n",
+		netdev_err(ena_dev->net_device, "Qid (%d) is bigger than max num of queues (%d)\n",
 			   qid, ENA_TOTAL_NUM_QUEUES);
 		return;
 	}
@@ -1983,8 +1913,7 @@
 		if (rc)
 			return rc;
 
-		if (get_resp.u.max_queue_ext.version !=
-		    ENA_FEATURE_MAX_QUEUE_EXT_VER)
+		if (get_resp.u.max_queue_ext.version != ENA_FEATURE_MAX_QUEUE_EXT_VER)
 			return -EINVAL;
 
 		memcpy(&get_feat_ctx->max_queue_ext, &get_resp.u.max_queue_ext,
@@ -2025,18 +1954,15 @@
 	rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_HW_HINTS, 0);
 
 	if (!rc)
-		memcpy(&get_feat_ctx->hw_hints, &get_resp.u.hw_hints,
-		       sizeof(get_resp.u.hw_hints));
+		memcpy(&get_feat_ctx->hw_hints, &get_resp.u.hw_hints, sizeof(get_resp.u.hw_hints));
 	else if (rc == -EOPNOTSUPP)
-		memset(&get_feat_ctx->hw_hints, 0x0,
-		       sizeof(get_feat_ctx->hw_hints));
+		memset(&get_feat_ctx->hw_hints, 0x0, sizeof(get_feat_ctx->hw_hints));
 	else
 		return rc;
 
 	rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_LLQ, 0);
 	if (!rc)
-		memcpy(&get_feat_ctx->llq, &get_resp.u.llq,
-		       sizeof(get_resp.u.llq));
+		memcpy(&get_feat_ctx->llq, &get_resp.u.llq, sizeof(get_resp.u.llq));
 	else if (rc == -EOPNOTSUPP)
 		memset(&get_feat_ctx->llq, 0x0, sizeof(get_feat_ctx->llq));
 	else
@@ -2084,8 +2010,7 @@
 	aenq_common = &aenq_e->aenq_common_desc;
 
 	/* Go over all the events */
-	while ((READ_ONCE(aenq_common->flags) &
-		ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK) == phase) {
+	while ((READ_ONCE(aenq_common->flags) & ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK) == phase) {
 		/* Make sure the phase bit (ownership) is as expected before
 		 * reading the rest of the descriptor.
 		 */
@@ -2094,8 +2019,7 @@
 		timestamp = (u64)aenq_common->timestamp_low |
 			((u64)aenq_common->timestamp_high << 32);
 
-		netdev_dbg(ena_dev->net_device,
-			   "AENQ! Group[%x] Syndrome[%x] timestamp: [%llus]\n",
+		netdev_dbg(ena_dev->net_device, "AENQ! Group[%x] Syndrome[%x] timestamp: [%llus]\n",
 			   aenq_common->group, aenq_common->syndrome, timestamp);
 
 		/* Handle specific event*/
@@ -2124,8 +2048,7 @@
 
 	/* write the aenq doorbell after all AENQ descriptors were read */
 	mb();
-	writel_relaxed((u32)aenq->head,
-		       ena_dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF);
+	writel_relaxed((u32)aenq->head, ena_dev->reg_bar + ENA_REGS_AENQ_HEAD_DB_OFF);
 }
 
 int ena_com_dev_reset(struct ena_com_dev *ena_dev,
@@ -2137,15 +2060,13 @@
 	stat = ena_com_reg_bar_read32(ena_dev, ENA_REGS_DEV_STS_OFF);
 	cap = ena_com_reg_bar_read32(ena_dev, ENA_REGS_CAPS_OFF);
 
-	if (unlikely((stat == ENA_MMIO_READ_TIMEOUT) ||
-		     (cap == ENA_MMIO_READ_TIMEOUT))) {
+	if (unlikely((stat == ENA_MMIO_READ_TIMEOUT) || (cap == ENA_MMIO_READ_TIMEOUT))) {
 		netdev_err(ena_dev->net_device, "Reg read32 timeout occurred\n");
 		return -ETIME;
 	}
 
 	if ((stat & ENA_REGS_DEV_STS_READY_MASK) == 0) {
-		netdev_err(ena_dev->net_device,
-			   "Device isn't ready, can't reset device\n");
+		netdev_err(ena_dev->net_device, "Device isn't ready, can't reset device\n");
 		return -EINVAL;
 	}
 
@@ -2168,8 +2089,7 @@
 	rc = wait_for_reset_state(ena_dev, timeout,
 				  ENA_REGS_DEV_STS_RESET_IN_PROGRESS_MASK);
 	if (rc != 0) {
-		netdev_err(ena_dev->net_device,
-			   "Reset indication didn't turn on\n");
+		netdev_err(ena_dev->net_device, "Reset indication didn't turn on\n");
 		return rc;
 	}
 
@@ -2177,8 +2097,7 @@
 	writel(0, ena_dev->reg_bar + ENA_REGS_DEV_CTL_OFF);
 	rc = wait_for_reset_state(ena_dev, timeout, 0);
 	if (rc != 0) {
-		netdev_err(ena_dev->net_device,
-			   "Reset indication didn't turn off\n");
+		netdev_err(ena_dev->net_device, "Reset indication didn't turn off\n");
 		return rc;
 	}
 
@@ -2215,8 +2134,7 @@
 					     sizeof(*get_resp));
 
 	if (unlikely(ret))
-		netdev_err(ena_dev->net_device,
-			   "Failed to get stats. error: %d\n", ret);
+		netdev_err(ena_dev->net_device, "Failed to get stats. error: %d\n", ret);
 
 	return ret;
 }
@@ -2228,8 +2146,7 @@
 	int ret;
 
 	if (!ena_com_get_cap(ena_dev, ENA_ADMIN_ENI_STATS)) {
-		netdev_err(ena_dev->net_device,
-			   "Capability %d isn't supported\n",
+		netdev_err(ena_dev->net_device, "Capability %d isn't supported\n",
 			   ENA_ADMIN_ENI_STATS);
 		return -EOPNOTSUPP;
 	}
@@ -2266,8 +2183,7 @@
 	int ret;
 
 	if (!ena_com_check_supported_feature_id(ena_dev, ENA_ADMIN_MTU)) {
-		netdev_dbg(ena_dev->net_device, "Feature %d isn't supported\n",
-			   ENA_ADMIN_MTU);
+		netdev_dbg(ena_dev->net_device, "Feature %d isn't supported\n", ENA_ADMIN_MTU);
 		return -EOPNOTSUPP;
 	}
 
@@ -2286,8 +2202,7 @@
 					    sizeof(resp));
 
 	if (unlikely(ret))
-		netdev_err(ena_dev->net_device,
-			   "Failed to set mtu %d. error: %d\n", mtu, ret);
+		netdev_err(ena_dev->net_device, "Failed to set mtu %d. error: %d\n", mtu, ret);
 
 	return ret;
 }
@@ -2301,8 +2216,7 @@
 	ret = ena_com_get_feature(ena_dev, &resp,
 				  ENA_ADMIN_STATELESS_OFFLOAD_CONFIG, 0);
 	if (unlikely(ret)) {
-		netdev_err(ena_dev->net_device,
-			   "Failed to get offload capabilities %d\n", ret);
+		netdev_err(ena_dev->net_device, "Failed to get offload capabilities %d\n", ret);
 		return ret;
 	}
 
@@ -2320,8 +2234,7 @@
 	struct ena_admin_get_feat_resp get_resp;
 	int ret;
 
-	if (!ena_com_check_supported_feature_id(ena_dev,
-						ENA_ADMIN_RSS_HASH_FUNCTION)) {
+	if (!ena_com_check_supported_feature_id(ena_dev, ENA_ADMIN_RSS_HASH_FUNCTION)) {
 		netdev_dbg(ena_dev->net_device, "Feature %d isn't supported\n",
 			   ENA_ADMIN_RSS_HASH_FUNCTION);
 		return -EOPNOTSUPP;
@@ -2334,8 +2247,7 @@
 		return ret;
 
 	if (!(get_resp.u.flow_hash_func.supported_func & BIT(rss->hash_func))) {
-		netdev_err(ena_dev->net_device,
-			   "Func hash %d isn't supported by device, abort\n",
+		netdev_err(ena_dev->net_device, "Func hash %d isn't supported by device, abort\n",
 			   rss->hash_func);
 		return -EOPNOTSUPP;
 	}
@@ -2365,8 +2277,7 @@
 					    (struct ena_admin_acq_entry *)&resp,
 					    sizeof(resp));
 	if (unlikely(ret)) {
-		netdev_err(ena_dev->net_device,
-			   "Failed to set hash function %d. error: %d\n",
+		netdev_err(ena_dev->net_device, "Failed to set hash function %d. error: %d\n",
 			   rss->hash_func, ret);
 		return -EINVAL;
 	}
@@ -2398,16 +2309,15 @@
 		return rc;
 
 	if (!(BIT(func) & get_resp.u.flow_hash_func.supported_func)) {
-		netdev_err(ena_dev->net_device,
-			   "Flow hash function %d isn't supported\n", func);
+		netdev_err(ena_dev->net_device, "Flow hash function %d isn't supported\n", func);
 		return -EOPNOTSUPP;
 	}
 
 	if ((func == ENA_ADMIN_TOEPLITZ) && key) {
 		if (key_len != sizeof(hash_key->key)) {
 			netdev_err(ena_dev->net_device,
-				   "key len (%u) doesn't equal the supported size (%zu)\n",
-				   key_len, sizeof(hash_key->key));
+				   "key len (%u) doesn't equal the supported size (%zu)\n", key_len,
+				   sizeof(hash_key->key));
 			return -EINVAL;
 		}
 		memcpy(hash_key->key, key, key_len);
@@ -2495,8 +2405,7 @@
 	struct ena_admin_set_feat_resp resp;
 	int ret;
 
-	if (!ena_com_check_supported_feature_id(ena_dev,
-						ENA_ADMIN_RSS_HASH_INPUT)) {
+	if (!ena_com_check_supported_feature_id(ena_dev, ENA_ADMIN_RSS_HASH_INPUT)) {
 		netdev_dbg(ena_dev->net_device, "Feature %d isn't supported\n",
 			   ENA_ADMIN_RSS_HASH_INPUT);
 		return -EOPNOTSUPP;
@@ -2527,8 +2436,7 @@
 					    (struct ena_admin_acq_entry *)&resp,
 					    sizeof(resp));
 	if (unlikely(ret))
-		netdev_err(ena_dev->net_device,
-			   "Failed to set hash input. error: %d\n", ret);
+		netdev_err(ena_dev->net_device, "Failed to set hash input. error: %d\n", ret);
 
 	return ret;
 }
@@ -2605,8 +2513,7 @@
 	int rc;
 
 	if (proto >= ENA_ADMIN_RSS_PROTO_NUM) {
-		netdev_err(ena_dev->net_device, "Invalid proto num (%u)\n",
-			   proto);
+		netdev_err(ena_dev->net_device, "Invalid proto num (%u)\n", proto);
 		return -EINVAL;
 	}
 
@@ -2658,8 +2565,7 @@
 	struct ena_admin_set_feat_resp resp;
 	int ret;
 
-	if (!ena_com_check_supported_feature_id(
-		    ena_dev, ENA_ADMIN_RSS_INDIRECTION_TABLE_CONFIG)) {
+	if (!ena_com_check_supported_feature_id(ena_dev, ENA_ADMIN_RSS_INDIRECTION_TABLE_CONFIG)) {
 		netdev_dbg(ena_dev->net_device, "Feature %d isn't supported\n",
 			   ENA_ADMIN_RSS_INDIRECTION_TABLE_CONFIG);
 		return -EOPNOTSUPP;
@@ -2699,8 +2605,7 @@
 					    sizeof(resp));
 
 	if (unlikely(ret))
-		netdev_err(ena_dev->net_device,
-			   "Failed to set indirect table. error: %d\n", ret);
+		netdev_err(ena_dev->net_device, "Failed to set indirect table. error: %d\n", ret);
 
 	return ret;
 }
@@ -2779,9 +2684,8 @@
 {
 	struct ena_host_attribute *host_attr = &ena_dev->host_attr;
 
-	host_attr->host_info =
-		dma_alloc_coherent(ena_dev->dmadev, SZ_4K,
-				   &host_attr->host_info_dma_addr, GFP_KERNEL);
+	host_attr->host_info = dma_alloc_coherent(ena_dev->dmadev, SZ_4K,
+						  &host_attr->host_info_dma_addr, GFP_KERNEL);
 	if (unlikely(!host_attr->host_info))
 		return -ENOMEM;
 
@@ -2827,8 +2731,7 @@
 
 	if (host_attr->debug_area_virt_addr) {
 		dma_free_coherent(ena_dev->dmadev, host_attr->debug_area_size,
-				  host_attr->debug_area_virt_addr,
-				  host_attr->debug_area_dma_addr);
+				  host_attr->debug_area_virt_addr, host_attr->debug_area_dma_addr);
 		host_attr->debug_area_virt_addr = NULL;
 	}
 }
@@ -2877,8 +2780,7 @@
 					    sizeof(resp));
 
 	if (unlikely(ret))
-		netdev_err(ena_dev->net_device,
-			   "Failed to set host attributes: %d\n", ret);
+		netdev_err(ena_dev->net_device, "Failed to set host attributes: %d\n", ret);
 
 	return ret;
 }
@@ -2896,8 +2798,7 @@
 							  u32 *intr_moder_interval)
 {
 	if (!intr_delay_resolution) {
-		netdev_err(ena_dev->net_device,
-			   "Illegal interrupt delay granularity value\n");
+		netdev_err(ena_dev->net_device, "Illegal interrupt delay granularity value\n");
 		return -EFAULT;
 	}
 
@@ -2935,14 +2836,12 @@
 
 	if (rc) {
 		if (rc == -EOPNOTSUPP) {
-			netdev_dbg(ena_dev->net_device,
-				   "Feature %d isn't supported\n",
+			netdev_dbg(ena_dev->net_device, "Feature %d isn't supported\n",
 				   ENA_ADMIN_INTERRUPT_MODERATION);
 			rc = 0;
 		} else {
 			netdev_err(ena_dev->net_device,
-				   "Failed to get interrupt moderation admin cmd. rc: %d\n",
-				   rc);
+				   "Failed to get interrupt moderation admin cmd. rc: %d\n", rc);
 		}
 
 		/* no moderation supported, disable adaptive support */
@@ -2990,8 +2889,7 @@
 		(llq_info->descs_num_before_header * sizeof(struct ena_eth_io_tx_desc));
 
 	if (unlikely(ena_dev->tx_max_header_size == 0)) {
-		netdev_err(ena_dev->net_device,
-			   "The size of the LLQ entry is smaller than needed\n");
+		netdev_err(ena_dev->net_device, "The size of the LLQ entry is smaller than needed\n");
 		return -EINVAL;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/amazon/ena/ena_com.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/amazon/ena/ena_com.h
@@ -46,7 +46,7 @@
 /*****************************************************************************/
 /* ENA adaptive interrupt moderation settings */
 
-#define ENA_INTR_INITIAL_TX_INTERVAL_USECS 64
+#define ENA_INTR_INITIAL_TX_INTERVAL_USECS 0
 #define ENA_INTR_INITIAL_RX_INTERVAL_USECS 0
 #define ENA_DEFAULT_INTR_DELAY_RESOLUTION 1
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/amazon/ena/ena_eth_com.c
@@ -18,8 +18,7 @@
 	cdesc = (struct ena_eth_io_rx_cdesc_base *)(io_cq->cdesc_addr.virt_addr
 			+ (head_masked * io_cq->cdesc_entry_size_in_bytes));
 
-	desc_phase = (READ_ONCE(cdesc->status) &
-		      ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK) >>
+	desc_phase = (READ_ONCE(cdesc->status) & ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK) >>
 		     ENA_ETH_IO_RX_CDESC_BASE_PHASE_SHIFT;
 
 	if (desc_phase != expected_phase)
@@ -65,8 +64,8 @@
 
 		io_sq->entries_in_tx_burst_left--;
 		netdev_dbg(ena_com_io_sq_to_ena_dev(io_sq)->net_device,
-			   "Decreasing entries_in_tx_burst_left of queue %d to %d\n",
-			   io_sq->qid, io_sq->entries_in_tx_burst_left);
+			   "Decreasing entries_in_tx_burst_left of queue %d to %d\n", io_sq->qid,
+			   io_sq->entries_in_tx_burst_left);
 	}
 
 	/* Make sure everything was written into the bounce buffer before
@@ -75,8 +74,8 @@
 	wmb();
 
 	/* The line is completed. Copy it to dev */
-	__iowrite64_copy(io_sq->desc_addr.pbuf_dev_addr + dst_offset,
-			 bounce_buffer, (llq_info->desc_list_entry_size) / 8);
+	__iowrite64_copy(io_sq->desc_addr.pbuf_dev_addr + dst_offset, bounce_buffer,
+			 (llq_info->desc_list_entry_size) / 8);
 
 	io_sq->tail++;
 
@@ -102,16 +101,14 @@
 	header_offset =
 		llq_info->descs_num_before_header * io_sq->desc_entry_size;
 
-	if (unlikely((header_offset + header_len) >
-		     llq_info->desc_list_entry_size)) {
+	if (unlikely((header_offset + header_len) > llq_info->desc_list_entry_size)) {
 		netdev_err(ena_com_io_sq_to_ena_dev(io_sq)->net_device,
 			   "Trying to write header larger than llq entry can accommodate\n");
 		return -EFAULT;
 	}
 
 	if (unlikely(!bounce_buffer)) {
-		netdev_err(ena_com_io_sq_to_ena_dev(io_sq)->net_device,
-			   "Bounce buffer is NULL\n");
+		netdev_err(ena_com_io_sq_to_ena_dev(io_sq)->net_device, "Bounce buffer is NULL\n");
 		return -EFAULT;
 	}
 
@@ -129,8 +126,7 @@
 	bounce_buffer = pkt_ctrl->curr_bounce_buf;
 
 	if (unlikely(!bounce_buffer)) {
-		netdev_err(ena_com_io_sq_to_ena_dev(io_sq)->net_device,
-			   "Bounce buffer is NULL\n");
+		netdev_err(ena_com_io_sq_to_ena_dev(io_sq)->net_device, "Bounce buffer is NULL\n");
 		return NULL;
 	}
 
@@ -233,31 +229,43 @@
 		idx * io_cq->cdesc_entry_size_in_bytes);
 }
 
-static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
-					   u16 *first_cdesc_idx)
+static int ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
+				    u16 *first_cdesc_idx,
+				    u16 *num_descs)
 {
+	u16 count = io_cq->cur_rx_pkt_cdesc_count, head_masked;
 	struct ena_eth_io_rx_cdesc_base *cdesc;
-	u16 count = 0, head_masked;
 	u32 last = 0;
 
 	do {
+		u32 status;
+
 		cdesc = ena_com_get_next_rx_cdesc(io_cq);
 		if (!cdesc)
 			break;
+		status = READ_ONCE(cdesc->status);
 
 		ena_com_cq_inc_head(io_cq);
+		if (unlikely((status & ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK) >>
+		    ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT && count != 0)) {
+			struct ena_com_dev *dev = ena_com_io_cq_to_ena_dev(io_cq);
+
+			netdev_err(dev->net_device,
+				   "First bit is on in descriptor #%d on q_id: %d, req_id: %u\n",
+				   count, io_cq->qid, cdesc->req_id);
+			return -EFAULT;
+		}
 		count++;
-		last = (READ_ONCE(cdesc->status) &
-			ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >>
-		       ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT;
+		last = (status & ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK) >>
+			ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT;
 	} while (!last);
 
 	if (last) {
 		*first_cdesc_idx = io_cq->cur_rx_pkt_cdesc_start_idx;
-		count += io_cq->cur_rx_pkt_cdesc_count;
 
 		head_masked = io_cq->head & (io_cq->q_depth - 1);
 
+		*num_descs = count;
 		io_cq->cur_rx_pkt_cdesc_count = 0;
 		io_cq->cur_rx_pkt_cdesc_start_idx = head_masked;
 
@@ -265,11 +273,11 @@
 			   "ENA q_id: %d packets were completed. first desc idx %u descs# %d\n",
 			   io_cq->qid, *first_cdesc_idx, count);
 	} else {
-		io_cq->cur_rx_pkt_cdesc_count += count;
-		count = 0;
+		io_cq->cur_rx_pkt_cdesc_count = count;
+		*num_descs = 0;
 	}
 
-	return count;
+	return 0;
 }
 
 static int ena_com_create_meta(struct ena_com_io_sq *io_sq,
@@ -369,9 +377,8 @@
 
 	netdev_dbg(ena_com_io_cq_to_ena_dev(io_cq)->net_device,
 		   "l3_proto %d l4_proto %d l3_csum_err %d l4_csum_err %d hash %d frag %d cdesc_status %x\n",
-		   ena_rx_ctx->l3_proto, ena_rx_ctx->l4_proto,
-		   ena_rx_ctx->l3_csum_err, ena_rx_ctx->l4_csum_err,
-		   ena_rx_ctx->hash, ena_rx_ctx->frag, cdesc->status);
+		   ena_rx_ctx->l3_proto, ena_rx_ctx->l4_proto, ena_rx_ctx->l3_csum_err,
+		   ena_rx_ctx->l4_csum_err, ena_rx_ctx->hash, ena_rx_ctx->frag, cdesc->status);
 }
 
 /*****************************************************************************/
@@ -403,13 +410,12 @@
 
 	if (unlikely(header_len > io_sq->tx_max_header_size)) {
 		netdev_err(ena_com_io_sq_to_ena_dev(io_sq)->net_device,
-			   "Header size is too large %d max header: %d\n",
-			   header_len, io_sq->tx_max_header_size);
+			   "Header size is too large %d max header: %d\n", header_len,
+			   io_sq->tx_max_header_size);
 		return -EINVAL;
 	}
 
-	if (unlikely(io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV &&
-		     !buffer_to_push)) {
+	if (unlikely(io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV && !buffer_to_push)) {
 		netdev_err(ena_com_io_sq_to_ena_dev(io_sq)->net_device,
 			   "Push header wasn't provided in LLQ mode\n");
 		return -EINVAL;
@@ -546,23 +552,25 @@
 	u16 cdesc_idx = 0;
 	u16 nb_hw_desc;
 	u16 i = 0;
+	int rc;
 
 	WARN(io_cq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type");
 
-	nb_hw_desc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx);
+	rc = ena_com_cdesc_rx_pkt_get(io_cq, &cdesc_idx, &nb_hw_desc);
+	if (unlikely(rc != 0))
+		return -EFAULT;
+
 	if (nb_hw_desc == 0) {
 		ena_rx_ctx->descs = nb_hw_desc;
 		return 0;
 	}
 
 	netdev_dbg(ena_com_io_cq_to_ena_dev(io_cq)->net_device,
-		   "Fetch rx packet: queue %d completed desc: %d\n", io_cq->qid,
-		   nb_hw_desc);
+		   "Fetch rx packet: queue %d completed desc: %d\n", io_cq->qid, nb_hw_desc);
 
 	if (unlikely(nb_hw_desc > ena_rx_ctx->max_bufs)) {
 		netdev_err(ena_com_io_cq_to_ena_dev(io_cq)->net_device,
-			   "Too many RX cdescs (%d) > MAX(%d)\n", nb_hw_desc,
-			   ena_rx_ctx->max_bufs);
+			   "Too many RX cdescs (%d) > MAX(%d)\n", nb_hw_desc, ena_rx_ctx->max_bufs);
 		return -ENOSPC;
 	}
 
@@ -586,8 +594,8 @@
 	io_sq->next_to_comp += nb_hw_desc;
 
 	netdev_dbg(ena_com_io_cq_to_ena_dev(io_cq)->net_device,
-		   "[%s][QID#%d] Updating SQ head to: %d\n", __func__,
-		   io_sq->qid, io_sq->next_to_comp);
+		   "[%s][QID#%d] Updating SQ head to: %d\n", __func__, io_sq->qid,
+		   io_sq->next_to_comp);
 
 	/* Get rx flags from the last pkt */
 	ena_com_rx_set_flags(io_cq, ena_rx_ctx, cdesc);
@@ -624,8 +632,8 @@
 	desc->req_id = req_id;
 
 	netdev_dbg(ena_com_io_sq_to_ena_dev(io_sq)->net_device,
-		   "[%s] Adding single RX desc, Queue: %u, req_id: %u\n",
-		   __func__, io_sq->qid, req_id);
+		   "[%s] Adding single RX desc, Queue: %u, req_id: %u\n", __func__, io_sq->qid,
+		   req_id);
 
 	desc->buff_addr_lo = (u32)ena_buf->paddr;
 	desc->buff_addr_hi =
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/amazon/ena/ena_eth_com.h
@@ -145,8 +145,8 @@
 	}
 
 	netdev_dbg(ena_com_io_sq_to_ena_dev(io_sq)->net_device,
-		   "Queue: %d num_descs: %d num_entries_needed: %d\n",
-		   io_sq->qid, num_descs, num_entries_needed);
+		   "Queue: %d num_descs: %d num_entries_needed: %d\n", io_sq->qid, num_descs,
+		   num_entries_needed);
 
 	return num_entries_needed > io_sq->entries_in_tx_burst_left;
 }
@@ -157,15 +157,14 @@
 	u16 tail = io_sq->tail;
 
 	netdev_dbg(ena_com_io_sq_to_ena_dev(io_sq)->net_device,
-		   "Write submission queue doorbell for queue: %d tail: %d\n",
-		   io_sq->qid, tail);
+		   "Write submission queue doorbell for queue: %d tail: %d\n", io_sq->qid, tail);
 
 	writel(tail, io_sq->db_addr);
 
 	if (is_llq_max_tx_burst_exists(io_sq)) {
 		netdev_dbg(ena_com_io_sq_to_ena_dev(io_sq)->net_device,
-			   "Reset available entries in tx burst for queue %d to %d\n",
-			   io_sq->qid, max_entries_in_tx_burst);
+			   "Reset available entries in tx burst for queue %d to %d\n", io_sq->qid,
+			   max_entries_in_tx_burst);
 		io_sq->entries_in_tx_burst_left = max_entries_in_tx_burst;
 	}
 
@@ -248,8 +247,8 @@
 
 	*req_id = READ_ONCE(cdesc->req_id);
 	if (unlikely(*req_id >= io_cq->q_depth)) {
-		netdev_err(ena_com_io_cq_to_ena_dev(io_cq)->net_device,
-			   "Invalid req id %d\n", cdesc->req_id);
+		netdev_err(ena_com_io_cq_to_ena_dev(io_cq)->net_device, "Invalid req id %d\n",
+			   cdesc->req_id);
 		return -EINVAL;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -116,11 +116,9 @@
 	if (unlikely(rc)) {
 		netif_err(adapter, tx_queued, adapter->netdev,
 			  "Failed to prepare tx bufs\n");
-		ena_increase_stat(&ring->tx_stats.prepare_ctx_err, 1,
-				  &ring->syncp);
+		ena_increase_stat(&ring->tx_stats.prepare_ctx_err, 1, &ring->syncp);
 		if (rc != -ENOMEM)
-			ena_reset_device(adapter,
-					 ENA_REGS_RESET_DRIVER_INVALID_STATE);
+			ena_reset_device(adapter, ENA_REGS_RESET_DRIVER_INVALID_STATE);
 		return rc;
 	}
 
@@ -485,8 +483,7 @@
 	 */
 	page = dev_alloc_page();
 	if (!page) {
-		ena_increase_stat(&rx_ring->rx_stats.page_alloc_fail, 1,
-				  &rx_ring->syncp);
+		ena_increase_stat(&rx_ring->rx_stats.page_alloc_fail, 1, &rx_ring->syncp);
 		return ERR_PTR(-ENOSPC);
 	}
 
@@ -545,8 +542,8 @@
 				    struct ena_rx_buffer *rx_info,
 				    unsigned long attrs)
 {
-	dma_unmap_page_attrs(rx_ring->dev, rx_info->dma_addr, ENA_PAGE_SIZE,
-			     DMA_BIDIRECTIONAL, attrs);
+	dma_unmap_page_attrs(rx_ring->dev, rx_info->dma_addr, ENA_PAGE_SIZE, DMA_BIDIRECTIONAL,
+			     attrs);
 }
 
 static void ena_free_rx_page(struct ena_ring *rx_ring,
@@ -696,8 +693,11 @@
 static void ena_free_tx_bufs(struct ena_ring *tx_ring)
 {
 	bool print_once = true;
+	bool is_xdp_ring;
 	u32 i;
 
+	is_xdp_ring = ENA_IS_XDP_INDEX(tx_ring->adapter, tx_ring->qid);
+
 	for (i = 0; i < tx_ring->ring_size; i++) {
 		struct ena_tx_buffer *tx_info = &tx_ring->tx_buffer_info[i];
 
@@ -717,10 +717,15 @@
 
 		ena_unmap_tx_buff(tx_ring, tx_info);
 
-		dev_kfree_skb_any(tx_info->skb);
+		if (is_xdp_ring)
+			xdp_return_frame(tx_info->xdpf);
+		else
+			dev_kfree_skb_any(tx_info->skb);
 	}
-	netdev_tx_reset_queue(netdev_get_tx_queue(tx_ring->netdev,
-						  tx_ring->qid));
+
+	if (!is_xdp_ring)
+		netdev_tx_reset_queue(netdev_get_tx_queue(tx_ring->netdev,
+							  tx_ring->qid));
 }
 
 static void ena_free_all_tx_bufs(struct ena_adapter *adapter)
@@ -819,8 +824,7 @@
 						&req_id);
 		if (rc) {
 			if (unlikely(rc == -EINVAL))
-				handle_invalid_req_id(tx_ring, req_id, NULL,
-						      false);
+				handle_invalid_req_id(tx_ring, req_id, NULL, false);
 			break;
 		}
 
@@ -1046,8 +1050,7 @@
 					DMA_FROM_DEVICE);
 
 		if (!reuse_rx_buf_page)
-			ena_unmap_rx_buff_attrs(rx_ring, rx_info,
-						DMA_ATTR_SKIP_CPU_SYNC);
+			ena_unmap_rx_buff_attrs(rx_ring, rx_info, DMA_ATTR_SKIP_CPU_SYNC);
 
 		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, rx_info->page,
 				page_offset + buf_offset, len, buf_len);
@@ -1320,9 +1323,10 @@
 	adapter = netdev_priv(rx_ring->netdev);
 
 	if (rc == -ENOSPC) {
-		ena_increase_stat(&rx_ring->rx_stats.bad_desc_num, 1,
-				  &rx_ring->syncp);
+		ena_increase_stat(&rx_ring->rx_stats.bad_desc_num, 1, &rx_ring->syncp);
 		ena_reset_device(adapter, ENA_REGS_RESET_TOO_MANY_RX_DESCS);
+	} else if (rc == -EFAULT) {
+		ena_reset_device(adapter, ENA_REGS_RESET_RX_DESCRIPTOR_MALFORMED);
 	} else {
 		ena_increase_stat(&rx_ring->rx_stats.bad_req_id, 1,
 				  &rx_ring->syncp);
@@ -1811,8 +1815,7 @@
 	if (!ena_dev->rss.tbl_log_size) {
 		rc = ena_rss_init_default(adapter);
 		if (rc && (rc != -EOPNOTSUPP)) {
-			netif_err(adapter, ifup, adapter->netdev,
-				  "Failed to init RSS rc: %d\n", rc);
+			netif_err(adapter, ifup, adapter->netdev, "Failed to init RSS rc: %d\n", rc);
 			return rc;
 		}
 	}
@@ -2670,22 +2673,6 @@
 	return NETDEV_TX_OK;
 }
 
-static u16 ena_select_queue(struct net_device *dev, struct sk_buff *skb,
-			    struct net_device *sb_dev)
-{
-	u16 qid;
-	/* we suspect that this is good for in--kernel network services that
-	 * want to loop incoming skb rx to tx in normal user generated traffic,
-	 * most probably we will not get to this
-	 */
-	if (skb_rx_queue_recorded(skb))
-		qid = skb_get_rx_queue(skb);
-	else
-		qid = netdev_pick_tx(dev, skb, NULL);
-
-	return qid;
-}
-
 static void ena_config_host_info(struct ena_com_dev *ena_dev, struct pci_dev *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -2764,8 +2751,7 @@
 	rc = ena_com_set_host_attributes(adapter->ena_dev);
 	if (rc) {
 		if (rc == -EOPNOTSUPP)
-			netif_warn(adapter, drv, adapter->netdev,
-				   "Cannot set host attributes\n");
+			netif_warn(adapter, drv, adapter->netdev, "Cannot set host attributes\n");
 		else
 			netif_err(adapter, drv, adapter->netdev,
 				  "Cannot set host attributes\n");
@@ -2863,7 +2849,6 @@
 	.ndo_open		= ena_open,
 	.ndo_stop		= ena_close,
 	.ndo_start_xmit		= ena_start_xmit,
-	.ndo_select_queue	= ena_select_queue,
 	.ndo_get_stats64	= ena_get_stats64,
 	.ndo_tx_timeout		= ena_tx_timeout,
 	.ndo_change_mtu		= ena_change_mtu,
@@ -3438,10 +3423,11 @@
 {
 	struct ena_ring *tx_ring;
 	struct ena_ring *rx_ring;
-	int i, budget, rc;
+	int qid, budget, rc;
 	int io_queue_count;
 
 	io_queue_count = adapter->xdp_num_queues + adapter->num_io_queues;
+
 	/* Make sure the driver doesn't turn the device in other process */
 	smp_rmb();
 
@@ -3454,27 +3440,29 @@
 	if (adapter->missing_tx_completion_to == ENA_HW_HINTS_NO_TIMEOUT)
 		return;
 
-	budget = ENA_MONITORED_TX_QUEUES;
+	budget = min_t(u32, io_queue_count, ENA_MONITORED_TX_QUEUES);
 
-	for (i = adapter->last_monitored_tx_qid; i < io_queue_count; i++) {
-		tx_ring = &adapter->tx_ring[i];
-		rx_ring = &adapter->rx_ring[i];
+	qid = adapter->last_monitored_tx_qid;
+
+	while (budget) {
+		qid = (qid + 1) % io_queue_count;
+
+		tx_ring = &adapter->tx_ring[qid];
+		rx_ring = &adapter->rx_ring[qid];
 
 		rc = check_missing_comp_in_tx_queue(adapter, tx_ring);
 		if (unlikely(rc))
 			return;
 
-		rc =  !ENA_IS_XDP_INDEX(adapter, i) ?
+		rc =  !ENA_IS_XDP_INDEX(adapter, qid) ?
 			check_for_rx_interrupt_queue(adapter, rx_ring) : 0;
 		if (unlikely(rc))
 			return;
 
 		budget--;
-		if (!budget)
-			break;
 	}
 
-	adapter->last_monitored_tx_qid = i % io_queue_count;
+	adapter->last_monitored_tx_qid = qid;
 }
 
 /* trigger napi schedule after 2 consecutive detections */
@@ -3762,8 +3750,8 @@
 		}
 	}
 
-	rc = ena_com_fill_hash_function(ena_dev, ENA_ADMIN_TOEPLITZ, NULL,
-					ENA_HASH_KEY_SIZE, 0xFFFFFFFF);
+	rc = ena_com_fill_hash_function(ena_dev, ENA_ADMIN_TOEPLITZ, NULL, ENA_HASH_KEY_SIZE,
+					0xFFFFFFFF);
 	if (unlikely(rc && (rc != -EOPNOTSUPP))) {
 		dev_err(dev, "Cannot fill hash function\n");
 		goto err_fill_indir;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/amazon/ena/ena_regs_defs.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/amazon/ena/ena_regs_defs.h
@@ -21,6 +21,7 @@
 	ENA_REGS_RESET_USER_TRIGGER                 = 12,
 	ENA_REGS_RESET_GENERIC                      = 13,
 	ENA_REGS_RESET_MISS_INTERRUPT               = 14,
+	ENA_REGS_RESET_RX_DESCRIPTOR_MALFORMED	    = 16,
 };
 
 /* ena_registers offsets */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/amazon/ena/ena_xdp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/amazon/ena/ena_xdp.c
@@ -89,7 +89,7 @@
 
 	rc = ena_xdp_tx_map_frame(tx_ring, tx_info, xdpf, &ena_tx_ctx);
 	if (unlikely(rc))
-		return rc;
+		goto err;
 
 	ena_tx_ctx.req_id = req_id;
 
@@ -112,7 +112,9 @@
 
 error_unmap_dma:
 	ena_unmap_tx_buff(tx_ring, tx_info);
+err:
 	tx_info->xdpf = NULL;
+
 	return rc;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/amd/mvme147.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/amd/mvme147.c
@@ -105,10 +105,6 @@
 	macaddr[3] = address&0xff;
 	eth_hw_addr_set(dev, macaddr);
 
-	printk("%s: MVME147 at 0x%08lx, irq %d, Hardware Address %pM\n",
-	       dev->name, dev->base_addr, MVME147_LANCE_IRQ,
-	       dev->dev_addr);
-
 	lp = netdev_priv(dev);
 	lp->ram = __get_dma_pages(GFP_ATOMIC, 3);	/* 32K */
 	if (!lp->ram) {
@@ -138,6 +134,9 @@
 		return ERR_PTR(err);
 	}
 
+	netdev_info(dev, "MVME147 at 0x%08lx, irq %d, Hardware Address %pM\n",
+		    dev->base_addr, MVME147_LANCE_IRQ, dev->dev_addr);
+
 	return dev;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/amd/pds_core/core.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/amd/pds_core/core.c
@@ -595,6 +595,16 @@
 	pdsc_teardown(pdsc, PDSC_TEARDOWN_RECOVERY);
 }
 
+void pdsc_pci_reset_thread(struct work_struct *work)
+{
+	struct pdsc *pdsc = container_of(work, struct pdsc, pci_reset_work);
+	struct pci_dev *pdev = pdsc->pdev;
+
+	pci_dev_get(pdev);
+	pci_reset_function(pdev);
+	pci_dev_put(pdev);
+}
+
 static void pdsc_check_pci_health(struct pdsc *pdsc)
 {
 	u8 fw_status;
@@ -609,8 +619,8 @@
 	if (fw_status != PDS_RC_BAD_PCI)
 		return;
 
-	pdsc_reset_prepare(pdsc->pdev);
-	pdsc_reset_done(pdsc->pdev);
+	/* prevent deadlock between pdsc_reset_prepare and pdsc_health_thread */
+	queue_work(pdsc->wq, &pdsc->pci_reset_work);
 }
 
 void pdsc_health_thread(struct work_struct *work)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/amd/pds_core/core.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/amd/pds_core/core.h
@@ -197,6 +197,7 @@
 	struct pdsc_qcq notifyqcq;
 	u64 last_eid;
 	struct pdsc_viftype *viftype_status;
+	struct work_struct pci_reset_work;
 };
 
 /** enum pds_core_dbell_bits - bitwise composition of dbell values.
@@ -283,9 +284,6 @@
 int pdsc_devcmd_reset(struct pdsc *pdsc);
 int pdsc_dev_init(struct pdsc *pdsc);
 
-void pdsc_reset_prepare(struct pci_dev *pdev);
-void pdsc_reset_done(struct pci_dev *pdev);
-
 int pdsc_intr_alloc(struct pdsc *pdsc, char *name,
 		    irq_handler_t handler, void *data);
 void pdsc_intr_free(struct pdsc *pdsc, int index);
@@ -315,5 +313,6 @@
 
 void pdsc_fw_down(struct pdsc *pdsc);
 void pdsc_fw_up(struct pdsc *pdsc);
+void pdsc_pci_reset_thread(struct work_struct *work);
 
 #endif /* _PDSC_H_ */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/amd/pds_core/dev.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/amd/pds_core/dev.c
@@ -229,6 +229,9 @@
 		.reset.opcode = PDS_CORE_CMD_RESET,
 	};
 
+	if (!pdsc_is_fw_running(pdsc))
+		return 0;
+
 	return pdsc_devcmd(pdsc, &cmd, &comp, pdsc->devcmd_timeout);
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/amd/pds_core/devlink.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/amd/pds_core/devlink.c
@@ -117,7 +117,7 @@
 	if (err && err != -EIO)
 		return err;
 
-	listlen = fw_list.num_fw_slots;
+	listlen = min(fw_list.num_fw_slots, ARRAY_SIZE(fw_list.fw_names));
 	for (i = 0; i < listlen; i++) {
 		if (i < ARRAY_SIZE(fw_slotnames))
 			strscpy(buf, fw_slotnames[i], sizeof(buf));
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/amd/pds_core/main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/amd/pds_core/main.c
@@ -238,6 +238,7 @@
 	snprintf(wq_name, sizeof(wq_name), "%s.%d", PDS_CORE_DRV_NAME, pdsc->uid);
 	pdsc->wq = create_singlethread_workqueue(wq_name);
 	INIT_WORK(&pdsc->health_work, pdsc_health_thread);
+	INIT_WORK(&pdsc->pci_reset_work, pdsc_pci_reset_thread);
 	timer_setup(&pdsc->wdtimer, pdsc_wdtimer_cb, 0);
 	pdsc->wdtimer_period = PDSC_WATCHDOG_SECS * HZ;
 
@@ -468,7 +469,7 @@
 	mod_timer(&pdsc->wdtimer, jiffies + 1);
 }
 
-void pdsc_reset_prepare(struct pci_dev *pdev)
+static void pdsc_reset_prepare(struct pci_dev *pdev)
 {
 	struct pdsc *pdsc = pci_get_drvdata(pdev);
 
@@ -477,10 +478,11 @@
 
 	pdsc_unmap_bars(pdsc);
 	pci_release_regions(pdev);
-	pci_disable_device(pdev);
+	if (pci_is_enabled(pdev))
+		pci_disable_device(pdev);
 }
 
-void pdsc_reset_done(struct pci_dev *pdev)
+static void pdsc_reset_done(struct pci_dev *pdev)
 {
 	struct pdsc *pdsc = pci_get_drvdata(pdev);
 	struct device *dev = pdsc->dev;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
@@ -923,7 +923,6 @@
 
 static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata)
 {
-	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
 	struct xgbe_phy_data *phy_data = pdata->phy_data;
 	unsigned int phy_id = phy_data->phydev->phy_id;
 
@@ -945,14 +944,7 @@
 	phy_write(phy_data->phydev, 0x04, 0x0d01);
 	phy_write(phy_data->phydev, 0x00, 0x9140);
 
-	linkmode_set_bit_array(phy_10_100_features_array,
-			       ARRAY_SIZE(phy_10_100_features_array),
-			       supported);
-	linkmode_set_bit_array(phy_gbit_features_array,
-			       ARRAY_SIZE(phy_gbit_features_array),
-			       supported);
-
-	linkmode_copy(phy_data->phydev->supported, supported);
+	linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES);
 
 	phy_support_asym_pause(phy_data->phydev);
 
@@ -964,7 +956,6 @@
 
 static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata)
 {
-	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
 	struct xgbe_phy_data *phy_data = pdata->phy_data;
 	struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom;
 	unsigned int phy_id = phy_data->phydev->phy_id;
@@ -1028,13 +1019,7 @@
 	reg = phy_read(phy_data->phydev, 0x00);
 	phy_write(phy_data->phydev, 0x00, reg & ~0x00800);
 
-	linkmode_set_bit_array(phy_10_100_features_array,
-			       ARRAY_SIZE(phy_10_100_features_array),
-			       supported);
-	linkmode_set_bit_array(phy_gbit_features_array,
-			       ARRAY_SIZE(phy_gbit_features_array),
-			       supported);
-	linkmode_copy(phy_data->phydev->supported, supported);
+	linkmode_copy(phy_data->phydev->supported, PHY_GBIT_FEATURES);
 	phy_support_asym_pause(phy_data->phydev);
 
 	netif_dbg(pdata, drv, pdata->netdev,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
@@ -265,7 +265,7 @@
 		const int rx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_rx_stat_names);
 		const int tx_stat_cnt = ARRAY_SIZE(aq_ethtool_queue_tx_stat_names);
 		char tc_string[8];
-		int tc;
+		unsigned int tc;
 
 		memset(tc_string, 0, sizeof(tc_string));
 		memcpy(p, aq_ethtool_stat_names,
@@ -274,7 +274,7 @@
 
 		for (tc = 0; tc < cfg->tcs; tc++) {
 			if (cfg->is_qos)
-				snprintf(tc_string, 8, "TC%d ", tc);
+				snprintf(tc_string, 8, "TC%u ", tc);
 
 			for (i = 0; i < cfg->vecs; i++) {
 				for (si = 0; si < rx_stat_cnt; si++) {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/aquantia/atlantic/aq_nic.c
@@ -1441,7 +1441,9 @@
 	aq_ptp_ring_free(self);
 	aq_ptp_free(self);
 
-	if (likely(self->aq_fw_ops->deinit) && link_down) {
+	/* May be invoked during hot unplug. */
+	if (pci_device_is_present(self->pdev) &&
+	    likely(self->aq_fw_ops->deinit) && link_down) {
 		mutex_lock(&self->fwreq_mutex);
 		self->aq_fw_ops->deinit(self->aq_hw);
 		mutex_unlock(&self->fwreq_mutex);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/arc/emac_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/arc/emac_main.c
@@ -111,6 +111,7 @@
 {
 	struct arc_emac_priv *priv = netdev_priv(ndev);
 	struct net_device_stats *stats = &ndev->stats;
+	struct device *dev = ndev->dev.parent;
 	unsigned int i;
 
 	for (i = 0; i < TX_BD_NUM; i++) {
@@ -140,7 +141,7 @@
 			stats->tx_bytes += skb->len;
 		}
 
-		dma_unmap_single(&ndev->dev, dma_unmap_addr(tx_buff, addr),
+		dma_unmap_single(dev, dma_unmap_addr(tx_buff, addr),
 				 dma_unmap_len(tx_buff, len), DMA_TO_DEVICE);
 
 		/* return the sk_buff to system */
@@ -174,6 +175,7 @@
 static int arc_emac_rx(struct net_device *ndev, int budget)
 {
 	struct arc_emac_priv *priv = netdev_priv(ndev);
+	struct device *dev = ndev->dev.parent;
 	unsigned int work_done;
 
 	for (work_done = 0; work_done < budget; work_done++) {
@@ -223,9 +225,9 @@
 			continue;
 		}
 
-		addr = dma_map_single(&ndev->dev, (void *)skb->data,
+		addr = dma_map_single(dev, (void *)skb->data,
 				      EMAC_BUFFER_SIZE, DMA_FROM_DEVICE);
-		if (dma_mapping_error(&ndev->dev, addr)) {
+		if (dma_mapping_error(dev, addr)) {
 			if (net_ratelimit())
 				netdev_err(ndev, "cannot map dma buffer\n");
 			dev_kfree_skb(skb);
@@ -237,7 +239,7 @@
 		}
 
 		/* unmap previosly mapped skb */
-		dma_unmap_single(&ndev->dev, dma_unmap_addr(rx_buff, addr),
+		dma_unmap_single(dev, dma_unmap_addr(rx_buff, addr),
 				 dma_unmap_len(rx_buff, len), DMA_FROM_DEVICE);
 
 		pktlen = info & LEN_MASK;
@@ -423,6 +425,7 @@
 {
 	struct arc_emac_priv *priv = netdev_priv(ndev);
 	struct phy_device *phy_dev = ndev->phydev;
+	struct device *dev = ndev->dev.parent;
 	int i;
 
 	phy_dev->autoneg = AUTONEG_ENABLE;
@@ -445,9 +448,9 @@
 		if (unlikely(!rx_buff->skb))
 			return -ENOMEM;
 
-		addr = dma_map_single(&ndev->dev, (void *)rx_buff->skb->data,
+		addr = dma_map_single(dev, (void *)rx_buff->skb->data,
 				      EMAC_BUFFER_SIZE, DMA_FROM_DEVICE);
-		if (dma_mapping_error(&ndev->dev, addr)) {
+		if (dma_mapping_error(dev, addr)) {
 			netdev_err(ndev, "cannot dma map\n");
 			dev_kfree_skb(rx_buff->skb);
 			return -ENOMEM;
@@ -548,6 +551,7 @@
 static void arc_free_tx_queue(struct net_device *ndev)
 {
 	struct arc_emac_priv *priv = netdev_priv(ndev);
+	struct device *dev = ndev->dev.parent;
 	unsigned int i;
 
 	for (i = 0; i < TX_BD_NUM; i++) {
@@ -555,7 +559,7 @@
 		struct buffer_state *tx_buff = &priv->tx_buff[i];
 
 		if (tx_buff->skb) {
-			dma_unmap_single(&ndev->dev,
+			dma_unmap_single(dev,
 					 dma_unmap_addr(tx_buff, addr),
 					 dma_unmap_len(tx_buff, len),
 					 DMA_TO_DEVICE);
@@ -579,6 +583,7 @@
 static void arc_free_rx_queue(struct net_device *ndev)
 {
 	struct arc_emac_priv *priv = netdev_priv(ndev);
+	struct device *dev = ndev->dev.parent;
 	unsigned int i;
 
 	for (i = 0; i < RX_BD_NUM; i++) {
@@ -586,7 +591,7 @@
 		struct buffer_state *rx_buff = &priv->rx_buff[i];
 
 		if (rx_buff->skb) {
-			dma_unmap_single(&ndev->dev,
+			dma_unmap_single(dev,
 					 dma_unmap_addr(rx_buff, addr),
 					 dma_unmap_len(rx_buff, len),
 					 DMA_FROM_DEVICE);
@@ -679,6 +684,7 @@
 	unsigned int len, *txbd_curr = &priv->txbd_curr;
 	struct net_device_stats *stats = &ndev->stats;
 	__le32 *info = &priv->txbd[*txbd_curr].info;
+	struct device *dev = ndev->dev.parent;
 	dma_addr_t addr;
 
 	if (skb_padto(skb, ETH_ZLEN))
@@ -692,10 +698,9 @@
 		return NETDEV_TX_BUSY;
 	}
 
-	addr = dma_map_single(&ndev->dev, (void *)skb->data, len,
-			      DMA_TO_DEVICE);
+	addr = dma_map_single(dev, (void *)skb->data, len, DMA_TO_DEVICE);
 
-	if (unlikely(dma_mapping_error(&ndev->dev, addr))) {
+	if (unlikely(dma_mapping_error(dev, addr))) {
 		stats->tx_dropped++;
 		stats->tx_errors++;
 		dev_kfree_skb_any(skb);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/arc/emac_mdio.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/arc/emac_mdio.c
@@ -133,6 +133,7 @@
 	struct arc_emac_mdio_bus_data *data = &priv->bus_data;
 	struct device_node *np = priv->dev->of_node;
 	const char *name = "Synopsys MII Bus";
+	struct device_node *mdio_node;
 	struct mii_bus *bus;
 	int error;
 
@@ -164,7 +165,13 @@
 
 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", bus->name);
 
-	error = of_mdiobus_register(bus, priv->dev->of_node);
+	/* Backwards compatibility for EMAC nodes without MDIO subnode. */
+	mdio_node = of_get_child_by_name(np, "mdio");
+	if (!mdio_node)
+		mdio_node = of_node_get(np);
+
+	error = of_mdiobus_register(bus, mdio_node);
+	of_node_put(mdio_node);
 	if (error) {
 		mdiobus_free(bus);
 		return dev_err_probe(priv->dev, error,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/Kconfig
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/Kconfig
@@ -32,4 +32,11 @@
 
 	  If unsure say N.
 
+config AX88179B
+	tristate "Asix AX88179B support"
+	select PHYLIB
+	depends on USB
+	help
+	  Say Y here if you intend to use ASIX AX88179B attached in USB mode.
+
 endif # NET_VENDOR_ASIX
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/Makefile
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/Makefile
@@ -4,3 +4,4 @@
 
 obj-$(CONFIG_SPI_AX88796C) += ax88796c.o
 ax88796c-y := ax88796c_main.o ax88796c_ioctl.o ax88796c_spi.o
+obj-$(CONFIG_AX88179B) += ax88179b/
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/Makefile
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/Makefile
@@ -0,0 +1,97 @@
+TARGET	= ax_usb_nic
+KDIR	:= /lib/modules/$(shell uname -r)/build
+PWD	= $(shell pwd)
+
+ENABLE_IOCTL_DEBUG = n
+ENABLE_AUTODETACH_FUNC = n
+ENABLE_MAC_PASS = n
+ENABLE_INT_AGGRESSIVE = y
+ENABLE_INT_POLLING = n
+ENABLE_AUTOSUSPEND = n
+ENABLE_TX_TASKLET = n
+ENABLE_RX_TASKLET = n
+ENABLE_PTP_FUNC = n
+ENABLE_PTP_DEBUG = n
+ENABLE_QUEUE_PRIORITY = n
+
+obj-$(CONFIG_AX88179B) := $(TARGET).o
+$(TARGET)-objs := ax_main.o ax88179_178a.o ax88179a_772d.o
+EXTRA_CFLAGS = -fno-pie
+TOOL_EXTRA_CFLAGS = -Werror
+
+ifeq ($(ENABLE_IOCTL_DEBUG), y)
+	EXTRA_CFLAGS += -DENABLE_IOCTL_DEBUG
+	TOOL_EXTRA_CFLAGS += -DENABLE_IOCTL_DEBUG
+endif
+
+ifeq ($(ENABLE_AUTODETACH_FUNC), y)
+	EXTRA_CFLAGS += -DENABLE_AUTODETACH_FUNC
+endif
+
+ifeq ($(ENABLE_MAC_PASS), y)
+	EXTRA_CFLAGS += -DENABLE_MAC_PASS
+endif
+
+ifeq ($(ENABLE_INT_AGGRESSIVE), y)
+	EXTRA_CFLAGS += -DENABLE_INT_AGGRESSIVE
+endif
+
+ifeq ($(ENABLE_INT_POLLING), y)
+	EXTRA_CFLAGS += -DENABLE_INT_POLLING
+endif
+
+ifeq ($(ENABLE_AUTOSUSPEND), y)
+	EXTRA_CFLAGS += -DENABLE_AUTOSUSPEND
+endif
+
+ifeq ($(ENABLE_TX_TASKLET), y)
+	EXTRA_CFLAGS += -DENABLE_TX_TASKLET
+endif
+ifeq ($(ENABLE_RX_TASKLET), y)
+	EXTRA_CFLAGS += -DENABLE_RX_TASKLET
+endif
+
+ifeq ($(ENABLE_PTP_FUNC), y)
+	$(TARGET)-objs += ax_ptp.o
+	EXTRA_CFLAGS += -DENABLE_PTP_FUNC
+ifeq ($(ENABLE_PTP_DEBUG), y)
+	EXTRA_CFLAGS += -DENABLE_PTP_DEBUG
+endif
+endif
+
+ifeq ($(ENABLE_QUEUE_PRIORITY), y)
+	EXTRA_CFLAGS += -DENABLE_QUEUE_PRIORITY
+endif
+
+	EXTRA_CFLAGS += -DENABLE_AX88279
+
+ifneq (,$(filter $(SUBLEVEL),14 15 16 17 18 19 20 21))
+MDIR	= kernel/drivers/usb/net
+else
+MDIR	= kernel/drivers/net/usb
+endif
+
+all:
+	make -C $(KDIR) M=$(PWD) modules
+	$(CC) $(TOOL_EXTRA_CFLAGS) ax88179_programmer.c -o ax88179_programmer
+	$(CC) $(TOOL_EXTRA_CFLAGS) ax88179a_programmer.c -o ax88179b_179a_772e_772d_programmer
+	$(CC) $(TOOL_EXTRA_CFLAGS) ax88279_programmer.c -o ax88279_programmer
+	$(CC) $(TOOL_EXTRA_CFLAGS) ax88179a_ieee.c -o ax88179b_179a_772e_772d_ieee
+	$(CC) $(TOOL_EXTRA_CFLAGS) axcmd.c -o axcmd
+
+install:
+ifneq (,$(wildcard /lib/modules/$(shell uname -r)/$(MDIR)/ax88179_178a.ko))
+	gzip /lib/modules/$(shell uname -r)/$(MDIR)/ax88179_178a.ko
+endif
+	make -C $(KDIR) M=$(PWD) INSTALL_MOD_DIR=$(MDIR) modules_install
+	depmod -a
+
+uninstall:
+ifneq (,$(wildcard /lib/modules/$(shell uname -r)/$(MDIR)/$(TARGET).ko))
+	rm -f /lib/modules/$(shell uname -r)/$(MDIR)/$(TARGET).ko
+endif
+	depmod -a
+
+clean:
+	make -C $(KDIR) M=$(PWD) clean
+	rm -rf *_programmer *_ieee axcmd .tmp_versions
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/Readme
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/Readme
@@ -0,0 +1,264 @@
+===============================================================================
+ASIX USB3.0/2.0 Gigabit Ethernet Network Adapter
+Driver Compilation & Configuration on Linux
+===============================================================================
+
+================
+Prerequisites
+================
+
+Prepare to build the driver, you need the Linux kernel sources installed on the
+build machine, and make sure that the version of the running kernel must match
+the installed kernel sources. If you don't have the kernel sources, you can get
+it from www.kernel.org or contact to your Linux distributor. If you don't know 
+how to do, please refer to KERNEL-HOWTO.
+
+Note: Please make sure the kernel is built with one of the "Support for 
+      Host-side, XHCI, EHCI, OHCI, or UHCI" option support.
+
+================
+Getting Start
+================
+
+1. Extract the compressed driver source file to your temporary directory by the
+following command:
+	$tar -xf DRIVER_SOURCE_PACKAGE.tar.bz2
+
+
+2. Now, the driver source files should be extracted under the current directory.
+Issue the following command to compile the driver:
+	$make
+
+
+3. If the compilation is done, the ax_usb_nic.ko will be created under the
+current directory.
+
+================
+Usage
+================
+
+=== Install driver to your system
+1. If you want to use modprobe command to mount the driver, issue the
+following command to install the driver into your system:
+	$sudo make install
+Note: This command will backup the built-in ax88179_178a driver if it exists.
+
+2. If you want to load the driver by modprobe command, issue the following 
+commands:
+	$sudo modprobe ax_usb_nic
+
+3. If you want to unload the driver by modprobe command, issue the following 
+commands:
+	$sudo modprobe -r ax_usb_nic
+
+4. If you want to check the information of driver, issue the following commands:
+	$modinfo ax_usb_nic 
+
+=== Install driver manually
+1. If you want to load the driver manually, go to the driver directory and
+execute the following commands:
+	$sudo modprobe mii
+	$sudo insmod ax_usb_nic.ko
+
+2. If you want to unload the driver, just executing the following command:
+	$sudo rmmod ax_usb_nic
+
+3. If you want to check the information of driver, issue the following commands:
+	$modinfo ax_usb_nic.ko
+
+
+================
+Programmer & IEEE TEST
+================
+ASIX USB Ethernet Linux Command Line Programming Tool
+
+[Note]: Enable DEBUG message
+* Modify ENABLE_IOCTL_DEBUG to y in Makefile.
+	ENABLE_IOCTL_DEBUG = n
+	->
+	ENABLE_IOCTL_DEBUG = y
+
+1. Extract the compressed driver source file to your temporary directory by the
+following command:
+	$tar -xf DRIVER_SOURCE_PACKAGE.tar.bz2
+
+2. Now, the driver source files should be extracted under the current directory.
+Executing the following command to compile the driver:
+	$make
+
+3. Load the driver manually, go to the driver directory and execute the 
+following commands:
+	$sudo modprobe mii
+	$sudo insmod ax_usb_nic.ko
+
+4. If the compilation is well, the ioctl will be created under the current 
+directory.
+
+Note: The default way to find the interface is to scan the ASIX device using
+ the ethx (x: 0~255).It is defined in the file, command.h.
+	(As follows)
+	...
+	// DEFAULT_SCAN   : scan "eth0" - "eth255"
+	// INTERFACE_SCAN : scan all available network interfaces
+	#define NET_INTERFACE	DEFAULT_SCAN
+	#define	DEFAULT_SCAN	0x00
+	#define	INTERFACE_SCAN	0x01
+	...
+Adjust the contents of #define NET_INTERFACE to select the method you want.
+
+================
+Enable PTP(Precision Time Protocol)
+================
+1. If you want to enable the PTP function, please modify ENABLE_PTP_FUNC to 'y' in the makefile, 
+	and then recompile it.
+	
+	ENABLE_PTP_FUNC = n
+	->
+	ENABLE_PTP_FUNC = y
+
+=== AX88179/178A EEPROM/eFuse Programmer
+1. If you want to read out values of the EEPROM/EFUSE to a file, go to the 
+driver directory and execute the following command:
+	$sudo ./ax88179_programmer reeprom 0 eeprom 512
+	$sudo ./ax88179_programmer reeprom 1 efuse 64
+
+2. If you want to write values of a file to the EEPROM/EFUSE,  go to the driver
+directory and execute the following command:
+	$sudo ./ax88179_programmer weeprom 0 eeprom 512
+	$sudo ./ax88179_programmer weeprom 1 efuse 64
+
+3. If you want to change the MAC address of a dongle, go to the driver directory
+ and execute the following command:
+	$sudo ./ax88179_programmer chgmac 0 mac_addr 512
+	$sudo ./ax88179_programmer chgmac 1 mac_addr 64
+
+4. If you need more information about the instructions, go to the driver 
+directory and execute the following commands:
+	$sudo ./ax88179_programmer reeprom help
+	$sudo ./ax88179_programmer weeprom help
+	$sudo ./ax88179_programmer chgmac help
+
+=== AX88179B/179A/772E/772D Flash/eFuse Programmer
+1. If you want to get help message for specific command, go to the driver 
+directory and execute the following command:
+	$sudo ./ax88179b_179a_772e_772d_programmer help [command]
+
+2. If you want to get the version of firmware, go to the driver directory 
+and execute the following command:
+	$sudo ./ax88179b_179a_772e_772d_programmer rversion
+
+3. If you want to get the MAC address, go to the driver directory and execute 
+the following command:
+	$sudo ./ax88179b_179a_772e_772d_programmer rmacaddr
+
+4. If you want to write values of a file to the flash, go to the driver 
+directory and execute the following command:
+	$sudo ./ax88179b_179a_772e_772d_programmer wflash [file]
+
+5. If you want to write the eFuse, go to the driver directory and execute 
+the following command:
+	$sudo ./ax88179b_179a_772e_772d_programmer wefuse -m [MAC] -s [SN] -f [File]
+	--led0 [value] --led1 [value] -p [device]
+		-m [MAC]    - MAC address (XX:XX:XX:XX:XX:XX)
+		-s [SN]     - Serial number
+		-f [File]   - eFuse file path
+		--led0 [value]   - value: control_blink (XXXX_XXXX)
+		--led1 [value]   - value: control_blink (XXXX_XXXX)
+		-p [device] - device: "AX88179B" or "AX88179A" or "AX88772E" or "AX88772D" 
+	example: 
+		$sudo ./ax88179b_179a_772e_772d_programmer wefuse -m 00:0E:C6:81:79:01 
+		-s 00000000000001 -f eFuse_Dump.txt
+
+		$sudo ./ax88179b_179a_772e_772d_programmer wefuse -m 00:0E:C6:81:79:01 
+		-s 0000000000179A --led0 8007_0000 --led1 8000_003F -p AX88179A
+
+		$sudo ./ax88179b_179a_772e_772d_programmer wefuse -m 00:0E:C6:87:72:D1
+		-s 0000000000772D -p AX88772D
+
+6. If you want to read the eFuse, go to the driver directory and execute 
+the following command:
+	$sudo ./ax88179b_179a_772e_772d_programmer refuse -f [File]
+
+7. If you want to reload the flash or eFuse to check version or MAC address 
+and so, go to the driver directory and execute the following command:
+	$sudo ./ax88179b_179a_772e_772d_programmer reload
+
+=== AX88179B/179A/772E/772D IEEE Test Tool
+1. If you want to execute IEEE test, go to the driver directory and execute the following command:
+
+	$sudo ./ax88179b_179a_772e_772d_ieee ieeetest speed option
+	    -- AX88179B_179A_772E_772D IEEE Test Tool
+		[speed]    - 1000: 1000Mbps,  100: 100Mbps,  10: 10Mbps
+		[option]   - For 1000Mbps
+				M1: Mode 1
+				M2: Mode 2
+				M3: Mode 3
+				M4: Mode 4
+
+			   - For 100Mbps
+				CA: Channel A
+				CB: Channel B
+
+			   - For 10Mbps
+				RP: Random Pattern
+				FF: Fixed Pattern(FF)
+				MDI: MDI
+
+=== AX88279 Linux Flash Programming Tool
+1. If you want to get help message for specific command, go to the driver 
+directory and execute the following command:
+	$sudo ./ax88279_programmer help [command]
+
+2. If you want to get the version of firmware, go to the driver directory 
+and execute the following command:
+	$sudo ./ax88279_programmer rversion
+
+3. If you want to get the MAC address, go to the driver directory and execute 
+the following command:
+	$sudo ./ax88279_programmer rmacaddr
+
+4. If you want to write values of a file to the flash, go to the driver 
+directory and execute the following command:
+	$sudo ./ax88279_programmer wflash [file]
+
+5. If you want to write the parameter in flash, go to the driver directory and execute 
+the following command:
+	$sudo ./ax88279_programmer wpara -m [MAC] -s [SN] -p [PID] -v [VID] -P [PS] -M [MN] -D [dump]
+	-S [SS] -H [HS] -w [wol] -l [led0 value] -e [led1 value] -d [led2 value]
+       -m [MAC]   	 - MAC address (XX:XX:XX:XX:XX:XX) X:'0'-'F'
+       -s [SN]    	 - Serial Number (Characters must be less than 19 bytes) X:'0'-'F'
+       -p [PID]   	 - Product ID (XX:XX) X:'0'-'F'
+       -v [VID]   	 - Vendor ID (XX:XX) X:'0'-'F'
+       -P [PS]    	 - Product String (Characters must be less than 19 bytes)
+       -M [MN]    	 - Manufacture Name (Characters must be less than 19 bytes)
+       -D [dump]	 - The parameter content currently in flash (dump)
+       -S [SS]    	 - SS bus power (XX) X:0-896 mA
+       -H [HS]    	 - HS bus power (XX) X:0-500 mA
+       -w [wol]    	 - wake on LAN (XXXXXXXX) X:1 or 0 (About setting dwol_enable s5wol_enable pme_enable)
+       -l [led0 value]	 - value: control_blink (XXXX_XXXX)
+       -e [led1 value]	 - value: control_blink (XXXX_XXXX)
+	example: 
+		$sudo ./ax88279_programmer wpara -m 00:0e:c6:81:79:01 -s 00000000000001
+
+		$sudo ./ax88279_programmer wpara -p 17:90 -v 0b:95 -P ax88279 -M asix
+
+		$sudo ./ax88279_programmer wpara -S 400 -H 200 -w 01000001(represent:bit[1]= 1, bit[7]= 1)
+
+		$sudo ./ax88279_programmer wpara -l C113_0004 -e C002_0C4F
+	explain:
+		-w bit[0] -> Disable Remote Wakeup, 
+			bit[1] -> PME enable, 
+			bit[2] -> DWOL Magic Packet, 
+			bit[3] -> DWOL Link Change, 
+			bit[4] -> S5 WOL Magic Packet, 
+			bit[5] -> S5 WOL Link Change,
+			bit[6] -> PME Retry Enable,
+			bit[7] -> PME IND Enable,
+
+6. If you want to view the current parameter content in flash, go to the driver directory and execute 
+the following command, and you can see the file parameter.txt in driver directory:
+	$sudo ./ax88279_programmer wpara -D dump
+
+7. If you want to reload the flash to check version or MAC address 
+and so, go to the driver directory and execute the following command:
+	$sudo ./ax88279_programmer reload
\ No newline at end of file
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/ax88179_178a.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/ax88179_178a.c
@@ -0,0 +1,1242 @@
+// SPDX-License-Identifier: GPL-2.0
+/*******************************************************************************
+ *     Copyright (c) 2022    ASIX Electronic Corporation    All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+#include "ax_main.h"
+#include "ax88179_178a.h"
+
+struct _ax_buikin_setting AX88179_BULKIN_SIZE[] = {
+	{7, 0x70, 0,	0x0C, 0x0f},
+	{7, 0x70, 0,	0x0C, 0x0f},
+	{7, 0x20, 3,	0x16, 0xff},
+	{7, 0xae, 7,	0x18, 0xff},
+};
+const struct ethtool_ops ax88179_ethtool_ops = {
+	.get_drvinfo	= ax_get_drvinfo,
+#if KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE
+	.get_settings	= ax_get_settings,
+	.set_settings	= ax_set_settings,
+#else
+	.get_link_ksettings = ax_get_link_ksettings,
+	.set_link_ksettings = ax_set_link_ksettings,
+#endif
+	.get_link	= ethtool_op_get_link,
+	.get_msglevel	= ax_get_msglevel,
+	.set_msglevel	= ax_set_msglevel,
+	.get_wol	= ax_get_wol,
+	.set_wol	= ax_set_wol,
+	.get_ts_info	= ethtool_op_get_ts_info,
+	.get_strings	= ax_get_strings,
+	.get_sset_count = ax_get_sset_count,
+	.get_ethtool_stats = ax_get_ethtool_stats,
+	.get_regs_len	= ax_get_regs_len,
+	.get_regs	= ax_get_regs,
+};
+
+int ax88179_signature(struct ax_device *axdev, struct _ax_ioctl_command *info)
+{
+	strncpy(info->sig, AX88179_SIGNATURE, strlen(AX88179_SIGNATURE));
+	return 0;
+}
+
+int ax88179_read_eeprom(struct ax_device *axdev, struct _ax_ioctl_command *info)
+{
+	u8 i;
+	u16 tmp;
+	u8 value;
+	unsigned short *buf;
+
+	if (info->buf != NULL) {
+		buf = kmalloc_array(info->size, sizeof(unsigned short),
+				    GFP_KERNEL);
+		if (!buf) {
+#if KERNEL_VERSION(2, 6, 34) <= LINUX_VERSION_CODE
+			netdev_err(axdev->netdev,
+				   "Cannot allocate memory for buffer");
+#endif
+			return -ENOMEM;
+		}
+	} else {
+		netdev_info(axdev->netdev,
+			    "The EEPROM buffer cannot be NULL. \r\n");
+		return -EINVAL;
+	}
+
+	if (info->type == 0) {
+		for (i = 0; i < info->size; i++) {
+
+			if (ax_write_cmd(axdev, AX_ACCESS_MAC,
+					      AX_SROM_ADDR, 1, 1, &i) < 0) {
+				kfree(buf);
+				return -EINVAL;
+			}
+
+			value = EEP_RD;
+			if (ax_write_cmd(axdev, AX_ACCESS_MAC,
+					      AX_SROM_CMD, 1, 1, &value) < 0) {
+				kfree(buf);
+				return -EINVAL;
+			}
+
+			do {
+				ax_read_cmd(axdev, AX_ACCESS_MAC,
+						 AX_SROM_CMD, 1, 1, &value, 0);
+			} while (value & EEP_BUSY);
+
+			if (ax_read_cmd(axdev, AX_ACCESS_MAC,
+					     AX_SROM_DATA_LOW, 2, 2,
+					     &tmp, 1) < 0) {
+				kfree(buf);
+				return -EINVAL;
+			}
+
+			*(buf + i) = be16_to_cpu(tmp);
+
+			if (i == (info->size - 1))
+				break;
+		}
+	} else {
+		for (i = 0; i < info->size; i++) {
+			if (ax_read_cmd(axdev, AX_ACCESS_EFUSE, i,
+					     1, 2, &tmp, 1) < 0) {
+				kfree(buf);
+				return -EINVAL;
+			}
+			*(buf + i) = be16_to_cpu(tmp);
+			if (i == (info->size - 1))
+				break;
+		}
+	}
+
+	if (copy_to_user(info->buf, buf, sizeof(unsigned short) * info->size)) {
+		kfree(buf);
+		return -EFAULT;
+	}
+
+	kfree(buf);
+
+	return 0;
+}
+
+int ax88179_write_eeprom(struct ax_device *axdev,
+			 struct _ax_ioctl_command *info)
+{
+	int i;
+	u16 data, csum = 0;
+	unsigned short *buf;
+
+	if (info->buf != NULL) {
+		buf = kmalloc_array(info->size, sizeof(unsigned short),
+				    GFP_KERNEL);
+		if (!buf) {
+#if KERNEL_VERSION(2, 6, 34) <= LINUX_VERSION_CODE
+			netdev_err(axdev->netdev,
+				   "Cannot allocate memory for buffer");
+#endif
+			return -ENOMEM;
+		}
+		if (copy_from_user(buf, info->buf,
+				   sizeof(unsigned short) * info->size)) {
+			kfree(buf);
+			return -EFAULT;
+		}
+	} else {
+		netdev_err(axdev->netdev,
+			   "The EEPROM buffer cannot be NULL. \r\n");
+		return -EINVAL;
+	}
+
+	if (info->type == 0) {
+		if ((*(buf) >> 8) & 0x01) {
+			netdev_info(axdev->netdev,
+				"Cannot be set to muliticast MAC address, ");
+			netdev_info(axdev->netdev,
+				"bit0 of Node ID-0 cannot be set to 1. \r\n");
+			kfree(buf);
+			return -EINVAL;
+		}
+
+		csum = (*(buf + 3) & 0xff) + ((*(buf + 3) >> 8) & 0xff) +
+		       (*(buf + 4) & 0xff) + ((*(buf + 4) >> 8) & 0xff);
+		csum = 0xff - ((csum >> 8) + (csum & 0xff));
+		data = ((*(buf + 5)) & 0xff) | (csum << 8);
+		*(buf + 5) = data;
+
+		for (i = 0; i < info->size; i++) {
+			data = cpu_to_be16(*(buf + i));
+			if (ax_write_cmd(axdev, AX_ACCESS_EEPROM,
+					      i, 1, 2, &data) < 0) {
+				kfree(buf);
+				return -EINVAL;
+			}
+
+			mdelay(info->delay);
+		}
+	} else if (info->type == 1) {
+		if ((*(buf) >> 8) & 0x01) {
+			netdev_info(axdev->netdev,
+				"Cannot be set to muliticast MAC address, ");
+			netdev_info(axdev->netdev,
+				"bit0 of Node ID-0 cannot be set to 1. \r\n");
+			kfree(buf);
+			return -EINVAL;
+		}
+
+		for (i = 0; i < info->size; i++)
+			csum += (*(buf + i)&0xff) + ((*(buf + i) >> 8)&0xff);
+
+		csum -= ((*(buf + 0x19) >> 8) & 0xff);
+		while (csum > 255)
+			csum = (csum & 0x00FF) + ((csum >> 8) & 0x00FF);
+		csum = 0xFF - csum;
+
+		data = ((*(buf + 0x19)) & 0xff) | (csum << 8);
+		*(buf + 0x19) = data;
+
+		if (ax_write_cmd(axdev, AX_WRITE_EFUSE_EN,
+				      0, 0, 0, NULL) < 0) {
+			kfree(buf);
+			return -EINVAL;
+		}
+
+		mdelay(info->delay);
+
+		for (i = 0; i < info->size; i++) {
+			data = cpu_to_be16(*(buf + i));
+			if (ax_write_cmd(axdev, AX_ACCESS_EFUSE,
+					      i, 1, 2, &data) < 0) {
+				kfree(buf);
+				return -EINVAL;
+			}
+
+			mdelay(info->delay);
+		}
+
+		if (ax_write_cmd(axdev, AX_WRITE_EFUSE_DIS,
+				 0, 0, 0, NULL) < 0) {
+			kfree(buf);
+			return -EINVAL;
+		}
+
+		mdelay(info->delay);
+	} else if (info->type == 2) {
+		if (ax_read_cmd(axdev, AX_ACCESS_EFUSE,
+				0, 1, 2, &data, 1) < 0) {
+			kfree(buf);
+			return -EINVAL;
+		}
+
+		if (data == 0xFFFF)
+			info->type = 0;
+		else
+			info->type = 1;
+	} else {
+		kfree(buf);
+		return -EINVAL;
+	}
+
+	kfree(buf);
+	return 0;
+}
+
+IOCTRL_TABLE ax88179_tbl[] = {
+	ax88179_signature,
+	NULL,//ax_usb_command,
+	ax88179_read_eeprom,
+	ax88179_write_eeprom,
+};
+
+#if KERNEL_VERSION(5, 15, 0) <= LINUX_VERSION_CODE
+int ax88179_siocdevprivate(struct net_device *netdev, struct ifreq *rq,
+			   void __user *udata, int cmd)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	struct _ax_ioctl_command info;
+	struct _ax_ioctl_command *uptr =
+				(struct _ax_ioctl_command *) rq->ifr_data;
+	int ret = 0;
+
+	switch (cmd) {
+	case AX_PRIVATE:
+		if (copy_from_user(&info, uptr,
+				   sizeof(struct _ax_ioctl_command)))
+			return -EFAULT;
+
+		if ((*ax88179_tbl[info.ioctl_cmd])(axdev, &info) < 0) {
+			netdev_info(netdev, "ax88179_tbl, return -EFAULT");
+			return -EFAULT;
+		}
+
+		if (copy_to_user(uptr, &info, sizeof(struct _ax_ioctl_command)))
+			return -EFAULT;
+
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+	}
+
+	return ret;
+}
+
+int ax88179_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+
+	return generic_mii_ioctl(&axdev->mii, if_mii(rq), cmd, NULL);
+}
+#else
+int ax88179_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	struct _ax_ioctl_command info;
+	struct _ax_ioctl_command *uptr =
+				(struct _ax_ioctl_command *) rq->ifr_data;
+
+	switch (cmd) {
+	case AX_PRIVATE:
+		if (copy_from_user(&info, uptr,
+				   sizeof(struct _ax_ioctl_command)))
+			return -EFAULT;
+
+		if ((*ax88179_tbl[info.ioctl_cmd])(axdev, &info) < 0) {
+			netdev_info(netdev, "ax88179_tbl, return -EFAULT");
+			return -EFAULT;
+		}
+
+		if (copy_to_user(uptr, &info, sizeof(struct _ax_ioctl_command)))
+			return -EFAULT;
+
+		break;
+	default:
+		return  generic_mii_ioctl(&axdev->mii, if_mii(rq), cmd, NULL);
+	}
+	return 0;
+}
+#endif
+
+void ax88179_set_multicast(struct net_device *net)
+{
+	struct ax_device *axdev = netdev_priv(net);
+	u8 *m_filter = axdev->m_filter;
+	int mc_count = 0;
+
+	if (!test_bit(AX_ENABLE, &axdev->flags))
+		return;
+
+#if KERNEL_VERSION(2, 6, 35) > LINUX_VERSION_CODE
+	mc_count = net->mc_count;
+#else
+	mc_count = netdev_mc_count(net);
+#endif
+
+	axdev->rxctl = (AX_RX_CTL_START | AX_RX_CTL_AB);
+
+	if (net->flags & IFF_PROMISC) {
+		axdev->rxctl |= AX_RX_CTL_PRO;
+	} else if (net->flags & IFF_ALLMULTI
+		   || mc_count > AX_MAX_MCAST) {
+		axdev->rxctl |= AX_RX_CTL_AMALL;
+	} else if (mc_count == 0) {
+	} else {
+		u32 crc_bits;
+#if KERNEL_VERSION(2, 6, 35) > LINUX_VERSION_CODE
+		struct dev_mc_list *mc_list = net->mc_list;
+		int i = 0;
+
+		memset(m_filter, 0, AX_MCAST_FILTER_SIZE);
+
+		for (i = 0; i < net->mc_count; i++) {
+			crc_bits = ether_crc(ETH_ALEN,
+					     mc_list->dmi_addr) >> 26;
+			*(m_filter + (crc_bits >> 3)) |=
+				1 << (crc_bits & 7);
+			mc_list = mc_list->next;
+		}
+#else
+		struct netdev_hw_addr *ha = NULL;
+
+		memset(m_filter, 0, AX_MCAST_FILTER_SIZE);
+		netdev_for_each_mc_addr(ha, net) {
+			crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26;
+			*(m_filter + (crc_bits >> 3)) |=
+				1 << (crc_bits & 7);
+		}
+#endif
+		ax_write_cmd_async(axdev, AX_ACCESS_MAC,
+					AX_MULTI_FILTER_ARRY,
+					AX_MCAST_FILTER_SIZE,
+					AX_MCAST_FILTER_SIZE, m_filter);
+
+		axdev->rxctl |= AX_RX_CTL_AM;
+	}
+
+	ax_write_cmd_async(axdev, AX_ACCESS_MAC, AX_RX_CTL,
+				2, 2, &axdev->rxctl);
+}
+
+int ax88179_set_mac_addr(struct net_device *netdev, void *p)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	struct sockaddr *addr = p;
+	int ret;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	if (netif_running(netdev))
+		return -EBUSY;
+#if KERNEL_VERSION(5, 16, 0) <= LINUX_VERSION_CODE
+	eth_hw_addr_set(netdev, addr->sa_data);
+#else
+	memcpy(netdev->dev_addr, addr->sa_data, ETH_ALEN);	
+#endif
+
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
+			   ETH_ALEN, addr->sa_data);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+
+}
+
+static int ax88179_check_eeprom(struct ax_device *axdev)
+{
+	u8 i = 0;
+	u8 buf[2];
+	u8 eeprom[20];
+	u16 csum = 0, delay = HZ / 10;
+
+	for (i = 0 ; i < 6; i++) {
+		buf[0] = i;
+		if (ax_write_cmd(axdev, AX_ACCESS_MAC, AX_SROM_ADDR,
+				      1, 1, buf) < 0)
+			return -EINVAL;
+
+		buf[0] = EEP_RD;
+		if (ax_write_cmd(axdev, AX_ACCESS_MAC, AX_SROM_CMD,
+				      1, 1, buf) < 0)
+			return -EINVAL;
+
+		do {
+			ax_read_cmd(axdev, AX_ACCESS_MAC, AX_SROM_CMD,
+					 1, 1, buf, 0);
+
+			if (time_after(jiffies, (jiffies + delay)))
+				return -EINVAL;
+		} while (buf[0] & EEP_BUSY);
+
+		ax_read_cmd(axdev, AX_ACCESS_MAC, AX_SROM_DATA_LOW,
+				 2, 2, &eeprom[i * 2], 0);
+
+		if ((i == 0) && (eeprom[0] == 0xFF))
+			return -EINVAL;
+	}
+
+	csum = eeprom[6] + eeprom[7] + eeprom[8] + eeprom[9];
+	csum = (csum >> 8) + (csum & 0xff);
+
+	if ((csum + eeprom[10]) == 0xff)
+		return 0;
+	else
+		return -EINVAL;
+
+	return 0;
+}
+
+static int ax88179_check_efuse(struct ax_device *axdev, void *ledmode)
+{
+	u8	i = 0;
+	u16	csum = 0;
+	u8	efuse[64];
+
+	if (ax_read_cmd(axdev, AX_ACCESS_EFUSE, 0, 64, 64, efuse, 0) < 0)
+		return -EINVAL;
+
+	if (efuse[0] == 0xFF)
+		return -EINVAL;
+
+	for (i = 0; i < 64; i++)
+		csum = csum + efuse[i];
+
+	while (csum > 255)
+		csum = (csum & 0x00FF) + ((csum >> 8) & 0x00FF);
+
+	if (csum == 0xFF) {
+		memcpy((u8 *)ledmode, &efuse[51], 2);
+		return 0;
+	} else
+		return -EINVAL;
+
+	return 0;
+}
+
+static int ax88179_convert_old_led(struct ax_device *axdev, u8 efuse, void *ledvalue)
+{
+	u8 ledmode = 0;
+	u16 reg16;
+	u16 led = 0;
+
+	/* loaded the old eFuse LED Mode */
+	if (efuse) {
+		if (ax_read_cmd(axdev, AX_ACCESS_EFUSE, 0x18,
+				     1, 2, &reg16, 1) < 0)
+			return -EINVAL;
+		ledmode = (u8)(reg16 & 0xFF);
+	} else { /* loaded the old EEprom LED Mode */
+		if (ax_read_cmd(axdev, AX_ACCESS_EEPROM, 0x3C,
+				     1, 2, &reg16, 1) < 0)
+			return -EINVAL;
+		ledmode = (u8) (reg16 >> 8);
+	}
+	netdev_dbg(axdev->netdev, "Old LED Mode = %02X\n", ledmode);
+
+	switch (ledmode) {
+	case 0xFF:
+		led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 |
+		      LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 |
+		      LED2_LINK_100 | LED2_LINK_1000 | LED_VALID;
+		break;
+	case 0xFE:
+		led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 | LED_VALID;
+		break;
+	case 0xFD:
+		led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 |
+		      LED2_LINK_10 | LED_VALID;
+		break;
+	case 0xFC:
+		led = LED0_ACTIVE | LED1_ACTIVE | LED1_LINK_1000 | LED2_ACTIVE |
+		      LED2_LINK_100 | LED2_LINK_10 | LED_VALID;
+		break;
+	default:
+		led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 |
+		      LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 |
+		      LED2_LINK_100 | LED2_LINK_1000 | LED_VALID;
+		break;
+	}
+
+	memcpy((u8 *)ledvalue, &led, 2);
+
+	return 0;
+}
+
+static void ax88179_Gether_setting(struct ax_device *axdev)
+{
+	u16 reg16;
+
+	reg16 = 0x03;
+	ax_write_cmd(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+			  31, 2, &reg16);
+	reg16 = 0x3246;
+	ax_write_cmd(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+			  25, 2, &reg16);
+	reg16 = 0;
+	ax_write_cmd(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+			  31, 2, &reg16);
+}
+
+static int ax88179_LED_setting(struct ax_device *axdev)
+{
+	u16 ledvalue = 0, delay = HZ / 10;
+	u16 ledact, ledlink;
+	u16 reg16;
+	u8 value;
+
+	ax_read_cmd(axdev, AX_ACCESS_MAC, GENERAL_STATUS, 1, 1, &value, 0);
+
+	if (!(value & AX_SECLD)) {
+		value = AX_GPIO_CTRL_GPIO3EN | AX_GPIO_CTRL_GPIO2EN |
+			AX_GPIO_CTRL_GPIO1EN;
+		if (ax_write_cmd(axdev, AX_ACCESS_MAC, AX_GPIO_CTRL,
+				      1, 1, &value) < 0)
+			return -EINVAL;
+	}
+
+	if (!ax88179_check_eeprom(axdev)) {
+		value = 0x42;
+		if (ax_write_cmd(axdev, AX_ACCESS_MAC, AX_SROM_ADDR,
+				      1, 1, &value) < 0)
+			return -EINVAL;
+
+		value = EEP_RD;
+		if (ax_write_cmd(axdev, AX_ACCESS_MAC, AX_SROM_CMD,
+				      1, 1, &value) < 0)
+			return -EINVAL;
+
+		do {
+			ax_read_cmd(axdev, AX_ACCESS_MAC, AX_SROM_CMD,
+					 1, 1, &value, 0);
+
+			ax_read_cmd(axdev, AX_ACCESS_MAC, AX_SROM_CMD,
+					 1, 1, &value, 0);
+
+			if (time_after(jiffies, (jiffies + delay)))
+				return -EINVAL;
+		} while (value & EEP_BUSY);
+
+		ax_read_cmd(axdev, AX_ACCESS_MAC, AX_SROM_DATA_HIGH,
+				 1, 1, &value, 0);
+		ledvalue = (value << 8);
+		ax_read_cmd(axdev, AX_ACCESS_MAC, AX_SROM_DATA_LOW,
+				 1, 1, &value, 0);
+		ledvalue |= value;
+
+		if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0))
+			ax88179_convert_old_led(axdev, 0, &ledvalue);
+
+	} else if (!ax88179_check_efuse(axdev, &ledvalue)) {
+		if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0))
+			ax88179_convert_old_led(axdev, 0, &ledvalue);
+	} else {
+		ax88179_convert_old_led(axdev, 0, &ledvalue);
+	}
+
+	reg16 = GMII_PHY_PAGE_SELECT_EXT;
+	ax_write_cmd(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+			  GMII_PHY_PAGE_SELECT, 2, &reg16);
+
+	reg16 = 0x2c;
+	ax_write_cmd(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+			  GMII_PHYPAGE, 2, &reg16);
+
+	ax_read_cmd(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+			 GMII_LED_ACTIVE, 2, &ledact, 1);
+
+	ax_read_cmd(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+			 GMII_LED_LINK, 2, &ledlink, 1);
+
+	ledact &= GMII_LED_ACTIVE_MASK;
+	ledlink &= GMII_LED_LINK_MASK;
+
+	if (ledvalue & LED0_ACTIVE)
+		ledact |= GMII_LED0_ACTIVE;
+	if (ledvalue & LED1_ACTIVE)
+		ledact |= GMII_LED1_ACTIVE;
+	if (ledvalue & LED2_ACTIVE)
+		ledact |= GMII_LED2_ACTIVE;
+
+	if (ledvalue & LED0_LINK_10)
+		ledlink |= GMII_LED0_LINK_10;
+	if (ledvalue & LED1_LINK_10)
+		ledlink |= GMII_LED1_LINK_10;
+	if (ledvalue & LED2_LINK_10)
+		ledlink |= GMII_LED2_LINK_10;
+
+	if (ledvalue & LED0_LINK_100)
+		ledlink |= GMII_LED0_LINK_100;
+	if (ledvalue & LED1_LINK_100)
+		ledlink |= GMII_LED1_LINK_100;
+	if (ledvalue & LED2_LINK_100)
+		ledlink |= GMII_LED2_LINK_100;
+
+	if (ledvalue & LED0_LINK_1000)
+		ledlink |= GMII_LED0_LINK_1000;
+	if (ledvalue & LED1_LINK_1000)
+		ledlink |= GMII_LED1_LINK_1000;
+	if (ledvalue & LED2_LINK_1000)
+		ledlink |= GMII_LED2_LINK_1000;
+
+	ax_write_cmd(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+			  GMII_LED_ACTIVE, 2, &ledact);
+
+	ax_write_cmd(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+			  GMII_LED_LINK, 2, &ledlink);
+
+	reg16 = GMII_PHY_PAGE_SELECT_PAGE0;
+	ax_write_cmd(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+			  GMII_PHY_PAGE_SELECT, 2, &reg16);
+
+	/* LED full duplex setting */
+	reg16 = 0;
+	if (ledvalue & LED0_FD)
+		reg16 |= 0x01;
+	else if ((ledvalue & LED0_USB3_MASK) == 0)
+		reg16 |= 0x02;
+
+	if (ledvalue & LED1_FD)
+		reg16 |= 0x04;
+	else if ((ledvalue & LED1_USB3_MASK) == 0)
+		reg16 |= 0x08;
+
+	if (ledvalue & LED2_FD) /* LED2_FD */
+		reg16 |= 0x10;
+	else if ((ledvalue & LED2_USB3_MASK) == 0) /* LED2_USB3 */
+		reg16 |= 0x20;
+
+	ax_write_cmd(axdev, AX_ACCESS_MAC, 0x73, 1, 1, &reg16);
+
+	return 0;
+}
+
+static void ax88179_EEE_setting(struct ax_device *axdev)
+{
+	u16 reg16;
+	/* Disable */
+	reg16 = 0x07;
+	ax_write_cmd(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+				GMII_PHY_MACR, 2, &reg16);
+	reg16 = 0x3c;
+	ax_write_cmd(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+				GMII_PHY_MAADR, 2, &reg16);
+	reg16 = 0x4007;
+	ax_write_cmd(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+				GMII_PHY_MACR, 2, &reg16);
+	reg16 = 0x00;
+	ax_write_cmd(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+				GMII_PHY_MAADR, 2, &reg16);
+}
+
+static int ax88179_AutoDetach(struct ax_device *axdev, int in_pm)
+{
+	u16 reg16;
+	usb_read_function fnr;
+	usb_write_function fnw;
+
+	if (!in_pm) {
+		fnr = ax_read_cmd;
+		fnw = ax_write_cmd;
+	} else {
+		fnr = ax_read_cmd_nopm;
+		fnw = ax_write_cmd_nopm;
+	}
+
+	if (fnr(axdev, AX_ACCESS_EEPROM, 0x43, 1, 2, &reg16, 1) < 0)
+		return 0;
+
+	if ((reg16 == 0xFFFF) || (!(reg16 & 0x0100)))
+		return 0;
+
+	reg16 = 0;
+	fnr(axdev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &reg16, 0);
+	reg16 |= AX_CLK_SELECT_ULR;
+	fnw(axdev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &reg16);
+
+	fnr(axdev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &reg16, 1);
+	reg16 |= AX_PHYPWR_RSTCTL_AUTODETACH;
+	fnw(axdev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &reg16);
+
+	return 0;
+}
+
+static int ax88179_hw_init(struct ax_device *axdev)
+{
+	u32 reg32;
+	u16 reg16;
+	u8 reg8;
+	u8 buf[6] = {0};
+
+	reg32 = 0;
+	ax_write_cmd(axdev, 0x81, 0x310, 0, 4, &reg32);
+
+	reg16 = 0;
+	ax_write_cmd(axdev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &reg16);
+	reg16 = AX_PHYPWR_RSTCTL_IPRL;
+	ax_write_cmd(axdev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &reg16);
+	msleep(200);
+
+	reg8 = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
+	ax_write_cmd(axdev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &reg8);
+	msleep(100);
+
+	ax88179_AutoDetach(axdev, 0);
+
+	memcpy(buf, &AX88179_BULKIN_SIZE[0], 5);
+	ax_write_cmd(axdev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, buf);
+
+	reg8 = 0x34;
+	ax_write_cmd(axdev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW,
+			  1, 1, &reg8);
+
+	reg8 = 0x52;
+	ax_write_cmd(axdev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
+			  1, 1, &reg8);
+
+	ax_write_cmd(axdev, 0x91, 0, 0, 0, NULL);
+
+	reg8 = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
+	       AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
+	ax_write_cmd(axdev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &reg8);
+
+	reg8 = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP |
+	       AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
+	ax_write_cmd(axdev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &reg8);
+
+	reg8 = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL |
+	       AX_MONITOR_MODE_RWLC | AX_MONITOR_MODE_RWMP;
+	ax_write_cmd(axdev, AX_ACCESS_MAC, AX_MONITOR_MODE, 1, 1, &reg8);
+
+	ax88179_LED_setting(axdev);
+
+	ax88179_EEE_setting(axdev);
+
+	ax88179_Gether_setting(axdev);
+
+	ax_set_tx_qlen(axdev);
+
+	mii_nway_restart(&axdev->mii);
+
+	return 0;
+
+}
+
+static int ax88179_bind(struct ax_device *axdev)
+{
+	struct net_device *netdev = axdev->netdev;
+
+	PRINT_VERSION(axdev, AX_DRIVER_STRING_179_178A);
+
+	netdev->features    |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+			       NETIF_F_SG | NETIF_F_TSO | NETIF_F_FRAGLIST;
+	netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+			       NETIF_F_SG | NETIF_F_TSO | NETIF_F_FRAGLIST;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
+	netdev->max_mtu = (9 * 1024);
+#else
+	axdev->max_mtu = (9 * 1024);
+#endif
+	axdev->tx_casecade_size = TX_CASECADES_SIZE;
+	axdev->gso_max_size = AX_GSO_DEFAULT_SIZE;
+	axdev->mii.supports_gmii = 1;
+	axdev->mii.dev = netdev;
+	axdev->mii.mdio_read = ax_mdio_read;
+	axdev->mii.mdio_write = ax_mdio_write;
+	axdev->mii.phy_id_mask = 0xff;
+	axdev->mii.reg_num_mask = 0xff;
+	axdev->mii.phy_id = AX88179_PHY_ID;
+	axdev->mii.force_media = 0;
+	axdev->mii.advertising = ADVERTISE_10HALF | ADVERTISE_10FULL |
+				 ADVERTISE_100HALF | ADVERTISE_100FULL;
+#if KERNEL_VERSION(5, 19, 0) <= LINUX_VERSION_CODE
+	netif_set_tso_max_size(netdev, axdev->gso_max_size);
+#else
+	netif_set_gso_max_size(netdev, axdev->gso_max_size);
+#endif
+
+	axdev->bin_setting.custom = 1;
+	axdev->tx_align_len = 4;
+
+	netdev->ethtool_ops = &ax88179_ethtool_ops;
+	axdev->netdev->netdev_ops = &ax88179_netdev_ops;
+
+	return 0;
+}
+
+static void ax88179_unbind(struct ax_device *axdev)
+{
+
+}
+
+static int ax88179_stop(struct ax_device *axdev)
+{
+	u16 reg16;
+
+	reg16 = AX_RX_CTL_STOP;
+	ax_write_cmd(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, &reg16);
+
+	reg16 = 0;
+	ax_write_cmd(axdev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &reg16);
+
+	reg16 = AX_PHYPWR_RSTCTL_BZ;
+	ax_write_cmd(axdev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &reg16);
+	msleep(200);
+
+	return 0;
+}
+
+static int ax88179_link_reset(struct ax_device *axdev)
+{
+	u8 reg8[5], link_sts;
+	u16 mode, reg16, delay;
+	u32 reg32;
+
+	mode = AX_MEDIUM_TXFLOW_CTRLEN | AX_MEDIUM_RXFLOW_CTRLEN;
+
+	ax_read_cmd_nopm(axdev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS,
+			 1, 1, &link_sts, 0);
+	ax_read_cmd_nopm(axdev, AX_ACCESS_PHY, AX88179_PHY_ID,
+			 GMII_PHY_PHYSR, 2, &reg16, 1);
+
+	if (!(reg16 & GMII_PHY_PHYSR_LINK)) {
+		return -1;
+	} else if (GMII_PHY_PHYSR_GIGA == (reg16 & GMII_PHY_PHYSR_SMASK)) {
+		mode |= AX_MEDIUM_GIGAMODE;
+		if (axdev->netdev->mtu > 1500)
+			mode |= AX_MEDIUM_JUMBO_EN;
+
+		if (link_sts & AX_USB_SS)
+			memcpy(reg8, &AX88179_BULKIN_SIZE[0], 5);
+		else if (link_sts & AX_USB_HS)
+			memcpy(reg8, &AX88179_BULKIN_SIZE[1], 5);
+		else
+			memcpy(reg8, &AX88179_BULKIN_SIZE[3], 5);
+	} else if (GMII_PHY_PHYSR_100 == (reg16 & GMII_PHY_PHYSR_SMASK)) {
+		mode |= AX_MEDIUM_PS;
+		if (link_sts & (AX_USB_SS | AX_USB_HS))
+			memcpy(reg8, &AX88179_BULKIN_SIZE[2], 5);
+		else
+			memcpy(reg8, &AX88179_BULKIN_SIZE[3], 5);
+	} else {
+		memcpy(reg8, &AX88179_BULKIN_SIZE[3], 5);
+	}
+
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, reg8);
+
+	if (reg16 & GMII_PHY_PHYSR_FULL)
+		mode |= AX_MEDIUM_FULL_DUPLEX;
+
+	ax_read_cmd_nopm(axdev, 0x81, 0x8c, 0, 4, &reg32, 1);
+	delay = HZ / 2;
+	if (reg32 & 0x40000000) {
+		unsigned long jtimeout;
+		u16 temp16 = 0;
+
+		ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL,
+				  2, 2, &temp16);
+		ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+				  2, 2, &mode);
+
+		jtimeout = jiffies + delay;
+		while (time_before(jiffies, jtimeout)) {
+			ax_read_cmd_nopm(axdev, 0x81, 0x8c, 0, 4, &reg32, 1);
+
+			if (!(reg32 & 0x40000000))
+				break;
+
+			reg32 = 0x80000000;
+			ax_write_cmd(axdev, 0x81, 0x8c, 0, 4, &reg32);
+		}
+
+		temp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_START |
+			 AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
+		ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL,
+				  2, 2, &temp16);
+	}
+
+	axdev->rxctl |= AX_RX_CTL_DROPCRCERR | AX_RX_CTL_START | AX_RX_CTL_AB;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL,
+			  2, 2, &axdev->rxctl);
+
+	mode |= AX_MEDIUM_RECEIVE_EN;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+			  2, 2, &mode);
+
+	return 0;
+}
+
+
+static int ax88179_tx_fixup(struct ax_device *axdev, struct tx_desc *desc)
+{
+	struct sk_buff_head skb_head, *tx_queue = &axdev->tx_queue[0];
+	struct net_device_stats *stats = &axdev->netdev->stats;
+	int remain, ret;
+	u8 *tx_data;
+
+	__skb_queue_head_init(&skb_head);
+	spin_lock(&tx_queue->lock);
+	skb_queue_splice_init(tx_queue, &skb_head);
+	spin_unlock(&tx_queue->lock);
+
+	tx_data = desc->head;
+	desc->skb_num = 0;
+	desc->skb_len = 0;
+	remain = axdev->tx_casecade_size;
+
+	while (remain >= ETH_ZLEN + 8) {
+		struct sk_buff *skb;
+		u32 *tx_hdr1, *tx_hdr2;
+
+		skb = __skb_dequeue(&skb_head);
+		if (!skb)
+			break;
+
+		if ((skb->len + AX_TX_HEADER_LEN) > remain &&
+		    (skb_shinfo(skb)->gso_size == 0)) {
+			__skb_queue_head(&skb_head, skb);
+			break;
+		}
+
+		memset(tx_data, 0, AX_TX_HEADER_LEN);
+		tx_hdr1 = (u32 *)tx_data;
+		tx_hdr2 = tx_hdr1 + 1;
+		*tx_hdr1 = skb->len;
+		*tx_hdr2 = skb_shinfo(skb)->gso_size;
+		cpu_to_le32s(tx_hdr1);
+		cpu_to_le32s(tx_hdr2);
+		tx_data += 8;
+
+		if (skb_copy_bits(skb, 0, tx_data, skb->len) < 0) {
+			stats->tx_dropped++;
+			dev_kfree_skb_any(skb);
+			continue;
+		}
+
+		tx_data += skb->len;
+		desc->skb_len += skb->len;
+		desc->skb_num += skb_shinfo(skb)->gso_segs ?: 1;
+		dev_kfree_skb_any(skb);
+
+		tx_data = __tx_buf_align(tx_data, axdev->tx_align_len);
+		if (*tx_hdr2 > 0)
+			break;
+		remain = axdev->tx_casecade_size -
+			 (int)((void *)tx_data - desc->head);
+	}
+
+	if (!skb_queue_empty(&skb_head)) {
+		spin_lock(&tx_queue->lock);
+		skb_queue_splice(&skb_head, tx_queue);
+		spin_unlock(&tx_queue->lock);
+	}
+
+	netif_tx_lock(axdev->netdev);
+
+	if (netif_queue_stopped(axdev->netdev) &&
+	    skb_queue_len(tx_queue) < axdev->tx_qlen) {
+		netif_wake_queue(axdev->netdev);
+	}
+
+	netif_tx_unlock(axdev->netdev);
+
+	ret = usb_autopm_get_interface_async(axdev->intf);
+	if (ret < 0)
+		goto out_tx_fill;
+
+	usb_fill_bulk_urb(desc->urb, axdev->udev,
+			  usb_sndbulkpipe(axdev->udev, 3),
+			  desc->head, (int)(tx_data - (u8 *)desc->head),
+			  (usb_complete_t)ax_write_bulk_callback, desc);
+
+	ret = usb_submit_urb(desc->urb, GFP_ATOMIC);
+	if (ret < 0)
+		usb_autopm_put_interface_async(axdev->intf);
+
+out_tx_fill:
+	return ret;
+}
+
+static void ax88179_rx_checksum(struct sk_buff *skb, u32 *pkt_hdr)
+{
+	skb->ip_summed = CHECKSUM_NONE;
+
+	if ((*pkt_hdr & AX_RXHDR_L3CSUM_ERR) ||
+	    (*pkt_hdr & AX_RXHDR_L4CSUM_ERR))
+		return;
+
+	if (((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_TCP) ||
+	    ((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_UDP))
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+}
+
+static void ax88179_rx_fixup(struct ax_device *axdev, struct rx_desc *desc,
+			     int *work_done, int budget)
+{
+	u8 *rx_data;
+	u32 const actual_length = desc->urb->actual_length;
+	u32 rx_hdr = 0, pkt_hdr = 0, pkt_hdr_curr = 0, hdr_off = 0;
+	u32 aa = 0;
+	int pkt_cnt = 0;
+	struct net_device *netdev = axdev->netdev;
+	struct net_device_stats *stats = ax_get_stats(netdev);
+
+	memcpy(&rx_hdr, (((u8 *)desc->head) + actual_length - 4),
+	       sizeof(rx_hdr));
+	le32_to_cpus(&rx_hdr);
+
+	pkt_cnt = rx_hdr & 0xFF;
+	pkt_hdr_curr = hdr_off = rx_hdr >> 16;
+
+	aa = (actual_length - (((pkt_cnt + 2) & 0xFE) * 4));
+	if ((aa != hdr_off) ||
+	    (hdr_off >= desc->urb->actual_length) ||
+	    (pkt_cnt == 0)) {
+		desc->urb->actual_length = 0;
+		stats->rx_length_errors++;
+		return;
+	}
+
+	rx_data = desc->head;
+	while (pkt_cnt--) {
+		u32 pkt_len;
+		struct sk_buff *skb;
+
+		memcpy(&pkt_hdr, (((u8 *)desc->head) + pkt_hdr_curr),
+		       sizeof(pkt_hdr));
+		pkt_hdr_curr += 4;
+
+		le32_to_cpus(&pkt_hdr);
+		pkt_len = (pkt_hdr >> 16) & 0x1FFF;
+
+		if (pkt_hdr & AX_RXHDR_CRC_ERR) {
+			stats->rx_crc_errors++;
+			goto find_next_rx;
+		}
+		if (pkt_hdr & AX_RXHDR_DROP_ERR) {
+			stats->rx_dropped++;
+			goto find_next_rx;
+		}
+
+#ifdef ENABLE_RX_TASKLET
+		skb = netdev_alloc_skb(netdev, pkt_len);
+#else
+		skb = napi_alloc_skb(&axdev->napi, pkt_len);
+#endif
+		if (!skb) {
+			stats->rx_dropped++;
+			goto find_next_rx;
+		}
+
+		memcpy(skb->data, rx_data, pkt_len);
+		skb_put(skb, pkt_len);
+
+		ax88179_rx_checksum(skb, &pkt_hdr);
+
+		skb->protocol = eth_type_trans(skb, netdev);
+
+		if (*work_done < budget) {
+#ifdef ENABLE_RX_TASKLET
+			netif_receive_skb(skb);
+#else
+			napi_gro_receive(&axdev->napi, skb);
+#endif
+			*work_done += 1;
+			stats->rx_packets++;
+			stats->rx_bytes += pkt_len;
+		} else {
+			__skb_queue_tail(&axdev->rx_queue, skb);
+		}
+find_next_rx:
+		rx_data += (pkt_len + 7) & 0xFFF8;
+	}
+}
+
+static int ax88179_system_suspend(struct ax_device *axdev)
+{
+	u16 reg16;
+
+	ax_read_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+			 2, 2, &reg16, 1);
+	reg16 &= ~AX_MEDIUM_RECEIVE_EN;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+			  2, 2, &reg16);
+
+	ax_read_cmd_nopm(axdev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+			 2, 2, &reg16, 1);
+	reg16 |= AX_PHYPWR_RSTCTL_IPRL;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL,
+			  2, 2, &reg16);
+
+	reg16 = AX_RX_CTL_STOP;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &reg16);
+
+	return 0;
+}
+
+static int ax88179_system_resume(struct ax_device *axdev)
+{
+	u16 reg16;
+	u8 reg8;
+
+	reg16 = 0;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &reg16);
+#if KERNEL_VERSION(2, 6, 36) <= LINUX_VERSION_CODE
+	usleep_range(1000, 2000);
+#else
+	msleep(20);
+#endif
+	reg16 = AX_PHYPWR_RSTCTL_IPRL;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &reg16);
+	msleep(200);
+
+	ax88179_AutoDetach(axdev, 1);
+
+	ax_read_cmd_nopm(axdev, AX_ACCESS_MAC,  AX_CLK_SELECT, 1, 1, &reg8, 0);
+	reg8 |= AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &reg8);
+	msleep(100);
+
+	reg16 = AX_RX_CTL_START | AX_RX_CTL_AP |
+		AX_RX_CTL_AMALL | AX_RX_CTL_AB;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &reg16);
+
+	return 0;
+}
+
+static int ax88179_runtime_suspend(struct ax_device *axdev)
+{
+       u16 reg16;
+#if 0
+       ax_read_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MONITOR_MODE, 1, 1, &reg16,
+                        1);
+       reg16 &= ~AX_MONITOR_MODE_RWLC;
+       ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MONITOR_MODE, 1, 1, &reg16);
+#endif
+       ax_read_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2,
+                        &reg16, 1);
+       reg16 &= ~AX_MEDIUM_RECEIVE_EN;
+       ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2,
+                         &reg16);
+       ax_read_cmd_nopm(axdev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &reg16,
+                        1);
+       reg16 |= AX_PHYPWR_RSTCTL_IPRL;
+       ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &reg16);
+       reg16 = AX_RX_CTL_STOP;
+       ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &reg16);
+       return 0;
+}
+
+static int ax88179_runtime_resume(struct ax_device *axdev)
+{
+       u16 reg16;
+       u8 reg8;
+       reg16 = 0;
+       ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &reg16);
+#if KERNEL_VERSION(2, 6, 36) <= LINUX_VERSION_CODE
+       usleep_range(1000, 2000);
+#else
+       msleep(20);
+#endif
+       reg16 = AX_PHYPWR_RSTCTL_IPRL;
+       ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &reg16);
+       msleep(200);
+       ax_read_cmd_nopm(axdev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &reg8, 0);
+       reg8 |= AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS;
+       ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &reg8);
+       msleep(100);
+       ax_read_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2,
+                        &reg16, 1);
+       reg16 |= AX_MEDIUM_RECEIVE_EN;
+       ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2,
+                         &reg16);
+       reg16 = AX_RX_CTL_START | AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB;
+       ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &reg16);
+       return 0;
+}
+
+const struct driver_info ax88179_info = {
+	.bind = ax88179_bind,
+	.unbind = ax88179_unbind,
+	.hw_init = ax88179_hw_init,
+	.stop = ax88179_stop,
+	.link_reset = ax88179_link_reset,
+	.rx_fixup = ax88179_rx_fixup,
+	.tx_fixup = ax88179_tx_fixup,
+	.system_suspend = ax88179_system_suspend,
+	.system_resume = ax88179_system_resume,
+	.runtime_suspend = ax88179_runtime_suspend,
+    .runtime_resume = ax88179_runtime_resume,
+	.napi_weight = AX88179_NAPI_WEIGHT,
+	.buf_rx_size = AX88179_BUF_RX_SIZE,
+};
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/ax88179_178a.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/ax88179_178a.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*******************************************************************************
+ *     Copyright (c) 2022    ASIX Electronic Corporation    All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+#ifndef __ASIX_AX88179_178A_H
+#define __ASIX_AX88179_178A_H
+
+#define AX88179_NAPI_WEIGHT		64
+#define AX88179_BUF_RX_SIZE		(48 * 1024)
+#define AX88179_PHY_ID			0x03
+
+extern const struct net_device_ops ax88179_netdev_ops;
+#if KERNEL_VERSION(5, 15, 0) <= LINUX_VERSION_CODE
+int ax88179_siocdevprivate(struct net_device *netdev, struct ifreq *rq,
+			   void __user *udata, int cmd);
+#endif
+int ax88179_ioctl(struct net_device *net, struct ifreq *rq, int cmd);
+
+int ax88179_set_mac_addr(struct net_device *net, void *p);
+void ax88179_set_multicast(struct net_device *net);
+
+extern const struct driver_info ax88179_info;
+#endif
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/ax88179_programmer.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/ax88179_programmer.c
@@ -0,0 +1,629 @@
+// SPDX-License-Identifier: GPL-2.0
+/*******************************************************************************
+ *     Copyright (c) 2022    ASIX Electronic Corporation    All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#if NET_INTERFACE == INTERFACE_SCAN
+#include <ifaddrs.h>
+#endif
+#include "ax_ioctl.h"
+
+#define AX88179_IOCTL_VERSION \
+"AX88179/AX88178A Linux EEPROM/eFuse Programming Tool v1.5.0"
+
+const char help_str1[] =
+"./ax88179_programmer help [command]\n"
+"    -- command description\n";
+const char help_str2[] =
+"        [command] - Display usage of specified command\n";
+
+const char readeeprom_str1[] =
+"./ax88179_programmer reeprom [type] [file] [size]\n"
+"    -- AX88179_178A EEPROM/eFuse read tool\n";
+const char readeeprom_str2[] =
+"        [type]    - 0: EEPROM,  1: eFuse\n"
+"        [file]    - Output file\n"
+"        [size]    - EEPROM/eFuse SIZE (bytes). EEPROM maximum 512 bytes,\n"
+"                    eFuse maximum 64 bytes.\n";
+
+const char writeeeprom_str1[] =
+"./ax88179_programmer weeeprom [type] [file] [size]\n"
+"    -- AX88179_178A EEPROM/eFuse write tool\n";
+const char writeeeprom_str2[] =
+"        [type]    - 0: EEPROM,  1: eFuse\n"
+"        [file]    - Input file\n"
+"        [size]    - EEPROM/eFuse SIZE (bytes). EEPROM size 12-512 bytes,\n"
+"                    eFuse maximum 64 bytes.\n";
+
+const char chgmac_str1[] =
+"./ax88179_programmer chgmac [type] [mac_addr] [size]\n"
+"    -- AX88179_178A EEPROM/eFuse write tool (specify MAC address)\n";
+const char chgmac_str2[] =
+"        [type]    - 0: EEPROM,  1: eFuse\n"
+"        [mac_addr]- MAC address (xx:xx:xx:xx:xx:xx)\n"
+"        [size]    - EEPROM/eFuse SIZE (bytes). EEPROM size 12-512 bytes,\n"
+"                    eFuse maximum 64 bytes.\n";
+
+static int help_func(struct ax_command_info *info);
+static int readeeprom_func(struct ax_command_info *info);
+static int writeeeprom_func(struct ax_command_info *info);
+static int chgmac_func(struct ax_command_info *info);
+struct _command_list ax88179_cmd_list[] = {
+	{
+		"help",
+		AX_SIGNATURE,
+		help_func,
+		help_str1,
+		help_str2
+	},
+	{
+		"reeprom",
+		AX88179_READ_EEPROM,
+		readeeprom_func,
+		readeeprom_str1,
+		readeeprom_str2
+	},
+	{
+		"weeprom",
+		AX88179_WRITE_EEPROM,
+		writeeeprom_func,
+		writeeeprom_str1,
+		writeeeprom_str2
+	},
+	{
+		"chgmac",
+		AX88179_WRITE_EEPROM,
+		chgmac_func,
+		chgmac_str1,
+		chgmac_str2
+	},
+	{NULL},
+};
+
+static void show_usage(void)
+{
+	int i;
+
+	printf("Usage:\n");
+	for (i = 0; ax88179_cmd_list[i].cmd != NULL; i++)
+		printf("%s\n", ax88179_cmd_list[i].help_ins);
+}
+
+static unsigned long STR_TO_U32(const char *cp, char **endp, unsigned int base)
+{
+	unsigned long result = 0, value;
+
+	if (*cp == '0') {
+		cp++;
+		if ((*cp == 'x') && isxdigit(cp[1])) {
+			base = 16;
+			cp++;
+		}
+		if (!base)
+			base = 8;
+	}
+	if (!base)
+		base = 10;
+
+	while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
+	    ? toupper(*cp) : *cp)-'A'+10) < base) {
+		result = result*base + value;
+		cp++;
+	}
+	if (endp)
+		*endp = (char *)cp;
+
+	return result;
+}
+
+static int help_func(struct ax_command_info *info)
+{
+	int i;
+
+	if (info->argv[2] == NULL) {
+		for (i = 0; ax88179_cmd_list[i].cmd != NULL; i++) {
+			printf("%s%s\n", ax88179_cmd_list[i].help_ins,
+			       ax88179_cmd_list[i].help_desc);
+		}
+	}
+
+	for (i = 0; ax88179_cmd_list[i].cmd != NULL; i++) {
+		if (strncmp(info->argv[1], ax88179_cmd_list[i].cmd,
+			    strlen(ax88179_cmd_list[i].cmd)) == 0) {
+			printf("%s%s\n", ax88179_cmd_list[i].help_ins,
+			       ax88179_cmd_list[i].help_desc);
+			return -FAIL_INVALID_PARAMETER;
+		}
+	}
+
+	return SUCCESS;
+}
+
+static int compare_file(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	unsigned short *rout_buf;
+	unsigned short *ori_buf;
+	struct _ax_ioctl_command *ioctl_cmd =
+				(struct _ax_ioctl_command *)(ifr->ifr_data);
+	int i;
+
+	rout_buf = malloc(sizeof(unsigned short) * ioctl_cmd->size);
+
+	ori_buf = ioctl_cmd->buf;
+
+	ioctl_cmd->ioctl_cmd = AX88179_READ_EEPROM;
+	ioctl_cmd->buf = rout_buf;
+
+	if (ioctl(info->inet_sock, AX_PRIVATE, ifr) < 0) {
+		perror("ioctl");
+		return -1;
+	}
+
+	for (i = 0; i < ioctl_cmd->size; i++) {
+		if (*(ioctl_cmd->buf + i) != *(ori_buf + i)) {
+			ioctl_cmd->buf = ori_buf;
+			free(rout_buf);
+			return -1;
+		}
+	}
+
+	ioctl_cmd->buf = ori_buf;
+	free(rout_buf);
+	return 0;
+}
+
+static int readeeprom_func(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	unsigned short *buf;
+	unsigned short wLen;
+	char str_buf[50];
+	unsigned char type;
+	FILE *pFile;
+	int i;
+
+	if (info->argc != 5) {
+		for (i = 0; ax88179_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88179_cmd_list[i].cmd,
+				    strlen(ax88179_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88179_cmd_list[i].help_ins,
+				       ax88179_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	type = STR_TO_U32(info->argv[2], NULL, 0);
+	wLen = STR_TO_U32(info->argv[4], NULL, 0) / 2;
+
+	if ((type > 1) ||
+	    ((type == 0) && (wLen > 256)) ||
+	    ((type == 1) && (wLen > 32))) {
+		for (i = 0; ax88179_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88179_cmd_list[i].cmd,
+				    strlen(ax88179_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88179_cmd_list[i].help_ins,
+				       ax88179_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	pFile = fopen(info->argv[3], "w");
+	if (pFile == NULL) {
+		printf("fail to open %s file\n", info->argv[3]);
+		return -FAIL_LOAD_FILE;
+	}
+
+	buf = (unsigned short *)malloc(sizeof(unsigned short) * wLen);
+
+	ioctl_cmd.ioctl_cmd = info->ioctl_cmd;
+	ioctl_cmd.size = wLen;
+	ioctl_cmd.buf = buf;
+	ioctl_cmd.type = type;
+	ioctl_cmd.delay = 0;
+
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	if (ioctl(info->inet_sock, AX_PRIVATE, ifr) < 0) {
+		perror("ioctl");
+		free(buf);
+		fclose(pFile);
+		return -FAIL_IOCTL;
+	}
+
+	for (i = 0; i < wLen / 8; i++) {
+		int j = 8 * i;
+
+		snprintf(str_buf, 50,
+			 "%04x %04x %04x %04x %04x %04x %04x %04x\n",
+			 *(buf + j + 0), *(buf + j + 1),
+			 *(buf + j + 2), *(buf + j + 3),
+			 *(buf + j + 4), *(buf + j + 5),
+			 *(buf + j + 6), *(buf + j + 7));
+
+		fputs(str_buf, pFile);
+	}
+
+	free(buf);
+	fclose(pFile);
+	printf("read completely\n");
+
+	return SUCCESS;
+}
+
+static int writeeeprom_func(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	int i;
+	unsigned short *buf;
+	unsigned short wLen;
+	char c[2] = {'\0'};
+	FILE *pFile;
+	unsigned char retried = 0;
+	unsigned char type;
+
+	if (info->argc != 5) {
+		for (i = 0; ax88179_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88179_cmd_list[i].cmd,
+				    strlen(ax88179_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88179_cmd_list[i].help_ins,
+				       ax88179_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	type = STR_TO_U32(info->argv[2], NULL, 0);
+	wLen = STR_TO_U32(info->argv[4], NULL, 0) / 2;
+
+	if ((type > 1) ||
+	    ((type == 0) && (wLen > 256)) ||
+	    ((type == 0) && (wLen < 6)) ||
+	    ((type == 1) && (wLen > 32))) {
+		for (i = 0; ax88179_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88179_cmd_list[i].cmd,
+				    strlen(ax88179_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88179_cmd_list[i].help_ins,
+				       ax88179_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	pFile = fopen(info->argv[3], "r");
+	if (pFile == NULL) {
+		printf("fail to open %s file\n", info->argv[3]);
+		return -FAIL_LOAD_FILE;
+	}
+
+	buf = (unsigned short *)malloc(sizeof(unsigned short) * wLen);
+
+	for (i = 0; i < wLen / 8; i++) {
+		int j = 8 * i;
+
+		fscanf(pFile, "%04X %04X %04X %04X %04X %04X %04X %04X%c",
+				(unsigned int *)&buf[j + 0],
+				(unsigned int *)&buf[j + 1],
+				(unsigned int *)&buf[j + 2],
+				(unsigned int *)&buf[j + 3],
+				(unsigned int *)&buf[j + 4],
+				(unsigned int *)&buf[j + 5],
+				(unsigned int *)&buf[j + 6],
+				(unsigned int *)&buf[j + 7], c);
+	}
+
+	ioctl_cmd.ioctl_cmd = info->ioctl_cmd;
+	ioctl_cmd.size = wLen;
+	ioctl_cmd.buf = buf;
+	ioctl_cmd.delay = 5;
+
+	if (type) {
+		ioctl_cmd.type = 2;
+		ifr->ifr_data = (caddr_t)&ioctl_cmd;
+		if (ioctl(info->inet_sock, AX_PRIVATE, ifr) < 0) {
+			free(buf);
+			fclose(pFile);
+			perror("ioctl");
+			return -FAIL_IOCTL;
+		}
+		if (ioctl_cmd.type) {
+			printf("EFuse has been programed.\n");
+			return -FAIL_INVALID_PARAMETER;
+		}
+	}
+
+	ioctl_cmd.type = type;
+io:
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	if (ioctl(info->inet_sock, AX_PRIVATE, ifr) < 0) {
+		free(buf);
+		fclose(pFile);
+		perror("ioctl");
+		return -FAIL_IOCTL;
+	}
+	if (compare_file(info) && retried < 3) {
+		ioctl_cmd.delay += 5;
+		ioctl_cmd.ioctl_cmd = info->ioctl_cmd;
+		retried++;
+		goto io;
+	}
+	if (retried == 3) {
+		printf("Failure to write\n");
+		free(buf);
+		fclose(pFile);
+		return -FAIL_GENERIAL_ERROR;
+	}
+
+	printf("Write completely\n");
+	free(buf);
+	fclose(pFile);
+
+	return SUCCESS;
+}
+
+static int chgmac_func(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	int i;
+	unsigned short *buf;
+	unsigned short wLen;
+	unsigned char retried = 0;
+	unsigned int MAC[6] = {0};
+	int ret = 0;
+	unsigned char type;
+	char c[2] = {'\0'};
+	FILE *pFile;
+
+	if (info->argc != 5) {
+		for (i = 0; ax88179_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88179_cmd_list[i].cmd,
+				    strlen(ax88179_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88179_cmd_list[i].help_ins,
+				       ax88179_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	type = STR_TO_U32(info->argv[2], NULL, 0);
+	wLen = STR_TO_U32(info->argv[4], NULL, 0) / 2;
+
+	if ((type > 1) ||
+	    ((type == 0) && (wLen > 256)) ||
+	    ((type == 0) && (wLen < 6)) ||
+	    ((type == 1) && (wLen > 32))) {
+		for (i = 0; ax88179_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88179_cmd_list[i].cmd,
+				    strlen(ax88179_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88179_cmd_list[i].help_ins,
+				       ax88179_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	buf = (unsigned short *)malloc(sizeof(unsigned short) * wLen);
+
+	if (type) {
+		pFile = fopen("efuse", "r");
+		if (pFile == NULL) {
+			printf("fail to open 'efuse' file\n");
+			free(buf);
+			return -FAIL_LOAD_FILE;
+		}
+
+		for (i = 0; i < wLen / 8; i++) {
+			int j = 8 * i;
+
+			fscanf(pFile, "%04X %04X %04X %04X %04X %04X %04X %04X%c",
+					(unsigned int *)&buf[j + 0],
+					(unsigned int *)&buf[j + 1],
+					(unsigned int *)&buf[j + 2],
+					(unsigned int *)&buf[j + 3],
+					(unsigned int *)&buf[j + 4],
+					(unsigned int *)&buf[j + 5],
+					(unsigned int *)&buf[j + 6],
+					(unsigned int *)&buf[j + 7], c);
+		}
+	} else {
+		ioctl_cmd.ioctl_cmd = AX88179_READ_EEPROM;
+		ioctl_cmd.size = wLen;
+		ioctl_cmd.buf = buf;
+		ioctl_cmd.delay = 0;
+		ioctl_cmd.type = type;
+
+		ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+		if (ioctl(info->inet_sock, AX_PRIVATE, ifr) < 0) {
+			perror("ioctl");
+			free(buf);
+			return -FAIL_IOCTL;
+		}
+	}
+
+	ret = sscanf(info->argv[3], "%02X:%02X:%02X:%02X:%02X:%02X",
+					(unsigned int *)&MAC[0],
+					(unsigned int *)&MAC[1],
+					(unsigned int *)&MAC[2],
+					(unsigned int *)&MAC[3],
+					(unsigned int *)&MAC[4],
+					(unsigned int *)&MAC[5]);
+	if (ret != 6) {
+		printf("Invalid MAC address\n");
+		return -FAIL_INVALID_PARAMETER;
+	}
+
+	*(((char *)buf) + 0) = (unsigned char)MAC[1];
+	*(((char *)buf) + 1) = (unsigned char)MAC[0];
+	*(((char *)buf) + 2) = (unsigned char)MAC[3];
+	*(((char *)buf) + 3) = (unsigned char)MAC[2];
+	*(((char *)buf) + 4) = (unsigned char)MAC[5];
+	*(((char *)buf) + 5) = (unsigned char)MAC[4];
+
+	ioctl_cmd.ioctl_cmd = info->ioctl_cmd;
+	ioctl_cmd.size = wLen;
+	ioctl_cmd.buf = buf;
+	ioctl_cmd.delay = 5;
+	ioctl_cmd.type = type;
+
+	if (type) {
+		ioctl_cmd.type = 2;
+		ifr->ifr_data = (caddr_t)&ioctl_cmd;
+		if (ioctl(info->inet_sock, AX_PRIVATE, ifr) < 0) {
+			free(buf);
+			perror("ioctl");
+			return -FAIL_IOCTL;
+		} else if (ioctl_cmd.type) {
+			printf("EFuse has been programed.\n");
+		}
+	}
+io:
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+	if (ioctl(info->inet_sock, AX_PRIVATE, ifr) < 0) {
+		perror("ioctl");
+		free(buf);
+		return -FAIL_IOCTL;
+	}
+	if (compare_file(info) && retried < 3) {
+		ioctl_cmd.delay += 5;
+		ioctl_cmd.ioctl_cmd = info->ioctl_cmd;
+		retried++;
+		goto io;
+	}
+	if (retried == 3) {
+		printf("Failure to write\n");
+		free(buf);
+		return -FAIL_GENERIAL_ERROR;
+	}
+
+	printf("Chgmac completely\n");
+	free(buf);
+
+	return SUCCESS;
+}
+
+int main(int argc, char **argv)
+{
+	int inet_sock;
+	struct ifreq ifr;
+	struct ax_command_info info;
+	unsigned char i;
+	unsigned char count = 0;
+	const unsigned char length = sizeof(char);
+	struct _ax_ioctl_command ioctl_cmd;
+#if NET_INTERFACE == INTERFACE_SCAN
+	struct ifaddrs *addrs, *tmp;
+	unsigned char	dev_exist;
+#endif
+
+	printf("\n%s\n", AX88179_IOCTL_VERSION);
+
+	if (argc < 2) {
+		show_usage();
+		return 0;
+	}
+
+	inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
+#if NET_INTERFACE == INTERFACE_SCAN
+	getifaddrs(&addrs);
+	tmp = addrs;
+	dev_exist = 0;
+
+	while (tmp) {
+		memset(&ioctl_cmd, 0, sizeof(struct _ax_ioctl_command));
+		ioctl_cmd.ioctl_cmd = AX_SIGNATURE;
+
+		sprintf(ifr.ifr_name, "%s", tmp->ifa_name);
+		tmp = tmp->ifa_next;
+
+		ioctl(inet_sock, SIOCGIFFLAGS, &ifr);
+		if (!(ifr.ifr_flags & IFF_UP))
+			continue;
+
+		ifr.ifr_data = (caddr_t)&ioctl_cmd;
+
+		if (ioctl(inet_sock, AX_PRIVATE, &ifr) < 0)
+			continue;
+
+		if (strncmp(ioctl_cmd.sig, AX88179_DRV_NAME,
+			    strlen(AX88179_DRV_NAME)) == 0) {
+			dev_exist = 1;
+			break;
+		}
+	}
+
+	freeifaddrs(addrs);
+
+	if (dev_exist == 0) {
+		printf("No %s found\n", AX88179_SIGNATURE);
+		return 0;
+	}
+#else
+	for (i = 0; i < 255; i++) {
+
+		memset(&ioctl_cmd, 0, sizeof(struct _ax_ioctl_command));
+		ioctl_cmd.ioctl_cmd = AX_SIGNATURE;
+
+		sprintf(ifr.ifr_name, "eth%d", i);
+
+		ioctl(inet_sock, SIOCGIFFLAGS, &ifr);
+		if (!(ifr.ifr_flags & IFF_UP))
+			continue;
+
+		ifr.ifr_data = (caddr_t)&ioctl_cmd;
+
+		if (ioctl(inet_sock, AX_PRIVATE, &ifr) < 0)
+			continue;
+
+		if (strncmp(ioctl_cmd.sig, AX88179_DRV_NAME,
+			    strlen(AX88179_DRV_NAME)) == 0)
+			break;
+	}
+
+	if (i == 255) {
+		printf("No %s found\n", AX88179_SIGNATURE);
+		return 0;
+	}
+#endif
+	for (i = 0; ax88179_cmd_list[i].cmd != NULL; i++) {
+		if (strncmp(argv[1], ax88179_cmd_list[i].cmd,
+			    strlen(ax88179_cmd_list[i].cmd)) == 0) {
+			info.help_ins = ax88179_cmd_list[i].help_ins;
+			info.help_desc = ax88179_cmd_list[i].help_desc;
+			info.ifr = &ifr;
+			info.argc = argc;
+			info.argv = argv;
+			info.inet_sock = inet_sock;
+			info.ioctl_cmd = ax88179_cmd_list[i].ioctl_cmd;
+			(ax88179_cmd_list[i].OptFunc)(&info);
+			return 0;
+		}
+	}
+	printf("Wrong command\n");
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/ax88179a_772d.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/ax88179a_772d.c
@@ -0,0 +1,2594 @@
+// SPDX-License-Identifier: GPL-2.0
+/*******************************************************************************
+ *     Copyright (c) 2022    ASIX Electronic Corporation    All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+#include "ax_main.h"
+#include "ax88179a_772d.h"
+#ifdef ENABLE_PTP_FUNC
+#include "ax_ptp.h"
+#endif
+
+struct _ax_buikin_setting AX88179A_BULKIN_SIZE[] = {
+	{5, 0x7B, 0x00,	0x18, 0x0F},	//1G, SS
+	{5, 0xC0, 0x02,	0x06, 0x0F},	//1G, HS
+	{7, 0xF0, 0x00,	0x0C, 0x0F},	//100M, Full, SS
+	{6, 0x00, 0x00,	0x06, 0x0F},	//100M, Half, SS
+	{5, 0xC0, 0x04,	0x06, 0x0F},	//100M, Full, HS
+	{7, 0xC0, 0x04,	0x06, 0x0F},	//100M, Half, HS
+	{7, 0x00, 0,	0x03, 0x3F},	//FS
+};
+#ifdef ENABLE_AX88279
+struct _ax_buikin_setting AX88279_BULKIN_SIZE[] = {
+	{5, 0x10, 0x01,	0x11, 0x0F},	//2.5G
+	{7, 0xB3, 0x01,	0x11, 0x0F},	//1G, SS
+	{7, 0xC0, 0x02,	0x06, 0x0F},	//1G, HS
+	{7, 0x80, 0x01,	0x03, 0x0F},	//100M, Full, SS
+	{7, 0x80, 0x01,	0x03, 0x0F},	//100M, Half, SS
+	{7, 0x80, 0x01,	0x03, 0x0F},	//100M, Full, HS
+	{7, 0x80, 0x01,	0x03, 0x0F},	//100M, Half, HS
+	{7, 0x00, 0,	0x03, 0x3F},	//FS
+};
+#endif
+
+static int ax88179a_set_phy_power(struct ax_device *axdev, bool on);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
+static int ax88179a_chk_eee(struct ax_device *axdev)
+{
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
+
+	mii_ethtool_gset(&axdev->mii, &ecmd);
+
+	if (ecmd.speed == SPEED_1000) {
+		int eee_lp, eee_cap, eee_adv;
+		u32 lp, cap, adv;
+
+		eee_cap = ax_mmd_read(axdev->netdev,
+				      MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
+		if (eee_cap < 0)
+			goto exit;
+		eee_cap &= ~MDIO_EEE_100TX;
+
+		cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap);
+		if (!cap)
+			goto exit;
+
+		eee_lp = ax_mmd_read(axdev->netdev,
+				     MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
+		if (eee_lp < 0)
+			goto exit;
+
+		eee_adv = ax_mmd_read(axdev->netdev,
+				      MDIO_MMD_AN, MDIO_AN_EEE_ADV);
+		if (eee_adv < 0)
+			goto exit;
+
+		adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv);
+		lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp);
+		if (!(lp & adv & SUPPORTED_1000baseT_Full))
+			goto exit;
+
+		axdev->eee_active = 1;
+		return true;
+	}
+exit:
+	axdev->eee_active = 0;
+	return false;
+}
+
+static int ax88179a_ethtool_get_eee(struct ax_device *axdev,
+				    struct ethtool_eee *data)
+{
+	int val;
+
+	val = ax_mmd_read(axdev->netdev, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
+	if (val < 0)
+		return val;
+	val &= ~MDIO_EEE_100TX;
+	data->supported = mmd_eee_cap_to_ethtool_sup_t(val);
+
+	val = ax_mmd_read(axdev->netdev, MDIO_MMD_AN, MDIO_AN_EEE_ADV);
+	if (val < 0)
+		return val;
+	data->advertised = mmd_eee_adv_to_ethtool_adv_t(val);
+
+	val = ax_mmd_read(axdev->netdev, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
+	if (val < 0)
+		return val;
+	data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val);
+
+	return 0;
+}
+
+static int ax88179a_get_eee(struct net_device *net, struct ethtool_eee *edata)
+{
+	struct ax_device *axdev = netdev_priv(net);
+
+	edata->eee_enabled = axdev->eee_enabled;
+	edata->eee_active = axdev->eee_active;
+
+	return ax88179a_ethtool_get_eee(axdev, edata);
+}
+
+static void ax88179a_eee_setting(struct ax_device *axdev, bool enable)
+{
+	ax_write_cmd(axdev, AX88179_GPHY_CTRL, AX_GPHY_EEE_CTRL,
+		     enable, 0, NULL);
+}
+
+static int ax88179a_set_eee(struct net_device *net, struct ethtool_eee *edata)
+{
+	struct ax_device *axdev = netdev_priv(net);
+
+	if (edata->advertised & MDIO_EEE_100TX)
+		return -EOPNOTSUPP;
+
+	axdev->eee_enabled = edata->eee_enabled;
+	ax88179a_eee_setting(axdev, axdev->eee_enabled);
+	if (axdev->eee_enabled) {
+		axdev->eee_enabled = ax88179a_chk_eee(axdev);
+		if (!axdev->eee_enabled) {
+			ax88179a_eee_setting(axdev, false);
+			return -EOPNOTSUPP;
+		}
+	}
+
+	mii_nway_restart(&axdev->mii);
+
+	return 0;
+}
+#endif
+
+#if KERNEL_VERSION(5, 15, 0) <= LINUX_VERSION_CODE
+static int ax88179a_get_coalesce(struct net_device *netdev,
+				 struct ethtool_coalesce *coalesce,
+				 struct kernel_ethtool_coalesce *kernel_coal,
+				 struct netlink_ext_ack *extack)
+#else
+static int ax88179a_get_coalesce(struct net_device *netdev,
+				 struct ethtool_coalesce *coalesce)
+#endif
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+
+	coalesce->rx_coalesce_usecs = axdev->coalesce;
+
+	return 0;
+}
+
+static u16 ax88179a_usec_to_bin_timer(struct ax_device *axdev)
+{
+	u16 speed_multiple;
+
+	switch (axdev->link_info.eth_speed) {
+	case ETHER_LINK_10:
+		speed_multiple = 100;
+		break;
+	case ETHER_LINK_100:
+		speed_multiple = 10;
+		break;
+	case ETHER_LINK_1000:
+	default:
+		speed_multiple = 1;
+		break;
+	};
+
+	return (axdev->coalesce * US_TO_NS * speed_multiple) /
+		AX88179A_BIN_TIMER_UINT;
+}
+
+static u32 ax88179a_bin_timer_to_usec(struct ax_device *axdev, u16 timer)
+{
+	u16 speed_multiple;
+
+	switch (axdev->link_info.eth_speed) {
+	case ETHER_LINK_10:
+		speed_multiple = 100;
+		break;
+	case ETHER_LINK_100:
+		speed_multiple = 10;
+		break;
+	case ETHER_LINK_1000:
+	default:
+		speed_multiple = 1;
+		break;
+	};
+
+	return (AX88179A_BIN_TIMER_UINT * timer) / (US_TO_NS * speed_multiple);
+}
+#if KERNEL_VERSION(5, 15, 0) <= LINUX_VERSION_CODE
+static int ax88179a_set_coalesce(struct net_device *netdev,
+				 struct ethtool_coalesce *coalesce,
+				 struct kernel_ethtool_coalesce *kernel_coal,
+				 struct netlink_ext_ack *extack)
+#else
+static int ax88179a_set_coalesce(struct net_device *netdev,
+				 struct ethtool_coalesce *coalesce)
+#endif
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	u16 timer;
+	int ret = 0;
+
+	ret = usb_autopm_get_interface(axdev->intf);
+	if (ret < 0)
+		return ret;
+
+	axdev->coalesce = coalesce->rx_coalesce_usecs;
+
+	timer = ax88179a_usec_to_bin_timer(axdev);
+	if (timer > 0) {
+		timer &= 0x7FFF;
+		ax_write_cmd(axdev, AX_ACCESS_MAC, AX_RX_BULKIN_QTIMR_LOW,
+			     2, 2, &timer);
+	}
+
+	usb_autopm_put_interface(axdev->intf);
+
+	return ret;
+}
+
+#ifdef ENABLE_PTP_FUNC
+static int ax88179a_set_wol_get_ts_info
+(struct net_device *dev, struct ethtool_ts_info *info)
+{
+	struct ax_device *axdev = (struct ax_device *)netdev_priv(dev);
+	struct ax_ptp_cfg *ptp_cfg = axdev->ptp_cfg;
+
+	info->so_timestamping =
+			SOF_TIMESTAMPING_TX_SOFTWARE |
+			SOF_TIMESTAMPING_RX_SOFTWARE |
+			SOF_TIMESTAMPING_SOFTWARE |
+			SOF_TIMESTAMPING_TX_HARDWARE |
+			SOF_TIMESTAMPING_RX_HARDWARE |
+			SOF_TIMESTAMPING_RAW_HARDWARE;
+
+	info->phc_index = ptp_cfg->phc_index;
+
+	info->tx_types = BIT(HWTSTAMP_TX_OFF) |
+			 BIT(HWTSTAMP_TX_ON) |
+			 BIT(HWTSTAMP_TX_ONESTEP_SYNC) |
+			 BIT(HWTSTAMP_TX_ONESTEP_P2P);
+
+	info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
+			   BIT(HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
+			   BIT(HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
+			   BIT(HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
+			   BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
+			   BIT(HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
+			   BIT(HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
+			   BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
+			   BIT(HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
+			   BIT(HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ);
+
+	return 0;
+}
+#endif
+
+const struct ethtool_ops ax88179a_ethtool_ops = {
+#if KERNEL_VERSION(5, 7, 0) < LINUX_VERSION_CODE
+	.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS,
+#endif
+	.get_drvinfo	= ax_get_drvinfo,
+#if KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE
+	.get_settings	= ax_get_settings,
+	.set_settings	= ax_set_settings,
+#else
+	.get_link_ksettings = ax_get_link_ksettings,
+	.set_link_ksettings = ax_set_link_ksettings,
+#endif
+	.get_link	= ethtool_op_get_link,
+	.get_msglevel	= ax_get_msglevel,
+	.set_msglevel	= ax_set_msglevel,
+	.get_wol	= ax_get_wol,
+	.set_wol	= ax_set_wol,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
+	.get_eee	= ax88179a_get_eee,
+	.set_eee	= ax88179a_set_eee,
+#endif
+	.get_coalesce	= ax88179a_get_coalesce,
+	.set_coalesce	= ax88179a_set_coalesce,
+	.get_strings	= ax_get_strings,
+	.get_sset_count = ax_get_sset_count,
+	.get_ethtool_stats = ax_get_ethtool_stats,
+	.get_pauseparam = ax_get_pauseparam,
+	.set_pauseparam = ax_set_pauseparam,
+	.get_regs_len	= ax_get_regs_len,
+	.get_regs	= ax_get_regs,
+#ifdef ENABLE_PTP_FUNC
+	.get_ts_info	= ax88179a_set_wol_get_ts_info,
+#else
+	.get_ts_info	= ethtool_op_get_ts_info,
+#endif
+};
+
+#ifdef ENABLE_AX88279
+const struct ethtool_ops ax88279_ethtool_ops = {
+#if KERNEL_VERSION(5, 7, 0) < LINUX_VERSION_CODE
+	.supported_coalesce_params = ETHTOOL_COALESCE_RX_USECS,
+#endif
+	.get_drvinfo	= ax_get_drvinfo,
+#if KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE
+	.get_settings	= ax_get_settings,
+	.set_settings	= ax_set_settings,
+#else
+	.get_link_ksettings = ax_get_link_ksettings,
+	.set_link_ksettings = ax_set_link_ksettings,
+#endif
+	.get_link	= ethtool_op_get_link,
+	.get_msglevel	= ax_get_msglevel,
+	.set_msglevel	= ax_set_msglevel,
+	.get_wol	= ax_get_wol,
+	.set_wol	= ax_set_wol,
+	.get_coalesce	= ax88179a_get_coalesce,
+	.set_coalesce	= ax88179a_set_coalesce,
+	.get_strings	= ax_get_strings,
+	.get_sset_count = ax_get_sset_count,
+	.get_ethtool_stats = ax_get_ethtool_stats,
+	.get_pauseparam = ax_get_pauseparam,
+	.set_pauseparam = ax_set_pauseparam,
+	.get_regs_len	= ax_get_regs_len,
+	.get_regs	= ax_get_regs,
+#ifdef ENABLE_PTP_FUNC
+	.get_ts_info	= ax88179a_set_wol_get_ts_info,
+#else
+	.get_ts_info	= ethtool_op_get_ts_info,
+#endif
+};
+#endif
+
+void ax88179a_get_fw_version(struct ax_device *axdev)
+{
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		if (ax_read_cmd(axdev, AX88179A_ACCESS_BL, (0xFD + i),
+				1, 1, &axdev->fw_version[i], 1) < 0) {
+			axdev->fw_version[i] = ~0;
+		}
+	}
+
+	if (ax_read_cmd(axdev, AX88179A_ACCESS_BL, AX88179A_SW_REVERSION, 1, 1,
+			&axdev->fw_version[3], 0) < 0)
+		axdev->fw_version[3] = ~0;
+	else
+		axdev->fw_version[3] &= 0xF;
+}
+
+int ax88179a_signature(struct ax_device *axdev, struct _ax_ioctl_command *info)
+{
+	strncpy(info->sig, AX88179A_SIGNATURE, strlen(AX88179A_SIGNATURE));
+	return 0;
+}
+
+int ax88179a_read_version(struct ax_device *axdev,
+			  struct _ax_ioctl_command *info)
+{
+	unsigned char temp[16] = {0};
+
+	DEBUG_PRINTK("%s - Start", __func__);
+
+	sprintf(temp, "v%d.%d.%d.%d",
+		axdev->fw_version[0], axdev->fw_version[1],
+		axdev->fw_version[2], axdev->fw_version[3]);
+
+	memcpy(&info->version.version, temp, 16);
+
+	return 0;
+}
+
+int ax88179a_write_flash(struct ax_device *axdev,
+			 struct _ax_ioctl_command *info)
+{
+	int i, ret;
+	u8 *buf = NULL;
+	u8 *block;
+
+	DEBUG_PRINTK("%s - Start", __func__);
+
+	buf = kzalloc(256, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	block = buf;
+
+	ret = ax_write_cmd(axdev, AX88179A_FLASH_WEN, 0, 0, 0, NULL);
+	if (ret < 0) {
+		netdev_err(axdev->netdev, "Flash write enable failed");
+		info->flash.status = -ERR_FALSH_WRITE_EN;
+		goto out;
+	}
+
+	for (i = info->flash.offset;
+	     i < (info->flash.length + info->flash.offset);
+	     i += 256) {
+		if (copy_from_user(block,
+				   (void __user *)&info->flash.buf[i], 256)) {
+			netdev_err(axdev->netdev,
+				   "copy_from_user offset: 0x%x failed", i);
+			ret = -EFAULT;
+			goto out;
+		}
+
+		ret = ax_write_cmd(axdev, AX88179A_FLASH_WRITE,
+					(u16)((i >> 16) & 0xFFFF),
+					(u16)(i & 0xFFFF), 256, block);
+		if (ret < 0) {
+			netdev_err(axdev->netdev,
+				   "Flash write offset: 0x%x failed", i);
+			info->flash.status = -ERR_FALSH_WRITE;
+			goto out;
+		}
+	}
+
+	ret = ax_write_cmd(axdev, AX88179A_FLASH_WDIS, 0, 0, 0, NULL);
+	if (ret < 0) {
+		netdev_err(axdev->netdev, "Flash write disable failed");
+		info->flash.status = -ERR_FALSH_WRITE_DIS;
+		return ret;
+	}
+out:
+	kfree(buf);
+
+	return ret;
+}
+
+int ax88179a_read_flash(struct ax_device *axdev, struct _ax_ioctl_command *info)
+{
+	int i, ret = 0;
+	void *buf = NULL;
+	u8 *block;
+
+	DEBUG_PRINTK("%s - Start", __func__);
+
+	buf = kzalloc(256, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	block = buf;
+
+	for (i = info->flash.offset;
+	     i < (info->flash.length + info->flash.offset);
+	     i += 256) {
+		ret = ax_read_cmd(axdev, AX88179A_FLASH_READ,
+				  (u16)((i >> 16) & 0xFFFF),
+				  (u16)(i & 0xFFFF), 256, block, 0);
+		if (ret < 0) {
+			netdev_err(axdev->netdev,
+				   "Flash read offset: 0x%x failed", i);
+			info->flash.status = -ERR_FALSH_READ;
+			break;
+		}
+
+		if (copy_to_user((void __user *)&info->flash.buf[i],
+				 block, 256)) {
+			netdev_err(axdev->netdev,
+				   "copy_to_user offset: 0x%x failed", i);
+			ret = -EFAULT;
+			break;
+		}
+	}
+
+	kfree(buf);
+
+	return ret;
+}
+
+int ax88179a_program_efuse(struct ax_device *axdev,
+			   struct _ax_ioctl_command *info)
+{
+	int ret = 0;
+	u16 offset = (u16)(info->flash.offset * 16);
+	u8 buf[20] = {0};
+
+	DEBUG_PRINTK("%s - Start offset: %d (0x%x)", __func__, offset, offset);
+
+	ret = copy_from_user(buf, (void __user *)info->flash.buf, 20);
+	if (ret) {
+		netdev_err(axdev->netdev,
+			   "copy_from_user efuse offset: 0x%x failed", offset);
+		return ret;
+	}
+
+	ret = ax_write_cmd(axdev, AX_ACCESS_EFUSE, offset, 0, 20, buf);
+	if (ret < 0) {
+		netdev_err(axdev->netdev,
+			   "eFuse write offset: 0x%x failed", offset);
+		info->flash.status = -ERR_EFUSE_WRITE;
+		return ret;
+	}
+
+	return ret;
+}
+
+int ax88179a_dump_efuse(struct ax_device *axdev, struct _ax_ioctl_command *info)
+{
+	int ret = 0;
+	u16 offset = (u16)(info->flash.offset * 16);
+	u8 buf[20] = {0};
+
+	DEBUG_PRINTK("%s - Start offset: %d (0x%x)", __func__, offset, offset);
+
+	ret = ax_read_cmd(axdev, AX_ACCESS_EFUSE, offset, 0, 20, buf, 0);
+	if (ret < 0) {
+		netdev_err(axdev->netdev,
+			   "eFuse read offset: 0x%x failed", offset);
+		info->flash.status = -ERR_EFUSE_READ;
+		return ret;
+	}
+
+	ret = copy_to_user((void __user *)info->flash.buf, buf, 20);
+	if (ret) {
+		netdev_err(axdev->netdev,
+			   "copy_to_user efuse offset: 0x%x failed", offset);
+		return ret;
+	}
+
+	return ret;
+}
+
+int ax88179a_boot_to_rom(struct ax_device *axdev,
+			 struct _ax_ioctl_command *info)
+{
+	int ret;
+	u8 reg8;
+
+	DEBUG_PRINTK("%s - Start", __func__);
+
+	ax_read_cmd(axdev, AX_ACCESS_MAC, AX_MONITOR_MODE, 1, 1, &reg8, 1);
+
+	ret = usb_control_msg(axdev->udev, usb_sndctrlpipe(axdev->udev, 0),
+			      AX88179A_BOOT_TO_ROM,
+			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      0x5A5A, 0xA5A5, NULL, 0, 1);
+	if (ret < 0) {
+		netdev_err(axdev->netdev, "Booting to rom failed");
+		info->flash.status = -ERR_BOOT_CODE;
+		return ret;
+	}
+
+	return 0;
+}
+
+int ax88179a_erase_flash(struct ax_device *axdev,
+			 struct _ax_ioctl_command *info)
+{
+	int ret = 0;
+
+	DEBUG_PRINTK("%s - Start", __func__);
+
+	ret = ax_write_cmd(axdev, AX88179A_FLASH_WEN, 0, 0, 0, NULL);
+	if (ret < 0) {
+		netdev_err(axdev->netdev, "Flash write enable failed");
+		info->flash.status = -ERR_FALSH_WRITE_EN;
+		return ret;
+	}
+
+	ret = usb_control_msg(axdev->udev, usb_sndctrlpipe(axdev->udev, 0),
+			      AX88179A_FLASH_EARSE_ALL,
+			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      0, 0, NULL, 0, 300000);
+	if (ret < 0) {
+		netdev_err(axdev->netdev, "Flash erase all failed");
+		info->flash.status = -ERR_FALSH_ERASE_ALL;
+		return ret;
+	}
+
+	ret = ax_write_cmd(axdev, AX88179A_FLASH_WDIS, 0, 0, 0, NULL);
+	if (ret < 0) {
+		netdev_err(axdev->netdev, "Flash write disable failed");
+		info->flash.status = -ERR_FALSH_WRITE_DIS;
+		return ret;
+	}
+
+	return 0;
+}
+
+int ax88179a_erase_sector_flash(struct ax_device *axdev,
+			 struct _ax_ioctl_command *info)
+{
+	int ret = 0;
+
+	DEBUG_PRINTK("%s - Start", __func__);
+
+	ret = ax_write_cmd(axdev, AX88179A_FLASH_WEN, 0, 0, 0, NULL);
+	if (ret < 0) {
+		netdev_err(axdev->netdev, "Flash write enable failed");
+		info->flash.status = -ERR_FALSH_WRITE_EN;
+		return ret;
+	}
+
+	ret = usb_control_msg(axdev->udev, usb_sndctrlpipe(axdev->udev, 0),
+			      0x28,
+			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      (info->flash.offset >> 16) & 0xFFFF, info->flash.offset & 0xFFFF, NULL, 0, 300000);
+	if (ret < 0) {
+		netdev_err(axdev->netdev, "Flash erase sector failed");
+		info->flash.status = -ERR_FALSH_ERASE_ALL;
+		return ret;
+	}
+
+	ret = ax_write_cmd(axdev, AX88179A_FLASH_WDIS, 0, 0, 0, NULL);
+	if (ret < 0) {
+		netdev_err(axdev->netdev, "Flash write disable failed");
+		info->flash.status = -ERR_FALSH_WRITE_DIS;
+		return ret;
+	}
+
+	return 0;
+}
+
+int ax88179a_sw_reset(struct ax_device *axdev, struct _ax_ioctl_command *info)
+{
+	void *buf = NULL;
+
+	DEBUG_PRINTK("%s - Start", __func__);
+
+	buf = kzalloc(sizeof(u32), GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	*((u32 *)buf) = 1;
+#ifdef ENABLE_AX88279	
+	if (axdev->chip_version == AX_VERSION_AX88279) {
+		*((u8 *)buf) = 0x41;
+		ax_write_cmd(axdev, 0x2A, 0xAA00, 0, 1, buf);
+	} else {
+		usb_control_msg(axdev->udev, usb_sndctrlpipe(axdev->udev, 0), 0x10,
+			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			0x18E8, 0x000F, buf, 4, 10);
+	}
+#else
+	usb_control_msg(axdev->udev, usb_sndctrlpipe(axdev->udev, 0), 0x10,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		0x18E8, 0x000F, buf, 4, 10);
+#endif
+	kfree(buf);
+
+	return 0;
+}
+
+#define _MDIO_WRITE(offset, value) \
+	ax_mdio_write(netdev, phy_id, offset, value)
+
+int ax88179a_ieee_test(struct ax_device *axdev, struct _ax_ioctl_command *info)
+{
+	struct net_device *netdev = axdev->netdev;
+	int phy_id = axdev->mii.phy_id;
+	int ret;
+
+	DEBUG_PRINTK("%s - Start", __func__);
+	DEBUG_PRINTK("Stop: %d", info->ieee.stop);
+	DEBUG_PRINTK("Speed: %d", info->ieee.speed);
+	DEBUG_PRINTK("Type: %d", info->ieee.type);
+
+	if (info->ieee.speed == 1000 && axdev->chip_pin == CHIP_32PIN) {
+		netdev_err(axdev->netdev, "Invalid Chip pin");
+		info->ieee.status = -ERR_IEEE_INVALID_CHIP;
+		return -EINVAL;
+	}
+
+	if (info->ieee.stop) {
+		ret = ax88179a_set_phy_power(axdev, false);
+		if (ret < 0)
+			return ret;
+		msleep(500);
+
+		ret = ax88179a_set_phy_power(axdev, true);
+		if (ret < 0)
+			return ret;
+		msleep(500);
+
+		switch (info->ieee.speed) {
+		case 1000:
+		case 100:
+			break;
+		case 10:
+			_MDIO_WRITE(0x00, 0x0100);
+			_MDIO_WRITE(0x0D, 0x001E);
+			_MDIO_WRITE(0x0E, 0x0145);
+			_MDIO_WRITE(0x0D, 0x401E);
+			_MDIO_WRITE(0x0E, 0x5010);
+			_MDIO_WRITE(0x0D, 0x001F);
+			_MDIO_WRITE(0x0E, 0x027B);
+			_MDIO_WRITE(0x0D, 0x401F);
+			_MDIO_WRITE(0x0E, 0x1177);
+			break;
+		default:
+			return -EINVAL;
+		};
+	} else {
+		switch (info->ieee.type) {
+		case IEEE_1000M1:
+			_MDIO_WRITE(0x09, 0x2700);
+			break;
+		case IEEE_1000M2:
+			_MDIO_WRITE(0x09, 0x4700);
+			break;
+		case IEEE_1000M3:
+			_MDIO_WRITE(0x09, 0x6700);
+			break;
+		case IEEE_1000M4:
+			_MDIO_WRITE(0x09, 0x8700);
+			break;
+		case IEEE_100CA:
+			_MDIO_WRITE(0x00, 0x2100);
+			_MDIO_WRITE(0x0D, 0x001E);
+			_MDIO_WRITE(0x0E, 0x0145);
+			_MDIO_WRITE(0x0D, 0x401E);
+			_MDIO_WRITE(0x0E, 0x5010);
+			break;
+		case IEEE_100CB:
+			_MDIO_WRITE(0x00, 0x2100);
+			_MDIO_WRITE(0x0D, 0x001E);
+			_MDIO_WRITE(0x0E, 0x0145);
+			_MDIO_WRITE(0x0D, 0x401E);
+			_MDIO_WRITE(0x0E, 0x5018);
+			break;
+		case IEEE_10R:
+			ret = ax88179a_set_phy_power(axdev, false);
+			if (ret < 0)
+				return ret;
+			msleep(100);
+
+			ret = ax88179a_set_phy_power(axdev, true);
+			if (ret < 0)
+				return ret;
+			_MDIO_WRITE(0x00, 0x0100);
+			_MDIO_WRITE(0x0D, 0x001E);
+			_MDIO_WRITE(0x0E, 0x0145);
+			_MDIO_WRITE(0x0D, 0x401E);
+			_MDIO_WRITE(0x0E, 0x5010);
+			_MDIO_WRITE(0x0D, 0x001F);
+			_MDIO_WRITE(0x0E, 0x027B);
+			_MDIO_WRITE(0x0D, 0x401F);
+			_MDIO_WRITE(0x0E, 0x1177);
+			_MDIO_WRITE(0x00, 0x0800);
+			_MDIO_WRITE(0x1F, 0x0001);
+			_MDIO_WRITE(0x1D, 0xF842);
+			ax_mmd_write(axdev->netdev, 0x1E, 0x01A3, 0x2);
+			ax_mmd_write(axdev->netdev, 0x1E, 0x01A4, 0x110e);
+			_MDIO_WRITE(0x1F, 0x0000);
+			_MDIO_WRITE(0x00, 0x0100);
+			break;
+		case IEEE_10FF:
+			ret = ax88179a_set_phy_power(axdev, false);
+			if (ret < 0)
+				return ret;
+			msleep(100);
+
+			ret = ax88179a_set_phy_power(axdev, true);
+			if (ret < 0)
+				return ret;
+			_MDIO_WRITE(0x00, 0x0100);
+			_MDIO_WRITE(0x0D, 0x001E);
+			_MDIO_WRITE(0x0E, 0x0145);
+			_MDIO_WRITE(0x0D, 0x401E);
+			_MDIO_WRITE(0x0E, 0x5010);
+			_MDIO_WRITE(0x0D, 0x001F);
+			_MDIO_WRITE(0x0E, 0x027B);
+			_MDIO_WRITE(0x0D, 0x401F);
+			_MDIO_WRITE(0x0E, 0x1177);
+			_MDIO_WRITE(0x00, 0x0800);
+			_MDIO_WRITE(0x1F, 0x0001);
+			_MDIO_WRITE(0x1D, 0xF840);
+			ax_mmd_write(axdev->netdev, 0x1E, 0x01A3, 0x0000);
+			_MDIO_WRITE(0x1F, 0x0000);
+			_MDIO_WRITE(0x00, 0x0100);
+			break;
+		case IEEE_10MDI:
+			_MDIO_WRITE(0x00, 0x0100);
+			_MDIO_WRITE(0x0D, 0x001E);
+			_MDIO_WRITE(0x0E, 0x0145);
+			_MDIO_WRITE(0x0D, 0x401E);
+			_MDIO_WRITE(0x0E, 0x5010);
+			_MDIO_WRITE(0x0D, 0x001F);
+			_MDIO_WRITE(0x0E, 0x027B);
+			_MDIO_WRITE(0x0D, 0x401F);
+			_MDIO_WRITE(0x0E, 0x1177);
+			break;
+		default:
+			return -EINVAL;
+		};
+	}
+
+	return 0;
+}
+
+int ax88179a_autosuspend_en(struct ax_device *axdev,
+			    struct _ax_ioctl_command *info)
+{
+	DEBUG_PRINTK("%s - Start", __func__);
+
+	if (axdev->autosuspend_is_supported) {
+		if (info->autosuspend.enable)
+			usb_enable_autosuspend(axdev->udev);
+		else
+			usb_disable_autosuspend(axdev->udev);
+	}
+
+	return 0;
+}
+
+IOCTRL_TABLE ax88179a_tbl[] = {
+	ax88179a_signature,
+	ax_usb_command,
+	ax88179a_read_version,
+	ax88179a_write_flash,
+	ax88179a_boot_to_rom,
+	ax88179a_erase_flash,
+	ax88179a_sw_reset,
+	ax88179a_read_flash,
+	ax88179a_program_efuse,
+	ax88179a_dump_efuse,
+	ax88179a_ieee_test,
+	ax88179a_autosuspend_en,
+	ax88179a_erase_sector_flash,
+};
+
+#ifdef ENABLE_PTP_FUNC
+static int ax88179a_hwtstamp_ioctl
+(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct hwtstamp_config config;
+
+	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
+		return -EFAULT;
+
+	if (config.flags)
+		return -EINVAL;
+
+	switch (config.rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		break;
+	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+	case HWTSTAMP_FILTER_ALL:
+	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+	case HWTSTAMP_FILTER_PTP_V2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+		config.rx_filter = HWTSTAMP_FILTER_ALL;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
+		-EFAULT : 0;
+}
+#endif
+
+#if KERNEL_VERSION(5, 15, 0) <= LINUX_VERSION_CODE
+int ax88179a_siocdevprivate(struct net_device *netdev, struct ifreq *rq,
+			    void __user *udata, int cmd)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	struct _ax_ioctl_command info;
+	void __user *uptr = (void __user *) rq->ifr_data;
+	int ret = 0;
+
+	switch (cmd) {
+	case AX_PRIVATE:
+		if (copy_from_user(&info, uptr,
+				   sizeof(struct _ax_ioctl_command))) {
+			netdev_err(netdev, "copy_from_user, return -EFAULT");
+			return -EFAULT;
+		}
+		DEBUG_PRINTK("ioctl_cmd: %d", info.ioctl_cmd);
+		ret = (*ax88179a_tbl[info.ioctl_cmd])(axdev, &info);
+		if (ret < 0)
+			netdev_err(netdev, "ax88179a_tbl, return %d", ret);
+
+		if (copy_to_user(uptr, &info,
+				 sizeof(struct _ax_ioctl_command))) {
+			netdev_err(netdev, "copy_to_user failed");
+			return ret;
+		}
+
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+	}
+
+	return ret;
+}
+
+int ax88179a_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+
+	switch (cmd) {
+#ifdef ENABLE_PTP_FUNC
+	case SIOCSHWTSTAMP:
+		return ax88179a_hwtstamp_ioctl(netdev, rq, cmd);
+#endif
+	}
+	return generic_mii_ioctl(&axdev->mii, if_mii(rq), cmd, NULL);
+}
+#else
+int ax88179a_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	struct _ax_ioctl_command info;
+	void __user *uptr = (void __user *) rq->ifr_data;
+	int ret;
+
+	switch (cmd) {
+	case AX_PRIVATE:
+		if (copy_from_user(&info, uptr,
+				   sizeof(struct _ax_ioctl_command))) {
+			netdev_err(netdev, "copy_from_user, return -EFAULT");
+			return -EFAULT;
+		}
+		DEBUG_PRINTK("ioctl_cmd: %d", info.ioctl_cmd);
+		ret = (*ax88179a_tbl[info.ioctl_cmd])(axdev, &info);
+		if (ret < 0) {
+			netdev_err(netdev, "ax88179a_tbl, return %d", ret);
+			return ret;
+		}
+
+		if (copy_to_user(uptr, &info,
+				 sizeof(struct _ax_ioctl_command))) {
+			netdev_err(netdev, "copy_to_user, return -EFAULT");
+			return -EFAULT;
+		}
+
+		break;
+#ifdef ENABLE_PTP_FUNC
+	case SIOCSHWTSTAMP:
+		return ax88179a_hwtstamp_ioctl(netdev, rq, cmd);
+#endif
+	default:
+		return generic_mii_ioctl(&axdev->mii, if_mii(rq), cmd, NULL);
+	}
+	return 0;
+}
+#endif
+
+static int ax88179a_autodetach(struct ax_device *axdev)
+{
+	u16 value = ((axdev->autodetach) ? 1 : 0) | AX88179A_AUTODETACH_DELAY;
+
+	return ax_write_cmd(axdev, AX88179A_AUTODETACH, value, 0, 0, NULL);
+}
+
+static bool ax88179a_check_phy_power(struct ax_device *axdev)
+{
+	u8 reg8 = 0;
+	int ret = 0;
+
+	ret = ax_read_cmd_nopm(axdev, AX88179A_PHY_POWER, 0, 0, 1, &reg8, 1);
+	if (ret < 0)
+		return false;
+
+	return (reg8 & AX_PHY_POWER);
+}
+
+static int ax88179a_set_phy_power(struct ax_device *axdev, bool on)
+{
+	u8 reg8;
+	int ret;
+
+	reg8 = (on)?AX_PHY_POWER:0;
+	ret = ax_write_cmd_nopm(axdev, AX88179A_PHY_POWER, 0, 0, 1, &reg8);
+	if (ret < 0)
+		return ret;
+	msleep(250);
+#ifdef ENABLE_INT_AGGRESSIVE
+	if (on) {
+		u16 reg16;
+
+		printk("ENABLE_INT_AGGRESSIVE");
+		ax_write_cmd(axdev, 0x32, 0x3, 0, 0, &reg16);
+	}
+#endif
+	return 0;
+}
+
+static int ax88179a_bind(struct ax_device *axdev)
+{
+	struct net_device *netdev = axdev->netdev;
+	u16 wvalue = 0;
+	int ret;
+
+	ax88179a_get_fw_version(axdev);
+#ifdef ENABLE_AX88279
+	if (axdev->chip_version == AX_VERSION_AX88279)
+		PRINT_VERSION(axdev, AX_DRIVER_STRING_279);
+	else
+		PRINT_VERSION(axdev, AX_DRIVER_STRING_179A_772D);
+#else
+	PRINT_VERSION(axdev, AX_DRIVER_STRING_179A_772D);
+#endif
+
+#ifdef ENABLE_QUEUE_PRIORITY
+	wvalue |= AX_USB_EP5_EN;
+#endif
+#ifdef ENABLE_AX88279
+#ifdef ENABLE_PTP_FUNC
+	wvalue |= AX_USB_EP4_EN;
+#endif
+#endif
+	ret = ax_write_cmd(axdev, AX_FW_MODE, AX_FW_MODE_179A, wvalue, 0, NULL);
+	if (ret < 0)
+		return ret;
+
+	ret = ax_write_cmd(axdev, AX_RELOAD_FLASH_EFUSE, 0, 0, 0, NULL);
+	if (ret < 0)
+		return ret;
+
+	netdev->features    |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+			       NETIF_F_SG | NETIF_F_TSO | NETIF_F_FRAGLIST |
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+					NETIF_F_HW_VLAN_CTAG_RX |
+					NETIF_F_HW_VLAN_CTAG_TX;
+#else
+					NETIF_F_HW_VLAN_RX |
+					NETIF_F_HW_VLAN_TX;
+#endif
+	netdev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+			       NETIF_F_SG | NETIF_F_TSO | NETIF_F_FRAGLIST |
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+					NETIF_F_HW_VLAN_CTAG_RX |
+					NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_RXALL;
+#else
+					NETIF_F_HW_VLAN_RX |
+					NETIF_F_HW_VLAN_TX | NETIF_F_RXALL;
+#endif
+
+		netdev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
+				NETIF_F_HIGHDMA | NETIF_F_FRAGLIST |
+				NETIF_F_IPV6_CSUM;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
+	netdev->max_mtu = (9 * 1024);
+#else
+	axdev->max_mtu = (9 * 1024);
+#endif
+	axdev->tx_casecade_size = TX_CASECADES_SIZE;
+	axdev->gso_max_size = AX_GSO_DEFAULT_SIZE;
+	axdev->mii.supports_gmii = true;
+	axdev->mii.dev = netdev;
+	axdev->mii.mdio_read = ax_mdio_read;
+	axdev->mii.mdio_write = ax_mdio_write;
+	axdev->mii.phy_id_mask = 0x3F;
+	axdev->mii.reg_num_mask = 0x1F;
+	axdev->mii.phy_id = AX88179A_PHY_ID;
+#if KERNEL_VERSION(5, 19, 0) <= LINUX_VERSION_CODE
+	netif_set_tso_max_size(netdev, axdev->gso_max_size);
+#else
+	netif_set_gso_max_size(netdev, axdev->gso_max_size);
+#endif
+	axdev->bin_setting.custom = false;
+	axdev->tx_align_len = 8;
+	axdev->coalesce = 0;
+#ifdef ENABLE_AX88279
+	if (axdev->chip_version == AX_VERSION_AX88279) {
+		netdev->ethtool_ops = &ax88279_ethtool_ops;
+	} else {
+		netdev->ethtool_ops = &ax88179a_ethtool_ops;
+	}
+#else
+	netdev->ethtool_ops = &ax88179a_ethtool_ops;
+#endif
+	
+	axdev->netdev->netdev_ops = &ax88179a_netdev_ops;
+
+#ifdef ENABLE_PTP_FUNC
+	ret = ax_ptp_register(axdev);
+	if (ret < 0)
+		netdev_warn(netdev,
+			    "Failed to register PHC device. (%d)\n", ret);
+#endif
+
+#ifdef ENABLE_AUTOSUSPEND
+	axdev->autosuspend_is_supported = true;
+	usb_enable_autosuspend(axdev->udev);
+#else
+	axdev->autosuspend_is_supported = false;
+	usb_disable_autosuspend(axdev->udev);
+#endif
+
+	return ret;
+}
+
+static void ax88179a_unbind(struct ax_device *axdev)
+{
+#ifdef ENABLE_PTP_FUNC
+	ax_ptp_unregister(axdev);
+#endif
+}
+
+static int ax88179a_stop(struct ax_device *axdev)
+{
+	u16 reg16;
+
+	reg16 = AX_RX_CTL_STOP;
+	ax_write_cmd(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2, &reg16);
+#ifdef ENABLE_AX88279
+#ifdef ENABLE_PTP_FUNC
+	ax88279_stop_get_ts(axdev);
+#endif
+#endif
+
+	ax88179a_set_phy_power(axdev, false);
+
+	return 0;
+}
+
+void ax88179a_set_multicast(struct net_device *netdev)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	u8 *m_filter = axdev->m_filter;
+	int mc_count = 0;
+
+	if (!test_bit(AX_ENABLE, &axdev->flags))
+		return;
+
+#if KERNEL_VERSION(2, 6, 35) > LINUX_VERSION_CODE
+	mc_count = net->mc_count;
+#else
+	mc_count = netdev_mc_count(netdev);
+#endif
+
+	axdev->rxctl = (AX_RX_CTL_START | AX_RX_CTL_AB);
+#ifdef ENABLE_AX88279
+	if (axdev->chip_version == AX_VERSION_AX88279)
+		axdev->rxctl |= AX_RX_CTL_DROPCRCERR;
+#endif
+
+	if (netdev->flags & IFF_PROMISC) {
+		axdev->rxctl |= AX_RX_CTL_PRO;
+	} else if (netdev->flags & IFF_ALLMULTI || mc_count > AX_MAX_MCAST) {
+		axdev->rxctl |= AX_RX_CTL_AMALL;
+	} else if (netdev_mc_empty(netdev)) {
+	} else {
+		u32 crc_bits;
+#if KERNEL_VERSION(2, 6, 35) > LINUX_VERSION_CODE
+		struct dev_mc_list *mc_list = netdev->mc_list;
+		int i = 0;
+
+		memset(m_filter, 0, AX_MCAST_FILTER_SIZE);
+		for (i = 0; i < netdev->mc_count; i++) {
+			crc_bits =
+			    ether_crc(ETH_ALEN,
+				      mc_list->dmi_addr) >> 26;
+			*(m_filter + (crc_bits >> 3)) |=
+				1 << (crc_bits & 7);
+			mc_list = mc_list->next;
+		}
+#else
+		struct netdev_hw_addr *ha = NULL;
+
+		memset(m_filter, 0, AX_MCAST_FILTER_SIZE);
+		netdev_for_each_mc_addr(ha, netdev) {
+			crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26;
+			*(m_filter + (crc_bits >> 3)) |= 1 << (crc_bits & 7);
+		}
+#endif
+		ax_write_cmd_async(axdev, AX_ACCESS_MAC, AX_MULTI_FILTER_ARRY,
+				   AX_MCAST_FILTER_SIZE, AX_MCAST_FILTER_SIZE,
+				   m_filter);
+
+		axdev->rxctl |= AX_RX_CTL_AM;
+	}
+
+	ax_write_cmd_async(axdev, AX_ACCESS_MAC, AX_RX_CTL,
+			   2, 2, &axdev->rxctl);
+}
+
+static int ax88179a_hw_init(struct ax_device *axdev)
+{
+	u16 reg16;
+	u8 reg8;
+	int ret;
+
+#ifdef ENABLE_AX88279
+	if (axdev->chip_version != AX_VERSION_AX88279) {
+		u32 reg32 = 0;
+		ret = ax_read_cmd(axdev, AX88179A_PBUS_REG,0x18C8, 0, 4,
+				  &reg32, 1);
+		if (ret < 0)
+			return ret;
+		axdev->chip_pin = reg32 & 0x03;
+	}
+#endif
+	ret = ax88179a_set_phy_power(axdev, true);
+	if (ret < 0)
+		return ret;
+	msleep(250);
+
+#ifdef ENABLE_AX88279
+	if (axdev->chip_version == AX_VERSION_AX88279) {
+		reg16 = ax_mdio_read(axdev->netdev, axdev->mii.phy_id,
+				     MII_ADVERTISE);
+		reg16 &= ~(ADVERTISE_10FULL | ADVERTISE_10HALF);
+		ax_mdio_write(axdev->netdev, axdev->mii.phy_id, MII_ADVERTISE,
+			      (reg16 | ADVERTISE_RESV));
+		reg16 = ax_mdio_read(axdev->netdev, axdev->mii.phy_id,
+				     MII_CTRL1000);
+		ax_mdio_write(axdev->netdev, axdev->mii.phy_id, MII_CTRL1000,
+			      (reg16 | CTL1000_AS_MASTER));
+		ax_mdio_write(axdev->netdev, axdev->mii.phy_id, 0,
+			      (BMCR_ANRESTART | BMCR_ANENABLE));
+	}
+#endif
+	ret = ax88179a_autodetach(axdev);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP |
+	       AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
+	       AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX_MAC_EFF_EN;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX88179A_MAC_BULK_OUT_CTRL,
+			    1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg16 = 0;
+	ret = ax_write_cmd_async(axdev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &reg16);
+	if (ret < 0)
+		return ret;
+
+	reg8 = 0x04;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW,
+			   1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = 0x10;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
+			   1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = 0;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+		if (axdev->netdev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
+#else
+		if (axdev->netdev->features & NETIF_F_HW_VLAN_FILTER)
+#endif		
+		reg8 |= AX_VLAN_CONTROL_VFE;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+		if (axdev->netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
+#else
+		if (axdev->netdev->features & NETIF_F_HW_VLAN_RX)
+#endif		
+	reg8 |= AX_VLAN_CONTROL_VSO;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX88179A_VLAN_ID_CONTROL,
+			   1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = 0xff;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX88179A_MAC_BM_INT_MASK,
+			    1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = 0;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX88179A_MAC_BM_RX_DMA_CTL,
+			    1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX88179A_MAC_BM_TX_DMA_CTL,
+			    1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX88179A_MAC_ARC_CTRL,
+			    1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX88179A_MAC_SWP_CTRL,
+			    1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+
+	reg8 = AX_TXHDR_CKSUM_EN;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_TX_HDR_CKSUM,
+				1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg16 = AX_RX_CTL_START | AX_RX_CTL_AP | AX_RX_CTL_AMALL |
+		AX_RX_CTL_AB | AX_RX_CTL_DROPCRCERR;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX_RX_CTL, 1, 1, &reg16);
+	if (ret < 0)
+		return ret;
+
+	reg8 = 0;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX88179A_MAC_PATH, 1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	ret = ax_read_cmd(axdev, AX_ACCESS_MAC, AX_MONITOR_MODE, 1, 1, &reg8, 1);
+	if (ret < 0)
+		return ret;
+	reg8 &= 0xE0;
+	reg8 |= AX_MONITOR_MODE_RWMP;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX_MONITOR_MODE, 1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+
+	ret = ax_read_cmd(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+				 2, 2, &reg16, 2);
+	if (ret < 0)
+		return ret;
+
+	reg16 &= ~AX_MEDIUM_GIGAMODE;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+			    2, 2, &reg16);
+	if (ret < 0)
+		return ret;
+
+	reg16 |= AX_MEDIUM_GIGAMODE;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+			    2, 2, &reg16);
+	if (ret < 0)
+		return ret;
+
+	reg8 = 0;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX88179A_BFM_DATA, 1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX88179A_CDC_ECM_CTRL,
+			   1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	ax_set_tx_qlen(axdev);
+
+#ifdef ENABLE_AX88279
+#ifdef ENABLE_PTP_FUNC
+	ax88279_start_get_ts(axdev);
+#endif
+#endif
+
+	return ret;
+}
+
+static int ax88179a_get_ether_link(struct ax_device *axdev)
+{
+	struct ax_link_info *link_info = &axdev->link_info;
+#if KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE
+	struct ethtool_cmd cmd;
+
+	mii_ethtool_gset(&axdev->mii, &cmd);
+	switch (ethtool_cmd_speed(&cmd)) {
+	case SPEED_1000:
+		link_info->eth_speed = ETHER_LINK_1000;
+		break;
+	case SPEED_100:
+		link_info->eth_speed = ETHER_LINK_100;
+		break;
+	case SPEED_10:
+	default:
+		link_info->eth_speed = ETHER_LINK_10;
+		break;
+	};
+
+	link_info->full_duplex = cmd.duplex;
+#else
+	struct ethtool_link_ksettings cmd;
+
+	mii_ethtool_get_link_ksettings(&axdev->mii, &cmd);
+	switch (cmd.base.speed) {
+	case SPEED_1000:
+		link_info->eth_speed = ETHER_LINK_1000;
+		break;
+	case SPEED_100:
+		link_info->eth_speed = ETHER_LINK_100;
+		break;
+	case SPEED_10:
+	default:
+		link_info->eth_speed = ETHER_LINK_10;
+		break;
+	};
+
+	link_info->full_duplex = cmd.base.duplex;
+#endif
+	return 0;
+}
+
+static int ax88179a_set_bulkin_setting(struct ax_device *axdev)
+{
+	struct ax_link_info *link_info = &axdev->link_info;
+	u8 link_sts;
+	int index = 0, ret;
+
+	ret = ax_read_cmd_nopm(axdev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS,
+			       1, 1, &link_sts, 0);
+	if (ret < 0)
+		return ret;
+
+	switch (link_info->eth_speed) {
+	case ETHER_LINK_1000:
+		if (link_sts & AX_USB_SS)
+			index = 0;
+		else if (link_sts & AX_USB_HS)
+			index = 1;
+		break;
+	case ETHER_LINK_100:
+		if (link_sts & AX_USB_SS)
+			index = 2;
+		else if (link_sts & AX_USB_HS)
+			index = 4;
+
+		if (!link_info->full_duplex)
+			index++;
+		break;
+	case ETHER_LINK_10:
+		index = 6;
+		break;
+	case ETHER_LINK_NONE:
+	default:
+		index = 0;
+		break;
+	};
+
+	if (axdev->coalesce == 0) {
+		u16 timer = *((u16 *)&AX88179A_BULKIN_SIZE[index].timer_l);
+
+		axdev->coalesce = ax88179a_bin_timer_to_usec(axdev, timer);
+	} else {
+		u16 timer = ax88179a_usec_to_bin_timer(axdev);
+
+		AX88179A_BULKIN_SIZE[index].timer_l = timer & 0xFF;
+		AX88179A_BULKIN_SIZE[index].timer_h = (timer >> 8) & 0xFF;
+	}
+
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL,
+				5, 5, &AX88179A_BULKIN_SIZE[index]);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int ax88179a_link_setting(struct ax_device *axdev)
+{
+	struct ax_link_info *link_info = &axdev->link_info;
+	u16 medium_mode, reg16;
+	u8 reg8[3];
+	int ret;
+
+	reg16 = AX_RX_CTL_STOP;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &reg16);
+	if (ret < 0)
+		return ret;
+
+	reg8[0] = 0;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_PATH,
+				1, 1, reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8[0] = 0xA5;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_CDC_DELAY_TX,
+				 1, 1, reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8[0] = 0x10;
+	reg8[1] = 0x04;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH,
+				2, 2, reg8);
+	if (ret < 0)
+		return ret;
+
+	medium_mode = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_RXFLOW_CTRLEN |
+		      AX_MEDIUM_TXFLOW_CTRLEN;
+	reg8[0] = 0x28 | AX_NEW_PAUSE_EN;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_NEW_PAUSE_CTRL,
+			   1, 1, reg8);
+	if (ret < 0)
+		return ret;
+
+	switch (link_info->eth_speed) {
+	case ETHER_LINK_1000:
+	case ETHER_LINK_100:
+		reg8[0] = 0x78;
+		reg8[1] = (AX_LSOFC_WCNT_7_ACCESS << 5) | AX_GMII_CRC_APPEND;
+		reg8[2] = 0;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_RX_STATUS_CDC, 3, 3, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0x40;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_RX_DATA_CDC_CNT,
+					1, 1, reg8);
+		if (ret < 0)
+			return ret;
+		if (link_info->eth_speed == ETHER_LINK_1000)
+			medium_mode |= AX_MEDIUM_GIGAMODE;
+		break;
+	case ETHER_LINK_10:
+		reg8[0] = 0xFA;
+		reg8[1] = (AX_LSOFC_WCNT_7_ACCESS << 5) | AX_GMII_CRC_APPEND;
+		reg8[2] = 0xFF;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_RX_STATUS_CDC, 3, 3, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0xFA;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_RX_DATA_CDC_CNT,
+					1, 1, reg8);
+		if (ret < 0)
+			return ret;
+		break;
+	default:
+		break;
+	};
+
+	reg8[0] = 0;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_BFM_DATA,
+				1, 1, reg8);
+	if (ret < 0)
+		return ret;
+
+	ret = ax88179a_set_bulkin_setting(axdev);
+	if (ret < 0)
+		return ret;
+
+	if (link_info->full_duplex)
+		medium_mode |= AX_MEDIUM_FULL_DUPLEX;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+				2, 2, &medium_mode);
+	if (ret < 0)
+		return ret;
+
+	axdev->rxctl |= AX_RX_CTL_START | AX_RX_CTL_AB;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL,
+				2, 2, &axdev->rxctl);
+	if (ret < 0)
+		return ret;
+
+	reg8[0] = AX_MAC_RX_PATH_READY | AX_MAC_TX_PATH_READY;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_PATH,
+				1, 1, reg8);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+#ifdef ENABLE_QUEUE_PRIORITY
+static int ax88179a_queue_priority(struct ax_device *axdev)
+{
+	u8 reg8;
+	int ret;
+
+	reg8 = AX_RX_CTL_STOP;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL, 1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = 0;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+				AX88179A_MAC_PATH, 1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	axdev->rxctl |= AX_RX_CTL_START | AX_RX_CTL_AB;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL,
+				2, 2, &axdev->rxctl);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX88179A_HIGH_QUEUE_POINT;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+				AX88179A_MAC_QUEUE_POINT, 1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX_TX_QUEUE_CFG | AX_TX_QUEUE_SET;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_BFM_DATA,
+				1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX_TX_Q1_AHB_FC_EN | AX_TX_QUEUE_CFG;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_BFM_DATA,
+				1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX_MAC_STOP_EP5_ACCESS;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_BFM_CTRL,
+				1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX_MAC_RX_PATH_READY | AX_MAC_TX_PATH_READY;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_PATH,
+				1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+#endif
+
+static int ax88179a_link_reset(struct ax_device *axdev)
+{
+	int ret;
+
+	ret = ax88179a_get_ether_link(axdev);
+	if (ret < 0)
+		return ret;
+
+	ret = ax88179a_link_setting(axdev);
+	if (ret < 0)
+		return ret;
+
+#ifdef ENABLE_QUEUE_PRIORITY
+	ret = axdev->driver_info->queue_priority(axdev);
+	if (ret < 0)
+		return ret;
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
+	axdev->eee_enabled = ax88179a_chk_eee(axdev);
+	ax88179a_eee_setting(axdev, axdev->eee_enabled);
+#endif
+
+#ifdef ENABLE_PTP_FUNC
+	if (axdev->driver_info->ptp_init)
+		axdev->driver_info->ptp_init(axdev);
+#endif
+
+	return 0;
+}
+#ifdef ENABLE_AX88279
+static int ax88279_get_ether_link(struct ax_device *axdev)
+{
+	ax88179a_get_ether_link(axdev);
+
+	if (axdev->chip_version >= AX_VERSION_AX88279) {
+		if (axdev->intr_link_info.eth_speed == ETHER_LINK_2500) {
+			axdev->link_info.eth_speed = ETHER_LINK_2500;
+			axdev->link_info.full_duplex = true;
+		}
+	}
+
+	return 0;
+}
+
+static int ax88279_set_bulkin_setting(struct ax_device *axdev)
+{
+	struct ax_link_info *link_info = &axdev->link_info;
+	u8 link_sts;
+	int index = 7;
+	int ret;
+
+	ret = ax_read_cmd_nopm(axdev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS,
+			       1, 1, &link_sts, 0);
+	if (ret < 0)
+		return ret;
+
+	if (link_sts & AX_USB_FS) {
+		index = 7;
+	} else {
+		switch (link_info->eth_speed) {
+		case ETHER_LINK_2500:
+			index = 0;
+			break;
+		case ETHER_LINK_1000:
+			if (link_sts & AX_USB_SS)
+				index = 1;
+			else if (link_sts & AX_USB_HS)
+				index = 2;
+			break;
+		case ETHER_LINK_100:
+			if (link_sts & AX_USB_SS)
+				index = 3;
+			else if (link_sts & AX_USB_HS)
+				index = 5;
+
+			if (!link_info->full_duplex)
+				index++;
+			break;
+		case ETHER_LINK_10:
+			break;
+		default:
+			return -1;
+		};
+	}
+
+	if (axdev->coalesce == 0) {
+		u16 timer = *((u16 *)&AX88279_BULKIN_SIZE[index].timer_l);
+
+		axdev->coalesce = ax88179a_bin_timer_to_usec(axdev, timer);
+	} else {
+		u16 timer = ax88179a_usec_to_bin_timer(axdev);
+
+		AX88279_BULKIN_SIZE[index].timer_l = timer & 0xFF;
+		AX88279_BULKIN_SIZE[index].timer_h = (timer >> 8) & 0xFF;
+	}
+
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL,
+				5, 5, &AX88279_BULKIN_SIZE[index]);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int ax88279_link_setting(struct ax_device *axdev)
+{
+	struct ax_link_info *link_info = &axdev->link_info;
+	u16 medium_mode, reg16;
+	u8 reg8[3];
+	int ret;
+
+	reg16 = AX_RX_CTL_STOP;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &reg16);
+	if (ret < 0)
+		return ret;
+
+	reg16 = 0;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_PATH,
+				1, 1, &reg16);
+	if (ret < 0)
+		return ret;
+
+	reg8[0] = 0xA5;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+				AX88179A_MAC_CDC_DELAY_TX, 1, 1, reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8[0] = 0x10;
+	reg8[1] = 0x04;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+				AX_PAUSE_WATERLVL_HIGH, 2, 2, reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8[0] = 0;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+				AX88179A_ETH_TX_GAP, 1, 1, reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8[0] = 0x07;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_EP5_EHR, 1, 1,
+				&reg8);
+	if (ret < 0)
+		return ret;
+
+	medium_mode = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_RXFLOW_CTRLEN |
+		      AX_MEDIUM_TXFLOW_CTRLEN;
+	reg8[0] = 0x28 | AX_NEW_PAUSE_EN;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX88179A_NEW_PAUSE_CTRL,
+			   1, 1, reg8);
+	if (ret < 0)
+		return ret;
+	switch (link_info->eth_speed) {
+	case ETHER_LINK_2500:
+		reg8[0] = 0x00;
+		reg8[1] = 0xF8;
+		reg8[2] = 0x07;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_TX_PAUSE_0, 3, 3, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0x78;
+		reg8[1] = (AX_LSOFC_WCNT_7_ACCESS << 5);
+		reg8[2] = 0;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_RX_STATUS_CDC, 3, 3, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0x40;
+		reg8[1] = AX_MAC_MIQFFCTRL_FORMAT | AX_MAC_MIQFFCTRL_DROP_CRC |
+			  AX_MAC_LSO_ERR_EN;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_RX_DATA_CDC_CNT,
+					2, 2, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = AX_XGMII_EN;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					 AX88179A_BFM_DATA, 1, 1, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = (0x1C) | AX_LSO_ENHANCE_EN;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_LSO_ENHANCE_CTRL, 1, 1,
+					&reg8);
+		if (ret < 0)
+			return ret;
+
+		medium_mode |= AX_MEDIUM_GIGAMODE;
+		break;
+	case ETHER_LINK_1000:
+		reg8[0] = 0x48;
+		reg8[1] = 0xF1;
+		reg8[2] = 0x3E;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					 AX88179A_MAC_TX_PAUSE_0, 3, 3, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0x78;
+		reg8[1] = (AX_LSOFC_WCNT_7_ACCESS << 5);
+		reg8[2] = 0;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_RX_STATUS_CDC, 3, 3, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0x40;
+		reg8[1] = AX_MAC_MIQFFCTRL_FORMAT | AX_MAC_MIQFFCTRL_DROP_CRC |
+			  AX_MAC_LSO_ERR_EN;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_RX_DATA_CDC_CNT,
+					2, 2, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					 AX88179A_BFM_DATA, 1, 1, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_LSO_ENHANCE_CTRL, 1, 1,
+					&reg8);
+		if (ret < 0)
+			return ret;
+
+
+		medium_mode |= AX_MEDIUM_GIGAMODE;
+		break;
+	case ETHER_LINK_100:
+		reg8[0] = 0x90;
+		reg8[1] = 0xE2;
+		reg8[2] = 0x7D;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					 AX88179A_MAC_TX_PAUSE_0, 3, 3, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0x78;
+		reg8[1] = (AX_LSOFC_WCNT_7_ACCESS << 5);
+		reg8[2] = 0;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_RX_STATUS_CDC, 3, 3, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0x40;
+		reg8[1] = AX_MAC_MIQFFCTRL_FORMAT | AX_MAC_MIQFFCTRL_DROP_CRC |
+			  AX_MAC_LSO_ERR_EN;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_RX_DATA_CDC_CNT,
+					2, 2, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_BFM_DATA, 1, 1, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_LSO_ENHANCE_CTRL, 1, 1,
+					&reg8);
+		if (ret < 0)
+			return ret;
+		break;
+	case ETHER_LINK_10:
+		reg8[0] = 0x90;
+		reg8[1] = 0xE2;
+		reg8[2] = 0x7D;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_TX_PAUSE_0, 3, 3, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0xFA;
+		reg8[1] = (AX_LSOFC_WCNT_7_ACCESS << 5);
+		reg8[2] = 0xFF;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_RX_STATUS_CDC, 3, 3, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0xFA;
+		reg8[1] = AX_MAC_MIQFFCTRL_FORMAT | AX_MAC_MIQFFCTRL_DROP_CRC |
+			  AX_MAC_LSO_ERR_EN;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_RX_DATA_CDC_CNT,
+					2, 2, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_BFM_DATA, 1, 1, reg8);
+		if (ret < 0)
+			return ret;
+
+		reg8[0] = 0;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_LSO_ENHANCE_CTRL, 1, 1,
+					&reg8);
+		if (ret < 0)
+			return ret;
+		break;
+	default:
+		break;
+	};
+
+	ret = ax88279_set_bulkin_setting(axdev);
+	if (ret < 0)
+		return ret;
+
+	if (link_info->full_duplex)
+		medium_mode |= AX_MEDIUM_FULL_DUPLEX;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+				2, 2, &medium_mode);
+	if (ret < 0)
+		return ret;
+
+	axdev->rxctl |= AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_CTL_DROPCRCERR;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL,
+				2, 2, &axdev->rxctl);
+	if (ret < 0)
+		return ret;
+
+	reg16 = AX_MAC_RX_PATH_READY | AX_MAC_TX_PATH_READY;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_PATH,
+				1, 1, &reg16);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+#ifdef ENABLE_QUEUE_PRIORITY
+static int ax88279_queue_setting(struct ax_device *axdev)
+{
+	u8 reg8;
+	int ret;
+
+	reg8 = AX_RX_CTL_STOP;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL, 1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = 0;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+				AX88179A_MAC_PATH, 1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	axdev->rxctl |= AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_CTL_DROPCRCERR;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL,
+				2, 2, &axdev->rxctl);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX88279_HIGH_QUEUE_POINT;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+				AX88179A_MAC_QUEUE_POINT, 1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX_TX_QUEUE_SET | AX_TX_QUEUE_CFG;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_BFM_DATA,
+				1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX_MAC_MIQFFCTRL_FORMAT | AX_MAC_MIQFFCTRL_DROP_CRC |
+	       AX_MAC_STOP_EP5_ACCESS | AX_MAC_STOP_EP3_ACCESS |
+	       AX_MAC_LSO_ERR_EN;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+				AX88179A_MAC_BFM_CTRL, 1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX_EP5_DAT_ERROR_HANDLE;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_EP5_EHR,
+				1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	switch (axdev->link_info.eth_speed) {
+	case ETHER_LINK_2500:
+		reg8 = AX_TX_QUEUE_CFG | AX_TX_Q1_AHB_FC_EN |
+		       AX_XGMII_EN | AX_TX_Q2_AHB_FC_EN;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_BFM_DATA, 1, 1, &reg8);
+		if (ret < 0)
+			return ret;
+		break;
+	case ETHER_LINK_1000:
+	case ETHER_LINK_100:
+		reg8 = AX_TX_QUEUE_CFG | AX_TX_Q1_AHB_FC_EN |
+		       AX_TX_Q2_AHB_FC_EN;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_BFM_DATA, 1, 1, &reg8);
+		if (ret < 0)
+			return ret;
+		break;
+	case ETHER_LINK_10:
+		reg8 = 0;
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_MAC_QUEUE_POINT, 1, 1, &reg8);
+		if (ret < 0)
+			return ret;
+
+		ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC,
+					AX88179A_BFM_DATA, 1, 1, &reg8);
+		if (ret < 0)
+			return ret;
+		break;
+	default:
+		break;
+	};
+
+	reg8 = AX_MAC_RX_PATH_READY | AX_MAC_TX_PATH_READY;
+	ret = ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_PATH,
+				1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+#endif
+
+static int ax88279_link_reset(struct ax_device *axdev)
+{
+	int ret;
+
+	ret = ax88279_get_ether_link(axdev);
+	if (ret < 0)
+		return ret;
+
+	ret = ax88279_link_setting(axdev);
+	if (ret < 0)
+		return ret;
+
+#ifdef ENABLE_QUEUE_PRIORITY
+	ret = axdev->driver_info->queue_priority(axdev);
+	if (ret < 0)
+		return ret;
+#endif
+
+#ifdef ENABLE_PTP_FUNC
+	if (axdev->driver_info->ptp_init)
+		axdev->driver_info->ptp_init(axdev);
+#endif
+
+	return 0;
+}
+#endif
+inline void ax88179a_rx_checksum(struct sk_buff *skb, void *pkt_hdr)
+{
+	struct _179a_rx_pkt_header *hdr = (struct _179a_rx_pkt_header *)pkt_hdr;
+
+	skb->ip_summed = CHECKSUM_NONE;
+
+	if ((hdr->L4_err) ||
+	    (hdr->L3_err))
+		return;
+
+	if ((hdr->L4_pkt_type == AX_RXHDR_L4_TYPE_TCP) ||
+	    (hdr->L4_pkt_type == AX_RXHDR_L4_TYPE_UDP))
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+}
+
+static void ax88179a_rx_fixup(struct ax_device *axdev, struct rx_desc *desc,
+			      int *work_done, int budget)
+{
+#ifndef ENABLE_RX_TASKLET
+	struct napi_struct *napi = &axdev->napi;
+#endif
+	struct net_device *netdev = axdev->netdev;
+	struct net_device_stats *stats = ax_get_stats(netdev);
+	struct _179a_rx_pkt_header *pkt_hdr;
+	struct _179a_rx_header *rx_header;
+	const u32 actual_length = desc->urb->actual_length;
+	u8 *rx_data;
+	u32 aa = 0, rx_hdroffset = 0;
+	u16 pkt_count = 0;
+
+	rx_header = (struct _179a_rx_header *)
+		(((u8 *)desc->head) + actual_length - AX88179A_RX_HEADER_SIZE);
+	le64_to_cpus((u64 *)rx_header);
+
+	rx_hdroffset = rx_header->hdr_off;
+	pkt_count = rx_header->pkt_cnt;
+	aa = (actual_length - ((pkt_count + 1) * 8));
+	if (((aa != rx_hdroffset) && ((aa - rx_hdroffset) % 16) != 0) ||
+	    (rx_hdroffset >= desc->urb->actual_length) ||
+	    (pkt_count == 0)) {
+		desc->urb->actual_length = 0;
+		stats->rx_length_errors++;
+		return;
+	}
+
+	pkt_hdr = (struct _179a_rx_pkt_header *)
+			(((u8 *)desc->head) + rx_header->hdr_off);
+
+	rx_data = desc->head;
+	while (pkt_count--) {
+		struct sk_buff *skb;
+		u32 pkt_len = 0;
+
+		le64_to_cpus((u64 *)pkt_hdr);
+
+		if (!pkt_hdr->RxOk) {
+			stats->rx_crc_errors++;
+			if (!(netdev->features & NETIF_F_RXALL))
+				goto find_next_rx;
+		}
+
+		if (pkt_hdr->drop) {
+			stats->rx_dropped++;
+			if (!(netdev->features & NETIF_F_RXALL))
+				goto find_next_rx;
+		}
+
+		pkt_len = (u32)(pkt_hdr->length & 0x7FFF);
+
+#ifdef ENABLE_RX_TASKLET
+		skb = netdev_alloc_skb(netdev, pkt_len);
+#else
+		skb = napi_alloc_skb(napi, pkt_len);
+#endif
+		if (!skb) {
+			stats->rx_dropped++;
+			goto find_next_rx;
+		}
+
+		skb_put(skb, pkt_len);
+		memcpy(skb->data, rx_data, pkt_len);
+		ax88179a_rx_checksum(skb, pkt_hdr);
+
+		skb->truesize = skb->len + sizeof(struct sk_buff);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+		if (pkt_hdr->vlan_ind) {
+				__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+						     pkt_hdr->vlan_tag & VLAN_VID_MASK);
+		}
+#else
+		if (pkt_hdr->vlan_ind) {
+			__vlan_hwaccel_put_tag(skb, pkt_hdr->vlan_tag & VLAN_VID_MASK);
+		}
+#endif
+#ifdef ENABLE_PTP_FUNC
+		if (pkt_hdr->PTP_ind) {
+			ax_rx_get_timestamp(skb, (u64 *)pkt_hdr);
+			pkt_hdr += 2;
+		}
+#endif
+		skb->protocol = eth_type_trans(skb, netdev);
+		if (*work_done < budget) {
+#ifdef ENABLE_RX_TASKLET
+			netif_receive_skb(skb);
+#else
+			napi_gro_receive(napi, skb);
+#endif
+
+			*work_done += 1;
+			stats->rx_packets++;
+			stats->rx_bytes += pkt_len;
+		} else {
+			__skb_queue_tail(&axdev->rx_queue, skb);
+		}
+find_next_rx:
+		rx_data += (pkt_len + 7) & 0x7FFF8;
+		pkt_hdr++;
+	}
+}
+
+static int ax88179a_tx_fixup(struct ax_device *axdev, struct tx_desc *desc)
+{
+	struct sk_buff_head skb_head, *tx_queue;
+	struct net_device_stats *stats = &axdev->netdev->stats;
+	int remain, ret;
+#ifdef ENABLE_QUEUE_PRIORITY
+	int endpoint = (desc->q_index == 1)?5:3;
+#else
+	int endpoint = 3;
+#endif
+	u8 *tx_data;
+
+#ifdef ENABLE_QUEUE_PRIORITY
+	tx_queue = &axdev->tx_queue[desc->q_index];
+#else
+	tx_queue = axdev->tx_queue;
+#endif
+
+	__skb_queue_head_init(&skb_head);
+	spin_lock(&tx_queue->lock);
+	skb_queue_splice_init(tx_queue, &skb_head);
+	spin_unlock(&tx_queue->lock);
+
+	tx_data = desc->head;
+	desc->skb_num = 0;
+	desc->skb_len = 0;
+	remain = axdev->tx_casecade_size;
+
+	while (remain >= (ETH_ZLEN + AX88179A_TX_HEADER_SIZE)) {
+		struct sk_buff *skb;
+		struct _179a_tx_pkt_header *tx_hdr;
+		u16 tci = 0;
+
+		skb = __skb_dequeue(&skb_head);
+		if (!skb)
+			break;
+
+		if ((skb->len + AX88179A_TX_HEADER_SIZE) > remain &&
+		    (skb_shinfo(skb)->gso_size == 0)) {
+			__skb_queue_head(&skb_head, skb);
+			break;
+		}
+
+		tx_hdr = (struct _179a_tx_pkt_header *)tx_data;
+		memset(tx_hdr, 0, AX88179A_TX_HEADER_SIZE);
+		tx_hdr->length = (skb->len & 0x1FFFFF);
+		tx_hdr->checksum = AX88179A_TX_HERDER_CHKSUM(tx_hdr->length);
+		tx_hdr->max_seg_size = skb_shinfo(skb)->gso_size;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
+		if ((axdev->netdev->features & NETIF_F_HW_VLAN_CTAG_TX) &&
+#else
+		if ((axdev->netdev->features & NETIF_F_HW_VLAN_TX) &&
+#endif		   
+			(vlan_get_tag(skb, &tci) >= 0)) {
+			tx_hdr->vlan_tag = 1;
+			tx_hdr->vlan_info = tci;
+		}
+
+		cpu_to_le64s((u64 *)tx_data);
+		tx_data += AX88179A_TX_HEADER_SIZE;
+
+		if (skb_copy_bits(skb, 0, tx_data, skb->len) < 0) {
+			stats->tx_dropped += skb_shinfo(skb)->gso_segs ?: 1;
+			dev_kfree_skb_any(skb);
+			continue;
+		}
+
+		tx_data = __tx_buf_align((void *)(tx_data + skb->len),
+					 axdev->tx_align_len);
+		desc->skb_len += skb->len;
+		desc->skb_num += skb_shinfo(skb)->gso_segs ?: 1;
+#ifdef ENABLE_PTP_FUNC
+		if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+			skb_queue_tail(&axdev->tx_timestamp, skb);
+			set_bit(AX_TX_TIMESTAMPS, &desc->flags);
+		} else {
+			dev_kfree_skb_any(skb);
+		}
+#else
+		dev_kfree_skb_any(skb);
+#endif
+
+		if (tx_hdr->max_seg_size)
+			break;
+
+		remain = axdev->tx_casecade_size -
+			 (int)((void *)tx_data - desc->head);
+	}
+
+	if (!skb_queue_empty(&skb_head)) {
+		spin_lock(&tx_queue->lock);
+		skb_queue_splice(&skb_head, tx_queue);
+		spin_unlock(&tx_queue->lock);
+	}
+
+	netif_tx_lock(axdev->netdev);
+	if (netif_queue_stopped(axdev->netdev) &&
+	    skb_queue_len(tx_queue) < axdev->tx_qlen) {
+		netif_wake_queue(axdev->netdev);
+	}
+	netif_tx_unlock(axdev->netdev);
+
+	ret = usb_autopm_get_interface_async(axdev->intf);
+	if (ret < 0)
+		return ret;
+
+	usb_fill_bulk_urb(desc->urb, axdev->udev,
+			  usb_sndbulkpipe(axdev->udev, endpoint),
+			  desc->head, (int)(tx_data - (u8 *)desc->head),
+			  (usb_complete_t)ax_write_bulk_callback, desc);
+
+	ret = usb_submit_urb(desc->urb, GFP_ATOMIC);
+	if (ret < 0)
+		usb_autopm_put_interface_async(axdev->intf);
+
+#ifdef ENABLE_QUEUE_PRIORITY
+	if (endpoint == 5)
+		axdev->ep5_count++;
+	else
+		axdev->ep3_count++;
+#endif
+
+	return 0;
+}
+
+static int ax88179a_system_suspend(struct ax_device *axdev)
+{
+#ifdef ENABLE_AX88279
+#ifdef ENABLE_PTP_FUNC
+	ax88279_stop_get_ts(axdev);
+#endif
+#endif
+
+	return 0;
+}
+
+static int ax88179a_system_resume(struct ax_device *axdev)
+{
+	int ret;
+
+	if (!ax88179a_check_phy_power(axdev))
+		ax88179a_set_phy_power(axdev, true);
+
+	ret = ax_write_cmd_nopm(axdev, AX_FW_MODE, AX_FW_MODE_179A, 0, 0, NULL);
+	if (ret < 0)
+		return ret;
+
+	axdev->driver_info->hw_init(axdev);
+
+	return 0;
+}
+
+static int ax88179a_runtime_suspend(struct ax_device *axdev)
+{
+	u16 reg16, medium_mode;
+	u8 reg8, loop = 100;
+
+#ifdef ENABLE_AX88279
+#ifdef ENABLE_PTP_FUNC
+	ax88279_stop_get_ts(axdev);
+#endif
+#endif
+	while(loop--) {
+		ax_read_cmd_nopm(axdev, AX_ACCESS_MAC, 0x57, 2, 2, &reg16, 0);
+		if (reg16 >= 0x11FF)
+			break;
+		mdelay(10);
+	};
+	loop = 100;
+	while(loop--) {
+		u8 reg[4];
+		ax_read_cmd_nopm(axdev, AX88179A_USB_DC, 0x1230, 4, 4, reg, 0);
+		if (reg[2] & 0x02)
+			break;
+		mdelay(10);
+	};
+
+	ax_read_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2,
+			 &medium_mode, 0);
+	medium_mode &= ~AX_MEDIUM_RECEIVE_EN;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2,
+			  &medium_mode);
+
+	reg16 = AX_RX_CTL_STOP;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &reg16);
+
+	reg8 = 0x10;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, 0x53, 1, 1, &reg8);
+
+	reg8 = 0;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, 0x53, 1, 1, &reg8);
+
+	reg8 = 0;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_PATH, 1, 1, &reg8);
+
+	reg16 = AX_RX_CTL_START | AX_RX_CTL_AB;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &reg16);
+
+	ax_write_cmd_nopm(axdev, AX8179A_WAKEUP_SETTING, 0, 0, 0, NULL);
+
+	reg16 = AX_RX_CTL_AB;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &reg16);
+
+	reg16 = AX_RX_CTL_START | AX_RX_CTL_AB ;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &reg16);
+
+	ax_read_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MONITOR_MODE, 1, 1, &reg8, 0);
+	reg8 &= 0xE0;
+	reg8 |= AX_MONITOR_MODE_RWLC | AX_MONITOR_MODE_RWMP |
+		AX_MONITOR_MODE_PMETYPE;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MONITOR_MODE, 1, 1, &reg8);
+
+	medium_mode |= AX_MEDIUM_RECEIVE_EN;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2,
+			  &medium_mode);
+
+	return 0;
+}
+
+static int ax88179a_runtime_resume(struct ax_device *axdev)
+{
+	struct ax_link_info *link_info = &axdev->link_info;
+	u16 reg16, medium_mode;
+	u8 reg8;
+
+	if (!ax88179a_check_phy_power(axdev))
+		ax88179a_set_phy_power(axdev, true);
+
+	ax_write_cmd_nopm(axdev, AX_FW_MODE, AX_FW_MODE_179A, 0, 0, NULL);
+
+	ax_read_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2,
+			 &medium_mode, 0);
+	medium_mode &= ~AX_MEDIUM_RECEIVE_EN;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2,
+			  &medium_mode);
+
+	reg8 = 0xFF;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_BM_INT_MASK,
+			  1, 1, &reg8);
+
+	reg8 = 0;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_BM_RX_DMA_CTL,
+			  1, 1, &reg8);
+
+	reg8 = 0;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_BM_TX_DMA_CTL,
+			  1, 1, &reg8);
+
+	reg8 = 0;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_ARC_CTRL,
+			  1, 1, &reg8);
+
+	reg16 = AX_RX_CTL_STOP;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &reg16);
+
+	reg8 = 0;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_PATH, 1, 1, &reg8);
+
+	reg8 = 0;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_SWP_CTRL,
+			  1, 1, &reg8);
+
+	reg16 = AX_RX_CTL_START | AX_RX_CTL_AB;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &reg16);
+
+	reg8 = AX_MAC_RX_PATH_READY | AX_MAC_TX_PATH_READY;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX88179A_MAC_PATH, 1, 1, &reg8);
+
+	if (link_info->eth_speed == ETHER_LINK_1000)
+		medium_mode |= AX_MEDIUM_GIGAMODE;
+	if (link_info->full_duplex)
+		medium_mode |= AX_MEDIUM_FULL_DUPLEX;
+
+	medium_mode |= AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_RXFLOW_CTRLEN |
+		       AX_MEDIUM_TXFLOW_CTRLEN;
+	ax_write_cmd_nopm(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, 2, 2,
+			  &medium_mode);
+
+	return 0;
+}
+
+#ifdef ENABLE_AX88279
+const struct driver_info ax88279_info = {
+	.bind		= ax88179a_bind,
+	.unbind		= ax88179a_unbind,
+	.hw_init	= ax88179a_hw_init,
+	.stop		= ax88179a_stop,
+#ifdef ENABLE_QUEUE_PRIORITY
+	.queue_priority	= ax88279_queue_setting,
+#endif
+	.link_reset	= ax88279_link_reset,
+	.link_setting	= ax88279_link_setting,
+	.rx_fixup	= ax88179a_rx_fixup,
+	.tx_fixup	= ax88179a_tx_fixup,
+	.system_suspend = ax88179a_system_suspend,
+	.system_resume	= ax88179a_system_resume,
+	.runtime_suspend = ax88179a_runtime_suspend,
+	.runtime_resume	= ax88179a_runtime_resume,
+#ifdef ENABLE_PTP_FUNC
+	.ptp_pps_ctrl = ax88279_ptp_pps_ctrl,
+	.ptp_init	= ax88279_ptp_init,
+	.ptp_remove	= ax88279_ptp_remove,
+#endif
+	.napi_weight	= AX88279_NAPI_WEIGHT,
+	.buf_rx_size	= AX88279_BUF_RX_SIZE,
+};
+#endif
+const struct driver_info ax88179a_info = {
+	.bind		= ax88179a_bind,
+	.unbind		= ax88179a_unbind,
+	.hw_init	= ax88179a_hw_init,
+	.stop		= ax88179a_stop,
+#ifdef ENABLE_QUEUE_PRIORITY
+	.queue_priority	= ax88179a_queue_priority,
+#endif
+	.link_reset	= ax88179a_link_reset,
+	.link_setting	= ax88179a_link_setting,
+	.rx_fixup	= ax88179a_rx_fixup,
+	.tx_fixup	= ax88179a_tx_fixup,
+	.system_suspend = ax88179a_system_suspend,
+	.system_resume	= ax88179a_system_resume,
+	.runtime_suspend = ax88179a_runtime_suspend,
+	.runtime_resume	= ax88179a_runtime_resume,
+#ifdef ENABLE_PTP_FUNC
+	.ptp_pps_ctrl = ax88179a_ptp_pps_ctrl,
+	.ptp_init	= ax88179a_ptp_init,
+	.ptp_remove	= ax88179a_ptp_remove,
+#endif
+	.napi_weight	= AX88179A_NAPI_WEIGHT,
+	.buf_rx_size	= AX88179A_BUF_RX_SIZE,
+};
+
+const struct driver_info ax88772d_info = {
+	.bind		= ax88179a_bind,
+	.unbind		= ax88179a_unbind,
+	.hw_init	= ax88179a_hw_init,
+	.stop		= ax88179a_stop,
+#ifdef ENABLE_QUEUE_PRIORITY
+	.queue_priority	= ax88179a_queue_priority,
+#endif
+	.link_reset	= ax88179a_link_reset,
+	.link_setting	= ax88179a_link_setting,
+	.rx_fixup	= ax88179a_rx_fixup,
+	.tx_fixup	= ax88179a_tx_fixup,
+	.system_suspend = ax88179a_system_suspend,
+	.system_resume	= ax88179a_system_resume,
+	.runtime_suspend = ax88179a_runtime_suspend,
+	.runtime_resume	= ax88179a_runtime_resume,
+#ifdef ENABLE_PTP_FUNC
+	.ptp_pps_ctrl = ax88179a_ptp_pps_ctrl,
+	.ptp_init	= ax88179a_ptp_init,
+	.ptp_remove	= ax88179a_ptp_remove,
+#endif
+	.napi_weight	= AX88179A_NAPI_WEIGHT,
+	.buf_rx_size	= AX88179A_BUF_RX_SIZE,
+};
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/ax88179a_772d.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/ax88179a_772d.h
@@ -0,0 +1,246 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*******************************************************************************
+ *     Copyright (c) 2022    ASIX Electronic Corporation    All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+#ifndef __ASIX_AX88179A_772D_H
+#define __ASIX_AX88179A_772D_H
+
+#define AX88179A_BIN_TIMER_UINT		800		//ns
+
+#define AX88179A_NAPI_WEIGHT		64
+#ifdef ENABLE_AX88279
+#define AX88279_NAPI_WEIGHT		256
+#endif
+#define AX88179A_BUF_RX_SIZE		(48 * 1024)
+#ifdef ENABLE_AX88279
+#define AX88279_BUF_RX_SIZE		(48 * 1024)
+#endif
+#define AX88179A_PHY_ID			0x03
+#define AX88179_GPHY_CTRL		0x0F
+	#define AX_GPHY_EEE_CTRL		0x01
+#define AX88179A_HIGH_QUEUE_POINT	0x60
+#ifdef ENABLE_AX88279
+#define AX88279_HIGH_QUEUE_POINT	0x70
+#endif
+#define AX88179A_AUTODETACH_DELAY	(5UL << 8)
+
+#define AX8179A_WAKEUP_SETTING		0x07
+#define AX88179A_PBUS_REG		0x10
+#define AX88179A_ACCESS_BL		0x2A
+#define AX88179A_PHY_CLAUSE45		0x27
+#define AX88179A_PHY_POWER		0x31
+	#define AX_PHY_POWER			0x02
+#define AX88179A_USB_DC			0x81
+#define AX88179A_BOOT_TO_ROM		0x9F
+#define AX88179A_AUTODETACH		0xC0
+
+#define AX88179A_BFM_DATA		0x0E
+	#define AX_TX_QUEUE_CFG			0x02
+	#define AX_TX_QUEUE_SET			0x08
+	#define AX_TX_Q1_AHB_FC_EN		0x10
+	#define AX_TX_Q2_AHB_FC_EN		0x20
+	#define AX_XGMII_EN			0x80
+#define AX88179A_ETH_TX_GAP		0x0D
+#define AX88179A_FLASH_READ		0x21
+#define AX88179A_FLASH_WEN		0x22
+#define AX88179A_FLASH_WDIS		0x23
+#define AX88179A_FLASH_WRITE		0x24
+#define AX88179A_FLASH_EARSE_ALL	0x25
+#define AX88179A_VLAN_ID_CONTROL	0x2B
+	#define AX_VLAN_CONTROL_WE		0x0001
+	#define AX_VLAN_CONTROL_RD		0x0002
+	#define AX_VLAN_CONTROL_VSO		0x0010
+	#define AX_VLAN_CONTROL_VFE		0x0020
+#define AX88179A_MAC_BM_INT_MASK	0x41
+#define AX88179A_MAC_BM_RX_DMA_CTL	0x43
+#define AX88179A_MAC_BM_TX_DMA_CTL	0x46
+#define AX88179A_CLK_EN_ARRAY_1		0x4B
+	#define AX_MAC_MII_TX_25M_EN		0x02
+	#define AX_MAC_RX_25M_EN		0x08
+#define AX88179A_MAC_CLK_SELECT_1	0x4D
+	#define AX_MAC_PCSCLK_MII_TX		0x01
+#define AX88179A_MAC_RX_STATUS_CDC	0x6D
+#define AX88179A_MAC_LSOFC_GMIIPF	0x6E
+	#define AX_GMII_CRC_APPEND		0x10
+	#define AX_LSOFC_WCNT_1_ACCESS		0x00
+	#define AX_LSOFC_WCNT_2_ACCESS		0x01
+	#define AX_LSOFC_WCNT_5_ACCESS		0x02
+	#define AX_LSOFC_WCNT_7_ACCESS		0x03
+#define AX88179A_MAC_RX_FILTER_CTRL	0x6F
+	#define AX_MAC_RX_FILTER_OFT_EN	0x80
+#define AX88179A_MAC_QUEUE_POINT	0x7F
+#define AX88179A_MAC_ARC_CTRL		0x9E
+#define AX88179A_CDC_ECM_CTRL		0xB0
+#define AX88179A_MAC_SWP_CTRL		0xB1
+#define AX88179A_MAC_TX_PAUSE_0		0xB2
+#define AX88179A_MAC_TX_PAUSE_1		0xB3
+#define AX88179A_MAC_TX_PAUSE_2		0xB4
+#define AX88179A_MAC_CDC_DELAY_TX	0xB5
+#define AX88179A_MAC_PATH		0xB7
+	#define AX_MAC_RX_PATH_READY		0x01
+	#define AX_MAC_TX_PATH_READY		0x02
+#define AX88179A_NEW_PAUSE_CTRL		0xB8
+	#define AX_NEW_PAUSE_EN			0x01
+#define AX88179A_MAC_BULK_OUT_CTRL	0xB9
+	#define AX_MAC_EFF_EN			0x02
+#define AX88179A_MAC_RX_DATA_CDC_CNT	0xC0
+#define AX88179A_MAC_BFM_CTRL		0xC1
+	#define AX_MAC_STOP_EP5_ACCESS		0x01
+	#define AX_MAC_STOP_EP3_ACCESS		0x02
+	#define AX_MAC_LSO_ERR_EN		0x04
+	#define AX_MAC_MIQFFCTRL_FORMAT		0x10
+	#define AX_MAC_MIQFFCTRL_DROP_CRC	0x20
+#define AX88179A_MAC_LSO_ENHANCE_CTRL	0xC3
+	#define AX_LSO_ENHANCE_EN		0x01
+#define AX88179A_MAC_TX_HDR_CKSUM	0xCC
+	#define AX_TXHDR_CKSUM_EN		0x01
+	#define AX_TXRX_INDV_RESET_EN		0x02
+#define AX88179A_MAC_CPU_CTRL_MAC_1	0xCE
+	#define AX_RX_INDV_RESET		0x01
+	#define AX_TX_INDV_RESET		0x02
+#define AX88179A_EP5_EHR		0xF9
+	#define AX_EP5_DAT_ERROR_HANDLE		0x80
+#define AX88179A_HW_EC_VERSION		0xFB
+#define AX88179A_SW_REVERSION		0xFC
+	#define AX88179A_FLASH_MODE		0x80
+
+#define PHY_1000M_STS			0x11
+	#define LINK_1000M_OK		0x1000
+#define PHY_100M_STS			0x10
+	#define LINK_100M_OK		0x1000
+#define PHY_10M_STS			0x16
+	#define LINK_10M_OK		0x40
+
+#ifdef ENABLE_AX88279
+#define AX_PBUS_A32			0x11
+
+#define AX_PBUS_REG_BASE_ADDR_HI	0x0013
+#define AX_TX_READY_CTRL		0x1008
+	#define AX_IPG_COUNTER_100M		0x28
+	#define AX_IPG_COUNTER_1G		0x22
+	#define AX_SOF_DELAY_COUNTER_100M	0x1C
+	#define AX_SOF_DELAY_COUNTER_1G		0x06
+	#define AX_VAILD_DELAY_COUNTER_100M	0x0F
+	#define AX_VAILD_DELAY_COUNTER_1G	0x07
+#define AX_MAC_CLK_CTRL			0x3004
+	#define AX_DIVIDE_PTP_CLK_SHIFT		0
+	#define AX_DIVIDE_AES_CLK_SHIFT		8
+	#define AX_PTP_CLK_EN			0x010000
+	#define AX_AES_CLK_EN			0x020000
+	#define AX_PTP_CLK_SELECT_DIVIDE	0x040000
+	#define AX_AES_CLK_SELECT_DIVIDE	0x080000
+	#define AX_XGMAC_TX_CLK_EN		0x100000
+	#define AX_XGMAC_RX_CLK_EN		0x200000
+#endif
+
+struct _179a_rx_pkt_header {
+#ifdef __BIG_ENDIAN
+	u64	reserved	:7,
+		PTP_ind		:1,
+		WUF_ind		:6,
+		WUF_wake	:1,
+		WUF_detect	:1,
+		vlan_tag	:16,
+		drop		:1,
+		length		:15,
+		BMC		:1,
+		reserved2	:3,
+		RxOk		:1,
+		vlan_ind	:1,
+		node_ID_match	:1,
+		TCO_match	:1,
+		CE		:1,
+		L3_pkt_type	:2,
+		L4_pkt_type	:3,
+		L3_err		:1,
+		L4_err		:1;
+#else
+	u64	L4_err		:1,
+		L3_err		:1,
+		L4_pkt_type	:3,
+		L3_pkt_type	:2,
+		CE		:1,
+		TCO_match	:1,
+		node_ID_match	:1,
+		vlan_ind	:1,
+		RxOk		:1,
+		reserved2	:3,
+		BMC		:1,
+		length		:15,
+		drop		:1,
+		vlan_tag	:16,
+		WUF_detect	:1,
+		WUF_wake	:1,
+		WUF_ind		:6,
+		PTP_ind		:1,
+		reserved	:7;
+#endif
+} __packed;
+
+struct _179a_rx_header {
+#ifdef __BIG_ENDIAN
+	u64	rxThroughput: 32,
+		hdr_off	:19,
+		pkt_cnt	:13;
+#else
+	u64	pkt_cnt	:13,
+		hdr_off	:19,
+		rxThroughput: 32;
+#endif
+} __packed;
+#define AX88179A_RX_HEADER_SIZE	sizeof(struct _179a_rx_header)
+
+struct _179a_tx_pkt_header {
+#ifdef __BIG_ENDIAN
+	u64	vlan_info	:16,
+		reserved	:1,
+		max_seg_size	:15,
+		DICF		:1,
+		CPHI		:1,
+		vlan_tag	:1,
+		padding		:1,
+		checksum	:7,
+		length		:21;
+#else
+	u64	length		:21,
+		checksum	:7,
+		padding		:1,
+		vlan_tag	:1,
+		CPHI		:1,
+		DICF		:1,
+		max_seg_size	:15,
+		reserved	:1,
+		vlan_info	:16;
+#endif
+} __packed;
+#define AX88179A_TX_HEADER_SIZE	sizeof(struct _179a_tx_pkt_header)
+
+#define AX88179A_TX_HERDER_CHKSUM(len)  ((tx_hdr->length + \
+					(tx_hdr->length >> 8) + \
+					((tx_hdr->length >> 16) & 0x1F)) & 0x7F)
+
+extern const struct net_device_ops ax88179a_netdev_ops;
+#ifdef ENABLE_AX88279
+extern const struct driver_info ax88279_info;
+#endif
+extern const struct driver_info ax88179a_info;
+extern const struct driver_info ax88772d_info;
+#if KERNEL_VERSION(5, 15, 0) <= LINUX_VERSION_CODE
+int ax88179a_siocdevprivate(struct net_device *netdev, struct ifreq *rq,
+			    void __user *udata, int cmd);
+#endif
+int ax88179a_ioctl(struct net_device *net, struct ifreq *rq, int cmd);
+void ax88179a_set_multicast(struct net_device *net);
+#endif /* End of __ASIX_AX88179A_772D_H */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/ax88179a_ieee.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/ax88179a_ieee.c
@@ -0,0 +1,369 @@
+// SPDX-License-Identifier: GPL-2.0
+/*******************************************************************************
+ *     Copyright (c) 2022    ASIX Electronic Corporation    All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#if NET_INTERFACE == INTERFACE_SCAN
+#include <ifaddrs.h>
+#endif
+#include "ax_ioctl.h"
+
+#define PRINT_IOCTL_FAIL(ret) \
+fprintf(stderr, "%s: ioctl failed. (err: %d)\n", __func__, ret)
+
+#define AX88179A_IOCTL_VERSION \
+"AX88179A/AX88772D Linux IEEE Test Tool v1.0.0"
+
+const char help_str1[] =
+"./ax88179a_772d_ieee help [command]\n"
+"    -- command description\n";
+const char help_str2[] =
+"        [command] - Display usage of specified command\n";
+
+const char ieeetest_str1[] =
+"./ax88179a_772d_ieee ieeetest [speed] [option]\n"
+"    -- AX88179A_772D IEEE Test Tool\n";
+const char ieeetest_str2[] =
+"        [speed]    - 1000: 1000Mbps,  100: 100Mbps,  10: 10Mbps\n"
+"        [option]   - For 1000Mbps\n"
+"			M1: Mode 1\n"
+"			M2: Mode 2\n"
+"			M3: Mode 3\n"
+"			M4: Mode 4\n\n"
+"		    - For 100Mbps\n"
+"			CA: Channel A\n"
+"			CB: Channel B\n\n"
+"		    - For 10Mbps\n"
+"			RP: Random Pattern\n"
+"			FF: Fixed Pattern(FF)\n"
+"			MDI: MDI\n\n";
+
+static int help_func(struct ax_command_info *info);
+static int ieeetest_func(struct ax_command_info *info);
+static int scan_ax_device(struct ifreq *ifr, int inet_sock);
+
+struct _command_list ax88179a_cmd_list[] = {
+	{
+		"help",
+		AX_SIGNATURE,
+		help_func,
+		help_str1,
+		help_str2
+	},
+	{
+		"ieeetest",
+		AX88179A_READ_VERSION,
+		ieeetest_func,
+		ieeetest_str1,
+		ieeetest_str2
+	},
+	{NULL},
+};
+
+#pragma pack(push)
+#pragma pack(1)
+#pragma pack(pop)
+
+static void show_usage(void)
+{
+	int i;
+
+	printf("Usage:\n");
+	for (i = 0; ax88179a_cmd_list[i].cmd != NULL; i++)
+		printf("%s\n", ax88179a_cmd_list[i].help_ins);
+}
+
+static unsigned long STR_TO_U32(const char *cp, char **endp, unsigned int base)
+{
+	unsigned long result = 0, value;
+
+	if (*cp == '0') {
+		cp++;
+		if ((*cp == 'x') && isxdigit(cp[1])) {
+			base = 16;
+			cp++;
+		}
+		if (!base)
+			base = 8;
+	}
+	if (!base)
+		base = 10;
+
+	while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
+	    ? toupper(*cp) : *cp)-'A'+10) < base) {
+		result = result*base + value;
+		cp++;
+	}
+	if (endp)
+		*endp = (char *)cp;
+
+	return result;
+}
+
+static int help_func(struct ax_command_info *info)
+{
+	int i;
+
+	if (info->argv[2] == NULL)
+		return -FAIL_INVALID_PARAMETER;
+
+	for (i = 0; ax88179a_cmd_list[i].cmd != NULL; i++) {
+		if (strncmp(info->argv[2],
+			    ax88179a_cmd_list[i].cmd,
+			    strlen(ax88179a_cmd_list[i].cmd)) == 0) {
+			printf("%s%s\n", ax88179a_cmd_list[i].help_ins,
+			       ax88179a_cmd_list[i].help_desc);
+			return -FAIL_INVALID_PARAMETER;
+		}
+	}
+
+	return SUCCESS;
+}
+
+static int ieeetest_func(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	int ret;
+
+	if (info->argc != 4) {
+		int i;
+
+		for (i = 0; ax88179a_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88179a_cmd_list[i].cmd,
+				    strlen(ax88179a_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88179a_cmd_list[i].help_ins,
+				       ax88179a_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	if (!strcmp(info->argv[2], "1000") && strlen(info->argv[2]) == 4) {
+		ioctl_cmd.ieee.speed = 1000;
+		if (!strcmp(info->argv[3], "M1")) {
+			printf("Test item: 1000M M1\n");
+			ioctl_cmd.ieee.type = IEEE_1000M1;
+		} else if (!strcmp(info->argv[3], "M2")) {
+			printf("Test item: 1000M M2\n");
+			ioctl_cmd.ieee.type = IEEE_1000M2;
+		} else if (!strcmp(info->argv[3], "M3")) {
+			printf("Test item: 1000M M3\n");
+			ioctl_cmd.ieee.type = IEEE_1000M3;
+		} else if (!strcmp(info->argv[3], "M4")) {
+			printf("Test item: 1000M M4\n");
+			ioctl_cmd.ieee.type = IEEE_1000M4;
+		} else {
+			printf("Invalid option\n");
+			return -FAIL_IVALID_VALUE;
+		}
+	} else if (!strcmp(info->argv[2], "100") &&
+		   strlen(info->argv[2]) == 3) {
+		ioctl_cmd.ieee.speed = 100;
+		if (!strcmp(info->argv[3], "CA")) {
+			printf("Test item: 100M Channel A\n");
+			ioctl_cmd.ieee.type = IEEE_100CA;
+		} else if (!strcmp(info->argv[3], "CB")) {
+			printf("Test item: 100M Channel B\n");
+			ioctl_cmd.ieee.type = IEEE_100CB;
+		} else {
+			printf("Invalid option\n");
+			return -FAIL_IVALID_VALUE;
+		}
+	} else if (!strcmp(info->argv[2], "10") &&
+		   strlen(info->argv[2]) == 2) {
+		ioctl_cmd.ieee.speed = 10;
+		if (!strcmp(info->argv[3], "RP")) {
+			printf("Test item: 10M Random Pattern\n");
+			ioctl_cmd.ieee.type = IEEE_10R;
+		} else if (!strcmp(info->argv[3], "FF")) {
+			printf("Test item: 10M Fixed Pattern(FF)\n");
+			ioctl_cmd.ieee.type = IEEE_10FF;
+		} else if (!strcmp(info->argv[3], "MDI")) {
+			printf("Test item: 10M MDI\n");
+			ioctl_cmd.ieee.type = IEEE_10MDI;
+		} else {
+			printf("Invalid option\n");
+			return -FAIL_IVALID_VALUE;
+		}
+	} else {
+		int i;
+
+		for (i = 0; ax88179a_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88179a_cmd_list[i].cmd,
+				    strlen(ax88179a_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88179a_cmd_list[i].help_ins,
+				       ax88179a_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	ioctl_cmd.ieee.stop = 0;
+
+	ioctl_cmd.ioctl_cmd = AX88179A_IEEE_TEST;
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+	ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		return -FAIL_IOCTL;
+	}
+
+	printf("Press Enter to stop testing...");
+	getchar();
+
+	ioctl_cmd.ieee.stop = 1;
+	ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		if (ioctl_cmd.ieee.status == -ERR_IEEE_INVALID_CHIP)
+			printf("Invalid speed and chip\n");
+		return -FAIL_IOCTL;
+	}
+
+	printf("Test completely\n");
+	return SUCCESS;
+}
+
+static int scan_ax_device(struct ifreq *ifr, int inet_sock)
+{
+	unsigned int retry;
+
+	for (retry = 0; retry < SCAN_DEV_MAX_RETRY; retry++) {
+		unsigned int i;
+		struct _ax_ioctl_command ioctl_cmd;
+#if NET_INTERFACE == INTERFACE_SCAN
+		struct ifaddrs *addrs, *tmp;
+		unsigned char	dev_exist;
+
+		getifaddrs(&addrs);
+		tmp = addrs;
+		dev_exist = 0;
+
+		while (tmp) {
+			memset(&ioctl_cmd, 0,
+			       sizeof(struct _ax_ioctl_command));
+			ioctl_cmd.ioctl_cmd = AX_SIGNATURE;
+
+			sprintf(ifr->ifr_name, "%s", tmp->ifa_name);
+
+			ifr->ifr_data = (caddr_t)&ioctl_cmd;
+			tmp = tmp->ifa_next;
+
+
+			if (ioctl(inet_sock, AX_PRIVATE, ifr) < 0)
+				continue;
+
+			if (strncmp(ioctl_cmd.sig,
+				    AX88179A_DRV_NAME,
+				    strlen(AX88179A_DRV_NAME)) == 0) {
+				dev_exist = 1;
+				break;
+			}
+		}
+
+		freeifaddrs(addrs);
+
+		if (dev_exist)
+			break;
+#else
+		for (i = 0; i < 255; i++) {
+
+			memset(&ioctl_cmd, 0,
+			       sizeof(struct _ax_ioctl_command));
+			ioctl_cmd.ioctl_cmd = AX_SIGNATURE;
+
+			sprintf(ifr->ifr_name, "eth%u", i);
+
+			ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+			if (ioctl(inet_sock, AX_PRIVATE, ifr) < 0)
+				continue;
+
+			if (strncmp(ioctl_cmd.sig,
+				    AX88179A_DRV_NAME,
+				    strlen(AX88179A_DRV_NAME)) == 0)
+				break;
+
+		}
+
+		if (i < 255)
+			break;
+#endif
+		usleep(500000);
+	}
+
+	if (retry >= SCAN_DEV_MAX_RETRY)
+		return -FAIL_SCAN_DEV;
+
+	return SUCCESS;
+}
+
+int main(int argc, char **argv)
+{
+	struct ifreq ifr;
+	struct ax_command_info info;
+	unsigned int i;
+	int inet_sock, ret;
+
+	printf("%s\n", AX88179A_IOCTL_VERSION);
+
+	if (argc < 2) {
+		show_usage();
+		return SUCCESS;
+	}
+
+	inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
+
+	if (scan_ax_device(&ifr, inet_sock)) {
+		printf("No %s found\n", AX88179A_SIGNATURE);
+		return FAIL_SCAN_DEV;
+	}
+
+	for (i = 0; ax88179a_cmd_list[i].cmd != NULL; i++) {
+		if (strncmp(argv[1],
+			    ax88179a_cmd_list[i].cmd,
+			    strlen(ax88179a_cmd_list[i].cmd)) == 0) {
+			info.help_ins = ax88179a_cmd_list[i].help_ins;
+			info.help_desc = ax88179a_cmd_list[i].help_desc;
+			info.ifr = &ifr;
+			info.argc = argc;
+			info.argv = argv;
+			info.inet_sock = inet_sock;
+			info.ioctl_cmd = ax88179a_cmd_list[i].ioctl_cmd;
+			ret = (ax88179a_cmd_list[i].OptFunc)(&info);
+			goto out;
+		}
+	}
+
+	if (ax88179a_cmd_list[i].cmd == NULL) {
+		printf("%u\n", i);
+		show_usage();
+		return SUCCESS;
+	}
+out:
+	if (ret == SUCCESS)
+		printf("SUCCESS\n");
+	else if (ret != -FAIL_INVALID_PARAMETER)
+		printf("FAIL\n");
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/ax88179a_programmer.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/ax88179a_programmer.c
@@ -0,0 +1,1532 @@
+// SPDX-License-Identifier: GPL-2.0
+/*******************************************************************************
+ *     Copyright (c) 2022    ASIX Electronic Corporation    All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <getopt.h>
+#include <endian.h>
+#if NET_INTERFACE == INTERFACE_SCAN
+#include <ifaddrs.h>
+#endif
+#include "ax_ioctl.h"
+#ifdef ENABLE_IOCTL_DEBUG
+#define NOT_PROGRAM
+#endif
+#define RELOAD_DELAY_TIME	10	// sec
+
+#define PRINT_IOCTL_FAIL(ret) \
+fprintf(stderr, "%s: ioctl failed. (err: %d)\n", __func__, ret)
+#define PRINT_SCAN_DEV_FAIL \
+fprintf(stderr, "%s: Scaning device failed.\n", __func__)
+#define PRINT_ALLCATE_MEM_FAIL \
+fprintf(stderr, "%s: Fail to allocate memory.\n", __func__)
+#define PRINT_LOAD_FILE_FAIL \
+fprintf(stderr, "%s: Read file failed.\n", __func__)
+
+#define AX88179A_IOCTL_VERSION \
+"AX88179B/AX88179A/AX88772E/AX88772D Linux Flash/eFuse Programming Tool v2.0.0"
+
+const char help_str1[] =
+"./ax88179b_179a_772e_772d_programmer help [command]\n"
+"    -- command description\n";
+const char help_str2[] =
+"        [command] - Display usage of specified command\n";
+
+const char readverion_str1[] =
+"./ax88179b_179a_772e_772d_programmer rversion\n"
+"    -- AX88179B_179A_772E_772D Read Firmware Verion\n";
+static const char readverion_str2[] = "";
+
+const char readmac_str1[] =
+"./ax88179b_179a_772e_772d_programmer rmacaddr\n"
+"    -- AX88179B_179A_772E_772D Read MAC Address\n";
+static const char readmac_str2[] = "";
+
+const char writeflash_str1[] =
+"./ax88179b_179a_772e_772d_programmer wflash [file]\n"
+"    -- AX88179B_179A_772E_772D Write Flash\n";
+const char writeflash_str2[] =
+"        [file]    - Flash file path\n";
+
+const char writeefuse_str1[] =
+"./ax88179b_179a_772e_772d_programmer wefuse -m [MAC] -s [SN] -f [File] --led0 [value]"
+" --led1 [value] -p [device]\n"
+"    -- AX88179B_179A_772E_772D Write eFuse\n";
+const char writeefuse_str2[] =
+"        -m [MAC]    - MAC address (XX:XX:XX:XX:XX:XX)\n"
+"        -s [SN]     - Serial number\n"
+"        -f [File]   - eFuse file path\n"
+"        --led0 [value]   - value: control_blink (XXXX_XXXX)\n"
+"        --led1 [value]   - value: control_blink (XXXX_XXXX)\n"
+"        -p [device] - device: \"AX88179B\" or \"AX88179A\" or \"AX88772E\" or \"AX88772D\"\n";
+
+const char readefuse_str1[] =
+"./ax88179b_179a_772e_772d_programmer refuse -f [File]\n"
+"    -- AX88179B_179A_772E_772D Read eFuse\n";
+const char readefuse_str2[] =
+"        -f [File]   - eFuse file path\n";
+
+const char reload_str1[] =
+"./ax88179b_179a_772e_772d_programmer reload\n"
+"    -- AX88179B_179A_772E_772D Reload\n";
+static const char reload_str2[] = "";
+
+static int help_func(struct ax_command_info *info);
+static int readversion_func(struct ax_command_info *info);
+static int readmac_func(struct ax_command_info *info);
+static int writeflash_func(struct ax_command_info *info);
+static int writeefuse_func(struct ax_command_info *info);
+static int readefuse_func(struct ax_command_info *info);
+static int reload_func(struct ax_command_info *info);
+static int scan_ax_device(struct ifreq *ifr, int inet_sock);
+
+struct _command_list ax88179a_cmd_list[] = {
+	{
+		"help",
+		AX_SIGNATURE,
+		help_func,
+		help_str1,
+		help_str2
+	},
+	{
+		"rversion",
+		AX88179A_READ_VERSION,
+		readversion_func,
+		readverion_str1,
+		readverion_str2
+	},
+	{
+		"rmacaddr",
+		~0,
+		readmac_func,
+		readmac_str1,
+		readmac_str2
+	},
+	{
+		"wflash",
+		AX88179A_WRITE_FLASH,
+		writeflash_func,
+		writeflash_str1,
+		writeflash_str2
+	},
+	{
+		"wefuse",
+		AX88179A_PROGRAM_EFUSE,
+		writeefuse_func,
+		writeefuse_str1,
+		writeefuse_str2
+	},
+	{
+		"refuse",
+		AX88179A_DUMP_EFUSE,
+		readefuse_func,
+		readefuse_str1,
+		readefuse_str2
+	},
+	{
+		"reload",
+		~0,
+		reload_func,
+		reload_str1,
+		reload_str2
+	},
+	{
+		NULL,
+		0,
+		NULL,
+		NULL,
+		NULL
+	}
+};
+
+static unsigned char sample_type1[] = {
+ 0x01, 0x0B, 0x95, 0x17,
+ 0x90, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x0A, 0x07, 0xFF,
+ 0x17, 0x32, 0x20, 0x00
+};
+
+static unsigned char sample_type4[] = {
+ 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
+
+static unsigned char sample_type11[] = {
+ 0x0B, 0x1F, 0x00, 0x00,
+ 0x00, 0x00, 0x1F, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x45, 0x00
+};
+
+#pragma pack(push)
+#pragma pack(1)
+enum _ef_Type_Def {
+	EF_TYPE_REV = 0x00,
+	EF_TYPE_01 = 0x01,
+	EF_TYPE_04 = 0x04,
+	EF_TYPE_11 = 0x0B,
+};
+struct _ef_type {
+#if __BYTE_ORDER == __BIG_ENDIAN
+	unsigned char	checksum: 4;
+	unsigned char	type	: 4;
+#else
+	unsigned char	type	: 4;
+	unsigned char	checksum: 4;
+#endif
+};
+
+struct _ef_type01 {
+	struct _ef_type	type;
+	unsigned short	vid;
+	unsigned short	pid;
+	unsigned char	mac[6];
+	unsigned short	bcdDevice;
+	unsigned char	bU1DevExitLat;
+	unsigned short	wU2DevExitLat;
+	unsigned char	SS_Max_Bus_Pw;
+	unsigned char	HS_Max_Bus_Pw;
+	unsigned char	IPSleep_Polling_Count;
+	unsigned char	reserve;
+};
+#define EF_TYPE_STRUCT_SIZE_01	sizeof(struct _ef_type01)
+
+struct _ef_type04 {
+	struct _ef_type	type;
+	unsigned char	serial[18];
+	unsigned char	reserve;
+};
+#define EF_TYPE_STRUCT_SIZE_04	sizeof(struct _ef_type04)
+
+struct _ef_type11 {
+	struct _ef_type	type;
+	unsigned char	dev_type0;
+	unsigned short	reg0;
+	unsigned short	value0;
+	unsigned char	dev_type1;
+	unsigned short	reg1;
+	unsigned short	value1;
+	unsigned char	dev_type2;
+	unsigned short	reg2;
+	unsigned short	value2;
+	unsigned char	reserved1[2];
+	unsigned char	subtype;
+	unsigned char	reserved2;
+};
+#define EF_TYPE_STRUCT_SIZE_11	sizeof(struct _ef_type11)
+
+struct _ef_data_struct {
+	union {
+		struct _ef_type01 type01;
+		struct _ef_type04 type04;
+		struct _ef_type11 type11;
+	} ef_data;
+};
+#define EF_DATA_STRUCT_SIZE	sizeof(struct _ef_data_struct)
+#pragma pack(pop)
+
+static void show_usage(void)
+{
+	int i;
+
+	printf("Usage:\n");
+	for (i = 0; ax88179a_cmd_list[i].cmd != NULL; i++)
+		printf("%s\n", ax88179a_cmd_list[i].help_ins);
+}
+
+static unsigned long STR_TO_U32(const char *cp, char **endp, unsigned int base)
+{
+	unsigned long result = 0, value;
+
+	if (*cp == '0') {
+		cp++;
+		if ((*cp == 'x') && isxdigit(cp[1])) {
+			base = 16;
+			cp++;
+		}
+		if (!base)
+			base = 8;
+	}
+	if (!base)
+		base = 10;
+
+	while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
+	    ? toupper(*cp) : *cp)-'A'+10) < base) {
+		result = result*base + value;
+		cp++;
+	}
+	if (endp)
+		*endp = (char *)cp;
+
+	return result;
+}
+
+static int help_func(struct ax_command_info *info)
+{
+	int i;
+
+	if (info->argv[2] == NULL)
+		return -FAIL_INVALID_PARAMETER;
+
+	for (i = 0; ax88179a_cmd_list[i].cmd != NULL; i++) {
+		if (strncmp(info->argv[2],
+			    ax88179a_cmd_list[i].cmd,
+			    strlen(ax88179a_cmd_list[i].cmd)) == 0) {
+			printf("%s%s\n", ax88179a_cmd_list[i].help_ins,
+			       ax88179a_cmd_list[i].help_desc);
+			return -FAIL_INVALID_PARAMETER;
+		}
+	}
+
+	return SUCCESS;
+}
+
+static int autosuspend_enable(struct ax_command_info *info,
+			      unsigned char enable)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	int ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_AUTOSUSPEND_EN;
+
+	ioctl_cmd.autosuspend.enable = enable;
+
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		return -FAIL_IOCTL;
+	}
+
+	return SUCCESS;
+}
+
+static int read_version(struct ax_command_info *info, char *version)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	int ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_READ_VERSION;
+
+	memset(ioctl_cmd.version.version, 0, 16);
+
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		return -FAIL_IOCTL;
+	}
+
+	memcpy(version, ioctl_cmd.version.version, 16);
+
+	return SUCCESS;
+}
+
+static int read_mac_address(struct ax_command_info *info, unsigned char *mac)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	int ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ret = scan_ax_device(ifr, info->inet_sock);
+	if (ret < 0) {
+		PRINT_SCAN_DEV_FAIL;
+		return ret;
+	}
+
+	ifr->ifr_flags &= 0;
+	ret = ioctl(info->inet_sock, SIOCSIFFLAGS, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		return ret;
+	}
+
+	usleep(20000);
+
+	ifr->ifr_flags = IFF_UP | IFF_BROADCAST | IFF_MULTICAST;
+	ret = ioctl(info->inet_sock, SIOCSIFFLAGS, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		return ret;
+	}
+
+	usleep(20000);
+
+	ret = ioctl(info->inet_sock, SIOCGIFHWADDR, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		return ret;
+	}
+
+	memcpy(mac, ifr->ifr_hwaddr.sa_data, 6);
+
+	return SUCCESS;
+}
+
+static int readversion_func(struct ax_command_info *info)
+{
+	char version[16] = {0};
+	int i, ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	if (info->argc != 2) {
+		for (i = 0; ax88179a_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88179a_cmd_list[i].cmd,
+				    strlen(ax88179a_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88179a_cmd_list[i].help_ins,
+				       ax88179a_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	autosuspend_enable(info, 0);
+
+	ret = read_version(info, version);
+	if (ret == SUCCESS)
+		printf("Firmware Version: %s\n", version);
+
+	usleep(20000);
+
+	autosuspend_enable(info, 1);
+
+	return ret;
+}
+
+static int readmac_func(struct ax_command_info *info)
+{
+	unsigned char mac[6] = {0};
+	int i, ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	if (info->argc != 2) {
+		for (i = 0; ax88179a_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88179a_cmd_list[i].cmd,
+				    strlen(ax88179a_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88179a_cmd_list[i].help_ins,
+				       ax88179a_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	ret = read_mac_address(info, mac);
+	if (ret == SUCCESS)
+		printf("MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
+			mac[0],
+			mac[1],
+			mac[2],
+			mac[3],
+			mac[4],
+			mac[5]);
+
+	return ret;
+}
+
+static int write_flash(struct ax_command_info *info, unsigned char *data,
+		       unsigned long offset, unsigned long len)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	int ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_WRITE_FLASH;
+	ioctl_cmd.flash.status = 0;
+	ioctl_cmd.flash.offset = offset;
+	ioctl_cmd.flash.length = len;
+	ioctl_cmd.flash.buf = data;
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+	if (ret < 0) {
+		if (ioctl_cmd.flash.status)
+			fprintf(stderr, "FLASH WRITE status: %d",
+				ioctl_cmd.flash.status);
+		PRINT_IOCTL_FAIL(ret);
+		return ret;
+	}
+
+	return SUCCESS;
+}
+
+static int read_flash(struct ax_command_info *info, unsigned char *data,
+		      unsigned long offset, unsigned long len)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	int ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_READ_FLASH;
+	ioctl_cmd.flash.status = 0;
+	ioctl_cmd.flash.offset = offset;
+	ioctl_cmd.flash.length = len;
+	ioctl_cmd.flash.buf = data;
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+	if (ret < 0) {
+		if (ioctl_cmd.flash.status)
+			fprintf(stderr, "FLASH READ status: %d",
+				ioctl_cmd.flash.status);
+		PRINT_IOCTL_FAIL(ret);
+		return -FAIL_IOCTL;
+	}
+
+	return SUCCESS;
+}
+
+static int erase_flash(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	int ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_ERASE_FLASH;
+	ioctl_cmd.flash.status = 0;
+
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		return -FAIL_IOCTL;
+	}
+
+	return SUCCESS;
+}
+
+static int boot_to_rom(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_ROOT_2_ROM;
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+	ioctl(info->inet_sock, AX_PRIVATE, ifr);
+
+	return SUCCESS;
+}
+
+static int sw_reset(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_SW_RESET;
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+	ioctl(info->inet_sock, AX_PRIVATE, ifr);
+
+	usleep(RELOAD_DELAY_TIME * 1000000);
+
+	return SUCCESS;
+}
+
+static int writeflash_func(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	unsigned char *wbuf = NULL, *rbuf = NULL;
+	FILE *pFile = NULL;
+	size_t result;
+	int length = 0;
+	int i, offset, len, ret;
+	char fw_version[16] = {0};
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	if (info->argc != 3) {
+		for (i = 0; ax88179a_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88179a_cmd_list[i].cmd,
+				    strlen(ax88179a_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88179a_cmd_list[i].help_ins,
+				       ax88179a_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	autosuspend_enable(info, 0);
+
+	boot_to_rom(info);
+
+	usleep(1000000);
+
+	ret = scan_ax_device(ifr, info->inet_sock);
+	if (ret < 0) {
+		PRINT_SCAN_DEV_FAIL;
+		return ret;
+	}
+
+	ret = erase_flash(info);
+	if (ret < 0) 
+		return ret;
+
+	pFile = fopen(info->argv[2], "rb");
+	if (pFile == NULL) {
+		fprintf(stderr, "%s: Fail to open %s file.\n",
+			__func__, info->argv[2]);
+		ret = -FAIL_LOAD_FILE;
+		goto fail;
+	}
+
+	fseek(pFile, 0, SEEK_END);
+	length = ftell(pFile);
+	fseek(pFile, 0, SEEK_SET);
+
+	wbuf = (unsigned char *)malloc((length + 256) & ~(0xFF));
+	if (!wbuf) {
+		PRINT_ALLCATE_MEM_FAIL;
+		ret = -FAIL_ALLCATE_MEM;
+		goto fail;
+	}
+	memset(wbuf, 0, (length + 256) & ~(0xFF));
+	rbuf = (unsigned char *)malloc((length + 256) & ~(0xFF));
+	if (!rbuf) {
+		PRINT_ALLCATE_MEM_FAIL;
+		ret = -FAIL_ALLCATE_MEM;
+		goto fail;
+	}
+	memset(rbuf, 0, (length + 256) & ~(0xFF));
+
+	result = fread(wbuf, 1, length, pFile);
+	if (result != length) {
+		PRINT_LOAD_FILE_FAIL;
+		ret = -PRINT_LOAD_FILE_FAIL;
+		goto fail;
+	}
+
+	offset = SWAP_32(*(unsigned long *)&wbuf[4]);
+	len = (SWAP_32(*(unsigned long *)&wbuf[8]) + 256) & ~(0xFF);
+
+	sprintf(fw_version, "v%d.%d.%d",
+		wbuf[offset + 0x1000],
+		wbuf[offset + 0x1001],
+		wbuf[offset + 0x1002]);
+	printf("File FW Version: %s\n", fw_version);
+
+	ret = write_flash(info, wbuf, offset, len);
+	if (ret < 0)
+		goto fail;
+
+	ret = read_flash(info, rbuf, offset, len);
+	if (ret < 0)
+		goto fail;
+
+	if (memcmp(&wbuf[offset], &rbuf[offset], len) != 0) {
+		fprintf(stderr, "%s: Program the FW failed.\n", __func__);
+		ret = -FAIL_FLASH_WRITE;
+		goto fail;
+	}
+
+	len = SWAP_32(*(unsigned long *)&wbuf[4]);
+
+	ret = write_flash(info, wbuf, 0, len);
+	if (ret < 0)
+		goto fail;
+
+	ret = read_flash(info, rbuf, 0, (length + 256) & ~(0xFF));
+	if (ret < 0)
+		goto fail;
+
+	if (memcmp(wbuf, rbuf,
+		   (SWAP_32(*(unsigned long *)&wbuf[8]) +
+		    SWAP_32(*(unsigned long *)&wbuf[4]))) != 0) {
+		fprintf(stderr, "%s: Program the Flash failed.\n", __func__);
+		ret = -FAIL_FLASH_WRITE;
+		goto fail;
+	}
+
+	ret = SUCCESS;
+	goto out;
+fail:
+	erase_flash(info);
+out:
+	if (rbuf)
+		free(rbuf);
+	if (wbuf)
+		free(wbuf);
+	if (pFile)
+		fclose(pFile);
+
+	autosuspend_enable(info, 1);
+
+	return ret;
+}
+
+#define EFUSE_NUM_BLOCK	32
+
+static void checksum_efuse_block(unsigned char *block)
+{
+	unsigned int Sum = 0;
+	int j;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (j = 0; j < 4; j++) {
+		if (j == 0)
+			Sum += block[j] & 0xF;
+		else
+			Sum += block[j];
+	}
+
+	while (Sum > 0xF)
+		Sum = (Sum & 0xF) + (Sum >> 4);
+
+	Sum = 0xF - Sum;
+
+	block[0] = (block[0] & 0xF) | ((Sum << 4) & 0xF0);
+}
+
+static int __find_efuse_index(struct _ef_data_struct *efuse,
+			      enum _ef_Type_Def type)
+{
+	int i;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (i = 5; i < EFUSE_NUM_BLOCK; i++) {
+		if (efuse[i].ef_data.type01.type.type == type)
+			return i;
+	}
+
+	return -FAIL_GENERIAL_ERROR;
+}
+
+static int change_mac_address(struct _ef_data_struct *efuse, unsigned int *mac)
+{
+	int index, i;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	index = __find_efuse_index(efuse, EF_TYPE_01);
+	if (index == -FAIL_GENERIAL_ERROR) {
+		fprintf(stderr, "%s: Not found type 1 from eFuese file\n",
+			__func__);
+		return -FAIL_GENERIAL_ERROR;
+	}
+
+	for (i = 0; i < 6; i++)
+		efuse[index].ef_data.type01.mac[i] = (unsigned char)mac[i];
+	checksum_efuse_block((unsigned char *)&efuse[index]);
+
+	return SUCCESS;
+}
+
+static int change_serial_number(struct _ef_data_struct *efuse, char *serial)
+{
+	int index;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	index = __find_efuse_index(efuse, EF_TYPE_04);
+	if (index == -FAIL_GENERIAL_ERROR) {
+		fprintf(stderr, "%s: Not found type 4 from eFuese file\n",
+			__func__);
+		return -FAIL_GENERIAL_ERROR;
+	}
+
+	memset(efuse[index].ef_data.type04.serial, 0, 18);
+	memcpy(efuse[index].ef_data.type04.serial, serial, strlen(serial));
+	checksum_efuse_block((unsigned char *)&efuse[index]);
+
+	return SUCCESS;
+}
+
+static void set_led(struct _ef_data_struct *efuse, char *led, int led_num)
+{
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	memcpy(efuse, sample_type11, EF_TYPE_STRUCT_SIZE_11);
+
+	efuse->ef_data.type11.reg0 = htobe16(0x0024 + (led_num << 1));
+	efuse->ef_data.type11.reg1 = htobe16(0x0025 + (led_num << 1));
+
+	led[4] = '\0';
+	efuse->ef_data.type11.value0 = htobe16(strtol(led, NULL, 16));
+	efuse->ef_data.type11.value1 = htobe16(strtol(&led[5], NULL, 16));
+
+	checksum_efuse_block((unsigned char *)efuse);
+}
+
+static int load_efuse_from_file(char *file_path, unsigned char *data)
+{
+	FILE *pFile = NULL;
+	int i, j;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	if (!file_path)
+		return -FAIL_LOAD_FILE;
+
+	pFile = fopen(file_path, "rb");
+	if (pFile == NULL) {
+		fprintf(stderr, "%s: Fail to open %s file.\n",
+			__func__, file_path);
+		return -FAIL_LOAD_FILE;
+	}
+
+	for (i = 0; i < (20 * EFUSE_NUM_BLOCK); i += 4) {
+		unsigned int size = 0;
+
+		for (j = 3; j >= 0; j--) {
+			unsigned int tmp;
+
+			size = fscanf(pFile, "%02X ", &tmp);
+			if (size == ~0)
+				break;
+			data[i + j] = tmp & 0xFF;
+		}
+		if (size == ~0)
+			break;
+	}
+
+	if (pFile)
+		fclose(pFile);
+
+	return SUCCESS;
+}
+
+static int __dump_efuse(struct ax_command_info *info,
+			struct _ef_data_struct *efuse,
+			int block_offset, int block_num)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	int i, limit = (block_offset + block_num);
+	struct _ax_ioctl_command ioctl_cmd;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	if (limit > EFUSE_NUM_BLOCK) {
+		fprintf(stderr, "%s: Invalid dump block size\n", __func__);
+		return -FAIL_IVALID_VALUE;
+	}
+
+	if (scan_ax_device(ifr, info->inet_sock)) {
+		PRINT_SCAN_DEV_FAIL;
+		return -FAIL_SCAN_DEV;
+	}
+
+	ioctl_cmd.ioctl_cmd = AX88179A_DUMP_EFUSE;
+	ioctl_cmd.flash.length = 20;
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	for (i = block_offset; i < limit; i++) {
+		int ret;
+
+		ioctl_cmd.flash.status = 0;
+		ioctl_cmd.flash.offset = i;
+		ioctl_cmd.flash.buf = (unsigned char *)&efuse[i];
+
+		ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+		if (ret < 0) {
+			if (ioctl_cmd.flash.status)
+				fprintf(stderr, "FLASH READ status: %d",
+					ioctl_cmd.flash.status);
+			PRINT_IOCTL_FAIL(ret);
+			return -FAIL_IOCTL;
+		}
+		usleep(200000);
+	}
+
+	return SUCCESS;
+}
+
+static int dump_efuse_from_chip(struct ax_command_info *info,
+				struct _ef_data_struct *efuse)
+{
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	return __dump_efuse(info, efuse, 0, 32);
+}
+
+static int find_empty_block_index(struct _ef_data_struct *efuse)
+{
+	int i;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (i = 5; i < EFUSE_NUM_BLOCK; i++) {
+		if (efuse[i].ef_data.type01.type.type == EF_TYPE_REV)
+			break;
+	}
+
+	return (i == EFUSE_NUM_BLOCK) ? -1 : i;
+}
+
+#ifdef ENABLE_IOCTL_DEBUG
+static void dump_efuse_data(struct _ef_data_struct *efuse)
+{
+	int i;
+	unsigned char *data = (unsigned char *)efuse;
+
+	for (i = 0; i < (20 * EFUSE_NUM_BLOCK); i += 4) {
+		printf("%02X %02X %02X %02X",
+			data[i + 3], data[i + 2], data[i + 1], data[i]);
+		if (i % 20 == 0)
+			printf(" == %d", i / 20);
+		printf("\n");
+	}
+
+}
+#define DUMP_EFUSE_DATA(efuse) dump_efuse_data(efuse)
+#else
+#define DUMP_EFUSE_DATA(efuse) while(0){}
+#endif
+
+static int check_efuse_block_valid(unsigned char *data)
+{
+	unsigned int sum = 0;
+	unsigned int tmp;
+	int j = 0;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	if ((data[0] & 0xF) == EF_TYPE_REV)
+		return -FAIL_IVALID_VALUE;
+
+	for (j = 0; j < 4; j++) {
+		if (j == 0)
+			sum += data[j] & 0xF;
+		else
+			sum += data[j];
+	}
+
+	while (sum > 0xF)
+		sum = (sum & 0xF) + (sum >> 4);
+
+	sum = 0xF - sum;
+
+	tmp = (data[0] & 0xF) | ((sum << 4) & 0xF0);
+
+	if (tmp != data[0])
+		return -FAIL_IVALID_CHKSUM;
+
+	return SUCCESS;
+}
+
+static int merge_efuse(struct _ef_data_struct *dump_efuse,
+		       struct _ef_data_struct *file_efuse,
+		       unsigned int *program_block, unsigned int *program_index)
+{
+	int dump_empty_index, i, j;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	dump_empty_index = find_empty_block_index(dump_efuse);
+	if (dump_empty_index < 0) {
+		fprintf(stderr, "%s: Non empty block.\n", __func__);
+		return -FAIL_NON_EMPTY_RFUSE_BLOCK;
+	}
+
+	*program_block = 0;
+	*program_index = -1;
+	for (i = 5, j = dump_empty_index; i < EFUSE_NUM_BLOCK; i++, j++) {
+		unsigned char *block = (unsigned char *)&file_efuse[i];
+		int ret;
+
+		if (file_efuse[i].ef_data.type01.type.type == EF_TYPE_REV)
+			break;
+
+		ret = check_efuse_block_valid(block);
+		if (ret < 0) {
+			fprintf(stderr,
+				"%s: ERROR eFuse block in file.\n", __func__);
+			return ret;
+		}
+		memcpy(&dump_efuse[j], &file_efuse[i], EF_DATA_STRUCT_SIZE);
+		*program_block += 1;
+	}
+
+	*program_index = dump_empty_index;
+	return SUCCESS;
+}
+
+static int __program_efuse_block(struct ax_command_info *info,
+				 struct _ef_data_struct *efuse,
+				 unsigned int block_offset,
+				 unsigned int block_num)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	int i, limit = (block_offset + block_num);
+	struct _ax_ioctl_command ioctl_cmd;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	if (limit > EFUSE_NUM_BLOCK) {
+		fprintf(stderr, "%s: eFuse block not enough\n", __func__);
+		return -FAIL_IVALID_VALUE;
+	}
+
+	if (scan_ax_device(ifr, info->inet_sock)) {
+		PRINT_SCAN_DEV_FAIL;
+		return -FAIL_SCAN_DEV;
+	}
+
+	ioctl_cmd.ioctl_cmd = AX88179A_PROGRAM_EFUSE;
+	ioctl_cmd.flash.length = 20;
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	for (i = block_offset; i < limit; i++) {
+		int ret;
+
+		ioctl_cmd.flash.status = 0;
+		ioctl_cmd.flash.offset = i;
+		ioctl_cmd.flash.buf = (unsigned char *)&efuse[i];
+
+		ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+		if (ret < 0) {
+			if (ioctl_cmd.flash.status)
+				fprintf(stderr, "FLASH PROGRAM status: %d",
+					ioctl_cmd.flash.status);
+			PRINT_IOCTL_FAIL(ret);
+			return -FAIL_IOCTL;
+		}
+	}
+
+	return SUCCESS;
+}
+
+static struct option const long_options[] =
+{
+  {"file", required_argument, NULL, 'f'},
+  {"mac", required_argument, NULL, 'm'},
+  {"serial", required_argument, NULL, 's'},
+  {"device", required_argument, NULL, 'p'},
+  {"led0", required_argument, NULL, 'l'},
+  {"led1", required_argument, NULL, 'e'},
+  {NULL, 0, NULL, 0}
+};
+
+struct __wefuse {
+	char *mac_address;
+	char *serial_num;
+	char *file_path;
+	char *led0;
+	char *led1;
+	char *device;
+	unsigned int MAC[6];
+};
+
+static void creat_sample_efuse(struct _ef_data_struct *efuse,
+			       struct __wefuse *par)
+{
+	int index = 5;
+
+	if (par->mac_address) {
+		memcpy(&efuse[index], sample_type1, EF_TYPE_STRUCT_SIZE_01);
+		if (!strcasecmp(par->device , "AX88179A"))
+			efuse[index].ef_data.type01.bcdDevice = htobe16(0x0200);
+		if (!strcasecmp(par->device , "AX88772D"))
+			efuse[index].ef_data.type01.bcdDevice = htobe16(0x0300);
+		index++;
+	}
+
+	if (par->serial_num)
+		memcpy(&efuse[index++], sample_type4, EF_TYPE_STRUCT_SIZE_04);
+
+	if (par->led0)
+		set_led(&efuse[index++], par->led0, 0);
+
+	if (par->led1)
+		set_led(&efuse[index++], par->led1, 1);
+}
+
+static int print_msg(char *cmd)
+{
+	int i;
+
+	for (i = 0; ax88179a_cmd_list[i].cmd != NULL; i++) {
+		if (strncmp(cmd, ax88179a_cmd_list[i].cmd,
+				strlen(ax88179a_cmd_list[i].cmd)) == 0) {
+			printf("%s%s\n", ax88179a_cmd_list[i].help_ins,
+				ax88179a_cmd_list[i].help_desc);
+			return -FAIL_INVALID_PARAMETER;
+		}
+	}
+}
+
+static int __check_led_parameter(char *led)
+{
+	if (!led)
+		return 1;
+
+	if (strlen(led) != 9 || led[4] != '_')
+		return 1;
+	do {
+		if (*led++ == '_')
+			continue;
+		if (!isxdigit(*led++))
+			return 1;
+	} while (*led);
+	return 0;
+}
+
+static int __check_wefuse_parameter(struct __wefuse *par)
+{
+	if (par->mac_address)
+		if (!par->device && !par->file_path)
+			return 1;
+
+	if (!par->led0 ^ !par->led1)
+		return 1;
+
+	return 0;
+}
+
+static int writeefuse_func(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ef_data_struct *file_efuse = NULL;
+	struct _ef_data_struct *dump_efuse = NULL;
+	int i, c, ret;
+	struct __wefuse argument = {0};
+	void *buf = NULL;
+	int oi = -1;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	while ((c = getopt_long(info->argc, info->argv,
+				"m:s:f:p:l:e:",
+				long_options, &oi)) != -1) {
+		switch (c) {
+		case 'm':
+			argument.mac_address = optarg;
+			DEBUG_PRINT("%s \r\n", argument.mac_address);
+			i = sscanf(argument.mac_address,
+				   "%02X:%02X:%02X:%02X:%02X:%02X",
+				   (unsigned int *)&argument.MAC[0],
+				   (unsigned int *)&argument.MAC[1],
+				   (unsigned int *)&argument.MAC[2],
+				   (unsigned int *)&argument.MAC[3],
+				   (unsigned int *)&argument.MAC[4],
+				   (unsigned int *)&argument.MAC[5]);
+			if (i != 6)
+				return print_msg("wefuse");
+			break;
+		case 's':
+			argument.serial_num = optarg;
+			DEBUG_PRINT("%s \r\n", argument.serial_num);
+			if (strlen(argument.serial_num) > 18)
+				return print_msg("wefuse");
+			break;
+		case 'f':
+			argument.file_path = optarg;
+			DEBUG_PRINT("%s \r\n", argument.file_path);
+			break;
+		case 'l':
+			argument.led0 = optarg;
+			DEBUG_PRINT("%s \r\n", argument.led0);
+			if (__check_led_parameter(argument.led0))
+				return print_msg("wefuse");
+			break;
+		case 'e':
+			argument.led1 = optarg;
+			DEBUG_PRINT("%s \r\n", argument.led1);
+			if (__check_led_parameter(argument.led1))
+				return print_msg("wefuse");			
+			break;
+		case 'p':
+			argument.device = optarg;
+			DEBUG_PRINT("%s \r\n", argument.device);
+			if (strcasecmp(argument.device , "AX88179B") &&
+			    strcasecmp(argument.device , "AX88179A") &&
+				strcasecmp(argument.device , "AX88772E") &&
+			    strcasecmp(argument.device , "AX88772D"))
+				return print_msg("wefuse");
+			break;	
+		case '?':
+		default:
+			return -FAIL_INVALID_PARAMETER;
+		}
+	}
+
+	if (__check_wefuse_parameter(&argument))
+		return print_msg("wefuse");
+
+	buf = calloc(128, EF_DATA_STRUCT_SIZE);
+	if (!buf) {
+		PRINT_ALLCATE_MEM_FAIL;
+		return -FAIL_ALLCATE_MEM;
+	}
+
+	file_efuse = (struct _ef_data_struct *)buf;
+	dump_efuse = (struct _ef_data_struct *)&file_efuse[64];
+
+	if (argument.file_path) {
+		if (load_efuse_from_file(argument.file_path,
+					 (unsigned char *)file_efuse)) {
+			PRINT_LOAD_FILE_FAIL;
+			ret = -PRINT_LOAD_FILE_FAIL;
+			goto fail;
+		}
+	} else {
+		creat_sample_efuse(file_efuse, &argument);
+	}
+
+	DUMP_EFUSE_DATA(file_efuse);
+
+	if (argument.mac_address) {
+		ret = change_mac_address(file_efuse, argument.MAC);
+		if (ret < 0) {
+			fprintf(stderr,
+				"%s: Changing MAC address failed.\n",
+				__func__);
+			goto fail;
+		}
+	}
+
+	if (argument.serial_num) {
+		ret = change_serial_number(file_efuse, argument.serial_num);
+		if (ret < 0) {
+			fprintf(stderr,
+				"%s: Changing serial number failed.\n",
+				__func__);
+			goto fail;
+		}
+	}
+
+	autosuspend_enable(info, 0);
+
+	DUMP_EFUSE_DATA(file_efuse);
+
+	ret = dump_efuse_from_chip(info, dump_efuse);
+	if (ret < 0)
+		goto fail;
+
+	DUMP_EFUSE_DATA(dump_efuse);
+
+	do {
+		unsigned int program_block;
+		unsigned int program_index;
+
+		ret = merge_efuse(dump_efuse, file_efuse,
+				  &program_block, &program_index);
+		if (ret < 0)
+			goto fail;
+
+		DUMP_EFUSE_DATA(dump_efuse);
+#ifndef NOT_PROGRAM
+		ret = __program_efuse_block(info, dump_efuse,
+					    program_index, program_block);
+		if (ret < 0)
+			goto fail;
+#endif
+	} while (0);
+#ifndef NOT_PROGRAM
+	usleep(100000);
+
+	ret = dump_efuse_from_chip(info, file_efuse);
+	if (ret < 0)
+		goto fail;
+
+	if (memcmp(file_efuse, dump_efuse, (EF_DATA_STRUCT_SIZE * 32))) {
+		fprintf(stderr, "%s: Comparing efuse failed.\n", __func__);
+		ret = -FAIL_EFUSE_WRITE;
+		goto fail;
+	}
+#endif
+	ret = SUCCESS;
+fail:
+	if (buf)
+		free(buf);
+
+	autosuspend_enable(info, 1);
+
+	return ret;
+}
+
+static int readefuse_func(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ef_data_struct *dump_efuse = NULL;
+	FILE *pFile = NULL;
+	char str_buf[50];
+	int i, j, c, ret, oi = -1;
+	char *file_path = NULL;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	while ((c = getopt_long(info->argc, info->argv,
+				"f",
+				long_options, &oi)) != -1) {
+		switch (c) {
+		case 'f':
+			file_path = info->argv[optind];
+			break;
+		case '?':
+		default:
+			return -FAIL_INVALID_PARAMETER;
+		}
+	}
+
+	if (file_path == NULL) {
+		for (i = 0; ax88179a_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp("refuse", ax88179a_cmd_list[i].cmd,
+				    strlen(ax88179a_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88179a_cmd_list[i].help_ins,
+				       ax88179a_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	dump_efuse = (struct _ef_data_struct *)malloc(EF_DATA_STRUCT_SIZE * 32);
+	if (!dump_efuse) {
+		PRINT_ALLCATE_MEM_FAIL;
+		return -FAIL_ALLCATE_MEM;
+	}
+	memset(dump_efuse, 0, EF_DATA_STRUCT_SIZE * 32);
+
+	autosuspend_enable(info, 0);
+
+	ret = dump_efuse_from_chip(info, dump_efuse);
+	if (ret < 0)
+		goto fail;
+
+	pFile = fopen(file_path, "w");
+	if (pFile == NULL) {
+		fprintf(stderr, "%s: Fail to open %s file.\n",
+			__func__, file_path);
+		ret = -FAIL_LOAD_FILE;
+		goto fail;
+	}
+
+	DUMP_EFUSE_DATA(dump_efuse);
+
+	for (i = 0; i < 32; i++) {
+		unsigned char *buf = (unsigned char *)&dump_efuse[i];
+
+		for (j = 0; j < 5; j++) {
+			snprintf(str_buf, 50, "%02x %02x %02x %02x\n",
+				 buf[(j * 4) + 3],
+				 buf[(j * 4) + 2],
+				 buf[(j * 4) + 1],
+				 buf[(j * 4)]);
+			fputs(str_buf, pFile);
+		}
+	}
+
+	ret = SUCCESS;
+fail:
+	if (dump_efuse)
+		free(dump_efuse);
+	if (pFile)
+		fclose(pFile);
+
+	autosuspend_enable(info, 1);
+	
+	return ret;
+}
+
+static int reload_func(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	char fw_version[16] = {0};
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	if (info->argc != 2) {
+		int i;
+
+		for (i = 0; ax88179a_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88179a_cmd_list[i].cmd,
+				    strlen(ax88179a_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88179a_cmd_list[i].help_ins,
+				       ax88179a_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	if (scan_ax_device(ifr, info->inet_sock)) {
+		PRINT_SCAN_DEV_FAIL;
+		return -FAIL_SCAN_DEV;
+	}
+
+	autosuspend_enable(info, 0);
+
+	sw_reset(info);
+
+	if (scan_ax_device(ifr, info->inet_sock)) {
+		PRINT_SCAN_DEV_FAIL;
+		return -FAIL_SCAN_DEV;
+	}
+
+	return SUCCESS;
+}
+
+static int scan_ax_device(struct ifreq *ifr, int inet_sock)
+{
+	unsigned int retry;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (retry = 0; retry < SCAN_DEV_MAX_RETRY; retry++) {
+		unsigned int i;
+		struct _ax_ioctl_command ioctl_cmd;
+#if NET_INTERFACE == INTERFACE_SCAN
+		struct ifaddrs *addrs, *tmp;
+		unsigned char	dev_exist;
+
+		getifaddrs(&addrs);
+		tmp = addrs;
+		dev_exist = 0;
+
+		while (tmp) {
+			memset(&ioctl_cmd, 0,
+			       sizeof(struct _ax_ioctl_command));
+			ioctl_cmd.ioctl_cmd = AX_SIGNATURE;
+
+			sprintf(ifr->ifr_name, "%s", tmp->ifa_name);
+			tmp = tmp->ifa_next;
+
+			ioctl(inet_sock, SIOCGIFFLAGS, ifr);
+			if (!(ifr->ifr_flags & IFF_UP))
+				continue;
+
+			ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+			if (ioctl(inet_sock, AX_PRIVATE, ifr) < 0)
+				continue;
+
+			if (strncmp(ioctl_cmd.sig,
+				    AX88179A_DRV_NAME,
+				    strlen(AX88179A_DRV_NAME)) == 0) {
+				dev_exist = 1;
+				break;
+			}
+		}
+
+		freeifaddrs(addrs);
+
+		if (dev_exist)
+			break;
+#else
+		for (i = 0; i < 255; i++) {
+
+			memset(&ioctl_cmd, 0,
+			       sizeof(struct _ax_ioctl_command));
+			ioctl_cmd.ioctl_cmd = AX_SIGNATURE;
+
+			sprintf(ifr->ifr_name, "eth%u", i);
+
+			ioctl(inet_sock, SIOCGIFFLAGS, ifr);
+			if (!(ifr->ifr_flags & IFF_UP))
+				continue;
+
+			ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+			if (ioctl(inet_sock, AX_PRIVATE, ifr) < 0)
+				continue;
+
+			if (strncmp(ioctl_cmd.sig,
+				    AX88179A_DRV_NAME,
+				    strlen(AX88179A_DRV_NAME)) == 0)
+				break;
+
+		}
+
+		if (i < 255)
+			break;
+#endif
+		usleep(500000);
+	}
+
+	if (retry >= SCAN_DEV_MAX_RETRY)
+		return -FAIL_SCAN_DEV;
+
+	return SUCCESS;
+}
+
+int main(int argc, char **argv)
+{
+	struct ifreq ifr;
+	struct ax_command_info info;
+	unsigned int i;
+	int inet_sock, ret = -FAIL_GENERIAL_ERROR;
+
+	printf("%s\n", AX88179A_IOCTL_VERSION);
+
+	if (argc < 2) {
+		show_usage();
+		return SUCCESS;
+	}
+
+	inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
+#ifndef NOT_PROGRAM 
+	if (scan_ax_device(&ifr, inet_sock)) {
+		printf("No %s found\n", AX88179A_SIGNATURE);
+		return FAIL_SCAN_DEV;
+	}
+#endif
+	for (i = 0; ax88179a_cmd_list[i].cmd != NULL; i++) {
+		if (strncmp(argv[1],
+			    ax88179a_cmd_list[i].cmd,
+			    strlen(ax88179a_cmd_list[i].cmd)) == 0) {
+			info.help_ins = ax88179a_cmd_list[i].help_ins;
+			info.help_desc = ax88179a_cmd_list[i].help_desc;
+			info.ifr = &ifr;
+			info.argc = argc;
+			info.argv = argv;
+			info.inet_sock = inet_sock;
+			info.ioctl_cmd = ax88179a_cmd_list[i].ioctl_cmd;
+			ret = (ax88179a_cmd_list[i].OptFunc)(&info);
+			goto out;
+		}
+	}
+
+	if (ax88179a_cmd_list[i].cmd == NULL) {
+		show_usage();
+		return SUCCESS;
+	}
+out:
+	if (ret == SUCCESS)
+		printf("SUCCESS\n");
+	else if (ret != -FAIL_INVALID_PARAMETER)
+		printf("FAIL\n");
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/ax88279_programmer.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/ax88279_programmer.c
@@ -0,0 +1,1854 @@
+// SPDX-License-Identifier: GPL-2.0
+/*******************************************************************************
+ *     Copyright (c) 2022    ASIX Electronic Corporation    All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <getopt.h>
+#include <endian.h>
+#if NET_INTERFACE == INTERFACE_SCAN
+#include <ifaddrs.h>
+#endif
+#include "ax_ioctl.h"
+#ifdef ENABLE_IOCTL_DEBUG
+#define NOT_PROGRAM
+#endif
+#define RELOAD_DELAY_TIME	10	// sec
+
+#define PRINT_IOCTL_FAIL(ret) \
+fprintf(stderr, "%s: ioctl failed. (err: %d)\n", __func__, ret)
+#define PRINT_SCAN_DEV_FAIL \
+fprintf(stderr, "%s: Scaning device failed.\n", __func__)
+#define PRINT_ALLCATE_MEM_FAIL \
+fprintf(stderr, "%s: Fail to allocate memory.\n", __func__)
+#define PRINT_LOAD_FILE_FAIL \
+fprintf(stderr, "%s: Read file failed.\n", __func__)
+
+#define AX88179A_IOCTL_VERSION \
+"AX88279 Linux Flash Programming Tool v1.0.0 beat1"
+
+const char help_str1[] =
+"./ax88279_programmer help [command]\n"
+"    -- command description\n";
+const char help_str2[] =
+"        [command] - Display usage of specified command\n";
+
+const char readverion_str1[] =
+"./ax88279_programmer rversion\n"
+"    -- AX88279 Read Firmware Verion\n";
+static const char readverion_str2[] = "";
+
+const char readmac_str1[] =
+"./ax88279_programmer rmacaddr\n"
+"    -- AX88279 Read MAC Address\n";
+static const char readmac_str2[] = "";
+
+const char writeflash_str1[] =
+"./ax88279_programmer wflash [file]\n"
+"    -- AX88279 Write Flash\n";
+const char writeflash_str2[] =
+"        [file]    - Flash file path\n";
+
+const char writeparameter_str1[] =
+"./ax88279_programmer wpara -m [MAC] -s [SN] -p [PID] -v [VID] -P [PS] -M [MN] -D [dump]\n"
+"                           -S [SS] -H [HS] -w [wol] -l [led0 value] -e [led1 value] -d [led2 value]\n"
+"    -- AX88279 Write Parameter\n";
+const char writeparameter_str2[] =
+"        -m [MAC]   	 - MAC address (XX:XX:XX:XX:XX:XX) X:'0'-'F'\n"
+"        -s [SN]    	 - Serial Number (Characters must be less than 19 bytes) X:'0'-'F'\n"
+"        -p [PID]   	 - Product ID (XX:XX) X:'0'-'F'\n"
+"        -v [VID]   	 - Vendor ID (XX:XX) X:'0'-'F'\n"
+"        -P [PS]    	 - Product String (Characters must be less than 19 bytes)\n"
+"        -M [MN]    	 - Manufacture Name (Characters must be less than 19 bytes)\n"
+"        -D [dump]	 - The parameter content currently in flash (dump)\n"
+"        -S [SS]    	 - SS bus power (XX) X:0-896\n"
+"        -H [HS]    	 - HS bus power (XX) X:0-500\n"
+"        -w [wol]    	 - wake on LAN (XXXXXXXX) X:digit\n"
+"        -l [led0 value]	 - value: control_blink (XXXX_XXXX)\n"
+"        -e [led1 value]	 - value: control_blink (XXXX_XXXX)\n";
+
+const char reload_str1[] =
+"./ax88279_programmer reload\n"
+"    -- AX88279 Reload\n";
+static const char reload_str2[] = "";
+
+static int help_func(struct ax_command_info *info);
+static int readversion_func(struct ax_command_info *info);
+static int readmac_func(struct ax_command_info *info);
+static int writeflash_func(struct ax_command_info *info);
+static int writeparameter_func(struct ax_command_info *info);
+static int reload_func(struct ax_command_info *info);
+static int scan_ax_device(struct ifreq *ifr, int inet_sock);
+
+struct _command_list ax88279_cmd_list[] = {
+	{
+		"help",
+		AX_SIGNATURE,
+		help_func,
+		help_str1,
+		help_str2
+	},
+	{
+		"rversion",
+		AX88179A_READ_VERSION,
+		readversion_func,
+		readverion_str1,
+		readverion_str2
+	},
+	{
+		"rmacaddr",
+		~0,
+		readmac_func,
+		readmac_str1,
+		readmac_str2
+	},
+	{
+		"wflash",
+		AX88179A_WRITE_FLASH,
+		writeflash_func,
+		writeflash_str1,
+		writeflash_str2
+	},
+	{
+		"wpara",
+		AX88179A_PROGRAM_EFUSE,
+		writeparameter_func,
+		writeparameter_str1,
+		writeparameter_str2
+	},
+	{
+		"reload",
+		~0,
+		reload_func,
+		reload_str1,
+		reload_str2
+	},
+	{
+		NULL,
+		0,
+		NULL,
+		NULL,
+		NULL
+	}
+};
+
+static struct option const long_options[] =
+{
+  {"mac", required_argument, NULL, 'm'},
+  {"serial", required_argument, NULL, 's'},
+  {"pid", required_argument, NULL, 'p'},
+  {"vid", required_argument, NULL, 'v'},
+  {"Product", required_argument, NULL, 'P'},
+  {"Manufacture", required_argument, NULL, 'M'},
+  {"dump", required_argument, NULL, 'D'},
+  {"ssbus", required_argument, NULL, 'S'},
+  {"hsbus", required_argument, NULL, 'H'},
+  {"wol", required_argument, NULL, 'w'},
+  {"led0", required_argument, NULL, 'l'},
+  {"led1", required_argument, NULL, 'e'},
+  {NULL, 0, NULL, 0}
+};
+
+struct __wpara {
+	char *mac_address;
+	char *serial_num;
+	char *PID;
+	char *VID;
+	char *product_string;
+	char *manufacture;
+	char *dump;
+	char *ss_bus;
+	char *hs_bus;
+	char *wol;
+	char *led0;
+	char *led1;
+	unsigned int iss_bus;
+	unsigned int ihs_bus;	
+	unsigned int MAC[6];
+	unsigned int LED0[9];
+	unsigned int LED1[9];
+	unsigned int pid[2];
+	unsigned int vid[2];
+	unsigned int ssbus[1];
+	unsigned int hsbus[1];
+};
+
+static unsigned char sample_type1[] = {
+ 0x01, 0x0B, 0x95, 0x17,
+ 0x90, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x04,
+ 0x00, 0x0A, 0x07, 0xFF,
+ 0x39, 0xE1, 0x20, 0x00
+};
+
+static unsigned char sample_type2[] = {
+ 0x02, 0x41, 0x53, 0x49,
+ 0x58, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
+
+static unsigned char sample_type3[] = {
+ 0x03, 0x41, 0x58, 0x38,
+ 0x38, 0x32, 0x37, 0x39,
+ 0x41, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
+
+static unsigned char sample_type4[] = {
+ 0x04, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30,
+ 0x31, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
+
+static unsigned char sample_type11[] = {
+ 0x0B, 0x1F, 0x00, 0x00,
+ 0x00, 0x00, 0x1F, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x45, 0x0B
+};
+
+static unsigned char sample_type15[] = {
+ 0x0F, 0x7D, 0x01, 0x63,
+ 0x81, 0x7F, 0x7F, 0x5F,
+ 0x5D, 0x2F, 0x07, 0xE8,
+ 0x04, 0x7D, 0x00, 0xC8,
+ 0x08, 0x01, 0x04, 0x00
+};
+
+#pragma pack(push)
+#pragma pack(1)
+enum Para_Type_Def {
+	TYPE_REV = 0x00,
+	TYPE_01 = 0x01,
+	TYPE_02 = 0x02,
+	TYPE_03 = 0x03,
+	TYPE_04 = 0x04,
+	TYPE_11 = 0x0B,
+	TYPE_15 = 0x0F,
+};
+struct _ef_type {
+#if __BYTE_ORDER == __BIG_ENDIAN
+	unsigned char	checksum: 4;
+	unsigned char	type	: 4;
+#else
+	unsigned char	type	: 4;
+	unsigned char	checksum: 4;
+#endif
+};
+
+struct _ef_type01 {
+	struct _ef_type	type;
+	unsigned short	vid;
+	unsigned short	pid;
+	unsigned char	mac[6];
+	unsigned short	bcdDevice;
+	unsigned char	bU1DevExitLat;
+	unsigned short	wU2DevExitLat;
+	unsigned char	SS_Max_Bus_Pw;
+	unsigned char	HS_Max_Bus_Pw;
+	unsigned char	IPSleep_Polling_Count;
+	unsigned char	reserve;
+};
+#define EF_TYPE_STRUCT_SIZE_01	sizeof(struct _ef_type01)
+
+struct _ef_type02 {
+	struct _ef_type	type;
+	unsigned char	m_string[18];
+	unsigned char	reserve;
+};
+#define EF_TYPE_STRUCT_SIZE_02	sizeof(struct _ef_type02)
+
+struct _ef_type03 {
+	struct _ef_type	type;
+	unsigned char	p_string[18];
+	unsigned char	reserve;
+};
+#define EF_TYPE_STRUCT_SIZE_03	sizeof(struct _ef_type03)
+
+struct _ef_type04 {
+	struct _ef_type	type;
+	unsigned char	serial[18];
+	unsigned char	reserve;
+};
+#define EF_TYPE_STRUCT_SIZE_04	sizeof(struct _ef_type04)
+
+struct _ef_type11 {
+	struct _ef_type	type;
+	unsigned char	dev_type0;
+	unsigned short	reg0;
+	unsigned short	value0;
+
+	unsigned char	dev_type1;
+	unsigned short	reg1;
+	unsigned short	value1;
+
+	unsigned char	dev_type2;
+	unsigned short	reg2;
+	unsigned short	value2;
+
+	unsigned char	reserved1[2];
+	unsigned char	subtype;
+	unsigned char	endofs;
+};
+#define EF_TYPE_STRUCT_SIZE_11	sizeof(struct _ef_type11)
+
+struct _ef_type15 {
+	struct _ef_type	type;
+	unsigned char	flag1;
+	unsigned char	flag2;
+	unsigned char	flag3;
+	unsigned char	flag4;
+	unsigned char	U1_inact_timer;
+	unsigned char	U2_inact_timer;
+	unsigned char	Lpm_besl_u3;
+	unsigned char	Lpm_besl;
+	unsigned char	Lpm_besld;
+	unsigned short	Ltm_belt_down;
+	unsigned short	Ltm_belt_up;
+	unsigned short	Ephy_poll_timer;
+
+	unsigned char	Pme_gpio_sel;
+	unsigned char	Pme_pulse_width;
+	unsigned char	Wol_mask_timer;
+
+	unsigned char	reserve;
+};
+#define EF_TYPE_STRUCT_SIZE_15	sizeof(struct _ef_type15)
+
+struct _ef_data_struct {
+	union {
+		struct _ef_type01 type01;
+		struct _ef_type02 type02;
+		struct _ef_type03 type03;
+		struct _ef_type04 type04;
+		struct _ef_type11 type11;
+		struct _ef_type15 type15;
+	} ef_data;
+};
+#define EF_DATA_STRUCT_SIZE	sizeof(struct _ef_data_struct)
+#pragma pack(pop)
+
+static void show_usage(void)
+{
+	int i;
+
+	printf("Usage:\n");
+	for (i = 0; ax88279_cmd_list[i].cmd != NULL; i++)
+		printf("%s\n", ax88279_cmd_list[i].help_ins);
+}
+
+static int help_func(struct ax_command_info *info)
+{
+	int i;
+
+	if (info->argv[2] == NULL)
+		return -FAIL_INVALID_PARAMETER;
+
+	for (i = 0; ax88279_cmd_list[i].cmd != NULL; i++) {
+		if (strncmp(info->argv[2],
+			    ax88279_cmd_list[i].cmd,
+			    strlen(ax88279_cmd_list[i].cmd)) == 0) {
+			printf("%s%s\n", ax88279_cmd_list[i].help_ins,
+			       ax88279_cmd_list[i].help_desc);
+			return -FAIL_INVALID_PARAMETER;
+		}
+	}
+
+	return SUCCESS;
+}
+
+static int autosuspend_enable(struct ax_command_info *info,
+			      unsigned char enable)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	int ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_AUTOSUSPEND_EN;
+
+	ioctl_cmd.autosuspend.enable = enable;
+
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		return -FAIL_IOCTL;
+	}
+
+	return SUCCESS;
+}
+
+static int read_version(struct ax_command_info *info, char *version)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	int ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_READ_VERSION;
+
+	memset(ioctl_cmd.version.version, 0, 16);
+
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		return -FAIL_IOCTL;
+	}
+
+	memcpy(version, ioctl_cmd.version.version, 16);
+
+	return SUCCESS;
+}
+
+static int read_mac_address(struct ax_command_info *info, unsigned char *mac)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	int ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ret = scan_ax_device(ifr, info->inet_sock);
+	if (ret < 0) {
+		PRINT_SCAN_DEV_FAIL;
+		return ret;
+	}
+
+	ifr->ifr_flags &= 0;
+	ret = ioctl(info->inet_sock, SIOCSIFFLAGS, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		return ret;
+	}
+
+	usleep(20000);
+
+	ifr->ifr_flags = IFF_UP | IFF_BROADCAST | IFF_MULTICAST;
+	ret = ioctl(info->inet_sock, SIOCSIFFLAGS, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		return ret;
+	}
+
+	usleep(20000);
+
+	ret = ioctl(info->inet_sock, SIOCGIFHWADDR, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		return ret;
+	}
+
+	memcpy(mac, ifr->ifr_hwaddr.sa_data, 6);
+
+	return SUCCESS;
+}
+
+static int readversion_func(struct ax_command_info *info)
+{
+	char version[16] = {0};
+	int i, ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	if (info->argc != 2) {
+		for (i = 0; ax88279_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88279_cmd_list[i].cmd,
+				    strlen(ax88279_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88279_cmd_list[i].help_ins,
+				       ax88279_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	ret = scan_ax_device(info->ifr, info->inet_sock);
+    if (ret < 0) {
+            PRINT_SCAN_DEV_FAIL;
+            return ret;
+    }
+
+	autosuspend_enable(info, 0);
+
+	ret = read_version(info, version);
+	if (ret == SUCCESS)
+		printf("Firmware Version: %s\n", version);
+
+	usleep(20000);
+
+	autosuspend_enable(info, 1);
+
+	return ret;
+}
+
+static int readmac_func(struct ax_command_info *info)
+{
+	unsigned char mac[6] = {0};
+	int i, ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	if (info->argc != 2) {
+		for (i = 0; ax88279_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88279_cmd_list[i].cmd,
+				    strlen(ax88279_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88279_cmd_list[i].help_ins,
+				       ax88279_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	ret = read_mac_address(info, mac);
+	if (ret == SUCCESS)
+		printf("MAC address: %02X:%02X:%02X:%02X:%02X:%02X\n",
+			mac[0],
+			mac[1],
+			mac[2],
+			mac[3],
+			mac[4],
+			mac[5]);
+
+	return ret;
+}
+
+static int write_flash(struct ax_command_info *info, unsigned char *data,
+		       unsigned long offset, unsigned long len)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	int ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_WRITE_FLASH;
+	ioctl_cmd.flash.status = 0;
+	ioctl_cmd.flash.offset = offset;
+	ioctl_cmd.flash.length = len;
+	ioctl_cmd.flash.buf = data;
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+	if (ret < 0) {
+		if (ioctl_cmd.flash.status)
+			fprintf(stderr, "FLASH WRITE status: %d",
+				ioctl_cmd.flash.status);
+		PRINT_IOCTL_FAIL(ret);
+		return ret;
+	}
+
+	return SUCCESS;
+}
+
+static int read_flash(struct ax_command_info *info, unsigned char *data,
+		      unsigned long offset, unsigned long len)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	int ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_READ_FLASH;
+	ioctl_cmd.flash.status = 0;
+	ioctl_cmd.flash.offset = offset;
+	ioctl_cmd.flash.length = len;
+	ioctl_cmd.flash.buf = data;
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+	if (ret < 0) {
+		if (ioctl_cmd.flash.status)
+			fprintf(stderr, "FLASH READ status: %d",
+				ioctl_cmd.flash.status);
+		PRINT_IOCTL_FAIL(ret);
+		return -FAIL_IOCTL;
+	}
+
+	return SUCCESS;
+}
+
+static int erase_flash(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	int ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_ERASE_FLASH;
+	ioctl_cmd.flash.status = 0;
+
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		return -FAIL_IOCTL;
+	}
+
+	return SUCCESS;
+}
+
+static int erase_sector_flash(struct ax_command_info *info, int offset)
+{
+
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	int ret;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_ERASE_SECTOR_FLASH;
+	ioctl_cmd.flash.status = 0;
+	ioctl_cmd.flash.offset = offset;
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	ret = ioctl(info->inet_sock, AX_PRIVATE, ifr);
+	if (ret < 0) {
+		PRINT_IOCTL_FAIL(ret);
+		return -FAIL_IOCTL;
+	}
+
+	return SUCCESS;
+}
+
+static int boot_to_rom(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_ROOT_2_ROM;
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+	ioctl(info->inet_sock, AX_PRIVATE, ifr);
+
+	return SUCCESS;
+}
+
+static int sw_reset(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	ioctl_cmd.ioctl_cmd = AX88179A_SW_RESET;
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+	ioctl(info->inet_sock, AX_PRIVATE, ifr);
+
+	usleep(RELOAD_DELAY_TIME * 100000);
+
+	return SUCCESS;
+}
+
+static int find_offest_min_index(int *offset_arr, int size)
+{
+	int i = 0;
+	int min = offset_arr[0];
+
+	for (i = 1; i < size; i++) {
+        if (offset_arr[i] < min) {
+            min = offset_arr[i];
+        }
+    }
+
+	return min;
+}
+
+static int find_offest_max_index(int *offset_arr, int size)
+{
+	int i = 0;
+	int max = offset_arr[0];
+
+	for (i = 1; i < size; i++) {
+		if (offset_arr[i] >= max) {
+				max = i;
+		}
+	}
+
+	return max;
+}
+
+static int writeflash_func(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	unsigned char *wbuf = NULL, *rbuf = NULL;
+	FILE *pFile = NULL;
+	size_t result;
+	int file_length = 0;
+	int i, offset, ret;
+	char fw_version[16] = {0};
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	if (info->argc != 3) {
+		for (i = 0; ax88279_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88279_cmd_list[i].cmd,
+				    strlen(ax88279_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88279_cmd_list[i].help_ins,
+				       ax88279_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	autosuspend_enable(info, 0);
+
+	ret = scan_ax_device(ifr, info->inet_sock);
+	if (ret < 0) {
+		PRINT_SCAN_DEV_FAIL;
+		return ret;
+	}
+
+	ret = erase_flash(info);
+	if (ret < 0) 
+		return ret;
+
+	pFile = fopen(info->argv[2], "rb");
+	if (pFile == NULL) {
+		fprintf(stderr, "%s: Fail to open %s file.\n",
+			__func__, info->argv[2]);
+		ret = -FAIL_LOAD_FILE;
+		goto fail;
+	}
+
+	fseek(pFile, 0, SEEK_END);
+	file_length = ftell(pFile);
+	fseek(pFile, 0, SEEK_SET);
+
+	wbuf = (unsigned char *)malloc((file_length + 256) & ~(0xFF));
+	if (!wbuf) {
+		PRINT_ALLCATE_MEM_FAIL;
+		ret = -FAIL_ALLCATE_MEM;
+		goto fail;
+	}
+	memset(wbuf, 0, (file_length + 256) & ~(0xFF));
+
+	result = fread(wbuf, 1, file_length, pFile);
+	if (result != file_length) {
+		PRINT_LOAD_FILE_FAIL;
+		ret = -PRINT_LOAD_FILE_FAIL;
+		goto fail;
+	}
+
+	ret = write_flash(info, wbuf, FLASH_PARA_OFFSET, result);
+	if (ret < 0)
+		goto fail;
+
+	ret = write_flash(info, wbuf, 0, FLASH_PARA_OFFSET);
+	if (ret < 0)
+		goto fail;
+
+	offset = SWAP_32(*(unsigned long *)&wbuf[0]);
+	sprintf(fw_version, "v%d.%d.%d",
+		wbuf[offset + 0x1000],
+		wbuf[offset + 0x1001],
+		wbuf[offset + 0x1002]);
+	printf("File FW Version: %s\n", fw_version);
+	
+	ret = SUCCESS;
+	goto out;
+
+fail:
+	erase_flash(info);
+out:
+	if (wbuf)
+		free(wbuf);
+	if (pFile)
+		fclose(pFile);
+
+	autosuspend_enable(info, 1);
+
+	return ret;
+}
+
+static int print_msg(char *cmd)
+{
+	int i;
+
+	printf("\n");
+	for (i = 0; ax88279_cmd_list[i].cmd != NULL; i++) {
+		if (strncmp(cmd, ax88279_cmd_list[i].cmd,
+				strlen(ax88279_cmd_list[i].cmd)) == 0) {
+			printf("%s%s\n", ax88279_cmd_list[i].help_ins,
+				ax88279_cmd_list[i].help_desc);
+			return -FAIL_INVALID_PARAMETER;
+		}
+	}
+}
+
+static int find_block_index(unsigned char *rpara_databuf, int para_size
+							, enum Para_Type_Def type)
+{
+	int i = 0;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (i = 0; i < para_size; i += 20) {
+		if ((rpara_databuf[i] & 0x0F) == type)
+			return i / 20;
+	}
+
+	return -FAIL_GENERIAL_ERROR;
+}
+
+static int change_para_macaddr(unsigned char *rpara_databuf, int block_index, unsigned int *mac)
+{
+	int i;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (i = 0; i < 6; i++)
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 5 + i] = (unsigned char)mac[i];
+
+	return SUCCESS;
+}
+
+static int change_para_serialnum(unsigned char *rpara_databuf, int block_index, char *serial)
+{
+	int i;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (i = 0; i < 18; i++) {
+		if (serial[i] == '-')
+			break;
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 1 + i] = serial[i];
+	}
+
+	return SUCCESS;
+}
+
+static int change_para_pid(unsigned char *rpara_databuf, int block_index, unsigned int *pid)
+{
+	int i;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (i = 0; i < 2; i++)
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 3 + i] = (unsigned char)pid[i];
+
+	return SUCCESS;
+}
+
+static int change_para_vid(unsigned char *rpara_databuf, int block_index, unsigned int *vid)
+{
+	int i;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (i = 0; i < 2; i++)
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 1 + i] = (unsigned char)vid[i];
+
+	return SUCCESS;
+}
+
+static int change_para_productstr(unsigned char *rpara_databuf, int block_index, char *productstr)
+{
+	int i;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (i = 0; i < 18; i++) {
+		if (productstr[i] == '-')
+			break;
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 1 + i] = productstr[i];
+	}
+
+	return SUCCESS;
+}
+
+static int change_para_manufacture(unsigned char *rpara_databuf, int block_index, char *manufac)
+{
+	int i;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (i = 0; i < 18; i++) {
+		if (manufac[i] == '-')
+			break;
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 1 + i] = manufac[i];
+	}
+
+	return SUCCESS;
+}
+
+static int change_para_ssbus(unsigned char *rpara_databuf, int block_index, int issbus)
+{
+	int i;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (i = 0; i < 1; i++) 
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 16 + i] = (issbus / 8);
+
+	return SUCCESS;
+}
+
+static int change_para_hsbus(unsigned char *rpara_databuf, int block_index, int ihsbus)
+{
+	int i;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (i = 0; i < 1; i++) 
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 17 + i] = (ihsbus / 2);
+
+	return SUCCESS;
+}
+
+static int change_para_wol(unsigned char *rpara_databuf, int block_index, char *wol)
+{
+	int i = 0;
+	unsigned int dwolEn = 0;
+	unsigned int s5wolEn = 0;
+	unsigned int pmeEn = 0;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (i = 0; i < 8; i++) {
+		unsigned char bit_value = 0;
+		bit_value = (wol[i]-'0');
+
+		if (i == 0 && bit_value == 1) { // Disable Remote Wakeup
+			dwolEn = 1;
+			rpara_databuf[block_index * FLASH_BLOCK_SIZE + 1] &= ~0x01;
+			break; 
+		}
+		if (i == 1 && bit_value == 1) { // PME Enable
+			pmeEn = 1;
+			rpara_databuf[block_index * FLASH_BLOCK_SIZE + 2] |= 0x10;
+		}
+		if (i == 2 && bit_value == 1) { // DWOL Magic Packet
+			dwolEn = 1;
+			rpara_databuf[block_index * FLASH_BLOCK_SIZE + 1] |= 0x02;
+			rpara_databuf[block_index * FLASH_BLOCK_SIZE + 2] |= 0x1C;
+		}
+		if (i == 3 && bit_value == 1) { // DWOL Link Change
+			dwolEn = 1;
+			rpara_databuf[block_index * FLASH_BLOCK_SIZE + 1] |= 0x02;
+			rpara_databuf[block_index * FLASH_BLOCK_SIZE + 2] |= 0x1A;
+		}
+		if (i == 4 && bit_value == 1) { // S5 WOL Magic Packet
+			s5wolEn = 1;
+			rpara_databuf[block_index * FLASH_BLOCK_SIZE + 1] |= 0x02;
+			rpara_databuf[block_index * FLASH_BLOCK_SIZE + 2] |= 0x18;
+			rpara_databuf[block_index * FLASH_BLOCK_SIZE + 4] |= 0x28;
+		}
+		if (i == 5 && bit_value == 1) { // S5 WOL Link Change
+			s5wolEn = 1;
+			rpara_databuf[block_index * FLASH_BLOCK_SIZE + 1] |= 0x02;
+			rpara_databuf[block_index * FLASH_BLOCK_SIZE + 2] |= 0x18;
+			rpara_databuf[block_index * FLASH_BLOCK_SIZE + 4] |= 0x18;
+		}
+
+		if (dwolEn || s5wolEn || pmeEn) {
+			if (i == 6 && bit_value == 1) { // PME Retry Enable
+				rpara_databuf[block_index * FLASH_BLOCK_SIZE + 2] |= 0x80;
+			}
+			if (i == 7 && bit_value == 1) { // PME IND Enable
+				rpara_databuf[block_index * FLASH_BLOCK_SIZE + 2] |= 0x40;
+			}
+
+		}
+	}
+
+	return SUCCESS;
+}
+
+static void set_para_led0(unsigned char *rpara_databuf, int block_index,  unsigned int *led)
+{
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 1] = 0x1F;
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 2] = 0x00;
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 3] = 0x24;
+
+	if (led) {
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 4] = led[0];
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 5] = led[1];
+
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 9] = led[2];
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 10] = led[3];
+	} else {
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 4] = 0xC1;
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 5] = 0x03;
+
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 9] = 0x00;
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 10] = 0x00;
+	}
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 6] = 0x1F;
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 7] = 0x00;
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 8] = 0x25;
+
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 18] = 0x45;
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 19] = 0x0B;
+
+}
+
+static void set_para_led1(unsigned char *rpara_databuf, int block_index,  unsigned int *led)
+{
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 1] = 0x1F;
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 2] = 0x00;
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 3] = 0x26;
+
+	if (led) {
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 4] = led[0];
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 5] = led[1];
+
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 9] = led[2];
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 10] = led[3];
+	} else {
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 4] = 0xC0;
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 5] = 0x00;
+
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 9] = 0x0C;
+		rpara_databuf[block_index * FLASH_BLOCK_SIZE + 10] = 0x0F;
+	}
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 6] = 0x1F;
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 7] = 0x00;
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 8] = 0x27;
+
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 18] = 0x45;
+	rpara_databuf[block_index * FLASH_BLOCK_SIZE + 19] = 0x0B;
+}
+
+static int program_para_block(struct ax_command_info *info, unsigned char *rpara_databuf, int para_size)
+{
+	int ret;
+
+	ret = write_flash(info, rpara_databuf, 0, para_size);
+	if (ret < 0)
+		return -1;
+	
+	return 0;
+}
+
+static int calculate_para_offset(void *buf)
+{
+	unsigned char *data = (unsigned char *)buf;
+	int offset[8];
+	int len[8];
+	int max;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	offset[0] = SWAP_32(*(unsigned int *)&data[PRAM_PRI_FW1_OFFSET]);
+	len[0] = SWAP_32(*(unsigned int *)&data[PRAM_PRI_FW1_LENGTH]);
+	offset[1] = SWAP_32(*(unsigned int *)&data[MD32_PRI_FW1_OFFSET]);
+	len[1] = SWAP_32(*(unsigned int *)&data[MD32_PRI_FW1_LENGTH]);
+	offset[2] = SWAP_32(*(unsigned int *)&data[PRAM_SEC_FW1_OFFSET]);
+	len[2] = SWAP_32(*(unsigned int *)&data[PRAM_SEC_FW1_LENGTH]);
+	offset[3] = SWAP_32(*(unsigned int *)&data[MD32_SEC_FW1_OFFSET]);
+	len[3] = SWAP_32(*(unsigned int *)&data[MD32_SEC_FW1_LENGTH]);
+	offset[4] = SWAP_32(*(unsigned int *)&data[PRAM_PRI_FW2_OFFSET]);
+	len[4] = SWAP_32(*(unsigned int *)&data[PRAM_PRI_FW2_LENGTH]);
+	offset[5] = SWAP_32(*(unsigned int *)&data[MD32_PRI_FW2_OFFSET]);
+	len[5] = SWAP_32(*(unsigned int *)&data[MD32_PRI_FW2_LENGTH]);
+	offset[6] = SWAP_32(*(unsigned int *)&data[PRAM_SEC_FW2_OFFSET]);
+	len[6] = SWAP_32(*(unsigned int *)&data[PRAM_SEC_FW2_LENGTH]);
+	offset[7] = SWAP_32(*(unsigned int *)&data[MD32_SEC_FW2_OFFSET]);
+	len[7] = SWAP_32(*(unsigned int *)&data[MD32_SEC_FW2_LENGTH]);
+
+	max = find_offest_max_index(offset, 8);
+
+	return (offset[max] + len[max] + 0x10000) & ~(0xFFFF);
+}
+
+void dump(unsigned char *buf, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++) {
+		printf("%02X ", buf[i]);
+		if (i % 4 == 3)
+			printf("\n");
+	}
+	printf("\n");
+}
+
+static void checksum_efuse_block(unsigned char *block)
+{
+	unsigned int Sum = 0;
+	int j;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (j = 0; j < 4; j++) {
+		if (j == 0)
+			Sum += block[j] & 0xF;
+		else
+			Sum += block[j];
+	}
+
+	while (Sum > 0xF)
+		Sum = (Sum & 0xF) + (Sum >> 4);
+
+	Sum = 0xF - Sum;
+
+	block[0] = (block[0] & 0xF) | ((Sum << 4) & 0xF0);
+}
+
+static void checksum_para_header(unsigned short *header)
+{
+	unsigned int Sum = 0;
+	unsigned short j;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (j = 0; j < 5; j++)
+		Sum += header[j];
+
+	while (Sum > 0xFFFF)
+		Sum = (Sum & 0xFFFF) + (Sum >> 16);
+
+	Sum = 0xFFFF - Sum;
+
+	header[5] = (Sum);
+}
+
+static int check_hex(char *temp, int size)
+{
+	int i = 0;
+	unsigned char *ptemp = temp;
+
+	for (i = 0; i < size; i++) {
+		if (ptemp[i] == ':') {
+			i++;
+			continue;
+		}
+		
+		if(!(isxdigit(ptemp[i])))
+			return -FAIL_INVALID_PARAMETER;
+	}
+
+	return 0;
+}
+
+static int check_led_parameter(char *led)
+{
+	if (!led)
+		return 1;
+
+	if (strlen(led) != 9 || led[4] != '_')
+		return 1;
+	do {
+		if (*led++ == '_')
+			continue;
+		if (!isxdigit(*led++))
+			return 1;
+	} while (*led);
+
+	return 0;
+}
+
+static int writeparameter_func(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	unsigned char *rpara_buf = NULL;
+	int para_offset, block_count, para_size, ret, block_index, c, i;
+	int oi = -1;
+	struct __wpara argument = {0};
+	int temp_para_offset = 0;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	while ((c = getopt_long(info->argc, info->argv,
+				"m:s:p:v:P:M:D:S:H:w:l:e:d:",
+				long_options, &oi)) != -1) {
+		switch (c) {
+		case 'm':
+			argument.mac_address = optarg;
+			DEBUG_PRINT("%s \r\n", argument.mac_address);
+			i = sscanf(argument.mac_address,
+				   "%02X:%02X:%02X:%02X:%02X:%02X",
+				   (unsigned int *)&argument.MAC[0],
+				   (unsigned int *)&argument.MAC[1],
+				   (unsigned int *)&argument.MAC[2],
+				   (unsigned int *)&argument.MAC[3],
+				   (unsigned int *)&argument.MAC[4],
+				   (unsigned int *)&argument.MAC[5]);
+			if (i != 6)
+				return print_msg("wpara");
+			break;
+		case 's':
+			argument.serial_num = optarg;
+			DEBUG_PRINT("%s \r\n", argument.serial_num);
+			if (strlen(argument.serial_num) > 18) {
+				printf("characters must be less than 19 bytes\n");
+				return print_msg("wpara");
+			}
+			break;
+		case 'p':
+			argument.PID = optarg;
+			DEBUG_PRINT("%s \r\n", argument.PID);
+			i = sscanf(argument.PID,
+				   "%02X:%02X",
+				   (unsigned int *)&argument.pid[0],
+				   (unsigned int *)&argument.pid[1]);
+			if (i != 2)
+				return print_msg("wpara");
+			break;
+		case 'v':
+			argument.VID = optarg;
+			DEBUG_PRINT("%s \r\n", argument.VID);
+			i = sscanf(argument.VID,
+				   "%02X:%02X",
+				   (unsigned int *)&argument.vid[0],
+				   (unsigned int *)&argument.vid[1]);
+			if (i != 2)
+				return print_msg("wpara");
+			break;
+		case 'P':
+			argument.product_string = optarg;
+			DEBUG_PRINT("%s \r\n", argument.product_string);
+			if (strlen(argument.product_string) > 18)
+				return print_msg("wpara");
+			break;
+		case 'D':
+			argument.dump = optarg;
+			DEBUG_PRINT("%s \r\n", argument.dump);
+			if (strcasecmp(argument.dump , "dump"))
+				return print_msg("wpara");
+			break;
+		case 'M':
+			argument.manufacture = optarg;
+			DEBUG_PRINT("%s \r\n", argument.manufacture);
+			if (strlen(argument.manufacture) > 18)
+				return print_msg("wpara");
+			break;
+		case 'S':
+			argument.ss_bus = optarg;
+			argument.iss_bus = atoi(argument.ss_bus);
+			DEBUG_PRINT("%s \r\n", argument.ss_bus);
+			break;
+		case 'H':
+			argument.hs_bus = optarg;
+			argument.ihs_bus = atoi(argument.hs_bus);
+			DEBUG_PRINT("%s \r\n", argument.hs_bus);
+			break;
+		case 'w':
+			argument.wol = optarg;
+			DEBUG_PRINT("%s \r\n", argument.wol);
+			break;
+		case 'l':
+			argument.led0 = optarg;
+			DEBUG_PRINT("%s \r\n", argument.led0);
+			i = sscanf(argument.led0,
+				   "%02X%02X_%02X%02X",
+				   (unsigned int *)&argument.LED0[0],
+				   (unsigned int *)&argument.LED0[1],
+				   (unsigned int *)&argument.LED0[2],
+				   (unsigned int *)&argument.LED0[3]);
+			break;
+		case 'e':
+			argument.led1 = optarg;
+			DEBUG_PRINT("%s \r\n", argument.led1);
+			i = sscanf(argument.led1,
+				   "%02X%02X_%02X%02X",
+				   (unsigned int *)&argument.LED1[0],
+				   (unsigned int *)&argument.LED1[1],
+				   (unsigned int *)&argument.LED1[2],
+				   (unsigned int *)&argument.LED1[3]);
+			break;
+		case '?':
+		default:
+			return -FAIL_INVALID_PARAMETER;
+		}
+	}
+
+	ret = scan_ax_device(ifr, info->inet_sock);
+	if (ret < 0) {
+		PRINT_SCAN_DEV_FAIL;
+		return ret;
+	}
+
+	rpara_buf = (unsigned char *)malloc((FLASH_SIZE + 256) & ~(0xFF));
+	if (!rpara_buf) {
+		PRINT_ALLCATE_MEM_FAIL;
+		ret = -FAIL_ALLCATE_MEM;
+		goto fail;
+	}
+	memset(rpara_buf, 0xFF, (FLASH_SIZE + 256) & ~(0xFF));
+
+	ret = read_flash(info, rpara_buf, 0, 0x3000);
+	if (ret < 0)
+		goto fail;
+
+	//temp_para_offset = calculate_para_offset(rpara_buf);
+
+	if (*(unsigned short *)&rpara_buf[PARAMETER_PRI_HEADER_OFFSET] != 0xA55A) {
+		//printf("Not 0xA55A, use sample\n");
+		para_offset = 0x3000;
+		block_count = 0;
+	} else {
+		para_offset = SWAP_32(*(unsigned long *)&rpara_buf[PARAMETER_PRI_OFFSET]);
+		block_count = SWAP_16(*(unsigned short *)&rpara_buf[PARAMETER_PRI_BLOCK_COUNT]);
+	}
+
+	para_size = 0;
+	if (block_count) {
+		para_size = block_count * FLASH_BLOCK_SIZE;
+		ret = read_flash(info, rpara_buf, para_offset, para_size);
+		if (ret < 0)
+			goto fail;
+	}
+
+	block_index = -FAIL_GENERIAL_ERROR;
+	if (argument.mac_address) {
+		if(check_hex(argument.mac_address, 17) == -FAIL_INVALID_PARAMETER) {
+			printf("\nFAIL: Char should be '0'-'9' & 'A(a)'-'F(f)'\n");
+			return -FAIL_INVALID_PARAMETER;
+		}
+
+		if(strlen(argument.mac_address) != 17) {
+			printf("FAIL: MAC address should be 6 bytes\n");
+			return -FAIL_INVALID_PARAMETER;
+		}
+
+		if (para_size)
+			block_index = find_block_index(&rpara_buf[para_offset], para_size, TYPE_01);
+		if (block_index == -FAIL_GENERIAL_ERROR) {
+			block_index = para_size / 20;
+			memcpy(&rpara_buf[para_offset + block_index * 20], sample_type1, 20);
+			para_size += 20;
+		}
+
+		ret = change_para_macaddr(&rpara_buf[para_offset], block_index, argument.MAC);
+		if (ret < 0) {
+			fprintf(stderr,
+				"%s: Changing MAC address failed.\n",
+				__func__);
+			goto fail;
+		}
+		checksum_efuse_block(&rpara_buf[para_offset + block_index * 20]);
+	}
+
+	if (argument.serial_num) {
+		if(check_hex(argument.serial_num, strlen(argument.serial_num)) == -FAIL_INVALID_PARAMETER) {
+			printf("\nFAIL: Char should be '0'-'9' & 'A(a)'-'F(f)'\n");
+			return -FAIL_INVALID_PARAMETER;
+		}
+
+		if (para_size)
+			block_index = find_block_index(&rpara_buf[para_offset], para_size, TYPE_04);
+		if (block_index == -FAIL_GENERIAL_ERROR) {
+			block_index = para_size / 20;
+			memcpy(&rpara_buf[para_offset + block_index * 20], sample_type4, 20);
+			para_size += 20;
+		}
+
+		ret = change_para_serialnum(&rpara_buf[para_offset], block_index, argument.serial_num);
+		if (ret < 0) {
+			fprintf(stderr,
+				"%s: Changing serial number failed.\n",
+				__func__);
+			goto fail;
+		}
+		checksum_efuse_block(&rpara_buf[para_offset + block_index * 20]);
+	}
+
+	if (argument.PID) {
+		if(check_hex(argument.PID, 5) == -FAIL_INVALID_PARAMETER) {
+			printf("\nFAIL: Char should be '0'-'9' & 'A(a)'-'F(f)'\n");
+			return -FAIL_INVALID_PARAMETER;
+		}
+
+		if(strlen(argument.PID) != 5) {
+			printf("FAIL: PID be 2 bytes\n");
+			return -FAIL_INVALID_PARAMETER;
+		}
+
+		if (para_size)
+			block_index = find_block_index(&rpara_buf[para_offset], para_size, TYPE_01);
+		if (block_index == -FAIL_GENERIAL_ERROR) {
+			block_index = para_size / 20;
+			memcpy(&rpara_buf[para_offset + block_index * 20], sample_type1, 20);
+			para_size += 20;
+		}
+
+		ret = change_para_pid(&rpara_buf[para_offset], block_index, argument.pid);
+		if (ret < 0) {
+			fprintf(stderr,
+				"%s: Changing PID failed.\n",
+				__func__);
+			goto fail;
+		}
+		checksum_efuse_block(&rpara_buf[para_offset + block_index * 20]);
+	}
+
+	if (argument.VID) {
+		if(check_hex(argument.VID, 5) == -FAIL_INVALID_PARAMETER) {
+			printf("\nFAIL: Char should be '0'-'9' & 'A(a)'-'F(f)'\n");
+			return -FAIL_INVALID_PARAMETER;
+		}
+
+		if(strlen(argument.VID) != 5) {
+			printf("FAIL: VID be 2 bytes\n");
+			return -FAIL_INVALID_PARAMETER;
+		}
+
+		if (para_size)
+			block_index = find_block_index(&rpara_buf[para_offset], para_size, TYPE_01);
+		if (block_index == -FAIL_GENERIAL_ERROR) {
+			block_index = para_size / 20;
+			memcpy(&rpara_buf[para_offset + block_index * 20], sample_type1, 20);
+			para_size += 20;
+		}
+
+		ret = change_para_vid(&rpara_buf[para_offset], block_index, argument.vid);
+		if (ret < 0) {
+			fprintf(stderr,
+				"%s: Changing VID failed.\n",
+				__func__);
+			goto fail;
+		}
+		checksum_efuse_block(&rpara_buf[para_offset + block_index * 20]);
+	}
+
+	if (argument.product_string) {
+		if (para_size)
+			block_index = find_block_index(&rpara_buf[para_offset], para_size, TYPE_03);
+		if (block_index == -FAIL_GENERIAL_ERROR) {
+			block_index = para_size / 20;
+			memcpy(&rpara_buf[para_offset + block_index * 20], sample_type3, 20);
+			para_size += 20;
+		}
+
+		ret = change_para_productstr(&rpara_buf[para_offset], block_index, argument.product_string);
+		if (ret < 0) {
+			fprintf(stderr,
+				"%s: Changing Product String failed.\n",
+				__func__);
+			goto fail;
+		}
+		checksum_efuse_block(&rpara_buf[para_offset + block_index * 20]);
+	}
+
+	if (argument.manufacture) {
+		if (para_size)
+			block_index = find_block_index(&rpara_buf[para_offset], para_size, TYPE_02);
+		if (block_index == -FAIL_GENERIAL_ERROR) {
+			block_index = para_size / 20;
+			memcpy(&rpara_buf[para_offset + block_index * 20], sample_type2, 20);
+			para_size += 20;
+		}
+
+		ret = change_para_manufacture(&rpara_buf[para_offset], block_index, argument.manufacture);
+		if (ret < 0) {
+			fprintf(stderr,
+				"%s: Changing manufacture failed.\n",
+				__func__);
+			goto fail;
+		}
+		checksum_efuse_block(&rpara_buf[para_offset + block_index * 20]);
+	}
+
+	if (argument.ss_bus) {
+		if (para_size)
+			block_index = find_block_index(&rpara_buf[para_offset], para_size, TYPE_01);
+		if (block_index == -FAIL_GENERIAL_ERROR) {
+			block_index = para_size / 20;
+			memcpy(&rpara_buf[para_offset + block_index * 20], sample_type1, 20);
+			para_size += 20;
+		}
+
+		if (argument.iss_bus > 896)	{
+			printf("FAIL: The value is between 0-896\n");
+			return -FAIL_INVALID_PARAMETER;
+		}
+
+		ret = change_para_ssbus(&rpara_buf[para_offset], block_index, argument.iss_bus);
+		if (ret < 0) {
+			fprintf(stderr,
+				"%s: Changing SS_MAX_BUS_PW failed.\n",
+				__func__);
+			goto fail;
+		}
+		checksum_efuse_block(&rpara_buf[para_offset + block_index * 20]);
+	}
+
+	if (argument.hs_bus) {
+		if (para_size)
+			block_index = find_block_index(&rpara_buf[para_offset], para_size, TYPE_01);
+		if (block_index == -FAIL_GENERIAL_ERROR) {
+			block_index = para_size / 20;
+			memcpy(&rpara_buf[para_offset + block_index * 20], sample_type1, 20);
+			para_size += 20;
+		}
+
+		if (argument.ihs_bus > 500)	{
+			printf("FAIL: The value is between 0-500\n");
+			return -FAIL_INVALID_PARAMETER;
+		}
+
+		ret = change_para_hsbus(&rpara_buf[para_offset], block_index, argument.ihs_bus);
+		if (ret < 0) {
+			fprintf(stderr,
+				"%s: Changing HS_MAX_BUS_PW failed.\n",
+				__func__);
+			goto fail;
+		}
+		checksum_efuse_block(&rpara_buf[para_offset + block_index * 20]);
+	}
+
+	if (argument.wol) {
+
+		int valid = 1;
+
+		if (para_size) {
+			block_index = find_block_index(&rpara_buf[para_offset], para_size, TYPE_15);
+			memcpy(&rpara_buf[para_offset + block_index * 20], sample_type15, 20);
+		}
+		if (block_index == -FAIL_GENERIAL_ERROR) {
+			block_index = para_size / 20;
+			memcpy(&rpara_buf[para_offset + block_index * 20], sample_type15, 20);
+			para_size += 20;
+		}
+
+		if (strlen(argument.wol) != 8)	{
+			printf("FAIL: The value must be 8 digit\n");
+			return -FAIL_INVALID_PARAMETER;
+		}
+
+		int time = 0;
+		for(time = 0; time < 8; time++) {
+			if (argument.wol[time] != '0' && argument.wol[time] != '1') {
+				printf("FAIL: The value must be 1 or 0\n");
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+
+		int count = 0;
+		for(time = 0; time < 8; time++) {
+			if (argument.wol[time] == '1')
+				count++;
+		}
+
+		if (count >= 1 && count != 8)
+			valid = 1;
+		else
+			valid = 0;
+
+		if (argument.wol[0] == '1') {
+			for(time = 1; time < 8; time++) {
+				if (argument.wol[time] == '1')
+					valid = 0;
+			}
+		} else if (argument.wol[0] == '0' && argument.wol[1] == '0') {
+			for(time = 2; time < 8; time++) {
+				if (argument.wol[time] == '1')
+					valid = 0;
+			}
+		}
+
+		if(!valid) {
+				printf("FAIL: The value is invalid\n");
+				return -FAIL_INVALID_PARAMETER;
+		}
+
+		ret = change_para_wol(&rpara_buf[para_offset], block_index, argument.wol);
+		if (ret < 0) {
+			fprintf(stderr,
+				"%s: Changing Wake on LAN failed.\n",
+				__func__);
+			goto fail;
+		}
+		checksum_efuse_block(&rpara_buf[para_offset + block_index * 20]);
+	}
+
+	if (argument.led0) {
+	/*	if (para_size)
+			block_index = find_block_index(&rpara_buf[para_offset], para_size, TYPE_11);*/
+	//	if (block_index == -FAIL_GENERIAL_ERROR) {
+			block_index = para_size / 20;
+			memcpy(&rpara_buf[para_offset + block_index * 20], sample_type11, 20);
+			para_size += 20;
+	//	}
+		if (check_led_parameter(argument.led0)) {
+			printf("FAIL: The value invaild.\n");
+			return -FAIL_INVALID_PARAMETER;
+		}
+
+		set_para_led0(&rpara_buf[para_offset], block_index, argument.LED0);
+
+		checksum_efuse_block(&rpara_buf[para_offset + block_index * 20]);
+	}
+
+	if (argument.led1) {
+	/*	if (para_size)
+			block_index = find_block_index(&rpara_buf[para_offset], para_size, TYPE_11);*/
+		//if (block_index == -FAIL_GENERIAL_ERROR) {
+			block_index = para_size / 20;
+			memcpy(&rpara_buf[para_offset + block_index * 20], sample_type11, 20);
+			para_size += 20;
+		//}
+		if (check_led_parameter(argument.led1)) {
+			printf("FAIL: The value invaild.\n");
+			return -FAIL_INVALID_PARAMETER;
+		}
+
+		set_para_led1(&rpara_buf[para_offset], block_index, argument.LED1);
+		
+		checksum_efuse_block(&rpara_buf[para_offset + block_index * 20]);
+	}
+
+	if (argument.dump) {
+		int i = 0;
+		unsigned char buf[32 * 20];
+		if (para_size == 0) {
+			printf("\nThe parameter content currently in flash has no data\n");
+			return -FAIL_INVALID_PARAMETER;
+		}
+		printf("\nDump the parameter content currently in flash as parameter.txt file\n");
+
+		FILE *file = fopen("parameter.txt", "w");
+		if (file == NULL) {
+			perror("Error opening file");
+			return -FAIL_INVALID_PARAMETER;
+		}
+
+		for (i = 0; i < para_size; i++) {
+			buf[i] = rpara_buf[para_offset + i];
+		}
+
+		for (i = 0; i < para_size; i++) {
+			fprintf(file, "%02X", buf[i]);
+
+			if(((i + 1) % 4 == 0))
+				fprintf(file, "\n");
+			else
+				fprintf(file, " ");
+		}
+
+		fclose(file);
+
+		dump(&rpara_buf[para_offset], para_size);
+	}
+
+	erase_sector_flash(info, PARAMETER_PRI_HEADER_OFFSET);
+	erase_sector_flash(info, para_offset);
+
+
+	if (*(unsigned short *)&rpara_buf[PARAMETER_PRI_HEADER_OFFSET] != 0xA55A) {
+		//printf("Not 0xA55A, create header\n");
+		rpara_buf[PARAMETER_PRI_HEADER_OFFSET] = 0x5A;
+		rpara_buf[PARAMETER_PRI_HEADER_OFFSET + 1] = 0xA5;
+		rpara_buf[PARAMETER_PRI_HEADER_OFFSET + 2] = 0x04;
+		rpara_buf[PARAMETER_PRI_HEADER_OFFSET + 3] = 0;
+	}
+	*(unsigned int *)&rpara_buf[PARAMETER_PRI_OFFSET] = SWAP_32(para_offset);
+	*(unsigned short *)&rpara_buf[PARAMETER_PRI_BLOCK_COUNT] = SWAP_16(para_size / 20);
+	checksum_para_header((unsigned short *)&rpara_buf[PARAMETER_PRI_HEADER_OFFSET]);
+
+	write_flash(info, rpara_buf, PARAMETER_PRI_HEADER_OFFSET, 256);
+	write_flash(info, rpara_buf, para_offset, para_size);
+
+	sw_reset(info);
+fail:
+	if (rpara_buf)
+		free(rpara_buf);
+
+	return 0;
+}
+
+static int reload_func(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	char fw_version[16] = {0};
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	if (info->argc != 2) {
+		int i;
+
+		for (i = 0; ax88279_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], ax88279_cmd_list[i].cmd,
+				    strlen(ax88279_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", ax88279_cmd_list[i].help_ins,
+				       ax88279_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	if (scan_ax_device(ifr, info->inet_sock)) {
+		PRINT_SCAN_DEV_FAIL;
+		return -FAIL_SCAN_DEV;
+	}
+
+	autosuspend_enable(info, 0);
+
+	sw_reset(info);
+
+	if (scan_ax_device(ifr, info->inet_sock)) {
+		PRINT_SCAN_DEV_FAIL;
+		return -FAIL_SCAN_DEV;
+	}
+
+	return SUCCESS;
+}
+
+static int scan_ax_device(struct ifreq *ifr, int inet_sock)
+{
+	unsigned int retry;
+
+	DEBUG_PRINT("=== %s - Start\n", __func__);
+
+	for (retry = 0; retry < SCAN_DEV_MAX_RETRY; retry++) {
+		unsigned int i;
+		struct _ax_ioctl_command ioctl_cmd;
+#if NET_INTERFACE == INTERFACE_SCAN
+		struct ifaddrs *addrs, *tmp;
+		unsigned char	dev_exist;
+
+		getifaddrs(&addrs);
+		tmp = addrs;
+		dev_exist = 0;
+
+		while (tmp) {
+			memset(&ioctl_cmd, 0,
+			       sizeof(struct _ax_ioctl_command));
+			ioctl_cmd.ioctl_cmd = AX_SIGNATURE;
+
+			sprintf(ifr->ifr_name, "%s", tmp->ifa_name);
+			tmp = tmp->ifa_next;
+
+			ioctl(inet_sock, SIOCGIFFLAGS, ifr);
+			if (!(ifr->ifr_flags & IFF_UP))
+				continue;
+
+			ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+			if (ioctl(inet_sock, AX_PRIVATE, ifr) < 0)
+				continue;
+
+			if (strncmp(ioctl_cmd.sig,
+				    AX88179A_DRV_NAME,
+				    strlen(AX88179A_DRV_NAME)) == 0) {
+				dev_exist = 1;
+				break;
+			}
+		}
+
+		freeifaddrs(addrs);
+
+		if (dev_exist)
+			break;
+#else
+		for (i = 0; i < 255; i++) {
+
+			memset(&ioctl_cmd, 0,
+			       sizeof(struct _ax_ioctl_command));
+			ioctl_cmd.ioctl_cmd = AX_SIGNATURE;
+
+			sprintf(ifr->ifr_name, "eth%u", i);
+
+			ioctl(inet_sock, SIOCGIFFLAGS, ifr);
+			if (!(ifr->ifr_flags & IFF_UP))
+				continue;
+
+			ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+			if (ioctl(inet_sock, AX_PRIVATE, ifr) < 0)
+				continue;
+
+			if (strncmp(ioctl_cmd.sig,
+				    AX88179A_DRV_NAME,
+				    strlen(AX88179A_DRV_NAME)) == 0)
+				break;
+
+		}
+
+		if (i < 255)
+			break;
+#endif
+		usleep(500000);
+	}
+
+	if (retry >= SCAN_DEV_MAX_RETRY)
+		return -FAIL_SCAN_DEV;
+
+	return SUCCESS;
+}
+
+int main(int argc, char **argv)
+{
+	struct ifreq ifr;
+	struct ax_command_info info;
+	unsigned int i;
+	int inet_sock, ret = -FAIL_GENERIAL_ERROR;
+
+	//printf("%s\n", AX88179A_IOCTL_VERSION);
+
+	if (argc < 2) {
+		show_usage();
+		return SUCCESS;
+	}
+
+	inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
+#ifndef NOT_PROGRAM 
+	if (scan_ax_device(&ifr, inet_sock)) {
+		printf("No %s found\n", AX88179A_SIGNATURE);
+		return FAIL_SCAN_DEV;
+	}
+#endif
+	for (i = 0; ax88279_cmd_list[i].cmd != NULL; i++) {
+		if (strncmp(argv[1],
+			    ax88279_cmd_list[i].cmd,
+			    strlen(ax88279_cmd_list[i].cmd)) == 0) {
+			info.help_ins = ax88279_cmd_list[i].help_ins;
+			info.help_desc = ax88279_cmd_list[i].help_desc;
+			info.ifr = &ifr;
+			info.argc = argc;
+			info.argv = argv;
+			info.inet_sock = inet_sock;
+			info.ioctl_cmd = ax88279_cmd_list[i].ioctl_cmd;
+			ret = (ax88279_cmd_list[i].OptFunc)(&info);
+			goto out;
+		}
+	}
+
+	if (ax88279_cmd_list[i].cmd == NULL) {
+		show_usage();
+		return SUCCESS;
+	}
+out:
+	if (ret == SUCCESS)
+		printf("SUCCESS\n");
+	else if (ret != -FAIL_INVALID_PARAMETER)
+		printf("FAIL\n");
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/ax_ioctl.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/ax_ioctl.h
@@ -0,0 +1,212 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*******************************************************************************
+ *     Copyright (c) 2022    ASIX Electronic Corporation    All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+#ifndef __ASIX_IOCTL_H
+#define __ASIX_IOCTL_H
+
+#ifdef ENABLE_IOCTL_DEBUG
+#define DEBUG_PRINT(fmt, args...) printf(fmt, ## args)
+#define DEBUG_PRINTK(fmt, args...) printk(fmt, ## args)
+#else
+#define DEBUG_PRINT(fmt, args...)
+#define DEBUG_PRINTK(fmt, args...)
+#endif
+
+// CHANGE NETWORK INTERFACE WAY
+// DEFAULT_SCAN   : scan "eth0" - "eth255"
+// INTERFACE_SCAN : scan all available network interfaces
+#define NET_INTERFACE	INTERFACE_SCAN
+#define DEFAULT_SCAN	0x00
+#define INTERFACE_SCAN	0x01
+
+#define AX88179_SIGNATURE	"AX88179_178A"
+#define AX88179_DRV_NAME	"AX88179_178A"
+#define AX88179A_SIGNATURE	"AX88179B_179A_772E_772D"
+#define AX88179A_DRV_NAME	"AX88179B_179A_772E_772D"
+
+#define AX_PRIVATE		SIOCDEVPRIVATE
+
+#define AX_SIGNATURE			0
+#define AX_USB_COMMAND			1
+#define AX88179_READ_EEPROM		2
+#define AX88179_WRITE_EEPROM		3
+#define AX88179A_READ_VERSION		2
+#define AX88179A_WRITE_FLASH		3
+#define AX88179A_ROOT_2_ROM		4
+#define AX88179A_ERASE_FLASH		5
+#define AX88179A_SW_RESET		6
+#define AX88179A_READ_FLASH		7
+#define AX88179A_PROGRAM_EFUSE		8
+#define AX88179A_DUMP_EFUSE		9
+#define AX88179A_IEEE_TEST		10
+#define AX88179A_AUTOSUSPEND_EN		11
+#define AX88179A_ERASE_SECTOR_FLASH	12
+
+#define IEEE_1000M1			0
+#define IEEE_1000M2			1
+#define IEEE_1000M3			2
+#define IEEE_1000M4			3
+#define IEEE_100CA			4
+#define IEEE_100CB			5
+#define IEEE_10R			6
+#define IEEE_10FF			7
+#define IEEE_10MDI			8
+
+#define ERR_FALSH_WRITE_EN		1
+#define ERR_FALSH_WRITE_DIS		2
+#define ERR_FALSH_ERASE_ALL		3
+#define ERR_FALSH_WRITE			4
+#define ERR_FALSH_READ			5
+#define ERR_EFUSE_READ			6
+#define ERR_EFUSE_WRITE			7
+#define ERR_IEEE_INVALID_CHIP		8
+#define ERR_BOOT_CODE			9
+#define ERR_FALSH_ERASE_SECTOR	10
+
+#define USB_READ_OPS			0
+#define USB_WRITE_OPS			1
+
+#define SCAN_DEV_MAX_RETRY		10
+
+#define FLASH_BLOCK_SIZE	20 //bytes
+#define WRITE_PARA_HEADER 0x2100
+#define FLASH_SIZE (16*1024*1024)
+#define FLASH_PARA_OFFSET 8448
+
+#define PRAM_PRI_FW1_OFFSET 0x0
+#define PRAM_PRI_FW1_LENGTH 0x4
+#define MD32_PRI_FW1_OFFSET 0x14
+#define MD32_PRI_FW1_LENGTH 0x18
+
+#define PRAM_SEC_FW1_OFFSET 0x28
+#define PRAM_SEC_FW1_LENGTH 0x2C
+#define MD32_SEC_FW1_OFFSET 0x3C
+#define MD32_SEC_FW1_LENGTH 0x40
+
+#define PRAM_PRI_FW2_OFFSET 0x1000
+#define PRAM_PRI_FW2_LENGTH 0x1004
+#define MD32_PRI_FW2_OFFSET 0x1014
+#define MD32_PRI_FW2_LENGTH 0x1018
+
+#define PRAM_SEC_FW2_OFFSET 0x1028
+#define PRAM_SEC_FW2_LENGTH 0x102C
+#define MD32_SEC_FW2_OFFSET 0x103C
+#define MD32_SEC_FW2_LENGTH 0x1040
+
+#define PARAMETER_PRI_HEADER_OFFSET 0x2000
+#define PARAMETER_SEC_HEADER_OFFSET 0x200C
+
+#define PARAMETER_PRI_OFFSET 0x2004
+#define PARAMETER_PRI_BLOCK_COUNT 0x2008
+#define PARAMETER_SEC_OFFSET 0x2010
+#define PARAMETER_SEC_BLOCK_COUNT 0x2014
+
+
+enum _exit_code {
+	SUCCESS			= 0,
+	FAIL_INVALID_PARAMETER	= 1,
+	FAIL_IOCTL,
+	FAIL_SCAN_DEV,
+	FAIL_ALLCATE_MEM,
+	FAIL_LOAD_FILE,
+	FAIL_FLASH_WRITE,
+	FAIL_IVALID_VALUE,
+	FAIL_IVALID_CHKSUM,
+	FAIL_NON_EMPTY_RFUSE_BLOCK,
+	FAIL_EFUSE_WRITE,
+	FAIL_GENERIAL_ERROR,
+};
+
+struct _ax_usb_command {
+	unsigned char	ops;
+	unsigned char	cmd;
+	unsigned short	value;
+	unsigned short	index;
+	unsigned short	size;
+	unsigned char	*data;
+	unsigned long	cmd_data;
+};
+
+struct _ax88179a_flash {
+	int status;
+	int length;
+	int offset;
+	unsigned char *buf;
+};
+
+struct _ax88179a_version {
+	unsigned char version[16];
+};
+
+struct _ax88179a_ieee {
+	unsigned int type;
+	unsigned int speed;
+	unsigned int stop;
+	int status;
+};
+
+struct _ax88179a_autosuspend {
+	unsigned int enable;
+};
+
+struct _ax_ioctl_command {
+	unsigned short	ioctl_cmd;
+	unsigned char	sig[32];
+	unsigned char	type;
+	unsigned short *buf;
+	unsigned short size;
+	unsigned char delay;
+	union {
+		struct _ax88179a_flash		flash;
+		struct _ax88179a_version	version;
+		struct _ax88179a_ieee		ieee;
+		struct _ax_usb_command		usb_cmd;
+		struct _ax88179a_autosuspend	autosuspend;
+	};
+};
+
+#define SWAP_32(val)	(((val >> 24) & 0x000000FF) | \
+			 ((val >>  8) & 0x0000FF00) | \
+			 ((val <<  8) & 0x00FF0000) | \
+			 ((val << 24) & 0xFF000000))
+#define SWAP_16(val)    ((val >> 8) & 0x00FF) | \
+                         ((val <<  8) & 0xFF00)
+
+struct ax_device;
+typedef int (*IOCTRL_TABLE)(struct ax_device *axdev,
+			    struct _ax_ioctl_command *info);
+
+struct ax_command_info {
+	int inet_sock;
+	struct ifreq *ifr;
+	int argc;
+	char **argv;
+	unsigned short ioctl_cmd;
+	const char *help_ins;
+	const char *help_desc;
+};
+
+typedef int (*MENU_FUNC)(struct ax_command_info *info);
+
+struct _command_list {
+	char *cmd;
+	unsigned short ioctl_cmd;
+	MENU_FUNC OptFunc;
+	const char *help_ins;
+	const char *help_desc;
+};
+
+#endif /* __ASIX_IOCTL_H */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/ax_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/ax_main.c
@@ -0,0 +1,2573 @@
+// SPDX-License-Identifier: GPL-2.0
+/*******************************************************************************
+ *     Copyright (c) 2022    ASIX Electronic Corporation    All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+#include "ax_main.h"
+#include "ax88179_178a.h"
+#include "ax88179a_772d.h"
+#ifdef ENABLE_PTP_FUNC
+#include "ax_ptp.h"
+#endif
+
+#ifdef ENABLE_AUTODETACH_FUNC
+static int autodetach = -1;
+module_param(autodetach, int, 0);
+MODULE_PARM_DESC(autodetach, "Autodetach configuration");
+#endif
+
+static int bctrl = -1;
+module_param(bctrl, int, 0);
+MODULE_PARM_DESC(bctrl, "RX Bulk Control");
+
+static int blwt = -1;
+module_param(blwt, int, 0);
+MODULE_PARM_DESC(blwt, "RX Bulk Timer Low");
+
+static int bhit = -1;
+module_param(bhit, int, 0);
+MODULE_PARM_DESC(bhit, "RX Bulk Timer High");
+
+static int bsize = -1;
+module_param(bsize, int, 0);
+MODULE_PARM_DESC(bsize, "RX Bulk Queue Size");
+
+static int bifg = -1;
+module_param(bifg, int, 0);
+MODULE_PARM_DESC(bifg, "RX Bulk Inter Frame Gap");
+
+static int
+ax_submit_rx(struct ax_device *netdev, struct rx_desc *desc, gfp_t mem_flags);
+static void ax_set_carrier(struct ax_device *axdev);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0)
+void ax_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
+{
+	struct ax_device *axdev = netdev_priv(net);
+
+	strscpy(info->driver, MODULENAME, sizeof(info->driver));
+	strscpy(info->version, DRIVER_VERSION, sizeof(info->version));
+	usb_make_path(axdev->udev, info->bus_info, sizeof(info->bus_info));
+
+	sprintf(info->fw_version, "v%d.%d.%d.%d",
+		axdev->fw_version[0], axdev->fw_version[1],
+		axdev->fw_version[2], axdev->fw_version[3]);
+}
+#else
+static size_t ax_strscpy(char *dest, const char *src, size_t size)
+{
+	size_t len = strnlen(src, size) + 1;
+	if(len > size) {
+		if (size)
+			dest[0] = '\0';
+		return 0;
+	}
+	memcpy(dest, src, len);
+	return len;
+}
+
+void ax_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
+{
+	struct ax_device *axdev = netdev_priv(net);
+
+	ax_strscpy(info->driver, MODULENAME, sizeof(info->driver));
+	ax_strscpy(info->version, DRIVER_VERSION, sizeof(info->version));
+	usb_make_path(axdev->udev, info->bus_info, sizeof(info->bus_info));
+
+	sprintf(info->fw_version, "v%d.%d.%d.%d",
+		axdev->fw_version[0], axdev->fw_version[1],
+		axdev->fw_version[2], axdev->fw_version[3]);
+}	
+#endif
+
+#if KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE
+int ax_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	int ret;
+
+	if (!axdev->mii.mdio_read)
+		return -EOPNOTSUPP;
+
+	ret = usb_autopm_get_interface(axdev->intf);
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&axdev->control);
+
+	mii_ethtool_gset(&axdev->mii, cmd);
+
+	mutex_unlock(&axdev->control);
+
+	usb_autopm_put_interface(axdev->intf);
+
+	return 0;
+}
+
+int ax_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	int ret;
+
+	ret = usb_autopm_get_interface(axdev->intf);
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&axdev->control);
+
+	mii_ethtool_sset(&axdev->mii, cmd);
+
+	mutex_unlock(&axdev->control);
+
+	usb_autopm_put_interface(axdev->intf);
+
+	return 0;
+}
+#else
+int ax_get_link_ksettings(struct net_device *netdev,
+			  struct ethtool_link_ksettings *cmd)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	int ret;
+
+	if (!axdev->mii.mdio_read)
+		return -EOPNOTSUPP;
+
+	ret = usb_autopm_get_interface(axdev->intf);
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&axdev->control);
+
+	mii_ethtool_get_link_ksettings(&axdev->mii, cmd);
+
+#ifdef ENABLE_AX88279
+	//printk("============AX88279==========");
+	if (axdev->chip_version == AX_VERSION_AX88279) {
+#if KERNEL_VERSION(5, 0, 0) <= LINUX_VERSION_CODE
+		linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+			 cmd->link_modes.supported, 1);
+
+		linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+				 cmd->link_modes.advertising,
+				 1);
+
+		linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+				 cmd->link_modes.lp_advertising,
+				 1);
+#else
+		__set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+			 cmd->link_modes.supported);
+
+		__set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+				 cmd->link_modes.advertising);
+
+		__set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+				 cmd->link_modes.lp_advertising);
+#endif
+		if (axdev->intr_link_info.eth_speed == ETHER_LINK_2500)
+			cmd->base.speed = SPEED_2500;
+	}
+#endif
+
+	mutex_unlock(&axdev->control);
+
+	usb_autopm_put_interface(axdev->intf);
+
+	return 0;
+}
+
+int ax_set_link_ksettings(struct net_device *netdev,
+			  const struct ethtool_link_ksettings *cmd)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	int ret;
+
+	ret = usb_autopm_get_interface(axdev->intf);
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&axdev->control);
+
+	mii_ethtool_set_link_ksettings(&axdev->mii, cmd);
+
+	mutex_unlock(&axdev->control);
+
+	usb_autopm_put_interface(axdev->intf);
+
+	return 0;
+}
+#endif
+u32 ax_get_msglevel(struct net_device *netdev)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+
+	return axdev->msg_enable;
+}
+
+void ax_set_msglevel(struct net_device *netdev, u32 value)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+
+	axdev->msg_enable = value;
+}
+
+void ax_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wolinfo)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	u8 reg8;
+	int ret;
+
+	ret = ax_read_cmd(axdev, AX_ACCESS_MAC, AX_MONITOR_MODE,
+			  1, 1, &reg8, 0);
+	if (ret < 0) {
+		wolinfo->supported = 0;
+		wolinfo->wolopts = 0;
+		return;
+	}
+
+	wolinfo->supported = WAKE_PHY | WAKE_MAGIC;
+
+	if (reg8 & AX_MONITOR_MODE_RWLC)
+		wolinfo->wolopts |= WAKE_PHY;
+	if (reg8 & AX_MONITOR_MODE_RWMP)
+		wolinfo->wolopts |= WAKE_MAGIC;
+}
+
+int ax_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wolinfo)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	u8 reg8 = 0;
+	int ret;
+
+	if (wolinfo->wolopts & WAKE_PHY)
+		reg8 |= AX_MONITOR_MODE_RWLC;
+	else
+		reg8 &= ~AX_MONITOR_MODE_RWLC;
+
+	if (wolinfo->wolopts & WAKE_MAGIC)
+		reg8 |= AX_MONITOR_MODE_RWMP;
+	else
+		reg8 &= ~AX_MONITOR_MODE_RWMP;
+
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX_MONITOR_MODE, 1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static const char ax_gstrings[][ETH_GSTRING_LEN] = {
+	"tx_packets",
+	"rx_packets",
+	"tx_bytes",
+	"rx_bytes",
+	"tx_dropped",
+	"rx_length_errors",
+	"rx_crc_errors",
+	"rx_dropped",
+	"buikin_complete",
+	"bulkin_error",
+	"bulkout_complete",
+	"bulkout_error",
+	"bulkint_complete",
+	"bulkint_error",
+#ifdef ENABLE_QUEUE_PRIORITY
+	"ep5_count",
+	"ep3_count",
+#endif
+};
+
+int ax_get_sset_count(struct net_device *netdev, int sset)
+{
+	switch (sset) {
+	case ETH_SS_STATS:
+		return ARRAY_SIZE(ax_gstrings);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+void ax_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
+{
+
+	switch (stringset) {
+	case ETH_SS_STATS:
+		memcpy(data, ax_gstrings, sizeof(ax_gstrings));
+		break;
+	}
+}
+
+void ax_get_ethtool_stats(struct net_device *netdev,
+			  struct ethtool_stats *stats, u64 *data)
+{
+	struct net_device_stats *net_stats = ax_get_stats(netdev);
+	struct ax_device *axdev = netdev_priv(netdev);
+	u64 *temp = data;
+
+	*temp++ = net_stats->tx_packets;
+	*temp++ = net_stats->rx_packets;
+	*temp++ = net_stats->tx_bytes;
+	*temp++ = net_stats->rx_bytes;
+	*temp++ = net_stats->tx_dropped;
+	*temp++ = net_stats->rx_length_errors;
+	*temp++ = net_stats->rx_crc_errors;
+	*temp++ = net_stats->rx_dropped;
+	*temp++ = axdev->bulkin_complete;
+	*temp++ = axdev->bulkin_error;
+	*temp++ = axdev->bulkout_complete;
+	*temp++ = axdev->bulkout_error;
+	*temp++ = axdev->bulkint_complete;
+	*temp++ = axdev->bulkint_error;
+#ifdef ENABLE_QUEUE_PRIORITY
+	*temp++ = axdev->ep5_count;
+	*temp++ = axdev->ep3_count;
+#endif
+}
+
+void ax_get_pauseparam(struct net_device *netdev,
+		       struct ethtool_pauseparam *pause)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	u16 bmcr, lcladv, rmtadv;
+	u8 cap;
+
+	if (usb_autopm_get_interface(axdev->intf) < 0)
+		return;
+
+	bmcr = ax_mdio_read(netdev, axdev->mii.phy_id, MII_BMCR);
+	lcladv = ax_mdio_read(netdev, axdev->mii.phy_id, MII_ADVERTISE);
+	rmtadv = ax_mdio_read(netdev, axdev->mii.phy_id, MII_LPA);
+
+	usb_autopm_put_interface(axdev->intf);
+
+	if (!(bmcr & BMCR_ANENABLE)) {
+		pause->autoneg = 0;
+		pause->rx_pause = 0;
+		pause->tx_pause = 0;
+		return;
+	}
+
+	pause->autoneg = 1;
+
+	cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv);
+
+	if (cap & FLOW_CTRL_RX)
+		pause->rx_pause = 1;
+
+	if (cap & FLOW_CTRL_TX)
+		pause->tx_pause = 1;
+}
+
+int ax_set_pauseparam(struct net_device *netdev,
+		      struct ethtool_pauseparam *pause)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	u16 old, new1, bmcr;
+	u8 cap = 0;
+	int ret;
+
+	ret = usb_autopm_get_interface(axdev->intf);
+	if (ret < 0)
+		return ret;
+
+	mutex_lock(&axdev->control);
+
+	bmcr = ax_mdio_read(netdev, axdev->mii.phy_id, MII_BMCR);
+	if (pause->autoneg && !(bmcr & BMCR_ANENABLE)) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (pause->rx_pause)
+		cap |= FLOW_CTRL_RX;
+
+	if (pause->tx_pause)
+		cap |= FLOW_CTRL_TX;
+
+	old = ax_mdio_read(netdev, axdev->mii.phy_id, MII_ADVERTISE);
+	new1 = (old & ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM)) |
+		mii_advertise_flowctrl(cap);
+	if (old != new1)
+		ax_mdio_write(netdev, axdev->mii.phy_id, MII_ADVERTISE, new1);
+
+	mii_nway_restart(&axdev->mii);
+out:
+	mutex_unlock(&axdev->control);
+	usb_autopm_put_interface(axdev->intf);
+
+	return ret;
+}
+
+int ax_get_regs_len(struct net_device *netdev)
+{
+	return 256;
+}
+
+void ax_get_regs(struct net_device *netdev,
+		 struct ethtool_regs *regs, void *buf)
+{
+	u8 *data = (u8 *)buf;
+	int i;
+	struct ax_device *axdev = netdev_priv(netdev);
+
+	for (i = 0; i < 256; i++)
+		ax_read_cmd(axdev, AX_ACCESS_MAC, i, 1, 1, &data[i], 0);
+}
+
+static int __ax_usb_read_cmd(struct ax_device *axdev, u8 cmd, u8 reqtype,
+			     u16 value, u16 index, void *data, u16 size)
+{
+	void *buf = NULL;
+	int err = -ENOMEM;
+
+	if (size) {
+		buf = kzalloc(size, GFP_KERNEL);
+		if (!buf)
+			goto out;
+	}
+
+	err = usb_control_msg(axdev->udev, usb_rcvctrlpipe(axdev->udev, 0),
+			      cmd, reqtype, value, index, buf, size,
+			      USB_CTRL_GET_TIMEOUT);
+	if (err > 0 && err <= size) {
+		if (data)
+			memcpy(data, buf, err);
+		else
+			netdev_dbg(axdev->netdev,
+				   "Huh? Data requested but thrown away.\n");
+	}
+
+	kfree(buf);
+out:
+	return err;
+}
+
+static int __ax_usb_write_cmd(struct ax_device *axdev, u8 cmd, u8 reqtype,
+			      u16 value, u16 index, const void *data, u16 size)
+{
+	void *buf = NULL;
+	int err = -ENOMEM;
+
+	if (data) {
+		buf = kmemdup(data, size, GFP_KERNEL);
+		if (!buf)
+			goto out;
+	} else {
+		if (size) {
+			WARN_ON_ONCE(1);
+			err = -EINVAL;
+			goto out;
+		}
+	}
+
+	err = usb_control_msg(axdev->udev, usb_sndctrlpipe(axdev->udev, 0),
+			      cmd, reqtype, value, index, buf, size,
+			      USB_CTRL_SET_TIMEOUT);
+	kfree(buf);
+
+out:
+	return err;
+}
+
+static int __ax_read_cmd(struct ax_device *axdev, u8 cmd, u8 reqtype,
+			 u16 value, u16 index, void *data, u16 size)
+{
+	int ret;
+
+	if (usb_autopm_get_interface(axdev->intf) < 0)
+		return -ENODEV;
+
+	ret = __ax_usb_read_cmd(axdev, cmd, reqtype, value, index,
+				data, size);
+
+	usb_autopm_put_interface(axdev->intf);
+
+	return ret;
+}
+
+static int __ax_write_cmd(struct ax_device *axdev, u8 cmd, u8 reqtype,
+			  u16 value, u16 index, const void *data, u16 size)
+{
+	int ret;
+
+	if (usb_autopm_get_interface(axdev->intf) < 0)
+		return -ENODEV;
+
+	ret = __ax_usb_write_cmd(axdev, cmd, reqtype, value, index,
+				 data, size);
+
+	usb_autopm_put_interface(axdev->intf);
+
+	return ret;
+}
+
+static int __ax_read_cmd_nopm(struct ax_device *axdev, u8 cmd, u8 reqtype,
+			      u16 value, u16 index, void *data, u16 size)
+{
+	return __ax_usb_read_cmd(axdev, cmd, reqtype, value, index,
+				 data, size);
+}
+
+static int __ax_write_cmd_nopm(struct ax_device *axdev, u8 cmd, u8 reqtype,
+			       u16 value, u16 index, const void *data,
+			       u16 size)
+{
+	return __ax_usb_write_cmd(axdev, cmd, reqtype, value, index,
+				  data, size);
+}
+
+static int __asix_read_cmd(struct ax_device *axdev, u8 cmd, u16 value,
+			   u16 index, u16 size, void *data, int in_pm)
+{
+	int ret;
+	_usb_read_function fn;
+
+	if (!in_pm)
+		fn = __ax_read_cmd;
+	else
+		fn = __ax_read_cmd_nopm;
+
+	ret = fn(axdev, cmd, USB_DIR_IN | USB_TYPE_VENDOR |
+		 USB_RECIP_DEVICE, value, index, data, size);
+
+	if (unlikely(ret < 0))
+		dev_warn(&axdev->intf->dev,
+			 "Failed to read reg %04X_%04X_%04X_%04X (err %d)",
+			 cmd, value, index, size, ret);
+
+	return ret;
+}
+
+static int __asix_write_cmd(struct ax_device *axdev, u8 cmd, u16 value,
+			    u16 index, u16 size, void *data, int in_pm)
+{
+	int ret;
+	_usb_write_function fn;
+
+	if (!in_pm)
+		fn = __ax_write_cmd;
+	else
+		fn = __ax_write_cmd_nopm;
+
+	ret = fn(axdev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR |
+		 USB_RECIP_DEVICE, value, index, data, size);
+
+	if (unlikely(ret < 0))
+		dev_warn(&axdev->intf->dev,
+			 "Failed to write reg %04X_%04X_%04X_%04X (err %d)",
+			 cmd, value, index, size, ret);
+
+	return ret;
+}
+
+int ax_read_cmd_nopm(struct ax_device *dev, u8 cmd, u16 value,
+		     u16 index, u16 size, void *data, int eflag)
+{
+	int ret;
+
+	if (eflag && (size == 2)) {
+		u16 buf = 0;
+
+		ret = __asix_read_cmd(dev, cmd, value, index, size, &buf, 1);
+		le16_to_cpus(&buf);
+		*((u16 *)data) = buf;
+	} else if (eflag && (size == 4)) {
+		u32 buf = 0;
+
+		ret = __asix_read_cmd(dev, cmd, value, index, size, &buf, 1);
+		le32_to_cpus(&buf);
+		*((u32 *)data) = buf;
+	} else {
+		ret = __asix_read_cmd(dev, cmd, value, index, size, data, 1);
+	}
+
+	return ret;
+}
+
+int ax_write_cmd_nopm(struct ax_device *dev, u8 cmd, u16 value,
+		      u16 index, u16 size, void *data)
+{
+	int ret;
+
+	if (size == 2) {
+		u16 buf = 0;
+
+		buf = *((u16 *)data);
+		cpu_to_le16s(&buf);
+		ret = __asix_write_cmd(dev, cmd, value, index,
+					  size, &buf, 1);
+	} else {
+		ret = __asix_write_cmd(dev, cmd, value, index,
+					  size, data, 1);
+	}
+
+	return ret;
+}
+
+int ax_read_cmd(struct ax_device *dev, u8 cmd, u16 value, u16 index, u16 size,
+		void *data, int eflag)
+{
+	int ret;
+
+	if (eflag && (size == 2)) {
+		u16 buf = 0;
+
+		ret = __asix_read_cmd(dev, cmd, value, index, size, &buf, 0);
+		le16_to_cpus(&buf);
+		*((u16 *)data) = buf;
+	} else if (eflag && (size == 4)) {
+		u32 buf = 0;
+
+		ret = __asix_read_cmd(dev, cmd, value, index, size, &buf, 0);
+		le32_to_cpus(&buf);
+		*((u32 *)data) = buf;
+	} else {
+		ret = __asix_read_cmd(dev, cmd, value, index, size, data, 0);
+	}
+
+	return ret;
+}
+
+int ax_write_cmd(struct ax_device *dev, u8 cmd, u16 value, u16 index, u16 size,
+		 void *data)
+{
+	int ret;
+
+	if (size == 2) {
+		u16 buf = 0;
+
+		buf = *((u16 *)data);
+		cpu_to_le16s(&buf);
+		ret = __asix_write_cmd(dev, cmd, value, index,
+					size, &buf, 0);
+	} else {
+		ret = __asix_write_cmd(dev, cmd, value, index,
+					size, data, 0);
+	}
+
+	return ret;
+}
+
+#if KERNEL_VERSION(2, 6, 20) > LINUX_VERSION_CODE
+static void ax_async_write_callback(struct urb *urb, struct pt_regs *regs)
+#else
+static void ax_async_write_callback(struct urb *urb)
+#endif
+{
+	struct _async_cmd_handle *asyncdata = (typeof(asyncdata))urb->context;
+
+	if (urb->status < 0)
+		dev_err(&asyncdata->axdev->intf->dev,
+			"ax_async_write_callback() failed with %d",
+			urb->status);
+
+	kfree(asyncdata->req);
+	kfree(asyncdata);
+	usb_free_urb(urb);
+}
+
+int ax_write_cmd_async(struct ax_device *axdev, u8 cmd, u16 value, u16 index,
+		       u16 size, void *data)
+{
+	struct usb_ctrlrequest *req = NULL;
+	int status = 0;
+	struct urb *urb = NULL;
+	void *buf = NULL;
+	struct _async_cmd_handle *asyncdata = NULL;
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (urb == NULL) {
+		netdev_err(axdev->netdev,
+			   "Error allocating URB in %s!", __func__);
+		return -ENOMEM;
+	}
+
+	req = kzalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC);
+	if (!req) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+
+	asyncdata = kzalloc(sizeof(struct _async_cmd_handle), GFP_ATOMIC);
+	if (asyncdata == NULL) {
+		kfree(req);
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+
+	asyncdata->req = req;
+	asyncdata->axdev = axdev;
+
+	if (size == 2) {
+		asyncdata->rxctl = *((u16 *)data);
+		cpu_to_le16s(&asyncdata->rxctl);
+		buf = &asyncdata->rxctl;
+	} else {
+		memcpy(asyncdata->m_filter, data, size);
+		buf = asyncdata->m_filter;
+	}
+
+	req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+	req->bRequest = cmd;
+	req->wValue = cpu_to_le16(value);
+	req->wIndex = cpu_to_le16(index);
+	req->wLength = cpu_to_le16(size);
+
+	usb_fill_control_urb(urb, axdev->udev, usb_sndctrlpipe(axdev->udev, 0),
+			     (void *)req, buf, size, ax_async_write_callback,
+			     asyncdata);
+
+	status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (status < 0) {
+		netdev_err(axdev->netdev,
+			   "Error submitting the control message: status=%d",
+			   status);
+		kfree(req);
+		kfree(asyncdata);
+		usb_free_urb(urb);
+	}
+
+	return status;
+}
+
+int ax_mmd_read(struct net_device *netdev, int dev_addr, int reg)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	u16 res = 0;
+
+	ax_read_cmd(axdev, AX88179A_PHY_CLAUSE45, (__u16)dev_addr,
+		    (__u16)reg, 2, &res, 1);
+
+	return res;
+}
+
+void ax_mmd_write(struct net_device *netdev, int dev_addr, int reg, int val)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	u16 res = (u16)val;
+
+	ax_write_cmd(axdev, AX88179A_PHY_CLAUSE45, (__u16)dev_addr,
+		     (__u16)reg, 2, &res);
+}
+
+int ax_mdio_read(struct net_device *netdev, int phy_id, int reg)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	u16 res;
+
+	ax_read_cmd_nopm(axdev, AX_ACCESS_PHY, phy_id, (__u16)reg, 2, &res, 1);
+
+	return res;
+}
+
+void ax_mdio_write(struct net_device *netdev, int phy_id, int reg, int val)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	u16 res = (u16)val;
+
+	ax_write_cmd_nopm(axdev, AX_ACCESS_PHY, phy_id, (__u16)reg, 2, &res);
+}
+
+static void ax_set_unplug(struct ax_device *axdev)
+{
+	if (axdev->udev->state == USB_STATE_NOTATTACHED)
+		set_bit(AX_UNPLUG, &axdev->flags);
+}
+
+static int ax_check_tx_queue_not_empty(struct ax_device *axdev)
+{
+	int i;
+
+	for (i = (AX_TX_QUEUE_SIZE - 1); i >= 0; i--)
+		if (!skb_queue_empty(&axdev->tx_queue[i]))
+			return i;
+
+	return -1;
+}
+
+static bool ax_check_tx_queue_len(struct ax_device *axdev)
+{
+	int i;
+
+	for (i = 0; i < AX_TX_QUEUE_SIZE; i++)
+		if (skb_queue_len(&axdev->tx_queue[i]) > axdev->tx_qlen)
+			return true;
+
+	return false;
+}
+
+static void ax_read_bulk_callback(struct urb *urb)
+{
+	struct net_device *netdev;
+	int status = urb->status;
+	struct rx_desc *desc;
+	struct ax_device *axdev;
+
+	desc = urb->context;
+	if (!desc)
+		return;
+
+	axdev = desc->context;
+	if (!axdev)
+		return;
+
+	if (test_bit(AX_UNPLUG, &axdev->flags) ||
+	    !test_bit(AX_ENABLE, &axdev->flags))
+		return;
+
+	netdev = axdev->netdev;
+
+	if (!netif_carrier_ok(netdev))
+		return;
+
+	usb_mark_last_busy(axdev->udev);
+
+	if (status)
+		axdev->bulkin_error++;
+	else
+		axdev->bulkin_complete++;
+
+	switch (status) {
+	case 0:
+		if (urb->actual_length < ETH_ZLEN)
+			break;
+
+		spin_lock(&axdev->rx_lock);
+		list_add_tail(&desc->list, &axdev->rx_done);
+		spin_unlock(&axdev->rx_lock);
+#ifdef ENABLE_RX_TASKLET
+		tasklet_schedule(&axdev->rx_tl);
+#else
+		napi_schedule(&axdev->napi);
+#endif
+		return;
+	case -ESHUTDOWN:
+		ax_set_unplug(axdev);
+		netif_device_detach(axdev->netdev);
+		return;
+	case -ENOENT:
+		return;
+	case -ETIME:
+		if (net_ratelimit())
+			netif_err(axdev, rx_err, netdev,
+				  "maybe reset is needed?\n");
+		break;
+	default:
+		if (net_ratelimit())
+			netif_err(axdev, rx_err, netdev,
+				  "RX status %d\n", status);
+		break;
+	}
+
+	ax_submit_rx(axdev, desc, GFP_ATOMIC);
+}
+
+void ax_write_bulk_callback(struct urb *urb)
+{
+	struct net_device_stats *stats;
+	struct net_device *netdev;
+	struct tx_desc *desc;
+	struct ax_device *axdev;
+	int status = urb->status;
+
+	desc = urb->context;
+	if (!desc)
+		return;
+
+	axdev = desc->context;
+	if (!axdev)
+		return;
+
+#ifdef ENABLE_PTP_FUNC
+	if (test_and_clear_bit(AX_TX_TIMESTAMPS, &desc->flags))
+		ax_ptp_ts_read_cmd_async(axdev);
+#endif
+	netdev = axdev->netdev;
+	stats = ax_get_stats(netdev);
+
+	if (status)
+		axdev->bulkout_error++;
+	else
+		axdev->bulkout_complete++;
+
+	if (status) {
+		if (net_ratelimit())
+			netif_warn(axdev, tx_err, netdev,
+				   "TX status %d\n", status);
+		stats->tx_errors += desc->skb_num;
+	} else {
+		stats->tx_packets += desc->skb_num;
+		stats->tx_bytes += desc->skb_len;
+	}
+
+	spin_lock(&axdev->tx_lock);
+	list_add_tail(&desc->list, &axdev->tx_free);
+	spin_unlock(&axdev->tx_lock);
+
+	usb_autopm_put_interface_async(axdev->intf);
+
+	if (!netif_carrier_ok(netdev))
+		return;
+	if (!test_bit(AX_ENABLE, &axdev->flags))
+		return;
+	if (test_bit(AX_UNPLUG, &axdev->flags))
+		return;
+
+	if (ax_check_tx_queue_not_empty(axdev) >= 0)
+#ifdef ENABLE_TX_TASKLET
+		tasklet_schedule(&axdev->tx_tl);
+#else
+		napi_schedule(&axdev->napi);
+#endif
+}
+
+static void ax_intr_callback(struct urb *urb)
+{
+	struct ax_device *axdev;
+	struct ax_device_int_data *event = NULL;
+	int status = urb->status;
+	int res;
+
+	axdev = urb->context;
+	if (!axdev)
+		return;
+
+	if (!test_bit(AX_ENABLE, &axdev->flags) ||
+	    test_bit(AX_UNPLUG, &axdev->flags))
+		return;
+
+	if (status)
+		axdev->bulkint_error++;
+	else
+		axdev->bulkint_complete++;
+
+	switch (status) {
+	case 0:
+		break;
+	case -ECONNRESET:
+	case -ESHUTDOWN:
+		netif_device_detach(axdev->netdev);
+		netif_err(axdev, intr, axdev->netdev,
+			  "Stop submitting intr, status %d\n", status);
+		return;
+	case -ENOENT:
+		netif_err(axdev, intr, axdev->netdev,
+			  "Stop submitting intr, status %d\n", status);
+		return;
+	case -EPROTO:
+		netif_err(axdev, intr, axdev->netdev,
+			  "Stop submitting intr, status %d\n", status);
+		return;
+	case -EOVERFLOW:
+		netif_err(axdev, intr, axdev->netdev,
+			  "intr status -EOVERFLOW\n");
+		goto resubmit;
+	default:
+		netif_err(axdev, intr, axdev->netdev,
+			  "intr status %d\n", status);
+		goto resubmit;
+	}
+
+	event = urb->transfer_buffer;
+	le64_to_cpus((u64 *)event);
+
+#ifndef ENABLE_INT_POLLING
+	axdev->link = event->link & AX_INT_PPLS_LINK;
+
+	if (axdev->link) {
+		if (!netif_carrier_ok(axdev->netdev)) {
+			axdev->intr_link_info = event->link_info;
+			set_bit(AX_LINK_CHG, &axdev->flags);
+			schedule_delayed_work(&axdev->schedule, 0);
+		}
+	} else {
+		if (netif_carrier_ok(axdev->netdev)) {
+			netif_stop_queue(axdev->netdev);
+			set_bit(AX_LINK_CHG, &axdev->flags);
+			schedule_delayed_work(&axdev->schedule, 0);
+		}
+	}
+#endif
+
+resubmit:
+	res = usb_submit_urb(urb, GFP_ATOMIC);
+	if (res == -ENODEV) {
+		ax_set_unplug(axdev);
+		netif_device_detach(axdev->netdev);
+	} else if (res) {
+		netif_err(axdev, intr, axdev->netdev,
+			  "can't resubmit intr, status %d\n", res);
+	}
+}
+
+#ifdef ENABLE_INT_POLLING
+static void __int_polling_work(struct work_struct *work)
+{
+	struct ax_device *axdev = container_of(work,
+				     struct ax_device, int_polling_work.work);
+	struct ax_link_info *link_info = &axdev->link_info;
+	u16 bmsr;
+	u16 speed;
+	
+	if (test_bit(AX_UNPLUG, &axdev->flags) ||
+	    !test_bit(AX_ENABLE, &axdev->flags))
+		return;
+
+	if (!mutex_trylock(&axdev->control)) {
+		schedule_delayed_work(&axdev->int_polling_work, 0);
+		return;
+	}
+
+	bmsr = ax_mdio_read(axdev->netdev, axdev->mii.phy_id, MII_BMSR);
+	axdev->link = bmsr & BMSR_LSTATUS;
+	
+	if (axdev->link) {
+		if (!netif_carrier_ok(axdev->netdev)) {
+			ax_set_carrier(axdev);
+			switch (link_info->eth_speed) {
+			case ETHER_LINK_10:
+				speed = 10;
+				break;
+			case ETHER_LINK_100:
+				speed = 100;
+				break;
+			case ETHER_LINK_1000:
+				speed = 1000;
+				break;
+			case ETHER_LINK_2500:
+				speed = 2500;
+				break;
+			}
+			netdev_info(axdev->netdev, "link up, %uMbps, %s-duplex\n",
+			    speed, link_info->full_duplex ? "full" : "half");
+		}
+	} else {
+		if (netif_carrier_ok(axdev->netdev)) {
+			netif_stop_queue(axdev->netdev);
+			ax_set_carrier(axdev);
+			netdev_info(axdev->netdev, "link down\n");
+		}
+	}
+
+	mutex_unlock(&axdev->control);
+
+	schedule_delayed_work(&axdev->int_polling_work,
+			      msecs_to_jiffies(INT_POLLING_TIMER));
+}
+#endif
+static void ax_free_buffer(struct ax_device *axdev)
+{
+	int i;
+
+	for (i = 0; i < AX88179_MAX_RX; i++) {
+		usb_free_urb(axdev->rx_list[i].urb);
+		axdev->rx_list[i].urb = NULL;
+
+		kfree(axdev->rx_list[i].buffer);
+		axdev->rx_list[i].buffer = NULL;
+		axdev->rx_list[i].head = NULL;
+	}
+
+	for (i = 0; i < AX88179_MAX_TX; i++) {
+		usb_free_urb(axdev->tx_list[i].urb);
+		axdev->tx_list[i].urb = NULL;
+
+		kfree(axdev->tx_list[i].buffer);
+		axdev->tx_list[i].buffer = NULL;
+		axdev->tx_list[i].head = NULL;
+	}
+
+	usb_free_urb(axdev->intr_urb);
+	axdev->intr_urb = NULL;
+
+	kfree(axdev->intr_buff);
+	axdev->intr_buff = NULL;
+}
+
+static int ax_alloc_buffer(struct ax_device *axdev)
+{
+	struct net_device *netdev = axdev->netdev;
+	struct usb_interface *intf = axdev->intf;
+	struct usb_host_interface *alt = intf->cur_altsetting;
+	struct usb_host_endpoint *ep_intr = alt->endpoint;
+	struct urb *urb;
+	int node, i;
+	u8 *buf;
+
+	node = netdev->dev.parent ? dev_to_node(netdev->dev.parent) : -1;
+
+	spin_lock_init(&axdev->rx_lock);
+	spin_lock_init(&axdev->tx_lock);
+	INIT_LIST_HEAD(&axdev->tx_free);
+	INIT_LIST_HEAD(&axdev->rx_done);
+	for (i = 0; i < AX_TX_QUEUE_SIZE; i++)
+		skb_queue_head_init(&axdev->tx_queue[i]);
+	skb_queue_head_init(&axdev->rx_queue);
+
+	for (i = 0; i < AX88179_MAX_RX; i++) {
+		buf = kmalloc_node(axdev->driver_info->buf_rx_size,
+				   GFP_KERNEL, node);
+		if (!buf)
+			goto err1;
+
+		if (buf != __rx_buf_align(buf)) {
+			kfree(buf);
+			buf = kmalloc_node(
+				axdev->driver_info->buf_rx_size + RX_ALIGN,
+				GFP_KERNEL,
+				node);
+			if (!buf)
+				goto err1;
+		}
+
+		urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!urb) {
+			kfree(buf);
+			goto err1;
+		}
+
+		INIT_LIST_HEAD(&axdev->rx_list[i].list);
+		axdev->rx_list[i].context = axdev;
+		axdev->rx_list[i].urb = urb;
+		axdev->rx_list[i].buffer = buf;
+		axdev->rx_list[i].head = __rx_buf_align(buf);
+	}
+
+	for (i = 0; i < AX88179_MAX_TX; i++) {
+		buf = kmalloc_node(AX88179_BUF_TX_SIZE, GFP_KERNEL, node);
+		if (!buf)
+			goto err1;
+
+		if (buf != __tx_buf_align(buf, axdev->tx_align_len)) {
+			kfree(buf);
+			buf = kmalloc_node(
+				AX88179_BUF_TX_SIZE + axdev->tx_align_len,
+				GFP_KERNEL, node);
+			if (!buf)
+				goto err1;
+		}
+
+		urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!urb) {
+			kfree(buf);
+			goto err1;
+		}
+
+		INIT_LIST_HEAD(&axdev->tx_list[i].list);
+		axdev->tx_list[i].context = axdev;
+		axdev->tx_list[i].urb = urb;
+		axdev->tx_list[i].buffer = buf;
+		axdev->tx_list[i].head = __tx_buf_align(buf,
+							axdev->tx_align_len);
+
+		list_add_tail(&axdev->tx_list[i].list, &axdev->tx_free);
+	}
+
+	axdev->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!axdev->intr_urb)
+		goto err1;
+
+	axdev->intr_buff = kzalloc(INTBUFSIZE, GFP_KERNEL);
+	if (!axdev->intr_buff)
+		goto err1;
+
+	axdev->intr_interval = (int)ep_intr->desc.bInterval;
+	usb_fill_int_urb(axdev->intr_urb, axdev->udev,
+			 usb_rcvintpipe(axdev->udev, 1), axdev->intr_buff,
+			 INTBUFSIZE, ax_intr_callback, axdev,
+			 axdev->intr_interval);
+
+	return 0;
+err1:
+	ax_free_buffer(axdev);
+	return -ENOMEM;
+}
+
+static struct tx_desc *ax_get_tx_desc(struct ax_device *dev)
+{
+	struct tx_desc *desc = NULL;
+	unsigned long flags;
+
+	if (list_empty(&dev->tx_free))
+		return NULL;
+
+	spin_lock_irqsave(&dev->tx_lock, flags);
+	if (!list_empty(&dev->tx_free)) {
+		struct list_head *cursor;
+
+		cursor = dev->tx_free.next;
+		list_del_init(cursor);
+		desc = list_entry(cursor, struct tx_desc, list);
+	}
+	spin_unlock_irqrestore(&dev->tx_lock, flags);
+
+	return desc;
+}
+
+static void ax_tx_bottom(struct ax_device *axdev)
+{
+	const struct driver_info *info = axdev->driver_info;
+	int ret;
+
+	do {
+		struct tx_desc *desc;
+		int index = -1;
+
+		index = ax_check_tx_queue_not_empty(axdev);
+		if (index < 0)
+			break;
+
+		desc = ax_get_tx_desc(axdev);
+		if (!desc)
+			break;
+#ifdef ENABLE_QUEUE_PRIORITY
+		desc->q_index = index;
+#else
+		desc->q_index = 0;
+#endif
+		ret = info->tx_fixup(axdev, desc);
+		if (ret) {
+			struct net_device *netdev = axdev->netdev;
+
+			if (ret == -ENODEV) {
+				ax_set_unplug(axdev);
+				netif_device_detach(netdev);
+			} else {
+				struct net_device_stats *stats;
+				unsigned long flags;
+
+				stats = ax_get_stats(netdev);
+				stats->tx_dropped += desc->skb_num;
+
+				spin_lock_irqsave(&axdev->tx_lock, flags);
+				list_add_tail(&desc->list, &axdev->tx_free);
+				spin_unlock_irqrestore(&axdev->tx_lock, flags);
+			}
+		}
+	} while (ret == 0);
+}
+#ifdef ENABLE_TX_TASKLET
+#if KERNEL_VERSION(5,10,0) > LINUX_VERSION_CODE
+static void ax_bottom_half(unsigned long t)
+{
+	struct ax_device *axdev = (struct ax_device *)t;
+#else
+static void ax_bottom_half(struct tasklet_struct *t)
+{
+	struct ax_device *axdev = from_tasklet(axdev, t, tx_tl);
+#endif
+
+#else
+static void ax_bottom_half(struct ax_device *axdev)
+{
+#endif
+	if (test_bit(AX_UNPLUG, &axdev->flags) ||
+	    !test_bit(AX_ENABLE, &axdev->flags) ||
+	    !netif_carrier_ok(axdev->netdev))
+		return;
+#ifdef ENABLE_TX_TASKLET
+	clear_bit(AX_SCHEDULE_TASKLET_TX, &axdev->flags);
+#else
+	clear_bit(AX_SCHEDULE_NAPI, &axdev->flags);
+#endif
+
+	ax_tx_bottom(axdev);
+}
+
+static int ax_rx_bottom(struct ax_device *axdev, int budget)
+{
+	unsigned long flags;
+	struct list_head *cursor, *next, rx_queue;
+	int ret = 0, work_done = 0;
+#ifndef ENABLE_RX_TASKLET
+	struct napi_struct *napi = &axdev->napi;
+#endif
+	struct net_device *netdev = axdev->netdev;
+	struct net_device_stats *stats = ax_get_stats(netdev);
+
+	if (!skb_queue_empty(&axdev->rx_queue)) {
+		while (work_done < budget) {
+			struct sk_buff *skb = __skb_dequeue(&axdev->rx_queue);
+			unsigned int pkt_len;
+
+			if (!skb)
+				break;
+
+			pkt_len = skb->len;
+#ifdef ENABLE_RX_TASKLET
+			netif_receive_skb(skb);
+#else
+			napi_gro_receive(napi, skb);
+#endif
+			work_done++;
+			stats->rx_packets++;
+			stats->rx_bytes += pkt_len;
+		}
+	}
+
+	if (list_empty(&axdev->rx_done))
+		return work_done;
+
+	INIT_LIST_HEAD(&rx_queue);
+	spin_lock_irqsave(&axdev->rx_lock, flags);
+	list_splice_init(&axdev->rx_done, &rx_queue);
+	spin_unlock_irqrestore(&axdev->rx_lock, flags);
+
+	list_for_each_safe(cursor, next, &rx_queue) {
+		struct rx_desc *desc;
+
+		list_del_init(cursor);
+
+		desc = list_entry(cursor, struct rx_desc, list);
+
+		if (desc->urb->actual_length < ETH_ZLEN)
+			goto submit;
+
+		if (unlikely(skb_queue_len(&axdev->rx_queue) >= 1000))
+			goto submit;
+
+		axdev->driver_info->rx_fixup(axdev, desc, &work_done, budget);
+submit:
+		if (!ret) {
+			ret = ax_submit_rx(axdev, desc, GFP_ATOMIC);
+		} else {
+			desc->urb->actual_length = 0;
+			list_add_tail(&desc->list, next);
+		}
+	}
+
+	if (!list_empty(&rx_queue)) {
+		spin_lock_irqsave(&axdev->rx_lock, flags);
+		list_splice_tail(&rx_queue, &axdev->rx_done);
+		spin_unlock_irqrestore(&axdev->rx_lock, flags);
+	}
+
+	return work_done;
+}
+
+static
+int ax_submit_rx(struct ax_device *dev, struct rx_desc *desc, gfp_t mem_flags)
+{
+	int ret;
+
+	if (test_bit(AX_UNPLUG, &dev->flags) ||
+	    !test_bit(AX_ENABLE, &dev->flags) ||
+	    !netif_carrier_ok(dev->netdev))
+		return 0;
+
+	usb_fill_bulk_urb(desc->urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2),
+			  desc->head, dev->driver_info->buf_rx_size,
+			  (usb_complete_t)ax_read_bulk_callback, desc);
+
+	ret = usb_submit_urb(desc->urb, mem_flags);
+	if (ret == -ENODEV) {
+		ax_set_unplug(dev);
+		netif_device_detach(dev->netdev);
+	} else if (ret) {
+		struct urb *urb = desc->urb;
+		unsigned long flags;
+
+		urb->actual_length = 0;
+		spin_lock_irqsave(&dev->rx_lock, flags);
+		list_add_tail(&desc->list, &dev->rx_done);
+		spin_unlock_irqrestore(&dev->rx_lock, flags);
+
+		netif_err(dev, rx_err, dev->netdev,
+			  "Couldn't submit rx[%p], ret = %d\n", desc, ret);
+#ifdef ENABLE_RX_TASKLET
+		tasklet_schedule(&dev->rx_tl);
+#else
+		napi_schedule(&dev->napi);
+#endif
+	}
+
+	return ret;
+}
+
+static inline int __ax_poll(struct ax_device *axdev, int budget)
+{
+#ifndef ENABLE_RX_TASKLET
+	struct napi_struct *napi = &axdev->napi;
+#endif
+	int work_done;
+
+	work_done = ax_rx_bottom(axdev, budget);
+#ifndef ENABLE_TX_TASKLET
+	ax_bottom_half(axdev);
+#endif
+
+	if (work_done < budget) {
+#ifndef ENABLE_RX_TASKLET
+#if KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE
+		napi_complete_done(napi, work_done);
+#else
+		if (!napi_complete_done(napi, work_done))
+			return work_done;
+#endif
+#endif
+		if (!list_empty(&axdev->rx_done))
+#ifdef ENABLE_RX_TASKLET
+			tasklet_schedule(&axdev->rx_tl);
+#else
+			napi_schedule(napi);
+#endif
+
+#ifndef ENABLE_TX_TASKLET
+		else if (ax_check_tx_queue_not_empty(axdev) >= 0 &&
+			 !list_empty(&axdev->tx_free))
+			napi_schedule(napi);
+#endif
+	}
+
+	return work_done;
+}
+
+#ifdef ENABLE_RX_TASKLET
+#if KERNEL_VERSION(5,10,0) > LINUX_VERSION_CODE
+static void ax_poll(unsigned long t)
+{
+	struct ax_device *axdev = (struct ax_device *)t;
+#else
+static void ax_poll(struct tasklet_struct *t)
+{
+	struct ax_device *axdev = from_tasklet(axdev, t, rx_tl);
+#endif
+	__ax_poll(axdev, 256);
+}
+
+#else
+
+static int ax_poll(struct napi_struct *napi, int budget)
+{
+	struct ax_device *axdev = container_of(napi, struct ax_device, napi);
+
+	return __ax_poll(axdev, budget);
+}
+#endif
+
+static void ax_drop_queued_tx(struct ax_device *axdev)
+{
+	struct net_device_stats *stats = ax_get_stats(axdev->netdev);
+	struct sk_buff_head skb_head, *tx_queue = axdev->tx_queue;
+	struct sk_buff *skb;
+	int i;
+
+	for (i = 0; i < AX_TX_QUEUE_SIZE; i++) {
+		if (skb_queue_empty(&tx_queue[i]))
+			continue;
+
+		__skb_queue_head_init(&skb_head);
+		spin_lock_bh(&tx_queue[i].lock);
+		skb_queue_splice_init(&tx_queue[i], &skb_head);
+		spin_unlock_bh(&tx_queue[i].lock);
+
+		while ((skb = __skb_dequeue(&skb_head))) {
+			dev_kfree_skb(skb);
+			stats->tx_dropped++;
+		}
+	}
+}
+
+#if KERNEL_VERSION(5, 6, 0) <= LINUX_VERSION_CODE
+static void ax_tx_timeout(struct net_device *netdev, unsigned int txqueue)
+#else
+static void ax_tx_timeout(struct net_device *netdev)
+#endif
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+
+	netif_warn(axdev, tx_err, netdev, "Tx timeout\n");
+
+	usb_queue_reset_device(axdev->intf);
+
+}
+
+#ifdef ENABLE_QUEUE_PRIORITY
+static u16 ax_select_queue(struct net_device *netdev, struct sk_buff *skb,
+			   struct net_device *sb_dev)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	struct ax_link_info *link_info = &axdev->link_info;
+
+	if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+#ifdef ENABLE_AX88279
+		if (axdev->chip_version >= AX_VERSION_AX88279)
+			return 1;
+#endif
+		if (link_info->eth_speed == ETHER_LINK_1000)
+			return 1;
+	}
+	return 0;
+}
+#endif
+
+static netdev_tx_t ax_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+#ifdef ENABLE_QUEUE_PRIORITY
+	u32 index = ax_select_queue(netdev, skb, NULL);
+#endif
+	skb_tx_timestamp(skb);
+#ifdef ENABLE_QUEUE_PRIORITY
+	skb_queue_tail(&axdev->tx_queue[index], skb);
+#else
+	skb_queue_tail(&axdev->tx_queue[0], skb);
+#endif
+	if (!list_empty(&axdev->tx_free)) {
+		if (test_bit(AX_SELECTIVE_SUSPEND, &axdev->flags)) {
+#ifdef ENABLE_TX_TASKLET
+			set_bit(AX_SCHEDULE_TASKLET_TX, &axdev->flags);
+#else
+			set_bit(AX_SCHEDULE_NAPI, &axdev->flags);
+#endif
+			schedule_delayed_work(&axdev->schedule, 0);
+		} else {
+			usb_mark_last_busy(axdev->udev);
+#ifdef ENABLE_TX_TASKLET
+			tasklet_schedule(&axdev->tx_tl);
+#else
+			napi_schedule(&axdev->napi);
+#endif
+		}
+	} else if (ax_check_tx_queue_len(axdev)) {
+		netif_stop_queue(netdev);
+	}
+
+	return NETDEV_TX_OK;
+}
+
+void ax_set_tx_qlen(struct ax_device *dev)
+{
+	struct net_device *netdev = dev->netdev;
+
+	dev->tx_qlen = AX88179_BUF_TX_SIZE / (netdev->mtu + ETH_FCS_LEN + 8);
+}
+
+static int ax_start_rx(struct ax_device *axdev)
+{
+	int i, ret = 0;
+
+	INIT_LIST_HEAD(&axdev->rx_done);
+	for (i = 0; i < AX88179_MAX_RX; i++) {
+		INIT_LIST_HEAD(&axdev->rx_list[i].list);
+		ret = ax_submit_rx(axdev, &axdev->rx_list[i], GFP_KERNEL);
+		if (ret)
+			break;
+	}
+
+	if (ret && ++i < AX88179_MAX_RX) {
+		struct list_head rx_queue;
+		unsigned long flags;
+
+		INIT_LIST_HEAD(&rx_queue);
+
+		do {
+			struct rx_desc *desc = &axdev->rx_list[i++];
+			struct urb *urb = desc->urb;
+
+			urb->actual_length = 0;
+			list_add_tail(&desc->list, &rx_queue);
+		} while (i < AX88179_MAX_RX);
+
+		spin_lock_irqsave(&axdev->rx_lock, flags);
+		list_splice_tail(&rx_queue, &axdev->rx_done);
+		spin_unlock_irqrestore(&axdev->rx_lock, flags);
+	}
+
+	return ret;
+}
+
+static int ax_stop_rx(struct ax_device *axdev)
+{
+	int i;
+
+	for (i = 0; i < AX88179_MAX_RX; i++)
+		usb_kill_urb(axdev->rx_list[i].urb);
+
+	while (!skb_queue_empty(&axdev->rx_queue))
+		dev_kfree_skb(__skb_dequeue(&axdev->rx_queue));
+
+	return 0;
+}
+
+static void ax_disable(struct ax_device *axdev)
+{
+	int i;
+
+	if (test_bit(AX_UNPLUG, &axdev->flags)) {
+		ax_drop_queued_tx(axdev);
+		return;
+	}
+
+	for (i = 0; i < AX88179_MAX_TX; i++)
+		usb_kill_urb(axdev->tx_list[i].urb);
+
+	ax_stop_rx(axdev);
+}
+
+#if KERNEL_VERSION(2, 6, 39) <= LINUX_VERSION_CODE
+static int
+#if KERNEL_VERSION(3, 3, 0) <= LINUX_VERSION_CODE
+ax88179_set_features(struct net_device *net, netdev_features_t features)
+#else
+ax88179_set_features(struct net_device *net, u32 features)
+#endif
+{
+	struct ax_device *dev = netdev_priv(net);
+	u8 reg8;
+
+#if KERNEL_VERSION(3, 3, 0) <= LINUX_VERSION_CODE
+	netdev_features_t changed = net->features ^ features;
+#else
+	u32 changed = net->features ^ features;
+#endif
+
+	if (changed & NETIF_F_IP_CSUM) {
+		ax_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &reg8, 0);
+		reg8 ^= AX_TXCOE_TCP | AX_TXCOE_UDP;
+		ax_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &reg8);
+	}
+
+	if (changed & NETIF_F_IPV6_CSUM) {
+		ax_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &reg8, 0);
+		reg8 ^= AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6;
+		ax_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &reg8);
+	}
+
+	if (changed & NETIF_F_RXCSUM) {
+		ax_read_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &reg8, 0);
+		reg8 ^= AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP |
+			AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6;
+		ax_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &reg8);
+	}
+
+	return 0;
+}
+#endif
+
+static void ax_set_carrier(struct ax_device *axdev)
+{
+	struct net_device *netdev = axdev->netdev;
+#ifndef ENABLE_RX_TASKLET
+	struct napi_struct *napi = &axdev->napi;
+#endif
+
+	if (axdev->link) {
+#ifdef ENABLE_PTP_FUNC
+		axdev->driver_info->ptp_pps_ctrl(axdev, 1);
+#endif
+		if (!netif_carrier_ok(netdev)) {
+			if (axdev->driver_info->link_reset(axdev))
+				return;
+			netif_stop_queue(netdev);
+#ifdef ENABLE_RX_TASKLET
+			tasklet_disable(&axdev->rx_tl);
+#else
+			napi_disable(napi);
+#endif	
+			netif_carrier_on(netdev);
+			ax_start_rx(axdev);
+#ifdef ENABLE_RX_TASKLET
+			tasklet_enable(&axdev->rx_tl);
+#else
+			napi_enable(napi);
+#endif
+			netif_wake_queue(netdev);
+		} else if (netif_queue_stopped(netdev) &&
+			   ax_check_tx_queue_len(axdev)) {
+			netif_wake_queue(netdev);
+		}
+	} else {
+#ifdef ENABLE_PTP_FUNC
+		axdev->driver_info->ptp_pps_ctrl(axdev, 0);
+#endif
+		if (netif_carrier_ok(netdev)) {
+			netif_carrier_off(netdev);
+#ifdef ENABLE_TX_TASKLET
+			tasklet_disable(&axdev->tx_tl);
+#endif
+#ifdef ENABLE_RX_TASKLET
+			tasklet_disable(&axdev->rx_tl);
+#else
+			napi_disable(napi);
+#endif			
+			ax_disable(axdev);
+#ifdef ENABLE_RX_TASKLET
+			tasklet_enable(&axdev->rx_tl);
+#else
+			napi_enable(napi);
+#endif	
+#ifdef ENABLE_TX_TASKLET
+			tasklet_enable(&axdev->tx_tl);
+#endif
+		}
+	}
+#ifdef ENABLE_AX88279
+	if (axdev->intr_link_info.eth_speed == ETHER_LINK_2500) {
+		netdev_info(axdev->netdev,
+			    "link up, 2500Mbps, full-duplex\n");
+	}
+#endif
+}
+
+static inline void __ax_work_func(struct ax_device *axdev)
+{
+	if (test_bit(AX_UNPLUG, &axdev->flags) || !netif_running(axdev->netdev))
+		return;
+
+	if (usb_autopm_get_interface(axdev->intf) < 0)
+		return;
+
+	if (!test_bit(AX_ENABLE, &axdev->flags))
+		goto out;
+
+	if (!mutex_trylock(&axdev->control)) {
+		schedule_delayed_work(&axdev->schedule, 0);
+		goto out;
+	}
+
+	if (test_and_clear_bit(AX_LINK_CHG, &axdev->flags))
+		ax_set_carrier(axdev);
+
+#ifdef ENABLE_RX_TASKLET
+	if (test_and_clear_bit(AX_SCHEDULE_TASKLET_RX, &axdev->flags) &&
+	    netif_carrier_ok(axdev->netdev))
+		tasklet_schedule(&axdev->rx_tl);
+#else
+	if (test_and_clear_bit(AX_SCHEDULE_NAPI, &axdev->flags) &&
+	    netif_carrier_ok(axdev->netdev))
+		napi_schedule(&axdev->napi);
+#endif
+#ifdef ENABLE_TX_TASKLET
+	if (test_and_clear_bit(AX_SCHEDULE_TASKLET_TX, &axdev->flags) &&
+	    netif_carrier_ok(axdev->netdev))
+		tasklet_schedule(&axdev->tx_tl);
+#endif
+
+	mutex_unlock(&axdev->control);
+
+out:
+	usb_autopm_put_interface(axdev->intf);
+}
+
+static void ax_work_func_t(struct work_struct *work)
+{
+	struct ax_device *axdev = container_of(work,
+					       struct ax_device, schedule.work);
+
+	__ax_work_func(axdev);
+}
+
+int ax_usb_command(struct ax_device *axdev, struct _ax_ioctl_command *info)
+{
+	struct _ax_usb_command *usb_cmd = &info->usb_cmd;
+	void *buf;
+	int err, timeout;
+	u16 size = usb_cmd->size;
+	u8 reqtype;
+
+	buf = kmemdup(&usb_cmd->cmd_data, size, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	if (usb_cmd->ops == USB_READ_OPS) {
+		reqtype = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+		timeout = USB_CTRL_GET_TIMEOUT;
+	} else {
+		reqtype = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+		timeout = USB_CTRL_SET_TIMEOUT;
+	}
+
+	err = usb_control_msg(axdev->udev, usb_rcvctrlpipe(axdev->udev, 0),
+			      usb_cmd->cmd, reqtype, usb_cmd->value,
+			      usb_cmd->index, buf, size, timeout);
+	if (err > 0 && err <= size)
+		memcpy(&usb_cmd->cmd_data, buf, size);
+
+	kfree(buf);
+
+	return 0;
+}
+
+static int ax_open(struct net_device *netdev)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	int res = 0;
+
+	res = ax_alloc_buffer(axdev);
+	if (res)
+		return res;
+
+	res = usb_autopm_get_interface(axdev->intf);
+	if (res < 0)
+		goto out_free;
+
+	mutex_lock(&axdev->control);
+
+	set_bit(AX_ENABLE, &axdev->flags);
+
+	res = axdev->driver_info->hw_init(axdev);
+	if (res < 0)
+		goto out_unlock;
+
+	res = usb_submit_urb(axdev->intr_urb, GFP_KERNEL);
+	if (res) {
+		if (res == -ENODEV)
+			netif_device_detach(netdev);
+		netif_warn(axdev, ifup, netdev,
+			   "intr_urb submit failed: %d\n", res);
+		goto out_unlock;
+	}
+#ifdef ENABLE_INT_POLLING
+	schedule_delayed_work(&axdev->int_polling_work,
+			      msecs_to_jiffies(INT_POLLING_TIMER));
+#endif
+#ifdef ENABLE_RX_TASKLET
+	tasklet_enable(&axdev->rx_tl);
+#else
+	napi_enable(&axdev->napi);
+#endif
+#ifdef ENABLE_TX_TASKLET
+	tasklet_enable(&axdev->tx_tl);
+#endif
+
+	netif_carrier_off(netdev);
+	netif_start_queue(netdev);
+	mutex_unlock(&axdev->control);
+	usb_autopm_put_interface(axdev->intf);
+
+	return 0;
+
+out_unlock:
+	mutex_unlock(&axdev->control);
+	usb_autopm_put_interface(axdev->intf);
+out_free:
+	ax_free_buffer(axdev);
+	return res;
+}
+
+static int ax_close(struct net_device *netdev)
+{
+	struct ax_device *axdev = netdev_priv(netdev);
+	int ret = 0;
+
+	if (axdev->driver_info->stop)
+		axdev->driver_info->stop(axdev);
+
+#ifdef ENABLE_TX_TASKLET
+	tasklet_disable(&axdev->tx_tl);
+#endif
+	clear_bit(AX_ENABLE, &axdev->flags);
+	usb_kill_urb(axdev->intr_urb);
+#ifdef ENABLE_INT_POLLING
+	cancel_delayed_work_sync(&axdev->int_polling_work);
+#endif
+	cancel_delayed_work_sync(&axdev->schedule);
+#ifdef ENABLE_RX_TASKLET
+	tasklet_disable(&axdev->rx_tl);
+#else
+	napi_disable(&axdev->napi);
+#endif
+	netif_stop_queue(axdev->netdev);
+
+	ret = usb_autopm_get_interface(axdev->intf);
+	if (ret < 0 || test_bit(AX_UNPLUG, &axdev->flags)) {
+		ax_drop_queued_tx(axdev);
+		ax_stop_rx(axdev);
+	} else {
+		ax_disable(axdev);
+	}
+
+	if (!ret)
+		usb_autopm_put_interface(axdev->intf);
+
+	ax_free_buffer(axdev);
+
+	return ret;
+}
+
+static int ax88179_change_mtu(struct net_device *net, int new_mtu)
+{
+	struct ax_device *axdev = netdev_priv(net);
+	u16 reg16;
+
+	if (new_mtu <= 0 ||
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
+		new_mtu > net->max_mtu)
+#else
+		new_mtu > axdev->max_mtu)
+#endif
+		return -EINVAL;
+
+	net->mtu = new_mtu;
+
+	if (net->mtu > 1500) {
+		ax_read_cmd(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+			    2, 2, &reg16, 1);
+		reg16 |= AX_MEDIUM_JUMBO_EN;
+		ax_write_cmd(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+			     2, 2, &reg16);
+	} else {
+		ax_read_cmd(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+			    2, 2, &reg16, 1);
+		reg16 &= ~AX_MEDIUM_JUMBO_EN;
+		ax_write_cmd(axdev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+			     2, 2, &reg16);
+	}
+
+	return 0;
+}
+
+int ax_get_mac_pass(struct ax_device *axdev, u8 *mac)
+{
+#ifdef ENABLE_MAC_PASS
+	efi_char16_t name[] = L"MacAddressPassTemp";
+	efi_guid_t guid = EFI_GUID(0xe2a741d8, 0xedf5, 0x47a1,
+				   0x8f, 0x94, 0xb0, 0xee,
+				   0x36, 0x8a, 0x3d, 0xe0);
+	u32 attr;
+	unsigned long data_size = sizeof(struct mac_pass);
+	struct mac_pass macpass;
+	efi_status_t status;
+#if KERNEL_VERSION(5, 7, 0) <= LINUX_VERSION_CODE
+	if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
+		return -EOPNOTSUPP;
+#else
+	if (!efi_enabled(EFI_RUNTIME_SERVICES))
+		return -EOPNOTSUPP;
+#endif
+	status = efi.get_variable(name, &guid, &attr, &data_size, &macpass);
+	if (status != EFI_SUCCESS) {
+		netdev_err(axdev->netdev, "Getting variable failed.(%ld)",
+			   status);
+		return status;
+	}
+
+	if (macpass.control == MAC_PASS_ENABLE_0)
+		memcpy(mac, macpass.mac0, 6);
+	else if (macpass.control == MAC_PASS_ENABLE_1)
+		memcpy(mac, macpass.mac1, 6);
+	else
+		return -1;
+#endif
+	return 0;
+}
+
+int ax_check_ether_addr(struct ax_device *axdev, struct sockaddr *p)
+{
+	u8 *addr = p->sa_data;
+
+	u8 default_mac[6] = {0, 0x0e, 0xc6, 0x81, 0x79, 0x01};
+	u8 default_mac_178a[6] = {0, 0x0e, 0xc6, 0x81, 0x78, 0x01};
+
+	if (((addr[0] == 0) && (addr[1] == 0) && (addr[2] == 0)) ||
+	    !is_valid_ether_addr(addr) ||
+	    !memcmp(axdev->netdev->dev_addr, default_mac, ETH_ALEN) ||
+	    !memcmp(axdev->netdev->dev_addr, default_mac_178a, ETH_ALEN)) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
+		eth_random_addr(addr);
+#else
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0)
+		eth_hw_addr_random(axdev->netdev);
+#else
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
+		axdev->netdev->addr_assign_type |= NET_ADDR_RANDOM;
+#endif
+		random_ether_addr(addr);
+#endif		
+#endif
+
+		addr[0] = 0;
+		addr[1] = 0x0E;
+		addr[2] = 0xC6;
+
+		return -EADDRNOTAVAIL;
+	}
+
+	return 0;
+}
+
+static int ax_get_chip_version(struct ax_device *axdev)
+{
+	int ret = 0;
+
+	axdev->chip_version = AX_VERSION_INVALID;
+	ret = ax_read_cmd(axdev, AX_ACCESS_MAC, AX_CHIP_STATUS,
+			  1, 1, &axdev->chip_version, 0);
+	if (ret < 0)
+		return ret;
+	axdev->chip_version = CHIP_CODE(axdev->chip_version);
+
+	return 0;
+}
+
+static void ax_get_chip_subversion(struct ax_device *axdev)
+{
+	if (axdev->chip_version < AX_VERSION_AX88179A_772D) {
+		axdev->sub_version = 0;
+		return;
+	}
+
+	if (ax_read_cmd(axdev, AX88179A_ACCESS_BL, AX88179A_HW_EC_VERSION,
+			1, 1, &axdev->sub_version, 0) < 0)
+		axdev->sub_version = 0;
+}
+
+static int ax_get_chip_feature(struct ax_device *axdev)
+{
+	if (ax_get_chip_version(axdev))
+		return -ENODEV;
+
+	if (axdev->chip_version < AX_VERSION_AX88179)
+		return -ENODEV;
+
+	ax_get_chip_subversion(axdev);
+
+	return 0;
+}
+
+static int ax_get_mac_address(struct ax_device *axdev)
+{
+	struct net_device *netdev = axdev->netdev;
+	struct sockaddr addr;
+
+	if (ax_read_cmd(axdev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
+			ETH_ALEN, addr.sa_data, 0) < 0) {
+		dev_err(&axdev->intf->dev, "Failed to read MAC address");
+		return -ENODEV;
+	}
+
+	if (ax_check_ether_addr(axdev, &addr))
+		dev_warn(&axdev->intf->dev, "Found invalid MAC address value");
+
+	ax_get_mac_pass(axdev, addr.sa_data);
+	
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
+	eth_hw_addr_set(netdev, addr.sa_data);	
+#else
+	memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN);
+#endif
+
+	memcpy(netdev->perm_addr, addr.sa_data, ETH_ALEN);
+
+	if (ax_write_cmd(axdev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
+			ETH_ALEN, addr.sa_data) < 0) {
+		dev_err(&axdev->intf->dev, "Failed to write MAC address");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+
+static bool ax_can_wakeup(struct ax_device *axdev)
+{
+	struct usb_device *udev = axdev->udev;
+
+	return (udev->actconfig->desc.bmAttributes & USB_CONFIG_ATT_WAKEUP);
+}
+
+static int ax_probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	//struct usb_driver *driver = to_usb_driver(intf->dev.driver);
+	const struct driver_info *info;
+	struct net_device *netdev;
+	struct ax_device *axdev;
+	int ret;
+
+	if (udev->actconfig->desc.bConfigurationValue != 1) {
+		usb_driver_set_configuration(udev, 1);
+		return -ENODEV;
+	}
+
+	info = (const struct driver_info *)id->driver_info;
+	if (!info || !info->bind || !info->unbind) {
+		dev_err(&intf->dev, "Driver method not registered\n");
+		return -ENODEV;
+	}
+
+	netdev = alloc_etherdev(sizeof(struct ax_device));
+	if (!netdev) {
+		dev_err(&intf->dev, "Out of memory\n");
+		return -ENOMEM;
+	}
+
+	axdev = netdev_priv(netdev);
+	axdev->driver_info = info;
+
+	netdev->watchdog_timeo = AX_TX_TIMEOUT;
+
+	axdev->udev = udev;
+	axdev->netdev = netdev;
+	axdev->intf = intf;
+	intf->needs_remote_wakeup = true;
+#ifdef ENABLE_AUTODETACH_FUNC
+	axdev->autodetach = (autodetach == -1) ? false : true;
+#else
+	axdev->autodetach = false;
+#endif
+	mutex_init(&axdev->control);
+	INIT_DELAYED_WORK(&axdev->schedule, ax_work_func_t);
+#ifdef ENABLE_TX_TASKLET
+#if KERNEL_VERSION(5,10,0) > LINUX_VERSION_CODE
+	tasklet_init(&axdev->tx_tl, ax_bottom_half, (unsigned long) axdev);
+#else
+	tasklet_setup(&axdev->tx_tl, ax_bottom_half);
+#endif
+	tasklet_disable(&axdev->tx_tl);
+#endif
+
+	ret = ax_get_chip_feature(axdev);
+	if (ret) {
+		dev_err(&intf->dev, "Failed to get Device feature\n");
+		goto out;
+	}
+
+	ret = info->bind(axdev);
+	if (ret) {
+		dev_err(&intf->dev, "Device initialization failed\n");
+		goto out;
+	}
+
+	usb_set_intfdata(intf, axdev);
+#ifdef ENABLE_RX_TASKLET
+#if KERNEL_VERSION(5,10,0) > LINUX_VERSION_CODE
+	tasklet_init(&axdev->rx_tl, ax_poll, (unsigned long) axdev);
+#else
+	tasklet_setup(&axdev->rx_tl, ax_poll);
+#endif
+	tasklet_disable(&axdev->rx_tl);
+#else
+#if KERNEL_VERSION(5, 19, 0) <= LINUX_VERSION_CODE
+	netif_napi_add_weight(netdev, &axdev->napi, ax_poll, AX88179_NAPI_WEIGHT);
+#else
+	netif_napi_add(netdev, &axdev->napi, ax_poll, AX88179_NAPI_WEIGHT);
+#endif
+#endif
+	ret = ax_get_mac_address(axdev);
+	if (ret < 0)
+		goto out;
+
+	SET_NETDEV_DEV(netdev, &intf->dev);
+	ret = register_netdev(netdev);
+	if (ret != 0) {
+		netif_err(axdev, probe, netdev,
+			  "couldn't register the device\n");
+		goto out1;
+	}
+
+	device_set_wakeup_enable(&udev->dev, ax_can_wakeup(axdev));
+#ifdef ENABLE_INT_POLLING
+	INIT_DELAYED_WORK(&axdev->int_polling_work, __int_polling_work);
+#endif
+
+	return 0;
+out1:
+#ifdef ENABLE_RX_TASKLET
+	tasklet_kill(&axdev->rx_tl);
+#else
+	netif_napi_del(&axdev->napi);
+#endif
+#ifdef ENABLE_TX_TASKLET
+	tasklet_kill(&axdev->tx_tl);
+#endif
+	usb_set_intfdata(intf, NULL);
+out:
+	free_netdev(netdev);
+	return ret;
+}
+
+static void ax_disconnect(struct usb_interface *intf)
+{
+	struct ax_device *axdev = usb_get_intfdata(intf);
+
+	usb_set_intfdata(intf, NULL);
+	if (axdev) {
+		axdev->driver_info->unbind(axdev);
+		ax_set_unplug(axdev);
+#ifdef ENABLE_RX_TASKLET
+		tasklet_kill(&axdev->rx_tl);
+#else
+		netif_napi_del(&axdev->napi);
+#endif
+#ifdef ENABLE_TX_TASKLET
+		tasklet_kill(&axdev->tx_tl);
+#endif
+		unregister_netdev(axdev->netdev);
+		free_netdev(axdev->netdev);
+	}
+}
+
+static int ax_pre_reset(struct usb_interface *intf)
+{
+	struct ax_device *axdev = usb_get_intfdata(intf);
+	struct net_device *netdev;
+
+	if (!axdev)
+		return 0;
+
+	netdev = axdev->netdev;
+	if (!netif_running(netdev))
+		return 0;
+
+	netif_stop_queue(netdev);
+#ifdef ENABLE_TX_TASKLET
+	tasklet_disable(&axdev->tx_tl);
+#endif
+	clear_bit(AX_ENABLE, &axdev->flags);
+	usb_kill_urb(axdev->intr_urb);
+#ifdef ENABLE_INT_POLLING
+	cancel_delayed_work_sync(&axdev->int_polling_work);
+#endif
+	cancel_delayed_work_sync(&axdev->schedule);
+#ifdef ENABLE_RX_TASKLET
+	tasklet_disable(&axdev->rx_tl);
+#else
+	napi_disable(&axdev->napi);
+#endif
+	return 0;
+}
+
+static int ax_post_reset(struct usb_interface *intf)
+{
+	struct ax_device *axdev = usb_get_intfdata(intf);
+	struct net_device *netdev;
+
+	if (!axdev)
+		return 0;
+
+	netdev = axdev->netdev;
+	if (!netif_running(netdev))
+		return 0;
+
+	set_bit(AX_ENABLE, &axdev->flags);
+	if (netif_carrier_ok(netdev)) {
+		mutex_lock(&axdev->control);
+		ax_start_rx(axdev);
+		mutex_unlock(&axdev->control);
+	}
+
+#ifdef ENABLE_RX_TASKLET
+	tasklet_enable(&axdev->rx_tl);
+#else
+	napi_enable(&axdev->napi);
+#endif
+#ifdef ENABLE_TX_TASKLET
+	tasklet_enable(&axdev->tx_tl);
+#endif
+	netif_wake_queue(netdev);
+	usb_submit_urb(axdev->intr_urb, GFP_KERNEL);
+#ifdef ENABLE_INT_POLLING
+	schedule_delayed_work(&axdev->int_polling_work,
+			      msecs_to_jiffies(INT_POLLING_TIMER));
+#endif
+
+	if (!list_empty(&axdev->rx_done))
+#ifdef ENABLE_RX_TASKLET
+		tasklet_schedule(&axdev->rx_tl);
+#else
+		napi_schedule(&axdev->napi);
+#endif
+
+	return 0;
+}
+
+static int ax_system_resume(struct ax_device *axdev)
+{
+	struct net_device *netdev = axdev->netdev;
+
+	netif_device_attach(netdev);
+
+	if (netif_running(netdev) && (netdev->flags & IFF_UP)) {
+		netif_carrier_off(netdev);
+
+		axdev->driver_info->system_resume(axdev);
+		set_bit(AX_ENABLE, &axdev->flags);
+		usb_submit_urb(axdev->intr_urb, GFP_NOIO);
+#ifdef ENABLE_INT_POLLING
+		schedule_delayed_work(&axdev->int_polling_work,
+				      msecs_to_jiffies(INT_POLLING_TIMER));
+#endif
+	}
+
+	return 0;
+}
+
+static int ax_runtime_resume(struct ax_device *axdev)
+{
+	struct net_device *netdev = axdev->netdev;
+
+	if (netif_running(netdev) && (netdev->flags & IFF_UP)) {
+#ifdef ENABLE_RX_TASKLET
+		tasklet_disable(&axdev->rx_tl);
+#else
+		struct napi_struct *napi = &axdev->napi;
+
+		napi_disable(napi);
+#endif
+		set_bit(AX_ENABLE, &axdev->flags);
+
+		if (netif_carrier_ok(netdev)) {
+			if (axdev->link) {
+				ax_start_rx(axdev);
+			} else {
+				netif_carrier_off(netdev);
+				if (axdev->driver_info->stop)
+					axdev->driver_info->stop(axdev);
+			}
+		}
+
+		axdev->driver_info->runtime_resume(axdev);
+
+#ifdef ENABLE_RX_TASKLET
+		tasklet_enable(&axdev->rx_tl);
+#else
+		napi_enable(napi);
+#endif	
+		clear_bit(AX_SELECTIVE_SUSPEND, &axdev->flags);
+		if (!list_empty(&axdev->rx_done)) {
+			local_bh_disable();
+#ifdef ENABLE_RX_TASKLET
+			tasklet_schedule(&axdev->rx_tl);
+#else
+			napi_schedule(&axdev->napi);
+#endif	
+			local_bh_enable();
+		}
+		usb_submit_urb(axdev->intr_urb, GFP_NOIO);
+	} else {
+		clear_bit(AX_SELECTIVE_SUSPEND, &axdev->flags);
+	}
+
+	return 0;
+}
+
+static int ax_system_suspend(struct ax_device *axdev)
+{
+	struct net_device *netdev = axdev->netdev;
+	int ret = 0;
+
+	netif_device_detach(netdev);
+
+	
+
+	if (netif_running(netdev) && test_bit(AX_ENABLE, &axdev->flags)) {
+#ifndef ENABLE_RX_TASKLET
+		struct napi_struct *napi = &axdev->napi;
+#endif
+
+		clear_bit(AX_ENABLE, &axdev->flags);
+		usb_kill_urb(axdev->intr_urb);
+#ifdef ENABLE_TX_TASKLET
+		tasklet_disable(&axdev->tx_tl);
+#endif
+#ifdef ENABLE_INT_POLLING
+		cancel_delayed_work_sync(&axdev->int_polling_work);
+#endif
+
+		ax_disable(axdev);
+
+		axdev->driver_info->system_suspend(axdev);
+#ifdef ENABLE_RX_TASKLET
+		tasklet_disable(&axdev->rx_tl);
+#else
+		napi_disable(napi);
+#endif
+		cancel_delayed_work_sync(&axdev->schedule);
+#ifdef ENABLE_RX_TASKLET
+		tasklet_enable(&axdev->rx_tl);
+#else
+		napi_enable(napi);
+#endif
+		
+#ifdef ENABLE_TX_TASKLET
+		tasklet_enable(&axdev->tx_tl);
+#endif
+	}
+
+	return ret;
+}
+
+static int ax_runtime_suspend(struct ax_device *axdev)
+{
+	struct net_device *netdev = axdev->netdev;
+
+	set_bit(AX_SELECTIVE_SUSPEND, &axdev->flags);
+
+	if (netif_running(netdev) && test_bit(AX_ENABLE, &axdev->flags)) {
+		clear_bit(AX_ENABLE, &axdev->flags);
+		usb_kill_urb(axdev->intr_urb);
+#ifdef ENABLE_INT_POLLING
+		cancel_delayed_work_sync(&axdev->int_polling_work);
+#endif
+
+		if (netif_carrier_ok(netdev)) {
+#ifdef ENABLE_RX_TASKLET
+			tasklet_disable(&axdev->rx_tl);
+#else
+			struct napi_struct *napi = &axdev->napi;
+
+			napi_disable(napi);
+#endif
+			
+			ax_stop_rx(axdev);
+#ifdef ENABLE_RX_TASKLET
+			tasklet_enable(&axdev->rx_tl);
+#else
+			napi_enable(napi);
+#endif
+		}
+
+		axdev->driver_info->runtime_suspend(axdev);
+	}
+
+	return 0;
+}
+
+static int ax_suspend(struct usb_interface *intf, pm_message_t message)
+{
+	struct ax_device *axdev = usb_get_intfdata(intf);
+	int ret;
+
+	mutex_lock(&axdev->control);
+
+	if (PMSG_IS_AUTO(message))
+		ret = ax_runtime_suspend(axdev);
+	else
+		ret = ax_system_suspend(axdev);
+
+	mutex_unlock(&axdev->control);
+
+	return ret;
+}
+
+static int ax_resume(struct usb_interface *intf)
+{
+	struct ax_device *axdev = usb_get_intfdata(intf);
+	int ret;
+
+	mutex_lock(&axdev->control);
+
+	if (test_bit(AX_SELECTIVE_SUSPEND, &axdev->flags))
+		ret = ax_runtime_resume(axdev);
+	else
+		ret = ax_system_resume(axdev);
+
+	mutex_unlock(&axdev->control);
+
+	return ret;
+}
+
+static int ax_reset_resume(struct usb_interface *intf)
+{
+	struct ax_device *axdev = usb_get_intfdata(intf);
+
+	clear_bit(AX_SELECTIVE_SUSPEND, &axdev->flags);
+
+	return ax_resume(intf);
+}
+
+const struct net_device_ops ax88179_netdev_ops = {
+	.ndo_open		= ax_open,
+	.ndo_stop		= ax_close,
+#if KERNEL_VERSION(5, 15, 0) <= LINUX_VERSION_CODE
+	.ndo_siocdevprivate	= ax88179_siocdevprivate,
+	.ndo_eth_ioctl		= ax88179_ioctl,
+#endif
+	.ndo_do_ioctl		= ax88179_ioctl,
+	.ndo_start_xmit		= ax_start_xmit,
+	.ndo_tx_timeout		= ax_tx_timeout,
+	.ndo_set_features	= ax88179_set_features,
+	.ndo_set_rx_mode	= ax88179_set_multicast,
+	.ndo_set_mac_address	= ax88179_set_mac_addr,
+	.ndo_change_mtu		= ax88179_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
+const struct net_device_ops ax88179a_netdev_ops = {
+	.ndo_open		= ax_open,
+	.ndo_stop		= ax_close,
+#if KERNEL_VERSION(5, 15, 0) <= LINUX_VERSION_CODE
+	.ndo_siocdevprivate	= ax88179a_siocdevprivate,
+	.ndo_eth_ioctl		= ax88179a_ioctl,
+#endif
+	.ndo_do_ioctl		= ax88179a_ioctl,
+	.ndo_start_xmit		= ax_start_xmit,
+	.ndo_tx_timeout		= ax_tx_timeout,
+	.ndo_set_features	= ax88179_set_features,
+	.ndo_set_rx_mode	= ax88179a_set_multicast,
+	.ndo_set_mac_address	= ax88179_set_mac_addr,
+	.ndo_change_mtu		= ax88179_change_mtu,
+	.ndo_validate_addr	= eth_validate_addr,
+};
+
+#define ASIX_USB_DEVICE(vend, prod, lo, hi, info) { \
+	USB_DEVICE_VER(vend, prod, lo, hi), \
+	.driver_info = (unsigned long)&info \
+}
+
+static const struct usb_device_id ax_usb_table[] = {
+	ASIX_USB_DEVICE(USB_VENDOR_ID_ASIX, AX_DEVICE_ID_179X, 0,
+			AX_BCDDEVICE_ID_179, ax88179_info),
+	ASIX_USB_DEVICE(USB_VENDOR_ID_ASIX, AX_DEVICE_ID_178A, 0,
+			AX_BCDDEVICE_ID_178A, ax88179_info),
+	ASIX_USB_DEVICE(USB_VENDOR_ID_SITECOM, 0x0072, 0,
+			AX_BCDDEVICE_ID_179, ax88179_info),
+	ASIX_USB_DEVICE(USB_VENDOR_ID_LENOVO, 0x304b, 0,
+			AX_BCDDEVICE_ID_179, ax88179_info),
+	ASIX_USB_DEVICE(USB_VENDOR_ID_TOSHIBA, 0x0a13, 0,
+			AX_BCDDEVICE_ID_179, ax88179_info),
+	ASIX_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, 0xa100, 0,
+			AX_BCDDEVICE_ID_179, ax88179_info),
+	ASIX_USB_DEVICE(USB_VENDOR_ID_DLINK, 0x4a00, 0,
+			AX_BCDDEVICE_ID_179, ax88179_info),
+	ASIX_USB_DEVICE(USB_VENDOR_ID_MAGIC_CONTROL, 0x0179, 0,
+			AX_BCDDEVICE_ID_179, ax88179_info),
+	ASIX_USB_DEVICE(USB_VENDOR_ID_ASIX, AX_DEVICE_ID_179X, 0,
+			AX_BCDDEVICE_ID_772D, ax88179a_info),
+	ASIX_USB_DEVICE(USB_VENDOR_ID_ASIX, AX_DEVICE_ID_179X, 0,
+			AX_BCDDEVICE_ID_179A, ax88179a_info),
+#ifdef ENABLE_AX88279
+	ASIX_USB_DEVICE(USB_VENDOR_ID_ASIX, AX_DEVICE_ID_179X, 0,
+			AX_BCDDEVICE_ID_279, ax88279_info),
+#endif
+	{/*END*/}
+};
+
+MODULE_DEVICE_TABLE(usb, ax_usb_table);
+
+static struct usb_driver ax_usb_driver = {
+	.name		= MODULENAME,
+	.id_table	= ax_usb_table,
+	.probe		= ax_probe,
+	.disconnect	= ax_disconnect,
+	.suspend	= ax_suspend,
+	.resume		= ax_resume,
+	.reset_resume	= ax_reset_resume,
+	.pre_reset	= ax_pre_reset,
+	.post_reset	= ax_post_reset,
+	.supports_autosuspend = 1,
+#if KERNEL_VERSION(3, 5, 0) <= LINUX_VERSION_CODE
+	.disable_hub_initiated_lpm = 1,
+#endif
+};
+
+module_usb_driver(ax_usb_driver);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/ax_main.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/ax_main.h
@@ -0,0 +1,706 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*******************************************************************************
+ *     Copyright (c) 2022    ASIX Electronic Corporation    All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+#ifndef __ASIX_MAIN_H
+#define __ASIX_MAIN_H
+
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <uapi/linux/mdio.h>
+#include <linux/mdio.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/usb.h>
+#include <linux/if_vlan.h>
+#include <linux/usb/cdc.h>
+#include <linux/suspend.h>
+#include <linux/pm_runtime.h>
+#include <linux/version.h>
+#include <linux/efi.h>
+#include <linux/crc32.h>
+#include <linux/time.h>
+#include "ax_ioctl.h"
+
+#define napi_alloc_skb(napi, length) netdev_alloc_skb_ip_align(netdev, length)
+#define napi_complete_done(n, d) napi_complete(n)
+
+typedef int (*_usb_read_function)(struct ax_device *dev, u8 cmd, u8 reqtype,
+				  u16 value, u16 index, void *data, u16 size);
+typedef int (*_usb_write_function)(struct ax_device *dev, u8 cmd, u8 reqtype,
+				   u16 value, u16 index, const void *data,
+				   u16 size);
+typedef int (*usb_read_function)(struct ax_device *axdev, u8 cmd, u16 value,
+				 u16 index, u16 size, void *data, int eflag);
+typedef int (*usb_write_function)(struct ax_device *axdev, u8 cmd, u16 value,
+				  u16 index, u16 size, void *data);
+
+#define USB_VENDOR_ID_ASIX		0x0B95
+#define USB_VENDOR_ID_SITECOM		0x0DF6
+#define USB_VENDOR_ID_LENOVO		0x17EF
+#define USB_VENDOR_ID_TOSHIBA		0x0930
+#define USB_VENDOR_ID_SAMSUNG		0x04E8
+#define USB_VENDOR_ID_DLINK		0x2001
+#define USB_VENDOR_ID_MAGIC_CONTROL	0x0711
+
+#define AX_DEVICE_ID_179X	0x1790
+#define AX_BCDDEVICE_ID_179	0x0100
+#define AX_BCDDEVICE_ID_179A	0x0200
+#define AX_DEVICE_ID_178A	0x178A
+#define AX_BCDDEVICE_ID_178A	0x0100
+#define AX_DEVICE_ID_772D	AX_DEVICE_ID_179X
+#define AX_BCDDEVICE_ID_772D	0x0300
+#ifdef ENABLE_AX88279
+#define AX_BCDDEVICE_ID_279	0x0400
+#endif
+
+#define AX_DRIVER_STRING_179_178A \
+				"ASIX AX88179_178A USB Ethernet Controller"
+#define AX_DRIVER_STRING_179A_772D \
+				"ASIX AX88179B_179A_772E_772D USB Ethernet Controller"
+#ifdef ENABLE_AX88279
+#define AX_DRIVER_STRING_279 \
+				"ASIX AX88279 USB Ethernet Controller"
+#endif
+
+#define DRIVER_VERSION		"3.3.0"
+#define DRIVER_AUTHOR		"ASIX"
+#define DRIVER_DESC		"ASIX USB Ethernet Controller"
+#define MODULENAME		"ax_usb_nic"
+
+#define PRINT_VERSION(axdev, str) \
+	dev_info(&axdev->intf->dev, \
+		"%s %s (%d.%d.%d.%d_%d.%d)", \
+		str, DRIVER_VERSION, \
+		axdev->fw_version[0], \
+		axdev->fw_version[1], \
+		axdev->fw_version[2], \
+		axdev->fw_version[3], \
+		axdev->chip_version, \
+		axdev->sub_version)
+
+#define AX88179_MAX_TX		4
+#define AX88179_MAX_RX		10
+#define AX88179_BUF_TX_SIZE	(81 * 1024)
+#define AX_GSO_DEFAULT_SIZE	(16 * 1024)
+#define INTBUFSIZE		8
+#define TX_ALIGN		4
+#define RX_ALIGN		8
+#define TX_CASECADES_SIZE	AX_GSO_DEFAULT_SIZE
+
+#define AX_TX_HEADER_LEN	8
+#define AX_TX_TIMEOUT		(5 * HZ)
+#define AX_MCAST_FILTER_SIZE	8
+#define AX_MAX_MCAST		64
+#ifdef ENABLE_QUEUE_PRIORITY
+#define AX_TX_QUEUE_SIZE	2
+#else
+#define AX_TX_QUEUE_SIZE	1
+#endif
+
+#define US_TO_NS		1000
+
+#define AX_ACCESS_MAC			0x01
+#define AX_ACCESS_PHY			0x02
+#define AX_ACCESS_WAKEUP		0x03
+#define AX_ACCESS_EEPROM		0x04
+#define AX_ACCESS_EFUSE			0x05
+#define AX_RELOAD_EEPROM_EFUSE		0x06
+#define AX_RELOAD_FLASH_EFUSE		0x06
+#define AX_FW_MODE			0x08
+	#define AX_FW_MODE_179A			0x0001
+	#define AX_USB_EP5_EN			0x0001
+#ifdef ENABLE_AX88279
+#ifdef ENABLE_PTP_FUNC
+	#define AX_USB_EP4_EN			0x0002
+#endif
+#endif
+#define AX_WRITE_EFUSE_EN		0x09
+#define AX_WRITE_EFUSE_DIS		0x0A
+#define AX_ACCESS_MFAB			0x10
+#define AX_PHY_POLLING			0x90
+
+#define PHYSICAL_LINK_STATUS		0x02
+	#define	AX_USB_SS			0x04
+	#define	AX_USB_HS			0x02
+	#define	AX_USB_FS			0x01
+#define GENERAL_STATUS			0x03
+	#define	AX_SECLD			0x04
+#define AX_CHIP_STATUS			0x05
+	#define AX_CHIP_CODE_MASK		0x70
+	#define CHIP_CODE(x)		((x & AX_CHIP_CODE_MASK) >> 4)
+#define AX_SROM_ADDR			0x07
+#define AX_SROM_CMD			0x0a
+	#define EEP_RD				0x04
+	#define EEP_WR				0x08
+	#define EEP_BUSY			0x10
+#define AX_SROM_DATA_LOW		0x08
+#define AX_SROM_DATA_HIGH		0x09
+#define AX_RX_CTL			0x0b
+#define AX_RX_CTL_HI			0x0c
+	#define AX_RX_CTL_DROPCRCERR_HI		0x01
+	#define AX_RX_CTL_DROPCRCERR		0x0100
+	#define AX_RX_CTL_IPE			0x0200
+	#define AX_RX_CTL_TXPADCRC		0x0400
+	#define AX_RX_CTL_START			0x0080
+	#define AX_RX_CTL_AP			0x0020
+	#define AX_RX_CTL_AM			0x0010
+	#define AX_RX_CTL_AB			0x0008
+	#define AX_RX_CTL_HA8B			0x0004
+	#define AX_RX_CTL_AMALL			0x0002
+	#define AX_RX_CTL_PRO			0x0001
+	#define AX_RX_CTL_STOP			0x0000
+#define AX_NODE_ID			0x10
+#define AX_MULTI_FILTER_ARRY		0x16
+#define AX_MEDIUM_STATUS_MODE		0x22
+	#define AX_MEDIUM_GIGAMODE		0x0001
+	#define AX_MEDIUM_FULL_DUPLEX		0x0002
+	#define AX_MEDIUM_RXFLOW_CTRLEN		0x0010
+	#define AX_MEDIUM_TXFLOW_CTRLEN		0x0020
+	#define AX_MEDIUM_RECEIVE_EN		0x0100
+	#define AX_MEDIUM_PS			0x0200
+	#define AX_MEDIUM_JUMBO_EN		0x8040
+#define AX_MONITOR_MODE			0x24
+	#define AX_MONITOR_MODE_RWLC		0x02
+	#define AX_MONITOR_MODE_RWMP		0x04
+	#define AX_MONITOR_MODE_RWWF		0x08
+	#define AX_MONITOR_MODE_RW_FLAG		0x10
+	#define AX_MONITOR_MODE_PMEPOL		0x20
+	#define AX_MONITOR_MODE_PMETYPE		0x40
+#define AX_GPIO_CTRL			0x25
+	#define AX_GPIO_CTRL_GPIO3EN		0x80
+	#define AX_GPIO_CTRL_GPIO2EN		0x40
+	#define AX_GPIO_CTRL_GPIO1EN		0x20
+#define AX_PHYPWR_RSTCTL		0x26
+	#define AX_PHYPWR_RSTCTL_BZ		0x0010
+	#define AX_PHYPWR_RSTCTL_IPRL		0x0020
+	#define AX_PHYPWR_RSTCTL_AUTODETACH	0x1000
+#define AX_RX_BULKIN_QCTRL		0x2e
+	#define AX_RX_BULKIN_QCTRL_TIME		0x01
+	#define AX_RX_BULKIN_QCTRL_IFG		0x02
+	#define AX_RX_BULKIN_QCTRL_SIZE		0x04
+#define AX_RX_BULKIN_QTIMR_LOW		0x2f
+#define AX_RX_BULKIN_QTIMR_HIGH			0x30
+#define AX_RX_BULKIN_QSIZE			0x31
+#define AX_RX_BULKIN_QIFG			0x32
+#define AX_CLK_SELECT			0x33
+	#define AX_CLK_SELECT_BCS		0x01
+	#define AX_CLK_SELECT_ACS		0x02
+	#define AX_CLK_SELECT_ACSREQ		0x10
+	#define AX_CLK_SELECT_ULR		0x08
+#define AX_RXCOE_CTL			0x34
+	#define AX_RXCOE_IP			0x01
+	#define AX_RXCOE_TCP			0x02
+	#define AX_RXCOE_UDP			0x04
+	#define AX_RXCOE_ICMP			0x08
+	#define AX_RXCOE_IGMP			0x10
+	#define AX_RXCOE_TCPV6			0x20
+	#define AX_RXCOE_UDPV6			0x40
+	#define AX_RXCOE_ICMV6			0x80
+
+#if KERNEL_VERSION(2, 6, 22) < LINUX_VERSION_CODE
+	#define AX_RXCOE_DEF_CSUM	(AX_RXCOE_IP	| AX_RXCOE_TCP  | \
+					 AX_RXCOE_UDP	| AX_RXCOE_ICMV6 | \
+					 AX_RXCOE_TCPV6	| AX_RXCOE_UDPV6)
+#else
+	#define AX_RXCOE_DEF_CSUM	(AX_RXCOE_IP	| AX_RXCOE_TCP | \
+					 AX_RXCOE_UDP)
+#endif
+
+#define AX_TXCOE_CTL			0x35
+	#define AX_TXCOE_IP			0x01
+	#define AX_TXCOE_TCP			0x02
+	#define AX_TXCOE_UDP			0x04
+	#define AX_TXCOE_ICMP			0x08
+	#define AX_TXCOE_IGMP			0x10
+	#define AX_TXCOE_TCPV6			0x20
+	#define AX_TXCOE_UDPV6			0x40
+	#define AX_TXCOE_ICMV6			0x80
+#if KERNEL_VERSION(2, 6, 22) < LINUX_VERSION_CODE
+	#define AX_TXCOE_DEF_CSUM	(AX_TXCOE_TCP   | AX_TXCOE_UDP | \
+					 AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6)
+#else
+	#define AX_TXCOE_DEF_CSUM	(AX_TXCOE_TCP	| AX_TXCOE_UDP)
+#endif
+#define AX_PAUSE_WATERLVL_HIGH		0x54
+#define AX_PAUSE_WATERLVL_LOW		0x55
+#define AX_RX_FREE_BUF_LOW		0x57
+
+#define GMII_PHY_CONTROL		0x00
+	#define GMII_CONTROL_RESET		0x8000
+	#define GMII_CONTROL_LOOPBACK		0x4000
+	#define GMII_CONTROL_10MB		0x0000
+	#define GMII_CONTROL_100MB		0x2000
+	#define GMII_CONTROL_1000MB		0x0040
+	#define GMII_CONTROL_SPEED_BITS		0x2040
+	#define GMII_CONTROL_ENABLE_AUTO	0x1000
+	#define GMII_CONTROL_POWER_DOWN		0x0800
+	#define GMII_CONTROL_ISOLATE		0x0400
+	#define GMII_CONTROL_START_AUTO		0x0200
+	#define GMII_CONTROL_FULL_DUPLEX	0x0100
+#define GMII_PHY_STATUS			0x01
+	#define GMII_STATUS_100MB_MASK		0xE000
+	#define GMII_STATUS_10MB_MASK		0x1800
+	#define GMII_STATUS_AUTO_DONE		0x0020
+	#define GMII_STATUS_AUTO		0x0008
+	#define GMII_STATUS_LINK_UP		0x0004
+	#define GMII_STATUS_EXTENDED		0x0001
+	#define GMII_STATUS_100T4		0x8000
+	#define GMII_STATUS_100TXFD		0x4000
+	#define GMII_STATUS_100TX		0x2000
+	#define GMII_STATUS_10TFD		0x1000
+	#define GMII_STATUS_10T			0x0800
+#define GMII_PHY_OUI			0x02
+#define GMII_PHY_MODEL			0x03
+#define GMII_PHY_ANAR			0x04
+	#define GMII_ANAR_ASYM_PAUSE		0x0800
+	#define GMII_ANAR_PAUSE			0x0400
+	#define GMII_ANAR_100T4			0x0200
+	#define GMII_ANAR_100TXFD		0x0100
+	#define GMII_ANAR_100TX			0x0080
+	#define GMII_ANAR_10TFD			0x0040
+	#define GMII_ANAR_10T			0x0020
+	#define GMII_SELECTOR_FIELD		0x001F
+
+#define GMII_PHY_ANLPAR			0x05
+	#define GMII_ANLPAR_100T4		0x0200
+	#define GMII_ANLPAR_100TXFD		0x0100
+	#define GMII_ANLPAR_100TX		0x0080
+	#define GMII_ANLPAR_10TFD		0x0040
+	#define GMII_ANLPAR_10T			0x0020
+	#define GMII_ANLPAR_PAUSE		0x0400
+	#define GMII_ANLPAR_ASYM_PAUSE		0x0800
+	#define GMII_ANLPAR_ACK			0x4000
+	#define GMII_SELECTOR_8023		0x0001
+#define GMII_PHY_ANER			0x06
+#define GMII_PHY_1000BT_CONTROL		0x09
+#define GMII_PHY_1000BT_STATUS		0x0A
+#define GMII_PHY_MACR			0x0D
+#define GMII_PHY_MAADR			0x0E
+#define GMII_PHY_PHYSR			0x11
+	#define GMII_PHY_PHYSR_SMASK		0xc000
+	#define GMII_PHY_PHYSR_GIGA		0x8000
+	#define GMII_PHY_PHYSR_100		0x4000
+	#define GMII_PHY_PHYSR_FULL		0x2000
+	#define GMII_PHY_PHYSR_LINK		0x400
+
+#define GMII_1000_AUX_CTRL_MASTER_SLAVE		0x1000
+#define GMII_1000_AUX_CTRL_FD_CAPABLE		0x0200
+#define GMII_1000_AUX_CTRL_HD_CAPABLE		0x0100
+#define GMII_1000_AUX_STATUS_FD_CAPABLE		0x0800
+#define GMII_1000_AUX_STATUS_HD_CAPABLE		0x0400
+#define GMII_AUX_CTRL_STATUS		0x1C
+#define GMII_AUX_ANEG_CPLT			0x8000
+#define GMII_AUX_FDX				0x0020
+#define GMII_AUX_SPEED_1000			0x0010
+#define GMII_AUX_SPEED_100			0x0008
+#define GMII_LED_ACTIVE			0x1a
+	#define GMII_LED_ACTIVE_MASK		0xff8f
+	#define GMII_LED0_ACTIVE		(1 << 4)
+	#define GMII_LED1_ACTIVE		(1 << 5)
+	#define GMII_LED2_ACTIVE		(1 << 6)
+#define GMII_LED_LINK			0x1c
+	#define GMII_LED_LINK_MASK		0xf888
+	#define GMII_LED0_LINK_10		(1 << 0)
+	#define GMII_LED0_LINK_100		(1 << 1)
+	#define GMII_LED0_LINK_1000		(1 << 2)
+	#define GMII_LED1_LINK_10		(1 << 4)
+	#define GMII_LED1_LINK_100		(1 << 5)
+	#define GMII_LED1_LINK_1000		(1 << 6)
+	#define GMII_LED2_LINK_10		(1 << 8)
+	#define GMII_LED2_LINK_100		(1 << 9)
+	#define GMII_LED2_LINK_1000		(1 << 10)
+	#define	LED_VALID			(1 << 15)
+	#define	LED0_ACTIVE			(1 << 0)
+	#define	LED0_LINK_10			(1 << 1)
+	#define	LED0_LINK_100			(1 << 2)
+	#define	LED0_LINK_1000			(1 << 3)
+	#define	LED0_FD				(1 << 4)
+	#define LED0_USB3_MASK			0x001f
+	#define	LED1_ACTIVE			(1 << 5)
+	#define	LED1_LINK_10			(1 << 6)
+	#define	LED1_LINK_100			(1 << 7)
+	#define	LED1_LINK_1000			(1 << 8)
+	#define	LED1_FD				(1 << 9)
+	#define LED1_USB3_MASK			0x03e0
+	#define	LED2_ACTIVE			(1 << 10)
+	#define	LED2_LINK_1000			(1 << 13)
+	#define	LED2_LINK_100			(1 << 12)
+	#define	LED2_LINK_10			(1 << 11)
+	#define	LED2_FD				(1 << 14)
+	#define LED2_USB3_MASK			0x7c00
+#define GMII_PHYPAGE			0x1e
+#define GMII_PHY_PAGE_SELECT		0x1f
+	#define GMII_PHY_PAGE_SELECT_EXT	0x0007
+	#define GMII_PHY_PAGE_SELECT_PAGE0	0X0000
+	#define GMII_PHY_PAGE_SELECT_PAGE1	0X0001
+	#define GMII_PHY_PAGE_SELECT_PAGE2	0X0002
+	#define GMII_PHY_PAGE_SELECT_PAGE3	0X0003
+	#define GMII_PHY_PAGE_SELECT_PAGE4	0X0004
+	#define GMII_PHY_PAGE_SELECT_PAGE5	0X0005
+	#define GMII_PHY_PAGE_SELECT_PAGE6	0X0006
+
+enum ax_driver_flags {
+	AX_UNPLUG = 0,
+	AX_ENABLE,
+	AX_LINK_CHG,
+	AX_SELECTIVE_SUSPEND,
+	AX_SCHEDULE_NAPI,
+	AX_EN_RX,
+	AX_SCHEDULE_TASKLET_TX,
+	AX_SCHEDULE_TASKLET_RX,
+};
+
+enum ax_chip_version {
+	AX_VERSION_INVALID		= 0,
+	AX_VERSION_AX88179		= 4,
+	AX_VERSION_AX88179A_772D	= 6,
+#ifdef ENABLE_AX88279
+	AX_VERSION_AX88279		= 7,
+#endif
+};
+
+struct ax_device;
+
+struct rx_desc {
+	struct list_head list;
+	struct urb *urb;
+	struct ax_device *context;
+	void *buffer;
+	void *head;
+};
+
+enum __ax_tx_flags {
+	AX_TX_NONE		= 0,
+	AX_TX_TIMESTAMPS	= 1,
+};
+
+enum __mac_pass_ctrl {
+	MAC_PASS_DISABLED	= 0,
+	MAC_PASS_ENABLE_0	= 1,
+	MAC_PASS_ENABLE_1	= 2,
+};
+
+struct mac_pass {
+	u8	control;
+	u8	mac0[8];
+	u8	mac1[8];
+} __packed;
+
+struct tx_desc {
+	struct list_head list;
+	struct urb *urb;
+	struct ax_device *context;
+	void *buffer;
+	void *head;
+	u32 skb_num;
+	u32 skb_len;
+	unsigned long flags;
+	int q_index;
+};
+
+struct ax_bulkin_setting {
+	u8 custom;
+	u8 bulkin_setting[5];
+};
+
+enum ax_ether_link_speed {
+	ETHER_LINK_NONE	= 0,
+	ETHER_LINK_10	= 1,
+	ETHER_LINK_100	= 2,
+	ETHER_LINK_1000	= 3,
+	ETHER_LINK_2500	= 4,
+};
+
+struct ax_link_info {
+	u8 eth_speed	: 3,
+	   full_duplex	: 1,
+	   usb_speed	: 4;
+} __packed;
+
+struct ax_device {
+	unsigned long flags;
+	struct usb_device *udev;
+	struct usb_interface *intf;
+	struct net_device *netdev;
+	const struct driver_info *driver_info;
+#ifndef ENABLE_RX_TASKLET
+	struct napi_struct napi;
+#endif
+	struct urb *intr_urb;
+	struct tx_desc tx_list[32];
+	struct rx_desc rx_list[32];
+	struct list_head rx_done, tx_free;
+	struct sk_buff_head tx_queue[AX_TX_QUEUE_SIZE];
+	struct sk_buff_head rx_queue;
+	spinlock_t rx_lock, tx_lock;
+	struct delayed_work schedule;
+	struct mii_if_info mii;
+	struct mutex control;
+#ifdef ENABLE_TX_TASKLET
+	struct tasklet_struct tx_tl;
+#endif
+#ifdef ENABLE_RX_TASKLET
+	struct tasklet_struct rx_tl;
+#endif
+
+	int intr_interval;
+	u32 saved_wolopts;
+	u32 msg_enable;
+	u32 tx_qlen;
+	u32 coalesce;
+	u32 max_mtu;
+	u16 speed;
+	u8 *intr_buff;
+	u8 tx_align_len;
+	u8 link;
+	u16 rxctl;
+	u8 m_filter[8];
+	u32 tx_casecade_size;
+	u32 gso_max_size;
+	u8 fw_version[4];
+
+	struct ax_link_info link_info;
+	struct ax_link_info intr_link_info;
+	u8  eee_enabled;
+	u8  eee_active;
+	int autodetach;
+
+	struct ax_bulkin_setting bin_setting;
+	bool tx_header_cksum;
+	unsigned char chip_version;
+	unsigned char sub_version;
+#define AX_ETH_SPEED_MASK	0xF
+#define AX_ETH_DUPLEX_FULL	0x10
+	u8 int_link_info;
+	u8 int_link_chg;
+
+#ifdef ENABLE_PTP_FUNC
+	struct ax_ptp_cfg *ptp_cfg;
+	struct sk_buff_head tx_timestamp;
+#endif
+	u64 bulkin_complete;
+	u64 bulkin_error;
+	u64 bulkout_complete;
+	u64 bulkout_error;
+	u64 bulkint_complete;
+	u64 bulkint_error;
+#ifdef ENABLE_QUEUE_PRIORITY
+	u64 ep5_count;
+	u64 ep3_count;
+#endif
+#define CHIP_40PIN	0x03
+#define CHIP_32PIN	0x02
+	u8 chip_pin;
+#ifdef ENABLE_INT_POLLING
+#define INT_POLLING_TIMER	128	/* in milliseconds */
+	struct delayed_work int_polling_work;
+#endif
+	unsigned autosuspend_is_supported:1;
+};
+
+struct driver_info {
+	int	(*bind)(struct ax_device *axdev);
+	void	(*unbind)(struct ax_device *axdev);
+	int	(*hw_init)(struct ax_device *axdev);
+	int	(*stop)(struct ax_device *axdev);
+#ifdef ENABLE_QUEUE_PRIORITY
+	int	(*queue_priority)(struct ax_device *axdev);
+#endif
+	void	(*rx_fixup)(struct ax_device *axdev, struct rx_desc *desc,
+			    int *work_done, int budget);
+	int	(*tx_fixup)(struct ax_device *axdev, struct tx_desc *desc);
+	int	(*link_reset)(struct ax_device *axdev);
+	int	(*link_setting)(struct ax_device *axdev);
+	int	(*system_suspend)(struct ax_device *axdev);
+	int	(*system_resume)(struct ax_device *axdev);
+	int	(*runtime_suspend)(struct ax_device *axdev);
+	int	(*runtime_resume)(struct ax_device *axdev);
+
+#ifdef ENABLE_PTP_FUNC
+	int (*ptp_pps_ctrl)(struct ax_device *axdev, u8 enable);
+	int	(*ptp_init)(struct ax_device *axdev);
+	void	(*ptp_remove)(struct ax_device *axdev);
+#endif
+
+	unsigned long napi_weight;
+	size_t	buf_rx_size;
+};
+
+struct _async_cmd_handle {
+	struct ax_device *axdev;
+	struct usb_ctrlrequest *req;
+	u8 m_filter[8];
+	u16 rxctl;
+} __packed;
+
+#define AX_INT_PPLS_LINK	(1 << 0)
+#define AX_INT_SPLS_LINK	(1 << 1)
+#define AX_INT_CABOFF_UNPLUG	(1 << 7)
+struct ax_device_int_data {
+#ifdef __BIG_ENDIAN
+	u16 res3;
+	u8 status;
+	u16 res2;
+	u8 link;
+	union {
+		struct ax_link_info link_info;
+		u8 link_info_u8;
+	};
+	u8 res1;
+#else
+	u8 res1;
+	union {
+		struct ax_link_info link_info;
+		u8 link_info_u8;
+	};
+	u8 link;
+	u16 res2;
+	u8 status;
+	u16 res3;
+#endif
+} __packed;
+
+struct _ax_buikin_setting {
+	u8 ctrl;
+	u8 timer_l;
+	u8 timer_h;
+	u8 size;
+	u8 ifg;
+} __packed;
+
+#define AX_RXHDR_L4_ERR		(1 << 8)
+#define AX_RXHDR_L3_ERR		(1 << 9)
+
+#define AX_RXHDR_L4_TYPE_ICMP	2
+#define AX_RXHDR_L4_TYPE_IGMP	3
+#define AX_RXHDR_L4_TYPE_TCMPV6	5
+
+#define AX_RXHDR_L3_TYPE_IP	1
+#define AX_RXHDR_L3_TYPE_IPV6	2
+
+#define AX_RXHDR_L4_TYPE_MASK	0x1c
+#define AX_RXHDR_L4_TYPE_UDP	4
+#define AX_RXHDR_L4_TYPE_TCP	16
+#define AX_RXHDR_L3CSUM_ERR	2
+#define AX_RXHDR_L4CSUM_ERR	1
+#define AX_RXHDR_CRC_ERR	0x20000000
+#define AX_RXHDR_MII_ERR	0x40000000
+#define AX_RXHDR_DROP_ERR	0x80000000
+
+static inline void *__rx_buf_align(void *data)
+{
+	return (void *)ALIGN((uintptr_t)data, RX_ALIGN);
+}
+static inline void *__tx_buf_align(void *data, u8 tx_align_len)
+{
+	return (void *)ALIGN((uintptr_t)data, tx_align_len);
+}
+static inline struct net_device_stats *ax_get_stats(struct net_device *netdev)
+{
+	return &netdev->stats;
+}
+
+int ax_get_mac_pass(struct ax_device *axdev, u8 *mac);
+int ax_check_ether_addr(struct ax_device *axdev, struct sockaddr *p);
+void ax_set_tx_qlen(struct ax_device *dev);
+void ax_write_bulk_callback(struct urb *urb);
+
+void ax_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info);
+#if KERNEL_VERSION(4, 10, 0) > LINUX_VERSION_CODE
+int ax_get_settings(struct net_device *net, struct ethtool_cmd *cmd);
+int ax_set_settings(struct net_device *net, struct ethtool_cmd *cmd);
+#else
+int ax_get_link_ksettings(struct net_device *netdev,
+			  struct ethtool_link_ksettings *cmd);
+int ax_set_link_ksettings(struct net_device *netdev,
+			  const struct ethtool_link_ksettings *cmd);
+#endif
+u32 ax_get_msglevel(struct net_device *netdev);
+void ax_set_msglevel(struct net_device *netdev, u32 value);
+void ax_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo);
+int ax_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo);
+int ax_get_sset_count(struct net_device *dev, int sset);
+void ax_get_ethtool_stats
+(struct net_device *dev, struct ethtool_stats *stats, u64 *data);
+void ax_get_strings(struct net_device *netdev, u32 stringset, u8 *data);
+void ax_get_pauseparam
+(struct net_device *netdev, struct ethtool_pauseparam *pause);
+int ax_set_pauseparam
+(struct net_device *netdev, struct ethtool_pauseparam *pause);
+int ax_get_regs_len(struct net_device *netdev);
+void ax_get_regs
+(struct net_device *netdev, struct ethtool_regs *regs, void *buf);
+
+int ax_read_cmd
+(struct ax_device *axdev, u8 cmd, u16 value, u16 index, u16 size, void *data,
+int eflag);
+
+int ax_write_cmd
+(struct ax_device *axdev, u8 cmd, u16 value, u16 index, u16 size, void *data);
+
+int ax_read_cmd_nopm
+(struct ax_device *axdev, u8 cmd, u16 value, u16 index, u16 size, void *data,
+int eflag);
+
+int ax_write_cmd_nopm
+(struct ax_device *axdev, u8 cmd, u16 value, u16 index, u16 size, void *data);
+
+int ax_write_cmd_async
+(struct ax_device *axdev, u8 cmd, u16 value, u16 index, u16 size, void *data);
+
+int ax_mmd_read(struct net_device *netdev, int dev_addr, int reg);
+void ax_mmd_write(struct net_device *netdev, int dev_addr, int reg, int val);
+
+int ax_mdio_read(struct net_device *netdev, int phy_id, int reg);
+void ax_mdio_write(struct net_device *netdev, int phy_id, int reg, int val);
+
+
+int ax_usb_command(struct ax_device *axdev, struct _ax_ioctl_command *info);
+
+int ax88179a_autosuspend_en(struct ax_device *axdev,
+				struct _ax_ioctl_command *info);
+int ax88179a_ieee_test(struct ax_device *axdev, 
+				struct _ax_ioctl_command *info);
+int ax88179a_sw_reset(struct ax_device *axdev, 
+				struct _ax_ioctl_command *info);
+int ax88179a_erase_sector_flash(struct ax_device *axdev,
+				struct _ax_ioctl_command *info);
+int ax88179a_erase_flash(struct ax_device *axdev,
+				struct _ax_ioctl_command *info);
+int ax88179a_boot_to_rom(struct ax_device *axdev,
+				struct _ax_ioctl_command *info);
+int ax88179a_dump_efuse(struct ax_device *axdev,
+				struct _ax_ioctl_command *info);
+int ax88179a_program_efuse(struct ax_device *axdev,
+				struct _ax_ioctl_command *info);
+int ax88179a_read_flash(struct ax_device *axdev,
+				struct _ax_ioctl_command *info);
+int ax88179a_write_flash(struct ax_device *axdev,
+				struct _ax_ioctl_command *info);
+int ax88179a_read_version(struct ax_device *axdev,
+				struct _ax_ioctl_command *info);
+int ax88179a_signature(struct ax_device *axdev,
+				struct _ax_ioctl_command *info);
+void ax88179a_get_fw_version(struct ax_device *axdev);
+int ax88179_write_eeprom(struct ax_device *axdev,
+				struct _ax_ioctl_command *info);
+int ax88179_read_eeprom(struct ax_device *axdev,
+				struct _ax_ioctl_command *info);
+int ax88179_signature(struct ax_device *axdev,
+				struct _ax_ioctl_command *info);
+
+#endif /* __ASIX_MAIN_H */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/ax_ptp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/ax_ptp.c
@@ -0,0 +1,1173 @@
+// SPDX-License-Identifier: GPL-2.0
+/*******************************************************************************
+ *     Copyright (c) 2022    ASIX Electronic Corporation    All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+#include "ax_main.h"
+#include "ax_ptp.h"
+#include "ax88179a_772d.h"
+
+#define ptp_to_dev(ptp) container_of(ptp, struct ax_ptp_cfg, ptp_caps)
+
+#ifdef ENABLE_AX88279
+static void ax_reset_ptp_queue(struct ax_device *axdev)
+{
+	struct ax_ptp_cfg *ptp_cfg = axdev->ptp_cfg;
+
+	if (!ptp_cfg)
+		return;
+
+	ptp_cfg->ptp_head = 0;
+	ptp_cfg->ptp_tail = 0;
+	ptp_cfg->num_items = 0;
+	ptp_cfg->get_timestamp_retry = 0;
+
+	memset(ptp_cfg->tx_ptp_info, 0, AX_PTP_INFO_SIZE * AX_PTP_QUEUE_SIZE);
+}
+#endif
+
+static int ax88179a_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+	struct ax_ptp_cfg *ptp_cfg = ptp_to_dev(ptp);
+	struct ax_device *axdev = (struct ax_device *)ptp_cfg->axdev;
+	u32 remainder = 0;
+	u64 high_timer = 0;
+	s64 sec = 0, rnsec = 0;
+	s64 nsec = 0;
+	u8 timestamp[10] = {0};
+	int ret;
+
+	ret = ax_read_cmd(axdev, AX_PTP_OP, AX_GET_LOCAL_CLOCK, 0,
+			  AX_GET_LOCAL_CLOCK_SIZE, &timestamp, 0);
+	if (ret < 0)
+		return ret;
+	memcpy(&nsec, timestamp, 4);
+	memcpy(&sec, &timestamp[4], 6);
+	sec *= NSEC_PER_SEC;
+	rnsec = (nsec + sec + delta);
+
+	high_timer = div_u64_rem(rnsec, NSEC_PER_SEC, &remainder);
+	memcpy(timestamp, &remainder, 4);
+	memcpy(&timestamp[4], &high_timer, 6);
+
+	ret = ax_write_cmd(axdev, AX_PTP_OP, AX_SET_LOCAL_CLOCK, 0,
+			    AX_SET_LOCAL_CLOCK_SIZE, &timestamp);
+	if (ret < 0)
+		return ret;
+
+
+	return 0;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,2,0)
+static int
+ax88179a_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+#else
+static int
+ax88179a_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+#endif
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,2,0)
+	long ppb = scaled_ppm_to_ppb(scaled_ppm);
+#endif
+	struct ax_ptp_cfg *ptp_cfg = ptp_to_dev(ptp);
+	struct ax_device *axdev = (struct ax_device *)ptp_cfg->axdev;
+	u32 new_addend_val;
+	u64 adjust_val;
+	int neg_adj = 0, ret;
+
+	if (ppb < 0) {
+		neg_adj = 1;
+		ppb = -ppb;
+	}
+
+	adjust_val = AX_BASE_ADDEND;
+	adjust_val *= ppb;
+	adjust_val = div_u64(adjust_val, NSEC_PER_SEC);
+
+	if (neg_adj)
+		new_addend_val = (u32)(AX_BASE_ADDEND - adjust_val);
+	else
+		new_addend_val = (u32)(AX_BASE_ADDEND + adjust_val);
+
+	ret = ax_write_cmd(axdev, AX_PTP_OP, AX_SET_ADDEND, 0,
+			   AX_SET_ADDEND_SIZE, &new_addend_val);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int ax88179a_ptp_gettime64
+(struct ptp_clock_info *ptp, struct timespec64 *ts)
+{
+	struct ax_ptp_cfg *ptp_cfg = ptp_to_dev(ptp);
+	struct ax_device *axdev = (struct ax_device *)ptp_cfg->axdev;
+	u64 sec = 0;
+	u32 nsec = 0;
+	u8 timestamp[10] = {0};
+	int ret;
+
+	ret = ax_read_cmd(axdev, AX_PTP_OP, AX_GET_LOCAL_CLOCK, 0,
+			  AX_GET_LOCAL_CLOCK_SIZE, &timestamp, 0);
+	if (ret < 0)
+		return ret;
+
+	memcpy(&nsec, timestamp, 4);
+	memcpy(&sec, &timestamp[4], 6);
+	ts->tv_nsec = nsec;
+	ts->tv_sec = sec;
+
+	return 0;
+}
+
+static int ax88179a_ptp_settime64
+(struct ptp_clock_info *ptp, const struct timespec64 *ts)
+{
+	struct ax_ptp_cfg *ptp_cfg = ptp_to_dev(ptp);
+	struct ax_device *axdev = (struct ax_device *)ptp_cfg->axdev;
+	u64 sec;
+	u32 nsec;
+	u8 timestamp[10] = {0};
+	int ret;
+
+	nsec = (u32)ts->tv_nsec;
+	memcpy(timestamp, &nsec, 4);
+	sec = (u64)ts->tv_sec;
+	memcpy(&timestamp[4], &sec, 6);
+
+	ret = ax_write_cmd(axdev, AX_PTP_OP, AX_SET_LOCAL_CLOCK, 0,
+			    AX_SET_LOCAL_CLOCK_SIZE, &timestamp);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int ax_ptp_enable(struct ptp_clock_info *ptp,
+			 struct ptp_clock_request *rq, int on)
+{
+	return -EOPNOTSUPP;
+}
+
+static struct ptp_clock_info ax88179a_772d_ptp_clock = {
+	.owner		= THIS_MODULE,
+	.name		= "asix ptp",
+	.max_adj	= 100000000,
+	.n_ext_ts	= 0,
+	.pps		= 0,
+#if KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE
+	.adjfine	= NULL,
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,2,0)
+	.adjfine	= ax88179a_ptp_adjfine,
+#else
+	.adjfreq	= ax88179a_ptp_adjfreq,
+#endif
+	.adjtime	= ax88179a_ptp_adjtime,
+	.gettime64	= ax88179a_ptp_gettime64,
+	.settime64	= ax88179a_ptp_settime64,
+	.n_per_out	= 0,
+	.enable		= ax_ptp_enable,
+	.n_pins		= 0,
+	.verify		= NULL,
+	.pin_config	= NULL,
+};
+
+int ax88179a_ptp_init(struct ax_device *axdev)
+{
+	struct ax_link_info *link_info = &axdev->link_info;
+	u32 new_addend_val = AX_BASE_ADDEND;
+	u8 reg8;
+	u8 ptpset;
+	u8 ptp_tx_delay[5] = { 0 };
+	u8 ptp_rx_delay[5] = { 0 };
+	u32 reg32;
+	u32 timeout = 0;
+	int ret;
+#ifdef ENABLE_PTP_FUNC
+	axdev->driver_info->ptp_pps_ctrl(axdev, 1);
+#endif
+	if (axdev->sub_version < 3)
+		return 0;
+
+	ret = ax_write_cmd(axdev, AX_PTP_OP, AX_SET_ADDEND, 0,
+			   AX_SET_ADDEND_SIZE, &new_addend_val);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX_PTP_PERIOD;
+	ret = ax_write_cmd(axdev, AX_PTP_CMD, AX88179A_PTP_TIMER_PERIOD,
+			    0, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	ret = ax_read_cmd(axdev, AX_PTP_CMD, AX88179A_PTP_CTRL_2,
+			   0, 1, &reg8, 0);
+	if (ret < 0)
+		return ret;
+	reg8 |= AX_PTP_CTRL_SET_PERIOD;
+	ret = ax_write_cmd(axdev, AX_PTP_CMD, AX88179A_PTP_CTRL_2, 0, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	ret = ax_read_cmd(axdev, AX_PTP_CMD, AX88179A_PTP_CTRL_1,
+			   0, 1, &ptpset, 0);
+	if (ret < 0)
+		return ret;
+	ptpset |= AX_PTP_CTRL_L3_EN | AX_PTP_CTRL_EN | AX_PTP_TX_PLUS_DELAY |
+		  AX_PTP_TX_FILTER_GENERAL_MSG | AX_PTP_RX_FILTER_GENERAL_MSG;
+	ret = ax_write_cmd(axdev, AX_PTP_CMD, AX88179A_PTP_CTRL_1,
+			    0, 1, &ptpset);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX_179A_PTP_INFO_SEG_SIZE * AX_PTP_HW_QUEUE_SIZE;
+	ret = ax_write_cmd(axdev, AX_PTP_CMD, AX88179A_PTP_MEM_SEG_SIZE,
+			   0, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	do {
+		reg8 = 0;
+		ret = ax_write_cmd(axdev, AX_PTP_CMD, AX88179A_PTP_MEM_SEG_SET,
+				   0, 1, &reg8);
+		if (ret < 0)
+			return ret;
+
+		ret = ax_read_cmd(axdev, AX_PTP_CMD,
+				  AX88179A_PTP_MEM_SEG_STATUS, 0, 1, &reg8, 0);
+		if (ret < 0)
+			return ret;
+		reg8 &= AX_PTP_MEM_SEG_MASK;
+
+		if (timeout++ > 5)
+			break;
+	} while (reg8 != AX_PTP_MEM_SEG_0);
+
+	reg32 = AX_PPS_ACTIVE_DEFAULT_TIME;
+	ret = ax_write_cmd(axdev, AX_PTP_OP, AX_SET_ACTIVE_TIME, 0,
+			   AX_SET_ACTIVE_TIME_SIZE, &reg32);
+	if (ret < 0)
+		return ret;
+
+	switch (link_info->eth_speed) {
+	case ETHER_LINK_100:
+		ptp_tx_delay[0] = 0x64;
+		ptp_tx_delay[4] = ptpset;
+		ptp_rx_delay[0] = 0x22;
+		ptp_rx_delay[1] = 0x01;
+		ptp_rx_delay[4] = ptpset;
+		break;
+	case ETHER_LINK_10:
+		ptp_tx_delay[0] = 0xB7;
+		ptp_tx_delay[1] = 0x0F;
+		ptp_tx_delay[4] = ptpset;
+		ptp_rx_delay[0] = 0xAC;
+		ptp_rx_delay[1] = 0x0A;
+		ptp_rx_delay[4] = ptpset;
+		break;
+	case ETHER_LINK_1000:
+	default:
+		ptp_tx_delay[0] = 0x6E;
+		ptp_tx_delay[4] = ptpset;
+		ptp_rx_delay[0] = 0xE4;
+		ptp_rx_delay[4] = ptpset;
+		break;
+	}
+
+	ret = ax_write_cmd(axdev, AX_PTP_OP, AX_SET_TX_PHY_DELAY, 0,
+			   AX_SET_TX_PHY_DELAY_SIZE, ptp_tx_delay);
+	if (ret < 0)
+		return ret;
+
+	ret = ax_write_cmd(axdev, AX_PTP_OP, AX_SET_RX_PHY_DELAY, 0,
+			   AX_SET_RX_PHY_DELAY_SIZE, ptp_rx_delay);
+	if (ret < 0)
+		return ret;
+
+	axdev->netdev->features &= ~(NETIF_F_SG | NETIF_F_TSO);
+	axdev->netdev->hw_features &= ~(NETIF_F_SG | NETIF_F_TSO);
+	axdev->netdev->vlan_features &= ~(NETIF_F_SG | NETIF_F_TSO);
+
+	return 0;
+}
+
+int ax88179a_ptp_pps_ctrl(struct ax_device *axdev, u8 enable)
+{
+	u32 reg32 = 0;
+	int ret;
+	
+	ret = ax_read_cmd(axdev, AX88179A_PBUS_REG, 0x1894, 0x000F, 4, &reg32, 1);
+	if (ret < 0)
+		return ret;
+
+	reg32 &= ~0x01000000;
+
+	if (enable) 
+		reg32 |= 0x01000000;
+
+	ret = ax_write_cmd(axdev, AX88179A_PBUS_REG, 0x1894, 0x000F, 4, &reg32);
+	if (ret < 0)
+		return ret;
+	
+	return 0;
+}
+
+#ifdef ENABLE_AX88279
+int ax88279_ptp_pps_ctrl(struct ax_device *axdev, u8 enable)
+{
+	u32 reg32 = 0;
+	int ret;
+
+	ret = ax_read_cmd(axdev, AX_PBUS_A32, 0xF8C8, 0x000C, 4, &reg32, 1);
+	if (ret < 0)
+		return ret;
+
+	reg32 &= ~0x00004000;
+	
+	if (enable) 
+		reg32 |= 0x00004000;
+
+	ret = ax_write_cmd(axdev, AX_PBUS_A32, 0xF8C8, 0x000C, 4, &reg32);
+
+	return 0;
+}
+#endif
+
+void ax88179a_ptp_remove(struct ax_device *axdev)
+{
+	u8 reg8;
+#ifdef ENABLE_PTP_FUNC
+	axdev->driver_info->ptp_pps_ctrl(axdev, 0);
+#endif
+	if (axdev->sub_version < 3)
+		return;
+
+	ax_read_cmd(axdev, AX_PTP_CMD,  AX88179A_PTP_CTRL_1, 0, 1, &reg8, 0);
+	reg8 &= ~(AX_PTP_CTRL_L3_EN | AX_PTP_CTRL_EN);
+	ax_write_cmd(axdev, AX_PTP_CMD, AX88179A_PTP_CTRL_1, 0, 1, &reg8);
+}
+
+void ax_ptp_unregister(struct ax_device *axdev)
+{
+	struct ax_ptp_cfg *ptp_cfg = axdev->ptp_cfg;
+
+	if (axdev->driver_info->ptp_remove)
+		axdev->driver_info->ptp_remove(axdev);
+
+	if (ptp_cfg) {
+		if (ptp_cfg->ptp_clock)
+			ptp_clock_unregister(ptp_cfg->ptp_clock);
+	}
+}
+
+static u8 ax_find_ptp_item(struct ax_device *axdev, struct _ptp_header *ptp,
+			   struct sk_buff *skb)
+{
+	struct ax_ptp_cfg *ptp_cfg = axdev->ptp_cfg;
+	struct _ax_ptp_info *temp_ptp_info = ptp_cfg->tx_ptp_info;
+	u16 sequence_id;
+	u8 message_type = ptp->message_type;
+	int i, read_ptr;
+
+	read_ptr = ptp_cfg->ptp_head;
+#ifdef ENABLE_PTP_DEBUG
+	printk("%s - ptp_head: %d", __func__, read_ptr);
+#endif
+
+	if (axdev->chip_version == AX_VERSION_AX88179A_772D)
+		sequence_id = ntohs(ptp->sequence_id) & 0xFF;
+	else
+		sequence_id = ntohs(ptp->sequence_id) & 0xFFFF;
+
+	for (i = 0; i < ptp_cfg->num_items; i++) {
+		if ((temp_ptp_info[read_ptr].sequence_id == sequence_id) &&
+		    (temp_ptp_info[read_ptr].msg_type == message_type)) {
+			struct skb_shared_hwtstamps shhwtstamps;
+			u64 timestamp_h, timestamp_l, temp;
+			u64 time64;
+
+			ptp_cfg->num_items--;
+			ptp_cfg->ptp_head++;
+			if (ptp_cfg->ptp_head == AX_PTP_QUEUE_SIZE)
+				ptp_cfg->ptp_head = 0;
+			timestamp_l = temp_ptp_info[read_ptr].nsec;
+			timestamp_h = temp_ptp_info[read_ptr].sec_l;
+			temp = temp_ptp_info[read_ptr].sec_h;
+			timestamp_h |= (temp << 32);
+			time64 = timestamp_h * NSEC_PER_SEC;
+			time64 += timestamp_l & 0xFFFFFFFF;
+			memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+			shhwtstamps.hwtstamp = ns_to_ktime(time64);
+			if (ptp->flags & 0x2 ||
+			    (ptp->message_type != 0 && ptp->message_type != 3))
+				skb_tstamp_tx(skb, &shhwtstamps);
+#ifdef ENABLE_PTP_DEBUG
+			printk("%s - skb_tstamp_tx return", __func__);
+#endif
+			dev_kfree_skb_any(skb);
+			return 0;
+		}
+		read_ptr++;
+		if (read_ptr == AX_PTP_QUEUE_SIZE)
+			read_ptr = 0;
+	}
+	return AX_PTP_QUEUE_SIZE;
+}
+
+static void ax_tx_check_timestamp(struct ax_device *axdev, struct sk_buff *skb)
+{
+	if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
+		struct _ptp_header ptp;
+		unsigned int ptp_msg_offset;
+		u16 tmp, tx_ethertype, vlan_id = 0;
+		u8 vlan_size = 0, ptp_item = AX_PTP_QUEUE_SIZE;
+
+		skb_copy_from_linear_data_offset(skb, AX_ETHTYPE_OFFSET,
+						 &tmp, 2);
+		tx_ethertype = ntohs(tmp);
+		if (tx_ethertype == ETH_P_8021Q) {
+			skb_copy_from_linear_data_offset(skb,
+							 AX_ETHTYPE_OFFSET + 2,
+							 &tmp, 2);
+			vlan_id = ntohs(tmp) & 0xFFF;
+			vlan_size = 4;
+			skb_copy_from_linear_data_offset(skb,
+							 AX_ETHTYPE_OFFSET + 4,
+							 &tmp, 2);
+			tx_ethertype = ntohs(tmp);
+			if (tx_ethertype == ETH_P_8021Q) {
+				vlan_size = 8;
+				skb_copy_from_linear_data_offset(skb,
+							 AX_ETHTYPE_OFFSET + 4,
+							 &tmp, 2);
+				tx_ethertype = ntohs(tmp);
+			}
+		}
+		ptp_msg_offset = vlan_size;
+		if (tx_ethertype == ETH_P_1588)
+			ptp_msg_offset += AX_TX_PTPHDR_OFFSET_L2;
+		else if (tx_ethertype == ETH_P_IP)
+			ptp_msg_offset += AX_TX_PTPHDR_OFFSET_L3_IP;
+		else if (tx_ethertype == ETH_P_IPV6)
+			ptp_msg_offset += AX_TX_PTPHDR_OFFSET_L3_IPV6;
+		else
+			return;
+
+		skb_copy_from_linear_data_offset(skb, ptp_msg_offset,
+						 &ptp, PTP_HDR_SIZE);
+
+		ptp_item = ax_find_ptp_item(axdev, &ptp, skb);
+		if (ptp_item == AX_PTP_QUEUE_SIZE) {
+			dev_err(&axdev->intf->dev,
+				"Not found item from PTP queue");
+			return;
+		}
+	}
+}
+
+static void ax_tx_timestamp(struct ax_device *axdev)
+{
+	struct sk_buff_head *tx_timestamp = &axdev->tx_timestamp;
+
+	while (!skb_queue_empty(tx_timestamp)) {
+		struct sk_buff *skb;
+
+		skb = __skb_dequeue(tx_timestamp);
+		if (!skb)
+			return;
+
+		ax_tx_check_timestamp(axdev, skb);
+	}
+}
+
+static struct _ax_ptp_info *ax_ptp_info_transform(struct ax_device *axdev,
+						  void *data)
+{
+	struct _ax_ptp_info temp[AX_PTP_HW_QUEUE_SIZE] = {0};
+	int i;
+
+	switch (axdev->chip_version) {
+	case AX_VERSION_AX88179A_772D:
+	{
+		struct _179a_ptp_info *_179a_ptp = (typeof(_179a_ptp))data;
+
+		for (i = 0; i < AX_PTP_HW_QUEUE_SIZE; i++) {
+			memcpy(&temp[i], &_179a_ptp[i], 2);
+			temp[i].sequence_id &= 0xFF;
+			temp[i].nsec = _179a_ptp[i].nsec;
+			temp[i].sec_l = _179a_ptp[i].sec_l;
+			temp[i].sec_h = _179a_ptp[i].sec_h;
+		}
+		memcpy(data, temp, AX_PTP_INFO_SIZE);
+		break;
+	}
+	};
+
+	return (struct _ax_ptp_info *)data;
+}
+
+
+#if KERNEL_VERSION(2, 6, 20) > LINUX_VERSION_CODE
+static void ax_ptp_ts_callback(struct urb *urb, struct pt_regs *regs)
+#else
+static void ax_ptp_ts_callback(struct urb *urb)
+#endif
+{
+	struct _ax_ptp_usb_info *ptp_info = (typeof(ptp_info))urb->context;
+	struct ax_device *axdev = (struct ax_device *)ptp_info->axdev;
+	struct ax_ptp_cfg *ptp_cfg = axdev->ptp_cfg;
+	struct _ax_ptp_info *temp_ptp_info = ptp_info->ax_ptp_info;
+	int i, count = 0;
+#ifdef ENABLE_PTP_DEBUG
+	printk("%s - Start urb->actual_length: %d",
+		__func__, urb->actual_length);
+#endif
+	if (urb->status < 0) {
+		printk(KERN_ERR "failed get ts (%d)", urb->status);
+		goto free;
+	}
+
+	temp_ptp_info = ax_ptp_info_transform(axdev, ptp_info->ax_ptp_info);
+	if (temp_ptp_info == NULL) {
+		printk(KERN_ERR "Failed to transform ptp info.");
+		goto free;
+	}
+
+	for (i = 0; i < AX_PTP_HW_QUEUE_SIZE; i++) {
+		if (temp_ptp_info[i].status) {
+			ptp_cfg->tx_ptp_info[ptp_cfg->ptp_tail++] = temp_ptp_info[i];
+			if (ptp_cfg->ptp_tail == AX_PTP_QUEUE_SIZE)
+				ptp_cfg->ptp_tail = 0;
+			ptp_cfg->num_items++;
+#ifdef ENABLE_PTP_DEBUG
+printk("### ptp_tail: %ld, ptp_head: %ld, num_items: %ld",
+	ptp_cfg->ptp_tail, ptp_cfg->ptp_head, ptp_cfg->num_items);
+printk("### (%s) - DATA %d -------------###", __func__, i);
+printk("### status: %d", temp_ptp_info[i].status);
+printk("### type: 0x%02x", temp_ptp_info[i].msg_type);
+printk("### s_id: 0x%04x", temp_ptp_info[i].sequence_id);
+printk("### nsec: 0x%08x", temp_ptp_info[i].nsec);
+printk("###  sec: 0x%04x%08x", temp_ptp_info[i].sec_h, temp_ptp_info[i].sec_l);
+printk("### ----------------------------###\n");
+#endif
+			count++;
+			ptp_cfg->get_timestamp_retry = 0;
+		}
+	}
+	if (count == 0 &&
+	    ptp_cfg->get_timestamp_retry < EP0_GET_TIMESTAMP_RETRY) {
+		ax_ptp_ts_read_cmd_async(axdev);
+		ptp_cfg->get_timestamp_retry++;
+		goto free;
+	}
+
+	if (ptp_cfg->get_timestamp_retry == EP0_GET_TIMESTAMP_RETRY)
+		dev_err(&axdev->intf->dev, "Get timestamp failed.");
+
+	ax_tx_timestamp(axdev);
+free:
+	kfree(temp_ptp_info);
+	usb_free_urb(urb);
+}
+
+int ax_ptp_ts_read_cmd_async(struct ax_device *axdev)
+{
+	struct usb_ctrlrequest *req;
+	int status = 0;
+	struct urb *urb;
+	struct _ax_ptp_usb_info *info;
+	u16 size = AX_PTP_INFO_SIZE * AX_PTP_HW_QUEUE_SIZE;
+
+	if (axdev->chip_version > AX_VERSION_AX88179A_772D)
+		return 0;
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (urb == NULL) {
+		dev_err(&axdev->intf->dev,
+			   "Error allocating URB in write_cmd_async!");
+		return -ENOMEM;
+	}
+
+	info = kzalloc(sizeof(struct _ax_ptp_usb_info), GFP_ATOMIC);
+	if (!info) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+
+	info->axdev = axdev;
+	req = &info->req;
+
+	req->bRequestType = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+	req->bRequest = AX_PTP_TIMESTAMP;
+	req->wValue = cpu_to_le16(0);
+	req->wIndex = cpu_to_le16(0);
+	req->wLength = cpu_to_le16(size);
+
+	memset(info->ax_ptp_info, 0, AX_PTP_INFO_SIZE * AX_PTP_QUEUE_SIZE);
+
+	usb_fill_control_urb(urb, axdev->udev,
+			     usb_sndctrlpipe(axdev->udev, 0),
+			     (void *)req, info->ax_ptp_info, size,
+			     ax_ptp_ts_callback, info);
+
+	status = usb_submit_urb(urb, GFP_ATOMIC);
+	if (status < 0) {
+		dev_err(&axdev->intf->dev,
+			   "Error submitting the control message: status=%d",
+			   status);
+		kfree(info);
+		usb_free_urb(urb);
+	}
+
+	return 0;
+}
+
+void ax_rx_get_timestamp(struct sk_buff *skb, u64 *pkt_hdr)
+{
+	struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
+	u64 timestamp_h, timestamp_l;
+	u64 time64;
+
+	timestamp_l = *((u64 *)(++pkt_hdr));
+	timestamp_h = *((u64 *)(++pkt_hdr));
+#ifdef ENABLE_PTP_DEBUG
+	printk("### (%s) h: 0x%llx, l: 0x%llx %lld###", __func__,
+		timestamp_h, timestamp_l, timestamp_l);
+#endif
+	timestamp_h <<= 32;
+	timestamp_h |= (timestamp_l >> 32) & 0xFFFFFFFF;
+	time64 = (timestamp_h * NSEC_PER_SEC);
+	time64 += (timestamp_l & 0xFFFFFFFF);
+#ifdef ENABLE_PTP_DEBUG
+	printk("### (%s) h: %lld, time64: %lld ###", __func__,
+		timestamp_h, time64);
+#endif
+	memset(shhwtstamps, 0, sizeof(struct skb_shared_hwtstamps));
+	shhwtstamps->hwtstamp = ns_to_ktime(time64);
+}
+
+#ifdef ENABLE_AX88279
+static int ax_ptp_pbus_write(struct ax_device *axdev, u16 offset, u16 len,
+			     void *data)
+{
+	int ret = 0;
+
+	ret = ax_write_cmd(axdev,
+			    AX_PBUS_A32,
+			    offset,
+			    AX_PTP_REG_BASE_ADDR_HI,
+			    len,
+			    data);
+
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int ax_ptp_clk_write(struct ax_device *axdev, u16 offset, u16 len,
+			    void *data)
+{
+	int ret = 0;
+
+	ret = ax_write_cmd(axdev,
+			    AX_PBUS_A32,
+			    offset,
+			    AX_PTP_REG_BASE_ADDR_HI,
+			    len,
+			    data);
+
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+static int ax_ptp_clk_read(struct ax_device *axdev, u16 offset, u16 len,
+			   void *data)
+{
+	int ret = 0;
+
+	ret = ax_read_cmd(axdev,
+			   AX_PTP_CLK,
+			   0x0002,
+			   offset,
+			   len,
+			   data,
+			   0);
+
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,2,0)
+static int ax88279_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
+#else
+static int ax88279_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+#endif
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,2,0)
+	long ppb = scaled_ppm_to_ppb(scaled_ppm);
+#endif
+	struct ax_ptp_cfg *ptp_cfg = ptp_to_dev(ptp);
+	struct ax_device *axdev = (struct ax_device *)ptp_cfg->axdev;
+	u32 new_addend_val;
+	u64 adjust_val;
+	int neg_adj = 0, ret;
+
+	if (ppb < 0) {
+		neg_adj = 1;
+		ppb = -ppb;
+	}
+
+	adjust_val = AX_BASE_ADDEND;
+	adjust_val *= ppb;
+	adjust_val = div_u64(adjust_val, NSEC_PER_SEC);
+
+	if (neg_adj)
+		new_addend_val = (u32)(AX_BASE_ADDEND - adjust_val);
+	else
+		new_addend_val = (u32)(AX_BASE_ADDEND + adjust_val);
+
+	ret = ax_ptp_pbus_write(axdev,
+			   AX_PTP_TIMER_ADDEND,
+			   sizeof(new_addend_val),
+			   &new_addend_val);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int ax88279_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+	struct ax_ptp_cfg *ptp_cfg = ptp_to_dev(ptp);
+	struct ax_device *axdev = (struct ax_device *)ptp_cfg->axdev;
+	u32 remainder = 0;
+	u64 high_timer = 0;
+	s64 sec = 0;
+	s64 nsec = 0;
+	u8 timestamp[12] = {0};
+	int ret;
+
+	ret = ax_ptp_clk_read(axdev, AX_PTP_GET_80B_LCK_VAL0, 10, timestamp);
+	if (ret < 0)
+		return ret;
+
+	memcpy(&nsec, timestamp, 4);
+	memcpy(&sec, &timestamp[4], 6);
+	sec *= NSEC_PER_SEC;
+	nsec = (sec + delta);
+
+	high_timer = div_u64_rem(nsec, NSEC_PER_SEC, &remainder);
+	memcpy(timestamp, &remainder, 4);
+	memcpy(&timestamp[4], &high_timer, 6);
+
+	ret = ax_ptp_clk_write(axdev, AX_PTP_SET_80B_LCK_VAL0, 12, timestamp);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int ax88279_ptp_gettime64(struct ptp_clock_info *ptp,
+				struct timespec64 *ts)
+{
+	struct ax_ptp_cfg *ptp_cfg = ptp_to_dev(ptp);
+	struct ax_device *axdev = (struct ax_device *)ptp_cfg->axdev;
+	u64 sec = 0;
+	u32 nsec = 0;
+	u8 timestamp[12] = {0};
+	int ret;
+
+	ret = ax_ptp_clk_read(axdev, AX_PTP_GET_80B_LCK_VAL0, 10, timestamp);
+	if (ret < 0)
+		return ret;
+
+	memcpy(&nsec, timestamp, 4);
+	memcpy(&sec, &timestamp[4], 6);
+	ts->tv_nsec = nsec;
+	ts->tv_sec = sec;
+
+	return 0;
+}
+
+static int ax88279_ptp_settime64(struct ptp_clock_info *ptp,
+				const struct timespec64 *ts)
+{
+	struct ax_ptp_cfg *ptp_cfg = ptp_to_dev(ptp);
+	struct ax_device *axdev = (struct ax_device *)ptp_cfg->axdev;
+	u64 sec;
+	u32 nsec;
+	u8 timestamp[10] = {0};
+	int ret;
+
+	nsec = (u32)ts->tv_nsec;
+	memcpy(timestamp, &nsec, 4);
+	sec = (u64)ts->tv_sec;
+	memcpy(&timestamp[4], &sec, 6);
+
+	ret = ax_ptp_clk_write(axdev, AX_PTP_SET_80B_LCK_VAL0, 10, timestamp);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static struct ptp_clock_info ax88279_ptp_clock = {
+	.owner		= THIS_MODULE,
+	.name		= "asix ptp",
+	.max_adj	= 100000000,
+	.n_ext_ts	= 0,
+	.pps		= 0,
+#if KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE
+	.adjfine	= NULL,
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,2,0)
+	.adjfine	= ax88279_ptp_adjfine,
+#else
+	.adjfreq	= ax88279_ptp_adjfreq,
+#endif
+	.adjtime	= ax88279_ptp_adjtime,
+	.gettime64	= ax88279_ptp_gettime64,
+	.settime64	= ax88279_ptp_settime64,
+	.n_per_out	= 0,
+	.enable		= ax_ptp_enable,
+	.n_pins		= 0,
+	.verify		= NULL,
+	.pin_config	= NULL,
+};
+
+int ax88279_ptp_init(struct ax_device *axdev)
+{
+	struct ax_link_info *link_info = &axdev->link_info;
+	u32 reg32;
+	u8 reg8;
+	int ret;
+
+	ax_reset_ptp_queue(axdev);
+
+#ifdef ENABLE_PTP_FUNC
+	axdev->driver_info->ptp_pps_ctrl(axdev, 1);
+#endif
+
+	reg32 = (AX_PTP_MEM_SEG_SIZE_279_5 << 24) |
+		(AX_PTP_MEM_START_ADDR << 8) | AX_PTP_PTP_CPU_EN;
+	ret = ax_ptp_pbus_write(axdev, AX_PTP_TX_MEM_SETTING, 4, &reg32);
+	if (ret < 0)
+		return ret;
+
+	reg32 = AX_PPS_ACTIVE_DEFAULT_TIME;
+	ret = ax_ptp_pbus_write(axdev, AX_PTP_PPS_ACTIVE_TIME, 4, &reg32);
+	if (ret < 0)
+		return ret;
+
+	reg32 = AX_PTP_LCK_CTRL0_EN | AX_PTP_LCK_CTRL0_80B_NS_EN |
+		AX_PTP_LCK_CTRL0_80B_S_EN | AX_PTP_LCK_CTRL0_48B_EN |
+		AX_PTP_LCK_CTRL0_PPS_EN | AX_PTP_LCK_CTRL0_TX_DEL_VEC;
+	ret = ax_ptp_pbus_write(axdev, AX_PTP_LCK_CTRL0, 4, &reg32);
+	if (ret < 0)
+		return ret;
+
+	reg32 = AX_BASE_ADDEND;
+	ret = ax_ptp_pbus_write(axdev, AX_PTP_TIMER_ADDEND, 4, &reg32);
+	if (ret < 0)
+		return ret;
+
+	reg32 = AX_PTP_PERIOD;
+	ret = ax_ptp_pbus_write(axdev, AX_PTP_TIMER_PERIOD, 4, &reg32);
+	if (ret < 0)
+		return ret;
+
+	ret = ax_read_cmd(axdev, AX_ACCESS_MAC, AX_MAC_BFM_CTRL, 1, 1, &reg8, 0);
+	if (ret < 0)
+		return ret;
+	reg8 |= AX_CS_TRAIL_UDPV4_EN | AX_CS_TRAIL_UDPV6_EN;
+	ret = ax_write_cmd(axdev, AX_ACCESS_MAC, AX_MAC_BFM_CTRL, 1, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	switch (link_info->eth_speed) {
+	case ETHER_LINK_100:
+		reg32 = (AX_IPG_COUNTER_100M) |
+			(AX_SOF_DELAY_COUNTER_100M << 8) |
+			(AX_VAILD_DELAY_COUNTER_100M << 16);
+		ret = ax_write_cmd(axdev, AX_PBUS_A32, AX_TX_READY_CTRL,
+				   AX_PBUS_REG_BASE_ADDR_HI, 4, &reg32);
+		if (ret < 0)
+			return ret;
+
+		reg32 = AX_PTP_RX_CTRL0_DEFAULT;
+		ret = ax_ptp_pbus_write(axdev, AX_PTP_RX_CTRL0, 4, &reg32);
+		if (ret < 0)
+			return ret;
+
+		reg32 = AX_PTP_TX_CTRL0_DEFAULT |
+			(0x10 << AX_TXC0_VAL_DELAY_CNT_SHIFT);
+		ret = ax_ptp_pbus_write(axdev, AX_PTP_TX_CTRL0, 4, &reg32);
+		if (ret < 0)
+			return ret;
+		break;
+	case ETHER_LINK_1000:
+		reg32 = (AX_IPG_COUNTER_1G) |
+			(AX_SOF_DELAY_COUNTER_1G << 8) |
+			(AX_VAILD_DELAY_COUNTER_1G << 16);
+		ret = ax_write_cmd(axdev, AX_PBUS_A32, AX_TX_READY_CTRL,
+				   AX_PBUS_REG_BASE_ADDR_HI, 4, &reg32);
+		if (ret < 0)
+			return ret;
+
+		reg32 = AX_PTP_RX_CTRL0_DEFAULT;
+		ret = ax_ptp_pbus_write(axdev, AX_PTP_RX_CTRL0, 4, &reg32);
+		if (ret < 0)
+			return ret;
+
+		reg32 = AX_PTP_TX_CTRL0_DEFAULT |
+			(0x8 << AX_TXC0_VAL_DELAY_CNT_SHIFT);
+		ret = ax_ptp_pbus_write(axdev, AX_PTP_TX_CTRL0, 4, &reg32);
+		if (ret < 0)
+			return ret;
+		break;
+	case ETHER_LINK_2500:
+		reg32 = AX_PTP_RX_CTRL0_DEFAULT | AX_PTP_RXC0_XGMII_EN;
+		ret = ax_ptp_pbus_write(axdev, AX_PTP_RX_CTRL0, 4, &reg32);
+		if (ret < 0)
+			return ret;
+
+		reg32 = AX_PTP_TX_CTRL0_DEFAULT | AX_PTP_TXC0_XGMII_EN |
+			(0x8 << AX_TXC0_VAL_DELAY_CNT_SHIFT);
+		ret = ax_ptp_pbus_write(axdev, AX_PTP_TX_CTRL0, 4, &reg32);
+		if (ret < 0)
+			return ret;
+		break;
+	default:
+		break;
+	}
+
+	reg32 = 0;
+	ret = ax_ptp_pbus_write(axdev, AX_PTP_TX_DELAY, 4, &reg32);
+	if (ret < 0)
+		return ret;
+
+	reg32 = 0;
+	ret = ax_ptp_pbus_write(axdev, AX_PTP_RX_DELAY, 4, &reg32);
+	if (ret < 0)
+		return ret;
+
+	reg8 = AX_EXT_INT_ON | AX_PTP_TX_TX_INT_EN;
+	ret = ax_write_cmd(axdev, AX_PTP_TOD_CTRL,
+			   (AX_PTP_TS_INT | AX_EXT_INT), 0, 1, &reg8);
+	if (ret < 0)
+		return ret;
+
+	reg32 = 0;
+	ret = ax_write_cmd(axdev, AX_PBUS_A32, AX_MAC_CLK_CTRL,
+			   AX_PBUS_REG_BASE_ADDR_HI, 4, &reg32);
+	if (ret < 0)
+		return ret;
+
+	reg32 = (0 << AX_DIVIDE_PTP_CLK_SHIFT) |
+		(1 << AX_DIVIDE_AES_CLK_SHIFT) |
+		AX_PTP_CLK_EN | AX_AES_CLK_EN |
+		AX_PTP_CLK_SELECT_DIVIDE | AX_AES_CLK_SELECT_DIVIDE |
+		AX_XGMAC_TX_CLK_EN | AX_XGMAC_RX_CLK_EN;
+	ret = ax_write_cmd(axdev, AX_PBUS_A32, AX_MAC_CLK_CTRL,
+			   AX_PBUS_REG_BASE_ADDR_HI, 4, &reg32);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+void ax88279_ptp_remove(struct ax_device *axdev)
+{
+	u32 reg32 = 0;
+#ifdef ENABLE_PTP_FUNC
+	axdev->driver_info->ptp_pps_ctrl(axdev, 0);
+#endif
+	ax_ptp_pbus_write(axdev, AX_PTP_LCK_CTRL0, 4, &reg32);
+	ax_ptp_pbus_write(axdev, AX_PTP_RX_CTRL0, 4, &reg32);
+	ax_ptp_pbus_write(axdev, AX_PTP_TX_CTRL0, 4, &reg32);
+}
+
+static int ax88279_submit_ts(struct ax_device *axdev);
+static void ax88279_read_ts_callback(struct urb *urb)
+{
+	struct net_device *netdev;
+	struct ax_device *axdev;
+	struct ax_ptp_cfg *ptp_cfg;
+	struct _ax_ptp_info *temp_ptp_info;
+	int i, index;
+
+	axdev = urb->context;
+	if (!axdev)
+		return;
+
+	if (test_bit(AX_UNPLUG, &axdev->flags) ||
+	    !test_bit(AX_ENABLE, &axdev->flags))
+		return;
+
+	netdev = axdev->netdev;
+	if (!netif_carrier_ok(netdev))
+		return;
+
+	usb_mark_last_busy(axdev->udev);
+
+	ptp_cfg = axdev->ptp_cfg;
+
+	if (urb->status < 0) {
+		dev_err(&axdev->intf->dev,
+			"failed get ts (%d)", urb->status);
+		goto out;
+	}
+#ifdef ENABLE_PTP_DEBUG
+	printk("EP4 Valid: 0x%x", ptp_cfg->ep4_buf[AX_PTP_EP4_SIZE - 1]);
+#endif
+	index = (ptp_cfg->ep4_buf[AX_PTP_EP4_SIZE - 1] & AX_TS_SEG_1) ?
+		0 : (AX_PTP_INFO_SIZE * AX_PTP_HW_QUEUE_SIZE);
+#ifdef ENABLE_PTP_DEBUG
+	printk("index: %d", index);
+#endif
+	temp_ptp_info = (struct _ax_ptp_info *)&ptp_cfg->ep4_buf[index];
+	for (i = 0; i < AX_PTP_HW_QUEUE_SIZE; i++) {
+		if (temp_ptp_info[i].status) {
+			ptp_cfg->tx_ptp_info[ptp_cfg->ptp_tail++] =
+							temp_ptp_info[i];
+			if (ptp_cfg->ptp_tail == AX_PTP_QUEUE_SIZE)
+				ptp_cfg->ptp_tail = 0;
+			ptp_cfg->num_items++;
+#ifdef ENABLE_PTP_DEBUG
+printk("### ptp_tail: %ld, ptp_head: %ld, num_items: %ld",
+	ptp_cfg->ptp_tail, ptp_cfg->ptp_head, ptp_cfg->num_items);
+printk("### (%s) - DATA %d -------------###", __func__, i);
+printk("### status: %d", temp_ptp_info[i].status);
+printk("### type: 0x%02x", temp_ptp_info[i].msg_type);
+printk("### s_id: 0x%04x", temp_ptp_info[i].sequence_id);
+printk("### nsec: 0x%08x", temp_ptp_info[i].nsec);
+printk("###  sec: 0x%04x%08x", temp_ptp_info[i].sec_h, temp_ptp_info[i].sec_l);
+printk("### ----------------------------###\n");
+#endif
+		}
+	}
+
+	ax_tx_timestamp(axdev);
+out:
+	ax88279_submit_ts(axdev);
+}
+
+static int ax88279_submit_ts(struct ax_device *axdev)
+{
+	struct ax_ptp_cfg *ptp_cfg = axdev->ptp_cfg;
+	struct urb *urb = ptp_cfg->urb;
+	int ret;
+
+	if (test_bit(AX_UNPLUG, &axdev->flags) ||
+	    !test_bit(AX_ENABLE, &axdev->flags))
+		return 0;
+
+	memset(ptp_cfg->ep4_buf, 0, AX_PTP_EP4_SIZE);
+
+	usb_fill_bulk_urb(urb, axdev->udev,
+			   usb_rcvbulkpipe(axdev->udev, 4),
+			   (void *)ptp_cfg->ep4_buf, AX_PTP_EP4_SIZE,
+			   (usb_complete_t)ax88279_read_ts_callback, axdev);
+
+	ret = usb_submit_urb(urb, GFP_KERNEL);
+	if (ret == -ENODEV)
+		netif_device_detach(axdev->netdev);
+
+	urb->actual_length = 0;
+
+	return ret;
+}
+
+int ax88279_start_get_ts(struct ax_device *axdev)
+{
+	int ret;
+
+	if (axdev->chip_version <= AX_VERSION_AX88179A_772D)
+		return 0;
+
+	ret = ax88279_submit_ts(axdev);
+	if (ret < 0)
+		dev_err(&axdev->intf->dev, "Failed to submit EP4 for TS\n");
+
+	return ret;
+}
+
+void ax88279_stop_get_ts(struct ax_device *axdev)
+{
+	struct ax_ptp_cfg *ptp_cfg = axdev->ptp_cfg;
+
+	if (axdev->chip_version <= AX_VERSION_AX88179A_772D)
+		return;
+
+	if (ptp_cfg->urb)
+		usb_kill_urb(ptp_cfg->urb);
+}
+#endif
+
+int ax_ptp_register(struct ax_device *axdev)
+{
+	struct ax_ptp_cfg *ptp_cfg;
+	int ret;
+
+	ptp_cfg = kzalloc(sizeof(struct ax_ptp_cfg), GFP_KERNEL);
+	if (!ptp_cfg)
+		return -ENOMEM;
+	axdev->ptp_cfg = ptp_cfg;
+
+	switch (axdev->chip_version) {
+#ifdef ENABLE_AX88279
+	case AX_VERSION_AX88279:
+		ptp_cfg->urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (!ptp_cfg->urb)
+			goto fail;
+
+		ptp_cfg->ptp_caps = ax88279_ptp_clock;
+		break;
+#endif
+	case AX_VERSION_AX88179A_772D:
+		if (axdev->sub_version < 3)
+			return 0;
+		ptp_cfg->ptp_caps = ax88179a_772d_ptp_clock;
+		break;
+	default:
+		return 0;
+	};
+
+	ptp_cfg->ptp_clock = ptp_clock_register(&ptp_cfg->ptp_caps,
+						&axdev->udev->dev);
+	if (IS_ERR(ptp_cfg->ptp_clock)) {
+		dev_err(&axdev->intf->dev, "ptp_clock_register failed\n");
+		ret = PTR_ERR(ptp_cfg->ptp_clock);
+		goto fail;
+	}
+
+	ptp_cfg->phc_index = ptp_clock_index(ptp_cfg->ptp_clock);
+	skb_queue_head_init(&axdev->tx_timestamp);
+
+	ptp_cfg->axdev = axdev;
+
+	return 0;
+fail:
+#ifdef ENABLE_AX88279
+	if (ptp_cfg->urb)
+		usb_free_urb(axdev->intr_urb);
+#endif
+	kfree(axdev->ptp_cfg);
+
+	return ret;
+}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/ax_ptp.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/ax_ptp.h
@@ -0,0 +1,242 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*******************************************************************************
+ *     Copyright (c) 2022    ASIX Electronic Corporation    All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+#ifndef __ASIX_PTP_H
+#define __ASIX_PTP_H
+
+#include <linux/ptp_clock_kernel.h>
+#include <linux/net_tstamp.h>
+
+#define AX_MAC_BFM_CTRL		0xC1
+	#define AX_CS_TRAIL_UDPV4_EN		0x40
+	#define AX_CS_TRAIL_UDPV6_EN		0x80
+
+#define EP0_GET_TIMESTAMP_RETRY	10
+
+#define AX_PTP_CMD		0x09
+#define AX_PTP_OP		0x0E
+	#define AX_SET_LOCAL_CLOCK	0x01
+	#define AX_SET_LOCAL_CLOCK_SIZE		0x0A
+	#define AX_GET_LOCAL_CLOCK	0x02
+	#define AX_GET_LOCAL_CLOCK_SIZE		0x0A
+	#define AX_SET_ADDEND		0x03
+	#define AX_SET_ADDEND_SIZE		0x04
+	#define AX_SET_ACTIVE_TIME	0x06
+	#define AX_SET_ACTIVE_TIME_SIZE	0x04
+	#define AX_SET_TX_PHY_DELAY	0x07
+	#define AX_SET_TX_PHY_DELAY_SIZE	0x05
+	#define AX_SET_RX_PHY_DELAY	0x08
+	#define AX_SET_RX_PHY_DELAY_SIZE	AX_SET_TX_PHY_DELAY_SIZE
+#define AX_PTP_TIMESTAMP	0x0A
+#define AX_PTP_CLK		0x13
+#define AX_PTP_TOD_CTRL	0x15
+	#define AX_PTP_TS_INT		0x02
+	#define AX_EXT_INT		0x04
+	#define AX_EXT_INT_ON		0x10
+	#define AX_PTP_TX_TX_INT_EN	0x40
+
+// Ethernet: 14B, IPv4: 20B, UDP: 8B
+#define AX_TX_PTPHDR_OFFSET_L3_IP	42
+// Ethernet: 14B, IPv6: 40B, UDP: 8B
+#define AX_TX_PTPHDR_OFFSET_L3_IPV6	62
+// Ethernet: 14B
+#define AX_TX_PTPHDR_OFFSET_L2	14
+#define AX_ETHTYPE_OFFSET		12
+#define AX_IP_PROTO_OFFSET		9
+#define AX_UDP_PORT_OFFSET		22
+#define AX_PTP_EVENT_PORT_NUM		0x13F
+#define PTP_HDR_SIZE			34
+
+#define AX_PPS_ACTIVE_DEFAULT_TIME	0x1DCD6500
+#define AX_BASE_ADDEND			0xCCCCCCCC
+#define AX_PTP_PERIOD			0xA
+
+#define AX88179A_PTP_CTRL_1		0x00
+	#define AX_PTP_TX_PLUS_DELAY		0x20
+	#define AX_PTP_RX_FILTER_GENERAL_MSG	0x10
+	#define AX_PTP_TX_FILTER_GENERAL_MSG	0x08
+	#define AX_PTP_CTRL_L3_EN		0x02
+	#define AX_PTP_CTRL_EN			0x01
+#define AX88179A_PTP_CTRL_2		0x01
+	#define AX_PTP_CTRL_SET_PERIOD		0x08
+	#define AX_PTP_CTRL_SET_ADDEND		0x04
+	#define AX_PTP_CTRL_GET_CLK		0x02
+	#define AX_PTP_CTRL_SET_CLK		0x01
+#define AX88179A_PTP_TIMER_PERIOD	0x0A
+#define AX88179A_PTP_MEM_SEG_SIZE	0x21
+#define AX88179A_PTP_MEM_SEG_SET	0x22
+#define AX88179A_PTP_MEM_SEG_STATUS	0x23
+	#define AX_PTP_MEM_SEG_MASK		0x01
+	#define AX_PTP_MEM_SEG_0		0
+
+#ifdef ENABLE_AX88279
+#define AX_PTP_REG_BASE_ADDR_HI		0x0012
+#define AX_PTP_TX_MEM_SETTING		0x0000
+	#define AX_PTP_PTP_CPU_EN		0x0001
+	/* TODO:: Change to Product code */
+	#define AX_PTP_MEM_SEG_SIZE_279_4	0x34	// USB 2.0
+	#define AX_PTP_MEM_SEG_SIZE_279_5	0x41
+	#define AX_PTP_MEM_START_ADDR		0x800
+#define AX_PTP_LCK_CTRL0		0x1000
+	#define AX_PTP_LCK_CTRL0_EN		0x0001
+	#define AX_PTP_LCK_CTRL0_80B_NS_EN	0x0002
+	#define AX_PTP_LCK_CTRL0_80B_S_EN	0x0004
+	#define AX_PTP_LCK_CTRL0_48B_EN		0x0008
+	#define AX_PTP_LCK_CTRL0_PPS_EN		0x0010
+	#define AX_PTP_LCK_CTRL0_TX_DEL_VEC	0x0040
+#define AX_PTP_LCK_CTRL1			0x1004
+#define AX_PTP_SET_80B_LCK_VAL0		0x1008
+#define AX_PTP_GET_80B_LCK_VAL0		0x1014
+#define AX_PTP_GET_80B_LCK_VAL1		0x1018
+#define AX_PTP_GET_80B_LCK_VAL2		0x101C
+#define AX_PTP_TIMER_ADDEND			0x1030
+#define AX_PTP_TIMER_PERIOD			0x1034
+#define AX_PTP_TX_DELAY			0x1038
+#define AX_PTP_RX_DELAY			0x103C
+#define AX_PTP_PPS_ACTIVE_TIME		0x1040
+
+#define AX_PTP_RX_CTRL0			0x2000
+	#define AX_PTP_RXC0_EN			0x0001
+	#define AX_PTP_RXC0_XGMII_EN		0x0002
+	#define AX_RXC0_PARSER_L2_EN		0x0010
+	#define AX_RXC0_PARSER_L2_PTP_EN	0x0020
+	#define AX_RXC0_PARSER_IPV4_EN	0x0040
+	#define AX_RXC0_PARSER_IPV6_EN	0x0080
+	#define AX_RXC0_PARSER_VLAN_EN	0x0100
+	#define AX_RXC0_PARSER_PPPOE_EN	0x0200
+	#define AX_RXC0_PARSER_SNAP_EN	0x0400
+	#define AX_RXC0_PARSER_UDP_EN		0x0800
+	#define AX_RXC0_PARSER_UDPV6_EN	0x1000
+	#define AX_RXC0_PARSER_UDP_PTP_EN	0x2000
+	#define AX_RXC0_PARSER_UDPV6_PTP_EN	0x4000
+	#define AX_RXC0_PARSER_EVENT_PORT_EN	0x00010000
+	#define AX_RXC0_VAL_DELAY_CNT_SHIFT	24
+
+#define AX_PTP_RX_CTRL0_DEFAULT	\
+	(AX_PTP_RXC0_EN | AX_RXC0_PARSER_L2_EN | AX_RXC0_PARSER_L2_PTP_EN | \
+	AX_RXC0_PARSER_IPV4_EN | AX_RXC0_PARSER_IPV6_EN | \
+	AX_RXC0_PARSER_VLAN_EN | AX_RXC0_PARSER_PPPOE_EN | \
+	AX_RXC0_PARSER_SNAP_EN | AX_RXC0_PARSER_UDP_EN | \
+	AX_RXC0_PARSER_UDPV6_EN | AX_RXC0_PARSER_UDP_PTP_EN | \
+	AX_RXC0_PARSER_UDPV6_PTP_EN | AX_RXC0_PARSER_EVENT_PORT_EN)
+
+#define AX_PTP_TX_CTRL0			0x3000
+	#define AX_PTP_TXC0_EN			0x0001
+	#define AX_PTP_TXC0_XGMII_EN		0x0002
+	#define AX_TXC0_PARSER_L2_EN		0x0010
+	#define AX_TXC0_PARSER_L2_PTP_EN	0x0020
+	#define AX_TXC0_PARSER_IPV4_EN	0x0040
+	#define AX_TXC0_PARSER_IPV6_EN	0x0080
+	#define AX_TXC0_PARSER_VLAN_EN	0x0100
+	#define AX_TXC0_PARSER_PPPOE_EN	0x0200
+	#define AX_TXC0_PARSER_SNAP_EN	0x0400
+	#define AX_TXC0_PARSER_UDP_EN		0x0800
+	#define AX_TXC0_PARSER_UDPV6_EN	0x1000
+	#define AX_TXC0_PARSER_UDP_PTP_EN	0x2000
+	#define AX_TXC0_PARSER_UDPV6_PTP_EN	0x4000
+	#define AX_TXC0_PARSER_EVENT_PORT_EN	0x00010000
+	#define AX_TXC0_VAL_DELAY_CNT_SHIFT	24
+
+#define AX_PTP_TX_CTRL0_DEFAULT	\
+	(AX_PTP_TXC0_EN | AX_TXC0_PARSER_L2_EN | AX_TXC0_PARSER_L2_PTP_EN | \
+	AX_TXC0_PARSER_IPV4_EN | AX_TXC0_PARSER_IPV6_EN | \
+	AX_TXC0_PARSER_VLAN_EN | AX_TXC0_PARSER_PPPOE_EN | \
+	AX_TXC0_PARSER_SNAP_EN | AX_TXC0_PARSER_UDP_EN | \
+	AX_TXC0_PARSER_UDPV6_EN | AX_TXC0_PARSER_UDP_PTP_EN | \
+	AX_TXC0_PARSER_UDPV6_PTP_EN | AX_TXC0_PARSER_EVENT_PORT_EN)
+#endif
+
+
+struct _ptp_header {
+	u16	message_type		:4,
+		transport_specific	:4,
+		reserved		:4,
+		version_ptp		:4;
+	u16	message_len;
+	u8	domain_num;
+	u8	reserved1;
+	u16	flags;
+	u64	correction_field;
+	u32	reserved2;
+	u8	source_port_id[10];
+	u16	sequence_id;
+	u8	ctrl_field;
+	u8	log_msg_interval;
+} __packed;
+
+struct _179a_ptp_info {
+	u8	reserved	:3,
+		status		:1,
+		msg_type	:4;
+	u8	sequence_id;
+	u32	nsec;
+	u32	sec_l;
+	u16	sec_h;
+} __packed;
+#define AX_179A_PTP_INFO_SEG_SIZE sizeof(struct _179a_ptp_info)
+
+struct _ax_ptp_info {
+	u8	reserved	:3,
+		status		:1,
+		msg_type	:4;
+	u16	sequence_id;
+	u32	nsec;
+	u32	sec_l;
+	u16	sec_h;
+} __packed;
+#define AX_PTP_HW_QUEUE_SIZE	5
+#define AX_PTP_QUEUE_SIZE	AX_PTP_HW_QUEUE_SIZE
+#define AX_PTP_INFO_SIZE	sizeof(struct _ax_ptp_info)
+
+struct _ax_ptp_usb_info {
+	struct _ax_ptp_info ax_ptp_info[AX_PTP_HW_QUEUE_SIZE];
+	struct usb_ctrlrequest req;
+	void *axdev;
+};
+
+struct ax_ptp_cfg {
+	void *axdev;
+	struct ptp_clock_info ptp_caps;
+	struct ptp_clock *ptp_clock;
+	unsigned int phc_index;
+	struct _ax_ptp_info tx_ptp_info[AX_PTP_QUEUE_SIZE];
+	unsigned long ptp_head, ptp_tail, num_items;
+	int get_timestamp_retry;
+#ifdef ENABLE_AX88279
+#define AX_PTP_EP4_SIZE	((2 * AX_PTP_INFO_SIZE * AX_PTP_HW_QUEUE_SIZE) + 1)
+#define AX_TS_SEG_1		1
+#define AX_EP4_INFO_SIZE (AX_PTP_QUEUE_SIZE * AX_PTP_EP4_SIZE)
+	struct urb *urb;
+	unsigned char ep4_buf[AX_PTP_EP4_SIZE];
+	struct _ax_ptp_info ep4_ptp_info[AX_EP4_INFO_SIZE];
+#endif
+};
+
+int ax_ptp_register(struct ax_device *axdev);
+void ax_ptp_unregister(struct ax_device *axdev);
+int ax88179a_ptp_pps_ctrl(struct ax_device *axdev, u8 enable);
+int ax88179a_ptp_init(struct ax_device *axdev);
+void ax88179a_ptp_remove(struct ax_device *axdev);
+#ifdef ENABLE_AX88279
+int ax88279_ptp_pps_ctrl(struct ax_device *axdev, u8 enable);
+int ax88279_ptp_init(struct ax_device *axdev);
+void ax88279_ptp_remove(struct ax_device *axdev);
+int ax88279_start_get_ts(struct ax_device *axdev);
+void ax88279_stop_get_ts(struct ax_device *axdev);
+#endif
+int ax_ptp_ts_read_cmd_async(struct ax_device *axdev);
+void ax_rx_get_timestamp(struct sk_buff *skb, u64 *pkt_hdr);
+#endif /* End of __ASIX_PTP_H */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/asix/ax88179b/axcmd.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/asix/ax88179b/axcmd.c
@@ -0,0 +1,295 @@
+// SPDX-License-Identifier: GPL-2.0
+/*******************************************************************************
+ *     Copyright (c) 2022    ASIX Electronic Corporation    All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <https://www.gnu.org/licenses/>.
+ ******************************************************************************/
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#if NET_INTERFACE == INTERFACE_SCAN
+#include <ifaddrs.h>
+#endif
+#include "ax_ioctl.h"
+
+#define ASIX_IOCTL_VERSION "ASIX Linux Command Tool v1.0.0"
+
+const char help_str1[] =
+"./ioctl help [command]\n"
+"    -- command description\n";
+const char help_str2[] =
+"        [command] - Display usage of specified command\n";
+
+const char usbcommand_str1[] =
+"./axcmd usb [ops] [cmd] [value] [index] [size] [data]\n"
+"    -- ASIX USB Command\n";
+const char usbcommand_str2[] =
+"        [ops]     - 0: Read,  1: Write\n"
+"        [cmd]     - USB Command (0 - 0xFF)\n"
+"        [value]   - USB wvalue (0 - 0xFFFF)\n"
+"        [index]   - USB windex (0 - 0xFFFF)\n"
+"        [size]    - USB wlength (0 - 0xFFFF)\n"
+"        [data]    - Data (0 - 0xFFFFFFFF)\n";
+
+static int help_func(struct ax_command_info *info);
+static int usbcommand_func(struct ax_command_info *info);
+
+struct _command_list asix_cmd_list[] = {
+	{	"help",
+		AX_SIGNATURE,
+		help_func,
+		help_str1,
+		help_str2
+	},
+	{	"usb",
+		AX_USB_COMMAND,
+		usbcommand_func,
+		usbcommand_str1,
+		usbcommand_str2
+	},
+	{NULL},
+};
+
+static void show_usage(void)
+{
+	int i;
+
+	printf("Usage:\n");
+	for (i = 0; asix_cmd_list[i].cmd != NULL; i++)
+		printf("%s\n", asix_cmd_list[i].help_ins);
+}
+
+static unsigned long STR_TO_U32(const char *cp, char **endp,
+				unsigned int base)
+{
+	unsigned long result = 0, value;
+
+	if (*cp == '0') {
+		cp++;
+		if ((*cp == 'x') && isxdigit(cp[1])) {
+			base = 16;
+			cp++;
+		}
+		if (!base)
+			base = 8;
+	}
+
+	if (!base)
+		base = 10;
+
+	while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
+	    ? toupper(*cp) : *cp)-'A'+10) < base) {
+		result = result*base + value;
+		cp++;
+	}
+
+	if (endp)
+		*endp = (char *)cp;
+
+	return result;
+}
+
+static int help_func(struct ax_command_info *info)
+{
+	int i;
+
+	if (info->argv[2] == NULL) {
+		for (i = 0; asix_cmd_list[i].cmd != NULL; i++) {
+			printf("%s%s\n",
+				asix_cmd_list[i].help_ins,
+				asix_cmd_list[i].help_desc);
+		}
+	}
+
+	for (i = 0; asix_cmd_list[i].cmd != NULL; i++) {
+		if (strncmp(info->argv[1],
+			    asix_cmd_list[i].cmd,
+			    strlen(asix_cmd_list[i].cmd)) == 0) {
+			printf("%s%s\n",
+				asix_cmd_list[i].help_ins,
+				asix_cmd_list[i].help_desc);
+			return -FAIL_INVALID_PARAMETER;
+		}
+	}
+
+}
+
+static int usbcommand_func(struct ax_command_info *info)
+{
+	struct ifreq *ifr = (struct ifreq *)info->ifr;
+	struct _ax_ioctl_command ioctl_cmd;
+	struct _ax_usb_command *usb_cmd;
+	int i;
+
+	if (info->argc > 8 || info->argc < 7) {
+		for (i = 0; asix_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], asix_cmd_list[i].cmd,
+				    strlen(asix_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", asix_cmd_list[i].help_ins,
+						 asix_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	usb_cmd = &ioctl_cmd.usb_cmd;
+	memset(usb_cmd, 0, sizeof(*usb_cmd));
+
+	usb_cmd->ops = STR_TO_U32(info->argv[2], NULL, 16);
+	usb_cmd->cmd = STR_TO_U32(info->argv[3], NULL, 16);
+	usb_cmd->value = STR_TO_U32(info->argv[4], NULL, 16);
+	usb_cmd->index = STR_TO_U32(info->argv[5], NULL, 16);
+	usb_cmd->size = STR_TO_U32(info->argv[6], NULL, 16);
+
+	if (usb_cmd->ops > USB_WRITE_OPS) {
+		for (i = 0; asix_cmd_list[i].cmd != NULL; i++) {
+			if (strncmp(info->argv[1], asix_cmd_list[i].cmd,
+				    strlen(asix_cmd_list[i].cmd)) == 0) {
+				printf("%s%s\n", asix_cmd_list[i].help_ins,
+						 asix_cmd_list[i].help_desc);
+				return -FAIL_INVALID_PARAMETER;
+			}
+		}
+	}
+
+	if (usb_cmd->ops == USB_WRITE_OPS)
+		usb_cmd->cmd_data = STR_TO_U32(info->argv[7], NULL, 16);
+
+	ioctl_cmd.ioctl_cmd = info->ioctl_cmd;
+	ioctl_cmd.size = usb_cmd->size;
+	ioctl_cmd.buf = NULL;
+	ioctl_cmd.type = 0;
+	ioctl_cmd.delay = 0;
+
+	ifr->ifr_data = (caddr_t)&ioctl_cmd;
+
+	if (ioctl(info->inet_sock, AX_PRIVATE, ifr) < 0) {
+		perror("ioctl");
+		return -FAIL_IOCTL;
+	}
+
+	if (usb_cmd->ops == USB_READ_OPS) {
+		printf("Read Command: CMD: 0x%02X\n", usb_cmd->cmd);
+		printf("wValue: 0x%04X, wIndex: 0x%04X, wLength: 0x%04X",
+			usb_cmd->value, usb_cmd->index, usb_cmd->size);
+		printf("\nData: 0x%08lX\n", usb_cmd->cmd_data);
+	}
+
+	printf("Command completely\n");
+
+	return SUCCESS;
+}
+
+int main(int argc, char **argv)
+{
+	int inet_sock;
+	struct ifreq ifr;
+	struct ax_command_info info;
+	unsigned char i;
+	unsigned char count = 0;
+	struct _ax_ioctl_command ioctl_cmd;
+#if NET_INTERFACE == INTERFACE_SCAN
+	struct ifaddrs *addrs, *tmp;
+	unsigned char	dev_exist;
+#endif
+
+	if (argc < 2) {
+		show_usage();
+		return 0;
+	}
+
+	inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
+#if NET_INTERFACE == INTERFACE_SCAN
+	getifaddrs(&addrs);
+	tmp = addrs;
+	dev_exist = 0;
+
+	while (tmp) {
+		memset(&ioctl_cmd, 0, sizeof(ioctl_cmd));
+		ioctl_cmd.ioctl_cmd = AX_SIGNATURE;
+		sprintf(ifr.ifr_name, "%s", tmp->ifa_name);
+		ifr.ifr_data = (caddr_t)&ioctl_cmd;
+		tmp = tmp->ifa_next;
+
+		if (ioctl(inet_sock, AX_PRIVATE, &ifr) < 0)
+			continue;
+
+		if (strncmp(ioctl_cmd.sig, AX88179_DRV_NAME,
+			    strlen(AX88179_DRV_NAME)) == 0) {
+			dev_exist = 1;
+			break;
+		}
+
+		if (strncmp(ioctl_cmd.sig, AX88179A_DRV_NAME,
+			    strlen(AX88179A_DRV_NAME)) == 0) {
+			dev_exist = 1;
+			break;
+		}
+	}
+
+	freeifaddrs(addrs);
+
+	if (dev_exist == 0) {
+		printf("No ASIX device found\n");
+		return 0;
+	}
+#else
+	for (i = 0; i < 255; i++) {
+
+		memset(&ioctl_cmd, 0, sizeof(ioctl_cmd));
+		ioctl_cmd.ioctl_cmd = AX_SIGNATURE;
+
+		sprintf(ifr.ifr_name, "eth%d", i);
+
+		ifr.ifr_data = (caddr_t)&ioctl_cmd;
+
+		if (ioctl(inet_sock, AX_PRIVATE, &ifr) < 0)
+			continue;
+
+		if (strncmp(ioctl_cmd.sig, AX88179_DRV_NAME,
+			    strlen(AX88179_DRV_NAME)) == 0)
+			break;
+
+		if (strncmp(ioctl_cmd.sig, AX88179A_DRV_NAME,
+			    strlen(AX88179A_DRV_NAME)) == 0)
+			break;
+	}
+
+	if (i == 255) {
+		printf("No ASIX device found\n");
+		return 0;
+	}
+#endif
+	for (i = 0; asix_cmd_list[i].cmd != NULL; i++) {
+		if (strncmp(argv[1], asix_cmd_list[i].cmd,
+			    strlen(asix_cmd_list[i].cmd)) == 0) {
+			info.help_ins = asix_cmd_list[i].help_ins;
+			info.help_desc = asix_cmd_list[i].help_desc;
+			info.ifr = &ifr;
+			info.argc = argc;
+			info.argv = argv;
+			info.inet_sock = inet_sock;
+			info.ioctl_cmd = asix_cmd_list[i].ioctl_cmd;
+			(asix_cmd_list[i].OptFunc)(&info);
+			return 0;
+		}
+	}
+
+	printf("Wrong command\n");
+
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/asp2/bcmasp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/asp2/bcmasp.c
@@ -1306,6 +1306,7 @@
 			dev_err(dev, "Cannot create eth interface %d\n", i);
 			bcmasp_remove_intfs(priv);
 			of_node_put(intf_node);
+			ret = -ENOMEM;
 			goto of_put_exit;
 		}
 		list_add_tail(&intf->list, &priv->intfs);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
@@ -322,6 +322,7 @@
 			}
 			/* Rewind so we do not have a hole */
 			spb_index = intf->tx_spb_index;
+			dev_kfree_skb(skb);
 			return NETDEV_TX_OK;
 		}
 
@@ -391,7 +392,9 @@
 	umac_wl(intf, 0x0, UMC_CMD);
 	umac_wl(intf, UMC_CMD_SW_RESET, UMC_CMD);
 	usleep_range(10, 100);
-	umac_wl(intf, 0x0, UMC_CMD);
+	/* We hold the umac in reset and bring it out of
+	 * reset when phy link is up.
+	 */
 }
 
 static void umac_set_hw_addr(struct bcmasp_intf *intf,
@@ -411,6 +414,8 @@
 	u32 reg;
 
 	reg = umac_rl(intf, UMC_CMD);
+	if (reg & UMC_CMD_SW_RESET)
+		return;
 	if (enable)
 		reg |= mask;
 	else
@@ -429,13 +434,10 @@
 	umac_wl(intf, 0x800, UMC_FRM_LEN);
 	umac_wl(intf, 0xffff, UMC_PAUSE_CNTRL);
 	umac_wl(intf, 0x800, UMC_RX_MAX_PKT_SZ);
-	umac_enable_set(intf, UMC_CMD_PROMISC, 1);
 }
 
-static int bcmasp_tx_poll(struct napi_struct *napi, int budget)
+static int bcmasp_tx_reclaim(struct bcmasp_intf *intf)
 {
-	struct bcmasp_intf *intf =
-		container_of(napi, struct bcmasp_intf, tx_napi);
 	struct bcmasp_intf_stats64 *stats = &intf->stats64;
 	struct device *kdev = &intf->parent->pdev->dev;
 	unsigned long read, released = 0;
@@ -478,10 +480,16 @@
 							DESC_RING_COUNT);
 	}
 
-	/* Ensure all descriptors have been written to DRAM for the hardware
-	 * to see updated contents.
-	 */
-	wmb();
+	return released;
+}
+
+static int bcmasp_tx_poll(struct napi_struct *napi, int budget)
+{
+	struct bcmasp_intf *intf =
+		container_of(napi, struct bcmasp_intf, tx_napi);
+	int released = 0;
+
+	released = bcmasp_tx_reclaim(intf);
 
 	napi_complete(&intf->tx_napi);
 
@@ -656,6 +664,12 @@
 			UMC_CMD_HD_EN | UMC_CMD_RX_PAUSE_IGNORE |
 			UMC_CMD_TX_PAUSE_IGNORE);
 		reg |= cmd_bits;
+		if (reg & UMC_CMD_SW_RESET) {
+			reg &= ~UMC_CMD_SW_RESET;
+			umac_wl(intf, reg, UMC_CMD);
+			udelay(2);
+			reg |= UMC_CMD_TX_EN | UMC_CMD_RX_EN | UMC_CMD_PROMISC;
+		}
 		umac_wl(intf, reg, UMC_CMD);
 
 		intf->eee.eee_active = phy_init_eee(phydev, 0) >= 0;
@@ -787,6 +801,7 @@
 
 	intf->tx_spb_index = 0;
 	intf->tx_spb_clean_index = 0;
+	memset(intf->tx_cbs, 0, sizeof(struct bcmasp_tx_cb) * DESC_RING_COUNT);
 
 	netif_napi_add_tx(intf->ndev, &intf->tx_napi, bcmasp_tx_poll);
 
@@ -897,6 +912,8 @@
 	} while (timeout-- > 0);
 	tx_spb_dma_wl(intf, 0x0, TX_SPB_DMA_FIFO_CTRL);
 
+	bcmasp_tx_reclaim(intf);
+
 	umac_enable_set(intf, UMC_CMD_TX_EN, 0);
 
 	phy_stop(dev->phydev);
@@ -1063,9 +1080,6 @@
 
 	umac_init(intf);
 
-	/* Disable the UniMAC RX/TX */
-	umac_enable_set(intf, (UMC_CMD_RX_EN | UMC_CMD_TX_EN), 0);
-
 	umac_set_hw_addr(intf, dev->dev_addr);
 
 	intf->old_duplex = -1;
@@ -1085,9 +1099,6 @@
 
 	bcmasp_enable_rx(intf, 1);
 
-	/* Turn on UniMAC TX/RX */
-	umac_enable_set(intf, (UMC_CMD_RX_EN | UMC_CMD_TX_EN), 1);
-
 	intf->crc_fwd = !!(umac_rl(intf, UMC_CMD) & UMC_CMD_CRC_FWD);
 
 	bcmasp_netif_start(dev);
@@ -1324,7 +1335,14 @@
 	if (intf->wolopts & WAKE_FILTER)
 		bcmasp_netfilt_suspend(intf);
 
-	/* UniMAC receive needs to be turned on */
+	/* Bring UniMAC out of reset if needed and enable RX */
+	reg = umac_rl(intf, UMC_CMD);
+	if (reg & UMC_CMD_SW_RESET)
+		reg &= ~UMC_CMD_SW_RESET;
+
+	reg |= UMC_CMD_RX_EN | UMC_CMD_PROMISC;
+	umac_wl(intf, reg, UMC_CMD);
+
 	umac_enable_set(intf, UMC_CMD_RX_EN, 1);
 
 	if (intf->parent->wol_irq > 0) {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/b44.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/b44.c
@@ -2009,12 +2009,14 @@
 		bp->flags |= B44_FLAG_TX_PAUSE;
 	else
 		bp->flags &= ~B44_FLAG_TX_PAUSE;
-	if (bp->flags & B44_FLAG_PAUSE_AUTO) {
-		b44_halt(bp);
-		b44_init_rings(bp);
-		b44_init_hw(bp, B44_FULL_RESET);
-	} else {
-		__b44_set_flow_ctrl(bp, bp->flags);
+	if (netif_running(dev)) {
+		if (bp->flags & B44_FLAG_PAUSE_AUTO) {
+			b44_halt(bp);
+			b44_init_rings(bp);
+			b44_init_hw(bp, B44_FULL_RESET);
+		} else {
+			__b44_set_flow_ctrl(bp, bp->flags);
+		}
 	}
 	spin_unlock_irq(&bp->lock);
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bcmsysport.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -1359,6 +1359,7 @@
 		netif_err(priv, tx_err, dev, "DMA map failed at %p (len=%d)\n",
 			  skb->data, skb_len);
 		ret = NETDEV_TX_OK;
+		dev_kfree_skb_any(skb);
 		goto out;
 	}
 
@@ -1966,7 +1967,11 @@
 	unsigned int i;
 	int ret;
 
-	clk_prepare_enable(priv->clk);
+	ret = clk_prepare_enable(priv->clk);
+	if (ret) {
+		netdev_err(dev, "could not enable priv clock\n");
+		return ret;
+	}
 
 	/* Reset UniMAC */
 	umac_reset(priv);
@@ -2624,7 +2629,11 @@
 		goto err_deregister_notifier;
 	}
 
-	clk_prepare_enable(priv->clk);
+	ret = clk_prepare_enable(priv->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "could not enable priv clock\n");
+		goto err_deregister_netdev;
+	}
 
 	priv->rev = topctrl_readl(priv, REV_CNTL) & REV_MASK;
 	dev_info(&pdev->dev,
@@ -2638,6 +2647,8 @@
 
 	return 0;
 
+err_deregister_netdev:
+	unregister_netdev(dev);
 err_deregister_notifier:
 	unregister_netdevice_notifier(&priv->netdev_notifier);
 err_deregister_fixed_link:
@@ -2807,7 +2818,12 @@
 	if (!netif_running(dev))
 		return 0;
 
-	clk_prepare_enable(priv->clk);
+	ret = clk_prepare_enable(priv->clk);
+	if (ret) {
+		netdev_err(dev, "could not enable priv clock\n");
+		return ret;
+	}
+
 	if (priv->wolopts)
 		clk_disable_unprepare(priv->wol_clk);
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bgmac-platform.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bgmac-platform.c
@@ -171,6 +171,7 @@
 static int bgmac_probe(struct platform_device *pdev)
 {
 	struct device_node *np = pdev->dev.of_node;
+	struct device_node *phy_node;
 	struct bgmac *bgmac;
 	struct resource *regs;
 	int ret;
@@ -236,7 +237,9 @@
 	bgmac->cco_ctl_maskset = platform_bgmac_cco_ctl_maskset;
 	bgmac->get_bus_clock = platform_bgmac_get_bus_clock;
 	bgmac->cmn_maskset32 = platform_bgmac_cmn_maskset32;
-	if (of_parse_phandle(np, "phy-handle", 0)) {
+	phy_node = of_parse_phandle(np, "phy-handle", 0);
+	if (phy_node) {
+		of_node_put(phy_node);
 		bgmac->phy_connect = platform_phy_connect;
 	} else {
 		bgmac->phy_connect = bgmac_phy_connect_direct;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bgmac.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bgmac.h
@@ -328,8 +328,7 @@
 #define BGMAC_RX_FRAME_OFFSET			30		/* There are 2 unused bytes between header and real data */
 #define BGMAC_RX_BUF_OFFSET			(NET_SKB_PAD + NET_IP_ALIGN - \
 						 BGMAC_RX_FRAME_OFFSET)
-/* Jumbo frame size with FCS */
-#define BGMAC_RX_MAX_FRAME_SIZE			9724
+#define BGMAC_RX_MAX_FRAME_SIZE			1536
 #define BGMAC_RX_BUF_SIZE			(BGMAC_RX_FRAME_OFFSET + BGMAC_RX_MAX_FRAME_SIZE)
 #define BGMAC_RX_ALLOC_SIZE			(SKB_DATA_ALIGN(BGMAC_RX_BUF_SIZE + BGMAC_RX_BUF_OFFSET) + \
 						 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1262,7 +1262,7 @@
 
 struct bnx2x_fw_stats_req {
 	struct stats_query_header hdr;
-	struct stats_query_entry query[FP_SB_MAX_E1x+
+	struct stats_query_entry query[FP_SB_MAX_E2 +
 		BNX2X_FIRST_QUEUE_QUERY_IDX];
 };
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -147,10 +147,11 @@
 
 		phy_fw_ver[0] = '\0';
 		bnx2x_get_ext_phy_fw_version(&bp->link_params,
-					     phy_fw_ver, PHY_FW_VER_LEN);
-		strscpy(buf, bp->fw_ver, buf_len);
-		snprintf(buf + strlen(bp->fw_ver), 32 - strlen(bp->fw_ver),
-			 "bc %d.%d.%d%s%s",
+					     phy_fw_ver, sizeof(phy_fw_ver));
+		/* This may become truncated. */
+		scnprintf(buf, buf_len,
+			 "%sbc %d.%d.%d%s%s",
+			 bp->fw_ver,
 			 (bp->common.bc_ver & 0xff0000) >> 16,
 			 (bp->common.bc_ver & 0xff00) >> 8,
 			 (bp->common.bc_ver & 0xff),
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -1002,9 +1002,6 @@
 static inline void bnx2x_free_rx_mem_pool(struct bnx2x *bp,
 					  struct bnx2x_alloc_pool *pool)
 {
-	if (!pool->page)
-		return;
-
 	put_page(pool->page);
 
 	pool->page = NULL;
@@ -1015,6 +1012,9 @@
 {
 	int i;
 
+	if (!fp->page_pool.page)
+		return;
+
 	if (fp->mode == TPA_MODE_DISABLED)
 		return;
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -1132,7 +1132,7 @@
 	}
 
 	memset(version, 0, sizeof(version));
-	bnx2x_fill_fw_str(bp, version, ETHTOOL_FWVERS_LEN);
+	bnx2x_fill_fw_str(bp, version, sizeof(version));
 	strlcat(info->fw_version, version, sizeof(info->fw_version));
 
 	strscpy(info->bus_info, pci_name(bp->pdev), sizeof(info->bus_info));
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -6163,8 +6163,8 @@
 
 static int bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
 {
-	str[0] = '\0';
-	(*len)--;
+	if (*len)
+		str[0] = '\0';
 	return 0;
 }
 
@@ -6173,7 +6173,7 @@
 	u16 ret;
 
 	if (*len < 10) {
-		/* Need more than 10chars for this format */
+		/* Need more than 10 chars for this format */
 		bnx2x_null_format_ver(num, str, len);
 		return -EINVAL;
 	}
@@ -6188,8 +6188,8 @@
 {
 	u16 ret;
 
-	if (*len < 10) {
-		/* Need more than 10chars for this format */
+	if (*len < 9) {
+		/* Need more than 9 chars for this format */
 		bnx2x_null_format_ver(num, str, len);
 		return -EINVAL;
 	}
@@ -6208,7 +6208,7 @@
 	int status = 0;
 	u8 *ver_p = version;
 	u16 remain_len = len;
-	if (version == NULL || params == NULL)
+	if (version == NULL || params == NULL || len == 0)
 		return -EINVAL;
 	bp = params->bp;
 
@@ -11546,7 +11546,7 @@
 	str[2] = (spirom_ver & 0xFF0000) >> 16;
 	str[3] = (spirom_ver & 0xFF000000) >> 24;
 	str[4] = '\0';
-	*len -= 5;
+	*len -= 4;
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -687,9 +687,6 @@
 	return NETDEV_TX_OK;
 
 tx_dma_error:
-	if (BNXT_TX_PTP_IS_SET(lflags))
-		atomic_inc(&bp->ptp_cfg->tx_avail);
-
 	last_frag = i;
 
 	/* start back at beginning and unmap skb */
@@ -711,6 +708,8 @@
 tx_free:
 	dev_kfree_skb_any(skb);
 tx_kick_pending:
+	if (BNXT_TX_PTP_IS_SET(lflags))
+		atomic_inc(&bp->ptp_cfg->tx_avail);
 	if (txr->kick_pending)
 		bnxt_txr_db_kick(bp, txr, txr->tx_prod);
 	txr->tx_buf_ring[txr->tx_prod].skb = NULL;
@@ -1420,7 +1419,7 @@
 		if (TPA_START_IS_IPV6(tpa_start1))
 			tpa_info->gso_type = SKB_GSO_TCPV6;
 		/* RSS profiles 1 and 3 with extract code 0 for inner 4-tuple */
-		else if (cmp_type == CMP_TYPE_RX_L2_TPA_START_CMP &&
+		else if (!BNXT_CHIP_P4_PLUS(bp) &&
 			 TPA_START_HASH_TYPE(tpa_start) == 3)
 			tpa_info->gso_type = SKB_GSO_TCPV6;
 		tpa_info->rss_hash =
@@ -1735,7 +1734,7 @@
 		skb = bnxt_copy_skb(bnapi, data_ptr, len, mapping);
 		if (!skb) {
 			bnxt_abort_tpa(cpr, idx, agg_bufs);
-			cpr->sw_stats.rx.rx_oom_discards += 1;
+			cpr->bnapi->cp_ring.sw_stats.rx.rx_oom_discards += 1;
 			return NULL;
 		}
 	} else {
@@ -1745,7 +1744,7 @@
 		new_data = __bnxt_alloc_rx_frag(bp, &new_mapping, GFP_ATOMIC);
 		if (!new_data) {
 			bnxt_abort_tpa(cpr, idx, agg_bufs);
-			cpr->sw_stats.rx.rx_oom_discards += 1;
+			cpr->bnapi->cp_ring.sw_stats.rx.rx_oom_discards += 1;
 			return NULL;
 		}
 
@@ -1761,7 +1760,7 @@
 		if (!skb) {
 			skb_free_frag(data);
 			bnxt_abort_tpa(cpr, idx, agg_bufs);
-			cpr->sw_stats.rx.rx_oom_discards += 1;
+			cpr->bnapi->cp_ring.sw_stats.rx.rx_oom_discards += 1;
 			return NULL;
 		}
 		skb_reserve(skb, bp->rx_offset);
@@ -1772,7 +1771,7 @@
 		skb = bnxt_rx_agg_pages_skb(bp, cpr, skb, idx, agg_bufs, true);
 		if (!skb) {
 			/* Page reuse already handled by bnxt_rx_pages(). */
-			cpr->sw_stats.rx.rx_oom_discards += 1;
+			cpr->bnapi->cp_ring.sw_stats.rx.rx_oom_discards += 1;
 			return NULL;
 		}
 	}
@@ -2051,11 +2050,8 @@
 			u32 frag_len = bnxt_rx_agg_pages_xdp(bp, cpr, &xdp,
 							     cp_cons, agg_bufs,
 							     false);
-			if (!frag_len) {
-				cpr->sw_stats.rx.rx_oom_discards += 1;
-				rc = -ENOMEM;
-				goto next_rx;
-			}
+			if (!frag_len)
+				goto oom_next_rx;
 		}
 		xdp_active = true;
 	}
@@ -2078,9 +2074,7 @@
 				else
 					bnxt_xdp_buff_frags_free(rxr, &xdp);
 			}
-			cpr->sw_stats.rx.rx_oom_discards += 1;
-			rc = -ENOMEM;
-			goto next_rx;
+			goto oom_next_rx;
 		}
 	} else {
 		u32 payload;
@@ -2091,29 +2085,21 @@
 			payload = 0;
 		skb = bp->rx_skb_func(bp, rxr, cons, data, data_ptr, dma_addr,
 				      payload | len);
-		if (!skb) {
-			cpr->sw_stats.rx.rx_oom_discards += 1;
-			rc = -ENOMEM;
-			goto next_rx;
-		}
+		if (!skb)
+			goto oom_next_rx;
 	}
 
 	if (agg_bufs) {
 		if (!xdp_active) {
 			skb = bnxt_rx_agg_pages_skb(bp, cpr, skb, cp_cons, agg_bufs, false);
-			if (!skb) {
-				cpr->sw_stats.rx.rx_oom_discards += 1;
-				rc = -ENOMEM;
-				goto next_rx;
-			}
+			if (!skb)
+				goto oom_next_rx;
 		} else {
 			skb = bnxt_xdp_build_skb(bp, skb, agg_bufs, rxr->page_pool, &xdp, rxcmp1);
 			if (!skb) {
 				/* we should be able to free the old skb here */
 				bnxt_xdp_buff_frags_free(rxr, &xdp);
-				cpr->sw_stats.rx.rx_oom_discards += 1;
-				rc = -ENOMEM;
-				goto next_rx;
+				goto oom_next_rx;
 			}
 		}
 	}
@@ -2124,15 +2110,13 @@
 		if (cmp_type == CMP_TYPE_RX_L2_V3_CMP) {
 			type = bnxt_rss_ext_op(bp, rxcmp);
 		} else {
-			u32 hash_type = RX_CMP_HASH_TYPE(rxcmp);
+			u32 itypes = RX_CMP_ITYPES(rxcmp);
 
-			/* RSS profiles 1 and 3 with extract code 0 for inner
-			 * 4-tuple
-			 */
-			if (hash_type != 1 && hash_type != 3)
-				type = PKT_HASH_TYPE_L3;
-			else
+			if (itypes == RX_CMP_FLAGS_ITYPE_TCP ||
+			    itypes == RX_CMP_FLAGS_ITYPE_UDP)
 				type = PKT_HASH_TYPE_L4;
+			else
+				type = PKT_HASH_TYPE_L3;
 		}
 		skb_set_hash(skb, le32_to_cpu(rxcmp->rx_cmp_rss_hash), type);
 	}
@@ -2166,10 +2150,11 @@
 
 			if (!bnxt_get_rx_ts_p5(bp, &ts, cmpl_ts)) {
 				struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+				unsigned long flags;
 
-				spin_lock_bh(&ptp->ptp_lock);
+				spin_lock_irqsave(&ptp->ptp_lock, flags);
 				ns = timecounter_cyc2time(&ptp->tc, ts);
-				spin_unlock_bh(&ptp->ptp_lock);
+				spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 				memset(skb_hwtstamps(skb), 0,
 				       sizeof(*skb_hwtstamps(skb)));
 				skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns);
@@ -2191,6 +2176,11 @@
 	*raw_cons = tmp_raw_cons;
 
 	return rc;
+
+oom_next_rx:
+	cpr->bnapi->cp_ring.sw_stats.rx.rx_oom_discards += 1;
+	rc = -ENOMEM;
+	goto next_rx;
 }
 
 /* In netpoll mode, if we are using a combined completion ring, we need to
@@ -2237,7 +2227,7 @@
 	}
 	rc = bnxt_rx_pkt(bp, cpr, raw_cons, event);
 	if (rc && rc != -EBUSY)
-		cpr->sw_stats.rx.rx_netpoll_discards += 1;
+		cpr->bnapi->cp_ring.sw_stats.rx.rx_netpoll_discards += 1;
 	return rc;
 }
 
@@ -2661,17 +2651,18 @@
 		case ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_FLAGS_PHC_RTC_UPDATE:
 			if (BNXT_PTP_USE_RTC(bp)) {
 				struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+				unsigned long flags;
 				u64 ns;
 
 				if (!ptp)
 					goto async_event_process_exit;
 
-				spin_lock_bh(&ptp->ptp_lock);
+				spin_lock_irqsave(&ptp->ptp_lock, flags);
 				bnxt_ptp_update_current_time(bp);
 				ns = (((u64)BNXT_EVENT_PHC_RTC_UPDATE(data1) <<
 				       BNXT_PHC_BITS) | ptp->current_time);
 				bnxt_ptp_rtc_timecounter_init(ptp, ns);
-				spin_unlock_bh(&ptp->ptp_lock);
+				spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 			}
 			break;
 		}
@@ -4347,12 +4338,12 @@
 /* Changing allocation mode of RX rings.
  * TODO: Update when extending xdp_rxq_info to support allocation modes.
  */
-int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
+static void __bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
 {
 	struct net_device *dev = bp->dev;
 
 	if (page_mode) {
-		bp->flags &= ~BNXT_FLAG_AGG_RINGS;
+		bp->flags &= ~(BNXT_FLAG_AGG_RINGS | BNXT_FLAG_NO_AGG_RINGS);
 		bp->flags |= BNXT_FLAG_RX_PAGE_MODE;
 
 		if (bp->xdp_prog->aux->xdp_has_frags)
@@ -4368,15 +4359,30 @@
 			bp->rx_skb_func = bnxt_rx_page_skb;
 		}
 		bp->rx_dir = DMA_BIDIRECTIONAL;
-		/* Disable LRO or GRO_HW */
-		netdev_update_features(dev);
 	} else {
 		dev->max_mtu = bp->max_mtu;
 		bp->flags &= ~BNXT_FLAG_RX_PAGE_MODE;
 		bp->rx_dir = DMA_FROM_DEVICE;
 		bp->rx_skb_func = bnxt_rx_skb;
 	}
-	return 0;
+}
+
+void bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode)
+{
+	__bnxt_set_rx_skb_mode(bp, page_mode);
+
+	if (!page_mode) {
+		int rx, tx;
+
+		bnxt_get_max_rings(bp, &rx, &tx, true);
+		if (rx > 1) {
+			bp->flags &= ~BNXT_FLAG_NO_AGG_RINGS;
+			bp->dev->hw_features |= NETIF_F_LRO;
+		}
+	}
+
+	/* Update LRO and GRO_HW availability */
+	netdev_update_features(bp->dev);
 }
 
 static void bnxt_free_vnic_attributes(struct bnxt *bp)
@@ -8574,7 +8580,6 @@
 	struct hwrm_port_mac_ptp_qcfg_output *resp;
 	struct hwrm_port_mac_ptp_qcfg_input *req;
 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
-	bool phc_cfg;
 	u8 flags;
 	int rc;
 
@@ -8617,8 +8622,9 @@
 		rc = -ENODEV;
 		goto exit;
 	}
-	phc_cfg = (flags & PORT_MAC_PTP_QCFG_RESP_FLAGS_RTC_CONFIGURED) != 0;
-	rc = bnxt_ptp_init(bp, phc_cfg);
+	ptp->rtc_configured =
+		(flags & PORT_MAC_PTP_QCFG_RESP_FLAGS_RTC_CONFIGURED) != 0;
+	rc = bnxt_ptp_init(bp);
 	if (rc)
 		netdev_warn(bp->dev, "PTP initialization failed.\n");
 exit:
@@ -8906,7 +8912,7 @@
 					     BNXT_FW_HEALTH_WIN_BASE +
 					     BNXT_GRC_REG_CHIP_NUM);
 		}
-		if (!BNXT_CHIP_P5(bp))
+		if (!BNXT_CHIP_P5_PLUS(bp))
 			return;
 
 		status_loc = BNXT_GRC_REG_STATUS_P5 |
@@ -11526,6 +11532,8 @@
 	/* VF-reps may need to be re-opened after the PF is re-opened */
 	if (BNXT_PF(bp))
 		bnxt_vf_reps_open(bp);
+	if (bp->ptp_cfg)
+		atomic_set(&bp->ptp_cfg->tx_avail, BNXT_MAX_TX_TS);
 	bnxt_ptp_init_rtc(bp, true);
 	bnxt_ptp_cfg_tstamp_filters(bp);
 	return 0;
@@ -12774,6 +12782,16 @@
 	bnxt_rtnl_unlock_sp(bp);
 }
 
+static void bnxt_fw_fatal_close(struct bnxt *bp)
+{
+	bnxt_tx_disable(bp);
+	bnxt_disable_napi(bp);
+	bnxt_disable_int_sync(bp);
+	bnxt_free_irq(bp);
+	bnxt_clear_int_mode(bp);
+	pci_disable_device(bp->pdev);
+}
+
 static void bnxt_fw_reset_close(struct bnxt *bp)
 {
 	bnxt_ulp_stop(bp);
@@ -12787,12 +12805,7 @@
 		pci_read_config_word(bp->pdev, PCI_SUBSYSTEM_ID, &val);
 		if (val == 0xffff)
 			bp->fw_reset_min_dsecs = 0;
-		bnxt_tx_disable(bp);
-		bnxt_disable_napi(bp);
-		bnxt_disable_int_sync(bp);
-		bnxt_free_irq(bp);
-		bnxt_clear_int_mode(bp);
-		pci_disable_device(bp->pdev);
+		bnxt_fw_fatal_close(bp);
 	}
 	__bnxt_close_nic(bp, true, false);
 	bnxt_vf_reps_free(bp);
@@ -12835,9 +12848,11 @@
 		return;
 
 	if (ptp) {
-		spin_lock_bh(&ptp->ptp_lock);
+		unsigned long flags;
+
+		spin_lock_irqsave(&ptp->ptp_lock, flags);
 		set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
-		spin_unlock_bh(&ptp->ptp_lock);
+		spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 	} else {
 		set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
 	}
@@ -12900,9 +12915,11 @@
 		int n = 0, tmo;
 
 		if (ptp) {
-			spin_lock_bh(&ptp->ptp_lock);
+			unsigned long flags;
+
+			spin_lock_irqsave(&ptp->ptp_lock, flags);
 			set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
-			spin_unlock_bh(&ptp->ptp_lock);
+			spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 		} else {
 			set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
 		}
@@ -13783,6 +13800,14 @@
 		bnxt_close_nic(bp, true, false);
 
 	dev->mtu = new_mtu;
+
+	/* MTU change may change the AGG ring settings if an XDP multi-buffer
+	 * program is attached.  We need to set the AGG rings settings and
+	 * rx_skb_func accordingly.
+	 */
+	if (READ_ONCE(bp->xdp_prog))
+		bnxt_set_rx_skb_mode(bp, true);
+
 	bnxt_set_ring_params(bp);
 
 	if (netif_running(dev))
@@ -14828,7 +14853,7 @@
 		goto init_err_pci_clean;
 
 	bnxt_init_l2_fltr_tbl(bp);
-	bnxt_set_rx_skb_mode(bp, false);
+	__bnxt_set_rx_skb_mode(bp, false);
 	bnxt_set_tpa_flags(bp);
 	bnxt_set_ring_params(bp);
 	rc = bnxt_set_dflt_rings(bp, true);
@@ -14934,6 +14959,7 @@
 	if (netif_running(dev))
 		dev_close(dev);
 
+	bnxt_ptp_clear(bp);
 	bnxt_clear_int_mode(bp);
 	pci_disable_device(pdev);
 
@@ -14960,6 +14986,7 @@
 		rc = bnxt_close(dev);
 	}
 	bnxt_hwrm_func_drv_unrgtr(bp);
+	bnxt_ptp_clear(bp);
 	pci_disable_device(bp->pdev);
 	bnxt_free_ctx_mem(bp);
 	rtnl_unlock();
@@ -15001,6 +15028,10 @@
 		goto resume_exit;
 	}
 
+	if (bnxt_ptp_init(bp)) {
+		kfree(bp->ptp_cfg);
+		bp->ptp_cfg = NULL;
+	}
 	bnxt_get_wol_settings(bp);
 	if (netif_running(dev)) {
 		rc = bnxt_open(dev);
@@ -15038,6 +15069,7 @@
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct bnxt *bp = netdev_priv(netdev);
+	bool abort = false;
 
 	netdev_info(netdev, "PCI I/O error detected\n");
 
@@ -15046,16 +15078,27 @@
 
 	bnxt_ulp_stop(bp);
 
-	if (state == pci_channel_io_perm_failure) {
+	if (test_and_set_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) {
+		netdev_err(bp->dev, "Firmware reset already in progress\n");
+		abort = true;
+	}
+
+	if (abort || state == pci_channel_io_perm_failure) {
 		rtnl_unlock();
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 
-	if (state == pci_channel_io_frozen)
+	/* Link is not reliable anymore if state is pci_channel_io_frozen
+	 * so we disable bus master to prevent any potential bad DMAs before
+	 * freeing kernel memory.
+	 */
+	if (state == pci_channel_io_frozen) {
 		set_bit(BNXT_STATE_PCI_CHANNEL_IO_FROZEN, &bp->state);
+		bnxt_fw_fatal_close(bp);
+	}
 
 	if (netif_running(netdev))
-		bnxt_close(netdev);
+		__bnxt_close_nic(bp, true, true);
 
 	if (pci_is_enabled(pdev))
 		pci_disable_device(pdev);
@@ -15139,6 +15182,7 @@
 	}
 
 reset_exit:
+	clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
 	bnxt_clear_reservations(bp, true);
 	rtnl_unlock();
 
@@ -15162,8 +15206,12 @@
 	rtnl_lock();
 
 	err = bnxt_hwrm_func_qcaps(bp);
-	if (!err && netif_running(netdev))
-		err = bnxt_open(netdev);
+	if (!err) {
+		if (netif_running(netdev))
+			err = bnxt_open(netdev);
+		else
+			err = bnxt_reserve_rings(bp, true);
+	}
 
 	bnxt_ulp_start(bp, err);
 	if (!err) {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -241,6 +241,9 @@
 	(((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_RSS_HASH_TYPE) >>\
 	  RX_CMP_RSS_HASH_TYPE_SHIFT) & RSS_PROFILE_ID_MASK)
 
+#define RX_CMP_ITYPES(rxcmp)					\
+	(le32_to_cpu((rxcmp)->rx_cmp_len_flags_type) & RX_CMP_FLAGS_ITYPES_MASK)
+
 #define RX_CMP_V3_HASH_TYPE_LEGACY(rxcmp)				\
 	((le32_to_cpu((rxcmp)->rx_cmp_misc_v1) & RX_CMP_V3_RSS_EXT_OP_LEGACY) >>\
 	 RX_CMP_V3_RSS_EXT_OP_LEGACY_SHIFT)
@@ -352,7 +355,7 @@
 	u32 rx_agg_cmp_opaque;
 	__le32 rx_agg_cmp_v;
 	#define RX_AGG_CMP_V					(1 << 0)
-	#define RX_AGG_CMP_AGG_ID				(0xffff << 16)
+	#define RX_AGG_CMP_AGG_ID				(0x0fff << 16)
 	 #define RX_AGG_CMP_AGG_ID_SHIFT			 16
 	__le32 rx_agg_cmp_unused;
 };
@@ -390,7 +393,7 @@
 	 #define RX_TPA_START_CMP_V3_RSS_HASH_TYPE_SHIFT	 7
 	#define RX_TPA_START_CMP_AGG_ID				(0x7f << 25)
 	 #define RX_TPA_START_CMP_AGG_ID_SHIFT			 25
-	#define RX_TPA_START_CMP_AGG_ID_P5			(0xffff << 16)
+	#define RX_TPA_START_CMP_AGG_ID_P5			(0x0fff << 16)
 	 #define RX_TPA_START_CMP_AGG_ID_SHIFT_P5		 16
 	#define RX_TPA_START_CMP_METADATA1			(0xf << 28)
 	 #define RX_TPA_START_CMP_METADATA1_SHIFT		 28
@@ -514,7 +517,7 @@
 	 #define RX_TPA_END_CMP_PAYLOAD_OFFSET_SHIFT		 16
 	#define RX_TPA_END_CMP_AGG_ID				(0x7f << 25)
 	 #define RX_TPA_END_CMP_AGG_ID_SHIFT			 25
-	#define RX_TPA_END_CMP_AGG_ID_P5			(0xffff << 16)
+	#define RX_TPA_END_CMP_AGG_ID_P5			(0x0fff << 16)
 	 #define RX_TPA_END_CMP_AGG_ID_SHIFT_P5			 16
 
 	__le32 rx_tpa_end_cmp_tsdelta;
@@ -1399,6 +1402,57 @@
 	atomic_t		refcnt;
 };
 
+/* Compat version of hwrm_port_phy_qcfg_output capped at 96 bytes.  The
+ * first 95 bytes are identical to hwrm_port_phy_qcfg_output in bnxt_hsi.h.
+ * The last valid byte in the compat version is different.
+ */
+struct hwrm_port_phy_qcfg_output_compat {
+	__le16	error_code;
+	__le16	req_type;
+	__le16	seq_id;
+	__le16	resp_len;
+	u8	link;
+	u8	active_fec_signal_mode;
+	__le16	link_speed;
+	u8	duplex_cfg;
+	u8	pause;
+	__le16	support_speeds;
+	__le16	force_link_speed;
+	u8	auto_mode;
+	u8	auto_pause;
+	__le16	auto_link_speed;
+	__le16	auto_link_speed_mask;
+	u8	wirespeed;
+	u8	lpbk;
+	u8	force_pause;
+	u8	module_status;
+	__le32	preemphasis;
+	u8	phy_maj;
+	u8	phy_min;
+	u8	phy_bld;
+	u8	phy_type;
+	u8	media_type;
+	u8	xcvr_pkg_type;
+	u8	eee_config_phy_addr;
+	u8	parallel_detect;
+	__le16	link_partner_adv_speeds;
+	u8	link_partner_adv_auto_mode;
+	u8	link_partner_adv_pause;
+	__le16	adv_eee_link_speed_mask;
+	__le16	link_partner_adv_eee_link_speed_mask;
+	__le32	xcvr_identifier_type_tx_lpi_timer;
+	__le16	fec_cfg;
+	u8	duplex_state;
+	u8	option_flags;
+	char	phy_vendor_name[16];
+	char	phy_vendor_partnumber[16];
+	__le16	support_pam4_speeds;
+	__le16	force_pam4_link_speed;
+	__le16	auto_pam4_link_speed_mask;
+	u8	link_partner_pam4_adv_speeds;
+	u8	valid;
+};
+
 struct bnxt_link_info {
 	u8			phy_type;
 	u8			media_type;
@@ -2640,7 +2694,7 @@
 u32 bnxt_fw_health_readl(struct bnxt *bp, int reg_idx);
 void bnxt_set_tpa_flags(struct bnxt *bp);
 void bnxt_set_ring_params(struct bnxt *);
-int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
+void bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode);
 int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap,
 			    int bmap_size, bool async_only);
 int bnxt_hwrm_func_drv_unrgtr(struct bnxt *bp);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -2482,19 +2482,24 @@
 	}
 
 	base->port = PORT_NONE;
-	if (link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_TP) {
+	if (media == BNXT_MEDIA_TP) {
 		base->port = PORT_TP;
 		linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
 				 lk_ksettings->link_modes.supported);
 		linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT,
 				 lk_ksettings->link_modes.advertising);
+	} else if (media == BNXT_MEDIA_KR) {
+		linkmode_set_bit(ETHTOOL_LINK_MODE_Backplane_BIT,
+				 lk_ksettings->link_modes.supported);
+		linkmode_set_bit(ETHTOOL_LINK_MODE_Backplane_BIT,
+				 lk_ksettings->link_modes.advertising);
 	} else {
 		linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
 				 lk_ksettings->link_modes.supported);
 		linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
 				 lk_ksettings->link_modes.advertising);
 
-		if (link_info->media_type == PORT_PHY_QCFG_RESP_MEDIA_TYPE_DAC)
+		if (media == BNXT_MEDIA_CR)
 			base->port = PORT_DA;
 		else
 			base->port = PORT_FIBRE;
@@ -3803,7 +3808,7 @@
 
 	if (!bnxt_get_pkginfo(dev, buf, sizeof(buf))) {
 		len = strlen(bp->fw_ver_str);
-		snprintf(bp->fw_ver_str + len, FW_VER_STR_LEN - len - 1,
+		snprintf(bp->fw_ver_str + len, FW_VER_STR_LEN - len,
 			 "/pkg %s", buf);
 	}
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c
@@ -680,7 +680,7 @@
 			    req_type);
 	else if (rc && rc != HWRM_ERR_CODE_PF_UNAVAILABLE)
 		hwrm_err(bp, ctx, "hwrm req_type 0x%x seq id 0x%x error 0x%x\n",
-			 req_type, token->seq_id, rc);
+			 req_type, le16_to_cpu(ctx->req->seq_id), rc);
 	rc = __hwrm_to_stderr(rc);
 exit:
 	if (token)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
@@ -62,13 +62,14 @@
 	struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
 						ptp_info);
 	u64 ns = timespec64_to_ns(ts);
+	unsigned long flags;
 
 	if (BNXT_PTP_USE_RTC(ptp->bp))
 		return bnxt_ptp_cfg_settime(ptp->bp, ns);
 
-	spin_lock_bh(&ptp->ptp_lock);
+	spin_lock_irqsave(&ptp->ptp_lock, flags);
 	timecounter_init(&ptp->tc, &ptp->cc, ns);
-	spin_unlock_bh(&ptp->ptp_lock);
+	spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 	return 0;
 }
 
@@ -100,13 +101,14 @@
 static void bnxt_ptp_get_current_time(struct bnxt *bp)
 {
 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+	unsigned long flags;
 
 	if (!ptp)
 		return;
-	spin_lock_bh(&ptp->ptp_lock);
+	spin_lock_irqsave(&ptp->ptp_lock, flags);
 	WRITE_ONCE(ptp->old_time, ptp->current_time);
 	bnxt_refclk_read(bp, NULL, &ptp->current_time);
-	spin_unlock_bh(&ptp->ptp_lock);
+	spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 }
 
 static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts)
@@ -142,17 +144,18 @@
 {
 	struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
 						ptp_info);
+	unsigned long flags;
 	u64 ns, cycles;
 	int rc;
 
-	spin_lock_bh(&ptp->ptp_lock);
+	spin_lock_irqsave(&ptp->ptp_lock, flags);
 	rc = bnxt_refclk_read(ptp->bp, sts, &cycles);
 	if (rc) {
-		spin_unlock_bh(&ptp->ptp_lock);
+		spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 		return rc;
 	}
 	ns = timecounter_cyc2time(&ptp->tc, cycles);
-	spin_unlock_bh(&ptp->ptp_lock);
+	spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 	*ts = ns_to_timespec64(ns);
 
 	return 0;
@@ -170,6 +173,7 @@
 static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta)
 {
 	struct hwrm_port_mac_cfg_input *req;
+	unsigned long flags;
 	int rc;
 
 	rc = hwrm_req_init(ptp->bp, req, HWRM_PORT_MAC_CFG);
@@ -183,9 +187,9 @@
 	if (rc) {
 		netdev_err(ptp->bp->dev, "ptp adjphc failed. rc = %x\n", rc);
 	} else {
-		spin_lock_bh(&ptp->ptp_lock);
+		spin_lock_irqsave(&ptp->ptp_lock, flags);
 		bnxt_ptp_update_current_time(ptp->bp);
-		spin_unlock_bh(&ptp->ptp_lock);
+		spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 	}
 
 	return rc;
@@ -195,13 +199,14 @@
 {
 	struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
 						ptp_info);
+	unsigned long flags;
 
 	if (BNXT_PTP_USE_RTC(ptp->bp))
 		return bnxt_ptp_adjphc(ptp, delta);
 
-	spin_lock_bh(&ptp->ptp_lock);
+	spin_lock_irqsave(&ptp->ptp_lock, flags);
 	timecounter_adjtime(&ptp->tc, delta);
-	spin_unlock_bh(&ptp->ptp_lock);
+	spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 	return 0;
 }
 
@@ -229,14 +234,15 @@
 	struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
 						ptp_info);
 	struct bnxt *bp = ptp->bp;
+	unsigned long flags;
 
 	if (!BNXT_MH(bp))
 		return bnxt_ptp_adjfine_rtc(bp, scaled_ppm);
 
-	spin_lock_bh(&ptp->ptp_lock);
+	spin_lock_irqsave(&ptp->ptp_lock, flags);
 	timecounter_read(&ptp->tc);
 	ptp->cc.mult = adjust_by_scaled_ppm(ptp->cmult, scaled_ppm);
-	spin_unlock_bh(&ptp->ptp_lock);
+	spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 	return 0;
 }
 
@@ -244,12 +250,13 @@
 {
 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
 	struct ptp_clock_event event;
+	unsigned long flags;
 	u64 ns, pps_ts;
 
 	pps_ts = EVENT_PPS_TS(data2, data1);
-	spin_lock_bh(&ptp->ptp_lock);
+	spin_lock_irqsave(&ptp->ptp_lock, flags);
 	ns = timecounter_cyc2time(&ptp->tc, pps_ts);
-	spin_unlock_bh(&ptp->ptp_lock);
+	spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 
 	switch (EVENT_DATA2_PPS_EVENT_TYPE(data2)) {
 	case ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_EVENT_TYPE_INTERNAL:
@@ -386,16 +393,17 @@
 {
 	u64 cycles_now;
 	u64 nsec_now, nsec_delta;
+	unsigned long flags;
 	int rc;
 
-	spin_lock_bh(&ptp->ptp_lock);
+	spin_lock_irqsave(&ptp->ptp_lock, flags);
 	rc = bnxt_refclk_read(ptp->bp, NULL, &cycles_now);
 	if (rc) {
-		spin_unlock_bh(&ptp->ptp_lock);
+		spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 		return rc;
 	}
 	nsec_now = timecounter_cyc2time(&ptp->tc, cycles_now);
-	spin_unlock_bh(&ptp->ptp_lock);
+	spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 
 	nsec_delta = target_ns - nsec_now;
 	*cycles_delta = div64_u64(nsec_delta << ptp->cc.shift, ptp->cc.mult);
@@ -672,15 +680,16 @@
 {
 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
 	struct skb_shared_hwtstamps timestamp;
+	unsigned long flags;
 	u64 ts = 0, ns = 0;
 	int rc;
 
 	rc = bnxt_hwrm_port_ts_query(bp, PORT_TS_QUERY_REQ_FLAGS_PATH_TX, &ts);
 	if (!rc) {
 		memset(&timestamp, 0, sizeof(timestamp));
-		spin_lock_bh(&ptp->ptp_lock);
+		spin_lock_irqsave(&ptp->ptp_lock, flags);
 		ns = timecounter_cyc2time(&ptp->tc, ts);
-		spin_unlock_bh(&ptp->ptp_lock);
+		spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 		timestamp.hwtstamp = ns_to_ktime(ns);
 		skb_tstamp_tx(ptp->tx_skb, &timestamp);
 	} else {
@@ -699,6 +708,7 @@
 						ptp_info);
 	unsigned long now = jiffies;
 	struct bnxt *bp = ptp->bp;
+	unsigned long flags;
 
 	if (ptp->tx_skb)
 		bnxt_stamp_tx_skb(bp, ptp->tx_skb);
@@ -709,9 +719,9 @@
 	bnxt_ptp_get_current_time(bp);
 	ptp->next_period = now + HZ;
 	if (time_after_eq(now, ptp->next_overflow_check)) {
-		spin_lock_bh(&ptp->ptp_lock);
+		spin_lock_irqsave(&ptp->ptp_lock, flags);
 		timecounter_read(&ptp->tc);
-		spin_unlock_bh(&ptp->ptp_lock);
+		spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 		ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD;
 	}
 	return HZ;
@@ -878,6 +888,7 @@
 int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg)
 {
 	struct timespec64 tsp;
+	unsigned long flags;
 	u64 ns;
 	int rc;
 
@@ -895,9 +906,9 @@
 		if (rc)
 			return rc;
 	}
-	spin_lock_bh(&bp->ptp_cfg->ptp_lock);
+	spin_lock_irqsave(&bp->ptp_cfg->ptp_lock, flags);
 	bnxt_ptp_rtc_timecounter_init(bp->ptp_cfg, ns);
-	spin_unlock_bh(&bp->ptp_cfg->ptp_lock);
+	spin_unlock_irqrestore(&bp->ptp_cfg->ptp_lock, flags);
 
 	return 0;
 }
@@ -914,7 +925,7 @@
 	}
 }
 
-int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg)
+int bnxt_ptp_init(struct bnxt *bp)
 {
 	struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
 	int rc;
@@ -936,7 +947,7 @@
 
 	if (BNXT_PTP_USE_RTC(bp)) {
 		bnxt_ptp_timecounter_init(bp, false);
-		rc = bnxt_ptp_init_rtc(bp, phc_cfg);
+		rc = bnxt_ptp_init_rtc(bp, ptp->rtc_configured);
 		if (rc)
 			goto out;
 	} else {
@@ -959,10 +970,12 @@
 		goto out;
 	}
 	if (BNXT_CHIP_P5(bp)) {
-		spin_lock_bh(&ptp->ptp_lock);
+		unsigned long flags;
+
+		spin_lock_irqsave(&ptp->ptp_lock, flags);
 		bnxt_refclk_read(bp, NULL, &ptp->current_time);
 		WRITE_ONCE(ptp->old_time, ptp->current_time);
-		spin_unlock_bh(&ptp->ptp_lock);
+		spin_unlock_irqrestore(&ptp->ptp_lock, flags);
 		ptp_schedule_worker(ptp->ptp_clock, 0);
 	}
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h
@@ -115,6 +115,7 @@
 					 BNXT_PTP_MSG_PDELAY_REQ |	\
 					 BNXT_PTP_MSG_PDELAY_RESP)
 	u8			tx_tstamp_en:1;
+	u8			rtc_configured:1;
 	int			rx_filter;
 	u32			tstamp_filters;
 
@@ -123,11 +124,13 @@
 };
 
 #if BITS_PER_LONG == 32
-#define BNXT_READ_TIME64(ptp, dst, src)		\
-do {						\
-	spin_lock_bh(&(ptp)->ptp_lock);		\
-	(dst) = (src);				\
-	spin_unlock_bh(&(ptp)->ptp_lock);	\
+#define BNXT_READ_TIME64(ptp, dst, src)				\
+do {								\
+	unsigned long flags;					\
+								\
+	spin_lock_irqsave(&(ptp)->ptp_lock, flags);		\
+	(dst) = (src);						\
+	spin_unlock_irqrestore(&(ptp)->ptp_lock, flags);	\
 } while (0)
 #else
 #define BNXT_READ_TIME64(ptp, dst, src)		\
@@ -145,6 +148,6 @@
 int bnxt_get_rx_ts_p5(struct bnxt *bp, u64 *ts, u32 pkt_ts);
 void bnxt_ptp_rtc_timecounter_init(struct bnxt_ptp_cfg *ptp, u64 ns);
 int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg);
-int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg);
+int bnxt_ptp_init(struct bnxt *bp);
 void bnxt_ptp_clear(struct bnxt *bp);
 #endif
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
@@ -950,8 +950,11 @@
 	struct hwrm_fwd_resp_input *req;
 	int rc;
 
-	if (BNXT_FWD_RESP_SIZE_ERR(msg_size))
+	if (BNXT_FWD_RESP_SIZE_ERR(msg_size)) {
+		netdev_warn_once(bp->dev, "HWRM fwd response too big (%d bytes)\n",
+				 msg_size);
 		return -EINVAL;
+	}
 
 	rc = hwrm_req_init(bp, req, HWRM_FWD_RESP);
 	if (!rc) {
@@ -1085,7 +1088,7 @@
 		rc = bnxt_hwrm_exec_fwd_resp(
 			bp, vf, sizeof(struct hwrm_port_phy_qcfg_input));
 	} else {
-		struct hwrm_port_phy_qcfg_output phy_qcfg_resp = {0};
+		struct hwrm_port_phy_qcfg_output_compat phy_qcfg_resp = {};
 		struct hwrm_port_phy_qcfg_input *phy_qcfg_req;
 
 		phy_qcfg_req =
@@ -1096,6 +1099,11 @@
 		mutex_unlock(&bp->link_lock);
 		phy_qcfg_resp.resp_len = cpu_to_le16(sizeof(phy_qcfg_resp));
 		phy_qcfg_resp.seq_id = phy_qcfg_req->seq_id;
+		/* New SPEEDS2 fields are beyond the legacy structure, so
+		 * clear the SPEEDS2_SUPPORTED flag.
+		 */
+		phy_qcfg_resp.option_flags &=
+			~PORT_PHY_QCAPS_RESP_FLAGS2_SPEEDS2_SUPPORTED;
 		phy_qcfg_resp.valid = 1;
 
 		if (vf->flags & BNXT_VF_LINK_UP) {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c
@@ -156,7 +156,7 @@
 
 	rc = hwrm_req_replace(bp, req, fw_msg->msg, fw_msg->msg_len);
 	if (rc)
-		return rc;
+		goto drop_req;
 
 	hwrm_req_timeout(bp, req, fw_msg->timeout);
 	resp = hwrm_req_hold(bp, req);
@@ -168,6 +168,7 @@
 
 		memcpy(fw_msg->resp, resp, resp_len);
 	}
+drop_req:
 	hwrm_req_drop(bp, req);
 	return rc;
 }
@@ -210,6 +211,9 @@
 	if (err)
 		return;
 
+	if (edev->ulp_tbl->msix_requested)
+		bnxt_fill_msix_vecs(bp, edev->msix_entries);
+
 	if (aux_priv) {
 		struct auxiliary_device *adev;
 
@@ -392,12 +396,13 @@
 	if (!edev)
 		goto aux_dev_uninit;
 
+	aux_priv->edev = edev;
+
 	ulp = kzalloc(sizeof(*ulp), GFP_KERNEL);
 	if (!ulp)
 		goto aux_dev_uninit;
 
 	edev->ulp_tbl = ulp;
-	aux_priv->edev = edev;
 	bp->edev = edev;
 	bnxt_set_edev_info(edev, bp);
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -297,11 +297,6 @@
 		 * redirect is coming from a frame received by the
 		 * bnxt_en driver.
 		 */
-		rx_buf = &rxr->rx_buf_ring[cons];
-		mapping = rx_buf->mapping - bp->rx_dma_offset;
-		dma_unmap_page_attrs(&pdev->dev, mapping,
-				     BNXT_RX_PAGE_SIZE, bp->rx_dir,
-				     DMA_ATTR_WEAK_ORDERING);
 
 		/* if we are unable to allocate a new buffer, abort and reuse */
 		if (bnxt_alloc_rx_data(bp, rxr, rxr->rx_prod, GFP_ATOMIC)) {
@@ -427,15 +422,8 @@
 		bnxt_set_rx_skb_mode(bp, true);
 		xdp_features_set_redirect_target(dev, true);
 	} else {
-		int rx, tx;
-
 		xdp_features_clear_redirect_target(dev);
 		bnxt_set_rx_skb_mode(bp, false);
-		bnxt_get_max_rings(bp, &rx, &tx, true);
-		if (rx > 1) {
-			bp->flags &= ~BNXT_FLAG_NO_AGG_RINGS;
-			bp->dev->hw_features |= NETIF_F_LRO;
-		}
 	}
 	bp->tx_nr_rings_xdp = tx_xdp;
 	bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tc + tx_xdp;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -2,7 +2,7 @@
 /*
  * Broadcom GENET (Gigabit Ethernet) controller driver
  *
- * Copyright (c) 2014-2020 Broadcom
+ * Copyright (c) 2014-2024 Broadcom
  */
 
 #define pr_fmt(fmt)				"bcmgenet: " fmt
@@ -2469,14 +2469,18 @@
 {
 	u32 reg;
 
+	spin_lock_bh(&priv->reg_lock);
 	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
-	if (reg & CMD_SW_RESET)
+	if (reg & CMD_SW_RESET) {
+		spin_unlock_bh(&priv->reg_lock);
 		return;
+	}
 	if (enable)
 		reg |= mask;
 	else
 		reg &= ~mask;
 	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+	spin_unlock_bh(&priv->reg_lock);
 
 	/* UniMAC stops on a packet boundary, wait for a full-size packet
 	 * to be processed
@@ -2492,8 +2496,10 @@
 	udelay(10);
 
 	/* issue soft reset and disable MAC while updating its registers */
+	spin_lock_bh(&priv->reg_lock);
 	bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD);
 	udelay(2);
+	spin_unlock_bh(&priv->reg_lock);
 }
 
 static void bcmgenet_intr_disable(struct bcmgenet_priv *priv)
@@ -3282,7 +3288,7 @@
 }
 
 /* Returns a reusable dma control register value */
-static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv)
+static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv, bool flush_rx)
 {
 	unsigned int i;
 	u32 reg;
@@ -3307,6 +3313,14 @@
 	udelay(10);
 	bcmgenet_umac_writel(priv, 0, UMAC_TX_FLUSH);
 
+	if (flush_rx) {
+		reg = bcmgenet_rbuf_ctrl_get(priv);
+		bcmgenet_rbuf_ctrl_set(priv, reg | BIT(0));
+		udelay(10);
+		bcmgenet_rbuf_ctrl_set(priv, reg);
+		udelay(10);
+	}
+
 	return dma_ctrl;
 }
 
@@ -3328,7 +3342,9 @@
 	struct bcmgenet_priv *priv = netdev_priv(dev);
 
 	/* Start the network engine */
+	netif_addr_lock_bh(dev);
 	bcmgenet_set_rx_mode(dev);
+	netif_addr_unlock_bh(dev);
 	bcmgenet_enable_rx_napi(priv);
 
 	umac_enable_set(priv, CMD_TX_EN | CMD_RX_EN, true);
@@ -3370,8 +3386,8 @@
 
 	bcmgenet_set_hw_addr(priv, dev->dev_addr);
 
-	/* Disable RX/TX DMA and flush TX queues */
-	dma_ctrl = bcmgenet_dma_disable(priv);
+	/* Disable RX/TX DMA and flush TX and RX queues */
+	dma_ctrl = bcmgenet_dma_disable(priv, true);
 
 	/* Reinitialize TDMA and RDMA and SW housekeeping */
 	ret = bcmgenet_init_dma(priv);
@@ -3589,16 +3605,19 @@
 	 * 3. The number of filters needed exceeds the number filters
 	 *    supported by the hardware.
 	*/
+	spin_lock(&priv->reg_lock);
 	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
 	if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) ||
 	    (nfilter > MAX_MDF_FILTER)) {
 		reg |= CMD_PROMISC;
 		bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+		spin_unlock(&priv->reg_lock);
 		bcmgenet_umac_writel(priv, 0, UMAC_MDF_CTRL);
 		return;
 	} else {
 		reg &= ~CMD_PROMISC;
 		bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+		spin_unlock(&priv->reg_lock);
 	}
 
 	/* update MDF filter */
@@ -3997,6 +4016,7 @@
 		goto err;
 	}
 
+	spin_lock_init(&priv->reg_lock);
 	spin_lock_init(&priv->lock);
 
 	/* Set default pause parameters */
@@ -4237,7 +4257,7 @@
 			bcmgenet_hfb_create_rxnfc_filter(priv, rule);
 
 	/* Disable RX/TX DMA and flush TX queues */
-	dma_ctrl = bcmgenet_dma_disable(priv);
+	dma_ctrl = bcmgenet_dma_disable(priv, false);
 
 	/* Reinitialize TDMA and RDMA and SW housekeeping */
 	ret = bcmgenet_init_dma(priv);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2014-2020 Broadcom
+ * Copyright (c) 2014-2024 Broadcom
  */
 
 #ifndef __BCMGENET_H__
@@ -573,6 +573,8 @@
 /* device context */
 struct bcmgenet_priv {
 	void __iomem *base;
+	/* reg_lock: lock to serialize access to shared registers */
+	spinlock_t reg_lock;
 	enum bcmgenet_version version;
 	struct net_device *dev;
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
@@ -2,7 +2,7 @@
 /*
  * Broadcom GENET (Gigabit Ethernet) Wake-on-LAN support
  *
- * Copyright (c) 2014-2020 Broadcom
+ * Copyright (c) 2014-2024 Broadcom
  */
 
 #define pr_fmt(fmt)				"bcmgenet_wol: " fmt
@@ -41,23 +41,27 @@
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
 	struct device *kdev = &priv->pdev->dev;
+	u32 phy_wolopts = 0;
 
 	if (dev->phydev) {
 		phy_ethtool_get_wol(dev->phydev, wol);
-		if (wol->supported)
-			return;
+		phy_wolopts = wol->wolopts;
 	}
 
-	if (!device_can_wakeup(kdev)) {
-		wol->supported = 0;
-		wol->wolopts = 0;
+	/* MAC is not wake-up capable, return what the PHY does */
+	if (!device_can_wakeup(kdev))
 		return;
-	}
 
-	wol->supported = WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER;
-	wol->wolopts = priv->wolopts;
-	memset(wol->sopass, 0, sizeof(wol->sopass));
+	/* Overlay MAC capabilities with that of the PHY queried before */
+	wol->supported |= WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_FILTER;
+	wol->wolopts |= priv->wolopts;
 
+	/* Return the PHY configured magic password */
+	if (phy_wolopts & WAKE_MAGICSECURE)
+		return;
+
+	/* Otherwise the MAC one */
+	memset(wol->sopass, 0, sizeof(wol->sopass));
 	if (wol->wolopts & WAKE_MAGICSECURE)
 		memcpy(wol->sopass, priv->sopass, sizeof(priv->sopass));
 }
@@ -74,7 +78,7 @@
 	/* Try Wake-on-LAN from the PHY first */
 	if (dev->phydev) {
 		ret = phy_ethtool_set_wol(dev->phydev, wol);
-		if (ret != -EOPNOTSUPP)
+		if (ret != -EOPNOTSUPP && wol->wolopts)
 			return ret;
 	}
 
@@ -151,6 +155,7 @@
 	}
 
 	/* Can't suspend with WoL if MAC is still in reset */
+	spin_lock_bh(&priv->reg_lock);
 	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
 	if (reg & CMD_SW_RESET)
 		reg &= ~CMD_SW_RESET;
@@ -158,6 +163,7 @@
 	/* disable RX */
 	reg &= ~CMD_RX_EN;
 	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+	spin_unlock_bh(&priv->reg_lock);
 	mdelay(10);
 
 	if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
@@ -203,6 +209,7 @@
 	}
 
 	/* Enable CRC forward */
+	spin_lock_bh(&priv->reg_lock);
 	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
 	priv->crc_fwd_en = 1;
 	reg |= CMD_CRC_FWD;
@@ -210,6 +217,7 @@
 	/* Receiver must be enabled for WOL MP detection */
 	reg |= CMD_RX_EN;
 	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+	spin_unlock_bh(&priv->reg_lock);
 
 	reg = UMAC_IRQ_MPD_R;
 	if (hfb_enable)
@@ -256,7 +264,9 @@
 	}
 
 	/* Disable CRC Forward */
+	spin_lock_bh(&priv->reg_lock);
 	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
 	reg &= ~CMD_CRC_FWD;
 	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+	spin_unlock_bh(&priv->reg_lock);
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/genet/bcmmii.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/genet/bcmmii.c
@@ -2,7 +2,7 @@
 /*
  * Broadcom GENET MDIO routines
  *
- * Copyright (c) 2014-2017 Broadcom
+ * Copyright (c) 2014-2024 Broadcom
  */
 
 #include <linux/acpi.h>
@@ -75,6 +75,7 @@
 	reg |= RGMII_LINK;
 	bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
 
+	spin_lock_bh(&priv->reg_lock);
 	reg = bcmgenet_umac_readl(priv, UMAC_CMD);
 	reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) |
 		       CMD_HD_EN |
@@ -87,6 +88,7 @@
 		reg |= CMD_TX_EN | CMD_RX_EN;
 	}
 	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
+	spin_unlock_bh(&priv->reg_lock);
 
 	priv->eee.eee_active = phy_init_eee(phydev, 0) >= 0;
 	bcmgenet_eee_enable_set(dev,
@@ -274,6 +276,7 @@
 	 * block for the interface to work, unconditionally clear the
 	 * Out-of-band disable since we do not need it.
 	 */
+	mutex_lock(&phydev->lock);
 	reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
 	reg &= ~OOB_DISABLE;
 	if (priv->ext_phy) {
@@ -285,6 +288,7 @@
 			reg |= RGMII_MODE_EN;
 	}
 	bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
+	mutex_unlock(&phydev->lock);
 
 	if (init)
 		dev_info(kdev, "configuring instance for %s\n", phy_name);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/broadcom/tg3.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/broadcom/tg3.c
@@ -55,6 +55,7 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/crc32poly.h>
+#include <linux/dmi.h>
 
 #include <net/checksum.h>
 #include <net/gso.h>
@@ -17811,6 +17812,9 @@
 	} else
 		persist_dma_mask = dma_mask = DMA_BIT_MASK(64);
 
+	if (tg3_asic_rev(tp) == ASIC_REV_57766)
+		persist_dma_mask = DMA_BIT_MASK(31);
+
 	/* Configure DMA attributes. */
 	if (dma_mask > DMA_BIT_MASK(32)) {
 		err = dma_set_mask(&pdev->dev, dma_mask);
@@ -18183,6 +18187,50 @@
 
 static SIMPLE_DEV_PM_OPS(tg3_pm_ops, tg3_suspend, tg3_resume);
 
+/* Systems where ACPI _PTS (Prepare To Sleep) S5 will result in a fatal
+ * PCIe AER event on the tg3 device if the tg3 device is not, or cannot
+ * be, powered down.
+ */
+static const struct dmi_system_id tg3_restart_aer_quirk_table[] = {
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R440"),
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R540"),
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R640"),
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R650"),
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R740"),
+		},
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R750"),
+		},
+	},
+	{}
+};
+
 static void tg3_shutdown(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
@@ -18199,6 +18247,19 @@
 
 	if (system_state == SYSTEM_POWER_OFF)
 		tg3_power_down(tp);
+	else if (system_state == SYSTEM_RESTART &&
+		 dmi_first_match(tg3_restart_aer_quirk_table) &&
+		 pdev->current_state != PCI_D3cold &&
+		 pdev->current_state != PCI_UNKNOWN) {
+		/* Disable PCIe AER on the tg3 to avoid a fatal
+		 * error during this system restart.
+		 */
+		pcie_capability_clear_word(pdev, PCI_EXP_DEVCTL,
+					   PCI_EXP_DEVCTL_CERE |
+					   PCI_EXP_DEVCTL_NFERE |
+					   PCI_EXP_DEVCTL_FERE |
+					   PCI_EXP_DEVCTL_URRE);
+	}
 
 	rtnl_unlock();
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/brocade/bna/bna_types.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/brocade/bna/bna_types.h
@@ -416,7 +416,7 @@
 /* Tx object */
 
 /* Tx datapath control structure */
-#define BNA_Q_NAME_SIZE		16
+#define BNA_Q_NAME_SIZE		(IFNAMSIZ + 6)
 struct bna_tcb {
 	/* Fast path */
 	void			**sw_qpt;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/brocade/bna/bnad.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/brocade/bna/bnad.c
@@ -1534,8 +1534,9 @@
 
 	for (i = 0; i < num_txqs; i++) {
 		vector_num = tx_info->tcb[i]->intr_vector;
-		sprintf(tx_info->tcb[i]->name, "%s TXQ %d", bnad->netdev->name,
-				tx_id + tx_info->tcb[i]->id);
+		snprintf(tx_info->tcb[i]->name, BNA_Q_NAME_SIZE, "%s TXQ %d",
+			 bnad->netdev->name,
+			 tx_id + tx_info->tcb[i]->id);
 		err = request_irq(bnad->msix_table[vector_num].vector,
 				  (irq_handler_t)bnad_msix_tx, 0,
 				  tx_info->tcb[i]->name,
@@ -1585,9 +1586,9 @@
 
 	for (i = 0; i < num_rxps; i++) {
 		vector_num = rx_info->rx_ctrl[i].ccb->intr_vector;
-		sprintf(rx_info->rx_ctrl[i].ccb->name, "%s CQ %d",
-			bnad->netdev->name,
-			rx_id + rx_info->rx_ctrl[i].ccb->id);
+		snprintf(rx_info->rx_ctrl[i].ccb->name, BNA_Q_NAME_SIZE,
+			 "%s CQ %d", bnad->netdev->name,
+			 rx_id + rx_info->rx_ctrl[i].ccb->id);
 		err = request_irq(bnad->msix_table[vector_num].vector,
 				  (irq_handler_t)bnad_msix_rx, 0,
 				  rx_info->rx_ctrl[i].ccb->name,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/brocade/bna/bnad_debugfs.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/brocade/bna/bnad_debugfs.c
@@ -312,7 +312,7 @@
 	void *kern_buf;
 
 	/* Copy the user space buf */
-	kern_buf = memdup_user(buf, nbytes);
+	kern_buf = memdup_user_nul(buf, nbytes);
 	if (IS_ERR(kern_buf))
 		return PTR_ERR(kern_buf);
 
@@ -372,7 +372,7 @@
 	void *kern_buf;
 
 	/* Copy the user space buf */
-	kern_buf = memdup_user(buf, nbytes);
+	kern_buf = memdup_user_nul(buf, nbytes);
 	if (IS_ERR(kern_buf))
 		return PTR_ERR(kern_buf);
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/cadence/macb_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/cadence/macb_main.c
@@ -930,9 +930,6 @@
 		return ret;
 	}
 
-	if (of_phy_is_fixed_link(np))
-		return mdiobus_register(bp->mii_bus);
-
 	/* Only create the PHY from the device tree if at least one PHY is
 	 * described. Otherwise scan the entire MDIO bus. We do this to support
 	 * old device tree that did not follow the best practices and did not
@@ -953,8 +950,19 @@
 
 static int macb_mii_init(struct macb *bp)
 {
+	struct device_node *child, *np = bp->pdev->dev.of_node;
 	int err = -ENXIO;
 
+	/* With fixed-link, we don't need to register the MDIO bus,
+	 * except if we have a child named "mdio" in the device tree.
+	 * In that case, some devices may be attached to the MACB's MDIO bus.
+	 */
+	child = of_get_child_by_name(np, "mdio");
+	if (child)
+		of_node_put(child);
+	else if (of_phy_is_fixed_link(np))
+		return macb_mii_probe(bp->dev);
+
 	/* Enable management port */
 	macb_writel(bp, NCR, MACB_BIT(MPE));
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c
@@ -272,13 +272,12 @@
 				pg_info->page_offset;
 			memcpy(skb->data, va, MIN_SKB_SIZE);
 			skb_put(skb, MIN_SKB_SIZE);
+			skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
+					pg_info->page,
+					pg_info->page_offset + MIN_SKB_SIZE,
+					len - MIN_SKB_SIZE,
+					LIO_RXBUFFER_SZ);
 		}
-
-		skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
-				pg_info->page,
-				pg_info->page_offset + MIN_SKB_SIZE,
-				len - MIN_SKB_SIZE,
-				LIO_RXBUFFER_SZ);
 	} else {
 		struct octeon_skb_page_info *pg_info =
 			((struct octeon_skb_page_info *)(skb->cb));
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -2082,7 +2082,7 @@
 		     struct sge_idma_monitor_state *idma,
 		     int hz, int ticks);
 int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf,
-		      unsigned int naddr, u8 *addr);
+		      u8 start, unsigned int naddr, u8 *addr);
 void t4_tp_pio_read(struct adapter *adap, u32 *buff, u32 nregs,
 		    u32 start_index, bool sleep_ok);
 void t4_tp_tm_pio_read(struct adapter *adap, u32 *buff, u32 nregs,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
@@ -1244,7 +1244,8 @@
 	 * in the Compressed Filter Tuple.
 	 */
 	if (tp->vlan_shift >= 0 && fs->mask.ivlan)
-		ntuple |= (FT_VLAN_VLD_F | fs->val.ivlan) << tp->vlan_shift;
+		ntuple |= (u64)(FT_VLAN_VLD_F |
+				fs->val.ivlan) << tp->vlan_shift;
 
 	if (tp->port_shift >= 0 && fs->mask.iport)
 		ntuple |= (u64)fs->val.iport << tp->port_shift;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -1799,7 +1799,10 @@
 	struct adapter *adap = container_of(t, struct adapter, tids);
 	struct sk_buff *skb;
 
-	WARN_ON(tid_out_of_range(&adap->tids, tid));
+	if (tid_out_of_range(&adap->tids, tid)) {
+		dev_err(adap->pdev_dev, "tid %d out of range\n", tid);
+		return;
+	}
 
 	if (t->tid_tab[tid - adap->tids.tid_base]) {
 		t->tid_tab[tid - adap->tids.tid_base] = NULL;
@@ -3246,7 +3249,7 @@
 
 	dev_info(pi->adapter->pdev_dev,
 		 "Setting MAC %pM on VF %d\n", mac, vf);
-	ret = t4_set_vf_mac_acl(adap, vf + 1, 1, mac);
+	ret = t4_set_vf_mac_acl(adap, vf + 1, pi->lport, 1, mac);
 	if (!ret)
 		ether_addr_copy(adap->vfinfo[vf].vf_mac_addr, mac);
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/chelsio/cxgb4/sge.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/chelsio/cxgb4/sge.c
@@ -2684,12 +2684,12 @@
 	lb->loopback = 1;
 
 	q = &adap->sge.ethtxq[pi->first_qset];
-	__netif_tx_lock(q->txq, smp_processor_id());
+	__netif_tx_lock_bh(q->txq);
 
 	reclaim_completed_tx(adap, &q->q, -1, true);
 	credits = txq_avail(&q->q) - ndesc;
 	if (unlikely(credits < 0)) {
-		__netif_tx_unlock(q->txq);
+		__netif_tx_unlock_bh(q->txq);
 		return -ENOMEM;
 	}
 
@@ -2724,7 +2724,7 @@
 	init_completion(&lb->completion);
 	txq_advance(&q->q, ndesc);
 	cxgb4_ring_tx_db(adap, &q->q, ndesc);
-	__netif_tx_unlock(q->txq);
+	__netif_tx_unlock_bh(q->txq);
 
 	/* wait for the pkt to return */
 	ret = wait_for_completion_timeout(&lb->completion, 10 * HZ);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -10215,11 +10215,12 @@
  *	t4_set_vf_mac_acl - Set MAC address for the specified VF
  *	@adapter: The adapter
  *	@vf: one of the VFs instantiated by the specified PF
+ *	@start: The start port id associated with specified VF
  *	@naddr: the number of MAC addresses
  *	@addr: the MAC address(es) to be set to the specified VF
  */
 int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf,
-		      unsigned int naddr, u8 *addr)
+		      u8 start, unsigned int naddr, u8 *addr)
 {
 	struct fw_acl_mac_cmd cmd;
 
@@ -10234,7 +10235,7 @@
 	cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd));
 	cmd.nmac = naddr;
 
-	switch (adapter->pf) {
+	switch (start) {
 	case 3:
 		memcpy(cmd.macaddr3, addr, sizeof(cmd.macaddr3));
 		break;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_main.c
@@ -346,8 +346,9 @@
 	 * driver. Once driver synthesizes cpl_pass_accpet_req the skb will go
 	 * through the regular cpl_pass_accept_req processing in TOM.
 	 */
-	skb = alloc_skb(gl->tot_len + sizeof(struct cpl_pass_accept_req)
-			- pktshift, GFP_ATOMIC);
+	skb = alloc_skb(size_add(gl->tot_len,
+				 sizeof(struct cpl_pass_accept_req)) -
+			pktshift, GFP_ATOMIC);
 	if (unlikely(!skb))
 		return NULL;
 	__skb_put(skb, gl->tot_len + sizeof(struct cpl_pass_accept_req)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/cisco/enic/enic_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -1117,18 +1117,30 @@
 	pp->request = nla_get_u8(port[IFLA_PORT_REQUEST]);
 
 	if (port[IFLA_PORT_PROFILE]) {
+		if (nla_len(port[IFLA_PORT_PROFILE]) != PORT_PROFILE_MAX) {
+			memcpy(pp, &prev_pp, sizeof(*pp));
+			return -EINVAL;
+		}
 		pp->set |= ENIC_SET_NAME;
 		memcpy(pp->name, nla_data(port[IFLA_PORT_PROFILE]),
 			PORT_PROFILE_MAX);
 	}
 
 	if (port[IFLA_PORT_INSTANCE_UUID]) {
+		if (nla_len(port[IFLA_PORT_INSTANCE_UUID]) != PORT_UUID_MAX) {
+			memcpy(pp, &prev_pp, sizeof(*pp));
+			return -EINVAL;
+		}
 		pp->set |= ENIC_SET_INSTANCE;
 		memcpy(pp->instance_uuid,
 			nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX);
 	}
 
 	if (port[IFLA_PORT_HOST_UUID]) {
+		if (nla_len(port[IFLA_PORT_HOST_UUID]) != PORT_UUID_MAX) {
+			memcpy(pp, &prev_pp, sizeof(*pp));
+			return -EINVAL;
+		}
 		pp->set |= ENIC_SET_HOST;
 		memcpy(pp->host_uuid,
 			nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/cortina/gemini.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/cortina/gemini.c
@@ -79,7 +79,8 @@
 #define GMAC0_IRQ4_8 (GMAC0_MIB_INT_BIT | GMAC0_RX_OVERRUN_INT_BIT)
 
 #define GMAC_OFFLOAD_FEATURES (NETIF_F_SG | NETIF_F_IP_CSUM | \
-			       NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM)
+			       NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | \
+			       NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6)
 
 /**
  * struct gmac_queue_page - page buffer per-page info
@@ -1107,10 +1108,13 @@
 {
 	struct gemini_ethernet_port *port = netdev_priv(netdev);
 	struct gemini_ethernet *geth = port->geth;
+	unsigned long flags;
 	u32 val, mask;
 
 	netdev_dbg(netdev, "%s device %d\n", __func__, netdev->dev_id);
 
+	spin_lock_irqsave(&geth->irq_lock, flags);
+
 	mask = GMAC0_IRQ0_TXQ0_INTS << (6 * netdev->dev_id + txq);
 
 	if (en)
@@ -1119,6 +1123,8 @@
 	val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG);
 	val = en ? val | mask : val & ~mask;
 	writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG);
+
+	spin_unlock_irqrestore(&geth->irq_lock, flags);
 }
 
 static void gmac_tx_irq(struct net_device *netdev, unsigned int txq_num)
@@ -1143,13 +1149,25 @@
 	skb_frag_t *skb_frag;
 	dma_addr_t mapping;
 	void *buffer;
+	u16 mss;
 	int ret;
 
-	/* TODO: implement proper TSO using MTU in word3 */
 	word1 = skb->len;
 	word3 = SOF_BIT;
 
-	if (skb->len >= ETH_FRAME_LEN) {
+	mss = skb_shinfo(skb)->gso_size;
+	if (mss) {
+		/* This means we are dealing with TCP and skb->len is the
+		 * sum total of all the segments. The TSO will deal with
+		 * chopping this up for us.
+		 */
+		/* The accelerator needs the full frame size here */
+		mss += skb_tcp_all_headers(skb);
+		netdev_dbg(netdev, "segment offloading mss = %04x len=%04x\n",
+			   mss, skb->len);
+		word1 |= TSS_MTU_ENABLE_BIT;
+		word3 |= mss;
+	} else if (skb->len >= ETH_FRAME_LEN) {
 		/* Hardware offloaded checksumming isn't working on frames
 		 * bigger than 1514 bytes. A hypothesis about this is that the
 		 * checksum buffer is only 1518 bytes, so when the frames get
@@ -1164,7 +1182,9 @@
 				return ret;
 		}
 		word1 |= TSS_BYPASS_BIT;
-	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+	}
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		int tcp = 0;
 
 		/* We do not switch off the checksumming on non TCP/UDP
@@ -1415,15 +1435,19 @@
 	union gmac_rxdesc_3 word3;
 	struct page *page = NULL;
 	unsigned int page_offs;
+	unsigned long flags;
 	unsigned short r, w;
 	union dma_rwptr rw;
 	dma_addr_t mapping;
 	int frag_nr = 0;
 
+	spin_lock_irqsave(&geth->irq_lock, flags);
 	rw.bits32 = readl(ptr_reg);
 	/* Reset interrupt as all packages until here are taken into account */
 	writel(DEFAULT_Q0_INT_BIT << netdev->dev_id,
 	       geth->base + GLOBAL_INTERRUPT_STATUS_1_REG);
+	spin_unlock_irqrestore(&geth->irq_lock, flags);
+
 	r = rw.bits.rptr;
 	w = rw.bits.wptr;
 
@@ -1726,10 +1750,9 @@
 		gmac_update_hw_stats(netdev);
 
 	if (val & (GMAC0_RX_OVERRUN_INT_BIT << (netdev->dev_id * 8))) {
+		spin_lock(&geth->irq_lock);
 		writel(GMAC0_RXDERR_INT_BIT << (netdev->dev_id * 8),
 		       geth->base + GLOBAL_INTERRUPT_STATUS_4_REG);
-
-		spin_lock(&geth->irq_lock);
 		u64_stats_update_begin(&port->ir_stats_syncp);
 		++port->stats.rx_fifo_errors;
 		u64_stats_update_end(&port->ir_stats_syncp);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/davicom/dm9000.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/davicom/dm9000.c
@@ -1777,10 +1777,11 @@
 
 	unregister_netdev(ndev);
 	dm9000_release_board(pdev, dm);
-	free_netdev(ndev);		/* free device structure */
 	if (dm->power_supply)
 		regulator_disable(dm->power_supply);
 
+	free_netdev(ndev);		/* free device structure */
+
 	dev_dbg(&pdev->dev, "released and freed device\n");
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/emulex/benet/be_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/emulex/benet/be_main.c
@@ -1381,10 +1381,8 @@
 	be_get_wrb_params_from_skb(adapter, skb, &wrb_params);
 
 	wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params);
-	if (unlikely(!wrb_cnt)) {
-		dev_kfree_skb_any(skb);
-		goto drop;
-	}
+	if (unlikely(!wrb_cnt))
+		goto drop_skb;
 
 	/* if os2bmc is enabled and if the pkt is destined to bmc,
 	 * enqueue the pkt a 2nd time with mgmt bit set.
@@ -1393,7 +1391,7 @@
 		BE_WRB_F_SET(wrb_params.features, OS2BMC, 1);
 		wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params);
 		if (unlikely(!wrb_cnt))
-			goto drop;
+			goto drop_skb;
 		else
 			skb_get(skb);
 	}
@@ -1407,6 +1405,8 @@
 		be_xmit_flush(adapter, txo);
 
 	return NETDEV_TX_OK;
+drop_skb:
+	dev_kfree_skb_any(skb);
 drop:
 	tx_stats(txo)->tx_drv_drops++;
 	/* Flush the already enqueued tx requests */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/faraday/ftgmac100.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/faraday/ftgmac100.c
@@ -572,7 +572,7 @@
 	(*processed)++;
 	return true;
 
- drop:
+drop:
 	/* Clean rxdes0 (which resets own bit) */
 	rxdes->rxdes0 = cpu_to_le32(status & priv->rxdes0_edorr_mask);
 	priv->rx_pointer = ftgmac100_next_rx_pointer(priv, pointer);
@@ -656,6 +656,11 @@
 	ftgmac100_free_tx_packet(priv, pointer, skb, txdes, ctl_stat);
 	txdes->txdes0 = cpu_to_le32(ctl_stat & priv->txdes0_edotr_mask);
 
+	/* Ensure the descriptor config is visible before setting the tx
+	 * pointer.
+	 */
+	smp_wmb();
+
 	priv->tx_clean_pointer = ftgmac100_next_tx_pointer(priv, pointer);
 
 	return true;
@@ -809,6 +814,11 @@
 	dma_wmb();
 	first->txdes0 = cpu_to_le32(f_ctl_stat);
 
+	/* Ensure the descriptor config is visible before setting the tx
+	 * pointer.
+	 */
+	smp_wmb();
+
 	/* Update next TX pointer */
 	priv->tx_pointer = pointer;
 
@@ -829,7 +839,7 @@
 
 	return NETDEV_TX_OK;
 
- dma_err:
+dma_err:
 	if (net_ratelimit())
 		netdev_err(netdev, "map tx fragment failed\n");
 
@@ -851,7 +861,7 @@
 	 * last fragment, so we know ftgmac100_free_tx_packet()
 	 * hasn't freed the skb yet.
 	 */
- drop:
+drop:
 	/* Drop the packet */
 	dev_kfree_skb_any(skb);
 	netdev->stats.tx_dropped++;
@@ -1344,7 +1354,7 @@
 	ftgmac100_init_all(priv, true);
 
 	netdev_dbg(netdev, "Reset done !\n");
- bail:
+bail:
 	if (priv->mii_bus)
 		mutex_unlock(&priv->mii_bus->mdio_lock);
 	if (netdev->phydev)
@@ -1543,15 +1553,15 @@
 
 	return 0;
 
- err_ncsi:
+err_ncsi:
 	napi_disable(&priv->napi);
 	netif_stop_queue(netdev);
- err_alloc:
+err_alloc:
 	ftgmac100_free_buffers(priv);
 	free_irq(netdev->irq, netdev);
- err_irq:
+err_irq:
 	netif_napi_del(&priv->napi);
- err_hw:
+err_hw:
 	iowrite32(0, priv->base + FTGMAC100_OFFSET_IER);
 	ftgmac100_free_rings(priv);
 	return err;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/faraday/ftgmac100.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/faraday/ftgmac100.h
@@ -84,7 +84,7 @@
 			    FTGMAC100_INT_RPKT_BUF)
 
 /* All the interrupts we care about */
-#define FTGMAC100_INT_ALL (FTGMAC100_INT_RPKT_BUF  |  \
+#define FTGMAC100_INT_ALL (FTGMAC100_INT_RXTX  |  \
 			   FTGMAC100_INT_BAD)
 
 /*
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
@@ -931,14 +931,18 @@
 	}
 }
 
-static void dpaa_fq_setup(struct dpaa_priv *priv,
-			  const struct dpaa_fq_cbs *fq_cbs,
-			  struct fman_port *tx_port)
+static int dpaa_fq_setup(struct dpaa_priv *priv,
+			 const struct dpaa_fq_cbs *fq_cbs,
+			 struct fman_port *tx_port)
 {
 	int egress_cnt = 0, conf_cnt = 0, num_portals = 0, portal_cnt = 0, cpu;
 	const cpumask_t *affine_cpus = qman_affine_cpus();
-	u16 channels[NR_CPUS];
 	struct dpaa_fq *fq;
+	u16 *channels;
+
+	channels = kcalloc(num_possible_cpus(), sizeof(u16), GFP_KERNEL);
+	if (!channels)
+		return -ENOMEM;
 
 	for_each_cpu_and(cpu, affine_cpus, cpu_online_mask)
 		channels[num_portals++] = qman_affine_channel(cpu);
@@ -997,6 +1001,10 @@
 				break;
 		}
 	}
+
+	kfree(channels);
+
+	return 0;
 }
 
 static inline int dpaa_tx_fq_to_id(const struct dpaa_priv *priv,
@@ -2277,12 +2285,12 @@
 dpaa_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
 {
 	const int queue_mapping = skb_get_queue_mapping(skb);
-	bool nonlinear = skb_is_nonlinear(skb);
 	struct rtnl_link_stats64 *percpu_stats;
 	struct dpaa_percpu_priv *percpu_priv;
 	struct netdev_queue *txq;
 	struct dpaa_priv *priv;
 	struct qm_fd fd;
+	bool nonlinear;
 	int offset = 0;
 	int err = 0;
 
@@ -2292,6 +2300,13 @@
 
 	qm_fd_clear_fd(&fd);
 
+	/* Packet data is always read as 32-bit words, so zero out any part of
+	 * the skb which might be sent if we have to pad the packet
+	 */
+	if (__skb_put_padto(skb, ETH_ZLEN, false))
+		goto enomem;
+
+	nonlinear = skb_is_nonlinear(skb);
 	if (!nonlinear) {
 		/* We're going to store the skb backpointer at the beginning
 		 * of the data buffer, so we need a privately owned skb
@@ -3416,7 +3431,9 @@
 	 */
 	dpaa_eth_add_channel(priv->channel, &pdev->dev);
 
-	dpaa_fq_setup(priv, &dpaa_fq_cbs, priv->mac_dev->port[TX]);
+	err = dpaa_fq_setup(priv, &dpaa_fq_cbs, priv->mac_dev->port[TX]);
+	if (err)
+		goto free_dpaa_bps;
 
 	/* Create a congestion group for this netdev, with
 	 * dynamically-allocated CGR ID.
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/dpaa/dpaa_eth_trace.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/dpaa/dpaa_eth_trace.h
@@ -56,7 +56,7 @@
 		__entry->fd_format = qm_fd_get_format(fd);
 		__entry->fd_offset = qm_fd_get_offset(fd);
 		__entry->fd_length = qm_fd_get_length(fd);
-		__entry->fd_status = fd->status;
+		__entry->fd_status = __be32_to_cpu(fd->status);
 		__assign_str(name, netdev->name);
 	),
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
@@ -457,12 +457,16 @@
 			     struct netlink_ext_ack *extack)
 {
 	const cpumask_t *cpus = qman_affine_cpus();
-	bool needs_revert[NR_CPUS] = {false};
 	struct qman_portal *portal;
 	u32 period, prev_period;
 	u8 thresh, prev_thresh;
+	bool *needs_revert;
 	int cpu, res;
 
+	needs_revert = kcalloc(num_possible_cpus(), sizeof(bool), GFP_KERNEL);
+	if (!needs_revert)
+		return -ENOMEM;
+
 	period = c->rx_coalesce_usecs;
 	thresh = c->rx_max_coalesced_frames;
 
@@ -485,6 +489,8 @@
 		needs_revert[cpu] = true;
 	}
 
+	kfree(needs_revert);
+
 	return 0;
 
 revert_values:
@@ -498,6 +504,8 @@
 		qman_dqrr_set_ithresh(portal, prev_thresh);
 	}
 
+	kfree(needs_revert);
+
 	return res;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -2896,11 +2896,14 @@
 static int update_xps(struct dpaa2_eth_priv *priv)
 {
 	struct net_device *net_dev = priv->net_dev;
-	struct cpumask xps_mask;
-	struct dpaa2_eth_fq *fq;
 	int i, num_queues, netdev_queues;
+	struct dpaa2_eth_fq *fq;
+	cpumask_var_t xps_mask;
 	int err = 0;
 
+	if (!alloc_cpumask_var(&xps_mask, GFP_KERNEL))
+		return -ENOMEM;
+
 	num_queues = dpaa2_eth_queue_count(priv);
 	netdev_queues = (net_dev->num_tc ? : 1) * num_queues;
 
@@ -2910,16 +2913,17 @@
 	for (i = 0; i < netdev_queues; i++) {
 		fq = &priv->fq[i % num_queues];
 
-		cpumask_clear(&xps_mask);
-		cpumask_set_cpu(fq->target_cpu, &xps_mask);
+		cpumask_clear(xps_mask);
+		cpumask_set_cpu(fq->target_cpu, xps_mask);
 
-		err = netif_set_xps_queue(net_dev, &xps_mask, i);
+		err = netif_set_xps_queue(net_dev, xps_mask, i);
 		if (err) {
 			netdev_warn_once(net_dev, "Error setting XPS queue\n");
 			break;
 		}
 	}
 
+	free_cpumask_var(xps_mask);
 	return err;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
@@ -2638,13 +2638,14 @@
 
 static int dpaa2_switch_seed_bp(struct ethsw_core *ethsw)
 {
-	int *count, i;
+	int *count, ret, i;
 
 	for (i = 0; i < DPAA2_ETHSW_NUM_BUFS; i += BUFS_PER_CMD) {
+		ret = dpaa2_switch_add_bufs(ethsw, ethsw->bpid);
 		count = &ethsw->buf_count;
-		*count += dpaa2_switch_add_bufs(ethsw, ethsw->bpid);
+		*count += ret;
 
-		if (unlikely(*count < BUFS_PER_CMD))
+		if (unlikely(ret < BUFS_PER_CMD))
 			return -ENOMEM;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/enetc/enetc.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/enetc/enetc.c
@@ -28,6 +28,9 @@
 static void enetc_change_preemptible_tcs(struct enetc_ndev_priv *priv,
 					 u8 preemptible_tcs)
 {
+	if (!(priv->si->hw_features & ENETC_SI_F_QBU))
+		return;
+
 	priv->preemptible_tcs = preemptible_tcs;
 	enetc_mm_commit_preemptible_tcs(priv);
 }
@@ -902,6 +905,7 @@
 
 	if (unlikely(tx_frm_cnt && netif_carrier_ok(ndev) &&
 		     __netif_subqueue_stopped(ndev, tx_ring->index) &&
+		     !test_bit(ENETC_TX_DOWN, &priv->flags) &&
 		     (enetc_bd_unused(tx_ring) >= ENETC_TXBDS_MAX_NEEDED))) {
 		netif_wake_subqueue(ndev, tx_ring->index);
 	}
@@ -1380,6 +1384,9 @@
 	int xdp_tx_bd_cnt, i, k;
 	int xdp_tx_frm_cnt = 0;
 
+	if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags)))
+		return -ENETDOWN;
+
 	enetc_lock_mdio();
 
 	tx_ring = priv->xdp_tx_ring[smp_processor_id()];
@@ -1524,7 +1531,6 @@
 				  &rx_ring->rx_swbd[rx_ring_first]);
 		enetc_bdr_idx_inc(rx_ring, &rx_ring_first);
 	}
-	rx_ring->stats.xdp_drops++;
 }
 
 static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
@@ -1589,6 +1595,7 @@
 			fallthrough;
 		case XDP_DROP:
 			enetc_xdp_drop(rx_ring, orig_i, i);
+			rx_ring->stats.xdp_drops++;
 			break;
 		case XDP_PASS:
 			rxbd = orig_rxbd;
@@ -1605,6 +1612,12 @@
 			break;
 		case XDP_TX:
 			tx_ring = priv->xdp_tx_ring[rx_ring->index];
+			if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags))) {
+				enetc_xdp_drop(rx_ring, orig_i, i);
+				tx_ring->stats.xdp_tx_drops++;
+				break;
+			}
+
 			xdp_tx_bd_cnt = enetc_rx_swbd_to_xdp_tx_swbd(xdp_tx_arr,
 								     rx_ring,
 								     orig_i, i);
@@ -2226,18 +2239,24 @@
 	enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr);
 }
 
-static void enetc_enable_bdrs(struct enetc_ndev_priv *priv)
+static void enetc_enable_rx_bdrs(struct enetc_ndev_priv *priv)
 {
 	struct enetc_hw *hw = &priv->si->hw;
 	int i;
 
-	for (i = 0; i < priv->num_tx_rings; i++)
-		enetc_enable_txbdr(hw, priv->tx_ring[i]);
-
 	for (i = 0; i < priv->num_rx_rings; i++)
 		enetc_enable_rxbdr(hw, priv->rx_ring[i]);
 }
 
+static void enetc_enable_tx_bdrs(struct enetc_ndev_priv *priv)
+{
+	struct enetc_hw *hw = &priv->si->hw;
+	int i;
+
+	for (i = 0; i < priv->num_tx_rings; i++)
+		enetc_enable_txbdr(hw, priv->tx_ring[i]);
+}
+
 static void enetc_disable_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring)
 {
 	int idx = rx_ring->index;
@@ -2254,18 +2273,24 @@
 	enetc_txbdr_wr(hw, idx, ENETC_TBMR, 0);
 }
 
-static void enetc_disable_bdrs(struct enetc_ndev_priv *priv)
+static void enetc_disable_rx_bdrs(struct enetc_ndev_priv *priv)
 {
 	struct enetc_hw *hw = &priv->si->hw;
 	int i;
 
-	for (i = 0; i < priv->num_tx_rings; i++)
-		enetc_disable_txbdr(hw, priv->tx_ring[i]);
-
 	for (i = 0; i < priv->num_rx_rings; i++)
 		enetc_disable_rxbdr(hw, priv->rx_ring[i]);
 }
 
+static void enetc_disable_tx_bdrs(struct enetc_ndev_priv *priv)
+{
+	struct enetc_hw *hw = &priv->si->hw;
+	int i;
+
+	for (i = 0; i < priv->num_tx_rings; i++)
+		enetc_disable_txbdr(hw, priv->tx_ring[i]);
+}
+
 static void enetc_wait_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring)
 {
 	int delay = 8, timeout = 100;
@@ -2305,12 +2330,11 @@
 
 		snprintf(v->name, sizeof(v->name), "%s-rxtx%d",
 			 priv->ndev->name, i);
-		err = request_irq(irq, enetc_msix, 0, v->name, v);
+		err = request_irq(irq, enetc_msix, IRQF_NO_AUTOEN, v->name, v);
 		if (err) {
 			dev_err(priv->dev, "request_irq() failed!\n");
 			goto irq_err;
 		}
-		disable_irq(irq);
 
 		v->tbier_base = hw->reg + ENETC_BDR(TX, 0, ENETC_TBIER);
 		v->rbier = hw->reg + ENETC_BDR(RX, i, ENETC_RBIER);
@@ -2464,9 +2488,13 @@
 		enable_irq(irq);
 	}
 
-	enetc_enable_bdrs(priv);
+	enetc_enable_tx_bdrs(priv);
+
+	enetc_enable_rx_bdrs(priv);
 
 	netif_tx_start_all_queues(ndev);
+
+	clear_bit(ENETC_TX_DOWN, &priv->flags);
 }
 EXPORT_SYMBOL_GPL(enetc_start);
 
@@ -2524,9 +2552,15 @@
 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
 	int i;
 
+	set_bit(ENETC_TX_DOWN, &priv->flags);
+
 	netif_tx_stop_all_queues(ndev);
 
-	enetc_disable_bdrs(priv);
+	enetc_disable_rx_bdrs(priv);
+
+	enetc_wait_bdrs(priv);
+
+	enetc_disable_tx_bdrs(priv);
 
 	for (i = 0; i < priv->bdr_int_num; i++) {
 		int irq = pci_irq_vector(priv->si->pdev,
@@ -2537,8 +2571,6 @@
 		napi_disable(&priv->int_vector[i]->napi);
 	}
 
-	enetc_wait_bdrs(priv);
-
 	enetc_clear_interrupts(priv);
 }
 EXPORT_SYMBOL_GPL(enetc_stop);
@@ -2769,7 +2801,7 @@
 	if (priv->min_num_stack_tx_queues + num_xdp_tx_queues >
 	    priv->num_tx_rings) {
 		NL_SET_ERR_MSG_FMT_MOD(extack,
-				       "Reserving %d XDP TXQs does not leave a minimum of %d for stack (total %d)",
+				       "Reserving %d XDP TXQs leaves under %d for stack (total %d)",
 				       num_xdp_tx_queues,
 				       priv->min_num_stack_tx_queues,
 				       priv->num_tx_rings);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/enetc/enetc.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/enetc/enetc.h
@@ -328,6 +328,7 @@
 
 enum enetc_flags_bit {
 	ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS = 0,
+	ENETC_TX_DOWN,
 };
 
 /* interrupt coalescing modes */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -665,19 +665,11 @@
 
 	if (!num_vfs) {
 		enetc_msg_psi_free(pf);
-		kfree(pf->vf_state);
 		pf->num_vfs = 0;
 		pci_disable_sriov(pdev);
 	} else {
 		pf->num_vfs = num_vfs;
 
-		pf->vf_state = kcalloc(num_vfs, sizeof(struct enetc_vf_state),
-				       GFP_KERNEL);
-		if (!pf->vf_state) {
-			pf->num_vfs = 0;
-			return -ENOMEM;
-		}
-
 		err = enetc_msg_psi_init(pf);
 		if (err) {
 			dev_err(&pdev->dev, "enetc_msg_psi_init (%d)\n", err);
@@ -696,7 +688,6 @@
 err_en_sriov:
 	enetc_msg_psi_free(pf);
 err_msg_psi:
-	kfree(pf->vf_state);
 	pf->num_vfs = 0;
 
 	return err;
@@ -1286,6 +1277,12 @@
 	pf = enetc_si_priv(si);
 	pf->si = si;
 	pf->total_vfs = pci_sriov_get_totalvfs(pdev);
+	if (pf->total_vfs) {
+		pf->vf_state = kcalloc(pf->total_vfs, sizeof(struct enetc_vf_state),
+				       GFP_KERNEL);
+		if (!pf->vf_state)
+			goto err_alloc_vf_state;
+	}
 
 	err = enetc_setup_mac_addresses(node, pf);
 	if (err)
@@ -1363,6 +1360,8 @@
 	free_netdev(ndev);
 err_alloc_netdev:
 err_setup_mac_addresses:
+	kfree(pf->vf_state);
+err_alloc_vf_state:
 	enetc_psi_destroy(pdev);
 err_psi_create:
 	return err;
@@ -1389,6 +1388,7 @@
 	enetc_free_si_resources(priv);
 
 	free_netdev(si->ndev);
+	kfree(pf->vf_state);
 
 	enetc_psi_destroy(pdev);
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/enetc/enetc_vf.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/enetc/enetc_vf.c
@@ -78,11 +78,18 @@
 {
 	struct enetc_ndev_priv *priv = netdev_priv(ndev);
 	struct sockaddr *saddr = addr;
+	int err;
 
 	if (!is_valid_ether_addr(saddr->sa_data))
 		return -EADDRNOTAVAIL;
 
-	return enetc_msg_vsi_set_primary_mac_addr(priv, saddr);
+	err = enetc_msg_vsi_set_primary_mac_addr(priv, saddr);
+	if (err)
+		return err;
+
+	eth_hw_addr_set(ndev, saddr->sa_data);
+
+	return 0;
 }
 
 static int enetc_vf_set_features(struct net_device *ndev,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/fec.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/fec.h
@@ -691,10 +691,19 @@
 	/* XDP BPF Program */
 	struct bpf_prog *xdp_prog;
 
+	struct {
+		int pps_enable;
+		u64 ns_sys, ns_phc;
+		u32 at_corr;
+		u8 at_inc_corr;
+	} ptp_saved_state;
+
 	u64 ethtool_stats[];
 };
 
 void fec_ptp_init(struct platform_device *pdev, int irq_idx);
+void fec_ptp_restore_state(struct fec_enet_private *fep);
+void fec_ptp_save_state(struct fec_enet_private *fep);
 void fec_ptp_stop(struct platform_device *pdev);
 void fec_ptp_start_cyclecounter(struct net_device *ndev);
 int fec_ptp_set(struct net_device *ndev, struct kernel_hwtstamp_config *config,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/fec_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/fec_main.c
@@ -240,8 +240,8 @@
 #define PKT_MINBUF_SIZE		64
 
 /* FEC receive acceleration */
-#define FEC_RACC_IPDIS		(1 << 1)
-#define FEC_RACC_PRODIS		(1 << 2)
+#define FEC_RACC_IPDIS		BIT(1)
+#define FEC_RACC_PRODIS		BIT(2)
 #define FEC_RACC_SHIFT16	BIT(7)
 #define FEC_RACC_OPTIONS	(FEC_RACC_IPDIS | FEC_RACC_PRODIS)
 
@@ -273,8 +273,23 @@
 #define FEC_MMFR_TA		(2 << 16)
 #define FEC_MMFR_DATA(v)	(v & 0xffff)
 /* FEC ECR bits definition */
-#define FEC_ECR_MAGICEN		(1 << 2)
-#define FEC_ECR_SLEEP		(1 << 3)
+#define FEC_ECR_RESET           BIT(0)
+#define FEC_ECR_ETHEREN         BIT(1)
+#define FEC_ECR_MAGICEN         BIT(2)
+#define FEC_ECR_SLEEP           BIT(3)
+#define FEC_ECR_EN1588          BIT(4)
+#define FEC_ECR_BYTESWP         BIT(8)
+/* FEC RCR bits definition */
+#define FEC_RCR_LOOP            BIT(0)
+#define FEC_RCR_HALFDPX         BIT(1)
+#define FEC_RCR_MII             BIT(2)
+#define FEC_RCR_PROMISC         BIT(3)
+#define FEC_RCR_BC_REJ          BIT(4)
+#define FEC_RCR_FLOWCTL         BIT(5)
+#define FEC_RCR_RMII            BIT(8)
+#define FEC_RCR_10BASET         BIT(9)
+/* TX WMARK bits */
+#define FEC_TXWMRK_STRFWD       BIT(8)
 
 #define FEC_MII_TIMEOUT		30000 /* us */
 
@@ -827,6 +842,8 @@
 	struct fec_enet_private *fep = netdev_priv(ndev);
 	int hdr_len, total_len, data_left;
 	struct bufdesc *bdp = txq->bd.cur;
+	struct bufdesc *tmp_bdp;
+	struct bufdesc_ex *ebdp;
 	struct tso_t tso;
 	unsigned int index = 0;
 	int ret;
@@ -900,7 +917,34 @@
 	return 0;
 
 err_release:
-	/* TODO: Release all used data descriptors for TSO */
+	/* Release all used data descriptors for TSO */
+	tmp_bdp = txq->bd.cur;
+
+	while (tmp_bdp != bdp) {
+		/* Unmap data buffers */
+		if (tmp_bdp->cbd_bufaddr &&
+		    !IS_TSO_HEADER(txq, fec32_to_cpu(tmp_bdp->cbd_bufaddr)))
+			dma_unmap_single(&fep->pdev->dev,
+					 fec32_to_cpu(tmp_bdp->cbd_bufaddr),
+					 fec16_to_cpu(tmp_bdp->cbd_datlen),
+					 DMA_TO_DEVICE);
+
+		/* Clear standard buffer descriptor fields */
+		tmp_bdp->cbd_sc = 0;
+		tmp_bdp->cbd_datlen = 0;
+		tmp_bdp->cbd_bufaddr = 0;
+
+		/* Handle extended descriptor if enabled */
+		if (fep->bufdesc_ex) {
+			ebdp = (struct bufdesc_ex *)tmp_bdp;
+			ebdp->cbd_esc = 0;
+		}
+
+		tmp_bdp = fec_enet_get_nextdesc(tmp_bdp, &txq->bd);
+	}
+
+	dev_kfree_skb_any(skb);
+
 	return ret;
 }
 
@@ -1062,7 +1106,10 @@
 	struct fec_enet_private *fep = netdev_priv(ndev);
 	u32 temp_mac[2];
 	u32 rcntl = OPT_FRAME_SIZE | 0x04;
-	u32 ecntl = 0x2; /* ETHEREN */
+	u32 ecntl = FEC_ECR_ETHEREN;
+
+	if (fep->bufdesc_ex)
+		fec_ptp_save_state(fep);
 
 	/* Whack a reset.  We should wait for this.
 	 * For i.MX6SX SOC, enet use AXI bus, we use disable MAC
@@ -1137,18 +1184,18 @@
 		    fep->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID)
 			rcntl |= (1 << 6);
 		else if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
-			rcntl |= (1 << 8);
+			rcntl |= FEC_RCR_RMII;
 		else
-			rcntl &= ~(1 << 8);
+			rcntl &= ~FEC_RCR_RMII;
 
 		/* 1G, 100M or 10M */
 		if (ndev->phydev) {
 			if (ndev->phydev->speed == SPEED_1000)
 				ecntl |= (1 << 5);
 			else if (ndev->phydev->speed == SPEED_100)
-				rcntl &= ~(1 << 9);
+				rcntl &= ~FEC_RCR_10BASET;
 			else
-				rcntl |= (1 << 9);
+				rcntl |= FEC_RCR_10BASET;
 		}
 	} else {
 #ifdef FEC_MIIGSK_ENR
@@ -1207,13 +1254,13 @@
 
 	if (fep->quirks & FEC_QUIRK_ENET_MAC) {
 		/* enable ENET endian swap */
-		ecntl |= (1 << 8);
+		ecntl |= FEC_ECR_BYTESWP;
 		/* enable ENET store and forward mode */
-		writel(1 << 8, fep->hwp + FEC_X_WMRK);
+		writel(FEC_TXWMRK_STRFWD, fep->hwp + FEC_X_WMRK);
 	}
 
 	if (fep->bufdesc_ex)
-		ecntl |= (1 << 4);
+		ecntl |= FEC_ECR_EN1588;
 
 	if (fep->quirks & FEC_QUIRK_DELAYED_CLKS_SUPPORT &&
 	    fep->rgmii_txc_dly)
@@ -1231,8 +1278,10 @@
 	writel(ecntl, fep->hwp + FEC_ECNTRL);
 	fec_enet_active_rxring(ndev);
 
-	if (fep->bufdesc_ex)
+	if (fep->bufdesc_ex) {
 		fec_ptp_start_cyclecounter(ndev);
+		fec_ptp_restore_state(fep);
+	}
 
 	/* Enable interrupts we wish to service */
 	if (fep->link)
@@ -1312,7 +1361,7 @@
 fec_stop(struct net_device *ndev)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
-	u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & (1 << 8);
+	u32 rmii_mode = readl(fep->hwp + FEC_R_CNTRL) & FEC_RCR_RMII;
 	u32 val;
 
 	/* We cannot expect a graceful transmit stop without link !!! */
@@ -1323,6 +1372,9 @@
 			netdev_err(ndev, "Graceful transmit stop did not complete!\n");
 	}
 
+	if (fep->bufdesc_ex)
+		fec_ptp_save_state(fep);
+
 	/* Whack a reset.  We should wait for this.
 	 * For i.MX6SX SOC, enet use AXI bus, we use disable MAC
 	 * instead of reset MAC itself.
@@ -1331,7 +1383,7 @@
 		if (fep->quirks & FEC_QUIRK_HAS_MULTI_QUEUES) {
 			writel(0, fep->hwp + FEC_ECNTRL);
 		} else {
-			writel(1, fep->hwp + FEC_ECNTRL);
+			writel(FEC_ECR_RESET, fep->hwp + FEC_ECNTRL);
 			udelay(10);
 		}
 	} else {
@@ -1345,11 +1397,19 @@
 	/* We have to keep ENET enabled to have MII interrupt stay working */
 	if (fep->quirks & FEC_QUIRK_ENET_MAC &&
 		!(fep->wol_flag & FEC_WOL_FLAG_SLEEP_ON)) {
-		writel(2, fep->hwp + FEC_ECNTRL);
+		writel(FEC_ECR_ETHEREN, fep->hwp + FEC_ECNTRL);
 		writel(rmii_mode, fep->hwp + FEC_R_CNTRL);
 	}
-}
 
+	if (fep->bufdesc_ex) {
+		val = readl(fep->hwp + FEC_ECNTRL);
+		val |= FEC_ECR_EN1588;
+		writel(val, fep->hwp + FEC_ECNTRL);
+
+		fec_ptp_start_cyclecounter(ndev);
+		fec_ptp_restore_state(fep);
+	}
+}
 
 static void
 fec_timeout(struct net_device *ndev, unsigned int txqueue)
@@ -1562,19 +1622,22 @@
 		fec_enet_tx_queue(ndev, i, budget);
 }
 
-static void fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq,
+static int fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq,
 				struct bufdesc *bdp, int index)
 {
 	struct page *new_page;
 	dma_addr_t phys_addr;
 
 	new_page = page_pool_dev_alloc_pages(rxq->page_pool);
-	WARN_ON(!new_page);
-	rxq->rx_skb_info[index].page = new_page;
+	if (unlikely(!new_page))
+		return -ENOMEM;
 
+	rxq->rx_skb_info[index].page = new_page;
 	rxq->rx_skb_info[index].offset = FEC_ENET_XDP_HEADROOM;
 	phys_addr = page_pool_get_dma_addr(new_page) + FEC_ENET_XDP_HEADROOM;
 	bdp->cbd_bufaddr = cpu_to_fec32(phys_addr);
+
+	return 0;
 }
 
 static u32
@@ -1669,6 +1732,7 @@
 	int cpu = smp_processor_id();
 	struct xdp_buff xdp;
 	struct page *page;
+	__fec32 cbd_bufaddr;
 	u32 sub_len = 4;
 
 #if !defined(CONFIG_M5272)
@@ -1737,12 +1801,17 @@
 
 		index = fec_enet_get_bd_index(bdp, &rxq->bd);
 		page = rxq->rx_skb_info[index].page;
+		cbd_bufaddr = bdp->cbd_bufaddr;
+		if (fec_enet_update_cbd(rxq, bdp, index)) {
+			ndev->stats.rx_dropped++;
+			goto rx_processing_done;
+		}
+
 		dma_sync_single_for_cpu(&fep->pdev->dev,
-					fec32_to_cpu(bdp->cbd_bufaddr),
+					fec32_to_cpu(cbd_bufaddr),
 					pkt_len,
 					DMA_FROM_DEVICE);
 		prefetch(page_address(page));
-		fec_enet_update_cbd(rxq, bdp, index);
 
 		if (xdp_prog) {
 			xdp_buff_clear_frags_flag(&xdp);
@@ -2406,8 +2475,6 @@
 	fep->link = 0;
 	fep->full_duplex = 0;
 
-	phy_dev->mac_managed_pm = true;
-
 	phy_attached_info(phy_dev);
 
 	return 0;
@@ -2419,10 +2486,12 @@
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct fec_enet_private *fep = netdev_priv(ndev);
 	bool suppress_preamble = false;
+	struct phy_device *phydev;
 	struct device_node *node;
 	int err = -ENXIO;
 	u32 mii_speed, holdtime;
 	u32 bus_freq;
+	int addr;
 
 	/*
 	 * The i.MX28 dual fec interfaces are not equal.
@@ -2536,6 +2605,13 @@
 		goto err_out_free_mdiobus;
 	of_node_put(node);
 
+	/* find all the PHY devices on the bus and set mac_managed_pm to true */
+	for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
+		phydev = mdiobus_get_phy(fep->mii_bus, addr);
+		if (phydev)
+			phydev->mac_managed_pm = true;
+	}
+
 	mii_cnt++;
 
 	/* save fec0 mii_bus */
@@ -3671,29 +3747,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/**
- * fec_poll_controller - FEC Poll controller function
- * @dev: The FEC network adapter
- *
- * Polled functionality used by netconsole and others in non interrupt mode
- *
- */
-static void fec_poll_controller(struct net_device *dev)
-{
-	int i;
-	struct fec_enet_private *fep = netdev_priv(dev);
-
-	for (i = 0; i < FEC_IRQ_NUM; i++) {
-		if (fep->irq[i] > 0) {
-			disable_irq(fep->irq[i]);
-			fec_enet_interrupt(fep->irq[i], dev);
-			enable_irq(fep->irq[i]);
-		}
-	}
-}
-#endif
-
 static inline void fec_enet_set_netdev_features(struct net_device *netdev,
 	netdev_features_t features)
 {
@@ -4000,9 +4053,6 @@
 	.ndo_tx_timeout		= fec_timeout,
 	.ndo_set_mac_address	= fec_set_mac_address,
 	.ndo_eth_ioctl		= phy_do_ioctl_running,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller	= fec_poll_controller,
-#endif
 	.ndo_set_features	= fec_set_features,
 	.ndo_bpf		= fec_enet_bpf,
 	.ndo_xdp_xmit		= fec_enet_xdp_xmit,
@@ -4153,6 +4203,14 @@
 	return ret;
 }
 
+static void fec_enet_deinit(struct net_device *ndev)
+{
+	struct fec_enet_private *fep = netdev_priv(ndev);
+
+	netif_napi_del(&fep->napi);
+	fec_enet_free_queue(ndev);
+}
+
 #ifdef CONFIG_OF
 static int fec_reset_phy(struct platform_device *pdev)
 {
@@ -4547,6 +4605,7 @@
 	fec_enet_mii_remove(fep);
 failed_mii_init:
 failed_irq:
+	fec_enet_deinit(ndev);
 failed_init:
 	fec_ptp_stop(pdev);
 failed_reset:
@@ -4610,6 +4669,7 @@
 	pm_runtime_put_noidle(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 
+	fec_enet_deinit(ndev);
 	free_netdev(ndev);
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
@@ -94,7 +94,7 @@
 		goto out_free;
 	}
 
-	snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
+	snprintf(bus->id, MII_BUS_ID_SIZE, "%pa", &res.start);
 	bus->priv = priv;
 
 	bus->parent = dev;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/fec_ptp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/fec_ptp.c
@@ -84,13 +84,36 @@
 #define FEC_CC_MULT	(1 << 31)
 #define FEC_COUNTER_PERIOD	(1 << 31)
 #define PPS_OUPUT_RELOAD_PERIOD	NSEC_PER_SEC
-#define FEC_CHANNLE_0		0
-#define DEFAULT_PPS_CHANNEL	FEC_CHANNLE_0
+#define DEFAULT_PPS_CHANNEL	0
 
 #define FEC_PTP_MAX_NSEC_PERIOD		4000000000ULL
 #define FEC_PTP_MAX_NSEC_COUNTER	0x80000000ULL
 
 /**
+ * fec_ptp_read - read raw cycle counter (to be used by time counter)
+ * @cc: the cyclecounter structure
+ *
+ * this function reads the cyclecounter registers and is called by the
+ * cyclecounter structure used to construct a ns counter from the
+ * arbitrary fixed point registers
+ */
+static u64 fec_ptp_read(const struct cyclecounter *cc)
+{
+	struct fec_enet_private *fep =
+		container_of(cc, struct fec_enet_private, cc);
+	u32 tempval;
+
+	tempval = readl(fep->hwp + FEC_ATIME_CTRL);
+	tempval |= FEC_T_CTRL_CAPTURE;
+	writel(tempval, fep->hwp + FEC_ATIME_CTRL);
+
+	if (fep->quirks & FEC_QUIRK_BUG_CAPTURE)
+		udelay(1);
+
+	return readl(fep->hwp + FEC_ATIME);
+}
+
+/**
  * fec_ptp_enable_pps
  * @fep: the fec_enet_private structure handle
  * @enable: enable the channel pps output
@@ -104,14 +127,13 @@
 	struct timespec64 ts;
 	u64 ns;
 
-	if (fep->pps_enable == enable)
-		return 0;
-
-	fep->pps_channel = DEFAULT_PPS_CHANNEL;
-	fep->reload_period = PPS_OUPUT_RELOAD_PERIOD;
-
 	spin_lock_irqsave(&fep->tmreg_lock, flags);
 
+	if (fep->pps_enable == enable) {
+		spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+		return 0;
+	}
+
 	if (enable) {
 		/* clear capture or output compare interrupt status if have.
 		 */
@@ -137,7 +159,7 @@
 		 * NSEC_PER_SEC - ts.tv_nsec. Add the remaining nanoseconds
 		 * to current timer would be next second.
 		 */
-		tempval = fep->cc.read(&fep->cc);
+		tempval = fec_ptp_read(&fep->cc);
 		/* Convert the ptp local counter to 1588 timestamp */
 		ns = timecounter_cyc2time(&fep->tc, tempval);
 		ts = ns_to_timespec64(ns);
@@ -212,13 +234,7 @@
 	timecounter_read(&fep->tc);
 
 	/* Get the current ptp hardware time counter */
-	temp_val = readl(fep->hwp + FEC_ATIME_CTRL);
-	temp_val |= FEC_T_CTRL_CAPTURE;
-	writel(temp_val, fep->hwp + FEC_ATIME_CTRL);
-	if (fep->quirks & FEC_QUIRK_BUG_CAPTURE)
-		udelay(1);
-
-	ptp_hc = readl(fep->hwp + FEC_ATIME);
+	ptp_hc = fec_ptp_read(&fep->cc);
 
 	/* Convert the ptp local counter to 1588 timestamp */
 	curr_time = timecounter_cyc2time(&fep->tc, ptp_hc);
@@ -273,30 +289,6 @@
 }
 
 /**
- * fec_ptp_read - read raw cycle counter (to be used by time counter)
- * @cc: the cyclecounter structure
- *
- * this function reads the cyclecounter registers and is called by the
- * cyclecounter structure used to construct a ns counter from the
- * arbitrary fixed point registers
- */
-static u64 fec_ptp_read(const struct cyclecounter *cc)
-{
-	struct fec_enet_private *fep =
-		container_of(cc, struct fec_enet_private, cc);
-	u32 tempval;
-
-	tempval = readl(fep->hwp + FEC_ATIME_CTRL);
-	tempval |= FEC_T_CTRL_CAPTURE;
-	writel(tempval, fep->hwp + FEC_ATIME_CTRL);
-
-	if (fep->quirks & FEC_QUIRK_BUG_CAPTURE)
-		udelay(1);
-
-	return readl(fep->hwp + FEC_ATIME);
-}
-
-/**
  * fec_ptp_start_cyclecounter - create the cycle counter from hw
  * @ndev: network device
  *
@@ -532,6 +524,8 @@
 	int ret = 0;
 
 	if (rq->type == PTP_CLK_REQ_PPS) {
+		fep->reload_period = PPS_OUPUT_RELOAD_PERIOD;
+
 		ret = fec_ptp_enable_pps(fep, on);
 
 		return ret;
@@ -540,10 +534,9 @@
 		if (rq->perout.flags)
 			return -EOPNOTSUPP;
 
-		if (rq->perout.index != DEFAULT_PPS_CHANNEL)
+		if (rq->perout.index != fep->pps_channel)
 			return -EOPNOTSUPP;
 
-		fep->pps_channel = DEFAULT_PPS_CHANNEL;
 		period.tv_sec = rq->perout.period.sec;
 		period.tv_nsec = rq->perout.period.nsec;
 		period_ns = timespec64_to_ns(&period);
@@ -711,12 +704,16 @@
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct fec_enet_private *fep = netdev_priv(ndev);
+	struct device_node *np = fep->pdev->dev.of_node;
 	int irq;
 	int ret;
 
 	fep->ptp_caps.owner = THIS_MODULE;
 	strscpy(fep->ptp_caps.name, "fec ptp", sizeof(fep->ptp_caps.name));
 
+	fep->pps_channel = DEFAULT_PPS_CHANNEL;
+	of_property_read_u32(np, "fsl,pps-channel", &fep->pps_channel);
+
 	fep->ptp_caps.max_adj = 250000000;
 	fep->ptp_caps.n_alarm = 0;
 	fep->ptp_caps.n_ext_ts = 0;
@@ -768,11 +765,64 @@
 	schedule_delayed_work(&fep->time_keep, HZ);
 }
 
+void fec_ptp_save_state(struct fec_enet_private *fep)
+{
+	unsigned long flags;
+	u32 atime_inc_corr;
+
+	spin_lock_irqsave(&fep->tmreg_lock, flags);
+
+	fep->ptp_saved_state.pps_enable = fep->pps_enable;
+
+	fep->ptp_saved_state.ns_phc = timecounter_read(&fep->tc);
+	fep->ptp_saved_state.ns_sys = ktime_get_ns();
+
+	fep->ptp_saved_state.at_corr = readl(fep->hwp + FEC_ATIME_CORR);
+	atime_inc_corr = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_CORR_MASK;
+	fep->ptp_saved_state.at_inc_corr = (u8)(atime_inc_corr >> FEC_T_INC_CORR_OFFSET);
+
+	spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+}
+
+/* Restore PTP functionality after a reset */
+void fec_ptp_restore_state(struct fec_enet_private *fep)
+{
+	u32 atime_inc = readl(fep->hwp + FEC_ATIME_INC) & FEC_T_INC_MASK;
+	unsigned long flags;
+	u32 counter;
+	u64 ns;
+
+	spin_lock_irqsave(&fep->tmreg_lock, flags);
+
+	/* Reset turned it off, so adjust our status flag */
+	fep->pps_enable = 0;
+
+	writel(fep->ptp_saved_state.at_corr, fep->hwp + FEC_ATIME_CORR);
+	atime_inc |= ((u32)fep->ptp_saved_state.at_inc_corr) << FEC_T_INC_CORR_OFFSET;
+	writel(atime_inc, fep->hwp + FEC_ATIME_INC);
+
+	ns = ktime_get_ns() - fep->ptp_saved_state.ns_sys + fep->ptp_saved_state.ns_phc;
+	counter = ns & fep->cc.mask;
+	writel(counter, fep->hwp + FEC_ATIME);
+	timecounter_init(&fep->tc, &fep->cc, ns);
+
+	spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+
+	/* Restart PPS if needed */
+	if (fep->ptp_saved_state.pps_enable) {
+		/* Re-enable PPS */
+		fec_ptp_enable_pps(fep, 1);
+	}
+}
+
 void fec_ptp_stop(struct platform_device *pdev)
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct fec_enet_private *fep = netdev_priv(ndev);
 
+	if (fep->pps_enable)
+		fec_ptp_enable_pps(fep, 0);
+
 	cancel_delayed_work_sync(&fep->time_keep);
 	hrtimer_cancel(&fep->perout_timer);
 	if (fep->ptp_clock)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/fman/fman.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/fman/fman.c
@@ -24,7 +24,6 @@
 
 /* General defines */
 #define FMAN_LIODN_TBL			64	/* size of LIODN table */
-#define MAX_NUM_OF_MACS			10
 #define FM_NUM_OF_FMAN_CTRL_EVENT_REGS	4
 #define BASE_RX_PORTID			0x08
 #define BASE_TX_PORTID			0x28
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/fman/fman.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/fman/fman.h
@@ -74,6 +74,9 @@
 #define BM_MAX_NUM_OF_POOLS		64 /* Buffers pools */
 #define FMAN_PORT_MAX_EXT_POOLS_NUM	8  /* External BM pools per Rx port */
 
+/* General defines */
+#define MAX_NUM_OF_MACS			10
+
 struct fman; /* FMan data */
 
 /* Enum for defining port types */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/fman/mac.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/fman/mac.c
@@ -197,55 +197,72 @@
 		err = -EINVAL;
 		goto _return_of_node_put;
 	}
+	mac_dev->fman_dev = &of_dev->dev;
 
 	/* Get the FMan cell-index */
 	err = of_property_read_u32(dev_node, "cell-index", &val);
 	if (err) {
 		dev_err(dev, "failed to read cell-index for %pOF\n", dev_node);
 		err = -EINVAL;
-		goto _return_of_node_put;
+		goto _return_dev_put;
 	}
 	/* cell-index 0 => FMan id 1 */
 	fman_id = (u8)(val + 1);
 
-	priv->fman = fman_bind(&of_dev->dev);
+	priv->fman = fman_bind(mac_dev->fman_dev);
 	if (!priv->fman) {
 		dev_err(dev, "fman_bind(%pOF) failed\n", dev_node);
 		err = -ENODEV;
-		goto _return_of_node_put;
+		goto _return_dev_put;
 	}
 
+	/* Two references have been taken in of_find_device_by_node()
+	 * and fman_bind(). Release one of them here. The second one
+	 * will be released in mac_remove().
+	 */
+	put_device(mac_dev->fman_dev);
 	of_node_put(dev_node);
+	dev_node = NULL;
 
 	/* Get the address of the memory mapped registers */
 	mac_dev->res = platform_get_mem_or_io(_of_dev, 0);
 	if (!mac_dev->res) {
 		dev_err(dev, "could not get registers\n");
-		return -EINVAL;
+		err = -EINVAL;
+		goto _return_dev_put;
 	}
 
 	err = devm_request_resource(dev, fman_get_mem_region(priv->fman),
 				    mac_dev->res);
 	if (err) {
 		dev_err_probe(dev, err, "could not request resource\n");
-		return err;
+		goto _return_dev_put;
 	}
 
 	mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start,
 				      resource_size(mac_dev->res));
 	if (!mac_dev->vaddr) {
 		dev_err(dev, "devm_ioremap() failed\n");
-		return -EIO;
+		err = -EIO;
+		goto _return_dev_put;
 	}
 
-	if (!of_device_is_available(mac_node))
-		return -ENODEV;
+	if (!of_device_is_available(mac_node)) {
+		err = -ENODEV;
+		goto _return_dev_put;
+	}
 
 	/* Get the cell-index */
 	err = of_property_read_u32(mac_node, "cell-index", &val);
 	if (err) {
 		dev_err(dev, "failed to read cell-index for %pOF\n", mac_node);
-		return -EINVAL;
+		err = -EINVAL;
+		goto _return_dev_put;
+	}
+	if (val >= MAX_NUM_OF_MACS) {
+		dev_err(dev, "cell-index value is too big for %pOF\n", mac_node);
+		err = -EINVAL;
+		goto _return_dev_put;
 	}
 	priv->cell_index = (u8)val;
 
@@ -259,22 +276,26 @@
 	if (unlikely(nph < 0)) {
 		dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n",
 			mac_node);
-		return nph;
+		err = nph;
+		goto _return_dev_put;
 	}
 
 	if (nph != ARRAY_SIZE(mac_dev->port)) {
 		dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n",
 			mac_node);
-		return -EINVAL;
+		err = -EINVAL;
+		goto _return_dev_put;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
+	/* PORT_NUM determines the size of the port array */
+	for (i = 0; i < PORT_NUM; i++) {
 		/* Find the port node */
 		dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
 		if (!dev_node) {
 			dev_err(dev, "of_parse_phandle(%pOF, fsl,fman-ports) failed\n",
 				mac_node);
-			return -EINVAL;
+			err = -EINVAL;
+			goto _return_dev_arr_put;
 		}
 
 		of_dev = of_find_device_by_node(dev_node);
@@ -282,17 +303,24 @@
 			dev_err(dev, "of_find_device_by_node(%pOF) failed\n",
 				dev_node);
 			err = -EINVAL;
-			goto _return_of_node_put;
+			goto _return_dev_arr_put;
 		}
+		mac_dev->fman_port_devs[i] = &of_dev->dev;
 
-		mac_dev->port[i] = fman_port_bind(&of_dev->dev);
+		mac_dev->port[i] = fman_port_bind(mac_dev->fman_port_devs[i]);
 		if (!mac_dev->port[i]) {
 			dev_err(dev, "dev_get_drvdata(%pOF) failed\n",
 				dev_node);
 			err = -EINVAL;
-			goto _return_of_node_put;
+			goto _return_dev_arr_put;
 		}
+		/* Two references have been taken in of_find_device_by_node()
+		 * and fman_port_bind(). Release one of them here. The second
+		 * one will be released in mac_remove().
+		 */
+		put_device(mac_dev->fman_port_devs[i]);
 		of_node_put(dev_node);
+		dev_node = NULL;
 	}
 
 	/* Get the PHY connection type */
@@ -312,7 +340,7 @@
 
 	err = init(mac_dev, mac_node, &params);
 	if (err < 0)
-		return err;
+		goto _return_dev_arr_put;
 
 	if (!is_zero_ether_addr(mac_dev->addr))
 		dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr);
@@ -327,6 +355,12 @@
 
 	return err;
 
+_return_dev_arr_put:
+	/* mac_dev is kzalloc'ed */
+	for (i = 0; i < PORT_NUM; i++)
+		put_device(mac_dev->fman_port_devs[i]);
+_return_dev_put:
+	put_device(mac_dev->fman_dev);
 _return_of_node_put:
 	of_node_put(dev_node);
 	return err;
@@ -335,6 +369,11 @@
 static void mac_remove(struct platform_device *pdev)
 {
 	struct mac_device *mac_dev = platform_get_drvdata(pdev);
+	int		   i;
+
+	for (i = 0; i < PORT_NUM; i++)
+		put_device(mac_dev->fman_port_devs[i]);
+	put_device(mac_dev->fman_dev);
 
 	platform_device_unregister(mac_dev->priv->eth_dev);
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/fman/mac.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/fman/mac.h
@@ -19,12 +19,13 @@
 struct fman_mac;
 struct mac_priv_s;
 
+#define PORT_NUM 2
 struct mac_device {
 	void __iomem		*vaddr;
 	struct device		*dev;
 	struct resource		*res;
 	u8			 addr[ETH_ALEN];
-	struct fman_port	*port[2];
+	struct fman_port	*port[PORT_NUM];
 	struct phylink		*phylink;
 	struct phylink_config	phylink_config;
 	phy_interface_t		phy_if;
@@ -52,6 +53,9 @@
 
 	struct fman_mac		*fman_mac;
 	struct mac_priv_s	*priv;
+
+	struct device		*fman_dev;
+	struct device		*fman_port_devs[PORT_NUM];
 };
 
 static inline struct mac_device
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
@@ -126,7 +126,7 @@
 	 * we get is an int, and the odds of multiple bitbang mdio buses
 	 * is low enough that it's not worth going too crazy.
 	 */
-	snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
+	snprintf(bus->id, MII_BUS_ID_SIZE, "%pa", &res.start);
 
 	data = of_get_property(np, "fsl,mdio-pin", &len);
 	if (!data || len != 4)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/google/gve/gve.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/google/gve/gve.h
@@ -678,6 +678,7 @@
 	union gve_adminq_command *adminq;
 	dma_addr_t adminq_bus_addr;
 	struct dma_pool *adminq_pool;
+	struct mutex adminq_lock; /* Protects adminq command execution */
 	u32 adminq_mask; /* masks prod_cnt to adminq size */
 	u32 adminq_prod_cnt; /* free-running count of AQ cmds executed */
 	u32 adminq_cmd_fail; /* free-running count of AQ cmds failed */
@@ -1051,6 +1052,7 @@
 void gve_xdp_tx_flush(struct gve_priv *priv, u32 xdp_qid);
 bool gve_tx_poll(struct gve_notify_block *block, int budget);
 bool gve_xdp_poll(struct gve_notify_block *block, int budget);
+int gve_xsk_tx_poll(struct gve_notify_block *block, int budget);
 int gve_tx_alloc_rings(struct gve_priv *priv, int start_id, int num_rings);
 void gve_tx_free_rings_gqi(struct gve_priv *priv, int start_id, int num_rings);
 u32 gve_tx_load_event_counter(struct gve_priv *priv,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/google/gve/gve_adminq.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/google/gve/gve_adminq.c
@@ -239,6 +239,7 @@
 			    &priv->reg_bar0->adminq_base_address_lo);
 		iowrite32be(GVE_DRIVER_STATUS_RUN_MASK, &priv->reg_bar0->driver_status);
 	}
+	mutex_init(&priv->adminq_lock);
 	gve_set_admin_queue_ok(priv);
 	return 0;
 }
@@ -466,28 +467,29 @@
 	return 0;
 }
 
-/* This function is not threadsafe - the caller is responsible for any
- * necessary locks.
- * The caller is also responsible for making sure there are no commands
- * waiting to be executed.
- */
 static int gve_adminq_execute_cmd(struct gve_priv *priv,
 				  union gve_adminq_command *cmd_orig)
 {
 	u32 tail, head;
 	int err;
 
+	mutex_lock(&priv->adminq_lock);
 	tail = ioread32be(&priv->reg_bar0->adminq_event_counter);
 	head = priv->adminq_prod_cnt;
-	if (tail != head)
-		// This is not a valid path
-		return -EINVAL;
+	if (tail != head) {
+		err = -EINVAL;
+		goto out;
+	}
 
 	err = gve_adminq_issue_cmd(priv, cmd_orig);
 	if (err)
-		return err;
+		goto out;
+
+	err = gve_adminq_kick_and_wait(priv);
 
-	return gve_adminq_kick_and_wait(priv);
+out:
+	mutex_unlock(&priv->adminq_lock);
+	return err;
 }
 
 /* The device specifies that the management vector can either be the first irq
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/google/gve/gve_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/google/gve/gve_main.c
@@ -275,6 +275,14 @@
 
 	if (block->rx) {
 		work_done = gve_rx_poll(block, budget);
+
+		/* Poll XSK TX as part of RX NAPI. Setup re-poll based on max of
+		 * TX and RX work done.
+		 */
+		if (priv->xdp_prog)
+			work_done = max_t(int, work_done,
+					  gve_xsk_tx_poll(block, budget));
+
 		reschedule |= work_done == budget;
 	}
 
@@ -1540,8 +1548,8 @@
 	if (err)
 		return err;
 
-	/* If XDP prog is not installed, return */
-	if (!priv->xdp_prog)
+	/* If XDP prog is not installed or interface is down, return. */
+	if (!priv->xdp_prog || !netif_running(dev))
 		return 0;
 
 	rx = &priv->rx[qid];
@@ -1586,21 +1594,16 @@
 	if (qid >= priv->rx_cfg.num_queues)
 		return -EINVAL;
 
-	/* If XDP prog is not installed, unmap DMA and return */
-	if (!priv->xdp_prog)
-		goto done;
-
-	tx_qid = gve_xdp_tx_queue_id(priv, qid);
-	if (!netif_running(dev)) {
-		priv->rx[qid].xsk_pool = NULL;
-		xdp_rxq_info_unreg(&priv->rx[qid].xsk_rxq);
-		priv->tx[tx_qid].xsk_pool = NULL;
+	/* If XDP prog is not installed or interface is down, unmap DMA and
+	 * return.
+	 */
+	if (!priv->xdp_prog || !netif_running(dev))
 		goto done;
-	}
 
 	napi_rx = &priv->ntfy_blocks[priv->rx[qid].ntfy_id].napi;
 	napi_disable(napi_rx); /* make sure current rx poll is done */
 
+	tx_qid = gve_xdp_tx_queue_id(priv, qid);
 	napi_tx = &priv->ntfy_blocks[priv->tx[tx_qid].ntfy_id].napi;
 	napi_disable(napi_tx); /* make sure current tx poll is done */
 
@@ -1626,24 +1629,20 @@
 static int gve_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
 {
 	struct gve_priv *priv = netdev_priv(dev);
-	int tx_queue_id = gve_xdp_tx_queue_id(priv, queue_id);
+	struct napi_struct *napi;
+
+	if (!gve_get_napi_enabled(priv))
+		return -ENETDOWN;
 
 	if (queue_id >= priv->rx_cfg.num_queues || !priv->xdp_prog)
 		return -EINVAL;
 
-	if (flags & XDP_WAKEUP_TX) {
-		struct gve_tx_ring *tx = &priv->tx[tx_queue_id];
-		struct napi_struct *napi =
-			&priv->ntfy_blocks[tx->ntfy_id].napi;
-
-		if (!napi_if_scheduled_mark_missed(napi)) {
-			/* Call local_bh_enable to trigger SoftIRQ processing */
-			local_bh_disable();
-			napi_schedule(napi);
-			local_bh_enable();
-		}
-
-		tx->xdp_xsk_wakeup++;
+	napi = &priv->ntfy_blocks[gve_rx_idx_to_ntfy(priv, queue_id)].napi;
+	if (!napi_if_scheduled_mark_missed(napi)) {
+		/* Call local_bh_enable to trigger SoftIRQ processing */
+		local_bh_disable();
+		napi_schedule(napi);
+		local_bh_enable();
 	}
 
 	return 0;
@@ -1769,6 +1768,9 @@
 
 	gve_clear_napi_enabled(priv);
 	gve_clear_report_stats(priv);
+
+	/* Make sure that all traffic is finished processing. */
+	synchronize_net();
 }
 
 static void gve_turnup(struct gve_priv *priv)
@@ -2021,14 +2023,18 @@
 
 static void gve_set_netdev_xdp_features(struct gve_priv *priv)
 {
+	xdp_features_t xdp_features;
+
 	if (priv->queue_format == GVE_GQI_QPL_FORMAT) {
-		priv->dev->xdp_features = NETDEV_XDP_ACT_BASIC;
-		priv->dev->xdp_features |= NETDEV_XDP_ACT_REDIRECT;
-		priv->dev->xdp_features |= NETDEV_XDP_ACT_NDO_XMIT;
-		priv->dev->xdp_features |= NETDEV_XDP_ACT_XSK_ZEROCOPY;
+		xdp_features = NETDEV_XDP_ACT_BASIC;
+		xdp_features |= NETDEV_XDP_ACT_REDIRECT;
+		xdp_features |= NETDEV_XDP_ACT_NDO_XMIT;
+		xdp_features |= NETDEV_XDP_ACT_XSK_ZEROCOPY;
 	} else {
-		priv->dev->xdp_features = 0;
+		xdp_features = 0;
 	}
+
+	xdp_set_features_flag(priv->dev, xdp_features);
 }
 
 static int gve_init_priv(struct gve_priv *priv, bool skip_describe_device)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/google/gve/gve_rx_dqo.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/google/gve/gve_rx_dqo.c
@@ -506,11 +506,13 @@
 	skb_set_hash(skb, le32_to_cpu(compl_desc->hash), hash_type);
 }
 
-static void gve_rx_free_skb(struct gve_rx_ring *rx)
+static void gve_rx_free_skb(struct napi_struct *napi, struct gve_rx_ring *rx)
 {
 	if (!rx->ctx.skb_head)
 		return;
 
+	if (rx->ctx.skb_head == napi->skb)
+		napi->skb = NULL;
 	dev_kfree_skb_any(rx->ctx.skb_head);
 	rx->ctx.skb_head = NULL;
 	rx->ctx.skb_tail = NULL;
@@ -783,7 +785,7 @@
 
 		err = gve_rx_dqo(napi, rx, compl_desc, rx->q_num);
 		if (err < 0) {
-			gve_rx_free_skb(rx);
+			gve_rx_free_skb(napi, rx);
 			u64_stats_update_begin(&rx->statss);
 			if (err == -ENOMEM)
 				rx->rx_skb_alloc_fail++;
@@ -826,7 +828,7 @@
 
 		/* gve_rx_complete_skb() will consume skb if successful */
 		if (gve_rx_complete_skb(rx, napi, compl_desc, feat) != 0) {
-			gve_rx_free_skb(rx);
+			gve_rx_free_skb(napi, rx);
 			u64_stats_update_begin(&rx->statss);
 			rx->rx_desc_err_dropped_pkt++;
 			u64_stats_update_end(&rx->statss);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/google/gve/gve_tx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/google/gve/gve_tx.c
@@ -158,15 +158,16 @@
 			      u32 to_do)
 {
 	struct gve_tx_buffer_state *info;
-	u32 clean_end = tx->done + to_do;
 	u64 pkts = 0, bytes = 0;
 	size_t space_freed = 0;
 	u32 xsk_complete = 0;
 	u32 idx;
+	int i;
 
-	for (; tx->done < clean_end; tx->done++) {
+	for (i = 0; i < to_do; i++) {
 		idx = tx->done & tx->mask;
 		info = &tx->info[idx];
+		tx->done++;
 
 		if (unlikely(!info->xdp.size))
 			continue;
@@ -776,9 +777,12 @@
 	struct gve_tx_ring *tx;
 	int i, err = 0, qid;
 
-	if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
+	if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK) || !priv->xdp_prog)
 		return -EINVAL;
 
+	if (!gve_get_napi_enabled(priv))
+		return -ENETDOWN;
+
 	qid = gve_xdp_tx_queue_id(priv,
 				  smp_processor_id() % priv->num_xdp_queues);
 
@@ -917,33 +921,41 @@
 	return sent;
 }
 
+int gve_xsk_tx_poll(struct gve_notify_block *rx_block, int budget)
+{
+	struct gve_rx_ring *rx = rx_block->rx;
+	struct gve_priv *priv = rx->gve;
+	struct gve_tx_ring *tx;
+	int sent = 0;
+
+	tx = &priv->tx[gve_xdp_tx_queue_id(priv, rx->q_num)];
+	if (tx->xsk_pool) {
+		sent = gve_xsk_tx(priv, tx, budget);
+
+		u64_stats_update_begin(&tx->statss);
+		tx->xdp_xsk_sent += sent;
+		u64_stats_update_end(&tx->statss);
+		if (xsk_uses_need_wakeup(tx->xsk_pool))
+			xsk_set_tx_need_wakeup(tx->xsk_pool);
+	}
+
+	return sent;
+}
+
 bool gve_xdp_poll(struct gve_notify_block *block, int budget)
 {
 	struct gve_priv *priv = block->priv;
 	struct gve_tx_ring *tx = block->tx;
 	u32 nic_done;
-	bool repoll;
 	u32 to_do;
 
 	/* Find out how much work there is to be done */
 	nic_done = gve_tx_load_event_counter(priv, tx);
 	to_do = min_t(u32, (nic_done - tx->done), budget);
 	gve_clean_xdp_done(priv, tx, to_do);
-	repoll = nic_done != tx->done;
-
-	if (tx->xsk_pool) {
-		int sent = gve_xsk_tx(priv, tx, budget);
-
-		u64_stats_update_begin(&tx->statss);
-		tx->xdp_xsk_sent += sent;
-		u64_stats_update_end(&tx->statss);
-		repoll |= (sent == budget);
-		if (xsk_uses_need_wakeup(tx->xsk_pool))
-			xsk_set_tx_need_wakeup(tx->xsk_pool);
-	}
 
 	/* If we still have work we want to repoll */
-	return repoll;
+	return nic_done != tx->done;
 }
 
 bool gve_tx_poll(struct gve_notify_block *block, int budget)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/google/gve/gve_tx_dqo.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/google/gve/gve_tx_dqo.c
@@ -501,28 +501,18 @@
 	if (unlikely(skb_shinfo(skb)->gso_size < GVE_TX_MIN_TSO_MSS_DQO))
 		return -1;
 
+	if (!(skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)))
+		return -EINVAL;
+
 	/* Needed because we will modify header. */
 	err = skb_cow_head(skb, 0);
 	if (err < 0)
 		return err;
 
 	tcp = tcp_hdr(skb);
-
-	/* Remove payload length from checksum. */
 	paylen = skb->len - skb_transport_offset(skb);
-
-	switch (skb_shinfo(skb)->gso_type) {
-	case SKB_GSO_TCPV4:
-	case SKB_GSO_TCPV6:
-		csum_replace_by_diff(&tcp->check,
-				     (__force __wsum)htonl(paylen));
-
-		/* Compute length of segmentation header. */
-		header_len = skb_tcp_all_headers(skb);
-		break;
-	default:
-		return -EINVAL;
-	}
+	csum_replace_by_diff(&tcp->check, (__force __wsum)htonl(paylen));
+	header_len = skb_tcp_all_headers(skb);
 
 	if (unlikely(header_len > GVE_TX_MAX_HDR_SIZE_DQO))
 		return -EINVAL;
@@ -822,22 +812,42 @@
 	const int header_len = skb_tcp_all_headers(skb);
 	const int gso_size = shinfo->gso_size;
 	int cur_seg_num_bufs;
+	int prev_frag_size;
 	int cur_seg_size;
 	int i;
 
 	cur_seg_size = skb_headlen(skb) - header_len;
+	prev_frag_size = skb_headlen(skb);
 	cur_seg_num_bufs = cur_seg_size > 0;
 
 	for (i = 0; i < shinfo->nr_frags; i++) {
 		if (cur_seg_size >= gso_size) {
 			cur_seg_size %= gso_size;
 			cur_seg_num_bufs = cur_seg_size > 0;
+
+			if (prev_frag_size > GVE_TX_MAX_BUF_SIZE_DQO) {
+				int prev_frag_remain = prev_frag_size %
+					GVE_TX_MAX_BUF_SIZE_DQO;
+
+				/* If the last descriptor of the previous frag
+				 * is less than cur_seg_size, the segment will
+				 * span two descriptors in the previous frag.
+				 * Since max gso size (9728) is less than
+				 * GVE_TX_MAX_BUF_SIZE_DQO, it is impossible
+				 * for the segment to span more than two
+				 * descriptors.
+				 */
+				if (prev_frag_remain &&
+				    cur_seg_size > prev_frag_remain)
+					cur_seg_num_bufs++;
+			}
 		}
 
 		if (unlikely(++cur_seg_num_bufs > max_bufs_per_seg))
 			return false;
 
-		cur_seg_size += skb_frag_size(&shinfo->frags[i]);
+		prev_frag_size = skb_frag_size(&shinfo->frags[i]);
+		cur_seg_size += prev_frag_size;
 	}
 
 	return true;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hip04_eth.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hip04_eth.c
@@ -947,6 +947,7 @@
 	priv->tx_coalesce_timer.function = tx_done;
 
 	priv->map = syscon_node_to_regmap(arg.np);
+	of_node_put(arg.np);
 	if (IS_ERR(priv->map)) {
 		dev_warn(d, "no syscon hisilicon,hip04-ppe\n");
 		ret = PTR_ERR(priv->map);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -933,6 +933,7 @@
 			mac_cb->cpld_ctrl = NULL;
 		} else {
 			syscon = syscon_node_to_regmap(cpld_args.np);
+			of_node_put(cpld_args.np);
 			if (IS_ERR_OR_NULL(syscon)) {
 				dev_dbg(mac_cb->dev, "no cpld-syscon found!\n");
 				mac_cb->cpld_ctrl = NULL;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/Makefile
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/Makefile
@@ -15,15 +15,14 @@
 
 hns3-$(CONFIG_HNS3_DCB) += hns3_dcbnl.o
 
-obj-$(CONFIG_HNS3_HCLGEVF) += hclgevf.o
+obj-$(CONFIG_HNS3_HCLGEVF) += hclgevf.o hclge-common.o
 
-hclgevf-objs = hns3vf/hclgevf_main.o hns3vf/hclgevf_mbx.o  hns3vf/hclgevf_devlink.o hns3vf/hclgevf_regs.o \
-		hns3_common/hclge_comm_cmd.o hns3_common/hclge_comm_rss.o hns3_common/hclge_comm_tqp_stats.o
+hclge-common-objs += hns3_common/hclge_comm_cmd.o hns3_common/hclge_comm_rss.o hns3_common/hclge_comm_tqp_stats.o
 
-obj-$(CONFIG_HNS3_HCLGE) += hclge.o
+hclgevf-objs = hns3vf/hclgevf_main.o hns3vf/hclgevf_mbx.o  hns3vf/hclgevf_devlink.o hns3vf/hclgevf_regs.o
+
+obj-$(CONFIG_HNS3_HCLGE) += hclge.o hclge-common.o
 hclge-objs = hns3pf/hclge_main.o hns3pf/hclge_mdio.o hns3pf/hclge_tm.o hns3pf/hclge_regs.o \
 		hns3pf/hclge_mbx.o hns3pf/hclge_err.o  hns3pf/hclge_debugfs.o hns3pf/hclge_ptp.o hns3pf/hclge_devlink.o \
-		hns3_common/hclge_comm_cmd.o hns3_common/hclge_comm_rss.o hns3_common/hclge_comm_tqp_stats.o
-
 
 hclge-$(CONFIG_HNS3_DCB) += hns3pf/hclge_dcb.o
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hnae3.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hnae3.c
@@ -25,8 +25,11 @@
 		pci_id = pci_match_id(ae_algo->pdev_id_table, ae_dev->pdev);
 		if (!pci_id)
 			continue;
-		if (IS_ENABLED(CONFIG_PCI_IOV))
+		if (IS_ENABLED(CONFIG_PCI_IOV)) {
+			device_lock(&ae_dev->pdev->dev);
 			pci_disable_sriov(ae_dev->pdev);
+			device_unlock(&ae_dev->pdev->dev);
+		}
 	}
 }
 EXPORT_SYMBOL(hnae3_unregister_ae_algo_prepare);
@@ -37,6 +40,21 @@
  */
 static DEFINE_MUTEX(hnae3_common_lock);
 
+/* ensure the drivers being unloaded one by one */
+static DEFINE_MUTEX(hnae3_unload_lock);
+
+void hnae3_acquire_unload_lock(void)
+{
+	mutex_lock(&hnae3_unload_lock);
+}
+EXPORT_SYMBOL(hnae3_acquire_unload_lock);
+
+void hnae3_release_unload_lock(void)
+{
+	mutex_unlock(&hnae3_unload_lock);
+}
+EXPORT_SYMBOL(hnae3_release_unload_lock);
+
 static bool hnae3_client_match(enum hnae3_client_type client_type)
 {
 	if (client_type == HNAE3_CLIENT_KNIC ||
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -895,15 +895,12 @@
 		struct hnae3_roce_private_info rinfo;
 	};
 
-	u32 numa_node_mask;	/* for multi-chip support */
+	nodemask_t numa_node_mask; /* for multi-chip support */
 
 	enum hnae3_port_base_vlan_state port_base_vlan_state;
 
 	u8 netdev_flags;
 	struct dentry *hnae3_dbgfs;
-	/* protects concurrent contention between debugfs commands */
-	struct mutex dbgfs_lock;
-	char **dbgfs_buf;
 
 	/* Network interface message level enabled bits */
 	u32 msg_enable;
@@ -951,4 +948,6 @@
 void hnae3_set_client_init_flag(struct hnae3_client *client,
 				struct hnae3_ae_dev *ae_dev,
 				unsigned int inited);
+void hnae3_acquire_unload_lock(void);
+void hnae3_release_unload_lock(void);
 #endif
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c
@@ -48,6 +48,7 @@
 	else
 		desc->flag &= cpu_to_le16(~HCLGE_COMM_CMD_FLAG_WR);
 }
+EXPORT_SYMBOL_GPL(hclge_comm_cmd_reuse_desc);
 
 static void hclge_comm_set_default_capability(struct hnae3_ae_dev *ae_dev,
 					      bool is_pf)
@@ -72,6 +73,7 @@
 	if (is_read)
 		desc->flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_WR);
 }
+EXPORT_SYMBOL_GPL(hclge_comm_cmd_setup_basic_desc);
 
 int hclge_comm_firmware_compat_config(struct hnae3_ae_dev *ae_dev,
 				      struct hclge_comm_hw *hw, bool en)
@@ -509,6 +511,7 @@
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_cmd_send);
 
 static void hclge_comm_cmd_uninit_regs(struct hclge_comm_hw *hw)
 {
@@ -545,6 +548,7 @@
 	hclge_comm_free_cmd_desc(&cmdq->csq);
 	hclge_comm_free_cmd_desc(&cmdq->crq);
 }
+EXPORT_SYMBOL_GPL(hclge_comm_cmd_uninit);
 
 int hclge_comm_cmd_queue_init(struct pci_dev *pdev, struct hclge_comm_hw *hw)
 {
@@ -583,6 +587,7 @@
 	hclge_comm_free_cmd_desc(&hw->cmq.csq);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_cmd_queue_init);
 
 int hclge_comm_cmd_init(struct hnae3_ae_dev *ae_dev, struct hclge_comm_hw *hw,
 			u32 *fw_version, bool is_pf,
@@ -653,3 +658,8 @@
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_cmd_init);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("HNS3: Hisilicon Ethernet PF/VF Common Library");
+MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_rss.c
@@ -62,6 +62,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_rss_init_cfg);
 
 void hclge_comm_get_rss_tc_info(u16 rss_size, u8 hw_tc_map, u16 *tc_offset,
 				u16 *tc_valid, u16 *tc_size)
@@ -78,6 +79,7 @@
 		tc_offset[i] = (hw_tc_map & BIT(i)) ? rss_size * i : 0;
 	}
 }
+EXPORT_SYMBOL_GPL(hclge_comm_get_rss_tc_info);
 
 int hclge_comm_set_rss_tc_mode(struct hclge_comm_hw *hw, u16 *tc_offset,
 			       u16 *tc_valid, u16 *tc_size)
@@ -113,6 +115,7 @@
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_set_rss_tc_mode);
 
 int hclge_comm_set_rss_hash_key(struct hclge_comm_rss_cfg *rss_cfg,
 				struct hclge_comm_hw *hw, const u8 *key,
@@ -143,6 +146,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_set_rss_hash_key);
 
 int hclge_comm_set_rss_tuple(struct hnae3_ae_dev *ae_dev,
 			     struct hclge_comm_hw *hw,
@@ -185,11 +189,13 @@
 	rss_cfg->rss_tuple_sets.ipv6_fragment_en = req->ipv6_fragment_en;
 	return 0;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_set_rss_tuple);
 
 u32 hclge_comm_get_rss_key_size(struct hnae3_handle *handle)
 {
 	return HCLGE_COMM_RSS_KEY_SIZE;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_get_rss_key_size);
 
 int hclge_comm_parse_rss_hfunc(struct hclge_comm_rss_cfg *rss_cfg,
 			       const u8 hfunc, u8 *hash_algo)
@@ -217,6 +223,7 @@
 	for (i = 0; i < ae_dev->dev_specs.rss_ind_tbl_size; i++)
 		rss_cfg->rss_indirection_tbl[i] = i % rss_cfg->rss_size;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_rss_indir_init_cfg);
 
 int hclge_comm_get_rss_tuple(struct hclge_comm_rss_cfg *rss_cfg, int flow_type,
 			     u8 *tuple_sets)
@@ -250,6 +257,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_get_rss_tuple);
 
 static void
 hclge_comm_append_rss_msb_info(struct hclge_comm_rss_ind_tbl_cmd *req,
@@ -304,6 +312,7 @@
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_set_rss_indir_table);
 
 int hclge_comm_set_rss_input_tuple(struct hclge_comm_hw *hw,
 				   struct hclge_comm_rss_cfg *rss_cfg)
@@ -332,6 +341,7 @@
 			"failed to configure rss input, ret = %d.\n", ret);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_set_rss_input_tuple);
 
 void hclge_comm_get_rss_hash_info(struct hclge_comm_rss_cfg *rss_cfg, u8 *key,
 				  u8 *hfunc)
@@ -355,6 +365,7 @@
 	if (key)
 		memcpy(key, rss_cfg->rss_hash_key, HCLGE_COMM_RSS_KEY_SIZE);
 }
+EXPORT_SYMBOL_GPL(hclge_comm_get_rss_hash_info);
 
 void hclge_comm_get_rss_indir_tbl(struct hclge_comm_rss_cfg *rss_cfg,
 				  u32 *indir, u16 rss_ind_tbl_size)
@@ -367,6 +378,7 @@
 	for (i = 0; i < rss_ind_tbl_size; i++)
 		indir[i] = rss_cfg->rss_indirection_tbl[i];
 }
+EXPORT_SYMBOL_GPL(hclge_comm_get_rss_indir_tbl);
 
 int hclge_comm_set_rss_algo_key(struct hclge_comm_hw *hw, const u8 hfunc,
 				const u8 *key)
@@ -408,6 +420,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_set_rss_algo_key);
 
 static u8 hclge_comm_get_rss_hash_bits(struct ethtool_rxnfc *nfc)
 {
@@ -502,3 +515,4 @@
 
 	return tuple_data;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_convert_rss_tuple);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_tqp_stats.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_tqp_stats.c
@@ -26,6 +26,7 @@
 
 	return buff;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_tqps_get_stats);
 
 int hclge_comm_tqps_get_sset_count(struct hnae3_handle *handle)
 {
@@ -33,6 +34,7 @@
 
 	return kinfo->num_tqps * HCLGE_COMM_QUEUE_PAIR_SIZE;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_tqps_get_sset_count);
 
 u8 *hclge_comm_tqps_get_strings(struct hnae3_handle *handle, u8 *data)
 {
@@ -56,6 +58,7 @@
 
 	return buff;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_tqps_get_strings);
 
 int hclge_comm_tqps_update_stats(struct hnae3_handle *handle,
 				 struct hclge_comm_hw *hw)
@@ -85,7 +88,7 @@
 		hclge_comm_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_TX_STATS,
 						true);
 
-		desc.data[0] = cpu_to_le32(tqp->index & 0x1ff);
+		desc.data[0] = cpu_to_le32(tqp->index);
 		ret = hclge_comm_cmd_send(hw, &desc, 1);
 		if (ret) {
 			dev_err(&hw->cmq.csq.pdev->dev,
@@ -99,6 +102,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(hclge_comm_tqps_update_stats);
 
 void hclge_comm_reset_tqp_stats(struct hnae3_handle *handle)
 {
@@ -113,3 +117,4 @@
 		memset(&tqp->tqp_stats, 0, sizeof(tqp->tqp_stats));
 	}
 }
+EXPORT_SYMBOL_GPL(hclge_comm_reset_tqp_stats);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3_dcbnl.c
@@ -76,7 +76,7 @@
 	if (hns3_nic_resetting(ndev))
 		return -EBUSY;
 
-	if (h->kinfo.dcb_ops->ieee_setapp)
+	if (h->kinfo.dcb_ops->ieee_delapp)
 		return h->kinfo.dcb_ops->ieee_delapp(h, app);
 
 	return -EOPNOTSUPP;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
@@ -1258,69 +1258,55 @@
 static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
 			     size_t count, loff_t *ppos)
 {
-	struct hns3_dbg_data *dbg_data = filp->private_data;
+	char *buf = filp->private_data;
+
+	return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
+}
+
+static int hns3_dbg_open(struct inode *inode, struct file *filp)
+{
+	struct hns3_dbg_data *dbg_data = inode->i_private;
 	struct hnae3_handle *handle = dbg_data->handle;
 	struct hns3_nic_priv *priv = handle->priv;
-	ssize_t size = 0;
-	char **save_buf;
-	char *read_buf;
 	u32 index;
+	char *buf;
 	int ret;
 
+	if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
+	    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
+		return -EBUSY;
+
 	ret = hns3_dbg_get_cmd_index(dbg_data, &index);
 	if (ret)
 		return ret;
 
-	mutex_lock(&handle->dbgfs_lock);
-	save_buf = &handle->dbgfs_buf[index];
-
-	if (!test_bit(HNS3_NIC_STATE_INITED, &priv->state) ||
-	    test_bit(HNS3_NIC_STATE_RESETTING, &priv->state)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
-	if (*save_buf) {
-		read_buf = *save_buf;
-	} else {
-		read_buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL);
-		if (!read_buf) {
-			ret = -ENOMEM;
-			goto out;
-		}
-
-		/* save the buffer addr until the last read operation */
-		*save_buf = read_buf;
-
-		/* get data ready for the first time to read */
-		ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd,
-					read_buf, hns3_dbg_cmd[index].buf_len);
-		if (ret)
-			goto out;
-	}
+	buf = kvzalloc(hns3_dbg_cmd[index].buf_len, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
 
-	size = simple_read_from_buffer(buffer, count, ppos, read_buf,
-				       strlen(read_buf));
-	if (size > 0) {
-		mutex_unlock(&handle->dbgfs_lock);
-		return size;
+	ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd,
+				buf, hns3_dbg_cmd[index].buf_len);
+	if (ret) {
+		kvfree(buf);
+		return ret;
 	}
 
-out:
-	/* free the buffer for the last read operation */
-	if (*save_buf) {
-		kvfree(*save_buf);
-		*save_buf = NULL;
-	}
+	filp->private_data = buf;
+	return 0;
+}
 
-	mutex_unlock(&handle->dbgfs_lock);
-	return ret;
+static int hns3_dbg_release(struct inode *inode, struct file *filp)
+{
+	kvfree(filp->private_data);
+	filp->private_data = NULL;
+	return 0;
 }
 
 static const struct file_operations hns3_dbg_fops = {
 	.owner = THIS_MODULE,
-	.open  = simple_open,
+	.open  = hns3_dbg_open,
 	.read  = hns3_dbg_read,
+	.release = hns3_dbg_release,
 };
 
 static int hns3_dbg_bd_file_init(struct hnae3_handle *handle, u32 cmd)
@@ -1377,13 +1363,6 @@
 	int ret;
 	u32 i;
 
-	handle->dbgfs_buf = devm_kcalloc(&handle->pdev->dev,
-					 ARRAY_SIZE(hns3_dbg_cmd),
-					 sizeof(*handle->dbgfs_buf),
-					 GFP_KERNEL);
-	if (!handle->dbgfs_buf)
-		return -ENOMEM;
-
 	hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry =
 				debugfs_create_dir(name, hns3_dbgfs_root);
 	handle->hnae3_dbgfs = hns3_dbg_dentry[HNS3_DBG_DENTRY_COMMON].dentry;
@@ -1393,8 +1372,6 @@
 			debugfs_create_dir(hns3_dbg_dentry[i].name,
 					   handle->hnae3_dbgfs);
 
-	mutex_init(&handle->dbgfs_lock);
-
 	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) {
 		if ((hns3_dbg_cmd[i].cmd == HNAE3_DBG_CMD_TM_NODES &&
 		     ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) ||
@@ -1423,24 +1400,13 @@
 out:
 	debugfs_remove_recursive(handle->hnae3_dbgfs);
 	handle->hnae3_dbgfs = NULL;
-	mutex_destroy(&handle->dbgfs_lock);
 	return ret;
 }
 
 void hns3_dbg_uninit(struct hnae3_handle *handle)
 {
-	u32 i;
-
 	debugfs_remove_recursive(handle->hnae3_dbgfs);
 	handle->hnae3_dbgfs = NULL;
-
-	for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++)
-		if (handle->dbgfs_buf[i]) {
-			kvfree(handle->dbgfs_buf[i]);
-			handle->dbgfs_buf[i] = NULL;
-		}
-
-	mutex_destroy(&handle->dbgfs_lock);
 }
 
 void hns3_dbg_register_debugfs(const char *debugfs_dir_name)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
@@ -2456,7 +2456,6 @@
 			return ret;
 	}
 
-	netdev->features = features;
 	return 0;
 }
 
@@ -3539,6 +3538,9 @@
 		ret = hns3_alloc_and_attach_buffer(ring, i);
 		if (ret)
 			goto out_buffer_fail;
+
+		if (!(i % HNS3_RESCHED_BD_NUM))
+			cond_resched();
 	}
 
 	return 0;
@@ -5111,6 +5113,7 @@
 		}
 
 		u64_stats_init(&priv->ring[i].syncp);
+		cond_resched();
 	}
 
 	return 0;
@@ -5724,6 +5727,9 @@
 	struct net_device *netdev = handle->kinfo.netdev;
 	struct hns3_nic_priv *priv = netdev_priv(netdev);
 
+	if (!test_bit(HNS3_NIC_STATE_DOWN, &priv->state))
+		hns3_nic_net_stop(netdev);
+
 	if (!test_and_clear_bit(HNS3_NIC_STATE_INITED, &priv->state)) {
 		netdev_warn(netdev, "already uninitialized\n");
 		return 0;
@@ -6000,9 +6006,11 @@
  */
 static void __exit hns3_exit_module(void)
 {
+	hnae3_acquire_unload_lock();
 	pci_unregister_driver(&hns3_driver);
 	hnae3_unregister_client(&client);
 	hns3_dbg_unregister_debugfs();
+	hnae3_release_unload_lock();
 }
 module_exit(hns3_exit_module);
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
@@ -214,6 +214,8 @@
 #define HNS3_CQ_MODE_EQE			1U
 #define HNS3_CQ_MODE_CQE			0U
 
+#define HNS3_RESCHED_BD_NUM			1024
+
 enum hns3_pkt_l2t_type {
 	HNS3_L2_TYPE_UNICAST,
 	HNS3_L2_TYPE_MULTICAST,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
@@ -78,6 +78,9 @@
 #define HNS3_NIC_LB_TEST_NO_MEM_ERR	1
 #define HNS3_NIC_LB_TEST_TX_CNT_ERR	2
 #define HNS3_NIC_LB_TEST_RX_CNT_ERR	3
+#define HNS3_NIC_LB_TEST_UNEXECUTED	4
+
+static int hns3_get_sset_count(struct net_device *netdev, int stringset);
 
 static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
 {
@@ -418,18 +421,26 @@
 static void hns3_self_test(struct net_device *ndev,
 			   struct ethtool_test *eth_test, u64 *data)
 {
+	int cnt = hns3_get_sset_count(ndev, ETH_SS_TEST);
 	struct hns3_nic_priv *priv = netdev_priv(ndev);
 	struct hnae3_handle *h = priv->ae_handle;
 	int st_param[HNAE3_LOOP_NONE][2];
 	bool if_running = netif_running(ndev);
+	int i;
+
+	/* initialize the loopback test result, avoid marking an unexcuted
+	 * loopback test as PASS.
+	 */
+	for (i = 0; i < cnt; i++)
+		data[i] = HNS3_NIC_LB_TEST_UNEXECUTED;
 
 	if (hns3_nic_resetting(ndev)) {
 		netdev_err(ndev, "dev resetting!");
-		return;
+		goto failure;
 	}
 
 	if (!(eth_test->flags & ETH_TEST_FL_OFFLINE))
-		return;
+		goto failure;
 
 	if (netif_msg_ifdown(h))
 		netdev_info(ndev, "self test start\n");
@@ -451,6 +462,10 @@
 
 	if (netif_msg_ifdown(h))
 		netdev_info(ndev, "self test end\n");
+	return;
+
+failure:
+	eth_test->flags |= ETH_TEST_FL_FAILED;
 }
 
 static void hns3_update_limit_promisc_mode(struct net_device *netdev,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
@@ -6,6 +6,7 @@
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
@@ -1524,6 +1525,9 @@
 			cfg.default_speed, ret);
 		return ret;
 	}
+	hdev->hw.mac.req_speed = hdev->hw.mac.speed;
+	hdev->hw.mac.req_autoneg = AUTONEG_ENABLE;
+	hdev->hw.mac.req_duplex = DUPLEX_FULL;
 
 	hclge_parse_link_mode(hdev, cfg.speed_ability);
 
@@ -1753,7 +1757,8 @@
 
 	nic->pdev = hdev->pdev;
 	nic->ae_algo = &ae_algo;
-	nic->numa_node_mask = hdev->numa_node_mask;
+	bitmap_copy(nic->numa_node_mask.bits, hdev->numa_node_mask.bits,
+		    MAX_NUMNODES);
 	nic->kinfo.io_base = hdev->hw.hw.io_base;
 
 	ret = hclge_knic_setup(vport, num_tqps,
@@ -2445,7 +2450,8 @@
 
 	roce->pdev = nic->pdev;
 	roce->ae_algo = nic->ae_algo;
-	roce->numa_node_mask = nic->numa_node_mask;
+	bitmap_copy(roce->numa_node_mask.bits, nic->numa_node_mask.bits,
+		    MAX_NUMNODES);
 
 	return 0;
 }
@@ -2591,8 +2597,17 @@
 {
 	struct hclge_vport *vport = hclge_get_vport(handle);
 	struct hclge_dev *hdev = vport->back;
+	int ret;
+
+	ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex, lane_num);
 
-	return hclge_cfg_mac_speed_dup(hdev, speed, duplex, lane_num);
+	if (ret)
+		return ret;
+
+	hdev->hw.mac.req_speed = speed;
+	hdev->hw.mac.req_duplex = duplex;
+
+	return 0;
 }
 
 static int hclge_set_autoneg_en(struct hclge_dev *hdev, bool enable)
@@ -2890,11 +2905,9 @@
 	int ret;
 
 	hdev->support_sfp_query = true;
-	hdev->hw.mac.duplex = HCLGE_MAC_FULL;
-	ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed,
-					 hdev->hw.mac.duplex, hdev->hw.mac.lane_num);
-	if (ret)
-		return ret;
+
+	if (!test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
+		hdev->hw.mac.duplex = HCLGE_MAC_FULL;
 
 	if (hdev->hw.mac.support_autoneg) {
 		ret = hclge_set_autoneg_en(hdev, hdev->hw.mac.autoneg);
@@ -2902,6 +2915,14 @@
 			return ret;
 	}
 
+	if (!hdev->hw.mac.autoneg) {
+		ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.req_speed,
+						 hdev->hw.mac.req_duplex,
+						 hdev->hw.mac.lane_num);
+		if (ret)
+			return ret;
+	}
+
 	mac->link = 0;
 
 	if (mac->user_fec_mode & BIT(HNAE3_FEC_USER_DEF)) {
@@ -3021,9 +3042,7 @@
 
 static void hclge_update_link_status(struct hclge_dev *hdev)
 {
-	struct hnae3_handle *rhandle = &hdev->vport[0].roce;
 	struct hnae3_handle *handle = &hdev->vport[0].nic;
-	struct hnae3_client *rclient = hdev->roce_client;
 	struct hnae3_client *client = hdev->nic_client;
 	int state;
 	int ret;
@@ -3047,8 +3066,15 @@
 
 		client->ops->link_status_change(handle, state);
 		hclge_config_mac_tnl_int(hdev, state);
-		if (rclient && rclient->ops->link_status_change)
-			rclient->ops->link_status_change(rhandle, state);
+
+		if (test_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state)) {
+			struct hnae3_handle *rhandle = &hdev->vport[0].roce;
+			struct hnae3_client *rclient = hdev->roce_client;
+
+			if (rclient && rclient->ops->link_status_change)
+				rclient->ops->link_status_change(rhandle,
+								 state);
+		}
 
 		hclge_push_link_status(hdev);
 	}
@@ -3326,9 +3352,9 @@
 		return ret;
 	}
 
-	hdev->hw.mac.autoneg = cmd->base.autoneg;
-	hdev->hw.mac.speed = cmd->base.speed;
-	hdev->hw.mac.duplex = cmd->base.duplex;
+	hdev->hw.mac.req_autoneg = cmd->base.autoneg;
+	hdev->hw.mac.req_speed = cmd->base.speed;
+	hdev->hw.mac.req_duplex = cmd->base.duplex;
 	linkmode_copy(hdev->hw.mac.advertising, cmd->link_modes.advertising);
 
 	return 0;
@@ -3361,9 +3387,9 @@
 	if (!hnae3_dev_phy_imp_supported(hdev))
 		return 0;
 
-	cmd.base.autoneg = hdev->hw.mac.autoneg;
-	cmd.base.speed = hdev->hw.mac.speed;
-	cmd.base.duplex = hdev->hw.mac.duplex;
+	cmd.base.autoneg = hdev->hw.mac.req_autoneg;
+	cmd.base.speed = hdev->hw.mac.req_speed;
+	cmd.base.duplex = hdev->hw.mac.req_duplex;
 	linkmode_copy(cmd.link_modes.advertising, hdev->hw.mac.advertising);
 
 	return hclge_set_phy_link_ksettings(&hdev->vport->nic, &cmd);
@@ -3501,6 +3527,17 @@
 	return ret;
 }
 
+static void hclge_set_reset_pending(struct hclge_dev *hdev,
+				    enum hnae3_reset_type reset_type)
+{
+	/* When an incorrect reset type is executed, the get_reset_level
+	 * function generates the HNAE3_NONE_RESET flag. As a result, this
+	 * type do not need to pending.
+	 */
+	if (reset_type != HNAE3_NONE_RESET)
+		set_bit(reset_type, &hdev->reset_pending);
+}
+
 static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
 {
 	u32 cmdq_src_reg, msix_src_reg, hw_err_src_reg;
@@ -3521,7 +3558,7 @@
 	 */
 	if (BIT(HCLGE_VECTOR0_IMPRESET_INT_B) & msix_src_reg) {
 		dev_info(&hdev->pdev->dev, "IMP reset interrupt\n");
-		set_bit(HNAE3_IMP_RESET, &hdev->reset_pending);
+		hclge_set_reset_pending(hdev, HNAE3_IMP_RESET);
 		set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state);
 		*clearval = BIT(HCLGE_VECTOR0_IMPRESET_INT_B);
 		hdev->rst_stats.imp_rst_cnt++;
@@ -3531,7 +3568,7 @@
 	if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & msix_src_reg) {
 		dev_info(&hdev->pdev->dev, "global reset interrupt\n");
 		set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state);
-		set_bit(HNAE3_GLOBAL_RESET, &hdev->reset_pending);
+		hclge_set_reset_pending(hdev, HNAE3_GLOBAL_RESET);
 		*clearval = BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B);
 		hdev->rst_stats.global_rst_cnt++;
 		return HCLGE_VECTOR0_EVENT_RST;
@@ -3686,7 +3723,7 @@
 	snprintf(hdev->misc_vector.name, HNAE3_INT_NAME_LEN, "%s-misc-%s",
 		 HCLGE_NAME, pci_name(hdev->pdev));
 	ret = request_irq(hdev->misc_vector.vector_irq, hclge_misc_irq_handle,
-			  0, hdev->misc_vector.name, hdev);
+			  IRQF_NO_AUTOEN, hdev->misc_vector.name, hdev);
 	if (ret) {
 		hclge_free_vector(hdev, 0);
 		dev_err(&hdev->pdev->dev, "request misc irq(%d) fail\n",
@@ -3979,7 +4016,7 @@
 	case HNAE3_FUNC_RESET:
 		dev_info(&pdev->dev, "PF reset requested\n");
 		/* schedule again to check later */
-		set_bit(HNAE3_FUNC_RESET, &hdev->reset_pending);
+		hclge_set_reset_pending(hdev, HNAE3_FUNC_RESET);
 		hclge_reset_task_schedule(hdev);
 		break;
 	default:
@@ -4013,6 +4050,8 @@
 		clear_bit(HNAE3_FLR_RESET, addr);
 	}
 
+	clear_bit(HNAE3_NONE_RESET, addr);
+
 	if (hdev->reset_type != HNAE3_NONE_RESET &&
 	    rst_level < hdev->reset_type)
 		return HNAE3_NONE_RESET;
@@ -4154,7 +4193,7 @@
 		return false;
 	} else if (hdev->rst_stats.reset_fail_cnt < MAX_RESET_FAIL_CNT) {
 		hdev->rst_stats.reset_fail_cnt++;
-		set_bit(hdev->reset_type, &hdev->reset_pending);
+		hclge_set_reset_pending(hdev, hdev->reset_type);
 		dev_info(&hdev->pdev->dev,
 			 "re-schedule reset task(%u)\n",
 			 hdev->rst_stats.reset_fail_cnt);
@@ -4397,8 +4436,20 @@
 static void hclge_set_def_reset_request(struct hnae3_ae_dev *ae_dev,
 					enum hnae3_reset_type rst_type)
 {
+#define HCLGE_SUPPORT_RESET_TYPE \
+	(BIT(HNAE3_FLR_RESET) | BIT(HNAE3_FUNC_RESET) | \
+	BIT(HNAE3_GLOBAL_RESET) | BIT(HNAE3_IMP_RESET))
+
 	struct hclge_dev *hdev = ae_dev->priv;
 
+	if (!(BIT(rst_type) & HCLGE_SUPPORT_RESET_TYPE)) {
+		/* To prevent reset triggered by hclge_reset_event */
+		set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request);
+		dev_warn(&hdev->pdev->dev, "unsupported reset type %d\n",
+			 rst_type);
+		return;
+	}
+
 	set_bit(rst_type, &hdev->default_reset_request);
 }
 
@@ -7936,8 +7987,7 @@
 		/* Set the DOWN flag here to disable link updating */
 		set_bit(HCLGE_STATE_DOWN, &hdev->state);
 
-		/* flush memory to make sure DOWN is seen by service task */
-		smp_mb__before_atomic();
+		smp_mb__after_atomic(); /* flush memory to make sure DOWN is seen by service task */
 		hclge_flush_link_update(hdev);
 	}
 }
@@ -9890,6 +9940,7 @@
 static int hclge_init_vlan_filter(struct hclge_dev *hdev)
 {
 	struct hclge_vport *vport;
+	bool enable = true;
 	int ret;
 	int i;
 
@@ -9909,8 +9960,12 @@
 		vport->cur_vlan_fltr_en = true;
 	}
 
+	if (test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, hdev->ae_dev->caps) &&
+	    !test_bit(HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B, hdev->ae_dev->caps))
+		enable = false;
+
 	return hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT,
-					  HCLGE_FILTER_FE_INGRESS, true, 0);
+					  HCLGE_FILTER_FE_INGRESS, enable, 0);
 }
 
 static int hclge_init_vlan_type(struct hclge_dev *hdev)
@@ -11220,6 +11275,12 @@
 	return ret;
 }
 
+static bool hclge_uninit_need_wait(struct hclge_dev *hdev)
+{
+	return test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state) ||
+	       test_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state);
+}
+
 static void hclge_uninit_client_instance(struct hnae3_client *client,
 					 struct hnae3_ae_dev *ae_dev)
 {
@@ -11228,7 +11289,7 @@
 
 	if (hdev->roce_client) {
 		clear_bit(HCLGE_STATE_ROCE_REGISTERED, &hdev->state);
-		while (test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
+		while (hclge_uninit_need_wait(hdev))
 			msleep(HCLGE_WAIT_RESET_DONE);
 
 		hdev->roce_client->ops->uninit_instance(&vport->roce, 0);
@@ -11334,7 +11395,7 @@
 
 	pcim_iounmap(pdev, hdev->hw.hw.io_base);
 	pci_free_irq_vectors(pdev);
-	pci_release_mem_regions(pdev);
+	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 }
 
@@ -11406,8 +11467,8 @@
 		dev_err(&hdev->pdev->dev, "fail to rebuild, ret=%d\n", ret);
 
 	hdev->reset_type = HNAE3_NONE_RESET;
-	clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
-	up(&hdev->reset_sem);
+	if (test_and_clear_bit(HCLGE_STATE_RST_HANDLING, &hdev->state))
+		up(&hdev->reset_sem);
 }
 
 static void hclge_clear_resetting_state(struct hclge_dev *hdev)
@@ -11606,14 +11667,10 @@
 	if (ret)
 		goto out;
 
-	ret = hclge_devlink_init(hdev);
-	if (ret)
-		goto err_pci_uninit;
-
 	/* Firmware command queue initialize */
 	ret = hclge_comm_cmd_queue_init(hdev->pdev, &hdev->hw.hw);
 	if (ret)
-		goto err_devlink_uninit;
+		goto err_pci_uninit;
 
 	/* Firmware command initialize */
 	ret = hclge_comm_cmd_init(hdev->ae_dev, &hdev->hw.hw, &hdev->fw_version,
@@ -11741,7 +11798,7 @@
 
 	ret = hclge_update_port_info(hdev);
 	if (ret)
-		goto err_mdiobus_unreg;
+		goto err_ptp_uninit;
 
 	INIT_KFIFO(hdev->mac_tnl_log);
 
@@ -11773,24 +11830,30 @@
 
 	hclge_init_rxd_adv_layout(hdev);
 
-	/* Enable MISC vector(vector0) */
-	hclge_enable_vector(&hdev->misc_vector, true);
-
 	ret = hclge_init_wol(hdev);
 	if (ret)
 		dev_warn(&pdev->dev,
 			 "failed to wake on lan init, ret = %d\n", ret);
 
+	ret = hclge_devlink_init(hdev);
+	if (ret)
+		goto err_ptp_uninit;
+
 	hclge_state_init(hdev);
 	hdev->last_reset_time = jiffies;
 
+	/* Enable MISC vector(vector0) */
+	enable_irq(hdev->misc_vector.vector_irq);
+	hclge_enable_vector(&hdev->misc_vector, true);
+
 	dev_info(&hdev->pdev->dev, "%s driver initialization finished.\n",
 		 HCLGE_DRIVER_NAME);
 
 	hclge_task_schedule(hdev, round_jiffies_relative(HZ));
-
 	return 0;
 
+err_ptp_uninit:
+	hclge_ptp_uninit(hdev);
 err_mdiobus_unreg:
 	if (hdev->hw.mac.phydev)
 		mdiobus_unregister(hdev->hw.mac.mdio_bus);
@@ -11800,8 +11863,6 @@
 	pci_free_irq_vectors(pdev);
 err_cmd_uninit:
 	hclge_comm_cmd_uninit(hdev->ae_dev, &hdev->hw.hw);
-err_devlink_uninit:
-	hclge_devlink_uninit(hdev);
 err_pci_uninit:
 	pcim_iounmap(pdev, hdev->hw.hw.io_base);
 	pci_release_regions(pdev);
@@ -12188,7 +12249,7 @@
 
 	/* Disable MISC vector(vector0) */
 	hclge_enable_vector(&hdev->misc_vector, false);
-	synchronize_irq(hdev->misc_vector.vector_irq);
+	disable_irq(hdev->misc_vector.vector_irq);
 
 	/* Disable all hw interrupts */
 	hclge_config_mac_tnl_int(hdev, false);
@@ -12779,9 +12840,11 @@
 
 static void __exit hclge_exit(void)
 {
+	hnae3_acquire_unload_lock();
 	hnae3_unregister_ae_algo_prepare(&ae_algo);
 	hnae3_unregister_ae_algo(&ae_algo);
 	destroy_workqueue(hclge_wq);
+	hnae3_release_unload_lock();
 }
 module_init(hclge_init);
 module_exit(hclge_exit);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
@@ -270,11 +270,14 @@
 	u8 media_type;	/* port media type, e.g. fibre/copper/backplane */
 	u8 mac_addr[ETH_ALEN];
 	u8 autoneg;
+	u8 req_autoneg;
 	u8 duplex;
+	u8 req_duplex;
 	u8 support_autoneg;
 	u8 speed_type;	/* 0: sfp speed, 1: active speed */
 	u8 lane_num;
 	u32 speed;
+	u32 req_speed;
 	u32 max_speed;
 	u32 speed_ability; /* speed ability supported by current media */
 	u32 module_type; /* sub media type, e.g. kr/cr/sr/lr */
@@ -882,7 +885,7 @@
 
 	u16 fdir_pf_filter_count; /* Num of guaranteed filters for this PF */
 	u16 num_alloc_vport;		/* Num vports this driver supports */
-	u32 numa_node_mask;
+	nodemask_t numa_node_mask;
 	u16 rx_buf_len;
 	u16 num_tx_desc;		/* desc num of per tx queue */
 	u16 num_rx_desc;		/* desc num of per rx queue */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
@@ -1077,12 +1077,13 @@
 
 	hdev = param->vport->back;
 	cmd_func = hclge_mbx_ops_list[param->req->msg.code];
-	if (cmd_func)
-		ret = cmd_func(param);
-	else
+	if (!cmd_func) {
 		dev_err(&hdev->pdev->dev,
 			"un-supported mailbox message, code = %u\n",
 			param->req->msg.code);
+		return;
+	}
+	ret = cmd_func(param);
 
 	/* PF driver should not reply IMP */
 	if (hnae3_get_bit(param->req->mbx_need_resp, HCLGE_MBX_NEED_RESP_B) &&
@@ -1123,10 +1124,11 @@
 		req = (struct hclge_mbx_vf_to_pf_cmd *)desc->data;
 
 		flag = le16_to_cpu(crq->desc[crq->next_to_use].flag);
-		if (unlikely(!hnae3_get_bit(flag, HCLGE_CMDQ_RX_OUTVLD_B))) {
+		if (unlikely(!hnae3_get_bit(flag, HCLGE_CMDQ_RX_OUTVLD_B) ||
+			     req->mbx_src_vfid > hdev->num_req_vfs)) {
 			dev_warn(&hdev->pdev->dev,
-				 "dropped invalid mailbox message, code = %u\n",
-				 req->msg.code);
+				 "dropped invalid mailbox message, code = %u, vfid = %u\n",
+				 req->msg.code, req->mbx_src_vfid);
 
 			/* dropping/not processing this invalid message */
 			crq->desc[crq->next_to_use].flag = 0;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
@@ -191,6 +191,9 @@
 	if (ret)
 		netdev_err(netdev, "failed to adjust link.\n");
 
+	hdev->hw.mac.req_speed = (u32)speed;
+	hdev->hw.mac.req_duplex = (u8)duplex;
+
 	ret = hclge_cfg_flowctrl(hdev);
 	if (ret)
 		netdev_err(netdev, "failed to configure flow control.\n");
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c
@@ -58,6 +58,9 @@
 	struct hclge_dev *hdev = vport->back;
 	struct hclge_ptp *ptp = hdev->ptp;
 
+	if (!ptp)
+		return false;
+
 	if (!test_bit(HCLGE_PTP_FLAG_TX_EN, &ptp->flags) ||
 	    test_and_set_bit(HCLGE_STATE_PTP_TX_HANDLING, &hdev->state)) {
 		ptp->tx_skipped++;
@@ -108,7 +111,7 @@
 	u64 ns = nsec;
 	u32 sec_h;
 
-	if (!test_bit(HCLGE_PTP_FLAG_RX_EN, &hdev->ptp->flags))
+	if (!hdev->ptp || !test_bit(HCLGE_PTP_FLAG_RX_EN, &hdev->ptp->flags))
 		return;
 
 	/* Since the BD does not have enough space for the higher 16 bits of
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c
@@ -510,9 +510,9 @@
 static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data,
 			      struct hnae3_knic_private_info *kinfo)
 {
-#define HCLGE_RING_REG_OFFSET		0x200
 #define HCLGE_RING_INT_REG_OFFSET	0x4
 
+	struct hnae3_queue *tqp;
 	int i, j, reg_num;
 	int data_num_sum;
 	u32 *reg = data;
@@ -533,10 +533,11 @@
 	reg_num = ARRAY_SIZE(ring_reg_addr_list);
 	for (j = 0; j < kinfo->num_tqps; j++) {
 		reg += hclge_reg_get_tlv(HCLGE_REG_TAG_RING, reg_num, reg);
+		tqp = kinfo->tqp[j];
 		for (i = 0; i < reg_num; i++)
-			*reg++ = hclge_read_dev(&hdev->hw,
-						ring_reg_addr_list[i] +
-						HCLGE_RING_REG_OFFSET * j);
+			*reg++ = readl_relaxed(tqp->io_base -
+					       HCLGE_TQP_REG_OFFSET +
+					       ring_reg_addr_list[i]);
 	}
 	data_num_sum += (reg_num + HCLGE_REG_TLV_SPACE) * kinfo->num_tqps;
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_trace.h
@@ -24,7 +24,7 @@
 		__field(u8, code)
 		__field(u8, subcode)
 		__string(pciname, pci_name(hdev->pdev))
-		__string(devname, &hdev->vport[0].nic.kinfo.netdev->name)
+		__string(devname, hdev->vport[0].nic.kinfo.netdev->name)
 		__array(u32, mbx_data, PF_GET_MBX_LEN)
 	),
 
@@ -33,7 +33,7 @@
 		__entry->code = req->msg.code;
 		__entry->subcode = req->msg.subcode;
 		__assign_str(pciname, pci_name(hdev->pdev));
-		__assign_str(devname, &hdev->vport[0].nic.kinfo.netdev->name);
+		__assign_str(devname, hdev->vport[0].nic.kinfo.netdev->name);
 		memcpy(__entry->mbx_data, req,
 		       sizeof(struct hclge_mbx_vf_to_pf_cmd));
 	),
@@ -56,7 +56,7 @@
 		__field(u8, vfid)
 		__field(u16, code)
 		__string(pciname, pci_name(hdev->pdev))
-		__string(devname, &hdev->vport[0].nic.kinfo.netdev->name)
+		__string(devname, hdev->vport[0].nic.kinfo.netdev->name)
 		__array(u32, mbx_data, PF_SEND_MBX_LEN)
 	),
 
@@ -64,7 +64,7 @@
 		__entry->vfid = req->dest_vfid;
 		__entry->code = le16_to_cpu(req->msg.code);
 		__assign_str(pciname, pci_name(hdev->pdev));
-		__assign_str(devname, &hdev->vport[0].nic.kinfo.netdev->name);
+		__assign_str(devname, hdev->vport[0].nic.kinfo.netdev->name);
 		memcpy(__entry->mbx_data, req,
 		       sizeof(struct hclge_mbx_pf_to_vf_cmd));
 	),
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -412,7 +412,8 @@
 
 	nic->ae_algo = &ae_algovf;
 	nic->pdev = hdev->pdev;
-	nic->numa_node_mask = hdev->numa_node_mask;
+	bitmap_copy(nic->numa_node_mask.bits, hdev->numa_node_mask.bits,
+		    MAX_NUMNODES);
 	nic->flags |= HNAE3_SUPPORT_VF;
 	nic->kinfo.io_base = hdev->hw.hw.io_base;
 
@@ -1357,6 +1358,17 @@
 	return ret;
 }
 
+static void hclgevf_set_reset_pending(struct hclgevf_dev *hdev,
+				      enum hnae3_reset_type reset_type)
+{
+	/* When an incorrect reset type is executed, the get_reset_level
+	 * function generates the HNAE3_NONE_RESET flag. As a result, this
+	 * type do not need to pending.
+	 */
+	if (reset_type != HNAE3_NONE_RESET)
+		set_bit(reset_type, &hdev->reset_pending);
+}
+
 static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
 {
 #define HCLGEVF_RESET_WAIT_US	20000
@@ -1506,7 +1518,7 @@
 		hdev->rst_stats.rst_fail_cnt);
 
 	if (hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT)
-		set_bit(hdev->reset_type, &hdev->reset_pending);
+		hclgevf_set_reset_pending(hdev, hdev->reset_type);
 
 	if (hclgevf_is_reset_pending(hdev)) {
 		set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
@@ -1626,6 +1638,8 @@
 		clear_bit(HNAE3_FLR_RESET, addr);
 	}
 
+	clear_bit(HNAE3_NONE_RESET, addr);
+
 	return rst_level;
 }
 
@@ -1635,14 +1649,15 @@
 	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
 	struct hclgevf_dev *hdev = ae_dev->priv;
 
-	dev_info(&hdev->pdev->dev, "received reset request from VF enet\n");
-
 	if (hdev->default_reset_request)
 		hdev->reset_level =
 			hclgevf_get_reset_level(&hdev->default_reset_request);
 	else
 		hdev->reset_level = HNAE3_VF_FUNC_RESET;
 
+	dev_info(&hdev->pdev->dev, "received reset request from VF enet, reset level is %d\n",
+		 hdev->reset_level);
+
 	/* reset of this VF requested */
 	set_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state);
 	hclgevf_reset_task_schedule(hdev);
@@ -1653,8 +1668,20 @@
 static void hclgevf_set_def_reset_request(struct hnae3_ae_dev *ae_dev,
 					  enum hnae3_reset_type rst_type)
 {
+#define HCLGEVF_SUPPORT_RESET_TYPE \
+	(BIT(HNAE3_VF_RESET) | BIT(HNAE3_VF_FUNC_RESET) | \
+	BIT(HNAE3_VF_PF_FUNC_RESET) | BIT(HNAE3_VF_FULL_RESET) | \
+	BIT(HNAE3_FLR_RESET) | BIT(HNAE3_VF_EXP_RESET))
+
 	struct hclgevf_dev *hdev = ae_dev->priv;
 
+	if (!(BIT(rst_type) & HCLGEVF_SUPPORT_RESET_TYPE)) {
+		/* To prevent reset triggered by hclge_reset_event */
+		set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request);
+		dev_info(&hdev->pdev->dev, "unsupported reset type %d\n",
+			 rst_type);
+		return;
+	}
 	set_bit(rst_type, &hdev->default_reset_request);
 }
 
@@ -1709,8 +1736,8 @@
 			 ret);
 
 	hdev->reset_type = HNAE3_NONE_RESET;
-	clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state);
-	up(&hdev->reset_sem);
+	if (test_and_clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state))
+		up(&hdev->reset_sem);
 }
 
 static u32 hclgevf_get_fw_version(struct hnae3_handle *handle)
@@ -1811,14 +1838,14 @@
 		 */
 		if (hdev->reset_attempts > HCLGEVF_MAX_RESET_ATTEMPTS_CNT) {
 			/* prepare for full reset of stack + pcie interface */
-			set_bit(HNAE3_VF_FULL_RESET, &hdev->reset_pending);
+			hclgevf_set_reset_pending(hdev, HNAE3_VF_FULL_RESET);
 
 			/* "defer" schedule the reset task again */
 			set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
 		} else {
 			hdev->reset_attempts++;
 
-			set_bit(hdev->reset_level, &hdev->reset_pending);
+			hclgevf_set_reset_pending(hdev, hdev->reset_level);
 			set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
 		}
 		hclgevf_reset_task_schedule(hdev);
@@ -1941,7 +1968,7 @@
 		rst_ing_reg = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING);
 		dev_info(&hdev->pdev->dev,
 			 "receive reset interrupt 0x%x!\n", rst_ing_reg);
-		set_bit(HNAE3_VF_RESET, &hdev->reset_pending);
+		hclgevf_set_reset_pending(hdev, HNAE3_VF_RESET);
 		set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
 		set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state);
 		*clearval = ~(1U << HCLGEVF_VECTOR0_RST_INT_B);
@@ -2082,8 +2109,8 @@
 
 	roce->pdev = nic->pdev;
 	roce->ae_algo = nic->ae_algo;
-	roce->numa_node_mask = nic->numa_node_mask;
-
+	bitmap_copy(roce->numa_node_mask.bits, nic->numa_node_mask.bits,
+		    MAX_NUMNODES);
 	return 0;
 }
 
@@ -2180,8 +2207,7 @@
 	} else {
 		set_bit(HCLGEVF_STATE_DOWN, &hdev->state);
 
-		/* flush memory to make sure DOWN is seen by service task */
-		smp_mb__before_atomic();
+		smp_mb__after_atomic(); /* flush memory to make sure DOWN is seen by service task */
 		hclgevf_flush_link_update(hdev);
 	}
 }
@@ -2252,6 +2278,8 @@
 	clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state);
 
 	INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task);
+	/* timer needs to be initialized before misc irq */
+	timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0);
 
 	mutex_init(&hdev->mbx_resp.mbx_mutex);
 	sema_init(&hdev->reset_sem, 1);
@@ -2845,10 +2873,6 @@
 	if (ret)
 		return ret;
 
-	ret = hclgevf_devlink_init(hdev);
-	if (ret)
-		goto err_devlink_init;
-
 	ret = hclge_comm_cmd_queue_init(hdev->pdev, &hdev->hw.hw);
 	if (ret)
 		goto err_cmd_queue_init;
@@ -2941,6 +2965,10 @@
 
 	hclgevf_init_rxd_adv_layout(hdev);
 
+	ret = hclgevf_devlink_init(hdev);
+	if (ret)
+		goto err_config;
+
 	set_bit(HCLGEVF_STATE_SERVICE_INITED, &hdev->state);
 
 	hdev->last_reset_time = jiffies;
@@ -2948,7 +2976,6 @@
 		 HCLGEVF_DRIVER_NAME);
 
 	hclgevf_task_schedule(hdev, round_jiffies_relative(HZ));
-	timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0);
 
 	return 0;
 
@@ -2960,8 +2987,6 @@
 err_cmd_init:
 	hclge_comm_cmd_uninit(hdev->ae_dev, &hdev->hw.hw);
 err_cmd_queue_init:
-	hclgevf_devlink_uninit(hdev);
-err_devlink_init:
 	hclgevf_pci_uninit(hdev);
 	clear_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state);
 	return ret;
@@ -3347,8 +3372,10 @@
 
 static void __exit hclgevf_exit(void)
 {
+	hnae3_acquire_unload_lock();
 	hnae3_unregister_ae_algo(&ae_algovf);
 	destroy_workqueue(hclgevf_wq);
+	hnae3_release_unload_lock();
 }
 module_init(hclgevf_init);
 module_exit(hclgevf_exit);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
@@ -236,7 +236,7 @@
 	u16 rss_size_max;	/* HW defined max RSS task queue */
 
 	u16 num_alloc_vport;	/* num vports this driver supports */
-	u32 numa_node_mask;
+	nodemask_t numa_node_mask;
 	u16 rx_buf_len;
 	u16 num_tx_desc;	/* desc num of per tx queue */
 	u16 num_rx_desc;	/* desc num of per rx queue */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_regs.c
@@ -123,10 +123,10 @@
 void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
 		      void *data)
 {
-#define HCLGEVF_RING_REG_OFFSET		0x200
 #define HCLGEVF_RING_INT_REG_OFFSET	0x4
 
 	struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
+	struct hnae3_queue *tqp;
 	int i, j, reg_um;
 	u32 *reg = data;
 
@@ -147,10 +147,11 @@
 	reg_um = sizeof(ring_reg_addr_list) / sizeof(u32);
 	for (j = 0; j < hdev->num_tqps; j++) {
 		reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_um, reg);
+		tqp = &hdev->htqp[j].q;
 		for (i = 0; i < reg_um; i++)
-			*reg++ = hclgevf_read_dev(&hdev->hw,
-						  ring_reg_addr_list[i] +
-						  HCLGEVF_RING_REG_OFFSET * j);
+			*reg++ = readl_relaxed(tqp->io_base -
+					       HCLGEVF_TQP_REG_OFFSET +
+					       ring_reg_addr_list[i]);
 	}
 
 	reg_um = sizeof(tqp_intr_reg_addr_list) / sizeof(u32);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_trace.h
@@ -23,7 +23,7 @@
 		__field(u8, vfid)
 		__field(u16, code)
 		__string(pciname, pci_name(hdev->pdev))
-		__string(devname, &hdev->nic.kinfo.netdev->name)
+		__string(devname, hdev->nic.kinfo.netdev->name)
 		__array(u32, mbx_data, VF_GET_MBX_LEN)
 	),
 
@@ -31,7 +31,7 @@
 		__entry->vfid = req->dest_vfid;
 		__entry->code = le16_to_cpu(req->msg.code);
 		__assign_str(pciname, pci_name(hdev->pdev));
-		__assign_str(devname, &hdev->nic.kinfo.netdev->name);
+		__assign_str(devname, hdev->nic.kinfo.netdev->name);
 		memcpy(__entry->mbx_data, req,
 		       sizeof(struct hclge_mbx_pf_to_vf_cmd));
 	),
@@ -55,7 +55,7 @@
 		__field(u8, code)
 		__field(u8, subcode)
 		__string(pciname, pci_name(hdev->pdev))
-		__string(devname, &hdev->nic.kinfo.netdev->name)
+		__string(devname, hdev->nic.kinfo.netdev->name)
 		__array(u32, mbx_data, VF_SEND_MBX_LEN)
 	),
 
@@ -64,7 +64,7 @@
 		__entry->code = req->msg.code;
 		__entry->subcode = req->msg.subcode;
 		__assign_str(pciname, pci_name(hdev->pdev));
-		__assign_str(devname, &hdev->nic.kinfo.netdev->name);
+		__assign_str(devname, hdev->nic.kinfo.netdev->name);
 		memcpy(__entry->mbx_data, req,
 		       sizeof(struct hclge_mbx_vf_to_pf_cmd));
 	),
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/hisilicon/hns_mdio.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/hisilicon/hns_mdio.c
@@ -575,6 +575,7 @@
 						MDIO_SC_RESET_ST;
 				}
 			}
+			of_node_put(reg_args.np);
 		} else {
 			dev_warn(&pdev->dev, "find syscon ret = %#x\n", ret);
 			mdio_dev->subctrl_vbase = NULL;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/huawei/hinic/hinic_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/huawei/hinic/hinic_main.c
@@ -172,6 +172,7 @@
 	hinic_sq_dbgfs_uninit(nic_dev);
 
 	devm_kfree(&netdev->dev, nic_dev->txqs);
+	nic_dev->txqs = NULL;
 	return err;
 }
 
@@ -268,6 +269,7 @@
 	hinic_rq_dbgfs_uninit(nic_dev);
 
 	devm_kfree(&netdev->dev, nic_dev->rxqs);
+	nic_dev->rxqs = NULL;
 	return err;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/i825xx/sun3_82586.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/i825xx/sun3_82586.c
@@ -987,7 +987,7 @@
 	{
 #ifdef DEBUG
 		printk("%s: xmitter timed out, try to restart! stat: %02x\n",dev->name,p->scb->cus);
-		printk("%s: command-stats: %04x %04x\n",dev->name,swab16(p->xmit_cmds[0]->cmd_status),swab16(p->xmit_cmds[1]->cmd_status));
+		printk("%s: command-stats: %04x\n", dev->name, swab16(p->xmit_cmds[0]->cmd_status));
 		printk("%s: check, whether you set the right interrupt number!\n",dev->name);
 #endif
 		sun3_82586_close(dev);
@@ -1012,6 +1012,7 @@
 	if(skb->len > XMIT_BUFF_SIZE)
 	{
 		printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len);
+		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/ibm/emac/mal.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/ibm/emac/mal.c
@@ -578,7 +578,7 @@
 		printk(KERN_ERR "%pOF: Support for 405EZ not enabled!\n",
 				ofdev->dev.of_node);
 		err = -ENODEV;
-		goto fail;
+		goto fail_unmap;
 #endif
 	}
 
@@ -734,6 +734,8 @@
 
 	mal_reset(mal);
 
+	dcr_unmap(mal->dcr_host, 0x100);
+
 	dma_free_coherent(&ofdev->dev,
 			  sizeof(struct mal_descriptor) *
 			  (NUM_TX_BUFF * mal->num_tx_chans +
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/ibm/ibmvnic.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/ibm/ibmvnic.c
@@ -2478,6 +2478,18 @@
 	    (tx_pool->consumer_index + 1) % tx_pool->num_buffers;
 
 	tx_buff = &tx_pool->tx_buff[bufidx];
+
+	/* Sanity checks on our free map to make sure it points to an index
+	 * that is not being occupied by another skb. If skb memory is
+	 * not freed then we see congestion control kick in and halt tx.
+	 */
+	if (unlikely(tx_buff->skb)) {
+		dev_warn_ratelimited(dev, "TX free map points to untracked skb (%s %d idx=%d)\n",
+				     skb_is_gso(skb) ? "tso_pool" : "tx_pool",
+				     queue_num, bufidx);
+		dev_kfree_skb_any(tx_buff->skb);
+	}
+
 	tx_buff->skb = skb;
 	tx_buff->index = bufidx;
 	tx_buff->pool_index = queue_num;
@@ -4057,6 +4069,12 @@
 		adapter->num_active_tx_scrqs = 0;
 	}
 
+	/* Clean any remaining outstanding SKBs
+	 * we freed the irq so we won't be hearing
+	 * from them
+	 */
+	clean_tx_pools(adapter);
+
 	if (adapter->rx_scrq) {
 		for (i = 0; i < adapter->num_active_rx_scrqs; i++) {
 			if (!adapter->rx_scrq[i])
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/e1000e/defines.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/e1000e/defines.h
@@ -805,4 +805,7 @@
 /* SerDes Control */
 #define E1000_GEN_POLL_TIMEOUT          640
 
+#define E1000_FEXTNVM12_PHYPD_CTRL_MASK	0x00C00000
+#define E1000_FEXTNVM12_PHYPD_CTRL_P1	0x00800000
+
 #endif /* _E1000_DEFINES_H_ */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/e1000e/hw.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/e1000e/hw.h
@@ -108,8 +108,8 @@
 #define E1000_DEV_ID_PCH_RPL_I219_V22		0x0DC8
 #define E1000_DEV_ID_PCH_MTP_I219_LM18		0x550A
 #define E1000_DEV_ID_PCH_MTP_I219_V18		0x550B
-#define E1000_DEV_ID_PCH_MTP_I219_LM19		0x550C
-#define E1000_DEV_ID_PCH_MTP_I219_V19		0x550D
+#define E1000_DEV_ID_PCH_ADP_I219_LM19		0x550C
+#define E1000_DEV_ID_PCH_ADP_I219_V19		0x550D
 #define E1000_DEV_ID_PCH_LNP_I219_LM20		0x550E
 #define E1000_DEV_ID_PCH_LNP_I219_V20		0x550F
 #define E1000_DEV_ID_PCH_LNP_I219_LM21		0x5510
@@ -628,6 +628,7 @@
 	u32 id;
 	u32 reset_delay_us;	/* in usec */
 	u32 revision;
+	u32 retry_count;
 
 	enum e1000_media_type media_type;
 
@@ -644,6 +645,7 @@
 	bool polarity_correction;
 	bool speed_downgraded;
 	bool autoneg_wait_to_complete;
+	bool retry_enabled;
 };
 
 struct e1000_nvm_info {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -222,11 +222,18 @@
 	if (hw->mac.type >= e1000_pch_lpt) {
 		/* Only unforce SMBus if ME is not active */
 		if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
+			/* Switching PHY interface always returns MDI error
+			 * so disable retry mechanism to avoid wasting time
+			 */
+			e1000e_disable_phy_retry(hw);
+
 			/* Unforce SMBus mode in PHY */
 			e1e_rphy_locked(hw, CV_SMB_CTRL, &phy_reg);
 			phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
 			e1e_wphy_locked(hw, CV_SMB_CTRL, phy_reg);
 
+			e1000e_enable_phy_retry(hw);
+
 			/* Unforce SMBus mode in MAC */
 			mac_reg = er32(CTRL_EXT);
 			mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS;
@@ -279,6 +286,45 @@
 }
 
 /**
+ * e1000_reconfigure_k1_exit_timeout - reconfigure K1 exit timeout to
+ * align to MTP and later platform requirements.
+ * @hw: pointer to the HW structure
+ *
+ * Context: PHY semaphore must be held by caller.
+ * Return: 0 on success, negative on failure
+ */
+static s32 e1000_reconfigure_k1_exit_timeout(struct e1000_hw *hw)
+{
+	u16 phy_timeout;
+	u32 fextnvm12;
+	s32 ret_val;
+
+	if (hw->mac.type < e1000_pch_mtp)
+		return 0;
+
+	/* Change Kumeran K1 power down state from P0s to P1 */
+	fextnvm12 = er32(FEXTNVM12);
+	fextnvm12 &= ~E1000_FEXTNVM12_PHYPD_CTRL_MASK;
+	fextnvm12 |= E1000_FEXTNVM12_PHYPD_CTRL_P1;
+	ew32(FEXTNVM12, fextnvm12);
+
+	/* Wait for the interface the settle */
+	usleep_range(1000, 1100);
+
+	/* Change K1 exit timeout */
+	ret_val = e1e_rphy_locked(hw, I217_PHY_TIMEOUTS_REG,
+				  &phy_timeout);
+	if (ret_val)
+		return ret_val;
+
+	phy_timeout &= ~I217_PHY_TIMEOUTS_K1_EXIT_TO_MASK;
+	phy_timeout |= 0xF00;
+
+	return e1e_wphy_locked(hw, I217_PHY_TIMEOUTS_REG,
+				  phy_timeout);
+}
+
+/**
  *  e1000_init_phy_workarounds_pchlan - PHY initialization workarounds
  *  @hw: pointer to the HW structure
  *
@@ -310,20 +356,32 @@
 		goto out;
 	}
 
+	/* There is no guarantee that the PHY is accessible at this time
+	 * so disable retry mechanism to avoid wasting time
+	 */
+	e1000e_disable_phy_retry(hw);
+
 	/* The MAC-PHY interconnect may be in SMBus mode.  If the PHY is
 	 * inaccessible and resetting the PHY is not blocked, toggle the
 	 * LANPHYPC Value bit to force the interconnect to PCIe mode.
 	 */
 	switch (hw->mac.type) {
+	case e1000_pch_mtp:
+	case e1000_pch_lnp:
+	case e1000_pch_ptp:
+	case e1000_pch_nvp:
+		/* At this point the PHY might be inaccessible so don't
+		 * propagate the failure
+		 */
+		if (e1000_reconfigure_k1_exit_timeout(hw))
+			e_dbg("Failed to reconfigure K1 exit timeout\n");
+
+		fallthrough;
 	case e1000_pch_lpt:
 	case e1000_pch_spt:
 	case e1000_pch_cnp:
 	case e1000_pch_tgp:
 	case e1000_pch_adp:
-	case e1000_pch_mtp:
-	case e1000_pch_lnp:
-	case e1000_pch_ptp:
-	case e1000_pch_nvp:
 		if (e1000_phy_is_accessible_pchlan(hw))
 			break;
 
@@ -380,6 +438,8 @@
 		break;
 	}
 
+	e1000e_enable_phy_retry(hw);
+
 	hw->phy.ops.release(hw);
 	if (!ret_val) {
 
@@ -405,8 +465,20 @@
 		 *  the PHY is in.
 		 */
 		ret_val = hw->phy.ops.check_reset_block(hw);
-		if (ret_val)
+		if (ret_val) {
 			e_err("ME blocked access to PHY after reset\n");
+			goto out;
+		}
+
+		if (hw->mac.type >= e1000_pch_mtp) {
+			ret_val = hw->phy.ops.acquire(hw);
+			if (ret_val) {
+				e_err("Failed to reconfigure K1 exit timeout\n");
+				goto out;
+			}
+			ret_val = e1000_reconfigure_k1_exit_timeout(hw);
+			hw->phy.ops.release(hw);
+		}
 	}
 
 out:
@@ -449,6 +521,11 @@
 
 	phy->id = e1000_phy_unknown;
 
+	if (hw->mac.type == e1000_pch_mtp) {
+		phy->retry_count = 2;
+		e1000e_enable_phy_retry(hw);
+	}
+
 	ret_val = e1000_init_phy_workarounds_pchlan(hw);
 	if (ret_val)
 		return ret_val;
@@ -1090,6 +1167,46 @@
 }
 
 /**
+ *  e1000e_force_smbus - Force interfaces to transition to SMBUS mode.
+ *  @hw: pointer to the HW structure
+ *
+ *  Force the MAC and the PHY to SMBUS mode. Assumes semaphore already
+ *  acquired.
+ *
+ * Return: 0 on success, negative errno on failure.
+ **/
+static s32 e1000e_force_smbus(struct e1000_hw *hw)
+{
+	u16 smb_ctrl = 0;
+	u32 ctrl_ext;
+	s32 ret_val;
+
+	/* Switching PHY interface always returns MDI error
+	 * so disable retry mechanism to avoid wasting time
+	 */
+	e1000e_disable_phy_retry(hw);
+
+	/* Force SMBus mode in the PHY */
+	ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &smb_ctrl);
+	if (ret_val) {
+		e1000e_enable_phy_retry(hw);
+		return ret_val;
+	}
+
+	smb_ctrl |= CV_SMB_CTRL_FORCE_SMBUS;
+	e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, smb_ctrl);
+
+	e1000e_enable_phy_retry(hw);
+
+	/* Force SMBus mode in the MAC */
+	ctrl_ext = er32(CTRL_EXT);
+	ctrl_ext |= E1000_CTRL_EXT_FORCE_SMBUS;
+	ew32(CTRL_EXT, ctrl_ext);
+
+	return 0;
+}
+
+/**
  *  e1000_enable_ulp_lpt_lp - configure Ultra Low Power mode for LynxPoint-LP
  *  @hw: pointer to the HW structure
  *  @to_sx: boolean indicating a system power state transition to Sx
@@ -1146,17 +1263,11 @@
 	if (ret_val)
 		goto out;
 
-	/* Force SMBus mode in PHY */
-	ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
-	if (ret_val)
+	ret_val = e1000e_force_smbus(hw);
+	if (ret_val) {
+		e_dbg("Failed to force SMBUS: %d\n", ret_val);
 		goto release;
-	phy_reg |= CV_SMB_CTRL_FORCE_SMBUS;
-	e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg);
-
-	/* Force SMBus mode in MAC */
-	mac_reg = er32(CTRL_EXT);
-	mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
-	ew32(CTRL_EXT, mac_reg);
+	}
 
 	/* Si workaround for ULP entry flow on i127/rev6 h/w.  Enable
 	 * LPLU and disable Gig speed when entering ULP
@@ -1313,6 +1424,11 @@
 		/* Toggle LANPHYPC Value bit */
 		e1000_toggle_lanphypc_pch_lpt(hw);
 
+	/* Switching PHY interface always returns MDI error
+	 * so disable retry mechanism to avoid wasting time
+	 */
+	e1000e_disable_phy_retry(hw);
+
 	/* Unforce SMBus mode in PHY */
 	ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
 	if (ret_val) {
@@ -1333,6 +1449,8 @@
 	phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
 	e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg);
 
+	e1000e_enable_phy_retry(hw);
+
 	/* Unforce SMBus mode in MAC */
 	mac_reg = er32(CTRL_EXT);
 	mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS;
@@ -4828,6 +4946,18 @@
 	u16 i;
 
 	e1000_initialize_hw_bits_ich8lan(hw);
+	if (hw->mac.type >= e1000_pch_mtp) {
+		ret_val = hw->phy.ops.acquire(hw);
+		if (ret_val)
+			return ret_val;
+
+		ret_val = e1000_reconfigure_k1_exit_timeout(hw);
+		hw->phy.ops.release(hw);
+		if (ret_val) {
+			e_dbg("Error failed to reconfigure K1 exit timeout\n");
+			return ret_val;
+		}
+	}
 
 	/* Initialize identification LED */
 	ret_val = mac->ops.id_led_init(hw);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/e1000e/ich8lan.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/e1000e/ich8lan.h
@@ -219,6 +219,10 @@
 #define I217_PLL_CLOCK_GATE_REG	PHY_REG(772, 28)
 #define I217_PLL_CLOCK_GATE_MASK	0x07FF
 
+/* PHY Timeouts */
+#define I217_PHY_TIMEOUTS_REG                   PHY_REG(770, 21)
+#define I217_PHY_TIMEOUTS_K1_EXIT_TO_MASK       0x0FC0
+
 #define SW_FLAG_TIMEOUT		1000	/* SW Semaphore flag timeout in ms */
 
 /* Inband Control */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/e1000e/netdev.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -6363,49 +6363,49 @@
 		mac_data |= E1000_EXTCNF_CTRL_GATE_PHY_CFG;
 		ew32(EXTCNF_CTRL, mac_data);
 
-		/* Enable the Dynamic Power Gating in the MAC */
-		mac_data = er32(FEXTNVM7);
-		mac_data |= BIT(22);
-		ew32(FEXTNVM7, mac_data);
-
 		/* Disable disconnected cable conditioning for Power Gating */
 		mac_data = er32(DPGFR);
 		mac_data |= BIT(2);
 		ew32(DPGFR, mac_data);
 
-		/* Don't wake from dynamic Power Gating with clock request */
-		mac_data = er32(FEXTNVM12);
-		mac_data |= BIT(12);
-		ew32(FEXTNVM12, mac_data);
-
-		/* Ungate PGCB clock */
-		mac_data = er32(FEXTNVM9);
-		mac_data &= ~BIT(28);
-		ew32(FEXTNVM9, mac_data);
-
-		/* Enable K1 off to enable mPHY Power Gating */
-		mac_data = er32(FEXTNVM6);
-		mac_data |= BIT(31);
-		ew32(FEXTNVM6, mac_data);
-
-		/* Enable mPHY power gating for any link and speed */
-		mac_data = er32(FEXTNVM8);
-		mac_data |= BIT(9);
-		ew32(FEXTNVM8, mac_data);
-
 		/* Enable the Dynamic Clock Gating in the DMA and MAC */
 		mac_data = er32(CTRL_EXT);
 		mac_data |= E1000_CTRL_EXT_DMA_DYN_CLK_EN;
 		ew32(CTRL_EXT, mac_data);
-
-		/* No MAC DPG gating SLP_S0 in modern standby
-		 * Switch the logic of the lanphypc to use PMC counter
-		 */
-		mac_data = er32(FEXTNVM5);
-		mac_data |= BIT(7);
-		ew32(FEXTNVM5, mac_data);
 	}
 
+	/* Enable the Dynamic Power Gating in the MAC */
+	mac_data = er32(FEXTNVM7);
+	mac_data |= BIT(22);
+	ew32(FEXTNVM7, mac_data);
+
+	/* Don't wake from dynamic Power Gating with clock request */
+	mac_data = er32(FEXTNVM12);
+	mac_data |= BIT(12);
+	ew32(FEXTNVM12, mac_data);
+
+	/* Ungate PGCB clock */
+	mac_data = er32(FEXTNVM9);
+	mac_data &= ~BIT(28);
+	ew32(FEXTNVM9, mac_data);
+
+	/* Enable K1 off to enable mPHY Power Gating */
+	mac_data = er32(FEXTNVM6);
+	mac_data |= BIT(31);
+	ew32(FEXTNVM6, mac_data);
+
+	/* Enable mPHY power gating for any link and speed */
+	mac_data = er32(FEXTNVM8);
+	mac_data |= BIT(9);
+	ew32(FEXTNVM8, mac_data);
+
+	/* No MAC DPG gating SLP_S0 in modern standby
+	 * Switch the logic of the lanphypc to use PMC counter
+	 */
+	mac_data = er32(FEXTNVM5);
+	mac_data |= BIT(7);
+	ew32(FEXTNVM5, mac_data);
+
 	/* Disable the time synchronization clock */
 	mac_data = er32(FEXTNVM7);
 	mac_data |= BIT(31);
@@ -6498,33 +6498,6 @@
 	} else {
 		/* Request driver unconfigure the device from S0ix */
 
-		/* Disable the Dynamic Power Gating in the MAC */
-		mac_data = er32(FEXTNVM7);
-		mac_data &= 0xFFBFFFFF;
-		ew32(FEXTNVM7, mac_data);
-
-		/* Disable mPHY power gating for any link and speed */
-		mac_data = er32(FEXTNVM8);
-		mac_data &= ~BIT(9);
-		ew32(FEXTNVM8, mac_data);
-
-		/* Disable K1 off */
-		mac_data = er32(FEXTNVM6);
-		mac_data &= ~BIT(31);
-		ew32(FEXTNVM6, mac_data);
-
-		/* Disable Ungate PGCB clock */
-		mac_data = er32(FEXTNVM9);
-		mac_data |= BIT(28);
-		ew32(FEXTNVM9, mac_data);
-
-		/* Cancel not waking from dynamic
-		 * Power Gating with clock request
-		 */
-		mac_data = er32(FEXTNVM12);
-		mac_data &= ~BIT(12);
-		ew32(FEXTNVM12, mac_data);
-
 		/* Cancel disable disconnected cable conditioning
 		 * for Power Gating
 		 */
@@ -6537,13 +6510,6 @@
 		mac_data &= 0xFFF7FFFF;
 		ew32(CTRL_EXT, mac_data);
 
-		/* Revert the lanphypc logic to use the internal Gbe counter
-		 * and not the PMC counter
-		 */
-		mac_data = er32(FEXTNVM5);
-		mac_data &= 0xFFFFFF7F;
-		ew32(FEXTNVM5, mac_data);
-
 		/* Enable the periodic inband message,
 		 * Request PCIe clock in K1 page770_17[10:9] =01b
 		 */
@@ -6581,6 +6547,40 @@
 	mac_data &= ~BIT(31);
 	mac_data |= BIT(0);
 	ew32(FEXTNVM7, mac_data);
+
+	/* Disable the Dynamic Power Gating in the MAC */
+	mac_data = er32(FEXTNVM7);
+	mac_data &= 0xFFBFFFFF;
+	ew32(FEXTNVM7, mac_data);
+
+	/* Disable mPHY power gating for any link and speed */
+	mac_data = er32(FEXTNVM8);
+	mac_data &= ~BIT(9);
+	ew32(FEXTNVM8, mac_data);
+
+	/* Disable K1 off */
+	mac_data = er32(FEXTNVM6);
+	mac_data &= ~BIT(31);
+	ew32(FEXTNVM6, mac_data);
+
+	/* Disable Ungate PGCB clock */
+	mac_data = er32(FEXTNVM9);
+	mac_data |= BIT(28);
+	ew32(FEXTNVM9, mac_data);
+
+	/* Cancel not waking from dynamic
+	 * Power Gating with clock request
+	 */
+	mac_data = er32(FEXTNVM12);
+	mac_data &= ~BIT(12);
+	ew32(FEXTNVM12, mac_data);
+
+	/* Revert the lanphypc logic to use the internal Gbe counter
+	 * and not the PMC counter
+	 */
+	mac_data = er32(FEXTNVM5);
+	mac_data &= 0xFFFFFF7F;
+	ew32(FEXTNVM5, mac_data);
 }
 
 static int e1000e_pm_freeze(struct device *dev)
@@ -6671,8 +6671,10 @@
 		if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
 			/* enable wakeup by the PHY */
 			retval = e1000_init_phy_wakeup(adapter, wufc);
-			if (retval)
-				return retval;
+			if (retval) {
+				e_err("Failed to enable wakeup\n");
+				goto skip_phy_configurations;
+			}
 		} else {
 			/* enable wakeup by the MAC */
 			ew32(WUFC, wufc);
@@ -6688,14 +6690,16 @@
 	if (adapter->hw.phy.type == e1000_phy_igp_3) {
 		e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
 	} else if (hw->mac.type >= e1000_pch_lpt) {
-		if (wufc && !(wufc & (E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_BC)))
+		if (wufc && !(wufc & (E1000_WUFC_EX | E1000_WUFC_MC | E1000_WUFC_BC))) {
 			/* ULP does not support wake from unicast, multicast
 			 * or broadcast.
 			 */
 			retval = e1000_enable_ulp_lpt_lp(hw, !runtime);
-
-		if (retval)
-			return retval;
+			if (retval) {
+				e_err("Failed to enable ULP\n");
+				goto skip_phy_configurations;
+			}
+		}
 	}
 
 	/* Ensure that the appropriate bits are set in LPI_CTRL
@@ -6726,6 +6730,7 @@
 		hw->phy.ops.release(hw);
 	}
 
+skip_phy_configurations:
 	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
 	 * would have already happened in close and is redundant.
 	 */
@@ -6968,15 +6973,13 @@
 	e1000e_pm_freeze(dev);
 
 	rc = __e1000_shutdown(pdev, false);
-	if (rc) {
-		e1000e_pm_thaw(dev);
-	} else {
+	if (!rc) {
 		/* Introduce S0ix implementation */
 		if (adapter->flags2 & FLAG2_ENABLE_S0IX_FLOWS)
 			e1000e_s0ix_entry_flow(adapter);
 	}
 
-	return rc;
+	return 0;
 }
 
 static __maybe_unused int e1000e_pm_resume(struct device *dev)
@@ -7896,10 +7899,10 @@
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V17), board_pch_adp },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_LM22), board_pch_adp },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_V22), board_pch_adp },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_LM19), board_pch_adp },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V19), board_pch_adp },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM18), board_pch_mtp },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V18), board_pch_mtp },
-	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM19), board_pch_mtp },
-	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V19), board_pch_mtp },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM20), board_pch_mtp },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V20), board_pch_mtp },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM21), board_pch_mtp },
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/e1000e/phy.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/e1000e/phy.c
@@ -107,6 +107,16 @@
 	return e1e_wphy(hw, M88E1000_PHY_GEN_CONTROL, 0);
 }
 
+void e1000e_disable_phy_retry(struct e1000_hw *hw)
+{
+	hw->phy.retry_enabled = false;
+}
+
+void e1000e_enable_phy_retry(struct e1000_hw *hw)
+{
+	hw->phy.retry_enabled = true;
+}
+
 /**
  *  e1000e_read_phy_reg_mdic - Read MDI control register
  *  @hw: pointer to the HW structure
@@ -118,55 +128,73 @@
  **/
 s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
 {
+	u32 i, mdic = 0, retry_counter, retry_max;
 	struct e1000_phy_info *phy = &hw->phy;
-	u32 i, mdic = 0;
+	bool success;
 
 	if (offset > MAX_PHY_REG_ADDRESS) {
 		e_dbg("PHY Address %d is out of range\n", offset);
 		return -E1000_ERR_PARAM;
 	}
 
+	retry_max = phy->retry_enabled ? phy->retry_count : 0;
+
 	/* Set up Op-code, Phy Address, and register offset in the MDI
 	 * Control register.  The MAC will take care of interfacing with the
 	 * PHY to retrieve the desired data.
 	 */
-	mdic = ((offset << E1000_MDIC_REG_SHIFT) |
-		(phy->addr << E1000_MDIC_PHY_SHIFT) |
-		(E1000_MDIC_OP_READ));
-
-	ew32(MDIC, mdic);
-
-	/* Poll the ready bit to see if the MDI read completed
-	 * Increasing the time out as testing showed failures with
-	 * the lower time out
-	 */
-	for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
-		udelay(50);
-		mdic = er32(MDIC);
-		if (mdic & E1000_MDIC_READY)
-			break;
-	}
-	if (!(mdic & E1000_MDIC_READY)) {
-		e_dbg("MDI Read PHY Reg Address %d did not complete\n", offset);
-		return -E1000_ERR_PHY;
-	}
-	if (mdic & E1000_MDIC_ERROR) {
-		e_dbg("MDI Read PHY Reg Address %d Error\n", offset);
-		return -E1000_ERR_PHY;
-	}
-	if (FIELD_GET(E1000_MDIC_REG_MASK, mdic) != offset) {
-		e_dbg("MDI Read offset error - requested %d, returned %d\n",
-		      offset, FIELD_GET(E1000_MDIC_REG_MASK, mdic));
-		return -E1000_ERR_PHY;
+	for (retry_counter = 0; retry_counter <= retry_max; retry_counter++) {
+		success = true;
+
+		mdic = ((offset << E1000_MDIC_REG_SHIFT) |
+			(phy->addr << E1000_MDIC_PHY_SHIFT) |
+			(E1000_MDIC_OP_READ));
+
+		ew32(MDIC, mdic);
+
+		/* Poll the ready bit to see if the MDI read completed
+		 * Increasing the time out as testing showed failures with
+		 * the lower time out
+		 */
+		for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
+			udelay(50);
+			mdic = er32(MDIC);
+			if (mdic & E1000_MDIC_READY)
+				break;
+		}
+		if (!(mdic & E1000_MDIC_READY)) {
+			e_dbg("MDI Read PHY Reg Address %d did not complete\n",
+			      offset);
+			success = false;
+		}
+		if (mdic & E1000_MDIC_ERROR) {
+			e_dbg("MDI Read PHY Reg Address %d Error\n", offset);
+			success = false;
+		}
+		if (FIELD_GET(E1000_MDIC_REG_MASK, mdic) != offset) {
+			e_dbg("MDI Read offset error - requested %d, returned %d\n",
+			      offset, FIELD_GET(E1000_MDIC_REG_MASK, mdic));
+			success = false;
+		}
+
+		/* Allow some time after each MDIC transaction to avoid
+		 * reading duplicate data in the next MDIC transaction.
+		 */
+		if (hw->mac.type == e1000_pch2lan)
+			udelay(100);
+
+		if (success) {
+			*data = (u16)mdic;
+			return 0;
+		}
+
+		if (retry_counter != retry_max) {
+			e_dbg("Perform retry on PHY transaction...\n");
+			mdelay(10);
+		}
 	}
-	*data = (u16)mdic;
 
-	/* Allow some time after each MDIC transaction to avoid
-	 * reading duplicate data in the next MDIC transaction.
-	 */
-	if (hw->mac.type == e1000_pch2lan)
-		udelay(100);
-	return 0;
+	return -E1000_ERR_PHY;
 }
 
 /**
@@ -179,56 +207,72 @@
  **/
 s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
 {
+	u32 i, mdic = 0, retry_counter, retry_max;
 	struct e1000_phy_info *phy = &hw->phy;
-	u32 i, mdic = 0;
+	bool success;
 
 	if (offset > MAX_PHY_REG_ADDRESS) {
 		e_dbg("PHY Address %d is out of range\n", offset);
 		return -E1000_ERR_PARAM;
 	}
 
+	retry_max = phy->retry_enabled ? phy->retry_count : 0;
+
 	/* Set up Op-code, Phy Address, and register offset in the MDI
 	 * Control register.  The MAC will take care of interfacing with the
 	 * PHY to retrieve the desired data.
 	 */
-	mdic = (((u32)data) |
-		(offset << E1000_MDIC_REG_SHIFT) |
-		(phy->addr << E1000_MDIC_PHY_SHIFT) |
-		(E1000_MDIC_OP_WRITE));
-
-	ew32(MDIC, mdic);
-
-	/* Poll the ready bit to see if the MDI read completed
-	 * Increasing the time out as testing showed failures with
-	 * the lower time out
-	 */
-	for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
-		udelay(50);
-		mdic = er32(MDIC);
-		if (mdic & E1000_MDIC_READY)
-			break;
-	}
-	if (!(mdic & E1000_MDIC_READY)) {
-		e_dbg("MDI Write PHY Reg Address %d did not complete\n", offset);
-		return -E1000_ERR_PHY;
-	}
-	if (mdic & E1000_MDIC_ERROR) {
-		e_dbg("MDI Write PHY Red Address %d Error\n", offset);
-		return -E1000_ERR_PHY;
-	}
-	if (FIELD_GET(E1000_MDIC_REG_MASK, mdic) != offset) {
-		e_dbg("MDI Write offset error - requested %d, returned %d\n",
-		      offset, FIELD_GET(E1000_MDIC_REG_MASK, mdic));
-		return -E1000_ERR_PHY;
-	}
+	for (retry_counter = 0; retry_counter <= retry_max; retry_counter++) {
+		success = true;
 
-	/* Allow some time after each MDIC transaction to avoid
-	 * reading duplicate data in the next MDIC transaction.
-	 */
-	if (hw->mac.type == e1000_pch2lan)
-		udelay(100);
+		mdic = (((u32)data) |
+			(offset << E1000_MDIC_REG_SHIFT) |
+			(phy->addr << E1000_MDIC_PHY_SHIFT) |
+			(E1000_MDIC_OP_WRITE));
+
+		ew32(MDIC, mdic);
+
+		/* Poll the ready bit to see if the MDI read completed
+		 * Increasing the time out as testing showed failures with
+		 * the lower time out
+		 */
+		for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
+			udelay(50);
+			mdic = er32(MDIC);
+			if (mdic & E1000_MDIC_READY)
+				break;
+		}
+		if (!(mdic & E1000_MDIC_READY)) {
+			e_dbg("MDI Write PHY Reg Address %d did not complete\n",
+			      offset);
+			success = false;
+		}
+		if (mdic & E1000_MDIC_ERROR) {
+			e_dbg("MDI Write PHY Reg Address %d Error\n", offset);
+			success = false;
+		}
+		if (FIELD_GET(E1000_MDIC_REG_MASK, mdic) != offset) {
+			e_dbg("MDI Write offset error - requested %d, returned %d\n",
+			      offset, FIELD_GET(E1000_MDIC_REG_MASK, mdic));
+			success = false;
+		}
+
+		/* Allow some time after each MDIC transaction to avoid
+		 * reading duplicate data in the next MDIC transaction.
+		 */
+		if (hw->mac.type == e1000_pch2lan)
+			udelay(100);
+
+		if (success)
+			return 0;
+
+		if (retry_counter != retry_max) {
+			e_dbg("Perform retry on PHY transaction...\n");
+			mdelay(10);
+		}
+	}
 
-	return 0;
+	return -E1000_ERR_PHY;
 }
 
 /**
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/e1000e/phy.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/e1000e/phy.h
@@ -51,6 +51,8 @@
 s32 e1000e_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data);
 void e1000_power_up_phy_copper(struct e1000_hw *hw);
 void e1000_power_down_phy_copper(struct e1000_hw *hw);
+void e1000e_disable_phy_retry(struct e1000_hw *hw);
+void e1000e_enable_phy_retry(struct e1000_hw *hw);
 s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
 s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
 s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/i40e/i40e.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/i40e/i40e.h
@@ -706,6 +706,7 @@
 	I40E_FILTER_ACTIVE,		/* Added to switch by FW */
 	I40E_FILTER_FAILED,		/* Rejected by FW */
 	I40E_FILTER_REMOVE,		/* To be removed */
+	I40E_FILTER_NEW_SYNC,		/* New, not sent yet, is in i40e_sync_vsi_filters() */
 /* There is no 'removed' state; the filter struct is freed */
 };
 struct i40e_mac_filter {
@@ -908,6 +909,7 @@
 	struct rcu_head rcu;	/* to avoid race with update stats on free */
 	char name[I40E_INT_NAME_STR_LEN];
 	bool arm_wb_state;
+	bool in_busy_poll;
 	int irq_num;		/* IRQ assigned to this q_vector */
 } ____cacheline_internodealigned_in_smp;
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/i40e/i40e_adminq.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/i40e/i40e_adminq.h
@@ -109,10 +109,6 @@
 		-EFBIG,      /* I40E_AQ_RC_EFBIG */
 	};
 
-	/* aq_rc is invalid if AQ timed out */
-	if (aq_ret == -EIO)
-		return -EAGAIN;
-
 	if (!((u32)aq_rc < (sizeof(aq_to_posix) / sizeof((aq_to_posix)[0]))))
 		return -ERANGE;
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
@@ -106,6 +106,7 @@
 	"ACTIVE",
 	"FAILED",
 	"REMOVE",
+	"NEW_SYNC",
 };
 
 /**
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -5306,7 +5306,7 @@
 	}
 
 flags_complete:
-	bitmap_xor(changed_flags, pf->flags, orig_flags, I40E_PF_FLAGS_NBITS);
+	bitmap_xor(changed_flags, new_flags, orig_flags, I40E_PF_FLAGS_NBITS);
 
 	if (test_bit(I40E_FLAG_FW_LLDP_DIS, changed_flags))
 		reset_needed = I40E_PF_RESET_AND_REBUILD_FLAG;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -1257,8 +1257,12 @@
 	int bkt;
 	int cnt = 0;
 
-	hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist)
-		++cnt;
+	hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {
+		if (f->state == I40E_FILTER_NEW ||
+		    f->state == I40E_FILTER_NEW_SYNC ||
+		    f->state == I40E_FILTER_ACTIVE)
+			++cnt;
+	}
 
 	return cnt;
 }
@@ -1442,6 +1446,8 @@
 
 			new->f = add_head;
 			new->state = add_head->state;
+			if (add_head->state == I40E_FILTER_NEW)
+				add_head->state = I40E_FILTER_NEW_SYNC;
 
 			/* Add the new filter to the tmp list */
 			hlist_add_head(&new->hlist, tmp_add_list);
@@ -1551,6 +1557,8 @@
 				return -ENOMEM;
 			new_mac->f = add_head;
 			new_mac->state = add_head->state;
+			if (add_head->state == I40E_FILTER_NEW)
+				add_head->state = I40E_FILTER_NEW_SYNC;
 
 			/* Add the new filter to the tmp list */
 			hlist_add_head(&new_mac->hlist, tmp_add_list);
@@ -1735,6 +1743,7 @@
 	struct hlist_node *h;
 	int bkt;
 
+	lockdep_assert_held(&vsi->mac_filter_hash_lock);
 	if (vsi->info.pvid)
 		return i40e_add_filter(vsi, macaddr,
 				       le16_to_cpu(vsi->info.pvid));
@@ -2437,7 +2446,8 @@
 i40e_aqc_broadcast_filter(struct i40e_vsi *vsi, const char *vsi_name,
 			  struct i40e_mac_filter *f)
 {
-	bool enable = f->state == I40E_FILTER_NEW;
+	bool enable = f->state == I40E_FILTER_NEW ||
+		      f->state == I40E_FILTER_NEW_SYNC;
 	struct i40e_hw *hw = &vsi->back->hw;
 	int aq_ret;
 
@@ -2611,6 +2621,7 @@
 
 				/* Add it to the hash list */
 				hlist_add_head(&new->hlist, &tmp_add_list);
+				f->state = I40E_FILTER_NEW_SYNC;
 			}
 
 			/* Count the number of active (current and new) VLAN
@@ -2762,7 +2773,8 @@
 		spin_lock_bh(&vsi->mac_filter_hash_lock);
 		hlist_for_each_entry_safe(new, h, &tmp_add_list, hlist) {
 			/* Only update the state if we're still NEW */
-			if (new->f->state == I40E_FILTER_NEW)
+			if (new->f->state == I40E_FILTER_NEW ||
+			    new->f->state == I40E_FILTER_NEW_SYNC)
 				new->f->state = new->state;
 			hlist_del(&new->hlist);
 			netdev_hw_addr_refcnt(new->f, vsi->netdev, -1);
@@ -3915,6 +3927,12 @@
 		     q_vector->tx.target_itr >> 1);
 		q_vector->tx.current_itr = q_vector->tx.target_itr;
 
+		/* Set ITR for software interrupts triggered after exiting
+		 * busy-loop polling.
+		 */
+		wr32(hw, I40E_PFINT_ITRN(I40E_SW_ITR, vector - 1),
+		     I40E_ITR_20K);
+
 		wr32(hw, I40E_PFINT_RATEN(vector - 1),
 		     i40e_intrl_usec_to_reg(vsi->int_rate_limit));
 
@@ -13292,6 +13310,10 @@
 	bool need_reset;
 	int i;
 
+	/* VSI shall be deleted in a moment, block loading new programs */
+	if (prog && test_bit(__I40E_IN_REMOVE, pf->state))
+		return -EINVAL;
+
 	/* Don't allow frames that span over multiple buffers */
 	if (vsi->netdev->mtu > frame_size - I40E_PACKET_HDR_PAD) {
 		NL_SET_ERR_MSG_MOD(extack, "MTU too large for linear frames and XDP prog does not support frags");
@@ -13300,14 +13322,9 @@
 
 	/* When turning XDP on->off/off->on we reset and rebuild the rings. */
 	need_reset = (i40e_enabled_xdp_vsi(vsi) != !!prog);
-
 	if (need_reset)
 		i40e_prep_for_reset(pf);
 
-	/* VSI shall be deleted in a moment, just return EINVAL */
-	if (test_bit(__I40E_IN_REMOVE, pf->state))
-		return -EINVAL;
-
 	old_prog = xchg(&vsi->xdp_prog, prog);
 
 	if (need_reset) {
@@ -16177,8 +16194,8 @@
 	val = FIELD_GET(I40E_PRTGL_SAH_MFS_MASK,
 			rd32(&pf->hw, I40E_PRTGL_SAH));
 	if (val < MAX_FRAME_SIZE_DEFAULT)
-		dev_warn(&pdev->dev, "MFS for port %x has been set below the default: %x\n",
-			 pf->hw.port, val);
+		dev_warn(&pdev->dev, "MFS for port %x (%d) has been set below the default (%d)\n",
+			 pf->hw.port, val, MAX_FRAME_SIZE_DEFAULT);
 
 	/* Add a filter to drop all Flow control frames from any VSI from being
 	 * transmitted. By doing so we stop a malicious VF from sending out
@@ -16724,7 +16741,7 @@
 	 * since we need to be able to guarantee forward progress even under
 	 * memory pressure.
 	 */
-	i40e_wq = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0, i40e_driver_name);
+	i40e_wq = alloc_workqueue("%s", 0, 0, i40e_driver_name);
 	if (!i40e_wq) {
 		pr_err("%s: Failed to create workqueue\n", i40e_driver_name);
 		return -ENOMEM;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/i40e/i40e_register.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/i40e/i40e_register.h
@@ -333,8 +333,11 @@
 #define I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT 3
 #define I40E_PFINT_DYN_CTLN_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT)
 #define I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT 5
+#define I40E_PFINT_DYN_CTLN_INTERVAL_MASK I40E_MASK(0xFFF, I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT)
 #define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT 24
 #define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_SHIFT)
+#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_SHIFT 25
+#define I40E_PFINT_DYN_CTLN_SW_ITR_INDX_MASK I40E_MASK(0x3, I40E_PFINT_DYN_CTLN_SW_ITR_INDX_SHIFT)
 #define I40E_PFINT_ICR0 0x00038780 /* Reset: CORER */
 #define I40E_PFINT_ICR0_INTEVENT_SHIFT 0
 #define I40E_PFINT_ICR0_INTEVENT_MASK I40E_MASK(0x1, I40E_PFINT_ICR0_INTEVENT_SHIFT)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -2630,7 +2630,22 @@
 	return failure ? budget : (int)total_rx_packets;
 }
 
-static inline u32 i40e_buildreg_itr(const int type, u16 itr)
+/**
+ * i40e_buildreg_itr - build a value for writing to I40E_PFINT_DYN_CTLN register
+ * @itr_idx: interrupt throttling index
+ * @interval: interrupt throttling interval value in usecs
+ * @force_swint: force software interrupt
+ *
+ * The function builds a value for I40E_PFINT_DYN_CTLN register that
+ * is used to update interrupt throttling interval for specified ITR index
+ * and optionally enforces a software interrupt. If the @itr_idx is equal
+ * to I40E_ITR_NONE then no interval change is applied and only @force_swint
+ * parameter is taken into account. If the interval change and enforced
+ * software interrupt are not requested then the built value just enables
+ * appropriate vector interrupt.
+ **/
+static u32 i40e_buildreg_itr(enum i40e_dyn_idx itr_idx, u16 interval,
+			     bool force_swint)
 {
 	u32 val;
 
@@ -2644,23 +2659,33 @@
 	 * an event in the PBA anyway so we need to rely on the automask
 	 * to hold pending events for us until the interrupt is re-enabled
 	 *
-	 * The itr value is reported in microseconds, and the register
-	 * value is recorded in 2 microsecond units. For this reason we
-	 * only need to shift by the interval shift - 1 instead of the
-	 * full value.
+	 * We have to shift the given value as it is reported in microseconds
+	 * and the register value is recorded in 2 microsecond units.
 	 */
-	itr &= I40E_ITR_MASK;
+	interval >>= 1;
 
+	/* 1. Enable vector interrupt
+	 * 2. Update the interval for the specified ITR index
+	 *    (I40E_ITR_NONE in the register is used to indicate that
+	 *     no interval update is requested)
+	 */
 	val = I40E_PFINT_DYN_CTLN_INTENA_MASK |
-	      (type << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT) |
-	      (itr << (I40E_PFINT_DYN_CTLN_INTERVAL_SHIFT - 1));
+	      FIELD_PREP(I40E_PFINT_DYN_CTLN_ITR_INDX_MASK, itr_idx) |
+	      FIELD_PREP(I40E_PFINT_DYN_CTLN_INTERVAL_MASK, interval);
+
+	/* 3. Enforce software interrupt trigger if requested
+	 *    (These software interrupts rate is limited by ITR2 that is
+	 *     set to 20K interrupts per second)
+	 */
+	if (force_swint)
+		val |= I40E_PFINT_DYN_CTLN_SWINT_TRIG_MASK |
+		       I40E_PFINT_DYN_CTLN_SW_ITR_INDX_ENA_MASK |
+		       FIELD_PREP(I40E_PFINT_DYN_CTLN_SW_ITR_INDX_MASK,
+				  I40E_SW_ITR);
 
 	return val;
 }
 
-/* a small macro to shorten up some long lines */
-#define INTREG I40E_PFINT_DYN_CTLN
-
 /* The act of updating the ITR will cause it to immediately trigger. In order
  * to prevent this from throwing off adaptive update statistics we defer the
  * update so that it can only happen so often. So after either Tx or Rx are
@@ -2679,8 +2704,10 @@
 static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
 					  struct i40e_q_vector *q_vector)
 {
+	enum i40e_dyn_idx itr_idx = I40E_ITR_NONE;
 	struct i40e_hw *hw = &vsi->back->hw;
-	u32 intval;
+	u16 interval = 0;
+	u32 itr_val;
 
 	/* If we don't have MSIX, then we only need to re-enable icr0 */
 	if (!test_bit(I40E_FLAG_MSIX_ENA, vsi->back->flags)) {
@@ -2702,8 +2729,8 @@
 	 */
 	if (q_vector->rx.target_itr < q_vector->rx.current_itr) {
 		/* Rx ITR needs to be reduced, this is highest priority */
-		intval = i40e_buildreg_itr(I40E_RX_ITR,
-					   q_vector->rx.target_itr);
+		itr_idx = I40E_RX_ITR;
+		interval = q_vector->rx.target_itr;
 		q_vector->rx.current_itr = q_vector->rx.target_itr;
 		q_vector->itr_countdown = ITR_COUNTDOWN_START;
 	} else if ((q_vector->tx.target_itr < q_vector->tx.current_itr) ||
@@ -2712,25 +2739,36 @@
 		/* Tx ITR needs to be reduced, this is second priority
 		 * Tx ITR needs to be increased more than Rx, fourth priority
 		 */
-		intval = i40e_buildreg_itr(I40E_TX_ITR,
-					   q_vector->tx.target_itr);
+		itr_idx = I40E_TX_ITR;
+		interval = q_vector->tx.target_itr;
 		q_vector->tx.current_itr = q_vector->tx.target_itr;
 		q_vector->itr_countdown = ITR_COUNTDOWN_START;
 	} else if (q_vector->rx.current_itr != q_vector->rx.target_itr) {
 		/* Rx ITR needs to be increased, third priority */
-		intval = i40e_buildreg_itr(I40E_RX_ITR,
-					   q_vector->rx.target_itr);
+		itr_idx = I40E_RX_ITR;
+		interval = q_vector->rx.target_itr;
 		q_vector->rx.current_itr = q_vector->rx.target_itr;
 		q_vector->itr_countdown = ITR_COUNTDOWN_START;
 	} else {
 		/* No ITR update, lowest priority */
-		intval = i40e_buildreg_itr(I40E_ITR_NONE, 0);
 		if (q_vector->itr_countdown)
 			q_vector->itr_countdown--;
 	}
 
-	if (!test_bit(__I40E_VSI_DOWN, vsi->state))
-		wr32(hw, INTREG(q_vector->reg_idx), intval);
+	/* Do not update interrupt control register if VSI is down */
+	if (test_bit(__I40E_VSI_DOWN, vsi->state))
+		return;
+
+	/* Update ITR interval if necessary and enforce software interrupt
+	 * if we are exiting busy poll.
+	 */
+	if (q_vector->in_busy_poll) {
+		itr_val = i40e_buildreg_itr(itr_idx, interval, true);
+		q_vector->in_busy_poll = false;
+	} else {
+		itr_val = i40e_buildreg_itr(itr_idx, interval, false);
+	}
+	wr32(hw, I40E_PFINT_DYN_CTLN(q_vector->reg_idx), itr_val);
 }
 
 /**
@@ -2845,6 +2883,8 @@
 	 */
 	if (likely(napi_complete_done(napi, work_done)))
 		i40e_update_enable_itr(vsi, q_vector);
+	else
+		q_vector->in_busy_poll = true;
 
 	return min(work_done, budget - 1);
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/i40e/i40e_txrx.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/i40e/i40e_txrx.h
@@ -68,6 +68,7 @@
 /* these are indexes into ITRN registers */
 #define I40E_RX_ITR    I40E_IDX_ITR0
 #define I40E_TX_ITR    I40E_IDX_ITR1
+#define I40E_SW_ITR    I40E_IDX_ITR2
 
 /* Supported RSS offloads */
 #define I40E_DEFAULT_RSS_HENA ( \
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -1628,8 +1628,8 @@
 {
 	struct i40e_hw *hw = &pf->hw;
 	struct i40e_vf *vf;
-	int i, v;
 	u32 reg;
+	int i;
 
 	/* If we don't have any VFs, then there is nothing to reset */
 	if (!pf->num_alloc_vfs)
@@ -1640,11 +1640,10 @@
 		return false;
 
 	/* Begin reset on all VFs at once */
-	for (v = 0; v < pf->num_alloc_vfs; v++) {
-		vf = &pf->vf[v];
+	for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
 		/* If VF is being reset no need to trigger reset again */
 		if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
-			i40e_trigger_vf_reset(&pf->vf[v], flr);
+			i40e_trigger_vf_reset(vf, flr);
 	}
 
 	/* HW requires some time to make sure it can flush the FIFO for a VF
@@ -1653,14 +1652,13 @@
 	 * the VFs using a simple iterator that increments once that VF has
 	 * finished resetting.
 	 */
-	for (i = 0, v = 0; i < 10 && v < pf->num_alloc_vfs; i++) {
+	for (i = 0, vf = &pf->vf[0]; i < 10 && vf < &pf->vf[pf->num_alloc_vfs]; ++i) {
 		usleep_range(10000, 20000);
 
 		/* Check each VF in sequence, beginning with the VF to fail
 		 * the previous check.
 		 */
-		while (v < pf->num_alloc_vfs) {
-			vf = &pf->vf[v];
+		while (vf < &pf->vf[pf->num_alloc_vfs]) {
 			if (!test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states)) {
 				reg = rd32(hw, I40E_VPGEN_VFRSTAT(vf->vf_id));
 				if (!(reg & I40E_VPGEN_VFRSTAT_VFRD_MASK))
@@ -1670,7 +1668,7 @@
 			/* If the current VF has finished resetting, move on
 			 * to the next VF in sequence.
 			 */
-			v++;
+			++vf;
 		}
 	}
 
@@ -1680,39 +1678,39 @@
 	/* Display a warning if at least one VF didn't manage to reset in
 	 * time, but continue on with the operation.
 	 */
-	if (v < pf->num_alloc_vfs)
+	if (vf < &pf->vf[pf->num_alloc_vfs])
 		dev_err(&pf->pdev->dev, "VF reset check timeout on VF %d\n",
-			pf->vf[v].vf_id);
+			vf->vf_id);
 	usleep_range(10000, 20000);
 
 	/* Begin disabling all the rings associated with VFs, but do not wait
 	 * between each VF.
 	 */
-	for (v = 0; v < pf->num_alloc_vfs; v++) {
+	for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
 		/* On initial reset, we don't have any queues to disable */
-		if (pf->vf[v].lan_vsi_idx == 0)
+		if (vf->lan_vsi_idx == 0)
 			continue;
 
 		/* If VF is reset in another thread just continue */
 		if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
 			continue;
 
-		i40e_vsi_stop_rings_no_wait(pf->vsi[pf->vf[v].lan_vsi_idx]);
+		i40e_vsi_stop_rings_no_wait(pf->vsi[vf->lan_vsi_idx]);
 	}
 
 	/* Now that we've notified HW to disable all of the VF rings, wait
 	 * until they finish.
 	 */
-	for (v = 0; v < pf->num_alloc_vfs; v++) {
+	for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
 		/* On initial reset, we don't have any queues to disable */
-		if (pf->vf[v].lan_vsi_idx == 0)
+		if (vf->lan_vsi_idx == 0)
 			continue;
 
 		/* If VF is reset in another thread just continue */
 		if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
 			continue;
 
-		i40e_vsi_wait_queues_disabled(pf->vsi[pf->vf[v].lan_vsi_idx]);
+		i40e_vsi_wait_queues_disabled(pf->vsi[vf->lan_vsi_idx]);
 	}
 
 	/* Hw may need up to 50ms to finish disabling the RX queues. We
@@ -1721,12 +1719,12 @@
 	mdelay(50);
 
 	/* Finish the reset on each VF */
-	for (v = 0; v < pf->num_alloc_vfs; v++) {
+	for (vf = &pf->vf[0]; vf < &pf->vf[pf->num_alloc_vfs]; ++vf) {
 		/* If VF is reset in another thread just continue */
 		if (test_bit(I40E_VF_STATE_RESETTING, &vf->vf_states))
 			continue;
 
-		i40e_cleanup_reset_vf(&pf->vf[v]);
+		i40e_cleanup_reset_vf(vf);
 	}
 
 	i40e_flush(hw);
@@ -2219,8 +2217,10 @@
 		vfres->vsi_res[0].qset_handle
 					  = le16_to_cpu(vsi->info.qs_handle[0]);
 		if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_USO) && !vf->pf_set_mac) {
+			spin_lock_bh(&vsi->mac_filter_hash_lock);
 			i40e_del_mac_filter(vsi, vf->default_lan_addr.addr);
 			eth_zero_addr(vf->default_lan_addr.addr);
+			spin_unlock_bh(&vsi->mac_filter_hash_lock);
 		}
 		ether_addr_copy(vfres->vsi_res[0].default_mac_addr,
 				vf->default_lan_addr.addr);
@@ -3143,11 +3143,12 @@
 		/* Allow to delete VF primary MAC only if it was not set
 		 * administratively by PF or if VF is trusted.
 		 */
-		if (ether_addr_equal(addr, vf->default_lan_addr.addr) &&
-		    i40e_can_vf_change_mac(vf))
-			was_unimac_deleted = true;
-		else
-			continue;
+		if (ether_addr_equal(addr, vf->default_lan_addr.addr)) {
+			if (i40e_can_vf_change_mac(vf))
+				was_unimac_deleted = true;
+			else
+				continue;
+		}
 
 		if (i40e_del_mac_filter(vsi, al->list[i].addr)) {
 			ret = -EINVAL;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/iavf/iavf_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/iavf/iavf_main.c
@@ -800,6 +800,11 @@
 		f->state = IAVF_VLAN_ADD;
 		adapter->num_vlan_filters++;
 		iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_ADD_VLAN_FILTER);
+	} else if (f->state == IAVF_VLAN_REMOVE) {
+		/* IAVF_VLAN_REMOVE means that VLAN wasn't yet removed.
+		 * We can safely only change the state here.
+		 */
+		f->state = IAVF_VLAN_ACTIVE;
 	}
 
 clearout:
@@ -820,8 +825,18 @@
 
 	f = iavf_find_vlan(adapter, vlan);
 	if (f) {
-		f->state = IAVF_VLAN_REMOVE;
-		iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_DEL_VLAN_FILTER);
+		/* IAVF_ADD_VLAN means that VLAN wasn't even added yet.
+		 * Remove it from the list.
+		 */
+		if (f->state == IAVF_VLAN_ADD) {
+			list_del(&f->list);
+			kfree(f);
+			adapter->num_vlan_filters--;
+		} else {
+			f->state = IAVF_VLAN_REMOVE;
+			iavf_schedule_aq_request(adapter,
+						 IAVF_FLAG_AQ_DEL_VLAN_FILTER);
+		}
 	}
 
 	spin_unlock_bh(&adapter->mac_vlan_list_lock);
@@ -3512,6 +3527,34 @@
 }
 
 /**
+ * iavf_is_tc_config_same - Compare the mqprio TC config with the
+ * TC config already configured on this adapter.
+ * @adapter: board private structure
+ * @mqprio_qopt: TC config received from kernel.
+ *
+ * This function compares the TC config received from the kernel
+ * with the config already configured on the adapter.
+ *
+ * Return: True if configuration is same, false otherwise.
+ **/
+static bool iavf_is_tc_config_same(struct iavf_adapter *adapter,
+				   struct tc_mqprio_qopt *mqprio_qopt)
+{
+	struct virtchnl_channel_info *ch = &adapter->ch_config.ch_info[0];
+	int i;
+
+	if (adapter->num_tc != mqprio_qopt->num_tc)
+		return false;
+
+	for (i = 0; i < adapter->num_tc; i++) {
+		if (ch[i].count != mqprio_qopt->count[i] ||
+		    ch[i].offset != mqprio_qopt->offset[i])
+			return false;
+	}
+	return true;
+}
+
+/**
  * __iavf_setup_tc - configure multiple traffic classes
  * @netdev: network interface device structure
  * @type_data: tc offload data
@@ -3568,7 +3611,7 @@
 		if (ret)
 			return ret;
 		/* Return if same TC config is requested */
-		if (adapter->num_tc == num_tc)
+		if (iavf_is_tc_config_same(adapter, &mqprio_qopt->qopt))
 			return 0;
 		adapter->num_tc = num_tc;
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice.h
@@ -317,6 +317,7 @@
 	ICE_VSI_UMAC_FLTR_CHANGED,
 	ICE_VSI_MMAC_FLTR_CHANGED,
 	ICE_VSI_PROMISC_CHANGED,
+	ICE_VSI_REBUILD_PENDING,
 	ICE_VSI_STATE_NBITS		/* must be last */
 };
 
@@ -412,9 +413,9 @@
 	struct ice_tc_cfg tc_cfg;
 	struct bpf_prog *xdp_prog;
 	struct ice_tx_ring **xdp_rings;	 /* XDP ring array */
-	unsigned long *af_xdp_zc_qps;	 /* tracks AF_XDP ZC enabled qps */
 	u16 num_xdp_txq;		 /* Used XDP queues */
 	u8 xdp_mapping_mode;		 /* ICE_MAP_MODE_[CONTIG|SCATTER] */
+	struct mutex xdp_state_lock;
 
 	struct net_device **target_netdevs;
 
@@ -749,21 +750,36 @@
 }
 
 /**
- * ice_xsk_pool - get XSK buffer pool bound to a ring
+ * ice_get_xp_from_qid - get ZC XSK buffer pool bound to a queue ID
+ * @vsi: pointer to VSI
+ * @qid: index of a queue to look at XSK buff pool presence
+ *
+ * Return: A pointer to xsk_buff_pool structure if there is a buffer pool
+ * attached and configured as zero-copy, NULL otherwise.
+ */
+static inline struct xsk_buff_pool *ice_get_xp_from_qid(struct ice_vsi *vsi,
+							u16 qid)
+{
+	struct xsk_buff_pool *pool = xsk_get_pool_from_qid(vsi->netdev, qid);
+
+	if (!ice_is_xdp_ena_vsi(vsi))
+		return NULL;
+
+	return (pool && pool->dev) ? pool : NULL;
+}
+
+/**
+ * ice_rx_xsk_pool - assign XSK buff pool to Rx ring
  * @ring: Rx ring to use
  *
- * Returns a pointer to xsk_buff_pool structure if there is a buffer pool
- * present, NULL otherwise.
+ * Sets XSK buff pool pointer on Rx ring.
  */
-static inline struct xsk_buff_pool *ice_xsk_pool(struct ice_rx_ring *ring)
+static inline void ice_rx_xsk_pool(struct ice_rx_ring *ring)
 {
 	struct ice_vsi *vsi = ring->vsi;
 	u16 qid = ring->q_index;
 
-	if (!ice_is_xdp_ena_vsi(vsi) || !test_bit(qid, vsi->af_xdp_zc_qps))
-		return NULL;
-
-	return xsk_get_pool_from_qid(vsi->netdev, qid);
+	WRITE_ONCE(ring->xsk_pool, ice_get_xp_from_qid(vsi, qid));
 }
 
 /**
@@ -788,12 +804,7 @@
 	if (!ring)
 		return;
 
-	if (!ice_is_xdp_ena_vsi(vsi) || !test_bit(qid, vsi->af_xdp_zc_qps)) {
-		ring->xsk_pool = NULL;
-		return;
-	}
-
-	ring->xsk_pool = xsk_get_pool_from_qid(vsi->netdev, qid);
+	WRITE_ONCE(ring->xsk_pool, ice_get_xp_from_qid(vsi, qid));
 }
 
 /**
@@ -921,9 +932,17 @@
 int ice_down_up(struct ice_vsi *vsi);
 int ice_vsi_cfg_lan(struct ice_vsi *vsi);
 struct ice_vsi *ice_lb_vsi_setup(struct ice_pf *pf, struct ice_port_info *pi);
+
+enum ice_xdp_cfg {
+	ICE_XDP_CFG_FULL,	/* Fully apply new config in .ndo_bpf() */
+	ICE_XDP_CFG_PART,	/* Save/use part of config in VSI rebuild */
+};
+
 int ice_vsi_determine_xdp_res(struct ice_vsi *vsi);
-int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog);
-int ice_destroy_xdp_rings(struct ice_vsi *vsi);
+int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
+			  enum ice_xdp_cfg cfg_type);
+int ice_destroy_xdp_rings(struct ice_vsi *vsi, enum ice_xdp_cfg cfg_type);
+void ice_map_xdp_rings(struct ice_vsi *vsi);
 int
 ice_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
 	     u32 flags);
@@ -983,6 +1002,8 @@
 int ice_load(struct ice_pf *pf);
 void ice_unload(struct ice_pf *pf);
 void ice_adv_lnk_speed_maps_init(void);
+int ice_init_dev(struct ice_pf *pf);
+void ice_deinit_dev(struct ice_pf *pf);
 
 /**
  * ice_set_rdma_cap - enable RDMA support
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
@@ -593,8 +593,9 @@
 struct ice_aqc_recipe_to_profile {
 	__le16 profile_id;
 	u8 rsvd[6];
-	DECLARE_BITMAP(recipe_assoc, ICE_MAX_NUM_RECIPES);
+	__le64 recipe_assoc;
 };
+static_assert(sizeof(struct ice_aqc_recipe_to_profile) == 16);
 
 /* Add/Update/Remove/Get switch rules (indirect 0x02A0, 0x02A1, 0x02A2, 0x02A3)
  */
@@ -2149,6 +2150,8 @@
 	struct ice_aqc_get_pkg_info pkg_info[];
 };
 
+#define ICE_AQC_GET_CGU_MAX_PHASE_ADJ	GENMASK(30, 0)
+
 /* Get CGU abilities command response data structure (indirect 0x0C61) */
 struct ice_aqc_get_cgu_abilities {
 	u8 num_inputs;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_base.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_base.c
@@ -189,16 +189,11 @@
 	}
 	q_vector = vsi->q_vectors[v_idx];
 
-	ice_for_each_tx_ring(tx_ring, q_vector->tx) {
-		ice_queue_set_napi(vsi, tx_ring->q_index, NETDEV_QUEUE_TYPE_TX,
-				   NULL);
+	ice_for_each_tx_ring(tx_ring, vsi->q_vectors[v_idx]->tx)
 		tx_ring->q_vector = NULL;
-	}
-	ice_for_each_rx_ring(rx_ring, q_vector->rx) {
-		ice_queue_set_napi(vsi, rx_ring->q_index, NETDEV_QUEUE_TYPE_RX,
-				   NULL);
+
+	ice_for_each_rx_ring(rx_ring, vsi->q_vectors[v_idx]->rx)
 		rx_ring->q_vector = NULL;
-	}
 
 	/* only VSI with an associated netdev is set up with NAPI */
 	if (vsi->netdev)
@@ -531,12 +526,31 @@
 }
 
 /**
+ * ice_get_frame_sz - calculate xdp_buff::frame_sz
+ * @rx_ring: the ring being configured
+ *
+ * Return frame size based on underlying PAGE_SIZE
+ */
+static unsigned int ice_get_frame_sz(struct ice_rx_ring *rx_ring)
+{
+	unsigned int frame_sz;
+
+#if (PAGE_SIZE >= 8192)
+	frame_sz = rx_ring->rx_buf_len;
+#else
+	frame_sz = ice_rx_pg_size(rx_ring) / 2;
+#endif
+
+	return frame_sz;
+}
+
+/**
  * ice_vsi_cfg_rxq - Configure an Rx queue
  * @ring: the ring being configured
  *
  * Return 0 on success and a negative value on error.
  */
-int ice_vsi_cfg_rxq(struct ice_rx_ring *ring)
+static int ice_vsi_cfg_rxq(struct ice_rx_ring *ring)
 {
 	struct device *dev = ice_pf_to_dev(ring->vsi->back);
 	u32 num_bufs = ICE_RX_DESC_UNUSED(ring);
@@ -554,7 +568,7 @@
 				return err;
 		}
 
-		ring->xsk_pool = ice_xsk_pool(ring);
+		ice_rx_xsk_pool(ring);
 		if (ring->xsk_pool) {
 			xdp_rxq_info_unreg(&ring->xdp_rxq);
 
@@ -594,7 +608,7 @@
 		}
 	}
 
-	xdp_init_buff(&ring->xdp, ice_rx_pg_size(ring) / 2, &ring->xdp_rxq);
+	xdp_init_buff(&ring->xdp, ice_get_frame_sz(ring), &ring->xdp_rxq);
 	ring->xdp.data = NULL;
 	ring->xdp_ext.pkt_ctx = &ring->pkt_ctx;
 	err = ice_setup_rx_ctx(ring);
@@ -615,7 +629,7 @@
 			return 0;
 		}
 
-		ok = ice_alloc_rx_bufs_zc(ring, num_bufs);
+		ok = ice_alloc_rx_bufs_zc(ring, ring->xsk_pool, num_bufs);
 		if (!ok) {
 			u16 pf_q = ring->vsi->rxq_map[ring->q_index];
 
@@ -631,6 +645,62 @@
 	return 0;
 }
 
+int ice_vsi_cfg_single_rxq(struct ice_vsi *vsi, u16 q_idx)
+{
+	if (q_idx >= vsi->num_rxq)
+		return -EINVAL;
+
+	return ice_vsi_cfg_rxq(vsi->rx_rings[q_idx]);
+}
+
+/**
+ * ice_vsi_cfg_frame_size - setup max frame size and Rx buffer length
+ * @vsi: VSI
+ */
+static void ice_vsi_cfg_frame_size(struct ice_vsi *vsi)
+{
+	if (!vsi->netdev || test_bit(ICE_FLAG_LEGACY_RX, vsi->back->flags)) {
+		vsi->max_frame = ICE_MAX_FRAME_LEGACY_RX;
+		vsi->rx_buf_len = ICE_RXBUF_1664;
+#if (PAGE_SIZE < 8192)
+	} else if (!ICE_2K_TOO_SMALL_WITH_PADDING &&
+		   (vsi->netdev->mtu <= ETH_DATA_LEN)) {
+		vsi->max_frame = ICE_RXBUF_1536 - NET_IP_ALIGN;
+		vsi->rx_buf_len = ICE_RXBUF_1536 - NET_IP_ALIGN;
+#endif
+	} else {
+		vsi->max_frame = ICE_AQ_SET_MAC_FRAME_SIZE_MAX;
+		vsi->rx_buf_len = ICE_RXBUF_3072;
+	}
+}
+
+/**
+ * ice_vsi_cfg_rxqs - Configure the VSI for Rx
+ * @vsi: the VSI being configured
+ *
+ * Return 0 on success and a negative value on error
+ * Configure the Rx VSI for operation.
+ */
+int ice_vsi_cfg_rxqs(struct ice_vsi *vsi)
+{
+	u16 i;
+
+	if (vsi->type == ICE_VSI_VF)
+		goto setup_rings;
+
+	ice_vsi_cfg_frame_size(vsi);
+setup_rings:
+	/* set up individual rings */
+	ice_for_each_rxq(vsi, i) {
+		int err = ice_vsi_cfg_rxq(vsi->rx_rings[i]);
+
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 /**
  * __ice_vsi_get_qs - helper function for assigning queues from PF to VSI
  * @qs_cfg: gathered variables needed for pf->vsi queues assignment
@@ -804,6 +874,9 @@
 		}
 		rx_rings_rem -= rx_rings_per_v;
 	}
+
+	if (ice_is_xdp_ena_vsi(vsi))
+		ice_map_xdp_rings(vsi);
 }
 
 /**
@@ -826,7 +899,7 @@
  * @ring: Tx ring to be configured
  * @qg_buf: queue group buffer
  */
-int
+static int
 ice_vsi_cfg_txq(struct ice_vsi *vsi, struct ice_tx_ring *ring,
 		struct ice_aqc_add_tx_qgrp *qg_buf)
 {
@@ -896,6 +969,80 @@
 
 	return 0;
 }
+
+int ice_vsi_cfg_single_txq(struct ice_vsi *vsi, struct ice_tx_ring **tx_rings,
+			   u16 q_idx)
+{
+	DEFINE_RAW_FLEX(struct ice_aqc_add_tx_qgrp, qg_buf, txqs, 1);
+
+	if (q_idx >= vsi->alloc_txq || !tx_rings || !tx_rings[q_idx])
+		return -EINVAL;
+
+	qg_buf->num_txqs = 1;
+
+	return ice_vsi_cfg_txq(vsi, tx_rings[q_idx], qg_buf);
+}
+
+/**
+ * ice_vsi_cfg_txqs - Configure the VSI for Tx
+ * @vsi: the VSI being configured
+ * @rings: Tx ring array to be configured
+ * @count: number of Tx ring array elements
+ *
+ * Return 0 on success and a negative value on error
+ * Configure the Tx VSI for operation.
+ */
+static int
+ice_vsi_cfg_txqs(struct ice_vsi *vsi, struct ice_tx_ring **rings, u16 count)
+{
+	DEFINE_RAW_FLEX(struct ice_aqc_add_tx_qgrp, qg_buf, txqs, 1);
+	int err = 0;
+	u16 q_idx;
+
+	qg_buf->num_txqs = 1;
+
+	for (q_idx = 0; q_idx < count; q_idx++) {
+		err = ice_vsi_cfg_txq(vsi, rings[q_idx], qg_buf);
+		if (err)
+			break;
+	}
+
+	return err;
+}
+
+/**
+ * ice_vsi_cfg_lan_txqs - Configure the VSI for Tx
+ * @vsi: the VSI being configured
+ *
+ * Return 0 on success and a negative value on error
+ * Configure the Tx VSI for operation.
+ */
+int ice_vsi_cfg_lan_txqs(struct ice_vsi *vsi)
+{
+	return ice_vsi_cfg_txqs(vsi, vsi->tx_rings, vsi->num_txq);
+}
+
+/**
+ * ice_vsi_cfg_xdp_txqs - Configure Tx queues dedicated for XDP in given VSI
+ * @vsi: the VSI being configured
+ *
+ * Return 0 on success and a negative value on error
+ * Configure the Tx queues dedicated for XDP in given VSI for operation.
+ */
+int ice_vsi_cfg_xdp_txqs(struct ice_vsi *vsi)
+{
+	int ret;
+	int i;
+
+	ret = ice_vsi_cfg_txqs(vsi, vsi->xdp_rings, vsi->num_xdp_txq);
+	if (ret)
+		return ret;
+
+	ice_for_each_rxq(vsi, i)
+		ice_tx_xsk_pool(vsi, i);
+
+	return 0;
+}
 
 /**
  * ice_cfg_itr - configure the initial interrupt throttle values
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_base.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_base.h
@@ -6,7 +6,8 @@
 
 #include "ice.h"
 
-int ice_vsi_cfg_rxq(struct ice_rx_ring *ring);
+int ice_vsi_cfg_single_rxq(struct ice_vsi *vsi, u16 q_idx);
+int ice_vsi_cfg_rxqs(struct ice_vsi *vsi);
 int __ice_vsi_get_qs(struct ice_qs_cfg *qs_cfg);
 int
 ice_vsi_ctrl_one_rx_ring(struct ice_vsi *vsi, bool ena, u16 rxq_idx, bool wait);
@@ -14,9 +15,10 @@
 int ice_vsi_alloc_q_vectors(struct ice_vsi *vsi);
 void ice_vsi_map_rings_to_vectors(struct ice_vsi *vsi);
 void ice_vsi_free_q_vectors(struct ice_vsi *vsi);
-int
-ice_vsi_cfg_txq(struct ice_vsi *vsi, struct ice_tx_ring *ring,
-		struct ice_aqc_add_tx_qgrp *qg_buf);
+int ice_vsi_cfg_single_txq(struct ice_vsi *vsi, struct ice_tx_ring **tx_rings,
+			   u16 q_idx);
+int ice_vsi_cfg_lan_txqs(struct ice_vsi *vsi);
+int ice_vsi_cfg_xdp_txqs(struct ice_vsi *vsi);
 void ice_cfg_itr(struct ice_hw *hw, struct ice_q_vector *q_vector);
 void
 ice_cfg_txq_interrupt(struct ice_vsi *vsi, u16 txq, u16 msix_idx, u16 itr_idx);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_common.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_common.c
@@ -475,7 +475,8 @@
 /**
  * ice_find_netlist_node
  * @hw: pointer to the hw struct
- * @node_type_ctx: type of netlist node to look for
+ * @node_type: type of netlist node to look for
+ * @ctx: context of the search
  * @node_part_number: node part number to look for
  * @node_handle: output parameter if node found - optional
  *
@@ -485,10 +486,12 @@
  * valid if the function returns zero, and should be ignored on any non-zero
  * return value.
  *
- * Returns: 0 if the node is found, -ENOENT if no handle was found, and
- * a negative error code on failure to access the AQ.
+ * Return:
+ * * 0 if the node is found,
+ * * -ENOENT if no handle was found,
+ * * negative error code on failure to access the AQ.
  */
-static int ice_find_netlist_node(struct ice_hw *hw, u8 node_type_ctx,
+static int ice_find_netlist_node(struct ice_hw *hw, u8 node_type, u8 ctx,
 				 u8 node_part_number, u16 *node_handle)
 {
 	u8 idx;
@@ -499,8 +502,8 @@
 		int status;
 
 		cmd.addr.topo_params.node_type_ctx =
-			FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_TYPE_M,
-				   node_type_ctx);
+			FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_TYPE_M, node_type) |
+			FIELD_PREP(ICE_AQC_LINK_TOPO_NODE_CTX_M, ctx);
 		cmd.addr.topo_params.index = idx;
 
 		status = ice_aq_get_netlist_node(hw, &cmd,
@@ -2624,9 +2627,11 @@
  */
 bool ice_is_phy_rclk_in_netlist(struct ice_hw *hw)
 {
-	if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL,
+	if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_PHY,
+				  ICE_AQC_LINK_TOPO_NODE_CTX_PORT,
 				  ICE_AQC_GET_LINK_TOPO_NODE_NR_C827, NULL) &&
-	    ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL,
+	    ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_PHY,
+				  ICE_AQC_LINK_TOPO_NODE_CTX_PORT,
 				  ICE_AQC_GET_LINK_TOPO_NODE_NR_E822_PHY, NULL))
 		return false;
 
@@ -2642,6 +2647,7 @@
 bool ice_is_clock_mux_in_netlist(struct ice_hw *hw)
 {
 	if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_MUX,
+				  ICE_AQC_LINK_TOPO_NODE_CTX_GLOBAL,
 				  ICE_AQC_GET_LINK_TOPO_NODE_NR_GEN_CLK_MUX,
 				  NULL))
 		return false;
@@ -2662,12 +2668,14 @@
 bool ice_is_cgu_in_netlist(struct ice_hw *hw)
 {
 	if (!ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL,
+				   ICE_AQC_LINK_TOPO_NODE_CTX_GLOBAL,
 				   ICE_AQC_GET_LINK_TOPO_NODE_NR_ZL30632_80032,
 				   NULL)) {
 		hw->cgu_part_number = ICE_AQC_GET_LINK_TOPO_NODE_NR_ZL30632_80032;
 		return true;
 	} else if (!ice_find_netlist_node(hw,
 					  ICE_AQC_LINK_TOPO_NODE_TYPE_CLK_CTRL,
+					  ICE_AQC_LINK_TOPO_NODE_CTX_GLOBAL,
 					  ICE_AQC_GET_LINK_TOPO_NODE_NR_SI5383_5384,
 					  NULL)) {
 		hw->cgu_part_number = ICE_AQC_GET_LINK_TOPO_NODE_NR_SI5383_5384;
@@ -2686,6 +2694,7 @@
 bool ice_is_gps_in_netlist(struct ice_hw *hw)
 {
 	if (ice_find_netlist_node(hw, ICE_AQC_LINK_TOPO_NODE_TYPE_GPS,
+				  ICE_AQC_LINK_TOPO_NODE_CTX_GLOBAL,
 				  ICE_AQC_GET_LINK_TOPO_NODE_NR_GEN_GPS, NULL))
 		return false;
 
@@ -3103,6 +3112,16 @@
 	case ICE_PHY_TYPE_HIGH_100G_AUI2:
 		speed_phy_type_high = ICE_AQ_LINK_SPEED_100GB;
 		break;
+	case ICE_PHY_TYPE_HIGH_200G_CR4_PAM4:
+	case ICE_PHY_TYPE_HIGH_200G_SR4:
+	case ICE_PHY_TYPE_HIGH_200G_FR4:
+	case ICE_PHY_TYPE_HIGH_200G_LR4:
+	case ICE_PHY_TYPE_HIGH_200G_DR4:
+	case ICE_PHY_TYPE_HIGH_200G_KR4_PAM4:
+	case ICE_PHY_TYPE_HIGH_200G_AUI4_AOC_ACC:
+	case ICE_PHY_TYPE_HIGH_200G_AUI4:
+		speed_phy_type_high = ICE_AQ_LINK_SPEED_200GB;
+		break;
 	default:
 		speed_phy_type_high = ICE_AQ_LINK_SPEED_UNKNOWN;
 		break;
@@ -4700,7 +4719,7 @@
 		enum ice_disq_rst_src rst_src, u16 vmvf_num,
 		struct ice_sq_cd *cd)
 {
-	DEFINE_FLEX(struct ice_aqc_dis_txq_item, qg_list, q_id, 1);
+	DEFINE_RAW_FLEX(struct ice_aqc_dis_txq_item, qg_list, q_id, 1);
 	u16 i, buf_size = __struct_size(qg_list);
 	struct ice_q_ctx *q_ctx;
 	int status = -ENOENT;
@@ -4922,7 +4941,7 @@
 ice_dis_vsi_rdma_qset(struct ice_port_info *pi, u16 count, u32 *qset_teid,
 		      u16 *q_id)
 {
-	DEFINE_FLEX(struct ice_aqc_dis_txq_item, qg_list, q_id, 1);
+	DEFINE_RAW_FLEX(struct ice_aqc_dis_txq_item, qg_list, q_id, 1);
 	u16 qg_size = __struct_size(qg_list);
 	struct ice_hw *hw;
 	int status = 0;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_ddp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_ddp.c
@@ -1329,6 +1329,7 @@
 
 	for (i = 0; i < count; i++) {
 		bool last = false;
+		int try_cnt = 0;
 		int status;
 
 		bh = (struct ice_buf_hdr *)(bufs + start + i);
@@ -1336,8 +1337,26 @@
 		if (indicate_last)
 			last = ice_is_last_download_buffer(bh, i, count);
 
-		status = ice_aq_download_pkg(hw, bh, ICE_PKG_BUF_SIZE, last,
-					     &offset, &info, NULL);
+		while (1) {
+			status = ice_aq_download_pkg(hw, bh, ICE_PKG_BUF_SIZE,
+						     last, &offset, &info,
+						     NULL);
+			if (hw->adminq.sq_last_status != ICE_AQ_RC_ENOSEC &&
+			    hw->adminq.sq_last_status != ICE_AQ_RC_EBADSIG)
+				break;
+
+			try_cnt++;
+
+			if (try_cnt == 5)
+				break;
+
+			msleep(20);
+		}
+
+		if (try_cnt)
+			dev_dbg(ice_hw_to_dev(hw),
+				"ice_aq_download_pkg number of retries: %d\n",
+				try_cnt);
 
 		/* Save AQ status from download package */
 		if (status) {
@@ -1424,14 +1443,14 @@
 		goto exit;
 	}
 
-	conf_idx = le32_to_cpu(seg->signed_seg_idx);
-	start = le32_to_cpu(seg->signed_buf_start);
 	count = le32_to_cpu(seg->signed_buf_count);
-
 	state = ice_download_pkg_sig_seg(hw, seg);
-	if (state)
+	if (state || !count)
 		goto exit;
 
+	conf_idx = le32_to_cpu(seg->signed_seg_idx);
+	start = le32_to_cpu(seg->signed_buf_start);
+
 	state = ice_download_pkg_config_seg(hw, pkg_hdr, conf_idx, start,
 					    count);
 
@@ -1934,8 +1953,8 @@
  */
 static enum ice_ddp_state ice_get_pkg_info(struct ice_hw *hw)
 {
-	DEFINE_FLEX(struct ice_aqc_get_pkg_info_resp, pkg_info, pkg_info,
-		    ICE_PKG_CNT);
+	DEFINE_RAW_FLEX(struct ice_aqc_get_pkg_info_resp, pkg_info, pkg_info,
+			ICE_PKG_CNT);
 	u16 size = __struct_size(pkg_info);
 	u32 i;
 
@@ -1986,8 +2005,8 @@
 					     struct ice_pkg_hdr *ospkg,
 					     struct ice_seg **seg)
 {
-	DEFINE_FLEX(struct ice_aqc_get_pkg_info_resp, pkg, pkg_info,
-		    ICE_PKG_CNT);
+	DEFINE_RAW_FLEX(struct ice_aqc_get_pkg_info_resp, pkg, pkg_info,
+			ICE_PKG_CNT);
 	u16 size = __struct_size(pkg);
 	enum ice_ddp_state state;
 	u32 i;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_debugfs.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_debugfs.c
@@ -174,7 +174,7 @@
 	if (*ppos != 0 || count > 8)
 		return -EINVAL;
 
-	cmd_buf = memdup_user(buf, count);
+	cmd_buf = memdup_user_nul(buf, count);
 	if (IS_ERR(cmd_buf))
 		return PTR_ERR(cmd_buf);
 
@@ -260,7 +260,7 @@
 	if (*ppos != 0 || count > 4)
 		return -EINVAL;
 
-	cmd_buf = memdup_user(buf, count);
+	cmd_buf = memdup_user_nul(buf, count);
 	if (IS_ERR(cmd_buf))
 		return PTR_ERR(cmd_buf);
 
@@ -335,7 +335,7 @@
 	if (*ppos != 0 || count > 2)
 		return -EINVAL;
 
-	cmd_buf = memdup_user(buf, count);
+	cmd_buf = memdup_user_nul(buf, count);
 	if (IS_ERR(cmd_buf))
 		return PTR_ERR(cmd_buf);
 
@@ -431,7 +431,7 @@
 	if (*ppos != 0 || count > 5)
 		return -EINVAL;
 
-	cmd_buf = memdup_user(buf, count);
+	cmd_buf = memdup_user_nul(buf, count);
 	if (IS_ERR(cmd_buf))
 		return PTR_ERR(cmd_buf);
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_devlink.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_devlink.c
@@ -445,6 +445,20 @@
 }
 
 /**
+ * ice_devlink_reinit_down - unload given PF
+ * @pf: pointer to the PF struct
+ */
+static void ice_devlink_reinit_down(struct ice_pf *pf)
+{
+	/* No need to take devl_lock, it's already taken by devlink API */
+	ice_unload(pf);
+	rtnl_lock();
+	ice_vsi_decfg(ice_get_main_vsi(pf));
+	rtnl_unlock();
+	ice_deinit_dev(pf);
+}
+
+/**
  * ice_devlink_reload_down - prepare for reload
  * @devlink: pointer to the devlink instance to reload
  * @netns_change: if true, the network namespace is changing
@@ -477,7 +491,7 @@
 					   "Remove all VFs before doing reinit\n");
 			return -EOPNOTSUPP;
 		}
-		ice_unload(pf);
+		ice_devlink_reinit_down(pf);
 		return 0;
 	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
 		return ice_devlink_reload_empr_start(pf, extack);
@@ -1270,6 +1284,45 @@
 }
 
 /**
+ * ice_devlink_reinit_up - do reinit of the given PF
+ * @pf: pointer to the PF struct
+ */
+static int ice_devlink_reinit_up(struct ice_pf *pf)
+{
+	struct ice_vsi *vsi = ice_get_main_vsi(pf);
+	struct ice_vsi_cfg_params params;
+	int err;
+
+	err = ice_init_dev(pf);
+	if (err)
+		return err;
+
+	params = ice_vsi_to_params(vsi);
+	params.flags = ICE_VSI_FLAG_INIT;
+
+	rtnl_lock();
+	err = ice_vsi_cfg(vsi, &params);
+	rtnl_unlock();
+	if (err)
+		goto err_vsi_cfg;
+
+	/* No need to take devl_lock, it's already taken by devlink API */
+	err = ice_load(pf);
+	if (err)
+		goto err_load;
+
+	return 0;
+
+err_load:
+	rtnl_lock();
+	ice_vsi_decfg(vsi);
+	rtnl_unlock();
+err_vsi_cfg:
+	ice_deinit_dev(pf);
+	return err;
+}
+
+/**
  * ice_devlink_reload_up - do reload up after reinit
  * @devlink: pointer to the devlink instance reloading
  * @action: the action requested
@@ -1289,7 +1342,7 @@
 	switch (action) {
 	case DEVLINK_RELOAD_ACTION_DRIVER_REINIT:
 		*actions_performed = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
-		return ice_load(pf);
+		return ice_devlink_reinit_up(pf);
 	case DEVLINK_RELOAD_ACTION_FW_ACTIVATE:
 		*actions_performed = BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE);
 		return ice_devlink_reload_empr_finish(pf, extack);
@@ -1569,6 +1622,7 @@
  * @pf: the PF to create a devlink port for
  *
  * Create and register a devlink_port for this PF.
+ * This function has to be called under devl_lock.
  *
  * Return: zero on success or an error code on failure.
  */
@@ -1581,6 +1635,8 @@
 	struct device *dev;
 	int err;
 
+	devlink = priv_to_devlink(pf);
+
 	dev = ice_pf_to_dev(pf);
 
 	devlink_port = &pf->devlink_port;
@@ -1590,7 +1646,7 @@
 		return -EIO;
 
 	attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
-	attrs.phys.port_number = pf->hw.bus.func;
+	attrs.phys.port_number = pf->hw.pf_id;
 
 	/* As FW supports only port split options for whole device,
 	 * set port split options only for first PF.
@@ -1601,10 +1657,9 @@
 	ice_devlink_set_switch_id(pf, &attrs.switch_id);
 
 	devlink_port_attrs_set(devlink_port, &attrs);
-	devlink = priv_to_devlink(pf);
 
-	err = devlink_port_register_with_ops(devlink, devlink_port, vsi->idx,
-					     &ice_devlink_port_ops);
+	err = devl_port_register_with_ops(devlink, devlink_port, vsi->idx,
+					  &ice_devlink_port_ops);
 	if (err) {
 		dev_err(dev, "Failed to create devlink port for PF %d, error %d\n",
 			pf->hw.pf_id, err);
@@ -1619,10 +1674,11 @@
  * @pf: the PF to cleanup
  *
  * Unregisters the devlink_port structure associated with this PF.
+ * This function has to be called under devl_lock.
  */
 void ice_devlink_destroy_pf_port(struct ice_pf *pf)
 {
-	devlink_port_unregister(&pf->devlink_port);
+	devl_port_unregister(&pf->devlink_port);
 }
 
 /**
@@ -1652,7 +1708,7 @@
 		return -EINVAL;
 
 	attrs.flavour = DEVLINK_PORT_FLAVOUR_PCI_VF;
-	attrs.pci_vf.pf = pf->hw.bus.func;
+	attrs.pci_vf.pf = pf->hw.pf_id;
 	attrs.pci_vf.vf = vf->vf_id;
 
 	ice_devlink_set_switch_id(pf, &attrs.switch_id);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_dpll.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_dpll.c
@@ -9,6 +9,8 @@
 #define ICE_CGU_STATE_ACQ_ERR_THRESHOLD		50
 #define ICE_DPLL_PIN_IDX_INVALID		0xff
 #define ICE_DPLL_RCLK_NUM_PER_PF		1
+#define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT	25
+#define ICE_DPLL_PIN_GEN_RCLK_FREQ		1953125
 
 /**
  * enum ice_dpll_pin_type - enumerate ice pin types:
@@ -30,6 +32,10 @@
 	[ICE_DPLL_PIN_TYPE_RCLK_INPUT] = "rclk-input",
 };
 
+static const struct dpll_pin_frequency ice_esync_range[] = {
+	DPLL_PIN_FREQUENCY_RANGE(0, DPLL_PIN_FREQUENCY_1_HZ),
+};
+
 /**
  * ice_dpll_is_reset - check if reset is in progress
  * @pf: private board structure
@@ -394,8 +400,8 @@
 
 	switch (pin_type) {
 	case ICE_DPLL_PIN_TYPE_INPUT:
-		ret = ice_aq_get_input_pin_cfg(&pf->hw, pin->idx, NULL, NULL,
-					       NULL, &pin->flags[0],
+		ret = ice_aq_get_input_pin_cfg(&pf->hw, pin->idx, &pin->status,
+					       NULL, NULL, &pin->flags[0],
 					       &pin->freq, &pin->phase_adjust);
 		if (ret)
 			goto err;
@@ -430,7 +436,7 @@
 			goto err;
 
 		parent &= ICE_AQC_GET_CGU_OUT_CFG_DPLL_SRC_SEL;
-		if (ICE_AQC_SET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) {
+		if (ICE_AQC_GET_CGU_OUT_CFG_OUT_EN & pin->flags[0]) {
 			pin->state[pf->dplls.eec.dpll_idx] =
 				parent == pf->dplls.eec.dpll_idx ?
 				DPLL_PIN_STATE_CONNECTED :
@@ -649,6 +655,8 @@
 	struct ice_dpll_pin *p = pin_priv;
 	struct ice_dpll *d = dpll_priv;
 
+	if (state == DPLL_PIN_STATE_SELECTABLE)
+		return -EINVAL;
 	if (!enable && p->state[d->dpll_idx] == DPLL_PIN_STATE_DISCONNECTED)
 		return 0;
 
@@ -1097,6 +1105,214 @@
 }
 
 /**
+ * ice_dpll_output_esync_set - callback for setting embedded sync
+ * @pin: pointer to a pin
+ * @pin_priv: private data pointer passed on pin registration
+ * @dpll: registered dpll pointer
+ * @dpll_priv: private data pointer passed on dpll registration
+ * @freq: requested embedded sync frequency
+ * @extack: error reporting
+ *
+ * Dpll subsystem callback. Handler for setting embedded sync frequency value
+ * on output pin.
+ *
+ * Context: Acquires pf->dplls.lock
+ * Return:
+ * * 0 - success
+ * * negative - error
+ */
+static int
+ice_dpll_output_esync_set(const struct dpll_pin *pin, void *pin_priv,
+			  const struct dpll_device *dpll, void *dpll_priv,
+			  u64 freq, struct netlink_ext_ack *extack)
+{
+	struct ice_dpll_pin *p = pin_priv;
+	struct ice_dpll *d = dpll_priv;
+	struct ice_pf *pf = d->pf;
+	u8 flags = 0;
+	int ret;
+
+	if (ice_dpll_is_reset(pf, extack))
+		return -EBUSY;
+	mutex_lock(&pf->dplls.lock);
+	if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_OUT_EN)
+		flags = ICE_AQC_SET_CGU_OUT_CFG_OUT_EN;
+	if (freq == DPLL_PIN_FREQUENCY_1_HZ) {
+		if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) {
+			ret = 0;
+		} else {
+			flags |= ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
+			ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags,
+							0, 0, 0);
+		}
+	} else {
+		if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN)) {
+			ret = 0;
+		} else {
+			flags &= ~ICE_AQC_SET_CGU_OUT_CFG_ESYNC_EN;
+			ret = ice_aq_set_output_pin_cfg(&pf->hw, p->idx, flags,
+							0, 0, 0);
+		}
+	}
+	mutex_unlock(&pf->dplls.lock);
+
+	return ret;
+}
+
+/**
+ * ice_dpll_output_esync_get - callback for getting embedded sync config
+ * @pin: pointer to a pin
+ * @pin_priv: private data pointer passed on pin registration
+ * @dpll: registered dpll pointer
+ * @dpll_priv: private data pointer passed on dpll registration
+ * @esync: on success holds embedded sync pin properties
+ * @extack: error reporting
+ *
+ * Dpll subsystem callback. Handler for getting embedded sync frequency value
+ * and capabilities on output pin.
+ *
+ * Context: Acquires pf->dplls.lock
+ * Return:
+ * * 0 - success
+ * * negative - error
+ */
+static int
+ice_dpll_output_esync_get(const struct dpll_pin *pin, void *pin_priv,
+			  const struct dpll_device *dpll, void *dpll_priv,
+			  struct dpll_pin_esync *esync,
+			  struct netlink_ext_ack *extack)
+{
+	struct ice_dpll_pin *p = pin_priv;
+	struct ice_dpll *d = dpll_priv;
+	struct ice_pf *pf = d->pf;
+
+	if (ice_dpll_is_reset(pf, extack))
+		return -EBUSY;
+	mutex_lock(&pf->dplls.lock);
+	if (!(p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_ABILITY) ||
+	    p->freq != DPLL_PIN_FREQUENCY_10_MHZ) {
+		mutex_unlock(&pf->dplls.lock);
+		return -EOPNOTSUPP;
+	}
+	esync->range = ice_esync_range;
+	esync->range_num = ARRAY_SIZE(ice_esync_range);
+	if (p->flags[0] & ICE_AQC_GET_CGU_OUT_CFG_ESYNC_EN) {
+		esync->freq = DPLL_PIN_FREQUENCY_1_HZ;
+		esync->pulse = ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT;
+	} else {
+		esync->freq = 0;
+		esync->pulse = 0;
+	}
+	mutex_unlock(&pf->dplls.lock);
+
+	return 0;
+}
+
+/**
+ * ice_dpll_input_esync_set - callback for setting embedded sync
+ * @pin: pointer to a pin
+ * @pin_priv: private data pointer passed on pin registration
+ * @dpll: registered dpll pointer
+ * @dpll_priv: private data pointer passed on dpll registration
+ * @freq: requested embedded sync frequency
+ * @extack: error reporting
+ *
+ * Dpll subsystem callback. Handler for setting embedded sync frequency value
+ * on input pin.
+ *
+ * Context: Acquires pf->dplls.lock
+ * Return:
+ * * 0 - success
+ * * negative - error
+ */
+static int
+ice_dpll_input_esync_set(const struct dpll_pin *pin, void *pin_priv,
+			 const struct dpll_device *dpll, void *dpll_priv,
+			 u64 freq, struct netlink_ext_ack *extack)
+{
+	struct ice_dpll_pin *p = pin_priv;
+	struct ice_dpll *d = dpll_priv;
+	struct ice_pf *pf = d->pf;
+	u8 flags_en = 0;
+	int ret;
+
+	if (ice_dpll_is_reset(pf, extack))
+		return -EBUSY;
+	mutex_lock(&pf->dplls.lock);
+	if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_INPUT_EN)
+		flags_en = ICE_AQC_SET_CGU_IN_CFG_FLG2_INPUT_EN;
+	if (freq == DPLL_PIN_FREQUENCY_1_HZ) {
+		if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) {
+			ret = 0;
+		} else {
+			flags_en |= ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
+			ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0,
+						       flags_en, 0, 0);
+		}
+	} else {
+		if (!(p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN)) {
+			ret = 0;
+		} else {
+			flags_en &= ~ICE_AQC_SET_CGU_IN_CFG_FLG2_ESYNC_EN;
+			ret = ice_aq_set_input_pin_cfg(&pf->hw, p->idx, 0,
+						       flags_en, 0, 0);
+		}
+	}
+	mutex_unlock(&pf->dplls.lock);
+
+	return ret;
+}
+
+/**
+ * ice_dpll_input_esync_get - callback for getting embedded sync config
+ * @pin: pointer to a pin
+ * @pin_priv: private data pointer passed on pin registration
+ * @dpll: registered dpll pointer
+ * @dpll_priv: private data pointer passed on dpll registration
+ * @esync: on success holds embedded sync pin properties
+ * @extack: error reporting
+ *
+ * Dpll subsystem callback. Handler for getting embedded sync frequency value
+ * and capabilities on input pin.
+ *
+ * Context: Acquires pf->dplls.lock
+ * Return:
+ * * 0 - success
+ * * negative - error
+ */
+static int
+ice_dpll_input_esync_get(const struct dpll_pin *pin, void *pin_priv,
+			 const struct dpll_device *dpll, void *dpll_priv,
+			 struct dpll_pin_esync *esync,
+			 struct netlink_ext_ack *extack)
+{
+	struct ice_dpll_pin *p = pin_priv;
+	struct ice_dpll *d = dpll_priv;
+	struct ice_pf *pf = d->pf;
+
+	if (ice_dpll_is_reset(pf, extack))
+		return -EBUSY;
+	mutex_lock(&pf->dplls.lock);
+	if (!(p->status & ICE_AQC_GET_CGU_IN_CFG_STATUS_ESYNC_CAP) ||
+	    p->freq != DPLL_PIN_FREQUENCY_10_MHZ) {
+		mutex_unlock(&pf->dplls.lock);
+		return -EOPNOTSUPP;
+	}
+	esync->range = ice_esync_range;
+	esync->range_num = ARRAY_SIZE(ice_esync_range);
+	if (p->flags[0] & ICE_AQC_GET_CGU_IN_CFG_FLG2_ESYNC_EN) {
+		esync->freq = DPLL_PIN_FREQUENCY_1_HZ;
+		esync->pulse = ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT;
+	} else {
+		esync->freq = 0;
+		esync->pulse = 0;
+	}
+	mutex_unlock(&pf->dplls.lock);
+
+	return 0;
+}
+
+/**
  * ice_dpll_rclk_state_on_pin_set - set a state on rclk pin
  * @pin: pointer to a pin
  * @pin_priv: private data pointer passed on pin registration
@@ -1220,6 +1436,8 @@
 	.phase_adjust_get = ice_dpll_pin_phase_adjust_get,
 	.phase_adjust_set = ice_dpll_input_phase_adjust_set,
 	.phase_offset_get = ice_dpll_phase_offset_get,
+	.esync_set = ice_dpll_input_esync_set,
+	.esync_get = ice_dpll_input_esync_get,
 };
 
 static const struct dpll_pin_ops ice_dpll_output_ops = {
@@ -1230,6 +1448,8 @@
 	.direction_get = ice_dpll_output_direction,
 	.phase_adjust_get = ice_dpll_pin_phase_adjust_get,
 	.phase_adjust_set = ice_dpll_output_phase_adjust_set,
+	.esync_set = ice_dpll_output_esync_set,
+	.esync_get = ice_dpll_output_esync_get,
 };
 
 static const struct dpll_device_ops ice_dpll_ops = {
@@ -1624,6 +1844,8 @@
 	struct dpll_pin *parent;
 	int ret, i;
 
+	if (WARN_ON((!vsi || !vsi->netdev)))
+		return -EINVAL;
 	ret = ice_dpll_get_pins(pf, pin, start_idx, ICE_DPLL_RCLK_NUM_PER_PF,
 				pf->dplls.clock_id);
 	if (ret)
@@ -1639,8 +1861,6 @@
 		if (ret)
 			goto unregister_pins;
 	}
-	if (WARN_ON((!vsi || !vsi->netdev)))
-		return -EINVAL;
 	dpll_netdev_pin_set(vsi->netdev, pf->dplls.rclk.pin);
 
 	return 0;
@@ -1843,6 +2063,85 @@
 }
 
 /**
+ * ice_dpll_phase_range_set - initialize phase adjust range helper
+ * @range: pointer to phase adjust range struct to be initialized
+ * @phase_adj: a value to be used as min(-)/max(+) boundary
+ */
+static void ice_dpll_phase_range_set(struct dpll_pin_phase_adjust_range *range,
+				     u32 phase_adj)
+{
+	range->min = -phase_adj;
+	range->max = phase_adj;
+}
+
+/**
+ * ice_dpll_init_info_pins_generic - initializes generic pins info
+ * @pf: board private structure
+ * @input: if input pins initialized
+ *
+ * Init information for generic pins, cache them in PF's pins structures.
+ *
+ * Return:
+ * * 0 - success
+ * * negative - init failure reason
+ */
+static int ice_dpll_init_info_pins_generic(struct ice_pf *pf, bool input)
+{
+	struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps;
+	static const char labels[][sizeof("99")] = {
+		"0", "1", "2", "3", "4", "5", "6", "7", "8",
+		"9", "10", "11", "12", "13", "14", "15" };
+	u32 cap = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
+	enum ice_dpll_pin_type pin_type;
+	int i, pin_num, ret = -EINVAL;
+	struct ice_dpll_pin *pins;
+	u32 phase_adj_max;
+
+	if (input) {
+		pin_num = pf->dplls.num_inputs;
+		pins = pf->dplls.inputs;
+		phase_adj_max = pf->dplls.input_phase_adj_max;
+		pin_type = ICE_DPLL_PIN_TYPE_INPUT;
+		cap |= DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE;
+	} else {
+		pin_num = pf->dplls.num_outputs;
+		pins = pf->dplls.outputs;
+		phase_adj_max = pf->dplls.output_phase_adj_max;
+		pin_type = ICE_DPLL_PIN_TYPE_OUTPUT;
+	}
+	if (pin_num > ARRAY_SIZE(labels))
+		return ret;
+
+	for (i = 0; i < pin_num; i++) {
+		pins[i].idx = i;
+		pins[i].prop.board_label = labels[i];
+		ice_dpll_phase_range_set(&pins[i].prop.phase_range,
+					 phase_adj_max);
+		pins[i].prop.capabilities = cap;
+		pins[i].pf = pf;
+		ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
+		if (ret)
+			break;
+		if (input && pins[i].freq == ICE_DPLL_PIN_GEN_RCLK_FREQ)
+			pins[i].prop.type = DPLL_PIN_TYPE_MUX;
+		else
+			pins[i].prop.type = DPLL_PIN_TYPE_EXT;
+		if (!input)
+			continue;
+		ret = ice_aq_get_cgu_ref_prio(&pf->hw, de->dpll_idx, i,
+					      &de->input_prio[i]);
+		if (ret)
+			break;
+		ret = ice_aq_get_cgu_ref_prio(&pf->hw, dp->dpll_idx, i,
+					      &dp->input_prio[i]);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+/**
  * ice_dpll_init_info_direct_pins - initializes direct pins info
  * @pf: board private structure
  * @pin_type: type of pins being initialized
@@ -1863,6 +2162,7 @@
 	struct ice_hw *hw = &pf->hw;
 	struct ice_dpll_pin *pins;
 	unsigned long caps;
+	u32 phase_adj_max;
 	u8 freq_supp_num;
 	bool input;
 
@@ -1870,16 +2170,20 @@
 	case ICE_DPLL_PIN_TYPE_INPUT:
 		pins = pf->dplls.inputs;
 		num_pins = pf->dplls.num_inputs;
+		phase_adj_max = pf->dplls.input_phase_adj_max;
 		input = true;
 		break;
 	case ICE_DPLL_PIN_TYPE_OUTPUT:
 		pins = pf->dplls.outputs;
 		num_pins = pf->dplls.num_outputs;
+		phase_adj_max = pf->dplls.output_phase_adj_max;
 		input = false;
 		break;
 	default:
 		return -EINVAL;
 	}
+	if (num_pins != ice_cgu_get_num_pins(hw, input))
+		return ice_dpll_init_info_pins_generic(pf, input);
 
 	for (i = 0; i < num_pins; i++) {
 		caps = 0;
@@ -1897,19 +2201,13 @@
 				return ret;
 			caps |= (DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE |
 				 DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE);
-			pins[i].prop.phase_range.min =
-				pf->dplls.input_phase_adj_max;
-			pins[i].prop.phase_range.max =
-				-pf->dplls.input_phase_adj_max;
 		} else {
-			pins[i].prop.phase_range.min =
-				pf->dplls.output_phase_adj_max;
-			pins[i].prop.phase_range.max =
-				-pf->dplls.output_phase_adj_max;
 			ret = ice_cgu_get_output_pin_state_caps(hw, i, &caps);
 			if (ret)
 				return ret;
 		}
+		ice_dpll_phase_range_set(&pins[i].prop.phase_range,
+					 phase_adj_max);
 		pins[i].prop.capabilities = caps;
 		ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
 		if (ret)
@@ -2017,8 +2315,10 @@
 	dp->dpll_idx = abilities.pps_dpll_idx;
 	d->num_inputs = abilities.num_inputs;
 	d->num_outputs = abilities.num_outputs;
-	d->input_phase_adj_max = le32_to_cpu(abilities.max_in_phase_adj);
-	d->output_phase_adj_max = le32_to_cpu(abilities.max_out_phase_adj);
+	d->input_phase_adj_max = le32_to_cpu(abilities.max_in_phase_adj) &
+		ICE_AQC_GET_CGU_MAX_PHASE_ADJ;
+	d->output_phase_adj_max = le32_to_cpu(abilities.max_out_phase_adj) &
+		ICE_AQC_GET_CGU_MAX_PHASE_ADJ;
 
 	alloc_size = sizeof(*d->inputs) * d->num_inputs;
 	d->inputs = kzalloc(alloc_size, GFP_KERNEL);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_dpll.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_dpll.h
@@ -31,6 +31,7 @@
 	struct dpll_pin_properties prop;
 	u32 freq;
 	s32 phase_adjust;
+	u8 status;
 };
 
 /** ice_dpll - store info required for DPLL control
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_eswitch_br.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_eswitch_br.c
@@ -582,10 +582,13 @@
 	return NOTIFY_DONE;
 }
 
-static void ice_eswitch_br_fdb_flush(struct ice_esw_br *bridge)
+void ice_eswitch_br_fdb_flush(struct ice_esw_br *bridge)
 {
 	struct ice_esw_br_fdb_entry *entry, *tmp;
 
+	if (!bridge)
+		return;
+
 	list_for_each_entry_safe(entry, tmp, &bridge->fdb_list, list)
 		ice_eswitch_br_fdb_entry_notify_and_cleanup(bridge, entry);
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_eswitch_br.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_eswitch_br.h
@@ -116,5 +116,6 @@
 ice_eswitch_br_offloads_deinit(struct ice_pf *pf);
 int
 ice_eswitch_br_offloads_init(struct ice_pf *pf);
+void ice_eswitch_br_fdb_flush(struct ice_esw_br *bridge);
 
 #endif /* _ICE_ESWITCH_BR_H_ */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_ethtool.c
@@ -3514,7 +3514,6 @@
 	struct ice_pf *pf = vsi->back;
 	int new_rx = 0, new_tx = 0;
 	bool locked = false;
-	u32 curr_combined;
 	int ret = 0;
 
 	/* do not support changing channels in Safe Mode */
@@ -3536,22 +3535,8 @@
 		return -EOPNOTSUPP;
 	}
 
-	curr_combined = ice_get_combined_cnt(vsi);
-
-	/* these checks are for cases where user didn't specify a particular
-	 * value on cmd line but we get non-zero value anyway via
-	 * get_channels(); look at ethtool.c in ethtool repository (the user
-	 * space part), particularly, do_schannels() routine
-	 */
-	if (ch->rx_count == vsi->num_rxq - curr_combined)
-		ch->rx_count = 0;
-	if (ch->tx_count == vsi->num_txq - curr_combined)
-		ch->tx_count = 0;
-	if (ch->combined_count == curr_combined)
-		ch->combined_count = 0;
-
-	if (!(ch->combined_count || (ch->rx_count && ch->tx_count))) {
-		netdev_err(dev, "Please specify at least 1 Rx and 1 Tx channel\n");
+	if (ch->rx_count && ch->tx_count) {
+		netdev_err(dev, "Dedicated RX or TX channels cannot be used simultaneously\n");
 		return -EINVAL;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c
@@ -526,7 +526,7 @@
  *
  * Returns the number of available flow director filters to this VSI
  */
-static int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi)
+int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi)
 {
 	u16 vsi_num = ice_get_hw_vsi_num(hw, vsi->idx);
 	u16 num_guar;
@@ -1696,11 +1696,12 @@
 ice_set_fdir_input_set(struct ice_vsi *vsi, struct ethtool_rx_flow_spec *fsp,
 		       struct ice_fdir_fltr *input)
 {
-	u16 dest_vsi, q_index = 0;
+	s16 q_index = ICE_FDIR_NO_QUEUE_IDX;
 	u16 orig_q_index = 0;
 	struct ice_pf *pf;
 	struct ice_hw *hw;
 	int flow_type;
+	u16 dest_vsi;
 	u8 dest_ctl;
 
 	if (!vsi || !fsp || !input)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_fdir.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_fdir.h
@@ -50,6 +50,8 @@
  */
 #define ICE_FDIR_IPV4_PKT_FLAG_MF		0x20
 
+#define ICE_FDIR_NO_QUEUE_IDX			-1
+
 enum ice_fltr_prgm_desc_dest {
 	ICE_FLTR_PRGM_DESC_DEST_DROP_PKT,
 	ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QINDEX,
@@ -181,7 +183,7 @@
 	u16 flex_fltr;
 
 	/* filter control */
-	u16 q_index;
+	s16 q_index;
 	u16 orig_q_index;
 	u16 dest_vsi;
 	u8 dest_ctl;
@@ -202,6 +204,8 @@
 	const u8 *tun_pkt;
 };
 
+struct ice_vsi;
+
 int ice_alloc_fd_res_cntr(struct ice_hw *hw, u16 *cntr_id);
 int ice_free_fd_res_cntr(struct ice_hw *hw, u16 cntr_id);
 int ice_alloc_fd_guar_item(struct ice_hw *hw, u16 *cntr_id, u16 num_fltr);
@@ -213,6 +217,7 @@
 ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
 			  u8 *pkt, bool frag, bool tun);
 int ice_get_fdir_cnt_all(struct ice_hw *hw);
+int ice_fdir_num_avail_fltr(struct ice_hw *hw, struct ice_vsi *vsi);
 bool ice_fdir_is_dup_fltr(struct ice_hw *hw, struct ice_fdir_fltr *input);
 bool ice_fdir_has_frag(enum ice_fltr_ptype flow);
 struct ice_fdir_fltr *
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_hwmon.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_hwmon.c
@@ -96,7 +96,7 @@
 
 	unsigned long sensors = pf->hw.dev_caps.supported_sensors;
 
-	return _test_bit(ICE_SENSOR_SUPPORT_E810_INT_TEMP_BIT, &sensors);
+	return test_bit(ICE_SENSOR_SUPPORT_E810_INT_TEMP_BIT, &sensors);
 };
 
 void ice_hwmon_init(struct ice_pf *pf)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_lag.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_lag.c
@@ -491,7 +491,7 @@
 ice_lag_move_vf_node_tc(struct ice_lag *lag, u8 oldport, u8 newport,
 			u16 vsi_num, u8 tc)
 {
-	DEFINE_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
+	DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
 	struct device *dev = ice_pf_to_dev(lag->pf);
 	u16 numq, valq, num_moved, qbuf_size;
 	u16 buf_size = __struct_size(buf);
@@ -849,7 +849,7 @@
 ice_lag_reclaim_vf_tc(struct ice_lag *lag, struct ice_hw *src_hw, u16 vsi_num,
 		      u8 tc)
 {
-	DEFINE_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
+	DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
 	struct device *dev = ice_pf_to_dev(lag->pf);
 	u16 numq, valq, num_moved, qbuf_size;
 	u16 buf_size = __struct_size(buf);
@@ -1873,7 +1873,7 @@
 ice_lag_move_vf_nodes_tc_sync(struct ice_lag *lag, struct ice_hw *dest_hw,
 			      u16 vsi_num, u8 tc)
 {
-	DEFINE_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
+	DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
 	struct device *dev = ice_pf_to_dev(lag->pf);
 	u16 numq, valq, num_moved, qbuf_size;
 	u16 buf_size = __struct_size(buf);
@@ -2041,7 +2041,7 @@
 	/* associate recipes to profiles */
 	for (n = 0; n < ICE_PROFID_IPV6_GTPU_IPV6_TCP_INNER; n++) {
 		err = ice_aq_get_recipe_to_profile(&pf->hw, n,
-						   (u8 *)&recipe_bits, NULL);
+						   &recipe_bits, NULL);
 		if (err)
 			continue;
 
@@ -2049,7 +2049,7 @@
 			recipe_bits |= BIT(lag->pf_recipe) |
 				       BIT(lag->lport_recipe);
 			ice_aq_map_recipe_to_profile(&pf->hw, n,
-						     (u8 *)&recipe_bits, NULL);
+						     recipe_bits, NULL);
 		}
 	}
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_lib.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -117,14 +117,8 @@
 	if (!vsi->q_vectors)
 		goto err_vectors;
 
-	vsi->af_xdp_zc_qps = bitmap_zalloc(max_t(int, vsi->alloc_txq, vsi->alloc_rxq), GFP_KERNEL);
-	if (!vsi->af_xdp_zc_qps)
-		goto err_zc_qps;
-
 	return 0;
 
-err_zc_qps:
-	devm_kfree(dev, vsi->q_vectors);
 err_vectors:
 	devm_kfree(dev, vsi->rxq_map);
 err_rxq_map:
@@ -328,8 +322,6 @@
 
 	dev = ice_pf_to_dev(pf);
 
-	bitmap_free(vsi->af_xdp_zc_qps);
-	vsi->af_xdp_zc_qps = NULL;
 	/* free the ring and vector containers */
 	devm_kfree(dev, vsi->q_vectors);
 	vsi->q_vectors = NULL;
@@ -474,6 +466,7 @@
 
 	ice_vsi_free_stats(vsi);
 	ice_vsi_free_arrays(vsi);
+	mutex_destroy(&vsi->xdp_state_lock);
 	mutex_unlock(&pf->sw_mutex);
 	devm_kfree(dev, vsi);
 }
@@ -673,6 +666,8 @@
 	pf->next_vsi = ice_get_free_slot(pf->vsi, pf->num_alloc_vsi,
 					 pf->next_vsi);
 
+	mutex_init(&vsi->xdp_state_lock);
+
 unlock_pf:
 	mutex_unlock(&pf->sw_mutex);
 	return vsi;
@@ -1672,27 +1667,6 @@
 }
 
 /**
- * ice_vsi_cfg_frame_size - setup max frame size and Rx buffer length
- * @vsi: VSI
- */
-static void ice_vsi_cfg_frame_size(struct ice_vsi *vsi)
-{
-	if (!vsi->netdev || test_bit(ICE_FLAG_LEGACY_RX, vsi->back->flags)) {
-		vsi->max_frame = ICE_MAX_FRAME_LEGACY_RX;
-		vsi->rx_buf_len = ICE_RXBUF_1664;
-#if (PAGE_SIZE < 8192)
-	} else if (!ICE_2K_TOO_SMALL_WITH_PADDING &&
-		   (vsi->netdev->mtu <= ETH_DATA_LEN)) {
-		vsi->max_frame = ICE_RXBUF_1536 - NET_IP_ALIGN;
-		vsi->rx_buf_len = ICE_RXBUF_1536 - NET_IP_ALIGN;
-#endif
-	} else {
-		vsi->max_frame = ICE_AQ_SET_MAC_FRAME_SIZE_MAX;
-		vsi->rx_buf_len = ICE_RXBUF_3072;
-	}
-}
-
-/**
  * ice_pf_state_is_nominal - checks the PF for nominal state
  * @pf: pointer to PF to check
  *
@@ -1795,114 +1769,6 @@
 	wr32(hw, QRXFLXP_CNTXT(pf_q), regval);
 }
 
-int ice_vsi_cfg_single_rxq(struct ice_vsi *vsi, u16 q_idx)
-{
-	if (q_idx >= vsi->num_rxq)
-		return -EINVAL;
-
-	return ice_vsi_cfg_rxq(vsi->rx_rings[q_idx]);
-}
-
-int ice_vsi_cfg_single_txq(struct ice_vsi *vsi, struct ice_tx_ring **tx_rings, u16 q_idx)
-{
-	DEFINE_FLEX(struct ice_aqc_add_tx_qgrp, qg_buf, txqs, 1);
-
-	if (q_idx >= vsi->alloc_txq || !tx_rings || !tx_rings[q_idx])
-		return -EINVAL;
-
-	qg_buf->num_txqs = 1;
-
-	return ice_vsi_cfg_txq(vsi, tx_rings[q_idx], qg_buf);
-}
-
-/**
- * ice_vsi_cfg_rxqs - Configure the VSI for Rx
- * @vsi: the VSI being configured
- *
- * Return 0 on success and a negative value on error
- * Configure the Rx VSI for operation.
- */
-int ice_vsi_cfg_rxqs(struct ice_vsi *vsi)
-{
-	u16 i;
-
-	if (vsi->type == ICE_VSI_VF)
-		goto setup_rings;
-
-	ice_vsi_cfg_frame_size(vsi);
-setup_rings:
-	/* set up individual rings */
-	ice_for_each_rxq(vsi, i) {
-		int err = ice_vsi_cfg_rxq(vsi->rx_rings[i]);
-
-		if (err)
-			return err;
-	}
-
-	return 0;
-}
-
-/**
- * ice_vsi_cfg_txqs - Configure the VSI for Tx
- * @vsi: the VSI being configured
- * @rings: Tx ring array to be configured
- * @count: number of Tx ring array elements
- *
- * Return 0 on success and a negative value on error
- * Configure the Tx VSI for operation.
- */
-static int
-ice_vsi_cfg_txqs(struct ice_vsi *vsi, struct ice_tx_ring **rings, u16 count)
-{
-	DEFINE_FLEX(struct ice_aqc_add_tx_qgrp, qg_buf, txqs, 1);
-	int err = 0;
-	u16 q_idx;
-
-	qg_buf->num_txqs = 1;
-
-	for (q_idx = 0; q_idx < count; q_idx++) {
-		err = ice_vsi_cfg_txq(vsi, rings[q_idx], qg_buf);
-		if (err)
-			break;
-	}
-
-	return err;
-}
-
-/**
- * ice_vsi_cfg_lan_txqs - Configure the VSI for Tx
- * @vsi: the VSI being configured
- *
- * Return 0 on success and a negative value on error
- * Configure the Tx VSI for operation.
- */
-int ice_vsi_cfg_lan_txqs(struct ice_vsi *vsi)
-{
-	return ice_vsi_cfg_txqs(vsi, vsi->tx_rings, vsi->num_txq);
-}
-
-/**
- * ice_vsi_cfg_xdp_txqs - Configure Tx queues dedicated for XDP in given VSI
- * @vsi: the VSI being configured
- *
- * Return 0 on success and a negative value on error
- * Configure the Tx queues dedicated for XDP in given VSI for operation.
- */
-int ice_vsi_cfg_xdp_txqs(struct ice_vsi *vsi)
-{
-	int ret;
-	int i;
-
-	ret = ice_vsi_cfg_txqs(vsi, vsi->xdp_rings, vsi->num_xdp_txq);
-	if (ret)
-		return ret;
-
-	ice_for_each_rxq(vsi, i)
-		ice_tx_xsk_pool(vsi, i);
-
-	return 0;
-}
-
 /**
  * ice_intrl_usec_to_reg - convert interrupt rate limit to register value
  * @intrl: interrupt rate limit in usecs
@@ -2423,22 +2289,20 @@
 		if (ret)
 			goto unroll_vector_base;
 
-		ice_vsi_map_rings_to_vectors(vsi);
-
-		/* Associate q_vector rings to napi */
-		ice_vsi_set_napi_queues(vsi);
-
-		vsi->stat_offsets_loaded = false;
-
 		if (ice_is_xdp_ena_vsi(vsi)) {
 			ret = ice_vsi_determine_xdp_res(vsi);
 			if (ret)
 				goto unroll_vector_base;
-			ret = ice_prepare_xdp_rings(vsi, vsi->xdp_prog);
+			ret = ice_prepare_xdp_rings(vsi, vsi->xdp_prog,
+						    ICE_XDP_CFG_PART);
 			if (ret)
 				goto unroll_vector_base;
 		}
 
+		ice_vsi_map_rings_to_vectors(vsi);
+
+		vsi->stat_offsets_loaded = false;
+
 		/* ICE_VSI_CTRL does not need RSS so skip RSS processing */
 		if (vsi->type != ICE_VSI_CTRL)
 			/* Do not exit if configuring RSS had an issue, at
@@ -2568,24 +2432,17 @@
 	struct ice_pf *pf = vsi->back;
 	int err;
 
-	/* The Rx rule will only exist to remove if the LLDP FW
-	 * engine is currently stopped
-	 */
-	if (!ice_is_safe_mode(pf) && vsi->type == ICE_VSI_PF &&
-	    !test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags))
-		ice_cfg_sw_lldp(vsi, false, false);
-
 	ice_rm_vsi_lan_cfg(vsi->port_info, vsi->idx);
 	err = ice_rm_vsi_rdma_cfg(vsi->port_info, vsi->idx);
 	if (err)
 		dev_err(ice_pf_to_dev(pf), "Failed to remove RDMA scheduler config for VSI %u, err %d\n",
 			vsi->vsi_num, err);
 
-	if (ice_is_xdp_ena_vsi(vsi))
+	if (vsi->xdp_rings)
 		/* return value check can be skipped here, it always returns
 		 * 0 if reset is in progress
 		 */
-		ice_destroy_xdp_rings(vsi);
+		ice_destroy_xdp_rings(vsi, ICE_XDP_CFG_PART);
 
 	ice_vsi_clear_rings(vsi);
 	ice_vsi_free_q_vectors(vsi);
@@ -2682,7 +2539,7 @@
 		for (q = 0; q < q_vector->num_ring_tx; q++) {
 			ice_write_itr(&q_vector->tx, 0);
 			wr32(hw, QINT_TQCTL(vsi->txq_map[txq]), 0);
-			if (ice_is_xdp_ena_vsi(vsi)) {
+			if (vsi->xdp_rings) {
 				u32 xdp_txq = txq + vsi->num_xdp_txq;
 
 				wr32(hw, QINT_TQCTL(vsi->txq_map[xdp_txq]), 0);
@@ -2782,6 +2639,7 @@
 	if (!test_and_set_bit(ICE_VSI_DOWN, vsi->state))
 		ice_down(vsi);
 
+	ice_vsi_clear_napi_queues(vsi);
 	ice_vsi_free_irq(vsi);
 	ice_vsi_free_tx_rings(vsi);
 	ice_vsi_free_rx_rings(vsi);
@@ -2825,8 +2683,7 @@
  */
 void ice_dis_vsi(struct ice_vsi *vsi, bool locked)
 {
-	if (test_bit(ICE_VSI_DOWN, vsi->state))
-		return;
+	bool already_down = test_bit(ICE_VSI_DOWN, vsi->state);
 
 	set_bit(ICE_VSI_NEEDS_RESTART, vsi->state);
 
@@ -2834,16 +2691,17 @@
 		if (netif_running(vsi->netdev)) {
 			if (!locked)
 				rtnl_lock();
-
-			ice_vsi_close(vsi);
+			already_down = test_bit(ICE_VSI_DOWN, vsi->state);
+			if (!already_down)
+				ice_vsi_close(vsi);
 
 			if (!locked)
 				rtnl_unlock();
-		} else {
+		} else if (!already_down) {
 			ice_vsi_close(vsi);
 		}
-	} else if (vsi->type == ICE_VSI_CTRL ||
-		   vsi->type == ICE_VSI_SWITCHDEV_CTRL) {
+	} else if ((vsi->type == ICE_VSI_CTRL ||
+		   vsi->type == ICE_VSI_SWITCHDEV_CTRL) && !already_down) {
 		ice_vsi_close(vsi);
 	}
 }
@@ -2904,120 +2762,55 @@
 }
 
 /**
- * __ice_queue_set_napi - Set the napi instance for the queue
- * @dev: device to which NAPI and queue belong
- * @queue_index: Index of queue
- * @type: queue type as RX or TX
- * @napi: NAPI context
- * @locked: is the rtnl_lock already held
- *
- * Set the napi instance for the queue. Caller indicates the lock status.
- */
-static void
-__ice_queue_set_napi(struct net_device *dev, unsigned int queue_index,
-		     enum netdev_queue_type type, struct napi_struct *napi,
-		     bool locked)
-{
-	if (!locked)
-		rtnl_lock();
-	netif_queue_set_napi(dev, queue_index, type, napi);
-	if (!locked)
-		rtnl_unlock();
-}
-
-/**
- * ice_queue_set_napi - Set the napi instance for the queue
- * @vsi: VSI being configured
- * @queue_index: Index of queue
- * @type: queue type as RX or TX
- * @napi: NAPI context
+ * ice_vsi_set_napi_queues - associate netdev queues with napi
+ * @vsi: VSI pointer
  *
- * Set the napi instance for the queue. The rtnl lock state is derived from the
- * execution path.
+ * Associate queue[s] with napi for all vectors.
+ * The caller must hold rtnl_lock.
  */
-void
-ice_queue_set_napi(struct ice_vsi *vsi, unsigned int queue_index,
-		   enum netdev_queue_type type, struct napi_struct *napi)
+void ice_vsi_set_napi_queues(struct ice_vsi *vsi)
 {
-	struct ice_pf *pf = vsi->back;
+	struct net_device *netdev = vsi->netdev;
+	int q_idx, v_idx;
 
-	if (!vsi->netdev)
+	if (!netdev)
 		return;
 
-	if (current_work() == &pf->serv_task ||
-	    test_bit(ICE_PREPARED_FOR_RESET, pf->state) ||
-	    test_bit(ICE_DOWN, pf->state) ||
-	    test_bit(ICE_SUSPENDED, pf->state))
-		__ice_queue_set_napi(vsi->netdev, queue_index, type, napi,
-				     false);
-	else
-		__ice_queue_set_napi(vsi->netdev, queue_index, type, napi,
-				     true);
-}
-
-/**
- * __ice_q_vector_set_napi_queues - Map queue[s] associated with the napi
- * @q_vector: q_vector pointer
- * @locked: is the rtnl_lock already held
- *
- * Associate the q_vector napi with all the queue[s] on the vector.
- * Caller indicates the lock status.
- */
-void __ice_q_vector_set_napi_queues(struct ice_q_vector *q_vector, bool locked)
-{
-	struct ice_rx_ring *rx_ring;
-	struct ice_tx_ring *tx_ring;
+	ice_for_each_rxq(vsi, q_idx)
+		netif_queue_set_napi(netdev, q_idx, NETDEV_QUEUE_TYPE_RX,
+				     &vsi->rx_rings[q_idx]->q_vector->napi);
 
-	ice_for_each_rx_ring(rx_ring, q_vector->rx)
-		__ice_queue_set_napi(q_vector->vsi->netdev, rx_ring->q_index,
-				     NETDEV_QUEUE_TYPE_RX, &q_vector->napi,
-				     locked);
-
-	ice_for_each_tx_ring(tx_ring, q_vector->tx)
-		__ice_queue_set_napi(q_vector->vsi->netdev, tx_ring->q_index,
-				     NETDEV_QUEUE_TYPE_TX, &q_vector->napi,
-				     locked);
+	ice_for_each_txq(vsi, q_idx)
+		netif_queue_set_napi(netdev, q_idx, NETDEV_QUEUE_TYPE_TX,
+				     &vsi->tx_rings[q_idx]->q_vector->napi);
 	/* Also set the interrupt number for the NAPI */
-	netif_napi_set_irq(&q_vector->napi, q_vector->irq.virq);
-}
+	ice_for_each_q_vector(vsi, v_idx) {
+		struct ice_q_vector *q_vector = vsi->q_vectors[v_idx];
 
-/**
- * ice_q_vector_set_napi_queues - Map queue[s] associated with the napi
- * @q_vector: q_vector pointer
- *
- * Associate the q_vector napi with all the queue[s] on the vector
- */
-void ice_q_vector_set_napi_queues(struct ice_q_vector *q_vector)
-{
-	struct ice_rx_ring *rx_ring;
-	struct ice_tx_ring *tx_ring;
-
-	ice_for_each_rx_ring(rx_ring, q_vector->rx)
-		ice_queue_set_napi(q_vector->vsi, rx_ring->q_index,
-				   NETDEV_QUEUE_TYPE_RX, &q_vector->napi);
-
-	ice_for_each_tx_ring(tx_ring, q_vector->tx)
-		ice_queue_set_napi(q_vector->vsi, tx_ring->q_index,
-				   NETDEV_QUEUE_TYPE_TX, &q_vector->napi);
-	/* Also set the interrupt number for the NAPI */
-	netif_napi_set_irq(&q_vector->napi, q_vector->irq.virq);
+		netif_napi_set_irq(&q_vector->napi, q_vector->irq.virq);
+	}
 }
 
 /**
- * ice_vsi_set_napi_queues
+ * ice_vsi_clear_napi_queues - dissociate netdev queues from napi
  * @vsi: VSI pointer
  *
- * Associate queue[s] with napi for all vectors
+ * Clear the association between all VSI queues queue[s] and napi.
+ * The caller must hold rtnl_lock.
  */
-void ice_vsi_set_napi_queues(struct ice_vsi *vsi)
+void ice_vsi_clear_napi_queues(struct ice_vsi *vsi)
 {
-	int i;
+	struct net_device *netdev = vsi->netdev;
+	int q_idx;
 
-	if (!vsi->netdev)
+	if (!netdev)
 		return;
 
-	ice_for_each_q_vector(vsi, i)
-		ice_q_vector_set_napi_queues(vsi->q_vectors[i]);
+	ice_for_each_txq(vsi, q_idx)
+		netif_queue_set_napi(netdev, q_idx, NETDEV_QUEUE_TYPE_TX, NULL);
+
+	ice_for_each_rxq(vsi, q_idx)
+		netif_queue_set_napi(netdev, q_idx, NETDEV_QUEUE_TYPE_RX, NULL);
 }
 
 /**
@@ -3038,6 +2831,14 @@
 		ice_rss_clean(vsi);
 
 	ice_vsi_close(vsi);
+
+	/* The Rx rule will only exist to remove if the LLDP FW
+	 * engine is currently stopped
+	 */
+	if (!ice_is_safe_mode(pf) && vsi->type == ICE_VSI_PF &&
+	    !test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags))
+		ice_cfg_sw_lldp(vsi, false, false);
+
 	ice_vsi_decfg(vsi);
 
 	/* retain SW VSI data structure since it is needed to unregister and
@@ -3238,7 +3039,7 @@
 {
 	struct ice_vsi_cfg_params params = {};
 	struct ice_coalesce_stored *coalesce;
-	int prev_num_q_vectors = 0;
+	int prev_num_q_vectors;
 	struct ice_pf *pf;
 	int ret;
 
@@ -3252,42 +3053,47 @@
 	if (WARN_ON(vsi->type == ICE_VSI_VF && !vsi->vf))
 		return -EINVAL;
 
-	coalesce = kcalloc(vsi->num_q_vectors,
-			   sizeof(struct ice_coalesce_stored), GFP_KERNEL);
-	if (!coalesce)
-		return -ENOMEM;
-
-	prev_num_q_vectors = ice_vsi_rebuild_get_coalesce(vsi, coalesce);
+	mutex_lock(&vsi->xdp_state_lock);
 
 	ret = ice_vsi_realloc_stat_arrays(vsi);
 	if (ret)
-		goto err_vsi_cfg;
+		goto unlock;
 
 	ice_vsi_decfg(vsi);
 	ret = ice_vsi_cfg_def(vsi, &params);
 	if (ret)
-		goto err_vsi_cfg;
+		goto unlock;
+
+	coalesce = kcalloc(vsi->num_q_vectors,
+			   sizeof(struct ice_coalesce_stored), GFP_KERNEL);
+	if (!coalesce) {
+		ret = -ENOMEM;
+		goto decfg;
+	}
+
+	prev_num_q_vectors = ice_vsi_rebuild_get_coalesce(vsi, coalesce);
 
 	ret = ice_vsi_cfg_tc_lan(pf, vsi);
 	if (ret) {
 		if (vsi_flags & ICE_VSI_FLAG_INIT) {
 			ret = -EIO;
-			goto err_vsi_cfg_tc_lan;
+			goto free_coalesce;
 		}
 
-		kfree(coalesce);
-		return ice_schedule_reset(pf, ICE_RESET_PFR);
+		ret = ice_schedule_reset(pf, ICE_RESET_PFR);
+		goto free_coalesce;
 	}
 
 	ice_vsi_rebuild_set_coalesce(vsi, coalesce, prev_num_q_vectors);
-	kfree(coalesce);
-
-	return 0;
+	clear_bit(ICE_VSI_REBUILD_PENDING, vsi->state);
 
-err_vsi_cfg_tc_lan:
-	ice_vsi_decfg(vsi);
-err_vsi_cfg:
+free_coalesce:
 	kfree(coalesce);
+decfg:
+	if (ret)
+		ice_vsi_decfg(vsi);
+unlock:
+	mutex_unlock(&vsi->xdp_state_lock);
 	return ret;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_lib.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_lib.h
@@ -54,14 +54,6 @@
 
 void ice_update_eth_stats(struct ice_vsi *vsi);
 
-int ice_vsi_cfg_single_rxq(struct ice_vsi *vsi, u16 q_idx);
-
-int ice_vsi_cfg_single_txq(struct ice_vsi *vsi, struct ice_tx_ring **tx_rings, u16 q_idx);
-
-int ice_vsi_cfg_rxqs(struct ice_vsi *vsi);
-
-int ice_vsi_cfg_lan_txqs(struct ice_vsi *vsi);
-
 void ice_vsi_cfg_msix(struct ice_vsi *vsi);
 
 int ice_vsi_start_all_rx_rings(struct ice_vsi *vsi);
@@ -72,8 +64,6 @@
 ice_vsi_stop_lan_tx_rings(struct ice_vsi *vsi, enum ice_disq_rst_src rst_src,
 			  u16 rel_vmvf_num);
 
-int ice_vsi_cfg_xdp_txqs(struct ice_vsi *vsi);
-
 int ice_vsi_stop_xdp_tx_rings(struct ice_vsi *vsi);
 
 void ice_cfg_sw_lldp(struct ice_vsi *vsi, bool tx, bool create);
@@ -91,16 +81,10 @@
 struct ice_vsi *
 ice_vsi_setup(struct ice_pf *pf, struct ice_vsi_cfg_params *params);
 
-void
-ice_queue_set_napi(struct ice_vsi *vsi, unsigned int queue_index,
-		   enum netdev_queue_type type, struct napi_struct *napi);
-
-void __ice_q_vector_set_napi_queues(struct ice_q_vector *q_vector, bool locked);
-
-void ice_q_vector_set_napi_queues(struct ice_q_vector *q_vector);
-
 void ice_vsi_set_napi_queues(struct ice_vsi *vsi);
 
+void ice_vsi_clear_napi_queues(struct ice_vsi *vsi);
+
 int ice_vsi_release(struct ice_vsi *vsi);
 
 void ice_vsi_close(struct ice_vsi *vsi);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_main.c
@@ -85,7 +85,8 @@
 
 bool netif_is_ice(const struct net_device *dev)
 {
-	return dev && (dev->netdev_ops == &ice_netdev_ops);
+	return dev && (dev->netdev_ops == &ice_netdev_ops ||
+		       dev->netdev_ops == &ice_netdev_safe_mode_ops);
 }
 
 /**
@@ -519,25 +520,6 @@
 }
 
 /**
- * ice_clear_sw_switch_recipes - clear switch recipes
- * @pf: board private structure
- *
- * Mark switch recipes as not created in sw structures. There are cases where
- * rules (especially advanced rules) need to be restored, either re-read from
- * hardware or added again. For example after the reset. 'recp_created' flag
- * prevents from doing that and need to be cleared upfront.
- */
-static void ice_clear_sw_switch_recipes(struct ice_pf *pf)
-{
-	struct ice_sw_recipe *recp;
-	u8 i;
-
-	recp = pf->hw.switch_info->recp_list;
-	for (i = 0; i < ICE_MAX_NUM_RECIPES; i++)
-		recp[i].recp_created = false;
-}
-
-/**
  * ice_prepare_for_reset - prep for reset
  * @pf: board private structure
  * @reset_type: reset type requested
@@ -558,6 +540,8 @@
 	if (test_bit(ICE_PREPARED_FOR_RESET, pf->state))
 		return;
 
+	synchronize_irq(pf->oicr_irq.virq);
+
 	ice_unplug_aux_dev(pf);
 
 	/* Notify VFs of impending reset */
@@ -571,8 +555,9 @@
 	mutex_unlock(&pf->vfs.table_lock);
 
 	if (ice_is_eswitch_mode_switchdev(pf)) {
-		if (reset_type != ICE_RESET_PFR)
-			ice_clear_sw_switch_recipes(pf);
+		rtnl_lock();
+		ice_eswitch_br_fdb_flush(pf->eswitch.br_offloads->bridge);
+		rtnl_unlock();
 	}
 
 	/* release ADQ specific HW and SW resources */
@@ -605,11 +590,15 @@
 			memset(&vsi->mqprio_qopt, 0, sizeof(vsi->mqprio_qopt));
 		}
 	}
+
+	if (vsi->netdev)
+		netif_device_detach(vsi->netdev);
 skip:
 
 	/* clear SW filtering DB */
 	ice_clear_hw_tbls(hw);
 	/* disable the VSIs and their queues that are not already DOWN */
+	set_bit(ICE_VSI_REBUILD_PENDING, ice_get_main_vsi(pf)->state);
 	ice_pf_dis_all_vsi(pf, false);
 
 	if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags))
@@ -803,6 +792,9 @@
 	}
 
 	switch (vsi->port_info->phy.link_info.link_speed) {
+	case ICE_AQ_LINK_SPEED_200GB:
+		speed = "200 G";
+		break;
 	case ICE_AQ_LINK_SPEED_100GB:
 		speed = "100 G";
 		break;
@@ -2668,17 +2660,72 @@
 		bpf_prog_put(old_prog);
 }
 
+static struct ice_tx_ring *ice_xdp_ring_from_qid(struct ice_vsi *vsi, int qid)
+{
+	struct ice_q_vector *q_vector;
+	struct ice_tx_ring *ring;
+
+	if (static_key_enabled(&ice_xdp_locking_key))
+		return vsi->xdp_rings[qid % vsi->num_xdp_txq];
+
+	q_vector = vsi->rx_rings[qid]->q_vector;
+	ice_for_each_tx_ring(ring, q_vector->tx)
+		if (ice_ring_is_xdp(ring))
+			return ring;
+
+	return NULL;
+}
+
+/**
+ * ice_map_xdp_rings - Map XDP rings to interrupt vectors
+ * @vsi: the VSI with XDP rings being configured
+ *
+ * Map XDP rings to interrupt vectors and perform the configuration steps
+ * dependent on the mapping.
+ */
+void ice_map_xdp_rings(struct ice_vsi *vsi)
+{
+	int xdp_rings_rem = vsi->num_xdp_txq;
+	int v_idx, q_idx;
+
+	/* follow the logic from ice_vsi_map_rings_to_vectors */
+	ice_for_each_q_vector(vsi, v_idx) {
+		struct ice_q_vector *q_vector = vsi->q_vectors[v_idx];
+		int xdp_rings_per_v, q_id, q_base;
+
+		xdp_rings_per_v = DIV_ROUND_UP(xdp_rings_rem,
+					       vsi->num_q_vectors - v_idx);
+		q_base = vsi->num_xdp_txq - xdp_rings_rem;
+
+		for (q_id = q_base; q_id < (q_base + xdp_rings_per_v); q_id++) {
+			struct ice_tx_ring *xdp_ring = vsi->xdp_rings[q_id];
+
+			xdp_ring->q_vector = q_vector;
+			xdp_ring->next = q_vector->tx.tx_ring;
+			q_vector->tx.tx_ring = xdp_ring;
+		}
+		xdp_rings_rem -= xdp_rings_per_v;
+	}
+
+	ice_for_each_rxq(vsi, q_idx) {
+		vsi->rx_rings[q_idx]->xdp_ring = ice_xdp_ring_from_qid(vsi,
+								       q_idx);
+		ice_tx_xsk_pool(vsi, q_idx);
+	}
+}
+
 /**
  * ice_prepare_xdp_rings - Allocate, configure and setup Tx rings for XDP
  * @vsi: VSI to bring up Tx rings used by XDP
  * @prog: bpf program that will be assigned to VSI
+ * @cfg_type: create from scratch or restore the existing configuration
  *
  * Return 0 on success and negative value on error
  */
-int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog)
+int ice_prepare_xdp_rings(struct ice_vsi *vsi, struct bpf_prog *prog,
+			  enum ice_xdp_cfg cfg_type)
 {
 	u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
-	int xdp_rings_rem = vsi->num_xdp_txq;
 	struct ice_pf *pf = vsi->back;
 	struct ice_qs_cfg xdp_qs_cfg = {
 		.qs_mutex = &pf->avail_q_mutex,
@@ -2691,8 +2738,7 @@
 		.mapping_mode = ICE_VSI_MAP_CONTIG
 	};
 	struct device *dev;
-	int i, v_idx;
-	int status;
+	int status, i;
 
 	dev = ice_pf_to_dev(pf);
 	vsi->xdp_rings = devm_kcalloc(dev, vsi->num_xdp_txq,
@@ -2711,49 +2757,15 @@
 	if (ice_xdp_alloc_setup_rings(vsi))
 		goto clear_xdp_rings;
 
-	/* follow the logic from ice_vsi_map_rings_to_vectors */
-	ice_for_each_q_vector(vsi, v_idx) {
-		struct ice_q_vector *q_vector = vsi->q_vectors[v_idx];
-		int xdp_rings_per_v, q_id, q_base;
-
-		xdp_rings_per_v = DIV_ROUND_UP(xdp_rings_rem,
-					       vsi->num_q_vectors - v_idx);
-		q_base = vsi->num_xdp_txq - xdp_rings_rem;
-
-		for (q_id = q_base; q_id < (q_base + xdp_rings_per_v); q_id++) {
-			struct ice_tx_ring *xdp_ring = vsi->xdp_rings[q_id];
-
-			xdp_ring->q_vector = q_vector;
-			xdp_ring->next = q_vector->tx.tx_ring;
-			q_vector->tx.tx_ring = xdp_ring;
-		}
-		xdp_rings_rem -= xdp_rings_per_v;
-	}
-
-	ice_for_each_rxq(vsi, i) {
-		if (static_key_enabled(&ice_xdp_locking_key)) {
-			vsi->rx_rings[i]->xdp_ring = vsi->xdp_rings[i % vsi->num_xdp_txq];
-		} else {
-			struct ice_q_vector *q_vector = vsi->rx_rings[i]->q_vector;
-			struct ice_tx_ring *ring;
-
-			ice_for_each_tx_ring(ring, q_vector->tx) {
-				if (ice_ring_is_xdp(ring)) {
-					vsi->rx_rings[i]->xdp_ring = ring;
-					break;
-				}
-			}
-		}
-		ice_tx_xsk_pool(vsi, i);
-	}
-
 	/* omit the scheduler update if in reset path; XDP queues will be
 	 * taken into account at the end of ice_vsi_rebuild, where
 	 * ice_cfg_vsi_lan is being called
 	 */
-	if (ice_is_reset_in_progress(pf->state))
+	if (cfg_type == ICE_XDP_CFG_PART)
 		return 0;
 
+	ice_map_xdp_rings(vsi);
+
 	/* tell the Tx scheduler that right now we have
 	 * additional queues
 	 */
@@ -2803,22 +2815,21 @@
 /**
  * ice_destroy_xdp_rings - undo the configuration made by ice_prepare_xdp_rings
  * @vsi: VSI to remove XDP rings
+ * @cfg_type: disable XDP permanently or allow it to be restored later
  *
  * Detach XDP rings from irq vectors, clean up the PF bitmap and free
  * resources
  */
-int ice_destroy_xdp_rings(struct ice_vsi *vsi)
+int ice_destroy_xdp_rings(struct ice_vsi *vsi, enum ice_xdp_cfg cfg_type)
 {
 	u16 max_txqs[ICE_MAX_TRAFFIC_CLASS] = { 0 };
 	struct ice_pf *pf = vsi->back;
 	int i, v_idx;
 
 	/* q_vectors are freed in reset path so there's no point in detaching
-	 * rings; in case of rebuild being triggered not from reset bits
-	 * in pf->state won't be set, so additionally check first q_vector
-	 * against NULL
+	 * rings
 	 */
-	if (ice_is_reset_in_progress(pf->state) || !vsi->q_vectors[0])
+	if (cfg_type == ICE_XDP_CFG_PART)
 		goto free_qmap;
 
 	ice_for_each_q_vector(vsi, v_idx) {
@@ -2859,7 +2870,7 @@
 	if (static_key_enabled(&ice_xdp_locking_key))
 		static_branch_dec(&ice_xdp_locking_key);
 
-	if (ice_is_reset_in_progress(pf->state) || !vsi->q_vectors[0])
+	if (cfg_type == ICE_XDP_CFG_PART)
 		return 0;
 
 	ice_vsi_assign_bpf_prog(vsi, NULL);
@@ -2888,7 +2899,7 @@
 	ice_for_each_rxq(vsi, i) {
 		struct ice_rx_ring *rx_ring = vsi->rx_rings[i];
 
-		if (rx_ring->xsk_pool)
+		if (READ_ONCE(rx_ring->xsk_pool))
 			napi_schedule(&rx_ring->q_vector->napi);
 	}
 }
@@ -2939,8 +2950,8 @@
 		   struct netlink_ext_ack *extack)
 {
 	unsigned int frame_size = vsi->netdev->mtu + ICE_ETH_PKT_HDR_PAD;
-	bool if_running = netif_running(vsi->netdev);
 	int ret = 0, xdp_ring_err = 0;
+	bool if_running;
 
 	if (prog && !prog->aux->xdp_has_frags) {
 		if (frame_size > ice_max_xdp_frame_size(vsi)) {
@@ -2951,13 +2962,17 @@
 	}
 
 	/* hot swap progs and avoid toggling link */
-	if (ice_is_xdp_ena_vsi(vsi) == !!prog) {
+	if (ice_is_xdp_ena_vsi(vsi) == !!prog ||
+	    test_bit(ICE_VSI_REBUILD_PENDING, vsi->state)) {
 		ice_vsi_assign_bpf_prog(vsi, prog);
 		return 0;
 	}
 
+	if_running = netif_running(vsi->netdev) &&
+		     !test_and_set_bit(ICE_VSI_DOWN, vsi->state);
+
 	/* need to stop netdev while setting up the program for Rx rings */
-	if (if_running && !test_and_set_bit(ICE_VSI_DOWN, vsi->state)) {
+	if (if_running) {
 		ret = ice_down(vsi);
 		if (ret) {
 			NL_SET_ERR_MSG_MOD(extack, "Preparing device for XDP attach failed");
@@ -2970,7 +2985,8 @@
 		if (xdp_ring_err) {
 			NL_SET_ERR_MSG_MOD(extack, "Not enough Tx resources for XDP");
 		} else {
-			xdp_ring_err = ice_prepare_xdp_rings(vsi, prog);
+			xdp_ring_err = ice_prepare_xdp_rings(vsi, prog,
+							     ICE_XDP_CFG_FULL);
 			if (xdp_ring_err)
 				NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Tx resources failed");
 		}
@@ -2981,7 +2997,7 @@
 			NL_SET_ERR_MSG_MOD(extack, "Setting up XDP Rx resources failed");
 	} else if (ice_is_xdp_ena_vsi(vsi) && !prog) {
 		xdp_features_clear_redirect_target(vsi->netdev);
-		xdp_ring_err = ice_destroy_xdp_rings(vsi);
+		xdp_ring_err = ice_destroy_xdp_rings(vsi, ICE_XDP_CFG_FULL);
 		if (xdp_ring_err)
 			NL_SET_ERR_MSG_MOD(extack, "Freeing XDP Tx resources failed");
 		/* reallocate Rx queues that were used for zero-copy */
@@ -3022,21 +3038,28 @@
 {
 	struct ice_netdev_priv *np = netdev_priv(dev);
 	struct ice_vsi *vsi = np->vsi;
+	int ret;
 
 	if (vsi->type != ICE_VSI_PF) {
 		NL_SET_ERR_MSG_MOD(xdp->extack, "XDP can be loaded only on PF VSI");
 		return -EINVAL;
 	}
 
+	mutex_lock(&vsi->xdp_state_lock);
+
 	switch (xdp->command) {
 	case XDP_SETUP_PROG:
-		return ice_xdp_setup_prog(vsi, xdp->prog, xdp->extack);
+		ret = ice_xdp_setup_prog(vsi, xdp->prog, xdp->extack);
+		break;
 	case XDP_SETUP_XSK_POOL:
-		return ice_xsk_pool_setup(vsi, xdp->xsk.pool,
-					  xdp->xsk.queue_id);
+		ret = ice_xsk_pool_setup(vsi, xdp->xsk.pool, xdp->xsk.queue_id);
+		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
 	}
+
+	mutex_unlock(&vsi->xdp_state_lock);
+	return ret;
 }
 
 /**
@@ -3492,11 +3515,9 @@
 	if (!vsi->netdev)
 		return;
 
-	ice_for_each_q_vector(vsi, v_idx) {
+	ice_for_each_q_vector(vsi, v_idx)
 		netif_napi_add(vsi->netdev, &vsi->q_vectors[v_idx]->napi,
 			       ice_napi_poll);
-		__ice_q_vector_set_napi_queues(vsi->q_vectors[v_idx], false);
-	}
 }
 
 /**
@@ -4077,7 +4098,7 @@
 int ice_vsi_recfg_qs(struct ice_vsi *vsi, int new_rx, int new_tx, bool locked)
 {
 	struct ice_pf *pf = vsi->back;
-	int err = 0, timeout = 50;
+	int i, err = 0, timeout = 50;
 
 	if (!new_rx && !new_tx)
 		return -EINVAL;
@@ -4096,15 +4117,32 @@
 
 	/* set for the next time the netdev is started */
 	if (!netif_running(vsi->netdev)) {
-		ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT);
+		err = ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT);
+		if (err)
+			goto rebuild_err;
 		dev_dbg(ice_pf_to_dev(pf), "Link is down, queue count change happens when link is brought up\n");
 		goto done;
 	}
 
 	ice_vsi_close(vsi);
-	ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT);
+	err = ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT);
+	if (err)
+		goto rebuild_err;
+
+	ice_for_each_traffic_class(i) {
+		if (vsi->tc_cfg.ena_tc & BIT(i))
+			netdev_set_tc_queue(vsi->netdev,
+					    vsi->tc_cfg.tc_info[i].netdev_tc,
+					    vsi->tc_cfg.tc_info[i].qcount_tx,
+					    vsi->tc_cfg.tc_info[i].qoffset);
+	}
 	ice_pf_dcb_recfg(pf, locked);
 	ice_vsi_open(vsi);
+	goto done;
+
+rebuild_err:
+	dev_err(ice_pf_to_dev(pf), "Error during VSI rebuild: %d. Unload and reload the driver.\n",
+		err);
 done:
 	clear_bit(ICE_CFG_BUSY, pf->state);
 	return err;
@@ -4572,90 +4610,6 @@
 	vsi->netdev = NULL;
 }
 
-static int ice_start_eth(struct ice_vsi *vsi)
-{
-	int err;
-
-	err = ice_init_mac_fltr(vsi->back);
-	if (err)
-		return err;
-
-	err = ice_vsi_open(vsi);
-	if (err)
-		ice_fltr_remove_all(vsi);
-
-	return err;
-}
-
-static void ice_stop_eth(struct ice_vsi *vsi)
-{
-	ice_fltr_remove_all(vsi);
-	ice_vsi_close(vsi);
-}
-
-static int ice_init_eth(struct ice_pf *pf)
-{
-	struct ice_vsi *vsi = ice_get_main_vsi(pf);
-	int err;
-
-	if (!vsi)
-		return -EINVAL;
-
-	/* init channel list */
-	INIT_LIST_HEAD(&vsi->ch_list);
-
-	err = ice_cfg_netdev(vsi);
-	if (err)
-		return err;
-	/* Setup DCB netlink interface */
-	ice_dcbnl_setup(vsi);
-
-	err = ice_init_mac_fltr(pf);
-	if (err)
-		goto err_init_mac_fltr;
-
-	err = ice_devlink_create_pf_port(pf);
-	if (err)
-		goto err_devlink_create_pf_port;
-
-	SET_NETDEV_DEVLINK_PORT(vsi->netdev, &pf->devlink_port);
-
-	err = ice_register_netdev(vsi);
-	if (err)
-		goto err_register_netdev;
-
-	err = ice_tc_indir_block_register(vsi);
-	if (err)
-		goto err_tc_indir_block_register;
-
-	ice_napi_add(vsi);
-
-	return 0;
-
-err_tc_indir_block_register:
-	ice_unregister_netdev(vsi);
-err_register_netdev:
-	ice_devlink_destroy_pf_port(pf);
-err_devlink_create_pf_port:
-err_init_mac_fltr:
-	ice_decfg_netdev(vsi);
-	return err;
-}
-
-static void ice_deinit_eth(struct ice_pf *pf)
-{
-	struct ice_vsi *vsi = ice_get_main_vsi(pf);
-
-	if (!vsi)
-		return;
-
-	ice_vsi_close(vsi);
-	ice_unregister_netdev(vsi);
-	ice_devlink_destroy_pf_port(pf);
-	ice_tc_indir_block_unregister(vsi);
-	ice_decfg_netdev(vsi);
-}
-
 /**
  * ice_wait_for_fw - wait for full FW readiness
  * @hw: pointer to the hardware structure
@@ -4681,7 +4635,7 @@
 	return -ETIMEDOUT;
 }
 
-static int ice_init_dev(struct ice_pf *pf)
+int ice_init_dev(struct ice_pf *pf)
 {
 	struct device *dev = ice_pf_to_dev(pf);
 	struct ice_hw *hw = &pf->hw;
@@ -4774,7 +4728,7 @@
 	return err;
 }
 
-static void ice_deinit_dev(struct ice_pf *pf)
+void ice_deinit_dev(struct ice_pf *pf)
 {
 	ice_free_irq_msix_misc(pf);
 	ice_deinit_pf(pf);
@@ -5079,31 +5033,47 @@
 /**
  * ice_load - load pf by init hw and starting VSI
  * @pf: pointer to the pf instance
+ *
+ * This function has to be called under devl_lock.
  */
 int ice_load(struct ice_pf *pf)
 {
-	struct ice_vsi_cfg_params params = {};
 	struct ice_vsi *vsi;
 	int err;
 
-	err = ice_init_dev(pf);
+	devl_assert_locked(priv_to_devlink(pf));
+
+	vsi = ice_get_main_vsi(pf);
+
+	/* init channel list */
+	INIT_LIST_HEAD(&vsi->ch_list);
+
+	err = ice_cfg_netdev(vsi);
 	if (err)
 		return err;
 
-	vsi = ice_get_main_vsi(pf);
+	/* Setup DCB netlink interface */
+	ice_dcbnl_setup(vsi);
 
-	params = ice_vsi_to_params(vsi);
-	params.flags = ICE_VSI_FLAG_INIT;
+	err = ice_init_mac_fltr(pf);
+	if (err)
+		goto err_init_mac_fltr;
 
-	rtnl_lock();
-	err = ice_vsi_cfg(vsi, &params);
+	err = ice_devlink_create_pf_port(pf);
 	if (err)
-		goto err_vsi_cfg;
+		goto err_devlink_create_pf_port;
+
+	SET_NETDEV_DEVLINK_PORT(vsi->netdev, &pf->devlink_port);
 
-	err = ice_start_eth(ice_get_main_vsi(pf));
+	err = ice_register_netdev(vsi);
 	if (err)
-		goto err_start_eth;
-	rtnl_unlock();
+		goto err_register_netdev;
+
+	err = ice_tc_indir_block_register(vsi);
+	if (err)
+		goto err_tc_indir_block_register;
+
+	ice_napi_add(vsi);
 
 	err = ice_init_rdma(pf);
 	if (err)
@@ -5117,29 +5087,35 @@
 	return 0;
 
 err_init_rdma:
-	ice_vsi_close(ice_get_main_vsi(pf));
-	rtnl_lock();
-err_start_eth:
-	ice_vsi_decfg(ice_get_main_vsi(pf));
-err_vsi_cfg:
-	rtnl_unlock();
-	ice_deinit_dev(pf);
+	ice_tc_indir_block_unregister(vsi);
+err_tc_indir_block_register:
+	ice_unregister_netdev(vsi);
+err_register_netdev:
+	ice_devlink_destroy_pf_port(pf);
+err_devlink_create_pf_port:
+err_init_mac_fltr:
+	ice_decfg_netdev(vsi);
 	return err;
 }
 
 /**
  * ice_unload - unload pf by stopping VSI and deinit hw
  * @pf: pointer to the pf instance
+ *
+ * This function has to be called under devl_lock.
  */
 void ice_unload(struct ice_pf *pf)
 {
+	struct ice_vsi *vsi = ice_get_main_vsi(pf);
+
+	devl_assert_locked(priv_to_devlink(pf));
+
 	ice_deinit_features(pf);
 	ice_deinit_rdma(pf);
-	rtnl_lock();
-	ice_stop_eth(ice_get_main_vsi(pf));
-	ice_vsi_decfg(ice_get_main_vsi(pf));
-	rtnl_unlock();
-	ice_deinit_dev(pf);
+	ice_tc_indir_block_unregister(vsi);
+	ice_unregister_netdev(vsi);
+	ice_devlink_destroy_pf_port(pf);
+	ice_decfg_netdev(vsi);
 }
 
 /**
@@ -5237,27 +5213,23 @@
 	if (err)
 		goto err_init;
 
-	err = ice_init_eth(pf);
-	if (err)
-		goto err_init_eth;
-
-	err = ice_init_rdma(pf);
+	devl_lock(priv_to_devlink(pf));
+	err = ice_load(pf);
+	devl_unlock(priv_to_devlink(pf));
 	if (err)
-		goto err_init_rdma;
+		goto err_load;
 
 	err = ice_init_devlink(pf);
 	if (err)
 		goto err_init_devlink;
 
-	ice_init_features(pf);
-
 	return 0;
 
 err_init_devlink:
-	ice_deinit_rdma(pf);
-err_init_rdma:
-	ice_deinit_eth(pf);
-err_init_eth:
+	devl_lock(priv_to_devlink(pf));
+	ice_unload(pf);
+	devl_unlock(priv_to_devlink(pf));
+err_load:
 	ice_deinit(pf);
 err_init:
 	pci_disable_device(pdev);
@@ -5355,12 +5327,14 @@
 
 	if (!ice_is_safe_mode(pf))
 		ice_remove_arfs(pf);
-	ice_deinit_features(pf);
+
 	ice_deinit_devlink(pf);
-	ice_deinit_rdma(pf);
-	ice_deinit_eth(pf);
-	ice_deinit(pf);
 
+	devl_lock(priv_to_devlink(pf));
+	ice_unload(pf);
+	devl_unlock(priv_to_devlink(pf));
+
+	ice_deinit(pf);
 	ice_vsi_release_all(pf);
 
 	ice_setup_mc_magic_wake(pf);
@@ -5447,7 +5421,9 @@
 		if (ret)
 			goto err_reinit;
 		ice_vsi_map_rings_to_vectors(pf->vsi[v]);
+		rtnl_lock();
 		ice_vsi_set_napi_queues(pf->vsi[v]);
+		rtnl_unlock();
 	}
 
 	ret = ice_req_irq_msix_misc(pf);
@@ -5461,8 +5437,12 @@
 
 err_reinit:
 	while (v--)
-		if (pf->vsi[v])
+		if (pf->vsi[v]) {
+			rtnl_lock();
+			ice_vsi_clear_napi_queues(pf->vsi[v]);
+			rtnl_unlock();
 			ice_vsi_free_q_vectors(pf->vsi[v]);
+		}
 
 	return ret;
 }
@@ -5495,7 +5475,7 @@
 	 */
 	disabled = ice_service_task_stop(pf);
 
-	ice_unplug_aux_dev(pf);
+	ice_deinit_rdma(pf);
 
 	/* Already suspended?, then there is nothing to do */
 	if (test_and_set_bit(ICE_SUSPENDED, pf->state)) {
@@ -5527,6 +5507,9 @@
 	ice_for_each_vsi(pf, v) {
 		if (!pf->vsi[v])
 			continue;
+		rtnl_lock();
+		ice_vsi_clear_napi_queues(pf->vsi[v]);
+		rtnl_unlock();
 		ice_vsi_free_q_vectors(pf->vsi[v]);
 	}
 	ice_clear_interrupt_scheme(pf);
@@ -5575,6 +5558,11 @@
 	if (ret)
 		dev_err(dev, "Cannot restore interrupt scheme: %d\n", ret);
 
+	ret = ice_init_rdma(pf);
+	if (ret)
+		dev_err(dev, "Reinitialize RDMA during resume failed: %d\n",
+			ret);
+
 	clear_bit(ICE_DOWN, pf->state);
 	/* Now perform PF reset and rebuild */
 	reset_type = ICE_RESET_PFR;
@@ -6737,6 +6725,7 @@
 {
 	struct rtnl_link_stats64 *net_stats, *stats_prev;
 	struct rtnl_link_stats64 *vsi_stats;
+	struct ice_pf *pf = vsi->back;
 	u64 pkts, bytes;
 	int i;
 
@@ -6782,21 +6771,18 @@
 	net_stats = &vsi->net_stats;
 	stats_prev = &vsi->net_stats_prev;
 
-	/* clear prev counters after reset */
-	if (vsi_stats->tx_packets < stats_prev->tx_packets ||
-	    vsi_stats->rx_packets < stats_prev->rx_packets) {
-		stats_prev->tx_packets = 0;
-		stats_prev->tx_bytes = 0;
-		stats_prev->rx_packets = 0;
-		stats_prev->rx_bytes = 0;
+	/* Update netdev counters, but keep in mind that values could start at
+	 * random value after PF reset. And as we increase the reported stat by
+	 * diff of Prev-Cur, we need to be sure that Prev is valid. If it's not,
+	 * let's skip this round.
+	 */
+	if (likely(pf->stat_prev_loaded)) {
+		net_stats->tx_packets += vsi_stats->tx_packets - stats_prev->tx_packets;
+		net_stats->tx_bytes += vsi_stats->tx_bytes - stats_prev->tx_bytes;
+		net_stats->rx_packets += vsi_stats->rx_packets - stats_prev->rx_packets;
+		net_stats->rx_bytes += vsi_stats->rx_bytes - stats_prev->rx_bytes;
 	}
 
-	/* update netdev counters */
-	net_stats->tx_packets += vsi_stats->tx_packets - stats_prev->tx_packets;
-	net_stats->tx_bytes += vsi_stats->tx_bytes - stats_prev->tx_bytes;
-	net_stats->rx_packets += vsi_stats->rx_packets - stats_prev->rx_packets;
-	net_stats->rx_bytes += vsi_stats->rx_bytes - stats_prev->rx_bytes;
-
 	stats_prev->tx_packets = vsi_stats->tx_packets;
 	stats_prev->tx_bytes = vsi_stats->tx_bytes;
 	stats_prev->rx_packets = vsi_stats->rx_packets;
@@ -7087,7 +7073,7 @@
 	if (tx_err)
 		netdev_err(vsi->netdev, "Failed stop Tx rings, VSI %d error %d\n",
 			   vsi->vsi_num, tx_err);
-	if (!tx_err && ice_is_xdp_ena_vsi(vsi)) {
+	if (!tx_err && vsi->xdp_rings) {
 		tx_err = ice_vsi_stop_xdp_tx_rings(vsi);
 		if (tx_err)
 			netdev_err(vsi->netdev, "Failed stop XDP rings, VSI %d error %d\n",
@@ -7104,7 +7090,7 @@
 	ice_for_each_txq(vsi, i)
 		ice_clean_tx_ring(vsi->tx_rings[i]);
 
-	if (ice_is_xdp_ena_vsi(vsi))
+	if (vsi->xdp_rings)
 		ice_for_each_xdp_txq(vsi, i)
 			ice_clean_tx_ring(vsi->xdp_rings[i]);
 
@@ -7309,6 +7295,8 @@
 		err = netif_set_real_num_rx_queues(vsi->netdev, vsi->num_rxq);
 		if (err)
 			goto err_set_qs;
+
+		ice_vsi_set_napi_queues(vsi);
 	}
 
 	err = ice_up_complete(vsi);
@@ -7446,6 +7434,7 @@
  */
 static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
 {
+	struct ice_vsi *vsi = ice_get_main_vsi(pf);
 	struct device *dev = ice_pf_to_dev(pf);
 	struct ice_hw *hw = &pf->hw;
 	bool dvm;
@@ -7594,6 +7583,9 @@
 		ice_rebuild_arfs(pf);
 	}
 
+	if (vsi && vsi->netdev)
+		netif_device_attach(vsi->netdev);
+
 	ice_update_pf_netdev_link(pf);
 
 	/* tell the firmware we are up */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_nvm.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_nvm.c
@@ -375,11 +375,25 @@
  *
  * Read the specified word from the copy of the Shadow RAM found in the
  * specified NVM module.
+ *
+ * Note that the Shadow RAM copy is always located after the CSS header, and
+ * is aligned to 64-byte (32-word) offsets.
  */
 static int
 ice_read_nvm_sr_copy(struct ice_hw *hw, enum ice_bank_select bank, u32 offset, u16 *data)
 {
-	return ice_read_nvm_module(hw, bank, ICE_NVM_SR_COPY_WORD_OFFSET + offset, data);
+	u32 sr_copy;
+
+	switch (bank) {
+	case ICE_ACTIVE_FLASH_BANK:
+		sr_copy = roundup(hw->flash.banks.active_css_hdr_len, 32);
+		break;
+	case ICE_INACTIVE_FLASH_BANK:
+		sr_copy = roundup(hw->flash.banks.inactive_css_hdr_len, 32);
+		break;
+	}
+
+	return ice_read_nvm_module(hw, bank, sr_copy + offset, data);
 }
 
 /**
@@ -441,8 +455,7 @@
 ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len,
 		       u16 module_type)
 {
-	u16 pfa_len, pfa_ptr;
-	u16 next_tlv;
+	u16 pfa_len, pfa_ptr, next_tlv, max_tlv;
 	int status;
 
 	status = ice_read_sr_word(hw, ICE_SR_PFA_PTR, &pfa_ptr);
@@ -455,11 +468,23 @@
 		ice_debug(hw, ICE_DBG_INIT, "Failed to read PFA length.\n");
 		return status;
 	}
+
+	/* The Preserved Fields Area contains a sequence of Type-Length-Value
+	 * structures which define its contents. The PFA length includes all
+	 * of the TLVs, plus the initial length word itself, *and* one final
+	 * word at the end after all of the TLVs.
+	 */
+	if (check_add_overflow(pfa_ptr, pfa_len - 1, &max_tlv)) {
+		dev_warn(ice_hw_to_dev(hw), "PFA starts at offset %u. PFA length of %u caused 16-bit arithmetic overflow.\n",
+			 pfa_ptr, pfa_len);
+		return -EINVAL;
+	}
+
 	/* Starting with first TLV after PFA length, iterate through the list
 	 * of TLVs to find the requested one.
 	 */
 	next_tlv = pfa_ptr + 1;
-	while (next_tlv < pfa_ptr + pfa_len) {
+	while (next_tlv < max_tlv) {
 		u16 tlv_sub_module_type;
 		u16 tlv_len;
 
@@ -483,10 +508,13 @@
 			}
 			return -EINVAL;
 		}
-		/* Check next TLV, i.e. current TLV pointer + length + 2 words
-		 * (for current TLV's type and length)
-		 */
-		next_tlv = next_tlv + tlv_len + 2;
+
+		if (check_add_overflow(next_tlv, 2, &next_tlv) ||
+		    check_add_overflow(next_tlv, tlv_len, &next_tlv)) {
+			dev_warn(ice_hw_to_dev(hw), "TLV of type %u and length 0x%04x caused 16-bit arithmetic overflow. The PFA starts at 0x%04x and has length of 0x%04x\n",
+				 tlv_sub_module_type, tlv_len, pfa_ptr, pfa_len);
+			return -EINVAL;
+		}
 	}
 	/* Module does not exist */
 	return -ENOENT;
@@ -1011,6 +1039,72 @@
 }
 
 /**
+ * ice_get_nvm_css_hdr_len - Read the CSS header length from the NVM CSS header
+ * @hw: pointer to the HW struct
+ * @bank: whether to read from the active or inactive flash bank
+ * @hdr_len: storage for header length in words
+ *
+ * Read the CSS header length from the NVM CSS header and add the Authentication
+ * header size, and then convert to words.
+ *
+ * Return: zero on success, or a negative error code on failure.
+ */
+static int
+ice_get_nvm_css_hdr_len(struct ice_hw *hw, enum ice_bank_select bank,
+			u32 *hdr_len)
+{
+	u16 hdr_len_l, hdr_len_h;
+	u32 hdr_len_dword;
+	int status;
+
+	status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_HDR_LEN_L,
+				     &hdr_len_l);
+	if (status)
+		return status;
+
+	status = ice_read_nvm_module(hw, bank, ICE_NVM_CSS_HDR_LEN_H,
+				     &hdr_len_h);
+	if (status)
+		return status;
+
+	/* CSS header length is in DWORD, so convert to words and add
+	 * authentication header size
+	 */
+	hdr_len_dword = hdr_len_h << 16 | hdr_len_l;
+	*hdr_len = (hdr_len_dword * 2) + ICE_NVM_AUTH_HEADER_LEN;
+
+	return 0;
+}
+
+/**
+ * ice_determine_css_hdr_len - Discover CSS header length for the device
+ * @hw: pointer to the HW struct
+ *
+ * Determine the size of the CSS header at the start of the NVM module. This
+ * is useful for locating the Shadow RAM copy in the NVM, as the Shadow RAM is
+ * always located just after the CSS header.
+ *
+ * Return: zero on success, or a negative error code on failure.
+ */
+static int ice_determine_css_hdr_len(struct ice_hw *hw)
+{
+	struct ice_bank_info *banks = &hw->flash.banks;
+	int status;
+
+	status = ice_get_nvm_css_hdr_len(hw, ICE_ACTIVE_FLASH_BANK,
+					 &banks->active_css_hdr_len);
+	if (status)
+		return status;
+
+	status = ice_get_nvm_css_hdr_len(hw, ICE_INACTIVE_FLASH_BANK,
+					 &banks->inactive_css_hdr_len);
+	if (status)
+		return status;
+
+	return 0;
+}
+
+/**
  * ice_init_nvm - initializes NVM setting
  * @hw: pointer to the HW struct
  *
@@ -1056,6 +1150,12 @@
 		return status;
 	}
 
+	status = ice_determine_css_hdr_len(hw);
+	if (status) {
+		ice_debug(hw, ICE_DBG_NVM, "Failed to determine Shadow RAM copy offsets.\n");
+		return status;
+	}
+
 	status = ice_get_nvm_ver_info(hw, ICE_ACTIVE_FLASH_BANK, &flash->nvm);
 	if (status) {
 		ice_debug(hw, ICE_DBG_INIT, "Failed to read NVM info.\n");
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_ptp_consts.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_ptp_consts.h
@@ -359,9 +359,9 @@
 		/* rx_desk_rsgb_par */
 		644531250, /* 644.53125 MHz Reed Solomon gearbox */
 		/* tx_desk_rsgb_pcs */
-		644531250, /* 644.53125 MHz Reed Solomon gearbox */
+		390625000, /* 390.625 MHz Reed Solomon gearbox */
 		/* rx_desk_rsgb_pcs */
-		644531250, /* 644.53125 MHz Reed Solomon gearbox */
+		390625000, /* 390.625 MHz Reed Solomon gearbox */
 		/* tx_fixed_delay */
 		1620,
 		/* pmd_adj_divisor */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_ptp_hw.c
@@ -33,7 +33,6 @@
 		ARRAY_SIZE(ice_cgu_pin_freq_common), ice_cgu_pin_freq_common },
 	{ "GNSS-1PPS",	  ZL_REF4P, DPLL_PIN_TYPE_GNSS,
 		ARRAY_SIZE(ice_cgu_pin_freq_1_hz), ice_cgu_pin_freq_1_hz },
-	{ "OCXO",	  ZL_REF4N, DPLL_PIN_TYPE_INT_OSCILLATOR, 0, },
 };
 
 static const struct ice_cgu_pin_desc ice_e810t_qsfp_cgu_inputs[] = {
@@ -51,7 +50,6 @@
 		ARRAY_SIZE(ice_cgu_pin_freq_common), ice_cgu_pin_freq_common },
 	{ "GNSS-1PPS",	  ZL_REF4P, DPLL_PIN_TYPE_GNSS,
 		ARRAY_SIZE(ice_cgu_pin_freq_1_hz), ice_cgu_pin_freq_1_hz },
-	{ "OCXO",	  ZL_REF4N, DPLL_PIN_TYPE_INT_OSCILLATOR, },
 };
 
 static const struct ice_cgu_pin_desc ice_e810t_sfp_cgu_outputs[] = {
@@ -3760,6 +3758,25 @@
 }
 
 /**
+ * ice_cgu_get_num_pins - get pin description array size
+ * @hw: pointer to the hw struct
+ * @input: if request is done against input or output pins
+ *
+ * Return: size of pin description array for given hw.
+ */
+int ice_cgu_get_num_pins(struct ice_hw *hw, bool input)
+{
+	const struct ice_cgu_pin_desc *t;
+	int size;
+
+	t = ice_cgu_get_pin_desc(hw, input, &size);
+	if (t)
+		return size;
+
+	return 0;
+}
+
+/**
  * ice_cgu_get_pin_type - get pin's type
  * @hw: pointer to the hw struct
  * @pin: pin index
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_ptp_hw.h
@@ -271,6 +271,7 @@
 int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data);
 int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data);
 bool ice_is_pca9575_present(struct ice_hw *hw);
+int ice_cgu_get_num_pins(struct ice_hw *hw, bool input);
 enum dpll_pin_type ice_cgu_get_pin_type(struct ice_hw *hw, u8 pin, bool input);
 struct dpll_pin_frequency *
 ice_cgu_get_pin_freq_supp(struct ice_hw *hw, u8 pin, bool input, u8 *num);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_repr.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_repr.c
@@ -9,39 +9,6 @@
 #include "ice_dcb_lib.h"
 
 /**
- * ice_repr_get_sw_port_id - get port ID associated with representor
- * @repr: pointer to port representor
- */
-static int ice_repr_get_sw_port_id(struct ice_repr *repr)
-{
-	return repr->src_vsi->back->hw.port_info->lport;
-}
-
-/**
- * ice_repr_get_phys_port_name - get phys port name
- * @netdev: pointer to port representor netdev
- * @buf: write here port name
- * @len: max length of buf
- */
-static int
-ice_repr_get_phys_port_name(struct net_device *netdev, char *buf, size_t len)
-{
-	struct ice_netdev_priv *np = netdev_priv(netdev);
-	struct ice_repr *repr = np->repr;
-	int res;
-
-	/* Devlink port is registered and devlink core is taking care of name formatting. */
-	if (repr->vf->devlink_port.devlink)
-		return -EOPNOTSUPP;
-
-	res = snprintf(buf, len, "pf%dvfr%d", ice_repr_get_sw_port_id(repr),
-		       repr->id);
-	if (res <= 0)
-		return -EOPNOTSUPP;
-	return 0;
-}
-
-/**
  * ice_repr_get_stats64 - get VF stats for VFPR use
  * @netdev: pointer to port representor netdev
  * @stats: pointer to struct where stats can be stored
@@ -240,7 +207,6 @@
 }
 
 static const struct net_device_ops ice_repr_netdev_ops = {
-	.ndo_get_phys_port_name = ice_repr_get_phys_port_name,
 	.ndo_get_stats64 = ice_repr_get_stats64,
 	.ndo_open = ice_repr_open,
 	.ndo_stop = ice_repr_stop,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_sched.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_sched.c
@@ -28,9 +28,8 @@
 	if (!root)
 		return -ENOMEM;
 
-	/* coverity[suspicious_sizeof] */
 	root->children = devm_kcalloc(ice_hw_to_dev(hw), hw->max_children[0],
-				      sizeof(*root), GFP_KERNEL);
+				      sizeof(*root->children), GFP_KERNEL);
 	if (!root->children) {
 		devm_kfree(ice_hw_to_dev(hw), root);
 		return -ENOMEM;
@@ -186,10 +185,9 @@
 	if (!node)
 		return -ENOMEM;
 	if (hw->max_children[layer]) {
-		/* coverity[suspicious_sizeof] */
 		node->children = devm_kcalloc(ice_hw_to_dev(hw),
 					      hw->max_children[layer],
-					      sizeof(*node), GFP_KERNEL);
+					      sizeof(*node->children), GFP_KERNEL);
 		if (!node->children) {
 			devm_kfree(ice_hw_to_dev(hw), node);
 			return -ENOMEM;
@@ -237,7 +235,7 @@
 ice_sched_remove_elems(struct ice_hw *hw, struct ice_sched_node *parent,
 		       u32 node_teid)
 {
-	DEFINE_FLEX(struct ice_aqc_delete_elem, buf, teid, 1);
+	DEFINE_RAW_FLEX(struct ice_aqc_delete_elem, buf, teid, 1);
 	u16 buf_size = __struct_size(buf);
 	u16 num_groups_removed = 0;
 	int status;
@@ -2219,7 +2217,7 @@
 ice_sched_move_nodes(struct ice_port_info *pi, struct ice_sched_node *parent,
 		     u16 num_items, u32 *list)
 {
-	DEFINE_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
+	DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
 	u16 buf_len = __struct_size(buf);
 	struct ice_sched_node *node;
 	u16 i, grps_movd = 0;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_sriov.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_sriov.c
@@ -1104,8 +1104,10 @@
 		return -ENOENT;
 
 	vsi = ice_get_vf_vsi(vf);
-	if (!vsi)
+	if (!vsi) {
+		ice_put_vf(vf);
 		return -ENOENT;
+	}
 
 	prev_msix = vf->num_msix;
 	prev_queues = vf->num_vf_qs;
@@ -1127,7 +1129,10 @@
 	if (vf->first_vector_idx < 0)
 		goto unroll;
 
-	if (ice_vf_reconfig_vsi(vf) || ice_vf_init_host_cfg(vf, vsi)) {
+	vsi->req_txq = queues;
+	vsi->req_rxq = queues;
+
+	if (ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT)) {
 		/* Try to rebuild with previous values */
 		needs_rebuild = true;
 		goto unroll;
@@ -1150,12 +1155,16 @@
 	vf->num_msix = prev_msix;
 	vf->num_vf_qs = prev_queues;
 	vf->first_vector_idx = ice_sriov_get_irqs(pf, vf->num_msix);
-	if (vf->first_vector_idx < 0)
+	if (vf->first_vector_idx < 0) {
+		ice_put_vf(vf);
 		return -EINVAL;
+	}
 
 	if (needs_rebuild) {
-		ice_vf_reconfig_vsi(vf);
-		ice_vf_init_host_cfg(vf, vsi);
+		vsi->req_txq = prev_queues;
+		vsi->req_rxq = prev_queues;
+
+		ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT);
 	}
 
 	ice_ena_vf_mappings(vf);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_switch.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_switch.c
@@ -1812,7 +1812,7 @@
 			   enum ice_sw_lkup_type lkup_type,
 			   enum ice_adminq_opc opc)
 {
-	DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
+	DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
 	u16 buf_len = __struct_size(sw_buf);
 	struct ice_aqc_res_elem *vsi_ele;
 	int status;
@@ -1825,7 +1825,8 @@
 	    lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
 	    lkup_type == ICE_SW_LKUP_PROMISC ||
 	    lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
-	    lkup_type == ICE_SW_LKUP_DFLT) {
+	    lkup_type == ICE_SW_LKUP_DFLT ||
+	    lkup_type == ICE_SW_LKUP_LAST) {
 		sw_buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_REP);
 	} else if (lkup_type == ICE_SW_LKUP_VLAN) {
 		if (opc == ice_aqc_opc_alloc_res)
@@ -2025,12 +2026,12 @@
  * ice_aq_map_recipe_to_profile - Map recipe to packet profile
  * @hw: pointer to the HW struct
  * @profile_id: package profile ID to associate the recipe with
- * @r_bitmap: Recipe bitmap filled in and need to be returned as response
+ * @r_assoc: Recipe bitmap filled in and need to be returned as response
  * @cd: pointer to command details structure or NULL
  * Recipe to profile association (0x0291)
  */
 int
-ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
+ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u64 r_assoc,
 			     struct ice_sq_cd *cd)
 {
 	struct ice_aqc_recipe_to_profile *cmd;
@@ -2042,7 +2043,7 @@
 	/* Set the recipe ID bit in the bitmask to let the device know which
 	 * profile we are associating the recipe to
 	 */
-	memcpy(cmd->recipe_assoc, r_bitmap, sizeof(cmd->recipe_assoc));
+	cmd->recipe_assoc = cpu_to_le64(r_assoc);
 
 	return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
 }
@@ -2051,12 +2052,12 @@
  * ice_aq_get_recipe_to_profile - Map recipe to packet profile
  * @hw: pointer to the HW struct
  * @profile_id: package profile ID to associate the recipe with
- * @r_bitmap: Recipe bitmap filled in and need to be returned as response
+ * @r_assoc: Recipe bitmap filled in and need to be returned as response
  * @cd: pointer to command details structure or NULL
  * Associate profile ID with given recipe (0x0293)
  */
 int
-ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
+ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u64 *r_assoc,
 			     struct ice_sq_cd *cd)
 {
 	struct ice_aqc_recipe_to_profile *cmd;
@@ -2069,7 +2070,7 @@
 
 	status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
 	if (!status)
-		memcpy(r_bitmap, cmd->recipe_assoc, sizeof(cmd->recipe_assoc));
+		*r_assoc = le64_to_cpu(cmd->recipe_assoc);
 
 	return status;
 }
@@ -2081,7 +2082,7 @@
  */
 int ice_alloc_recipe(struct ice_hw *hw, u16 *rid)
 {
-	DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
+	DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, sw_buf, elem, 1);
 	u16 buf_len = __struct_size(sw_buf);
 	int status;
 
@@ -2108,6 +2109,7 @@
 static void ice_get_recp_to_prof_map(struct ice_hw *hw)
 {
 	DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
+	u64 recp_assoc;
 	u16 i;
 
 	for (i = 0; i < hw->switch_info->max_used_prof_index + 1; i++) {
@@ -2115,8 +2117,9 @@
 
 		bitmap_zero(profile_to_recipe[i], ICE_MAX_NUM_RECIPES);
 		bitmap_zero(r_bitmap, ICE_MAX_NUM_RECIPES);
-		if (ice_aq_get_recipe_to_profile(hw, i, (u8 *)r_bitmap, NULL))
+		if (ice_aq_get_recipe_to_profile(hw, i, &recp_assoc, NULL))
 			continue;
+		bitmap_from_arr64(r_bitmap, &recp_assoc, ICE_MAX_NUM_RECIPES);
 		bitmap_copy(profile_to_recipe[i], r_bitmap,
 			    ICE_MAX_NUM_RECIPES);
 		for_each_set_bit(j, r_bitmap, ICE_MAX_NUM_RECIPES)
@@ -2255,10 +2258,10 @@
 		/* Propagate some data to the recipe database */
 		recps[idx].is_root = !!is_root;
 		recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
-		recps[idx].need_pass_l2 = root_bufs.content.act_ctrl &
-					  ICE_AQ_RECIPE_ACT_NEED_PASS_L2;
-		recps[idx].allow_pass_l2 = root_bufs.content.act_ctrl &
-					   ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2;
+		recps[idx].need_pass_l2 = !!(root_bufs.content.act_ctrl &
+					     ICE_AQ_RECIPE_ACT_NEED_PASS_L2);
+		recps[idx].allow_pass_l2 = !!(root_bufs.content.act_ctrl &
+					      ICE_AQ_RECIPE_ACT_ALLOW_PASS_L2);
 		bitmap_zero(recps[idx].res_idxs, ICE_MAX_FV_WORDS);
 		if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) {
 			recps[idx].chain_idx = root_bufs.content.result_indx &
@@ -2757,7 +2760,8 @@
 	    lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
 	    lkup_type == ICE_SW_LKUP_PROMISC ||
 	    lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
-	    lkup_type == ICE_SW_LKUP_DFLT)
+	    lkup_type == ICE_SW_LKUP_DFLT ||
+	    lkup_type == ICE_SW_LKUP_LAST)
 		rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR :
 			ICE_AQC_SW_RULES_T_VSI_LIST_SET;
 	else if (lkup_type == ICE_SW_LKUP_VLAN)
@@ -3052,7 +3056,7 @@
 
 		/* A rule already exists with the new VSI being added */
 		if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
-			return 0;
+			return -EEXIST;
 
 		/* Update the previously created VSI list set with
 		 * the new VSI ID passed in
@@ -3122,7 +3126,7 @@
 
 	list_head = &sw->recp_list[recp_id].filt_rules;
 	list_for_each_entry(list_itr, list_head, list_entry) {
-		if (list_itr->vsi_list_info) {
+		if (list_itr->vsi_count == 1 && list_itr->vsi_list_info) {
 			map_info = list_itr->vsi_list_info;
 			if (test_bit(vsi_handle, map_info->vsi_map)) {
 				*vsi_list_id = map_info->vsi_list_id;
@@ -4418,7 +4422,7 @@
 ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
 		   u16 *counter_id)
 {
-	DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
+	DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
 	u16 buf_len = __struct_size(buf);
 	int status;
 
@@ -4446,7 +4450,7 @@
 ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
 		  u16 counter_id)
 {
-	DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
+	DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
 	u16 buf_len = __struct_size(buf);
 	int status;
 
@@ -4476,7 +4480,7 @@
  */
 int ice_share_res(struct ice_hw *hw, u16 type, u8 shared, u16 res_id)
 {
-	DEFINE_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
+	DEFINE_RAW_FLEX(struct ice_aqc_alloc_free_res_elem, buf, elem, 1);
 	u16 buf_len = __struct_size(buf);
 	u16 res_type;
 	int status;
@@ -5390,22 +5394,24 @@
 	 */
 	list_for_each_entry(fvit, &rm->fv_list, list_entry) {
 		DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
+		u64 recp_assoc;
 		u16 j;
 
 		status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id,
-						      (u8 *)r_bitmap, NULL);
+						      &recp_assoc, NULL);
 		if (status)
 			goto err_unroll;
 
+		bitmap_from_arr64(r_bitmap, &recp_assoc, ICE_MAX_NUM_RECIPES);
 		bitmap_or(r_bitmap, r_bitmap, rm->r_bitmap,
 			  ICE_MAX_NUM_RECIPES);
 		status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
 		if (status)
 			goto err_unroll;
 
+		bitmap_to_arr64(&recp_assoc, r_bitmap, ICE_MAX_NUM_RECIPES);
 		status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id,
-						      (u8 *)r_bitmap,
-						      NULL);
+						      recp_assoc, NULL);
 		ice_release_change_lock(hw);
 
 		if (status)
@@ -6289,8 +6295,6 @@
 		if (!itr->vsi_list_info ||
 		    !test_bit(vsi_handle, itr->vsi_list_info->vsi_map))
 			continue;
-		/* Clearing it so that the logic can add it back */
-		clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
 		f_entry.fltr_info.vsi_handle = vsi_handle;
 		f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
 		/* update the src in case it is VSI num */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_switch.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_switch.h
@@ -424,10 +424,10 @@
 		      struct ice_aqc_recipe_data_elem *s_recipe_list,
 		      u16 num_recipes, struct ice_sq_cd *cd);
 int
-ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
+ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u64 *r_assoc,
 			     struct ice_sq_cd *cd);
 int
-ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
+ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u64 r_assoc,
 			     struct ice_sq_cd *cd);
 
 #endif /* _ICE_SWITCH_H_ */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_tc_lib.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_tc_lib.c
@@ -28,6 +28,8 @@
 	 * - ICE_TC_FLWR_FIELD_VLAN_TPID (present if specified)
 	 * - Tunnel flag (present if tunnel)
 	 */
+	if (fltr->direction == ICE_ESWITCH_FLTR_EGRESS)
+		lkups_cnt++;
 
 	if (flags & ICE_TC_FLWR_FIELD_TENANT_ID)
 		lkups_cnt++;
@@ -363,6 +365,11 @@
 	/* Always add direction metadata */
 	ice_rule_add_direction_metadata(&list[ICE_TC_METADATA_LKUP_IDX]);
 
+	if (tc_fltr->direction == ICE_ESWITCH_FLTR_EGRESS) {
+		ice_rule_add_src_vsi_metadata(&list[i]);
+		i++;
+	}
+
 	rule_info->tun_type = ice_sw_type_from_tunnel(tc_fltr->tunnel_type);
 	if (tc_fltr->tunnel_type != TNL_LAST) {
 		i = ice_tc_fill_tunnel_outer(flags, tc_fltr, list, i);
@@ -772,7 +779,7 @@
 	int ret;
 	int i;
 
-	if (!flags || (flags & ICE_TC_FLWR_FIELD_ENC_SRC_L4_PORT)) {
+	if (flags & ICE_TC_FLWR_FIELD_ENC_SRC_L4_PORT) {
 		NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported encap field(s)");
 		return -EOPNOTSUPP;
 	}
@@ -811,6 +818,17 @@
 		rule_info.sw_act.flag |= ICE_FLTR_TX;
 		rule_info.sw_act.src = vsi->idx;
 		rule_info.flags_info.act = ICE_SINGLE_ACT_LAN_ENABLE;
+		/* This is a specific case. The destination VSI index is
+		 * overwritten by the source VSI index. This type of filter
+		 * should allow the packet to go to the LAN, not to the
+		 * VSI passed here. It should set LAN_EN bit only. However,
+		 * the VSI must be a valid one. Setting source VSI index
+		 * here is safe. Even if the result from switch is set LAN_EN
+		 * and LB_EN (which normally will pass the packet to this VSI)
+		 * packet won't be seen on the VSI, because local loopback is
+		 * turned off.
+		 */
+		rule_info.sw_act.vsi_handle = vsi->idx;
 	} else {
 		/* VF to VF */
 		rule_info.sw_act.flag |= ICE_FLTR_TX;
@@ -820,6 +838,7 @@
 
 	/* specify the cookie as filter_rule_id */
 	rule_info.fltr_rule_id = fltr->cookie;
+	rule_info.src_vsi = vsi->idx;
 
 	ret = ice_add_adv_rule(hw, list, lkups_cnt, &rule_info, &rule_added);
 	if (ret == -EEXIST) {
@@ -1481,7 +1500,10 @@
 		  (BIT_ULL(FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS) |
 		   BIT_ULL(FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS) |
 		   BIT_ULL(FLOW_DISSECTOR_KEY_ENC_KEYID) |
-		   BIT_ULL(FLOW_DISSECTOR_KEY_ENC_PORTS))) {
+		   BIT_ULL(FLOW_DISSECTOR_KEY_ENC_PORTS) |
+		   BIT_ULL(FLOW_DISSECTOR_KEY_ENC_IP) |
+		   BIT_ULL(FLOW_DISSECTOR_KEY_ENC_OPTS) |
+		   BIT_ULL(FLOW_DISSECTOR_KEY_ENC_CONTROL))) {
 		NL_SET_ERR_MSG_MOD(fltr->extack, "Tunnel key used, but device isn't a tunnel");
 		return -EOPNOTSUPP;
 	} else {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_txrx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_txrx.c
@@ -456,7 +456,7 @@
 	if (rx_ring->vsi->type == ICE_VSI_PF)
 		if (xdp_rxq_info_is_reg(&rx_ring->xdp_rxq))
 			xdp_rxq_info_unreg(&rx_ring->xdp_rxq);
-	rx_ring->xdp_prog = NULL;
+	WRITE_ONCE(rx_ring->xdp_prog, NULL);
 	if (rx_ring->xsk_pool) {
 		kfree(rx_ring->xdp_buf);
 		rx_ring->xdp_buf = NULL;
@@ -522,44 +522,19 @@
 }
 
 /**
- * ice_rx_frame_truesize
- * @rx_ring: ptr to Rx ring
- * @size: size
- *
- * calculate the truesize with taking into the account PAGE_SIZE of
- * underlying arch
- */
-static unsigned int
-ice_rx_frame_truesize(struct ice_rx_ring *rx_ring, const unsigned int size)
-{
-	unsigned int truesize;
-
-#if (PAGE_SIZE < 8192)
-	truesize = ice_rx_pg_size(rx_ring) / 2; /* Must be power-of-2 */
-#else
-	truesize = rx_ring->rx_offset ?
-		SKB_DATA_ALIGN(rx_ring->rx_offset + size) +
-		SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
-		SKB_DATA_ALIGN(size);
-#endif
-	return truesize;
-}
-
-/**
  * ice_run_xdp - Executes an XDP program on initialized xdp_buff
  * @rx_ring: Rx ring
  * @xdp: xdp_buff used as input to the XDP program
  * @xdp_prog: XDP program to run
  * @xdp_ring: ring to be used for XDP_TX action
- * @rx_buf: Rx buffer to store the XDP action
  * @eop_desc: Last descriptor in packet to read metadata from
  *
  * Returns any of ICE_XDP_{PASS, CONSUMED, TX, REDIR}
  */
-static void
+static u32
 ice_run_xdp(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
 	    struct bpf_prog *xdp_prog, struct ice_tx_ring *xdp_ring,
-	    struct ice_rx_buf *rx_buf, union ice_32b_rx_flex_desc *eop_desc)
+	    union ice_32b_rx_flex_desc *eop_desc)
 {
 	unsigned int ret = ICE_XDP_PASS;
 	u32 act;
@@ -598,7 +573,7 @@
 		ret = ICE_XDP_CONSUMED;
 	}
 exit:
-	ice_set_rx_bufs_act(xdp, rx_ring, ret);
+	return ret;
 }
 
 /**
@@ -837,16 +812,15 @@
 	if (!dev_page_is_reusable(page))
 		return false;
 
-#if (PAGE_SIZE < 8192)
 	/* if we are only owner of page we can reuse it */
 	if (unlikely(rx_buf->pgcnt - pagecnt_bias > 1))
 		return false;
-#else
+#if (PAGE_SIZE >= 8192)
 #define ICE_LAST_OFFSET \
-	(SKB_WITH_OVERHEAD(PAGE_SIZE) - ICE_RXBUF_2048)
+	(SKB_WITH_OVERHEAD(PAGE_SIZE) - ICE_RXBUF_3072)
 	if (rx_buf->page_offset > ICE_LAST_OFFSET)
 		return false;
-#endif /* PAGE_SIZE < 8192) */
+#endif /* PAGE_SIZE >= 8192) */
 
 	/* If we have drained the page fragment pool we need to update
 	 * the pagecnt_bias and page count so that we fully restock the
@@ -885,10 +859,8 @@
 		xdp_buff_set_frags_flag(xdp);
 	}
 
-	if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS)) {
-		ice_set_rx_bufs_act(xdp, rx_ring, ICE_XDP_CONSUMED);
+	if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS))
 		return -ENOMEM;
-	}
 
 	__skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++, rx_buf->page,
 				   rx_buf->page_offset, size);
@@ -949,12 +921,6 @@
 	struct ice_rx_buf *rx_buf;
 
 	rx_buf = &rx_ring->rx_buf[ntc];
-	rx_buf->pgcnt =
-#if (PAGE_SIZE < 8192)
-		page_count(rx_buf->page);
-#else
-		0;
-#endif
 	prefetchw(rx_buf->page);
 
 	if (!size)
@@ -971,6 +937,31 @@
 }
 
 /**
+ * ice_get_pgcnts - grab page_count() for gathered fragments
+ * @rx_ring: Rx descriptor ring to store the page counts on
+ *
+ * This function is intended to be called right before running XDP
+ * program so that the page recycling mechanism will be able to take
+ * a correct decision regarding underlying pages; this is done in such
+ * way as XDP program can change the refcount of page
+ */
+static void ice_get_pgcnts(struct ice_rx_ring *rx_ring)
+{
+	u32 nr_frags = rx_ring->nr_frags + 1;
+	u32 idx = rx_ring->first_desc;
+	struct ice_rx_buf *rx_buf;
+	u32 cnt = rx_ring->count;
+
+	for (int i = 0; i < nr_frags; i++) {
+		rx_buf = &rx_ring->rx_buf[idx];
+		rx_buf->pgcnt = page_count(rx_buf->page);
+
+		if (++idx == cnt)
+			idx = 0;
+	}
+}
+
+/**
  * ice_build_skb - Build skb around an existing buffer
  * @rx_ring: Rx descriptor ring to transact packets on
  * @xdp: xdp_buff pointing to the data
@@ -1082,12 +1073,12 @@
 				rx_buf->page_offset + headlen, size,
 				xdp->frame_sz);
 	} else {
-		/* buffer is unused, change the act that should be taken later
-		 * on; data was copied onto skb's linear part so there's no
+		/* buffer is unused, restore biased page count in Rx buffer;
+		 * data was copied onto skb's linear part so there's no
 		 * need for adjusting page offset and we can reuse this buffer
 		 * as-is
 		 */
-		rx_buf->act = ICE_SKB_CONSUMED;
+		rx_buf->pagecnt_bias++;
 	}
 
 	if (unlikely(xdp_buff_has_frags(xdp))) {
@@ -1135,6 +1126,65 @@
 }
 
 /**
+ * ice_put_rx_mbuf - ice_put_rx_buf() caller, for all frame frags
+ * @rx_ring: Rx ring with all the auxiliary data
+ * @xdp: XDP buffer carrying linear + frags part
+ * @xdp_xmit: XDP_TX/XDP_REDIRECT verdict storage
+ * @ntc: a current next_to_clean value to be stored at rx_ring
+ * @verdict: return code from XDP program execution
+ *
+ * Walk through gathered fragments and satisfy internal page
+ * recycle mechanism; we take here an action related to verdict
+ * returned by XDP program;
+ */
+static void ice_put_rx_mbuf(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
+			    u32 *xdp_xmit, u32 ntc, u32 verdict)
+{
+	u32 nr_frags = rx_ring->nr_frags + 1;
+	u32 idx = rx_ring->first_desc;
+	u32 cnt = rx_ring->count;
+	u32 post_xdp_frags = 1;
+	struct ice_rx_buf *buf;
+	int i;
+
+	if (unlikely(xdp_buff_has_frags(xdp)))
+		post_xdp_frags += xdp_get_shared_info_from_buff(xdp)->nr_frags;
+
+	for (i = 0; i < post_xdp_frags; i++) {
+		buf = &rx_ring->rx_buf[idx];
+
+		if (verdict & (ICE_XDP_TX | ICE_XDP_REDIR)) {
+			ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
+			*xdp_xmit |= verdict;
+		} else if (verdict & ICE_XDP_CONSUMED) {
+			buf->pagecnt_bias++;
+		} else if (verdict == ICE_XDP_PASS) {
+			ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
+		}
+
+		ice_put_rx_buf(rx_ring, buf);
+
+		if (++idx == cnt)
+			idx = 0;
+	}
+	/* handle buffers that represented frags released by XDP prog;
+	 * for these we keep pagecnt_bias as-is; refcount from struct page
+	 * has been decremented within XDP prog and we do not have to increase
+	 * the biased refcnt
+	 */
+	for (; i < nr_frags; i++) {
+		buf = &rx_ring->rx_buf[idx];
+		ice_put_rx_buf(rx_ring, buf);
+		if (++idx == cnt)
+			idx = 0;
+	}
+
+	xdp->data = NULL;
+	rx_ring->first_desc = ntc;
+	rx_ring->nr_frags = 0;
+}
+
+/**
  * ice_clean_rx_irq - Clean completed descriptors from Rx ring - bounce buf
  * @rx_ring: Rx descriptor ring to transact packets on
  * @budget: Total limit on number of packets to process
@@ -1151,20 +1201,13 @@
 	unsigned int total_rx_bytes = 0, total_rx_pkts = 0;
 	unsigned int offset = rx_ring->rx_offset;
 	struct xdp_buff *xdp = &rx_ring->xdp;
-	u32 cached_ntc = rx_ring->first_desc;
 	struct ice_tx_ring *xdp_ring = NULL;
 	struct bpf_prog *xdp_prog = NULL;
 	u32 ntc = rx_ring->next_to_clean;
+	u32 cached_ntu, xdp_verdict;
 	u32 cnt = rx_ring->count;
 	u32 xdp_xmit = 0;
-	u32 cached_ntu;
 	bool failure;
-	u32 first;
-
-	/* Frame size depend on rx_ring setup when PAGE_SIZE=4K */
-#if (PAGE_SIZE < 8192)
-	xdp->frame_sz = ice_rx_frame_truesize(rx_ring, 0);
-#endif
 
 	xdp_prog = READ_ONCE(rx_ring->xdp_prog);
 	if (xdp_prog) {
@@ -1224,12 +1267,9 @@
 			hard_start = page_address(rx_buf->page) + rx_buf->page_offset -
 				     offset;
 			xdp_prepare_buff(xdp, hard_start, offset, size, !!offset);
-#if (PAGE_SIZE > 4096)
-			/* At larger PAGE_SIZE, frame_sz depend on len size */
-			xdp->frame_sz = ice_rx_frame_truesize(rx_ring, size);
-#endif
 			xdp_buff_clear_frags_flag(xdp);
 		} else if (ice_add_xdp_frag(rx_ring, xdp, rx_buf, size)) {
+			ice_put_rx_mbuf(rx_ring, xdp, NULL, ntc, ICE_XDP_CONSUMED);
 			break;
 		}
 		if (++ntc == cnt)
@@ -1239,15 +1279,15 @@
 		if (ice_is_non_eop(rx_ring, rx_desc))
 			continue;
 
-		ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_buf, rx_desc);
-		if (rx_buf->act == ICE_XDP_PASS)
+		ice_get_pgcnts(rx_ring);
+		xdp_verdict = ice_run_xdp(rx_ring, xdp, xdp_prog, xdp_ring, rx_desc);
+		if (xdp_verdict == ICE_XDP_PASS)
 			goto construct_skb;
 		total_rx_bytes += xdp_get_buff_len(xdp);
 		total_rx_pkts++;
 
-		xdp->data = NULL;
-		rx_ring->first_desc = ntc;
-		rx_ring->nr_frags = 0;
+		ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
+
 		continue;
 construct_skb:
 		if (likely(ice_ring_uses_build_skb(rx_ring)))
@@ -1257,18 +1297,12 @@
 		/* exit if we failed to retrieve a buffer */
 		if (!skb) {
 			rx_ring->ring_stats->rx_stats.alloc_page_failed++;
-			rx_buf->act = ICE_XDP_CONSUMED;
-			if (unlikely(xdp_buff_has_frags(xdp)))
-				ice_set_rx_bufs_act(xdp, rx_ring,
-						    ICE_XDP_CONSUMED);
-			xdp->data = NULL;
-			rx_ring->first_desc = ntc;
-			rx_ring->nr_frags = 0;
-			break;
+			xdp_verdict = ICE_XDP_CONSUMED;
 		}
-		xdp->data = NULL;
-		rx_ring->first_desc = ntc;
-		rx_ring->nr_frags = 0;
+		ice_put_rx_mbuf(rx_ring, xdp, &xdp_xmit, ntc, xdp_verdict);
+
+		if (!skb)
+			break;
 
 		stat_err_bits = BIT(ICE_RX_FLEX_DESC_STATUS0_RXE_S);
 		if (unlikely(ice_test_staterr(rx_desc->wb.status_error0,
@@ -1297,23 +1331,6 @@
 		total_rx_pkts++;
 	}
 
-	first = rx_ring->first_desc;
-	while (cached_ntc != first) {
-		struct ice_rx_buf *buf = &rx_ring->rx_buf[cached_ntc];
-
-		if (buf->act & (ICE_XDP_TX | ICE_XDP_REDIR)) {
-			ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
-			xdp_xmit |= buf->act;
-		} else if (buf->act & ICE_XDP_CONSUMED) {
-			buf->pagecnt_bias++;
-		} else if (buf->act == ICE_XDP_PASS) {
-			ice_rx_buf_adjust_pg_offset(buf, xdp->frame_sz);
-		}
-
-		ice_put_rx_buf(rx_ring, buf);
-		if (++cached_ntc >= cnt)
-			cached_ntc = 0;
-	}
 	rx_ring->next_to_clean = ntc;
 	/* return up to cleaned_count buffers to hardware */
 	failure = ice_alloc_rx_bufs(rx_ring, ICE_RX_DESC_UNUSED(rx_ring));
@@ -1522,10 +1539,11 @@
 	 * budget and be more aggressive about cleaning up the Tx descriptors.
 	 */
 	ice_for_each_tx_ring(tx_ring, q_vector->tx) {
+		struct xsk_buff_pool *xsk_pool = READ_ONCE(tx_ring->xsk_pool);
 		bool wd;
 
-		if (tx_ring->xsk_pool)
-			wd = ice_xmit_zc(tx_ring);
+		if (xsk_pool)
+			wd = ice_xmit_zc(tx_ring, xsk_pool);
 		else if (ice_ring_is_xdp(tx_ring))
 			wd = true;
 		else
@@ -1551,6 +1569,7 @@
 		budget_per_ring = budget;
 
 	ice_for_each_rx_ring(rx_ring, q_vector->rx) {
+		struct xsk_buff_pool *xsk_pool = READ_ONCE(rx_ring->xsk_pool);
 		int cleaned;
 
 		/* A dedicated path for zero-copy allows making a single
@@ -1558,7 +1577,7 @@
 		 * ice_clean_rx_irq function and makes the codebase cleaner.
 		 */
 		cleaned = rx_ring->xsk_pool ?
-			  ice_clean_rx_irq_zc(rx_ring, budget_per_ring) :
+			  ice_clean_rx_irq_zc(rx_ring, xsk_pool, budget_per_ring) :
 			  ice_clean_rx_irq(rx_ring, budget_per_ring);
 		work_done += cleaned;
 		/* if we clean as many as budgeted, we must not be done */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_txrx.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_txrx.h
@@ -201,7 +201,6 @@
 	struct page *page;
 	unsigned int page_offset;
 	unsigned int pgcnt;
-	unsigned int act;
 	unsigned int pagecnt_bias;
 };
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_txrx_lib.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_txrx_lib.h
@@ -6,49 +6,6 @@
 #include "ice.h"
 
 /**
- * ice_set_rx_bufs_act - propagate Rx buffer action to frags
- * @xdp: XDP buffer representing frame (linear and frags part)
- * @rx_ring: Rx ring struct
- * act: action to store onto Rx buffers related to XDP buffer parts
- *
- * Set action that should be taken before putting Rx buffer from first frag
- * to the last.
- */
-static inline void
-ice_set_rx_bufs_act(struct xdp_buff *xdp, const struct ice_rx_ring *rx_ring,
-		    const unsigned int act)
-{
-	u32 sinfo_frags = xdp_get_shared_info_from_buff(xdp)->nr_frags;
-	u32 nr_frags = rx_ring->nr_frags + 1;
-	u32 idx = rx_ring->first_desc;
-	u32 cnt = rx_ring->count;
-	struct ice_rx_buf *buf;
-
-	for (int i = 0; i < nr_frags; i++) {
-		buf = &rx_ring->rx_buf[idx];
-		buf->act = act;
-
-		if (++idx == cnt)
-			idx = 0;
-	}
-
-	/* adjust pagecnt_bias on frags freed by XDP prog */
-	if (sinfo_frags < rx_ring->nr_frags && act == ICE_XDP_CONSUMED) {
-		u32 delta = rx_ring->nr_frags - sinfo_frags;
-
-		while (delta) {
-			if (idx == 0)
-				idx = cnt - 1;
-			else
-				idx--;
-			buf = &rx_ring->rx_buf[idx];
-			buf->pagecnt_bias--;
-			delta--;
-		}
-	}
-}
-
-/**
  * ice_test_staterr - tests bits in Rx descriptor status and error fields
  * @status_err_n: Rx descriptor status_error0 or status_error1 bits
  * @stat_err_bits: value to mask
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_type.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_type.h
@@ -480,6 +480,8 @@
 	u32 orom_size;				/* Size of OROM bank */
 	u32 netlist_ptr;			/* Pointer to 1st Netlist bank */
 	u32 netlist_size;			/* Size of Netlist bank */
+	u32 active_css_hdr_len;			/* Active CSS header length */
+	u32 inactive_css_hdr_len;		/* Inactive CSS header length */
 	enum ice_flash_bank nvm_bank;		/* Active NVM bank */
 	enum ice_flash_bank orom_bank;		/* Active OROM bank */
 	enum ice_flash_bank netlist_bank;	/* Active Netlist bank */
@@ -1083,17 +1085,13 @@
 #define ICE_SR_SECTOR_SIZE_IN_WORDS	0x800
 
 /* CSS Header words */
+#define ICE_NVM_CSS_HDR_LEN_L			0x02
+#define ICE_NVM_CSS_HDR_LEN_H			0x03
 #define ICE_NVM_CSS_SREV_L			0x14
 #define ICE_NVM_CSS_SREV_H			0x15
 
-/* Length of CSS header section in words */
-#define ICE_CSS_HEADER_LENGTH			330
-
-/* Offset of Shadow RAM copy in the NVM bank area. */
-#define ICE_NVM_SR_COPY_WORD_OFFSET		roundup(ICE_CSS_HEADER_LENGTH, 32)
-
-/* Size in bytes of Option ROM trailer */
-#define ICE_NVM_OROM_TRAILER_LENGTH		(2 * ICE_CSS_HEADER_LENGTH)
+/* Length of Authentication header section in words */
+#define ICE_NVM_AUTH_HEADER_LEN			0x08
 
 /* The Link Topology Netlist section is stored as a series of words. It is
  * stored in the NVM as a TLV, with the first two words containing the type
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_vf_lib.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_vf_lib.c
@@ -256,7 +256,7 @@
  *
  * It brings the VSI down and then reconfigures it with the hardware.
  */
-int ice_vf_reconfig_vsi(struct ice_vf *vf)
+static int ice_vf_reconfig_vsi(struct ice_vf *vf)
 {
 	struct ice_vsi *vsi = ice_get_vf_vsi(vf);
 	struct ice_vsi_cfg_params params = {};
@@ -344,6 +344,13 @@
 
 		err = vlan_ops->add_vlan(vsi, &vf->port_vlan_info);
 	} else {
+		/* clear possible previous port vlan config */
+		err = ice_vsi_clear_port_vlan(vsi);
+		if (err) {
+			dev_err(dev, "failed to clear port VLAN via VSI parameters for VF %u, error %d\n",
+				vf->vf_id, err);
+			return err;
+		}
 		err = ice_vsi_add_vlan_zero(vsi);
 	}
 
@@ -863,6 +870,11 @@
 		return 0;
 	}
 
+	if (flags & ICE_VF_RESET_LOCK)
+		mutex_lock(&vf->cfg_lock);
+	else
+		lockdep_assert_held(&vf->cfg_lock);
+
 	lag = pf->lag;
 	mutex_lock(&pf->lag_mutex);
 	if (lag && lag->bonded && lag->primary) {
@@ -874,11 +886,6 @@
 			act_prt = ICE_LAG_INVALID_PORT;
 	}
 
-	if (flags & ICE_VF_RESET_LOCK)
-		mutex_lock(&vf->cfg_lock);
-	else
-		lockdep_assert_held(&vf->cfg_lock);
-
 	if (ice_is_vf_disabled(vf)) {
 		vsi = ice_get_vf_vsi(vf);
 		if (!vsi) {
@@ -963,14 +970,14 @@
 	ice_mbx_clear_malvf(&vf->mbx_info);
 
 out_unlock:
-	if (flags & ICE_VF_RESET_LOCK)
-		mutex_unlock(&vf->cfg_lock);
-
 	if (lag && lag->bonded && lag->primary &&
 	    act_prt != ICE_LAG_INVALID_PORT)
 		ice_lag_move_vf_nodes_cfg(lag, pri_prt, act_prt);
 	mutex_unlock(&pf->lag_mutex);
 
+	if (flags & ICE_VF_RESET_LOCK)
+		mutex_unlock(&vf->cfg_lock);
+
 	return err;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_vf_lib_private.h
@@ -23,7 +23,6 @@
 #warning "Only include ice_vf_lib_private.h in CONFIG_PCI_IOV virtualization files"
 #endif
 
-int ice_vf_reconfig_vsi(struct ice_vf *vf);
 void ice_initialize_vf_entry(struct ice_vf *vf);
 void ice_dis_vf_qs(struct ice_vf *vf);
 int ice_check_vf_init(struct ice_vf *vf);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_vf_vsi_vlan_ops.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_vf_vsi_vlan_ops.c
@@ -26,24 +26,22 @@
 	struct ice_vsi_vlan_ops *vlan_ops;
 	struct ice_pf *pf = vsi->back;
 
-	if (ice_is_dvm_ena(&pf->hw)) {
-		vlan_ops = &vsi->outer_vlan_ops;
+	/* setup inner VLAN ops */
+	vlan_ops = &vsi->inner_vlan_ops;
 
-		/* setup outer VLAN ops */
-		vlan_ops->set_port_vlan = ice_vsi_set_outer_port_vlan;
-		vlan_ops->clear_port_vlan = ice_vsi_clear_outer_port_vlan;
-
-		/* setup inner VLAN ops */
-		vlan_ops = &vsi->inner_vlan_ops;
+	if (ice_is_dvm_ena(&pf->hw)) {
 		vlan_ops->add_vlan = noop_vlan_arg;
 		vlan_ops->del_vlan = noop_vlan_arg;
 		vlan_ops->ena_stripping = ice_vsi_ena_inner_stripping;
 		vlan_ops->dis_stripping = ice_vsi_dis_inner_stripping;
 		vlan_ops->ena_insertion = ice_vsi_ena_inner_insertion;
 		vlan_ops->dis_insertion = ice_vsi_dis_inner_insertion;
-	} else {
-		vlan_ops = &vsi->inner_vlan_ops;
 
+		/* setup outer VLAN ops */
+		vlan_ops = &vsi->outer_vlan_ops;
+		vlan_ops->set_port_vlan = ice_vsi_set_outer_port_vlan;
+		vlan_ops->clear_port_vlan = ice_vsi_clear_outer_port_vlan;
+	} else {
 		vlan_ops->set_port_vlan = ice_vsi_set_inner_port_vlan;
 		vlan_ops->clear_port_vlan = ice_vsi_clear_inner_port_vlan;
 	}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_virtchnl.c
@@ -499,7 +499,7 @@
 	vfres->rss_lut_size = ICE_LUT_VSI_SIZE;
 	vfres->max_mtu = ice_vc_get_max_frame_size(vf);
 
-	vfres->vsi_res[0].vsi_id = vf->lan_vsi_num;
+	vfres->vsi_res[0].vsi_id = ICE_VF_VSI_ID;
 	vfres->vsi_res[0].vsi_type = VIRTCHNL_VSI_SRIOV;
 	vfres->vsi_res[0].num_queue_pairs = vsi->num_txq;
 	ether_addr_copy(vfres->vsi_res[0].default_mac_addr,
@@ -545,27 +545,20 @@
  */
 bool ice_vc_isvalid_vsi_id(struct ice_vf *vf, u16 vsi_id)
 {
-	struct ice_pf *pf = vf->pf;
-	struct ice_vsi *vsi;
-
-	vsi = ice_find_vsi(pf, vsi_id);
-
-	return (vsi && (vsi->vf == vf));
+	return vsi_id == ICE_VF_VSI_ID;
 }
 
 /**
  * ice_vc_isvalid_q_id
- * @vf: pointer to the VF info
- * @vsi_id: VSI ID
+ * @vsi: VSI to check queue ID against
  * @qid: VSI relative queue ID
  *
  * check for the valid queue ID
  */
-static bool ice_vc_isvalid_q_id(struct ice_vf *vf, u16 vsi_id, u8 qid)
+static bool ice_vc_isvalid_q_id(struct ice_vsi *vsi, u8 qid)
 {
-	struct ice_vsi *vsi = ice_find_vsi(vf->pf, vsi_id);
 	/* allocated Tx and Rx queues should be always equal for VF VSI */
-	return (vsi && (qid < vsi->alloc_txq));
+	return qid < vsi->alloc_txq;
 }
 
 /**
@@ -1323,7 +1316,7 @@
 	 */
 	q_map = vqs->rx_queues;
 	for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) {
-		if (!ice_vc_isvalid_q_id(vf, vqs->vsi_id, vf_q_id)) {
+		if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) {
 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
 			goto error_param;
 		}
@@ -1345,7 +1338,7 @@
 
 	q_map = vqs->tx_queues;
 	for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) {
-		if (!ice_vc_isvalid_q_id(vf, vqs->vsi_id, vf_q_id)) {
+		if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) {
 			v_ret = VIRTCHNL_STATUS_ERR_PARAM;
 			goto error_param;
 		}
@@ -1450,7 +1443,7 @@
 		q_map = vqs->tx_queues;
 
 		for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) {
-			if (!ice_vc_isvalid_q_id(vf, vqs->vsi_id, vf_q_id)) {
+			if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) {
 				v_ret = VIRTCHNL_STATUS_ERR_PARAM;
 				goto error_param;
 			}
@@ -1476,7 +1469,7 @@
 		bitmap_zero(vf->rxq_ena, ICE_MAX_RSS_QS_PER_VF);
 	} else if (q_map) {
 		for_each_set_bit(vf_q_id, &q_map, ICE_MAX_RSS_QS_PER_VF) {
-			if (!ice_vc_isvalid_q_id(vf, vqs->vsi_id, vf_q_id)) {
+			if (!ice_vc_isvalid_q_id(vsi, vf_q_id)) {
 				v_ret = VIRTCHNL_STATUS_ERR_PARAM;
 				goto error_param;
 			}
@@ -1532,7 +1525,7 @@
 	for_each_set_bit(vsi_q_id_idx, &qmap, ICE_MAX_RSS_QS_PER_VF) {
 		vsi_q_id = vsi_q_id_idx;
 
-		if (!ice_vc_isvalid_q_id(vf, vsi->vsi_num, vsi_q_id))
+		if (!ice_vc_isvalid_q_id(vsi, vsi_q_id))
 			return VIRTCHNL_STATUS_ERR_PARAM;
 
 		q_vector->num_ring_rx++;
@@ -1546,7 +1539,7 @@
 	for_each_set_bit(vsi_q_id_idx, &qmap, ICE_MAX_RSS_QS_PER_VF) {
 		vsi_q_id = vsi_q_id_idx;
 
-		if (!ice_vc_isvalid_q_id(vf, vsi->vsi_num, vsi_q_id))
+		if (!ice_vc_isvalid_q_id(vsi, vsi_q_id))
 			return VIRTCHNL_STATUS_ERR_PARAM;
 
 		q_vector->num_ring_tx++;
@@ -1703,7 +1696,7 @@
 		    qpi->txq.headwb_enabled ||
 		    !ice_vc_isvalid_ring_len(qpi->txq.ring_len) ||
 		    !ice_vc_isvalid_ring_len(qpi->rxq.ring_len) ||
-		    !ice_vc_isvalid_q_id(vf, qci->vsi_id, qpi->txq.queue_id)) {
+		    !ice_vc_isvalid_q_id(vsi, qpi->txq.queue_id)) {
 			goto error_param;
 		}
 
@@ -1718,8 +1711,8 @@
 
 		/* copy Tx queue info from VF into VSI */
 		if (qpi->txq.ring_len > 0) {
-			vsi->tx_rings[i]->dma = qpi->txq.dma_ring_addr;
-			vsi->tx_rings[i]->count = qpi->txq.ring_len;
+			vsi->tx_rings[q_idx]->dma = qpi->txq.dma_ring_addr;
+			vsi->tx_rings[q_idx]->count = qpi->txq.ring_len;
 
 			/* Disable any existing queue first */
 			if (ice_vf_vsi_dis_single_txq(vf, vsi, q_idx))
@@ -1728,7 +1721,7 @@
 			/* Configure a queue with the requested settings */
 			if (ice_vsi_cfg_single_txq(vsi, vsi->tx_rings, q_idx)) {
 				dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure TX queue %d\n",
-					 vf->vf_id, i);
+					 vf->vf_id, q_idx);
 				goto error_param;
 			}
 		}
@@ -1736,24 +1729,23 @@
 		/* copy Rx queue info from VF into VSI */
 		if (qpi->rxq.ring_len > 0) {
 			u16 max_frame_size = ice_vc_get_max_frame_size(vf);
+			struct ice_rx_ring *ring = vsi->rx_rings[q_idx];
 			u32 rxdid;
 
-			vsi->rx_rings[i]->dma = qpi->rxq.dma_ring_addr;
-			vsi->rx_rings[i]->count = qpi->rxq.ring_len;
+			ring->dma = qpi->rxq.dma_ring_addr;
+			ring->count = qpi->rxq.ring_len;
 
 			if (qpi->rxq.crc_disable)
-				vsi->rx_rings[q_idx]->flags |=
-					ICE_RX_FLAGS_CRC_STRIP_DIS;
+				ring->flags |= ICE_RX_FLAGS_CRC_STRIP_DIS;
 			else
-				vsi->rx_rings[q_idx]->flags &=
-					~ICE_RX_FLAGS_CRC_STRIP_DIS;
+				ring->flags &= ~ICE_RX_FLAGS_CRC_STRIP_DIS;
 
 			if (qpi->rxq.databuffer_size != 0 &&
 			    (qpi->rxq.databuffer_size > ((16 * 1024) - 128) ||
 			     qpi->rxq.databuffer_size < 1024))
 				goto error_param;
 			vsi->rx_buf_len = qpi->rxq.databuffer_size;
-			vsi->rx_rings[i]->rx_buf_len = vsi->rx_buf_len;
+			ring->rx_buf_len = vsi->rx_buf_len;
 			if (qpi->rxq.max_pkt_size > max_frame_size ||
 			    qpi->rxq.max_pkt_size < 64)
 				goto error_param;
@@ -1768,7 +1760,7 @@
 
 			if (ice_vsi_cfg_single_rxq(vsi, q_idx)) {
 				dev_warn(ice_pf_to_dev(pf), "VF-%d failed to configure RX queue %d\n",
-					 vf->vf_id, i);
+					 vf->vf_id, q_idx);
 				goto error_param;
 			}
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_virtchnl.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_virtchnl.h
@@ -19,6 +19,15 @@
 #define ICE_MAX_MACADDR_PER_VF		18
 #define ICE_FLEX_DESC_RXDID_MAX_NUM	64
 
+/* VFs only get a single VSI. For ice hardware, the VF does not need to know
+ * its VSI index. However, the virtchnl interface requires a VSI number,
+ * mainly due to legacy hardware.
+ *
+ * Since the VF doesn't need this information, report a static value to the VF
+ * instead of leaking any information about the PF or hardware setup.
+ */
+#define ICE_VF_VSI_ID	1
+
 struct ice_virtchnl_ops {
 	int (*get_ver_msg)(struct ice_vf *vf, u8 *msg);
 	int (*get_vf_res_msg)(struct ice_vf *vf, u8 *msg);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.c
@@ -94,9 +94,6 @@
 	if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_FDIR_PF))
 		return -EINVAL;
 
-	if (vsi_id != vf->lan_vsi_num)
-		return -EINVAL;
-
 	if (!ice_vc_isvalid_vsi_id(vf, vsi_id))
 		return -EINVAL;
 
@@ -539,6 +536,8 @@
 		fdir->fdir_fltr_cnt[flow][0] = 0;
 		fdir->fdir_fltr_cnt[flow][1] = 0;
 	}
+
+	fdir->fdir_fltr_cnt_total = 0;
 }
 
 /**
@@ -1563,6 +1562,7 @@
 	resp->status = status;
 	resp->flow_id = conf->flow_id;
 	vf->fdir.fdir_fltr_cnt[conf->input.flow_type][is_tun]++;
+	vf->fdir.fdir_fltr_cnt_total++;
 
 	ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret,
 				    (u8 *)resp, len);
@@ -1627,6 +1627,7 @@
 	resp->status = status;
 	ice_vc_fdir_remove_entry(vf, conf, conf->flow_id);
 	vf->fdir.fdir_fltr_cnt[conf->input.flow_type][is_tun]--;
+	vf->fdir.fdir_fltr_cnt_total--;
 
 	ret = ice_vc_send_msg_to_vf(vf, ctx->v_opcode, v_ret,
 				    (u8 *)resp, len);
@@ -1793,6 +1794,7 @@
 	struct virtchnl_fdir_add *stat = NULL;
 	struct virtchnl_fdir_fltr_conf *conf;
 	enum virtchnl_status_code v_ret;
+	struct ice_vsi *vf_vsi;
 	struct device *dev;
 	struct ice_pf *pf;
 	int is_tun = 0;
@@ -1801,6 +1803,17 @@
 
 	pf = vf->pf;
 	dev = ice_pf_to_dev(pf);
+	vf_vsi = ice_get_vf_vsi(vf);
+
+#define ICE_VF_MAX_FDIR_FILTERS	128
+	if (!ice_fdir_num_avail_fltr(&pf->hw, vf_vsi) ||
+	    vf->fdir.fdir_fltr_cnt_total >= ICE_VF_MAX_FDIR_FILTERS) {
+		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
+		dev_err(dev, "Max number of FDIR filters for VF %d is reached\n",
+			vf->vf_id);
+		goto err_exit;
+	}
+
 	ret = ice_vc_fdir_param_check(vf, fltr->vsi_id);
 	if (ret) {
 		v_ret = VIRTCHNL_STATUS_ERR_PARAM;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_virtchnl_fdir.h
@@ -29,6 +29,7 @@
 struct ice_vf_fdir {
 	u16 fdir_fltr_cnt[ICE_FLTR_PTYPE_MAX][ICE_FD_HW_SEG_MAX];
 	int prof_entry_cnt[ICE_FLTR_PTYPE_MAX][ICE_FD_HW_SEG_MAX];
+	u16 fdir_fltr_cnt_total;
 	struct ice_fd_hw_prof **fdir_prof;
 
 	struct idr fdir_rule_idr;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c
@@ -45,14 +45,15 @@
 		return -EINVAL;
 
 	err = ice_fltr_add_vlan(vsi, vlan);
-	if (err && err != -EEXIST) {
+	if (!err)
+		vsi->num_vlan++;
+	else if (err == -EEXIST)
+		err = 0;
+	else
 		dev_err(ice_pf_to_dev(vsi->back), "Failure Adding VLAN %d on VSI %i, status %d\n",
 			vlan->vid, vsi->vsi_num, err);
-		return err;
-	}
 
-	vsi->num_vlan++;
-	return 0;
+	return err;
 }
 
 /**
@@ -785,4 +786,61 @@
 
 	kfree(ctxt);
 	return err;
+}
+
+int ice_vsi_clear_port_vlan(struct ice_vsi *vsi)
+{
+	struct ice_hw *hw = &vsi->back->hw;
+	struct ice_vsi_ctx *ctxt;
+	int err;
+
+	ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
+	if (!ctxt)
+		return -ENOMEM;
+
+	ctxt->info = vsi->info;
+
+	ctxt->info.port_based_outer_vlan = 0;
+	ctxt->info.port_based_inner_vlan = 0;
+
+	ctxt->info.inner_vlan_flags =
+		FIELD_PREP(ICE_AQ_VSI_INNER_VLAN_TX_MODE_M,
+			   ICE_AQ_VSI_INNER_VLAN_TX_MODE_ALL);
+	if (ice_is_dvm_ena(hw)) {
+		ctxt->info.inner_vlan_flags |=
+			FIELD_PREP(ICE_AQ_VSI_INNER_VLAN_EMODE_M,
+				   ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING);
+		ctxt->info.outer_vlan_flags =
+			FIELD_PREP(ICE_AQ_VSI_OUTER_VLAN_TX_MODE_M,
+				   ICE_AQ_VSI_OUTER_VLAN_TX_MODE_ALL);
+		ctxt->info.outer_vlan_flags |=
+			FIELD_PREP(ICE_AQ_VSI_OUTER_TAG_TYPE_M,
+				   ICE_AQ_VSI_OUTER_TAG_VLAN_8100);
+		ctxt->info.outer_vlan_flags |=
+			ICE_AQ_VSI_OUTER_VLAN_EMODE_NOTHING <<
+			ICE_AQ_VSI_OUTER_VLAN_EMODE_S;
+	}
+
+	ctxt->info.sw_flags2 &= ~ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA;
+	ctxt->info.valid_sections =
+		cpu_to_le16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID |
+			    ICE_AQ_VSI_PROP_VLAN_VALID |
+			    ICE_AQ_VSI_PROP_SW_VALID);
+
+	err = ice_update_vsi(hw, vsi->idx, ctxt, NULL);
+	if (err) {
+		dev_err(ice_pf_to_dev(vsi->back), "update VSI for clearing port based VLAN failed, err %d aq_err %s\n",
+			err, ice_aq_str(hw->adminq.sq_last_status));
+	} else {
+		vsi->info.port_based_outer_vlan =
+			ctxt->info.port_based_outer_vlan;
+		vsi->info.port_based_inner_vlan =
+			ctxt->info.port_based_inner_vlan;
+		vsi->info.outer_vlan_flags = ctxt->info.outer_vlan_flags;
+		vsi->info.inner_vlan_flags = ctxt->info.inner_vlan_flags;
+		vsi->info.sw_flags2 = ctxt->info.sw_flags2;
+	}
+
+	kfree(ctxt);
+	return err;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.h
@@ -36,5 +36,6 @@
 int ice_vsi_dis_outer_insertion(struct ice_vsi *vsi);
 int ice_vsi_set_outer_port_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan);
 int ice_vsi_clear_outer_port_vlan(struct ice_vsi *vsi);
+int ice_vsi_clear_port_vlan(struct ice_vsi *vsi);
 
 #endif /* _ICE_VSI_VLAN_LIB_H_ */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_xsk.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_xsk.c
@@ -39,7 +39,7 @@
 	       sizeof(vsi_stat->rx_ring_stats[q_idx]->rx_stats));
 	memset(&vsi_stat->tx_ring_stats[q_idx]->stats, 0,
 	       sizeof(vsi_stat->tx_ring_stats[q_idx]->stats));
-	if (ice_is_xdp_ena_vsi(vsi))
+	if (vsi->xdp_rings)
 		memset(&vsi->xdp_rings[q_idx]->ring_stats->stats, 0,
 		       sizeof(vsi->xdp_rings[q_idx]->ring_stats->stats));
 }
@@ -52,10 +52,8 @@
 static void ice_qp_clean_rings(struct ice_vsi *vsi, u16 q_idx)
 {
 	ice_clean_tx_ring(vsi->tx_rings[q_idx]);
-	if (ice_is_xdp_ena_vsi(vsi)) {
-		synchronize_rcu();
+	if (vsi->xdp_rings)
 		ice_clean_tx_ring(vsi->xdp_rings[q_idx]);
-	}
 	ice_clean_rx_ring(vsi->rx_rings[q_idx]);
 }
 
@@ -112,25 +110,29 @@
  * ice_qvec_cfg_msix - Enable IRQ for given queue vector
  * @vsi: the VSI that contains queue vector
  * @q_vector: queue vector
+ * @qid: queue index
  */
 static void
-ice_qvec_cfg_msix(struct ice_vsi *vsi, struct ice_q_vector *q_vector)
+ice_qvec_cfg_msix(struct ice_vsi *vsi, struct ice_q_vector *q_vector, u16 qid)
 {
 	u16 reg_idx = q_vector->reg_idx;
 	struct ice_pf *pf = vsi->back;
 	struct ice_hw *hw = &pf->hw;
-	struct ice_tx_ring *tx_ring;
-	struct ice_rx_ring *rx_ring;
+	int q, _qid = qid;
 
 	ice_cfg_itr(hw, q_vector);
 
-	ice_for_each_tx_ring(tx_ring, q_vector->tx)
-		ice_cfg_txq_interrupt(vsi, tx_ring->reg_idx, reg_idx,
-				      q_vector->tx.itr_idx);
-
-	ice_for_each_rx_ring(rx_ring, q_vector->rx)
-		ice_cfg_rxq_interrupt(vsi, rx_ring->reg_idx, reg_idx,
-				      q_vector->rx.itr_idx);
+	for (q = 0; q < q_vector->num_ring_tx; q++) {
+		ice_cfg_txq_interrupt(vsi, _qid, reg_idx, q_vector->tx.itr_idx);
+		_qid++;
+	}
+
+	_qid = qid;
+
+	for (q = 0; q < q_vector->num_ring_rx; q++) {
+		ice_cfg_rxq_interrupt(vsi, _qid, reg_idx, q_vector->rx.itr_idx);
+		_qid++;
+	}
 
 	ice_flush(hw);
 }
@@ -163,7 +165,7 @@
 	struct ice_q_vector *q_vector;
 	struct ice_tx_ring *tx_ring;
 	struct ice_rx_ring *rx_ring;
-	int timeout = 50;
+	int fail = 0;
 	int err;
 
 	if (q_idx >= vsi->num_rxq || q_idx >= vsi->num_txq)
@@ -173,40 +175,33 @@
 	rx_ring = vsi->rx_rings[q_idx];
 	q_vector = rx_ring->q_vector;
 
-	while (test_and_set_bit(ICE_CFG_BUSY, vsi->state)) {
-		timeout--;
-		if (!timeout)
-			return -EBUSY;
-		usleep_range(1000, 2000);
-	}
+	synchronize_net();
+	netif_carrier_off(vsi->netdev);
+	netif_tx_stop_queue(netdev_get_tx_queue(vsi->netdev, q_idx));
 
 	ice_qvec_dis_irq(vsi, rx_ring, q_vector);
 	ice_qvec_toggle_napi(vsi, q_vector, false);
 
-	netif_tx_stop_queue(netdev_get_tx_queue(vsi->netdev, q_idx));
-
 	ice_fill_txq_meta(vsi, tx_ring, &txq_meta);
 	err = ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, 0, tx_ring, &txq_meta);
-	if (err)
-		return err;
-	if (ice_is_xdp_ena_vsi(vsi)) {
+	if (!fail)
+		fail = err;
+	if (vsi->xdp_rings) {
 		struct ice_tx_ring *xdp_ring = vsi->xdp_rings[q_idx];
 
 		memset(&txq_meta, 0, sizeof(txq_meta));
 		ice_fill_txq_meta(vsi, xdp_ring, &txq_meta);
 		err = ice_vsi_stop_tx_ring(vsi, ICE_NO_RESET, 0, xdp_ring,
 					   &txq_meta);
-		if (err)
-			return err;
+		if (!fail)
+			fail = err;
 	}
-	err = ice_vsi_ctrl_one_rx_ring(vsi, false, q_idx, true);
-	if (err)
-		return err;
 
+	ice_vsi_ctrl_one_rx_ring(vsi, false, q_idx, false);
 	ice_qp_clean_rings(vsi, q_idx);
 	ice_qp_reset_stats(vsi, q_idx);
 
-	return 0;
+	return fail;
 }
 
 /**
@@ -218,55 +213,48 @@
  */
 static int ice_qp_ena(struct ice_vsi *vsi, u16 q_idx)
 {
-	DEFINE_FLEX(struct ice_aqc_add_tx_qgrp, qg_buf, txqs, 1);
-	u16 size = __struct_size(qg_buf);
 	struct ice_q_vector *q_vector;
-	struct ice_tx_ring *tx_ring;
-	struct ice_rx_ring *rx_ring;
+	int fail = 0;
+	bool link_up;
 	int err;
 
-	if (q_idx >= vsi->num_rxq || q_idx >= vsi->num_txq)
-		return -EINVAL;
-
-	qg_buf->num_txqs = 1;
-
-	tx_ring = vsi->tx_rings[q_idx];
-	rx_ring = vsi->rx_rings[q_idx];
-	q_vector = rx_ring->q_vector;
-
-	err = ice_vsi_cfg_txq(vsi, tx_ring, qg_buf);
-	if (err)
-		return err;
+	err = ice_vsi_cfg_single_txq(vsi, vsi->tx_rings, q_idx);
+	if (!fail)
+		fail = err;
 
 	if (ice_is_xdp_ena_vsi(vsi)) {
 		struct ice_tx_ring *xdp_ring = vsi->xdp_rings[q_idx];
 
-		memset(qg_buf, 0, size);
-		qg_buf->num_txqs = 1;
-		err = ice_vsi_cfg_txq(vsi, xdp_ring, qg_buf);
-		if (err)
-			return err;
+		err = ice_vsi_cfg_single_txq(vsi, vsi->xdp_rings, q_idx);
+		if (!fail)
+			fail = err;
 		ice_set_ring_xdp(xdp_ring);
 		ice_tx_xsk_pool(vsi, q_idx);
 	}
 
-	err = ice_vsi_cfg_rxq(rx_ring);
-	if (err)
-		return err;
+	err = ice_vsi_cfg_single_rxq(vsi, q_idx);
+	if (!fail)
+		fail = err;
 
-	ice_qvec_cfg_msix(vsi, q_vector);
+	q_vector = vsi->rx_rings[q_idx]->q_vector;
+	ice_qvec_cfg_msix(vsi, q_vector, q_idx);
 
 	err = ice_vsi_ctrl_one_rx_ring(vsi, true, q_idx, true);
-	if (err)
-		return err;
+	if (!fail)
+		fail = err;
 
 	ice_qvec_toggle_napi(vsi, q_vector, true);
 	ice_qvec_ena_irq(vsi, q_vector);
 
-	netif_tx_start_queue(netdev_get_tx_queue(vsi->netdev, q_idx));
-	clear_bit(ICE_CFG_BUSY, vsi->state);
+	/* make sure NAPI sees updated ice_{t,x}_ring::xsk_pool */
+	synchronize_net();
+	ice_get_link_status(vsi->port_info, &link_up);
+	if (link_up) {
+		netif_tx_start_queue(netdev_get_tx_queue(vsi->netdev, q_idx));
+		netif_carrier_on(vsi->netdev);
+	}
 
-	return 0;
+	return fail;
 }
 
 /**
@@ -283,7 +271,6 @@
 	if (!pool)
 		return -EINVAL;
 
-	clear_bit(qid, vsi->af_xdp_zc_qps);
 	xsk_pool_dma_unmap(pool, ICE_RX_DMA_ATTR);
 
 	return 0;
@@ -314,8 +301,6 @@
 	if (err)
 		return err;
 
-	set_bit(qid, vsi->af_xdp_zc_qps);
-
 	return 0;
 }
 
@@ -363,11 +348,13 @@
 int ice_realloc_zc_buf(struct ice_vsi *vsi, bool zc)
 {
 	struct ice_rx_ring *rx_ring;
-	unsigned long q;
+	uint i;
+
+	ice_for_each_rxq(vsi, i) {
+		rx_ring = vsi->rx_rings[i];
+		if (!rx_ring->xsk_pool)
+			continue;
 
-	for_each_set_bit(q, vsi->af_xdp_zc_qps,
-			 max_t(int, vsi->alloc_txq, vsi->alloc_rxq)) {
-		rx_ring = vsi->rx_rings[q];
 		if (ice_realloc_rx_xdp_bufs(rx_ring, zc))
 			return -ENOMEM;
 	}
@@ -394,7 +381,8 @@
 		goto failure;
 	}
 
-	if_running = netif_running(vsi->netdev) && ice_is_xdp_ena_vsi(vsi);
+	if_running = !test_bit(ICE_VSI_DOWN, vsi->state) &&
+		     ice_is_xdp_ena_vsi(vsi);
 
 	if (if_running) {
 		struct ice_rx_ring *rx_ring = vsi->rx_rings[qid];
@@ -474,6 +462,7 @@
 /**
  * __ice_alloc_rx_bufs_zc - allocate a number of Rx buffers
  * @rx_ring: Rx ring
+ * @xsk_pool: XSK buffer pool to pick buffers to be filled by HW
  * @count: The number of buffers to allocate
  *
  * Place the @count of descriptors onto Rx ring. Handle the ring wrap
@@ -482,7 +471,8 @@
  *
  * Returns true if all allocations were successful, false if any fail.
  */
-static bool __ice_alloc_rx_bufs_zc(struct ice_rx_ring *rx_ring, u16 count)
+static bool __ice_alloc_rx_bufs_zc(struct ice_rx_ring *rx_ring,
+				   struct xsk_buff_pool *xsk_pool, u16 count)
 {
 	u32 nb_buffs_extra = 0, nb_buffs = 0;
 	union ice_32b_rx_flex_desc *rx_desc;
@@ -494,8 +484,7 @@
 	xdp = ice_xdp_buf(rx_ring, ntu);
 
 	if (ntu + count >= rx_ring->count) {
-		nb_buffs_extra = ice_fill_rx_descs(rx_ring->xsk_pool, xdp,
-						   rx_desc,
+		nb_buffs_extra = ice_fill_rx_descs(xsk_pool, xdp, rx_desc,
 						   rx_ring->count - ntu);
 		if (nb_buffs_extra != rx_ring->count - ntu) {
 			ntu += nb_buffs_extra;
@@ -508,7 +497,7 @@
 		ice_release_rx_desc(rx_ring, 0);
 	}
 
-	nb_buffs = ice_fill_rx_descs(rx_ring->xsk_pool, xdp, rx_desc, count);
+	nb_buffs = ice_fill_rx_descs(xsk_pool, xdp, rx_desc, count);
 
 	ntu += nb_buffs;
 	if (ntu == rx_ring->count)
@@ -524,6 +513,7 @@
 /**
  * ice_alloc_rx_bufs_zc - allocate a number of Rx buffers
  * @rx_ring: Rx ring
+ * @xsk_pool: XSK buffer pool to pick buffers to be filled by HW
  * @count: The number of buffers to allocate
  *
  * Wrapper for internal allocation routine; figure out how many tail
@@ -531,7 +521,8 @@
  *
  * Returns true if all calls to internal alloc routine succeeded
  */
-bool ice_alloc_rx_bufs_zc(struct ice_rx_ring *rx_ring, u16 count)
+bool ice_alloc_rx_bufs_zc(struct ice_rx_ring *rx_ring,
+			  struct xsk_buff_pool *xsk_pool, u16 count)
 {
 	u16 rx_thresh = ICE_RING_QUARTER(rx_ring);
 	u16 leftover, i, tail_bumps;
@@ -540,9 +531,9 @@
 	leftover = count - (tail_bumps * rx_thresh);
 
 	for (i = 0; i < tail_bumps; i++)
-		if (!__ice_alloc_rx_bufs_zc(rx_ring, rx_thresh))
+		if (!__ice_alloc_rx_bufs_zc(rx_ring, xsk_pool, rx_thresh))
 			return false;
-	return __ice_alloc_rx_bufs_zc(rx_ring, leftover);
+	return __ice_alloc_rx_bufs_zc(rx_ring, xsk_pool, leftover);
 }
 
 /**
@@ -612,8 +603,10 @@
 /**
  * ice_clean_xdp_irq_zc - produce AF_XDP descriptors to CQ
  * @xdp_ring: XDP Tx ring
+ * @xsk_pool: AF_XDP buffer pool pointer
  */
-static u32 ice_clean_xdp_irq_zc(struct ice_tx_ring *xdp_ring)
+static u32 ice_clean_xdp_irq_zc(struct ice_tx_ring *xdp_ring,
+				struct xsk_buff_pool *xsk_pool)
 {
 	u16 ntc = xdp_ring->next_to_clean;
 	struct ice_tx_desc *tx_desc;
@@ -664,7 +657,7 @@
 	if (xdp_ring->next_to_clean >= cnt)
 		xdp_ring->next_to_clean -= cnt;
 	if (xsk_frames)
-		xsk_tx_completed(xdp_ring->xsk_pool, xsk_frames);
+		xsk_tx_completed(xsk_pool, xsk_frames);
 
 	return completed_frames;
 }
@@ -673,6 +666,7 @@
  * ice_xmit_xdp_tx_zc - AF_XDP ZC handler for XDP_TX
  * @xdp: XDP buffer to xmit
  * @xdp_ring: XDP ring to produce descriptor onto
+ * @xsk_pool: AF_XDP buffer pool pointer
  *
  * note that this function works directly on xdp_buff, no need to convert
  * it to xdp_frame. xdp_buff pointer is stored to ice_tx_buf so that cleaning
@@ -682,7 +676,8 @@
  * was not enough space on XDP ring
  */
 static int ice_xmit_xdp_tx_zc(struct xdp_buff *xdp,
-			      struct ice_tx_ring *xdp_ring)
+			      struct ice_tx_ring *xdp_ring,
+			      struct xsk_buff_pool *xsk_pool)
 {
 	struct skb_shared_info *sinfo = NULL;
 	u32 size = xdp->data_end - xdp->data;
@@ -696,7 +691,7 @@
 
 	free_space = ICE_DESC_UNUSED(xdp_ring);
 	if (free_space < ICE_RING_QUARTER(xdp_ring))
-		free_space += ice_clean_xdp_irq_zc(xdp_ring);
+		free_space += ice_clean_xdp_irq_zc(xdp_ring, xsk_pool);
 
 	if (unlikely(!free_space))
 		goto busy;
@@ -716,7 +711,7 @@
 		dma_addr_t dma;
 
 		dma = xsk_buff_xdp_get_dma(xdp);
-		xsk_buff_raw_dma_sync_for_device(xdp_ring->xsk_pool, dma, size);
+		xsk_buff_raw_dma_sync_for_device(xsk_pool, dma, size);
 
 		tx_buf->xdp = xdp;
 		tx_buf->type = ICE_TX_BUF_XSK_TX;
@@ -758,12 +753,14 @@
  * @xdp: xdp_buff used as input to the XDP program
  * @xdp_prog: XDP program to run
  * @xdp_ring: ring to be used for XDP_TX action
+ * @xsk_pool: AF_XDP buffer pool pointer
  *
  * Returns any of ICE_XDP_{PASS, CONSUMED, TX, REDIR}
  */
 static int
 ice_run_xdp_zc(struct ice_rx_ring *rx_ring, struct xdp_buff *xdp,
-	       struct bpf_prog *xdp_prog, struct ice_tx_ring *xdp_ring)
+	       struct bpf_prog *xdp_prog, struct ice_tx_ring *xdp_ring,
+	       struct xsk_buff_pool *xsk_pool)
 {
 	int err, result = ICE_XDP_PASS;
 	u32 act;
@@ -774,7 +771,7 @@
 		err = xdp_do_redirect(rx_ring->netdev, xdp, xdp_prog);
 		if (!err)
 			return ICE_XDP_REDIR;
-		if (xsk_uses_need_wakeup(rx_ring->xsk_pool) && err == -ENOBUFS)
+		if (xsk_uses_need_wakeup(xsk_pool) && err == -ENOBUFS)
 			result = ICE_XDP_EXIT;
 		else
 			result = ICE_XDP_CONSUMED;
@@ -785,7 +782,7 @@
 	case XDP_PASS:
 		break;
 	case XDP_TX:
-		result = ice_xmit_xdp_tx_zc(xdp, xdp_ring);
+		result = ice_xmit_xdp_tx_zc(xdp, xdp_ring, xsk_pool);
 		if (result == ICE_XDP_CONSUMED)
 			goto out_failure;
 		break;
@@ -837,14 +834,16 @@
 /**
  * ice_clean_rx_irq_zc - consumes packets from the hardware ring
  * @rx_ring: AF_XDP Rx ring
+ * @xsk_pool: AF_XDP buffer pool pointer
  * @budget: NAPI budget
  *
  * Returns number of processed packets on success, remaining budget on failure.
  */
-int ice_clean_rx_irq_zc(struct ice_rx_ring *rx_ring, int budget)
+int ice_clean_rx_irq_zc(struct ice_rx_ring *rx_ring,
+			struct xsk_buff_pool *xsk_pool,
+			int budget)
 {
 	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
-	struct xsk_buff_pool *xsk_pool = rx_ring->xsk_pool;
 	u32 ntc = rx_ring->next_to_clean;
 	u32 ntu = rx_ring->next_to_use;
 	struct xdp_buff *first = NULL;
@@ -907,7 +906,8 @@
 		if (ice_is_non_eop(rx_ring, rx_desc))
 			continue;
 
-		xdp_res = ice_run_xdp_zc(rx_ring, first, xdp_prog, xdp_ring);
+		xdp_res = ice_run_xdp_zc(rx_ring, first, xdp_prog, xdp_ring,
+					 xsk_pool);
 		if (likely(xdp_res & (ICE_XDP_TX | ICE_XDP_REDIR))) {
 			xdp_xmit |= xdp_res;
 		} else if (xdp_res == ICE_XDP_EXIT) {
@@ -956,7 +956,8 @@
 	rx_ring->next_to_clean = ntc;
 	entries_to_alloc = ICE_RX_DESC_UNUSED(rx_ring);
 	if (entries_to_alloc > ICE_RING_QUARTER(rx_ring))
-		failure |= !ice_alloc_rx_bufs_zc(rx_ring, entries_to_alloc);
+		failure |= !ice_alloc_rx_bufs_zc(rx_ring, xsk_pool,
+						 entries_to_alloc);
 
 	ice_finalize_xdp_rx(xdp_ring, xdp_xmit, 0);
 	ice_update_rx_ring_stats(rx_ring, total_rx_packets, total_rx_bytes);
@@ -979,17 +980,19 @@
 /**
  * ice_xmit_pkt - produce a single HW Tx descriptor out of AF_XDP descriptor
  * @xdp_ring: XDP ring to produce the HW Tx descriptor on
+ * @xsk_pool: XSK buffer pool to pick buffers to be consumed by HW
  * @desc: AF_XDP descriptor to pull the DMA address and length from
  * @total_bytes: bytes accumulator that will be used for stats update
  */
-static void ice_xmit_pkt(struct ice_tx_ring *xdp_ring, struct xdp_desc *desc,
+static void ice_xmit_pkt(struct ice_tx_ring *xdp_ring,
+			 struct xsk_buff_pool *xsk_pool, struct xdp_desc *desc,
 			 unsigned int *total_bytes)
 {
 	struct ice_tx_desc *tx_desc;
 	dma_addr_t dma;
 
-	dma = xsk_buff_raw_get_dma(xdp_ring->xsk_pool, desc->addr);
-	xsk_buff_raw_dma_sync_for_device(xdp_ring->xsk_pool, dma, desc->len);
+	dma = xsk_buff_raw_get_dma(xsk_pool, desc->addr);
+	xsk_buff_raw_dma_sync_for_device(xsk_pool, dma, desc->len);
 
 	tx_desc = ICE_TX_DESC(xdp_ring, xdp_ring->next_to_use++);
 	tx_desc->buf_addr = cpu_to_le64(dma);
@@ -1002,10 +1005,13 @@
 /**
  * ice_xmit_pkt_batch - produce a batch of HW Tx descriptors out of AF_XDP descriptors
  * @xdp_ring: XDP ring to produce the HW Tx descriptors on
+ * @xsk_pool: XSK buffer pool to pick buffers to be consumed by HW
  * @descs: AF_XDP descriptors to pull the DMA addresses and lengths from
  * @total_bytes: bytes accumulator that will be used for stats update
  */
-static void ice_xmit_pkt_batch(struct ice_tx_ring *xdp_ring, struct xdp_desc *descs,
+static void ice_xmit_pkt_batch(struct ice_tx_ring *xdp_ring,
+			       struct xsk_buff_pool *xsk_pool,
+			       struct xdp_desc *descs,
 			       unsigned int *total_bytes)
 {
 	u16 ntu = xdp_ring->next_to_use;
@@ -1015,8 +1021,8 @@
 	loop_unrolled_for(i = 0; i < PKTS_PER_BATCH; i++) {
 		dma_addr_t dma;
 
-		dma = xsk_buff_raw_get_dma(xdp_ring->xsk_pool, descs[i].addr);
-		xsk_buff_raw_dma_sync_for_device(xdp_ring->xsk_pool, dma, descs[i].len);
+		dma = xsk_buff_raw_get_dma(xsk_pool, descs[i].addr);
+		xsk_buff_raw_dma_sync_for_device(xsk_pool, dma, descs[i].len);
 
 		tx_desc = ICE_TX_DESC(xdp_ring, ntu++);
 		tx_desc->buf_addr = cpu_to_le64(dma);
@@ -1032,60 +1038,69 @@
 /**
  * ice_fill_tx_hw_ring - produce the number of Tx descriptors onto ring
  * @xdp_ring: XDP ring to produce the HW Tx descriptors on
+ * @xsk_pool: XSK buffer pool to pick buffers to be consumed by HW
  * @descs: AF_XDP descriptors to pull the DMA addresses and lengths from
  * @nb_pkts: count of packets to be send
  * @total_bytes: bytes accumulator that will be used for stats update
  */
-static void ice_fill_tx_hw_ring(struct ice_tx_ring *xdp_ring, struct xdp_desc *descs,
-				u32 nb_pkts, unsigned int *total_bytes)
+static void ice_fill_tx_hw_ring(struct ice_tx_ring *xdp_ring,
+				struct xsk_buff_pool *xsk_pool,
+				struct xdp_desc *descs, u32 nb_pkts,
+				unsigned int *total_bytes)
 {
 	u32 batched, leftover, i;
 
 	batched = ALIGN_DOWN(nb_pkts, PKTS_PER_BATCH);
 	leftover = nb_pkts & (PKTS_PER_BATCH - 1);
 	for (i = 0; i < batched; i += PKTS_PER_BATCH)
-		ice_xmit_pkt_batch(xdp_ring, &descs[i], total_bytes);
+		ice_xmit_pkt_batch(xdp_ring, xsk_pool, &descs[i], total_bytes);
 	for (; i < batched + leftover; i++)
-		ice_xmit_pkt(xdp_ring, &descs[i], total_bytes);
+		ice_xmit_pkt(xdp_ring, xsk_pool, &descs[i], total_bytes);
 }
 
 /**
  * ice_xmit_zc - take entries from XSK Tx ring and place them onto HW Tx ring
  * @xdp_ring: XDP ring to produce the HW Tx descriptors on
+ * @xsk_pool: AF_XDP buffer pool pointer
  *
  * Returns true if there is no more work that needs to be done, false otherwise
  */
-bool ice_xmit_zc(struct ice_tx_ring *xdp_ring)
+bool ice_xmit_zc(struct ice_tx_ring *xdp_ring, struct xsk_buff_pool *xsk_pool)
 {
-	struct xdp_desc *descs = xdp_ring->xsk_pool->tx_descs;
+	struct xdp_desc *descs = xsk_pool->tx_descs;
 	u32 nb_pkts, nb_processed = 0;
 	unsigned int total_bytes = 0;
 	int budget;
 
-	ice_clean_xdp_irq_zc(xdp_ring);
+	ice_clean_xdp_irq_zc(xdp_ring, xsk_pool);
+
+	if (!netif_carrier_ok(xdp_ring->vsi->netdev) ||
+	    !netif_running(xdp_ring->vsi->netdev))
+		return true;
 
 	budget = ICE_DESC_UNUSED(xdp_ring);
 	budget = min_t(u16, budget, ICE_RING_QUARTER(xdp_ring));
 
-	nb_pkts = xsk_tx_peek_release_desc_batch(xdp_ring->xsk_pool, budget);
+	nb_pkts = xsk_tx_peek_release_desc_batch(xsk_pool, budget);
 	if (!nb_pkts)
 		return true;
 
 	if (xdp_ring->next_to_use + nb_pkts >= xdp_ring->count) {
 		nb_processed = xdp_ring->count - xdp_ring->next_to_use;
-		ice_fill_tx_hw_ring(xdp_ring, descs, nb_processed, &total_bytes);
+		ice_fill_tx_hw_ring(xdp_ring, xsk_pool, descs, nb_processed,
+				    &total_bytes);
 		xdp_ring->next_to_use = 0;
 	}
 
-	ice_fill_tx_hw_ring(xdp_ring, &descs[nb_processed], nb_pkts - nb_processed,
-			    &total_bytes);
+	ice_fill_tx_hw_ring(xdp_ring, xsk_pool, &descs[nb_processed],
+			    nb_pkts - nb_processed, &total_bytes);
 
 	ice_set_rs_bit(xdp_ring);
 	ice_xdp_ring_update_tail(xdp_ring);
 	ice_update_tx_ring_stats(xdp_ring, nb_pkts, total_bytes);
 
-	if (xsk_uses_need_wakeup(xdp_ring->xsk_pool))
-		xsk_set_tx_need_wakeup(xdp_ring->xsk_pool);
+	if (xsk_uses_need_wakeup(xsk_pool))
+		xsk_set_tx_need_wakeup(xsk_pool);
 
 	return nb_pkts < budget;
 }
@@ -1107,7 +1122,7 @@
 	struct ice_vsi *vsi = np->vsi;
 	struct ice_tx_ring *ring;
 
-	if (test_bit(ICE_VSI_DOWN, vsi->state))
+	if (test_bit(ICE_VSI_DOWN, vsi->state) || !netif_carrier_ok(netdev))
 		return -ENETDOWN;
 
 	if (!ice_is_xdp_ena_vsi(vsi))
@@ -1118,7 +1133,7 @@
 
 	ring = vsi->rx_rings[queue_id]->xdp_ring;
 
-	if (!ring->xsk_pool)
+	if (!READ_ONCE(ring->xsk_pool))
 		return -EINVAL;
 
 	/* The idea here is that if NAPI is running, mark a miss, so
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ice/ice_xsk.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ice/ice_xsk.h
@@ -20,16 +20,20 @@
 #ifdef CONFIG_XDP_SOCKETS
 int ice_xsk_pool_setup(struct ice_vsi *vsi, struct xsk_buff_pool *pool,
 		       u16 qid);
-int ice_clean_rx_irq_zc(struct ice_rx_ring *rx_ring, int budget);
+int ice_clean_rx_irq_zc(struct ice_rx_ring *rx_ring,
+			struct xsk_buff_pool *xsk_pool,
+			int budget);
 int ice_xsk_wakeup(struct net_device *netdev, u32 queue_id, u32 flags);
-bool ice_alloc_rx_bufs_zc(struct ice_rx_ring *rx_ring, u16 count);
+bool ice_alloc_rx_bufs_zc(struct ice_rx_ring *rx_ring,
+			  struct xsk_buff_pool *xsk_pool, u16 count);
 bool ice_xsk_any_rx_ring_ena(struct ice_vsi *vsi);
 void ice_xsk_clean_rx_ring(struct ice_rx_ring *rx_ring);
 void ice_xsk_clean_xdp_ring(struct ice_tx_ring *xdp_ring);
-bool ice_xmit_zc(struct ice_tx_ring *xdp_ring);
+bool ice_xmit_zc(struct ice_tx_ring *xdp_ring, struct xsk_buff_pool *xsk_pool);
 int ice_realloc_zc_buf(struct ice_vsi *vsi, bool zc);
 #else
-static inline bool ice_xmit_zc(struct ice_tx_ring __always_unused *xdp_ring)
+static inline bool ice_xmit_zc(struct ice_tx_ring __always_unused *xdp_ring,
+			       struct xsk_buff_pool __always_unused *xsk_pool)
 {
 	return false;
 }
@@ -44,6 +48,7 @@
 
 static inline int
 ice_clean_rx_irq_zc(struct ice_rx_ring __always_unused *rx_ring,
+		    struct xsk_buff_pool __always_unused *xsk_pool,
 		    int __always_unused budget)
 {
 	return 0;
@@ -51,6 +56,7 @@
 
 static inline bool
 ice_alloc_rx_bufs_zc(struct ice_rx_ring __always_unused *rx_ring,
+		     struct xsk_buff_pool __always_unused *xsk_pool,
 		     u16 __always_unused count)
 {
 	return false;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/idpf/idpf.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/idpf/idpf.h
@@ -20,7 +20,6 @@
 #include <linux/dim.h>
 
 #include "virtchnl2.h"
-#include "idpf_lan_txrx.h"
 #include "idpf_txrx.h"
 #include "idpf_controlq.h"
 
@@ -145,6 +144,7 @@
  * @adapter: Adapter back pointer
  * @vport: Vport back pointer
  * @vport_id: Vport identifier
+ * @link_speed_mbps: Link speed in mbps
  * @vport_idx: Relative vport index
  * @state: See enum idpf_vport_state
  * @netstats: Packet and byte stats
@@ -154,6 +154,7 @@
 	struct idpf_adapter *adapter;
 	struct idpf_vport *vport;
 	u32 vport_id;
+	u32 link_speed_mbps;
 	u16 vport_idx;
 	enum idpf_vport_state state;
 	struct rtnl_link_stats64 netstats;
@@ -357,7 +358,6 @@
  * @tx_itr_profile: TX profiles for Dynamic Interrupt Moderation
  * @port_stats: per port csum, header split, and other offload stats
  * @link_up: True if link is up
- * @link_speed_mbps: Link speed in mbps
  * @vc_msg: Virtchnl message buffer
  * @vc_state: Virtchnl message state
  * @vchnl_wq: Wait queue for virtchnl messages
@@ -406,7 +406,6 @@
 	struct idpf_port_stats port_stats;
 
 	bool link_up;
-	u32 link_speed_mbps;
 
 	char vc_msg[IDPF_CTLQ_MAX_BUF_LEN];
 	DECLARE_BITMAP(vc_state, IDPF_VC_NBITS);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/idpf/idpf_controlq.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/idpf/idpf_controlq.c
@@ -376,6 +376,9 @@
 		if (!(le16_to_cpu(desc->flags) & IDPF_CTLQ_FLAG_DD))
 			break;
 
+		/* Ensure no other fields are read until DD flag is checked */
+		dma_rmb();
+
 		/* strip off FW internal code */
 		desc_err = le16_to_cpu(desc->ret_val) & 0xff;
 
@@ -566,6 +569,9 @@
 		if (!(flags & IDPF_CTLQ_FLAG_DD))
 			break;
 
+		/* Ensure no other fields are read until DD flag is checked */
+		dma_rmb();
+
 		q_msg[i].vmvf_type = (flags &
 				      (IDPF_CTLQ_FLAG_FTYPE_VM |
 				       IDPF_CTLQ_FLAG_FTYPE_PF)) >>
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
@@ -222,14 +222,19 @@
 			     struct ethtool_channels *ch)
 {
 	struct idpf_vport_config *vport_config;
-	u16 combined, num_txq, num_rxq;
 	unsigned int num_req_tx_q;
 	unsigned int num_req_rx_q;
 	struct idpf_vport *vport;
+	u16 num_txq, num_rxq;
 	struct device *dev;
 	int err = 0;
 	u16 idx;
 
+	if (ch->rx_count && ch->tx_count) {
+		netdev_err(netdev, "Dedicated RX or TX channels cannot be used simultaneously\n");
+		return -EINVAL;
+	}
+
 	idpf_vport_ctrl_lock(netdev);
 	vport = idpf_netdev_to_vport(netdev);
 
@@ -239,20 +244,6 @@
 	num_txq = vport_config->user_config.num_req_tx_qs;
 	num_rxq = vport_config->user_config.num_req_rx_qs;
 
-	combined = min(num_txq, num_rxq);
-
-	/* these checks are for cases where user didn't specify a particular
-	 * value on cmd line but we get non-zero value anyway via
-	 * get_channels(); look at ethtool.c in ethtool repository (the user
-	 * space part), particularly, do_schannels() routine
-	 */
-	if (ch->combined_count == combined)
-		ch->combined_count = 0;
-	if (ch->combined_count && ch->rx_count == num_rxq - combined)
-		ch->rx_count = 0;
-	if (ch->combined_count && ch->tx_count == num_txq - combined)
-		ch->tx_count = 0;
-
 	num_req_tx_q = ch->combined_count + ch->tx_count;
 	num_req_rx_q = ch->combined_count + ch->rx_count;
 
@@ -376,7 +367,8 @@
 			    new_tx_count);
 
 	if (new_tx_count == vport->txq_desc_count &&
-	    new_rx_count == vport->rxq_desc_count)
+	    new_rx_count == vport->rxq_desc_count &&
+	    kring->tcp_data_split == idpf_vport_get_hsplit(vport))
 		goto unlock_mutex;
 
 	if (!idpf_vport_set_hsplit(vport, kring->tcp_data_split)) {
@@ -1318,24 +1310,19 @@
 static int idpf_get_link_ksettings(struct net_device *netdev,
 				   struct ethtool_link_ksettings *cmd)
 {
-	struct idpf_vport *vport;
-
-	idpf_vport_ctrl_lock(netdev);
-	vport = idpf_netdev_to_vport(netdev);
+	struct idpf_netdev_priv *np = netdev_priv(netdev);
 
 	ethtool_link_ksettings_zero_link_mode(cmd, supported);
 	cmd->base.autoneg = AUTONEG_DISABLE;
 	cmd->base.port = PORT_NONE;
-	if (vport->link_up) {
+	if (netif_carrier_ok(netdev)) {
 		cmd->base.duplex = DUPLEX_FULL;
-		cmd->base.speed = vport->link_speed_mbps;
+		cmd->base.speed = np->link_speed_mbps;
 	} else {
 		cmd->base.duplex = DUPLEX_UNKNOWN;
 		cmd->base.speed = SPEED_UNKNOWN;
 	}
 
-	idpf_vport_ctrl_unlock(netdev);
-
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/idpf/idpf_lan_txrx.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/idpf/idpf_lan_txrx.h
@@ -4,6 +4,8 @@
 #ifndef _IDPF_LAN_TXRX_H_
 #define _IDPF_LAN_TXRX_H_
 
+#include <linux/bits.h>
+
 enum idpf_rss_hash {
 	IDPF_HASH_INVALID			= 0,
 	/* Values 1 - 28 are reserved for future use */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/idpf/idpf_lib.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/idpf/idpf_lib.c
@@ -1419,6 +1419,7 @@
 	}
 
 	idpf_rx_init_buf_tail(vport);
+	idpf_vport_intr_ena(vport);
 
 	err = idpf_send_config_queues_msg(vport);
 	if (err) {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/idpf/idpf_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/idpf/idpf_main.c
@@ -169,7 +169,8 @@
 	pci_set_master(pdev);
 	pci_set_drvdata(pdev, adapter);
 
-	adapter->init_wq = alloc_workqueue("%s-%s-init", 0, 0,
+	adapter->init_wq = alloc_workqueue("%s-%s-init",
+					   WQ_UNBOUND | WQ_MEM_RECLAIM, 0,
 					   dev_driver_string(dev),
 					   dev_name(dev));
 	if (!adapter->init_wq) {
@@ -178,7 +179,8 @@
 		goto err_free;
 	}
 
-	adapter->serv_wq = alloc_workqueue("%s-%s-service", 0, 0,
+	adapter->serv_wq = alloc_workqueue("%s-%s-service",
+					   WQ_UNBOUND | WQ_MEM_RECLAIM, 0,
 					   dev_driver_string(dev),
 					   dev_name(dev));
 	if (!adapter->serv_wq) {
@@ -187,7 +189,8 @@
 		goto err_serv_wq_alloc;
 	}
 
-	adapter->mbx_wq = alloc_workqueue("%s-%s-mbx", 0, 0,
+	adapter->mbx_wq = alloc_workqueue("%s-%s-mbx",
+					  WQ_UNBOUND | WQ_MEM_RECLAIM, 0,
 					  dev_driver_string(dev),
 					  dev_name(dev));
 	if (!adapter->mbx_wq) {
@@ -196,7 +199,8 @@
 		goto err_mbx_wq_alloc;
 	}
 
-	adapter->stats_wq = alloc_workqueue("%s-%s-stats", 0, 0,
+	adapter->stats_wq = alloc_workqueue("%s-%s-stats",
+					    WQ_UNBOUND | WQ_MEM_RECLAIM, 0,
 					    dev_driver_string(dev),
 					    dev_name(dev));
 	if (!adapter->stats_wq) {
@@ -205,7 +209,8 @@
 		goto err_stats_wq_alloc;
 	}
 
-	adapter->vc_event_wq = alloc_workqueue("%s-%s-vc_event", 0, 0,
+	adapter->vc_event_wq = alloc_workqueue("%s-%s-vc_event",
+					       WQ_UNBOUND | WQ_MEM_RECLAIM, 0,
 					       dev_driver_string(dev),
 					       dev_name(dev));
 	if (!adapter->vc_event_wq) {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c
@@ -205,7 +205,7 @@
 	data_len = skb->data_len;
 	size = skb_headlen(skb);
 
-	tx_desc = IDPF_BASE_TX_DESC(tx_q, i);
+	tx_desc = &tx_q->base_tx[i];
 
 	dma = dma_map_single(tx_q->dev, skb->data, size, DMA_TO_DEVICE);
 
@@ -239,7 +239,7 @@
 			i++;
 
 			if (i == tx_q->desc_count) {
-				tx_desc = IDPF_BASE_TX_DESC(tx_q, 0);
+				tx_desc = &tx_q->base_tx[0];
 				i = 0;
 			}
 
@@ -259,7 +259,7 @@
 		i++;
 
 		if (i == tx_q->desc_count) {
-			tx_desc = IDPF_BASE_TX_DESC(tx_q, 0);
+			tx_desc = &tx_q->base_tx[0];
 			i = 0;
 		}
 
@@ -307,7 +307,7 @@
 	memset(&txq->tx_buf[ntu], 0, sizeof(struct idpf_tx_buf));
 	txq->tx_buf[ntu].ctx_entry = true;
 
-	ctx_desc = IDPF_BASE_TX_CTX_DESC(txq, ntu);
+	ctx_desc = &txq->base_ctx[ntu];
 
 	IDPF_SINGLEQ_BUMP_RING_IDX(txq, ntu);
 	txq->next_to_use = ntu;
@@ -455,7 +455,7 @@
 	struct netdev_queue *nq;
 	bool dont_wake;
 
-	tx_desc = IDPF_BASE_TX_DESC(tx_q, ntc);
+	tx_desc = &tx_q->base_tx[ntc];
 	tx_buf = &tx_q->tx_buf[ntc];
 	ntc -= tx_q->desc_count;
 
@@ -517,7 +517,7 @@
 			if (unlikely(!ntc)) {
 				ntc -= tx_q->desc_count;
 				tx_buf = tx_q->tx_buf;
-				tx_desc = IDPF_BASE_TX_DESC(tx_q, 0);
+				tx_desc = &tx_q->base_tx[0];
 			}
 
 			/* unmap any remaining paged data */
@@ -540,7 +540,7 @@
 		if (unlikely(!ntc)) {
 			ntc -= tx_q->desc_count;
 			tx_buf = tx_q->tx_buf;
-			tx_desc = IDPF_BASE_TX_DESC(tx_q, 0);
+			tx_desc = &tx_q->base_tx[0];
 		}
 	} while (likely(budget));
 
@@ -895,7 +895,7 @@
 	if (!cleaned_count)
 		return false;
 
-	desc = IDPF_SINGLEQ_RX_BUF_DESC(rx_q, nta);
+	desc = &rx_q->single_buf[nta];
 	buf = &rx_q->rx_buf.buf[nta];
 
 	do {
@@ -915,7 +915,7 @@
 		buf++;
 		nta++;
 		if (unlikely(nta == rx_q->desc_count)) {
-			desc = IDPF_SINGLEQ_RX_BUF_DESC(rx_q, 0);
+			desc = &rx_q->single_buf[0];
 			buf = rx_q->rx_buf.buf;
 			nta = 0;
 		}
@@ -1016,7 +1016,7 @@
 		struct idpf_rx_buf *rx_buf;
 
 		/* get the Rx desc from Rx queue based on 'next_to_clean' */
-		rx_desc = IDPF_RX_DESC(rx_q, ntc);
+		rx_desc = &rx_q->rx[ntc];
 
 		/* status_error_ptype_len will always be zero for unused
 		 * descriptors because it's cleared in cleanup, and overlaps
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/idpf/idpf_txrx.c
@@ -530,7 +530,7 @@
 	struct idpf_rx_buf *buf;
 	dma_addr_t addr;
 
-	splitq_rx_desc = IDPF_SPLITQ_RX_BUF_DESC(bufq, nta);
+	splitq_rx_desc = &bufq->split_buf[nta];
 	buf = &bufq->rx_buf.buf[buf_id];
 
 	if (bufq->rx_hsplit_en) {
@@ -1583,7 +1583,7 @@
 	if (unlikely(!(ntc))) {					\
 		ntc -= (txq)->desc_count;			\
 		buf = (txq)->tx_buf;				\
-		desc = IDPF_FLEX_TX_DESC(txq, 0);		\
+		desc = &(txq)->flex_tx[0];			\
 	} else {						\
 		(buf)++;					\
 		(desc)++;					\
@@ -1616,8 +1616,8 @@
 	s16 ntc = tx_q->next_to_clean;
 	struct idpf_tx_buf *tx_buf;
 
-	tx_desc = IDPF_FLEX_TX_DESC(tx_q, ntc);
-	next_pending_desc = IDPF_FLEX_TX_DESC(tx_q, end);
+	tx_desc = &tx_q->flex_tx[ntc];
+	next_pending_desc = &tx_q->flex_tx[end];
 	tx_buf = &tx_q->tx_buf[ntc];
 	ntc -= tx_q->desc_count;
 
@@ -1813,7 +1813,7 @@
 	int i;
 
 	complq_budget = vport->compln_clean_budget;
-	tx_desc = IDPF_SPLITQ_TX_COMPLQ_DESC(complq, ntc);
+	tx_desc = &complq->comp[ntc];
 	ntc -= complq->desc_count;
 
 	do {
@@ -1878,7 +1878,7 @@
 		ntc++;
 		if (unlikely(!ntc)) {
 			ntc -= complq->desc_count;
-			tx_desc = IDPF_SPLITQ_TX_COMPLQ_DESC(complq, 0);
+			tx_desc = &complq->comp[0];
 			change_bit(__IDPF_Q_GEN_CHK, complq->flags);
 		}
 
@@ -2142,7 +2142,7 @@
 		 * used one additional descriptor for a context
 		 * descriptor. Reset that here.
 		 */
-		tx_desc = IDPF_FLEX_TX_DESC(txq, idx);
+		tx_desc = &txq->flex_tx[idx];
 		memset(tx_desc, 0, sizeof(struct idpf_flex_tx_ctx_desc));
 		if (idx == 0)
 			idx = txq->desc_count;
@@ -2201,7 +2201,7 @@
 	data_len = skb->data_len;
 	size = skb_headlen(skb);
 
-	tx_desc = IDPF_FLEX_TX_DESC(tx_q, i);
+	tx_desc = &tx_q->flex_tx[i];
 
 	dma = dma_map_single(tx_q->dev, skb->data, size, DMA_TO_DEVICE);
 
@@ -2274,7 +2274,7 @@
 			i++;
 
 			if (i == tx_q->desc_count) {
-				tx_desc = IDPF_FLEX_TX_DESC(tx_q, 0);
+				tx_desc = &tx_q->flex_tx[0];
 				i = 0;
 				tx_q->compl_tag_cur_gen =
 					IDPF_TX_ADJ_COMPL_TAG_GEN(tx_q);
@@ -2319,7 +2319,7 @@
 		i++;
 
 		if (i == tx_q->desc_count) {
-			tx_desc = IDPF_FLEX_TX_DESC(tx_q, 0);
+			tx_desc = &tx_q->flex_tx[0];
 			i = 0;
 			tx_q->compl_tag_cur_gen = IDPF_TX_ADJ_COMPL_TAG_GEN(tx_q);
 		}
@@ -2552,7 +2552,7 @@
 	txq->tx_buf[i].compl_tag = IDPF_SPLITQ_TX_INVAL_COMPL_TAG;
 
 	/* grab the next descriptor */
-	desc = IDPF_FLEX_TX_CTX_DESC(txq, i);
+	desc = &txq->flex_ctx[i];
 	txq->next_to_use = idpf_tx_splitq_bump_ntu(txq, i);
 
 	return desc;
@@ -2940,6 +2940,8 @@
 	rx_ptype = le16_get_bits(rx_desc->ptype_err_fflags0,
 				 VIRTCHNL2_RX_FLEX_DESC_ADV_PTYPE_M);
 
+	skb->protocol = eth_type_trans(skb, rxq->vport->netdev);
+
 	decoded = rxq->vport->rx_ptype_lkup[rx_ptype];
 	/* If we don't know the ptype we can't do anything else with it. Just
 	 * pass it up the stack as-is.
@@ -2950,8 +2952,6 @@
 	/* process RSS/hash */
 	idpf_rx_hash(rxq, skb, rx_desc, &decoded);
 
-	skb->protocol = eth_type_trans(skb, rxq->vport->netdev);
-
 	if (le16_get_bits(rx_desc->hdrlen_flags,
 			  VIRTCHNL2_RX_FLEX_DESC_ADV_RSC_M))
 		return idpf_rx_rsc(rxq, skb, rx_desc, &decoded);
@@ -3128,7 +3128,6 @@
 		struct idpf_sw_queue *refillq = NULL;
 		struct idpf_rxq_set *rxq_set = NULL;
 		struct idpf_rx_buf *rx_buf = NULL;
-		union virtchnl2_rx_desc *desc;
 		unsigned int pkt_len = 0;
 		unsigned int hdr_len = 0;
 		u16 gen_id, buf_id = 0;
@@ -3138,8 +3137,7 @@
 		u8 rxdid;
 
 		/* get the Rx desc from Rx queue based on 'next_to_clean' */
-		desc = IDPF_RX_DESC(rxq, ntc);
-		rx_desc = (struct virtchnl2_rx_flex_desc_adv_nic_3 *)desc;
+		rx_desc = &rxq->rx[ntc].flex_adv_nic_3_wb;
 
 		/* This memory barrier is needed to keep us from reading
 		 * any other fields out of the rx_desc
@@ -3320,11 +3318,11 @@
 	int cleaned = 0;
 	u16 gen;
 
-	buf_desc = IDPF_SPLITQ_RX_BUF_DESC(bufq, bufq_nta);
+	buf_desc = &bufq->split_buf[bufq_nta];
 
 	/* make sure we stop at ring wrap in the unlikely case ring is full */
 	while (likely(cleaned < refillq->desc_count)) {
-		u16 refill_desc = IDPF_SPLITQ_RX_BI_DESC(refillq, ntc);
+		u16 refill_desc = refillq->ring[ntc];
 		bool failure;
 
 		gen = FIELD_GET(IDPF_RX_BI_GEN_M, refill_desc);
@@ -3342,7 +3340,7 @@
 		}
 
 		if (unlikely(++bufq_nta == bufq->desc_count)) {
-			buf_desc = IDPF_SPLITQ_RX_BUF_DESC(bufq, 0);
+			buf_desc = &bufq->split_buf[0];
 			bufq_nta = 0;
 		} else {
 			buf_desc++;
@@ -3636,13 +3634,15 @@
 /**
  * idpf_vport_intr_req_irq - get MSI-X vectors from the OS for the vport
  * @vport: main vport structure
- * @basename: name for the vector
  */
-static int idpf_vport_intr_req_irq(struct idpf_vport *vport, char *basename)
+static int idpf_vport_intr_req_irq(struct idpf_vport *vport)
 {
 	struct idpf_adapter *adapter = vport->adapter;
+	const char *drv_name, *if_name, *vec_name;
 	int vector, err, irq_num, vidx;
-	const char *vec_name;
+
+	drv_name = dev_driver_string(&adapter->pdev->dev);
+	if_name = netdev_name(vport->netdev);
 
 	for (vector = 0; vector < vport->num_q_vectors; vector++) {
 		struct idpf_q_vector *q_vector = &vport->q_vectors[vector];
@@ -3659,8 +3659,8 @@
 		else
 			continue;
 
-		q_vector->name = kasprintf(GFP_KERNEL, "%s-%s-%d",
-					   basename, vec_name, vidx);
+		q_vector->name = kasprintf(GFP_KERNEL, "%s-%s-%s-%d", drv_name,
+					   if_name, vec_name, vidx);
 
 		err = request_irq(irq_num, idpf_vport_intr_clean_queues, 0,
 				  q_vector->name, q_vector);
@@ -3746,9 +3746,9 @@
  */
 void idpf_vport_intr_deinit(struct idpf_vport *vport)
 {
+	idpf_vport_intr_dis_irq_all(vport);
 	idpf_vport_intr_napi_dis_all(vport);
 	idpf_vport_intr_napi_del_all(vport);
-	idpf_vport_intr_dis_irq_all(vport);
 	idpf_vport_intr_rel_irq(vport);
 }
 
@@ -4170,7 +4170,6 @@
  */
 int idpf_vport_intr_init(struct idpf_vport *vport)
 {
-	char *int_name;
 	int err;
 
 	err = idpf_vport_intr_init_vec_idx(vport);
@@ -4179,31 +4178,29 @@
 
 	idpf_vport_intr_map_vector_to_qs(vport);
 	idpf_vport_intr_napi_add_all(vport);
-	idpf_vport_intr_napi_ena_all(vport);
 
 	err = vport->adapter->dev_ops.reg_ops.intr_reg_init(vport);
 	if (err)
 		goto unroll_vectors_alloc;
 
-	int_name = kasprintf(GFP_KERNEL, "%s-%s",
-			     dev_driver_string(&vport->adapter->pdev->dev),
-			     vport->netdev->name);
-
-	err = idpf_vport_intr_req_irq(vport, int_name);
+	err = idpf_vport_intr_req_irq(vport);
 	if (err)
 		goto unroll_vectors_alloc;
 
-	idpf_vport_intr_ena_irq_all(vport);
-
 	return 0;
 
 unroll_vectors_alloc:
-	idpf_vport_intr_napi_dis_all(vport);
 	idpf_vport_intr_napi_del_all(vport);
 
 	return err;
 }
 
+void idpf_vport_intr_ena(struct idpf_vport *vport)
+{
+	idpf_vport_intr_napi_ena_all(vport);
+	idpf_vport_intr_ena_irq_all(vport);
+}
+
 /**
  * idpf_config_rss - Send virtchnl messages to configure RSS
  * @vport: virtual port
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/idpf/idpf_txrx.h
@@ -8,6 +8,8 @@
 #include <net/tcp.h>
 #include <net/netdev_queues.h>
 
+#include "idpf_lan_txrx.h"
+
 #define IDPF_LARGE_MAX_Q			256
 #define IDPF_MAX_Q				16
 #define IDPF_MIN_Q				2
@@ -115,24 +117,6 @@
 #define IDPF_RXD_EOF_SPLITQ		VIRTCHNL2_RX_FLEX_DESC_ADV_STATUS0_EOF_M
 #define IDPF_RXD_EOF_SINGLEQ		VIRTCHNL2_RX_BASE_DESC_STATUS_EOF_M
 
-#define IDPF_SINGLEQ_RX_BUF_DESC(rxq, i)	\
-	(&(((struct virtchnl2_singleq_rx_buf_desc *)((rxq)->desc_ring))[i]))
-#define IDPF_SPLITQ_RX_BUF_DESC(rxq, i)	\
-	(&(((struct virtchnl2_splitq_rx_buf_desc *)((rxq)->desc_ring))[i]))
-#define IDPF_SPLITQ_RX_BI_DESC(rxq, i) ((((rxq)->ring))[i])
-
-#define IDPF_BASE_TX_DESC(txq, i)	\
-	(&(((struct idpf_base_tx_desc *)((txq)->desc_ring))[i]))
-#define IDPF_BASE_TX_CTX_DESC(txq, i) \
-	(&(((struct idpf_base_tx_ctx_desc *)((txq)->desc_ring))[i]))
-#define IDPF_SPLITQ_TX_COMPLQ_DESC(txcq, i)	\
-	(&(((struct idpf_splitq_tx_compl_desc *)((txcq)->desc_ring))[i]))
-
-#define IDPF_FLEX_TX_DESC(txq, i) \
-	(&(((union idpf_tx_flex_desc *)((txq)->desc_ring))[i]))
-#define IDPF_FLEX_TX_CTX_DESC(txq, i)	\
-	(&(((struct idpf_flex_tx_ctx_desc *)((txq)->desc_ring))[i]))
-
 #define IDPF_DESC_UNUSED(txq)     \
 	((((txq)->next_to_clean > (txq)->next_to_use) ? 0 : (txq)->desc_count) + \
 	(txq)->next_to_clean - (txq)->next_to_use - 1)
@@ -315,8 +299,6 @@
 
 #define IDPF_RX_DMA_ATTR \
 	(DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING)
-#define IDPF_RX_DESC(rxq, i)	\
-	(&(((union virtchnl2_rx_desc *)((rxq)->desc_ring))[i]))
 
 struct idpf_rx_buf {
 	struct page *page;
@@ -653,7 +635,15 @@
  * @q_vector: Backreference to associated vector
  * @size: Length of descriptor ring in bytes
  * @dma: Physical address of ring
- * @desc_ring: Descriptor ring memory
+ * @rx: universal receive descriptor array
+ * @single_buf: Rx buffer descriptor array in singleq
+ * @split_buf: Rx buffer descriptor array in splitq
+ * @base_tx: basic Tx descriptor array
+ * @base_ctx: basic Tx context descriptor array
+ * @flex_tx: flex Tx descriptor array
+ * @flex_ctx: flex Tx context descriptor array
+ * @comp: completion descriptor array
+ * @desc_ring: virtual descriptor ring address
  * @tx_max_bufs: Max buffers that can be transmitted with scatter-gather
  * @tx_min_pkt_len: Min supported packet length
  * @num_completions: Only relevant for TX completion queue. It tracks the
@@ -731,7 +721,21 @@
 	struct idpf_q_vector *q_vector;
 	unsigned int size;
 	dma_addr_t dma;
-	void *desc_ring;
+	union {
+		union virtchnl2_rx_desc *rx;
+
+		struct virtchnl2_singleq_rx_buf_desc *single_buf;
+		struct virtchnl2_splitq_rx_buf_desc *split_buf;
+
+		struct idpf_base_tx_desc *base_tx;
+		struct idpf_base_tx_ctx_desc *base_ctx;
+		union idpf_tx_flex_desc *flex_tx;
+		struct idpf_flex_tx_ctx_desc *flex_ctx;
+
+		struct idpf_splitq_tx_compl_desc *comp;
+
+		void *desc_ring;
+	};
 
 	u16 tx_max_bufs;
 	u8 tx_min_pkt_len;
@@ -988,6 +992,7 @@
 void idpf_vport_intr_update_itr_ena_irq(struct idpf_q_vector *q_vector);
 void idpf_vport_intr_deinit(struct idpf_vport *vport);
 int idpf_vport_intr_init(struct idpf_vport *vport);
+void idpf_vport_intr_ena(struct idpf_vport *vport);
 enum pkt_hash_types idpf_ptype_to_htype(const struct idpf_rx_ptype_decoded *decoded);
 int idpf_config_rss(struct idpf_vport *vport);
 int idpf_init_rss(struct idpf_vport *vport);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
@@ -23,7 +23,7 @@
 
 	switch (event) {
 	case VIRTCHNL2_EVENT_LINK_CHANGE:
-		vport->link_speed_mbps = le32_to_cpu(v2e->link_speed);
+		np->link_speed_mbps = le32_to_cpu(v2e->link_speed);
 		link_status = v2e->link_status;
 
 		if (vport->link_up == link_status)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/igb/igb_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/igb/igb_main.c
@@ -33,6 +33,7 @@
 #include <linux/bpf_trace.h>
 #include <linux/pm_runtime.h>
 #include <linux/etherdevice.h>
+#include <linux/lockdep.h>
 #ifdef CONFIG_IGB_DCA
 #include <linux/dca.h>
 #endif
@@ -664,6 +665,10 @@
 	dca_register_notify(&dca_notifier);
 #endif
 	ret = pci_register_driver(&igb_driver);
+#ifdef CONFIG_IGB_DCA
+	if (ret)
+		dca_unregister_notify(&dca_notifier);
+#endif
 	return ret;
 }
 
@@ -2939,8 +2944,11 @@
 	}
 }
 
+/* This function assumes __netif_tx_lock is held by the caller. */
 static void igb_xdp_ring_update_tail(struct igb_ring *ring)
 {
+	lockdep_assert_held(&txring_txq(ring)->_xmit_lock);
+
 	/* Force memory writes to complete before letting h/w know there
 	 * are new descriptors to fetch.
 	 */
@@ -3025,11 +3033,11 @@
 		nxmit++;
 	}
 
-	__netif_tx_unlock(nq);
-
 	if (unlikely(flags & XDP_XMIT_FLUSH))
 		igb_xdp_ring_update_tail(tx_ring);
 
+	__netif_tx_unlock(nq);
+
 	return nxmit;
 }
 
@@ -4833,6 +4841,7 @@
 
 #if (PAGE_SIZE < 8192)
 	if (adapter->max_frame_size > IGB_MAX_FRAME_BUILD_SKB ||
+	    IGB_2K_TOO_SMALL_WITH_PADDING ||
 	    rd32(E1000_RCTL) & E1000_RCTL_SBP)
 		set_ring_uses_large_buffer(rx_ring);
 #endif
@@ -6984,45 +6993,42 @@
 
 static void igb_tsync_interrupt(struct igb_adapter *adapter)
 {
+	const u32 mask = (TSINTR_SYS_WRAP | E1000_TSICR_TXTS |
+			  TSINTR_TT0 | TSINTR_TT1 |
+			  TSINTR_AUTT0 | TSINTR_AUTT1);
 	struct e1000_hw *hw = &adapter->hw;
-	u32 ack = 0, tsicr = rd32(E1000_TSICR);
+	u32 tsicr = rd32(E1000_TSICR);
 	struct ptp_clock_event event;
 
+	if (hw->mac.type == e1000_82580) {
+		/* 82580 has a hardware bug that requires an explicit
+		 * write to clear the TimeSync interrupt cause.
+		 */
+		wr32(E1000_TSICR, tsicr & mask);
+	}
+
 	if (tsicr & TSINTR_SYS_WRAP) {
 		event.type = PTP_CLOCK_PPS;
 		if (adapter->ptp_caps.pps)
 			ptp_clock_event(adapter->ptp_clock, &event);
-		ack |= TSINTR_SYS_WRAP;
 	}
 
 	if (tsicr & E1000_TSICR_TXTS) {
 		/* retrieve hardware timestamp */
 		schedule_work(&adapter->ptp_tx_work);
-		ack |= E1000_TSICR_TXTS;
 	}
 
-	if (tsicr & TSINTR_TT0) {
+	if (tsicr & TSINTR_TT0)
 		igb_perout(adapter, 0);
-		ack |= TSINTR_TT0;
-	}
 
-	if (tsicr & TSINTR_TT1) {
+	if (tsicr & TSINTR_TT1)
 		igb_perout(adapter, 1);
-		ack |= TSINTR_TT1;
-	}
 
-	if (tsicr & TSINTR_AUTT0) {
+	if (tsicr & TSINTR_AUTT0)
 		igb_extts(adapter, 0);
-		ack |= TSINTR_AUTT0;
-	}
 
-	if (tsicr & TSINTR_AUTT1) {
+	if (tsicr & TSINTR_AUTT1)
 		igb_extts(adapter, 1);
-		ack |= TSINTR_AUTT1;
-	}
-
-	/* acknowledge the interrupts */
-	wr32(E1000_TSICR, ack);
 }
 
 static irqreturn_t igb_msix_other(int irq, void *data)
@@ -8891,12 +8897,14 @@
 
 static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
 {
+	unsigned int total_bytes = 0, total_packets = 0;
 	struct igb_adapter *adapter = q_vector->adapter;
 	struct igb_ring *rx_ring = q_vector->rx.ring;
-	struct sk_buff *skb = rx_ring->skb;
-	unsigned int total_bytes = 0, total_packets = 0;
 	u16 cleaned_count = igb_desc_unused(rx_ring);
+	struct sk_buff *skb = rx_ring->skb;
+	int cpu = smp_processor_id();
 	unsigned int xdp_xmit = 0;
+	struct netdev_queue *nq;
 	struct xdp_buff xdp;
 	u32 frame_sz = 0;
 	int rx_buf_pgcnt;
@@ -9024,7 +9032,10 @@
 	if (xdp_xmit & IGB_XDP_TX) {
 		struct igb_ring *tx_ring = igb_xdp_tx_queue_mapping(adapter);
 
+		nq = txring_txq(tx_ring);
+		__netif_tx_lock(nq, cpu);
 		igb_xdp_ring_update_tail(tx_ring);
+		__netif_tx_unlock(nq);
 	}
 
 	u64_stats_update_begin(&rx_ring->rx_syncp);
@@ -9665,6 +9676,10 @@
 	struct igb_adapter *adapter = netdev_priv(netdev);
 
 	if (netif_running(netdev)) {
+		if (!test_bit(__IGB_DOWN, &adapter->state)) {
+			dev_dbg(&pdev->dev, "Resuming from non-fatal error, do nothing.\n");
+			return;
+		}
 		if (igb_up(adapter)) {
 			dev_err(&pdev->dev, "igb_up failed after reset\n");
 			return;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/igc/igc_base.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/igc/igc_base.c
@@ -68,6 +68,10 @@
 	u32 eecd = rd32(IGC_EECD);
 	u16 size;
 
+	/* failed to read reg and got all F's */
+	if (!(~eecd))
+		return -ENXIO;
+
 	size = FIELD_GET(IGC_EECD_SIZE_EX_MASK, eecd);
 
 	/* Added to a constant, "size" becomes the left-shift value
@@ -221,6 +225,8 @@
 
 	/* NVM initialization */
 	ret_val = igc_init_nvm_params_base(hw);
+	if (ret_val)
+		goto out;
 	switch (hw->mac.type) {
 	case igc_i225:
 		ret_val = igc_init_nvm_params_i225(hw);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/igc/igc_defines.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/igc/igc_defines.h
@@ -404,6 +404,12 @@
 #define IGC_DTXMXPKTSZ_TSN	0x19 /* 1600 bytes of max TX DMA packet size */
 #define IGC_DTXMXPKTSZ_DEFAULT	0x98 /* 9728-byte Jumbo frames */
 
+/* Retry Buffer Control */
+#define IGC_RETX_CTL			0x041C
+#define IGC_RETX_CTL_WATERMARK_MASK	0xF
+#define IGC_RETX_CTL_QBVFULLTH_SHIFT	8 /* QBV Retry Buffer Full Threshold */
+#define IGC_RETX_CTL_QBVFULLEN	0x1000 /* Enable QBV Retry Buffer Full Threshold */
+
 /* Transmit Scheduling Latency */
 /* Latency between transmission scheduling (LaunchTime) and the time
  * the packet is transmitted to the network in nanosecond.
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/igc/igc_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/igc/igc_main.c
@@ -1642,10 +1642,6 @@
 
 	if (unlikely(test_bit(IGC_RING_FLAG_TX_HWTSTAMP, &tx_ring->flags) &&
 		     skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
-		/* FIXME: add support for retrieving timestamps from
-		 * the other timer registers before skipping the
-		 * timestamping request.
-		 */
 		unsigned long flags;
 		u32 tstamp_flags;
 
@@ -5302,25 +5298,22 @@
 
 static void igc_tsync_interrupt(struct igc_adapter *adapter)
 {
-	u32 ack, tsauxc, sec, nsec, tsicr;
 	struct igc_hw *hw = &adapter->hw;
+	u32 tsauxc, sec, nsec, tsicr;
 	struct ptp_clock_event event;
 	struct timespec64 ts;
 
 	tsicr = rd32(IGC_TSICR);
-	ack = 0;
 
 	if (tsicr & IGC_TSICR_SYS_WRAP) {
 		event.type = PTP_CLOCK_PPS;
 		if (adapter->ptp_caps.pps)
 			ptp_clock_event(adapter->ptp_clock, &event);
-		ack |= IGC_TSICR_SYS_WRAP;
 	}
 
 	if (tsicr & IGC_TSICR_TXTS) {
 		/* retrieve hardware timestamp */
 		igc_ptp_tx_tstamp_event(adapter);
-		ack |= IGC_TSICR_TXTS;
 	}
 
 	if (tsicr & IGC_TSICR_TT0) {
@@ -5334,7 +5327,6 @@
 		wr32(IGC_TSAUXC, tsauxc);
 		adapter->perout[0].start = ts;
 		spin_unlock(&adapter->tmreg_lock);
-		ack |= IGC_TSICR_TT0;
 	}
 
 	if (tsicr & IGC_TSICR_TT1) {
@@ -5348,7 +5340,6 @@
 		wr32(IGC_TSAUXC, tsauxc);
 		adapter->perout[1].start = ts;
 		spin_unlock(&adapter->tmreg_lock);
-		ack |= IGC_TSICR_TT1;
 	}
 
 	if (tsicr & IGC_TSICR_AUTT0) {
@@ -5358,7 +5349,6 @@
 		event.index = 0;
 		event.timestamp = sec * NSEC_PER_SEC + nsec;
 		ptp_clock_event(adapter->ptp_clock, &event);
-		ack |= IGC_TSICR_AUTT0;
 	}
 
 	if (tsicr & IGC_TSICR_AUTT1) {
@@ -5368,11 +5358,7 @@
 		event.index = 1;
 		event.timestamp = sec * NSEC_PER_SEC + nsec;
 		ptp_clock_event(adapter->ptp_clock, &event);
-		ack |= IGC_TSICR_AUTT1;
 	}
-
-	/* acknowledge the interrupts */
-	wr32(IGC_TSICR, ack);
 }
 
 /**
@@ -6220,21 +6206,6 @@
 	size_t n;
 	int i;
 
-	switch (qopt->cmd) {
-	case TAPRIO_CMD_REPLACE:
-		break;
-	case TAPRIO_CMD_DESTROY:
-		return igc_tsn_clear_schedule(adapter);
-	case TAPRIO_CMD_STATS:
-		igc_taprio_stats(adapter->netdev, &qopt->stats);
-		return 0;
-	case TAPRIO_CMD_QUEUE_STATS:
-		igc_taprio_queue_stats(adapter->netdev, &qopt->queue_stats);
-		return 0;
-	default:
-		return -EOPNOTSUPP;
-	}
-
 	if (qopt->base_time < 0)
 		return -ERANGE;
 
@@ -6244,12 +6215,16 @@
 	if (!validate_schedule(adapter, qopt))
 		return -EINVAL;
 
+	igc_ptp_read(adapter, &now);
+
+	if (igc_tsn_is_taprio_activated_by_user(adapter) &&
+	    is_base_time_past(qopt->base_time, &now))
+		adapter->qbv_config_change_errors++;
+
 	adapter->cycle_time = qopt->cycle_time;
 	adapter->base_time = qopt->base_time;
 	adapter->taprio_offload_enable = true;
 
-	igc_ptp_read(adapter, &now);
-
 	for (n = 0; n < qopt->num_entries; n++) {
 		struct tc_taprio_sched_entry *e = &qopt->entries[n];
 
@@ -6343,7 +6318,23 @@
 	if (hw->mac.type != igc_i225)
 		return -EOPNOTSUPP;
 
-	err = igc_save_qbv_schedule(adapter, qopt);
+	switch (qopt->cmd) {
+	case TAPRIO_CMD_REPLACE:
+		err = igc_save_qbv_schedule(adapter, qopt);
+		break;
+	case TAPRIO_CMD_DESTROY:
+		err = igc_tsn_clear_schedule(adapter);
+		break;
+	case TAPRIO_CMD_STATS:
+		igc_taprio_stats(adapter->netdev, &qopt->stats);
+		return 0;
+	case TAPRIO_CMD_QUEUE_STATS:
+		igc_taprio_queue_stats(adapter->netdev, &qopt->queue_stats);
+		return 0;
+	default:
+		return -EOPNOTSUPP;
+	}
+
 	if (err)
 		return err;
 
@@ -6833,6 +6824,9 @@
 	memcpy(&hw->mac.ops, ei->mac_ops, sizeof(hw->mac.ops));
 	memcpy(&hw->phy.ops, ei->phy_ops, sizeof(hw->phy.ops));
 
+	if (pci_is_thunderbolt_attached(pdev))
+		msleep(600);
+
 	/* Initialize skew-specific constants */
 	err = ei->get_invariants(hw);
 	if (err)
@@ -7316,6 +7310,7 @@
 	rtnl_lock();
 	if (netif_running(netdev)) {
 		if (igc_open(netdev)) {
+			rtnl_unlock();
 			netdev_err(netdev, "igc_open failed after reset\n");
 			return;
 		}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/igc/igc_tsn.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/igc/igc_tsn.c
@@ -49,12 +49,19 @@
 	return new_flags;
 }
 
+static bool igc_tsn_is_tx_mode_in_tsn(struct igc_adapter *adapter)
+{
+	struct igc_hw *hw = &adapter->hw;
+
+	return !!(rd32(IGC_TQAVCTRL) & IGC_TQAVCTRL_TRANSMIT_MODE_TSN);
+}
+
 void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter)
 {
 	struct igc_hw *hw = &adapter->hw;
 	u16 txoffset;
 
-	if (!is_any_launchtime(adapter))
+	if (!igc_tsn_is_tx_mode_in_tsn(adapter))
 		return;
 
 	switch (adapter->link_speed) {
@@ -78,6 +85,23 @@
 	wr32(IGC_GTXOFFSET, txoffset);
 }
 
+static void igc_tsn_restore_retx_default(struct igc_adapter *adapter)
+{
+	struct igc_hw *hw = &adapter->hw;
+	u32 retxctl;
+
+	retxctl = rd32(IGC_RETX_CTL) & IGC_RETX_CTL_WATERMARK_MASK;
+	wr32(IGC_RETX_CTL, retxctl);
+}
+
+bool igc_tsn_is_taprio_activated_by_user(struct igc_adapter *adapter)
+{
+	struct igc_hw *hw = &adapter->hw;
+
+	return (rd32(IGC_BASET_H) || rd32(IGC_BASET_L)) &&
+		adapter->taprio_offload_enable;
+}
+
 /* Returns the TSN specific registers to their default values after
  * the adapter is reset.
  */
@@ -91,6 +115,9 @@
 	wr32(IGC_TXPBS, I225_TXPBSIZE_DEFAULT);
 	wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_DEFAULT);
 
+	if (igc_is_device_id_i226(hw))
+		igc_tsn_restore_retx_default(adapter);
+
 	tqavctrl = rd32(IGC_TQAVCTRL);
 	tqavctrl &= ~(IGC_TQAVCTRL_TRANSMIT_MODE_TSN |
 		      IGC_TQAVCTRL_ENHANCED_QAV | IGC_TQAVCTRL_FUTSCDDIS);
@@ -111,6 +138,25 @@
 	return 0;
 }
 
+/* To partially fix i226 HW errata, reduce MAC internal buffering from 192 Bytes
+ * to 88 Bytes by setting RETX_CTL register using the recommendation from:
+ * a) Ethernet Controller I225/I226 Specification Update Rev 2.1
+ *    Item 9: TSN: Packet Transmission Might Cross the Qbv Window
+ * b) I225/6 SW User Manual Rev 1.2.4: Section 8.11.5 Retry Buffer Control
+ */
+static void igc_tsn_set_retx_qbvfullthreshold(struct igc_adapter *adapter)
+{
+	struct igc_hw *hw = &adapter->hw;
+	u32 retxctl, watermark;
+
+	retxctl = rd32(IGC_RETX_CTL);
+	watermark = retxctl & IGC_RETX_CTL_WATERMARK_MASK;
+	/* Set QBVFULLTH value using watermark and set QBVFULLEN */
+	retxctl |= (watermark << IGC_RETX_CTL_QBVFULLTH_SHIFT) |
+		   IGC_RETX_CTL_QBVFULLEN;
+	wr32(IGC_RETX_CTL, retxctl);
+}
+
 static int igc_tsn_enable_offload(struct igc_adapter *adapter)
 {
 	struct igc_hw *hw = &adapter->hw;
@@ -123,6 +169,9 @@
 	wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN);
 	wr32(IGC_TXPBS, IGC_TXPBSIZE_TSN);
 
+	if (igc_is_device_id_i226(hw))
+		igc_tsn_set_retx_qbvfullthreshold(adapter);
+
 	for (i = 0; i < adapter->num_tx_queues; i++) {
 		struct igc_ring *ring = adapter->tx_ring[i];
 		u32 txqctl = 0;
@@ -262,14 +311,6 @@
 		s64 n = div64_s64(ktime_sub_ns(systim, base_time), cycle);
 
 		base_time = ktime_add_ns(base_time, (n + 1) * cycle);
-
-		/* Increase the counter if scheduling into the past while
-		 * Gate Control List (GCL) is running.
-		 */
-		if ((rd32(IGC_BASET_H) || rd32(IGC_BASET_L)) &&
-		    (adapter->tc_setup_type == TC_SETUP_QDISC_TAPRIO) &&
-		    (adapter->qbv_count > 1))
-			adapter->qbv_config_change_errors++;
 	} else {
 		if (igc_is_device_id_i226(hw)) {
 			ktime_t adjust_time, expires_time;
@@ -331,15 +372,22 @@
 	return err;
 }
 
-int igc_tsn_offload_apply(struct igc_adapter *adapter)
+static bool igc_tsn_will_tx_mode_change(struct igc_adapter *adapter)
 {
-	struct igc_hw *hw = &adapter->hw;
+	bool any_tsn_enabled = !!(igc_tsn_new_flags(adapter) &
+				  IGC_FLAG_TSN_ANY_ENABLED);
 
-	/* Per I225/6 HW Design Section 7.5.2.1, transmit mode
-	 * cannot be changed dynamically. Require reset the adapter.
+	return (any_tsn_enabled && !igc_tsn_is_tx_mode_in_tsn(adapter)) ||
+	       (!any_tsn_enabled && igc_tsn_is_tx_mode_in_tsn(adapter));
+}
+
+int igc_tsn_offload_apply(struct igc_adapter *adapter)
+{
+	/* Per I225/6 HW Design Section 7.5.2.1 guideline, if tx mode change
+	 * from legacy->tsn or tsn->legacy, then reset adapter is needed.
 	 */
 	if (netif_running(adapter->netdev) &&
-	    (igc_is_device_id_i225(hw) || !adapter->qbv_count)) {
+	    igc_tsn_will_tx_mode_change(adapter)) {
 		schedule_work(&adapter->reset_task);
 		return 0;
 	}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/igc/igc_tsn.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/igc/igc_tsn.h
@@ -7,5 +7,6 @@
 int igc_tsn_offload_apply(struct igc_adapter *adapter);
 int igc_tsn_reset(struct igc_adapter *adapter);
 void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter);
+bool igc_tsn_is_taprio_activated_by_user(struct igc_adapter *adapter);
 
 #endif /* _IGC_BASE_H */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
@@ -194,6 +194,8 @@
 	dev_err(&adapter->pdev->dev, format, ## arg)
 #define e_dev_notice(format, arg...) \
 	dev_notice(&adapter->pdev->dev, format, ## arg)
+#define e_dbg(msglvl, format, arg...) \
+	netif_dbg(adapter, msglvl, adapter->netdev, format, ## arg)
 #define e_info(msglvl, format, arg...) \
 	netif_info(adapter, msglvl, adapter->netdev, format, ## arg)
 #define e_err(msglvl, format, arg...) \
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -914,7 +914,13 @@
 		goto err_out;
 	}
 
-	xs = kzalloc(sizeof(*xs), GFP_KERNEL);
+	algo = xfrm_aead_get_byname(aes_gcm_name, IXGBE_IPSEC_AUTH_BITS, 1);
+	if (unlikely(!algo)) {
+		err = -ENOENT;
+		goto err_out;
+	}
+
+	xs = kzalloc(sizeof(*xs), GFP_ATOMIC);
 	if (unlikely(!xs)) {
 		err = -ENOMEM;
 		goto err_out;
@@ -930,14 +936,8 @@
 		memcpy(&xs->id.daddr.a4, sam->addr, sizeof(xs->id.daddr.a4));
 	xs->xso.dev = adapter->netdev;
 
-	algo = xfrm_aead_get_byname(aes_gcm_name, IXGBE_IPSEC_AUTH_BITS, 1);
-	if (unlikely(!algo)) {
-		err = -ENOENT;
-		goto err_xs;
-	}
-
 	aead_len = sizeof(*xs->aead) + IXGBE_IPSEC_KEY_BITS / 8;
-	xs->aead = kzalloc(aead_len, GFP_KERNEL);
+	xs->aead = kzalloc(aead_len, GFP_ATOMIC);
 	if (unlikely(!xs->aead)) {
 		err = -ENOMEM;
 		goto err_xs;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -1047,7 +1047,7 @@
 		break;
 	}
 
-	e_info(drv, "VF %d requested invalid api version %u\n", vf, api);
+	e_dbg(drv, "VF %d requested unsupported api version %u\n", vf, api);
 
 	return -1;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -3673,9 +3673,7 @@
 #define IXGBE_KRM_LINK_S1(P)		((P) ? 0x8200 : 0x4200)
 #define IXGBE_KRM_LINK_CTRL_1(P)	((P) ? 0x820C : 0x420C)
 #define IXGBE_KRM_AN_CNTL_1(P)		((P) ? 0x822C : 0x422C)
-#define IXGBE_KRM_AN_CNTL_4(P)		((P) ? 0x8238 : 0x4238)
 #define IXGBE_KRM_AN_CNTL_8(P)		((P) ? 0x8248 : 0x4248)
-#define IXGBE_KRM_PCS_KX_AN(P)		((P) ? 0x9918 : 0x5918)
 #define IXGBE_KRM_SGMII_CTRL(P)		((P) ? 0x82A0 : 0x42A0)
 #define IXGBE_KRM_LP_BASE_PAGE_HIGH(P)	((P) ? 0x836C : 0x436C)
 #define IXGBE_KRM_DSP_TXFFE_STATE_4(P)	((P) ? 0x8634 : 0x4634)
@@ -3685,7 +3683,6 @@
 #define IXGBE_KRM_PMD_FLX_MASK_ST20(P)	((P) ? 0x9054 : 0x5054)
 #define IXGBE_KRM_TX_COEFF_CTRL_1(P)	((P) ? 0x9520 : 0x5520)
 #define IXGBE_KRM_RX_ANA_CTL(P)		((P) ? 0x9A00 : 0x5A00)
-#define IXGBE_KRM_FLX_TMRS_CTRL_ST31(P)	((P) ? 0x9180 : 0x5180)
 
 #define IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA		~(0x3 << 20)
 #define IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_SR		BIT(20)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
@@ -1722,59 +1722,9 @@
 		return -EINVAL;
 	}
 
-	(void)mac->ops.write_iosf_sb_reg(hw,
-			IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
-			IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
-
-	/* change mode enforcement rules to hybrid */
-	(void)mac->ops.read_iosf_sb_reg(hw,
-			IXGBE_KRM_FLX_TMRS_CTRL_ST31(hw->bus.lan_id),
-			IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
-	reg_val |= 0x0400;
-
-	(void)mac->ops.write_iosf_sb_reg(hw,
-			IXGBE_KRM_FLX_TMRS_CTRL_ST31(hw->bus.lan_id),
-			IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
-
-	/* manually control the config */
-	(void)mac->ops.read_iosf_sb_reg(hw,
-			IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
-			IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
-	reg_val |= 0x20002240;
-
-	(void)mac->ops.write_iosf_sb_reg(hw,
-			IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
-			IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
-
-	/* move the AN base page values */
-	(void)mac->ops.read_iosf_sb_reg(hw,
-			IXGBE_KRM_PCS_KX_AN(hw->bus.lan_id),
-			IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
-	reg_val |= 0x1;
-
-	(void)mac->ops.write_iosf_sb_reg(hw,
-			IXGBE_KRM_PCS_KX_AN(hw->bus.lan_id),
-			IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
-
-	/* set the AN37 over CB mode */
-	(void)mac->ops.read_iosf_sb_reg(hw,
-			IXGBE_KRM_AN_CNTL_4(hw->bus.lan_id),
-			IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
-	reg_val |= 0x20000000;
-
-	(void)mac->ops.write_iosf_sb_reg(hw,
-			IXGBE_KRM_AN_CNTL_4(hw->bus.lan_id),
-			IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
-
-	/* restart AN manually */
-	(void)mac->ops.read_iosf_sb_reg(hw,
-			IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
-			IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
-	reg_val |= IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART;
-
-	(void)mac->ops.write_iosf_sb_reg(hw,
-			IXGBE_KRM_LINK_CTRL_1(hw->bus.lan_id),
-			IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
+	status = mac->ops.write_iosf_sb_reg(hw,
+				IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
+				IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
 
 	/* Toggle port SW reset by AN reset. */
 	status = ixgbe_restart_an_internal_phy_x550em(hw);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/intel/ixgbevf/ipsec.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/intel/ixgbevf/ipsec.c
@@ -629,7 +629,6 @@
 
 	switch (adapter->hw.api_version) {
 	case ixgbe_mbox_api_14:
-	case ixgbe_mbox_api_15:
 		break;
 	default:
 		return;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/jme.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/jme.c
@@ -946,15 +946,13 @@
 	if (skb->protocol != htons(ETH_P_IP))
 		return csum;
 	skb_set_network_header(skb, ETH_HLEN);
-	if ((ip_hdr(skb)->protocol != IPPROTO_UDP) ||
-	    (skb->len < (ETH_HLEN +
-			(ip_hdr(skb)->ihl << 2) +
-			sizeof(struct udphdr)))) {
+
+	if (ip_hdr(skb)->protocol != IPPROTO_UDP ||
+	    skb->len < (ETH_HLEN + ip_hdrlen(skb) + sizeof(struct udphdr))) {
 		skb_reset_network_header(skb);
 		return csum;
 	}
-	skb_set_transport_header(skb,
-			ETH_HLEN + (ip_hdr(skb)->ihl << 2));
+	skb_set_transport_header(skb, ETH_HLEN + ip_hdrlen(skb));
 	csum = udp_hdr(skb)->check;
 	skb_reset_transport_header(skb);
 	skb_reset_network_header(skb);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/lantiq_etop.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/lantiq_etop.c
@@ -217,9 +217,9 @@
 	if (ch->dma.irq)
 		free_irq(ch->dma.irq, priv);
 	if (IS_RX(ch->idx)) {
-		int desc;
+		struct ltq_dma_channel *dma = &ch->dma;
 
-		for (desc = 0; desc < LTQ_DESC_NUM; desc++)
+		for (dma->desc = 0; dma->desc < LTQ_DESC_NUM; dma->desc++)
 			dev_kfree_skb_any(ch->skb[ch->dma.desc]);
 	}
 }
@@ -482,7 +482,9 @@
 	unsigned long flags;
 	u32 byte_offset;
 
-	len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+	if (skb_put_padto(skb, ETH_ZLEN))
+		return NETDEV_TX_OK;
+	len = skb->len;
 
 	if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
 		netdev_err(dev, "tx ring full\n");
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -2708,9 +2708,15 @@
 
 static void mv643xx_eth_shared_of_remove(void)
 {
+	struct mv643xx_eth_platform_data *pd;
 	int n;
 
 	for (n = 0; n < 3; n++) {
+		if (!port_platdev[n])
+			continue;
+		pd = dev_get_platdata(&port_platdev[n]->dev);
+		if (pd)
+			of_node_put(pd->phy_node);
 		platform_device_del(port_platdev[n]);
 		port_platdev[n] = NULL;
 	}
@@ -2773,8 +2779,10 @@
 	}
 
 	ppdev = platform_device_alloc(MV643XX_ETH_NAME, dev_num);
-	if (!ppdev)
-		return -ENOMEM;
+	if (!ppdev) {
+		ret = -ENOMEM;
+		goto put_err;
+	}
 	ppdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 	ppdev->dev.of_node = pnp;
 
@@ -2796,6 +2804,8 @@
 
 port_err:
 	platform_device_put(ppdev);
+put_err:
+	of_node_put(ppd.phy_node);
 	return ret;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/mvpp2/mvpp2.h
@@ -1088,7 +1088,7 @@
 	unsigned int max_port_rxqs;
 
 	/* Workqueue to gather hardware statistics */
-	char queue_name[30];
+	char queue_name[31];
 	struct workqueue_struct *stats_queue;
 
 	/* Debugfs root entry */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -953,13 +953,13 @@
 static void mvpp2_bm_pool_update_priv_fc(struct mvpp2 *priv, bool en)
 {
 	struct mvpp2_port *port;
-	int i;
+	int i, j;
 
 	for (i = 0; i < priv->port_count; i++) {
 		port = priv->port_list[i];
 		if (port->priv->percpu_pools) {
-			for (i = 0; i < port->nrxqs; i++)
-				mvpp2_bm_pool_update_fc(port, &port->priv->bm_pools[i],
+			for (j = 0; j < port->nrxqs; j++)
+				mvpp2_bm_pool_update_fc(port, &port->priv->bm_pools[j],
 							port->tx_fc & en);
 		} else {
 			mvpp2_bm_pool_update_fc(port, port->pool_long, port->tx_fc & en);
@@ -4013,7 +4013,10 @@
 			}
 		}
 
-		skb = build_skb(data, frag_size);
+		if (frag_size)
+			skb = build_skb(data, frag_size);
+		else
+			skb = slab_build_skb(data);
 		if (!skb) {
 			netdev_warn(port->dev, "skb build failed\n");
 			goto err_drop_frame;
@@ -6903,6 +6906,7 @@
 	/* 9704 == 9728 - 20 and rounding to 8 */
 	dev->max_mtu = MVPP2_BM_JUMBO_PKT_SIZE;
 	device_set_node(&dev->dev, port_fwnode);
+	dev->dev_port = port->id;
 
 	port->pcs_gmac.ops = &mvpp2_phylink_gmac_pcs_ops;
 	port->pcs_gmac.neg_mode = true;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeon_ep/octep_ethtool.c
@@ -157,17 +157,14 @@
 				    iface_rx_stats,
 				    iface_tx_stats);
 
-	for (q = 0; q < oct->num_oqs; q++) {
-		struct octep_iq *iq = oct->iq[q];
-		struct octep_oq *oq = oct->oq[q];
-
-		tx_packets += iq->stats.instr_completed;
-		tx_bytes += iq->stats.bytes_sent;
-		tx_busy_errors += iq->stats.tx_busy;
-
-		rx_packets += oq->stats.packets;
-		rx_bytes += oq->stats.bytes;
-		rx_alloc_errors += oq->stats.alloc_failures;
+	for (q = 0; q < OCTEP_MAX_QUEUES; q++) {
+		tx_packets += oct->stats_iq[q].instr_completed;
+		tx_bytes += oct->stats_iq[q].bytes_sent;
+		tx_busy_errors += oct->stats_iq[q].tx_busy;
+
+		rx_packets += oct->stats_oq[q].packets;
+		rx_bytes += oct->stats_oq[q].bytes;
+		rx_alloc_errors += oct->stats_oq[q].alloc_failures;
 	}
 	i = 0;
 	data[i++] = rx_packets;
@@ -205,22 +202,18 @@
 	data[i++] = iface_rx_stats->err_pkts;
 
 	/* Per Tx Queue stats */
-	for (q = 0; q < oct->num_iqs; q++) {
-		struct octep_iq *iq = oct->iq[q];
-
-		data[i++] = iq->stats.instr_posted;
-		data[i++] = iq->stats.instr_completed;
-		data[i++] = iq->stats.bytes_sent;
-		data[i++] = iq->stats.tx_busy;
+	for (q = 0; q < OCTEP_MAX_QUEUES; q++) {
+		data[i++] = oct->stats_iq[q].instr_posted;
+		data[i++] = oct->stats_iq[q].instr_completed;
+		data[i++] = oct->stats_iq[q].bytes_sent;
+		data[i++] = oct->stats_iq[q].tx_busy;
 	}
 
 	/* Per Rx Queue stats */
-	for (q = 0; q < oct->num_oqs; q++) {
-		struct octep_oq *oq = oct->oq[q];
-
-		data[i++] = oq->stats.packets;
-		data[i++] = oq->stats.bytes;
-		data[i++] = oq->stats.alloc_failures;
+	for (q = 0; q < OCTEP_MAX_QUEUES; q++) {
+		data[i++] = oct->stats_oq[q].packets;
+		data[i++] = oct->stats_oq[q].bytes;
+		data[i++] = oct->stats_oq[q].alloc_failures;
 	}
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeon_ep/octep_main.c
@@ -822,7 +822,7 @@
 	if (unlikely(IQ_INSTR_SPACE(iq) >
 		     OCTEP_WAKE_QUEUE_THRESHOLD)) {
 		netif_start_subqueue(iq->netdev, iq->q_no);
-		iq->stats.restart_cnt++;
+		iq->stats->restart_cnt++;
 		return 0;
 	}
 
@@ -960,7 +960,7 @@
 	wmb();
 	/* Ring Doorbell to notify the NIC of new packets */
 	writel(iq->fill_cnt, iq->doorbell_reg);
-	iq->stats.instr_posted += iq->fill_cnt;
+	iq->stats->instr_posted += iq->fill_cnt;
 	iq->fill_cnt = 0;
 	return NETDEV_TX_OK;
 
@@ -991,37 +991,24 @@
 static void octep_get_stats64(struct net_device *netdev,
 			      struct rtnl_link_stats64 *stats)
 {
-	u64 tx_packets, tx_bytes, rx_packets, rx_bytes;
 	struct octep_device *oct = netdev_priv(netdev);
+	u64 tx_packets, tx_bytes, rx_packets, rx_bytes;
 	int q;
 
-	if (netif_running(netdev))
-		octep_ctrl_net_get_if_stats(oct,
-					    OCTEP_CTRL_NET_INVALID_VFID,
-					    &oct->iface_rx_stats,
-					    &oct->iface_tx_stats);
-
 	tx_packets = 0;
 	tx_bytes = 0;
 	rx_packets = 0;
 	rx_bytes = 0;
-	for (q = 0; q < oct->num_oqs; q++) {
-		struct octep_iq *iq = oct->iq[q];
-		struct octep_oq *oq = oct->oq[q];
-
-		tx_packets += iq->stats.instr_completed;
-		tx_bytes += iq->stats.bytes_sent;
-		rx_packets += oq->stats.packets;
-		rx_bytes += oq->stats.bytes;
+	for (q = 0; q < OCTEP_MAX_QUEUES; q++) {
+		tx_packets += oct->stats_iq[q].instr_completed;
+		tx_bytes += oct->stats_iq[q].bytes_sent;
+		rx_packets += oct->stats_oq[q].packets;
+		rx_bytes += oct->stats_oq[q].bytes;
 	}
 	stats->tx_packets = tx_packets;
 	stats->tx_bytes = tx_bytes;
 	stats->rx_packets = rx_packets;
 	stats->rx_bytes = rx_bytes;
-	stats->multicast = oct->iface_rx_stats.mcast_pkts;
-	stats->rx_errors = oct->iface_rx_stats.err_pkts;
-	stats->collisions = oct->iface_tx_stats.xscol;
-	stats->tx_fifo_errors = oct->iface_tx_stats.undflw;
 }
 
 /**
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeon_ep/octep_main.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeon_ep/octep_main.h
@@ -257,11 +257,17 @@
 	/* Pointers to Octeon Tx queues */
 	struct octep_iq *iq[OCTEP_MAX_IQ];
 
+	/* Per iq stats */
+	struct octep_iq_stats stats_iq[OCTEP_MAX_IQ];
+
 	/* Rx queues (OQ: Output Queue) */
 	u16 num_oqs;
 	/* Pointers to Octeon Rx queues */
 	struct octep_oq *oq[OCTEP_MAX_OQ];
 
+	/* Per oq stats */
+	struct octep_oq_stats stats_oq[OCTEP_MAX_OQ];
+
 	/* Hardware port number of the PCIe interface */
 	u16 pcie_port;
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeon_ep/octep_rx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeon_ep/octep_rx.c
@@ -87,7 +87,7 @@
 		page = dev_alloc_page();
 		if (unlikely(!page)) {
 			dev_err(oq->dev, "refill: rx buffer alloc failed\n");
-			oq->stats.alloc_failures++;
+			oq->stats->alloc_failures++;
 			break;
 		}
 
@@ -98,7 +98,7 @@
 				"OQ-%d buffer refill: DMA mapping error!\n",
 				oq->q_no);
 			put_page(page);
-			oq->stats.alloc_failures++;
+			oq->stats->alloc_failures++;
 			break;
 		}
 		oq->buff_info[refill_idx].page = page;
@@ -134,6 +134,7 @@
 	oq->netdev = oct->netdev;
 	oq->dev = &oct->pdev->dev;
 	oq->q_no = q_no;
+	oq->stats = &oct->stats_oq[q_no];
 	oq->max_count = CFG_GET_OQ_NUM_DESC(oct->conf);
 	oq->ring_size_mask = oq->max_count - 1;
 	oq->buffer_size = CFG_GET_OQ_BUF_SIZE(oct->conf);
@@ -337,6 +338,51 @@
 }
 
 /**
+ * octep_oq_next_pkt() - Move to the next packet in Rx queue.
+ *
+ * @oq: Octeon Rx queue data structure.
+ * @buff_info: Current packet buffer info.
+ * @read_idx: Current packet index in the ring.
+ * @desc_used: Current packet descriptor number.
+ *
+ * Free the resources associated with a packet.
+ * Increment packet index in the ring and packet descriptor number.
+ */
+static void octep_oq_next_pkt(struct octep_oq *oq,
+			      struct octep_rx_buffer *buff_info,
+			      u32 *read_idx, u32 *desc_used)
+{
+	dma_unmap_page(oq->dev, oq->desc_ring[*read_idx].buffer_ptr,
+		       PAGE_SIZE, DMA_FROM_DEVICE);
+	buff_info->page = NULL;
+	(*read_idx)++;
+	(*desc_used)++;
+	if (*read_idx == oq->max_count)
+		*read_idx = 0;
+}
+
+/**
+ * octep_oq_drop_rx() - Free the resources associated with a packet.
+ *
+ * @oq: Octeon Rx queue data structure.
+ * @buff_info: Current packet buffer info.
+ * @read_idx: Current packet index in the ring.
+ * @desc_used: Current packet descriptor number.
+ *
+ */
+static void octep_oq_drop_rx(struct octep_oq *oq,
+			     struct octep_rx_buffer *buff_info,
+			     u32 *read_idx, u32 *desc_used)
+{
+	int data_len = buff_info->len - oq->max_single_buffer_size;
+
+	while (data_len > 0) {
+		octep_oq_next_pkt(oq, buff_info, read_idx, desc_used);
+		data_len -= oq->buffer_size;
+	};
+}
+
+/**
  * __octep_oq_process_rx() - Process hardware Rx queue and push to stack.
  *
  * @oct: Octeon device private data structure.
@@ -367,10 +413,7 @@
 	desc_used = 0;
 	for (pkt = 0; pkt < pkts_to_process; pkt++) {
 		buff_info = (struct octep_rx_buffer *)&oq->buff_info[read_idx];
-		dma_unmap_page(oq->dev, oq->desc_ring[read_idx].buffer_ptr,
-			       PAGE_SIZE, DMA_FROM_DEVICE);
 		resp_hw = page_address(buff_info->page);
-		buff_info->page = NULL;
 
 		/* Swap the length field that is in Big-Endian to CPU */
 		buff_info->len = be64_to_cpu(resp_hw->length);
@@ -394,36 +437,33 @@
 			data_offset = OCTEP_OQ_RESP_HW_SIZE;
 			rx_ol_flags = 0;
 		}
+
+		octep_oq_next_pkt(oq, buff_info, &read_idx, &desc_used);
+
+		skb = build_skb((void *)resp_hw, PAGE_SIZE);
+		if (!skb) {
+			octep_oq_drop_rx(oq, buff_info,
+					 &read_idx, &desc_used);
+			oq->stats->alloc_failures++;
+			continue;
+		}
+		skb_reserve(skb, data_offset);
+
 		rx_bytes += buff_info->len;
 
 		if (buff_info->len <= oq->max_single_buffer_size) {
-			skb = build_skb((void *)resp_hw, PAGE_SIZE);
-			skb_reserve(skb, data_offset);
 			skb_put(skb, buff_info->len);
-			read_idx++;
-			desc_used++;
-			if (read_idx == oq->max_count)
-				read_idx = 0;
 		} else {
 			struct skb_shared_info *shinfo;
 			u16 data_len;
 
-			skb = build_skb((void *)resp_hw, PAGE_SIZE);
-			skb_reserve(skb, data_offset);
 			/* Head fragment includes response header(s);
 			 * subsequent fragments contains only data.
 			 */
 			skb_put(skb, oq->max_single_buffer_size);
-			read_idx++;
-			desc_used++;
-			if (read_idx == oq->max_count)
-				read_idx = 0;
-
 			shinfo = skb_shinfo(skb);
 			data_len = buff_info->len - oq->max_single_buffer_size;
 			while (data_len) {
-				dma_unmap_page(oq->dev, oq->desc_ring[read_idx].buffer_ptr,
-					       PAGE_SIZE, DMA_FROM_DEVICE);
 				buff_info = (struct octep_rx_buffer *)
 					    &oq->buff_info[read_idx];
 				if (data_len < oq->buffer_size) {
@@ -438,11 +478,8 @@
 						buff_info->page, 0,
 						buff_info->len,
 						buff_info->len);
-				buff_info->page = NULL;
-				read_idx++;
-				desc_used++;
-				if (read_idx == oq->max_count)
-					read_idx = 0;
+
+				octep_oq_next_pkt(oq, buff_info, &read_idx, &desc_used);
 			}
 		}
 
@@ -458,8 +495,8 @@
 
 	oq->host_read_idx = read_idx;
 	oq->refill_count += desc_used;
-	oq->stats.packets += pkt;
-	oq->stats.bytes += rx_bytes;
+	oq->stats->packets += pkt;
+	oq->stats->bytes += rx_bytes;
 
 	return pkt;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeon_ep/octep_rx.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeon_ep/octep_rx.h
@@ -186,8 +186,8 @@
 	 */
 	u8 __iomem *pkts_sent_reg;
 
-	/* Statistics for this OQ. */
-	struct octep_oq_stats stats;
+	/* Pointer to statistics for this OQ. */
+	struct octep_oq_stats *stats;
 
 	/* Packets pending to be processed */
 	u32 pkts_pending;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeon_ep/octep_tx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeon_ep/octep_tx.c
@@ -81,9 +81,9 @@
 	}
 
 	iq->pkts_processed += compl_pkts;
-	iq->stats.instr_completed += compl_pkts;
-	iq->stats.bytes_sent += compl_bytes;
-	iq->stats.sgentry_sent += compl_sg;
+	iq->stats->instr_completed += compl_pkts;
+	iq->stats->bytes_sent += compl_bytes;
+	iq->stats->sgentry_sent += compl_sg;
 	iq->flush_index = fi;
 
 	netdev_tx_completed_queue(iq->netdev_q, compl_pkts, compl_bytes);
@@ -187,6 +187,7 @@
 	iq->netdev = oct->netdev;
 	iq->dev = &oct->pdev->dev;
 	iq->q_no = q_no;
+	iq->stats = &oct->stats_iq[q_no];
 	iq->max_count = CFG_GET_IQ_NUM_DESC(oct->conf);
 	iq->ring_size_mask = iq->max_count - 1;
 	iq->fill_threshold = CFG_GET_IQ_DB_MIN(oct->conf);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h
@@ -170,8 +170,8 @@
 	 */
 	u16 flush_index;
 
-	/* Statistics for this input queue. */
-	struct octep_iq_stats stats;
+	/* Pointer to statistics for this input queue. */
+	struct octep_iq_stats *stats;
 
 	/* Pointer to the Virtual Base addr of the input ring. */
 	struct octep_tx_desc_hw *desc_ring;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
@@ -24,6 +24,8 @@
 #define DRV_NAME	"Marvell-CGX/RPM"
 #define DRV_STRING      "Marvell CGX/RPM Driver"
 
+#define CGX_RX_STAT_GLOBAL_INDEX	9
+
 static LIST_HEAD(cgx_list);
 
 /* Convert firmware speed encoding to user format(Mbps) */
@@ -110,6 +112,11 @@
 	return ((struct cgx *)cgxd)->mac_ops;
 }
 
+u32 cgx_get_fifo_len(void *cgxd)
+{
+	return ((struct cgx *)cgxd)->fifo_len;
+}
+
 void cgx_write(struct cgx *cgx, u64 lmac, u64 offset, u64 val)
 {
 	writeq(val, cgx->reg_base + (lmac << cgx->mac_ops->lmac_offset) +
@@ -207,6 +214,24 @@
 	return (cfg & CMR_P2X_SEL_MASK) >> CMR_P2X_SEL_SHIFT;
 }
 
+static u8 cgx_get_nix_resetbit(struct cgx *cgx)
+{
+	int first_lmac;
+	u8 p2x;
+
+	/* non 98XX silicons supports only NIX0 block */
+	if (cgx->pdev->subsystem_device != PCI_SUBSYS_DEVID_98XX)
+		return CGX_NIX0_RESET;
+
+	first_lmac = find_first_bit(&cgx->lmac_bmap, cgx->max_lmac_per_mac);
+	p2x = cgx_lmac_get_p2x(cgx->cgx_id, first_lmac);
+
+	if (p2x == CMR_P2X_SEL_NIX1)
+		return CGX_NIX1_RESET;
+	else
+		return CGX_NIX0_RESET;
+}
+
 /* Ensure the required lock for event queue(where asynchronous events are
  * posted) is acquired before calling this API. Else an asynchronous event(with
  * latest link status) can reach the destination before this function returns
@@ -499,7 +524,7 @@
 	u8 num_lmacs;
 	u32 fifo_len;
 
-	fifo_len = cgx->mac_ops->fifo_len;
+	fifo_len = cgx->fifo_len;
 	num_lmacs = cgx->mac_ops->get_nr_lmacs(cgx);
 
 	switch (num_lmacs) {
@@ -701,6 +726,30 @@
 	return ((struct cgx *)cgxd)->hw_features;
 }
 
+int cgx_stats_reset(void *cgxd, int lmac_id)
+{
+	struct cgx *cgx = cgxd;
+	int stat_id;
+
+	if (!is_lmac_valid(cgx, lmac_id))
+		return -ENODEV;
+
+	for (stat_id = 0 ; stat_id < CGX_RX_STATS_COUNT; stat_id++) {
+		if (stat_id >= CGX_RX_STAT_GLOBAL_INDEX)
+		/* pass lmac as 0 for CGX_CMR_RX_STAT9-12 */
+			cgx_write(cgx, 0,
+				  (CGXX_CMRX_RX_STAT0 + (stat_id * 8)), 0);
+		else
+			cgx_write(cgx, lmac_id,
+				  (CGXX_CMRX_RX_STAT0 + (stat_id * 8)), 0);
+	}
+
+	for (stat_id = 0 ; stat_id < CGX_TX_STATS_COUNT; stat_id++)
+		cgx_write(cgx, lmac_id, CGXX_CMRX_TX_STAT0 + (stat_id * 8), 0);
+
+	return 0;
+}
+
 static int cgx_set_fec_stats_count(struct cgx_link_user_info *linfo)
 {
 	if (!linfo->fec)
@@ -808,6 +857,11 @@
 	if (!is_lmac_valid(cgx, lmac_id))
 		return -ENODEV;
 
+	cfg = cgx_read(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL);
+	cfg &= ~CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK;
+	cfg |= rx_pause ? CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK : 0x0;
+	cgx_write(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL, cfg);
+
 	cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL);
 	cfg &= ~CGX_SMUX_RX_FRM_CTL_CTL_BCK;
 	cfg |= rx_pause ? CGX_SMUX_RX_FRM_CTL_CTL_BCK : 0x0;
@@ -1338,7 +1392,7 @@
 
 		/* Release thread waiting for completion  */
 		lmac->cmd_pend = false;
-		wake_up_interruptible(&lmac->wq_cmd_cmplt);
+		wake_up(&lmac->wq_cmd_cmplt);
 		break;
 	case CGX_EVT_ASYNC:
 		if (cgx_event_is_linkevent(event))
@@ -1688,6 +1742,8 @@
 		lmac->lmac_type = cgx->mac_ops->get_lmac_type(cgx, lmac->lmac_id);
 	}
 
+	/* Start X2P reset on given MAC block */
+	cgx->mac_ops->mac_x2p_reset(cgx, true);
 	return cgx_lmac_verify_fwi_version(cgx);
 
 err_bitmap_free:
@@ -1733,7 +1789,7 @@
 	u64 cfg;
 
 	cfg = cgx_read(cgx, 0, CGX_CONST);
-	cgx->mac_ops->fifo_len = FIELD_GET(CGX_CONST_RXFIFO_SIZE, cfg);
+	cgx->fifo_len = FIELD_GET(CGX_CONST_RXFIFO_SIZE, cfg);
 	cgx->max_lmac_per_mac = FIELD_GET(CGX_CONST_MAX_LMACS, cfg);
 
 	if (is_dev_rpm(cgx))
@@ -1753,6 +1809,45 @@
 		return 0x60;
 }
 
+static void cgx_x2p_reset(void *cgxd, bool enable)
+{
+	struct cgx *cgx = cgxd;
+	int lmac_id;
+	u64 cfg;
+
+	if (enable) {
+		for_each_set_bit(lmac_id, &cgx->lmac_bmap, cgx->max_lmac_per_mac)
+			cgx->mac_ops->mac_enadis_rx(cgx, lmac_id, false);
+
+		usleep_range(1000, 2000);
+
+		cfg = cgx_read(cgx, 0, CGXX_CMR_GLOBAL_CONFIG);
+		cfg |= cgx_get_nix_resetbit(cgx) | CGX_NSCI_DROP;
+		cgx_write(cgx, 0, CGXX_CMR_GLOBAL_CONFIG, cfg);
+	} else {
+		cfg = cgx_read(cgx, 0, CGXX_CMR_GLOBAL_CONFIG);
+		cfg &= ~(cgx_get_nix_resetbit(cgx) | CGX_NSCI_DROP);
+		cgx_write(cgx, 0, CGXX_CMR_GLOBAL_CONFIG, cfg);
+	}
+}
+
+static int cgx_enadis_rx(void *cgxd, int lmac_id, bool enable)
+{
+	struct cgx *cgx = cgxd;
+	u64 cfg;
+
+	if (!is_lmac_valid(cgx, lmac_id))
+		return -ENODEV;
+
+	cfg = cgx_read(cgx, lmac_id, CGXX_CMRX_CFG);
+	if (enable)
+		cfg |= DATA_PKT_RX_EN;
+	else
+		cfg &= ~DATA_PKT_RX_EN;
+	cgx_write(cgx, lmac_id, CGXX_CMRX_CFG, cfg);
+	return 0;
+}
+
 static struct mac_ops	cgx_mac_ops    = {
 	.name		=       "cgx",
 	.csr_offset	=       0,
@@ -1783,6 +1878,9 @@
 	.pfc_config =                   cgx_lmac_pfc_config,
 	.mac_get_pfc_frm_cfg   =        cgx_lmac_get_pfc_frm_cfg,
 	.mac_reset   =			cgx_lmac_reset,
+	.mac_stats_reset       =	cgx_stats_reset,
+	.mac_x2p_reset                   =      cgx_x2p_reset,
+	.mac_enadis_rx			 =      cgx_enadis_rx,
 };
 
 static int cgx_probe(struct pci_dev *pdev, const struct pci_device_id *id)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/cgx.h
@@ -32,6 +32,10 @@
 #define CGX_LMAC_TYPE_MASK		0xF
 #define CGXX_CMRX_INT			0x040
 #define FW_CGX_INT			BIT_ULL(1)
+#define CGXX_CMR_GLOBAL_CONFIG          0x08
+#define CGX_NIX0_RESET			BIT_ULL(2)
+#define CGX_NIX1_RESET			BIT_ULL(3)
+#define CGX_NSCI_DROP			BIT_ULL(9)
 #define CGXX_CMRX_INT_ENA_W1S		0x058
 #define CGXX_CMRX_RX_ID_MAP		0x060
 #define CGXX_CMRX_RX_STAT0		0x070
@@ -141,6 +145,7 @@
 int cgx_lmac_evh_unregister(void *cgxd, int lmac_id);
 int cgx_get_tx_stats(void *cgxd, int lmac_id, int idx, u64 *tx_stat);
 int cgx_get_rx_stats(void *cgxd, int lmac_id, int idx, u64 *rx_stat);
+int cgx_stats_reset(void *cgxd, int lmac_id);
 int cgx_lmac_rx_tx_enable(void *cgxd, int lmac_id, bool enable);
 int cgx_lmac_tx_enable(void *cgxd, int lmac_id, bool enable);
 int cgx_lmac_addr_set(u8 cgx_id, u8 lmac_id, u8 *mac_addr);
@@ -184,4 +189,5 @@
 int verify_lmac_fc_cfg(void *cgxd, int lmac_id, u8 tx_pause, u8 rx_pause,
 		       int pfvf_idx);
 int cgx_lmac_reset(void *cgxd, int lmac_id, u8 pf_req_flr);
+u32 cgx_get_fifo_len(void *cgxd);
 #endif /* CGX_H */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/lmac_common.h
@@ -72,7 +72,6 @@
 	u8			irq_offset;
 	u8			int_ena_bit;
 	u8			lmac_fwi;
-	u32			fifo_len;
 	bool			non_contiguous_serdes_lane;
 	/* RPM & CGX differs in number of Receive/transmit stats */
 	u8			rx_stats_cnt;
@@ -132,6 +131,9 @@
 	/* FEC stats */
 	int			(*get_fec_stats)(void *cgxd, int lmac_id,
 						 struct cgx_fec_stats_rsp *rsp);
+	int			(*mac_stats_reset)(void *cgxd, int lmac_id);
+	void                    (*mac_x2p_reset)(void *cgxd, bool enable);
+	int			(*mac_enadis_rx)(void *cgxd, int lmac_id, bool enable);
 };
 
 struct cgx {
@@ -141,6 +143,10 @@
 	u8			lmac_count;
 	/* number of LMACs per MAC could be 4 or 8 */
 	u8			max_lmac_per_mac;
+	/* length of fifo varies depending on the number
+	 * of LMACS
+	 */
+	u32			fifo_len;
 #define MAX_LMAC_COUNT		8
 	struct lmac             *lmac_idmap[MAX_LMAC_COUNT];
 	struct			work_struct cgx_cmd_work;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/mbox.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/mbox.c
@@ -214,11 +214,12 @@
 }
 EXPORT_SYMBOL(otx2_mbox_busy_poll_for_rsp);
 
-void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid)
+static void otx2_mbox_msg_send_data(struct otx2_mbox *mbox, int devid, u64 data)
 {
 	struct otx2_mbox_dev *mdev = &mbox->dev[devid];
 	struct mbox_hdr *tx_hdr, *rx_hdr;
 	void *hw_mbase = mdev->hwbase;
+	u64 intr_val;
 
 	tx_hdr = hw_mbase + mbox->tx_start;
 	rx_hdr = hw_mbase + mbox->rx_start;
@@ -254,14 +255,52 @@
 
 	spin_unlock(&mdev->mbox_lock);
 
+	/* Check if interrupt pending */
+	intr_val = readq((void __iomem *)mbox->reg_base +
+		     (mbox->trigger | (devid << mbox->tr_shift)));
+
+	intr_val |= data;
 	/* The interrupt should be fired after num_msgs is written
 	 * to the shared memory
 	 */
-	writeq(1, (void __iomem *)mbox->reg_base +
+	writeq(intr_val, (void __iomem *)mbox->reg_base +
 	       (mbox->trigger | (devid << mbox->tr_shift)));
 }
+
+void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid)
+{
+	otx2_mbox_msg_send_data(mbox, devid, MBOX_DOWN_MSG);
+}
 EXPORT_SYMBOL(otx2_mbox_msg_send);
 
+void otx2_mbox_msg_send_up(struct otx2_mbox *mbox, int devid)
+{
+	otx2_mbox_msg_send_data(mbox, devid, MBOX_UP_MSG);
+}
+EXPORT_SYMBOL(otx2_mbox_msg_send_up);
+
+bool otx2_mbox_wait_for_zero(struct otx2_mbox *mbox, int devid)
+{
+	u64 data;
+
+	data = readq((void __iomem *)mbox->reg_base +
+		     (mbox->trigger | (devid << mbox->tr_shift)));
+
+	/* If data is non-zero wait for ~1ms and return to caller
+	 * whether data has changed to zero or not after the wait.
+	 */
+	if (!data)
+		return true;
+
+	usleep_range(950, 1000);
+
+	data = readq((void __iomem *)mbox->reg_base +
+		     (mbox->trigger | (devid << mbox->tr_shift)));
+
+	return data == 0;
+}
+EXPORT_SYMBOL(otx2_mbox_wait_for_zero);
+
 struct mbox_msghdr *otx2_mbox_alloc_msg_rsp(struct otx2_mbox *mbox, int devid,
 					    int size, int size_rsp)
 {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -16,6 +16,9 @@
 
 #define MBOX_SIZE		SZ_64K
 
+#define MBOX_DOWN_MSG		1
+#define MBOX_UP_MSG		2
+
 /* AF/PF: PF initiated, PF/VF VF initiated */
 #define MBOX_DOWN_RX_START	0
 #define MBOX_DOWN_RX_SIZE	(46 * SZ_1K)
@@ -101,6 +104,7 @@
 			   struct pci_dev *pdev, void __force *reg_base,
 			   int direction, int ndevs, unsigned long *bmap);
 void otx2_mbox_msg_send(struct otx2_mbox *mbox, int devid);
+void otx2_mbox_msg_send_up(struct otx2_mbox *mbox, int devid);
 int otx2_mbox_wait_for_rsp(struct otx2_mbox *mbox, int devid);
 int otx2_mbox_busy_poll_for_rsp(struct otx2_mbox *mbox, int devid);
 struct mbox_msghdr *otx2_mbox_alloc_msg_rsp(struct otx2_mbox *mbox, int devid,
@@ -118,6 +122,8 @@
 	return otx2_mbox_alloc_msg_rsp(mbox, devid, size, 0);
 }
 
+bool otx2_mbox_wait_for_zero(struct otx2_mbox *mbox, int devid);
+
 /* Mailbox message types */
 #define MBOX_MSG_MASK				0xFFFF
 #define MBOX_MSG_INVALID			0xFFFE
@@ -168,6 +174,7 @@
 M(CGX_SET_LINK_MODE,	0x218, cgx_set_link_mode, cgx_set_link_mode_req,\
 			       cgx_set_link_mode_rsp)	\
 M(CGX_GET_PHY_FEC_STATS, 0x219, cgx_get_phy_fec_stats, msg_req, msg_rsp) \
+M(CGX_STATS_RST,	0x21A, cgx_stats_rst, msg_req, msg_rsp)		\
 M(CGX_FEATURES_GET,	0x21B, cgx_features_get, msg_req,		\
 			       cgx_features_info_msg)			\
 M(RPM_STATS,		0x21C, rpm_stats, msg_req, rpm_stats_rsp)	\
@@ -1736,7 +1743,7 @@
 	u16 nix_pf_func;
 	u16 sso_pf_func;
 	u16 eng_grpmsk;
-	int blkaddr;
+	u8 blkaddr;
 	u8 ctx_ilen_valid : 1;
 	u8 ctx_ilen : 7;
 };
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c
@@ -121,13 +121,17 @@
 static int mcs_notify_pfvf(struct mcs_intr_event *event, struct rvu *rvu)
 {
 	struct mcs_intr_info *req;
-	int err, pf;
+	int pf;
 
 	pf = rvu_get_pf(event->pcifunc);
 
+	mutex_lock(&rvu->mbox_lock);
+
 	req = otx2_mbox_alloc_msg_mcs_intr_notify(rvu, pf);
-	if (!req)
+	if (!req) {
+		mutex_unlock(&rvu->mbox_lock);
 		return -ENOMEM;
+	}
 
 	req->mcs_id = event->mcs_id;
 	req->intr_mask = event->intr_mask;
@@ -135,10 +139,11 @@
 	req->hdr.pcifunc = event->pcifunc;
 	req->lmac_id = event->lmac_id;
 
-	otx2_mbox_msg_send(&rvu->afpf_wq_info.mbox_up, pf);
-	err = otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, pf);
-	if (err)
-		dev_warn(rvu->dev, "MCS notification to pf %d failed\n", pf);
+	otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pf);
+
+	otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf);
+
+	mutex_unlock(&rvu->mbox_lock);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/npc.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/npc.h
@@ -63,8 +63,13 @@
 	NPC_LT_LB_CUSTOM1 = 0xF,
 };
 
+/* Don't modify ltypes up to IP6_EXT, otherwise length and checksum of IP
+ * headers may not be checked correctly. IPv4 ltypes and IPv6 ltypes must
+ * differ only at bit 0 so mask 0xE can be used to detect extended headers.
+ */
 enum npc_kpu_lc_ltype {
-	NPC_LT_LC_IP = 1,
+	NPC_LT_LC_PTP = 1,
+	NPC_LT_LC_IP,
 	NPC_LT_LC_IP_OPT,
 	NPC_LT_LC_IP6,
 	NPC_LT_LC_IP6_EXT,
@@ -72,7 +77,6 @@
 	NPC_LT_LC_RARP,
 	NPC_LT_LC_MPLS,
 	NPC_LT_LC_NSH,
-	NPC_LT_LC_PTP,
 	NPC_LT_LC_FCOE,
 	NPC_LT_LC_NGIO,
 	NPC_LT_LC_CUSTOM0 = 0xE,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/rpm.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/rpm.c
@@ -38,6 +38,9 @@
 	.pfc_config =                   rpm_lmac_pfc_config,
 	.mac_get_pfc_frm_cfg   =        rpm_lmac_get_pfc_frm_cfg,
 	.mac_reset   =			rpm_lmac_reset,
+	.mac_stats_reset		 =	  rpm_stats_reset,
+	.mac_x2p_reset                   =        rpm_x2p_reset,
+	.mac_enadis_rx			 =        rpm_enadis_rx,
 };
 
 static struct mac_ops		rpm2_mac_ops   = {
@@ -70,6 +73,9 @@
 	.pfc_config =                   rpm_lmac_pfc_config,
 	.mac_get_pfc_frm_cfg   =        rpm_lmac_get_pfc_frm_cfg,
 	.mac_reset   =			rpm_lmac_reset,
+	.mac_stats_reset	    =	rpm_stats_reset,
+	.mac_x2p_reset              =   rpm_x2p_reset,
+	.mac_enadis_rx		    =   rpm_enadis_rx,
 };
 
 bool is_dev_rpm2(void *rpmd)
@@ -443,6 +449,21 @@
 	return 0;
 }
 
+int rpm_stats_reset(void *rpmd, int lmac_id)
+{
+	rpm_t *rpm = rpmd;
+	u64 cfg;
+
+	if (!is_lmac_valid(rpm, lmac_id))
+		return -ENODEV;
+
+	cfg = rpm_read(rpm, 0, RPMX_MTI_STAT_STATN_CONTROL);
+	cfg |= RPMX_CMD_CLEAR_TX | RPMX_CMD_CLEAR_RX | BIT_ULL(lmac_id);
+	rpm_write(rpm, 0, RPMX_MTI_STAT_STATN_CONTROL, cfg);
+
+	return 0;
+}
+
 u8 rpm_get_lmac_type(void *rpmd, int lmac_id)
 {
 	rpm_t *rpm = rpmd;
@@ -450,7 +471,7 @@
 	int err;
 
 	req = FIELD_SET(CMDREG_ID, CGX_CMD_GET_LINK_STS, req);
-	err = cgx_fwi_cmd_generic(req, &resp, rpm, 0);
+	err = cgx_fwi_cmd_generic(req, &resp, rpm, lmac_id);
 	if (!err)
 		return FIELD_GET(RESP_LINKSTAT_LMAC_TYPE, resp);
 	return err;
@@ -463,7 +484,7 @@
 	u8 num_lmacs;
 	u32 fifo_len;
 
-	fifo_len = rpm->mac_ops->fifo_len;
+	fifo_len = rpm->fifo_len;
 	num_lmacs = rpm->mac_ops->get_nr_lmacs(rpm);
 
 	switch (num_lmacs) {
@@ -516,9 +537,9 @@
 	 */
 	max_lmac = (rpm_read(rpm, 0, CGX_CONST) >> 24) & 0xFF;
 	if (max_lmac > 4)
-		fifo_len = rpm->mac_ops->fifo_len / 2;
+		fifo_len = rpm->fifo_len / 2;
 	else
-		fifo_len = rpm->mac_ops->fifo_len;
+		fifo_len = rpm->fifo_len;
 
 	if (lmac_id < 4) {
 		num_lmacs = hweight8(lmac_info & 0xF);
@@ -682,46 +703,51 @@
 	if (rpm->lmac_idmap[lmac_id]->link_info.fec == OTX2_FEC_NONE)
 		return 0;
 
+	/* latched registers FCFECX_CW_HI/RSFEC_STAT_FAST_DATA_HI_CDC are common
+	 * for all counters. Acquire lock to ensure serialized reads
+	 */
+	mutex_lock(&rpm->lock);
 	if (rpm->lmac_idmap[lmac_id]->link_info.fec == OTX2_FEC_BASER) {
-		val_lo = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_VL0_CCW_LO);
-		val_hi = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_CW_HI);
+		val_lo = rpm_read(rpm, 0, RPMX_MTI_FCFECX_VL0_CCW_LO(lmac_id));
+		val_hi = rpm_read(rpm, 0, RPMX_MTI_FCFECX_CW_HI(lmac_id));
 		rsp->fec_corr_blks = (val_hi << 16 | val_lo);
 
-		val_lo = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_VL0_NCCW_LO);
-		val_hi = rpm_read(rpm, lmac_id, RPMX_MTI_FCFECX_CW_HI);
+		val_lo = rpm_read(rpm, 0, RPMX_MTI_FCFECX_VL0_NCCW_LO(lmac_id));
+		val_hi = rpm_read(rpm, 0, RPMX_MTI_FCFECX_CW_HI(lmac_id));
 		rsp->fec_uncorr_blks = (val_hi << 16 | val_lo);
 
 		/* 50G uses 2 Physical serdes lines */
 		if (rpm->lmac_idmap[lmac_id]->link_info.lmac_type_id ==
 		    LMAC_MODE_50G_R) {
-			val_lo = rpm_read(rpm, lmac_id,
-					  RPMX_MTI_FCFECX_VL1_CCW_LO);
-			val_hi = rpm_read(rpm, lmac_id,
-					  RPMX_MTI_FCFECX_CW_HI);
+			val_lo = rpm_read(rpm, 0,
+					  RPMX_MTI_FCFECX_VL1_CCW_LO(lmac_id));
+			val_hi = rpm_read(rpm, 0,
+					  RPMX_MTI_FCFECX_CW_HI(lmac_id));
 			rsp->fec_corr_blks += (val_hi << 16 | val_lo);
 
-			val_lo = rpm_read(rpm, lmac_id,
-					  RPMX_MTI_FCFECX_VL1_NCCW_LO);
-			val_hi = rpm_read(rpm, lmac_id,
-					  RPMX_MTI_FCFECX_CW_HI);
+			val_lo = rpm_read(rpm, 0,
+					  RPMX_MTI_FCFECX_VL1_NCCW_LO(lmac_id));
+			val_hi = rpm_read(rpm, 0,
+					  RPMX_MTI_FCFECX_CW_HI(lmac_id));
 			rsp->fec_uncorr_blks += (val_hi << 16 | val_lo);
 		}
 	} else {
 		/* enable RS-FEC capture */
-		cfg = rpm_read(rpm, 0, RPMX_MTI_STAT_STATN_CONTROL);
+		cfg = rpm_read(rpm, 0, RPMX_MTI_RSFEC_STAT_STATN_CONTROL);
 		cfg |= RPMX_RSFEC_RX_CAPTURE | BIT(lmac_id);
-		rpm_write(rpm, 0, RPMX_MTI_STAT_STATN_CONTROL, cfg);
+		rpm_write(rpm, 0, RPMX_MTI_RSFEC_STAT_STATN_CONTROL, cfg);
 
 		val_lo = rpm_read(rpm, 0,
 				  RPMX_MTI_RSFEC_STAT_COUNTER_CAPTURE_2);
-		val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC);
+		val_hi = rpm_read(rpm, 0, RPMX_MTI_RSFEC_STAT_FAST_DATA_HI_CDC);
 		rsp->fec_corr_blks = (val_hi << 32 | val_lo);
 
 		val_lo = rpm_read(rpm, 0,
 				  RPMX_MTI_RSFEC_STAT_COUNTER_CAPTURE_3);
-		val_hi = rpm_read(rpm, 0, RPMX_MTI_STAT_DATA_HI_CDC);
+		val_hi = rpm_read(rpm, 0, RPMX_MTI_RSFEC_STAT_FAST_DATA_HI_CDC);
 		rsp->fec_uncorr_blks = (val_hi << 32 | val_lo);
 	}
+	mutex_unlock(&rpm->lock);
 
 	return 0;
 }
@@ -746,3 +772,41 @@
 
 	return 0;
 }
+
+void rpm_x2p_reset(void *rpmd, bool enable)
+{
+	rpm_t *rpm = rpmd;
+	int lmac_id;
+	u64 cfg;
+
+	if (enable) {
+		for_each_set_bit(lmac_id, &rpm->lmac_bmap, rpm->max_lmac_per_mac)
+			rpm->mac_ops->mac_enadis_rx(rpm, lmac_id, false);
+
+		usleep_range(1000, 2000);
+
+		cfg = rpm_read(rpm, 0, RPMX_CMR_GLOBAL_CFG);
+		rpm_write(rpm, 0, RPMX_CMR_GLOBAL_CFG, cfg | RPM_NIX0_RESET);
+	} else {
+		cfg = rpm_read(rpm, 0, RPMX_CMR_GLOBAL_CFG);
+		cfg &= ~RPM_NIX0_RESET;
+		rpm_write(rpm, 0, RPMX_CMR_GLOBAL_CFG, cfg);
+	}
+}
+
+int rpm_enadis_rx(void *rpmd, int lmac_id, bool enable)
+{
+	rpm_t *rpm = rpmd;
+	u64 cfg;
+
+	if (!is_lmac_valid(rpm, lmac_id))
+		return -ENODEV;
+
+	cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG);
+	if (enable)
+		cfg |= RPM_RX_EN;
+	else
+		cfg &= ~RPM_RX_EN;
+	rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg);
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/rpm.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/rpm.h
@@ -17,6 +17,8 @@
 
 /* Registers */
 #define RPMX_CMRX_CFG			0x00
+#define RPMX_CMR_GLOBAL_CFG		0x08
+#define RPM_NIX0_RESET			BIT_ULL(3)
 #define RPMX_RX_TS_PREPEND              BIT_ULL(22)
 #define RPMX_TX_PTP_1S_SUPPORT          BIT_ULL(17)
 #define RPMX_CMRX_RX_ID_MAP		0x80
@@ -84,14 +86,18 @@
 /* FEC stats */
 #define RPMX_MTI_STAT_STATN_CONTROL			0x10018
 #define RPMX_MTI_STAT_DATA_HI_CDC			0x10038
-#define RPMX_RSFEC_RX_CAPTURE				BIT_ULL(27)
+#define RPMX_RSFEC_RX_CAPTURE				BIT_ULL(28)
+#define RPMX_CMD_CLEAR_RX				BIT_ULL(30)
+#define RPMX_CMD_CLEAR_TX				BIT_ULL(31)
+#define RPMX_MTI_RSFEC_STAT_STATN_CONTROL               0x40018
+#define RPMX_MTI_RSFEC_STAT_FAST_DATA_HI_CDC            0x40000
 #define RPMX_MTI_RSFEC_STAT_COUNTER_CAPTURE_2		0x40050
 #define RPMX_MTI_RSFEC_STAT_COUNTER_CAPTURE_3		0x40058
-#define RPMX_MTI_FCFECX_VL0_CCW_LO			0x38618
-#define RPMX_MTI_FCFECX_VL0_NCCW_LO			0x38620
-#define RPMX_MTI_FCFECX_VL1_CCW_LO			0x38628
-#define RPMX_MTI_FCFECX_VL1_NCCW_LO			0x38630
-#define RPMX_MTI_FCFECX_CW_HI				0x38638
+#define RPMX_MTI_FCFECX_VL0_CCW_LO(a)			(0x38618 + ((a) * 0x40))
+#define RPMX_MTI_FCFECX_VL0_NCCW_LO(a)			(0x38620 + ((a) * 0x40))
+#define RPMX_MTI_FCFECX_VL1_CCW_LO(a)			(0x38628 + ((a) * 0x40))
+#define RPMX_MTI_FCFECX_VL1_NCCW_LO(a)			(0x38630 + ((a) * 0x40))
+#define RPMX_MTI_FCFECX_CW_HI(a)			(0x38638 + ((a) * 0x40))
 
 /* CN10KB CSR Declaration */
 #define  RPM2_CMRX_SW_INT				0x1b0
@@ -134,4 +140,7 @@
 bool is_dev_rpm2(void *rpmd);
 int rpm_get_fec_stats(void *cgxd, int lmac_id, struct cgx_fec_stats_rsp *rsp);
 int rpm_lmac_reset(void *rpmd, int lmac_id, u8 pf_req_flr);
+int rpm_stats_reset(void *rpmd, int lmac_id);
+void rpm_x2p_reset(void *rpmd, bool enable);
+int rpm_enadis_rx(void *rpmd, int lmac_id, bool enable);
 #endif /* RPM_H */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
@@ -1160,6 +1160,7 @@
 	}
 
 	rvu_program_channels(rvu);
+	cgx_start_linkup(rvu);
 
 	err = rvu_mcs_init(rvu);
 	if (err) {
@@ -1641,7 +1642,7 @@
 		if (req->ssow > block->lf.max) {
 			dev_err(&rvu->pdev->dev,
 				"Func 0x%x: Invalid SSOW req, %d > max %d\n",
-				 pcifunc, req->sso, block->lf.max);
+				 pcifunc, req->ssow, block->lf.max);
 			return -EINVAL;
 		}
 		mappedlfs = rvu_get_rsrc_mapcount(pfvf, block->addr);
@@ -2117,7 +2118,7 @@
 	}
 }
 
-static void __rvu_mbox_handler(struct rvu_work *mwork, int type)
+static void __rvu_mbox_handler(struct rvu_work *mwork, int type, bool poll)
 {
 	struct rvu *rvu = mwork->rvu;
 	int offset, err, id, devid;
@@ -2184,6 +2185,9 @@
 	}
 	mw->mbox_wrk[devid].num_msgs = 0;
 
+	if (poll)
+		otx2_mbox_wait_for_zero(mbox, devid);
+
 	/* Send mbox responses to VF/PF */
 	otx2_mbox_msg_send(mbox, devid);
 }
@@ -2191,15 +2195,18 @@
 static inline void rvu_afpf_mbox_handler(struct work_struct *work)
 {
 	struct rvu_work *mwork = container_of(work, struct rvu_work, work);
+	struct rvu *rvu = mwork->rvu;
 
-	__rvu_mbox_handler(mwork, TYPE_AFPF);
+	mutex_lock(&rvu->mbox_lock);
+	__rvu_mbox_handler(mwork, TYPE_AFPF, true);
+	mutex_unlock(&rvu->mbox_lock);
 }
 
 static inline void rvu_afvf_mbox_handler(struct work_struct *work)
 {
 	struct rvu_work *mwork = container_of(work, struct rvu_work, work);
 
-	__rvu_mbox_handler(mwork, TYPE_AFVF);
+	__rvu_mbox_handler(mwork, TYPE_AFVF, false);
 }
 
 static void __rvu_mbox_up_handler(struct rvu_work *mwork, int type)
@@ -2374,6 +2381,8 @@
 		}
 	}
 
+	mutex_init(&rvu->mbox_lock);
+
 	mbox_regions = kcalloc(num, sizeof(void *), GFP_KERNEL);
 	if (!mbox_regions) {
 		err = -ENOMEM;
@@ -2523,10 +2532,9 @@
 	}
 }
 
-static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
+static irqreturn_t rvu_mbox_pf_intr_handler(int irq, void *rvu_irq)
 {
 	struct rvu *rvu = (struct rvu *)rvu_irq;
-	int vfs = rvu->vfs;
 	u64 intr;
 
 	intr = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_PFAF_MBOX_INT);
@@ -2540,6 +2548,18 @@
 
 	rvu_queue_work(&rvu->afpf_wq_info, 0, rvu->hw->total_pfs, intr);
 
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t rvu_mbox_intr_handler(int irq, void *rvu_irq)
+{
+	struct rvu *rvu = (struct rvu *)rvu_irq;
+	int vfs = rvu->vfs;
+	u64 intr;
+
+	/* Sync with mbox memory region */
+	rmb();
+
 	/* Handle VF interrupts */
 	if (vfs > 64) {
 		intr = rvupf_read64(rvu, RVU_PF_VFPF_MBOX_INTX(1));
@@ -2881,7 +2901,7 @@
 	/* Register mailbox interrupt handler */
 	sprintf(&rvu->irq_name[RVU_AF_INT_VEC_MBOX * NAME_SIZE], "RVUAF Mbox");
 	ret = request_irq(pci_irq_vector(rvu->pdev, RVU_AF_INT_VEC_MBOX),
-			  rvu_mbox_intr_handler, 0,
+			  rvu_mbox_pf_intr_handler, 0,
 			  &rvu->irq_name[RVU_AF_INT_VEC_MBOX * NAME_SIZE], rvu);
 	if (ret) {
 		dev_err(rvu->dev,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -308,6 +308,7 @@
 
 /* smq(flush) to tl1 cir/pir info */
 struct nix_smq_tree_ctx {
+	u16 schq;
 	u64 cir_off;
 	u64 cir_val;
 	u64 pir_off;
@@ -317,8 +318,6 @@
 /* smq flush context */
 struct nix_smq_flush_ctx {
 	int smq;
-	u16 tl1_schq;
-	u16 tl2_schq;
 	struct nix_smq_tree_ctx smq_tree_ctx[NIX_TXSCH_LVL_CNT];
 };
 
@@ -570,6 +569,8 @@
 	spinlock_t		mcs_intrq_lock;
 	/* CPT interrupt lock */
 	spinlock_t		cpt_intr_lock;
+
+	struct mutex		mbox_lock; /* Serialize mbox up and down msgs */
 };
 
 static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val)
@@ -940,6 +941,7 @@
 int rvu_cgx_cfg_pause_frm(struct rvu *rvu, u16 pcifunc, u8 tx_pause, u8 rx_pause);
 void rvu_mac_reset(struct rvu *rvu, u16 pcifunc);
 u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac);
+void cgx_start_linkup(struct rvu *rvu);
 int npc_get_nixlf_mcam_index(struct npc_mcam *mcam, u16 pcifunc, int nixlf,
 			     int type);
 bool is_mcam_entry_enabled(struct rvu *rvu, struct npc_mcam *mcam, int blkaddr,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c
@@ -160,6 +160,8 @@
 			continue;
 		lmac_bmap = cgx_get_lmac_bmap(rvu_cgx_pdata(cgx, rvu));
 		for_each_set_bit(iter, &lmac_bmap, rvu->hw->lmac_per_cgx) {
+			if (iter >= MAX_LMAC_COUNT)
+				continue;
 			lmac = cgx_get_lmacid(rvu_cgx_pdata(cgx, rvu),
 					      iter);
 			rvu->pf2cgxlmac_map[pf] = cgxlmac_id_to_bmap(cgx, lmac);
@@ -232,7 +234,7 @@
 	struct cgx_link_user_info *linfo;
 	struct cgx_link_info_msg *msg;
 	unsigned long pfmap;
-	int err, pfid;
+	int pfid;
 
 	linfo = &event->link_uinfo;
 	pfmap = cgxlmac_to_pfmap(rvu, event->cgx_id, event->lmac_id);
@@ -255,16 +257,22 @@
 			continue;
 		}
 
+		mutex_lock(&rvu->mbox_lock);
+
 		/* Send mbox message to PF */
 		msg = otx2_mbox_alloc_msg_cgx_link_event(rvu, pfid);
-		if (!msg)
+		if (!msg) {
+			mutex_unlock(&rvu->mbox_lock);
 			continue;
+		}
+
 		msg->link_info = *linfo;
-		otx2_mbox_msg_send(&rvu->afpf_wq_info.mbox_up, pfid);
-		err = otx2_mbox_wait_for_rsp(&rvu->afpf_wq_info.mbox_up, pfid);
-		if (err)
-			dev_warn(rvu->dev, "notification to pf %d failed\n",
-				 pfid);
+
+		otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pfid);
+
+		otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pfid);
+
+		mutex_unlock(&rvu->mbox_lock);
 	} while (pfmap);
 }
 
@@ -341,6 +349,7 @@
 
 int rvu_cgx_init(struct rvu *rvu)
 {
+	struct mac_ops *mac_ops;
 	int cgx, err;
 	void *cgxd;
 
@@ -367,6 +376,15 @@
 	if (err)
 		return err;
 
+	/* Clear X2P reset on all MAC blocks */
+	for (cgx = 0; cgx < rvu->cgx_cnt_max; cgx++) {
+		cgxd = rvu_cgx_pdata(cgx, rvu);
+		if (!cgxd)
+			continue;
+		mac_ops = get_mac_ops(cgxd);
+		mac_ops->mac_x2p_reset(cgxd, false);
+	}
+
 	/* Register for CGX events */
 	err = cgx_lmac_event_handler_init(rvu);
 	if (err)
@@ -374,10 +392,26 @@
 
 	mutex_init(&rvu->cgx_cfg_lock);
 
-	/* Ensure event handler registration is completed, before
-	 * we turn on the links
-	 */
-	mb();
+	return 0;
+}
+
+void cgx_start_linkup(struct rvu *rvu)
+{
+	unsigned long lmac_bmap;
+	struct mac_ops *mac_ops;
+	int cgx, lmac, err;
+	void *cgxd;
+
+	/* Enable receive on all LMACS */
+	for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) {
+		cgxd = rvu_cgx_pdata(cgx, rvu);
+		if (!cgxd)
+			continue;
+		mac_ops = get_mac_ops(cgxd);
+		lmac_bmap = cgx_get_lmac_bmap(cgxd);
+		for_each_set_bit(lmac, &lmac_bmap, rvu->hw->lmac_per_cgx)
+			mac_ops->mac_enadis_rx(cgxd, lmac, true);
+	}
 
 	/* Do link up for all CGX ports */
 	for (cgx = 0; cgx <= rvu->cgx_cnt_max; cgx++) {
@@ -390,8 +424,6 @@
 				"Link up process failed to start on cgx %d\n",
 				cgx);
 	}
-
-	return 0;
 }
 
 int rvu_cgx_exit(struct rvu *rvu)
@@ -596,6 +628,35 @@
 	return rvu_lmac_get_stats(rvu, req, (void *)rsp);
 }
 
+int rvu_mbox_handler_cgx_stats_rst(struct rvu *rvu, struct msg_req *req,
+				   struct msg_rsp *rsp)
+{
+	int pf = rvu_get_pf(req->hdr.pcifunc);
+	struct rvu_pfvf	*parent_pf;
+	struct mac_ops *mac_ops;
+	u8 cgx_idx, lmac;
+	void *cgxd;
+
+	if (!is_cgx_config_permitted(rvu, req->hdr.pcifunc))
+		return LMAC_AF_ERR_PERM_DENIED;
+
+	parent_pf = &rvu->pf[pf];
+	/* To ensure reset cgx stats won't affect VF stats,
+	 *  check if it used by only PF interface.
+	 *  If not, return
+	 */
+	if (parent_pf->cgx_users > 1) {
+		dev_info(rvu->dev, "CGX busy, could not reset statistics\n");
+		return 0;
+	}
+
+	rvu_get_cgx_lmac_id(rvu->pf2cgxlmac_map[pf], &cgx_idx, &lmac);
+	cgxd = rvu_cgx_pdata(cgx_idx, rvu);
+	mac_ops = get_mac_ops(cgxd);
+
+	return mac_ops->mac_stats_reset(cgxd, lmac);
+}
+
 int rvu_mbox_handler_cgx_fec_stats(struct rvu *rvu,
 				   struct msg_req *req,
 				   struct cgx_fec_stats_rsp *rsp)
@@ -886,13 +947,12 @@
 
 u32 rvu_cgx_get_fifolen(struct rvu *rvu)
 {
-	struct mac_ops *mac_ops;
-	u32 fifo_len;
+	void *cgxd = rvu_first_cgx_pdata(rvu);
 
-	mac_ops = get_mac_ops(rvu_first_cgx_pdata(rvu));
-	fifo_len = mac_ops ? mac_ops->fifo_len : 0;
+	if (!cgxd)
+		return 0;
 
-	return fifo_len;
+	return cgx_get_fifo_len(cgxd);
 }
 
 u32 rvu_cgx_get_lmac_fifolen(struct rvu *rvu, int cgx, int lmac)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c
@@ -632,7 +632,9 @@
 	return ret;
 }
 
-static bool is_valid_offset(struct rvu *rvu, struct cpt_rd_wr_reg_msg *req)
+static bool validate_and_update_reg_offset(struct rvu *rvu,
+					   struct cpt_rd_wr_reg_msg *req,
+					   u64 *reg_offset)
 {
 	u64 offset = req->reg_offset;
 	int blkaddr, num_lfs, lf;
@@ -663,6 +665,11 @@
 		if (lf < 0)
 			return false;
 
+		/* Translate local LF's offset to global CPT LF's offset to
+		 * access LFX register.
+		 */
+		*reg_offset = (req->reg_offset & 0xFF000) + (lf << 3);
+
 		return true;
 	} else if (!(req->hdr.pcifunc & RVU_PFVF_FUNC_MASK)) {
 		/* Registers that can be accessed from PF */
@@ -696,6 +703,7 @@
 					struct cpt_rd_wr_reg_msg *req,
 					struct cpt_rd_wr_reg_msg *rsp)
 {
+	u64 offset = req->reg_offset;
 	int blkaddr;
 
 	blkaddr = validate_and_get_cpt_blkaddr(req->blkaddr);
@@ -707,17 +715,17 @@
 	    !is_cpt_vf(rvu, req->hdr.pcifunc))
 		return CPT_AF_ERR_ACCESS_DENIED;
 
+	if (!validate_and_update_reg_offset(rvu, req, &offset))
+		return CPT_AF_ERR_ACCESS_DENIED;
+
 	rsp->reg_offset = req->reg_offset;
 	rsp->ret_val = req->ret_val;
 	rsp->is_write = req->is_write;
 
-	if (!is_valid_offset(rvu, req))
-		return CPT_AF_ERR_ACCESS_DENIED;
-
 	if (req->is_write)
-		rvu_write64(rvu, blkaddr, req->reg_offset, req->val);
+		rvu_write64(rvu, blkaddr, offset, req->val);
 	else
-		rsp->val = rvu_read64(rvu, blkaddr, req->reg_offset);
+		rsp->val = rvu_read64(rvu, blkaddr, offset);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
@@ -999,12 +999,10 @@
 	u16 pcifunc;
 	int ret, lf;
 
-	cmd_buf = memdup_user(buffer, count + 1);
+	cmd_buf = memdup_user_nul(buffer, count);
 	if (IS_ERR(cmd_buf))
 		return -ENOMEM;
 
-	cmd_buf[count] = '\0';
-
 	cmd_buf_tmp = strchr(cmd_buf, '\n');
 	if (cmd_buf_tmp) {
 		*cmd_buf_tmp = '\0';
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
@@ -1235,8 +1235,8 @@
 enum rvu_af_dl_param_id {
 	RVU_AF_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
 	RVU_AF_DEVLINK_PARAM_ID_DWRR_MTU,
-	RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
 	RVU_AF_DEVLINK_PARAM_ID_NPC_MCAM_ZONE_PERCENT,
+	RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
 	RVU_AF_DEVLINK_PARAM_ID_NIX_MAXLF,
 };
 
@@ -1434,15 +1434,6 @@
 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
 			     rvu_af_dl_dwrr_mtu_get, rvu_af_dl_dwrr_mtu_set,
 			     rvu_af_dl_dwrr_mtu_validate),
-};
-
-static const struct devlink_param rvu_af_dl_param_exact_match[] = {
-	DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
-			     "npc_exact_feature_disable", DEVLINK_PARAM_TYPE_STRING,
-			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
-			     rvu_af_npc_exact_feature_get,
-			     rvu_af_npc_exact_feature_disable,
-			     rvu_af_npc_exact_feature_validate),
 	DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_MCAM_ZONE_PERCENT,
 			     "npc_mcam_high_zone_percent", DEVLINK_PARAM_TYPE_U8,
 			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
@@ -1457,6 +1448,15 @@
 			     rvu_af_dl_nix_maxlf_validate),
 };
 
+static const struct devlink_param rvu_af_dl_param_exact_match[] = {
+	DEVLINK_PARAM_DRIVER(RVU_AF_DEVLINK_PARAM_ID_NPC_EXACT_FEATURE_DISABLE,
+			     "npc_exact_feature_disable", DEVLINK_PARAM_TYPE_STRING,
+			     BIT(DEVLINK_PARAM_CMODE_RUNTIME),
+			     rvu_af_npc_exact_feature_get,
+			     rvu_af_npc_exact_feature_disable,
+			     rvu_af_npc_exact_feature_validate),
+};
+
 /* Devlink switch mode */
 static int rvu_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode)
 {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -2168,14 +2168,13 @@
 	schq = smq;
 	for (lvl = NIX_TXSCH_LVL_SMQ; lvl <= NIX_TXSCH_LVL_TL1; lvl++) {
 		smq_tree_ctx = &smq_flush_ctx->smq_tree_ctx[lvl];
+		smq_tree_ctx->schq = schq;
 		if (lvl == NIX_TXSCH_LVL_TL1) {
-			smq_flush_ctx->tl1_schq = schq;
 			smq_tree_ctx->cir_off = NIX_AF_TL1X_CIR(schq);
 			smq_tree_ctx->pir_off = 0;
 			smq_tree_ctx->pir_val = 0;
 			parent_off = 0;
 		} else if (lvl == NIX_TXSCH_LVL_TL2) {
-			smq_flush_ctx->tl2_schq = schq;
 			smq_tree_ctx->cir_off = NIX_AF_TL2X_CIR(schq);
 			smq_tree_ctx->pir_off = NIX_AF_TL2X_PIR(schq);
 			parent_off = NIX_AF_TL2X_PARENT(schq);
@@ -2210,8 +2209,8 @@
 {
 	struct nix_txsch *txsch;
 	struct nix_hw *nix_hw;
+	int tl2, tl2_schq;
 	u64 regoff;
-	int tl2;
 
 	nix_hw = get_nix_hw(rvu->hw, blkaddr);
 	if (!nix_hw)
@@ -2219,16 +2218,17 @@
 
 	/* loop through all TL2s with matching PF_FUNC */
 	txsch = &nix_hw->txsch[NIX_TXSCH_LVL_TL2];
+	tl2_schq = smq_flush_ctx->smq_tree_ctx[NIX_TXSCH_LVL_TL2].schq;
 	for (tl2 = 0; tl2 < txsch->schq.max; tl2++) {
 		/* skip the smq(flush) TL2 */
-		if (tl2 == smq_flush_ctx->tl2_schq)
+		if (tl2 == tl2_schq)
 			continue;
 		/* skip unused TL2s */
 		if (TXSCH_MAP_FLAGS(txsch->pfvf_map[tl2]) & NIX_TXSCHQ_FREE)
 			continue;
 		/* skip if PF_FUNC doesn't match */
 		if ((TXSCH_MAP_FUNC(txsch->pfvf_map[tl2]) & ~RVU_PFVF_FUNC_MASK) !=
-		    (TXSCH_MAP_FUNC(txsch->pfvf_map[smq_flush_ctx->tl2_schq] &
+		    (TXSCH_MAP_FUNC(txsch->pfvf_map[tl2_schq] &
 				    ~RVU_PFVF_FUNC_MASK)))
 			continue;
 		/* enable/disable XOFF */
@@ -2270,10 +2270,12 @@
 			 int smq, u16 pcifunc, int nixlf)
 {
 	struct nix_smq_flush_ctx *smq_flush_ctx;
+	int err, restore_tx_en = 0, i;
 	int pf = rvu_get_pf(pcifunc);
 	u8 cgx_id = 0, lmac_id = 0;
-	int err, restore_tx_en = 0;
-	u64 cfg;
+	u16 tl2_tl3_link_schq;
+	u8 link, link_level;
+	u64 cfg, bmap = 0;
 
 	if (!is_rvu_otx2(rvu)) {
 		/* Skip SMQ flush if pkt count is zero */
@@ -2297,16 +2299,38 @@
 	nix_smq_flush_enadis_xoff(rvu, blkaddr, smq_flush_ctx, true);
 	nix_smq_flush_enadis_rate(rvu, blkaddr, smq_flush_ctx, false);
 
-	cfg = rvu_read64(rvu, blkaddr, NIX_AF_SMQX_CFG(smq));
-	/* Do SMQ flush and set enqueue xoff */
-	cfg |= BIT_ULL(50) | BIT_ULL(49);
-	rvu_write64(rvu, blkaddr, NIX_AF_SMQX_CFG(smq), cfg);
-
 	/* Disable backpressure from physical link,
 	 * otherwise SMQ flush may stall.
 	 */
 	rvu_cgx_enadis_rx_bp(rvu, pf, false);
 
+	link_level = rvu_read64(rvu, blkaddr, NIX_AF_PSE_CHANNEL_LEVEL) & 0x01 ?
+			NIX_TXSCH_LVL_TL3 : NIX_TXSCH_LVL_TL2;
+	tl2_tl3_link_schq = smq_flush_ctx->smq_tree_ctx[link_level].schq;
+	link = smq_flush_ctx->smq_tree_ctx[NIX_TXSCH_LVL_TL1].schq;
+
+	/* SMQ set enqueue xoff */
+	cfg = rvu_read64(rvu, blkaddr, NIX_AF_SMQX_CFG(smq));
+	cfg |= BIT_ULL(50);
+	rvu_write64(rvu, blkaddr, NIX_AF_SMQX_CFG(smq), cfg);
+
+	/* Clear all NIX_AF_TL3_TL2_LINK_CFG[ENA] for the TL3/TL2 queue */
+	for (i = 0; i < (rvu->hw->cgx_links + rvu->hw->lbk_links); i++) {
+		cfg = rvu_read64(rvu, blkaddr,
+				 NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link));
+		if (!(cfg & BIT_ULL(12)))
+			continue;
+		bmap |= BIT_ULL(i);
+		cfg &= ~BIT_ULL(12);
+		rvu_write64(rvu, blkaddr,
+			    NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link), cfg);
+	}
+
+	/* Do SMQ flush and set enqueue xoff */
+	cfg = rvu_read64(rvu, blkaddr, NIX_AF_SMQX_CFG(smq));
+	cfg |= BIT_ULL(50) | BIT_ULL(49);
+	rvu_write64(rvu, blkaddr, NIX_AF_SMQX_CFG(smq), cfg);
+
 	/* Wait for flush to complete */
 	err = rvu_poll_reg(rvu, blkaddr,
 			   NIX_AF_SMQX_CFG(smq), BIT_ULL(49), true);
@@ -2315,6 +2339,17 @@
 			 "NIXLF%d: SMQ%d flush failed, txlink might be busy\n",
 			 nixlf, smq);
 
+	/* Set NIX_AF_TL3_TL2_LINKX_CFG[ENA] for the TL3/TL2 queue */
+	for (i = 0; i < (rvu->hw->cgx_links + rvu->hw->lbk_links); i++) {
+		if (!(bmap & BIT_ULL(i)))
+			continue;
+		cfg = rvu_read64(rvu, blkaddr,
+				 NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link));
+		cfg |= BIT_ULL(12);
+		rvu_write64(rvu, blkaddr,
+			    NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link), cfg);
+	}
+
 	/* clear XOFF on TL2s */
 	nix_smq_flush_enadis_rate(rvu, blkaddr, smq_flush_ctx, true);
 	nix_smq_flush_enadis_xoff(rvu, blkaddr, smq_flush_ctx, false);
@@ -3773,6 +3808,11 @@
 	return -ERANGE;
 }
 
+/* Mask to match ipv6(NPC_LT_LC_IP6) and ipv6 ext(NPC_LT_LC_IP6_EXT) */
+#define NPC_LT_LC_IP6_MATCH_MSK ((~(NPC_LT_LC_IP6 ^ NPC_LT_LC_IP6_EXT)) & 0xf)
+/* Mask to match both ipv4(NPC_LT_LC_IP) and ipv4 ext(NPC_LT_LC_IP_OPT) */
+#define NPC_LT_LC_IP_MATCH_MSK  ((~(NPC_LT_LC_IP ^ NPC_LT_LC_IP_OPT)) & 0xf)
+
 static int set_flowkey_fields(struct nix_rx_flowkey_alg *alg, u32 flow_cfg)
 {
 	int idx, nr_field, key_off, field_marker, keyoff_marker;
@@ -3842,7 +3882,7 @@
 			field->hdr_offset = 9; /* offset */
 			field->bytesm1 = 0; /* 1 byte */
 			field->ltype_match = NPC_LT_LC_IP;
-			field->ltype_mask = 0xF;
+			field->ltype_mask = NPC_LT_LC_IP_MATCH_MSK;
 			break;
 		case NIX_FLOW_KEY_TYPE_IPV4:
 		case NIX_FLOW_KEY_TYPE_INNR_IPV4:
@@ -3869,8 +3909,7 @@
 					field->bytesm1 = 3; /* DIP, 4 bytes */
 				}
 			}
-
-			field->ltype_mask = 0xF; /* Match only IPv4 */
+			field->ltype_mask = NPC_LT_LC_IP_MATCH_MSK;
 			keyoff_marker = false;
 			break;
 		case NIX_FLOW_KEY_TYPE_IPV6:
@@ -3899,7 +3938,7 @@
 					field->bytesm1 = 15; /* DIP,16 bytes */
 				}
 			}
-			field->ltype_mask = 0xF; /* Match only IPv6 */
+			field->ltype_mask = NPC_LT_LC_IP6_MATCH_MSK;
 			break;
 		case NIX_FLOW_KEY_TYPE_TCP:
 		case NIX_FLOW_KEY_TYPE_UDP:
@@ -4721,18 +4760,18 @@
 		 */
 		rvu_write64(rvu, blkaddr, NIX_AF_CFG,
 			    rvu_read64(rvu, blkaddr, NIX_AF_CFG) | 0x40ULL);
+	}
 
-		/* Set chan/link to backpressure TL3 instead of TL2 */
-		rvu_write64(rvu, blkaddr, NIX_AF_PSE_CHANNEL_LEVEL, 0x01);
+	/* Set chan/link to backpressure TL3 instead of TL2 */
+	rvu_write64(rvu, blkaddr, NIX_AF_PSE_CHANNEL_LEVEL, 0x01);
 
-		/* Disable SQ manager's sticky mode operation (set TM6 = 0)
-		 * This sticky mode is known to cause SQ stalls when multiple
-		 * SQs are mapped to same SMQ and transmitting pkts at a time.
-		 */
-		cfg = rvu_read64(rvu, blkaddr, NIX_AF_SQM_DBG_CTL_STATUS);
-		cfg &= ~BIT_ULL(15);
-		rvu_write64(rvu, blkaddr, NIX_AF_SQM_DBG_CTL_STATUS, cfg);
-	}
+	/* Disable SQ manager's sticky mode operation (set TM6 = 0)
+	 * This sticky mode is known to cause SQ stalls when multiple
+	 * SQs are mapped to same SMQ and transmitting pkts at a time.
+	 */
+	cfg = rvu_read64(rvu, blkaddr, NIX_AF_SQM_DBG_CTL_STATUS);
+	cfg &= ~BIT_ULL(15);
+	rvu_write64(rvu, blkaddr, NIX_AF_SQM_DBG_CTL_STATUS, cfg);
 
 	ltdefs = rvu->kpu.lt_def;
 	/* Calibrate X2P bus to check if CGX/LBK links are fine */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
@@ -1657,7 +1657,7 @@
 	struct npc_coalesced_kpu_prfl *img_data = NULL;
 	int i = 0, rc = -EINVAL;
 	void __iomem *kpu_prfl_addr;
-	u16 offset;
+	u32 offset;
 
 	img_data = (struct npc_coalesced_kpu_prfl __force *)rvu->kpu_prfl_addr;
 	if (le64_to_cpu(img_data->signature) == KPU_SIGN &&
@@ -2181,7 +2181,6 @@
 
 	kfree(pkind->rsrc.bmap);
 	npc_mcam_rsrcs_deinit(rvu);
-	kfree(mcam->counters.bmap);
 	if (rvu->kpu_prfl_addr)
 		iounmap(rvu->kpu_prfl_addr);
 	else
@@ -2520,7 +2519,17 @@
 	 * - when available free entries are less.
 	 * Lower priority ones out of avaialble free entries are always
 	 * chosen when 'high vs low' question arises.
+	 *
+	 * For a VF base MCAM match rule is set by its PF. And all the
+	 * further MCAM rules installed by VF on its own are
+	 * concatenated with the base rule set by its PF. Hence PF entries
+	 * should be at lower priority compared to VF entries. Otherwise
+	 * base rule is hit always and rules installed by VF will be of
+	 * no use. Hence if the request is from PF then allocate low
+	 * priority entries.
 	 */
+	if (!(pcifunc & RVU_PFVF_FUNC_MASK))
+		goto lprio_alloc;
 
 	/* Get the search range for priority allocation request */
 	if (req->priority) {
@@ -2529,17 +2538,6 @@
 		goto alloc;
 	}
 
-	/* For a VF base MCAM match rule is set by its PF. And all the
-	 * further MCAM rules installed by VF on its own are
-	 * concatenated with the base rule set by its PF. Hence PF entries
-	 * should be at lower priority compared to VF entries. Otherwise
-	 * base rule is hit always and rules installed by VF will be of
-	 * no use. Hence if the request is from PF and NOT a priority
-	 * allocation request then allocate low priority entries.
-	 */
-	if (!(pcifunc & RVU_PFVF_FUNC_MASK))
-		goto lprio_alloc;
-
 	/* Find out the search range for non-priority allocation request
 	 *
 	 * Get MCAM free entry count in middle zone.
@@ -2569,6 +2567,18 @@
 		reverse = true;
 		start = 0;
 		end = mcam->bmap_entries;
+		/* Ensure PF requests are always at bottom and if PF requests
+		 * for higher/lower priority entry wrt reference entry then
+		 * honour that criteria and start search for entries from bottom
+		 * and not in mid zone.
+		 */
+		if (!(pcifunc & RVU_PFVF_FUNC_MASK) &&
+		    req->priority == NPC_MCAM_HIGHER_PRIO)
+			end = req->ref_entry;
+
+		if (!(pcifunc & RVU_PFVF_FUNC_MASK) &&
+		    req->priority == NPC_MCAM_LOWER_PRIO)
+			start = req->ref_entry;
 	}
 
 alloc:
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/Makefile
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/Makefile
@@ -9,10 +9,9 @@
 rvu_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o \
                otx2_flows.o otx2_tc.o cn10k.o otx2_dmac_flt.o \
                otx2_devlink.o qos_sq.o qos.o
-rvu_nicvf-y := otx2_vf.o otx2_devlink.o
+rvu_nicvf-y := otx2_vf.o
 
 rvu_nicpf-$(CONFIG_DCB) += otx2_dcbnl.o
-rvu_nicvf-$(CONFIG_DCB) += otx2_dcbnl.o
 rvu_nicpf-$(CONFIG_MACSEC) += cn10k_macsec.o
 
 ccflags-y += -I$(srctree)/drivers/net/ethernet/marvell/octeontx2/af
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
@@ -203,6 +203,11 @@
 
 	rsp = (struct  nix_bandprof_alloc_rsp *)
 	       otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
+	if (IS_ERR(rsp)) {
+		rc = PTR_ERR(rsp);
+		goto out;
+	}
+
 	if (!rsp->prof_count[BAND_PROF_LEAF_LAYER]) {
 		rc = -EIO;
 		goto out;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
@@ -648,14 +648,14 @@
 	} else if (lvl == NIX_TXSCH_LVL_TL4) {
 		parent = schq_list[NIX_TXSCH_LVL_TL3][prio];
 		req->reg[0] = NIX_AF_TL4X_PARENT(schq);
-		req->regval[0] = parent << 16;
+		req->regval[0] = (u64)parent << 16;
 		req->num_regs++;
 		req->reg[1] = NIX_AF_TL4X_SCHEDULE(schq);
 		req->regval[1] = dwrr_val;
 	} else if (lvl == NIX_TXSCH_LVL_TL3) {
 		parent = schq_list[NIX_TXSCH_LVL_TL2][prio];
 		req->reg[0] = NIX_AF_TL3X_PARENT(schq);
-		req->regval[0] = parent << 16;
+		req->regval[0] = (u64)parent << 16;
 		req->num_regs++;
 		req->reg[1] = NIX_AF_TL3X_SCHEDULE(schq);
 		req->regval[1] = dwrr_val;
@@ -670,11 +670,11 @@
 	} else if (lvl == NIX_TXSCH_LVL_TL2) {
 		parent = schq_list[NIX_TXSCH_LVL_TL1][prio];
 		req->reg[0] = NIX_AF_TL2X_PARENT(schq);
-		req->regval[0] = parent << 16;
+		req->regval[0] = (u64)parent << 16;
 
 		req->num_regs++;
 		req->reg[1] = NIX_AF_TL2X_SCHEDULE(schq);
-		req->regval[1] = TXSCH_TL1_DFLT_RR_PRIO << 24 | dwrr_val;
+		req->regval[1] = (u64)hw->txschq_aggr_lvl_rr_prio << 24 | dwrr_val;
 
 		if (lvl == hw->txschq_link_cfg_lvl) {
 			req->num_regs++;
@@ -698,7 +698,7 @@
 
 		req->num_regs++;
 		req->reg[1] = NIX_AF_TL1X_TOPOLOGY(schq);
-		req->regval[1] = (TXSCH_TL1_DFLT_RR_PRIO << 1);
+		req->regval[1] = hw->txschq_aggr_lvl_rr_prio << 1;
 
 		req->num_regs++;
 		req->reg[2] = NIX_AF_TL1X_CIR(schq);
@@ -1592,7 +1592,7 @@
 	detach->partial = false;
 
 	/* Send detach request to AF */
-	otx2_mbox_msg_send(&mbox->mbox, 0);
+	otx2_sync_mbox_msg(mbox);
 	mutex_unlock(&mbox->lock);
 	return 0;
 }
@@ -1837,6 +1837,10 @@
 	if (!rc) {
 		rsp = (struct nix_hw_info *)
 		       otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
+		if (IS_ERR(rsp)) {
+			rc = PTR_ERR(rsp);
+			goto out;
+		}
 
 		/* HW counts VLAN insertion bytes (8 for double tag)
 		 * irrespective of whether SQE is requesting to insert VLAN
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
@@ -815,7 +815,7 @@
 
 	if (!otx2_mbox_nonempty(&mbox->mbox_up, devid))
 		return 0;
-	otx2_mbox_msg_send(&mbox->mbox_up, devid);
+	otx2_mbox_msg_send_up(&mbox->mbox_up, devid);
 	err = otx2_mbox_wait_for_rsp(&mbox->mbox_up, devid);
 	if (err)
 		return err;
@@ -961,6 +961,7 @@
 void otx2_config_irq_coalescing(struct otx2_nic *pfvf, int qidx);
 int otx2_config_pause_frm(struct otx2_nic *pfvf);
 void otx2_setup_segmentation(struct otx2_nic *pfvf);
+int otx2_reset_mac_stats(struct otx2_nic *pfvf);
 
 /* RVU block related APIs */
 int otx2_attach_npa_nix(struct otx2_nic *pfvf);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c
@@ -54,6 +54,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(otx2_pfc_txschq_config);
 
 static int otx2_pfc_txschq_alloc_one(struct otx2_nic *pfvf, u8 prio)
 {
@@ -122,6 +123,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(otx2_pfc_txschq_alloc);
 
 static int otx2_pfc_txschq_stop_one(struct otx2_nic *pfvf, u8 prio)
 {
@@ -260,6 +262,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(otx2_pfc_txschq_update);
 
 int otx2_pfc_txschq_stop(struct otx2_nic *pfvf)
 {
@@ -282,6 +285,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(otx2_pfc_txschq_stop);
 
 int otx2_config_priority_flow_ctrl(struct otx2_nic *pfvf)
 {
@@ -311,6 +315,11 @@
 	if (!otx2_sync_mbox_msg(&pfvf->mbox)) {
 		rsp = (struct cgx_pfc_rsp *)
 		       otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
+		if (IS_ERR(rsp)) {
+			err = PTR_ERR(rsp);
+			goto unlock;
+		}
+
 		if (req->rx_pause != rsp->rx_pause || req->tx_pause != rsp->tx_pause) {
 			dev_warn(pfvf->dev,
 				 "Failed to config PFC\n");
@@ -321,6 +330,7 @@
 	mutex_unlock(&pfvf->mbox.lock);
 	return err;
 }
+EXPORT_SYMBOL(otx2_config_priority_flow_ctrl);
 
 void otx2_update_bpid_in_rqctx(struct otx2_nic *pfvf, int vlan_prio, int qidx,
 			       bool pfc_enable)
@@ -385,6 +395,7 @@
 			 "Updating BPIDs in CQ and Aura contexts of RQ%d failed with err %d\n",
 			 qidx, err);
 }
+EXPORT_SYMBOL(otx2_update_bpid_in_rqctx);
 
 static int otx2_dcbnl_ieee_getpfc(struct net_device *dev, struct ieee_pfc *pfc)
 {
@@ -472,3 +483,4 @@
 
 	return 0;
 }
+EXPORT_SYMBOL(otx2_dcbnl_set_ops);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c
@@ -112,6 +112,7 @@
 	devlink_free(dl);
 	return err;
 }
+EXPORT_SYMBOL(otx2_register_dl);
 
 void otx2_unregister_dl(struct otx2_nic *pfvf)
 {
@@ -123,3 +124,4 @@
 				  ARRAY_SIZE(otx2_dl_params));
 	devlink_free(dl);
 }
+EXPORT_SYMBOL(otx2_unregister_dl);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dmac_flt.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dmac_flt.c
@@ -28,6 +28,11 @@
 	if (!err) {
 		rsp = (struct cgx_mac_addr_add_rsp *)
 			 otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr);
+		if (IS_ERR(rsp)) {
+			mutex_unlock(&pf->mbox.lock);
+			return PTR_ERR(rsp);
+		}
+
 		*dmac_index = rsp->index;
 	}
 
@@ -200,6 +205,10 @@
 
 	rsp = (struct cgx_mac_addr_update_rsp *)
 		otx2_mbox_get_rsp(&pf->mbox.mbox, 0, &req->hdr);
+	if (IS_ERR(rsp)) {
+		rc = PTR_ERR(rsp);
+		goto out;
+	}
 
 	pf->flow_cfg->bmap_to_dmacindex[bit_pos] = rsp->index;
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c
@@ -343,6 +343,11 @@
 	if (!otx2_sync_mbox_msg(&pfvf->mbox)) {
 		rsp = (struct cgx_pause_frm_cfg *)
 		       otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
+		if (IS_ERR(rsp)) {
+			mutex_unlock(&pfvf->mbox.lock);
+			return;
+		}
+
 		pause->rx_pause = rsp->rx_pause;
 		pause->tx_pause = rsp->tx_pause;
 	}
@@ -1074,6 +1079,11 @@
 
 	rsp = (struct fec_mode *)otx2_mbox_get_rsp(&pfvf->mbox.mbox,
 						   0, &req->hdr);
+	if (IS_ERR(rsp)) {
+		err = PTR_ERR(rsp);
+		goto end;
+	}
+
 	if (rsp->fec >= 0)
 		pfvf->linfo.fec = rsp->fec;
 	else
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
@@ -121,6 +121,8 @@
 
 		rsp = (struct npc_mcam_alloc_entry_rsp *)otx2_mbox_get_rsp
 			(&pfvf->mbox.mbox, 0, &req->hdr);
+		if (IS_ERR(rsp))
+			goto exit;
 
 		for (ent = 0; ent < rsp->count; ent++)
 			flow_cfg->flow_ent[ent + allocated] = rsp->entry_list[ent];
@@ -199,6 +201,10 @@
 
 	rsp = (struct npc_mcam_alloc_entry_rsp *)otx2_mbox_get_rsp
 	       (&pfvf->mbox.mbox, 0, &req->hdr);
+	if (IS_ERR(rsp)) {
+		mutex_unlock(&pfvf->mbox.lock);
+		return PTR_ERR(rsp);
+	}
 
 	if (rsp->count != req->count) {
 		netdev_info(pfvf->netdev,
@@ -234,6 +240,10 @@
 
 	frsp = (struct npc_get_field_status_rsp *)otx2_mbox_get_rsp
 	       (&pfvf->mbox.mbox, 0, &freq->hdr);
+	if (IS_ERR(frsp)) {
+		mutex_unlock(&pfvf->mbox.lock);
+		return PTR_ERR(frsp);
+	}
 
 	if (frsp->enable) {
 		pfvf->flags |= OTX2_FLAG_RX_VLAN_SUPPORT;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
@@ -292,8 +292,8 @@
 	return 0;
 }
 
-static void otx2_queue_work(struct mbox *mw, struct workqueue_struct *mbox_wq,
-			    int first, int mdevs, u64 intr, int type)
+static void otx2_queue_vf_work(struct mbox *mw, struct workqueue_struct *mbox_wq,
+			       int first, int mdevs, u64 intr)
 {
 	struct otx2_mbox_dev *mdev;
 	struct otx2_mbox *mbox;
@@ -307,40 +307,26 @@
 
 		mbox = &mw->mbox;
 		mdev = &mbox->dev[i];
-		if (type == TYPE_PFAF)
-			otx2_sync_mbox_bbuf(mbox, i);
 		hdr = mdev->mbase + mbox->rx_start;
 		/* The hdr->num_msgs is set to zero immediately in the interrupt
-		 * handler to  ensure that it holds a correct value next time
-		 * when the interrupt handler is called.
-		 * pf->mbox.num_msgs holds the data for use in pfaf_mbox_handler
-		 * pf>mbox.up_num_msgs holds the data for use in
-		 * pfaf_mbox_up_handler.
+		 * handler to ensure that it holds a correct value next time
+		 * when the interrupt handler is called. pf->mw[i].num_msgs
+		 * holds the data for use in otx2_pfvf_mbox_handler and
+		 * pf->mw[i].up_num_msgs holds the data for use in
+		 * otx2_pfvf_mbox_up_handler.
 		 */
 		if (hdr->num_msgs) {
 			mw[i].num_msgs = hdr->num_msgs;
 			hdr->num_msgs = 0;
-			if (type == TYPE_PFAF)
-				memset(mbox->hwbase + mbox->rx_start, 0,
-				       ALIGN(sizeof(struct mbox_hdr),
-					     sizeof(u64)));
-
 			queue_work(mbox_wq, &mw[i].mbox_wrk);
 		}
 
 		mbox = &mw->mbox_up;
 		mdev = &mbox->dev[i];
-		if (type == TYPE_PFAF)
-			otx2_sync_mbox_bbuf(mbox, i);
 		hdr = mdev->mbase + mbox->rx_start;
 		if (hdr->num_msgs) {
 			mw[i].up_num_msgs = hdr->num_msgs;
 			hdr->num_msgs = 0;
-			if (type == TYPE_PFAF)
-				memset(mbox->hwbase + mbox->rx_start, 0,
-				       ALIGN(sizeof(struct mbox_hdr),
-					     sizeof(u64)));
-
 			queue_work(mbox_wq, &mw[i].mbox_up_wrk);
 		}
 	}
@@ -356,8 +342,10 @@
 	/* Msgs are already copied, trigger VF's mbox irq */
 	smp_wmb();
 
+	otx2_mbox_wait_for_zero(pfvf_mbox, devid);
+
 	offset = pfvf_mbox->trigger | (devid << pfvf_mbox->tr_shift);
-	writeq(1, (void __iomem *)pfvf_mbox->reg_base + offset);
+	writeq(MBOX_DOWN_MSG, (void __iomem *)pfvf_mbox->reg_base + offset);
 
 	/* Restore VF's mbox bounce buffer region address */
 	src_mdev->mbase = bbuf_base;
@@ -547,7 +535,7 @@
 end:
 		offset = mbox->rx_start + msg->next_msgoff;
 		if (mdev->msgs_acked == (vf_mbox->up_num_msgs - 1))
-			__otx2_mbox_reset(mbox, 0);
+			__otx2_mbox_reset(mbox, vf_idx);
 		mdev->msgs_acked++;
 	}
 }
@@ -564,8 +552,7 @@
 	if (vfs > 64) {
 		intr = otx2_read64(pf, RVU_PF_VFPF_MBOX_INTX(1));
 		otx2_write64(pf, RVU_PF_VFPF_MBOX_INTX(1), intr);
-		otx2_queue_work(mbox, pf->mbox_pfvf_wq, 64, vfs, intr,
-				TYPE_PFVF);
+		otx2_queue_vf_work(mbox, pf->mbox_pfvf_wq, 64, vfs, intr);
 		if (intr)
 			trace_otx2_msg_interrupt(mbox->mbox.pdev, "VF(s) to PF", intr);
 		vfs = 64;
@@ -574,7 +561,7 @@
 	intr = otx2_read64(pf, RVU_PF_VFPF_MBOX_INTX(0));
 	otx2_write64(pf, RVU_PF_VFPF_MBOX_INTX(0), intr);
 
-	otx2_queue_work(mbox, pf->mbox_pfvf_wq, 0, vfs, intr, TYPE_PFVF);
+	otx2_queue_vf_work(mbox, pf->mbox_pfvf_wq, 0, vfs, intr);
 
 	if (intr)
 		trace_otx2_msg_interrupt(mbox->mbox.pdev, "VF(s) to PF", intr);
@@ -597,8 +584,9 @@
 	if (!pf->mbox_pfvf)
 		return -ENOMEM;
 
-	pf->mbox_pfvf_wq = alloc_ordered_workqueue("otx2_pfvf_mailbox",
-						   WQ_HIGHPRI | WQ_MEM_RECLAIM);
+	pf->mbox_pfvf_wq = alloc_workqueue("otx2_pfvf_mailbox",
+					   WQ_UNBOUND | WQ_HIGHPRI |
+					   WQ_MEM_RECLAIM, 0);
 	if (!pf->mbox_pfvf_wq)
 		return -ENOMEM;
 
@@ -821,20 +809,22 @@
 	struct mbox *af_mbox;
 	struct otx2_nic *pf;
 	int offset, id;
+	u16 num_msgs;
 
 	af_mbox = container_of(work, struct mbox, mbox_wrk);
 	mbox = &af_mbox->mbox;
 	mdev = &mbox->dev[0];
 	rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
+	num_msgs = rsp_hdr->num_msgs;
 
 	offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
 	pf = af_mbox->pfvf;
 
-	for (id = 0; id < af_mbox->num_msgs; id++) {
+	for (id = 0; id < num_msgs; id++) {
 		msg = (struct mbox_msghdr *)(mdev->mbase + offset);
 		otx2_process_pfaf_mbox_msg(pf, msg);
 		offset = mbox->rx_start + msg->next_msgoff;
-		if (mdev->msgs_acked == (af_mbox->num_msgs - 1))
+		if (mdev->msgs_acked == (num_msgs - 1))
 			__otx2_mbox_reset(mbox, 0);
 		mdev->msgs_acked++;
 	}
@@ -945,12 +935,14 @@
 	int offset, id, devid = 0;
 	struct mbox_hdr *rsp_hdr;
 	struct mbox_msghdr *msg;
+	u16 num_msgs;
 
 	rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
+	num_msgs = rsp_hdr->num_msgs;
 
 	offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
 
-	for (id = 0; id < af_mbox->up_num_msgs; id++) {
+	for (id = 0; id < num_msgs; id++) {
 		msg = (struct mbox_msghdr *)(mdev->mbase + offset);
 
 		devid = msg->pcifunc & RVU_PFVF_FUNC_MASK;
@@ -959,10 +951,11 @@
 			otx2_process_mbox_msg_up(pf, msg);
 		offset = mbox->rx_start + msg->next_msgoff;
 	}
-	if (devid) {
+	/* Forward to VF iff VFs are really present */
+	if (devid && pci_num_vf(pf->pdev)) {
 		otx2_forward_vf_mbox_msgs(pf, &pf->mbox.mbox_up,
 					  MBOX_DIR_PFVF_UP, devid - 1,
-					  af_mbox->up_num_msgs);
+					  num_msgs);
 		return;
 	}
 
@@ -972,16 +965,49 @@
 static irqreturn_t otx2_pfaf_mbox_intr_handler(int irq, void *pf_irq)
 {
 	struct otx2_nic *pf = (struct otx2_nic *)pf_irq;
-	struct mbox *mbox;
+	struct mbox *mw = &pf->mbox;
+	struct otx2_mbox_dev *mdev;
+	struct otx2_mbox *mbox;
+	struct mbox_hdr *hdr;
+	u64 mbox_data;
 
 	/* Clear the IRQ */
 	otx2_write64(pf, RVU_PF_INT, BIT_ULL(0));
 
-	mbox = &pf->mbox;
 
-	trace_otx2_msg_interrupt(mbox->mbox.pdev, "AF to PF", BIT_ULL(0));
+	mbox_data = otx2_read64(pf, RVU_PF_PFAF_MBOX0);
+
+	if (mbox_data & MBOX_UP_MSG) {
+		mbox_data &= ~MBOX_UP_MSG;
+		otx2_write64(pf, RVU_PF_PFAF_MBOX0, mbox_data);
 
-	otx2_queue_work(mbox, pf->mbox_wq, 0, 1, 1, TYPE_PFAF);
+		mbox = &mw->mbox_up;
+		mdev = &mbox->dev[0];
+		otx2_sync_mbox_bbuf(mbox, 0);
+
+		hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
+		if (hdr->num_msgs)
+			queue_work(pf->mbox_wq, &mw->mbox_up_wrk);
+
+		trace_otx2_msg_interrupt(pf->pdev, "UP message from AF to PF",
+					 BIT_ULL(0));
+	}
+
+	if (mbox_data & MBOX_DOWN_MSG) {
+		mbox_data &= ~MBOX_DOWN_MSG;
+		otx2_write64(pf, RVU_PF_PFAF_MBOX0, mbox_data);
+
+		mbox = &mw->mbox;
+		mdev = &mbox->dev[0];
+		otx2_sync_mbox_bbuf(mbox, 0);
+
+		hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
+		if (hdr->num_msgs)
+			queue_work(pf->mbox_wq, &mw->mbox_wrk);
+
+		trace_otx2_msg_interrupt(pf->pdev, "DOWN reply from AF to PF",
+					 BIT_ULL(0));
+	}
 
 	return IRQ_HANDLED;
 }
@@ -1124,6 +1150,23 @@
 	return err;
 }
 
+int otx2_reset_mac_stats(struct otx2_nic *pfvf)
+{
+	struct msg_req *req;
+	int err;
+
+	mutex_lock(&pfvf->mbox.lock);
+	req = otx2_mbox_alloc_msg_cgx_stats_rst(&pfvf->mbox);
+	if (!req) {
+		mutex_unlock(&pfvf->mbox.lock);
+		return -ENOMEM;
+	}
+
+	err = otx2_sync_mbox_msg(&pfvf->mbox);
+	mutex_unlock(&pfvf->mbox.lock);
+	return err;
+}
+
 static int otx2_cgx_config_loopback(struct otx2_nic *pf, bool enable)
 {
 	struct msg_req *msg;
@@ -1907,7 +1950,7 @@
 	 * mcam entries are enabled to receive the packets. Hence disable the
 	 * packet I/O.
 	 */
-	if (err == EIO)
+	if (err == -EIO)
 		goto err_disable_rxtx;
 	else if (err)
 		goto err_tx_stop_queues;
@@ -3012,6 +3055,9 @@
 	netdev->min_mtu = OTX2_MIN_MTU;
 	netdev->max_mtu = otx2_get_max_mtu(pf);
 
+	/* reset CGX/RPM MAC stats */
+	otx2_reset_mac_stats(pf);
+
 	err = register_netdev(netdev);
 	if (err) {
 		dev_err(dev, "Failed to register netdevice\n");
@@ -3087,6 +3133,7 @@
 	struct otx2_vf_config *config;
 	struct cgx_link_info_msg *req;
 	struct mbox_msghdr *msghdr;
+	struct delayed_work *dwork;
 	struct otx2_nic *pf;
 	int vf_idx;
 
@@ -3095,10 +3142,24 @@
 	vf_idx = config - config->pf->vf_configs;
 	pf = config->pf;
 
+	if (config->intf_down)
+		return;
+
+	mutex_lock(&pf->mbox.lock);
+
+	dwork = &config->link_event_work;
+
+	if (!otx2_mbox_wait_for_zero(&pf->mbox_pfvf[0].mbox_up, vf_idx)) {
+		schedule_delayed_work(dwork, msecs_to_jiffies(100));
+		mutex_unlock(&pf->mbox.lock);
+		return;
+	}
+
 	msghdr = otx2_mbox_alloc_msg_rsp(&pf->mbox_pfvf[0].mbox_up, vf_idx,
 					 sizeof(*req), sizeof(struct msg_rsp));
 	if (!msghdr) {
 		dev_err(pf->dev, "Failed to create VF%d link event\n", vf_idx);
+		mutex_unlock(&pf->mbox.lock);
 		return;
 	}
 
@@ -3107,7 +3168,11 @@
 	req->hdr.sig = OTX2_MBOX_REQ_SIG;
 	memcpy(&req->link_info, &pf->linfo, sizeof(req->link_info));
 
+	otx2_mbox_wait_for_zero(&pf->mbox_pfvf[0].mbox_up, vf_idx);
+
 	otx2_sync_mbox_up_msg(&pf->mbox_pfvf[0], vf_idx);
+
+	mutex_unlock(&pf->mbox.lock);
 }
 
 static int otx2_sriov_enable(struct pci_dev *pdev, int numvfs)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_reg.h
@@ -139,33 +139,34 @@
 #define	NIX_LF_CINTX_ENA_W1C(a)		(NIX_LFBASE | 0xD50 | (a) << 12)
 
 /* NIX AF transmit scheduler registers */
-#define NIX_AF_SMQX_CFG(a)		(0x700 | (a) << 16)
-#define NIX_AF_TL1X_SCHEDULE(a)		(0xC00 | (a) << 16)
-#define NIX_AF_TL1X_CIR(a)		(0xC20 | (a) << 16)
-#define NIX_AF_TL1X_TOPOLOGY(a)		(0xC80 | (a) << 16)
-#define NIX_AF_TL2X_PARENT(a)		(0xE88 | (a) << 16)
-#define NIX_AF_TL2X_SCHEDULE(a)		(0xE00 | (a) << 16)
-#define NIX_AF_TL2X_TOPOLOGY(a)		(0xE80 | (a) << 16)
-#define NIX_AF_TL2X_CIR(a)              (0xE20 | (a) << 16)
-#define NIX_AF_TL2X_PIR(a)              (0xE30 | (a) << 16)
-#define NIX_AF_TL3X_PARENT(a)		(0x1088 | (a) << 16)
-#define NIX_AF_TL3X_SCHEDULE(a)		(0x1000 | (a) << 16)
-#define NIX_AF_TL3X_SHAPE(a)		(0x1010 | (a) << 16)
-#define NIX_AF_TL3X_CIR(a)		(0x1020 | (a) << 16)
-#define NIX_AF_TL3X_PIR(a)		(0x1030 | (a) << 16)
-#define NIX_AF_TL3X_TOPOLOGY(a)		(0x1080 | (a) << 16)
-#define NIX_AF_TL4X_PARENT(a)		(0x1288 | (a) << 16)
-#define NIX_AF_TL4X_SCHEDULE(a)		(0x1200 | (a) << 16)
-#define NIX_AF_TL4X_SHAPE(a)		(0x1210 | (a) << 16)
-#define NIX_AF_TL4X_CIR(a)		(0x1220 | (a) << 16)
-#define NIX_AF_TL4X_PIR(a)		(0x1230 | (a) << 16)
-#define NIX_AF_TL4X_TOPOLOGY(a)		(0x1280 | (a) << 16)
-#define NIX_AF_MDQX_SCHEDULE(a)		(0x1400 | (a) << 16)
-#define NIX_AF_MDQX_SHAPE(a)		(0x1410 | (a) << 16)
-#define NIX_AF_MDQX_CIR(a)		(0x1420 | (a) << 16)
-#define NIX_AF_MDQX_PIR(a)		(0x1430 | (a) << 16)
-#define NIX_AF_MDQX_PARENT(a)		(0x1480 | (a) << 16)
-#define NIX_AF_TL3_TL2X_LINKX_CFG(a, b)	(0x1700 | (a) << 16 | (b) << 3)
+#define NIX_AF_SMQX_CFG(a)		(0x700 | (u64)(a) << 16)
+#define NIX_AF_TL4X_SDP_LINK_CFG(a)	(0xB10 | (u64)(a) << 16)
+#define NIX_AF_TL1X_SCHEDULE(a)		(0xC00 | (u64)(a) << 16)
+#define NIX_AF_TL1X_CIR(a)		(0xC20 | (u64)(a) << 16)
+#define NIX_AF_TL1X_TOPOLOGY(a)		(0xC80 | (u64)(a) << 16)
+#define NIX_AF_TL2X_PARENT(a)		(0xE88 | (u64)(a) << 16)
+#define NIX_AF_TL2X_SCHEDULE(a)		(0xE00 | (u64)(a) << 16)
+#define NIX_AF_TL2X_TOPOLOGY(a)		(0xE80 | (u64)(a) << 16)
+#define NIX_AF_TL2X_CIR(a)		(0xE20 | (u64)(a) << 16)
+#define NIX_AF_TL2X_PIR(a)		(0xE30 | (u64)(a) << 16)
+#define NIX_AF_TL3X_PARENT(a)		(0x1088 | (u64)(a) << 16)
+#define NIX_AF_TL3X_SCHEDULE(a)		(0x1000 | (u64)(a) << 16)
+#define NIX_AF_TL3X_SHAPE(a)		(0x1010 | (u64)(a) << 16)
+#define NIX_AF_TL3X_CIR(a)		(0x1020 | (u64)(a) << 16)
+#define NIX_AF_TL3X_PIR(a)		(0x1030 | (u64)(a) << 16)
+#define NIX_AF_TL3X_TOPOLOGY(a)		(0x1080 | (u64)(a) << 16)
+#define NIX_AF_TL4X_PARENT(a)		(0x1288 | (u64)(a) << 16)
+#define NIX_AF_TL4X_SCHEDULE(a)		(0x1200 | (u64)(a) << 16)
+#define NIX_AF_TL4X_SHAPE(a)		(0x1210 | (u64)(a) << 16)
+#define NIX_AF_TL4X_CIR(a)		(0x1220 | (u64)(a) << 16)
+#define NIX_AF_TL4X_PIR(a)		(0x1230 | (u64)(a) << 16)
+#define NIX_AF_TL4X_TOPOLOGY(a)		(0x1280 | (u64)(a) << 16)
+#define NIX_AF_MDQX_SCHEDULE(a)		(0x1400 | (u64)(a) << 16)
+#define NIX_AF_MDQX_SHAPE(a)		(0x1410 | (u64)(a) << 16)
+#define NIX_AF_MDQX_CIR(a)		(0x1420 | (u64)(a) << 16)
+#define NIX_AF_MDQX_PIR(a)		(0x1430 | (u64)(a) << 16)
+#define NIX_AF_MDQX_PARENT(a)		(0x1480 | (u64)(a) << 16)
+#define NIX_AF_TL3_TL2X_LINKX_CFG(a, b)	(0x1700 | (u64)(a) << 16 | (b) << 3)
 
 /* LMT LF registers */
 #define LMT_LFBASE			BIT_ULL(RVU_FUNC_BLKADDR_SHIFT)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
@@ -688,6 +688,7 @@
 
 	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
 		struct flow_match_control match;
+		u32 val;
 
 		flow_rule_match_control(rule, &match);
 		if (match.mask->flags & FLOW_DIS_FIRST_FRAG) {
@@ -696,12 +697,14 @@
 		}
 
 		if (match.mask->flags & FLOW_DIS_IS_FRAGMENT) {
+			val = match.key->flags & FLOW_DIS_IS_FRAGMENT;
 			if (ntohs(flow_spec->etype) == ETH_P_IP) {
-				flow_spec->ip_flag = IPV4_FLAG_MORE;
+				flow_spec->ip_flag = val ? IPV4_FLAG_MORE : 0;
 				flow_mask->ip_flag = IPV4_FLAG_MORE;
 				req->features |= BIT_ULL(NPC_IPFRAG_IPV4);
 			} else if (ntohs(flow_spec->etype) == ETH_P_IPV6) {
-				flow_spec->next_header = IPPROTO_FRAGMENT;
+				flow_spec->next_header = val ?
+							 IPPROTO_FRAGMENT : 0;
 				flow_mask->next_header = 0xff;
 				req->features |= BIT_ULL(NPC_IPFRAG_IPV6);
 			} else {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
@@ -510,7 +510,7 @@
 
 static void otx2_adjust_adaptive_coalese(struct otx2_nic *pfvf, struct otx2_cq_poll *cq_poll)
 {
-	struct dim_sample dim_sample;
+	struct dim_sample dim_sample = { 0 };
 	u64 rx_frames, rx_bytes;
 	u64 tx_frames, tx_bytes;
 
@@ -1171,8 +1171,11 @@
 
 	if (skb_shinfo(skb)->gso_size && !is_hw_tso_supported(pfvf, skb)) {
 		/* Insert vlan tag before giving pkt to tso */
-		if (skb_vlan_tag_present(skb))
+		if (skb_vlan_tag_present(skb)) {
 			skb = __vlan_hwaccel_push_inside(skb);
+			if (!skb)
+				return true;
+		}
 		otx2_sq_append_tso(pfvf, sq, skb, qidx);
 		return true;
 	}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
@@ -89,16 +89,20 @@
 	struct otx2_mbox *mbox;
 	struct mbox *af_mbox;
 	int offset, id;
+	u16 num_msgs;
 
 	af_mbox = container_of(work, struct mbox, mbox_wrk);
 	mbox = &af_mbox->mbox;
 	mdev = &mbox->dev[0];
 	rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
-	if (af_mbox->num_msgs == 0)
+	num_msgs = rsp_hdr->num_msgs;
+
+	if (num_msgs == 0)
 		return;
+
 	offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
 
-	for (id = 0; id < af_mbox->num_msgs; id++) {
+	for (id = 0; id < num_msgs; id++) {
 		msg = (struct mbox_msghdr *)(mdev->mbase + offset);
 		otx2vf_process_vfaf_mbox_msg(af_mbox->pfvf, msg);
 		offset = mbox->rx_start + msg->next_msgoff;
@@ -151,6 +155,7 @@
 	struct mbox *vf_mbox;
 	struct otx2_nic *vf;
 	int offset, id;
+	u16 num_msgs;
 
 	vf_mbox = container_of(work, struct mbox, mbox_up_wrk);
 	vf = vf_mbox->pfvf;
@@ -158,12 +163,14 @@
 	mdev = &mbox->dev[0];
 
 	rsp_hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
-	if (vf_mbox->up_num_msgs == 0)
+	num_msgs = rsp_hdr->num_msgs;
+
+	if (num_msgs == 0)
 		return;
 
 	offset = mbox->rx_start + ALIGN(sizeof(*rsp_hdr), MBOX_MSG_ALIGN);
 
-	for (id = 0; id < vf_mbox->up_num_msgs; id++) {
+	for (id = 0; id < num_msgs; id++) {
 		msg = (struct mbox_msghdr *)(mdev->mbase + offset);
 		otx2vf_process_mbox_msg_up(vf, msg);
 		offset = mbox->rx_start + msg->next_msgoff;
@@ -178,40 +185,48 @@
 	struct otx2_mbox_dev *mdev;
 	struct otx2_mbox *mbox;
 	struct mbox_hdr *hdr;
+	u64 mbox_data;
 
 	/* Clear the IRQ */
 	otx2_write64(vf, RVU_VF_INT, BIT_ULL(0));
 
+	mbox_data = otx2_read64(vf, RVU_VF_VFPF_MBOX0);
+
 	/* Read latest mbox data */
 	smp_rmb();
 
-	/* Check for PF => VF response messages */
-	mbox = &vf->mbox.mbox;
-	mdev = &mbox->dev[0];
-	otx2_sync_mbox_bbuf(mbox, 0);
-
-	trace_otx2_msg_interrupt(mbox->pdev, "PF to VF", BIT_ULL(0));
+	if (mbox_data & MBOX_DOWN_MSG) {
+		mbox_data &= ~MBOX_DOWN_MSG;
+		otx2_write64(vf, RVU_VF_VFPF_MBOX0, mbox_data);
+
+		/* Check for PF => VF response messages */
+		mbox = &vf->mbox.mbox;
+		mdev = &mbox->dev[0];
+		otx2_sync_mbox_bbuf(mbox, 0);
+
+		hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
+		if (hdr->num_msgs)
+			queue_work(vf->mbox_wq, &vf->mbox.mbox_wrk);
+
+		trace_otx2_msg_interrupt(mbox->pdev, "DOWN reply from PF to VF",
+					 BIT_ULL(0));
+	}
+
+	if (mbox_data & MBOX_UP_MSG) {
+		mbox_data &= ~MBOX_UP_MSG;
+		otx2_write64(vf, RVU_VF_VFPF_MBOX0, mbox_data);
+
+		/* Check for PF => VF notification messages */
+		mbox = &vf->mbox.mbox_up;
+		mdev = &mbox->dev[0];
+		otx2_sync_mbox_bbuf(mbox, 0);
+
+		hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
+		if (hdr->num_msgs)
+			queue_work(vf->mbox_wq, &vf->mbox.mbox_up_wrk);
 
-	hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
-	if (hdr->num_msgs) {
-		vf->mbox.num_msgs = hdr->num_msgs;
-		hdr->num_msgs = 0;
-		memset(mbox->hwbase + mbox->rx_start, 0,
-		       ALIGN(sizeof(struct mbox_hdr), sizeof(u64)));
-		queue_work(vf->mbox_wq, &vf->mbox.mbox_wrk);
-	}
-	/* Check for PF => VF notification messages */
-	mbox = &vf->mbox.mbox_up;
-	mdev = &mbox->dev[0];
-	otx2_sync_mbox_bbuf(mbox, 0);
-
-	hdr = (struct mbox_hdr *)(mdev->mbase + mbox->rx_start);
-	if (hdr->num_msgs) {
-		vf->mbox.up_num_msgs = hdr->num_msgs;
-		hdr->num_msgs = 0;
-		memset(mbox->hwbase + mbox->rx_start, 0,
-		       ALIGN(sizeof(struct mbox_hdr), sizeof(u64)));
-		queue_work(vf->mbox_wq, &vf->mbox.mbox_up_wrk);
+		trace_otx2_msg_interrupt(mbox->pdev, "UP message from PF to VF",
+					 BIT_ULL(0));
 	}
 
 	return IRQ_HANDLED;
@@ -760,8 +775,8 @@
 	otx2_mcam_flow_del(vf);
 	otx2_shutdown_tc(vf);
 	otx2_shutdown_qos(vf);
-	otx2vf_disable_mbox_intr(vf);
 	otx2_detach_resources(&vf->mbox);
+	otx2vf_disable_mbox_intr(vf);
 	free_percpu(vf->hw.lmt_info);
 	if (test_bit(CN10K_LMTST, &vf->hw.cap_flag))
 		qmem_free(vf->dev, vf->dync_lmt);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
@@ -153,7 +153,6 @@
 		num_regs++;
 
 		otx2_config_sched_shaping(pfvf, node, cfg, &num_regs);
-
 	} else if (level == NIX_TXSCH_LVL_TL4) {
 		otx2_config_sched_shaping(pfvf, node, cfg, &num_regs);
 	} else if (level == NIX_TXSCH_LVL_TL3) {
@@ -176,7 +175,7 @@
 		/* check if node is root */
 		if (node->qid == OTX2_QOS_QID_INNER && !node->parent) {
 			cfg->reg[num_regs] = NIX_AF_TL2X_SCHEDULE(node->schq);
-			cfg->regval[num_regs] =  TXSCH_TL1_DFLT_RR_PRIO << 24 |
+			cfg->regval[num_regs] =  (u64)hw->txschq_aggr_lvl_rr_prio << 24 |
 						 mtu_to_dwrr_weight(pfvf,
 								    pfvf->tx_max_pktlen);
 			num_regs++;
@@ -382,6 +381,7 @@
 		otx2_qos_read_txschq_cfg_tl(node, cfg);
 		cnt = cfg->static_node_pos[node->level];
 		cfg->schq_contig_list[node->level][cnt] = node->schq;
+		cfg->schq_index_used[node->level][cnt] = true;
 		cfg->schq_contig[node->level]++;
 		cfg->static_node_pos[node->level]++;
 		otx2_qos_read_txschq_cfg_schq(node, cfg);
@@ -1406,7 +1406,10 @@
 	otx2_qos_read_txschq_cfg(pfvf, node, old_cfg);
 
 	/* delete the txschq nodes allocated for this node */
+	otx2_qos_disable_sq(pfvf, qid);
+	otx2_qos_free_hw_node_schq(pfvf, node);
 	otx2_qos_free_sw_node_schq(pfvf, node);
+	pfvf->qos.qid_to_sqmap[qid] = OTX2_QOS_INVALID_SQ;
 
 	/* mark this node as htb inner node */
 	WRITE_ONCE(node->qid, OTX2_QOS_QID_INNER);
@@ -1553,6 +1556,7 @@
 		dwrr_del_node = true;
 
 	/* destroy the leaf node */
+	otx2_qos_disable_sq(pfvf, qid);
 	otx2_qos_destroy_node(pfvf, node);
 	pfvf->qos.qid_to_sqmap[qid] = OTX2_QOS_INVALID_SQ;
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/pxa168_eth.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -1394,18 +1394,15 @@
 
 	printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n");
 
-	clk = devm_clk_get(&pdev->dev, NULL);
+	clk = devm_clk_get_enabled(&pdev->dev, NULL);
 	if (IS_ERR(clk)) {
-		dev_err(&pdev->dev, "Fast Ethernet failed to get clock\n");
+		dev_err(&pdev->dev, "Fast Ethernet failed to get and enable clock\n");
 		return -ENODEV;
 	}
-	clk_prepare_enable(clk);
 
 	dev = alloc_etherdev(sizeof(struct pxa168_eth_private));
-	if (!dev) {
-		err = -ENOMEM;
-		goto err_clk;
-	}
+	if (!dev)
+		return -ENOMEM;
 
 	platform_set_drvdata(pdev, dev);
 	pep = netdev_priv(dev);
@@ -1523,8 +1520,6 @@
 	mdiobus_free(pep->smi_bus);
 err_netdev:
 	free_netdev(dev);
-err_clk:
-	clk_disable_unprepare(clk);
 	return err;
 }
 
@@ -1542,7 +1537,6 @@
 	if (dev->phydev)
 		phy_disconnect(dev->phydev);
 
-	clk_disable_unprepare(pep->clk);
 	mdiobus_unregister(pep->smi_bus);
 	mdiobus_free(pep->smi_bus);
 	unregister_netdev(dev);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/marvell/sky2.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/marvell/sky2.c
@@ -129,6 +129,7 @@
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436C) }, /* 88E8072 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436D) }, /* 88E8055 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4370) }, /* 88E8075 */
+	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4373) }, /* 88E8075 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4380) }, /* 88E8057 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4381) }, /* 88E8059 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4382) }, /* 88E8079 */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -110,16 +110,16 @@
 	.tx_irq_mask		= 0x461c,
 	.tx_irq_status		= 0x4618,
 	.pdma = {
-		.rx_ptr		= 0x6100,
-		.rx_cnt_cfg	= 0x6104,
-		.pcrx_ptr	= 0x6108,
-		.glo_cfg	= 0x6204,
-		.rst_idx	= 0x6208,
-		.delay_irq	= 0x620c,
-		.irq_status	= 0x6220,
-		.irq_mask	= 0x6228,
-		.adma_rx_dbg0	= 0x6238,
-		.int_grp	= 0x6250,
+		.rx_ptr		= 0x4100,
+		.rx_cnt_cfg	= 0x4104,
+		.pcrx_ptr	= 0x4108,
+		.glo_cfg	= 0x4204,
+		.rst_idx	= 0x4208,
+		.delay_irq	= 0x420c,
+		.irq_status	= 0x4220,
+		.irq_mask	= 0x4228,
+		.adma_rx_dbg0	= 0x4238,
+		.int_grp	= 0x4250,
 	},
 	.qdma = {
 		.qtx_cfg	= 0x4400,
@@ -677,8 +677,7 @@
 	mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
 	mcr_new = mcr_cur;
 	mcr_new |= MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE |
-		   MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK |
-		   MAC_MCR_RX_FIFO_CLR_DIS;
+		   MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_RX_FIFO_CLR_DIS;
 
 	/* Only update control register when needed! */
 	if (mcr_new != mcr_cur)
@@ -694,7 +693,7 @@
 					   phylink_config);
 	u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
 
-	mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN);
+	mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK);
 	mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
 }
 
@@ -803,7 +802,7 @@
 	if (rx_pause)
 		mcr |= MAC_MCR_FORCE_RX_FC;
 
-	mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN;
+	mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK;
 	mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
 }
 
@@ -1108,7 +1107,7 @@
 	rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
 	rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
 	rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
-	if (mtk_is_netsys_v2_or_greater(eth)) {
+	if (mtk_is_netsys_v3_or_greater(eth)) {
 		rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
 		rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
 	}
@@ -1132,51 +1131,57 @@
 {
 	const struct mtk_soc_data *soc = eth->soc;
 	dma_addr_t phy_ring_tail;
-	int cnt = MTK_QDMA_RING_SIZE;
+	int cnt = soc->tx.fq_dma_size;
 	dma_addr_t dma_addr;
-	int i;
+	int i, j, len;
 
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM))
 		eth->scratch_ring = eth->sram_base;
 	else
 		eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
-						       cnt * soc->txrx.txd_size,
+						       cnt * soc->tx.desc_size,
 						       &eth->phy_scratch_ring,
 						       GFP_KERNEL);
+
 	if (unlikely(!eth->scratch_ring))
 		return -ENOMEM;
 
-	eth->scratch_head = kcalloc(cnt, MTK_QDMA_PAGE_SIZE, GFP_KERNEL);
-	if (unlikely(!eth->scratch_head))
-		return -ENOMEM;
+	phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1);
 
-	dma_addr = dma_map_single(eth->dma_dev,
-				  eth->scratch_head, cnt * MTK_QDMA_PAGE_SIZE,
-				  DMA_FROM_DEVICE);
-	if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
-		return -ENOMEM;
+	for (j = 0; j < DIV_ROUND_UP(soc->tx.fq_dma_size, MTK_FQ_DMA_LENGTH); j++) {
+		len = min_t(int, cnt - j * MTK_FQ_DMA_LENGTH, MTK_FQ_DMA_LENGTH);
+		eth->scratch_head[j] = kcalloc(len, MTK_QDMA_PAGE_SIZE, GFP_KERNEL);
+
+		if (unlikely(!eth->scratch_head[j]))
+			return -ENOMEM;
 
-	phy_ring_tail = eth->phy_scratch_ring + soc->txrx.txd_size * (cnt - 1);
+		dma_addr = dma_map_single(eth->dma_dev,
+					  eth->scratch_head[j], len * MTK_QDMA_PAGE_SIZE,
+					  DMA_FROM_DEVICE);
 
-	for (i = 0; i < cnt; i++) {
-		dma_addr_t addr = dma_addr + i * MTK_QDMA_PAGE_SIZE;
-		struct mtk_tx_dma_v2 *txd;
-
-		txd = eth->scratch_ring + i * soc->txrx.txd_size;
-		txd->txd1 = addr;
-		if (i < cnt - 1)
-			txd->txd2 = eth->phy_scratch_ring +
-				    (i + 1) * soc->txrx.txd_size;
-
-		txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
-		if (MTK_HAS_CAPS(soc->caps, MTK_36BIT_DMA))
-			txd->txd3 |= TX_DMA_PREP_ADDR64(addr);
-		txd->txd4 = 0;
-		if (mtk_is_netsys_v2_or_greater(eth)) {
-			txd->txd5 = 0;
-			txd->txd6 = 0;
-			txd->txd7 = 0;
-			txd->txd8 = 0;
+		if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
+			return -ENOMEM;
+
+		for (i = 0; i < len; i++) {
+			struct mtk_tx_dma_v2 *txd;
+
+			txd = eth->scratch_ring + (j * MTK_FQ_DMA_LENGTH + i) * soc->tx.desc_size;
+			txd->txd1 = dma_addr + i * MTK_QDMA_PAGE_SIZE;
+			if (j * MTK_FQ_DMA_LENGTH + i < cnt)
+				txd->txd2 = eth->phy_scratch_ring +
+					    (j * MTK_FQ_DMA_LENGTH + i + 1) * soc->tx.desc_size;
+
+			txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
+			if (MTK_HAS_CAPS(soc->caps, MTK_36BIT_DMA))
+				txd->txd3 |= TX_DMA_PREP_ADDR64(dma_addr + i * MTK_QDMA_PAGE_SIZE);
+
+			txd->txd4 = 0;
+			if (mtk_is_netsys_v2_or_greater(eth)) {
+				txd->txd5 = 0;
+				txd->txd6 = 0;
+				txd->txd7 = 0;
+				txd->txd8 = 0;
+			}
 		}
 	}
 
@@ -1417,7 +1422,7 @@
 	if (itxd == ring->last_free)
 		return -ENOMEM;
 
-	itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->txrx.txd_size);
+	itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size);
 	memset(itx_buf, 0, sizeof(*itx_buf));
 
 	txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size,
@@ -1458,7 +1463,7 @@
 
 			memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
 			txd_info.size = min_t(unsigned int, frag_size,
-					      soc->txrx.dma_max_len);
+					      soc->tx.dma_max_len);
 			txd_info.qid = queue;
 			txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 &&
 					!(frag_size - txd_info.size);
@@ -1471,7 +1476,7 @@
 			mtk_tx_set_dma_desc(dev, txd, &txd_info);
 
 			tx_buf = mtk_desc_to_tx_buf(ring, txd,
-						    soc->txrx.txd_size);
+						    soc->tx.desc_size);
 			if (new_desc)
 				memset(tx_buf, 0, sizeof(*tx_buf));
 			tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
@@ -1514,7 +1519,7 @@
 	} else {
 		int next_idx;
 
-		next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->txrx.txd_size),
+		next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->tx.desc_size),
 					 ring->dma_size);
 		mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0);
 	}
@@ -1523,7 +1528,7 @@
 
 err_dma:
 	do {
-		tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->txrx.txd_size);
+		tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size);
 
 		/* unmap dma */
 		mtk_tx_unmap(eth, tx_buf, NULL, false);
@@ -1548,7 +1553,7 @@
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 			frag = &skb_shinfo(skb)->frags[i];
 			nfrags += DIV_ROUND_UP(skb_frag_size(frag),
-					       eth->soc->txrx.dma_max_len);
+					       eth->soc->tx.dma_max_len);
 		}
 	} else {
 		nfrags += skb_shinfo(skb)->nr_frags;
@@ -1655,7 +1660,7 @@
 
 		ring = &eth->rx_ring[i];
 		idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
-		rxd = ring->dma + idx * eth->soc->txrx.rxd_size;
+		rxd = ring->dma + idx * eth->soc->rx.desc_size;
 		if (rxd->rxd2 & RX_DMA_DONE) {
 			ring->calc_idx_update = true;
 			return ring;
@@ -1823,7 +1828,7 @@
 	}
 	htxd = txd;
 
-	tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->txrx.txd_size);
+	tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->tx.desc_size);
 	memset(tx_buf, 0, sizeof(*tx_buf));
 	htx_buf = tx_buf;
 
@@ -1842,7 +1847,7 @@
 				goto unmap;
 
 			tx_buf = mtk_desc_to_tx_buf(ring, txd,
-						    soc->txrx.txd_size);
+						    soc->tx.desc_size);
 			memset(tx_buf, 0, sizeof(*tx_buf));
 			n_desc++;
 		}
@@ -1880,7 +1885,7 @@
 	} else {
 		int idx;
 
-		idx = txd_to_idx(ring, txd, soc->txrx.txd_size);
+		idx = txd_to_idx(ring, txd, soc->tx.desc_size);
 		mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size),
 			MT7628_TX_CTX_IDX0);
 	}
@@ -1891,7 +1896,7 @@
 
 unmap:
 	while (htxd != txd) {
-		tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->txrx.txd_size);
+		tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->tx.desc_size);
 		mtk_tx_unmap(eth, tx_buf, NULL, false);
 
 		htxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
@@ -2022,14 +2027,14 @@
 			goto rx_done;
 
 		idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
-		rxd = ring->dma + idx * eth->soc->txrx.rxd_size;
+		rxd = ring->dma + idx * eth->soc->rx.desc_size;
 		data = ring->data[idx];
 
 		if (!mtk_rx_get_desc(eth, &trxd, rxd))
 			break;
 
 		/* find out which mac the packet come from. values start at 1 */
-		if (mtk_is_netsys_v2_or_greater(eth)) {
+		if (mtk_is_netsys_v3_or_greater(eth)) {
 			u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
 
 			switch (val) {
@@ -2141,7 +2146,7 @@
 		skb->dev = netdev;
 		bytes += skb->len;
 
-		if (mtk_is_netsys_v2_or_greater(eth)) {
+		if (mtk_is_netsys_v3_or_greater(eth)) {
 			reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
 			hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
 			if (hash != MTK_RXD5_FOE_ENTRY)
@@ -2157,7 +2162,7 @@
 			rxdcsum = &trxd.rxd4;
 		}
 
-		if (*rxdcsum & eth->soc->txrx.rx_dma_l4_valid)
+		if (*rxdcsum & eth->soc->rx.dma_l4_valid)
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 		else
 			skb_checksum_none_assert(skb);
@@ -2281,7 +2286,7 @@
 			break;
 
 		tx_buf = mtk_desc_to_tx_buf(ring, desc,
-					    eth->soc->txrx.txd_size);
+					    eth->soc->tx.desc_size);
 		if (!tx_buf->data)
 			break;
 
@@ -2332,7 +2337,7 @@
 		}
 		mtk_tx_unmap(eth, tx_buf, &bq, true);
 
-		desc = ring->dma + cpu * eth->soc->txrx.txd_size;
+		desc = ring->dma + cpu * eth->soc->tx.desc_size;
 		ring->last_free = desc;
 		atomic_inc(&ring->free_count);
 
@@ -2422,7 +2427,7 @@
 	do {
 		int rx_done;
 
-		mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask,
+		mtk_w32(eth, eth->soc->rx.irq_done_mask,
 			reg_map->pdma.irq_status);
 		rx_done = mtk_poll_rx(napi, budget - rx_done_total, eth);
 		rx_done_total += rx_done;
@@ -2438,10 +2443,10 @@
 			return budget;
 
 	} while (mtk_r32(eth, reg_map->pdma.irq_status) &
-		 eth->soc->txrx.rx_irq_done_mask);
+		 eth->soc->rx.irq_done_mask);
 
 	if (napi_complete_done(napi, rx_done_total))
-		mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask);
+		mtk_rx_irq_enable(eth, eth->soc->rx.irq_done_mask);
 
 	return rx_done_total;
 }
@@ -2450,7 +2455,7 @@
 {
 	const struct mtk_soc_data *soc = eth->soc;
 	struct mtk_tx_ring *ring = &eth->tx_ring;
-	int i, sz = soc->txrx.txd_size;
+	int i, sz = soc->tx.desc_size;
 	struct mtk_tx_dma_v2 *txd;
 	int ring_size;
 	u32 ofs, val;
@@ -2458,7 +2463,7 @@
 	if (MTK_HAS_CAPS(soc->caps, MTK_QDMA))
 		ring_size = MTK_QDMA_RING_SIZE;
 	else
-		ring_size = MTK_DMA_SIZE;
+		ring_size = soc->tx.dma_size;
 
 	ring->buf = kcalloc(ring_size, sizeof(*ring->buf),
 			       GFP_KERNEL);
@@ -2466,8 +2471,8 @@
 		goto no_tx_mem;
 
 	if (MTK_HAS_CAPS(soc->caps, MTK_SRAM)) {
-		ring->dma = eth->sram_base + ring_size * sz;
-		ring->phys = eth->phy_scratch_ring + ring_size * (dma_addr_t)sz;
+		ring->dma = eth->sram_base + soc->tx.fq_dma_size * sz;
+		ring->phys = eth->phy_scratch_ring + soc->tx.fq_dma_size * (dma_addr_t)sz;
 	} else {
 		ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
 					       &ring->phys, GFP_KERNEL);
@@ -2573,14 +2578,14 @@
 	}
 	if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) {
 		dma_free_coherent(eth->dma_dev,
-				  ring->dma_size * soc->txrx.txd_size,
+				  ring->dma_size * soc->tx.desc_size,
 				  ring->dma, ring->phys);
 		ring->dma = NULL;
 	}
 
 	if (ring->dma_pdma) {
 		dma_free_coherent(eth->dma_dev,
-				  ring->dma_size * soc->txrx.txd_size,
+				  ring->dma_size * soc->tx.desc_size,
 				  ring->dma_pdma, ring->phys_pdma);
 		ring->dma_pdma = NULL;
 	}
@@ -2589,6 +2594,7 @@
 static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
 {
 	const struct mtk_reg_map *reg_map = eth->soc->reg_map;
+	const struct mtk_soc_data *soc = eth->soc;
 	struct mtk_rx_ring *ring;
 	int rx_data_len, rx_dma_size, tx_ring_size;
 	int i;
@@ -2596,7 +2602,7 @@
 	if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
 		tx_ring_size = MTK_QDMA_RING_SIZE;
 	else
-		tx_ring_size = MTK_DMA_SIZE;
+		tx_ring_size = soc->tx.dma_size;
 
 	if (rx_flag == MTK_RX_FLAGS_QDMA) {
 		if (ring_no)
@@ -2611,7 +2617,7 @@
 		rx_dma_size = MTK_HW_LRO_DMA_SIZE;
 	} else {
 		rx_data_len = ETH_DATA_LEN;
-		rx_dma_size = MTK_DMA_SIZE;
+		rx_dma_size = soc->rx.dma_size;
 	}
 
 	ring->frag_size = mtk_max_frag_size(rx_data_len);
@@ -2635,15 +2641,15 @@
 	if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) ||
 	    rx_flag != MTK_RX_FLAGS_NORMAL) {
 		ring->dma = dma_alloc_coherent(eth->dma_dev,
-					       rx_dma_size * eth->soc->txrx.rxd_size,
-					       &ring->phys, GFP_KERNEL);
+				rx_dma_size * eth->soc->rx.desc_size,
+				&ring->phys, GFP_KERNEL);
 	} else {
 		struct mtk_tx_ring *tx_ring = &eth->tx_ring;
 
 		ring->dma = tx_ring->dma + tx_ring_size *
-			    eth->soc->txrx.txd_size * (ring_no + 1);
+			    eth->soc->tx.desc_size * (ring_no + 1);
 		ring->phys = tx_ring->phys + tx_ring_size *
-			     eth->soc->txrx.txd_size * (ring_no + 1);
+			     eth->soc->tx.desc_size * (ring_no + 1);
 	}
 
 	if (!ring->dma)
@@ -2654,7 +2660,7 @@
 		dma_addr_t dma_addr;
 		void *data;
 
-		rxd = ring->dma + i * eth->soc->txrx.rxd_size;
+		rxd = ring->dma + i * eth->soc->rx.desc_size;
 		if (ring->page_pool) {
 			data = mtk_page_pool_get_buff(ring->page_pool,
 						      &dma_addr, GFP_KERNEL);
@@ -2691,7 +2697,7 @@
 
 		rxd->rxd3 = 0;
 		rxd->rxd4 = 0;
-		if (mtk_is_netsys_v2_or_greater(eth)) {
+		if (mtk_is_netsys_v3_or_greater(eth)) {
 			rxd->rxd5 = 0;
 			rxd->rxd6 = 0;
 			rxd->rxd7 = 0;
@@ -2745,7 +2751,7 @@
 			if (!ring->data[i])
 				continue;
 
-			rxd = ring->dma + i * eth->soc->txrx.rxd_size;
+			rxd = ring->dma + i * eth->soc->rx.desc_size;
 			if (!rxd->rxd1)
 				continue;
 
@@ -2762,7 +2768,7 @@
 
 	if (!in_sram && ring->dma) {
 		dma_free_coherent(eth->dma_dev,
-				  ring->dma_size * eth->soc->txrx.rxd_size,
+				  ring->dma_size * eth->soc->rx.desc_size,
 				  ring->dma, ring->phys);
 		ring->dma = NULL;
 	}
@@ -3125,7 +3131,7 @@
 			netdev_reset_queue(eth->netdev[i]);
 	if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) {
 		dma_free_coherent(eth->dma_dev,
-				  MTK_QDMA_RING_SIZE * soc->txrx.txd_size,
+				  MTK_QDMA_RING_SIZE * soc->tx.desc_size,
 				  eth->scratch_ring, eth->phy_scratch_ring);
 		eth->scratch_ring = NULL;
 		eth->phy_scratch_ring = 0;
@@ -3140,7 +3146,10 @@
 			mtk_rx_clean(eth, &eth->rx_ring[i], false);
 	}
 
-	kfree(eth->scratch_head);
+	for (i = 0; i < DIV_ROUND_UP(soc->tx.fq_dma_size, MTK_FQ_DMA_LENGTH); i++) {
+		kfree(eth->scratch_head[i]);
+		eth->scratch_head[i] = NULL;
+	}
 }
 
 static bool mtk_hw_reset_check(struct mtk_eth *eth)
@@ -3175,7 +3184,7 @@
 
 	eth->rx_events++;
 	if (likely(napi_schedule_prep(&eth->rx_napi))) {
-		mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
+		mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
 		__napi_schedule(&eth->rx_napi);
 	}
 
@@ -3201,9 +3210,9 @@
 	const struct mtk_reg_map *reg_map = eth->soc->reg_map;
 
 	if (mtk_r32(eth, reg_map->pdma.irq_mask) &
-	    eth->soc->txrx.rx_irq_done_mask) {
+	    eth->soc->rx.irq_done_mask) {
 		if (mtk_r32(eth, reg_map->pdma.irq_status) &
-		    eth->soc->txrx.rx_irq_done_mask)
+		    eth->soc->rx.irq_done_mask)
 			mtk_handle_irq_rx(irq, _eth);
 	}
 	if (mtk_r32(eth, reg_map->tx_irq_mask) & MTK_TX_DONE_INT) {
@@ -3221,10 +3230,10 @@
 	struct mtk_eth *eth = mac->hw;
 
 	mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
-	mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
+	mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
 	mtk_handle_irq_rx(eth->irq[2], dev);
 	mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
-	mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask);
+	mtk_rx_irq_enable(eth, eth->soc->rx.irq_done_mask);
 }
 #endif
 
@@ -3388,7 +3397,7 @@
 		napi_enable(&eth->tx_napi);
 		napi_enable(&eth->rx_napi);
 		mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
-		mtk_rx_irq_enable(eth, soc->txrx.rx_irq_done_mask);
+		mtk_rx_irq_enable(eth, soc->rx.irq_done_mask);
 		refcount_set(&eth->dma_refcnt, 1);
 	}
 	else
@@ -3472,7 +3481,7 @@
 	mtk_gdm_config(eth, MTK_GDMA_DROP_ALL);
 
 	mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
-	mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask);
+	mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
 	napi_disable(&eth->tx_napi);
 	napi_disable(&eth->rx_napi);
 
@@ -3894,7 +3903,7 @@
 	else
 		mtk_hw_reset(eth);
 
-	if (mtk_is_netsys_v2_or_greater(eth)) {
+	if (mtk_is_netsys_v3_or_greater(eth)) {
 		/* Set FE to PDMAv2 if necessary */
 		val = mtk_r32(eth, MTK_FE_GLO_MISC);
 		mtk_w32(eth,  val | BIT(4), MTK_FE_GLO_MISC);
@@ -3948,9 +3957,9 @@
 
 	/* FE int grouping */
 	mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp);
-	mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->pdma.int_grp + 4);
+	mtk_w32(eth, eth->soc->rx.irq_done_mask, reg_map->pdma.int_grp + 4);
 	mtk_w32(eth, MTK_TX_DONE_INT, reg_map->qdma.int_grp);
-	mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
+	mtk_w32(eth, eth->soc->rx.irq_done_mask, reg_map->qdma.int_grp + 4);
 	mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
 
 	if (mtk_is_netsys_v3_or_greater(eth)) {
@@ -5040,11 +5049,18 @@
 	.required_clks = MT7623_CLKS_BITMAP,
 	.required_pctl = true,
 	.version = 1,
-	.txrx = {
-		.txd_size = sizeof(struct mtk_tx_dma),
-		.rxd_size = sizeof(struct mtk_rx_dma),
-		.rx_irq_done_mask = MTK_RX_DONE_INT,
-		.rx_dma_l4_valid = RX_DMA_L4_VALID,
+	.tx = {
+		.desc_size = sizeof(struct mtk_tx_dma),
+		.dma_max_len = MTK_TX_DMA_BUF_LEN,
+		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(2K),
+	},
+	.rx = {
+		.desc_size = sizeof(struct mtk_rx_dma),
+		.irq_done_mask = MTK_RX_DONE_INT,
+		.dma_l4_valid = RX_DMA_L4_VALID,
+		.dma_size = MTK_DMA_SIZE(2K),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
 	},
@@ -5060,11 +5076,18 @@
 	.offload_version = 1,
 	.hash_offset = 2,
 	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
-	.txrx = {
-		.txd_size = sizeof(struct mtk_tx_dma),
-		.rxd_size = sizeof(struct mtk_rx_dma),
-		.rx_irq_done_mask = MTK_RX_DONE_INT,
-		.rx_dma_l4_valid = RX_DMA_L4_VALID,
+	.tx = {
+		.desc_size = sizeof(struct mtk_tx_dma),
+		.dma_max_len = MTK_TX_DMA_BUF_LEN,
+		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(2K),
+	},
+	.rx = {
+		.desc_size = sizeof(struct mtk_rx_dma),
+		.irq_done_mask = MTK_RX_DONE_INT,
+		.dma_l4_valid = RX_DMA_L4_VALID,
+		.dma_size = MTK_DMA_SIZE(2K),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
 	},
@@ -5082,11 +5105,18 @@
 	.hash_offset = 2,
 	.has_accounting = true,
 	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
-	.txrx = {
-		.txd_size = sizeof(struct mtk_tx_dma),
-		.rxd_size = sizeof(struct mtk_rx_dma),
-		.rx_irq_done_mask = MTK_RX_DONE_INT,
-		.rx_dma_l4_valid = RX_DMA_L4_VALID,
+	.tx = {
+		.desc_size = sizeof(struct mtk_tx_dma),
+		.dma_max_len = MTK_TX_DMA_BUF_LEN,
+		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(2K),
+	},
+	.rx = {
+		.desc_size = sizeof(struct mtk_rx_dma),
+		.irq_done_mask = MTK_RX_DONE_INT,
+		.dma_l4_valid = RX_DMA_L4_VALID,
+		.dma_size = MTK_DMA_SIZE(2K),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
 	},
@@ -5103,11 +5133,18 @@
 	.hash_offset = 2,
 	.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
 	.disable_pll_modes = true,
-	.txrx = {
-		.txd_size = sizeof(struct mtk_tx_dma),
-		.rxd_size = sizeof(struct mtk_rx_dma),
-		.rx_irq_done_mask = MTK_RX_DONE_INT,
-		.rx_dma_l4_valid = RX_DMA_L4_VALID,
+	.tx = {
+		.desc_size = sizeof(struct mtk_tx_dma),
+		.dma_max_len = MTK_TX_DMA_BUF_LEN,
+		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(2K),
+	},
+	.rx = {
+		.desc_size = sizeof(struct mtk_rx_dma),
+		.irq_done_mask = MTK_RX_DONE_INT,
+		.dma_l4_valid = RX_DMA_L4_VALID,
+		.dma_size = MTK_DMA_SIZE(2K),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
 	},
@@ -5122,11 +5159,18 @@
 	.required_pctl = false,
 	.has_accounting = true,
 	.version = 1,
-	.txrx = {
-		.txd_size = sizeof(struct mtk_tx_dma),
-		.rxd_size = sizeof(struct mtk_rx_dma),
-		.rx_irq_done_mask = MTK_RX_DONE_INT,
-		.rx_dma_l4_valid = RX_DMA_L4_VALID,
+	.tx = {
+		.desc_size = sizeof(struct mtk_tx_dma),
+		.dma_max_len = MTK_TX_DMA_BUF_LEN,
+		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(2K),
+	},
+	.rx = {
+		.desc_size = sizeof(struct mtk_rx_dma),
+		.irq_done_mask = MTK_RX_DONE_INT,
+		.dma_l4_valid = RX_DMA_L4_VALID,
+		.dma_size = MTK_DMA_SIZE(2K),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
 	},
@@ -5144,13 +5188,20 @@
 	.hash_offset = 4,
 	.has_accounting = true,
 	.foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
-	.txrx = {
-		.txd_size = sizeof(struct mtk_tx_dma_v2),
-		.rxd_size = sizeof(struct mtk_rx_dma_v2),
-		.rx_irq_done_mask = MTK_RX_DONE_INT_V2,
-		.rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
+	.tx = {
+		.desc_size = sizeof(struct mtk_tx_dma_v2),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
 		.dma_len_offset = 8,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(2K),
+	},
+	.rx = {
+		.desc_size = sizeof(struct mtk_rx_dma),
+		.irq_done_mask = MTK_RX_DONE_INT,
+		.dma_l4_valid = RX_DMA_L4_VALID_V2,
+		.dma_max_len = MTK_TX_DMA_BUF_LEN,
+		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
 	},
 };
 
@@ -5166,13 +5217,20 @@
 	.hash_offset = 4,
 	.has_accounting = true,
 	.foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
-	.txrx = {
-		.txd_size = sizeof(struct mtk_tx_dma_v2),
-		.rxd_size = sizeof(struct mtk_rx_dma_v2),
-		.rx_irq_done_mask = MTK_RX_DONE_INT_V2,
-		.rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
+	.tx = {
+		.desc_size = sizeof(struct mtk_tx_dma_v2),
 		.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
 		.dma_len_offset = 8,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(2K),
+	},
+	.rx = {
+		.desc_size = sizeof(struct mtk_rx_dma),
+		.irq_done_mask = MTK_RX_DONE_INT,
+		.dma_l4_valid = RX_DMA_L4_VALID_V2,
+		.dma_max_len = MTK_TX_DMA_BUF_LEN,
+		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
 	},
 };
 
@@ -5188,13 +5246,20 @@
 	.hash_offset = 4,
 	.has_accounting = true,
 	.foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
-	.txrx = {
-		.txd_size = sizeof(struct mtk_tx_dma_v2),
-		.rxd_size = sizeof(struct mtk_rx_dma_v2),
-		.rx_irq_done_mask = MTK_RX_DONE_INT_V2,
-		.rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
+	.tx = {
+		.desc_size = sizeof(struct mtk_tx_dma_v2),
+		.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
+		.dma_len_offset = 8,
+		.dma_size = MTK_DMA_SIZE(2K),
+		.fq_dma_size = MTK_DMA_SIZE(4K),
+	},
+	.rx = {
+		.desc_size = sizeof(struct mtk_rx_dma_v2),
+		.irq_done_mask = MTK_RX_DONE_INT_V2,
+		.dma_l4_valid = RX_DMA_L4_VALID_V2,
 		.dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
 		.dma_len_offset = 8,
+		.dma_size = MTK_DMA_SIZE(2K),
 	},
 };
 
@@ -5205,13 +5270,19 @@
 	.required_clks = MT7628_CLKS_BITMAP,
 	.required_pctl = false,
 	.version = 1,
-	.txrx = {
-		.txd_size = sizeof(struct mtk_tx_dma),
-		.rxd_size = sizeof(struct mtk_rx_dma),
-		.rx_irq_done_mask = MTK_RX_DONE_INT,
-		.rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA,
+	.tx = {
+		.desc_size = sizeof(struct mtk_tx_dma),
+		.dma_max_len = MTK_TX_DMA_BUF_LEN,
+		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
+	},
+	.rx = {
+		.desc_size = sizeof(struct mtk_rx_dma),
+		.irq_done_mask = MTK_RX_DONE_INT,
+		.dma_l4_valid = RX_DMA_L4_VALID_PDMA,
 		.dma_max_len = MTK_TX_DMA_BUF_LEN,
 		.dma_len_offset = 16,
+		.dma_size = MTK_DMA_SIZE(2K),
 	},
 };
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -32,7 +32,9 @@
 #define MTK_TX_DMA_BUF_LEN	0x3fff
 #define MTK_TX_DMA_BUF_LEN_V2	0xffff
 #define MTK_QDMA_RING_SIZE	2048
-#define MTK_DMA_SIZE		512
+#define MTK_DMA_SIZE(x)		(SZ_##x)
+#define MTK_FQ_DMA_HEAD		32
+#define MTK_FQ_DMA_LENGTH	2048
 #define MTK_RX_ETH_HLEN		(ETH_HLEN + ETH_FCS_LEN)
 #define MTK_RX_HLEN		(NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
 #define MTK_DMA_DUMMY_DESC	0xffffffff
@@ -327,8 +329,8 @@
 /* QDMA descriptor txd3 */
 #define TX_DMA_OWNER_CPU	BIT(31)
 #define TX_DMA_LS0		BIT(30)
-#define TX_DMA_PLEN0(x)		(((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
-#define TX_DMA_PLEN1(x)		((x) & eth->soc->txrx.dma_max_len)
+#define TX_DMA_PLEN0(x)		(((x) & eth->soc->tx.dma_max_len) << eth->soc->tx.dma_len_offset)
+#define TX_DMA_PLEN1(x)		((x) & eth->soc->tx.dma_max_len)
 #define TX_DMA_SWC		BIT(14)
 #define TX_DMA_PQID		GENMASK(3, 0)
 #define TX_DMA_ADDR64_MASK	GENMASK(3, 0)
@@ -348,8 +350,8 @@
 /* QDMA descriptor rxd2 */
 #define RX_DMA_DONE		BIT(31)
 #define RX_DMA_LSO		BIT(30)
-#define RX_DMA_PREP_PLEN0(x)	(((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
-#define RX_DMA_GET_PLEN0(x)	(((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len)
+#define RX_DMA_PREP_PLEN0(x)	(((x) & eth->soc->rx.dma_max_len) << eth->soc->rx.dma_len_offset)
+#define RX_DMA_GET_PLEN0(x)	(((x) >> eth->soc->rx.dma_len_offset) & eth->soc->rx.dma_max_len)
 #define RX_DMA_VTAG		BIT(15)
 #define RX_DMA_ADDR64_MASK	GENMASK(3, 0)
 #if IS_ENABLED(CONFIG_64BIT)
@@ -1153,10 +1155,9 @@
  * @foe_entry_size		Foe table entry size.
  * @has_accounting		Bool indicating support for accounting of
  *				offloaded flows.
- * @txd_size			Tx DMA descriptor size.
- * @rxd_size			Rx DMA descriptor size.
- * @rx_irq_done_mask		Rx irq done register mask.
- * @rx_dma_l4_valid		Rx DMA valid register mask.
+ * @desc_size			Tx/Rx DMA descriptor size.
+ * @irq_done_mask		Rx irq done register mask.
+ * @dma_l4_valid		Rx DMA valid register mask.
  * @dma_max_len			Max DMA tx/rx buffer length.
  * @dma_len_offset		Tx/Rx DMA length field offset.
  */
@@ -1174,13 +1175,20 @@
 	bool		has_accounting;
 	bool		disable_pll_modes;
 	struct {
-		u32	txd_size;
-		u32	rxd_size;
-		u32	rx_irq_done_mask;
-		u32	rx_dma_l4_valid;
+		u32	desc_size;
 		u32	dma_max_len;
 		u32	dma_len_offset;
-	} txrx;
+		u32	dma_size;
+		u32	fq_dma_size;
+	} tx;
+	struct {
+		u32	desc_size;
+		u32	irq_done_mask;
+		u32	dma_l4_valid;
+		u32	dma_max_len;
+		u32	dma_len_offset;
+		u32	dma_size;
+	} rx;
 };
 
 #define MTK_DMA_MONITOR_TIMEOUT		msecs_to_jiffies(1000)
@@ -1261,7 +1269,7 @@
 	struct napi_struct		rx_napi;
 	void				*scratch_ring;
 	dma_addr_t			phy_scratch_ring;
-	void				*scratch_head;
+	void				*scratch_head[MTK_FQ_DMA_HEAD];
 	struct clk			*clks[MTK_CLK_MAX];
 
 	struct mii_bus			*mii_bus;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mediatek/mtk_ppe.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mediatek/mtk_ppe.c
@@ -994,7 +994,7 @@
 			 MTK_PPE_KEEPALIVE_DISABLE) |
 	      FIELD_PREP(MTK_PPE_TB_CFG_HASH_MODE, 1) |
 	      FIELD_PREP(MTK_PPE_TB_CFG_SCAN_MODE,
-			 MTK_PPE_SCAN_MODE_KEEPALIVE_AGE) |
+			 MTK_PPE_SCAN_MODE_CHECK_AGE) |
 	      FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM,
 			 MTK_PPE_ENTRIES_SHIFT);
 	if (mtk_is_netsys_v2_or_greater(ppe->eth))
@@ -1090,17 +1090,21 @@
 
 	mtk_ppe_cache_enable(ppe, false);
 
-	/* disable offload engine */
-	ppe_clear(ppe, MTK_PPE_GLO_CFG, MTK_PPE_GLO_CFG_EN);
-	ppe_w32(ppe, MTK_PPE_FLOW_CFG, 0);
-
 	/* disable aging */
 	val = MTK_PPE_TB_CFG_AGE_NON_L4 |
 	      MTK_PPE_TB_CFG_AGE_UNBIND |
 	      MTK_PPE_TB_CFG_AGE_TCP |
 	      MTK_PPE_TB_CFG_AGE_UDP |
-	      MTK_PPE_TB_CFG_AGE_TCP_FIN;
+	      MTK_PPE_TB_CFG_AGE_TCP_FIN |
+		  MTK_PPE_TB_CFG_SCAN_MODE;
 	ppe_clear(ppe, MTK_PPE_TB_CFG, val);
 
-	return mtk_ppe_wait_busy(ppe);
+	if (mtk_ppe_wait_busy(ppe))
+		return -ETIMEDOUT;
+
+	/* disable offload engine */
+	ppe_clear(ppe, MTK_PPE_GLO_CFG, MTK_PPE_GLO_CFG_EN);
+	ppe_w32(ppe, MTK_PPE_FLOW_CFG, 0);
+
+	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -1524,6 +1524,7 @@
 {
 	struct device_node *of_node;
 	struct mtk_star_priv *priv;
+	struct phy_device *phydev;
 	struct net_device *ndev;
 	struct device *dev;
 	void __iomem *base;
@@ -1649,6 +1650,12 @@
 	netif_napi_add(ndev, &priv->rx_napi, mtk_star_rx_poll);
 	netif_napi_add_tx(ndev, &priv->tx_napi, mtk_star_tx_poll);
 
+	phydev = of_phy_find_device(priv->phy_node);
+	if (phydev) {
+		phydev->mac_managed_pm = true;
+		put_device(&phydev->mdio.dev);
+	}
+
 	return devm_register_netdev(dev, ndev);
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mediatek/mtk_wed.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mediatek/mtk_wed.c
@@ -1074,13 +1074,13 @@
 static void
 mtk_wed_stop(struct mtk_wed_device *dev)
 {
+	mtk_wed_dma_disable(dev);
 	mtk_wed_set_ext_int(dev, false);
 
 	wed_w32(dev, MTK_WED_WPDMA_INT_TRIGGER, 0);
 	wed_w32(dev, MTK_WED_WDMA_INT_TRIGGER, 0);
 	wdma_w32(dev, MTK_WDMA_INT_MASK, 0);
 	wdma_w32(dev, MTK_WDMA_INT_GRP2, 0);
-	wed_w32(dev, MTK_WED_WPDMA_INT_MASK, 0);
 
 	if (!mtk_wed_get_rx_capa(dev))
 		return;
@@ -1093,7 +1093,6 @@
 mtk_wed_deinit(struct mtk_wed_device *dev)
 {
 	mtk_wed_stop(dev);
-	mtk_wed_dma_disable(dev);
 
 	wed_clr(dev, MTK_WED_CTRL,
 		MTK_WED_CTRL_WDMA_INT_AGENT_EN |
@@ -2605,9 +2604,6 @@
 static void
 mtk_wed_irq_set_mask(struct mtk_wed_device *dev, u32 mask)
 {
-	if (!dev->running)
-		return;
-
 	mtk_wed_set_ext_int(dev, !!mask);
 	wed_w32(dev, MTK_WED_INT_MASK, mask);
 }
@@ -2670,14 +2666,15 @@
 {
 	struct mtk_wed_flow_block_priv *priv = cb_priv;
 	struct flow_cls_offload *cls = type_data;
-	struct mtk_wed_hw *hw = priv->hw;
+	struct mtk_wed_hw *hw = NULL;
 
-	if (!tc_can_offload(priv->dev))
+	if (!priv || !tc_can_offload(priv->dev))
 		return -EOPNOTSUPP;
 
 	if (type != TC_SETUP_CLSFLOWER)
 		return -EOPNOTSUPP;
 
+	hw = priv->hw;
 	return mtk_flow_offload_cmd(hw->eth, cls, hw->index);
 }
 
@@ -2733,6 +2730,7 @@
 			flow_block_cb_remove(block_cb, f);
 			list_del(&block_cb->driver_list);
 			kfree(block_cb->cb_priv);
+			block_cb->cb_priv = NULL;
 		}
 		return 0;
 	default:
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mediatek/mtk_wed_wo.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/mediatek/mtk_wed_wo.h
@@ -91,8 +91,8 @@
 #define MT7981_FIRMWARE_WO	"mediatek/mt7981_wo.bin"
 #define MT7986_FIRMWARE_WO0	"mediatek/mt7986_wo_0.bin"
 #define MT7986_FIRMWARE_WO1	"mediatek/mt7986_wo_1.bin"
-#define MT7988_FIRMWARE_WO0	"mediatek/mt7988_wo_0.bin"
-#define MT7988_FIRMWARE_WO1	"mediatek/mt7988_wo_1.bin"
+#define MT7988_FIRMWARE_WO0	"mediatek/mt7988/mt7988_wo_0.bin"
+#define MT7988_FIRMWARE_WO1	"mediatek/mt7988/mt7988_wo_1.bin"
 
 #define MTK_WO_MCU_CFG_LS_BASE				0
 #define MTK_WO_MCU_CFG_LS_HW_VER_ADDR			(MTK_WO_MCU_CFG_LS_BASE + 0x000)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -969,19 +969,32 @@
 	bool poll_cmd = ent->polling;
 	struct mlx5_cmd_layout *lay;
 	struct mlx5_core_dev *dev;
-	unsigned long cb_timeout;
-	struct semaphore *sem;
+	unsigned long timeout;
 	unsigned long flags;
 	int alloc_ret;
 	int cmd_mode;
 
+	complete(&ent->handling);
+
 	dev = container_of(cmd, struct mlx5_core_dev, cmd);
-	cb_timeout = msecs_to_jiffies(mlx5_tout_ms(dev, CMD));
+	timeout = msecs_to_jiffies(mlx5_tout_ms(dev, CMD));
 
-	complete(&ent->handling);
-	sem = ent->page_queue ? &cmd->vars.pages_sem : &cmd->vars.sem;
-	down(sem);
 	if (!ent->page_queue) {
+		if (down_timeout(&cmd->vars.sem, timeout)) {
+			mlx5_core_warn(dev, "%s(0x%x) timed out while waiting for a slot.\n",
+				       mlx5_command_str(ent->op), ent->op);
+			if (ent->callback) {
+				ent->callback(-EBUSY, ent->context);
+				mlx5_free_cmd_msg(dev, ent->out);
+				free_msg(dev, ent->in);
+				cmd_ent_put(ent);
+			} else {
+				ent->ret = -EBUSY;
+				complete(&ent->done);
+			}
+			complete(&ent->slotted);
+			return;
+		}
 		alloc_ret = cmd_alloc_index(cmd, ent);
 		if (alloc_ret < 0) {
 			mlx5_core_err_rl(dev, "failed to allocate command entry\n");
@@ -994,10 +1007,12 @@
 				ent->ret = -EAGAIN;
 				complete(&ent->done);
 			}
-			up(sem);
+			up(&cmd->vars.sem);
+			complete(&ent->slotted);
 			return;
 		}
 	} else {
+		down(&cmd->vars.pages_sem);
 		ent->idx = cmd->vars.max_reg_cmds;
 		spin_lock_irqsave(&cmd->alloc_lock, flags);
 		clear_bit(ent->idx, &cmd->vars.bitmask);
@@ -1005,6 +1020,8 @@
 		spin_unlock_irqrestore(&cmd->alloc_lock, flags);
 	}
 
+	complete(&ent->slotted);
+
 	lay = get_inst(cmd, ent->idx);
 	ent->lay = lay;
 	memset(lay, 0, sizeof(*lay));
@@ -1023,7 +1040,7 @@
 	ent->ts1 = ktime_get_ns();
 	cmd_mode = cmd->mode;
 
-	if (ent->callback && schedule_delayed_work(&ent->cb_timeout_work, cb_timeout))
+	if (ent->callback && schedule_delayed_work(&ent->cb_timeout_work, timeout))
 		cmd_ent_get(ent);
 	set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state);
 
@@ -1143,6 +1160,9 @@
 		ent->ret = -ECANCELED;
 		goto out_err;
 	}
+
+	wait_for_completion(&ent->slotted);
+
 	if (cmd->mode == CMD_MODE_POLLING || ent->polling)
 		wait_for_completion(&ent->done);
 	else if (!wait_for_completion_timeout(&ent->done, timeout))
@@ -1157,6 +1177,9 @@
 	} else if (err == -ECANCELED) {
 		mlx5_core_warn(dev, "%s(0x%x) canceled on out of queue timeout.\n",
 			       mlx5_command_str(ent->op), ent->op);
+	} else if (err == -EBUSY) {
+		mlx5_core_warn(dev, "%s(0x%x) timeout while waiting for command semaphore.\n",
+			       mlx5_command_str(ent->op), ent->op);
 	}
 	mlx5_core_dbg(dev, "err %d, delivery status %s(%d)\n",
 		      err, deliv_status_to_str(ent->status), ent->status);
@@ -1208,6 +1231,7 @@
 	ent->polling = force_polling;
 
 	init_completion(&ent->handling);
+	init_completion(&ent->slotted);
 	if (!callback)
 		init_completion(&ent->done);
 
@@ -1225,7 +1249,7 @@
 		return 0; /* mlx5_cmd_comp_handler() will put(ent) */
 
 	err = wait_func(dev, ent);
-	if (err == -ETIMEDOUT || err == -ECANCELED)
+	if (err == -ETIMEDOUT || err == -ECANCELED || err == -EBUSY)
 		goto out_free;
 
 	ds = ent->ts2 - ent->ts1;
@@ -1611,6 +1635,9 @@
 	dev = container_of(cmd, struct mlx5_core_dev, cmd);
 	eqe = data;
 
+	if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
+		return NOTIFY_DONE;
+
 	mlx5_cmd_comp_handler(dev, be32_to_cpu(eqe->data.cmd.vector), false);
 
 	return NOTIFY_OK;
@@ -1734,6 +1761,10 @@
 	}
 }
 
+#define MLX5_MAX_MANAGE_PAGES_CMD_ENT 1
+#define MLX5_CMD_MASK ((1UL << (cmd->vars.max_reg_cmds + \
+			   MLX5_MAX_MANAGE_PAGES_CMD_ENT)) - 1)
+
 static void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev)
 {
 	struct mlx5_cmd *cmd = &dev->cmd;
@@ -1745,7 +1776,7 @@
 	/* wait for pending handlers to complete */
 	mlx5_eq_synchronize_cmd_irq(dev);
 	spin_lock_irqsave(&dev->cmd.alloc_lock, flags);
-	vector = ~dev->cmd.vars.bitmask & ((1ul << (1 << dev->cmd.vars.log_sz)) - 1);
+	vector = ~dev->cmd.vars.bitmask & MLX5_CMD_MASK;
 	if (!vector)
 		goto no_trig;
 
@@ -2319,7 +2350,7 @@
 
 	cmd->state = MLX5_CMDIF_STATE_DOWN;
 	cmd->vars.max_reg_cmds = (1 << cmd->vars.log_sz) - 1;
-	cmd->vars.bitmask = (1UL << cmd->vars.max_reg_cmds) - 1;
+	cmd->vars.bitmask = MLX5_CMD_MASK;
 
 	sema_init(&cmd->vars.sem, cmd->vars.max_reg_cmds);
 	sema_init(&cmd->vars.pages_sem, 1);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -79,6 +79,7 @@
 				 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
 
 #define MLX5E_RX_MAX_HEAD (256)
+#define MLX5E_SHAMPO_LOG_HEADER_ENTRY_SIZE (8)
 #define MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE (9)
 #define MLX5E_SHAMPO_WQ_HEADER_PER_PAGE (PAGE_SIZE >> MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE)
 #define MLX5E_SHAMPO_WQ_BASE_HEAD_ENTRY_SIZE (64)
@@ -145,25 +146,6 @@
 #define MLX5E_TX_XSK_POLL_BUDGET       64
 #define MLX5E_SQ_RECOVER_MIN_INTERVAL  500 /* msecs */
 
-#define MLX5E_KLM_UMR_WQE_SZ(sgl_len)\
-	(sizeof(struct mlx5e_umr_wqe) +\
-	(sizeof(struct mlx5_klm) * (sgl_len)))
-
-#define MLX5E_KLM_UMR_WQEBBS(klm_entries) \
-	(DIV_ROUND_UP(MLX5E_KLM_UMR_WQE_SZ(klm_entries), MLX5_SEND_WQE_BB))
-
-#define MLX5E_KLM_UMR_DS_CNT(klm_entries)\
-	(DIV_ROUND_UP(MLX5E_KLM_UMR_WQE_SZ(klm_entries), MLX5_SEND_WQE_DS))
-
-#define MLX5E_KLM_MAX_ENTRIES_PER_WQE(wqe_size)\
-	(((wqe_size) - sizeof(struct mlx5e_umr_wqe)) / sizeof(struct mlx5_klm))
-
-#define MLX5E_KLM_ENTRIES_PER_WQE(wqe_size)\
-	ALIGN_DOWN(MLX5E_KLM_MAX_ENTRIES_PER_WQE(wqe_size), MLX5_UMR_KLM_NUM_ENTRIES_ALIGNMENT)
-
-#define MLX5E_MAX_KLM_PER_WQE(mdev) \
-	MLX5E_KLM_ENTRIES_PER_WQE(MLX5_SEND_WQE_BB * mlx5e_get_max_sq_aligned_wqebbs(mdev))
-
 #define mlx5e_state_dereference(priv, p) \
 	rcu_dereference_protected((p), lockdep_is_held(&(priv)->state_lock))
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en/params.c
@@ -1131,18 +1131,18 @@
 				 struct mlx5e_params *params,
 				 struct mlx5e_rq_param *rq_param)
 {
-	int max_num_of_umr_per_wqe, max_hd_per_wqe, max_klm_per_umr, rest;
+	int max_num_of_umr_per_wqe, max_hd_per_wqe, max_ksm_per_umr, rest;
 	void *wqc = MLX5_ADDR_OF(rqc, rq_param->rqc, wq);
 	int wq_size = BIT(MLX5_GET(wq, wqc, log_wq_sz));
 	u32 wqebbs;
 
-	max_klm_per_umr = MLX5E_MAX_KLM_PER_WQE(mdev);
+	max_ksm_per_umr = MLX5E_MAX_KSM_PER_WQE(mdev);
 	max_hd_per_wqe = mlx5e_shampo_hd_per_wqe(mdev, params, rq_param);
-	max_num_of_umr_per_wqe = max_hd_per_wqe / max_klm_per_umr;
-	rest = max_hd_per_wqe % max_klm_per_umr;
-	wqebbs = MLX5E_KLM_UMR_WQEBBS(max_klm_per_umr) * max_num_of_umr_per_wqe;
+	max_num_of_umr_per_wqe = max_hd_per_wqe / max_ksm_per_umr;
+	rest = max_hd_per_wqe % max_ksm_per_umr;
+	wqebbs = MLX5E_KSM_UMR_WQEBBS(max_ksm_per_umr) * max_num_of_umr_per_wqe;
 	if (rest)
-		wqebbs += MLX5E_KLM_UMR_WQEBBS(rest);
+		wqebbs += MLX5E_KSM_UMR_WQEBBS(rest);
 	wqebbs *= wq_size;
 	return wqebbs;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.h
@@ -95,9 +95,15 @@
 }
 
 static inline u8
+mlx5e_ptp_metadata_fifo_peek(struct mlx5e_ptp_metadata_fifo *fifo)
+{
+	return fifo->data[fifo->mask & fifo->cc];
+}
+
+static inline void
 mlx5e_ptp_metadata_fifo_pop(struct mlx5e_ptp_metadata_fifo *fifo)
 {
-	return fifo->data[fifo->mask & fifo->cc++];
+	fifo->cc++;
 }
 
 static inline void
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c
@@ -83,24 +83,25 @@
 
 	txq_ix = mlx5e_qid_from_qos(chs, node_qid);
 
-	WARN_ON(node_qid > priv->htb_max_qos_sqs);
-	if (node_qid == priv->htb_max_qos_sqs) {
-		struct mlx5e_sq_stats *stats, **stats_list = NULL;
-
-		if (priv->htb_max_qos_sqs == 0) {
-			stats_list = kvcalloc(mlx5e_qos_max_leaf_nodes(priv->mdev),
-					      sizeof(*stats_list),
-					      GFP_KERNEL);
-			if (!stats_list)
-				return -ENOMEM;
-		}
+	WARN_ON(node_qid >= mlx5e_htb_cur_leaf_nodes(priv->htb));
+	if (!priv->htb_qos_sq_stats) {
+		struct mlx5e_sq_stats **stats_list;
+
+		stats_list = kvcalloc(mlx5e_qos_max_leaf_nodes(priv->mdev),
+				      sizeof(*stats_list), GFP_KERNEL);
+		if (!stats_list)
+			return -ENOMEM;
+
+		WRITE_ONCE(priv->htb_qos_sq_stats, stats_list);
+	}
+
+	if (!priv->htb_qos_sq_stats[node_qid]) {
+		struct mlx5e_sq_stats *stats;
+
 		stats = kzalloc(sizeof(*stats), GFP_KERNEL);
-		if (!stats) {
-			kvfree(stats_list);
+		if (!stats)
 			return -ENOMEM;
-		}
-		if (stats_list)
-			WRITE_ONCE(priv->htb_qos_sq_stats, stats_list);
+
 		WRITE_ONCE(priv->htb_qos_sq_stats[node_qid], stats);
 		/* Order htb_max_qos_sqs increment after writing the array pointer.
 		 * Pairs with smp_load_acquire in en_stats.c.
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
@@ -143,7 +143,9 @@
 		return err;
 	}
 
+	mutex_lock(&priv->state_lock);
 	err = mlx5e_safe_reopen_channels(priv);
+	mutex_unlock(&priv->state_lock);
 	if (!err) {
 		to_ctx->status = 1; /* all channels recovered */
 		return err;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/selq.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en/selq.c
@@ -57,6 +57,7 @@
 
 void mlx5e_selq_cleanup(struct mlx5e_selq *selq)
 {
+	mutex_lock(selq->state_lock);
 	WARN_ON_ONCE(selq->is_prepared);
 
 	kvfree(selq->standby);
@@ -67,6 +68,7 @@
 
 	kvfree(selq->standby);
 	selq->standby = NULL;
+	mutex_unlock(selq->state_lock);
 }
 
 void mlx5e_selq_prepare_params(struct mlx5e_selq *selq, struct mlx5e_params *params)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
@@ -854,7 +854,7 @@
 	return 0;
 
 err_rule:
-	mlx5_tc_ct_entry_destroy_mod_hdr(ct_priv, zone_rule->attr, zone_rule->mh);
+	mlx5_tc_ct_entry_destroy_mod_hdr(ct_priv, attr, zone_rule->mh);
 	mlx5_put_label_mapping(ct_priv, attr->ct_attr.ct_labels_id);
 err_mod_hdr:
 	kfree(attr);
@@ -920,6 +920,7 @@
 	mlx5_tc_ct_entry_destroy_mod_hdr(ct_priv, zone_rule->attr, mh);
 	mlx5_put_label_mapping(ct_priv, attr->ct_attr.ct_labels_id);
 err_mod_hdr:
+	*attr = *old_attr;
 	kfree(old_attr);
 err_attr:
 	kvfree(spec);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c
@@ -5,6 +5,7 @@
 #include <net/nexthop.h>
 #include <net/ip_tunnels.h>
 #include "tc_tun_encap.h"
+#include "fs_core.h"
 #include "en_tc.h"
 #include "tc_tun.h"
 #include "rep/tc.h"
@@ -24,10 +25,18 @@
 
 	route_dev = dev_get_by_index(dev_net(e->out_dev), e->route_dev_ifindex);
 
-	if (!route_dev || !netif_is_ovs_master(route_dev) ||
-	    attr->parse_attr->filter_dev == e->out_dev)
+	if (!route_dev || !netif_is_ovs_master(route_dev))
 		goto out;
 
+	if (priv->mdev->priv.steering->mode == MLX5_FLOW_STEERING_MODE_DMFS &&
+	    mlx5e_eswitch_uplink_rep(attr->parse_attr->filter_dev) &&
+	    (attr->esw_attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP)) {
+		mlx5_core_warn(priv->mdev,
+			       "Matching on external port with encap + fwd to table actions is not allowed for firmware steering\n");
+		err = -EINVAL;
+		goto out;
+	}
+
 	err = mlx5e_set_fwd_to_int_port_actions(priv, attr, e->route_dev_ifindex,
 						MLX5E_TC_INT_PORT_EGRESS,
 						&attr->action, out_index);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/tir.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en/tir.c
@@ -23,6 +23,9 @@
 	struct mlx5e_tir_builder *builder;
 
 	builder = kvzalloc(sizeof(*builder), GFP_KERNEL);
+	if (!builder)
+		return NULL;
+
 	builder->modify = modify;
 
 	return builder;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
@@ -34,6 +34,25 @@
 
 #define MLX5E_RX_ERR_CQE(cqe) (get_cqe_opcode(cqe) != MLX5_CQE_RESP_SEND)
 
+#define MLX5E_KSM_UMR_WQE_SZ(sgl_len)\
+	(sizeof(struct mlx5e_umr_wqe) +\
+	(sizeof(struct mlx5_ksm) * (sgl_len)))
+
+#define MLX5E_KSM_UMR_WQEBBS(ksm_entries) \
+	(DIV_ROUND_UP(MLX5E_KSM_UMR_WQE_SZ(ksm_entries), MLX5_SEND_WQE_BB))
+
+#define MLX5E_KSM_UMR_DS_CNT(ksm_entries)\
+	(DIV_ROUND_UP(MLX5E_KSM_UMR_WQE_SZ(ksm_entries), MLX5_SEND_WQE_DS))
+
+#define MLX5E_KSM_MAX_ENTRIES_PER_WQE(wqe_size)\
+	(((wqe_size) - sizeof(struct mlx5e_umr_wqe)) / sizeof(struct mlx5_ksm))
+
+#define MLX5E_KSM_ENTRIES_PER_WQE(wqe_size)\
+	ALIGN_DOWN(MLX5E_KSM_MAX_ENTRIES_PER_WQE(wqe_size), MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT)
+
+#define MLX5E_MAX_KSM_PER_WQE(mdev) \
+	MLX5E_KSM_ENTRIES_PER_WQE(MLX5_SEND_WQE_BB * mlx5e_get_max_sq_aligned_wqebbs(mdev))
+
 static inline
 ktime_t mlx5e_cqe_ts_to_ns(cqe_ts_to_ns func, struct mlx5_clock *clock, u64 cqe_ts)
 {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
@@ -28,8 +28,10 @@
 			      struct mlx5e_xsk_param *xsk,
 			      struct mlx5_core_dev *mdev)
 {
-	/* AF_XDP doesn't support frames larger than PAGE_SIZE. */
-	if (xsk->chunk_size > PAGE_SIZE || xsk->chunk_size < MLX5E_MIN_XSK_CHUNK_SIZE) {
+	/* AF_XDP doesn't support frames larger than PAGE_SIZE,
+	 * and xsk->chunk_size is limited to 65535 bytes.
+	 */
+	if ((size_t)xsk->chunk_size > PAGE_SIZE || xsk->chunk_size < MLX5E_MIN_XSK_CHUNK_SIZE) {
 		mlx5_core_err(mdev, "XSK chunk size %u out of bounds [%u, %lu]\n", xsk->chunk_size,
 			      MLX5E_MIN_XSK_CHUNK_SIZE, PAGE_SIZE);
 		return false;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
@@ -102,8 +102,14 @@
 mlx5e_udp_gso_handle_tx_skb(struct sk_buff *skb)
 {
 	int payload_len = skb_shinfo(skb)->gso_size + sizeof(struct udphdr);
+	struct udphdr *udphdr;
 
-	udp_hdr(skb)->len = htons(payload_len);
+	if (skb->encapsulation)
+		udphdr = (struct udphdr *)skb_inner_transport_header(skb);
+	else
+		udphdr = udp_hdr(skb);
+
+	udphdr->len = htons(payload_len);
 }
 
 struct mlx5e_accel_tx_state {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
@@ -67,7 +67,6 @@
 		return;
 
 	spin_lock_bh(&x->lock);
-	xfrm_state_check_expire(x);
 	if (x->km.state == XFRM_STATE_EXPIRED) {
 		sa_entry->attrs.drop = true;
 		spin_unlock_bh(&x->lock);
@@ -75,6 +74,13 @@
 		mlx5e_accel_ipsec_fs_modify(sa_entry);
 		return;
 	}
+
+	if (x->km.state != XFRM_STATE_VALID) {
+		spin_unlock_bh(&x->lock);
+		return;
+	}
+
+	xfrm_state_check_expire(x);
 	spin_unlock_bh(&x->lock);
 
 	queue_delayed_work(sa_entry->ipsec->wq, &dwork->dwork,
@@ -718,6 +724,12 @@
 	/* check esn */
 	if (x->props.flags & XFRM_STATE_ESN)
 		mlx5e_ipsec_update_esn_state(sa_entry);
+	else
+		/* According to RFC4303, section "3.3.3. Sequence Number Generation",
+		 * the first packet sent using a given SA will contain a sequence
+		 * number of 1.
+		 */
+		sa_entry->esn_state.esn = 1;
 
 	mlx5e_ipsec_build_accel_xfrm_attrs(sa_entry, &sa_entry->attrs);
 
@@ -762,9 +774,12 @@
 				   MLX5_IPSEC_RESCHED);
 
 	if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET &&
-	    x->props.mode == XFRM_MODE_TUNNEL)
-		xa_set_mark(&ipsec->sadb, sa_entry->ipsec_obj_id,
-			    MLX5E_IPSEC_TUNNEL_SA);
+	    x->props.mode == XFRM_MODE_TUNNEL) {
+		xa_lock_bh(&ipsec->sadb);
+		__xa_set_mark(&ipsec->sadb, sa_entry->ipsec_obj_id,
+			      MLX5E_IPSEC_TUNNEL_SA);
+		xa_unlock_bh(&ipsec->sadb);
+	}
 
 out:
 	x->xso.offload_handle = (unsigned long)sa_entry;
@@ -791,7 +806,6 @@
 static void mlx5e_xfrm_del_state(struct xfrm_state *x)
 {
 	struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
-	struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
 	struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
 	struct mlx5e_ipsec_sa_entry *old;
 
@@ -800,12 +814,6 @@
 
 	old = xa_erase_bh(&ipsec->sadb, sa_entry->ipsec_obj_id);
 	WARN_ON(old != sa_entry);
-
-	if (attrs->mode == XFRM_MODE_TUNNEL &&
-	    attrs->type == XFRM_DEV_OFFLOAD_PACKET)
-		/* Make sure that no ARP requests are running in parallel */
-		flush_workqueue(ipsec->wq);
-
 }
 
 static void mlx5e_xfrm_free_state(struct xfrm_state *x)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c
@@ -750,8 +750,7 @@
 err_fs_ft:
 	if (rx->allow_tunnel_mode)
 		mlx5_eswitch_unblock_encap(mdev);
-	mlx5_del_flow_rules(rx->status.rule);
-	mlx5_modify_header_dealloc(mdev, rx->status.modify_hdr);
+	mlx5_ipsec_rx_status_destroy(ipsec, rx);
 err_add:
 	mlx5_destroy_flow_table(rx->ft.status);
 err_fs_ft_status:
@@ -1719,23 +1718,21 @@
 		goto err_alloc;
 	}
 
-	if (attrs->family == AF_INET)
-		setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4);
-	else
-		setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
-
 	setup_fte_no_frags(spec);
 	setup_fte_upper_proto_match(spec, &attrs->upspec);
 
 	switch (attrs->type) {
 	case XFRM_DEV_OFFLOAD_CRYPTO:
+		if (attrs->family == AF_INET)
+			setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4);
+		else
+			setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6);
 		setup_fte_spi(spec, attrs->spi, false);
 		setup_fte_esp(spec);
 		setup_fte_reg_a(spec);
 		break;
 	case XFRM_DEV_OFFLOAD_PACKET:
-		if (attrs->reqid)
-			setup_fte_reg_c4(spec, attrs->reqid);
+		setup_fte_reg_c4(spec, attrs->reqid);
 		err = setup_pkt_reformat(ipsec, attrs, &flow_act);
 		if (err)
 			goto err_pkt_reformat;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c
@@ -51,9 +51,10 @@
 		    MLX5_CAP_FLOWTABLE_NIC_RX(mdev, decap))
 			caps |= MLX5_IPSEC_CAP_PACKET_OFFLOAD;
 
-		if ((MLX5_CAP_FLOWTABLE_NIC_TX(mdev, ignore_flow_level) &&
-		     MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ignore_flow_level)) ||
-		    MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, ignore_flow_level))
+		if (IS_ENABLED(CONFIG_MLX5_CLS_ACT) &&
+		    ((MLX5_CAP_FLOWTABLE_NIC_TX(mdev, ignore_flow_level) &&
+		      MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ignore_flow_level)) ||
+		     MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, ignore_flow_level)))
 			caps |= MLX5_IPSEC_CAP_PRIO;
 
 		if (MLX5_CAP_FLOWTABLE_NIC_TX(mdev,
@@ -90,8 +91,9 @@
 EXPORT_SYMBOL_GPL(mlx5_ipsec_device_caps);
 
 static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn,
-				     struct mlx5_accel_esp_xfrm_attrs *attrs)
+				     struct mlx5e_ipsec_sa_entry *sa_entry)
 {
+	struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
 	void *aso_ctx;
 
 	aso_ctx = MLX5_ADDR_OF(ipsec_obj, obj, ipsec_aso);
@@ -119,8 +121,12 @@
 	 * active.
 	 */
 	MLX5_SET(ipsec_obj, obj, aso_return_reg, MLX5_IPSEC_ASO_REG_C_4_5);
-	if (attrs->dir == XFRM_DEV_OFFLOAD_OUT)
+	if (attrs->dir == XFRM_DEV_OFFLOAD_OUT) {
 		MLX5_SET(ipsec_aso, aso_ctx, mode, MLX5_IPSEC_ASO_INC_SN);
+		if (!attrs->replay_esn.trigger)
+			MLX5_SET(ipsec_aso, aso_ctx, mode_parameter,
+				 sa_entry->esn_state.esn);
+	}
 
 	if (attrs->lft.hard_packet_limit != XFRM_INF) {
 		MLX5_SET(ipsec_aso, aso_ctx, remove_flow_pkt_cnt,
@@ -173,7 +179,7 @@
 
 	res = &mdev->mlx5e_res.hw_objs;
 	if (attrs->type == XFRM_DEV_OFFLOAD_PACKET)
-		mlx5e_ipsec_packet_setup(obj, res->pdn, attrs);
+		mlx5e_ipsec_packet_setup(obj, res->pdn, sa_entry);
 
 	err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out));
 	if (!err)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.h
@@ -98,18 +98,11 @@
 		if (!x || !x->xso.offload_handle)
 			goto out_disable;
 
-		if (xo->inner_ipproto) {
-			/* Cannot support tunnel packet over IPsec tunnel mode
-			 * because we cannot offload three IP header csum
-			 */
-			if (x->props.mode == XFRM_MODE_TUNNEL)
-				goto out_disable;
-
-			/* Only support UDP or TCP L4 checksum */
-			if (xo->inner_ipproto != IPPROTO_UDP &&
-			    xo->inner_ipproto != IPPROTO_TCP)
-				goto out_disable;
-		}
+		/* Only support UDP or TCP L4 checksum */
+		if (xo->inner_ipproto &&
+		    xo->inner_ipproto != IPPROTO_UDP &&
+		    xo->inner_ipproto != IPPROTO_TCP)
+			goto out_disable;
 
 		return features;
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
@@ -660,7 +660,7 @@
 	while (remaining > 0) {
 		skb_frag_t *frag = &record->frags[i];
 
-		get_page(skb_frag_page(frag));
+		page_ref_inc(skb_frag_page(frag));
 		remaining -= skb_frag_size(frag);
 		info->frags[i++] = *frag;
 	}
@@ -763,7 +763,7 @@
 	stats = sq->stats;
 
 	mlx5e_tx_dma_unmap(sq->pdev, dma);
-	put_page(wi->resync_dump_frag_page);
+	page_ref_dec(wi->resync_dump_frag_page);
 	stats->tls_dump_packets++;
 	stats->tls_dump_bytes += wi->num_bytes;
 }
@@ -816,12 +816,12 @@
 
 err_out:
 	for (; i < info.nr_frags; i++)
-		/* The put_page() here undoes the page ref obtained in tx_sync_info_get().
+		/* The page_ref_dec() here undoes the page ref obtained in tx_sync_info_get().
 		 * Page refs obtained for the DUMP WQEs above (by page_ref_add) will be
 		 * released only upon their completions (or in mlx5e_free_txqsq_descs,
 		 * if channel closes).
 		 */
-		put_page(skb_frag_page(&info.frags[i]));
+		page_ref_dec(skb_frag_page(&info.frags[i]));
 
 	return MLX5E_KTLS_SYNC_FAIL;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
@@ -339,9 +339,13 @@
 {
 	struct mlx5e_priv *priv = macsec_netdev_priv(ctx->netdev);
 	struct mlx5_macsec_fs *macsec_fs = priv->mdev->macsec_fs;
+	const struct macsec_tx_sc *tx_sc = &ctx->secy->tx_sc;
 	struct mlx5_macsec_rule_attrs rule_attrs;
 	union mlx5_macsec_rule *macsec_rule;
 
+	if (is_tx && tx_sc->encoding_sa != sa->assoc_num)
+		return 0;
+
 	rule_attrs.macsec_obj_id = sa->macsec_obj_id;
 	rule_attrs.sci = sa->sci;
 	rule_attrs.assoc_num = sa->assoc_num;
@@ -1640,6 +1644,7 @@
 	.mdo_add_secy = mlx5e_macsec_add_secy,
 	.mdo_upd_secy = mlx5e_macsec_upd_secy,
 	.mdo_del_secy = mlx5e_macsec_del_secy,
+	.rx_uses_md_dst = true,
 };
 
 bool mlx5e_macsec_handle_tx_skb(struct mlx5e_macsec *macsec, struct sk_buff *skb)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
@@ -45,6 +45,10 @@
 	struct hlist_head	 rules_hash[ARFS_HASH_SIZE];
 };
 
+enum {
+	MLX5E_ARFS_STATE_ENABLED,
+};
+
 enum arfs_type {
 	ARFS_IPV4_TCP,
 	ARFS_IPV6_TCP,
@@ -59,6 +63,7 @@
 	spinlock_t                     arfs_lock;
 	int                            last_filter_id;
 	struct workqueue_struct        *wq;
+	unsigned long                  state;
 };
 
 struct arfs_tuple {
@@ -169,6 +174,8 @@
 			return err;
 		}
 	}
+	set_bit(MLX5E_ARFS_STATE_ENABLED, &arfs->state);
+
 	return 0;
 }
 
@@ -454,6 +461,8 @@
 	int i;
 	int j;
 
+	clear_bit(MLX5E_ARFS_STATE_ENABLED, &arfs->state);
+
 	spin_lock_bh(&arfs->arfs_lock);
 	mlx5e_for_each_arfs_rule(rule, htmp, arfs->arfs_tables, i, j) {
 		hlist_del_init(&rule->hlist);
@@ -626,17 +635,8 @@
 	struct mlx5_flow_handle *rule;
 
 	arfs = mlx5e_fs_get_arfs(priv->fs);
-	mutex_lock(&priv->state_lock);
-	if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
-		spin_lock_bh(&arfs->arfs_lock);
-		hlist_del(&arfs_rule->hlist);
-		spin_unlock_bh(&arfs->arfs_lock);
-
-		mutex_unlock(&priv->state_lock);
-		kfree(arfs_rule);
-		goto out;
-	}
-	mutex_unlock(&priv->state_lock);
+	if (!test_bit(MLX5E_ARFS_STATE_ENABLED, &arfs->state))
+		return;
 
 	if (!arfs_rule->rule) {
 		rule = arfs_add_rule(priv, arfs_rule);
@@ -752,6 +752,11 @@
 		return -EPROTONOSUPPORT;
 
 	spin_lock_bh(&arfs->arfs_lock);
+	if (!test_bit(MLX5E_ARFS_STATE_ENABLED, &arfs->state)) {
+		spin_unlock_bh(&arfs->arfs_lock);
+		return -EPERM;
+	}
+
 	arfs_rule = arfs_find_rule(arfs_t, &fk);
 	if (arfs_rule) {
 		if (arfs_rule->rxq == rxq_index || work_busy(&arfs_rule->arfs_work)) {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -136,6 +136,10 @@
 				       ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT);
 	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GBASE_LR4, legacy,
 				       ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT);
+	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100BASE_TX, legacy,
+				       ETHTOOL_LINK_MODE_100baseT_Full_BIT);
+	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_1000BASE_T, legacy,
+				       ETHTOOL_LINK_MODE_1000baseT_Full_BIT);
 	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_10GBASE_T, legacy,
 				       ETHTOOL_LINK_MODE_10000baseT_Full_BIT);
 	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_25GBASE_CR, legacy,
@@ -201,6 +205,12 @@
 				       ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT,
 				       ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT,
 				       ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT);
+	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_400GAUI_8_400GBASE_CR8, ext,
+				       ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT,
+				       ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT,
+				       ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT,
+				       ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT,
+				       ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT);
 	MLX5_BUILD_PTYS2ETHTOOL_CONFIG(MLX5E_100GAUI_1_100GBASE_CR_KR, ext,
 				       ETHTOOL_LINK_MODE_100000baseKR_Full_BIT,
 				       ETHTOOL_LINK_MODE_100000baseSR_Full_BIT,
@@ -451,6 +461,23 @@
 
 	mutex_lock(&priv->state_lock);
 
+	/* If RXFH is configured, changing the channels number is allowed only if
+	 * it does not require resizing the RSS table. This is because the previous
+	 * configuration may no longer be compatible with the new RSS table.
+	 */
+	if (netif_is_rxfh_configured(priv->netdev)) {
+		int cur_rqt_size = mlx5e_rqt_size(priv->mdev, cur_params->num_channels);
+		int new_rqt_size = mlx5e_rqt_size(priv->mdev, count);
+
+		if (new_rqt_size != cur_rqt_size) {
+			err = -EINVAL;
+			netdev_err(priv->netdev,
+				   "%s: RXFH is configured, block changing channels number that affects RSS table size (new: %d, current: %d)\n",
+				   __func__, new_rqt_size, cur_rqt_size);
+			goto out;
+		}
+	}
+
 	/* Don't allow changing the number of channels if HTB offload is active,
 	 * because the numeration of the QoS SQs will change, while per-queue
 	 * qdiscs are attached.
@@ -1223,7 +1250,12 @@
 	if (!an_changes && link_modes == eproto.admin)
 		goto out;
 
-	mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext);
+	err = mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext);
+	if (err) {
+		netdev_err(priv->netdev, "%s: failed to set ptys reg: %d\n", __func__, err);
+		goto out;
+	}
+
 	mlx5_toggle_port_link(mdev);
 
 out:
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
@@ -734,7 +734,7 @@
 	if (num_tuples <= 0) {
 		netdev_warn(priv->netdev, "%s: flow is not valid %d\n",
 			    __func__, num_tuples);
-		return num_tuples;
+		return num_tuples < 0 ? num_tuples : -EINVAL;
 	}
 
 	eth_ft = get_flow_table(priv, fs, num_tuples);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -501,8 +501,8 @@
 	return err;
 }
 
-static int mlx5e_create_umr_klm_mkey(struct mlx5_core_dev *mdev,
-				     u64 nentries,
+static int mlx5e_create_umr_ksm_mkey(struct mlx5_core_dev *mdev,
+				     u64 nentries, u8 log_entry_size,
 				     u32 *umr_mkey)
 {
 	int inlen;
@@ -522,12 +522,13 @@
 	MLX5_SET(mkc, mkc, umr_en, 1);
 	MLX5_SET(mkc, mkc, lw, 1);
 	MLX5_SET(mkc, mkc, lr, 1);
-	MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_KLMS);
+	MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_KSM);
 	mlx5e_mkey_set_relaxed_ordering(mdev, mkc);
 	MLX5_SET(mkc, mkc, qpn, 0xffffff);
 	MLX5_SET(mkc, mkc, pd, mdev->mlx5e_res.hw_objs.pdn);
 	MLX5_SET(mkc, mkc, translations_octword_size, nentries);
-	MLX5_SET(mkc, mkc, length64, 1);
+	MLX5_SET(mkc, mkc, log_page_size, log_entry_size);
+	MLX5_SET64(mkc, mkc, len, nentries << log_entry_size);
 	err = mlx5_core_create_mkey(mdev, umr_mkey, in, inlen);
 
 	kvfree(in);
@@ -562,14 +563,16 @@
 static int mlx5e_create_rq_hd_umr_mkey(struct mlx5_core_dev *mdev,
 				       struct mlx5e_rq *rq)
 {
-	u32 max_klm_size = BIT(MLX5_CAP_GEN(mdev, log_max_klm_list_size));
+	u32 max_ksm_size = BIT(MLX5_CAP_GEN(mdev, log_max_klm_list_size));
 
-	if (max_klm_size < rq->mpwqe.shampo->hd_per_wq) {
-		mlx5_core_err(mdev, "max klm list size 0x%x is smaller than shampo header buffer list size 0x%x\n",
-			      max_klm_size, rq->mpwqe.shampo->hd_per_wq);
+	if (max_ksm_size < rq->mpwqe.shampo->hd_per_wq) {
+		mlx5_core_err(mdev, "max ksm list size 0x%x is smaller than shampo header buffer list size 0x%x\n",
+			      max_ksm_size, rq->mpwqe.shampo->hd_per_wq);
 		return -EINVAL;
 	}
-	return mlx5e_create_umr_klm_mkey(mdev, rq->mpwqe.shampo->hd_per_wq,
+
+	return mlx5e_create_umr_ksm_mkey(mdev, rq->mpwqe.shampo->hd_per_wq,
+					 MLX5E_SHAMPO_LOG_HEADER_ENTRY_SIZE,
 					 &rq->mpwqe.shampo->mkey);
 }
 
@@ -3769,7 +3772,7 @@
 		mlx5e_fold_sw_stats64(priv, stats);
 	}
 
-	stats->rx_dropped = priv->stats.qcnt.rx_out_of_buffer;
+	stats->rx_missed_errors = priv->stats.qcnt.rx_out_of_buffer;
 
 	stats->rx_length_errors =
 		PPORT_802_3_GET(pstats, a_in_range_length_errors) +
@@ -4080,7 +4083,8 @@
 	struct mlx5e_params *params = &priv->channels.params;
 	xdp_features_t val;
 
-	if (params->packet_merge.type != MLX5E_PACKET_MERGE_NONE) {
+	if (!netdev->netdev_ops->ndo_bpf ||
+	    params->packet_merge.type != MLX5E_PACKET_MERGE_NONE) {
 		xdp_clear_features_flag(netdev);
 		return;
 	}
@@ -4717,7 +4721,7 @@
 
 		/* Verify if UDP port is being offloaded by HW */
 		if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, port))
-			return features;
+			return vxlan_features_check(skb, features);
 
 #if IS_ENABLED(CONFIG_GENEVE)
 		/* Support Geneve offload for default UDP port */
@@ -4743,7 +4747,6 @@
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 
 	features = vlan_features_check(skb, features);
-	features = vxlan_features_check(skb, features);
 
 	/* Validate if the tunneled packet is being offloaded by HW */
 	if (skb->encapsulation &&
@@ -5695,15 +5698,18 @@
 	kfree(priv->tx_rates);
 	kfree(priv->txq2sq);
 	destroy_workqueue(priv->wq);
-	mutex_lock(&priv->state_lock);
 	mlx5e_selq_cleanup(&priv->selq);
-	mutex_unlock(&priv->state_lock);
 	free_cpumask_var(priv->scratchpad.cpumask);
 
 	for (i = 0; i < priv->htb_max_qos_sqs; i++)
 		kfree(priv->htb_qos_sq_stats[i]);
 	kvfree(priv->htb_qos_sq_stats);
 
+	if (priv->mqprio_rl) {
+		mlx5e_mqprio_rl_cleanup(priv->mqprio_rl);
+		mlx5e_mqprio_rl_free(priv->mqprio_rl);
+	}
+
 	memset(priv, 0, sizeof(*priv));
 }
 
@@ -6005,14 +6011,14 @@
 	return 0;
 }
 
-static int _mlx5e_suspend(struct auxiliary_device *adev)
+static int _mlx5e_suspend(struct auxiliary_device *adev, bool pre_netdev_reg)
 {
 	struct mlx5e_dev *mlx5e_dev = auxiliary_get_drvdata(adev);
 	struct mlx5e_priv *priv = mlx5e_dev->priv;
 	struct net_device *netdev = priv->netdev;
 	struct mlx5_core_dev *mdev = priv->mdev;
 
-	if (!netif_device_present(netdev)) {
+	if (!pre_netdev_reg && !netif_device_present(netdev)) {
 		if (test_bit(MLX5E_STATE_DESTROYING, &priv->state))
 			mlx5e_destroy_mdev_resources(mdev);
 		return -ENODEV;
@@ -6025,7 +6031,7 @@
 
 static int mlx5e_suspend(struct auxiliary_device *adev, pm_message_t state)
 {
-	return _mlx5e_suspend(adev);
+	return _mlx5e_suspend(adev, false);
 }
 
 static int _mlx5e_probe(struct auxiliary_device *adev)
@@ -6089,7 +6095,7 @@
 	return 0;
 
 err_resume:
-	_mlx5e_suspend(adev);
+	_mlx5e_suspend(adev, true);
 err_profile_cleanup:
 	profile->cleanup(priv);
 err_destroy_netdev:
@@ -6114,9 +6120,22 @@
 
 	mlx5_core_uplink_netdev_set(priv->mdev, NULL);
 	mlx5e_dcbnl_delete_app(priv);
-	unregister_netdev(priv->netdev);
-	_mlx5e_suspend(adev);
-	priv->profile->cleanup(priv);
+	/* When unload driver, the netdev is in registered state
+	 * if it's from legacy mode. If from switchdev mode, it
+	 * is already unregistered before changing to NIC profile.
+	 */
+	if (priv->netdev->reg_state == NETREG_REGISTERED) {
+		unregister_netdev(priv->netdev);
+		_mlx5e_suspend(adev, false);
+	} else {
+		if (test_bit(MLX5E_STATE_DESTROYING, &priv->state))
+			mlx5e_destroy_mdev_resources(priv->mdev);
+		else
+			_mlx5e_suspend(adev, true);
+	}
+	/* Avoid cleanup if profile rollback failed. */
+	if (priv->profile)
+		priv->profile->cleanup(priv);
 	mlx5e_destroy_netdev(priv);
 	mlx5e_devlink_port_unregister(mlx5e_dev);
 	mlx5e_destroy_devlink(mlx5e_dev);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -1469,6 +1469,21 @@
 
 	priv = netdev_priv(netdev);
 
+	/* This bit is set when using devlink to change eswitch mode from
+	 * switchdev to legacy. As need to keep uplink netdev ifindex, we
+	 * detach uplink representor profile and attach NIC profile only.
+	 * The netdev will be unregistered later when unload NIC auxiliary
+	 * driver for this case.
+	 * We explicitly block devlink eswitch mode change if any IPSec rules
+	 * offloaded, but can't block other cases, such as driver unload
+	 * and devlink reload. We have to unregister netdev before profile
+	 * change for those cases. This is to avoid resource leak because
+	 * the offloaded rules don't have the chance to be unoffloaded before
+	 * cleanup which is triggered by detach uplink representor profile.
+	 */
+	if (!(priv->mdev->priv.flags & MLX5_PRIV_FLAGS_SWITCH_LEGACY))
+		unregister_netdev(netdev);
+
 	mlx5e_netdev_attach_nic_profile(priv);
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -619,25 +619,25 @@
 	return min(len, count);
 }
 
-static void build_klm_umr(struct mlx5e_icosq *sq, struct mlx5e_umr_wqe *umr_wqe,
-			  __be32 key, u16 offset, u16 klm_len, u16 wqe_bbs)
+static void build_ksm_umr(struct mlx5e_icosq *sq, struct mlx5e_umr_wqe *umr_wqe,
+			  __be32 key, u16 offset, u16 ksm_len)
 {
-	memset(umr_wqe, 0, offsetof(struct mlx5e_umr_wqe, inline_klms));
+	memset(umr_wqe, 0, offsetof(struct mlx5e_umr_wqe, inline_ksms));
 	umr_wqe->ctrl.opmod_idx_opcode =
 		cpu_to_be32((sq->pc << MLX5_WQE_CTRL_WQE_INDEX_SHIFT) |
 			     MLX5_OPCODE_UMR);
 	umr_wqe->ctrl.umr_mkey = key;
 	umr_wqe->ctrl.qpn_ds = cpu_to_be32((sq->sqn << MLX5_WQE_CTRL_QPN_SHIFT)
-					    | MLX5E_KLM_UMR_DS_CNT(klm_len));
+					    | MLX5E_KSM_UMR_DS_CNT(ksm_len));
 	umr_wqe->uctrl.flags = MLX5_UMR_TRANSLATION_OFFSET_EN | MLX5_UMR_INLINE;
 	umr_wqe->uctrl.xlt_offset = cpu_to_be16(offset);
-	umr_wqe->uctrl.xlt_octowords = cpu_to_be16(klm_len);
+	umr_wqe->uctrl.xlt_octowords = cpu_to_be16(ksm_len);
 	umr_wqe->uctrl.mkey_mask     = cpu_to_be64(MLX5_MKEY_MASK_FREE);
 }
 
 static int mlx5e_build_shampo_hd_umr(struct mlx5e_rq *rq,
 				     struct mlx5e_icosq *sq,
-				     u16 klm_entries, u16 index)
+				     u16 ksm_entries, u16 index)
 {
 	struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo;
 	u16 entries, pi, header_offset, err, wqe_bbs, new_entries;
@@ -650,20 +650,20 @@
 	int headroom, i;
 
 	headroom = rq->buff.headroom;
-	new_entries = klm_entries - (shampo->pi & (MLX5_UMR_KLM_NUM_ENTRIES_ALIGNMENT - 1));
-	entries = ALIGN(klm_entries, MLX5_UMR_KLM_NUM_ENTRIES_ALIGNMENT);
-	wqe_bbs = MLX5E_KLM_UMR_WQEBBS(entries);
+	new_entries = ksm_entries - (shampo->pi & (MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT - 1));
+	entries = ALIGN(ksm_entries, MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT);
+	wqe_bbs = MLX5E_KSM_UMR_WQEBBS(entries);
 	pi = mlx5e_icosq_get_next_pi(sq, wqe_bbs);
 	umr_wqe = mlx5_wq_cyc_get_wqe(&sq->wq, pi);
-	build_klm_umr(sq, umr_wqe, shampo->key, index, entries, wqe_bbs);
+	build_ksm_umr(sq, umr_wqe, shampo->key, index, entries);
 
 	frag_page = &shampo->pages[page_index];
 
 	for (i = 0; i < entries; i++, index++) {
 		dma_info = &shampo->info[index];
-		if (i >= klm_entries || (index < shampo->pi && shampo->pi - index <
-					 MLX5_UMR_KLM_NUM_ENTRIES_ALIGNMENT))
-			goto update_klm;
+		if (i >= ksm_entries || (index < shampo->pi && shampo->pi - index <
+					 MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT))
+			goto update_ksm;
 		header_offset = (index & (MLX5E_SHAMPO_WQ_HEADER_PER_PAGE - 1)) <<
 			MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE;
 		if (!(header_offset & (PAGE_SIZE - 1))) {
@@ -683,12 +683,11 @@
 			dma_info->frag_page = frag_page;
 		}
 
-update_klm:
-		umr_wqe->inline_klms[i].bcount =
-			cpu_to_be32(MLX5E_RX_MAX_HEAD);
-		umr_wqe->inline_klms[i].key    = cpu_to_be32(lkey);
-		umr_wqe->inline_klms[i].va     =
-			cpu_to_be64(dma_info->addr + headroom);
+update_ksm:
+		umr_wqe->inline_ksms[i] = (struct mlx5_ksm) {
+			.key = cpu_to_be32(lkey),
+			.va  = cpu_to_be64(dma_info->addr + headroom),
+		};
 	}
 
 	sq->db.wqe_info[pi] = (struct mlx5e_icosq_wqe_info) {
@@ -720,37 +719,38 @@
 static int mlx5e_alloc_rx_hd_mpwqe(struct mlx5e_rq *rq)
 {
 	struct mlx5e_shampo_hd *shampo = rq->mpwqe.shampo;
-	u16 klm_entries, num_wqe, index, entries_before;
+	u16 ksm_entries, num_wqe, index, entries_before;
 	struct mlx5e_icosq *sq = rq->icosq;
-	int i, err, max_klm_entries, len;
+	int i, err, max_ksm_entries, len;
 
-	max_klm_entries = MLX5E_MAX_KLM_PER_WQE(rq->mdev);
-	klm_entries = bitmap_find_window(shampo->bitmap,
+	max_ksm_entries = MLX5E_MAX_KSM_PER_WQE(rq->mdev);
+	ksm_entries = bitmap_find_window(shampo->bitmap,
 					 shampo->hd_per_wqe,
 					 shampo->hd_per_wq, shampo->pi);
-	if (!klm_entries)
+	ksm_entries = ALIGN_DOWN(ksm_entries, MLX5E_SHAMPO_WQ_HEADER_PER_PAGE);
+	if (!ksm_entries)
 		return 0;
 
-	klm_entries += (shampo->pi & (MLX5_UMR_KLM_NUM_ENTRIES_ALIGNMENT - 1));
-	index = ALIGN_DOWN(shampo->pi, MLX5_UMR_KLM_NUM_ENTRIES_ALIGNMENT);
+	ksm_entries += (shampo->pi & (MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT - 1));
+	index = ALIGN_DOWN(shampo->pi, MLX5_UMR_KSM_NUM_ENTRIES_ALIGNMENT);
 	entries_before = shampo->hd_per_wq - index;
 
-	if (unlikely(entries_before < klm_entries))
-		num_wqe = DIV_ROUND_UP(entries_before, max_klm_entries) +
-			  DIV_ROUND_UP(klm_entries - entries_before, max_klm_entries);
+	if (unlikely(entries_before < ksm_entries))
+		num_wqe = DIV_ROUND_UP(entries_before, max_ksm_entries) +
+			  DIV_ROUND_UP(ksm_entries - entries_before, max_ksm_entries);
 	else
-		num_wqe = DIV_ROUND_UP(klm_entries, max_klm_entries);
+		num_wqe = DIV_ROUND_UP(ksm_entries, max_ksm_entries);
 
 	for (i = 0; i < num_wqe; i++) {
-		len = (klm_entries > max_klm_entries) ? max_klm_entries :
-							klm_entries;
+		len = (ksm_entries > max_ksm_entries) ? max_ksm_entries :
+							ksm_entries;
 		if (unlikely(index + len > shampo->hd_per_wq))
 			len = shampo->hd_per_wq - index;
 		err = mlx5e_build_shampo_hd_umr(rq, sq, len, index);
 		if (unlikely(err))
 			return err;
 		index = (index + len) & (rq->mpwqe.shampo->hd_per_wq - 1);
-		klm_entries -= len;
+		ksm_entries -= len;
 	}
 
 	return 0;
@@ -2369,11 +2369,15 @@
 	if (flush)
 		mlx5e_shampo_flush_skb(rq, cqe, match);
 free_hd_entry:
-	mlx5e_free_rx_shampo_hd_entry(rq, header_index);
+	if (likely(head_size))
+		mlx5e_free_rx_shampo_hd_entry(rq, header_index);
 mpwrq_cqe_out:
 	if (likely(wi->consumed_strides < rq->mpwqe.num_strides))
 		return;
 
+	if (unlikely(!cstrides))
+		return;
+
 	wq  = &rq->mpwqe.wq;
 	wqe = mlx5_wq_ll_get_wqe(wq, wqe_id);
 	mlx5_wq_ll_pop(wq, cqe->wqe_id, &wqe->next.next_wqe_index);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
@@ -153,7 +153,11 @@
 
 	*hopbyhop = 0;
 	if (skb->encapsulation) {
-		ihs = skb_inner_tcp_all_headers(skb);
+		if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4)
+			ihs = skb_inner_transport_offset(skb) +
+			      sizeof(struct udphdr);
+		else
+			ihs = skb_inner_tcp_all_headers(skb);
 		stats->tso_inner_packets++;
 		stats->tso_inner_bytes += skb->len - ihs;
 	} else {
@@ -398,6 +402,8 @@
 		     (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))) {
 		u8 metadata_index = be32_to_cpu(eseg->flow_table_metadata);
 
+		mlx5e_ptp_metadata_fifo_pop(&sq->ptpsq->metadata_freelist);
+
 		mlx5e_skb_cb_hwtstamp_init(skb);
 		mlx5e_ptp_metadata_map_put(&sq->ptpsq->metadata_map, skb,
 					   metadata_index);
@@ -496,9 +502,6 @@
 
 err_drop:
 	stats->dropped++;
-	if (unlikely(sq->ptpsq && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)))
-		mlx5e_ptp_metadata_fifo_push(&sq->ptpsq->metadata_freelist,
-					     be32_to_cpu(eseg->flow_table_metadata));
 	dev_kfree_skb_any(skb);
 	mlx5e_tx_flush(sq);
 }
@@ -639,7 +642,6 @@
 	return;
 
 err_unmap:
-	mlx5e_dma_unmap_wqe_err(sq, 1);
 	sq->stats->dropped++;
 	dev_kfree_skb_any(skb);
 	mlx5e_tx_flush(sq);
@@ -657,7 +659,7 @@
 {
 	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP))
 		eseg->flow_table_metadata =
-			cpu_to_be32(mlx5e_ptp_metadata_fifo_pop(&ptpsq->metadata_freelist));
+			cpu_to_be32(mlx5e_ptp_metadata_fifo_peek(&ptpsq->metadata_freelist));
 }
 
 static void mlx5e_txwqe_build_eseg(struct mlx5e_priv *priv, struct mlx5e_txqsq *sq,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -1073,6 +1073,12 @@
 	struct mlx5_eq_comp *eq;
 	int ret = 0;
 
+	if (vecidx >= table->max_comp_eqs) {
+		mlx5_core_dbg(dev, "Requested vector index %u should be less than %u",
+			      vecidx, table->max_comp_eqs);
+		return -EINVAL;
+	}
+
 	mutex_lock(&table->comp_lock);
 	eq = xa_load(&table->comp_eqs, vecidx);
 	if (eq) {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c
@@ -6,6 +6,9 @@
 #include "helper.h"
 #include "ofld.h"
 
+static int
+acl_ingress_ofld_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport);
+
 static bool
 esw_acl_ingress_prio_tag_enabled(struct mlx5_eswitch *esw,
 				 const struct mlx5_vport *vport)
@@ -123,18 +126,31 @@
 {
 	struct mlx5_flow_act flow_act = {};
 	struct mlx5_flow_handle *flow_rule;
+	bool created = false;
 	int err = 0;
 
+	if (!vport->ingress.acl) {
+		err = acl_ingress_ofld_setup(esw, vport);
+		if (err)
+			return err;
+		created = true;
+	}
+
 	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
 	flow_act.fg = vport->ingress.offloads.drop_grp;
 	flow_rule = mlx5_add_flow_rules(vport->ingress.acl, NULL, &flow_act, NULL, 0);
 	if (IS_ERR(flow_rule)) {
 		err = PTR_ERR(flow_rule);
-		goto out;
+		goto err_out;
 	}
 
 	vport->ingress.offloads.drop_rule = flow_rule;
-out:
+
+	return 0;
+err_out:
+	/* Only destroy ingress acl created in this function. */
+	if (created)
+		esw_acl_ingress_ofld_cleanup(esw, vport);
 	return err;
 }
 
@@ -299,16 +315,12 @@
 	}
 }
 
-int esw_acl_ingress_ofld_setup(struct mlx5_eswitch *esw,
-			       struct mlx5_vport *vport)
+static int
+acl_ingress_ofld_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
 {
 	int num_ftes = 0;
 	int err;
 
-	if (!mlx5_eswitch_vport_match_metadata_enabled(esw) &&
-	    !esw_acl_ingress_prio_tag_enabled(esw, vport))
-		return 0;
-
 	esw_acl_ingress_allow_rule_destroy(vport);
 
 	if (mlx5_eswitch_vport_match_metadata_enabled(esw))
@@ -347,6 +359,15 @@
 	return err;
 }
 
+int esw_acl_ingress_ofld_setup(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
+{
+	if (!mlx5_eswitch_vport_match_metadata_enabled(esw) &&
+	    !esw_acl_ingress_prio_tag_enabled(esw, vport))
+		return 0;
+
+	return acl_ingress_ofld_setup(esw, vport);
+}
+
 void esw_acl_ingress_ofld_cleanup(struct mlx5_eswitch *esw,
 				  struct mlx5_vport *vport)
 {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
@@ -1874,7 +1874,7 @@
 				 "Failed to lookup bridge port vlan metadata to create MDB (MAC=%pM,vid=%u,vport=%u)\n",
 				 addr, vid, vport_num);
 			NL_SET_ERR_MSG_FMT_MOD(extack,
-					       "Failed to lookup bridge port vlan metadata to create MDB (MAC=%pM,vid=%u,vport=%u)\n",
+					       "Failed to lookup vlan metadata for MDB (MAC=%pM,vid=%u,vport=%u)\n",
 					       addr, vid, vport_num);
 			return -EINVAL;
 		}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c
@@ -150,11 +150,11 @@
 	unsigned long i;
 	int err;
 
-	xa_for_each(&esw->offloads.vport_reps, i, rep) {
-		rpriv = rep->rep_data[REP_ETH].priv;
-		if (!rpriv || !rpriv->netdev)
+	mlx5_esw_for_each_rep(esw, i, rep) {
+		if (atomic_read(&rep->rep_data[REP_ETH].state) != REP_LOADED)
 			continue;
 
+		rpriv = rep->rep_data[REP_ETH].priv;
 		rhashtable_walk_enter(&rpriv->tc_ht, &iter);
 		rhashtable_walk_start(&iter);
 		while ((flow = rhashtable_walk_next(&iter)) != NULL) {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c
@@ -319,7 +319,7 @@
 		return -EPERM;
 
 	mutex_lock(&esw->state_lock);
-	if (esw->mode != MLX5_ESWITCH_LEGACY) {
+	if (esw->mode != MLX5_ESWITCH_LEGACY || !mlx5_esw_is_fdb_created(esw)) {
 		err = -EOPNOTSUPP;
 		goto out;
 	}
@@ -339,7 +339,7 @@
 	if (!mlx5_esw_allowed(esw))
 		return -EPERM;
 
-	if (esw->mode != MLX5_ESWITCH_LEGACY)
+	if (esw->mode != MLX5_ESWITCH_LEGACY || !mlx5_esw_is_fdb_created(esw))
 		return -EOPNOTSUPP;
 
 	*setting = esw->fdb_table.legacy.vepa_uplink_rule ? 1 : 0;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c
@@ -312,6 +312,25 @@
 	return err;
 }
 
+static bool esw_qos_element_type_supported(struct mlx5_core_dev *dev, int type)
+{
+	switch (type) {
+	case SCHEDULING_CONTEXT_ELEMENT_TYPE_TSAR:
+		return MLX5_CAP_QOS(dev, esw_element_type) &
+		       ELEMENT_TYPE_CAP_MASK_TSAR;
+	case SCHEDULING_CONTEXT_ELEMENT_TYPE_VPORT:
+		return MLX5_CAP_QOS(dev, esw_element_type) &
+		       ELEMENT_TYPE_CAP_MASK_VPORT;
+	case SCHEDULING_CONTEXT_ELEMENT_TYPE_VPORT_TC:
+		return MLX5_CAP_QOS(dev, esw_element_type) &
+		       ELEMENT_TYPE_CAP_MASK_VPORT_TC;
+	case SCHEDULING_CONTEXT_ELEMENT_TYPE_PARA_VPORT_TC:
+		return MLX5_CAP_QOS(dev, esw_element_type) &
+		       ELEMENT_TYPE_CAP_MASK_PARA_VPORT_TC;
+	}
+	return false;
+}
+
 static int esw_qos_vport_create_sched_element(struct mlx5_eswitch *esw,
 					      struct mlx5_vport *vport,
 					      u32 max_rate, u32 bw_share)
@@ -323,6 +342,9 @@
 	void *vport_elem;
 	int err;
 
+	if (!esw_qos_element_type_supported(dev, SCHEDULING_CONTEXT_ELEMENT_TYPE_VPORT))
+		return -EOPNOTSUPP;
+
 	parent_tsar_ix = group ? group->tsar_ix : esw->qos.root_tsar_ix;
 	MLX5_SET(scheduling_context, sched_ctx, element_type,
 		 SCHEDULING_CONTEXT_ELEMENT_TYPE_VPORT);
@@ -421,6 +443,7 @@
 {
 	u32 tsar_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {};
 	struct mlx5_esw_rate_group *group;
+	__be32 *attr;
 	u32 divider;
 	int err;
 
@@ -428,6 +451,12 @@
 	if (!group)
 		return ERR_PTR(-ENOMEM);
 
+	MLX5_SET(scheduling_context, tsar_ctx, element_type,
+		 SCHEDULING_CONTEXT_ELEMENT_TYPE_TSAR);
+
+	attr = MLX5_ADDR_OF(scheduling_context, tsar_ctx, element_attributes);
+	*attr = cpu_to_be32(TSAR_ELEMENT_TSAR_TYPE_DWRR << 16);
+
 	MLX5_SET(scheduling_context, tsar_ctx, parent_element_id,
 		 esw->qos.root_tsar_ix);
 	err = mlx5_create_scheduling_element_cmd(esw->dev,
@@ -526,25 +555,6 @@
 	return err;
 }
 
-static bool esw_qos_element_type_supported(struct mlx5_core_dev *dev, int type)
-{
-	switch (type) {
-	case SCHEDULING_CONTEXT_ELEMENT_TYPE_TSAR:
-		return MLX5_CAP_QOS(dev, esw_element_type) &
-		       ELEMENT_TYPE_CAP_MASK_TASR;
-	case SCHEDULING_CONTEXT_ELEMENT_TYPE_VPORT:
-		return MLX5_CAP_QOS(dev, esw_element_type) &
-		       ELEMENT_TYPE_CAP_MASK_VPORT;
-	case SCHEDULING_CONTEXT_ELEMENT_TYPE_VPORT_TC:
-		return MLX5_CAP_QOS(dev, esw_element_type) &
-		       ELEMENT_TYPE_CAP_MASK_VPORT_TC;
-	case SCHEDULING_CONTEXT_ELEMENT_TYPE_PARA_VPORT_TC:
-		return MLX5_CAP_QOS(dev, esw_element_type) &
-		       ELEMENT_TYPE_CAP_MASK_PARA_VPORT_TC;
-	}
-	return false;
-}
-
 static int esw_qos_create(struct mlx5_eswitch *esw, struct netlink_ext_ack *extack)
 {
 	u32 tsar_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {};
@@ -555,7 +565,8 @@
 	if (!MLX5_CAP_GEN(dev, qos) || !MLX5_CAP_QOS(dev, esw_scheduling))
 		return -EOPNOTSUPP;
 
-	if (!esw_qos_element_type_supported(dev, SCHEDULING_CONTEXT_ELEMENT_TYPE_TSAR))
+	if (!esw_qos_element_type_supported(dev, SCHEDULING_CONTEXT_ELEMENT_TYPE_TSAR) ||
+	    !(MLX5_CAP_QOS(dev, esw_tsar_type) & TSAR_TYPE_CAP_MASK_DWRR))
 		return -EOPNOTSUPP;
 
 	MLX5_SET(scheduling_context, tsar_ctx, element_type,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -1489,7 +1489,7 @@
 	}
 
 	if (err)
-		goto abort;
+		goto err_esw_enable;
 
 	esw->fdb_table.flags |= MLX5_ESW_FDB_CREATED;
 
@@ -1503,7 +1503,8 @@
 
 	return 0;
 
-abort:
+err_esw_enable:
+	mlx5_eq_notifier_unregister(esw->dev, &esw->nb);
 	mlx5_esw_acls_ns_cleanup(esw);
 	return err;
 }
@@ -1868,6 +1869,7 @@
 	if (err)
 		goto abort;
 
+	dev->priv.eswitch = esw;
 	err = esw_offloads_init(esw);
 	if (err)
 		goto reps_err;
@@ -1892,11 +1894,6 @@
 		esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_BASIC;
 	else
 		esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE;
-	if (MLX5_ESWITCH_MANAGER(dev) &&
-	    mlx5_esw_vport_match_metadata_supported(esw))
-		esw->flags |= MLX5_ESWITCH_VPORT_MATCH_METADATA;
-
-	dev->priv.eswitch = esw;
 	BLOCKING_INIT_NOTIFIER_HEAD(&esw->n_head);
 
 	esw_info(dev,
@@ -1908,6 +1905,7 @@
 
 reps_err:
 	mlx5_esw_vports_cleanup(esw);
+	dev->priv.eswitch = NULL;
 abort:
 	if (esw->work_queue)
 		destroy_workqueue(esw->work_queue);
@@ -1926,7 +1924,6 @@
 
 	esw_info(esw->dev, "cleanup\n");
 
-	esw->dev->priv.eswitch = NULL;
 	destroy_workqueue(esw->work_queue);
 	WARN_ON(refcount_read(&esw->qos.refcnt));
 	mutex_destroy(&esw->state_lock);
@@ -1937,6 +1934,7 @@
 	mutex_destroy(&esw->offloads.encap_tbl_lock);
 	mutex_destroy(&esw->offloads.decap_tbl_lock);
 	esw_offloads_cleanup(esw);
+	esw->dev->priv.eswitch = NULL;
 	mlx5_esw_vports_cleanup(esw);
 	debugfs_remove_recursive(esw->debugfs_root);
 	devl_params_unregister(priv_to_devlink(esw->dev), mlx5_eswitch_params,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -706,6 +706,9 @@
 			  MLX5_CAP_GEN_2((esw->dev), ec_vf_vport_base) +\
 			  (last) - 1)
 
+#define mlx5_esw_for_each_rep(esw, i, rep) \
+	xa_for_each(&((esw)->offloads.vport_reps), i, rep)
+
 struct mlx5_eswitch *__must_check
 mlx5_devlink_eswitch_get(struct devlink *devlink);
 
@@ -833,7 +836,7 @@
 					     struct mlx5_eswitch *slave_esw, int max_slaves);
 void mlx5_eswitch_offloads_single_fdb_del_one(struct mlx5_eswitch *master_esw,
 					      struct mlx5_eswitch *slave_esw);
-int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw);
+int mlx5_eswitch_reload_ib_reps(struct mlx5_eswitch *esw);
 
 bool mlx5_eswitch_block_encap(struct mlx5_core_dev *dev);
 void mlx5_eswitch_unblock_encap(struct mlx5_core_dev *dev);
@@ -925,7 +928,7 @@
 static inline int mlx5_eswitch_get_npeers(struct mlx5_eswitch *esw) { return 0; }
 
 static inline int
-mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw)
+mlx5_eswitch_reload_ib_reps(struct mlx5_eswitch *esw)
 {
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -52,9 +52,6 @@
 #include "lag/lag.h"
 #include "en/tc/post_meter.h"
 
-#define mlx5_esw_for_each_rep(esw, i, rep) \
-	xa_for_each(&((esw)->offloads.vport_reps), i, rep)
-
 /* There are two match-all miss flows, one for unicast dst mac and
  * one for multicast.
  */
@@ -2476,6 +2473,10 @@
 	if (err)
 		return err;
 
+	if (MLX5_ESWITCH_MANAGER(esw->dev) &&
+	    mlx5_esw_vport_match_metadata_supported(esw))
+		esw->flags |= MLX5_ESWITCH_VPORT_MATCH_METADATA;
+
 	err = devl_params_register(priv_to_devlink(esw->dev),
 				   esw_devlink_params,
 				   ARRAY_SIZE(esw_devlink_params));
@@ -2497,6 +2498,16 @@
 	esw_offloads_cleanup_reps(esw);
 }
 
+static int __esw_offloads_load_rep(struct mlx5_eswitch *esw,
+				   struct mlx5_eswitch_rep *rep, u8 rep_type)
+{
+	if (atomic_cmpxchg(&rep->rep_data[rep_type].state,
+			   REP_REGISTERED, REP_LOADED) == REP_REGISTERED)
+		return esw->offloads.rep_ops[rep_type]->load(esw->dev, rep);
+
+	return 0;
+}
+
 static void __esw_offloads_unload_rep(struct mlx5_eswitch *esw,
 				      struct mlx5_eswitch_rep *rep, u8 rep_type)
 {
@@ -2521,13 +2532,11 @@
 	int err;
 
 	rep = mlx5_eswitch_get_rep(esw, vport_num);
-	for (rep_type = 0; rep_type < NUM_REP_TYPES; rep_type++)
-		if (atomic_cmpxchg(&rep->rep_data[rep_type].state,
-				   REP_REGISTERED, REP_LOADED) == REP_REGISTERED) {
-			err = esw->offloads.rep_ops[rep_type]->load(esw->dev, rep);
-			if (err)
-				goto err_reps;
-		}
+	for (rep_type = 0; rep_type < NUM_REP_TYPES; rep_type++) {
+		err = __esw_offloads_load_rep(esw, rep, rep_type);
+		if (err)
+			goto err_reps;
+	}
 
 	return 0;
 
@@ -3272,7 +3281,7 @@
 		esw_vport_destroy_offloads_acl_tables(esw, vport);
 }
 
-int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw)
+int mlx5_eswitch_reload_ib_reps(struct mlx5_eswitch *esw)
 {
 	struct mlx5_eswitch_rep *rep;
 	unsigned long i;
@@ -3285,13 +3294,13 @@
 	if (atomic_read(&rep->rep_data[REP_ETH].state) != REP_LOADED)
 		return 0;
 
-	ret = mlx5_esw_offloads_rep_load(esw, MLX5_VPORT_UPLINK);
+	ret = __esw_offloads_load_rep(esw, rep, REP_IB);
 	if (ret)
 		return ret;
 
 	mlx5_esw_for_each_rep(esw, i, rep) {
 		if (atomic_read(&rep->rep_data[REP_ETH].state) == REP_LOADED)
-			mlx5_esw_offloads_rep_load(esw, rep->vport);
+			__esw_offloads_load_rep(esw, rep, REP_IB);
 	}
 
 	return 0;
@@ -3729,6 +3738,8 @@
 	esw->eswitch_operation_in_progress = true;
 	up_write(&esw->mode_lock);
 
+	if (mode == DEVLINK_ESWITCH_MODE_LEGACY)
+		esw->dev->priv.flags |= MLX5_PRIV_FLAGS_SWITCH_LEGACY;
 	mlx5_eswitch_disable_locked(esw);
 	if (mode == DEVLINK_ESWITCH_MODE_SWITCHDEV) {
 		if (mlx5_devlink_trap_get_num_active(esw->dev)) {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
@@ -1664,6 +1664,16 @@
 	return err;
 }
 
+static bool mlx5_pkt_reformat_cmp(struct mlx5_pkt_reformat *p1,
+				  struct mlx5_pkt_reformat *p2)
+{
+	return p1->owner == p2->owner &&
+		(p1->owner == MLX5_FLOW_RESOURCE_OWNER_FW ?
+		 p1->id == p2->id :
+		 mlx5_fs_dr_action_get_pkt_reformat_id(p1) ==
+		 mlx5_fs_dr_action_get_pkt_reformat_id(p2));
+}
+
 static bool mlx5_flow_dests_cmp(struct mlx5_flow_destination *d1,
 				struct mlx5_flow_destination *d2)
 {
@@ -1675,8 +1685,8 @@
 		     ((d1->vport.flags & MLX5_FLOW_DEST_VPORT_VHCA_ID) ?
 		      (d1->vport.vhca_id == d2->vport.vhca_id) : true) &&
 		     ((d1->vport.flags & MLX5_FLOW_DEST_VPORT_REFORMAT_ID) ?
-		      (d1->vport.pkt_reformat->id ==
-		       d2->vport.pkt_reformat->id) : true)) ||
+		      mlx5_pkt_reformat_cmp(d1->vport.pkt_reformat,
+					    d2->vport.pkt_reformat) : true)) ||
 		    (d1->type == MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE &&
 		     d1->ft == d2->ft) ||
 		    (d1->type == MLX5_FLOW_DESTINATION_TYPE_TIR &&
@@ -1808,8 +1818,9 @@
 	}
 	trace_mlx5_fs_set_fte(fte, false);
 
+	/* Link newly added rules into the tree. */
 	for (i = 0; i < handle->num_rules; i++) {
-		if (refcount_read(&handle->rule[i]->node.refcount) == 1) {
+		if (!handle->rule[i]->node.parent) {
 			tree_add_node(&handle->rule[i]->node, &fte->node);
 			trace_mlx5_fs_add_rule(handle->rule[i]);
 		}
@@ -1935,13 +1946,22 @@
 		fte_tmp = NULL;
 		goto out;
 	}
+
+	nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD);
+
 	if (!fte_tmp->node.active) {
+		up_write_ref_node(&fte_tmp->node, false);
+
+		if (take_write)
+			up_write_ref_node(&g->node, false);
+		else
+			up_read_ref_node(&g->node);
+
 		tree_put_node(&fte_tmp->node, false);
-		fte_tmp = NULL;
-		goto out;
+
+		return NULL;
 	}
 
-	nested_down_write_ref_node(&fte_tmp->node, FS_LOCK_CHILD);
 out:
 	if (take_write)
 		up_write_ref_node(&g->node, false);
@@ -2470,6 +2490,7 @@
 		break;
 	case MLX5_FLOW_NAMESPACE_RDMA_TX:
 		root_ns = steering->rdma_tx_root_ns;
+		prio = RDMA_TX_BYPASS_PRIO;
 		break;
 	case MLX5_FLOW_NAMESPACE_RDMA_RX_COUNTERS:
 		root_ns = steering->rdma_rx_root_ns;
@@ -3458,6 +3479,7 @@
 int mlx5_fs_core_alloc(struct mlx5_core_dev *dev)
 {
 	struct mlx5_flow_steering *steering;
+	char name[80];
 	int err = 0;
 
 	err = mlx5_init_fc_stats(dev);
@@ -3482,10 +3504,12 @@
 	else
 		steering->mode = MLX5_FLOW_STEERING_MODE_DMFS;
 
-	steering->fgs_cache = kmem_cache_create("mlx5_fs_fgs",
+	snprintf(name, sizeof(name), "%s-mlx5_fs_fgs", dev_name(dev->device));
+	steering->fgs_cache = kmem_cache_create(name,
 						sizeof(struct mlx5_flow_group), 0,
 						0, NULL);
-	steering->ftes_cache = kmem_cache_create("mlx5_fs_ftes", sizeof(struct fs_fte), 0,
+	snprintf(name, sizeof(name), "%s-mlx5_fs_ftes", dev_name(dev->device));
+	steering->ftes_cache = kmem_cache_create(name, sizeof(struct fs_fte), 0,
 						 0, NULL);
 	if (!steering->ftes_cache || !steering->fgs_cache) {
 		err = -ENOMEM;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/fw.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/fw.c
@@ -373,6 +373,10 @@
 	do {
 		if (mlx5_get_nic_state(dev) == MLX5_NIC_IFC_DISABLED)
 			break;
+		if (pci_channel_offline(dev->pdev)) {
+			mlx5_core_err(dev, "PCI channel offline, stop waiting for NIC IFC\n");
+			return -EACCES;
+		}
 
 		cond_resched();
 	} while (!time_after(jiffies, end));
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c
@@ -206,6 +206,7 @@
 static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev, bool unloaded)
 {
 	struct mlx5_fw_reset *fw_reset = dev->priv.fw_reset;
+	struct devlink *devlink = priv_to_devlink(dev);
 
 	/* if this is the driver that initiated the fw reset, devlink completed the reload */
 	if (test_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags)) {
@@ -217,9 +218,11 @@
 			mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
 		else
 			mlx5_load_one(dev, true);
-		devlink_remote_reload_actions_performed(priv_to_devlink(dev), 0,
+		devl_lock(devlink);
+		devlink_remote_reload_actions_performed(devlink, 0,
 							BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
 							BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE));
+		devl_unlock(devlink);
 	}
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/health.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/health.c
@@ -248,6 +248,10 @@
 	do {
 		if (mlx5_get_nic_state(dev) == MLX5_NIC_IFC_DISABLED)
 			break;
+		if (pci_channel_offline(dev->pdev)) {
+			mlx5_core_err(dev, "PCI channel offline, stop waiting for NIC IFC\n");
+			goto unlock;
+		}
 
 		msleep(20);
 	} while (!time_after(jiffies, end));
@@ -317,6 +321,10 @@
 			mlx5_core_warn(dev, "device is being removed, stop waiting for PCI\n");
 			return -ENODEV;
 		}
+		if (pci_channel_offline(dev->pdev)) {
+			mlx5_core_err(dev, "PCI channel offline, stop waiting for PCI\n");
+			return -EACCES;
+		}
 		msleep(100);
 	}
 	return 0;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c
@@ -48,6 +48,7 @@
 irq_pool_request_irq(struct mlx5_irq_pool *pool, struct irq_affinity_desc *af_desc)
 {
 	struct irq_affinity_desc auto_desc = {};
+	struct mlx5_irq *irq;
 	u32 irq_index;
 	int err;
 
@@ -64,9 +65,12 @@
 		else
 			cpu_get(pool, cpumask_first(&af_desc->mask));
 	}
-	return mlx5_irq_alloc(pool, irq_index,
-			      cpumask_empty(&auto_desc.mask) ? af_desc : &auto_desc,
-			      NULL);
+	irq = mlx5_irq_alloc(pool, irq_index,
+			     cpumask_empty(&auto_desc.mask) ? af_desc : &auto_desc,
+			     NULL);
+	if (IS_ERR(irq))
+		xa_erase(&pool->irqs, irq_index);
+	return irq;
 }
 
 /* Looking for the IRQ with the smallest refcount that fits req_mask.
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
@@ -703,8 +703,10 @@
 		return err;
 	}
 
-	if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &flags))
+	if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &flags)) {
 		mlx5_lag_port_sel_destroy(ldev);
+		ldev->buckets = 1;
+	}
 	if (mlx5_lag_has_drop_rule(ldev))
 		mlx5_lag_drop_rule_cleanup(ldev);
 
@@ -718,6 +720,7 @@
 	struct mlx5_core_dev *dev;
 	u8 mode;
 #endif
+	bool roce_support;
 	int i;
 
 	for (i = 0; i < ldev->ports; i++)
@@ -744,6 +747,11 @@
 		if (mlx5_sriov_is_enabled(ldev->pf[i].dev))
 			return false;
 #endif
+	roce_support = mlx5_get_roce_state(ldev->pf[MLX5_LAG_P1].dev);
+	for (i = 1; i < ldev->ports; i++)
+		if (mlx5_get_roce_state(ldev->pf[i].dev) != roce_support)
+			return false;
+
 	return true;
 }
 
@@ -812,7 +820,7 @@
 	if (shared_fdb)
 		for (i = 0; i < ldev->ports; i++)
 			if (!(ldev->pf[i].dev->priv.flags & MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV))
-				mlx5_eswitch_reload_reps(ldev->pf[i].dev->priv.eswitch);
+				mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
 }
 
 static bool mlx5_shared_fdb_supported(struct mlx5_lag *ldev)
@@ -911,8 +919,10 @@
 		} else if (roce_lag) {
 			dev0->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
 			mlx5_rescan_drivers_locked(dev0);
-			for (i = 1; i < ldev->ports; i++)
-				mlx5_nic_vport_enable_roce(ldev->pf[i].dev);
+			for (i = 1; i < ldev->ports; i++) {
+				if (mlx5_get_roce_state(ldev->pf[i].dev))
+					mlx5_nic_vport_enable_roce(ldev->pf[i].dev);
+			}
 		} else if (shared_fdb) {
 			int i;
 
@@ -920,7 +930,7 @@
 			mlx5_rescan_drivers_locked(dev0);
 
 			for (i = 0; i < ldev->ports; i++) {
-				err = mlx5_eswitch_reload_reps(ldev->pf[i].dev->priv.eswitch);
+				err = mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
 				if (err)
 					break;
 			}
@@ -931,7 +941,7 @@
 				mlx5_deactivate_lag(ldev);
 				mlx5_lag_add_devices(ldev);
 				for (i = 0; i < ldev->ports; i++)
-					mlx5_eswitch_reload_reps(ldev->pf[i].dev->priv.eswitch);
+					mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
 				mlx5_core_err(dev0, "Failed to enable lag\n");
 				return;
 			}
@@ -1531,7 +1541,7 @@
 		goto unlock;
 
 	for (i = 0; i < ldev->ports; i++) {
-		if (ldev->pf[MLX5_LAG_P1].netdev == slave) {
+		if (ldev->pf[i].netdev == slave) {
 			port = i;
 			break;
 		}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c
@@ -99,7 +99,7 @@
 	dev0->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
 	mlx5_rescan_drivers_locked(dev0);
 	for (i = 0; i < ldev->ports; i++) {
-		err = mlx5_eswitch_reload_reps(ldev->pf[i].dev->priv.eswitch);
+		err = mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
 		if (err)
 			goto err_rescan_drivers;
 	}
@@ -113,7 +113,7 @@
 err_add_devices:
 	mlx5_lag_add_devices(ldev);
 	for (i = 0; i < ldev->ports; i++)
-		mlx5_eswitch_reload_reps(ldev->pf[i].dev->priv.eswitch);
+		mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
 	mlx5_mpesw_metadata_cleanup(ldev);
 	return err;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c
@@ -88,9 +88,13 @@
 								      &dest, 1);
 			if (IS_ERR(lag_definer->rules[idx])) {
 				err = PTR_ERR(lag_definer->rules[idx]);
-				while (i--)
-					while (j--)
+				do {
+					while (j--) {
+						idx = i * ldev->buckets + j;
 						mlx5_del_flow_rules(lag_definer->rules[idx]);
+					}
+					j = ldev->buckets;
+				} while (i--);
 				goto destroy_fg;
 			}
 		}
@@ -530,7 +534,7 @@
 	set_tt_map(port_sel, hash_type);
 	err = mlx5_lag_create_definers(ldev, hash_type, ports);
 	if (err)
-		return err;
+		goto clear_port_sel;
 
 	if (port_sel->tunnel) {
 		err = mlx5_lag_create_inner_ttc_table(ldev);
@@ -549,6 +553,8 @@
 		mlx5_destroy_ttc_table(port_sel->inner.ttc);
 destroy_definers:
 	mlx5_lag_destroy_definers(ldev);
+clear_port_sel:
+	memset(port_sel, 0, sizeof(*port_sel));
 	return err;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c
@@ -237,17 +237,16 @@
 	}
 }
 
-static void mlx5_timestamp_overflow(struct work_struct *work)
+static long mlx5_timestamp_overflow(struct ptp_clock_info *ptp_info)
 {
-	struct delayed_work *dwork = to_delayed_work(work);
 	struct mlx5_core_dev *mdev;
 	struct mlx5_timer *timer;
 	struct mlx5_clock *clock;
 	unsigned long flags;
 
-	timer = container_of(dwork, struct mlx5_timer, overflow_work);
-	clock = container_of(timer, struct mlx5_clock, timer);
+	clock = container_of(ptp_info, struct mlx5_clock, ptp_info);
 	mdev = container_of(clock, struct mlx5_core_dev, clock);
+	timer = &clock->timer;
 
 	if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
 		goto out;
@@ -258,7 +257,7 @@
 	write_sequnlock_irqrestore(&clock->lock, flags);
 
 out:
-	schedule_delayed_work(&timer->overflow_work, timer->overflow_period);
+	return timer->overflow_period;
 }
 
 static int mlx5_ptp_settime_real_time(struct mlx5_core_dev *mdev,
@@ -436,6 +435,7 @@
 	timer->cycles.mult = mult;
 	mlx5_update_clock_info_page(mdev);
 	write_sequnlock_irqrestore(&clock->lock, flags);
+	ptp_schedule_worker(clock->ptp, timer->overflow_period);
 
 	return 0;
 }
@@ -771,6 +771,7 @@
 	.settime64	= mlx5_ptp_settime,
 	.enable		= NULL,
 	.verify		= NULL,
+	.do_aux_work	= mlx5_timestamp_overflow,
 };
 
 static int mlx5_query_mtpps_pin_mode(struct mlx5_core_dev *mdev, u8 pin,
@@ -971,12 +972,11 @@
 	do_div(ns, NSEC_PER_SEC / HZ);
 	timer->overflow_period = ns;
 
-	INIT_DELAYED_WORK(&timer->overflow_work, mlx5_timestamp_overflow);
-	if (timer->overflow_period)
-		schedule_delayed_work(&timer->overflow_work, 0);
-	else
+	if (!timer->overflow_period) {
+		timer->overflow_period = HZ;
 		mlx5_core_warn(mdev,
-			       "invalid overflow period, overflow_work is not scheduled\n");
+			       "invalid overflow period, overflow_work is scheduled once per second\n");
+	}
 
 	if (clock_info)
 		clock_info->overflow_period = timer->overflow_period;
@@ -1085,6 +1085,9 @@
 
 	MLX5_NB_INIT(&clock->pps_nb, mlx5_pps_event, PPS_EVENT);
 	mlx5_eq_notifier_register(mdev, &clock->pps_nb);
+
+	if (clock->ptp)
+		ptp_schedule_worker(clock->ptp, 0);
 }
 
 void mlx5_cleanup_clock(struct mlx5_core_dev *mdev)
@@ -1101,7 +1104,6 @@
 	}
 
 	cancel_work_sync(&clock->pps_info.out_work);
-	cancel_delayed_work_sync(&clock->timer.overflow_work);
 
 	if (mdev->clock_info) {
 		free_page((unsigned long)mdev->clock_info);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/lib/ipsec_fs_roce.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/lib/ipsec_fs_roce.c
@@ -386,7 +386,8 @@
 		return -EOPNOTSUPP;
 
 	peer_priv = mlx5_devcom_get_next_peer_data(*ipsec_roce->devcom, &tmp);
-	if (!peer_priv) {
+	if (!peer_priv || !peer_priv->ipsec) {
+		mlx5_core_err(mdev, "IPsec not supported on master device\n");
 		err = -EOPNOTSUPP;
 		goto release_peer;
 	}
@@ -455,7 +456,8 @@
 		return -EOPNOTSUPP;
 
 	peer_priv = mlx5_devcom_get_next_peer_data(*ipsec_roce->devcom, &tmp);
-	if (!peer_priv) {
+	if (!peer_priv || !peer_priv->ipsec) {
+		mlx5_core_err(mdev, "IPsec not supported on master device\n");
 		err = -EOPNOTSUPP;
 		goto release_peer;
 	}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/lib/pci_vsc.c
@@ -24,6 +24,11 @@
 	pci_write_config_dword((dev)->pdev, (dev)->vsc_addr + (offset), (val))
 #define VSC_MAX_RETRIES 2048
 
+/* Reading VSC registers can take relatively long time.
+ * Yield the cpu every 128 registers read.
+ */
+#define VSC_GW_READ_BLOCK_COUNT 128
+
 enum {
 	VSC_CTRL_OFFSET = 0x4,
 	VSC_COUNTER_OFFSET = 0x8,
@@ -74,6 +79,10 @@
 			ret = -EBUSY;
 			goto pci_unlock;
 		}
+		if (pci_channel_offline(dev->pdev)) {
+			ret = -EACCES;
+			goto pci_unlock;
+		}
 
 		/* Check if semaphore is already locked */
 		ret = vsc_read(dev, VSC_SEMAPHORE_OFFSET, &lock_val);
@@ -269,6 +278,7 @@
 {
 	unsigned int next_read_addr = 0;
 	unsigned int read_addr = 0;
+	unsigned int count = 0;
 
 	while (read_addr < length) {
 		if (mlx5_vsc_gw_read_fast(dev, read_addr, &next_read_addr,
@@ -276,6 +286,10 @@
 			return read_addr;
 
 		read_addr = next_read_addr;
+		if (++count == VSC_GW_READ_BLOCK_COUNT) {
+			cond_resched();
+			count = 0;
+		}
 	}
 	return length;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -1298,6 +1298,9 @@
 
 	if (!err)
 		mlx5_function_disable(dev, boot);
+	else
+		mlx5_stop_health_poll(dev, boot);
+
 	return err;
 }
 
@@ -1480,6 +1483,14 @@
 	if (err)
 		goto err_register;
 
+	err = mlx5_crdump_enable(dev);
+	if (err)
+		mlx5_core_err(dev, "mlx5_crdump_enable failed with error code %d\n", err);
+
+	err = mlx5_hwmon_dev_register(dev);
+	if (err)
+		mlx5_core_err(dev, "mlx5_hwmon_dev_register failed with error code %d\n", err);
+
 	mutex_unlock(&dev->intf_state_mutex);
 	return 0;
 
@@ -1505,7 +1516,10 @@
 	int err;
 
 	devl_lock(devlink);
+	devl_register(devlink);
 	err = mlx5_init_one_devl_locked(dev);
+	if (err)
+		devl_unregister(devlink);
 	devl_unlock(devlink);
 	return err;
 }
@@ -1517,6 +1531,8 @@
 	devl_lock(devlink);
 	mutex_lock(&dev->intf_state_mutex);
 
+	mlx5_hwmon_dev_unregister(dev);
+	mlx5_crdump_disable(dev);
 	mlx5_unregister_device(dev);
 
 	if (!test_bit(MLX5_INTERFACE_STATE_UP, &dev->intf_state)) {
@@ -1534,6 +1550,7 @@
 	mlx5_function_teardown(dev, true);
 out:
 	mutex_unlock(&dev->intf_state_mutex);
+	devl_unregister(devlink);
 	devl_unlock(devlink);
 }
 
@@ -1666,6 +1683,8 @@
 	struct devlink *devlink = priv_to_devlink(dev);
 	int err;
 
+	devl_lock(devlink);
+	devl_register(devlink);
 	dev->state = MLX5_DEVICE_STATE_UP;
 	err = mlx5_function_enable(dev, true, mlx5_tout_ms(dev, FW_PRE_INIT_TIMEOUT));
 	if (err) {
@@ -1679,20 +1698,21 @@
 		goto query_hca_caps_err;
 	}
 
-	devl_lock(devlink);
 	err = mlx5_devlink_params_register(priv_to_devlink(dev));
-	devl_unlock(devlink);
 	if (err) {
 		mlx5_core_warn(dev, "mlx5_devlink_param_reg err = %d\n", err);
 		goto query_hca_caps_err;
 	}
 
+	devl_unlock(devlink);
 	return 0;
 
 query_hca_caps_err:
 	mlx5_function_disable(dev, true);
 out:
 	dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR;
+	devl_unregister(devlink);
+	devl_unlock(devlink);
 	return err;
 }
 
@@ -1702,6 +1722,7 @@
 
 	devl_lock(devlink);
 	mlx5_devlink_params_unregister(priv_to_devlink(dev));
+	devl_unregister(devlink);
 	devl_unlock(devlink);
 	if (dev->state != MLX5_DEVICE_STATE_UP)
 		return;
@@ -1943,16 +1964,7 @@
 		goto err_init_one;
 	}
 
-	err = mlx5_crdump_enable(dev);
-	if (err)
-		dev_err(&pdev->dev, "mlx5_crdump_enable failed with error code %d\n", err);
-
-	err = mlx5_hwmon_dev_register(dev);
-	if (err)
-		mlx5_core_err(dev, "mlx5_hwmon_dev_register failed with error code %d\n", err);
-
 	pci_save_state(pdev);
-	devlink_register(devlink);
 	return 0;
 
 err_init_one:
@@ -1973,16 +1985,9 @@
 	struct devlink *devlink = priv_to_devlink(dev);
 
 	set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state);
-	/* mlx5_drain_fw_reset() and mlx5_drain_health_wq() are using
-	 * devlink notify APIs.
-	 * Hence, we must drain them before unregistering the devlink.
-	 */
 	mlx5_drain_fw_reset(dev);
 	mlx5_drain_health_wq(dev);
-	devlink_unregister(devlink);
 	mlx5_sriov_disable(pdev, false);
-	mlx5_hwmon_dev_unregister(dev);
-	mlx5_crdump_disable(dev);
 	mlx5_uninit_one(dev);
 	mlx5_pci_close(dev);
 	mlx5_mdev_uninit(dev);
@@ -2135,7 +2140,6 @@
 	/* Panic tear down fw command will stop the PCI bus communication
 	 * with the HCA, so the health poll is no longer needed.
 	 */
-	mlx5_drain_health_wq(dev);
 	mlx5_stop_health_poll(dev, false);
 
 	ret = mlx5_cmd_fast_teardown_hca(dev);
@@ -2170,6 +2174,7 @@
 
 	mlx5_core_info(dev, "Shutdown was called\n");
 	set_bit(MLX5_BREAK_FW_WAIT, &dev->intf_state);
+	mlx5_drain_health_wq(dev);
 	err = mlx5_try_fast_unload(dev);
 	if (err)
 		mlx5_unload_one(dev, false);
@@ -2210,6 +2215,7 @@
 	{ PCI_VDEVICE(MELLANOX, 0x101f) },			/* ConnectX-6 LX */
 	{ PCI_VDEVICE(MELLANOX, 0x1021) },			/* ConnectX-7 */
 	{ PCI_VDEVICE(MELLANOX, 0x1023) },			/* ConnectX-8 */
+	{ PCI_VDEVICE(MELLANOX, 0x1025) },			/* ConnectX-9 */
 	{ PCI_VDEVICE(MELLANOX, 0xa2d2) },			/* BlueField integrated ConnectX-5 network controller */
 	{ PCI_VDEVICE(MELLANOX, 0xa2d3), MLX5_PCI_DEV_IS_VF},	/* BlueField integrated ConnectX-5 network controller VF */
 	{ PCI_VDEVICE(MELLANOX, 0xa2d6) },			/* BlueField-2 integrated ConnectX-6 Dx network controller */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c
@@ -19,6 +19,7 @@
 #define MLX5_IRQ_CTRL_SF_MAX 8
 /* min num of vectors for SFs to be enabled */
 #define MLX5_IRQ_VEC_COMP_BASE_SF 2
+#define MLX5_IRQ_VEC_COMP_BASE 1
 
 #define MLX5_EQ_SHARE_IRQ_MAX_COMP (8)
 #define MLX5_EQ_SHARE_IRQ_MAX_CTRL (UINT_MAX)
@@ -246,6 +247,7 @@
 		return;
 	}
 
+	vecidx -= MLX5_IRQ_VEC_COMP_BASE;
 	snprintf(name, MLX5_MAX_IRQ_NAME, "mlx5_comp%d", vecidx);
 }
 
@@ -585,7 +587,7 @@
 	struct mlx5_irq_table *table = mlx5_irq_table_get(dev);
 	struct mlx5_irq_pool *pool = table->pcif_pool;
 	struct irq_affinity_desc af_desc;
-	int offset = 1;
+	int offset = MLX5_IRQ_VEC_COMP_BASE;
 
 	if (!pool->xa_num_irqs.max)
 		offset = 0;
@@ -636,9 +638,11 @@
 	kvfree(pool);
 }
 
-static int irq_pools_init(struct mlx5_core_dev *dev, int sf_vec, int pcif_vec)
+static int irq_pools_init(struct mlx5_core_dev *dev, int sf_vec, int pcif_vec,
+			  bool dynamic_vec)
 {
 	struct mlx5_irq_table *table = dev->priv.irq_table;
+	int sf_vec_available = sf_vec;
 	int num_sf_ctrl_by_msix;
 	int num_sf_ctrl_by_sfs;
 	int num_sf_ctrl;
@@ -663,6 +667,13 @@
 					  MLX5_SFS_PER_CTRL_IRQ);
 	num_sf_ctrl = min_t(int, num_sf_ctrl_by_msix, num_sf_ctrl_by_sfs);
 	num_sf_ctrl = min_t(int, MLX5_IRQ_CTRL_SF_MAX, num_sf_ctrl);
+	if (!dynamic_vec && (num_sf_ctrl + 1) > sf_vec_available) {
+		mlx5_core_dbg(dev,
+			      "Not enough IRQs for SFs control and completion pool, required=%d avail=%d\n",
+			      num_sf_ctrl + 1, sf_vec_available);
+		return 0;
+	}
+
 	table->sf_ctrl_pool = irq_pool_alloc(dev, pcif_vec, num_sf_ctrl,
 					     "mlx5_sf_ctrl",
 					     MLX5_EQ_SHARE_IRQ_MIN_CTRL,
@@ -671,9 +682,11 @@
 		err = PTR_ERR(table->sf_ctrl_pool);
 		goto err_pf;
 	}
-	/* init sf_comp_pool */
+	sf_vec_available -= num_sf_ctrl;
+
+	/* init sf_comp_pool, remaining vectors are for the SF completions */
 	table->sf_comp_pool = irq_pool_alloc(dev, pcif_vec + num_sf_ctrl,
-					     sf_vec - num_sf_ctrl, "mlx5_sf_comp",
+					     sf_vec_available, "mlx5_sf_comp",
 					     MLX5_EQ_SHARE_IRQ_MIN_COMP,
 					     MLX5_EQ_SHARE_IRQ_MAX_COMP);
 	if (IS_ERR(table->sf_comp_pool)) {
@@ -764,6 +777,7 @@
 	int num_eqs = MLX5_CAP_GEN(dev, max_num_eqs) ?
 		      MLX5_CAP_GEN(dev, max_num_eqs) :
 		      1 << MLX5_CAP_GEN(dev, log_max_eq);
+	bool dynamic_vec;
 	int total_vec;
 	int pcif_vec;
 	int req_vec;
@@ -773,22 +787,32 @@
 	if (mlx5_core_is_sf(dev))
 		return 0;
 
+	/* PCI PF vectors usage is limited by online cpus, device EQs and
+	 * PCI MSI-X capability.
+	 */
 	pcif_vec = MLX5_CAP_GEN(dev, num_ports) * num_online_cpus() + 1;
 	pcif_vec = min_t(int, pcif_vec, num_eqs);
+	pcif_vec = min_t(int, pcif_vec, pci_msix_vec_count(dev->pdev));
 
 	total_vec = pcif_vec;
 	if (mlx5_sf_max_functions(dev))
 		total_vec += MLX5_IRQ_CTRL_SF_MAX +
 			MLX5_COMP_EQS_PER_SF * mlx5_sf_max_functions(dev);
 	total_vec = min_t(int, total_vec, pci_msix_vec_count(dev->pdev));
-	pcif_vec = min_t(int, pcif_vec, pci_msix_vec_count(dev->pdev));
 
 	req_vec = pci_msix_can_alloc_dyn(dev->pdev) ? 1 : total_vec;
 	n = pci_alloc_irq_vectors(dev->pdev, 1, req_vec, PCI_IRQ_MSIX);
 	if (n < 0)
 		return n;
 
-	err = irq_pools_init(dev, total_vec - pcif_vec, pcif_vec);
+	/* Further limit vectors of the pools based on platform for non dynamic case */
+	dynamic_vec = pci_msix_can_alloc_dyn(dev->pdev);
+	if (!dynamic_vec) {
+		pcif_vec = min_t(int, n, pcif_vec);
+		total_vec = min_t(int, n, total_vec);
+	}
+
+	err = irq_pools_init(dev, total_vec - pcif_vec, pcif_vec, dynamic_vec);
 	if (err)
 		pci_free_irq_vectors(dev->pdev);
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/qos.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/qos.c
@@ -28,6 +28,9 @@
 {
 	u32 sched_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {0};
 
+	if (!(MLX5_CAP_QOS(mdev, nic_element_type) & ELEMENT_TYPE_CAP_MASK_QUEUE_GROUP))
+		return -EOPNOTSUPP;
+
 	MLX5_SET(scheduling_context, sched_ctx, parent_element_id, parent_id);
 	MLX5_SET(scheduling_context, sched_ctx, element_type,
 		 SCHEDULING_CONTEXT_ELEMENT_TYPE_QUEUE_GROUP);
@@ -44,6 +47,10 @@
 	u32 sched_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {0};
 	void *attr;
 
+	if (!(MLX5_CAP_QOS(mdev, nic_element_type) & ELEMENT_TYPE_CAP_MASK_TSAR) ||
+	    !(MLX5_CAP_QOS(mdev, nic_tsar_type) & TSAR_TYPE_CAP_MASK_DWRR))
+		return -EOPNOTSUPP;
+
 	MLX5_SET(scheduling_context, sched_ctx, parent_element_id, parent_id);
 	MLX5_SET(scheduling_context, sched_ctx, element_type,
 		 SCHEDULING_CONTEXT_ELEMENT_TYPE_TSAR);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/driver.c
@@ -60,6 +60,13 @@
 		goto remap_err;
 	}
 
+	/* Peer devlink logic expects to work on unregistered devlink instance. */
+	err = mlx5_core_peer_devlink_set(sf_dev, devlink);
+	if (err) {
+		mlx5_core_warn(mdev, "mlx5_core_peer_devlink_set err=%d\n", err);
+		goto peer_devlink_set_err;
+	}
+
 	if (MLX5_ESWITCH_MANAGER(sf_dev->parent_mdev))
 		err = mlx5_init_one_light(mdev);
 	else
@@ -69,21 +76,10 @@
 		goto init_one_err;
 	}
 
-	err = mlx5_core_peer_devlink_set(sf_dev, devlink);
-	if (err) {
-		mlx5_core_warn(mdev, "mlx5_core_peer_devlink_set err=%d\n", err);
-		goto peer_devlink_set_err;
-	}
-
-	devlink_register(devlink);
 	return 0;
 
-peer_devlink_set_err:
-	if (mlx5_dev_is_lightweight(sf_dev->mdev))
-		mlx5_uninit_one_light(sf_dev->mdev);
-	else
-		mlx5_uninit_one(sf_dev->mdev);
 init_one_err:
+peer_devlink_set_err:
 	iounmap(mdev->iseg);
 remap_err:
 	mlx5_mdev_uninit(mdev);
@@ -95,24 +91,29 @@
 static void mlx5_sf_dev_remove(struct auxiliary_device *adev)
 {
 	struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev);
-	struct devlink *devlink = priv_to_devlink(sf_dev->mdev);
+	struct mlx5_core_dev *mdev = sf_dev->mdev;
+	struct devlink *devlink;
 
-	mlx5_drain_health_wq(sf_dev->mdev);
-	devlink_unregister(devlink);
-	if (mlx5_dev_is_lightweight(sf_dev->mdev))
-		mlx5_uninit_one_light(sf_dev->mdev);
+	devlink = priv_to_devlink(mdev);
+	set_bit(MLX5_BREAK_FW_WAIT, &mdev->intf_state);
+	mlx5_drain_health_wq(mdev);
+	if (mlx5_dev_is_lightweight(mdev))
+		mlx5_uninit_one_light(mdev);
 	else
-		mlx5_uninit_one(sf_dev->mdev);
-	iounmap(sf_dev->mdev->iseg);
-	mlx5_mdev_uninit(sf_dev->mdev);
+		mlx5_uninit_one(mdev);
+	iounmap(mdev->iseg);
+	mlx5_mdev_uninit(mdev);
 	mlx5_devlink_free(devlink);
 }
 
 static void mlx5_sf_dev_shutdown(struct auxiliary_device *adev)
 {
 	struct mlx5_sf_dev *sf_dev = container_of(adev, struct mlx5_sf_dev, adev);
+	struct mlx5_core_dev *mdev = sf_dev->mdev;
 
-	mlx5_unload_one(sf_dev->mdev, false);
+	set_bit(MLX5_BREAK_FW_WAIT, &mdev->intf_state);
+	mlx5_drain_health_wq(mdev);
+	mlx5_unload_one(mdev, false);
 }
 
 static const struct auxiliary_device_id mlx5_sf_dev_id_table[] = {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c
@@ -249,6 +249,7 @@
 	return 0;
 
 esw_err:
+	mlx5_sf_function_id_erase(table, sf);
 	mlx5_sf_free(table, sf);
 	return err;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c
@@ -297,7 +297,9 @@
 	if (ret) {
 		mlx5dr_dbg(dmn, "Couldn't insert new vport into xarray (%d)\n", ret);
 		kvfree(vport_caps);
-		return ERR_PTR(ret);
+		if (ret == -EBUSY)
+			return ERR_PTR(-EBUSY);
+		return NULL;
 	}
 
 	return vport_caps;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
@@ -7,7 +7,7 @@
 /* don't try to optimize STE allocation if the stack is too constaraining */
 #define DR_RULE_MAX_STES_OPTIMIZED 0
 #else
-#define DR_RULE_MAX_STES_OPTIMIZED 5
+#define DR_RULE_MAX_STES_OPTIMIZED 2
 #endif
 #define DR_RULE_MAX_STE_CHAIN_OPTIMIZED (DR_RULE_MAX_STES_OPTIMIZED + DR_ACTION_MAX_STES)
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c
@@ -1067,7 +1067,6 @@
 	int inlen, err, eqn;
 	void *cqc, *in;
 	__be64 *pas;
-	int vector;
 	u32 i;
 
 	cq = kzalloc(sizeof(*cq), GFP_KERNEL);
@@ -1096,8 +1095,7 @@
 	if (!in)
 		goto err_cqwq;
 
-	vector = raw_smp_processor_id() % mlx5_comp_vectors_max(mdev);
-	err = mlx5_comp_eqn_get(mdev, vector, &eqn);
+	err = mlx5_comp_eqn_get(mdev, 0, &eqn);
 	if (err) {
 		kvfree(in);
 		goto err_cqwq;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige.h
@@ -40,6 +40,7 @@
  */
 #define MLXBF_GIGE_BCAST_MAC_FILTER_IDX 0
 #define MLXBF_GIGE_LOCAL_MAC_FILTER_IDX 1
+#define MLXBF_GIGE_MAX_FILTER_IDX       3
 
 /* Define for broadcast MAC literal */
 #define BCAST_MAC_ADDR 0xFFFFFFFFFFFF
@@ -175,6 +176,13 @@
 int mlxbf_gige_mdio_probe(struct platform_device *pdev,
 			  struct mlxbf_gige *priv);
 void mlxbf_gige_mdio_remove(struct mlxbf_gige *priv);
+
+void mlxbf_gige_enable_multicast_rx(struct mlxbf_gige *priv);
+void mlxbf_gige_disable_multicast_rx(struct mlxbf_gige *priv);
+void mlxbf_gige_enable_mac_rx_filter(struct mlxbf_gige *priv,
+				     unsigned int index);
+void mlxbf_gige_disable_mac_rx_filter(struct mlxbf_gige *priv,
+				      unsigned int index);
 void mlxbf_gige_set_mac_rx_filter(struct mlxbf_gige *priv,
 				  unsigned int index, u64 dmac);
 void mlxbf_gige_get_mac_rx_filter(struct mlxbf_gige *priv,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c
@@ -14,6 +14,7 @@
 #include <linux/module.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
+#include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
 
 #include "mlxbf_gige.h"
@@ -139,13 +140,10 @@
 	control |= MLXBF_GIGE_CONTROL_PORT_EN;
 	writeq(control, priv->base + MLXBF_GIGE_CONTROL);
 
-	err = mlxbf_gige_request_irqs(priv);
-	if (err)
-		return err;
 	mlxbf_gige_cache_stats(priv);
 	err = mlxbf_gige_clean_port(priv);
 	if (err)
-		goto free_irqs;
+		return err;
 
 	/* Clear driver's valid_polarity to match hardware,
 	 * since the above call to clean_port() resets the
@@ -157,7 +155,7 @@
 
 	err = mlxbf_gige_tx_init(priv);
 	if (err)
-		goto free_irqs;
+		goto phy_deinit;
 	err = mlxbf_gige_rx_init(priv);
 	if (err)
 		goto tx_deinit;
@@ -166,6 +164,14 @@
 	napi_enable(&priv->napi);
 	netif_start_queue(netdev);
 
+	err = mlxbf_gige_request_irqs(priv);
+	if (err)
+		goto napi_deinit;
+
+	mlxbf_gige_enable_mac_rx_filter(priv, MLXBF_GIGE_BCAST_MAC_FILTER_IDX);
+	mlxbf_gige_enable_mac_rx_filter(priv, MLXBF_GIGE_LOCAL_MAC_FILTER_IDX);
+	mlxbf_gige_enable_multicast_rx(priv);
+
 	/* Set bits in INT_EN that we care about */
 	int_en = MLXBF_GIGE_INT_EN_HW_ACCESS_ERROR |
 		 MLXBF_GIGE_INT_EN_TX_CHECKSUM_INPUTS |
@@ -182,11 +188,17 @@
 
 	return 0;
 
+napi_deinit:
+	netif_stop_queue(netdev);
+	napi_disable(&priv->napi);
+	netif_napi_del(&priv->napi);
+	mlxbf_gige_rx_deinit(priv);
+
 tx_deinit:
 	mlxbf_gige_tx_deinit(priv);
 
-free_irqs:
-	mlxbf_gige_free_irqs(priv);
+phy_deinit:
+	phy_stop(phydev);
 	return err;
 }
 
@@ -371,6 +383,7 @@
 	void __iomem *plu_base;
 	void __iomem *base;
 	int addr, phy_irq;
+	unsigned int i;
 	int err;
 
 	base = devm_platform_ioremap_resource(pdev, MLXBF_GIGE_RES_MAC);
@@ -415,6 +428,11 @@
 	priv->rx_q_entries = MLXBF_GIGE_DEFAULT_RXQ_SZ;
 	priv->tx_q_entries = MLXBF_GIGE_DEFAULT_TXQ_SZ;
 
+	for (i = 0; i <= MLXBF_GIGE_MAX_FILTER_IDX; i++)
+		mlxbf_gige_disable_mac_rx_filter(priv, i);
+	mlxbf_gige_disable_multicast_rx(priv);
+	mlxbf_gige_disable_promisc(priv);
+
 	/* Write initial MAC address to hardware */
 	mlxbf_gige_initial_mac(priv);
 
@@ -485,8 +503,13 @@
 {
 	struct mlxbf_gige *priv = platform_get_drvdata(pdev);
 
-	writeq(0, priv->base + MLXBF_GIGE_INT_EN);
-	mlxbf_gige_clean_port(priv);
+	rtnl_lock();
+	netif_device_detach(priv->netdev);
+
+	if (netif_running(priv->netdev))
+		dev_close(priv->netdev);
+
+	rtnl_unlock();
 }
 
 static const struct acpi_device_id __maybe_unused mlxbf_gige_acpi_match[] = {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_regs.h
@@ -62,6 +62,8 @@
 #define MLXBF_GIGE_TX_STATUS_DATA_FIFO_FULL           BIT(1)
 #define MLXBF_GIGE_RX_MAC_FILTER_DMAC_RANGE_START     0x0520
 #define MLXBF_GIGE_RX_MAC_FILTER_DMAC_RANGE_END       0x0528
+#define MLXBF_GIGE_RX_MAC_FILTER_GENERAL              0x0530
+#define MLXBF_GIGE_RX_MAC_FILTER_EN_MULTICAST         BIT(1)
 #define MLXBF_GIGE_RX_MAC_FILTER_COUNT_DISC           0x0540
 #define MLXBF_GIGE_RX_MAC_FILTER_COUNT_DISC_EN        BIT(0)
 #define MLXBF_GIGE_RX_MAC_FILTER_COUNT_PASS           0x0548
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c
@@ -11,15 +11,31 @@
 #include "mlxbf_gige.h"
 #include "mlxbf_gige_regs.h"
 
-void mlxbf_gige_set_mac_rx_filter(struct mlxbf_gige *priv,
-				  unsigned int index, u64 dmac)
+void mlxbf_gige_enable_multicast_rx(struct mlxbf_gige *priv)
 {
 	void __iomem *base = priv->base;
-	u64 control;
+	u64 data;
 
-	/* Write destination MAC to specified MAC RX filter */
-	writeq(dmac, base + MLXBF_GIGE_RX_MAC_FILTER +
-	       (index * MLXBF_GIGE_RX_MAC_FILTER_STRIDE));
+	data = readq(base + MLXBF_GIGE_RX_MAC_FILTER_GENERAL);
+	data |= MLXBF_GIGE_RX_MAC_FILTER_EN_MULTICAST;
+	writeq(data, base + MLXBF_GIGE_RX_MAC_FILTER_GENERAL);
+}
+
+void mlxbf_gige_disable_multicast_rx(struct mlxbf_gige *priv)
+{
+	void __iomem *base = priv->base;
+	u64 data;
+
+	data = readq(base + MLXBF_GIGE_RX_MAC_FILTER_GENERAL);
+	data &= ~MLXBF_GIGE_RX_MAC_FILTER_EN_MULTICAST;
+	writeq(data, base + MLXBF_GIGE_RX_MAC_FILTER_GENERAL);
+}
+
+void mlxbf_gige_enable_mac_rx_filter(struct mlxbf_gige *priv,
+				     unsigned int index)
+{
+	void __iomem *base = priv->base;
+	u64 control;
 
 	/* Enable MAC receive filter mask for specified index */
 	control = readq(base + MLXBF_GIGE_CONTROL);
@@ -27,6 +43,28 @@
 	writeq(control, base + MLXBF_GIGE_CONTROL);
 }
 
+void mlxbf_gige_disable_mac_rx_filter(struct mlxbf_gige *priv,
+				      unsigned int index)
+{
+	void __iomem *base = priv->base;
+	u64 control;
+
+	/* Disable MAC receive filter mask for specified index */
+	control = readq(base + MLXBF_GIGE_CONTROL);
+	control &= ~(MLXBF_GIGE_CONTROL_EN_SPECIFIC_MAC << index);
+	writeq(control, base + MLXBF_GIGE_CONTROL);
+}
+
+void mlxbf_gige_set_mac_rx_filter(struct mlxbf_gige *priv,
+				  unsigned int index, u64 dmac)
+{
+	void __iomem *base = priv->base;
+
+	/* Write destination MAC to specified MAC RX filter */
+	writeq(dmac, base + MLXBF_GIGE_RX_MAC_FILTER +
+	       (index * MLXBF_GIGE_RX_MAC_FILTER_STRIDE));
+}
+
 void mlxbf_gige_get_mac_rx_filter(struct mlxbf_gige *priv,
 				  unsigned int index, u64 *dmac)
 {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c
@@ -14,7 +14,6 @@
 #define MLXFW_FSM_STATE_WAIT_TIMEOUT_MS 30000
 #define MLXFW_FSM_STATE_WAIT_ROUNDS \
 	(MLXFW_FSM_STATE_WAIT_TIMEOUT_MS / MLXFW_FSM_STATE_WAIT_CYCLE_MS)
-#define MLXFW_FSM_MAX_COMPONENT_SIZE (10 * (1 << 20))
 
 static const int mlxfw_fsm_state_errno[] = {
 	[MLXFW_FSM_STATE_ERR_ERROR] = -EIO,
@@ -229,7 +228,6 @@
 		return err;
 	}
 
-	comp_max_size = min_t(u32, comp_max_size, MLXFW_FSM_MAX_COMPONENT_SIZE);
 	if (comp->data_size > comp_max_size) {
 		MLXFW_ERR_MSG(mlxfw_dev, extack,
 			      "Component size is bigger than limit", -EINVAL);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -849,7 +849,7 @@
 
 static const struct mlxsw_listener mlxsw_emad_rx_listener =
 	MLXSW_RXL(mlxsw_emad_rx_listener_func, ETHEMAD, TRAP_TO_CPU, false,
-		  EMAD, DISCARD);
+		  EMAD, FORWARD);
 
 static int mlxsw_emad_tlv_enable(struct mlxsw_core *mlxsw_core)
 {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c
@@ -95,7 +95,7 @@
 		      */
 	   has_trap:1,
 	   has_police:1;
-	unsigned int ref_count;
+	refcount_t ref_count;
 	struct mlxsw_afa_set *next; /* Pointer to the next set. */
 	struct mlxsw_afa_set *prev; /* Pointer to the previous set,
 				     * note that set may have multiple
@@ -120,7 +120,7 @@
 	struct rhash_head ht_node;
 	struct mlxsw_afa_fwd_entry_ht_key ht_key;
 	u32 kvdl_index;
-	unsigned int ref_count;
+	refcount_t ref_count;
 };
 
 static const struct rhashtable_params mlxsw_afa_fwd_entry_ht_params = {
@@ -282,7 +282,7 @@
 	/* Need to initialize the set to pass by default */
 	mlxsw_afa_set_goto_set(set, MLXSW_AFA_SET_GOTO_BINDING_CMD_TERM, 0);
 	set->ht_key.is_first = is_first;
-	set->ref_count = 1;
+	refcount_set(&set->ref_count, 1);
 	return set;
 }
 
@@ -330,7 +330,7 @@
 static void mlxsw_afa_set_put(struct mlxsw_afa *mlxsw_afa,
 			      struct mlxsw_afa_set *set)
 {
-	if (--set->ref_count)
+	if (!refcount_dec_and_test(&set->ref_count))
 		return;
 	if (set->shared)
 		mlxsw_afa_set_unshare(mlxsw_afa, set);
@@ -350,7 +350,7 @@
 	set = rhashtable_lookup_fast(&mlxsw_afa->set_ht, &orig_set->ht_key,
 				     mlxsw_afa_set_ht_params);
 	if (set) {
-		set->ref_count++;
+		refcount_inc(&set->ref_count);
 		mlxsw_afa_set_put(mlxsw_afa, orig_set);
 	} else {
 		set = orig_set;
@@ -564,7 +564,7 @@
 	if (!fwd_entry)
 		return ERR_PTR(-ENOMEM);
 	fwd_entry->ht_key.local_port = local_port;
-	fwd_entry->ref_count = 1;
+	refcount_set(&fwd_entry->ref_count, 1);
 
 	err = rhashtable_insert_fast(&mlxsw_afa->fwd_entry_ht,
 				     &fwd_entry->ht_node,
@@ -607,7 +607,7 @@
 	fwd_entry = rhashtable_lookup_fast(&mlxsw_afa->fwd_entry_ht, &ht_key,
 					   mlxsw_afa_fwd_entry_ht_params);
 	if (fwd_entry) {
-		fwd_entry->ref_count++;
+		refcount_inc(&fwd_entry->ref_count);
 		return fwd_entry;
 	}
 	return mlxsw_afa_fwd_entry_create(mlxsw_afa, local_port);
@@ -616,7 +616,7 @@
 static void mlxsw_afa_fwd_entry_put(struct mlxsw_afa *mlxsw_afa,
 				    struct mlxsw_afa_fwd_entry *fwd_entry)
 {
-	if (--fwd_entry->ref_count)
+	if (!refcount_dec_and_test(&fwd_entry->ref_count))
 		return;
 	mlxsw_afa_fwd_entry_destroy(mlxsw_afa, fwd_entry);
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c
@@ -5,6 +5,7 @@
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/errno.h>
+#include <linux/refcount.h>
 
 #include "item.h"
 #include "core_acl_flex_keys.h"
@@ -66,7 +67,7 @@
 
 		for (j = 0; j < block->instances_count; j++) {
 			const struct mlxsw_afk_element_info *elinfo;
-			struct mlxsw_afk_element_inst *elinst;
+			const struct mlxsw_afk_element_inst *elinst;
 
 			elinst = &block->instances[j];
 			elinfo = &mlxsw_afk_element_infos[elinst->element];
@@ -107,7 +108,7 @@
 
 struct mlxsw_afk_key_info {
 	struct list_head list;
-	unsigned int ref_count;
+	refcount_t ref_count;
 	unsigned int blocks_count;
 	int element_to_block[MLXSW_AFK_ELEMENT_MAX]; /* index is element, value
 						      * is index inside "blocks"
@@ -153,7 +154,7 @@
 		const struct mlxsw_afk_block *block = &mlxsw_afk->blocks[i];
 
 		for (j = 0; j < block->instances_count; j++) {
-			struct mlxsw_afk_element_inst *elinst;
+			const struct mlxsw_afk_element_inst *elinst;
 
 			elinst = &block->instances[j];
 			if (elinst->element == element) {
@@ -334,7 +335,7 @@
 	if (err)
 		goto err_picker;
 	list_add(&key_info->list, &mlxsw_afk->key_info_list);
-	key_info->ref_count = 1;
+	refcount_set(&key_info->ref_count, 1);
 	return key_info;
 
 err_picker:
@@ -356,7 +357,7 @@
 
 	key_info = mlxsw_afk_key_info_find(mlxsw_afk, elusage);
 	if (key_info) {
-		key_info->ref_count++;
+		refcount_inc(&key_info->ref_count);
 		return key_info;
 	}
 	return mlxsw_afk_key_info_create(mlxsw_afk, elusage);
@@ -365,7 +366,7 @@
 
 void mlxsw_afk_key_info_put(struct mlxsw_afk_key_info *key_info)
 {
-	if (--key_info->ref_count)
+	if (!refcount_dec_and_test(&key_info->ref_count))
 		return;
 	mlxsw_afk_key_info_destroy(key_info);
 }
@@ -385,7 +386,7 @@
 	int i;
 
 	for (i = 0; i < block->instances_count; i++) {
-		struct mlxsw_afk_element_inst *elinst;
+		const struct mlxsw_afk_element_inst *elinst;
 
 		elinst = &block->instances[i];
 		if (elinst->element == element)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h
@@ -117,7 +117,7 @@
 
 struct mlxsw_afk_block {
 	u16 encoding; /* block ID */
-	struct mlxsw_afk_element_inst *instances;
+	const struct mlxsw_afk_element_inst *instances;
 	unsigned int instances_count;
 	bool high_entropy;
 };
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/core_env.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/core_env.c
@@ -1357,24 +1357,20 @@
 	.got_inactive = mlxsw_env_got_inactive,
 };
 
-static int mlxsw_env_max_module_eeprom_len_query(struct mlxsw_env *mlxsw_env)
+static void mlxsw_env_max_module_eeprom_len_query(struct mlxsw_env *mlxsw_env)
 {
 	char mcam_pl[MLXSW_REG_MCAM_LEN];
-	bool mcia_128b_supported;
+	bool mcia_128b_supported = false;
 	int err;
 
 	mlxsw_reg_mcam_pack(mcam_pl,
 			    MLXSW_REG_MCAM_FEATURE_GROUP_ENHANCED_FEATURES);
 	err = mlxsw_reg_query(mlxsw_env->core, MLXSW_REG(mcam), mcam_pl);
-	if (err)
-		return err;
-
-	mlxsw_reg_mcam_unpack(mcam_pl, MLXSW_REG_MCAM_MCIA_128B,
-			      &mcia_128b_supported);
+	if (!err)
+		mlxsw_reg_mcam_unpack(mcam_pl, MLXSW_REG_MCAM_MCIA_128B,
+				      &mcia_128b_supported);
 
 	mlxsw_env->max_eeprom_len = mcia_128b_supported ? 128 : 48;
-
-	return 0;
 }
 
 int mlxsw_env_init(struct mlxsw_core *mlxsw_core,
@@ -1445,15 +1441,11 @@
 	if (err)
 		goto err_type_set;
 
-	err = mlxsw_env_max_module_eeprom_len_query(env);
-	if (err)
-		goto err_eeprom_len_query;
-
+	mlxsw_env_max_module_eeprom_len_query(env);
 	env->line_cards[0]->active = true;
 
 	return 0;
 
-err_eeprom_len_query:
 err_type_set:
 	mlxsw_env_module_event_disable(env, 0);
 err_mlxsw_env_module_event_enable:
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
@@ -1484,6 +1484,7 @@
 	vfree(types_info->data);
 err_data_alloc:
 	kfree(types_info);
+	linecards->types_info = NULL;
 	return err;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/pci.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/pci.c
@@ -1490,20 +1490,31 @@
 	return -EBUSY;
 }
 
-static int mlxsw_pci_reset_at_pci_disable(struct mlxsw_pci *mlxsw_pci)
+static int mlxsw_pci_reset_at_pci_disable(struct mlxsw_pci *mlxsw_pci,
+					  bool pci_reset_sbr_supported)
 {
 	struct pci_dev *pdev = mlxsw_pci->pdev;
 	char mrsr_pl[MLXSW_REG_MRSR_LEN];
+	struct pci_dev *bridge;
 	int err;
 
+	if (!pci_reset_sbr_supported) {
+		pci_dbg(pdev, "Performing PCI hot reset instead of \"all reset\"\n");
+		goto sbr;
+	}
+
 	mlxsw_reg_mrsr_pack(mrsr_pl,
 			    MLXSW_REG_MRSR_COMMAND_RESET_AT_PCI_DISABLE);
 	err = mlxsw_reg_write(mlxsw_pci->core, MLXSW_REG(mrsr), mrsr_pl);
 	if (err)
 		return err;
 
+sbr:
 	device_lock_assert(&pdev->dev);
 
+	bridge = pci_upstream_bridge(pdev);
+	if (bridge)
+		pci_cfg_access_lock(bridge);
 	pci_cfg_access_lock(pdev);
 	pci_save_state(pdev);
 
@@ -1513,6 +1524,8 @@
 
 	pci_restore_state(pdev);
 	pci_cfg_access_unlock(pdev);
+	if (bridge)
+		pci_cfg_access_unlock(bridge);
 
 	return err;
 }
@@ -1529,8 +1542,9 @@
 mlxsw_pci_reset(struct mlxsw_pci *mlxsw_pci, const struct pci_device_id *id)
 {
 	struct pci_dev *pdev = mlxsw_pci->pdev;
+	bool pci_reset_sbr_supported = false;
 	char mcam_pl[MLXSW_REG_MCAM_LEN];
-	bool pci_reset_supported;
+	bool pci_reset_supported = false;
 	u32 sys_status;
 	int err;
 
@@ -1548,15 +1562,17 @@
 	mlxsw_reg_mcam_pack(mcam_pl,
 			    MLXSW_REG_MCAM_FEATURE_GROUP_ENHANCED_FEATURES);
 	err = mlxsw_reg_query(mlxsw_pci->core, MLXSW_REG(mcam), mcam_pl);
-	if (err)
-		return err;
-
-	mlxsw_reg_mcam_unpack(mcam_pl, MLXSW_REG_MCAM_PCI_RESET,
-			      &pci_reset_supported);
+	if (!err) {
+		mlxsw_reg_mcam_unpack(mcam_pl, MLXSW_REG_MCAM_PCI_RESET,
+				      &pci_reset_supported);
+		mlxsw_reg_mcam_unpack(mcam_pl, MLXSW_REG_MCAM_PCI_RESET_SBR,
+				      &pci_reset_sbr_supported);
+	}
 
 	if (pci_reset_supported) {
 		pci_dbg(pdev, "Starting PCI reset flow\n");
-		err = mlxsw_pci_reset_at_pci_disable(mlxsw_pci);
+		err = mlxsw_pci_reset_at_pci_disable(mlxsw_pci,
+						     pci_reset_sbr_supported);
 	} else {
 		pci_dbg(pdev, "Starting software reset flow\n");
 		err = mlxsw_pci_reset_sw(mlxsw_pci);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -10668,6 +10668,8 @@
 	MLXSW_REG_MCAM_MCIA_128B = 34,
 	/* If set, MRSR.command=6 is supported. */
 	MLXSW_REG_MCAM_PCI_RESET = 48,
+	/* If set, MRSR.command=6 is supported with Secondary Bus Reset. */
+	MLXSW_REG_MCAM_PCI_RESET_SBR = 67,
 };
 
 #define MLXSW_REG_BYTES_PER_DWORD 0x4
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
@@ -9,6 +9,7 @@
 #include <linux/rhashtable.h>
 #include <linux/netdevice.h>
 #include <linux/mutex.h>
+#include <linux/refcount.h>
 #include <net/net_namespace.h>
 #include <net/tc_act/tc_vlan.h>
 
@@ -55,7 +56,7 @@
 	struct rhash_head ht_node; /* Member of acl HT */
 	struct mlxsw_sp_acl_ruleset_ht_key ht_key;
 	struct rhashtable rule_ht;
-	unsigned int ref_count;
+	refcount_t ref_count;
 	unsigned int min_prio;
 	unsigned int max_prio;
 	unsigned long priv[];
@@ -99,7 +100,7 @@
 mlxsw_sp_acl_ruleset_is_singular(const struct mlxsw_sp_acl_ruleset *ruleset)
 {
 	/* We hold a reference on ruleset ourselves */
-	return ruleset->ref_count == 2;
+	return refcount_read(&ruleset->ref_count) == 2;
 }
 
 int mlxsw_sp_acl_ruleset_bind(struct mlxsw_sp *mlxsw_sp,
@@ -176,7 +177,7 @@
 	ruleset = kzalloc(alloc_size, GFP_KERNEL);
 	if (!ruleset)
 		return ERR_PTR(-ENOMEM);
-	ruleset->ref_count = 1;
+	refcount_set(&ruleset->ref_count, 1);
 	ruleset->ht_key.block = block;
 	ruleset->ht_key.chain_index = chain_index;
 	ruleset->ht_key.ops = ops;
@@ -222,13 +223,13 @@
 
 static void mlxsw_sp_acl_ruleset_ref_inc(struct mlxsw_sp_acl_ruleset *ruleset)
 {
-	ruleset->ref_count++;
+	refcount_inc(&ruleset->ref_count);
 }
 
 static void mlxsw_sp_acl_ruleset_ref_dec(struct mlxsw_sp *mlxsw_sp,
 					 struct mlxsw_sp_acl_ruleset *ruleset)
 {
-	if (--ruleset->ref_count)
+	if (!refcount_dec_and_test(&ruleset->ref_count))
 		return;
 	mlxsw_sp_acl_ruleset_destroy(mlxsw_sp, ruleset);
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c
@@ -391,7 +391,8 @@
 	if (err)
 		return err;
 
-	lkey_id = aregion->ops->lkey_id_get(aregion, aentry->enc_key, erp_id);
+	lkey_id = aregion->ops->lkey_id_get(aregion, aentry->ht_key.enc_key,
+					    erp_id);
 	if (IS_ERR(lkey_id))
 		return PTR_ERR(lkey_id);
 	aentry->lkey_id = lkey_id;
@@ -399,7 +400,7 @@
 	kvdl_index = mlxsw_afa_block_first_kvdl_index(rulei->act_block);
 	mlxsw_reg_ptce3_pack(ptce3_pl, true, MLXSW_REG_PTCE3_OP_WRITE_WRITE,
 			     priority, region->tcam_region_info,
-			     aentry->enc_key, erp_id,
+			     aentry->ht_key.enc_key, erp_id,
 			     aentry->delta_info.start,
 			     aentry->delta_info.mask,
 			     aentry->delta_info.value,
@@ -428,7 +429,7 @@
 
 	mlxsw_reg_ptce3_pack(ptce3_pl, false, MLXSW_REG_PTCE3_OP_WRITE_WRITE, 0,
 			     region->tcam_region_info,
-			     aentry->enc_key, erp_id,
+			     aentry->ht_key.enc_key, erp_id,
 			     aentry->delta_info.start,
 			     aentry->delta_info.mask,
 			     aentry->delta_info.value,
@@ -457,7 +458,7 @@
 	kvdl_index = mlxsw_afa_block_first_kvdl_index(rulei->act_block);
 	mlxsw_reg_ptce3_pack(ptce3_pl, true, MLXSW_REG_PTCE3_OP_WRITE_UPDATE,
 			     priority, region->tcam_region_info,
-			     aentry->enc_key, erp_id,
+			     aentry->ht_key.enc_key, erp_id,
 			     aentry->delta_info.start,
 			     aentry->delta_info.mask,
 			     aentry->delta_info.value,
@@ -480,15 +481,13 @@
 	int err;
 
 	mlxsw_afk_encode(afk, region->key_info, &rulei->values,
-			 aentry->ht_key.full_enc_key, mask);
+			 aentry->ht_key.enc_key, mask);
 
 	erp_mask = mlxsw_sp_acl_erp_mask_get(aregion, mask, false);
 	if (IS_ERR(erp_mask))
 		return PTR_ERR(erp_mask);
 	aentry->erp_mask = erp_mask;
 	aentry->ht_key.erp_id = mlxsw_sp_acl_erp_mask_erp_id(erp_mask);
-	memcpy(aentry->enc_key, aentry->ht_key.full_enc_key,
-	       sizeof(aentry->enc_key));
 
 	/* Compute all needed delta information and clear the delta bits
 	 * from the encrypted key.
@@ -497,9 +496,8 @@
 	aentry->delta_info.start = mlxsw_sp_acl_erp_delta_start(delta);
 	aentry->delta_info.mask = mlxsw_sp_acl_erp_delta_mask(delta);
 	aentry->delta_info.value =
-		mlxsw_sp_acl_erp_delta_value(delta,
-					     aentry->ht_key.full_enc_key);
-	mlxsw_sp_acl_erp_delta_clear(delta, aentry->enc_key);
+		mlxsw_sp_acl_erp_delta_value(delta, aentry->ht_key.enc_key);
+	mlxsw_sp_acl_erp_delta_clear(delta, aentry->ht_key.enc_key);
 
 	/* Add rule to the list of A-TCAM rules, assuming this
 	 * rule is intended to A-TCAM. In case this rule does
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c
@@ -249,7 +249,7 @@
 		memcpy(chunk + pad_bytes, &erp_region_id,
 		       sizeof(erp_region_id));
 		memcpy(chunk + key_offset,
-		       &aentry->enc_key[chunk_key_offsets[chunk_index]],
+		       &aentry->ht_key.enc_key[chunk_key_offsets[chunk_index]],
 		       chunk_key_len);
 		chunk += chunk_len;
 	}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c
@@ -1217,18 +1217,6 @@
 	return err ? false : true;
 }
 
-static int mlxsw_sp_acl_erp_hints_obj_cmp(const void *obj1, const void *obj2)
-{
-	const struct mlxsw_sp_acl_erp_key *key1 = obj1;
-	const struct mlxsw_sp_acl_erp_key *key2 = obj2;
-
-	/* For hints purposes, two objects are considered equal
-	 * in case the masks are the same. Does not matter what
-	 * the "ctcam" value is.
-	 */
-	return memcmp(key1->mask, key2->mask, sizeof(key1->mask));
-}
-
 static void *mlxsw_sp_acl_erp_delta_create(void *priv, void *parent_obj,
 					   void *obj)
 {
@@ -1308,7 +1296,6 @@
 static const struct objagg_ops mlxsw_sp_acl_erp_objagg_ops = {
 	.obj_size = sizeof(struct mlxsw_sp_acl_erp_key),
 	.delta_check = mlxsw_sp_acl_erp_delta_check,
-	.hints_obj_cmp = mlxsw_sp_acl_erp_hints_obj_cmp,
 	.delta_create = mlxsw_sp_acl_erp_delta_create,
 	.delta_destroy = mlxsw_sp_acl_erp_delta_destroy,
 	.root_create = mlxsw_sp_acl_erp_root_create,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c
@@ -7,7 +7,7 @@
 #include "item.h"
 #include "core_acl_flex_keys.h"
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_dmac[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_dmac[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47, 0x00, 2),
 	MLXSW_AFK_ELEMENT_INST_BUF(DMAC_0_31, 0x02, 4),
 	MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 13, 3),
@@ -15,7 +15,7 @@
 	MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47, 0x00, 2),
 	MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31, 0x02, 4),
 	MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 13, 3),
@@ -23,27 +23,27 @@
 	MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac_ex[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac_ex[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47, 0x02, 2),
 	MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31, 0x04, 4),
 	MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x0C, 0, 16),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_sip[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_sip[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x00, 4),
 	MLXSW_AFK_ELEMENT_INST_U32(L4_PORT_RANGE, 0x04, 16, 16),
 	MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
 	MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_dip[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_dip[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x00, 4),
 	MLXSW_AFK_ELEMENT_INST_U32(L4_PORT_RANGE, 0x04, 16, 16),
 	MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
 	MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x00, 4),
 	MLXSW_AFK_ELEMENT_INST_U32(IP_ECN, 0x04, 4, 2),
 	MLXSW_AFK_ELEMENT_INST_U32(IP_TTL_, 0x04, 24, 8),
@@ -51,35 +51,35 @@
 	MLXSW_AFK_ELEMENT_INST_U32(TCP_FLAGS, 0x08, 8, 9), /* TCP_CONTROL+TCP_ECN */
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_ex[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_ex[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(VID, 0x00, 0, 12),
 	MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 29, 3),
 	MLXSW_AFK_ELEMENT_INST_U32(SRC_L4_PORT, 0x08, 0, 16),
 	MLXSW_AFK_ELEMENT_INST_U32(DST_L4_PORT, 0x0C, 0, 16),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_dip[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_dip[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_32_63, 0x00, 4),
 	MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x04, 4),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_ex1[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_ex1[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127, 0x00, 4),
 	MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_64_95, 0x04, 4),
 	MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_32_63, 0x00, 4),
 	MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x04, 4),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip_ex[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip_ex[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_96_127, 0x00, 4),
 	MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_64_95, 0x04, 4),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_packet_type[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_packet_type[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x00, 0, 16),
 };
 
@@ -124,90 +124,90 @@
 	.clear_block	= mlxsw_sp1_afk_clear_block,
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_0[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_0[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(FDB_MISS, 0x00, 3, 1),
 	MLXSW_AFK_ELEMENT_INST_BUF(DMAC_0_31, 0x04, 4),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_1[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_1[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(FDB_MISS, 0x00, 3, 1),
 	MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31, 0x04, 4),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_2[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_2[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47, 0x04, 2),
 	MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47, 0x06, 2),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_3[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_3[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x00, 0, 3),
 	MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 16, 12),
 	MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47, 0x06, 2),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_4[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_4[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x00, 0, 3),
 	MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 16, 12),
 	MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x04, 0, 16),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 16, 12),
 	MLXSW_AFK_ELEMENT_INST_EXT_U32(SRC_SYS_PORT, 0x04, 0, 8, -1, true), /* RX_ACL_SYSTEM_PORT */
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_0[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_0[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x04, 4),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_1[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_1[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x04, 4),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_2[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_2[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(IP_DSCP, 0x04, 0, 6),
 	MLXSW_AFK_ELEMENT_INST_U32(IP_ECN, 0x04, 6, 2),
 	MLXSW_AFK_ELEMENT_INST_U32(IP_TTL_, 0x04, 8, 8),
 	MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x04, 16, 8),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_5[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_5[] = {
 	MLXSW_AFK_ELEMENT_INST_EXT_U32(VIRT_ROUTER, 0x04, 20, 11, 0, true),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_0[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_0[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_0_3, 0x00, 0, 4),
 	MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_32_63, 0x04, 4),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_1[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_1[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_4_7, 0x00, 0, 4),
 	MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_64_95, 0x04, 4),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2[] = {
 	MLXSW_AFK_ELEMENT_INST_EXT_U32(VIRT_ROUTER_MSB, 0x00, 0, 3, 0, true),
 	MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127, 0x04, 4),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_3[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_3[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_32_63, 0x04, 4),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_4[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_4[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_64_95, 0x04, 4),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_5[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_5[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_96_127, 0x04, 4),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_0[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_0[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(SRC_L4_PORT, 0x04, 16, 16),
 	MLXSW_AFK_ELEMENT_INST_U32(DST_L4_PORT, 0x04, 0, 16),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_2[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_2[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(TCP_FLAGS, 0x04, 16, 9), /* TCP_CONTROL + TCP_ECN */
 	MLXSW_AFK_ELEMENT_INST_U32(L4_PORT_RANGE, 0x04, 0, 16),
 };
@@ -319,16 +319,20 @@
 	.clear_block	= mlxsw_sp2_afk_clear_block,
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5b[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5b[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 18, 12),
 	MLXSW_AFK_ELEMENT_INST_EXT_U32(SRC_SYS_PORT, 0x04, 0, 9, -1, true), /* RX_ACL_SYSTEM_PORT */
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_5b[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_1b[] = {
+	MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x04, 4),
+};
+
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_5b[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER, 0x04, 20, 12),
 };
 
-static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2b[] = {
+static const struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2b[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(VIRT_ROUTER_MSB, 0x00, 0, 4),
 	MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127, 0x04, 4),
 };
@@ -341,7 +345,7 @@
 	MLXSW_AFK_BLOCK(0x14, mlxsw_sp_afk_element_info_mac_4),
 	MLXSW_AFK_BLOCK_HIGH_ENTROPY(0x1A, mlxsw_sp_afk_element_info_mac_5b),
 	MLXSW_AFK_BLOCK_HIGH_ENTROPY(0x38, mlxsw_sp_afk_element_info_ipv4_0),
-	MLXSW_AFK_BLOCK_HIGH_ENTROPY(0x39, mlxsw_sp_afk_element_info_ipv4_1),
+	MLXSW_AFK_BLOCK_HIGH_ENTROPY(0x3F, mlxsw_sp_afk_element_info_ipv4_1b),
 	MLXSW_AFK_BLOCK(0x3A, mlxsw_sp_afk_element_info_ipv4_2),
 	MLXSW_AFK_BLOCK(0x36, mlxsw_sp_afk_element_info_ipv4_5b),
 	MLXSW_AFK_BLOCK(0x40, mlxsw_sp_afk_element_info_ipv6_0),
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
@@ -9,6 +9,8 @@
 #include <linux/rhashtable.h>
 #include <linux/netdevice.h>
 #include <linux/mutex.h>
+#include <linux/refcount.h>
+#include <linux/idr.h>
 #include <net/devlink.h>
 #include <trace/events/mlxsw.h>
 
@@ -57,41 +59,43 @@
 static int mlxsw_sp_acl_tcam_region_id_get(struct mlxsw_sp_acl_tcam *tcam,
 					   u16 *p_id)
 {
-	u16 id;
+	int id;
 
-	id = find_first_zero_bit(tcam->used_regions, tcam->max_regions);
-	if (id < tcam->max_regions) {
-		__set_bit(id, tcam->used_regions);
-		*p_id = id;
-		return 0;
-	}
-	return -ENOBUFS;
+	id = ida_alloc_max(&tcam->used_regions, tcam->max_regions - 1,
+			   GFP_KERNEL);
+	if (id < 0)
+		return id;
+
+	*p_id = id;
+
+	return 0;
 }
 
 static void mlxsw_sp_acl_tcam_region_id_put(struct mlxsw_sp_acl_tcam *tcam,
 					    u16 id)
 {
-	__clear_bit(id, tcam->used_regions);
+	ida_free(&tcam->used_regions, id);
 }
 
 static int mlxsw_sp_acl_tcam_group_id_get(struct mlxsw_sp_acl_tcam *tcam,
 					  u16 *p_id)
 {
-	u16 id;
+	int id;
 
-	id = find_first_zero_bit(tcam->used_groups, tcam->max_groups);
-	if (id < tcam->max_groups) {
-		__set_bit(id, tcam->used_groups);
-		*p_id = id;
-		return 0;
-	}
-	return -ENOBUFS;
+	id = ida_alloc_max(&tcam->used_groups, tcam->max_groups - 1,
+			   GFP_KERNEL);
+	if (id < 0)
+		return id;
+
+	*p_id = id;
+
+	return 0;
 }
 
 static void mlxsw_sp_acl_tcam_group_id_put(struct mlxsw_sp_acl_tcam *tcam,
 					   u16 id)
 {
-	__clear_bit(id, tcam->used_groups);
+	ida_free(&tcam->used_groups, id);
 }
 
 struct mlxsw_sp_acl_tcam_pattern {
@@ -155,7 +159,7 @@
 		struct mlxsw_sp_acl_tcam_rehash_ctx ctx;
 	} rehash;
 	struct mlxsw_sp *mlxsw_sp;
-	unsigned int ref_count;
+	refcount_t ref_count;
 };
 
 struct mlxsw_sp_acl_tcam_vchunk;
@@ -176,7 +180,7 @@
 	unsigned int priority; /* Priority within the vregion and group */
 	struct mlxsw_sp_acl_tcam_vgroup *vgroup;
 	struct mlxsw_sp_acl_tcam_vregion *vregion;
-	unsigned int ref_count;
+	refcount_t ref_count;
 };
 
 struct mlxsw_sp_acl_tcam_entry {
@@ -714,7 +718,9 @@
 			     rehash.dw.work);
 	int credits = MLXSW_SP_ACL_TCAM_VREGION_REHASH_CREDITS;
 
+	mutex_lock(&vregion->lock);
 	mlxsw_sp_acl_tcam_vregion_rehash(vregion->mlxsw_sp, vregion, &credits);
+	mutex_unlock(&vregion->lock);
 	if (credits < 0)
 		/* Rehash gone out of credits so it was interrupted.
 		 * Schedule the work as soon as possible to continue.
@@ -725,6 +731,17 @@
 }
 
 static void
+mlxsw_sp_acl_tcam_rehash_ctx_vchunk_reset(struct mlxsw_sp_acl_tcam_rehash_ctx *ctx)
+{
+	/* The entry markers are relative to the current chunk and therefore
+	 * needs to be reset together with the chunk marker.
+	 */
+	ctx->current_vchunk = NULL;
+	ctx->start_ventry = NULL;
+	ctx->stop_ventry = NULL;
+}
+
+static void
 mlxsw_sp_acl_tcam_rehash_ctx_vchunk_changed(struct mlxsw_sp_acl_tcam_vchunk *vchunk)
 {
 	struct mlxsw_sp_acl_tcam_vregion *vregion = vchunk->vregion;
@@ -746,7 +763,7 @@
 	 * the current chunk pointer to make sure all chunks
 	 * are properly migrated.
 	 */
-	vregion->rehash.ctx.current_vchunk = NULL;
+	mlxsw_sp_acl_tcam_rehash_ctx_vchunk_reset(&vregion->rehash.ctx);
 }
 
 static struct mlxsw_sp_acl_tcam_vregion *
@@ -769,7 +786,7 @@
 	vregion->tcam = tcam;
 	vregion->mlxsw_sp = mlxsw_sp;
 	vregion->vgroup = vgroup;
-	vregion->ref_count = 1;
+	refcount_set(&vregion->ref_count, 1);
 
 	vregion->key_info = mlxsw_afk_key_info_get(afk, elusage);
 	if (IS_ERR(vregion->key_info)) {
@@ -819,10 +836,14 @@
 	struct mlxsw_sp_acl_tcam *tcam = vregion->tcam;
 
 	if (vgroup->vregion_rehash_enabled && ops->region_rehash_hints_get) {
+		struct mlxsw_sp_acl_tcam_rehash_ctx *ctx = &vregion->rehash.ctx;
+
 		mutex_lock(&tcam->lock);
 		list_del(&vregion->tlist);
 		mutex_unlock(&tcam->lock);
-		cancel_delayed_work_sync(&vregion->rehash.dw);
+		if (cancel_delayed_work_sync(&vregion->rehash.dw) &&
+		    ctx->hints_priv)
+			ops->region_rehash_hints_put(ctx->hints_priv);
 	}
 	mlxsw_sp_acl_tcam_vgroup_vregion_detach(mlxsw_sp, vregion);
 	if (vregion->region2)
@@ -856,7 +877,7 @@
 			 */
 			return ERR_PTR(-EOPNOTSUPP);
 		}
-		vregion->ref_count++;
+		refcount_inc(&vregion->ref_count);
 		return vregion;
 	}
 
@@ -871,7 +892,7 @@
 mlxsw_sp_acl_tcam_vregion_put(struct mlxsw_sp *mlxsw_sp,
 			      struct mlxsw_sp_acl_tcam_vregion *vregion)
 {
-	if (--vregion->ref_count)
+	if (!refcount_dec_and_test(&vregion->ref_count))
 		return;
 	mlxsw_sp_acl_tcam_vregion_destroy(mlxsw_sp, vregion);
 }
@@ -924,7 +945,7 @@
 	INIT_LIST_HEAD(&vchunk->ventry_list);
 	vchunk->priority = priority;
 	vchunk->vgroup = vgroup;
-	vchunk->ref_count = 1;
+	refcount_set(&vchunk->ref_count, 1);
 
 	vregion = mlxsw_sp_acl_tcam_vregion_get(mlxsw_sp, vgroup,
 						priority, elusage);
@@ -1008,7 +1029,7 @@
 		if (WARN_ON(!mlxsw_afk_key_info_subset(vchunk->vregion->key_info,
 						       elusage)))
 			return ERR_PTR(-EINVAL);
-		vchunk->ref_count++;
+		refcount_inc(&vchunk->ref_count);
 		return vchunk;
 	}
 	return mlxsw_sp_acl_tcam_vchunk_create(mlxsw_sp, vgroup,
@@ -1019,7 +1040,7 @@
 mlxsw_sp_acl_tcam_vchunk_put(struct mlxsw_sp *mlxsw_sp,
 			     struct mlxsw_sp_acl_tcam_vchunk *vchunk)
 {
-	if (--vchunk->ref_count)
+	if (!refcount_dec_and_test(&vchunk->ref_count))
 		return;
 	mlxsw_sp_acl_tcam_vchunk_destroy(mlxsw_sp, vchunk);
 }
@@ -1153,8 +1174,14 @@
 				      struct mlxsw_sp_acl_tcam_ventry *ventry,
 				      bool *activity)
 {
-	return mlxsw_sp_acl_tcam_entry_activity_get(mlxsw_sp,
-						    ventry->entry, activity);
+	struct mlxsw_sp_acl_tcam_vregion *vregion = ventry->vchunk->vregion;
+	int err;
+
+	mutex_lock(&vregion->lock);
+	err = mlxsw_sp_acl_tcam_entry_activity_get(mlxsw_sp, ventry->entry,
+						   activity);
+	mutex_unlock(&vregion->lock);
+	return err;
 }
 
 static int
@@ -1188,6 +1215,8 @@
 {
 	struct mlxsw_sp_acl_tcam_chunk *new_chunk;
 
+	WARN_ON(vchunk->chunk2);
+
 	new_chunk = mlxsw_sp_acl_tcam_chunk_create(mlxsw_sp, vchunk, region);
 	if (IS_ERR(new_chunk))
 		return PTR_ERR(new_chunk);
@@ -1206,7 +1235,7 @@
 {
 	mlxsw_sp_acl_tcam_chunk_destroy(mlxsw_sp, vchunk->chunk2);
 	vchunk->chunk2 = NULL;
-	ctx->current_vchunk = NULL;
+	mlxsw_sp_acl_tcam_rehash_ctx_vchunk_reset(ctx);
 }
 
 static int
@@ -1229,6 +1258,9 @@
 		return 0;
 	}
 
+	if (list_empty(&vchunk->ventry_list))
+		goto out;
+
 	/* If the migration got interrupted, we have the ventry to start from
 	 * stored in context.
 	 */
@@ -1238,6 +1270,8 @@
 		ventry = list_first_entry(&vchunk->ventry_list,
 					  typeof(*ventry), list);
 
+	WARN_ON(ventry->vchunk != vchunk);
+
 	list_for_each_entry_from(ventry, &vchunk->ventry_list, list) {
 		/* During rollback, once we reach the ventry that failed
 		 * to migrate, we are done.
@@ -1278,6 +1312,7 @@
 		}
 	}
 
+out:
 	mlxsw_sp_acl_tcam_vchunk_migrate_end(mlxsw_sp, vchunk, ctx);
 	return 0;
 }
@@ -1291,6 +1326,9 @@
 	struct mlxsw_sp_acl_tcam_vchunk *vchunk;
 	int err;
 
+	if (list_empty(&vregion->vchunk_list))
+		return 0;
+
 	/* If the migration got interrupted, we have the vchunk
 	 * we are working on stored in context.
 	 */
@@ -1319,16 +1357,17 @@
 	int err, err2;
 
 	trace_mlxsw_sp_acl_tcam_vregion_migrate(mlxsw_sp, vregion);
-	mutex_lock(&vregion->lock);
 	err = mlxsw_sp_acl_tcam_vchunk_migrate_all(mlxsw_sp, vregion,
 						   ctx, credits);
 	if (err) {
+		if (ctx->this_is_rollback)
+			return err;
 		/* In case migration was not successful, we need to swap
 		 * so the original region pointer is assigned again
 		 * to vregion->region.
 		 */
 		swap(vregion->region, vregion->region2);
-		ctx->current_vchunk = NULL;
+		mlxsw_sp_acl_tcam_rehash_ctx_vchunk_reset(ctx);
 		ctx->this_is_rollback = true;
 		err2 = mlxsw_sp_acl_tcam_vchunk_migrate_all(mlxsw_sp, vregion,
 							    ctx, credits);
@@ -1339,7 +1378,6 @@
 			/* Let the rollback to be continued later on. */
 		}
 	}
-	mutex_unlock(&vregion->lock);
 	trace_mlxsw_sp_acl_tcam_vregion_migrate_end(mlxsw_sp, vregion);
 	return err;
 }
@@ -1388,6 +1426,7 @@
 
 	ctx->hints_priv = hints_priv;
 	ctx->this_is_rollback = false;
+	mlxsw_sp_acl_tcam_rehash_ctx_vchunk_reset(ctx);
 
 	return 0;
 
@@ -1440,7 +1479,8 @@
 	err = mlxsw_sp_acl_tcam_vregion_migrate(mlxsw_sp, vregion,
 						ctx, credits);
 	if (err) {
-		dev_err(mlxsw_sp->bus_info->dev, "Failed to migrate vregion\n");
+		dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to migrate vregion\n");
+		return;
 	}
 
 	if (*credits >= 0)
@@ -1548,19 +1588,11 @@
 	if (max_tcam_regions < max_regions)
 		max_regions = max_tcam_regions;
 
-	tcam->used_regions = bitmap_zalloc(max_regions, GFP_KERNEL);
-	if (!tcam->used_regions) {
-		err = -ENOMEM;
-		goto err_alloc_used_regions;
-	}
+	ida_init(&tcam->used_regions);
 	tcam->max_regions = max_regions;
 
 	max_groups = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_GROUPS);
-	tcam->used_groups = bitmap_zalloc(max_groups, GFP_KERNEL);
-	if (!tcam->used_groups) {
-		err = -ENOMEM;
-		goto err_alloc_used_groups;
-	}
+	ida_init(&tcam->used_groups);
 	tcam->max_groups = max_groups;
 	tcam->max_group_size = MLXSW_CORE_RES_GET(mlxsw_sp->core,
 						  ACL_MAX_GROUP_SIZE);
@@ -1574,10 +1606,8 @@
 	return 0;
 
 err_tcam_init:
-	bitmap_free(tcam->used_groups);
-err_alloc_used_groups:
-	bitmap_free(tcam->used_regions);
-err_alloc_used_regions:
+	ida_destroy(&tcam->used_groups);
+	ida_destroy(&tcam->used_regions);
 	mlxsw_sp_acl_tcam_rehash_params_unregister(mlxsw_sp);
 err_rehash_params_register:
 	mutex_destroy(&tcam->lock);
@@ -1590,8 +1620,8 @@
 	const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
 
 	ops->fini(mlxsw_sp, tcam->priv);
-	bitmap_free(tcam->used_groups);
-	bitmap_free(tcam->used_regions);
+	ida_destroy(&tcam->used_groups);
+	ida_destroy(&tcam->used_regions);
 	mlxsw_sp_acl_tcam_rehash_params_unregister(mlxsw_sp);
 	mutex_destroy(&tcam->lock);
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
@@ -6,15 +6,16 @@
 
 #include <linux/list.h>
 #include <linux/parman.h>
+#include <linux/idr.h>
 
 #include "reg.h"
 #include "spectrum.h"
 #include "core_acl_flex_keys.h"
 
 struct mlxsw_sp_acl_tcam {
-	unsigned long *used_regions; /* bit array */
+	struct ida used_regions;
 	unsigned int max_regions;
-	unsigned long *used_groups;  /* bit array */
+	struct ida used_groups;
 	unsigned int max_groups;
 	unsigned int max_group_size;
 	struct mutex lock; /* guards vregion list */
@@ -166,9 +167,9 @@
 };
 
 struct mlxsw_sp_acl_atcam_entry_ht_key {
-	char full_enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded
-								 * key.
-								 */
+	char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key, minus
+							    * delta bits.
+							    */
 	u8 erp_id;
 };
 
@@ -180,9 +181,6 @@
 	struct rhash_head ht_node;
 	struct list_head list; /* Member in entries_list */
 	struct mlxsw_sp_acl_atcam_entry_ht_key ht_key;
-	char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key,
-							    * minus delta bits.
-							    */
 	struct {
 		u16 start;
 		u8 mask;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
@@ -1607,8 +1607,8 @@
 int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core,
 			     unsigned int sb_index)
 {
+	u16 local_port, local_port_1, first_local_port, last_local_port;
 	struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
-	u16 local_port, local_port_1, last_local_port;
 	struct mlxsw_sp_sb_sr_occ_query_cb_ctx cb_ctx;
 	u8 masked_count, current_page = 0;
 	unsigned long cb_priv = 0;
@@ -1628,6 +1628,7 @@
 	masked_count = 0;
 	mlxsw_reg_sbsr_pack(sbsr_pl, false);
 	mlxsw_reg_sbsr_port_page_set(sbsr_pl, current_page);
+	first_local_port = current_page * MLXSW_REG_SBSR_NUM_PORTS_IN_PAGE;
 	last_local_port = current_page * MLXSW_REG_SBSR_NUM_PORTS_IN_PAGE +
 			  MLXSW_REG_SBSR_NUM_PORTS_IN_PAGE - 1;
 
@@ -1645,9 +1646,12 @@
 		if (local_port != MLXSW_PORT_CPU_PORT) {
 			/* Ingress quotas are not supported for the CPU port */
 			mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl,
-							     local_port, 1);
+							     local_port - first_local_port,
+							     1);
 		}
-		mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl, local_port, 1);
+		mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl,
+						    local_port - first_local_port,
+						    1);
 		for (i = 0; i < mlxsw_sp->sb_vals->pool_count; i++) {
 			err = mlxsw_sp_sb_pm_occ_query(mlxsw_sp, local_port, i,
 						       &bulk_list);
@@ -1684,7 +1688,7 @@
 			      unsigned int sb_index)
 {
 	struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
-	u16 local_port, last_local_port;
+	u16 local_port, first_local_port, last_local_port;
 	LIST_HEAD(bulk_list);
 	unsigned int masked_count;
 	u8 current_page = 0;
@@ -1702,6 +1706,7 @@
 	masked_count = 0;
 	mlxsw_reg_sbsr_pack(sbsr_pl, true);
 	mlxsw_reg_sbsr_port_page_set(sbsr_pl, current_page);
+	first_local_port = current_page * MLXSW_REG_SBSR_NUM_PORTS_IN_PAGE;
 	last_local_port = current_page * MLXSW_REG_SBSR_NUM_PORTS_IN_PAGE +
 			  MLXSW_REG_SBSR_NUM_PORTS_IN_PAGE - 1;
 
@@ -1719,9 +1724,12 @@
 		if (local_port != MLXSW_PORT_CPU_PORT) {
 			/* Ingress quotas are not supported for the CPU port */
 			mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl,
-							     local_port, 1);
+							     local_port - first_local_port,
+							     1);
 		}
-		mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl, local_port, 1);
+		mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl,
+						    local_port - first_local_port,
+						    1);
 		for (i = 0; i < mlxsw_sp->sb_vals->pool_count; i++) {
 			err = mlxsw_sp_sb_pm_occ_clear(mlxsw_sp, local_port, i,
 						       &bulk_list);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_ipip.c
@@ -471,11 +471,33 @@
 				    struct mlxsw_sp_ipip_entry *ipip_entry,
 				    struct netlink_ext_ack *extack)
 {
+	u32 new_kvdl_index, old_kvdl_index = ipip_entry->dip_kvdl_index;
+	struct in6_addr old_addr6 = ipip_entry->parms.daddr.addr6;
 	struct mlxsw_sp_ipip_parms new_parms;
+	int err;
 
 	new_parms = mlxsw_sp_ipip_netdev_parms_init_gre6(ipip_entry->ol_dev);
-	return mlxsw_sp_ipip_ol_netdev_change_gre(mlxsw_sp, ipip_entry,
-						  &new_parms, extack);
+
+	err = mlxsw_sp_ipv6_addr_kvdl_index_get(mlxsw_sp,
+						&new_parms.daddr.addr6,
+						&new_kvdl_index);
+	if (err)
+		return err;
+	ipip_entry->dip_kvdl_index = new_kvdl_index;
+
+	err = mlxsw_sp_ipip_ol_netdev_change_gre(mlxsw_sp, ipip_entry,
+						 &new_parms, extack);
+	if (err)
+		goto err_change_gre;
+
+	mlxsw_sp_ipv6_addr_put(mlxsw_sp, &old_addr6);
+
+	return 0;
+
+err_change_gre:
+	ipip_entry->dip_kvdl_index = old_kvdl_index;
+	mlxsw_sp_ipv6_addr_put(mlxsw_sp, &new_parms.daddr.addr6);
+	return err;
 }
 
 static int
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c
@@ -1003,10 +1003,10 @@
 	mr->mr_ops->route_stats(mlxsw_sp, mr_route->route_priv, &packets,
 				&bytes);
 
-	if (mr_route->mfc->mfc_un.res.pkt != packets)
-		mr_route->mfc->mfc_un.res.lastuse = jiffies;
-	mr_route->mfc->mfc_un.res.pkt = packets;
-	mr_route->mfc->mfc_un.res.bytes = bytes;
+	if (atomic_long_read(&mr_route->mfc->mfc_un.res.pkt) != packets)
+		WRITE_ONCE(mr_route->mfc->mfc_un.res.lastuse, jiffies);
+	atomic_long_set(&mr_route->mfc->mfc_un.res.pkt, packets);
+	atomic_long_set(&mr_route->mfc->mfc_un.res.bytes, bytes);
 }
 
 static void mlxsw_sp_mr_stats_update(struct work_struct *work)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
@@ -16,6 +16,7 @@
 #include "spectrum.h"
 #include "spectrum_ptp.h"
 #include "core.h"
+#include "txheader.h"
 
 #define MLXSW_SP1_PTP_CLOCK_CYCLES_SHIFT	29
 #define MLXSW_SP1_PTP_CLOCK_FREQ_KHZ		156257 /* 6.4nSec */
@@ -1684,6 +1685,12 @@
 				 struct sk_buff *skb,
 				 const struct mlxsw_tx_info *tx_info)
 {
+	if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) {
+		this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
+		dev_kfree_skb_any(skb);
+		return -ENOMEM;
+	}
+
 	mlxsw_sp_txhdr_construct(skb, tx_info);
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -501,7 +501,7 @@
 
 struct mlxsw_sp_lpm_tree {
 	u8 id; /* tree ID */
-	unsigned int ref_count;
+	refcount_t ref_count;
 	enum mlxsw_sp_l3proto proto;
 	unsigned long prefix_ref_count[MLXSW_SP_PREFIX_COUNT];
 	struct mlxsw_sp_prefix_usage prefix_usage;
@@ -578,7 +578,7 @@
 
 	for (i = 0; i < mlxsw_sp->router->lpm.tree_count; i++) {
 		lpm_tree = &mlxsw_sp->router->lpm.trees[i];
-		if (lpm_tree->ref_count == 0)
+		if (refcount_read(&lpm_tree->ref_count) == 0)
 			return lpm_tree;
 	}
 	return NULL;
@@ -654,7 +654,7 @@
 	       sizeof(lpm_tree->prefix_usage));
 	memset(&lpm_tree->prefix_ref_count, 0,
 	       sizeof(lpm_tree->prefix_ref_count));
-	lpm_tree->ref_count = 1;
+	refcount_set(&lpm_tree->ref_count, 1);
 	return lpm_tree;
 
 err_left_struct_set:
@@ -678,7 +678,7 @@
 
 	for (i = 0; i < mlxsw_sp->router->lpm.tree_count; i++) {
 		lpm_tree = &mlxsw_sp->router->lpm.trees[i];
-		if (lpm_tree->ref_count != 0 &&
+		if (refcount_read(&lpm_tree->ref_count) &&
 		    lpm_tree->proto == proto &&
 		    mlxsw_sp_prefix_usage_eq(&lpm_tree->prefix_usage,
 					     prefix_usage)) {
@@ -691,14 +691,15 @@
 
 static void mlxsw_sp_lpm_tree_hold(struct mlxsw_sp_lpm_tree *lpm_tree)
 {
-	lpm_tree->ref_count++;
+	refcount_inc(&lpm_tree->ref_count);
 }
 
 static void mlxsw_sp_lpm_tree_put(struct mlxsw_sp *mlxsw_sp,
 				  struct mlxsw_sp_lpm_tree *lpm_tree)
 {
-	if (--lpm_tree->ref_count == 0)
-		mlxsw_sp_lpm_tree_destroy(mlxsw_sp, lpm_tree);
+	if (!refcount_dec_and_test(&lpm_tree->ref_count))
+		return;
+	mlxsw_sp_lpm_tree_destroy(mlxsw_sp, lpm_tree);
 }
 
 #define MLXSW_SP_LPM_TREE_MIN 1 /* tree 0 is reserved */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
@@ -423,8 +423,7 @@
 
 	parms = mlxsw_sp_ipip_netdev_parms4(to_dev);
 	ip_tunnel_init_flow(&fl4, parms.iph.protocol, *daddrp, *saddrp,
-			    0, 0, dev_net(to_dev), parms.link, tun->fwmark, 0,
-			    0);
+			    0, 0, tun->net, parms.link, tun->fwmark, 0, 0);
 
 	rt = ip_route_output_key(tun->net, &fl4);
 	if (IS_ERR(rt))
@@ -539,7 +538,7 @@
 	if (!dst || dst->error)
 		goto out;
 
-	rt6 = container_of(dst, struct rt6_info, dst);
+	rt6 = dst_rt6_info(dst);
 
 	dev = dst->dev;
 	*saddrp = fl6.saddr;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
@@ -61,7 +61,7 @@
 	struct mlxsw_sp_bridge_device *bridge_device;
 	struct list_head list;
 	struct list_head vlans_list;
-	unsigned int ref_count;
+	refcount_t ref_count;
 	u8 stp_state;
 	unsigned long flags;
 	bool mrouter;
@@ -495,7 +495,7 @@
 			     BR_MCAST_FLOOD;
 	INIT_LIST_HEAD(&bridge_port->vlans_list);
 	list_add(&bridge_port->list, &bridge_device->ports_list);
-	bridge_port->ref_count = 1;
+	refcount_set(&bridge_port->ref_count, 1);
 
 	err = switchdev_bridge_port_offload(brport_dev, mlxsw_sp_port->dev,
 					    NULL, NULL, NULL, false, extack);
@@ -531,7 +531,7 @@
 
 	bridge_port = mlxsw_sp_bridge_port_find(bridge, brport_dev);
 	if (bridge_port) {
-		bridge_port->ref_count++;
+		refcount_inc(&bridge_port->ref_count);
 		return bridge_port;
 	}
 
@@ -558,7 +558,7 @@
 {
 	struct mlxsw_sp_bridge_device *bridge_device;
 
-	if (--bridge_port->ref_count != 0)
+	if (!refcount_dec_and_test(&bridge_port->ref_count))
 		return;
 	bridge_device = bridge_port->bridge_device;
 	mlxsw_sp_bridge_port_destroy(bridge_port);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/micrel/ks8851.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/micrel/ks8851.h
@@ -368,7 +368,6 @@
  * @rdfifo: FIFO read callback
  * @wrfifo: FIFO write callback
  * @start_xmit: start_xmit() implementation callback
- * @rx_skb: rx_skb() implementation callback
  * @flush_tx_work: flush_tx_work() implementation callback
  *
  * The @statelock is used to protect information in the structure which may
@@ -423,8 +422,6 @@
 					  struct sk_buff *txp, bool irq);
 	netdev_tx_t		(*start_xmit)(struct sk_buff *skb,
 					      struct net_device *dev);
-	void			(*rx_skb)(struct ks8851_net *ks,
-					  struct sk_buff *skb);
 	void			(*flush_tx_work)(struct ks8851_net *ks);
 };
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/micrel/ks8851_common.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/micrel/ks8851_common.c
@@ -232,24 +232,15 @@
 }
 
 /**
- * ks8851_rx_skb - receive skbuff
- * @ks: The device state.
- * @skb: The skbuff
- */
-static void ks8851_rx_skb(struct ks8851_net *ks, struct sk_buff *skb)
-{
-	ks->rx_skb(ks, skb);
-}
-
-/**
  * ks8851_rx_pkts - receive packets from the host
  * @ks: The device information.
+ * @rxq: Queue of packets received in this function.
  *
  * This is called from the IRQ work queue when the system detects that there
  * are packets in the receive queue. Find out how many packets there are and
  * read them from the FIFO.
  */
-static void ks8851_rx_pkts(struct ks8851_net *ks)
+static void ks8851_rx_pkts(struct ks8851_net *ks, struct sk_buff_head *rxq)
 {
 	struct sk_buff *skb;
 	unsigned rxfc;
@@ -309,7 +300,7 @@
 					ks8851_dbg_dumpkkt(ks, rxpkt);
 
 				skb->protocol = eth_type_trans(skb, ks->netdev);
-				ks8851_rx_skb(ks, skb);
+				__skb_queue_tail(rxq, skb);
 
 				ks->netdev->stats.rx_packets++;
 				ks->netdev->stats.rx_bytes += rxlen;
@@ -336,63 +327,50 @@
 static irqreturn_t ks8851_irq(int irq, void *_ks)
 {
 	struct ks8851_net *ks = _ks;
-	unsigned handled = 0;
+	struct sk_buff_head rxq;
 	unsigned long flags;
 	unsigned int status;
+	struct sk_buff *skb;
 
 	ks8851_lock(ks, &flags);
 
 	status = ks8851_rdreg16(ks, KS_ISR);
+	ks8851_wrreg16(ks, KS_ISR, status);
 
 	netif_dbg(ks, intr, ks->netdev,
 		  "%s: status 0x%04x\n", __func__, status);
 
-	if (status & IRQ_LCI)
-		handled |= IRQ_LCI;
-
 	if (status & IRQ_LDI) {
 		u16 pmecr = ks8851_rdreg16(ks, KS_PMECR);
 		pmecr &= ~PMECR_WKEVT_MASK;
 		ks8851_wrreg16(ks, KS_PMECR, pmecr | PMECR_WKEVT_LINK);
-
-		handled |= IRQ_LDI;
 	}
 
-	if (status & IRQ_RXPSI)
-		handled |= IRQ_RXPSI;
-
 	if (status & IRQ_TXI) {
 		unsigned short tx_space = ks8851_rdreg16(ks, KS_TXMIR);
 
 		netif_dbg(ks, intr, ks->netdev,
 			  "%s: txspace %d\n", __func__, tx_space);
 
-		spin_lock(&ks->statelock);
+		spin_lock_bh(&ks->statelock);
 		ks->tx_space = tx_space;
 		if (netif_queue_stopped(ks->netdev))
 			netif_wake_queue(ks->netdev);
-		spin_unlock(&ks->statelock);
-
-		handled |= IRQ_TXI;
+		spin_unlock_bh(&ks->statelock);
 	}
 
-	if (status & IRQ_RXI)
-		handled |= IRQ_RXI;
-
 	if (status & IRQ_SPIBEI) {
 		netdev_err(ks->netdev, "%s: spi bus error\n", __func__);
-		handled |= IRQ_SPIBEI;
 	}
 
-	ks8851_wrreg16(ks, KS_ISR, handled);
-
 	if (status & IRQ_RXI) {
 		/* the datasheet says to disable the rx interrupt during
 		 * packet read-out, however we're masking the interrupt
 		 * from the device so do not bother masking just the RX
 		 * from the device. */
 
-		ks8851_rx_pkts(ks);
+		__skb_queue_head_init(&rxq);
+		ks8851_rx_pkts(ks, &rxq);
 	}
 
 	/* if something stopped the rx process, probably due to wanting
@@ -416,6 +394,10 @@
 	if (status & IRQ_LCI)
 		mii_check_link(&ks->mii);
 
+	if (status & IRQ_RXI)
+		while ((skb = __skb_dequeue(&rxq)))
+			netif_rx(skb);
+
 	return IRQ_HANDLED;
 }
 
@@ -500,6 +482,7 @@
 	ks8851_wrreg16(ks, KS_IER, ks->rc_ier);
 
 	ks->queued_len = 0;
+	ks->tx_space = ks8851_rdreg16(ks, KS_TXMIR);
 	netif_start_queue(ks->netdev);
 
 	netif_dbg(ks, ifup, ks->netdev, "network device up\n");
@@ -653,14 +636,14 @@
 
 	/* schedule work to do the actual set of the data if needed */
 
-	spin_lock(&ks->statelock);
+	spin_lock_bh(&ks->statelock);
 
 	if (memcmp(&rxctrl, &ks->rxctrl, sizeof(rxctrl)) != 0) {
 		memcpy(&ks->rxctrl, &rxctrl, sizeof(ks->rxctrl));
 		schedule_work(&ks->rxctrl_work);
 	}
 
-	spin_unlock(&ks->statelock);
+	spin_unlock_bh(&ks->statelock);
 }
 
 static int ks8851_set_mac_address(struct net_device *dev, void *addr)
@@ -1119,7 +1102,6 @@
 	int ret;
 
 	ks->netdev = netdev;
-	ks->tx_space = 6144;
 
 	ks->gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
 	ret = PTR_ERR_OR_ZERO(ks->gpio);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/micrel/ks8851_par.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/micrel/ks8851_par.c
@@ -210,16 +210,6 @@
 	iowrite16_rep(ksp->hw_addr, txp->data, len / 2);
 }
 
-/**
- * ks8851_rx_skb_par - receive skbuff
- * @ks: The device state.
- * @skb: The skbuff
- */
-static void ks8851_rx_skb_par(struct ks8851_net *ks, struct sk_buff *skb)
-{
-	netif_rx(skb);
-}
-
 static unsigned int ks8851_rdreg16_par_txqcr(struct ks8851_net *ks)
 {
 	return ks8851_rdreg16_par(ks, KS_TXQCR);
@@ -298,7 +288,6 @@
 	ks->rdfifo = ks8851_rdfifo_par;
 	ks->wrfifo = ks8851_wrfifo_par;
 	ks->start_xmit = ks8851_start_xmit_par;
-	ks->rx_skb = ks8851_rx_skb_par;
 
 #define STD_IRQ (IRQ_LCI |	/* Link Change */	\
 		 IRQ_RXI |	/* RX done */		\
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/micrel/ks8851_spi.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/micrel/ks8851_spi.c
@@ -299,16 +299,6 @@
 }
 
 /**
- * ks8851_rx_skb_spi - receive skbuff
- * @ks: The device state
- * @skb: The skbuff
- */
-static void ks8851_rx_skb_spi(struct ks8851_net *ks, struct sk_buff *skb)
-{
-	netif_rx(skb);
-}
-
-/**
  * ks8851_tx_work - process tx packet(s)
  * @work: The work strucutre what was scheduled.
  *
@@ -350,10 +340,10 @@
 
 	tx_space = ks8851_rdreg16_spi(ks, KS_TXMIR);
 
-	spin_lock(&ks->statelock);
+	spin_lock_bh(&ks->statelock);
 	ks->queued_len -= dequeued_len;
 	ks->tx_space = tx_space;
-	spin_unlock(&ks->statelock);
+	spin_unlock_bh(&ks->statelock);
 
 	ks8851_unlock_spi(ks, &flags);
 }
@@ -435,7 +425,6 @@
 	ks->rdfifo = ks8851_rdfifo_spi;
 	ks->wrfifo = ks8851_wrfifo_spi;
 	ks->start_xmit = ks8851_start_xmit_spi;
-	ks->rx_skb = ks8851_rx_skb_spi;
 	ks->flush_tx_work = ks8851_flush_tx_work_spi;
 
 #define STD_IRQ (IRQ_LCI |	/* Link Change */	\
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/microchip/lan743x_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/microchip/lan743x_ethtool.c
@@ -1148,8 +1148,12 @@
 	if (netdev->phydev)
 		phy_ethtool_get_wol(netdev->phydev, wol);
 
-	wol->supported |= WAKE_BCAST | WAKE_UCAST | WAKE_MCAST |
-		WAKE_MAGIC | WAKE_PHY | WAKE_ARP;
+	if (wol->supported != adapter->phy_wol_supported)
+		netif_warn(adapter, drv, adapter->netdev,
+			   "PHY changed its supported WOL! old=%x, new=%x\n",
+			   adapter->phy_wol_supported, wol->supported);
+
+	wol->supported |= MAC_SUPPORTED_WAKES;
 
 	if (adapter->is_pci11x1x)
 		wol->supported |= WAKE_MAGICSECURE;
@@ -1164,7 +1168,39 @@
 {
 	struct lan743x_adapter *adapter = netdev_priv(netdev);
 
+	/* WAKE_MAGICSEGURE is a modifier of and only valid together with
+	 * WAKE_MAGIC
+	 */
+	if ((wol->wolopts & WAKE_MAGICSECURE) && !(wol->wolopts & WAKE_MAGIC))
+		return -EINVAL;
+
+	if (netdev->phydev) {
+		struct ethtool_wolinfo phy_wol;
+		int ret;
+
+		phy_wol.wolopts = wol->wolopts & adapter->phy_wol_supported;
+
+		/* If WAKE_MAGICSECURE was requested, filter out WAKE_MAGIC
+		 * for PHYs that do not support WAKE_MAGICSECURE
+		 */
+		if (wol->wolopts & WAKE_MAGICSECURE &&
+		    !(adapter->phy_wol_supported & WAKE_MAGICSECURE))
+			phy_wol.wolopts &= ~WAKE_MAGIC;
+
+		ret = phy_ethtool_set_wol(netdev->phydev, &phy_wol);
+		if (ret && (ret != -EOPNOTSUPP))
+			return ret;
+
+		if (ret == -EOPNOTSUPP)
+			adapter->phy_wolopts = 0;
+		else
+			adapter->phy_wolopts = phy_wol.wolopts;
+	} else {
+		adapter->phy_wolopts = 0;
+	}
+
 	adapter->wolopts = 0;
+	wol->wolopts &= ~adapter->phy_wolopts;
 	if (wol->wolopts & WAKE_UCAST)
 		adapter->wolopts |= WAKE_UCAST;
 	if (wol->wolopts & WAKE_MCAST)
@@ -1185,10 +1221,10 @@
 		memset(adapter->sopass, 0, sizeof(u8) * SOPASS_MAX);
 	}
 
+	wol->wolopts = adapter->wolopts | adapter->phy_wolopts;
 	device_set_wakeup_enable(&adapter->pdev->dev, (bool)wol->wolopts);
 
-	return netdev->phydev ? phy_ethtool_set_wol(netdev->phydev, wol)
-			: -ENETDOWN;
+	return 0;
 }
 #endif /* CONFIG_PM */
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/microchip/lan743x_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/microchip/lan743x_main.c
@@ -25,6 +25,8 @@
 #define PCS_POWER_STATE_DOWN	0x6
 #define PCS_POWER_STATE_UP	0x4
 
+#define RFE_RD_FIFO_TH_3_DWORDS	0x3
+
 static void pci11x1x_strap_get_status(struct lan743x_adapter *adapter)
 {
 	u32 chip_rev;
@@ -3109,6 +3111,17 @@
 		if (ret)
 			goto close_tx;
 	}
+
+#ifdef CONFIG_PM
+	if (adapter->netdev->phydev) {
+		struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
+
+		phy_ethtool_get_wol(netdev->phydev, &wol);
+		adapter->phy_wol_supported = wol.supported;
+		adapter->phy_wolopts = wol.wolopts;
+	}
+#endif
+
 	return 0;
 
 close_tx:
@@ -3272,6 +3285,21 @@
 	lan743x_pci_cleanup(adapter);
 }
 
+static void pci11x1x_set_rfe_rd_fifo_threshold(struct lan743x_adapter *adapter)
+{
+	u16 rev = adapter->csr.id_rev & ID_REV_CHIP_REV_MASK_;
+
+	if (rev == ID_REV_CHIP_REV_PCI11X1X_B0_) {
+		u32 misc_ctl;
+
+		misc_ctl = lan743x_csr_read(adapter, MISC_CTL_0);
+		misc_ctl &= ~MISC_CTL_0_RFE_READ_FIFO_MASK_;
+		misc_ctl |= FIELD_PREP(MISC_CTL_0_RFE_READ_FIFO_MASK_,
+				       RFE_RD_FIFO_TH_3_DWORDS);
+		lan743x_csr_write(adapter, MISC_CTL_0, misc_ctl);
+	}
+}
+
 static int lan743x_hardware_init(struct lan743x_adapter *adapter,
 				 struct pci_dev *pdev)
 {
@@ -3287,6 +3315,7 @@
 		pci11x1x_strap_get_status(adapter);
 		spin_lock_init(&adapter->eth_syslock_spinlock);
 		mutex_init(&adapter->sgmii_rw_lock);
+		pci11x1x_set_rfe_rd_fifo_threshold(adapter);
 	} else {
 		adapter->max_tx_channels = LAN743X_MAX_TX_CHANNELS;
 		adapter->used_tx_channels = LAN743X_USED_TX_CHANNELS;
@@ -3550,7 +3579,7 @@
 
 	/* clear wake settings */
 	pmtctl = lan743x_csr_read(adapter, PMT_CTL);
-	pmtctl |= PMT_CTL_WUPS_MASK_;
+	pmtctl |= PMT_CTL_WUPS_MASK_ | PMT_CTL_RES_CLR_WKP_MASK_;
 	pmtctl &= ~(PMT_CTL_GPIO_WAKEUP_EN_ | PMT_CTL_EEE_WAKEUP_EN_ |
 		PMT_CTL_WOL_EN_ | PMT_CTL_MAC_D3_RX_CLK_OVR_ |
 		PMT_CTL_RX_FCT_RFE_D3_CLK_OVR_ | PMT_CTL_ETH_PHY_WAKE_EN_);
@@ -3562,10 +3591,9 @@
 
 	pmtctl |= PMT_CTL_ETH_PHY_D3_COLD_OVR_ | PMT_CTL_ETH_PHY_D3_OVR_;
 
-	if (adapter->wolopts & WAKE_PHY) {
-		pmtctl |= PMT_CTL_ETH_PHY_EDPD_PLL_CTL_;
+	if (adapter->phy_wolopts)
 		pmtctl |= PMT_CTL_ETH_PHY_WAKE_EN_;
-	}
+
 	if (adapter->wolopts & WAKE_MAGIC) {
 		wucsr |= MAC_WUCSR_MPEN_;
 		macrx |= MAC_RX_RXEN_;
@@ -3661,7 +3689,7 @@
 	lan743x_csr_write(adapter, MAC_WUCSR2, 0);
 	lan743x_csr_write(adapter, MAC_WK_SRC, 0xFFFFFFFF);
 
-	if (adapter->wolopts)
+	if (adapter->wolopts || adapter->phy_wolopts)
 		lan743x_pm_set_wol(adapter);
 
 	if (adapter->is_pci11x1x) {
@@ -3685,6 +3713,7 @@
 	struct pci_dev *pdev = to_pci_dev(dev);
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct lan743x_adapter *adapter = netdev_priv(netdev);
+	u32 data;
 	int ret;
 
 	pci_set_power_state(pdev, PCI_D0);
@@ -3703,6 +3732,30 @@
 		return ret;
 	}
 
+	ret = lan743x_csr_read(adapter, MAC_WK_SRC);
+	netif_dbg(adapter, drv, adapter->netdev,
+		  "Wakeup source : 0x%08X\n", ret);
+
+	/* Clear the wol configuration and status bits. Note that
+	 * the status bits are "Write One to Clear (W1C)"
+	 */
+	data = MAC_WUCSR_EEE_TX_WAKE_ | MAC_WUCSR_EEE_RX_WAKE_ |
+	       MAC_WUCSR_RFE_WAKE_FR_ | MAC_WUCSR_PFDA_FR_ | MAC_WUCSR_WUFR_ |
+	       MAC_WUCSR_MPR_ | MAC_WUCSR_BCAST_FR_;
+	lan743x_csr_write(adapter, MAC_WUCSR, data);
+
+	data = MAC_WUCSR2_NS_RCD_ | MAC_WUCSR2_ARP_RCD_ |
+	       MAC_WUCSR2_IPV6_TCPSYN_RCD_ | MAC_WUCSR2_IPV4_TCPSYN_RCD_;
+	lan743x_csr_write(adapter, MAC_WUCSR2, data);
+
+	data = MAC_WK_SRC_ETH_PHY_WK_ | MAC_WK_SRC_IPV6_TCPSYN_RCD_WK_ |
+	       MAC_WK_SRC_IPV4_TCPSYN_RCD_WK_ | MAC_WK_SRC_EEE_TX_WK_ |
+	       MAC_WK_SRC_EEE_RX_WK_ | MAC_WK_SRC_RFE_FR_WK_ |
+	       MAC_WK_SRC_PFDA_FR_WK_ | MAC_WK_SRC_MP_FR_WK_ |
+	       MAC_WK_SRC_BCAST_FR_WK_ | MAC_WK_SRC_WU_FR_WK_ |
+	       MAC_WK_SRC_WK_FR_SAVED_;
+	lan743x_csr_write(adapter, MAC_WK_SRC, data);
+
 	/* open netdev when netdev is at running state while resume.
 	 * For instance, it is true when system wakesup after pm-suspend
 	 * However, it is false when system wakes up after suspend GUI menu
@@ -3711,9 +3764,6 @@
 		lan743x_netdev_open(netdev);
 
 	netif_device_attach(netdev);
-	ret = lan743x_csr_read(adapter, MAC_WK_SRC);
-	netif_info(adapter, drv, adapter->netdev,
-		   "Wakeup source : 0x%08X\n", ret);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/microchip/lan743x_main.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/microchip/lan743x_main.h
@@ -26,6 +26,7 @@
 #define ID_REV_CHIP_REV_MASK_		(0x0000FFFF)
 #define ID_REV_CHIP_REV_A0_		(0x00000000)
 #define ID_REV_CHIP_REV_B0_		(0x00000010)
+#define ID_REV_CHIP_REV_PCI11X1X_B0_	(0x000000B0)
 
 #define FPGA_REV			(0x04)
 #define FPGA_REV_GET_MINOR_(fpga_rev)	(((fpga_rev) >> 8) & 0x000000FF)
@@ -60,6 +61,7 @@
 #define PMT_CTL_RX_FCT_RFE_D3_CLK_OVR_		BIT(18)
 #define PMT_CTL_GPIO_WAKEUP_EN_			BIT(15)
 #define PMT_CTL_EEE_WAKEUP_EN_			BIT(13)
+#define PMT_CTL_RES_CLR_WKP_MASK_		GENMASK(9, 8)
 #define PMT_CTL_READY_				BIT(7)
 #define PMT_CTL_ETH_PHY_RST_			BIT(4)
 #define PMT_CTL_WOL_EN_				BIT(3)
@@ -226,12 +228,31 @@
 #define MAC_WUCSR				(0x140)
 #define MAC_MP_SO_EN_				BIT(21)
 #define MAC_WUCSR_RFE_WAKE_EN_			BIT(14)
+#define MAC_WUCSR_EEE_TX_WAKE_			BIT(13)
+#define MAC_WUCSR_EEE_RX_WAKE_			BIT(11)
+#define MAC_WUCSR_RFE_WAKE_FR_			BIT(9)
+#define MAC_WUCSR_PFDA_FR_			BIT(7)
+#define MAC_WUCSR_WUFR_				BIT(6)
+#define MAC_WUCSR_MPR_				BIT(5)
+#define MAC_WUCSR_BCAST_FR_			BIT(4)
 #define MAC_WUCSR_PFDA_EN_			BIT(3)
 #define MAC_WUCSR_WAKE_EN_			BIT(2)
 #define MAC_WUCSR_MPEN_				BIT(1)
 #define MAC_WUCSR_BCST_EN_			BIT(0)
 
 #define MAC_WK_SRC				(0x144)
+#define MAC_WK_SRC_ETH_PHY_WK_			BIT(17)
+#define MAC_WK_SRC_IPV6_TCPSYN_RCD_WK_		BIT(16)
+#define MAC_WK_SRC_IPV4_TCPSYN_RCD_WK_		BIT(15)
+#define MAC_WK_SRC_EEE_TX_WK_			BIT(14)
+#define MAC_WK_SRC_EEE_RX_WK_			BIT(13)
+#define MAC_WK_SRC_RFE_FR_WK_			BIT(12)
+#define MAC_WK_SRC_PFDA_FR_WK_			BIT(11)
+#define MAC_WK_SRC_MP_FR_WK_			BIT(10)
+#define MAC_WK_SRC_BCAST_FR_WK_			BIT(9)
+#define MAC_WK_SRC_WU_FR_WK_			BIT(8)
+#define MAC_WK_SRC_WK_FR_SAVED_			BIT(7)
+
 #define MAC_MP_SO_HI				(0x148)
 #define MAC_MP_SO_LO				(0x14C)
 
@@ -294,6 +315,10 @@
 #define RFE_INDX(index)			(0x580 + (index << 2))
 
 #define MAC_WUCSR2			(0x600)
+#define MAC_WUCSR2_NS_RCD_		BIT(7)
+#define MAC_WUCSR2_ARP_RCD_		BIT(6)
+#define MAC_WUCSR2_IPV6_TCPSYN_RCD_	BIT(5)
+#define MAC_WUCSR2_IPV4_TCPSYN_RCD_	BIT(4)
 
 #define SGMII_ACC			(0x720)
 #define SGMII_ACC_SGMII_BZY_		BIT(31)
@@ -311,6 +336,9 @@
 #define SGMII_CTL_LINK_STATUS_SOURCE_	BIT(8)
 #define SGMII_CTL_SGMII_POWER_DN_	BIT(1)
 
+#define MISC_CTL_0			(0x920)
+#define MISC_CTL_0_RFE_READ_FIFO_MASK_	GENMASK(6, 4)
+
 /* Vendor Specific SGMII MMD details */
 #define SR_VSMMD_PCS_ID1		0x0004
 #define SR_VSMMD_PCS_ID2		0x0005
@@ -1014,6 +1042,8 @@
 	LINK_2500_SLAVE
 };
 
+#define MAC_SUPPORTED_WAKES  (WAKE_BCAST | WAKE_UCAST | WAKE_MCAST | \
+			      WAKE_MAGIC | WAKE_ARP)
 struct lan743x_adapter {
 	struct net_device       *netdev;
 	struct mii_bus		*mdiobus;
@@ -1021,6 +1051,8 @@
 #ifdef CONFIG_PM
 	u32			wolopts;
 	u8			sopass[SOPASS_MAX];
+	u32			phy_wolopts;
+	u32			phy_wol_supported;
 #endif
 	struct pci_dev		*pdev;
 	struct lan743x_csr      csr;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/microchip/lan966x/lan966x_main.c
@@ -474,14 +474,14 @@
 	    cfg->source != HWTSTAMP_SOURCE_PHYLIB)
 		return -EOPNOTSUPP;
 
+	if (cfg->source == HWTSTAMP_SOURCE_NETDEV && !port->lan966x->ptp)
+		return -EOPNOTSUPP;
+
 	err = lan966x_ptp_setup_traps(port, cfg);
 	if (err)
 		return err;
 
 	if (cfg->source == HWTSTAMP_SOURCE_NETDEV) {
-		if (!port->lan966x->ptp)
-			return -EOPNOTSUPP;
-
 		err = lan966x_ptp_hwtstamp_set(port, cfg, extack);
 		if (err) {
 			lan966x_ptp_del_traps(port);
@@ -1087,8 +1087,6 @@
 	platform_set_drvdata(pdev, lan966x);
 	lan966x->dev = &pdev->dev;
 
-	lan966x->debugfs_root = debugfs_create_dir("lan966x", NULL);
-
 	if (!device_get_mac_address(&pdev->dev, mac_addr)) {
 		ether_addr_copy(lan966x->base_mac, mac_addr);
 	} else {
@@ -1179,6 +1177,8 @@
 		return dev_err_probe(&pdev->dev, -ENODEV,
 				     "no ethernet-ports child found\n");
 
+	lan966x->debugfs_root = debugfs_create_dir("lan966x", NULL);
+
 	/* init switch */
 	lan966x_init(lan966x);
 	lan966x_stats_init(lan966x);
@@ -1257,6 +1257,8 @@
 	destroy_workqueue(lan966x->stats_queue);
 	mutex_destroy(&lan966x->stats_lock);
 
+	debugfs_remove_recursive(lan966x->debugfs_root);
+
 	return err;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -693,12 +693,11 @@
 	err = -ENXIO;
 	if (sparx5->fdma_irq >= 0) {
 		if (GCB_CHIP_ID_REV_ID_GET(sparx5->chip_id) > 0)
-			err = devm_request_threaded_irq(sparx5->dev,
-							sparx5->fdma_irq,
-							NULL,
-							sparx5_fdma_handler,
-							IRQF_ONESHOT,
-							"sparx5-fdma", sparx5);
+			err = devm_request_irq(sparx5->dev,
+					       sparx5->fdma_irq,
+					       sparx5_fdma_handler,
+					       0,
+					       "sparx5-fdma", sparx5);
 		if (!err)
 			err = sparx5_fdma_start(sparx5);
 		if (err)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/microchip/sparx5/sparx5_packet.c
@@ -45,8 +45,12 @@
 	fwd = (fwd >> 5);
 	info->src_port = FIELD_GET(GENMASK(7, 1), fwd);
 
+	/*
+	 * Bit 270-271 are occasionally unexpectedly set by the hardware,
+	 * clear bits before extracting timestamp
+	 */
 	info->timestamp =
-		((u64)xtr_hdr[2] << 24) |
+		((u64)(xtr_hdr[2] & GENMASK(5, 0)) << 24) |
 		((u64)xtr_hdr[3] << 16) |
 		((u64)xtr_hdr[4] <<  8) |
 		((u64)xtr_hdr[5] <<  0);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -731,7 +731,7 @@
 	bool sgmii = false, inband_aneg = false;
 	int err;
 
-	if (port->conf.inband) {
+	if (conf->inband) {
 		if (conf->portmode == PHY_INTERFACE_MODE_SGMII ||
 		    conf->portmode == PHY_INTERFACE_MODE_QSGMII)
 			inband_aneg = true; /* Cisco-SGMII in-band-aneg */
@@ -948,7 +948,7 @@
 	if (err)
 		return -EINVAL;
 
-	if (port->conf.inband) {
+	if (conf->inband) {
 		/* Enable/disable 1G counters in ASM */
 		spx5_rmw(ASM_PORT_CFG_CSC_STAT_DIS_SET(high_speed_dev),
 			 ASM_PORT_CFG_CSC_STAT_DIS,
@@ -1119,7 +1119,7 @@
 	spx5_inst_rmw(DEV10G_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
 		      DEV10G_MAC_MAXLEN_CFG_MAX_LEN,
 		      devinst,
-		      DEV10G_MAC_ENA_CFG(0));
+		      DEV10G_MAC_MAXLEN_CFG(0));
 
 	/* Handle Signal Detect in 10G PCS */
 	spx5_inst_wr(PCS10G_BR_PCS_SD_CFG_SD_POL_SET(sd_pol) |
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
@@ -36,6 +36,27 @@
 	u16 l3_proto; /* protocol specified in the template */
 };
 
+/* SparX-5 VCAP fragment types:
+ * 0 = no fragment, 1 = initial fragment,
+ * 2 = suspicious fragment, 3 = valid follow-up fragment
+ */
+enum {                   /* key / mask */
+	FRAG_NOT   = 0x03, /* 0 / 3 */
+	FRAG_SOME  = 0x11, /* 1 / 1 */
+	FRAG_FIRST = 0x13, /* 1 / 3 */
+	FRAG_LATER = 0x33, /* 3 / 3 */
+	FRAG_INVAL = 0xff, /* invalid */
+};
+
+/* Flower fragment flag to VCAP fragment type mapping */
+static const u8 sparx5_vcap_frag_map[4][4] = {		  /* is_frag */
+	{ FRAG_INVAL, FRAG_INVAL, FRAG_INVAL, FRAG_FIRST }, /* 0/0 */
+	{ FRAG_NOT,   FRAG_NOT,   FRAG_INVAL, FRAG_INVAL }, /* 0/1 */
+	{ FRAG_INVAL, FRAG_INVAL, FRAG_INVAL, FRAG_INVAL }, /* 1/0 */
+	{ FRAG_SOME,  FRAG_LATER, FRAG_INVAL, FRAG_FIRST }  /* 1/1 */
+	/* 0/0	      0/1	  1/0	      1/1 <-- first_frag */
+};
+
 static int
 sparx5_tc_flower_es0_tpid(struct vcap_tc_flower_parse_usage *st)
 {
@@ -145,29 +166,27 @@
 	flow_rule_match_control(st->frule, &mt);
 
 	if (mt.mask->flags) {
-		if (mt.mask->flags & FLOW_DIS_FIRST_FRAG) {
-			if (mt.key->flags & FLOW_DIS_FIRST_FRAG) {
-				value = 1; /* initial fragment */
-				mask = 0x3;
-			} else {
-				if (mt.mask->flags & FLOW_DIS_IS_FRAGMENT) {
-					value = 3; /* follow up fragment */
-					mask = 0x3;
-				} else {
-					value = 0; /* no fragment */
-					mask = 0x3;
-				}
-			}
-		} else {
-			if (mt.mask->flags & FLOW_DIS_IS_FRAGMENT) {
-				value = 3; /* follow up fragment */
-				mask = 0x3;
-			} else {
-				value = 0; /* no fragment */
-				mask = 0x3;
-			}
+		u8 is_frag_key = !!(mt.key->flags & FLOW_DIS_IS_FRAGMENT);
+		u8 is_frag_mask = !!(mt.mask->flags & FLOW_DIS_IS_FRAGMENT);
+		u8 is_frag_idx = (is_frag_key << 1) | is_frag_mask;
+
+		u8 first_frag_key = !!(mt.key->flags & FLOW_DIS_FIRST_FRAG);
+		u8 first_frag_mask = !!(mt.mask->flags & FLOW_DIS_FIRST_FRAG);
+		u8 first_frag_idx = (first_frag_key << 1) | first_frag_mask;
+
+		/* Lookup verdict based on the 2 + 2 input bits */
+		u8 vdt = sparx5_vcap_frag_map[is_frag_idx][first_frag_idx];
+
+		if (vdt == FRAG_INVAL) {
+			NL_SET_ERR_MSG_MOD(st->fco->common.extack,
+					   "Match on invalid fragment flag combination");
+			return -EINVAL;
 		}
 
+		/* Extract VCAP fragment key and mask from verdict */
+		value = (vdt >> 4) & 0x3;
+		mask = vdt & 0x3;
+
 		err = vcap_rule_add_key_u32(st->vrule,
 					    VCAP_KF_L3_FRAGMENT_TYPE,
 					    value, mask);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c
@@ -366,12 +366,13 @@
 	struct vcap_typegroup typegroups[] = {
 		{ .offset = 0, .width = 2, .value = 2, },
 		{ .offset = 156, .width = 1, .value = 0, },
-		{ .offset = 0, .width = 0, .value = 0, },
+		{ }
 	};
 	struct vcap_typegroup typegroups2[] = {
 		{ .offset = 0, .width = 3, .value = 4, },
 		{ .offset = 49, .width = 2, .value = 0, },
 		{ .offset = 98, .width = 2, .value = 0, },
+		{ }
 	};
 
 	vcap_iter_init(&iter, 52, typegroups, 86);
@@ -399,6 +400,7 @@
 		{ .offset = 147, .width = 3, .value = 0, },
 		{ .offset = 196, .width = 2, .value = 0, },
 		{ .offset = 245, .width = 1, .value = 0, },
+		{ }
 	};
 	int idx;
 
@@ -433,7 +435,7 @@
 		{ .offset = 147, .width = 3, .value = 5, },
 		{ .offset = 196, .width = 2, .value = 2, },
 		{ .offset = 245, .width = 5, .value = 27, },
-		{ .offset = 0, .width = 0, .value = 0, },
+		{ }
 	};
 
 	vcap_encode_typegroups(stream, 49, typegroups, false);
@@ -463,6 +465,7 @@
 		{ .offset = 147, .width = 3, .value = 5, },
 		{ .offset = 196, .width = 2, .value = 2, },
 		{ .offset = 245, .width = 1, .value = 0, },
+		{ }
 	};
 
 	vcap_iter_init(&iter, 49, typegroups, 44);
@@ -489,7 +492,7 @@
 		{ .offset = 147, .width = 3, .value = 5, },
 		{ .offset = 196, .width = 2, .value = 2, },
 		{ .offset = 245, .width = 5, .value = 27, },
-		{ .offset = 0, .width = 0, .value = 0, },
+		{ }
 	};
 	struct vcap_field rf = {
 		.type = VCAP_FIELD_U32,
@@ -538,7 +541,7 @@
 		{ .offset = 0, .width = 3, .value = 7, },
 		{ .offset = 21, .width = 2, .value = 3, },
 		{ .offset = 42, .width = 1, .value = 1, },
-		{ .offset = 0, .width = 0, .value = 0, },
+		{ }
 	};
 	struct vcap_field rf = {
 		.type = VCAP_FIELD_U32,
@@ -608,7 +611,7 @@
 	struct vcap_typegroup tgt[] = {
 		{ .offset = 0, .width = 2, .value = 2, },
 		{ .offset = 156, .width = 1, .value = 1, },
-		{ .offset = 0, .width = 0, .value = 0, },
+		{ }
 	};
 
 	vcap_test_api_init(&admin);
@@ -671,7 +674,7 @@
 	struct vcap_typegroup tgt[] = {
 		{ .offset = 0, .width = 2, .value = 2, },
 		{ .offset = 156, .width = 1, .value = 1, },
-		{ .offset = 0, .width = 0, .value = 0, },
+		{ }
 	};
 	u32 keyres[] = {
 		0x928e8a84,
@@ -732,7 +735,7 @@
 		{ .offset = 0, .width = 2, .value = 2, },
 		{ .offset = 21, .width = 1, .value = 1, },
 		{ .offset = 42, .width = 1, .value = 0, },
-		{ .offset = 0, .width = 0, .value = 0, },
+		{ }
 	};
 
 	vcap_encode_actionfield(&rule, &caf, &rf, tgt);
@@ -1442,18 +1445,10 @@
 	vcap_enable_lookups(&test_vctrl, &test_netdev, 0, 0,
 			    rule->cookie, false);
 
-	vcap_free_rule(rule);
-
-	/* Check that the rule has been freed: tricky to access since this
-	 * memory should not be accessible anymore
-	 */
-	KUNIT_EXPECT_PTR_NE(test, NULL, rule);
-	ret = list_empty(&rule->keyfields);
-	KUNIT_EXPECT_EQ(test, true, ret);
-	ret = list_empty(&rule->actionfields);
-	KUNIT_EXPECT_EQ(test, true, ret);
+	ret = vcap_del_rule(&test_vctrl, &test_netdev, id);
+	KUNIT_EXPECT_EQ(test, 0, ret);
 
-	vcap_del_rule(&test_vctrl, &test_netdev, id);
+	vcap_free_rule(rule);
 }
 
 static void vcap_api_set_rule_counter_test(struct kunit *test)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/microsoft/Kconfig
+++ linux-qcom-6.8.0/drivers/net/ethernet/microsoft/Kconfig
@@ -17,7 +17,8 @@
 
 config MICROSOFT_MANA
 	tristate "Microsoft Azure Network Adapter (MANA) support"
-	depends on PCI_MSI && X86_64
+	depends on PCI_MSI
+	depends on X86_64 || (ARM64 && !CPU_BIG_ENDIAN)
 	depends on PCI_HYPERV
 	select AUXILIARY_BUS
 	select PAGE_POOL
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/microsoft/mana/gdma_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/microsoft/mana/gdma_main.c
@@ -182,7 +182,7 @@
 	dma_addr_t dma_handle;
 	void *buf;
 
-	if (length < PAGE_SIZE || !is_power_of_2(length))
+	if (length < MANA_PAGE_SIZE || !is_power_of_2(length))
 		return -EINVAL;
 
 	gmi->dev = gc->dev;
@@ -717,7 +717,7 @@
 static int mana_gd_create_dma_region(struct gdma_dev *gd,
 				     struct gdma_mem_info *gmi)
 {
-	unsigned int num_page = gmi->length / PAGE_SIZE;
+	unsigned int num_page = gmi->length / MANA_PAGE_SIZE;
 	struct gdma_create_dma_region_req *req = NULL;
 	struct gdma_create_dma_region_resp resp = {};
 	struct gdma_context *gc = gd->gdma_context;
@@ -727,10 +727,10 @@
 	int err;
 	int i;
 
-	if (length < PAGE_SIZE || !is_power_of_2(length))
+	if (length < MANA_PAGE_SIZE || !is_power_of_2(length))
 		return -EINVAL;
 
-	if (offset_in_page(gmi->virt_addr) != 0)
+	if (!MANA_PAGE_ALIGNED(gmi->virt_addr))
 		return -EINVAL;
 
 	hwc = gc->hwc.driver_data;
@@ -751,7 +751,7 @@
 	req->page_addr_list_len = num_page;
 
 	for (i = 0; i < num_page; i++)
-		req->page_addr_list[i] = gmi->dma_handle +  i * PAGE_SIZE;
+		req->page_addr_list[i] = gmi->dma_handle +  i * MANA_PAGE_SIZE;
 
 	err = mana_gd_send_request(gc, req_msg_size, req, sizeof(resp), &resp);
 	if (err)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/microsoft/mana/hw_channel.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/microsoft/mana/hw_channel.c
@@ -51,9 +51,33 @@
 	return 0;
 }
 
+static int mana_hwc_post_rx_wqe(const struct hwc_wq *hwc_rxq,
+				struct hwc_work_request *req)
+{
+	struct device *dev = hwc_rxq->hwc->dev;
+	struct gdma_sge *sge;
+	int err;
+
+	sge = &req->sge;
+	sge->address = (u64)req->buf_sge_addr;
+	sge->mem_key = hwc_rxq->msg_buf->gpa_mkey;
+	sge->size = req->buf_len;
+
+	memset(&req->wqe_req, 0, sizeof(struct gdma_wqe_request));
+	req->wqe_req.sgl = sge;
+	req->wqe_req.num_sge = 1;
+	req->wqe_req.client_data_unit = 0;
+
+	err = mana_gd_post_and_ring(hwc_rxq->gdma_wq, &req->wqe_req, NULL);
+	if (err)
+		dev_err(dev, "Failed to post WQE on HWC RQ: %d\n", err);
+	return err;
+}
+
 static void mana_hwc_handle_resp(struct hw_channel_context *hwc, u32 resp_len,
-				 const struct gdma_resp_hdr *resp_msg)
+				 struct hwc_work_request *rx_req)
 {
+	const struct gdma_resp_hdr *resp_msg = rx_req->buf_va;
 	struct hwc_caller_ctx *ctx;
 	int err;
 
@@ -61,6 +85,7 @@
 		      hwc->inflight_msg_res.map)) {
 		dev_err(hwc->dev, "hwc_rx: invalid msg_id = %u\n",
 			resp_msg->response.hwc_msg_id);
+		mana_hwc_post_rx_wqe(hwc->rxq, rx_req);
 		return;
 	}
 
@@ -74,30 +99,13 @@
 	memcpy(ctx->output_buf, resp_msg, resp_len);
 out:
 	ctx->error = err;
-	complete(&ctx->comp_event);
-}
-
-static int mana_hwc_post_rx_wqe(const struct hwc_wq *hwc_rxq,
-				struct hwc_work_request *req)
-{
-	struct device *dev = hwc_rxq->hwc->dev;
-	struct gdma_sge *sge;
-	int err;
-
-	sge = &req->sge;
-	sge->address = (u64)req->buf_sge_addr;
-	sge->mem_key = hwc_rxq->msg_buf->gpa_mkey;
-	sge->size = req->buf_len;
 
-	memset(&req->wqe_req, 0, sizeof(struct gdma_wqe_request));
-	req->wqe_req.sgl = sge;
-	req->wqe_req.num_sge = 1;
-	req->wqe_req.client_data_unit = 0;
+	/* Must post rx wqe before complete(), otherwise the next rx may
+	 * hit no_wqe error.
+	 */
+	mana_hwc_post_rx_wqe(hwc->rxq, rx_req);
 
-	err = mana_gd_post_and_ring(hwc_rxq->gdma_wq, &req->wqe_req, NULL);
-	if (err)
-		dev_err(dev, "Failed to post WQE on HWC RQ: %d\n", err);
-	return err;
+	complete(&ctx->comp_event);
 }
 
 static void mana_hwc_init_event_handler(void *ctx, struct gdma_queue *q_self,
@@ -234,14 +242,12 @@
 		return;
 	}
 
-	mana_hwc_handle_resp(hwc, rx_oob->tx_oob_data_size, resp);
+	mana_hwc_handle_resp(hwc, rx_oob->tx_oob_data_size, rx_req);
 
-	/* Do no longer use 'resp', because the buffer is posted to the HW
-	 * in the below mana_hwc_post_rx_wqe().
+	/* Can no longer use 'resp', because the buffer is posted to the HW
+	 * in mana_hwc_handle_resp() above.
 	 */
 	resp = NULL;
-
-	mana_hwc_post_rx_wqe(hwc_rxq, rx_req);
 }
 
 static void mana_hwc_tx_event_handler(void *ctx, u32 gdma_txq_id,
@@ -361,12 +367,12 @@
 	int err;
 
 	eq_size = roundup_pow_of_two(GDMA_EQE_SIZE * q_depth);
-	if (eq_size < MINIMUM_SUPPORTED_PAGE_SIZE)
-		eq_size = MINIMUM_SUPPORTED_PAGE_SIZE;
+	if (eq_size < MANA_MIN_QSIZE)
+		eq_size = MANA_MIN_QSIZE;
 
 	cq_size = roundup_pow_of_two(GDMA_CQE_SIZE * q_depth);
-	if (cq_size < MINIMUM_SUPPORTED_PAGE_SIZE)
-		cq_size = MINIMUM_SUPPORTED_PAGE_SIZE;
+	if (cq_size < MANA_MIN_QSIZE)
+		cq_size = MANA_MIN_QSIZE;
 
 	hwc_cq = kzalloc(sizeof(*hwc_cq), GFP_KERNEL);
 	if (!hwc_cq)
@@ -428,7 +434,7 @@
 
 	dma_buf->num_reqs = q_depth;
 
-	buf_size = PAGE_ALIGN(q_depth * max_msg_size);
+	buf_size = MANA_PAGE_ALIGN(q_depth * max_msg_size);
 
 	gmi = &dma_buf->mem_info;
 	err = mana_gd_alloc_memory(gc, buf_size, gmi);
@@ -496,8 +502,8 @@
 	else
 		queue_size = roundup_pow_of_two(GDMA_MAX_SQE_SIZE * q_depth);
 
-	if (queue_size < MINIMUM_SUPPORTED_PAGE_SIZE)
-		queue_size = MINIMUM_SUPPORTED_PAGE_SIZE;
+	if (queue_size < MANA_MIN_QSIZE)
+		queue_size = MANA_MIN_QSIZE;
 
 	hwc_wq = kzalloc(sizeof(*hwc_wq), GFP_KERNEL);
 	if (!hwc_wq)
@@ -848,7 +854,7 @@
 	}
 
 	if (!wait_for_completion_timeout(&ctx->comp_event,
-					 (msecs_to_jiffies(hwc->hwc_timeout) * HZ))) {
+					 (msecs_to_jiffies(hwc->hwc_timeout)))) {
 		dev_err(hwc->dev, "HWC: Request timed out!\n");
 		err = -ETIMEDOUT;
 		goto out;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -599,9 +599,13 @@
 	else
 		*headroom = XDP_PACKET_HEADROOM;
 
-	*alloc_size = mtu + MANA_RXBUF_PAD + *headroom;
+	*alloc_size = SKB_DATA_ALIGN(mtu + MANA_RXBUF_PAD + *headroom);
 
-	*datasize = ALIGN(mtu + ETH_HLEN, MANA_RX_DATA_ALIGN);
+	/* Using page pool in this case, so alloc_size is PAGE_SIZE */
+	if (*alloc_size < PAGE_SIZE)
+		*alloc_size = PAGE_SIZE;
+
+	*datasize = mtu + ETH_HLEN;
 }
 
 static int mana_pre_alloc_rxbufs(struct mana_port_context *mpc, int new_mtu)
@@ -1775,7 +1779,6 @@
 static int mana_cq_handler(void *context, struct gdma_queue *gdma_queue)
 {
 	struct mana_cq *cq = context;
-	u8 arm_bit;
 	int w;
 
 	WARN_ON_ONCE(cq->gdma_cq != gdma_queue);
@@ -1786,16 +1789,23 @@
 		mana_poll_tx_cq(cq);
 
 	w = cq->work_done;
+	cq->work_done_since_doorbell += w;
 
-	if (w < cq->budget &&
-	    napi_complete_done(&cq->napi, w)) {
-		arm_bit = SET_ARM_BIT;
-	} else {
-		arm_bit = 0;
+	if (w < cq->budget) {
+		mana_gd_ring_cq(gdma_queue, SET_ARM_BIT);
+		cq->work_done_since_doorbell = 0;
+		napi_complete_done(&cq->napi, w);
+	} else if (cq->work_done_since_doorbell >
+		   cq->gdma_cq->queue_size / COMP_ENTRY_SIZE * 4) {
+		/* MANA hardware requires at least one doorbell ring every 8
+		 * wraparounds of CQ even if there is no need to arm the CQ.
+		 * This driver rings the doorbell as soon as we have exceeded
+		 * 4 wraparounds.
+		 */
+		mana_gd_ring_cq(gdma_queue, 0);
+		cq->work_done_since_doorbell = 0;
 	}
 
-	mana_gd_ring_cq(gdma_queue, arm_bit);
-
 	return w;
 }
 
@@ -1849,10 +1859,12 @@
 
 	for (i = 0; i < apc->num_queues; i++) {
 		napi = &apc->tx_qp[i].tx_cq.napi;
-		napi_synchronize(napi);
-		napi_disable(napi);
-		netif_napi_del(napi);
-
+		if (apc->tx_qp[i].txq.napi_initialized) {
+			napi_synchronize(napi);
+			napi_disable(napi);
+			netif_napi_del(napi);
+			apc->tx_qp[i].txq.napi_initialized = false;
+		}
 		mana_destroy_wq_obj(apc, GDMA_SQ, apc->tx_qp[i].tx_object);
 
 		mana_deinit_cq(apc, &apc->tx_qp[i].tx_cq);
@@ -1891,10 +1903,10 @@
 	 *  to prevent overflow.
 	 */
 	txq_size = MAX_SEND_BUFFERS_PER_QUEUE * 32;
-	BUILD_BUG_ON(!PAGE_ALIGNED(txq_size));
+	BUILD_BUG_ON(!MANA_PAGE_ALIGNED(txq_size));
 
 	cq_size = MAX_SEND_BUFFERS_PER_QUEUE * COMP_ENTRY_SIZE;
-	cq_size = PAGE_ALIGN(cq_size);
+	cq_size = MANA_PAGE_ALIGN(cq_size);
 
 	gc = gd->gdma_context;
 
@@ -1908,6 +1920,7 @@
 		txq->ndev = net;
 		txq->net_txq = netdev_get_tx_queue(net, i);
 		txq->vp_offset = apc->tx_vp_offset;
+		txq->napi_initialized = false;
 		skb_queue_head_init(&txq->pending_skbs);
 
 		memset(&spec, 0, sizeof(spec));
@@ -1974,6 +1987,7 @@
 
 		netif_napi_add_tx(net, &cq->napi, mana_poll);
 		napi_enable(&cq->napi);
+		txq->napi_initialized = true;
 
 		mana_gd_ring_cq(cq->gdma_cq, SET_ARM_BIT);
 	}
@@ -1985,7 +1999,7 @@
 }
 
 static void mana_destroy_rxq(struct mana_port_context *apc,
-			     struct mana_rxq *rxq, bool validate_state)
+			     struct mana_rxq *rxq, bool napi_initialized)
 
 {
 	struct gdma_context *gc = apc->ac->gdma_dev->gdma_context;
@@ -2000,15 +2014,15 @@
 
 	napi = &rxq->rx_cq.napi;
 
-	if (validate_state)
+	if (napi_initialized) {
 		napi_synchronize(napi);
 
-	napi_disable(napi);
+		napi_disable(napi);
 
+		netif_napi_del(napi);
+	}
 	xdp_rxq_info_unreg(&rxq->xdp_rxq);
 
-	netif_napi_del(napi);
-
 	mana_destroy_wq_obj(apc, GDMA_RQ, rxq->rxobj);
 
 	mana_deinit_cq(apc, &rxq->rx_cq);
@@ -2191,8 +2205,8 @@
 	if (err)
 		goto out;
 
-	rq_size = PAGE_ALIGN(rq_size);
-	cq_size = PAGE_ALIGN(cq_size);
+	rq_size = MANA_PAGE_ALIGN(rq_size);
+	cq_size = MANA_PAGE_ALIGN(cq_size);
 
 	/* Create RQ */
 	memset(&spec, 0, sizeof(spec));
@@ -2387,6 +2401,7 @@
 
 	mana_gd_init_req_hdr(&req.hdr, MANA_QUERY_GF_STAT,
 			     sizeof(req), sizeof(resp));
+	req.hdr.resp.msg_version = GDMA_MESSAGE_V2;
 	req.req_stats = STATISTICS_FLAGS_RX_DISCARDS_NO_WQE |
 			STATISTICS_FLAGS_RX_ERRORS_VPORT_DISABLED |
 			STATISTICS_FLAGS_HC_RX_BYTES |
@@ -2800,6 +2815,8 @@
 	if (ret)
 		goto init_fail;
 
+	/* madev is owned by the auxiliary device */
+	madev = NULL;
 	ret = auxiliary_device_add(adev);
 	if (ret)
 		goto add_fail;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/microsoft/mana/shm_channel.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/microsoft/mana/shm_channel.c
@@ -6,6 +6,7 @@
 #include <linux/io.h>
 #include <linux/mm.h>
 
+#include <net/mana/gdma.h>
 #include <net/mana/shm_channel.h>
 
 #define PAGE_FRAME_L48_WIDTH_BYTES 6
@@ -155,8 +156,8 @@
 		return err;
 	}
 
-	if (!PAGE_ALIGNED(eq_addr) || !PAGE_ALIGNED(cq_addr) ||
-	    !PAGE_ALIGNED(rq_addr) || !PAGE_ALIGNED(sq_addr))
+	if (!MANA_PAGE_ALIGNED(eq_addr) || !MANA_PAGE_ALIGNED(cq_addr) ||
+	    !MANA_PAGE_ALIGNED(rq_addr) || !MANA_PAGE_ALIGNED(sq_addr))
 		return -EINVAL;
 
 	if ((eq_msix_index & VECTOR_MASK) != eq_msix_index)
@@ -183,7 +184,7 @@
 
 	/* EQ addr: low 48 bits of frame address */
 	shmem = (u64 *)ptr;
-	frame_addr = PHYS_PFN(eq_addr);
+	frame_addr = MANA_PFN(eq_addr);
 	*shmem = frame_addr & PAGE_FRAME_L48_MASK;
 	all_addr_h4bits |= (frame_addr >> PAGE_FRAME_L48_WIDTH_BITS) <<
 		(frame_addr_seq++ * PAGE_FRAME_H4_WIDTH_BITS);
@@ -191,7 +192,7 @@
 
 	/* CQ addr: low 48 bits of frame address */
 	shmem = (u64 *)ptr;
-	frame_addr = PHYS_PFN(cq_addr);
+	frame_addr = MANA_PFN(cq_addr);
 	*shmem = frame_addr & PAGE_FRAME_L48_MASK;
 	all_addr_h4bits |= (frame_addr >> PAGE_FRAME_L48_WIDTH_BITS) <<
 		(frame_addr_seq++ * PAGE_FRAME_H4_WIDTH_BITS);
@@ -199,7 +200,7 @@
 
 	/* RQ addr: low 48 bits of frame address */
 	shmem = (u64 *)ptr;
-	frame_addr = PHYS_PFN(rq_addr);
+	frame_addr = MANA_PFN(rq_addr);
 	*shmem = frame_addr & PAGE_FRAME_L48_MASK;
 	all_addr_h4bits |= (frame_addr >> PAGE_FRAME_L48_WIDTH_BITS) <<
 		(frame_addr_seq++ * PAGE_FRAME_H4_WIDTH_BITS);
@@ -207,7 +208,7 @@
 
 	/* SQ addr: low 48 bits of frame address */
 	shmem = (u64 *)ptr;
-	frame_addr = PHYS_PFN(sq_addr);
+	frame_addr = MANA_PFN(sq_addr);
 	*shmem = frame_addr & PAGE_FRAME_L48_MASK;
 	all_addr_h4bits |= (frame_addr >> PAGE_FRAME_L48_WIDTH_BITS) <<
 		(frame_addr_seq++ * PAGE_FRAME_H4_WIDTH_BITS);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mscc/ocelot.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mscc/ocelot.c
@@ -1099,6 +1099,48 @@
 }
 EXPORT_SYMBOL(ocelot_ptp_rx_timestamp);
 
+void ocelot_lock_inj_grp(struct ocelot *ocelot, int grp)
+			 __acquires(&ocelot->inj_lock)
+{
+	spin_lock(&ocelot->inj_lock);
+}
+EXPORT_SYMBOL_GPL(ocelot_lock_inj_grp);
+
+void ocelot_unlock_inj_grp(struct ocelot *ocelot, int grp)
+			   __releases(&ocelot->inj_lock)
+{
+	spin_unlock(&ocelot->inj_lock);
+}
+EXPORT_SYMBOL_GPL(ocelot_unlock_inj_grp);
+
+void ocelot_lock_xtr_grp(struct ocelot *ocelot, int grp)
+			 __acquires(&ocelot->inj_lock)
+{
+	spin_lock(&ocelot->inj_lock);
+}
+EXPORT_SYMBOL_GPL(ocelot_lock_xtr_grp);
+
+void ocelot_unlock_xtr_grp(struct ocelot *ocelot, int grp)
+			   __releases(&ocelot->inj_lock)
+{
+	spin_unlock(&ocelot->inj_lock);
+}
+EXPORT_SYMBOL_GPL(ocelot_unlock_xtr_grp);
+
+void ocelot_lock_xtr_grp_bh(struct ocelot *ocelot, int grp)
+			    __acquires(&ocelot->xtr_lock)
+{
+	spin_lock_bh(&ocelot->xtr_lock);
+}
+EXPORT_SYMBOL_GPL(ocelot_lock_xtr_grp_bh);
+
+void ocelot_unlock_xtr_grp_bh(struct ocelot *ocelot, int grp)
+			      __releases(&ocelot->xtr_lock)
+{
+	spin_unlock_bh(&ocelot->xtr_lock);
+}
+EXPORT_SYMBOL_GPL(ocelot_unlock_xtr_grp_bh);
+
 int ocelot_xtr_poll_frame(struct ocelot *ocelot, int grp, struct sk_buff **nskb)
 {
 	u64 timestamp, src_port, len;
@@ -1109,6 +1151,8 @@
 	u32 val, *buf;
 	int err;
 
+	lockdep_assert_held(&ocelot->xtr_lock);
+
 	err = ocelot_xtr_poll_xfh(ocelot, grp, xfh);
 	if (err)
 		return err;
@@ -1184,6 +1228,8 @@
 {
 	u32 val = ocelot_read(ocelot, QS_INJ_STATUS);
 
+	lockdep_assert_held(&ocelot->inj_lock);
+
 	if (!(val & QS_INJ_STATUS_FIFO_RDY(BIT(grp))))
 		return false;
 	if (val & QS_INJ_STATUS_WMARK_REACHED(BIT(grp)))
@@ -1193,28 +1239,55 @@
 }
 EXPORT_SYMBOL(ocelot_can_inject);
 
-void ocelot_ifh_port_set(void *ifh, int port, u32 rew_op, u32 vlan_tag)
+/**
+ * ocelot_ifh_set_basic - Set basic information in Injection Frame Header
+ * @ifh: Pointer to Injection Frame Header memory
+ * @ocelot: Switch private data structure
+ * @port: Egress port number
+ * @rew_op: Egress rewriter operation for PTP
+ * @skb: Pointer to socket buffer (packet)
+ *
+ * Populate the Injection Frame Header with basic information for this skb: the
+ * analyzer bypass bit, destination port, VLAN info, egress rewriter info.
+ */
+void ocelot_ifh_set_basic(void *ifh, struct ocelot *ocelot, int port,
+			  u32 rew_op, struct sk_buff *skb)
 {
+	struct ocelot_port *ocelot_port = ocelot->ports[port];
+	struct net_device *dev = skb->dev;
+	u64 vlan_tci, tag_type;
+	int qos_class;
+
+	ocelot_xmit_get_vlan_info(skb, ocelot_port->bridge, &vlan_tci,
+				  &tag_type);
+
+	qos_class = netdev_get_num_tc(dev) ?
+		    netdev_get_prio_tc_map(dev, skb->priority) : skb->priority;
+
+	memset(ifh, 0, OCELOT_TAG_LEN);
 	ocelot_ifh_set_bypass(ifh, 1);
+	ocelot_ifh_set_src(ifh, ocelot->num_phys_ports);
 	ocelot_ifh_set_dest(ifh, BIT_ULL(port));
-	ocelot_ifh_set_tag_type(ifh, IFH_TAG_TYPE_C);
-	if (vlan_tag)
-		ocelot_ifh_set_vlan_tci(ifh, vlan_tag);
+	ocelot_ifh_set_qos_class(ifh, qos_class);
+	ocelot_ifh_set_tag_type(ifh, tag_type);
+	ocelot_ifh_set_vlan_tci(ifh, vlan_tci);
 	if (rew_op)
 		ocelot_ifh_set_rew_op(ifh, rew_op);
 }
-EXPORT_SYMBOL(ocelot_ifh_port_set);
+EXPORT_SYMBOL(ocelot_ifh_set_basic);
 
 void ocelot_port_inject_frame(struct ocelot *ocelot, int port, int grp,
 			      u32 rew_op, struct sk_buff *skb)
 {
-	u32 ifh[OCELOT_TAG_LEN / 4] = {0};
+	u32 ifh[OCELOT_TAG_LEN / 4];
 	unsigned int i, count, last;
 
+	lockdep_assert_held(&ocelot->inj_lock);
+
 	ocelot_write_rix(ocelot, QS_INJ_CTRL_GAP_SIZE(1) |
 			 QS_INJ_CTRL_SOF, QS_INJ_CTRL, grp);
 
-	ocelot_ifh_port_set(ifh, port, rew_op, skb_vlan_tag_get(skb));
+	ocelot_ifh_set_basic(ifh, ocelot, port, rew_op, skb);
 
 	for (i = 0; i < OCELOT_TAG_LEN / 4; i++)
 		ocelot_write_rix(ocelot, ifh[i], QS_INJ_WR, grp);
@@ -1247,6 +1320,8 @@
 
 void ocelot_drain_cpu_queue(struct ocelot *ocelot, int grp)
 {
+	lockdep_assert_held(&ocelot->xtr_lock);
+
 	while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp))
 		ocelot_read_rix(ocelot, QS_XTR_RD, grp);
 }
@@ -2929,6 +3004,8 @@
 	mutex_init(&ocelot->fwd_domain_lock);
 	spin_lock_init(&ocelot->ptp_clock_lock);
 	spin_lock_init(&ocelot->ts_id_lock);
+	spin_lock_init(&ocelot->inj_lock);
+	spin_lock_init(&ocelot->xtr_lock);
 
 	ocelot->owq = alloc_ordered_workqueue("ocelot-owq", 0);
 	if (!ocelot->owq)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mscc/ocelot_fdma.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mscc/ocelot_fdma.c
@@ -665,8 +665,7 @@
 
 	ifh = skb_push(skb, OCELOT_TAG_LEN);
 	skb_put(skb, ETH_FCS_LEN);
-	memset(ifh, 0, OCELOT_TAG_LEN);
-	ocelot_ifh_port_set(ifh, port, rew_op, skb_vlan_tag_get(skb));
+	ocelot_ifh_set_basic(ifh, ocelot, port, rew_op, skb);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mscc/ocelot_ptp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mscc/ocelot_ptp.c
@@ -14,6 +14,8 @@
 #include <soc/mscc/ocelot.h>
 #include "ocelot.h"
 
+#define OCELOT_PTP_TX_TSTAMP_TIMEOUT		(5 * HZ)
+
 int ocelot_ptp_gettime64(struct ptp_clock_info *ptp, struct timespec64 *ts)
 {
 	struct ocelot *ocelot = container_of(ptp, struct ocelot, ptp_info);
@@ -495,6 +497,28 @@
 	return HWTSTAMP_FILTER_NONE;
 }
 
+static int ocelot_ptp_tx_type_to_cmd(int tx_type, int *ptp_cmd)
+{
+	switch (tx_type) {
+	case HWTSTAMP_TX_ON:
+		*ptp_cmd = IFH_REW_OP_TWO_STEP_PTP;
+		break;
+	case HWTSTAMP_TX_ONESTEP_SYNC:
+		/* IFH_REW_OP_ONE_STEP_PTP updates the correctionField,
+		 * what we need to update is the originTimestamp.
+		 */
+		*ptp_cmd = IFH_REW_OP_ORIGIN_PTP;
+		break;
+	case HWTSTAMP_TX_OFF:
+		*ptp_cmd = 0;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	return 0;
+}
+
 int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr)
 {
 	struct ocelot_port *ocelot_port = ocelot->ports[port];
@@ -521,30 +545,19 @@
 int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr)
 {
 	struct ocelot_port *ocelot_port = ocelot->ports[port];
+	int ptp_cmd, old_ptp_cmd = ocelot_port->ptp_cmd;
 	bool l2 = false, l4 = false;
 	struct hwtstamp_config cfg;
+	bool old_l2, old_l4;
 	int err;
 
 	if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
 		return -EFAULT;
 
 	/* Tx type sanity check */
-	switch (cfg.tx_type) {
-	case HWTSTAMP_TX_ON:
-		ocelot_port->ptp_cmd = IFH_REW_OP_TWO_STEP_PTP;
-		break;
-	case HWTSTAMP_TX_ONESTEP_SYNC:
-		/* IFH_REW_OP_ONE_STEP_PTP updates the correctional field, we
-		 * need to update the origin time.
-		 */
-		ocelot_port->ptp_cmd = IFH_REW_OP_ORIGIN_PTP;
-		break;
-	case HWTSTAMP_TX_OFF:
-		ocelot_port->ptp_cmd = 0;
-		break;
-	default:
-		return -ERANGE;
-	}
+	err = ocelot_ptp_tx_type_to_cmd(cfg.tx_type, &ptp_cmd);
+	if (err)
+		return err;
 
 	switch (cfg.rx_filter) {
 	case HWTSTAMP_FILTER_NONE:
@@ -569,13 +582,27 @@
 		return -ERANGE;
 	}
 
+	old_l2 = ocelot_port->trap_proto & OCELOT_PROTO_PTP_L2;
+	old_l4 = ocelot_port->trap_proto & OCELOT_PROTO_PTP_L4;
+
 	err = ocelot_setup_ptp_traps(ocelot, port, l2, l4);
 	if (err)
 		return err;
 
+	ocelot_port->ptp_cmd = ptp_cmd;
+
 	cfg.rx_filter = ocelot_traps_to_ptp_rx_filter(ocelot_port->trap_proto);
 
-	return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
+	if (copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg))) {
+		err = -EFAULT;
+		goto out_restore_ptp_traps;
+	}
+
+	return 0;
+out_restore_ptp_traps:
+	ocelot_setup_ptp_traps(ocelot, port, old_l2, old_l4);
+	ocelot_port->ptp_cmd = old_ptp_cmd;
+	return err;
 }
 EXPORT_SYMBOL(ocelot_hwstamp_set);
 
@@ -607,34 +634,87 @@
 }
 EXPORT_SYMBOL(ocelot_get_ts_info);
 
-static int ocelot_port_add_txtstamp_skb(struct ocelot *ocelot, int port,
-					struct sk_buff *clone)
+static struct sk_buff *ocelot_port_dequeue_ptp_tx_skb(struct ocelot *ocelot,
+						      int port, u8 ts_id,
+						      u32 seqid)
 {
 	struct ocelot_port *ocelot_port = ocelot->ports[port];
-	unsigned long flags;
+	struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
+	struct ptp_header *hdr;
+
+	spin_lock(&ocelot->ts_id_lock);
+
+	skb_queue_walk_safe(&ocelot_port->tx_skbs, skb, skb_tmp) {
+		if (OCELOT_SKB_CB(skb)->ts_id != ts_id)
+			continue;
 
-	spin_lock_irqsave(&ocelot->ts_id_lock, flags);
+		/* Check that the timestamp ID is for the expected PTP
+		 * sequenceId. We don't have to test ptp_parse_header() against
+		 * NULL, because we've pre-validated the packet's ptp_class.
+		 */
+		hdr = ptp_parse_header(skb, OCELOT_SKB_CB(skb)->ptp_class);
+		if (seqid != ntohs(hdr->sequence_id))
+			continue;
+
+		__skb_unlink(skb, &ocelot_port->tx_skbs);
+		ocelot->ptp_skbs_in_flight--;
+		skb_match = skb;
+		break;
+	}
 
-	if (ocelot_port->ptp_skbs_in_flight == OCELOT_MAX_PTP_ID ||
-	    ocelot->ptp_skbs_in_flight == OCELOT_PTP_FIFO_SIZE) {
-		spin_unlock_irqrestore(&ocelot->ts_id_lock, flags);
+	spin_unlock(&ocelot->ts_id_lock);
+
+	return skb_match;
+}
+
+static int ocelot_port_queue_ptp_tx_skb(struct ocelot *ocelot, int port,
+					struct sk_buff *clone)
+{
+	struct ocelot_port *ocelot_port = ocelot->ports[port];
+	DECLARE_BITMAP(ts_id_in_flight, OCELOT_MAX_PTP_ID);
+	struct sk_buff *skb, *skb_tmp;
+	unsigned long n;
+
+	spin_lock(&ocelot->ts_id_lock);
+
+	/* To get a better chance of acquiring a timestamp ID, first flush the
+	 * stale packets still waiting in the TX timestamping queue. They are
+	 * probably lost.
+	 */
+	skb_queue_walk_safe(&ocelot_port->tx_skbs, skb, skb_tmp) {
+		if (time_before(OCELOT_SKB_CB(skb)->ptp_tx_time +
+				OCELOT_PTP_TX_TSTAMP_TIMEOUT, jiffies)) {
+			dev_warn_ratelimited(ocelot->dev,
+					     "port %d invalidating stale timestamp ID %u which seems lost\n",
+					     port, OCELOT_SKB_CB(skb)->ts_id);
+			__skb_unlink(skb, &ocelot_port->tx_skbs);
+			kfree_skb(skb);
+			ocelot->ptp_skbs_in_flight--;
+		} else {
+			__set_bit(OCELOT_SKB_CB(skb)->ts_id, ts_id_in_flight);
+		}
+	}
+
+	if (ocelot->ptp_skbs_in_flight == OCELOT_PTP_FIFO_SIZE) {
+		spin_unlock(&ocelot->ts_id_lock);
 		return -EBUSY;
 	}
 
-	skb_shinfo(clone)->tx_flags |= SKBTX_IN_PROGRESS;
-	/* Store timestamp ID in OCELOT_SKB_CB(clone)->ts_id */
-	OCELOT_SKB_CB(clone)->ts_id = ocelot_port->ts_id;
-
-	ocelot_port->ts_id++;
-	if (ocelot_port->ts_id == OCELOT_MAX_PTP_ID)
-		ocelot_port->ts_id = 0;
+	n = find_first_zero_bit(ts_id_in_flight, OCELOT_MAX_PTP_ID);
+	if (n == OCELOT_MAX_PTP_ID) {
+		spin_unlock(&ocelot->ts_id_lock);
+		return -EBUSY;
+	}
 
-	ocelot_port->ptp_skbs_in_flight++;
+	/* Found an available timestamp ID, use it */
+	OCELOT_SKB_CB(clone)->ts_id = n;
+	OCELOT_SKB_CB(clone)->ptp_tx_time = jiffies;
 	ocelot->ptp_skbs_in_flight++;
+	__skb_queue_tail(&ocelot_port->tx_skbs, clone);
 
-	skb_queue_tail(&ocelot_port->tx_skbs, clone);
+	spin_unlock(&ocelot->ts_id_lock);
 
-	spin_unlock_irqrestore(&ocelot->ts_id_lock, flags);
+	dev_dbg_ratelimited(ocelot->dev, "port %d timestamp id %lu\n", port, n);
 
 	return 0;
 }
@@ -691,10 +771,14 @@
 		if (!(*clone))
 			return -ENOMEM;
 
-		err = ocelot_port_add_txtstamp_skb(ocelot, port, *clone);
-		if (err)
+		/* Store timestamp ID in OCELOT_SKB_CB(clone)->ts_id */
+		err = ocelot_port_queue_ptp_tx_skb(ocelot, port, *clone);
+		if (err) {
+			kfree_skb(*clone);
 			return err;
+		}
 
+		skb_shinfo(*clone)->tx_flags |= SKBTX_IN_PROGRESS;
 		OCELOT_SKB_CB(skb)->ptp_cmd = ptp_cmd;
 		OCELOT_SKB_CB(*clone)->ptp_class = ptp_class;
 	}
@@ -730,28 +814,15 @@
 	spin_unlock_irqrestore(&ocelot->ptp_clock_lock, flags);
 }
 
-static bool ocelot_validate_ptp_skb(struct sk_buff *clone, u16 seqid)
-{
-	struct ptp_header *hdr;
-
-	hdr = ptp_parse_header(clone, OCELOT_SKB_CB(clone)->ptp_class);
-	if (WARN_ON(!hdr))
-		return false;
-
-	return seqid == ntohs(hdr->sequence_id);
-}
-
 void ocelot_get_txtstamp(struct ocelot *ocelot)
 {
 	int budget = OCELOT_PTP_QUEUE_SZ;
 
 	while (budget--) {
-		struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
 		struct skb_shared_hwtstamps shhwtstamps;
 		u32 val, id, seqid, txport;
-		struct ocelot_port *port;
+		struct sk_buff *skb_match;
 		struct timespec64 ts;
-		unsigned long flags;
 
 		val = ocelot_read(ocelot, SYS_PTP_STATUS);
 
@@ -766,36 +837,14 @@
 		txport = SYS_PTP_STATUS_PTP_MESS_TXPORT_X(val);
 		seqid = SYS_PTP_STATUS_PTP_MESS_SEQ_ID(val);
 
-		port = ocelot->ports[txport];
-
-		spin_lock(&ocelot->ts_id_lock);
-		port->ptp_skbs_in_flight--;
-		ocelot->ptp_skbs_in_flight--;
-		spin_unlock(&ocelot->ts_id_lock);
-
 		/* Retrieve its associated skb */
-try_again:
-		spin_lock_irqsave(&port->tx_skbs.lock, flags);
-
-		skb_queue_walk_safe(&port->tx_skbs, skb, skb_tmp) {
-			if (OCELOT_SKB_CB(skb)->ts_id != id)
-				continue;
-			__skb_unlink(skb, &port->tx_skbs);
-			skb_match = skb;
-			break;
-		}
-
-		spin_unlock_irqrestore(&port->tx_skbs.lock, flags);
-
-		if (WARN_ON(!skb_match))
-			continue;
-
-		if (!ocelot_validate_ptp_skb(skb_match, seqid)) {
-			dev_err_ratelimited(ocelot->dev,
-					    "port %d received stale TX timestamp for seqid %d, discarding\n",
-					    txport, seqid);
-			dev_kfree_skb_any(skb);
-			goto try_again;
+		skb_match = ocelot_port_dequeue_ptp_tx_skb(ocelot, txport, id,
+							   seqid);
+		if (!skb_match) {
+			dev_warn_ratelimited(ocelot->dev,
+					     "port %d received TX timestamp (seqid %d, ts id %u) for packet previously declared stale\n",
+					     txport, seqid, id);
+			goto next_ts;
 		}
 
 		/* Get the h/w timestamp */
@@ -806,7 +855,7 @@
 		shhwtstamps.hwtstamp = ktime_set(ts.tv_sec, ts.tv_nsec);
 		skb_complete_tx_timestamp(skb_match, &shhwtstamps);
 
-		/* Next ts */
+next_ts:
 		ocelot_write(ocelot, SYS_PTP_NXT_PTP_NXT, SYS_PTP_NXT);
 	}
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/mscc/ocelot_vsc7514.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/mscc/ocelot_vsc7514.c
@@ -51,6 +51,8 @@
 	struct ocelot *ocelot = arg;
 	int grp = 0, err;
 
+	ocelot_lock_xtr_grp(ocelot, grp);
+
 	while (ocelot_read(ocelot, QS_XTR_DATA_PRESENT) & BIT(grp)) {
 		struct sk_buff *skb;
 
@@ -69,6 +71,8 @@
 	if (err < 0)
 		ocelot_drain_cpu_queue(ocelot, 0);
 
+	ocelot_unlock_xtr_grp(ocelot, grp);
+
 	return IRQ_HANDLED;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/netronome/nfp/bpf/offload.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/netronome/nfp/bpf/offload.c
@@ -458,7 +458,8 @@
 	map_id_full = be64_to_cpu(cbe->map_ptr);
 	map_id = map_id_full;
 
-	if (len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
+	if (size_add(pkt_size, data_size) > INT_MAX ||
+	    len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size)
 		return -EINVAL;
 	if (cbe->hdr.ver != NFP_CCM_ABI_VERSION)
 		return -EINVAL;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c
@@ -337,6 +337,11 @@
 
 		acti_netdevs = kmalloc_array(entry->slave_cnt,
 					     sizeof(*acti_netdevs), GFP_KERNEL);
+		if (!acti_netdevs) {
+			schedule_delayed_work(&lag->work,
+					      NFP_FL_LAG_DELAY);
+			continue;
+		}
 
 		/* Include sanity check in the loop. It may be that a bond has
 		 * changed between processing the last notification and the
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -821,14 +821,13 @@
 
 	snprintf(r_vec->name, sizeof(r_vec->name),
 		 "%s-rxtx-%d", nfp_net_name(nn), idx);
-	err = request_irq(r_vec->irq_vector, r_vec->handler, 0, r_vec->name,
-			  r_vec);
+	err = request_irq(r_vec->irq_vector, r_vec->handler, IRQF_NO_AUTOEN,
+			  r_vec->name, r_vec);
 	if (err) {
 		nfp_net_napi_del(&nn->dp, r_vec);
 		nn_err(nn, "Error requesting IRQ %d\n", r_vec->irq_vector);
 		return err;
 	}
-	disable_irq(r_vec->irq_vector);
 
 	irq_set_affinity_hint(r_vec->irq_vector, &r_vec->affinity_mask);
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c
@@ -388,6 +388,7 @@
 err_out_pci:
 	ionic_dev_teardown(ionic);
 	ionic_clear_pci(ionic);
+	ionic_debugfs_del_dev(ionic);
 err_out:
 	mutex_destroy(&ionic->dev_cmd_lock);
 	ionic_devlink_free(ionic);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
@@ -947,8 +947,8 @@
 	len = min_t(u32, sizeof(xcvr->sprom), ee->len);
 
 	do {
-		memcpy(data, xcvr->sprom, len);
-		memcpy(tbuf, xcvr->sprom, len);
+		memcpy(data, &xcvr->sprom[ee->offset], len);
+		memcpy(tbuf, &xcvr->sprom[ee->offset], len);
 
 		/* Let's make sure we got a consistent copy */
 		if (!memcmp(data, tbuf, len))
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/pensando/ionic/ionic_lif.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/pensando/ionic/ionic_lif.c
@@ -234,7 +234,7 @@
 		name = dev_name(dev);
 
 	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,
 				0, intr->name, &qcq->napi);
@@ -296,10 +296,8 @@
 	if (ret)
 		return ret;
 
-	if (qcq->napi.poll)
-		napi_enable(&qcq->napi);
-
 	if (qcq->flags & IONIC_QCQ_F_INTR) {
+		napi_enable(&qcq->napi);
 		irq_set_affinity_hint(qcq->intr.vector,
 				      &qcq->intr.affinity_mask);
 		ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
@@ -3391,9 +3389,12 @@
 
 	napi_enable(&qcq->napi);
 
-	if (qcq->flags & IONIC_QCQ_F_INTR)
+	if (qcq->flags & IONIC_QCQ_F_INTR) {
+		irq_set_affinity_hint(qcq->intr.vector,
+				      &qcq->intr.affinity_mask);
 		ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
 				IONIC_INTR_MASK_CLEAR);
+	}
 
 	qcq->flags |= IONIC_QCQ_F_INITED;
 
@@ -3661,8 +3662,8 @@
 	/* only register LIF0 for now */
 	err = register_netdev(lif->netdev);
 	if (err) {
-		dev_err(lif->ionic->dev, "Cannot register net device, aborting\n");
-		ionic_lif_unregister_phc(lif);
+		dev_err(lif->ionic->dev, "Cannot register net device: %d, aborting\n", err);
+		ionic_lif_unregister(lif);
 		return err;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -1206,7 +1206,6 @@
 static int qed_slowpath_wq_start(struct qed_dev *cdev)
 {
 	struct qed_hwfn *hwfn;
-	char name[NAME_SIZE];
 	int i;
 
 	if (IS_VF(cdev))
@@ -1215,11 +1214,11 @@
 	for_each_hwfn(cdev, i) {
 		hwfn = &cdev->hwfns[i];
 
-		snprintf(name, NAME_SIZE, "slowpath-%02x:%02x.%02x",
-			 cdev->pdev->bus->number,
-			 PCI_SLOT(cdev->pdev->devfn), hwfn->abs_pf_id);
+		hwfn->slowpath_wq = alloc_workqueue("slowpath-%02x:%02x.%02x",
+					 0, 0, cdev->pdev->bus->number,
+					 PCI_SLOT(cdev->pdev->devfn),
+					 hwfn->abs_pf_id);
 
-		hwfn->slowpath_wq = alloc_workqueue(name, 0, 0);
 		if (!hwfn->slowpath_wq) {
 			DP_NOTICE(hwfn, "Cannot create slowpath workqueue\n");
 			return -ENOMEM;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -3314,7 +3314,9 @@
 	if (rc)
 		return rc;
 
-	if (((rsp & FW_MSG_CODE_MASK) != FW_MSG_CODE_OK))
+	if (((rsp & FW_MSG_CODE_MASK) == FW_MSG_CODE_UNSUPPORTED))
+		rc = -EOPNOTSUPP;
+	else if (((rsp & FW_MSG_CODE_MASK) != FW_MSG_CODE_OK))
 		rc = -EINVAL;
 
 	return rc;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/qlogic/qede/qede_filter.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/qlogic/qede/qede_filter.c
@@ -1868,8 +1868,8 @@
 			    struct flow_cls_offload *f)
 {
 	struct qede_arfs_fltr_node *n;
-	int min_hlen, rc = -EINVAL;
 	struct qede_arfs_tuple t;
+	int min_hlen, rc;
 
 	__qede_lock(edev);
 
@@ -1879,7 +1879,8 @@
 	}
 
 	/* parse flower attribute and prepare filter */
-	if (qede_parse_flow_attr(edev, proto, f->rule, &t))
+	rc = qede_parse_flow_attr(edev, proto, f->rule, &t);
+	if (rc)
 		goto unlock;
 
 	/* Validate profile mode and number of filters */
@@ -1888,11 +1889,13 @@
 		DP_NOTICE(edev,
 			  "Filter configuration invalidated, filter mode=0x%x, configured mode=0x%x, filter count=0x%x\n",
 			  t.mode, edev->arfs->mode, edev->arfs->filter_count);
+		rc = -EINVAL;
 		goto unlock;
 	}
 
 	/* parse tc actions and get the vf_id */
-	if (qede_parse_actions(edev, &f->rule->action, f->common.extack))
+	rc = qede_parse_actions(edev, &f->rule->action, f->common.extack);
+	if (rc)
 		goto unlock;
 
 	if (qede_flow_find_fltr(edev, &t)) {
@@ -1998,10 +2001,9 @@
 	if (IS_ERR(flow))
 		return PTR_ERR(flow);
 
-	if (qede_parse_flow_attr(edev, proto, flow->rule, t)) {
-		err = -EINVAL;
+	err = qede_parse_flow_attr(edev, proto, flow->rule, t);
+	if (err)
 		goto err_out;
-	}
 
 	/* Make sure location is valid and filter isn't already set */
 	err = qede_flow_spec_validate(edev, &flow->rule->action, t,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/qualcomm/qca_debug.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/qualcomm/qca_debug.c
@@ -111,10 +111,8 @@
 
 	seq_printf(s, "IRQ              : %d\n",
 		   qca->spi_dev->irq);
-	seq_printf(s, "INTR REQ         : %u\n",
-		   qca->intr_req);
-	seq_printf(s, "INTR SVC         : %u\n",
-		   qca->intr_svc);
+	seq_printf(s, "INTR             : %lx\n",
+		   qca->intr);
 
 	seq_printf(s, "SPI max speed    : %lu\n",
 		   (unsigned long)qca->spi_dev->max_speed_hz);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/qualcomm/qca_spi.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/qualcomm/qca_spi.c
@@ -48,6 +48,8 @@
 
 #define MAX_DMA_BURST_LEN 5000
 
+#define SPI_INTR 0
+
 /*   Modules parameters     */
 #define QCASPI_CLK_SPEED_MIN 1000000
 #define QCASPI_CLK_SPEED_MAX 16000000
@@ -64,7 +66,7 @@
 
 #define QCASPI_PLUGGABLE_MIN 0
 #define QCASPI_PLUGGABLE_MAX 1
-static int qcaspi_pluggable = QCASPI_PLUGGABLE_MIN;
+static int qcaspi_pluggable = QCASPI_PLUGGABLE_MAX;
 module_param(qcaspi_pluggable, int, 0);
 MODULE_PARM_DESC(qcaspi_pluggable, "Pluggable SPI connection (yes/no).");
 
@@ -592,14 +594,14 @@
 			continue;
 		}
 
-		if ((qca->intr_req == qca->intr_svc) &&
+		if (!test_bit(SPI_INTR, &qca->intr) &&
 		    !qca->txr.skb[qca->txr.head])
 			schedule();
 
 		set_current_state(TASK_RUNNING);
 
-		netdev_dbg(qca->net_dev, "have work to do. int: %d, tx_skb: %p\n",
-			   qca->intr_req - qca->intr_svc,
+		netdev_dbg(qca->net_dev, "have work to do. int: %lu, tx_skb: %p\n",
+			   qca->intr,
 			   qca->txr.skb[qca->txr.head]);
 
 		qcaspi_qca7k_sync(qca, QCASPI_EVENT_UPDATE);
@@ -613,8 +615,7 @@
 			msleep(QCASPI_QCA7K_REBOOT_TIME_MS);
 		}
 
-		if (qca->intr_svc != qca->intr_req) {
-			qca->intr_svc = qca->intr_req;
+		if (test_and_clear_bit(SPI_INTR, &qca->intr)) {
 			start_spi_intr_handling(qca, &intr_cause);
 
 			if (intr_cause & SPI_INT_CPU_ON) {
@@ -676,7 +677,7 @@
 {
 	struct qcaspi *qca = data;
 
-	qca->intr_req++;
+	set_bit(SPI_INTR, &qca->intr);
 	if (qca->spi_thread)
 		wake_up_process(qca->spi_thread);
 
@@ -692,8 +693,7 @@
 	if (!qca)
 		return -EINVAL;
 
-	qca->intr_req = 1;
-	qca->intr_svc = 0;
+	set_bit(SPI_INTR, &qca->intr);
 	qca->sync = QCASPI_SYNC_UNKNOWN;
 	qcafrm_fsm_init_spi(&qca->frm_handle);
 
@@ -828,7 +828,6 @@
 
 	dev->mtu = QCAFRM_MAX_MTU;
 	dev->type = ARPHRD_ETHER;
-	qca->clkspeed = qcaspi_clkspeed;
 	qca->burst_len = qcaspi_burst_len;
 	qca->spi_thread = NULL;
 	qca->buffer_size = (dev->mtu + VLAN_ETH_HLEN + QCAFRM_HEADER_LEN +
@@ -917,17 +916,15 @@
 	legacy_mode = of_property_read_bool(spi->dev.of_node,
 					    "qca,legacy-mode");
 
-	if (qcaspi_clkspeed == 0) {
-		if (spi->max_speed_hz)
-			qcaspi_clkspeed = spi->max_speed_hz;
-		else
-			qcaspi_clkspeed = QCASPI_CLK_SPEED;
-	}
-
-	if ((qcaspi_clkspeed < QCASPI_CLK_SPEED_MIN) ||
-	    (qcaspi_clkspeed > QCASPI_CLK_SPEED_MAX)) {
-		dev_err(&spi->dev, "Invalid clkspeed: %d\n",
-			qcaspi_clkspeed);
+	if (qcaspi_clkspeed)
+		spi->max_speed_hz = qcaspi_clkspeed;
+	else if (!spi->max_speed_hz)
+		spi->max_speed_hz = QCASPI_CLK_SPEED;
+
+	if (spi->max_speed_hz < QCASPI_CLK_SPEED_MIN ||
+	    spi->max_speed_hz > QCASPI_CLK_SPEED_MAX) {
+		dev_err(&spi->dev, "Invalid clkspeed: %u\n",
+			spi->max_speed_hz);
 		return -EINVAL;
 	}
 
@@ -952,14 +949,13 @@
 		return -EINVAL;
 	}
 
-	dev_info(&spi->dev, "ver=%s, clkspeed=%d, burst_len=%d, pluggable=%d\n",
+	dev_info(&spi->dev, "ver=%s, clkspeed=%u, burst_len=%d, pluggable=%d\n",
 		 QCASPI_DRV_VERSION,
-		 qcaspi_clkspeed,
+		 spi->max_speed_hz,
 		 qcaspi_burst_len,
 		 qcaspi_pluggable);
 
 	spi->mode = SPI_MODE_3;
-	spi->max_speed_hz = qcaspi_clkspeed;
 	if (spi_setup(spi) < 0) {
 		dev_err(&spi->dev, "Unable to setup SPI device\n");
 		return -EFAULT;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/qualcomm/qca_spi.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/qualcomm/qca_spi.h
@@ -93,8 +93,7 @@
 	struct qcafrm_handle frm_handle;
 	struct sk_buff *rx_skb;
 
-	unsigned int intr_req;
-	unsigned int intr_svc;
+	unsigned long intr;
 	u16 reset_count;
 
 #ifdef CONFIG_DEBUG_FS
@@ -102,7 +101,6 @@
 #endif
 
 	/* user configurable options */
-	u32 clkspeed;
 	u8 legacy_mode;
 	u16 burst_len;
 };
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/realtek/r8169.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/realtek/r8169.h
@@ -72,6 +72,7 @@
 };
 
 struct rtl8169_private;
+struct r8169_led_classdev;
 
 void r8169_apply_firmware(struct rtl8169_private *tp);
 u16 rtl8168h_2_get_adc_bias_ioffset(struct rtl8169_private *tp);
@@ -83,4 +84,5 @@
 			char *buf, int buf_len);
 int rtl8168_get_led_mode(struct rtl8169_private *tp);
 int rtl8168_led_mod_ctrl(struct rtl8169_private *tp, u16 mask, u16 val);
-void rtl8168_init_leds(struct net_device *ndev);
+struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev);
+void r8169_remove_leds(struct r8169_led_classdev *leds);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/realtek/r8169_leds.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/realtek/r8169_leds.c
@@ -138,20 +138,31 @@
 	led_cdev->hw_control_get_device = r8169_led_hw_control_get_device;
 
 	/* ignore errors */
-	devm_led_classdev_register(&ndev->dev, led_cdev);
+	led_classdev_register(&ndev->dev, led_cdev);
 }
 
-void rtl8168_init_leds(struct net_device *ndev)
+struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev)
 {
-	/* bind resource mgmt to netdev */
-	struct device *dev = &ndev->dev;
 	struct r8169_led_classdev *leds;
 	int i;
 
-	leds = devm_kcalloc(dev, RTL8168_NUM_LEDS, sizeof(*leds), GFP_KERNEL);
+	leds = kcalloc(RTL8168_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL);
 	if (!leds)
-		return;
+		return NULL;
 
 	for (i = 0; i < RTL8168_NUM_LEDS; i++)
 		rtl8168_setup_ldev(leds + i, ndev, i);
+
+	return leds;
+}
+
+void r8169_remove_leds(struct r8169_led_classdev *leds)
+{
+	if (!leds)
+		return;
+
+	for (struct r8169_led_classdev *l = leds; l->ndev; l++)
+		led_classdev_unregister(&l->led);
+
+	kfree(leds);
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/realtek/r8169_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/realtek/r8169_main.c
@@ -15,6 +15,7 @@
 #include <linux/etherdevice.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
+#include <linux/dmi.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
 #include <linux/if_vlan.h>
@@ -563,7 +564,34 @@
 	__le64	rx_broadcast;
 	__le32	rx_multicast;
 	__le16	tx_aborted;
-	__le16	tx_underun;
+	__le16	tx_underrun;
+	/* new since RTL8125 */
+	__le64 tx_octets;
+	__le64 rx_octets;
+	__le64 rx_multicast64;
+	__le64 tx_unicast64;
+	__le64 tx_broadcast64;
+	__le64 tx_multicast64;
+	__le32 tx_pause_on;
+	__le32 tx_pause_off;
+	__le32 tx_pause_all;
+	__le32 tx_deferred;
+	__le32 tx_late_collision;
+	__le32 tx_all_collision;
+	__le32 tx_aborted32;
+	__le32 align_errors32;
+	__le32 rx_frame_too_long;
+	__le32 rx_runt;
+	__le32 rx_pause_on;
+	__le32 rx_pause_off;
+	__le32 rx_pause_all;
+	__le32 rx_unknown_opcode;
+	__le32 rx_mac_error;
+	__le32 tx_underrun32;
+	__le32 rx_mac_missed;
+	__le32 rx_tcam_dropped;
+	__le32 tdu;
+	__le32 rdu;
 };
 
 struct rtl8169_tc_offsets {
@@ -634,6 +662,8 @@
 	const char *fw_name;
 	struct rtl_fw *rtl_fw;
 
+	struct r8169_led_classdev *leds;
+
 	u32 ocp_base;
 };
 
@@ -1255,17 +1285,40 @@
 	RTL_W8(tp, IBCR0, RTL_R8(tp, IBCR0) & ~0x01);
 }
 
+static void rtl_dash_loop_wait(struct rtl8169_private *tp,
+			       const struct rtl_cond *c,
+			       unsigned long usecs, int n, bool high)
+{
+	if (!tp->dash_enabled)
+		return;
+	rtl_loop_wait(tp, c, usecs, n, high);
+}
+
+static void rtl_dash_loop_wait_high(struct rtl8169_private *tp,
+				    const struct rtl_cond *c,
+				    unsigned long d, int n)
+{
+	rtl_dash_loop_wait(tp, c, d, n, true);
+}
+
+static void rtl_dash_loop_wait_low(struct rtl8169_private *tp,
+				   const struct rtl_cond *c,
+				   unsigned long d, int n)
+{
+	rtl_dash_loop_wait(tp, c, d, n, false);
+}
+
 static void rtl8168dp_driver_start(struct rtl8169_private *tp)
 {
 	r8168dp_oob_notify(tp, OOB_CMD_DRIVER_START);
-	rtl_loop_wait_high(tp, &rtl_dp_ocp_read_cond, 10000, 10);
+	rtl_dash_loop_wait_high(tp, &rtl_dp_ocp_read_cond, 10000, 10);
 }
 
 static void rtl8168ep_driver_start(struct rtl8169_private *tp)
 {
 	r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_START);
 	r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01);
-	rtl_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30);
+	rtl_dash_loop_wait_high(tp, &rtl_ep_ocp_read_cond, 10000, 30);
 }
 
 static void rtl8168_driver_start(struct rtl8169_private *tp)
@@ -1279,7 +1332,7 @@
 static void rtl8168dp_driver_stop(struct rtl8169_private *tp)
 {
 	r8168dp_oob_notify(tp, OOB_CMD_DRIVER_STOP);
-	rtl_loop_wait_low(tp, &rtl_dp_ocp_read_cond, 10000, 10);
+	rtl_dash_loop_wait_low(tp, &rtl_dp_ocp_read_cond, 10000, 10);
 }
 
 static void rtl8168ep_driver_stop(struct rtl8169_private *tp)
@@ -1287,7 +1340,7 @@
 	rtl8168ep_stop_cmac(tp);
 	r8168ep_ocp_write(tp, 0x01, 0x180, OOB_CMD_DRIVER_STOP);
 	r8168ep_ocp_write(tp, 0x01, 0x30, r8168ep_ocp_read(tp, 0x30) | 0x01);
-	rtl_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10);
+	rtl_dash_loop_wait_low(tp, &rtl_ep_ocp_read_cond, 10000, 10);
 }
 
 static void rtl8168_driver_stop(struct rtl8169_private *tp)
@@ -1757,7 +1810,7 @@
 	data[9] = le64_to_cpu(counters->rx_broadcast);
 	data[10] = le32_to_cpu(counters->rx_multicast);
 	data[11] = le16_to_cpu(counters->tx_aborted);
-	data[12] = le16_to_cpu(counters->tx_underun);
+	data[12] = le16_to_cpu(counters->tx_underrun);
 }
 
 static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
@@ -4049,8 +4102,8 @@
 {
 	unsigned int padto = 0, len = skb->len;
 
-	if (rtl_is_8125(tp) && len < 128 + RTL_MIN_PATCH_LEN &&
-	    rtl_skb_is_udp(skb) && skb_transport_header_was_set(skb)) {
+	if (len < 128 + RTL_MIN_PATCH_LEN && rtl_skb_is_udp(skb) &&
+	    skb_transport_header_was_set(skb)) {
 		unsigned int trans_data_len = skb_tail_pointer(skb) -
 					      skb_transport_header(skb);
 
@@ -4074,9 +4127,15 @@
 static unsigned int rtl_quirk_packet_padto(struct rtl8169_private *tp,
 					   struct sk_buff *skb)
 {
-	unsigned int padto;
+	unsigned int padto = 0;
 
-	padto = rtl8125_quirk_udp_padto(tp, skb);
+	switch (tp->mac_version) {
+	case RTL_GIGA_MAC_VER_61 ... RTL_GIGA_MAC_VER_63:
+		padto = rtl8125_quirk_udp_padto(tp, skb);
+		break;
+	default:
+		break;
+	}
 
 	switch (tp->mac_version) {
 	case RTL_GIGA_MAC_VER_34:
@@ -4196,17 +4255,18 @@
 static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
 				      struct net_device *dev)
 {
-	unsigned int frags = skb_shinfo(skb)->nr_frags;
 	struct rtl8169_private *tp = netdev_priv(dev);
 	unsigned int entry = tp->cur_tx % NUM_TX_DESC;
 	struct TxDesc *txd_first, *txd_last;
 	bool stop_queue, door_bell;
+	unsigned int frags;
 	u32 opts[2];
 
 	if (unlikely(!rtl_tx_slots_avail(tp))) {
 		if (net_ratelimit())
 			netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
-		goto err_stop_0;
+		netif_stop_queue(dev);
+		return NETDEV_TX_BUSY;
 	}
 
 	opts[1] = rtl8169_tx_vlan_tag(skb);
@@ -4223,6 +4283,7 @@
 
 	txd_first = tp->TxDescArray + entry;
 
+	frags = skb_shinfo(skb)->nr_frags;
 	if (frags) {
 		if (rtl8169_xmit_frags(tp, skb, opts, entry))
 			goto err_dma_1;
@@ -4261,11 +4322,6 @@
 	dev_kfree_skb_any(skb);
 	dev->stats.tx_dropped++;
 	return NETDEV_TX_OK;
-
-err_stop_0:
-	netif_stop_queue(dev);
-	dev->stats.tx_dropped++;
-	return NETDEV_TX_BUSY;
 }
 
 static unsigned int rtl_last_frag_len(struct sk_buff *skb)
@@ -4502,7 +4558,9 @@
 	if ((status & 0xffff) == 0xffff || !(status & tp->irq_mask))
 		return IRQ_NONE;
 
-	if (unlikely(status & SYSErr)) {
+	/* At least RTL8168fp may unexpectedly set the SYSErr bit */
+	if (unlikely(status & SYSErr &&
+	    tp->mac_version <= RTL_GIGA_MAC_VER_06)) {
 		rtl8169_pcierr_interrupt(tp->dev);
 		goto out;
 	}
@@ -4516,10 +4574,8 @@
 		rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
 	}
 
-	if (napi_schedule_prep(&tp->napi)) {
-		rtl_irq_disable(tp);
-		__napi_schedule(&tp->napi);
-	}
+	rtl_irq_disable(tp);
+	napi_schedule(&tp->napi);
 out:
 	rtl_ack_events(tp, status);
 
@@ -4907,6 +4963,9 @@
 
 	cancel_work_sync(&tp->wk.work);
 
+	if (IS_ENABLED(CONFIG_R8169_LEDS))
+		r8169_remove_leds(tp->leds);
+
 	unregister_netdev(tp->dev);
 
 	if (tp->dash_type != RTL_DASH_NONE)
@@ -5027,6 +5086,15 @@
 	struct mii_bus *new_bus;
 	int ret;
 
+	/* On some boards with this chip version the BIOS is buggy and misses
+	 * to reset the PHY page selector. This results in the PHY ID read
+	 * accessing registers on a different page, returning a more or
+	 * less random value. Fix this by resetting the page selector first.
+	 */
+	if (tp->mac_version == RTL_GIGA_MAC_VER_25 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_26)
+		r8169_mdio_write(tp, 0x1f, 0);
+
 	new_bus = devm_mdiobus_alloc(&pdev->dev);
 	if (!new_bus)
 		return -ENOMEM;
@@ -5164,11 +5232,87 @@
 	rtl_rar_set(tp, mac_addr);
 }
 
+static bool rtl_aspm_dell_workaround(struct rtl8169_private *tp)
+{
+	static const struct dmi_system_id sysids[] = {
+		{
+			.ident = "Dell",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+				DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 16 5640"),
+				DMI_MATCH(DMI_PRODUCT_SKU, "0CA0"),
+			},
+		},
+		{
+			.ident = "Dell",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+				DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 14 3440"),
+				DMI_MATCH(DMI_PRODUCT_SKU, "0CA5"),
+			},
+		},
+		{
+			.ident = "Dell",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+				DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 14 3440"),
+				DMI_MATCH(DMI_PRODUCT_SKU, "0CA6"),
+			},
+		},
+		{
+			.ident = "Dell",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+				DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 3450"),
+				DMI_MATCH(DMI_PRODUCT_SKU, "0C99"),
+			},
+		},
+		{
+			.ident = "Dell",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+				DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 3450"),
+				DMI_MATCH(DMI_PRODUCT_SKU, "0C97"),
+			},
+		},
+		{
+			.ident = "Dell",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+				DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 3550"),
+				DMI_MATCH(DMI_PRODUCT_SKU, "0C9A"),
+			},
+		},
+		{
+			.ident = "Dell",
+			.matches = {
+				DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+				DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 3550"),
+				DMI_MATCH(DMI_PRODUCT_SKU, "0C98"),
+			},
+		},
+		{}
+	};
+
+	if (tp->mac_version == RTL_GIGA_MAC_VER_46 && dmi_check_system(sysids))
+		return true;
+
+	return false;
+}
+
 /* register is set if system vendor successfully tested ASPM 1.2 */
 static bool rtl_aspm_is_safe(struct rtl8169_private *tp)
 {
+	 /* definition of 0xc0b2,
+	  * 0: L1
+	  * 1: ASPM L1.0
+	  * 2: ASPM L0s
+	  * 3: CLKEREQ
+	  * 4-7: Reserved
+	  */
 	if (tp->mac_version >= RTL_GIGA_MAC_VER_61 &&
-	    r8168_mac_ocp_read(tp, 0xc0b2) & 0xf)
+		r8168_mac_ocp_read(tp, 0xc0b2) & 0xf ||
+		rtl_aspm_dell_workaround(tp))
 		return true;
 
 	return false;
@@ -5359,7 +5503,7 @@
 	if (IS_ENABLED(CONFIG_R8169_LEDS) &&
 	    tp->mac_version > RTL_GIGA_MAC_VER_06 &&
 	    tp->mac_version < RTL_GIGA_MAC_VER_61)
-		rtl8168_init_leds(dev);
+		tp->leds = rtl8168_init_leds(dev);
 
 	netdev_info(dev, "%s, %pM, XID %03x, IRQ %d\n",
 		    rtl_chip_infos[chipset].name, dev->dev_addr, xid, tp->irq);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/realtek/r8169_phy_config.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/realtek/r8169_phy_config.c
@@ -1060,6 +1060,7 @@
 	phy_modify_paged(phydev, 0xa86, 0x15, 0x0001, 0x0000);
 	rtl8168g_enable_gphy_10m(phydev);
 
+	rtl8168g_disable_aldps(phydev);
 	rtl8125a_config_eee_phy(phydev);
 }
 
@@ -1099,6 +1100,7 @@
 	phy_modify_paged(phydev, 0xbf8, 0x12, 0xe000, 0xa000);
 
 	rtl8125_legacy_force_mode(phydev);
+	rtl8168g_disable_aldps(phydev);
 	rtl8125b_config_eee_phy(phydev);
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/renesas/ravb.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/renesas/ravb.h
@@ -1027,7 +1027,8 @@
 	int stats_len;
 	size_t max_rx_len;
 	u32 tccr_mask;
-	u32 rx_max_buf_size;
+	u32 tx_max_frame_size;
+	u32 rx_max_frame_size;
 	unsigned aligned_tx: 1;
 
 	/* hardware features */
@@ -1060,8 +1061,10 @@
 	struct ravb_desc *desc_bat;
 	dma_addr_t rx_desc_dma[NUM_RX_QUEUE];
 	dma_addr_t tx_desc_dma[NUM_TX_QUEUE];
-	struct ravb_rx_desc *gbeth_rx_ring;
-	struct ravb_ex_rx_desc *rx_ring[NUM_RX_QUEUE];
+	union {
+		struct ravb_rx_desc *desc;
+		struct ravb_ex_rx_desc *ex_desc;
+	} rx_ring[NUM_RX_QUEUE];
 	struct ravb_tx_desc *tx_ring[NUM_TX_QUEUE];
 	void *tx_align[NUM_TX_QUEUE];
 	struct sk_buff *rx_1st_skb;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/renesas/ravb_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/renesas/ravb_main.c
@@ -250,11 +250,11 @@
 	unsigned int ring_size;
 	unsigned int i;
 
-	if (!priv->gbeth_rx_ring)
+	if (!priv->rx_ring[q].desc)
 		return;
 
 	for (i = 0; i < priv->num_rx_ring[q]; i++) {
-		struct ravb_rx_desc *desc = &priv->gbeth_rx_ring[i];
+		struct ravb_rx_desc *desc = &priv->rx_ring[q].desc[i];
 
 		if (!dma_mapping_error(ndev->dev.parent,
 				       le32_to_cpu(desc->dptr)))
@@ -264,9 +264,9 @@
 					 DMA_FROM_DEVICE);
 	}
 	ring_size = sizeof(struct ravb_rx_desc) * (priv->num_rx_ring[q] + 1);
-	dma_free_coherent(ndev->dev.parent, ring_size, priv->gbeth_rx_ring,
+	dma_free_coherent(ndev->dev.parent, ring_size, priv->rx_ring[q].desc,
 			  priv->rx_desc_dma[q]);
-	priv->gbeth_rx_ring = NULL;
+	priv->rx_ring[q].desc = NULL;
 }
 
 static void ravb_rx_ring_free_rcar(struct net_device *ndev, int q)
@@ -275,11 +275,11 @@
 	unsigned int ring_size;
 	unsigned int i;
 
-	if (!priv->rx_ring[q])
+	if (!priv->rx_ring[q].ex_desc)
 		return;
 
 	for (i = 0; i < priv->num_rx_ring[q]; i++) {
-		struct ravb_ex_rx_desc *desc = &priv->rx_ring[q][i];
+		struct ravb_ex_rx_desc *desc = &priv->rx_ring[q].ex_desc[i];
 
 		if (!dma_mapping_error(ndev->dev.parent,
 				       le32_to_cpu(desc->dptr)))
@@ -290,9 +290,9 @@
 	}
 	ring_size = sizeof(struct ravb_ex_rx_desc) *
 		    (priv->num_rx_ring[q] + 1);
-	dma_free_coherent(ndev->dev.parent, ring_size, priv->rx_ring[q],
+	dma_free_coherent(ndev->dev.parent, ring_size, priv->rx_ring[q].ex_desc,
 			  priv->rx_desc_dma[q]);
-	priv->rx_ring[q] = NULL;
+	priv->rx_ring[q].ex_desc = NULL;
 }
 
 /* Free skb's and DMA buffers for Ethernet AVB */
@@ -344,11 +344,11 @@
 	unsigned int i;
 
 	rx_ring_size = sizeof(*rx_desc) * priv->num_rx_ring[q];
-	memset(priv->gbeth_rx_ring, 0, rx_ring_size);
+	memset(priv->rx_ring[q].desc, 0, rx_ring_size);
 	/* Build RX ring buffer */
 	for (i = 0; i < priv->num_rx_ring[q]; i++) {
 		/* RX descriptor */
-		rx_desc = &priv->gbeth_rx_ring[i];
+		rx_desc = &priv->rx_ring[q].desc[i];
 		rx_desc->ds_cc = cpu_to_le16(GBETH_RX_DESC_DATA_SIZE);
 		dma_addr = dma_map_single(ndev->dev.parent, priv->rx_skb[q][i]->data,
 					  GBETH_RX_BUFF_MAX,
@@ -361,7 +361,7 @@
 		rx_desc->dptr = cpu_to_le32(dma_addr);
 		rx_desc->die_dt = DT_FEMPTY;
 	}
-	rx_desc = &priv->gbeth_rx_ring[i];
+	rx_desc = &priv->rx_ring[q].desc[i];
 	rx_desc->dptr = cpu_to_le32((u32)priv->rx_desc_dma[q]);
 	rx_desc->die_dt = DT_LINKFIX; /* type */
 }
@@ -374,11 +374,11 @@
 	dma_addr_t dma_addr;
 	unsigned int i;
 
-	memset(priv->rx_ring[q], 0, rx_ring_size);
+	memset(priv->rx_ring[q].ex_desc, 0, rx_ring_size);
 	/* Build RX ring buffer */
 	for (i = 0; i < priv->num_rx_ring[q]; i++) {
 		/* RX descriptor */
-		rx_desc = &priv->rx_ring[q][i];
+		rx_desc = &priv->rx_ring[q].ex_desc[i];
 		rx_desc->ds_cc = cpu_to_le16(RX_BUF_SZ);
 		dma_addr = dma_map_single(ndev->dev.parent, priv->rx_skb[q][i]->data,
 					  RX_BUF_SZ,
@@ -391,7 +391,7 @@
 		rx_desc->dptr = cpu_to_le32(dma_addr);
 		rx_desc->die_dt = DT_FEMPTY;
 	}
-	rx_desc = &priv->rx_ring[q][i];
+	rx_desc = &priv->rx_ring[q].ex_desc[i];
 	rx_desc->dptr = cpu_to_le32((u32)priv->rx_desc_dma[q]);
 	rx_desc->die_dt = DT_LINKFIX; /* type */
 }
@@ -446,10 +446,10 @@
 
 	ring_size = sizeof(struct ravb_rx_desc) * (priv->num_rx_ring[q] + 1);
 
-	priv->gbeth_rx_ring = dma_alloc_coherent(ndev->dev.parent, ring_size,
-						 &priv->rx_desc_dma[q],
-						 GFP_KERNEL);
-	return priv->gbeth_rx_ring;
+	priv->rx_ring[q].desc = dma_alloc_coherent(ndev->dev.parent, ring_size,
+						   &priv->rx_desc_dma[q],
+						   GFP_KERNEL);
+	return priv->rx_ring[q].desc;
 }
 
 static void *ravb_alloc_rx_desc_rcar(struct net_device *ndev, int q)
@@ -459,10 +459,11 @@
 
 	ring_size = sizeof(struct ravb_ex_rx_desc) * (priv->num_rx_ring[q] + 1);
 
-	priv->rx_ring[q] = dma_alloc_coherent(ndev->dev.parent, ring_size,
-					      &priv->rx_desc_dma[q],
-					      GFP_KERNEL);
-	return priv->rx_ring[q];
+	priv->rx_ring[q].ex_desc = dma_alloc_coherent(ndev->dev.parent,
+						      ring_size,
+						      &priv->rx_desc_dma[q],
+						      GFP_KERNEL);
+	return priv->rx_ring[q].ex_desc;
 }
 
 /* Init skb and descriptor buffer for Ethernet AVB */
@@ -561,8 +562,16 @@
 
 static void ravb_emac_init_rcar(struct net_device *ndev)
 {
-	/* Receive frame limit set register */
-	ravb_write(ndev, ndev->mtu + ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN, RFLR);
+	struct ravb_private *priv = netdev_priv(ndev);
+
+	/* Set receive frame length
+	 *
+	 * The length set here describes the frame from the destination address
+	 * up to and including the CRC data. However only the frame data,
+	 * excluding the CRC, are transferred to memory. To allow for the
+	 * largest frames add the CRC length to the maximum Rx descriptor size.
+	 */
+	ravb_write(ndev, priv->info->rx_max_frame_size + ETH_FCS_LEN, RFLR);
 
 	/* EMAC Mode: PAUSE prohibition; Duplex; RX Checksum; TX; RX */
 	ravb_write(ndev, ECMR_ZPF | ECMR_DM |
@@ -780,12 +789,15 @@
 	int limit;
 	int i;
 
-	entry = priv->cur_rx[q] % priv->num_rx_ring[q];
 	limit = priv->dirty_rx[q] + priv->num_rx_ring[q] - priv->cur_rx[q];
 	stats = &priv->stats[q];
 
-	desc = &priv->gbeth_rx_ring[entry];
-	for (i = 0; i < limit && rx_packets < *quota && desc->die_dt != DT_FEMPTY; i++) {
+	for (i = 0; i < limit; i++, priv->cur_rx[q]++) {
+		entry = priv->cur_rx[q] % priv->num_rx_ring[q];
+		desc = &priv->rx_ring[q].desc[entry];
+		if (rx_packets == *quota || desc->die_dt == DT_FEMPTY)
+			break;
+
 		/* Descriptor type must be checked before all other reads */
 		dma_rmb();
 		desc_status = desc->msc;
@@ -849,15 +861,12 @@
 				break;
 			}
 		}
-
-		entry = (++priv->cur_rx[q]) % priv->num_rx_ring[q];
-		desc = &priv->gbeth_rx_ring[entry];
 	}
 
 	/* Refill the RX ring buffers. */
 	for (; priv->cur_rx[q] - priv->dirty_rx[q] > 0; priv->dirty_rx[q]++) {
 		entry = priv->dirty_rx[q] % priv->num_rx_ring[q];
-		desc = &priv->gbeth_rx_ring[entry];
+		desc = &priv->rx_ring[q].desc[entry];
 		desc->ds_cc = cpu_to_le16(GBETH_RX_DESC_DATA_SIZE);
 
 		if (!priv->rx_skb[q][entry]) {
@@ -893,30 +902,29 @@
 {
 	struct ravb_private *priv = netdev_priv(ndev);
 	const struct ravb_hw_info *info = priv->info;
-	int entry = priv->cur_rx[q] % priv->num_rx_ring[q];
-	int boguscnt = (priv->dirty_rx[q] + priv->num_rx_ring[q]) -
-			priv->cur_rx[q];
 	struct net_device_stats *stats = &priv->stats[q];
 	struct ravb_ex_rx_desc *desc;
+	unsigned int limit, i;
 	struct sk_buff *skb;
 	dma_addr_t dma_addr;
 	struct timespec64 ts;
+	int rx_packets = 0;
 	u8  desc_status;
 	u16 pkt_len;
-	int limit;
+	int entry;
+
+	limit = priv->dirty_rx[q] + priv->num_rx_ring[q] - priv->cur_rx[q];
+	for (i = 0; i < limit; i++, priv->cur_rx[q]++) {
+		entry = priv->cur_rx[q] % priv->num_rx_ring[q];
+		desc = &priv->rx_ring[q].ex_desc[entry];
+		if (rx_packets == *quota || desc->die_dt == DT_FEMPTY)
+			break;
 
-	boguscnt = min(boguscnt, *quota);
-	limit = boguscnt;
-	desc = &priv->rx_ring[q][entry];
-	while (desc->die_dt != DT_FEMPTY) {
 		/* Descriptor type must be checked before all other reads */
 		dma_rmb();
 		desc_status = desc->msc;
 		pkt_len = le16_to_cpu(desc->ds_cc) & RX_DS;
 
-		if (--boguscnt < 0)
-			break;
-
 		/* We use 0-byte descriptors to mark the DMA mapping errors */
 		if (!pkt_len)
 			continue;
@@ -962,18 +970,15 @@
 			if (ndev->features & NETIF_F_RXCSUM)
 				ravb_rx_csum(skb);
 			napi_gro_receive(&priv->napi[q], skb);
-			stats->rx_packets++;
+			rx_packets++;
 			stats->rx_bytes += pkt_len;
 		}
-
-		entry = (++priv->cur_rx[q]) % priv->num_rx_ring[q];
-		desc = &priv->rx_ring[q][entry];
 	}
 
 	/* Refill the RX ring buffers. */
 	for (; priv->cur_rx[q] - priv->dirty_rx[q] > 0; priv->dirty_rx[q]++) {
 		entry = priv->dirty_rx[q] % priv->num_rx_ring[q];
-		desc = &priv->rx_ring[q][entry];
+		desc = &priv->rx_ring[q].ex_desc[entry];
 		desc->ds_cc = cpu_to_le16(RX_BUF_SZ);
 
 		if (!priv->rx_skb[q][entry]) {
@@ -998,9 +1003,9 @@
 		desc->die_dt = DT_FEMPTY;
 	}
 
-	*quota -= limit - (++boguscnt);
-
-	return boguscnt <= 0;
+	stats->rx_packets += rx_packets;
+	*quota -= rx_packets;
+	return *quota == 0;
 }
 
 /* Packet receive function for Ethernet AVB */
@@ -1284,25 +1289,16 @@
 	struct net_device *ndev = napi->dev;
 	struct ravb_private *priv = netdev_priv(ndev);
 	const struct ravb_hw_info *info = priv->info;
-	bool gptp = info->gptp || info->ccc_gac;
-	struct ravb_rx_desc *desc;
 	unsigned long flags;
 	int q = napi - priv->napi;
 	int mask = BIT(q);
 	int quota = budget;
-	unsigned int entry;
+	bool unmask;
 
-	if (!gptp) {
-		entry = priv->cur_rx[q] % priv->num_rx_ring[q];
-		desc = &priv->gbeth_rx_ring[entry];
-	}
 	/* Processing RX Descriptor Ring */
 	/* Clear RX interrupt */
 	ravb_write(ndev, ~(mask | RIS0_RESERVED), RIS0);
-	if (gptp || desc->die_dt != DT_FEMPTY) {
-		if (ravb_rx(ndev, &quota, q))
-			goto out;
-	}
+	unmask = !ravb_rx(ndev, &quota, q);
 
 	/* Processing TX Descriptor Ring */
 	spin_lock_irqsave(&priv->lock, flags);
@@ -1312,6 +1308,18 @@
 	netif_wake_subqueue(ndev, q);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
+	/* Receive error message handling */
+	priv->rx_over_errors = priv->stats[RAVB_BE].rx_over_errors;
+	if (info->nc_queues)
+		priv->rx_over_errors += priv->stats[RAVB_NC].rx_over_errors;
+	if (priv->rx_over_errors != ndev->stats.rx_over_errors)
+		ndev->stats.rx_over_errors = priv->rx_over_errors;
+	if (priv->rx_fifo_errors != ndev->stats.rx_fifo_errors)
+		ndev->stats.rx_fifo_errors = priv->rx_fifo_errors;
+
+	if (!unmask)
+		goto out;
+
 	napi_complete(napi);
 
 	/* Re-enable RX/TX interrupts */
@@ -1325,14 +1333,6 @@
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	/* Receive error message handling */
-	priv->rx_over_errors =  priv->stats[RAVB_BE].rx_over_errors;
-	if (info->nc_queues)
-		priv->rx_over_errors += priv->stats[RAVB_NC].rx_over_errors;
-	if (priv->rx_over_errors != ndev->stats.rx_over_errors)
-		ndev->stats.rx_over_errors = priv->rx_over_errors;
-	if (priv->rx_fifo_errors != ndev->stats.rx_fifo_errors)
-		ndev->stats.rx_fifo_errors = priv->rx_fifo_errors;
 out:
 	return budget - quota;
 }
@@ -1674,20 +1674,19 @@
 	struct ravb_private *priv = netdev_priv(ndev);
 	const struct ravb_hw_info *hw_info = priv->info;
 
-	info->so_timestamping =
-		SOF_TIMESTAMPING_TX_SOFTWARE |
-		SOF_TIMESTAMPING_RX_SOFTWARE |
-		SOF_TIMESTAMPING_SOFTWARE |
-		SOF_TIMESTAMPING_TX_HARDWARE |
-		SOF_TIMESTAMPING_RX_HARDWARE |
-		SOF_TIMESTAMPING_RAW_HARDWARE;
-	info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
-	info->rx_filters =
-		(1 << HWTSTAMP_FILTER_NONE) |
-		(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
-		(1 << HWTSTAMP_FILTER_ALL);
-	if (hw_info->gptp || hw_info->ccc_gac)
+	if (hw_info->gptp || hw_info->ccc_gac) {
+		info->so_timestamping =
+			SOF_TIMESTAMPING_TX_SOFTWARE |
+			SOF_TIMESTAMPING_TX_HARDWARE |
+			SOF_TIMESTAMPING_RX_HARDWARE |
+			SOF_TIMESTAMPING_RAW_HARDWARE;
+		info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
+		info->rx_filters =
+			(1 << HWTSTAMP_FILTER_NONE) |
+			(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
+			(1 << HWTSTAMP_FILTER_ALL);
 		info->phc_index = ptp_clock_index(priv->ptp.clock);
+	}
 
 	return 0;
 }
@@ -2445,7 +2444,8 @@
 	.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
 	.max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1,
 	.tccr_mask = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
-	.rx_max_buf_size = SZ_2K,
+	.tx_max_frame_size = SZ_2K,
+	.rx_max_frame_size = SZ_2K,
 	.internal_delay = 1,
 	.tx_counters = 1,
 	.multi_irqs = 1,
@@ -2471,7 +2471,8 @@
 	.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
 	.max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1,
 	.tccr_mask = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
-	.rx_max_buf_size = SZ_2K,
+	.tx_max_frame_size = SZ_2K,
+	.rx_max_frame_size = SZ_2K,
 	.aligned_tx = 1,
 	.gptp = 1,
 	.nc_queues = 1,
@@ -2494,7 +2495,8 @@
 	.stats_len = ARRAY_SIZE(ravb_gstrings_stats),
 	.max_rx_len = RX_BUF_SZ + RAVB_ALIGN - 1,
 	.tccr_mask = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3,
-	.rx_max_buf_size = SZ_2K,
+	.tx_max_frame_size = SZ_2K,
+	.rx_max_frame_size = SZ_2K,
 	.multi_irqs = 1,
 	.err_mgmt_irqs = 1,
 	.gptp = 1,
@@ -2517,7 +2519,8 @@
 	.stats_len = ARRAY_SIZE(ravb_gstrings_stats_gbeth),
 	.max_rx_len = ALIGN(GBETH_RX_BUFF_MAX, RAVB_ALIGN),
 	.tccr_mask = TCCR_TSRQ0,
-	.rx_max_buf_size = SZ_8K,
+	.tx_max_frame_size = 1522,
+	.rx_max_frame_size = SZ_8K,
 	.aligned_tx = 1,
 	.tx_counters = 1,
 	.carrier_counters = 1,
@@ -2788,7 +2791,7 @@
 		clk_prepare_enable(priv->gptp_clk);
 	}
 
-	ndev->max_mtu = info->rx_max_buf_size - (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN);
+	ndev->max_mtu = info->tx_max_frame_size - (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN);
 	ndev->min_mtu = ETH_MIN_MTU;
 
 	/* FIXME: R-Car Gen2 has 4byte alignment restriction for tx buffer
@@ -2991,10 +2994,12 @@
 
 	netif_device_detach(ndev);
 
+	rtnl_lock();
 	if (priv->wol_enabled)
 		ret = ravb_wol_setup(ndev);
 	else
 		ret = ravb_close(ndev);
+	rtnl_unlock();
 
 	if (priv->info->ccc_gac)
 		ravb_ptp_stop(ndev);
@@ -3009,12 +3014,16 @@
 	const struct ravb_hw_info *info = priv->info;
 	int ret = 0;
 
+	rtnl_lock();
 	/* If WoL is enabled set reset mode to rearm the WoL logic */
 	if (priv->wol_enabled) {
 		ret = ravb_set_opmode(ndev, CCC_OPC_RESET);
-		if (ret)
+		if (ret) {
+			rtnl_unlock();
 			return ret;
+		}
 	}
+	rtnl_unlock();
 
 	/* All register have been reset to default values.
 	 * Restore all registers which where setup at probe time and
@@ -3046,14 +3055,20 @@
 		ravb_ptp_init(ndev, priv->pdev);
 
 	if (netif_running(ndev)) {
+		rtnl_lock();
 		if (priv->wol_enabled) {
 			ret = ravb_wol_restore(ndev);
-			if (ret)
+			if (ret) {
+				rtnl_unlock();
 				return ret;
+			}
 		}
 		ret = ravb_open(ndev);
-		if (ret < 0)
+		if (ret < 0) {
+			rtnl_unlock();
 			return ret;
+		}
+		rtnl_unlock();
 		ravb_set_rx_mode(ndev);
 		netif_device_attach(ndev);
 	}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/renesas/rswitch.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/renesas/rswitch.c
@@ -547,7 +547,6 @@
 	desc = &gq->ts_ring[gq->ring_size];
 	desc->desc.die_dt = DT_LINKFIX;
 	rswitch_desc_set_dptr(&desc->desc, gq->ring_dma);
-	INIT_LIST_HEAD(&priv->gwca.ts_info_list);
 
 	return 0;
 }
@@ -862,24 +861,24 @@
 	struct rswitch_ext_desc *desc;
 	struct sk_buff *skb;
 
-	for (; rswitch_get_num_cur_queues(gq) > 0;
-	     gq->dirty = rswitch_next_queue_index(gq, false, 1)) {
-		desc = &gq->tx_ring[gq->dirty];
-		if ((desc->desc.die_dt & DT_MASK) != DT_FEMPTY)
-			break;
-
+	desc = &gq->tx_ring[gq->dirty];
+	while ((desc->desc.die_dt & DT_MASK) == DT_FEMPTY) {
 		dma_rmb();
+
 		skb = gq->skbs[gq->dirty];
 		if (skb) {
+			rdev->ndev->stats.tx_packets++;
+			rdev->ndev->stats.tx_bytes += skb->len;
 			dma_unmap_single(ndev->dev.parent,
 					 gq->unmap_addrs[gq->dirty],
 					 skb->len, DMA_TO_DEVICE);
 			dev_kfree_skb_any(gq->skbs[gq->dirty]);
 			gq->skbs[gq->dirty] = NULL;
-			rdev->ndev->stats.tx_packets++;
-			rdev->ndev->stats.tx_bytes += skb->len;
 		}
+
 		desc->desc.die_dt = DT_EEMPTY;
+		gq->dirty = rswitch_next_queue_index(gq, false, 1);
+		desc = &gq->tx_ring[gq->dirty];
 	}
 }
 
@@ -908,8 +907,10 @@
 
 	if (napi_complete_done(napi, budget - quota)) {
 		spin_lock_irqsave(&priv->lock, flags);
-		rswitch_enadis_data_irq(priv, rdev->tx_queue->index, true);
-		rswitch_enadis_data_irq(priv, rdev->rx_queue->index, true);
+		if (test_bit(rdev->port, priv->opened_ports)) {
+			rswitch_enadis_data_irq(priv, rdev->tx_queue->index, true);
+			rswitch_enadis_data_irq(priv, rdev->rx_queue->index, true);
+		}
 		spin_unlock_irqrestore(&priv->lock, flags);
 	}
 
@@ -1001,9 +1002,10 @@
 static void rswitch_ts(struct rswitch_private *priv)
 {
 	struct rswitch_gwca_queue *gq = &priv->gwca.ts_queue;
-	struct rswitch_gwca_ts_info *ts_info, *ts_info2;
 	struct skb_shared_hwtstamps shhwtstamps;
 	struct rswitch_ts_desc *desc;
+	struct rswitch_device *rdev;
+	struct sk_buff *ts_skb;
 	struct timespec64 ts;
 	unsigned int num;
 	u32 tag, port;
@@ -1013,23 +1015,28 @@
 		dma_rmb();
 
 		port = TS_DESC_DPN(__le32_to_cpu(desc->desc.dptrl));
-		tag = TS_DESC_TSUN(__le32_to_cpu(desc->desc.dptrl));
-
-		list_for_each_entry_safe(ts_info, ts_info2, &priv->gwca.ts_info_list, list) {
-			if (!(ts_info->port == port && ts_info->tag == tag))
-				continue;
+		if (unlikely(port >= RSWITCH_NUM_PORTS))
+			goto next;
+		rdev = priv->rdev[port];
 
-			memset(&shhwtstamps, 0, sizeof(shhwtstamps));
-			ts.tv_sec = __le32_to_cpu(desc->ts_sec);
-			ts.tv_nsec = __le32_to_cpu(desc->ts_nsec & cpu_to_le32(0x3fffffff));
-			shhwtstamps.hwtstamp = timespec64_to_ktime(ts);
-			skb_tstamp_tx(ts_info->skb, &shhwtstamps);
-			dev_consume_skb_irq(ts_info->skb);
-			list_del(&ts_info->list);
-			kfree(ts_info);
-			break;
-		}
+		tag = TS_DESC_TSUN(__le32_to_cpu(desc->desc.dptrl));
+		if (unlikely(tag >= TS_TAGS_PER_PORT))
+			goto next;
+		ts_skb = xchg(&rdev->ts_skb[tag], NULL);
+		smp_mb(); /* order rdev->ts_skb[] read before bitmap update */
+		clear_bit(tag, rdev->ts_skb_used);
+
+		if (unlikely(!ts_skb))
+			goto next;
+
+		memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+		ts.tv_sec = __le32_to_cpu(desc->ts_sec);
+		ts.tv_nsec = __le32_to_cpu(desc->ts_nsec & cpu_to_le32(0x3fffffff));
+		shhwtstamps.hwtstamp = timespec64_to_ktime(ts);
+		skb_tstamp_tx(ts_skb, &shhwtstamps);
+		dev_consume_skb_irq(ts_skb);
 
+next:
 		gq->cur = rswitch_next_queue_index(gq, true, 1);
 		desc = &gq->ts_ring[gq->cur];
 	}
@@ -1114,25 +1121,40 @@
 
 static void rswitch_rmac_setting(struct rswitch_etha *etha, const u8 *mac)
 {
-	u32 val;
+	u32 pis, lsc;
 
 	rswitch_etha_write_mac_address(etha, mac);
 
+	switch (etha->phy_interface) {
+	case PHY_INTERFACE_MODE_SGMII:
+		pis = MPIC_PIS_GMII;
+		break;
+	case PHY_INTERFACE_MODE_USXGMII:
+	case PHY_INTERFACE_MODE_5GBASER:
+		pis = MPIC_PIS_XGMII;
+		break;
+	default:
+		pis = FIELD_GET(MPIC_PIS, ioread32(etha->addr + MPIC));
+		break;
+	}
+
 	switch (etha->speed) {
 	case 100:
-		val = MPIC_LSC_100M;
+		lsc = MPIC_LSC_100M;
 		break;
 	case 1000:
-		val = MPIC_LSC_1G;
+		lsc = MPIC_LSC_1G;
 		break;
 	case 2500:
-		val = MPIC_LSC_2_5G;
+		lsc = MPIC_LSC_2_5G;
 		break;
 	default:
-		return;
+		lsc = FIELD_GET(MPIC_LSC, ioread32(etha->addr + MPIC));
+		break;
 	}
 
-	iowrite32(MPIC_PIS_GMII | val, etha->addr + MPIC);
+	rswitch_modify(etha->addr, MPIC, MPIC_PIS | MPIC_LSC,
+		       FIELD_PREP(MPIC_PIS, pis) | FIELD_PREP(MPIC_LSC, lsc));
 }
 
 static void rswitch_etha_enable_mii(struct rswitch_etha *etha)
@@ -1538,20 +1560,20 @@
 	struct rswitch_device *rdev = netdev_priv(ndev);
 	unsigned long flags;
 
-	phy_start(ndev->phydev);
+	if (bitmap_empty(rdev->priv->opened_ports, RSWITCH_NUM_PORTS))
+		iowrite32(GWCA_TS_IRQ_BIT, rdev->priv->addr + GWTSDIE);
 
 	napi_enable(&rdev->napi);
-	netif_start_queue(ndev);
 
 	spin_lock_irqsave(&rdev->priv->lock, flags);
+	bitmap_set(rdev->priv->opened_ports, rdev->port, 1);
 	rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, true);
 	rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, true);
 	spin_unlock_irqrestore(&rdev->priv->lock, flags);
 
-	if (bitmap_empty(rdev->priv->opened_ports, RSWITCH_NUM_PORTS))
-		iowrite32(GWCA_TS_IRQ_BIT, rdev->priv->addr + GWTSDIE);
+	phy_start(ndev->phydev);
 
-	bitmap_set(rdev->priv->opened_ports, rdev->port, 1);
+	netif_start_queue(ndev);
 
 	return 0;
 };
@@ -1559,31 +1581,34 @@
 static int rswitch_stop(struct net_device *ndev)
 {
 	struct rswitch_device *rdev = netdev_priv(ndev);
-	struct rswitch_gwca_ts_info *ts_info, *ts_info2;
+	struct sk_buff *ts_skb;
 	unsigned long flags;
+	unsigned int tag;
 
 	netif_tx_stop_all_queues(ndev);
-	bitmap_clear(rdev->priv->opened_ports, rdev->port, 1);
 
-	if (bitmap_empty(rdev->priv->opened_ports, RSWITCH_NUM_PORTS))
-		iowrite32(GWCA_TS_IRQ_BIT, rdev->priv->addr + GWTSDID);
-
-	list_for_each_entry_safe(ts_info, ts_info2, &rdev->priv->gwca.ts_info_list, list) {
-		if (ts_info->port != rdev->port)
-			continue;
-		dev_kfree_skb_irq(ts_info->skb);
-		list_del(&ts_info->list);
-		kfree(ts_info);
-	}
+	phy_stop(ndev->phydev);
 
 	spin_lock_irqsave(&rdev->priv->lock, flags);
 	rswitch_enadis_data_irq(rdev->priv, rdev->tx_queue->index, false);
 	rswitch_enadis_data_irq(rdev->priv, rdev->rx_queue->index, false);
+	bitmap_clear(rdev->priv->opened_ports, rdev->port, 1);
 	spin_unlock_irqrestore(&rdev->priv->lock, flags);
 
-	phy_stop(ndev->phydev);
 	napi_disable(&rdev->napi);
 
+	if (bitmap_empty(rdev->priv->opened_ports, RSWITCH_NUM_PORTS))
+		iowrite32(GWCA_TS_IRQ_BIT, rdev->priv->addr + GWTSDID);
+
+	for (tag = find_first_bit(rdev->ts_skb_used, TS_TAGS_PER_PORT);
+	     tag < TS_TAGS_PER_PORT;
+	     tag = find_next_bit(rdev->ts_skb_used, TS_TAGS_PER_PORT, tag + 1)) {
+		ts_skb = xchg(&rdev->ts_skb[tag], NULL);
+		clear_bit(tag, rdev->ts_skb_used);
+		if (ts_skb)
+			dev_kfree_skb(ts_skb);
+	}
+
 	return 0;
 };
 
@@ -1594,20 +1619,17 @@
 	desc->info1 = cpu_to_le64(INFO1_DV(BIT(rdev->etha->index)) |
 				  INFO1_IPV(GWCA_IPV_NUM) | INFO1_FMT);
 	if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
-		struct rswitch_gwca_ts_info *ts_info;
+		unsigned int tag;
 
-		ts_info = kzalloc(sizeof(*ts_info), GFP_ATOMIC);
-		if (!ts_info)
+		tag = find_first_zero_bit(rdev->ts_skb_used, TS_TAGS_PER_PORT);
+		if (tag == TS_TAGS_PER_PORT)
 			return false;
+		smp_mb(); /* order bitmap read before rdev->ts_skb[] write */
+		rdev->ts_skb[tag] = skb_get(skb);
+		set_bit(tag, rdev->ts_skb_used);
 
 		skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
-		rdev->ts_tag++;
-		desc->info1 |= cpu_to_le64(INFO1_TSUN(rdev->ts_tag) | INFO1_TXC);
-
-		ts_info->skb = skb_get(skb);
-		ts_info->port = rdev->port;
-		ts_info->tag = rdev->ts_tag;
-		list_add_tail(&ts_info->list, &rdev->priv->gwca.ts_info_list);
+		desc->info1 |= cpu_to_le64(INFO1_TSUN(tag) | INFO1_TXC);
 
 		skb_tx_timestamp(skb);
 	}
@@ -1681,8 +1703,11 @@
 	if (dma_mapping_error(ndev->dev.parent, dma_addr_orig))
 		goto err_kfree;
 
-	gq->skbs[gq->cur] = skb;
-	gq->unmap_addrs[gq->cur] = dma_addr_orig;
+	/* Stored the skb at the last descriptor to avoid skb free before hardware completes send */
+	gq->skbs[(gq->cur + nr_desc - 1) % gq->ring_size] = skb;
+	gq->unmap_addrs[(gq->cur + nr_desc - 1) % gq->ring_size] = dma_addr_orig;
+
+	dma_wmb();
 
 	/* DT_FSTART should be set at last. So, this is reverse order. */
 	for (i = nr_desc; i-- > 0; ) {
@@ -1694,14 +1719,13 @@
 			goto err_unmap;
 	}
 
-	wmb();	/* gq->cur must be incremented after die_dt was set */
-
 	gq->cur = rswitch_next_queue_index(gq, true, nr_desc);
 	rswitch_modify(rdev->addr, GWTRC(gq->index), 0, BIT(gq->index % 32));
 
 	return ret;
 
 err_unmap:
+	gq->skbs[(gq->cur + nr_desc - 1) % gq->ring_size] = NULL;
 	dma_unmap_single(ndev->dev.parent, dma_addr_orig, skb->len, DMA_TO_DEVICE);
 
 err_kfree:
@@ -1891,7 +1915,6 @@
 	rdev->np_port = rswitch_get_port_node(rdev);
 	rdev->disabled = !rdev->np_port;
 	err = of_get_ethdev_address(rdev->np_port, ndev);
-	of_node_put(rdev->np_port);
 	if (err) {
 		if (is_valid_ether_addr(rdev->etha->mac_addr))
 			eth_hw_addr_set(ndev, rdev->etha->mac_addr);
@@ -1921,6 +1944,7 @@
 
 out_rxdmac:
 out_get_params:
+	of_node_put(rdev->np_port);
 	netif_napi_del(&rdev->napi);
 	free_netdev(ndev);
 
@@ -1934,6 +1958,7 @@
 
 	rswitch_txdmac_free(ndev);
 	rswitch_rxdmac_free(ndev);
+	of_node_put(rdev->np_port);
 	netif_napi_del(&rdev->napi);
 	free_netdev(ndev);
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/renesas/rswitch.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/renesas/rswitch.h
@@ -724,13 +724,13 @@
 
 #define EAVCC_VEM_SC_TAG	(0x3 << 16)
 
-#define MPIC_PIS_MII		0x00
-#define MPIC_PIS_GMII		0x02
-#define MPIC_PIS_XGMII		0x04
-#define MPIC_LSC_SHIFT		3
-#define MPIC_LSC_100M		(1 << MPIC_LSC_SHIFT)
-#define MPIC_LSC_1G		(2 << MPIC_LSC_SHIFT)
-#define MPIC_LSC_2_5G		(3 << MPIC_LSC_SHIFT)
+#define MPIC_PIS		GENMASK(2, 0)
+#define MPIC_PIS_GMII		2
+#define MPIC_PIS_XGMII		4
+#define MPIC_LSC		GENMASK(5, 3)
+#define MPIC_LSC_100M		1
+#define MPIC_LSC_1G		2
+#define MPIC_LSC_2_5G		3
 
 #define MDIO_READ_C45		0x03
 #define MDIO_WRITE_C45		0x01
@@ -972,14 +972,6 @@
 	};
 };
 
-struct rswitch_gwca_ts_info {
-	struct sk_buff *skb;
-	struct list_head list;
-
-	int port;
-	u8 tag;
-};
-
 #define RSWITCH_NUM_IRQ_REGS	(RSWITCH_MAX_NUM_QUEUES / BITS_PER_TYPE(u32))
 struct rswitch_gwca {
 	unsigned int index;
@@ -989,7 +981,6 @@
 	struct rswitch_gwca_queue *queues;
 	int num_queues;
 	struct rswitch_gwca_queue ts_queue;
-	struct list_head ts_info_list;
 	DECLARE_BITMAP(used, RSWITCH_MAX_NUM_QUEUES);
 	u32 tx_irq_bits[RSWITCH_NUM_IRQ_REGS];
 	u32 rx_irq_bits[RSWITCH_NUM_IRQ_REGS];
@@ -997,6 +988,7 @@
 };
 
 #define NUM_QUEUES_PER_NDEV	2
+#define TS_TAGS_PER_PORT	256
 struct rswitch_device {
 	struct rswitch_private *priv;
 	struct net_device *ndev;
@@ -1004,7 +996,8 @@
 	void __iomem *addr;
 	struct rswitch_gwca_queue *tx_queue;
 	struct rswitch_gwca_queue *rx_queue;
-	u8 ts_tag;
+	struct sk_buff *ts_skb[TS_TAGS_PER_PORT];
+	DECLARE_BITMAP(ts_skb_used, TS_TAGS_PER_PORT);
 	bool disabled;
 
 	int port;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/renesas/sh_eth.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/renesas/sh_eth.c
@@ -50,7 +50,7 @@
  * the macros available to do this only define GCC 8.
  */
 __diag_push();
-__diag_ignore(GCC, 8, "-Woverride-init",
+__diag_ignore_all("-Woverride-init",
 	      "logic to initialize all and then override some is OK");
 static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
 	SH_ETH_OFFSET_DEFAULTS,
@@ -3494,10 +3494,12 @@
 
 	netif_device_detach(ndev);
 
+	rtnl_lock();
 	if (mdp->wol_enabled)
 		ret = sh_eth_wol_setup(ndev);
 	else
 		ret = sh_eth_close(ndev);
+	rtnl_unlock();
 
 	return ret;
 }
@@ -3511,10 +3513,12 @@
 	if (!netif_running(ndev))
 		return 0;
 
+	rtnl_lock();
 	if (mdp->wol_enabled)
 		ret = sh_eth_wol_restore(ndev);
 	else
 		ret = sh_eth_open(ndev);
+	rtnl_unlock();
 
 	if (ret < 0)
 		return ret;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/rocker/rocker_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/rocker/rocker_main.c
@@ -2504,7 +2504,7 @@
 	u64 link_status = rocker_read64(rocker, PORT_PHYS_LINK_STATUS);
 	bool link_up;
 
-	link_up = link_status & (1 << rocker_port->pport);
+	link_up = link_status & (1ULL << rocker_port->pport);
 	if (link_up)
 		netif_carrier_on(rocker_port->dev);
 	else
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/seeq/ether3.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/seeq/ether3.c
@@ -847,9 +847,11 @@
 {
 	struct net_device *dev = ecard_get_drvdata(ec);
 
+	ether3_outw(priv(dev)->regs.config2 |= CFG2_CTRLO, REG_CONFIG2);
 	ecard_set_drvdata(ec, NULL);
 
 	unregister_netdev(dev);
+	del_timer_sync(&priv(dev)->timer);
 	free_netdev(dev);
 	ecard_release_resources(ec);
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/sfc/ef100_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/sfc/ef100_ethtool.c
@@ -59,6 +59,7 @@
 
 	.get_rxfh_indir_size	= efx_ethtool_get_rxfh_indir_size,
 	.get_rxfh_key_size	= efx_ethtool_get_rxfh_key_size,
+	.cap_rss_rxnfc_adds	= true,
 	.get_rxfh		= efx_ethtool_get_rxfh,
 	.set_rxfh		= efx_ethtool_set_rxfh,
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/sfc/ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/sfc/ethtool.c
@@ -268,6 +268,7 @@
 	.set_rxnfc		= efx_ethtool_set_rxnfc,
 	.get_rxfh_indir_size	= efx_ethtool_get_rxfh_indir_size,
 	.get_rxfh_key_size	= efx_ethtool_get_rxfh_key_size,
+	.cap_rss_rxnfc_adds	= true,
 	.get_rxfh		= efx_ethtool_get_rxfh,
 	.set_rxfh		= efx_ethtool_set_rxfh,
 	.get_ts_info		= efx_ethtool_get_ts_info,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/sfc/tc_conntrack.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/sfc/tc_conntrack.c
@@ -16,7 +16,7 @@
 			     void *cb_priv);
 
 static const struct rhashtable_params efx_tc_ct_zone_ht_params = {
-	.key_len	= offsetof(struct efx_tc_ct_zone, linkage),
+	.key_len	= sizeof_field(struct efx_tc_ct_zone, zone),
 	.key_offset	= 0,
 	.head_offset	= offsetof(struct efx_tc_ct_zone, linkage),
 };
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/smsc/smc91x.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/smsc/smc91x.h
@@ -156,8 +156,8 @@
 		writew(*wp++, a);
 }
 
-#define SMC_inw(a, r)		_swapw(readw((a) + (r)))
-#define SMC_outw(lp, v, a, r)	writew(_swapw(v), (a) + (r))
+#define SMC_inw(a, r)		ioread16be((a) + (r))
+#define SMC_outw(lp, v, a, r)	iowrite16be(v, (a) + (r))
 #define SMC_insw(a, r, p, l)	mcf_insw(a + r, p, l)
 #define SMC_outsw(a, r, p, l)	mcf_outsw(a + r, p, l)
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -165,9 +165,9 @@
 	help
 	  Support for ethernet controllers on StarFive RISC-V SoCs
 
-	  This selects the StarFive platform specific glue layer support for
-	  the stmmac device driver. This driver is used for StarFive JH7110
-	  ethernet controller.
+	  This selects the StarFive platform specific glue layer support
+	  for the stmmac device driver. This driver is used for the
+	  StarFive JH7100 and JH7110 ethernet controllers.
 
 config DWMAC_STI
 	tristate "STi GMAC support"
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -6,7 +6,7 @@
 	      mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o	\
 	      dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
 	      stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o dwxgmac2_descs.o \
-	      stmmac_xdp.o stmmac_est.o \
+	      stmmac_xdp.o stmmac_est.o dw25gmac.o \
 	      $(stmmac-y)
 
 stmmac-$(CONFIG_STMMAC_SELFTESTS) += stmmac_selftests.o
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/common.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -37,9 +37,11 @@
 #define DWXGMAC_CORE_2_10	0x21
 #define DWXGMAC_CORE_2_20	0x22
 #define DWXLGMAC_CORE_2_00	0x20
+#define DW25GMAC_CORE_4_00	0x40
 
 /* Device ID */
 #define DWXGMAC_ID		0x76
+#define DW25GMAC_ID		0x55
 #define DWXLGMAC_ID		0x27
 
 #define STMMAC_CHAN0	0	/* Always supported and default for all chips */
@@ -194,6 +196,7 @@
 	unsigned long pcs_link;
 	unsigned long pcs_duplex;
 	unsigned long pcs_speed;
+	unsigned long pcs_err_count;
 	/* debug register */
 	unsigned long mtl_tx_status_fifo_full;
 	unsigned long mtl_tx_fifo_not_empty;
@@ -225,6 +228,8 @@
 	unsigned long mtl_est_hlbf;
 	unsigned long mtl_est_btre;
 	unsigned long mtl_est_btrlm;
+	unsigned long max_sdu_txq_drop[MTL_MAX_TX_QUEUES];
+	unsigned long mtl_est_txq_hlbf[MTL_MAX_TX_QUEUES];
 	/* per queue statistics */
 	struct stmmac_txq_stats txq_stats[MTL_MAX_TX_QUEUES];
 	struct stmmac_rxq_stats rxq_stats[MTL_MAX_RX_QUEUES];
@@ -369,6 +374,7 @@
 	REQ_IRQ_ERR_ALL,
 	REQ_IRQ_ERR_TX,
 	REQ_IRQ_ERR_RX,
+	REQ_IRQ_ERR_SFTY,
 	REQ_IRQ_ERR_SFTY_UE,
 	REQ_IRQ_ERR_SFTY_CE,
 	REQ_IRQ_ERR_LPI,
@@ -550,6 +556,7 @@
 extern const struct stmmac_mode_ops dwmac4_ring_mode_ops;
 
 struct mac_link {
+	u32 caps;
 	u32 speed_mask;
 	u32 speed10;
 	u32 speed100;
@@ -560,6 +567,7 @@
 		u32 speed2500;
 		u32 speed5000;
 		u32 speed10000;
+		u32 speed25000;
 	} xgmii;
 	struct {
 		u32 speed25000;
@@ -590,7 +598,7 @@
 	const struct stmmac_mmc_ops *mmc;
 	const struct stmmac_est_ops *est;
 	struct dw_xpcs *xpcs;
-	struct phylink_pcs *lynx_pcs; /* Lynx external PCS */
+	struct phylink_pcs *phylink_pcs;
 	struct mii_regs mii;	/* MII register Addresses */
 	struct mac_link link;
 	void __iomem *pcsr;     /* vpointer to device CSRs */
@@ -618,6 +626,7 @@
 int dwmac1000_setup(struct stmmac_priv *priv);
 int dwmac4_setup(struct stmmac_priv *priv);
 int dwxgmac2_setup(struct stmmac_priv *priv);
+int dw25gmac_setup(struct stmmac_priv *priv);
 int dwxlgmac2_setup(struct stmmac_priv *priv);
 
 void stmmac_set_mac_addr(void __iomem *ioaddr, const u8 addr[6],
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dw25gmac.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dw25gmac.c
@@ -0,0 +1,238 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 Broadcom Corporation
+ */
+#include "stmmac.h"
+#include "dwxgmac2.h"
+#include "dw25gmac.h"
+
+u32 dw25gmac_decode_vdma_count(u32 regval)
+{
+	/* compressed encoding for vdma count */
+	if (regval < 16) /* Direct mapping */
+		return regval + 1;
+	else if (regval < 20) /* 20, 24, 28, 32 */
+		return 20 + (regval - 16) * 4;
+	else if (regval < 24) /* 40, 48, 56, 64 */
+		return 40 + (regval - 20) * 8;
+	else if (regval < 28) /* 80, 96, 112, 128 */
+		return 80 + (regval - 24) * 16;
+	else  /* not defined */
+		return 0;
+}
+
+static int dw25gmac_dma_ops_wait(void __iomem *ioaddr)
+{
+	u32 value;
+
+	if (readl_poll_timeout(ioaddr + XXVGMAC_DMA_CH_IND_CONTROL, value,
+			       !(value & XGMAC_OB), 10, 200))
+		return -EBUSY;
+
+	return 0;
+}
+
+static int rd_dma_ch_ind(void __iomem *ioaddr, u8 mode, u32 channel)
+{
+	u32 reg_val = 0;
+
+	reg_val |= FIELD_PREP(XXVGMAC_MODE_SELECT, mode);
+	reg_val |= FIELD_PREP(XXVGMAC_ADDR_OFFSET, channel);
+	reg_val |= XXVGMAC_CMD_TYPE | XXVGMAC_OB;
+	writel(reg_val, ioaddr + XXVGMAC_DMA_CH_IND_CONTROL);
+	dw25gmac_dma_ops_wait(ioaddr);
+	return readl(ioaddr + XXVGMAC_DMA_CH_IND_DATA);
+}
+
+static void wr_dma_ch_ind(void __iomem *ioaddr, u8 mode, u32 channel, u32 val)
+{
+	u32 reg_val = 0;
+
+	writel(val, ioaddr + XXVGMAC_DMA_CH_IND_DATA);
+	reg_val |= FIELD_PREP(XXVGMAC_MODE_SELECT, mode);
+	reg_val |= FIELD_PREP(XXVGMAC_ADDR_OFFSET, channel);
+	reg_val |= XGMAC_OB;
+	writel(reg_val, ioaddr + XXVGMAC_DMA_CH_IND_CONTROL);
+	dw25gmac_dma_ops_wait(ioaddr);
+}
+
+void dw25gmac_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr,
+		       struct stmmac_dma_cfg *dma_cfg, int atds)
+{
+	u32 tx_pdmas, rx_pdmas;
+	u32 hw_cap;
+	u32 value;
+	u32 i;
+	int ret;
+
+	ret = readl_poll_timeout(ioaddr + XGMAC_DMA_MODE, value,
+				 (value & XGMAC_HMIC), 10, 200);
+
+	value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE);
+	value &= ~(XGMAC_AAL | XGMAC_EAME);
+	if (dma_cfg->aal)
+		value |= XGMAC_AAL;
+	if (dma_cfg->eame)
+		value |= XGMAC_EAME;
+	writel(value, ioaddr + XGMAC_DMA_SYSBUS_MODE);
+
+	/* Get PDMA counts etither from the device-tree or the HW */
+	hw_cap = readl(ioaddr + XGMAC_HW_FEATURE2);
+	tx_pdmas = (priv->plat->tx_queues_to_use ? priv->plat->tx_queues_to_use :
+		   FIELD_GET(XGMAC_HWFEAT_TXQCNT, hw_cap) + 1);
+	rx_pdmas = (priv->plat->rx_queues_to_use ? priv->plat->rx_queues_to_use :
+		   FIELD_GET(XGMAC_HWFEAT_RXQCNT, hw_cap) + 1);
+
+	/* Initialize all PDMAs with burst length fields */
+	for (i = 0; i < tx_pdmas; i++) {
+		value = rd_dma_ch_ind(ioaddr, MODE_TXEXTCFG, i);
+		value &= ~(XXVGMAC_TXPBL | XXVGMAC_TPBLX8_MODE);
+		if (dma_cfg->pblx8)
+			value |= XXVGMAC_TPBLX8_MODE;
+		value |= FIELD_PREP(XXVGMAC_TXPBL, dma_cfg->pbl);
+		wr_dma_ch_ind(ioaddr, MODE_TXEXTCFG, i, value);
+	}
+
+	for (i = 0; i < rx_pdmas; i++) {
+		value = rd_dma_ch_ind(ioaddr, MODE_RXEXTCFG, i);
+		value &= ~(XXVGMAC_RXPBL | XXVGMAC_RPBLX8_MODE);
+		if (dma_cfg->pblx8)
+			value |= XXVGMAC_RPBLX8_MODE;
+		value |= FIELD_PREP(XXVGMAC_RXPBL, dma_cfg->pbl);
+		wr_dma_ch_ind(ioaddr, MODE_RXEXTCFG, i, value);
+	}
+}
+
+void dw25gmac_dma_init_tx_chan(struct stmmac_priv *priv,
+			       void __iomem *ioaddr,
+			       struct stmmac_dma_cfg *dma_cfg,
+			       dma_addr_t dma_addr, u32 chan)
+{
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+	u32 tc = (dma_cfg->tx_pdma_custom_map ? dma_cfg->tx_pdma_map[chan] : chan);
+	u32 value;
+
+	/* Descriptor cache size and prefetch threshold size */
+	value = rd_dma_ch_ind(ioaddr, MODE_TXDESCCTRL, chan);
+	value &= ~XXVGMAC_TXDCSZ;
+	value |= FIELD_PREP(XXVGMAC_TXDCSZ,
+			    dma_cfg->txdcsz);
+	value &= ~XXVGMAC_TDPS;
+	value |= FIELD_PREP(XXVGMAC_TDPS, dma_cfg->tdps);
+	wr_dma_ch_ind(ioaddr, MODE_TXDESCCTRL, chan, value);
+
+	/* PDMA to TC mapping */
+	value = rd_dma_ch_ind(ioaddr, MODE_TXEXTCFG, chan);
+	value &= ~XXVGMAC_TP2TCMP;
+	value |= FIELD_PREP(XXVGMAC_TP2TCMP, tc);
+	if (dma_cfg->orrq)
+		value |= FIELD_PREP(XXVGMAC_ORRQ, dma_cfg->orrq);
+	wr_dma_ch_ind(ioaddr, MODE_TXEXTCFG, chan, value);
+
+	/* VDMA to TC mapping */
+	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan));
+	value &= ~XXVGMAC_TVDMA2TCMP;
+	value |= FIELD_PREP(XXVGMAC_TVDMA2TCMP, tc);
+	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan));
+
+	writel(upper_32_bits(dma_addr),
+	       ioaddr + XGMAC_DMA_CH_TxDESC_HADDR(dwxgmac_addrs, chan));
+	writel(lower_32_bits(dma_addr),
+	       ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(dwxgmac_addrs, chan));
+}
+
+void dw25gmac_dma_init_rx_chan(struct stmmac_priv *priv,
+			       void __iomem *ioaddr,
+			       struct stmmac_dma_cfg *dma_cfg,
+			       dma_addr_t dma_addr, u32 chan)
+{
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+	u32 tc = (dma_cfg->rx_pdma_custom_map ? dma_cfg->rx_pdma_map[chan] : chan);
+	u32 value;
+
+	/* Descriptor cache size and prefetch threshold size */
+	value = rd_dma_ch_ind(ioaddr, MODE_RXDESCCTRL, chan);
+	value &= ~XXVGMAC_RXDCSZ;
+	value |= FIELD_PREP(XXVGMAC_RXDCSZ,
+			    dma_cfg->rxdcsz);
+	value &= ~XXVGMAC_RDPS;
+	value |= FIELD_PREP(XXVGMAC_RDPS, dma_cfg->rdps);
+	wr_dma_ch_ind(ioaddr, MODE_RXDESCCTRL, chan, value);
+
+	/* PDMA to TC mapping */
+	value = rd_dma_ch_ind(ioaddr, MODE_RXEXTCFG, chan);
+	value &= ~XXVGMAC_RP2TCMP;
+	value |= FIELD_PREP(XXVGMAC_RP2TCMP, tc);
+	if (dma_cfg->owrq)
+		value |= FIELD_PREP(XXVGMAC_OWRQ, dma_cfg->owrq);
+	value |= XXVGMAC_RXPEN;
+	wr_dma_ch_ind(ioaddr, MODE_RXEXTCFG, chan, value);
+
+	/* VDMA to TC mapping */
+	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(dwxgmac_addrs, chan));
+	value &= ~XXVGMAC_RVDMA2TCMP;
+	value |= FIELD_PREP(XXVGMAC_RVDMA2TCMP, tc);
+	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(dwxgmac_addrs, chan));
+
+	writel(upper_32_bits(dma_addr),
+	       ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(dwxgmac_addrs, chan));
+	writel(lower_32_bits(dma_addr),
+	       ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(dwxgmac_addrs, chan));
+}
+
+void dw25gmac_dma_map_tx_offline_chan(struct stmmac_priv *priv,
+				      void __iomem *ioaddr,
+				      struct stmmac_dma_cfg *dma_cfg,
+				      u32 chan)
+{
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+	u32 tc = (dma_cfg->tx_pdma_custom_map ? dma_cfg->tx_pdma_map[chan] : chan);
+	u32 value;
+
+	/* PDMA to TC mapping for channels that are offline */
+	value = rd_dma_ch_ind(ioaddr, MODE_TXEXTCFG, chan);
+	value &= ~XXVGMAC_TP2TCMP;
+	value |= FIELD_PREP(XXVGMAC_TP2TCMP, tc);
+	wr_dma_ch_ind(ioaddr, MODE_TXEXTCFG, chan, value);
+
+	/* VDMA to TC mapping for channels that are offline */
+	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan));
+	value &= ~XXVGMAC_TVDMA2TCMP;
+	value |= FIELD_PREP(XXVGMAC_TVDMA2TCMP, tc);
+	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan));
+}
+
+void dw25gmac_dma_map_rx_offline_chan(struct stmmac_priv *priv,
+				      void __iomem *ioaddr,
+				      struct stmmac_dma_cfg *dma_cfg,
+				      u32 chan)
+{
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+	u32 tc = (dma_cfg->rx_pdma_custom_map ? dma_cfg->rx_pdma_map[chan] : chan);
+	u32 value;
+
+	/* PDMA to TC mapping for channels that are offline */
+	value = rd_dma_ch_ind(ioaddr, MODE_RXEXTCFG, chan);
+	value &= ~XXVGMAC_RP2TCMP;
+	value |= FIELD_PREP(XXVGMAC_RP2TCMP, tc);
+	wr_dma_ch_ind(ioaddr, MODE_RXEXTCFG, chan, value);
+
+	/* VDMA to TC mapping for channels that are offline */
+	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(dwxgmac_addrs, chan));
+	value &= ~XXVGMAC_RVDMA2TCMP;
+	value |= FIELD_PREP(XXVGMAC_RVDMA2TCMP, tc);
+	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(dwxgmac_addrs, chan));
+}
+
+void dw25gmac_desc_cache_compute(void __iomem *ioaddr)
+{
+	u32 value;
+	int ret;
+
+	value = readl(ioaddr + XGMAC_DMA_MODE);
+	value |= XGMAC_DSCB;
+	writel(value, ioaddr + XGMAC_DMA_MODE);
+
+	ret = readl_poll_timeout(ioaddr + XGMAC_DMA_MODE, value,
+				 !(value & XGMAC_DSCB), 10, 200);
+}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dw25gmac.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dw25gmac.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* Copyright (c) 2024 Broadcom Corporation
+ * DW25GMAC definitions.
+ */
+#ifndef __STMMAC_DW25GMAC_H__
+#define __STMMAC_DW25GMAC_H__
+
+/* Hardware features */
+#define XXVGMAC_HWFEAT_VDMA_RXCNT	GENMASK(16, 12)
+#define XXVGMAC_HWFEAT_VDMA_TXCNT	GENMASK(22, 18)
+
+/* DMA Indirect Registers*/
+#define XXVGMAC_DMA_CH_IND_CONTROL	0x00003080
+#define XXVGMAC_MODE_SELECT		GENMASK(27, 24)
+enum dma_ch_ind_modes {
+	MODE_TXEXTCFG	 = 0x0,	  /* Tx Extended Config */
+	MODE_RXEXTCFG	 = 0x1,	  /* Rx Extended Config */
+	MODE_TXDBGSTS	 = 0x2,	  /* Tx Debug Status */
+	MODE_RXDBGSTS	 = 0x3,	  /* Rx Debug Status */
+	MODE_TXDESCCTRL	 = 0x4,	  /* Tx Descriptor control */
+	MODE_RXDESCCTRL	 = 0x5,	  /* Rx Descriptor control */
+};
+
+#define XXVGMAC_ADDR_OFFSET		GENMASK(14, 8)
+#define XXVGMAC_AUTO_INCR		GENMASK(5, 4)
+#define XXVGMAC_CMD_TYPE		BIT(1)
+#define XXVGMAC_OB			BIT(0)
+#define XXVGMAC_DMA_CH_IND_DATA		0x00003084
+
+/* TX Config definitions */
+#define XXVGMAC_TXPBL			GENMASK(29, 24)
+#define XXVGMAC_TPBLX8_MODE		BIT(19)
+#define XXVGMAC_TP2TCMP			GENMASK(18, 16)
+#define XXVGMAC_ORRQ			GENMASK(13, 8)
+
+/* RX Config definitions */
+#define XXVGMAC_RXPEN			BIT(31)
+#define XXVGMAC_RXPBL			GENMASK(29, 24)
+#define XXVGMAC_RPBLX8_MODE		BIT(19)
+#define XXVGMAC_RP2TCMP			GENMASK(18, 16)
+#define XXVGMAC_OWRQ			GENMASK(13, 8)
+
+/* Tx Descriptor control */
+#define XXVGMAC_TXDCSZ			GENMASK(2, 0)
+#define XXVGMAC_TDPS			GENMASK(5, 3)
+
+/* Rx Descriptor control */
+#define XXVGMAC_RXDCSZ			GENMASK(2, 0)
+#define XXVGMAC_RDPS			GENMASK(5, 3)
+
+/* DWCXG_DMA_CH(#i) Registers*/
+#define XXVGMAC_DSL			GENMASK(20, 18)
+#define XXVGMAC_MSS			GENMASK(13, 0)
+#define XXVGMAC_TFSEL			GENMASK(30, 29)
+#define XXVGMAC_TQOS			GENMASK(27, 24)
+#define XXVGMAC_IPBL			BIT(15)
+#define XXVGMAC_TVDMA2TCMP		GENMASK(6, 4)
+#define XXVGMAC_RPF			BIT(31)
+#define XXVGMAC_RVDMA2TCMP		GENMASK(30, 28)
+#define XXVGMAC_RQOS			GENMASK(27, 24)
+
+u32 dw25gmac_decode_vdma_count(u32 regval);
+
+void dw25gmac_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr,
+		       struct stmmac_dma_cfg *dma_cfg, int atds);
+
+void dw25gmac_dma_init_tx_chan(struct stmmac_priv *priv,
+			       void __iomem *ioaddr,
+			       struct stmmac_dma_cfg *dma_cfg,
+			       dma_addr_t dma_addr, u32 chan);
+void dw25gmac_dma_init_rx_chan(struct stmmac_priv *priv,
+			       void __iomem *ioaddr,
+			       struct stmmac_dma_cfg *dma_cfg,
+			       dma_addr_t dma_addr, u32 chan);
+void dw25gmac_dma_map_tx_offline_chan(struct stmmac_priv *priv,
+				      void __iomem *ioaddr,
+				      struct stmmac_dma_cfg *dma_cfg,
+				      u32 chan);
+void dw25gmac_dma_map_rx_offline_chan(struct stmmac_priv *priv,
+				      void __iomem *ioaddr,
+				      struct stmmac_dma_cfg *dma_cfg,
+				      u32 chan);
+void dw25gmac_desc_cache_compute(void __iomem *ioaddr);
+#endif /* __STMMAC_DW25GMAC_H__ */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c
@@ -108,7 +108,12 @@
 			if (IS_ERR(dwmac->tx_clk))
 				return PTR_ERR(dwmac->tx_clk);
 
-			clk_prepare_enable(dwmac->tx_clk);
+			ret = clk_prepare_enable(dwmac->tx_clk);
+			if (ret) {
+				dev_err(&pdev->dev,
+					"Failed to enable tx_clk\n");
+				return ret;
+			}
 
 			/* Check and configure TX clock rate */
 			rate = clk_get_rate(dwmac->tx_clk);
@@ -119,7 +124,7 @@
 				if (ret) {
 					dev_err(&pdev->dev,
 						"Failed to set tx_clk\n");
-					return ret;
+					goto err_tx_clk_disable;
 				}
 			}
 		}
@@ -133,7 +138,7 @@
 			if (ret) {
 				dev_err(&pdev->dev,
 					"Failed to set clk_ptp_ref\n");
-				return ret;
+				goto err_tx_clk_disable;
 			}
 		}
 	}
@@ -149,12 +154,15 @@
 	}
 
 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
-	if (ret) {
-		clk_disable_unprepare(dwmac->tx_clk);
-		return ret;
-	}
+	if (ret)
+		goto err_tx_clk_disable;
 
 	return 0;
+
+err_tx_clk_disable:
+	if (dwmac->data->tx_clk_en)
+		clk_disable_unprepare(dwmac->tx_clk);
+	return ret;
 }
 
 static void intel_eth_plat_remove(struct platform_device *pdev)
@@ -162,7 +170,8 @@
 	struct intel_dwmac *dwmac = get_stmmac_bsp_priv(&pdev->dev);
 
 	stmmac_pltfr_remove(pdev);
-	clk_disable_unprepare(dwmac->tx_clk);
+	if (dwmac->data->tx_clk_en)
+		clk_disable_unprepare(dwmac->tx_clk);
 }
 
 static struct platform_driver intel_eth_plat_driver = {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
@@ -35,6 +35,9 @@
 	/* Disable RX queues routing by default */
 	plat->rx_queues_cfg[0].pkt_route = 0x0;
 
+	plat->clk_ref_rate = 125000000;
+	plat->clk_ptp_rate = 125000000;
+
 	/* Default to phy auto-detection */
 	plat->phy_addr = -1;
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c
@@ -589,9 +589,9 @@
 
 	plat->mac_interface = priv_plat->phy_mode;
 	if (priv_plat->mac_wol)
-		plat->flags |= STMMAC_FLAG_USE_PHY_WOL;
-	else
 		plat->flags &= ~STMMAC_FLAG_USE_PHY_WOL;
+	else
+		plat->flags |= STMMAC_FLAG_USE_PHY_WOL;
 	plat->riwt_off = 1;
 	plat->maxmtu = ETH_DATA_LEN;
 	plat->host_dma_width = priv_plat->variant->dma_bit_mask;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
@@ -7,10 +7,15 @@
 #include <linux/platform_device.h>
 #include <linux/phy.h>
 #include <linux/phy/phy.h>
+#include <linux/pcs-xpcs-qcom.h>
+#include <linux/i2c.h>
 
 #include "stmmac.h"
 #include "stmmac_platform.h"
 
+#define EEPROM_STMMAC_READ_BYTE	17
+#define EEPROM_STMMAC_WRITE_OFFSET_BYTE	2
+
 #define RGMII_IO_MACRO_CONFIG		0x0
 #define SDCC_HC_REG_DLL_CONFIG		0x4
 #define SDCC_TEST_CTL			0x8
@@ -21,12 +26,16 @@
 #define RGMII_IO_MACRO_CONFIG2		0x1C
 #define RGMII_IO_MACRO_DEBUG1		0x20
 #define EMAC_SYSTEM_LOW_POWER_DEBUG	0x28
+#define EMAC_WRAPPER_SGMII_PHY_CNTRL1	0xf4
+#define RGMII_IO_MACRO_BYPASS 0x16C
+#define EMAC_WRAPPER_SGMII_PHY_CNTRL0 0x170
+#define EMAC_WRAPPER_USXGMII_MUX_SEL 0x1D0
+#define RGMII_IO_MACRO_SCRATCH_2		0x44
+#define EMAC_WRAPPER_SGMII_PHY_CNTRL1_V4 0x174
 
 /* RGMII_IO_MACRO_CONFIG fields */
 #define RGMII_CONFIG_FUNC_CLK_EN		BIT(30)
 #define RGMII_CONFIG_POS_NEG_DATA_SEL		BIT(23)
-#define RGMII_CONFIG_GPIO_CFG_RX_INT		GENMASK(21, 20)
-#define RGMII_CONFIG_GPIO_CFG_TX_INT		GENMASK(19, 17)
 #define RGMII_CONFIG_MAX_SPD_PRG_9		GENMASK(16, 8)
 #define RGMII_CONFIG_MAX_SPD_PRG_2		GENMASK(7, 6)
 #define RGMII_CONFIG_INTF_SEL			GENMASK(5, 4)
@@ -36,6 +45,12 @@
 #define RGMII_CONFIG_DDR_MODE			BIT(0)
 #define RGMII_CONFIG_SGMII_CLK_DVDR		GENMASK(18, 10)
 
+#define RGMII_CONFIG_MAX_SPD_PRG_9_V4		GENMASK(18, 10)
+#define RGMII_CONFIG_MAX_SPD_PRG_2_V4		GENMASK(9, 6)
+
+/*RGMII IO MACRO BYPASS fields*/
+#define RGMII_BYPASS_EN		BIT(0)
+
 /* SDCC_HC_REG_DLL_CONFIG fields */
 #define SDCC_DLL_CONFIG_DLL_RST			BIT(30)
 #define SDCC_DLL_CONFIG_PDN			BIT(29)
@@ -68,6 +83,8 @@
 
 /* RGMII_IO_MACRO_CONFIG2 fields */
 #define RGMII_CONFIG2_RSVD_CONFIG15		GENMASK(31, 17)
+#define RGMII_CONFIG2_MODE_EN_VIA_GMII        BIT(21)
+#define RGMII_CONFIG2_MAX_SPD_PRG_3		GENMASK(20, 17)
 #define RGMII_CONFIG2_RGMII_CLK_SEL_CFG		BIT(16)
 #define RGMII_CONFIG2_TX_TO_RX_LOOPBACK_EN	BIT(13)
 #define RGMII_CONFIG2_CLK_DIVIDE_SEL		BIT(12)
@@ -79,6 +96,23 @@
 #define ETHQOS_MAC_CTRL_SPEED_MODE		BIT(14)
 #define ETHQOS_MAC_CTRL_PORT_SEL		BIT(15)
 
+/* EMAC_WRAPPER_SGMII_PHY_CNTRL0 bits */
+#define SGMII_PHY_CNTRL0_2P5G_1G_CLK_SEL		GENMASK(6, 5)
+
+/* EMAC_WRAPPER_SGMII_PHY_CNTRL1 bits */
+#define SGMII_PHY_CNTRL1_RGMII_SGMII_CLK_MUX_SEL BIT(0)
+#define SGMII_PHY_CNTRL1_USXGMII_GMII_MASTER_CLK_MUX_SEL BIT(4)
+#define SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN	BIT(3)
+
+/* EMAC_WRAPPER_USXGMII_MUX_SEL bits */
+#define USXGMII_CLK_BLK_GMII_CLK_BLK_SEL BIT(1)
+#define USXGMII_CLK_BLK_CLK_EN BIT(0)
+
+/* RGMII_IO_MACRO_SCRATCH_2 bits */
+#define RGMII_SCRATCH2_MAX_SPD_PRG_4		GENMASK(5, 2)
+#define RGMII_SCRATCH2_MAX_SPD_PRG_5		GENMASK(9, 6)
+#define RGMII_SCRATCH2_MAX_SPD_PRG_6		GENMASK(13, 10)
+
 #define SGMII_10M_RX_CLK_DVDR			0x31
 
 struct ethqos_emac_por {
@@ -88,12 +122,17 @@
 
 struct ethqos_emac_driver_data {
 	const struct ethqos_emac_por *por;
+	struct dwxgmac_addrs dwxgmac_addrs;
 	unsigned int num_por;
 	bool rgmii_config_loopback_en;
 	bool has_emac_ge_3;
 	const char *link_clk_name;
 	bool has_integrated_pcs;
+	u32 dma_addr_width;
 	struct dwmac4_addrs dwmac4_addrs;
+	bool needs_sgmii_loopback;
+	bool has_hdma;
+	bool has_io_macro_ge_4;
 };
 
 struct qcom_ethqos {
@@ -106,12 +145,16 @@
 	struct clk *link_clk;
 	struct phy *serdes_phy;
 	unsigned int speed;
+	int serdes_speed;
 	phy_interface_t phy_mode;
 
 	const struct ethqos_emac_por *por;
 	unsigned int num_por;
+	bool has_io_macro_ge_4;
 	bool rgmii_config_loopback_en;
 	bool has_emac_ge_3;
+	bool needs_sgmii_loopback;
+	bool needs_rx_prog_swap;
 };
 
 static int rgmii_readl(struct qcom_ethqos *ethqos, unsigned int offset)
@@ -169,6 +212,9 @@
 static void
 ethqos_update_link_clk(struct qcom_ethqos *ethqos, unsigned int speed)
 {
+	if (!phy_interface_mode_is_rgmii(ethqos->phy_mode))
+		return;
+
 	switch (speed) {
 	case SPEED_1000:
 		ethqos->link_clk_rate =  RGMII_1000_NOM_CLK_FREQ;
@@ -186,8 +232,23 @@
 	clk_set_rate(ethqos->link_clk, ethqos->link_clk_rate);
 }
 
+static void
+qcom_ethqos_set_sgmii_loopback(struct qcom_ethqos *ethqos, bool enable)
+{
+	if (ethqos->needs_sgmii_loopback &&
+	    (ethqos->phy_mode == PHY_INTERFACE_MODE_2500BASEX ||
+	     ethqos->phy_mode == PHY_INTERFACE_MODE_USXGMII))
+		rgmii_updatel(ethqos,
+			      SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN,
+			      enable ? SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN : 0,
+			      ethqos->has_io_macro_ge_4 ?
+			      EMAC_WRAPPER_SGMII_PHY_CNTRL1_V4 :
+			      EMAC_WRAPPER_SGMII_PHY_CNTRL1);
+}
+
 static void ethqos_set_func_clk_en(struct qcom_ethqos *ethqos)
 {
+	qcom_ethqos_set_sgmii_loopback(ethqos, true);
 	rgmii_updatel(ethqos, RGMII_CONFIG_FUNC_CLK_EN,
 		      RGMII_CONFIG_FUNC_CLK_EN, RGMII_IO_MACRO_CONFIG);
 }
@@ -224,6 +285,22 @@
 	.has_emac_ge_3 = false,
 };
 
+static const struct ethqos_emac_por emac_v2_3_1_por[] = {
+	{ .offset = RGMII_IO_MACRO_CONFIG,	.value = 0x00C01343 },
+	{ .offset = SDCC_HC_REG_DLL_CONFIG,	.value = 0x2004642C },
+	{ .offset = SDCC_HC_REG_DDR_CONFIG,	.value = 0x00000000 },
+	{ .offset = SDCC_HC_REG_DLL_CONFIG2,	.value = 0x00200000 },
+	{ .offset = SDCC_USR_CTL,		.value = 0x00010800 },
+	{ .offset = RGMII_IO_MACRO_CONFIG2,	.value = 0x00002060 },
+};
+
+static const struct ethqos_emac_driver_data emac_v2_3_1_data = {
+	.por = emac_v2_3_1_por,
+	.num_por = ARRAY_SIZE(emac_v2_3_1_por),
+	.rgmii_config_loopback_en = true,
+	.has_emac_ge_3 = false,
+};
+
 static const struct ethqos_emac_por emac_v3_0_0_por[] = {
 	{ .offset = RGMII_IO_MACRO_CONFIG,	.value = 0x40c01343 },
 	{ .offset = SDCC_HC_REG_DLL_CONFIG,	.value = 0x2004642c },
@@ -265,13 +342,25 @@
 	{ .offset = RGMII_IO_MACRO_CONFIG2,	.value = 0x00002060 },
 };
 
+static const struct ethqos_emac_por emac_v6_6_0_por[] = {
+	{ .offset = RGMII_IO_MACRO_CONFIG,	.value = 0xC04D03 },
+	{ .offset = SDCC_HC_REG_DLL_CONFIG,	.value = 0x2004642C },
+	{ .offset = SDCC_HC_REG_DDR_CONFIG,	.value = 0x80040800 },
+	{ .offset = SDCC_HC_REG_DLL_CONFIG2,	.value = 0x00200000 },
+	{ .offset = SDCC_USR_CTL,		.value = 0x00010800 },
+	{ .offset = RGMII_IO_MACRO_CONFIG2,	.value = 0x222060},
+	{ .offset = RGMII_IO_MACRO_SCRATCH_2, .value = 0x4c },
+};
+
 static const struct ethqos_emac_driver_data emac_v4_0_0_data = {
 	.por = emac_v4_0_0_por,
-	.num_por = ARRAY_SIZE(emac_v3_0_0_por),
+	.num_por = ARRAY_SIZE(emac_v4_0_0_por),
 	.rgmii_config_loopback_en = false,
 	.has_emac_ge_3 = true,
 	.link_clk_name = "phyaux",
 	.has_integrated_pcs = true,
+	.needs_sgmii_loopback = true,
+	.dma_addr_width = 36,
 	.dwmac4_addrs = {
 		.dma_chan = 0x00008100,
 		.dma_chan_offset = 0x1000,
@@ -290,6 +379,27 @@
 	},
 };
 
+static const struct ethqos_emac_driver_data emac_v6_6_0_data = {
+	.por = emac_v6_6_0_por,
+	.num_por = ARRAY_SIZE(emac_v6_6_0_por),
+	.rgmii_config_loopback_en = false,
+	.dma_addr_width = 40,
+	.link_clk_name = "phyaux",
+	.has_hdma = true,
+	.needs_sgmii_loopback = true,
+	.has_io_macro_ge_4 = true,
+	.dwxgmac_addrs = {
+		.dma_even_chan_base  = 0x00008500,
+		.dma_odd_chan_base = 0x00008580,
+		.dma_chan_offset = 0x00001000,
+		.mtl_chan_base = 0x00008000,
+		.mtl_chan_offset =  0x00001000,
+		.timestamp_base = 0x00007000,
+		.pps_base = 0x00007080,
+		.pps_offset = 0x10,
+	},
+};
+
 static int ethqos_dll_configure(struct qcom_ethqos *ethqos)
 {
 	struct device *dev = &ethqos->pdev->dev;
@@ -374,6 +484,7 @@
 static int ethqos_rgmii_macro_init(struct qcom_ethqos *ethqos)
 {
 	struct device *dev = &ethqos->pdev->dev;
+	int rx_prog_swap = 0;
 	int phase_shift;
 	int loopback;
 
@@ -394,6 +505,9 @@
 	else
 		loopback = 0;
 
+	if (ethqos->needs_rx_prog_swap)
+		rx_prog_swap = RGMII_CONFIG2_RX_PROG_SWAP;
+
 	/* Select RGMII, write 0 to interface select */
 	rgmii_updatel(ethqos, RGMII_CONFIG_INTF_SEL,
 		      0, RGMII_IO_MACRO_CONFIG);
@@ -457,14 +571,8 @@
 			      BIT(6), RGMII_IO_MACRO_CONFIG);
 		rgmii_updatel(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
 			      0, RGMII_IO_MACRO_CONFIG2);
-
-		if (ethqos->has_emac_ge_3)
-			rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
-				      RGMII_CONFIG2_RX_PROG_SWAP,
-				      RGMII_IO_MACRO_CONFIG2);
-		else
-			rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
-				      0, RGMII_IO_MACRO_CONFIG2);
+		rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP, rx_prog_swap,
+			      RGMII_IO_MACRO_CONFIG2);
 
 		/* Write 0x5 to PRG_RCLK_DLY_CODE */
 		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
@@ -498,13 +606,9 @@
 			      RGMII_IO_MACRO_CONFIG);
 		rgmii_updatel(ethqos, RGMII_CONFIG2_RSVD_CONFIG15,
 			      0, RGMII_IO_MACRO_CONFIG2);
-		if (ethqos->has_emac_ge_3)
-			rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
-				      RGMII_CONFIG2_RX_PROG_SWAP,
-				      RGMII_IO_MACRO_CONFIG2);
-		else
-			rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP,
-				      0, RGMII_IO_MACRO_CONFIG2);
+		rgmii_updatel(ethqos, RGMII_CONFIG2_RX_PROG_SWAP, rx_prog_swap,
+			      RGMII_IO_MACRO_CONFIG2);
+
 		/* Write 0x5 to PRG_RCLK_DLY_CODE */
 		rgmii_updatel(ethqos, SDCC_DDR_CONFIG_EXT_PRG_RCLK_DLY_CODE,
 			      (BIT(29) | BIT(27)), SDCC_HC_REG_DDR_CONFIG);
@@ -606,19 +710,39 @@
  */
 static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos)
 {
+	struct net_device *dev = platform_get_drvdata(ethqos->pdev);
+	struct stmmac_priv *priv = netdev_priv(dev);
 	int val;
 
 	val = readl(ethqos->mac_base + MAC_CTRL_REG);
 
 	switch (ethqos->speed) {
+	case SPEED_2500:
+		val &= ~ETHQOS_MAC_CTRL_PORT_SEL;
+		rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+			      RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+			      RGMII_IO_MACRO_CONFIG2);
+		if (ethqos->serdes_speed != SPEED_2500)
+			phy_set_speed(ethqos->serdes_phy, SPEED_2500);
+		ethqos->serdes_speed = SPEED_2500;
+		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 0, 0, 0);
+		break;
 	case SPEED_1000:
 		val &= ~ETHQOS_MAC_CTRL_PORT_SEL;
 		rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
 			      RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
 			      RGMII_IO_MACRO_CONFIG2);
+		if (ethqos->serdes_speed != SPEED_1000)
+			phy_set_speed(ethqos->serdes_phy, SPEED_1000);
+		ethqos->serdes_speed = SPEED_1000;
+		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
 		break;
 	case SPEED_100:
 		val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE;
+		if (ethqos->serdes_speed != SPEED_1000)
+			phy_set_speed(ethqos->serdes_phy, SPEED_1000);
+		ethqos->serdes_speed = SPEED_1000;
+		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
 		break;
 	case SPEED_10:
 		val |= ETHQOS_MAC_CTRL_PORT_SEL;
@@ -627,6 +751,10 @@
 			      FIELD_PREP(RGMII_CONFIG_SGMII_CLK_DVDR,
 					 SGMII_10M_RX_CLK_DVDR),
 			      RGMII_IO_MACRO_CONFIG);
+		if (ethqos->serdes_speed != SPEED_1000)
+			phy_set_speed(ethqos->serdes_phy, ethqos->speed);
+		ethqos->serdes_speed = SPEED_1000;
+		stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0);
 		break;
 	}
 
@@ -635,18 +763,165 @@
 	return val;
 }
 
+static void qcom_ethqos_speed_mode_2500(struct net_device *ndev, void *data)
+{
+	struct stmmac_priv *priv = netdev_priv(ndev);
+
+	priv->plat->max_speed = 2500;
+	priv->plat->phy_interface = PHY_INTERFACE_MODE_2500BASEX;
+}
+
+static int  ethqos_configure_5gbaser(struct qcom_ethqos *ethqos)
+{
+	ethqos_set_func_clk_en(ethqos);
+
+	rgmii_updatel(ethqos, RGMII_BYPASS_EN, RGMII_BYPASS_EN, RGMII_IO_MACRO_BYPASS);
+	rgmii_updatel(ethqos, SGMII_PHY_CNTRL0_2P5G_1G_CLK_SEL, BIT(5),
+		      EMAC_WRAPPER_SGMII_PHY_CNTRL0);
+	rgmii_updatel(ethqos, SGMII_PHY_CNTRL1_RGMII_SGMII_CLK_MUX_SEL, 0,
+		      EMAC_WRAPPER_SGMII_PHY_CNTRL1_V4);
+	rgmii_updatel(ethqos, SGMII_PHY_CNTRL1_USXGMII_GMII_MASTER_CLK_MUX_SEL,
+		      SGMII_PHY_CNTRL1_USXGMII_GMII_MASTER_CLK_MUX_SEL,
+		      EMAC_WRAPPER_SGMII_PHY_CNTRL1_V4);
+	rgmii_updatel(ethqos, SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN, 0,
+		      EMAC_WRAPPER_SGMII_PHY_CNTRL1_V4);
+	rgmii_updatel(ethqos, RGMII_CONFIG2_MODE_EN_VIA_GMII, 0, RGMII_IO_MACRO_CONFIG2);
+	rgmii_updatel(ethqos, USXGMII_CLK_BLK_GMII_CLK_BLK_SEL, USXGMII_CLK_BLK_GMII_CLK_BLK_SEL,
+		      EMAC_WRAPPER_USXGMII_MUX_SEL);
+	rgmii_updatel(ethqos, USXGMII_CLK_BLK_CLK_EN, 0, EMAC_WRAPPER_USXGMII_MUX_SEL);
+
+	rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_2_V4, (BIT(6) | BIT(9)),
+		      RGMII_IO_MACRO_CONFIG);
+	rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_9_V4, (BIT(10) |  BIT(14) | BIT(15)),
+		      RGMII_IO_MACRO_CONFIG);
+	rgmii_updatel(ethqos, RGMII_CONFIG2_MAX_SPD_PRG_3, (BIT(17) | BIT(20)),
+		      RGMII_IO_MACRO_CONFIG2);
+	rgmii_updatel(ethqos, RGMII_SCRATCH2_MAX_SPD_PRG_4, BIT(2),
+		      RGMII_IO_MACRO_SCRATCH_2);
+	rgmii_updatel(ethqos, RGMII_SCRATCH2_MAX_SPD_PRG_5, (BIT(6) | BIT(7)),
+		      RGMII_IO_MACRO_SCRATCH_2);
+	rgmii_updatel(ethqos, RGMII_SCRATCH2_MAX_SPD_PRG_6, 0,
+		      RGMII_IO_MACRO_SCRATCH_2);
+	rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+		      RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+		      RGMII_IO_MACRO_CONFIG2);
+
+	return 0;
+}
+
+static int ethqos_configure_usxgmii(struct qcom_ethqos *ethqos)
+{
+	unsigned int i;
+
+	/* Reset to POR values */
+	for (i = 0; i < ethqos->num_por; i++)
+		rgmii_writel(ethqos, ethqos->por[i].value,
+			     ethqos->por[i].offset);
+
+	ethqos_set_func_clk_en(ethqos);
+
+	rgmii_updatel(ethqos, RGMII_BYPASS_EN, RGMII_BYPASS_EN, RGMII_IO_MACRO_BYPASS);
+	rgmii_updatel(ethqos, RGMII_CONFIG2_MODE_EN_VIA_GMII, 0, RGMII_IO_MACRO_CONFIG2);
+	rgmii_updatel(ethqos, SGMII_PHY_CNTRL0_2P5G_1G_CLK_SEL, BIT(5),
+		      EMAC_WRAPPER_SGMII_PHY_CNTRL0);
+	rgmii_updatel(ethqos, SGMII_PHY_CNTRL1_RGMII_SGMII_CLK_MUX_SEL, 0,
+		      EMAC_WRAPPER_SGMII_PHY_CNTRL1_V4);
+	rgmii_updatel(ethqos, SGMII_PHY_CNTRL1_USXGMII_GMII_MASTER_CLK_MUX_SEL,
+		      SGMII_PHY_CNTRL1_USXGMII_GMII_MASTER_CLK_MUX_SEL,
+		      EMAC_WRAPPER_SGMII_PHY_CNTRL1_V4);
+	rgmii_updatel(ethqos, SGMII_PHY_CNTRL1_SGMII_TX_TO_RX_LOOPBACK_EN, 0,
+		      EMAC_WRAPPER_SGMII_PHY_CNTRL1_V4);
+	rgmii_updatel(ethqos, USXGMII_CLK_BLK_GMII_CLK_BLK_SEL, 0, EMAC_WRAPPER_USXGMII_MUX_SEL);
+	rgmii_updatel(ethqos, USXGMII_CLK_BLK_CLK_EN, 0, EMAC_WRAPPER_USXGMII_MUX_SEL);
+
+	switch (ethqos->speed) {
+	case SPEED_10000:
+		rgmii_updatel(ethqos, USXGMII_CLK_BLK_GMII_CLK_BLK_SEL,
+			      USXGMII_CLK_BLK_GMII_CLK_BLK_SEL,
+			      EMAC_WRAPPER_USXGMII_MUX_SEL);
+		break;
+
+	case SPEED_5000:
+		rgmii_updatel(ethqos, SGMII_PHY_CNTRL0_2P5G_1G_CLK_SEL, 0,
+			      EMAC_WRAPPER_SGMII_PHY_CNTRL0);
+		rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_2_V4, (BIT(6) | BIT(7)),
+			      RGMII_IO_MACRO_CONFIG);
+		rgmii_updatel(ethqos, RGMII_CONFIG2_MAX_SPD_PRG_3, (BIT(17) | BIT(18)),
+			      RGMII_IO_MACRO_CONFIG2);
+		break;
+
+	case SPEED_2500:
+		rgmii_updatel(ethqos, SGMII_PHY_CNTRL0_2P5G_1G_CLK_SEL, 0,
+			      EMAC_WRAPPER_SGMII_PHY_CNTRL0);
+		rgmii_updatel(ethqos, RGMII_CONFIG_SGMII_CLK_DVDR, (BIT(10) | BIT(11)),
+			      RGMII_IO_MACRO_CONFIG);
+		rgmii_updatel(ethqos, RGMII_SCRATCH2_MAX_SPD_PRG_4, (BIT(2) | BIT(3)),
+			      RGMII_IO_MACRO_SCRATCH_2);
+		rgmii_updatel(ethqos, RGMII_SCRATCH2_MAX_SPD_PRG_5, 0,
+			      RGMII_IO_MACRO_SCRATCH_2);
+		break;
+
+	case SPEED_1000:
+		rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+			      RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+			      RGMII_IO_MACRO_CONFIG2);
+		break;
+
+	case SPEED_100:
+		rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+			      RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+			      RGMII_IO_MACRO_CONFIG2);
+		rgmii_updatel(ethqos, RGMII_CONFIG_MAX_SPD_PRG_2_V4, BIT(9),
+			      RGMII_IO_MACRO_CONFIG);
+		rgmii_updatel(ethqos, RGMII_CONFIG2_MAX_SPD_PRG_3, BIT(20),
+			      RGMII_IO_MACRO_CONFIG2);
+		rgmii_updatel(ethqos, RGMII_SCRATCH2_MAX_SPD_PRG_6, BIT(10),
+			      RGMII_IO_MACRO_SCRATCH_2);
+		break;
+
+	case SPEED_10:
+		rgmii_updatel(ethqos, RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+			      RGMII_CONFIG2_RGMII_CLK_SEL_CFG,
+			      RGMII_IO_MACRO_CONFIG2);
+		break;
+
+	default:
+		dev_err(&ethqos->pdev->dev,
+			"Invalid speed %d\n", ethqos->speed);
+		return -EINVAL;
+	}
+	return 0;
+}
+
 static int ethqos_configure(struct qcom_ethqos *ethqos)
 {
 	return ethqos->configure_func(ethqos);
 }
 
-static void ethqos_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
+static void ethqos_safety_feature(struct stmmac_priv *priv, bool en)
 {
-	struct qcom_ethqos *ethqos = priv;
+	if (priv->sfty_irq > 0) {
+		if (en)
+			enable_irq(priv->sfty_irq);
+		else
+			disable_irq(priv->sfty_irq);
+	}
+}
+
+static void ethqos_fix_mac_speed(void *priv_n, unsigned int speed, unsigned int mode)
+{
+	struct qcom_ethqos *ethqos = priv_n;
+	struct net_device *dev = platform_get_drvdata(ethqos->pdev);
+	struct stmmac_priv *priv = netdev_priv(dev);
 
+	qcom_ethqos_set_sgmii_loopback(ethqos, false);
 	ethqos->speed = speed;
 	ethqos_update_link_clk(ethqos, speed);
 	ethqos_configure(ethqos);
+	if (priv->hw->phylink_pcs)
+		qcom_xpcs_link_up(priv->hw->phylink_pcs, mode,
+				  priv->plat->phy_interface, speed,
+				  DUPLEX_FULL);
 }
 
 static int qcom_ethqos_serdes_powerup(struct net_device *ndev, void *priv)
@@ -720,15 +995,135 @@
 	netdev_dbg(priv->dev, "PTP rate %d\n", plat_dat->clk_ptp_rate);
 }
 
+static void qcom_ethqos_hdma_cfg(struct plat_stmmacenet_data *plat)
+{
+	plat->dma_cfg->orrq = 15;
+	plat->dma_cfg->owrq = 15;
+	plat->dma_cfg->txdcsz = 4;
+	plat->dma_cfg->tdps = 1;
+	plat->dma_cfg->rxdcsz = 4;
+	plat->dma_cfg->rdps = 1;
+
+	plat->dma_cfg->tx_pdma_custom_map = true;
+	plat->dma_cfg->tx_pdma_map[0] = 0;
+	plat->dma_cfg->tx_pdma_map[1] = 0;
+	plat->dma_cfg->tx_pdma_map[2] = 0;
+	plat->dma_cfg->tx_pdma_map[3] = 0;
+	plat->dma_cfg->tx_pdma_map[4] = 5;
+	plat->dma_cfg->tx_pdma_map[5] = 5;
+	plat->dma_cfg->tx_pdma_map[6] = 5;
+	plat->dma_cfg->tx_pdma_map[7] = 2;
+	plat->dma_cfg->tx_pdma_map[8] = 3;
+	plat->dma_cfg->tx_pdma_map[9] = 4;
+	plat->dma_cfg->tx_pdma_map[10] = 6;
+	plat->dma_cfg->tx_pdma_map[11] = 7;
+
+	plat->dma_cfg->rx_pdma_custom_map = true;
+	plat->dma_cfg->rx_pdma_map[0] = 0;
+	plat->dma_cfg->rx_pdma_map[1] = 0;
+	plat->dma_cfg->rx_pdma_map[2] = 0;
+	plat->dma_cfg->rx_pdma_map[3] = 0;
+	plat->dma_cfg->rx_pdma_map[4] = 5;
+	plat->dma_cfg->rx_pdma_map[5] = 5;
+	plat->dma_cfg->rx_pdma_map[6] = 5;
+	plat->dma_cfg->rx_pdma_map[7] = 2;
+	plat->dma_cfg->rx_pdma_map[8] = 3;
+	plat->dma_cfg->rx_pdma_map[9] = 4;
+	plat->dma_cfg->rx_pdma_map[10] = 6;
+	plat->dma_cfg->rx_pdma_map[11] = 7;
+}
+
+static int ethqos_xpcs_init(struct stmmac_priv *priv)
+{
+	struct device_node *xpcs_node;
+
+	xpcs_node = of_parse_phandle(priv->device->of_node, "qcom-xpcs-handle", 0);
+
+	priv->hw->phylink_pcs = qcom_xpcs_create(xpcs_node, priv->plat->phy_interface);
+	if (IS_ERR_OR_NULL(priv->hw->phylink_pcs))
+		return -ENODEV;
+
+	return 0;
+}
+
+static void ethqos_xpcs_exit(struct stmmac_priv *priv)
+{
+	qcom_xpcs_destroy(priv->hw->phylink_pcs);
+}
+
+static void ethqos_xpcs_safety_stats(struct stmmac_priv *priv, unsigned long *ptr)
+{
+	if (priv->sfty_irq > 0)
+		qcom_xpcs_get_err_stats(priv->hw->phylink_pcs, ptr);
+}
+
+static int ethqos_eeprom_readmac(struct plat_stmmacenet_data *plat_dat, struct device *dev,
+	 u8 *mac_addr)
+{
+	u8 wr_data[EEPROM_STMMAC_WRITE_OFFSET_BYTE] = {0, 0};
+	u8 rd_data[EEPROM_STMMAC_READ_BYTE];
+	struct i2c_adapter *adapter;
+	int mac_id = 0, j = 0, ret;
+	struct i2c_msg msg[2];
+	char *token = NULL;
+	u8 addr[ETH_ALEN];
+	char *temp_mac_addr;
+
+	adapter = i2c_get_adapter(plat_dat->i2c_id);
+	if (!adapter) {
+		/* error, no such I2C adaptor. */
+		dev_err(dev, "Chip at i2c Invalid i2c adapter %d\n", plat_dat->i2c_id);
+		return -ENODEV;
+	}
+
+	msg[0].addr = plat_dat->eeprom_reg;
+	msg[0].len = EEPROM_STMMAC_WRITE_OFFSET_BYTE;
+	msg[0].flags = 0;
+	msg[0].buf = wr_data;
+
+	msg[1].addr = plat_dat->eeprom_reg;
+	msg[1].len = EEPROM_STMMAC_READ_BYTE;
+	msg[1].flags = I2C_M_RD;
+	msg[1].buf = rd_data;
+
+	ret = i2c_transfer(adapter, msg, 2);
+	if (ret != 2) {
+		dev_err(dev, "EEPROM I2C wrong response\n");
+		return ret;
+	} else {
+		temp_mac_addr = kmalloc(EEPROM_STMMAC_READ_BYTE, GFP_KERNEL);
+		if (!temp_mac_addr) {
+			dev_err(dev, "Memory allocation failed\n");
+			return -ENOMEM;
+		}
+
+		memcpy(temp_mac_addr, rd_data, EEPROM_STMMAC_READ_BYTE);
+		token = strsep(&temp_mac_addr, ":");
+		while (token) {
+			sscanf(token, "%x", &mac_id);
+			addr[j++] = mac_id;
+			token = strsep(&temp_mac_addr, ":");
+		}
+
+		if (is_valid_ether_addr(addr))
+			memcpy(mac_addr, addr, ETH_ALEN);
+		else
+			dev_err(dev, "invalid mac address from EEPROM\n");
+
+		kfree(temp_mac_addr);
+	}
+	return 0;
+}
+
 static int qcom_ethqos_probe(struct platform_device *pdev)
 {
-	struct device_node *np = pdev->dev.of_node;
+	struct device_node *np = pdev->dev.of_node, *root;
 	const struct ethqos_emac_driver_data *data;
 	struct plat_stmmacenet_data *plat_dat;
 	struct stmmac_resources stmmac_res;
 	struct device *dev = &pdev->dev;
 	struct qcom_ethqos *ethqos;
-	int ret;
+	int ret, i;
 
 	ret = stmmac_get_platform_resources(pdev, &stmmac_res);
 	if (ret)
@@ -750,6 +1145,15 @@
 	ret = of_get_phy_mode(np, &ethqos->phy_mode);
 	if (ret)
 		return dev_err_probe(dev, ret, "Failed to get phy mode\n");
+
+	root = of_find_node_by_path("/");
+	if (root && of_device_is_compatible(root, "qcom,sa8540p-ride"))
+		ethqos->needs_rx_prog_swap = true;
+	else
+		ethqos->needs_rx_prog_swap =
+			of_property_read_bool(np, "qcom,rx-prog-swap");
+	of_node_put(root);
+
 	switch (ethqos->phy_mode) {
 	case PHY_INTERFACE_MODE_RGMII:
 	case PHY_INTERFACE_MODE_RGMII_ID:
@@ -757,9 +1161,19 @@
 	case PHY_INTERFACE_MODE_RGMII_TXID:
 		ethqos->configure_func = ethqos_configure_rgmii;
 		break;
+	case PHY_INTERFACE_MODE_2500BASEX:
+		plat_dat->speed_mode_2500 = qcom_ethqos_speed_mode_2500;
+		fallthrough;
 	case PHY_INTERFACE_MODE_SGMII:
 		ethqos->configure_func = ethqos_configure_sgmii;
 		break;
+	case PHY_INTERFACE_MODE_5GBASER:
+		ethqos->configure_func = ethqos_configure_5gbaser;
+		break;
+	case PHY_INTERFACE_MODE_USXGMII:
+	case PHY_INTERFACE_MODE_10GBASER:
+		ethqos->configure_func = ethqos_configure_usxgmii;
+		break;
 	default:
 		dev_err(dev, "Unsupported phy mode %s\n",
 			phy_modes(ethqos->phy_mode));
@@ -777,8 +1191,10 @@
 	data = of_device_get_match_data(dev);
 	ethqos->por = data->por;
 	ethqos->num_por = data->num_por;
+	ethqos->has_io_macro_ge_4 = data->has_io_macro_ge_4;
 	ethqos->rgmii_config_loopback_en = data->rgmii_config_loopback_en;
 	ethqos->has_emac_ge_3 = data->has_emac_ge_3;
+	ethqos->needs_sgmii_loopback = data->needs_sgmii_loopback;
 
 	ethqos->link_clk = devm_clk_get(dev, data->link_clk_name ?: "rgmii");
 	if (IS_ERR(ethqos->link_clk))
@@ -799,6 +1215,7 @@
 				     "Failed to get serdes phy\n");
 
 	ethqos->speed = SPEED_1000;
+	ethqos->serdes_speed = SPEED_1000;
 	ethqos_update_link_clk(ethqos, SPEED_1000);
 	ethqos_set_func_clk_en(ethqos);
 
@@ -810,26 +1227,53 @@
 	if (ethqos->has_emac_ge_3)
 		plat_dat->dwmac4_addrs = &data->dwmac4_addrs;
 	plat_dat->pmt = 1;
+	if (plat_dat->has_xgmac) {
+		plat_dat->has_gmac4 = 0;
+		plat_dat->dwxgmac_addrs = &data->dwxgmac_addrs;
+		plat_dat->has_hdma = data->has_hdma;
+		plat_dat->insert_ts_pktid = true;
+		if (plat_dat->has_hdma)
+			qcom_ethqos_hdma_cfg(plat_dat);
+	}
+	if (of_property_present(dev->of_node, "qcom-xpcs-handle")) {
+		plat_dat->pcs_init = ethqos_xpcs_init;
+		plat_dat->pcs_exit = ethqos_xpcs_exit;
+		plat_dat->safety_irq = ethqos_safety_feature;
+		plat_dat->safety_pcs_stats = ethqos_xpcs_safety_stats;
+	}
 	if (of_property_read_bool(np, "snps,tso"))
 		plat_dat->flags |= STMMAC_FLAG_TSO_EN;
 	if (of_device_is_compatible(np, "qcom,qcs404-ethqos"))
 		plat_dat->flags |= STMMAC_FLAG_RX_CLK_RUNS_IN_LPI;
 	if (data->has_integrated_pcs)
 		plat_dat->flags |= STMMAC_FLAG_HAS_INTEGRATED_PCS;
+	if (data->dma_addr_width)
+		plat_dat->host_dma_width = data->dma_addr_width;
 
 	if (ethqos->serdes_phy) {
 		plat_dat->serdes_powerup = qcom_ethqos_serdes_powerup;
 		plat_dat->serdes_powerdown  = qcom_ethqos_serdes_powerdown;
 	}
 
+	if (plat_dat->eeprom_reg)
+		ethqos_eeprom_readmac(plat_dat, dev, stmmac_res.mac);
+
+	/* Enable TSO on queue0 and enable TBS on rest of the queues */
+	for (i = 1; i < plat_dat->tx_queues_to_use; i++)
+		plat_dat->tx_queues_cfg[i].tbs_en = 1;
+
 	return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res);
 }
 
 static const struct of_device_id qcom_ethqos_match[] = {
 	{ .compatible = "qcom,qcs404-ethqos", .data = &emac_v2_3_0_data},
+	{ .compatible = "qcom,qcs615-ethqos", .data = &emac_v2_3_1_data},
+	{ .compatible = "qcom,qcs8300-ethqos", .data = &emac_v4_0_0_data},
 	{ .compatible = "qcom,sa8775p-ethqos", .data = &emac_v4_0_0_data},
 	{ .compatible = "qcom,sc8280xp-ethqos", .data = &emac_v3_0_0_data},
 	{ .compatible = "qcom,sm8150-ethqos", .data = &emac_v2_1_0_data},
+	{ .compatible = "qcom,sa8620p-ethqos", .data = &emac_v4_0_0_data},
+	{ .compatible = "qcom,sa8797p-ethqos", .data = &emac_v6_6_0_data},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, qcom_ethqos_match);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -427,6 +427,8 @@
 	plat_dat->bsp_priv = dwmac;
 	plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
 
+	plat_dat->riwt_off = 1;
+
 	ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
 	if (ret)
 		return ret;
@@ -479,9 +481,9 @@
 			goto err_dvr_remove;
 		}
 
-		stpriv->hw->lynx_pcs = lynx_pcs_create_mdiodev(pcs_bus, 0);
-		if (IS_ERR(stpriv->hw->lynx_pcs)) {
-			ret = PTR_ERR(stpriv->hw->lynx_pcs);
+		stpriv->hw->phylink_pcs = lynx_pcs_create_mdiodev(pcs_bus, 0);
+		if (IS_ERR(stpriv->hw->phylink_pcs)) {
+			ret = PTR_ERR(stpriv->hw->phylink_pcs);
 			goto err_dvr_remove;
 		}
 	}
@@ -498,7 +500,7 @@
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct stmmac_priv *priv = netdev_priv(ndev);
-	struct phylink_pcs *pcs = priv->hw->lynx_pcs;
+	struct phylink_pcs *pcs = priv->hw->phylink_pcs;
 
 	stmmac_pltfr_remove(pdev);
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c
@@ -15,13 +15,20 @@
 
 #include "stmmac_platform.h"
 
-#define STARFIVE_DWMAC_PHY_INFT_RGMII	0x1
-#define STARFIVE_DWMAC_PHY_INFT_RMII	0x4
-#define STARFIVE_DWMAC_PHY_INFT_FIELD	0x7U
+#define STARFIVE_DWMAC_PHY_INFT_RGMII		0x1
+#define STARFIVE_DWMAC_PHY_INFT_RMII		0x4
+#define STARFIVE_DWMAC_PHY_INFT_FIELD		0x7U
+
+#define JH7100_SYSMAIN_REGISTER49_DLYCHAIN	0xc8
+
+struct starfive_dwmac_data {
+	unsigned int gtxclk_dlychain;
+};
 
 struct starfive_dwmac {
 	struct device *dev;
 	struct clk *clk_tx;
+	const struct starfive_dwmac_data *data;
 };
 
 static void starfive_dwmac_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
@@ -67,6 +74,8 @@
 
 	case PHY_INTERFACE_MODE_RGMII:
 	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
 		mode = STARFIVE_DWMAC_PHY_INFT_RGMII;
 		break;
 
@@ -89,6 +98,14 @@
 	if (err)
 		return dev_err_probe(dwmac->dev, err, "error setting phy mode\n");
 
+	if (dwmac->data) {
+		err = regmap_write(regmap, JH7100_SYSMAIN_REGISTER49_DLYCHAIN,
+				   dwmac->data->gtxclk_dlychain);
+		if (err)
+			return dev_err_probe(dwmac->dev, err,
+					     "error selecting gtxclk delay chain\n");
+	}
+
 	return 0;
 }
 
@@ -114,6 +131,8 @@
 	if (!dwmac)
 		return -ENOMEM;
 
+	dwmac->data = device_get_match_data(&pdev->dev);
+
 	dwmac->clk_tx = devm_clk_get_enabled(&pdev->dev, "tx");
 	if (IS_ERR(dwmac->clk_tx))
 		return dev_err_probe(&pdev->dev, PTR_ERR(dwmac->clk_tx),
@@ -144,8 +163,13 @@
 	return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
 }
 
+static const struct starfive_dwmac_data jh7100_data = {
+	.gtxclk_dlychain = 4,
+};
+
 static const struct of_device_id starfive_dwmac_match[] = {
-	{ .compatible = "starfive,jh7110-dwmac"	},
+	{ .compatible = "starfive,jh7100-dwmac", .data = &jh7100_data },
+	{ .compatible = "starfive,jh7110-dwmac" },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, starfive_dwmac_match);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -298,7 +298,7 @@
 /* sun8i_dwmac_dma_init() - initialize the EMAC
  * Called from stmmac via stmmac_dma_ops->init
  */
-static void sun8i_dwmac_dma_init(void __iomem *ioaddr,
+static void sun8i_dwmac_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr,
 				 struct stmmac_dma_cfg *dma_cfg, int atds)
 {
 	writel(EMAC_RX_INT | EMAC_TX_INT, ioaddr + EMAC_INT_EN);
@@ -343,7 +343,8 @@
  * Called from stmmac_ops->dump_regs
  * Used for ethtool
  */
-static void sun8i_dwmac_dump_mac_regs(struct mac_device_info *hw,
+static void sun8i_dwmac_dump_mac_regs(struct stmmac_priv *priv,
+				      struct mac_device_info *hw,
 				      u32 *reg_space)
 {
 	int i;
@@ -1096,6 +1097,8 @@
 
 	priv->dev->priv_flags |= IFF_UNICAST_FLT;
 
+	mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+			 MAC_10 | MAC_100 | MAC_1000;
 	/* The loopback bit seems to be re-set when link change
 	 * Simply mask it each time
 	 * Speed 10/100/1000 are set in BIT(2)/BIT(3)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
+#include <linux/iommu.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/module.h>
@@ -19,6 +20,8 @@
 	struct reset_control *rst_mac;
 	struct reset_control *rst_pcs;
 
+	u32 iommu_sid;
+
 	void __iomem *hv;
 	void __iomem *regs;
 	void __iomem *xpcs;
@@ -50,7 +53,6 @@
 #define MGBE_WRAP_COMMON_INTR_ENABLE	0x8704
 #define MAC_SBD_INTR			BIT(2)
 #define MGBE_WRAP_AXI_ASID0_CTRL	0x8400
-#define MGBE_SID			0x6
 
 static int __maybe_unused tegra_mgbe_suspend(struct device *dev)
 {
@@ -84,7 +86,7 @@
 	writel(MAC_SBD_INTR, mgbe->regs + MGBE_WRAP_COMMON_INTR_ENABLE);
 
 	/* Program SID */
-	writel(MGBE_SID, mgbe->hv + MGBE_WRAP_AXI_ASID0_CTRL);
+	writel(mgbe->iommu_sid, mgbe->hv + MGBE_WRAP_AXI_ASID0_CTRL);
 
 	value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_STATUS);
 	if ((value & XPCS_WRAP_UPHY_STATUS_TX_P_UP) == 0) {
@@ -127,10 +129,12 @@
 	value &= ~XPCS_WRAP_UPHY_RX_CONTROL_AUX_RX_IDDQ;
 	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 
+	usleep_range(10, 20);  /* 50ns min delay needed as per HW design */
 	value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 	value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_SLEEP;
 	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 
+	usleep_range(10, 20);  /* 500ns min delay needed as per HW design */
 	value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 	value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CAL_EN;
 	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
@@ -143,22 +147,30 @@
 		return err;
 	}
 
+	usleep_range(10, 20);  /* 50ns min delay needed as per HW design */
 	value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 	value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_DATA_EN;
 	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 
 	value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
-	value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET;
+	value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_PCS_PHY_RDY;
 	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 
+	usleep_range(10, 20);  /* 50ns min delay needed as per HW design */
 	value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
-	value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET;
+	value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET;
 	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 
+	usleep_range(10, 20);  /* 50ns min delay needed as per HW design */
 	value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 	value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_PCS_PHY_RDY;
 	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
 
+	msleep(30);  /* 30ms delay needed as per HW design */
+	value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
+	value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET;
+	writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL);
+
 	err = readl_poll_timeout(mgbe->xpcs + XPCS_WRAP_IRQ_STATUS, value,
 				 value & XPCS_WRAP_IRQ_STATUS_PCS_LINK_STS,
 				 500, 500 * 2000);
@@ -231,6 +243,12 @@
 	if (IS_ERR(mgbe->xpcs))
 		return PTR_ERR(mgbe->xpcs);
 
+	/* get controller's stream id from iommu property in device tree */
+	if (!tegra_dev_iommu_get_stream_id(mgbe->dev, &mgbe->iommu_sid)) {
+		dev_err(mgbe->dev, "failed to get iommu stream id\n");
+		return -EINVAL;
+	}
+
 	res.addr = mgbe->regs;
 	res.irq = irq;
 
@@ -336,7 +354,7 @@
 	writel(MAC_SBD_INTR, mgbe->regs + MGBE_WRAP_COMMON_INTR_ENABLE);
 
 	/* Program SID */
-	writel(MGBE_SID, mgbe->hv + MGBE_WRAP_AXI_ASID0_CTRL);
+	writel(mgbe->iommu_sid, mgbe->hv + MGBE_WRAP_AXI_ASID0_CTRL);
 
 	plat->flags |= STMMAC_FLAG_SERDES_UP_AFTER_PHY_LINKUP;
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -85,7 +85,8 @@
 	return !!(value & GMAC_CONTROL_IPC);
 }
 
-static void dwmac1000_dump_regs(struct mac_device_info *hw, u32 *reg_space)
+static void dwmac1000_dump_regs(struct stmmac_priv *priv, struct mac_device_info *hw,
+				u32 *reg_space)
 {
 	void __iomem *ioaddr = hw->pcsr;
 	int i;
@@ -539,6 +540,8 @@
 	if (mac->multicast_filter_bins)
 		mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
 
+	mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+			 MAC_10 | MAC_100 | MAC_1000;
 	mac->link.duplex = GMAC_CONTROL_DM;
 	mac->link.speed10 = GMAC_CONTROL_PS;
 	mac->link.speed100 = GMAC_CONTROL_PS | GMAC_CONTROL_FES;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
@@ -70,7 +70,7 @@
 	writel(value, ioaddr + DMA_AXI_BUS_MODE);
 }
 
-static void dwmac1000_dma_init(void __iomem *ioaddr,
+static void dwmac1000_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr,
 			       struct stmmac_dma_cfg *dma_cfg, int atds)
 {
 	u32 value = readl(ioaddr + DMA_BUS_MODE);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c
@@ -34,7 +34,8 @@
 #endif
 }
 
-static void dwmac100_dump_mac_regs(struct mac_device_info *hw, u32 *reg_space)
+static void dwmac100_dump_mac_regs(struct stmmac_priv *priv, struct mac_device_info *hw,
+				   u32 *reg_space)
 {
 	void __iomem *ioaddr = hw->pcsr;
 
@@ -175,6 +176,8 @@
 	dev_info(priv->device, "\tDWMAC100\n");
 
 	mac->pcsr = priv->ioaddr;
+	mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+			 MAC_10 | MAC_100;
 	mac->link.duplex = MAC_CONTROL_F;
 	mac->link.speed10 = 0;
 	mac->link.speed100 = 0;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
@@ -18,7 +18,7 @@
 #include "dwmac100.h"
 #include "dwmac_dma.h"
 
-static void dwmac100_dma_init(void __iomem *ioaddr,
+static void dwmac100_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr,
 			      struct stmmac_dma_cfg *dma_cfg, int atds)
 {
 	/* Enable Application Access by writing to DMA CSR0 */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
@@ -44,6 +44,7 @@
 #define GMAC_MDIO_DATA			0x00000204
 #define GMAC_GPIO_STATUS		0x0000020C
 #define GMAC_ARP_ADDR			0x00000210
+#define GMAC_EXT_CFG1			0x00000238
 #define GMAC_ADDR_HIGH(reg)		(0x300 + reg * 8)
 #define GMAC_ADDR_LOW(reg)		(0x304 + reg * 8)
 #define GMAC_L3L4_CTRL(reg)		(0x900 + (reg) * 0x30)
@@ -284,6 +285,10 @@
 #define GMAC_HW_FEAT_DVLAN		BIT(5)
 #define GMAC_HW_FEAT_NRVF		GENMASK(2, 0)
 
+/* MAC extended config 1 */
+#define GMAC_CONFIG1_SAVE_EN		BIT(24)
+#define GMAC_CONFIG1_SPLM(v)		FIELD_PREP(GENMASK(9, 8), v)
+
 /* GMAC GPIO Status reg */
 #define GMAC_GPO0			BIT(16)
 #define GMAC_GPO1			BIT(17)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/ethtool.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include "stmmac.h"
 #include "stmmac_pcs.h"
 #include "dwmac4.h"
@@ -70,7 +71,10 @@
 
 static void dwmac4_phylink_get_caps(struct stmmac_priv *priv)
 {
-	priv->phylink_config.mac_capabilities |= MAC_2500FD;
+	if (priv->plat->tx_queues_to_use > 1)
+		priv->hw->link.caps &= ~(MAC_10HD | MAC_100HD | MAC_1000HD);
+	else
+		priv->hw->link.caps |= (MAC_10HD | MAC_100HD | MAC_1000HD);
 }
 
 static void dwmac4_rx_queue_enable(struct mac_device_info *hw,
@@ -92,19 +96,41 @@
 				     u32 prio, u32 queue)
 {
 	void __iomem *ioaddr = hw->pcsr;
-	u32 base_register;
-	u32 value;
+	u32 clear_mask = 0;
+	u32 ctrl2, ctrl3;
+	int i;
 
-	base_register = (queue < 4) ? GMAC_RXQ_CTRL2 : GMAC_RXQ_CTRL3;
-	if (queue >= 4)
-		queue -= 4;
+	ctrl2 = readl(ioaddr + GMAC_RXQ_CTRL2);
+	ctrl3 = readl(ioaddr + GMAC_RXQ_CTRL3);
 
-	value = readl(ioaddr + base_register);
+	/* The software must ensure that the same priority
+	 * is not mapped to multiple Rx queues
+	 */
+	for (i = 0; i < 4; i++)
+		clear_mask |= ((prio << GMAC_RXQCTRL_PSRQX_SHIFT(i)) &
+						GMAC_RXQCTRL_PSRQX_MASK(i));
+
+	ctrl2 &= ~clear_mask;
+	ctrl3 &= ~clear_mask;
 
-	value &= ~GMAC_RXQCTRL_PSRQX_MASK(queue);
-	value |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
+	/* First assign new priorities to a queue, then
+	 * clear them from others queues
+	 */
+	if (queue < 4) {
+		ctrl2 |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
 						GMAC_RXQCTRL_PSRQX_MASK(queue);
-	writel(value, ioaddr + base_register);
+
+		writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2);
+		writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3);
+	} else {
+		queue -= 4;
+
+		ctrl3 |= (prio << GMAC_RXQCTRL_PSRQX_SHIFT(queue)) &
+						GMAC_RXQCTRL_PSRQX_MASK(queue);
+
+		writel(ctrl3, ioaddr + GMAC_RXQ_CTRL3);
+		writel(ctrl2, ioaddr + GMAC_RXQ_CTRL2);
+	}
 }
 
 static void dwmac4_tx_queue_priority(struct mac_device_info *hw,
@@ -181,7 +207,7 @@
 	writel(value, ioaddr + MTL_OPERATION_MODE);
 }
 
-static void dwmac4_prog_mtl_tx_algorithms(struct mac_device_info *hw,
+static void dwmac4_prog_mtl_tx_algorithms(struct stmmac_priv *priv, struct mac_device_info *hw,
 					  u32 tx_alg)
 {
 	void __iomem *ioaddr = hw->pcsr;
@@ -285,7 +311,7 @@
 	writel(value, ioaddr + mtl_low_credx_base_addr(dwmac4_addrs, queue));
 }
 
-static void dwmac4_dump_regs(struct mac_device_info *hw, u32 *reg_space)
+static void dwmac4_dump_regs(struct stmmac_priv *priv, struct mac_device_info *hw, u32 *reg_space)
 {
 	void __iomem *ioaddr = hw->pcsr;
 	int i;
@@ -450,7 +476,7 @@
 				    u8 index, u32 data)
 {
 	void __iomem *ioaddr = (void __iomem *)dev->base_addr;
-	int i, timeout = 10;
+	int ret;
 	u32 val;
 
 	if (index >= hw->num_vlan)
@@ -466,16 +492,15 @@
 
 	writel(val, ioaddr + GMAC_VLAN_TAG);
 
-	for (i = 0; i < timeout; i++) {
-		val = readl(ioaddr + GMAC_VLAN_TAG);
-		if (!(val & GMAC_VLAN_TAG_CTRL_OB))
-			return 0;
-		udelay(1);
+	ret = readl_poll_timeout(ioaddr + GMAC_VLAN_TAG, val,
+				 !(val & GMAC_VLAN_TAG_CTRL_OB),
+				 1000, 500000);
+	if (ret) {
+		netdev_err(dev, "Timeout accessing MAC_VLAN_Tag_Filter\n");
+		return -EBUSY;
 	}
 
-	netdev_err(dev, "Timeout accessing MAC_VLAN_Tag_Filter\n");
-
-	return -EBUSY;
+	return 0;
 }
 
 static int dwmac4_add_hw_vlan_rx_fltr(struct net_device *dev,
@@ -730,7 +755,14 @@
 static void dwmac4_ctrl_ane(void __iomem *ioaddr, bool ane, bool srgmi_ral,
 			    bool loopback)
 {
+	u32 intr_mask = readl(ioaddr + GMAC_INT_EN);
+
 	dwmac_ctrl_ane(ioaddr, GMAC_PCS_BASE, ane, srgmi_ral, loopback);
+	if (!ane)
+		intr_mask &= ~(GMAC_INT_PCS_LINK | GMAC_INT_PCS_ANE);
+	else
+		intr_mask |= (GMAC_INT_PCS_LINK | GMAC_INT_PCS_ANE);
+	writel(intr_mask, ioaddr + GMAC_INT_EN);
 }
 
 static void dwmac4_rane(void __iomem *ioaddr, bool restart)
@@ -957,7 +989,7 @@
 }
 
 static void dwmac4_update_vlan_hash(struct mac_device_info *hw, u32 hash,
-				    __le16 perfect_match, bool is_double)
+				    u16 perfect_match, bool is_double)
 {
 	void __iomem *ioaddr = hw->pcsr;
 	u32 value;
@@ -1356,6 +1388,8 @@
 	if (mac->multicast_filter_bins)
 		mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
 
+	mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+			 MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
 	mac->link.duplex = GMAC_CONFIG_DM;
 	mac->link.speed10 = GMAC_CONFIG_PS;
 	mac->link.speed100 = GMAC_CONFIG_FES | GMAC_CONFIG_PS;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -152,7 +152,7 @@
 	       ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
 }
 
-static void dwmac4_dma_init(void __iomem *ioaddr,
+static void dwmac4_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr,
 			    struct stmmac_dma_cfg *dma_cfg, int atds)
 {
 	u32 value = readl(ioaddr + DMA_SYS_BUS_MODE);
@@ -203,8 +203,12 @@
 		readl(ioaddr + DMA_CHAN_TX_CONTROL(dwmac4_addrs, channel));
 	reg_space[DMA_CHAN_RX_CONTROL(default_addrs, channel) / 4] =
 		readl(ioaddr + DMA_CHAN_RX_CONTROL(dwmac4_addrs, channel));
+	reg_space[DMA_CHAN_TX_BASE_ADDR_HI(default_addrs, channel) / 4] =
+		readl(ioaddr + DMA_CHAN_TX_BASE_ADDR_HI(dwmac4_addrs, channel));
 	reg_space[DMA_CHAN_TX_BASE_ADDR(default_addrs, channel) / 4] =
 		readl(ioaddr + DMA_CHAN_TX_BASE_ADDR(dwmac4_addrs, channel));
+	reg_space[DMA_CHAN_RX_BASE_ADDR_HI(default_addrs, channel) / 4] =
+		readl(ioaddr + DMA_CHAN_RX_BASE_ADDR_HI(dwmac4_addrs, channel));
 	reg_space[DMA_CHAN_RX_BASE_ADDR(default_addrs, channel) / 4] =
 		readl(ioaddr + DMA_CHAN_RX_BASE_ADDR(dwmac4_addrs, channel));
 	reg_space[DMA_CHAN_TX_END_ADDR(default_addrs, channel) / 4] =
@@ -225,8 +229,12 @@
 		readl(ioaddr + DMA_CHAN_CUR_TX_DESC(dwmac4_addrs, channel));
 	reg_space[DMA_CHAN_CUR_RX_DESC(default_addrs, channel) / 4] =
 		readl(ioaddr + DMA_CHAN_CUR_RX_DESC(dwmac4_addrs, channel));
+	reg_space[DMA_CHAN_CUR_TX_BUF_ADDR_HI(default_addrs, channel) / 4] =
+		readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR_HI(dwmac4_addrs, channel));
 	reg_space[DMA_CHAN_CUR_TX_BUF_ADDR(default_addrs, channel) / 4] =
 		readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR(dwmac4_addrs, channel));
+	reg_space[DMA_CHAN_CUR_RX_BUF_ADDR_HI(default_addrs, channel) / 4] =
+		readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR_HI(dwmac4_addrs, channel));
 	reg_space[DMA_CHAN_CUR_RX_BUF_ADDR(default_addrs, channel) / 4] =
 		readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR(dwmac4_addrs, channel));
 	reg_space[DMA_CHAN_STATUS(default_addrs, channel) / 4] =
@@ -526,6 +534,11 @@
 	value |= GMAC_CONFIG_HDSMS_256; /* Segment max 256 bytes */
 	writel(value, ioaddr + GMAC_EXT_CONFIG);
 
+	value = readl(ioaddr + GMAC_EXT_CFG1);
+	value |= GMAC_CONFIG1_SPLM(1); /* Split mode set to L2OFST */
+	value |= GMAC_CONFIG1_SAVE_EN; /* Enable Split AV mode */
+	writel(value, ioaddr + GMAC_EXT_CFG1);
+
 	value = readl(ioaddr + DMA_CHAN_CONTROL(dwmac4_addrs, chan));
 	if (en)
 		value |= DMA_CONTROL_SPH;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h
@@ -127,7 +127,9 @@
 #define DMA_CHAN_SLOT_CTRL_STATUS(addrs, x)	(dma_chanx_base_addr(addrs, x) + 0x3c)
 #define DMA_CHAN_CUR_TX_DESC(addrs, x)	(dma_chanx_base_addr(addrs, x) + 0x44)
 #define DMA_CHAN_CUR_RX_DESC(addrs, x)	(dma_chanx_base_addr(addrs, x) + 0x4c)
+#define DMA_CHAN_CUR_TX_BUF_ADDR_HI(addrs, x)	(dma_chanx_base_addr(addrs, x) + 0x50)
 #define DMA_CHAN_CUR_TX_BUF_ADDR(addrs, x)	(dma_chanx_base_addr(addrs, x) + 0x54)
+#define DMA_CHAN_CUR_RX_BUF_ADDR_HI(addrs, x)	(dma_chanx_base_addr(addrs, x) + 0x58)
 #define DMA_CHAN_CUR_RX_BUF_ADDR(addrs, x)	(dma_chanx_base_addr(addrs, x) + 0x5c)
 #define DMA_CHAN_STATUS(addrs, x)	(dma_chanx_base_addr(addrs, x) + 0x60)
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
@@ -517,7 +517,7 @@
 	return ret;
 }
 
-int dwmac5_flex_pps_config(void __iomem *ioaddr, int index,
+int dwmac5_flex_pps_config(struct stmmac_priv *priv, void __iomem *ioaddr, int index,
 			   struct stmmac_pps_cfg *cfg, bool enable,
 			   u32 sub_second_inc, u32 systime_flags)
 {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac5.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwmac5.h
@@ -99,7 +99,7 @@
 			int index, unsigned long *count, const char **desc);
 int dwmac5_rxp_config(void __iomem *ioaddr, struct stmmac_tc_entry *entries,
 		      unsigned int count);
-int dwmac5_flex_pps_config(void __iomem *ioaddr, int index,
+int dwmac5_flex_pps_config(struct stmmac_priv *priv, void __iomem *ioaddr, int index,
 			   struct stmmac_pps_cfg *cfg, bool enable,
 			   u32 sub_second_inc, u32 systime_flags);
 void dwmac5_fpe_configure(void __iomem *ioaddr, struct stmmac_fpe_cfg *cfg,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -17,6 +17,7 @@
 #define XGMAC_CONFIG_SS_OFF		29
 #define XGMAC_CONFIG_SS_MASK		GENMASK(31, 29)
 #define XGMAC_CONFIG_SS_10000		(0x0 << XGMAC_CONFIG_SS_OFF)
+#define XGMAC_CONFIG_SS_25000		(0x1 << XGMAC_CONFIG_SS_OFF)
 #define XGMAC_CONFIG_SS_2500_GMII	(0x2 << XGMAC_CONFIG_SS_OFF)
 #define XGMAC_CONFIG_SS_1000_GMII	(0x3 << XGMAC_CONFIG_SS_OFF)
 #define XGMAC_CONFIG_SS_100_MII		(0x4 << XGMAC_CONFIG_SS_OFF)
@@ -241,12 +242,47 @@
 #define XGMAC_CT			BIT(1)
 #define XGMAC_OB			BIT(0)
 #define XGMAC_RSS_DATA			0x00000c8c
-#define XGMAC_TIMESTAMP_STATUS		0x00000d20
+#define XGMAC_TIMESTAMP_BASE_ADDR	0x00000d00
+#define XGMAC_PPS_BASE_ADDR		0x00000d80
+
+/* MAC extended config 1 */
+#define XGMAC_EXT_CFG1			0x144
+#define XGMAC_CONFIG1_SAVE_EN		BIT(24)
+#define XGMAC_CONFIG1_SPLM(v)		FIELD_PREP(GENMASK(9, 8), v)
+
+static inline u32 xgmac_timestamp_base_addr(const struct dwxgmac_addrs *addrs)
+{
+	u32 addr;
+
+	if (addrs)
+		addr = addrs->timestamp_base;
+	else
+		addr = XGMAC_TIMESTAMP_BASE_ADDR;
+
+	return addr;
+}
+
+static inline u32 xgmac_pps_base_addr(const struct dwxgmac_addrs *addrs,
+				      const u32 x)
+{
+	u32 addr;
+
+	if (addrs)
+		addr = addrs->pps_base +  x * addrs->pps_offset;
+	else
+		addr = XGMAC_PPS_BASE_ADDR + x * 0x10;
+
+	return addr;
+}
+
+#define XGMAC_TIMESTAMP_STATUS(addrs)	(xgmac_timestamp_base_addr(addrs) + 0x20)
 #define XGMAC_TXTSC			BIT(15)
-#define XGMAC_TXTIMESTAMP_NSEC		0x00000d30
+#define XGMAC_TXTIMESTAMP_NSEC(addrs)		(xgmac_timestamp_base_addr(addrs) + 0x30)
 #define XGMAC_TXTSSTSLO			GENMASK(30, 0)
-#define XGMAC_TXTIMESTAMP_SEC		0x00000d34
-#define XGMAC_PPS_CONTROL		0x00000d70
+#define XGMAC_TXTIMESTAMP_SEC(addrs)		(xgmac_timestamp_base_addr(addrs) + 0x34)
+#define XGMAC_TXTIMESTAMP_STATUS_PKTID(addrs) (xgmac_timestamp_base_addr(addrs) + 0x38)
+
+#define XGMAC_PPS_CONTROL(addrs)		(xgmac_timestamp_base_addr(addrs) + 0x70)
 #define XGMAC_PPS_MAXIDX(x)		((((x) + 1) * 8) - 1)
 #define XGMAC_PPS_MINIDX(x)		((x) * 8)
 #define XGMAC_PPSx_MASK(x)		\
@@ -260,13 +296,15 @@
 #define XGMAC_PPSCMD_START		0x2
 #define XGMAC_PPSCMD_STOP		0x5
 #define XGMAC_PPSENx(x)			BIT(4 + (x) * 8)
-#define XGMAC_PPSx_TARGET_TIME_SEC(x)	(0x00000d80 + (x) * 0x10)
-#define XGMAC_PPSx_TARGET_TIME_NSEC(x)	(0x00000d84 + (x) * 0x10)
+#define XGMAC_PPSx_TARGET_TIME_SEC(addrs, x)			xgmac_pps_base_addr(addrs, x)
+#define XGMAC_PPSx_TARGET_TIME_NSEC(addrs, x)	(xgmac_pps_base_addr(addrs, x) + 0x04)
 #define XGMAC_TRGTBUSY0			BIT(31)
-#define XGMAC_PPSx_INTERVAL(x)		(0x00000d88 + (x) * 0x10)
-#define XGMAC_PPSx_WIDTH(x)		(0x00000d8c + (x) * 0x10)
+#define XGMAC_PPSx_INTERVAL(addrs, x)		(xgmac_pps_base_addr(addrs, x) + 0x08)
+#define XGMAC_PPSx_WIDTH(addrs, x)		(xgmac_pps_base_addr(addrs, x) + 0x0c)
 
 /* MTL Registers */
+#define XGMAC_MTL_CHAN_BASE_ADDR	0x00001100
+#define XGMAC_MTL_CHAN_OFFSET		0x80
 #define XGMAC_MTL_OPMODE		0x00001000
 #define XGMAC_FRPE			BIT(15)
 #define XGMAC_ETSALG			GENMASK(6, 5)
@@ -305,7 +343,21 @@
 #define XGMAC_MTL_ECC_INT_STATUS	0x000010cc
 #define XGMAC_MTL_DPP_CONTROL		0x000010e0
 #define XGMAC_DPP_DISABLE		BIT(0)
-#define XGMAC_MTL_TXQ_OPMODE(x)		(0x00001100 + (0x80 * (x)))
+
+static inline u32 xgmac_mtl_chanx_base_addr(const struct dwxgmac_addrs *addrs,
+					    const u32 x)
+{
+	u32 addr;
+
+	if (addrs)
+		addr = addrs->mtl_chan_base + (x * addrs->mtl_chan_offset);
+	else
+		addr = XGMAC_MTL_CHAN_BASE_ADDR + (x * XGMAC_MTL_CHAN_OFFSET);
+
+	return addr;
+}
+
+#define XGMAC_MTL_TXQ_OPMODE(addrs, x)	xgmac_mtl_chanx_base_addr(addrs, x)
 #define XGMAC_TQS			GENMASK(25, 16)
 #define XGMAC_TQS_SHIFT			16
 #define XGMAC_Q2TCMAP			GENMASK(10, 8)
@@ -315,39 +367,43 @@
 #define XGMAC_TXQEN			GENMASK(3, 2)
 #define XGMAC_TXQEN_SHIFT		2
 #define XGMAC_TSF			BIT(1)
-#define XGMAC_MTL_TCx_ETS_CONTROL(x)	(0x00001110 + (0x80 * (x)))
-#define XGMAC_MTL_TCx_QUANTUM_WEIGHT(x)	(0x00001118 + (0x80 * (x)))
-#define XGMAC_MTL_TCx_SENDSLOPE(x)	(0x0000111c + (0x80 * (x)))
-#define XGMAC_MTL_TCx_HICREDIT(x)	(0x00001120 + (0x80 * (x)))
-#define XGMAC_MTL_TCx_LOCREDIT(x)	(0x00001124 + (0x80 * (x)))
+#define XGMAC_MTL_TCx_ETS_CONTROL(addrs, x)	(xgmac_mtl_chanx_base_addr(addrs, x) + 0x10)
+#define XGMAC_MTL_TCx_QUANTUM_WEIGHT(addrs, x)	(xgmac_mtl_chanx_base_addr(addrs, x) + 0x18)
+#define XGMAC_MTL_TCx_SENDSLOPE(addrs, x)	(xgmac_mtl_chanx_base_addr(addrs, x) + 0x1c)
+#define XGMAC_MTL_TCx_HICREDIT(addrs, x)	(xgmac_mtl_chanx_base_addr(addrs, x) + 0x20)
+#define XGMAC_MTL_TCx_LOCREDIT(addrs, x)	(xgmac_mtl_chanx_base_addr(addrs, x) + 0x24)
 #define XGMAC_CC			BIT(3)
 #define XGMAC_TSA			GENMASK(1, 0)
 #define XGMAC_SP			(0x0 << 0)
 #define XGMAC_CBS			(0x1 << 0)
 #define XGMAC_ETS			(0x2 << 0)
-#define XGMAC_MTL_RXQ_OPMODE(x)		(0x00001140 + (0x80 * (x)))
+#define XGMAC_MTL_RXQ_OPMODE(addrs, x)		(xgmac_mtl_chanx_base_addr(addrs, x) + 0x40)
 #define XGMAC_RQS			GENMASK(25, 16)
 #define XGMAC_RQS_SHIFT			16
 #define XGMAC_EHFC			BIT(7)
 #define XGMAC_RSF			BIT(5)
 #define XGMAC_RTC			GENMASK(1, 0)
 #define XGMAC_RTC_SHIFT			0
-#define XGMAC_MTL_RXQ_FLOW_CONTROL(x)	(0x00001150 + (0x80 * (x)))
+#define XGMAC_MTL_RXQ_FLOW_CONTROL(addrs, x)	(xgmac_mtl_chanx_base_addr(addrs, x) + 0x50)
 #define XGMAC_RFD			GENMASK(31, 17)
 #define XGMAC_RFD_SHIFT			17
 #define XGMAC_RFA			GENMASK(15, 1)
 #define XGMAC_RFA_SHIFT			1
-#define XGMAC_MTL_QINTEN(x)		(0x00001170 + (0x80 * (x)))
+#define XGMAC_MTL_QINTEN(addrs, x)		(xgmac_mtl_chanx_base_addr(addrs, x) + 0x70)
 #define XGMAC_RXOIE			BIT(16)
-#define XGMAC_MTL_QINT_STATUS(x)	(0x00001174 + (0x80 * (x)))
+#define XGMAC_MTL_QINT_STATUS(addrs, x)	(xgmac_mtl_chanx_base_addr(addrs, x) + 0x74)
 #define XGMAC_RXOVFIS			BIT(16)
 #define XGMAC_ABPSIS			BIT(1)
 #define XGMAC_TXUNFIS			BIT(0)
-#define XGMAC_MAC_REGSIZE		(XGMAC_MTL_QINT_STATUS(15) / 4)
+#define XGMAC_MAC_REGSIZE(addrs)		(XGMAC_MTL_QINT_STATUS(addrs, 15) / 4)
 
 /* DMA Registers */
+#define XGMAC_DMA_CHAN_BASE_ADDR		0x00003100
+#define XGMAC_DMA_CHAN_OFFSET		0x80
 #define XGMAC_DMA_MODE			0x00003000
 #define XGMAC_SWR			BIT(0)
+#define XGMAC_DSCB		BIT(16)
+#define XGMAC_HMIC		BIT(17)
 #define XGMAC_DMA_SYSBUS_MODE		0x00003004
 #define XGMAC_WR_OSR_LMT		GENMASK(29, 24)
 #define XGMAC_WR_OSR_LMT_SHIFT		24
@@ -355,6 +411,7 @@
 #define XGMAC_RD_OSR_LMT_SHIFT		16
 #define XGMAC_EN_LPI			BIT(15)
 #define XGMAC_LPI_XIT_PKT		BIT(14)
+#define XGMAC_ONEKBBE		BIT(13)
 #define XGMAC_AAL			BIT(12)
 #define XGMAC_EAME			BIT(11)
 #define XGMAC_BLEN			GENMASK(7, 1)
@@ -388,44 +445,61 @@
 #define XGMAC_TCEIE			BIT(0)
 #define XGMAC_DMA_ECC_INT_STATUS	0x0000306c
 #define XGMAC_DMA_DPP_INT_STATUS	0x00003074
-#define XGMAC_DMA_CH_CONTROL(x)		(0x00003100 + (0x80 * (x)))
+
+static inline u32 xgmac_dma_chanx_base_addr(const struct dwxgmac_addrs *addrs,
+					    const u32 x)
+{
+	u32 addr;
+
+	if (addrs && (x % 2))
+		addr = addrs->dma_odd_chan_base + (x * addrs->dma_chan_offset);
+	else if (addrs)
+		addr = addrs->dma_even_chan_base + (x * addrs->dma_chan_offset);
+	else
+		addr = XGMAC_DMA_CHAN_BASE_ADDR + (x * XGMAC_DMA_CHAN_OFFSET);
+
+	return addr;
+}
+
+#define XGMAC_DMA_CH_CONTROL(addr, x)		(xgmac_dma_chanx_base_addr(addr, x))
 #define XGMAC_SPH			BIT(24)
 #define XGMAC_PBLx8			BIT(16)
-#define XGMAC_DMA_CH_TX_CONTROL(x)	(0x00003104 + (0x80 * (x)))
+#define XGMAC_DMA_CH_TX_CONTROL(addr, x)	(xgmac_dma_chanx_base_addr(addr, x) + 0x04)
 #define XGMAC_EDSE			BIT(28)
 #define XGMAC_TxPBL			GENMASK(21, 16)
 #define XGMAC_TxPBL_SHIFT		16
 #define XGMAC_TSE			BIT(12)
 #define XGMAC_OSP			BIT(4)
 #define XGMAC_TXST			BIT(0)
-#define XGMAC_DMA_CH_RX_CONTROL(x)	(0x00003108 + (0x80 * (x)))
+#define XGMAC_DMA_CH_RX_CONTROL(addr, x)	(xgmac_dma_chanx_base_addr(addr, x) + 0x08)
 #define XGMAC_RxPBL			GENMASK(21, 16)
 #define XGMAC_RxPBL_SHIFT		16
 #define XGMAC_RBSZ			GENMASK(14, 1)
 #define XGMAC_RBSZ_SHIFT		1
 #define XGMAC_RXST			BIT(0)
-#define XGMAC_DMA_CH_TxDESC_HADDR(x)	(0x00003110 + (0x80 * (x)))
-#define XGMAC_DMA_CH_TxDESC_LADDR(x)	(0x00003114 + (0x80 * (x)))
-#define XGMAC_DMA_CH_RxDESC_HADDR(x)	(0x00003118 + (0x80 * (x)))
-#define XGMAC_DMA_CH_RxDESC_LADDR(x)	(0x0000311c + (0x80 * (x)))
-#define XGMAC_DMA_CH_TxDESC_TAIL_LPTR(x)	(0x00003124 + (0x80 * (x)))
-#define XGMAC_DMA_CH_RxDESC_TAIL_LPTR(x)	(0x0000312c + (0x80 * (x)))
-#define XGMAC_DMA_CH_TxDESC_RING_LEN(x)		(0x00003130 + (0x80 * (x)))
-#define XGMAC_DMA_CH_RxDESC_RING_LEN(x)		(0x00003134 + (0x80 * (x)))
-#define XGMAC_DMA_CH_INT_EN(x)		(0x00003138 + (0x80 * (x)))
+#define XGMAC_DMA_CH_TxDESC_HADDR(addr, x)	(xgmac_dma_chanx_base_addr(addr, x) + 0x10)
+#define XGMAC_DMA_CH_TxDESC_LADDR(addr, x)	(xgmac_dma_chanx_base_addr(addr, x) + 0x14)
+#define XGMAC_DMA_CH_RxDESC_HADDR(addr, x)	(xgmac_dma_chanx_base_addr(addr, x) + 0x18)
+#define XGMAC_DMA_CH_RxDESC_LADDR(addr, x)	(xgmac_dma_chanx_base_addr(addr, x) + 0x1c)
+#define XGMAC_DMA_CH_TxDESC_TAIL_LPTR(addr, x)	(xgmac_dma_chanx_base_addr(addr, x) + 0x24)
+#define XGMAC_DMA_CH_RxDESC_TAIL_LPTR(addr, x)	(xgmac_dma_chanx_base_addr(addr, x) + 0x2c)
+#define XGMAC_DMA_CH_TxDESC_RING_LEN(addr, x)		(xgmac_dma_chanx_base_addr(addr, x) + 0x30)
+#define XGMAC_DMA_CH_RxDESC_RING_LEN(addr, x)		(xgmac_dma_chanx_base_addr(addr, x) + 0x34)
+#define XGMAC_DMA_CH_INT_EN(addr, x)		(xgmac_dma_chanx_base_addr(addr, x) + 0x38)
 #define XGMAC_NIE			BIT(15)
 #define XGMAC_AIE			BIT(14)
+#define XGMAC_FBEE			BIT(12)
 #define XGMAC_RBUE			BIT(7)
 #define XGMAC_RIE			BIT(6)
 #define XGMAC_TBUE			BIT(2)
 #define XGMAC_TIE			BIT(0)
 #define XGMAC_DMA_INT_DEFAULT_EN	(XGMAC_NIE | XGMAC_AIE | XGMAC_RBUE | \
-					XGMAC_RIE | XGMAC_TIE)
+					XGMAC_RIE | XGMAC_TIE | XGMAC_FBEE)
 #define XGMAC_DMA_INT_DEFAULT_RX	(XGMAC_RBUE | XGMAC_RIE)
 #define XGMAC_DMA_INT_DEFAULT_TX	(XGMAC_TIE)
-#define XGMAC_DMA_CH_Rx_WATCHDOG(x)	(0x0000313c + (0x80 * (x)))
+#define XGMAC_DMA_CH_Rx_WATCHDOG(addr, x)	(xgmac_dma_chanx_base_addr(addr, x) + 0x3c)
 #define XGMAC_RWT			GENMASK(7, 0)
-#define XGMAC_DMA_CH_STATUS(x)		(0x00003160 + (0x80 * (x)))
+#define XGMAC_DMA_CH_STATUS(addr, x)		(xgmac_dma_chanx_base_addr(addr, x) + 0x60)
 #define XGMAC_NIS			BIT(15)
 #define XGMAC_AIS			BIT(14)
 #define XGMAC_FBE			BIT(12)
@@ -434,7 +508,7 @@
 #define XGMAC_TBU			BIT(2)
 #define XGMAC_TPS			BIT(1)
 #define XGMAC_TI			BIT(0)
-#define XGMAC_REGSIZE			((0x0000317c + (0x80 * 15)) / 4)
+#define XGMAC_REGSIZE(addr)			((xgmac_dma_chanx_base_addr(addr, 15) + 0x7c) / 4)
 
 #define XGMAC_DMA_STATUS_MSK_COMMON	(XGMAC_NIS | XGMAC_AIS | XGMAC_FBE)
 #define XGMAC_DMA_STATUS_MSK_RX		(XGMAC_RBU | XGMAC_RI | \
@@ -445,6 +519,7 @@
 /* Descriptors */
 #define XGMAC_TDES0_LTV			BIT(31)
 #define XGMAC_TDES0_LT			GENMASK(7, 0)
+#define XGMAC_TDES0_TTSL		GENMASK(9, 0)
 #define XGMAC_TDES1_LT			GENMASK(31, 8)
 #define XGMAC_TDES2_IVT			GENMASK(31, 16)
 #define XGMAC_TDES2_IVT_SHIFT		16
@@ -459,6 +534,8 @@
 #define XGMAC_TDES3_CTXT		BIT(30)
 #define XGMAC_TDES3_FD			BIT(29)
 #define XGMAC_TDES3_LD			BIT(28)
+#define XGMAC_TDES3_OSTC		BIT(27)
+#define XGMAC_TDES3_PIDV		BIT(25)
 #define XGMAC_TDES3_CPC			GENMASK(27, 26)
 #define XGMAC_TDES3_CPC_SHIFT		26
 #define XGMAC_TDES3_TCMSSV		BIT(26)
@@ -478,6 +555,7 @@
 #define XGMAC_TDES3_VT			GENMASK(15, 0)
 #define XGMAC_TDES3_FL			GENMASK(14, 0)
 #define XGMAC_RDES2_HL			GENMASK(9, 0)
+#define XGMAC_RDES2_NONIPHL		GENMASK(9, 2)
 #define XGMAC_RDES3_OWN			BIT(31)
 #define XGMAC_RDES3_CTXT		BIT(30)
 #define XGMAC_RDES3_IOC			BIT(30)
@@ -485,6 +563,7 @@
 #define XGMAC_RDES3_CDA			BIT(27)
 #define XGMAC_RDES3_RSV			BIT(26)
 #define XGMAC_RDES3_L34T		GENMASK(23, 20)
+#define XGMAC_RDES3_L2T			GENMASK(19, 16)
 #define XGMAC_RDES3_L34T_SHIFT		20
 #define XGMAC_L34T_IP4TCP		0x1
 #define XGMAC_L34T_IP4UDP		0x2
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
@@ -11,6 +11,7 @@
 #include "stmmac_ptp.h"
 #include "dwxlgmac2.h"
 #include "dwxgmac2.h"
+#include "dw25gmac.h"
 
 static void dwxgmac2_core_init(struct mac_device_info *hw,
 			       struct net_device *dev)
@@ -47,14 +48,6 @@
 	writel(XGMAC_INT_DEFAULT_EN, ioaddr + XGMAC_INT_EN);
 }
 
-static void xgmac_phylink_get_caps(struct stmmac_priv *priv)
-{
-	priv->phylink_config.mac_capabilities |= MAC_2500FD | MAC_5000FD |
-						 MAC_10000FD | MAC_25000FD |
-						 MAC_40000FD | MAC_50000FD |
-						 MAC_100000FD;
-}
-
 static void dwxgmac2_set_mac(void __iomem *ioaddr, bool enable)
 {
 	u32 tx = readl(ioaddr + XGMAC_TX_CONFIG);
@@ -105,17 +98,41 @@
 				   u32 queue)
 {
 	void __iomem *ioaddr = hw->pcsr;
-	u32 value, reg;
+	u32 clear_mask = 0;
+	u32 ctrl2, ctrl3;
+	int i;
 
-	reg = (queue < 4) ? XGMAC_RXQ_CTRL2 : XGMAC_RXQ_CTRL3;
-	if (queue >= 4)
+	ctrl2 = readl(ioaddr + XGMAC_RXQ_CTRL2);
+	ctrl3 = readl(ioaddr + XGMAC_RXQ_CTRL3);
+
+	/* The software must ensure that the same priority
+	 * is not mapped to multiple Rx queues
+	 */
+	for (i = 0; i < 4; i++)
+		clear_mask |= ((prio << XGMAC_PSRQ_SHIFT(i)) &
+						XGMAC_PSRQ(i));
+
+	ctrl2 &= ~clear_mask;
+	ctrl3 &= ~clear_mask;
+
+	/* First assign new priorities to a queue, then
+	 * clear them from others queues
+	 */
+	if (queue < 4) {
+		ctrl2 |= (prio << XGMAC_PSRQ_SHIFT(queue)) &
+						XGMAC_PSRQ(queue);
+
+		writel(ctrl2, ioaddr + XGMAC_RXQ_CTRL2);
+		writel(ctrl3, ioaddr + XGMAC_RXQ_CTRL3);
+	} else {
 		queue -= 4;
 
-	value = readl(ioaddr + reg);
-	value &= ~XGMAC_PSRQ(queue);
-	value |= (prio << XGMAC_PSRQ_SHIFT(queue)) & XGMAC_PSRQ(queue);
+		ctrl3 |= (prio << XGMAC_PSRQ_SHIFT(queue)) &
+						XGMAC_PSRQ(queue);
 
-	writel(value, ioaddr + reg);
+		writel(ctrl3, ioaddr + XGMAC_RXQ_CTRL3);
+		writel(ctrl2, ioaddr + XGMAC_RXQ_CTRL2);
+	}
 }
 
 static void dwxgmac2_tx_queue_prio(struct mac_device_info *hw, u32 prio,
@@ -187,9 +204,10 @@
 	writel(value, ioaddr + XGMAC_MTL_OPMODE);
 }
 
-static void dwxgmac2_prog_mtl_tx_algorithms(struct mac_device_info *hw,
+static void dwxgmac2_prog_mtl_tx_algorithms(struct stmmac_priv *priv, struct mac_device_info *hw,
 					    u32 tx_alg)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	void __iomem *ioaddr = hw->pcsr;
 	bool ets = true;
 	u32 value;
@@ -217,11 +235,11 @@
 
 	/* Set ETS if desired */
 	for (i = 0; i < MTL_MAX_TX_QUEUES; i++) {
-		value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(i));
+		value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(dwxgmac_addrs, i));
 		value &= ~XGMAC_TSA;
 		if (ets)
 			value |= XGMAC_ETS;
-		writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(i));
+		writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(dwxgmac_addrs, i));
 	}
 }
 
@@ -229,9 +247,10 @@
 					     struct mac_device_info *hw,
 					     u32 weight, u32 queue)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	void __iomem *ioaddr = hw->pcsr;
 
-	writel(weight, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(queue));
+	writel(weight, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(dwxgmac_addrs, queue));
 }
 
 static void dwxgmac2_map_mtl_to_dma(struct mac_device_info *hw, u32 queue,
@@ -256,26 +275,28 @@
 				u32 send_slope, u32 idle_slope,
 				u32 high_credit, u32 low_credit, u32 queue)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	void __iomem *ioaddr = hw->pcsr;
 	u32 value;
 
-	writel(send_slope, ioaddr + XGMAC_MTL_TCx_SENDSLOPE(queue));
-	writel(idle_slope, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(queue));
-	writel(high_credit, ioaddr + XGMAC_MTL_TCx_HICREDIT(queue));
-	writel(low_credit, ioaddr + XGMAC_MTL_TCx_LOCREDIT(queue));
+	writel(send_slope, ioaddr + XGMAC_MTL_TCx_SENDSLOPE(dwxgmac_addrs, queue));
+	writel(idle_slope, ioaddr + XGMAC_MTL_TCx_QUANTUM_WEIGHT(dwxgmac_addrs, queue));
+	writel(high_credit, ioaddr + XGMAC_MTL_TCx_HICREDIT(dwxgmac_addrs, queue));
+	writel(low_credit, ioaddr + XGMAC_MTL_TCx_LOCREDIT(dwxgmac_addrs, queue));
 
-	value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue));
+	value = readl(ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(dwxgmac_addrs, queue));
 	value &= ~XGMAC_TSA;
 	value |= XGMAC_CC | XGMAC_CBS;
-	writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(queue));
+	writel(value, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(dwxgmac_addrs, queue));
 }
 
-static void dwxgmac2_dump_regs(struct mac_device_info *hw, u32 *reg_space)
+static void dwxgmac2_dump_regs(struct stmmac_priv *priv, struct mac_device_info *hw, u32 *reg_space)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	void __iomem *ioaddr = hw->pcsr;
 	int i;
 
-	for (i = 0; i < XGMAC_MAC_REGSIZE; i++)
+	for (i = 0; i < XGMAC_MAC_REGSIZE(dwxgmac_addrs); i++)
 		reg_space[i] = readl(ioaddr + i * 4);
 }
 
@@ -319,18 +340,19 @@
 static int dwxgmac2_host_mtl_irq_status(struct stmmac_priv *priv,
 					struct mac_device_info *hw, u32 chan)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	void __iomem *ioaddr = hw->pcsr;
 	int ret = 0;
 	u32 status;
 
 	status = readl(ioaddr + XGMAC_MTL_INT_STATUS);
 	if (status & BIT(chan)) {
-		u32 chan_status = readl(ioaddr + XGMAC_MTL_QINT_STATUS(chan));
+		u32 chan_status = readl(ioaddr + XGMAC_MTL_QINT_STATUS(dwxgmac_addrs, chan));
 
 		if (chan_status & XGMAC_RXOVFIS)
 			ret |= CORE_IRQ_MTL_RX_OVERFLOW;
 
-		writel(~0x0, ioaddr + XGMAC_MTL_QINT_STATUS(chan));
+		writel(~0x0, ioaddr + XGMAC_MTL_QINT_STATUS(dwxgmac_addrs, chan));
 	}
 
 	return ret;
@@ -599,7 +621,7 @@
 }
 
 static void dwxgmac2_update_vlan_hash(struct mac_device_info *hw, u32 hash,
-				      __le16 perfect_match, bool is_double)
+				      u16 perfect_match, bool is_double)
 {
 	void __iomem *ioaddr = hw->pcsr;
 
@@ -1195,26 +1217,29 @@
 	return ret;
 }
 
-static int dwxgmac2_get_mac_tx_timestamp(struct mac_device_info *hw, u64 *ts)
+static int dwxgmac2_get_mac_tx_timestamp(struct stmmac_priv *priv, struct mac_device_info *hw,
+					 u64 *ts)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	void __iomem *ioaddr = hw->pcsr;
 	u32 value;
 
-	if (readl_poll_timeout_atomic(ioaddr + XGMAC_TIMESTAMP_STATUS,
+	if (readl_poll_timeout_atomic(ioaddr + XGMAC_TIMESTAMP_STATUS(dwxgmac_addrs),
 				      value, value & XGMAC_TXTSC, 100, 10000))
 		return -EBUSY;
 
-	*ts = readl(ioaddr + XGMAC_TXTIMESTAMP_NSEC) & XGMAC_TXTSSTSLO;
-	*ts += readl(ioaddr + XGMAC_TXTIMESTAMP_SEC) * 1000000000ULL;
+	*ts = readl(ioaddr + XGMAC_TXTIMESTAMP_NSEC(dwxgmac_addrs)) & XGMAC_TXTSSTSLO;
+	*ts += readl(ioaddr + XGMAC_TXTIMESTAMP_SEC(dwxgmac_addrs)) * 1000000000ULL;
 	return 0;
 }
 
-static int dwxgmac2_flex_pps_config(void __iomem *ioaddr, int index,
+static int dwxgmac2_flex_pps_config(struct stmmac_priv *priv, void __iomem *ioaddr, int index,
 				    struct stmmac_pps_cfg *cfg, bool enable,
 				    u32 sub_second_inc, u32 systime_flags)
 {
-	u32 tnsec = readl(ioaddr + XGMAC_PPSx_TARGET_TIME_NSEC(index));
-	u32 val = readl(ioaddr + XGMAC_PPS_CONTROL);
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+	u32 tnsec = readl(ioaddr + XGMAC_PPSx_TARGET_TIME_NSEC(dwxgmac_addrs, index));
+	u32 val = readl(ioaddr + XGMAC_PPS_CONTROL(dwxgmac_addrs));
 	u64 period;
 
 	if (!cfg->available)
@@ -1228,7 +1253,7 @@
 
 	if (!enable) {
 		val |= XGMAC_PPSCMDx(index, XGMAC_PPSCMD_STOP);
-		writel(val, ioaddr + XGMAC_PPS_CONTROL);
+		writel(val, ioaddr + XGMAC_PPS_CONTROL(dwxgmac_addrs));
 		return 0;
 	}
 
@@ -1248,11 +1273,11 @@
 	 */
 	val |= XGMAC_PPSENx(index);
 
-	writel(cfg->start.tv_sec, ioaddr + XGMAC_PPSx_TARGET_TIME_SEC(index));
+	writel(cfg->start.tv_sec, ioaddr + XGMAC_PPSx_TARGET_TIME_SEC(dwxgmac_addrs, index));
 
 	if (!(systime_flags & PTP_TCR_TSCTRLSSR))
 		cfg->start.tv_nsec = (cfg->start.tv_nsec * 1000) / 465;
-	writel(cfg->start.tv_nsec, ioaddr + XGMAC_PPSx_TARGET_TIME_NSEC(index));
+	writel(cfg->start.tv_nsec, ioaddr + XGMAC_PPSx_TARGET_TIME_NSEC(dwxgmac_addrs, index));
 
 	period = cfg->period.tv_sec * 1000000000;
 	period += cfg->period.tv_nsec;
@@ -1262,16 +1287,16 @@
 	if (period <= 1)
 		return -EINVAL;
 
-	writel(period - 1, ioaddr + XGMAC_PPSx_INTERVAL(index));
+	writel(period - 1, ioaddr + XGMAC_PPSx_INTERVAL(dwxgmac_addrs, index));
 
 	period >>= 1;
 	if (period <= 1)
 		return -EINVAL;
 
-	writel(period - 1, ioaddr + XGMAC_PPSx_WIDTH(index));
+	writel(period - 1, ioaddr + XGMAC_PPSx_WIDTH(dwxgmac_addrs, index));
 
 	/* Finally, activate it */
-	writel(val, ioaddr + XGMAC_PPS_CONTROL);
+	writel(val, ioaddr + XGMAC_PPS_CONTROL(dwxgmac_addrs));
 	return 0;
 }
 
@@ -1516,7 +1541,6 @@
 
 const struct stmmac_ops dwxgmac210_ops = {
 	.core_init = dwxgmac2_core_init,
-	.phylink_get_caps = xgmac_phylink_get_caps,
 	.set_mac = dwxgmac2_set_mac,
 	.rx_ipc = dwxgmac2_rx_ipc,
 	.rx_queue_enable = dwxgmac2_rx_queue_enable,
@@ -1577,7 +1601,6 @@
 
 const struct stmmac_ops dwxlgmac2_ops = {
 	.core_init = dwxgmac2_core_init,
-	.phylink_get_caps = xgmac_phylink_get_caps,
 	.set_mac = dwxgmac2_set_mac,
 	.rx_ipc = dwxgmac2_rx_ipc,
 	.rx_queue_enable = dwxlgmac2_rx_queue_enable,
@@ -1637,6 +1660,50 @@
 	if (mac->multicast_filter_bins)
 		mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
 
+	mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+			 MAC_1000FD | MAC_2500FD | MAC_5000FD |
+			 MAC_10000FD;
+	mac->link.duplex = 0;
+	mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
+	mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
+	mac->link.speed1000 = XGMAC_CONFIG_SS_1000_GMII;
+	mac->link.speed2500 = XGMAC_CONFIG_SS_2500_GMII;
+	mac->link.xgmii.speed2500 = XGMAC_CONFIG_SS_2500;
+	mac->link.xgmii.speed5000 = XGMAC_CONFIG_SS_5000;
+	mac->link.xgmii.speed10000 = XGMAC_CONFIG_SS_10000;
+	mac->link.speed_mask = XGMAC_CONFIG_SS_MASK;
+
+	mac->mii.addr = XGMAC_MDIO_ADDR;
+	mac->mii.data = XGMAC_MDIO_DATA;
+	mac->mii.addr_shift = 16;
+	mac->mii.addr_mask = GENMASK(20, 16);
+	mac->mii.reg_shift = 0;
+	mac->mii.reg_mask = GENMASK(15, 0);
+	mac->mii.clk_csr_shift = 19;
+	mac->mii.clk_csr_mask = GENMASK(21, 19);
+
+	return 0;
+}
+
+int dw25gmac_setup(struct stmmac_priv *priv)
+{
+	struct mac_device_info *mac = priv->hw;
+
+	dev_info(priv->device, "\tDW25GMAC\n");
+
+	priv->dev->priv_flags |= IFF_UNICAST_FLT;
+	mac->pcsr = priv->ioaddr;
+	mac->multicast_filter_bins = priv->plat->multicast_filter_bins;
+	mac->unicast_filter_entries = priv->plat->unicast_filter_entries;
+	mac->mcast_bits_log2 = 0;
+
+	if (mac->multicast_filter_bins)
+		mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
+
+	mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+			 MAC_10FD | MAC_100FD | MAC_1000FD |
+			 MAC_2500FD | MAC_5000FD |
+			 MAC_10000FD | MAC_25000FD;
 	mac->link.duplex = 0;
 	mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
 	mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
@@ -1645,6 +1712,7 @@
 	mac->link.xgmii.speed2500 = XGMAC_CONFIG_SS_2500;
 	mac->link.xgmii.speed5000 = XGMAC_CONFIG_SS_5000;
 	mac->link.xgmii.speed10000 = XGMAC_CONFIG_SS_10000;
+	mac->link.xgmii.speed25000 = XGMAC_CONFIG_SS_25000;
 	mac->link.speed_mask = XGMAC_CONFIG_SS_MASK;
 
 	mac->mii.addr = XGMAC_MDIO_ADDR;
@@ -1674,6 +1742,11 @@
 	if (mac->multicast_filter_bins)
 		mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
 
+	mac->link.caps = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+			 MAC_1000FD | MAC_2500FD | MAC_5000FD |
+			 MAC_10000FD | MAC_25000FD |
+			 MAC_40000FD | MAC_50000FD |
+			 MAC_100000FD;
 	mac->link.duplex = 0;
 	mac->link.speed1000 = XLGMAC_CONFIG_SS_1000;
 	mac->link.speed2500 = XLGMAC_CONFIG_SS_2500;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
@@ -285,6 +285,8 @@
 {
 	if (le32_to_cpu(p->des3) & XGMAC_RDES3_L34T)
 		*len = le32_to_cpu(p->des2) & XGMAC_RDES2_HL;
+	else if (le32_to_cpu(p->des3) & XGMAC_RDES3_L2T)
+		*len = (le32_to_cpu(p->des2) & XGMAC_RDES2_NONIPHL) >> 2;
 }
 
 static void dwxgmac2_set_sec_addr(struct dma_desc *p, dma_addr_t addr, bool is_valid)
@@ -341,6 +343,17 @@
 	p->des7 = 0;
 }
 
+static void dwxgmac2_set_hw_ts(struct dma_desc *p, u32 pid)
+{
+	p->des0 = 0;
+	p->des1 = 0;
+	p->des2 = 0;
+	p->des3 = 0;
+	p->des0 = cpu_to_le32(pid & XGMAC_TDES0_TTSL);
+	p->des3 |= cpu_to_le32(XGMAC_TDES3_CTXT);
+	p->des3 |= cpu_to_le32(XGMAC_TDES3_PIDV);
+}
+
 const struct stmmac_desc_ops dwxgmac210_desc_ops = {
 	.tx_status = dwxgmac2_get_tx_status,
 	.rx_status = dwxgmac2_get_rx_status,
@@ -370,4 +383,5 @@
 	.set_vlan_tag = dwxgmac2_set_vlan_tag,
 	.set_vlan = dwxgmac2_set_vlan,
 	.set_tbs = dwxgmac2_set_tbs,
+	.set_hw_ts = dwxgmac2_set_hw_ts,
 };
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
@@ -7,6 +7,7 @@
 #include <linux/iopoll.h>
 #include "stmmac.h"
 #include "dwxgmac2.h"
+#include "dw25gmac.h"
 
 static int dwxgmac2_dma_reset(void __iomem *ioaddr)
 {
@@ -19,7 +20,7 @@
 				  !(value & XGMAC_SWR), 0, 100000);
 }
 
-static void dwxgmac2_dma_init(void __iomem *ioaddr,
+static void dwxgmac2_dma_init(struct stmmac_priv *priv, void __iomem *ioaddr,
 			      struct stmmac_dma_cfg *dma_cfg, int atds)
 {
 	u32 value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE);
@@ -37,13 +38,14 @@
 				   void __iomem *ioaddr,
 				   struct stmmac_dma_cfg *dma_cfg, u32 chan)
 {
-	u32 value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(chan));
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+	u32 value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(dwxgmac_addrs, chan));
 
 	if (dma_cfg->pblx8)
 		value |= XGMAC_PBLx8;
 
-	writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(chan));
-	writel(XGMAC_DMA_INT_DEFAULT_EN, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+	writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(dwxgmac_addrs, chan));
+	writel(XGMAC_DMA_INT_DEFAULT_EN, ioaddr + XGMAC_DMA_CH_INT_EN(dwxgmac_addrs, chan));
 }
 
 static void dwxgmac2_dma_init_rx_chan(struct stmmac_priv *priv,
@@ -51,16 +53,17 @@
 				      struct stmmac_dma_cfg *dma_cfg,
 				      dma_addr_t phy, u32 chan)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	u32 rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
 	u32 value;
 
-	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(dwxgmac_addrs, chan));
 	value &= ~XGMAC_RxPBL;
 	value |= (rxpbl << XGMAC_RxPBL_SHIFT) & XGMAC_RxPBL;
-	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(dwxgmac_addrs, chan));
 
-	writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(chan));
-	writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(chan));
+	writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(dwxgmac_addrs, chan));
+	writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(dwxgmac_addrs, chan));
 }
 
 static void dwxgmac2_dma_init_tx_chan(struct stmmac_priv *priv,
@@ -68,17 +71,18 @@
 				      struct stmmac_dma_cfg *dma_cfg,
 				      dma_addr_t phy, u32 chan)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	u32 txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
 	u32 value;
 
-	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan));
 	value &= ~XGMAC_TxPBL;
 	value |= (txpbl << XGMAC_TxPBL_SHIFT) & XGMAC_TxPBL;
 	value |= XGMAC_OSP;
-	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan));
 
-	writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_HADDR(chan));
-	writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chan));
+	writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_HADDR(dwxgmac_addrs, chan));
+	writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(dwxgmac_addrs, chan));
 }
 
 static void dwxgmac2_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
@@ -102,6 +106,9 @@
 	if (!axi->axi_fb)
 		value |= XGMAC_UNDEF;
 
+	if (axi->axi_kbbe)
+		value |= XGMAC_ONEKBBE;
+
 	value &= ~XGMAC_BLEN;
 	for (i = 0; i < AXI_BLEN; i++) {
 		switch (axi->axi_blen[i]) {
@@ -137,16 +144,18 @@
 static void dwxgmac2_dma_dump_regs(struct stmmac_priv *priv,
 				   void __iomem *ioaddr, u32 *reg_space)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	int i;
 
-	for (i = (XGMAC_DMA_MODE / 4); i < XGMAC_REGSIZE; i++)
+	for (i = (XGMAC_DMA_MODE / 4); i < XGMAC_REGSIZE(dwxgmac_addrs); i++)
 		reg_space[i] = readl(ioaddr + i * 4);
 }
 
 static void dwxgmac2_dma_rx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
 				 int mode, u32 channel, int fifosz, u8 qmode)
 {
-	u32 value = readl(ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+	u32 value = readl(ioaddr + XGMAC_MTL_RXQ_OPMODE(dwxgmac_addrs, channel));
 	unsigned int rqs = fifosz / 256 - 1;
 
 	if (mode == SF_DMA_MODE) {
@@ -167,7 +176,7 @@
 	value |= (rqs << XGMAC_RQS_SHIFT) & XGMAC_RQS;
 
 	if ((fifosz >= 4096) && (qmode != MTL_QUEUE_AVB)) {
-		u32 flow = readl(ioaddr + XGMAC_MTL_RXQ_FLOW_CONTROL(channel));
+		u32 flow = readl(ioaddr + XGMAC_MTL_RXQ_FLOW_CONTROL(dwxgmac_addrs, channel));
 		unsigned int rfd, rfa;
 
 		value |= XGMAC_EHFC;
@@ -199,20 +208,21 @@
 		flow &= ~XGMAC_RFA;
 		flow |= rfa << XGMAC_RFA_SHIFT;
 
-		writel(flow, ioaddr + XGMAC_MTL_RXQ_FLOW_CONTROL(channel));
+		writel(flow, ioaddr + XGMAC_MTL_RXQ_FLOW_CONTROL(dwxgmac_addrs, channel));
 	}
 
-	writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+	writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(dwxgmac_addrs, channel));
 
 	/* Enable MTL RX overflow */
-	value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
-	writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+	value = readl(ioaddr + XGMAC_MTL_QINTEN(dwxgmac_addrs, channel));
+	writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(dwxgmac_addrs, channel));
 }
 
 static void dwxgmac2_dma_tx_mode(struct stmmac_priv *priv, void __iomem *ioaddr,
 				 int mode, u32 channel, int fifosz, u8 qmode)
 {
-	u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(channel));
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+	u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(dwxgmac_addrs, channel));
 	unsigned int tqs = fifosz / 256 - 1;
 
 	if (mode == SF_DMA_MODE) {
@@ -249,45 +259,48 @@
 	value &= ~XGMAC_TQS;
 	value |= (tqs << XGMAC_TQS_SHIFT) & XGMAC_TQS;
 
-	writel(value, ioaddr +  XGMAC_MTL_TXQ_OPMODE(channel));
+	writel(value, ioaddr + XGMAC_MTL_TXQ_OPMODE(dwxgmac_addrs, channel));
 }
 
 static void dwxgmac2_enable_dma_irq(struct stmmac_priv *priv,
 				    void __iomem *ioaddr, u32 chan,
 				    bool rx, bool tx)
 {
-	u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+	u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(dwxgmac_addrs, chan));
 
 	if (rx)
 		value |= XGMAC_DMA_INT_DEFAULT_RX;
 	if (tx)
 		value |= XGMAC_DMA_INT_DEFAULT_TX;
 
-	writel(value, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+	writel(value, ioaddr + XGMAC_DMA_CH_INT_EN(dwxgmac_addrs, chan));
 }
 
 static void dwxgmac2_disable_dma_irq(struct stmmac_priv *priv,
 				     void __iomem *ioaddr, u32 chan,
 				     bool rx, bool tx)
 {
-	u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+	u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(dwxgmac_addrs, chan));
 
 	if (rx)
 		value &= ~XGMAC_DMA_INT_DEFAULT_RX;
 	if (tx)
 		value &= ~XGMAC_DMA_INT_DEFAULT_TX;
 
-	writel(value, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+	writel(value, ioaddr + XGMAC_DMA_CH_INT_EN(dwxgmac_addrs, chan));
 }
 
 static void dwxgmac2_dma_start_tx(struct stmmac_priv *priv,
 				  void __iomem *ioaddr, u32 chan)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	u32 value;
 
-	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan));
 	value |= XGMAC_TXST;
-	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan));
 
 	value = readl(ioaddr + XGMAC_TX_CONFIG);
 	value |= XGMAC_CONFIG_TE;
@@ -297,11 +310,12 @@
 static void dwxgmac2_dma_stop_tx(struct stmmac_priv *priv, void __iomem *ioaddr,
 				 u32 chan)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	u32 value;
 
-	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan));
 	value &= ~XGMAC_TXST;
-	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan));
 
 	value = readl(ioaddr + XGMAC_TX_CONFIG);
 	value &= ~XGMAC_CONFIG_TE;
@@ -311,11 +325,12 @@
 static void dwxgmac2_dma_start_rx(struct stmmac_priv *priv,
 				  void __iomem *ioaddr, u32 chan)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	u32 value;
 
-	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(dwxgmac_addrs, chan));
 	value |= XGMAC_RXST;
-	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(dwxgmac_addrs, chan));
 
 	value = readl(ioaddr + XGMAC_RX_CONFIG);
 	value |= XGMAC_CONFIG_RE;
@@ -325,11 +340,12 @@
 static void dwxgmac2_dma_stop_rx(struct stmmac_priv *priv, void __iomem *ioaddr,
 				 u32 chan)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	u32 value;
 
-	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(dwxgmac_addrs, chan));
 	value &= ~XGMAC_RXST;
-	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(dwxgmac_addrs, chan));
 }
 
 static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
@@ -338,8 +354,10 @@
 				  u32 dir)
 {
 	struct stmmac_pcpu_stats *stats = this_cpu_ptr(priv->xstats.pcpu_stats);
-	u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan));
-	u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+	u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(dwxgmac_addrs, chan));
+	u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(dwxgmac_addrs, chan));
+
 	int ret = 0;
 
 	if (dir == DMA_DIR_RX)
@@ -380,7 +398,7 @@
 	}
 
 	/* Clear interrupts */
-	writel(intr_en & intr_status, ioaddr + XGMAC_DMA_CH_STATUS(chan));
+	writel(intr_en & intr_status, ioaddr + XGMAC_DMA_CH_STATUS(dwxgmac_addrs, chan));
 
 	return ret;
 }
@@ -500,108 +518,151 @@
 	return 0;
 }
 
+static int dw25gmac_get_hw_feature(void __iomem *ioaddr,
+				   struct dma_features *dma_cap)
+
+{
+	u32 hw_cap;
+	int ret;
+
+	ret = dwxgmac2_get_hw_feature(ioaddr, dma_cap);
+
+	/* For DW25GMAC VDMA channel count is channel count */
+	hw_cap = readl(ioaddr + XGMAC_HW_FEATURE2);
+	dma_cap->number_tx_channel =
+		dw25gmac_decode_vdma_count(FIELD_GET(XXVGMAC_HWFEAT_VDMA_TXCNT,
+						     hw_cap));
+	dma_cap->number_rx_channel =
+		dw25gmac_decode_vdma_count(FIELD_GET(XXVGMAC_HWFEAT_VDMA_RXCNT,
+						     hw_cap));
+
+	return ret;
+}
+
 static void dwxgmac2_rx_watchdog(struct stmmac_priv *priv, void __iomem *ioaddr,
 				 u32 riwt, u32 queue)
 {
-	writel(riwt & XGMAC_RWT, ioaddr + XGMAC_DMA_CH_Rx_WATCHDOG(queue));
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+
+	writel(riwt & XGMAC_RWT, ioaddr + XGMAC_DMA_CH_Rx_WATCHDOG(dwxgmac_addrs, queue));
 }
 
 static void dwxgmac2_set_rx_ring_len(struct stmmac_priv *priv,
 				     void __iomem *ioaddr, u32 len, u32 chan)
 {
-	writel(len, ioaddr + XGMAC_DMA_CH_RxDESC_RING_LEN(chan));
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+
+	writel(len, ioaddr + XGMAC_DMA_CH_RxDESC_RING_LEN(dwxgmac_addrs, chan));
 }
 
 static void dwxgmac2_set_tx_ring_len(struct stmmac_priv *priv,
 				     void __iomem *ioaddr, u32 len, u32 chan)
 {
-	writel(len, ioaddr + XGMAC_DMA_CH_TxDESC_RING_LEN(chan));
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+
+	writel(len, ioaddr + XGMAC_DMA_CH_TxDESC_RING_LEN(dwxgmac_addrs, chan));
 }
 
 static void dwxgmac2_set_rx_tail_ptr(struct stmmac_priv *priv,
 				     void __iomem *ioaddr, u32 ptr, u32 chan)
 {
-	writel(ptr, ioaddr + XGMAC_DMA_CH_RxDESC_TAIL_LPTR(chan));
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+
+	writel(ptr, ioaddr + XGMAC_DMA_CH_RxDESC_TAIL_LPTR(dwxgmac_addrs, chan));
 }
 
 static void dwxgmac2_set_tx_tail_ptr(struct stmmac_priv *priv,
 				     void __iomem *ioaddr, u32 ptr, u32 chan)
 {
-	writel(ptr, ioaddr + XGMAC_DMA_CH_TxDESC_TAIL_LPTR(chan));
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+
+	writel(ptr, ioaddr + XGMAC_DMA_CH_TxDESC_TAIL_LPTR(dwxgmac_addrs, chan));
 }
 
 static void dwxgmac2_enable_tso(struct stmmac_priv *priv, void __iomem *ioaddr,
 				bool en, u32 chan)
 {
-	u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+
+	u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan));
 
 	if (en)
 		value |= XGMAC_TSE;
 	else
 		value &= ~XGMAC_TSE;
 
-	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan));
 }
 
 static void dwxgmac2_qmode(struct stmmac_priv *priv, void __iomem *ioaddr,
 			   u32 channel, u8 qmode)
 {
-	u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(channel));
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+	u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(dwxgmac_addrs, channel));
+
 	u32 flow = readl(ioaddr + XGMAC_RX_FLOW_CTRL);
 
 	value &= ~XGMAC_TXQEN;
 	if (qmode != MTL_QUEUE_AVB) {
 		value |= 0x2 << XGMAC_TXQEN_SHIFT;
-		writel(0, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(channel));
+		writel(0, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(dwxgmac_addrs, channel));
 	} else {
 		value |= 0x1 << XGMAC_TXQEN_SHIFT;
 		writel(flow & (~XGMAC_RFE), ioaddr + XGMAC_RX_FLOW_CTRL);
 	}
 
-	writel(value, ioaddr +  XGMAC_MTL_TXQ_OPMODE(channel));
+	writel(value, ioaddr + XGMAC_MTL_TXQ_OPMODE(dwxgmac_addrs, channel));
 }
 
 static void dwxgmac2_set_bfsize(struct stmmac_priv *priv, void __iomem *ioaddr,
 				int bfsize, u32 chan)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	u32 value;
 
-	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(dwxgmac_addrs, chan));
 	value &= ~XGMAC_RBSZ;
 	value |= bfsize << XGMAC_RBSZ_SHIFT;
-	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(dwxgmac_addrs, chan));
 }
 
 static void dwxgmac2_enable_sph(struct stmmac_priv *priv, void __iomem *ioaddr,
 				bool en, u32 chan)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	u32 value = readl(ioaddr + XGMAC_RX_CONFIG);
 
 	value &= ~XGMAC_CONFIG_HDSMS;
 	value |= XGMAC_CONFIG_HDSMS_256; /* Segment max 256 bytes */
 	writel(value, ioaddr + XGMAC_RX_CONFIG);
 
-	value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(chan));
+	value = readl(ioaddr + XGMAC_EXT_CFG1);
+	value |= XGMAC_CONFIG1_SPLM(1);
+	value |= XGMAC_CONFIG1_SAVE_EN;
+	writel(value, ioaddr + XGMAC_EXT_CFG1);
+
+	value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(dwxgmac_addrs, chan));
 	if (en)
 		value |= XGMAC_SPH;
 	else
 		value &= ~XGMAC_SPH;
-	writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(chan));
+	writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(dwxgmac_addrs, chan));
 }
 
 static int dwxgmac2_enable_tbs(struct stmmac_priv *priv, void __iomem *ioaddr,
 			       bool en, u32 chan)
 {
-	u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
+	u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan));
 
 	if (en)
 		value |= XGMAC_EDSE;
 	else
 		value &= ~XGMAC_EDSE;
 
-	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan));
 
-	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan)) & XGMAC_EDSE;
+	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(dwxgmac_addrs, chan)) & XGMAC_EDSE;
 	if (en && !value)
 		return -EIO;
 
@@ -633,6 +694,39 @@
 	.rx_watchdog = dwxgmac2_rx_watchdog,
 	.set_rx_ring_len = dwxgmac2_set_rx_ring_len,
 	.set_tx_ring_len = dwxgmac2_set_tx_ring_len,
+	.set_rx_tail_ptr = dwxgmac2_set_rx_tail_ptr,
+	.set_tx_tail_ptr = dwxgmac2_set_tx_tail_ptr,
+	.enable_tso = dwxgmac2_enable_tso,
+	.qmode = dwxgmac2_qmode,
+	.set_bfsize = dwxgmac2_set_bfsize,
+	.enable_sph = dwxgmac2_enable_sph,
+	.enable_tbs = dwxgmac2_enable_tbs,
+};
+
+const struct stmmac_dma_ops dw25gmac400_dma_ops = {
+	.reset = dwxgmac2_dma_reset,
+	.init = dw25gmac_dma_init,
+	.init_chan = dwxgmac2_dma_init_chan,
+	.init_rx_chan = dw25gmac_dma_init_rx_chan,
+	.init_tx_chan = dw25gmac_dma_init_tx_chan,
+	.map_tx_offline_chan = dw25gmac_dma_map_tx_offline_chan,
+	.map_rx_offline_chan = dw25gmac_dma_map_rx_offline_chan,
+	.desc_cache_compute = dw25gmac_desc_cache_compute,
+	.axi = dwxgmac2_dma_axi,
+	.dump_regs = dwxgmac2_dma_dump_regs,
+	.dma_rx_mode = dwxgmac2_dma_rx_mode,
+	.dma_tx_mode = dwxgmac2_dma_tx_mode,
+	.enable_dma_irq = dwxgmac2_enable_dma_irq,
+	.disable_dma_irq = dwxgmac2_disable_dma_irq,
+	.start_tx = dwxgmac2_dma_start_tx,
+	.stop_tx = dwxgmac2_dma_stop_tx,
+	.start_rx = dwxgmac2_dma_start_rx,
+	.stop_rx = dwxgmac2_dma_stop_rx,
+	.dma_interrupt = dwxgmac2_dma_interrupt,
+	.get_hw_feature = dw25gmac_get_hw_feature,
+	.rx_watchdog = dwxgmac2_rx_watchdog,
+	.set_rx_ring_len = dwxgmac2_set_rx_ring_len,
+	.set_tx_ring_len = dwxgmac2_set_tx_ring_len,
 	.set_rx_tail_ptr = dwxgmac2_set_rx_tail_ptr,
 	.set_tx_tail_ptr = dwxgmac2_set_tx_tail_ptr,
 	.enable_tso = dwxgmac2_enable_tso,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -278,11 +278,31 @@
 		.est = &dwmac510_est_ops,
 		.setup = dwxlgmac2_setup,
 		.quirks = stmmac_dwxlgmac_quirks,
+	}, {
+		.gmac = false,
+		.gmac4 = false,
+		.xgmac = true,
+		.min_id = DW25GMAC_CORE_4_00,
+		.dev_id = DW25GMAC_ID,
+		.regs = {
+			.ptp_off = PTP_XGMAC_OFFSET,
+			.mmc_off = MMC_XGMAC_OFFSET,
+		},
+		.desc = &dwxgmac210_desc_ops,
+		.dma = &dw25gmac400_dma_ops,
+		.mac = &dwxgmac210_ops,
+		.hwtimestamp = &stmmac_ptp,
+		.mode = NULL,
+		.tc = &dwmac510_tc_ops,
+		.mmc = &dw25gmac_mmc_ops,
+		.setup = dw25gmac_setup,
+		.quirks = NULL,
 	},
 };
 
 int stmmac_hwif_init(struct stmmac_priv *priv)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	bool needs_xgmac = priv->plat->has_xgmac;
 	bool needs_gmac4 = priv->plat->has_gmac4;
 	bool needs_gmac = priv->plat->has_gmac;
@@ -292,7 +312,10 @@
 	u32 id, dev_id = 0;
 	int i, ret;
 
-	if (needs_gmac) {
+	if (priv->plat->snps_id && priv->plat->dev_id) {
+		id = priv->plat->snps_id;
+		dev_id = priv->plat->dev_id;
+	} else if (needs_gmac) {
 		id = stmmac_get_id(priv, GMAC_VERSION);
 	} else if (needs_gmac4 || needs_xgmac) {
 		id = stmmac_get_id(priv, GMAC4_VERSION);
@@ -353,7 +376,8 @@
 		mac->est = mac->est ? : entry->est;
 
 		priv->hw = mac;
-		priv->ptpaddr = priv->ioaddr + entry->regs.ptp_off;
+		priv->ptpaddr = priv->ioaddr +
+			(dwxgmac_addrs ? dwxgmac_addrs->timestamp_base : entry->regs.ptp_off);
 		priv->mmcaddr = priv->ioaddr + entry->regs.mmc_off;
 		if (entry->est)
 			priv->estaddr = priv->ioaddr + entry->regs.est_off;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -101,6 +101,7 @@
 			     u32 inner_type);
 	void (*set_vlan)(struct dma_desc *p, u32 type);
 	void (*set_tbs)(struct dma_edesc *p, u32 sec, u32 nsec);
+	void (*set_hw_ts)(struct dma_desc *p, u32 pid);
 };
 
 #define stmmac_init_rx_desc(__priv, __args...) \
@@ -167,6 +168,8 @@
 	stmmac_do_void_callback(__priv, desc, set_vlan, __args)
 #define stmmac_set_desc_tbs(__priv, __args...) \
 	stmmac_do_void_callback(__priv, desc, set_tbs, __args)
+#define stmmac_set_desc_hw_ts(__priv, __args...) \
+	stmmac_do_void_callback(__priv, desc, set_hw_ts, __args)
 
 struct stmmac_dma_cfg;
 struct dma_features;
@@ -175,7 +178,7 @@
 struct stmmac_dma_ops {
 	/* DMA core initialization */
 	int (*reset)(void __iomem *ioaddr);
-	void (*init)(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg,
+	void (*init)(struct stmmac_priv *priv, void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg,
 		     int atds);
 	void (*init_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
 			  struct stmmac_dma_cfg *dma_cfg, u32 chan);
@@ -185,6 +188,13 @@
 	void (*init_tx_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
 			     struct stmmac_dma_cfg *dma_cfg,
 			     dma_addr_t phy, u32 chan);
+	void (*map_rx_offline_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
+				    struct stmmac_dma_cfg *dma_cfg,
+				    u32 chan);
+	void (*map_tx_offline_chan)(struct stmmac_priv *priv, void __iomem *ioaddr,
+				    struct stmmac_dma_cfg *dma_cfg,
+				    u32 chan);
+	void (*desc_cache_compute)(void __iomem *ioaddr);
 	/* Configure the AXI Bus Mode Register */
 	void (*axi)(void __iomem *ioaddr, struct stmmac_axi *axi);
 	/* Dump DMA registers */
@@ -240,13 +250,19 @@
 };
 
 #define stmmac_dma_init(__priv, __args...) \
-	stmmac_do_void_callback(__priv, dma, init, __args)
+	stmmac_do_void_callback(__priv, dma, init, __priv, __args)
 #define stmmac_init_chan(__priv, __args...) \
 	stmmac_do_void_callback(__priv, dma, init_chan, __priv, __args)
 #define stmmac_init_rx_chan(__priv, __args...) \
 	stmmac_do_void_callback(__priv, dma, init_rx_chan, __priv, __args)
 #define stmmac_init_tx_chan(__priv, __args...) \
 	stmmac_do_void_callback(__priv, dma, init_tx_chan, __priv, __args)
+#define stmmac_map_rx_offline_chan(__priv, __args...) \
+	stmmac_do_void_callback(__priv, dma, map_rx_offline_chan, __priv, __args)
+#define stmmac_map_tx_offline_chan(__priv, __args...) \
+	stmmac_do_void_callback(__priv, dma, map_tx_offline_chan, __priv, __args)
+#define stmmac_desc_cache_compute(__priv, __args...) \
+	stmmac_do_void_callback(__priv, dma, desc_cache_compute, __args)
 #define stmmac_axi(__priv, __args...) \
 	stmmac_do_void_callback(__priv, dma, axi, __args)
 #define stmmac_dump_dma_regs(__priv, __args...) \
@@ -326,7 +342,8 @@
 	/* Program RX Algorithms */
 	void (*prog_mtl_rx_algorithms)(struct mac_device_info *hw, u32 rx_alg);
 	/* Program TX Algorithms */
-	void (*prog_mtl_tx_algorithms)(struct mac_device_info *hw, u32 tx_alg);
+	void (*prog_mtl_tx_algorithms)(struct stmmac_priv *priv, struct mac_device_info *hw,
+				       u32 tx_alg);
 	/* Set MTL TX queues weight */
 	void (*set_mtl_tx_queue_weight)(struct stmmac_priv *priv,
 					struct mac_device_info *hw,
@@ -338,7 +355,9 @@
 			   u32 send_slope, u32 idle_slope, u32 high_credit,
 			   u32 low_credit, u32 queue);
 	/* Dump MAC registers */
-	void (*dump_regs)(struct mac_device_info *hw, u32 *reg_space);
+	void (*dump_regs)(struct stmmac_priv *priv,
+			  struct mac_device_info *hw,
+			  u32 *reg_space);
 	/* Handle extra events on specific interrupts hw dependent */
 	int (*host_irq_status)(struct mac_device_info *hw,
 			       struct stmmac_extra_stats *x);
@@ -384,7 +403,7 @@
 	int (*rxp_config)(void __iomem *ioaddr, struct stmmac_tc_entry *entries,
 			  unsigned int count);
 	/* Flexible PPS */
-	int (*flex_pps_config)(void __iomem *ioaddr, int index,
+	int (*flex_pps_config)(struct stmmac_priv *priv, void __iomem *ioaddr, int index,
 			       struct stmmac_pps_cfg *cfg, bool enable,
 			       u32 sub_second_inc, u32 systime_flags);
 	/* Loopback for selftests */
@@ -394,7 +413,7 @@
 			     struct stmmac_rss *cfg, u32 num_rxq);
 	/* VLAN */
 	void (*update_vlan_hash)(struct mac_device_info *hw, u32 hash,
-				 __le16 perfect_match, bool is_double);
+				 u16 perfect_match, bool is_double);
 	void (*enable_vlan)(struct mac_device_info *hw, u32 type);
 	void (*rx_hw_vlan)(struct mac_device_info *hw, struct dma_desc *rx_desc,
 			   struct sk_buff *skb);
@@ -408,7 +427,7 @@
 	void (*restore_hw_vlan_rx_fltr)(struct net_device *dev,
 					struct mac_device_info *hw);
 	/* TX Timestamp */
-	int (*get_mac_tx_timestamp)(struct mac_device_info *hw, u64 *ts);
+	int (*get_mac_tx_timestamp)(struct stmmac_priv *priv, struct mac_device_info *hw, u64 *ts);
 	/* Source Address Insertion / Replacement */
 	void (*sarc_configure)(void __iomem *ioaddr, int val);
 	/* Filtering */
@@ -447,7 +466,7 @@
 #define stmmac_prog_mtl_rx_algorithms(__priv, __args...) \
 	stmmac_do_void_callback(__priv, mac, prog_mtl_rx_algorithms, __args)
 #define stmmac_prog_mtl_tx_algorithms(__priv, __args...) \
-	stmmac_do_void_callback(__priv, mac, prog_mtl_tx_algorithms, __args)
+	stmmac_do_void_callback(__priv, mac, prog_mtl_tx_algorithms, __priv, __args)
 #define stmmac_set_mtl_tx_queue_weight(__priv, __args...) \
 	stmmac_do_void_callback(__priv, mac, set_mtl_tx_queue_weight, __priv, __args)
 #define stmmac_map_mtl_to_dma(__priv, __args...) \
@@ -455,7 +474,7 @@
 #define stmmac_config_cbs(__priv, __args...) \
 	stmmac_do_void_callback(__priv, mac, config_cbs, __priv, __args)
 #define stmmac_dump_mac_regs(__priv, __args...) \
-	stmmac_do_void_callback(__priv, mac, dump_regs, __args)
+	stmmac_do_void_callback(__priv, mac, dump_regs, __priv, __args)
 #define stmmac_host_irq_status(__priv, __args...) \
 	stmmac_do_callback(__priv, mac, host_irq_status, __args)
 #define stmmac_host_mtl_irq_status(__priv, __args...) \
@@ -497,7 +516,7 @@
 #define stmmac_rxp_config(__priv, __args...) \
 	stmmac_do_callback(__priv, mac, rxp_config, __args)
 #define stmmac_flex_pps_config(__priv, __args...) \
-	stmmac_do_callback(__priv, mac, flex_pps_config, __args)
+	stmmac_do_callback(__priv, mac, flex_pps_config, __priv, __args)
 #define stmmac_set_mac_loopback(__priv, __args...) \
 	stmmac_do_void_callback(__priv, mac, set_mac_loopback, __args)
 #define stmmac_rss_configure(__priv, __args...) \
@@ -517,7 +536,7 @@
 #define stmmac_restore_hw_vlan_rx_fltr(__priv, __args...) \
 	stmmac_do_void_callback(__priv, mac, restore_hw_vlan_rx_fltr, __args)
 #define stmmac_get_mac_tx_timestamp(__priv, __args...) \
-	stmmac_do_callback(__priv, mac, get_mac_tx_timestamp, __args)
+	stmmac_do_callback(__priv, mac, get_mac_tx_timestamp, __priv, __args)
 #define stmmac_sarc_configure(__priv, __args...) \
 	stmmac_do_void_callback(__priv, mac, sarc_configure, __args)
 #define stmmac_config_l3_filter(__priv, __args...) \
@@ -686,6 +705,8 @@
 extern const struct stmmac_mmc_ops dwmac_mmc_ops;
 extern const struct stmmac_mmc_ops dwxgmac_mmc_ops;
 extern const struct stmmac_est_ops dwmac510_est_ops;
+extern const struct stmmac_mmc_ops dw25gmac_mmc_ops;
+extern const struct stmmac_dma_ops dw25gmac400_dma_ops;
 
 #define GMAC_VERSION		0x00000020	/* GMAC CORE Version */
 #define GMAC4_VERSION		0x00000110	/* GMAC4+ CORE Version */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/mmc.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/mmc.h
@@ -21,6 +21,7 @@
 						 * current value.*/
 #define MMC_CNTRL_PRESET		0x10
 #define MMC_CNTRL_FULL_HALF_PRESET	0x20
+#define MMC_CNTRL_DRCHM			BIT(31)
 
 #define MMC_GMAC4_OFFSET		0x700
 #define MMC_GMAC3_X_OFFSET		0x100
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/mmc_core.c
@@ -224,6 +224,43 @@
 #define MMC_XGMAC_RX_ICMP_GD_OCTETS	0x334
 #define MMC_XGMAC_RX_ICMP_ERR_OCTETS	0x33c
 
+/* 25GMAC MMC registers */
+#define MMC_25GMAC_RX_IPC_INTR				0x260
+
+/* IPv4 */
+#define MMC_25GMAC_RX_IPV4_GD				0x264
+#define MMC_25GMAC_RX_IPV4_HDERR			0x26c
+#define MMC_25GMAC_RX_IPV4_NOPAY			0x274
+#define MMC_25GMAC_RX_IPV4_FRAG				0x27c
+#define MMC_25GMAC_RX_IPV4_UDSBL			0x284
+#define MMC_25GMAC_RX_IPV4_GD_OCTETS			0x2d4
+#define MMC_25GMAC_RX_IPV4_HDERR_OCTETS			0x2dc
+#define MMC_25GMAC_RX_IPV4_NOPAY_OCTETS			0x2e4
+#define MMC_25GMAC_RX_IPV4_FRAG_OCTETS			0x2ec
+#define MMC_25GMAC_RX_IPV4_UDSBL_OCTETS			0x2f4
+
+/* IPV6 */
+#define MMC_25GMAC_RX_IPV6_GD				0x28c
+#define MMC_25GMAC_RX_IPV6_HDERR			0x294
+#define MMC_25GMAC_RX_IPV6_NOPAY			0x29c
+#define MMC_25GMAC_RX_IPV6_GD_OCTETS			0x2fc
+#define MMC_25GMAC_RX_IPV6_HDERR_OCTETS			0x304
+#define MMC_25GMAC_RX_IPV6_NOPAY_OCTETS			0x30c
+
+/* Protocols */
+#define MMC_25GMAC_RX_UDP_GD				0x2a4
+#define MMC_25GMAC_RX_UDP_ERR				0x2ac
+#define MMC_25GMAC_RX_TCP_GD				0x2b4
+#define MMC_25GMAC_RX_TCP_ERR				0x2bc
+#define MMC_25GMAC_RX_ICMP_GD				0x2c4
+#define MMC_25GMAC_RX_ICMP_ERR				0x2cc
+#define MMC_25GMAC_RX_UDP_GD_OCTETS			0x314
+#define MMC_25GMAC_RX_UDP_ERR_OCTETS			0x31c
+#define MMC_25GMAC_RX_TCP_GD_OCTETS			0x324
+#define MMC_25GMAC_RX_TCP_ERR_OCTETS			0x32c
+#define MMC_25GMAC_RX_ICMP_GD_OCTETS			0x334
+#define MMC_25GMAC_RX_ICMP_ERR_OCTETS			0x33c
+
 static void dwmac_mmc_ctrl(void __iomem *mmcaddr, unsigned int mode)
 {
 	u32 value = readl(mmcaddr + MMC_CNTRL);
@@ -592,3 +629,189 @@
 	.intr_all_mask = dwxgmac_mmc_intr_all_mask,
 	.read = dwxgmac_mmc_read,
 };
+
+static void dw25gmac_mmc_ctrl(void __iomem *mmcaddr, unsigned int mode)
+{
+	u32 value = readl(mmcaddr + MMC_CNTRL);
+
+	value |= (mode & 0x3F);
+	/* This field disables receive channels mapping for certain set of
+	 * Receive Frame/Priority/IPC MAC Management Counters.
+	 * Application should set this field to 1 to disable it.
+	 */
+	value |= (mode & 0x80000000);
+
+	writel(value, mmcaddr + MMC_CNTRL);
+}
+
+/* This reads the MAC core counters (if actaully supported).
+ * by default the MMC core is programmed to reset each
+ * counter after a read. So all the field of the mmc struct
+ * have to be incremented.
+ */
+static void dw25gmac_mmc_read(void __iomem *mmcaddr, struct stmmac_counters *mmc)
+{
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_OCTET_GB,
+			     &mmc->mmc_tx_octetcount_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_PKT_GB,
+			     &mmc->mmc_tx_framecount_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_BROAD_PKT_G,
+			     &mmc->mmc_tx_broadcastframe_g);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_MULTI_PKT_G,
+			     &mmc->mmc_tx_multicastframe_g);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_64OCT_GB,
+			     &mmc->mmc_tx_64_octets_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_65OCT_GB,
+			     &mmc->mmc_tx_65_to_127_octets_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_128OCT_GB,
+			     &mmc->mmc_tx_128_to_255_octets_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_256OCT_GB,
+			     &mmc->mmc_tx_256_to_511_octets_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_512OCT_GB,
+			     &mmc->mmc_tx_512_to_1023_octets_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_1024OCT_GB,
+			     &mmc->mmc_tx_1024_to_max_octets_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_UNI_PKT_GB,
+			     &mmc->mmc_tx_unicast_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_MULTI_PKT_GB,
+			     &mmc->mmc_tx_multicast_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_BROAD_PKT_GB,
+			     &mmc->mmc_tx_broadcast_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_UNDER,
+			     &mmc->mmc_tx_underflow_error);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_OCTET_G,
+			     &mmc->mmc_tx_octetcount_g);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_PKT_G,
+			     &mmc->mmc_tx_framecount_g);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_PAUSE,
+			     &mmc->mmc_tx_pause_frame);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_TX_VLAN_PKT_G,
+			     &mmc->mmc_tx_vlan_frame_g);
+
+	/* MMC RX counter registers */
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_PKT_GB,
+			     &mmc->mmc_rx_framecount_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_OCTET_GB,
+			     &mmc->mmc_rx_octetcount_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_OCTET_G,
+			     &mmc->mmc_rx_octetcount_g);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_BROAD_PKT_G,
+			     &mmc->mmc_rx_broadcastframe_g);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_MULTI_PKT_G,
+			     &mmc->mmc_rx_multicastframe_g);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_CRC_ERR,
+			     &mmc->mmc_rx_crc_error);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_CRC_ERR,
+			     &mmc->mmc_rx_crc_error);
+	mmc->mmc_rx_run_error += readl(mmcaddr + MMC_XGMAC_RX_RUNT_ERR);
+	mmc->mmc_rx_jabber_error += readl(mmcaddr + MMC_XGMAC_RX_JABBER_ERR);
+	mmc->mmc_rx_undersize_g += readl(mmcaddr + MMC_XGMAC_RX_UNDER);
+	mmc->mmc_rx_oversize_g += readl(mmcaddr + MMC_XGMAC_RX_OVER);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_64OCT_GB,
+			     &mmc->mmc_rx_64_octets_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_65OCT_GB,
+			     &mmc->mmc_rx_65_to_127_octets_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_128OCT_GB,
+			     &mmc->mmc_rx_128_to_255_octets_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_256OCT_GB,
+			     &mmc->mmc_rx_256_to_511_octets_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_512OCT_GB,
+			     &mmc->mmc_rx_512_to_1023_octets_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_1024OCT_GB,
+			     &mmc->mmc_rx_1024_to_max_octets_gb);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_UNI_PKT_G,
+			     &mmc->mmc_rx_unicast_g);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_LENGTH_ERR,
+			     &mmc->mmc_rx_length_error);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_RANGE,
+			     &mmc->mmc_rx_autofrangetype);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_PAUSE,
+			     &mmc->mmc_rx_pause_frames);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_FIFOOVER_PKT,
+			     &mmc->mmc_rx_fifo_overflow);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_XGMAC_RX_VLAN_PKT_GB,
+			     &mmc->mmc_rx_vlan_frames_gb);
+	mmc->mmc_rx_watchdog_error += readl(mmcaddr + MMC_XGMAC_RX_WATCHDOG_ERR);
+	mmc->mmc_rx_ipc_intr_mask = readl(mmcaddr + MMC_XGMAC_RX_IPC_INTR_MASK);
+
+	mmc->mmc_tx_fpe_fragment_cntr += readl(mmcaddr + MMC_XGMAC_TX_FPE_FRAG);
+	mmc->mmc_tx_hold_req_cntr += readl(mmcaddr + MMC_XGMAC_TX_HOLD_REQ);
+	mmc->mmc_rx_packet_assembly_err_cntr +=
+		readl(mmcaddr + MMC_XGMAC_RX_PKT_ASSEMBLY_ERR);
+	mmc->mmc_rx_packet_smd_err_cntr +=
+		readl(mmcaddr + MMC_XGMAC_RX_PKT_SMD_ERR);
+	mmc->mmc_rx_packet_assembly_ok_cntr +=
+		readl(mmcaddr + MMC_XGMAC_RX_PKT_ASSEMBLY_OK);
+	mmc->mmc_rx_fpe_fragment_cntr +=
+		readl(mmcaddr + MMC_XGMAC_RX_FPE_FRAG);
+
+	/* Additional 25GMAC counters */
+	mmc->mmc_rx_ipc_intr = readl(mmcaddr + MMC_25GMAC_RX_IPC_INTR);
+	/* IPv4 */
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV4_GD,
+			     &mmc->mmc_rx_ipv4_gd);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV4_HDERR,
+			     &mmc->mmc_rx_ipv4_hderr);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV4_NOPAY,
+			     &mmc->mmc_rx_ipv4_nopay);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV4_FRAG,
+			     &mmc->mmc_rx_ipv4_frag);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV4_UDSBL,
+			     &mmc->mmc_rx_ipv4_udsbl);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV4_GD_OCTETS,
+			     &mmc->mmc_rx_ipv4_gd_octets);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV4_HDERR_OCTETS,
+			     &mmc->mmc_rx_ipv4_hderr_octets);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV4_NOPAY_OCTETS,
+			     &mmc->mmc_rx_ipv4_nopay_octets);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV4_FRAG_OCTETS,
+			     &mmc->mmc_rx_ipv4_frag_octets);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV4_UDSBL_OCTETS,
+			     &mmc->mmc_rx_ipv4_udsbl_octets);
+
+	/* IPV6 */
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV6_GD,
+			     &mmc->mmc_rx_ipv6_gd);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV6_HDERR,
+			     &mmc->mmc_rx_ipv6_hderr);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV6_NOPAY,
+			     &mmc->mmc_rx_ipv6_nopay);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV6_GD_OCTETS,
+			     &mmc->mmc_rx_ipv6_gd_octets);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV6_HDERR_OCTETS,
+			     &mmc->mmc_rx_ipv6_hderr_octets);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_IPV6_NOPAY_OCTETS,
+			     &mmc->mmc_rx_ipv6_nopay_octets);
+
+	/* Protocols */
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_UDP_GD,
+			     &mmc->mmc_rx_udp_gd);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_UDP_ERR,
+			     &mmc->mmc_rx_udp_err);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_TCP_GD,
+			     &mmc->mmc_rx_tcp_gd);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_TCP_ERR,
+			     &mmc->mmc_rx_tcp_err);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_ICMP_GD,
+			     &mmc->mmc_rx_icmp_gd);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_ICMP_ERR,
+			     &mmc->mmc_rx_icmp_err);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_UDP_GD_OCTETS,
+			     &mmc->mmc_rx_udp_gd_octets);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_UDP_ERR_OCTETS,
+			     &mmc->mmc_rx_udp_err_octets);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_TCP_GD_OCTETS,
+			     &mmc->mmc_rx_tcp_gd_octets);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_TCP_ERR_OCTETS,
+			     &mmc->mmc_rx_tcp_err_octets);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_ICMP_GD_OCTETS,
+			     &mmc->mmc_rx_icmp_gd_octets);
+	dwxgmac_read_mmc_reg(mmcaddr, MMC_25GMAC_RX_ICMP_ERR_OCTETS,
+			     &mmc->mmc_rx_icmp_err_octets);
+}
+
+const struct stmmac_mmc_ops dw25gmac_mmc_ops = {
+	.ctrl = dw25gmac_mmc_ctrl,
+	.intr_all_mask = dwxgmac_mmc_intr_all_mask,
+	.read = dw25gmac_mmc_read,
+};
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -31,6 +31,7 @@
 	int wol_irq;
 	int lpi_irq;
 	int irq;
+	int sfty_irq;
 	int sfty_ce_irq;
 	int sfty_ue_irq;
 	int rx_irq[MTL_MAX_RX_QUEUES];
@@ -79,6 +80,7 @@
 	dma_addr_t dma_tx_phy;
 	dma_addr_t tx_tail_addr;
 	u32 mss;
+	u32 pid;
 };
 
 struct stmmac_rx_buffer {
@@ -260,6 +262,8 @@
 	struct stmmac_extra_stats xstats ____cacheline_aligned_in_smp;
 	struct stmmac_safety_stats sstats;
 	struct plat_stmmacenet_data *plat;
+	/* Protect est parameters */
+	struct mutex est_lock;
 	struct dma_features dma_cap;
 	struct stmmac_counters mmc;
 	int hw_cap_support;
@@ -298,6 +302,7 @@
 	void __iomem *ptpaddr;
 	void __iomem *estaddr;
 	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
+	int sfty_irq;
 	int sfty_ce_irq;
 	int sfty_ue_irq;
 	int rx_irq[MTL_MAX_RX_QUEUES];
@@ -306,6 +311,7 @@
 	char int_name_mac[IFNAMSIZ + 9];
 	char int_name_wol[IFNAMSIZ + 9];
 	char int_name_lpi[IFNAMSIZ + 9];
+	char int_name_sfty[IFNAMSIZ + 10];
 	char int_name_sfty_ce[IFNAMSIZ + 10];
 	char int_name_sfty_ue[IFNAMSIZ + 10];
 	char int_name_rx_irq[MTL_MAX_TX_QUEUES][IFNAMSIZ + 14];
@@ -357,7 +363,8 @@
 int stmmac_mdio_unregister(struct net_device *ndev);
 int stmmac_mdio_register(struct net_device *ndev);
 int stmmac_mdio_reset(struct mii_bus *mii);
-int stmmac_xpcs_setup(struct mii_bus *mii);
+int stmmac_pcs_setup(struct net_device *ndev);
+void stmmac_pcs_clean(struct net_device *ndev);
 void stmmac_set_ethtool_ops(struct net_device *netdev);
 
 int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_est.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/stmmac_est.c
@@ -81,6 +81,7 @@
 	u32 status, value, feqn, hbfq, hbfs, btrl, btrl_max;
 	void __iomem *est_addr = priv->estaddr;
 	u32 txqcnt_mask = BIT(txqcnt) - 1;
+	int i;
 
 	status = readl(est_addr + EST_STATUS);
 
@@ -125,6 +126,11 @@
 
 		x->mtl_est_hlbf++;
 
+		for (i = 0; i < txqcnt; i++) {
+			if (feqn & BIT(i))
+				x->mtl_est_txq_hlbf[i]++;
+		}
+
 		/* Clear Interrupt */
 		writel(feqn, est_addr + EST_FRM_SZ_ERR);
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -130,6 +130,7 @@
 	STMMAC_STAT(irq_pcs_ane_n),
 	STMMAC_STAT(irq_pcs_link_n),
 	STMMAC_STAT(irq_rgmii_n),
+	STMMAC_STAT(pcs_err_count),
 	/* DEBUG */
 	STMMAC_STAT(mtl_tx_status_fifo_full),
 	STMMAC_STAT(mtl_tx_fifo_not_empty),
@@ -448,9 +449,10 @@
 static int stmmac_ethtool_get_regs_len(struct net_device *dev)
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 
 	if (priv->plat->has_xgmac)
-		return XGMAC_REGSIZE * 4;
+		return XGMAC_REGSIZE(dwxgmac_addrs) * 4;
 	else if (priv->plat->has_gmac4)
 		return GMAC4_REG_SPACE_SIZE;
 	return REG_SPACE_SIZE;
@@ -644,6 +646,9 @@
 		}
 	}
 
+	if (priv->plat->safety_pcs_stats)
+		priv->plat->safety_pcs_stats(priv, &priv->xstats.pcs_err_count);
+
 	/* Update the DMA HW counters for dwmac10/100 */
 	ret = stmmac_dma_diagnostic_fr(priv, &priv->xstats, priv->ioaddr);
 	if (ret) {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
@@ -218,6 +218,7 @@
 {
 	u32 num_snapshot, ts_status, tsync_int;
 	struct ptp_clock_event event;
+	u32 acr_value, channel;
 	unsigned long flags;
 	u64 ptp_time;
 	int i;
@@ -243,12 +244,15 @@
 	num_snapshot = (ts_status & GMAC_TIMESTAMP_ATSNS_MASK) >>
 		       GMAC_TIMESTAMP_ATSNS_SHIFT;
 
+	acr_value = readl(priv->ptpaddr + PTP_ACR);
+	channel = ilog2(FIELD_GET(PTP_ACR_MASK, acr_value));
+
 	for (i = 0; i < num_snapshot; i++) {
 		read_lock_irqsave(&priv->ptp_lock, flags);
 		get_ptptime(priv->ptpaddr, &ptp_time);
 		read_unlock_irqrestore(&priv->ptp_lock, flags);
 		event.type = PTP_CLOCK_EXTTS;
-		event.index = 0;
+		event.index = channel;
 		event.timestamp = ptp_time;
 		ptp_clock_event(priv->ptp_clock, &event);
 	}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -536,8 +536,11 @@
 static void stmmac_get_tx_hwtstamp(struct stmmac_priv *priv,
 				   struct dma_desc *p, struct sk_buff *skb)
 {
+	const struct dwxgmac_addrs *dwxgmac_addrs = priv->plat->dwxgmac_addrs;
 	struct skb_shared_hwtstamps shhwtstamp;
+	void __iomem *ioaddr = priv->hw->pcsr;
 	bool found = false;
+	u32 pktid;
 	u64 ns = 0;
 
 	if (!priv->hwts_tx_en)
@@ -547,6 +550,9 @@
 	if (likely(!skb || !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)))
 		return;
 
+	if (priv->plat->insert_ts_pktid)
+		pktid = readl(ioaddr + XGMAC_TXTIMESTAMP_STATUS_PKTID(dwxgmac_addrs));
+
 	/* check tx tstamp status */
 	if (stmmac_get_tx_timestamp_status(priv, p)) {
 		stmmac_get_timestamp(priv, p, priv->adv_ts, &ns);
@@ -944,10 +950,7 @@
 	if (priv->hw->xpcs)
 		return &priv->hw->xpcs->pcs;
 
-	if (priv->hw->lynx_pcs)
-		return priv->hw->lynx_pcs;
-
-	return NULL;
+	return priv->hw->phylink_pcs;
 }
 
 static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,
@@ -977,6 +980,9 @@
 {
 	struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
 
+	if (priv->plat->safety_irq)
+		priv->plat->safety_irq(priv, false);
+
 	stmmac_mac_set(priv, priv->ioaddr, false);
 	priv->eee_active = false;
 	priv->tx_lpi_enabled = false;
@@ -1014,6 +1020,15 @@
 		case SPEED_2500:
 			ctrl |= priv->hw->link.xgmii.speed2500;
 			break;
+		case SPEED_1000:
+			ctrl |= priv->hw->link.speed1000;
+			break;
+		case SPEED_100:
+			ctrl |= priv->hw->link.speed100;
+			break;
+		case SPEED_10:
+			ctrl |= priv->hw->link.speed10;
+			break;
 		default:
 			return;
 		}
@@ -1043,6 +1058,34 @@
 		default:
 			return;
 		}
+	} else if (interface == PHY_INTERFACE_MODE_10GBASER) {
+		switch (speed) {
+		case SPEED_10000:
+			ctrl |= priv->hw->link.xgmii.speed10000;
+			break;
+		default:
+			return;
+		}
+	} else if (interface == PHY_INTERFACE_MODE_5GBASER) {
+		switch (speed) {
+		case SPEED_5000:
+			ctrl |= priv->hw->link.xgmii.speed5000;
+			break;
+		case SPEED_2500:
+			ctrl |= priv->hw->link.xgmii.speed2500;
+			break;
+		case SPEED_1000:
+			ctrl |= priv->hw->link.speed1000;
+			break;
+		case SPEED_100:
+			ctrl |= priv->hw->link.speed100;
+			break;
+		case SPEED_10:
+			ctrl |= priv->hw->link.speed10;
+			break;
+		default:
+			return;
+		}
 	} else {
 		switch (speed) {
 		case SPEED_2500:
@@ -1102,6 +1145,10 @@
 
 	if (priv->plat->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY)
 		stmmac_hwtstamp_correct_latency(priv, priv);
+
+	/*enable safety feature after physical link is up*/
+	if (priv->plat->safety_irq)
+		priv->plat->safety_irq(priv, true);
 }
 
 static const struct phylink_mac_ops stmmac_phylink_mac_ops = {
@@ -1198,17 +1245,6 @@
 	return ret;
 }
 
-static void stmmac_set_half_duplex(struct stmmac_priv *priv)
-{
-	/* Half-Duplex can only work with single tx queue */
-	if (priv->plat->tx_queues_to_use > 1)
-		priv->phylink_config.mac_capabilities &=
-			~(MAC_10HD | MAC_100HD | MAC_1000HD);
-	else
-		priv->phylink_config.mac_capabilities |=
-			(MAC_10HD | MAC_100HD | MAC_1000HD);
-}
-
 static int stmmac_phy_setup(struct stmmac_priv *priv)
 {
 	struct stmmac_mdio_bus_data *mdio_bus_data;
@@ -1221,6 +1257,9 @@
 	priv->phylink_config.type = PHYLINK_NETDEV;
 	priv->phylink_config.mac_managed_pm = true;
 
+	/* Stmmac always requires an RX clock for hardware initialization */
+	priv->phylink_config.mac_requires_rxc = true;
+
 	mdio_bus_data = priv->plat->mdio_bus_data;
 	if (mdio_bus_data)
 		priv->phylink_config.ovr_an_inband =
@@ -1236,15 +1275,11 @@
 		xpcs_get_interfaces(priv->hw->xpcs,
 				    priv->phylink_config.supported_interfaces);
 
-	priv->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
-						MAC_10FD | MAC_100FD |
-						MAC_1000FD;
-
-	stmmac_set_half_duplex(priv);
-
 	/* Get the MAC specific capabilities */
 	stmmac_mac_phylink_get_caps(priv);
 
+	priv->phylink_config.mac_capabilities = priv->hw->link.caps;
+
 	max_speed = priv->plat->max_speed;
 	if (max_speed)
 		phylink_limit_mac_speed(&priv->phylink_config, max_speed);
@@ -2506,6 +2541,13 @@
 		if (!xsk_tx_peek_desc(pool, &xdp_desc))
 			break;
 
+		if (priv->plat->est && priv->plat->est->enable &&
+		    priv->plat->est->max_sdu[queue] &&
+		    xdp_desc.len > priv->plat->est->max_sdu[queue]) {
+			priv->xstats.max_sdu_txq_drop[queue]++;
+			continue;
+		}
+
 		if (likely(priv->extend_desc))
 			tx_desc = (struct dma_desc *)(tx_q->dma_etx + entry);
 		else if (tx_q->tbs & STMMAC_TBS_AVAIL)
@@ -2944,7 +2986,8 @@
 static void stmmac_mmc_setup(struct stmmac_priv *priv)
 {
 	unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET |
-			    MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET;
+			    MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET |
+			    MMC_CNTRL_DRCHM;
 
 	stmmac_mmc_intr_all_mask(priv, priv->mmcaddr);
 
@@ -3001,9 +3044,11 @@
  */
 static int stmmac_init_dma_engine(struct stmmac_priv *priv)
 {
-	u32 rx_channels_count = priv->plat->rx_queues_to_use;
-	u32 tx_channels_count = priv->plat->tx_queues_to_use;
-	u32 dma_csr_ch = max(rx_channels_count, tx_channels_count);
+	u32 rx_channels_enabled = priv->plat->rx_queues_to_use;
+	u32 tx_channels_enabled = priv->plat->tx_queues_to_use;
+	u32 rx_channels_supported = priv->dma_cap.number_rx_channel;
+	u32 tx_channels_supported = priv->dma_cap.number_tx_channel;
+	u32 dma_csr_ch = max(rx_channels_enabled, tx_channels_enabled);
 	struct stmmac_rx_queue *rx_q;
 	struct stmmac_tx_queue *tx_q;
 	u32 chan = 0;
@@ -3037,7 +3082,7 @@
 	}
 
 	/* DMA RX Channel Configuration */
-	for (chan = 0; chan < rx_channels_count; chan++) {
+	for (chan = 0; chan < rx_channels_enabled; chan++) {
 		rx_q = &priv->dma_conf.rx_queue[chan];
 
 		stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
@@ -3051,7 +3096,7 @@
 	}
 
 	/* DMA TX Channel Configuration */
-	for (chan = 0; chan < tx_channels_count; chan++) {
+	for (chan = 0; chan < tx_channels_enabled ; chan++) {
 		tx_q = &priv->dma_conf.tx_queue[chan];
 
 		stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
@@ -3062,6 +3107,18 @@
 				       tx_q->tx_tail_addr, chan);
 	}
 
+	if (priv->plat->has_hdma) {
+		/* DMA RX Mapping Configuration for offline channels */
+		for (chan = rx_channels_enabled; chan < rx_channels_supported; chan++)
+			stmmac_map_rx_offline_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan);
+
+		/* DMA TX Mapping Configuration for offline channels */
+		for (chan = tx_channels_enabled; chan < tx_channels_supported; chan++)
+			stmmac_map_tx_offline_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan);
+
+		stmmac_desc_cache_compute(priv, priv->ioaddr);
+	}
+
 	return ret;
 }
 
@@ -3591,6 +3648,10 @@
 		if (priv->wol_irq > 0 && priv->wol_irq != dev->irq)
 			free_irq(priv->wol_irq, dev);
 		fallthrough;
+	case REQ_IRQ_ERR_SFTY:
+		if (priv->sfty_irq > 0 && priv->sfty_irq != dev->irq)
+			free_irq(priv->sfty_irq, dev);
+		fallthrough;
 	case REQ_IRQ_ERR_WOL:
 		free_irq(dev->irq, dev);
 		fallthrough;
@@ -3661,6 +3722,23 @@
 		}
 	}
 
+	/* Request the common Safety Feature Correctible/Uncorrectible
+	 * Error line in case of another line is used
+	 */
+	if (priv->sfty_irq > 0 && priv->sfty_irq != dev->irq) {
+		int_name = priv->int_name_sfty;
+		sprintf(int_name, "%s:%s", dev->name, "safety");
+		ret = request_irq(priv->sfty_irq, stmmac_safety_interrupt,
+				  0, int_name, dev);
+		if (unlikely(ret < 0)) {
+			netdev_err(priv->dev,
+				   "%s: alloc sfty MSI %d (error: %d)\n",
+				   __func__, priv->sfty_irq, ret);
+			irq_err = REQ_IRQ_ERR_SFTY;
+			goto irq_error;
+		}
+	}
+
 	/* Request the Safety Feature Correctible Error line in
 	 * case of another line is used
 	 */
@@ -3773,6 +3851,7 @@
 	/* Request the Wake IRQ in case of another line
 	 * is used for WoL
 	 */
+	priv->wol_irq_disabled = true;
 	if (priv->wol_irq > 0 && priv->wol_irq != dev->irq) {
 		ret = request_irq(priv->wol_irq, stmmac_interrupt,
 				  IRQF_SHARED, dev->name, dev);
@@ -3798,6 +3877,23 @@
 		}
 	}
 
+	/* Request the common Safety Feature Correctible/Uncorrectible
+	 * Error line in case of another line is used
+	 */
+	if (priv->sfty_irq > 0 && priv->sfty_irq != dev->irq) {
+		ret = request_irq(priv->sfty_irq, stmmac_safety_interrupt,
+				  IRQF_SHARED, dev->name, dev);
+		if (unlikely(ret < 0)) {
+			netdev_err(priv->dev,
+				   "%s: ERROR: allocating the sfty IRQ %d (%d)\n",
+				   __func__, priv->sfty_irq, ret);
+			irq_err = REQ_IRQ_ERR_SFTY;
+			goto irq_error;
+		}
+		if (priv->plat->safety_irq)
+			priv->plat->safety_irq(priv, false);
+	}
+
 	return 0;
 
 irq_error:
@@ -3917,8 +4013,7 @@
 	if (priv->hw->pcs != STMMAC_PCS_TBI &&
 	    priv->hw->pcs != STMMAC_PCS_RTBI &&
 	    (!priv->hw->xpcs ||
-	     xpcs_get_an_mode(priv->hw->xpcs, mode) != DW_AN_C73) &&
-	    !priv->hw->lynx_pcs) {
+	     xpcs_get_an_mode(priv->hw->xpcs, mode) != DW_AN_C73)) {
 		ret = stmmac_init_phy(dev);
 		if (ret) {
 			netdev_err(priv->dev,
@@ -3938,6 +4033,10 @@
 
 	stmmac_reset_queues_param(priv);
 
+	/* Make sure RX clock is enabled */
+	if (priv->hw->phylink_pcs)
+		phylink_pcs_pre_init(priv->phylink, priv->hw->phylink_pcs);
+
 	if (!(priv->plat->flags & STMMAC_FLAG_SERDES_UP_AFTER_PHY_LINKUP) &&
 	    priv->plat->serdes_powerup) {
 		ret = priv->plat->serdes_powerup(dev, priv->plat->bsp_priv);
@@ -4206,18 +4305,32 @@
 {
 	struct dma_desc *desc, *first, *mss_desc = NULL;
 	struct stmmac_priv *priv = netdev_priv(dev);
-	int nfrags = skb_shinfo(skb)->nr_frags;
-	u32 queue = skb_get_queue_mapping(skb);
+	int tmp_pay_len = 0, first_tx, nfrags;
 	unsigned int first_entry, tx_packets;
 	struct stmmac_txq_stats *txq_stats;
-	int tmp_pay_len = 0, first_tx;
 	struct stmmac_tx_queue *tx_q;
-	bool has_vlan, set_ic;
+	u32 pay_len, mss, queue;
+	dma_addr_t tso_des, des;
 	u8 proto_hdr_len, hdr;
-	u32 pay_len, mss;
-	dma_addr_t des;
+	bool set_ic;
 	int i;
 
+	/* Always insert VLAN tag to SKB payload for TSO frames.
+	 *
+	 * Never insert VLAN tag by HW, since segments splited by
+	 * TSO engine will be un-tagged by mistake.
+	 */
+	if (skb_vlan_tag_present(skb)) {
+		skb = __vlan_hwaccel_push_inside(skb);
+		if (unlikely(!skb)) {
+			priv->xstats.tx_dropped++;
+			return NETDEV_TX_OK;
+		}
+	}
+
+	nfrags = skb_shinfo(skb)->nr_frags;
+	queue = skb_get_queue_mapping(skb);
+
 	tx_q = &priv->dma_conf.tx_queue[queue];
 	txq_stats = &priv->xstats.txq_stats[queue];
 	first_tx = tx_q->cur_tx;
@@ -4270,9 +4383,6 @@
 			skb->data_len);
 	}
 
-	/* Check if VLAN can be inserted by HW */
-	has_vlan = stmmac_vlan_insert(priv, skb, tx_q);
-
 	first_entry = tx_q->cur_tx;
 	WARN_ON(tx_q->tx_skbuff[first_entry]);
 
@@ -4282,20 +4392,12 @@
 		desc = &tx_q->dma_tx[first_entry];
 	first = desc;
 
-	if (has_vlan)
-		stmmac_set_desc_vlan(priv, first, STMMAC_VLAN_INSERT);
-
 	/* first descriptor: fill Headers on Buf1 */
 	des = dma_map_single(priv->device, skb->data, skb_headlen(skb),
 			     DMA_TO_DEVICE);
 	if (dma_mapping_error(priv->device, des))
 		goto dma_map_err;
 
-	tx_q->tx_skbuff_dma[first_entry].buf = des;
-	tx_q->tx_skbuff_dma[first_entry].len = skb_headlen(skb);
-	tx_q->tx_skbuff_dma[first_entry].map_as_page = false;
-	tx_q->tx_skbuff_dma[first_entry].buf_type = STMMAC_TXBUF_T_SKB;
-
 	if (priv->dma_cap.addr64 <= 32) {
 		first->des0 = cpu_to_le32(des);
 
@@ -4305,14 +4407,32 @@
 
 		/* If needed take extra descriptors to fill the remaining payload */
 		tmp_pay_len = pay_len - TSO_MAX_BUFF_SIZE;
+		tso_des = des;
 	} else {
 		stmmac_set_desc_addr(priv, first, des);
 		tmp_pay_len = pay_len;
-		des += proto_hdr_len;
+		tso_des = des + proto_hdr_len;
 		pay_len = 0;
 	}
 
-	stmmac_tso_allocator(priv, des, tmp_pay_len, (nfrags == 0), queue);
+	stmmac_tso_allocator(priv, tso_des, tmp_pay_len, (nfrags == 0), queue);
+
+	/* In case two or more DMA transmit descriptors are allocated for this
+	 * non-paged SKB data, the DMA buffer address should be saved to
+	 * tx_q->tx_skbuff_dma[].buf corresponding to the last descriptor,
+	 * and leave the other tx_q->tx_skbuff_dma[].buf as NULL to guarantee
+	 * that stmmac_tx_clean() does not unmap the entire DMA buffer too early
+	 * since the tail areas of the DMA buffer can be accessed by DMA engine
+	 * sooner or later.
+	 * By saving the DMA buffer address to tx_q->tx_skbuff_dma[].buf
+	 * corresponding to the last descriptor, stmmac_tx_clean() will unmap
+	 * this DMA buffer right after the DMA engine completely finishes the
+	 * full buffer transmission.
+	 */
+	tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des;
+	tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_headlen(skb);
+	tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = false;
+	tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = STMMAC_TXBUF_T_SKB;
 
 	/* Prepare fragments */
 	for (i = 0; i < nfrags; i++) {
@@ -4460,6 +4580,34 @@
 		(proto == htons(ETH_P_IP) || proto == htons(ETH_P_IPV6));
 }
 
+#define STMMAC_MAX_PID 1023
+
+static void stmmac_hw_ts_insert(struct stmmac_priv *priv, struct stmmac_tx_queue *tx_q)
+{
+	struct dma_desc *p;
+
+	if (!priv->plat->insert_ts_pktid)
+		return;
+
+	if (priv->extend_desc)
+		p = &tx_q->dma_etx[tx_q->cur_tx].basic;
+	else if (tx_q->tbs & STMMAC_TBS_AVAIL)
+		p = &tx_q->dma_entx[tx_q->cur_tx].basic;
+	else
+		p = &tx_q->dma_tx[tx_q->cur_tx];
+
+	tx_q->pid = (tx_q->pid + 1) % STMMAC_MAX_PID;
+
+	/*this condition will be hit when 1023%1023 is 0*/
+	if (tx_q->pid == 0)
+		tx_q->pid = 1;
+
+	stmmac_set_desc_hw_ts(priv, p, tx_q->pid);
+	stmmac_set_tx_owner(priv, p);
+
+	tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
+}
+
 /**
  *  stmmac_xmit - Tx entry point of the driver
  *  @skb : the socket buffer
@@ -4500,6 +4648,13 @@
 			return stmmac_tso_xmit(skb, dev);
 	}
 
+	if (priv->plat->est && priv->plat->est->enable &&
+	    priv->plat->est->max_sdu[queue] &&
+	    skb->len > priv->plat->est->max_sdu[queue]){
+		priv->xstats.max_sdu_txq_drop[queue]++;
+		goto max_sdu_err;
+	}
+
 	if (unlikely(stmmac_tx_avail(priv, queue) < nfrags + 1)) {
 		if (!netif_tx_queue_stopped(netdev_get_tx_queue(dev, queue))) {
 			netif_tx_stop_queue(netdev_get_tx_queue(priv->dev,
@@ -4512,6 +4667,11 @@
 		return NETDEV_TX_BUSY;
 	}
 
+	/* Check if HW TS can be inserted by HW */
+	if (unlikely((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
+		     priv->hwts_tx_en))
+		stmmac_hw_ts_insert(priv, tx_q);
+
 	/* Check if VLAN can be inserted by HW */
 	has_vlan = stmmac_vlan_insert(priv, skb, tx_q);
 
@@ -4717,6 +4877,7 @@
 
 dma_map_err:
 	netdev_err(priv->dev, "Tx DMA map failed\n");
+max_sdu_err:
 	dev_kfree_skb(skb);
 	priv->xstats.tx_dropped++;
 	return NETDEV_TX_OK;
@@ -4873,6 +5034,13 @@
 	if (stmmac_tx_avail(priv, queue) < STMMAC_TX_THRESH(priv))
 		return STMMAC_XDP_CONSUMED;
 
+	if (priv->plat->est && priv->plat->est->enable &&
+	    priv->plat->est->max_sdu[queue] &&
+	    xdpf->len > priv->plat->est->max_sdu[queue]) {
+		priv->xstats.max_sdu_txq_drop[queue]++;
+		return STMMAC_XDP_CONSUMED;
+	}
+
 	if (likely(priv->extend_desc))
 		tx_desc = (struct dma_desc *)(tx_q->dma_etx + entry);
 	else if (tx_q->tbs & STMMAC_TBS_AVAIL)
@@ -6044,8 +6212,8 @@
 	if (test_bit(STMMAC_DOWN, &priv->state))
 		return IRQ_HANDLED;
 
-	/* Check if a fatal error happened */
-	if (stmmac_safety_feat_interrupt(priv))
+	/* Check ASP error if it isn't delivered via an individual IRQ */
+	if (priv->sfty_irq <= 0 && stmmac_safety_feat_interrupt(priv))
 		return IRQ_HANDLED;
 
 	/* To handle Common interrupts */
@@ -6590,7 +6758,7 @@
 static int stmmac_vlan_update(struct stmmac_priv *priv, bool is_double)
 {
 	u32 crc, hash = 0;
-	__le16 pmatch = 0;
+	u16 pmatch = 0;
 	int count = 0;
 	u16 vid = 0;
 
@@ -6605,7 +6773,7 @@
 		if (count > 2) /* VID = 0 always passes filter */
 			return -EOPNOTSUPP;
 
-		pmatch = cpu_to_le16(vid);
+		pmatch = vid;
 		hash = 0;
 	}
 
@@ -7111,6 +7279,7 @@
 	while (test_and_set_bit(STMMAC_RESETING, &priv->state))
 		usleep_range(1000, 2000);
 
+	disable_irq(priv->dev->irq);
 	set_bit(STMMAC_DOWN, &priv->state);
 	dev_close(priv->dev);
 	dev_open(priv->dev, NULL);
@@ -7206,6 +7375,36 @@
 	if (priv->dma_cap.tsoen)
 		dev_info(priv->device, "TSO supported\n");
 
+	if (priv->dma_cap.number_rx_queues &&
+	    priv->plat->rx_queues_to_use > priv->dma_cap.number_rx_queues) {
+		dev_warn(priv->device,
+			 "Number of Rx queues (%u) exceeds dma capability\n",
+			 priv->plat->rx_queues_to_use);
+		priv->plat->rx_queues_to_use = priv->dma_cap.number_rx_queues;
+	}
+	if (priv->dma_cap.number_tx_queues &&
+	    priv->plat->tx_queues_to_use > priv->dma_cap.number_tx_queues) {
+		dev_warn(priv->device,
+			 "Number of Tx queues (%u) exceeds dma capability\n",
+			 priv->plat->tx_queues_to_use);
+		priv->plat->tx_queues_to_use = priv->dma_cap.number_tx_queues;
+	}
+
+	if (priv->dma_cap.rx_fifo_size &&
+	    priv->plat->rx_fifo_size > priv->dma_cap.rx_fifo_size) {
+		dev_warn(priv->device,
+			 "Rx FIFO size (%u) exceeds dma capability\n",
+			 priv->plat->rx_fifo_size);
+		priv->plat->rx_fifo_size = priv->dma_cap.rx_fifo_size;
+	}
+	if (priv->dma_cap.tx_fifo_size &&
+	    priv->plat->tx_fifo_size > priv->dma_cap.tx_fifo_size) {
+		dev_warn(priv->device,
+			 "Tx FIFO size (%u) exceeds dma capability\n",
+			 priv->plat->tx_fifo_size);
+		priv->plat->tx_fifo_size = priv->dma_cap.tx_fifo_size;
+	}
+
 	priv->hw->vlan_fail_q_en =
 		(priv->plat->flags & STMMAC_FLAG_VLAN_FAIL_Q_EN);
 	priv->hw->vlan_fail_q = priv->plat->vlan_fail_q;
@@ -7286,6 +7485,7 @@
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
 	int ret = 0, i;
+	int max_speed;
 
 	if (netif_running(dev))
 		stmmac_release(dev);
@@ -7299,7 +7499,14 @@
 			priv->rss.table[i] = ethtool_rxfh_indir_default(i,
 									rx_cnt);
 
-	stmmac_set_half_duplex(priv);
+	stmmac_mac_phylink_get_caps(priv);
+
+	priv->phylink_config.mac_capabilities = priv->hw->link.caps;
+
+	max_speed = priv->plat->max_speed;
+	if (max_speed)
+		phylink_limit_mac_speed(&priv->phylink_config, max_speed);
+
 	stmmac_napi_add(dev);
 
 	if (netif_running(dev))
@@ -7474,6 +7681,7 @@
 	priv->dev->irq = res->irq;
 	priv->wol_irq = res->wol_irq;
 	priv->lpi_irq = res->lpi_irq;
+	priv->sfty_irq = res->sfty_irq;
 	priv->sfty_ce_irq = res->sfty_ce_irq;
 	priv->sfty_ue_irq = res->sfty_ue_irq;
 	for (i = 0; i < MTL_MAX_RX_QUEUES; i++)
@@ -7612,9 +7820,10 @@
 #ifdef STMMAC_VLAN_TAG_USED
 	/* Both mac100 and gmac support receive VLAN tag detection */
 	ndev->features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX;
-	ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
-	priv->hw->hw_vlan_en = true;
-
+	if (priv->plat->has_gmac4) {
+		ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
+		priv->hw->hw_vlan_en = true;
+	}
 	if (priv->dma_cap.vlhash) {
 		ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
 		ndev->features |= NETIF_F_HW_VLAN_STAG_FILTER;
@@ -7639,8 +7848,6 @@
 		ndev->features |= NETIF_F_RXHASH;
 
 	ndev->vlan_features |= ndev->features;
-	/* TSO doesn't work on VLANs yet */
-	ndev->vlan_features &= ~NETIF_F_TSO;
 
 	/* MTU range: 46 - hw-specific max */
 	ndev->min_mtu = ETH_ZLEN - ETH_HLEN;
@@ -7704,11 +7911,9 @@
 	if (priv->plat->speed_mode_2500)
 		priv->plat->speed_mode_2500(ndev, priv->plat->bsp_priv);
 
-	if (priv->plat->mdio_bus_data && priv->plat->mdio_bus_data->has_xpcs) {
-		ret = stmmac_xpcs_setup(priv->mii);
-		if (ret)
-			goto error_xpcs_setup;
-	}
+	ret = stmmac_pcs_setup(ndev);
+	if (ret)
+		goto error_pcs_setup;
 
 	ret = stmmac_phy_setup(priv);
 	if (ret) {
@@ -7739,8 +7944,9 @@
 
 error_netdev_register:
 	phylink_destroy(priv->phylink);
-error_xpcs_setup:
 error_phy_setup:
+	stmmac_pcs_clean(ndev);
+error_pcs_setup:
 	if (priv->hw->pcs != STMMAC_PCS_TBI &&
 	    priv->hw->pcs != STMMAC_PCS_RTBI)
 		stmmac_mdio_unregister(ndev);
@@ -7782,6 +7988,9 @@
 	if (priv->plat->stmmac_rst)
 		reset_control_assert(priv->plat->stmmac_rst);
 	reset_control_assert(priv->plat->stmmac_ahb_rst);
+
+	stmmac_pcs_clean(ndev);
+
 	if (priv->hw->pcs != STMMAC_PCS_TBI &&
 	    priv->hw->pcs != STMMAC_PCS_RTBI)
 		stmmac_mdio_unregister(ndev);
@@ -7936,6 +8145,10 @@
 			stmmac_mdio_reset(priv->mii);
 	}
 
+	/* Make sure RX clock is enabled */
+	if (priv->hw->phylink_pcs)
+		phylink_pcs_pre_init(priv->phylink, priv->hw->phylink_pcs);
+
 	if (!(priv->plat->flags & STMMAC_FLAG_SERDES_UP_AFTER_PHY_LINKUP) &&
 	    priv->plat->serdes_powerup) {
 		ret = priv->plat->serdes_powerup(ndev,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -495,34 +495,57 @@
 	return 0;
 }
 
-int stmmac_xpcs_setup(struct mii_bus *bus)
+int stmmac_pcs_setup(struct net_device *ndev)
 {
-	struct net_device *ndev = bus->priv;
+	struct dw_xpcs *xpcs = NULL;
 	struct stmmac_priv *priv;
-	struct dw_xpcs *xpcs;
+	int ret = -ENODEV;
 	int mode, addr;
 
 	priv = netdev_priv(ndev);
 	mode = priv->plat->phy_interface;
 
-	/* Try to probe the XPCS by scanning all addresses. */
-	for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
-		xpcs = xpcs_create_mdiodev(bus, addr, mode);
-		if (IS_ERR(xpcs))
-			continue;
+	if (priv->plat->pcs_init) {
+		ret = priv->plat->pcs_init(priv);
+	} else if (priv->plat->mdio_bus_data &&
+		   priv->plat->mdio_bus_data->has_xpcs) {
+		/* Try to probe the XPCS by scanning all addresses */
+		for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
+			xpcs = xpcs_create_mdiodev(priv->mii, addr, mode);
+			if (IS_ERR(xpcs))
+				continue;
 
-		priv->hw->xpcs = xpcs;
-		break;
+			ret = 0;
+			break;
+		}
+	} else {
+		return 0;
 	}
 
-	if (!priv->hw->xpcs) {
+	if (ret) {
 		dev_warn(priv->device, "No xPCS found\n");
-		return -ENODEV;
+		return ret;
 	}
 
+	priv->hw->xpcs = xpcs;
+
 	return 0;
 }
 
+void stmmac_pcs_clean(struct net_device *ndev)
+{
+	struct stmmac_priv *priv = netdev_priv(ndev);
+
+	if (priv->plat->pcs_exit)
+		priv->plat->pcs_exit(priv);
+
+	if (!priv->hw->xpcs)
+		return;
+
+	xpcs_destroy(priv->hw->xpcs);
+	priv->hw->xpcs = NULL;
+}
+
 /**
  * stmmac_mdio_register
  * @ndev: net device structure
@@ -679,9 +702,6 @@
 	if (!priv->mii)
 		return 0;
 
-	if (priv->hw->xpcs)
-		xpcs_destroy(priv->hw->xpcs);
-
 	mdiobus_unregister(priv->mii);
 	priv->mii->priv = NULL;
 	mdiobus_free(priv->mii);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
@@ -110,6 +110,8 @@
 	/* Enable and restart the Auto-Negotiation */
 	if (ane)
 		value |= GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_RAN;
+	else
+		value &= ~GMAC_AN_CTRL_ANE;
 
 	/* In case of MAC-2-MAC connection, block is configured to operate
 	 * according to MAC conf register.
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -406,22 +406,6 @@
 }
 
 /**
- * stmmac_remove_config_dt - undo the effects of stmmac_probe_config_dt()
- * @pdev: platform_device structure
- * @plat: driver data platform structure
- *
- * Release resources claimed by stmmac_probe_config_dt().
- */
-static void stmmac_remove_config_dt(struct platform_device *pdev,
-				    struct plat_stmmacenet_data *plat)
-{
-	clk_disable_unprepare(plat->stmmac_clk);
-	clk_disable_unprepare(plat->pclk);
-	of_node_put(plat->phy_node);
-	of_node_put(plat->mdio_node);
-}
-
-/**
  * stmmac_probe_config_dt - parse device-tree driver parameters
  * @pdev: platform_device structure
  * @mac: MAC address to use
@@ -438,6 +422,7 @@
 	int phy_mode;
 	void *ret;
 	int rc;
+	struct device_node *eeprom;
 
 	plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
 	if (!plat)
@@ -490,8 +475,10 @@
 		dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
 
 	rc = stmmac_mdio_setup(plat, np, &pdev->dev);
-	if (rc)
-		return ERR_PTR(rc);
+	if (rc) {
+		ret = ERR_PTR(rc);
+		goto error_put_phy;
+	}
 
 	of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size);
 
@@ -514,6 +501,17 @@
 	/* Set default value for unicast filter entries */
 	plat->unicast_filter_entries = 1;
 
+	plat->eeprom_reg = 0;
+	plat->i2c_id = 0;
+	eeprom = of_parse_phandle(np, "eeprom-for-mac", 0);
+	if (eeprom) {
+		if (of_property_read_u32(eeprom, "reg", &plat->eeprom_reg))
+			dev_err(&pdev->dev, "Failed to read eeprom_reg\n");
+
+		if (of_property_read_u32(eeprom, "i2c_id", &plat->i2c_id))
+			dev_err(&pdev->dev, "Failed to read i2c_id\n");
+	}
+
 	/*
 	 * Currently only the properties needed on SPEAr600
 	 * are provided. All other properties should be added
@@ -580,8 +578,8 @@
 	dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
 			       GFP_KERNEL);
 	if (!dma_cfg) {
-		stmmac_remove_config_dt(pdev, plat);
-		return ERR_PTR(-ENOMEM);
+		ret = ERR_PTR(-ENOMEM);
+		goto error_put_mdio;
 	}
 	plat->dma_cfg = dma_cfg;
 
@@ -609,8 +607,8 @@
 
 	rc = stmmac_mtl_setup(pdev, plat);
 	if (rc) {
-		stmmac_remove_config_dt(pdev, plat);
-		return ERR_PTR(rc);
+		ret = ERR_PTR(rc);
+		goto error_put_mdio;
 	}
 
 	/* clock setup */
@@ -662,6 +660,10 @@
 	clk_disable_unprepare(plat->pclk);
 error_pclk_get:
 	clk_disable_unprepare(plat->stmmac_clk);
+error_put_mdio:
+	of_node_put(plat->mdio_node);
+error_put_phy:
+	of_node_put(plat->phy_node);
 
 	return ret;
 }
@@ -670,16 +672,17 @@
 {
 	struct plat_stmmacenet_data *plat = data;
 
-	/* Platform data argument is unused */
-	stmmac_remove_config_dt(NULL, plat);
+	clk_disable_unprepare(plat->stmmac_clk);
+	clk_disable_unprepare(plat->pclk);
+	of_node_put(plat->mdio_node);
+	of_node_put(plat->phy_node);
 }
 
 /**
  * devm_stmmac_probe_config_dt
  * @pdev: platform_device structure
  * @mac: MAC address to use
- * Description: Devres variant of stmmac_probe_config_dt(). Does not require
- * the user to call stmmac_remove_config_dt() at driver detach.
+ * Description: Devres variant of stmmac_probe_config_dt().
  */
 struct plat_stmmacenet_data *
 devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
@@ -743,6 +746,14 @@
 		dev_info(&pdev->dev, "IRQ eth_lpi not found\n");
 	}
 
+	stmmac_res->sfty_irq =
+		platform_get_irq_byname_optional(pdev, "sfty");
+	if (stmmac_res->sfty_irq < 0) {
+		if (stmmac_res->sfty_irq == -EPROBE_DEFER)
+			return -EPROBE_DEFER;
+		dev_info(&pdev->dev, "IRQ sfty not found\n");
+	}
+
 	stmmac_res->addr = devm_platform_ioremap_resource(pdev, 0);
 
 	return PTR_ERR_OR_ZERO(stmmac_res->addr);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
@@ -70,11 +70,11 @@
 	/* If EST is enabled, disabled it before adjust ptp time. */
 	if (priv->plat->est && priv->plat->est->enable) {
 		est_rst = true;
-		mutex_lock(&priv->plat->est->lock);
+		mutex_lock(&priv->est_lock);
 		priv->plat->est->enable = false;
 		stmmac_est_configure(priv, priv, priv->plat->est,
 				     priv->plat->clk_ptp_rate);
-		mutex_unlock(&priv->plat->est->lock);
+		mutex_unlock(&priv->est_lock);
 	}
 
 	write_lock_irqsave(&priv->ptp_lock, flags);
@@ -87,7 +87,7 @@
 		ktime_t current_time_ns, basetime;
 		u64 cycle_time;
 
-		mutex_lock(&priv->plat->est->lock);
+		mutex_lock(&priv->est_lock);
 		priv->ptp_clock_ops.gettime64(&priv->ptp_clock_ops, &current_time);
 		current_time_ns = timespec64_to_ktime(current_time);
 		time.tv_nsec = priv->plat->est->btr_reserve[0];
@@ -104,7 +104,7 @@
 		priv->plat->est->enable = true;
 		ret = stmmac_est_configure(priv, priv, priv->plat->est,
 					   priv->plat->clk_ptp_rate);
-		mutex_unlock(&priv->plat->est->lock);
+		mutex_unlock(&priv->est_lock);
 		if (ret)
 			netdev_err(priv->dev, "failed to configure EST\n");
 	}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
@@ -343,10 +343,11 @@
 			struct tc_cbs_qopt_offload *qopt)
 {
 	u32 tx_queues_count = priv->plat->tx_queues_to_use;
+	s64 port_transmit_rate_kbps;
 	u32 queue = qopt->queue;
-	u32 ptr, speed_div;
 	u32 mode_to_use;
 	u64 value;
+	u32 ptr;
 	int ret;
 
 	/* Queue 0 is not AVB capable */
@@ -355,30 +356,30 @@
 	if (!priv->dma_cap.av)
 		return -EOPNOTSUPP;
 
-	/* Port Transmit Rate and Speed Divider */
-	switch (priv->speed) {
-	case SPEED_10000:
-		ptr = 32;
-		speed_div = 10000000;
-		break;
-	case SPEED_5000:
-		ptr = 32;
-		speed_div = 5000000;
-		break;
-	case SPEED_2500:
-		ptr = 8;
-		speed_div = 2500000;
-		break;
-	case SPEED_1000:
-		ptr = 8;
-		speed_div = 1000000;
-		break;
-	case SPEED_100:
-		ptr = 4;
-		speed_div = 100000;
-		break;
-	default:
-		return -EOPNOTSUPP;
+	port_transmit_rate_kbps = qopt->idleslope - qopt->sendslope;
+
+	if (qopt->enable) {
+		/* Port Transmit Rate and Speed Divider */
+		switch (div_s64(port_transmit_rate_kbps, 1000)) {
+		case SPEED_10000:
+		case SPEED_5000:
+			ptr = 32;
+			break;
+		case SPEED_2500:
+		case SPEED_1000:
+			ptr = 8;
+			break;
+		case SPEED_100:
+			ptr = 4;
+			break;
+		default:
+			netdev_err(priv->dev,
+				   "Invalid portTransmitRate %lld (idleSlope - sendSlope)\n",
+				   port_transmit_rate_kbps);
+			return -EINVAL;
+		}
+	} else {
+		ptr = 0;
 	}
 
 	mode_to_use = priv->plat->tx_queues_cfg[queue].mode_to_use;
@@ -395,13 +396,14 @@
 			return ret;
 
 		priv->plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
+		return 0;
 	}
 
 	/* Final adjustments for HW */
-	value = div_s64(qopt->idleslope * 1024ll * ptr, speed_div);
+	value = div_s64(qopt->idleslope * 1024ll * ptr, port_transmit_rate_kbps);
 	priv->plat->tx_queues_cfg[queue].idle_slope = value & GENMASK(31, 0);
 
-	value = div_s64(-qopt->sendslope * 1024ll * ptr, speed_div);
+	value = div_s64(-qopt->sendslope * 1024ll * ptr, port_transmit_rate_kbps);
 	priv->plat->tx_queues_cfg[queue].send_slope = value & GENMASK(31, 0);
 
 	value = qopt->hicredit * 1024ll * 8;
@@ -915,8 +917,30 @@
 	return time;
 }
 
-static int tc_setup_taprio(struct stmmac_priv *priv,
-			   struct tc_taprio_qopt_offload *qopt)
+static void tc_taprio_map_maxsdu_txq(struct stmmac_priv *priv,
+				     struct tc_taprio_qopt_offload *qopt)
+{
+	struct plat_stmmacenet_data *plat = priv->plat;
+	u32 num_tc = qopt->mqprio.qopt.num_tc;
+	u32 offset, count, i, j;
+
+	/* QueueMaxSDU received from the driver corresponds to the Linux traffic
+	 * class. Map queueMaxSDU per Linux traffic class to DWMAC Tx queues.
+	 */
+	for (i = 0; i < num_tc; i++) {
+		if (!qopt->max_sdu[i])
+			continue;
+
+		offset = qopt->mqprio.qopt.offset[i];
+		count = qopt->mqprio.qopt.count[i];
+
+		for (j = offset; j < offset + count; j++)
+			plat->est->max_sdu[j] = qopt->max_sdu[i] + ETH_HLEN - ETH_TLEN;
+	}
+}
+
+static int tc_taprio_configure(struct stmmac_priv *priv,
+			       struct tc_taprio_qopt_offload *qopt)
 {
 	u32 size, wid = priv->dma_cap.estwid, dep = priv->dma_cap.estdep;
 	struct plat_stmmacenet_data *plat = priv->plat;
@@ -968,8 +992,6 @@
 
 	if (qopt->cmd == TAPRIO_CMD_DESTROY)
 		goto disable;
-	else if (qopt->cmd != TAPRIO_CMD_REPLACE)
-		return -EOPNOTSUPP;
 
 	if (qopt->num_entries >= dep)
 		return -EINVAL;
@@ -984,17 +1006,19 @@
 		if (!plat->est)
 			return -ENOMEM;
 
-		mutex_init(&priv->plat->est->lock);
+		mutex_init(&priv->est_lock);
 	} else {
+		mutex_lock(&priv->est_lock);
 		memset(plat->est, 0, sizeof(*plat->est));
+		mutex_unlock(&priv->est_lock);
 	}
 
 	size = qopt->num_entries;
 
-	mutex_lock(&priv->plat->est->lock);
+	mutex_lock(&priv->est_lock);
 	priv->plat->est->gcl_size = size;
 	priv->plat->est->enable = qopt->cmd == TAPRIO_CMD_REPLACE;
-	mutex_unlock(&priv->plat->est->lock);
+	mutex_unlock(&priv->est_lock);
 
 	for (i = 0; i < size; i++) {
 		s64 delta_ns = qopt->entries[i].interval;
@@ -1025,7 +1049,7 @@
 		priv->plat->est->gcl[i] = delta_ns | (gates << wid);
 	}
 
-	mutex_lock(&priv->plat->est->lock);
+	mutex_lock(&priv->est_lock);
 	/* Adjust for real system time */
 	priv->ptp_clock_ops.gettime64(&priv->ptp_clock_ops, &current_time);
 	current_time_ns = timespec64_to_ktime(current_time);
@@ -1045,8 +1069,10 @@
 
 	priv->plat->est->ter = qopt->cycle_time_extension;
 
+	tc_taprio_map_maxsdu_txq(priv, qopt);
+
 	if (fpe && !priv->dma_cap.fpesel) {
-		mutex_unlock(&priv->plat->est->lock);
+		mutex_unlock(&priv->est_lock);
 		return -EOPNOTSUPP;
 	}
 
@@ -1057,7 +1083,7 @@
 
 	ret = stmmac_est_configure(priv, priv, priv->plat->est,
 				   priv->plat->clk_ptp_rate);
-	mutex_unlock(&priv->plat->est->lock);
+	mutex_unlock(&priv->est_lock);
 	if (ret) {
 		netdev_err(priv->dev, "failed to configure EST\n");
 		goto disable;
@@ -1074,11 +1100,16 @@
 
 disable:
 	if (priv->plat->est) {
-		mutex_lock(&priv->plat->est->lock);
+		mutex_lock(&priv->est_lock);
 		priv->plat->est->enable = false;
 		stmmac_est_configure(priv, priv, priv->plat->est,
 				     priv->plat->clk_ptp_rate);
-		mutex_unlock(&priv->plat->est->lock);
+		/* Reset taprio status */
+		for (i = 0; i < priv->plat->tx_queues_to_use; i++) {
+			priv->xstats.max_sdu_txq_drop[i] = 0;
+			priv->xstats.mtl_est_txq_hlbf[i] = 0;
+		}
+		mutex_unlock(&priv->est_lock);
 	}
 
 	priv->plat->fpe_cfg->enable = false;
@@ -1095,6 +1126,57 @@
 	return ret;
 }
 
+static void tc_taprio_stats(struct stmmac_priv *priv,
+			    struct tc_taprio_qopt_offload *qopt)
+{
+	u64 window_drops = 0;
+	int i = 0;
+
+	for (i = 0; i < priv->plat->tx_queues_to_use; i++)
+		window_drops += priv->xstats.max_sdu_txq_drop[i] +
+				priv->xstats.mtl_est_txq_hlbf[i];
+	qopt->stats.window_drops = window_drops;
+
+	/* Transmission overrun doesn't happen for stmmac, hence always 0 */
+	qopt->stats.tx_overruns = 0;
+}
+
+static void tc_taprio_queue_stats(struct stmmac_priv *priv,
+				  struct tc_taprio_qopt_offload *qopt)
+{
+	struct tc_taprio_qopt_queue_stats *q_stats = &qopt->queue_stats;
+	int queue = qopt->queue_stats.queue;
+
+	q_stats->stats.window_drops = priv->xstats.max_sdu_txq_drop[queue] +
+				      priv->xstats.mtl_est_txq_hlbf[queue];
+
+	/* Transmission overrun doesn't happen for stmmac, hence always 0 */
+	q_stats->stats.tx_overruns = 0;
+}
+
+static int tc_setup_taprio(struct stmmac_priv *priv,
+			   struct tc_taprio_qopt_offload *qopt)
+{
+	int err = 0;
+
+	switch (qopt->cmd) {
+	case TAPRIO_CMD_REPLACE:
+	case TAPRIO_CMD_DESTROY:
+		err = tc_taprio_configure(priv, qopt);
+		break;
+	case TAPRIO_CMD_STATS:
+		tc_taprio_stats(priv, qopt);
+		break;
+	case TAPRIO_CMD_QUEUE_STATS:
+		tc_taprio_queue_stats(priv, qopt);
+		break;
+	default:
+		err = -EOPNOTSUPP;
+	}
+
+	return err;
+}
+
 static int tc_setup_etf(struct stmmac_priv *priv,
 			struct tc_etf_qopt_offload *qopt)
 {
@@ -1126,6 +1208,7 @@
 			return -EOPNOTSUPP;
 
 		caps->gate_mask_per_txq = true;
+		caps->supports_queue_max_sdu = true;
 
 		return 0;
 	}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/sun/sungem.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/sun/sungem.c
@@ -949,17 +949,6 @@
 	return IRQ_HANDLED;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void gem_poll_controller(struct net_device *dev)
-{
-	struct gem *gp = netdev_priv(dev);
-
-	disable_irq(gp->pdev->irq);
-	gem_interrupt(gp->pdev->irq, dev);
-	enable_irq(gp->pdev->irq);
-}
-#endif
-
 static void gem_tx_timeout(struct net_device *dev, unsigned int txqueue)
 {
 	struct gem *gp = netdev_priv(dev);
@@ -2839,9 +2828,6 @@
 	.ndo_change_mtu		= gem_change_mtu,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address    = gem_set_mac_address,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller    = gem_poll_controller,
-#endif
 };
 
 static int gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/ti/am65-cpsw-nuss.c
@@ -1719,7 +1719,7 @@
 	for (i = 0; i < common->tx_ch_num; i++) {
 		struct am65_cpsw_tx_chn *tx_chn = &common->tx_chns[i];
 
-		if (tx_chn->irq)
+		if (tx_chn->irq > 0)
 			devm_free_irq(dev, tx_chn->irq, tx_chn);
 
 		netif_napi_del(&tx_chn->napi_tx);
@@ -2793,6 +2793,8 @@
 
 static int am65_cpsw_nuss_register_ndevs(struct am65_cpsw_common *common)
 {
+	struct am65_cpsw_rx_chn *rx_chan = &common->rx_chns;
+	struct am65_cpsw_tx_chn *tx_chan = common->tx_chns;
 	struct device *dev = common->dev;
 	struct am65_cpsw_port *port;
 	int ret = 0, i;
@@ -2805,6 +2807,22 @@
 	if (ret)
 		return ret;
 
+	/* The DMA Channels are not guaranteed to be in a clean state.
+	 * Reset and disable them to ensure that they are back to the
+	 * clean state and ready to be used.
+	 */
+	for (i = 0; i < common->tx_ch_num; i++) {
+		k3_udma_glue_reset_tx_chn(tx_chan[i].tx_chn, &tx_chan[i],
+					  am65_cpsw_nuss_tx_cleanup);
+		k3_udma_glue_disable_tx_chn(tx_chan[i].tx_chn);
+	}
+
+	for (i = 0; i < AM65_CPSW_MAX_RX_FLOWS; i++)
+		k3_udma_glue_reset_rx_chn(rx_chan->rx_chn, i, rx_chan,
+					  am65_cpsw_nuss_rx_cleanup, !!i);
+
+	k3_udma_glue_disable_rx_chn(rx_chan->rx_chn);
+
 	ret = am65_cpsw_nuss_register_devlink(common);
 	if (ret)
 		return ret;
@@ -2976,7 +2994,7 @@
 	common->rx_flow_id_base = -1;
 	init_completion(&common->tdown_complete);
 	common->tx_ch_num = AM65_CPSW_DEFAULT_TX_CHNS;
-	common->pf_p0_rx_ptype_rrobin = false;
+	common->pf_p0_rx_ptype_rrobin = true;
 	common->default_vlan = 1;
 
 	common->ports = devm_kcalloc(dev, common->port_num,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/ti/am65-cpts.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/ti/am65-cpts.c
@@ -784,6 +784,11 @@
 		struct am65_cpts_skb_cb_data *skb_cb =
 					(struct am65_cpts_skb_cb_data *)skb->cb;
 
+		if ((ptp_classify_raw(skb) & PTP_CLASS_V1) &&
+		    ((mtype_seqid & AM65_CPTS_EVENT_1_SEQUENCE_ID_MASK) ==
+		     (skb_cb->skb_mtype_seqid & AM65_CPTS_EVENT_1_SEQUENCE_ID_MASK)))
+			mtype_seqid = skb_cb->skb_mtype_seqid;
+
 		if (mtype_seqid == skb_cb->skb_mtype_seqid) {
 			u64 ns = event->timestamp;
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/ti/cpsw_ale.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/ti/cpsw_ale.c
@@ -106,15 +106,15 @@
 
 static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
 {
-	int idx, idx2;
+	int idx, idx2, index;
 	u32 hi_val = 0;
 
 	idx    = start / 32;
 	idx2 = (start + bits - 1) / 32;
 	/* Check if bits to be fetched exceed a word */
 	if (idx != idx2) {
-		idx2 = 2 - idx2; /* flip */
-		hi_val = ale_entry[idx2] << ((idx2 * 32) - start);
+		index = 2 - idx2; /* flip */
+		hi_val = ale_entry[index] << ((idx2 * 32) - start);
 	}
 	start -= idx * 32;
 	idx    = 2 - idx; /* flip */
@@ -124,16 +124,16 @@
 static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
 				      u32 value)
 {
-	int idx, idx2;
+	int idx, idx2, index;
 
 	value &= BITMASK(bits);
 	idx = start / 32;
 	idx2 = (start + bits - 1) / 32;
 	/* Check if bits to be set exceed a word */
 	if (idx != idx2) {
-		idx2 = 2 - idx2; /* flip */
-		ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32)));
-		ale_entry[idx2] |= (value >> ((idx2 * 32) - start));
+		index = 2 - idx2; /* flip */
+		ale_entry[index] &= ~(BITMASK(bits + start - (idx2 * 32)));
+		ale_entry[index] |= (value >> ((idx2 * 32) - start));
 	}
 	start -= idx * 32;
 	idx = 2 - idx; /* flip */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/ti/icssg/icss_iep.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/ti/icssg/icss_iep.c
@@ -290,6 +290,9 @@
 	for (cmp = IEP_MIN_CMP; cmp < IEP_MAX_CMP; cmp++) {
 		regmap_update_bits(iep->map, ICSS_IEP_CMP_STAT_REG,
 				   IEP_CMP_STATUS(cmp), IEP_CMP_STATUS(cmp));
+
+		regmap_update_bits(iep->map, ICSS_IEP_CMP_CFG_REG,
+				   IEP_CMP_CFG_CMP_EN(cmp), 0);
 	}
 
 	/* enable reset counter on CMP0 event */
@@ -808,6 +811,11 @@
 	}
 	icss_iep_disable(iep);
 
+	if (iep->pps_enabled)
+		icss_iep_pps_enable(iep, false);
+	else if (iep->perout_enabled)
+		icss_iep_perout_enable(iep, NULL, false);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(icss_iep_exit);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/ti/icssg/icssg_classifier.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/ti/icssg/icssg_classifier.c
@@ -360,7 +360,7 @@
 {
 	const u8 mask_addr[] = { 0, 0, 0, 0, 0, 0, };
 
-	rx_class_ft1_set_start_len(miig_rt, slice, 0, 6);
+	rx_class_ft1_set_start_len(miig_rt, slice, ETH_ALEN, ETH_ALEN);
 	rx_class_ft1_set_da(miig_rt, slice, 0, mac_addr);
 	rx_class_ft1_set_da_mask(miig_rt, slice, 0, mask_addr);
 	rx_class_ft1_cfg_set_type(miig_rt, slice, 0, FT1_CFG_TYPE_EQ);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -15,6 +15,7 @@
 #include <linux/genalloc.h>
 #include <linux/if_vlan.h>
 #include <linux/interrupt.h>
+#include <linux/io-64-nonatomic-hi-lo.h>
 #include <linux/kernel.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
@@ -421,12 +422,14 @@
 		if (!i)
 			fdqring_id = k3_udma_glue_rx_flow_get_fdq_id(rx_chn->rx_chn,
 								     i);
-		rx_chn->irq[i] = k3_udma_glue_rx_get_irq(rx_chn->rx_chn, i);
-		if (rx_chn->irq[i] <= 0) {
-			ret = rx_chn->irq[i];
+		ret = k3_udma_glue_rx_get_irq(rx_chn->rx_chn, i);
+		if (ret <= 0) {
+			if (!ret)
+				ret = -ENXIO;
 			netdev_err(ndev, "Failed to get rx dma irq");
 			goto fail;
 		}
+		rx_chn->irq[i] = ret;
 	}
 
 	return 0;
@@ -1249,6 +1252,8 @@
 	struct prueth_emac *emac = clockops_data;
 	u32 reduction_factor = 0, offset = 0;
 	struct timespec64 ts;
+	u64 current_cycle;
+	u64 start_offset;
 	u64 ns_period;
 
 	if (!on)
@@ -1287,8 +1292,14 @@
 	writel(reduction_factor, emac->prueth->shram.va +
 		TIMESYNC_FW_WC_SYNCOUT_REDUCTION_FACTOR_OFFSET);
 
-	writel(0, emac->prueth->shram.va +
-		TIMESYNC_FW_WC_SYNCOUT_START_TIME_CYCLECOUNT_OFFSET);
+	current_cycle = icssg_read_time(emac->prueth->shram.va +
+					TIMESYNC_FW_WC_CYCLECOUNT_OFFSET);
+
+	/* Rounding of current_cycle count to next second */
+	start_offset = roundup(current_cycle, MSEC_PER_SEC);
+
+	hi_lo_writeq(start_offset, emac->prueth->shram.va +
+		     TIMESYNC_FW_WC_SYNCOUT_START_TIME_CYCLECOUNT_OFFSET);
 
 	return 0;
 }
@@ -2154,7 +2165,12 @@
 
 		prueth->registered_netdevs[PRUETH_MAC0] = prueth->emac[PRUETH_MAC0]->ndev;
 
-		emac_phy_connect(prueth->emac[PRUETH_MAC0]);
+		ret = emac_phy_connect(prueth->emac[PRUETH_MAC0]);
+		if (ret) {
+			dev_err(dev,
+				"can't connect to MII0 PHY, error -%d", ret);
+			goto netdev_unregister;
+		}
 		phy_attached_info(prueth->emac[PRUETH_MAC0]->ndev->phydev);
 	}
 
@@ -2166,7 +2182,12 @@
 		}
 
 		prueth->registered_netdevs[PRUETH_MAC1] = prueth->emac[PRUETH_MAC1]->ndev;
-		emac_phy_connect(prueth->emac[PRUETH_MAC1]);
+		ret = emac_phy_connect(prueth->emac[PRUETH_MAC1]);
+		if (ret) {
+			dev_err(dev,
+				"can't connect to MII1 PHY, error %d", ret);
+			goto netdev_unregister;
+		}
 		phy_attached_info(prueth->emac[PRUETH_MAC1]->ndev->phydev);
 	}
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/ti/icssg/icssg_prueth.h
@@ -258,6 +258,18 @@
 
 extern const struct ethtool_ops icssg_ethtool_ops;
 
+static inline u64 icssg_read_time(const void __iomem *addr)
+{
+	u32 low, high;
+
+	do {
+		high = readl(addr + 4);
+		low = readl(addr);
+	} while (high != readl(addr + 4));
+
+	return low + ((u64)high << 32);
+}
+
 /* Classifier helpers */
 void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac);
 void icssg_class_set_host_mac_addr(struct regmap *miig_rt, const u8 *mac);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/vertexcom/mse102x.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/vertexcom/mse102x.c
@@ -222,7 +222,7 @@
 	struct mse102x_net_spi *mses = to_mse102x_spi(mse);
 	struct spi_transfer *xfer = &mses->spi_xfer;
 	struct spi_message *msg = &mses->spi_msg;
-	struct sk_buff *tskb;
+	struct sk_buff *tskb = NULL;
 	int ret;
 
 	netif_dbg(mse, tx_queued, mse->ndev, "%s: skb %p, %d@%p\n",
@@ -235,7 +235,6 @@
 		if (!tskb)
 			return -ENOMEM;
 
-		dev_kfree_skb(txp);
 		txp = tskb;
 	}
 
@@ -257,6 +256,8 @@
 		mse->stats.xfer_err++;
 	}
 
+	dev_kfree_skb(tskb);
+
 	return ret;
 }
 
@@ -436,13 +437,15 @@
 	mse = &mses->mse102x;
 
 	while ((txb = skb_dequeue(&mse->txq))) {
+		unsigned int len = max_t(unsigned int, txb->len, ETH_ZLEN);
+
 		mutex_lock(&mses->lock);
 		ret = mse102x_tx_pkt_spi(mse, txb, work_timeout);
 		mutex_unlock(&mses->lock);
 		if (ret) {
 			mse->ndev->stats.tx_dropped++;
 		} else {
-			mse->ndev->stats.tx_bytes += txb->len;
+			mse->ndev->stats.tx_bytes += len;
 			mse->ndev->stats.tx_packets++;
 		}
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/libwx/wx_hw.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/libwx/wx_hw.c
@@ -334,27 +334,25 @@
 	status = read_poll_timeout(rd32, hicr, hicr & WX_MNG_MBOX_CTL_FWRDY, 1000,
 				   timeout * 1000, false, wx, WX_MNG_MBOX_CTL);
 
+	buf[0] = rd32(wx, WX_MNG_MBOX);
+	if ((buf[0] & 0xff0000) >> 16 == 0x80) {
+		wx_err(wx, "Unknown FW command: 0x%x\n", buffer[0] & 0xff);
+		status = -EINVAL;
+		goto rel_out;
+	}
+
 	/* Check command completion */
 	if (status) {
-		wx_dbg(wx, "Command has failed with no status valid.\n");
-
-		buf[0] = rd32(wx, WX_MNG_MBOX);
-		if ((buffer[0] & 0xff) != (~buf[0] >> 24)) {
-			status = -EINVAL;
-			goto rel_out;
-		}
-		if ((buf[0] & 0xff0000) >> 16 == 0x80) {
-			wx_dbg(wx, "It's unknown cmd.\n");
-			status = -EINVAL;
-			goto rel_out;
-		}
-
+		wx_err(wx, "Command has failed with no status valid.\n");
 		wx_dbg(wx, "write value:\n");
 		for (i = 0; i < dword_len; i++)
 			wx_dbg(wx, "%x ", buffer[i]);
 		wx_dbg(wx, "read value:\n");
 		for (i = 0; i < dword_len; i++)
 			wx_dbg(wx, "%x ", buf[i]);
+		wx_dbg(wx, "\ncheck: %x %x\n", buffer[0] & 0xff, ~buf[0] >> 24);
+
+		goto rel_out;
 	}
 
 	if (!return_data)
@@ -1958,7 +1956,8 @@
 		return -ENOMEM;
 	}
 
-	wx->msix_in_use = false;
+	bitmap_zero(wx->state, WX_STATE_NBITS);
+	wx->misc_irq_domain = false;
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/libwx/wx_lib.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/libwx/wx_lib.c
@@ -1614,14 +1614,12 @@
 	/* One for non-queue interrupts */
 	nvecs += 1;
 
-	if (!wx->msix_in_use) {
-		wx->msix_entry = kcalloc(1, sizeof(struct msix_entry),
-					 GFP_KERNEL);
-		if (!wx->msix_entry) {
-			kfree(wx->msix_q_entries);
-			wx->msix_q_entries = NULL;
-			return -ENOMEM;
-		}
+	wx->msix_entry = kcalloc(1, sizeof(struct msix_entry),
+				 GFP_KERNEL);
+	if (!wx->msix_entry) {
+		kfree(wx->msix_q_entries);
+		wx->msix_q_entries = NULL;
+		return -ENOMEM;
 	}
 
 	nvecs = pci_alloc_irq_vectors_affinity(wx->pdev, nvecs,
@@ -1688,6 +1686,7 @@
 	}
 
 	pdev->irq = pci_irq_vector(pdev, 0);
+	wx->num_q_vectors = 1;
 
 	return 0;
 }
@@ -1931,10 +1930,8 @@
 	if (pdev->msix_enabled) {
 		kfree(wx->msix_q_entries);
 		wx->msix_q_entries = NULL;
-		if (!wx->msix_in_use) {
-			kfree(wx->msix_entry);
-			wx->msix_entry = NULL;
-		}
+		kfree(wx->msix_entry);
+		wx->msix_entry = NULL;
 	}
 	pci_free_irq_vectors(wx->pdev);
 }
@@ -2000,7 +1997,8 @@
 	int vector;
 
 	if (!(pdev->msix_enabled)) {
-		free_irq(pdev->irq, wx);
+		if (!wx->misc_irq_domain)
+			free_irq(pdev->irq, wx);
 		return;
 	}
 
@@ -2015,7 +2013,7 @@
 		free_irq(entry->vector, q_vector);
 	}
 
-	if (wx->mac.type == wx_mac_em)
+	if (!wx->misc_irq_domain)
 		free_irq(wx->msix_entry->vector, wx);
 }
 EXPORT_SYMBOL(wx_free_irq);
@@ -2030,6 +2028,9 @@
 {
 	struct pci_dev *pdev = wx->pdev;
 
+	if (wx->isb_mem)
+		return 0;
+
 	wx->isb_mem = dma_alloc_coherent(&pdev->dev,
 					 sizeof(u32) * 4,
 					 &wx->isb_dma,
@@ -2389,7 +2390,6 @@
 
 void wx_free_resources(struct wx *wx)
 {
-	wx_free_isb_resources(wx);
 	wx_free_all_rx_resources(wx);
 	wx_free_all_tx_resources(wx);
 }
@@ -2694,15 +2694,63 @@
 		wx->rss_enabled = false;
 	}
 
-	if (changed &
-	    (NETIF_F_HW_VLAN_CTAG_RX |
-	     NETIF_F_HW_VLAN_STAG_RX))
+	netdev->features = features;
+
+	if (wx->mac.type == wx_mac_sp && changed & NETIF_F_HW_VLAN_CTAG_RX)
+		wx->do_reset(netdev);
+	else if (changed & (NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_FILTER))
 		wx_set_rx_mode(netdev);
 
-	return 1;
+	return 0;
 }
 EXPORT_SYMBOL(wx_set_features);
 
+#define NETIF_VLAN_STRIPPING_FEATURES	(NETIF_F_HW_VLAN_CTAG_RX | \
+					 NETIF_F_HW_VLAN_STAG_RX)
+
+#define NETIF_VLAN_INSERTION_FEATURES	(NETIF_F_HW_VLAN_CTAG_TX | \
+					 NETIF_F_HW_VLAN_STAG_TX)
+
+#define NETIF_VLAN_FILTERING_FEATURES	(NETIF_F_HW_VLAN_CTAG_FILTER | \
+					 NETIF_F_HW_VLAN_STAG_FILTER)
+
+netdev_features_t wx_fix_features(struct net_device *netdev,
+				  netdev_features_t features)
+{
+	netdev_features_t changed = netdev->features ^ features;
+	struct wx *wx = netdev_priv(netdev);
+
+	if (changed & NETIF_VLAN_STRIPPING_FEATURES) {
+		if ((features & NETIF_VLAN_STRIPPING_FEATURES) != NETIF_VLAN_STRIPPING_FEATURES &&
+		    (features & NETIF_VLAN_STRIPPING_FEATURES) != 0) {
+			features &= ~NETIF_VLAN_STRIPPING_FEATURES;
+			features |= netdev->features & NETIF_VLAN_STRIPPING_FEATURES;
+			wx_err(wx, "802.1Q and 802.1ad VLAN stripping must be either both on or both off.");
+		}
+	}
+
+	if (changed & NETIF_VLAN_INSERTION_FEATURES) {
+		if ((features & NETIF_VLAN_INSERTION_FEATURES) != NETIF_VLAN_INSERTION_FEATURES &&
+		    (features & NETIF_VLAN_INSERTION_FEATURES) != 0) {
+			features &= ~NETIF_VLAN_INSERTION_FEATURES;
+			features |= netdev->features & NETIF_VLAN_INSERTION_FEATURES;
+			wx_err(wx, "802.1Q and 802.1ad VLAN insertion must be either both on or both off.");
+		}
+	}
+
+	if (changed & NETIF_VLAN_FILTERING_FEATURES) {
+		if ((features & NETIF_VLAN_FILTERING_FEATURES) != NETIF_VLAN_FILTERING_FEATURES &&
+		    (features & NETIF_VLAN_FILTERING_FEATURES) != 0) {
+			features &= ~NETIF_VLAN_FILTERING_FEATURES;
+			features |= netdev->features & NETIF_VLAN_FILTERING_FEATURES;
+			wx_err(wx, "802.1Q and 802.1ad VLAN filtering must be either both on or both off.");
+		}
+	}
+
+	return features;
+}
+EXPORT_SYMBOL(wx_fix_features);
+
 void wx_set_ring(struct wx *wx, u32 new_tx_count,
 		 u32 new_rx_count, struct wx_ring *temp_ring)
 {
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/libwx/wx_lib.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/libwx/wx_lib.h
@@ -30,6 +30,8 @@
 void wx_get_stats64(struct net_device *netdev,
 		    struct rtnl_link_stats64 *stats);
 int wx_set_features(struct net_device *netdev, netdev_features_t features);
+netdev_features_t wx_fix_features(struct net_device *netdev,
+				  netdev_features_t features);
 void wx_set_ring(struct wx *wx, u32 new_tx_count,
 		 u32 new_rx_count, struct wx_ring *temp_ring);
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/libwx/wx_type.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/libwx/wx_type.h
@@ -424,9 +424,9 @@
 #define WX_MIN_RXD                   128
 #define WX_MIN_TXD                   128
 
-/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
-#define WX_REQ_RX_DESCRIPTOR_MULTIPLE   8
-#define WX_REQ_TX_DESCRIPTOR_MULTIPLE   8
+/* Number of Transmit and Receive Descriptors must be a multiple of 128 */
+#define WX_REQ_RX_DESCRIPTOR_MULTIPLE   128
+#define WX_REQ_TX_DESCRIPTOR_MULTIPLE   128
 
 #define WX_MAX_JUMBO_FRAME_SIZE      9432 /* max payload 9414 */
 #define VMDQ_P(p)                    p
@@ -982,8 +982,13 @@
 	u64 qmprc;
 };
 
+enum wx_state {
+	WX_STATE_RESETTING,
+	WX_STATE_NBITS,		/* must be last */
+};
 struct wx {
 	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
+	DECLARE_BITMAP(state, WX_STATE_NBITS);
 
 	void *priv;
 	u8 __iomem *hw_addr;
@@ -1047,13 +1052,13 @@
 	unsigned int queues_per_pool;
 	struct msix_entry *msix_q_entries;
 	struct msix_entry *msix_entry;
-	bool msix_in_use;
 	struct wx_ring_feature ring_feature[RING_F_ARRAY_SIZE];
 
 	/* misc interrupt status block */
 	dma_addr_t isb_dma;
 	u32 *isb_mem;
 	u32 isb_tag[WX_ISB_MAX];
+	bool misc_irq_domain;
 
 #define WX_MAX_RETA_ENTRIES 128
 #define WX_RSS_INDIR_TBL_MAX 64
@@ -1072,6 +1077,8 @@
 	u64 hw_csum_rx_good;
 	u64 hw_csum_rx_error;
 	u64 alloc_rx_buff_failed;
+
+	void (*do_reset)(struct net_device *netdev);
 };
 
 #define WX_INTR_ALL (~0ULL)
@@ -1132,4 +1139,19 @@
 	return container_of(config, struct wx, phylink_config);
 }
 
+static inline int wx_set_state_reset(struct wx *wx)
+{
+	u8 timeout = 50;
+
+	while (test_and_set_bit(WX_STATE_RESETTING, wx->state)) {
+		timeout--;
+		if (!timeout)
+			return -EBUSY;
+
+		usleep_range(1000, 2000);
+	}
+
+	return 0;
+}
+
 #endif /* _WX_TYPE_H_ */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c
@@ -52,7 +52,7 @@
 	struct wx *wx = netdev_priv(netdev);
 	u32 new_rx_count, new_tx_count;
 	struct wx_ring *temp_ring;
-	int i;
+	int i, err = 0;
 
 	new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD);
 	new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE);
@@ -64,6 +64,10 @@
 	    new_rx_count == wx->rx_ring_count)
 		return 0;
 
+	err = wx_set_state_reset(wx);
+	if (err)
+		return err;
+
 	if (!netif_running(wx->netdev)) {
 		for (i = 0; i < wx->num_tx_queues; i++)
 			wx->tx_ring[i]->count = new_tx_count;
@@ -72,14 +76,16 @@
 		wx->tx_ring_count = new_tx_count;
 		wx->rx_ring_count = new_rx_count;
 
-		return 0;
+		goto clear_reset;
 	}
 
 	/* allocate temporary buffer to store rings in */
 	i = max_t(int, wx->num_tx_queues, wx->num_rx_queues);
 	temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL);
-	if (!temp_ring)
-		return -ENOMEM;
+	if (!temp_ring) {
+		err = -ENOMEM;
+		goto clear_reset;
+	}
 
 	ngbe_down(wx);
 
@@ -89,7 +95,9 @@
 	wx_configure(wx);
 	ngbe_up(wx);
 
-	return 0;
+clear_reset:
+	clear_bit(WX_STATE_RESETTING, wx->state);
+	return err;
 }
 
 static int ngbe_set_channels(struct net_device *dev,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
@@ -387,6 +387,7 @@
 err_free_irq:
 	wx_free_irq(wx);
 err_free_resources:
+	wx_free_isb_resources(wx);
 	wx_free_resources(wx);
 	return err;
 }
@@ -408,6 +409,7 @@
 
 	ngbe_down(wx);
 	wx_free_irq(wx);
+	wx_free_isb_resources(wx);
 	wx_free_resources(wx);
 	phylink_disconnect_phy(wx->phylink);
 	wx_control_hw(wx, false);
@@ -499,6 +501,7 @@
 	.ndo_start_xmit         = wx_xmit_frame,
 	.ndo_set_rx_mode        = wx_set_rx_mode,
 	.ndo_set_features       = wx_set_features,
+	.ndo_fix_features       = wx_fix_features,
 	.ndo_validate_addr      = eth_validate_addr,
 	.ndo_set_mac_address    = wx_set_mac,
 	.ndo_get_stats64        = wx_get_stats64,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/ngbe/ngbe_mdio.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/ngbe/ngbe_mdio.c
@@ -124,8 +124,12 @@
 				   MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
 	config->mac_managed_pm = true;
 
-	phy_mode = PHY_INTERFACE_MODE_RGMII_ID;
-	__set_bit(PHY_INTERFACE_MODE_RGMII_ID, config->supported_interfaces);
+	/* The MAC only has add the Tx delay and it can not be modified.
+	 * So just disable TX delay in PHY, and it is does not matter to
+	 * internal phy.
+	 */
+	phy_mode = PHY_INTERFACE_MODE_RGMII_RXID;
+	__set_bit(PHY_INTERFACE_MODE_RGMII_RXID, config->supported_interfaces);
 
 	phylink = phylink_create(config, NULL, phy_mode, &ngbe_mac_ops);
 	if (IS_ERR(phylink))
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/txgbe/Makefile
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/txgbe/Makefile
@@ -9,4 +9,5 @@
 txgbe-objs := txgbe_main.o \
               txgbe_hw.o \
               txgbe_phy.o \
+              txgbe_irq.o \
               txgbe_ethtool.o
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c
@@ -19,7 +19,7 @@
 	struct wx *wx = netdev_priv(netdev);
 	u32 new_rx_count, new_tx_count;
 	struct wx_ring *temp_ring;
-	int i;
+	int i, err = 0;
 
 	new_tx_count = clamp_t(u32, ring->tx_pending, WX_MIN_TXD, WX_MAX_TXD);
 	new_tx_count = ALIGN(new_tx_count, WX_REQ_TX_DESCRIPTOR_MULTIPLE);
@@ -31,6 +31,10 @@
 	    new_rx_count == wx->rx_ring_count)
 		return 0;
 
+	err = wx_set_state_reset(wx);
+	if (err)
+		return err;
+
 	if (!netif_running(wx->netdev)) {
 		for (i = 0; i < wx->num_tx_queues; i++)
 			wx->tx_ring[i]->count = new_tx_count;
@@ -39,14 +43,16 @@
 		wx->tx_ring_count = new_tx_count;
 		wx->rx_ring_count = new_rx_count;
 
-		return 0;
+		goto clear_reset;
 	}
 
 	/* allocate temporary buffer to store rings in */
 	i = max_t(int, wx->num_tx_queues, wx->num_rx_queues);
 	temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL);
-	if (!temp_ring)
-		return -ENOMEM;
+	if (!temp_ring) {
+		err = -ENOMEM;
+		goto clear_reset;
+	}
 
 	txgbe_down(wx);
 
@@ -55,7 +61,9 @@
 
 	txgbe_up(wx);
 
-	return 0;
+clear_reset:
+	clear_bit(WX_STATE_RESETTING, wx->state);
+	return err;
 }
 
 static int txgbe_set_channels(struct net_device *dev,
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2015 - 2024 Beijing WangXun Technology Co., Ltd. */
+
+#include <linux/irqdomain.h>
+#include <linux/pci.h>
+
+#include "../libwx/wx_type.h"
+#include "../libwx/wx_lib.h"
+#include "../libwx/wx_hw.h"
+#include "txgbe_type.h"
+#include "txgbe_phy.h"
+#include "txgbe_irq.h"
+
+/**
+ * txgbe_irq_enable - Enable default interrupt generation settings
+ * @wx: pointer to private structure
+ * @queues: enable irqs for queues
+ **/
+void txgbe_irq_enable(struct wx *wx, bool queues)
+{
+	wr32(wx, WX_PX_MISC_IEN, TXGBE_PX_MISC_IEN_MASK);
+
+	/* unmask interrupt */
+	wx_intr_enable(wx, TXGBE_INTR_MISC);
+	if (queues)
+		wx_intr_enable(wx, TXGBE_INTR_QALL(wx));
+}
+
+/**
+ * txgbe_request_queue_irqs - Initialize MSI-X queue interrupts
+ * @wx: board private structure
+ *
+ * Allocate MSI-X queue vectors and request interrupts from the kernel.
+ **/
+int txgbe_request_queue_irqs(struct wx *wx)
+{
+	struct net_device *netdev = wx->netdev;
+	int vector, err;
+
+	if (!wx->pdev->msix_enabled)
+		return 0;
+
+	for (vector = 0; vector < wx->num_q_vectors; vector++) {
+		struct wx_q_vector *q_vector = wx->q_vector[vector];
+		struct msix_entry *entry = &wx->msix_q_entries[vector];
+
+		if (q_vector->tx.ring && q_vector->rx.ring)
+			snprintf(q_vector->name, sizeof(q_vector->name) - 1,
+				 "%s-TxRx-%d", netdev->name, entry->entry);
+		else
+			/* skip this unused q_vector */
+			continue;
+
+		err = request_irq(entry->vector, wx_msix_clean_rings, 0,
+				  q_vector->name, q_vector);
+		if (err) {
+			wx_err(wx, "request_irq failed for MSIX interrupt %s Error: %d\n",
+			       q_vector->name, err);
+			goto free_queue_irqs;
+		}
+	}
+
+	return 0;
+
+free_queue_irqs:
+	while (vector) {
+		vector--;
+		free_irq(wx->msix_q_entries[vector].vector,
+			 wx->q_vector[vector]);
+	}
+	wx_reset_interrupt_capability(wx);
+	return err;
+}
+
+static int txgbe_request_link_irq(struct txgbe *txgbe)
+{
+	txgbe->link_irq = irq_find_mapping(txgbe->misc.domain, TXGBE_IRQ_LINK);
+	return request_threaded_irq(txgbe->link_irq, NULL,
+				    txgbe_link_irq_handler,
+				    IRQF_ONESHOT, "txgbe-link-irq", txgbe);
+}
+
+static const struct irq_chip txgbe_irq_chip = {
+	.name = "txgbe-misc-irq",
+};
+
+static int txgbe_misc_irq_domain_map(struct irq_domain *d,
+				     unsigned int irq,
+				     irq_hw_number_t hwirq)
+{
+	struct txgbe *txgbe = d->host_data;
+
+	irq_set_chip_data(irq, txgbe);
+	irq_set_chip(irq, &txgbe->misc.chip);
+	irq_set_nested_thread(irq, true);
+	irq_set_noprobe(irq);
+
+	return 0;
+}
+
+static const struct irq_domain_ops txgbe_misc_irq_domain_ops = {
+	.map = txgbe_misc_irq_domain_map,
+};
+
+static irqreturn_t txgbe_misc_irq_handle(int irq, void *data)
+{
+	struct wx_q_vector *q_vector;
+	struct txgbe *txgbe = data;
+	struct wx *wx = txgbe->wx;
+	u32 eicr;
+
+	if (wx->pdev->msix_enabled)
+		return IRQ_WAKE_THREAD;
+
+	eicr = wx_misc_isb(wx, WX_ISB_VEC0);
+	if (!eicr) {
+		/* shared interrupt alert!
+		 * the interrupt that we masked before the ICR read.
+		 */
+		if (netif_running(wx->netdev))
+			txgbe_irq_enable(wx, true);
+		return IRQ_NONE;        /* Not our interrupt */
+	}
+	wx->isb_mem[WX_ISB_VEC0] = 0;
+	if (!(wx->pdev->msi_enabled))
+		wr32(wx, WX_PX_INTA, 1);
+
+	/* would disable interrupts here but it is auto disabled */
+	q_vector = wx->q_vector[0];
+	napi_schedule_irqoff(&q_vector->napi);
+
+	return IRQ_WAKE_THREAD;
+}
+
+static irqreturn_t txgbe_misc_irq_thread_fn(int irq, void *data)
+{
+	struct txgbe *txgbe = data;
+	struct wx *wx = txgbe->wx;
+	unsigned int nhandled = 0;
+	unsigned int sub_irq;
+	u32 eicr;
+
+	eicr = wx_misc_isb(wx, WX_ISB_MISC);
+	if (eicr & (TXGBE_PX_MISC_ETH_LK | TXGBE_PX_MISC_ETH_LKDN |
+		    TXGBE_PX_MISC_ETH_AN)) {
+		sub_irq = irq_find_mapping(txgbe->misc.domain, TXGBE_IRQ_LINK);
+		handle_nested_irq(sub_irq);
+		nhandled++;
+	}
+
+	wx_intr_enable(wx, TXGBE_INTR_MISC);
+	return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
+}
+
+static void txgbe_del_irq_domain(struct txgbe *txgbe)
+{
+	int hwirq, virq;
+
+	for (hwirq = 0; hwirq < txgbe->misc.nirqs; hwirq++) {
+		virq = irq_find_mapping(txgbe->misc.domain, hwirq);
+		irq_dispose_mapping(virq);
+	}
+
+	irq_domain_remove(txgbe->misc.domain);
+}
+
+void txgbe_free_misc_irq(struct txgbe *txgbe)
+{
+	free_irq(txgbe->link_irq, txgbe);
+	free_irq(txgbe->misc.irq, txgbe);
+	txgbe_del_irq_domain(txgbe);
+}
+
+int txgbe_setup_misc_irq(struct txgbe *txgbe)
+{
+	unsigned long flags = IRQF_ONESHOT;
+	struct wx *wx = txgbe->wx;
+	int hwirq, err;
+
+	txgbe->misc.nirqs = 1;
+	txgbe->misc.domain = irq_domain_add_simple(NULL, txgbe->misc.nirqs, 0,
+						   &txgbe_misc_irq_domain_ops, txgbe);
+	if (!txgbe->misc.domain)
+		return -ENOMEM;
+
+	for (hwirq = 0; hwirq < txgbe->misc.nirqs; hwirq++)
+		irq_create_mapping(txgbe->misc.domain, hwirq);
+
+	txgbe->misc.chip = txgbe_irq_chip;
+	if (wx->pdev->msix_enabled) {
+		txgbe->misc.irq = wx->msix_entry->vector;
+	} else {
+		txgbe->misc.irq = wx->pdev->irq;
+		if (!wx->pdev->msi_enabled)
+			flags |= IRQF_SHARED;
+	}
+
+	err = request_threaded_irq(txgbe->misc.irq, txgbe_misc_irq_handle,
+				   txgbe_misc_irq_thread_fn,
+				   flags,
+				   wx->netdev->name, txgbe);
+	if (err)
+		goto del_misc_irq;
+
+	err = txgbe_request_link_irq(txgbe);
+	if (err)
+		goto free_msic_irq;
+
+	wx->misc_irq_domain = true;
+
+	return 0;
+
+free_msic_irq:
+	free_irq(txgbe->misc.irq, txgbe);
+del_misc_irq:
+	txgbe_del_irq_domain(txgbe);
+
+	return err;
+}
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/txgbe/txgbe_irq.h
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (c) 2015 - 2024 Beijing WangXun Technology Co., Ltd. */
+
+void txgbe_irq_enable(struct wx *wx, bool queues);
+int txgbe_request_queue_irqs(struct wx *wx);
+void txgbe_free_misc_irq(struct txgbe *txgbe);
+int txgbe_setup_misc_irq(struct txgbe *txgbe);
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c
@@ -17,6 +17,7 @@
 #include "txgbe_type.h"
 #include "txgbe_hw.h"
 #include "txgbe_phy.h"
+#include "txgbe_irq.h"
 #include "txgbe_ethtool.h"
 
 char txgbe_driver_name[] = "txgbe";
@@ -76,133 +77,6 @@
 	return physfns;
 }
 
-/**
- * txgbe_irq_enable - Enable default interrupt generation settings
- * @wx: pointer to private structure
- * @queues: enable irqs for queues
- **/
-static void txgbe_irq_enable(struct wx *wx, bool queues)
-{
-	wr32(wx, WX_PX_MISC_IEN, TXGBE_PX_MISC_IEN_MASK);
-
-	/* unmask interrupt */
-	wx_intr_enable(wx, TXGBE_INTR_MISC);
-	if (queues)
-		wx_intr_enable(wx, TXGBE_INTR_QALL(wx));
-}
-
-/**
- * txgbe_intr - msi/legacy mode Interrupt Handler
- * @irq: interrupt number
- * @data: pointer to a network interface device structure
- **/
-static irqreturn_t txgbe_intr(int __always_unused irq, void *data)
-{
-	struct wx_q_vector *q_vector;
-	struct wx *wx  = data;
-	struct pci_dev *pdev;
-	u32 eicr;
-
-	q_vector = wx->q_vector[0];
-	pdev = wx->pdev;
-
-	eicr = wx_misc_isb(wx, WX_ISB_VEC0);
-	if (!eicr) {
-		/* shared interrupt alert!
-		 * the interrupt that we masked before the ICR read.
-		 */
-		if (netif_running(wx->netdev))
-			txgbe_irq_enable(wx, true);
-		return IRQ_NONE;        /* Not our interrupt */
-	}
-	wx->isb_mem[WX_ISB_VEC0] = 0;
-	if (!(pdev->msi_enabled))
-		wr32(wx, WX_PX_INTA, 1);
-
-	wx->isb_mem[WX_ISB_MISC] = 0;
-	/* would disable interrupts here but it is auto disabled */
-	napi_schedule_irqoff(&q_vector->napi);
-
-	/* re-enable link(maybe) and non-queue interrupts, no flush.
-	 * txgbe_poll will re-enable the queue interrupts
-	 */
-	if (netif_running(wx->netdev))
-		txgbe_irq_enable(wx, false);
-
-	return IRQ_HANDLED;
-}
-
-/**
- * txgbe_request_msix_irqs - Initialize MSI-X interrupts
- * @wx: board private structure
- *
- * Allocate MSI-X vectors and request interrupts from the kernel.
- **/
-static int txgbe_request_msix_irqs(struct wx *wx)
-{
-	struct net_device *netdev = wx->netdev;
-	int vector, err;
-
-	for (vector = 0; vector < wx->num_q_vectors; vector++) {
-		struct wx_q_vector *q_vector = wx->q_vector[vector];
-		struct msix_entry *entry = &wx->msix_q_entries[vector];
-
-		if (q_vector->tx.ring && q_vector->rx.ring)
-			snprintf(q_vector->name, sizeof(q_vector->name) - 1,
-				 "%s-TxRx-%d", netdev->name, entry->entry);
-		else
-			/* skip this unused q_vector */
-			continue;
-
-		err = request_irq(entry->vector, wx_msix_clean_rings, 0,
-				  q_vector->name, q_vector);
-		if (err) {
-			wx_err(wx, "request_irq failed for MSIX interrupt %s Error: %d\n",
-			       q_vector->name, err);
-			goto free_queue_irqs;
-		}
-	}
-
-	return 0;
-
-free_queue_irqs:
-	while (vector) {
-		vector--;
-		free_irq(wx->msix_q_entries[vector].vector,
-			 wx->q_vector[vector]);
-	}
-	wx_reset_interrupt_capability(wx);
-	return err;
-}
-
-/**
- * txgbe_request_irq - initialize interrupts
- * @wx: board private structure
- *
- * Attempt to configure interrupts using the best available
- * capabilities of the hardware and kernel.
- **/
-static int txgbe_request_irq(struct wx *wx)
-{
-	struct net_device *netdev = wx->netdev;
-	struct pci_dev *pdev = wx->pdev;
-	int err;
-
-	if (pdev->msix_enabled)
-		err = txgbe_request_msix_irqs(wx);
-	else if (pdev->msi_enabled)
-		err = request_irq(wx->pdev->irq, &txgbe_intr, 0,
-				  netdev->name, wx);
-	else
-		err = request_irq(wx->pdev->irq, &txgbe_intr, IRQF_SHARED,
-				  netdev->name, wx);
-
-	if (err)
-		wx_err(wx, "request_irq failed, Error %d\n", err);
-
-	return err;
-}
-
 static void txgbe_up_complete(struct wx *wx)
 {
 	struct net_device *netdev = wx->netdev;
@@ -394,6 +268,8 @@
 	wx->tx_work_limit = TXGBE_DEFAULT_TX_WORK;
 	wx->rx_work_limit = TXGBE_DEFAULT_RX_WORK;
 
+	wx->do_reset = txgbe_do_reset;
+
 	return 0;
 }
 
@@ -417,9 +293,9 @@
 
 	wx_configure(wx);
 
-	err = txgbe_request_irq(wx);
+	err = txgbe_request_queue_irqs(wx);
 	if (err)
-		goto err_free_isb;
+		goto err_free_resources;
 
 	/* Notify the stack of the actual queue counts. */
 	err = netif_set_real_num_tx_queues(netdev, wx->num_tx_queues);
@@ -436,8 +312,8 @@
 
 err_free_irq:
 	wx_free_irq(wx);
-err_free_isb:
-	wx_free_isb_resources(wx);
+err_free_resources:
+	wx_free_resources(wx);
 err_reset:
 	txgbe_reset(wx);
 
@@ -518,6 +394,7 @@
 int txgbe_setup_tc(struct net_device *dev, u8 tc)
 {
 	struct wx *wx = netdev_priv(dev);
+	struct txgbe *txgbe = wx->priv;
 
 	/* Hardware has to reinitialize queues and interrupts to
 	 * match packet buffer alignment. Unfortunately, the
@@ -528,6 +405,7 @@
 	else
 		txgbe_reset(wx);
 
+	txgbe_free_misc_irq(txgbe);
 	wx_clear_interrupt_scheme(wx);
 
 	if (tc)
@@ -536,6 +414,7 @@
 		netdev_reset_tc(dev);
 
 	wx_init_interrupt_scheme(wx);
+	txgbe_setup_misc_irq(txgbe);
 
 	if (netif_running(dev))
 		txgbe_open(dev);
@@ -543,6 +422,34 @@
 	return 0;
 }
 
+static void txgbe_reinit_locked(struct wx *wx)
+{
+	int err = 0;
+
+	netif_trans_update(wx->netdev);
+
+	err = wx_set_state_reset(wx);
+	if (err) {
+		wx_err(wx, "wait device reset timeout\n");
+		return;
+	}
+
+	txgbe_down(wx);
+	txgbe_up(wx);
+
+	clear_bit(WX_STATE_RESETTING, wx->state);
+}
+
+void txgbe_do_reset(struct net_device *netdev)
+{
+	struct wx *wx = netdev_priv(netdev);
+
+	if (netif_running(netdev))
+		txgbe_reinit_locked(wx);
+	else
+		txgbe_reset(wx);
+}
+
 static const struct net_device_ops txgbe_netdev_ops = {
 	.ndo_open               = txgbe_open,
 	.ndo_stop               = txgbe_close,
@@ -550,6 +457,7 @@
 	.ndo_start_xmit         = wx_xmit_frame,
 	.ndo_set_rx_mode        = wx_set_rx_mode,
 	.ndo_set_features       = wx_set_features,
+	.ndo_fix_features       = wx_fix_features,
 	.ndo_validate_addr      = eth_validate_addr,
 	.ndo_set_mac_address    = wx_set_mac,
 	.ndo_get_stats64        = wx_get_stats64,
@@ -751,10 +659,14 @@
 	txgbe->wx = wx;
 	wx->priv = txgbe;
 
-	err = txgbe_init_phy(txgbe);
+	err = txgbe_setup_misc_irq(txgbe);
 	if (err)
 		goto err_release_hw;
 
+	err = txgbe_init_phy(txgbe);
+	if (err)
+		goto err_free_misc_irq;
+
 	err = register_netdev(netdev);
 	if (err)
 		goto err_remove_phy;
@@ -781,6 +693,8 @@
 
 err_remove_phy:
 	txgbe_remove_phy(txgbe);
+err_free_misc_irq:
+	txgbe_free_misc_irq(txgbe);
 err_release_hw:
 	wx_clear_interrupt_scheme(wx);
 	wx_control_hw(wx, false);
@@ -813,6 +727,8 @@
 	unregister_netdev(netdev);
 
 	txgbe_remove_phy(txgbe);
+	txgbe_free_misc_irq(txgbe);
+	wx_free_isb_resources(wx);
 
 	pci_release_selected_regions(pdev,
 				     pci_select_bars(pdev, IORESOURCE_MEM));
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
@@ -162,7 +162,7 @@
 	struct wx *wx = phylink_to_wx(config);
 	struct txgbe *txgbe = wx->priv;
 
-	if (interface == PHY_INTERFACE_MODE_10GBASER)
+	if (wx->media_type != sp_media_copper)
 		return &txgbe->xpcs->pcs;
 
 	return NULL;
@@ -292,6 +292,21 @@
 	return 0;
 }
 
+irqreturn_t txgbe_link_irq_handler(int irq, void *data)
+{
+	struct txgbe *txgbe = data;
+	struct wx *wx = txgbe->wx;
+	u32 status;
+	bool up;
+
+	status = rd32(wx, TXGBE_CFG_PORT_ST);
+	up = !!(status & TXGBE_CFG_PORT_ST_LINK_UP);
+
+	phylink_mac_change(wx->phylink, up);
+
+	return IRQ_HANDLED;
+}
+
 static int txgbe_gpio_get(struct gpio_chip *chip, unsigned int offset)
 {
 	struct wx *wx = gpiochip_get_data(chip);
@@ -343,156 +358,8 @@
 	return 0;
 }
 
-static void txgbe_gpio_irq_ack(struct irq_data *d)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	irq_hw_number_t hwirq = irqd_to_hwirq(d);
-	struct wx *wx = gpiochip_get_data(gc);
-	unsigned long flags;
-
-	raw_spin_lock_irqsave(&wx->gpio_lock, flags);
-	wr32(wx, WX_GPIO_EOI, BIT(hwirq));
-	raw_spin_unlock_irqrestore(&wx->gpio_lock, flags);
-}
-
-static void txgbe_gpio_irq_mask(struct irq_data *d)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	irq_hw_number_t hwirq = irqd_to_hwirq(d);
-	struct wx *wx = gpiochip_get_data(gc);
-	unsigned long flags;
-
-	gpiochip_disable_irq(gc, hwirq);
-
-	raw_spin_lock_irqsave(&wx->gpio_lock, flags);
-	wr32m(wx, WX_GPIO_INTMASK, BIT(hwirq), BIT(hwirq));
-	raw_spin_unlock_irqrestore(&wx->gpio_lock, flags);
-}
-
-static void txgbe_gpio_irq_unmask(struct irq_data *d)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	irq_hw_number_t hwirq = irqd_to_hwirq(d);
-	struct wx *wx = gpiochip_get_data(gc);
-	unsigned long flags;
-
-	gpiochip_enable_irq(gc, hwirq);
-
-	raw_spin_lock_irqsave(&wx->gpio_lock, flags);
-	wr32m(wx, WX_GPIO_INTMASK, BIT(hwirq), 0);
-	raw_spin_unlock_irqrestore(&wx->gpio_lock, flags);
-}
-
-static void txgbe_toggle_trigger(struct gpio_chip *gc, unsigned int offset)
-{
-	struct wx *wx = gpiochip_get_data(gc);
-	u32 pol, val;
-
-	pol = rd32(wx, WX_GPIO_POLARITY);
-	val = rd32(wx, WX_GPIO_EXT);
-
-	if (val & BIT(offset))
-		pol &= ~BIT(offset);
-	else
-		pol |= BIT(offset);
-
-	wr32(wx, WX_GPIO_POLARITY, pol);
-}
-
-static int txgbe_gpio_set_type(struct irq_data *d, unsigned int type)
-{
-	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
-	irq_hw_number_t hwirq = irqd_to_hwirq(d);
-	struct wx *wx = gpiochip_get_data(gc);
-	u32 level, polarity, mask;
-	unsigned long flags;
-
-	mask = BIT(hwirq);
-
-	if (type & IRQ_TYPE_LEVEL_MASK) {
-		level = 0;
-		irq_set_handler_locked(d, handle_level_irq);
-	} else {
-		level = mask;
-		irq_set_handler_locked(d, handle_edge_irq);
-	}
-
-	if (type == IRQ_TYPE_EDGE_RISING || type == IRQ_TYPE_LEVEL_HIGH)
-		polarity = mask;
-	else
-		polarity = 0;
-
-	raw_spin_lock_irqsave(&wx->gpio_lock, flags);
-
-	wr32m(wx, WX_GPIO_INTEN, mask, mask);
-	wr32m(wx, WX_GPIO_INTTYPE_LEVEL, mask, level);
-	if (type == IRQ_TYPE_EDGE_BOTH)
-		txgbe_toggle_trigger(gc, hwirq);
-	else
-		wr32m(wx, WX_GPIO_POLARITY, mask, polarity);
-
-	raw_spin_unlock_irqrestore(&wx->gpio_lock, flags);
-
-	return 0;
-}
-
-static const struct irq_chip txgbe_gpio_irq_chip = {
-	.name = "txgbe_gpio_irq",
-	.irq_ack = txgbe_gpio_irq_ack,
-	.irq_mask = txgbe_gpio_irq_mask,
-	.irq_unmask = txgbe_gpio_irq_unmask,
-	.irq_set_type = txgbe_gpio_set_type,
-	.flags = IRQCHIP_IMMUTABLE,
-	GPIOCHIP_IRQ_RESOURCE_HELPERS,
-};
-
-static void txgbe_irq_handler(struct irq_desc *desc)
-{
-	struct irq_chip *chip = irq_desc_get_chip(desc);
-	struct wx *wx = irq_desc_get_handler_data(desc);
-	struct txgbe *txgbe = wx->priv;
-	irq_hw_number_t hwirq;
-	unsigned long gpioirq;
-	struct gpio_chip *gc;
-	unsigned long flags;
-	u32 eicr;
-
-	eicr = wx_misc_isb(wx, WX_ISB_MISC);
-
-	chained_irq_enter(chip, desc);
-
-	gpioirq = rd32(wx, WX_GPIO_INTSTATUS);
-
-	gc = txgbe->gpio;
-	for_each_set_bit(hwirq, &gpioirq, gc->ngpio) {
-		int gpio = irq_find_mapping(gc->irq.domain, hwirq);
-		u32 irq_type = irq_get_trigger_type(gpio);
-
-		generic_handle_domain_irq(gc->irq.domain, hwirq);
-
-		if ((irq_type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
-			raw_spin_lock_irqsave(&wx->gpio_lock, flags);
-			txgbe_toggle_trigger(gc, hwirq);
-			raw_spin_unlock_irqrestore(&wx->gpio_lock, flags);
-		}
-	}
-
-	chained_irq_exit(chip, desc);
-
-	if (eicr & (TXGBE_PX_MISC_ETH_LK | TXGBE_PX_MISC_ETH_LKDN |
-		    TXGBE_PX_MISC_ETH_AN)) {
-		u32 reg = rd32(wx, TXGBE_CFG_PORT_ST);
-
-		phylink_mac_change(wx->phylink, !!(reg & TXGBE_CFG_PORT_ST_LINK_UP));
-	}
-
-	/* unmask interrupt */
-	wx_intr_enable(wx, TXGBE_INTR_MISC);
-}
-
 static int txgbe_gpio_init(struct txgbe *txgbe)
 {
-	struct gpio_irq_chip *girq;
 	struct gpio_chip *gc;
 	struct device *dev;
 	struct wx *wx;
@@ -522,24 +389,6 @@
 	gc->direction_input = txgbe_gpio_direction_in;
 	gc->direction_output = txgbe_gpio_direction_out;
 
-	girq = &gc->irq;
-	gpio_irq_chip_set_chip(girq, &txgbe_gpio_irq_chip);
-	girq->parent_handler = txgbe_irq_handler;
-	girq->parent_handler_data = wx;
-	girq->num_parents = 1;
-	girq->parents = devm_kcalloc(dev, girq->num_parents,
-				     sizeof(*girq->parents), GFP_KERNEL);
-	if (!girq->parents)
-		return -ENOMEM;
-
-	/* now only suuported on MSI-X interrupt */
-	if (!wx->msix_entry)
-		return -EPERM;
-
-	girq->parents[0] = wx->msix_entry->vector;
-	girq->default_type = IRQ_TYPE_NONE;
-	girq->handler = handle_bad_irq;
-
 	ret = devm_gpiochip_add_data(dev, gc, wx);
 	if (ret)
 		return ret;
@@ -754,8 +603,6 @@
 		goto err_unregister_i2c;
 	}
 
-	wx->msix_in_use = true;
-
 	return 0;
 
 err_unregister_i2c:
@@ -788,5 +635,4 @@
 	phylink_destroy(txgbe->wx->phylink);
 	xpcs_destroy(txgbe->xpcs);
 	software_node_unregister_node_group(txgbe->nodes.group);
-	txgbe->wx->msix_in_use = false;
 }
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/txgbe/txgbe_phy.h
@@ -4,6 +4,7 @@
 #ifndef _TXGBE_PHY_H_
 #define _TXGBE_PHY_H_
 
+irqreturn_t txgbe_link_irq_handler(int irq, void *data);
 int txgbe_init_phy(struct txgbe *txgbe);
 void txgbe_remove_phy(struct txgbe *txgbe);
 
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/wangxun/txgbe/txgbe_type.h
@@ -5,6 +5,7 @@
 #define _TXGBE_TYPE_H_
 
 #include <linux/property.h>
+#include <linux/irq.h>
 
 /* Device IDs */
 #define TXGBE_DEV_ID_SP1000                     0x1001
@@ -74,8 +75,7 @@
 #define TXGBE_PX_MISC_IEN_MASK                            \
 	(TXGBE_PX_MISC_ETH_LKDN | TXGBE_PX_MISC_DEV_RST | \
 	 TXGBE_PX_MISC_ETH_EVENT | TXGBE_PX_MISC_ETH_LK | \
-	 TXGBE_PX_MISC_ETH_AN | TXGBE_PX_MISC_INT_ERR |   \
-	 TXGBE_PX_MISC_GPIO)
+	 TXGBE_PX_MISC_ETH_AN | TXGBE_PX_MISC_INT_ERR)
 
 /* Port cfg registers */
 #define TXGBE_CFG_PORT_ST                       0x14404
@@ -133,6 +133,7 @@
 void txgbe_down(struct wx *wx);
 void txgbe_up(struct wx *wx);
 int txgbe_setup_tc(struct net_device *dev, u8 tc);
+void txgbe_do_reset(struct net_device *netdev);
 
 #define NODE_PROP(_NAME, _PROP)			\
 	(const struct software_node) {		\
@@ -169,15 +170,29 @@
 	const struct software_node *group[SWNODE_MAX + 1];
 };
 
+enum txgbe_misc_irqs {
+	TXGBE_IRQ_LINK = 0,
+	TXGBE_IRQ_MAX
+};
+
+struct txgbe_irq {
+	struct irq_chip chip;
+	struct irq_domain *domain;
+	int nirqs;
+	int irq;
+};
+
 struct txgbe {
 	struct wx *wx;
 	struct txgbe_nodes nodes;
+	struct txgbe_irq misc;
 	struct dw_xpcs *xpcs;
 	struct platform_device *sfp_dev;
 	struct platform_device *i2c_dev;
 	struct clk_lookup *clock;
 	struct clk *clk;
 	struct gpio_chip *gpio;
+	unsigned int link_irq;
 };
 
 #endif /* _TXGBE_TYPE_H_ */
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -1443,7 +1443,7 @@
 	}
 
 	/* map device registers */
-	lp->regs = devm_platform_ioremap_resource_byname(pdev, 0);
+	lp->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(lp->regs)) {
 		dev_err(&pdev->dev, "could not map TEMAC registers\n");
 		return -ENOMEM;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/xilinx/xilinx_axienet.h
+++ linux-qcom-6.8.0/drivers/net/ethernet/xilinx/xilinx_axienet.h
@@ -160,16 +160,17 @@
 #define XAE_RCW1_OFFSET		0x00000404 /* Rx Configuration Word 1 */
 #define XAE_TC_OFFSET		0x00000408 /* Tx Configuration */
 #define XAE_FCC_OFFSET		0x0000040C /* Flow Control Configuration */
-#define XAE_EMMC_OFFSET		0x00000410 /* EMAC mode configuration */
-#define XAE_PHYC_OFFSET		0x00000414 /* RGMII/SGMII configuration */
+#define XAE_EMMC_OFFSET		0x00000410 /* MAC speed configuration */
+#define XAE_PHYC_OFFSET		0x00000414 /* RX Max Frame Configuration */
 #define XAE_ID_OFFSET		0x000004F8 /* Identification register */
-#define XAE_MDIO_MC_OFFSET	0x00000500 /* MII Management Config */
-#define XAE_MDIO_MCR_OFFSET	0x00000504 /* MII Management Control */
-#define XAE_MDIO_MWD_OFFSET	0x00000508 /* MII Management Write Data */
-#define XAE_MDIO_MRD_OFFSET	0x0000050C /* MII Management Read Data */
+#define XAE_MDIO_MC_OFFSET	0x00000500 /* MDIO Setup */
+#define XAE_MDIO_MCR_OFFSET	0x00000504 /* MDIO Control */
+#define XAE_MDIO_MWD_OFFSET	0x00000508 /* MDIO Write Data */
+#define XAE_MDIO_MRD_OFFSET	0x0000050C /* MDIO Read Data */
 #define XAE_UAW0_OFFSET		0x00000700 /* Unicast address word 0 */
 #define XAE_UAW1_OFFSET		0x00000704 /* Unicast address word 1 */
-#define XAE_FMI_OFFSET		0x00000708 /* Filter Mask Index */
+#define XAE_FMI_OFFSET		0x00000708 /* Frame Filter Control */
+#define XAE_FFE_OFFSET		0x0000070C /* Frame Filter Enable */
 #define XAE_AF0_OFFSET		0x00000710 /* Address Filter 0 */
 #define XAE_AF1_OFFSET		0x00000714 /* Address Filter 1 */
 
@@ -308,7 +309,7 @@
  */
 #define XAE_UAW1_UNICASTADDR_MASK	0x0000FFFF
 
-/* Bit masks for Axi Ethernet FMI register */
+/* Bit masks for Axi Ethernet FMC register */
 #define XAE_FMI_PM_MASK			0x80000000 /* Promis. mode enable */
 #define XAE_FMI_IND_MASK		0x00000003 /* Index Mask */
 
@@ -435,6 +436,8 @@
  * @tx_bytes:	TX byte count for statistics
  * @tx_stat_sync: Synchronization object for TX stats
  * @dma_err_task: Work structure to process Axi DMA errors
+ * @stopping:   Set when @dma_err_task shouldn't do anything because we are
+ *              about to stop the device.
  * @tx_irq:	Axidma TX IRQ number
  * @rx_irq:	Axidma RX IRQ number
  * @eth_irq:	Ethernet core IRQ number
@@ -506,6 +509,7 @@
 	struct u64_stats_sync tx_stat_sync;
 
 	struct work_struct dma_err_task;
+	bool stopping;
 
 	int tx_irq;
 	int rx_irq;
--- linux-qcom-6.8.0.orig/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
+++ linux-qcom-6.8.0/drivers/net/ethernet/xilinx/xilinx_axienet_main.c
@@ -432,7 +432,7 @@
  */
 static void axienet_set_multicast_list(struct net_device *ndev)
 {
-	int i;
+	int i = 0;
 	u32 reg, af0reg, af1reg;
 	struct axienet_local *lp = netdev_priv(ndev);
 
@@ -450,7 +450,10 @@
 	} else if (!netdev_mc_empty(ndev)) {
 		struct netdev_hw_addr *ha;
 
-		i = 0;
+		reg = axienet_ior(lp, XAE_FMI_OFFSET);
+		reg &= ~XAE_FMI_PM_MASK;
+		axienet_iow(lp, XAE_FMI_OFFSET, reg);
+
 		netdev_for_each_mc_addr(ha, ndev) {
 			if (i >= XAE_MULTICAST_CAM_TABLE_NUM)
 				break;
@@ -469,6 +472,7 @@
 			axienet_iow(lp, XAE_FMI_OFFSET, reg);
 			axienet_iow(lp, XAE_AF0_OFFSET, af0reg);
 			axienet_iow(lp, XAE_AF1_OFFSET, af1reg);
+			axienet_iow(lp, XAE_FFE_OFFSET, 1);
 			i++;
 		}
 	} else {
@@ -476,18 +480,15 @@
 		reg &= ~XAE_FMI_PM_MASK;
 
 		axienet_iow(lp, XAE_FMI_OFFSET, reg);
-
-		for (i = 0; i < XAE_MULTICAST_CAM_TABLE_NUM; i++) {
-			reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00;
-			reg |= i;
-
-			axienet_iow(lp, XAE_FMI_OFFSET, reg);
-			axienet_iow(lp, XAE_AF0_OFFSET, 0);
-			axienet_iow(lp, XAE_AF1_OFFSET, 0);
-		}
-
 		dev_info(&ndev->dev, "Promiscuous mode disabled.\n");
 	}
+
+	for (; i < XAE_MULTICAST_CAM_TABLE_NUM; i++) {
+		reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00;
+		reg |= i;
+		axienet_iow(lp, XAE_FMI_OFFSET, reg);
+		axienet_iow(lp, XAE_FFE_OFFSET, 0);
+	}
 }
 
 /**
@@ -673,15 +674,15 @@
  *
  * Would either be called after a successful transmit operation, or after
  * there was an error when setting up the chain.
- * Returns the number of descriptors handled.
+ * Returns the number of packets handled.
  */
 static int axienet_free_tx_chain(struct axienet_local *lp, u32 first_bd,
 				 int nr_bds, bool force, u32 *sizep, int budget)
 {
 	struct axidma_bd *cur_p;
 	unsigned int status;
+	int i, packets = 0;
 	dma_addr_t phys;
-	int i;
 
 	for (i = 0; i < nr_bds; i++) {
 		cur_p = &lp->tx_bd_v[(first_bd + i) % lp->tx_bd_num];
@@ -700,8 +701,10 @@
 				 (cur_p->cntrl & XAXIDMA_BD_CTRL_LENGTH_MASK),
 				 DMA_TO_DEVICE);
 
-		if (cur_p->skb && (status & XAXIDMA_BD_STS_COMPLETE_MASK))
+		if (cur_p->skb && (status & XAXIDMA_BD_STS_COMPLETE_MASK)) {
 			napi_consume_skb(cur_p->skb, budget);
+			packets++;
+		}
 
 		cur_p->app0 = 0;
 		cur_p->app1 = 0;
@@ -717,7 +720,13 @@
 			*sizep += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK;
 	}
 
-	return i;
+	if (!force) {
+		lp->tx_bd_ci += i;
+		if (lp->tx_bd_ci >= lp->tx_bd_num)
+			lp->tx_bd_ci %= lp->tx_bd_num;
+	}
+
+	return packets;
 }
 
 /**
@@ -853,13 +862,13 @@
 	skbuf_dma->sg_len = sg_len;
 	dma_tx_desc->callback_param = lp;
 	dma_tx_desc->callback_result = axienet_dma_tx_cb;
-	dmaengine_submit(dma_tx_desc);
-	dma_async_issue_pending(lp->tx_chan);
 	txq = skb_get_tx_queue(lp->ndev, skb);
 	netdev_tx_sent_queue(txq, skb->len);
 	netif_txq_maybe_stop(txq, CIRC_SPACE(lp->tx_ring_head, lp->tx_ring_tail, TX_BD_NUM_MAX),
 			     MAX_SKB_FRAGS + 1, 2 * MAX_SKB_FRAGS);
 
+	dmaengine_submit(dma_tx_desc);
+	dma_async_issue_pending(lp->tx_chan);
 	return NETDEV_TX_OK;
 
 xmit_error_unmap_sg:
@@ -890,13 +899,10 @@
 	u32 size = 0;
 	int packets;
 
-	packets = axienet_free_tx_chain(lp, lp->tx_bd_ci, budget, false, &size, budget);
+	packets = axienet_free_tx_chain(lp, lp->tx_bd_ci, lp->tx_bd_num, false,
+					&size, budget);
 
 	if (packets) {
-		lp->tx_bd_ci += packets;
-		if (lp->tx_bd_ci >= lp->tx_bd_num)
-			lp->tx_bd_ci %= lp->tx_bd_num;
-
 		u64_stats_update_begin(&lp->tx_stat_sync);
 		u64_stats_add(&lp->tx_packets, packets);
 		u64_stats_add(&lp->tx_bytes, size);
@@ -983,6 +989,7 @@
 		if (net_ratelimit())
 			netdev_err(ndev, "TX DMA mapping error\n");
 		ndev->stats.tx_dropped++;
+		dev_kfree_skb_any(skb);
 		return NETDEV_TX_OK;
 	}
 	desc_set_phys_addr(lp, phys, cur_p);
@@ -1003,6 +1010,7 @@
 			ndev->stats.tx_dropped++;
 			axienet_free_tx_chain(lp, orig_tail_ptr, ii + 1,
 					      true, NULL, 0);
+			dev_kfree_skb_any(skb);
 			return NETDEV_TX_OK;
 		}
 		desc_set_phys_addr(lp, phys, cur_p);
@@ -1221,9 +1229,10 @@
 		u32 cr = lp->tx_dma_cr;
 
 		cr &= ~(XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK);
-		axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
-
-		napi_schedule(&lp->napi_tx);
+		if (napi_schedule_prep(&lp->napi_tx)) {
+			axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr);
+			__napi_schedule(&lp->napi_tx);
+		}
 	}
 
 	return IRQ_HANDLED;
@@ -1265,9 +1274,10 @@
 		u32 cr = lp->rx_dma_cr;
 
 		cr &= ~(XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK);
-		axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
-
-		napi_schedule(&lp->napi_rx);
+		if (napi_schedule_prep(&lp->napi_rx)) {
+			axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr);
+			__napi_schedule(&lp->napi_rx);
+		}
 	}
 
 	return IRQ_HANDLED;
@@ -1459,6 +1469,7 @@
 	struct axienet_local *lp = netdev_priv(ndev);
 
 	/* Enable worker thread for Axi DMA error handling */
+	lp->stopping = false;
 	INIT_WORK(&lp->dma_err_task, axienet_dma_err_handler);
 
 	napi_enable(&lp->napi_rx);
@@ -1579,6 +1590,9 @@
 	dev_dbg(&ndev->dev, "axienet_close()\n");
 
 	if (!lp->use_dmaengine) {
+		WRITE_ONCE(lp->stopping, true);
+		flush_work(&lp->dma_err_task);
+
 		napi_disable(&lp->napi_tx);
 		napi_disable(&lp->napi_rx);
 	}
@@ -1950,6 +1964,12 @@
 		return -EFAULT;
 	}
 
+	if (ecoalesce->rx_max_coalesced_frames > 255 ||
+	    ecoalesce->tx_max_coalesced_frames > 255) {
+		NL_SET_ERR_MSG(extack, "frames must be less than 256");
+		return -EINVAL;
+	}
+
 	if (ecoalesce->rx_max_coalesced_frames)
 		lp->coalesce_count_rx = ecoalesce->rx_max_coalesced_frames;
 	if (ecoalesce->rx_coalesce_usecs)
@@ -2153,6 +2173,10 @@
 						dma_err_task);
 	struct net_device *ndev = lp->ndev;
 
+	/* Don't bother if we are going to stop anyway */
+	if (READ_ONCE(lp->stopping))
+		return;
+
 	napi_disable(&lp->napi_tx);
 	napi_disable(&lp->napi_rx);
 
@@ -2219,9 +2243,9 @@
 			   ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN));
 	axienet_set_mac_address(ndev, NULL);
 	axienet_set_multicast_list(ndev);
-	axienet_setoptions(ndev, lp->options);
 	napi_enable(&lp->napi_rx);
 	napi_enable(&lp->napi_tx);
+	axienet_setoptions(ndev, lp->options);
 }
 
 /**
--- linux-qcom-6.8.0.orig/drivers/net/geneve.c
+++ linux-qcom-6.8.0/drivers/net/geneve.c
@@ -349,6 +349,7 @@
 		gro_cells_destroy(&geneve->gro_cells);
 		return err;
 	}
+	netdev_lockdep_set_classes(dev);
 	return 0;
 }
 
@@ -818,6 +819,7 @@
 			   struct geneve_dev *geneve,
 			   const struct ip_tunnel_info *info)
 {
+	bool inner_proto_inherit = geneve->cfg.inner_proto_inherit;
 	bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
 	struct geneve_sock *gs4 = rcu_dereference(geneve->sock4);
 	const struct ip_tunnel_key *key = &info->key;
@@ -829,7 +831,7 @@
 	__be16 sport;
 	int err;
 
-	if (!pskb_inet_may_pull(skb))
+	if (!skb_vlan_inet_prepare(skb, inner_proto_inherit))
 		return -EINVAL;
 
 	if (!gs4)
@@ -896,7 +898,7 @@
 		if (geneve->cfg.df == GENEVE_DF_SET) {
 			df = htons(IP_DF);
 		} else if (geneve->cfg.df == GENEVE_DF_INHERIT) {
-			struct ethhdr *eth = eth_hdr(skb);
+			struct ethhdr *eth = skb_eth_hdr(skb);
 
 			if (ntohs(eth->h_proto) == ETH_P_IPV6) {
 				df = htons(IP_DF);
@@ -910,7 +912,7 @@
 	}
 
 	err = geneve_build_skb(&rt->dst, skb, info, xnet, sizeof(struct iphdr),
-			       geneve->cfg.inner_proto_inherit);
+			       inner_proto_inherit);
 	if (unlikely(err))
 		return err;
 
@@ -926,6 +928,7 @@
 			    struct geneve_dev *geneve,
 			    const struct ip_tunnel_info *info)
 {
+	bool inner_proto_inherit = geneve->cfg.inner_proto_inherit;
 	bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
 	struct geneve_sock *gs6 = rcu_dereference(geneve->sock6);
 	const struct ip_tunnel_key *key = &info->key;
@@ -936,7 +939,7 @@
 	__be16 sport;
 	int err;
 
-	if (!pskb_inet_may_pull(skb))
+	if (!skb_vlan_inet_prepare(skb, inner_proto_inherit))
 		return -EINVAL;
 
 	if (!gs6)
@@ -998,7 +1001,7 @@
 		ttl = ttl ? : ip6_dst_hoplimit(dst);
 	}
 	err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct ipv6hdr),
-			       geneve->cfg.inner_proto_inherit);
+			       inner_proto_inherit);
 	if (unlikely(err))
 		return err;
 
--- linux-qcom-6.8.0.orig/drivers/net/gtp.c
+++ linux-qcom-6.8.0/drivers/net/gtp.c
@@ -901,6 +901,9 @@
 	if (skb_cow_head(skb, dev->needed_headroom))
 		goto tx_err;
 
+	if (!pskb_inet_may_pull(skb))
+		goto tx_err;
+
 	skb_reset_inner_headers(skb);
 
 	/* PDP context lookups in gtp_build_skb_*() need rcu read-side lock. */
@@ -1092,8 +1095,8 @@
 		goto out_encap;
 	}
 
-	gn = net_generic(dev_net(dev), gtp_net_id);
-	list_add_rcu(&gtp->list, &gn->gtp_dev_list);
+	gn = net_generic(src_net, gtp_net_id);
+	list_add(&gtp->list, &gn->gtp_dev_list);
 	dev->priv_destructor = gtp_destructor;
 
 	netdev_dbg(dev, "registered new GTP interface\n");
@@ -1111,14 +1114,15 @@
 static void gtp_dellink(struct net_device *dev, struct list_head *head)
 {
 	struct gtp_dev *gtp = netdev_priv(dev);
+	struct hlist_node *next;
 	struct pdp_ctx *pctx;
 	int i;
 
 	for (i = 0; i < gtp->hash_size; i++)
-		hlist_for_each_entry_rcu(pctx, &gtp->tid_hash[i], hlist_tid)
+		hlist_for_each_entry_safe(pctx, next, &gtp->tid_hash[i], hlist_tid)
 			pdp_context_delete(pctx);
 
-	list_del_rcu(&gtp->list);
+	list_del(&gtp->list);
 	unregister_netdevice_queue(dev, head);
 }
 
@@ -1216,7 +1220,7 @@
 	sock = sockfd_lookup(fd, &err);
 	if (!sock) {
 		pr_debug("gtp socket fd=%d not found\n", fd);
-		return NULL;
+		return ERR_PTR(err);
 	}
 
 	sk = sock->sk;
@@ -1259,20 +1263,24 @@
 		return -EINVAL;
 
 	if (data[IFLA_GTP_FD0]) {
-		u32 fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
+		int fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
 
-		sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp);
-		if (IS_ERR(sk0))
-			return PTR_ERR(sk0);
+		if (fd0 >= 0) {
+			sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp);
+			if (IS_ERR(sk0))
+				return PTR_ERR(sk0);
+		}
 	}
 
 	if (data[IFLA_GTP_FD1]) {
-		u32 fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
+		int fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
 
-		sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp);
-		if (IS_ERR(sk1u)) {
-			gtp_encap_disable_sock(sk0);
-			return PTR_ERR(sk1u);
+		if (fd1 >= 0) {
+			sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp);
+			if (IS_ERR(sk1u)) {
+				gtp_encap_disable_sock(sk0);
+				return PTR_ERR(sk1u);
+			}
 		}
 	}
 
@@ -1682,16 +1690,19 @@
 	struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp;
 	int i, j, bucket = cb->args[0], skip = cb->args[1];
 	struct net *net = sock_net(skb->sk);
+	struct net_device *dev;
 	struct pdp_ctx *pctx;
-	struct gtp_net *gn;
-
-	gn = net_generic(net, gtp_net_id);
 
 	if (cb->args[4])
 		return 0;
 
 	rcu_read_lock();
-	list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) {
+	for_each_netdev_rcu(net, dev) {
+		if (dev->rtnl_link_ops != &gtp_link_ops)
+			continue;
+
+		gtp = netdev_priv(dev);
+
 		if (last_gtp && last_gtp != gtp)
 			continue;
 		else
@@ -1876,23 +1887,23 @@
 	return 0;
 }
 
-static void __net_exit gtp_net_exit(struct net *net)
+static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list,
+					       struct list_head *dev_to_kill)
 {
-	struct gtp_net *gn = net_generic(net, gtp_net_id);
-	struct gtp_dev *gtp;
-	LIST_HEAD(list);
+	struct net *net;
 
-	rtnl_lock();
-	list_for_each_entry(gtp, &gn->gtp_dev_list, list)
-		gtp_dellink(gtp->dev, &list);
+	list_for_each_entry(net, net_list, exit_list) {
+		struct gtp_net *gn = net_generic(net, gtp_net_id);
+		struct gtp_dev *gtp, *gtp_next;
 
-	unregister_netdevice_many(&list);
-	rtnl_unlock();
+		list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list)
+			gtp_dellink(gtp->dev, dev_to_kill);
+	}
 }
 
 static struct pernet_operations gtp_net_ops = {
 	.init	= gtp_net_init,
-	.exit	= gtp_net_exit,
+	.exit_batch_rtnl = gtp_net_exit_batch_rtnl,
 	.id	= &gtp_net_id,
 	.size	= sizeof(struct gtp_net),
 };
--- linux-qcom-6.8.0.orig/drivers/net/hyperv/netvsc.c
+++ linux-qcom-6.8.0/drivers/net/hyperv/netvsc.c
@@ -154,8 +154,11 @@
 	int i;
 
 	kfree(nvdev->extension);
-	vfree(nvdev->recv_buf);
-	vfree(nvdev->send_buf);
+
+	if (!nvdev->recv_buf_gpadl_handle.decrypted)
+		vfree(nvdev->recv_buf);
+	if (!nvdev->send_buf_gpadl_handle.decrypted)
+		vfree(nvdev->send_buf);
 	bitmap_free(nvdev->send_section_map);
 
 	for (i = 0; i < VRSS_CHANNEL_MAX; i++) {
--- linux-qcom-6.8.0.orig/drivers/net/hyperv/netvsc_drv.c
+++ linux-qcom-6.8.0/drivers/net/hyperv/netvsc_drv.c
@@ -2797,6 +2797,31 @@
 	},
 };
 
+/* Set VF's namespace same as the synthetic NIC */
+static void netvsc_event_set_vf_ns(struct net_device *ndev)
+{
+	struct net_device_context *ndev_ctx = netdev_priv(ndev);
+	struct net_device *vf_netdev;
+	int ret;
+
+	vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
+	if (!vf_netdev)
+		return;
+
+	if (!net_eq(dev_net(ndev), dev_net(vf_netdev))) {
+		ret = dev_change_net_namespace(vf_netdev, dev_net(ndev),
+					       "eth%d");
+		if (ret)
+			netdev_err(vf_netdev,
+				   "Cannot move to same namespace as %s: %d\n",
+				   ndev->name, ret);
+		else
+			netdev_info(vf_netdev,
+				    "Moved VF to namespace with: %s\n",
+				    ndev->name);
+	}
+}
+
 /*
  * On Hyper-V, every VF interface is matched with a corresponding
  * synthetic interface. The synthetic interface is presented first
@@ -2809,6 +2834,11 @@
 	struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
 	int ret = 0;
 
+	if (event_dev->netdev_ops == &device_ops && event == NETDEV_REGISTER) {
+		netvsc_event_set_vf_ns(event_dev);
+		return NOTIFY_DONE;
+	}
+
 	ret = check_dev_is_matching_vf(event_dev);
 	if (ret != 0)
 		return NOTIFY_DONE;
--- linux-qcom-6.8.0.orig/drivers/net/ieee802154/Kconfig
+++ linux-qcom-6.8.0/drivers/net/ieee802154/Kconfig
@@ -101,6 +101,7 @@
 
 config IEEE802154_MCR20A
 	tristate "MCR20A transceiver driver"
+	select REGMAP_SPI
 	depends on IEEE802154_DRIVERS && MAC802154
 	depends on SPI
 	help
--- linux-qcom-6.8.0.orig/drivers/net/ieee802154/ca8210.c
+++ linux-qcom-6.8.0/drivers/net/ieee802154/ca8210.c
@@ -3078,7 +3078,11 @@
 	spi_set_drvdata(priv->spi, priv);
 	if (IS_ENABLED(CONFIG_IEEE802154_CA8210_DEBUGFS)) {
 		cascoda_api_upstream = ca8210_test_int_driver_write;
-		ca8210_test_interface_init(priv);
+		ret = ca8210_test_interface_init(priv);
+		if (ret) {
+			dev_crit(&spi_device->dev, "ca8210_test_interface_init failed\n");
+			goto error;
+		}
 	} else {
 		cascoda_api_upstream = NULL;
 	}
--- linux-qcom-6.8.0.orig/drivers/net/ieee802154/mcr20a.c
+++ linux-qcom-6.8.0/drivers/net/ieee802154/mcr20a.c
@@ -1303,16 +1303,13 @@
 		irq_type = IRQF_TRIGGER_FALLING;
 
 	ret = devm_request_irq(&spi->dev, spi->irq, mcr20a_irq_isr,
-			       irq_type, dev_name(&spi->dev), lp);
+			       irq_type | IRQF_NO_AUTOEN, dev_name(&spi->dev), lp);
 	if (ret) {
 		dev_err(&spi->dev, "could not request_irq for mcr20a\n");
 		ret = -ENODEV;
 		goto free_dev;
 	}
 
-	/* disable_irq by default and wait for starting hardware */
-	disable_irq(spi->irq);
-
 	ret = ieee802154_register_hw(hw);
 	if (ret) {
 		dev_crit(&spi->dev, "ieee802154_register_hw failed\n");
--- linux-qcom-6.8.0.orig/drivers/net/ipa/ipa_smp2p.c
+++ linux-qcom-6.8.0/drivers/net/ipa/ipa_smp2p.c
@@ -92,7 +92,7 @@
 		return;
 
 	dev = &smp2p->ipa->pdev->dev;
-	smp2p->power_on = pm_runtime_get_if_active(dev, true) > 0;
+	smp2p->power_on = pm_runtime_get_if_active(dev) > 0;
 
 	/* Signal whether the IPA power is enabled */
 	mask = BIT(smp2p->enabled_bit);
--- linux-qcom-6.8.0.orig/drivers/net/ipvlan/ipvlan_core.c
+++ linux-qcom-6.8.0/drivers/net/ipvlan/ipvlan_core.c
@@ -439,7 +439,7 @@
 
 	memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
 
-	err = ip_local_out(net, skb->sk, skb);
+	err = ip_local_out(net, NULL, skb);
 	if (unlikely(net_xmit_eval(err)))
 		DEV_STATS_INC(dev, tx_errors);
 	else
@@ -494,7 +494,7 @@
 
 	memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
 
-	err = ip6_local_out(dev_net(dev), skb->sk, skb);
+	err = ip6_local_out(dev_net(dev), NULL, skb);
 	if (unlikely(net_xmit_eval(err)))
 		DEV_STATS_INC(dev, tx_errors);
 	else
--- linux-qcom-6.8.0.orig/drivers/net/loopback.c
+++ linux-qcom-6.8.0/drivers/net/loopback.c
@@ -144,6 +144,7 @@
 	dev->lstats = netdev_alloc_pcpu_stats(struct pcpu_lstats);
 	if (!dev->lstats)
 		return -ENOMEM;
+	netdev_lockdep_set_classes(dev);
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/macsec.c
+++ linux-qcom-6.8.0/drivers/net/macsec.c
@@ -154,19 +154,6 @@
 	return sa;
 }
 
-static struct macsec_rx_sa *macsec_active_rxsa_get(struct macsec_rx_sc *rx_sc)
-{
-	struct macsec_rx_sa *sa = NULL;
-	int an;
-
-	for (an = 0; an < MACSEC_NUM_AN; an++)	{
-		sa = macsec_rxsa_get(rx_sc->sa[an]);
-		if (sa)
-			break;
-	}
-	return sa;
-}
-
 static void free_rx_sc_rcu(struct rcu_head *head)
 {
 	struct macsec_rx_sc *rx_sc = container_of(head, struct macsec_rx_sc, rcu_head);
@@ -999,10 +986,12 @@
 	struct metadata_dst *md_dst;
 	struct macsec_rxh_data *rxd;
 	struct macsec_dev *macsec;
+	bool is_macsec_md_dst;
 
 	rcu_read_lock();
 	rxd = macsec_data_rcu(skb->dev);
 	md_dst = skb_metadata_dst(skb);
+	is_macsec_md_dst = md_dst && md_dst->type == METADATA_MACSEC;
 
 	list_for_each_entry_rcu(macsec, &rxd->secys, secys) {
 		struct sk_buff *nskb;
@@ -1013,14 +1002,42 @@
 		 * the SecTAG, so we have to deduce which port to deliver to.
 		 */
 		if (macsec_is_offloaded(macsec) && netif_running(ndev)) {
-			struct macsec_rx_sc *rx_sc = NULL;
+			const struct macsec_ops *ops;
 
-			if (md_dst && md_dst->type == METADATA_MACSEC)
-				rx_sc = find_rx_sc(&macsec->secy, md_dst->u.macsec_info.sci);
+			ops = macsec_get_ops(macsec, NULL);
 
-			if (md_dst && md_dst->type == METADATA_MACSEC && !rx_sc)
+			if (ops->rx_uses_md_dst && !is_macsec_md_dst)
 				continue;
 
+			if (is_macsec_md_dst) {
+				struct macsec_rx_sc *rx_sc;
+
+				/* All drivers that implement MACsec offload
+				 * support using skb metadata destinations must
+				 * indicate that they do so.
+				 */
+				DEBUG_NET_WARN_ON_ONCE(!ops->rx_uses_md_dst);
+				rx_sc = find_rx_sc(&macsec->secy,
+						   md_dst->u.macsec_info.sci);
+				if (!rx_sc)
+					continue;
+				/* device indicated macsec offload occurred */
+				skb->dev = ndev;
+				skb->pkt_type = PACKET_HOST;
+				eth_skb_pkt_type(skb, ndev);
+				ret = RX_HANDLER_ANOTHER;
+				goto out;
+			}
+
+			/* This datapath is insecure because it is unable to
+			 * enforce isolation of broadcast/multicast traffic and
+			 * unicast traffic with promiscuous mode on the macsec
+			 * netdev. Since the core stack has no mechanism to
+			 * check that the hardware did indeed receive MACsec
+			 * traffic, it is possible that the response handling
+			 * done by the MACsec port was to a plaintext packet.
+			 * This violates the MACsec protocol standard.
+			 */
 			if (ether_addr_equal_64bits(hdr->h_dest,
 						    ndev->dev_addr)) {
 				/* exact match, divert skb to this port */
@@ -1036,14 +1053,10 @@
 					break;
 
 				nskb->dev = ndev;
-				if (ether_addr_equal_64bits(hdr->h_dest,
-							    ndev->broadcast))
-					nskb->pkt_type = PACKET_BROADCAST;
-				else
-					nskb->pkt_type = PACKET_MULTICAST;
+				eth_skb_pkt_type(nskb, ndev);
 
 				__netif_rx(nskb);
-			} else if (rx_sc || ndev->flags & IFF_PROMISC) {
+			} else if (ndev->flags & IFF_PROMISC) {
 				skb->dev = ndev;
 				skb->pkt_type = PACKET_HOST;
 				ret = RX_HANDLER_ANOTHER;
@@ -1182,15 +1195,12 @@
 		/* If validateFrames is Strict or the C bit in the
 		 * SecTAG is set, discard
 		 */
-		struct macsec_rx_sa *active_rx_sa = macsec_active_rxsa_get(rx_sc);
 		if (hdr->tci_an & MACSEC_TCI_C ||
 		    secy->validate_frames == MACSEC_VALIDATE_STRICT) {
 			u64_stats_update_begin(&rxsc_stats->syncp);
 			rxsc_stats->stats.InPktsNotUsingSA++;
 			u64_stats_update_end(&rxsc_stats->syncp);
 			DEV_STATS_INC(secy->netdev, rx_errors);
-			if (active_rx_sa)
-				this_cpu_inc(active_rx_sa->stats->InPktsNotUsingSA);
 			goto drop_nosa;
 		}
 
@@ -1200,8 +1210,6 @@
 		u64_stats_update_begin(&rxsc_stats->syncp);
 		rxsc_stats->stats.InPktsUnusedSA++;
 		u64_stats_update_end(&rxsc_stats->syncp);
-		if (active_rx_sa)
-			this_cpu_inc(active_rx_sa->stats->InPktsUnusedSA);
 		goto deliver;
 	}
 
@@ -3796,8 +3804,7 @@
 {
 	struct macsec_dev *macsec = macsec_priv(dev);
 
-	if (macsec->secy.tx_sc.md_dst)
-		metadata_dst_free(macsec->secy.tx_sc.md_dst);
+	dst_release(&macsec->secy.tx_sc.md_dst->dst);
 	free_percpu(macsec->stats);
 	free_percpu(macsec->secy.tx_sc.stats);
 
--- linux-qcom-6.8.0.orig/drivers/net/mctp/mctp-i2c.c
+++ linux-qcom-6.8.0/drivers/net/mctp/mctp-i2c.c
@@ -547,6 +547,9 @@
 	if (len > MCTP_I2C_MAXMTU)
 		return -EMSGSIZE;
 
+	if (!daddr || !saddr)
+		return -EINVAL;
+
 	lldst = *((u8 *)daddr);
 	llsrc = *((u8 *)saddr);
 
--- linux-qcom-6.8.0.orig/drivers/net/mctp/mctp-i3c.c
+++ linux-qcom-6.8.0/drivers/net/mctp/mctp-i3c.c
@@ -125,6 +125,8 @@
 
 	xfer.data.in = skb_put(skb, mi->mrl);
 
+	/* Make sure netif_rx() is read in the same order as i3c. */
+	mutex_lock(&mi->lock);
 	rc = i3c_device_do_priv_xfers(mi->i3c, &xfer, 1);
 	if (rc < 0)
 		goto err;
@@ -166,8 +168,10 @@
 		stats->rx_dropped++;
 	}
 
+	mutex_unlock(&mi->lock);
 	return 0;
 err:
+	mutex_unlock(&mi->lock);
 	kfree_skb(skb);
 	return rc;
 }
--- linux-qcom-6.8.0.orig/drivers/net/mctp/mctp-serial.c
+++ linux-qcom-6.8.0/drivers/net/mctp/mctp-serial.c
@@ -91,8 +91,8 @@
 	 * will be those non-escaped bytes, and does not include the escaped
 	 * byte.
 	 */
-	for (i = 1; i + dev->txpos + 1 < dev->txlen; i++) {
-		if (needs_escape(dev->txbuf[dev->txpos + i + 1]))
+	for (i = 1; i + dev->txpos < dev->txlen; i++) {
+		if (needs_escape(dev->txbuf[dev->txpos + i]))
 			break;
 	}
 
--- linux-qcom-6.8.0.orig/drivers/net/mdio/fwnode_mdio.c
+++ linux-qcom-6.8.0/drivers/net/mdio/fwnode_mdio.c
@@ -39,6 +39,7 @@
 static struct mii_timestamper *
 fwnode_find_mii_timestamper(struct fwnode_handle *fwnode)
 {
+	struct mii_timestamper *mii_ts;
 	struct of_phandle_args arg;
 	int err;
 
@@ -52,10 +53,16 @@
 	else if (err)
 		return ERR_PTR(err);
 
-	if (arg.args_count != 1)
-		return ERR_PTR(-EINVAL);
+	if (arg.args_count != 1) {
+		mii_ts = ERR_PTR(-EINVAL);
+		goto put_node;
+	}
 
-	return register_mii_timestamper(arg.np, arg.args[0]);
+	mii_ts = register_mii_timestamper(arg.np, arg.args[0]);
+
+put_node:
+	of_node_put(arg.np);
+	return mii_ts;
 }
 
 int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
--- linux-qcom-6.8.0.orig/drivers/net/mdio/mdio-bcm-unimac.c
+++ linux-qcom-6.8.0/drivers/net/mdio/mdio-bcm-unimac.c
@@ -329,6 +329,7 @@
 static const struct of_device_id unimac_mdio_ids[] = {
 	{ .compatible = "brcm,asp-v2.1-mdio", },
 	{ .compatible = "brcm,asp-v2.0-mdio", },
+	{ .compatible = "brcm,bcm6846-mdio", },
 	{ .compatible = "brcm,genet-mdio-v5", },
 	{ .compatible = "brcm,genet-mdio-v4", },
 	{ .compatible = "brcm,genet-mdio-v3", },
--- linux-qcom-6.8.0.orig/drivers/net/mdio/mdio-ipq4019.c
+++ linux-qcom-6.8.0/drivers/net/mdio/mdio-ipq4019.c
@@ -255,8 +255,11 @@
 	/* The platform resource is provided on the chipset IPQ5018 */
 	/* This resource is optional */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	if (res)
+	if (res) {
 		priv->eth_ldo_rdy = devm_ioremap_resource(&pdev->dev, res);
+		if (IS_ERR(priv->eth_ldo_rdy))
+			return PTR_ERR(priv->eth_ldo_rdy);
+	}
 
 	bus->name = "ipq4019_mdio";
 	bus->read = ipq4019_mdio_read_c22;
--- linux-qcom-6.8.0.orig/drivers/net/mhi_ep_net.c
+++ linux-qcom-6.8.0/drivers/net/mhi_ep_net.c
@@ -0,0 +1,332 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * MHI Endpoint Network driver
+ *
+ * Based on drivers/net/mhi_net.c
+ *
+ * Copyright (c) 2023, Linaro Ltd.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ *
+ * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+ */
+
+#include <linux/if_arp.h>
+#include <linux/mhi_ep.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/u64_stats_sync.h>
+
+#define MHI_NET_MIN_MTU		ETH_MIN_MTU
+#define MHI_NET_MAX_MTU		0xffff
+
+struct mhi_ep_net_stats {
+	u64_stats_t rx_packets;
+	u64_stats_t rx_bytes;
+	u64_stats_t rx_errors;
+	u64_stats_t tx_packets;
+	u64_stats_t tx_bytes;
+	u64_stats_t tx_errors;
+	u64_stats_t tx_dropped;
+	struct u64_stats_sync tx_syncp;
+	struct u64_stats_sync rx_syncp;
+};
+
+struct mhi_ep_net_dev {
+	struct mhi_ep_device *mdev;
+	struct net_device *ndev;
+	struct mhi_ep_net_stats stats;
+	struct workqueue_struct *xmit_wq;
+	struct work_struct xmit_work;
+	struct sk_buff_head tx_buffers;
+	spinlock_t tx_lock; /* Lock for protecting tx_buffers */
+	u32 mru;
+};
+
+static void mhi_ep_net_dev_process_queue_packets(struct work_struct *work)
+{
+	struct mhi_ep_net_dev *mhi_ep_netdev = container_of(work,
+			struct mhi_ep_net_dev, xmit_work);
+	struct mhi_ep_device *mdev = mhi_ep_netdev->mdev;
+	struct sk_buff_head q;
+	struct sk_buff *skb;
+	int ret;
+
+	if (mhi_ep_queue_is_empty(mdev, DMA_FROM_DEVICE)) {
+		netif_stop_queue(mhi_ep_netdev->ndev);
+		return;
+	}
+
+	__skb_queue_head_init(&q);
+
+	spin_lock_bh(&mhi_ep_netdev->tx_lock);
+	skb_queue_splice_init(&mhi_ep_netdev->tx_buffers, &q);
+	spin_unlock_bh(&mhi_ep_netdev->tx_lock);
+
+	while ((skb = __skb_dequeue(&q))) {
+		ret = mhi_ep_queue_skb(mdev, skb);
+		if (ret) {
+			kfree_skb(skb);
+			goto exit_drop;
+		}
+
+		u64_stats_update_begin(&mhi_ep_netdev->stats.tx_syncp);
+		u64_stats_inc(&mhi_ep_netdev->stats.tx_packets);
+		u64_stats_add(&mhi_ep_netdev->stats.tx_bytes, skb->len);
+		u64_stats_update_end(&mhi_ep_netdev->stats.tx_syncp);
+
+		/* Check if queue is empty */
+		if (mhi_ep_queue_is_empty(mdev, DMA_FROM_DEVICE)) {
+			netif_stop_queue(mhi_ep_netdev->ndev);
+			break;
+		}
+
+		consume_skb(skb);
+		cond_resched();
+	}
+
+	return;
+
+exit_drop:
+	u64_stats_update_begin(&mhi_ep_netdev->stats.tx_syncp);
+	u64_stats_inc(&mhi_ep_netdev->stats.tx_dropped);
+	u64_stats_update_end(&mhi_ep_netdev->stats.tx_syncp);
+}
+
+static int mhi_ndo_open(struct net_device *ndev)
+{
+	netif_carrier_on(ndev);
+	netif_start_queue(ndev);
+
+	return 0;
+}
+
+static int mhi_ndo_stop(struct net_device *ndev)
+{
+	netif_stop_queue(ndev);
+	netif_carrier_off(ndev);
+
+	return 0;
+}
+
+static netdev_tx_t mhi_ndo_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+	struct mhi_ep_net_dev *mhi_ep_netdev = netdev_priv(ndev);
+
+	spin_lock(&mhi_ep_netdev->tx_lock);
+	skb_queue_tail(&mhi_ep_netdev->tx_buffers, skb);
+	spin_unlock(&mhi_ep_netdev->tx_lock);
+
+	queue_work(mhi_ep_netdev->xmit_wq, &mhi_ep_netdev->xmit_work);
+
+	return NETDEV_TX_OK;
+}
+
+static void mhi_ndo_get_stats64(struct net_device *ndev,
+				struct rtnl_link_stats64 *stats)
+{
+	struct mhi_ep_net_dev *mhi_ep_netdev = netdev_priv(ndev);
+	unsigned int start;
+
+	do {
+		start = u64_stats_fetch_begin(&mhi_ep_netdev->stats.rx_syncp);
+		stats->rx_packets = u64_stats_read(&mhi_ep_netdev->stats.rx_packets);
+		stats->rx_bytes = u64_stats_read(&mhi_ep_netdev->stats.rx_bytes);
+		stats->rx_errors = u64_stats_read(&mhi_ep_netdev->stats.rx_errors);
+	} while (u64_stats_fetch_retry(&mhi_ep_netdev->stats.rx_syncp, start));
+
+	do {
+		start = u64_stats_fetch_begin(&mhi_ep_netdev->stats.tx_syncp);
+		stats->tx_packets = u64_stats_read(&mhi_ep_netdev->stats.tx_packets);
+		stats->tx_bytes = u64_stats_read(&mhi_ep_netdev->stats.tx_bytes);
+		stats->tx_errors = u64_stats_read(&mhi_ep_netdev->stats.tx_errors);
+		stats->tx_dropped = u64_stats_read(&mhi_ep_netdev->stats.tx_dropped);
+	} while (u64_stats_fetch_retry(&mhi_ep_netdev->stats.tx_syncp, start));
+}
+
+static const struct net_device_ops mhi_ep_netdev_ops = {
+	.ndo_open               = mhi_ndo_open,
+	.ndo_stop               = mhi_ndo_stop,
+	.ndo_start_xmit         = mhi_ndo_xmit,
+	.ndo_get_stats64	= mhi_ndo_get_stats64,
+};
+
+static void mhi_ep_net_setup(struct net_device *ndev)
+{
+	ndev->header_ops = NULL;  /* No header */
+	ndev->type = ARPHRD_RAWIP;
+	ndev->hard_header_len = 0;
+	ndev->addr_len = 0;
+	ndev->flags = IFF_POINTOPOINT | IFF_NOARP;
+	ndev->netdev_ops = &mhi_ep_netdev_ops;
+	ndev->mtu = MHI_EP_DEFAULT_MTU;
+	ndev->min_mtu = MHI_NET_MIN_MTU;
+	ndev->max_mtu = MHI_NET_MAX_MTU;
+	ndev->tx_queue_len = 1000;
+}
+
+static void mhi_ep_net_ul_callback(struct mhi_ep_device *mhi_dev,
+				   struct mhi_result *mhi_res)
+{
+	struct mhi_ep_net_dev *mhi_ep_netdev = dev_get_drvdata(&mhi_dev->dev);
+	struct net_device *ndev = mhi_ep_netdev->ndev;
+	struct sk_buff *skb;
+	size_t size;
+
+	size = mhi_ep_netdev->mru ? mhi_ep_netdev->mru : READ_ONCE(ndev->mtu);
+
+	skb = netdev_alloc_skb(ndev, size);
+	if (unlikely(!skb)) {
+		u64_stats_update_begin(&mhi_ep_netdev->stats.rx_syncp);
+		u64_stats_inc(&mhi_ep_netdev->stats.rx_errors);
+		u64_stats_update_end(&mhi_ep_netdev->stats.rx_syncp);
+		return;
+	}
+
+	skb_copy_to_linear_data(skb, mhi_res->buf_addr, mhi_res->bytes_xferd);
+	skb->len = mhi_res->bytes_xferd;
+	skb->dev = mhi_ep_netdev->ndev;
+
+	if (unlikely(mhi_res->transaction_status)) {
+		switch (mhi_res->transaction_status) {
+		case -ENOTCONN:
+			/* MHI layer stopping/resetting the UL channel */
+			dev_kfree_skb_any(skb);
+			return;
+		default:
+			/* Unknown error, simply drop */
+			dev_kfree_skb_any(skb);
+			u64_stats_update_begin(&mhi_ep_netdev->stats.rx_syncp);
+			u64_stats_inc(&mhi_ep_netdev->stats.rx_errors);
+			u64_stats_update_end(&mhi_ep_netdev->stats.rx_syncp);
+		}
+	} else {
+		skb_put(skb, mhi_res->bytes_xferd);
+
+		switch (skb->data[0] & 0xf0) {
+		case 0x40:
+			skb->protocol = htons(ETH_P_IP);
+			break;
+		case 0x60:
+			skb->protocol = htons(ETH_P_IPV6);
+			break;
+		default:
+			skb->protocol = htons(ETH_P_MAP);
+			break;
+		}
+
+		u64_stats_update_begin(&mhi_ep_netdev->stats.rx_syncp);
+		u64_stats_inc(&mhi_ep_netdev->stats.rx_packets);
+		u64_stats_add(&mhi_ep_netdev->stats.rx_bytes, skb->len);
+		u64_stats_update_end(&mhi_ep_netdev->stats.rx_syncp);
+		netif_rx(skb);
+	}
+}
+
+static void mhi_ep_net_dl_callback(struct mhi_ep_device *mhi_dev,
+				   struct mhi_result *mhi_res)
+{
+	struct mhi_ep_net_dev *mhi_ep_netdev = dev_get_drvdata(&mhi_dev->dev);
+
+	if (unlikely(mhi_res->transaction_status == -ENOTCONN))
+		return;
+
+	/* Since we got enough buffers to queue, wake the queue if stopped */
+	if (netif_queue_stopped(mhi_ep_netdev->ndev)) {
+		netif_wake_queue(mhi_ep_netdev->ndev);
+		queue_work(mhi_ep_netdev->xmit_wq, &mhi_ep_netdev->xmit_work);
+	}
+}
+
+static int mhi_ep_net_newlink(struct mhi_ep_device *mhi_dev, struct net_device *ndev)
+{
+	struct mhi_ep_net_dev *mhi_ep_netdev;
+	int ret;
+
+	mhi_ep_netdev = netdev_priv(ndev);
+
+	dev_set_drvdata(&mhi_dev->dev, mhi_ep_netdev);
+	mhi_ep_netdev->ndev = ndev;
+	mhi_ep_netdev->mdev = mhi_dev;
+	mhi_ep_netdev->mru = mhi_dev->mhi_cntrl->mru;
+
+	skb_queue_head_init(&mhi_ep_netdev->tx_buffers);
+	spin_lock_init(&mhi_ep_netdev->tx_lock);
+
+	u64_stats_init(&mhi_ep_netdev->stats.rx_syncp);
+	u64_stats_init(&mhi_ep_netdev->stats.tx_syncp);
+
+	mhi_ep_netdev->xmit_wq = alloc_workqueue("mhi_ep_net_xmit_wq", 0, WQ_HIGHPRI);
+	INIT_WORK(&mhi_ep_netdev->xmit_work, mhi_ep_net_dev_process_queue_packets);
+
+	ret = register_netdev(ndev);
+	if (ret) {
+		destroy_workqueue(mhi_ep_netdev->xmit_wq);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void mhi_ep_net_dellink(struct mhi_ep_device *mhi_dev, struct net_device *ndev)
+{
+	struct mhi_ep_net_dev *mhi_ep_netdev = netdev_priv(ndev);
+
+	destroy_workqueue(mhi_ep_netdev->xmit_wq);
+	unregister_netdev(ndev);
+	free_netdev(ndev);
+	dev_set_drvdata(&mhi_dev->dev, NULL);
+}
+
+static int mhi_ep_net_probe(struct mhi_ep_device *mhi_dev, const struct mhi_device_id *id)
+{
+	struct net_device *ndev;
+	int ret;
+
+	ndev = alloc_netdev(sizeof(struct mhi_ep_net_dev), (const char *)id->driver_data,
+			    NET_NAME_PREDICTABLE, mhi_ep_net_setup);
+	if (!ndev)
+		return -ENOMEM;
+
+	SET_NETDEV_DEV(ndev, &mhi_dev->dev);
+
+	ret = mhi_ep_net_newlink(mhi_dev, ndev);
+	if (ret) {
+		free_netdev(ndev);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void mhi_ep_net_remove(struct mhi_ep_device *mhi_dev)
+{
+	struct mhi_ep_net_dev *mhi_ep_netdev = dev_get_drvdata(&mhi_dev->dev);
+
+	mhi_ep_net_dellink(mhi_dev, mhi_ep_netdev->ndev);
+}
+
+static const struct mhi_device_id mhi_ep_net_id_table[] = {
+	/* Software data PATH (from endpoint CPU) */
+	{ .chan = "IP_SW0", .driver_data = (kernel_ulong_t)"mhi_swip%d" },
+	{}
+};
+MODULE_DEVICE_TABLE(mhi, mhi_ep_net_id_table);
+
+static struct mhi_ep_driver mhi_ep_net_driver = {
+	.probe = mhi_ep_net_probe,
+	.remove = mhi_ep_net_remove,
+	.dl_xfer_cb = mhi_ep_net_dl_callback,
+	.ul_xfer_cb = mhi_ep_net_ul_callback,
+	.id_table = mhi_ep_net_id_table,
+	.driver = {
+		.name = "mhi_ep_net",
+		.owner = THIS_MODULE,
+	},
+};
+
+module_mhi_ep_driver(mhi_ep_net_driver);
+
+MODULE_DESCRIPTION("MHI Endpoint Network driver");
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/net/netconsole.c
+++ linux-qcom-6.8.0/drivers/net/netconsole.c
@@ -763,6 +763,7 @@
 				/* rtnl_lock already held
 				 * we might sleep in __netpoll_cleanup()
 				 */
+				nt->enabled = false;
 				spin_unlock_irqrestore(&target_list_lock, flags);
 
 				__netpoll_cleanup(&nt->np);
@@ -770,7 +771,6 @@
 				spin_lock_irqsave(&target_list_lock, flags);
 				netdev_put(nt->np.dev, &nt->np.dev_tracker);
 				nt->np.dev = NULL;
-				nt->enabled = false;
 				stopped = true;
 				netconsole_target_put(nt);
 				goto restart;
--- linux-qcom-6.8.0.orig/drivers/net/netdevsim/dev.c
+++ linux-qcom-6.8.0/drivers/net/netdevsim/dev.c
@@ -836,7 +836,8 @@
 	nsim_dev = nsim_trap_data->nsim_dev;
 
 	if (!devl_trylock(priv_to_devlink(nsim_dev))) {
-		schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, 1);
+		queue_delayed_work(system_unbound_wq,
+				   &nsim_dev->trap_data->trap_report_dw, 1);
 		return;
 	}
 
@@ -848,11 +849,12 @@
 			continue;
 
 		nsim_dev_trap_report(nsim_dev_port);
+		cond_resched();
 	}
 	devl_unlock(priv_to_devlink(nsim_dev));
-
-	schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw,
-			      msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS));
+	queue_delayed_work(system_unbound_wq,
+			   &nsim_dev->trap_data->trap_report_dw,
+			   msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS));
 }
 
 static int nsim_dev_traps_init(struct devlink *devlink)
@@ -907,8 +909,9 @@
 
 	INIT_DELAYED_WORK(&nsim_dev->trap_data->trap_report_dw,
 			  nsim_dev_trap_report_work);
-	schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw,
-			      msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS));
+	queue_delayed_work(system_unbound_wq,
+			   &nsim_dev->trap_data->trap_report_dw,
+			   msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS));
 
 	return 0;
 
--- linux-qcom-6.8.0.orig/drivers/net/netdevsim/fib.c
+++ linux-qcom-6.8.0/drivers/net/netdevsim/fib.c
@@ -1377,10 +1377,12 @@
 
 	if (pos != 0)
 		return -EINVAL;
-	if (size > sizeof(buf))
+	if (size > sizeof(buf) - 1)
 		return -EINVAL;
 	if (copy_from_user(buf, user_buf, size))
 		return -EFAULT;
+	buf[size] = 0;
+
 	if (sscanf(buf, "%u %hu", &nhid, &bucket_index) != 2)
 		return -EINVAL;
 
--- linux-qcom-6.8.0.orig/drivers/net/netdevsim/health.c
+++ linux-qcom-6.8.0/drivers/net/netdevsim/health.c
@@ -149,6 +149,8 @@
 	char *break_msg;
 	int err;
 
+	if (count == 0 || count > PAGE_SIZE)
+		return -EINVAL;
 	break_msg = memdup_user_nul(data, count);
 	if (IS_ERR(break_msg))
 		return PTR_ERR(break_msg);
--- linux-qcom-6.8.0.orig/drivers/net/netdevsim/ipsec.c
+++ linux-qcom-6.8.0/drivers/net/netdevsim/ipsec.c
@@ -176,14 +176,13 @@
 		return ret;
 	}
 
-	if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) {
+	if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN)
 		sa.rx = true;
 
-		if (xs->props.family == AF_INET6)
-			memcpy(sa.ipaddr, &xs->id.daddr.a6, 16);
-		else
-			memcpy(&sa.ipaddr[3], &xs->id.daddr.a4, 4);
-	}
+	if (xs->props.family == AF_INET6)
+		memcpy(sa.ipaddr, &xs->id.daddr.a6, 16);
+	else
+		memcpy(&sa.ipaddr[3], &xs->id.daddr.a4, 4);
 
 	/* the preparations worked, so save the info */
 	memcpy(&ipsec->sa[sa_idx], &sa, sizeof(sa));
--- linux-qcom-6.8.0.orig/drivers/net/netdevsim/netdevsim.h
+++ linux-qcom-6.8.0/drivers/net/netdevsim/netdevsim.h
@@ -121,6 +121,7 @@
 		u32 sleep;
 		u32 __ports[2][NSIM_UDP_TUNNEL_N_PORTS];
 		u32 (*ports)[NSIM_UDP_TUNNEL_N_PORTS];
+		struct dentry *ddir;
 		struct debugfs_u32_array dfs_ports[2];
 	} udp_ports;
 
--- linux-qcom-6.8.0.orig/drivers/net/netdevsim/udp_tunnels.c
+++ linux-qcom-6.8.0/drivers/net/netdevsim/udp_tunnels.c
@@ -112,9 +112,11 @@
 	struct net_device *dev = file->private_data;
 	struct netdevsim *ns = netdev_priv(dev);
 
-	memset(ns->udp_ports.ports, 0, sizeof(ns->udp_ports.__ports));
 	rtnl_lock();
-	udp_tunnel_nic_reset_ntf(dev);
+	if (dev->reg_state == NETREG_REGISTERED) {
+		memset(ns->udp_ports.ports, 0, sizeof(ns->udp_ports.__ports));
+		udp_tunnel_nic_reset_ntf(dev);
+	}
 	rtnl_unlock();
 
 	return count;
@@ -144,23 +146,23 @@
 	else
 		ns->udp_ports.ports = nsim_dev->udp_ports.__ports;
 
-	debugfs_create_u32("udp_ports_inject_error", 0600,
-			   ns->nsim_dev_port->ddir,
+	ns->udp_ports.ddir = debugfs_create_dir("udp_ports",
+						ns->nsim_dev_port->ddir);
+
+	debugfs_create_u32("inject_error", 0600, ns->udp_ports.ddir,
 			   &ns->udp_ports.inject_error);
 
 	ns->udp_ports.dfs_ports[0].array = ns->udp_ports.ports[0];
 	ns->udp_ports.dfs_ports[0].n_elements = NSIM_UDP_TUNNEL_N_PORTS;
-	debugfs_create_u32_array("udp_ports_table0", 0400,
-				 ns->nsim_dev_port->ddir,
+	debugfs_create_u32_array("table0", 0400, ns->udp_ports.ddir,
 				 &ns->udp_ports.dfs_ports[0]);
 
 	ns->udp_ports.dfs_ports[1].array = ns->udp_ports.ports[1];
 	ns->udp_ports.dfs_ports[1].n_elements = NSIM_UDP_TUNNEL_N_PORTS;
-	debugfs_create_u32_array("udp_ports_table1", 0400,
-				 ns->nsim_dev_port->ddir,
+	debugfs_create_u32_array("table1", 0400, ns->udp_ports.ddir,
 				 &ns->udp_ports.dfs_ports[1]);
 
-	debugfs_create_file("udp_ports_reset", 0200, ns->nsim_dev_port->ddir,
+	debugfs_create_file("reset", 0200, ns->udp_ports.ddir,
 			    dev, &nsim_udp_tunnels_info_reset_fops);
 
 	/* Note: it's not normal to allocate the info struct like this!
@@ -196,6 +198,9 @@
 
 void nsim_udp_tunnels_info_destroy(struct net_device *dev)
 {
+	struct netdevsim *ns = netdev_priv(dev);
+
+	debugfs_remove_recursive(ns->udp_ports.ddir);
 	kfree(dev->udp_tunnel_nic_info);
 	dev->udp_tunnel_nic_info = NULL;
 }
--- linux-qcom-6.8.0.orig/drivers/net/netkit.c
+++ linux-qcom-6.8.0/drivers/net/netkit.c
@@ -20,6 +20,7 @@
 	struct net_device __rcu *peer;
 	struct bpf_mprog_entry __rcu *active;
 	enum netkit_action policy;
+	enum netkit_scrub scrub;
 	struct bpf_mprog_bundle	bundle;
 
 	/* Needed in slow-path */
@@ -50,11 +51,24 @@
 	return ret;
 }
 
-static void netkit_prep_forward(struct sk_buff *skb, bool xnet)
+static void netkit_xnet(struct sk_buff *skb)
 {
-	skb_scrub_packet(skb, xnet);
 	skb->priority = 0;
+	skb->mark = 0;
+}
+
+static void netkit_prep_forward(struct sk_buff *skb,
+				bool xnet, bool xnet_scrub)
+{
+	skb_scrub_packet(skb, false);
 	nf_skip_egress(skb, true);
+	skb_reset_mac_header(skb);
+	if (!xnet)
+		return;
+	ipvs_reset(skb);
+	skb_clear_tstamp(skb);
+	if (xnet_scrub)
+		netkit_xnet(skb);
 }
 
 static struct netkit *netkit_priv(const struct net_device *dev)
@@ -77,7 +91,9 @@
 		     !pskb_may_pull(skb, ETH_HLEN) ||
 		     skb_orphan_frags(skb, GFP_ATOMIC)))
 		goto drop;
-	netkit_prep_forward(skb, !net_eq(dev_net(dev), dev_net(peer)));
+	netkit_prep_forward(skb, !net_eq(dev_net(dev), dev_net(peer)),
+			    nk->scrub);
+	eth_skb_pkt_type(skb, peer);
 	skb->dev = peer;
 	entry = rcu_dereference(nk->active);
 	if (entry)
@@ -85,7 +101,7 @@
 	switch (ret) {
 	case NETKIT_NEXT:
 	case NETKIT_PASS:
-		skb->protocol = eth_type_trans(skb, skb->dev);
+		eth_skb_pull_mac(skb);
 		skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
 		if (likely(__netif_rx(skb) == NET_RX_SUCCESS)) {
 			dev_sw_netstats_tx_add(dev, 1, len);
@@ -155,6 +171,16 @@
 	/* Nothing to do, we receive whatever gets pushed to us! */
 }
 
+static int netkit_set_macaddr(struct net_device *dev, void *sa)
+{
+	struct netkit *nk = netkit_priv(dev);
+
+	if (nk->mode != NETKIT_L2)
+		return -EOPNOTSUPP;
+
+	return eth_mac_addr(dev, sa);
+}
+
 static void netkit_set_headroom(struct net_device *dev, int headroom)
 {
 	struct netkit *nk = netkit_priv(dev), *nk2;
@@ -198,6 +224,7 @@
 	.ndo_start_xmit		= netkit_xmit,
 	.ndo_set_rx_mode	= netkit_set_multicast,
 	.ndo_set_rx_headroom	= netkit_set_headroom,
+	.ndo_set_mac_address	= netkit_set_macaddr,
 	.ndo_get_iflink		= netkit_get_iflink,
 	.ndo_get_peer_dev	= netkit_peer_dev,
 	.ndo_get_stats64	= netkit_get_stats,
@@ -300,9 +327,11 @@
 
 	if (!attr)
 		return 0;
-	NL_SET_ERR_MSG_ATTR(extack, attr,
-			    "Setting Ethernet address is not supported");
-	return -EOPNOTSUPP;
+	if (nla_len(attr) != ETH_ALEN)
+		return -EINVAL;
+	if (!is_valid_ether_addr(nla_data(attr)))
+		return -EADDRNOTAVAIL;
+	return 0;
 }
 
 static struct rtnl_link_ops netkit_link_ops;
@@ -312,8 +341,10 @@
 			   struct netlink_ext_ack *extack)
 {
 	struct nlattr *peer_tb[IFLA_MAX + 1], **tbp = tb, *attr;
-	enum netkit_action default_prim = NETKIT_PASS;
-	enum netkit_action default_peer = NETKIT_PASS;
+	enum netkit_action policy_prim = NETKIT_PASS;
+	enum netkit_action policy_peer = NETKIT_PASS;
+	enum netkit_scrub scrub_prim = NETKIT_SCRUB_DEFAULT;
+	enum netkit_scrub scrub_peer = NETKIT_SCRUB_DEFAULT;
 	enum netkit_mode mode = NETKIT_L3;
 	unsigned char ifname_assign_type;
 	struct ifinfomsg *ifmp = NULL;
@@ -342,17 +373,21 @@
 				return err;
 			tbp = peer_tb;
 		}
+		if (data[IFLA_NETKIT_SCRUB])
+			scrub_prim = nla_get_u32(data[IFLA_NETKIT_SCRUB]);
+		if (data[IFLA_NETKIT_PEER_SCRUB])
+			scrub_peer = nla_get_u32(data[IFLA_NETKIT_PEER_SCRUB]);
 		if (data[IFLA_NETKIT_POLICY]) {
 			attr = data[IFLA_NETKIT_POLICY];
-			default_prim = nla_get_u32(attr);
-			err = netkit_check_policy(default_prim, attr, extack);
+			policy_prim = nla_get_u32(attr);
+			err = netkit_check_policy(policy_prim, attr, extack);
 			if (err < 0)
 				return err;
 		}
 		if (data[IFLA_NETKIT_PEER_POLICY]) {
 			attr = data[IFLA_NETKIT_PEER_POLICY];
-			default_peer = nla_get_u32(attr);
-			err = netkit_check_policy(default_peer, attr, extack);
+			policy_peer = nla_get_u32(attr);
+			err = netkit_check_policy(policy_peer, attr, extack);
 			if (err < 0)
 				return err;
 		}
@@ -365,6 +400,9 @@
 		strscpy(ifname, "nk%d", IFNAMSIZ);
 		ifname_assign_type = NET_NAME_ENUM;
 	}
+	if (mode != NETKIT_L2 &&
+	    (tb[IFLA_ADDRESS] || tbp[IFLA_ADDRESS]))
+		return -EOPNOTSUPP;
 
 	net = rtnl_link_get_net(src_net, tbp);
 	if (IS_ERR(net))
@@ -379,14 +417,15 @@
 
 	netif_inherit_tso_max(peer, dev);
 
-	if (mode == NETKIT_L2)
+	if (mode == NETKIT_L2 && !(ifmp && tbp[IFLA_ADDRESS]))
 		eth_hw_addr_random(peer);
 	if (ifmp && dev->ifindex)
 		peer->ifindex = ifmp->ifi_index;
 
 	nk = netkit_priv(peer);
 	nk->primary = false;
-	nk->policy = default_peer;
+	nk->policy = policy_peer;
+	nk->scrub = scrub_peer;
 	nk->mode = mode;
 	bpf_mprog_bundle_init(&nk->bundle);
 
@@ -402,7 +441,7 @@
 	if (err < 0)
 		goto err_configure_peer;
 
-	if (mode == NETKIT_L2)
+	if (mode == NETKIT_L2 && !tb[IFLA_ADDRESS])
 		eth_hw_addr_random(dev);
 	if (tb[IFLA_IFNAME])
 		nla_strscpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ);
@@ -411,7 +450,8 @@
 
 	nk = netkit_priv(dev);
 	nk->primary = true;
-	nk->policy = default_prim;
+	nk->policy = policy_prim;
+	nk->scrub = scrub_prim;
 	nk->mode = mode;
 	bpf_mprog_bundle_init(&nk->bundle);
 
@@ -851,6 +891,18 @@
 		return -EACCES;
 	}
 
+	if (data[IFLA_NETKIT_SCRUB]) {
+		NL_SET_ERR_MSG_ATTR(extack, data[IFLA_NETKIT_SCRUB],
+				    "netkit scrubbing cannot be changed after device creation");
+		return -EACCES;
+	}
+
+	if (data[IFLA_NETKIT_PEER_SCRUB]) {
+		NL_SET_ERR_MSG_ATTR(extack, data[IFLA_NETKIT_PEER_SCRUB],
+				    "netkit scrubbing cannot be changed after device creation");
+		return -EACCES;
+	}
+
 	if (data[IFLA_NETKIT_PEER_INFO]) {
 		NL_SET_ERR_MSG_ATTR(extack, data[IFLA_NETKIT_PEER_INFO],
 				    "netkit peer info cannot be changed after device creation");
@@ -885,8 +937,10 @@
 {
 	return nla_total_size(sizeof(u32)) + /* IFLA_NETKIT_POLICY */
 	       nla_total_size(sizeof(u32)) + /* IFLA_NETKIT_PEER_POLICY */
-	       nla_total_size(sizeof(u8))  + /* IFLA_NETKIT_PRIMARY */
+	       nla_total_size(sizeof(u32)) + /* IFLA_NETKIT_SCRUB */
+	       nla_total_size(sizeof(u32)) + /* IFLA_NETKIT_PEER_SCRUB */
 	       nla_total_size(sizeof(u32)) + /* IFLA_NETKIT_MODE */
+	       nla_total_size(sizeof(u8))  + /* IFLA_NETKIT_PRIMARY */
 	       0;
 }
 
@@ -901,11 +955,15 @@
 		return -EMSGSIZE;
 	if (nla_put_u32(skb, IFLA_NETKIT_MODE, nk->mode))
 		return -EMSGSIZE;
+	if (nla_put_u32(skb, IFLA_NETKIT_SCRUB, nk->scrub))
+		return -EMSGSIZE;
 
 	if (peer) {
 		nk = netkit_priv(peer);
 		if (nla_put_u32(skb, IFLA_NETKIT_PEER_POLICY, nk->policy))
 			return -EMSGSIZE;
+		if (nla_put_u32(skb, IFLA_NETKIT_PEER_SCRUB, nk->scrub))
+			return -EMSGSIZE;
 	}
 
 	return 0;
@@ -913,9 +971,11 @@
 
 static const struct nla_policy netkit_policy[IFLA_NETKIT_MAX + 1] = {
 	[IFLA_NETKIT_PEER_INFO]		= { .len = sizeof(struct ifinfomsg) },
-	[IFLA_NETKIT_POLICY]		= { .type = NLA_U32 },
 	[IFLA_NETKIT_MODE]		= { .type = NLA_U32 },
+	[IFLA_NETKIT_POLICY]		= { .type = NLA_U32 },
 	[IFLA_NETKIT_PEER_POLICY]	= { .type = NLA_U32 },
+	[IFLA_NETKIT_SCRUB]		= NLA_POLICY_MAX(NLA_U32, NETKIT_SCRUB_DEFAULT),
+	[IFLA_NETKIT_PEER_SCRUB]	= NLA_POLICY_MAX(NLA_U32, NETKIT_SCRUB_DEFAULT),
 	[IFLA_NETKIT_PRIMARY]		= { .type = NLA_REJECT,
 					    .reject_message = "Primary attribute is read-only" },
 };
--- linux-qcom-6.8.0.orig/drivers/net/ntb_netdev.c
+++ linux-qcom-6.8.0/drivers/net/ntb_netdev.c
@@ -119,7 +119,7 @@
 	skb->protocol = eth_type_trans(skb, ndev);
 	skb->ip_summed = CHECKSUM_NONE;
 
-	if (__netif_rx(skb) == NET_RX_DROP) {
+	if (netif_rx(skb) == NET_RX_DROP) {
 		ndev->stats.rx_errors++;
 		ndev->stats.rx_dropped++;
 	} else {
--- linux-qcom-6.8.0.orig/drivers/net/pcs/Makefile
+++ linux-qcom-6.8.0/drivers/net/pcs/Makefile
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 # Makefile for Linux PCS drivers
 
-pcs_xpcs-$(CONFIG_PCS_XPCS)	:= pcs-xpcs.o pcs-xpcs-nxp.o pcs-xpcs-wx.o
+pcs_xpcs-$(CONFIG_PCS_XPCS)	:= pcs-xpcs.o pcs-xpcs-nxp.o pcs-xpcs-wx.o pcs-xpcs-qcom.o
 
 obj-$(CONFIG_PCS_XPCS)		+= pcs_xpcs.o
 obj-$(CONFIG_PCS_LYNX)		+= pcs-lynx.o
--- linux-qcom-6.8.0.orig/drivers/net/pcs/pcs-xpcs-qcom.c
+++ linux-qcom-6.8.0/drivers/net/pcs/pcs-xpcs-qcom.c
@@ -0,0 +1,1065 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Synopsys DesignWare XPCS platform device driver
+ *
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/pcs-xpcs-qcom.h>
+#include <linux/platform_device.h>
+#include <linux/mdio.h>
+#include <linux/phylink.h>
+#include <linux/workqueue.h>
+#include "pcs-xpcs-qcom.h"
+
+#define phylink_pcs_to_xpcs(pl_pcs) \
+	container_of((pl_pcs), struct dw_xpcs_qcom, pcs)
+
+#define DRV_NAME "qcom-xpcs"
+
+#define XPCSINFO(fmt, args...) \
+	pr_info(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+
+#define XPCSERR(fmt, args...) \
+	pr_err(DRV_NAME " %s:%d " fmt, __func__, __LINE__, ## args)
+
+phy_interface_t g_interface;
+static const int xpcs_usxgmii_features[] = {
+	ETHTOOL_LINK_MODE_Pause_BIT,
+	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+	ETHTOOL_LINK_MODE_Autoneg_BIT,
+	ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+	ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+	ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
+	ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+	ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
+	ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+	ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+	ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
+	ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
+	ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
+	__ETHTOOL_LINK_MODE_MASK_NBITS,
+};
+
+static const int xpcs_10gbaser_features[] = {
+	ETHTOOL_LINK_MODE_Pause_BIT,
+	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+	ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
+	ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
+	ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
+	ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
+	__ETHTOOL_LINK_MODE_MASK_NBITS,
+};
+
+static const int xpcs_usx5g_features[] = {
+	ETHTOOL_LINK_MODE_Pause_BIT,
+	ETHTOOL_LINK_MODE_Asym_Pause_BIT,
+	ETHTOOL_LINK_MODE_Autoneg_BIT,
+	ETHTOOL_LINK_MODE_10baseT_Half_BIT,
+	ETHTOOL_LINK_MODE_10baseT_Full_BIT,
+	ETHTOOL_LINK_MODE_100baseT_Half_BIT,
+	ETHTOOL_LINK_MODE_100baseT_Full_BIT,
+	ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
+	ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+	ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+	ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+	__ETHTOOL_LINK_MODE_MASK_NBITS,
+};
+
+static const phy_interface_t xpcs_usxgmii_interfaces[] = {
+	PHY_INTERFACE_MODE_USXGMII,
+};
+
+static const phy_interface_t xpcs_10gbaser_interfaces[] = {
+	PHY_INTERFACE_MODE_10GBASER,
+};
+
+static const phy_interface_t xpcs_usx5g_interfaces[] = {
+	PHY_INTERFACE_MODE_5GBASER,
+};
+
+enum {
+	DW_XPCS_USXGMII,
+	DW_XPCS_10GBASER,
+	DW_XPCS_USX5G,
+	DW_XPCS_INTERFACE_MAX,
+};
+
+struct xpcs_id {
+	u32 id;
+	u32 mask;
+	const struct xpcs_compat *compat;
+};
+
+const struct xpcs_compat *xpcs_find_compat(const struct xpcs_id *id,
+					   phy_interface_t interface)
+{
+	int i, j;
+
+	for (i = 0; i < DW_XPCS_INTERFACE_MAX; i++) {
+		const struct xpcs_compat *compat = &id->compat[i];
+
+		for (j = 0; j < compat->num_interfaces; j++)
+			if (compat->interface[j] == interface)
+				return compat;
+	}
+
+	return NULL;
+}
+
+int qcom_xpcs_get_an_mode(struct dw_xpcs_qcom *qxpcs, phy_interface_t interface)
+{
+	const struct xpcs_compat *compat;
+
+	compat = xpcs_find_compat(qxpcs->id, interface);
+	if (!compat)
+		return -ENODEV;
+
+	return compat->an_mode;
+}
+
+static int qcom_xpcs_read(struct dw_xpcs_qcom *qxpcs, u32 reg)
+{
+	return readl(qxpcs->addr + reg);
+}
+
+static void qcom_xpcs_write(struct dw_xpcs_qcom *qxpcs, u32 reg, u16 val)
+{
+	writel(val, qxpcs->addr + reg);
+}
+
+static int qcom_xpcs_poll_reset(struct dw_xpcs_qcom *qxpcs, unsigned int offset,
+				unsigned int field)
+{
+	unsigned int retries = 32;
+	int ret;
+
+	do {
+		usleep_range(1000, 2000);
+		ret = qcom_xpcs_read(qxpcs, offset);
+		if (ret < 0)
+			return ret;
+	} while (ret & field && --retries);
+
+	return (ret & field) ? -ETIMEDOUT : 0;
+}
+
+static int qcom_xpcs_poll_bit_set(struct dw_xpcs_qcom *qxpcs, unsigned int offset,
+				  unsigned int field)
+{
+	unsigned int retries = 256;
+	int ret;
+
+	do {
+		usleep_range(1000, 2000);
+		ret = qcom_xpcs_read(qxpcs, offset);
+		if (ret & field)
+			return 0;
+	} while (--retries);
+
+	return -ETIMEDOUT;
+}
+
+static int xpcs_soft_reset(struct dw_xpcs_qcom *qxpcs,
+			   const struct xpcs_compat *compat)
+{
+	int ret;
+
+	ret = qcom_xpcs_read(qxpcs, DW_SR_MII_PCS_CTRL1);
+	if (ret < 0)
+		return ret;
+
+	qcom_xpcs_write(qxpcs, DW_SR_MII_PCS_CTRL1, ret | SOFT_RST);
+
+	ret = qcom_xpcs_poll_reset(qxpcs, DW_SR_MII_PCS_CTRL1, SW_RST_BIT_STATUS);
+
+	ret = qcom_xpcs_read(qxpcs, DW_VR_MII_DIG_CTRL1);
+	if (ret < 0)
+		return ret;
+
+	qcom_xpcs_write(qxpcs, DW_VR_MII_DIG_CTRL1, ret | SOFT_RST);
+
+	return qcom_xpcs_poll_reset(qxpcs, DW_VR_MII_DIG_CTRL1, SW_RST_BIT_STATUS);
+}
+
+static int qcom_xpcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
+			      const struct phylink_link_state *state)
+{
+	__ETHTOOL_DECLARE_LINK_MODE_MASK(xpcs_supported);
+	struct dw_xpcs_qcom *qxpcs = phylink_pcs_to_xpcs(pcs);
+	const struct xpcs_compat *compat;
+	int i;
+
+	/* phylink expects us to report all supported modes with
+	 * PHY_INTERFACE_MODE_NA, just don't limit the supported and
+	 * advertising masks and exit.
+	 */
+	if (state->interface == PHY_INTERFACE_MODE_NA)
+		return -EINVAL;
+
+	bitmap_zero(xpcs_supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
+
+	compat = xpcs_find_compat(qxpcs->id, state->interface);
+
+	/* Populate the supported link modes for this
+	 * PHY interface type
+	 */
+	if (compat)
+		for (i = 0; compat->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
+			set_bit(compat->supported[i], xpcs_supported);
+
+	linkmode_and(supported, supported, xpcs_supported);
+	linkmode_and(state->advertising, state->advertising, xpcs_supported);
+
+	return 0;
+}
+
+/* Cannot sleep in interrupt-context, increase retries and remove usleep call. */
+static int qcom_xpcs_poll_reset_usxgmii(struct dw_xpcs_qcom *qxpcs, unsigned int offset,
+					unsigned int field)
+{
+	unsigned int retries = 1000;
+	int ret;
+
+	do {
+		ret = qcom_xpcs_read(qxpcs, offset);
+		if (ret < 0)
+			return ret;
+	} while (ret & field && --retries);
+
+	return (ret & field) ? -ETIMEDOUT : 0;
+}
+
+/* Reset PCS and USXGMII Rate Adaptor Logic*/
+static int qcom_xpcs_reset_usxgmii(struct dw_xpcs_qcom *qxpcs)
+{
+	int ret;
+
+	ret = qcom_xpcs_read(qxpcs, DW_VR_MII_DIG_CTRL1);
+	if (ret < 0)
+		return ret;
+
+	qcom_xpcs_write(qxpcs, DW_VR_MII_DIG_CTRL1, ret | SOFT_RST);
+
+	if (!qxpcs->intr_en)
+		ret = qcom_xpcs_poll_reset(qxpcs, DW_VR_MII_DIG_CTRL1, SW_RST_BIT_STATUS);
+	else
+		ret = qcom_xpcs_poll_reset_usxgmii(qxpcs, DW_VR_MII_DIG_CTRL1, SW_RST_BIT_STATUS);
+
+	if (ret < 0)
+		return ret;
+
+	ret = qcom_xpcs_read(qxpcs, DW_VR_MII_PCS_DIG_CTRL1);
+	if (ret < 0)
+		return ret;
+
+	qcom_xpcs_write(qxpcs, DW_VR_MII_PCS_DIG_CTRL1, ret | DW_USXGMII_RST);
+
+	if (!qxpcs->intr_en) {
+		ret = qcom_xpcs_poll_reset(qxpcs, DW_VR_MII_PCS_DIG_CTRL1, USXG_RST_BIT_STATUS);
+
+		if (ret < 0)
+			return ret;
+
+		switch (qxpcs->phy_interface) {
+		case PHY_INTERFACE_MODE_USXGMII:
+			ret = qcom_xpcs_poll_bit_set(qxpcs,
+						     DW_SR_MII_MMD_STS, DW_SR_MII_STS_LINK_STS);
+			if (ret < 0)
+				return ret;
+			fallthrough;
+		case PHY_INTERFACE_MODE_10GBASER:
+		case PHY_INTERFACE_MODE_5GBASER:
+			ret = qcom_xpcs_poll_bit_set(qxpcs,
+						     DW_SR_MII_PCS_STS1, DW_SR_XS_PCS_STS1);
+			if (ret < 0)
+				return ret;
+		}
+		return ret;
+	}
+
+	return qcom_xpcs_poll_reset_usxgmii(qxpcs, DW_VR_MII_PCS_DIG_CTRL1, USXG_RST_BIT_STATUS);
+}
+
+static int qcom_xpcs_usxgmii_read_intr_status(struct dw_xpcs_qcom *qxpcs)
+{
+	int intr_stat;
+
+	intr_stat = qcom_xpcs_read(qxpcs, DW_VR_MII_AN_INTR_STS);
+	if (intr_stat < 0)
+		return intr_stat;
+
+	if (intr_stat & DW_VR_MII_USXG_ANSGM_SP_LNKSTS) {
+		int mmd_ctrl, speed;
+
+		mmd_ctrl = qcom_xpcs_read(qxpcs, DW_SR_MII_MMD_CTRL);
+		if (mmd_ctrl < 0)
+			return mmd_ctrl;
+
+		mmd_ctrl &= ~DW_USXGMII_SS_MASK;
+		speed = (intr_stat & DW_VR_MII_USXG_ANSGM_SP) >> DW_VR_MII_USXG_ANSGM_SP_SHIFT;
+
+		switch (speed) {
+		case DW_VR_MII_USXG_ANSGM_SP_10G:
+			mmd_ctrl |= DW_USXGMII_10000;
+			XPCSINFO("10Gbps-USXGMII enabled\n");
+			break;
+		case DW_VR_MII_USXG_ANSGM_SP_5G:
+			mmd_ctrl |= DW_USXGMII_5000;
+			XPCSINFO("5Gbps-USXGMII enabled\n");
+			break;
+		case DW_VR_MII_USXG_ANSGM_SP_2P5G:
+			mmd_ctrl |= DW_GMII_2500;
+			XPCSINFO("2.5Gbps-USXGMII enabled\n");
+			break;
+		case DW_VR_MII_USXG_ANSGM_SP_1000:
+			mmd_ctrl |= DW_GMII_1000;
+			XPCSINFO("1Gbps-USXGMII enabled\n");
+			break;
+		case DW_VR_MII_USXG_ANSGM_SP_100:
+			mmd_ctrl |= DW_GMII_100;
+			XPCSINFO("100Mbps-USXGMII enabled\n");
+			break;
+		case DW_VR_MII_USXG_ANSGM_SP_10:
+			XPCSINFO("10Mbps-USXGMII enabled\n");
+			break;
+		default:
+			XPCSERR("Invalid speed mode: %d\n", speed);
+			return -EINVAL;
+		}
+
+		qcom_xpcs_write(qxpcs, DW_SR_MII_MMD_CTRL, mmd_ctrl);
+
+		mmd_ctrl = qcom_xpcs_reset_usxgmii(qxpcs);
+		if (mmd_ctrl < 0)
+			XPCSERR("Failed to reset USXGMII\n");
+
+		return mmd_ctrl;
+	}
+		XPCSERR("Link is down, aborting\n");
+		return 0;
+}
+
+static void qcom_xpcs_handle_an_intr(struct dw_xpcs_qcom *qxpcs,
+				     phy_interface_t interface)
+{
+	int ret = 0;
+
+	switch (interface) {
+	case PHY_INTERFACE_MODE_USXGMII:
+		ret = qcom_xpcs_usxgmii_read_intr_status(qxpcs);
+		if (ret < 0)
+			goto out;
+
+		XPCSINFO("Finished Autonegotiation for USXGMII\n");
+		return;
+	default:
+		XPCSERR("Invalid MII mode for Autonegotiation\n");
+		goto out;
+	}
+
+out:
+	XPCSERR("Failed to handle Autonegotiation interrupt\n");
+}
+
+int qcom_xpcs_check_aneg_ioc(struct dw_xpcs_qcom *qxpcs, phy_interface_t interface)
+{
+	int ret;
+
+	/* Check if interrupt was set */
+	ret = qcom_xpcs_read(qxpcs, DW_VR_MII_AN_INTR_STS);
+	if (ret < 0)
+		return -EINVAL;
+
+	if (!(ret & DW_VR_MII_ANCMPLT_INTR)) {
+		XPCSERR("Autonegotiation is still not finished\n");
+		return -ENODEV;
+	}
+
+	/* Clear the IOC status */
+	ret &= ~DW_VR_MII_ANCMPLT_INTR;
+	qcom_xpcs_write(qxpcs, DW_VR_MII_AN_INTR_STS, ret);
+
+	qcom_xpcs_handle_an_intr(qxpcs, interface);
+	return 0;
+}
+
+/* By default, enable Clause 37 autonegotiation */
+static int xpcs_config_aneg_c37(struct dw_xpcs_qcom *qxpcs)
+{
+	int ret;
+
+	ret = qcom_xpcs_read(qxpcs, DW_SR_MII_MMD_CTRL);
+	if (ret < 0)
+		return -EINVAL;
+
+	ret |= AN_CL37_EN;
+	qcom_xpcs_write(qxpcs, DW_SR_MII_MMD_CTRL, ret);
+
+	ret = qcom_xpcs_read(qxpcs, DW_VR_MII_AN_CTRL);
+	if (ret < 0)
+		return -EINVAL;
+
+	ret |= DW_VR_MII_TX_CONFIG_PHY_SIDE << DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT;
+	ret |= DW_VR_MII_SGMII_LINK_STS;
+
+	qcom_xpcs_write(qxpcs, DW_VR_MII_AN_CTRL, ret);
+
+	return 0;
+}
+
+static int qcom_xpcs_do_config(struct dw_xpcs_qcom *qxpcs, phy_interface_t interface)
+{
+	const struct xpcs_compat *compat;
+	int ret;
+
+	compat = xpcs_find_compat(qxpcs->id, interface);
+	if (!compat)
+		return -ENODEV;
+
+	switch (compat->an_mode) {
+	case DW_AN_C37_USXGMII:
+		qxpcs->needs_aneg = true;
+		ret = xpcs_config_aneg_c37(qxpcs);
+		if (ret < 0)
+			return ret;
+		break;
+	case DW_10GBASER:
+		break;
+	default:
+		XPCSERR("Incompatible Autonegotiation mode\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int qcom_xpcs_config(struct phylink_pcs *pcs, unsigned int mode, phy_interface_t interface,
+			    const unsigned long *advertising,
+			    bool permit_pause_to_mac)
+{
+	struct dw_xpcs_qcom *qxpcs = phylink_pcs_to_xpcs(pcs);
+
+	return qcom_xpcs_do_config(qxpcs, interface);
+}
+
+static int xpcs_get_state_c37_usxgmii(struct dw_xpcs_qcom *qxpcs,
+				      struct phylink_link_state *state)
+{
+	int ret;
+
+	ret = qcom_xpcs_read(qxpcs, DW_VR_MII_AN_INTR_STS);
+	if (ret < 0)
+		return -ENODEV;
+
+	if (ret & DW_VR_MII_USXG_ANSGM_SP_LNKSTS)
+		state->link = true;
+	else
+		state->link = false;
+
+	return 0;
+}
+
+static void qcom_xpcs_get_state(struct phylink_pcs *pcs,
+				struct phylink_link_state *state)
+{
+	struct dw_xpcs_qcom *qxpcs = phylink_pcs_to_xpcs(pcs);
+	const struct xpcs_compat *compat;
+	int ret;
+
+	compat = xpcs_find_compat(qxpcs->id, state->interface);
+	if (!compat)
+		return;
+
+	switch (compat->an_mode) {
+	case DW_AN_C37_USXGMII:
+		ret = xpcs_get_state_c37_usxgmii(qxpcs, state);
+		if (ret < 0)
+			XPCSERR("Failed to get USXGMII state\n");
+		break;
+	default:
+		return;
+	}
+}
+
+irqreturn_t qcom_xpcs_fusa_isr(int irq, void *dev_data)
+{
+	struct dw_xpcs_qcom *qxpcs = (struct dw_xpcs_qcom *)dev_data;
+	int ret, linksts, remotelinksts;
+
+	ret = qcom_xpcs_read(qxpcs, DW_VR_XS_PCS_SFTY_UE_INTR0);
+
+	/* PCS fusa is valid only when link is up */
+	switch (qxpcs->phy_interface) {
+	case PHY_INTERFACE_MODE_USXGMII:
+		remotelinksts = qcom_xpcs_read(qxpcs, DW_SR_MII_MMD_STS);
+		if (!(remotelinksts & DW_SR_MII_STS_LINK_STS))
+			return IRQ_NONE;
+		fallthrough;
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_5GBASER:
+		linksts = qcom_xpcs_read(qxpcs, DW_SR_MII_PCS_STS1);
+		if (!(linksts & DW_SR_XS_PCS_STS1))
+			return IRQ_NONE;
+	}
+
+	if (ret > 0) {
+		pr_debug("Fusa XPCS IRQ %d\n", ret);
+		qxpcs->pcs_fusa_error_count++;
+		qcom_xpcs_write(qxpcs, DW_VR_XS_PCS_SFTY_UE_INTR0, 0x0);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+static int qcom_xpcs_fusa_intr_enable(struct dw_xpcs_qcom *qxpcs)
+{
+	int ret = 0;
+
+	ret = request_irq(qxpcs->pcs_fusa_intr, qcom_xpcs_fusa_isr,
+			  IRQF_SHARED, "xpcs-fusa", qxpcs);
+	if (ret)
+		pr_err("Unable to register XPCS IRQ %d\n",
+		       qxpcs->pcs_fusa_intr);
+
+	return ret;
+}
+
+static void qcom_xpcs_fusa_intr_disable(struct dw_xpcs_qcom *qxpcs)
+{
+	if (qxpcs->pcs_fusa_intr) {
+		free_irq(qxpcs->pcs_fusa_intr, qxpcs);
+		qxpcs->pcs_fusa_error_count = 0x0;
+		qcom_xpcs_write(qxpcs, DW_VR_XS_PCS_SFTY_DISABLE, 0x1);
+	}
+}
+
+static int qcom_xpcs_enable(struct phylink_pcs *pcs)
+{
+	struct dw_xpcs_qcom *qxpcs = phylink_pcs_to_xpcs(pcs);
+	int ret = 0;
+
+	if (qxpcs->pcs_fusa_intr)
+		ret = qcom_xpcs_fusa_intr_enable(qxpcs);
+
+	return ret;
+}
+
+static void qcom_xpcs_disable(struct phylink_pcs *pcs)
+{
+	struct dw_xpcs_qcom *qxpcs = phylink_pcs_to_xpcs(pcs);
+
+	if (qxpcs->pcs_fusa_intr)
+		qcom_xpcs_fusa_intr_disable(qxpcs);
+}
+
+static void qcom_xpcs_loopback(struct dw_xpcs_qcom *qxpcs, bool on)
+{
+	int ret;
+
+	ret = qcom_xpcs_read(qxpcs, DW_VR_MII_PCS_DIG_CTRL1);
+
+	qcom_xpcs_write(qxpcs, DW_VR_MII_PCS_DIG_CTRL1, ret |= DW_USXGMII_EN);
+
+	ret = qcom_xpcs_read(qxpcs, DW_SR_MII_MMD_CTRL);
+	if (on)
+		ret |= DW_LBE;
+	else
+		ret &= ~DW_LBE;
+
+	qcom_xpcs_write(qxpcs, DW_SR_MII_MMD_CTRL, ret);
+}
+
+static int qcom_xpcs_pre_init(struct phylink_pcs *pcs)
+{
+	struct dw_xpcs_qcom *qxpcs = phylink_pcs_to_xpcs(pcs);
+
+	/* Loopback RX clock if MAC requires it */
+	if (pcs->rxc_always_on)
+		qcom_xpcs_loopback(qxpcs, true);
+
+	return 0;
+}
+
+void qcom_xpcs_get_err_stats(struct phylink_pcs *pcs, unsigned long *ptr)
+{
+	struct dw_xpcs_qcom *qxpcs = phylink_pcs_to_xpcs(pcs);
+
+	*ptr = qxpcs->pcs_fusa_error_count;
+}
+EXPORT_SYMBOL_GPL(qcom_xpcs_get_err_stats);
+
+void qcom_xpcs_link_up_usxgmii(struct dw_xpcs_qcom *qxpcs, int speed)
+{
+	int mmd_ctrl;
+	int ret;
+
+	ret = qcom_xpcs_read(qxpcs, DW_VR_MII_PCS_DIG_CTRL1);
+	if (ret < 0)
+		goto read_err;
+
+	qcom_xpcs_write(qxpcs, DW_VR_MII_PCS_DIG_CTRL1, ret | SOFT_RST);
+
+	mmd_ctrl = qcom_xpcs_poll_reset(qxpcs, DW_VR_MII_PCS_DIG_CTRL1,
+					SW_RST_BIT_STATUS);
+	if (mmd_ctrl < 0) {
+		XPCSERR("Failed to perform soft reset\n");
+		return;
+	}
+
+	if (qxpcs->needs_aneg) {
+		ret = qcom_xpcs_read(qxpcs, DW_VR_MII_AN_CTRL);
+		if (ret < 0)
+			goto read_err;
+
+		ret |= DW_VR_MII_TX_CONFIG_PHY_SIDE << DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT;
+		ret |= DW_VR_MII_SGMII_LINK_STS;
+
+		qcom_xpcs_write(qxpcs, DW_VR_MII_AN_CTRL, ret);
+	}
+
+	mmd_ctrl = qcom_xpcs_read(qxpcs, DW_SR_MII_MMD_CTRL);
+	if (mmd_ctrl < 0)
+		goto read_err;
+
+	mmd_ctrl &= ~DW_USXGMII_SS_MASK;
+
+	switch (speed) {
+	case SPEED_10000:
+		mmd_ctrl |= DW_USXGMII_10000;
+		XPCSINFO("10Gbps-USXGMII enabled\n");
+		break;
+	case SPEED_5000:
+		mmd_ctrl |= DW_USXGMII_5000;
+		XPCSINFO("5Gbps-USXGMII enabled\n");
+		break;
+	case SPEED_2500:
+		mmd_ctrl |= DW_GMII_2500;
+		XPCSINFO("2.5Gbps-USXGMII enabled\n");
+		break;
+	case SPEED_1000:
+		mmd_ctrl |= DW_GMII_1000;
+		XPCSINFO("1Gbps-USXGMII enabled\n");
+		break;
+	case SPEED_100:
+		mmd_ctrl |= DW_GMII_100;
+		XPCSINFO("100Mbps-USXGMII enabled\n");
+		break;
+	case SPEED_10:
+		XPCSINFO("10Mbps-USXGMII enabled\n");
+		break;
+	default:
+		XPCSERR("Invalid speed mode selected\n");
+		return;
+	}
+
+	qcom_xpcs_write(qxpcs, DW_SR_MII_MMD_CTRL, mmd_ctrl);
+
+	if (qxpcs->needs_aneg) {
+		ret = qcom_xpcs_read(qxpcs, DW_SR_MII_MMD_CTRL);
+		if (ret < 0)
+			goto read_err;
+
+		qcom_xpcs_write(qxpcs, DW_SR_MII_MMD_CTRL, ret | AN_CL37_EN);
+	}
+
+	mmd_ctrl = qcom_xpcs_reset_usxgmii(qxpcs);
+	if (mmd_ctrl < 0)
+		goto out;
+
+	if (qxpcs->pcs_fusa_intr) {
+		/* enable PCS FUSA only when link is up*/
+		qcom_xpcs_write(qxpcs, DW_VR_XS_PCS_SFTY_DISABLE, 0x0);
+		/* Reset Fusa Error for all Link down/up */
+		qxpcs->pcs_fusa_error_count = 0x0;
+	}
+	XPCSINFO("USXGMII link is up\n");
+	return;
+read_err:
+	XPCSERR("Failed to read register\n");
+out:
+	XPCSERR("Failed to bring up USXGMII link\n");
+}
+
+static int qcom_xpcs_select_mode(struct dw_xpcs_qcom *qxpcs, phy_interface_t interface)
+{
+	int ret;
+
+	g_interface = interface;
+
+	if (interface == PHY_INTERFACE_MODE_USXGMII ||
+	    interface == PHY_INTERFACE_MODE_10GBASER ||
+	    interface == PHY_INTERFACE_MODE_5GBASER) {
+		ret = qcom_xpcs_read(qxpcs, DW_SR_MII_PCS_CTRL2);
+		if (ret < 0)
+			goto out;
+
+		ret &= ~PCS_TYPE_SEL_10GBR;
+		qcom_xpcs_write(qxpcs, DW_SR_MII_PCS_CTRL2, ret);
+
+		ret = qcom_xpcs_read(qxpcs, DW_SR_MII_PCS_CTRL1);
+		if (ret < 0)
+			goto out;
+
+		qcom_xpcs_write(qxpcs, DW_SR_MII_PCS_CTRL1, ret | LPM_EN);
+
+		usleep_range(1, 20);
+
+		ret = qcom_xpcs_read(qxpcs, DW_SR_MII_PCS_CTRL1);
+		if (ret < 0)
+			goto out;
+
+		ret &= ~LPM_EN;
+		qcom_xpcs_write(qxpcs, DW_SR_MII_PCS_CTRL1, ret);
+
+		ret = qcom_xpcs_read(qxpcs, DW_VR_MII_PCS_DIG_CTRL1);
+		if (ret < 0)
+			goto out;
+
+		qcom_xpcs_write(qxpcs, DW_VR_MII_PCS_DIG_CTRL1, ret | DW_USXGMII_EN);
+
+		ret = qcom_xpcs_read(qxpcs, DW_VR_MII_PCS_KR_CTRL);
+		if (ret < 0)
+			goto out;
+
+		ret &= ~USXG_MODE_SEL;
+		if (interface == PHY_INTERFACE_MODE_5GBASER)
+			ret |= USXGMII_5G;
+
+		qcom_xpcs_write(qxpcs, DW_VR_MII_PCS_KR_CTRL, ret);
+
+		return 0;
+	}
+
+	XPCSERR("Incompatible MII interface: %d\n", interface);
+	return -EINVAL;
+
+out:
+	XPCSERR("Register read failed\n");
+	return -EINVAL;
+}
+
+/* USXGMII: Return early if interrupt was enabled.
+ * Autonegotiation ISR will set speed and duplex instead.
+ * SGMII: For 2.5Gbps, let ISR do NOP since SGMII+ not supported in
+ * registers for CL37. qcom_xpcs_link_up_sgmii will take care of
+ * setting 2.5Gbps.
+ */
+void qcom_xpcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
+		       phy_interface_t interface, int speed, int duplex)
+{
+	struct dw_xpcs_qcom *qxpcs = phylink_pcs_to_xpcs(pcs);
+	int ret;
+
+	if (qxpcs->intr_en)
+		return;
+
+	/* Disable Loopback RX clock as we expect the Phy or switch
+	 * to be able to supply the required Rx clock by this time
+	 */
+	qcom_xpcs_loopback(qxpcs, false);
+
+	switch (interface) {
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_5GBASER:
+		ret = qcom_xpcs_read(qxpcs, DW_VR_MII_PCS_DIG_CTRL1);
+		if (ret < 0)
+			goto read_err;
+
+		qcom_xpcs_write(qxpcs, DW_VR_MII_PCS_DIG_CTRL1, ret &= ~DW_USXGMII_EN);
+		fallthrough;
+	case PHY_INTERFACE_MODE_USXGMII:
+		qcom_xpcs_link_up_usxgmii(qxpcs, speed);
+		break;
+	default:
+		XPCSERR("Invalid MII mode: %s\n", phy_modes(interface));
+		return;
+	}
+read_err:
+	XPCSERR("Failed to read register\n");
+}
+EXPORT_SYMBOL_GPL(qcom_xpcs_link_up);
+
+static u32 xpcs_get_id(struct dw_xpcs_qcom *qxpcs)
+{
+	int ret;
+	u32 id;
+
+	/* Next, search C37 PCS using Vendor-Specific MII MMD */
+	ret = qcom_xpcs_read(qxpcs, DW_SR_MII_PCS_DEV_ID1);
+	if (ret < 0)
+		return 0xffffffff;
+
+	id = ret << 16;
+
+	ret = qcom_xpcs_read(qxpcs, DW_SR_MII_PCS_DEV_ID2);
+	if (ret < 0)
+		return 0xffffffff;
+
+	/* If Device IDs are not all zeros, we found C37 AN-type device */
+	if (id | ret)
+		return id | ret;
+
+	return 0xffffffff;
+}
+
+static const struct xpcs_compat synopsys_xpcs_compat[DW_XPCS_INTERFACE_MAX] = {
+	[DW_XPCS_USXGMII] = {
+		.supported = xpcs_usxgmii_features,
+		.interface = xpcs_usxgmii_interfaces,
+		.num_interfaces = ARRAY_SIZE(xpcs_usxgmii_interfaces),
+		.an_mode = DW_AN_C37_USXGMII,
+	},
+	[DW_XPCS_10GBASER] = {
+		.supported = xpcs_10gbaser_features,
+		.interface = xpcs_10gbaser_interfaces,
+		.num_interfaces = ARRAY_SIZE(xpcs_10gbaser_interfaces),
+		.an_mode = DW_10GBASER,
+	},
+	[DW_XPCS_USX5G] = {
+		.supported = xpcs_usx5g_features,
+		.interface = xpcs_usx5g_interfaces,
+		.num_interfaces = ARRAY_SIZE(xpcs_usx5g_interfaces),
+		.an_mode = DW_10GBASER,
+	},
+};
+
+static const struct xpcs_id xpcs_id_list[] = {
+	{
+		.id = SYNOPSYS_XPCS_ID,
+		.mask = SYNOPSYS_XPCS_MASK,
+		.compat = synopsys_xpcs_compat,
+	},
+};
+
+static const struct phylink_pcs_ops qcom_xpcs_phylink_ops = {
+	.pcs_validate = qcom_xpcs_validate,
+	.pcs_config = qcom_xpcs_config,
+	.pcs_get_state = qcom_xpcs_get_state,
+	.pcs_enable = qcom_xpcs_enable,
+	.pcs_disable = qcom_xpcs_disable,
+	.pcs_pre_init = qcom_xpcs_pre_init,
+};
+
+struct phylink_pcs *qcom_xpcs_create(struct device_node *np, phy_interface_t interface)
+{
+	const struct xpcs_compat *compat;
+	struct platform_device *pdev;
+	struct dw_xpcs_qcom *qxpcs;
+	u32 xpcs_id;
+	int i, ret = 0;
+
+	pdev = of_find_device_by_node(np);
+	of_node_put(np);
+
+	if (!pdev || !platform_get_drvdata(pdev)) {
+		if (pdev)
+			put_device(&pdev->dev);
+
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	qxpcs = platform_get_drvdata(pdev);
+
+	qxpcs->phy_interface = interface;
+
+	xpcs_id = xpcs_get_id(qxpcs);
+	if (xpcs_id == 0xffffffff) {
+		XPCSERR("Invalid qxpcs Device ID\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(xpcs_id_list); i++) {
+		const struct xpcs_id *entry = &xpcs_id_list[i];
+
+		if ((xpcs_id & entry->mask) != entry->id)
+			continue;
+
+		qxpcs->id = entry;
+		compat = xpcs_find_compat(entry, interface);
+		if (!compat) {
+			XPCSERR("Incompatible MII interface: %d\n", interface);
+			ret = -ENODEV;
+			goto out;
+		}
+
+		qxpcs->pcs.ops = &qcom_xpcs_phylink_ops;
+		qxpcs->pcs.poll = true;
+
+		ret = xpcs_soft_reset(qxpcs, compat);
+		if (ret) {
+			XPCSERR("Soft reset of XPCS block failed\n");
+			goto out;
+		}
+
+		/* Select PCS mode before further configuration */
+		ret = qcom_xpcs_select_mode(qxpcs, interface);
+		if (ret < 0)
+			goto out;
+
+		/* Loopback RX clock from the get go to be able to
+		 * support the needs of the MAC HW
+		 */
+		qcom_xpcs_loopback(qxpcs, true);
+
+		return &qxpcs->pcs;
+	}
+
+out:
+	XPCSERR("qxpcs creation failed\n");
+	kfree(qxpcs);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(qcom_xpcs_create);
+
+/* Power off the DWC_xpcs controller */
+void qcom_xpcs_destroy(struct phylink_pcs *pcs)
+{
+	int i, ret;
+	u32 xpcs_id;
+	const struct xpcs_compat *compat;
+	struct dw_xpcs_qcom *qxpcs = phylink_pcs_to_xpcs(pcs);
+
+	xpcs_id = xpcs_get_id(qxpcs);
+	if (xpcs_id == 0xffffffff) {
+		XPCSERR("Invalid XPCS Device ID\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(xpcs_id_list); i++) {
+		const struct xpcs_id *entry = &xpcs_id_list[i];
+
+		if ((xpcs_id & entry->mask) != entry->id)
+			continue;
+
+		qxpcs->id = entry;
+		compat = xpcs_find_compat(entry, g_interface);
+		if (!compat) {
+			XPCSERR("Incompatible MII interface: %d\n", g_interface);
+			ret = -ENODEV;
+			goto out;
+		}
+
+		ret = xpcs_soft_reset(qxpcs, compat);
+		if (ret) {
+			XPCSERR("Soft reset of XPCS block failed\n");
+			ret = -ENODEV;
+		}
+		goto done;
+	}
+
+	/* Enable xpc_spdown_o signal assertion on xpcs power down, then
+	 * intiate the power down sequence
+	 */
+	ret = qcom_xpcs_read(qxpcs, DW_SR_MII_VSMMD_CTRL);
+	if (ret < 0)
+		goto out;
+
+	qcom_xpcs_write(qxpcs, DW_SR_MII_VSMMD_CTRL, ret & ~PD_CTRL);
+
+	ret = qcom_xpcs_read(qxpcs, DW_SR_MII_PCS_CTRL1);
+	if (ret < 0)
+		goto out;
+
+	qcom_xpcs_write(qxpcs, DW_SR_MII_PCS_CTRL1, ret | LPM_EN);
+	goto done;
+
+out:
+	XPCSERR("Could not power down the XPCS\n");
+done:
+	kfree(qxpcs);
+}
+EXPORT_SYMBOL_GPL(qcom_xpcs_destroy);
+
+irqreturn_t qcom_xpcs_isr(int irq, void *dev_data)
+{
+	int ret;
+	struct dw_xpcs_qcom *qxpcs = (struct dw_xpcs_qcom *)dev_data;
+
+	ret = qcom_xpcs_check_aneg_ioc(qxpcs, qxpcs->phy_interface);
+	if (ret < 0)
+		return IRQ_HANDLED;
+
+	return IRQ_HANDLED;
+}
+
+int qcom_xpcs_intr_enable(struct dw_xpcs_qcom *qxpcs)
+{
+	int ret = 0;
+
+	ret = qcom_xpcs_read(qxpcs, DW_VR_MII_AN_CTRL);
+	if (ret < 0) {
+		XPCSERR("Failed to enable CL37 interrupts\n");
+		return ret;
+	}
+
+	ret |= DW_VR_MII_AN_INTR_EN;
+
+	qcom_xpcs_write(qxpcs, DW_VR_MII_AN_CTRL, ret);
+
+	ret = request_irq(qxpcs->pcs_intr, qcom_xpcs_isr,
+			  IRQF_SHARED, "qcom-xpcs", qxpcs);
+	if (ret)
+		pr_err("Unable to register XPCS IRQ %d\n",
+		       qxpcs->pcs_intr);
+
+	return ret;
+}
+
+static int qcom_xpcs_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct dw_xpcs_qcom *qxpcs;
+
+	qxpcs = kzalloc(sizeof(*qxpcs), GFP_KERNEL);
+	if (!qxpcs)
+		return ERR_PTR(-ENOMEM);
+
+	qxpcs->addr = devm_platform_ioremap_resource_byname(pdev, "qxpcs");
+	if (IS_ERR_OR_NULL(qxpcs->addr)) {
+		pr_err("XPCS not supported from device tree!\n");
+		kfree(qxpcs);
+		return -ENODEV;
+	}
+
+	qxpcs->pcs_intr = platform_get_irq_byname_optional(pdev, "pcs_intr");
+	if (qxpcs->pcs_intr < 0) {
+		pr_info("XPCS IRQ is not enabled\n");
+	} else {
+		ret = qcom_xpcs_intr_enable(qxpcs);
+		if (ret)
+			qxpcs->intr_en = false;
+		else
+			qxpcs->intr_en = true;
+	}
+
+	qxpcs->pcs_fusa_intr = platform_get_irq_byname_optional(pdev, "sfty");
+	if (qxpcs->pcs_fusa_intr < 0)
+		pr_info("XPCS FUSA IRQ is not enabled\n");
+
+	platform_set_drvdata(pdev, qxpcs);
+
+	return 0;
+}
+
+static const struct of_device_id qcom_xpcs_match[] = {
+	{ .compatible = "qcom,xpcs"},
+	{}
+};
+
+static struct platform_driver pcs_xpcs_qcom_driver = {
+	.probe = qcom_xpcs_probe,
+	.driver = {
+		.name = "dwxpcs",
+		.of_match_table = of_match_ptr(qcom_xpcs_match),
+	},
+};
+module_platform_driver(pcs_xpcs_qcom_driver);
+
+MODULE_LICENSE("GPL");
--- linux-qcom-6.8.0.orig/drivers/net/pcs/pcs-xpcs-qcom.h
+++ linux-qcom-6.8.0/drivers/net/pcs/pcs-xpcs-qcom.h
@@ -0,0 +1,232 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Synopsys DesignWare XPCS platform device driver
+ *
+ * Copyright (c) 2024-2025 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/pcs-xpcs-qcom.h>
+
+#define LINK_STS_RETRY_COUNT		50
+#define SYNOPSYS_XPCS_ID		0x7996ced0
+#define SYNOPSYS_XPCS_MASK		0xffffffff // Reset mask for Dev IDs
+
+/* Vendor regs access */
+#define DW_VENDOR			BIT(15)
+
+/* VR_XS_PCS */
+#define DW_USXGMII_RST			BIT(10)
+#define DW_USXGMII_EN			BIT(9)
+#define DW_VR_XS_PCS_DIG_STS		0x2040 /* SWI name: EMAC0_VR_XS_PCS_DIG_STS */
+#define DW_RXFIFO_ERR			GENMASK(6, 5)
+#define DW_LBE				BIT(14)
+#define DW_SR_XS_PCS_STS1		BIT(2)
+
+/* SWI name: EMAC0_VR_XS_PCS_SFTY_UE_INTR0 */
+#define DW_VR_XS_PCS_SFTY_UE_INTR0		0x23C0
+/* SWI name EMAC0_VR_XS_PCS_SFTY_DISABLE*/
+#define DW_VR_XS_PCS_SFTY_DISABLE		0x23D0
+
+
+/* SR_MII */
+#define DW_FULL_DUPLEX			BIT(8)
+#define DW_USXGMII_SS_MASK		(BIT(13) | BIT(6) | BIT(5))
+#define DW_USXGMII_10000		(BIT(13) | BIT(6))
+#define DW_USXGMII_5000			(BIT(13) | BIT(5))
+#define DW_GMII_2500			(BIT(5))
+#define DW_GMII_1000			(BIT(6))
+#define DW_GMII_100				(BIT(13))
+#define DW_SGMII_SS_MASK		(BIT(13) | BIT(6))
+
+/* SR_AN */
+#define DW_SR_AN_ADV1			0x10
+#define DW_SR_AN_ADV2			0x11
+#define DW_SR_AN_ADV3			0x12
+#define DW_SR_AN_LP_ABL1		0x13
+#define DW_SR_AN_LP_ABL2		0x14
+#define DW_SR_AN_LP_ABL3		0x15
+
+/* Clause 37 Defines */
+/* VR MII MMD registers offsets */
+#define DW_SR_MII_MMD_CTRL		0x4000 /* SWI name: EMAC0_SR_MII_CTRL */
+#define DW_VR_MII_DIG_CTRL1		0x5000 /* SWI name: EMAC0_VR_MII_DIG_CTRL1 */
+#define DW_VR_MII_AN_CTRL		0x5004 /* SWI name: EMAC0_VR_MII_AN_CTRL */
+#define DW_VR_MII_AN_INTR_STS		0x5008 /* SWI name: EMAC0_VR_MII_AN_INTR_STS */
+/* Enable 2.5G Mode */
+#define DW_VR_MII_DIG_CTRL1_2G5_EN	BIT(2)
+/* EEE Mode Control Register */
+#define DW_VR_XS_PCS_EEE_MCTRL0		0x2018 /* SWI name: EMAC0_VR_XS_PCS_EEE_MCTRL0 */
+#define DW_VR_XS_PCS_EEE_MCTRL1		0x202c /* SWI name: EMAC0_VR_XS_PCS_EEE_MCTRL1 */
+#define DW_VR_MII_DIG_CTRL2		0x2004 /* SWI name: EMAC0_VR_XS_PCS_DIG_CTRL2 */
+
+#define DW_SR_MII_PCS_CTRL1		0x0000 /* SWI name: EMAC0_SR_XS_PCS_CTRL1 */
+#define DW_SR_MII_PCS_STS1		0x0004 /* SWI name: EMAC0_SR_XS_PCS_STS1 */
+#define DW_SR_MII_PCS_DEV_ID1		0x0008
+#define DW_SR_MII_PCS_DEV_ID2		0x000c
+#define DW_SR_MII_PCS_SPD_ABL		0x0010
+#define DW_SR_MII_PCS_DEV_PKG1		0x0014
+#define DW_SR_MII_PCS_DEV_PKG2		0x0018
+#define DW_SR_MII_PCS_CTRL2		0x001c
+#define DW_SR_MII_PCS_STS2		0x0020
+#define DW_SR_MII_PCS_STS3		0x0024
+#define DW_SR_MII_PCS_PKG1		0x0038
+#define DW_SR_MII_PCS_PKG2		0x003c
+#define DW_SR_MII_PCS_EEE_ABL		0x0050
+#define DW_SR_MII_PCS_EEE_ABL2		0x0054
+#define DW_SR_MII_PCS_EEE_WKERR		0x0058
+#define DW_SR_MII_PCS_LSTS		0x0060
+#define DW_SR_MII_PCS_TCTRL		0x0064
+#define DW_SR_MII_PCS_KR_STS1		0x0080
+#define DW_SR_MII_PCS_KR_STS2		0x0084
+#define DW_SR_MII_PCS_TP_A0		0x0088
+#define DW_SR_MII_PCS_TP_A1		0x008c
+#define DW_SR_MII_PCS_TP_A2		0x0090
+#define DW_SR_MII_PCS_TP_A3		0x0094
+#define DW_SR_MII_PCS_TP_B0		0x0098
+#define DW_SR_MII_PCS_TP_B1		0x009c
+#define DW_SR_MII_PCS_TP_B2		0x00a0
+#define DW_SR_MII_PCS_TP_B3		0x00a4
+#define DW_SR_MII_PCS_TP_CTRL		0x00a8
+#define DW_SR_MII_PCS_TP_ERRCTR		0x00ac
+#define DW_SR_MII_PCS_ABL		0x1c20
+#define DW_SR_MII_PCS_TIME_SYNC_TX_MAX_DLY_LWR		0x1c24
+#define DW_SR_MII_PCS_TIME_SYNC_TX_MAX_DLY_UPR		0x1c28
+#define DW_SR_MII_PCS_TIME_SYNC_TX_MIN_DLY_LWR		0x1c2c
+#define DW_SR_MII_PCS_TIME_SYNC_TX_MIN_DLY_UPR		0x1c30
+#define DW_SR_MII_PCS_TIME_SYNC_RX_MAX_DLY_LWR		0x1c34
+#define DW_SR_MII_PCS_TIME_SYNC_RX_MAX_DLY_UPR		0x1c38
+#define DW_SR_MII_PCS_TIME_SYNC_RX_MIN_DLY_LWR		0x1c3c
+#define DW_SR_MII_PCS_TIME_SYNC_RX_MIN_DLY_UPR		0x1c40
+#define DW_VR_MII_PCS_DIG_CTRL1		0x2000
+#define DW_VR_MII_PCS_DIG_ERRCNT_SEL	0x2008
+#define DW_VR_MII_PCS_XAUI_CTRL		0x2010
+#define DW_VR_MII_PCS_DEBUG_CTRL	0x2014
+#define DW_VR_MII_PCS_KR_CTRL		0x201c
+#define DW_VR_MII_PCS_EEE_TXTIMER	0x2020
+#define DW_VR_MII_PCS_EEE_RXTIMER	0x2024
+#define DW_VR_MII_PCS_ICG_ERRCNT1	0x2044
+#define DW_VR_MII_PCS_GPIO		0x2054
+#define DW_SR_MII_VSMMD_PMA_ID1		0x3000
+#define DW_SR_MII_VSMMD_PMA_ID2		0x3004
+#define DW_SR_MII_VSMMD_DEV_ID1		0x3008
+#define DW_SR_MII_VSMMD_DEV_ID2		0x300c
+#define DW_SR_MII_VSMMD_PCS_ID1		0x3010
+#define DW_SR_MII_VSMMD_PCS_ID2		0x3014
+#define DW_SR_MII_VSMMD_AN_ID1		0x3018
+#define DW_SR_MII_VSMMD_AN_ID2		0x301c
+#define DW_SR_MII_VSMMD_MMD_STS		0x3020
+#define DW_SR_MII_VSMMD_CTRL		0x3024
+#define DW_SR_MII_VSMMD_PKGID1		0x3038
+#define DW_SR_MII_VSMMD_PKGID2		0x303c
+#define DW_SR_MII_MMD_STS		0x4004
+#define DW_SR_MII_MMD_DEV_ID1		0x4008
+#define DW_SR_MII_MMD_DEV_ID2		0x400c
+#define DW_SR_MII_AN_ADV		0x4010
+#define DW_SR_MII_LP_BABL		0x4014
+#define DW_SR_MII_AN_EXPN		0x4018
+#define DW_SR_MII_EXT_STS		0x403c
+#define DW_VR_MII_LINK_TIMER_CTRL	0x5028
+
+/* XPCS power-down configuration registers */
+#define PD_CTRL					BIT(5)
+#define LPM_EN					BIT(11)
+
+/* VR_MII_DIG_CTRL1 */
+#define DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW		BIT(9)
+#define DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL	BIT(0)
+
+/* VR_MII_DIG_CTRL2 */
+#define DW_VR_MII_DIG_CTRL2_TX_POL_INV		BIT(4)
+#define DW_VR_MII_DIG_CTRL2_RX_POL_INV		BIT(0)
+
+/* VR_MII_AN_CTRL */
+#define DW_VR_MII_AN_CTRL_TX_CONFIG_SHIFT	3
+#define DW_VR_MII_TX_CONFIG_MASK		BIT(3)
+#define DW_VR_MII_TX_CONFIG_PHY_SIDE		0x1
+#define DW_VR_MII_TX_CONFIG_MAC_SIDE		0x0
+#define DW_VR_MII_AN_CTRL_PCS_MODE_SHIFT	1
+#define DW_VR_MII_PCS_MODE_MASK			GENMASK(2, 1)
+#define DW_VR_MII_PCS_MODE_C37_1000BASEX	0x0
+#define DW_VR_MII_PCS_MODE_C37_SGMII		BIT(2)
+#define DW_VR_MII_PCS_MODE_C37_QSGMII		0x3
+#define DW_VR_MII_AN_INTR_EN			BIT(0)
+#define DW_VR_MII_SGMII_LINK_STS		BIT(4)
+#define DW_VR_MII_CTRL					BIT(8)
+
+/* VR_MII_AN_INTR_STS */
+#define DW_VR_MII_AN_STS_C37_ANSGM_FD		BIT(1)
+#define DW_VR_MII_AN_STS_C37_ANSGM_SP_SHIFT	2
+#define DW_VR_MII_AN_STS_C37_ANSGM_SP		GENMASK(3, 2)
+#define DW_VR_MII_C37_ANSGM_SP_10		0x0
+#define DW_VR_MII_C37_ANSGM_SP_100		0x1
+#define DW_VR_MII_C37_ANSGM_SP_1000		0x2
+#define DW_VR_MII_C37_ANSGM_SP_LNKSTS		BIT(4)
+#define DW_VR_MII_USXG_ANSGM_FD			BIT(13)
+#define DW_VR_MII_USXG_ANSGM_SP_SHIFT		10
+#define DW_VR_MII_USXG_ANSGM_SP			GENMASK(12, 10)
+#define DW_VR_MII_USXG_ANSGM_SP_10		0x0
+#define DW_VR_MII_USXG_ANSGM_SP_100		0x1
+#define DW_VR_MII_USXG_ANSGM_SP_1000		0x2
+#define DW_VR_MII_USXG_ANSGM_SP_10G		0x3
+#define DW_VR_MII_USXG_ANSGM_SP_2P5G		0x4
+#define DW_VR_MII_USXG_ANSGM_SP_5G		0x5
+#define DW_VR_MII_USXG_ANSGM_SP_LNKSTS		BIT(14)
+#define DW_VR_MII_ANCMPLT_INTR			BIT(0)
+
+/* Bit 15 is the Soft Reset field for various registers */
+#define SOFT_RST				BIT(15)
+#define SW_RST_BIT_STATUS			0x8000
+#define USXG_RST_BIT_STATUS			0x0400
+
+/* SR MII MMD Control defines */
+#define AN_CL37_EN			BIT(12)	/* Enable Clause 37 auto-nego */
+
+/* VR MII EEE Control 0 defines */
+#define DW_VR_MII_EEE_LTX_EN			BIT(0)  /* LPI Tx Enable */
+#define DW_VR_MII_EEE_LRX_EN			BIT(1)  /* LPI Rx Enable */
+#define DW_VR_MII_EEE_TX_QUIET_EN		BIT(2)  /* Tx Quiet Enable */
+#define DW_VR_MII_EEE_RX_QUIET_EN		BIT(3)  /* Rx Quiet Enable */
+#define DW_VR_MII_EEE_TX_EN_CTRL		BIT(4)  /* Tx Control Enable */
+#define DW_VR_MII_EEE_RX_EN_CTRL		BIT(7)  /* Rx Control Enable */
+
+#define DW_VR_MII_EEE_MULT_FACT_100NS_SHIFT	8
+#define DW_VR_MII_EEE_MULT_FACT_100NS		GENMASK(11, 8)
+
+/* VR MII EEE Control 1 defines */
+#define DW_VR_MII_EEE_TRN_LPI		BIT(0)	/* Transparent Mode Enable */
+
+/* SR MII PCS Control 2 defines */
+#define PCS_TYPE_SEL_10GBR			GENMASK(3, 0)
+#define PCS_TYPE_SEL_10GBX			BIT(0)
+
+/* SR MII PCS Control 2 defines */
+#define PCS_TYPE_SEL_2500BASEX			GENMASK(3, 1)
+
+/* SR MII PCS KR Control defines */
+#define USXG_MODE_SEL				GENMASK(12, 10)
+#define USXGMII_5G				BIT(10)
+#define USXGMII_2P5G				BIT(11)
+
+/* SR_MII_AN_ADV */
+#define DW_SR_MII_AN_ADV_FD			BIT(5)
+#define DW_SR_MII_AN_ADV_HD			BIT(6)
+#define DW_SR_MII_STS_LINK_STS			BIT(2)
+
+/* Required settings to enable 2.5G SGMII mode */
+#define LINK_TIMER_1P6MS			0x07a1
+#define CL37_TMR_OVR_RIDE			BIT(3)
+
+/* EEE Ability register defines */
+#define KREEE_SUPPORT				BIT(6)
+#define KX4EEE_SUPPORT				BIT(5)
+#define KXEEE_SUPPORT				BIT(4)
+
+/* Tx Preemable Control for Debug Register */
+#define TX_PMBL_CTRL				BIT(8)
+
+struct xpcs_compat {
+	const int *supported;
+	const phy_interface_t *interface;
+	int num_interfaces;
+	int an_mode;
+};
--- linux-qcom-6.8.0.orig/drivers/net/pcs/pcs-xpcs-wx.c
+++ linux-qcom-6.8.0/drivers/net/pcs/pcs-xpcs-wx.c
@@ -109,7 +109,7 @@
 	txgbe_write_pma(xpcs, TXGBE_DFE_TAP_CTL0, 0);
 	val = txgbe_read_pma(xpcs, TXGBE_RX_GEN_CTL3);
 	val = u16_replace_bits(val, 0x4, TXGBE_RX_GEN_CTL3_LOS_TRSHLD0);
-	txgbe_write_pma(xpcs, TXGBE_RX_EQ_ATTN_CTL, val);
+	txgbe_write_pma(xpcs, TXGBE_RX_GEN_CTL3, val);
 
 	txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL0, 0x20);
 	txgbe_write_pma(xpcs, TXGBE_MPLLA_CTL3, 0x46);
--- linux-qcom-6.8.0.orig/drivers/net/pcs/pcs-xpcs.c
+++ linux-qcom-6.8.0/drivers/net/pcs/pcs-xpcs.c
@@ -293,7 +293,7 @@
 		dev = MDIO_MMD_VEND2;
 		break;
 	default:
-		return -1;
+		return -EINVAL;
 	}
 
 	ret = xpcs_write(xpcs, dev, MDIO_CTRL1, MDIO_CTRL1_RESET);
@@ -891,7 +891,7 @@
 			return ret;
 		break;
 	default:
-		return -1;
+		return -EINVAL;
 	}
 
 	if (compat->pma_config) {
--- linux-qcom-6.8.0.orig/drivers/net/phy/aquantia/Makefile
+++ linux-qcom-6.8.0/drivers/net/phy/aquantia/Makefile
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
-aquantia-objs			+= aquantia_main.o aquantia_firmware.o
+aquantia-objs			+= aquantia_main.o aquantia_firmware.o aquantia_leds.o
 ifdef CONFIG_HWMON
 aquantia-objs			+= aquantia_hwmon.o
 endif
--- linux-qcom-6.8.0.orig/drivers/net/phy/aquantia/aquantia.h
+++ linux-qcom-6.8.0/drivers/net/phy/aquantia/aquantia.h
@@ -6,6 +6,9 @@
  * Author: Heiner Kallweit <hkallweit1@gmail.com>
  */
 
+#ifndef AQUANTIA_H
+#define AQUANTIA_H
+
 #include <linux/device.h>
 #include <linux/phy.h>
 
@@ -63,6 +66,28 @@
 #define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL_OVD	BIT(6)
 #define VEND1_GLOBAL_CONTROL2_UP_RUN_STALL	BIT(0)
 
+#define VEND1_GLOBAL_LED_PROV			0xc430
+#define AQR_LED_PROV(x)				(VEND1_GLOBAL_LED_PROV + (x))
+#define VEND1_GLOBAL_LED_PROV_LINK2500		BIT(14)
+#define VEND1_GLOBAL_LED_PROV_LINK5000		BIT(15)
+#define VEND1_GLOBAL_LED_PROV_FORCE_ON		BIT(8)
+#define VEND1_GLOBAL_LED_PROV_LINK10000		BIT(7)
+#define VEND1_GLOBAL_LED_PROV_LINK1000		BIT(6)
+#define VEND1_GLOBAL_LED_PROV_LINK100		BIT(5)
+#define VEND1_GLOBAL_LED_PROV_RX_ACT		BIT(3)
+#define VEND1_GLOBAL_LED_PROV_TX_ACT		BIT(2)
+#define VEND1_GLOBAL_LED_PROV_ACT_STRETCH	GENMASK(0, 1)
+
+#define VEND1_GLOBAL_LED_PROV_LINK_MASK		(VEND1_GLOBAL_LED_PROV_LINK100 | \
+						 VEND1_GLOBAL_LED_PROV_LINK1000 | \
+						 VEND1_GLOBAL_LED_PROV_LINK10000 | \
+						 VEND1_GLOBAL_LED_PROV_LINK5000 | \
+						 VEND1_GLOBAL_LED_PROV_LINK2500)
+
+#define VEND1_GLOBAL_LED_DRIVE			0xc438
+#define VEND1_GLOBAL_LED_DRIVE_VDD		BIT(1)
+#define AQR_LED_DRIVE(x)			(VEND1_GLOBAL_LED_DRIVE + (x))
+
 #define VEND1_THERMAL_PROV_HIGH_TEMP_FAIL	0xc421
 #define VEND1_THERMAL_PROV_LOW_TEMP_FAIL	0xc422
 #define VEND1_THERMAL_PROV_HIGH_TEMP_WARN	0xc423
@@ -87,6 +112,18 @@
 #define VEND1_GLOBAL_RSVD_STAT9_MODE		GENMASK(7, 0)
 #define VEND1_GLOBAL_RSVD_STAT9_1000BT2		0x23
 
+/* MDIO_MMD_C22EXT */
+#define MDIO_C22EXT_STAT_SGMII_RX_GOOD_FRAMES		0xd292
+#define MDIO_C22EXT_STAT_SGMII_RX_BAD_FRAMES		0xd294
+#define MDIO_C22EXT_STAT_SGMII_RX_FALSE_CARRIER		0xd297
+#define MDIO_C22EXT_STAT_SGMII_TX_GOOD_FRAMES		0xd313
+#define MDIO_C22EXT_STAT_SGMII_TX_BAD_FRAMES		0xd315
+#define MDIO_C22EXT_STAT_SGMII_TX_FALSE_CARRIER		0xd317
+#define MDIO_C22EXT_STAT_SGMII_TX_COLLISIONS		0xd318
+#define MDIO_C22EXT_STAT_SGMII_TX_LINE_COLLISIONS	0xd319
+#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR	0xd31a
+#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES		0xd31b
+
 #define VEND1_GLOBAL_INT_STD_STATUS		0xfc00
 #define VEND1_GLOBAL_INT_VEND_STATUS		0xfc01
 
@@ -113,6 +150,35 @@
 #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2	BIT(1)
 #define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3	BIT(0)
 
+#define AQR_MAX_LEDS				3
+
+struct aqr107_hw_stat {
+	const char *name;
+	int reg;
+	int size;
+};
+
+#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s }
+static const struct aqr107_hw_stat aqr107_hw_stats[] = {
+	SGMII_STAT("sgmii_rx_good_frames",	    RX_GOOD_FRAMES,	26),
+	SGMII_STAT("sgmii_rx_bad_frames",	    RX_BAD_FRAMES,	26),
+	SGMII_STAT("sgmii_rx_false_carrier_events", RX_FALSE_CARRIER,	 8),
+	SGMII_STAT("sgmii_tx_good_frames",	    TX_GOOD_FRAMES,	26),
+	SGMII_STAT("sgmii_tx_bad_frames",	    TX_BAD_FRAMES,	26),
+	SGMII_STAT("sgmii_tx_false_carrier_events", TX_FALSE_CARRIER,	 8),
+	SGMII_STAT("sgmii_tx_collisions",	    TX_COLLISIONS,	 8),
+	SGMII_STAT("sgmii_tx_line_collisions",	    TX_LINE_COLLISIONS,	 8),
+	SGMII_STAT("sgmii_tx_frame_alignment_err",  TX_FRAME_ALIGN_ERR,	16),
+	SGMII_STAT("sgmii_tx_runt_frames",	    TX_RUNT_FRAMES,	22),
+};
+
+#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats)
+
+struct aqr107_priv {
+	u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
+	unsigned long leds_active_low;
+};
+
 #if IS_REACHABLE(CONFIG_HWMON)
 int aqr_hwmon_probe(struct phy_device *phydev);
 #else
@@ -120,3 +186,21 @@
 #endif
 
 int aqr_firmware_load(struct phy_device *phydev);
+
+int aqr_phy_led_blink_set(struct phy_device *phydev, u8 index,
+			  unsigned long *delay_on,
+			  unsigned long *delay_off);
+int aqr_phy_led_brightness_set(struct phy_device *phydev,
+			       u8 index, enum led_brightness value);
+int aqr_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+				unsigned long rules);
+int aqr_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
+			       unsigned long *rules);
+int aqr_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
+			       unsigned long rules);
+int aqr_phy_led_active_low_set(struct phy_device *phydev, int index, bool enable);
+int aqr_phy_led_polarity_set(struct phy_device *phydev, int index,
+			     unsigned long modes);
+int aqr_wait_reset_complete(struct phy_device *phydev);
+
+#endif /* AQUANTIA_H */
--- linux-qcom-6.8.0.orig/drivers/net/phy/aquantia/aquantia_firmware.c
+++ linux-qcom-6.8.0/drivers/net/phy/aquantia/aquantia_firmware.c
@@ -353,22 +353,32 @@
 {
 	int ret;
 
-	/* Check if the firmware is not already loaded by pooling
-	 * the current version returned by the PHY. If 0 is returned,
-	 * no firmware is loaded.
+	/* Check if the firmware is not already loaded by polling
+	 * the current version returned by the PHY.
 	 */
-	ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID);
-	if (ret > 0)
-		goto exit;
+	ret = aqr_wait_reset_complete(phydev);
+	switch (ret) {
+	case 0:
+		/* Some firmware is loaded => do nothing */
+		return 0;
+	case -ETIMEDOUT:
+		/* VEND1_GLOBAL_FW_ID still reads 0 after 2 seconds of polling.
+		 * We don't have full confidence that no firmware is loaded (in
+		 * theory it might just not have loaded yet), but we will
+		 * assume that, and load a new image.
+		 */
+		ret = aqr_firmware_load_nvmem(phydev);
+		if (!ret)
+			return ret;
 
-	ret = aqr_firmware_load_nvmem(phydev);
-	if (!ret)
-		goto exit;
-
-	ret = aqr_firmware_load_fs(phydev);
-	if (ret)
+		ret = aqr_firmware_load_fs(phydev);
+		if (ret)
+			return ret;
+		break;
+	default:
+		/* PHY read error, propagate it to the caller */
 		return ret;
+	}
 
-exit:
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/net/phy/aquantia/aquantia_leds.c
+++ linux-qcom-6.8.0/drivers/net/phy/aquantia/aquantia_leds.c
@@ -0,0 +1,150 @@
+// SPDX-License-Identifier: GPL-2.0
+/* LED driver for Aquantia PHY
+ *
+ * Author: Daniel Golle <daniel@makrotopia.org>
+ */
+
+#include <linux/phy.h>
+
+#include "aquantia.h"
+
+int aqr_phy_led_brightness_set(struct phy_device *phydev,
+			       u8 index, enum led_brightness value)
+{
+	if (index >= AQR_MAX_LEDS)
+		return -EINVAL;
+
+	return phy_modify_mmd(phydev, MDIO_MMD_VEND1, AQR_LED_PROV(index),
+			      VEND1_GLOBAL_LED_PROV_LINK_MASK |
+			      VEND1_GLOBAL_LED_PROV_FORCE_ON |
+			      VEND1_GLOBAL_LED_PROV_RX_ACT |
+			      VEND1_GLOBAL_LED_PROV_TX_ACT,
+			      value ? VEND1_GLOBAL_LED_PROV_FORCE_ON : 0);
+}
+
+static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_LINK) |
+						 BIT(TRIGGER_NETDEV_LINK_100) |
+						 BIT(TRIGGER_NETDEV_LINK_1000) |
+						 BIT(TRIGGER_NETDEV_LINK_2500) |
+						 BIT(TRIGGER_NETDEV_LINK_5000) |
+						 BIT(TRIGGER_NETDEV_LINK_10000)  |
+						 BIT(TRIGGER_NETDEV_RX) |
+						 BIT(TRIGGER_NETDEV_TX));
+
+int aqr_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
+				unsigned long rules)
+{
+	if (index >= AQR_MAX_LEDS)
+		return -EINVAL;
+
+	/* All combinations of the supported triggers are allowed */
+	if (rules & ~supported_triggers)
+		return -EOPNOTSUPP;
+
+	return 0;
+}
+
+int aqr_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
+			       unsigned long *rules)
+{
+	int val;
+
+	if (index >= AQR_MAX_LEDS)
+		return -EINVAL;
+
+	val = phy_read_mmd(phydev, MDIO_MMD_VEND1, AQR_LED_PROV(index));
+	if (val < 0)
+		return val;
+
+	*rules = 0;
+	if (val & VEND1_GLOBAL_LED_PROV_LINK100)
+		*rules |= BIT(TRIGGER_NETDEV_LINK_100);
+
+	if (val & VEND1_GLOBAL_LED_PROV_LINK1000)
+		*rules |= BIT(TRIGGER_NETDEV_LINK_1000);
+
+	if (val & VEND1_GLOBAL_LED_PROV_LINK2500)
+		*rules |= BIT(TRIGGER_NETDEV_LINK_2500);
+
+	if (val & VEND1_GLOBAL_LED_PROV_LINK5000)
+		*rules |= BIT(TRIGGER_NETDEV_LINK_5000);
+
+	if (val & VEND1_GLOBAL_LED_PROV_LINK10000)
+		*rules |= BIT(TRIGGER_NETDEV_LINK_10000);
+
+	if (val & VEND1_GLOBAL_LED_PROV_RX_ACT)
+		*rules |= BIT(TRIGGER_NETDEV_RX);
+
+	if (val & VEND1_GLOBAL_LED_PROV_TX_ACT)
+		*rules |= BIT(TRIGGER_NETDEV_TX);
+
+	return 0;
+}
+
+int aqr_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
+			       unsigned long rules)
+{
+	u16 val = 0;
+
+	if (index >= AQR_MAX_LEDS)
+		return -EINVAL;
+
+	if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
+		val |= VEND1_GLOBAL_LED_PROV_LINK100;
+
+	if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
+		val |= VEND1_GLOBAL_LED_PROV_LINK1000;
+
+	if (rules & (BIT(TRIGGER_NETDEV_LINK_2500) | BIT(TRIGGER_NETDEV_LINK)))
+		val |= VEND1_GLOBAL_LED_PROV_LINK2500;
+
+	if (rules & (BIT(TRIGGER_NETDEV_LINK_5000) | BIT(TRIGGER_NETDEV_LINK)))
+		val |= VEND1_GLOBAL_LED_PROV_LINK5000;
+
+	if (rules & (BIT(TRIGGER_NETDEV_LINK_10000) | BIT(TRIGGER_NETDEV_LINK)))
+		val |= VEND1_GLOBAL_LED_PROV_LINK10000;
+
+	if (rules & BIT(TRIGGER_NETDEV_RX))
+		val |= VEND1_GLOBAL_LED_PROV_RX_ACT;
+
+	if (rules & BIT(TRIGGER_NETDEV_TX))
+		val |= VEND1_GLOBAL_LED_PROV_TX_ACT;
+
+	return phy_modify_mmd(phydev, MDIO_MMD_VEND1, AQR_LED_PROV(index),
+			      VEND1_GLOBAL_LED_PROV_LINK_MASK |
+			      VEND1_GLOBAL_LED_PROV_FORCE_ON |
+			      VEND1_GLOBAL_LED_PROV_RX_ACT |
+			      VEND1_GLOBAL_LED_PROV_TX_ACT, val);
+}
+
+int aqr_phy_led_active_low_set(struct phy_device *phydev, int index, bool enable)
+{
+	return phy_modify_mmd(phydev, MDIO_MMD_VEND1, AQR_LED_DRIVE(index),
+			      VEND1_GLOBAL_LED_DRIVE_VDD, enable);
+}
+
+int aqr_phy_led_polarity_set(struct phy_device *phydev, int index, unsigned long modes)
+{
+	struct aqr107_priv *priv = phydev->priv;
+	bool active_low = false;
+	u32 mode;
+
+	if (index >= AQR_MAX_LEDS)
+		return -EINVAL;
+
+	for_each_set_bit(mode, &modes, __PHY_LED_MODES_NUM) {
+		switch (mode) {
+		case PHY_LED_ACTIVE_LOW:
+			active_low = true;
+			break;
+		default:
+			return -EINVAL;
+		}
+	}
+
+	/* Save LED driver vdd state to restore on SW reset */
+	if (active_low)
+		priv->leds_active_low |= BIT(index);
+
+	return aqr_phy_led_active_low_set(phydev, index, active_low);
+}
--- linux-qcom-6.8.0.orig/drivers/net/phy/aquantia/aquantia_main.c
+++ linux-qcom-6.8.0/drivers/net/phy/aquantia/aquantia_main.c
@@ -22,9 +22,15 @@
 #define PHY_ID_AQR107	0x03a1b4e0
 #define PHY_ID_AQCS109	0x03a1b5c2
 #define PHY_ID_AQR405	0x03a1b4b0
+#define PHY_ID_AQR111	0x03a1b610
+#define PHY_ID_AQR111B0	0x03a1b612
 #define PHY_ID_AQR112	0x03a1b662
 #define PHY_ID_AQR412	0x03a1b712
+#define PHY_ID_AQR113	0x31c31c40
 #define PHY_ID_AQR113C	0x31c31c12
+#define PHY_ID_AQR114C	0x31c31c22
+#define PHY_ID_AQR115C	0x31c31c33
+#define PHY_ID_AQR813	0x31c31cb2
 
 #define MDIO_PHYXS_VEND_IF_STATUS		0xe812
 #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK	GENMASK(7, 3)
@@ -35,7 +41,9 @@
 #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI	4
 #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII	6
 #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI	7
+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OFF	9
 #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII	10
+#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_USX_5G	12
 
 #define MDIO_AN_VEND_PROV			0xc400
 #define MDIO_AN_VEND_PROV_1000BASET_FULL	BIT(15)
@@ -79,49 +87,12 @@
 #define MDIO_AN_RX_VEND_STAT3			0xe832
 #define MDIO_AN_RX_VEND_STAT3_AFR		BIT(0)
 
-/* MDIO_MMD_C22EXT */
-#define MDIO_C22EXT_STAT_SGMII_RX_GOOD_FRAMES		0xd292
-#define MDIO_C22EXT_STAT_SGMII_RX_BAD_FRAMES		0xd294
-#define MDIO_C22EXT_STAT_SGMII_RX_FALSE_CARRIER		0xd297
-#define MDIO_C22EXT_STAT_SGMII_TX_GOOD_FRAMES		0xd313
-#define MDIO_C22EXT_STAT_SGMII_TX_BAD_FRAMES		0xd315
-#define MDIO_C22EXT_STAT_SGMII_TX_FALSE_CARRIER		0xd317
-#define MDIO_C22EXT_STAT_SGMII_TX_COLLISIONS		0xd318
-#define MDIO_C22EXT_STAT_SGMII_TX_LINE_COLLISIONS	0xd319
-#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR	0xd31a
-#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES		0xd31b
-
 /* Sleep and timeout for checking if the Processor-Intensive
  * MDIO operation is finished
  */
 #define AQR107_OP_IN_PROG_SLEEP		1000
 #define AQR107_OP_IN_PROG_TIMEOUT	100000
 
-struct aqr107_hw_stat {
-	const char *name;
-	int reg;
-	int size;
-};
-
-#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s }
-static const struct aqr107_hw_stat aqr107_hw_stats[] = {
-	SGMII_STAT("sgmii_rx_good_frames",	    RX_GOOD_FRAMES,	26),
-	SGMII_STAT("sgmii_rx_bad_frames",	    RX_BAD_FRAMES,	26),
-	SGMII_STAT("sgmii_rx_false_carrier_events", RX_FALSE_CARRIER,	 8),
-	SGMII_STAT("sgmii_tx_good_frames",	    TX_GOOD_FRAMES,	26),
-	SGMII_STAT("sgmii_tx_bad_frames",	    TX_BAD_FRAMES,	26),
-	SGMII_STAT("sgmii_tx_false_carrier_events", TX_FALSE_CARRIER,	 8),
-	SGMII_STAT("sgmii_tx_collisions",	    TX_COLLISIONS,	 8),
-	SGMII_STAT("sgmii_tx_line_collisions",	    TX_LINE_COLLISIONS,	 8),
-	SGMII_STAT("sgmii_tx_frame_alignment_err",  TX_FRAME_ALIGN_ERR,	16),
-	SGMII_STAT("sgmii_tx_runt_frames",	    TX_RUNT_FRAMES,	22),
-};
-#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats)
-
-struct aqr107_priv {
-	u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
-};
-
 static int aqr107_get_sset_count(struct phy_device *phydev)
 {
 	return AQR107_SGMII_STAT_SZ;
@@ -373,9 +344,19 @@
 	if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE)
 		return 0;
 
-	val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS);
-	if (val < 0)
-		return val;
+	/**
+	 * The status register is not immediately correct on line side link up.
+	 * Poll periodically until it reflects the correct ON state.
+	 * Only return fail for read error, timeout defaults to OFF state.
+	 */
+	ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PHYXS,
+					MDIO_PHYXS_VEND_IF_STATUS, val,
+					(FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val) !=
+					MDIO_PHYXS_VEND_IF_STATUS_TYPE_OFF),
+					AQR107_OP_IN_PROG_SLEEP,
+					AQR107_OP_IN_PROG_TIMEOUT, false);
+	if (ret && ret != -ETIMEDOUT)
+		return ret;
 
 	switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) {
 	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR:
@@ -402,7 +383,12 @@
 	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII:
 		phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
 		break;
+	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USX_5G:
+		phydev->interface = PHY_INTERFACE_MODE_5GBASER;
+		break;
+	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OFF:
 	default:
+		phydev->link = false;
 		phydev->interface = PHY_INTERFACE_MODE_NA;
 		break;
 	}
@@ -466,6 +452,9 @@
 	}
 }
 
+#define AQR_FW_WAIT_SLEEP_US	20000
+#define AQR_FW_WAIT_TIMEOUT_US	2000000
+
 /* If we configure settings whilst firmware is still initializing the chip,
  * then these settings may be overwritten. Therefore make sure chip
  * initialization has completed. Use presence of the firmware ID as
@@ -473,13 +462,24 @@
  * The chip also provides a "reset completed" bit, but it's cleared after
  * read. Therefore function would time out if called again.
  */
-static int aqr107_wait_reset_complete(struct phy_device *phydev)
+int aqr_wait_reset_complete(struct phy_device *phydev)
 {
-	int val;
+	int ret, val;
 
-	return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
-					 VEND1_GLOBAL_FW_ID, val, val != 0,
-					 20000, 2000000, false);
+	ret = read_poll_timeout(phy_read_mmd, val, val != 0,
+				AQR_FW_WAIT_SLEEP_US, AQR_FW_WAIT_TIMEOUT_US,
+				false, phydev, MDIO_MMD_VEND1,
+				VEND1_GLOBAL_FW_ID);
+	if (val < 0) {
+		if (phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+					      VEND1_GLOBAL_RSVD_STAT1, val,
+					      FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID,
+							val) != 0,
+					      20000, 2000000, false))
+			phydev_dbg(phydev, "Provision ID is 0\n");
+	}
+
+	return ret;
 }
 
 static void aqr107_chip_info(struct phy_device *phydev)
@@ -507,7 +507,9 @@
 
 static int aqr107_config_init(struct phy_device *phydev)
 {
-	int ret;
+	struct aqr107_priv *priv = phydev->priv;
+	u32 led_active_low;
+	int ret, index = 0;
 
 	/* Check that the PHY interface type is compatible */
 	if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
@@ -518,17 +520,30 @@
 	    phydev->interface != PHY_INTERFACE_MODE_10GKR &&
 	    phydev->interface != PHY_INTERFACE_MODE_10GBASER &&
 	    phydev->interface != PHY_INTERFACE_MODE_XAUI &&
-	    phydev->interface != PHY_INTERFACE_MODE_RXAUI)
+	    phydev->interface != PHY_INTERFACE_MODE_RXAUI &&
+	    phydev->interface != PHY_INTERFACE_MODE_5GBASER)
 		return -ENODEV;
 
 	WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII,
 	     "Your devicetree is out of date, please update it. The AQR107 family doesn't support XGMII, maybe you mean USXGMII.\n");
 
-	ret = aqr107_wait_reset_complete(phydev);
+	ret = aqr_wait_reset_complete(phydev);
 	if (!ret)
 		aqr107_chip_info(phydev);
 
-	return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
+	ret = aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
+	if (ret)
+		return ret;
+
+	/* Restore LED polarity state after reset */
+	for_each_set_bit(led_active_low, &priv->leds_active_low, AQR_MAX_LEDS) {
+		ret = aqr_phy_led_active_low_set(phydev, index, led_active_low);
+		if (ret)
+			return ret;
+		index++;
+	}
+
+	return 0;
 }
 
 static int aqcs109_config_init(struct phy_device *phydev)
@@ -540,7 +555,7 @@
 	    phydev->interface != PHY_INTERFACE_MODE_2500BASEX)
 		return -ENODEV;
 
-	ret = aqr107_wait_reset_complete(phydev);
+	ret = aqr_wait_reset_complete(phydev);
 	if (!ret)
 		aqr107_chip_info(phydev);
 
@@ -627,7 +642,8 @@
 {
 	if (iface == PHY_INTERFACE_MODE_10GBASER ||
 	    iface == PHY_INTERFACE_MODE_2500BASEX ||
-	    iface == PHY_INTERFACE_MODE_NA)
+	    iface == PHY_INTERFACE_MODE_NA ||
+	    iface == PHY_INTERFACE_MODE_5GBASER)
 		return RATE_MATCH_PAUSE;
 	return RATE_MATCH_NONE;
 }
@@ -719,6 +735,53 @@
 	return 0;
 }
 
+static int aqr113c_fill_interface_modes(struct phy_device *phydev)
+{
+	int val, ret;
+
+	/* It's been observed on some models that - when coming out of suspend
+	 * - the FW signals that the PHY is ready but the GLOBAL_CFG registers
+	 * continue on returning zeroes for some time. Let's poll the 100M
+	 * register until it returns a real value as both 113c and 115c support
+	 * this mode.
+	 */
+	ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+					VEND1_GLOBAL_CFG_100M, val, val != 0,
+					1000, 100000, false);
+	if (ret)
+		return ret;
+
+	return aqr107_fill_interface_modes(phydev);
+}
+
+static int aqr113c_get_features(struct phy_device *phydev)
+{
+	unsigned long *supported = phydev->supported;
+
+	/* PHY supports speeds up to 10G with autoneg. PMA capabilities
+	 * are not useful.
+	 */
+	linkmode_or(supported, supported, phy_gbit_features);
+	linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, supported);
+	linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, supported);
+	linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, supported);
+
+	return 0;
+}
+
+static int aqr115c_get_features(struct phy_device *phydev)
+{
+	unsigned long *supported = phydev->supported;
+
+	/* PHY supports speeds up to 2.5G with autoneg. PMA capabilities
+	 * are not useful.
+	 */
+	linkmode_or(supported, supported, phy_gbit_features);
+	linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, supported);
+
+	return 0;
+}
+
 static int aqr113c_config_init(struct phy_device *phydev)
 {
 	int ret;
@@ -727,7 +790,16 @@
 	if (ret < 0)
 		return ret;
 
-	return aqr107_fill_interface_modes(phydev);
+	ret = phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS,
+				 MDIO_PMD_TXDIS_GLOBAL);
+	if (ret)
+		return ret;
+
+	ret = aqr107_wait_processor_intensive_op(phydev);
+	if (ret)
+		return ret;
+
+	return aqr113c_fill_interface_modes(phydev);
 }
 
 static int aqr107_probe(struct phy_device *phydev)
@@ -746,6 +818,16 @@
 	return aqr_hwmon_probe(phydev);
 }
 
+static int aqr111_config_init(struct phy_device *phydev)
+{
+	/* AQR111 reports supporting speed up to 10G,
+	 * however only speeds up to 5G are supported.
+	 */
+	phy_set_max_speed(phydev, SPEED_5000);
+
+	return aqr107_config_init(phydev);
+}
+
 static struct phy_driver aqr_driver[] = {
 {
 	PHY_ID_MATCH_MODEL(PHY_ID_AQ1202),
@@ -799,6 +881,11 @@
 	.get_strings	= aqr107_get_strings,
 	.get_stats	= aqr107_get_stats,
 	.link_change_notify = aqr107_link_change_notify,
+	.led_brightness_set = aqr_phy_led_brightness_set,
+	.led_hw_is_supported = aqr_phy_led_hw_is_supported,
+	.led_hw_control_set = aqr_phy_led_hw_control_set,
+	.led_hw_control_get = aqr_phy_led_hw_control_get,
+	.led_polarity_set = aqr_phy_led_polarity_set,
 },
 {
 	PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),
@@ -818,6 +905,59 @@
 	.get_strings	= aqr107_get_strings,
 	.get_stats	= aqr107_get_stats,
 	.link_change_notify = aqr107_link_change_notify,
+	.led_brightness_set = aqr_phy_led_brightness_set,
+	.led_hw_is_supported = aqr_phy_led_hw_is_supported,
+	.led_hw_control_set = aqr_phy_led_hw_control_set,
+	.led_hw_control_get = aqr_phy_led_hw_control_get,
+	.led_polarity_set = aqr_phy_led_polarity_set,
+},
+{
+	PHY_ID_MATCH_MODEL(PHY_ID_AQR111),
+	.name		= "Aquantia AQR111",
+	.probe		= aqr107_probe,
+	.get_rate_matching = aqr107_get_rate_matching,
+	.config_init	= aqr111_config_init,
+	.config_aneg    = aqr_config_aneg,
+	.config_intr	= aqr_config_intr,
+	.handle_interrupt = aqr_handle_interrupt,
+	.read_status	= aqr107_read_status,
+	.get_tunable    = aqr107_get_tunable,
+	.set_tunable    = aqr107_set_tunable,
+	.suspend	= aqr107_suspend,
+	.resume		= aqr107_resume,
+	.get_sset_count	= aqr107_get_sset_count,
+	.get_strings	= aqr107_get_strings,
+	.get_stats	= aqr107_get_stats,
+	.link_change_notify = aqr107_link_change_notify,
+	.led_brightness_set = aqr_phy_led_brightness_set,
+	.led_hw_is_supported = aqr_phy_led_hw_is_supported,
+	.led_hw_control_set = aqr_phy_led_hw_control_set,
+	.led_hw_control_get = aqr_phy_led_hw_control_get,
+	.led_polarity_set = aqr_phy_led_polarity_set,
+},
+{
+	PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0),
+	.name		= "Aquantia AQR111B0",
+	.probe		= aqr107_probe,
+	.get_rate_matching = aqr107_get_rate_matching,
+	.config_init	= aqr111_config_init,
+	.config_aneg    = aqr_config_aneg,
+	.config_intr	= aqr_config_intr,
+	.handle_interrupt = aqr_handle_interrupt,
+	.read_status	= aqr107_read_status,
+	.get_tunable    = aqr107_get_tunable,
+	.set_tunable    = aqr107_set_tunable,
+	.suspend	= aqr107_suspend,
+	.resume		= aqr107_resume,
+	.get_sset_count	= aqr107_get_sset_count,
+	.get_strings	= aqr107_get_strings,
+	.get_stats	= aqr107_get_stats,
+	.link_change_notify = aqr107_link_change_notify,
+	.led_brightness_set = aqr_phy_led_brightness_set,
+	.led_hw_is_supported = aqr_phy_led_hw_is_supported,
+	.led_hw_control_set = aqr_phy_led_hw_control_set,
+	.led_hw_control_get = aqr_phy_led_hw_control_get,
+	.led_polarity_set = aqr_phy_led_polarity_set,
 },
 {
 	PHY_ID_MATCH_MODEL(PHY_ID_AQR405),
@@ -844,6 +984,11 @@
 	.get_strings	= aqr107_get_strings,
 	.get_stats	= aqr107_get_stats,
 	.link_change_notify = aqr107_link_change_notify,
+	.led_brightness_set = aqr_phy_led_brightness_set,
+	.led_hw_is_supported = aqr_phy_led_hw_is_supported,
+	.led_hw_control_set = aqr_phy_led_hw_control_set,
+	.led_hw_control_get = aqr_phy_led_hw_control_get,
+	.led_polarity_set = aqr_phy_led_polarity_set,
 },
 {
 	PHY_ID_MATCH_MODEL(PHY_ID_AQR412),
@@ -864,6 +1009,30 @@
 	.link_change_notify = aqr107_link_change_notify,
 },
 {
+	PHY_ID_MATCH_MODEL(PHY_ID_AQR113),
+	.name		= "Aquantia AQR113",
+	.probe          = aqr107_probe,
+	.get_rate_matching = aqr107_get_rate_matching,
+	.config_init    = aqr113c_config_init,
+	.config_aneg    = aqr_config_aneg,
+	.config_intr    = aqr_config_intr,
+	.handle_interrupt       = aqr_handle_interrupt,
+	.read_status    = aqr107_read_status,
+	.get_tunable    = aqr107_get_tunable,
+	.set_tunable    = aqr107_set_tunable,
+	.suspend        = aqr107_suspend,
+	.resume         = aqr107_resume,
+	.get_sset_count = aqr107_get_sset_count,
+	.get_strings    = aqr107_get_strings,
+	.get_stats      = aqr107_get_stats,
+	.link_change_notify = aqr107_link_change_notify,
+	.led_brightness_set = aqr_phy_led_brightness_set,
+	.led_hw_is_supported = aqr_phy_led_hw_is_supported,
+	.led_hw_control_set = aqr_phy_led_hw_control_set,
+	.led_hw_control_get = aqr_phy_led_hw_control_get,
+	.led_polarity_set = aqr_phy_led_polarity_set,
+},
+{
 	PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),
 	.name           = "Aquantia AQR113C",
 	.probe          = aqr107_probe,
@@ -880,7 +1049,86 @@
 	.get_sset_count = aqr107_get_sset_count,
 	.get_strings    = aqr107_get_strings,
 	.get_stats      = aqr107_get_stats,
+	.get_features   = aqr113c_get_features,
+	.link_change_notify = aqr107_link_change_notify,
+	.led_brightness_set = aqr_phy_led_brightness_set,
+	.led_hw_is_supported = aqr_phy_led_hw_is_supported,
+	.led_hw_control_set = aqr_phy_led_hw_control_set,
+	.led_hw_control_get = aqr_phy_led_hw_control_get,
+	.led_polarity_set = aqr_phy_led_polarity_set,
+},
+{
+	PHY_ID_MATCH_MODEL(PHY_ID_AQR114C),
+	.name           = "Aquantia AQR114C",
+	.probe          = aqr107_probe,
+	.get_rate_matching = aqr107_get_rate_matching,
+	.config_init    = aqr111_config_init,
+	.config_aneg    = aqr_config_aneg,
+	.config_intr    = aqr_config_intr,
+	.handle_interrupt = aqr_handle_interrupt,
+	.read_status    = aqr107_read_status,
+	.get_tunable    = aqr107_get_tunable,
+	.set_tunable    = aqr107_set_tunable,
+	.suspend        = aqr107_suspend,
+	.resume         = aqr107_resume,
+	.get_sset_count = aqr107_get_sset_count,
+	.get_strings    = aqr107_get_strings,
+	.get_stats      = aqr107_get_stats,
+	.link_change_notify = aqr107_link_change_notify,
+	.led_brightness_set = aqr_phy_led_brightness_set,
+	.led_hw_is_supported = aqr_phy_led_hw_is_supported,
+	.led_hw_control_set = aqr_phy_led_hw_control_set,
+	.led_hw_control_get = aqr_phy_led_hw_control_get,
+	.led_polarity_set = aqr_phy_led_polarity_set,
+},
+{
+	PHY_ID_MATCH_MODEL(PHY_ID_AQR115C),
+	.name           = "Aquantia AQR115C",
+	.probe          = aqr107_probe,
+	.get_rate_matching = aqr107_get_rate_matching,
+	.config_init    = aqr113c_config_init,
+	.config_aneg    = aqr_config_aneg,
+	.config_intr    = aqr_config_intr,
+	.handle_interrupt = aqr_handle_interrupt,
+	.read_status    = aqr107_read_status,
+	.get_tunable    = aqr107_get_tunable,
+	.set_tunable    = aqr107_set_tunable,
+	.suspend        = aqr107_suspend,
+	.resume         = aqr107_resume,
+	.get_sset_count = aqr107_get_sset_count,
+	.get_strings    = aqr107_get_strings,
+	.get_stats      = aqr107_get_stats,
+	.get_features   = aqr115c_get_features,
+	.link_change_notify = aqr107_link_change_notify,
+	.led_brightness_set = aqr_phy_led_brightness_set,
+	.led_hw_is_supported = aqr_phy_led_hw_is_supported,
+	.led_hw_control_set = aqr_phy_led_hw_control_set,
+	.led_hw_control_get = aqr_phy_led_hw_control_get,
+	.led_polarity_set = aqr_phy_led_polarity_set,
+},
+{
+	PHY_ID_MATCH_MODEL(PHY_ID_AQR813),
+	.name		= "Aquantia AQR813",
+	.probe		= aqr107_probe,
+	.get_rate_matching = aqr107_get_rate_matching,
+	.config_init	= aqr107_config_init,
+	.config_aneg    = aqr_config_aneg,
+	.config_intr	= aqr_config_intr,
+	.handle_interrupt = aqr_handle_interrupt,
+	.read_status	= aqr107_read_status,
+	.get_tunable    = aqr107_get_tunable,
+	.set_tunable    = aqr107_set_tunable,
+	.suspend	= aqr107_suspend,
+	.resume		= aqr107_resume,
+	.get_sset_count	= aqr107_get_sset_count,
+	.get_strings	= aqr107_get_strings,
+	.get_stats	= aqr107_get_stats,
 	.link_change_notify = aqr107_link_change_notify,
+	.led_brightness_set = aqr_phy_led_brightness_set,
+	.led_hw_is_supported = aqr_phy_led_hw_is_supported,
+	.led_hw_control_set = aqr_phy_led_hw_control_set,
+	.led_hw_control_get = aqr_phy_led_hw_control_get,
+	.led_polarity_set = aqr_phy_led_polarity_set,
 },
 };
 
@@ -894,9 +1142,15 @@
 	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },
 	{ PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
 	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
+	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR111) },
+	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) },
 	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR112) },
 	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },
+	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },
 	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
+	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR114C) },
+	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR115C) },
+	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
 	{ }
 };
 
--- linux-qcom-6.8.0.orig/drivers/net/phy/at803x.c
+++ linux-qcom-6.8.0/drivers/net/phy/at803x.c
@@ -1503,7 +1503,7 @@
 
 static int at8031_probe(struct phy_device *phydev)
 {
-	struct at803x_priv *priv = phydev->priv;
+	struct at803x_priv *priv;
 	int mode_cfg;
 	int ccr;
 	int ret;
@@ -1512,6 +1512,8 @@
 	if (ret)
 		return ret;
 
+	priv = phydev->priv;
+
 	/* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping
 	 * options.
 	 */
--- linux-qcom-6.8.0.orig/drivers/net/phy/bcm84881.c
+++ linux-qcom-6.8.0/drivers/net/phy/bcm84881.c
@@ -132,7 +132,7 @@
 
 	bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR);
 	if (bmsr < 0)
-		return val;
+		return bmsr;
 
 	return !!(val & MDIO_AN_STAT1_COMPLETE) &&
 	       !!(bmsr & BMSR_ANEGCOMPLETE);
@@ -158,7 +158,7 @@
 
 	bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR);
 	if (bmsr < 0)
-		return val;
+		return bmsr;
 
 	phydev->autoneg_complete = !!(val & MDIO_AN_STAT1_COMPLETE) &&
 				   !!(bmsr & BMSR_ANEGCOMPLETE);
--- linux-qcom-6.8.0.orig/drivers/net/phy/dp83822.c
+++ linux-qcom-6.8.0/drivers/net/phy/dp83822.c
@@ -40,8 +40,8 @@
 /* Control Register 2 bits */
 #define DP83822_FX_ENABLE	BIT(14)
 
-#define DP83822_HW_RESET	BIT(15)
-#define DP83822_SW_RESET	BIT(14)
+#define DP83822_SW_RESET	BIT(15)
+#define DP83822_DIG_RESTART	BIT(14)
 
 /* PHY STS bits */
 #define DP83822_PHYSTS_DUPLEX			BIT(2)
@@ -380,7 +380,7 @@
 {
 	struct dp83822_private *dp83822 = phydev->priv;
 	struct device *dev = &phydev->mdio.dev;
-	int rgmii_delay;
+	int rgmii_delay = 0;
 	s32 rx_int_delay;
 	s32 tx_int_delay;
 	int err = 0;
@@ -390,30 +390,33 @@
 		rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
 						      true);
 
-		if (rx_int_delay <= 0)
-			rgmii_delay = 0;
-		else
-			rgmii_delay = DP83822_RX_CLK_SHIFT;
+		/* Set DP83822_RX_CLK_SHIFT to enable rx clk internal delay */
+		if (rx_int_delay > 0)
+			rgmii_delay |= DP83822_RX_CLK_SHIFT;
 
 		tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
 						      false);
+
+		/* Set DP83822_TX_CLK_SHIFT to disable tx clk internal delay */
 		if (tx_int_delay <= 0)
-			rgmii_delay &= ~DP83822_TX_CLK_SHIFT;
-		else
 			rgmii_delay |= DP83822_TX_CLK_SHIFT;
 
-		if (rgmii_delay) {
-			err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
-					       MII_DP83822_RCSR, rgmii_delay);
-			if (err)
-				return err;
-		}
+		err = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR,
+				     DP83822_RX_CLK_SHIFT | DP83822_TX_CLK_SHIFT, rgmii_delay);
+		if (err)
+			return err;
 
-		phy_set_bits_mmd(phydev, DP83822_DEVADDR,
-					MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
+		err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
+				       MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
+
+		if (err)
+			return err;
 	} else {
-		phy_clear_bits_mmd(phydev, DP83822_DEVADDR,
-					MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
+		err = phy_clear_bits_mmd(phydev, DP83822_DEVADDR,
+					 MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
+
+		if (err)
+			return err;
 	}
 
 	if (dp83822->fx_enabled) {
--- linux-qcom-6.8.0.orig/drivers/net/phy/dp83848.c
+++ linux-qcom-6.8.0/drivers/net/phy/dp83848.c
@@ -147,6 +147,8 @@
 		/* IRQ related */				\
 		.config_intr	= dp83848_config_intr,		\
 		.handle_interrupt = dp83848_handle_interrupt,	\
+								\
+		.flags		= PHY_RST_AFTER_CLK_EN,		\
 	}
 
 static struct phy_driver dp83848_driver[] = {
--- linux-qcom-6.8.0.orig/drivers/net/phy/dp83869.c
+++ linux-qcom-6.8.0/drivers/net/phy/dp83869.c
@@ -153,19 +153,31 @@
 	int mode;
 };
 
+static int dp83869_config_aneg(struct phy_device *phydev)
+{
+	struct dp83869_private *dp83869 = phydev->priv;
+
+	if (dp83869->mode != DP83869_RGMII_1000_BASE)
+		return genphy_config_aneg(phydev);
+
+	return genphy_c37_config_aneg(phydev);
+}
+
 static int dp83869_read_status(struct phy_device *phydev)
 {
 	struct dp83869_private *dp83869 = phydev->priv;
 	int ret;
 
+	if (dp83869->mode == DP83869_RGMII_1000_BASE)
+		return genphy_c37_read_status(phydev);
+
 	ret = genphy_read_status(phydev);
 	if (ret)
 		return ret;
 
-	if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported)) {
+	if (dp83869->mode == DP83869_RGMII_100_BASE) {
 		if (phydev->link) {
-			if (dp83869->mode == DP83869_RGMII_100_BASE)
-				phydev->speed = SPEED_100;
+			phydev->speed = SPEED_100;
 		} else {
 			phydev->speed = SPEED_UNKNOWN;
 			phydev->duplex = DUPLEX_UNKNOWN;
@@ -645,7 +657,6 @@
 		     phydev->supported);
 
 	linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported);
-	linkmode_set_bit(ADVERTISED_FIBRE, phydev->advertising);
 
 	if (dp83869->mode == DP83869_RGMII_1000_BASE) {
 		linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
@@ -695,7 +706,8 @@
 	phy_ctrl_val = dp83869->mode;
 	if (phydev->interface == PHY_INTERFACE_MODE_MII) {
 		if (dp83869->mode == DP83869_100M_MEDIA_CONVERT ||
-		    dp83869->mode == DP83869_RGMII_100_BASE) {
+		    dp83869->mode == DP83869_RGMII_100_BASE ||
+		    dp83869->mode == DP83869_RGMII_COPPER_ETHERNET) {
 			phy_ctrl_val |= DP83869_OP_MODE_MII;
 		} else {
 			phydev_err(phydev, "selected op-mode is not valid with MII mode\n");
@@ -898,6 +910,7 @@
 	.soft_reset	= dp83869_phy_reset,			\
 	.config_intr	= dp83869_config_intr,			\
 	.handle_interrupt = dp83869_handle_interrupt,		\
+	.config_aneg    = dp83869_config_aneg,                  \
 	.read_status	= dp83869_read_status,			\
 	.get_tunable	= dp83869_get_tunable,			\
 	.set_tunable	= dp83869_set_tunable,			\
--- linux-qcom-6.8.0.orig/drivers/net/phy/dp83tg720.c
+++ linux-qcom-6.8.0/drivers/net/phy/dp83tg720.c
@@ -17,6 +17,11 @@
 #define DP83TG720S_PHY_RESET			0x1f
 #define DP83TG720S_HW_RESET			BIT(15)
 
+#define DP83TG720S_LPS_CFG3			0x18c
+/* Power modes are documented as bit fields but used as values */
+/* Power Mode 0 is Normal mode */
+#define DP83TG720S_LPS_CFG3_PWR_MODE_0		BIT(0)
+
 #define DP83TG720S_RGMII_DELAY_CTRL		0x602
 /* In RGMII mode, Enable or disable the internal delay for RXD */
 #define DP83TG720S_RGMII_RX_CLK_SEL		BIT(1)
@@ -31,11 +36,20 @@
 
 static int dp83tg720_config_aneg(struct phy_device *phydev)
 {
+	int ret;
+
 	/* Autoneg is not supported and this PHY supports only one speed.
 	 * We need to care only about master/slave configuration if it was
 	 * changed by user.
 	 */
-	return genphy_c45_pma_baset1_setup_master_slave(phydev);
+	ret = genphy_c45_pma_baset1_setup_master_slave(phydev);
+	if (ret)
+		return ret;
+
+	/* Re-read role configuration to make changes visible even if
+	 * the link is in administrative down state.
+	 */
+	return genphy_c45_pma_baset1_read_master_slave(phydev);
 }
 
 static int dp83tg720_read_status(struct phy_device *phydev)
@@ -64,6 +78,8 @@
 			return ret;
 
 		/* After HW reset we need to restore master/slave configuration.
+		 * genphy_c45_pma_baset1_read_master_slave() call will be done
+		 * by the dp83tg720_config_aneg() function.
 		 */
 		ret = dp83tg720_config_aneg(phydev);
 		if (ret)
@@ -154,10 +170,24 @@
 	 */
 	usleep_range(1000, 2000);
 
-	if (phy_interface_is_rgmii(phydev))
-		return dp83tg720_config_rgmii_delay(phydev);
+	if (phy_interface_is_rgmii(phydev)) {
+		ret = dp83tg720_config_rgmii_delay(phydev);
+		if (ret)
+			return ret;
+	}
+
+	/* In case the PHY is bootstrapped in managed mode, we need to
+	 * wake it.
+	 */
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_LPS_CFG3,
+			    DP83TG720S_LPS_CFG3_PWR_MODE_0);
+	if (ret)
+		return ret;
 
-	return 0;
+	/* Make role configuration visible for ethtool on init and after
+	 * rest.
+	 */
+	return genphy_c45_pma_baset1_read_master_slave(phydev);
 }
 
 static struct phy_driver dp83tg720_driver[] = {
--- linux-qcom-6.8.0.orig/drivers/net/phy/marvell.c
+++ linux-qcom-6.8.0/drivers/net/phy/marvell.c
@@ -33,6 +33,7 @@
 #include <linux/bitfield.h>
 #include <linux/of.h>
 #include <linux/sfp.h>
+#include <linux/dmi.h>
 
 #include <linux/io.h>
 #include <asm/irq.h>
@@ -312,6 +313,16 @@
 	s8 pair;
 };
 
+static const struct dmi_system_id skip_config_led_tbl[] = {
+	{
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Dell EMC"),
+			DMI_MATCH(DMI_BOARD_NAME, "0d370eed-89ca-4dc0-a365-e9904c4c62bb"),
+		},
+	},
+	{}
+};
+
 static int marvell_read_page(struct phy_device *phydev)
 {
 	return __phy_read(phydev, MII_MARVELL_PHY_PAGE);
@@ -759,6 +770,9 @@
 	u16 def_config;
 	int err;
 
+	if (dmi_check_system(skip_config_led_tbl))
+		return;
+
 	switch (MARVELL_PHY_FAMILY_ID(phydev->phy_id)) {
 	/* Default PHY LED config: LED[0] .. Link, LED[1] .. Activity */
 	case MARVELL_PHY_FAMILY_ID(MARVELL_PHY_ID_88E1121R):
--- linux-qcom-6.8.0.orig/drivers/net/phy/mediatek-ge-soc.c
+++ linux-qcom-6.8.0/drivers/net/phy/mediatek-ge-soc.c
@@ -216,6 +216,9 @@
 #define   MTK_PHY_LED_ON_LINK1000		BIT(0)
 #define   MTK_PHY_LED_ON_LINK100		BIT(1)
 #define   MTK_PHY_LED_ON_LINK10			BIT(2)
+#define   MTK_PHY_LED_ON_LINK			(MTK_PHY_LED_ON_LINK10 |\
+						 MTK_PHY_LED_ON_LINK100 |\
+						 MTK_PHY_LED_ON_LINK1000)
 #define   MTK_PHY_LED_ON_LINKDOWN		BIT(3)
 #define   MTK_PHY_LED_ON_FDX			BIT(4) /* Full duplex */
 #define   MTK_PHY_LED_ON_HDX			BIT(5) /* Half duplex */
@@ -231,6 +234,12 @@
 #define   MTK_PHY_LED_BLINK_100RX		BIT(3)
 #define   MTK_PHY_LED_BLINK_10TX		BIT(4)
 #define   MTK_PHY_LED_BLINK_10RX		BIT(5)
+#define   MTK_PHY_LED_BLINK_RX			(MTK_PHY_LED_BLINK_10RX |\
+						 MTK_PHY_LED_BLINK_100RX |\
+						 MTK_PHY_LED_BLINK_1000RX)
+#define   MTK_PHY_LED_BLINK_TX			(MTK_PHY_LED_BLINK_10TX |\
+						 MTK_PHY_LED_BLINK_100TX |\
+						 MTK_PHY_LED_BLINK_1000TX)
 #define   MTK_PHY_LED_BLINK_COLLISION		BIT(6)
 #define   MTK_PHY_LED_BLINK_RX_CRC_ERR		BIT(7)
 #define   MTK_PHY_LED_BLINK_RX_IDLE_ERR		BIT(8)
@@ -1247,11 +1256,9 @@
 	if (blink < 0)
 		return -EIO;
 
-	if ((on & (MTK_PHY_LED_ON_LINK1000 | MTK_PHY_LED_ON_LINK100 |
-		   MTK_PHY_LED_ON_LINK10)) ||
-	    (blink & (MTK_PHY_LED_BLINK_1000RX | MTK_PHY_LED_BLINK_100RX |
-		      MTK_PHY_LED_BLINK_10RX | MTK_PHY_LED_BLINK_1000TX |
-		      MTK_PHY_LED_BLINK_100TX | MTK_PHY_LED_BLINK_10TX)))
+	if ((on & (MTK_PHY_LED_ON_LINK | MTK_PHY_LED_ON_FDX | MTK_PHY_LED_ON_HDX |
+		   MTK_PHY_LED_ON_LINKDOWN)) ||
+	    (blink & (MTK_PHY_LED_BLINK_RX | MTK_PHY_LED_BLINK_TX)))
 		set_bit(bit_netdev, &priv->led_state);
 	else
 		clear_bit(bit_netdev, &priv->led_state);
@@ -1269,7 +1276,7 @@
 	if (!rules)
 		return 0;
 
-	if (on & (MTK_PHY_LED_ON_LINK1000 | MTK_PHY_LED_ON_LINK100 | MTK_PHY_LED_ON_LINK10))
+	if (on & MTK_PHY_LED_ON_LINK)
 		*rules |= BIT(TRIGGER_NETDEV_LINK);
 
 	if (on & MTK_PHY_LED_ON_LINK10)
@@ -1287,10 +1294,10 @@
 	if (on & MTK_PHY_LED_ON_HDX)
 		*rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
 
-	if (blink & (MTK_PHY_LED_BLINK_1000RX | MTK_PHY_LED_BLINK_100RX | MTK_PHY_LED_BLINK_10RX))
+	if (blink & MTK_PHY_LED_BLINK_RX)
 		*rules |= BIT(TRIGGER_NETDEV_RX);
 
-	if (blink & (MTK_PHY_LED_BLINK_1000TX | MTK_PHY_LED_BLINK_100TX | MTK_PHY_LED_BLINK_10TX))
+	if (blink & MTK_PHY_LED_BLINK_TX)
 		*rules |= BIT(TRIGGER_NETDEV_TX);
 
 	return 0;
@@ -1323,15 +1330,19 @@
 		on |= MTK_PHY_LED_ON_LINK1000;
 
 	if (rules & BIT(TRIGGER_NETDEV_RX)) {
-		blink |= MTK_PHY_LED_BLINK_10RX  |
-			 MTK_PHY_LED_BLINK_100RX |
-			 MTK_PHY_LED_BLINK_1000RX;
+		blink |= (on & MTK_PHY_LED_ON_LINK) ?
+			  (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10RX : 0) |
+			   ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100RX : 0) |
+			   ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000RX : 0)) :
+			  MTK_PHY_LED_BLINK_RX;
 	}
 
 	if (rules & BIT(TRIGGER_NETDEV_TX)) {
-		blink |= MTK_PHY_LED_BLINK_10TX  |
-			 MTK_PHY_LED_BLINK_100TX |
-			 MTK_PHY_LED_BLINK_1000TX;
+		blink |= (on & MTK_PHY_LED_ON_LINK) ?
+			  (((on & MTK_PHY_LED_ON_LINK10) ? MTK_PHY_LED_BLINK_10TX : 0) |
+			   ((on & MTK_PHY_LED_ON_LINK100) ? MTK_PHY_LED_BLINK_100TX : 0) |
+			   ((on & MTK_PHY_LED_ON_LINK1000) ? MTK_PHY_LED_BLINK_1000TX : 0)) :
+			  MTK_PHY_LED_BLINK_TX;
 	}
 
 	if (blink || on)
@@ -1344,9 +1355,7 @@
 				MTK_PHY_LED0_ON_CTRL,
 			     MTK_PHY_LED_ON_FDX     |
 			     MTK_PHY_LED_ON_HDX     |
-			     MTK_PHY_LED_ON_LINK10  |
-			     MTK_PHY_LED_ON_LINK100 |
-			     MTK_PHY_LED_ON_LINK1000,
+			     MTK_PHY_LED_ON_LINK,
 			     on);
 
 	if (ret)
--- linux-qcom-6.8.0.orig/drivers/net/phy/micrel.c
+++ linux-qcom-6.8.0/drivers/net/phy/micrel.c
@@ -336,10 +336,12 @@
 struct kszphy_priv {
 	struct kszphy_ptp_priv ptp_priv;
 	const struct kszphy_type *type;
+	struct clk *clk;
 	int led_mode;
 	u16 vct_ctrl1000;
 	bool rmii_ref_clk_sel;
 	bool rmii_ref_clk_sel_val;
+	bool clk_enable;
 	u64 stats[ARRAY_SIZE(kszphy_hw_stats)];
 };
 
@@ -770,6 +772,17 @@
 {
 	int ret;
 
+	/* Chip can be powered down by the bootstrap code. */
+	ret = phy_read(phydev, MII_BMCR);
+	if (ret < 0)
+		return ret;
+	if (ret & BMCR_PDOWN) {
+		ret = phy_write(phydev, MII_BMCR, ret & ~BMCR_PDOWN);
+		if (ret < 0)
+			return ret;
+		usleep_range(1000, 2000);
+	}
+
 	ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_DEVID1, 0xB61A);
 	if (ret)
 		return ret;
@@ -1282,6 +1295,8 @@
 	const struct device *dev_walker;
 	int ret;
 
+	phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
+
 	dev_walker = &phydev->mdio.dev;
 	do {
 		of_node = dev_walker->of_node;
@@ -1331,28 +1346,30 @@
 #define MII_KSZ9131_AUTO_MDIX		0x1C
 #define MII_KSZ9131_AUTO_MDI_SET	BIT(7)
 #define MII_KSZ9131_AUTO_MDIX_SWAP_OFF	BIT(6)
+#define MII_KSZ9131_DIG_AXAN_STS	0x14
+#define MII_KSZ9131_DIG_AXAN_STS_LINK_DET	BIT(14)
+#define MII_KSZ9131_DIG_AXAN_STS_A_SELECT	BIT(12)
 
 static int ksz9131_mdix_update(struct phy_device *phydev)
 {
 	int ret;
 
-	ret = phy_read(phydev, MII_KSZ9131_AUTO_MDIX);
-	if (ret < 0)
-		return ret;
-
-	if (ret & MII_KSZ9131_AUTO_MDIX_SWAP_OFF) {
-		if (ret & MII_KSZ9131_AUTO_MDI_SET)
-			phydev->mdix_ctrl = ETH_TP_MDI;
-		else
-			phydev->mdix_ctrl = ETH_TP_MDI_X;
+	if (phydev->mdix_ctrl != ETH_TP_MDI_AUTO) {
+		phydev->mdix = phydev->mdix_ctrl;
 	} else {
-		phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
-	}
+		ret = phy_read(phydev, MII_KSZ9131_DIG_AXAN_STS);
+		if (ret < 0)
+			return ret;
 
-	if (ret & MII_KSZ9131_AUTO_MDI_SET)
-		phydev->mdix = ETH_TP_MDI;
-	else
-		phydev->mdix = ETH_TP_MDI_X;
+		if (ret & MII_KSZ9131_DIG_AXAN_STS_LINK_DET) {
+			if (ret & MII_KSZ9131_DIG_AXAN_STS_A_SELECT)
+				phydev->mdix = ETH_TP_MDI;
+			else
+				phydev->mdix = ETH_TP_MDI_X;
+		} else {
+			phydev->mdix = ETH_TP_MDI_INVALID;
+		}
+	}
 
 	return 0;
 }
@@ -1843,7 +1860,7 @@
 	{0x1c, 0x20, 0xeeee},
 };
 
-static int ksz9477_config_init(struct phy_device *phydev)
+static int ksz9477_phy_errata(struct phy_device *phydev)
 {
 	int err;
 	int i;
@@ -1871,16 +1888,30 @@
 			return err;
 	}
 
+	err = genphy_restart_aneg(phydev);
+	if (err)
+		return err;
+
+	return err;
+}
+
+static int ksz9477_config_init(struct phy_device *phydev)
+{
+	int err;
+
+	/* Only KSZ9897 family of switches needs this fix. */
+	if ((phydev->phy_id & 0xf) == 1) {
+		err = ksz9477_phy_errata(phydev);
+		if (err)
+			return err;
+	}
+
 	/* According to KSZ9477 Errata DS80000754C (Module 4) all EEE modes
 	 * in this switch shall be regarded as broken.
 	 */
 	if (phydev->dev_flags & MICREL_NO_EEE)
 		phydev->eee_broken_modes = -1;
 
-	err = genphy_restart_aneg(phydev);
-	if (err)
-		return err;
-
 	return kszphy_config_init(phydev);
 }
 
@@ -1927,6 +1958,46 @@
 		data[i] = kszphy_get_stat(phydev, i);
 }
 
+static void kszphy_enable_clk(struct phy_device *phydev)
+{
+	struct kszphy_priv *priv = phydev->priv;
+
+	if (!priv->clk_enable && priv->clk) {
+		clk_prepare_enable(priv->clk);
+		priv->clk_enable = true;
+	}
+}
+
+static void kszphy_disable_clk(struct phy_device *phydev)
+{
+	struct kszphy_priv *priv = phydev->priv;
+
+	if (priv->clk_enable && priv->clk) {
+		clk_disable_unprepare(priv->clk);
+		priv->clk_enable = false;
+	}
+}
+
+static int kszphy_generic_resume(struct phy_device *phydev)
+{
+	kszphy_enable_clk(phydev);
+
+	return genphy_resume(phydev);
+}
+
+static int kszphy_generic_suspend(struct phy_device *phydev)
+{
+	int ret;
+
+	ret = genphy_suspend(phydev);
+	if (ret)
+		return ret;
+
+	kszphy_disable_clk(phydev);
+
+	return 0;
+}
+
 static int kszphy_suspend(struct phy_device *phydev)
 {
 	/* Disable PHY Interrupts */
@@ -1936,7 +2007,7 @@
 			phydev->drv->config_intr(phydev);
 	}
 
-	return genphy_suspend(phydev);
+	return kszphy_generic_suspend(phydev);
 }
 
 static void kszphy_parse_led_mode(struct phy_device *phydev)
@@ -1967,7 +2038,9 @@
 {
 	int ret;
 
-	genphy_resume(phydev);
+	ret = kszphy_generic_resume(phydev);
+	if (ret)
+		return ret;
 
 	/* After switching from power-down to normal mode, an internal global
 	 * reset is automatically generated. Wait a minimum of 1 ms before
@@ -1989,6 +2062,97 @@
 	return 0;
 }
 
+/* Because of errata DS80000700A, receiver error following software
+ * power down. Suspend and resume callbacks only disable and enable
+ * external rmii reference clock.
+ */
+static int ksz8041_resume(struct phy_device *phydev)
+{
+	kszphy_enable_clk(phydev);
+
+	return 0;
+}
+
+static int ksz8041_suspend(struct phy_device *phydev)
+{
+	kszphy_disable_clk(phydev);
+
+	return 0;
+}
+
+static int ksz9477_resume(struct phy_device *phydev)
+{
+	int ret;
+
+	/* No need to initialize registers if not powered down. */
+	ret = phy_read(phydev, MII_BMCR);
+	if (ret < 0)
+		return ret;
+	if (!(ret & BMCR_PDOWN))
+		return 0;
+
+	genphy_resume(phydev);
+
+	/* After switching from power-down to normal mode, an internal global
+	 * reset is automatically generated. Wait a minimum of 1 ms before
+	 * read/write access to the PHY registers.
+	 */
+	usleep_range(1000, 2000);
+
+	/* Only KSZ9897 family of switches needs this fix. */
+	if ((phydev->phy_id & 0xf) == 1) {
+		ret = ksz9477_phy_errata(phydev);
+		if (ret)
+			return ret;
+	}
+
+	/* Enable PHY Interrupts */
+	if (phy_interrupt_is_valid(phydev)) {
+		phydev->interrupts = PHY_INTERRUPT_ENABLED;
+		if (phydev->drv->config_intr)
+			phydev->drv->config_intr(phydev);
+	}
+
+	return 0;
+}
+
+static int ksz8061_resume(struct phy_device *phydev)
+{
+	int ret;
+
+	/* This function can be called twice when the Ethernet device is on. */
+	ret = phy_read(phydev, MII_BMCR);
+	if (ret < 0)
+		return ret;
+	if (!(ret & BMCR_PDOWN))
+		return 0;
+
+	ret = kszphy_generic_resume(phydev);
+	if (ret)
+		return ret;
+
+	usleep_range(1000, 2000);
+
+	/* Re-program the value after chip is reset. */
+	ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_DEVID1, 0xB61A);
+	if (ret)
+		return ret;
+
+	/* Enable PHY Interrupts */
+	if (phy_interrupt_is_valid(phydev)) {
+		phydev->interrupts = PHY_INTERRUPT_ENABLED;
+		if (phydev->drv->config_intr)
+			phydev->drv->config_intr(phydev);
+	}
+
+	return 0;
+}
+
+static int ksz8061_suspend(struct phy_device *phydev)
+{
+	return kszphy_suspend(phydev);
+}
+
 static int kszphy_probe(struct phy_device *phydev)
 {
 	const struct kszphy_type *type = phydev->drv->driver_data;
@@ -2029,10 +2193,14 @@
 	} else if (!clk) {
 		/* unnamed clock from the generic ethernet-phy binding */
 		clk = devm_clk_get_optional_enabled(&phydev->mdio.dev, NULL);
-		if (IS_ERR(clk))
-			return PTR_ERR(clk);
 	}
 
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	clk_disable_unprepare(clk);
+	priv->clk = clk;
+
 	if (ksz8041_fiber_mode(phydev))
 		phydev->port = PORT_FIBRE;
 
@@ -2416,6 +2584,7 @@
 	struct lan8814_ptp_rx_ts *rx_ts, *tmp;
 	int txcfg = 0, rxcfg = 0;
 	int pkt_ts_enable;
+	int tx_mod;
 
 	ptp_priv->hwts_tx_type = config->tx_type;
 	ptp_priv->rx_filter = config->rx_filter;
@@ -2462,9 +2631,14 @@
 	lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_RX_TIMESTAMP_EN, pkt_ts_enable);
 	lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_TIMESTAMP_EN, pkt_ts_enable);
 
-	if (ptp_priv->hwts_tx_type == HWTSTAMP_TX_ONESTEP_SYNC)
+	tx_mod = lanphy_read_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD);
+	if (ptp_priv->hwts_tx_type == HWTSTAMP_TX_ONESTEP_SYNC) {
+		lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD,
+				      tx_mod | PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_);
+	} else if (ptp_priv->hwts_tx_type == HWTSTAMP_TX_ON) {
 		lanphy_write_page_reg(ptp_priv->phydev, 5, PTP_TX_MOD,
-				      PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_);
+				      tx_mod & ~PTP_TX_MOD_TX_PTP_SYNC_TS_INSERT_);
+	}
 
 	if (config->rx_filter != HWTSTAMP_FILTER_NONE)
 		lan8814_config_ts_intr(ptp_priv->phydev, true);
@@ -2522,7 +2696,7 @@
 	}
 }
 
-static void lan8814_get_sig_rx(struct sk_buff *skb, u16 *sig)
+static bool lan8814_get_sig_rx(struct sk_buff *skb, u16 *sig)
 {
 	struct ptp_header *ptp_header;
 	u32 type;
@@ -2532,7 +2706,11 @@
 	ptp_header = ptp_parse_header(skb, type);
 	skb_pull_inline(skb, ETH_HLEN);
 
+	if (!ptp_header)
+		return false;
+
 	*sig = (__force u16)(ntohs(ptp_header->sequence_id));
+	return true;
 }
 
 static bool lan8814_match_rx_skb(struct kszphy_ptp_priv *ptp_priv,
@@ -2544,7 +2722,8 @@
 	bool ret = false;
 	u16 skb_sig;
 
-	lan8814_get_sig_rx(skb, &skb_sig);
+	if (!lan8814_get_sig_rx(skb, &skb_sig))
+		return ret;
 
 	/* Iterate over all RX timestamps and match it with the received skbs */
 	spin_lock_irqsave(&ptp_priv->rx_ts_lock, flags);
@@ -2824,7 +3003,7 @@
 	return 0;
 }
 
-static void lan8814_get_sig_tx(struct sk_buff *skb, u16 *sig)
+static bool lan8814_get_sig_tx(struct sk_buff *skb, u16 *sig)
 {
 	struct ptp_header *ptp_header;
 	u32 type;
@@ -2832,7 +3011,11 @@
 	type = ptp_classify_raw(skb);
 	ptp_header = ptp_parse_header(skb, type);
 
+	if (!ptp_header)
+		return false;
+
 	*sig = (__force u16)(ntohs(ptp_header->sequence_id));
+	return true;
 }
 
 static void lan8814_match_tx_skb(struct kszphy_ptp_priv *ptp_priv,
@@ -2846,7 +3029,8 @@
 
 	spin_lock_irqsave(&ptp_priv->tx_queue.lock, flags);
 	skb_queue_walk_safe(&ptp_priv->tx_queue, skb, skb_tmp) {
-		lan8814_get_sig_tx(skb, &skb_sig);
+		if (!lan8814_get_sig_tx(skb, &skb_sig))
+			continue;
 
 		if (memcmp(&skb_sig, &seq_id, sizeof(seq_id)))
 			continue;
@@ -2900,7 +3084,8 @@
 
 	spin_lock_irqsave(&ptp_priv->rx_queue.lock, flags);
 	skb_queue_walk_safe(&ptp_priv->rx_queue, skb, skb_tmp) {
-		lan8814_get_sig_rx(skb, &skb_sig);
+		if (!lan8814_get_sig_rx(skb, &skb_sig))
+			continue;
 
 		if (memcmp(&skb_sig, &rx_ts->seq_id, sizeof(rx_ts->seq_id)))
 			continue;
@@ -3458,7 +3643,7 @@
 
 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
 		err = phy_read(phydev, LAN8814_INTS);
-		if (err)
+		if (err < 0)
 			return err;
 
 		/* Enable / disable interrupts. It is OK to enable PTP interrupt
@@ -3474,6 +3659,14 @@
 			return err;
 
 		err = phy_read(phydev, LAN8814_INTS);
+		if (err < 0)
+			return err;
+
+		/* Getting a positive value doesn't mean that is an error, it
+		 * just indicates what was the status. Therefore make sure to
+		 * clear the value and say that there is no error.
+		 */
+		err = 0;
 	}
 
 	return err;
@@ -4613,14 +4806,30 @@
 	return 0;
 }
 
+static int lan8804_resume(struct phy_device *phydev)
+{
+	return kszphy_resume(phydev);
+}
+
+static int lan8804_suspend(struct phy_device *phydev)
+{
+	return kszphy_generic_suspend(phydev);
+}
+
+static int lan8841_resume(struct phy_device *phydev)
+{
+	return kszphy_generic_resume(phydev);
+}
+
 static int lan8841_suspend(struct phy_device *phydev)
 {
 	struct kszphy_priv *priv = phydev->priv;
 	struct kszphy_ptp_priv *ptp_priv = &priv->ptp_priv;
 
-	ptp_cancel_worker_sync(ptp_priv->ptp_clock);
+	if (ptp_priv->ptp_clock)
+		ptp_cancel_worker_sync(ptp_priv->ptp_clock);
 
-	return genphy_suspend(phydev);
+	return kszphy_generic_suspend(phydev);
 }
 
 static struct phy_driver ksphy_driver[] = {
@@ -4680,9 +4889,8 @@
 	.get_sset_count = kszphy_get_sset_count,
 	.get_strings	= kszphy_get_strings,
 	.get_stats	= kszphy_get_stats,
-	/* No suspend/resume callbacks because of errata DS80000700A,
-	 * receiver error following software power down.
-	 */
+	.suspend	= ksz8041_suspend,
+	.resume		= ksz8041_resume,
 }, {
 	.phy_id		= PHY_ID_KSZ8041RNLI,
 	.phy_id_mask	= MICREL_PHY_ID_MASK,
@@ -4755,10 +4963,11 @@
 	/* PHY_BASIC_FEATURES */
 	.probe		= kszphy_probe,
 	.config_init	= ksz8061_config_init,
+	.soft_reset	= genphy_soft_reset,
 	.config_intr	= kszphy_config_intr,
 	.handle_interrupt = kszphy_handle_interrupt,
-	.suspend	= kszphy_suspend,
-	.resume		= kszphy_resume,
+	.suspend	= ksz8061_suspend,
+	.resume		= ksz8061_resume,
 }, {
 	.phy_id		= PHY_ID_KSZ9021,
 	.phy_id_mask	= 0x000ffffe,
@@ -4828,8 +5037,8 @@
 	.get_sset_count	= kszphy_get_sset_count,
 	.get_strings	= kszphy_get_strings,
 	.get_stats	= kszphy_get_stats,
-	.suspend	= genphy_suspend,
-	.resume		= kszphy_resume,
+	.suspend	= lan8804_suspend,
+	.resume		= lan8804_resume,
 	.config_intr	= lan8804_config_intr,
 	.handle_interrupt = lan8804_handle_interrupt,
 }, {
@@ -4847,7 +5056,7 @@
 	.get_strings	= kszphy_get_strings,
 	.get_stats	= kszphy_get_stats,
 	.suspend	= lan8841_suspend,
-	.resume		= genphy_resume,
+	.resume		= lan8841_resume,
 	.cable_test_start	= lan8814_cable_test_start,
 	.cable_test_get_status	= ksz886x_cable_test_get_status,
 }, {
@@ -4912,7 +5121,7 @@
 	.config_intr	= kszphy_config_intr,
 	.handle_interrupt = kszphy_handle_interrupt,
 	.suspend	= genphy_suspend,
-	.resume		= genphy_resume,
+	.resume		= ksz9477_resume,
 	.get_features	= ksz9477_get_features,
 } };
 
@@ -4936,6 +5145,7 @@
 	{ PHY_ID_KSZ8081, MICREL_PHY_ID_MASK },
 	{ PHY_ID_KSZ8873MLL, MICREL_PHY_ID_MASK },
 	{ PHY_ID_KSZ886X, MICREL_PHY_ID_MASK },
+	{ PHY_ID_KSZ9477, MICREL_PHY_ID_MASK },
 	{ PHY_ID_LAN8814, MICREL_PHY_ID_MASK },
 	{ PHY_ID_LAN8804, MICREL_PHY_ID_MASK },
 	{ PHY_ID_LAN8841, MICREL_PHY_ID_MASK },
--- linux-qcom-6.8.0.orig/drivers/net/phy/microchip.c
+++ linux-qcom-6.8.0/drivers/net/phy/microchip.c
@@ -345,6 +345,22 @@
 static void lan88xx_link_change_notify(struct phy_device *phydev)
 {
 	int temp;
+	int ret;
+
+	/* Reset PHY to ensure MII_LPA provides up-to-date information. This
+	 * issue is reproducible only after parallel detection, as described
+	 * in IEEE 802.3-2022, Section 28.2.3.1 ("Parallel detection function"),
+	 * where the link partner does not support auto-negotiation.
+	 */
+	if (phydev->state == PHY_NOLINK) {
+		ret = phy_init_hw(phydev);
+		if (ret < 0)
+			goto link_change_notify_failed;
+
+		ret = _phy_start_aneg(phydev);
+		if (ret < 0)
+			goto link_change_notify_failed;
+	}
 
 	/* At forced 100 F/H mode, chip may fail to set mode correctly
 	 * when cable is switched between long(~50+m) and short one.
@@ -371,6 +387,11 @@
 		temp |= LAN88XX_INT_MASK_MDINTPIN_EN_;
 		phy_write(phydev, LAN88XX_INT_MASK, temp);
 	}
+
+	return;
+
+link_change_notify_failed:
+	phydev_err(phydev, "Link change process failed %pe\n", ERR_PTR(ret));
 }
 
 static struct phy_driver microchip_phy_driver[] = {
--- linux-qcom-6.8.0.orig/drivers/net/phy/microchip_t1.c
+++ linux-qcom-6.8.0/drivers/net/phy/microchip_t1.c
@@ -748,7 +748,7 @@
 	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
 				lan87xx_cable_test_report_trans(detect));
 
-	return 0;
+	return phy_init_hw(phydev);
 }
 
 static int lan87xx_cable_test_get_status(struct phy_device *phydev,
--- linux-qcom-6.8.0.orig/drivers/net/phy/mxl-gpy.c
+++ linux-qcom-6.8.0/drivers/net/phy/mxl-gpy.c
@@ -107,6 +107,7 @@
 
 	u8 fw_major;
 	u8 fw_minor;
+	u32 wolopts;
 
 	/* It takes 3 seconds to fully switch out of loopback mode before
 	 * it can safely re-enter loopback mode. Record the time when
@@ -221,6 +222,15 @@
 }
 #endif
 
+static int gpy_ack_interrupt(struct phy_device *phydev)
+{
+	int ret;
+
+	/* Clear all pending interrupts */
+	ret = phy_read(phydev, PHY_ISTAT);
+	return ret < 0 ? ret : 0;
+}
+
 static int gpy_mbox_read(struct phy_device *phydev, u32 addr)
 {
 	struct gpy_priv *priv = phydev->priv;
@@ -262,16 +272,8 @@
 
 static int gpy_config_init(struct phy_device *phydev)
 {
-	int ret;
-
-	/* Mask all interrupts */
-	ret = phy_write(phydev, PHY_IMASK, 0);
-	if (ret)
-		return ret;
-
-	/* Clear all pending interrupts */
-	ret = phy_read(phydev, PHY_ISTAT);
-	return ret < 0 ? ret : 0;
+	/* Nothing to configure. Configuration Requirement Placeholder */
+	return 0;
 }
 
 static int gpy_probe(struct phy_device *phydev)
@@ -619,11 +621,23 @@
 
 static int gpy_config_intr(struct phy_device *phydev)
 {
+	struct gpy_priv *priv = phydev->priv;
 	u16 mask = 0;
+	int ret;
+
+	ret = gpy_ack_interrupt(phydev);
+	if (ret)
+		return ret;
 
 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
 		mask = PHY_IMASK_MASK;
 
+	if (priv->wolopts & WAKE_MAGIC)
+		mask |= PHY_IMASK_WOL;
+
+	if (priv->wolopts & WAKE_PHY)
+		mask |= PHY_IMASK_LSTC;
+
 	return phy_write(phydev, PHY_IMASK, mask);
 }
 
@@ -670,6 +684,7 @@
 		       struct ethtool_wolinfo *wol)
 {
 	struct net_device *attach_dev = phydev->attached_dev;
+	struct gpy_priv *priv = phydev->priv;
 	int ret;
 
 	if (wol->wolopts & WAKE_MAGIC) {
@@ -717,6 +732,8 @@
 		ret = phy_read(phydev, PHY_ISTAT);
 		if (ret < 0)
 			return ret;
+
+		priv->wolopts |= WAKE_MAGIC;
 	} else {
 		/* Disable magic packet matching */
 		ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2,
@@ -724,6 +741,13 @@
 					 WOL_EN);
 		if (ret < 0)
 			return ret;
+
+		/* Disable the WOL interrupt */
+		ret = phy_clear_bits(phydev, PHY_IMASK, PHY_IMASK_WOL);
+		if (ret < 0)
+			return ret;
+
+		priv->wolopts &= ~WAKE_MAGIC;
 	}
 
 	if (wol->wolopts & WAKE_PHY) {
@@ -740,9 +764,11 @@
 		if (ret & (PHY_IMASK_MASK & ~PHY_IMASK_LSTC))
 			phy_trigger_machine(phydev);
 
+		priv->wolopts |= WAKE_PHY;
 		return 0;
 	}
 
+	priv->wolopts &= ~WAKE_PHY;
 	/* Disable the link state change interrupt */
 	return phy_clear_bits(phydev, PHY_IMASK, PHY_IMASK_LSTC);
 }
@@ -750,18 +776,10 @@
 static void gpy_get_wol(struct phy_device *phydev,
 			struct ethtool_wolinfo *wol)
 {
-	int ret;
+	struct gpy_priv *priv = phydev->priv;
 
 	wol->supported = WAKE_MAGIC | WAKE_PHY;
-	wol->wolopts = 0;
-
-	ret = phy_read_mmd(phydev, MDIO_MMD_VEND2, VPSPEC2_WOL_CTL);
-	if (ret & WOL_EN)
-		wol->wolopts |= WAKE_MAGIC;
-
-	ret = phy_read(phydev, PHY_IMASK);
-	if (ret & PHY_IMASK_LSTC)
-		wol->wolopts |= WAKE_PHY;
+	wol->wolopts = priv->wolopts;
 }
 
 static int gpy_loopback(struct phy_device *phydev, bool enable)
--- linux-qcom-6.8.0.orig/drivers/net/phy/nxp-c45-tja11xx.c
+++ linux-qcom-6.8.0/drivers/net/phy/nxp-c45-tja11xx.c
@@ -1296,6 +1296,8 @@
 	if (ret)
 		return ret;
 
+	usleep_range(2000, 2050);
+
 	return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
 					 VEND1_DEVICE_CONTROL, ret,
 					 !(ret & DEVICE_CONTROL_RESET), 20000,
--- linux-qcom-6.8.0.orig/drivers/net/phy/phy.c
+++ linux-qcom-6.8.0/drivers/net/phy/phy.c
@@ -342,14 +342,19 @@
 		if (mdio_phy_id_is_c45(mii_data->phy_id)) {
 			prtad = mdio_phy_id_prtad(mii_data->phy_id);
 			devad = mdio_phy_id_devad(mii_data->phy_id);
-			mii_data->val_out = mdiobus_c45_read(
-				phydev->mdio.bus, prtad, devad,
-				mii_data->reg_num);
+			ret = mdiobus_c45_read(phydev->mdio.bus, prtad, devad,
+					       mii_data->reg_num);
+
 		} else {
-			mii_data->val_out = mdiobus_read(
-				phydev->mdio.bus, mii_data->phy_id,
-				mii_data->reg_num);
+			ret = mdiobus_read(phydev->mdio.bus, mii_data->phy_id,
+					   mii_data->reg_num);
 		}
+
+		if (ret < 0)
+			return ret;
+
+		mii_data->val_out = ret;
+
 		return 0;
 
 	case SIOCSMIIREG:
--- linux-qcom-6.8.0.orig/drivers/net/phy/phy_device.c
+++ linux-qcom-6.8.0/drivers/net/phy/phy_device.c
@@ -1413,6 +1413,11 @@
 }
 EXPORT_SYMBOL(phy_sfp_probe);
 
+static bool phy_drv_supports_irq(struct phy_driver *phydrv)
+{
+	return phydrv->config_intr && phydrv->handle_interrupt;
+}
+
 /**
  * phy_attach_direct - attach a network device to a given PHY device pointer
  * @dev: network device to attach
@@ -1527,6 +1532,9 @@
 	if (phydev->dev_flags & PHY_F_NO_IRQ)
 		phydev->irq = PHY_POLL;
 
+	if (!phy_drv_supports_irq(phydev->drv) && phy_interrupt_is_valid(phydev))
+		phydev->irq = PHY_POLL;
+
 	/* Port is set to PORT_TP by default and the actual PHY driver will set
 	 * it to different value depending on the PHY configuration. If we have
 	 * the generic PHY driver we can't figure it out, thus set the old
@@ -2706,8 +2714,8 @@
 int genphy_loopback(struct phy_device *phydev, bool enable)
 {
 	if (enable) {
-		u16 val, ctl = BMCR_LOOPBACK;
-		int ret;
+		u16 ctl = BMCR_LOOPBACK;
+		int ret, val;
 
 		ctl |= mii_bmcr_encode_fixed(phydev->speed, phydev->duplex);
 
@@ -2959,7 +2967,7 @@
 	if (delay < 0)
 		return delay;
 
-	if (delay && size == 0)
+	if (size == 0)
 		return delay;
 
 	if (delay < delay_values[0] || delay > delay_values[size - 1]) {
@@ -2992,11 +3000,6 @@
 }
 EXPORT_SYMBOL(phy_get_internal_delay);
 
-static bool phy_drv_supports_irq(struct phy_driver *phydrv)
-{
-	return phydrv->config_intr && phydrv->handle_interrupt;
-}
-
 static int phy_led_set_brightness(struct led_classdev *led_cdev,
 				  enum led_brightness value)
 {
@@ -3084,10 +3087,11 @@
 
 static void phy_leds_unregister(struct phy_device *phydev)
 {
-	struct phy_led *phyled;
+	struct phy_led *phyled, *tmp;
 
-	list_for_each_entry(phyled, &phydev->leds, list) {
+	list_for_each_entry_safe(phyled, tmp, &phydev->leds, list) {
 		led_classdev_unregister(&phyled->led_cdev);
+		list_del(&phyled->list);
 	}
 }
 
@@ -3097,6 +3101,7 @@
 	struct device *dev = &phydev->mdio.dev;
 	struct led_init_data init_data = {};
 	struct led_classdev *cdev;
+	unsigned long modes = 0;
 	struct phy_led *phyled;
 	u32 index;
 	int err;
@@ -3114,6 +3119,21 @@
 	if (index > U8_MAX)
 		return -EINVAL;
 
+	if (of_property_read_bool(led, "active-low"))
+		set_bit(PHY_LED_ACTIVE_LOW, &modes);
+	if (of_property_read_bool(led, "inactive-high-impedance"))
+		set_bit(PHY_LED_INACTIVE_HIGH_IMPEDANCE, &modes);
+
+	if (modes) {
+		/* Return error if asked to set polarity modes but not supported */
+		if (!phydev->drv->led_polarity_set)
+			return -EINVAL;
+
+		err = phydev->drv->led_polarity_set(phydev, index, modes);
+		if (err)
+			return err;
+	}
+
 	phyled->index = index;
 	if (phydev->drv->led_brightness_set)
 		cdev->brightness_set_blocking = phy_led_set_brightness;
@@ -3166,11 +3186,13 @@
 		err = of_phy_led(phydev, led);
 		if (err) {
 			of_node_put(led);
+			of_node_put(leds);
 			phy_leds_unregister(phydev);
 			return err;
 		}
 	}
 
+	of_node_put(leds);
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/phy/phylink.c
+++ linux-qcom-6.8.0/drivers/net/phy/phylink.c
@@ -78,7 +78,7 @@
 	unsigned int pcs_neg_mode;
 	unsigned int pcs_state;
 
-	bool mac_link_dropped;
+	bool link_failed;
 	bool using_mac_select_pcs;
 
 	struct sfp_bus *sfp_bus;
@@ -691,13 +691,17 @@
 	}
 
 	/* Then validate the link parameters with the MAC */
-	if (pl->mac_ops->mac_get_caps)
-		capabilities = pl->mac_ops->mac_get_caps(pl->config,
-							 state->interface);
-	else
-		capabilities = pl->config->mac_capabilities;
+	if (pl->mac_ops->validate) {
+		pl->mac_ops->validate(pl->config, supported, state);
+	} else {
+		if (pl->mac_ops->mac_get_caps)
+			capabilities = pl->mac_ops->mac_get_caps(pl->config,
+							state->interface);
+		else
+			capabilities = pl->config->mac_capabilities;
 
-	phylink_validate_mask_caps(supported, state, capabilities);
+		phylink_validate_mask_caps(supported, state, capabilities);
+	}
 
 	return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
 }
@@ -1042,6 +1046,21 @@
 		mod_timer(&pl->link_poll, jiffies + HZ);
 }
 
+int phylink_pcs_pre_init(struct phylink *pl, struct phylink_pcs *pcs)
+{
+	int ret = 0;
+
+	/* Signal to PCS driver that MAC requires RX clock for init */
+	if (pl->config->mac_requires_rxc)
+		pcs->rxc_always_on = true;
+
+	if (pcs->ops->pcs_pre_init)
+		ret = pcs->ops->pcs_pre_init(pcs);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(phylink_pcs_pre_init);
+
 static void phylink_mac_config(struct phylink *pl,
 			       const struct phylink_link_state *state)
 {
@@ -1448,9 +1467,9 @@
 		cur_link_state = pl->old_link_state;
 
 	if (pl->phylink_disable_state) {
-		pl->mac_link_dropped = false;
+		pl->link_failed = false;
 		link_state.link = false;
-	} else if (pl->mac_link_dropped) {
+	} else if (pl->link_failed) {
 		link_state.link = false;
 		retrigger = true;
 	} else {
@@ -1545,7 +1564,7 @@
 			phylink_link_up(pl, link_state);
 	}
 	if (!link_state.link && retrigger) {
-		pl->mac_link_dropped = false;
+		pl->link_failed = false;
 		queue_work(system_power_efficient_wq, &pl->resolve);
 	}
 	mutex_unlock(&pl->state_mutex);
@@ -1766,6 +1785,8 @@
 		pl->phy_state.pause |= MLO_PAUSE_RX;
 	pl->phy_state.interface = phydev->interface;
 	pl->phy_state.link = up;
+	if (!up)
+		pl->link_failed = true;
 	mutex_unlock(&pl->state_mutex);
 
 	phylink_run_resolve(pl);
@@ -1923,6 +1944,8 @@
 static int phylink_attach_phy(struct phylink *pl, struct phy_device *phy,
 			      phy_interface_t interface)
 {
+	u32 flags = 0;
+
 	if (WARN_ON(pl->cfg_link_an_mode == MLO_AN_FIXED ||
 		    (pl->cfg_link_an_mode == MLO_AN_INBAND &&
 		     phy_interface_mode_is_8023z(interface) && !pl->sfp_bus)))
@@ -1931,7 +1954,10 @@
 	if (pl->phydev)
 		return -EBUSY;
 
-	return phy_attach_direct(pl->netdev, phy, 0, interface);
+	if (pl->config->mac_requires_rxc)
+		flags |= PHY_F_RXC_ALWAYS_ON;
+
+	return phy_attach_direct(pl->netdev, phy, flags, interface);
 }
 
 /**
@@ -2034,6 +2060,9 @@
 		pl->link_config.interface = pl->link_interface;
 	}
 
+	if (pl->config->mac_requires_rxc)
+		flags |= PHY_F_RXC_ALWAYS_ON;
+
 	ret = phy_attach_direct(pl->netdev, phy_dev, flags,
 				pl->link_interface);
 	phy_device_free(phy_dev);
@@ -2078,7 +2107,7 @@
 static void phylink_link_changed(struct phylink *pl, bool up, const char *what)
 {
 	if (!up)
-		pl->mac_link_dropped = true;
+		pl->link_failed = true;
 	phylink_run_resolve(pl);
 	phylink_dbg(pl, "%s link %s\n", what, up ? "up" : "down");
 }
@@ -2712,7 +2741,7 @@
 	 * link will cycle.
 	 */
 	if (manual_changed) {
-		pl->mac_link_dropped = true;
+		pl->link_failed = true;
 		phylink_run_resolve(pl);
 	}
 
--- linux-qcom-6.8.0.orig/drivers/net/phy/realtek.c
+++ linux-qcom-6.8.0/drivers/net/phy/realtek.c
@@ -1083,6 +1083,13 @@
 		.handle_interrupt = genphy_handle_interrupt_no_ack,
 		.suspend	= genphy_suspend,
 		.resume		= genphy_resume,
+	}, {
+		PHY_ID_MATCH_EXACT(0x001cc960),
+		.name		= "RTL8366S Gigabit Ethernet",
+		.suspend	= genphy_suspend,
+		.resume		= genphy_resume,
+		.read_mmd	= genphy_read_mmd_unsupported,
+		.write_mmd	= genphy_write_mmd_unsupported,
 	},
 };
 
--- linux-qcom-6.8.0.orig/drivers/net/phy/sfp.c
+++ linux-qcom-6.8.0/drivers/net/phy/sfp.c
@@ -461,7 +461,8 @@
 static const struct sfp_quirk sfp_quirks[] = {
 	// Alcatel Lucent G-010S-P can operate at 2500base-X, but incorrectly
 	// report 2500MBd NRZ in their EEPROM
-	SFP_QUIRK_M("ALCATELLUCENT", "G010SP", sfp_quirk_2500basex),
+	SFP_QUIRK("ALCATELLUCENT", "G010SP", sfp_quirk_2500basex,
+		  sfp_fixup_ignore_tx_fault),
 
 	// Alcatel Lucent G-010S-A can operate at 2500base-X, but report 3.2GBd
 	// NRZ in their EEPROM
@@ -502,6 +503,9 @@
 	SFP_QUIRK_F("Walsun", "HXSX-ATRC-1", sfp_fixup_fs_10gt),
 	SFP_QUIRK_F("Walsun", "HXSX-ATRI-1", sfp_fixup_fs_10gt),
 
+	// OEM SFP-GE-T is a 1000Base-T module with broken TX_FAULT indicator
+	SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault),
+
 	SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
 	SFP_QUIRK_M("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
 	SFP_QUIRK_F("OEM", "RTSFP-10", sfp_fixup_rollball_cc),
@@ -2418,8 +2422,7 @@
 
 	/* Handle remove event globally, it resets this state machine */
 	if (event == SFP_E_REMOVE) {
-		if (sfp->sm_mod_state > SFP_MOD_PROBE)
-			sfp_sm_mod_remove(sfp);
+		sfp_sm_mod_remove(sfp);
 		sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0);
 		return;
 	}
--- linux-qcom-6.8.0.orig/drivers/net/phy/vitesse.c
+++ linux-qcom-6.8.0/drivers/net/phy/vitesse.c
@@ -237,16 +237,6 @@
 	return 0;
 }
 
-static int vsc73xx_config_aneg(struct phy_device *phydev)
-{
-	/* The VSC73xx switches does not like to be instructed to
-	 * do autonegotiation in any way, it prefers that you just go
-	 * with the power-on/reset defaults. Writing some registers will
-	 * just make autonegotiation permanently fail.
-	 */
-	return 0;
-}
-
 /* This adds a skew for both TX and RX clocks, so the skew should only be
  * applied to "rgmii-id" interfaces. It may not work as expected
  * on "rgmii-txid", "rgmii-rxid" or "rgmii" interfaces.
@@ -444,7 +434,6 @@
 	.phy_id_mask    = 0x000ffff0,
 	/* PHY_GBIT_FEATURES */
 	.config_init    = vsc738x_config_init,
-	.config_aneg    = vsc73xx_config_aneg,
 	.read_page      = vsc73xx_read_page,
 	.write_page     = vsc73xx_write_page,
 }, {
@@ -453,7 +442,6 @@
 	.phy_id_mask    = 0x000ffff0,
 	/* PHY_GBIT_FEATURES */
 	.config_init    = vsc738x_config_init,
-	.config_aneg    = vsc73xx_config_aneg,
 	.read_page      = vsc73xx_read_page,
 	.write_page     = vsc73xx_write_page,
 }, {
@@ -462,7 +450,6 @@
 	.phy_id_mask    = 0x000ffff0,
 	/* PHY_GBIT_FEATURES */
 	.config_init    = vsc739x_config_init,
-	.config_aneg    = vsc73xx_config_aneg,
 	.read_page      = vsc73xx_read_page,
 	.write_page     = vsc73xx_write_page,
 }, {
@@ -471,7 +458,6 @@
 	.phy_id_mask    = 0x000ffff0,
 	/* PHY_GBIT_FEATURES */
 	.config_init    = vsc739x_config_init,
-	.config_aneg    = vsc73xx_config_aneg,
 	.read_page      = vsc73xx_read_page,
 	.write_page     = vsc73xx_write_page,
 }, {
--- linux-qcom-6.8.0.orig/drivers/net/plip/plip.c
+++ linux-qcom-6.8.0/drivers/net/plip/plip.c
@@ -815,7 +815,7 @@
 				return HS_TIMEOUT;
 			}
 		}
-		break;
+		fallthrough;
 
 	case PLIP_PK_LENGTH_LSB:
 		if (plip_send(nibble_timeout, dev,
--- linux-qcom-6.8.0.orig/drivers/net/ppp/ppp_async.c
+++ linux-qcom-6.8.0/drivers/net/ppp/ppp_async.c
@@ -542,7 +542,7 @@
 	 * and 7 (code-reject) must be sent as though no options
 	 * had been negotiated.
 	 */
-	islcp = proto == PPP_LCP && 1 <= data[2] && data[2] <= 7;
+	islcp = proto == PPP_LCP && count >= 3 && 1 <= data[2] && data[2] <= 7;
 
 	if (i == 0) {
 		if (islcp)
--- linux-qcom-6.8.0.orig/drivers/net/ppp/ppp_generic.c
+++ linux-qcom-6.8.0/drivers/net/ppp/ppp_generic.c
@@ -70,6 +70,7 @@
 #define MPHDRLEN_SSN	4	/* ditto with short sequence numbers */
 
 #define PPP_PROTO_LEN	2
+#define PPP_LCP_HDRLEN	4
 
 /*
  * An instance of /dev/ppp can be associated with either a ppp
@@ -491,6 +492,15 @@
 	return ret;
 }
 
+static bool ppp_check_packet(struct sk_buff *skb, size_t count)
+{
+	/* LCP packets must include LCP header which 4 bytes long:
+	 * 1-byte code, 1-byte identifier, and 2-byte length.
+	 */
+	return get_unaligned_be16(skb->data) != PPP_LCP ||
+		count >= PPP_PROTO_LEN + PPP_LCP_HDRLEN;
+}
+
 static ssize_t ppp_write(struct file *file, const char __user *buf,
 			 size_t count, loff_t *ppos)
 {
@@ -513,6 +523,11 @@
 		kfree_skb(skb);
 		goto out;
 	}
+	ret = -EINVAL;
+	if (unlikely(!ppp_check_packet(skb, count))) {
+		kfree_skb(skb);
+		goto out;
+	}
 
 	switch (pf->kind) {
 	case INTERFACE:
@@ -2254,7 +2269,7 @@
 	if (!pchb)
 		goto out_rcu;
 
-	spin_lock(&pchb->downl);
+	spin_lock_bh(&pchb->downl);
 	if (!pchb->chan) {
 		/* channel got unregistered */
 		kfree_skb(skb);
@@ -2266,7 +2281,7 @@
 		kfree_skb(skb);
 
 outl:
-	spin_unlock(&pchb->downl);
+	spin_unlock_bh(&pchb->downl);
 out_rcu:
 	rcu_read_unlock();
 
--- linux-qcom-6.8.0.orig/drivers/net/slip/slhc.c
+++ linux-qcom-6.8.0/drivers/net/slip/slhc.c
@@ -643,46 +643,57 @@
 int
 slhc_remember(struct slcompress *comp, unsigned char *icp, int isize)
 {
-	struct cstate *cs;
-	unsigned ihl;
-
+	const struct tcphdr *th;
 	unsigned char index;
+	struct iphdr *iph;
+	struct cstate *cs;
+	unsigned int ihl;
 
-	if(isize < 20) {
-		/* The packet is shorter than a legal IP header */
+	/* The packet is shorter than a legal IP header.
+	 * Also make sure isize is positive.
+	 */
+	if (isize < (int)sizeof(struct iphdr)) {
+runt:
 		comp->sls_i_runt++;
-		return slhc_toss( comp );
+		return slhc_toss(comp);
 	}
+	iph = (struct iphdr *)icp;
 	/* Peek at the IP header's IHL field to find its length */
-	ihl = icp[0] & 0xf;
-	if(ihl < 20 / 4){
-		/* The IP header length field is too small */
-		comp->sls_i_runt++;
-		return slhc_toss( comp );
-	}
-	index = icp[9];
-	icp[9] = IPPROTO_TCP;
+	ihl = iph->ihl;
+	/* The IP header length field is too small,
+	 * or packet is shorter than the IP header followed
+	 * by minimal tcp header.
+	 */
+	if (ihl < 5 || isize < ihl * 4 + sizeof(struct tcphdr))
+		goto runt;
+
+	index = iph->protocol;
+	iph->protocol = IPPROTO_TCP;
 
 	if (ip_fast_csum(icp, ihl)) {
 		/* Bad IP header checksum; discard */
 		comp->sls_i_badcheck++;
-		return slhc_toss( comp );
+		return slhc_toss(comp);
 	}
-	if(index > comp->rslot_limit) {
+	if (index > comp->rslot_limit) {
 		comp->sls_i_error++;
 		return slhc_toss(comp);
 	}
-
+	th = (struct tcphdr *)(icp + ihl * 4);
+	if (th->doff < sizeof(struct tcphdr) / 4)
+		goto runt;
+	if (isize < ihl * 4 + th->doff * 4)
+		goto runt;
 	/* Update local state */
 	cs = &comp->rstate[comp->recv_current = index];
 	comp->flags &=~ SLF_TOSS;
-	memcpy(&cs->cs_ip,icp,20);
-	memcpy(&cs->cs_tcp,icp + ihl*4,20);
+	memcpy(&cs->cs_ip, iph, sizeof(*iph));
+	memcpy(&cs->cs_tcp, th, sizeof(*th));
 	if (ihl > 5)
-	  memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4);
-	if (cs->cs_tcp.doff > 5)
-	  memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4);
-	cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2;
+	  memcpy(cs->cs_ipopt, &iph[1], (ihl - 5) * 4);
+	if (th->doff > 5)
+	  memcpy(cs->cs_tcpopt, &th[1], (th->doff - 5) * 4);
+	cs->cs_hsize = ihl*2 + th->doff*2;
 	cs->initialized = true;
 	/* Put headers back on packet
 	 * Neither header checksum is recalculated
--- linux-qcom-6.8.0.orig/drivers/net/tap.c
+++ linux-qcom-6.8.0/drivers/net/tap.c
@@ -1177,6 +1177,11 @@
 	struct sk_buff *skb;
 	int err, depth;
 
+	if (unlikely(xdp->data_end - xdp->data < ETH_HLEN)) {
+		err = -EINVAL;
+		goto err;
+	}
+
 	if (q->flags & IFF_VNET_HDR)
 		vnet_hdr_len = READ_ONCE(q->vnet_hdr_sz);
 
@@ -1325,9 +1330,9 @@
 	list_for_each_entry(q, &tap->queue_list, next)
 		rings[i++] = &q->ring;
 
-	ret = ptr_ring_resize_multiple(rings, n,
-				       dev->tx_queue_len, GFP_KERNEL,
-				       __skb_array_destroy_skb);
+	ret = ptr_ring_resize_multiple_bh(rings, n,
+					  dev->tx_queue_len, GFP_KERNEL,
+					  __skb_array_destroy_skb);
 
 	kfree(rings);
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/net/team/team.c
+++ linux-qcom-6.8.0/drivers/net/team/team.c
@@ -982,7 +982,8 @@
 
 #define TEAM_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \
 			    NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | \
-			    NETIF_F_HIGHDMA | NETIF_F_LRO)
+			    NETIF_F_HIGHDMA | NETIF_F_LRO | \
+			    NETIF_F_GSO_ENCAP_ALL)
 
 #define TEAM_ENC_FEATURES	(NETIF_F_HW_CSUM | NETIF_F_SG | \
 				 NETIF_F_RXCSUM | NETIF_F_GSO_SOFTWARE)
@@ -990,14 +991,19 @@
 static void __team_compute_features(struct team *team)
 {
 	struct team_port *port;
-	netdev_features_t vlan_features = TEAM_VLAN_FEATURES &
-					  NETIF_F_ALL_FOR_ALL;
+	netdev_features_t vlan_features = TEAM_VLAN_FEATURES;
 	netdev_features_t enc_features  = TEAM_ENC_FEATURES;
 	unsigned short max_hard_header_len = ETH_HLEN;
 	unsigned int dst_release_flag = IFF_XMIT_DST_RELEASE |
 					IFF_XMIT_DST_RELEASE_PERM;
 
 	rcu_read_lock();
+	if (list_empty(&team->port_list))
+		goto done;
+
+	vlan_features = netdev_base_features(vlan_features);
+	enc_features = netdev_base_features(enc_features);
+
 	list_for_each_entry_rcu(port, &team->port_list, list) {
 		vlan_features = netdev_increment_features(vlan_features,
 					port->dev->vlan_features,
@@ -1007,11 +1013,11 @@
 						  port->dev->hw_enc_features,
 						  TEAM_ENC_FEATURES);
 
-
 		dst_release_flag &= port->dev->priv_flags;
 		if (port->dev->hard_header_len > max_hard_header_len)
 			max_hard_header_len = port->dev->hard_header_len;
 	}
+done:
 	rcu_read_unlock();
 
 	team->dev->vlan_features = vlan_features;
@@ -1168,6 +1174,13 @@
 		return -EBUSY;
 	}
 
+	if (netdev_has_upper_dev(port_dev, dev)) {
+		NL_SET_ERR_MSG(extack, "Device is already a lower device of the team interface");
+		netdev_err(dev, "Device %s is already a lower device of the team interface\n",
+			   portname);
+		return -EBUSY;
+	}
+
 	if (port_dev->features & NETIF_F_VLAN_CHALLENGED &&
 	    vlan_uses_dev(dev)) {
 		NL_SET_ERR_MSG(extack, "Device is VLAN challenged and team device has VLAN set up");
@@ -2011,8 +2024,7 @@
 	netdev_features_t mask;
 
 	mask = features;
-	features &= ~NETIF_F_ONE_FOR_ALL;
-	features |= NETIF_F_ALL_FOR_ALL;
+	features = netdev_base_features(features);
 
 	rcu_read_lock();
 	list_for_each_entry_rcu(port, &team->port_list, list) {
--- linux-qcom-6.8.0.orig/drivers/net/tun.c
+++ linux-qcom-6.8.0/drivers/net/tun.c
@@ -580,7 +580,7 @@
 	struct net *net = dev_net(tun->dev);
 
 	return ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) ||
-		  (gid_valid(tun->group) && !in_egroup_p(tun->group))) &&
+		(gid_valid(tun->group) && !in_egroup_p(tun->group))) &&
 		!ns_capable(net->user_ns, CAP_NET_ADMIN);
 }
 
@@ -1487,7 +1487,7 @@
 	skb->truesize += skb->data_len;
 
 	for (i = 1; i < it->nr_segs; i++) {
-		const struct iovec *iov = iter_iov(it);
+		const struct iovec *iov = iter_iov(it) + i;
 		size_t fragsz = iov->iov_len;
 		struct page *page;
 		void *frag;
@@ -2132,14 +2132,16 @@
 					    tun_is_little_endian(tun), true,
 					    vlan_hlen)) {
 			struct skb_shared_info *sinfo = skb_shinfo(skb);
-			pr_err("unexpected GSO type: "
-			       "0x%x, gso_size %d, hdr_len %d\n",
-			       sinfo->gso_type, tun16_to_cpu(tun, gso.gso_size),
-			       tun16_to_cpu(tun, gso.hdr_len));
-			print_hex_dump(KERN_ERR, "tun: ",
-				       DUMP_PREFIX_NONE,
-				       16, 1, skb->head,
-				       min((int)tun16_to_cpu(tun, gso.hdr_len), 64), true);
+
+			if (net_ratelimit()) {
+				netdev_err(tun->dev, "unexpected GSO type: 0x%x, gso_size %d, hdr_len %d\n",
+					   sinfo->gso_type, tun16_to_cpu(tun, gso.gso_size),
+					   tun16_to_cpu(tun, gso.hdr_len));
+				print_hex_dump(KERN_ERR, "tun: ",
+					       DUMP_PREFIX_NONE,
+					       16, 1, skb->head,
+					       min((int)tun16_to_cpu(tun, gso.hdr_len), 64), true);
+			}
 			WARN_ON_ONCE(1);
 			return -EINVAL;
 		}
@@ -2457,6 +2459,9 @@
 	bool skb_xdp = false;
 	struct page *page;
 
+	if (unlikely(datasize < ETH_HLEN))
+		return -EINVAL;
+
 	xdp_prog = rcu_dereference(tun->xdp_prog);
 	if (xdp_prog) {
 		if (gso->gso_type) {
@@ -3677,9 +3682,9 @@
 	list_for_each_entry(tfile, &tun->disabled, next)
 		rings[i++] = &tfile->tx_ring;
 
-	ret = ptr_ring_resize_multiple(rings, n,
-				       dev->tx_queue_len, GFP_KERNEL,
-				       tun_ptr_free);
+	ret = ptr_ring_resize_multiple_bh(rings, n,
+					  dev->tx_queue_len, GFP_KERNEL,
+					  tun_ptr_free);
 
 	kfree(rings);
 	return ret;
--- linux-qcom-6.8.0.orig/drivers/net/usb/aqc111.c
+++ linux-qcom-6.8.0/drivers/net/usb/aqc111.c
@@ -1141,17 +1141,15 @@
 			continue;
 		}
 
-		/* Clone SKB */
-		new_skb = skb_clone(skb, GFP_ATOMIC);
+		new_skb = netdev_alloc_skb_ip_align(dev->net, pkt_len);
 
 		if (!new_skb)
 			goto err;
 
-		new_skb->len = pkt_len;
+		skb_put(new_skb, pkt_len);
+		memcpy(new_skb->data, skb->data, pkt_len);
 		skb_pull(new_skb, AQ_RX_HW_PAD);
-		skb_set_tail_pointer(new_skb, new_skb->len);
 
-		new_skb->truesize = SKB_TRUESIZE(new_skb->len);
 		if (aqc111_data->rx_checksum)
 			aqc111_rx_checksum(new_skb, pkt_desc);
 
--- linux-qcom-6.8.0.orig/drivers/net/usb/ax88179_178a.c
+++ linux-qcom-6.8.0/drivers/net/usb/ax88179_178a.c
@@ -326,7 +326,8 @@
 
 	if (netif_carrier_ok(dev->net) != link) {
 		usbnet_link_change(dev, link, 1);
-		netdev_info(dev->net, "ax88179 - Link status is: %d\n", link);
+		if (!link)
+			netdev_info(dev->net, "ax88179 - Link status is: 0\n");
 	}
 }
 
@@ -1273,6 +1274,8 @@
 
 	if (is_valid_ether_addr(mac)) {
 		eth_hw_addr_set(dev->net, mac);
+		if (!is_local_ether_addr(mac))
+			dev->net->addr_assign_type = NET_ADDR_PERM;
 	} else {
 		netdev_info(dev->net, "invalid MAC address, using random\n");
 		eth_hw_addr_random(dev->net);
@@ -1315,6 +1318,8 @@
 
 	netif_set_tso_max_size(dev->net, 16384);
 
+	ax88179_reset(dev);
+
 	return 0;
 }
 
@@ -1452,21 +1457,16 @@
 			/* Skip IP alignment pseudo header */
 			skb_pull(skb, 2);
 
-			skb->truesize = SKB_TRUESIZE(pkt_len_plus_padd);
 			ax88179_rx_checksum(skb, pkt_hdr);
 			return 1;
 		}
 
-		ax_skb = skb_clone(skb, GFP_ATOMIC);
+		ax_skb = netdev_alloc_skb_ip_align(dev->net, pkt_len);
 		if (!ax_skb)
 			return 0;
-		skb_trim(ax_skb, pkt_len);
+		skb_put(ax_skb, pkt_len);
+		memcpy(ax_skb->data, skb->data + 2, pkt_len);
 
-		/* Skip IP alignment pseudo header */
-		skb_pull(ax_skb, 2);
-
-		skb->truesize = pkt_len_plus_padd +
-				SKB_DATA_ALIGN(sizeof(struct sk_buff));
 		ax88179_rx_checksum(ax_skb, pkt_hdr);
 		usbnet_skb_return(dev, ax_skb);
 
@@ -1541,6 +1541,7 @@
 			 GMII_PHY_PHYSR, 2, &tmp16);
 
 	if (!(tmp16 & GMII_PHY_PHYSR_LINK)) {
+		netdev_info(dev->net, "ax88179 - Link status is: 0\n");
 		return 0;
 	} else if (GMII_PHY_PHYSR_GIGA == (tmp16 & GMII_PHY_PHYSR_SMASK)) {
 		mode |= AX_MEDIUM_GIGAMODE | AX_MEDIUM_EN_125MHZ;
@@ -1578,6 +1579,8 @@
 
 	netif_carrier_on(dev->net);
 
+	netdev_info(dev->net, "ax88179 - Link status is: 1\n");
+
 	return 0;
 }
 
@@ -1674,6 +1677,27 @@
 	return 0;
 }
 
+static int ax88179_net_reset(struct usbnet *dev)
+{
+	u16 tmp16;
+
+	ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, GMII_PHY_PHYSR,
+			 2, &tmp16);
+	if (tmp16) {
+		ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+				 2, 2, &tmp16);
+		if (!(tmp16 & AX_MEDIUM_RECEIVE_EN)) {
+			tmp16 |= AX_MEDIUM_RECEIVE_EN;
+			ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE,
+					  2, 2, &tmp16);
+		}
+	} else {
+		ax88179_reset(dev);
+	}
+
+	return 0;
+}
+
 static int ax88179_stop(struct usbnet *dev)
 {
 	u16 tmp16;
@@ -1693,7 +1717,7 @@
 	.unbind = ax88179_unbind,
 	.status = ax88179_status,
 	.link_reset = ax88179_link_reset,
-	.reset = ax88179_reset,
+	.reset = ax88179_net_reset,
 	.stop = ax88179_stop,
 	.flags = FLAG_ETHER | FLAG_FRAMING_AX,
 	.rx_fixup = ax88179_rx_fixup,
@@ -1706,7 +1730,7 @@
 	.unbind = ax88179_unbind,
 	.status = ax88179_status,
 	.link_reset = ax88179_link_reset,
-	.reset = ax88179_reset,
+	.reset = ax88179_net_reset,
 	.stop = ax88179_stop,
 	.flags = FLAG_ETHER | FLAG_FRAMING_AX,
 	.rx_fixup = ax88179_rx_fixup,
@@ -1719,7 +1743,7 @@
 	.unbind = ax88179_unbind,
 	.status = ax88179_status,
 	.link_reset = ax88179_link_reset,
-	.reset = ax88179_reset,
+	.reset = ax88179_net_reset,
 	.stop = ax88179_stop,
 	.flags = FLAG_ETHER | FLAG_FRAMING_AX,
 	.rx_fixup = ax88179_rx_fixup,
@@ -1732,7 +1756,7 @@
 	.unbind = ax88179_unbind,
 	.status = ax88179_status,
 	.link_reset = ax88179_link_reset,
-	.reset = ax88179_reset,
+	.reset = ax88179_net_reset,
 	.stop = ax88179_stop,
 	.flags = FLAG_ETHER | FLAG_FRAMING_AX,
 	.rx_fixup = ax88179_rx_fixup,
@@ -1745,7 +1769,7 @@
 	.unbind = ax88179_unbind,
 	.status = ax88179_status,
 	.link_reset = ax88179_link_reset,
-	.reset = ax88179_reset,
+	.reset = ax88179_net_reset,
 	.stop = ax88179_stop,
 	.flags = FLAG_ETHER | FLAG_FRAMING_AX,
 	.rx_fixup = ax88179_rx_fixup,
@@ -1758,7 +1782,7 @@
 	.unbind = ax88179_unbind,
 	.status = ax88179_status,
 	.link_reset = ax88179_link_reset,
-	.reset = ax88179_reset,
+	.reset = ax88179_net_reset,
 	.stop = ax88179_stop,
 	.flags = FLAG_ETHER | FLAG_FRAMING_AX,
 	.rx_fixup = ax88179_rx_fixup,
@@ -1771,7 +1795,7 @@
 	.unbind = ax88179_unbind,
 	.status = ax88179_status,
 	.link_reset = ax88179_link_reset,
-	.reset = ax88179_reset,
+	.reset = ax88179_net_reset,
 	.stop = ax88179_stop,
 	.flags = FLAG_ETHER | FLAG_FRAMING_AX,
 	.rx_fixup = ax88179_rx_fixup,
@@ -1784,7 +1808,7 @@
 	.unbind = ax88179_unbind,
 	.status = ax88179_status,
 	.link_reset = ax88179_link_reset,
-	.reset	= ax88179_reset,
+	.reset	= ax88179_net_reset,
 	.stop	= ax88179_stop,
 	.flags	= FLAG_ETHER | FLAG_FRAMING_AX,
 	.rx_fixup = ax88179_rx_fixup,
@@ -1797,7 +1821,7 @@
 	.unbind = ax88179_unbind,
 	.status = ax88179_status,
 	.link_reset = ax88179_link_reset,
-	.reset	= ax88179_reset,
+	.reset	= ax88179_net_reset,
 	.stop = ax88179_stop,
 	.flags	= FLAG_ETHER | FLAG_FRAMING_AX,
 	.rx_fixup = ax88179_rx_fixup,
@@ -1810,7 +1834,7 @@
 	.unbind	= ax88179_unbind,
 	.status	= ax88179_status,
 	.link_reset = ax88179_link_reset,
-	.reset	= ax88179_reset,
+	.reset	= ax88179_net_reset,
 	.stop	= ax88179_stop,
 	.flags	= FLAG_ETHER | FLAG_FRAMING_AX,
 	.rx_fixup = ax88179_rx_fixup,
@@ -1823,7 +1847,7 @@
 	.unbind = ax88179_unbind,
 	.status = ax88179_status,
 	.link_reset = ax88179_link_reset,
-	.reset  = ax88179_reset,
+	.reset  = ax88179_net_reset,
 	.stop   = ax88179_stop,
 	.flags  = FLAG_ETHER | FLAG_FRAMING_AX,
 	.rx_fixup = ax88179_rx_fixup,
@@ -1836,7 +1860,7 @@
 	.unbind = ax88179_unbind,
 	.status = ax88179_status,
 	.link_reset = ax88179_link_reset,
-	.reset  = ax88179_reset,
+	.reset  = ax88179_net_reset,
 	.stop   = ax88179_stop,
 	.flags  = FLAG_ETHER | FLAG_FRAMING_AX,
 	.rx_fixup = ax88179_rx_fixup,
@@ -1849,7 +1873,7 @@
 	.unbind = ax88179_unbind,
 	.status = ax88179_status,
 	.link_reset = ax88179_link_reset,
-	.reset  = ax88179_reset,
+	.reset  = ax88179_net_reset,
 	.stop   = ax88179_stop,
 	.flags  = FLAG_ETHER | FLAG_FRAMING_AX,
 	.rx_fixup = ax88179_rx_fixup,
--- linux-qcom-6.8.0.orig/drivers/net/usb/ipheth.c
+++ linux-qcom-6.8.0/drivers/net/usb/ipheth.c
@@ -61,7 +61,18 @@
 #define IPHETH_USBINTF_PROTO    1
 
 #define IPHETH_IP_ALIGN		2	/* padding at front of URB */
-#define IPHETH_NCM_HEADER_SIZE  (12 + 96) /* NCMH + NCM0 */
+/* On iOS devices, NCM headers in RX have a fixed size regardless of DPE count:
+ * - NTH16 (NCMH): 12 bytes, as per CDC NCM 1.0 spec
+ * - NDP16 (NCM0): 96 bytes, of which
+ *    - NDP16 fixed header: 8 bytes
+ *    - maximum of 22 DPEs (21 datagrams + trailer), 4 bytes each
+ */
+#define IPHETH_NDP16_MAX_DPE	22
+#define IPHETH_NDP16_HEADER_SIZE (sizeof(struct usb_cdc_ncm_ndp16) + \
+				  IPHETH_NDP16_MAX_DPE * \
+				  sizeof(struct usb_cdc_ncm_dpe16))
+#define IPHETH_NCM_HEADER_SIZE	(sizeof(struct usb_cdc_ncm_nth16) + \
+				 IPHETH_NDP16_HEADER_SIZE)
 #define IPHETH_TX_BUF_SIZE      ETH_FRAME_LEN
 #define IPHETH_RX_BUF_SIZE_LEGACY (IPHETH_IP_ALIGN + ETH_FRAME_LEN)
 #define IPHETH_RX_BUF_SIZE_NCM	65536
@@ -207,15 +218,23 @@
 	return ipheth_consume_skb(buf, len, dev);
 }
 
+/* In "NCM mode", the iOS device encapsulates RX (phone->computer) traffic
+ * in NCM Transfer Blocks (similarly to CDC NCM). However, unlike reverse
+ * tethering (handled by the `cdc_ncm` driver), regular tethering is not
+ * compliant with the CDC NCM spec, as the device is missing the necessary
+ * descriptors, and TX (computer->phone) traffic is not encapsulated
+ * at all. Thus `ipheth` implements a very limited subset of the spec with
+ * the sole purpose of parsing RX URBs.
+ */
 static int ipheth_rcvbulk_callback_ncm(struct urb *urb)
 {
 	struct usb_cdc_ncm_nth16 *ncmh;
 	struct usb_cdc_ncm_ndp16 *ncm0;
 	struct usb_cdc_ncm_dpe16 *dpe;
 	struct ipheth_device *dev;
+	u16 dg_idx, dg_len;
 	int retval = -EINVAL;
 	char *buf;
-	int len;
 
 	dev = urb->context;
 
@@ -226,40 +245,42 @@
 
 	ncmh = urb->transfer_buffer;
 	if (ncmh->dwSignature != cpu_to_le32(USB_CDC_NCM_NTH16_SIGN) ||
-	    le16_to_cpu(ncmh->wNdpIndex) >= urb->actual_length) {
-		dev->net->stats.rx_errors++;
-		return retval;
-	}
-
-	ncm0 = urb->transfer_buffer + le16_to_cpu(ncmh->wNdpIndex);
-	if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN) ||
-	    le16_to_cpu(ncmh->wHeaderLength) + le16_to_cpu(ncm0->wLength) >=
-	    urb->actual_length) {
-		dev->net->stats.rx_errors++;
-		return retval;
-	}
+	    /* On iOS, NDP16 directly follows NTH16 */
+	    ncmh->wNdpIndex != cpu_to_le16(sizeof(struct usb_cdc_ncm_nth16)))
+		goto rx_error;
+
+	ncm0 = urb->transfer_buffer + sizeof(struct usb_cdc_ncm_nth16);
+	if (ncm0->dwSignature != cpu_to_le32(USB_CDC_NCM_NDP16_NOCRC_SIGN))
+		goto rx_error;
 
 	dpe = ncm0->dpe16;
-	while (le16_to_cpu(dpe->wDatagramIndex) != 0 &&
-	       le16_to_cpu(dpe->wDatagramLength) != 0) {
-		if (le16_to_cpu(dpe->wDatagramIndex) >= urb->actual_length ||
-		    le16_to_cpu(dpe->wDatagramIndex) +
-		    le16_to_cpu(dpe->wDatagramLength) > urb->actual_length) {
+	for (int dpe_i = 0; dpe_i < IPHETH_NDP16_MAX_DPE; ++dpe_i, ++dpe) {
+		dg_idx = le16_to_cpu(dpe->wDatagramIndex);
+		dg_len = le16_to_cpu(dpe->wDatagramLength);
+
+		/* Null DPE must be present after last datagram pointer entry
+		 * (3.3.1 USB CDC NCM spec v1.0)
+		 */
+		if (dg_idx == 0 && dg_len == 0)
+			return 0;
+
+		if (dg_idx < IPHETH_NCM_HEADER_SIZE ||
+		    dg_idx >= urb->actual_length ||
+		    dg_len > urb->actual_length - dg_idx) {
 			dev->net->stats.rx_length_errors++;
 			return retval;
 		}
 
-		buf = urb->transfer_buffer + le16_to_cpu(dpe->wDatagramIndex);
-		len = le16_to_cpu(dpe->wDatagramLength);
+		buf = urb->transfer_buffer + dg_idx;
 
-		retval = ipheth_consume_skb(buf, len, dev);
+		retval = ipheth_consume_skb(buf, dg_len, dev);
 		if (retval != 0)
 			return retval;
-
-		dpe++;
 	}
 
-	return 0;
+rx_error:
+	dev->net->stats.rx_errors++;
+	return retval;
 }
 
 static void ipheth_rcvbulk_callback(struct urb *urb)
@@ -286,10 +307,11 @@
 		return;
 	}
 
-	if (urb->actual_length <= IPHETH_IP_ALIGN) {
-		dev->net->stats.rx_length_errors++;
-		return;
-	}
+	/* iPhone may periodically send URBs with no payload
+	 * on the "bulk in" endpoint. It is safe to ignore them.
+	 */
+	if (urb->actual_length == 0)
+		goto rx_submit;
 
 	/* RX URBs starting with 0x00 0x01 do not encapsulate Ethernet frames,
 	 * but rather are control frames. Their purpose is not documented, and
@@ -298,7 +320,8 @@
 	 * URB received from the bulk IN endpoint.
 	 */
 	if (unlikely
-		(((char *)urb->transfer_buffer)[0] == 0 &&
+		(urb->actual_length == 4 &&
+		 ((char *)urb->transfer_buffer)[0] == 0 &&
 		 ((char *)urb->transfer_buffer)[1] == 1))
 		goto rx_submit;
 
@@ -306,7 +329,6 @@
 	if (retval != 0) {
 		dev_err(&dev->intf->dev, "%s: callback retval: %d\n",
 			__func__, retval);
-		return;
 	}
 
 rx_submit:
@@ -354,13 +376,14 @@
 			0x02, /* index */
 			dev->ctrl_buf, IPHETH_CTRL_BUF_SIZE,
 			IPHETH_CTRL_TIMEOUT);
-	if (retval < 0) {
+	if (retval <= 0) {
 		dev_err(&dev->intf->dev, "%s: usb_control_msg: %d\n",
 			__func__, retval);
 		return retval;
 	}
 
-	if (dev->ctrl_buf[0] == IPHETH_CARRIER_ON) {
+	if ((retval == 1 && dev->ctrl_buf[0] == IPHETH_CARRIER_ON) ||
+	    (retval >= 2 && dev->ctrl_buf[1] == IPHETH_CARRIER_ON)) {
 		netif_carrier_on(dev->net);
 		if (dev->tx_urb->status != -EINPROGRESS)
 			netif_wake_queue(dev->net);
@@ -475,8 +498,8 @@
 {
 	struct ipheth_device *dev = netdev_priv(net);
 
-	cancel_delayed_work_sync(&dev->carrier_work);
 	netif_stop_queue(net);
+	cancel_delayed_work_sync(&dev->carrier_work);
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/usb/lan78xx.c
+++ linux-qcom-6.8.0/drivers/net/usb/lan78xx.c
@@ -1657,13 +1657,13 @@
 	struct lan78xx_priv *pdata = (struct lan78xx_priv *)(dev->data[0]);
 	int ret;
 
+	if (wol->wolopts & ~WAKE_ALL)
+		return -EINVAL;
+
 	ret = usb_autopm_get_interface(dev->intf);
 	if (ret < 0)
 		return ret;
 
-	if (wol->wolopts & ~WAKE_ALL)
-		return -EINVAL;
-
 	pdata->wol = wol->wolopts;
 
 	device_set_wakeup_enable(&dev->udev->dev, (bool)wol->wolopts);
@@ -2385,6 +2385,7 @@
 		if (dev->chipid == ID_REV_CHIP_ID_7801_) {
 			if (phy_is_pseudo_fixed_link(phydev)) {
 				fixed_phy_unregister(phydev);
+				phy_device_free(phydev);
 			} else {
 				phy_unregister_fixup_for_uid(PHY_KSZ9031RNX,
 							     0xfffffff0);
@@ -4244,8 +4245,10 @@
 
 	phy_disconnect(net->phydev);
 
-	if (phy_is_pseudo_fixed_link(phydev))
+	if (phy_is_pseudo_fixed_link(phydev)) {
 		fixed_phy_unregister(phydev);
+		phy_device_free(phydev);
+	}
 
 	usb_scuttle_anchored_urbs(&dev->deferred);
 
@@ -4412,29 +4415,30 @@
 
 	period = ep_intr->desc.bInterval;
 	maxp = usb_maxpacket(dev->udev, dev->pipe_intr);
-	buf = kmalloc(maxp, GFP_KERNEL);
-	if (!buf) {
+
+	dev->urb_intr = usb_alloc_urb(0, GFP_KERNEL);
+	if (!dev->urb_intr) {
 		ret = -ENOMEM;
 		goto out5;
 	}
 
-	dev->urb_intr = usb_alloc_urb(0, GFP_KERNEL);
-	if (!dev->urb_intr) {
+	buf = kmalloc(maxp, GFP_KERNEL);
+	if (!buf) {
 		ret = -ENOMEM;
-		goto out6;
-	} else {
-		usb_fill_int_urb(dev->urb_intr, dev->udev,
-				 dev->pipe_intr, buf, maxp,
-				 intr_complete, dev, period);
-		dev->urb_intr->transfer_flags |= URB_FREE_BUFFER;
+		goto free_urbs;
 	}
 
+	usb_fill_int_urb(dev->urb_intr, dev->udev,
+			 dev->pipe_intr, buf, maxp,
+			 intr_complete, dev, period);
+	dev->urb_intr->transfer_flags |= URB_FREE_BUFFER;
+
 	dev->maxpacket = usb_maxpacket(dev->udev, dev->pipe_out);
 
 	/* Reject broken descriptors. */
 	if (dev->maxpacket == 0) {
 		ret = -ENODEV;
-		goto out6;
+		goto free_urbs;
 	}
 
 	/* driver requires remote-wakeup capability during autosuspend. */
@@ -4442,7 +4446,7 @@
 
 	ret = lan78xx_phy_init(dev);
 	if (ret < 0)
-		goto out7;
+		goto free_urbs;
 
 	ret = register_netdev(netdev);
 	if (ret != 0) {
@@ -4464,10 +4468,8 @@
 
 out8:
 	phy_disconnect(netdev->phydev);
-out7:
+free_urbs:
 	usb_free_urb(dev->urb_intr);
-out6:
-	kfree(buf);
 out5:
 	lan78xx_unbind(dev, intf);
 out4:
--- linux-qcom-6.8.0.orig/drivers/net/usb/qmi_wwan.c
+++ linux-qcom-6.8.0/drivers/net/usb/qmi_wwan.c
@@ -201,6 +201,7 @@
 			break;
 		default:
 			/* not ip - do not know what to do */
+			kfree_skb(skbn);
 			goto skip;
 		}
 
@@ -1083,6 +1084,7 @@
 		USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7),
 		.driver_info = (unsigned long)&qmi_wwan_info,
 	},
+	{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0122)},	/* Quectel RG650V */
 	{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)},	/* Quectel EC25, EC20 R2.0  Mini PCIe */
 	{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)},	/* Quectel EP06/EG06/EM06 */
 	{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)},	/* Quectel EG12/EM12 */
@@ -1368,6 +1370,12 @@
 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1060, 2)},	/* Telit LN920 */
 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1070, 2)},	/* Telit FN990 */
 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1080, 2)}, /* Telit FE990 */
+	{QMI_QUIRK_SET_DTR(0x1bc7, 0x10a0, 0)}, /* Telit FN920C04 */
+	{QMI_QUIRK_SET_DTR(0x1bc7, 0x10a4, 0)}, /* Telit FN920C04 */
+	{QMI_QUIRK_SET_DTR(0x1bc7, 0x10a9, 0)}, /* Telit FN920C04 */
+	{QMI_QUIRK_SET_DTR(0x1bc7, 0x10c0, 0)}, /* Telit FE910C04 */
+	{QMI_QUIRK_SET_DTR(0x1bc7, 0x10c4, 0)}, /* Telit FE910C04 */
+	{QMI_QUIRK_SET_DTR(0x1bc7, 0x10c8, 0)}, /* Telit FE910C04 */
 	{QMI_FIXED_INTF(0x1bc7, 0x1100, 3)},	/* Telit ME910 */
 	{QMI_FIXED_INTF(0x1bc7, 0x1101, 3)},	/* Telit ME910 dual modem */
 	{QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},	/* Telit LE920 */
@@ -1377,6 +1385,8 @@
 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1260, 2)},	/* Telit LE910Cx */
 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1261, 2)},	/* Telit LE910Cx */
 	{QMI_QUIRK_SET_DTR(0x1bc7, 0x1900, 1)},	/* Telit LN940 series */
+	{QMI_QUIRK_SET_DTR(0x1bc7, 0x3000, 0)},	/* Telit FN912 series */
+	{QMI_QUIRK_SET_DTR(0x1bc7, 0x3001, 0)},	/* Telit FN912 series */
 	{QMI_FIXED_INTF(0x1c9e, 0x9801, 3)},	/* Telewell TW-3G HSPA+ */
 	{QMI_FIXED_INTF(0x1c9e, 0x9803, 4)},	/* Telewell TW-3G HSPA+ */
 	{QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)},	/* XS Stick W100-2 from 4G Systems */
@@ -1426,11 +1436,14 @@
 	{QMI_FIXED_INTF(0x2c7c, 0x0296, 4)},	/* Quectel BG96 */
 	{QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)},	/* Quectel EM05GV2 */
 	{QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)},	/* Fibocom NL678 series */
+	{QMI_QUIRK_SET_DTR(0x2cb7, 0x0112, 0)},	/* Fibocom FG132 */
 	{QMI_FIXED_INTF(0x0489, 0xe0b4, 0)},	/* Foxconn T77W968 LTE */
 	{QMI_FIXED_INTF(0x0489, 0xe0b5, 0)},	/* Foxconn T77W968 LTE with eSIM support*/
 	{QMI_FIXED_INTF(0x2692, 0x9025, 4)},    /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */
 	{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(0x33f8, 0x0104, 4)}, /* Rolling RW101 RMNET */
+	{QMI_FIXED_INTF(0x2dee, 0x4d22, 5)},    /* MeiG Smart SRM825L */
 
 	/* 4. Gobi 1000 devices */
 	{QMI_GOBI1K_DEVICE(0x05c6, 0x9212)},	/* Acer Gobi Modem Device */
--- linux-qcom-6.8.0.orig/drivers/net/usb/r8152.c
+++ linux-qcom-6.8.0/drivers/net/usb/r8152.c
@@ -5176,14 +5176,23 @@
 	data = (u8 *)mac;
 	data += __le16_to_cpu(mac->fw_offset);
 
-	generic_ocp_write(tp, __le16_to_cpu(mac->fw_reg), 0xff, length, data,
-			  type);
+	if (generic_ocp_write(tp, __le16_to_cpu(mac->fw_reg), 0xff, length,
+			      data, type) < 0) {
+		dev_err(&tp->intf->dev, "Write %s fw fail\n",
+			type ? "PLA" : "USB");
+		return;
+	}
 
 	ocp_write_word(tp, type, __le16_to_cpu(mac->bp_ba_addr),
 		       __le16_to_cpu(mac->bp_ba_value));
 
-	generic_ocp_write(tp, __le16_to_cpu(mac->bp_start), BYTE_EN_DWORD,
-			  __le16_to_cpu(mac->bp_num) << 1, mac->bp, type);
+	if (generic_ocp_write(tp, __le16_to_cpu(mac->bp_start), BYTE_EN_DWORD,
+			      ALIGN(__le16_to_cpu(mac->bp_num) << 1, 4),
+			      mac->bp, type) < 0) {
+		dev_err(&tp->intf->dev, "Write %s bp fail\n",
+			type ? "PLA" : "USB");
+		return;
+	}
 
 	bp_en_addr = __le16_to_cpu(mac->bp_en_addr);
 	if (bp_en_addr)
@@ -10040,6 +10049,7 @@
 	{ USB_DEVICE(VENDOR_ID_LENOVO,  0x3062) },
 	{ USB_DEVICE(VENDOR_ID_LENOVO,  0x3069) },
 	{ USB_DEVICE(VENDOR_ID_LENOVO,  0x3082) },
+	{ USB_DEVICE(VENDOR_ID_LENOVO,  0x3098) },
 	{ USB_DEVICE(VENDOR_ID_LENOVO,  0x7205) },
 	{ USB_DEVICE(VENDOR_ID_LENOVO,  0x720c) },
 	{ USB_DEVICE(VENDOR_ID_LENOVO,  0x7214) },
@@ -10078,7 +10088,7 @@
 	 * driver supports it.
 	 */
 	if (__rtl_get_hw_ver(udev) == RTL_VER_UNKNOWN)
-		return 0;
+		return -ENODEV;
 
 	/* The vendor mode is not always config #1, so to find it out. */
 	c = udev->config;
--- linux-qcom-6.8.0.orig/drivers/net/usb/rtl8150.c
+++ linux-qcom-6.8.0/drivers/net/usb/rtl8150.c
@@ -71,6 +71,14 @@
 #define MSR_SPEED		(1<<3)
 #define MSR_LINK		(1<<2)
 
+/* USB endpoints */
+enum rtl8150_usb_ep {
+	RTL8150_USB_EP_CONTROL = 0,
+	RTL8150_USB_EP_BULK_IN = 1,
+	RTL8150_USB_EP_BULK_OUT = 2,
+	RTL8150_USB_EP_INT_IN = 3,
+};
+
 /* Interrupt pipe data */
 #define INT_TSR			0x00
 #define INT_RSR			0x01
@@ -778,7 +786,8 @@
 				      struct ethtool_link_ksettings *ecmd)
 {
 	rtl8150_t *dev = netdev_priv(netdev);
-	short lpa, bmcr;
+	short lpa = 0;
+	short bmcr = 0;
 	u32 supported;
 
 	supported = (SUPPORTED_10baseT_Half |
@@ -866,6 +875,13 @@
 	struct usb_device *udev = interface_to_usbdev(intf);
 	rtl8150_t *dev;
 	struct net_device *netdev;
+	static const u8 bulk_ep_addr[] = {
+		RTL8150_USB_EP_BULK_IN | USB_DIR_IN,
+		RTL8150_USB_EP_BULK_OUT | USB_DIR_OUT,
+		0};
+	static const u8 int_ep_addr[] = {
+		RTL8150_USB_EP_INT_IN | USB_DIR_IN,
+		0};
 
 	netdev = alloc_etherdev(sizeof(rtl8150_t));
 	if (!netdev)
@@ -879,6 +895,13 @@
 		return -ENOMEM;
 	}
 
+	/* Verify that all required endpoints are present */
+	if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) ||
+	    !usb_check_int_endpoints(intf, int_ep_addr)) {
+		dev_err(&intf->dev, "couldn't find required endpoints\n");
+		goto out;
+	}
+
 	tasklet_setup(&dev->tl, rx_fixup);
 	spin_lock_init(&dev->rx_pool_lock);
 
--- linux-qcom-6.8.0.orig/drivers/net/usb/smsc95xx.c
+++ linux-qcom-6.8.0/drivers/net/usb/smsc95xx.c
@@ -879,7 +879,7 @@
 static int smsc95xx_reset(struct usbnet *dev)
 {
 	struct smsc95xx_priv *pdata = dev->driver_priv;
-	u32 read_buf, write_buf, burst_cap;
+	u32 read_buf, burst_cap;
 	int ret = 0, timeout;
 
 	netif_dbg(dev, ifup, dev->net, "entering smsc95xx_reset\n");
@@ -1003,10 +1003,13 @@
 		return ret;
 	netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x\n", read_buf);
 
+	ret = smsc95xx_read_reg(dev, LED_GPIO_CFG, &read_buf);
+	if (ret < 0)
+		return ret;
 	/* Configure GPIO pins as LED outputs */
-	write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED |
-		LED_GPIO_CFG_FDX_LED;
-	ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf);
+	read_buf |= LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED |
+		    LED_GPIO_CFG_FDX_LED;
+	ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, read_buf);
 	if (ret < 0)
 		return ret;
 
@@ -1810,9 +1813,11 @@
 
 static void smsc95xx_rx_csum_offload(struct sk_buff *skb)
 {
-	skb->csum = *(u16 *)(skb_tail_pointer(skb) - 2);
+	u16 *csum_ptr = (u16 *)(skb_tail_pointer(skb) - 2);
+
+	skb->csum = (__force __wsum)get_unaligned(csum_ptr);
 	skb->ip_summed = CHECKSUM_COMPLETE;
-	skb_trim(skb, skb->len - 2);
+	skb_trim(skb, skb->len - 2); /* remove csum */
 }
 
 static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
@@ -1870,25 +1875,22 @@
 				if (dev->net->features & NETIF_F_RXCSUM)
 					smsc95xx_rx_csum_offload(skb);
 				skb_trim(skb, skb->len - 4); /* remove fcs */
-				skb->truesize = size + sizeof(struct sk_buff);
 
 				return 1;
 			}
 
-			ax_skb = skb_clone(skb, GFP_ATOMIC);
+			ax_skb = netdev_alloc_skb_ip_align(dev->net, size);
 			if (unlikely(!ax_skb)) {
 				netdev_warn(dev->net, "Error allocating skb\n");
 				return 0;
 			}
 
-			ax_skb->len = size;
-			ax_skb->data = packet;
-			skb_set_tail_pointer(ax_skb, size);
+			skb_put(ax_skb, size);
+			memcpy(ax_skb->data, packet, size);
 
 			if (dev->net->features & NETIF_F_RXCSUM)
 				smsc95xx_rx_csum_offload(ax_skb);
 			skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
-			ax_skb->truesize = size + sizeof(struct sk_buff);
 
 			usbnet_skb_return(dev, ax_skb);
 		}
--- linux-qcom-6.8.0.orig/drivers/net/usb/sr9700.c
+++ linux-qcom-6.8.0/drivers/net/usb/sr9700.c
@@ -179,6 +179,7 @@
 	struct usbnet *dev = netdev_priv(netdev);
 	__le16 res;
 	int rc = 0;
+	int err;
 
 	if (phy_id) {
 		netdev_dbg(netdev, "Only internal phy supported\n");
@@ -189,11 +190,17 @@
 	if (loc == MII_BMSR) {
 		u8 value;
 
-		sr_read_reg(dev, SR_NSR, &value);
+		err = sr_read_reg(dev, SR_NSR, &value);
+		if (err < 0)
+			return err;
+
 		if (value & NSR_LINKST)
 			rc = 1;
 	}
-	sr_share_read_word(dev, 1, loc, &res);
+	err = sr_share_read_word(dev, 1, loc, &res);
+	if (err < 0)
+		return err;
+
 	if (rc == 1)
 		res = le16_to_cpu(res) | BMSR_LSTATUS;
 	else
@@ -421,19 +428,15 @@
 			skb_pull(skb, 3);
 			skb->len = len;
 			skb_set_tail_pointer(skb, len);
-			skb->truesize = len + sizeof(struct sk_buff);
 			return 2;
 		}
 
-		/* skb_clone is used for address align */
-		sr_skb = skb_clone(skb, GFP_ATOMIC);
+		sr_skb = netdev_alloc_skb_ip_align(dev->net, len);
 		if (!sr_skb)
 			return 0;
 
-		sr_skb->len = len;
-		sr_skb->data = skb->data + 3;
-		skb_set_tail_pointer(sr_skb, len);
-		sr_skb->truesize = len + sizeof(struct sk_buff);
+		skb_put(sr_skb, len);
+		memcpy(sr_skb->data, skb->data + 3, len);
 		usbnet_skb_return(dev, sr_skb);
 
 		skb_pull(skb, len + SR_RX_OVERHEAD);
--- linux-qcom-6.8.0.orig/drivers/net/usb/sr9800.c
+++ linux-qcom-6.8.0/drivers/net/usb/sr9800.c
@@ -737,7 +737,9 @@
 
 	data->eeprom_len = SR9800_EEPROM_LEN;
 
-	usbnet_get_endpoints(dev, intf);
+	ret = usbnet_get_endpoints(dev, intf);
+	if (ret)
+		goto out;
 
 	/* LED Setting Rule :
 	 * AABB:CCDD
--- linux-qcom-6.8.0.orig/drivers/net/usb/usbnet.c
+++ linux-qcom-6.8.0/drivers/net/usb/usbnet.c
@@ -61,9 +61,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-// randomly generated ethernet address
-static u8	node_id [ETH_ALEN];
-
 /* use ethtool to change the level for any given device */
 static int msg_level = -1;
 module_param (msg_level, int, 0);
@@ -467,10 +464,15 @@
 void usbnet_defer_kevent (struct usbnet *dev, int work)
 {
 	set_bit (work, &dev->flags);
-	if (!schedule_work (&dev->kevent))
-		netdev_dbg(dev->net, "kevent %s may have been dropped\n", usbnet_event_names[work]);
-	else
-		netdev_dbg(dev->net, "kevent %s scheduled\n", usbnet_event_names[work]);
+	if (!usbnet_going_away(dev)) {
+		if (!schedule_work(&dev->kevent))
+			netdev_dbg(dev->net,
+				   "kevent %s may have been dropped\n",
+				   usbnet_event_names[work]);
+		else
+			netdev_dbg(dev->net,
+				   "kevent %s scheduled\n", usbnet_event_names[work]);
+	}
 }
 EXPORT_SYMBOL_GPL(usbnet_defer_kevent);
 
@@ -538,7 +540,8 @@
 			tasklet_schedule (&dev->bh);
 			break;
 		case 0:
-			__usbnet_queue_skb(&dev->rxq, skb, rx_start);
+			if (!usbnet_going_away(dev))
+				__usbnet_queue_skb(&dev->rxq, skb, rx_start);
 		}
 	} else {
 		netif_dbg(dev, ifdown, dev->net, "rx: stopped\n");
@@ -846,9 +849,18 @@
 
 	/* deferred work (timer, softirq, task) must also stop */
 	dev->flags = 0;
-	del_timer_sync (&dev->delay);
-	tasklet_kill (&dev->bh);
+	del_timer_sync(&dev->delay);
+	tasklet_kill(&dev->bh);
 	cancel_work_sync(&dev->kevent);
+
+	/* We have cyclic dependencies. Those calls are needed
+	 * to break a cycle. We cannot fall into the gaps because
+	 * we have a flag
+	 */
+	tasklet_kill(&dev->bh);
+	del_timer_sync(&dev->delay);
+	cancel_work_sync(&dev->kevent);
+
 	if (!pm)
 		usb_autopm_put_interface(dev->intf);
 
@@ -1174,7 +1186,8 @@
 					   status);
 		} else {
 			clear_bit (EVENT_RX_HALT, &dev->flags);
-			tasklet_schedule (&dev->bh);
+			if (!usbnet_going_away(dev))
+				tasklet_schedule(&dev->bh);
 		}
 	}
 
@@ -1199,7 +1212,8 @@
 			usb_autopm_put_interface(dev->intf);
 fail_lowmem:
 			if (resched)
-				tasklet_schedule (&dev->bh);
+				if (!usbnet_going_away(dev))
+					tasklet_schedule(&dev->bh);
 		}
 	}
 
@@ -1562,6 +1576,7 @@
 	} else if (netif_running (dev->net) &&
 		   netif_device_present (dev->net) &&
 		   netif_carrier_ok(dev->net) &&
+		   !usbnet_going_away(dev) &&
 		   !timer_pending(&dev->delay) &&
 		   !test_bit(EVENT_RX_PAUSED, &dev->flags) &&
 		   !test_bit(EVENT_RX_HALT, &dev->flags)) {
@@ -1609,6 +1624,7 @@
 	usb_set_intfdata(intf, NULL);
 	if (!dev)
 		return;
+	usbnet_mark_going_away(dev);
 
 	xdev = interface_to_usbdev (intf);
 
@@ -1731,7 +1747,6 @@
 
 	dev->net = net;
 	strscpy(net->name, "usb%d", sizeof(net->name));
-	eth_hw_addr_set(net, node_id);
 
 	/* rx and tx sides can use different message sizes;
 	 * bind() should set rx_urb_size in that case.
@@ -1756,7 +1771,8 @@
 		// can rename the link if it knows better.
 		if ((dev->driver_info->flags & FLAG_ETHER) != 0 &&
 		    ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 ||
-		     (net->dev_addr [0] & 0x02) == 0))
+		     /* somebody touched it*/
+		     !is_zero_ether_addr(net->dev_addr)))
 			strscpy(net->name, "eth%d", sizeof(net->name));
 		/* WLAN devices should always be named "wlan%d" */
 		if ((dev->driver_info->flags & FLAG_WLAN) != 0)
@@ -1805,9 +1821,9 @@
 		goto out4;
 	}
 
-	/* let userspace know we have a random address */
-	if (ether_addr_equal(net->dev_addr, node_id))
-		net->addr_assign_type = NET_ADDR_RANDOM;
+	/* this flags the device for user space */
+	if (!is_valid_ether_addr(net->dev_addr))
+		eth_hw_addr_random(net);
 
 	if ((dev->driver_info->flags & FLAG_WLAN) != 0)
 		SET_NETDEV_DEVTYPE(net, &wlan_type);
@@ -1859,6 +1875,7 @@
 	 * may trigger an error resubmitting itself and, worse,
 	 * schedule a timer. So we kill it all just in case.
 	 */
+	usbnet_mark_going_away(dev);
 	cancel_work_sync(&dev->kevent);
 	del_timer_sync(&dev->delay);
 	free_percpu(net->tstats);
@@ -2217,7 +2234,6 @@
 	BUILD_BUG_ON(
 		sizeof_field(struct sk_buff, cb) < sizeof(struct skb_data));
 
-	eth_random_addr(node_id);
 	return 0;
 }
 module_init(usbnet_init);
--- linux-qcom-6.8.0.orig/drivers/net/veth.c
+++ linux-qcom-6.8.0/drivers/net/veth.c
@@ -1483,6 +1483,7 @@
 
 static int veth_dev_init(struct net_device *dev)
 {
+	netdev_lockdep_set_classes(dev);
 	return veth_alloc_queues(dev);
 }
 
@@ -1533,8 +1534,6 @@
 		if (peer_priv->_xdp_prog)
 			features &= ~NETIF_F_GSO_SOFTWARE;
 	}
-	if (priv->_xdp_prog)
-		features |= NETIF_F_GRO;
 
 	return features;
 }
@@ -1638,14 +1637,6 @@
 		}
 
 		if (!old_prog) {
-			if (!veth_gro_requested(dev)) {
-				/* user-space did not require GRO, but adding
-				 * XDP is supposed to get GRO working
-				 */
-				dev->features |= NETIF_F_GRO;
-				netdev_features_change(dev);
-			}
-
 			peer->hw_features &= ~NETIF_F_GSO_SOFTWARE;
 			peer->max_mtu = max_mtu;
 		}
@@ -1661,14 +1652,6 @@
 			if (dev->flags & IFF_UP)
 				veth_disable_xdp(dev);
 
-			/* if user-space did not require GRO, since adding XDP
-			 * enabled it, clear it now
-			 */
-			if (!veth_gro_requested(dev)) {
-				dev->features &= ~NETIF_F_GRO;
-				netdev_features_change(dev);
-			}
-
 			if (peer) {
 				peer->hw_features |= NETIF_F_GSO_SOFTWARE;
 				peer->max_mtu = ETH_MAX_MTU;
--- linux-qcom-6.8.0.orig/drivers/net/virtio_net.c
+++ linux-qcom-6.8.0/drivers/net/virtio_net.c
@@ -695,9 +695,6 @@
 	void *buf, *head;
 	dma_addr_t addr;
 
-	if (unlikely(!skb_page_frag_refill(size, alloc_frag, gfp)))
-		return NULL;
-
 	head = page_address(alloc_frag->page);
 
 	if (rq->do_dma) {
@@ -1209,6 +1206,10 @@
 	if (unlikely(hdr->hdr.gso_type))
 		goto err_xdp;
 
+	/* Partially checksummed packets must be dropped. */
+	if (unlikely(hdr->hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM))
+		goto err_xdp;
+
 	buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
 		SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 
@@ -1284,6 +1285,11 @@
 	struct page *page = virt_to_head_page(buf);
 	struct sk_buff *skb;
 
+	/* We passed the address of virtnet header to virtio-core,
+	 * so truncate the padding.
+	 */
+	buf -= VIRTNET_RX_PAD + xdp_headroom;
+
 	len -= vi->hdr_len;
 	u64_stats_add(&stats->bytes, len);
 
@@ -1526,6 +1532,10 @@
 	if (unlikely(hdr->hdr.gso_type))
 		return NULL;
 
+	/* Partially checksummed packets must be dropped. */
+	if (unlikely(hdr->hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM))
+		return NULL;
+
 	/* Now XDP core assumes frag size is PAGE_SIZE, but buffers
 	 * with headroom may add hole in truesize, which
 	 * make their length exceed PAGE_SIZE. So we disabled the
@@ -1792,6 +1802,7 @@
 	struct net_device *dev = vi->dev;
 	struct sk_buff *skb;
 	struct virtio_net_common_hdr *hdr;
+	u8 flags;
 
 	if (unlikely(len < vi->hdr_len + ETH_HLEN)) {
 		pr_debug("%s: short packet %i\n", dev->name, len);
@@ -1800,6 +1811,15 @@
 		return;
 	}
 
+	/* 1. Save the flags early, as the XDP program might overwrite them.
+	 * These flags ensure packets marked as VIRTIO_NET_HDR_F_DATA_VALID
+	 * stay valid after XDP processing.
+	 * 2. XDP doesn't work with partially checksummed packets (refer to
+	 * virtnet_xdp_set()), so packets marked as
+	 * VIRTIO_NET_HDR_F_NEEDS_CSUM get dropped during XDP processing.
+	 */
+	flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags;
+
 	if (vi->mergeable_rx_bufs)
 		skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
 					stats);
@@ -1815,7 +1835,7 @@
 	if (dev->features & NETIF_F_RXHASH && vi->has_rss_hash_report)
 		virtio_skb_set_hash(&hdr->hash_v1_hdr, skb);
 
-	if (hdr->hdr.flags & VIRTIO_NET_HDR_F_DATA_VALID)
+	if (flags & VIRTIO_NET_HDR_F_DATA_VALID)
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 	if (virtio_net_hdr_to_skb(skb, &hdr->hdr,
@@ -1856,12 +1876,16 @@
 	len = SKB_DATA_ALIGN(len) +
 	      SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 
+	if (unlikely(!skb_page_frag_refill(len, &rq->alloc_frag, gfp)))
+		return -ENOMEM;
+
 	buf = virtnet_rq_alloc(rq, len, gfp);
 	if (unlikely(!buf))
 		return -ENOMEM;
 
-	virtnet_rq_init_one_sg(rq, buf + VIRTNET_RX_PAD + xdp_headroom,
-			       vi->hdr_len + GOOD_PACKET_LEN);
+	buf += VIRTNET_RX_PAD + xdp_headroom;
+
+	virtnet_rq_init_one_sg(rq, buf, vi->hdr_len + GOOD_PACKET_LEN);
 
 	err = virtqueue_add_inbuf_ctx(rq->vq, rq->sg, 1, buf, ctx, gfp);
 	if (err < 0) {
@@ -1957,6 +1981,12 @@
 	 */
 	len = get_mergeable_buf_len(rq, &rq->mrg_avg_pkt_len, room);
 
+	if (unlikely(!skb_page_frag_refill(len + room, alloc_frag, gfp)))
+		return -ENOMEM;
+
+	if (!alloc_frag->offset && len + room + sizeof(struct virtnet_rq_dma) > alloc_frag->size)
+		len -= sizeof(struct virtnet_rq_dma);
+
 	buf = virtnet_rq_alloc(rq, len + room, gfp);
 	if (unlikely(!buf))
 		return -ENOMEM;
@@ -2142,7 +2172,7 @@
 	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;
 	unsigned int index = vq2rxq(rq->vq);
@@ -2160,7 +2190,7 @@
 
 		do {
 			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)));
 
 		if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS)
@@ -2198,7 +2228,7 @@
 	unsigned int xdp_xmit = 0;
 	bool napi_complete;
 
-	virtnet_poll_cleantx(rq);
+	virtnet_poll_cleantx(rq, budget);
 
 	received = virtnet_receive(rq, budget, &xdp_xmit);
 	rq->packets_in_napi += received;
@@ -2258,6 +2288,25 @@
 	return err;
 }
 
+static void virtnet_update_settings(struct virtnet_info *vi)
+{
+	u32 speed;
+	u8 duplex;
+
+	if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_SPEED_DUPLEX))
+		return;
+
+	virtio_cread_le(vi->vdev, struct virtio_net_config, speed, &speed);
+
+	if (ethtool_validate_speed(speed))
+		vi->speed = speed;
+
+	virtio_cread_le(vi->vdev, struct virtio_net_config, duplex, &duplex);
+
+	if (ethtool_validate_duplex(duplex))
+		vi->duplex = duplex;
+}
+
 static int virtnet_open(struct net_device *dev)
 {
 	struct virtnet_info *vi = netdev_priv(dev);
@@ -2276,6 +2325,15 @@
 			goto err_enable_qp;
 	}
 
+	if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
+		if (vi->status & VIRTIO_NET_S_LINK_UP)
+			netif_carrier_on(vi->dev);
+		virtio_config_driver_enable(vi->vdev);
+	} else {
+		vi->status = VIRTIO_NET_S_LINK_UP;
+		netif_carrier_on(dev);
+	}
+
 	return 0;
 
 err_enable_qp:
@@ -2308,7 +2366,7 @@
 	txq = netdev_get_tx_queue(vi->dev, index);
 	__netif_tx_lock(txq, raw_smp_processor_id());
 	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)
 		netif_tx_wake_queue(txq);
@@ -2697,12 +2755,22 @@
 	disable_delayed_refill(vi);
 	/* Make sure refill_work doesn't re-enable napi! */
 	cancel_delayed_work_sync(&vi->refill);
+	/* Prevent the config change callback from changing carrier
+	 * after close
+	 */
+	virtio_config_driver_disable(vi->vdev);
+	/* Stop getting status/speed updates: we don't care until next
+	 * open
+	 */
+	cancel_work_sync(&vi->config_work);
 
 	for (i = 0; i < vi->max_queue_pairs; i++) {
 		virtnet_disable_queue_pair(vi, i);
 		cancel_work_sync(&vi->rq[i].dim.work);
 	}
 
+	netif_carrier_off(dev);
+
 	return 0;
 }
 
@@ -2932,6 +3000,9 @@
 {
 	int err;
 
+	if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_VQ_NOTF_COAL))
+		return -EOPNOTSUPP;
+
 	err = virtnet_send_ctrl_coal_vq_cmd(vi, rxq2vq(queue),
 					    max_usecs, max_packets);
 	if (err)
@@ -2949,6 +3020,9 @@
 {
 	int err;
 
+	if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_VQ_NOTF_COAL))
+		return -EOPNOTSUPP;
+
 	err = virtnet_send_ctrl_coal_vq_cmd(vi, txq2vq(queue),
 					    max_usecs, max_packets);
 	if (err)
@@ -3017,7 +3091,11 @@
 			err = virtnet_send_tx_ctrl_coal_vq_cmd(vi, i,
 							       vi->intr_coal_tx.max_usecs,
 							       vi->intr_coal_tx.max_packets);
-			if (err)
+
+			/* Don't break the tx resize action if the vq coalescing is not
+			 * supported. The same is true for rx resize below.
+			 */
+			if (err && err != -EOPNOTSUPP)
 				return err;
 		}
 
@@ -3030,7 +3108,7 @@
 			err = virtnet_send_rx_ctrl_coal_vq_cmd(vi, i,
 							       vi->intr_coal_rx.max_usecs,
 							       vi->intr_coal_rx.max_packets);
-			if (err)
+			if (err && err != -EOPNOTSUPP)
 				return err;
 		}
 	}
@@ -3550,10 +3628,10 @@
 			if (err)
 				pr_debug("%s: Failed to send dim parameters on rxq%d\n",
 					 dev->name, qnum);
-			dim->state = DIM_START_MEASURE;
 		}
 	}
 
+	dim->state = DIM_START_MEASURE;
 	rtnl_unlock();
 }
 
@@ -3715,25 +3793,6 @@
 	vi->duplex = DUPLEX_UNKNOWN;
 }
 
-static void virtnet_update_settings(struct virtnet_info *vi)
-{
-	u32 speed;
-	u8 duplex;
-
-	if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_SPEED_DUPLEX))
-		return;
-
-	virtio_cread_le(vi->vdev, struct virtio_net_config, speed, &speed);
-
-	if (ethtool_validate_speed(speed))
-		vi->speed = speed;
-
-	virtio_cread_le(vi->vdev, struct virtio_net_config, duplex, &duplex);
-
-	if (ethtool_validate_duplex(duplex))
-		vi->duplex = duplex;
-}
-
 static u32 virtnet_get_rxfh_key_size(struct net_device *dev)
 {
 	return ((struct virtnet_info *)netdev_priv(dev))->rss_key_size;
@@ -3768,6 +3827,7 @@
 			    struct netlink_ext_ack *extack)
 {
 	struct virtnet_info *vi = netdev_priv(dev);
+	bool update = false;
 	int i;
 
 	if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
@@ -3775,13 +3835,28 @@
 		return -EOPNOTSUPP;
 
 	if (rxfh->indir) {
+		if (!vi->has_rss)
+			return -EOPNOTSUPP;
+
 		for (i = 0; i < vi->rss_indir_table_size; ++i)
 			vi->ctrl->rss.indirection_table[i] = rxfh->indir[i];
+		update = true;
 	}
-	if (rxfh->key)
+
+	if (rxfh->key) {
+		/* If either _F_HASH_REPORT or _F_RSS are negotiated, the
+		 * device provides hash calculation capabilities, that is,
+		 * hash_key is configured.
+		 */
+		if (!vi->has_rss && !vi->has_rss_hash_report)
+			return -EOPNOTSUPP;
+
 		memcpy(vi->ctrl->rss.key, rxfh->key, vi->rss_key_size);
+		update = true;
+	}
 
-	virtnet_commit_rss_command(vi);
+	if (update)
+		virtnet_commit_rss_command(vi);
 
 	return 0;
 }
@@ -4640,8 +4715,16 @@
 			dev->features |= dev->hw_features & NETIF_F_ALL_TSO;
 		/* (!csum && gso) case will be fixed by register_netdev() */
 	}
-	if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM))
-		dev->features |= NETIF_F_RXCSUM;
+
+	/* 1. With VIRTIO_NET_F_GUEST_CSUM negotiation, the driver doesn't
+	 * need to calculate checksums for partially checksummed packets,
+	 * as they're considered valid by the upper layer.
+	 * 2. Without VIRTIO_NET_F_GUEST_CSUM negotiation, the driver only
+	 * receives fully checksummed packets. The device may assist in
+	 * validating these packets' checksums, so the driver won't have to.
+	 */
+	dev->features |= NETIF_F_RXCSUM;
+
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
 	    virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6))
 		dev->features |= NETIF_F_GRO_HW;
@@ -4686,15 +4769,23 @@
 	if (virtio_has_feature(vdev, VIRTIO_NET_F_HASH_REPORT))
 		vi->has_rss_hash_report = true;
 
-	if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS))
+	if (virtio_has_feature(vdev, VIRTIO_NET_F_RSS)) {
 		vi->has_rss = true;
 
-	if (vi->has_rss || vi->has_rss_hash_report) {
 		vi->rss_indir_table_size =
 			virtio_cread16(vdev, offsetof(struct virtio_net_config,
 				rss_max_indirection_table_length));
+	}
+
+	if (vi->has_rss || vi->has_rss_hash_report) {
 		vi->rss_key_size =
 			virtio_cread8(vdev, offsetof(struct virtio_net_config, rss_max_key_size));
+		if (vi->rss_key_size > VIRTIO_NET_RSS_MAX_KEY_SIZE) {
+			dev_err(&vdev->dev, "rss_max_key_size=%u exceeds the limit %u.\n",
+				vi->rss_key_size, VIRTIO_NET_RSS_MAX_KEY_SIZE);
+			err = -EINVAL;
+			goto free;
+		}
 
 		vi->rss_hash_types_supported =
 		    virtio_cread32(vdev, offsetof(struct virtio_net_config, supported_hash_types));
@@ -4808,8 +4899,20 @@
 		goto free_failover;
 	}
 
+	/* Disable config change notification until ndo_open. */
+	virtio_config_driver_disable(vi->vdev);
+
 	virtio_device_ready(vdev);
 
+	if (vi->has_rss || vi->has_rss_hash_report) {
+		if (!virtnet_commit_rss_command(vi)) {
+			dev_warn(&vdev->dev, "RSS disabled because committing failed.\n");
+			dev->hw_features &= ~NETIF_F_RXHASH;
+			vi->has_rss_hash_report = false;
+			vi->has_rss = false;
+		}
+	}
+
 	_virtnet_set_queues(vi, vi->curr_queue_pairs);
 
 	/* a random MAC address has been assigned, notify the device.
@@ -4830,19 +4933,11 @@
 		}
 	}
 
-	rtnl_unlock();
-
-	err = virtnet_cpu_notif_add(vi);
-	if (err) {
-		pr_debug("virtio_net: registering cpu notifier failed\n");
-		goto free_unregister_netdev;
-	}
-
 	/* Assume link up if device can't report link status,
 	   otherwise get link status from config. */
 	netif_carrier_off(dev);
 	if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
-		schedule_work(&vi->config_work);
+		virtnet_config_changed_work(&vi->config_work);
 	} else {
 		vi->status = VIRTIO_NET_S_LINK_UP;
 		virtnet_update_settings(vi);
@@ -4854,6 +4949,14 @@
 			set_bit(guest_offloads[i], &vi->guest_offloads);
 	vi->guest_offloads_capable = vi->guest_offloads;
 
+	rtnl_unlock();
+
+	err = virtnet_cpu_notif_add(vi);
+	if (err) {
+		pr_debug("virtio_net: registering cpu notifier failed\n");
+		goto free_unregister_netdev;
+	}
+
 	pr_debug("virtnet: registered device %s with %d RX and TX vq's\n",
 		 dev->name, max_queue_pairs);
 
--- linux-qcom-6.8.0.orig/drivers/net/vmxnet3/vmxnet3_drv.c
+++ linux-qcom-6.8.0/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -2034,8 +2034,8 @@
 					  rq->data_ring.base,
 					  rq->data_ring.basePA);
 			rq->data_ring.base = NULL;
-			rq->data_ring.desc_size = 0;
 		}
+		rq->data_ring.desc_size = 0;
 	}
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/vmxnet3/vmxnet3_xdp.c
+++ linux-qcom-6.8.0/drivers/net/vmxnet3/vmxnet3_xdp.c
@@ -28,7 +28,7 @@
 	if (likely(cpu < tq_number))
 		tq = &adapter->tx_queue[cpu];
 	else
-		tq = &adapter->tx_queue[reciprocal_scale(cpu, tq_number)];
+		tq = &adapter->tx_queue[cpu % tq_number];
 
 	return tq;
 }
@@ -124,6 +124,7 @@
 	u32 buf_size;
 	u32 dw2;
 
+	spin_lock_irq(&tq->tx_lock);
 	dw2 = (tq->tx_ring.gen ^ 0x1) << VMXNET3_TXD_GEN_SHIFT;
 	dw2 |= xdpf->len;
 	ctx.sop_txd = tq->tx_ring.base + tq->tx_ring.next2fill;
@@ -134,6 +135,7 @@
 
 	if (vmxnet3_cmd_ring_desc_avail(&tq->tx_ring) == 0) {
 		tq->stats.tx_ring_full++;
+		spin_unlock_irq(&tq->tx_lock);
 		return -ENOSPC;
 	}
 
@@ -142,13 +144,15 @@
 		tbi->dma_addr = dma_map_single(&adapter->pdev->dev,
 					       xdpf->data, buf_size,
 					       DMA_TO_DEVICE);
-		if (dma_mapping_error(&adapter->pdev->dev, tbi->dma_addr))
+		if (dma_mapping_error(&adapter->pdev->dev, tbi->dma_addr)) {
+			spin_unlock_irq(&tq->tx_lock);
 			return -EFAULT;
+		}
 		tbi->map_type |= VMXNET3_MAP_SINGLE;
 	} else { /* XDP buffer from page pool */
 		page = virt_to_page(xdpf->data);
 		tbi->dma_addr = page_pool_get_dma_addr(page) +
-				VMXNET3_XDP_HEADROOM;
+				(xdpf->data - (void *)xdpf);
 		dma_sync_single_for_device(&adapter->pdev->dev,
 					   tbi->dma_addr, buf_size,
 					   DMA_TO_DEVICE);
@@ -182,6 +186,7 @@
 	dma_wmb();
 	gdesc->dword[2] = cpu_to_le32(le32_to_cpu(gdesc->dword[2]) ^
 						  VMXNET3_TXD_GEN);
+	spin_unlock_irq(&tq->tx_lock);
 
 	/* No need to handle the case when tx_num_deferred doesn't reach
 	 * threshold. Backend driver at hypervisor side will poll and reset
@@ -225,6 +230,7 @@
 {
 	struct vmxnet3_adapter *adapter = netdev_priv(dev);
 	struct vmxnet3_tx_queue *tq;
+	struct netdev_queue *nq;
 	int i;
 
 	if (unlikely(test_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state)))
@@ -236,6 +242,9 @@
 	if (tq->stopped)
 		return -ENETDOWN;
 
+	nq = netdev_get_tx_queue(adapter->netdev, tq->qid);
+
+	__netif_tx_lock(nq, smp_processor_id());
 	for (i = 0; i < n; i++) {
 		if (vmxnet3_xdp_xmit_frame(adapter, frames[i], tq, true)) {
 			tq->stats.xdp_xmit_err++;
@@ -243,6 +252,7 @@
 		}
 	}
 	tq->stats.xdp_xmit += i;
+	__netif_tx_unlock(nq);
 
 	return i;
 }
@@ -382,12 +392,12 @@
 	page = rbi->page;
 	dma_sync_single_for_cpu(&adapter->pdev->dev,
 				page_pool_get_dma_addr(page) +
-				rq->page_pool->p.offset, rcd->len,
+				rq->page_pool->p.offset, rbi->len,
 				page_pool_get_dma_dir(rq->page_pool));
 
-	xdp_init_buff(&xdp, rbi->len, &rq->xdp_rxq);
+	xdp_init_buff(&xdp, PAGE_SIZE, &rq->xdp_rxq);
 	xdp_prepare_buff(&xdp, page_address(page), rq->page_pool->p.offset,
-			 rcd->len, false);
+			 rbi->len, false);
 	xdp_buff_clear_frags_flag(&xdp);
 
 	xdp_prog = rcu_dereference(rq->adapter->xdp_bpf_prog);
--- linux-qcom-6.8.0.orig/drivers/net/vrf.c
+++ linux-qcom-6.8.0/drivers/net/vrf.c
@@ -628,7 +628,9 @@
 		eth_zero_addr(eth->h_dest);
 		eth->h_proto = skb->protocol;
 
+		rcu_read_lock_bh();
 		dev_queue_xmit_nit(skb, vrf_dev);
+		rcu_read_unlock_bh();
 
 		skb_pull(skb, ETH_HLEN);
 	}
@@ -653,7 +655,7 @@
 	skb->dev = dev;
 
 	rcu_read_lock();
-	nexthop = rt6_nexthop((struct rt6_info *)dst, &ipv6_hdr(skb)->daddr);
+	nexthop = rt6_nexthop(dst_rt6_info(dst), &ipv6_hdr(skb)->daddr);
 	neigh = __ipv6_neigh_lookup_noref(dst->dev, nexthop);
 	if (unlikely(!neigh))
 		neigh = __neigh_create(&nd_tbl, nexthop, dst->dev, false);
@@ -860,7 +862,7 @@
 static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
 	struct dst_entry *dst = skb_dst(skb);
-	struct rtable *rt = (struct rtable *)dst;
+	struct rtable *rt = dst_rtable(dst);
 	struct net_device *dev = dst->dev;
 	unsigned int hh_len = LL_RESERVED_SPACE(dev);
 	struct neighbour *neigh;
--- linux-qcom-6.8.0.orig/drivers/net/vxlan/vxlan_core.c
+++ linux-qcom-6.8.0/drivers/net/vxlan/vxlan_core.c
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/udp.h>
 #include <linux/igmp.h>
+#include <linux/inetdevice.h>
 #include <linux/if_ether.h>
 #include <linux/ethtool.h>
 #include <net/arp.h>
@@ -71,6 +72,167 @@
 	       ip_tunnel_collect_metadata();
 }
 
+static struct ip_fan_map *vxlan_fan_find_map(struct vxlan_dev *vxlan, __be32 daddr)
+{
+	struct ip_fan_map *fan_map;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(fan_map, &vxlan->fan.fan_maps, list) {
+		if (fan_map->overlay ==
+		    (daddr & inet_make_mask(fan_map->overlay_prefix))) {
+			rcu_read_unlock();
+			return fan_map;
+		}
+	}
+	rcu_read_unlock();
+
+	return NULL;
+}
+
+static void vxlan_fan_flush_map(struct vxlan_dev *vxlan)
+{
+	struct ip_fan_map *fan_map;
+
+	list_for_each_entry_rcu(fan_map, &vxlan->fan.fan_maps, list) {
+		list_del_rcu(&fan_map->list);
+		kfree_rcu(fan_map, rcu);
+	}
+}
+
+static int vxlan_fan_del_map(struct vxlan_dev *vxlan, __be32 overlay)
+{
+	struct ip_fan_map *fan_map;
+
+	fan_map = vxlan_fan_find_map(vxlan, overlay);
+	if (!fan_map)
+		return -ENOENT;
+
+	list_del_rcu(&fan_map->list);
+	kfree_rcu(fan_map, rcu);
+
+	return 0;
+}
+
+static int vxlan_fan_add_map(struct vxlan_dev *vxlan, struct ifla_fan_map *map)
+{
+	__be32 overlay_mask, underlay_mask;
+	struct ip_fan_map *fan_map;
+
+	overlay_mask = inet_make_mask(map->overlay_prefix);
+	underlay_mask = inet_make_mask(map->underlay_prefix);
+
+	netdev_dbg(vxlan->dev, "vfam: map: o %x/%d u %x/%d om %x um %x\n",
+		   map->overlay, map->overlay_prefix,
+		   map->underlay, map->underlay_prefix,
+		   overlay_mask, underlay_mask);
+
+	if ((map->overlay & ~overlay_mask) || (map->underlay & ~underlay_mask))
+		return -EINVAL;
+
+	if (!(map->overlay & overlay_mask) && (map->underlay & underlay_mask))
+		return -EINVAL;
+
+	/* Special case: overlay 0 and underlay 0: flush all mappings */
+	if (!map->overlay && !map->underlay) {
+		vxlan_fan_flush_map(vxlan);
+		return 0;
+	}
+
+	/* Special case: overlay set and underlay 0: clear map for overlay */
+	if (!map->underlay)
+		return vxlan_fan_del_map(vxlan, map->overlay);
+
+	if (vxlan_fan_find_map(vxlan, map->overlay))
+		return -EEXIST;
+
+	fan_map = kmalloc(sizeof(*fan_map), GFP_KERNEL);
+	fan_map->underlay = map->underlay;
+	fan_map->overlay = map->overlay;
+	fan_map->underlay_prefix = map->underlay_prefix;
+	fan_map->overlay_mask = ntohl(overlay_mask);
+	fan_map->overlay_prefix = map->overlay_prefix;
+
+	list_add_tail_rcu(&fan_map->list, &vxlan->fan.fan_maps);
+
+	return 0;
+}
+
+static int vxlan_parse_fan_map(struct nlattr *data[], struct vxlan_dev *vxlan)
+{
+	struct ifla_fan_map *map;
+	struct nlattr *attr;
+	int rem, rv;
+
+	nla_for_each_nested(attr, data[IFLA_IPTUN_FAN_MAP], rem) {
+		map = nla_data(attr);
+		rv = vxlan_fan_add_map(vxlan, map);
+		if (rv)
+			return rv;
+	}
+
+	return 0;
+}
+
+static int vxlan_fan_build_rdst(struct vxlan_dev *vxlan, struct sk_buff *skb,
+				      struct vxlan_rdst *fan_rdst)
+{
+	struct ip_fan_map *f_map;
+	union vxlan_addr *va;
+	u32 daddr, underlay;
+	struct arphdr *arp;
+	void *arp_ptr;
+	struct ethhdr *eth;
+	struct iphdr *iph;
+
+	eth = eth_hdr(skb);
+	switch (eth->h_proto) {
+	case htons(ETH_P_IP):
+		iph = ip_hdr(skb);
+		if (!iph)
+			return -EINVAL;
+		daddr = iph->daddr;
+		break;
+	case htons(ETH_P_ARP):
+		arp = arp_hdr(skb);
+		if (!arp)
+			return -EINVAL;
+		arp_ptr = arp + 1;
+		netdev_dbg(vxlan->dev,
+			   "vfbr: arp sha %pM sip %pI4 tha %pM tip %pI4\n",
+			   arp_ptr, arp_ptr + skb->dev->addr_len,
+			   arp_ptr + skb->dev->addr_len + 4,
+			   arp_ptr + (skb->dev->addr_len * 2) + 4);
+		arp_ptr += (skb->dev->addr_len * 2) + 4;
+		memcpy(&daddr, arp_ptr, 4);
+		break;
+	default:
+		netdev_dbg(vxlan->dev, "vfbr: unknown eth p %x\n", eth->h_proto);
+		return -EINVAL;
+	}
+
+	f_map = vxlan_fan_find_map(vxlan, daddr);
+	if (!f_map)
+		return -EINVAL;
+
+	daddr = ntohl(daddr);
+	underlay = ntohl(f_map->underlay);
+	if (!underlay)
+		return -EINVAL;
+
+	memset(fan_rdst, 0, sizeof(*fan_rdst));
+	va = &fan_rdst->remote_ip;
+	va->sa.sa_family = AF_INET;
+	fan_rdst->remote_vni = vxlan->default_dst.remote_vni;
+	va->sin.sin_addr.s_addr = htonl(underlay |
+					((daddr & ~f_map->overlay_mask) >>
+					 (32 - f_map->overlay_prefix -
+					  (32 - f_map->underlay_prefix))));
+	netdev_dbg(vxlan->dev, "vfbr: daddr %x ul %x dst %x\n",
+		   daddr, underlay, va->sin.sin_addr.s_addr);
+
+	return 0;
+}
+
 /* Find VXLAN socket based on network namespace, address family, UDP port,
  * enabled unshareable flags and socket device binding (see l3mdev with
  * non-default VRF).
@@ -1446,6 +1608,10 @@
 	struct vxlan_fdb *f;
 	u32 ifindex = 0;
 
+	/* Ignore packets from invalid src-address */
+	if (!is_valid_ether_addr(src_mac))
+		return true;
+
 #if IS_ENABLED(CONFIG_IPV6)
 	if (src_ip->sa.sa_family == AF_INET6 &&
 	    (ipv6_addr_type(&src_ip->sin6.sin6_addr) & IPV6_ADDR_LINKLOCAL))
@@ -1670,6 +1836,7 @@
 	bool raw_proto = false;
 	void *oiph;
 	__be32 vni = 0;
+	int nh;
 
 	/* Need UDP and VXLAN header to be present */
 	if (!pskb_may_pull(skb, VXLAN_HLEN))
@@ -1758,12 +1925,28 @@
 		skb->pkt_type = PACKET_HOST;
 	}
 
-	oiph = skb_network_header(skb);
+	/* Save offset of outer header relative to skb->head,
+	 * because we are going to reset the network header to the inner header
+	 * and might change skb->head.
+	 */
+	nh = skb_network_header(skb) - skb->head;
+
 	skb_reset_network_header(skb);
 
+	if (!pskb_inet_may_pull(skb)) {
+		DEV_STATS_INC(vxlan->dev, rx_length_errors);
+		DEV_STATS_INC(vxlan->dev, rx_errors);
+		vxlan_vnifilter_count(vxlan, vni, vninode,
+				      VXLAN_VNI_STATS_RX_ERRORS, 0);
+		goto drop;
+	}
+
+	/* Get the outer header. */
+	oiph = skb->head + nh;
+
 	if (!vxlan_ecn_decapsulate(vs, oiph, skb)) {
-		++vxlan->dev->stats.rx_frame_errors;
-		++vxlan->dev->stats.rx_errors;
+		DEV_STATS_INC(vxlan->dev, rx_frame_errors);
+		DEV_STATS_INC(vxlan->dev, rx_errors);
 		vxlan_vnifilter_count(vxlan, vni, vninode,
 				      VXLAN_VNI_STATS_RX_ERRORS, 0);
 		goto drop;
@@ -1833,7 +2016,9 @@
 		goto out;
 
 	if (!pskb_may_pull(skb, arp_hdr_len(dev))) {
-		dev->stats.tx_dropped++;
+		dev_core_stats_tx_dropped_inc(dev);
+		vxlan_vnifilter_count(vxlan, vni, NULL,
+				      VXLAN_VNI_STATS_TX_DROPS, 0);
 		goto out;
 	}
 	parp = arp_hdr(skb);
@@ -1889,7 +2074,7 @@
 		reply->pkt_type = PACKET_HOST;
 
 		if (netif_rx(reply) == NET_RX_DROP) {
-			dev->stats.rx_dropped++;
+			dev_core_stats_rx_dropped_inc(dev);
 			vxlan_vnifilter_count(vxlan, vni, NULL,
 					      VXLAN_VNI_STATS_RX_DROPS, 0);
 		}
@@ -2048,7 +2233,7 @@
 			goto out;
 
 		if (netif_rx(reply) == NET_RX_DROP) {
-			dev->stats.rx_dropped++;
+			dev_core_stats_rx_dropped_inc(dev);
 			vxlan_vnifilter_count(vxlan, vni, NULL,
 					      VXLAN_VNI_STATS_RX_DROPS, 0);
 		}
@@ -2259,7 +2444,7 @@
 				      len);
 	} else {
 drop:
-		dev->stats.rx_dropped++;
+		dev_core_stats_rx_dropped_inc(dev);
 		vxlan_vnifilter_count(dst_vxlan, vni, NULL,
 				      VXLAN_VNI_STATS_RX_DROPS, 0);
 	}
@@ -2291,7 +2476,7 @@
 					   addr_family, dst_port,
 					   vxlan->cfg.flags);
 		if (!dst_vxlan) {
-			dev->stats.tx_errors++;
+			DEV_STATS_INC(dev, tx_errors);
 			vxlan_vnifilter_count(vxlan, vni, NULL,
 					      VXLAN_VNI_STATS_TX_ERRORS, 0);
 			kfree_skb(skb);
@@ -2313,7 +2498,7 @@
 	struct ip_tunnel_key *pkey;
 	struct ip_tunnel_key key;
 	struct vxlan_dev *vxlan = netdev_priv(dev);
-	const struct iphdr *old_iph = ip_hdr(skb);
+	const struct iphdr *old_iph;
 	struct vxlan_metadata _md;
 	struct vxlan_metadata *md = &_md;
 	unsigned int pkt_len = skb->len;
@@ -2327,8 +2512,15 @@
 	bool use_cache;
 	bool udp_sum = false;
 	bool xnet = !net_eq(vxlan->net, dev_net(vxlan->dev));
+	bool no_eth_encap;
 	__be32 vni = 0;
 
+	no_eth_encap = flags & VXLAN_F_GPE && skb->protocol != htons(ETH_P_TEB);
+	if (!skb_vlan_inet_prepare(skb, no_eth_encap))
+		goto drop;
+
+	old_iph = ip_hdr(skb);
+
 	info = skb_tunnel_info(skb);
 	use_cache = ip_tunnel_dst_cache_usable(skb, info);
 
@@ -2433,6 +2625,14 @@
 			goto tx_error;
 		}
 
+		if (fan_has_map(&vxlan->fan) && rt->rt_flags & RTCF_LOCAL) {
+			netdev_dbg(dev, "discard fan to localhost %pI4\n",
+				   &rdst->remote_ip.sin.sin_addr.s_addr);
+			rcu_read_unlock();
+			ip_rt_put(rt);
+			goto tx_free;
+		}
+
 		if (!info) {
 			/* Bypass encapsulation if the destination is local */
 			err = encap_bypass_if_local(skb, dev, vxlan, AF_INET,
@@ -2505,7 +2705,7 @@
 		}
 
 		if (!info) {
-			u32 rt6i_flags = ((struct rt6_info *)ndst)->rt6i_flags;
+			u32 rt6i_flags = dst_rt6_info(ndst)->rt6i_flags;
 
 			err = encap_bypass_if_local(skb, dev, vxlan, AF_INET6,
 						    dst_port, ifindex, vni,
@@ -2555,7 +2755,7 @@
 	return;
 
 drop:
-	dev->stats.tx_dropped++;
+	dev_core_stats_tx_dropped_inc(dev);
 	vxlan_vnifilter_count(vxlan, vni, NULL, VXLAN_VNI_STATS_TX_DROPS, 0);
 	dev_kfree_skb(skb);
 	return;
@@ -2563,12 +2763,13 @@
 tx_error:
 	rcu_read_unlock();
 	if (err == -ELOOP)
-		dev->stats.collisions++;
+		DEV_STATS_INC(dev, collisions);
 	else if (err == -ENETUNREACH)
-		dev->stats.tx_carrier_errors++;
+		DEV_STATS_INC(dev, tx_carrier_errors);
 	dst_release(ndst);
-	dev->stats.tx_errors++;
+	DEV_STATS_INC(dev, tx_errors);
 	vxlan_vnifilter_count(vxlan, vni, NULL, VXLAN_VNI_STATS_TX_ERRORS, 0);
+tx_free:
 	kfree_skb(skb);
 }
 
@@ -2600,7 +2801,7 @@
 	return;
 
 drop:
-	dev->stats.tx_dropped++;
+	dev_core_stats_tx_dropped_inc(dev);
 	vxlan_vnifilter_count(netdev_priv(dev), vni, NULL,
 			      VXLAN_VNI_STATS_TX_DROPS, 0);
 	dev_kfree_skb(skb);
@@ -2638,7 +2839,7 @@
 	return NETDEV_TX_OK;
 
 drop:
-	dev->stats.tx_dropped++;
+	dev_core_stats_tx_dropped_inc(dev);
 	vxlan_vnifilter_count(netdev_priv(dev), vni, NULL,
 			      VXLAN_VNI_STATS_TX_DROPS, 0);
 	dev_kfree_skb(skb);
@@ -2716,6 +2917,20 @@
 		rcu_read_unlock();
 	}
 
+	if (fan_has_map(&vxlan->fan)) {
+		struct vxlan_rdst fan_rdst;
+
+		netdev_dbg(vxlan->dev, "vxlan_xmit p %x d %pM\n",
+			   eth->h_proto, eth->h_dest);
+		if (vxlan_fan_build_rdst(vxlan, skb, &fan_rdst)) {
+			dev_core_stats_tx_dropped_inc(dev);
+			kfree_skb(skb);
+			return NETDEV_TX_OK;
+		}
+		vxlan_xmit_one(skb, dev, vni, &fan_rdst, 0);
+		return NETDEV_TX_OK;
+	}
+
 	eth = eth_hdr(skb);
 	f = vxlan_find_mac(vxlan, eth->h_dest, vni);
 	did_rsc = false;
@@ -2735,7 +2950,7 @@
 			    !is_multicast_ether_addr(eth->h_dest))
 				vxlan_fdb_miss(vxlan, eth->h_dest);
 
-			dev->stats.tx_dropped++;
+			dev_core_stats_tx_dropped_inc(dev);
 			vxlan_vnifilter_count(vxlan, vni, NULL,
 					      VXLAN_VNI_STATS_TX_DROPS, 0);
 			kfree_skb(skb);
@@ -2855,6 +3070,7 @@
 	if (err)
 		goto err_gro_cells_destroy;
 
+	netdev_lockdep_set_classes(dev);
 	return 0;
 
 err_gro_cells_destroy:
@@ -3325,6 +3541,8 @@
 		spin_lock_init(&vxlan->hash_lock[h]);
 		INIT_HLIST_HEAD(&vxlan->fdb_head[h]);
 	}
+
+	INIT_LIST_HEAD(&vxlan->fan.fan_maps);
 }
 
 static void vxlan_ether_setup(struct net_device *dev)
@@ -3344,6 +3562,22 @@
 	dev->netdev_ops = &vxlan_netdev_raw_ops;
 }
 
+/* Validate Ubuntu FAN payload.
+ *
+ * This is required to bypass the strict length validation enforced for the
+ * attribute types >= IFLA_VXLAN_LOCALBYPASS in vxlan_policy.
+ *
+ * In this way we can continue to use the same allocated ID for
+ * IFLA_VXLAN_FAN_MAP, without breaking the existing user-space and also
+ * future kernel ABIs that may add new attribute types to vxlan_policy.
+ */
+static int fan_map_validate_entry(const struct nlattr *attr,
+				  struct netlink_ext_ack *extack)
+{
+	/* Accept any payload for Ubuntu FAN */
+	return 0;
+}
+
 static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = {
 	[IFLA_VXLAN_UNSPEC]     = { .strict_start_type = IFLA_VXLAN_LOCALBYPASS },
 	[IFLA_VXLAN_ID]		= { .type = NLA_U32 },
@@ -3378,6 +3612,9 @@
 	[IFLA_VXLAN_VNIFILTER]	= { .type = NLA_U8 },
 	[IFLA_VXLAN_LOCALBYPASS]	= NLA_POLICY_MAX(NLA_U8, 1),
 	[IFLA_VXLAN_LABEL_POLICY]       = NLA_POLICY_MAX(NLA_U32, VXLAN_LABEL_MAX),
+	[IFLA_VXLAN_FAN_MAP]		= NLA_POLICY_VALIDATE_FN(NLA_BINARY,
+						fan_map_validate_entry,
+						sizeof(struct ifla_fan_map) * 256),
 };
 
 static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[],
@@ -4055,6 +4292,12 @@
 		conf->remote_ip.sa.sa_family = AF_INET6;
 	}
 
+	if (data[IFLA_VXLAN_FAN_MAP]) {
+		err = vxlan_parse_fan_map(data, vxlan);
+		if (err)
+			return err;
+	}
+
 	if (data[IFLA_VXLAN_LOCAL]) {
 		if (changelink && (conf->saddr.sa.sa_family != AF_INET)) {
 			NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_VXLAN_LOCAL], "New local address family does not match old");
@@ -4440,6 +4683,7 @@
 		nla_total_size(0) + /* IFLA_VXLAN_GPE */
 		nla_total_size(0) + /* IFLA_VXLAN_REMCSUM_NOPARTIAL */
 		nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_VNIFILTER */
+		nla_total_size(sizeof(struct ip_fan_map) * 256) +
 		0;
 }
 
@@ -4486,6 +4730,26 @@
 		}
 	}
 
+	if (fan_has_map(&vxlan->fan)) {
+		struct nlattr *fan_nest;
+		struct ip_fan_map *fan_map;
+
+		fan_nest = nla_nest_start(skb, IFLA_VXLAN_FAN_MAP);
+		if (!fan_nest)
+			goto nla_put_failure;
+		list_for_each_entry_rcu(fan_map, &vxlan->fan.fan_maps, list) {
+			struct ifla_fan_map map;
+
+			map.underlay = fan_map->underlay;
+			map.underlay_prefix = fan_map->underlay_prefix;
+			map.overlay = fan_map->overlay;
+			map.overlay_prefix = fan_map->overlay_prefix;
+			if (nla_put(skb, IFLA_FAN_MAPPING, sizeof(map), &map))
+				goto nla_put_failure;
+		}
+		nla_nest_end(skb, fan_nest);
+	}
+
 	if (nla_put_u8(skb, IFLA_VXLAN_TTL, vxlan->cfg.ttl) ||
 	    nla_put_u8(skb, IFLA_VXLAN_TTL_INHERIT,
 		       !!(vxlan->cfg.flags & VXLAN_F_TTL_INHERIT)) ||
@@ -4826,6 +5090,22 @@
 					 NULL);
 }
 
+#ifdef CONFIG_SYSCTL
+static struct ctl_table_header *vxlan_fan_header;
+static unsigned int vxlan_fan_version = 4;
+
+static struct ctl_table vxlan_fan_sysctls[] = {
+	{
+		.procname	= "vxlan",
+		.data		= &vxlan_fan_version,
+		.maxlen		= sizeof(vxlan_fan_version),
+		.mode		= 0444,
+		.proc_handler	= proc_dointvec,
+	},
+	{},
+};
+#endif /* CONFIG_SYSCTL */
+
 static void vxlan_destroy_tunnels(struct net *net, struct list_head *head)
 {
 	struct vxlan_net *vn = net_generic(net, vxlan_net_id);
@@ -4901,9 +5181,22 @@
 	if (rc)
 		goto out4;
 
-	vxlan_vnifilter_init();
+	rc = vxlan_vnifilter_init();
+	if (rc)
+		goto out5;
+
+#ifdef CONFIG_SYSCTL
+	vxlan_fan_header = register_net_sysctl(&init_net, "net/fan",
+					      vxlan_fan_sysctls);
+	if (!vxlan_fan_header) {
+		rc = -ENOMEM;
+		goto out5;
+	}
+#endif /* CONFIG_SYSCTL */
 
 	return 0;
+out5:
+	rtnl_link_unregister(&vxlan_link_ops);
 out4:
 	unregister_switchdev_notifier(&vxlan_switchdev_notifier_block);
 out3:
@@ -4917,6 +5210,9 @@
 
 static void __exit vxlan_cleanup_module(void)
 {
+#ifdef CONFIG_SYSCTL
+	unregister_net_sysctl_table(vxlan_fan_header);
+#endif /* CONFIG_SYSCTL */
 	vxlan_vnifilter_uninit();
 	rtnl_link_unregister(&vxlan_link_ops);
 	unregister_switchdev_notifier(&vxlan_switchdev_notifier_block);
--- linux-qcom-6.8.0.orig/drivers/net/vxlan/vxlan_private.h
+++ linux-qcom-6.8.0/drivers/net/vxlan/vxlan_private.h
@@ -202,7 +202,7 @@
 int vxlan_vnigroup_init(struct vxlan_dev *vxlan);
 void vxlan_vnigroup_uninit(struct vxlan_dev *vxlan);
 
-void vxlan_vnifilter_init(void);
+int vxlan_vnifilter_init(void);
 void vxlan_vnifilter_uninit(void);
 void vxlan_vnifilter_count(struct vxlan_dev *vxlan, __be32 vni,
 			   struct vxlan_vni_node *vninode,
--- linux-qcom-6.8.0.orig/drivers/net/vxlan/vxlan_vnifilter.c
+++ linux-qcom-6.8.0/drivers/net/vxlan/vxlan_vnifilter.c
@@ -411,6 +411,11 @@
 	struct tunnel_msg *tmsg;
 	struct net_device *dev;
 
+	if (cb->nlh->nlmsg_len < nlmsg_msg_size(sizeof(struct tunnel_msg))) {
+		NL_SET_ERR_MSG(cb->extack, "Invalid msg length");
+		return -EINVAL;
+	}
+
 	tmsg = nlmsg_data(cb->nlh);
 
 	if (tmsg->flags & ~TUNNEL_MSG_VALID_USER_FLAGS) {
@@ -992,19 +997,18 @@
 	return err;
 }
 
-void vxlan_vnifilter_init(void)
+static const struct rtnl_msg_handler vxlan_vnifilter_rtnl_msg_handlers[] = {
+	{THIS_MODULE, PF_BRIDGE, RTM_GETTUNNEL, NULL, vxlan_vnifilter_dump, 0},
+	{THIS_MODULE, PF_BRIDGE, RTM_NEWTUNNEL, vxlan_vnifilter_process, NULL, 0},
+	{THIS_MODULE, PF_BRIDGE, RTM_DELTUNNEL, vxlan_vnifilter_process, NULL, 0},
+};
+
+int vxlan_vnifilter_init(void)
 {
-	rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_GETTUNNEL, NULL,
-			     vxlan_vnifilter_dump, 0);
-	rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_NEWTUNNEL,
-			     vxlan_vnifilter_process, NULL, 0);
-	rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_DELTUNNEL,
-			     vxlan_vnifilter_process, NULL, 0);
+	return rtnl_register_many(vxlan_vnifilter_rtnl_msg_handlers);
 }
 
 void vxlan_vnifilter_uninit(void)
 {
-	rtnl_unregister(PF_BRIDGE, RTM_GETTUNNEL);
-	rtnl_unregister(PF_BRIDGE, RTM_NEWTUNNEL);
-	rtnl_unregister(PF_BRIDGE, RTM_DELTUNNEL);
+	rtnl_unregister_many(vxlan_vnifilter_rtnl_msg_handlers);
 }
--- linux-qcom-6.8.0.orig/drivers/net/wireguard/allowedips.c
+++ linux-qcom-6.8.0/drivers/net/wireguard/allowedips.c
@@ -15,8 +15,8 @@
 	if (bits == 32) {
 		*(u32 *)dst = be32_to_cpu(*(const __be32 *)src);
 	} else if (bits == 128) {
-		((u64 *)dst)[0] = be64_to_cpu(((const __be64 *)src)[0]);
-		((u64 *)dst)[1] = be64_to_cpu(((const __be64 *)src)[1]);
+		((u64 *)dst)[0] = get_unaligned_be64(src);
+		((u64 *)dst)[1] = get_unaligned_be64(src + 8);
 	}
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/wireguard/netlink.c
+++ linux-qcom-6.8.0/drivers/net/wireguard/netlink.c
@@ -164,8 +164,8 @@
 	if (!allowedips_node)
 		goto no_allowedips;
 	if (!ctx->allowedips_seq)
-		ctx->allowedips_seq = peer->device->peer_allowedips.seq;
-	else if (ctx->allowedips_seq != peer->device->peer_allowedips.seq)
+		ctx->allowedips_seq = ctx->wg->peer_allowedips.seq;
+	else if (ctx->allowedips_seq != ctx->wg->peer_allowedips.seq)
 		goto no_allowedips;
 
 	allowedips_nest = nla_nest_start(skb, WGPEER_A_ALLOWEDIPS);
@@ -255,17 +255,17 @@
 	if (!peers_nest)
 		goto out;
 	ret = 0;
-	/* If the last cursor was removed via list_del_init in peer_remove, then
+	lockdep_assert_held(&wg->device_update_lock);
+	/* If the last cursor was removed in peer_remove or peer_remove_all, then
 	 * we just treat this the same as there being no more peers left. The
 	 * reason is that seq_nr should indicate to userspace that this isn't a
 	 * coherent dump anyway, so they'll try again.
 	 */
 	if (list_empty(&wg->peer_list) ||
-	    (ctx->next_peer && list_empty(&ctx->next_peer->peer_list))) {
+	    (ctx->next_peer && ctx->next_peer->is_dead)) {
 		nla_nest_cancel(skb, peers_nest);
 		goto out;
 	}
-	lockdep_assert_held(&wg->device_update_lock);
 	peer = list_prepare_entry(ctx->next_peer, &wg->peer_list, peer_list);
 	list_for_each_entry_continue(peer, &wg->peer_list, peer_list) {
 		if (get_peer(peer, skb, ctx)) {
--- linux-qcom-6.8.0.orig/drivers/net/wireguard/queueing.h
+++ linux-qcom-6.8.0/drivers/net/wireguard/queueing.h
@@ -124,10 +124,10 @@
  */
 static inline int wg_cpumask_next_online(int *last_cpu)
 {
-	int cpu = cpumask_next(*last_cpu, cpu_online_mask);
+	int cpu = cpumask_next(READ_ONCE(*last_cpu), cpu_online_mask);
 	if (cpu >= nr_cpu_ids)
 		cpu = cpumask_first(cpu_online_mask);
-	*last_cpu = cpu;
+	WRITE_ONCE(*last_cpu, cpu);
 	return cpu;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/wireguard/receive.c
+++ linux-qcom-6.8.0/drivers/net/wireguard/receive.c
@@ -251,7 +251,7 @@
 
 	if (unlikely(!READ_ONCE(keypair->receiving.is_valid) ||
 		  wg_birthdate_has_expired(keypair->receiving.birthdate, REJECT_AFTER_TIME) ||
-		  keypair->receiving_counter.counter >= REJECT_AFTER_MESSAGES)) {
+		  READ_ONCE(keypair->receiving_counter.counter) >= REJECT_AFTER_MESSAGES)) {
 		WRITE_ONCE(keypair->receiving.is_valid, false);
 		return false;
 	}
@@ -318,7 +318,7 @@
 		for (i = 1; i <= top; ++i)
 			counter->backtrack[(i + index_current) &
 				((COUNTER_BITS_TOTAL / BITS_PER_LONG) - 1)] = 0;
-		counter->counter = their_counter;
+		WRITE_ONCE(counter->counter, their_counter);
 	}
 
 	index &= (COUNTER_BITS_TOTAL / BITS_PER_LONG) - 1;
@@ -463,7 +463,7 @@
 			net_dbg_ratelimited("%s: Packet has invalid nonce %llu (max %llu)\n",
 					    peer->device->dev->name,
 					    PACKET_CB(skb)->nonce,
-					    keypair->receiving_counter.counter);
+					    READ_ONCE(keypair->receiving_counter.counter));
 			goto next;
 		}
 
--- linux-qcom-6.8.0.orig/drivers/net/wireguard/send.c
+++ linux-qcom-6.8.0/drivers/net/wireguard/send.c
@@ -222,7 +222,7 @@
 {
 	struct sk_buff *skb;
 
-	if (skb_queue_empty(&peer->staged_packet_queue)) {
+	if (skb_queue_empty_lockless(&peer->staged_packet_queue)) {
 		skb = alloc_skb(DATA_PACKET_HEAD_ROOM + MESSAGE_MINIMUM_LENGTH,
 				GFP_ATOMIC);
 		if (unlikely(!skb))
--- linux-qcom-6.8.0.orig/drivers/net/wireless/Kconfig
+++ linux-qcom-6.8.0/drivers/net/wireless/Kconfig
@@ -36,6 +36,7 @@
 source "drivers/net/wireless/ti/Kconfig"
 source "drivers/net/wireless/zydas/Kconfig"
 source "drivers/net/wireless/quantenna/Kconfig"
+source "drivers/net/wireless/bcmdhd/Kconfig"
 
 source "drivers/net/wireless/virtual/Kconfig"
 
--- linux-qcom-6.8.0.orig/drivers/net/wireless/Makefile
+++ linux-qcom-6.8.0/drivers/net/wireless/Makefile
@@ -21,5 +21,6 @@
 obj-$(CONFIG_WLAN_VENDOR_ST) += st/
 obj-$(CONFIG_WLAN_VENDOR_TI) += ti/
 obj-$(CONFIG_WLAN_VENDOR_ZYDAS) += zydas/
+obj-$(CONFIG_WLAN_VENDOR_BCMDHD) += bcmdhd/
 
 obj-$(CONFIG_WLAN) += virtual/
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ar5523/ar5523.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ar5523/ar5523.c
@@ -1590,6 +1590,20 @@
 	struct ar5523 *ar;
 	int error = -ENOMEM;
 
+	static const u8 bulk_ep_addr[] = {
+		AR5523_CMD_TX_PIPE | USB_DIR_OUT,
+		AR5523_DATA_TX_PIPE | USB_DIR_OUT,
+		AR5523_CMD_RX_PIPE | USB_DIR_IN,
+		AR5523_DATA_RX_PIPE | USB_DIR_IN,
+		0};
+
+	if (!usb_check_bulk_endpoints(intf, bulk_ep_addr)) {
+		dev_err(&dev->dev,
+			"Could not find all expected endpoints\n");
+		error = -ENODEV;
+		goto out;
+	}
+
 	/*
 	 * Load firmware if the device requires it.  This will return
 	 * -ENXIO on success and we'll get called back afer the usb
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath.h
@@ -171,8 +171,10 @@
 	unsigned int clockrate;
 
 	spinlock_t cc_lock;
-	struct ath_cycle_counters cc_ani;
-	struct ath_cycle_counters cc_survey;
+	struct_group(cc,
+		struct ath_cycle_counters cc_ani;
+		struct ath_cycle_counters cc_survey;
+	);
 
 	struct ath_regulatory regulatory;
 	struct ath_regulatory reg_world_copy;
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath10k/Kconfig
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath10k/Kconfig
@@ -45,6 +45,7 @@
 	depends on ATH10K
 	depends on ARCH_QCOM || COMPILE_TEST
 	depends on QCOM_SMEM
+	depends on QCOM_RPROC_COMMON || QCOM_RPROC_COMMON=n
 	select QCOM_SCM
 	select QCOM_QMI_HELPERS
 	help
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath10k/core.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath10k/core.c
@@ -720,6 +720,9 @@
 		.max_spatial_stream = 4,
 		.fw = {
 			.dir = WCN3990_HW_1_0_FW_DIR,
+			.board = WCN3990_HW_1_0_BOARD_DATA_FILE,
+			.board_size = WCN3990_BOARD_DATA_SZ,
+			.board_ext_size = WCN3990_BOARD_EXT_DATA_SZ,
 		},
 		.sw_decrypt_mcast_mgmt = true,
 		.rx_desc_ops = &wcn3990_rx_desc_ops,
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath10k/debugfs_sta.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath10k/debugfs_sta.c
@@ -439,7 +439,7 @@
 	}
 out:
 	mutex_unlock(&ar->conf_mutex);
-	return count;
+	return ret ?: count;
 }
 
 static const struct file_operations fops_peer_debug_trigger = {
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath10k/hw.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath10k/hw.h
@@ -133,6 +133,7 @@
 /* WCN3990 1.0 definitions */
 #define WCN3990_HW_1_0_DEV_VERSION	ATH10K_HW_WCN3990
 #define WCN3990_HW_1_0_FW_DIR		ATH10K_FW_DIR "/WCN3990/hw1.0"
+#define WCN3990_HW_1_0_BOARD_DATA_FILE "board.bin"
 
 #define ATH10K_FW_FILE_BASE		"firmware"
 #define ATH10K_FW_API_MAX		6
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath10k/mac.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath10k/mac.c
@@ -9120,7 +9120,7 @@
 	{6,  {2633, 2925}, {1215, 1350}, {585,  650} },
 	{7,  {2925, 3250}, {1350, 1500}, {650,  722} },
 	{8,  {3510, 3900}, {1620, 1800}, {780,  867} },
-	{9,  {3900, 4333}, {1800, 2000}, {780,  867} }
+	{9,  {3900, 4333}, {1800, 2000}, {865,  960} }
 };
 
 /*MCS parameters with Nss = 2 */
@@ -9135,7 +9135,7 @@
 	{6,  {5265, 5850}, {2430, 2700}, {1170, 1300} },
 	{7,  {5850, 6500}, {2700, 3000}, {1300, 1444} },
 	{8,  {7020, 7800}, {3240, 3600}, {1560, 1733} },
-	{9,  {7800, 8667}, {3600, 4000}, {1560, 1733} }
+	{9,  {7800, 8667}, {3600, 4000}, {1730, 1920} }
 };
 
 static void ath10k_mac_get_rate_flags_ht(struct ath10k *ar, u32 rate, u8 nss, u8 mcs,
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath10k/sdio.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath10k/sdio.c
@@ -3,7 +3,7 @@
  * Copyright (c) 2004-2011 Atheros Communications Inc.
  * Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc.
  * Copyright (c) 2016-2017 Erik Stromdahl <erik.stromdahl@gmail.com>
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -2648,9 +2648,9 @@
 
 	netif_napi_del(&ar->napi);
 
-	ath10k_core_destroy(ar);
-
 	destroy_workqueue(ar_sdio->workqueue);
+
+	ath10k_core_destroy(ar);
 }
 
 static const struct sdio_device_id ath10k_sdio_devices[] = {
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath10k/targaddrs.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath10k/targaddrs.h
@@ -491,4 +491,7 @@
 #define QCA4019_BOARD_DATA_SZ	  12064
 #define QCA4019_BOARD_EXT_DATA_SZ 0
 
+#define WCN3990_BOARD_DATA_SZ	  26328
+#define WCN3990_BOARD_EXT_DATA_SZ 0
+
 #endif /* __TARGADDRS_H__ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -851,6 +851,10 @@
 	}
 
 	ev = tb[WMI_TLV_TAG_STRUCT_MGMT_TX_COMPL_EVENT];
+	if (!ev) {
+		kfree(tb);
+		return -EPROTO;
+	}
 
 	arg->desc_id = ev->desc_id;
 	arg->status = ev->status;
@@ -3038,9 +3042,14 @@
 				       struct sk_buff *msdu)
 {
 	struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
+	struct ath10k_mgmt_tx_pkt_addr *pkt_addr;
 	struct ath10k_wmi *wmi = &ar->wmi;
 
-	idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id);
+	spin_lock_bh(&ar->data_lock);
+	pkt_addr = idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id);
+	spin_unlock_bh(&ar->data_lock);
+
+	kfree(pkt_addr);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath10k/wmi.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1763,12 +1763,32 @@
 
 int ath10k_wmi_wait_for_service_ready(struct ath10k *ar)
 {
-	unsigned long time_left;
+	unsigned long time_left, i;
 
 	time_left = wait_for_completion_timeout(&ar->wmi.service_ready,
 						WMI_SERVICE_READY_TIMEOUT_HZ);
-	if (!time_left)
-		return -ETIMEDOUT;
+	if (!time_left) {
+		/* Sometimes the PCI HIF doesn't receive interrupt
+		 * for the service ready message even if the buffer
+		 * was completed. PCIe sniffer shows that it's
+		 * because the corresponding CE ring doesn't fires
+		 * it. Workaround here by polling CE rings once.
+		 */
+		ath10k_warn(ar, "failed to receive service ready completion, polling..\n");
+
+		for (i = 0; i < CE_COUNT; i++)
+			ath10k_hif_send_complete_check(ar, i, 1);
+
+		time_left = wait_for_completion_timeout(&ar->wmi.service_ready,
+							WMI_SERVICE_READY_TIMEOUT_HZ);
+		if (!time_left) {
+			ath10k_warn(ar, "polling timed out\n");
+			return -ETIMEDOUT;
+		}
+
+		ath10k_warn(ar, "service ready completion received, continuing normally\n");
+	}
+
 	return 0;
 }
 
@@ -2421,6 +2441,7 @@
 	dma_unmap_single(ar->dev, pkt_addr->paddr,
 			 msdu->len, DMA_TO_DEVICE);
 	info = IEEE80211_SKB_CB(msdu);
+	kfree(pkt_addr);
 
 	if (param->status) {
 		info->flags &= ~IEEE80211_TX_STAT_ACK;
@@ -9540,6 +9561,7 @@
 	dma_unmap_single(ar->dev, pkt_addr->paddr,
 			 msdu->len, DMA_TO_DEVICE);
 	ieee80211_free_txskb(ar->hw, msdu);
+	kfree(pkt_addr);
 
 	return 0;
 }
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/Kconfig
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/Kconfig
@@ -57,3 +57,14 @@
 	  Enable ath11k spectral scan support
 
 	  Say Y to enable access to the FFT/spectral data via debugfs.
+
+config ATH11K_COREDUMP
+	bool "ath11k coredump"
+	depends on ATH11K
+	select WANT_DEV_COREDUMP
+	help
+	  Enable ath11k coredump collection
+
+	  If unsure, say Y to make it easier to debug problems. But if
+	  dump collection not required choose N.
+
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/Makefile
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/Makefile
@@ -26,6 +26,7 @@
 ath11k-$(CONFIG_THERMAL) += thermal.o
 ath11k-$(CONFIG_ATH11K_SPECTRAL) += spectral.o
 ath11k-$(CONFIG_PM) += wow.o
+ath11k-$(CONFIG_ATH11K_COREDUMP) += coredump.o
 
 obj-$(CONFIG_ATH11K_AHB) += ath11k_ahb.o
 ath11k_ahb-y += ahb.o
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/ce.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/ce.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "dp_rx.h"
@@ -387,18 +387,26 @@
 
 	ath11k_hal_srng_access_begin(ab, srng);
 
-	desc = ath11k_hal_srng_dst_get_next_entry(ab, srng);
+	desc = ath11k_hal_srng_dst_peek(ab, srng);
 	if (!desc) {
 		ret = -EIO;
 		goto err;
 	}
 
 	*nbytes = ath11k_hal_ce_dst_status_get_length(desc);
-	if (*nbytes == 0) {
+	if (unlikely(*nbytes == 0)) {
+		/* A relatively unusual race condition occurs between host
+		 * software and hardware, where the host sees the updated
+		 * destination ring head pointer before the hardware updates
+		 * the corresponding descriptor. Temporarily skip processing
+		 * the current descriptor and handle it again next time.
+		 */
 		ret = -EIO;
 		goto err;
 	}
 
+	ath11k_hal_srng_dst_next(ab, srng);
+
 	*skb = pipe->dest_ring->skb[sw_index];
 	pipe->dest_ring->skb[sw_index] = NULL;
 
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/ce.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/ce.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef ATH11K_CE_H
@@ -146,7 +146,7 @@
 	/* Host address space */
 	void *base_addr_owner_space_unaligned;
 	/* CE address space */
-	u32 base_addr_ce_space_unaligned;
+	dma_addr_t base_addr_ce_space_unaligned;
 
 	/* Actual start of descriptors.
 	 * Aligned to descriptor-size boundary.
@@ -156,7 +156,7 @@
 	void *base_addr_owner_space;
 
 	/* CE address space */
-	u32 base_addr_ce_space;
+	dma_addr_t base_addr_ce_space;
 
 	/* HAL ring id */
 	u32 hal_ring_id;
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/core.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/core.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/module.h>
@@ -62,7 +62,7 @@
 		.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
 		.single_pdev_only = false,
 		.rxdma1_enable = true,
-		.num_rxmda_per_pdev = 1,
+		.num_rxdma_per_pdev = 1,
 		.rx_mac_buf_ring = false,
 		.vdev_start_delay = false,
 		.htt_peer_map_v2 = true,
@@ -122,6 +122,8 @@
 		.tcl_ring_retry = true,
 		.tx_ring_size = DP_TCL_DATA_RING_SIZE,
 		.smp2p_wow_exit = false,
+		.support_dual_stations = false,
+		.pdev_suspend = false,
 	},
 	{
 		.hw_rev = ATH11K_HW_IPQ6018_HW10,
@@ -147,7 +149,7 @@
 		.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
 		.single_pdev_only = false,
 		.rxdma1_enable = true,
-		.num_rxmda_per_pdev = 1,
+		.num_rxdma_per_pdev = 1,
 		.rx_mac_buf_ring = false,
 		.vdev_start_delay = false,
 		.htt_peer_map_v2 = true,
@@ -205,6 +207,8 @@
 		.tx_ring_size = DP_TCL_DATA_RING_SIZE,
 		.smp2p_wow_exit = false,
 		.support_fw_mac_sequence = false,
+		.support_dual_stations = false,
+		.pdev_suspend = false,
 	},
 	{
 		.name = "qca6390 hw2.0",
@@ -230,7 +234,7 @@
 		.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
 		.single_pdev_only = true,
 		.rxdma1_enable = false,
-		.num_rxmda_per_pdev = 2,
+		.num_rxdma_per_pdev = 2,
 		.rx_mac_buf_ring = true,
 		.vdev_start_delay = true,
 		.htt_peer_map_v2 = false,
@@ -255,7 +259,7 @@
 		.coldboot_cal_ftm = false,
 		.cbcal_restart_fw = false,
 		.fw_mem_mode = 0,
-		.num_vdevs = 16 + 1,
+		.num_vdevs = 2 + 1,
 		.num_peers = 512,
 		.supports_suspend = true,
 		.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
@@ -290,6 +294,8 @@
 		.tx_ring_size = DP_TCL_DATA_RING_SIZE,
 		.smp2p_wow_exit = false,
 		.support_fw_mac_sequence = true,
+		.support_dual_stations = true,
+		.pdev_suspend = false,
 	},
 	{
 		.name = "qcn9074 hw1.0",
@@ -314,7 +320,7 @@
 		.svc_to_ce_map_len = 18,
 		.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
 		.rxdma1_enable = true,
-		.num_rxmda_per_pdev = 1,
+		.num_rxdma_per_pdev = 1,
 		.rx_mac_buf_ring = false,
 		.vdev_start_delay = false,
 		.htt_peer_map_v2 = true,
@@ -372,6 +378,8 @@
 		.tx_ring_size = DP_TCL_DATA_RING_SIZE,
 		.smp2p_wow_exit = false,
 		.support_fw_mac_sequence = false,
+		.support_dual_stations = false,
+		.pdev_suspend = false,
 	},
 	{
 		.name = "wcn6855 hw2.0",
@@ -397,7 +405,7 @@
 		.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
 		.single_pdev_only = true,
 		.rxdma1_enable = false,
-		.num_rxmda_per_pdev = 2,
+		.num_rxdma_per_pdev = 2,
 		.rx_mac_buf_ring = true,
 		.vdev_start_delay = true,
 		.htt_peer_map_v2 = false,
@@ -422,7 +430,7 @@
 		.coldboot_cal_ftm = false,
 		.cbcal_restart_fw = false,
 		.fw_mem_mode = 0,
-		.num_vdevs = 16 + 1,
+		.num_vdevs = 2 + 1,
 		.num_peers = 512,
 		.supports_suspend = true,
 		.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
@@ -457,6 +465,8 @@
 		.tx_ring_size = DP_TCL_DATA_RING_SIZE,
 		.smp2p_wow_exit = false,
 		.support_fw_mac_sequence = true,
+		.support_dual_stations = true,
+		.pdev_suspend = false,
 	},
 	{
 		.name = "wcn6855 hw2.1",
@@ -481,7 +491,7 @@
 		.svc_to_ce_map_len = 14,
 		.single_pdev_only = true,
 		.rxdma1_enable = false,
-		.num_rxmda_per_pdev = 2,
+		.num_rxdma_per_pdev = 2,
 		.rx_mac_buf_ring = true,
 		.vdev_start_delay = true,
 		.htt_peer_map_v2 = false,
@@ -505,7 +515,7 @@
 		.coldboot_cal_ftm = false,
 		.cbcal_restart_fw = false,
 		.fw_mem_mode = 0,
-		.num_vdevs = 16 + 1,
+		.num_vdevs = 2 + 1,
 		.num_peers = 512,
 		.supports_suspend = true,
 		.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
@@ -540,6 +550,8 @@
 		.tx_ring_size = DP_TCL_DATA_RING_SIZE,
 		.smp2p_wow_exit = false,
 		.support_fw_mac_sequence = true,
+		.support_dual_stations = true,
+		.pdev_suspend = false,
 	},
 	{
 		.name = "wcn6750 hw1.0",
@@ -565,7 +577,7 @@
 		.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
 		.single_pdev_only = true,
 		.rxdma1_enable = false,
-		.num_rxmda_per_pdev = 1,
+		.num_rxdma_per_pdev = 1,
 		.rx_mac_buf_ring = true,
 		.vdev_start_delay = true,
 		.htt_peer_map_v2 = false,
@@ -589,7 +601,7 @@
 		.coldboot_cal_ftm = true,
 		.cbcal_restart_fw = false,
 		.fw_mem_mode = 0,
-		.num_vdevs = 16 + 1,
+		.num_vdevs = 3,
 		.num_peers = 512,
 		.supports_suspend = false,
 		.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
@@ -601,7 +613,7 @@
 		.supports_dynamic_smps_6ghz = false,
 		.alloc_cacheable_memory = false,
 		.supports_rssi_stats = true,
-		.fw_wmi_diag_event = false,
+		.fw_wmi_diag_event = true,
 		.current_cc_support = true,
 		.dbr_debug_support = false,
 		.global_reset = false,
@@ -621,6 +633,8 @@
 		.tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750,
 		.smp2p_wow_exit = true,
 		.support_fw_mac_sequence = true,
+		.support_dual_stations = false,
+		.pdev_suspend = true,
 	},
 	{
 		.hw_rev = ATH11K_HW_IPQ5018_HW10,
@@ -657,7 +671,7 @@
 		.ce_ie_addr = &ath11k_ce_ie_addr_ipq5018,
 		.ce_remap = &ath11k_ce_remap_ipq5018,
 		.rxdma1_enable = true,
-		.num_rxmda_per_pdev = RXDMA_PER_PDEV_5018,
+		.num_rxdma_per_pdev = RXDMA_PER_PDEV_5018,
 		.rx_mac_buf_ring = false,
 		.vdev_start_delay = false,
 		.htt_peer_map_v2 = true,
@@ -702,6 +716,183 @@
 		.tx_ring_size = DP_TCL_DATA_RING_SIZE,
 		.smp2p_wow_exit = false,
 		.support_fw_mac_sequence = false,
+		.support_dual_stations = false,
+		.pdev_suspend = false,
+	},
+	{
+		.name = "qca2066 hw2.1",
+		.hw_rev = ATH11K_HW_QCA2066_HW21,
+		.fw = {
+			.dir = "QCA2066/hw2.1",
+			.board_size = 256 * 1024,
+			.cal_offset = 128 * 1024,
+		},
+		.max_radios = 3,
+		.bdf_addr = 0x4B0C0000,
+		.hw_ops = &wcn6855_ops,
+		.ring_mask = &ath11k_hw_ring_mask_qca6390,
+		.internal_sleep_clock = true,
+		.regs = &wcn6855_regs,
+		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
+		.host_ce_config = ath11k_host_ce_config_qca6390,
+		.ce_count = 9,
+		.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
+		.target_ce_count = 9,
+		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
+		.svc_to_ce_map_len = 14,
+		.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
+		.single_pdev_only = true,
+		.rxdma1_enable = false,
+		.num_rxdma_per_pdev = 2,
+		.rx_mac_buf_ring = true,
+		.vdev_start_delay = true,
+		.htt_peer_map_v2 = false,
+
+		.spectral = {
+			.fft_sz = 0,
+			.fft_pad_sz = 0,
+			.summary_pad_sz = 0,
+			.fft_hdr_len = 0,
+			.max_fft_bins = 0,
+			.fragment_160mhz = false,
+		},
+
+		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
+					BIT(NL80211_IFTYPE_AP),
+		.supports_monitor = false,
+		.full_monitor_mode = false,
+		.supports_shadow_regs = true,
+		.idle_ps = true,
+		.supports_sta_ps = true,
+		.coldboot_cal_mm = false,
+		.coldboot_cal_ftm = false,
+		.cbcal_restart_fw = false,
+		.fw_mem_mode = 0,
+		.num_vdevs = 2 + 1,
+		.num_peers = 512,
+		.supports_suspend = true,
+		.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
+		.supports_regdb = true,
+		.fix_l1ss = false,
+		.credit_flow = true,
+		.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
+		.hal_params = &ath11k_hw_hal_params_qca6390,
+		.supports_dynamic_smps_6ghz = false,
+		.alloc_cacheable_memory = false,
+		.supports_rssi_stats = true,
+		.fw_wmi_diag_event = true,
+		.current_cc_support = true,
+		.dbr_debug_support = false,
+		.global_reset = true,
+		.bios_sar_capa = &ath11k_hw_sar_capa_wcn6855,
+		.m3_fw_support = true,
+		.fixed_bdf_addr = false,
+		.fixed_mem_region = false,
+		.static_window_map = false,
+		.hybrid_bus_type = false,
+		.fixed_fw_mem = false,
+		.support_off_channel_tx = true,
+		.supports_multi_bssid = true,
+
+		.sram_dump = {
+			.start = 0x01400000,
+			.end = 0x0177ffff,
+		},
+
+		.tcl_ring_retry = true,
+		.tx_ring_size = DP_TCL_DATA_RING_SIZE,
+		.smp2p_wow_exit = false,
+		.support_fw_mac_sequence = true,
+		.support_dual_stations = true,
+		.pdev_suspend = false,
+	},
+	{
+		.name = "qca6698aq hw2.1",
+		.hw_rev = ATH11K_HW_QCA6698AQ_HW21,
+		.fw = {
+			.dir = "QCA6698AQ/hw2.1",
+			.board_size = 256 * 1024,
+			.cal_offset = 128 * 1024,
+		},
+		.max_radios = 3,
+		.bdf_addr = 0x4B0C0000,
+		.hw_ops = &wcn6855_ops,
+		.ring_mask = &ath11k_hw_ring_mask_qca6390,
+		.internal_sleep_clock = true,
+		.regs = &wcn6855_regs,
+		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
+		.host_ce_config = ath11k_host_ce_config_qca6390,
+		.ce_count = 9,
+		.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
+		.target_ce_count = 9,
+		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
+		.svc_to_ce_map_len = 14,
+		.single_pdev_only = true,
+		.rxdma1_enable = false,
+		.num_rxdma_per_pdev = 2,
+		.rx_mac_buf_ring = true,
+		.vdev_start_delay = true,
+		.htt_peer_map_v2 = false,
+
+		.spectral = {
+			.fft_sz = 0,
+			.fft_pad_sz = 0,
+			.summary_pad_sz = 0,
+			.fft_hdr_len = 0,
+			.max_fft_bins = 0,
+			.fragment_160mhz = false,
+		},
+
+		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
+					BIT(NL80211_IFTYPE_AP) |
+					BIT(NL80211_IFTYPE_P2P_DEVICE) |
+					BIT(NL80211_IFTYPE_P2P_CLIENT) |
+					BIT(NL80211_IFTYPE_P2P_GO),
+		.supports_monitor = false,
+		.supports_shadow_regs = true,
+		.idle_ps = true,
+		.supports_sta_ps = true,
+		.coldboot_cal_mm = false,
+		.coldboot_cal_ftm = false,
+		.cbcal_restart_fw = false,
+		.fw_mem_mode = 0,
+		.num_vdevs = 2 + 1,
+		.num_peers = 512,
+		.supports_suspend = true,
+		.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
+		.supports_regdb = true,
+		.fix_l1ss = false,
+		.credit_flow = true,
+		.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
+		.hal_params = &ath11k_hw_hal_params_qca6390,
+		.supports_dynamic_smps_6ghz = false,
+		.alloc_cacheable_memory = false,
+		.supports_rssi_stats = true,
+		.fw_wmi_diag_event = true,
+		.current_cc_support = true,
+		.dbr_debug_support = false,
+		.global_reset = true,
+		.bios_sar_capa = &ath11k_hw_sar_capa_wcn6855,
+		.m3_fw_support = true,
+		.fixed_bdf_addr = false,
+		.fixed_mem_region = false,
+		.static_window_map = false,
+		.hybrid_bus_type = false,
+		.fixed_fw_mem = false,
+		.support_off_channel_tx = true,
+		.supports_multi_bssid = true,
+
+		.sram_dump = {
+			.start = 0x01400000,
+			.end = 0x0177ffff,
+		},
+
+		.tcl_ring_retry = true,
+		.tx_ring_size = DP_TCL_DATA_RING_SIZE,
+		.smp2p_wow_exit = false,
+		.support_fw_mac_sequence = true,
+		.support_dual_stations = true,
+		.pdev_suspend = false,
 	},
 };
 
@@ -1563,11 +1754,47 @@
 	return ret;
 }
 
+static void ath11k_core_pdev_suspend_target(struct ath11k_base *ab)
+{
+	struct ath11k *ar;
+	struct ath11k_pdev *pdev;
+	unsigned long time_left;
+	int ret;
+	int i;
+
+	if (!ab->hw_params.pdev_suspend)
+		return;
+
+	for (i = 0; i < ab->num_radios; i++) {
+		pdev = &ab->pdevs[i];
+		ar = pdev->ar;
+
+		reinit_completion(&ab->htc_suspend);
+
+		ret = ath11k_wmi_pdev_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR,
+					      pdev->pdev_id);
+		if (ret) {
+			ath11k_warn(ab, "could not suspend target :%d\n", ret);
+			/* pointless to try other pdevs */
+			return;
+		}
+
+		time_left = wait_for_completion_timeout(&ab->htc_suspend, 3 * HZ);
+
+		if (!time_left) {
+			ath11k_warn(ab, "suspend timed out - target pause event never came\n");
+			/* pointless to try other pdevs */
+			return;
+		}
+	}
+}
+
 static void ath11k_core_pdev_destroy(struct ath11k_base *ab)
 {
 	ath11k_spectral_deinit(ab);
 	ath11k_thermal_unregister(ab);
 	ath11k_mac_unregister(ab);
+	ath11k_core_pdev_suspend_target(ab);
 	ath11k_hif_irq_disable(ab);
 	ath11k_dp_pdev_free(ab);
 	ath11k_debugfs_pdev_destroy(ab);
@@ -1655,7 +1882,7 @@
 	}
 
 	/* put hardware to DBS mode */
-	if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxmda_per_pdev > 1) {
+	if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxdma_per_pdev > 1) {
 		ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS);
 		if (ret) {
 			ath11k_err(ab, "failed to send dbs mode: %d\n", ret);
@@ -1810,6 +2037,7 @@
 void ath11k_core_halt(struct ath11k *ar)
 {
 	struct ath11k_base *ab = ar->ab;
+	struct list_head *pos, *n;
 
 	lockdep_assert_held(&ar->conf_mutex);
 
@@ -1824,7 +2052,12 @@
 
 	rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
 	synchronize_rcu();
-	INIT_LIST_HEAD(&ar->arvifs);
+
+	spin_lock_bh(&ar->data_lock);
+	list_for_each_safe(pos, n, &ar->arvifs)
+		list_del_init(pos);
+	spin_unlock_bh(&ar->data_lock);
+
 	idr_init(&ar->txmgmt_idr);
 }
 
@@ -1833,23 +2066,20 @@
 	struct ath11k_base *ab = container_of(work, struct ath11k_base, update_11d_work);
 	struct ath11k *ar;
 	struct ath11k_pdev *pdev;
-	struct wmi_set_current_country_params set_current_param = {};
 	int ret, i;
 
-	spin_lock_bh(&ab->base_lock);
-	memcpy(&set_current_param.alpha2, &ab->new_alpha2, 2);
-	spin_unlock_bh(&ab->base_lock);
-
-	ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c\n",
-		   set_current_param.alpha2[0],
-		   set_current_param.alpha2[1]);
-
 	for (i = 0; i < ab->num_radios; i++) {
 		pdev = &ab->pdevs[i];
 		ar = pdev->ar;
 
-		memcpy(&ar->alpha2, &set_current_param.alpha2, 2);
-		ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
+		spin_lock_bh(&ab->base_lock);
+		memcpy(&ar->alpha2, &ab->new_alpha2, 2);
+		spin_unlock_bh(&ab->base_lock);
+
+		ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c for pdev %d\n",
+			   ar->alpha2[0], ar->alpha2[1], i);
+
+		ret = ath11k_reg_set_cc(ar);
 		if (ret)
 			ath11k_warn(ar->ab,
 				    "pdev id %d failed set current country code: %d\n",
@@ -2023,6 +2253,7 @@
 	reinit_completion(&ab->recovery_start);
 	atomic_set(&ab->recovery_start_count, 0);
 
+	ath11k_coredump_collect(ab);
 	ath11k_core_pre_reconfigure_recovery(ab);
 
 	reinit_completion(&ab->reconfigure_complete);
@@ -2156,6 +2387,7 @@
 	INIT_WORK(&ab->restart_work, ath11k_core_restart);
 	INIT_WORK(&ab->update_11d_work, ath11k_update_11d);
 	INIT_WORK(&ab->reset_work, ath11k_core_reset);
+	INIT_WORK(&ab->dump_work, ath11k_coredump_upload);
 	timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
 	init_completion(&ab->htc_suspend);
 	init_completion(&ab->wow.wakeup_completed);
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/core.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/core.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef ATH11K_CORE_H
@@ -32,6 +32,7 @@
 #include "spectral.h"
 #include "wow.h"
 #include "fw.h"
+#include "coredump.h"
 
 #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
 
@@ -147,6 +148,8 @@
 	ATH11K_HW_WCN6855_HW21,
 	ATH11K_HW_WCN6750_HW10,
 	ATH11K_HW_IPQ5018_HW10,
+	ATH11K_HW_QCA2066_HW21,
+	ATH11K_HW_QCA6698AQ_HW21,
 };
 
 enum ath11k_firmware_mode {
@@ -331,6 +334,7 @@
 
 	u16 tx_seq_no;
 	struct wmi_wmm_params_all_arg wmm_params;
+	struct wmi_wmm_params_all_arg muedca_params;
 	struct list_head list;
 	union {
 		struct {
@@ -358,6 +362,7 @@
 	u8 bssid[ETH_ALEN];
 	struct cfg80211_bitrate_mask bitrate_mask;
 	struct delayed_work connection_loss_work;
+	struct work_struct bcn_tx_work;
 	int num_legacy_stations;
 	int rtscts_prot_mode;
 	int txpower;
@@ -851,6 +856,10 @@
 	/* HW channel counters frequency value in hertz common to all MACs */
 	u32 cc_freq_hz;
 
+	struct ath11k_dump_file_data *dump_data;
+	size_t ath11k_coredump_len;
+	struct work_struct dump_work;
+
 	struct ath11k_htc htc;
 
 	struct ath11k_dp dp;
@@ -918,6 +927,7 @@
 	 * This may or may not be used during the runtime
 	 */
 	struct ieee80211_regdomain *new_regd[MAX_RADIOS];
+	struct cur_regulatory_info *reg_info_store;
 
 	/* Current DFS Regulatory */
 	enum ath11k_dfs_region dfs_region;
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/coredump.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/coredump.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: BSD-3-Clause-Clear
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#include <linux/devcoredump.h>
+#include "hif.h"
+#include "coredump.h"
+#include "debug.h"
+
+enum
+ath11k_fw_crash_dump_type ath11k_coredump_get_dump_type(int type)
+{
+	enum ath11k_fw_crash_dump_type dump_type;
+
+	switch (type) {
+	case HOST_DDR_REGION_TYPE:
+		dump_type = FW_CRASH_DUMP_REMOTE_MEM_DATA;
+		break;
+	case M3_DUMP_REGION_TYPE:
+		dump_type = FW_CRASH_DUMP_M3_DUMP;
+		break;
+	case PAGEABLE_MEM_REGION_TYPE:
+		dump_type = FW_CRASH_DUMP_PAGEABLE_DATA;
+		break;
+	case BDF_MEM_REGION_TYPE:
+	case CALDB_MEM_REGION_TYPE:
+		dump_type = FW_CRASH_DUMP_NONE;
+		break;
+	default:
+		dump_type = FW_CRASH_DUMP_TYPE_MAX;
+		break;
+	}
+
+	return dump_type;
+}
+EXPORT_SYMBOL_GPL(ath11k_coredump_get_dump_type);
+
+void ath11k_coredump_upload(struct work_struct *work)
+{
+	struct ath11k_base *ab = container_of(work, struct ath11k_base, dump_work);
+
+	ath11k_info(ab, "Uploading coredump\n");
+	/* dev_coredumpv() takes ownership of the buffer */
+	dev_coredumpv(ab->dev, ab->dump_data, ab->ath11k_coredump_len, GFP_KERNEL);
+	ab->dump_data = NULL;
+}
+
+void ath11k_coredump_collect(struct ath11k_base *ab)
+{
+	ath11k_hif_coredump_download(ab);
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/coredump.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/coredump.h
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+#ifndef _ATH11K_COREDUMP_H_
+#define _ATH11K_COREDUMP_H_
+
+#define ATH11K_FW_CRASH_DUMP_V2      2
+
+enum ath11k_fw_crash_dump_type {
+	FW_CRASH_DUMP_PAGING_DATA,
+	FW_CRASH_DUMP_RDDM_DATA,
+	FW_CRASH_DUMP_REMOTE_MEM_DATA,
+	FW_CRASH_DUMP_PAGEABLE_DATA,
+	FW_CRASH_DUMP_M3_DUMP,
+	FW_CRASH_DUMP_NONE,
+
+	/* keep last */
+	FW_CRASH_DUMP_TYPE_MAX,
+};
+
+#define COREDUMP_TLV_HDR_SIZE 8
+
+struct ath11k_tlv_dump_data {
+	/* see ath11k_fw_crash_dump_type above */
+	__le32 type;
+
+	/* in bytes */
+	__le32 tlv_len;
+
+	/* pad to 32-bit boundaries as needed */
+	u8 tlv_data[];
+} __packed;
+
+struct ath11k_dump_file_data {
+	/* "ATH11K-FW-DUMP" */
+	char df_magic[16];
+	/* total dump len in bytes */
+	__le32 len;
+	/* file dump version */
+	__le32 version;
+	/* pci device id */
+	__le32 chip_id;
+	/* qrtr instance id */
+	__le32 qrtr_id;
+	/* pci domain id */
+	__le32 bus_id;
+	guid_t guid;
+	/* time-of-day stamp */
+	__le64 tv_sec;
+	/* time-of-day stamp, nano-seconds */
+	__le64 tv_nsec;
+	/* room for growth w/out changing binary format */
+	u8 unused[128];
+	u8 data[];
+} __packed;
+
+#ifdef CONFIG_ATH11K_COREDUMP
+enum ath11k_fw_crash_dump_type ath11k_coredump_get_dump_type(int type);
+void ath11k_coredump_upload(struct work_struct *work);
+void ath11k_coredump_collect(struct ath11k_base *ab);
+#else
+static inline enum
+ath11k_fw_crash_dump_type ath11k_coredump_get_dump_type(int type)
+{
+	return FW_CRASH_DUMP_TYPE_MAX;
+}
+
+static inline void ath11k_coredump_upload(struct work_struct *work)
+{
+}
+
+static inline void ath11k_coredump_collect(struct ath11k_base *ab)
+{
+}
+#endif
+
+#endif
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/debugfs.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/debugfs.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/vmalloc.h>
@@ -668,7 +668,7 @@
 
 	ar->debug.rx_filter = tlv_filter.rx_filter;
 
-	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+	for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
 		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
 						       HAL_RXDMA_MONITOR_STATUS,
@@ -980,7 +980,7 @@
 	debugfs_create_file("simulate_fw_crash", 0600, ab->debugfs_soc, ab,
 			    &fops_simulate_fw_crash);
 
-	debugfs_create_file("soc_dp_stats", 0600, ab->debugfs_soc, ab,
+	debugfs_create_file("soc_dp_stats", 0400, ab->debugfs_soc, ab,
 			    &fops_soc_dp_stats);
 
 	if (ab->hw_params.sram_dump.start != 0)
@@ -1112,7 +1112,7 @@
 	}
 
 	/* Clear rx filter set for monitor mode and rx status */
-	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+	for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
 		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id, ar->dp.mac_id,
 						       HAL_RXDMA_MONITOR_STATUS,
@@ -1171,7 +1171,7 @@
 					       HTT_RX_FP_DATA_FILTER_FLASG3;
 	}
 
-	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+	for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
 		ret = ath11k_dp_tx_htt_rx_filter_setup(ab, ring_id,
 						       ar->dp.mac_id + i,
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/dp.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/dp.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <crypto/hash.h>
@@ -816,8 +816,8 @@
 
 	if (ab->hw_params.ring_mask->rx_mon_status[grp_id]) {
 		for (i = 0; i < ab->num_radios; i++) {
-			for (j = 0; j < ab->hw_params.num_rxmda_per_pdev; j++) {
-				int id = i * ab->hw_params.num_rxmda_per_pdev + j;
+			for (j = 0; j < ab->hw_params.num_rxdma_per_pdev; j++) {
+				int id = i * ab->hw_params.num_rxdma_per_pdev + j;
 
 				if (ab->hw_params.ring_mask->rx_mon_status[grp_id] &
 					BIT(id)) {
@@ -839,8 +839,8 @@
 		ath11k_dp_process_reo_status(ab);
 
 	for (i = 0; i < ab->num_radios; i++) {
-		for (j = 0; j < ab->hw_params.num_rxmda_per_pdev; j++) {
-			int id = i * ab->hw_params.num_rxmda_per_pdev + j;
+		for (j = 0; j < ab->hw_params.num_rxdma_per_pdev; j++) {
+			int id = i * ab->hw_params.num_rxdma_per_pdev + j;
 
 			if (ab->hw_params.ring_mask->rxdma2host[grp_id] & BIT(id)) {
 				work_done = ath11k_dp_process_rxdma_err(ab, id, budget);
@@ -899,7 +899,7 @@
 		spin_lock_init(&dp->rx_refill_buf_ring.idr_lock);
 		atomic_set(&dp->num_tx_pending, 0);
 		init_waitqueue_head(&dp->tx_empty_waitq);
-		for (j = 0; j < ab->hw_params.num_rxmda_per_pdev; j++) {
+		for (j = 0; j < ab->hw_params.num_rxdma_per_pdev; j++) {
 			idr_init(&dp->rx_mon_status_refill_ring[j].bufs_idr);
 			spin_lock_init(&dp->rx_mon_status_refill_ring[j].idr_lock);
 		}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/ieee80211.h>
@@ -311,7 +311,7 @@
 	struct ath11k_base *ab = from_timer(ab, t, mon_reap_timer);
 	int i;
 
-	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++)
+	for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++)
 		ath11k_dp_rx_process_mon_rings(ab, i, NULL, DP_MON_SERVICE_BUDGET);
 
 	mod_timer(&ab->mon_reap_timer, jiffies +
@@ -324,7 +324,7 @@
 	unsigned long timeout = jiffies + msecs_to_jiffies(DP_MON_PURGE_TIMEOUT_MS);
 
 	do {
-		for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++)
+		for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++)
 			reaped += ath11k_dp_rx_process_mon_rings(ab, i,
 								 NULL,
 								 DP_MON_SERVICE_BUDGET);
@@ -468,7 +468,7 @@
 	rx_ring = &dp->rxdma_mon_buf_ring;
 	ath11k_dp_rxdma_buf_ring_free(ar, rx_ring);
 
-	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+	for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 		rx_ring = &dp->rx_mon_status_refill_ring[i];
 		ath11k_dp_rxdma_buf_ring_free(ar, rx_ring);
 	}
@@ -506,7 +506,7 @@
 		ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_MONITOR_BUF);
 	}
 
-	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+	for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 		rx_ring = &dp->rx_mon_status_refill_ring[i];
 		ath11k_dp_rxdma_ring_buf_setup(ar, rx_ring, HAL_RXDMA_MONITOR_STATUS);
 	}
@@ -522,7 +522,7 @@
 
 	ath11k_dp_srng_cleanup(ab, &dp->rx_refill_buf_ring.refill_buf_ring);
 
-	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+	for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 		if (ab->hw_params.rx_mac_buf_ring)
 			ath11k_dp_srng_cleanup(ab, &dp->rx_mac_buf_ring[i]);
 
@@ -585,7 +585,7 @@
 	}
 
 	if (ar->ab->hw_params.rx_mac_buf_ring) {
-		for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+		for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 			ret = ath11k_dp_srng_setup(ar->ab,
 						   &dp->rx_mac_buf_ring[i],
 						   HAL_RXDMA_BUF, 1,
@@ -598,7 +598,7 @@
 		}
 	}
 
-	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+	for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 		ret = ath11k_dp_srng_setup(ar->ab, &dp->rxdma_err_dst_ring[i],
 					   HAL_RXDMA_DST, 0, dp->mac_id + i,
 					   DP_RXDMA_ERR_DST_RING_SIZE);
@@ -608,7 +608,7 @@
 		}
 	}
 
-	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+	for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 		srng = &dp->rx_mon_status_refill_ring[i].refill_buf_ring;
 		ret = ath11k_dp_srng_setup(ar->ab,
 					   srng,
@@ -1877,8 +1877,7 @@
 			  CHECKSUM_NONE : CHECKSUM_UNNECESSARY;
 }
 
-static int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar,
-				       enum hal_encrypt_type enctype)
+int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, enum hal_encrypt_type enctype)
 {
 	switch (enctype) {
 	case HAL_ENCRYPT_TYPE_OPEN:
@@ -2698,7 +2697,7 @@
 		if (unlikely(push_reason !=
 			     HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION)) {
 			dev_kfree_skb_any(msdu);
-			ab->soc_stats.hal_reo_error[dp->reo_dst_ring[ring_id].ring_id]++;
+			ab->soc_stats.hal_reo_error[ring_id]++;
 			continue;
 		}
 
@@ -3809,6 +3808,7 @@
 		ath11k_hal_rx_msdu_link_info_get(link_desc_va, &num_msdus, msdu_cookies,
 						 &rbm);
 		if (rbm != HAL_RX_BUF_RBM_WBM_IDLE_DESC_LIST &&
+		    rbm != HAL_RX_BUF_RBM_SW1_BM &&
 		    rbm != HAL_RX_BUF_RBM_SW3_BM) {
 			ab->soc_stats.invalid_rbm++;
 			ath11k_warn(ab, "invalid return buffer manager %d\n", rbm);
@@ -4391,7 +4391,7 @@
 	}
 
 	if (ab->hw_params.rx_mac_buf_ring) {
-		for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+		for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 			ring_id = dp->rx_mac_buf_ring[i].ring_id;
 			ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id,
 							  mac_id + i, HAL_RXDMA_BUF);
@@ -4403,7 +4403,7 @@
 		}
 	}
 
-	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+	for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 		ring_id = dp->rxdma_err_dst_ring[i].ring_id;
 		ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id,
 						  mac_id + i, HAL_RXDMA_DST);
@@ -4443,7 +4443,7 @@
 	}
 
 config_refill_ring:
-	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+	for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 		ring_id = dp->rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
 		ret = ath11k_dp_tx_htt_srng_setup(ab, ring_id, mac_id + i,
 						  HAL_RXDMA_MONITOR_STATUS);
@@ -5228,8 +5228,11 @@
 		    hal_status == HAL_TLV_STATUS_PPDU_DONE) {
 			rx_mon_stats->status_ppdu_done++;
 			pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE;
-			ath11k_dp_rx_mon_dest_process(ar, mac_id, budget, napi);
-			pmon->mon_ppdu_status = DP_PPDU_STATUS_START;
+			if (!ab->hw_params.full_monitor_mode) {
+				ath11k_dp_rx_mon_dest_process(ar, mac_id,
+							      budget, napi);
+				pmon->mon_ppdu_status = DP_PPDU_STATUS_START;
+			}
 		}
 
 		if (ppdu_info->peer_id == HAL_INVALID_PEERID ||
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/dp_rx.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/dp_rx.h
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 #ifndef ATH11K_DP_RX_H
 #define ATH11K_DP_RX_H
@@ -95,4 +96,6 @@
 int ath11k_dp_rx_pktlog_start(struct ath11k_base *ab);
 int ath11k_dp_rx_pktlog_stop(struct ath11k_base *ab, bool stop_timer);
 
+int ath11k_dp_rx_crypto_mic_len(struct ath11k *ar, enum hal_encrypt_type enctype);
+
 #endif /* ATH11K_DP_RX_H */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/dp_tx.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/dp_tx.c
@@ -1035,7 +1035,7 @@
 	int ret;
 	int i;
 
-	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+	for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 		skb = ath11k_htc_alloc_skb(ab, len);
 		if (!skb)
 			return -ENOMEM;
@@ -1218,7 +1218,7 @@
 						       &tlv_filter);
 	} else if (!reset) {
 		/* set in monitor mode only */
-		for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+		for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 			ring_id = dp->rx_mac_buf_ring[i].ring_id;
 			ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,
 							       dp->mac_id + i,
@@ -1231,7 +1231,7 @@
 	if (ret)
 		return ret;
 
-	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+	for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 		ring_id = dp->rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
 		if (!reset) {
 			tlv_filter.rx_filter =
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/hal.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/hal.c
@@ -600,7 +600,11 @@
 	u32 len;
 
 	len = FIELD_GET(HAL_CE_DST_STATUS_DESC_FLAGS_LEN, desc->flags);
-	desc->flags &= ~HAL_CE_DST_STATUS_DESC_FLAGS_LEN;
+	/* Skip updating the length field of the descriptor when it is 0,
+	 * because there's a racing update, may never see the updated length.
+	 */
+	if (likely(len))
+		desc->flags &= ~HAL_CE_DST_STATUS_DESC_FLAGS_LEN;
 
 	return len;
 }
@@ -641,6 +645,21 @@
 	}
 }
 
+void ath11k_hal_srng_dst_next(struct ath11k_base *ab, struct hal_srng *srng)
+{
+	lockdep_assert_held(&srng->lock);
+
+	srng->u.dst_ring.tp += srng->entry_size;
+
+	/* wrap around to start of ring*/
+	if (srng->u.dst_ring.tp == srng->ring_size)
+		srng->u.dst_ring.tp = 0;
+
+	/* Try to prefetch the next descriptor in the ring */
+	if (srng->flags & HAL_SRNG_FLAGS_CACHED)
+		ath11k_hal_srng_prefetch_desc(ab, srng);
+}
+
 u32 *ath11k_hal_srng_dst_get_next_entry(struct ath11k_base *ab,
 					struct hal_srng *srng)
 {
@@ -1322,6 +1341,7 @@
 	ath11k_hal_free_cont_rdp(ab);
 	ath11k_hal_free_cont_wrp(ab);
 	kfree(hal->srng_config);
+	hal->srng_config = NULL;
 }
 EXPORT_SYMBOL(ath11k_hal_srng_deinit);
 
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/hal.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/hal.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022, 2025 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef ATH11K_HAL_H
@@ -940,6 +940,7 @@
 int ath11k_hal_srng_get_max_entries(struct ath11k_base *ab, u32 ring_type);
 void ath11k_hal_srng_get_params(struct ath11k_base *ab, struct hal_srng *srng,
 				struct hal_srng_params *params);
+void ath11k_hal_srng_dst_next(struct ath11k_base *ab, struct hal_srng *srng);
 u32 *ath11k_hal_srng_dst_get_next_entry(struct ath11k_base *ab,
 					struct hal_srng *srng);
 u32 *ath11k_hal_srng_dst_peek(struct ath11k_base *ab, struct hal_srng *srng);
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/hal_rx.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/hal_rx.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "debug.h"
@@ -372,7 +372,8 @@
 
 	ret_buf_mgr = FIELD_GET(BUFFER_ADDR_INFO1_RET_BUF_MGR,
 				wbm_desc->buf_addr_info.info1);
-	if (ret_buf_mgr != HAL_RX_BUF_RBM_SW3_BM) {
+	if (ret_buf_mgr != HAL_RX_BUF_RBM_SW1_BM &&
+	    ret_buf_mgr != HAL_RX_BUF_RBM_SW3_BM) {
 		ab->soc_stats.invalid_rbm++;
 		return -EINVAL;
 	}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/hif.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/hif.h
@@ -31,6 +31,7 @@
 	void (*ce_irq_enable)(struct ath11k_base *ab);
 	void (*ce_irq_disable)(struct ath11k_base *ab);
 	void (*get_ce_msi_idx)(struct ath11k_base *ab, u32 ce_id, u32 *msi_idx);
+	void (*coredump_download)(struct ath11k_base *ab);
 };
 
 static inline void ath11k_hif_ce_irq_enable(struct ath11k_base *ab)
@@ -146,4 +147,10 @@
 		*msi_data_idx = ce_id;
 }
 
+static inline void ath11k_hif_coredump_download(struct ath11k_base *ab)
+{
+	if (ab->hif.ops->coredump_download)
+		ab->hif.ops->coredump_download(ab);
+}
+
 #endif /* _HIF_H_ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/hw.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/hw.c
@@ -58,7 +58,7 @@
 static void ath11k_init_wmi_config_qca6390(struct ath11k_base *ab,
 					   struct target_resource_config *config)
 {
-	config->num_vdevs = 4;
+	config->num_vdevs = ab->hw_params.num_vdevs;
 	config->num_peers = 16;
 	config->num_tids = 32;
 
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/hw.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/hw.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef ATH11K_HW_H
@@ -167,7 +167,7 @@
 	bool single_pdev_only;
 
 	bool rxdma1_enable;
-	int num_rxmda_per_pdev;
+	int num_rxdma_per_pdev;
 	bool rx_mac_buf_ring;
 	bool vdev_start_delay;
 	bool htt_peer_map_v2;
@@ -226,6 +226,8 @@
 	u32 tx_ring_size;
 	bool smp2p_wow_exit;
 	bool support_fw_mac_sequence;
+	bool support_dual_stations;
+	bool pdev_suspend;
 };
 
 struct ath11k_hw_ops {
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/mac.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/mac.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <net/mac80211.h>
@@ -255,9 +255,6 @@
 	[WLAN_HT_CAP_SM_PS_DISABLED] = WMI_PEER_SMPS_PS_NONE,
 };
 
-static int ath11k_start_vdev_delay(struct ieee80211_hw *hw,
-				   struct ieee80211_vif *vif);
-
 enum nl80211_he_ru_alloc ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(u16 ru_phy)
 {
 	enum nl80211_he_ru_alloc ret;
@@ -1234,14 +1231,7 @@
 
 	enable_ps = arvif->ps;
 
-	if (!arvif->is_started) {
-		/* mac80211 can update vif powersave state while disconnected.
-		 * Firmware doesn't behave nicely and consumes more power than
-		 * necessary if PS is disabled on a non-started vdev. Hence
-		 * force-enable PS for non-running vdevs.
-		 */
-		psmode = WMI_STA_PS_MODE_ENABLED;
-	} else if (enable_ps) {
+	if (enable_ps) {
 		psmode = WMI_STA_PS_MODE_ENABLED;
 		param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
 
@@ -2297,6 +2287,8 @@
 	mcs_160_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160);
 	mcs_80_map = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80);
 
+	/* Initialize rx_mcs_160 to 9 which is an invalid value */
+	rx_mcs_160 = 9;
 	if (support_160) {
 		for (i = 7; i >= 0; i--) {
 			u8 mcs_160 = (mcs_160_map >> (2 * i)) & 3;
@@ -2308,6 +2300,8 @@
 		}
 	}
 
+	/* Initialize rx_mcs_80 to 9 which is an invalid value */
+	rx_mcs_80 = 9;
 	for (i = 7; i >= 0; i--) {
 		u8 mcs_80 = (mcs_80_map >> (2 * i)) & 3;
 
@@ -3026,7 +3020,14 @@
 
 	rcu_read_unlock();
 
+	if (!ath11k_mac_vif_recalc_sta_he_txbf(ar, vif, &he_cap)) {
+		ath11k_warn(ar->ab, "failed to recalc he txbf for vdev %i on bss %pM\n",
+			    arvif->vdev_id, bss_conf->bssid);
+		return;
+	}
+
 	peer_arg.is_assoc = true;
+
 	ret = ath11k_wmi_send_peer_assoc_cmd(ar, &peer_arg);
 	if (ret) {
 		ath11k_warn(ar->ab, "failed to run peer assoc for %pM vdev %i: %d\n",
@@ -3049,12 +3050,6 @@
 		return;
 	}
 
-	if (!ath11k_mac_vif_recalc_sta_he_txbf(ar, vif, &he_cap)) {
-		ath11k_warn(ar->ab, "failed to recalc he txbf for vdev %i on bss %pM\n",
-			    arvif->vdev_id, bss_conf->bssid);
-		return;
-	}
-
 	WARN_ON(arvif->is_up);
 
 	arvif->aid = vif->cfg.aid;
@@ -4133,6 +4128,7 @@
 
 	switch (key->cipher) {
 	case WLAN_CIPHER_SUITE_CCMP:
+	case WLAN_CIPHER_SUITE_CCMP_256:
 		arg.key_cipher = WMI_CIPHER_AES_CCM;
 		/* TODO: Re-check if flag is valid */
 		key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
@@ -4142,12 +4138,10 @@
 		arg.key_txmic_len = 8;
 		arg.key_rxmic_len = 8;
 		break;
-	case WLAN_CIPHER_SUITE_CCMP_256:
-		arg.key_cipher = WMI_CIPHER_AES_CCM;
-		break;
 	case WLAN_CIPHER_SUITE_GCMP:
 	case WLAN_CIPHER_SUITE_GCMP_256:
 		arg.key_cipher = WMI_CIPHER_AES_GCM;
+		key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;
 		break;
 	default:
 		ath11k_warn(ar->ab, "cipher %d is not supported\n", key->cipher);
@@ -4906,100 +4900,6 @@
 	ar->num_stations--;
 }
 
-static int ath11k_mac_station_add(struct ath11k *ar,
-				  struct ieee80211_vif *vif,
-				  struct ieee80211_sta *sta)
-{
-	struct ath11k_base *ab = ar->ab;
-	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
-	struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
-	struct peer_create_params peer_param;
-	int ret;
-
-	lockdep_assert_held(&ar->conf_mutex);
-
-	ret = ath11k_mac_inc_num_stations(arvif, sta);
-	if (ret) {
-		ath11k_warn(ab, "refusing to associate station: too many connected already (%d)\n",
-			    ar->max_num_stations);
-		goto exit;
-	}
-
-	arsta->rx_stats = kzalloc(sizeof(*arsta->rx_stats), GFP_KERNEL);
-	if (!arsta->rx_stats) {
-		ret = -ENOMEM;
-		goto dec_num_station;
-	}
-
-	peer_param.vdev_id = arvif->vdev_id;
-	peer_param.peer_addr = sta->addr;
-	peer_param.peer_type = WMI_PEER_TYPE_DEFAULT;
-
-	ret = ath11k_peer_create(ar, arvif, sta, &peer_param);
-	if (ret) {
-		ath11k_warn(ab, "Failed to add peer: %pM for VDEV: %d\n",
-			    sta->addr, arvif->vdev_id);
-		goto free_rx_stats;
-	}
-
-	ath11k_dbg(ab, ATH11K_DBG_MAC, "Added peer: %pM for VDEV: %d\n",
-		   sta->addr, arvif->vdev_id);
-
-	if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) {
-		arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats), GFP_KERNEL);
-		if (!arsta->tx_stats) {
-			ret = -ENOMEM;
-			goto free_peer;
-		}
-	}
-
-	if (ieee80211_vif_is_mesh(vif)) {
-		ath11k_dbg(ab, ATH11K_DBG_MAC,
-			   "setting USE_4ADDR for mesh STA %pM\n", sta->addr);
-		ret = ath11k_wmi_set_peer_param(ar, sta->addr,
-						arvif->vdev_id,
-						WMI_PEER_USE_4ADDR, 1);
-		if (ret) {
-			ath11k_warn(ab, "failed to set mesh STA %pM 4addr capability: %d\n",
-				    sta->addr, ret);
-			goto free_tx_stats;
-		}
-	}
-
-	ret = ath11k_dp_peer_setup(ar, arvif->vdev_id, sta->addr);
-	if (ret) {
-		ath11k_warn(ab, "failed to setup dp for peer %pM on vdev %i (%d)\n",
-			    sta->addr, arvif->vdev_id, ret);
-		goto free_tx_stats;
-	}
-
-	if (ab->hw_params.vdev_start_delay &&
-	    !arvif->is_started &&
-	    arvif->vdev_type != WMI_VDEV_TYPE_AP) {
-		ret = ath11k_start_vdev_delay(ar->hw, vif);
-		if (ret) {
-			ath11k_warn(ab, "failed to delay vdev start: %d\n", ret);
-			goto free_tx_stats;
-		}
-	}
-
-	ewma_avg_rssi_init(&arsta->avg_rssi);
-	return 0;
-
-free_tx_stats:
-	kfree(arsta->tx_stats);
-	arsta->tx_stats = NULL;
-free_peer:
-	ath11k_peer_delete(ar, arvif->vdev_id, sta->addr);
-free_rx_stats:
-	kfree(arsta->rx_stats);
-	arsta->rx_stats = NULL;
-dec_num_station:
-	ath11k_mac_dec_num_stations(arvif, sta);
-exit:
-	return ret;
-}
-
 static u32 ath11k_mac_ieee80211_sta_bw_to_wmi(struct ath11k *ar,
 					      struct ieee80211_sta *sta)
 {
@@ -5028,140 +4928,6 @@
 	return bw;
 }
 
-static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
-				   struct ieee80211_vif *vif,
-				   struct ieee80211_sta *sta,
-				   enum ieee80211_sta_state old_state,
-				   enum ieee80211_sta_state new_state)
-{
-	struct ath11k *ar = hw->priv;
-	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
-	struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
-	struct ath11k_peer *peer;
-	int ret = 0;
-
-	/* cancel must be done outside the mutex to avoid deadlock */
-	if ((old_state == IEEE80211_STA_NONE &&
-	     new_state == IEEE80211_STA_NOTEXIST)) {
-		cancel_work_sync(&arsta->update_wk);
-		cancel_work_sync(&arsta->set_4addr_wk);
-	}
-
-	mutex_lock(&ar->conf_mutex);
-
-	if (old_state == IEEE80211_STA_NOTEXIST &&
-	    new_state == IEEE80211_STA_NONE) {
-		memset(arsta, 0, sizeof(*arsta));
-		arsta->arvif = arvif;
-		arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
-		INIT_WORK(&arsta->update_wk, ath11k_sta_rc_update_wk);
-		INIT_WORK(&arsta->set_4addr_wk, ath11k_sta_set_4addr_wk);
-
-		ret = ath11k_mac_station_add(ar, vif, sta);
-		if (ret)
-			ath11k_warn(ar->ab, "Failed to add station: %pM for VDEV: %d\n",
-				    sta->addr, arvif->vdev_id);
-	} else if ((old_state == IEEE80211_STA_NONE &&
-		    new_state == IEEE80211_STA_NOTEXIST)) {
-		bool skip_peer_delete = ar->ab->hw_params.vdev_start_delay &&
-			vif->type == NL80211_IFTYPE_STATION;
-
-		ath11k_dp_peer_cleanup(ar, arvif->vdev_id, sta->addr);
-
-		if (!skip_peer_delete) {
-			ret = ath11k_peer_delete(ar, arvif->vdev_id, sta->addr);
-			if (ret)
-				ath11k_warn(ar->ab,
-					    "Failed to delete peer: %pM for VDEV: %d\n",
-					    sta->addr, arvif->vdev_id);
-			else
-				ath11k_dbg(ar->ab,
-					   ATH11K_DBG_MAC,
-					   "Removed peer: %pM for VDEV: %d\n",
-					   sta->addr, arvif->vdev_id);
-		}
-
-		ath11k_mac_dec_num_stations(arvif, sta);
-		mutex_lock(&ar->ab->tbl_mtx_lock);
-		spin_lock_bh(&ar->ab->base_lock);
-		peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
-		if (skip_peer_delete && peer) {
-			peer->sta = NULL;
-		} else if (peer && peer->sta == sta) {
-			ath11k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n",
-				    vif->addr, arvif->vdev_id);
-			ath11k_peer_rhash_delete(ar->ab, peer);
-			peer->sta = NULL;
-			list_del(&peer->list);
-			kfree(peer);
-			ar->num_peers--;
-		}
-		spin_unlock_bh(&ar->ab->base_lock);
-		mutex_unlock(&ar->ab->tbl_mtx_lock);
-
-		kfree(arsta->tx_stats);
-		arsta->tx_stats = NULL;
-
-		kfree(arsta->rx_stats);
-		arsta->rx_stats = NULL;
-	} else if (old_state == IEEE80211_STA_AUTH &&
-		   new_state == IEEE80211_STA_ASSOC &&
-		   (vif->type == NL80211_IFTYPE_AP ||
-		    vif->type == NL80211_IFTYPE_MESH_POINT ||
-		    vif->type == NL80211_IFTYPE_ADHOC)) {
-		ret = ath11k_station_assoc(ar, vif, sta, false);
-		if (ret)
-			ath11k_warn(ar->ab, "Failed to associate station: %pM\n",
-				    sta->addr);
-
-		spin_lock_bh(&ar->data_lock);
-		/* Set arsta bw and prev bw */
-		arsta->bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta);
-		arsta->bw_prev = arsta->bw;
-		spin_unlock_bh(&ar->data_lock);
-	} else if (old_state == IEEE80211_STA_ASSOC &&
-		   new_state == IEEE80211_STA_AUTHORIZED) {
-		spin_lock_bh(&ar->ab->base_lock);
-
-		peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
-		if (peer)
-			peer->is_authorized = true;
-
-		spin_unlock_bh(&ar->ab->base_lock);
-
-		if (vif->type == NL80211_IFTYPE_STATION && arvif->is_up) {
-			ret = ath11k_wmi_set_peer_param(ar, sta->addr,
-							arvif->vdev_id,
-							WMI_PEER_AUTHORIZE,
-							1);
-			if (ret)
-				ath11k_warn(ar->ab, "Unable to authorize peer %pM vdev %d: %d\n",
-					    sta->addr, arvif->vdev_id, ret);
-		}
-	} else if (old_state == IEEE80211_STA_AUTHORIZED &&
-		   new_state == IEEE80211_STA_ASSOC) {
-		spin_lock_bh(&ar->ab->base_lock);
-
-		peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
-		if (peer)
-			peer->is_authorized = false;
-
-		spin_unlock_bh(&ar->ab->base_lock);
-	} else if (old_state == IEEE80211_STA_ASSOC &&
-		   new_state == IEEE80211_STA_AUTH &&
-		   (vif->type == NL80211_IFTYPE_AP ||
-		    vif->type == NL80211_IFTYPE_MESH_POINT ||
-		    vif->type == NL80211_IFTYPE_ADHOC)) {
-		ret = ath11k_station_disassoc(ar, vif, sta);
-		if (ret)
-			ath11k_warn(ar->ab, "Failed to disassociate station: %pM\n",
-				    sta->addr);
-	}
-
-	mutex_unlock(&ar->conf_mutex);
-	return ret;
-}
-
 static int ath11k_mac_op_sta_set_txpwr(struct ieee80211_hw *hw,
 				       struct ieee80211_vif *vif,
 				       struct ieee80211_sta *sta)
@@ -5338,6 +5104,51 @@
 	return ret;
 }
 
+static int ath11k_mac_op_conf_tx_mu_edca(struct ieee80211_hw *hw,
+					 struct ieee80211_vif *vif,
+					 unsigned int link_id, u16 ac,
+					 const struct ieee80211_tx_queue_params *params)
+{
+	struct ath11k *ar = hw->priv;
+	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
+	struct wmi_wmm_params_arg *p = NULL;
+	int ret;
+
+	switch (ac) {
+	case IEEE80211_AC_VO:
+		p = &arvif->muedca_params.ac_vo;
+		break;
+	case IEEE80211_AC_VI:
+		p = &arvif->muedca_params.ac_vi;
+		break;
+	case IEEE80211_AC_BE:
+		p = &arvif->muedca_params.ac_be;
+		break;
+	case IEEE80211_AC_BK:
+		p = &arvif->muedca_params.ac_bk;
+		break;
+	}
+
+	if (WARN_ON(!p)) {
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	p->cwmin = params->mu_edca_param_rec.ecw_min_max & 0x0f;
+	p->cwmax = (params->mu_edca_param_rec.ecw_min_max & 0xf0) >> 4;
+	p->aifs = params->mu_edca_param_rec.aifsn & 0x0f;
+	p->txop = params->mu_edca_param_rec.mu_edca_timer;
+
+	ret = ath11k_wmi_send_wmm_update_cmd_tlv(ar, arvif->vdev_id,
+						 &arvif->muedca_params,
+						 WMM_PARAM_TYPE_11AX_MU_EDCA);
+	if (ret)
+		ath11k_warn(ar->ab, "failed to set mu_edca params: %d\n", ret);
+
+exit:
+	return ret;
+}
+
 static int ath11k_mac_op_conf_tx(struct ieee80211_hw *hw,
 				 struct ieee80211_vif *vif,
 				 unsigned int link_id, u16 ac,
@@ -5376,12 +5187,21 @@
 	p->txop = params->txop;
 
 	ret = ath11k_wmi_send_wmm_update_cmd_tlv(ar, arvif->vdev_id,
-						 &arvif->wmm_params);
+					 &arvif->wmm_params, WMM_PARAM_TYPE_LEGACY);
 	if (ret) {
 		ath11k_warn(ar->ab, "failed to set wmm params: %d\n", ret);
 		goto exit;
 	}
 
+	if (params->mu_edca) {
+		ret = ath11k_mac_op_conf_tx_mu_edca(hw, vif, link_id, ac,
+						    params);
+		if (ret) {
+			ath11k_warn(ar->ab, "failed to set mu_edca params: %d\n", ret);
+			goto exit;
+		}
+	}
+
 	ret = ath11k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
 
 	if (ret)
@@ -5470,8 +5290,6 @@
 	if (vht_cap & (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE)) {
 		nsts = vht_cap & IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
 		nsts >>= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
-		if (nsts > (ar->num_rx_chains - 1))
-			nsts = ar->num_rx_chains - 1;
 		value |= SM(nsts, WMI_TXBF_STS_CAP_OFFSET);
 	}
 
@@ -5555,9 +5373,6 @@
 
 	/* Enable Beamformee STS Field only if SU BF is enabled */
 	if (subfee) {
-		if (nsts > (ar->num_rx_chains - 1))
-			nsts = ar->num_rx_chains - 1;
-
 		nsts <<= IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT;
 		nsts &=  IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
 		*vht_cap |= nsts;
@@ -6035,7 +5850,10 @@
 {
 	struct ath11k_base *ab = ar->ab;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);
 	struct ieee80211_tx_info *info;
+	enum hal_encrypt_type enctype;
+	unsigned int mic_len;
 	dma_addr_t paddr;
 	int buf_id;
 	int ret;
@@ -6059,7 +5877,12 @@
 		     ieee80211_is_deauth(hdr->frame_control) ||
 		     ieee80211_is_disassoc(hdr->frame_control)) &&
 		     ieee80211_has_protected(hdr->frame_control)) {
-			skb_put(skb, IEEE80211_CCMP_MIC_LEN);
+			if (!(skb_cb->flags & ATH11K_SKB_CIPHER_SET))
+				ath11k_warn(ab, "WMI management tx frame without ATH11K_SKB_CIPHER_SET");
+
+			enctype = ath11k_dp_tx_get_encrypt_type(skb_cb->cipher);
+			mic_len = ath11k_dp_rx_crypto_mic_len(ar, enctype);
+			skb_put(skb, mic_len);
 		}
 	}
 
@@ -6240,7 +6063,7 @@
 			tlv_filter.rx_filter = ath11k_debugfs_rx_filter(ar);
 	}
 
-	for (i = 0; i < ab->hw_params.num_rxmda_per_pdev; i++) {
+	for (i = 0; i < ab->hw_params.num_rxdma_per_pdev; i++) {
 		ring_id = ar->dp.rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
 		ret = ath11k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,
 						       ar->dp.mac_id + i,
@@ -6724,6 +6547,16 @@
 	return ret;
 }
 
+static void ath11k_mac_bcn_tx_work(struct work_struct *work)
+{
+	struct ath11k_vif *arvif = container_of(work, struct ath11k_vif,
+						bcn_tx_work);
+
+	mutex_lock(&arvif->ar->conf_mutex);
+	ath11k_mac_bcn_tx_event(arvif);
+	mutex_unlock(&arvif->ar->conf_mutex);
+}
+
 static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
 				       struct ieee80211_vif *vif)
 {
@@ -6762,6 +6595,7 @@
 	arvif->vif = vif;
 
 	INIT_LIST_HEAD(&arvif->list);
+	INIT_WORK(&arvif->bcn_tx_work, ath11k_mac_bcn_tx_work);
 	INIT_DELAYED_WORK(&arvif->connection_loss_work,
 			  ath11k_mac_vif_sta_connection_loss_work);
 
@@ -6940,6 +6774,14 @@
 				    ret);
 	}
 
+	if (ath11k_wmi_supports_6ghz_cc_ext(ar)) {
+		struct cur_regulatory_info *reg_info;
+
+		reg_info = &ab->reg_info_store[ar->pdev_idx];
+		ath11k_dbg(ab, ATH11K_DBG_MAC, "interface added to change reg rules\n");
+		ath11k_reg_handle_chan_list(ab, reg_info, IEEE80211_REG_LPI_AP);
+	}
+
 	mutex_unlock(&ar->conf_mutex);
 
 	return 0;
@@ -6987,6 +6829,7 @@
 	int i;
 
 	cancel_delayed_work_sync(&arvif->connection_loss_work);
+	cancel_work_sync(&arvif->bcn_tx_work);
 
 	mutex_lock(&ar->conf_mutex);
 
@@ -7542,8 +7385,8 @@
 	mutex_unlock(&ar->conf_mutex);
 }
 
-static int ath11k_start_vdev_delay(struct ieee80211_hw *hw,
-				   struct ieee80211_vif *vif)
+static int ath11k_mac_start_vdev_delay(struct ieee80211_hw *hw,
+				       struct ieee80211_vif *vif)
 {
 	struct ath11k *ar = hw->priv;
 	struct ath11k_base *ab = ar->ab;
@@ -7589,6 +7432,30 @@
 	return 0;
 }
 
+static int ath11k_mac_stop_vdev_early(struct ieee80211_hw *hw,
+				      struct ieee80211_vif *vif)
+{
+	struct ath11k *ar = hw->priv;
+	struct ath11k_base *ab = ar->ab;
+	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
+	int ret;
+
+	if (WARN_ON(!arvif->is_started))
+		return -EBUSY;
+
+	ret = ath11k_mac_vdev_stop(arvif);
+	if (ret) {
+		ath11k_warn(ab, "failed to stop vdev %i: %d\n",
+			    arvif->vdev_id, ret);
+		return ret;
+	}
+
+	arvif->is_started = false;
+
+	/* TODO: Setup ps and cts/rts protection */
+	return 0;
+}
+
 static int
 ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
 				 struct ieee80211_vif *vif,
@@ -7599,7 +7466,8 @@
 	struct ath11k_base *ab = ar->ab;
 	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
 	int ret;
-	struct peer_create_params param;
+	struct cur_regulatory_info *reg_info;
+	enum ieee80211_ap_reg_power power_type;
 
 	mutex_lock(&ar->conf_mutex);
 
@@ -7607,6 +7475,22 @@
 		   "chanctx assign ptr %p vdev_id %i\n",
 		   ctx, arvif->vdev_id);
 
+	if (ath11k_wmi_supports_6ghz_cc_ext(ar) &&
+	    ctx->def.chan->band == NL80211_BAND_6GHZ &&
+	    arvif->vdev_type == WMI_VDEV_TYPE_STA) {
+		reg_info = &ab->reg_info_store[ar->pdev_idx];
+		power_type = vif->bss_conf.power_type;
+
+		ath11k_dbg(ab, ATH11K_DBG_MAC, "chanctx power type %d\n", power_type);
+
+		if (power_type == IEEE80211_REG_UNSET_AP) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		ath11k_reg_handle_chan_list(ab, reg_info, power_type);
+	}
+
 	/* for QCA6390 bss peer must be created before vdev_start */
 	if (ab->hw_params.vdev_start_delay &&
 	    arvif->vdev_type != WMI_VDEV_TYPE_AP &&
@@ -7622,21 +7506,6 @@
 		goto out;
 	}
 
-	if (ab->hw_params.vdev_start_delay &&
-	    arvif->vdev_type != WMI_VDEV_TYPE_AP &&
-	    arvif->vdev_type != WMI_VDEV_TYPE_MONITOR) {
-		param.vdev_id = arvif->vdev_id;
-		param.peer_type = WMI_PEER_TYPE_DEFAULT;
-		param.peer_addr = ar->mac_addr;
-
-		ret = ath11k_peer_create(ar, arvif, NULL, &param);
-		if (ret) {
-			ath11k_warn(ab, "failed to create peer after vdev start delay: %d",
-				    ret);
-			goto out;
-		}
-	}
-
 	if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
 		ret = ath11k_mac_monitor_start(ar);
 		if (ret) {
@@ -7649,15 +7518,17 @@
 		goto out;
 	}
 
-	ret = ath11k_mac_vdev_start(arvif, ctx);
-	if (ret) {
-		ath11k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n",
-			    arvif->vdev_id, vif->addr,
-			    ctx->def.chan->center_freq, ret);
-		goto out;
-	}
+	if (!arvif->is_started) {
+		ret = ath11k_mac_vdev_start(arvif, ctx);
+		if (ret) {
+			ath11k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n",
+				    arvif->vdev_id, vif->addr,
+				    ctx->def.chan->center_freq, ret);
+			goto out;
+		}
 
-	arvif->is_started = true;
+		arvif->is_started = true;
+	}
 
 	if (arvif->vdev_type != WMI_VDEV_TYPE_MONITOR &&
 	    test_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags)) {
@@ -7697,8 +7568,6 @@
 		   "chanctx unassign ptr %p vdev_id %i\n",
 		   ctx, arvif->vdev_id);
 
-	WARN_ON(!arvif->is_started);
-
 	if (ab->hw_params.vdev_start_delay &&
 	    arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) {
 		spin_lock_bh(&ab->base_lock);
@@ -7722,24 +7591,13 @@
 		return;
 	}
 
-	ret = ath11k_mac_vdev_stop(arvif);
-	if (ret)
-		ath11k_warn(ab, "failed to stop vdev %i: %d\n",
-			    arvif->vdev_id, ret);
-
-	arvif->is_started = false;
-
-	if (ab->hw_params.vdev_start_delay &&
-	    arvif->vdev_type == WMI_VDEV_TYPE_STA) {
-		ret = ath11k_peer_delete(ar, arvif->vdev_id, arvif->bssid);
+	if (arvif->is_started) {
+		ret = ath11k_mac_vdev_stop(arvif);
 		if (ret)
-			ath11k_warn(ar->ab,
-				    "failed to delete peer %pM for vdev %d: %d\n",
-				    arvif->bssid, arvif->vdev_id, ret);
-		else
-			ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
-				   "removed peer %pM  vdev %d after vdev stop\n",
-				   arvif->bssid, arvif->vdev_id);
+			ath11k_warn(ab, "failed to stop vdev %i: %d\n",
+				    arvif->vdev_id, ret);
+
+		arvif->is_started = false;
 	}
 
 	if (ab->hw_params.vdev_start_delay &&
@@ -8482,12 +8340,8 @@
 		ieee80211_wake_queues(ar->hw);
 
 		if (ar->ab->hw_params.current_cc_support &&
-		    ar->alpha2[0] != 0 && ar->alpha2[1] != 0) {
-			struct wmi_set_current_country_params set_current_param = {};
-
-			memcpy(&set_current_param.alpha2, ar->alpha2, 2);
-			ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
-		}
+		    ar->alpha2[0] != 0 && ar->alpha2[1] != 0)
+			ath11k_reg_set_cc(ar);
 
 		if (ab->is_reset) {
 			recovery_count = atomic_inc_return(&ab->recovery_count);
@@ -9097,6 +8951,252 @@
 	return 0;
 }
 
+static int ath11k_mac_station_add(struct ath11k *ar,
+				  struct ieee80211_vif *vif,
+				  struct ieee80211_sta *sta)
+{
+	struct ath11k_base *ab = ar->ab;
+	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
+	struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
+	struct peer_create_params peer_param;
+	int ret;
+
+	lockdep_assert_held(&ar->conf_mutex);
+
+	ret = ath11k_mac_inc_num_stations(arvif, sta);
+	if (ret) {
+		ath11k_warn(ab, "refusing to associate station: too many connected already (%d)\n",
+			    ar->max_num_stations);
+		goto exit;
+	}
+
+	arsta->rx_stats = kzalloc(sizeof(*arsta->rx_stats), GFP_KERNEL);
+	if (!arsta->rx_stats) {
+		ret = -ENOMEM;
+		goto dec_num_station;
+	}
+
+	peer_param.vdev_id = arvif->vdev_id;
+	peer_param.peer_addr = sta->addr;
+	peer_param.peer_type = WMI_PEER_TYPE_DEFAULT;
+
+	ret = ath11k_peer_create(ar, arvif, sta, &peer_param);
+	if (ret) {
+		ath11k_warn(ab, "Failed to add peer: %pM for VDEV: %d\n",
+			    sta->addr, arvif->vdev_id);
+		goto free_rx_stats;
+	}
+
+	ath11k_dbg(ab, ATH11K_DBG_MAC, "Added peer: %pM for VDEV: %d\n",
+		   sta->addr, arvif->vdev_id);
+
+	if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) {
+		arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats), GFP_KERNEL);
+		if (!arsta->tx_stats) {
+			ret = -ENOMEM;
+			goto free_peer;
+		}
+	}
+
+	if (ieee80211_vif_is_mesh(vif)) {
+		ath11k_dbg(ab, ATH11K_DBG_MAC,
+			   "setting USE_4ADDR for mesh STA %pM\n", sta->addr);
+		ret = ath11k_wmi_set_peer_param(ar, sta->addr,
+						arvif->vdev_id,
+						WMI_PEER_USE_4ADDR, 1);
+		if (ret) {
+			ath11k_warn(ab, "failed to set mesh STA %pM 4addr capability: %d\n",
+				    sta->addr, ret);
+			goto free_tx_stats;
+		}
+	}
+
+	ret = ath11k_dp_peer_setup(ar, arvif->vdev_id, sta->addr);
+	if (ret) {
+		ath11k_warn(ab, "failed to setup dp for peer %pM on vdev %i (%d)\n",
+			    sta->addr, arvif->vdev_id, ret);
+		goto free_tx_stats;
+	}
+
+	if (ab->hw_params.vdev_start_delay &&
+	    !arvif->is_started &&
+	    arvif->vdev_type != WMI_VDEV_TYPE_AP) {
+		ret = ath11k_mac_start_vdev_delay(ar->hw, vif);
+		if (ret) {
+			ath11k_warn(ab, "failed to delay vdev start: %d\n", ret);
+			goto free_tx_stats;
+		}
+	}
+
+	ewma_avg_rssi_init(&arsta->avg_rssi);
+	return 0;
+
+free_tx_stats:
+	kfree(arsta->tx_stats);
+	arsta->tx_stats = NULL;
+free_peer:
+	ath11k_peer_delete(ar, arvif->vdev_id, sta->addr);
+free_rx_stats:
+	kfree(arsta->rx_stats);
+	arsta->rx_stats = NULL;
+dec_num_station:
+	ath11k_mac_dec_num_stations(arvif, sta);
+exit:
+	return ret;
+}
+
+static int ath11k_mac_station_remove(struct ath11k *ar,
+				     struct ieee80211_vif *vif,
+				     struct ieee80211_sta *sta)
+{
+	struct ath11k_base *ab = ar->ab;
+	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
+	struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
+	int ret;
+
+	if (ab->hw_params.vdev_start_delay &&
+	    arvif->is_started &&
+	    arvif->vdev_type != WMI_VDEV_TYPE_AP) {
+		ret = ath11k_mac_stop_vdev_early(ar->hw, vif);
+		if (ret) {
+			ath11k_warn(ab, "failed to do early vdev stop: %d\n", ret);
+			return ret;
+		}
+	}
+
+	ath11k_dp_peer_cleanup(ar, arvif->vdev_id, sta->addr);
+
+	ret = ath11k_peer_delete(ar, arvif->vdev_id, sta->addr);
+	if (ret)
+		ath11k_warn(ab, "Failed to delete peer: %pM for VDEV: %d\n",
+			    sta->addr, arvif->vdev_id);
+	else
+		ath11k_dbg(ab, ATH11K_DBG_MAC, "Removed peer: %pM for VDEV: %d\n",
+			   sta->addr, arvif->vdev_id);
+
+	ath11k_mac_dec_num_stations(arvif, sta);
+
+	kfree(arsta->tx_stats);
+	arsta->tx_stats = NULL;
+
+	kfree(arsta->rx_stats);
+	arsta->rx_stats = NULL;
+
+	return ret;
+}
+
+static int ath11k_mac_op_sta_state(struct ieee80211_hw *hw,
+				   struct ieee80211_vif *vif,
+				   struct ieee80211_sta *sta,
+				   enum ieee80211_sta_state old_state,
+				   enum ieee80211_sta_state new_state)
+{
+	struct ath11k *ar = hw->priv;
+	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
+	struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
+	struct ath11k_peer *peer;
+	int ret = 0;
+
+	/* cancel must be done outside the mutex to avoid deadlock */
+	if ((old_state == IEEE80211_STA_NONE &&
+	     new_state == IEEE80211_STA_NOTEXIST)) {
+		cancel_work_sync(&arsta->update_wk);
+		cancel_work_sync(&arsta->set_4addr_wk);
+	}
+
+	mutex_lock(&ar->conf_mutex);
+
+	if (old_state == IEEE80211_STA_NOTEXIST &&
+	    new_state == IEEE80211_STA_NONE) {
+		memset(arsta, 0, sizeof(*arsta));
+		arsta->arvif = arvif;
+		arsta->peer_ps_state = WMI_PEER_PS_STATE_DISABLED;
+		INIT_WORK(&arsta->update_wk, ath11k_sta_rc_update_wk);
+		INIT_WORK(&arsta->set_4addr_wk, ath11k_sta_set_4addr_wk);
+
+		ret = ath11k_mac_station_add(ar, vif, sta);
+		if (ret)
+			ath11k_warn(ar->ab, "Failed to add station: %pM for VDEV: %d\n",
+				    sta->addr, arvif->vdev_id);
+	} else if ((old_state == IEEE80211_STA_NONE &&
+		    new_state == IEEE80211_STA_NOTEXIST)) {
+		ret = ath11k_mac_station_remove(ar, vif, sta);
+		if (ret)
+			ath11k_warn(ar->ab, "Failed to remove station: %pM for VDEV: %d\n",
+				    sta->addr, arvif->vdev_id);
+
+		mutex_lock(&ar->ab->tbl_mtx_lock);
+		spin_lock_bh(&ar->ab->base_lock);
+		peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
+		if (peer && peer->sta == sta) {
+			ath11k_warn(ar->ab, "Found peer entry %pM n vdev %i after it was supposedly removed\n",
+				    vif->addr, arvif->vdev_id);
+			ath11k_peer_rhash_delete(ar->ab, peer);
+			peer->sta = NULL;
+			list_del(&peer->list);
+			kfree(peer);
+			ar->num_peers--;
+		}
+		spin_unlock_bh(&ar->ab->base_lock);
+		mutex_unlock(&ar->ab->tbl_mtx_lock);
+	} else if (old_state == IEEE80211_STA_AUTH &&
+		   new_state == IEEE80211_STA_ASSOC &&
+		   (vif->type == NL80211_IFTYPE_AP ||
+		    vif->type == NL80211_IFTYPE_MESH_POINT ||
+		    vif->type == NL80211_IFTYPE_ADHOC)) {
+		ret = ath11k_station_assoc(ar, vif, sta, false);
+		if (ret)
+			ath11k_warn(ar->ab, "Failed to associate station: %pM\n",
+				    sta->addr);
+
+		spin_lock_bh(&ar->data_lock);
+		/* Set arsta bw and prev bw */
+		arsta->bw = ath11k_mac_ieee80211_sta_bw_to_wmi(ar, sta);
+		arsta->bw_prev = arsta->bw;
+		spin_unlock_bh(&ar->data_lock);
+	} else if (old_state == IEEE80211_STA_ASSOC &&
+		   new_state == IEEE80211_STA_AUTHORIZED) {
+		spin_lock_bh(&ar->ab->base_lock);
+
+		peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
+		if (peer)
+			peer->is_authorized = true;
+
+		spin_unlock_bh(&ar->ab->base_lock);
+
+		if (vif->type == NL80211_IFTYPE_STATION && arvif->is_up) {
+			ret = ath11k_wmi_set_peer_param(ar, sta->addr,
+							arvif->vdev_id,
+							WMI_PEER_AUTHORIZE,
+							1);
+			if (ret)
+				ath11k_warn(ar->ab, "Unable to authorize peer %pM vdev %d: %d\n",
+					    sta->addr, arvif->vdev_id, ret);
+		}
+	} else if (old_state == IEEE80211_STA_AUTHORIZED &&
+		   new_state == IEEE80211_STA_ASSOC) {
+		spin_lock_bh(&ar->ab->base_lock);
+
+		peer = ath11k_peer_find(ar->ab, arvif->vdev_id, sta->addr);
+		if (peer)
+			peer->is_authorized = false;
+
+		spin_unlock_bh(&ar->ab->base_lock);
+	} else if (old_state == IEEE80211_STA_ASSOC &&
+		   new_state == IEEE80211_STA_AUTH &&
+		   (vif->type == NL80211_IFTYPE_AP ||
+		    vif->type == NL80211_IFTYPE_MESH_POINT ||
+		    vif->type == NL80211_IFTYPE_ADHOC)) {
+		ret = ath11k_station_disassoc(ar, vif, sta);
+		if (ret)
+			ath11k_warn(ar->ab, "Failed to disassociate station: %pM\n",
+				    sta->addr);
+	}
+
+	mutex_unlock(&ar->conf_mutex);
+	return ret;
+}
+
 static const struct ieee80211_ops ath11k_ops = {
 	.tx				= ath11k_mac_op_tx,
 	.wake_tx_queue			= ieee80211_handle_wake_tx_queue,
@@ -9288,19 +9388,50 @@
 	return 0;
 }
 
+static void ath11k_mac_setup_mac_address_list(struct ath11k *ar)
+{
+	struct mac_address *addresses;
+	u16 n_addresses;
+	int i;
+
+	if (!ar->ab->hw_params.support_dual_stations)
+		return;
+
+	n_addresses = ar->ab->hw_params.num_vdevs;
+	addresses = kcalloc(n_addresses, sizeof(*addresses), GFP_KERNEL);
+	if (!addresses)
+		return;
+
+	memcpy(addresses[0].addr, ar->mac_addr, ETH_ALEN);
+	for (i = 1; i < n_addresses; i++) {
+		memcpy(addresses[i].addr, ar->mac_addr, ETH_ALEN);
+		/* set Local Administered Address bit */
+		addresses[i].addr[0] |= 0x2;
+
+		addresses[i].addr[0] += (i - 1) << 4;
+	}
+
+	ar->hw->wiphy->addresses = addresses;
+	ar->hw->wiphy->n_addresses = n_addresses;
+}
+
 static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
 {
 	struct ath11k_base *ab = ar->ab;
 	struct ieee80211_iface_combination *combinations;
 	struct ieee80211_iface_limit *limits;
-	int n_limits;
+	int n_limits, n_combos;
 
-	combinations = kzalloc(sizeof(*combinations), GFP_KERNEL);
+	if (ab->hw_params.support_dual_stations)
+		n_combos = 2;
+	else
+		n_combos = 1;
+
+	combinations = kcalloc(n_combos, sizeof(*combinations), GFP_KERNEL);
 	if (!combinations)
 		return -ENOMEM;
 
 	n_limits = 2;
-
 	limits = kcalloc(n_limits, sizeof(*limits), GFP_KERNEL);
 	if (!limits) {
 		kfree(combinations);
@@ -9309,20 +9440,18 @@
 
 	limits[0].max = 1;
 	limits[0].types |= BIT(NL80211_IFTYPE_STATION);
-
 	limits[1].max = 16;
 	limits[1].types |= BIT(NL80211_IFTYPE_AP);
-
 	if (IS_ENABLED(CONFIG_MAC80211_MESH) &&
 	    ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT))
 		limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT);
 
 	combinations[0].limits = limits;
 	combinations[0].n_limits = n_limits;
-	combinations[0].max_interfaces = 16;
-	combinations[0].num_different_channels = 1;
 	combinations[0].beacon_int_infra_match = true;
 	combinations[0].beacon_int_min_gcd = 100;
+	combinations[0].max_interfaces = 16;
+	combinations[0].num_different_channels = 1;
 	combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
 						BIT(NL80211_CHAN_WIDTH_20) |
 						BIT(NL80211_CHAN_WIDTH_40) |
@@ -9330,8 +9459,19 @@
 						BIT(NL80211_CHAN_WIDTH_80P80) |
 						BIT(NL80211_CHAN_WIDTH_160);
 
+	if (ab->hw_params.support_dual_stations) {
+		limits[0].max = 2;
+
+		combinations[1].limits = limits;
+		combinations[1].n_limits = n_limits;
+		combinations[1].beacon_int_infra_match = true;
+		combinations[1].beacon_int_min_gcd = 100;
+		combinations[1].max_interfaces = ab->hw_params.num_vdevs;
+		combinations[1].num_different_channels = 2;
+	}
+
 	ar->hw->wiphy->iface_combinations = combinations;
-	ar->hw->wiphy->n_iface_combinations = 1;
+	ar->hw->wiphy->n_iface_combinations = n_combos;
 
 	return 0;
 }
@@ -9393,6 +9533,8 @@
 	kfree(ar->hw->wiphy->iface_combinations[0].limits);
 	kfree(ar->hw->wiphy->iface_combinations);
 
+	kfree(ar->hw->wiphy->addresses);
+
 	SET_IEEE80211_DEV(ar->hw, NULL);
 }
 
@@ -9435,6 +9577,7 @@
 	ath11k_pdev_caps_update(ar);
 
 	SET_IEEE80211_PERM_ADDR(ar->hw, ar->mac_addr);
+	ath11k_mac_setup_mac_address_list(ar);
 
 	SET_IEEE80211_DEV(ar->hw, ab->dev);
 
@@ -9629,11 +9772,8 @@
 	}
 
 	if (ab->hw_params.current_cc_support && ab->new_alpha2[0]) {
-		struct wmi_set_current_country_params set_current_param = {};
-
-		memcpy(&set_current_param.alpha2, ab->new_alpha2, 2);
 		memcpy(&ar->alpha2, ab->new_alpha2, 2);
-		ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
+		ret = ath11k_reg_set_cc(ar);
 		if (ret)
 			ath11k_warn(ar->ab,
 				    "failed set cc code for mac register: %d\n", ret);
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/mhi.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/mhi.c
@@ -20,7 +20,7 @@
 #define MHI_TIMEOUT_DEFAULT_MS	20000
 #define RDDM_DUMP_SIZE	0x420000
 
-static struct mhi_channel_config ath11k_mhi_channels_qca6390[] = {
+static const struct mhi_channel_config ath11k_mhi_channels_qca6390[] = {
 	{
 		.num = 0,
 		.name = "LOOPBACK",
@@ -102,18 +102,18 @@
 	},
 };
 
-static struct mhi_controller_config ath11k_mhi_config_qca6390 = {
+static const struct mhi_controller_config ath11k_mhi_config_qca6390 = {
 	.max_channels = 128,
 	.timeout_ms = 2000,
 	.use_bounce_buf = false,
-	.buf_len = 0,
+	.buf_len = 8192,
 	.num_channels = ARRAY_SIZE(ath11k_mhi_channels_qca6390),
 	.ch_cfg = ath11k_mhi_channels_qca6390,
 	.num_events = ARRAY_SIZE(ath11k_mhi_events_qca6390),
 	.event_cfg = ath11k_mhi_events_qca6390,
 };
 
-static struct mhi_channel_config ath11k_mhi_channels_qcn9074[] = {
+static const struct mhi_channel_config ath11k_mhi_channels_qcn9074[] = {
 	{
 		.num = 0,
 		.name = "LOOPBACK",
@@ -195,7 +195,7 @@
 	},
 };
 
-static struct mhi_controller_config ath11k_mhi_config_qcn9074 = {
+static const struct mhi_controller_config ath11k_mhi_config_qcn9074 = {
 	.max_channels = 30,
 	.timeout_ms = 10000,
 	.use_bounce_buf = false,
@@ -384,7 +384,7 @@
 {
 	struct ath11k_base *ab = ab_pci->ab;
 	struct mhi_controller *mhi_ctrl;
-	struct mhi_controller_config *ath11k_mhi_config;
+	const struct mhi_controller_config *ath11k_mhi_config;
 	int ret;
 
 	mhi_ctrl = mhi_alloc_controller();
@@ -443,6 +443,8 @@
 	case ATH11K_HW_QCA6390_HW20:
 	case ATH11K_HW_WCN6855_HW20:
 	case ATH11K_HW_WCN6855_HW21:
+	case ATH11K_HW_QCA2066_HW21:
+	case ATH11K_HW_QCA6698AQ_HW21:
 		ath11k_mhi_config = &ath11k_mhi_config_qca6390;
 		break;
 	default:
@@ -534,3 +536,8 @@
 
 	return 0;
 }
+
+void ath11k_mhi_coredump(struct mhi_controller *mhi_ctrl, bool in_panic)
+{
+	mhi_download_rddm_image(mhi_ctrl, in_panic);
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/mhi.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/mhi.h
@@ -26,5 +26,5 @@
 
 int ath11k_mhi_suspend(struct ath11k_pci *ar_pci);
 int ath11k_mhi_resume(struct ath11k_pci *ar_pci);
-
+void ath11k_mhi_coredump(struct mhi_controller *mhi_ctrl, bool in_panic);
 #endif
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/pci.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/pci.c
@@ -1,13 +1,15 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/module.h>
 #include <linux/msi.h>
 #include <linux/pci.h>
 #include <linux/of.h>
+#include <linux/time.h>
+#include <linux/vmalloc.h>
 
 #include "pci.h"
 #include "core.h"
@@ -28,6 +30,8 @@
 #define QCN9074_DEVICE_ID		0x1104
 #define WCN6855_DEVICE_ID		0x1103
 
+#define TCSR_SOC_HW_SUB_VER	0x1910010
+
 static const struct pci_device_id ath11k_pci_id_table[] = {
 	{ PCI_VDEVICE(QCOM, QCA6390_DEVICE_ID) },
 	{ PCI_VDEVICE(QCOM, WCN6855_DEVICE_ID) },
@@ -597,6 +601,187 @@
 						   PCI_EXP_LNKCTL_ASPMC);
 }
 
+#ifdef CONFIG_ATH11K_COREDUMP
+static int ath11k_pci_coredump_calculate_size(struct ath11k_base *ab, u32 *dump_seg_sz)
+{
+	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
+	struct mhi_controller *mhi_ctrl = ab_pci->mhi_ctrl;
+	struct image_info *rddm_img, *fw_img;
+	struct ath11k_tlv_dump_data *dump_tlv;
+	enum ath11k_fw_crash_dump_type mem_type;
+	u32 len = 0, rddm_tlv_sz = 0, paging_tlv_sz = 0;
+	struct ath11k_dump_file_data *file_data;
+	int i;
+
+	rddm_img = mhi_ctrl->rddm_image;
+	if (!rddm_img) {
+		ath11k_err(ab, "No RDDM dump found\n");
+		return 0;
+	}
+
+	fw_img = mhi_ctrl->fbc_image;
+
+	for (i = 0; i < fw_img->entries ; i++) {
+		if (!fw_img->mhi_buf[i].buf)
+			continue;
+
+		paging_tlv_sz += fw_img->mhi_buf[i].len;
+	}
+	dump_seg_sz[FW_CRASH_DUMP_PAGING_DATA] = paging_tlv_sz;
+
+	for (i = 0; i < rddm_img->entries; i++) {
+		if (!rddm_img->mhi_buf[i].buf)
+			continue;
+
+		rddm_tlv_sz += rddm_img->mhi_buf[i].len;
+	}
+	dump_seg_sz[FW_CRASH_DUMP_RDDM_DATA] = rddm_tlv_sz;
+
+	for (i = 0; i < ab->qmi.mem_seg_count; i++) {
+		mem_type = ath11k_coredump_get_dump_type(ab->qmi.target_mem[i].type);
+
+		if (mem_type == FW_CRASH_DUMP_NONE)
+			continue;
+
+		if (mem_type == FW_CRASH_DUMP_TYPE_MAX) {
+			ath11k_dbg(ab, ATH11K_DBG_PCI,
+				   "target mem region type %d not supported",
+				   ab->qmi.target_mem[i].type);
+			continue;
+		}
+
+		if (!ab->qmi.target_mem[i].v.iaddr)
+			continue;
+
+		dump_seg_sz[mem_type] += ab->qmi.target_mem[i].size;
+	}
+
+	for (i = 0; i < FW_CRASH_DUMP_TYPE_MAX; i++) {
+		if (!dump_seg_sz[i])
+			continue;
+
+		len += sizeof(*dump_tlv) + dump_seg_sz[i];
+	}
+
+	if (len)
+		len += sizeof(*file_data);
+
+	return len;
+}
+
+static void ath11k_pci_coredump_download(struct ath11k_base *ab)
+{
+	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
+	struct mhi_controller *mhi_ctrl = ab_pci->mhi_ctrl;
+	struct image_info *rddm_img, *fw_img;
+	struct timespec64 timestamp;
+	int i, len, mem_idx;
+	enum ath11k_fw_crash_dump_type mem_type;
+	struct ath11k_dump_file_data *file_data;
+	struct ath11k_tlv_dump_data *dump_tlv;
+	size_t hdr_len = sizeof(*file_data);
+	void *buf;
+	u32 dump_seg_sz[FW_CRASH_DUMP_TYPE_MAX] = { 0 };
+
+	ath11k_mhi_coredump(mhi_ctrl, false);
+
+	len = ath11k_pci_coredump_calculate_size(ab, dump_seg_sz);
+	if (!len) {
+		ath11k_warn(ab, "No crash dump data found for devcoredump");
+		return;
+	}
+
+	rddm_img = mhi_ctrl->rddm_image;
+	fw_img = mhi_ctrl->fbc_image;
+
+	/* dev_coredumpv() requires vmalloc data */
+	buf = vzalloc(len);
+	if (!buf)
+		return;
+
+	ab->dump_data = buf;
+	ab->ath11k_coredump_len = len;
+	file_data = ab->dump_data;
+	strscpy(file_data->df_magic, "ATH11K-FW-DUMP", sizeof(file_data->df_magic));
+	file_data->len = cpu_to_le32(len);
+	file_data->version = cpu_to_le32(ATH11K_FW_CRASH_DUMP_V2);
+	file_data->chip_id = cpu_to_le32(ab_pci->dev_id);
+	file_data->qrtr_id = cpu_to_le32(ab_pci->ab->qmi.service_ins_id);
+	file_data->bus_id = cpu_to_le32(pci_domain_nr(ab_pci->pdev->bus));
+	guid_gen(&file_data->guid);
+	ktime_get_real_ts64(&timestamp);
+	file_data->tv_sec = cpu_to_le64(timestamp.tv_sec);
+	file_data->tv_nsec = cpu_to_le64(timestamp.tv_nsec);
+	buf += hdr_len;
+	dump_tlv = buf;
+	dump_tlv->type = cpu_to_le32(FW_CRASH_DUMP_PAGING_DATA);
+	dump_tlv->tlv_len = cpu_to_le32(dump_seg_sz[FW_CRASH_DUMP_PAGING_DATA]);
+	buf += COREDUMP_TLV_HDR_SIZE;
+
+	/* append all segments together as they are all part of a single contiguous
+	 * block of memory
+	 */
+	for (i = 0; i < fw_img->entries ; i++) {
+		if (!fw_img->mhi_buf[i].buf)
+			continue;
+
+		memcpy_fromio(buf, (void const __iomem *)fw_img->mhi_buf[i].buf,
+			      fw_img->mhi_buf[i].len);
+		buf += fw_img->mhi_buf[i].len;
+	}
+
+	dump_tlv = buf;
+	dump_tlv->type = cpu_to_le32(FW_CRASH_DUMP_RDDM_DATA);
+	dump_tlv->tlv_len = cpu_to_le32(dump_seg_sz[FW_CRASH_DUMP_RDDM_DATA]);
+	buf += COREDUMP_TLV_HDR_SIZE;
+
+	/* append all segments together as they are all part of a single contiguous
+	 * block of memory
+	 */
+	for (i = 0; i < rddm_img->entries; i++) {
+		if (!rddm_img->mhi_buf[i].buf)
+			continue;
+
+		memcpy_fromio(buf, (void const __iomem *)rddm_img->mhi_buf[i].buf,
+			      rddm_img->mhi_buf[i].len);
+		buf += rddm_img->mhi_buf[i].len;
+	}
+
+	mem_idx = FW_CRASH_DUMP_REMOTE_MEM_DATA;
+	for (; mem_idx < FW_CRASH_DUMP_TYPE_MAX; mem_idx++) {
+		if (mem_idx == FW_CRASH_DUMP_NONE)
+			continue;
+
+		for (i = 0; i < ab->qmi.mem_seg_count; i++) {
+			mem_type = ath11k_coredump_get_dump_type
+						(ab->qmi.target_mem[i].type);
+
+			if (mem_type != mem_idx)
+				continue;
+
+			if (!ab->qmi.target_mem[i].v.iaddr) {
+				ath11k_dbg(ab, ATH11K_DBG_PCI,
+					   "Skipping mem region type %d",
+					   ab->qmi.target_mem[i].type);
+				continue;
+			}
+
+			dump_tlv = buf;
+			dump_tlv->type = cpu_to_le32(mem_idx);
+			dump_tlv->tlv_len = cpu_to_le32(dump_seg_sz[mem_idx]);
+			buf += COREDUMP_TLV_HDR_SIZE;
+
+			memcpy_fromio(buf, ab->qmi.target_mem[i].v.iaddr,
+				      ab->qmi.target_mem[i].size);
+
+			buf += ab->qmi.target_mem[i].size;
+		}
+	}
+
+	queue_work(ab->workqueue, &ab->dump_work);
+}
+#endif
+
 static int ath11k_pci_power_up(struct ath11k_base *ab)
 {
 	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab);
@@ -700,6 +885,9 @@
 	.ce_irq_enable = ath11k_pci_hif_ce_irq_enable,
 	.ce_irq_disable = ath11k_pci_hif_ce_irq_disable,
 	.get_ce_msi_idx = ath11k_pcic_get_ce_msi_idx,
+#ifdef CONFIG_ATH11K_COREDUMP
+	.coredump_download = ath11k_pci_coredump_download,
+#endif
 };
 
 static void ath11k_pci_read_hw_version(struct ath11k_base *ab, u32 *major, u32 *minor)
@@ -731,8 +919,8 @@
 	struct ath11k_base *ab;
 	struct ath11k_pci *ab_pci;
 	u32 soc_hw_version_major, soc_hw_version_minor, addr;
-	const struct ath11k_pci_ops *pci_ops;
 	int ret;
+	u32 sub_version;
 
 	ab = ath11k_core_alloc(&pdev->dev, sizeof(*ab_pci), ATH11K_BUS_PCI);
 
@@ -777,6 +965,12 @@
 
 	switch (pci_dev->device) {
 	case QCA6390_DEVICE_ID:
+		ret = ath11k_pcic_register_pci_ops(ab, &ath11k_pci_ops_qca6390);
+		if (ret) {
+			ath11k_err(ab, "failed to register PCI ops: %d\n", ret);
+			goto err_pci_free_region;
+		}
+
 		ath11k_pci_read_hw_version(ab, &soc_hw_version_major,
 					   &soc_hw_version_minor);
 		switch (soc_hw_version_major) {
@@ -790,13 +984,21 @@
 			goto err_pci_free_region;
 		}
 
-		pci_ops = &ath11k_pci_ops_qca6390;
 		break;
 	case QCN9074_DEVICE_ID:
-		pci_ops = &ath11k_pci_ops_qcn9074;
+		ret = ath11k_pcic_register_pci_ops(ab, &ath11k_pci_ops_qcn9074);
+		if (ret) {
+			ath11k_err(ab, "failed to register PCI ops: %d\n", ret);
+			goto err_pci_free_region;
+		}
 		ab->hw_rev = ATH11K_HW_QCN9074_HW10;
 		break;
 	case WCN6855_DEVICE_ID:
+		ret = ath11k_pcic_register_pci_ops(ab, &ath11k_pci_ops_qca6390);
+		if (ret) {
+			ath11k_err(ab, "failed to register PCI ops: %d\n", ret);
+			goto err_pci_free_region;
+		}
 		ab->id.bdf_search = ATH11K_BDF_SEARCH_BUS_AND_BOARD;
 		ath11k_pci_read_hw_version(ab, &soc_hw_version_major,
 					   &soc_hw_version_minor);
@@ -809,7 +1011,23 @@
 				break;
 			case 0x10:
 			case 0x11:
-				ab->hw_rev = ATH11K_HW_WCN6855_HW21;
+				sub_version = ath11k_pcic_read32(ab, TCSR_SOC_HW_SUB_VER);
+				ath11k_dbg(ab, ATH11K_DBG_PCI, "sub_version 0x%x\n",
+					   sub_version);
+				switch (sub_version) {
+				case 0x1019A0E1:
+				case 0x1019B0E1:
+				case 0x1019C0E1:
+				case 0x1019D0E1:
+					ab->hw_rev = ATH11K_HW_QCA2066_HW21;
+					break;
+				case 0x001e60e1:
+				case 0x1016d0e1:
+					ab->hw_rev = ATH11K_HW_QCA6698AQ_HW21;
+					break;
+				default:
+					ab->hw_rev = ATH11K_HW_WCN6855_HW21;
+				}
 				break;
 			default:
 				goto unsupported_wcn6855_soc;
@@ -823,7 +1041,6 @@
 			goto err_pci_free_region;
 		}
 
-		pci_ops = &ath11k_pci_ops_qca6390;
 		break;
 	default:
 		dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n",
@@ -832,12 +1049,6 @@
 		goto err_pci_free_region;
 	}
 
-	ret = ath11k_pcic_register_pci_ops(ab, pci_ops);
-	if (ret) {
-		ath11k_err(ab, "failed to register PCI ops: %d\n", ret);
-		goto err_pci_free_region;
-	}
-
 	ret = ath11k_pcic_init_msi_config(ab);
 	if (ret) {
 		ath11k_err(ab, "failed to init msi config: %d\n", ret);
@@ -946,6 +1157,8 @@
 
 	set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags);
 
+	cancel_work_sync(&ab->reset_work);
+	cancel_work_sync(&ab->dump_work);
 	ath11k_core_deinit(ab);
 
 qmi_fail:
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/pcic.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/pcic.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "core.h"
@@ -115,6 +115,28 @@
 		},
 		.hw_rev = ATH11K_HW_WCN6750_HW10,
 	},
+	{
+		.total_vectors = 32,
+		.total_users = 4,
+		.users = (struct ath11k_msi_user[]) {
+			{ .name = "MHI", .num_vectors = 3, .base_vector = 0 },
+			{ .name = "CE", .num_vectors = 10, .base_vector = 3 },
+			{ .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
+			{ .name = "DP", .num_vectors = 18, .base_vector = 14 },
+		},
+		.hw_rev = ATH11K_HW_QCA2066_HW21,
+	},
+	{
+		.total_vectors = 32,
+		.total_users = 4,
+		.users = (struct ath11k_msi_user[]) {
+			{ .name = "MHI", .num_vectors = 3, .base_vector = 0 },
+			{ .name = "CE", .num_vectors = 10, .base_vector = 3 },
+			{ .name = "WAKE", .num_vectors = 1, .base_vector = 13 },
+			{ .name = "DP", .num_vectors = 18, .base_vector = 14 },
+		},
+		.hw_rev = ATH11K_HW_QCA6698AQ_HW21,
+	},
 };
 
 int ath11k_pcic_init_msi_config(struct ath11k_base *ab)
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/qmi.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/qmi.c
@@ -1955,19 +1955,21 @@
 	int i;
 
 	for (i = 0; i < ab->qmi.mem_seg_count; i++) {
-		if ((ab->hw_params.fixed_mem_region ||
-		     test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) &&
-		     ab->qmi.target_mem[i].iaddr)
-			iounmap(ab->qmi.target_mem[i].iaddr);
+		if (!ab->qmi.target_mem[i].v.iaddr)
+			continue;
 
-		if (!ab->qmi.target_mem[i].vaddr)
+		if (ab->hw_params.fixed_mem_region ||
+		    test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) {
+			iounmap(ab->qmi.target_mem[i].v.iaddr);
+			ab->qmi.target_mem[i].v.iaddr = NULL;
 			continue;
+		}
 
 		dma_free_coherent(ab->dev,
 				  ab->qmi.target_mem[i].prev_size,
-				  ab->qmi.target_mem[i].vaddr,
+				  ab->qmi.target_mem[i].v.vaddr,
 				  ab->qmi.target_mem[i].paddr);
-		ab->qmi.target_mem[i].vaddr = NULL;
+		ab->qmi.target_mem[i].v.vaddr = NULL;
 	}
 }
 
@@ -1984,22 +1986,22 @@
 		/* Firmware reloads in coldboot/firmware recovery.
 		 * in such case, no need to allocate memory for FW again.
 		 */
-		if (chunk->vaddr) {
+		if (chunk->v.vaddr) {
 			if (chunk->prev_type == chunk->type &&
 			    chunk->prev_size == chunk->size)
 				continue;
 
 			/* cannot reuse the existing chunk */
 			dma_free_coherent(ab->dev, chunk->prev_size,
-					  chunk->vaddr, chunk->paddr);
-			chunk->vaddr = NULL;
+					  chunk->v.vaddr, chunk->paddr);
+			chunk->v.vaddr = NULL;
 		}
 
-		chunk->vaddr = dma_alloc_coherent(ab->dev,
-						  chunk->size,
-						  &chunk->paddr,
-						  GFP_KERNEL | __GFP_NOWARN);
-		if (!chunk->vaddr) {
+		chunk->v.vaddr = dma_alloc_coherent(ab->dev,
+						    chunk->size,
+						    &chunk->paddr,
+						    GFP_KERNEL | __GFP_NOWARN);
+		if (!chunk->v.vaddr) {
 			if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) {
 				ath11k_dbg(ab, ATH11K_DBG_QMI,
 					   "dma allocation failed (%d B type %u), will try later with small size\n",
@@ -2055,10 +2057,10 @@
 			}
 
 			ab->qmi.target_mem[idx].paddr = res.start;
-			ab->qmi.target_mem[idx].iaddr =
+			ab->qmi.target_mem[idx].v.iaddr =
 				ioremap(ab->qmi.target_mem[idx].paddr,
 					ab->qmi.target_mem[i].size);
-			if (!ab->qmi.target_mem[idx].iaddr)
+			if (!ab->qmi.target_mem[idx].v.iaddr)
 				return -EIO;
 
 			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
@@ -2068,7 +2070,7 @@
 			break;
 		case BDF_MEM_REGION_TYPE:
 			ab->qmi.target_mem[idx].paddr = ab->hw_params.bdf_addr;
-			ab->qmi.target_mem[idx].vaddr = NULL;
+			ab->qmi.target_mem[idx].v.vaddr = NULL;
 			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
 			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
 			idx++;
@@ -2083,18 +2085,19 @@
 				if (hremote_node) {
 					ab->qmi.target_mem[idx].paddr =
 							res.start + host_ddr_sz;
-					ab->qmi.target_mem[idx].iaddr =
+					ab->qmi.target_mem[idx].v.iaddr =
 						ioremap(ab->qmi.target_mem[idx].paddr,
 							ab->qmi.target_mem[i].size);
-					if (!ab->qmi.target_mem[idx].iaddr)
+					if (!ab->qmi.target_mem[idx].v.iaddr)
 						return -EIO;
 				} else {
 					ab->qmi.target_mem[idx].paddr =
 						ATH11K_QMI_CALDB_ADDRESS;
+					ab->qmi.target_mem[idx].v.vaddr = NULL;
 				}
 			} else {
 				ab->qmi.target_mem[idx].paddr = 0;
-				ab->qmi.target_mem[idx].vaddr = NULL;
+				ab->qmi.target_mem[idx].v.vaddr = NULL;
 			}
 			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
 			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
@@ -2180,6 +2183,9 @@
 	ab->mem = bar_addr_va;
 	ab->mem_len = resp.bar_size;
 
+	if (!ab->hw_params.ce_remap)
+		ab->mem_ce = ab->mem;
+
 	return 0;
 out:
 	return ret;
@@ -2293,7 +2299,7 @@
 	struct qmi_txn txn;
 	const u8 *temp = data;
 	void __iomem *bdf_addr = NULL;
-	int ret;
+	int ret = 0;
 	u32 remaining = len;
 
 	req = kzalloc(sizeof(*req), GFP_KERNEL);
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/qmi.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/qmi.h
@@ -102,8 +102,10 @@
 	u32 prev_size;
 	u32 prev_type;
 	dma_addr_t paddr;
-	u32 *vaddr;
-	void __iomem *iaddr;
+	union {
+		u32 *vaddr;
+		void __iomem *iaddr;
+	} v;
 };
 
 struct target_info {
@@ -154,6 +156,7 @@
 #define BDF_MEM_REGION_TYPE				0x2
 #define M3_DUMP_REGION_TYPE				0x3
 #define CALDB_MEM_REGION_TYPE				0x4
+#define PAGEABLE_MEM_REGION_TYPE			0x9
 
 struct qmi_wlanfw_host_cap_req_msg_v01 {
 	u8 num_clients_valid;
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/reg.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/reg.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 #include <linux/rtnetlink.h>
 
@@ -49,7 +49,6 @@
 {
 	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
 	struct wmi_init_country_params init_country_param;
-	struct wmi_set_current_country_params set_current_param = {};
 	struct ath11k *ar = hw->priv;
 	int ret;
 
@@ -83,9 +82,8 @@
 	 * reg info
 	 */
 	if (ar->ab->hw_params.current_cc_support) {
-		memcpy(&set_current_param.alpha2, request->alpha2, 2);
-		memcpy(&ar->alpha2, &set_current_param.alpha2, 2);
-		ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
+		memcpy(&ar->alpha2, request->alpha2, 2);
+		ret = ath11k_reg_set_cc(ar);
 		if (ret)
 			ath11k_warn(ar->ab,
 				    "failed set current country code: %d\n", ret);
@@ -425,6 +423,11 @@
 	/* Use the flags of both the rules */
 	new_rule->flags = rule1->flags | rule2->flags;
 
+	if ((rule1->flags & NL80211_RRF_PSD) && (rule2->flags & NL80211_RRF_PSD))
+		new_rule->psd = min_t(s8, rule1->psd, rule2->psd);
+	else
+		new_rule->flags &= ~NL80211_RRF_PSD;
+
 	/* To be safe, lts use the max cac timeout of both rules */
 	new_rule->dfs_cac_ms = max_t(u32, rule1->dfs_cac_ms,
 				     rule2->dfs_cac_ms);
@@ -527,13 +530,14 @@
 static void
 ath11k_reg_update_rule(struct ieee80211_reg_rule *reg_rule, u32 start_freq,
 		       u32 end_freq, u32 bw, u32 ant_gain, u32 reg_pwr,
-		       u32 reg_flags)
+		       s8 psd, u32 reg_flags)
 {
 	reg_rule->freq_range.start_freq_khz = MHZ_TO_KHZ(start_freq);
 	reg_rule->freq_range.end_freq_khz = MHZ_TO_KHZ(end_freq);
 	reg_rule->freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw);
 	reg_rule->power_rule.max_antenna_gain = DBI_TO_MBI(ant_gain);
 	reg_rule->power_rule.max_eirp = DBM_TO_MBM(reg_pwr);
+	reg_rule->psd = psd;
 	reg_rule->flags = reg_flags;
 }
 
@@ -563,7 +567,7 @@
 				       reg_rule->start_freq,
 				       ETSI_WEATHER_RADAR_BAND_LOW, bw,
 				       reg_rule->ant_gain, reg_rule->reg_power,
-				       flags);
+				       reg_rule->psd_eirp, flags);
 
 		ath11k_dbg(ab, ATH11K_DBG_REG,
 			   "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
@@ -584,7 +588,7 @@
 
 		ath11k_reg_update_rule(regd->reg_rules + i, start_freq,
 				       end_freq, bw, reg_rule->ant_gain,
-				       reg_rule->reg_power, flags);
+				       reg_rule->reg_power, reg_rule->psd_eirp, flags);
 
 		regd->reg_rules[i].dfs_cac_ms = ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT;
 
@@ -605,7 +609,7 @@
 				       ETSI_WEATHER_RADAR_BAND_HIGH,
 				       reg_rule->end_freq, bw,
 				       reg_rule->ant_gain, reg_rule->reg_power,
-				       flags);
+				       reg_rule->psd_eirp, flags);
 
 		ath11k_dbg(ab, ATH11K_DBG_REG,
 			   "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n",
@@ -618,25 +622,68 @@
 	*rule_idx = i;
 }
 
+enum wmi_reg_6ghz_ap_type
+ath11k_reg_ap_pwr_convert(enum ieee80211_ap_reg_power power_type)
+{
+	switch (power_type) {
+	case IEEE80211_REG_LPI_AP:
+		return WMI_REG_INDOOR_AP;
+	case IEEE80211_REG_SP_AP:
+		return WMI_REG_STANDARD_POWER_AP;
+	case IEEE80211_REG_VLP_AP:
+		return WMI_REG_VERY_LOW_POWER_AP;
+	default:
+		return WMI_REG_MAX_AP_TYPE;
+	}
+}
+
 struct ieee80211_regdomain *
 ath11k_reg_build_regd(struct ath11k_base *ab,
-		      struct cur_regulatory_info *reg_info, bool intersect)
+		      struct cur_regulatory_info *reg_info, bool intersect,
+		      enum wmi_vdev_type vdev_type,
+		      enum ieee80211_ap_reg_power power_type)
 {
 	struct ieee80211_regdomain *tmp_regd, *default_regd, *new_regd = NULL;
-	struct cur_reg_rule *reg_rule;
+	struct cur_reg_rule *reg_rule, *reg_rule_6ghz;
 	u8 i = 0, j = 0, k = 0;
 	u8 num_rules;
 	u16 max_bw;
-	u32 flags;
+	u32 flags, reg_6ghz_number, max_bw_6ghz;
 	char alpha2[3];
 
 	num_rules = reg_info->num_5ghz_reg_rules + reg_info->num_2ghz_reg_rules;
 
-	/* FIXME: Currently taking reg rules for 6 GHz only from Indoor AP mode list.
-	 * This can be updated after complete 6 GHz regulatory support is added.
-	 */
-	if (reg_info->is_ext_reg_event)
-		num_rules += reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP];
+	if (reg_info->is_ext_reg_event) {
+		if (vdev_type == WMI_VDEV_TYPE_STA) {
+			enum wmi_reg_6ghz_ap_type ap_type;
+
+			ap_type = ath11k_reg_ap_pwr_convert(power_type);
+
+			if (ap_type == WMI_REG_MAX_AP_TYPE)
+				ap_type = WMI_REG_INDOOR_AP;
+
+			reg_6ghz_number = reg_info->num_6ghz_rules_client
+					[ap_type][WMI_REG_DEFAULT_CLIENT];
+
+			if (reg_6ghz_number == 0) {
+				ap_type = WMI_REG_INDOOR_AP;
+				reg_6ghz_number = reg_info->num_6ghz_rules_client
+						[ap_type][WMI_REG_DEFAULT_CLIENT];
+			}
+
+			reg_rule_6ghz = reg_info->reg_rules_6ghz_client_ptr
+					[ap_type][WMI_REG_DEFAULT_CLIENT];
+			max_bw_6ghz = reg_info->max_bw_6ghz_client
+					[ap_type][WMI_REG_DEFAULT_CLIENT];
+		} else {
+			reg_6ghz_number = reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP];
+			reg_rule_6ghz =
+				reg_info->reg_rules_6ghz_ap_ptr[WMI_REG_INDOOR_AP];
+			max_bw_6ghz = reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP];
+		}
+
+		num_rules += reg_6ghz_number;
+	}
 
 	if (!num_rules)
 		goto ret;
@@ -683,14 +730,13 @@
 			 * per other BW rule flags we pass from here
 			 */
 			flags = NL80211_RRF_AUTO_BW;
-		} else if (reg_info->is_ext_reg_event &&
-			   reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP] &&
-			   (k < reg_info->num_6ghz_rules_ap[WMI_REG_INDOOR_AP])) {
-			reg_rule = reg_info->reg_rules_6ghz_ap_ptr[WMI_REG_INDOOR_AP] +
-				   k++;
-			max_bw = min_t(u16, reg_rule->max_bw,
-				       reg_info->max_bw_6ghz_ap[WMI_REG_INDOOR_AP]);
+		} else if (reg_info->is_ext_reg_event && reg_6ghz_number &&
+			   k < reg_6ghz_number) {
+			reg_rule = reg_rule_6ghz + k++;
+			max_bw = min_t(u16, reg_rule->max_bw, max_bw_6ghz);
 			flags = NL80211_RRF_AUTO_BW;
+			if (reg_rule->psd_flag)
+				flags |= NL80211_RRF_PSD;
 		} else {
 			break;
 		}
@@ -702,7 +748,7 @@
 				       reg_rule->start_freq,
 				       reg_rule->end_freq, max_bw,
 				       reg_rule->ant_gain, reg_rule->reg_power,
-				       flags);
+				       reg_rule->psd_eirp, flags);
 
 		/* Update dfs cac timeout if the dfs domain is ETSI and the
 		 * new rule covers weather radar band.
@@ -758,6 +804,159 @@
 	return new_regd;
 }
 
+static bool ath11k_reg_is_world_alpha(char *alpha)
+{
+	if (alpha[0] == '0' && alpha[1] == '0')
+		return true;
+
+	if (alpha[0] == 'n' && alpha[1] == 'a')
+		return true;
+
+	return false;
+}
+
+static enum wmi_vdev_type ath11k_reg_get_ar_vdev_type(struct ath11k *ar)
+{
+	struct ath11k_vif *arvif;
+
+	/* Currently each struct ath11k maps to one struct ieee80211_hw/wiphy
+	 * and one struct ieee80211_regdomain, so it could only store one group
+	 * reg rules. It means multi-interface concurrency in the same ath11k is
+	 * not support for the regdomain. So get the vdev type of the first entry
+	 * now. After concurrency support for the regdomain, this should change.
+	 */
+	arvif = list_first_entry_or_null(&ar->arvifs, struct ath11k_vif, list);
+	if (arvif)
+		return arvif->vdev_type;
+
+	return WMI_VDEV_TYPE_UNSPEC;
+}
+
+int ath11k_reg_handle_chan_list(struct ath11k_base *ab,
+				struct cur_regulatory_info *reg_info,
+				enum ieee80211_ap_reg_power power_type)
+{
+	struct ieee80211_regdomain *regd;
+	bool intersect = false;
+	int pdev_idx;
+	struct ath11k *ar;
+	enum wmi_vdev_type vdev_type;
+
+	ath11k_dbg(ab, ATH11K_DBG_WMI, "event reg handle chan list");
+
+	if (reg_info->status_code != REG_SET_CC_STATUS_PASS) {
+		/* In case of failure to set the requested ctry,
+		 * fw retains the current regd. We print a failure info
+		 * and return from here.
+		 */
+		ath11k_warn(ab, "Failed to set the requested Country regulatory setting\n");
+		return -EINVAL;
+	}
+
+	pdev_idx = reg_info->phy_id;
+
+	/* Avoid default reg rule updates sent during FW recovery if
+	 * it is already available
+	 */
+	spin_lock_bh(&ab->base_lock);
+	if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags) &&
+	    ab->default_regd[pdev_idx]) {
+		spin_unlock_bh(&ab->base_lock);
+		goto retfail;
+	}
+	spin_unlock_bh(&ab->base_lock);
+
+	if (pdev_idx >= ab->num_radios) {
+		/* Process the event for phy0 only if single_pdev_only
+		 * is true. If pdev_idx is valid but not 0, discard the
+		 * event. Otherwise, it goes to fallback. In either case
+		 * ath11k_reg_reset_info() needs to be called to avoid
+		 * memory leak issue.
+		 */
+		ath11k_reg_reset_info(reg_info);
+
+		if (ab->hw_params.single_pdev_only &&
+		    pdev_idx < ab->hw_params.num_rxdma_per_pdev)
+			return 0;
+		goto fallback;
+	}
+
+	/* Avoid multiple overwrites to default regd, during core
+	 * stop-start after mac registration.
+	 */
+	if (ab->default_regd[pdev_idx] && !ab->new_regd[pdev_idx] &&
+	    !memcmp((char *)ab->default_regd[pdev_idx]->alpha2,
+		    (char *)reg_info->alpha2, 2))
+		goto retfail;
+
+	/* Intersect new rules with default regd if a new country setting was
+	 * requested, i.e a default regd was already set during initialization
+	 * and the regd coming from this event has a valid country info.
+	 */
+	if (ab->default_regd[pdev_idx] &&
+	    !ath11k_reg_is_world_alpha((char *)
+		ab->default_regd[pdev_idx]->alpha2) &&
+	    !ath11k_reg_is_world_alpha((char *)reg_info->alpha2))
+		intersect = true;
+
+	ar = ab->pdevs[pdev_idx].ar;
+	vdev_type = ath11k_reg_get_ar_vdev_type(ar);
+
+	ath11k_dbg(ab, ATH11K_DBG_WMI,
+		   "wmi handle chan list power type %d vdev type %d intersect %d\n",
+		   power_type, vdev_type, intersect);
+
+	regd = ath11k_reg_build_regd(ab, reg_info, intersect, vdev_type, power_type);
+	if (!regd) {
+		ath11k_warn(ab, "failed to build regd from reg_info\n");
+		goto fallback;
+	}
+
+	if (power_type == IEEE80211_REG_UNSET_AP) {
+		ath11k_reg_reset_info(&ab->reg_info_store[pdev_idx]);
+		ab->reg_info_store[pdev_idx] = *reg_info;
+	}
+
+	spin_lock_bh(&ab->base_lock);
+	if (ab->default_regd[pdev_idx]) {
+		/* The initial rules from FW after WMI Init is to build
+		 * the default regd. From then on, any rules updated for
+		 * the pdev could be due to user reg changes.
+		 * Free previously built regd before assigning the newly
+		 * generated regd to ar. NULL pointer handling will be
+		 * taken care by kfree itself.
+		 */
+		ar = ab->pdevs[pdev_idx].ar;
+		kfree(ab->new_regd[pdev_idx]);
+		ab->new_regd[pdev_idx] = regd;
+		queue_work(ab->workqueue, &ar->regd_update_work);
+	} else {
+		/* This regd would be applied during mac registration and is
+		 * held constant throughout for regd intersection purpose
+		 */
+		ab->default_regd[pdev_idx] = regd;
+	}
+	ab->dfs_region = reg_info->dfs_region;
+	spin_unlock_bh(&ab->base_lock);
+
+	return 0;
+
+fallback:
+	/* Fallback to older reg (by sending previous country setting
+	 * again if fw has succeeded and we failed to process here.
+	 * The Regdomain should be uniform across driver and fw. Since the
+	 * FW has processed the command and sent a success status, we expect
+	 * this function to succeed as well. If it doesn't, CTRY needs to be
+	 * reverted at the fw and the old SCAN_CHAN_LIST cmd needs to be sent.
+	 */
+	/* TODO: This is rare, but still should also be handled */
+	WARN_ON(1);
+
+retfail:
+
+	return -EINVAL;
+}
+
 void ath11k_regd_update_work(struct work_struct *work)
 {
 	struct ath11k *ar = container_of(work, struct ath11k,
@@ -781,12 +980,46 @@
 	ar->hw->wiphy->reg_notifier = ath11k_reg_notifier;
 }
 
+void ath11k_reg_reset_info(struct cur_regulatory_info *reg_info)
+{
+	int i, j;
+
+	if (!reg_info)
+		return;
+
+	kfree(reg_info->reg_rules_2ghz_ptr);
+	kfree(reg_info->reg_rules_5ghz_ptr);
+
+	for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++) {
+		kfree(reg_info->reg_rules_6ghz_ap_ptr[i]);
+
+		for (j = 0; j < WMI_REG_MAX_CLIENT_TYPE; j++)
+			kfree(reg_info->reg_rules_6ghz_client_ptr[i][j]);
+	}
+
+	memset(reg_info, 0, sizeof(*reg_info));
+}
+
 void ath11k_reg_free(struct ath11k_base *ab)
 {
 	int i;
 
+	for (i = 0; i < ab->num_radios; i++)
+		ath11k_reg_reset_info(&ab->reg_info_store[i]);
+
+	kfree(ab->reg_info_store);
+	ab->reg_info_store = NULL;
+
 	for (i = 0; i < ab->hw_params.max_radios; i++) {
 		kfree(ab->default_regd[i]);
 		kfree(ab->new_regd[i]);
 	}
 }
+
+int ath11k_reg_set_cc(struct ath11k *ar)
+{
+	struct wmi_set_current_country_params set_current_param = {};
+
+	memcpy(&set_current_param.alpha2, ar->alpha2, 2);
+	return ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/reg.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/reg.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 /*
  * Copyright (c) 2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef ATH11K_REG_H
@@ -30,11 +30,20 @@
 
 /* ATH11K Regulatory API's */
 void ath11k_reg_init(struct ath11k *ar);
+void ath11k_reg_reset_info(struct cur_regulatory_info *reg_info);
 void ath11k_reg_free(struct ath11k_base *ab);
 void ath11k_regd_update_work(struct work_struct *work);
 struct ieee80211_regdomain *
 ath11k_reg_build_regd(struct ath11k_base *ab,
-		      struct cur_regulatory_info *reg_info, bool intersect);
+		      struct cur_regulatory_info *reg_info, bool intersect,
+		      enum wmi_vdev_type vdev_type,
+		      enum ieee80211_ap_reg_power power_type);
 int ath11k_regd_update(struct ath11k *ar);
 int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait);
+enum wmi_reg_6ghz_ap_type
+ath11k_reg_ap_pwr_convert(enum ieee80211_ap_reg_power power_type);
+int ath11k_reg_handle_chan_list(struct ath11k_base *ab,
+				struct cur_regulatory_info *reg_info,
+				enum ieee80211_ap_reg_power power_type);
+int ath11k_reg_set_cc(struct ath11k *ar);
 #endif
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/wmi.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/wmi.c
@@ -2554,7 +2554,7 @@
 }
 
 int ath11k_wmi_send_wmm_update_cmd_tlv(struct ath11k *ar, u32 vdev_id,
-				       struct wmi_wmm_params_all_arg *param)
+				       struct wmi_wmm_params_all_arg *param, u32 wmm_param_type)
 {
 	struct ath11k_pdev_wmi *wmi = ar->wmi;
 	struct wmi_vdev_set_wmm_params_cmd *cmd;
@@ -2573,7 +2573,7 @@
 			  FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
 
 	cmd->vdev_id = vdev_id;
-	cmd->wmm_param_type = 0;
+	cmd->wmm_param_type = wmm_param_type;
 
 	for (ac = 0; ac < WME_NUM_AC; ac++) {
 		switch (ac) {
@@ -2606,8 +2606,8 @@
 		wmm_param->no_ack = wmi_wmm_arg->no_ack;
 
 		ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
-			   "wmm set ac %d aifs %d cwmin %d cwmax %d txop %d acm %d no_ack %d\n",
-			   ac, wmm_param->aifs, wmm_param->cwmin,
+			   "wmm set type %d ac %d aifs %d cwmin %d cwmax %d txop %d acm %d no_ack %d\n",
+			   wmm_param_type, ac, wmm_param->aifs, wmm_param->cwmin,
 			   wmm_param->cwmax, wmm_param->txoplimit,
 			   wmm_param->acm, wmm_param->no_ack);
 	}
@@ -4749,6 +4749,14 @@
 		soc->pdevs[0].pdev_id = 0;
 	}
 
+	if (!soc->reg_info_store) {
+		soc->reg_info_store = kcalloc(soc->num_radios,
+					      sizeof(*soc->reg_info_store),
+					      GFP_ATOMIC);
+		if (!soc->reg_info_store)
+			return -ENOMEM;
+	}
+
 	return 0;
 }
 
@@ -7060,32 +7068,15 @@
 		wake_up(&wmi->tx_ce_desc_wq);
 }
 
-static bool ath11k_reg_is_world_alpha(char *alpha)
-{
-	if (alpha[0] == '0' && alpha[1] == '0')
-		return true;
-
-	if (alpha[0] == 'n' && alpha[1] == 'a')
-		return true;
-
-	return false;
-}
-
-static int ath11k_reg_chan_list_event(struct ath11k_base *ab,
-				      struct sk_buff *skb,
+static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *skb,
 				      enum wmi_reg_chan_list_cmd_type id)
 {
-	struct cur_regulatory_info *reg_info = NULL;
-	struct ieee80211_regdomain *regd = NULL;
-	bool intersect = false;
-	int ret = 0, pdev_idx, i, j;
-	struct ath11k *ar;
+	struct cur_regulatory_info *reg_info;
+	int ret;
 
 	reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC);
-	if (!reg_info) {
-		ret = -ENOMEM;
-		goto fallback;
-	}
+	if (!reg_info)
+		return -ENOMEM;
 
 	if (id == WMI_REG_CHAN_LIST_CC_ID)
 		ret = ath11k_pull_reg_chan_list_update_ev(ab, skb, reg_info);
@@ -7093,118 +7084,22 @@
 		ret = ath11k_pull_reg_chan_list_ext_update_ev(ab, skb, reg_info);
 
 	if (ret) {
-		ath11k_warn(ab, "failed to extract regulatory info from received event\n");
-		goto fallback;
-	}
-
-	ath11k_dbg(ab, ATH11K_DBG_WMI, "event reg chan list id %d", id);
-
-	if (reg_info->status_code != REG_SET_CC_STATUS_PASS) {
-		/* In case of failure to set the requested ctry,
-		 * fw retains the current regd. We print a failure info
-		 * and return from here.
-		 */
-		ath11k_warn(ab, "Failed to set the requested Country regulatory setting\n");
-		goto mem_free;
-	}
-
-	pdev_idx = reg_info->phy_id;
-
-	/* Avoid default reg rule updates sent during FW recovery if
-	 * it is already available
-	 */
-	spin_lock(&ab->base_lock);
-	if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags) &&
-	    ab->default_regd[pdev_idx]) {
-		spin_unlock(&ab->base_lock);
+		ath11k_warn(ab, "failed to extract regulatory info\n");
 		goto mem_free;
 	}
-	spin_unlock(&ab->base_lock);
 
-	if (pdev_idx >= ab->num_radios) {
-		/* Process the event for phy0 only if single_pdev_only
-		 * is true. If pdev_idx is valid but not 0, discard the
-		 * event. Otherwise, it goes to fallback.
-		 */
-		if (ab->hw_params.single_pdev_only &&
-		    pdev_idx < ab->hw_params.num_rxmda_per_pdev)
-			goto mem_free;
-		else
-			goto fallback;
-	}
-
-	/* Avoid multiple overwrites to default regd, during core
-	 * stop-start after mac registration.
-	 */
-	if (ab->default_regd[pdev_idx] && !ab->new_regd[pdev_idx] &&
-	    !memcmp((char *)ab->default_regd[pdev_idx]->alpha2,
-		    (char *)reg_info->alpha2, 2))
+	ret = ath11k_reg_handle_chan_list(ab, reg_info, IEEE80211_REG_UNSET_AP);
+	if (ret) {
+		ath11k_warn(ab, "failed to process regulatory info %d\n", ret);
 		goto mem_free;
-
-	/* Intersect new rules with default regd if a new country setting was
-	 * requested, i.e a default regd was already set during initialization
-	 * and the regd coming from this event has a valid country info.
-	 */
-	if (ab->default_regd[pdev_idx] &&
-	    !ath11k_reg_is_world_alpha((char *)
-		ab->default_regd[pdev_idx]->alpha2) &&
-	    !ath11k_reg_is_world_alpha((char *)reg_info->alpha2))
-		intersect = true;
-
-	regd = ath11k_reg_build_regd(ab, reg_info, intersect);
-	if (!regd) {
-		ath11k_warn(ab, "failed to build regd from reg_info\n");
-		goto fallback;
-	}
-
-	spin_lock(&ab->base_lock);
-	if (ab->default_regd[pdev_idx]) {
-		/* The initial rules from FW after WMI Init is to build
-		 * the default regd. From then on, any rules updated for
-		 * the pdev could be due to user reg changes.
-		 * Free previously built regd before assigning the newly
-		 * generated regd to ar. NULL pointer handling will be
-		 * taken care by kfree itself.
-		 */
-		ar = ab->pdevs[pdev_idx].ar;
-		kfree(ab->new_regd[pdev_idx]);
-		ab->new_regd[pdev_idx] = regd;
-		queue_work(ab->workqueue, &ar->regd_update_work);
-	} else {
-		/* This regd would be applied during mac registration and is
-		 * held constant throughout for regd intersection purpose
-		 */
-		ab->default_regd[pdev_idx] = regd;
 	}
-	ab->dfs_region = reg_info->dfs_region;
-	spin_unlock(&ab->base_lock);
 
-	goto mem_free;
+	kfree(reg_info);
+	return 0;
 
-fallback:
-	/* Fallback to older reg (by sending previous country setting
-	 * again if fw has succeeded and we failed to process here.
-	 * The Regdomain should be uniform across driver and fw. Since the
-	 * FW has processed the command and sent a success status, we expect
-	 * this function to succeed as well. If it doesn't, CTRY needs to be
-	 * reverted at the fw and the old SCAN_CHAN_LIST cmd needs to be sent.
-	 */
-	/* TODO: This is rare, but still should also be handled */
-	WARN_ON(1);
 mem_free:
-	if (reg_info) {
-		kfree(reg_info->reg_rules_2ghz_ptr);
-		kfree(reg_info->reg_rules_5ghz_ptr);
-		if (reg_info->is_ext_reg_event) {
-			for (i = 0; i < WMI_REG_CURRENT_MAX_AP_TYPE; i++)
-				kfree(reg_info->reg_rules_6ghz_ap_ptr[i]);
-
-			for (j = 0; j < WMI_REG_CURRENT_MAX_AP_TYPE; j++)
-				for (i = 0; i < WMI_REG_MAX_CLIENT_TYPE; i++)
-					kfree(reg_info->reg_rules_6ghz_client_ptr[j][i]);
-		}
-		kfree(reg_info);
-	}
+	ath11k_reg_reset_info(reg_info);
+	kfree(reg_info);
 	return ret;
 }
 
@@ -7400,7 +7295,9 @@
 		rcu_read_unlock();
 		return;
 	}
-	ath11k_mac_bcn_tx_event(arvif);
+
+	queue_work(ab->workqueue, &arvif->bcn_tx_work);
+
 	rcu_read_unlock();
 }
 
@@ -9023,7 +8920,7 @@
 	ab->wmi_ab.preferred_hw_mode = WMI_HOST_HW_MODE_MAX;
 
 	/* It's overwritten when service_ext_ready is handled */
-	if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxmda_per_pdev > 1)
+	if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxdma_per_pdev > 1)
 		ab->wmi_ab.preferred_hw_mode = WMI_HOST_HW_MODE_SINGLE;
 
 	/* TODO: Init remaining wmi soc resources required */
@@ -9793,3 +9690,9 @@
 
 	return ath11k_wmi_cmd_send(wmi, skb, WMI_STA_KEEPALIVE_CMDID);
 }
+
+bool ath11k_wmi_supports_6ghz_cc_ext(struct ath11k *ar)
+{
+	return test_bit(WMI_TLV_SERVICE_REG_CC_EXT_EVENT_SUPPORT,
+			ar->ab->wmi_ab.svc_map) && ar->supports_6ghz;
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath11k/wmi.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath11k/wmi.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 /*
  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef ATH11K_WMI_H
@@ -3399,34 +3399,6 @@
 	const u8 *bssid;
 };
 
-struct wmi_start_scan_arg {
-	u32 scan_id;
-	u32 scan_req_id;
-	u32 vdev_id;
-	u32 scan_priority;
-	u32 notify_scan_events;
-	u32 dwell_time_active;
-	u32 dwell_time_passive;
-	u32 min_rest_time;
-	u32 max_rest_time;
-	u32 repeat_probe_time;
-	u32 probe_spacing_time;
-	u32 idle_time;
-	u32 max_scan_time;
-	u32 probe_delay;
-	u32 scan_ctrl_flags;
-
-	u32 ie_len;
-	u32 n_channels;
-	u32 n_ssids;
-	u32 n_bssids;
-
-	u8 ie[WLAN_SCAN_PARAMS_MAX_IE_LEN];
-	u32 channels[64];
-	struct wmi_ssid_arg ssids[WLAN_SCAN_PARAMS_MAX_SSID];
-	struct wmi_bssid_arg bssids[WLAN_SCAN_PARAMS_MAX_BSSID];
-};
-
 #define WMI_SCAN_STOP_ONE       0x00000000
 #define WMI_SCN_STOP_VAP_ALL    0x01000000
 #define WMI_SCAN_STOP_ALL       0x04000000
@@ -4951,6 +4923,7 @@
 };
 
 enum wmi_vdev_type {
+	WMI_VDEV_TYPE_UNSPEC =  0,
 	WMI_VDEV_TYPE_AP      = 1,
 	WMI_VDEV_TYPE_STA     = 2,
 	WMI_VDEV_TYPE_IBSS    = 3,
@@ -6295,6 +6268,11 @@
 #define WMI_STA_KEEPALIVE_INTERVAL_DEFAULT	30
 #define WMI_STA_KEEPALIVE_INTERVAL_DISABLE	0
 
+enum wmm_edca_params_type {
+	WMM_PARAM_TYPE_LEGACY = 0,
+	WMM_PARAM_TYPE_11AX_MU_EDCA = 1,
+};
+
 const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void *ptr,
 					size_t len, gfp_t gfp);
 int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb,
@@ -6349,7 +6327,7 @@
 int ath11k_wmi_send_scan_stop_cmd(struct ath11k *ar,
 				  struct scan_cancel_param *param);
 int ath11k_wmi_send_wmm_update_cmd_tlv(struct ath11k *ar, u32 vdev_id,
-				       struct wmi_wmm_params_all_arg *param);
+				       struct wmi_wmm_params_all_arg *param, u32 wmm_param_type);
 int ath11k_wmi_pdev_suspend(struct ath11k *ar, u32 suspend_opt,
 			    u32 pdev_id);
 int ath11k_wmi_pdev_resume(struct ath11k *ar, u32 pdev_id);
@@ -6479,5 +6457,6 @@
 int ath11k_wmi_pdev_set_bios_geo_table_param(struct ath11k *ar);
 int ath11k_wmi_sta_keepalive(struct ath11k *ar,
 			     const struct wmi_sta_keepalive_arg *arg);
+bool ath11k_wmi_supports_6ghz_cc_ext(struct ath11k *ar);
 
 #endif
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/Makefile
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/Makefile
@@ -19,7 +19,8 @@
 	    hw.o \
 	    mhi.o \
 	    pci.o \
-	    dp_mon.o
+	    dp_mon.o \
+	    fw.o
 
 ath12k-$(CONFIG_ATH12K_TRACING) += trace.o
 
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/ce.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/ce.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-3-Clause-Clear */
 /*
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef ATH12K_CE_H
@@ -119,7 +119,7 @@
 	/* Host address space */
 	void *base_addr_owner_space_unaligned;
 	/* CE address space */
-	u32 base_addr_ce_space_unaligned;
+	dma_addr_t base_addr_ce_space_unaligned;
 
 	/* Actual start of descriptors.
 	 * Aligned to descriptor-size boundary.
@@ -129,7 +129,7 @@
 	void *base_addr_owner_space;
 
 	/* CE address space */
-	u32 base_addr_ce_space;
+	dma_addr_t base_addr_ce_space;
 
 	/* HAL ring id */
 	u32 hal_ring_id;
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/core.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/core.c
@@ -14,6 +14,7 @@
 #include "dp_rx.h"
 #include "debug.h"
 #include "hif.h"
+#include "fw.h"
 
 unsigned int ath12k_debug_mask;
 module_param_named(debug_mask, ath12k_debug_mask, uint, 0644);
@@ -104,27 +105,66 @@
 	return 0;
 }
 
-static int ath12k_core_create_board_name(struct ath12k_base *ab, char *name,
-					 size_t name_len)
+static int __ath12k_core_create_board_name(struct ath12k_base *ab, char *name,
+					   size_t name_len, bool with_variant,
+					   bool bus_type_mode)
 {
 	/* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */
 	char variant[9 + ATH12K_QMI_BDF_EXT_STR_LENGTH] = { 0 };
 
-	if (ab->qmi.target.bdf_ext[0] != '\0')
+	if (with_variant && ab->qmi.target.bdf_ext[0] != '\0')
 		scnprintf(variant, sizeof(variant), ",variant=%s",
 			  ab->qmi.target.bdf_ext);
 
-	scnprintf(name, name_len,
-		  "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
-		  ath12k_bus_str(ab->hif.bus),
-		  ab->qmi.target.chip_id,
-		  ab->qmi.target.board_id, variant);
+	switch (ab->id.bdf_search) {
+	case ATH12K_BDF_SEARCH_BUS_AND_BOARD:
+		if (bus_type_mode)
+			scnprintf(name, name_len,
+				  "bus=%s",
+				  ath12k_bus_str(ab->hif.bus));
+		else
+			scnprintf(name, name_len,
+				  "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s",
+				  ath12k_bus_str(ab->hif.bus),
+				  ab->id.vendor, ab->id.device,
+				  ab->id.subsystem_vendor,
+				  ab->id.subsystem_device,
+				  ab->qmi.target.chip_id,
+				  ab->qmi.target.board_id,
+				  variant);
+		break;
+	default:
+		scnprintf(name, name_len,
+			  "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
+			  ath12k_bus_str(ab->hif.bus),
+			  ab->qmi.target.chip_id,
+			  ab->qmi.target.board_id, variant);
+		break;
+	}
 
 	ath12k_dbg(ab, ATH12K_DBG_BOOT, "boot using board name '%s'\n", name);
 
 	return 0;
 }
 
+static int ath12k_core_create_board_name(struct ath12k_base *ab, char *name,
+					 size_t name_len)
+{
+	return __ath12k_core_create_board_name(ab, name, name_len, true, false);
+}
+
+static int ath12k_core_create_fallback_board_name(struct ath12k_base *ab, char *name,
+						  size_t name_len)
+{
+	return __ath12k_core_create_board_name(ab, name, name_len, false, false);
+}
+
+static int ath12k_core_create_bus_type_board_name(struct ath12k_base *ab, char *name,
+						  size_t name_len)
+{
+	return __ath12k_core_create_board_name(ab, name, name_len, false, true);
+}
+
 const struct firmware *ath12k_core_firmware_request(struct ath12k_base *ab,
 						    const char *file)
 {
@@ -159,7 +199,9 @@
 					 struct ath12k_board_data *bd,
 					 const void *buf, size_t buf_len,
 					 const char *boardname,
-					 int bd_ie_type)
+					 int ie_id,
+					 int name_id,
+					 int data_id)
 {
 	const struct ath12k_fw_ie *hdr;
 	bool name_match_found;
@@ -169,7 +211,7 @@
 
 	name_match_found = false;
 
-	/* go through ATH12K_BD_IE_BOARD_ elements */
+	/* go through ATH12K_BD_IE_BOARD_/ATH12K_BD_IE_REGDB_ elements */
 	while (buf_len > sizeof(struct ath12k_fw_ie)) {
 		hdr = buf;
 		board_ie_id = le32_to_cpu(hdr->id);
@@ -180,48 +222,50 @@
 		buf += sizeof(*hdr);
 
 		if (buf_len < ALIGN(board_ie_len, 4)) {
-			ath12k_err(ab, "invalid ATH12K_BD_IE_BOARD length: %zu < %zu\n",
+			ath12k_err(ab, "invalid %s length: %zu < %zu\n",
+				   ath12k_bd_ie_type_str(ie_id),
 				   buf_len, ALIGN(board_ie_len, 4));
 			ret = -EINVAL;
 			goto out;
 		}
 
-		switch (board_ie_id) {
-		case ATH12K_BD_IE_BOARD_NAME:
+		if (board_ie_id == name_id) {
 			ath12k_dbg_dump(ab, ATH12K_DBG_BOOT, "board name", "",
 					board_ie_data, board_ie_len);
 
 			if (board_ie_len != strlen(boardname))
-				break;
+				goto next;
 
 			ret = memcmp(board_ie_data, boardname, strlen(boardname));
 			if (ret)
-				break;
+				goto next;
 
 			name_match_found = true;
 			ath12k_dbg(ab, ATH12K_DBG_BOOT,
-				   "boot found match for name '%s'",
+				   "boot found match %s for name '%s'",
+				   ath12k_bd_ie_type_str(ie_id),
 				   boardname);
-			break;
-		case ATH12K_BD_IE_BOARD_DATA:
+		} else if (board_ie_id == data_id) {
 			if (!name_match_found)
 				/* no match found */
-				break;
+				goto next;
 
 			ath12k_dbg(ab, ATH12K_DBG_BOOT,
-				   "boot found board data for '%s'", boardname);
+				   "boot found %s for '%s'",
+				   ath12k_bd_ie_type_str(ie_id),
+				   boardname);
 
 			bd->data = board_ie_data;
 			bd->len = board_ie_len;
 
 			ret = 0;
 			goto out;
-		default:
-			ath12k_warn(ab, "unknown ATH12K_BD_IE_BOARD found: %d\n",
+		} else {
+			ath12k_warn(ab, "unknown %s id found: %d\n",
+				    ath12k_bd_ie_type_str(ie_id),
 				    board_ie_id);
-			break;
 		}
-
+next:
 		/* jump over the padding */
 		board_ie_len = ALIGN(board_ie_len, 4);
 
@@ -238,7 +282,10 @@
 
 static int ath12k_core_fetch_board_data_api_n(struct ath12k_base *ab,
 					      struct ath12k_board_data *bd,
-					      const char *boardname)
+					      const char *boardname,
+					      int ie_id_match,
+					      int name_id,
+					      int data_id)
 {
 	size_t len, magic_len;
 	const u8 *data;
@@ -303,22 +350,23 @@
 			goto err;
 		}
 
-		switch (ie_id) {
-		case ATH12K_BD_IE_BOARD:
+		if (ie_id == ie_id_match) {
 			ret = ath12k_core_parse_bd_ie_board(ab, bd, data,
 							    ie_len,
 							    boardname,
-							    ATH12K_BD_IE_BOARD);
+							    ie_id_match,
+							    name_id,
+							    data_id);
 			if (ret == -ENOENT)
 				/* no match found, continue */
-				break;
+				goto next;
 			else if (ret)
 				/* there was an error, bail out */
 				goto err;
 			/* either found or error, so stop searching */
 			goto out;
 		}
-
+next:
 		/* jump over the padding */
 		ie_len = ALIGN(ie_len, 4);
 
@@ -328,8 +376,9 @@
 
 out:
 	if (!bd->data || !bd->len) {
-		ath12k_err(ab,
-			   "failed to fetch board data for %s from %s\n",
+		ath12k_dbg(ab, ATH12K_DBG_BOOT,
+			   "failed to fetch %s for %s from %s\n",
+			   ath12k_bd_ie_type_str(ie_id_match),
 			   boardname, filepath);
 		ret = -ENODATA;
 		goto err;
@@ -356,28 +405,56 @@
 	return 0;
 }
 
-#define BOARD_NAME_SIZE 100
+#define BOARD_NAME_SIZE 200
 int ath12k_core_fetch_bdf(struct ath12k_base *ab, struct ath12k_board_data *bd)
 {
-	char boardname[BOARD_NAME_SIZE];
+	char boardname[BOARD_NAME_SIZE], fallback_boardname[BOARD_NAME_SIZE];
+	char *filename, filepath[100];
 	int bd_api;
 	int ret;
 
-	ret = ath12k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
+	filename = ATH12K_BOARD_API2_FILE;
+
+	ret = ath12k_core_create_board_name(ab, boardname, sizeof(boardname));
 	if (ret) {
 		ath12k_err(ab, "failed to create board name: %d", ret);
 		return ret;
 	}
 
 	bd_api = 2;
-	ret = ath12k_core_fetch_board_data_api_n(ab, bd, boardname);
+	ret = ath12k_core_fetch_board_data_api_n(ab, bd, boardname,
+						 ATH12K_BD_IE_BOARD,
+						 ATH12K_BD_IE_BOARD_NAME,
+						 ATH12K_BD_IE_BOARD_DATA);
+	if (!ret)
+		goto success;
+
+	ret = ath12k_core_create_fallback_board_name(ab, fallback_boardname,
+						     sizeof(fallback_boardname));
+	if (ret) {
+		ath12k_err(ab, "failed to create fallback board name: %d", ret);
+		return ret;
+	}
+
+	ret = ath12k_core_fetch_board_data_api_n(ab, bd, fallback_boardname,
+						 ATH12K_BD_IE_BOARD,
+						 ATH12K_BD_IE_BOARD_NAME,
+						 ATH12K_BD_IE_BOARD_DATA);
 	if (!ret)
 		goto success;
 
 	bd_api = 1;
 	ret = ath12k_core_fetch_board_data_api_1(ab, bd, ATH12K_DEFAULT_BOARD_FILE);
 	if (ret) {
-		ath12k_err(ab, "failed to fetch board-2.bin or board.bin from %s\n",
+		ath12k_core_create_firmware_path(ab, filename,
+						 filepath, sizeof(filepath));
+		ath12k_err(ab, "failed to fetch board data for %s from %s\n",
+			   boardname, filepath);
+		if (memcmp(boardname, fallback_boardname, strlen(boardname)))
+			ath12k_err(ab, "failed to fetch board data for %s from %s\n",
+				   fallback_boardname, filepath);
+
+		ath12k_err(ab, "failed to fetch board.bin from %s\n",
 			   ab->hw_params->fw.dir);
 		return ret;
 	}
@@ -387,6 +464,52 @@
 	return 0;
 }
 
+int ath12k_core_fetch_regdb(struct ath12k_base *ab, struct ath12k_board_data *bd)
+{
+	char boardname[BOARD_NAME_SIZE], default_boardname[BOARD_NAME_SIZE];
+	int ret;
+
+	ret = ath12k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
+	if (ret) {
+		ath12k_dbg(ab, ATH12K_DBG_BOOT,
+			   "failed to create board name for regdb: %d", ret);
+		goto exit;
+	}
+
+	ret = ath12k_core_fetch_board_data_api_n(ab, bd, boardname,
+						 ATH12K_BD_IE_REGDB,
+						 ATH12K_BD_IE_REGDB_NAME,
+						 ATH12K_BD_IE_REGDB_DATA);
+	if (!ret)
+		goto exit;
+
+	ret = ath12k_core_create_bus_type_board_name(ab, default_boardname,
+						     BOARD_NAME_SIZE);
+	if (ret) {
+		ath12k_dbg(ab, ATH12K_DBG_BOOT,
+			   "failed to create default board name for regdb: %d", ret);
+		goto exit;
+	}
+
+	ret = ath12k_core_fetch_board_data_api_n(ab, bd, default_boardname,
+						 ATH12K_BD_IE_REGDB,
+						 ATH12K_BD_IE_REGDB_NAME,
+						 ATH12K_BD_IE_REGDB_DATA);
+	if (!ret)
+		goto exit;
+
+	ret = ath12k_core_fetch_board_data_api_1(ab, bd, ATH12K_REGDB_FILE_NAME);
+	if (ret)
+		ath12k_dbg(ab, ATH12K_DBG_BOOT, "failed to fetch %s from %s\n",
+			   ATH12K_REGDB_FILE_NAME, ab->hw_params->fw.dir);
+
+exit:
+	if (!ret)
+		ath12k_dbg(ab, ATH12K_DBG_BOOT, "fetched regdb\n");
+
+	return ret;
+}
+
 static void ath12k_core_stop(struct ath12k_base *ab)
 {
 	if (!test_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags))
@@ -963,7 +1086,6 @@
 						ATH12K_RECOVER_START_TIMEOUT_HZ);
 
 	ath12k_hif_power_down(ab);
-	ath12k_qmi_free_resource(ab);
 	ath12k_hif_power_up(ab);
 
 	ath12k_dbg(ab, ATH12K_DBG_BOOT, "reset started\n");
@@ -979,6 +1101,8 @@
 		return ret;
 	}
 
+	ath12k_fw_map(ab);
+
 	return 0;
 }
 
@@ -1007,6 +1131,7 @@
 	ath12k_hif_power_down(ab);
 	ath12k_mac_destroy(ab);
 	ath12k_core_soc_destroy(ab);
+	ath12k_fw_unmap(ab);
 }
 
 void ath12k_core_free(struct ath12k_base *ab)
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/core.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/core.h
@@ -13,6 +13,7 @@
 #include <linux/bitfield.h>
 #include <linux/dmi.h>
 #include <linux/ctype.h>
+#include <linux/firmware.h>
 #include "qmi.h"
 #include "htc.h"
 #include "wmi.h"
@@ -24,6 +25,7 @@
 #include "hal_rx.h"
 #include "reg.h"
 #include "dbring.h"
+#include "fw.h"
 
 #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
 
@@ -55,6 +57,11 @@
 #define ATH12K_RECONFIGURE_TIMEOUT_HZ		(10 * HZ)
 #define ATH12K_RECOVER_START_TIMEOUT_HZ		(20 * HZ)
 
+enum ath12k_bdf_search {
+	ATH12K_BDF_SEARCH_DEFAULT,
+	ATH12K_BDF_SEARCH_BUS_AND_BOARD,
+};
+
 enum wme_ac {
 	WME_AC_BE,
 	WME_AC_BK,
@@ -420,7 +427,7 @@
 };
 
 #define ATH12K_MIN_5G_FREQ 4150
-#define ATH12K_MIN_6G_FREQ 5945
+#define ATH12K_MIN_6G_FREQ 5925
 #define ATH12K_MAX_6G_FREQ 7115
 #define ATH12K_NUM_CHANS 100
 #define ATH12K_MAX_5G_CHAN 173
@@ -793,6 +800,26 @@
 	/* true means radio is on */
 	bool rfkill_radio_on;
 
+	struct {
+		enum ath12k_bdf_search bdf_search;
+		u32 vendor;
+		u32 device;
+		u32 subsystem_vendor;
+		u32 subsystem_device;
+	} id;
+
+	struct {
+		u32 api_version;
+
+		const struct firmware *fw;
+		const u8 *amss_data;
+		size_t amss_len;
+		const u8 *m3_data;
+		size_t m3_len;
+
+		DECLARE_BITMAP(fw_features, ATH12K_FW_FEATURE_COUNT);
+	} fw;
+
 	/* must be last */
 	u8 drv_priv[] __aligned(sizeof(void *));
 };
@@ -810,6 +837,7 @@
 int ath12k_core_fetch_bdf(struct ath12k_base *ath12k,
 			  struct ath12k_board_data *bd);
 void ath12k_core_free_bdf(struct ath12k_base *ab, struct ath12k_board_data *bd);
+int ath12k_core_fetch_regdb(struct ath12k_base *ab, struct ath12k_board_data *bd);
 int ath12k_core_check_dt(struct ath12k_base *ath12k);
 int ath12k_core_check_smbios(struct ath12k_base *ab);
 void ath12k_core_halt(struct ath12k *ar);
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/dp.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/dp.c
@@ -127,7 +127,9 @@
 static int ath12k_dp_srng_calculate_msi_group(struct ath12k_base *ab,
 					      enum hal_ring_type type, int ring_num)
 {
+	const struct ath12k_hal_tcl_to_wbm_rbm_map *map;
 	const u8 *grp_mask;
+	int i;
 
 	switch (type) {
 	case HAL_WBM2SW_RELEASE:
@@ -135,6 +137,14 @@
 			grp_mask = &ab->hw_params->ring_mask->rx_wbm_rel[0];
 			ring_num = 0;
 		} else {
+			map = ab->hw_params->hal_ops->tcl_to_wbm_rbm_map;
+			for (i = 0; i < ab->hw_params->max_tx_ring; i++) {
+				if (ring_num == map[i].wbm_ring_num) {
+					ring_num = i;
+					break;
+				}
+			}
+
 			grp_mask = &ab->hw_params->ring_mask->tx[0];
 		}
 		break;
@@ -876,11 +886,9 @@
 	enum dp_monitor_mode monitor_mode;
 	u8 ring_mask;
 
-	while (i < ab->hw_params->max_tx_ring) {
-		if (ab->hw_params->ring_mask->tx[grp_id] &
-			BIT(ab->hw_params->hal_ops->tcl_to_wbm_rbm_map[i].wbm_ring_num))
-			ath12k_dp_tx_completion_handler(ab, i);
-		i++;
+	if (ab->hw_params->ring_mask->tx[grp_id]) {
+		i = fls(ab->hw_params->ring_mask->tx[grp_id]) - 1;
+		ath12k_dp_tx_completion_handler(ab, i);
 	}
 
 	if (ab->hw_params->ring_mask->rx_err[grp_id]) {
@@ -1204,6 +1212,7 @@
 	}
 
 	kfree(dp->spt_info);
+	dp->spt_info = NULL;
 }
 
 static void ath12k_dp_reoq_lut_cleanup(struct ath12k_base *ab)
@@ -1239,8 +1248,10 @@
 
 	ath12k_dp_rx_reo_cmd_list_cleanup(ab);
 
-	for (i = 0; i < ab->hw_params->max_tx_ring; i++)
+	for (i = 0; i < ab->hw_params->max_tx_ring; i++) {
 		kfree(dp->tx_ring[i].tx_status);
+		dp->tx_ring[i].tx_status = NULL;
+	}
 
 	ath12k_dp_rx_free(ab);
 	/* Deinit any SOC level resource */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/dp_rx.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/dp_rx.c
@@ -2355,8 +2355,10 @@
 	channel_num = meta_data;
 	center_freq = meta_data >> 16;
 
-	if (center_freq >= 5935 && center_freq <= 7105) {
+	if (center_freq >= ATH12K_MIN_6G_FREQ &&
+	    center_freq <= ATH12K_MAX_6G_FREQ) {
 		rx_status->band = NL80211_BAND_6GHZ;
+		rx_status->freq = center_freq;
 	} else if (channel_num >= 1 && channel_num <= 14) {
 		rx_status->band = NL80211_BAND_2GHZ;
 	} else if (channel_num >= 36 && channel_num <= 173) {
@@ -2374,8 +2376,9 @@
 				rx_desc, sizeof(*rx_desc));
 	}
 
-	rx_status->freq = ieee80211_channel_to_frequency(channel_num,
-							 rx_status->band);
+	if (rx_status->band != NL80211_BAND_6GHZ)
+		rx_status->freq = ieee80211_channel_to_frequency(channel_num,
+								 rx_status->band);
 
 	ath12k_dp_rx_h_rate(ar, rx_desc, rx_status);
 }
@@ -2647,7 +2650,7 @@
 		if (push_reason !=
 		    HAL_REO_DEST_RING_PUSH_REASON_ROUTING_INSTRUCTION) {
 			dev_kfree_skb_any(msdu);
-			ab->soc_stats.hal_reo_error[dp->reo_dst_ring[ring_id].ring_id]++;
+			ab->soc_stats.hal_reo_error[ring_id]++;
 			continue;
 		}
 
@@ -2734,6 +2737,7 @@
 	peer = ath12k_peer_find(ab, vdev_id, peer_mac);
 	if (!peer) {
 		spin_unlock_bh(&ab->base_lock);
+		crypto_free_shash(tfm);
 		ath12k_warn(ab, "failed to find the peer to set up fragment info\n");
 		return -ENOENT;
 	}
@@ -2963,7 +2967,7 @@
 	struct hal_srng *srng;
 	dma_addr_t link_paddr, buf_paddr;
 	u32 desc_bank, msdu_info, msdu_ext_info, mpdu_info;
-	u32 cookie, hal_rx_desc_sz, dest_ring_info0;
+	u32 cookie, hal_rx_desc_sz, dest_ring_info0, queue_addr_hi;
 	int ret;
 	struct ath12k_rx_desc_info *desc_info;
 	u8 dst_ind;
@@ -2999,7 +3003,7 @@
 
 	buf_paddr = dma_map_single(ab->dev, defrag_skb->data,
 				   defrag_skb->len + skb_tailroom(defrag_skb),
-				   DMA_FROM_DEVICE);
+				   DMA_TO_DEVICE);
 	if (dma_mapping_error(ab->dev, buf_paddr))
 		return -ENOMEM;
 
@@ -3055,13 +3059,11 @@
 	reo_ent_ring->rx_mpdu_info.peer_meta_data =
 		reo_dest_ring->rx_mpdu_info.peer_meta_data;
 
-	/* Firmware expects physical address to be filled in queue_addr_lo in
-	 * the MLO scenario and in case of non MLO peer meta data needs to be
-	 * filled.
-	 * TODO: Need to handle for MLO scenario.
-	 */
-	reo_ent_ring->queue_addr_lo = reo_dest_ring->rx_mpdu_info.peer_meta_data;
-	reo_ent_ring->info0 = le32_encode_bits(dst_ind,
+	reo_ent_ring->queue_addr_lo = cpu_to_le32(lower_32_bits(rx_tid->paddr));
+	queue_addr_hi = upper_32_bits(rx_tid->paddr);
+	reo_ent_ring->info0 = le32_encode_bits(queue_addr_hi,
+					       HAL_REO_ENTR_RING_INFO0_QUEUE_ADDR_HI) |
+			      le32_encode_bits(dst_ind,
 					       HAL_REO_ENTR_RING_INFO0_DEST_IND);
 
 	reo_ent_ring->info1 = le32_encode_bits(rx_tid->cur_sn,
@@ -3085,7 +3087,7 @@
 	spin_unlock_bh(&dp->rx_desc_lock);
 err_unmap_dma:
 	dma_unmap_single(ab->dev, buf_paddr, defrag_skb->len + skb_tailroom(defrag_skb),
-			 DMA_FROM_DEVICE);
+			 DMA_TO_DEVICE);
 	return ret;
 }
 
@@ -3956,7 +3958,7 @@
 	struct ath12k_dp *dp = &ab->dp;
 	struct htt_rx_ring_tlv_filter tlv_filter = {0};
 	u32 ring_id;
-	int ret;
+	int ret = 0;
 	u32 hal_rx_desc_sz = ab->hw_params->hal_desc_sz;
 	int i;
 
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/dp_tx.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/dp_tx.c
@@ -124,6 +124,60 @@
 						 HAL_TX_MSDU_EXT_INFO1_ENCRYPT_TYPE);
 }
 
+static void ath12k_dp_tx_move_payload(struct sk_buff *skb,
+				      unsigned long delta,
+				      bool head)
+{
+	unsigned long len = skb->len;
+
+	if (head) {
+		skb_push(skb, delta);
+		memmove(skb->data, skb->data + delta, len);
+		skb_trim(skb, len);
+	} else {
+		skb_put(skb, delta);
+		memmove(skb->data + delta, skb->data, len);
+		skb_pull(skb, delta);
+	}
+}
+
+static int ath12k_dp_tx_align_payload(struct ath12k_base *ab,
+				      struct sk_buff **pskb)
+{
+	u32 iova_mask = ab->hw_params->iova_mask;
+	unsigned long offset, delta1, delta2;
+	struct sk_buff *skb2, *skb = *pskb;
+	unsigned int headroom = skb_headroom(skb);
+	int tailroom = skb_tailroom(skb);
+	int ret = 0;
+
+	offset = (unsigned long)skb->data & iova_mask;
+	delta1 = offset;
+	delta2 = iova_mask - offset + 1;
+
+	if (headroom >= delta1) {
+		ath12k_dp_tx_move_payload(skb, delta1, true);
+	} else if (tailroom >= delta2) {
+		ath12k_dp_tx_move_payload(skb, delta2, false);
+	} else {
+		skb2 = skb_realloc_headroom(skb, iova_mask);
+		if (!skb2) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		dev_kfree_skb_any(skb);
+
+		offset = (unsigned long)skb2->data & iova_mask;
+		if (offset)
+			ath12k_dp_tx_move_payload(skb2, offset, true);
+		*pskb = skb2;
+	}
+
+out:
+	return ret;
+}
+
 int ath12k_dp_tx(struct ath12k *ar, struct ath12k_vif *arvif,
 		 struct sk_buff *skb)
 {
@@ -145,6 +199,7 @@
 	u8 ring_selector, ring_map = 0;
 	bool tcl_ring_retry;
 	bool msdu_ext_desc = false;
+	u32 iova_mask = ab->hw_params->iova_mask;
 
 	if (test_bit(ATH12K_FLAG_CRASH_FLUSH, &ar->ab->dev_flags))
 		return -ESHUTDOWN;
@@ -240,6 +295,23 @@
 		goto fail_remove_tx_buf;
 	}
 
+	if (iova_mask &&
+	    (unsigned long)skb->data & iova_mask) {
+		ret = ath12k_dp_tx_align_payload(ab, &skb);
+		if (ret) {
+			ath12k_warn(ab, "failed to align TX buffer %d\n", ret);
+			/* don't bail out, give original buffer
+			 * a chance even unaligned.
+			 */
+			goto map;
+		}
+
+		/* hdr is pointing to a wrong place after alignment,
+		 * so refresh it for later use.
+		 */
+		hdr = (void *)skb->data;
+	}
+map:
 	ti.paddr = dma_map_single(ab->dev, skb->data, skb->len, DMA_TO_DEVICE);
 	if (dma_mapping_error(ab->dev, ti.paddr)) {
 		atomic_inc(&ab->soc_stats.tx_err.misc_fail);
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/fw.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/fw.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: BSD-3-Clause-Clear
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "core.h"
+
+#include "debug.h"
+
+static int ath12k_fw_request_firmware_api_n(struct ath12k_base *ab,
+					    const char *name)
+{
+	size_t magic_len, len, ie_len;
+	int ie_id, i, index, bit, ret;
+	struct ath12k_fw_ie *hdr;
+	const u8 *data;
+	__le32 *timestamp;
+
+	ab->fw.fw = ath12k_core_firmware_request(ab, name);
+	if (IS_ERR(ab->fw.fw)) {
+		ret = PTR_ERR(ab->fw.fw);
+		ath12k_dbg(ab, ATH12K_DBG_BOOT, "failed to load %s: %d\n", name, ret);
+		ab->fw.fw = NULL;
+		return ret;
+	}
+
+	data = ab->fw.fw->data;
+	len = ab->fw.fw->size;
+
+	/* magic also includes the null byte, check that as well */
+	magic_len = strlen(ATH12K_FIRMWARE_MAGIC) + 1;
+
+	if (len < magic_len) {
+		ath12k_err(ab, "firmware image too small to contain magic: %zu\n",
+			   len);
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (memcmp(data, ATH12K_FIRMWARE_MAGIC, magic_len) != 0) {
+		ath12k_err(ab, "Invalid firmware magic\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	/* jump over the padding */
+	magic_len = ALIGN(magic_len, 4);
+
+	/* make sure there's space for padding */
+	if (magic_len > len) {
+		ath12k_err(ab, "No space for padding after magic\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	len -= magic_len;
+	data += magic_len;
+
+	/* loop elements */
+	while (len > sizeof(struct ath12k_fw_ie)) {
+		hdr = (struct ath12k_fw_ie *)data;
+
+		ie_id = le32_to_cpu(hdr->id);
+		ie_len = le32_to_cpu(hdr->len);
+
+		len -= sizeof(*hdr);
+		data += sizeof(*hdr);
+
+		if (len < ie_len) {
+			ath12k_err(ab, "Invalid length for FW IE %d (%zu < %zu)\n",
+				   ie_id, len, ie_len);
+			ret = -EINVAL;
+			goto err;
+		}
+
+		switch (ie_id) {
+		case ATH12K_FW_IE_TIMESTAMP:
+			if (ie_len != sizeof(u32))
+				break;
+
+			timestamp = (__le32 *)data;
+
+			ath12k_dbg(ab, ATH12K_DBG_BOOT, "found fw timestamp %d\n",
+				   le32_to_cpup(timestamp));
+			break;
+		case ATH12K_FW_IE_FEATURES:
+			ath12k_dbg(ab, ATH12K_DBG_BOOT,
+				   "found firmware features ie (%zd B)\n",
+				   ie_len);
+
+			for (i = 0; i < ATH12K_FW_FEATURE_COUNT; i++) {
+				index = i / 8;
+				bit = i % 8;
+
+				if (index == ie_len)
+					break;
+
+				if (data[index] & (1 << bit))
+					__set_bit(i, ab->fw.fw_features);
+			}
+
+			ath12k_dbg_dump(ab, ATH12K_DBG_BOOT, "features", "",
+					ab->fw.fw_features,
+					sizeof(ab->fw.fw_features));
+			break;
+		case ATH12K_FW_IE_AMSS_IMAGE:
+			ath12k_dbg(ab, ATH12K_DBG_BOOT,
+				   "found fw image ie (%zd B)\n",
+				   ie_len);
+
+			ab->fw.amss_data = data;
+			ab->fw.amss_len = ie_len;
+			break;
+		case ATH12K_FW_IE_M3_IMAGE:
+			ath12k_dbg(ab, ATH12K_DBG_BOOT,
+				   "found m3 image ie (%zd B)\n",
+				   ie_len);
+
+			ab->fw.m3_data = data;
+			ab->fw.m3_len = ie_len;
+			break;
+		default:
+			ath12k_warn(ab, "Unknown FW IE: %u\n", ie_id);
+			break;
+		}
+
+		/* jump over the padding */
+		ie_len = ALIGN(ie_len, 4);
+
+		/* make sure there's space for padding */
+		if (ie_len > len)
+			break;
+
+		len -= ie_len;
+		data += ie_len;
+	}
+
+	return 0;
+
+err:
+	release_firmware(ab->fw.fw);
+	ab->fw.fw = NULL;
+	return ret;
+}
+
+void ath12k_fw_map(struct ath12k_base *ab)
+{
+	int ret;
+
+	ret = ath12k_fw_request_firmware_api_n(ab, ATH12K_FW_API2_FILE);
+	if (ret == 0)
+		ab->fw.api_version = 2;
+	else
+		ab->fw.api_version = 1;
+
+	ath12k_dbg(ab, ATH12K_DBG_BOOT, "using fw api %d\n",
+		   ab->fw.api_version);
+}
+
+void ath12k_fw_unmap(struct ath12k_base *ab)
+{
+	release_firmware(ab->fw.fw);
+	memset(&ab->fw, 0, sizeof(ab->fw));
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/fw.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/fw.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: BSD-3-Clause-Clear */
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef ATH12K_FW_H
+#define ATH12K_FW_H
+
+#define ATH12K_FW_API2_FILE		"firmware-2.bin"
+#define ATH12K_FIRMWARE_MAGIC		"QCOM-ATH12K-FW"
+
+enum ath12k_fw_ie_type {
+	ATH12K_FW_IE_TIMESTAMP = 0,
+	ATH12K_FW_IE_FEATURES = 1,
+	ATH12K_FW_IE_AMSS_IMAGE = 2,
+	ATH12K_FW_IE_M3_IMAGE = 3,
+};
+
+enum ath12k_fw_features {
+	/* keep last */
+	ATH12K_FW_FEATURE_COUNT,
+};
+
+void ath12k_fw_map(struct ath12k_base *ab);
+void ath12k_fw_unmap(struct ath12k_base *ab);
+
+#endif /* ATH12K_FW_H */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/hal.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/hal.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 #include <linux/dma-mapping.h>
 #include "hal_tx.h"
@@ -449,8 +449,8 @@
 
 static bool ath12k_hw_qcn9274_rx_desc_is_da_mcbc(struct hal_rx_desc *desc)
 {
-	return __le16_to_cpu(desc->u.qcn9274.msdu_end.info5) &
-	       RX_MSDU_END_INFO5_DA_IS_MCBC;
+	return __le32_to_cpu(desc->u.qcn9274.mpdu_start.info6) &
+	       RX_MPDU_START_INFO6_MCAST_BCAST;
 }
 
 static void ath12k_hw_qcn9274_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc,
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/hw.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/hw.c
@@ -540,9 +540,6 @@
 	},
 	.rx_mon_dest = {
 		0, 0, 0,
-		ATH12K_RX_MON_RING_MASK_0,
-		ATH12K_RX_MON_RING_MASK_1,
-		ATH12K_RX_MON_RING_MASK_2,
 	},
 	.rx = {
 		0, 0, 0, 0,
@@ -568,16 +565,15 @@
 		ATH12K_HOST2RXDMA_RING_MASK_0,
 	},
 	.tx_mon_dest = {
-		ATH12K_TX_MON_RING_MASK_0,
-		ATH12K_TX_MON_RING_MASK_1,
+		0, 0, 0,
 	},
 };
 
 static const struct ath12k_hw_ring_mask ath12k_hw_ring_mask_wcn7850 = {
 	.tx  = {
 		ATH12K_TX_RING_MASK_0,
+		ATH12K_TX_RING_MASK_1,
 		ATH12K_TX_RING_MASK_2,
-		ATH12K_TX_RING_MASK_4,
 	},
 	.rx_mon_dest = {
 	},
@@ -914,6 +910,8 @@
 		.rfkill_on_level = 0,
 
 		.rddm_size = 0,
+
+		.iova_mask = 0,
 	},
 	{
 		.name = "wcn7850 hw2.0",
@@ -978,6 +976,8 @@
 		.rfkill_on_level = 1,
 
 		.rddm_size = 0x780000,
+
+		.iova_mask = ATH12K_PCIE_MAX_PAYLOAD_SIZE - 1,
 	},
 	{
 		.name = "qcn9274 hw2.0",
@@ -1040,6 +1040,8 @@
 		.rfkill_on_level = 0,
 
 		.rddm_size = 0,
+
+		.iova_mask = 0,
 	},
 };
 
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/hw.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/hw.h
@@ -66,6 +66,7 @@
 #define TARGET_NUM_WDS_ENTRIES		32
 #define TARGET_DMA_BURST_SIZE		1
 #define TARGET_RX_BATCHMODE		1
+#define TARGET_EMA_MAX_PROFILE_PERIOD	8
 
 #define ATH12K_HW_MAX_QUEUES		4
 #define ATH12K_QUEUE_LEN		4096
@@ -82,6 +83,8 @@
 #define ATH12K_M3_FILE			"m3.bin"
 #define ATH12K_REGDB_FILE_NAME		"regdb.bin"
 
+#define ATH12K_PCIE_MAX_PAYLOAD_SIZE	128
+
 enum ath12k_hw_rate_cck {
 	ATH12K_HW_RATE_CCK_LP_11M = 0,
 	ATH12K_HW_RATE_CCK_LP_5_5M,
@@ -192,6 +195,8 @@
 	u32 rfkill_on_level;
 
 	u32 rddm_size;
+
+	u32 iova_mask;
 };
 
 struct ath12k_hw_ops {
@@ -242,10 +247,16 @@
 	ATH12K_BD_IE_BOARD_DATA = 1,
 };
 
+enum ath12k_bd_ie_regdb_type {
+	ATH12K_BD_IE_REGDB_NAME = 0,
+	ATH12K_BD_IE_REGDB_DATA = 1,
+};
+
 enum ath12k_bd_ie_type {
 	/* contains sub IEs of enum ath12k_bd_ie_board_type */
 	ATH12K_BD_IE_BOARD = 0,
-	ATH12K_BD_IE_BOARD_EXT = 1,
+	/* contains sub IEs of enum ath12k_bd_ie_regdb_type */
+	ATH12K_BD_IE_REGDB = 1,
 };
 
 struct ath12k_hw_regs {
@@ -315,6 +326,18 @@
 	u32 hal_reo_status_ring_base;
 };
 
+static inline const char *ath12k_bd_ie_type_str(enum ath12k_bd_ie_type type)
+{
+	switch (type) {
+	case ATH12K_BD_IE_BOARD:
+		return "board data";
+	case ATH12K_BD_IE_REGDB:
+		return "regdb data";
+	}
+
+	return "unknown";
+}
+
 int ath12k_hw_init(struct ath12k_base *ab);
 
 #endif
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/mac.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/mac.c
@@ -780,7 +780,10 @@
 
 	spin_lock_bh(&ab->base_lock);
 	list_for_each_entry_safe(peer, tmp, &ab->peers, list) {
-		ath12k_dp_rx_peer_tid_cleanup(ar, peer);
+		/* Skip Rx TID cleanup for self peer */
+		if (peer->sta)
+			ath12k_dp_rx_peer_tid_cleanup(ar, peer);
+
 		list_del(&peer->list);
 		kfree(peer);
 	}
@@ -1619,7 +1622,9 @@
 {
 	const struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
 	int i;
-	u8 ampdu_factor, rx_mcs_80, rx_mcs_160, max_nss;
+	u8 ampdu_factor, max_nss;
+	u8 rx_mcs_80 = IEEE80211_HE_MCS_NOT_SUPPORTED;
+	u8 rx_mcs_160 = IEEE80211_HE_MCS_NOT_SUPPORTED;
 	u16 mcs_160_map, mcs_80_map;
 	bool support_160;
 	u16 v;
@@ -1684,9 +1689,8 @@
 	 * request, then use MAX_AMPDU_LEN_FACTOR as 16 to calculate max_ampdu
 	 * length.
 	 */
-	ampdu_factor = (he_cap->he_cap_elem.mac_cap_info[3] &
-			IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK) >>
-			IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK;
+	ampdu_factor = u8_get_bits(he_cap->he_cap_elem.mac_cap_info[3],
+				   IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_MASK);
 
 	if (ampdu_factor) {
 		if (sta->deflink.vht_cap.vht_supported)
@@ -3361,6 +3365,11 @@
 
 	ath12k_peer_assoc_prepare(ar, vif, sta, &peer_arg, reassoc);
 
+	if (peer_arg.peer_nss < 1) {
+		ath12k_warn(ar->ab,
+			    "invalid peer NSS %d\n", peer_arg.peer_nss);
+		return -EINVAL;
+	}
 	ret = ath12k_wmi_send_peer_assoc_cmd(ar, &peer_arg);
 	if (ret) {
 		ath12k_warn(ar->ab, "failed to run peer assoc for STA %pM vdev %i: %d\n",
@@ -5269,7 +5278,7 @@
 	do {
 		if (ab->free_vdev_stats_id_map & (1LL << vdev_stats_id)) {
 			vdev_stats_id++;
-			if (vdev_stats_id <= ATH12K_INVAL_VDEV_STATS_ID) {
+			if (vdev_stats_id >= ATH12K_MAX_VDEV_STATS_ID) {
 				vdev_stats_id = ATH12K_INVAL_VDEV_STATS_ID;
 				break;
 			}
@@ -5911,14 +5920,24 @@
 				     enum nl80211_band band,
 				     enum nl80211_iftype type)
 {
-	struct ieee80211_sta_eht_cap *eht_cap;
+	struct ieee80211_sta_eht_cap *eht_cap = NULL;
 	enum wmi_phy_mode down_mode;
+	int n = ar->mac.sbands[band].n_iftype_data;
+	int i;
+	struct ieee80211_sband_iftype_data *data;
 
 	if (mode < MODE_11BE_EHT20)
 		return mode;
 
-	eht_cap = &ar->mac.iftype[band][type].eht_cap;
-	if (eht_cap->has_eht)
+	data = ar->mac.iftype[band];
+	for (i = 0; i < n; i++) {
+		if (data[i].types_mask & BIT(type)) {
+			eht_cap = &data[i].eht_cap;
+			break;
+		}
+	}
+
+	if (eht_cap && eht_cap->has_eht)
 		return mode;
 
 	switch (mode) {
@@ -5988,9 +6007,9 @@
 							chandef->chan->band,
 							arvif->vif->type);
 	arg.min_power = 0;
-	arg.max_power = chandef->chan->max_power * 2;
-	arg.max_reg_power = chandef->chan->max_reg_power * 2;
-	arg.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
+	arg.max_power = chandef->chan->max_power;
+	arg.max_reg_power = chandef->chan->max_reg_power;
+	arg.max_antenna_gain = chandef->chan->max_antenna_gain;
 
 	arg.pref_tx_streams = ar->num_tx_chains;
 	arg.pref_rx_streams = ar->num_rx_chains;
@@ -6845,9 +6864,9 @@
 				    arvif->vdev_id, ret);
 			return ret;
 		}
-		ieee80211_iterate_stations_atomic(hw,
-						  ath12k_mac_disable_peer_fixed_rate,
-						  arvif);
+		ieee80211_iterate_stations_mtx(hw,
+					       ath12k_mac_disable_peer_fixed_rate,
+					       arvif);
 	} else if (ath12k_mac_bitrate_mask_get_single_nss(ar, band, mask,
 							  &single_nss)) {
 		rate = WMI_FIXED_RATE_NONE;
@@ -6891,16 +6910,16 @@
 			return -EINVAL;
 		}
 
-		ieee80211_iterate_stations_atomic(hw,
-						  ath12k_mac_disable_peer_fixed_rate,
-						  arvif);
+		ieee80211_iterate_stations_mtx(hw,
+					       ath12k_mac_disable_peer_fixed_rate,
+					       arvif);
 
 		mutex_lock(&ar->conf_mutex);
 
 		arvif->bitrate_mask = *mask;
-		ieee80211_iterate_stations_atomic(hw,
-						  ath12k_mac_set_bitrate_mask_iter,
-						  arvif);
+		ieee80211_iterate_stations_mtx(hw,
+					       ath12k_mac_set_bitrate_mask_iter,
+					       arvif);
 
 		mutex_unlock(&ar->conf_mutex);
 	}
@@ -7198,7 +7217,7 @@
 	}
 
 	if (supported_bands & WMI_HOST_WLAN_5G_CAP) {
-		if (reg_cap->high_5ghz_chan >= ATH12K_MAX_6G_FREQ) {
+		if (reg_cap->high_5ghz_chan >= ATH12K_MIN_6G_FREQ) {
 			channels = kmemdup(ath12k_6ghz_channels,
 					   sizeof(ath12k_6ghz_channels), GFP_KERNEL);
 			if (!channels) {
@@ -7314,19 +7333,23 @@
 
 static const u8 ath12k_if_types_ext_capa[] = {
 	[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
+	[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
 	[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
 };
 
 static const u8 ath12k_if_types_ext_capa_sta[] = {
 	[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
+	[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
 	[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
 	[9] = WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT,
 };
 
 static const u8 ath12k_if_types_ext_capa_ap[] = {
 	[0] = WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING,
+	[2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT,
 	[7] = WLAN_EXT_CAPA8_OPMODE_NOTIF,
 	[9] = WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT,
+	[10] = WLAN_EXT_CAPA11_EMA_SUPPORT,
 };
 
 static const struct wiphy_iftype_ext_capab ath12k_iftypes_ext_capa[] = {
@@ -7495,6 +7518,7 @@
 
 	hw->vif_data_size = sizeof(struct ath12k_vif);
 	hw->sta_data_size = sizeof(struct ath12k_sta);
+	hw->extra_tx_headroom = ab->hw_params->iova_mask;
 
 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);
@@ -7505,6 +7529,9 @@
 	wiphy->iftype_ext_capab = ath12k_iftypes_ext_capa;
 	wiphy->num_iftype_ext_capab = ARRAY_SIZE(ath12k_iftypes_ext_capa);
 
+	wiphy->mbssid_max_interfaces = TARGET_NUM_VDEVS;
+	wiphy->ema_max_profile_periodicity = TARGET_EMA_MAX_PROFILE_PERIOD;
+
 	if (ar->supports_6ghz) {
 		wiphy_ext_feature_set(wiphy,
 				      NL80211_EXT_FEATURE_FILS_DISCOVERY);
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/mhi.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/mhi.c
@@ -1,11 +1,12 @@
 // SPDX-License-Identifier: BSD-3-Clause-Clear
 /*
  * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/msi.h>
 #include <linux/pci.h>
+#include <linux/firmware.h>
 
 #include "core.h"
 #include "debug.h"
@@ -364,17 +365,24 @@
 	if (!mhi_ctrl)
 		return -ENOMEM;
 
-	ath12k_core_create_firmware_path(ab, ATH12K_AMSS_FILE,
-					 ab_pci->amss_path,
-					 sizeof(ab_pci->amss_path));
-
 	ab_pci->mhi_ctrl = mhi_ctrl;
 	mhi_ctrl->cntrl_dev = ab->dev;
-	mhi_ctrl->fw_image = ab_pci->amss_path;
 	mhi_ctrl->regs = ab->mem;
 	mhi_ctrl->reg_len = ab->mem_len;
 	mhi_ctrl->rddm_size = ab->hw_params->rddm_size;
 
+	if (ab->fw.amss_data && ab->fw.amss_len > 0) {
+		/* use MHI firmware file from firmware-N.bin */
+		mhi_ctrl->fw_data = ab->fw.amss_data;
+		mhi_ctrl->fw_sz = ab->fw.amss_len;
+	} else {
+		/* use the old separate mhi.bin MHI firmware file */
+		ath12k_core_create_firmware_path(ab, ATH12K_AMSS_FILE,
+						 ab_pci->amss_path,
+						 sizeof(ab_pci->amss_path));
+		mhi_ctrl->fw_image = ab_pci->amss_path;
+	}
+
 	ret = ath12k_mhi_get_msi(ab_pci);
 	if (ret) {
 		ath12k_err(ab, "failed to get msi for mhi\n");
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/pci.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/pci.c
@@ -469,7 +469,8 @@
 {
 	int i;
 
-	clear_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags);
+	if (!test_and_clear_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags))
+		return;
 
 	for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) {
 		struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
@@ -1057,14 +1058,14 @@
 {
 	int i;
 
-	set_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags);
-
 	for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) {
 		struct ath12k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i];
 
 		napi_enable(&irq_grp->napi);
 		ath12k_pci_ext_grp_enable(irq_grp);
 	}
+
+	set_bit(ATH12K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags);
 }
 
 void ath12k_pci_ext_irq_disable(struct ath12k_base *ab)
@@ -1310,6 +1311,15 @@
 		goto err_free_core;
 	}
 
+	ath12k_dbg(ab, ATH12K_DBG_BOOT, "pci probe %04x:%04x %04x:%04x\n",
+		   pdev->vendor, pdev->device,
+		   pdev->subsystem_vendor, pdev->subsystem_device);
+
+	ab->id.vendor = pdev->vendor;
+	ab->id.device = pdev->device;
+	ab->id.subsystem_vendor = pdev->subsystem_vendor;
+	ab->id.subsystem_device = pdev->subsystem_device;
+
 	switch (pci_dev->device) {
 	case QCN9274_DEVICE_ID:
 		ab_pci->msi_config = &ath12k_msi_config[0];
@@ -1333,6 +1343,7 @@
 		}
 		break;
 	case WCN7850_DEVICE_ID:
+		ab->id.bdf_search = ATH12K_BDF_SEARCH_BUS_AND_BOARD;
 		ab_pci->msi_config = &ath12k_msi_config[0];
 		ab->static_window_map = false;
 		ab_pci->pci_ops = &ath12k_pci_ops_wcn7850;
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/qmi.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/qmi.c
@@ -1977,6 +1977,7 @@
 			       QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN,
 			       qmi_wlanfw_host_cap_req_msg_v01_ei, &req);
 	if (ret < 0) {
+		qmi_txn_cancel(&txn);
 		ath12k_warn(ab, "Failed to send host capability request,err = %d\n", ret);
 		goto out;
 	}
@@ -2040,6 +2041,7 @@
 			       QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,
 			       qmi_wlanfw_ind_register_req_msg_v01_ei, req);
 	if (ret < 0) {
+		qmi_txn_cancel(&txn);
 		ath12k_warn(ab, "Failed to send indication register request, err = %d\n",
 			    ret);
 		goto out;
@@ -2114,6 +2116,7 @@
 			       QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,
 			       qmi_wlanfw_respond_mem_req_msg_v01_ei, req);
 	if (ret < 0) {
+		qmi_txn_cancel(&txn);
 		ath12k_warn(ab, "qmi failed to respond memory request, err = %d\n",
 			    ret);
 		goto out;
@@ -2149,8 +2152,9 @@
 	for (i = 0; i < ab->qmi.mem_seg_count; i++) {
 		if (!ab->qmi.target_mem[i].v.addr)
 			continue;
+
 		dma_free_coherent(ab->dev,
-				  ab->qmi.target_mem[i].size,
+				  ab->qmi.target_mem[i].prev_size,
 				  ab->qmi.target_mem[i].v.addr,
 				  ab->qmi.target_mem[i].paddr);
 		ab->qmi.target_mem[i].v.addr = NULL;
@@ -2176,6 +2180,20 @@
 		case M3_DUMP_REGION_TYPE:
 		case PAGEABLE_MEM_REGION_TYPE:
 		case CALDB_MEM_REGION_TYPE:
+			/* Firmware reloads in recovery/resume.
+			 * In such cases, no need to allocate memory for FW again.
+			 */
+			if (chunk->v.addr) {
+				if (chunk->prev_type == chunk->type &&
+				    chunk->prev_size == chunk->size)
+					goto this_chunk_done;
+
+				/* cannot reuse the existing chunk */
+				dma_free_coherent(ab->dev, chunk->prev_size,
+						  chunk->v.addr, chunk->paddr);
+				chunk->v.addr = NULL;
+			}
+
 			chunk->v.addr = dma_alloc_coherent(ab->dev,
 							   chunk->size,
 							   &chunk->paddr,
@@ -2194,6 +2212,10 @@
 					    chunk->type, chunk->size);
 				return -ENOMEM;
 			}
+
+			chunk->prev_type = chunk->type;
+			chunk->prev_size = chunk->size;
+this_chunk_done:
 			break;
 		default:
 			ath12k_warn(ab, "memory type %u not supported\n",
@@ -2229,6 +2251,7 @@
 			       QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,
 			       qmi_wlanfw_cap_req_msg_v01_ei, &req);
 	if (ret < 0) {
+		qmi_txn_cancel(&txn);
 		ath12k_warn(ab, "qmi failed to send target cap request, err = %d\n",
 			    ret);
 		goto out;
@@ -2313,7 +2336,7 @@
 	struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
 	struct qmi_txn txn = {};
 	const u8 *temp = data;
-	int ret;
+	int ret = 0;
 	u32 remaining = len;
 
 	req = kzalloc(sizeof(*req), GFP_KERNEL);
@@ -2423,8 +2446,7 @@
 
 		break;
 	case ATH12K_QMI_BDF_TYPE_REGDB:
-		ret = ath12k_core_fetch_board_data_api_1(ab, &bd,
-							 ATH12K_REGDB_FILE_NAME);
+		ret = ath12k_core_fetch_regdb(ab, &bd);
 		if (ret) {
 			ath12k_warn(ab, "qmi failed to load regdb bin:\n");
 			goto out;
@@ -2494,53 +2516,78 @@
 	return ret;
 }
 
+static void ath12k_qmi_m3_free(struct ath12k_base *ab)
+{
+	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
+
+	if (!m3_mem->vaddr)
+		return;
+
+	dma_free_coherent(ab->dev, m3_mem->size,
+			  m3_mem->vaddr, m3_mem->paddr);
+	m3_mem->vaddr = NULL;
+	m3_mem->size = 0;
+}
+
 static int ath12k_qmi_m3_load(struct ath12k_base *ab)
 {
 	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
-	const struct firmware *fw;
+	const struct firmware *fw = NULL;
+	const void *m3_data;
 	char path[100];
+	size_t m3_len;
 	int ret;
 
-	if (m3_mem->vaddr || m3_mem->size)
-		return 0;
+	if (ab->fw.m3_data && ab->fw.m3_len > 0) {
+		/* firmware-N.bin had a m3 firmware file so use that */
+		m3_data = ab->fw.m3_data;
+		m3_len = ab->fw.m3_len;
+	} else {
+		/* No m3 file in firmware-N.bin so try to request old
+		 * separate m3.bin.
+		 */
+		fw = ath12k_core_firmware_request(ab, ATH12K_M3_FILE);
+		if (IS_ERR(fw)) {
+			ret = PTR_ERR(fw);
+			ath12k_core_create_firmware_path(ab, ATH12K_M3_FILE,
+							 path, sizeof(path));
+			ath12k_err(ab, "failed to load %s: %d\n", path, ret);
+			return ret;
+		}
+
+		m3_data = fw->data;
+		m3_len = fw->size;
+	}
+
+	/* In recovery/resume cases, M3 buffer is not freed, try to reuse that */
+	if (m3_mem->vaddr) {
+		if (m3_mem->size >= m3_len)
+			goto skip_m3_alloc;
 
-	fw = ath12k_core_firmware_request(ab, ATH12K_M3_FILE);
-	if (IS_ERR(fw)) {
-		ret = PTR_ERR(fw);
-		ath12k_core_create_firmware_path(ab, ATH12K_M3_FILE,
-						 path, sizeof(path));
-		ath12k_err(ab, "failed to load %s: %d\n", path, ret);
-		return ret;
+		/* Old buffer is too small, free and reallocate */
+		ath12k_qmi_m3_free(ab);
 	}
 
 	m3_mem->vaddr = dma_alloc_coherent(ab->dev,
-					   fw->size, &m3_mem->paddr,
+					   m3_len, &m3_mem->paddr,
 					   GFP_KERNEL);
 	if (!m3_mem->vaddr) {
 		ath12k_err(ab, "failed to allocate memory for M3 with size %zu\n",
 			   fw->size);
-		release_firmware(fw);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto out;
 	}
 
-	memcpy(m3_mem->vaddr, fw->data, fw->size);
-	m3_mem->size = fw->size;
-	release_firmware(fw);
+skip_m3_alloc:
+	memcpy(m3_mem->vaddr, m3_data, m3_len);
+	m3_mem->size = m3_len;
 
-	return 0;
-}
-
-static void ath12k_qmi_m3_free(struct ath12k_base *ab)
-{
-	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
+	ret = 0;
 
-	if (!m3_mem->vaddr)
-		return;
+out:
+	release_firmware(fw);
 
-	dma_free_coherent(ab->dev, m3_mem->size,
-			  m3_mem->vaddr, m3_mem->paddr);
-	m3_mem->vaddr = NULL;
-	m3_mem->size = 0;
+	return ret;
 }
 
 static int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab)
@@ -2573,6 +2620,7 @@
 			       QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,
 			       qmi_wlanfw_m3_info_req_msg_v01_ei, &req);
 	if (ret < 0) {
+		qmi_txn_cancel(&txn);
 		ath12k_warn(ab, "qmi failed to send M3 information request, err = %d\n",
 			    ret);
 		goto out;
@@ -2619,6 +2667,7 @@
 			       QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,
 			       qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);
 	if (ret < 0) {
+		qmi_txn_cancel(&txn);
 		ath12k_warn(ab, "qmi failed to send mode request, mode: %d, err = %d\n",
 			    mode, ret);
 		goto out;
@@ -2710,6 +2759,7 @@
 			       QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,
 			       qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);
 	if (ret < 0) {
+		qmi_txn_cancel(&txn);
 		ath12k_warn(ab, "qmi failed to send wlan config request, err = %d\n",
 			    ret);
 		goto out;
@@ -2941,6 +2991,9 @@
 		.decoded_size = sizeof(struct qmi_wlanfw_fw_ready_ind_msg_v01),
 		.fn = ath12k_qmi_msg_fw_ready_cb,
 	},
+
+	/* end of list */
+	{},
 };
 
 static int ath12k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/qmi.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/qmi.h
@@ -97,6 +97,8 @@
 struct target_mem_chunk {
 	u32 size;
 	u32 type;
+	u32 prev_size;
+	u32 prev_type;
 	dma_addr_t paddr;
 	union {
 		void __iomem *ioaddr;
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/reg.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/reg.c
@@ -103,7 +103,7 @@
 
 	bands = hw->wiphy->bands;
 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
-		if (!bands[band])
+		if (!(ar->mac.sbands[band].channels && bands[band]))
 			continue;
 
 		for (i = 0; i < bands[band]->n_channels; i++) {
@@ -129,7 +129,7 @@
 	ch = arg->channel;
 
 	for (band = 0; band < NUM_NL80211_BANDS; band++) {
-		if (!bands[band])
+		if (!(ar->mac.sbands[band].channels && bands[band]))
 			continue;
 
 		for (i = 0; i < bands[band]->n_channels; i++) {
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/wmi.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/wmi.c
@@ -228,6 +228,9 @@
 	config->peer_map_unmap_version = 0x32;
 	config->twt_ap_pdev_count = ab->num_radios;
 	config->twt_ap_sta_count = 1000;
+	config->ema_max_vap_cnt = ab->num_radios;
+	config->ema_max_profile_period = TARGET_EMA_MAX_PROFILE_PERIOD;
+	config->beacon_tx_offload_max_vdev += config->ema_max_vap_cnt;
 }
 
 void ath12k_wmi_init_wcn7850(struct ath12k_base *ab,
@@ -1503,6 +1506,7 @@
 	cmd->tlv_header = ath12k_wmi_tlv_cmd_hdr(WMI_TAG_PDEV_BSS_CHAN_INFO_REQUEST,
 						 sizeof(*cmd));
 	cmd->req_type = cpu_to_le32(type);
+	cmd->pdev_id = cpu_to_le32(ar->pdev->pdev_id);
 
 	ath12k_dbg(ar->ab, ATH12K_DBG_WMI,
 		   "WMI bss chan info req type %d\n", type);
@@ -1836,7 +1840,7 @@
 		if (arg->bw_160)
 			cmd->peer_flags |= cpu_to_le32(WMI_PEER_160MHZ);
 		if (arg->bw_320)
-			cmd->peer_flags |= cpu_to_le32(WMI_PEER_EXT_320MHZ);
+			cmd->peer_flags_ext |= cpu_to_le32(WMI_PEER_EXT_320MHZ);
 
 		/* Typically if STBC is enabled for VHT it should be enabled
 		 * for HT as well
@@ -3267,6 +3271,9 @@
 	wmi_cfg->twt_ap_sta_count = cpu_to_le32(tg_cfg->twt_ap_sta_count);
 	wmi_cfg->host_service_flags = cpu_to_le32(tg_cfg->is_reg_cc_ext_event_supported <<
 				WMI_RSRC_CFG_HOST_SVC_FLAG_REG_CC_EXT_SUPPORT_BIT);
+	wmi_cfg->ema_max_vap_cnt = cpu_to_le32(tg_cfg->ema_max_vap_cnt);
+	wmi_cfg->ema_max_profile_period = cpu_to_le32(tg_cfg->ema_max_profile_period);
+	wmi_cfg->flags2 |= cpu_to_le32(WMI_RSRC_CFG_FLAGS2_CALC_NEXT_DTIM_COUNT_SET);
 }
 
 static int ath12k_init_cmd_send(struct ath12k_wmi_pdev *wmi,
@@ -5799,8 +5806,10 @@
 	if (rx_ev.status & WMI_RX_STATUS_ERR_MIC)
 		status->flag |= RX_FLAG_MMIC_ERROR;
 
-	if (rx_ev.chan_freq >= ATH12K_MIN_6G_FREQ) {
+	if (rx_ev.chan_freq >= ATH12K_MIN_6G_FREQ &&
+	    rx_ev.chan_freq <= ATH12K_MAX_6G_FREQ) {
 		status->band = NL80211_BAND_6GHZ;
+		status->freq = rx_ev.chan_freq;
 	} else if (rx_ev.channel >= 1 && rx_ev.channel <= 14) {
 		status->band = NL80211_BAND_2GHZ;
 	} else if (rx_ev.channel >= 36 && rx_ev.channel <= ATH12K_MAX_5G_CHAN) {
@@ -5821,8 +5830,10 @@
 
 	sband = &ar->mac.sbands[status->band];
 
-	status->freq = ieee80211_channel_to_frequency(rx_ev.channel,
-						      status->band);
+	if (status->band != NL80211_BAND_6GHZ)
+		status->freq = ieee80211_channel_to_frequency(rx_ev.channel,
+							      status->band);
+
 	status->signal = rx_ev.snr + ATH12K_DEFAULT_NOISE_FLOOR;
 	status->rate_idx = ath12k_mac_bitrate_to_idx(sband, rx_ev.rate / 100);
 
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath12k/wmi.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath12k/wmi.h
@@ -2350,6 +2350,8 @@
 	u32 twt_ap_pdev_count;
 	u32 twt_ap_sta_count;
 	bool is_reg_cc_ext_event_supported;
+	u32 ema_max_vap_cnt;
+	u32 ema_max_profile_period;
 };
 
 struct ath12k_wmi_init_cmd_arg {
@@ -2402,6 +2404,7 @@
 } __packed;
 
 #define WMI_RSRC_CFG_HOST_SVC_FLAG_REG_CC_EXT_SUPPORT_BIT 4
+#define WMI_RSRC_CFG_FLAGS2_CALC_NEXT_DTIM_COUNT_SET      BIT(9)
 
 struct ath12k_wmi_resource_config_params {
 	__le32 tlv_header;
@@ -3064,6 +3067,7 @@
 	__le32 tlv_header;
 	/* ref wmi_bss_chan_info_req_type */
 	__le32 req_type;
+	__le32 pdev_id;
 } __packed;
 
 struct wmi_ap_ps_peer_cmd {
@@ -4014,7 +4018,6 @@
 } __packed;
 
 struct wmi_pdev_bss_chan_info_event {
-	__le32 pdev_id;
 	__le32 freq;	/* Units in MHz */
 	__le32 noise_floor;	/* units are dBm */
 	/* rx clear - how often the channel was unused */
@@ -4032,6 +4035,7 @@
 	/*rx_cycle cnt for my bss in 64bits format */
 	__le32 rx_bss_cycle_count_low;
 	__le32 rx_bss_cycle_count_high;
+	__le32 pdev_id;
 } __packed;
 
 #define WMI_VDEV_INSTALL_KEY_COMPL_STATUS_SUCCESS 0
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath5k/pci.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath5k/pci.c
@@ -46,6 +46,8 @@
 	{ PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
 	{ PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
 	{ PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
+	{ PCI_VDEVICE(ATHEROS, 0xff16) }, /* Gigaset SX76[23] AR241[34]A */
+	{ PCI_VDEVICE(ATHEROS, 0xff1a) }, /* Arcadyan ARV45XX AR2417 */
 	{ PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */
 	{ 0 }
 };
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath9k/antenna.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath9k/antenna.c
@@ -643,7 +643,7 @@
 				conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
 				conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
 			} else if (antcomb->rssi_sub >
-				   antcomb->rssi_lna1) {
+				   antcomb->rssi_lna2) {
 				/* set to A-B */
 				conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
 				conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath9k/debug.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath9k/debug.c
@@ -1325,11 +1325,11 @@
 	struct ath_softc *sc = hw->priv;
 	int i = 0;
 
-	data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all +
+	data[i++] = ((u64)sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all +
 		     sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_pkts_all +
 		     sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_pkts_all +
 		     sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_pkts_all);
-	data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all +
+	data[i++] = ((u64)sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all +
 		     sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_bytes_all +
 		     sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_bytes_all +
 		     sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_bytes_all);
@@ -1380,8 +1380,6 @@
 
 	sc->debug.debugfs_phy = debugfs_create_dir("ath9k",
 						   sc->hw->wiphy->debugfsdir);
-	if (IS_ERR(sc->debug.debugfs_phy))
-		return -ENOMEM;
 
 #ifdef CONFIG_ATH_DEBUG
 	debugfs_create_file("debug", 0600, sc->debug.debugfs_phy,
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -716,8 +716,7 @@
 	}
 
 resubmit:
-	skb_reset_tail_pointer(skb);
-	skb_trim(skb, 0);
+	__skb_set_length(skb, 0);
 
 	usb_anchor_urb(urb, &hif_dev->rx_submitted);
 	ret = usb_submit_urb(urb, GFP_ATOMIC);
@@ -754,8 +753,7 @@
 	case -ESHUTDOWN:
 		goto free_skb;
 	default:
-		skb_reset_tail_pointer(skb);
-		skb_trim(skb, 0);
+		__skb_set_length(skb, 0);
 
 		goto resubmit;
 	}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath9k/htc.h
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath9k/htc.h
@@ -306,7 +306,6 @@
 	DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM);
 	struct timer_list cleanup_timer;
 	spinlock_t tx_lock;
-	bool initialized;
 };
 
 struct ath9k_htc_tx_ctl {
@@ -515,6 +514,7 @@
 	unsigned long ps_usecount;
 	bool ps_enabled;
 	bool ps_idle;
+	bool initialized;
 
 #ifdef CONFIG_MAC80211_LEDS
 	enum led_brightness brightness;
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -486,8 +486,6 @@
 
 	priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME,
 					     priv->hw->wiphy->debugfsdir);
-	if (IS_ERR(priv->debug.debugfs_phy))
-		return -ENOMEM;
 
 	ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy);
 
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -966,6 +966,10 @@
 
 	htc_handle->drv_priv = priv;
 
+	/* Allow ath9k_wmi_event_tasklet() to operate. */
+	smp_wmb();
+	priv->initialized = true;
+
 	return 0;
 
 err_init:
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -815,10 +815,6 @@
 	skb_queue_head_init(&priv->tx.data_vo_queue);
 	skb_queue_head_init(&priv->tx.tx_failed);
 
-	/* Allow ath9k_wmi_event_tasklet(WMI_TXSTATUS_EVENTID) to operate. */
-	smp_wmb();
-	priv->tx.initialized = true;
-
 	return 0;
 }
 
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath9k/htc_hst.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -294,6 +294,9 @@
 		return -ETIMEDOUT;
 	}
 
+	if (target->conn_rsp_epid < 0 || target->conn_rsp_epid >= ENDPOINT_MAX)
+		return -EINVAL;
+
 	*conn_rsp_epid = target->conn_rsp_epid;
 	return 0;
 err:
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath9k/main.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath9k/main.c
@@ -135,8 +135,7 @@
 	if (power_mode != ATH9K_PM_AWAKE) {
 		spin_lock(&common->cc_lock);
 		ath_hw_cycle_counters_update(common);
-		memset(&common->cc_survey, 0, sizeof(common->cc_survey));
-		memset(&common->cc_ani, 0, sizeof(common->cc_ani));
+		memset(&common->cc, 0, sizeof(common->cc));
 		spin_unlock(&common->cc_lock);
 	}
 
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/ath9k/wmi.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/ath9k/wmi.c
@@ -155,6 +155,12 @@
 		}
 		spin_unlock_irqrestore(&wmi->wmi_lock, flags);
 
+		/* Check if ath9k_htc_probe_device() completed. */
+		if (!data_race(priv->initialized)) {
+			kfree_skb(skb);
+			continue;
+		}
+
 		hdr = (struct wmi_cmd_hdr *) skb->data;
 		cmd_id = be16_to_cpu(hdr->command_id);
 		wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
@@ -169,10 +175,6 @@
 					     &wmi->drv_priv->fatal_work);
 			break;
 		case WMI_TXSTATUS_EVENTID:
-			/* Check if ath9k_tx_init() completed. */
-			if (!data_race(priv->tx.initialized))
-				break;
-
 			spin_lock_bh(&priv->tx.tx_lock);
 			if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
 				spin_unlock_bh(&priv->tx.tx_lock);
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/carl9170/tx.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/carl9170/tx.c
@@ -280,7 +280,8 @@
 	 * carl9170_tx_fill_rateinfo() has filled the rate information
 	 * before we get to this point.
 	 */
-	memset_after(&txinfo->status, 0, rates);
+	memset(&txinfo->pad, 0, sizeof(txinfo->pad));
+	memset(&txinfo->rate_driver_data, 0, sizeof(txinfo->rate_driver_data));
 
 	if (atomic_read(&ar->tx_total_queued))
 		ar->tx_schedule = true;
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/carl9170/usb.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/carl9170/usb.c
@@ -1069,6 +1069,38 @@
 			ar->usb_ep_cmd_is_bulk = true;
 	}
 
+	/* Verify that all expected endpoints are present */
+	if (ar->usb_ep_cmd_is_bulk) {
+		u8 bulk_ep_addr[] = {
+			AR9170_USB_EP_RX | USB_DIR_IN,
+			AR9170_USB_EP_TX | USB_DIR_OUT,
+			AR9170_USB_EP_CMD | USB_DIR_OUT,
+			0};
+		u8 int_ep_addr[] = {
+			AR9170_USB_EP_IRQ | USB_DIR_IN,
+			0};
+		if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) ||
+		    !usb_check_int_endpoints(intf, int_ep_addr))
+			err = -ENODEV;
+	} else {
+		u8 bulk_ep_addr[] = {
+			AR9170_USB_EP_RX | USB_DIR_IN,
+			AR9170_USB_EP_TX | USB_DIR_OUT,
+			0};
+		u8 int_ep_addr[] = {
+			AR9170_USB_EP_IRQ | USB_DIR_IN,
+			AR9170_USB_EP_CMD | USB_DIR_OUT,
+			0};
+		if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) ||
+		    !usb_check_int_endpoints(intf, int_ep_addr))
+			err = -ENODEV;
+	}
+
+	if (err) {
+		carl9170_free(ar);
+		return err;
+	}
+
 	usb_set_intfdata(intf, ar);
 	SET_IEEE80211_DEV(ar->hw, &intf->dev);
 
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/wcn36xx/main.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1586,7 +1586,10 @@
 	}
 
 	n_channels = wcn_band_2ghz.n_channels + wcn_band_5ghz.n_channels;
-	wcn->chan_survey = devm_kmalloc(wcn->dev, n_channels, GFP_KERNEL);
+	wcn->chan_survey = devm_kcalloc(wcn->dev,
+					n_channels,
+					sizeof(struct wcn36xx_chan_survey),
+					GFP_KERNEL);
 	if (!wcn->chan_survey) {
 		ret = -ENOMEM;
 		goto out_wq;
--- linux-qcom-6.8.0.orig/drivers/net/wireless/ath/wil6210/txrx.c
+++ linux-qcom-6.8.0/drivers/net/wireless/ath/wil6210/txrx.c
@@ -306,7 +306,7 @@
 				       struct sk_buff *skb)
 {
 	struct wil6210_rtap {
-		struct ieee80211_radiotap_header rthdr;
+		struct ieee80211_radiotap_header_fixed rthdr;
 		/* fields should be in the order of bits in rthdr.it_present */
 		/* flags */
 		u8 flags;
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/Kconfig
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/Kconfig
@@ -0,0 +1,114 @@
+#
+# Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+#
+# This software is licensed to you under the terms of the
+# GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+#
+# INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+# EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+# AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+# IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+# AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+# DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+# SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+# EXCEED ONE HUNDRED U.S. DOLLARS
+#
+# Copyright (C) 2024, Broadcom.
+#
+#      Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed to you
+# under the terms of the GNU General Public License version 2 (the "GPL"),
+# available at http://www.broadcom.com/licenses/GPLv2.php, with the
+# following added to such license:
+#
+#      As a special exception, the copyright holders of this software give you
+# permission to link this software with independent modules, and to copy and
+# distribute the resulting executable under terms of your choice, provided that
+# you also meet, for each linked independent module, the terms and conditions of
+# the license of that module.  An independent module is a module which is not
+# derived from this software.  The special exception does not apply to any
+# modifications of the software.
+#
+#
+# <<Broadcom-WL-IPTag/Open:>>
+#
+
+config WLAN_VENDOR_BCMDHD
+	bool "BCMDHD devices"
+	default y
+	help
+	  If you have a wireless card belonging to this class, say Y.
+
+	  Note that the answer to this question doesn't directly affect the
+	  kernel: saying N will just cause the configurator to skip all the
+	  questions about these cards. If you say Y, you will be asked for
+	  your specific card in the following questions.
+
+if WLAN_VENDOR_BCMDHD
+config BCMDHD
+	tristate "Broadcom FullMAC wireless cards support"
+#	default m
+	help
+	  This module adds support for wireless adapters based on
+	  Broadcom FullMAC chipset.
+
+config BCMDHD_FW_PATH
+	depends on BCMDHD
+	string "Firmware path"
+	default "/lib/firmware/fw_bcmdhd.bin"
+	help
+	  Path to the firmware file.
+
+config BCMDHD_NVRAM_PATH
+	depends on BCMDHD
+	string "NVRAM path"
+	default "/lib/firmware/nvram.txt"
+	help
+	  Path to the calibration file.
+
+config BCMDHD_WEXT
+	bool "Enable WEXT support"
+	depends on BCMDHD && CFG80211 = n
+	select WIRELESS_EXT
+	select WEXT_PRIV
+	help
+	  Enables WEXT support
+
+choice
+	prompt "Enable Chip Interface"
+	depends on BCMDHD
+	help
+		Enable Chip Interface.
+config BCMDHD_SDIO
+		bool "SDIO bus interface support"
+		depends on BCMDHD && MMC
+config BCMDHD_PCIE
+		bool "PCIe bus interface support"
+		depends on BCMDHD && PCI
+config BCMDHD_USB
+		bool "USB bus interface support"
+		depends on BCMDHD && USB
+endchoice
+
+choice
+	depends on BCMDHD && BCMDHD_SDIO
+	prompt "Interrupt type"
+	help
+		Interrupt type
+config BCMDHD_OOB
+	depends on BCMDHD && BCMDHD_SDIO
+	bool "Out-of-Band Interrupt"
+	help
+		Interrupt from WL_HOST_WAKE.
+config BCMDHD_SDIO_IRQ
+	depends on BCMDHD && BCMDHD_SDIO
+	bool "In-Band Interrupt"
+	help
+	  Interrupt from SDIO DAT[1]
+endchoice
+endif # WLAN_VENDOR_BCMDHD
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/Makefile
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/Makefile
@@ -0,0 +1,515 @@
+# bcmdhd
+#
+# Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+#
+# This software is licensed to you under the terms of the
+# GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+#
+# INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+# EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+# AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+# IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+# AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+# DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+# SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+# EXCEED ONE HUNDRED U.S. DOLLARS
+#
+# Copyright (C) 2024, Broadcom.
+#
+#      Unless you and Broadcom execute a separate written software license
+# agreement governing use of this software, this software is licensed to you
+# under the terms of the GNU General Public License version 2 (the "GPL"),
+# available at http://www.broadcom.com/licenses/GPLv2.php, with the
+# following added to such license:
+#
+#      As a special exception, the copyright holders of this software give you
+# permission to link this software with independent modules, and to copy and
+# distribute the resulting executable under terms of your choice, provided that
+# you also meet, for each linked independent module, the terms and conditions of
+# the license of that module.  An independent module is a module which is not
+# derived from this software.  The special exception does not apply to any
+# modifications of the software.
+#
+#
+# <<Broadcom-WL-IPTag/Open:>>
+#
+
+MODULE_NAME := bcmdhd
+CONFIG_BCMDHD ?= m
+
+#CONFIG_BCMDHD_SDIO := y
+#CONFIG_BCMDHD_PCIE := y
+#CONFIG_BCMDHD_USB := y
+
+CONFIG_BCMDHD_OOB := y
+#CONFIG_BCMDHD_CUSB := y
+#CONFIG_BCMDHD_NO_POWER_OFF := y
+CONFIG_BCMDHD_PROPTXSTATUS := y
+CONFIG_DHD_USE_STATIC_BUF := y
+CONFIG_BCMDHD_STATIC_BUF_IN_DHD := y
+#CONFIG_BCMDHD_STATIC_BUF_IN_KERNEL := y
+CONFIG_BCMDHD_ANDROID_VERSION := 13
+CONFIG_BCMDHD_AUTO_SELECT := y
+CONFIG_BCMDHD_DEBUG := y
+#CONFIG_BCMDHD_RECONNECT := y
+#CONFIG_BCMDHD_TIMESTAMP := y
+#CONFIG_BCMDHD_WAPI := y
+#CONFIG_BCMDHD_REQUEST_FW := y
+#CONFIG_BCMDHD_FW_SIGNATURE := y
+#CONFIG_BCMDHD_DWDS := y
+
+#CONFIG_BCMDHD_MULTIPLE_DRIVER := y
+#CONFIG_BCMDHD_ADAPTER_INDEX ?= 0
+
+CONFIG_MACH_PLATFORM := y
+CONFIG_BCMDHD_DTS := y
+
+DHDCFLAGS = -Wall -Wstrict-prototypes -Wno-date-time                      \
+	-Wno-uninitialized                                              \
+	-Dlinux -DLINUX -DBCMDRIVER -DBCMUTILS_ERR_CODES                      \
+	-DBCMDONGLEHOST -DBCMDMA32 -DBCMFILEIMAGE                             \
+	-DDHDTHREAD -DDHD_DEBUG -DSHOW_EVENTS -DGET_OTP_MAC_ENABLE            \
+	-DWIFI_ACT_FRAME -DARP_OFFLOAD_SUPPORT -DSUPPORT_PM2_ONLY             \
+	-DPKTPRIO_OVERRIDE                                                    \
+	-DKEEP_ALIVE -DPKT_FILTER_SUPPORT -DDHDTCPACK_SUPPRESS                \
+	-DDHD_DONOT_FORWARD_BCMEVENT_AS_NETWORK_PKT -DOEM_ANDROID             \
+	-DMULTIPLE_SUPPLICANT -DTSQ_MULTIPLIER=10 -DMFP -DDHD_8021X_DUMP      \
+	-DPOWERUP_MAX_RETRY=1 -DIFACE_HANG_FORCE_DEV_CLOSE -DWAIT_DEQUEUE     \
+	-DUSE_NEW_RSPEC_DEFS                                                  \
+	-DWL_EXT_IAPSTA -DWL_ESCAN -DCCODE_LIST -DSUSPEND_EVENT               \
+	-DKEY_INSTALL_CHECK                                                   \
+	-DENABLE_INSMOD_NO_FW_LOAD
+
+DHDOFILES = aiutils.o siutils.o sbutils.o hndpmu.o hndjtag.o              \
+	bcmutils.o bcmwifi_channels.o bcmxtlv.o bcm_app_utils.o bcmstdlib_s.o \
+	dhd_linux.o dhd_linux_platdev.o dhd_linux_sched.o dhd_pno.o           \
+	dhd_common.o dhd_ip.o dhd_linux_wq.o dhd_custom_gpio.o                \
+	bcmevent.o linux_osl.o wldev_common.o wl_android.o                    \
+	dhd_debug_linux.o dhd_debug.o dhd_mschdbg.o dhd_dbg_ring.o            \
+	hnd_pktq.o hnd_pktpool.o linux_pkt.o frag.o                           \
+	dhd_linux_exportfs.o dhd_linux_pktdump.o dhd_mschdbg.o linuxerrmap.o  \
+	dhd_linux_tx.o dhd_linux_rx.o fwpkg_utils.o                           \
+	dhd_config.o dhd_ccode.o wl_event.o wl_android_ext.o                  \
+	wl_iapsta.o wl_escan.o wl_timer.o
+
+ifneq ($(CONFIG_WIRELESS_EXT),)
+	DHDOFILES += wl_iw.o
+	DHDCFLAGS += -DSOFTAP -DWL_WIRELESS_EXT -DUSE_IW
+endif
+ifneq ($(CONFIG_CFG80211),)
+	DHDOFILES += wl_cfg80211.o wl_cfgscan.o wl_cfgp2p.o
+	DHDOFILES += wl_linux_mon.o wl_cfg_btcoex.o wl_cfgvendor.o
+	DHDOFILES += dhd_cfg80211.o wl_cfgvif.o wl_roam.o
+	DHDCFLAGS += -DWL_CFG80211 -DWLP2P -DWL_CFG80211_STA_EVENT
+	DHDCFLAGS += -DWL_CFG80211_GON_COLLISION
+#	DHDCFLAGS += -DCFG80211_INFO_CHANDEF
+#	DHDCFLAGS += -DAP_P2P_CONCURRENT
+	DHDCFLAGS += -DCONFIG_CFG80211_INTERNAL_REGDB #-DEXT_REG_INFO
+	DHDCFLAGS += -DWL_CAP_HE -DWL_6G_BAND -DWL_5P9G -DWL_P2P_6G
+	DHDCFLAGS += -DWL11U
+#	DHDCFLAGS += -DCONFIG_6GHZ_BKPORT
+	DHDCFLAGS += -DWL_IFACE_COMB_NUM_CHANNELS
+	DHDCFLAGS += -DCUSTOM_PNO_EVENT_LOCK_xTIME=10
+	DHDCFLAGS += -DWL_SUPPORT_BACKPORTED_KPATCHES
+	DHDCFLAGS += -DESCAN_RESULT_PATCH -DESCAN_BUF_OVERFLOW_MGMT
+	DHDCFLAGS += -DVSDB -DWL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
+	DHDCFLAGS += -DWLTDLS -DMIRACAST_AMPDU_SIZE=8
+	DHDCFLAGS += -DHOSTAPD_BW_SUPPORT
+	DHDCFLAGS += -DWL_VIRTUAL_APSTA -DSOFTAP_UAPSD_OFF #-DSTA_MGMT
+	DHDCFLAGS += -DWL_SUPPORT_AUTO_CHANNEL -DWL_SOFTAP_ACS #-DACS_MONITOR
+#	DHDCFLAGS += -DDHD_DFS_MASTER
+	DHDCFLAGS += -DNUM_SCB_MAX_PROBE=3
+	DHDCFLAGS += -DWL_SCB_TIMEOUT=10
+#	DHDCFLAGS += -DWL_BEACON_RATE
+	DHDCFLAGS += -DEXPLICIT_DISCIF_CLEANUP
+	DHDCFLAGS += -DDHD_USE_SCAN_WAKELOCK #DHD_DEBUG_SCAN_WAKELOCK
+	DHDCFLAGS += -DSPECIFIC_MAC_GEN_SCHEME
+	DHDCFLAGS += -DWL_IFACE_MGMT
+	DHDCFLAGS += -DSUPPORT_RSSI_SUM_REPORT
+	DHDCFLAGS += -DWLFBT -DWL_GCMP_SUPPORT -DWL_OWE -DWL_SAE_FT
+	DHDCFLAGS += -DROAM_CHANNEL_CACHE -DDHD_LOSSLESS_ROAMING
+#	DHDCFLAGS += -DWL_SKIP_CONNECT_HINTS
+#	DHDCFLAGS += -DWL_CFGVENDOR_SEND_HANG_EVENT
+	DHDCFLAGS += -DGTK_OFFLOAD_SUPPORT
+	DHDCFLAGS += -DWL_STATIC_IF #-DDHD_MAX_STATIC_IFS=2
+#	DHDCFLAGS += -DWL_STATIC_IFNAME_PREFIX=\"sap%d\"
+	DHDCFLAGS += -DWL_CLIENT_SAE
+	DHDCFLAGS += -DCONNECT_INFO_WAR -DWL_ROAM_WAR
+	DHDCFLAGS += -DVNDR_IE_WAR
+	DHDCFLAGS += -DRESTART_AP_WAR -DRXF0OVFL_REINIT_WAR
+endif
+
+#BCMDHD_SDIO
+ifneq ($(CONFIG_BCMDHD_SDIO),)
+BUS_TYPE := sdio
+DHDCFLAGS += -DBCMSDIO -DMMC_SDIO_ABORT -DUSE_SDIOFIFO_IOVAR -DBCMLXSDMMC \
+	-DSDTEST -DBDC -DDHD_USE_IDLECOUNT -DCUSTOM_SDIO_F2_BLKSIZE=256       \
+	-DBCMSDIOH_TXGLOM -DDHD_SI_WD_RESET -DBCMSDIOH_STATIC_COPY_BUF        \
+	-DRXFRAME_THREAD -DDHDENABLE_TAILPAD -DSUPPORT_P2P_GO_PS              \
+	-DBCMSDIO_RXLIM_POST -DBCMSDIO_TXSEQ_SYNC -DCONSOLE_DPC               \
+	-DBCMSDIO_INTSTATUS_WAR
+DHDCFLAGS += -DMMC_HW_RESET -DMMC_SW_RESET #-DBUS_POWER_RESTORE
+#DHDCFLAGS += -DDEVICE_PM_CALLBACK
+ifeq ($(CONFIG_BCMDHD_OOB),y)
+	DHDCFLAGS += -DOOB_INTR_ONLY -DCUSTOMER_OOB -DHW_OOB
+ifeq ($(CONFIG_BCMDHD_DISABLE_WOWLAN),y)
+	DHDCFLAGS += -DDISABLE_WOWLAN
+endif
+else
+	DHDCFLAGS += -DSDIO_ISR_THREAD
+endif
+DHDOFILES += bcmsdh.o bcmsdh_linux.o bcmsdh_sdmmc.o bcmsdh_sdmmc_linux.o  \
+	dhd_sdio.o dhd_cdc.o dhd_wlfc.o
+endif
+
+#BCMDHD_PCIE
+ifneq ($(CONFIG_BCMDHD_PCIE),)
+BUS_TYPE := pcie
+	DHDCFLAGS += -DPCIE_FULL_DONGLE -DBCMPCIE -DCUSTOM_DPC_PRIO_SETTING=-1
+	DHDCFLAGS += -DDONGLE_ENABLE_ISOLATION
+	DHDCFLAGS += -DDHD_LB -DDHD_LB_RXP -DDHD_LB_STATS -DDHD_LB_TXP
+	DHDCFLAGS += -DDHD_LB_PRIMARY_CPUS=0xF0 -DDHD_LB_SECONDARY_CPUS=0x0E
+	DHDCFLAGS += -DDHD_PKTID_AUDIT_ENABLED
+	DHDCFLAGS += -DBCMPCIE_CTO_PREVENTION
+	DHDCFLAGS += -DEAPOL_PKT_PRIO -DENABLE_DHD_GRO
+	DHDCFLAGS += -DDHD_SKIP_DONGLE_RESET_IN_ATTACH
+	DHDCFLAGS += -DDHD_DONGLE_TRAP_IN_DETACH
+	DHDCFLAGS += -DFORCE_DONGLE_RESET_IN_DEVRESET_ON
+	DHDCFLAGS += -DDHD_USE_COHERENT_MEM_FOR_RING
+	DHDCFLAGS += -DCHECK_TRAP_ROT
+	DHDCFLAGS += -DINSMOD_FW_LOAD
+	DHDCFLAGS += -DCONFIG_HAS_WAKELOCK #-DDHD_DEBUG_WAKE_LOCK
+	DHDCFLAGS += -DDHD_PACKET_TIMEOUT_MS=50 -DMAX_TX_TIMEOUT=50
+#	DHDCFLAGS += -DRMMOD_POWER_DOWN_LATER -DPCIE_ATU_FIXUP
+#	DHDCFLAGS += -DDEVICE_PM_CALLBACK
+ifeq ($(CONFIG_BCMDHD),y)
+	DHDCFLAGS += -DWAKEUP_KSOFTIRQD_POST_NAPI_SCHEDULE
+endif
+ifeq ($(CONFIG_BCMDHD_OOB),y)
+	DHDCFLAGS += -DCUSTOMER_OOB -DBCMPCIE_OOB_HOST_WAKE -DHW_OOB
+endif
+ifneq ($(CONFIG_PCI_MSI),)
+	DHDCFLAGS += -DDHD_MSI_SUPPORT
+endif
+DHDOFILES += dhd_pcie.o dhd_pcie_linux.o pcie_core.o dhd_flowring.o       \
+	dhd_msgbuf.o dhd_linux_lb.o
+endif
+
+#BCMDHD_USB
+ifneq ($(CONFIG_BCMDHD_USB),)
+BUS_TYPE := usb
+DHDCFLAGS += -DUSBOS_TX_THREAD -DBCMDBUS -DBCMTRXV2 -DDBUS_USB_LOOPBACK   \
+	-DBDC
+DHDCFLAGS += -DINSMOD_FW_LOAD
+DHDCFLAGS += -DBCM_REQUEST_FW
+DHDCFLAGS += -DSHOW_LOGTRACE
+DHDCFLAGS += -DWL_EXT_WOWL
+ifneq ($(CONFIG_BCMDHD_REQUEST_FW),y)
+	DHDCFLAGS += -DEXTERNAL_FW_PATH
+endif
+ifneq ($(CONFIG_BCMDHD_CUSB),)
+	DHDCFLAGS += -DBCMUSBDEV_COMPOSITE
+	CONFIG_BCMDHD_NO_POWER_OFF := y
+endif
+DHDOFILES += dbus.o dbus_usb.o dbus_usb_linux.o dhd_cdc.o dhd_wlfc.o
+endif
+
+ifeq ($(CONFIG_BCMDHD_NO_POWER_OFF),y)
+	DHDCFLAGS += -DENABLE_INSMOD_NO_FW_LOAD
+	DHDCFLAGS += -DENABLE_INSMOD_NO_POWER_OFF -DNO_POWER_OFF_AFTER_OPEN
+endif
+
+ifeq ($(CONFIG_BCMDHD_MULTIPLE_DRIVER),y)
+	DHDCFLAGS += -DBCMDHD_MDRIVER
+ifneq ($(CONFIG_BCMDHD_ADAPTER_INDEX),)
+	MODULE_NAME := dhd$(BUS_TYPE)_$(CONFIG_BCMDHD_ADAPTER_INDEX)
+	DHDCFLAGS += -DADAPTER_IDX=$(CONFIG_BCMDHD_ADAPTER_INDEX)
+	DHDCFLAGS += -DADAPTER_IDX_STR=\"_$(CONFIG_BCMDHD_ADAPTER_INDEX)\"
+	DHDCFLAGS += -DBUS_TYPE=\"_$(BUS_TYPE)-$(CONFIG_BCMDHD_ADAPTER_INDEX)\"
+	DHDCFLAGS += -DDHD_LOG_PREFIX=\"[dhd-$(BUS_TYPE)-$(CONFIG_BCMDHD_ADAPTER_INDEX)]\"
+else
+	MODULE_NAME := dhd$(BUS_TYPE)
+	DHDCFLAGS += -DADAPTER_IDX_STR=\"_$(BUS_TYPE)\"
+	DHDCFLAGS += -DBUS_TYPE=\"_$(BUS_TYPE)\"
+	DHDCFLAGS += -DDHD_LOG_PREFIX=\"[dhd-$(BUS_TYPE)]\"
+endif
+else
+	DHDCFLAGS += -DADAPTER_IDX_STR=\"\"
+	DHDCFLAGS += -DBUS_TYPE=\"\"
+endif
+
+ifeq ($(CONFIG_BCMDHD_TIMESTAMP),y)
+	DHDCFLAGS += -DKERNEL_TIMESTAMP
+	DHDCFLAGS += -DSYSTEM_TIMESTAMP
+endif
+
+#PROPTXSTATUS
+ifeq ($(CONFIG_BCMDHD_PROPTXSTATUS),y)
+ifneq ($(CONFIG_BCMDHD_USB),)
+	DHDCFLAGS += -DPROP_TXSTATUS
+	DHDCFLAGS += -DLIMIT_BORROW -DBULK_DEQUEUE
+endif
+ifneq ($(CONFIG_BCMDHD_SDIO),)
+	DHDCFLAGS += -DPROP_TXSTATUS -DPROPTX_MAXCOUNT
+	DHDCFLAGS += -DLIMIT_BORROW -DBULK_DEQUEUE
+endif
+ifneq ($(CONFIG_CFG80211),)
+	DHDCFLAGS += -DPROP_TXSTATUS_VSDB
+endif
+endif
+
+ifeq ($(CONFIG_64BIT),y)
+	DHDCFLAGS := $(filter-out -DBCMDMA32,$(DHDCFLAGS))
+	DHDCFLAGS += -DBCMDMA64OSL
+endif
+
+# For Android VTS
+ifneq ($(CONFIG_BCMDHD_ANDROID_VERSION),)
+	DHDCFLAGS += -DANDROID_VERSION=$(CONFIG_BCMDHD_ANDROID_VERSION)
+	DHDCFLAGS += -DDHD_NOTIFY_MAC_CHANGED
+	DHDCFLAGS += -DANDROID_BKPORT
+ifneq ($(CONFIG_CFG80211),)
+	DHDCFLAGS += -DPNO_SUPPORT
+	DHDCFLAGS += -DWL_SCHED_SCAN
+	DHDCFLAGS += -DWL_P2P_RAND
+	DHDCFLAGS += -DGSCAN_SUPPORT -DRTT_SUPPORT
+	DHDCFLAGS += -DLINKSTAT_SUPPORT -DLINKSTAT_EXT_SUPPORT
+	DHDCFLAGS += -DCUSTOM_COUNTRY_CODE -DDHD_GET_VALID_CHANNELS
+	DHDCFLAGS += -DDEBUGABILITY -DDBG_PKT_MON -DDEBUGABILITY_DISABLE_MEMDUMP
+	DHDCFLAGS += -DDHD_LOG_DUMP -DDHD_FW_COREDUMP
+	DHDCFLAGS += -DWIFI_TURNON_USE_HALINIT
+	DHDCFLAGS += -DDHD_PKT_LOGGING_DBGRING -DDHD_PKT_LOGGING
+	DHDCFLAGS += -DAPF -DNDO_CONFIG_SUPPORT -DRSSI_MONITOR_SUPPORT
+	DHDCFLAGS += -DDHD_WAKE_STATUS
+	DHDCFLAGS += -DWL_LATENCY_MODE -DWL_USABLE_CHAN -DWL_SAR_TX_POWER
+	DHDOFILES += dhd_rtt.o
+	DHDOFILES += dhd_log_dump.o
+	DHDOFILES += dhd_pktlog.o
+endif
+else
+	DHDCFLAGS += -DANDROID_VERSION=0
+endif
+
+# For Debug
+ifeq ($(CONFIG_BCMDHD_DEBUG),y)
+	DHDCFLAGS += -DDHD_ARP_DUMP -DDHD_DHCP_DUMP -DDHD_ICMP_DUMP
+	DHDCFLAGS += -DDHD_DNS_DUMP -DDHD_TRX_DUMP
+	DHDCFLAGS += -DTPUT_MONITOR
+#	DHDCFLAGS += -DSCAN_SUPPRESS -DBSSCACHE
+	DHDCFLAGS += -DCHECK_DOWNLOAD_FW
+	DHDCFLAGS += -DPKT_STATICS
+	DHDCFLAGS += -DKSO_DEBUG
+#	DHDCFLAGS += -DDHD_PKTDUMP_TOFW
+#	DHDCFLAGS += -DDHD_DUMP_FILE_WRITE_FROM_KERNEL
+endif
+
+# For Debug2
+ifeq ($(CONFIG_BCMDHD_DEBUG2),y)
+	DHDCFLAGS += -DDEBUGFS_CFG80211
+	DHDCFLAGS += -DSHOW_LOGTRACE -DDHD_LOG_DUMP -DDHD_FW_COREDUMP
+	DHDCFLAGS += -DBCMASSERT_LOG -DSI_ERROR_ENFORCE
+ifneq ($(CONFIG_BCMDHD_PCIE),)
+	DHDCFLAGS += -DEWP_EDL
+	DHDCFLAGS += -DDNGL_EVENT_SUPPORT
+	DHDCFLAGS += -DDHD_SSSR_DUMP
+	DHDCFLAGS += -DDHD_MEM_STATS
+	DHDCFLAGS += -DDHD_FLOW_RING_STATUS_TRACE
+	DHDCFLAGS += -DDNGL_AXI_ERROR_LOGGING
+endif
+	DHDOFILES += dhd_log_dump.o
+endif
+
+# MESH support for kernel 3.10 later
+ifeq ($(CONFIG_BCMDHD_WLMESH),y)
+	DHDCFLAGS += -DWLMESH
+ifneq ($(CONFIG_CFG80211),)
+	DHDCFLAGS += -DWLMESH_CFG80211
+endif
+ifneq ($(CONFIG_BCMDHD_PCIE),)
+	DHDCFLAGS += -DBCM_HOST_BUF -DDMA_HOST_BUFFER_LEN=0x80000
+endif
+	DHDCFLAGS += -DDHD_UPDATE_INTF_MAC
+	DHDCFLAGS :=$(filter-out -DDHD_FW_COREDUMP,$(DHDCFLAGS))
+	DHDCFLAGS :=$(filter-out -DWL_STATIC_IF,$(DHDCFLAGS))
+endif
+
+# EasyMesh
+ifeq ($(CONFIG_BCMDHD_EASYMESH),y)
+	DHDCFLAGS :=$(filter-out -DDHD_FW_COREDUMP,$(DHDCFLAGS))
+	DHDCFLAGS :=$(filter-out -DDHD_LOG_DUMP,$(DHDCFLAGS))
+	DHDCFLAGS += -DWLEASYMESH
+	CONFIG_BCMDHD_DWDS := y
+endif
+
+# DWDS
+ifeq ($(CONFIG_BCMDHD_DWDS),y)
+ifneq ($(CONFIG_CFG80211),)
+	DHDCFLAGS += -DWLDWDS -DFOURADDR_AUTO_BRG
+ifneq ($(CONFIG_BCMDHD_SDIO),)
+	DHDCFLAGS += -DRXF_DEQUEUE_ON_BUSY
+endif
+	DHDCFLAGS += -DWL_STATIC_IF
+endif
+endif
+
+# CSI_SUPPORT
+ifeq ($(CONFIG_CSI_SUPPORT),y)
+	DHDCFLAGS += -DCSI_SUPPORT
+	DHDOFILES += dhd_csi.o
+endif
+
+# For CONNECTION_IMPROVE
+ifeq ($(CONFIG_BCMDHD_RECONNECT),y)
+	DHDCFLAGS += -DEAPOL_RESEND -DEAPOL_RESEND_M4
+ifneq ($(CONFIG_CFG80211),)
+	DHDCFLAGS += -DWL_EXT_RECONNECT -DWL_REASSOC_BCAST
+	DHDCFLAGS += -DWL_EXT_DISCONNECT_RECONNECT
+endif
+endif
+
+# For TPUT_IMPROVE
+ifeq ($(CONFIG_BCMDHD_TPUT),y)
+	DHDCFLAGS += -DDHD_TPUT_PATCH
+	DHDCFLAGS += -DTCPACK_INFO_MAXNUM=40 -DTCPDATA_INFO_MAXNUM=40
+ifneq ($(CONFIG_BCMDHD_SDIO),)
+	DHDCFLAGS += -DDYNAMIC_MAX_HDR_READ
+	DHDCFLAGS :=$(filter-out -DSDTEST,$(DHDCFLAGS))
+endif
+ifneq ($(CONFIG_BCMDHD_PCIE),)
+	DHDCFLAGS += -DDHD_LB_TXP_DEFAULT_ENAB
+	DHDCFLAGS += -DSET_RPS_CPUS -DSET_XPS_CPUS
+	DHDCFLAGS += -DDHD_LB_PRIMARY_CPUS=0xF0 -DDHD_LB_SECONDARY_CPUS=0x0E
+endif
+endif
+
+# For Zero configure
+ifeq ($(CONFIG_BCMDHD_ZEROCONFIG),y)
+	DHDCFLAGS += -DWL_EXT_GENL -DSENDPROB
+	DHDOFILES += wl_ext_genl.o
+endif
+
+# For WAPI
+ifeq ($(CONFIG_BCMDHD_WAPI),y)
+	DHDCFLAGS += -DBCMWAPI_WPI -DBCMWAPI_WAI
+	DHDCFLAGS += -DCFG80211_WAPI_BKPORT
+endif
+
+# For scan random mac
+ifneq ($(CONFIG_BCMDHD_RANDOM_MAC),)
+ifneq ($(CONFIG_CFG80211),)
+	DHDCFLAGS += -DSUPPORT_RANDOM_MAC_SCAN -DWL_USE_RANDOMIZED_SCAN
+endif
+endif
+
+# For NAN
+ifneq ($(CONFIG_BCMDHD_NAN),)
+	DHDCFLAGS += -DWL_NAN -DWL_NAN_DISC_CACHE -DWL_NANP2P -DWL_NAN_ENABLE_MERGE
+	DHDOFILES += wl_cfgnan.o bcmbloom.o
+endif
+
+# For Module auto-selection
+ifeq ($(CONFIG_BCMDHD_AUTO_SELECT),y)
+	DHDCFLAGS += -DUPDATE_MODULE_NAME
+ifeq ($(CONFIG_BCMDHD_REQUEST_FW),y)
+#	DHDCFLAGS += -DFW_AMPAK_PATH="\"ampak\""
+#	DHDCFLAGS += -DMODULE_PATH
+endif
+ifneq ($(CONFIG_BCMDHD_SDIO),)
+	DHDCFLAGS += -DGET_OTP_MODULE_NAME -DCOMPAT_OLD_MODULE
+endif
+endif
+
+ifeq ($(CONFIG_BCMDHD),y)
+	DHDCFLAGS += -DUSE_LATE_INITCALL_SYNC
+	DHDCFLAGS += -DBCM_USE_PLATFORM_STRLCPY
+endif
+ifeq ($(CONFIG_BCMDHD),m)
+	DHDCFLAGS += -DBCMDHD_MODULAR
+	DHDCFLAGS += -DBOARD_MODULAR_INIT
+endif
+
+ifeq ($(CONFIG_MACH_PLATFORM),y)
+	DHDOFILES += dhd_gpio.o
+ifeq ($(CONFIG_BCMDHD_DTS),y)
+	DHDCFLAGS += -DBCMDHD_DTS
+endif
+	DHDCFLAGS += -DCUSTOMER_HW -DDHD_OF_SUPPORT
+endif
+
+ifeq ($(CONFIG_BCMDHD_REQUEST_FW),y)
+	DHDCFLAGS += -DDHD_LINUX_STD_FW_API
+	DHDCFLAGS += -DDHD_REQUEST_FW_PATH
+	DHDCFLAGS += -DDHD_FW_NAME="\"fw_bcmdhd.bin\""
+	DHDCFLAGS += -DDHD_NVRAM_NAME="\"nvram.txt\""
+	DHDCFLAGS += -DDHD_CLM_NAME="\"clm_bcmdhd.blob\""
+	DHDCFLAGS += -DDHD_CONFIG_NAME="\"config.txt\""
+else
+	DHDCFLAGS += -DDHD_SUPPORT_VFS_CALL
+ifeq ($(CONFIG_BCMDHD_FW_PATH),)
+	DHDCFLAGS += -DCONFIG_BCMDHD_FW_PATH="\"/vendor/etc/firmware/fw_bcmdhd.bin\""
+	DHDCFLAGS += -DCONFIG_BCMDHD_NVRAM_PATH="\"/vendor/etc/firmware/nvram.txt\""
+	DHDCFLAGS += -DCONFIG_BCMDHD_CLM_PATH="\"/vendor/etc/firmware/clm_bcmdhd.blob\""
+endif
+	DHDCFLAGS += -DCONFIG_BCMDHD_CONFIG_PATH="\"/vendor/etc/firmware/config.txt\""
+endif
+
+ifeq ($(CONFIG_BCMDHD_FW_SIGNATURE),y)
+	DHDCFLAGS += -DFW_SIGNATURE
+	DHDCFLAGS += -DBL_HEAP_START_GAP_SIZE=0x1000 -DBL_HEAP_SIZE=0x10000
+endif
+
+ifeq ($(CONFIG_DHD_USE_STATIC_BUF),y)
+ifeq ($(CONFIG_BCMDHD_STATIC_BUF_IN_DHD),y)
+	DHDOFILES += dhd_static_buf.o
+	DHDCFLAGS += -DDHD_STATIC_IN_DRIVER
+else ifneq ($(CONFIG_BCMDHD_STATIC_BUF_IN_KERNEL),y)
+	obj-m += dhd_static_buf.o
+endif
+	DHDCFLAGS += -DSTATIC_WL_PRIV_STRUCT -DENHANCED_STATIC_BUF
+	DHDCFLAGS += -DCONFIG_DHD_USE_STATIC_BUF
+ifneq ($(filter -DDHD_LOG_DUMP, $(DHDCFLAGS)),)
+	DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
+endif
+ifneq ($(filter -DDHD_FW_COREDUMP, $(DHDCFLAGS)),)
+	DHDCFLAGS += -DDHD_USE_STATIC_MEMDUMP
+endif
+ifneq ($(CONFIG_BCMDHD_PCIE),)
+	DHDCFLAGS += -DDHD_USE_STATIC_CTRLBUF
+endif
+endif
+
+BCMDHD_ROOT = $(abs_srctree)/drivers/net/wireless/bcmdhd
+#$(warning "BCMDHD_ROOT=$(BCMDHD_ROOT)")
+EXTRA_CFLAGS = $(DHDCFLAGS)
+EXTRA_CFLAGS += -DDHD_COMPILED=\"$(BCMDHD_ROOT)\"
+EXTRA_CFLAGS += -I$(BCMDHD_ROOT)/include -I$(BCMDHD_ROOT)
+ifeq ($(CONFIG_BCMDHD),m)
+EXTRA_LDFLAGS += --strip-debug
+endif
+
+obj-$(CONFIG_BCMDHD) += $(MODULE_NAME).o
+$(MODULE_NAME)-objs += $(DHDOFILES)
+ccflags-y := $(EXTRA_CFLAGS)
+
+all: bcmdhd_pcie bcmdhd_sdio bcmdhd_usb
+
+bcmdhd_pcie:
+	$(warning "building BCMDHD_PCIE..........")
+	$(MAKE) -C $(LINUXDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules CONFIG_BCMDHD=m CONFIG_BCMDHD_PCIE=y
+
+bcmdhd_sdio:
+	$(warning "building BCMDHD_SDIO..........")
+	$(MAKE) -C $(LINUXDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules CONFIG_BCMDHD=m CONFIG_BCMDHD_SDIO=y
+
+bcmdhd_usb:
+	$(warning "building BCMDHD_USB..........")
+	$(MAKE) -C $(LINUXDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules CONFIG_BCMDHD=m CONFIG_BCMDHD_USB=y
+
+clean:
+	rm -rf *.o *.ko *.mod.c *~ .*.cmd *.o.cmd .*.o.cmd *.mod \
+	Module.symvers modules.order .tmp_versions modules.builtin
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/aiutils.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/aiutils.c
@@ -0,0 +1,2641 @@
+/*
+ * Misc utility routines for accessing chip-specific features
+ * of the SiliconBackplane-based Broadcom chips.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Dual:>>
+ */
+
+#include <typedefs.h>
+#include <bcmdefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <siutils.h>
+#include <hndsoc.h>
+#include <sbchipc.h>
+#include <pcicfg.h>
+#include <pcie_core.h>
+
+#include "siutils_priv.h"
+#include <bcmdevs.h>
+
+#if defined(ETD)
+#include <etd.h>
+#endif
+
+#if !defined(BCMDONGLEHOST)
+#define PMU_DMP()  (cores_info->coreid[sii->curidx] == PMU_CORE_ID)
+#define GCI_DMP()  (cores_info->coreid[sii->curidx] == GCI_CORE_ID)
+#else
+#define PMU_DMP() (0)
+#define GCI_DMP() (0)
+#endif /* !defined(BCMDONGLEHOST) */
+
+#if defined(AXI_TIMEOUTS_NIC)
+static bool ai_get_apb_bridge(const si_t *sih, uint32 coreidx, uint32 *apb_id,
+	uint32 *apb_coreunit);
+#endif /* AXI_TIMEOUTS_NIC */
+
+#if defined(AXI_TIMEOUTS) || defined(AXI_TIMEOUTS_NIC)
+static void ai_reset_axi_to(const si_info_t *sii, aidmp_t *ai);
+#endif	/* defined (AXI_TIMEOUTS) || defined (AXI_TIMEOUTS_NIC) */
+
+#ifdef DONGLEBUILD
+static uint32 ai_get_sizeof_wrapper_offsets_to_dump(void);
+static uint32 ai_get_wrapper_base_addr(uint32 **offset);
+#endif /* DONGLEBUILD */
+
+/* AXI ID to CoreID + unit mappings */
+typedef struct axi_to_coreidx {
+	uint coreid;
+	uint coreunit;
+} axi_to_coreidx_t;
+
+static const axi_to_coreidx_t axi2coreidx_4369[] = {
+	{CC_CORE_ID, 0},	/* 00 Chipcommon */
+	{PCIE2_CORE_ID, 0},	/* 01 PCIe */
+	{D11_CORE_ID, 0},	/* 02 D11 Main */
+	{ARMCR4_CORE_ID, 0},	/* 03 ARM */
+	{BT_CORE_ID, 0},	/* 04 BT AHB */
+	{D11_CORE_ID, 1},	/* 05 D11 Aux */
+	{D11_CORE_ID, 0},	/* 06 D11 Main l1 */
+	{D11_CORE_ID, 1},	/* 07 D11 Aux  l1 */
+	{D11_CORE_ID, 0},	/* 08 D11 Main l2 */
+	{D11_CORE_ID, 1},	/* 09 D11 Aux  l2 */
+	{NODEV_CORE_ID, 0},	/* 10 M2M DMA */
+	{NODEV_CORE_ID, 0},	/* 11 unused */
+	{NODEV_CORE_ID, 0},	/* 12 unused */
+	{NODEV_CORE_ID, 0},	/* 13 unused */
+	{NODEV_CORE_ID, 0},	/* 14 unused */
+	{NODEV_CORE_ID, 0}	/* 15 unused */
+};
+
+/* EROM parsing */
+
+static uint32
+get_erom_ent(const si_t *sih, uint32 **eromptr, uint32 mask, uint32 match)
+{
+	uint32 ent;
+	uint inv = 0, nom = 0;
+	uint32 size = 0;
+
+	while (TRUE) {
+		ent = R_REG(SI_INFO(sih)->osh, *eromptr);
+		(*eromptr)++;
+
+		if (mask == 0)
+			break;
+
+		if ((ent & ER_VALID) == 0) {
+			inv++;
+			continue;
+		}
+
+		if (ent == (ER_END | ER_VALID))
+			break;
+
+		if ((ent & mask) == match)
+			break;
+
+		/* escape condition related EROM size if it has invalid values */
+		size += sizeof(*eromptr);
+		if (size >= ER_SZ_MAX) {
+			SI_ERROR(("Failed to find end of EROM marker\n"));
+			break;
+		}
+
+		nom++;
+	}
+
+	SI_VMSG(("get_erom_ent: Returning ent 0x%08x\n", ent));
+	if (inv + nom) {
+		SI_VMSG(("  after %d invalid and %d non-matching entries\n", inv, nom));
+	}
+	return ent;
+}
+
+static uint32
+get_asd(const si_t *sih, uint32 **eromptr, uint sp, uint ad, uint st, uint32 *addrl, uint32 *addrh,
+	uint32 *sizel, uint32 *sizeh)
+{
+	uint32 asd, sz, szd;
+
+	BCM_REFERENCE(ad);
+
+	asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID);
+	if (((asd & ER_TAG1) != ER_ADD) ||
+	    (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) ||
+	    ((asd & AD_ST_MASK) != st)) {
+		/* This is not what we want, "push" it back */
+		(*eromptr)--;
+		return 0;
+	}
+	*addrl = asd & AD_ADDR_MASK;
+	if (asd & AD_AG32)
+		*addrh = get_erom_ent(sih, eromptr, 0, 0);
+	else
+		*addrh = 0;
+	*sizeh = 0;
+	sz = asd & AD_SZ_MASK;
+	if (sz == AD_SZ_SZD) {
+		szd = get_erom_ent(sih, eromptr, 0, 0);
+		*sizel = szd & SD_SZ_MASK;
+		if (szd & SD_SG32)
+			*sizeh = get_erom_ent(sih, eromptr, 0, 0);
+	} else
+		*sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT);
+
+	SI_VMSG(("  SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n",
+	        sp, ad, st, *sizeh, *sizel, *addrh, *addrl));
+
+	return asd;
+}
+
+/* Parse the enumeration rom to identify all cores */
+void
+ai_scan(si_t *sih, void *regs, uint devid)
+{
+	si_info_t *sii = SI_INFO(sih);
+	si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
+	chipcregs_t *cc = (chipcregs_t *)regs;
+	uint32 erombase, *eromptr, *eromlim;
+	axi_wrapper_t * axi_wrapper = sii->axi_wrapper;
+
+	SI_MSG_DBG_REG(("%s: Enter\n", __FUNCTION__));
+	BCM_REFERENCE(devid);
+
+	erombase = R_REG(sii->osh, &cc->eromptr);
+
+	switch (BUSTYPE(sih->bustype)) {
+	case SI_BUS:
+		eromptr = (uint32 *)REG_MAP(erombase, SI_CORE_SIZE);
+		break;
+
+	case PCI_BUS:
+		/* Set wrappers address */
+		sii->curwrap = (void *)((uintptr)regs + SI_CORE_SIZE);
+
+		/* Now point the window at the erom */
+		OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, erombase);
+		eromptr = regs;
+		break;
+
+#ifdef BCMSDIO
+	case SPI_BUS:
+	case SDIO_BUS:
+		eromptr = (uint32 *)(uintptr)erombase;
+		break;
+#endif	/* BCMSDIO */
+
+	default:
+		SI_ERROR(("Don't know how to do AXI enumeration on bus %d\n", sih->bustype));
+		ASSERT(0);
+		return;
+	}
+	eromlim = eromptr + (ER_REMAPCONTROL / sizeof(uint32));
+	sii->axi_num_wrappers = 0;
+
+	SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n",
+	         OSL_OBFUSCATE_BUF(regs), erombase,
+		OSL_OBFUSCATE_BUF(eromptr), OSL_OBFUSCATE_BUF(eromlim)));
+	while (eromptr < eromlim) {
+		uint32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp;
+		uint32 mpd, asd, addrl, addrh, sizel, sizeh;
+		uint i, j, idx;
+		bool br;
+
+		br = FALSE;
+
+		/* Grok a component */
+		cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI);
+		if (cia == (ER_END | ER_VALID)) {
+			SI_VMSG(("Found END of erom after %d cores\n", sii->numcores));
+			SI_MSG_DBG_REG(("%s: Exit\n", __FUNCTION__));
+			return;
+		}
+
+		cib = get_erom_ent(sih, &eromptr, 0, 0);
+
+		if ((cib & ER_TAG) != ER_CI) {
+			SI_ERROR(("CIA not followed by CIB\n"));
+			goto error;
+		}
+
+		cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT;
+		mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
+		crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
+		nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT;
+		nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT;
+		nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT;
+		nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT;
+
+#ifdef BCMDBG_SI
+		SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, "
+		         "nsw = %d, nmp = %d & nsp = %d\n",
+		         mfg, cid, crev, OSL_OBFUSCATE_BUF(eromptr - 1), nmw, nsw, nmp, nsp));
+#else
+		BCM_REFERENCE(crev);
+#endif
+
+		/* Include Default slave wrapper for timeout monitoring */
+		if ((nsp == 0 && nsw == 0) ||
+#if !defined(AXI_TIMEOUTS) && !defined(AXI_TIMEOUTS_NIC)
+			((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) ||
+#else
+			((CHIPTYPE(sii->pub.socitype) == SOCI_NAI) &&
+			(mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) ||
+#endif /* !defined(AXI_TIMEOUTS) && !defined(AXI_TIMEOUTS_NIC) */
+			FALSE) {
+			continue;
+		}
+
+		if ((nmw + nsw == 0)) {
+			/* A component which is not a core */
+			/* Should record some info */
+			if (cid == OOB_ROUTER_CORE_ID) {
+				asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE,
+					&addrl, &addrh, &sizel, &sizeh);
+				if (asd != 0) {
+					if ((sii->oob_router != 0) && (sii->oob_router != addrl)) {
+						sii->oob_router1 = addrl;
+					} else {
+						sii->oob_router = addrl;
+					}
+				}
+			}
+			if ((cid != NS_CCB_CORE_ID) && (cid != PMU_CORE_ID) &&
+				(cid != GCI_CORE_ID) && (cid != SR_CORE_ID) &&
+				(cid != HUB_CORE_ID) && (cid != HND_OOBR_CORE_ID) &&
+				(cid != CCI400_CORE_ID) && (cid != SPMI_SLAVE_CORE_ID)) {
+				continue;
+			}
+		}
+
+		idx = sii->numcores;
+
+		cores_info->cia[idx] = cia;
+		cores_info->cib[idx] = cib;
+		cores_info->coreid[idx] = cid;
+
+		/* workaround the fact the variable buscoretype is used in _ai_set_coreidx()
+		 * when checking PCIE_GEN2() for PCI_BUS case before it is setup later...,
+		 * both use and setup happen in si_buscore_setup().
+		 */
+		if (BUSTYPE(sih->bustype) == PCI_BUS &&
+		    (cid == PCI_CORE_ID || cid == PCIE_CORE_ID || cid == PCIE2_CORE_ID)) {
+			sii->pub.buscoretype = (uint16)cid;
+		}
+
+		for (i = 0; i < nmp; i++) {
+			mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID);
+			if ((mpd & ER_TAG) != ER_MP) {
+				SI_ERROR(("Not enough MP entries for component 0x%x\n", cid));
+				goto error;
+			}
+			/* Record something? */
+			SI_VMSG(("  Master port %d, mp: %d id: %d\n", i,
+			         (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT,
+			         (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT));
+		}
+
+		/* First Slave Address Descriptor should be port 0:
+		 * the main register space for the core
+		 */
+		asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh);
+		if (asd == 0) {
+			do {
+			/* Try again to see if it is a bridge */
+			asd = get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, &addrh,
+			              &sizel, &sizeh);
+			if (asd != 0)
+				br = TRUE;
+			else {
+					break;
+				}
+			} while (1);
+		} else {
+			if (addrl == 0 || sizel == 0) {
+				SI_ERROR((" Invalid ASD %x for slave port \n", asd));
+				goto error;
+			}
+			cores_info->coresba[idx] = addrl;
+			cores_info->coresba_size[idx] = sizel;
+		}
+
+		/* Get any more ASDs in first port */
+		j = 1;
+		do {
+			asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh,
+			              &sizel, &sizeh);
+			/* Support ARM debug core ASD with address space > 4K */
+			if ((asd != 0) && (j == 1)) {
+				SI_VMSG(("Warning: sizel > 0x1000\n"));
+				cores_info->coresba2[idx] = addrl;
+				cores_info->coresba2_size[idx] = sizel;
+			}
+			j++;
+		} while (asd != 0);
+
+		/* Go through the ASDs for other slave ports */
+		for (i = 1; i < nsp; i++) {
+			j = 0;
+			do {
+				asd = get_asd(sih, &eromptr, i, j, AD_ST_SLAVE, &addrl, &addrh,
+				              &sizel, &sizeh);
+				/* To get the first base address of second slave port */
+				if ((asd != 0) && (i == 1) && (j == 0)) {
+					cores_info->csp2ba[idx] = addrl;
+					cores_info->csp2ba_size[idx] = sizel;
+				}
+				if (asd == 0)
+					break;
+				j++;
+			} while (1);
+			if (j == 0) {
+				SI_ERROR((" SP %d has no address descriptors\n", i));
+				goto error;
+			}
+		}
+
+		/* Now get master wrappers */
+		for (i = 0; i < nmw; i++) {
+			asd = get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl, &addrh,
+			              &sizel, &sizeh);
+			if (asd == 0) {
+				SI_ERROR(("Missing descriptor for MW %d\n", i));
+				goto error;
+			}
+			if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
+				SI_ERROR(("Master wrapper %d is not 4KB\n", i));
+				goto error;
+			}
+			if (i == 0) {
+				cores_info->wrapba[idx] = addrl;
+			} else if (i == 1) {
+				cores_info->wrapba2[idx] = addrl;
+			} else if (i == 2) {
+				cores_info->wrapba3[idx] = addrl;
+			}
+
+			if (axi_wrapper && (sii->axi_num_wrappers < SI_MAX_AXI_WRAPPERS)) {
+				axi_wrapper[sii->axi_num_wrappers].mfg = mfg;
+				axi_wrapper[sii->axi_num_wrappers].cid = cid;
+				axi_wrapper[sii->axi_num_wrappers].rev = crev;
+				axi_wrapper[sii->axi_num_wrappers].wrapper_type = AI_MASTER_WRAPPER;
+				axi_wrapper[sii->axi_num_wrappers].wrapper_addr = addrl;
+				sii->axi_num_wrappers++;
+				SI_VMSG(("MASTER WRAPPER: %d, mfg:%x, cid:%x,"
+					"rev:%x, addr:%x, size:%x\n",
+					sii->axi_num_wrappers, mfg, cid, crev, addrl, sizel));
+			}
+		}
+
+		/* And finally slave wrappers */
+		for (i = 0; i < nsw; i++) {
+			uint fwp = (nsp <= 1) ? 0 : 1;
+			asd = get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP, &addrl, &addrh,
+			              &sizel, &sizeh);
+			if (asd == 0) {
+				SI_ERROR(("Missing descriptor for SW %d cid %x eromp %p fwp %d \n",
+					i, cid, eromptr, fwp));
+				goto error;
+			}
+
+			if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
+				SI_ERROR(("Slave wrapper %d is not 4KB\n", i));
+				goto error;
+			}
+
+			/* cache APB bridge wrapper address for set/clear timeout */
+			if ((mfg == MFGID_ARM) && (cid == APB_BRIDGE_ID)) {
+				ASSERT(sii->num_br < SI_MAXBR);
+				if (sii->num_br >= SI_MAXBR) {
+					SI_ERROR(("bridge number %d is overflowed\n", sii->num_br));
+					goto error;
+				}
+
+				sii->br_wrapba[sii->num_br++] = addrl;
+			}
+
+			if ((mfg == MFGID_ARM) && (cid == ADB_BRIDGE_ID)) {
+				br = TRUE;
+			}
+
+			BCM_REFERENCE(br);
+
+			if ((nmw == 0) && (i == 0)) {
+				cores_info->wrapba[idx] = addrl;
+			} else if ((nmw == 0) && (i == 1)) {
+				cores_info->wrapba2[idx] = addrl;
+			} else if ((nmw == 0) && (i == 2)) {
+				cores_info->wrapba3[idx] = addrl;
+			}
+
+			/* Include all slave wrappers to the list to
+			 * enable and monitor watchdog timeouts
+			 */
+
+			if (axi_wrapper && (sii->axi_num_wrappers < SI_MAX_AXI_WRAPPERS)) {
+				axi_wrapper[sii->axi_num_wrappers].mfg = mfg;
+				axi_wrapper[sii->axi_num_wrappers].cid = cid;
+				axi_wrapper[sii->axi_num_wrappers].rev = crev;
+				axi_wrapper[sii->axi_num_wrappers].wrapper_type = AI_SLAVE_WRAPPER;
+				axi_wrapper[sii->axi_num_wrappers].wrapper_addr = addrl;
+
+				sii->axi_num_wrappers++;
+
+				SI_VMSG(("SLAVE WRAPPER: %d,  mfg:%x, cid:%x,"
+					"rev:%x, addr:%x, size:%x\n",
+					sii->axi_num_wrappers,  mfg, cid, crev, addrl, sizel));
+			}
+		}
+
+#ifndef AXI_TIMEOUTS_NIC
+		/* Don't record bridges and core with 0 slave ports */
+		if (br || (nsp == 0)) {
+			continue;
+		}
+#endif
+
+		/* Done with core */
+		sii->numcores++;
+	}
+
+	SI_ERROR(("Reached end of erom without finding END\n"));
+
+error:
+	sii->numcores = 0;
+	SI_MSG_DBG_REG(("%s: Exit\n", __FUNCTION__));
+	return;
+}
+
+#define AI_SETCOREIDX_MAPSIZE(coreid) \
+	(((coreid) == NS_CCB_CORE_ID) ? 15 * SI_CORE_SIZE : SI_CORE_SIZE)
+
+/* This function changes the logical "focus" to the indicated core.
+ * Return the current core's virtual address.
+ */
+static volatile void *
+BCMPOSTTRAPFN(_ai_setcoreidx)(si_t *sih, uint coreidx, uint use_wrapn)
+{
+	si_info_t *sii = SI_INFO(sih);
+	si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
+	uint32 addr, wrap, wrap2, wrap3;
+	volatile void *regs;
+
+	if (coreidx >= MIN(sii->numcores, SI_MAXCORES))
+		return (NULL);
+
+	addr = cores_info->coresba[coreidx];
+	wrap = cores_info->wrapba[coreidx];
+	wrap2 = cores_info->wrapba2[coreidx];
+	wrap3 = cores_info->wrapba3[coreidx];
+
+#ifdef AXI_TIMEOUTS_NIC
+	/* No need to disable interrupts while entering/exiting APB bridge core */
+	if ((cores_info->coreid[coreidx] != APB_BRIDGE_CORE_ID) &&
+		(cores_info->coreid[sii->curidx] != APB_BRIDGE_CORE_ID))
+#endif /* AXI_TIMEOUTS_NIC */
+	{
+		/*
+		 * If the user has provided an interrupt mask enabled function,
+		 * then assert interrupts are disabled before switching the core.
+		 */
+		ASSERT((sii->intrsenabled_fn == NULL) ||
+			!(*(sii)->intrsenabled_fn)((sii)->intr_arg));
+	}
+
+	switch (BUSTYPE(sih->bustype)) {
+	case SI_BUS:
+		/* map new one */
+		if (!cores_info->regs[coreidx]) {
+			cores_info->regs[coreidx] = REG_MAP(addr,
+				AI_SETCOREIDX_MAPSIZE(cores_info->coreid[coreidx]));
+			ASSERT(GOODREGS(cores_info->regs[coreidx]));
+		}
+		sii->curmap = regs = cores_info->regs[coreidx];
+		if (!cores_info->wrappers[coreidx] && (wrap != 0)) {
+			cores_info->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE);
+			ASSERT(GOODREGS(cores_info->wrappers[coreidx]));
+		}
+		if (!cores_info->wrappers2[coreidx] && (wrap2 != 0)) {
+			cores_info->wrappers2[coreidx] = REG_MAP(wrap2, SI_CORE_SIZE);
+			ASSERT(GOODREGS(cores_info->wrappers2[coreidx]));
+		}
+		if (!cores_info->wrappers3[coreidx] && (wrap3 != 0)) {
+			cores_info->wrappers3[coreidx] = REG_MAP(wrap3, SI_CORE_SIZE);
+			ASSERT(GOODREGS(cores_info->wrappers3[coreidx]));
+		}
+
+		if (use_wrapn == 2) {
+			sii->curwrap = cores_info->wrappers3[coreidx];
+		} else if (use_wrapn == 1) {
+			sii->curwrap = cores_info->wrappers2[coreidx];
+		} else {
+			sii->curwrap = cores_info->wrappers[coreidx];
+		}
+		break;
+
+	case PCI_BUS:
+		regs = sii->curmap;
+
+		/* point bar0 2nd 4KB window to the primary wrapper */
+		if (use_wrapn == 2) {
+			wrap = wrap3;
+		} else if (use_wrapn == 1) {
+			wrap = wrap2;
+		}
+
+		/* Use BAR0 Window to support dual mac chips... */
+
+		/* TODO: the other mac unit can't be supportd by the current BAR0 window.
+		 * need to find other ways to access these cores.
+		 */
+
+		switch (sii->slice) {
+		case 0: /* main/first slice */
+#ifdef AXI_TIMEOUTS_NIC
+			/* No need to set the BAR0 if core is APB Bridge.
+			 * This is to reduce 2 PCI writes while checkng for errlog
+			 */
+			if (cores_info->coreid[coreidx] != APB_BRIDGE_CORE_ID)
+#endif /* AXI_TIMEOUTS_NIC */
+			{
+				/* point bar0 window */
+				OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, addr);
+			}
+
+			if (PCIE_GEN2(sii))
+				OSL_PCI_WRITE_CONFIG(sii->osh, PCIE2_BAR0_WIN2, 4, wrap);
+			else
+				OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN2, 4, wrap);
+
+			break;
+
+		case 1: /* aux/second slice */
+			/* PCIE GEN2 only for other slices */
+			if (!PCIE_GEN2(sii)) {
+				/* other slices not supported */
+				SI_ERROR(("PCI GEN not supported for slice %d\n", sii->slice));
+				ASSERT(0);
+				break;
+			}
+
+			/* 0x4000 - 0x4fff: enum space 0x5000 - 0x5fff: wrapper space */
+			regs = (volatile uint8 *)regs + PCI_SEC_BAR0_WIN_OFFSET;
+			sii->curwrap = (void *)((uintptr)regs + SI_CORE_SIZE);
+
+			/* point bar0 window */
+			OSL_PCI_WRITE_CONFIG(sii->osh, PCIE2_BAR0_CORE2_WIN, 4, addr);
+			OSL_PCI_WRITE_CONFIG(sii->osh, PCIE2_BAR0_CORE2_WIN2, 4, wrap);
+			break;
+
+		case 2: /* scan/third slice */
+			/* PCIE GEN2 only for other slices */
+			if (!PCIE_GEN2(sii)) {
+				/* other slices not supported */
+				SI_ERROR(("PCI GEN not supported for slice %d\n", sii->slice));
+				ASSERT(0);
+				break;
+			}
+
+			/* 0x9000 - 0x9fff: enum space 0xa000 - 0xafff: wrapper space */
+			regs = (volatile uint8 *)regs + PCI_TER_BAR0_WIN_OFFSET;
+			sii->curwrap = (void *)((uintptr)regs + SI_CORE_SIZE);
+
+			/* point bar0 window */
+			ai_corereg(sih, sih->buscoreidx,
+			            PCIE_TER_BAR0_WIN_REG(sih->buscorerev), ~0, addr);
+			ai_corereg(sih, sih->buscoreidx,
+			            PCIE_TER_BAR0_WRAPPER_REG(sih->buscorerev), ~0, wrap);
+			break;
+
+		default: /* other slices */
+			SI_ERROR(("BAR0 Window not supported for slice %d\n", sii->slice));
+			ASSERT(0);
+			break;
+		}
+
+		break;
+
+#ifdef BCMSDIO
+	case SPI_BUS:
+	case SDIO_BUS:
+		sii->curmap = regs = (void *)((uintptr)addr);
+		if (use_wrapn)
+			sii->curwrap = (void *)((uintptr)wrap2);
+		else
+			sii->curwrap = (void *)((uintptr)wrap);
+		break;
+#endif	/* BCMSDIO */
+
+	default:
+		ASSERT(0);
+		sii->curmap = regs = NULL;
+		break;
+	}
+
+	sii->curidx = coreidx;
+
+	if (regs) {
+		SI_MSG_DBG_REG(("%s: %d\n", __FUNCTION__, coreidx));
+	}
+
+	return regs;
+}
+
+volatile void *
+BCMPOSTTRAPFN(ai_setcoreidx)(si_t *sih, uint coreidx)
+{
+	return _ai_setcoreidx(sih, coreidx, 0);
+}
+
+volatile void *
+BCMPOSTTRAPFN(ai_setcoreidx_2ndwrap)(si_t *sih, uint coreidx)
+{
+	return _ai_setcoreidx(sih, coreidx, 1);
+}
+
+volatile void *
+BCMPOSTTRAPFN(ai_setcoreidx_3rdwrap)(si_t *sih, uint coreidx)
+{
+	return _ai_setcoreidx(sih, coreidx, 2);
+}
+
+void
+ai_coreaddrspaceX(const si_t *sih, uint asidx, uint32 *addr, uint32 *size)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	const si_cores_info_t *cores_info = (const si_cores_info_t *)sii->cores_info;
+	chipcregs_t *cc = NULL;
+	uint32 erombase, *eromptr, *eromlim;
+	uint i, j, cidx;
+	uint32 cia, cib, nmp, nsp;
+	uint32 asd, addrl, addrh, sizel, sizeh;
+
+	for (i = 0; i < sii->numcores; i++) {
+		if (cores_info->coreid[i] == CC_CORE_ID) {
+			cc = (chipcregs_t *)cores_info->regs[i];
+			break;
+		}
+	}
+	if (cc == NULL)
+		goto error;
+
+	BCM_REFERENCE(erombase);
+	erombase = R_REG(sii->osh, &cc->eromptr);
+	eromptr = (uint32 *)REG_MAP(erombase, SI_CORE_SIZE);
+	eromlim = eromptr + (ER_REMAPCONTROL / sizeof(uint32));
+
+	cidx = sii->curidx;
+	cia = cores_info->cia[cidx];
+	cib = cores_info->cib[cidx];
+
+	nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT;
+	nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT;
+
+	/* scan for cores */
+	while (eromptr < eromlim) {
+		if ((get_erom_ent(sih, &eromptr, ER_TAG, ER_CI) == cia) &&
+			(get_erom_ent(sih, &eromptr, 0, 0) == cib)) {
+			break;
+		}
+	}
+
+	/* skip master ports */
+	for (i = 0; i < nmp; i++)
+		get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID);
+
+	/* Skip ASDs in port 0 */
+	asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh);
+	if (asd == 0) {
+		/* Try again to see if it is a bridge */
+		asd = get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl, &addrh,
+		              &sizel, &sizeh);
+	}
+
+	j = 1;
+	do {
+		asd = get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl, &addrh,
+		              &sizel, &sizeh);
+		j++;
+	} while (asd != 0);
+
+	/* Go through the ASDs for other slave ports */
+	for (i = 1; i < nsp; i++) {
+		j = 0;
+		do {
+			asd = get_asd(sih, &eromptr, i, j, AD_ST_SLAVE, &addrl, &addrh,
+				&sizel, &sizeh);
+			if (asd == 0)
+				break;
+
+			if (!asidx--) {
+				*addr = addrl;
+				*size = sizel;
+				return;
+			}
+			j++;
+		} while (1);
+
+		if (j == 0) {
+			SI_ERROR((" SP %d has no address descriptors\n", i));
+			break;
+		}
+	}
+
+error:
+	*size = 0;
+	return;
+}
+
+/* Return the number of address spaces in current core */
+int
+ai_numaddrspaces(const si_t *sih)
+{
+	/* TODO: Either save it or parse the EROM on demand, currently hardcode 2 */
+	BCM_REFERENCE(sih);
+
+	return 2;
+}
+
+/* Return the address of the nth address space in the current core
+ * Arguments:
+ * sih : Pointer to struct si_t
+ * spidx : slave port index
+ * baidx : base address index
+ */
+uint32
+ai_addrspace(const si_t *sih, uint spidx, uint baidx)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	const si_cores_info_t *cores_info = (const si_cores_info_t *)sii->cores_info;
+	uint cidx;
+
+	cidx = sii->curidx;
+
+	if (spidx == CORE_SLAVE_PORT_0) {
+		if (baidx == CORE_BASE_ADDR_0)
+			return cores_info->coresba[cidx];
+		else if (baidx == CORE_BASE_ADDR_1)
+			return cores_info->coresba2[cidx];
+	}
+	else if (spidx == CORE_SLAVE_PORT_1) {
+		if (baidx == CORE_BASE_ADDR_0)
+			return cores_info->csp2ba[cidx];
+	}
+
+	SI_ERROR(("ai_addrspace: Need to parse the erom again to find %d base addr"
+		" in %d slave port\n",
+		baidx, spidx));
+
+	return 0;
+
+}
+
+/* Return the size of the nth address space in the current core
+* Arguments:
+* sih : Pointer to struct si_t
+* spidx : slave port index
+* baidx : base address index
+*/
+uint32
+ai_addrspacesize(const si_t *sih, uint spidx, uint baidx)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	const si_cores_info_t *cores_info = (const si_cores_info_t *)sii->cores_info;
+	uint cidx;
+
+	cidx = sii->curidx;
+	if (spidx == CORE_SLAVE_PORT_0) {
+		if (baidx == CORE_BASE_ADDR_0)
+			return cores_info->coresba_size[cidx];
+		else if (baidx == CORE_BASE_ADDR_1)
+			return cores_info->coresba2_size[cidx];
+	}
+	else if (spidx == CORE_SLAVE_PORT_1) {
+		if (baidx == CORE_BASE_ADDR_0)
+			return cores_info->csp2ba_size[cidx];
+	}
+
+	SI_ERROR(("ai_addrspacesize: Need to parse the erom again to find %d"
+		" base addr in %d slave port\n",
+		baidx, spidx));
+
+	return 0;
+}
+
+uint
+ai_flag(si_t *sih)
+{
+	const si_info_t *sii = SI_INFO(sih);
+#if !defined(BCMDONGLEHOST)
+	const si_cores_info_t *cores_info = (const si_cores_info_t *)sii->cores_info;
+#endif
+	aidmp_t *ai;
+
+	if (PMU_DMP()) {
+		uint idx, flag;
+		idx = sii->curidx;
+		ai_setcoreidx(sih, SI_CC_IDX);
+		flag = ai_flag_alt(sih);
+		ai_setcoreidx(sih, idx);
+		return flag;
+	}
+
+	ai = sii->curwrap;
+	ASSERT(ai != NULL);
+
+	return (R_REG(sii->osh, &ai->oobselouta30) & 0x1f);
+}
+
+uint
+ai_flag_alt(const si_t *sih)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	aidmp_t *ai = sii->curwrap;
+
+	return ((R_REG(sii->osh, &ai->oobselouta30) >> AI_OOBSEL_1_SHIFT) & AI_OOBSEL_MASK);
+}
+
+void
+ai_setint(const si_t *sih, int siflag)
+{
+	BCM_REFERENCE(sih);
+	BCM_REFERENCE(siflag);
+
+	/* TODO: Figure out how to set interrupt mask in ai */
+}
+
+uint
+BCMPOSTTRAPFN(ai_wrap_reg)(const si_t *sih, uint32 offset, uint32 mask, uint32 val)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	uint32 *addr = (uint32 *) ((uchar *)(sii->curwrap) + offset);
+
+	if (mask || val) {
+		uint32 w = R_REG(sii->osh, addr);
+		w &= ~mask;
+		w |= val;
+		W_REG(sii->osh, addr, w);
+	}
+	return (R_REG(sii->osh, addr));
+}
+
+uint
+ai_corevendor(const si_t *sih)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	const si_cores_info_t *cores_info = (const si_cores_info_t *)sii->cores_info;
+	uint32 cia;
+
+	cia = cores_info->cia[sii->curidx];
+	return ((cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT);
+}
+
+uint
+BCMPOSTTRAPFN(ai_corerev)(const si_t *sih)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	const si_cores_info_t *cores_info = (const si_cores_info_t *)sii->cores_info;
+	uint32 cib;
+
+	cib = cores_info->cib[sii->curidx];
+	return ((cib & CIB_REV_MASK) >> CIB_REV_SHIFT);
+}
+
+uint
+ai_corerev_minor(const si_t *sih)
+{
+	return (ai_core_sflags(sih, 0, 0) >> SISF_MINORREV_D11_SHIFT) &
+			SISF_MINORREV_D11_MASK;
+}
+
+bool
+BCMPOSTTRAPFN(ai_iscoreup)(const si_t *sih)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	aidmp_t *ai = sii->curwrap;
+
+	return (((R_REG(sii->osh, &ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) == SICF_CLOCK_EN) &&
+	        ((R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) == 0));
+}
+
+/*
+ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation,
+ * switch back to the original core, and return the new value.
+ *
+ * When using the silicon backplane, no fiddling with interrupts or core switches is needed.
+ *
+ * Also, when using pci/pcie, we can optimize away the core switching for pci registers
+ * and (on newer pci cores) chipcommon registers.
+ */
+uint
+BCMPOSTTRAPFN(ai_corereg)(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
+{
+	uint origidx = 0;
+	volatile uint32 *r = NULL;
+	uint w;
+	bcm_int_bitmask_t intr_val;
+	bool fast = FALSE;
+	si_info_t *sii = SI_INFO(sih);
+	si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
+
+	ASSERT(GOODIDX(coreidx, sii->numcores));
+	ASSERT(regoff < SI_CORE_SIZE);
+	ASSERT((val & ~mask) == 0);
+
+	if (coreidx >= SI_MAXCORES)
+		return 0;
+
+	if (BUSTYPE(sih->bustype) == SI_BUS) {
+		/* If internal bus, we can always get at everything */
+		fast = TRUE;
+		/* map if does not exist */
+		if (!cores_info->regs[coreidx]) {
+			cores_info->regs[coreidx] = REG_MAP(cores_info->coresba[coreidx],
+			                            SI_CORE_SIZE);
+			ASSERT(GOODREGS(cores_info->regs[coreidx]));
+		}
+		r = (volatile uint32 *)((volatile uchar *)cores_info->regs[coreidx] + regoff);
+	} else if (BUSTYPE(sih->bustype) == PCI_BUS) {
+		/* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */
+
+		if ((cores_info->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
+			/* Chipc registers are mapped at 12KB */
+
+			fast = TRUE;
+			r = (volatile uint32 *)((volatile char *)sii->curmap +
+			               PCI_16KB0_CCREGS_OFFSET + regoff);
+		} else if (sii->pub.buscoreidx == coreidx) {
+			/* pci registers are at either in the last 2KB of an 8KB window
+			 * or, in pcie and pci rev 13 at 8KB
+			 */
+			fast = TRUE;
+			if (SI_FAST(sii))
+				r = (volatile uint32 *)((volatile char *)sii->curmap +
+				               PCI_16KB0_PCIREGS_OFFSET + regoff);
+			else
+				r = (volatile uint32 *)((volatile char *)sii->curmap +
+				               ((regoff >= SBCONFIGOFF) ?
+				                PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) +
+				               regoff);
+		}
+	}
+
+	if (!fast) {
+		INTR_OFF(sii, &intr_val);
+
+		/* save current core index */
+		origidx = si_coreidx(&sii->pub);
+
+		/* switch core */
+		r = (volatile uint32*) ((volatile uchar*) ai_setcoreidx(&sii->pub, coreidx) +
+		               regoff);
+	}
+	ASSERT(r != NULL);
+
+	/* mask and set */
+	if (mask || val) {
+		w = (R_REG(sii->osh, r) & ~mask) | val;
+		W_REG(sii->osh, r, w);
+	}
+
+	/* readback */
+	w = R_REG(sii->osh, r);
+
+	if (!fast) {
+		/* restore core index */
+		if (origidx != coreidx)
+			ai_setcoreidx(&sii->pub, origidx);
+
+		INTR_RESTORE(sii, &intr_val);
+	}
+
+	return (w);
+}
+
+/*
+ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation,
+ * switch back to the original core, and return the new value.
+ *
+ * When using the silicon backplane, no fiddling with interrupts or core switches is needed.
+ *
+ * Also, when using pci/pcie, we can optimize away the core switching for pci registers
+ * and (on newer pci cores) chipcommon registers.
+ */
+uint
+ai_corereg_writeonly(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
+{
+	uint origidx = 0;
+	volatile uint32 *r = NULL;
+	uint w = 0;
+	bcm_int_bitmask_t intr_val;
+	bool fast = FALSE;
+	si_info_t *sii = SI_INFO(sih);
+	si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
+
+	ASSERT(GOODIDX(coreidx, sii->numcores));
+	ASSERT(regoff < SI_CORE_SIZE);
+	ASSERT((val & ~mask) == 0);
+
+	if (coreidx >= SI_MAXCORES)
+		return 0;
+
+	if (BUSTYPE(sih->bustype) == SI_BUS) {
+		/* If internal bus, we can always get at everything */
+		fast = TRUE;
+		/* map if does not exist */
+		if (!cores_info->regs[coreidx]) {
+			cores_info->regs[coreidx] = REG_MAP(cores_info->coresba[coreidx],
+			                            SI_CORE_SIZE);
+			ASSERT(GOODREGS(cores_info->regs[coreidx]));
+		}
+		r = (volatile uint32 *)((volatile uchar *)cores_info->regs[coreidx] + regoff);
+	} else if (BUSTYPE(sih->bustype) == PCI_BUS) {
+		/* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */
+
+		if ((cores_info->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
+			/* Chipc registers are mapped at 12KB */
+
+			fast = TRUE;
+			r = (volatile uint32 *)((volatile char *)sii->curmap +
+			               PCI_16KB0_CCREGS_OFFSET + regoff);
+		} else if (sii->pub.buscoreidx == coreidx) {
+			/* pci registers are at either in the last 2KB of an 8KB window
+			 * or, in pcie and pci rev 13 at 8KB
+			 */
+			fast = TRUE;
+			if (SI_FAST(sii))
+				r = (volatile uint32 *)((volatile char *)sii->curmap +
+				               PCI_16KB0_PCIREGS_OFFSET + regoff);
+			else
+				r = (volatile uint32 *)((volatile char *)sii->curmap +
+				               ((regoff >= SBCONFIGOFF) ?
+				                PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) +
+				               regoff);
+		}
+	}
+
+	if (!fast) {
+		INTR_OFF(sii, &intr_val);
+
+		/* save current core index */
+		origidx = si_coreidx(&sii->pub);
+
+		/* switch core */
+		r = (volatile uint32*) ((volatile uchar*) ai_setcoreidx(&sii->pub, coreidx) +
+		               regoff);
+	}
+	ASSERT(r != NULL);
+
+	/* mask and set */
+	if (mask || val) {
+		w = (R_REG(sii->osh, r) & ~mask) | val;
+		W_REG(sii->osh, r, w);
+	}
+
+	if (!fast) {
+		/* restore core index */
+		if (origidx != coreidx)
+			ai_setcoreidx(&sii->pub, origidx);
+
+		INTR_RESTORE(sii, &intr_val);
+	}
+
+	return (w);
+}
+
+/*
+ * If there is no need for fiddling with interrupts or core switches (typically silicon
+ * back plane registers, pci registers and chipcommon registers), this function
+ * returns the register offset on this core to a mapped address. This address can
+ * be used for W_REG/R_REG directly.
+ *
+ * For accessing registers that would need a core switch, this function will return
+ * NULL.
+ */
+volatile uint32 *
+BCMPOSTTRAPFN(ai_corereg_addr)(si_t *sih, uint coreidx, uint regoff)
+{
+	volatile uint32 *r = NULL;
+	bool fast = FALSE;
+	si_info_t *sii = SI_INFO(sih);
+	si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
+
+	ASSERT(GOODIDX(coreidx, sii->numcores));
+	ASSERT(regoff < SI_CORE_SIZE);
+
+	if (coreidx >= SI_MAXCORES)
+		return 0;
+
+	if (BUSTYPE(sih->bustype) == SI_BUS) {
+		/* If internal bus, we can always get at everything */
+		fast = TRUE;
+		/* map if does not exist */
+		if (!cores_info->regs[coreidx]) {
+			cores_info->regs[coreidx] = REG_MAP(cores_info->coresba[coreidx],
+			                            SI_CORE_SIZE);
+			ASSERT(GOODREGS(cores_info->regs[coreidx]));
+		}
+		r = (volatile uint32 *)((volatile uchar *)cores_info->regs[coreidx] + regoff);
+	} else if (BUSTYPE(sih->bustype) == PCI_BUS) {
+		/* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */
+
+		if ((cores_info->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
+			/* Chipc registers are mapped at 12KB */
+
+			fast = TRUE;
+			r = (volatile uint32 *)((volatile char *)sii->curmap +
+			               PCI_16KB0_CCREGS_OFFSET + regoff);
+		} else if (sii->pub.buscoreidx == coreidx) {
+			/* pci registers are at either in the last 2KB of an 8KB window
+			 * or, in pcie and pci rev 13 at 8KB
+			 */
+			fast = TRUE;
+			if (SI_FAST(sii))
+				r = (volatile uint32 *)((volatile char *)sii->curmap +
+				               PCI_16KB0_PCIREGS_OFFSET + regoff);
+			else
+				r = (volatile uint32 *)((volatile char *)sii->curmap +
+				               ((regoff >= SBCONFIGOFF) ?
+				                PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) +
+				               regoff);
+		}
+	}
+
+	if (!fast) {
+		ASSERT(sii->curidx == coreidx);
+		r = (volatile uint32*) ((volatile uchar*)sii->curmap + regoff);
+	}
+
+	return (r);
+}
+
+void
+ai_core_disable(const si_t *sih, uint32 bits)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	volatile uint32 dummy;
+	uint32 status;
+	aidmp_t *ai;
+
+	ASSERT(GOODREGS(sii->curwrap));
+	ai = sii->curwrap;
+
+	/* if core is already in reset, just return */
+	if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) {
+		return;
+	}
+
+	/* ensure there are no pending backplane operations */
+	SPINWAIT(((status = R_REG(sii->osh, &ai->resetstatus)) != 0), 300);
+
+	/* if pending backplane ops still, try waiting longer */
+	if (status != 0) {
+		/* 300usecs was sufficient to allow backplane ops to clear for big hammer */
+		/* during driver load we may need more time */
+		SPINWAIT(((status = R_REG(sii->osh, &ai->resetstatus)) != 0), 10000);
+		/* if still pending ops, continue on and try disable anyway */
+		/* this is in big hammer path, so don't call wl_reinit in this case... */
+#ifdef BCMDBG
+		if (status != 0) {
+			SI_ERROR(("ai_core_disable: WARN: resetstatus=%0x on core disable\n",
+				status));
+		}
+#endif
+	}
+
+	W_REG(sii->osh, &ai->resetctrl, AIRC_RESET);
+	dummy = R_REG(sii->osh, &ai->resetctrl);
+	BCM_REFERENCE(dummy);
+	OSL_DELAY(1);
+
+	W_REG(sii->osh, &ai->ioctrl, bits);
+	dummy = R_REG(sii->osh, &ai->ioctrl);
+	BCM_REFERENCE(dummy);
+	OSL_DELAY(10);
+}
+
+/* reset and re-enable a core
+ * inputs:
+ * bits - core specific bits that are set during and after reset sequence
+ * resetbits - core specific bits that are set only during reset sequence
+ */
+static bool
+_ai_core_reset(const si_t *sih, uint32 bits, uint32 resetbits)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	aidmp_t *ai;
+	volatile uint32 dummy;
+	uint loop_counter = 10;
+
+	ASSERT(GOODREGS(sii->curwrap));
+	ai = sii->curwrap;
+
+	if (R_REG(sii->osh, &ai->resetstatus) == 0xffffffff &&
+		R_REG(sii->osh, &ai->ioctrl) == 0xffffffff &&
+		R_REG(sii->osh, &ai->resetctrl) == 0xffffffff) {
+		SI_ERROR(("%s: fail, resetstatus&ioctrl&resetctrl is 0xffffffff\n", __func__));
+		return FALSE;
+	}
+	/* ensure there are no pending backplane operations */
+	SPINWAIT(((dummy = R_REG(sii->osh, &ai->resetstatus)) != 0), 300);
+
+#ifdef BCMDBG_ERR
+	if (dummy != 0) {
+		SI_ERROR(("_ai_core_reset: WARN1: resetstatus=0x%0x\n", dummy));
+	}
+#endif /* BCMDBG_ERR */
+
+	SI_ERROR(("%s: &ai->ioctrl = 0x%x, &ai->resetctrl = 0x%x, &ai->resetstatus = 0x%x\n",
+			__func__,
+			R_REG(sii->osh, &ai->ioctrl),
+			R_REG(sii->osh, &ai->resetctrl),
+			R_REG(sii->osh, &ai->resetstatus)));
+
+	/* put core into reset state */
+	W_REG(sii->osh, &ai->resetctrl, AIRC_RESET);
+	OSL_DELAY(10);
+
+	/* ensure there are no pending backplane operations */
+	SPINWAIT((R_REG(sii->osh, &ai->resetstatus) != 0), 300);
+
+	W_REG(sii->osh, &ai->ioctrl, (bits | resetbits | SICF_FGC | SICF_CLOCK_EN));
+	dummy = R_REG(sii->osh, &ai->ioctrl);
+	BCM_REFERENCE(dummy);
+#ifdef UCM_CORRUPTION_WAR
+	if (si_coreid(sih) == D11_CORE_ID) {
+		/* Reset FGC */
+		OSL_DELAY(1);
+		W_REG(sii->osh, &ai->ioctrl, (dummy & (~SICF_FGC)));
+	}
+#endif /* UCM_CORRUPTION_WAR */
+	/* ensure there are no pending backplane operations */
+	SPINWAIT(((dummy = R_REG(sii->osh, &ai->resetstatus)) != 0), 300);
+
+#ifdef BCMDBG_ERR
+	if (dummy != 0)
+		SI_ERROR(("_ai_core_reset: WARN2: resetstatus=0x%0x\n", dummy));
+#endif
+
+	while (R_REG(sii->osh, &ai->resetctrl) != 0 && --loop_counter != 0) {
+		/* ensure there are no pending backplane operations */
+		SPINWAIT(((dummy = R_REG(sii->osh, &ai->resetstatus)) != 0), 300);
+
+#ifdef BCMDBG_ERR
+		if (dummy != 0)
+			SI_ERROR(("_ai_core_reset: WARN3 resetstatus=0x%0x\n", dummy));
+#endif
+
+		/* take core out of reset */
+		W_REG(sii->osh, &ai->resetctrl, 0);
+
+		/* ensure there are no pending backplane operations */
+		SPINWAIT((R_REG(sii->osh, &ai->resetstatus) != 0), 300);
+	}
+
+#ifdef BCMDBG_ERR
+	if (loop_counter == 0) {
+		SI_ERROR(("_ai_core_reset: Failed to take core 0x%x out of reset\n",
+			si_coreid(sih)));
+	}
+#endif
+
+#ifdef UCM_CORRUPTION_WAR
+	/* Pulse FGC after lifting Reset */
+	W_REG(sii->osh, &ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN));
+#else
+	W_REG(sii->osh, &ai->ioctrl, (bits | SICF_CLOCK_EN));
+#endif /* UCM_CORRUPTION_WAR */
+	dummy = R_REG(sii->osh, &ai->ioctrl);
+	BCM_REFERENCE(dummy);
+#ifdef UCM_CORRUPTION_WAR
+	if (si_coreid(sih) == D11_CORE_ID) {
+		/* Reset FGC */
+		OSL_DELAY(1);
+		W_REG(sii->osh, &ai->ioctrl, (dummy & (~SICF_FGC)));
+	}
+#endif /* UCM_CORRUPTION_WAR */
+	OSL_DELAY(1);
+	return TRUE;
+}
+
+bool
+ai_core_reset(si_t *sih, uint32 bits, uint32 resetbits)
+{
+	si_info_t *sii = SI_INFO(sih);
+	const si_cores_info_t *cores_info = (const si_cores_info_t *)sii->cores_info;
+	uint idx = sii->curidx;
+	bool ret = TRUE;
+
+	if (cores_info->wrapba3[idx] != 0) {
+		ai_setcoreidx_3rdwrap(sih, idx);
+		ret = _ai_core_reset(sih, bits, resetbits);
+		ai_setcoreidx(sih, idx);
+	}
+
+	if (cores_info->wrapba2[idx] != 0) {
+		ai_setcoreidx_2ndwrap(sih, idx);
+		ret = _ai_core_reset(sih, bits, resetbits);
+		ai_setcoreidx(sih, idx);
+	}
+
+	ret = _ai_core_reset(sih, bits, resetbits);
+	return ret;
+}
+
+#ifdef BOOKER_NIC400_INF
+void
+BCMPOSTTRAPFN(ai_core_reset_ext)(const si_t *sih, uint32 bits, uint32 resetbits)
+{
+	_ai_core_reset(sih, bits, resetbits);
+}
+#endif /* BOOKER_NIC400_INF */
+
+void
+ai_core_cflags_wo(const si_t *sih, uint32 mask, uint32 val)
+{
+	const si_info_t *sii = SI_INFO(sih);
+#if !defined(BCMDONGLEHOST)
+	const si_cores_info_t *cores_info = (const si_cores_info_t *)sii->cores_info;
+#endif
+	aidmp_t *ai;
+	uint32 w;
+
+	if (PMU_DMP()) {
+		SI_ERROR(("ai_core_cflags_wo: Accessing PMU DMP register (ioctrl)\n"));
+		return;
+	}
+
+	ASSERT(GOODREGS(sii->curwrap));
+	ai = sii->curwrap;
+
+	ASSERT((val & ~mask) == 0);
+
+	if (mask || val) {
+		w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val);
+		W_REG(sii->osh, &ai->ioctrl, w);
+	}
+}
+
+uint32
+BCMPOSTTRAPFN(ai_core_cflags)(const si_t *sih, uint32 mask, uint32 val)
+{
+	const si_info_t *sii = SI_INFO(sih);
+#if !defined(BCMDONGLEHOST)
+	const si_cores_info_t *cores_info = (const si_cores_info_t *)sii->cores_info;
+#endif
+	aidmp_t *ai;
+	uint32 w;
+
+	if (PMU_DMP()) {
+		SI_ERROR(("ai_core_cflags: Accessing PMU DMP register (ioctrl)\n"));
+		return 0;
+	}
+	ASSERT(GOODREGS(sii->curwrap));
+	ai = sii->curwrap;
+
+	ASSERT((val & ~mask) == 0);
+
+	if (mask || val) {
+		w = ((R_REG(sii->osh, &ai->ioctrl) & ~mask) | val);
+		W_REG(sii->osh, &ai->ioctrl, w);
+	}
+
+	return R_REG(sii->osh, &ai->ioctrl);
+}
+
+uint32
+ai_core_sflags(const si_t *sih, uint32 mask, uint32 val)
+{
+	const si_info_t *sii = SI_INFO(sih);
+#if !defined(BCMDONGLEHOST)
+	const si_cores_info_t *cores_info = (const si_cores_info_t *)sii->cores_info;
+#endif
+	aidmp_t *ai;
+	uint32 w;
+
+	if (PMU_DMP()) {
+		SI_ERROR(("ai_core_sflags: Accessing PMU DMP register (ioctrl)\n"));
+		return 0;
+	}
+
+	ASSERT(GOODREGS(sii->curwrap));
+	ai = sii->curwrap;
+
+	ASSERT((val & ~mask) == 0);
+	ASSERT((mask & ~SISF_CORE_BITS) == 0);
+
+	if (mask || val) {
+		w = ((R_REG(sii->osh, &ai->iostatus) & ~mask) | val);
+		W_REG(sii->osh, &ai->iostatus, w);
+	}
+
+	return R_REG(sii->osh, &ai->iostatus);
+}
+
+#if defined(BCMDBG) || defined(BCMDBG_DUMP) || defined(BCMDBG_PHYDUMP)
+/* print interesting aidmp registers */
+void
+ai_dumpregs(const si_t *sih, struct bcmstrbuf *b)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	osl_t *osh;
+	aidmp_t *ai;
+	uint i;
+	uint32 prev_value = 0;
+	const axi_wrapper_t * axi_wrapper = sii->axi_wrapper;
+	uint32 cfg_reg = 0;
+	uint bar0_win_offset = 0;
+
+	osh = sii->osh;
+
+	/* Save and restore wrapper access window */
+	if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
+		if (PCIE_GEN2(sii)) {
+			cfg_reg = PCIE2_BAR0_CORE2_WIN2;
+			bar0_win_offset = PCIE2_BAR0_CORE2_WIN2_OFFSET;
+		} else {
+			cfg_reg = PCI_BAR0_WIN2;
+			bar0_win_offset = PCI_BAR0_WIN2_OFFSET;
+		}
+
+		prev_value = OSL_PCI_READ_CONFIG(osh, cfg_reg, 4);
+
+		if (prev_value == ID32_INVALID) {
+			SI_PRINT(("ai_dumpregs, PCI_BAR0_WIN2 - %x\n", prev_value));
+			return;
+		}
+	}
+
+	bcm_bprintf(b, "ChipNum:%x, ChipRev;%x, BusType:%x, BoardType:%x, BoardVendor:%x\n\n",
+		sih->chip, sih->chiprev, sih->bustype, sih->boardtype, sih->boardvendor);
+
+	for (i = 0; i < sii->axi_num_wrappers; i++) {
+
+		if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
+			/* Set BAR0 window to bridge wapper base address */
+			OSL_PCI_WRITE_CONFIG(osh,
+				cfg_reg, 4, axi_wrapper[i].wrapper_addr);
+
+			ai = (aidmp_t *) ((volatile uint8*)sii->curmap + bar0_win_offset);
+		} else {
+			ai = (aidmp_t *)(uintptr) axi_wrapper[i].wrapper_addr;
+		}
+
+		bcm_bprintf(b, "core 0x%x: core_rev:%d, %s_WR ADDR:%x \n", axi_wrapper[i].cid,
+			axi_wrapper[i].rev,
+			axi_wrapper[i].wrapper_type == AI_SLAVE_WRAPPER ? "SLAVE" : "MASTER",
+			axi_wrapper[i].wrapper_addr);
+
+		bcm_bprintf(b, "ioctrlset 0x%x ioctrlclear 0x%x ioctrl 0x%x iostatus 0x%x "
+			    "ioctrlwidth 0x%x iostatuswidth 0x%x\n"
+			    "resetctrl 0x%x resetstatus 0x%x resetreadid 0x%x resetwriteid 0x%x\n"
+			    "errlogctrl 0x%x errlogdone 0x%x errlogstatus 0x%x "
+			    "errlogaddrlo 0x%x errlogaddrhi 0x%x\n"
+			    "errlogid 0x%x errloguser 0x%x errlogflags 0x%x\n"
+			    "intstatus 0x%x config 0x%x itcr 0x%x\n\n",
+			    R_REG(osh, &ai->ioctrlset),
+			    R_REG(osh, &ai->ioctrlclear),
+			    R_REG(osh, &ai->ioctrl),
+			    R_REG(osh, &ai->iostatus),
+			    R_REG(osh, &ai->ioctrlwidth),
+			    R_REG(osh, &ai->iostatuswidth),
+			    R_REG(osh, &ai->resetctrl),
+			    R_REG(osh, &ai->resetstatus),
+			    R_REG(osh, &ai->resetreadid),
+			    R_REG(osh, &ai->resetwriteid),
+			    R_REG(osh, &ai->errlogctrl),
+			    R_REG(osh, &ai->errlogdone),
+			    R_REG(osh, &ai->errlogstatus),
+			    R_REG(osh, &ai->errlogaddrlo),
+			    R_REG(osh, &ai->errlogaddrhi),
+			    R_REG(osh, &ai->errlogid),
+			    R_REG(osh, &ai->errloguser),
+			    R_REG(osh, &ai->errlogflags),
+			    R_REG(osh, &ai->intstatus),
+			    R_REG(osh, &ai->config),
+			    R_REG(osh, &ai->itcr));
+	}
+
+	/* Restore the initial wrapper space */
+	if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
+		if (prev_value && cfg_reg) {
+			OSL_PCI_WRITE_CONFIG(osh, cfg_reg, 4, prev_value);
+		}
+	}
+}
+#endif	/* BCMDBG || BCMDBG_DUMP || BCMDBG_PHYDUMP */
+
+#ifdef BCMDBG
+static void
+_ai_view(osl_t *osh, aidmp_t *ai, uint32 cid, uint32 addr, bool verbose)
+{
+	uint32 config;
+
+	config = R_REG(osh, &ai->config);
+	SI_PRINT(("\nCore ID: 0x%x, addr 0x%x, config 0x%x\n", cid, addr, config));
+
+	if (config & AICFG_RST)
+		SI_PRINT(("resetctrl 0x%x, resetstatus 0x%x, resetreadid 0x%x, resetwriteid 0x%x\n",
+		          R_REG(osh, &ai->resetctrl), R_REG(osh, &ai->resetstatus),
+		          R_REG(osh, &ai->resetreadid), R_REG(osh, &ai->resetwriteid)));
+
+	if (config & AICFG_IOC)
+		SI_PRINT(("ioctrl 0x%x, width %d\n", R_REG(osh, &ai->ioctrl),
+		          R_REG(osh, &ai->ioctrlwidth)));
+
+	if (config & AICFG_IOS)
+		SI_PRINT(("iostatus 0x%x, width %d\n", R_REG(osh, &ai->iostatus),
+		          R_REG(osh, &ai->iostatuswidth)));
+
+	if (config & AICFG_ERRL) {
+		SI_PRINT(("errlogctrl 0x%x, errlogdone 0x%x, errlogstatus 0x%x, intstatus 0x%x\n",
+		          R_REG(osh, &ai->errlogctrl), R_REG(osh, &ai->errlogdone),
+		          R_REG(osh, &ai->errlogstatus), R_REG(osh, &ai->intstatus)));
+		SI_PRINT(("errlogid 0x%x, errloguser 0x%x, errlogflags 0x%x, errlogaddr "
+		          "0x%x/0x%x\n",
+		          R_REG(osh, &ai->errlogid), R_REG(osh, &ai->errloguser),
+		          R_REG(osh, &ai->errlogflags), R_REG(osh, &ai->errlogaddrhi),
+		          R_REG(osh, &ai->errlogaddrlo)));
+	}
+
+	if (verbose && (config & AICFG_OOB)) {
+		SI_PRINT(("oobselina30 0x%x, oobselina74 0x%x\n",
+		          R_REG(osh, &ai->oobselina30), R_REG(osh, &ai->oobselina74)));
+		SI_PRINT(("oobselinb30 0x%x, oobselinb74 0x%x\n",
+		          R_REG(osh, &ai->oobselinb30), R_REG(osh, &ai->oobselinb74)));
+		SI_PRINT(("oobselinc30 0x%x, oobselinc74 0x%x\n",
+		          R_REG(osh, &ai->oobselinc30), R_REG(osh, &ai->oobselinc74)));
+		SI_PRINT(("oobselind30 0x%x, oobselind74 0x%x\n",
+		          R_REG(osh, &ai->oobselind30), R_REG(osh, &ai->oobselind74)));
+		SI_PRINT(("oobselouta30 0x%x, oobselouta74 0x%x\n",
+		          R_REG(osh, &ai->oobselouta30), R_REG(osh, &ai->oobselouta74)));
+		SI_PRINT(("oobseloutb30 0x%x, oobseloutb74 0x%x\n",
+		          R_REG(osh, &ai->oobseloutb30), R_REG(osh, &ai->oobseloutb74)));
+		SI_PRINT(("oobseloutc30 0x%x, oobseloutc74 0x%x\n",
+		          R_REG(osh, &ai->oobseloutc30), R_REG(osh, &ai->oobseloutc74)));
+		SI_PRINT(("oobseloutd30 0x%x, oobseloutd74 0x%x\n",
+		          R_REG(osh, &ai->oobseloutd30), R_REG(osh, &ai->oobseloutd74)));
+		SI_PRINT(("oobsynca 0x%x, oobseloutaen 0x%x\n",
+		          R_REG(osh, &ai->oobsynca), R_REG(osh, &ai->oobseloutaen)));
+		SI_PRINT(("oobsyncb 0x%x, oobseloutben 0x%x\n",
+		          R_REG(osh, &ai->oobsyncb), R_REG(osh, &ai->oobseloutben)));
+		SI_PRINT(("oobsyncc 0x%x, oobseloutcen 0x%x\n",
+		          R_REG(osh, &ai->oobsyncc), R_REG(osh, &ai->oobseloutcen)));
+		SI_PRINT(("oobsyncd 0x%x, oobseloutden 0x%x\n",
+		          R_REG(osh, &ai->oobsyncd), R_REG(osh, &ai->oobseloutden)));
+		SI_PRINT(("oobaextwidth 0x%x, oobainwidth 0x%x, oobaoutwidth 0x%x\n",
+		          R_REG(osh, &ai->oobaextwidth), R_REG(osh, &ai->oobainwidth),
+		          R_REG(osh, &ai->oobaoutwidth)));
+		SI_PRINT(("oobbextwidth 0x%x, oobbinwidth 0x%x, oobboutwidth 0x%x\n",
+		          R_REG(osh, &ai->oobbextwidth), R_REG(osh, &ai->oobbinwidth),
+		          R_REG(osh, &ai->oobboutwidth)));
+		SI_PRINT(("oobcextwidth 0x%x, oobcinwidth 0x%x, oobcoutwidth 0x%x\n",
+		          R_REG(osh, &ai->oobcextwidth), R_REG(osh, &ai->oobcinwidth),
+		          R_REG(osh, &ai->oobcoutwidth)));
+		SI_PRINT(("oobdextwidth 0x%x, oobdinwidth 0x%x, oobdoutwidth 0x%x\n",
+		          R_REG(osh, &ai->oobdextwidth), R_REG(osh, &ai->oobdinwidth),
+		          R_REG(osh, &ai->oobdoutwidth)));
+	}
+}
+
+void
+ai_view(const si_t *sih, bool verbose)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	const si_cores_info_t *cores_info = (const si_cores_info_t *)sii->cores_info;
+	osl_t *osh;
+	aidmp_t *ai;
+	uint32 cid, addr;
+
+	ai = sii->curwrap;
+	osh = sii->osh;
+
+	if (PMU_DMP()) {
+		SI_ERROR(("Cannot access pmu DMP\n"));
+		return;
+	}
+	cid = cores_info->coreid[sii->curidx];
+	addr = cores_info->wrapba[sii->curidx];
+	_ai_view(osh, ai, cid, addr, verbose);
+}
+
+void
+ai_viewall(si_t *sih, bool verbose)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	const si_cores_info_t *cores_info = (const si_cores_info_t *)sii->cores_info;
+	osl_t *osh;
+	aidmp_t *ai;
+	uint32 cid, addr;
+	uint i;
+
+	osh = sii->osh;
+	for (i = 0; i < sii->numcores; i++) {
+		si_setcoreidx(sih, i);
+
+		if (PMU_DMP()) {
+			SI_ERROR(("Skipping pmu DMP\n"));
+			continue;
+		}
+		ai = sii->curwrap;
+		cid = cores_info->coreid[sii->curidx];
+		addr = cores_info->wrapba[sii->curidx];
+		_ai_view(osh, ai, cid, addr, verbose);
+	}
+}
+#endif	/* BCMDBG */
+
+void
+ai_update_backplane_timeouts(const si_t *sih, bool enable, uint32 timeout_exp, uint32 cid)
+{
+#if defined(AXI_TIMEOUTS) || defined(AXI_TIMEOUTS_NIC)
+	const si_info_t *sii = SI_INFO(sih);
+	aidmp_t *ai;
+	uint32 i;
+	axi_wrapper_t * axi_wrapper = sii->axi_wrapper;
+	uint32 errlogctrl = (enable << AIELC_TO_ENAB_SHIFT) |
+		((timeout_exp << AIELC_TO_EXP_SHIFT) & AIELC_TO_EXP_MASK);
+
+#ifdef AXI_TIMEOUTS_NIC
+	uint32 prev_value = 0;
+	osl_t *osh = sii->osh;
+	uint32 cfg_reg = 0;
+	uint32 offset = 0;
+#endif /* AXI_TIMEOUTS_NIC */
+
+	if ((sii->axi_num_wrappers == 0) ||
+#ifdef AXI_TIMEOUTS_NIC
+		(!PCIE(sii)) ||
+#endif /* AXI_TIMEOUTS_NIC */
+		FALSE) {
+		SI_VMSG((" iai_update_backplane_timeouts, axi_num_wrappers:%d, Is_PCIE:%d,"
+			" BUS_TYPE:%d, ID:%x\n",
+			sii->axi_num_wrappers, PCIE(sii),
+			BUSTYPE(sii->pub.bustype), sii->pub.buscoretype));
+		return;
+	}
+
+#ifdef AXI_TIMEOUTS_NIC
+	/* Save and restore the wrapper access window */
+	if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
+		if (PCIE_GEN1(sii)) {
+			cfg_reg = PCI_BAR0_WIN2;
+			offset = PCI_BAR0_WIN2_OFFSET;
+		} else if (PCIE_GEN2(sii)) {
+			cfg_reg = PCIE2_BAR0_CORE2_WIN2;
+			offset = PCIE2_BAR0_CORE2_WIN2_OFFSET;
+		}
+		else {
+			ASSERT(!"!PCIE_GEN1 && !PCIE_GEN2");
+		}
+
+		prev_value = OSL_PCI_READ_CONFIG(osh, cfg_reg, 4);
+		if (prev_value == ID32_INVALID) {
+			SI_PRINT(("ai_update_backplane_timeouts, PCI_BAR0_WIN2 - %x\n",
+				prev_value));
+			return;
+		}
+	}
+#endif /* AXI_TIMEOUTS_NIC */
+
+	for (i = 0; i < sii->axi_num_wrappers; ++i) {
+		/* WAR for wrong EROM entries w.r.t slave and master wrapper
+		 * for ADB bridge core...so checking actual wrapper config to determine type
+		 * http://jira.broadcom.com/browse/HW4388-905
+		*/
+		if ((cid == 0 || cid == ADB_BRIDGE_ID) &&
+				(axi_wrapper[i].cid == ADB_BRIDGE_ID)) {
+			/* WAR is applicable only to 89B0 and 89C0 */
+			if (CCREV(sih->ccrev) == 70) {
+				ai = (aidmp_t *)(uintptr)axi_wrapper[i].wrapper_addr;
+				if (R_REG(sii->osh, &ai->config) & WRAPPER_TIMEOUT_CONFIG) {
+					axi_wrapper[i].wrapper_type  = AI_SLAVE_WRAPPER;
+				} else {
+					axi_wrapper[i].wrapper_type  = AI_MASTER_WRAPPER;
+				}
+			}
+		}
+		if (axi_wrapper[i].wrapper_type != AI_SLAVE_WRAPPER || ((BCM4389_CHIP(sih->chip) ||
+				BCM4388_CHIP(sih->chip)) &&
+				(axi_wrapper[i].wrapper_addr == WL_BRIDGE1_S ||
+				axi_wrapper[i].wrapper_addr == WL_BRIDGE2_S))) {
+			SI_VMSG(("SKIP ENABLE BPT: MFG:%x, CID:%x, ADDR:%x\n",
+				axi_wrapper[i].mfg,
+				axi_wrapper[i].cid,
+				axi_wrapper[i].wrapper_addr));
+			continue;
+		}
+
+		/* Update only given core if requested */
+		if ((cid != 0) && (axi_wrapper[i].cid != cid)) {
+			continue;
+		}
+
+#ifdef AXI_TIMEOUTS_NIC
+		if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
+			/* Set BAR0_CORE2_WIN2 to bridge wapper base address */
+			OSL_PCI_WRITE_CONFIG(osh,
+				cfg_reg, 4, axi_wrapper[i].wrapper_addr);
+
+			/* set AI to BAR0 + Offset corresponding to Gen1 or gen2 */
+			ai = (aidmp_t *) (DISCARD_QUAL(sii->curmap, uint8) + offset);
+		}
+		else
+#endif /* AXI_TIMEOUTS_NIC */
+		{
+			ai = (aidmp_t *)(uintptr) axi_wrapper[i].wrapper_addr;
+		}
+
+		W_REG(sii->osh, &ai->errlogctrl, errlogctrl);
+
+		SI_VMSG(("ENABLED BPT: MFG:%x, CID:%x, ADDR:%x, ERR_CTRL:%x\n",
+			axi_wrapper[i].mfg,
+			axi_wrapper[i].cid,
+			axi_wrapper[i].wrapper_addr,
+			R_REG(sii->osh, &ai->errlogctrl)));
+	}
+
+#ifdef AXI_TIMEOUTS_NIC
+	/* Restore the initial wrapper space */
+	if (prev_value) {
+		OSL_PCI_WRITE_CONFIG(osh, cfg_reg, 4, prev_value);
+	}
+#endif /* AXI_TIMEOUTS_NIC */
+
+#endif /* AXI_TIMEOUTS || AXI_TIMEOUTS_NIC */
+}
+
+#if defined(AXI_TIMEOUTS) || defined(AXI_TIMEOUTS_NIC)
+
+/* slave error is ignored, so account for those cases */
+static uint32 si_ignore_errlog_cnt = 0;
+
+static bool
+BCMPOSTTRAPFN(ai_ignore_errlog)(const si_info_t *sii, const aidmp_t *ai,
+	uint32 lo_addr, uint32 hi_addr, uint32 err_axi_id, uint32 errsts)
+{
+	uint32 ignore_errsts = AIELS_SLAVE_ERR;
+	uint32 ignore_errsts_2 = 0;
+	uint32 ignore_hi = BT_CC_SPROM_BADREG_HI;
+	uint32 ignore_lo = BT_CC_SPROM_BADREG_LO;
+	uint32 ignore_size = BT_CC_SPROM_BADREG_SIZE;
+	bool address_check = TRUE;
+	uint32 axi_id = 0;
+	uint32 axi_id2 = 0;
+	bool extd_axi_id_mask = FALSE;
+	uint32 axi_id_mask;
+
+	SI_PRINT(("err check: core %p, error %d, axi id 0x%04x, addr(0x%08x:%08x)\n",
+		ai, errsts, err_axi_id, hi_addr, lo_addr));
+
+	/* ignore the BT slave errors if the errlog is to chipcommon addr 0x190 */
+	switch (CHIPID(sii->pub.chip)) {
+#if defined(BT_WLAN_REG_ON_WAR)
+		/*
+		 * 4389B0/C0 - WL and BT turn on WAR, ignore AXI error originating from
+		 * AHB-AXI bridge i.e, any slave error or timeout from BT access
+		 */
+		case BCM4389_CHIP_GRPID:
+			axi_id = BCM4389_BT_AXI_ID;
+			ignore_errsts = AIELS_SLAVE_ERR;
+			axi_id2 = BCM4389_BT_AXI_ID;
+			ignore_errsts_2 = AIELS_TIMEOUT;
+			address_check = FALSE;
+			extd_axi_id_mask = TRUE;
+			break;
+#endif /* BT_WLAN_REG_ON_WAR */
+#ifdef BTOVERPCIE
+		case BCM4388_CHIP_GRPID:
+			axi_id = BCM4388_BT_AXI_ID;
+		/* For BT over PCIE, ignore any slave error from BT. */
+		/* No need to check any address range */
+			address_check = FALSE;
+			ignore_errsts_2 = AIELS_DECODE;
+			break;
+		case BCM4369_CHIP_GRPID:
+			axi_id = BCM4369_BT_AXI_ID;
+		/* For BT over PCIE, ignore any slave error from BT. */
+		/* No need to check any address range */
+			address_check = FALSE;
+			ignore_errsts_2 = AIELS_DECODE;
+			break;
+#endif /* BTOVERPCIE */
+		case BCM4376_CHIP_GRPID:
+		case BCM4378_CHIP_GRPID:
+		case BCM4385_CHIP_GRPID:
+		case BCM4387_CHIP_GRPID:
+#ifdef BTOVERPCIE
+			axi_id = BCM4378_BT_AXI_ID;
+			/* For BT over PCIE, ignore any slave error from BT. */
+			/* No need to check any address range */
+			address_check = FALSE;
+#endif /* BTOVERPCIE */
+			axi_id2 = BCM4378_ARM_PREFETCH_AXI_ID;
+			extd_axi_id_mask = TRUE;
+			ignore_errsts_2 = AIELS_DECODE;
+			break;
+		default:
+			return FALSE;
+	}
+
+	axi_id_mask = extd_axi_id_mask ? AI_ERRLOGID_AXI_ID_MASK_EXTD : AI_ERRLOGID_AXI_ID_MASK;
+
+	/* AXI ID check */
+	err_axi_id &= axi_id_mask;
+	errsts &=  AIELS_ERROR_MASK;
+
+	/* check the ignore error cases. 2 checks */
+	if (!(((err_axi_id == axi_id) && (errsts == ignore_errsts)) ||
+		((err_axi_id == axi_id2) && (errsts == ignore_errsts_2)))) {
+		/* not the error ignore cases */
+		return FALSE;
+
+	}
+
+	/* check the specific address checks now, if specified */
+	if (address_check) {
+		/* address range check */
+		if ((hi_addr != ignore_hi) ||
+		    (lo_addr < ignore_lo) || (lo_addr >= (ignore_lo + ignore_size))) {
+			return FALSE;
+		}
+	}
+
+	SI_PRINT(("err check: ignored\n"));
+	return TRUE;
+}
+#endif /* defined (AXI_TIMEOUTS) || defined (AXI_TIMEOUTS_NIC) */
+
+#ifdef AXI_TIMEOUTS_NIC
+
+/* Function to return the APB bridge details corresponding to the core */
+static bool
+ai_get_apb_bridge(const si_t * sih, uint32 coreidx, uint32 *apb_id, uint32 * apb_coreunit)
+{
+	uint i;
+	uint32 core_base, core_end;
+	const si_info_t *sii = SI_INFO(sih);
+	static uint32 coreidx_cached = 0, apb_id_cached = 0, apb_coreunit_cached = 0;
+	uint32 tmp_coreunit = 0;
+	const si_cores_info_t *cores_info = (si_cores_info_t *)sii->cores_info;
+
+	if (coreidx >= MIN(sii->numcores, SI_MAXCORES))
+		return FALSE;
+
+	/* Most of the time apb bridge query will be for d11 core.
+	 * Maintain the last cache and return if found rather than iterating the table
+	 */
+	if (coreidx_cached == coreidx) {
+		*apb_id = apb_id_cached;
+		*apb_coreunit = apb_coreunit_cached;
+		return TRUE;
+	}
+
+	core_base = cores_info->coresba[coreidx];
+	core_end = core_base + cores_info->coresba_size[coreidx];
+
+	for (i = 0; i < sii->numcores; i++) {
+		if (cores_info->coreid[i] == APB_BRIDGE_ID) {
+			uint32 apb_base;
+			uint32 apb_end;
+
+			apb_base = cores_info->coresba[i];
+			apb_end = apb_base + cores_info->coresba_size[i];
+
+			if ((core_base >= apb_base) &&
+				(core_end <= apb_end)) {
+				/* Current core is attached to this APB bridge */
+				*apb_id = apb_id_cached = APB_BRIDGE_ID;
+				*apb_coreunit = apb_coreunit_cached = tmp_coreunit;
+				coreidx_cached = coreidx;
+				return TRUE;
+			}
+			/* Increment the coreunit */
+			tmp_coreunit++;
+		}
+	}
+
+	return FALSE;
+}
+
+uint32
+ai_clear_backplane_to_fast(si_t *sih, void *addr)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	volatile const void *curmap = sii->curmap;
+	bool core_reg = FALSE;
+
+	/* Use fast path only for core register access */
+	if (((uintptr)addr >= (uintptr)curmap) &&
+		((uintptr)addr < ((uintptr)curmap + SI_CORE_SIZE))) {
+		/* address being accessed is within current core reg map */
+		core_reg = TRUE;
+	}
+
+	if (core_reg) {
+		uint32 apb_id, apb_coreunit;
+
+		if (ai_get_apb_bridge(sih, si_coreidx(&sii->pub),
+			&apb_id, &apb_coreunit) == TRUE) {
+			/* Found the APB bridge corresponding to current core,
+			 * Check for bus errors in APB wrapper
+			 */
+			return ai_clear_backplane_to_per_core(sih,
+				apb_id, apb_coreunit, NULL);
+		}
+	}
+
+	/* Default is to poll for errors on all slave wrappers */
+	return si_clear_backplane_to(sih);
+}
+#endif /* AXI_TIMEOUTS_NIC */
+
+#if defined(AXI_TIMEOUTS) || defined(AXI_TIMEOUTS_NIC)
+static bool g_disable_backplane_logs = FALSE;
+
+static uint32 last_axi_error = AXI_WRAP_STS_NONE;
+static uint32 last_axi_error_log_status = 0;
+static uint32 last_axi_error_core = 0;
+static uint32 last_axi_error_wrap = 0;
+static uint32 last_axi_errlog_lo = 0;
+static uint32 last_axi_errlog_hi = 0;
+static uint32 last_axi_errlog_id = 0;
+
+/*
+ * API to clear the back plane timeout per core.
+ * Caller may pass optional wrapper address. If present this will be used as
+ * the wrapper base address. If wrapper base address is provided then caller
+ * must provide the coreid also.
+ * If both coreid and wrapper is zero, then err status of current bridge
+ * will be verified.
+ */
+uint32
+BCMPOSTTRAPFN(ai_clear_backplane_to_per_core)(si_t *sih, uint coreid, uint coreunit, void *wrap)
+{
+	int ret = AXI_WRAP_STS_NONE;
+	aidmp_t *ai = NULL;
+	uint32 errlog_status = 0;
+	const si_info_t *sii = SI_INFO(sih);
+	uint32 errlog_lo = 0, errlog_hi = 0, errlog_id = 0, errlog_flags = 0;
+	uint32 current_coreidx = si_coreidx(sih);
+	uint32 target_coreidx = si_findcoreidx(sih, coreid, coreunit);
+
+#if defined(AXI_TIMEOUTS_NIC)
+	si_axi_error_t * axi_error = sih->err_info ?
+		&sih->err_info->axi_error[sih->err_info->count] : NULL;
+#endif /* AXI_TIMEOUTS_NIC */
+	bool restore_core = FALSE;
+
+	if ((sii->axi_num_wrappers == 0) ||
+#ifdef AXI_TIMEOUTS_NIC
+		(!PCIE(sii)) ||
+#endif /* AXI_TIMEOUTS_NIC */
+		FALSE) {
+		SI_VMSG(("ai_clear_backplane_to_per_core, axi_num_wrappers:%d, Is_PCIE:%d,"
+			" BUS_TYPE:%d, ID:%x\n",
+			sii->axi_num_wrappers, PCIE(sii),
+			BUSTYPE(sii->pub.bustype), sii->pub.buscoretype));
+		return AXI_WRAP_STS_NONE;
+	}
+
+	if (wrap != NULL) {
+		ai = (aidmp_t *)wrap;
+	} else if (coreid && (target_coreidx != current_coreidx)) {
+
+		if (ai_setcoreidx(sih, target_coreidx) == NULL) {
+			/* Unable to set the core */
+			SI_PRINT(("Set Code Failed: coreid:%x, unit:%d, target_coreidx:%d\n",
+				coreid, coreunit, target_coreidx));
+			errlog_lo = target_coreidx;
+			ret = AXI_WRAP_STS_SET_CORE_FAIL;
+			goto end;
+		}
+
+		restore_core = TRUE;
+		ai = (aidmp_t *)si_wrapperregs(sih);
+	} else {
+		/* Read error status of current wrapper */
+		ai = (aidmp_t *)si_wrapperregs(sih);
+
+		/* Update CoreID to current Code ID */
+		coreid = si_coreid(sih);
+	}
+
+	/* read error log status */
+	errlog_status = R_REG(sii->osh, &ai->errlogstatus);
+
+	if (errlog_status == ID32_INVALID) {
+		/* Do not try to peek further */
+		SI_PRINT(("ai_clear_backplane_to_per_core, errlogstatus:%x - Slave Wrapper:%x\n",
+			errlog_status, coreid));
+		ret = AXI_WRAP_STS_WRAP_RD_ERR;
+		errlog_lo = (uint32)(uintptr)&ai->errlogstatus;
+		goto end;
+	}
+
+	if ((errlog_status & AIELS_ERROR_MASK) != 0) {
+		uint32 tmp;
+		uint32 count = 0;
+		/* set ErrDone to clear the condition */
+		W_REG(sii->osh, &ai->errlogdone, AIELD_ERRDONE_MASK);
+
+		/* SPINWAIT on errlogstatus timeout status bits */
+		while ((tmp = R_REG(sii->osh, &ai->errlogstatus)) & AIELS_ERROR_MASK) {
+
+			if (tmp == ID32_INVALID) {
+				SI_PRINT(("ai_clear_backplane_to_per_core: prev errlogstatus:%x,"
+					" errlogstatus:%x\n",
+					errlog_status, tmp));
+				ret = AXI_WRAP_STS_WRAP_RD_ERR;
+				errlog_lo = (uint32)(uintptr)&ai->errlogstatus;
+				goto end;
+			}
+			/*
+			 * Clear again, to avoid getting stuck in the loop, if a new error
+			 * is logged after we cleared the first timeout
+			 */
+			W_REG(sii->osh, &ai->errlogdone, AIELD_ERRDONE_MASK);
+
+			count++;
+			OSL_DELAY(10);
+			if ((10 * count) > AI_REG_READ_TIMEOUT) {
+				errlog_status = tmp;
+				break;
+			}
+		}
+
+		errlog_lo = R_REG(sii->osh, &ai->errlogaddrlo);
+		errlog_hi = R_REG(sii->osh, &ai->errlogaddrhi);
+		errlog_id = R_REG(sii->osh, &ai->errlogid);
+		errlog_flags = R_REG(sii->osh, &ai->errlogflags);
+
+		/* we are already in the error path, so OK to check for the  slave error */
+		if (ai_ignore_errlog(sii, ai, errlog_lo, errlog_hi, errlog_id,
+			errlog_status)) {
+			si_ignore_errlog_cnt++;
+			goto end;
+		}
+
+		/* only reset APB Bridge on timeout (not slave error, or dec error) */
+		switch (errlog_status & AIELS_ERROR_MASK) {
+			case AIELS_SLAVE_ERR:
+				SI_PRINT(("AXI slave error\n"));
+				ret |= AXI_WRAP_STS_SLAVE_ERR;
+				break;
+
+			case AIELS_TIMEOUT:
+				ai_reset_axi_to(sii, ai);
+				ret |= AXI_WRAP_STS_TIMEOUT;
+				break;
+
+			case AIELS_DECODE:
+				SI_PRINT(("AXI decode error\n"));
+				{
+					ret |= AXI_WRAP_STS_DECODE_ERR;
+				}
+				break;
+			default:
+				ASSERT(0);	/* should be impossible */
+		}
+
+		if (errlog_status & AIELS_MULTIPLE_ERRORS) {
+			SI_PRINT(("Multiple AXI Errors\n"));
+			/* Set multiple errors bit only if actual error is not ignored */
+			if (ret) {
+				ret |= AXI_WRAP_STS_MULTIPLE_ERRORS;
+			}
+		}
+
+		SI_PRINT(("\tCoreID: %x\n", coreid));
+		SI_PRINT(("\t errlog: lo 0x%08x, hi 0x%08x, id 0x%08x, flags 0x%08x"
+			", status 0x%08x\n",
+			errlog_lo, errlog_hi, errlog_id, errlog_flags,
+			errlog_status));
+	}
+
+end:
+	if (ret != AXI_WRAP_STS_NONE) {
+		last_axi_error = ret;
+		last_axi_error_log_status = errlog_status;
+		last_axi_error_core = coreid;
+		last_axi_error_wrap = (uint32)ai;
+		last_axi_errlog_lo = errlog_lo;
+		last_axi_errlog_hi = errlog_hi;
+		last_axi_errlog_id = errlog_id;
+	}
+
+#if defined(AXI_TIMEOUTS_NIC)
+	if (axi_error && (ret != AXI_WRAP_STS_NONE)) {
+		axi_error->error = ret;
+		axi_error->coreid = coreid;
+		axi_error->errlog_lo = errlog_lo;
+		axi_error->errlog_hi = errlog_hi;
+		axi_error->errlog_id = errlog_id;
+		axi_error->errlog_flags = errlog_flags;
+		axi_error->errlog_status = errlog_status;
+		sih->err_info->count++;
+
+		if (sih->err_info->count == SI_MAX_ERRLOG_SIZE) {
+			sih->err_info->count = SI_MAX_ERRLOG_SIZE - 1;
+			SI_PRINT(("AXI Error log overflow\n"));
+		}
+	}
+#endif /* AXI_TIMEOUTS_NIC */
+
+	if (restore_core) {
+		if (ai_setcoreidx(sih, current_coreidx) == NULL) {
+			/* Unable to set the core */
+			return ID32_INVALID;
+		}
+	}
+
+	return ret;
+}
+
+/* reset AXI timeout */
+static void
+BCMPOSTTRAPFN(ai_reset_axi_to)(const si_info_t *sii, aidmp_t *ai)
+{
+	/* reset APB Bridge */
+	OR_REG(sii->osh, &ai->resetctrl, AIRC_RESET);
+	/* sync write */
+	(void)R_REG(sii->osh, &ai->resetctrl);
+	/* clear Reset bit */
+	AND_REG(sii->osh, &ai->resetctrl, ~(AIRC_RESET));
+	/* sync write */
+	(void)R_REG(sii->osh, &ai->resetctrl);
+	SI_PRINT(("AXI timeout\n"));
+	if (R_REG(sii->osh, &ai->resetctrl) & AIRC_RESET) {
+		SI_PRINT(("reset failed on wrapper %p\n", ai));
+		g_disable_backplane_logs = TRUE;
+	}
+}
+
+void
+BCMPOSTTRAPFN(ai_wrapper_get_last_error)(const si_t *sih, uint32 *error_status, uint32 *core,
+	uint32 *lo, uint32 *hi, uint32 *id)
+{
+	*error_status = last_axi_error_log_status;
+	*core = last_axi_error_core;
+	*lo = last_axi_errlog_lo;
+	*hi = last_axi_errlog_hi;
+	*id = last_axi_errlog_id;
+}
+
+/* Function to check whether AXI timeout has been registered on a core */
+uint32
+ai_get_axi_timeout_reg(void)
+{
+	return (GOODREGS(last_axi_errlog_lo) ? last_axi_errlog_lo : 0);
+}
+#endif /* AXI_TIMEOUTS || AXI_TIMEOUTS_NIC */
+
+uint32
+BCMPOSTTRAPFN(ai_findcoreidx_by_axiid)(const si_t *sih, uint32 axiid)
+{
+	uint coreid = 0;
+	uint coreunit = 0;
+	const axi_to_coreidx_t *axi2coreidx = NULL;
+	switch (CHIPID(sih->chip)) {
+		case BCM4369_CHIP_GRPID:
+			axi2coreidx = axi2coreidx_4369;
+			break;
+		default:
+			SI_PRINT(("Chipid mapping not found\n"));
+			break;
+	}
+
+	if (!axi2coreidx)
+		return (BADIDX);
+
+	coreid = axi2coreidx[axiid].coreid;
+	coreunit = axi2coreidx[axiid].coreunit;
+
+	return si_findcoreidx(sih, coreid, coreunit);
+
+}
+
+/*
+ * This API polls all slave wrappers for errors and returns bit map of
+ * all reported errors.
+ * return - bit map of
+ *	AXI_WRAP_STS_NONE
+ *	AXI_WRAP_STS_TIMEOUT
+ *	AXI_WRAP_STS_SLAVE_ERR
+ *	AXI_WRAP_STS_DECODE_ERR
+ *	AXI_WRAP_STS_PCI_RD_ERR
+ *	AXI_WRAP_STS_WRAP_RD_ERR
+ *	AXI_WRAP_STS_SET_CORE_FAIL
+ * On timeout detection, correspondign bridge will be reset to
+ * unblock the bus.
+ * Error reported in each wrapper can be retrieved using the API
+ * si_get_axi_errlog_info()
+ */
+uint32
+BCMPOSTTRAPFN(ai_clear_backplane_to)(si_t *sih)
+{
+	uint32 ret = 0;
+#if defined(AXI_TIMEOUTS) || defined(AXI_TIMEOUTS_NIC)
+	const si_info_t *sii = SI_INFO(sih);
+	aidmp_t *ai;
+	uint32 i;
+	axi_wrapper_t * axi_wrapper = sii->axi_wrapper;
+
+#ifdef AXI_TIMEOUTS_NIC
+	uint32 prev_value = 0;
+	osl_t *osh = sii->osh;
+	uint32 cfg_reg = 0;
+	uint32 offset = 0;
+
+	if ((sii->axi_num_wrappers == 0) || (!PCIE(sii)))
+#else
+	if (sii->axi_num_wrappers == 0)
+#endif
+	{
+		SI_VMSG(("ai_clear_backplane_to, axi_num_wrappers:%d, Is_PCIE:%d, BUS_TYPE:%d,"
+			" ID:%x\n",
+			sii->axi_num_wrappers, PCIE(sii),
+			BUSTYPE(sii->pub.bustype), sii->pub.buscoretype));
+		return AXI_WRAP_STS_NONE;
+	}
+
+#ifdef AXI_TIMEOUTS_NIC
+	/* Save and restore wrapper access window */
+	if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
+		if (PCIE_GEN1(sii)) {
+			cfg_reg = PCI_BAR0_WIN2;
+			offset = PCI_BAR0_WIN2_OFFSET;
+		} else if (PCIE_GEN2(sii)) {
+			cfg_reg = PCIE2_BAR0_CORE2_WIN2;
+			offset = PCIE2_BAR0_CORE2_WIN2_OFFSET;
+		}
+		else {
+			ASSERT(!"!PCIE_GEN1 && !PCIE_GEN2");
+		}
+
+		prev_value = OSL_PCI_READ_CONFIG(osh, cfg_reg, 4);
+
+		if (prev_value == ID32_INVALID) {
+			si_axi_error_t * axi_error =
+				sih->err_info ?
+					&sih->err_info->axi_error[sih->err_info->count] :
+					NULL;
+
+			SI_PRINT(("ai_clear_backplane_to, PCI_BAR0_WIN2 - %x\n", prev_value));
+			if (axi_error) {
+				axi_error->error = ret = AXI_WRAP_STS_PCI_RD_ERR;
+				axi_error->errlog_lo = cfg_reg;
+				sih->err_info->count++;
+
+				if (sih->err_info->count == SI_MAX_ERRLOG_SIZE) {
+					sih->err_info->count = SI_MAX_ERRLOG_SIZE - 1;
+					SI_PRINT(("AXI Error log overflow\n"));
+				}
+			}
+
+			return ret;
+		}
+	}
+#endif /* AXI_TIMEOUTS_NIC */
+
+	for (i = 0; i < sii->axi_num_wrappers; ++i) {
+		uint32 tmp;
+
+		if (axi_wrapper[i].wrapper_type != AI_SLAVE_WRAPPER) {
+			continue;
+		}
+
+#ifdef AXI_TIMEOUTS_NIC
+		if (BUSTYPE(sii->pub.bustype) == PCI_BUS) {
+			/* Set BAR0_CORE2_WIN2 to bridge wapper base address */
+			OSL_PCI_WRITE_CONFIG(osh,
+				cfg_reg, 4, axi_wrapper[i].wrapper_addr);
+
+			/* set AI to BAR0 + Offset corresponding to Gen1 or gen2 */
+			ai = (aidmp_t *) (DISCARD_QUAL(sii->curmap, uint8) + offset);
+		}
+		else
+#endif /* AXI_TIMEOUTS_NIC */
+		{
+			ai = (aidmp_t *)(uintptr) axi_wrapper[i].wrapper_addr;
+		}
+
+		tmp = ai_clear_backplane_to_per_core(sih, axi_wrapper[i].cid, 0,
+			DISCARD_QUAL(ai, void));
+
+		ret |= tmp;
+	}
+
+#ifdef AXI_TIMEOUTS_NIC
+	/* Restore the initial wrapper space */
+	if (prev_value) {
+		OSL_PCI_WRITE_CONFIG(osh, cfg_reg, 4, prev_value);
+	}
+#endif /* AXI_TIMEOUTS_NIC */
+
+#endif /* AXI_TIMEOUTS || AXI_TIMEOUTS_NIC */
+
+	return ret;
+}
+
+uint
+ai_num_slaveports(const si_t *sih, uint coreidx)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	const si_cores_info_t *cores_info = (const si_cores_info_t *)sii->cores_info;
+	uint32 cib;
+
+	cib = cores_info->cib[coreidx];
+	return ((cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT);
+}
+
+#ifdef UART_TRAP_DBG
+void
+ai_dump_APB_Bridge_registers(const si_t *sih)
+{
+	aidmp_t *ai;
+	const si_info_t *sii = SI_INFO(sih);
+
+	ai = (aidmp_t *)sii->br_wrapba[0];
+	printf("APB Bridge 0\n");
+	printf("lo 0x%08x, hi 0x%08x, id 0x%08x, flags 0x%08x",
+		R_REG(sii->osh, &ai->errlogaddrlo),
+		R_REG(sii->osh, &ai->errlogaddrhi),
+		R_REG(sii->osh, &ai->errlogid),
+		R_REG(sii->osh, &ai->errlogflags));
+	printf("\n status 0x%08x\n", R_REG(sii->osh, &ai->errlogstatus));
+}
+#endif /* UART_TRAP_DBG */
+
+void
+ai_force_clocks(const si_t *sih, uint clock_state)
+{
+	const si_info_t *sii = SI_INFO(sih);
+	aidmp_t *ai, *ai_sec = NULL;
+	volatile uint32 dummy;
+	uint32 ioctrl;
+	const si_cores_info_t *cores_info = (const si_cores_info_t *)sii->cores_info;
+
+	ASSERT(GOODREGS(sii->curwrap));
+	ai = sii->curwrap;
+	if (cores_info->wrapba2[sii->curidx])
+		ai_sec = REG_MAP(cores_info->wrapba2[sii->curidx], SI_CORE_SIZE);
+
+	/* ensure there are no pending backplane operations */
+	SPINWAIT((R_REG(sii->osh, &ai->resetstatus) != 0), 300);
+
+	if (clock_state == FORCE_CLK_ON) {
+		ioctrl = R_REG(sii->osh, &ai->ioctrl);
+		W_REG(sii->osh, &ai->ioctrl, (ioctrl | SICF_FGC));
+		dummy = R_REG(sii->osh, &ai->ioctrl);
+		BCM_REFERENCE(dummy);
+		if (ai_sec) {
+			ioctrl = R_REG(sii->osh, &ai_sec->ioctrl);
+			W_REG(sii->osh, &ai_sec->ioctrl, (ioctrl | SICF_FGC));
+			dummy = R_REG(sii->osh, &ai_sec->ioctrl);
+			BCM_REFERENCE(dummy);
+		}
+	} else {
+		ioctrl = R_REG(sii->osh, &ai->ioctrl);
+		W_REG(sii->osh, &ai->ioctrl, (ioctrl & (~SICF_FGC)));
+		dummy = R_REG(sii->osh, &ai->ioctrl);
+		BCM_REFERENCE(dummy);
+		if (ai_sec) {
+			ioctrl = R_REG(sii->osh, &ai_sec->ioctrl);
+			W_REG(sii->osh, &ai_sec->ioctrl, (ioctrl & (~SICF_FGC)));
+			dummy = R_REG(sii->osh, &ai_sec->ioctrl);
+			BCM_REFERENCE(dummy);
+		}
+	}
+	/* ensure there are no pending backplane operations */
+	SPINWAIT((R_REG(sii->osh, &ai->resetstatus) != 0), 300);
+}
+
+#ifdef DONGLEBUILD
+/*
+ * this is not declared as static const, although that is the right thing to do
+ * reason being if declared as static const, compile/link process would that in
+ * read only section...
+ * currently this code/array is used to identify the registers which are dumped
+ * during trap processing
+ * and usually for the trap buffer, .rodata buffer is reused,  so for now just static
+*/
+static uint32 BCMPOST_TRAP_RODATA(wrapper_offsets_to_dump)[] = {
+	OFFSETOF(aidmp_t, ioctrlset),
+	OFFSETOF(aidmp_t, ioctrlclear),
+	OFFSETOF(aidmp_t, ioctrl),
+	OFFSETOF(aidmp_t, iostatus),
+	OFFSETOF(aidmp_t, ioctrlwidth),
+	OFFSETOF(aidmp_t, iostatuswidth),
+	OFFSETOF(aidmp_t, resetctrl),
+	OFFSETOF(aidmp_t, resetstatus),
+	OFFSETOF(aidmp_t, resetreadid),
+	OFFSETOF(aidmp_t, resetwriteid),
+	OFFSETOF(aidmp_t, errlogctrl),
+	OFFSETOF(aidmp_t, errlogdone),
+	OFFSETOF(aidmp_t, errlogstatus),
+	OFFSETOF(aidmp_t, errlogaddrlo),
+	OFFSETOF(aidmp_t, errlogaddrhi),
+	OFFSETOF(aidmp_t, errlogid),
+	OFFSETOF(aidmp_t, errloguser),
+	OFFSETOF(aidmp_t, errlogflags),
+	OFFSETOF(aidmp_t, intstatus),
+	OFFSETOF(aidmp_t, config),
+	OFFSETOF(aidmp_t, itipoobaout),
+	OFFSETOF(aidmp_t, itipoobbout),
+	OFFSETOF(aidmp_t, itipoobcout),
+	OFFSETOF(aidmp_t, itipoobdout)};
+
+#ifdef ETD
+
+/* This is used for dumping wrapper registers for etd when axierror happens.
+ * This should match with the structure hnd_ext_trap_bp_err_t
+ */
+static uint32 BCMPOST_TRAP_RODATA(etd_wrapper_offsets_axierr)[] = {
+	OFFSETOF(aidmp_t, ioctrl),
+	OFFSETOF(aidmp_t, iostatus),
+	OFFSETOF(aidmp_t, resetctrl),
+	OFFSETOF(aidmp_t, resetstatus),
+	OFFSETOF(aidmp_t, resetreadid),
+	OFFSETOF(aidmp_t, resetwriteid),
+	OFFSETOF(aidmp_t, errlogctrl),
+	OFFSETOF(aidmp_t, errlogdone),
+	OFFSETOF(aidmp_t, errlogstatus),
+	OFFSETOF(aidmp_t, errlogaddrlo),
+	OFFSETOF(aidmp_t, errlogaddrhi),
+	OFFSETOF(aidmp_t, errlogid),
+	OFFSETOF(aidmp_t, errloguser),
+	OFFSETOF(aidmp_t, errlogflags),
+	OFFSETOF(aidmp_t, itipoobaout),
+	OFFSETOF(aidmp_t, itipoobbout),
+	OFFSETOF(aidmp_t, itipoobcout),
+	OFFSETOF(aidmp_t, itipoobdout)};
+#endif /* ETD */
+
+/* wrapper function to access the global array wrapper_offsets_to_dump */
+static uint32
+BCMRAMFN(ai_get_sizeof_wrapper_offsets_to_dump)(void)
+{
+	return (sizeof(wrapper_offsets_to_dump));
+}
+
+static uint32
+BCMPOSTTRAPRAMFN(ai_get_wrapper_base_addr)(uint32 **offset)
+{
+	uint32 arr_size = ARRAYSIZE(wrapper_offsets_to_dump);
+
+	*offset = &wrapper_offsets_to_dump[0];
+	return arr_size;
+}
+
+uint32
+ai_wrapper_dump_buf_size(const si_t *sih)
+{
+	uint32 buf_size = 0;
+	uint32 wrapper_count = 0;
+	const si_info_t *sii = SI_INFO(sih);
+
+	wrapper_count = sii->axi_num_wrappers;
+	if (wrapper_count == 0)
+		return 0;
+
+	/* cnt indicates how many registers, tag_id 0 will say these are address/value */
+	/* address/value pairs */
+	buf_size += 2 * (ai_get_sizeof_wrapper_offsets_to_dump() * wrapper_count);
+
+	return buf_size;
+}
+
+static uint32*
+BCMPOSTTRAPFN(ai_wrapper_dump_binary_one)(const si_info_t *sii, uint32 *p32, uint32 wrap_ba)
+{
+	uint i;
+	uint32 *addr;
+	uint32 arr_size;
+	uint32 *offset_base;
+
+	arr_size = ai_get_wrapper_base_addr(&offset_base);
+
+	for (i = 0; i < arr_size; i++) {
+		addr = (uint32 *)(wrap_ba + *(offset_base + i));
+		*p32++ = (uint32)addr;
+		*p32++ = R_REG(sii->osh, addr);
+	}
+	return p32;
+}
+
+#if defined(ETD)
+static uint32
+BCMPOSTTRAPRAMFN(ai_get_wrapper_base_addr_etd_axierr)(uint32 **offset)
+{
+	uint32 arr_size = ARRAYSIZE(etd_wrapper_offsets_axierr);
+
+	*offset = &etd_wrapper_offsets_axierr[0];
+	return arr_size;
+}
+
+uint32
+BCMPOSTTRAPFN(ai_wrapper_dump_last_timeout)(const si_t *sih, uint32 *error, uint32 *core,
+	uint32 *ba, uchar *p)
+{
+#if defined(AXI_TIMEOUTS) || defined(AXI_TIMEOUTS_NIC)
+	uint32 *p32;
+	uint32 wrap_ba = last_axi_error_wrap;
+	uint i;
+	uint32 *addr;
+
+	const si_info_t *sii = SI_INFO(sih);
+
+	if (last_axi_error != AXI_WRAP_STS_NONE)
+	{
+		if (wrap_ba)
+		{
+			p32 = (uint32 *)p;
+			uint32 arr_size;
+			uint32 *offset_base;
+
+			arr_size = ai_get_wrapper_base_addr_etd_axierr(&offset_base);
+			for (i = 0; i < arr_size; i++) {
+				addr = (uint32 *)(wrap_ba + *(offset_base + i));
+				*p32++ = R_REG(sii->osh, addr);
+			}
+		}
+		*error = last_axi_error;
+		*core = last_axi_error_core;
+		*ba = wrap_ba;
+	}
+#else
+	*error = 0;
+	*core = 0;
+	*ba = 0;
+#endif /* AXI_TIMEOUTS || AXI_TIMEOUTS_NIC */
+	return 0;
+}
+#endif /* ETD */
+
+uint32
+BCMPOSTTRAPFN(ai_wrapper_dump_binary)(const si_t *sih, uchar *p)
+{
+	uint32 *p32 = (uint32 *)p;
+	uint32 i;
+	const si_info_t *sii = SI_INFO(sih);
+
+	for (i = 0; i < sii->axi_num_wrappers; i++) {
+		p32 = ai_wrapper_dump_binary_one(sii, p32, sii->axi_wrapper[i].wrapper_addr);
+	}
+	return 0;
+}
+
+bool
+BCMPOSTTRAPFN(ai_check_enable_backplane_log)(const si_t *sih)
+{
+#if defined(AXI_TIMEOUTS) || defined(AXI_TIMEOUTS_NIC)
+	if (g_disable_backplane_logs) {
+		return FALSE;
+	}
+	else {
+		return TRUE;
+	}
+#else /*  (AXI_TIMEOUTS) || defined (AXI_TIMEOUTS_NIC) */
+	return FALSE;
+#endif /*  (AXI_TIMEOUTS) || defined (AXI_TIMEOUTS_NIC) */
+}
+#endif /* DONGLEBUILD */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcm_app_utils.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcm_app_utils.c
@@ -0,0 +1,1271 @@
+/*
+ * Misc utility routines used by kernel or app-level.
+ * Contents are wifi-specific, used by any kernel or app-level
+ * software that might want wifi things as it grows.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Dual:>>
+ */
+
+#include <typedefs.h>
+
+#ifdef BCMDRIVER
+#include <osl.h>
+#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
+#ifndef tolower
+#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
+#endif /* tolower */
+#else /* BCMDRIVER */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#ifndef ASSERT
+#define ASSERT(exp)
+#endif
+#endif /* BCMDRIVER */
+#include <bcmwifi_channels.h>
+
+#if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL) || defined(_CONSOLE))
+#include <bcmstdlib.h>	/* For wlexe/Makefile.wlm_dll */
+#endif
+
+#include <bcmutils.h>
+#include <wlioctl.h>
+#include <wlioctl_utils.h>
+
+#ifndef BCMDRIVER
+/*	Take an array of measurments representing a single channel over time and return
+	a summary. Currently implemented as a simple average but could easily evolve
+	into more cpomplex alogrithms.
+*/
+cca_congest_channel_req_t *
+cca_per_chan_summary(cca_congest_channel_req_t *input, cca_congest_channel_req_t *avg, bool percent)
+{
+	int sec;
+	cca_congest_t totals;
+
+	totals.duration  = 0;
+	totals.congest_ibss  = 0;
+	totals.congest_obss  = 0;
+	totals.interference  = 0;
+	avg->num_secs = 0;
+
+	for (sec = 0; sec < input->num_secs; sec++) {
+		if (input->secs[sec].duration) {
+			totals.duration += input->secs[sec].duration;
+			totals.congest_ibss += input->secs[sec].congest_ibss;
+			totals.congest_obss += input->secs[sec].congest_obss;
+			totals.interference += input->secs[sec].interference;
+			avg->num_secs++;
+		}
+	}
+	avg->chanspec = input->chanspec;
+
+	if (!avg->num_secs || !totals.duration)
+		return (avg);
+
+	if (percent) {
+		avg->secs[0].duration = totals.duration / avg->num_secs;
+		avg->secs[0].congest_ibss = totals.congest_ibss * 100/totals.duration;
+		avg->secs[0].congest_obss = totals.congest_obss * 100/totals.duration;
+		avg->secs[0].interference = totals.interference * 100/totals.duration;
+	} else {
+		avg->secs[0].duration = totals.duration / avg->num_secs;
+		avg->secs[0].congest_ibss = totals.congest_ibss / avg->num_secs;
+		avg->secs[0].congest_obss = totals.congest_obss / avg->num_secs;
+		avg->secs[0].interference = totals.interference / avg->num_secs;
+	}
+
+	return (avg);
+}
+
+static void
+cca_info(uint8 *bitmap, int num_bits, int *left, int *bit_pos)
+{
+	int i;
+	for (*left = 0, i = 0; i < num_bits; i++) {
+		if (isset(bitmap, i)) {
+			(*left)++;
+			*bit_pos = i;
+		}
+	}
+}
+
+static uint8
+spec_to_chan(chanspec_t chspec)
+{
+	return wf_chspec_primary20_chan(chspec);
+}
+
+/*
+	Take an array of measumrements representing summaries of different channels.
+	Return a recomended channel.
+	Interference is evil, get rid of that first.
+	Then hunt for lowest Other bss traffic.
+	Don't forget that channels with low duration times may not have accurate readings.
+	For the moment, do not overwrite input array.
+*/
+int
+cca_analyze(cca_congest_channel_req_t *input[], int num_chans, uint flags, chanspec_t *answer)
+{
+	uint8 *bitmap = NULL;	/* 38 Max channels needs 5 bytes  = 40 */
+	int i, left, winner, ret_val = 0;
+	uint32 min_obss = 1 << 30;
+	uint bitmap_sz;
+
+	bitmap_sz = CEIL(num_chans, NBBY);
+	bitmap = (uint8 *)malloc(bitmap_sz);
+	if (bitmap == NULL) {
+		printf("unable to allocate memory\n");
+		return BCME_NOMEM;
+	}
+
+	bzero(bitmap, bitmap_sz);
+	/* Initially, all channels are up for consideration */
+	for (i = 0; i < num_chans; i++) {
+		if (input[i]->chanspec)
+			setbit(bitmap, i);
+	}
+	cca_info(bitmap, num_chans, &left, &i);
+	if (!left) {
+		ret_val = CCA_ERRNO_TOO_FEW;
+		goto f_exit;
+	}
+
+	/* Filter for 2.4 GHz Band */
+	if (flags & CCA_FLAG_2G_ONLY) {
+		for (i = 0; i < num_chans; i++) {
+			if (!CHSPEC_IS2G(input[i]->chanspec))
+				clrbit(bitmap, i);
+		}
+	}
+	cca_info(bitmap, num_chans, &left, &i);
+	if (!left) {
+		ret_val = CCA_ERRNO_BAND;
+		goto f_exit;
+	}
+
+	/* Filter for 5 GHz Band */
+	if (flags & CCA_FLAG_5G_ONLY) {
+		for (i = 0; i < num_chans; i++) {
+			if (!CHSPEC_IS5G(input[i]->chanspec))
+				clrbit(bitmap, i);
+		}
+	}
+	cca_info(bitmap, num_chans, &left, &i);
+	if (!left) {
+		ret_val = CCA_ERRNO_BAND;
+		goto f_exit;
+	}
+
+	/* Filter for Duration */
+	if (!(flags & CCA_FLAG_IGNORE_DURATION)) {
+		for (i = 0; i < num_chans; i++) {
+			if (input[i]->secs[0].duration < CCA_THRESH_MILLI)
+				clrbit(bitmap, i);
+		}
+	}
+	cca_info(bitmap, num_chans, &left, &i);
+	if (!left) {
+		ret_val = CCA_ERRNO_DURATION;
+		goto f_exit;
+	}
+
+	/* Filter for 1 6 11 on 2.4 Band */
+	if (flags &  CCA_FLAGS_PREFER_1_6_11) {
+		int tmp_channel = spec_to_chan(input[i]->chanspec);
+		int is2g = CHSPEC_IS2G(input[i]->chanspec);
+		for (i = 0; i < num_chans; i++) {
+			if (is2g && tmp_channel != 1 && tmp_channel != 6 && tmp_channel != 11)
+				clrbit(bitmap, i);
+		}
+	}
+	cca_info(bitmap, num_chans, &left, &i);
+	if (!left) {
+		ret_val = CCA_ERRNO_PREF_CHAN;
+		goto f_exit;
+	}
+
+	/* Toss high interference interference */
+	if (!(flags & CCA_FLAG_IGNORE_INTERFER)) {
+		for (i = 0; i < num_chans; i++) {
+			if (input[i]->secs[0].interference > CCA_THRESH_INTERFERE)
+				clrbit(bitmap, i);
+		}
+		cca_info(bitmap, num_chans, &left, &i);
+		if (!left) {
+			ret_val = CCA_ERRNO_INTERFER;
+			goto f_exit;
+		}
+	}
+
+	/* Now find lowest obss */
+	winner = 0;
+	for (i = 0; i < num_chans; i++) {
+		if (isset(bitmap, i) && input[i]->secs[0].congest_obss < min_obss) {
+			winner = i;
+			min_obss = input[i]->secs[0].congest_obss;
+		}
+	}
+	*answer = input[winner]->chanspec;
+	f_exit:
+	free(bitmap);	/* free the allocated memory for bitmap */
+	return ret_val;
+}
+#endif /* !BCMDRIVER */
+
+/* offset of cntmember by sizeof(uint32) from the first cnt variable, txframe. */
+#define IDX_IN_WL_CNT_VER_6_T(cntmember)		\
+	((OFFSETOF(wl_cnt_ver_6_t, cntmember) - OFFSETOF(wl_cnt_ver_6_t, txframe)) / sizeof(uint32))
+
+#define IDX_IN_WL_CNT_VER_7_T(cntmember)		\
+	((OFFSETOF(wl_cnt_ver_7_t, cntmember) - OFFSETOF(wl_cnt_ver_7_t, txframe)) / sizeof(uint32))
+
+#define IDX_IN_WL_CNT_VER_11_T(cntmember)		\
+	((OFFSETOF(wl_cnt_ver_11_t, cntmember) - OFFSETOF(wl_cnt_ver_11_t, txframe))	\
+	/ sizeof(uint32))
+
+/* Exclude version and length fields */
+#define NUM_OF_CNT_IN_WL_CNT_VER_6_T	\
+	((sizeof(wl_cnt_ver_6_t) - 2 * sizeof(uint16)) / sizeof(uint32))
+/* Exclude macstat cnt variables. wl_cnt_ver_6_t only has 62 macstat cnt variables. */
+#define NUM_OF_WLCCNT_IN_WL_CNT_VER_6_T			\
+	(NUM_OF_CNT_IN_WL_CNT_VER_6_T - (WL_CNT_MCST_VAR_NUM - 2))
+
+/* Exclude version and length fields */
+#define NUM_OF_CNT_IN_WL_CNT_VER_7_T	\
+	((sizeof(wl_cnt_ver_7_t) - 2 * sizeof(uint16)) / sizeof(uint32))
+
+/* Exclude version and length fields */
+#define NUM_OF_CNT_IN_WL_CNT_VER_11_T	\
+	((sizeof(wl_cnt_ver_11_t) - 2 * sizeof(uint16)) / sizeof(uint32))
+/* Exclude 64 macstat cnt variables. */
+#define NUM_OF_WLCCNT_IN_WL_CNT_VER_11_T	\
+	((sizeof(wl_cnt_wlc_t)) / sizeof(uint32))
+
+/* Index conversion table from wl_cnt_ver_6_t to wl_cnt_wlc_t */
+static const uint8 wlcntver6t_to_wlcntwlct[NUM_OF_WLCCNT_IN_WL_CNT_VER_6_T] = {
+	IDX_IN_WL_CNT_VER_6_T(txframe),
+	IDX_IN_WL_CNT_VER_6_T(txbyte),
+	IDX_IN_WL_CNT_VER_6_T(txretrans),
+	IDX_IN_WL_CNT_VER_6_T(txerror),
+	IDX_IN_WL_CNT_VER_6_T(txctl),
+	IDX_IN_WL_CNT_VER_6_T(txprshort),
+	IDX_IN_WL_CNT_VER_6_T(txserr),
+	IDX_IN_WL_CNT_VER_6_T(txnobuf),
+	IDX_IN_WL_CNT_VER_6_T(txnoassoc),
+	IDX_IN_WL_CNT_VER_6_T(txrunt),
+	IDX_IN_WL_CNT_VER_6_T(txchit),
+	IDX_IN_WL_CNT_VER_6_T(txcmiss),
+	IDX_IN_WL_CNT_VER_6_T(txuflo),
+	IDX_IN_WL_CNT_VER_6_T(txphyerr),
+	IDX_IN_WL_CNT_VER_6_T(txphycrs),
+	IDX_IN_WL_CNT_VER_6_T(rxframe),
+	IDX_IN_WL_CNT_VER_6_T(rxbyte),
+	IDX_IN_WL_CNT_VER_6_T(rxerror),
+	IDX_IN_WL_CNT_VER_6_T(rxctl),
+	IDX_IN_WL_CNT_VER_6_T(rxnobuf),
+	IDX_IN_WL_CNT_VER_6_T(rxnondata),
+	IDX_IN_WL_CNT_VER_6_T(rxbadds),
+	IDX_IN_WL_CNT_VER_6_T(rxbadcm),
+	IDX_IN_WL_CNT_VER_6_T(rxfragerr),
+	IDX_IN_WL_CNT_VER_6_T(rxrunt),
+	IDX_IN_WL_CNT_VER_6_T(rxgiant),
+	IDX_IN_WL_CNT_VER_6_T(rxnoscb),
+	IDX_IN_WL_CNT_VER_6_T(rxbadproto),
+	IDX_IN_WL_CNT_VER_6_T(rxbadsrcmac),
+	IDX_IN_WL_CNT_VER_6_T(rxbadda),
+	IDX_IN_WL_CNT_VER_6_T(rxfilter),
+	IDX_IN_WL_CNT_VER_6_T(rxoflo),
+	IDX_IN_WL_CNT_VER_6_T(rxuflo),
+	IDX_IN_WL_CNT_VER_6_T(rxuflo) + 1,
+	IDX_IN_WL_CNT_VER_6_T(rxuflo) + 2,
+	IDX_IN_WL_CNT_VER_6_T(rxuflo) + 3,
+	IDX_IN_WL_CNT_VER_6_T(rxuflo) + 4,
+	IDX_IN_WL_CNT_VER_6_T(rxuflo) + 5,
+	IDX_IN_WL_CNT_VER_6_T(d11cnt_txrts_off),
+	IDX_IN_WL_CNT_VER_6_T(d11cnt_rxcrc_off),
+	IDX_IN_WL_CNT_VER_6_T(d11cnt_txnocts_off),
+	IDX_IN_WL_CNT_VER_6_T(dmade),
+	IDX_IN_WL_CNT_VER_6_T(dmada),
+	IDX_IN_WL_CNT_VER_6_T(dmape),
+	IDX_IN_WL_CNT_VER_6_T(reset),
+	IDX_IN_WL_CNT_VER_6_T(tbtt),
+	IDX_IN_WL_CNT_VER_6_T(txdmawar),
+	IDX_IN_WL_CNT_VER_6_T(pkt_callback_reg_fail),
+	IDX_IN_WL_CNT_VER_6_T(txfrag),
+	IDX_IN_WL_CNT_VER_6_T(txmulti),
+	IDX_IN_WL_CNT_VER_6_T(txfail),
+	IDX_IN_WL_CNT_VER_6_T(txretry),
+	IDX_IN_WL_CNT_VER_6_T(txretrie),
+	IDX_IN_WL_CNT_VER_6_T(rxdup),
+	IDX_IN_WL_CNT_VER_6_T(txrts),
+	IDX_IN_WL_CNT_VER_6_T(txnocts),
+	IDX_IN_WL_CNT_VER_6_T(txnoack),
+	IDX_IN_WL_CNT_VER_6_T(rxfrag),
+	IDX_IN_WL_CNT_VER_6_T(rxmulti),
+	IDX_IN_WL_CNT_VER_6_T(rxcrc),
+	IDX_IN_WL_CNT_VER_6_T(txfrmsnt),
+	IDX_IN_WL_CNT_VER_6_T(rxundec),
+	IDX_IN_WL_CNT_VER_6_T(tkipmicfaill),
+	IDX_IN_WL_CNT_VER_6_T(tkipcntrmsr),
+	IDX_IN_WL_CNT_VER_6_T(tkipreplay),
+	IDX_IN_WL_CNT_VER_6_T(ccmpfmterr),
+	IDX_IN_WL_CNT_VER_6_T(ccmpreplay),
+	IDX_IN_WL_CNT_VER_6_T(ccmpundec),
+	IDX_IN_WL_CNT_VER_6_T(fourwayfail),
+	IDX_IN_WL_CNT_VER_6_T(wepundec),
+	IDX_IN_WL_CNT_VER_6_T(wepicverr),
+	IDX_IN_WL_CNT_VER_6_T(decsuccess),
+	IDX_IN_WL_CNT_VER_6_T(tkipicverr),
+	IDX_IN_WL_CNT_VER_6_T(wepexcluded),
+	IDX_IN_WL_CNT_VER_6_T(txchanrej),
+	IDX_IN_WL_CNT_VER_6_T(psmwds),
+	IDX_IN_WL_CNT_VER_6_T(phywatchdog),
+	IDX_IN_WL_CNT_VER_6_T(prq_entries_handled),
+	IDX_IN_WL_CNT_VER_6_T(prq_undirected_entries),
+	IDX_IN_WL_CNT_VER_6_T(prq_bad_entries),
+	IDX_IN_WL_CNT_VER_6_T(atim_suppress_count),
+	IDX_IN_WL_CNT_VER_6_T(bcn_template_not_ready),
+	IDX_IN_WL_CNT_VER_6_T(bcn_template_not_ready_done),
+	IDX_IN_WL_CNT_VER_6_T(late_tbtt_dpc),
+	IDX_IN_WL_CNT_VER_6_T(rx1mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx2mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx5mbps5),
+	IDX_IN_WL_CNT_VER_6_T(rx6mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx9mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx11mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx12mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx18mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx24mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx36mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx48mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx54mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx108mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx162mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx216mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx270mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx324mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx378mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx432mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx486mbps),
+	IDX_IN_WL_CNT_VER_6_T(rx540mbps),
+	IDX_IN_WL_CNT_VER_6_T(rfdisable),
+	IDX_IN_WL_CNT_VER_6_T(txexptime),
+	IDX_IN_WL_CNT_VER_6_T(txmpdu_sgi),
+	IDX_IN_WL_CNT_VER_6_T(rxmpdu_sgi),
+	IDX_IN_WL_CNT_VER_6_T(txmpdu_stbc),
+	IDX_IN_WL_CNT_VER_6_T(rxmpdu_stbc),
+	IDX_IN_WL_CNT_VER_6_T(rxundec_mcst),
+	IDX_IN_WL_CNT_VER_6_T(tkipmicfaill_mcst),
+	IDX_IN_WL_CNT_VER_6_T(tkipcntrmsr_mcst),
+	IDX_IN_WL_CNT_VER_6_T(tkipreplay_mcst),
+	IDX_IN_WL_CNT_VER_6_T(ccmpfmterr_mcst),
+	IDX_IN_WL_CNT_VER_6_T(ccmpreplay_mcst),
+	IDX_IN_WL_CNT_VER_6_T(ccmpundec_mcst),
+	IDX_IN_WL_CNT_VER_6_T(fourwayfail_mcst),
+	IDX_IN_WL_CNT_VER_6_T(wepundec_mcst),
+	IDX_IN_WL_CNT_VER_6_T(wepicverr_mcst),
+	IDX_IN_WL_CNT_VER_6_T(decsuccess_mcst),
+	IDX_IN_WL_CNT_VER_6_T(tkipicverr_mcst),
+	IDX_IN_WL_CNT_VER_6_T(wepexcluded_mcst)
+};
+
+#define INVALID_IDX ((uint8)(-1))
+
+/* Index conversion table from wl_cnt_ver_7_t to wl_cnt_wlc_t */
+static const uint8 wlcntver7t_to_wlcntwlct[] = {
+	IDX_IN_WL_CNT_VER_7_T(txframe),
+	IDX_IN_WL_CNT_VER_7_T(txbyte),
+	IDX_IN_WL_CNT_VER_7_T(txretrans),
+	IDX_IN_WL_CNT_VER_7_T(txerror),
+	IDX_IN_WL_CNT_VER_7_T(txctl),
+	IDX_IN_WL_CNT_VER_7_T(txprshort),
+	IDX_IN_WL_CNT_VER_7_T(txserr),
+	IDX_IN_WL_CNT_VER_7_T(txnobuf),
+	IDX_IN_WL_CNT_VER_7_T(txnoassoc),
+	IDX_IN_WL_CNT_VER_7_T(txrunt),
+	IDX_IN_WL_CNT_VER_7_T(txchit),
+	IDX_IN_WL_CNT_VER_7_T(txcmiss),
+	IDX_IN_WL_CNT_VER_7_T(txuflo),
+	IDX_IN_WL_CNT_VER_7_T(txphyerr),
+	IDX_IN_WL_CNT_VER_7_T(txphycrs),
+	IDX_IN_WL_CNT_VER_7_T(rxframe),
+	IDX_IN_WL_CNT_VER_7_T(rxbyte),
+	IDX_IN_WL_CNT_VER_7_T(rxerror),
+	IDX_IN_WL_CNT_VER_7_T(rxctl),
+	IDX_IN_WL_CNT_VER_7_T(rxnobuf),
+	IDX_IN_WL_CNT_VER_7_T(rxnondata),
+	IDX_IN_WL_CNT_VER_7_T(rxbadds),
+	IDX_IN_WL_CNT_VER_7_T(rxbadcm),
+	IDX_IN_WL_CNT_VER_7_T(rxfragerr),
+	IDX_IN_WL_CNT_VER_7_T(rxrunt),
+	IDX_IN_WL_CNT_VER_7_T(rxgiant),
+	IDX_IN_WL_CNT_VER_7_T(rxnoscb),
+	IDX_IN_WL_CNT_VER_7_T(rxbadproto),
+	IDX_IN_WL_CNT_VER_7_T(rxbadsrcmac),
+	IDX_IN_WL_CNT_VER_7_T(rxbadda),
+	IDX_IN_WL_CNT_VER_7_T(rxfilter),
+	IDX_IN_WL_CNT_VER_7_T(rxoflo),
+	IDX_IN_WL_CNT_VER_7_T(rxuflo),
+	IDX_IN_WL_CNT_VER_7_T(rxuflo) + 1,
+	IDX_IN_WL_CNT_VER_7_T(rxuflo) + 2,
+	IDX_IN_WL_CNT_VER_7_T(rxuflo) + 3,
+	IDX_IN_WL_CNT_VER_7_T(rxuflo) + 4,
+	IDX_IN_WL_CNT_VER_7_T(rxuflo) + 5,
+	IDX_IN_WL_CNT_VER_7_T(d11cnt_txrts_off),
+	IDX_IN_WL_CNT_VER_7_T(d11cnt_rxcrc_off),
+	IDX_IN_WL_CNT_VER_7_T(d11cnt_txnocts_off),
+	IDX_IN_WL_CNT_VER_7_T(dmade),
+	IDX_IN_WL_CNT_VER_7_T(dmada),
+	IDX_IN_WL_CNT_VER_7_T(dmape),
+	IDX_IN_WL_CNT_VER_7_T(reset),
+	IDX_IN_WL_CNT_VER_7_T(tbtt),
+	IDX_IN_WL_CNT_VER_7_T(txdmawar),
+	IDX_IN_WL_CNT_VER_7_T(pkt_callback_reg_fail),
+	IDX_IN_WL_CNT_VER_7_T(txfrag),
+	IDX_IN_WL_CNT_VER_7_T(txmulti),
+	IDX_IN_WL_CNT_VER_7_T(txfail),
+	IDX_IN_WL_CNT_VER_7_T(txretry),
+	IDX_IN_WL_CNT_VER_7_T(txretrie),
+	IDX_IN_WL_CNT_VER_7_T(rxdup),
+	IDX_IN_WL_CNT_VER_7_T(txrts),
+	IDX_IN_WL_CNT_VER_7_T(txnocts),
+	IDX_IN_WL_CNT_VER_7_T(txnoack),
+	IDX_IN_WL_CNT_VER_7_T(rxfrag),
+	IDX_IN_WL_CNT_VER_7_T(rxmulti),
+	IDX_IN_WL_CNT_VER_7_T(rxcrc),
+	IDX_IN_WL_CNT_VER_7_T(txfrmsnt),
+	IDX_IN_WL_CNT_VER_7_T(rxundec),
+	IDX_IN_WL_CNT_VER_7_T(tkipmicfaill),
+	IDX_IN_WL_CNT_VER_7_T(tkipcntrmsr),
+	IDX_IN_WL_CNT_VER_7_T(tkipreplay),
+	IDX_IN_WL_CNT_VER_7_T(ccmpfmterr),
+	IDX_IN_WL_CNT_VER_7_T(ccmpreplay),
+	IDX_IN_WL_CNT_VER_7_T(ccmpundec),
+	IDX_IN_WL_CNT_VER_7_T(fourwayfail),
+	IDX_IN_WL_CNT_VER_7_T(wepundec),
+	IDX_IN_WL_CNT_VER_7_T(wepicverr),
+	IDX_IN_WL_CNT_VER_7_T(decsuccess),
+	IDX_IN_WL_CNT_VER_7_T(tkipicverr),
+	IDX_IN_WL_CNT_VER_7_T(wepexcluded),
+	IDX_IN_WL_CNT_VER_7_T(txchanrej),
+	IDX_IN_WL_CNT_VER_7_T(psmwds),
+	IDX_IN_WL_CNT_VER_7_T(phywatchdog),
+	IDX_IN_WL_CNT_VER_7_T(prq_entries_handled),
+	IDX_IN_WL_CNT_VER_7_T(prq_undirected_entries),
+	IDX_IN_WL_CNT_VER_7_T(prq_bad_entries),
+	IDX_IN_WL_CNT_VER_7_T(atim_suppress_count),
+	IDX_IN_WL_CNT_VER_7_T(bcn_template_not_ready),
+	IDX_IN_WL_CNT_VER_7_T(bcn_template_not_ready_done),
+	IDX_IN_WL_CNT_VER_7_T(late_tbtt_dpc),
+	IDX_IN_WL_CNT_VER_7_T(rx1mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx2mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx5mbps5),
+	IDX_IN_WL_CNT_VER_7_T(rx6mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx9mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx11mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx12mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx18mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx24mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx36mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx48mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx54mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx108mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx162mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx216mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx270mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx324mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx378mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx432mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx486mbps),
+	IDX_IN_WL_CNT_VER_7_T(rx540mbps),
+	IDX_IN_WL_CNT_VER_7_T(rfdisable),
+	IDX_IN_WL_CNT_VER_7_T(txexptime),
+	IDX_IN_WL_CNT_VER_7_T(txmpdu_sgi),
+	IDX_IN_WL_CNT_VER_7_T(rxmpdu_sgi),
+	IDX_IN_WL_CNT_VER_7_T(txmpdu_stbc),
+	IDX_IN_WL_CNT_VER_7_T(rxmpdu_stbc),
+	IDX_IN_WL_CNT_VER_7_T(rxundec_mcst),
+	IDX_IN_WL_CNT_VER_7_T(tkipmicfaill_mcst),
+	IDX_IN_WL_CNT_VER_7_T(tkipcntrmsr_mcst),
+	IDX_IN_WL_CNT_VER_7_T(tkipreplay_mcst),
+	IDX_IN_WL_CNT_VER_7_T(ccmpfmterr_mcst),
+	IDX_IN_WL_CNT_VER_7_T(ccmpreplay_mcst),
+	IDX_IN_WL_CNT_VER_7_T(ccmpundec_mcst),
+	IDX_IN_WL_CNT_VER_7_T(fourwayfail_mcst),
+	IDX_IN_WL_CNT_VER_7_T(wepundec_mcst),
+	IDX_IN_WL_CNT_VER_7_T(wepicverr_mcst),
+	IDX_IN_WL_CNT_VER_7_T(decsuccess_mcst),
+	IDX_IN_WL_CNT_VER_7_T(tkipicverr_mcst),
+	IDX_IN_WL_CNT_VER_7_T(wepexcluded_mcst),
+	IDX_IN_WL_CNT_VER_7_T(dma_hang),
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	IDX_IN_WL_CNT_VER_7_T(rxrtry)
+};
+
+/* Max wl_cnt_wlc_t fields including rxrtry */
+#define NUM_OF_WLCCNT_IN_WL_CNT_VER_7_T				\
+	(sizeof(wlcntver7t_to_wlcntwlct) / sizeof(uint8))
+
+/* Index conversion table from wl_cnt_ver_11_t to wl_cnt_wlc_t */
+static const uint8 wlcntver11t_to_wlcntwlct[NUM_OF_WLCCNT_IN_WL_CNT_VER_11_T] = {
+	IDX_IN_WL_CNT_VER_11_T(txframe),
+	IDX_IN_WL_CNT_VER_11_T(txbyte),
+	IDX_IN_WL_CNT_VER_11_T(txretrans),
+	IDX_IN_WL_CNT_VER_11_T(txerror),
+	IDX_IN_WL_CNT_VER_11_T(txctl),
+	IDX_IN_WL_CNT_VER_11_T(txprshort),
+	IDX_IN_WL_CNT_VER_11_T(txserr),
+	IDX_IN_WL_CNT_VER_11_T(txnobuf),
+	IDX_IN_WL_CNT_VER_11_T(txnoassoc),
+	IDX_IN_WL_CNT_VER_11_T(txrunt),
+	IDX_IN_WL_CNT_VER_11_T(txchit),
+	IDX_IN_WL_CNT_VER_11_T(txcmiss),
+	IDX_IN_WL_CNT_VER_11_T(txuflo),
+	IDX_IN_WL_CNT_VER_11_T(txphyerr),
+	IDX_IN_WL_CNT_VER_11_T(txphycrs),
+	IDX_IN_WL_CNT_VER_11_T(rxframe),
+	IDX_IN_WL_CNT_VER_11_T(rxbyte),
+	IDX_IN_WL_CNT_VER_11_T(rxerror),
+	IDX_IN_WL_CNT_VER_11_T(rxctl),
+	IDX_IN_WL_CNT_VER_11_T(rxnobuf),
+	IDX_IN_WL_CNT_VER_11_T(rxnondata),
+	IDX_IN_WL_CNT_VER_11_T(rxbadds),
+	IDX_IN_WL_CNT_VER_11_T(rxbadcm),
+	IDX_IN_WL_CNT_VER_11_T(rxfragerr),
+	IDX_IN_WL_CNT_VER_11_T(rxrunt),
+	IDX_IN_WL_CNT_VER_11_T(rxgiant),
+	IDX_IN_WL_CNT_VER_11_T(rxnoscb),
+	IDX_IN_WL_CNT_VER_11_T(rxbadproto),
+	IDX_IN_WL_CNT_VER_11_T(rxbadsrcmac),
+	IDX_IN_WL_CNT_VER_11_T(rxbadda),
+	IDX_IN_WL_CNT_VER_11_T(rxfilter),
+	IDX_IN_WL_CNT_VER_11_T(rxoflo),
+	IDX_IN_WL_CNT_VER_11_T(rxuflo),
+	IDX_IN_WL_CNT_VER_11_T(rxuflo) + 1,
+	IDX_IN_WL_CNT_VER_11_T(rxuflo) + 2,
+	IDX_IN_WL_CNT_VER_11_T(rxuflo) + 3,
+	IDX_IN_WL_CNT_VER_11_T(rxuflo) + 4,
+	IDX_IN_WL_CNT_VER_11_T(rxuflo) + 5,
+	IDX_IN_WL_CNT_VER_11_T(d11cnt_txrts_off),
+	IDX_IN_WL_CNT_VER_11_T(d11cnt_rxcrc_off),
+	IDX_IN_WL_CNT_VER_11_T(d11cnt_txnocts_off),
+	IDX_IN_WL_CNT_VER_11_T(dmade),
+	IDX_IN_WL_CNT_VER_11_T(dmada),
+	IDX_IN_WL_CNT_VER_11_T(dmape),
+	IDX_IN_WL_CNT_VER_11_T(reset),
+	IDX_IN_WL_CNT_VER_11_T(tbtt),
+	IDX_IN_WL_CNT_VER_11_T(txdmawar),
+	IDX_IN_WL_CNT_VER_11_T(pkt_callback_reg_fail),
+	IDX_IN_WL_CNT_VER_11_T(txfrag),
+	IDX_IN_WL_CNT_VER_11_T(txmulti),
+	IDX_IN_WL_CNT_VER_11_T(txfail),
+	IDX_IN_WL_CNT_VER_11_T(txretry),
+	IDX_IN_WL_CNT_VER_11_T(txretrie),
+	IDX_IN_WL_CNT_VER_11_T(rxdup),
+	IDX_IN_WL_CNT_VER_11_T(txrts),
+	IDX_IN_WL_CNT_VER_11_T(txnocts),
+	IDX_IN_WL_CNT_VER_11_T(txnoack),
+	IDX_IN_WL_CNT_VER_11_T(rxfrag),
+	IDX_IN_WL_CNT_VER_11_T(rxmulti),
+	IDX_IN_WL_CNT_VER_11_T(rxcrc),
+	IDX_IN_WL_CNT_VER_11_T(txfrmsnt),
+	IDX_IN_WL_CNT_VER_11_T(rxundec),
+	IDX_IN_WL_CNT_VER_11_T(tkipmicfaill),
+	IDX_IN_WL_CNT_VER_11_T(tkipcntrmsr),
+	IDX_IN_WL_CNT_VER_11_T(tkipreplay),
+	IDX_IN_WL_CNT_VER_11_T(ccmpfmterr),
+	IDX_IN_WL_CNT_VER_11_T(ccmpreplay),
+	IDX_IN_WL_CNT_VER_11_T(ccmpundec),
+	IDX_IN_WL_CNT_VER_11_T(fourwayfail),
+	IDX_IN_WL_CNT_VER_11_T(wepundec),
+	IDX_IN_WL_CNT_VER_11_T(wepicverr),
+	IDX_IN_WL_CNT_VER_11_T(decsuccess),
+	IDX_IN_WL_CNT_VER_11_T(tkipicverr),
+	IDX_IN_WL_CNT_VER_11_T(wepexcluded),
+	IDX_IN_WL_CNT_VER_11_T(txchanrej),
+	IDX_IN_WL_CNT_VER_11_T(psmwds),
+	IDX_IN_WL_CNT_VER_11_T(phywatchdog),
+	IDX_IN_WL_CNT_VER_11_T(prq_entries_handled),
+	IDX_IN_WL_CNT_VER_11_T(prq_undirected_entries),
+	IDX_IN_WL_CNT_VER_11_T(prq_bad_entries),
+	IDX_IN_WL_CNT_VER_11_T(atim_suppress_count),
+	IDX_IN_WL_CNT_VER_11_T(bcn_template_not_ready),
+	IDX_IN_WL_CNT_VER_11_T(bcn_template_not_ready_done),
+	IDX_IN_WL_CNT_VER_11_T(late_tbtt_dpc),
+	IDX_IN_WL_CNT_VER_11_T(rx1mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx2mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx5mbps5),
+	IDX_IN_WL_CNT_VER_11_T(rx6mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx9mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx11mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx12mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx18mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx24mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx36mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx48mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx54mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx108mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx162mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx216mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx270mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx324mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx378mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx432mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx486mbps),
+	IDX_IN_WL_CNT_VER_11_T(rx540mbps),
+	IDX_IN_WL_CNT_VER_11_T(rfdisable),
+	IDX_IN_WL_CNT_VER_11_T(txexptime),
+	IDX_IN_WL_CNT_VER_11_T(txmpdu_sgi),
+	IDX_IN_WL_CNT_VER_11_T(rxmpdu_sgi),
+	IDX_IN_WL_CNT_VER_11_T(txmpdu_stbc),
+	IDX_IN_WL_CNT_VER_11_T(rxmpdu_stbc),
+	IDX_IN_WL_CNT_VER_11_T(rxundec_mcst),
+	IDX_IN_WL_CNT_VER_11_T(tkipmicfaill_mcst),
+	IDX_IN_WL_CNT_VER_11_T(tkipcntrmsr_mcst),
+	IDX_IN_WL_CNT_VER_11_T(tkipreplay_mcst),
+	IDX_IN_WL_CNT_VER_11_T(ccmpfmterr_mcst),
+	IDX_IN_WL_CNT_VER_11_T(ccmpreplay_mcst),
+	IDX_IN_WL_CNT_VER_11_T(ccmpundec_mcst),
+	IDX_IN_WL_CNT_VER_11_T(fourwayfail_mcst),
+	IDX_IN_WL_CNT_VER_11_T(wepundec_mcst),
+	IDX_IN_WL_CNT_VER_11_T(wepicverr_mcst),
+	IDX_IN_WL_CNT_VER_11_T(decsuccess_mcst),
+	IDX_IN_WL_CNT_VER_11_T(tkipicverr_mcst),
+	IDX_IN_WL_CNT_VER_11_T(wepexcluded_mcst),
+	IDX_IN_WL_CNT_VER_11_T(dma_hang),
+	IDX_IN_WL_CNT_VER_11_T(reinit),
+	IDX_IN_WL_CNT_VER_11_T(pstatxucast),
+	IDX_IN_WL_CNT_VER_11_T(pstatxnoassoc),
+	IDX_IN_WL_CNT_VER_11_T(pstarxucast),
+	IDX_IN_WL_CNT_VER_11_T(pstarxbcmc),
+	IDX_IN_WL_CNT_VER_11_T(pstatxbcmc),
+	IDX_IN_WL_CNT_VER_11_T(cso_passthrough),
+	IDX_IN_WL_CNT_VER_11_T(cso_normal),
+	IDX_IN_WL_CNT_VER_11_T(chained),
+	IDX_IN_WL_CNT_VER_11_T(chainedsz1),
+	IDX_IN_WL_CNT_VER_11_T(unchained),
+	IDX_IN_WL_CNT_VER_11_T(maxchainsz),
+	IDX_IN_WL_CNT_VER_11_T(currchainsz),
+	IDX_IN_WL_CNT_VER_11_T(pciereset),
+	IDX_IN_WL_CNT_VER_11_T(cfgrestore),
+	IDX_IN_WL_CNT_VER_11_T(reinitreason),
+	IDX_IN_WL_CNT_VER_11_T(reinitreason) + 1,
+	IDX_IN_WL_CNT_VER_11_T(reinitreason) + 2,
+	IDX_IN_WL_CNT_VER_11_T(reinitreason) + 3,
+	IDX_IN_WL_CNT_VER_11_T(reinitreason) + 4,
+	IDX_IN_WL_CNT_VER_11_T(reinitreason) + 5,
+	IDX_IN_WL_CNT_VER_11_T(reinitreason) + 6,
+	IDX_IN_WL_CNT_VER_11_T(reinitreason) + 7,
+	IDX_IN_WL_CNT_VER_11_T(rxrtry),
+	IDX_IN_WL_CNT_VER_11_T(rxmpdu_mu),
+	IDX_IN_WL_CNT_VER_11_T(txbar),
+	IDX_IN_WL_CNT_VER_11_T(rxbar),
+	IDX_IN_WL_CNT_VER_11_T(txpspoll),
+	IDX_IN_WL_CNT_VER_11_T(rxpspoll),
+	IDX_IN_WL_CNT_VER_11_T(txnull),
+	IDX_IN_WL_CNT_VER_11_T(rxnull),
+	IDX_IN_WL_CNT_VER_11_T(txqosnull),
+	IDX_IN_WL_CNT_VER_11_T(rxqosnull),
+	IDX_IN_WL_CNT_VER_11_T(txassocreq),
+	IDX_IN_WL_CNT_VER_11_T(rxassocreq),
+	IDX_IN_WL_CNT_VER_11_T(txreassocreq),
+	IDX_IN_WL_CNT_VER_11_T(rxreassocreq),
+	IDX_IN_WL_CNT_VER_11_T(txdisassoc),
+	IDX_IN_WL_CNT_VER_11_T(rxdisassoc),
+	IDX_IN_WL_CNT_VER_11_T(txassocrsp),
+	IDX_IN_WL_CNT_VER_11_T(rxassocrsp),
+	IDX_IN_WL_CNT_VER_11_T(txreassocrsp),
+	IDX_IN_WL_CNT_VER_11_T(rxreassocrsp),
+	IDX_IN_WL_CNT_VER_11_T(txauth),
+	IDX_IN_WL_CNT_VER_11_T(rxauth),
+	IDX_IN_WL_CNT_VER_11_T(txdeauth),
+	IDX_IN_WL_CNT_VER_11_T(rxdeauth),
+	IDX_IN_WL_CNT_VER_11_T(txprobereq),
+	IDX_IN_WL_CNT_VER_11_T(rxprobereq),
+	IDX_IN_WL_CNT_VER_11_T(txprobersp),
+	IDX_IN_WL_CNT_VER_11_T(rxprobersp),
+	IDX_IN_WL_CNT_VER_11_T(txaction),
+	IDX_IN_WL_CNT_VER_11_T(rxaction),
+	IDX_IN_WL_CNT_VER_11_T(ampdu_wds),
+	IDX_IN_WL_CNT_VER_11_T(txlost),
+	IDX_IN_WL_CNT_VER_11_T(txdatamcast),
+	IDX_IN_WL_CNT_VER_11_T(txdatabcast),
+	INVALID_IDX,
+	IDX_IN_WL_CNT_VER_11_T(rxback),
+	IDX_IN_WL_CNT_VER_11_T(txback),
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	INVALID_IDX,
+	IDX_IN_WL_CNT_VER_11_T(txbcast),
+	IDX_IN_WL_CNT_VER_11_T(txdropped),
+	IDX_IN_WL_CNT_VER_11_T(rxbcast),
+	IDX_IN_WL_CNT_VER_11_T(rxdropped)
+};
+
+/* Index conversion table from wl_cnt_ver_11_t to
+ * either wl_cnt_ge40mcst_v1_t or wl_cnt_lt40mcst_v1_t
+ */
+static const uint8 wlcntver11t_to_wlcntXX40mcstv1t[WL_CNT_MCST_VAR_NUM] = {
+	IDX_IN_WL_CNT_VER_11_T(txallfrm),
+	IDX_IN_WL_CNT_VER_11_T(txrtsfrm),
+	IDX_IN_WL_CNT_VER_11_T(txctsfrm),
+	IDX_IN_WL_CNT_VER_11_T(txackfrm),
+	IDX_IN_WL_CNT_VER_11_T(txdnlfrm),
+	IDX_IN_WL_CNT_VER_11_T(txbcnfrm),
+	IDX_IN_WL_CNT_VER_11_T(txfunfl),
+	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 1,
+	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 2,
+	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 3,
+	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 4,
+	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 5,
+	IDX_IN_WL_CNT_VER_11_T(txfbw),
+	IDX_IN_WL_CNT_VER_11_T(txmpdu),
+	IDX_IN_WL_CNT_VER_11_T(txtplunfl),
+	IDX_IN_WL_CNT_VER_11_T(txphyerror),
+	IDX_IN_WL_CNT_VER_11_T(pktengrxducast),
+	IDX_IN_WL_CNT_VER_11_T(pktengrxdmcast),
+	IDX_IN_WL_CNT_VER_11_T(rxfrmtoolong),
+	IDX_IN_WL_CNT_VER_11_T(rxfrmtooshrt),
+	IDX_IN_WL_CNT_VER_11_T(rxinvmachdr),
+	IDX_IN_WL_CNT_VER_11_T(rxbadfcs),
+	IDX_IN_WL_CNT_VER_11_T(rxbadplcp),
+	IDX_IN_WL_CNT_VER_11_T(rxcrsglitch),
+	IDX_IN_WL_CNT_VER_11_T(rxstrt),
+	IDX_IN_WL_CNT_VER_11_T(rxdfrmucastmbss),
+	IDX_IN_WL_CNT_VER_11_T(rxmfrmucastmbss),
+	IDX_IN_WL_CNT_VER_11_T(rxcfrmucast),
+	IDX_IN_WL_CNT_VER_11_T(rxrtsucast),
+	IDX_IN_WL_CNT_VER_11_T(rxctsucast),
+	IDX_IN_WL_CNT_VER_11_T(rxackucast),
+	IDX_IN_WL_CNT_VER_11_T(rxdfrmocast),
+	IDX_IN_WL_CNT_VER_11_T(rxmfrmocast),
+	IDX_IN_WL_CNT_VER_11_T(rxcfrmocast),
+	IDX_IN_WL_CNT_VER_11_T(rxrtsocast),
+	IDX_IN_WL_CNT_VER_11_T(rxctsocast),
+	IDX_IN_WL_CNT_VER_11_T(rxdfrmmcast),
+	IDX_IN_WL_CNT_VER_11_T(rxmfrmmcast),
+	IDX_IN_WL_CNT_VER_11_T(rxcfrmmcast),
+	IDX_IN_WL_CNT_VER_11_T(rxbeaconmbss),
+	IDX_IN_WL_CNT_VER_11_T(rxdfrmucastobss),
+	IDX_IN_WL_CNT_VER_11_T(rxbeaconobss),
+	IDX_IN_WL_CNT_VER_11_T(rxrsptmout),
+	IDX_IN_WL_CNT_VER_11_T(bcntxcancl),
+	IDX_IN_WL_CNT_VER_11_T(rxnodelim),
+	IDX_IN_WL_CNT_VER_11_T(rxf0ovfl),
+	IDX_IN_WL_CNT_VER_11_T(rxf1ovfl),
+	IDX_IN_WL_CNT_VER_11_T(rxf2ovfl),
+	IDX_IN_WL_CNT_VER_11_T(txsfovfl),
+	IDX_IN_WL_CNT_VER_11_T(pmqovfl),
+	IDX_IN_WL_CNT_VER_11_T(rxcgprqfrm),
+	IDX_IN_WL_CNT_VER_11_T(rxcgprsqovfl),
+	IDX_IN_WL_CNT_VER_11_T(txcgprsfail),
+	IDX_IN_WL_CNT_VER_11_T(txcgprssuc),
+	IDX_IN_WL_CNT_VER_11_T(prs_timeout),
+	IDX_IN_WL_CNT_VER_11_T(rxnack),
+	IDX_IN_WL_CNT_VER_11_T(frmscons),
+	IDX_IN_WL_CNT_VER_11_T(txnack),
+	IDX_IN_WL_CNT_VER_11_T(rxback),
+	IDX_IN_WL_CNT_VER_11_T(txback),
+	IDX_IN_WL_CNT_VER_11_T(bphy_rxcrsglitch),
+	IDX_IN_WL_CNT_VER_11_T(rxdrop20s),
+	IDX_IN_WL_CNT_VER_11_T(rxtoolate),
+	IDX_IN_WL_CNT_VER_11_T(bphy_badplcp)
+};
+
+/* For mcst offsets that were not used. (2 Pads) */
+#define INVALID_MCST_IDX ((uint8)(-1))
+/* Index conversion table from wl_cnt_ver_11_t to wl_cnt_v_le10_mcst_t */
+static const uint8 wlcntver11t_to_wlcntvle10mcstt[WL_CNT_MCST_VAR_NUM] = {
+	IDX_IN_WL_CNT_VER_11_T(txallfrm),
+	IDX_IN_WL_CNT_VER_11_T(txrtsfrm),
+	IDX_IN_WL_CNT_VER_11_T(txctsfrm),
+	IDX_IN_WL_CNT_VER_11_T(txackfrm),
+	IDX_IN_WL_CNT_VER_11_T(txdnlfrm),
+	IDX_IN_WL_CNT_VER_11_T(txbcnfrm),
+	IDX_IN_WL_CNT_VER_11_T(txfunfl),
+	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 1,
+	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 2,
+	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 3,
+	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 4,
+	IDX_IN_WL_CNT_VER_11_T(txfunfl) + 5,
+	IDX_IN_WL_CNT_VER_11_T(txfbw),
+	INVALID_MCST_IDX,
+	IDX_IN_WL_CNT_VER_11_T(txtplunfl),
+	IDX_IN_WL_CNT_VER_11_T(txphyerror),
+	IDX_IN_WL_CNT_VER_11_T(pktengrxducast),
+	IDX_IN_WL_CNT_VER_11_T(pktengrxdmcast),
+	IDX_IN_WL_CNT_VER_11_T(rxfrmtoolong),
+	IDX_IN_WL_CNT_VER_11_T(rxfrmtooshrt),
+	IDX_IN_WL_CNT_VER_11_T(rxinvmachdr),
+	IDX_IN_WL_CNT_VER_11_T(rxbadfcs),
+	IDX_IN_WL_CNT_VER_11_T(rxbadplcp),
+	IDX_IN_WL_CNT_VER_11_T(rxcrsglitch),
+	IDX_IN_WL_CNT_VER_11_T(rxstrt),
+	IDX_IN_WL_CNT_VER_11_T(rxdfrmucastmbss),
+	IDX_IN_WL_CNT_VER_11_T(rxmfrmucastmbss),
+	IDX_IN_WL_CNT_VER_11_T(rxcfrmucast),
+	IDX_IN_WL_CNT_VER_11_T(rxrtsucast),
+	IDX_IN_WL_CNT_VER_11_T(rxctsucast),
+	IDX_IN_WL_CNT_VER_11_T(rxackucast),
+	IDX_IN_WL_CNT_VER_11_T(rxdfrmocast),
+	IDX_IN_WL_CNT_VER_11_T(rxmfrmocast),
+	IDX_IN_WL_CNT_VER_11_T(rxcfrmocast),
+	IDX_IN_WL_CNT_VER_11_T(rxrtsocast),
+	IDX_IN_WL_CNT_VER_11_T(rxctsocast),
+	IDX_IN_WL_CNT_VER_11_T(rxdfrmmcast),
+	IDX_IN_WL_CNT_VER_11_T(rxmfrmmcast),
+	IDX_IN_WL_CNT_VER_11_T(rxcfrmmcast),
+	IDX_IN_WL_CNT_VER_11_T(rxbeaconmbss),
+	IDX_IN_WL_CNT_VER_11_T(rxdfrmucastobss),
+	IDX_IN_WL_CNT_VER_11_T(rxbeaconobss),
+	IDX_IN_WL_CNT_VER_11_T(rxrsptmout),
+	IDX_IN_WL_CNT_VER_11_T(bcntxcancl),
+	INVALID_MCST_IDX,
+	IDX_IN_WL_CNT_VER_11_T(rxf0ovfl),
+	IDX_IN_WL_CNT_VER_11_T(rxf1ovfl),
+	IDX_IN_WL_CNT_VER_11_T(rxf2ovfl),
+	IDX_IN_WL_CNT_VER_11_T(txsfovfl),
+	IDX_IN_WL_CNT_VER_11_T(pmqovfl),
+	IDX_IN_WL_CNT_VER_11_T(rxcgprqfrm),
+	IDX_IN_WL_CNT_VER_11_T(rxcgprsqovfl),
+	IDX_IN_WL_CNT_VER_11_T(txcgprsfail),
+	IDX_IN_WL_CNT_VER_11_T(txcgprssuc),
+	IDX_IN_WL_CNT_VER_11_T(prs_timeout),
+	IDX_IN_WL_CNT_VER_11_T(rxnack),
+	IDX_IN_WL_CNT_VER_11_T(frmscons),
+	IDX_IN_WL_CNT_VER_11_T(txnack),
+	IDX_IN_WL_CNT_VER_11_T(rxback),
+	IDX_IN_WL_CNT_VER_11_T(txback),
+	IDX_IN_WL_CNT_VER_11_T(bphy_rxcrsglitch),
+	IDX_IN_WL_CNT_VER_11_T(rxdrop20s),
+	IDX_IN_WL_CNT_VER_11_T(rxtoolate),
+	IDX_IN_WL_CNT_VER_11_T(bphy_badplcp)
+};
+
+/* Index conversion table from wl_cnt_ver_6_t to wl_cnt_v_le10_mcst_t */
+static const uint8 wlcntver6t_to_wlcntvle10mcstt[WL_CNT_MCST_VAR_NUM] = {
+	IDX_IN_WL_CNT_VER_6_T(txallfrm),
+	IDX_IN_WL_CNT_VER_6_T(txrtsfrm),
+	IDX_IN_WL_CNT_VER_6_T(txctsfrm),
+	IDX_IN_WL_CNT_VER_6_T(txackfrm),
+	IDX_IN_WL_CNT_VER_6_T(txdnlfrm),
+	IDX_IN_WL_CNT_VER_6_T(txbcnfrm),
+	IDX_IN_WL_CNT_VER_6_T(txfunfl),
+	IDX_IN_WL_CNT_VER_6_T(txfunfl) + 1,
+	IDX_IN_WL_CNT_VER_6_T(txfunfl) + 2,
+	IDX_IN_WL_CNT_VER_6_T(txfunfl) + 3,
+	IDX_IN_WL_CNT_VER_6_T(txfunfl) + 4,
+	IDX_IN_WL_CNT_VER_6_T(txfunfl) + 5,
+	IDX_IN_WL_CNT_VER_6_T(txfbw),
+	INVALID_MCST_IDX,
+	IDX_IN_WL_CNT_VER_6_T(txtplunfl),
+	IDX_IN_WL_CNT_VER_6_T(txphyerror),
+	IDX_IN_WL_CNT_VER_6_T(pktengrxducast),
+	IDX_IN_WL_CNT_VER_6_T(pktengrxdmcast),
+	IDX_IN_WL_CNT_VER_6_T(rxfrmtoolong),
+	IDX_IN_WL_CNT_VER_6_T(rxfrmtooshrt),
+	IDX_IN_WL_CNT_VER_6_T(rxinvmachdr),
+	IDX_IN_WL_CNT_VER_6_T(rxbadfcs),
+	IDX_IN_WL_CNT_VER_6_T(rxbadplcp),
+	IDX_IN_WL_CNT_VER_6_T(rxcrsglitch),
+	IDX_IN_WL_CNT_VER_6_T(rxstrt),
+	IDX_IN_WL_CNT_VER_6_T(rxdfrmucastmbss),
+	IDX_IN_WL_CNT_VER_6_T(rxmfrmucastmbss),
+	IDX_IN_WL_CNT_VER_6_T(rxcfrmucast),
+	IDX_IN_WL_CNT_VER_6_T(rxrtsucast),
+	IDX_IN_WL_CNT_VER_6_T(rxctsucast),
+	IDX_IN_WL_CNT_VER_6_T(rxackucast),
+	IDX_IN_WL_CNT_VER_6_T(rxdfrmocast),
+	IDX_IN_WL_CNT_VER_6_T(rxmfrmocast),
+	IDX_IN_WL_CNT_VER_6_T(rxcfrmocast),
+	IDX_IN_WL_CNT_VER_6_T(rxrtsocast),
+	IDX_IN_WL_CNT_VER_6_T(rxctsocast),
+	IDX_IN_WL_CNT_VER_6_T(rxdfrmmcast),
+	IDX_IN_WL_CNT_VER_6_T(rxmfrmmcast),
+	IDX_IN_WL_CNT_VER_6_T(rxcfrmmcast),
+	IDX_IN_WL_CNT_VER_6_T(rxbeaconmbss),
+	IDX_IN_WL_CNT_VER_6_T(rxdfrmucastobss),
+	IDX_IN_WL_CNT_VER_6_T(rxbeaconobss),
+	IDX_IN_WL_CNT_VER_6_T(rxrsptmout),
+	IDX_IN_WL_CNT_VER_6_T(bcntxcancl),
+	INVALID_MCST_IDX,
+	IDX_IN_WL_CNT_VER_6_T(rxf0ovfl),
+	IDX_IN_WL_CNT_VER_6_T(rxf1ovfl),
+	IDX_IN_WL_CNT_VER_6_T(rxf2ovfl),
+	IDX_IN_WL_CNT_VER_6_T(txsfovfl),
+	IDX_IN_WL_CNT_VER_6_T(pmqovfl),
+	IDX_IN_WL_CNT_VER_6_T(rxcgprqfrm),
+	IDX_IN_WL_CNT_VER_6_T(rxcgprsqovfl),
+	IDX_IN_WL_CNT_VER_6_T(txcgprsfail),
+	IDX_IN_WL_CNT_VER_6_T(txcgprssuc),
+	IDX_IN_WL_CNT_VER_6_T(prs_timeout),
+	IDX_IN_WL_CNT_VER_6_T(rxnack),
+	IDX_IN_WL_CNT_VER_6_T(frmscons),
+	IDX_IN_WL_CNT_VER_6_T(txnack),
+	IDX_IN_WL_CNT_VER_6_T(rxback),
+	IDX_IN_WL_CNT_VER_6_T(txback),
+	IDX_IN_WL_CNT_VER_6_T(bphy_rxcrsglitch),
+	IDX_IN_WL_CNT_VER_6_T(rxdrop20s),
+	IDX_IN_WL_CNT_VER_6_T(rxtoolate),
+	IDX_IN_WL_CNT_VER_6_T(bphy_badplcp)
+};
+
+/* Index conversion table from wl_cnt_ver_7_t to wl_cnt_v_le10_mcst_t */
+static const uint8 wlcntver7t_to_wlcntvle10mcstt[WL_CNT_MCST_VAR_NUM] = {
+	IDX_IN_WL_CNT_VER_7_T(txallfrm),
+	IDX_IN_WL_CNT_VER_7_T(txrtsfrm),
+	IDX_IN_WL_CNT_VER_7_T(txctsfrm),
+	IDX_IN_WL_CNT_VER_7_T(txackfrm),
+	IDX_IN_WL_CNT_VER_7_T(txdnlfrm),
+	IDX_IN_WL_CNT_VER_7_T(txbcnfrm),
+	IDX_IN_WL_CNT_VER_7_T(txfunfl),
+	IDX_IN_WL_CNT_VER_7_T(txfunfl) + 1,
+	IDX_IN_WL_CNT_VER_7_T(txfunfl) + 2,
+	IDX_IN_WL_CNT_VER_7_T(txfunfl) + 3,
+	IDX_IN_WL_CNT_VER_7_T(txfunfl) + 4,
+	IDX_IN_WL_CNT_VER_7_T(txfunfl) + 5,
+	INVALID_MCST_IDX,
+	INVALID_MCST_IDX,
+	IDX_IN_WL_CNT_VER_7_T(txtplunfl),
+	IDX_IN_WL_CNT_VER_7_T(txphyerror),
+	IDX_IN_WL_CNT_VER_7_T(pktengrxducast),
+	IDX_IN_WL_CNT_VER_7_T(pktengrxdmcast),
+	IDX_IN_WL_CNT_VER_7_T(rxfrmtoolong),
+	IDX_IN_WL_CNT_VER_7_T(rxfrmtooshrt),
+	IDX_IN_WL_CNT_VER_7_T(rxinvmachdr),
+	IDX_IN_WL_CNT_VER_7_T(rxbadfcs),
+	IDX_IN_WL_CNT_VER_7_T(rxbadplcp),
+	IDX_IN_WL_CNT_VER_7_T(rxcrsglitch),
+	IDX_IN_WL_CNT_VER_7_T(rxstrt),
+	IDX_IN_WL_CNT_VER_7_T(rxdfrmucastmbss),
+	IDX_IN_WL_CNT_VER_7_T(rxmfrmucastmbss),
+	IDX_IN_WL_CNT_VER_7_T(rxcfrmucast),
+	IDX_IN_WL_CNT_VER_7_T(rxrtsucast),
+	IDX_IN_WL_CNT_VER_7_T(rxctsucast),
+	IDX_IN_WL_CNT_VER_7_T(rxackucast),
+	IDX_IN_WL_CNT_VER_7_T(rxdfrmocast),
+	IDX_IN_WL_CNT_VER_7_T(rxmfrmocast),
+	IDX_IN_WL_CNT_VER_7_T(rxcfrmocast),
+	IDX_IN_WL_CNT_VER_7_T(rxrtsocast),
+	IDX_IN_WL_CNT_VER_7_T(rxctsocast),
+	IDX_IN_WL_CNT_VER_7_T(rxdfrmmcast),
+	IDX_IN_WL_CNT_VER_7_T(rxmfrmmcast),
+	IDX_IN_WL_CNT_VER_7_T(rxcfrmmcast),
+	IDX_IN_WL_CNT_VER_7_T(rxbeaconmbss),
+	IDX_IN_WL_CNT_VER_7_T(rxdfrmucastobss),
+	IDX_IN_WL_CNT_VER_7_T(rxbeaconobss),
+	IDX_IN_WL_CNT_VER_7_T(rxrsptmout),
+	IDX_IN_WL_CNT_VER_7_T(bcntxcancl),
+	INVALID_MCST_IDX,
+	IDX_IN_WL_CNT_VER_7_T(rxf0ovfl),
+	IDX_IN_WL_CNT_VER_7_T(rxf1ovfl),
+	IDX_IN_WL_CNT_VER_7_T(rxf2ovfl),
+	IDX_IN_WL_CNT_VER_7_T(txsfovfl),
+	IDX_IN_WL_CNT_VER_7_T(pmqovfl),
+	IDX_IN_WL_CNT_VER_7_T(rxcgprqfrm),
+	IDX_IN_WL_CNT_VER_7_T(rxcgprsqovfl),
+	IDX_IN_WL_CNT_VER_7_T(txcgprsfail),
+	IDX_IN_WL_CNT_VER_7_T(txcgprssuc),
+	IDX_IN_WL_CNT_VER_7_T(prs_timeout),
+	IDX_IN_WL_CNT_VER_7_T(rxnack),
+	IDX_IN_WL_CNT_VER_7_T(frmscons),
+	IDX_IN_WL_CNT_VER_7_T(txnack),
+	INVALID_MCST_IDX,
+	INVALID_MCST_IDX,
+	IDX_IN_WL_CNT_VER_7_T(bphy_rxcrsglitch),
+	INVALID_MCST_IDX,
+	INVALID_MCST_IDX,
+	INVALID_MCST_IDX
+};
+
+/* copy wlc layer counters from old type cntbuf to wl_cnt_wlc_t type. */
+static int
+wl_copy_wlccnt(uint16 cntver, uint32 *dst, uint32 *src, uint8 src_max_idx)
+{
+	uint i;
+	if (dst == NULL || src == NULL) {
+		return BCME_ERROR;
+	}
+
+	/* Init wlccnt with invalid value. Unchanged value will not be printed out */
+	for (i = 0; i < (sizeof(wl_cnt_wlc_t) / sizeof(uint32)); i++) {
+		dst[i] = INVALID_CNT_VAL;
+	}
+
+	if (cntver == WL_CNT_VERSION_6) {
+		for (i = 0; i < NUM_OF_WLCCNT_IN_WL_CNT_VER_6_T; i++) {
+			if (wlcntver6t_to_wlcntwlct[i] >= src_max_idx) {
+				/* src buffer does not have counters from here */
+				break;
+			}
+			dst[i] = src[wlcntver6t_to_wlcntwlct[i]];
+		}
+	} else if (cntver == WL_CNT_VERSION_7) {
+		for (i = 0; i < NUM_OF_WLCCNT_IN_WL_CNT_VER_7_T; i++) {
+			if (wlcntver7t_to_wlcntwlct[i] >= src_max_idx ||
+				wlcntver7t_to_wlcntwlct[i] == INVALID_IDX) {
+				continue;
+			}
+			dst[i] = src[wlcntver7t_to_wlcntwlct[i]];
+		}
+	} else {
+		for (i = 0; i < NUM_OF_WLCCNT_IN_WL_CNT_VER_11_T; i++) {
+			if (wlcntver11t_to_wlcntwlct[i] >= src_max_idx) {
+				if (wlcntver11t_to_wlcntwlct[i] == INVALID_IDX) {
+					continue;
+				}
+				else {
+					/* src buffer does not have counters from here */
+					break;
+				}
+			}
+			dst[i] = src[wlcntver11t_to_wlcntwlct[i]];
+		}
+	}
+	return BCME_OK;
+}
+
+/* copy macstat counters from old type cntbuf to wl_cnt_v_le10_mcst_t type. */
+static int
+wl_copy_macstat_upto_ver10(uint16 cntver, uint32 *dst, uint32 *src)
+{
+	uint i;
+
+	if (dst == NULL || src == NULL) {
+		return BCME_ERROR;
+	}
+
+	if (cntver == WL_CNT_VERSION_6) {
+		for (i = 0; i < WL_CNT_MCST_VAR_NUM; i++) {
+			if (wlcntver6t_to_wlcntvle10mcstt[i] == INVALID_MCST_IDX) {
+				/* This mcst counter does not exist in wl_cnt_ver_6_t */
+				dst[i] = INVALID_CNT_VAL;
+			} else {
+				dst[i] = src[wlcntver6t_to_wlcntvle10mcstt[i]];
+			}
+		}
+	} else if (cntver == WL_CNT_VERSION_7) {
+		for (i = 0; i < WL_CNT_MCST_VAR_NUM; i++) {
+			if (wlcntver7t_to_wlcntvle10mcstt[i] == INVALID_MCST_IDX) {
+				/* This mcst counter does not exist in wl_cnt_ver_7_t */
+				dst[i] = INVALID_CNT_VAL;
+			} else {
+				dst[i] = src[wlcntver7t_to_wlcntvle10mcstt[i]];
+			}
+		}
+	} else {
+		for (i = 0; i < WL_CNT_MCST_VAR_NUM; i++) {
+			if (wlcntver11t_to_wlcntvle10mcstt[i] == INVALID_MCST_IDX) {
+				/* This mcst counter does not exist in wl_cnt_ver_11_t */
+				dst[i] = INVALID_CNT_VAL;
+			} else {
+				dst[i] = src[wlcntver11t_to_wlcntvle10mcstt[i]];
+			}
+		}
+	}
+	return BCME_OK;
+}
+
+static int
+wl_copy_macstat_ver11(uint32 *dst, uint32 *src)
+{
+	uint i;
+
+	if (dst == NULL || src == NULL) {
+		return BCME_ERROR;
+	}
+
+	for (i = 0; i < WL_CNT_MCST_VAR_NUM; i++) {
+		dst[i] = src[wlcntver11t_to_wlcntXX40mcstv1t[i]];
+	}
+	return BCME_OK;
+}
+
+/**
+ * Translate non-xtlv 'wl counters' IOVar buffer received by old driver/FW to xtlv format.
+ * Parameters:
+ *	cntbuf: pointer to non-xtlv 'wl counters' IOVar buffer received by old driver/FW.
+ *		Newly translated xtlv format is written to this pointer.
+ *	buflen: length of the "cntbuf" without any padding.
+ *	corerev: chip core revision of the driver/FW.
+ */
+int
+wl_cntbuf_to_xtlv_format(void *ctx, void *cntbuf, int buflen, uint32 corerev)
+{
+	wl_cnt_wlc_t *wlccnt = NULL;
+	uint32 *macstat = NULL;
+	xtlv_desc_t xtlv_desc[3];
+	uint16 mcst_xtlv_id;
+	int res = BCME_OK;
+	wl_cnt_info_t *cntinfo = cntbuf;
+	uint8 *xtlvbuf_p = cntinfo->data;
+	uint16 ver = cntinfo->version;
+	uint16 xtlvbuflen = (uint16)buflen;
+	uint16 src_max_idx;
+#ifdef BCMDRIVER
+	osl_t *osh = ctx;
+#else
+	BCM_REFERENCE(ctx);
+#endif
+
+	if (ver >= WL_CNT_VERSION_XTLV) {
+		/* Already in xtlv format. */
+		goto exit;
+	}
+
+#ifdef BCMDRIVER
+	wlccnt = MALLOCZ(osh, sizeof(*wlccnt));
+	macstat = MALLOCZ(osh, WL_CNT_MCST_STRUCT_SZ);
+#else
+	wlccnt = (wl_cnt_wlc_t *)malloc(sizeof(*wlccnt));
+	macstat = (uint32 *)malloc(WL_CNT_MCST_STRUCT_SZ);
+#endif
+	if (!wlccnt || !macstat) {
+		printf("wl_cntbuf_to_xtlv_format: malloc fail!\n");
+		res = BCME_NOMEM;
+		goto exit;
+	}
+
+	/* Check if the max idx in the struct exceeds the boundary of uint8 */
+	if (NUM_OF_CNT_IN_WL_CNT_VER_6_T > ((uint8)(-1) + 1) ||
+		NUM_OF_CNT_IN_WL_CNT_VER_7_T > ((uint8)(-1) + 1) ||
+		NUM_OF_CNT_IN_WL_CNT_VER_11_T > ((uint8)(-1) + 1)) {
+		printf("wlcntverXXt_to_wlcntwlct and src_max_idx need"
+			" to be of uint16 instead of uint8\n");
+		res = BCME_ERROR;
+		goto exit;
+	}
+
+	/* Exclude version and length fields in either wlc_cnt_ver_6_t or wlc_cnt_ver_11_t */
+	src_max_idx = (cntinfo->datalen - OFFSETOF(wl_cnt_info_t, data)) / sizeof(uint32);
+	if (src_max_idx > (uint8)(-1)) {
+		printf("wlcntverXXt_to_wlcntwlct and src_max_idx need"
+			" to be of uint16 instead of uint8\n"
+			"Try updating wl utility to the latest.\n");
+		src_max_idx = (uint8)(-1);
+	}
+
+	/* Copy wlc layer counters to wl_cnt_wlc_t */
+	res = wl_copy_wlccnt(ver, (uint32 *)wlccnt, (uint32 *)cntinfo->data, (uint8)src_max_idx);
+	if (res != BCME_OK) {
+		printf("wl_copy_wlccnt fail!\n");
+		goto exit;
+	}
+
+	/* Copy macstat counters to wl_cnt_wlc_t */
+	if (ver == WL_CNT_VERSION_11) {
+		res = wl_copy_macstat_ver11(macstat, (uint32 *)cntinfo->data);
+		if (res != BCME_OK) {
+			printf("wl_copy_macstat_ver11 fail!\n");
+			goto exit;
+		}
+		if (corerev >= 40) {
+			mcst_xtlv_id = WL_CNT_XTLV_GE40_UCODE_V1;
+		} else {
+			mcst_xtlv_id = WL_CNT_XTLV_LT40_UCODE_V1;
+		}
+	} else {
+		res = wl_copy_macstat_upto_ver10(ver, macstat, (uint32 *)cntinfo->data);
+		if (res != BCME_OK) {
+			printf("wl_copy_macstat_upto_ver10 fail!\n");
+			goto exit;
+		}
+		mcst_xtlv_id = WL_CNT_XTLV_CNTV_LE10_UCODE;
+	}
+
+	xtlv_desc[0].type = WL_CNT_XTLV_WLC;
+	xtlv_desc[0].len = sizeof(*wlccnt);
+	xtlv_desc[0].ptr = wlccnt;
+
+	xtlv_desc[1].type = mcst_xtlv_id;
+	xtlv_desc[1].len = WL_CNT_MCST_STRUCT_SZ;
+	xtlv_desc[1].ptr = macstat;
+
+	xtlv_desc[2].type = 0;
+	xtlv_desc[2].len = 0;
+	xtlv_desc[2].ptr = NULL;
+
+	bzero(cntbuf, buflen);
+
+	res = bcm_pack_xtlv_buf_from_mem(&xtlvbuf_p, &xtlvbuflen,
+		xtlv_desc, BCM_XTLV_OPTION_ALIGN32);
+	cntinfo->datalen = (buflen - xtlvbuflen);
+exit:
+#ifdef BCMDRIVER
+	if (wlccnt) {
+		MFREE(osh, wlccnt, sizeof(*wlccnt));
+	}
+	if (macstat) {
+		MFREE(osh, macstat, WL_CNT_MCST_STRUCT_SZ);
+	}
+#else
+	if (wlccnt) {
+		free(wlccnt);
+	}
+	if (macstat) {
+		free(macstat);
+	}
+#endif
+	return res;
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcmbloom.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcmbloom.c
@@ -0,0 +1,251 @@
+/*
+ * Bloom filter support
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Dual:>>
+ */
+
+#include <typedefs.h>
+#include <bcmdefs.h>
+
+#ifdef BCMDRIVER
+#include <osl.h>
+#include <bcmutils.h>
+#else /* !BCMDRIVER */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifndef ASSERT
+#define ASSERT(exp)
+#endif
+#endif /* !BCMDRIVER */
+#include <bcmutils.h>
+
+#include <bcmbloom.h>
+
+#define BLOOM_BIT_LEN(_x) ((_x) << 3)
+
+struct bcm_bloom_filter {
+	void *cb_ctx;
+	uint max_hash;
+	bcm_bloom_hash_t *hash;	/* array of hash functions */
+	uint filter_size; 		/* in bytes */
+	uint8 *filter; 			/* can be NULL for validate only */
+};
+
+/* public interface */
+int
+bcm_bloom_create(bcm_bloom_alloc_t alloc_cb,
+	bcm_bloom_free_t free_cb, void *cb_ctx, uint max_hash,
+	uint filter_size, bcm_bloom_filter_t **bloom)
+{
+	int err = BCME_OK;
+	bcm_bloom_filter_t *bp = NULL;
+
+	if (!bloom || !alloc_cb || (max_hash == 0)) {
+		err = BCME_BADARG;
+		goto done;
+	}
+
+	bp = (*alloc_cb)(cb_ctx, sizeof(*bp));
+	if (!bp) {
+		err = BCME_NOMEM;
+		goto done;
+	}
+	bzero(bp, sizeof(*bp));
+
+	bp->cb_ctx = cb_ctx;
+	bp->max_hash = max_hash;
+	bp->hash = (*alloc_cb)(cb_ctx, sizeof(*bp->hash) * max_hash);
+	if (!bp->hash) {
+		err = BCME_NOMEM;
+		goto done;
+	}
+	bzero(bp->hash, sizeof(*bp->hash) * max_hash);
+
+	if (filter_size > 0) {
+		bp->filter = (*alloc_cb)(cb_ctx, filter_size);
+		if (!bp->filter) {
+			err = BCME_NOMEM;
+			goto done;
+		}
+		bp->filter_size = filter_size;
+		bzero(bp->filter, filter_size);
+	}
+
+	*bloom = bp;
+
+done:
+	if (err != BCME_OK)
+		bcm_bloom_destroy(&bp, free_cb);
+
+	return err;
+}
+
+int
+bcm_bloom_destroy(bcm_bloom_filter_t **bloom, bcm_bloom_free_t free_cb)
+{
+	int err = BCME_OK;
+	bcm_bloom_filter_t *bp;
+
+	if (!bloom || !*bloom || !free_cb)
+		goto done;
+
+	bp = *bloom;
+	*bloom = NULL;
+
+	if (bp->filter)
+		(*free_cb)(bp->cb_ctx, bp->filter, bp->filter_size);
+	if (bp->hash)
+		(*free_cb)(bp->cb_ctx, bp->hash,
+			sizeof(*bp->hash) * bp->max_hash);
+	(*free_cb)(bp->cb_ctx, bp, sizeof(*bp));
+
+done:
+	return err;
+}
+
+int
+bcm_bloom_add_hash(bcm_bloom_filter_t *bp, bcm_bloom_hash_t hash, uint *idx)
+{
+	uint i;
+
+	if (!bp || !hash || !idx)
+		return BCME_BADARG;
+
+	for (i = 0; i < bp->max_hash; ++i) {
+		if (bp->hash[i] == NULL)
+			break;
+	}
+
+	if (i >= bp->max_hash)
+		return BCME_NORESOURCE;
+
+	bp->hash[i] = hash;
+	*idx = i;
+	return BCME_OK;
+}
+
+int
+bcm_bloom_remove_hash(bcm_bloom_filter_t *bp, uint idx)
+{
+	if (!bp)
+		return BCME_BADARG;
+
+	if (idx >= bp->max_hash)
+		return BCME_NOTFOUND;
+
+	bp->hash[idx] = NULL;
+	return BCME_OK;
+}
+
+bool
+bcm_bloom_is_member(bcm_bloom_filter_t *bp,
+	const uint8 *tag, uint tag_len, const uint8 *buf, uint buf_len)
+{
+	uint i;
+	int err = BCME_OK;
+
+	if (!tag || (tag_len == 0)) /* empty tag is always a member */
+		goto done;
+
+	/* use internal buffer if none was specified */
+	if (!buf || (buf_len == 0)) {
+		if (!bp->filter)	/* every one is a member of empty filter */
+			goto done;
+
+		buf = bp->filter;
+		buf_len = bp->filter_size;
+	}
+
+	for (i = 0; i < bp->max_hash; ++i) {
+		uint pos;
+		if (!bp->hash[i])
+			continue;
+		pos = (*bp->hash[i])(bp->cb_ctx, i, tag, tag_len);
+
+		/* all bits must be set for a match */
+		if (isclr(buf, pos % BLOOM_BIT_LEN(buf_len))) {
+			err = BCME_NOTFOUND;
+			break;
+		}
+	}
+
+done:
+	return err;
+}
+
+int
+bcm_bloom_add_member(bcm_bloom_filter_t *bp, const uint8 *tag, uint tag_len)
+{
+	uint i;
+
+	if (!bp || !tag || (tag_len == 0))
+		return BCME_BADARG;
+
+	if (!bp->filter)		/* validate only */
+		return BCME_UNSUPPORTED;
+
+	for (i = 0; i < bp->max_hash; ++i) {
+		uint pos;
+		if (!bp->hash[i])
+			continue;
+		pos = (*bp->hash[i])(bp->cb_ctx, i, tag, tag_len);
+		setbit(bp->filter, pos % BLOOM_BIT_LEN(bp->filter_size));
+	}
+
+	return BCME_OK;
+}
+
+int bcm_bloom_get_filter_data(bcm_bloom_filter_t *bp,
+	uint buf_size, uint8 *buf, uint *buf_len)
+{
+	if (!bp)
+		return BCME_BADARG;
+
+	if (buf_len)
+		*buf_len = bp->filter_size;
+
+	if (buf_size < bp->filter_size)
+		return BCME_BUFTOOSHORT;
+
+	if (bp->filter && bp->filter_size)
+		memcpy(buf, bp->filter, bp->filter_size);
+
+	return BCME_OK;
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcmevent.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcmevent.c
@@ -0,0 +1,471 @@
+/*
+ * bcmevent read-only data shared by kernel or app layers
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Dual:>>
+ */
+
+#include <typedefs.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <ethernet.h>
+#include <bcmeth.h>
+#include <bcmevent.h>
+#include <802.11.h>
+#include <802.11brcm.h>
+
+/* Table of event name strings for UIs and debugging dumps */
+typedef struct {
+	uint event;
+	const char *name;
+} bcmevent_name_str_t;
+
+/* Use the actual name for event tracing */
+#define BCMEVENT_NAME(_event) {(_event), #_event}
+
+/* this becomes static data when all code is changed to use
+ * the bcmevent_get_name() API
+ */
+static const bcmevent_name_str_t bcmevent_names[] = {
+	BCMEVENT_NAME(WLC_E_SET_SSID),
+	BCMEVENT_NAME(WLC_E_JOIN),
+	BCMEVENT_NAME(WLC_E_START),
+	BCMEVENT_NAME(WLC_E_AUTH),
+	BCMEVENT_NAME(WLC_E_AUTH_IND),
+	BCMEVENT_NAME(WLC_E_DEAUTH),
+	BCMEVENT_NAME(WLC_E_DEAUTH_IND),
+	BCMEVENT_NAME(WLC_E_ASSOC),
+	BCMEVENT_NAME(WLC_E_ASSOC_IND),
+	BCMEVENT_NAME(WLC_E_REASSOC),
+	BCMEVENT_NAME(WLC_E_REASSOC_IND),
+	BCMEVENT_NAME(WLC_E_DISASSOC),
+	BCMEVENT_NAME(WLC_E_DISASSOC_IND),
+	BCMEVENT_NAME(WLC_E_QUIET_START),
+	BCMEVENT_NAME(WLC_E_QUIET_END),
+	BCMEVENT_NAME(WLC_E_BEACON_RX),
+	BCMEVENT_NAME(WLC_E_LINK),
+	BCMEVENT_NAME(WLC_E_MIC_ERROR),
+	BCMEVENT_NAME(WLC_E_NDIS_LINK),
+	BCMEVENT_NAME(WLC_E_ROAM),
+	BCMEVENT_NAME(WLC_E_TXFAIL),
+	BCMEVENT_NAME(WLC_E_PMKID_CACHE),
+	BCMEVENT_NAME(WLC_E_RETROGRADE_TSF),
+	BCMEVENT_NAME(WLC_E_PRUNE),
+	BCMEVENT_NAME(WLC_E_AUTOAUTH),
+	BCMEVENT_NAME(WLC_E_EAPOL_MSG),
+	BCMEVENT_NAME(WLC_E_SCAN_COMPLETE),
+	BCMEVENT_NAME(WLC_E_ADDTS_IND),
+	BCMEVENT_NAME(WLC_E_DELTS_IND),
+	BCMEVENT_NAME(WLC_E_BCNSENT_IND),
+	BCMEVENT_NAME(WLC_E_BCNRX_MSG),
+	BCMEVENT_NAME(WLC_E_BCNLOST_MSG),
+	BCMEVENT_NAME(WLC_E_ROAM_PREP),
+	BCMEVENT_NAME(WLC_E_PFN_NET_FOUND),
+	BCMEVENT_NAME(WLC_E_PFN_SCAN_ALLGONE),
+	BCMEVENT_NAME(WLC_E_PFN_NET_LOST),
+	BCMEVENT_NAME(WLC_E_JOIN_START),
+	BCMEVENT_NAME(WLC_E_ROAM_START),
+	BCMEVENT_NAME(WLC_E_ASSOC_START),
+#ifdef EXT_STA
+	BCMEVENT_NAME(WLC_E_RESET_COMPLETE),
+	BCMEVENT_NAME(WLC_E_JOIN_START),
+	BCMEVENT_NAME(WLC_E_ROAM_START),
+	BCMEVENT_NAME(WLC_E_ASSOC_START),
+	BCMEVENT_NAME(WLC_E_ASSOC_RECREATED),
+	BCMEVENT_NAME(WLC_E_SPEEDY_RECREATE_FAIL),
+#endif /* EXT_STA */
+#if defined(IBSS_PEER_DISCOVERY_EVENT)
+	BCMEVENT_NAME(WLC_E_IBSS_ASSOC),
+#endif /* defined(IBSS_PEER_DISCOVERY_EVENT) */
+	BCMEVENT_NAME(WLC_E_RADIO),
+	BCMEVENT_NAME(WLC_E_PSM_WATCHDOG),
+	BCMEVENT_NAME(WLC_E_PROBREQ_MSG),
+	BCMEVENT_NAME(WLC_E_SCAN_CONFIRM_IND),
+	BCMEVENT_NAME(WLC_E_PSK_SUP),
+	BCMEVENT_NAME(WLC_E_COUNTRY_CODE_CHANGED),
+	BCMEVENT_NAME(WLC_E_EXCEEDED_MEDIUM_TIME),
+	BCMEVENT_NAME(WLC_E_ICV_ERROR),
+	BCMEVENT_NAME(WLC_E_UNICAST_DECODE_ERROR),
+	BCMEVENT_NAME(WLC_E_MULTICAST_DECODE_ERROR),
+	BCMEVENT_NAME(WLC_E_TRACE),
+	BCMEVENT_NAME(WLC_E_IF),
+#ifdef WLP2P
+	BCMEVENT_NAME(WLC_E_P2P_DISC_LISTEN_COMPLETE),
+#endif
+	BCMEVENT_NAME(WLC_E_RSSI),
+	BCMEVENT_NAME(WLC_E_PFN_SCAN_COMPLETE),
+	BCMEVENT_NAME(WLC_E_ACTION_FRAME),
+	BCMEVENT_NAME(WLC_E_ACTION_FRAME_RX),
+	BCMEVENT_NAME(WLC_E_ACTION_FRAME_COMPLETE),
+#if defined(NDIS)
+	BCMEVENT_NAME(WLC_E_PRE_ASSOC_IND),
+	BCMEVENT_NAME(WLC_E_PRE_REASSOC_IND),
+	BCMEVENT_NAME(WLC_E_CHANNEL_ADOPTED),
+	BCMEVENT_NAME(WLC_E_AP_STARTED),
+	BCMEVENT_NAME(WLC_E_DFS_AP_STOP),
+	BCMEVENT_NAME(WLC_E_DFS_AP_RESUME),
+	BCMEVENT_NAME(WLC_E_ASSOC_IND_NDIS),
+	BCMEVENT_NAME(WLC_E_REASSOC_IND_NDIS),
+	BCMEVENT_NAME(WLC_E_ACTION_FRAME_RX_NDIS),
+	BCMEVENT_NAME(WLC_E_AUTH_REQ),
+	BCMEVENT_NAME(WLC_E_IBSS_COALESCE),
+#endif /* #if defined(NDIS) */
+
+#ifdef BCMWAPI_WAI
+	BCMEVENT_NAME(WLC_E_WAI_STA_EVENT),
+	BCMEVENT_NAME(WLC_E_WAI_MSG),
+#endif /* BCMWAPI_WAI */
+
+	BCMEVENT_NAME(WLC_E_ESCAN_RESULT),
+	BCMEVENT_NAME(WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE),
+#ifdef WLP2P
+	BCMEVENT_NAME(WLC_E_PROBRESP_MSG),
+	BCMEVENT_NAME(WLC_E_P2P_PROBREQ_MSG),
+#endif
+#ifdef PROP_TXSTATUS
+	BCMEVENT_NAME(WLC_E_FIFO_CREDIT_MAP),
+#endif
+	BCMEVENT_NAME(WLC_E_WAKE_EVENT),
+	BCMEVENT_NAME(WLC_E_DCS_REQUEST),
+	BCMEVENT_NAME(WLC_E_RM_COMPLETE),
+	BCMEVENT_NAME(WLC_E_OVERLAY_REQ),
+	BCMEVENT_NAME(WLC_E_CSA_COMPLETE_IND),
+	BCMEVENT_NAME(WLC_E_EXCESS_PM_WAKE_EVENT),
+	BCMEVENT_NAME(WLC_E_PFN_SCAN_NONE),
+	BCMEVENT_NAME(WLC_E_PFN_SCAN_ALLGONE),
+#ifdef SOFTAP
+	BCMEVENT_NAME(WLC_E_GTK_PLUMBED),
+#endif
+	BCMEVENT_NAME(WLC_E_ASSOC_REQ_IE),
+	BCMEVENT_NAME(WLC_E_ASSOC_RESP_IE),
+	BCMEVENT_NAME(WLC_E_BEACON_FRAME_RX),
+#ifdef WLTDLS
+	BCMEVENT_NAME(WLC_E_TDLS_PEER_EVENT),
+#endif /* WLTDLS */
+	BCMEVENT_NAME(WLC_E_NATIVE),
+#ifdef WLPKTDLYSTAT
+	BCMEVENT_NAME(WLC_E_PKTDELAY_IND),
+#endif /* WLPKTDLYSTAT */
+	BCMEVENT_NAME(WLC_E_SERVICE_FOUND),
+	BCMEVENT_NAME(WLC_E_GAS_FRAGMENT_RX),
+	BCMEVENT_NAME(WLC_E_GAS_COMPLETE),
+	BCMEVENT_NAME(WLC_E_P2PO_ADD_DEVICE),
+	BCMEVENT_NAME(WLC_E_P2PO_DEL_DEVICE),
+#ifdef WLWNM
+	BCMEVENT_NAME(WLC_E_WNM_STA_SLEEP),
+#endif /* WLWNM */
+#if defined(WL_PROXDETECT) || defined(RTT_SUPPORT)
+	BCMEVENT_NAME(WLC_E_PROXD),
+#endif
+	BCMEVENT_NAME(WLC_E_CCA_CHAN_QUAL),
+	BCMEVENT_NAME(WLC_E_BSSID),
+#ifdef PROP_TXSTATUS
+	BCMEVENT_NAME(WLC_E_BCMC_CREDIT_SUPPORT),
+#endif
+	BCMEVENT_NAME(WLC_E_PSTA_PRIMARY_INTF_IND),
+	BCMEVENT_NAME(WLC_E_TXFAIL_THRESH),
+#ifdef GSCAN_SUPPORT
+	BCMEVENT_NAME(WLC_E_PFN_GSCAN_FULL_RESULT),
+	BCMEVENT_NAME(WLC_E_PFN_SSID_EXT),
+#endif /* GSCAN_SUPPORT */
+#ifdef WLBSSLOAD_REPORT
+	BCMEVENT_NAME(WLC_E_BSS_LOAD),
+#endif
+#ifdef WLFBT
+	BCMEVENT_NAME(WLC_E_FBT),
+#endif /* WLFBT */
+	BCMEVENT_NAME(WLC_E_AUTHORIZED),
+	BCMEVENT_NAME(WLC_E_PROBREQ_MSG_RX),
+
+	BCMEVENT_NAME(WLC_E_CSA_START_IND),
+	BCMEVENT_NAME(WLC_E_CSA_DONE_IND),
+	BCMEVENT_NAME(WLC_E_CSA_FAILURE_IND),
+	BCMEVENT_NAME(WLC_E_RMC_EVENT),
+	BCMEVENT_NAME(WLC_E_DPSTA_INTF_IND),
+	BCMEVENT_NAME(WLC_E_ALLOW_CREDIT_BORROW),
+	BCMEVENT_NAME(WLC_E_MSCH),
+	BCMEVENT_NAME(WLC_E_ULP),
+	BCMEVENT_NAME(WLC_E_NAN),
+	BCMEVENT_NAME(WLC_E_PKT_FILTER),
+	BCMEVENT_NAME(WLC_E_DMA_TXFLUSH_COMPLETE),
+	BCMEVENT_NAME(WLC_E_PSK_AUTH),
+	BCMEVENT_NAME(WLC_E_SDB_TRANSITION),
+	BCMEVENT_NAME(WLC_E_PFN_SCAN_BACKOFF),
+	BCMEVENT_NAME(WLC_E_PFN_BSSID_SCAN_BACKOFF),
+	BCMEVENT_NAME(WLC_E_AGGR_EVENT),
+	BCMEVENT_NAME(WLC_E_TVPM_MITIGATION),
+	BCMEVENT_NAME(WLC_E_SCAN),
+	BCMEVENT_NAME(WLC_E_SLOTTED_BSS_PEER_OP),
+	BCMEVENT_NAME(WLC_E_PHY_CAL),
+#ifdef WL_NAN
+	BCMEVENT_NAME(WLC_E_NAN_CRITICAL),
+	BCMEVENT_NAME(WLC_E_NAN_NON_CRITICAL),
+	BCMEVENT_NAME(WLC_E_NAN),
+#endif /* WL_NAN */
+	BCMEVENT_NAME(WLC_E_RPSNOA),
+	BCMEVENT_NAME(WLC_E_WA_LQM),
+	BCMEVENT_NAME(WLC_E_OBSS_DETECTION),
+	BCMEVENT_NAME(WLC_E_SC_CHAN_QUAL),
+	BCMEVENT_NAME(WLC_E_DYNSAR),
+	BCMEVENT_NAME(WLC_E_ROAM_CACHE_UPDATE),
+	BCMEVENT_NAME(WLC_E_AP_BCN_DRIFT),
+	BCMEVENT_NAME(WLC_E_PFN_SCAN_ALLGONE_EXT),
+#ifdef WL_TWT
+	BCMEVENT_NAME(WLC_E_TWT),
+#endif /* WL_TWT */
+	BCMEVENT_NAME(WLC_E_AMT),
+	BCMEVENT_NAME(WLC_E_ROAM_SCAN_RESULT),
+#if defined(XRAPI)
+	BCMEVENT_NAME(WLC_E_XR_SOFTAP_PSMODE),
+#endif /* XRAPI */
+#ifdef WL_SIB_COEX
+	BCMEVENT_NAME(WLC_E_SIB),
+#endif /* WL_SIB_COEX */
+	BCMEVENT_NAME(WLC_E_MSCS),
+	BCMEVENT_NAME(WLC_E_RXDMA_RECOVERY_ATMPT),
+#ifdef WL_SCHED_SCAN
+	BCMEVENT_NAME(WLC_E_PFN_PARTIAL_RESULT),
+#endif /* WL_SCHED_SCAN */
+	BCMEVENT_NAME(WLC_E_MLO_LINK_INFO),
+	BCMEVENT_NAME(WLC_E_C2C),
+	BCMEVENT_NAME(WLC_E_BCN_TSF),
+	BCMEVENT_NAME(WLC_E_OWE_INFO),
+	BCMEVENT_NAME(WLC_E_ULMU_DISABLED_REASON_UPD),
+#ifdef CSI_SUPPORT
+	BCMEVENT_NAME(WLC_E_CSI)
+#endif /* CSI_SUPPORT */
+};
+
+const char *bcmevent_get_name(uint event_type)
+{
+	/* note:  first coded this as a static const but some
+	 * ROMs already have something called event_name so
+	 * changed it so we don't have a variable for the
+	 * 'unknown string
+	 */
+	const char *event_name = NULL;
+
+	uint idx;
+	for (idx = 0; idx < (uint)ARRAYSIZE(bcmevent_names); idx++) {
+
+		if (bcmevent_names[idx].event == event_type) {
+			event_name = bcmevent_names[idx].name;
+			break;
+		}
+	}
+
+	/* if we find an event name in the array, return it.
+	 * otherwise return unknown string.
+	 */
+	return ((event_name) ? event_name : "Unknown Event");
+}
+
+void
+wl_event_to_host_order(wl_event_msg_t * evt)
+{
+	/* Event struct members passed from dongle to host are stored in network
+	* byte order. Convert all members to host-order.
+	*/
+	evt->event_type = ntoh32(evt->event_type);
+	evt->flags = ntoh16(evt->flags);
+	evt->status = ntoh32(evt->status);
+	evt->reason = ntoh32(evt->reason);
+	evt->auth_type = ntoh32(evt->auth_type);
+	evt->datalen = ntoh32(evt->datalen);
+	evt->version = ntoh16(evt->version);
+}
+
+void
+wl_event_to_network_order(wl_event_msg_t * evt)
+{
+	/* Event struct members passed from dongle to host are stored in network
+	* byte order. Convert all members to host-order.
+	*/
+	evt->event_type = hton32(evt->event_type);
+	evt->flags = hton16(evt->flags);
+	evt->status = hton32(evt->status);
+	evt->reason = hton32(evt->reason);
+	evt->auth_type = hton32(evt->auth_type);
+	evt->datalen = hton32(evt->datalen);
+	evt->version = hton16(evt->version);
+}
+
+/*
+ * Validate if the event is proper and if valid copy event header to event.
+ * If proper event pointer is passed, to just validate, pass NULL to event.
+ *
+ * Return values are
+ *	BCME_OK - It is a BRCM event or BRCM dongle event
+ *	BCME_NOTFOUND - Not BRCM, not an event, may be okay
+ *	BCME_BADLEN - Bad length, should not process, just drop
+ */
+int
+is_wlc_event_frame(void *pktdata, uint pktlen, uint16 exp_usr_subtype,
+	bcm_event_msg_u_t *out_event)
+{
+	uint16 evlen = 0;	/* length in bcmeth_hdr */
+	uint16 subtype;
+	uint16 usr_subtype;
+	bcm_event_t *bcm_event;
+	uint8 *pktend;
+	uint8 *evend;
+	int err = BCME_OK;
+	uint32 data_len = 0; /* data length in bcm_event */
+
+	pktend = (uint8 *)pktdata + pktlen;
+	bcm_event = (bcm_event_t *)pktdata;
+
+	/* only care about 16-bit subtype / length versions */
+	if ((uint8 *)&bcm_event->bcm_hdr < pktend) {
+		uint8 short_subtype = *(uint8 *)&bcm_event->bcm_hdr;
+		if (!(short_subtype & 0x80)) {
+			err = BCME_NOTFOUND;
+			goto done;
+		}
+	}
+
+	/* must have both ether_header and bcmeth_hdr */
+	if (pktlen < OFFSETOF(bcm_event_t, event)) {
+		err = BCME_BADLEN;
+		goto done;
+	}
+
+	/* check length in bcmeth_hdr */
+
+#ifdef BCMDONGLEHOST
+	/* temporary - header length not always set properly. When the below
+	 * !BCMDONGLEHOST is in all branches that use trunk DHD, the code
+	 * under BCMDONGLEHOST can be removed.
+	 */
+	evlen = (uint16)(pktend - (uint8 *)&bcm_event->bcm_hdr.version);
+#else
+	evlen = ntoh16_ua((void *)&bcm_event->bcm_hdr.length);
+#endif /* BCMDONGLEHOST */
+	evend = (uint8 *)&bcm_event->bcm_hdr.version + evlen;
+	if (evend != pktend) {
+		err = BCME_BADLEN;
+		goto done;
+	}
+
+	/* match on subtype, oui and usr subtype for BRCM events */
+	subtype = ntoh16_ua((void *)&bcm_event->bcm_hdr.subtype);
+	if (subtype != BCMILCP_SUBTYPE_VENDOR_LONG) {
+		err = BCME_NOTFOUND;
+		goto done;
+	}
+
+	if (bcmp(BRCM_OUI, &bcm_event->bcm_hdr.oui[0], DOT11_OUI_LEN)) {
+		err = BCME_NOTFOUND;
+		goto done;
+	}
+
+	/* if it is a bcm_event or bcm_dngl_event_t, validate it */
+	usr_subtype = ntoh16_ua((void *)&bcm_event->bcm_hdr.usr_subtype);
+	switch (usr_subtype) {
+	case BCMILCP_BCM_SUBTYPE_EVENT:
+		/* check that header length and pkt length are sufficient */
+		if ((pktlen < sizeof(bcm_event_t)) ||
+			(evend < ((uint8 *)bcm_event + sizeof(bcm_event_t)))) {
+			err = BCME_BADLEN;
+			goto done;
+		}
+
+		/* ensure data length in event is not beyond the packet. */
+		data_len = ntoh32_ua((void *)&bcm_event->event.datalen);
+		if ((sizeof(bcm_event_t) + data_len +
+			BCMILCP_BCM_SUBTYPE_EVENT_DATA_PAD) != pktlen) {
+			err = BCME_BADLEN;
+			goto done;
+		}
+
+		if (exp_usr_subtype && (exp_usr_subtype != usr_subtype)) {
+			err = BCME_NOTFOUND;
+			goto done;
+		}
+
+		if (out_event) {
+			/* ensure BRCM event pkt aligned */
+			(void)memcpy_s(&out_event->event, sizeof(out_event->event),
+				&bcm_event->event, sizeof(out_event->event));
+		}
+
+		break;
+
+	case BCMILCP_BCM_SUBTYPE_DNGLEVENT:
+#if defined(HEALTH_CHECK) || defined(DNGL_EVENT_SUPPORT)
+		if ((pktlen < sizeof(bcm_dngl_event_t)) ||
+			(evend < ((uint8 *)bcm_event + sizeof(bcm_dngl_event_t)))) {
+			err = BCME_BADLEN;
+			goto done;
+		}
+
+		/* ensure data length in event is not beyond the packet. */
+		data_len = ntoh16_ua((void *)&((bcm_dngl_event_t *)pktdata)->dngl_event.datalen);
+		if ((sizeof(bcm_dngl_event_t) + data_len +
+			BCMILCP_BCM_SUBTYPE_EVENT_DATA_PAD) != pktlen) {
+			err = BCME_BADLEN;
+			goto done;
+		}
+
+		if (exp_usr_subtype && (exp_usr_subtype != usr_subtype)) {
+			err = BCME_NOTFOUND;
+			goto done;
+		}
+
+		if (out_event) {
+			/* ensure BRCM dngl event pkt aligned */
+			(void)memcpy_s(&out_event->dngl_event, sizeof(out_event->dngl_event),
+				&((bcm_dngl_event_t *)pktdata)->dngl_event,
+				sizeof(out_event->dngl_event));
+		}
+
+		break;
+#else
+		err = BCME_UNSUPPORTED;
+		break;
+#endif /* HEALTH_CHECK  || DNGL_EVENT_SUPPORT */
+
+	default:
+		err = BCME_NOTFOUND;
+		goto done;
+	}
+
+	BCM_REFERENCE(data_len);
+done:
+	return err;
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcmsdh.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcmsdh.c
@@ -0,0 +1,966 @@
+/*
+ *  BCMSDH interface glue
+ *  implement bcmsdh API for SDIOH driver
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+/**
+ * @file bcmsdh.c
+ */
+
+/* ****************** BCMSDH Interface Functions *************************** */
+
+#include <typedefs.h>
+#include <bcmdevs.h>
+#include <bcmendian.h>
+#include <bcmutils.h>
+#include <hndsoc.h>
+#include <siutils.h>
+#if !defined(BCMDONGLEHOST)
+#include <bcmsrom.h>
+#endif /* !defined(BCMDONGLEHOST) */
+#include <osl.h>
+
+#include <bcmsdh.h>	/* BRCM API for SDIO clients (such as wl, dhd) */
+#include <bcmsdbus.h>	/* common SDIO/controller interface */
+#include <sbsdio.h>	/* SDIO device core hardware definitions. */
+#include <sdio.h>	/* SDIO Device and Protocol Specs */
+
+#if defined(BT_OVER_SDIO)
+#include <dhd_bt_interface.h>
+#endif /* defined (BT_OVER_SDIO) */
+
+#define SDIOH_API_ACCESS_RETRY_LIMIT	2
+const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL;
+
+/* local copy of bcm sd handler */
+bcmsdh_info_t * l_bcmsdh = NULL;
+
+#if defined(BT_OVER_SDIO)
+struct sdio_func *func_f3 = NULL;
+static f3intr_handler processf3intr = NULL;
+static dhd_hang_notification process_dhd_hang_notification = NULL;
+static dhd_hang_state_t g_dhd_hang_state = NO_HANG_STATE;
+#endif /* defined (BT_OVER_SDIO) */
+
+#if defined(NDIS) && (NDISVER < 0x0630)
+extern SDIOH_API_RC sdioh_detach(osl_t *osh, sdioh_info_t *sd);
+#endif
+
+#if defined(OOB_INTR_ONLY) && defined(HW_OOB) || defined(FORCE_WOWLAN)
+extern int
+sdioh_enable_hw_oob_intr(void *sdioh, bool enable);
+
+void
+bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable)
+{
+	sdioh_enable_hw_oob_intr(sdh->sdioh, enable);
+}
+#endif
+
+#if defined(BT_OVER_SDIO)
+void bcmsdh_btsdio_process_hang_state(dhd_hang_state_t new_state)
+{
+	bool state_change = false;
+
+	BCMSDH_ERROR(("%s: DHD hang state changed - [%d] -> [%d]\n",
+		__FUNCTION__, g_dhd_hang_state, new_state));
+
+	if (g_dhd_hang_state == new_state)
+		return;
+
+	switch (g_dhd_hang_state) {
+		case NO_HANG_STATE:
+			if (HANG_START_STATE == new_state)
+				state_change = true;
+		break;
+
+		case HANG_START_STATE:
+			if (HANG_RECOVERY_STATE == new_state ||
+				NO_HANG_STATE == new_state)
+				state_change = true;
+
+		break;
+
+		case HANG_RECOVERY_STATE:
+			if (NO_HANG_STATE == new_state)
+				state_change = true;
+		break;
+
+		default:
+			BCMSDH_ERROR(("%s: Unhandled Hang state\n", __FUNCTION__));
+		break;
+	}
+
+	if (!state_change) {
+		BCMSDH_ERROR(("%s: Hang state cannot be changed\n", __FUNCTION__));
+		return;
+	}
+
+	g_dhd_hang_state = new_state;
+}
+
+void bcmsdh_btsdio_process_f3_intr(void)
+{
+	if (processf3intr && (g_dhd_hang_state == NO_HANG_STATE))
+		processf3intr(func_f3);
+}
+
+void bcmsdh_btsdio_process_dhd_hang_notification(bool wifi_recovery_completed)
+{
+	bcmsdh_btsdio_process_hang_state(HANG_START_STATE);
+
+	if (process_dhd_hang_notification)
+		process_dhd_hang_notification(func_f3, wifi_recovery_completed);
+
+	/* WiFi was off, so HANG_RECOVERY_STATE is not needed */
+	if (wifi_recovery_completed)
+		bcmsdh_btsdio_process_hang_state(NO_HANG_STATE);
+	else {
+		bcmsdh_btsdio_process_hang_state(HANG_RECOVERY_STATE);
+	}
+}
+
+void bcmsdh_btsdio_interface_init(struct sdio_func *func,
+	f3intr_handler f3intr_fun, dhd_hang_notification hang_notification)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)l_bcmsdh;
+	BCMSDH_INFO(("%s: func %p \n", __FUNCTION__, func));
+	func_f3 = func;
+	processf3intr = f3intr_fun;
+	sdioh_sdmmc_card_enable_func_f3(bcmsdh->sdioh, func);
+	process_dhd_hang_notification = hang_notification;
+
+} EXPORT_SYMBOL(bcmsdh_btsdio_interface_init);
+#endif /* defined (BT_OVER_SDIO) */
+
+/* Attach BCMSDH layer to SDIO Host Controller Driver
+ *
+ * @param osh OSL Handle.
+ * @param cfghdl Configuration Handle.
+ * @param regsva Virtual address of controller registers.
+ * @param irq Interrupt number of SDIO controller.
+ *
+ * @return bcmsdh_info_t Handle to BCMSDH context.
+ */
+bcmsdh_info_t *
+bcmsdh_attach(osl_t *osh, void *sdioh, ulong *regsva)
+{
+	bcmsdh_info_t *bcmsdh;
+
+	if ((bcmsdh = (bcmsdh_info_t *)MALLOC(osh, sizeof(bcmsdh_info_t))) == NULL) {
+		BCMSDH_ERROR(("bcmsdh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh)));
+		return NULL;
+	}
+	bzero((char *)bcmsdh, sizeof(bcmsdh_info_t));
+	bcmsdh->sdioh = sdioh;
+	bcmsdh->osh = osh;
+	bcmsdh->init_success = TRUE;
+	*regsva = si_enum_base(0);
+
+	bcmsdh_force_sbwad_calc(bcmsdh, FALSE);
+
+	/* Report the BAR, to fix if needed */
+	bcmsdh->sbwad = si_enum_base(0);
+
+	/* save the handler locally */
+	l_bcmsdh = bcmsdh;
+
+	return bcmsdh;
+}
+
+int
+bcmsdh_detach(osl_t *osh, void *sdh)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+	if (bcmsdh != NULL) {
+#if defined(NDIS) && (NDISVER < 0x0630)
+		if (bcmsdh->sdioh)
+			sdioh_detach(osh, bcmsdh->sdioh);
+#endif
+		MFREE(osh, bcmsdh, sizeof(bcmsdh_info_t));
+	}
+
+	l_bcmsdh = NULL;
+
+	return 0;
+}
+
+int
+bcmsdh_iovar_op(void *sdh, const char *name,
+                void *params, uint plen, void *arg, uint len, bool set)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set);
+}
+
+bool
+bcmsdh_intr_query(void *sdh)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+	bool on;
+
+	ASSERT(bcmsdh);
+	status = sdioh_interrupt_query(bcmsdh->sdioh, &on);
+	if (SDIOH_API_SUCCESS(status))
+		return FALSE;
+	else
+		return on;
+}
+
+int
+bcmsdh_intr_enable(void *sdh)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+#ifdef BCMSPI_ANDROID
+	uint32 data;
+#endif /* BCMSPI_ANDROID */
+	ASSERT(bcmsdh);
+
+	status = sdioh_interrupt_set(bcmsdh->sdioh, TRUE);
+#ifdef BCMSPI_ANDROID
+	data = bcmsdh_cfg_read_word(sdh, 0, 4, NULL);
+	data |= 0xE0E70000;
+	bcmsdh_cfg_write_word(sdh, 0, 4, data, NULL);
+#endif /* BCMSPI_ANDROID */
+	return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+int
+bcmsdh_intr_disable(void *sdh)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+#ifdef BCMSPI_ANDROID
+	uint32 data;
+#endif /* BCMSPI_ANDROID */
+	ASSERT(bcmsdh);
+
+	status = sdioh_interrupt_set(bcmsdh->sdioh, FALSE);
+#ifdef BCMSPI_ANDROID
+	data = bcmsdh_cfg_read_word(sdh, 0, 4, NULL);
+	data &= ~0xE0E70000;
+	bcmsdh_cfg_write_word(sdh, 0, 4, data, NULL);
+#endif /* BCMSPI_ANDROID */
+	return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+int
+bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+
+	if (!bcmsdh)
+		bcmsdh = l_bcmsdh;
+
+	ASSERT(bcmsdh);
+
+	status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh);
+	return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+int
+bcmsdh_intr_dereg(void *sdh)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+
+	if (!bcmsdh)
+		bcmsdh = l_bcmsdh;
+
+	ASSERT(bcmsdh);
+
+	status = sdioh_interrupt_deregister(bcmsdh->sdioh);
+	return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+#if defined(DHD_DEBUG) || defined(BCMDBG)
+bool
+bcmsdh_intr_pending(void *sdh)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+	ASSERT(sdh);
+	return sdioh_interrupt_pending(bcmsdh->sdioh);
+}
+#endif
+
+int
+bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
+{
+	ASSERT(sdh);
+
+	/* don't support yet */
+	return BCME_UNSUPPORTED;
+}
+
+/**
+ * Read from SDIO Configuration Space
+ * @param sdh SDIO Host context.
+ * @param func_num Function number to read from.
+ * @param addr Address to read from.
+ * @param err Error return.
+ * @return value read from SDIO configuration space.
+ */
+uint8
+bcmsdh_cfg_read(void *sdh, uint fnc_num, uint32 addr, int *err)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+	int32 retry = 0;
+#endif
+	uint8 data = 0;
+
+	if (!bcmsdh)
+		bcmsdh = l_bcmsdh;
+
+	ASSERT(bcmsdh->init_success);
+
+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+	do {
+		if (retry)	/* wait for 1 ms till bus get settled down */
+			OSL_DELAY(1000);
+#endif
+	status = sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data);
+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+	} while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
+#endif
+	if (err)
+		*err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
+
+	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__,
+	            fnc_num, addr, data));
+
+	return data;
+}
+
+void
+bcmsdh_cfg_write(void *sdh, uint fnc_num, uint32 addr, uint8 data, int *err)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+	int32 retry = 0;
+#endif
+
+	if (!bcmsdh)
+		bcmsdh = l_bcmsdh;
+
+	ASSERT(bcmsdh->init_success);
+
+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+	do {
+		if (retry)	/* wait for 1 ms till bus get settled down */
+			OSL_DELAY(1000);
+#endif
+	status = sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data);
+#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
+	} while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
+#endif
+	if (err)
+		*err = SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR;
+
+	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__,
+	            fnc_num, addr, data));
+}
+
+uint32
+bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+	uint32 data = 0;
+
+	if (!bcmsdh)
+		bcmsdh = l_bcmsdh;
+
+	ASSERT(bcmsdh->init_success);
+
+	status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ, fnc_num,
+	                            addr, &data, 4);
+
+	if (err)
+		*err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
+
+	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint32data = 0x%x\n", __FUNCTION__,
+	            fnc_num, addr, data));
+
+	return data;
+}
+
+void
+bcmsdh_cfg_write_word(void *sdh, uint fnc_num, uint32 addr, uint32 data, int *err)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+
+	if (!bcmsdh)
+		bcmsdh = l_bcmsdh;
+
+	ASSERT(bcmsdh->init_success);
+
+	status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, fnc_num,
+	                            addr, &data, 4);
+
+	if (err)
+		*err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
+
+	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint32data = 0x%x\n", __FUNCTION__, fnc_num,
+	             addr, data));
+}
+
+int
+bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+
+	uint8 *tmp_buf, *tmp_ptr;
+	uint8 *ptr;
+	bool ascii = func & ~0xf;
+	func &= 0x7;
+
+	if (!bcmsdh)
+		bcmsdh = l_bcmsdh;
+
+	ASSERT(bcmsdh->init_success);
+	ASSERT(cis);
+	ASSERT(length <= SBSDIO_CIS_SIZE_LIMIT);
+
+	status = sdioh_cis_read(bcmsdh->sdioh, func, cis, length);
+
+	if (ascii) {
+		/* Move binary bits to tmp and format them into the provided buffer. */
+		if ((tmp_buf = (uint8 *)MALLOC(bcmsdh->osh, length)) == NULL) {
+			BCMSDH_ERROR(("%s: out of memory\n", __FUNCTION__));
+			return BCME_NOMEM;
+		}
+		bcopy(cis, tmp_buf, length);
+		for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4); tmp_ptr++) {
+			ptr += snprintf((char*)ptr, (cis + length - ptr - 4),
+				"%.2x ", *tmp_ptr & 0xff);
+			if ((((tmp_ptr - tmp_buf) + 1) & 0xf) == 0)
+				ptr += snprintf((char *)ptr, (cis + length - ptr -4), "\n");
+		}
+		MFREE(bcmsdh->osh, tmp_buf, length);
+	}
+
+	return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+int
+bcmsdh_cisaddr_read(void *sdh, uint func, uint8 *cisd, uint32 offset)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+
+	func &= 0x7;
+
+	if (!bcmsdh)
+		bcmsdh = l_bcmsdh;
+
+	ASSERT(bcmsdh->init_success);
+	ASSERT(cisd);
+
+	status = sdioh_cisaddr_read(bcmsdh->sdioh, func, cisd, offset);
+
+	return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+int
+bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address, bool force_set)
+{
+	int err = 0;
+	uint bar0 = address & ~SBSDIO_SB_OFT_ADDR_MASK;
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+	if (bar0 != bcmsdh->sbwad || force_set) {
+		bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
+			(address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
+		if (!err)
+			bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID,
+				(address >> 16) & SBSDIO_SBADDRMID_MASK, &err);
+		if (!err)
+			bcmsdh_cfg_write(bcmsdh, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH,
+				(address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err);
+
+		if (!err)
+			bcmsdh->sbwad = bar0;
+		else
+			/* invalidate cached window var */
+			bcmsdh->sbwad = 0;
+
+#ifdef BCMDBG
+		if (err)
+			BCMSDH_ERROR(("%s: error setting address window %08x\n",
+				__FUNCTION__, address));
+#endif /* BCMDBG */
+	}
+
+	return err;
+}
+
+uint32
+bcmsdh_reg_read(void *sdh, uintptr addr, uint size)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+	uint32 word = 0;
+
+	BCMSDH_INFO(("%s:fun = 1, addr = 0x%x\n", __FUNCTION__, (unsigned int)addr));
+
+	if (!bcmsdh)
+		bcmsdh = l_bcmsdh;
+
+	ASSERT(bcmsdh->init_success);
+
+	if (bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, bcmsdh->force_sbwad_calc)) {
+		bcmsdh->regfail = TRUE; // terence 20130621: prevent dhd_dpc in dead lock
+		return 0xFFFFFFFF;
+	}
+
+	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+	if (size == 4)
+		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+	status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL,
+		SDIOH_READ, SDIO_FUNC_1, addr, &word, size);
+
+	bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
+
+	BCMSDH_INFO(("uint32data = 0x%x\n", word));
+
+	/* if ok, return appropriately masked word */
+	/* XXX Masking was put in for NDIS port, remove if not needed */
+	if (SDIOH_API_SUCCESS(status)) {
+		switch (size) {
+			case sizeof(uint8):
+				return (word & 0xff);
+			case sizeof(uint16):
+				return (word & 0xffff);
+			case sizeof(uint32):
+				return word;
+			default:
+				bcmsdh->regfail = TRUE;
+
+		}
+	}
+
+	/* otherwise, bad sdio access or invalid size */
+	BCMSDH_ERROR(("%s: error reading addr 0x%x size %d\n",
+		__FUNCTION__, (unsigned int)addr, size));
+	return 0xFFFFFFFF;
+}
+
+uint32
+bcmsdh_reg_write(void *sdh, uintptr addr, uint size, uint32 data)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+	int err = 0;
+
+	BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
+	             __FUNCTION__, (unsigned int)addr, size*8, data));
+
+	if (!bcmsdh)
+		bcmsdh = l_bcmsdh;
+
+	ASSERT(bcmsdh->init_success);
+
+	if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, bcmsdh->force_sbwad_calc))) {
+		bcmsdh->regfail = TRUE; // terence 20130621:
+		return err;
+	}
+
+	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+	if (size == 4)
+		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+	status = sdioh_request_word(bcmsdh->sdioh, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, SDIO_FUNC_1,
+	                            addr, &data, size);
+	bcmsdh->regfail = !(SDIOH_API_SUCCESS(status));
+
+	if (SDIOH_API_SUCCESS(status))
+		return 0;
+
+	BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
+	              __FUNCTION__, data, (unsigned int)addr, size));
+	return 0xFFFFFFFF;
+}
+
+bool
+bcmsdh_regfail(void *sdh)
+{
+	return ((bcmsdh_info_t *)sdh)->regfail;
+}
+
+int
+bcmsdh_recv_buf(void *sdh, uint32 addr, uint fn, uint flags,
+                uint8 *buf, uint nbytes, void *pkt,
+                bcmsdh_cmplt_fn_t complete_fn, void *handle)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+	uint incr_fix;
+	uint width;
+	int err = 0;
+
+	ASSERT(bcmsdh);
+	ASSERT(bcmsdh->init_success);
+
+	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
+	             __FUNCTION__, fn, addr, nbytes));
+
+	/* Async not implemented yet */
+	ASSERT(!(flags & SDIO_REQ_ASYNC));
+	if (flags & SDIO_REQ_ASYNC)
+		return BCME_UNSUPPORTED;
+
+	if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE)))
+		return err;
+
+	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+
+	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
+	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
+	if (width == 4)
+		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+	status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
+	                              SDIOH_READ, fn, addr, width, nbytes, buf, pkt);
+
+	return (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
+}
+
+int
+bcmsdh_send_buf(void *sdh, uint32 addr, uint fn, uint flags,
+                uint8 *buf, uint nbytes, void *pkt,
+                bcmsdh_cmplt_fn_t complete_fn, void *handle)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+	uint incr_fix;
+	uint width;
+	int err = 0;
+
+	ASSERT(bcmsdh);
+	ASSERT(bcmsdh->init_success);
+
+	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n",
+	            __FUNCTION__, fn, addr, nbytes));
+
+	/* Async not implemented yet */
+	ASSERT(!(flags & SDIO_REQ_ASYNC));
+	if (flags & SDIO_REQ_ASYNC)
+		return BCME_UNSUPPORTED;
+
+	if ((err = bcmsdhsdio_set_sbaddr_window(bcmsdh, addr, FALSE)))
+		return err;
+
+	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+
+	incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
+	width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
+	if (width == 4)
+		addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+	status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
+	                              SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt);
+
+	return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+int
+bcmsdh_rwdata(void *sdh, uint rw, uint32 addr, uint8 *buf, uint nbytes)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	SDIOH_API_RC status;
+
+	ASSERT(bcmsdh);
+	ASSERT(bcmsdh->init_success);
+	ASSERT((addr & SBSDIO_SBWINDOW_MASK) == 0);
+
+	addr &= SBSDIO_SB_OFT_ADDR_MASK;
+	addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+	status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, SDIOH_DATA_INC,
+	                              (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
+	                              addr, 4, nbytes, buf, NULL);
+
+	return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
+}
+
+int
+bcmsdh_abort(void *sdh, uint fn)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+	return sdioh_abort(bcmsdh->sdioh, fn);
+}
+
+int
+bcmsdh_start(void *sdh, int stage)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+	return sdioh_start(bcmsdh->sdioh, stage);
+}
+
+int
+bcmsdh_stop(void *sdh)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+	return sdioh_stop(bcmsdh->sdioh);
+}
+
+int
+bcmsdh_waitlockfree(void *sdh)
+{
+#ifdef LINUX
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+	return sdioh_waitlockfree(bcmsdh->sdioh);
+#else
+	return 0;
+#endif
+}
+
+int
+bcmsdh_query_device(void *sdh)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+#if defined(BCMDONGLEHOST)
+	bcmsdh->vendevid = (VENDOR_BROADCOM << 16) | 0;
+#else
+	uint8 *fn0cis[1];
+	int err;
+	char *vars;
+	uint varsz;
+	osl_t *osh = bcmsdh->osh;
+
+	bcmsdh->vendevid = ~(0);
+
+	if (!(fn0cis[0] = MALLOC(osh, SBSDIO_CIS_SIZE_LIMIT))) {
+		BCMSDH_ERROR(("%s: CIS malloc failed\n", __FUNCTION__));
+		return (bcmsdh->vendevid);
+	}
+
+	bzero(fn0cis[0], SBSDIO_CIS_SIZE_LIMIT);
+
+	if ((err = bcmsdh_cis_read(sdh, 0, fn0cis[0], SBSDIO_CIS_SIZE_LIMIT))) {
+		BCMSDH_ERROR(("%s: CIS read err %d, report unknown BRCM device\n",
+		              __FUNCTION__, err));
+		bcmsdh->vendevid = (VENDOR_BROADCOM << 16) | 0;
+		MFREE(osh, fn0cis[0], SBSDIO_CIS_SIZE_LIMIT);
+		return (bcmsdh->vendevid);
+	}
+
+	if (!err) {
+		if ((err = srom_parsecis(NULL, osh, fn0cis, 1, &vars, &varsz))) {
+			BCMSDH_ERROR(("%s: Error parsing CIS = %d\n", __FUNCTION__, err));
+		} else {
+			bcmsdh->vendevid = (getintvar(vars, "vendid") << 16) |
+			                    getintvar(vars, "devid");
+			MFREE(osh, vars, varsz);
+		}
+	}
+
+	MFREE(osh, fn0cis[0], SBSDIO_CIS_SIZE_LIMIT);
+#endif /* BCMDONGLEHOST */
+	return (bcmsdh->vendevid);
+}
+
+uint
+bcmsdh_query_iofnum(void *sdh)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+	if (!bcmsdh)
+		bcmsdh = l_bcmsdh;
+
+	return (sdioh_query_iofnum(bcmsdh->sdioh));
+}
+
+int
+bcmsdh_reset(bcmsdh_info_t *sdh)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+	return sdioh_sdio_reset(bcmsdh->sdioh);
+}
+
+/* XXX For use by NDIS port, remove if not needed. */
+void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh)
+{
+	ASSERT(sdh);
+	return sdh->sdioh;
+}
+
+/* Function to pass device-status bits to DHD. */
+uint32
+bcmsdh_get_dstatus(void *sdh)
+{
+#ifdef BCMSPI
+	bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+	sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+	return sdioh_get_dstatus(sd);
+#else
+	return 0;
+#endif /* BCMSPI */
+}
+uint32
+bcmsdh_cur_sbwad(void *sdh)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+	if (!bcmsdh)
+		bcmsdh = l_bcmsdh;
+
+	return (bcmsdh->sbwad);
+}
+
+/* example usage: if force is TRUE, forces the bcmsdhsdio_set_sbaddr_window to
+ * calculate sbwad always instead of caching.
+ */
+void
+bcmsdh_force_sbwad_calc(void *sdh, bool force)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+	if (!bcmsdh)
+		bcmsdh = l_bcmsdh;
+	bcmsdh->force_sbwad_calc = force;
+}
+
+void
+bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev)
+{
+#ifdef BCMSPI
+	bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+	sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+	sdioh_chipinfo(sd, chip, chiprev);
+#else
+	return;
+#endif /* BCMSPI */
+}
+
+#ifdef BCMSPI
+void
+bcmsdh_dwordmode(void *sdh, bool set)
+{
+	bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+	sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+	sdioh_dwordmode(sd, set);
+	return;
+}
+#endif /* BCMSPI */
+
+int
+bcmsdh_sleep(void *sdh, bool enab)
+{
+#ifdef SDIOH_SLEEP_ENABLED
+	bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+	sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+
+	return sdioh_sleep(sd, enab);
+#else
+	return BCME_UNSUPPORTED;
+#endif
+}
+
+int
+bcmsdh_gpio_init(void *sdh)
+{
+	bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+	sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+
+	return sdioh_gpio_init(sd);
+}
+
+bool
+bcmsdh_gpioin(void *sdh, uint32 gpio)
+{
+	bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+	sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+
+	return sdioh_gpioin(sd, gpio);
+}
+
+int
+bcmsdh_gpioouten(void *sdh, uint32 gpio)
+{
+	bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+	sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+
+	return sdioh_gpioouten(sd, gpio);
+}
+
+int
+bcmsdh_gpioout(void *sdh, uint32 gpio, bool enab)
+{
+	bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+	sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+
+	return sdioh_gpioout(sd, gpio, enab);
+}
+
+uint
+bcmsdh_set_mode(void *sdh, uint mode)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+
+	return (sdioh_set_mode(bcmsdh->sdioh, mode));
+}
+
+#ifdef PKT_STATICS
+uint32
+bcmsdh_get_spend_time(void *sdh)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
+	return (sdioh_get_spend_time(bcmsdh->sdioh));
+}
+#endif
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcmsdh_linux.c
@@ -0,0 +1,621 @@
+/*
+ * SDIO access interface for drivers - linux specific (pci only)
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+/**
+ * @file bcmsdh_linux.c
+ */
+
+#define __UNDEF_NO_VERSION__
+
+#include <typedefs.h>
+#include <linuxver.h>
+#include <linux/pci.h>
+#include <linux/completion.h>
+
+#include <osl.h>
+#include <pcicfg.h>
+#include <bcmdefs.h>
+#include <bcmdevs.h>
+#include <linux/irq.h>
+extern void dhdsdio_isr(void * args);
+#include <bcmutils.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#if defined(CONFIG_ARCH_ODIN)
+#include <linux/platform_data/gpio-odin.h>
+#endif /* defined(CONFIG_ARCH_ODIN) */
+#include <dhd_linux.h>
+
+/* driver info, initialized when bcmsdh_register is called */
+static bcmsdh_driver_t drvinfo = {NULL, NULL, NULL, NULL};
+
+typedef enum {
+	DHD_INTR_INVALID = 0,
+	DHD_INTR_INBAND,
+	DHD_INTR_HWOOB,
+	DHD_INTR_SWOOB
+} DHD_HOST_INTR_TYPE;
+
+/* the BCMSDH module comprises the generic part (bcmsdh.c) and OS specific layer (e.g.
+ * bcmsdh_linux.c). Put all OS specific variables (e.g. irq number and flags) here rather
+ * than in the common structure bcmsdh_info. bcmsdh_info only keeps a handle (os_ctx) to this
+ * structure.
+ */
+typedef struct bcmsdh_os_info {
+	DHD_HOST_INTR_TYPE	intr_type;
+	int			oob_irq_num;	/* valid when hardware or software oob in use */
+	unsigned long		oob_irq_flags;	/* valid when hardware or software oob in use */
+	bool			oob_irq_registered;
+	bool			oob_irq_enabled;
+	bool			oob_irq_wake_enabled;
+	spinlock_t		oob_irq_spinlock;
+	bcmsdh_cb_fn_t		oob_irq_handler;
+	void			*oob_irq_handler_context;
+	void			*context;	/* context returned from upper layer */
+	void			*sdioh;		/* handle to lower layer (sdioh) */
+	void			*dev;		/* handle to the underlying device */
+	bool			dev_wake_enabled;
+} bcmsdh_os_info_t;
+
+/* debugging macros */
+#ifdef BCMDBG_ERR
+#define SDLX_ERR(x) printf x
+#define SDLX_MSG(x)	printf x
+#else
+#define SDLX_ERR(x) printf x
+#define SDLX_MSG(x)	printf x
+#endif /* BCMDBG_ERR */
+
+/**
+ * Checks to see if vendor and device IDs match a supported SDIO Host Controller.
+ */
+bool
+bcmsdh_chipmatch(uint16 vendor, uint16 device)
+{
+	/* Add other vendors and devices as required */
+
+#ifdef BCMSDIOH_STD
+	/* Check for Arasan host controller */
+	if (vendor == VENDOR_SI_IMAGE) {
+		return (TRUE);
+	}
+	/* Check for BRCM 27XX Standard host controller */
+	if (device == BCM27XX_SDIOH_ID && vendor == VENDOR_BROADCOM) {
+		return (TRUE);
+	}
+	/* Check for BRCM Standard host controller */
+	if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM) {
+		return (TRUE);
+	}
+	/* Check for TI PCIxx21 Standard host controller */
+	if (device == PCIXX21_SDIOH_ID && vendor == VENDOR_TI) {
+		return (TRUE);
+	}
+	if (device == PCIXX21_SDIOH0_ID && vendor == VENDOR_TI) {
+		return (TRUE);
+	}
+	/* Ricoh R5C822 Standard SDIO Host */
+	if (device == R5C822_SDIOH_ID && vendor == VENDOR_RICOH) {
+		return (TRUE);
+	}
+	/* JMicron Standard SDIO Host */
+	if (device == JMICRON_SDIOH_ID && vendor == VENDOR_JMICRON) {
+		return (TRUE);
+	}
+
+#endif /* BCMSDIOH_STD */
+#ifdef BCMSDIOH_SPI
+	/* This is the PciSpiHost. */
+	if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) {
+		printf("Found PCI SPI Host Controller\n");
+		return (TRUE);
+	}
+
+#endif /* BCMSDIOH_SPI */
+
+	return (FALSE);
+}
+
+void* bcmsdh_probe(osl_t *osh, void *dev, void *sdioh, void *adapter_info, uint bus_type,
+	uint bus_num, uint slot_num)
+{
+	ulong regs;
+	bcmsdh_info_t *bcmsdh;
+	uint32 vendevid;
+	bcmsdh_os_info_t *bcmsdh_osinfo = NULL;
+
+	bcmsdh = bcmsdh_attach(osh, sdioh, &regs);
+	if (bcmsdh == NULL) {
+		SDLX_ERR(("%s: bcmsdh_attach failed\n", __FUNCTION__));
+		goto err;
+	}
+	bcmsdh_osinfo = MALLOC(osh, sizeof(bcmsdh_os_info_t));
+	if (bcmsdh_osinfo == NULL) {
+		SDLX_ERR(("%s: failed to allocate bcmsdh_os_info_t\n", __FUNCTION__));
+		goto err;
+	}
+	bzero((char *)bcmsdh_osinfo, sizeof(bcmsdh_os_info_t));
+	bcmsdh->os_cxt = bcmsdh_osinfo;
+	bcmsdh_osinfo->sdioh = sdioh;
+	bcmsdh_osinfo->dev = dev;
+	osl_set_bus_handle(osh, bcmsdh);
+
+#if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36))
+	if (dev && device_init_wakeup(dev, true) == 0)
+		bcmsdh_osinfo->dev_wake_enabled = TRUE;
+#endif /* !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) */
+
+#if defined(OOB_INTR_ONLY)
+	spin_lock_init(&bcmsdh_osinfo->oob_irq_spinlock);
+	/* Get customer specific OOB IRQ parametres: IRQ number as IRQ type */
+	bcmsdh_osinfo->oob_irq_num = wifi_platform_get_irq_number(adapter_info,
+		&bcmsdh_osinfo->oob_irq_flags);
+	if  (bcmsdh_osinfo->oob_irq_num < 0) {
+		SDLX_ERR(("%s: Host OOB irq is not defined\n", __FUNCTION__));
+		goto err;
+	}
+#endif /* defined(BCMLXSDMMC) */
+
+	/* Read the vendor/device ID from the CIS */
+	vendevid = bcmsdh_query_device(bcmsdh);
+	/* try to attach to the target device */
+	bcmsdh_osinfo->context = drvinfo.probe((vendevid >> 16), (vendevid & 0xFFFF), bus_num,
+		slot_num, 0, bus_type, (void *)regs, osh, bcmsdh);
+	if (bcmsdh_osinfo->context == NULL) {
+		SDLX_ERR(("%s: device attach failed\n", __FUNCTION__));
+		goto err;
+	}
+
+	return bcmsdh;
+
+	/* error handling */
+err:
+	if (bcmsdh != NULL)
+		bcmsdh_detach(osh, bcmsdh);
+	if (bcmsdh_osinfo != NULL)
+		MFREE(osh, bcmsdh_osinfo, sizeof(bcmsdh_os_info_t));
+	return NULL;
+}
+
+int bcmsdh_remove(bcmsdh_info_t *bcmsdh)
+{
+	bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
+
+#if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36))
+	if (bcmsdh_osinfo->dev)
+		device_init_wakeup(bcmsdh_osinfo->dev, false);
+	bcmsdh_osinfo->dev_wake_enabled = FALSE;
+#endif /* !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) */
+
+	drvinfo.remove(bcmsdh_osinfo->context);
+	MFREE(bcmsdh->osh, bcmsdh->os_cxt, sizeof(bcmsdh_os_info_t));
+	bcmsdh_detach(bcmsdh->osh, bcmsdh);
+
+	return 0;
+}
+
+#ifdef DHD_WAKE_STATUS
+int bcmsdh_get_total_wake(bcmsdh_info_t *bcmsdh)
+{
+	return bcmsdh->total_wake_count;
+}
+
+int bcmsdh_set_get_wake(bcmsdh_info_t *bcmsdh, int flag)
+{
+#if defined(OOB_INTR_ONLY)
+	bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
+	unsigned long flags;
+#endif
+	int ret;
+
+#if defined(OOB_INTR_ONLY)
+	spin_lock_irqsave(&bcmsdh_osinfo->oob_irq_spinlock, flags);
+#endif
+
+	ret = bcmsdh->pkt_wake;
+	bcmsdh->total_wake_count += flag;
+	bcmsdh->pkt_wake = flag;
+
+#if defined(OOB_INTR_ONLY)
+	spin_unlock_irqrestore(&bcmsdh_osinfo->oob_irq_spinlock, flags);
+#endif
+	return ret;
+}
+
+int bcmsdh_get_wake(bcmsdh_info_t *bcmsdh)
+{
+#if defined(OOB_INTR_ONLY)
+	bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
+	unsigned long flags;
+#endif
+	int ret;
+
+#if defined(OOB_INTR_ONLY)
+	spin_lock_irqsave(&bcmsdh_osinfo->oob_irq_spinlock, flags);
+#endif
+
+	ret = bcmsdh->pkt_wake;
+
+#if defined(OOB_INTR_ONLY)
+	spin_unlock_irqrestore(&bcmsdh_osinfo->oob_irq_spinlock, flags);
+#endif
+	return ret;
+}
+#endif /* DHD_WAKE_STATUS */
+
+int bcmsdh_suspend(bcmsdh_info_t *bcmsdh)
+{
+	bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
+
+	if (drvinfo.suspend && drvinfo.suspend(bcmsdh_osinfo->context))
+		return -EBUSY;
+	return 0;
+}
+
+int bcmsdh_resume(bcmsdh_info_t *bcmsdh)
+{
+	bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
+
+	if (drvinfo.resume)
+		return drvinfo.resume(bcmsdh_osinfo->context);
+	return 0;
+}
+
+#ifdef DEVICE_PM_CALLBACK
+int bcmsdh_prepare(bcmsdh_info_t *bcmsdh)
+{
+	bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
+
+	if (drvinfo.prepare && drvinfo.prepare(bcmsdh_osinfo->context))
+		return -EBUSY;
+	return 0;
+}
+
+int bcmsdh_complete(bcmsdh_info_t *bcmsdh)
+{
+	bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
+
+	if (drvinfo.complete)
+		return drvinfo.complete(bcmsdh_osinfo->context);
+	return 0;
+}
+#endif /* DEVICE_PM_CALLBACK */
+
+extern int bcmsdh_register_client_driver(void);
+extern void bcmsdh_unregister_client_driver(void);
+extern int sdio_func_reg_notify(void* semaphore);
+extern void sdio_func_unreg_notify(void);
+
+#if defined(BCMLXSDMMC)
+int bcmsdh_reg_sdio_notify(void* semaphore)
+{
+	return sdio_func_reg_notify(semaphore);
+}
+
+void bcmsdh_unreg_sdio_notify(void)
+{
+	sdio_func_unreg_notify();
+}
+#endif /* defined(BCMLXSDMMC) */
+
+int
+bcmsdh_register(bcmsdh_driver_t *driver)
+{
+	int error = 0;
+
+	drvinfo = *driver;
+	SDLX_MSG(("%s: register client driver\n", __FUNCTION__));
+	error = bcmsdh_register_client_driver();
+	if (error) {
+		SDLX_MSG(("%s: failed %d\n", __FUNCTION__, error));
+		bcmsdh_unregister_client_driver();
+		memset(&drvinfo, 0, sizeof(drvinfo));
+	}
+
+	return error;
+}
+
+void
+bcmsdh_unregister(void)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
+		if (bcmsdh_pci_driver.node.next == NULL)
+			return;
+#endif
+
+	bcmsdh_unregister_client_driver();
+}
+
+void *bcmsdh_get_dev(bcmsdh_info_t *sdh)
+{
+	bcmsdh_os_info_t *bcmsdh_osinfo = sdh->os_cxt;
+	return bcmsdh_osinfo->dev;
+}
+
+void bcmsdh_dev_pm_stay_awake(bcmsdh_info_t *bcmsdh)
+{
+#if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36))
+	bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
+	pm_stay_awake(bcmsdh_osinfo->dev);
+#endif /* !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) */
+}
+
+void bcmsdh_dev_relax(bcmsdh_info_t *bcmsdh)
+{
+#if !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36))
+	bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
+	pm_relax(bcmsdh_osinfo->dev);
+#endif /* !defined(CONFIG_HAS_WAKELOCK) && (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 36)) */
+}
+
+bool bcmsdh_dev_pm_enabled(bcmsdh_info_t *bcmsdh)
+{
+	bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
+
+	return bcmsdh_osinfo->dev_wake_enabled;
+}
+
+#if defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID)
+int bcmsdh_get_oob_intr_num(bcmsdh_info_t *bcmsdh)
+{
+	bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
+
+	return bcmsdh_osinfo->oob_irq_num;
+}
+
+void bcmsdh_oob_intr_set(bcmsdh_info_t *bcmsdh, bool enable)
+{
+	unsigned long flags;
+	bcmsdh_os_info_t *bcmsdh_osinfo;
+
+	if (!bcmsdh)
+		return;
+
+	bcmsdh_osinfo = bcmsdh->os_cxt;
+	spin_lock_irqsave(&bcmsdh_osinfo->oob_irq_spinlock, flags);
+	if (bcmsdh_osinfo->oob_irq_enabled != enable) {
+		if (enable)
+			enable_irq(bcmsdh_osinfo->oob_irq_num);
+		else
+			disable_irq_nosync(bcmsdh_osinfo->oob_irq_num);
+		bcmsdh_osinfo->oob_irq_enabled = enable;
+	}
+	spin_unlock_irqrestore(&bcmsdh_osinfo->oob_irq_spinlock, flags);
+}
+
+#ifdef ENABLE_WAKEUP_PKT_DUMP
+extern volatile bool dhd_mmc_suspend;
+extern volatile bool dhd_mmc_wake;
+#endif /* ENABLE_WAKEUP_PKT_DUMP */
+
+static irqreturn_t wlan_oob_irq(int irq, void *dev_id)
+{
+	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)dev_id;
+	bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
+
+#ifndef BCMSPI_ANDROID
+	bcmsdh_oob_intr_set(bcmsdh, FALSE);
+#endif /* !BCMSPI_ANDROID */
+	bcmsdh_osinfo->oob_irq_handler(bcmsdh_osinfo->oob_irq_handler_context);
+
+#ifdef ENABLE_WAKEUP_PKT_DUMP
+	if (dhd_mmc_suspend) {
+		dhd_mmc_wake = TRUE;
+	}
+#endif /* ENABLE_WAKEUP_PKT_DUMP */
+
+	return IRQ_HANDLED;
+}
+
+int bcmsdh_oob_intr_register(bcmsdh_info_t *bcmsdh, bcmsdh_cb_fn_t oob_irq_handler,
+	void* oob_irq_handler_context)
+{
+	int err = 0;
+	bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
+
+	if (bcmsdh_osinfo->oob_irq_registered) {
+		SDLX_ERR(("%s: irq is already registered\n", __FUNCTION__));
+		return -EBUSY;
+	}
+#ifdef HW_OOB
+	SDLX_MSG(("%s: HW_OOB irq=%d flags=0x%X\n", __FUNCTION__,
+		(int)bcmsdh_osinfo->oob_irq_num, (int)bcmsdh_osinfo->oob_irq_flags));
+#else
+	SDLX_MSG(("%s: SW_OOB irq=%d flags=0x%X\n", __FUNCTION__,
+		(int)bcmsdh_osinfo->oob_irq_num, (int)bcmsdh_osinfo->oob_irq_flags));
+#endif
+	bcmsdh_osinfo->oob_irq_handler = oob_irq_handler;
+	bcmsdh_osinfo->oob_irq_handler_context = oob_irq_handler_context;
+	bcmsdh_osinfo->oob_irq_enabled = TRUE;
+	bcmsdh_osinfo->oob_irq_registered = TRUE;
+#if defined(CONFIG_ARCH_ODIN)
+	err = odin_gpio_sms_request_irq(bcmsdh_osinfo->oob_irq_num, wlan_oob_irq,
+		bcmsdh_osinfo->oob_irq_flags, "bcmsdh_sdmmc", bcmsdh);
+#else
+	err = request_irq(bcmsdh_osinfo->oob_irq_num, wlan_oob_irq,
+		bcmsdh_osinfo->oob_irq_flags, "bcmsdh_sdmmc", bcmsdh);
+#endif /* defined(CONFIG_ARCH_ODIN) */
+	if (err) {
+		SDLX_ERR(("%s: request_irq failed with %d\n", __FUNCTION__, err));
+		bcmsdh_osinfo->oob_irq_enabled = FALSE;
+		bcmsdh_osinfo->oob_irq_registered = FALSE;
+		return err;
+	}
+
+#if defined(DISABLE_WOWLAN)
+	SDLX_MSG(("%s: disable_irq_wake\n", __FUNCTION__));
+	bcmsdh_osinfo->oob_irq_wake_enabled = FALSE;
+#else
+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI)
+	if (device_may_wakeup(bcmsdh_osinfo->dev)) {
+#endif /* CONFIG_ARCH_RHEA || CONFIG_ARCH_CAPRI */
+		err = enable_irq_wake(bcmsdh_osinfo->oob_irq_num);
+		if (err)
+			SDLX_ERR(("%s: enable_irq_wake failed with %d\n", __FUNCTION__, err));
+		else
+			bcmsdh_osinfo->oob_irq_wake_enabled = TRUE;
+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI)
+	}
+#endif /* CONFIG_ARCH_RHEA || CONFIG_ARCH_CAPRI */
+#endif
+
+	return 0;
+}
+
+void bcmsdh_oob_intr_unregister(bcmsdh_info_t *bcmsdh)
+{
+	int err = 0;
+	bcmsdh_os_info_t *bcmsdh_osinfo = bcmsdh->os_cxt;
+
+	SDLX_MSG(("%s: Enter\n", __FUNCTION__));
+	if (!bcmsdh_osinfo->oob_irq_registered) {
+		SDLX_MSG(("%s: irq is not registered\n", __FUNCTION__));
+		return;
+	}
+	if (bcmsdh_osinfo->oob_irq_wake_enabled) {
+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI)
+		if (device_may_wakeup(bcmsdh_osinfo->dev)) {
+#endif /* CONFIG_ARCH_RHEA || CONFIG_ARCH_CAPRI */
+			err = disable_irq_wake(bcmsdh_osinfo->oob_irq_num);
+			if (!err)
+				bcmsdh_osinfo->oob_irq_wake_enabled = FALSE;
+#if defined(CONFIG_ARCH_RHEA) || defined(CONFIG_ARCH_CAPRI)
+		}
+#endif /* CONFIG_ARCH_RHEA || CONFIG_ARCH_CAPRI */
+	}
+	if (bcmsdh_osinfo->oob_irq_enabled) {
+		disable_irq(bcmsdh_osinfo->oob_irq_num);
+		bcmsdh_osinfo->oob_irq_enabled = FALSE;
+	}
+	free_irq(bcmsdh_osinfo->oob_irq_num, bcmsdh);
+	bcmsdh_osinfo->oob_irq_registered = FALSE;
+}
+#endif /* defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID) */
+
+/* Module parameters specific to each host-controller driver */
+/* XXX Need to move these to where they really belong! */
+
+extern uint sd_msglevel;	/* Debug message level */
+module_param(sd_msglevel, uint, 0);
+
+extern uint sd_power;	/* 0 = SD Power OFF, 1 = SD Power ON. */
+module_param(sd_power, uint, 0);
+
+extern uint sd_clock;	/* SD Clock Control, 0 = SD Clock OFF, 1 = SD Clock ON */
+module_param(sd_clock, uint, 0);
+
+extern uint sd_divisor;	/* Divisor (-1 means external clock) */
+module_param(sd_divisor, uint, 0);
+
+extern uint sd_sdmode;	/* Default is SD4, 0=SPI, 1=SD1, 2=SD4 */
+module_param(sd_sdmode, uint, 0);
+
+extern uint sd_hiok;	/* Ok to use hi-speed mode */
+module_param(sd_hiok, uint, 0);
+
+extern uint sd_f2_blocksize;
+module_param(sd_f2_blocksize, int, 0);
+
+extern uint sd_f1_blocksize;
+module_param(sd_f1_blocksize, int, 0);
+
+#ifdef BCMSDIOH_STD
+extern int sd_uhsimode;
+module_param(sd_uhsimode, int, 0);
+extern uint sd_tuning_period;
+module_param(sd_tuning_period, uint, 0);
+extern int sd_delay_value;
+module_param(sd_delay_value, uint, 0);
+
+/* SDIO Drive Strength for UHSI mode specific to SDIO3.0 */
+extern char dhd_sdiod_uhsi_ds_override[2];
+module_param_string(dhd_sdiod_uhsi_ds_override, dhd_sdiod_uhsi_ds_override, 2, 0);
+
+#endif
+
+#ifdef BCMSDH_MODULE
+EXPORT_SYMBOL(bcmsdh_attach);
+EXPORT_SYMBOL(bcmsdh_detach);
+EXPORT_SYMBOL(bcmsdh_intr_query);
+EXPORT_SYMBOL(bcmsdh_intr_enable);
+EXPORT_SYMBOL(bcmsdh_intr_disable);
+EXPORT_SYMBOL(bcmsdh_intr_reg);
+EXPORT_SYMBOL(bcmsdh_intr_dereg);
+
+#if defined(DHD_DEBUG) || defined(BCMDBG)
+EXPORT_SYMBOL(bcmsdh_intr_pending);
+#endif
+
+#if defined(BT_OVER_SDIO)
+EXPORT_SYMBOL(bcmsdh_btsdio_interface_init);
+#endif /* defined (BT_OVER_SDIO) */
+
+EXPORT_SYMBOL(bcmsdh_devremove_reg);
+EXPORT_SYMBOL(bcmsdh_cfg_read);
+EXPORT_SYMBOL(bcmsdh_cfg_write);
+EXPORT_SYMBOL(bcmsdh_cis_read);
+EXPORT_SYMBOL(bcmsdh_reg_read);
+EXPORT_SYMBOL(bcmsdh_reg_write);
+EXPORT_SYMBOL(bcmsdh_regfail);
+EXPORT_SYMBOL(bcmsdh_send_buf);
+EXPORT_SYMBOL(bcmsdh_recv_buf);
+
+EXPORT_SYMBOL(bcmsdh_rwdata);
+EXPORT_SYMBOL(bcmsdh_abort);
+EXPORT_SYMBOL(bcmsdh_query_device);
+EXPORT_SYMBOL(bcmsdh_query_iofnum);
+EXPORT_SYMBOL(bcmsdh_iovar_op);
+EXPORT_SYMBOL(bcmsdh_register);
+EXPORT_SYMBOL(bcmsdh_unregister);
+EXPORT_SYMBOL(bcmsdh_chipmatch);
+EXPORT_SYMBOL(bcmsdh_reset);
+EXPORT_SYMBOL(bcmsdh_waitlockfree);
+
+EXPORT_SYMBOL(bcmsdh_get_dstatus);
+EXPORT_SYMBOL(bcmsdh_cfg_read_word);
+EXPORT_SYMBOL(bcmsdh_cfg_write_word);
+EXPORT_SYMBOL(bcmsdh_cur_sbwad);
+EXPORT_SYMBOL(bcmsdh_chipinfo);
+
+#endif /* BCMSDH_MODULE */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
@@ -0,0 +1,2098 @@
+/*
+ * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+#include <typedefs.h>
+
+#include <bcmdevs.h>
+#include <bcmendian.h>
+#include <bcmutils.h>
+#include <osl.h>
+#include <sdio.h>	/* SDIO Device and Protocol Specs */
+#include <sdioh.h>	/* Standard SDIO Host Controller Specification */
+#include <bcmsdbus.h>	/* bcmsdh to/from specific controller APIs */
+#include <sdiovar.h>	/* ioctl/iovars */
+
+#include <linux/mmc/core.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_dbg.h>
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
+#include <linux/suspend.h>
+extern volatile bool dhd_mmc_suspend;
+#endif
+#include "bcmsdh_sdmmc.h"
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)) || \
+	(LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+static inline void
+mmc_host_clk_hold(struct mmc_host *host)
+{
+	BCM_REFERENCE(host);
+	return;
+}
+
+static inline void
+mmc_host_clk_release(struct mmc_host *host)
+{
+	BCM_REFERENCE(host);
+	return;
+}
+
+static inline unsigned int
+mmc_host_clk_rate(struct mmc_host *host)
+{
+	return host->ios.clock;
+}
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0) */
+
+#ifndef BCMSDH_MODULE
+extern int sdio_function_init(void);
+extern void sdio_function_cleanup(void);
+#endif /* BCMSDH_MODULE */
+
+#if !defined(OOB_INTR_ONLY)
+static void IRQHandler(struct sdio_func *func);
+static void IRQHandlerF2(struct sdio_func *func);
+#endif /* !defined(OOB_INTR_ONLY) */
+static int sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr);
+#if defined(ENABLE_INSMOD_NO_FW_LOAD)
+#if defined(MMC_SW_RESET) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+extern int mmc_sw_reset(struct mmc_card *card);
+#else
+extern int mmc_sw_reset(struct mmc_host *host);
+#endif
+#elif defined(MMC_HW_RESET) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
+extern int mmc_hw_reset(struct mmc_card *card);
+#else
+extern int mmc_hw_reset(struct mmc_host *host);
+#endif
+#elif defined(BUS_POWER_RESTORE) && \
+LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
+#undef MMC_SW_RESET
+#undef MMC_HW_RESET
+#else
+extern int sdio_reset_comm(struct mmc_card *card);
+#endif
+#endif
+#ifdef GLOBAL_SDMMC_INSTANCE
+extern PBCMSDH_SDMMC_INSTANCE gInstance;
+#endif
+
+#define DEFAULT_SDIO_F2_BLKSIZE		512
+#ifndef CUSTOM_SDIO_F2_BLKSIZE
+#ifndef DYNAMIC_F2_BLKSIZE_FOR_NONLEGACY
+#define CUSTOM_SDIO_F2_BLKSIZE		DEFAULT_SDIO_F2_BLKSIZE
+#else
+#define CUSTOM_SDIO_F2_BLKSIZE     DYNAMIC_F2_BLKSIZE_FOR_NONLEGACY
+#endif /* CUSTOM_SDIO_F2_BLKSIZE */
+#endif
+
+#define DEFAULT_SDIO_F1_BLKSIZE		64
+#ifndef CUSTOM_SDIO_F1_BLKSIZE
+#define CUSTOM_SDIO_F1_BLKSIZE		DEFAULT_SDIO_F1_BLKSIZE
+#endif
+
+#define COPY_BUF_SIZE	(SDPCM_MAXGLOM_SIZE * 1600)
+
+#define MAX_IO_RW_EXTENDED_BLK		511
+
+uint sd_sdmode = SDIOH_MODE_SD4;	/* Use SD4 mode by default */
+uint sd_f2_blocksize = CUSTOM_SDIO_F2_BLKSIZE;
+uint sd_f1_blocksize = CUSTOM_SDIO_F1_BLKSIZE;
+
+#if defined(BT_OVER_SDIO)
+uint sd_f3_blocksize = 64;
+#endif /* defined (BT_OVER_SDIO) */
+
+uint sd_divisor = 2;			/* Default 48MHz/2 = 24MHz */
+
+uint sd_power = 1;		/* Default to SD Slot powered ON */
+uint sd_clock = 1;		/* Default to SD Clock turned ON */
+uint sd_hiok = FALSE;	/* Don't use hi-speed mode by default */
+uint sd_msglevel = SDH_ERROR_VAL;
+uint sd_use_dma = TRUE;
+
+#ifndef CUSTOM_RXCHAIN
+#define CUSTOM_RXCHAIN 0
+#endif
+
+DHD_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait);
+DHD_PM_RESUME_WAIT_INIT(sdioh_request_word_wait);
+DHD_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait);
+DHD_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait);
+
+#define DMA_ALIGN_MASK	0x03
+#define MMC_SDIO_ABORT_RETRY_LIMIT 5
+
+int sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data);
+#ifdef NOTYET
+static int
+sdioh_sdmmc_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data);
+#endif /* NOTYET */
+
+#if defined(BT_OVER_SDIO)
+extern
+void sdioh_sdmmc_card_enable_func_f3(sdioh_info_t *sd, struct sdio_func *func)
+{
+	sd->func[3] = func;
+	sd_info(("%s sd->func[3] %p\n", __FUNCTION__, sd->func[3]));
+}
+#endif /* defined (BT_OVER_SDIO) */
+
+void  sdmmc_set_timing(sdioh_info_t *sd, uint8 timing);
+uint8 sdmmc_get_timing(sdioh_info_t *sd);
+void  sdmmc_set_clock_rate(sdioh_info_t *sd, uint hz);
+uint  sdmmc_get_clock_rate(sdioh_info_t *sd);
+void  sdmmc_set_clock_divisor(sdioh_info_t *sd, uint sd_div);
+
+static int
+sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd)
+{
+	int err_ret;
+	uint32 fbraddr;
+	uint8 func;
+
+	sd_trace(("%s\n", __FUNCTION__));
+
+	/* Get the Card's common CIS address */
+	sd->com_cis_ptr = sdioh_sdmmc_get_cisaddr(sd, SDIOD_CCCR_CISPTR_0);
+	sd->func_cis_ptr[0] = sd->com_cis_ptr;
+	sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr));
+
+	/* Get the Card's function CIS (for each function) */
+	for (fbraddr = SDIOD_FBR_STARTADDR, func = 1;
+	     func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
+		sd->func_cis_ptr[func] = sdioh_sdmmc_get_cisaddr(sd, SDIOD_FBR_CISPTR_0 + fbraddr);
+		sd_info(("%s: Function %d CIS Ptr = 0x%x\n",
+		         __FUNCTION__, func, sd->func_cis_ptr[func]));
+	}
+
+	sd->func_cis_ptr[0] = sd->com_cis_ptr;
+	sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr));
+
+	/* Enable Function 1 */
+	sdio_claim_host(sd->func[1]);
+	err_ret = sdio_enable_func(sd->func[1]);
+	sdio_release_host(sd->func[1]);
+	if (err_ret) {
+		sd_err(("bcmsdh_sdmmc: Failed to enable F1 Err: %d\n", err_ret));
+	}
+
+	return FALSE;
+}
+
+/*
+ *  Set standard CCCR driver strength. Default value is type B.
+ *  Type: Value, driver strength
+ *     A:  0x10, x1.5
+ *     B:  0x00, x1
+ *     C:  0x20, x0.75
+ *     D:  0x30, x0.5
+ */
+int
+sdioh_set_driver_strength(struct sdio_func *func, uint8 level)
+{
+	int reg;
+	int err = 0;
+
+	sdio_claim_host(func);
+	reg = sdio_readb(func, SDIOD_CCCR_DRIVER_STRENGTH, &err);
+	if (err) {
+		sd_err(("sd_ds error for read SDIOD_CCCR_DRIVER_STRENGTH : 0x%x\n", err));
+		goto done;
+	} else {
+		sd_info(("SYNA: sd_ds get cccr driver strength 0x%x\n", reg));
+	}
+
+	reg = ((reg & 0xf) | level);
+	sdio_writeb(func, reg, SDIOD_CCCR_DRIVER_STRENGTH, &err);
+
+	if (err) {
+		sd_err(("sd_ds error for write SDIOD_CCCR_DRIVER_STRENGTH : 0x%x\n", err));
+		goto done;
+	} else {
+		sd_info(("SYNA: sd_ds set cccr driver strength 0x%x\n", reg));
+	}
+done:
+	sdio_release_host(func);
+	return err;
+}
+
+/*
+ *	Public entry points & extern's
+ */
+extern sdioh_info_t *
+sdioh_attach(osl_t *osh, struct sdio_func *func)
+{
+	sdioh_info_t *sd = NULL;
+	int err_ret;
+
+	sd_trace(("%s\n", __FUNCTION__));
+
+	if (func == NULL) {
+		sd_err(("%s: sdio function device is NULL\n", __FUNCTION__));
+		return NULL;
+	}
+
+	if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) {
+		sd_err(("sdioh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh)));
+		return NULL;
+	}
+	bzero((char *)sd, sizeof(sdioh_info_t));
+#if defined(BCMSDIOH_TXGLOM) && defined(BCMSDIOH_STATIC_COPY_BUF)
+	sd->copy_buf = MALLOC(osh, COPY_BUF_SIZE);
+	if (sd->copy_buf == NULL) {
+		sd_err(("%s: MALLOC of %d-byte copy_buf failed\n",
+			__FUNCTION__, COPY_BUF_SIZE));
+		goto fail;
+	}
+#endif
+	sd->osh = osh;
+	sd->fake_func0.num = 0;
+	sd->fake_func0.card = func->card;
+	sd->func[0] = &sd->fake_func0;
+#ifdef GLOBAL_SDMMC_INSTANCE
+	if (func->num == 2)
+		sd->func[1] = gInstance->func[1];
+#else
+	sd->func[1] = func->card->sdio_func[0];
+#endif
+	sd->func[2] = func->card->sdio_func[1];
+#ifdef GLOBAL_SDMMC_INSTANCE
+	sd->func[func->num] = func;
+#endif
+
+#if defined(BT_OVER_SDIO)
+	sd->func[3] = NULL;
+#endif /* defined (BT_OVER_SDIO) */
+
+	sd->num_funcs = 2;
+	sd->sd_blockmode = TRUE;
+	sd->use_client_ints = TRUE;
+	sd->client_block_size[0] = 64;
+	sd->use_rxchain = CUSTOM_RXCHAIN;
+	if (sd->func[1] == NULL || sd->func[2] == NULL) {
+		sd_err(("%s: func 1 or 2 is null \n", __FUNCTION__));
+		goto fail;
+	}
+	sdio_set_drvdata(sd->func[1], sd);
+
+	sdio_claim_host(sd->func[1]);
+	sd->client_block_size[1] = sd_f1_blocksize;
+	err_ret = sdio_set_block_size(sd->func[1], sd_f1_blocksize);
+	sdio_release_host(sd->func[1]);
+	if (err_ret) {
+		sd_err(("bcmsdh_sdmmc: Failed to set F1 blocksize(%d)\n", err_ret));
+		goto fail;
+	}
+
+	sdio_claim_host(sd->func[2]);
+	sd->client_block_size[2] = sd_f2_blocksize;
+	printf("%s: set sd_f2_blocksize %d\n", __FUNCTION__, sd_f2_blocksize);
+	err_ret = sdio_set_block_size(sd->func[2], sd_f2_blocksize);
+	sdio_release_host(sd->func[2]);
+	if (err_ret) {
+		sd_err(("bcmsdh_sdmmc: Failed to set F2 blocksize to %d(%d)\n",
+			sd_f2_blocksize, err_ret));
+		goto fail;
+	}
+
+	sd->sd_clk_rate = sdmmc_get_clock_rate(sd);
+	printf("%s: sd clock rate = %u\n", __FUNCTION__, sd->sd_clk_rate);
+	sdioh_sdmmc_card_enablefuncs(sd);
+#if !defined(OOB_INTR_ONLY)
+	mutex_init(&sd->claim_host_mutex); // terence 20140926: fix for claim host issue
+#endif
+
+	sd_trace(("%s: Done\n", __FUNCTION__));
+	return sd;
+
+fail:
+#if defined(BCMSDIOH_TXGLOM) && defined(BCMSDIOH_STATIC_COPY_BUF)
+	MFREE(sd->osh, sd->copy_buf, COPY_BUF_SIZE);
+#endif
+	MFREE(sd->osh, sd, sizeof(sdioh_info_t));
+	return NULL;
+}
+
+extern SDIOH_API_RC
+sdioh_detach(osl_t *osh, sdioh_info_t *sd)
+{
+	sd_trace(("%s\n", __FUNCTION__));
+
+	if (sd) {
+
+		/* Disable Function 2 */
+		if (sd->func[2]) {
+			sdio_claim_host(sd->func[2]);
+			sdio_disable_func(sd->func[2]);
+			sdio_release_host(sd->func[2]);
+		}
+
+		/* Disable Function 1 */
+		if (sd->func[1]) {
+			sdio_claim_host(sd->func[1]);
+			sdio_disable_func(sd->func[1]);
+			sdio_release_host(sd->func[1]);
+		}
+
+		sd->func[1] = NULL;
+		sd->func[2] = NULL;
+
+#if defined(BCMSDIOH_TXGLOM) && defined(BCMSDIOH_STATIC_COPY_BUF)
+		MFREE(sd->osh, sd->copy_buf, COPY_BUF_SIZE);
+#endif
+		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
+	}
+	return SDIOH_API_RC_SUCCESS;
+}
+
+#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
+
+extern SDIOH_API_RC
+sdioh_enable_func_intr(sdioh_info_t *sd)
+{
+	uint8 reg;
+	int err;
+
+	if (sd->func[0] == NULL) {
+		sd_err(("%s: function 0 pointer is NULL\n", __FUNCTION__));
+		return SDIOH_API_RC_FAIL;
+	}
+
+	sdio_claim_host(sd->func[0]);
+	reg = sdio_readb(sd->func[0], SDIOD_CCCR_INTEN, &err);
+	if (err) {
+		sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err));
+		sdio_release_host(sd->func[0]);
+		return SDIOH_API_RC_FAIL;
+	}
+	/* Enable F1 and F2 interrupts, clear master enable */
+	reg &= ~INTR_CTL_MASTER_EN;
+	reg |= (INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN);
+#if defined(BT_OVER_SDIO)
+	reg |= (INTR_CTL_FUNC3_EN);
+#endif /* defined (BT_OVER_SDIO) */
+	sdio_writeb(sd->func[0], reg, SDIOD_CCCR_INTEN, &err);
+	sdio_release_host(sd->func[0]);
+
+	if (err) {
+		sd_err(("%s: error for write SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err));
+		return SDIOH_API_RC_FAIL;
+	}
+
+	return SDIOH_API_RC_SUCCESS;
+}
+
+extern SDIOH_API_RC
+sdioh_disable_func_intr(sdioh_info_t *sd)
+{
+	uint8 reg;
+	int err;
+
+	if (sd->func[0] == NULL) {
+		sd_err(("%s: function 0 pointer is NULL\n", __FUNCTION__));
+		return SDIOH_API_RC_FAIL;
+	}
+
+	sdio_claim_host(sd->func[0]);
+	reg = sdio_readb(sd->func[0], SDIOD_CCCR_INTEN, &err);
+	if (err) {
+		sd_err(("%s: error for read SDIO_CCCR_IENx : 0x%x (ignore when remove)\n",
+			__FUNCTION__, err));
+		sdio_release_host(sd->func[0]);
+		return SDIOH_API_RC_FAIL;
+	}
+	reg &= ~(INTR_CTL_FUNC1_EN | INTR_CTL_FUNC2_EN);
+#if defined(BT_OVER_SDIO)
+	reg &= ~INTR_CTL_FUNC3_EN;
+#endif
+	/* Disable master interrupt with the last function interrupt */
+	if (!(reg & 0xFE))
+		reg = 0;
+	sdio_writeb(sd->func[0], reg, SDIOD_CCCR_INTEN, &err);
+	sdio_release_host(sd->func[0]);
+
+	if (err) {
+		sd_err(("%s: error for write SDIO_CCCR_IENx : 0x%x\n", __FUNCTION__, err));
+		return SDIOH_API_RC_FAIL;
+	}
+
+	return SDIOH_API_RC_SUCCESS;
+}
+#endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */
+
+/* Configure callback to client when we recieve client interrupt */
+extern SDIOH_API_RC
+sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh)
+{
+	sd_trace(("%s: Entering\n", __FUNCTION__));
+	if (fn == NULL) {
+		sd_err(("%s: interrupt handler is NULL, not registering\n", __FUNCTION__));
+		return SDIOH_API_RC_FAIL;
+	}
+#if !defined(OOB_INTR_ONLY)
+	sd->intr_handler = fn;
+	sd->intr_handler_arg = argh;
+	sd->intr_handler_valid = TRUE;
+
+	/* register and unmask irq */
+	if (sd->func[2]) {
+		sdio_claim_host(sd->func[2]);
+		sdio_claim_irq(sd->func[2], IRQHandlerF2);
+		sdio_release_host(sd->func[2]);
+	}
+
+	if (sd->func[1]) {
+		sdio_claim_host(sd->func[1]);
+		sdio_claim_irq(sd->func[1], IRQHandler);
+		sdio_release_host(sd->func[1]);
+	}
+#elif defined(HW_OOB)
+	sdioh_enable_func_intr(sd);
+#endif /* !defined(OOB_INTR_ONLY) */
+
+	return SDIOH_API_RC_SUCCESS;
+}
+
+extern SDIOH_API_RC
+sdioh_interrupt_deregister(sdioh_info_t *sd)
+{
+	sd_trace(("%s: Entering\n", __FUNCTION__));
+
+#if !defined(OOB_INTR_ONLY)
+	if (sd->func[1]) {
+		/* register and unmask irq */
+		sdio_claim_host(sd->func[1]);
+		sdio_release_irq(sd->func[1]);
+		sdio_release_host(sd->func[1]);
+	}
+
+	if (sd->func[2]) {
+		/* Claim host controller F2 */
+		sdio_claim_host(sd->func[2]);
+		sdio_release_irq(sd->func[2]);
+		/* Release host controller F2 */
+		sdio_release_host(sd->func[2]);
+	}
+
+	sd->intr_handler_valid = FALSE;
+	sd->intr_handler = NULL;
+	sd->intr_handler_arg = NULL;
+#elif defined(HW_OOB)
+	if (dhd_download_fw_on_driverload)
+		sdioh_disable_func_intr(sd);
+#endif /* !defined(OOB_INTR_ONLY) */
+	return SDIOH_API_RC_SUCCESS;
+}
+
+extern SDIOH_API_RC
+sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff)
+{
+	sd_trace(("%s: Entering\n", __FUNCTION__));
+	*onoff = sd->client_intr_enabled;
+	return SDIOH_API_RC_SUCCESS;
+}
+
+#if defined(DHD_DEBUG) || defined(BCMDBG)
+extern bool
+sdioh_interrupt_pending(sdioh_info_t *sd)
+{
+	return (0);
+}
+#endif
+
+uint
+sdioh_query_iofnum(sdioh_info_t *sd)
+{
+	return sd->num_funcs;
+}
+
+/* IOVar table */
+enum {
+	IOV_MSGLEVEL = 1,
+	IOV_BLOCKMODE,
+	IOV_BLOCKSIZE,
+	IOV_DMA,
+	IOV_USEINTS,
+	IOV_NUMINTS,
+	IOV_NUMLOCALINTS,
+	IOV_HOSTREG,
+	IOV_DEVREG,
+	IOV_DIVISOR,
+	IOV_SDMODE,
+	IOV_HISPEED,
+	IOV_HCIREGS,
+	IOV_POWER,
+	IOV_CLOCK,
+	IOV_RXCHAIN,
+	IOV_DS
+};
+
+const bcm_iovar_t sdioh_iovars[] = {
+	{"sd_msglevel", IOV_MSGLEVEL,	0, 0,	IOVT_UINT32,	0 },
+	{"sd_blockmode", IOV_BLOCKMODE, 0, 0,	IOVT_BOOL,	0 },
+	{"sd_blocksize", IOV_BLOCKSIZE, 0, 0,	IOVT_UINT32,	0 }, /* ((fn << 16) | size) */
+	{"sd_dma",	IOV_DMA,	0, 0,	IOVT_BOOL,	0 },
+	{"sd_ints",	IOV_USEINTS,	0, 0,	IOVT_BOOL,	0 },
+	{"sd_numints",	IOV_NUMINTS,	0, 0,	IOVT_UINT32,	0 },
+	{"sd_numlocalints", IOV_NUMLOCALINTS, 0, 0, IOVT_UINT32,	0 },
+	{"sd_divisor",	IOV_DIVISOR,	0, 0,	IOVT_UINT32,	0 },
+	{"sd_power",	IOV_POWER,	0, 0,	IOVT_UINT32,	0 },
+	{"sd_clock",	IOV_CLOCK,	0, 0,	IOVT_UINT32,	0 },
+	{"sd_mode",	IOV_SDMODE,	0, 0,	IOVT_UINT32,	100},
+	{"sd_highspeed", IOV_HISPEED,	0, 0,	IOVT_UINT32,	0 },
+	{"sd_rxchain",  IOV_RXCHAIN,    0, 0, 	IOVT_BOOL,	0 },
+#ifdef BCMDBG
+	{"sd_hciregs",	IOV_HCIREGS,	0, 0,	IOVT_BUFFER,	0 },
+#endif
+	{"sd_ds",	IOV_DS,		0, 0,	IOVT_UINT32,	0 },
+	{NULL, 0, 0, 0, 0, 0 }
+};
+
+int
+sdioh_iovar_op(sdioh_info_t *si, const char *name,
+                           void *params, int plen, void *arg, uint len, bool set)
+{
+	const bcm_iovar_t *vi = NULL;
+	int bcmerror = 0;
+	uint val_size;
+	int32 int_val = 0;
+	bool bool_val;
+	uint32 actionid;
+
+	ASSERT(name);
+
+	/* Get must have return space; Set does not take qualifiers */
+	ASSERT(set || (arg && len));
+	ASSERT(!set || (!params && !plen));
+
+	sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name));
+
+	if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) {
+		bcmerror = BCME_UNSUPPORTED;
+		goto exit;
+	}
+
+	if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0)
+		goto exit;
+
+	/* XXX Copied from dhd, copied from wl; certainly overkill here? */
+	/* Set up params so get and set can share the convenience variables */
+	if (params == NULL) {
+		params = arg;
+		plen = len;
+	}
+
+	if (vi->type == IOVT_VOID)
+		val_size = 0;
+	else if (vi->type == IOVT_BUFFER)
+		val_size = len;
+	else
+		val_size = sizeof(int);
+
+	if (plen >= (int)sizeof(int_val))
+		bcopy(params, &int_val, sizeof(int_val));
+
+	bool_val = (int_val != 0) ? TRUE : FALSE;
+	BCM_REFERENCE(bool_val);
+
+	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+	switch (actionid) {
+	case IOV_GVAL(IOV_MSGLEVEL):
+		int_val = (int32)sd_msglevel;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_MSGLEVEL):
+		sd_msglevel = int_val;
+		break;
+
+	case IOV_GVAL(IOV_BLOCKMODE):
+		int_val = (int32)si->sd_blockmode;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_BLOCKMODE):
+		si->sd_blockmode = (bool)int_val;
+		/* Haven't figured out how to make non-block mode with DMA */
+		break;
+
+	case IOV_GVAL(IOV_BLOCKSIZE):
+		if ((uint32)int_val > si->num_funcs) {
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		int_val = (int32)si->client_block_size[int_val];
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_BLOCKSIZE):
+	{
+		uint func = ((uint32)int_val >> 16);
+		uint blksize = (uint16)int_val;
+		uint maxsize;
+
+		if (func > si->num_funcs) {
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		/* XXX These hardcoded sizes are a hack, remove after proper CIS parsing. */
+		switch (func) {
+		case 0: maxsize = 32; break;
+		case 1: maxsize = BLOCK_SIZE_4318; break;
+		case 2: maxsize = BLOCK_SIZE_4328; break;
+		default: maxsize = 0;
+		}
+		if (blksize > maxsize) {
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		if (!blksize) {
+			blksize = maxsize;
+		}
+
+		/* Now set it */
+		si->client_block_size[func] = blksize;
+
+#ifdef USE_DYNAMIC_F2_BLKSIZE
+		if (si->func[func] == NULL) {
+			sd_err(("%s: SDIO Device not present\n", __FUNCTION__));
+			bcmerror = BCME_NORESOURCE;
+			break;
+		}
+		sdio_claim_host(si->func[func]);
+		bcmerror = sdio_set_block_size(si->func[func], blksize);
+		if (bcmerror)
+			sd_err(("%s: Failed to set F%d blocksize to %d(%d)\n",
+				__FUNCTION__, func, blksize, bcmerror));
+		sdio_release_host(si->func[func]);
+#endif /* USE_DYNAMIC_F2_BLKSIZE */
+		break;
+	}
+
+	case IOV_GVAL(IOV_RXCHAIN):
+		int_val = (int32)si->use_rxchain;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_GVAL(IOV_DMA):
+		int_val = (int32)si->sd_use_dma;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_DMA):
+		si->sd_use_dma = (bool)int_val;
+		break;
+
+	case IOV_GVAL(IOV_USEINTS):
+		int_val = (int32)si->use_client_ints;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_USEINTS):
+		si->use_client_ints = (bool)int_val;
+		if (si->use_client_ints)
+			si->intmask |= CLIENT_INTR;
+		else
+			si->intmask &= ~CLIENT_INTR;
+
+		break;
+
+	case IOV_GVAL(IOV_DIVISOR):
+		int_val = (uint32)sd_divisor;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_DIVISOR):
+		/* set the clock to divisor, if value is non-zero & power of 2 */
+		if (int_val && !(int_val & (int_val - 1))) {
+			sd_divisor = int_val;
+			sdmmc_set_clock_divisor(si, sd_divisor);
+		} else {
+			DHD_ERROR(("%s: Invalid sd_divisor value, should be power of 2!\n",
+				__FUNCTION__));
+		}
+		break;
+
+	case IOV_GVAL(IOV_POWER):
+		int_val = (uint32)sd_power;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_POWER):
+		sd_power = int_val;
+		break;
+
+	case IOV_GVAL(IOV_CLOCK):
+		int_val = (uint32)sd_clock;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_CLOCK):
+		sd_clock = int_val;
+		break;
+
+	case IOV_GVAL(IOV_SDMODE):
+		int_val = (uint32)sd_sdmode;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_SDMODE):
+		sd_sdmode = int_val;
+		break;
+
+	case IOV_GVAL(IOV_HISPEED):
+		int_val = (uint32)sd_hiok;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_HISPEED):
+		sd_hiok = int_val;
+		break;
+
+	case IOV_GVAL(IOV_NUMINTS):
+		int_val = (int32)si->intrcount;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_GVAL(IOV_NUMLOCALINTS):
+		int_val = (int32)0;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_GVAL(IOV_DS):
+	{
+		uint8 reg2;
+		int err;
+
+		sdio_claim_host(si->func[0]);
+		reg2 = sdio_readb(si->func[0], SDIOD_CCCR_DRIVER_STRENGTH, &err);
+		if (err) {
+			sd_err(("sd_ds error for read SDIOD_CCCR_DRIVER_STRENGTH : 0x%x\n", err));
+			bcmerror = BCME_SDIO_ERROR;
+		} else {
+			sd_trace(("sd_ds get cccr driver strength 0x%x\n", reg2));
+		}
+		sdio_release_host(si->func[0]);
+
+		int_val = (int)reg2;
+		bcopy(&int_val, arg, sizeof(int_val));
+		break;
+	}
+
+	case IOV_SVAL(IOV_DS):
+	{
+		uint8 type;
+		int err;
+
+		if (int_val == 0) {
+			type = 0x0;
+		} else if (int_val == 1) {
+			type = 0x10;
+		} else if (int_val == 2) {
+			type = 0x20;
+		} else if (int_val == 3) {
+			type = 0x30;
+		} else {
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		err = sdioh_set_driver_strength(si->func[0], type);
+		if (err) {
+			sd_err(("sd_ds error write SDIOD_CCCR_DRIVER_STRENGTH : 0x%x\n", err));
+		}
+		break;
+	}
+
+	default:
+		bcmerror = BCME_UNSUPPORTED;
+		break;
+	}
+exit:
+
+	/* XXX Remove protective lock after clients all clean... */
+	return bcmerror;
+}
+
+#if (defined(OOB_INTR_ONLY) && defined(HW_OOB)) || defined(FORCE_WOWLAN)
+/*
+ * XXX dhd -i eth0 sd_devreg 0 0xf2 0x3
+ */
+
+SDIOH_API_RC
+sdioh_enable_hw_oob_intr(sdioh_info_t *sd, bool enable)
+{
+	SDIOH_API_RC status;
+	uint8 data;
+
+	if (enable)
+		data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE | SDIO_SEPINT_ACT_HI;
+	else
+		data = SDIO_SEPINT_ACT_HI;	/* disable hw oob interrupt */
+
+	status = sdioh_request_byte(sd, SDIOH_WRITE, 0, SDIOD_CCCR_BRCM_SEPINT, &data);
+	return status;
+}
+#endif /* defined(OOB_INTR_ONLY) && defined(HW_OOB) */
+
+extern SDIOH_API_RC
+sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data)
+{
+	SDIOH_API_RC status;
+	/* No lock needed since sdioh_request_byte does locking */
+	status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data);
+	return status;
+}
+
+extern SDIOH_API_RC
+sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data)
+{
+	/* No lock needed since sdioh_request_byte does locking */
+	SDIOH_API_RC status;
+	status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data);
+	return status;
+}
+
+static int
+sdioh_sdmmc_get_cisaddr(sdioh_info_t *sd, uint32 regaddr)
+{
+	/* read 24 bits and return valid 17 bit addr */
+	int i;
+	uint32 scratch, regdata;
+	uint8 *ptr = (uint8 *)&scratch;
+	for (i = 0; i < 3; i++) {
+		if ((sdioh_sdmmc_card_regread (sd, 0, regaddr, 1, &regdata)) != SUCCESS)
+			sd_err(("%s: Can't read!\n", __FUNCTION__));
+
+		*ptr++ = (uint8) regdata;
+		regaddr++;
+	}
+
+	/* Only the lower 17-bits are valid */
+	scratch = ltoh32(scratch);
+	scratch &= 0x0001FFFF;
+	return (scratch);
+}
+
+extern SDIOH_API_RC
+sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length)
+{
+	uint32 count;
+	int offset;
+	uint32 foo;
+	uint8 *cis = cisd;
+
+	sd_trace(("%s: Func = %d\n", __FUNCTION__, func));
+
+	if (!sd->func_cis_ptr[func]) {
+		bzero(cis, length);
+		sd_err(("%s: no func_cis_ptr[%d]\n", __FUNCTION__, func));
+		return SDIOH_API_RC_FAIL;
+	}
+
+	sd_err(("%s: func_cis_ptr[%d]=0x%04x\n", __FUNCTION__, func, sd->func_cis_ptr[func]));
+
+	for (count = 0; count < length; count++) {
+		offset =  sd->func_cis_ptr[func] + count;
+		if (sdioh_sdmmc_card_regread (sd, 0, offset, 1, &foo) < 0) {
+			sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__));
+			return SDIOH_API_RC_FAIL;
+		}
+
+		*cis = (uint8)(foo & 0xff);
+		cis++;
+	}
+
+	return SDIOH_API_RC_SUCCESS;
+}
+
+extern SDIOH_API_RC
+sdioh_cisaddr_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 offset)
+{
+	uint32 foo;
+
+	sd_trace(("%s: Func = %d\n", __FUNCTION__, func));
+
+	if (!sd->func_cis_ptr[func]) {
+		sd_err(("%s: no func_cis_ptr[%d]\n", __FUNCTION__, func));
+		return SDIOH_API_RC_FAIL;
+	}
+
+	if (sdioh_sdmmc_card_regread (sd, 0, sd->func_cis_ptr[func]+offset, 1, &foo) < 0) {
+		sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__));
+		return SDIOH_API_RC_FAIL;
+	}
+
+	*cisd = (uint8)(foo & 0xff);
+
+	return SDIOH_API_RC_SUCCESS;
+}
+
+extern SDIOH_API_RC
+sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte)
+{
+	int err_ret = 0;
+#if defined(MMC_SDIO_ABORT)
+	int sdio_abort_retry = MMC_SDIO_ABORT_RETRY_LIMIT;
+#endif
+	struct osl_timespec now, before;
+
+	if (sd_msglevel & SDH_COST_VAL)
+		osl_do_gettimeofday(&before);
+
+	sd_info(("%s: rw=%d, func=%d, addr=0x%05x\n", __FUNCTION__, rw, func, regaddr));
+
+	DHD_PM_RESUME_WAIT(sdioh_request_byte_wait);
+	DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+	if(rw) { /* CMD52 Write */
+		if (func == 0) {
+			/* Can only directly write to some F0 registers.  Handle F2 enable
+			 * as a special case.
+			 */
+			if (regaddr == SDIOD_CCCR_IOEN) {
+#if defined(BT_OVER_SDIO)
+				if (sd->func[3]) {
+					sd_info(("bcmsdh_sdmmc F3: *byte 0x%x\n", *byte));
+
+					if (*byte & SDIO_FUNC_ENABLE_3) {
+						sdio_claim_host(sd->func[3]);
+
+						/* Set Function 3 Block Size */
+						err_ret = sdio_set_block_size(sd->func[3],
+						sd_f3_blocksize);
+						if (err_ret) {
+							sd_err(("F3 blocksize set err%d\n",
+								err_ret));
+						}
+
+						/* Enable Function 3 */
+						sd_info(("bcmsdh_sdmmc F3: enable F3 fn %p\n",
+						sd->func[3]));
+						err_ret = sdio_enable_func(sd->func[3]);
+						if (err_ret) {
+							sd_err(("bcmsdh_sdmmc: enable F3 err:%d\n",
+								err_ret));
+						}
+
+						sdio_release_host(sd->func[3]);
+
+						break;
+					} else if (*byte & SDIO_FUNC_DISABLE_3) {
+						sdio_claim_host(sd->func[3]);
+
+						/* Disable Function 3 */
+						sd_info(("bcmsdh_sdmmc F3: disable F3 fn %p\n",
+						sd->func[3]));
+						err_ret = sdio_disable_func(sd->func[3]);
+						if (err_ret) {
+							sd_err(("bcmsdh_sdmmc: Disable F3 err:%d\n",
+								err_ret));
+						}
+						sdio_release_host(sd->func[3]);
+						sd->func[3] = NULL;
+
+						break;
+					}
+				}
+#endif /* defined (BT_OVER_SDIO) */
+				if (sd->func[2]) {
+					sdio_claim_host(sd->func[2]);
+					if (*byte & SDIO_FUNC_ENABLE_2) {
+						/* Enable Function 2 */
+						err_ret = sdio_enable_func(sd->func[2]);
+						if (err_ret) {
+							sd_err(("bcmsdh_sdmmc: enable F2 failed:%d\n",
+								err_ret));
+						}
+					} else {
+						/* Disable Function 2 */
+						err_ret = sdio_disable_func(sd->func[2]);
+						if (err_ret) {
+							sd_err(("bcmsdh_sdmmc: Disab F2 failed:%d\n",
+								err_ret));
+						}
+					}
+					sdio_release_host(sd->func[2]);
+				}
+			}
+#if defined(MMC_SDIO_ABORT)
+			/* to allow abort command through F1 */
+			else if (regaddr == SDIOD_CCCR_IOABORT) {
+				/* XXX Because of SDIO3.0 host issue on Manta,
+				 * sometimes the abort fails.
+				 * Retrying again will fix this issue.
+				 */
+				while (sdio_abort_retry--) {
+					if (sd->func[func]) {
+						sdio_claim_host(sd->func[func]);
+						/*
+						 * this sdio_f0_writeb() can be replaced with
+						 * another api depending upon MMC driver change.
+						 * As of this time, this is temporaray one
+						 */
+						sdio_writeb(sd->func[func],
+							*byte, regaddr, &err_ret);
+						sdio_release_host(sd->func[func]);
+					}
+					if (!err_ret)
+						break;
+				}
+			}
+#endif /* MMC_SDIO_ABORT */
+#if defined(SDIO_ISR_THREAD)
+			else if (regaddr == SDIOD_CCCR_INTR_EXTN) {
+				while (sdio_abort_retry--) {
+					if (sd->func[func]) {
+						sdio_claim_host(sd->func[func]);
+						/*
+						 * this sdio_f0_writeb() can be replaced with
+						 * another api depending upon MMC driver change.
+						 * As of this time, this is temporaray one
+						 */
+						sdio_writeb(sd->func[func],
+							*byte, regaddr, &err_ret);
+						sdio_release_host(sd->func[func]);
+					}
+					if (!err_ret)
+						break;
+				}
+			}
+#endif
+			else if (regaddr < 0xF0) {
+				sd_err(("bcmsdh_sdmmc: F0 Wr:0x%02x: write disallowed\n", regaddr));
+			} else {
+				/* Claim host controller, perform F0 write, and release */
+				if (sd->func[func]) {
+					sdio_claim_host(sd->func[func]);
+					sdio_f0_writeb(sd->func[func],
+						*byte, regaddr, &err_ret);
+					sdio_release_host(sd->func[func]);
+				}
+			}
+		} else {
+			/* Claim host controller, perform Fn write, and release */
+			if (sd->func[func]) {
+				sdio_claim_host(sd->func[func]);
+				sdio_writeb(sd->func[func], *byte, regaddr, &err_ret);
+				sdio_release_host(sd->func[func]);
+			}
+		}
+	} else { /* CMD52 Read */
+		/* Claim host controller, perform Fn read, and release */
+		if (sd->func[func]) {
+			sdio_claim_host(sd->func[func]);
+			if (func == 0) {
+				*byte = sdio_f0_readb(sd->func[func], regaddr, &err_ret);
+			} else {
+				*byte = sdio_readb(sd->func[func], regaddr, &err_ret);
+			}
+			sdio_release_host(sd->func[func]);
+		}
+	}
+
+	if (err_ret) {
+		if (regaddr == 0x1001F) {
+			/* XXX: Read/Write to SBSDIO_FUNC1_SLEEPCSR could return -110(timeout)
+			 * 	or -84(CRC) error in case the host tries to wake the device up.
+			 *	Skip error log message if err code is -110 or -84 when accessing
+			 *	to SBSDIO_FUNC1_SLEEPCSR to avoid QA misunderstand and DHD shoul
+			 *	print error log message if retry count over the MAX_KSO_ATTEMPTS.
+			 */
+		} else {
+			sd_err(("bcmsdh_sdmmc: Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
+				rw ? "Write" : "Read", func, regaddr, *byte, err_ret));
+		}
+	}
+
+	if (sd_msglevel & SDH_COST_VAL) {
+		uint32 diff_us;
+		osl_do_gettimeofday(&now);
+		diff_us = osl_do_gettimediff(&now, &before);
+		sd_cost(("%s: rw=%d len=1 cost = %3dms %3dus\n", __FUNCTION__,
+			rw, diff_us/1000, diff_us%1000));
+	}
+
+	return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
+}
+
+#ifdef PKT_STATICS
+uint32
+sdioh_get_spend_time(sdioh_info_t *sd)
+{
+	return (sd->sdio_spent_time_us);
+}
+#endif
+
+extern SDIOH_API_RC
+sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr,
+                                   uint32 *word, uint nbytes)
+{
+	int err_ret = SDIOH_API_RC_FAIL;
+	int err_ret2 = SDIOH_API_RC_SUCCESS; // terence 20130621: prevent dhd_dpc in dead lock
+#if defined(MMC_SDIO_ABORT)
+	int sdio_abort_retry = MMC_SDIO_ABORT_RETRY_LIMIT;
+#endif
+	struct osl_timespec now, before;
+
+	if (sd_msglevel & SDH_COST_VAL)
+		osl_do_gettimeofday(&before);
+
+	if (func == 0) {
+		sd_err(("%s: Only CMD52 allowed to F0.\n", __FUNCTION__));
+		return SDIOH_API_RC_FAIL;
+	}
+
+	sd_info(("%s: cmd_type=%d, rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
+	         __FUNCTION__, cmd_type, rw, func, addr, nbytes));
+
+	DHD_PM_RESUME_WAIT(sdioh_request_word_wait);
+	DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+	/* Claim host controller */
+	sdio_claim_host(sd->func[func]);
+
+	if(rw) { /* CMD52 Write */
+		if (nbytes == 4) {
+			sdio_writel(sd->func[func], *word, addr, &err_ret);
+		} else if (nbytes == 2) {
+			sdio_writew(sd->func[func], (*word & 0xFFFF), addr, &err_ret);
+		} else {
+			sd_err(("%s: Invalid nbytes: %d\n", __FUNCTION__, nbytes));
+		}
+	} else { /* CMD52 Read */
+		if (nbytes == 4) {
+			*word = sdio_readl(sd->func[func], addr, &err_ret);
+		} else if (nbytes == 2) {
+			*word = sdio_readw(sd->func[func], addr, &err_ret) & 0xFFFF;
+		} else {
+			sd_err(("%s: Invalid nbytes: %d\n", __FUNCTION__, nbytes));
+		}
+	}
+
+	/* Release host controller */
+	sdio_release_host(sd->func[func]);
+
+	if (err_ret) {
+#if defined(MMC_SDIO_ABORT)
+		/* Any error on CMD53 transaction should abort that function using function 0. */
+		while (sdio_abort_retry--) {
+			if (sd->func[0]) {
+				sdio_claim_host(sd->func[0]);
+				/*
+				 * this sdio_f0_writeb() can be replaced with another api
+				 * depending upon MMC driver change.
+				 * As of this time, this is temporaray one
+				 */
+				sdio_writeb(sd->func[0],
+					func, SDIOD_CCCR_IOABORT, &err_ret2);
+				sdio_release_host(sd->func[0]);
+			}
+			if (!err_ret2)
+				break;
+		}
+		if (err_ret)
+#endif /* MMC_SDIO_ABORT */
+		{
+			sd_err(("bcmsdh_sdmmc: Failed to %s word F%d:@0x%05x=%02x, Err: %d\n",
+				rw ? "Write" : "Read", func, addr, *word, err_ret));
+		}
+	}
+
+	if (sd_msglevel & SDH_COST_VAL) {
+		uint32 diff_us;
+		osl_do_gettimeofday(&now);
+		diff_us = osl_do_gettimediff(&now, &before);
+		sd_cost(("%s: rw=%d, len=%d cost = %3dms %3dus\n", __FUNCTION__,
+			rw, nbytes, diff_us/1000, diff_us%1000));
+	}
+
+	return (((err_ret == 0)&&(err_ret2 == 0)) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
+}
+
+#ifdef BCMSDIOH_TXGLOM
+static SDIOH_API_RC
+sdioh_request_packet_chain(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
+                     uint addr, void *pkt)
+{
+	bool fifo = (fix_inc == SDIOH_DATA_FIX);
+	int err_ret = 0;
+	void *pnext;
+	uint ttl_len = 0, pkt_offset;
+	uint blk_num;
+	uint blk_size;
+	uint max_blk_count;
+	uint max_req_size;
+	struct mmc_request mmc_req;
+	struct mmc_command mmc_cmd;
+	struct mmc_data mmc_dat;
+	uint32 sg_count = 0;
+	struct sdio_func *sdio_func = sd->func[func];
+	struct mmc_host *host = sdio_func->card->host;
+	uint8 *localbuf = NULL;
+	uint local_plen = 0;
+	uint pkt_len = 0;
+	struct osl_timespec now, before;
+
+	sd_trace(("%s: Enter\n", __FUNCTION__));
+	ASSERT(pkt);
+	DHD_PM_RESUME_WAIT(sdioh_request_packet_wait);
+	DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+
+#ifndef PKT_STATICS
+	if (sd_msglevel & SDH_COST_VAL)
+#endif
+		osl_do_gettimeofday(&before);
+
+	blk_size = sd->client_block_size[func];
+	max_blk_count = min(host->max_blk_count, (uint)MAX_IO_RW_EXTENDED_BLK);
+	max_req_size = min(max_blk_count * blk_size, host->max_req_size);
+
+	pkt_offset = 0;
+	pnext = pkt;
+
+	ttl_len = 0;
+	sg_count = 0;
+	if(sd->txglom_mode == SDPCM_TXGLOM_MDESC) {
+		while (pnext != NULL) {
+			ttl_len = 0;
+			sg_count = 0;
+			memset(&mmc_req, 0, sizeof(struct mmc_request));
+			memset(&mmc_cmd, 0, sizeof(struct mmc_command));
+			memset(&mmc_dat, 0, sizeof(struct mmc_data));
+			sg_init_table(sd->sg_list, ARRAYSIZE(sd->sg_list));
+
+			/* Set up scatter-gather DMA descriptors. this loop is to find out
+			 * the max data we can transfer with one command 53. blocks per command
+			 * is limited by host max_req_size and 9-bit max block number. when the
+			 * total length of this packet chain is bigger than max_req_size, use
+			 * multiple SD_IO_RW_EXTENDED commands (each transfer is still block
+			 * aligned)
+			 */
+			while (pnext != NULL && ttl_len < max_req_size) {
+				int pkt_len;
+				int sg_data_size;
+				uint8 *pdata = (uint8*)PKTDATA(sd->osh, pnext);
+
+				ASSERT(pdata != NULL);
+				pkt_len = PKTLEN(sd->osh, pnext);
+				sd_trace(("%s[%d] data=%p, len=%d\n", __FUNCTION__, write, pdata, pkt_len));
+				/* sg_count is unlikely larger than the array size,
+				 * and this is NOT something we can handle here, but in
+				 * case it happens, PLEASE put a restriction on max tx/glom
+				 * count (based on host->max_segs).
+				 */
+				if (sg_count >= ARRAYSIZE(sd->sg_list)) {
+					sd_err(("%s: sg list entries(%u) exceed limit(%zu),"
+						" sd blk_size=%u\n",
+						__FUNCTION__, sg_count, (size_t)ARRAYSIZE(sd->sg_list), blk_size));
+					return (SDIOH_API_RC_FAIL);
+				}
+				pdata += pkt_offset;
+
+				sg_data_size = pkt_len - pkt_offset;
+				if (sg_data_size > max_req_size - ttl_len)
+					sg_data_size = max_req_size - ttl_len;
+				/* some platforms put a restriction on the data size of each
+				 * scatter-gather DMA descriptor, use multiple sg buffers when
+				 * xfer_size is bigger than max_seg_size
+				 */
+				if (sg_data_size > host->max_seg_size) {
+					sg_data_size = host->max_seg_size;
+				}
+				sg_set_buf(&sd->sg_list[sg_count++], pdata, sg_data_size);
+
+				ttl_len += sg_data_size;
+				pkt_offset += sg_data_size;
+				if (pkt_offset == pkt_len) {
+					pnext = PKTNEXT(sd->osh, pnext);
+					pkt_offset = 0;
+				}
+			}
+
+			if (ttl_len % blk_size != 0) {
+				sd_err(("%s, data length %d not aligned to block size %d\n",
+					__FUNCTION__,  ttl_len, blk_size));
+				return SDIOH_API_RC_FAIL;
+			}
+			blk_num = ttl_len / blk_size;
+			mmc_dat.sg = sd->sg_list;
+			mmc_dat.sg_len = sg_count;
+			mmc_dat.blksz = blk_size;
+			mmc_dat.blocks = blk_num;
+			mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
+			mmc_cmd.opcode = 53; /* SD_IO_RW_EXTENDED */
+			mmc_cmd.arg = write ? 1<<31 : 0;
+			mmc_cmd.arg |= (func & 0x7) << 28;
+			mmc_cmd.arg |= 1<<27;
+			mmc_cmd.arg |= fifo ? 0 : 1<<26;
+			mmc_cmd.arg |= (addr & 0x1FFFF) << 9;
+			mmc_cmd.arg |= blk_num & 0x1FF;
+			mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
+			mmc_req.cmd = &mmc_cmd;
+			mmc_req.data = &mmc_dat;
+			if (!fifo)
+				addr += ttl_len;
+
+			sdio_claim_host(sdio_func);
+			mmc_set_data_timeout(&mmc_dat, sdio_func->card);
+			mmc_wait_for_req(host, &mmc_req);
+			sdio_release_host(sdio_func);
+
+			err_ret = mmc_cmd.error? mmc_cmd.error : mmc_dat.error;
+			if (0 != err_ret) {
+				sd_err(("%s:CMD53 %s failed with code %d\n",
+					__FUNCTION__, write ? "write" : "read", err_ret));
+				return SDIOH_API_RC_FAIL;
+			}
+		}
+	}
+	else if(sd->txglom_mode == SDPCM_TXGLOM_CPY) {
+		for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) {
+			ttl_len += PKTLEN(sd->osh, pnext);
+		}
+		/* Claim host controller */
+		sdio_claim_host(sd->func[func]);
+		for (pnext = pkt; pnext; pnext = PKTNEXT(sd->osh, pnext)) {
+			uint8 *buf = (uint8*)PKTDATA(sd->osh, pnext);
+			pkt_len = PKTLEN(sd->osh, pnext);
+			if (!localbuf) {
+#ifdef BCMSDIOH_STATIC_COPY_BUF
+				if (ttl_len <= COPY_BUF_SIZE)
+					localbuf = sd->copy_buf;
+#else
+				localbuf = (uint8 *)MALLOC(sd->osh, ttl_len);
+#endif
+				if (localbuf == NULL) {
+					sd_err(("%s: %s localbuf malloc FAILED ttl_len=%d\n",
+						__FUNCTION__, (write) ? "TX" : "RX", ttl_len));
+					ttl_len -= pkt_len;
+					goto txglomfail;
+				}
+			}
+			bcopy(buf, (localbuf + local_plen), pkt_len);
+			local_plen += pkt_len;
+			if (PKTNEXT(sd->osh, pnext))
+				continue;
+
+			buf = localbuf;
+			pkt_len = local_plen;
+txglomfail:
+			/* Align Patch */
+			if (!write || pkt_len < 32)
+				pkt_len = (pkt_len + 3) & 0xFFFFFFFC;
+			else if (pkt_len % blk_size)
+				pkt_len += blk_size - (pkt_len % blk_size);
+
+			if ((write) && (!fifo))
+				err_ret = sdio_memcpy_toio(sd->func[func], addr, buf, pkt_len);
+			else if (write)
+				err_ret = sdio_memcpy_toio(sd->func[func], addr, buf, pkt_len);
+			else if (fifo)
+				err_ret = sdio_readsb(sd->func[func], buf, addr, pkt_len);
+			else
+				err_ret = sdio_memcpy_fromio(sd->func[func], buf, addr, pkt_len);
+
+			if (err_ret)
+				sd_err(("%s: %s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=%d\n",
+				       __FUNCTION__,
+				       (write) ? "TX" : "RX",
+				       pnext, sg_count, addr, pkt_len, err_ret));
+			else
+				sd_trace(("%s: %s xfr'd %p[%d], addr=0x%05x, len=%d\n",
+					__FUNCTION__,
+					(write) ? "TX" : "RX",
+					pnext, sg_count, addr, pkt_len));
+
+			if (!fifo)
+				addr += pkt_len;
+			sg_count ++;
+		}
+		sdio_release_host(sd->func[func]);
+	} else {
+		sd_err(("%s: set to wrong glom mode %d\n", __FUNCTION__, sd->txglom_mode));
+		return SDIOH_API_RC_FAIL;
+	}
+
+#ifndef BCMSDIOH_STATIC_COPY_BUF
+	if (localbuf)
+		MFREE(sd->osh, localbuf, ttl_len);
+#endif
+
+#ifndef PKT_STATICS
+	if (sd_msglevel & SDH_COST_VAL)
+#endif
+	{
+		uint32 diff_us;
+		osl_do_gettimeofday(&now);
+		diff_us = osl_do_gettimediff(&now, &before);
+		sd_cost(("%s: rw=%d, ttl_len=%4d cost = %3dms %3dus\n", __FUNCTION__,
+			write, ttl_len, diff_us/1000, diff_us%1000));
+#ifdef PKT_STATICS
+		if (write && (func == 2))
+			sd->sdio_spent_time_us = diff_us;
+#endif
+	}
+
+	sd_trace(("%s: Exit\n", __FUNCTION__));
+	return SDIOH_API_RC_SUCCESS;
+}
+#endif /* BCMSDIOH_TXGLOM */
+
+static SDIOH_API_RC
+sdioh_buffer_tofrom_bus(sdioh_info_t *sd, uint fix_inc, uint write, uint func,
+                     uint addr, uint8 *buf, uint len)
+{
+	bool fifo = (fix_inc == SDIOH_DATA_FIX);
+	int err_ret = 0;
+	struct osl_timespec now, before;
+
+	sd_trace(("%s: Enter\n", __FUNCTION__));
+	ASSERT(buf);
+
+	if (sd_msglevel & SDH_COST_VAL)
+		osl_do_gettimeofday(&before);
+
+	/* NOTE:
+	 * For all writes, each packet length is aligned to 32 (or 4)
+	 * bytes in dhdsdio_txpkt_preprocess, and for glom the last packet length
+	 * is aligned to block boundary. If you want to align each packet to
+	 * a custom size, please do it in dhdsdio_txpkt_preprocess, NOT here
+	 *
+	 * For reads, the alignment is doen in sdioh_request_buffer.
+	 *
+	 */
+	sdio_claim_host(sd->func[func]);
+
+	if ((write) && (!fifo))
+		err_ret = sdio_memcpy_toio(sd->func[func], addr, buf, len);
+	else if (write)
+		err_ret = sdio_memcpy_toio(sd->func[func], addr, buf, len);
+	else if (fifo)
+		err_ret = sdio_readsb(sd->func[func], buf, addr, len);
+	else
+		err_ret = sdio_memcpy_fromio(sd->func[func], buf, addr, len);
+
+	sdio_release_host(sd->func[func]);
+
+	if (err_ret)
+		sd_err(("%s: %s FAILED %p, addr=0x%05x, pkt_len=%d, ERR=%d\n", __FUNCTION__,
+		       (write) ? "TX" : "RX", buf, addr, len, err_ret));
+	else
+		sd_trace(("%s: %s xfr'd %p, addr=0x%05x, len=%d\n", __FUNCTION__,
+			(write) ? "TX" : "RX", buf, addr, len));
+
+	sd_trace(("%s: Exit\n", __FUNCTION__));
+
+	if (sd_msglevel & SDH_COST_VAL) {
+		uint32 diff_us;
+		osl_do_gettimeofday(&now);
+		diff_us = osl_do_gettimediff(&now, &before);
+		sd_cost(("%s: rw=%d, len=%4d cost = %3dms %3dus\n", __FUNCTION__,
+			write, len, diff_us/1000, diff_us%1000));
+	}
+
+	return ((err_ret == 0) ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
+}
+
+/*
+ * This function takes a buffer or packet, and fixes everything up so that in the
+ * end, a DMA-able packet is created.
+ *
+ * A buffer does not have an associated packet pointer, and may or may not be aligned.
+ * A packet may consist of a single packet, or a packet chain.  If it is a packet chain,
+ * then all the packets in the chain must be properly aligned.  If the packet data is not
+ * aligned, then there may only be one packet, and in this case, it is copied to a new
+ * aligned packet.
+ *
+ */
+extern SDIOH_API_RC
+sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, uint func,
+	uint addr, uint reg_width, uint buf_len, uint8 *buffer, void *pkt)
+{
+	SDIOH_API_RC status;
+	void *tmppkt;
+	int is_vmalloc = FALSE;
+	struct osl_timespec now, before;
+
+	sd_trace(("%s: Enter\n", __FUNCTION__));
+	DHD_PM_RESUME_WAIT(sdioh_request_buffer_wait);
+	DHD_PM_RESUME_RETURN_ERROR(SDIOH_API_RC_FAIL);
+
+	if (sd_msglevel & SDH_COST_VAL)
+		osl_do_gettimeofday(&before);
+
+	if (pkt) {
+#ifdef BCMSDIOH_TXGLOM
+		/* packet chain, only used for tx/rx glom, all packets length
+		 * are aligned, total length is a block multiple
+		 */
+		if (PKTNEXT(sd->osh, pkt))
+			return sdioh_request_packet_chain(sd, fix_inc, write, func, addr, pkt);
+#endif /* BCMSDIOH_TXGLOM */
+		/* non-glom mode, ignore the buffer parameter and use the packet pointer
+		 * (this shouldn't happen)
+		 */
+		buffer = PKTDATA(sd->osh, pkt);
+		buf_len = PKTLEN(sd->osh, pkt);
+	}
+
+	ASSERT(buffer);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 24)
+	is_vmalloc = is_vmalloc_addr(buffer);
+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 24) */
+
+	/* buffer and length are aligned, use it directly so we can avoid memory copy */
+	if ((((ulong)buffer & DMA_ALIGN_MASK) == 0) && ((buf_len & DMA_ALIGN_MASK) == 0) &&
+			(!is_vmalloc)) {
+		return sdioh_buffer_tofrom_bus(sd, fix_inc, write, func, addr, buffer, buf_len);
+	}
+
+	if (is_vmalloc) {
+		sd_trace(("%s: Need to memory copy due to virtual memory address.\n",
+			__FUNCTION__));
+	}
+
+	sd_trace(("%s: [%d] doing memory copy buf=%p, len=%d\n",
+		__FUNCTION__, write, buffer, buf_len));
+
+	/* otherwise, a memory copy is needed as the input buffer is not aligned */
+	tmppkt = PKTGET_STATIC(sd->osh, buf_len + DEFAULT_SDIO_F2_BLKSIZE, write ? TRUE : FALSE);
+	if (tmppkt == NULL) {
+		sd_err(("%s: PKTGET failed: len %d\n", __FUNCTION__, buf_len));
+		return SDIOH_API_RC_FAIL;
+	}
+
+	if (write)
+		bcopy(buffer, PKTDATA(sd->osh, tmppkt), buf_len);
+
+	status = sdioh_buffer_tofrom_bus(sd, fix_inc, write, func, addr,
+		PKTDATA(sd->osh, tmppkt), ROUNDUP(buf_len, (DMA_ALIGN_MASK+1)));
+
+	if (!write)
+		bcopy(PKTDATA(sd->osh, tmppkt), buffer, buf_len);
+
+	PKTFREE_STATIC(sd->osh, tmppkt, write ? TRUE : FALSE);
+
+	if (sd_msglevel & SDH_COST_VAL) {
+		uint32 diff_us;
+		osl_do_gettimeofday(&now);
+		diff_us = osl_do_gettimediff(&now, &before);
+		sd_cost(("%s: rw=%d, len=%d cost = %3dms %3dus\n", __FUNCTION__,
+			write, buf_len, diff_us/1000, diff_us%1000));
+	}
+
+	return status;
+}
+
+/* this function performs "abort" for both of host & device */
+extern int
+sdioh_abort(sdioh_info_t *sd, uint func)
+{
+#if defined(MMC_SDIO_ABORT)
+	char t_func = (char) func;
+#endif /* defined(MMC_SDIO_ABORT) */
+	sd_trace(("%s: Enter\n", __FUNCTION__));
+
+	/* XXX Standard Linux SDIO Stack cannot perform an abort. */
+#if defined(MMC_SDIO_ABORT)
+	/* issue abort cmd52 command through F1 */
+	sdioh_request_byte(sd, SD_IO_OP_WRITE, SDIO_FUNC_0, SDIOD_CCCR_IOABORT, &t_func);
+#endif /* defined(MMC_SDIO_ABORT) */
+
+	sd_trace(("%s: Exit\n", __FUNCTION__));
+	return SDIOH_API_RC_SUCCESS;
+}
+
+/* Reset and re-initialize the device */
+int sdioh_sdio_reset(sdioh_info_t *si)
+{
+	sd_trace(("%s: Enter\n", __FUNCTION__));
+	sd_trace(("%s: Exit\n", __FUNCTION__));
+	return SDIOH_API_RC_SUCCESS;
+}
+
+/* Disable device interrupt */
+void
+sdioh_sdmmc_devintr_off(sdioh_info_t *sd)
+{
+	sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints));
+	sd->intmask &= ~CLIENT_INTR;
+}
+
+/* Enable device interrupt */
+void
+sdioh_sdmmc_devintr_on(sdioh_info_t *sd)
+{
+	sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints));
+	sd->intmask |= CLIENT_INTR;
+}
+
+/* Read client card reg */
+int
+sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data)
+{
+
+	if ((func == 0) || (regsize == 1)) {
+		uint8 temp = 0;
+
+		sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp);
+		*data = temp;
+		*data &= 0xff;
+		sd_data(("%s: byte read data=0x%02x\n",
+		         __FUNCTION__, *data));
+	} else {
+		if (sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, data, regsize)) {
+			return BCME_SDIO_ERROR;
+		}
+		if (regsize == 2)
+			*data &= 0xffff;
+
+		sd_data(("%s: word read data=0x%08x\n",
+		         __FUNCTION__, *data));
+	}
+
+	return SUCCESS;
+}
+
+#if !defined(OOB_INTR_ONLY)
+void sdio_claim_host_lock_local(sdioh_info_t *sd) // terence 20140926: fix for claim host issue
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+	if (sd)
+		mutex_lock(&sd->claim_host_mutex);
+#endif
+}
+
+void sdio_claim_host_unlock_local(sdioh_info_t *sd) // terence 20140926: fix for claim host issue
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+	if (sd)
+		mutex_unlock(&sd->claim_host_mutex);
+#endif
+}
+
+/* bcmsdh_sdmmc interrupt handler */
+static void IRQHandler(struct sdio_func *func)
+{
+	sdioh_info_t *sd;
+
+	sd = sdio_get_drvdata(func);
+
+	ASSERT(sd != NULL);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+	if (mutex_is_locked(&sd->claim_host_mutex)) {
+		printf("%s: muxtex is locked and return\n", __FUNCTION__);
+		return;
+	}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
+
+	sdio_claim_host_lock_local(sd);
+	sdio_release_host(sd->func[0]);
+
+	if (sd->use_client_ints) {
+		sd->intrcount++;
+		ASSERT(sd->intr_handler);
+		ASSERT(sd->intr_handler_arg);
+		(sd->intr_handler)(sd->intr_handler_arg);
+	} else { /* XXX - Do not remove these sd_err messages.  Need to figure
+			          out how to keep interrupts disabled until DHD registers
+			          a handler.
+			  */
+		sd_err(("bcmsdh_sdmmc: ***IRQHandler\n"));
+
+		sd_err(("%s: Not ready for intr: enabled %d, handler %p\n",
+		        __FUNCTION__, sd->client_intr_enabled, sd->intr_handler));
+	}
+
+	sdio_claim_host(sd->func[0]);
+	sdio_claim_host_unlock_local(sd);
+}
+
+/* bcmsdh_sdmmc interrupt handler for F2 (dummy handler) */
+static void IRQHandlerF2(struct sdio_func *func)
+{
+	sd_trace(("bcmsdh_sdmmc: ***IRQHandlerF2\n"));
+}
+#endif /* !defined(OOB_INTR_ONLY) */
+
+#ifdef NOTUSED
+/* Write client card reg */
+static int
+sdioh_sdmmc_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data)
+{
+
+	if ((func == 0) || (regsize == 1)) {
+		uint8 temp;
+
+		temp = data & 0xff;
+		sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp);
+		sd_data(("%s: byte write data=0x%02x\n",
+		         __FUNCTION__, data));
+	} else {
+		if (regsize == 2)
+			data &= 0xffff;
+
+		sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, &data, regsize);
+
+		sd_data(("%s: word write data=0x%08x\n",
+		         __FUNCTION__, data));
+	}
+
+	return SUCCESS;
+}
+#endif /* NOTUSED */
+
+#if defined(ENABLE_INSMOD_NO_FW_LOAD)
+static int sdio_sw_reset(sdioh_info_t *sd)
+{
+	struct mmc_card *card = sd->func[0]->card;
+	int err = 0;
+
+#if defined(MMC_SW_RESET) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0)
+	/* MMC_SW_RESET */
+	printf("%s: call mmc_sw_reset\n", __FUNCTION__);
+	sdio_claim_host(sd->func[0]);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+	err = mmc_sw_reset(card);
+#else
+	err = mmc_sw_reset(card->host);
+#endif
+	sdio_release_host(sd->func[0]);
+#elif defined(MMC_HW_RESET) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)
+	/* MMC_HW_RESET */
+	printf("%s: call mmc_hw_reset\n", __FUNCTION__);
+	sdio_claim_host(sd->func[0]);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
+	while (atomic_read(&card->sdio_funcs_probed) > 1) {
+		atomic_dec(&card->sdio_funcs_probed);
+	}
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
+	err = mmc_hw_reset(card);
+#else
+	err = mmc_hw_reset(card->host);
+#endif
+	sdio_release_host(sd->func[0]);
+#elif defined(BUS_POWER_RESTORE) && \
+LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
+	printf("%s: call mmc_power_restore_host\n", __FUNCTION__);
+	mmc_power_restore_host(card->host);
+#else
+	/* sdio_reset_comm */
+	printf("%s: call sdio_reset_comm\n", __FUNCTION__);
+	err = sdio_reset_comm(card);
+#endif
+
+	if (err)
+		sd_err(("%s Failed, error = %d\n", __FUNCTION__, err));
+
+	return err;
+}
+#endif
+
+int
+sdioh_start(sdioh_info_t *sd, int stage)
+{
+#if defined(OEM_ANDROID)
+	int ret = 0;
+
+	if (!sd) {
+		sd_err(("%s Failed, sd is NULL\n", __FUNCTION__));
+		return (0);
+	}
+
+	/* Need to do this stages as we can't enable the interrupt till
+		downloading of the firmware is complete, other wise polling
+		sdio access will come in way
+	*/
+	if (sd->func[0]) {
+		if (stage == 0) {
+			/* Since the power to the chip is killed, we will have
+			   re enumerate the device again. Set the block size
+			   and enable the fucntion 1 for in preparation for
+			   downloading the code
+			*/
+			/* sdio_reset_comm() - has been fixed in latest kernel/msm.git for Linux
+			   2.6.27. The implementation prior to that is buggy, and needs broadcom's
+			   patch for it
+			*/
+#if defined(ENABLE_INSMOD_NO_FW_LOAD)
+			if ((ret = sdio_sw_reset(sd))) {
+				sd_err(("%s Failed, error = %d\n", __FUNCTION__, ret));
+				return ret;
+			} else
+#endif
+			{
+				sd->num_funcs = 2;
+				sd->sd_blockmode = TRUE;
+				sd->use_client_ints = TRUE;
+				sd->client_block_size[0] = 64;
+
+				if (sd->func[1]) {
+					/* Claim host controller */
+					sdio_claim_host(sd->func[1]);
+
+					sd->client_block_size[1] = 64;
+					ret = sdio_set_block_size(sd->func[1], 64);
+					if (ret) {
+						sd_err(("bcmsdh_sdmmc: Failed to set F1 "
+							"blocksize(%d)\n", ret));
+					}
+
+					/* Release host controller F1 */
+					sdio_release_host(sd->func[1]);
+				}
+
+				if (sd->func[2]) {
+					/* Claim host controller F2 */
+					sdio_claim_host(sd->func[2]);
+
+					sd->client_block_size[2] = sd_f2_blocksize;
+					printf("%s: set sd_f2_blocksize %d\n", __FUNCTION__, sd_f2_blocksize);
+					ret = sdio_set_block_size(sd->func[2], sd_f2_blocksize);
+					if (ret) {
+						sd_err(("bcmsdh_sdmmc: Failed to set F2 blocksize"
+							" to %d(%d)\n", sd_f2_blocksize, ret));
+					}
+
+					/* Release host controller F2 */
+					sdio_release_host(sd->func[2]);
+				}
+
+				sdioh_sdmmc_card_enablefuncs(sd);
+			}
+		} else {
+#if !defined(OOB_INTR_ONLY)
+			sdio_claim_host(sd->func[0]);
+			if (sd->func[2])
+				sdio_claim_irq(sd->func[2], IRQHandlerF2);
+			if (sd->func[1])
+				sdio_claim_irq(sd->func[1], IRQHandler);
+			sdio_release_host(sd->func[0]);
+#else /* defined(OOB_INTR_ONLY) */
+#if defined(HW_OOB)
+			sdioh_enable_func_intr(sd);
+#endif
+			bcmsdh_oob_intr_set(sd->bcmsdh, TRUE);
+#endif /* !defined(OOB_INTR_ONLY) */
+		}
+	} else
+		sd_err(("%s Failed\n", __FUNCTION__));
+#endif /* defined(OEM_ANDROID) */
+
+	return (ret);
+}
+
+int
+sdioh_stop(sdioh_info_t *sd)
+{
+#if defined(OEM_ANDROID)
+	/* MSM7201A Android sdio stack has bug with interrupt
+		So internaly within SDIO stack they are polling
+		which cause issue when device is turned off. So
+		unregister interrupt with SDIO stack to stop the
+		polling
+	*/
+#if !defined(OOB_INTR_ONLY)
+	sdio_claim_host_lock_local(sd);
+#endif
+	if (sd->func[0]) {
+#if !defined(OOB_INTR_ONLY)
+		sdio_claim_host(sd->func[0]);
+		if (sd->func[1])
+			sdio_release_irq(sd->func[1]);
+		if (sd->func[2])
+			sdio_release_irq(sd->func[2]);
+		sdio_release_host(sd->func[0]);
+#else /* defined(OOB_INTR_ONLY) */
+#if defined(HW_OOB)
+		sdioh_disable_func_intr(sd);
+#endif
+		bcmsdh_oob_intr_set(sd->bcmsdh, FALSE);
+#endif /* !defined(OOB_INTR_ONLY) */
+	}
+	else
+		sd_err(("%s Failed\n", __FUNCTION__));
+#if !defined(MMC_SW_RESET) && !defined(MMC_HW_RESET)
+#if defined(BUS_POWER_RESTORE) && \
+LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0)
+	if (sd->func[0]) {
+		struct mmc_card *card = sd->func[0]->card;
+		printf("%s: call mmc_power_save_host\n", __FUNCTION__);
+		mmc_power_save_host(card->host);
+	}
+#endif
+#endif
+#if !defined(OOB_INTR_ONLY)
+	sdio_claim_host_unlock_local(sd);
+#endif
+#endif /* defined(OEM_ANDROID) */
+	return (0);
+}
+
+int
+sdioh_waitlockfree(sdioh_info_t *sd)
+{
+	return (1);
+}
+
+SDIOH_API_RC
+sdioh_gpioouten(sdioh_info_t *sd, uint32 gpio)
+{
+	return SDIOH_API_RC_FAIL;
+}
+
+SDIOH_API_RC
+sdioh_gpioout(sdioh_info_t *sd, uint32 gpio, bool enab)
+{
+	return SDIOH_API_RC_FAIL;
+}
+
+bool
+sdioh_gpioin(sdioh_info_t *sd, uint32 gpio)
+{
+	return FALSE;
+}
+
+SDIOH_API_RC
+sdioh_gpio_init(sdioh_info_t *sd)
+{
+	return SDIOH_API_RC_FAIL;
+}
+
+uint8
+sdmmc_get_timing(sdioh_info_t *sd)
+{
+	struct sdio_func *sdio_func = sd->func[0];
+	struct mmc_host *host = sdio_func->card->host;
+	return host->ios.timing;
+}
+
+void
+sdmmc_set_timing(sdioh_info_t *sd, uint8 timing)
+{
+	struct sdio_func *sdio_func = sd->func[0];
+	struct mmc_host *host = sdio_func->card->host;
+	struct mmc_ios *ios = &host->ios;
+
+	mmc_host_clk_hold(host);
+	DHD_INFO(("%s: Before change: sd current timing is %u\n", __FUNCTION__, ios->timing));
+	ios->timing = timing;
+	host->ops->set_ios(host, ios);
+	DHD_ERROR(("%s: After change: sd timing is %u\n", __FUNCTION__, ios->timing));
+	mmc_host_clk_release(host);
+}
+
+uint
+sdmmc_get_clock_rate(sdioh_info_t *sd)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+	struct sdio_func *sdio_func = sd->func[0];
+	struct mmc_host *host = sdio_func->card->host;
+	return mmc_host_clk_rate(host);
+#else
+	return 0;
+#endif
+}
+
+void
+sdmmc_set_clock_rate(sdioh_info_t *sd, uint hz)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
+	struct sdio_func *sdio_func = sd->func[0];
+	struct mmc_host *host = sdio_func->card->host;
+	struct mmc_ios *ios = &host->ios;
+
+	mmc_host_clk_hold(host);
+	DHD_INFO(("%s: Before change: sd clock rate is %u\n", __FUNCTION__, ios->clock));
+	if (hz < host->f_min) {
+		DHD_ERROR(("%s: Intended rate is below min rate, setting to min\n", __FUNCTION__));
+		hz = host->f_min;
+	}
+
+	if (hz > host->f_max) {
+		DHD_ERROR(("%s: Intended rate exceeds max rate, setting to max\n", __FUNCTION__));
+		hz = host->f_max;
+	}
+	ios->clock = hz;
+	host->ops->set_ios(host, ios);
+	DHD_ERROR(("%s: After change: sd clock rate is %u\n", __FUNCTION__, ios->clock));
+	mmc_host_clk_release(host);
+#else
+	return;
+#endif
+}
+
+void
+sdmmc_set_clock_divisor(sdioh_info_t *sd, uint sd_div)
+{
+	uint hz;
+	uint old_div = sdmmc_get_clock_rate(sd);
+	if (old_div == sd_div) {
+		return;
+	}
+
+	hz = sd->sd_clk_rate / sd_div;
+	sdmmc_set_clock_rate(sd, hz);
+}
+
+uint
+sdioh_set_mode(sdioh_info_t *sd, uint mode)
+{
+	if (mode == SDPCM_TXGLOM_CPY)
+		sd->txglom_mode = mode;
+	else if (mode == SDPCM_TXGLOM_MDESC)
+		sd->txglom_mode = mode;
+
+	return (sd->txglom_mode);
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
@@ -0,0 +1,484 @@
+/*
+ * BCMSDH Function Driver for the native SDIO/MMC driver in the Linux Kernel
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <typedefs.h>
+#include <bcmutils.h>
+#include <sdio.h>	/* SDIO Device and Protocol Specs */
+#include <bcmsdbus.h>	/* bcmsdh to/from specific controller APIs */
+#include <sdiovar.h>	/* to get msglevel bit values */
+
+#include <linux/sched.h>	/* request_irq() */
+
+#include <linux/mmc/core.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <dhd_linux.h>
+#include <bcmsdh_sdmmc.h>
+#include <dhd_dbg.h>
+#include <bcmdevs.h>
+
+#if !defined(SDIO_VENDOR_ID_BROADCOM)
+#define SDIO_VENDOR_ID_BROADCOM		0x02d0
+#endif /* !defined(SDIO_VENDOR_ID_BROADCOM) */
+
+#if !defined(SDIO_VENDOR_ID_SYNAPTICS)
+#define SDIO_VENDOR_ID_SYNAPTICS	0x06cb
+#endif /* !defined(SDIO_VENDOR_ID_SYNAPTICS) */
+
+#define SDIO_DEVICE_ID_BROADCOM_DEFAULT	0x0000
+
+extern void wl_cfg80211_set_parent_dev(void *dev);
+extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd);
+extern void sdioh_sdmmc_devintr_on(sdioh_info_t *sd);
+extern void* bcmsdh_probe(osl_t *osh, void *dev, void *sdioh, void *adapter_info, uint bus_type,
+	uint bus_num, uint slot_num);
+extern int bcmsdh_remove(bcmsdh_info_t *bcmsdh);
+
+int sdio_function_init(void);
+void sdio_function_cleanup(void);
+
+#define DESCRIPTION "bcmsdh_sdmmc Driver"
+#define AUTHOR "Broadcom Corporation"
+
+/* module param defaults */
+static int clockoverride = 0;
+
+module_param(clockoverride, int, 0644);
+MODULE_PARM_DESC(clockoverride, "SDIO card clock override");
+
+#ifdef GLOBAL_SDMMC_INSTANCE
+PBCMSDH_SDMMC_INSTANCE gInstance;
+#endif
+
+/* Maximum number of bcmsdh_sdmmc devices supported by driver */
+#define BCMSDH_SDMMC_MAX_DEVICES 1
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM_SLEEP)
+extern volatile bool dhd_mmc_suspend;
+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM_SLEEP) */
+
+static int sdioh_probe(struct sdio_func *func)
+{
+	int host_idx = func->card->host->index;
+	uint32 rca = func->card->rca;
+	wifi_adapter_info_t *adapter;
+	osl_t *osh = NULL;
+	sdioh_info_t *sdioh = NULL;
+
+	sd_err(("bus num (host idx)=%d, slot num (rca)=%d, caps=0x%x\n",
+		host_idx, rca, func->card->host->caps));
+	adapter = dhd_wifi_platform_get_adapter(SDIO_BUS, host_idx, rca);
+	if (adapter != NULL) {
+		sd_err(("found adapter info '%s'\n", adapter->name));
+		adapter->bus_type = SDIO_BUS;
+		adapter->bus_num = host_idx;
+		adapter->slot_num = rca;
+		adapter->sdio_func = func;
+	} else {
+		sd_err(("can't find adapter info for this chip\n"));
+#ifdef ADAPTER_IDX
+		goto fail;
+#endif
+	}
+
+#ifdef WL_CFG80211
+	wl_cfg80211_set_parent_dev(&func->dev);
+#endif
+
+	/* allocate SDIO Host Controller state info */
+	osh = osl_attach(&func->dev, SDIO_BUS, TRUE);
+	if (osh == NULL) {
+		sd_err(("%s: osl_attach failed\n", __FUNCTION__));
+		goto fail;
+	}
+	osl_static_mem_init(osh, adapter);
+	sdioh = sdioh_attach(osh, func);
+	if (sdioh == NULL) {
+		sd_err(("%s: sdioh_attach failed\n", __FUNCTION__));
+		goto fail;
+	}
+	if (!(func->card->host->caps & MMC_CAP_NONREMOVABLE)) {
+		sd_err(("%s: MMC_CAP_NONREMOVABLE not enabled in SDIO driver\n", __FUNCTION__));
+//		func->card->host->caps |= MMC_CAP_NONREMOVABLE;
+	}
+	if ((func->card->host->caps & MMC_CAP_NEEDS_POLL)) {
+		sd_err(("%s: MMC_CAP_NEEDS_POLL enabled in SDIO driver\n", __FUNCTION__));
+//		func->card->host->caps &= ~MMC_CAP_NEEDS_POLL;
+	}
+	sdioh->bcmsdh = bcmsdh_probe(osh, &func->dev, sdioh, adapter, SDIO_BUS, host_idx, rca);
+	if (sdioh->bcmsdh == NULL) {
+		sd_err(("%s: bcmsdh_probe failed\n", __FUNCTION__));
+		goto fail;
+	}
+
+	sdio_set_drvdata(func, sdioh);
+	return 0;
+
+fail:
+	if (sdioh != NULL)
+		sdioh_detach(osh, sdioh);
+	if (osh != NULL)
+		osl_detach(osh);
+	return -ENOMEM;
+}
+
+static void sdioh_remove(struct sdio_func *func)
+{
+	sdioh_info_t *sdioh;
+	osl_t *osh;
+
+	sdioh = sdio_get_drvdata(func);
+	if (sdioh == NULL) {
+		sd_err(("%s: error, no sdioh handler found\n", __FUNCTION__));
+		return;
+	}
+	sd_err(("%s: Enter\n", __FUNCTION__));
+
+	osh = sdioh->osh;
+	bcmsdh_remove(sdioh->bcmsdh);
+	sdioh_detach(osh, sdioh);
+	osl_detach(osh);
+}
+
+static int bcmsdh_sdmmc_probe(struct sdio_func *func,
+                              const struct sdio_device_id *id)
+{
+	int ret = 0;
+
+	if (func == NULL)
+		return -EINVAL;
+
+	sd_err(("%s: Enter num=%d\n", __FUNCTION__, func->num));
+	sd_info(("sdio_bcmsdh: func->class=%x\n", func->class));
+	sd_info(("sdio_vendor: 0x%04x\n", func->vendor));
+	sd_info(("sdio_device: 0x%04x\n", func->device));
+	sd_info(("Function#: 0x%04x\n", func->num));
+
+#ifdef GLOBAL_SDMMC_INSTANCE
+	gInstance->func[func->num] = func;
+#endif
+
+	/* 4318 doesn't have function 2 */
+	if ((func->num == 2) || (func->num == 1 && func->device == 0x4))
+		ret = sdioh_probe(func);
+
+	return ret;
+}
+
+static void bcmsdh_sdmmc_remove(struct sdio_func *func)
+{
+	if (func == NULL) {
+		sd_err(("%s is called with NULL SDIO function pointer\n", __FUNCTION__));
+		return;
+	}
+
+	sd_trace(("bcmsdh_sdmmc: %s Enter\n", __FUNCTION__));
+	sd_info(("sdio_bcmsdh: func->class=%x\n", func->class));
+	sd_info(("sdio_vendor: 0x%04x\n", func->vendor));
+	sd_info(("sdio_device: 0x%04x\n", func->device));
+	sd_info(("Function#: 0x%04x\n", func->num));
+
+	if ((func->num == 2) || (func->num == 1 && func->device == 0x4))
+		sdioh_remove(func);
+}
+
+/* devices we support, null terminated */
+static const struct sdio_device_id bcmsdh_sdmmc_ids[] = {
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_DEFAULT) },
+	/* XXX This should not be in the external release, as it will attach to any SDIO
+	 * device, even non-WLAN devices.
+	 * Need to add IDs for the FALCON-based chips and put this under BCMINTERNAL
+	 { SDIO_DEVICE_CLASS(SDIO_CLASS_NONE) },
+	 */
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM4362_CHIP_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43751_CHIP_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43752_CHIP_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43756_CHIP_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43012_CHIP_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43014_CHIP_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43014_D11N_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43014_D11N2G_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43014_D11N5G_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43013_CHIP_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43013_D11N_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43013_D11N2G_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM43013_D11N5G_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_ANY_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM4381_CHIP_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, BCM4382_CHIP_ID) },
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_SYNAPTICS, BCM43711_CHIP_ID) },
+	{ SDIO_DEVICE_CLASS(SDIO_CLASS_NONE)		},
+	{ 0, 0, 0, 0 /* end: all zeroes */
+	},
+};
+
+MODULE_DEVICE_TABLE(sdio, bcmsdh_sdmmc_ids);
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM_SLEEP)
+static int bcmsdh_sdmmc_suspend(struct device *pdev)
+{
+	int err;
+	sdioh_info_t *sdioh;
+	struct sdio_func *func = dev_to_sdio_func(pdev);
+	mmc_pm_flag_t sdio_flags;
+
+	printf("%s Enter func->num=%d\n", __FUNCTION__, func->num);
+	if (func->num != 2)
+		return 0;
+
+	dhd_mmc_suspend = TRUE;
+	sdioh = sdio_get_drvdata(func);
+	err = bcmsdh_suspend(sdioh->bcmsdh);
+	if (err) {
+		printf("%s bcmsdh_suspend err=%d\n", __FUNCTION__, err);
+		dhd_mmc_suspend = FALSE;
+		return err;
+	}
+
+	sdio_flags = sdio_get_host_pm_caps(func);
+	if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
+		sd_err(("%s: can't keep power while host is suspended\n", __FUNCTION__));
+		dhd_mmc_suspend = FALSE;
+		return  -EINVAL;
+	}
+
+	/* keep power while host suspended */
+	err = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+	if (err) {
+		sd_err(("%s: error while trying to keep power\n", __FUNCTION__));
+		dhd_mmc_suspend = FALSE;
+		return err;
+	}
+	smp_mb();
+
+	printf("%s Exit\n", __FUNCTION__);
+	return 0;
+}
+
+static int bcmsdh_sdmmc_resume(struct device *pdev)
+{
+	sdioh_info_t *sdioh;
+	struct sdio_func *func = dev_to_sdio_func(pdev);
+
+	printf("%s Enter func->num=%d\n", __FUNCTION__, func->num);
+	if (func->num != 2)
+		return 0;
+
+	dhd_mmc_suspend = FALSE;
+	sdioh = sdio_get_drvdata(func);
+	bcmsdh_resume(sdioh->bcmsdh);
+
+	smp_mb();
+	printf("%s Exit\n", __FUNCTION__);
+	return 0;
+}
+
+#ifdef DEVICE_PM_CALLBACK
+static int bcmsdh_sdmmc_prepare(struct device *pdev)
+{
+	int err;
+	sdioh_info_t *sdioh;
+	struct sdio_func *func = dev_to_sdio_func(pdev);
+
+	printf("%s Enter func->num=%d\n", __FUNCTION__, func->num);
+	if (func->num != 2)
+		return 0;
+
+	sdioh = sdio_get_drvdata(func);
+	err = bcmsdh_prepare(sdioh->bcmsdh);
+	if (err) {
+		printf("%s bcmsdh_suspend err=%d\n", __FUNCTION__, err);
+		return err;
+	}
+
+	printf("%s Exit\n", __FUNCTION__);
+	return 0;
+}
+
+static void bcmsdh_sdmmc_complete(struct device *pdev)
+{
+	sdioh_info_t *sdioh;
+	struct sdio_func *func = dev_to_sdio_func(pdev);
+
+	printf("%s Enter func->num=%d\n", __FUNCTION__, func->num);
+	if (func->num != 2)
+		return;
+
+	sdioh = sdio_get_drvdata(func);
+	bcmsdh_complete(sdioh->bcmsdh);
+
+	printf("%s Exit\n", __FUNCTION__);
+	return;
+}
+#endif /* DEVICE_PM_CALLBACK */
+
+static const struct dev_pm_ops bcmsdh_sdmmc_pm_ops = {
+	.suspend	= bcmsdh_sdmmc_suspend,
+	.resume		= bcmsdh_sdmmc_resume,
+#ifdef DEVICE_PM_CALLBACK
+	.prepare	= bcmsdh_sdmmc_prepare,
+	.complete	= bcmsdh_sdmmc_complete,
+#endif /* DEVICE_PM_CALLBACK */
+};
+#endif  /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM_SLEEP) */
+
+#if defined(BCMLXSDMMC)
+static struct semaphore *notify_semaphore = NULL;
+
+static int dummy_probe(struct sdio_func *func,
+                              const struct sdio_device_id *id)
+{
+	if (func)
+		sd_err(("%s: func->num=0x%x; \n", __FUNCTION__, func->num));
+	if (id) {
+		if ((id->vendor != SDIO_VENDOR_ID_BROADCOM) &&
+			(id->vendor != SDIO_VENDOR_ID_SYNAPTICS)) {
+				sd_err(("%s: class=0x%x; vendor=0x%x; device=0x%x\n", __FUNCTION__,
+					id->class, id->vendor, id->device));
+				return -ENODEV;
+		}
+	}
+
+	if (func && (func->num != 2)) {
+		return 0;
+	}
+
+	if (notify_semaphore)
+		up(notify_semaphore);
+	return 0;
+}
+
+static void dummy_remove(struct sdio_func *func)
+{
+}
+
+static struct sdio_driver dummy_sdmmc_driver = {
+	.probe		= dummy_probe,
+	.remove		= dummy_remove,
+	.name		= "dummy_sdmmc",
+	.id_table	= bcmsdh_sdmmc_ids,
+};
+
+int sdio_func_reg_notify(void* semaphore)
+{
+	notify_semaphore = semaphore;
+	return sdio_register_driver(&dummy_sdmmc_driver);
+}
+
+void sdio_func_unreg_notify(void)
+{
+	OSL_SLEEP(15);
+	sdio_unregister_driver(&dummy_sdmmc_driver);
+}
+
+#endif /* defined(BCMLXSDMMC) */
+
+static struct sdio_driver bcmsdh_sdmmc_driver = {
+	.probe		= bcmsdh_sdmmc_probe,
+	.remove		= bcmsdh_sdmmc_remove,
+	.name		= "bcmsdh_sdmmc",
+	.id_table	= bcmsdh_sdmmc_ids,
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM_SLEEP)
+	.drv = {
+	.pm	= &bcmsdh_sdmmc_pm_ops,
+	},
+#endif /* (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39)) && defined(CONFIG_PM_SLEEP) */
+	};
+
+struct sdos_info {
+	sdioh_info_t *sd;
+	spinlock_t lock;
+};
+
+/* Interrupt enable/disable */
+SDIOH_API_RC
+sdioh_interrupt_set(sdioh_info_t *sd, bool enable)
+{
+	if (!sd)
+		return BCME_BADARG;
+
+	sd_trace(("%s: %s\n", __FUNCTION__, enable ? "Enabling" : "Disabling"));
+	return SDIOH_API_RC_SUCCESS;
+}
+
+#ifdef BCMSDH_MODULE
+static int __init
+bcmsdh_module_init(void)
+{
+	int error = 0;
+	error = sdio_function_init();
+	return error;
+}
+
+static void __exit
+bcmsdh_module_cleanup(void)
+{
+	sdio_function_cleanup();
+}
+
+module_init(bcmsdh_module_init);
+module_exit(bcmsdh_module_cleanup);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION(DESCRIPTION);
+MODULE_AUTHOR(AUTHOR);
+
+#endif /* BCMSDH_MODULE */
+/*
+ * module init
+*/
+int bcmsdh_register_client_driver(void)
+{
+	return sdio_register_driver(&bcmsdh_sdmmc_driver);
+}
+
+/*
+ * module cleanup
+*/
+void bcmsdh_unregister_client_driver(void)
+{
+	sdio_unregister_driver(&bcmsdh_sdmmc_driver);
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcmsdstd.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcmsdstd.c
@@ -0,0 +1,5327 @@
+/*
+ *  'Standard' SDIO HOST CONTROLLER driver
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <typedefs.h>
+
+#include <bcmdevs.h>
+#include <bcmendian.h>
+#include <bcmutils.h>
+#include <osl.h>
+#include <siutils.h>
+#include <sdio.h>	/* SDIO Device and Protocol Specs */
+#include <sdioh.h>	/* Standard SDIO Host Controller Specification */
+#include <bcmsdbus.h>	/* bcmsdh to/from specific controller APIs */
+#include <sdiovar.h>	/* ioctl/iovars */
+#include <pcicfg.h>
+#include <bcmsdstd.h>
+/* XXX Quick NDIS hack */
+#ifdef NDIS
+#define inline  __inline
+#define	PCI_CFG_VID		0
+#define	PCI_CFG_BAR0	0x10
+#endif
+
+#define SD_PAGE_BITS	12
+#define SD_PAGE 	(1 << SD_PAGE_BITS)
+#define SDSTD_MAX_TUNING_PHASE	5
+
+/*
+ * Upper GPIO 16 - 31 are available on J22
+ *   J22.pin3 == gpio16, J22.pin5 == gpio17, etc.
+ * Lower GPIO 0 - 15 are available on J15 (WL_GPIO)
+ */
+#define SDH_GPIO16		16
+#define SDH_GPIO_ENABLE		0xffff
+
+#include <bcmsdstd.h>
+#include <sbsdio.h> /* SDIOH (host controller) core hardware definitions */
+
+/* Globals */
+uint sd_msglevel = SDH_ERROR_VAL;
+
+uint sd_hiok = TRUE;			/* Use hi-speed mode if available? */
+uint sd_sdmode = SDIOH_MODE_SD4;	/* Use SD4 mode by default */
+uint sd_f2_blocksize = 256;		/* Default blocksize */
+uint sd_f1_blocksize = BLOCK_SIZE_4318;		/* Default blocksize */
+
+#define sd3_trace(x)
+
+/*	sd3ClkMode: 	0-SDR12 [25MHz]
+ *				1-SDR25 [50MHz]+SHS=1
+ *				2-SDR50 [100MHz]+SSDR50=1
+ *				3-SDR104 [208MHz]+SSDR104=1
+ *				4-DDR50 [50MHz]+SDDR50=1
+ */
+#define SD3CLKMODE_0_SDR12	(0)
+#define SD3CLKMODE_1_SDR25	(1)
+#define SD3CLKMODE_2_SDR50	(2)
+#define SD3CLKMODE_3_SDR104	(3)
+#define SD3CLKMODE_4_DDR50	(4)
+#define SD3CLKMODE_DISABLED	(-1)
+#define SD3CLKMODE_AUTO		(99)
+
+/* values for global_UHSI_Supp : Means host and card caps match. */
+#define HOST_SDR_UNSUPP			(0)
+#define HOST_SDR_12_25			(1)
+#define HOST_SDR_50_104_DDR		(2)
+
+/* depends-on/affects sd3_autoselect_uhsi_max.
+ *	see sd3_autoselect_uhsi_max
+ */
+int sd_uhsimode = SD3CLKMODE_DISABLED;
+uint sd_tuning_period = CAP3_RETUNING_TC_OTHER;
+uint sd_delay_value = 500000;
+/* Enables host to dongle glomming. Also increases the
+ * dma buffer size. This will increase the rx throughput
+ * as there will be lesser CMD53 transactions
+ */
+#ifdef BCMSDIOH_TXGLOM
+uint sd_txglom;
+#ifdef LINUX
+module_param(sd_txglom, uint, 0);
+#endif
+#endif /* BCMSDIOH_TXGLOM */
+
+char dhd_sdiod_uhsi_ds_override[2] = {' '};
+
+#define MAX_DTS_INDEX		(3)
+#define DRVSTRN_MAX_CHAR	('D')
+#define DRVSTRN_IGNORE_CHAR	(' ')
+
+char DTS_vals[MAX_DTS_INDEX + 1] = {
+	0x1, /* Driver Strength Type-A */
+	0x0, /* Driver Strength Type-B */
+	0x2, /* Driver Strength Type-C */
+	0x3, /* Driver Strength Type-D */
+	};
+
+/* depends-on/affects sd_uhsimode.
+	select MAX speed automatically based on caps of host and card.
+	If this is 1, sd_uhsimode will be ignored. If the sd_uhsimode is set
+	by the user specifically, this var becomes 0. default value: 0. [XXX:TBD: for future]
+	*/
+uint32 sd3_autoselect_uhsi_max = 0;
+
+#define MAX_TUNING_ITERS		(40)
+/* (150+10)millisecs total time; so dividing it for per-loop */
+#define PER_TRY_TUNING_DELAY_MS		(160/MAX_TUNING_ITERS)
+#define CLKTUNING_MAX_BRR_RETRIES	(1000)	/* 1 ms: 1000 retries with 1 us delay per loop */
+
+/* table analogous to preset value register.
+*	This is bcos current HC doesn't have preset value reg support.
+*	All has DrvStr as 'B' [val:0] and CLKGEN as 0.
+*/
+static unsigned short presetval_sw_table[] = {
+	0x0520, /* initialization:	DrvStr:'B' [0]; CLKGen:0;
+			* SDCLKFreqSel: 520 [division: 320*2 = 640: ~400 KHz]
+			*/
+	0x0008, /* default speed:DrvStr:'B' [0]; CLKGen:0;
+			* SDCLKFreqSel: 8 [division: 6*2 = 12: ~25 MHz]
+			*/
+	0x0004, /* High speed: DrvStr:'B' [0]; CLKGen:0;
+			* SDCLKFreqSel: 4 [division: 3*2 = 6: ~50 MHz]
+			*/
+	0x0008, /* SDR12:		DrvStr:'B' [0]; CLKGen:0;
+			* SDCLKFreqSel: 8 [division: 6*2 = 12: ~25 MHz]
+			*/
+	0x0004, /* SDR25:		DrvStr:'B' [0]; CLKGen:0;
+			* SDCLKFreqSel: 4 [division: 3*2 = 6: ~50 MHz]
+			*/
+	0x0001, /* SDR50:		DrvStr:'B' [0]; CLKGen:0;
+			* SDCLKFreqSel: 2 [division: 1*2 = 2: ~100 MHz]
+			*/
+	0x0001, /* SDR104:		DrvStr:'B' [0]; CLKGen:0;
+			SDCLKFreqSel: 1 [no division: ~255/~208 MHz]
+			*/
+	0x0002  /* DDR50:		DrvStr:'B' [0]; CLKGen:0;
+			SDCLKFreqSel: 4 [division: 3*2 = 6: ~50 MHz]
+			*/
+};
+
+#ifdef BCMFPGA_HW
+/*
+ * Voltage switch, clock tuning and preset are not supported in
+ * FPGA which operates at 6.25Mhz.
+ */
+bool sd3_sw_override1 = TRUE;
+#else
+/* This is to have software overrides to the hardware. Info follows:
+	For override [1]:	Preset registers: not supported
+	Voltage switch:  not supported
+	Clock Tuning: not supported
+*/
+bool sd3_sw_override1 = FALSE;
+#endif /* BCMFPGA_HW */
+bool sd3_sw_read_magic_bytes = FALSE;
+
+#define SD3_TUNING_REQD(sd, sd_uhsimode) ((sd_uhsimode != SD3CLKMODE_DISABLED) && \
+			(sd->version == HOST_CONTR_VER_3) &&	\
+			((sd_uhsimode == SD3CLKMODE_3_SDR104) ||	\
+			((sd_uhsimode == SD3CLKMODE_2_SDR50) &&	\
+			(GFIELD(sd->caps3, CAP3_TUNING_SDR50)))))
+
+/* find next power of 2 */
+#define NEXT_POW2(n)  {n--; n |= n>>1; n |= n>>2; n |= n>>4; n++;}
+
+#ifdef BCMSDYIELD
+bool sd_yieldcpu = TRUE;		/* Allow CPU yielding for buffer requests */
+uint sd_minyield = 0;			/* Minimum xfer size to allow CPU yield */
+bool sd_forcerb = FALSE;		/* Force sync readback in intrs_on/off */
+#endif
+
+/* XXX: Issues with CMD14 enter/exit sleep
+ * XXX: Temp fix for special CMD14 handling
+ */
+#define F1_SLEEPCSR_ADDR	0x1001F
+
+uint sd_divisor = 2;	/* Default 48MHz/2 = 24MHz
+							:might get changed in code for 208
+							*/
+
+uint sd_power = 1;		/* Default to SD Slot powered ON */
+uint sd_3_power_save = 1;		/* Default to SDIO 3.0 power save */
+uint sd_clock = 1;		/* Default to SD Clock turned ON */
+uint sd_pci_slot = 0xFFFFffff; /* Used to force selection of a particular PCI slot */
+uint8 sd_dma_mode = DMA_MODE_AUTO; /* Default to AUTO & program based on capability */
+
+/* XXX Base timeout counter value on 48MHz (2^20 @ 48MHz => 21845us)
+ * Could adjust by adding sd_divisor (to maintain bit count) but really
+ * need something more elaborate to do that right.  Still allows xfer
+ * of about 1000 bytes at 400KHz, so constant is ok.
+ * Timeout control N produces 2^(13+N) counter.
+ */
+uint sd_toctl = 7;
+static bool trap_errs = FALSE;
+
+static const char *dma_mode_description[] = { "PIO", "SDMA", "ADMA1", "32b ADMA2", "64b ADMA2" };
+
+/* Prototypes */
+static bool sdstd_start_clock(sdioh_info_t *sd, uint16 divisor);
+static uint16 sdstd_start_power(sdioh_info_t *sd, int volts_req);
+static bool sdstd_bus_width(sdioh_info_t *sd, int width);
+static int sdstd_set_highspeed_mode(sdioh_info_t *sd, bool HSMode);
+static int sdstd_set_dma_mode(sdioh_info_t *sd, int8 dma_mode);
+static int sdstd_card_enablefuncs(sdioh_info_t *sd);
+static void sdstd_cmd_getrsp(sdioh_info_t *sd, uint32 *rsp_buffer, int count);
+static int sdstd_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd, uint32 arg);
+static int sdstd_card_regread(sdioh_info_t *sd, int func, uint32 regaddr,
+                              int regsize, uint32 *data);
+static int sdstd_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr,
+                               int regsize, uint32 data);
+static int sdstd_driver_init(sdioh_info_t *sd);
+static bool sdstd_reset(sdioh_info_t *sd, bool host_reset, bool client_reset);
+static int sdstd_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo,
+                          uint32 addr, int nbytes, uint32 *data);
+static int sdstd_abort(sdioh_info_t *sd, uint func);
+static int sdstd_check_errs(sdioh_info_t *sdioh_info, uint32 cmd, uint32 arg);
+static int set_client_block_size(sdioh_info_t *sd, int func, int blocksize);
+static void sd_map_dma(sdioh_info_t * sd);
+static void sd_unmap_dma(sdioh_info_t * sd);
+static void sd_clear_adma_dscr_buf(sdioh_info_t *sd);
+static void sd_fill_dma_data_buf(sdioh_info_t *sd, uint8 data);
+static void sd_create_adma_descriptor(sdioh_info_t *sd,
+                                      uint32 index, uint32 addr_phys,
+                                      uint16 length, uint16 flags);
+static void sd_dump_adma_dscr(sdioh_info_t *sd);
+static void sdstd_dumpregs(sdioh_info_t *sd);
+
+static int sdstd_3_set_highspeed_uhsi_mode(sdioh_info_t *sd, int sd3ClkMode);
+static int sdstd_3_sigvoltswitch_proc(sdioh_info_t *sd);
+static int sdstd_3_get_matching_uhsi_clkmode(sdioh_info_t *sd,
+	int sd3_requested_clkmode);
+static bool sdstd_3_get_matching_drvstrn(sdioh_info_t *sd,
+	int sd3_requested_clkmode, uint32 *drvstrn, uint16 *presetval);
+static int sdstd_3_clock_wrapper(sdioh_info_t *sd);
+static int sdstd_clock_wrapper(sdioh_info_t *sd);
+
+#ifdef BCMDBG
+static void print_regs(sdioh_info_t *sd);
+#endif
+
+/*
+ * Private register access routines.
+ */
+
+/* 16 bit PCI regs */
+
+/* XXX This is a hack to satisfy the -Wmissing-prototypes warning */
+extern uint16 sdstd_rreg16(sdioh_info_t *sd, uint reg);
+uint16
+sdstd_rreg16(sdioh_info_t *sd, uint reg)
+{
+
+	volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg);
+	sd_ctrl(("16: R Reg 0x%02x, Data 0x%x\n", reg, data));
+	return data;
+}
+
+/* XXX This is a hack to satisfy the -Wmissing-prototypes warning */
+extern void sdstd_wreg16(sdioh_info_t *sd, uint reg, uint16 data);
+void
+sdstd_wreg16(sdioh_info_t *sd, uint reg, uint16 data)
+{
+	*(volatile uint16 *)(sd->mem_space + reg) = (uint16) data;
+	sd_ctrl(("16: W Reg 0x%02x, Data 0x%x\n", reg, data));
+}
+
+static void
+sdstd_or_reg16(sdioh_info_t *sd, uint reg, uint16 val)
+{
+	volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg);
+	sd_ctrl(("16: OR Reg 0x%02x, Val 0x%x\n", reg, val));
+	data |= val;
+	*(volatile uint16 *)(sd->mem_space + reg) = (uint16)data;
+
+}
+static void
+sdstd_mod_reg16(sdioh_info_t *sd, uint reg, int16 mask, uint16 val)
+{
+
+	volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg);
+	sd_ctrl(("16: MOD Reg 0x%02x, Mask 0x%x, Val 0x%x\n", reg, mask, val));
+	data &= ~mask;
+	data |= (val & mask);
+	*(volatile uint16 *)(sd->mem_space + reg) = (uint16)data;
+}
+
+/* 32 bit PCI regs */
+static uint32
+sdstd_rreg(sdioh_info_t *sd, uint reg)
+{
+	volatile uint32 data = *(volatile uint32 *)(sd->mem_space + reg);
+	sd_ctrl(("32: R Reg 0x%02x, Data 0x%x\n", reg, data));
+	return data;
+}
+static inline void
+sdstd_wreg(sdioh_info_t *sd, uint reg, uint32 data)
+{
+	*(volatile uint32 *)(sd->mem_space + reg) = (uint32)data;
+	sd_ctrl(("32: W Reg 0x%02x, Data 0x%x\n", reg, data));
+
+}
+
+/* 8 bit PCI regs */
+static inline void
+sdstd_wreg8(sdioh_info_t *sd, uint reg, uint8 data)
+{
+	*(volatile uint8 *)(sd->mem_space + reg) = (uint8)data;
+	sd_ctrl(("08: W Reg 0x%02x, Data 0x%x\n", reg, data));
+}
+static uint8
+sdstd_rreg8(sdioh_info_t *sd, uint reg)
+{
+	volatile uint8 data = *(volatile uint8 *)(sd->mem_space + reg);
+	sd_ctrl(("08: R Reg 0x%02x, Data 0x%x\n", reg, data));
+	return data;
+}
+
+/*
+ * Private work routines
+ */
+
+sdioh_info_t *glob_sd;
+
+/*
+ *  Public entry points & extern's
+ */
+extern sdioh_info_t *
+sdioh_attach(osl_t *osh, void *bar0, uint irq)
+{
+	sdioh_info_t *sd;
+
+	sd_trace(("%s\n", __FUNCTION__));
+	if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) {
+		sd_err(("sdioh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh)));
+		return NULL;
+	}
+	bzero((char *)sd, sizeof(sdioh_info_t));
+	glob_sd = sd;
+	sd->osh = osh;
+	if (sdstd_osinit(sd) != 0) {
+		sd_err(("%s:sdstd_osinit() failed\n", __FUNCTION__));
+		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
+		return NULL;
+	}
+	sd->mem_space = (volatile char *)sdstd_reg_map(osh, (ulong)bar0, SDIOH_REG_WINSZ);
+	sd_init_dma(sd);
+	sd->irq = irq;
+	if (sd->mem_space == NULL) {
+		sd_err(("%s:ioremap() failed\n", __FUNCTION__));
+		sdstd_osfree(sd);
+		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
+		return NULL;
+	}
+	sd_info(("%s:sd->mem_space = %p\n", __FUNCTION__, sd->mem_space));
+	sd->intr_handler = NULL;
+	sd->intr_handler_arg = NULL;
+	sd->intr_handler_valid = FALSE;
+
+	/* Set defaults */
+	sd->sd_blockmode = TRUE;
+	sd->use_client_ints = TRUE;
+	sd->sd_dma_mode = sd_dma_mode;
+
+	/* XXX Haven't figured out how to make bytemode work with dma */
+	if (!sd->sd_blockmode)
+		sd->sd_dma_mode = DMA_MODE_NONE;
+
+	if (sdstd_driver_init(sd) != SUCCESS) {
+		/* If host CPU was reset without resetting SD bus or
+		   SD device, the device will still have its RCA but
+		   driver no longer knows what it is (since driver has been restarted).
+		   go through once to clear the RCA and a gain reassign it.
+		 */
+		sd_info(("driver_init failed - Reset RCA and try again\n"));
+		if (sdstd_driver_init(sd) != SUCCESS) {
+			sd_err(("%s:driver_init() failed()\n", __FUNCTION__));
+			if (sd->mem_space) {
+				sdstd_reg_unmap(osh, (ulong)sd->mem_space, SDIOH_REG_WINSZ);
+				sd->mem_space = NULL;
+			}
+			sdstd_osfree(sd);
+			MFREE(sd->osh, sd, sizeof(sdioh_info_t));
+			return (NULL);
+		}
+	}
+
+	/* XXX Needed for NDIS as its OSL checks for correct dma address width
+	 * This value is normally set by wlc_attach() which has yet to run
+	 */
+	OSL_DMADDRWIDTH(osh, 32);
+
+	/* Always map DMA buffers, so we can switch between DMA modes. */
+	sd_map_dma(sd);
+
+	if (sdstd_register_irq(sd, irq) != SUCCESS) {
+		sd_err(("%s: sdstd_register_irq() failed for irq = %d\n", __FUNCTION__, irq));
+		sdstd_free_irq(sd->irq, sd);
+		if (sd->mem_space) {
+			sdstd_reg_unmap(osh, (ulong)sd->mem_space, SDIOH_REG_WINSZ);
+			sd->mem_space = NULL;
+		}
+
+		sdstd_osfree(sd);
+		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
+		return (NULL);
+	}
+
+	sd_trace(("%s: Done\n", __FUNCTION__));
+	return sd;
+}
+
+extern SDIOH_API_RC
+sdioh_detach(osl_t *osh, sdioh_info_t *sd)
+{
+	sd_trace(("%s\n", __FUNCTION__));
+	if (sd) {
+		sd_unmap_dma(sd);
+		sdstd_wreg16(sd, SD_IntrSignalEnable, 0);
+		if (sd->sd3_tuning_reqd == TRUE) {
+			sdstd_3_osclean_tuning(sd);
+			sd->sd3_tuning_reqd = FALSE;
+		}
+		sd->sd3_tuning_disable = FALSE;
+		sd_trace(("%s: freeing irq %d\n", __FUNCTION__, sd->irq));
+		sdstd_free_irq(sd->irq, sd);
+		if (sd->card_init_done)
+			sdstd_reset(sd, 1, 1);
+		if (sd->mem_space) {
+			sdstd_reg_unmap(osh, (ulong)sd->mem_space, SDIOH_REG_WINSZ);
+			sd->mem_space = NULL;
+		}
+
+		sdstd_osfree(sd);
+		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
+	}
+	return SDIOH_API_RC_SUCCESS;
+}
+
+/* Configure callback to client when we receive client interrupt */
+extern SDIOH_API_RC
+sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh)
+{
+	sd_trace(("%s: Entering\n", __FUNCTION__));
+	sd->intr_handler = fn;
+	sd->intr_handler_arg = argh;
+	sd->intr_handler_valid = TRUE;
+	return SDIOH_API_RC_SUCCESS;
+}
+
+extern SDIOH_API_RC
+sdioh_interrupt_deregister(sdioh_info_t *sd)
+{
+	sd_trace(("%s: Entering\n", __FUNCTION__));
+	sd->intr_handler_valid = FALSE;
+	sd->intr_handler = NULL;
+	sd->intr_handler_arg = NULL;
+	return SDIOH_API_RC_SUCCESS;
+}
+
+extern SDIOH_API_RC
+sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff)
+{
+	sd_trace(("%s: Entering\n", __FUNCTION__));
+	*onoff = sd->client_intr_enabled;
+	return SDIOH_API_RC_SUCCESS;
+}
+
+#if defined(DHD_DEBUG) || defined(BCMDBG)
+extern bool
+sdioh_interrupt_pending(sdioh_info_t *sd)
+{
+	uint16 intrstatus;
+	intrstatus = sdstd_rreg16(sd, SD_IntrStatus);
+	return !!(intrstatus & CLIENT_INTR);
+}
+#endif
+
+uint
+sdioh_query_iofnum(sdioh_info_t *sd)
+{
+	return sd->num_funcs;
+}
+
+/* IOVar table */
+enum {
+	IOV_MSGLEVEL = 1,
+	IOV_BLOCKMODE,
+	IOV_BLOCKSIZE,
+	IOV_DMA,
+	IOV_USEINTS,
+	IOV_NUMINTS,
+	IOV_NUMLOCALINTS,
+	IOV_HOSTREG,
+	IOV_DEVREG,
+	IOV_DIVISOR,
+	IOV_SDMODE,
+	IOV_HISPEED,
+	IOV_HCIREGS,
+	IOV_POWER,
+	IOV_POWER_SAVE,
+	IOV_YIELDCPU,
+	IOV_MINYIELD,
+	IOV_FORCERB,
+	IOV_CLOCK,
+	IOV_UHSIMOD,
+	IOV_TUNEMOD,
+	IOV_TUNEDIS,
+	IOV_DS
+};
+
+const bcm_iovar_t sdioh_iovars[] = {
+	{"sd_msglevel",	IOV_MSGLEVEL,	0,	0, IOVT_UINT32,	0 },
+	{"sd_blockmode", IOV_BLOCKMODE,	0,	0, IOVT_BOOL,	0 },
+	{"sd_blocksize", IOV_BLOCKSIZE, 0,	0, IOVT_UINT32,	0 }, /* ((fn << 16) | size) */
+	{"sd_dma",	IOV_DMA,	0,	0, IOVT_UINT32,	0 },
+#ifdef BCMSDYIELD
+	{"sd_yieldcpu",	IOV_YIELDCPU,	0,	0, IOVT_BOOL,	0 },
+	{"sd_minyield",	IOV_MINYIELD,	0,	0, IOVT_UINT32,	0 },
+	{"sd_forcerb",	IOV_FORCERB,	0,	0, IOVT_BOOL,	0 },
+#endif
+	{"sd_ints",	IOV_USEINTS,	0,	0, IOVT_BOOL,	0 },
+	{"sd_numints",	IOV_NUMINTS,	0,	0, IOVT_UINT32,	0 },
+	{"sd_numlocalints", IOV_NUMLOCALINTS, 0, 0, IOVT_UINT32,	0 },
+	{"sd_hostreg",	IOV_HOSTREG,	0,	0, IOVT_BUFFER,	sizeof(sdreg_t) },
+	{"sd_devreg",	IOV_DEVREG,	0,	0, IOVT_BUFFER,	sizeof(sdreg_t)	},
+	{"sd_divisor",	IOV_DIVISOR,	0,	0, IOVT_UINT32,	0 },
+	{"sd_power",	IOV_POWER,	0,	0, IOVT_UINT32,	0 },
+	{"sd_power_save",	IOV_POWER_SAVE,	0,	0, IOVT_UINT32,	0 },
+	{"sd_clock",	IOV_CLOCK,	0,	0, IOVT_UINT32,	0 },
+	{"sd_mode",	IOV_SDMODE,	0,	0, IOVT_UINT32,	100},
+	{"sd_highspeed",	IOV_HISPEED,	0,	0, IOVT_UINT32,	0},
+	{"sd_uhsimode",	IOV_UHSIMOD,	0,	0, IOVT_UINT32,	0},
+#ifdef BCMDBG
+	{"sd_hciregs",	IOV_HCIREGS,	0,	0, IOVT_BUFFER,	0 },
+#endif
+	{"tuning_mode", IOV_TUNEMOD,	0,	0, IOVT_UINT32,	0},
+	{"sd3_tuning_disable", IOV_TUNEDIS,	0,	0, IOVT_BOOL,	0},
+	{"sd_ds",	IOV_DS,		0,	0, IOVT_UINT32,	0},
+
+	{NULL, 0, 0, 0, 0, 0 }
+};
+uint8 sdstd_turn_on_clock(sdioh_info_t *sd)
+{
+	sdstd_or_reg16(sd, SD_ClockCntrl, 0x4);
+	return 0;
+}
+
+uint8 sdstd_turn_off_clock(sdioh_info_t *sd)
+{
+	sdstd_wreg16(sd, SD_ClockCntrl, sdstd_rreg16(sd, SD_ClockCntrl) & ~((uint16)0x4));
+	return 0;
+}
+
+int
+sdioh_iovar_op(sdioh_info_t *si, const char *name,
+               void *params, int plen, void *arg, uint len, bool set)
+{
+	const bcm_iovar_t *vi = NULL;
+	int bcmerror = 0;
+	uint val_size;
+	int32 int_val = 0;
+	bool bool_val;
+	uint32 actionid;
+
+	ASSERT(name);
+
+	/* Get must have return space; Set does not take qualifiers */
+	ASSERT(set || (arg && len));
+	ASSERT(!set || (!params && !plen));
+
+	sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name));
+
+	if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) {
+		bcmerror = BCME_UNSUPPORTED;
+		goto exit;
+	}
+
+	if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0)
+		goto exit;
+
+	/* XXX Copied from dhd, copied from wl; certainly overkill here? */
+	/* Set up params so get and set can share the convenience variables */
+	if (params == NULL) {
+		params = arg;
+		plen = len;
+	}
+
+	if (vi->type == IOVT_VOID)
+		val_size = 0;
+	else if (vi->type == IOVT_BUFFER)
+		val_size = len;
+	else
+		val_size = sizeof(int);
+
+	if (plen >= (int)sizeof(int_val))
+		bcopy(params, &int_val, sizeof(int_val));
+
+	bool_val = (int_val != 0) ? TRUE : FALSE;
+	BCM_REFERENCE(bool_val);
+
+	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+	switch (actionid) {
+	case IOV_GVAL(IOV_MSGLEVEL):
+		int_val = (int32)sd_msglevel;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_MSGLEVEL):
+		sd_msglevel = int_val;
+		break;
+
+	case IOV_GVAL(IOV_BLOCKMODE):
+		int_val = (int32)si->sd_blockmode;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_BLOCKMODE):
+		si->sd_blockmode = (bool)int_val;
+		/* Haven't figured out how to make non-block mode with DMA */
+		if (!si->sd_blockmode)
+			si->sd_dma_mode = DMA_MODE_NONE;
+		break;
+
+#ifdef BCMSDYIELD
+	case IOV_GVAL(IOV_YIELDCPU):
+		int_val = sd_yieldcpu;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_YIELDCPU):
+		sd_yieldcpu = (bool)int_val;
+		break;
+
+	case IOV_GVAL(IOV_MINYIELD):
+		int_val = sd_minyield;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_MINYIELD):
+		sd_minyield = (bool)int_val;
+		break;
+
+	case IOV_GVAL(IOV_FORCERB):
+		int_val = sd_forcerb;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_FORCERB):
+		sd_forcerb = (bool)int_val;
+		break;
+#endif /* BCMSDYIELD */
+
+	case IOV_GVAL(IOV_BLOCKSIZE):
+		if ((uint32)int_val > si->num_funcs) {
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		int_val = (int32)si->client_block_size[int_val];
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_BLOCKSIZE):
+	{
+		uint func = ((uint32)int_val >> 16);
+		uint blksize = (uint16)int_val;
+		uint maxsize;
+
+		if (func > si->num_funcs) {
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		/* XXX These hardcoded sizes are a hack, remove after proper CIS parsing. */
+		switch (func) {
+		case 0: maxsize = 32; break;
+		case 1: maxsize = BLOCK_SIZE_4318; break;
+		case 2: maxsize = BLOCK_SIZE_4328; break;
+		default: maxsize = 0;
+		}
+		if (blksize > maxsize) {
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		if (!blksize) {
+			blksize = maxsize;
+		}
+
+		/* Now set it */
+		sdstd_lock(si);
+		bcmerror = set_client_block_size(si, func, blksize);
+		sdstd_unlock(si);
+		break;
+	}
+
+	case IOV_GVAL(IOV_DMA):
+		int_val = (int32)si->sd_dma_mode;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_DMA):
+		si->sd_dma_mode = (char)int_val;
+		sdstd_set_dma_mode(si, si->sd_dma_mode);
+		break;
+
+	case IOV_GVAL(IOV_USEINTS):
+		int_val = (int32)si->use_client_ints;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_USEINTS):
+		si->use_client_ints = (bool)int_val;
+		if (si->use_client_ints)
+			si->intmask |= CLIENT_INTR;
+		else
+			si->intmask &= ~CLIENT_INTR;
+		break;
+
+	case IOV_GVAL(IOV_DIVISOR):
+		int_val = (uint32)sd_divisor;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_DIVISOR):
+		sd_divisor = int_val;
+		if (!sdstd_start_clock(si, (uint16)sd_divisor)) {
+			sd_err(("set clock failed!\n"));
+			bcmerror = BCME_ERROR;
+		}
+		break;
+
+	case IOV_GVAL(IOV_POWER):
+		int_val = (uint32)sd_power;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_GVAL(IOV_POWER_SAVE):
+		int_val = (uint32)sd_3_power_save;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_POWER):
+		sd_power = int_val;
+		if (sd_power == 1) {
+			if (sdstd_driver_init(si) != SUCCESS) {
+				sd_err(("set SD Slot power failed!\n"));
+				bcmerror = BCME_ERROR;
+			} else {
+				sd_err(("SD Slot Powered ON.\n"));
+			}
+		} else {
+			uint8 pwr = 0;
+
+			pwr = SFIELD(pwr, PWR_BUS_EN, 0);
+			sdstd_wreg8(si, SD_PwrCntrl, pwr); /* Set Voltage level */
+			sd_err(("SD Slot Powered OFF.\n"));
+		}
+		break;
+
+	case IOV_SVAL(IOV_POWER_SAVE):
+		sd_3_power_save = int_val;
+		break;
+
+	case IOV_GVAL(IOV_CLOCK):
+		int_val = (uint32)sd_clock;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_CLOCK):
+		sd_clock = int_val;
+		if (sd_clock == 1) {
+			sd_info(("SD Clock turned ON.\n"));
+			if (!sdstd_start_clock(si, (uint16)sd_divisor)) {
+				sd_err(("sdstd_start_clock failed\n"));
+				bcmerror = BCME_ERROR;
+			}
+		} else {
+			/* turn off HC clock */
+			sdstd_wreg16(si, SD_ClockCntrl,
+			             sdstd_rreg16(si, SD_ClockCntrl) & ~((uint16)0x4));
+
+			sd_info(("SD Clock turned OFF.\n"));
+		}
+		break;
+
+	case IOV_GVAL(IOV_SDMODE):
+		int_val = (uint32)sd_sdmode;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_SDMODE):
+		sd_sdmode = int_val;
+
+		if (!sdstd_bus_width(si, sd_sdmode)) {
+			sd_err(("sdstd_bus_width failed\n"));
+			bcmerror = BCME_ERROR;
+		}
+		break;
+
+	case IOV_GVAL(IOV_HISPEED):
+		int_val = (uint32)sd_hiok;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_HISPEED):
+		sd_hiok = int_val;
+		bcmerror = sdstd_set_highspeed_mode(si, (bool)sd_hiok);
+		break;
+
+	case IOV_GVAL(IOV_UHSIMOD):
+		sd3_trace(("%s: Get UHSI: \n", __FUNCTION__));
+		int_val = (int)sd_uhsimode;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_UHSIMOD):
+		{
+			int oldval = sd_uhsimode; /* save old, working value */
+			sd3_trace(("%s: Set UHSI: \n", __FUNCTION__));
+			/* check if UHSI is supported by card/host */
+			if (!(si->card_UHSI_voltage_Supported && si->host_UHSISupported)) {
+				sd_err(("%s:UHSI not suppoted!\n", __FUNCTION__));
+				bcmerror = BCME_UNSUPPORTED;
+				break;
+			}
+			/* check for valid values */
+			if (!((int_val == SD3CLKMODE_AUTO) ||
+				(int_val == SD3CLKMODE_DISABLED) ||
+				((int_val >= SD3CLKMODE_0_SDR12) &&
+				(int_val <= SD3CLKMODE_4_DDR50)))) {
+				sd_err(("%s:CLK: bad arg!\n", __FUNCTION__));
+				bcmerror = BCME_BADARG;
+				break;
+			}
+
+			sd_uhsimode = int_val;
+			if (SUCCESS != sdstd_3_clock_wrapper(si)) {
+				sd_err(("%s:Error in setting uhsi clkmode:%d,"
+					"restoring back to %d\n", __FUNCTION__,
+					sd_uhsimode, oldval));
+				/* try to set back the old one */
+				sd_uhsimode = oldval;
+				if (SUCCESS != sdstd_3_clock_wrapper(si)) {
+					sd_err(("%s:Error in setting uhsi to old mode;"
+						"ignoring:\n", __FUNCTION__));
+				}
+			}
+			break;
+		}
+#ifdef DHD_DEBUG
+	case IOV_SVAL(IOV_TUNEMOD):
+	{
+
+		if( int_val == SD_DHD_DISABLE_PERIODIC_TUNING) { /* do tuning single time */
+			sd3_trace(("Start tuning from Iovar\n"));
+			si->sd3_tuning_reqd = TRUE;
+			sdstd_enable_disable_periodic_timer(si, int_val);
+			sdstd_lock(si);
+			sdstd_3_clk_tuning(si, sdstd_3_get_uhsi_clkmode(si));
+			sdstd_unlock(si);
+			si->sd3_tuning_reqd = FALSE;
+		}
+		if (int_val == SD_DHD_ENABLE_PERIODIC_TUNING) {
+			sd3_trace(("Enabling  automatic tuning\n"));
+			si->sd3_tuning_reqd = TRUE;
+		    sdstd_enable_disable_periodic_timer(si, int_val);
+		}
+		break;
+	}
+#endif /* debugging purpose */
+	case IOV_GVAL(IOV_NUMINTS):
+		int_val = (int32)si->intrcount;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_GVAL(IOV_NUMLOCALINTS):
+		int_val = (int32)si->local_intrcount;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_GVAL(IOV_HOSTREG):
+	{
+		/* XXX Should copy for alignment reasons */
+		sdreg_t *sd_ptr = (sdreg_t *)params;
+
+		if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD3_WL_BT_reset_register) {
+			sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		sd_trace(("%s: rreg%d at offset %d\n", __FUNCTION__,
+		          (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32),
+		          sd_ptr->offset));
+		if (sd_ptr->offset & 1)
+			int_val = sdstd_rreg8(si, sd_ptr->offset);
+		else if (sd_ptr->offset & 2)
+			int_val = sdstd_rreg16(si, sd_ptr->offset);
+		else
+			int_val = sdstd_rreg(si, sd_ptr->offset);
+
+		bcopy(&int_val, arg, sizeof(int_val));
+		break;
+	}
+
+	case IOV_SVAL(IOV_HOSTREG):
+	{
+		/* XXX Should copy for alignment reasons */
+		sdreg_t *sd_ptr = (sdreg_t *)params;
+
+		if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD3_WL_BT_reset_register) {
+			sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		sd_trace(("%s: wreg%d value 0x%08x at offset %d\n", __FUNCTION__, sd_ptr->value,
+		          (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32),
+		          sd_ptr->offset));
+		if (sd_ptr->offset & 1)
+			sdstd_wreg8(si, sd_ptr->offset, (uint8)sd_ptr->value);
+		else if (sd_ptr->offset & 2)
+			sdstd_wreg16(si, sd_ptr->offset, (uint16)sd_ptr->value);
+		else
+			sdstd_wreg(si, sd_ptr->offset, (uint32)sd_ptr->value);
+
+		break;
+	}
+
+	case IOV_GVAL(IOV_DEVREG):
+	{
+		/* XXX Should copy for alignment reasons */
+		sdreg_t *sd_ptr = (sdreg_t *)params;
+		uint8 data;
+
+		if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) {
+			bcmerror = BCME_SDIO_ERROR;
+			break;
+		}
+
+		int_val = (int)data;
+		bcopy(&int_val, arg, sizeof(int_val));
+		break;
+	}
+
+	case IOV_SVAL(IOV_DEVREG):
+	{
+		/* XXX Should copy for alignment reasons */
+		sdreg_t *sd_ptr = (sdreg_t *)params;
+		uint8 data = (uint8)sd_ptr->value;
+
+		if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) {
+			bcmerror = BCME_SDIO_ERROR;
+			break;
+		}
+		break;
+	}
+
+#ifdef BCMDBG
+	case IOV_GVAL(IOV_HCIREGS):
+	{
+		struct bcmstrbuf b;
+		bcm_binit(&b, arg, len);
+
+		sdstd_lock(si);
+		bcm_bprintf(&b, "IntrStatus:       0x%04x ErrorIntrStatus       0x%04x\n",
+		            sdstd_rreg16(si, SD_IntrStatus),
+		            sdstd_rreg16(si, SD_ErrorIntrStatus));
+		bcm_bprintf(&b, "IntrStatusEnable: 0x%04x ErrorIntrStatusEnable 0x%04x\n",
+		            sdstd_rreg16(si, SD_IntrStatusEnable),
+		            sdstd_rreg16(si, SD_ErrorIntrStatusEnable));
+		bcm_bprintf(&b, "IntrSignalEnable: 0x%04x ErrorIntrSignalEnable 0x%04x\n",
+		            sdstd_rreg16(si, SD_IntrSignalEnable),
+		            sdstd_rreg16(si, SD_ErrorIntrSignalEnable));
+		print_regs(si);
+
+		sdstd_unlock(si);
+
+		if (!b.size)
+			bcmerror = BCME_BUFTOOSHORT;
+		break;
+	}
+#endif /* BCMDBG */
+
+	case IOV_SVAL(IOV_TUNEDIS):
+		si->sd3_tuning_disable = (bool)int_val;
+		break;
+
+	case IOV_GVAL(IOV_DS):
+	{
+		uint32 drvstrn;
+		int status;
+
+		status = sdstd_card_regread(si, 0, SDIOD_CCCR_DRIVER_STRENGTH, 1, &drvstrn);
+		if (status != BCME_OK) {
+			sd_err(("sd_ds error for read SDIOD_CCCR_DRIVER_STRENGTH : 0x%x\n",
+				status));
+			bcmerror = BCME_SDIO_ERROR;
+		} else {
+			sd_err(("sd_ds get cccr driver strength 0x%x\n", drvstrn));
+		}
+		int_val = (uint32)drvstrn;
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+
+	case IOV_SVAL(IOV_DS):
+	{
+		uint32 drvstrn;
+		int status;
+
+		status = sdstd_card_regread(si, 0, SDIOD_CCCR_DRIVER_STRENGTH, 1, &drvstrn);
+		if (status != BCME_OK) {
+			sd_err(("sd_ds error for read SDIOD_CCCR_DRIVER_STRENGTH : 0x%x\n",
+				status));
+			bcmerror = BCME_SDIO_ERROR;
+		} else {
+			sd_err(("sd_ds get cccr driver strength 0x%x\n", drvstrn));
+		}
+
+		if (int_val == 0) {
+			drvstrn = ((drvstrn & 0xf) | 0x0);
+		} else if (int_val == 1) {
+			drvstrn = ((drvstrn & 0xf) | 0x10);
+		} else if (int_val == 2) {
+			drvstrn = ((drvstrn & 0xf) | 0x20);
+		} else if (int_val == 3) {
+			drvstrn = ((drvstrn & 0xf) | 0x30);
+		} else {
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		status = sdstd_card_regwrite(si, 0, SDIOD_CCCR_DRIVER_STRENGTH, 1, drvstrn);
+		if (status != BCME_OK) {
+			sd_err(("sd_ds error write SDIOD_CCCR_DRIVER_STRENGTH : 0x%x\n", status));
+		}
+		break;
+	}
+
+	default:
+		bcmerror = BCME_UNSUPPORTED;
+		break;
+	}
+exit:
+
+	/* XXX Remove protective lock after clients all clean... */
+	return bcmerror;
+}
+
+extern SDIOH_API_RC
+sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data)
+{
+	SDIOH_API_RC status;
+	/* No lock needed since sdioh_request_byte does locking */
+	status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data);
+	return status;
+}
+
+extern SDIOH_API_RC
+sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data)
+{
+	/* No lock needed since sdioh_request_byte does locking */
+	SDIOH_API_RC status;
+	status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data);
+	return status;
+}
+
+extern SDIOH_API_RC
+sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length)
+{
+	uint32 count;
+	int offset;
+	uint32 foo;
+	uint8 *cis = cisd;
+
+	sd_trace(("%s: Func = %d\n", __FUNCTION__, func));
+
+	if (!sd->func_cis_ptr[func]) {
+		bzero(cis, length);
+		return SDIOH_API_RC_FAIL;
+	}
+
+	sdstd_lock(sd);
+	*cis = 0;
+	for (count = 0; count < length; count++) {
+		offset =  sd->func_cis_ptr[func] + count;
+		if (sdstd_card_regread(sd, 0, offset, 1, &foo)) {
+			sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__));
+			sdstd_unlock(sd);
+			return SDIOH_API_RC_FAIL;
+		}
+		*cis = (uint8)(foo & 0xff);
+		cis++;
+	}
+	sdstd_unlock(sd);
+	return SDIOH_API_RC_SUCCESS;
+}
+
+extern SDIOH_API_RC
+sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte)
+{
+	int status = SDIOH_API_RC_SUCCESS;
+	uint32 cmd_arg;
+	uint32 rsp5;
+
+	sdstd_lock(sd);
+	if (rw == SDIOH_READ)
+	sdstd_3_check_and_do_tuning(sd, CHECK_TUNING_PRE_DATA);
+
+	/* Change to DATA_TRANSFER_ONGOING , protection against tuning tasklet */
+	sdstd_3_set_data_state(sd, DATA_TRANSFER_ONGOING);
+
+#ifdef BCMDBG
+	if (sdstd_rreg16 (sd, SD_ErrorIntrStatus) != 0) {
+		sd_err(("%s: Entering: ErririntrStatus 0x%x, intstat = 0x%x\n",
+		        __FUNCTION__, sdstd_rreg16(sd, SD_ErrorIntrStatus),
+		        sdstd_rreg16(sd, SD_IntrStatus)));
+	}
+#endif
+	cmd_arg = 0;
+	cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func);
+	cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr);
+	cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, rw == SDIOH_READ ? 0 : 1);
+	cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0);
+	cmd_arg = SFIELD(cmd_arg, CMD52_DATA, rw == SDIOH_READ ? 0 : *byte);
+
+	if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_52, cmd_arg)) != SUCCESS) {
+		/* Change to DATA_TRANSFER_IDLE */
+		sdstd_3_set_data_state(sd, DATA_TRANSFER_IDLE);
+		sdstd_unlock(sd);
+		return status;
+	}
+
+	sdstd_cmd_getrsp(sd, &rsp5, 1);
+	if (sdstd_rreg16 (sd, SD_ErrorIntrStatus) != 0) {
+		sd_err(("%s: 1: ErrorintrStatus 0x%x\n",
+		        __FUNCTION__, sdstd_rreg16(sd, SD_ErrorIntrStatus)));
+		status = SDIOH_API_RC_FAIL;
+	}
+	if (GFIELD(rsp5, RSP5_FLAGS) != 0x10) {
+		/* PR 101351: sdiod_aos sleep followed by immediate wakeup
+		 *    before sdiod_aos takes over has a problem.
+		 * While exiting sleep with CMD14, device returning 0x00
+		 * Don't flag as error for now for 0x1001f.
+		 */
+		if (GFIELD(cmd_arg, CMD52_REG_ADDR) != F1_SLEEPCSR_ADDR) {
+			sd_err(("%s: rsp5 flags is 0x%x\t %d \n",
+				__FUNCTION__, GFIELD(rsp5, RSP5_FLAGS), func));
+		}
+		status = SDIOH_API_RC_FAIL;
+	}
+
+	if (GFIELD(rsp5, RSP5_STUFF)) {
+		sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n",
+		        __FUNCTION__, GFIELD(rsp5, RSP5_STUFF)));
+		status = SDIOH_API_RC_FAIL;
+	}
+
+	if (rw == SDIOH_READ)
+		*byte = GFIELD(rsp5, RSP5_DATA);
+
+	/* Change to DATA_TRANSFER_IDLE */
+	sdstd_3_set_data_state(sd, DATA_TRANSFER_IDLE);
+
+	/* check if we have to do tuning; if so, start */
+	sdstd_3_check_and_do_tuning(sd, CHECK_TUNING_POST_DATA);
+
+	sdstd_unlock(sd);
+	return status;
+}
+
+extern SDIOH_API_RC
+sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr,
+                   uint32 *word, uint nbytes)
+{
+	int status;
+
+	sdstd_lock(sd);
+
+	sdstd_3_check_and_do_tuning(sd, CHECK_TUNING_PRE_DATA);
+
+	/* Change to DATA_TRANSFER_ONGOING , protection against tuning tasklet */
+	sdstd_3_set_data_state(sd, DATA_TRANSFER_ONGOING);
+
+	if (rw == SDIOH_READ) {
+		status = sdstd_card_regread(sd, func, addr, nbytes, word);
+	} else {
+		status = sdstd_card_regwrite(sd, func, addr, nbytes, *word);
+	}
+
+	/* Change to DATA_TRANSFER_IDLE */
+	sdstd_3_set_data_state(sd, DATA_TRANSFER_IDLE);
+
+	/* check if we have to do tuning; if so, start */
+	sdstd_3_check_and_do_tuning(sd, CHECK_TUNING_POST_DATA);
+
+	sdstd_unlock(sd);
+	return (status == SUCCESS ?  SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
+}
+
+#ifdef BCMSDIOH_TXGLOM
+void
+sdioh_glom_post(sdioh_info_t *sd, uint8 *frame, void *pkt, uint len)
+{
+	BCM_REFERENCE(pkt);
+	sd->glom_info.dma_buf_arr[sd->glom_info.count] = frame;
+	sd->glom_info.nbytes[sd->glom_info.count] = len;
+	/* Convert the frame addr to phy addr for DMA in case of host controller version3 */
+	if (sd->txglom_mode == SDPCM_TXGLOM_MDESC) {
+		sd->glom_info.dma_phys_arr[sd->glom_info.count] = DMA_MAP(sd->osh,
+			frame,
+			len,
+			DMA_TX, 0, 0);
+	}
+	sd->glom_info.count++;
+}
+
+void
+sdioh_glom_clear(sdioh_info_t *sd)
+{
+	int i;
+	/* DMA_MAP is done per frame only if host controller version is 3 */
+	if (sd->txglom_mode == SDPCM_TXGLOM_MDESC) {
+		for (i = 0; i < sd->glom_info.count; i++) {
+			DMA_UNMAP(sd->osh,
+				sd->glom_info.dma_phys_arr[i],
+				sd->glom_info.nbytes[i],
+				DMA_TX, 0, 0);
+		}
+	}
+	sd->glom_info.count = 0;
+}
+
+uint
+sdioh_set_mode(sdioh_info_t *sd, uint mode)
+{
+	if (mode == SDPCM_TXGLOM_CPY)
+		sd->txglom_mode = mode;
+	else if ((mode == SDPCM_TXGLOM_MDESC) && (sd->version == HOST_CONTR_VER_3))
+		sd->txglom_mode = mode;
+
+	return (sd->txglom_mode);
+}
+
+bool
+sdioh_glom_enabled(void)
+{
+	return sd_txglom;
+}
+#endif /* BCMSDIOH_TXGLOM */
+
+extern SDIOH_API_RC
+sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint rw, uint func,
+                     uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt)
+{
+	uint8 is_ddr50 = FALSE;
+	int len;
+	int buflen = (int)buflen_u;
+	bool fifo = (fix_inc == SDIOH_DATA_FIX);
+	uint8 *localbuf = NULL, *tmpbuf = NULL;
+	bool local_blockmode = sd->sd_blockmode;
+	SDIOH_API_RC status = SDIOH_API_RC_SUCCESS;
+
+	sdstd_lock(sd);
+
+	is_ddr50 = (sd_uhsimode == SD3CLKMODE_4_DDR50) ? TRUE : FALSE;
+
+	sdstd_3_check_and_do_tuning(sd, CHECK_TUNING_PRE_DATA);
+
+	/* Change to DATA_TRANSFER_ONGOING , protection against tuning tasklet */
+	sdstd_3_set_data_state(sd, DATA_TRANSFER_ONGOING);
+
+	ASSERT(reg_width == 4);
+	ASSERT(buflen_u < (1 << 30));
+	ASSERT(sd->client_block_size[func]);
+
+#ifdef BCMSDIOH_TXGLOM
+	if (sd_txglom) {
+		while (pkt) {
+			sdioh_glom_post(sd, PKTDATA(sd->osh, pkt), pkt, PKTLEN(sd->osh, pkt));
+			pkt = PKTNEXT(sd->osh, pkt);
+		}
+	}
+#endif
+	sd_data(("%s: %c len %d r_cnt %d t_cnt %d, pkt @0x%p\n",
+	         __FUNCTION__, rw == SDIOH_READ ? 'R' : 'W',
+	         buflen_u, sd->r_cnt, sd->t_cnt, pkt));
+
+	/* Break buffer down into blocksize chunks:
+	 * Bytemode: 1 block at a time.
+	 * Blockmode: Multiples of blocksizes at a time w/ max of SD_PAGE.
+	 * Both: leftovers are handled last (will be sent via bytemode).
+	 */
+	while (buflen > 0) {
+		if (local_blockmode) {
+			int max_tran_size = SD_PAGE;
+#ifdef BCMSDIOH_TXGLOM
+			/* There is no alignment requirement for HC3 */
+			if ((sd->version == HOST_CONTR_VER_3) && sd_txglom)
+				max_tran_size = SD_PAGE * 4;
+#endif
+			/* Max xfer is Page size */
+			len = MIN(max_tran_size, buflen);
+
+			/* Round down to a block boundry */
+			if (buflen > sd->client_block_size[func])
+				len = (len/sd->client_block_size[func]) *
+				        sd->client_block_size[func];
+			/* XXX Arasan trashes 3-byte transfers, WAR to add one byte extra. */
+			/* XXX In Case of SDIO3.0 DDR50 mode if no of bytes to be
+			 * transferred is odd append one more byte to make it even.
+			 * Check If odd bytes can come for SDIO_FUNC_2 also.
+			 */
+			if ((func == SDIO_FUNC_1) && (((len % 4) == 3) || (((len % 2) == 1) &&
+			    (is_ddr50))) && ((rw == SDIOH_WRITE) || (rw == SDIOH_READ))) {
+				sd_err(("%s: Rounding up buffer to mod4 length.\n", __FUNCTION__));
+				len++;
+				tmpbuf = buffer;
+				if ((localbuf = (uint8 *)MALLOC(sd->osh, len)) == NULL) {
+					sd_err(("out of memory, malloced %d bytes\n",
+					        MALLOCED(sd->osh)));
+					status = SDIOH_API_RC_FAIL;
+					goto done;
+				}
+				bcopy(buffer, localbuf, len);
+				buffer = localbuf;
+			}
+		} else {
+			/* Byte mode: One block at a time */
+			len = MIN(sd->client_block_size[func], buflen);
+		}
+
+		if (sdstd_card_buf(sd, rw, func, fifo, addr, len, (uint32 *)buffer) != SUCCESS) {
+			status = SDIOH_API_RC_FAIL;
+		}
+
+		/* XXX Restore len and buffer pointer WAR'ed for Arasan 3-byte transfer problem */
+		/* XXX WAR for SDIO3.0 DDR50 mode. */
+		if (local_blockmode && localbuf) {
+			MFREE(sd->osh, localbuf, len);
+			len--;
+			buffer = tmpbuf;
+			sd_err(("%s: Restoring back buffer ptr and len.\n", __FUNCTION__));
+		}
+
+		if (status == SDIOH_API_RC_FAIL) {
+			goto done;
+		}
+
+		buffer += len;
+		buflen -= len;
+		if (!fifo)
+			addr += len;
+#ifdef BCMSDIOH_TXGLOM
+		/* This loop should not come in case of glommed pkts as it is send in
+		 * multiple of blocks or total pkt size less than a block
+		 */
+		if (sd->glom_info.count != 0)
+			buflen = 0;
+#endif
+	}
+done:
+
+	/* Change to DATA_TRANSFER_IDLE */
+	sdstd_3_set_data_state(sd, DATA_TRANSFER_IDLE);
+
+	/* check if we have to do tuning; if so, start */
+	sdstd_3_check_and_do_tuning(sd, CHECK_TUNING_POST_DATA);
+
+	sdstd_unlock(sd);
+
+#ifdef BCMSDIOH_TXGLOM
+	if (sd_txglom)
+		sdioh_glom_clear(sd);
+#endif
+
+	return status;
+}
+
+extern SDIOH_API_RC
+sdioh_gpioouten(sdioh_info_t *sd, uint32 gpio)
+{
+	uint offset = 0;
+	uint16 val;
+
+	/* check if upper bank */
+	if (gpio >= SDH_GPIO16) {
+		gpio -= SDH_GPIO16;
+		offset = 2;
+	}
+
+	val = sdstd_rreg16(sd, SD_GPIO_OE + offset);
+	val |= (1 << gpio);
+	sdstd_wreg16(sd, SD_GPIO_OE + offset, val);
+
+	return SDIOH_API_RC_SUCCESS;
+}
+
+extern SDIOH_API_RC
+sdioh_gpioout(sdioh_info_t *sd, uint32 gpio, bool enab)
+{
+	uint offset = 0;
+	uint16 val;
+
+	/* check if upper bank */
+	if (gpio >= SDH_GPIO16) {
+		gpio -= SDH_GPIO16;
+		offset = 2;
+	}
+
+	val = sdstd_rreg16(sd, SD_GPIO_Reg + offset);
+	if (enab == TRUE)
+		val |= (1 << gpio);
+	else
+		val &= ~(1 << gpio);
+	sdstd_wreg16(sd, SD_GPIO_Reg + offset, val);
+
+	return SDIOH_API_RC_SUCCESS;
+}
+
+extern bool
+sdioh_gpioin(sdioh_info_t *sd, uint32 gpio)
+{
+	uint offset = 0;
+	uint16 val;
+
+	/* check if upper bank */
+	if (gpio >= SDH_GPIO16) {
+		gpio -= SDH_GPIO16;
+		offset = 2;
+	}
+
+	val = sdstd_rreg16(sd, SD_GPIO_Reg + offset);
+	val = (val >> gpio) & 1;
+
+	return (val == 1);
+}
+
+extern SDIOH_API_RC
+sdioh_gpio_init(sdioh_info_t *sd)
+{
+	uint rev;
+
+	rev = sdstd_rreg16(sd, SD_HostControllerVersion) >> 8;
+
+	/* Only P206 (fpga rev >= 16) supports gpio */
+	if (rev < 16) {
+		sd_err(("%s: gpio not supported in rev %d \n", __FUNCTION__, rev));
+		return SDIOH_API_RC_FAIL;
+	}
+
+	sdstd_wreg16(sd, SD_GPIO_Enable, SDH_GPIO_ENABLE);
+	sdstd_wreg16(sd, SD_GPIO_Enable + 2, SDH_GPIO_ENABLE);
+
+	/* Default to input */
+	sdstd_wreg16(sd, SD_GPIO_OE, 0);
+	sdstd_wreg16(sd, SD_GPIO_OE + 2, 0);
+
+	return SDIOH_API_RC_SUCCESS;
+}
+
+extern SDIOH_API_RC
+sdioh_sleep(sdioh_info_t *sd, bool enab)
+{
+	SDIOH_API_RC status;
+	uint32 cmd_arg = 0, rsp1 = 0;
+	int retry = 100;
+
+	sdstd_lock(sd);
+
+	cmd_arg = SFIELD(cmd_arg, CMD14_RCA, sd->card_rca);
+	cmd_arg = SFIELD(cmd_arg, CMD14_SLEEP, enab);
+
+	/*
+	 * For ExitSleep:
+	 *  1) Repeat CMD14 until R1 is received
+	 *  2) Send CMD7
+	 */
+	status = SDIOH_API_RC_FAIL;
+	while (retry-- > 0) {
+		if ((sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_14, cmd_arg)) == SUCCESS) {
+			status = SDIOH_API_RC_SUCCESS;
+			break;
+		}
+		OSL_DELAY(1400);
+	}
+
+	if (status == SDIOH_API_RC_FAIL) {
+		sd_err(("%s: CMD14: failed! enable:%d\n", __FUNCTION__, enab));
+		goto exit;
+	}
+
+	sdstd_cmd_getrsp(sd, &rsp1, 1);
+	sd_info(("%s: CMD14 OK: cmd_resp:0x%x\n", __FUNCTION__, rsp1));
+
+	/* ExitSleep: Send CMD7 After R1 */
+	if (enab == FALSE) {
+		/* Select the card */
+		cmd_arg = SFIELD(0, CMD7_RCA, sd->card_rca);
+		if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_7, cmd_arg)) != SUCCESS) {
+			sd_err(("%s: CMD14 send CMD7 failed!\n", __FUNCTION__));
+			status = SDIOH_API_RC_FAIL;
+			goto exit;
+		}
+
+		sdstd_cmd_getrsp(sd, &rsp1, 1);
+		if (rsp1 != SDIOH_CMD7_EXP_STATUS) {
+			sd_err(("%s: CMD7 response error. Response = 0x%x!\n",
+			        __FUNCTION__, rsp1));
+			status = SDIOH_API_RC_FAIL;
+			goto exit;
+		}
+	}
+
+exit:
+	sdstd_unlock(sd);
+
+	return status;
+}
+
+/* XXX Copied guts of request_byte and cmd_issue.  Might make sense to fold this into
+ * those by passing another parameter indicating command type (abort).  [But maybe
+ * keeping it separate is better -- if called internally on command failure it's less
+ * recursion to wrap your head around?]
+ */
+static int
+sdstd_abort(sdioh_info_t *sd, uint func)
+{
+	int err = 0;
+	int retries;
+
+	uint16 cmd_reg;
+	uint32 cmd_arg;
+	uint32 rsp5;
+	uint8 rflags;
+
+	uint16 int_reg = 0;
+	uint16 plain_intstatus;
+
+	/* Argument is write to F0 (CCCR) IOAbort with function number */
+	cmd_arg = 0;
+	cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, SDIO_FUNC_0);
+	cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, SDIOD_CCCR_IOABORT);
+	cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SD_IO_OP_WRITE);
+	cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0);
+	cmd_arg = SFIELD(cmd_arg, CMD52_DATA, func);
+
+	/* Command is CMD52 write */
+	cmd_reg = 0;
+	cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48_BUSY);
+	cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1);
+	cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1);
+	cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0);
+	cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_ABORT);
+	cmd_reg = SFIELD(cmd_reg, CMD_INDEX, SDIOH_CMD_52);
+
+	/* XXX Copied from cmd_issue(), but no SPI response handling! */
+	if (sd->sd_mode == SDIOH_MODE_SPI) {
+		cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0);
+	}
+
+	/* Wait for CMD_INHIBIT to go away as per spec section 3.6.1.1 */
+	/* XXX For a single-threaded driver, what circumstances would result
+	 * in cmd_inhibit being on but going off in a short time?  Experiment
+	 * shows a HW command timeout doesn't leave inhibit on, so maybe a SW
+	 * timeout?  Then that command should be responsible for clearing...
+	 */
+	retries = RETRIES_SMALL;
+	while (GFIELD(sdstd_rreg(sd, SD_PresentState), PRES_CMD_INHIBIT)) {
+		if (retries == RETRIES_SMALL)
+			sd_err(("%s: Waiting for Command Inhibit, state 0x%08x\n",
+			        __FUNCTION__, sdstd_rreg(sd, SD_PresentState)));
+		if (!--retries) {
+			sd_err(("%s: Command Inhibit timeout, state 0x%08x\n",
+			        __FUNCTION__, sdstd_rreg(sd, SD_PresentState)));
+			if (trap_errs)
+				ASSERT(0);
+			err = BCME_SDIO_ERROR;
+			goto done;
+		}
+	}
+
+	/* Clear errors from any previous commands */
+	if ((plain_intstatus = sdstd_rreg16(sd, SD_ErrorIntrStatus)) != 0) {
+		sd_err(("abort: clearing errstat 0x%04x\n", plain_intstatus));
+		sdstd_wreg16(sd, SD_ErrorIntrStatus, plain_intstatus);
+	}
+	plain_intstatus = sdstd_rreg16(sd, SD_IntrStatus);
+	if (plain_intstatus & ~(SFIELD(0, INTSTAT_CARD_INT, 1))) {
+		sd_err(("abort: intstatus 0x%04x\n", plain_intstatus));
+		if (GFIELD(plain_intstatus, INTSTAT_CMD_COMPLETE)) {
+			sd_err(("SDSTD_ABORT: CMD COMPLETE SET BEFORE COMMAND GIVEN!!!\n"));
+		}
+		if (GFIELD(plain_intstatus, INTSTAT_CARD_REMOVAL)) {
+			sd_err(("SDSTD_ABORT: INTSTAT_CARD_REMOVAL\n"));
+			err = BCME_NODEVICE;
+			goto done;
+		}
+	}
+
+	/* Issue the command */
+	sdstd_wreg(sd, SD_Arg0, cmd_arg);
+	sdstd_wreg16(sd, SD_Command, cmd_reg);
+
+	/* In interrupt mode return, expect later CMD_COMPLETE interrupt */
+	if (!sd->polled_mode)
+		return err;
+
+	/* Otherwise, wait for the command to complete */
+	retries = RETRIES_LARGE;
+	do {
+		int_reg = sdstd_rreg16(sd, SD_IntrStatus);
+	} while (--retries &&
+	         (GFIELD(int_reg, INTSTAT_ERROR_INT) == 0) &&
+	         (GFIELD(int_reg, INTSTAT_CMD_COMPLETE) == 0));
+
+	/* If command completion fails, do a cmd reset and note the error */
+	if (!retries) {
+		sd_err(("%s: CMD_COMPLETE timeout: intr 0x%04x err 0x%04x state 0x%08x\n",
+		        __FUNCTION__, int_reg,
+		        sdstd_rreg16(sd, SD_ErrorIntrStatus),
+		        sdstd_rreg(sd, SD_PresentState)));
+
+		sdstd_wreg8(sd, SD_SoftwareReset, SFIELD(0, SW_RESET_CMD, 1));
+		retries = RETRIES_LARGE;
+		do {
+			sd_trace(("%s: waiting for CMD line reset\n", __FUNCTION__));
+		} while ((GFIELD(sdstd_rreg8(sd, SD_SoftwareReset),
+		                 SW_RESET_CMD)) && retries--);
+
+		if (!retries) {
+			sd_err(("%s: Timeout waiting for CMD line reset\n", __FUNCTION__));
+		}
+
+		if (trap_errs)
+			ASSERT(0);
+
+		err = BCME_SDIO_ERROR;
+	}
+
+	/* Clear Command Complete interrupt */
+	int_reg = SFIELD(0, INTSTAT_CMD_COMPLETE, 1);
+	sdstd_wreg16(sd, SD_IntrStatus, int_reg);
+
+	/* Check for Errors */
+	if ((plain_intstatus = sdstd_rreg16 (sd, SD_ErrorIntrStatus)) != 0) {
+		sd_err(("%s: ErrorintrStatus: 0x%x, "
+		        "(intrstatus = 0x%x, present state 0x%x) clearing\n",
+		        __FUNCTION__, plain_intstatus,
+		        sdstd_rreg16(sd, SD_IntrStatus),
+		        sdstd_rreg(sd, SD_PresentState)));
+
+		sdstd_wreg16(sd, SD_ErrorIntrStatus, plain_intstatus);
+
+		sdstd_wreg8(sd, SD_SoftwareReset, SFIELD(0, SW_RESET_DAT, 1));
+		retries = RETRIES_LARGE;
+		do {
+			sd_trace(("%s: waiting for DAT line reset\n", __FUNCTION__));
+		} while ((GFIELD(sdstd_rreg8(sd, SD_SoftwareReset),
+		                 SW_RESET_DAT)) && retries--);
+
+		if (!retries) {
+			sd_err(("%s: Timeout waiting for DAT line reset\n", __FUNCTION__));
+		}
+
+		if (trap_errs)
+			ASSERT(0);
+
+		/* ABORT is dataless, only cmd errs count */
+		/* XXX But what about busy timeout?  Response valid? */
+		if (plain_intstatus & ERRINT_CMD_ERRS)
+			err = BCME_SDIO_ERROR;
+	}
+
+	/* If command failed don't bother looking at response */
+	if (err)
+		goto done;
+
+	/* Otherwise, check the response */
+	sdstd_cmd_getrsp(sd, &rsp5, 1);
+	rflags = GFIELD(rsp5, RSP5_FLAGS);
+
+	if (rflags & SD_RSP_R5_ERRBITS) {
+		sd_err(("%s: R5 flags include errbits: 0x%02x\n", __FUNCTION__, rflags));
+
+		/* The CRC error flag applies to the previous command */
+		if (rflags & (SD_RSP_R5_ERRBITS & ~SD_RSP_R5_COM_CRC_ERROR)) {
+			err = BCME_SDIO_ERROR;
+			goto done;
+		}
+	}
+
+	if (((rflags & (SD_RSP_R5_IO_CURRENTSTATE0 | SD_RSP_R5_IO_CURRENTSTATE1)) != 0x10) &&
+	    ((rflags & (SD_RSP_R5_IO_CURRENTSTATE0 | SD_RSP_R5_IO_CURRENTSTATE1)) != 0x20)) {
+		sd_err(("%s: R5 flags has bad state: 0x%02x\n", __FUNCTION__, rflags));
+		err = BCME_SDIO_ERROR;
+		goto done;
+	}
+
+	if (GFIELD(rsp5, RSP5_STUFF)) {
+		sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n",
+		        __FUNCTION__, GFIELD(rsp5, RSP5_STUFF)));
+		err = BCME_SDIO_ERROR;
+		goto done;
+	}
+
+done:
+	if (err == BCME_NODEVICE)
+		return err;
+
+	/* XXX As per spec 3.7.1 (and to be safe) do the resets here */
+	sdstd_wreg8(sd, SD_SoftwareReset,
+	            SFIELD(SFIELD(0, SW_RESET_DAT, 1), SW_RESET_CMD, 1));
+
+	retries = RETRIES_LARGE;
+	do {
+		rflags = sdstd_rreg8(sd, SD_SoftwareReset);
+		if (!GFIELD(rflags, SW_RESET_DAT) && !GFIELD(rflags, SW_RESET_CMD))
+			break;
+	} while (--retries);
+
+	if (!retries) {
+		sd_err(("%s: Timeout waiting for DAT/CMD reset: 0x%02x\n",
+		        __FUNCTION__, rflags));
+		err = BCME_SDIO_ERROR;
+	}
+
+	return err;
+}
+
+extern int
+sdioh_abort(sdioh_info_t *sd, uint fnum)
+{
+	int ret;
+
+	sdstd_lock(sd);
+	ret = sdstd_abort(sd, fnum);
+	sdstd_unlock(sd);
+
+	return ret;
+}
+
+int
+sdioh_start(sdioh_info_t *sd, int stage)
+{
+	return SUCCESS;
+}
+
+int
+sdioh_stop(sdioh_info_t *sd)
+{
+	return SUCCESS;
+}
+
+int
+sdioh_waitlockfree(sdioh_info_t *sd)
+{
+	sdstd_waitlockfree(sd);
+	return SUCCESS;
+}
+
+static int
+sdstd_check_errs(sdioh_info_t *sdioh_info, uint32 cmd, uint32 arg)
+{
+	uint16 regval;
+	uint retries;
+	uint function = 0;
+
+	/* If no errors, we're done */
+	if ((regval = sdstd_rreg16(sdioh_info, SD_ErrorIntrStatus)) == 0)
+		return SUCCESS;
+
+#ifdef BCMQT
+	if (regval == 0xFFFF) {
+		/* XXX - Getting bogus errors under QT
+		 * XXX - Not sure why; Just ignore for now
+		 */
+		sd_err(("%s: Bogus SD_ErrorIntrStatus: 0x%x????\n", __FUNCTION__, regval));
+		sdstd_wreg16(sdioh_info, SD_ErrorIntrStatus, regval);
+		return SUCCESS;
+	}
+#endif
+
+	sd_info(("%s: ErrorIntrStatus 0x%04x (clearing), IntrStatus 0x%04x PresentState 0x%08x\n",
+	        __FUNCTION__, regval, sdstd_rreg16(sdioh_info, SD_IntrStatus),
+	        sdstd_rreg(sdioh_info, SD_PresentState)));
+	sdstd_wreg16(sdioh_info, SD_ErrorIntrStatus, regval);
+
+	if (cmd == SDIOH_CMD_14) {
+		if (regval & ERRINT_CMD_TIMEOUT_BIT) {
+			/* PR 101351: sdiod_aos sleep followed by immediate wakeup
+			 *    before sdiod_aos takes over has a problem.
+			 * Getting command timeouts while exiting sleep
+			 * with CMD14. Ignore this error due to this PR.
+			 */
+			regval &= ~ERRINT_CMD_TIMEOUT_BIT;
+		}
+	}
+
+	/* On command error, issue CMD reset */
+	if (regval & ERRINT_CMD_ERRS) {
+		sd_trace(("%s: issuing CMD reset\n", __FUNCTION__));
+		sdstd_wreg8(sdioh_info, SD_SoftwareReset, SFIELD(0, SW_RESET_CMD, 1));
+		for (retries = RETRIES_LARGE; retries; retries--)
+			if (!(GFIELD(sdstd_rreg8(sdioh_info, SD_SoftwareReset), SW_RESET_CMD)))
+				break;
+		if (!retries) {
+			sd_err(("%s: Timeout waiting for CMD line reset\n", __FUNCTION__));
+		}
+	}
+
+	/* On data error, issue DAT reset */
+	if (regval & ERRINT_DATA_ERRS) {
+		if (regval & ERRINT_ADMA_BIT)
+			sd_err(("%s:ADMAError: status:0x%x\n",
+				__FUNCTION__, sdstd_rreg(sdioh_info, SD_ADMA_ErrStatus)));
+		sd_trace(("%s: issuing DAT reset\n", __FUNCTION__));
+		sdstd_wreg8(sdioh_info, SD_SoftwareReset, SFIELD(0, SW_RESET_DAT, 1));
+		for (retries = RETRIES_LARGE; retries; retries--)
+			if (!(GFIELD(sdstd_rreg8(sdioh_info, SD_SoftwareReset), SW_RESET_DAT)))
+				break;
+		if (!retries) {
+			sd_err(("%s: Timeout waiting for DAT line reset\n", __FUNCTION__));
+		}
+	}
+
+	/* For an IO command (CMD52 or CMD53) issue an abort to the appropriate function */
+	if (cmd == SDIOH_CMD_53)
+		function = GFIELD(arg, CMD53_FUNCTION);
+	else if (cmd == SDIOH_CMD_52) {
+		/* PR 101351: sdiod_aos sleep followed by immediate wakeup
+		 *    before sdiod_aos takes over has a problem.
+		 */
+		if (GFIELD(arg, CMD52_REG_ADDR) != F1_SLEEPCSR_ADDR)
+			function = GFIELD(arg, CMD52_FUNCTION);
+	}
+	if (function) {
+		sd_trace(("%s: requesting abort for function %d after cmd %d\n",
+		          __FUNCTION__, function, cmd));
+		sdstd_abort(sdioh_info, function);
+	}
+
+	if (trap_errs)
+		ASSERT(0);
+
+	return ERROR;
+}
+
+/*
+ * Private/Static work routines
+ */
+static bool
+sdstd_reset(sdioh_info_t *sd, bool host_reset, bool client_reset)
+{
+	int retries = RETRIES_LARGE;
+	uchar regval;
+
+	if (!sd)
+		return TRUE;
+
+	sdstd_lock(sd);
+	/* Reset client card */
+	if (client_reset && (sd->adapter_slot != -1)) {
+		if (sdstd_card_regwrite(sd, 0, SDIOD_CCCR_IOABORT, 1, 0x8) != SUCCESS)
+			sd_err(("%s: Cannot write to card reg 0x%x\n",
+			        __FUNCTION__, SDIOD_CCCR_IOABORT));
+		else
+			sd->card_rca = 0;
+	}
+
+	/* Reset host controller */
+	if (host_reset) {
+		regval = SFIELD(0, SW_RESET_ALL, 1);
+		sdstd_wreg8(sd, SD_SoftwareReset, regval);
+		do {
+			sd_trace(("%s: waiting for reset\n", __FUNCTION__));
+		} while ((sdstd_rreg8(sd, SD_SoftwareReset) & regval) && retries--);
+
+		if (!retries) {
+			sd_err(("%s: Timeout waiting for host reset\n", __FUNCTION__));
+			sdstd_unlock(sd);
+			return (FALSE);
+		}
+
+		/* A reset should reset bus back to 1 bit mode */
+		sd->sd_mode = SDIOH_MODE_SD1;
+		sdstd_set_dma_mode(sd, sd->sd_dma_mode);
+	}
+	sdstd_unlock(sd);
+	return TRUE;
+}
+
+/* Disable device interrupt */
+void
+sdstd_devintr_off(sdioh_info_t *sd)
+{
+	sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints));
+	if (sd->use_client_ints) {
+		sd->intmask &= ~CLIENT_INTR;
+		sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask);
+		sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */
+	}
+}
+
+/* Enable device interrupt */
+void
+sdstd_devintr_on(sdioh_info_t *sd)
+{
+	ASSERT(sd->lockcount == 0);
+	sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints));
+	if (sd->use_client_ints) {
+		if (sd->version < HOST_CONTR_VER_3) {
+			uint16 status = sdstd_rreg16(sd, SD_IntrStatusEnable);
+			sdstd_wreg16(sd, SD_IntrStatusEnable, SFIELD(status, INTSTAT_CARD_INT, 0));
+			sdstd_wreg16(sd, SD_IntrStatusEnable, status);
+		}
+
+		sd->intmask |= CLIENT_INTR;
+		sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask);
+		sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */
+	}
+}
+
+#ifdef BCMSDYIELD
+/* Enable/disable other interrupts */
+void
+sdstd_intrs_on(sdioh_info_t *sd, uint16 norm, uint16 err)
+{
+	if (err) {
+		norm = SFIELD(norm, INTSTAT_ERROR_INT, 1);
+		sdstd_wreg16(sd, SD_ErrorIntrSignalEnable, err);
+	}
+
+	sd->intmask |= norm;
+	sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask);
+	if (sd_forcerb)
+		sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */
+}
+
+void
+sdstd_intrs_off(sdioh_info_t *sd, uint16 norm, uint16 err)
+{
+	if (err) {
+		norm = SFIELD(norm, INTSTAT_ERROR_INT, 1);
+		sdstd_wreg16(sd, SD_ErrorIntrSignalEnable, 0);
+	}
+
+	sd->intmask &= ~norm;
+	sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask);
+	if (sd_forcerb)
+		sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */
+}
+#endif /* BCMSDYIELD */
+
+static int
+sdstd_host_init(sdioh_info_t *sd)
+{
+	int 		num_slots, full_slot;
+	uint8		reg8;
+	uint32		card_ins;
+	int		slot, first_bar = 0;
+	bool		detect_slots = FALSE;
+#ifdef _WIN32
+	NDIS_PHYSICAL_ADDRESS	bar;
+#else
+	uint		bar;
+#endif
+
+	/* Check for Arasan ID */
+	if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_SI_IMAGE) {
+		sd_info(("%s: Found Arasan Standard SDIO Host Controller\n", __FUNCTION__));
+		sd->controller_type = SDIOH_TYPE_ARASAN_HDK;
+		detect_slots = TRUE;
+		/* Controller supports SDMA, so turn it on here. */
+		sd->sd_dma_mode = DMA_MODE_SDMA;
+	} else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_BROADCOM) {
+		sd_info(("%s: Found Broadcom 27xx Standard SDIO Host Controller\n", __FUNCTION__));
+		sd->controller_type = SDIOH_TYPE_BCM27XX;
+		detect_slots = FALSE;
+	} else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_TI) {
+		sd_info(("%s: Found TI PCIxx21 Standard SDIO Host Controller\n", __FUNCTION__));
+		sd->controller_type = SDIOH_TYPE_TI_PCIXX21;
+		detect_slots = TRUE;
+	} else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_RICOH) {
+		sd_info(("%s: Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter\n",
+			__FUNCTION__));
+		sd->controller_type = SDIOH_TYPE_RICOH_R5C822;
+		detect_slots = TRUE;
+	} else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_JMICRON) {
+		sd_info(("%s: JMicron Standard SDIO Host Controller\n",
+			__FUNCTION__));
+		sd->controller_type = SDIOH_TYPE_JMICRON;
+		detect_slots = TRUE;
+	} else {
+		return ERROR;
+	}
+
+	/*
+	 * Determine num of slots
+	 * Search each slot
+	 */
+
+	first_bar = OSL_PCI_READ_CONFIG(sd->osh, SD_SlotInfo, 4) & 0x7;
+	num_slots = (OSL_PCI_READ_CONFIG(sd->osh, SD_SlotInfo, 4) & 0xff) >> 4;
+	num_slots &= 7;
+	num_slots++;   	/* map bits to num slots according to spec */
+
+	/* XXX Since the sdio20h core does not present the proper SD_SlotInfo
+	 * register at PCI config space offset 0x40, fake it here.  Also,
+	 * set the BAR0 window to point to the sdio20h core.
+	 */
+	if (OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) ==
+	    ((SDIOH_FPGA_ID << 16) | VENDOR_BROADCOM)) {
+		sd_err(("%s: Found Broadcom Standard SDIO Host Controller FPGA\n", __FUNCTION__));
+		/* Set BAR0 Window to SDIOSTH core */
+		OSL_PCI_WRITE_CONFIG(sd->osh, PCI_BAR0_WIN, 4, 0x18001000);
+
+		/* Set defaults particular to this controller. */
+		detect_slots = TRUE;
+		num_slots = 1;
+		first_bar = 0;
+
+		/* Controller supports ADMA2, so turn it on here. */
+		sd->sd_dma_mode = DMA_MODE_ADMA2;
+	}
+
+	/* Map in each slot on the board and query it to see if a
+	 * card is inserted.  Use the first populated slot found.
+	 */
+	if (sd->mem_space) {
+		sdstd_reg_unmap(sd->osh, (ulong)sd->mem_space, SDIOH_REG_WINSZ);
+		sd->mem_space = NULL;
+	}
+
+	full_slot = -1;
+
+	for (slot = 0; slot < num_slots; slot++) {
+/* XXX :Ugly define, is there a better way */
+#ifdef _WIN32
+		bar.HighPart = 0;
+		bar.LowPart = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0
+		              + (4*(slot + first_bar)), 4);
+		sd->mem_space = (volatile char *)sdstd_reg_map(sd->osh,
+		                                               (int32)&bar, SDIOH_REG_WINSZ);
+#else
+		bar = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(slot + first_bar)), 4);
+		sd->mem_space = (volatile char *)sdstd_reg_map(sd->osh,
+		                                               (uintptr)bar, SDIOH_REG_WINSZ);
+#endif
+
+		sd->adapter_slot = -1;
+
+		if (detect_slots) {
+			card_ins = GFIELD(sdstd_rreg(sd, SD_PresentState), PRES_CARD_PRESENT);
+		} else {
+			card_ins = TRUE;
+		}
+
+		if (card_ins) {
+			sd_info(("%s: SDIO slot %d: Full\n", __FUNCTION__, slot));
+			if (full_slot < 0)
+				full_slot = slot;
+		} else {
+			sd_info(("%s: SDIO slot %d: Empty\n", __FUNCTION__, slot));
+		}
+
+		if (sd->mem_space) {
+			sdstd_reg_unmap(sd->osh, (ulong)sd->mem_space, SDIOH_REG_WINSZ);
+			sd->mem_space = NULL;
+		}
+	}
+
+	if (full_slot < 0) {
+		sd_err(("No slots on SDIO controller are populated\n"));
+		return -1;
+	}
+
+/* XXX :Ugly define, is there a better way */
+#ifdef _WIN32
+	bar.HighPart = 0;
+	bar.LowPart = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(full_slot + first_bar)), 4);
+	sd->mem_space = (volatile char *)sdstd_reg_map(sd->osh, (int32)&bar, SDIOH_REG_WINSZ);
+#else
+	bar = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(full_slot + first_bar)), 4);
+	sd->mem_space = (volatile char *)sdstd_reg_map(sd->osh, (uintptr)bar, SDIOH_REG_WINSZ);
+#endif
+
+	sd_err(("Using slot %d at BAR%d [0x%08x] mem_space 0x%p\n",
+		full_slot,
+		(full_slot + first_bar),
+		OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(full_slot + first_bar)), 4),
+		sd->mem_space));
+
+	sd->adapter_slot = full_slot;
+
+	sd->version = sdstd_rreg16(sd, SD_HostControllerVersion) & 0xFF;
+	switch (sd->version) {
+		case 0:
+			sd_err(("Host Controller version 1.0, Vendor Revision: 0x%02x\n",
+				sdstd_rreg16(sd, SD_HostControllerVersion) >> 8));
+			break;
+		case 1:
+			sd_err(("Host Controller version 2.0, Vendor Revision: 0x%02x\n",
+				sdstd_rreg16(sd, SD_HostControllerVersion) >> 8));
+			break;
+		case 2:
+			sd_err(("Host Controller version 3.0, Vendor Revision: 0x%02x\n",
+				sdstd_rreg16(sd, SD_HostControllerVersion) >> 8));
+			break;
+		default:
+			sd_err(("%s: Host Controller version 0x%02x not supported.\n",
+			    __FUNCTION__, sd->version));
+			break;
+	}
+
+	sd->caps = sdstd_rreg(sd, SD_Capabilities);	/* Cache this for later use */
+	/* MSB 32 bits of caps supported in sdio 3.0 */
+	sd->caps3 = sdstd_rreg(sd, SD_Capabilities3); /* Cache this for later use */
+	sd3_trace(("sd3: %s: caps: 0x%x; MCCap:0x%x\n", __FUNCTION__, sd->caps, sd->curr_caps));
+	sd3_trace(("sd3: %s: caps3: 0x%x\n", __FUNCTION__, sd->caps3));
+	sd->curr_caps = sdstd_rreg(sd, SD_MaxCurCap);
+
+	sd_info(("%s: caps: 0x%x; MCCap:0x%x\n", __FUNCTION__, sd->caps, sd->curr_caps));
+
+	sdstd_set_dma_mode(sd, sd->sd_dma_mode);
+
+	sdstd_reset(sd, 1, 0);
+
+	/* Read SD4/SD1 mode */
+	if ((reg8 = sdstd_rreg8(sd, SD_HostCntrl))) {
+		if (reg8 & SD4_MODE) {
+			sd_err(("%s: Host cntrlr already in 4 bit mode: 0x%x\n",
+			        __FUNCTION__,  reg8));
+		}
+	}
+
+	/* Default power on mode is SD1 */
+	sd->sd_mode = SDIOH_MODE_SD1;
+	sd->polled_mode = TRUE;
+	sd->host_init_done = TRUE;
+	sd->card_init_done = FALSE;
+	sd->adapter_slot = full_slot;
+
+	/* XXX: If sd_uhsimode is disabled, which means that, use the HC in SDIO 2.0 mode. */
+	if (sd_uhsimode == SD3CLKMODE_DISABLED) {
+		sd->version = HOST_CONTR_VER_2;
+		sd3_trace(("%s:forcing to SDIO HC 2.0\n", __FUNCTION__));
+	}
+
+	if (sd->version == HOST_CONTR_VER_3) {
+		/* read host ctrl 2 */
+		uint16 reg16 = 0;
+		sd3_trace(("sd3: %s: HC3: reading additional regs\n", __FUNCTION__));
+
+		reg16 = sdstd_rreg16(sd, SD3_HostCntrl2);
+
+		sd_info(("%s: HCtrl: 0x%x; HCtrl2:0x%x\n", __FUNCTION__, reg8, reg16));
+		BCM_REFERENCE(reg16);
+
+		/* if HC supports 1.8V and one of the SDR/DDR modes, hc uhci support is PRESENT */
+		if ((GFIELD(sd->caps, CAP_VOLT_1_8)) &&
+			(GFIELD(sd->caps3, CAP3_SDR50_SUP) ||
+			GFIELD(sd->caps3, CAP3_SDR104_SUP) ||
+			GFIELD(sd->caps3, CAP3_DDR50_SUP)))
+			sd->host_UHSISupported = 1;
+	}
+
+#ifdef BCMQT
+	{
+		uint32 intmask;
+
+		/* FIX: force interrupts with QT sdio20 host */
+		/* pci cw [expr $def(configbase) +0x95] 1 2 */
+		intmask = OSL_PCI_READ_CONFIG(sd->osh, PCI_INT_MASK, 4);
+		intmask |= 0x0200;
+		OSL_PCI_WRITE_CONFIG(sd->osh, PCI_INT_MASK, 4, intmask);
+	}
+#endif
+	return (SUCCESS);
+}
+#define CMD5_RETRIES 200
+static int
+get_ocr(sdioh_info_t *sd, uint32 *cmd_arg, uint32 *cmd_rsp)
+{
+	int retries, status;
+
+	/* Get the Card's Operation Condition.  Occasionally the board
+	 * takes a while to become ready
+	 */
+	retries = CMD5_RETRIES;
+	do {
+		*cmd_rsp = 0;
+		if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_5, *cmd_arg))
+		    != SUCCESS) {
+			sd_err(("%s: CMD5 failed\n", __FUNCTION__));
+			return status;
+		}
+		sdstd_cmd_getrsp(sd, cmd_rsp, 1);
+		if (!GFIELD(*cmd_rsp, RSP4_CARD_READY))
+			sd_trace(("%s: Waiting for card to become ready\n", __FUNCTION__));
+	} while ((!GFIELD(*cmd_rsp, RSP4_CARD_READY)) && --retries);
+	if (!retries)
+		return ERROR;
+
+	return (SUCCESS);
+}
+
+static int
+sdstd_client_init(sdioh_info_t *sd)
+{
+	uint32 cmd_arg, cmd_rsp;
+	int status;
+	uint8 fn_ints;
+	uint32 regdata;
+	uint16 powerstat = 0;
+
+	sd_trace(("%s: Powering up slot %d\n", __FUNCTION__, sd->adapter_slot));
+
+	/* Clear any pending ints */
+	sdstd_wreg16(sd, SD_IntrStatus, 0x1fff);
+	sdstd_wreg16(sd, SD_ErrorIntrStatus, 0x0fff);
+
+	/* Enable both Normal and Error Status.  This does not enable
+	 * interrupts, it only enables the status bits to
+	 * become 'live'
+	 */
+
+	if (!sd->host_UHSISupported)
+		sdstd_wreg16(sd, SD_IntrStatusEnable, 0x1ff);
+	else
+	{
+		/* INT_x interrupts, but DO NOT enable signalling [enable retuning
+		 * will happen later]
+		 */
+		sdstd_wreg16(sd, SD_IntrStatusEnable, 0x0fff);
+	}
+	sdstd_wreg16(sd, SD_ErrorIntrStatusEnable, 0xffff);
+
+	sdstd_wreg16(sd, SD_IntrSignalEnable, 0);	  /* Disable ints for now. */
+
+	if (sd->host_UHSISupported) {
+		/* when HC is started for SDIO 3.0 mode, start in lowest voltage mode first. */
+		powerstat = sdstd_start_power(sd, 1);
+		if (SDIO_OCR_READ_FAIL == powerstat) {
+			/* This could be because the device is 3.3V, and possible does
+			 * not have sdio3.0 support. So, try in highest voltage
+			 */
+			sd_err(("sdstd_start_power: legacy device: trying highest voltage\n"));
+			sd_err(("%s failed\n", __FUNCTION__));
+			return ERROR;
+		} else if (TRUE != powerstat) {
+			sd_err(("sdstd_start_power failed\n"));
+			return ERROR;
+		}
+	} else
+	/* XXX legacy driver: start in highest voltage mode first.
+	 * CAUTION: trying to start a legacy dhd with sdio3.0HC and sdio3.0 device could
+	 * burn the sdio3.0device if the device has started in 1.8V.
+	 */
+	if (TRUE != sdstd_start_power(sd, 0)) {
+		sd_err(("sdstd_start_power failed\n"));
+		return ERROR;
+	}
+
+	if (sd->num_funcs == 0) {
+		sd_err(("%s: No IO funcs!\n", __FUNCTION__));
+		return ERROR;
+	}
+
+	/* In SPI mode, issue CMD0 first */
+	if (sd->sd_mode == SDIOH_MODE_SPI) {
+		cmd_arg = 0;
+		if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_0, cmd_arg))
+		    != SUCCESS) {
+			sd_err(("BCMSDIOH: cardinit: CMD0 failed!\n"));
+			return status;
+		}
+	}
+
+	if (sd->sd_mode != SDIOH_MODE_SPI) {
+		uint16 rsp6_status;
+
+		/* Card is operational. Ask it to send an RCA */
+		cmd_arg = 0;
+		if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_3, cmd_arg))
+		    != SUCCESS) {
+			sd_err(("%s: CMD3 failed!\n", __FUNCTION__));
+			return status;
+		}
+
+		/* Verify the card status returned with the cmd response */
+		sdstd_cmd_getrsp(sd, &cmd_rsp, 1);
+		rsp6_status = GFIELD(cmd_rsp, RSP6_STATUS);
+		if (GFIELD(rsp6_status, RSP6STAT_COM_CRC_ERROR) ||
+		    GFIELD(rsp6_status, RSP6STAT_ILLEGAL_CMD) ||
+		    GFIELD(rsp6_status, RSP6STAT_ERROR)) {
+			sd_err(("%s: CMD3 response error. Response = 0x%x!\n",
+			        __FUNCTION__, rsp6_status));
+			return ERROR;
+		}
+
+		/* Save the Card's RCA */
+		sd->card_rca = GFIELD(cmd_rsp, RSP6_IO_RCA);
+		sd_info(("RCA is 0x%x\n", sd->card_rca));
+
+		if (rsp6_status)
+			sd_err(("raw status is 0x%x\n", rsp6_status));
+
+		/* Select the card */
+		cmd_arg = SFIELD(0, CMD7_RCA, sd->card_rca);
+		if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_7, cmd_arg))
+		    != SUCCESS) {
+			sd_err(("%s: CMD7 failed!\n", __FUNCTION__));
+			return status;
+		}
+		sdstd_cmd_getrsp(sd, &cmd_rsp, 1);
+		if (cmd_rsp != SDIOH_CMD7_EXP_STATUS) {
+			sd_err(("%s: CMD7 response error. Response = 0x%x!\n",
+			        __FUNCTION__, cmd_rsp));
+			return ERROR;
+		}
+	}
+
+	/* Disable default/power-up device Card Detect (CD) pull up resistor on DAT3
+	 * via CCCR bus interface control register.  Set CD disable bit while leaving
+	 * others alone.
+	 */
+	if (sdstd_card_regread (sd, 0, SDIOD_CCCR_BICTRL, 1, &regdata) != SUCCESS) {
+		sd_err(("Disabling card detect: read of device CCCR BICTRL register failed\n"));
+		return ERROR;
+	}
+	regdata |= BUS_CARD_DETECT_DIS;
+
+	if (sdstd_card_regwrite (sd, 0, SDIOD_CCCR_BICTRL, 1, regdata) != SUCCESS) {
+		sd_err(("Disabling card detect: write of device CCCR BICTRL register failed\n"));
+		return ERROR;
+	}
+
+	sdstd_card_enablefuncs(sd);
+
+	if (!sdstd_bus_width(sd, sd_sdmode)) {
+		sd_err(("sdstd_bus_width failed\n"));
+		return ERROR;
+	}
+
+	set_client_block_size(sd, 1, sd_f1_blocksize);
+	fn_ints = INTR_CTL_FUNC1_EN;
+
+	if (sd->num_funcs >= 2) {
+		/* XXX Device side can't handle 512 yet */
+		set_client_block_size(sd, 2, sd_f2_blocksize /* BLOCK_SIZE_4328 */);
+		fn_ints |= INTR_CTL_FUNC2_EN;
+	}
+
+	/* Enable/Disable Client interrupts */
+	/* Turn on here but disable at host controller? */
+	if (sdstd_card_regwrite(sd, 0, SDIOD_CCCR_INTEN, 1,
+	                        (fn_ints | INTR_CTL_MASTER_EN)) != SUCCESS) {
+		sd_err(("%s: Could not enable ints in CCCR\n", __FUNCTION__));
+		return ERROR;
+	}
+
+	if (sd_uhsimode != SD3CLKMODE_DISABLED) {
+	/* Switch to High-speed clocking mode if both host and device support it */
+		if (sdstd_3_clock_wrapper(sd) != SUCCESS) {
+				sd_err(("sdstd_3_clock_wrapper failed\n"));
+				return ERROR;
+		}
+	} else
+	{
+		if (sdstd_clock_wrapper(sd)) {
+			sd_err(("sdstd_start_clock failed\n"));
+			return ERROR;
+		}
+	}
+	sd->card_init_done = TRUE;
+
+	return SUCCESS;
+}
+
+static int
+sdstd_clock_wrapper(sdioh_info_t *sd)
+{
+	uint ret = 0;
+	sd_trace(("%s:Enter\n", __FUNCTION__));
+	/* After configuring for High-Speed mode, set the desired clock rate. */
+	sdstd_set_highspeed_mode(sd, (bool)sd_hiok);
+
+#ifdef BCMFPGA_HW
+	/*
+	 * To make the SDIO clock 6.25Mhz for FPGA divide the
+	 * standard clock with 8 insted of default 2. 50Mhz/8 = 6.25Mhz
+	 * sdstd_clock_wrapper() is used to start clock for default and
+	 * high speed only.
+	 */
+	sd_err(("%s set 6.25Mhz clock speed for FPGA default or high speed\n", __FUNCTION__));
+	ret = sdstd_start_clock(sd, ((uint16)sd_divisor * 4));
+#else
+	ret = sdstd_start_clock(sd, (uint16)sd_divisor);
+#endif /* BCMFPGA_HW */
+	if (ret != TRUE) {
+		sd_err(("sdstd_start_clock failed\n"));
+		return ERROR;
+	}
+	return SUCCESS;
+}
+
+static int
+sdstd_3_clock_wrapper(sdioh_info_t *sd)
+{
+	int retclk = 0;
+	sd_info(("%s: Enter\n", __FUNCTION__));
+	if (sd->card_UHSI_voltage_Supported) {
+		/* check if clk config requested is supported by both host and target. */
+		retclk = sdstd_3_get_matching_uhsi_clkmode(sd, sd_uhsimode);
+
+		/* if no match for requested caps, try to get the max match possible */
+		if (retclk == -1) {
+			/* if auto enabled */
+			if (sd3_autoselect_uhsi_max == 1) {
+				retclk = sdstd_3_get_matching_uhsi_clkmode(sd, SD3CLKMODE_AUTO);
+				/* still NO match */
+				if (retclk == -1) {
+					/* NO match with HC and card capabilities. Now try the
+					 * High speed/legacy mode if possible.
+					 */
+
+					sd_err(("%s: Not able to set requested clock\n",
+					        __FUNCTION__));
+					return ERROR;
+				}
+			} else {
+				/* means user doesn't want auto clock. So return ERROR */
+				sd_err(("%s: Not able to set requested clock, Try"
+				"auto mode\n", __FUNCTION__));
+				return ERROR;
+			}
+		}
+
+		if (retclk != -1) {
+			/* set the current clk to be selected clock */
+			sd_uhsimode = retclk;
+
+			if (BCME_OK != sdstd_3_set_highspeed_uhsi_mode(sd, sd_uhsimode)) {
+				sd_err(("%s: Not able to set requested clock\n", __FUNCTION__));
+				return ERROR;
+			}
+		} else {
+			/* try legacy mode */
+			if (SUCCESS != sdstd_clock_wrapper(sd)) {
+				sd_err(("sdstd_start_clock failed\n"));
+				return ERROR;
+			}
+		}
+	} else {
+		sd_info(("%s: Legacy Mode Clock\n", __FUNCTION__));
+		/* try legacy mode */
+		if (SUCCESS != sdstd_clock_wrapper(sd)) {
+			sd_err(("%s sdstd_clock_wrapper failed\n", __FUNCTION__));
+			return ERROR;
+		}
+	}
+	return SUCCESS;
+}
+
+int
+sdstd_3_clk_tuning(sdioh_info_t *sd, uint32 sd3ClkMode)
+{
+	int status, lcount = 0, brr_count = 0;
+	uint16 val1 = 0, bufready = 0;
+	uint32 val2 = 0;
+	uint8 phase_info_local = 0;
+
+	sd3_trace(("sd3: %s: Enter\n", __FUNCTION__));
+	/* if (NOT SDR104) OR
+	 *	(SDR_50 AND sdr50_tuning_reqd is NOT enabled)
+	 * return success, as tuning not reqd.
+	 */
+	if (!sd->sd3_tuning_reqd) {
+		sd_info(("%s: Tuning NOT reqd!\n", __FUNCTION__));
+		return SUCCESS;
+	}
+
+	/* execute tuning procedure */
+
+	/* enable Buffer ready  status. [donot enable the interrupt right now] */
+	/* Execute tuning */
+	sd_trace(("sd3: %s: Execute tuning\n", __FUNCTION__));
+	val1 = sdstd_rreg16(sd, SD3_HostCntrl2);
+	val1 = SFIELD(val1, HOSTCtrl2_EXEC_TUNING, 1);
+	sdstd_wreg16(sd, SD3_HostCntrl2, val1);
+
+	do {
+		sd3_trace(("sd3: %s: cmd19 issue\n", __FUNCTION__));
+		/* Issue cmd19 */
+		if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_19, 0))
+			!= SUCCESS) {
+			sd_err(("%s: CMD19 failed\n", __FUNCTION__));
+			val1 = sdstd_rreg16(sd, SD3_HostCntrl2);
+			val1 = SFIELD(val1, HOSTCtrl2_EXEC_TUNING, 0);
+			val1 = SFIELD(val1, HOSTCtrl2_SAMPCLK_SEL, 0);
+			sdstd_wreg16(sd, SD3_HostCntrl2, val1);
+			return status;
+		}
+
+		/* wait for buffer read ready */
+		brr_count = 0;
+		do {
+			bufready = sdstd_rreg16(sd, SD_IntrStatus);
+
+			if (GFIELD(bufready, INTSTAT_BUF_READ_READY))
+				break;
+
+			/* delay after checking bufready becuase INTSTAT_BUF_READ_READY
+			   might have been most likely set already in the first check
+			*/
+			OSL_DELAY(1);
+		} while (++brr_count < CLKTUNING_MAX_BRR_RETRIES);
+
+		/* buffer read ready timedout */
+		if (brr_count == CLKTUNING_MAX_BRR_RETRIES) {
+			sd_err(("%s: TUNINGFAILED: BRR response timedout!\n",
+				__FUNCTION__));
+			val1 = sdstd_rreg16(sd, SD3_HostCntrl2);
+			val1 = SFIELD(val1, HOSTCtrl2_EXEC_TUNING, 0);
+			val1 = SFIELD(val1, HOSTCtrl2_SAMPCLK_SEL, 0);
+			sdstd_wreg16(sd, SD3_HostCntrl2, val1);
+			return ERROR;
+		}
+
+		/* In response to CMD19 card will send 64 magic bytes.
+		 * Current Aizyc HC h/w doesn't auto clear those bytes.
+		 * So read 64 bytes send by card.
+		 * Aizyc need to implement in hw to do an auto clear.
+		*/
+		if (sd3_sw_read_magic_bytes == TRUE)
+		{
+			uint8 l_cnt_1 = 0;
+			uint32 l_val_1 = 0;
+			for (l_cnt_1 = 0; l_cnt_1 < 16; l_cnt_1++) {
+				l_val_1 = sdstd_rreg(sd, SD_BufferDataPort0);
+				sd_trace(("%s:l_val_1 = 0x%x", __FUNCTION__, l_val_1));
+			}
+			BCM_REFERENCE(l_val_1);
+		}
+
+		/* clear BuffReadReady int */
+		bufready = SFIELD(bufready, INTSTAT_BUF_READ_READY, 1);
+		sdstd_wreg16(sd, SD_IntrStatus, bufready);
+
+		/* wait before continuing */
+		/* OSL_DELAY(PER_TRY_TUNING_DELAY_MS * 1000); */ /* Not required */
+
+		/* check execute tuning bit */
+		val1 = sdstd_rreg16(sd, SD3_HostCntrl2);
+		if (!GFIELD(val1, HOSTCtrl2_EXEC_TUNING)) {
+			/* done tuning, break from loop */
+			break;
+		}
+
+		/* max tuning iterations exceeded */
+		if (lcount++ > MAX_TUNING_ITERS) {
+			sd_err(("%s: TUNINGFAILED: Max tuning iterations"
+				"exceeded!\n", __FUNCTION__));
+			val1 = sdstd_rreg16(sd, SD3_HostCntrl2);
+			val1 = SFIELD(val1, HOSTCtrl2_EXEC_TUNING, 0);
+			val1 = SFIELD(val1, HOSTCtrl2_SAMPCLK_SEL, 0);
+			sdstd_wreg16(sd, SD3_HostCntrl2, val1);
+			return ERROR;
+		}
+	} while (1);
+
+	val2 = sdstd_rreg(sd, SD3_Tuning_Info_Register);
+	phase_info_local = ((val2>>15)& 0x7);
+	sd_info(("Phase passed info: 0x%x\n", (val2>>8)& 0x3F));
+	sd_info(("Phase selected post tune: 0x%x\n", phase_info_local));
+
+	if (phase_info_local > SDSTD_MAX_TUNING_PHASE) {
+		sd_err(("!!Phase selected:%x\n", phase_info_local));
+	}
+
+	/* check sampling clk select */
+	val1 = sdstd_rreg16(sd, SD3_HostCntrl2);
+	if (!GFIELD(val1, HOSTCtrl2_SAMPCLK_SEL)) {
+		/* error in selecting clk */
+		sd_err(("%s: TUNINGFAILED: SamplClkSel failed!\n", __FUNCTION__));
+		val1 = sdstd_rreg16(sd, SD3_HostCntrl2);
+		val1 = SFIELD(val1, HOSTCtrl2_EXEC_TUNING, 0);
+		val1 = SFIELD(val1, HOSTCtrl2_SAMPCLK_SEL, 0);
+		sdstd_wreg16(sd, SD3_HostCntrl2, val1);
+		return ERROR;
+	}
+/* done: */
+	sd_info(("%s: TUNING Success!\n", __FUNCTION__));
+	return SUCCESS;
+}
+
+void
+sdstd_3_enable_retuning_int(sdioh_info_t *sd)
+{
+	uint16 raw_int;
+	unsigned long flags;
+
+	sdstd_os_lock_irqsave(sd, &flags);
+	raw_int = sdstd_rreg16(sd, SD_IntrSignalEnable);
+	sdstd_wreg16(sd, SD_IntrSignalEnable, (raw_int | HC_INTR_RETUNING));
+	/* Enable retuning status */
+	raw_int = sdstd_rreg16(sd, SD_IntrStatusEnable);
+	sdstd_wreg16(sd, SD_IntrStatusEnable, (raw_int | HC_INTR_RETUNING));
+	sdstd_os_unlock_irqrestore(sd, &flags);
+}
+
+void
+sdstd_3_disable_retuning_int(sdioh_info_t *sd)
+{
+	uint16 raw_int;
+	unsigned long flags;
+
+	sdstd_os_lock_irqsave(sd, &flags);
+	sd->intmask &= ~HC_INTR_RETUNING;
+	raw_int = sdstd_rreg16(sd, SD_IntrSignalEnable);
+	sdstd_wreg16(sd, SD_IntrSignalEnable, (raw_int & (~HC_INTR_RETUNING)));
+	/* Disable retuning status */
+	raw_int = sdstd_rreg16(sd, SD_IntrStatusEnable);
+	sdstd_wreg16(sd, SD_IntrStatusEnable, (raw_int & (~HC_INTR_RETUNING)));
+	sdstd_os_unlock_irqrestore(sd, &flags);
+}
+
+bool
+sdstd_3_is_retuning_int_set(sdioh_info_t *sd)
+{
+	uint16 raw_int;
+
+	raw_int = sdstd_rreg16(sd, SD_IntrStatus);
+
+	if (GFIELD(raw_int, INTSTAT_RETUNING_INT))
+		return TRUE;
+
+	return FALSE;
+}
+
+/*
+	Assumption: sd3ClkMode is checked to be present in both host/card
+	capabilities before entering this function. VALID values for sd3ClkMode
+	in this function: SD3CLKMODE_2, 3, 4 [0 and 1 NOT supported as
+	they are legacy] For that, need to call
+	sdstd_3_get_matching_uhsi_clkmode()
+*/
+static int
+sdstd_3_set_highspeed_uhsi_mode(sdioh_info_t *sd, int sd3ClkMode)
+{
+	uint32 drvstrn;
+	int status;
+	uint8 hc_reg8;
+	uint16 val1 = 0, presetval = 0;
+	uint32 regdata;
+	uint32 ret = 0;
+
+	sd3_trace(("sd3: %s:enter:clkmode:%d\n", __FUNCTION__, sd3ClkMode));
+
+	hc_reg8 = sdstd_rreg8(sd, SD_HostCntrl);
+
+	if (HOST_SDR_UNSUPP == sd->global_UHSI_Supp) {
+		sd_err(("%s:Trying to set clk with unsupported global support\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	/* get [double check, as this is already done in
+		sdstd_3_get_matching_uhsi_clkmode] drvstrn
+	*/
+	if (!sdstd_3_get_matching_drvstrn(sd, sd3ClkMode, &drvstrn, &presetval)) {
+		sd_err(("%s:DRVStrn mismatch!: card strn:0x%x; HC preset"
+			"val:0x%x\n", __FUNCTION__, drvstrn, presetval));
+		return BCME_SDIO_ERROR;
+	}
+
+	/* also set driver type select in CCCR */
+	if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_DRIVER_STRENGTH,
+		1, drvstrn)) != BCME_OK) {
+		sd_err(("%s:Setting SDIOD_CCCR_DRIVER_STRENGTH in card Failed!\n", __FUNCTION__));
+		return BCME_SDIO_ERROR;
+	}
+
+	/* ********** change Bus speed select in device */
+	if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
+	                                 1, &regdata)) != SUCCESS) {
+		sd_err(("%s:FAILED 1\n", __FUNCTION__));
+		return BCME_SDIO_ERROR;
+	}
+	sd_info(("Attempting to change BSS.current val:0x%x\n", regdata));
+
+	if (regdata & SDIO_SPEED_SHS) {
+		sd_info(("Device supports High-Speed mode.\n"));
+		/* clear existing BSS */
+		regdata &= ~0xE;
+
+		regdata |= (sd3ClkMode << 1);
+
+		sd_info(("Writing %08x to Card at %08x\n",
+		         regdata, SDIOD_CCCR_SPEED_CONTROL));
+		if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
+		                                  1, regdata)) != BCME_OK) {
+			sd_err(("%s:FAILED 2\n", __FUNCTION__));
+			return BCME_SDIO_ERROR;
+		}
+
+		if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
+		                                 1, &regdata)) != BCME_OK) {
+			sd_err(("%s:FAILED 3\n", __FUNCTION__));
+			return BCME_SDIO_ERROR;
+		}
+
+		sd_info(("Read %08x from Card at %08x\n", regdata, SDIOD_CCCR_SPEED_CONTROL));
+	}
+	else {
+		sd_err(("Device does not support High-Speed Mode.\n"));
+	}
+
+	/* SD Clock Enable = 0 */
+	sdstd_wreg16(sd, SD_ClockCntrl,
+		sdstd_rreg16(sd, SD_ClockCntrl) & ~((uint16)0x4));
+
+	/* set to HighSpeed mode */
+	/* TBD: is these to change SD_HostCntrl reqd for UHSI? */
+	hc_reg8 = SFIELD(hc_reg8, HOST_HI_SPEED_EN, 1);
+	sdstd_wreg8(sd, SD_HostCntrl, hc_reg8);
+
+	/* set UHS Mode select in HC2 and also set preset */
+	val1 = sdstd_rreg16(sd, SD3_HostCntrl2);
+	val1 = SFIELD(val1, HOSTCtrl2_UHSMODE_SEL, sd3ClkMode);
+	if (TRUE != sd3_sw_override1) {
+		val1 = SFIELD(val1, HOSTCtrl2_PRESVAL_EN, 1);
+	} else {
+		/* set hC registers manually using the retreived values */
+		/* *set drvstrn */
+		val1 = SFIELD(val1, HOSTCtrl2_DRIVSTRENGTH_SEL,
+			GFIELD(presetval, PRESET_DRIVR_SELECT));
+		val1 = SFIELD(val1, HOSTCtrl2_PRESVAL_EN, 0);
+	}
+
+	/* finally write Hcontrol2 */
+	sdstd_wreg16(sd, SD3_HostCntrl2, val1);
+
+	sd_err(("%s:HostCtrl2 final value:0x%x\n", __FUNCTION__, val1));
+#ifdef BCMFPGA_HW
+	/*
+	 * To make the SDIO clock 6.25Mhz for FPGA divide the
+	 * standard clock with 0x20. 208Mhz/32 = 6.25Mhz
+	 * this function is invoked to start clock for UHSI mode only
+	 */
+	sd_err(("%s set 6.25Mhz clock speed for UHSI speed\n", __FUNCTION__));
+	ret = sdstd_start_clock(sd, 0x20);
+#else
+	ret = sdstd_start_clock(sd, GFIELD(presetval, PRESET_CLK_DIV));
+#endif /* BCMFPGA_HW */
+	if (ret != TRUE) {
+	/* start clock : clk will be enabled inside. */
+		sd_err(("sdstd_start_clock failed\n"));
+		return ERROR;
+	}
+
+	/* execute first tuning procedure */
+	if (!sd3_sw_override1) {
+		if (SD3_TUNING_REQD(sd, sd3ClkMode)) {
+			sd_err(("%s: Tuning start..\n", __FUNCTION__));
+			sd->sd3_tuning_reqd = TRUE;
+			/* TBD: first time: enabling INT's could be problem? */
+			sdstd_3_start_tuning(sd);
+		}
+		else
+			sd->sd3_tuning_reqd = FALSE;
+	}
+
+	return BCME_OK;
+}
+
+/* Check & do tuning if required */
+void sdstd_3_check_and_do_tuning(sdioh_info_t *sd, int tuning_param)
+{
+	int retries = 0;
+
+	if (!sd->sd3_tuning_disable && sd->sd3_tuning_reqd) {
+		sd3_trace(("sd3: %s: tuning reqd\n", __FUNCTION__));
+			if (tuning_param == CHECK_TUNING_PRE_DATA) {
+			if (sd->sd3_tun_state == TUNING_ONGOING) {
+				retries = RETRIES_SMALL;
+				/* check if tuning is already going on */
+				while ((GFIELD(sdstd_rreg(sd, SD3_HostCntrl2),
+					HOSTCtrl2_EXEC_TUNING)) && retries--) {
+					if (retries == RETRIES_SMALL)
+						sd_err(("%s: Waiting for Tuning to complete\n",
+						__FUNCTION__));
+				}
+
+				if (!retries) {
+					sd_err(("%s: Tuning wait timeout\n", __FUNCTION__));
+					if (trap_errs)
+						ASSERT(0);
+				}
+			} else if (sd->sd3_tun_state == TUNING_START) {
+				/* check and start tuning if required. */
+				sd3_trace(("sd3 : %s : Doing Tuning before Data Transfer\n",
+					__FUNCTION__));
+				sdstd_3_start_tuning(sd);
+			}
+		} else if (tuning_param == CHECK_TUNING_POST_DATA) {
+			if (sd->sd3_tun_state == TUNING_START_AFTER_DAT) {
+				sd3_trace(("sd3: %s: tuning start\n", __FUNCTION__));
+				/* check and start tuning if required. */
+				sdstd_3_start_tuning(sd);
+			}
+		}
+	}
+}
+/* Need to run this function in interrupt-disabled context */
+bool sdstd_3_check_and_set_retuning(sdioh_info_t *sd)
+{
+	sd3_trace(("sd3: %s:\n", __FUNCTION__));
+
+	/* if already initiated, just return without anything */
+	if ((sd->sd3_tun_state == TUNING_START) ||
+		(sd->sd3_tun_state == TUNING_ONGOING) ||
+		(sd->sd3_tun_state == TUNING_START_AFTER_DAT)) {
+		/* do nothing */
+		return FALSE;
+	}
+
+	if (sd->sd3_dat_state == DATA_TRANSFER_IDLE) {
+		sd->sd3_tun_state = TUNING_START; /* tuning to be started by the tasklet */
+		return TRUE;
+	} else {
+		/* tuning to be started after finishing the existing data transfer */
+		sd->sd3_tun_state = TUNING_START_AFTER_DAT;
+	}
+	return FALSE;
+}
+
+int sdstd_3_get_data_state(sdioh_info_t *sd)
+{
+	return sd->sd3_dat_state;
+}
+
+void sdstd_3_set_data_state(sdioh_info_t *sd, int state)
+{
+	sd->sd3_dat_state = state;
+}
+
+int sdstd_3_get_tune_state(sdioh_info_t *sd)
+{
+	return sd->sd3_tun_state;
+}
+
+void sdstd_3_set_tune_state(sdioh_info_t *sd, int state)
+{
+	sd->sd3_tun_state = state;
+}
+
+uint8 sdstd_3_get_tuning_exp(sdioh_info_t *sd)
+{
+	if (sd_tuning_period == CAP3_RETUNING_TC_OTHER) {
+		return GFIELD(sd->caps3, CAP3_RETUNING_TC);
+	} else {
+		return (uint8)sd_tuning_period;
+	}
+}
+
+uint32 sdstd_3_get_uhsi_clkmode(sdioh_info_t *sd)
+{
+	return sd_uhsimode;
+}
+
+/* check, to see if the card supports driver_type corr to the driver_type
+	in preset value, which will be selected by requested UHSI mode
+    input:
+	clk mode: valid values: SD3CLKMODE_2_SDR50, SD3CLKMODE_3_SDR104,
+			SD3CLKMODE_4_DDR50, SD3CLKMODE_AUTO
+    outputs:
+	return_val: 	TRUE; if a matching drvstrn for the given clkmode is
+		found in both HC and card. otherwise, FALSE.
+		[other outputs below valid ONLY if return_val is TRUE]
+	drvstrn	:      driver strength read from CCCR.
+	presetval: 	value of preset reg, corr to the clkmode.
+ */
+static bool
+sdstd_3_get_matching_drvstrn(sdioh_info_t *sd, int sd3_requested_clkmode,
+	uint32 *drvstrn, uint16 *presetval)
+{
+	int status;
+	uint8 presetreg;
+	uint8 cccr_reqd_dtype_mask = 1;
+
+	sd3_trace(("sd3: %s:\n", __FUNCTION__));
+
+	if (sd3_requested_clkmode != SD3CLKMODE_AUTO) {
+		/* CARD: get the card driver strength from cccr */
+		if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_DRIVER_STRENGTH,
+			1, drvstrn)) != BCME_OK) {
+			sd_err(("%s:Reading SDIOD_CCCR_DRIVER_STRENGTH from card"
+				"Failed!\n", __FUNCTION__));
+			return FALSE;
+		}
+		if (TRUE != sd3_sw_override1) {
+		/* HOSTC: get the addr of preset register indexed by the clkmode */
+		presetreg = SD3_PresetValStart +
+			(2*sd3_requested_clkmode + 6);
+		*presetval = sdstd_rreg16(sd, presetreg);
+		} else {
+			/* Note: +3 for mapping between SD3CLKMODE_xxx and presetval_sw_table */
+			*presetval = presetval_sw_table[sd3_requested_clkmode + 3];
+		}
+		sd_err(("%s:reqCLK: %d, presetval: 0x%x\n",
+			__FUNCTION__, sd3_requested_clkmode, *presetval));
+
+		cccr_reqd_dtype_mask <<= GFIELD(*presetval, PRESET_DRIVR_SELECT);
+
+		/* compare/match */
+		if (!(cccr_reqd_dtype_mask & GFIELD(*drvstrn, SDIO_BUS_DRVR_TYPE_CAP))) {
+			sd_err(("%s:cccr_reqd_dtype_mask and SDIO_BUS_DRVR_TYPE_CAP"
+				"not matching!:reqd:0x%x, cap:0x%x\n", __FUNCTION__,
+				cccr_reqd_dtype_mask, GFIELD(*drvstrn, SDIO_BUS_DRVR_TYPE_CAP)));
+			return FALSE;
+		} else {
+			/* check if drive strength override is required. If so, first setit */
+			if (*dhd_sdiod_uhsi_ds_override != DRVSTRN_IGNORE_CHAR) {
+				int ds_offset = 0;
+				uint32 temp = 0;
+
+				/* drvstrn to reflect the preset val: this is default */
+				*drvstrn = GFIELD(*presetval, PRESET_DRIVR_SELECT);
+
+				/* now check override */
+				ds_offset = (((int)DRVSTRN_MAX_CHAR -
+					(int)(*dhd_sdiod_uhsi_ds_override)));
+				if ((ds_offset >= 0) && (ds_offset <= MAX_DTS_INDEX)) {
+					ds_offset = MAX_DTS_INDEX - ds_offset;
+					sd_err(("%s:Drive strength override: %c, offset: "
+						"%d, val: %d\n", __FUNCTION__,
+						*dhd_sdiod_uhsi_ds_override,
+						ds_offset, DTS_vals[ds_offset]));
+					temp = SFIELD(*drvstrn, SDIO_BUS_DRVR_TYPE_SEL,
+						DTS_vals[ds_offset]);
+					sd_err(("%s:DrvStrn orig: 0x%x, modif: 0x%x\n",
+						__FUNCTION__, *drvstrn, temp));
+					*drvstrn = temp;
+				} else {
+					/* else case is default: use preset val */
+					sd_err(("%s:override invalid: DrvStrn is from "
+						"preset: 0x%x\n",
+						__FUNCTION__, *drvstrn));
+				}
+			} else {
+				sd_err(("%s:DrvStrn is from preset: 0x%x\n",
+					__FUNCTION__, *drvstrn));
+			}
+		}
+	} else {
+		/* TBD check for sd3_requested_clkmode : -1 also.  */
+		sd_err(("%s: Automode not supported!\n", __FUNCTION__));
+		return FALSE;
+	}
+	return TRUE;
+}
+
+/* Returns a matching UHSI clk speed is found. If not, returns -1.
+	Also, if  sd3_requested_clkmode is -1, finds the closest max match clk and returns.
+ */
+static int
+sdstd_3_get_matching_uhsi_clkmode(sdioh_info_t *sd, int sd3_requested_clkmode)
+{
+	uint32 card_val_uhsisupp;
+	uint8 speedmask = 1;
+	uint32 drvstrn;
+	uint16 presetval;
+	int status;
+
+	sd3_trace(("sd3: %s:\n", __FUNCTION__));
+
+	sd->global_UHSI_Supp = HOST_SDR_UNSUPP;
+
+	/* for legacy/25MHz/50MHz bus speeds, no checks done here */
+	if ((sd3_requested_clkmode == SD3CLKMODE_0_SDR12) ||
+		(sd3_requested_clkmode == SD3CLKMODE_1_SDR25)) {
+		sd->global_UHSI_Supp = HOST_SDR_12_25;
+		return sd3_requested_clkmode;
+	}
+	/* get cap of card */
+	if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_UHSI_SUPPORT,
+	                                 1, &card_val_uhsisupp)) != BCME_OK) {
+		sd_err(("%s:SDIOD_CCCR_UHSI_SUPPORT query failed!\n", __FUNCTION__));
+		return -1;
+	}
+	sd_info(("%s:Read %08x from Card at %08x\n", __FUNCTION__,
+		card_val_uhsisupp, SDIOD_CCCR_UHSI_SUPPORT));
+
+	if (sd3_requested_clkmode != SD3CLKMODE_AUTO) {
+		/* Note: it is assumed that, following are executed when (sd3ClkMode >= 2) */
+		speedmask <<= (sd3_requested_clkmode - SD3CLKMODE_2_SDR50);
+
+		/* check first about 3.0 HS CLK modes */
+		if (!(GFIELD(sd->caps3, CAP3_30CLKCAP) & speedmask)) {
+			sd_err(("%s:HC does not support req 3.0 UHSI mode."
+				"requested:%d; capable:0x%x\n", __FUNCTION__,
+				sd3_requested_clkmode, GFIELD(sd->caps3, CAP3_30CLKCAP)));
+			return -1;
+		}
+
+		/* check first about 3.0 CARD CLK modes */
+		if (!(GFIELD(card_val_uhsisupp, SDIO_BUS_SPEED_UHSICAP) & speedmask)) {
+			sd_err(("%s:Card does not support req 3.0 UHSI mode. requested:%d;"
+				"capable:0x%x\n", __FUNCTION__, sd3_requested_clkmode,
+				GFIELD(card_val_uhsisupp, SDIO_BUS_SPEED_UHSICAP)));
+			return -1;
+		}
+
+		/* check, to see if the card supports driver_type corr to the
+			driver_type in preset value, which will be selected by
+			requested UHSI mode
+		*/
+		if (!sdstd_3_get_matching_drvstrn(sd, sd3_requested_clkmode,
+			&drvstrn, &presetval)) {
+			sd_err(("%s:DRVStrn mismatch!: card strn:0x%x; HC preset"
+				"val:0x%x\n", __FUNCTION__, drvstrn, presetval));
+			return -1;
+		}
+		/* success path. change the support variable accordingly */
+		sd->global_UHSI_Supp = HOST_SDR_50_104_DDR;
+		return sd3_requested_clkmode;
+	} else {
+		/* auto clk selection: get the highest clock capable by both card and HC */
+/* TBD		TOBE DONE */
+/* 		sd->global_UHSI_Supp = TRUE; on success */
+		return -1;
+	}
+}
+
+static int
+sdstd_3_sigvoltswitch_proc(sdioh_info_t *sd)
+{
+	int status;
+	uint32 cmd_rsp = 0, presst;
+	uint16 val1 = 0;
+
+	sd3_trace(("sd3: %s:\n", __FUNCTION__));
+
+	/* Issue cmd11 */
+	if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_11, 0))
+		!= SUCCESS) {
+		sd_err(("%s: CMD11 failed\n", __FUNCTION__));
+		return status;
+	}
+
+	/* check response */
+	sdstd_cmd_getrsp(sd, &cmd_rsp, 1);
+	if (
+		GFIELD(cmd_rsp, RSP1_ERROR) ||	/*  bit 19 */
+		GFIELD(cmd_rsp, RSP1_ILLEGAL_CMD) ||	/*  bit 22 */
+		GFIELD(cmd_rsp, RSP1_COM_CRC_ERROR) ||	/*  bit 23 */
+		GFIELD(cmd_rsp, RSP1_CARD_LOCKED)	/*  bit 25 */	) {
+		sd_err(("%s: FAIL:CMD11: cmd_resp:0x%x\n", __FUNCTION__, cmd_rsp));
+		return ERROR;
+	}
+
+	/* SD Clock Enable = 0 */
+	sdstd_wreg16(sd, SD_ClockCntrl,
+	             sdstd_rreg16(sd, SD_ClockCntrl) & ~((uint16)0x4));
+
+	/* check DAT[3..0] using Present State Reg. If not 0, error */
+	presst = sdstd_rreg(sd, SD_PresentState);
+	if (0 != GFIELD(presst, PRES_DAT_SIGNAL)) {
+		sd_err(("%s: FAIL: PRESTT:0x%x\n", __FUNCTION__, presst));
+		return ERROR;
+	}
+
+	/* turn 1.8V sig enable in HC2 */
+	val1 = sdstd_rreg16(sd, SD3_HostCntrl2);
+	val1 = SFIELD(val1, HOSTCtrl2_1_8SIG_EN, 1);
+	sdstd_wreg16(sd, SD3_HostCntrl2, val1);
+
+	/* wait 5ms */
+	OSL_DELAY(5000);
+
+	/* check 1.8V sig enable in HC2. if cleared, error */
+	val1 = sdstd_rreg16(sd, SD3_HostCntrl2);
+
+	if (!GFIELD(val1, HOSTCtrl2_1_8SIG_EN)) {
+		sd_err(("%s: FAIL: HC2:1.8V_En:0x%x\n", __FUNCTION__, val1));
+		return ERROR;
+	}
+
+	/* SD Clock Enable = 1 */
+	val1 = sdstd_rreg16(sd, SD_ClockCntrl);
+	sdstd_wreg16(sd, SD_ClockCntrl, val1 | 0x4);
+
+	/* wait 1ms */
+	OSL_DELAY(1000);
+
+	/* check DAT[3..0] using Present State Reg. If not 0b1111, error */
+	presst = sdstd_rreg(sd, SD_PresentState);
+	if (0xf != GFIELD(presst, PRES_DAT_SIGNAL)) {
+		sd_err(("%s: FAIL: PRESTT_FINAL:0x%x\n", __FUNCTION__, presst));
+		return ERROR;
+	}
+
+	return (SUCCESS);
+}
+
+static int
+sdstd_set_highspeed_mode(sdioh_info_t *sd, bool HSMode)
+{
+	uint32 regdata;
+	int status;
+	uint8 reg8;
+
+	uint32 drvstrn;
+
+	reg8 = sdstd_rreg8(sd, SD_HostCntrl);
+
+	if (HSMode == TRUE) {
+		if (sd_hiok && (GFIELD(sd->caps, CAP_HIGHSPEED)) == 0) {
+			sd_err(("Host Controller does not support hi-speed mode.\n"));
+			return BCME_ERROR;
+		}
+
+		sd_info(("Attempting to enable High-Speed mode.\n"));
+
+		if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
+		                                 1, &regdata)) != SUCCESS) {
+			return BCME_SDIO_ERROR;
+		}
+		if (regdata & SDIO_SPEED_SHS) {
+			sd_info(("Device supports High-Speed mode.\n"));
+
+			regdata |= SDIO_SPEED_EHS;
+
+			sd_info(("Writing %08x to Card at %08x\n",
+			         regdata, SDIOD_CCCR_SPEED_CONTROL));
+			if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
+			                                  1, regdata)) != BCME_OK) {
+				return BCME_SDIO_ERROR;
+			}
+
+			if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
+			                                 1, &regdata)) != BCME_OK) {
+				return BCME_SDIO_ERROR;
+			}
+
+			sd_info(("Read %08x to Card at %08x\n", regdata, SDIOD_CCCR_SPEED_CONTROL));
+
+			reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 1);
+
+			sd_err(("High-speed clocking mode enabled.\n"));
+		}
+		else {
+			sd_err(("Device does not support High-Speed Mode.\n"));
+			reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 0);
+		}
+	} else {
+		/* Force off device bit */
+		if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
+		                                 1, &regdata)) != BCME_OK) {
+			return status;
+		}
+		if (regdata & SDIO_SPEED_EHS) {
+			regdata &= ~SDIO_SPEED_EHS;
+			if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
+			                                  1, regdata)) != BCME_OK) {
+				return status;
+			}
+		}
+
+		sd_err(("High-speed clocking mode disabled.\n"));
+		reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 0);
+	}
+
+	if ((sd->host_UHSISupported) && (sd->card_UHSI_voltage_Supported)) {
+		/* also set the default driver strength in the card/HC [this is reqd because,
+			if earlier we selected any other drv_strn, we need to reset it]
+		*/
+		/* get the card driver strength from cccr */
+		if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_DRIVER_STRENGTH,
+			1, &drvstrn)) != BCME_OK) {
+			sd_err(("%s:Reading SDIOD_CCCR_DRIVER_STRENGTH from card"
+				"Failed!\n", __FUNCTION__));
+			return BCME_SDIO_ERROR;
+		}
+
+		/* reset card drv strn */
+		drvstrn = SFIELD(drvstrn, SDIO_BUS_DRVR_TYPE_SEL, 0);
+
+		/* set card drv strn */
+		if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_DRIVER_STRENGTH,
+			1, drvstrn)) != BCME_OK) {
+			sd_err(("%s:Setting SDIOD_CCCR_DRIVER_STRENGTH in"
+				"card Failed!\n", __FUNCTION__));
+			return BCME_SDIO_ERROR;
+		}
+	}
+
+	sdstd_wreg8(sd, SD_HostCntrl, reg8);
+
+	return BCME_OK;
+}
+
+/* Select DMA Mode:
+ * If dma_mode == DMA_MODE_AUTO, pick the "best" mode.
+ * Otherwise, pick the selected mode if supported.
+ * If not supported, use PIO mode.
+ */
+static int
+sdstd_set_dma_mode(sdioh_info_t *sd, int8 dma_mode)
+{
+	uint8 reg8, dma_sel_bits = SDIOH_SDMA_MODE;
+	int8 prev_dma_mode = sd->sd_dma_mode;
+
+	switch (prev_dma_mode) {
+		case DMA_MODE_AUTO:
+			sd_dma(("%s: Selecting best DMA mode supported by controller.\n",
+			          __FUNCTION__));
+			if (GFIELD(sd->caps, CAP_ADMA2)) {
+				sd->sd_dma_mode = DMA_MODE_ADMA2;
+				dma_sel_bits = SDIOH_ADMA2_MODE;
+			} else if (GFIELD(sd->caps, CAP_ADMA1)) {
+				sd->sd_dma_mode = DMA_MODE_ADMA1;
+				dma_sel_bits = SDIOH_ADMA1_MODE;
+			} else if (GFIELD(sd->caps, CAP_DMA)) {
+				sd->sd_dma_mode = DMA_MODE_SDMA;
+			} else {
+				sd->sd_dma_mode = DMA_MODE_NONE;
+			}
+			break;
+		case DMA_MODE_NONE:
+			sd->sd_dma_mode = DMA_MODE_NONE;
+			break;
+		case DMA_MODE_SDMA:
+			if (GFIELD(sd->caps, CAP_DMA)) {
+				sd->sd_dma_mode = DMA_MODE_SDMA;
+			} else {
+				sd_err(("%s: SDMA not supported by controller.\n", __FUNCTION__));
+				sd->sd_dma_mode = DMA_MODE_NONE;
+			}
+			break;
+		case DMA_MODE_ADMA1:
+			if (GFIELD(sd->caps, CAP_ADMA1)) {
+				sd->sd_dma_mode = DMA_MODE_ADMA1;
+				dma_sel_bits = SDIOH_ADMA1_MODE;
+			} else {
+				sd_err(("%s: ADMA1 not supported by controller.\n", __FUNCTION__));
+				sd->sd_dma_mode = DMA_MODE_NONE;
+			}
+			break;
+		case DMA_MODE_ADMA2:
+			if (GFIELD(sd->caps, CAP_ADMA2)) {
+				sd->sd_dma_mode = DMA_MODE_ADMA2;
+				dma_sel_bits = SDIOH_ADMA2_MODE;
+			} else {
+				sd_err(("%s: ADMA2 not supported by controller.\n", __FUNCTION__));
+				sd->sd_dma_mode = DMA_MODE_NONE;
+			}
+			break;
+		case DMA_MODE_ADMA2_64:
+			sd_err(("%s: 64b ADMA2 not supported by driver.\n", __FUNCTION__));
+			sd->sd_dma_mode = DMA_MODE_NONE;
+			break;
+		default:
+			sd_err(("%s: Unsupported DMA Mode %d requested.\n", __FUNCTION__,
+			        prev_dma_mode));
+			sd->sd_dma_mode = DMA_MODE_NONE;
+			break;
+	}
+
+	/* clear SysAddr, only used for SDMA */
+	sdstd_wreg(sd, SD_SysAddr, 0);
+
+	sd_err(("%s: %s mode selected.\n", __FUNCTION__, dma_mode_description[sd->sd_dma_mode]));
+
+	reg8 = sdstd_rreg8(sd, SD_HostCntrl);
+	reg8 = SFIELD(reg8, HOST_DMA_SEL, dma_sel_bits);
+	sdstd_wreg8(sd, SD_HostCntrl, reg8);
+	sd_dma(("%s: SD_HostCntrl=0x%02x\n", __FUNCTION__, reg8));
+
+	return BCME_OK;
+}
+
+#ifdef BCMDBG
+void
+print_regs(sdioh_info_t *sd)
+{
+	uint8 reg8 = 0;
+	uint16 reg16 = 0;
+	uint32 reg32 = 0;
+	uint8 presetreg;
+	int i;
+
+	reg8 = sdstd_rreg8(sd, SD_BlockSize);
+	printf("REGS: SD_BlockSize [004h]:0x%x\n", reg8);
+
+	reg8 = sdstd_rreg8(sd, SD_BlockCount);
+	printf("REGS: SD_BlockCount [006h]:0x%x\n", reg8);
+
+	reg8 = sdstd_rreg8(sd, SD_BlockSize);
+	printf("REGS: SD_BlockSize [004h]:0x%x\n", reg8);
+
+	reg8 = sdstd_rreg8(sd, SD_TransferMode);
+	printf("REGS: SD_TransferMode [00Ch]:0x%x\n", reg8);
+
+	reg8 = sdstd_rreg8(sd, SD_HostCntrl);
+	printf("REGS: SD_HostCntrl [028h]:0x%x\n", reg8);
+
+	reg32 = sdstd_rreg(sd, SD_PresentState);
+	printf("REGS: SD_PresentState [024h]:0x%x\n", reg32);
+
+	reg8 = sdstd_rreg8(sd, SD_PwrCntrl);
+	printf("REGS: SD_PwrCntrl [029h]:0x%x\n", reg8);
+
+	reg8 = sdstd_rreg8(sd, SD_BlockGapCntrl);
+	printf("REGS: SD_BlockGapCntrl [02Ah]:0x%x\n", reg8);
+
+	reg8 = sdstd_rreg8(sd, SD_WakeupCntrl);
+	printf("REGS: SD_WakeupCntrl [02Bh]:0x%x\n", reg8);
+
+	reg16 = sdstd_rreg16(sd, SD_ClockCntrl);
+	printf("REGS: SD_ClockCntrl [02Ch]:0x%x\n", reg16);
+
+	reg8 = sdstd_rreg8(sd, SD_TimeoutCntrl);
+	printf("REGS: SD_TimeoutCntrl [02Eh]:0x%x\n", reg8);
+
+	reg8 = sdstd_rreg8(sd, SD_SoftwareReset);
+	printf("REGS: SD_SoftwareReset [02Fh]:0x%x\n", reg8);
+
+	reg16 = sdstd_rreg16(sd, SD_IntrStatus);
+	printf("REGS: SD_IntrStatus [030h]:0x%x\n", reg16);
+
+	reg16 = sdstd_rreg16(sd, SD_ErrorIntrStatus);
+	printf("REGS: SD_ErrorIntrStatus [032h]:0x%x\n", reg16);
+
+	reg16 = sdstd_rreg16(sd, SD_IntrStatusEnable);
+	printf("REGS: SD_IntrStatusEnable [034h]:0x%x\n", reg16);
+
+	reg16 = sdstd_rreg16(sd, SD_ErrorIntrStatusEnable);
+	printf("REGS: SD_ErrorIntrStatusEnable [036h]:0x%x\n", reg16);
+
+	reg16 = sdstd_rreg16(sd, SD_IntrSignalEnable);
+	printf("REGS: SD_IntrSignalEnable [038h]:0x%x\n", reg16);
+
+	reg16 = sdstd_rreg16(sd, SD_ErrorIntrSignalEnable);
+	printf("REGS: SD_ErrorIntrSignalEnable [03Ah]:0x%x\n", reg16);
+
+	reg32 = sdstd_rreg(sd, SD_Capabilities);
+	printf("REGS: SD_Capabilities [040h]:0x%x\n", reg32);
+
+	reg32 = sdstd_rreg(sd, SD_MaxCurCap);
+	printf("REGS: SD_MaxCurCap [04Ah]:0x%x\n", reg32);
+
+	reg32 = sdstd_rreg(sd, SD_Capabilities3);
+	printf("REGS: SD_Capabilities3 [044h]:0x%x\n", reg32);
+
+	reg16 = sdstd_rreg16(sd, SD3_HostCntrl2);
+	printf("REGS: SD3_HostCntrl2 [03Eh]:0x%x\n", reg16);
+
+	for (i = 0; i < 8; i++) {
+		presetreg = SD3_PresetValStart + i*2;
+		printf("REGS: Presetvalreg:ix[%d]:0x%x, val=0x%x\n", i,
+		       presetreg, sdstd_rreg16(sd, presetreg));
+	}
+
+	reg16 = sdstd_rreg16(sd, SD_SlotInterruptStatus);
+	printf("REGS: SD_SlotInterruptStatus [0FCh]:0x%x\n", reg16);
+
+	reg16 = sdstd_rreg16(sd, SD_HostControllerVersion);
+	printf("REGS: SD_HostControllerVersion [0FEh]:0x%x\n", reg16);
+}
+#endif /* BCMDBG */
+
+/* XXX Per SDIO Host Controller Spec section 3.2.1
+	Note: for 2.x HC, new_sd_divisor should be a power of 2, but for 3.0
+	HC, new_sd_divisor should be a multiple of 2.
+*/
+bool
+sdstd_start_clock(sdioh_info_t *sd, uint16 new_sd_divisor)
+{
+	uint rc, count;
+	uint16 divisor;
+	uint16 regdata;
+	uint16 val1;
+
+	sd3_trace(("%s: starting clk\n", __FUNCTION__));
+	/* turn off HC clock */
+	sdstd_wreg16(sd, SD_ClockCntrl,
+	             sdstd_rreg16(sd, SD_ClockCntrl) & ~((uint16)0x4)); /*  Disable the HC clock */
+
+	/* Set divisor */
+	if (sd->host_UHSISupported) {
+#ifdef BCMDBG
+		if ((new_sd_divisor != 1) &&		/* 1 is a valid value */
+		    ((new_sd_divisor & (0x1)) ||	/* check for multiple of 2 */
+		     (new_sd_divisor == 0) ||
+		     (new_sd_divisor > 0x3ff))) {
+			sd_err(("3.0: Invalid clock divisor target: %d\n", new_sd_divisor));
+			return FALSE;
+		}
+#endif
+		divisor = (new_sd_divisor >> 1);
+	} else
+	{
+#ifdef BCMDBG
+		if ((new_sd_divisor & (new_sd_divisor-1)) ||
+		    (new_sd_divisor == 0)) {
+			sd_err(("Invalid clock divisor target: %d\n", new_sd_divisor));
+			return FALSE;
+		}
+#endif
+		/* new logic: if divisor > 256, restrict to 256 */
+		if (new_sd_divisor > 256)
+			new_sd_divisor = 256;
+		divisor = (new_sd_divisor >> 1) << 8;
+	}
+
+	sd_info(("Clock control is 0x%x\n", sdstd_rreg16(sd, SD_ClockCntrl)));
+	if (sd->host_UHSISupported) {
+		/* *get preset value and shift so that.
+		*	bits 0-7 are in 15-8 and 9-8 are in 7-6 of clkctrl
+		*/
+		val1 = divisor << 2;
+		val1 &= 0x0ffc;
+		val1 |= divisor >> 8;
+		val1 <<= 6;
+		printf("divisor:%x;val1:%x\n", divisor, val1);
+		sdstd_mod_reg16(sd, SD_ClockCntrl, 0xffC0, val1);
+	} else
+	{
+		sdstd_mod_reg16(sd, SD_ClockCntrl, 0xff00, divisor);
+	}
+
+	sd_err(("%s: Using clock divisor of %d (regval 0x%04x)\n", __FUNCTION__,
+	         new_sd_divisor, divisor));
+	if (new_sd_divisor > 0)
+		sd_err(("%s:now, divided clk is: %d Hz\n",
+		  __FUNCTION__, GFIELD(sd->caps, CAP_BASECLK)*1000000/new_sd_divisor));
+	else
+		sd_err(("Using Primary Clock Freq of %d MHz\n", GFIELD(sd->caps, CAP_BASECLK)));
+	sd_info(("Primary Clock Freq = %d MHz\n", GFIELD(sd->caps, CAP_BASECLK)));
+	if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 50) {
+		sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__,
+		        ((50 % new_sd_divisor) ? (50000 / new_sd_divisor) : (50 / new_sd_divisor)),
+		        ((50 % new_sd_divisor) ? "KHz" : "MHz")));
+	} else if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 48) {
+		sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__,
+		        ((48 % new_sd_divisor) ? (48000 / new_sd_divisor) : (48 / new_sd_divisor)),
+		        ((48 % new_sd_divisor) ? "KHz" : "MHz")));
+	} else if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 33) {
+		sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__,
+		        ((33 % new_sd_divisor) ? (33000 / new_sd_divisor) : (33 / new_sd_divisor)),
+		        ((33 % new_sd_divisor) ? "KHz" : "MHz")));
+	} else if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 31) {
+		sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__,
+		        ((31 % new_sd_divisor) ? (31000 / new_sd_divisor) : (31 / new_sd_divisor)),
+		        ((31 % new_sd_divisor) ? "KHz" : "MHz")));
+	} else if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 8) {
+		sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__,
+		        ((8 % new_sd_divisor) ? (8000 / new_sd_divisor) : (8 / new_sd_divisor)),
+		        ((8 % new_sd_divisor) ? "KHz" : "MHz")));
+	} else if (sd->controller_type == SDIOH_TYPE_BCM27XX) {
+		/* XXX - BCM 27XX Standard Host Controller returns 0 for CLKFREQ */
+	} else {
+		sd_err(("Need to determine divisor for %d MHz clocks\n",
+		        GFIELD(sd->caps, CAP_BASECLK)));
+		sd_err(("Consult SD Host Controller Spec: Clock Control Register\n"));
+		return (FALSE);
+	}
+
+	sdstd_or_reg16(sd, SD_ClockCntrl, 0x1); /*  Enable the clock */
+
+	/* Wait for clock to stabilize */
+	rc = (sdstd_rreg16(sd, SD_ClockCntrl) & 2);
+	count = 0;
+	while (!rc) {
+		OSL_DELAY(1);
+		sd_info(("Waiting for clock to become stable 0x%x\n", rc));
+		rc = (sdstd_rreg16(sd, SD_ClockCntrl) & 2);
+		count++;
+		if (count > 10000) {
+			sd_err(("%s:Clocks failed to stabilize after %u attempts\n",
+			        __FUNCTION__, count));
+			return (FALSE);
+		}
+	}
+	/* Turn on clock */
+	sdstd_or_reg16(sd, SD_ClockCntrl, 0x4);
+
+	OSL_DELAY(20);
+
+	/* Set timeout control (adjust default value based on divisor).
+	 * Disabling timeout interrupts during setting is advised by host spec.
+	 */
+#ifdef BCMQT
+	if (GFIELD(sd->caps, CAP_BASECLK) < 50)
+#endif
+	{
+		uint toval;
+
+		toval = sd_toctl;
+		divisor = new_sd_divisor;
+
+		while (toval && !(divisor & 1)) {
+			toval -= 1;
+			divisor >>= 1;
+		}
+
+		regdata = sdstd_rreg16(sd, SD_ErrorIntrStatusEnable);
+		sdstd_wreg16(sd, SD_ErrorIntrStatusEnable, (regdata & ~ERRINT_DATA_TIMEOUT_BIT));
+		sdstd_wreg8(sd, SD_TimeoutCntrl, (uint8)toval);
+		sdstd_wreg16(sd, SD_ErrorIntrStatusEnable, regdata);
+	}
+#ifdef BCMQT
+	else {
+		sd_info(("%s: REsetting err int control\n", __FUNCTION__));
+		/* XXX: turn off timeout INT, it resets clk ctrl bit */
+		regdata = sdstd_rreg16(sd, SD_ErrorIntrStatusEnable);
+		sdstd_wreg16(sd, SD_ErrorIntrStatusEnable, (regdata & ~ERRINT_DATA_TIMEOUT_BIT));
+	}
+#endif
+	OSL_DELAY(2);
+
+	sd_info(("Final Clock control is 0x%x\n", sdstd_rreg16(sd, SD_ClockCntrl)));
+
+	return TRUE;
+}
+
+/* XXX Per SDIO Host Controller Spec 3.3
+ * volts_req:
+ *		0 means default: select highest voltage.
+ *		1 means 1.8V
+ *		2 means 3.0V
+ *		3 means 3.3V
+ * returns
+ *	TRUE: no error
+ *	FALSE: general error
+ *	SDIO_OCR_READ_FAIL: ocr reading failure. Now the HC has to try in other available voltages.
+*/
+uint16
+sdstd_start_power(sdioh_info_t *sd, int volts_req)
+{
+	char *s;
+	uint32 cmd_arg;
+	uint32 cmd_rsp;
+	uint8 pwr = 0;
+	int volts = 0;
+	uint16 val1;
+	uint16 init_divider = 0;
+	uint8 baseclk = 0;
+	bool selhighest = (volts_req == 0) ? TRUE : FALSE;
+
+	/* reset the card uhsi volt support to false */
+	sd->card_UHSI_voltage_Supported = FALSE;
+
+	/* Ensure a power on reset by turning off bus power in case it happened to
+	 * be on already. (This might happen if driver doesn't unload/clean up correctly,
+	 * crash, etc.)  Leave off for 100ms to make sure the power off isn't
+	 * ignored/filtered by the device.  Note we can't skip this step if the power is
+	 * off already since we don't know how long it has been off before starting
+	 * the driver.
+	 */
+	sdstd_wreg8(sd, SD_PwrCntrl, 0);
+	sd_info(("Turning off VDD/bus power briefly (100ms) to ensure reset\n"));
+	OSL_DELAY(100000);
+
+	/* For selecting highest available voltage, start from lowest and iterate */
+	if (!volts_req)
+		volts_req = 1;
+
+	s = NULL;
+
+	if (volts_req == 1) {
+		if (GFIELD(sd->caps, CAP_VOLT_1_8)) {
+			volts = 5;
+			s = "1.8";
+			if (FALSE == selhighest)
+				goto voltsel;
+			else
+				volts_req++;
+		} else {
+			sd_err(("HC doesn't support voltage! trying higher voltage: %d\n", volts));
+			volts_req++;
+		}
+	}
+
+	if (volts_req == 2) {
+		if (GFIELD(sd->caps, CAP_VOLT_3_0)) {
+			volts = 6;
+			s = "3.0";
+			if (FALSE == selhighest)
+				goto voltsel;
+			else volts_req++;
+		} else {
+			sd_err(("HC doesn't support voltage! trying higher voltage: %d\n", volts));
+			volts_req++;
+		}
+	}
+
+	if (volts_req == 3) {
+		if (GFIELD(sd->caps, CAP_VOLT_3_3)) {
+			volts = 7;
+			s = "3.3";
+		} else {
+			if ((FALSE == selhighest) || (volts == 0)) {
+				sd_err(("HC doesn't support any voltage! error!\n"));
+				return FALSE;
+			}
+		}
+	}
+
+	/* XXX
+	 * if UHSI is NOT supported, check for other voltages also. This is a safety measure
+	 * for embedded devices also, so that HC starts in lower power first. If this
+	 * function fails, the caller may disable UHSISupported
+	 * and call start power again to check support in higher voltages.
+	 */
+
+voltsel:
+	pwr = SFIELD(pwr, PWR_VOLTS, volts);
+	pwr = SFIELD(pwr, PWR_BUS_EN, 1);
+	sdstd_wreg8(sd, SD_PwrCntrl, pwr); /* Set Voltage level */
+	sd_info(("Setting Bus Power to %s Volts\n", s));
+	BCM_REFERENCE(s);
+
+	/*
+	 * PR101766 : BRCM SDIO3.0 card is an embedded SD device. It is not a SD card.
+	 * VDDIO signalling will be tied to 1.8v level on all SDIO3.0 based boards.
+	 * So program the HC to drive VDDIO at 1.8v level.
+	 */
+	if ((sd->version == HOST_CONTR_VER_3) && (volts == 5)) {
+		val1 = sdstd_rreg16(sd, SD3_HostCntrl2);
+		val1 = SFIELD(val1, HOSTCtrl2_1_8SIG_EN, 1);
+		sdstd_wreg16(sd, SD3_HostCntrl2, val1);
+	}
+
+	/* Wait for 500ms for power to stabilize.  Some designs have reset IC's
+	 * which can hold reset low for close to 300ms.  In addition there can
+	 * be ramp time for VDD and/or VDDIO which might be provided from a LDO.
+	 * For these reasons we need a pretty conservative delay here to have
+	 * predictable reset behavior in the face of an unknown design.
+	 */
+	OSL_DELAY(500000);
+
+	baseclk = GFIELD(sd->caps, CAP_BASECLK);
+	sd_info(("%s:baseclk: %d MHz\n",	__FUNCTION__, baseclk));
+	/* for 3.0, find divisor */
+	if (sd->host_UHSISupported) {
+		/* ToDo : Dynamic modification of preset value table based on base clk */
+		sd3_trace(("sd3: %s: checking divisor\n", __FUNCTION__));
+		if (GFIELD(sd->caps3, CAP3_CLK_MULT) != 0)	{
+			sd_err(("%s:Possible error: CLK Mul 1 CLOCKING NOT supported!\n",
+				__FUNCTION__));
+			return FALSE;
+		} else {
+			/*  calculate dividor, which leads to 400KHz.  */
+			init_divider = baseclk*10/4; /* baseclk*1000000/(400000); */
+			/* make it a multiple of 2. */
+			init_divider += (init_divider & 0x1);
+			sd_err(("%s:divider used for init:%d\n",
+				__FUNCTION__, init_divider));
+		}
+	} else {
+		/* Note: sd_divisor assumes that SDIO Base CLK is 50MHz. */
+		int final_freq_based_on_div = 50/sd_divisor;
+	    if (baseclk > 50)
+			sd_divisor = baseclk/final_freq_based_on_div;
+		/* TBD: merge both SDIO 2.0 and 3.0 to share same divider logic */
+		init_divider = baseclk*10/4; /* baseclk*1000000/(400000); */
+		/* find next power of 2 */
+		NEXT_POW2(init_divider);
+		sd_err(("%s:NONUHSI: divider used for init:%d\n",
+			__FUNCTION__, init_divider));
+	}
+
+	/* Start at ~400KHz clock rate for initialization */
+	if (!sdstd_start_clock(sd, init_divider)) {
+		sd_err(("%s: sdstd_start_clock failed\n", __FUNCTION__));
+		return FALSE;
+	}
+
+	/* Get the Card's Operation Condition.  Occasionally the board
+	 * takes a while to become ready
+	 */
+	cmd_arg = 0;
+	cmd_rsp = 0;
+	if (get_ocr(sd, &cmd_arg, &cmd_rsp) != SUCCESS) {
+		sd_err(("%s: Failed to get OCR bailing\n", __FUNCTION__));
+		/* No need to reset as not sure in what state the card is. */
+		return SDIO_OCR_READ_FAIL;
+	}
+
+	sd_info(("cmd_rsp = 0x%x\n", cmd_rsp));
+	sd_info(("mem_present = %d\n", GFIELD(cmd_rsp, RSP4_MEM_PRESENT)));
+	sd_info(("num_funcs = %d\n", GFIELD(cmd_rsp, RSP4_NUM_FUNCS)));
+	sd_info(("card_ready = %d\n", GFIELD(cmd_rsp, RSP4_CARD_READY)));
+	sd_info(("OCR = 0x%x\n", GFIELD(cmd_rsp, RSP4_IO_OCR)));
+
+	/* Verify that the card supports I/O mode */
+	if (GFIELD(cmd_rsp, RSP4_NUM_FUNCS) == 0) {
+		sd_err(("%s: Card does not support I/O\n", __FUNCTION__));
+		return ERROR;
+	}
+	sd->num_funcs = GFIELD(cmd_rsp, RSP4_NUM_FUNCS);
+
+	/* Examine voltage: Arasan only supports 3.3 volts,
+	 * so look for 3.2-3.3 Volts and also 3.3-3.4 volts.
+	 */
+
+	/* XXX Pg 10 SDIO spec v1.10 */
+	if ((GFIELD(cmd_rsp, RSP4_IO_OCR) & (0x3 << 20)) == 0) {
+		sd_err(("This client does not support 3.3 volts!\n"));
+		return ERROR;
+	}
+	sd_info(("Leaving bus power at 3.3 Volts\n"));
+
+	cmd_arg = SFIELD(0, CMD5_OCR, 0xfff000);
+	/* if HC uhsi supported and card voltage set is 3.3V then switch to 1.8V */
+	if ((sd->host_UHSISupported) && (volts == 5)) {
+		/* set S18R also */
+		cmd_arg = SFIELD(cmd_arg, CMD5_S18R, 1);
+	}
+	cmd_rsp = 0;
+	get_ocr(sd, &cmd_arg, &cmd_rsp);
+	sd_info(("OCR = 0x%x\n", GFIELD(cmd_rsp, RSP4_IO_OCR)));
+
+	if ((sd->host_UHSISupported)) {
+		/* card responded with s18A => card supports sdio3.0,do tuning proc */
+		if (GFIELD(cmd_rsp, RSP4_S18A) == 1) {
+			if (sdstd_3_sigvoltswitch_proc(sd)) {
+				/* continue with legacy way of working */
+				sd_err(("%s: voltage switch not done. error, stopping\n",
+					__FUNCTION__));
+				/* How to gracefully proceced here? */
+				return FALSE;
+			} else {
+				sd->card_UHSI_voltage_Supported = TRUE;
+				sd_err(("%s: voltage switch SUCCESS!\n", __FUNCTION__));
+			}
+		} else {
+				/* This could happen for 2 cases.
+				 * 1) means card is NOT sdio3.0 . Note that
+				 *    card_UHSI_voltage_Supported is already false.
+				 * 2) card is sdio3.0 but it is already in 1.8V.
+				 *    But now, how to change host controller's voltage?
+				 * In this case we need to do the following.
+				 * sd->card_UHSI_voltage_Supported = TRUE;
+				 * turn 1.8V sig enable in HC2
+				 * val1 = sdstd_rreg16(sd, SD3_HostCntrl2);
+				 * val1 = SFIELD(val1, HOSTCtrl2_1_8SIG_EN, 1);
+				 * sdstd_wreg16(sd, SD3_HostCntrl2, val1);
+				 */
+
+				sd_info(("%s: Not sdio3.0: host_UHSISupported: %d; HC volts=%d\n",
+					__FUNCTION__, sd->host_UHSISupported, volts));
+		}
+	} else {
+		sd_info(("%s: Legacy [non sdio3.0] HC\n", __FUNCTION__));
+	}
+
+	return TRUE;
+}
+
+bool
+sdstd_bus_width(sdioh_info_t *sd, int new_mode)
+{
+	uint32 regdata;
+	int status;
+	uint8 reg8;
+
+	sd_trace(("%s\n", __FUNCTION__));
+	if (sd->sd_mode == new_mode) {
+		sd_info(("%s: Already at width %d\n", __FUNCTION__, new_mode));
+		/* Could exit, but continue just in case... */
+	}
+
+	/* Set client side via reg 0x7 in CCCR */
+	if ((status = sdstd_card_regread (sd, 0, SDIOD_CCCR_BICTRL, 1, &regdata)) != SUCCESS)
+		return (bool)status;
+	regdata &= ~BUS_SD_DATA_WIDTH_MASK;
+	if (new_mode == SDIOH_MODE_SD4) {
+		sd_info(("Changing to SD4 Mode\n"));
+		regdata |= SD4_MODE;
+	} else if (new_mode == SDIOH_MODE_SD1) {
+		sd_info(("Changing to SD1 Mode\n"));
+	} else {
+		sd_err(("SPI Mode not supported by Standard Host Controller\n"));
+	}
+
+	if ((status = sdstd_card_regwrite (sd, 0, SDIOD_CCCR_BICTRL, 1, regdata)) != SUCCESS)
+		return (bool)status;
+
+	if (sd->host_UHSISupported) {
+		uint32 card_asyncint = 0;
+		uint16 host_asyncint = 0;
+
+		if ((status = sdstd_card_regread (sd, 0, SDIOD_CCCR_INTR_EXTN, 1,
+			&card_asyncint)) != SUCCESS) {
+			sd_err(("%s:INTR EXT getting failed!, ignoring\n", __FUNCTION__));
+		} else {
+			host_asyncint = sdstd_rreg16(sd, SD3_HostCntrl2);
+
+			/* check if supported by host and card */
+			if ((regdata & SD4_MODE) &&
+				(GFIELD(card_asyncint, SDIO_BUS_ASYNCINT_CAP)) &&
+				(GFIELD(sd->caps, CAP_ASYNCINT_SUP))) {
+				/* set enable async int in card */
+				card_asyncint = SFIELD(card_asyncint, SDIO_BUS_ASYNCINT_SEL, 1);
+
+				if ((status = sdstd_card_regwrite (sd, 0,
+					SDIOD_CCCR_INTR_EXTN, 1, card_asyncint)) != SUCCESS)
+					sd_err(("%s:INTR EXT setting failed!, ignoring\n",
+					__FUNCTION__));
+				else {
+					/* set enable async int in host */
+					host_asyncint = SFIELD(host_asyncint,
+						HOSTCtrl2_ASYINT_EN, 1);
+					sdstd_wreg16(sd, SD3_HostCntrl2, host_asyncint);
+				}
+			} else {
+				sd_err(("%s:INTR EXT NOT supported by either host or"
+					"card!, ignoring\n", __FUNCTION__));
+			}
+		}
+	}
+
+	/* Set host side via Host reg */
+	reg8 = sdstd_rreg8(sd, SD_HostCntrl) & ~SD4_MODE;
+	if (new_mode == SDIOH_MODE_SD4)
+		reg8 |= SD4_MODE;
+	sdstd_wreg8(sd, SD_HostCntrl, reg8);
+
+	sd->sd_mode = new_mode;
+
+	return TRUE;
+}
+
+static int
+sdstd_driver_init(sdioh_info_t *sd)
+{
+	sd_trace(("%s\n", __FUNCTION__));
+	sd->sd3_tuning_reqd = FALSE;
+	sd->sd3_tuning_disable = FALSE;
+	if ((sdstd_host_init(sd)) != SUCCESS) {
+		return ERROR;
+	}
+
+	/* Give WL_reset before sending CMD5 to dongle for Revx SDIO3 HC's */
+	if ((sd->controller_type == SDIOH_TYPE_RICOH_R5C822) && (sd->version == HOST_CONTR_VER_3))
+	{
+		sdstd_wreg16(sd, SD3_WL_BT_reset_register, 0x8);
+		OSL_DELAY(sd_delay_value);
+		sdstd_wreg16(sd, SD3_WL_BT_reset_register, 0x0);
+		OSL_DELAY(500000);
+	}
+
+	if (sdstd_client_init(sd) != SUCCESS) {
+		return ERROR;
+	}
+
+	/* if the global cap matched and is SDR 104/50 [if 50 it is reqd] enable tuning. */
+	if ((TRUE != sd3_sw_override1) && SD3_TUNING_REQD(sd, sd_uhsimode)) {
+			sd->sd3_tuning_reqd = TRUE;
+
+			/* init OS structs for tuning */
+			sdstd_3_osinit_tuning(sd);
+
+			/* enable HC tuning interrupt OR timer based on tuning method */
+			if (GFIELD(sd->caps3, CAP3_RETUNING_MODES)) {
+				/* enable both RTReq and timer */
+				sd->intmask |= HC_INTR_RETUNING;
+				sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask);
+#ifdef BCMSDYIELD
+				if (sd_forcerb)
+					sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */
+#endif /* BCMSDYIELD */
+			}
+		}
+
+	return SUCCESS;
+}
+
+static int
+sdstd_get_cisaddr(sdioh_info_t *sd, uint32 regaddr)
+{
+	/* read 24 bits and return valid 17 bit addr */
+	int i;
+	uint32 scratch, regdata;
+	uint8 *ptr = (uint8 *)&scratch;
+	for (i = 0; i < 3; i++) {
+		if ((sdstd_card_regread (sd, 0, regaddr, 1, &regdata)) != SUCCESS)
+			sd_err(("%s: Can't read!\n", __FUNCTION__));
+
+		*ptr++ = (uint8) regdata;
+		regaddr++;
+	}
+	/* Only the lower 17-bits are valid */
+	scratch = ltoh32(scratch);
+	scratch &= 0x0001FFFF;
+	return (scratch);
+}
+
+static int
+sdstd_card_enablefuncs(sdioh_info_t *sd)
+{
+	int status;
+	uint32 regdata;
+	uint32 fbraddr;
+	uint8 func;
+
+	sd_trace(("%s\n", __FUNCTION__));
+
+	/* Get the Card's common CIS address */
+	sd->com_cis_ptr = sdstd_get_cisaddr(sd, SDIOD_CCCR_CISPTR_0);
+	sd->func_cis_ptr[0] = sd->com_cis_ptr;
+	sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __FUNCTION__, sd->com_cis_ptr));
+
+	/* Get the Card's function CIS (for each function) */
+	for (fbraddr = SDIOD_FBR_STARTADDR, func = 1;
+	     func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
+		sd->func_cis_ptr[func] = sdstd_get_cisaddr(sd, SDIOD_FBR_CISPTR_0 + fbraddr);
+		sd_info(("%s: Function %d CIS Ptr = 0x%x\n",
+		         __FUNCTION__, func, sd->func_cis_ptr[func]));
+	}
+
+	/* Enable function 1 on the card */
+	regdata = SDIO_FUNC_ENABLE_1;
+	if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_IOEN, 1, regdata)) != SUCCESS)
+		return status;
+
+	return SUCCESS;
+}
+
+/* Read client card reg */
+static int
+sdstd_card_regread(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 *data)
+{
+	int status;
+	uint32 cmd_arg;
+	uint32 rsp5;
+
+#ifdef BCMDBG
+	if (sdstd_rreg16 (sd, SD_ErrorIntrStatus) != 0) {
+		sd_err(("%s: Entering: ErrorintrStatus 0x%x, intstat = 0x%x\n",
+		        __FUNCTION__, sdstd_rreg16(sd, SD_ErrorIntrStatus),
+		        sdstd_rreg16(sd, SD_IntrStatus)));
+	}
+#endif
+
+	cmd_arg = 0;
+
+	if ((func == 0) || (regsize == 1)) {
+		cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func);
+		cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr);
+		cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SDIOH_XFER_TYPE_READ);
+		cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0);
+		cmd_arg = SFIELD(cmd_arg, CMD52_DATA, 0);
+
+		if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_52, cmd_arg))
+		    != SUCCESS)
+			return status;
+
+		sdstd_cmd_getrsp(sd, &rsp5, 1);
+		if (sdstd_rreg16(sd, SD_ErrorIntrStatus) != 0) {
+			sd_err(("%s: 1: ErrorintrStatus 0x%x\n",
+			        __FUNCTION__, sdstd_rreg16(sd, SD_ErrorIntrStatus)));
+		}
+
+		if (GFIELD(rsp5, RSP5_FLAGS) != 0x10)
+			sd_err(("%s: rsp5 flags is 0x%x\t %d\n",
+			        __FUNCTION__, GFIELD(rsp5, RSP5_FLAGS), func));
+
+		if (GFIELD(rsp5, RSP5_STUFF))
+			sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n",
+			        __FUNCTION__, GFIELD(rsp5, RSP5_STUFF)));
+		*data = GFIELD(rsp5, RSP5_DATA);
+
+		sd_data(("%s: Resp data(0x%x)\n", __FUNCTION__, *data));
+	} else {
+		cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, regsize);
+		cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1);	/* XXX SDIO spec v 1.10, Sec 5.3 */
+		cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0);
+		cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func);
+		cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, regaddr);
+		cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_READ);
+
+		sd->data_xfer_count = regsize;
+
+		/* sdstd_cmd_issue() returns with the command complete bit
+		 * in the ISR already cleared
+		 */
+		if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_53, cmd_arg))
+		    != SUCCESS)
+			return status;
+
+		sdstd_cmd_getrsp(sd, &rsp5, 1);
+
+		if (GFIELD(rsp5, RSP5_FLAGS) != 0x10)
+			sd_err(("%s: rsp5 flags is 0x%x\t %d\n",
+			        __FUNCTION__, GFIELD(rsp5, RSP5_FLAGS), func));
+
+		if (GFIELD(rsp5, RSP5_STUFF))
+			sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n",
+			        __FUNCTION__, GFIELD(rsp5, RSP5_STUFF)));
+
+		if (sd->polled_mode) {
+			volatile uint16 int_reg;
+			int retries = RETRIES_LARGE;
+
+			/* Wait for Read Buffer to become ready */
+			do {
+				sdstd_os_yield(sd);
+				int_reg = sdstd_rreg16(sd, SD_IntrStatus);
+			} while (--retries && (GFIELD(int_reg, INTSTAT_BUF_READ_READY) == 0));
+
+			if (!retries) {
+				sd_err(("%s: Timeout on Buf_Read_Ready: "
+				        "intStat: 0x%x errint: 0x%x PresentState 0x%x\n",
+				        __FUNCTION__, int_reg,
+				        sdstd_rreg16(sd, SD_ErrorIntrStatus),
+				        sdstd_rreg(sd, SD_PresentState)));
+				sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg);
+				return (ERROR);
+			}
+
+			/* Have Buffer Ready, so clear it and read the data */
+			sdstd_wreg16(sd, SD_IntrStatus, SFIELD(0, INTSTAT_BUF_READ_READY, 1));
+			if (regsize == 2)
+				*data = sdstd_rreg16(sd, SD_BufferDataPort0);
+			else
+				*data = sdstd_rreg(sd, SD_BufferDataPort0);
+
+			sd_data(("%s: Resp data(0x%x)\n", __FUNCTION__, *data));
+			/* Check Status.
+			 * After the data is read, the Transfer Complete bit should be on
+			 */
+			retries = RETRIES_LARGE;
+			do {
+				int_reg = sdstd_rreg16(sd, SD_IntrStatus);
+			} while (--retries && (GFIELD(int_reg, INTSTAT_XFER_COMPLETE) == 0));
+
+			/* Check for any errors from the data phase */
+			if (sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg))
+				return ERROR;
+
+			if (!retries) {
+				sd_err(("%s: Timeout on xfer complete: "
+				        "intr 0x%04x err 0x%04x state 0x%08x\n",
+				        __FUNCTION__, int_reg,
+				        sdstd_rreg16(sd, SD_ErrorIntrStatus),
+				        sdstd_rreg(sd, SD_PresentState)));
+				return (ERROR);
+			}
+
+			sdstd_wreg16(sd, SD_IntrStatus, SFIELD(0, INTSTAT_XFER_COMPLETE, 1));
+		}
+	}
+	if (sd->polled_mode) {
+		if (regsize == 2)
+			*data &= 0xffff;
+	}
+	return SUCCESS;
+}
+
+bool
+check_client_intr(sdioh_info_t *sd)
+{
+	uint16 raw_int, cur_int, old_int;
+
+	raw_int = sdstd_rreg16(sd, SD_IntrStatus);
+	cur_int = raw_int & sd->intmask;
+
+	if (!cur_int) {
+		/* Not an error -- might share interrupts... */
+		return FALSE;
+	}
+
+	if (GFIELD(cur_int, INTSTAT_CARD_INT)) {
+		unsigned long flags;
+
+		sdstd_os_lock_irqsave(sd, &flags);
+		old_int = sdstd_rreg16(sd, SD_IntrStatusEnable);
+		sdstd_wreg16(sd, SD_IntrStatusEnable, SFIELD(old_int, INTSTAT_CARD_INT, 0));
+		sdstd_os_unlock_irqrestore(sd, &flags);
+
+		if (sd->client_intr_enabled && sd->use_client_ints) {
+			sd->intrcount++;
+			ASSERT(sd->intr_handler);
+			ASSERT(sd->intr_handler_arg);
+			(sd->intr_handler)(sd->intr_handler_arg);
+		} else {
+			sd_err(("%s: Not ready for intr: enabled %d, handler %p\n",
+			        __FUNCTION__, sd->client_intr_enabled, sd->intr_handler));
+		}
+		sdstd_os_lock_irqsave(sd, &flags);
+		old_int = sdstd_rreg16(sd, SD_IntrStatusEnable);
+		sdstd_wreg16(sd, SD_IntrStatusEnable, SFIELD(old_int, INTSTAT_CARD_INT, 1));
+		sdstd_os_unlock_irqrestore(sd, &flags);
+	} else {
+		/* Local interrupt: disable, set flag, and save intrstatus */
+		sdstd_wreg16(sd, SD_IntrSignalEnable, 0);
+		sdstd_wreg16(sd, SD_ErrorIntrSignalEnable, 0);
+		sd->local_intrcount++;
+		sd->got_hcint = TRUE;
+		sd->last_intrstatus = cur_int;
+	}
+
+	return TRUE;
+}
+
+void
+sdstd_spinbits(sdioh_info_t *sd, uint16 norm, uint16 err)
+{
+	uint16 int_reg, err_reg;
+	int retries = RETRIES_LARGE;
+
+	do {
+		int_reg = sdstd_rreg16(sd, SD_IntrStatus);
+		err_reg = sdstd_rreg16(sd, SD_ErrorIntrStatus);
+	} while (--retries && !(int_reg & norm) && !(err_reg & err));
+
+	norm |= sd->intmask;
+	if (err_reg & err)
+		norm = SFIELD(norm, INTSTAT_ERROR_INT, 1);
+	sd->last_intrstatus = int_reg & norm;
+}
+
+/* write a client register */
+static int
+sdstd_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr, int regsize, uint32 data)
+{
+	int status;
+	uint32 cmd_arg, rsp5, flags;
+
+	cmd_arg = 0;
+
+	if ((func == 0) || (regsize == 1)) {
+		cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func);
+		cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr);
+		cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SDIOH_XFER_TYPE_WRITE);
+		cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0);
+		cmd_arg = SFIELD(cmd_arg, CMD52_DATA, data & 0xff);
+		if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_52, cmd_arg))
+		    != SUCCESS)
+			return status;
+
+		sdstd_cmd_getrsp(sd, &rsp5, 1);
+		flags = GFIELD(rsp5, RSP5_FLAGS);
+		if (flags && (flags != 0x10))
+			sd_err(("%s: rsp5.rsp5.flags = 0x%x, expecting 0x10\n",
+			        __FUNCTION__,  flags));
+	}
+	else {
+		cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, regsize);
+		/* XXX SDIO spec v 1.10, Sec 5.3  Not FIFO */
+		cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1);
+		cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0);
+		cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func);
+		cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, regaddr);
+		cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_WRITE);
+
+		sd->data_xfer_count = regsize;
+
+		/* sdstd_cmd_issue() returns with the command complete bit
+		 * in the ISR already cleared
+		 */
+		if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_53, cmd_arg))
+		    != SUCCESS)
+			return status;
+
+		sdstd_cmd_getrsp(sd, &rsp5, 1);
+
+		if (GFIELD(rsp5, RSP5_FLAGS) != 0x10)
+			sd_err(("%s: rsp5 flags = 0x%x, expecting 0x10\n",
+			        __FUNCTION__,  GFIELD(rsp5, RSP5_FLAGS)));
+		if (GFIELD(rsp5, RSP5_STUFF))
+			sd_err(("%s: rsp5 stuff is 0x%x: expecting 0\n",
+			        __FUNCTION__, GFIELD(rsp5, RSP5_STUFF)));
+
+		if (sd->polled_mode) {
+			uint16 int_reg;
+			int retries = RETRIES_LARGE;
+
+			/* Wait for Write Buffer to become ready */
+			do {
+				int_reg = sdstd_rreg16(sd, SD_IntrStatus);
+			} while (--retries && (GFIELD(int_reg, INTSTAT_BUF_WRITE_READY) == 0));
+
+			if (!retries) {
+				sd_err(("%s: Timeout on Buf_Write_Ready: intStat: 0x%x "
+				        "errint: 0x%x PresentState 0x%x\n",
+				        __FUNCTION__, int_reg,
+				        sdstd_rreg16(sd, SD_ErrorIntrStatus),
+				        sdstd_rreg(sd, SD_PresentState)));
+				sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg);
+				return (ERROR);
+			}
+			/* Clear Write Buf Ready bit */
+			int_reg = 0;
+			int_reg = SFIELD(int_reg, INTSTAT_BUF_WRITE_READY, 1);
+			sdstd_wreg16(sd, SD_IntrStatus, int_reg);
+
+			/* At this point we have Buffer Ready, so write the data */
+			if (regsize == 2)
+				sdstd_wreg16(sd, SD_BufferDataPort0, (uint16) data);
+			else
+				sdstd_wreg(sd, SD_BufferDataPort0, data);
+
+			/* Wait for Transfer Complete */
+			retries = RETRIES_LARGE;
+			do {
+				int_reg = sdstd_rreg16(sd, SD_IntrStatus);
+			} while (--retries && (GFIELD(int_reg, INTSTAT_XFER_COMPLETE) == 0));
+
+			/* Check for any errors from the data phase */
+			if (sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg))
+				return ERROR;
+
+			if (retries == 0) {
+				sd_err(("%s: Timeout for xfer complete; State = 0x%x, "
+				        "intr state=0x%x, Errintstatus 0x%x rcnt %d, tcnt %d\n",
+				        __FUNCTION__, sdstd_rreg(sd, SD_PresentState),
+				        int_reg, sdstd_rreg16(sd, SD_ErrorIntrStatus),
+				        sd->r_cnt, sd->t_cnt));
+			}
+			/* Clear the status bits */
+			sdstd_wreg16(sd, SD_IntrStatus, SFIELD(int_reg, INTSTAT_CARD_INT, 0));
+		}
+	}
+	return SUCCESS;
+}
+
+void
+sdstd_cmd_getrsp(sdioh_info_t *sd, uint32 *rsp_buffer, int count /* num 32 bit words */)
+{
+	int rsp_count;
+	int respaddr = SD_Response0;
+
+	if (count > 4)
+		count = 4;
+
+	for (rsp_count = 0; rsp_count < count; rsp_count++) {
+		*rsp_buffer++ = sdstd_rreg(sd, respaddr);
+		respaddr += 4;
+	}
+}
+
+/*
+	Note: options: 0 - default
+				 1 - tuning option: Means that, this cmd issue is as a part
+					of tuning. So no need to check the start tuning function.
+*/
+static int
+sdstd_cmd_issue(sdioh_info_t *sdioh_info, bool use_dma, uint32 cmd, uint32 arg)
+{
+	uint16 cmd_reg;
+	int retries;
+	uint32 cmd_arg;
+	uint16 xfer_reg = 0;
+
+#ifdef BCMDBG
+	if (sdstd_rreg16(sdioh_info, SD_ErrorIntrStatus) != 0) {
+		sd_err(("%s: Entering: ErrorIntrStatus 0x%x, Expecting 0\n",
+		        __FUNCTION__, sdstd_rreg16(sdioh_info, SD_ErrorIntrStatus)));
+	}
+#endif
+
+	if ((sdioh_info->sd_mode == SDIOH_MODE_SPI) &&
+	    ((cmd == SDIOH_CMD_3) || (cmd == SDIOH_CMD_7) || (cmd == SDIOH_CMD_15))) {
+		sd_err(("%s: Cmd %d is not for SPI\n", __FUNCTION__, cmd));
+		return ERROR;
+	}
+
+	retries = RETRIES_SMALL;
+	while ((GFIELD(sdstd_rreg(sdioh_info, SD_PresentState), PRES_CMD_INHIBIT)) && --retries) {
+		if (retries == RETRIES_SMALL)
+			sd_err(("%s: Waiting for Command Inhibit cmd = %d 0x%x\n",
+			        __FUNCTION__, cmd, sdstd_rreg(sdioh_info, SD_PresentState)));
+	}
+	if (!retries) {
+		sd_err(("%s: Command Inhibit timeout\n", __FUNCTION__));
+		if (trap_errs)
+			ASSERT(0);
+		return ERROR;
+	}
+
+	cmd_reg = 0;
+	switch (cmd) {
+	case SDIOH_CMD_0:       /* Set Card to Idle State - No Response */
+		sd_data(("%s: CMD%d\n", __FUNCTION__, cmd));
+		cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_NONE);
+		cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd);
+		break;
+
+	case SDIOH_CMD_3:	/* Ask card to send RCA - Response R6 */
+		sd_data(("%s: CMD%d\n", __FUNCTION__, cmd));
+		cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48);
+		cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd);
+		break;
+
+	case SDIOH_CMD_5:	/* Send Operation condition - Response R4 */
+		sd_data(("%s: CMD%d\n", __FUNCTION__, cmd));
+		cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48);
+		cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd);
+		break;
+
+	case SDIOH_CMD_7:	/* Select card - Response R1 */
+		sd_data(("%s: CMD%d\n", __FUNCTION__, cmd));
+		cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48);
+		cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1);
+		cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd);
+		break;
+
+	case SDIOH_CMD_14:	/* eSD Sleep - Response R1 */
+	case SDIOH_CMD_11:	/* Select card - Response R1 */
+		sd_data(("%s: CMD%d\n", __FUNCTION__, cmd));
+		cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48);
+		cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1);
+		cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd);
+		break;
+
+	case SDIOH_CMD_15:	/* Set card to inactive state - Response None */
+		sd_data(("%s: CMD%d\n", __FUNCTION__, cmd));
+		cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_NONE);
+		cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd);
+		break;
+
+	case SDIOH_CMD_19:	/* clock tuning - Response R1 */
+		sd_data(("%s: CMD%d\n", __FUNCTION__, cmd));
+		cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48);
+		cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1);
+		cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 1);
+		cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd);
+		/* Host controller reads 64 byte magic pattern from card
+		*  Hence Direction = 1 ( READ )
+		*/
+		xfer_reg = SFIELD(xfer_reg, XFER_DATA_DIRECTION, 1);
+		break;
+
+	case SDIOH_CMD_52:	/* IO R/W Direct (single byte) - Response R5 */
+
+		sd_data(("%s: CMD52 func(%d) addr(0x%x) %s data(0x%x)\n",
+			__FUNCTION__,
+			GFIELD(arg, CMD52_FUNCTION),
+			GFIELD(arg, CMD52_REG_ADDR),
+			GFIELD(arg, CMD52_RW_FLAG) ? "W" : "R",
+			GFIELD(arg, CMD52_DATA)));
+
+		cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48);
+		cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1);
+		cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd);
+		break;
+
+	case SDIOH_CMD_53:	/* IO R/W Extended (multiple bytes/blocks) */
+
+		sd_data(("%s: CMD53 func(%d) addr(0x%x) %s mode(%s) cnt(%d), %s\n",
+			__FUNCTION__,
+			GFIELD(arg, CMD53_FUNCTION),
+			GFIELD(arg, CMD53_REG_ADDR),
+			GFIELD(arg, CMD53_RW_FLAG) ? "W" : "R",
+			GFIELD(arg, CMD53_BLK_MODE) ? "Block" : "Byte",
+			GFIELD(arg, CMD53_BYTE_BLK_CNT),
+			GFIELD(arg, CMD53_OP_CODE) ? "Incrementing addr" : "Single addr"));
+
+		cmd_arg = arg;
+		xfer_reg = 0;
+
+		cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48);
+		cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1);
+		cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 1);
+		cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_NORMAL);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX, cmd);
+
+		use_dma = USE_DMA(sdioh_info) && GFIELD(cmd_arg, CMD53_BLK_MODE);
+
+		if (GFIELD(cmd_arg, CMD53_BLK_MODE)) {
+			uint16 blocksize;
+			uint16 blockcount;
+			int func;
+
+			ASSERT(sdioh_info->sd_blockmode);
+
+			func = GFIELD(cmd_arg, CMD53_FUNCTION);
+			blocksize = MIN((int)sdioh_info->data_xfer_count,
+			                sdioh_info->client_block_size[func]);
+			blockcount = GFIELD(cmd_arg, CMD53_BYTE_BLK_CNT);
+
+			/* data_xfer_cnt is already setup so that for multiblock mode,
+			 * it is the entire buffer length.  For non-block or single block,
+			 * it is < 64 bytes
+			 */
+			if (use_dma) {
+				switch (sdioh_info->sd_dma_mode) {
+				case DMA_MODE_SDMA:
+					sd_dma(("%s: SDMA: SysAddr reg was 0x%x now 0x%x\n",
+					      __FUNCTION__, sdstd_rreg(sdioh_info, SD_SysAddr),
+					     (uint32)sdioh_info->dma_phys));
+				sdstd_wreg(sdioh_info, SD_SysAddr, sdioh_info->dma_phys);
+					break;
+				case DMA_MODE_ADMA1:
+				case DMA_MODE_ADMA2:
+					sd_dma(("%s: ADMA: Using ADMA\n", __FUNCTION__));
+#ifdef BCMSDIOH_TXGLOM
+					/* multi-descriptor is currently used only for hc3 */
+					if ((sdioh_info->glom_info.count != 0) &&
+						(sdioh_info->txglom_mode == SDPCM_TXGLOM_MDESC)) {
+						uint32 i = 0;
+						for (i = 0;
+							i < sdioh_info->glom_info.count-1;
+							i++) {
+							glom_buf_t *glom_info;
+							glom_info = &(sdioh_info->glom_info);
+							sd_create_adma_descriptor(sdioh_info,
+								i,
+								glom_info->dma_phys_arr[i],
+								glom_info->nbytes[i],
+								ADMA2_ATTRIBUTE_VALID |
+								ADMA2_ATTRIBUTE_ACT_TRAN);
+						}
+
+						sd_create_adma_descriptor(sdioh_info,
+							i,
+							sdioh_info->glom_info.dma_phys_arr[i],
+							sdioh_info->glom_info.nbytes[i],
+							ADMA2_ATTRIBUTE_VALID |
+							ADMA2_ATTRIBUTE_END |
+							ADMA2_ATTRIBUTE_INT |
+							ADMA2_ATTRIBUTE_ACT_TRAN);
+					} else
+#endif /* BCMSDIOH_TXGLOM */
+					{
+						sd_create_adma_descriptor(sdioh_info, 0,
+						sdioh_info->dma_phys, blockcount*blocksize,
+						ADMA2_ATTRIBUTE_VALID | ADMA2_ATTRIBUTE_END |
+						ADMA2_ATTRIBUTE_INT | ADMA2_ATTRIBUTE_ACT_TRAN);
+					}
+					/* Dump descriptor if DMA debugging is enabled. */
+					if (sd_msglevel & SDH_DMA_VAL) {
+						sd_dump_adma_dscr(sdioh_info);
+					}
+
+					sdstd_wreg(sdioh_info, SD_ADMA_SysAddr,
+					           sdioh_info->adma2_dscr_phys);
+					break;
+				default:
+					sd_err(("%s: unsupported DMA mode %d.\n",
+						__FUNCTION__, sdioh_info->sd_dma_mode));
+					break;
+				}
+			}
+
+			sd_trace(("%s: Setting block count %d, block size %d bytes\n",
+			          __FUNCTION__, blockcount, blocksize));
+			sdstd_wreg16(sdioh_info, SD_BlockSize, blocksize);
+			sdstd_wreg16(sdioh_info, SD_BlockCount, blockcount);
+
+			xfer_reg = SFIELD(xfer_reg, XFER_DMA_ENABLE, use_dma);
+
+			if (sdioh_info->client_block_size[func] != blocksize)
+				set_client_block_size(sdioh_info, 1, blocksize);
+
+			if (blockcount > 1) {
+				xfer_reg = SFIELD(xfer_reg, XFER_MULTI_BLOCK, 1);
+				xfer_reg = SFIELD(xfer_reg, XFER_BLK_COUNT_EN, 1);
+				xfer_reg = SFIELD(xfer_reg, XFER_CMD_12_EN, 0);
+			} else {
+				xfer_reg = SFIELD(xfer_reg, XFER_MULTI_BLOCK, 0);
+				xfer_reg = SFIELD(xfer_reg, XFER_BLK_COUNT_EN, 0);
+				xfer_reg = SFIELD(xfer_reg, XFER_CMD_12_EN, 0);
+			}
+
+			if (GFIELD(cmd_arg, CMD53_RW_FLAG) == SDIOH_XFER_TYPE_READ)
+				xfer_reg = SFIELD(xfer_reg, XFER_DATA_DIRECTION, 1);
+			else
+				xfer_reg = SFIELD(xfer_reg, XFER_DATA_DIRECTION, 0);
+
+			retries = RETRIES_SMALL;
+			while (GFIELD(sdstd_rreg(sdioh_info, SD_PresentState),
+			              PRES_DAT_INHIBIT) && --retries)
+				sd_err(("%s: Waiting for Data Inhibit cmd = %d\n",
+				        __FUNCTION__, cmd));
+			if (!retries) {
+				sd_err(("%s: Data Inhibit timeout\n", __FUNCTION__));
+				if (trap_errs)
+					ASSERT(0);
+				return ERROR;
+			}
+
+			/* Consider deferring this write to the comment below "Deferred Write" */
+			sdstd_wreg16(sdioh_info, SD_TransferMode, xfer_reg);
+
+		} else {	/* Non block mode */
+			uint16 bytes = GFIELD(cmd_arg, CMD53_BYTE_BLK_CNT);
+			/* The byte/block count field only has 9 bits,
+			 * so, to do a 512-byte bytemode transfer, this
+			 * field will contain 0, but we need to tell the
+			 * controller we're transferring 512 bytes.
+			 */
+			if (bytes == 0) bytes = 512;
+
+			if (use_dma)
+				sdstd_wreg(sdioh_info, SD_SysAddr, sdioh_info->dma_phys);
+
+			/* PCI: Transfer Mode register 0x0c */
+			xfer_reg = SFIELD(xfer_reg, XFER_DMA_ENABLE, bytes <= 4 ? 0 : use_dma);
+			xfer_reg = SFIELD(xfer_reg, XFER_CMD_12_EN, 0);
+			if (GFIELD(cmd_arg, CMD53_RW_FLAG) == SDIOH_XFER_TYPE_READ)
+				xfer_reg = SFIELD(xfer_reg, XFER_DATA_DIRECTION, 1);
+			else
+				xfer_reg = SFIELD(xfer_reg, XFER_DATA_DIRECTION, 0);
+			/* See table 2-8 Host Controller spec ver 1.00 */
+			xfer_reg = SFIELD(xfer_reg, XFER_BLK_COUNT_EN, 0); /* Dont care */
+			xfer_reg = SFIELD(xfer_reg, XFER_MULTI_BLOCK, 0);
+
+			sdstd_wreg16(sdioh_info, SD_BlockSize,  bytes);
+
+			/* XXX This should be a don't care but Arasan needs it
+			 * to be one.  Its fixed in later versions (but they
+			 * don't have version numbers, sigh).
+			 */
+			sdstd_wreg16(sdioh_info, SD_BlockCount, 1);
+
+			retries = RETRIES_SMALL;
+			while (GFIELD(sdstd_rreg(sdioh_info, SD_PresentState),
+			              PRES_DAT_INHIBIT) && --retries)
+				sd_err(("%s: Waiting for Data Inhibit cmd = %d\n",
+				        __FUNCTION__, cmd));
+			if (!retries) {
+				sd_err(("%s: Data Inhibit timeout\n", __FUNCTION__));
+				if (trap_errs)
+					ASSERT(0);
+				return ERROR;
+			}
+
+			/* Consider deferring this write to the comment below "Deferred Write" */
+			sdstd_wreg16(sdioh_info, SD_TransferMode, xfer_reg);
+		}
+		break;
+
+	default:
+		sd_err(("%s: Unknown command\n", __FUNCTION__));
+		return ERROR;
+	}
+
+	if (sdioh_info->sd_mode == SDIOH_MODE_SPI) {
+		cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0);
+		cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0);
+	}
+
+	/* Setup and issue the SDIO command */
+	sdstd_wreg(sdioh_info, SD_Arg0, arg);
+
+	/* Deferred Write
+	 * Consider deferring the two writes above until this point in the code.
+	 * The following would do one 32 bit write.
+	 *
+	 * {
+	 *	uint32 tmp32 = cmd_reg << 16;
+	 *	tmp32 |= xfer_reg;
+	 *	sdstd_wreg(sdioh_info, SD_TransferMode, tmp32);
+	 * }
+	 */
+
+	/* Alternate to Deferred Write START */
+
+	/* In response to CMD19 card sends 64 byte magic pattern.
+	 * So SD_BlockSize = 64 & SD_BlockCount = 1
+	*/
+	if (GFIELD(cmd_reg, CMD_INDEX) == SDIOH_CMD_19) {
+		sdstd_wreg16(sdioh_info, SD_TransferMode, xfer_reg);
+		sdstd_wreg16(sdioh_info, SD_BlockSize, 64);
+		sdstd_wreg16(sdioh_info, SD_BlockCount, 1);
+	}
+	sdstd_wreg16(sdioh_info, SD_Command, cmd_reg);
+
+	/* Alternate to Deferred Write END */
+
+	/* If we are in polled mode, wait for the command to complete.
+	 * In interrupt mode, return immediately. The calling function will
+	 * know that the command has completed when the CMDATDONE interrupt
+	 * is asserted
+	 */
+	if (sdioh_info->polled_mode) {
+		uint16 int_reg = 0;
+		retries = RETRIES_LARGE;
+
+		/* For CMD19 no need to wait for cmd completion */
+		if (GFIELD(cmd_reg, CMD_INDEX) == SDIOH_CMD_19)
+			return SUCCESS;
+
+		do {
+			int_reg = sdstd_rreg16(sdioh_info, SD_IntrStatus);
+			sdstd_os_yield(sdioh_info);
+		} while (--retries &&
+		         (GFIELD(int_reg, INTSTAT_ERROR_INT) == 0) &&
+		         (GFIELD(int_reg, INTSTAT_CMD_COMPLETE) == 0));
+
+		if (!retries) {
+			sd_err(("%s: CMD_COMPLETE timeout: intrStatus: 0x%x "
+			        "error stat 0x%x state 0x%x\n",
+			        __FUNCTION__, int_reg,
+			        sdstd_rreg16(sdioh_info, SD_ErrorIntrStatus),
+			        sdstd_rreg(sdioh_info, SD_PresentState)));
+
+			/* Attempt to reset CMD line when we get a CMD timeout */
+			sdstd_wreg8(sdioh_info, SD_SoftwareReset, SFIELD(0, SW_RESET_CMD, 1));
+			retries = RETRIES_LARGE;
+			do {
+				sd_trace(("%s: waiting for CMD line reset\n", __FUNCTION__));
+			} while ((GFIELD(sdstd_rreg8(sdioh_info, SD_SoftwareReset),
+			                 SW_RESET_CMD)) && retries--);
+
+			if (!retries) {
+				sd_err(("%s: Timeout waiting for CMD line reset\n", __FUNCTION__));
+			}
+
+			if (trap_errs)
+				ASSERT(0);
+			return (ERROR);
+		}
+
+		/* Clear Command Complete interrupt */
+		int_reg = SFIELD(0, INTSTAT_CMD_COMPLETE, 1);
+		sdstd_wreg16(sdioh_info, SD_IntrStatus, int_reg);
+
+		/* Check for Errors */
+		if (sdstd_check_errs(sdioh_info, cmd, arg)) {
+			if (trap_errs)
+				ASSERT(0);
+			return ERROR;
+		}
+	}
+	return SUCCESS;
+}
+
+/*
+ * XXX On entry: If single block or non-block, buffersize <= blocksize.
+ * If Mulitblock, buffersize is unlimited.
+ * Question is how to handle the leftovers in either single or multiblock.
+ * I think the caller should break the buffer up so this routine will always
+ * use blocksize == buffersize to handle the end piece of the buffer
+ */
+
+static int
+sdstd_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo, uint32 addr, int nbytes, uint32 *data)
+{
+	int retval = SUCCESS;
+	int status;
+	uint32 cmd_arg;
+	uint32 rsp5;
+	uint16 int_reg, int_bit;
+	uint flags;
+	int num_blocks, blocksize;
+	bool local_blockmode, local_dma;
+	bool read = rw == SDIOH_READ ? 1 : 0;
+	bool local_yield = FALSE;
+#ifdef BCMSDIOH_TXGLOM
+	uint32 i;
+	uint8 *localbuf = NULL;
+#endif
+
+	ASSERT(nbytes);
+
+	cmd_arg = 0;
+
+	sd_data(("%s: %s 53 addr 0x%x, len %d bytes, r_cnt %d t_cnt %d\n",
+	         __FUNCTION__, read ? "Rd" : "Wr", addr, nbytes, sd->r_cnt, sd->t_cnt));
+
+	if (read) sd->r_cnt++; else sd->t_cnt++;
+
+	local_blockmode = sd->sd_blockmode;
+	local_dma = USE_DMA(sd);
+
+#ifdef BCMSDIOH_TXGLOM
+	/* If multiple buffers are there, then calculate the nbytes from that */
+	if (!read && (func == SDIO_FUNC_2) && (sd->glom_info.count != 0)) {
+		uint32 ii;
+		nbytes = 0;
+		for (ii = 0; ii < sd->glom_info.count; ii++) {
+			nbytes += sd->glom_info.nbytes[ii];
+		}
+		ASSERT(nbytes <= sd->alloced_dma_size);
+	}
+#endif
+
+	/* Don't bother with block mode on small xfers */
+	if (nbytes < sd->client_block_size[func]) {
+		sd_data(("setting local blockmode to false: nbytes (%d) != block_size (%d)\n",
+		         nbytes, sd->client_block_size[func]));
+		local_blockmode = FALSE;
+		local_dma = FALSE;
+#ifdef BCMSDIOH_TXGLOM
+		/* In glommed case, create a single pkt from multiple pkts */
+		if (!read && (func == SDIO_FUNC_2) && (sd->glom_info.count != 0)) {
+			uint32 offset = 0;
+			localbuf = (uint8 *)MALLOC(sd->osh, nbytes);
+			data = (uint32 *)localbuf;
+			for (i = 0; i < sd->glom_info.count; i++) {
+				bcopy(sd->glom_info.dma_buf_arr[i],
+					((uint8 *)data + offset),
+					sd->glom_info.nbytes[i]);
+				offset += sd->glom_info.nbytes[i];
+			}
+		}
+#endif
+	}
+
+	if (local_blockmode) {
+		blocksize = MIN(sd->client_block_size[func], nbytes);
+		num_blocks = nbytes/blocksize;
+		cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, num_blocks);
+		cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 1);
+	} else {
+		num_blocks =  1;
+		blocksize = nbytes;
+		cmd_arg = SFIELD(cmd_arg, CMD53_BYTE_BLK_CNT, nbytes);
+		cmd_arg = SFIELD(cmd_arg, CMD53_BLK_MODE, 0);
+	}
+
+	if (local_dma && !read) {
+#ifdef BCMSDIOH_TXGLOM
+		if ((func == SDIO_FUNC_2) && (sd->glom_info.count != 0)) {
+			/* In case of hc ver 2 DMA_MAP may not work properly due to 4K alignment
+			 * requirements. So copying pkt to 4K aligned pre-allocated pkt.
+			 * Total length should not cross the pre-alloced memory size
+			 */
+			if (sd->txglom_mode == SDPCM_TXGLOM_CPY) {
+				uint32 total_bytes = 0;
+				for (i = 0; i < sd->glom_info.count; i++) {
+					bcopy(sd->glom_info.dma_buf_arr[i],
+						(uint8 *)sd->dma_buf + total_bytes,
+						sd->glom_info.nbytes[i]);
+					total_bytes += sd->glom_info.nbytes[i];
+				}
+				sd_sync_dma(sd, read, total_bytes);
+			}
+		} else
+#endif /* BCMSDIOH_TXGLOM */
+		{
+			bcopy(data, sd->dma_buf, nbytes);
+			sd_sync_dma(sd, read, nbytes);
+		}
+	}
+
+	if (fifo)
+		cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 0);	/* XXX SDIO spec v 1.10, Sec 5.3  */
+	else
+		cmd_arg = SFIELD(cmd_arg, CMD53_OP_CODE, 1);	/* XXX SDIO spec v 1.10, Sec 5.3  */
+
+	cmd_arg = SFIELD(cmd_arg, CMD53_FUNCTION, func);
+	cmd_arg = SFIELD(cmd_arg, CMD53_REG_ADDR, addr);
+	if (read)
+		cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_READ);
+	else
+		cmd_arg = SFIELD(cmd_arg, CMD53_RW_FLAG, SDIOH_XFER_TYPE_WRITE);
+
+	sd->data_xfer_count = nbytes;
+
+	/* sdstd_cmd_issue() returns with the command complete bit
+	 * in the ISR already cleared
+	 */
+	if ((status = sdstd_cmd_issue(sd, local_dma, SDIOH_CMD_53, cmd_arg)) != SUCCESS) {
+		sd_err(("%s: cmd_issue failed for %s\n", __FUNCTION__, (read ? "read" : "write")));
+		retval = status;
+		goto done;
+	}
+
+	sdstd_cmd_getrsp(sd, &rsp5, 1);
+
+	if ((flags = GFIELD(rsp5, RSP5_FLAGS)) != 0x10) {
+		sd_err(("%s: Rsp5: nbytes %d, dma %d blockmode %d, read %d "
+		        "numblocks %d, blocksize %d\n",
+		        __FUNCTION__, nbytes, local_dma, local_dma, read, num_blocks, blocksize));
+
+		if (flags & 1)
+			sd_err(("%s: rsp5: Command not accepted: arg out of range 0x%x, "
+			        "bytes %d dma %d\n",
+			        __FUNCTION__, flags, GFIELD(cmd_arg, CMD53_BYTE_BLK_CNT),
+			        GFIELD(cmd_arg, CMD53_BLK_MODE)));
+		if (flags & 0x8)
+			sd_err(("%s: Rsp5: General Error\n", __FUNCTION__));
+
+		sd_err(("%s: rsp5 flags = 0x%x, expecting 0x10 returning error\n",
+		        __FUNCTION__,  flags));
+		if (trap_errs)
+			ASSERT(0);
+		retval = ERROR;
+		goto done;
+	}
+
+	if (GFIELD(rsp5, RSP5_STUFF))
+		sd_err(("%s: rsp5 stuff is 0x%x: expecting 0\n",
+		        __FUNCTION__, GFIELD(rsp5, RSP5_STUFF)));
+
+#ifdef BCMSDYIELD
+	local_yield = sd_yieldcpu && ((uint)nbytes >= sd_minyield);
+#endif
+
+	if (!local_dma) {
+		int bytes, ii;
+		uint32 tmp;
+
+		for (ii = 0; ii < num_blocks; ii++) {
+			int words;
+
+			/* Decide which status bit we're waiting for */
+			if (read)
+				int_bit = SFIELD(0, INTSTAT_BUF_READ_READY, 1);
+			else
+				int_bit = SFIELD(0, INTSTAT_BUF_WRITE_READY, 1);
+
+			/* If not on, wait for it (or for xfer error) */
+			int_reg = sdstd_rreg16(sd, SD_IntrStatus);
+			if (!(int_reg & int_bit)) {
+				status = sdstd_waitbits(sd, int_bit, ERRINT_TRANSFER_ERRS,
+				                        local_yield, &int_reg);
+				switch (status) {
+				case -1:
+					sd_err(("%s: pio interrupted\n", __FUNCTION__));
+					retval = ERROR;
+					goto done;
+				case -2:
+					sd_err(("%s: pio timeout waiting for interrupt\n",
+					        __FUNCTION__));
+					retval = ERROR;
+					goto done;
+				}
+			}
+#ifdef BCMSLTGT
+		/*	int_reg = sdstd_rreg16(sd, SD_IntrStatus); */
+#endif
+			/* Confirm we got the bit w/o error */
+			if (!(int_reg & int_bit) || GFIELD(int_reg, INTSTAT_ERROR_INT)) {
+				sd_err(("%s: Error or timeout for Buf_%s_Ready: intStat: 0x%x "
+				        "errint: 0x%x PresentState 0x%x\n",
+				        __FUNCTION__, read ? "Read" : "Write", int_reg,
+				        sdstd_rreg16(sd, SD_ErrorIntrStatus),
+				        sdstd_rreg(sd, SD_PresentState)));
+				sdstd_dumpregs(sd);
+				sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg);
+				retval = ERROR;
+				goto done;
+			}
+
+			/* Clear Buf Ready bit */
+			sdstd_wreg16(sd, SD_IntrStatus, int_bit);
+
+			/* At this point we have Buffer Ready, write the data 4 bytes at a time */
+			for (words = blocksize/4; words; words--) {
+				if (read)
+					*data = sdstd_rreg(sd, SD_BufferDataPort0);
+				else
+					sdstd_wreg(sd, SD_BufferDataPort0, *data);
+				data++;
+			}
+
+			/* XXX
+			 * Handle < 4 bytes.  wlc_pio.c currently (as of 12/20/05) truncates buflen
+			 * to be evenly divisible by 4.  However dongle passes arbitrary lengths,
+			 * so handle it here
+			 */
+			bytes = blocksize % 4;
+
+			/* If no leftover bytes, go to next block */
+			if (!bytes)
+				continue;
+
+			switch (bytes) {
+			case 1:
+				/* R/W 8 bits */
+				if (read)
+					*(data++) = (uint32)(sdstd_rreg8(sd, SD_BufferDataPort0));
+				else
+					sdstd_wreg8(sd, SD_BufferDataPort0,
+					            (uint8)(*(data++) & 0xff));
+				break;
+			case 2:
+				/* R/W 16 bits */
+				if (read)
+					*(data++) = (uint32)sdstd_rreg16(sd, SD_BufferDataPort0);
+				else
+					sdstd_wreg16(sd, SD_BufferDataPort0, (uint16)(*(data++)));
+				break;
+			case 3:
+				/* R/W 24 bits:
+				 * SD_BufferDataPort0[0-15] | SD_BufferDataPort1[16-23]
+				 */
+				if (read) {
+					tmp = (uint32)sdstd_rreg16(sd, SD_BufferDataPort0);
+					tmp |= ((uint32)(sdstd_rreg8(sd,
+					                             SD_BufferDataPort1)) << 16);
+					*(data++) = tmp;
+				} else {
+					tmp = *(data++);
+					sdstd_wreg16(sd, SD_BufferDataPort0, (uint16)tmp & 0xffff);
+					sdstd_wreg8(sd, SD_BufferDataPort1,
+					            (uint8)((tmp >> 16) & 0xff));
+				}
+				break;
+			default:
+				sd_err(("%s: Unexpected bytes leftover %d\n",
+				        __FUNCTION__, bytes));
+				ASSERT(0);
+				break;
+			}
+		}
+	}	/* End PIO processing */
+
+	/* Wait for Transfer Complete or Transfer Error */
+	int_bit = SFIELD(0, INTSTAT_XFER_COMPLETE, 1);
+
+	/* If not on, wait for it (or for xfer error) */
+	int_reg = sdstd_rreg16(sd, SD_IntrStatus);
+	if (!(int_reg & int_bit)) {
+		status = sdstd_waitbits(sd, int_bit, ERRINT_TRANSFER_ERRS, local_yield, &int_reg);
+		switch (status) {
+		case -1:
+			sd_err(("%s: interrupted\n", __FUNCTION__));
+			retval = ERROR;
+			goto done;
+		case -2:
+			sd_err(("%s: timeout waiting for interrupt\n", __FUNCTION__));
+			retval = ERROR;
+			goto done;
+		}
+	}
+
+	/* Check for any errors from the data phase */
+	if (sdstd_check_errs(sd, SDIOH_CMD_53, cmd_arg)) {
+		retval = ERROR;
+		goto done;
+	}
+
+	/* May have gotten a software timeout if not blocking? */
+	int_reg = sdstd_rreg16(sd, SD_IntrStatus);
+	if (!(int_reg & int_bit)) {
+		sd_err(("%s: Error or Timeout for xfer complete; %s, dma %d, State 0x%08x, "
+		        "intr 0x%04x, Err 0x%04x, len = %d, rcnt %d, tcnt %d\n",
+		        __FUNCTION__, read ? "R" : "W", local_dma,
+		        sdstd_rreg(sd, SD_PresentState), int_reg,
+		        sdstd_rreg16(sd, SD_ErrorIntrStatus), nbytes,
+		        sd->r_cnt, sd->t_cnt));
+		sdstd_dumpregs(sd);
+		retval = ERROR;
+		goto done;
+	}
+
+	/* Clear the status bits */
+	int_reg = int_bit;
+	if (local_dma) {
+		/* DMA Complete */
+		/* XXX Step 14, Section 3.6.2.2 Stnd Cntrlr Spec */
+		/* Reads in particular don't have DMA_COMPLETE set */
+		int_reg = SFIELD(int_reg, INTSTAT_DMA_INT, 1);
+	}
+	sdstd_wreg16(sd, SD_IntrStatus, int_reg);
+
+	/* Fetch data */
+	if (local_dma && read) {
+		sd_sync_dma(sd, read, nbytes);
+		bcopy(sd->dma_buf, data, nbytes);
+	}
+
+done:
+#ifdef BCMSDIOH_TXGLOM
+	if (localbuf)
+		MFREE(sd->osh, localbuf, nbytes);
+#endif
+	return retval;
+}
+
+static int
+set_client_block_size(sdioh_info_t *sd, int func, int block_size)
+{
+	int base;
+	int err = 0;
+
+	sd_err(("%s: Setting block size %d, func %d\n", __FUNCTION__, block_size, func));
+	sd->client_block_size[func] = block_size;
+
+	/* Set the block size in the SDIO Card register */
+	base = func * SDIOD_FBR_SIZE;
+	err = sdstd_card_regwrite(sd, 0, base+SDIOD_CCCR_BLKSIZE_0, 1, block_size & 0xff);
+	if (!err) {
+		err = sdstd_card_regwrite(sd, 0, base+SDIOD_CCCR_BLKSIZE_1, 1,
+		                          (block_size >> 8) & 0xff);
+	}
+
+	/* Do not set the block size in the SDIO Host register, that
+	 * is func dependent and will get done on an individual
+	 * transaction basis
+	 */
+
+	return (err ? BCME_SDIO_ERROR : 0);
+}
+
+/* Reset and re-initialize the device */
+int
+sdioh_sdio_reset(sdioh_info_t *si)
+{
+	uint8 hreg;
+
+	/* Reset the attached device (use slower clock for safety) */
+	if (!sdstd_start_clock(si, 128)) {
+			sd_err(("set clock failed!\n"));
+			return ERROR;
+			}
+	sdstd_reset(si, 0, 1);
+
+	/* Reset portions of the host state accordingly */
+	hreg = sdstd_rreg8(si, SD_HostCntrl);
+	hreg = SFIELD(hreg, HOST_HI_SPEED_EN, 0);
+	hreg = SFIELD(hreg, HOST_DATA_WIDTH, 0);
+	si->sd_mode = SDIOH_MODE_SD1;
+
+	/* Reinitialize the card */
+	si->card_init_done = FALSE;
+	return sdstd_client_init(si);
+}
+
+static void
+sd_map_dma(sdioh_info_t * sd)
+{
+
+	int alloced;
+	void *va;
+	uint dma_buf_size = SD_PAGE;
+
+#ifdef BCMSDIOH_TXGLOM
+	/* There is no alignment requirement for HC3 */
+	if ((sd->version == HOST_CONTR_VER_3) && sd_txglom) {
+		/* Max glom packet length is 64KB */
+		dma_buf_size = SD_PAGE * 16;
+	}
+#endif
+
+	alloced = 0;
+	if ((va = DMA_ALLOC_CONSISTENT(sd->osh, dma_buf_size, SD_PAGE_BITS, &alloced,
+		&sd->dma_start_phys, 0x12)) == NULL) {
+		sd->sd_dma_mode = DMA_MODE_NONE;
+		sd->dma_start_buf = 0;
+		sd->dma_buf = (void *)0;
+		sd->dma_phys = 0;
+		sd->alloced_dma_size = 0;
+		sd_err(("%s: DMA_ALLOC failed. Disabling DMA support.\n", __FUNCTION__));
+	} else {
+		sd->dma_start_buf = va;
+		sd->dma_buf = (void *)ROUNDUP((uintptr)va, SD_PAGE);
+		sd->dma_phys = ROUNDUP((sd->dma_start_phys), SD_PAGE);
+		sd->alloced_dma_size = alloced;
+		sd_err(("%s: Mapped DMA Buffer %dbytes @virt/phys: %p/0x%x-0x%x\n",
+		        __FUNCTION__, sd->alloced_dma_size, sd->dma_buf,
+		        (uint)PHYSADDRHI(sd->dma_phys), (uint)PHYSADDRLO(sd->dma_phys)));
+		sd_fill_dma_data_buf(sd, 0xA5);
+	}
+
+	if ((va = DMA_ALLOC_CONSISTENT(sd->osh, SD_PAGE, SD_PAGE_BITS, &alloced,
+		&sd->adma2_dscr_start_phys, 0x12)) == NULL) {
+		sd->sd_dma_mode = DMA_MODE_NONE;
+		sd->adma2_dscr_start_buf = 0;
+		sd->adma2_dscr_buf = (void *)0;
+		sd->adma2_dscr_phys = 0;
+		sd->alloced_adma2_dscr_size = 0;
+		sd_err(("%s: DMA_ALLOC failed for descriptor buffer. "
+		        "Disabling DMA support.\n", __FUNCTION__));
+	} else {
+		sd->adma2_dscr_start_buf = va;
+		sd->adma2_dscr_buf = (void *)ROUNDUP((uintptr)va, SD_PAGE);
+		sd->adma2_dscr_phys = ROUNDUP((sd->adma2_dscr_start_phys), SD_PAGE);
+		sd->alloced_adma2_dscr_size = alloced;
+		sd_err(("%s: Mapped ADMA2 Descriptor Buffer %dbytes @virt/phys: %p/0x%x-0x%x\n",
+		        __FUNCTION__, sd->alloced_adma2_dscr_size, sd->adma2_dscr_buf,
+		        (uint)PHYSADDRHI(sd->adma2_dscr_phys),
+			(uint)PHYSADDRLO(sd->adma2_dscr_phys)));
+		sd_clear_adma_dscr_buf(sd);
+	}
+}
+
+static void
+sd_unmap_dma(sdioh_info_t * sd)
+{
+	if (sd->dma_start_buf) {
+		DMA_FREE_CONSISTENT(sd->osh, sd->dma_start_buf, sd->alloced_dma_size,
+			sd->dma_start_phys, 0x12);
+	}
+
+	if (sd->adma2_dscr_start_buf) {
+		DMA_FREE_CONSISTENT(sd->osh, sd->adma2_dscr_start_buf, sd->alloced_adma2_dscr_size,
+		                    sd->adma2_dscr_start_phys, 0x12);
+	}
+}
+
+static void
+sd_clear_adma_dscr_buf(sdioh_info_t *sd)
+{
+	bzero((char *)sd->adma2_dscr_buf, SD_PAGE);
+	sd_dump_adma_dscr(sd);
+}
+
+static void
+sd_fill_dma_data_buf(sdioh_info_t *sd, uint8 data)
+{
+	memset((char *)sd->dma_buf, data, SD_PAGE);
+}
+
+static void
+sd_create_adma_descriptor(sdioh_info_t *sd, uint32 index,
+                          uint32 addr_phys, uint16 length, uint16 flags)
+{
+	adma2_dscr_32b_t *adma2_dscr_table;
+	adma1_dscr_t *adma1_dscr_table;
+
+	adma2_dscr_table = sd->adma2_dscr_buf;
+	adma1_dscr_table = sd->adma2_dscr_buf;
+
+	switch (sd->sd_dma_mode) {
+		case DMA_MODE_ADMA2:
+			sd_dma(("%s: creating ADMA2 descriptor for index %d\n",
+				__FUNCTION__, index));
+
+			adma2_dscr_table[index].phys_addr = addr_phys;
+			adma2_dscr_table[index].len_attr = length << 16;
+			adma2_dscr_table[index].len_attr |= flags;
+			break;
+		case DMA_MODE_ADMA1:
+			/* ADMA1 requires two descriptors, one for len
+			 * and the other for data transfer
+			 */
+			index <<= 1;
+
+			sd_dma(("%s: creating ADMA1 descriptor for index %d\n",
+				__FUNCTION__, index));
+
+			adma1_dscr_table[index].phys_addr_attr = length << 12;
+			adma1_dscr_table[index].phys_addr_attr |= (ADMA1_ATTRIBUTE_ACT_SET |
+			                                           ADMA2_ATTRIBUTE_VALID);
+			adma1_dscr_table[index+1].phys_addr_attr = addr_phys & 0xFFFFF000;
+			adma1_dscr_table[index+1].phys_addr_attr |= (flags & 0x3f);
+			break;
+		default:
+			sd_err(("%s: cannot create ADMA descriptor for DMA mode %d\n",
+				__FUNCTION__, sd->sd_dma_mode));
+			break;
+	}
+}
+
+static void
+sd_dump_adma_dscr(sdioh_info_t *sd)
+{
+	adma2_dscr_32b_t *adma2_dscr_table;
+	adma1_dscr_t *adma1_dscr_table;
+	uint32 i = 0;
+	uint16 flags;
+	char flags_str[32];
+
+	ASSERT(sd->adma2_dscr_buf != NULL);
+
+	adma2_dscr_table = sd->adma2_dscr_buf;
+	adma1_dscr_table = sd->adma2_dscr_buf;
+
+	switch (sd->sd_dma_mode) {
+		case DMA_MODE_ADMA2:
+			sd_err(("ADMA2 Descriptor Table (%dbytes) @virt/phys: %p/0x%x-0x%x\n",
+				SD_PAGE, sd->adma2_dscr_buf,
+			        (uint)PHYSADDRHI(sd->adma2_dscr_phys),
+			        (uint)PHYSADDRLO(sd->adma2_dscr_phys)));
+			sd_err((" #[Descr VA  ]  Buffer PA  | Len    | Flags  (5:4  2   1   0)"
+			        "     |\n"));
+			while (adma2_dscr_table->len_attr & ADMA2_ATTRIBUTE_VALID) {
+				flags = adma2_dscr_table->len_attr & 0xFFFF;
+				sprintf(flags_str, "%s%s%s%s",
+					((flags & ADMA2_ATTRIBUTE_ACT_LINK) ==
+					ADMA2_ATTRIBUTE_ACT_LINK) ? "LINK " :
+					((flags & ADMA2_ATTRIBUTE_ACT_LINK) ==
+					ADMA2_ATTRIBUTE_ACT_TRAN) ? "TRAN " :
+					((flags & ADMA2_ATTRIBUTE_ACT_LINK) ==
+					ADMA2_ATTRIBUTE_ACT_NOP) ? "NOP  " : "RSV  ",
+					(flags & ADMA2_ATTRIBUTE_INT ? "INT " : "    "),
+					(flags & ADMA2_ATTRIBUTE_END ? "END " : "    "),
+					(flags & ADMA2_ATTRIBUTE_VALID ? "VALID" : ""));
+				sd_err(("%2d[0x%p]: 0x%08x | 0x%04x | 0x%04x (%s) |\n",
+				        i, adma2_dscr_table, adma2_dscr_table->phys_addr,
+				        adma2_dscr_table->len_attr >> 16, flags, flags_str));
+				i++;
+
+#ifdef linux
+				/* Follow LINK descriptors or skip to next. */
+				if ((flags & ADMA2_ATTRIBUTE_ACT_LINK) ==
+				     ADMA2_ATTRIBUTE_ACT_LINK) {
+					adma2_dscr_table = phys_to_virt(
+					    adma2_dscr_table->phys_addr);
+				} else {
+					adma2_dscr_table++;
+				}
+#else
+				adma2_dscr_table++;
+#endif /* linux */
+
+			}
+			break;
+		case DMA_MODE_ADMA1:
+			sd_err(("ADMA1 Descriptor Table (%dbytes) @virt/phys: %p/0x%x-0x%x\n",
+			         SD_PAGE, sd->adma2_dscr_buf,
+			        (uint)PHYSADDRHI(sd->adma2_dscr_phys),
+			        (uint)PHYSADDRLO(sd->adma2_dscr_phys)));
+			sd_err((" #[Descr VA  ]  Buffer PA  | Flags  (5:4  2   1   0)     |\n"));
+
+			for (i = 0; adma1_dscr_table->phys_addr_attr & ADMA2_ATTRIBUTE_VALID; i++) {
+				flags = adma1_dscr_table->phys_addr_attr & 0x3F;
+				sprintf(flags_str, "%s%s%s%s",
+					((flags & ADMA2_ATTRIBUTE_ACT_LINK) ==
+					ADMA2_ATTRIBUTE_ACT_LINK) ? "LINK " :
+					((flags & ADMA2_ATTRIBUTE_ACT_LINK) ==
+					ADMA2_ATTRIBUTE_ACT_TRAN) ? "TRAN " :
+					((flags & ADMA2_ATTRIBUTE_ACT_LINK) ==
+					ADMA2_ATTRIBUTE_ACT_NOP) ? "NOP  " : "SET  ",
+					(flags & ADMA2_ATTRIBUTE_INT ? "INT " : "    "),
+					(flags & ADMA2_ATTRIBUTE_END ? "END " : "    "),
+					(flags & ADMA2_ATTRIBUTE_VALID ? "VALID" : ""));
+				sd_err(("%2d[0x%p]: 0x%08x | 0x%04x | (%s) |\n",
+				        i, adma1_dscr_table,
+				        adma1_dscr_table->phys_addr_attr & 0xFFFFF000,
+				        flags, flags_str));
+
+#ifdef linux
+				/* Follow LINK descriptors or skip to next. */
+				if ((flags & ADMA2_ATTRIBUTE_ACT_LINK) ==
+				     ADMA2_ATTRIBUTE_ACT_LINK) {
+					adma1_dscr_table = phys_to_virt(
+						adma1_dscr_table->phys_addr_attr & 0xFFFFF000);
+				} else {
+					adma1_dscr_table++;
+				}
+#else
+				adma2_dscr_table++;
+#endif /* linux */
+			}
+			break;
+		default:
+			sd_err(("Unknown DMA Descriptor Table Format.\n"));
+			break;
+	}
+}
+
+static void
+sdstd_dumpregs(sdioh_info_t *sd)
+{
+	sd_err(("IntrStatus:       0x%04x ErrorIntrStatus       0x%04x\n",
+	            sdstd_rreg16(sd, SD_IntrStatus),
+	            sdstd_rreg16(sd, SD_ErrorIntrStatus)));
+	sd_err(("IntrStatusEnable: 0x%04x ErrorIntrStatusEnable 0x%04x\n",
+	            sdstd_rreg16(sd, SD_IntrStatusEnable),
+	            sdstd_rreg16(sd, SD_ErrorIntrStatusEnable)));
+	sd_err(("IntrSignalEnable: 0x%04x ErrorIntrSignalEnable 0x%04x\n",
+	            sdstd_rreg16(sd, SD_IntrSignalEnable),
+	            sdstd_rreg16(sd, SD_ErrorIntrSignalEnable)));
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcmsdstd.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcmsdstd.h
@@ -0,0 +1,317 @@
+/*
+ *  'Standard' SDIO HOST CONTROLLER driver
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id: bcmsdstd.h 833030 2019-08-02 17:22:42Z $
+ */
+#ifndef	_BCM_SD_STD_H
+#define	_BCM_SD_STD_H
+
+/* global msglevel for debug messages - bitvals come from sdiovar.h */
+#ifdef BCMDBG
+#define sd_err(x)	do { if (sd_msglevel & SDH_ERROR_VAL) printf x; } while (0)
+#define sd_trace(x)	do { if (sd_msglevel & SDH_TRACE_VAL) printf x; } while (0)
+#define sd_info(x)	do { if (sd_msglevel & SDH_INFO_VAL)  printf x; } while (0)
+#define sd_debug(x)	do { if (sd_msglevel & SDH_DEBUG_VAL) printf x; } while (0)
+#define sd_data(x)	do { if (sd_msglevel & SDH_DATA_VAL)  printf x; } while (0)
+#define sd_ctrl(x)	do { if (sd_msglevel & SDH_CTRL_VAL)  printf x; } while (0)
+#define sd_dma(x)	do { if (sd_msglevel & SDH_DMA_VAL)  printf x; } while (0)
+#else
+#define sd_err(x)	do { if (sd_msglevel & SDH_ERROR_VAL) printf x; } while (0)
+#define sd_trace(x)
+#define sd_info(x)
+#define sd_debug(x)
+#define sd_data(x)
+#define sd_ctrl(x)
+#define sd_dma(x)
+#endif /* BCMDBG */
+
+#define sd_sync_dma(sd, read, nbytes)
+#define sd_init_dma(sd)
+#define sd_ack_intr(sd)
+#define sd_wakeup(sd);
+/* Allocate/init/free per-OS private data */
+extern int sdstd_osinit(sdioh_info_t *sd);
+extern void sdstd_osfree(sdioh_info_t *sd);
+
+#ifdef BCMPERFSTATS
+#define sd_log(x)	do { if (sd_msglevel & SDH_LOG_VAL)	 bcmlog x; } while (0)
+#else
+#define sd_log(x)
+#endif
+
+#define SDIOH_ASSERT(exp) \
+	do { if (!(exp)) \
+		printf("!!!ASSERT fail: file %s lines %d", __FILE__, __LINE__); \
+	} while (0)
+
+#define BLOCK_SIZE_4318 64
+#define BLOCK_SIZE_4328 512
+
+/* internal return code */
+#define SUCCESS	0
+#define ERROR	1
+
+/* private bus modes */
+#define SDIOH_MODE_SPI		0
+#define SDIOH_MODE_SD1		1
+#define SDIOH_MODE_SD4		2
+
+#define MAX_SLOTS 6 	/* For PCI: Only 6 BAR entries => 6 slots */
+#define SDIOH_REG_WINSZ	0x100 /* Number of registers in Standard Host Controller */
+
+#define SDIOH_TYPE_ARASAN_HDK	1
+#define SDIOH_TYPE_BCM27XX	2
+#define SDIOH_TYPE_TI_PCIXX21	4	/* TI PCIxx21 Standard Host Controller */
+#define SDIOH_TYPE_RICOH_R5C822	5	/* Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter */
+#define SDIOH_TYPE_JMICRON	6	/* JMicron Standard SDIO Host Controller */
+
+/* For linux, allow yielding for dongle */
+#if defined(linux) && defined(BCMDONGLEHOST)
+#define BCMSDYIELD
+#endif
+
+/* Expected card status value for CMD7 */
+#define SDIOH_CMD7_EXP_STATUS   0x00001E00
+
+#define RETRIES_LARGE 100000
+#ifdef BCMQT
+extern void sdstd_os_yield(sdioh_info_t *sd);
+#define RETRIES_SMALL 10000
+#else
+#define sdstd_os_yield(sd)	do {} while (0)
+#define RETRIES_SMALL 100
+#endif
+
+#define USE_BLOCKMODE		0x2	/* Block mode can be single block or multi */
+#define USE_MULTIBLOCK		0x4
+
+#define USE_FIFO		0x8	/* Fifo vs non-fifo */
+
+#define CLIENT_INTR 		0x100	/* Get rid of this! */
+
+#define HC_INTR_RETUNING	0x1000
+
+#ifdef BCMSDIOH_TXGLOM
+/* Total glom pkt can not exceed 64K
+ * need one more slot for glom padding packet
+ */
+#define SDIOH_MAXGLOM_SIZE	(40+1)
+
+typedef struct glom_buf {
+	uint32 count;				/* Total number of pkts queued */
+	void *dma_buf_arr[SDIOH_MAXGLOM_SIZE];	/* Frame address */
+	dmaaddr_t dma_phys_arr[SDIOH_MAXGLOM_SIZE]; /* DMA_MAPed address of frames */
+	uint16 nbytes[SDIOH_MAXGLOM_SIZE];	/* Size of each frame */
+} glom_buf_t;
+#endif
+
+struct sdioh_info {
+	uint cfg_bar;				/* pci cfg address for bar */
+	uint32 caps;				/* cached value of capabilities reg */
+	uint32 curr_caps;			/* max current capabilities reg */
+
+	osl_t		*osh;			/* osh handler */
+	volatile char	*mem_space;		/* pci device memory va */
+	uint		lockcount;		/* nest count of sdstd_lock() calls */
+	bool		client_intr_enabled;	/* interrupt connnected flag */
+	bool		intr_handler_valid;	/* client driver interrupt handler valid */
+	sdioh_cb_fn_t	intr_handler;		/* registered interrupt handler */
+	void		*intr_handler_arg;	/* argument to call interrupt handler */
+	bool		initialized;		/* card initialized */
+	uint		target_dev;		/* Target device ID */
+	uint16		intmask;		/* Current active interrupts */
+	void		*sdos_info;		/* Pointer to per-OS private data */
+	void		*bcmsdh;		/* handler to upper layer stack (bcmsdh) */
+
+	uint32		controller_type;	/* Host controller type */
+	uint8		version;		/* Host Controller Spec Compliance Version */
+	uint		irq;			/* Client irq */
+	int		intrcount;		/* Client interrupts */
+	int		local_intrcount;	/* Controller interrupts */
+	bool		host_init_done;		/* Controller initted */
+	bool		card_init_done;		/* Client SDIO interface initted */
+	bool		polled_mode;		/* polling for command completion */
+
+	bool		sd_blockmode;		/* sd_blockmode == FALSE => 64 Byte Cmd 53s. */
+						/*  Must be on for sd_multiblock to be effective */
+	bool		use_client_ints;	/* If this is false, make sure to restore */
+						/*  polling hack in wl_linux.c:wl_timer() */
+	int		adapter_slot;		/* Maybe dealing with multiple slots/controllers */
+	int		sd_mode;		/* SD1/SD4/SPI */
+	int		client_block_size[SDIOD_MAX_IOFUNCS];		/* Blocksize */
+	uint32		data_xfer_count;	/* Current transfer */
+	uint16		card_rca;		/* Current Address */
+	int8		sd_dma_mode;		/* DMA Mode (PIO, SDMA, ... ADMA2) on CMD53 */
+	uint8		num_funcs;		/* Supported funcs on client */
+	uint32		com_cis_ptr;
+	uint32		func_cis_ptr[SDIOD_MAX_IOFUNCS];
+	void		*dma_buf;		/* DMA Buffer virtual address */
+	dmaaddr_t	dma_phys;		/* DMA Buffer physical address */
+	void		*adma2_dscr_buf;	/* ADMA2 Descriptor Buffer virtual address */
+	dmaaddr_t	adma2_dscr_phys;	/* ADMA2 Descriptor Buffer physical address */
+
+	/* adjustments needed to make the dma align properly */
+	void		*dma_start_buf;
+	dmaaddr_t	dma_start_phys;
+	uint		alloced_dma_size;
+	void		*adma2_dscr_start_buf;
+	dmaaddr_t	adma2_dscr_start_phys;
+	uint		alloced_adma2_dscr_size;
+
+	int		r_cnt;			/* rx count */
+	int		t_cnt;			/* tx_count */
+	bool		got_hcint;		/* local interrupt flag */
+	uint16		last_intrstatus;	/* to cache intrstatus */
+	int	host_UHSISupported;		/* whether UHSI is supported for HC. */
+	int	card_UHSI_voltage_Supported;	/* whether UHSI is supported for
+						 * Card in terms of Voltage [1.8 or 3.3].
+						 */
+	int	global_UHSI_Supp;	/* type of UHSI support in both host and card.
+					 * HOST_SDR_UNSUPP: capabilities not supported/matched
+					 * HOST_SDR_12_25: SDR12 and SDR25 supported
+					 * HOST_SDR_50_104_DDR: one of SDR50/SDR104 or DDR50 supptd
+					 */
+	volatile int	sd3_dat_state;		/* data transfer state used for retuning check */
+	volatile int	sd3_tun_state;		/* tuning state used for retuning check */
+	bool	sd3_tuning_reqd;	/* tuning requirement parameter */
+	bool	sd3_tuning_disable;	/* tuning disable due to bus sleeping */
+	uint32	caps3;			/* cached value of 32 MSbits capabilities reg (SDIO 3.0) */
+#ifdef BCMSDIOH_TXGLOM
+	glom_buf_t glom_info;		/* pkt information used for glomming */
+	uint	txglom_mode;		/* Txglom mode: 0 - copy, 1 - multi-descriptor */
+#endif
+};
+
+#define DMA_MODE_NONE	0
+#define DMA_MODE_SDMA	1
+#define DMA_MODE_ADMA1	2
+#define DMA_MODE_ADMA2	3
+#define DMA_MODE_ADMA2_64 4
+#define DMA_MODE_AUTO	-1
+
+#define USE_DMA(sd)		((bool)((sd->sd_dma_mode > 0) ? TRUE : FALSE))
+
+/* States for Tuning and corr data */
+#define TUNING_IDLE 			0
+#define TUNING_START 			1
+#define TUNING_START_AFTER_DAT 	2
+#define TUNING_ONGOING 			3
+
+#define DATA_TRANSFER_IDLE 		0
+#define DATA_TRANSFER_ONGOING	1
+
+#define CHECK_TUNING_PRE_DATA	1
+#define CHECK_TUNING_POST_DATA	2
+
+#ifdef DHD_DEBUG
+#define SD_DHD_DISABLE_PERIODIC_TUNING 0x01
+#define SD_DHD_ENABLE_PERIODIC_TUNING  0x00
+#endif
+
+/************************************************************
+ * Internal interfaces: per-port references into bcmsdstd.c
+ */
+
+/* Global message bits */
+extern uint sd_msglevel;
+
+/* OS-independent interrupt handler */
+extern bool check_client_intr(sdioh_info_t *sd);
+
+/* Core interrupt enable/disable of device interrupts */
+extern void sdstd_devintr_on(sdioh_info_t *sd);
+extern void sdstd_devintr_off(sdioh_info_t *sd);
+
+/* Enable/disable interrupts for local controller events */
+extern void sdstd_intrs_on(sdioh_info_t *sd, uint16 norm, uint16 err);
+extern void sdstd_intrs_off(sdioh_info_t *sd, uint16 norm, uint16 err);
+
+/* Wait for specified interrupt and error bits to be set */
+extern void sdstd_spinbits(sdioh_info_t *sd, uint16 norm, uint16 err);
+
+/**************************************************************
+ * Internal interfaces: bcmsdstd.c references to per-port code
+ */
+
+/* Register mapping routines */
+extern uint32 *sdstd_reg_map(osl_t *osh, dmaaddr_t addr, int size);
+extern void sdstd_reg_unmap(osl_t *osh, dmaaddr_t addr, int size);
+
+/* Interrupt (de)registration routines */
+extern int sdstd_register_irq(sdioh_info_t *sd, uint irq);
+extern void sdstd_free_irq(uint irq, sdioh_info_t *sd);
+
+/* OS-specific interrupt wrappers (atomic interrupt enable/disable) */
+extern void sdstd_lock(sdioh_info_t *sd);
+extern void sdstd_unlock(sdioh_info_t *sd);
+extern void sdstd_waitlockfree(sdioh_info_t *sd);
+
+/* OS-specific wrappers for safe concurrent register access */
+extern void sdstd_os_lock_irqsave(sdioh_info_t *sd, ulong* flags);
+extern void sdstd_os_unlock_irqrestore(sdioh_info_t *sd, ulong* flags);
+
+/* OS-specific wait-for-interrupt-or-status */
+extern int sdstd_waitbits(sdioh_info_t *sd, uint16 norm, uint16 err, bool yield, uint16 *bits);
+
+/* used by bcmsdstd_linux [implemented in sdstd] */
+extern void sdstd_3_enable_retuning_int(sdioh_info_t *sd);
+extern void sdstd_3_disable_retuning_int(sdioh_info_t *sd);
+extern bool sdstd_3_is_retuning_int_set(sdioh_info_t *sd);
+extern void sdstd_3_check_and_do_tuning(sdioh_info_t *sd, int tuning_param);
+extern bool sdstd_3_check_and_set_retuning(sdioh_info_t *sd);
+extern int sdstd_3_get_tune_state(sdioh_info_t *sd);
+extern int sdstd_3_get_data_state(sdioh_info_t *sd);
+extern void sdstd_3_set_tune_state(sdioh_info_t *sd, int state);
+extern void sdstd_3_set_data_state(sdioh_info_t *sd, int state);
+extern uint8 sdstd_3_get_tuning_exp(sdioh_info_t *sd);
+extern uint32 sdstd_3_get_uhsi_clkmode(sdioh_info_t *sd);
+extern int sdstd_3_clk_tuning(sdioh_info_t *sd, uint32 sd3ClkMode);
+
+/* used by sdstd [implemented in bcmsdstd_linux/ndis] */
+extern void sdstd_3_start_tuning(sdioh_info_t *sd);
+extern void sdstd_3_osinit_tuning(sdioh_info_t *sd);
+extern void sdstd_3_osclean_tuning(sdioh_info_t *sd);
+
+extern void sdstd_enable_disable_periodic_timer(sdioh_info_t * sd, uint val);
+
+extern sdioh_info_t *sdioh_attach(osl_t *osh, void *bar0, uint irq);
+extern SDIOH_API_RC sdioh_detach(osl_t *osh, sdioh_info_t *sd);
+#endif /* _BCM_SD_STD_H */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcmsdstd_linux.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcmsdstd_linux.c
@@ -0,0 +1,716 @@
+/*
+ *  'Standard' SDIO HOST CONTROLLER driver - linux portion
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <linux/sched.h>	/* request_irq() */
+#include <typedefs.h>
+#include <pcicfg.h>
+#include <bcmutils.h>
+#include <sdio.h>	/* SDIO Device and Protocol Specs */
+#include <sdioh.h> /* SDIO Host Controller Spec header file */
+#include <bcmsdbus.h>	/* bcmsdh to/from specific controller APIs */
+#include <sdiovar.h>	/* to get msglevel bit values */
+#include <bcmsdstd.h>
+#include <bcmdevs.h>
+
+extern void* bcmsdh_probe(osl_t *osh, void *dev, void *sdioh, void *adapter_info, uint bus_type,
+	uint bus_num, uint slot_num);
+extern int bcmsdh_remove(bcmsdh_info_t *bcmsdh);
+
+/* Extern functions for sdio power save */
+extern uint8 sdstd_turn_on_clock(sdioh_info_t *sd);
+extern uint8 sdstd_turn_off_clock(sdioh_info_t *sd);
+/* Extern variable for sdio power save. This is enabled or disabled using the IOCTL call */
+extern uint sd_3_power_save;
+
+struct sdos_info {
+	sdioh_info_t *sd;
+	spinlock_t lock;
+	wait_queue_head_t intr_wait_queue;
+	timer_list_compat_t tuning_timer;
+	int tuning_timer_exp;
+	atomic_t timer_enab;
+	struct tasklet_struct tuning_tasklet;
+};
+
+#define SDSTD_WAITBITS_TIMEOUT		(5 * HZ)	/* seconds * HZ */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+#define BLOCKABLE()	(!in_atomic())
+#else
+#define BLOCKABLE()	(!in_interrupt()) /* XXX Doesn't handle CONFIG_PREEMPT? */
+#endif
+
+static void
+sdstd_3_ostasklet(ulong data);
+static void
+sdstd_3_tuning_timer(ulong data);
+
+/* Interrupt handler */
+static irqreturn_t
+sdstd_isr(int irq, void *dev_id
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
+, struct pt_regs *ptregs
+#endif
+)
+{
+	sdioh_info_t *sd;
+	struct sdos_info *sdos;
+	bool ours;
+
+	unsigned long flags;
+	sd = (sdioh_info_t *)dev_id;
+	sdos = (struct sdos_info *)sd->sdos_info;
+
+	if (!sd->card_init_done) {
+		sd_err(("%s: Hey Bogus intr...not even initted: irq %d\n", __FUNCTION__, irq));
+		return IRQ_RETVAL(FALSE);
+	} else {
+		if (sdstd_3_is_retuning_int_set(sd)) {
+			/* for 3.0 host, retuning request might come in this path */
+			/* * disable ISR's */
+			local_irq_save(flags);
+
+			if (sdstd_3_check_and_set_retuning(sd))
+				tasklet_schedule(&sdos->tuning_tasklet);
+
+			/* * enable back ISR's */
+			local_irq_restore(flags);
+
+			/* * disable tuning isr signaling */
+			sdstd_3_disable_retuning_int(sd);
+			/* * note: check_client_intr() checks for  intmask also to
+				wakeup. so be careful to use sd->intmask to disable
+				re-tuning ISR.
+				*/
+		}
+		ours = check_client_intr(sd);
+
+		/* For local interrupts, wake the waiting process */
+		if (ours && sd->got_hcint) {
+			sd_trace(("INTR->WAKE\n"));
+/* 			sdos = (struct sdos_info *)sd->sdos_info; */
+			wake_up_interruptible(&sdos->intr_wait_queue);
+		}
+		return IRQ_RETVAL(ours);
+	}
+}
+
+/* Register with Linux for interrupts */
+int
+sdstd_register_irq(sdioh_info_t *sd, uint irq)
+{
+	sd_trace(("Entering %s: irq == %d\n", __FUNCTION__, irq));
+	if (request_irq(irq, sdstd_isr, IRQF_SHARED, "bcmsdstd", sd) < 0) {
+		sd_err(("%s: request_irq() failed\n", __FUNCTION__));
+		return ERROR;
+	}
+	return SUCCESS;
+}
+
+/* Free Linux irq */
+void
+sdstd_free_irq(uint irq, sdioh_info_t *sd)
+{
+	free_irq(irq, sd);
+}
+
+/* Map Host controller registers */
+
+uint32 *
+sdstd_reg_map(osl_t *osh, dmaaddr_t addr, int size)
+{
+	return (uint32 *)REG_MAP(addr, size);
+}
+
+void
+sdstd_reg_unmap(osl_t *osh, dmaaddr_t addr, int size)
+{
+	REG_UNMAP((void*)(uintptr)addr);
+}
+
+int
+sdstd_osinit(sdioh_info_t *sd)
+{
+	struct sdos_info *sdos;
+
+	sdos = (struct sdos_info*)MALLOC(sd->osh, sizeof(struct sdos_info));
+	sd->sdos_info = (void*)sdos;
+	if (sdos == NULL)
+		return BCME_NOMEM;
+
+	sdos->sd = sd;
+	spin_lock_init(&sdos->lock);
+	atomic_set(&sdos->timer_enab, FALSE);
+	init_waitqueue_head(&sdos->intr_wait_queue);
+	return BCME_OK;
+}
+
+/* initilize tuning related OS structures */
+void
+sdstd_3_osinit_tuning(sdioh_info_t *sd)
+{
+	struct sdos_info *sdos = (struct sdos_info *)sd->sdos_info;
+	uint8 timer_count = sdstd_3_get_tuning_exp(sdos->sd);
+
+	sd_trace(("%s Enter\n", __FUNCTION__));
+
+	init_timer_compat(&sdos->tuning_timer, sdstd_3_tuning_timer, sdos);
+	if (timer_count == CAP3_RETUNING_TC_DISABLED || timer_count > CAP3_RETUNING_TC_1024S) {
+		sdos->tuning_timer_exp = 0;
+	} else {
+		sdos->tuning_timer_exp = 1 << (timer_count - 1);
+	}
+	tasklet_init(&sdos->tuning_tasklet, sdstd_3_ostasklet, (ulong)sdos);
+	if (sdos->tuning_timer_exp) {
+		timer_expires(&sdos->tuning_timer) = jiffies + sdos->tuning_timer_exp * HZ;
+		add_timer(&sdos->tuning_timer);
+		atomic_set(&sdos->timer_enab, TRUE);
+	}
+}
+
+/* finalize tuning related OS structures */
+void
+sdstd_3_osclean_tuning(sdioh_info_t *sd)
+{
+	struct sdos_info *sdos = (struct sdos_info *)sd->sdos_info;
+	if (atomic_read(&sdos->timer_enab) == TRUE) {
+		/* disable timer if it was running */
+		del_timer_sync(&sdos->tuning_timer);
+		atomic_set(&sdos->timer_enab, FALSE);
+	}
+	tasklet_kill(&sdos->tuning_tasklet);
+}
+
+static void
+sdstd_3_ostasklet(ulong data)
+{
+	struct sdos_info *sdos = (struct sdos_info *)data;
+	int tune_state = sdstd_3_get_tune_state(sdos->sd);
+	int data_state = sdstd_3_get_data_state(sdos->sd);
+	if ((tune_state == TUNING_START) || (tune_state == TUNING_ONGOING) ||
+		(tune_state == TUNING_START_AFTER_DAT)) {
+		return;
+	}
+	else if (data_state == DATA_TRANSFER_IDLE)
+		sdstd_3_set_tune_state(sdos->sd, TUNING_START);
+	else if (data_state == DATA_TRANSFER_ONGOING)
+		sdstd_3_set_tune_state(sdos->sd, TUNING_START_AFTER_DAT);
+}
+
+static void
+sdstd_3_tuning_timer(ulong data)
+{
+	struct sdos_info *sdos = (struct sdos_info *)data;
+/* 	uint8 timeout = 0; */
+	unsigned long int_flags;
+
+	sd_trace(("%s: enter\n", __FUNCTION__));
+	/* schedule tasklet */
+	/* * disable ISR's */
+	local_irq_save(int_flags);
+	if (sdstd_3_check_and_set_retuning(sdos->sd))
+		tasklet_schedule(&sdos->tuning_tasklet);
+
+	/* * enable back ISR's */
+	local_irq_restore(int_flags);
+}
+
+void sdstd_3_start_tuning(sdioh_info_t *sd)
+{
+	int tune_state;
+	unsigned long int_flags = 0;
+	unsigned int timer_enab;
+	struct sdos_info *sdos = (struct sdos_info *)sd->sdos_info;
+	sd_trace(("%s: enter\n", __FUNCTION__));
+	/* * disable ISR's */
+	local_irq_save(int_flags);
+	timer_enab = atomic_read(&sdos->timer_enab);
+
+	tune_state = sdstd_3_get_tune_state(sd);
+
+	if (tune_state == TUNING_ONGOING) {
+		/* do nothing */
+		local_irq_restore(int_flags);
+		goto exit;
+	}
+	/* change state */
+	sdstd_3_set_tune_state(sd, TUNING_ONGOING);
+	/* * enable ISR's */
+	local_irq_restore(int_flags);
+	sdstd_3_clk_tuning(sd, sdstd_3_get_uhsi_clkmode(sd));
+#ifdef BCMSDIOH_STD_TUNING_WAR
+	/*
+	 * Observed intermittent SDIO command error after re-tuning done
+	 * successfully.  Re-tuning twice is giving much reliable results.
+	 */
+	sdstd_3_clk_tuning(sd, sdstd_3_get_uhsi_clkmode(sd));
+#endif /* BCMSDIOH_STD_TUNING_WAR */
+	/* * disable ISR's */
+	local_irq_save(int_flags);
+	sdstd_3_set_tune_state(sd, TUNING_IDLE);
+	/* * enable ISR's */
+	local_irq_restore(int_flags);
+
+	/* enable retuning intrrupt */
+	sdstd_3_enable_retuning_int(sd);
+
+	/* start retuning timer if enabled */
+	if ((sdos->tuning_timer_exp) && (timer_enab)) {
+		if (sd->sd3_tuning_reqd) {
+			timer_expires(&sdos->tuning_timer) = jiffies + sdos->tuning_timer_exp * HZ;
+			mod_timer(&sdos->tuning_timer, timer_expires(&sdos->tuning_timer));
+		}
+	}
+exit:
+	return;
+
+}
+
+void
+sdstd_osfree(sdioh_info_t *sd)
+{
+	struct sdos_info *sdos;
+	ASSERT(sd && sd->sdos_info);
+
+	sdos = (struct sdos_info *)sd->sdos_info;
+	MFREE(sd->osh, sdos, sizeof(struct sdos_info));
+}
+
+/* Interrupt enable/disable */
+SDIOH_API_RC
+sdioh_interrupt_set(sdioh_info_t *sd, bool enable)
+{
+	ulong flags;
+	struct sdos_info *sdos;
+
+	sd_trace(("%s: %s\n", __FUNCTION__, enable ? "Enabling" : "Disabling"));
+
+	sdos = (struct sdos_info *)sd->sdos_info;
+	ASSERT(sdos);
+
+	if (!(sd->host_init_done && sd->card_init_done)) {
+		sd_err(("%s: Card & Host are not initted - bailing\n", __FUNCTION__));
+		return SDIOH_API_RC_FAIL;
+	}
+
+	if (enable && !(sd->intr_handler && sd->intr_handler_arg)) {
+		sd_err(("%s: no handler registered, will not enable\n", __FUNCTION__));
+		return SDIOH_API_RC_FAIL;
+	}
+
+	/* Ensure atomicity for enable/disable calls */
+	spin_lock_irqsave(&sdos->lock, flags);
+
+	sd->client_intr_enabled = enable;
+	if (enable && !sd->lockcount)
+		sdstd_devintr_on(sd);
+	else
+		sdstd_devintr_off(sd);
+
+	spin_unlock_irqrestore(&sdos->lock, flags);
+
+	return SDIOH_API_RC_SUCCESS;
+}
+
+/* Protect against reentrancy (disable device interrupts while executing) */
+void
+sdstd_lock(sdioh_info_t *sd)
+{
+	ulong flags;
+	struct sdos_info *sdos;
+	int    wait_count = 0;
+
+	sdos = (struct sdos_info *)sd->sdos_info;
+	ASSERT(sdos);
+
+	sd_trace(("%s: %d\n", __FUNCTION__, sd->lockcount));
+
+	spin_lock_irqsave(&sdos->lock, flags);
+	while (sd->lockcount)
+	{
+	    spin_unlock_irqrestore(&sdos->lock, flags);
+	    yield();
+		spin_lock_irqsave(&sdos->lock, flags);
+		if (++wait_count == 25000) {
+		    if (!(sd->lockcount == 0)) {
+			sd_err(("%s: ERROR: sd->lockcount == 0\n", __FUNCTION__));
+		    }
+		}
+	}
+	/* PR86684: Add temporary debugging print */
+	if (wait_count)
+		printk("sdstd_lock: wait count = %d\n", wait_count);
+	sdstd_devintr_off(sd);
+	sd->lockcount++;
+	spin_unlock_irqrestore(&sdos->lock, flags);
+	if ((sd->controller_type == SDIOH_TYPE_RICOH_R5C822) && (sd->version == HOST_CONTR_VER_3))
+		sdstd_turn_on_clock(sd);
+}
+
+/* Enable client interrupt */
+void
+sdstd_unlock(sdioh_info_t *sd)
+{
+	ulong flags;
+	struct sdos_info *sdos;
+
+	sd_trace(("%s: %d, %d\n", __FUNCTION__, sd->lockcount, sd->client_intr_enabled));
+	ASSERT(sd->lockcount > 0);
+
+	sdos = (struct sdos_info *)sd->sdos_info;
+	ASSERT(sdos);
+
+	spin_lock_irqsave(&sdos->lock, flags);
+	if (--sd->lockcount == 0 && sd->client_intr_enabled) {
+		sdstd_devintr_on(sd);
+	}
+	spin_unlock_irqrestore(&sdos->lock, flags);
+	if (sd_3_power_save)
+	{
+		if ((sd->controller_type == SDIOH_TYPE_RICOH_R5C822) &&
+			(sd->version == HOST_CONTR_VER_3))
+			sdstd_turn_off_clock(sd);
+	}
+}
+
+void
+sdstd_os_lock_irqsave(sdioh_info_t *sd, ulong* flags)
+{
+	struct sdos_info *sdos = (struct sdos_info *)sd->sdos_info;
+	spin_lock_irqsave(&sdos->lock, *flags);
+}
+void
+sdstd_os_unlock_irqrestore(sdioh_info_t *sd, ulong* flags)
+{
+	struct sdos_info *sdos = (struct sdos_info *)sd->sdos_info;
+	spin_unlock_irqrestore(&sdos->lock, *flags);
+}
+
+void
+sdstd_waitlockfree(sdioh_info_t *sd)
+{
+	if (sd->lockcount) {
+		printk("wait lock free\n");
+		while (sd->lockcount)
+		{
+		    yield();
+		}
+	}
+}
+
+#ifdef BCMQT
+void
+sdstd_os_yield(sdioh_info_t *sd)
+{
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 29))
+/*
+ * FC4/11 issue on QT if driver hogs > 10s of CPU causing:
+ *    BUG: soft lockup detected on CPU#0!
+ *
+ * XXX Hack: For now, interleave yielding of CPU when we're spinning waiting for
+ * XXX register status
+ */
+	yield();
+#endif
+}
+#endif /* BCMQT */
+
+/* Returns 0 for success, -1 for interrupted, -2 for timeout */
+int
+sdstd_waitbits(sdioh_info_t *sd, uint16 norm, uint16 err, bool local_yield, uint16 *bits)
+{
+	struct sdos_info *sdos;
+	int rc = 0;
+
+	sdos = (struct sdos_info *)sd->sdos_info;
+
+#ifndef BCMSDYIELD
+	ASSERT(!local_yield);
+#endif
+	sd_trace(("%s: int 0x%02x err 0x%02x yield %d canblock %d\n",
+	          __FUNCTION__, norm, err, local_yield, BLOCKABLE()));
+
+	/* Clear the "interrupt happened" flag and last intrstatus */
+	sd->got_hcint = FALSE;
+	sd->last_intrstatus = 0;
+
+#ifdef BCMSDYIELD
+	if (local_yield && BLOCKABLE()) {
+		/* Enable interrupts, wait for the indication, then disable */
+		sdstd_intrs_on(sd, norm, err);
+		rc = wait_event_interruptible_timeout(sdos->intr_wait_queue,
+		                                      (sd->got_hcint),
+		                                      SDSTD_WAITBITS_TIMEOUT);
+		if (rc < 0)
+			rc = -1;	/* interrupted */
+		else if (rc == 0)
+			rc = -2;	/* timeout */
+		else
+			rc = 0;		/* success */
+		sdstd_intrs_off(sd, norm, err);
+	} else
+#endif /* BCMSDYIELD */
+	{
+		sdstd_spinbits(sd, norm, err);
+	}
+
+	sd_trace(("%s: last_intrstatus 0x%04x\n", __FUNCTION__, sd->last_intrstatus));
+
+	*bits = sd->last_intrstatus;
+
+	return rc;
+}
+
+#ifdef DHD_DEBUG
+void sdstd_enable_disable_periodic_timer(sdioh_info_t *sd, uint val)
+{
+	struct sdos_info *sdos = (struct sdos_info *)sd->sdos_info;
+
+	    if (val == SD_DHD_ENABLE_PERIODIC_TUNING) {
+			/* start of tuning timer */
+			timer_expires(&sdos->tuning_timer) = jiffies +  sdos->tuning_timer_exp * HZ;
+			mod_timer(&sdos->tuning_timer, timer_expires(&sdos->tuning_timer));
+		}
+	    if (val == SD_DHD_DISABLE_PERIODIC_TUNING) {
+			/* stop periodic timer */
+		   del_timer_sync(&sdos->tuning_timer);
+		}
+}
+#endif /* debugging purpose */
+
+/* forward declarations for PCI probe and remove functions. */
+static int __devinit bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+static void __devexit bcmsdh_pci_remove(struct pci_dev *pdev);
+
+/**
+ * pci id table
+ */
+static struct pci_device_id bcmsdh_pci_devid[] __devinitdata = {
+	{ vendor: PCI_ANY_ID,
+	device: PCI_ANY_ID,
+	subvendor: PCI_ANY_ID,
+	subdevice: PCI_ANY_ID,
+	class: 0,
+	class_mask: 0,
+	driver_data: 0,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0))
+	override_only: 0,
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)) */
+	},
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0))
+	{ 0, 0, 0, 0, 0, 0, 0, 0}
+#else
+	{ 0, 0, 0, 0, 0, 0, 0}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)) */
+};
+MODULE_DEVICE_TABLE(pci, bcmsdh_pci_devid);
+
+/**
+ * SDIO Host Controller pci driver info
+ */
+static struct pci_driver bcmsdh_pci_driver = {
+	node:		{&(bcmsdh_pci_driver.node), &(bcmsdh_pci_driver.node)},
+	name:		"bcmsdh",
+	id_table:	bcmsdh_pci_devid,
+	probe:		bcmsdh_pci_probe,
+	remove:		bcmsdh_pci_remove,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0))
+	save_state:	NULL,
+#endif
+	suspend:	NULL,
+	resume:		NULL,
+	};
+
+extern uint sd_pci_slot;	/* Force detection to a particular PCI */
+							/* slot only . Allows for having multiple */
+							/* WL devices at once in a PC */
+							/* Only one instance of dhd will be */
+							/* usable at a time */
+							/* Upper word is bus number, */
+							/* lower word is slot number */
+							/* Default value of 0xffffffff turns this */
+							/* off */
+module_param(sd_pci_slot, uint, 0);
+
+/**
+ * Detect supported SDIO Host Controller and attach if found.
+ *
+ * Determine if the device described by pdev is a supported SDIO Host
+ * Controller.  If so, attach to it and attach to the target device.
+ */
+static int __devinit
+bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+	osl_t *osh = NULL;
+	sdioh_info_t *sdioh = NULL;
+	int rc;
+
+	if (sd_pci_slot != 0xFFFFffff) {
+		if (pdev->bus->number != (sd_pci_slot>>16) ||
+			PCI_SLOT(pdev->devfn) != (sd_pci_slot&0xffff)) {
+			sd_err(("%s: %s: bus %X, slot %X, vend %X, dev %X\n",
+				__FUNCTION__,
+				bcmsdh_chipmatch(pdev->vendor, pdev->device)
+				?"Found compatible SDIOHC"
+				:"Probing unknown device",
+				pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor,
+				pdev->device));
+			return -ENODEV;
+		}
+		sd_err(("%s: %s: bus %X, slot %X, vendor %X, device %X (good PCI location)\n",
+			__FUNCTION__,
+			bcmsdh_chipmatch(pdev->vendor, pdev->device)
+			?"Using compatible SDIOHC"
+			:"WARNING, forced use of unkown device",
+			pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor, pdev->device));
+	}
+
+	if ((pdev->vendor == VENDOR_TI) && ((pdev->device == PCIXX21_FLASHMEDIA_ID) ||
+	    (pdev->device == PCIXX21_FLASHMEDIA0_ID))) {
+		uint32 config_reg;
+
+		sd_err(("%s: Disabling TI FlashMedia Controller.\n", __FUNCTION__));
+		if (!(osh = osl_attach(pdev, SDIO_BUS, TRUE))) {
+			sd_err(("%s: osl_attach failed\n", __FUNCTION__));
+			goto err;
+		}
+
+		config_reg = OSL_PCI_READ_CONFIG(osh, 0x4c, 4);
+
+		/*
+		 * Set MMC_SD_DIS bit in FlashMedia Controller.
+		 * Disbling the SD/MMC Controller in the FlashMedia Controller
+		 * allows the Standard SD Host Controller to take over control
+		 * of the SD Slot.
+		 */
+		config_reg |= 0x02;
+		OSL_PCI_WRITE_CONFIG(osh, 0x4c, 4, config_reg);
+		osl_detach(osh);
+	}
+	/* match this pci device with what we support */
+	/* we can't solely rely on this to believe it is our SDIO Host Controller! */
+	if (!bcmsdh_chipmatch(pdev->vendor, pdev->device)) {
+		if (pdev->vendor == VENDOR_BROADCOM) {
+			sd_err(("%s: Unknown Broadcom device (vendor: %#x, device: %#x).\n",
+				__FUNCTION__, pdev->vendor, pdev->device));
+		}
+		return -ENODEV;
+	}
+
+	/* this is a pci device we might support */
+	sd_err(("%s: Found possible SDIO Host Controller: bus %d slot %d func %d irq %d\n",
+		__FUNCTION__,
+		pdev->bus->number, PCI_SLOT(pdev->devfn),
+		PCI_FUNC(pdev->devfn), pdev->irq));
+
+	/* use bcmsdh_query_device() to get the vendor ID of the target device so
+	 * it will eventually appear in the Broadcom string on the console
+	 */
+
+	/* allocate SDIO Host Controller state info */
+	if (!(osh = osl_attach(pdev, SDIO_BUS, TRUE))) {
+		sd_err(("%s: osl_attach failed\n", __FUNCTION__));
+		goto err;
+	}
+
+	/* map to address where host can access */
+	pci_set_master(pdev);
+	rc = pci_enable_device(pdev);
+	if (rc) {
+		sd_err(("%s: Cannot enable PCI device\n", __FUNCTION__));
+		goto err;
+	}
+
+	sdioh = sdioh_attach(osh, (void *)(ulong)pci_resource_start(pdev, 0), pdev->irq);
+	if (sdioh == NULL) {
+		sd_err(("%s: sdioh_attach failed\n", __FUNCTION__));
+		goto err;
+	}
+	sdioh->bcmsdh = bcmsdh_probe(osh, &pdev->dev, sdioh, NULL, PCI_BUS, -1, -1);
+	if (sdioh->bcmsdh == NULL) {
+		sd_err(("%s: bcmsdh_probe failed\n", __FUNCTION__));
+		goto err;
+	}
+
+	pci_set_drvdata(pdev, sdioh);
+	return 0;
+
+err:
+	if (sdioh != NULL)
+		sdioh_detach(osh, sdioh);
+	if (osh != NULL)
+		osl_detach(osh);
+	return -ENOMEM;
+}
+
+/**
+ * Detach from target devices and SDIO Host Controller
+ */
+static void __devexit
+bcmsdh_pci_remove(struct pci_dev *pdev)
+{
+	sdioh_info_t *sdioh;
+	osl_t *osh;
+
+	sdioh = pci_get_drvdata(pdev);
+	if (sdioh == NULL) {
+		sd_err(("%s: error, no sdioh handler found\n", __FUNCTION__));
+		return;
+	}
+
+	osh = sdioh->osh;
+	bcmsdh_remove(sdioh->bcmsdh);
+	sdioh_detach(osh, sdioh);
+	osl_detach(osh);
+}
+
+int bcmsdh_register_client_driver(void)
+{
+	return pci_module_init(&bcmsdh_pci_driver);
+}
+
+void bcmsdh_unregister_client_driver(void)
+{
+	pci_unregister_driver(&bcmsdh_pci_driver);
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcmstdlib_s.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcmstdlib_s.c
@@ -0,0 +1,318 @@
+/*
+ * Broadcom Secure Standard Library.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Dual:>>
+ */
+
+#include <typedefs.h>
+#include <bcmdefs.h>
+#ifdef BCMDRIVER
+#include <osl.h>
+#else /* BCMDRIVER */
+#include <stddef.h>
+#include <string.h>
+#include <stdlib.h>
+#endif /* else BCMDRIVER */
+
+#include <bcmstdlib_s.h>
+#include <bcmutils.h>
+
+/* Don't use compiler builtins for stdlib APIs within the implementation of the stdlib itself. */
+#if defined(BCM_STDLIB_S_BUILTINS_TEST)
+	#undef memmove_s
+	#undef memcpy_s
+	#undef memset_s
+	#undef strlcpy
+	#undef strlcat_s
+#endif /* BCM_STDLIB_S_BUILTINS_TEST */
+
+/*
+ * __SIZE_MAX__ value is depending on platform:
+ * Firmware Dongle: RAMSIZE (Dongle Specific Limit).
+ * LINUX NIC/Windows/MACOSX/Application: OS Native or
+ * 0xFFFFFFFFu if not defined.
+ */
+#ifndef SIZE_MAX
+#ifndef __SIZE_MAX__
+#ifdef DONGLEBUILD
+#define __SIZE_MAX__ RAMSIZE
+#else
+#define __SIZE_MAX__ 0xFFFFFFFFu
+#endif /* DONGLEBUILD */
+#endif /* __SIZE_MAX__ */
+#define SIZE_MAX __SIZE_MAX__
+#endif /* SIZE_MAX */
+#define RSIZE_MAX (SIZE_MAX >> 1u)
+
+#if !defined(__STDC_WANT_SECURE_LIB__) && !(defined(__STDC_LIB_EXT1__) && \
+	defined(__STDC_WANT_LIB_EXT1__))
+/*
+ * memmove_s - secure memmove
+ * dest : pointer to the object to copy to
+ * destsz : size of the destination buffer
+ * src : pointer to the object to copy from
+ * n : number of bytes to copy
+ * Return Value : zero on success and non-zero on error
+ * Also on error, if dest is not a null pointer and destsz not greater
+ * than RSIZE_MAX, writes destsz zero bytes into the dest object.
+ */
+int
+BCMPOSTTRAPFN(memmove_s)(void *dest, size_t destsz, const void *src, size_t n)
+{
+	int err = BCME_OK;
+
+	if ((!dest) || (((char *)dest + destsz) < (char *)dest)) {
+		err = BCME_BADARG;
+		goto exit;
+	}
+
+	if (destsz > RSIZE_MAX) {
+		err = BCME_BADLEN;
+		goto exit;
+	}
+
+	if (destsz < n) {
+		bzero(dest, destsz);
+		err = BCME_BADLEN;
+		goto exit;
+	}
+
+	if ((!src) || (((const char *)src + n) < (const char *)src)) {
+		bzero(dest, destsz);
+		err = BCME_BADARG;
+		goto exit;
+	}
+
+	memmove(dest, src, n);
+exit:
+	return err;
+}
+
+/*
+ * memcpy_s - secure memcpy
+ * dest : pointer to the object to copy to
+ * destsz : size of the destination buffer
+ * src : pointer to the object to copy from
+ * n : number of bytes to copy
+ * Return Value : zero on success and non-zero on error
+ * Also on error, if dest is not a null pointer and destsz not greater
+ * than RSIZE_MAX, writes destsz zero bytes into the dest object.
+ */
+int
+BCMPOSTTRAPFN(memcpy_s)(void *dest, size_t destsz, const void *src, size_t n)
+{
+	int err = BCME_OK;
+	char *d = dest;
+	const char *s = src;
+
+	if ((!d) || ((d + destsz) < d)) {
+		err = BCME_BADARG;
+		goto exit;
+	}
+
+	if (destsz > RSIZE_MAX) {
+		err = BCME_BADLEN;
+		goto exit;
+	}
+
+	if (destsz < n) {
+		bzero(dest, destsz);
+		err = BCME_BADLEN;
+		goto exit;
+	}
+
+	if ((!s) || ((s + n) < s)) {
+		bzero(dest, destsz);
+		err = BCME_BADARG;
+		goto exit;
+	}
+
+	/* overlap checking between dest and src */
+	if (!(((d + destsz) <= s) || (d >= (s + n)))) {
+		bzero(dest, destsz);
+		err = BCME_BADARG;
+		goto exit;
+	}
+
+	(void)memcpy(dest, src, n);
+exit:
+	return err;
+}
+
+/*
+ * memset_s - secure memset
+ * dest : pointer to the object to be set
+ * destsz : size of the destination buffer
+ * c : byte value
+ * n : number of bytes to be set
+ * Return Value : zero on success and non-zero on error
+ * Also on error, if dest is not a null pointer and destsz not greater
+ * than RSIZE_MAX, writes destsz bytes with value c into the dest object.
+ */
+int
+BCMPOSTTRAPFN(memset_s)(void *dest, size_t destsz, int c, size_t n)
+{
+	int err = BCME_OK;
+	if ((!dest) || (((char *)dest + destsz) < (char *)dest)) {
+		err = BCME_BADARG;
+		goto exit;
+	}
+
+	if (destsz > RSIZE_MAX) {
+		err = BCME_BADLEN;
+		goto exit;
+	}
+
+	if (destsz < n) {
+		(void)memset(dest, c, destsz);
+		err = BCME_BADLEN;
+		goto exit;
+	}
+
+	(void)memset(dest, c, n);
+exit:
+	return err;
+}
+#endif /* !__STDC_WANT_SECURE_LIB__ && !(__STDC_LIB_EXT1__ && __STDC_WANT_LIB_EXT1__) */
+
+#if !defined(FREEBSD) && !defined(MACOSX) && !defined(BCM_USE_PLATFORM_STRLCPY)
+/**
+ * strlcpy - Copy a %NUL terminated string into a sized buffer
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ * @size: size of destination buffer 0 if input parameters are NOK
+ * return: string leng of src (which is always < size) on success or size on failure
+ *
+ * Compatible with *BSD: the result is always a valid
+ * NUL-terminated string that fits in the buffer (unless,
+ * of course, the buffer size is zero). It does not pad
+ * out the result like strncpy() does.
+ */
+size_t BCMPOSTTRAPFN(strlcpy)(char *dest, const char *src, size_t size)
+{
+	size_t i;
+
+	if (dest == NULL || size == 0) {
+		return 0;
+	}
+
+	if (src == NULL) {
+		*dest = '\0';
+		return 0;
+	}
+
+	for (i = 0; i < size; i++) {
+		dest[i] = src[i];
+		if (dest[i] == '\0') {
+			/* success - src string copied */
+			return i;
+		}
+	}
+
+	/* NULL terminate since not found in src */
+	dest[size - 1u] = '\0';
+
+	/* fail - src string truncated */
+	return size;
+}
+#endif /* !defined(FREEBSD) && !defined(MACOSX) && !defined(BCM_USE_PLATFORM_STRLCPY) */
+
+/**
+ * strlcat_s - Concatenate a %NUL terminated string with a sized buffer
+ * @dest: Where to concatenate the string to
+ * @src: Where to copy the string from
+ * @size: size of destination buffer
+ * return: string length of created string (i.e. the initial length of dest plus the length of src)
+ *         not including the NUL char, up until size
+ *
+ * Unlike strncat(), strlcat() take the full size of the buffer (not just the number of bytes to
+ * copy) and guarantee to NUL-terminate the result (even when there's nothing to concat).
+ * If the length of dest string concatinated with the src string >= size, truncation occurs.
+ *
+ * Compatible with *BSD: the result is always a valid NUL-terminated string that fits in the buffer
+ * (unless, of course, the buffer size is zero).
+ *
+ * If either src or dest is not NUL-terminated, dest[size-1] will be set to NUL.
+ * If size < strlen(dest) + strlen(src), dest[size-1] will be set to NUL.
+ * If size == 0, dest[0] will be set to NUL.
+ */
+size_t
+strlcat_s(char *dest, const char *src, size_t size)
+{
+	char *d = dest;
+	const char *s = src;	/* point to the start of the src string */
+	size_t n = size;
+	size_t dlen;
+	size_t bytes_to_copy = 0;
+
+	if (dest == NULL) {
+		return 0;
+	}
+
+	/* set d to point to the end of dest string (up to size) */
+	while (n != 0 && *d != '\0') {
+		d++;
+		n--;
+	}
+	dlen = (size_t)(d - dest);
+
+	if (s != NULL) {
+		size_t slen = 0;
+
+		/* calculate src len in case it's not null-terminated */
+		n = size;
+		while (n-- != 0 && *(s + slen) != '\0') {
+			++slen;
+		}
+
+		n = size - dlen;	/* maximum num of chars to copy */
+		if (n != 0) {
+			/* copy relevant chars (until end of src buf or given size is reached) */
+			bytes_to_copy = MIN(slen - (size_t)(s - src), n - 1);
+			(void)memcpy(d, s, bytes_to_copy);
+			d += bytes_to_copy;
+		}
+	}
+	if (n == 0 && dlen != 0) {
+		--d;	/* nothing to copy, but NUL-terminate dest anyway */
+	}
+	*d = '\0';	/* NUL-terminate dest */
+
+	return (dlen + bytes_to_copy);
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcmutils.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcmutils.c
@@ -0,0 +1,6529 @@
+/*
+ * Driver O/S-independent utility routines
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Dual:>>
+ */
+
+#include <typedefs.h>
+#include <bcmdefs.h>
+
+#ifdef BCMDRIVER
+#include <osl.h>
+#include <bcmutils.h>
+#if !defined(BCMDONGLEHOST) || defined(BCMNVRAM)
+#include <bcmnvram.h>
+#endif
+
+#else /* !BCMDRIVER */
+
+#include <stdio.h>
+#include <string.h>
+#include <bcmutils.h>
+#include <stdlib.h>
+
+#if defined(BCMEXTSUP)
+#include <bcm_osl.h>
+#endif
+
+#ifndef ASSERT
+#define ASSERT(exp)
+#endif
+#ifndef ASSERT_FP
+#define ASSERT_FP(exp)
+#endif
+
+#endif /* !BCMDRIVER */
+
+#if defined(_WIN32) || defined(NDIS) || defined(DONGLEBUILD)
+/* Debatable */
+#include <bcmstdlib.h>
+#endif
+#include <bcmstdlib_s.h>
+#include <bcmendian.h>
+#include <bcmdevs.h>
+#include <ethernet.h>
+#include <vlan.h>
+#include <bcmip.h>
+#include <802.1d.h>
+#include <802.11.h>
+#include <bcmip.h>
+#include <bcmipv6.h>
+#include <bcmtcp.h>
+#ifdef BCMPERFSTATS
+#include <bcmperf.h>
+#endif
+#include <wl_android.h>
+
+#include <event_log_payload.h>
+
+#define NUMBER_OF_BITS_BYTE	8u
+
+/* TX_HISTOGRAM enable/disable state flag
+ * Updated in histogram.c
+ */
+#if defined(TX_HISTOGRAM) && !defined(TX_HISTOGRAM_DISABLED)
+/* initialized to TRUE in tx_histogram_init() */
+bool _tx_histogram_enabled = FALSE;
+#else
+bool _tx_histogram_enabled = FALSE;
+#endif /* TX_HISTOGRAM && !TX_HISTOGRAM_DISABLED */
+
+#ifdef PRIVACY_MASK
+struct ether_addr privacy_addrmask;
+
+/* RAM accessor function to avoid 'privacy_addrmask' in ROM/RAM shared data section. */
+static struct ether_addr *
+BCMRAMFN(privacy_addrmask_get)(void)
+{
+	return &privacy_addrmask;
+}
+#endif /* PRIVACY_MASK */
+
+#ifdef BCMDRIVER
+
+#ifndef BCM_ARM_BACKTRACE
+/* function pointers for firmware stack backtrace utility */
+void (*const BCMPOST_TRAP_RODATA(print_btrace_int_fn))(int depth, uint32 pc, uint32 lr, uint32 sp) =
+	NULL;
+void (*const BCMPOST_TRAP_RODATA(print_btrace_fn))(int depth) = NULL;
+#else
+void print_backtrace(int depth);
+void (*const BCMPOST_TRAP_RODATA(print_btrace_fn))(int depth) = print_backtrace;
+void print_backtrace_int(int depth, uint32 pc, uint32 lr, uint32 sp);
+void (*const BCMPOST_TRAP_RODATA(print_btrace_int_fn))(int depth, uint32 pc, uint32 lr, uint32 sp) =
+	print_backtrace_int;
+#endif
+
+#if !defined(BCMDONGLEHOST)
+
+#ifndef BCM_BOOTLOADER
+/* Forward declarations */
+static int getintvararray_internal(char *vars, const char *name, int index);
+static int getintvararraysize_internal(char *vars, const char *name);
+static
+#ifndef ATE_BUILD
+const
+#endif
+char * getvar_internal(char *vars, const char *name);
+static int getintvar_internal(char *vars, const char *name);
+
+/*
+ * Search the name=value vars for a specific one and return its value.
+ * Returns NULL if not found.
+ */
+#ifndef ATE_BUILD
+const
+#endif
+char *
+getvar(char *vars, const char *name)
+{
+	NVRAM_RECLAIM_CHECK(name);
+	return getvar_internal(vars, name);
+}
+
+static
+#ifndef ATE_BUILD
+const
+#endif
+char *
+getvar_internal(char *vars, const char *name)
+{
+	char *s;
+	uint len;
+
+	if (!name)
+		return NULL;
+
+	len = strlen(name);
+	if (len == 0u) {
+		return NULL;
+	}
+
+	/* first look in vars[] */
+	for (s = vars; s && *s;) {
+		if ((bcmp(s, name, len) == 0) && (s[len] == '=')) {
+			return (&s[len+1u]);
+		}
+		while (*s++)
+			;
+	}
+
+	/* then query nvram */
+	return (nvram_get(name));
+}
+
+/*
+ * Search the vars for a specific one and return its value as
+ * an integer. Returns 0 if not found.
+ */
+int
+getintvar(char *vars, const char *name)
+{
+	NVRAM_RECLAIM_CHECK(name);
+	return getintvar_internal(vars, name);
+}
+
+static int
+getintvar_internal(char *vars, const char *name)
+{
+	const char *val;
+
+	if ((val = getvar_internal(vars, name)) == NULL)
+		return (0);
+
+	return (int)(bcm_strtoul(val, NULL, 0));
+}
+
+int
+getintvararray(char *vars, const char *name, int index)
+{
+	NVRAM_RECLAIM_CHECK(name);
+	return getintvararray_internal(vars, name, index);
+}
+
+static int
+getintvararray_internal(char *vars, const char *name, int index)
+{
+	const char *buf;
+	char *endp;
+	int i = 0;
+	int val = 0;
+
+	if ((buf = getvar_internal(vars, name)) == NULL) {
+		return (0);
+	}
+
+	/* table values are always separated by "," or " " */
+	while (*buf != '\0') {
+		val = (int)bcm_strtoul(buf, &endp, 0);
+		if (i == index) {
+			return val;
+		}
+		buf = endp;
+		/* delimiter is ',' */
+		if (*buf == ',')
+			buf++;
+		i++;
+	}
+	return (0);
+}
+
+int
+getintvararraysize(char *vars, const char *name)
+{
+	NVRAM_RECLAIM_CHECK(name);
+	return getintvararraysize_internal(vars, name);
+}
+
+static int
+getintvararraysize_internal(char *vars, const char *name)
+{
+	const char *buf;
+	char *endp;
+	int count = 0;
+	int val = 0;
+
+	if ((buf = getvar_internal(vars, name)) == NULL) {
+		return (0);
+	}
+
+	/* table values are always separated by "," or " " */
+	while (*buf != '\0') {
+		val = (int)bcm_strtoul(buf, &endp, 0);
+		buf = endp;
+		/* delimiter is ',' */
+		if (*buf == ',')
+			buf++;
+		count++;
+	}
+	BCM_REFERENCE(val);
+	return count;
+}
+
+/* Read an array of values from a possibly slice-specific nvram string
+ * Store the values in either the uint8 dest_array1 or in the int16 dest_array2.
+ * Pass in NULL for the dest_array[12] that is not to be used.
+ */
+static int
+getintvararray_slicespecific(osl_t *osh, char *vars, char *vars_table_accessor,
+	const char* name, uint8* dest_array1, int16* dest_array2, uint dest_size)
+{
+	uint i;
+	uint array_size = 0;
+	int err = BCME_OK;
+	uint prefixed_name_sz;
+	char *prefixed_name = NULL;
+	const char *new_name;
+	int val;
+
+	prefixed_name_sz = get_slicespecific_var_name(osh, vars_table_accessor,
+		name, &prefixed_name);
+	if (prefixed_name_sz == 0) {
+		return BCME_NOMEM;
+	}
+
+	new_name = prefixed_name;
+	(void) new_name;
+	if (getvar(vars, new_name) == NULL) {
+		/* Try again without the slice prefix in the name */
+		new_name = name;
+		if (getvar(vars, name) == NULL) {
+			err = BCME_NOTFOUND;
+			goto done;
+		}
+	}
+
+	array_size = (uint)getintvararraysize(vars, new_name);
+	if (array_size > dest_size) {
+		err = BCME_BUFTOOSHORT;
+		ASSERT(array_size <= dest_size);
+		goto done;
+	}
+
+	/* limit the initialization to the size of the nvram array */
+	array_size = MIN(array_size, dest_size);
+
+	/* load the destination array with the nvram array values */
+	for (i = 0; i < array_size; i++) {
+		val = getintvararray(vars, new_name, (int)i);
+		if (dest_array1) {
+			dest_array1[i] = (uint8)val;
+		} else if (dest_array2) {
+			dest_array2[i] = (int16)val;
+		}
+	}
+done:
+	MFREE(osh, prefixed_name, prefixed_name_sz);
+	return (err < 0) ? err : (int)array_size;
+}
+
+int
+get_uint8_vararray_slicespecific(osl_t *osh, char *vars, char *vars_table_accessor,
+	const char* name, uint8* dest_array, uint dest_size)
+{
+	int ret;
+
+	ret = getintvararray_slicespecific(osh, vars, vars_table_accessor,
+		name, dest_array, NULL, dest_size);
+	return ret;
+}
+
+int
+get_int16_vararray_slicespecific(osl_t *osh, char *vars, char *vars_table_accessor,
+	const char* name, int16* dest_array, uint dest_size)
+{
+	return getintvararray_slicespecific(osh, vars, vars_table_accessor,
+		name, NULL, dest_array, dest_size);
+}
+
+/* Prepend a slice-specific accessor to an nvram string name.
+ * Sets name_out to the allocated string. Returns the allocated size of the name string.
+ * Caller is responsible for freeing the resulting name string with MFREE.
+ */
+uint
+get_slicespecific_var_name(osl_t *osh, char *vars_table_accessor, const char *name,
+	char **name_out)
+{
+	char *name_with_prefix = NULL;
+	uint sz;
+	uint max_copy_size;
+
+	sz = strlen(name) + strlen(vars_table_accessor) + 1;
+	name_with_prefix = (char *) MALLOC_NOPERSIST(osh, sz);
+	if (name_with_prefix == NULL) {
+		sz = 0;
+		goto end;
+	}
+	name_with_prefix[0] = 0;
+	name_with_prefix[sz - 1] = 0;
+	max_copy_size = sz - 1;
+
+	/* if accessor contains a "slice/N/" string */
+	if (vars_table_accessor[0] != 0) {
+		/* prepend accessor to the vars-name */
+		bcmstrncat(name_with_prefix, vars_table_accessor, max_copy_size);
+		max_copy_size -= strlen(name_with_prefix);
+	}
+
+	/* Append vars-name */
+	bcmstrncat(name_with_prefix, name, max_copy_size);
+end:
+	*name_out = name_with_prefix;
+	return sz;
+}
+#endif /* BCM_BOOTLOADER */
+
+#if defined(BCMNVRAMR) || defined(BCMNVRAMW)
+/* Search for token in comma separated token-string */
+static int
+findmatch(const char *string, const char *name)
+{
+	uint len;
+	char *c;
+
+	len = strlen(name);
+	while ((c = strchr(string, ',')) != NULL) {
+		if (len == (uint)(c - string) && !strncmp(string, name, len))
+			return 1;
+		string = c + 1;
+	}
+
+	return (!strcmp(string, name));
+}
+
+/* Return gpio pin number assigned to the named pin
+ *
+ * Variable should be in format:
+ *
+ *	gpio<N>=pin_name,pin_name
+ *
+ * This format allows multiple features to share the gpio with mutual
+ * understanding.
+ *
+ * 'def_pin' is returned if a specific gpio is not defined for the requested functionality
+ * and if def_pin is not used by others.
+ */
+uint
+getgpiopin(char *vars, char *pin_name, uint def_pin)
+{
+	char name[] = "gpioXXXX";
+	const char *val;
+	uint pin;
+
+	/* Go thru all possibilities till a match in pin name */
+	for (pin = 0; pin < GPIO_NUMPINS; pin ++) {
+		snprintf(name, sizeof(name), "gpio%d", pin);
+		val = getvar(vars, name);
+		if (val && findmatch(val, pin_name))
+			return pin;
+	}
+
+	if (def_pin != GPIO_PIN_NOTDEFINED) {
+		/* make sure the default pin is not used by someone else */
+		snprintf(name, sizeof(name), "gpio%d", def_pin);
+		if (getvar(vars, name)) {
+			def_pin =  GPIO_PIN_NOTDEFINED;
+		}
+	}
+	return def_pin;
+}
+#endif /* BCMNVRAMR || BCMNVRAMW */
+#endif /* !BCMDONGLEHOST */
+
+/* return total length of buffer chain. In case of CSO, submsdu may have extra tsohdr and if
+ * pktotlen should not include submsdu tso header, use the API pkttotlen_no_sfhtoe_hdr.
+ */
+uint
+BCMFASTPATH(pkttotlen)(osl_t *osh, void *p)
+{
+	uint total = 0;
+
+	for (; p; p = PKTNEXT(osh, p)) {
+		total += PKTLEN(osh, p);
+
+		if (BCMLFRAG_ENAB() && PKTISFRAG(osh, p)) {
+			total += PKTFRAGTOTLEN(osh, p);
+		}
+	}
+
+	return (total);
+}
+
+#ifdef WLCSO
+/* return total length of buffer chain, but exclude tso hdr of submsdu if its added  */
+uint
+BCMFASTPATH(pkttotlen_no_sfhtoe_hdr)(osl_t *osh, void *p, uint toe_hdr_len)
+{
+	uint total = 0;
+
+	for (; p; p = PKTNEXT(osh, p)) {
+		total += PKTLEN(osh, p);
+
+		/* exclude toe_hdr_len if its part of PKTLEN()  */
+		if (PKTISSUBMSDUTOEHDR(osh, p)) {
+			total -= toe_hdr_len;
+		}
+
+		if (BCMLFRAG_ENAB() && PKTISFRAG(osh, p)) {
+			total += PKTFRAGTOTLEN(osh, p);
+		}
+	}
+
+	return (total);
+}
+#endif /* WLCSO */
+
+/* return total length of buffer chain */
+uint
+BCMFASTPATH(pkttotcnt)(osl_t *osh, void *p)
+{
+	uint cnt = 0;
+
+	for (; p; p = PKTNEXT(osh, p)) {
+		cnt++;
+	}
+
+	return (cnt);
+}
+
+/* return the last buffer of chained pkt */
+void *
+BCMFASTPATH(pktlast)(osl_t *osh, void *p)
+{
+	for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p))
+		;
+
+	return (p);
+}
+
+/* count segments of a chained packet */
+uint
+BCMFASTPATH(pktsegcnt)(osl_t *osh, void *p)
+{
+	uint cnt;
+
+	for (cnt = 0; p; p = PKTNEXT(osh, p)) {
+		if (PKTLEN(osh, p)) {
+			cnt++;
+		}
+#ifdef BCMLFRAG
+		if (BCMLFRAG_ENAB() && PKTISFRAG(osh, p)) {
+				cnt += PKTFRAGTOTNUM(osh, p);
+		}
+#endif /* BCMLFRAG */
+	}
+
+	return cnt;
+}
+
+#ifdef DONGLEBUILD
+/**
+ * Takes in a lbuf/lfrag and no of bytes to be trimmed from tail.
+ * trim bytes  could be spread out in below 3 formats
+ *     1. entirely in dongle
+ *     2. entirely in host
+ *     3. split between host-dongle
+ */
+void
+BCMFASTPATH(pktfrag_trim_tailbytes)(osl_t * osh, void* p, uint16 trim_len, uint8 type)
+{
+	uint tcmseg_len = PKTLEN(osh, p);	/* TCM segment length */
+	uint hostseg_len = PKTFRAGUSEDLEN(osh, p);	/* HOST segment length */
+
+	/* return if zero trim length- Nothing to do */
+	if (trim_len == 0)
+		return;
+
+	/* if header conv is on, there is no fcs at the end */
+	/* JIRA:SW4349-318 */
+	if (PKTISHDRCONVTD(osh, p))
+		return;
+
+	/* if pktfetched, then its already trimmed */
+	if (PKTISPKTFETCHED(osh, p))
+		return;
+
+	if (PKTFRAGUSEDLEN(osh, p) >= trim_len) {
+		/* TRIM bytes entirely in host */
+		ASSERT_FP(PKTISRXFRAG(osh, p));
+
+		PKTSETFRAGUSEDLEN(osh, p, (hostseg_len - trim_len));
+	} else {
+		/* trim bytes either in dongle or split between dongle-host */
+		PKTSETLEN(osh, p, (tcmseg_len - (trim_len - hostseg_len)));
+
+		/* No more contents in host; reset length to zero */
+		if (PKTFRAGUSEDLEN(osh, p))
+			PKTSETFRAGUSEDLEN(osh, p, 0);
+	}
+}
+#endif /* DONGLEBUILD */
+
+/* copy a pkt buffer chain into a buffer */
+uint
+BCMPOSTTRAPFN(pktcopy)(osl_t *osh, void *p, uint offset, uint len, uchar *buf)
+{
+	uint n, ret = 0;
+
+	/* skip 'offset' bytes */
+	for (; p && offset; p = PKTNEXT(osh, p)) {
+		if (offset < PKTLEN(osh, p))
+			break;
+		offset -= PKTLEN(osh, p);
+	}
+
+	if (!p)
+		return 0;
+
+	/* copy the data */
+	for (; p && len; p = PKTNEXT(osh, p)) {
+		n = MIN(PKTLEN(osh, p) - offset, len);
+		bcopy(PKTDATA(osh, p) + offset, buf, n);
+		buf += n;
+		len -= n;
+		ret += n;
+		offset = 0;
+	}
+
+	return ret;
+}
+
+/* copy a buffer into a pkt buffer chain */
+uint
+pktfrombuf(osl_t *osh, void *p, uint offset, uint len, uchar *buf)
+{
+	uint n, ret = 0;
+
+	/* skip 'offset' bytes */
+	for (; p && offset; p = PKTNEXT(osh, p)) {
+		if (offset < PKTLEN(osh, p))
+			break;
+		offset -= PKTLEN(osh, p);
+	}
+
+	if (!p)
+		return 0;
+
+	/* copy the data */
+	for (; p && len; p = PKTNEXT(osh, p)) {
+		n = MIN(PKTLEN(osh, p) - offset, len);
+		bcopy(buf, PKTDATA(osh, p) + offset, n);
+		buf += n;
+		len -= n;
+		ret += n;
+		offset = 0;
+	}
+
+	return ret;
+}
+
+uint8 *
+BCMFASTPATH(pktdataoffset)(osl_t *osh, void *p,  uint offset)
+{
+	uint total = pkttotlen(osh, p);
+	uint pkt_off = 0, len = 0;
+	uint8 *pdata = (uint8 *) PKTDATA(osh, p);
+
+	if (offset > total)
+		return NULL;
+
+	for (; p; p = PKTNEXT(osh, p)) {
+		pdata = (uint8 *) PKTDATA(osh, p);
+		pkt_off = offset - len;
+		len += PKTLEN(osh, p);
+		if (len > offset)
+			break;
+	}
+	return (uint8*) (pdata+pkt_off);
+}
+
+/* given a offset in pdata, find the pkt seg hdr */
+void *
+pktoffset(osl_t *osh, void *p,  uint offset)
+{
+	uint total = pkttotlen(osh, p);
+	uint len = 0;
+
+	if (offset > total)
+		return NULL;
+
+	for (; p; p = PKTNEXT(osh, p)) {
+		len += PKTLEN(osh, p);
+		if (len > offset)
+			break;
+	}
+	return p;
+}
+
+void
+bcm_mdelay(uint ms)
+{
+	uint i;
+
+	for (i = 0; i < ms; i++) {
+		OSL_DELAY(1000);
+	}
+}
+
+#if defined(BCMPERFSTATS) || defined(BCMTSTAMPEDLOGS)
+
+#if defined(__ARM_ARCH_7R__)
+#define BCMLOG_CYCLE_OVERHEAD	54	/* Number of CPU cycle overhead due to bcmlog().
+					 * This is to compensate CPU cycle incurred by
+					 * added bcmlog() function call for profiling.
+					 */
+#else
+#define BCMLOG_CYCLE_OVERHEAD	0
+#endif
+
+#define	LOGSIZE	256			/* should be power of 2 to avoid div below */
+static struct {
+	uint	cycles;
+	const char	*fmt;
+	uint	a1;
+	uint	a2;
+	uchar   indent;		/* track indent level for nice printing */
+} logtab[LOGSIZE];
+
+/* last entry logged  */
+static uint logi = 0;
+/* next entry to read */
+static uint volatile readi = 0;
+#endif	/* defined(BCMPERFSTATS) || defined(BCMTSTAMPEDLOGS) */
+
+#ifdef BCMPERFSTATS
+/* TODO: make the utility configurable (choose between icache, dcache, hits, misses ...)  */
+void
+bcm_perf_enable()
+{
+	BCMPERF_ENABLE_INSTRCOUNT();
+	BCMPERF_ENABLE_ICACHE_MISS();
+	BCMPERF_ENABLE_ICACHE_HIT();
+}
+
+/* WARNING:  This routine uses OSL_GETCYCLES(), which can give unexpected results on
+ * modern speed stepping CPUs.  Use bcmtslog() instead in combination with TSF counter.
+ */
+void
+bcmlog(char *fmt, uint a1, uint a2)
+{
+	static uint last = 0;
+	uint cycles, i, elapsed;
+	OSL_GETCYCLES(cycles);
+
+	i = logi;
+
+	elapsed = cycles - last;
+	if (elapsed > BCMLOG_CYCLE_OVERHEAD)
+		logtab[i].cycles = elapsed - BCMLOG_CYCLE_OVERHEAD;
+	else
+		logtab[i].cycles = 0;
+	logtab[i].fmt = fmt;
+	logtab[i].a1 = a1;
+	logtab[i].a2 = a2;
+
+	logi = (i + 1) % LOGSIZE;
+	last = cycles;
+
+	/* if log buffer is overflowing, readi should be advanced.
+	 * Otherwise logi and readi will become out of sync.
+	 */
+	if (logi == readi) {
+		readi = (readi + 1) % LOGSIZE;
+	} else {
+		/* This redundant else is to make CPU cycles of bcmlog() function to be uniform,
+		 * so that the cycle compensation with BCMLOG_CYCLE_OVERHEAD is more accurate.
+		 */
+		readi = readi % LOGSIZE;
+	}
+}
+
+/* Same as bcmlog but specializes the use of a1 and a2 to
+ * store icache misses and instruction count.
+ *  TODO : make this use a configuration array to decide what counter to read.
+ * We are limited to 2 numbers but it seems it is the most we can get anyway
+ * since dcache and icache cannot be enabled at the same time. Recording
+ * both the hits and misses at the same time for a given cache is not that useful either.
+*/
+
+void
+bcmstats(char *fmt)
+{
+	static uint last = 0;
+	static uint32 ic_miss = 0;
+	static uint32 instr_count = 0;
+	uint32 ic_miss_cur;
+	uint32 instr_count_cur;
+	uint cycles, i;
+
+	OSL_GETCYCLES(cycles);
+	BCMPERF_GETICACHE_MISS(ic_miss_cur);
+	BCMPERF_GETINSTRCOUNT(instr_count_cur);
+
+	i = logi;
+
+	logtab[i].cycles = cycles - last;
+	logtab[i].a1 = ic_miss_cur - ic_miss;
+	logtab[i].a2 = instr_count_cur - instr_count;
+	logtab[i].fmt = fmt;
+
+	logi = (i + 1) % LOGSIZE;
+
+	last = cycles;
+	instr_count = instr_count_cur;
+	ic_miss = ic_miss_cur;
+
+	/* if log buffer is overflowing, readi should be advanced.
+	 * Otherwise logi and readi will become out of sync.
+	 */
+	if (logi == readi) {
+		readi = (readi + 1) % LOGSIZE;
+	} else {
+		/* This redundant else is to make CPU cycles of bcmstats() function to be uniform
+		 */
+		readi = readi % LOGSIZE;
+	}
+}
+
+/*
+ * TODO (linux version): a "proc" version where the log would be dumped
+ * on the proc file directly.
+ */
+
+void
+bcmdumplog(char *buf, int size)
+{
+	char *limit;
+	int j = 0;
+	int num;
+	struct bcmstrbuf strubuf;
+	struct bcmstrbuf *b = &strubuf;
+
+	bcm_binit(b, buf, size);
+
+	limit = BCMSTRBUF_BUF(b) + BCMSTRBUF_LEN(b) - 80;
+
+	num = logi - readi;
+
+	if (num < 0)
+		num += LOGSIZE;
+
+	/* print in chronological order */
+
+	for (j = 0; j < num && (BCMSTRBUF_BUF(b) < limit); readi = (readi + 1) % LOGSIZE, j++) {
+		if (logtab[readi].fmt == NULL)
+		    continue;
+		bcm_bprintf(b, "%d\t", logtab[readi].cycles);
+		bcm_bprintf(b, logtab[readi].fmt, logtab[readi].a1, logtab[readi].a2);
+		bcm_bprintf(b, "\n");
+	}
+
+}
+
+/*
+ * Dump one log entry at a time.
+ * Return index of next entry or -1 when no more .
+ */
+int
+bcmdumplogent(char *buf, uint i)
+{
+	bool hit;
+	struct bcmstrbuf strubuf;
+	struct bcmstrbuf *b = &strubuf;
+
+	/*
+	 * If buf is NULL, return the starting index,
+	 * interpreting i as the indicator of last 'i' entries to dump.
+	 */
+	if (buf == NULL) {
+		i = ((i > 0) && (i < (LOGSIZE - 1))) ? i : (LOGSIZE - 1);
+		return ((logi - i) % LOGSIZE);
+	}
+
+	*buf = '\0';
+
+	ASSERT(i < LOGSIZE);
+
+	if (i == logi)
+		return (-1);
+
+	bcm_binit(b, buf, i);
+	hit = FALSE;
+	for (; (i != logi) && !hit; i = (i + 1) % LOGSIZE) {
+		if (logtab[i].fmt == NULL)
+			continue;
+		bcm_bprintf(b, "%d: %d\t", i, logtab[i].cycles);
+		bcm_bprintf(b, logtab[i].fmt, logtab[i].a1, logtab[i].a2);
+		bcm_bprintf(b, "\n");
+		hit = TRUE;
+	}
+
+	return (i);
+}
+
+#endif	/* BCMPERFSTATS */
+
+#if defined(BCMTSTAMPEDLOGS)
+/* Store a TSF timestamp and a log line in the log buffer */
+/*
+	a1 is used to signify entering/exiting a routine.  When entering
+	the indent level is increased.  When exiting, the delta since entering
+	is printed and the indent level is bumped back out.
+	Nesting can go up to level MAX_TS_INDENTS deep.
+*/
+#define MAX_TS_INDENTS 20
+void
+bcmtslog(uint32 tstamp, const char *fmt, uint a1, uint a2)
+{
+	uint i = logi;
+	bool use_delta = TRUE;
+	static uint32 last = 0;	/* used only when use_delta is true */
+	static uchar indent = 0;
+	static uint32 indents[MAX_TS_INDENTS];
+
+	logtab[i].cycles = tstamp;
+	if (use_delta)
+		logtab[i].cycles -= last;
+
+	logtab[i].a2 = a2;
+
+	if (a1 == TS_EXIT && indent) {
+		indent--;
+		logtab[i].a2 = tstamp - indents[indent];
+	}
+
+	logtab[i].fmt = fmt;
+	logtab[i].a1 = a1;
+	logtab[i].indent = indent;
+
+	if (a1 == TS_ENTER) {
+		indents[indent] = tstamp;
+		if (indent < MAX_TS_INDENTS - 1)
+			indent++;
+	}
+
+	if (use_delta)
+		last = tstamp;
+	logi = (i + 1) % LOGSIZE;
+}
+
+/* Print out a microsecond timestamp as "sec.ms.us " */
+void
+bcmprinttstamp(uint32 ticks)
+{
+	uint us, ms, sec;
+
+	us = (ticks % TSF_TICKS_PER_MS) * 1000 / TSF_TICKS_PER_MS;
+	ms = ticks / TSF_TICKS_PER_MS;
+	sec = ms / 1000;
+	ms -= sec * 1000;
+	printf("%04u.%03u.%03u ", sec, ms, us);
+}
+
+/* Print out the log buffer with timestamps */
+void
+bcmprinttslogs(void)
+{
+	int j = 0;
+	int num;
+
+	num = logi - readi;
+	if (num < 0)
+		num += LOGSIZE;
+
+	/* Format and print the log entries directly in chronological order */
+	for (j = 0; j < num; readi = (readi + 1) % LOGSIZE, j++) {
+		if (logtab[readi].fmt == NULL)
+		    continue;
+		bcmprinttstamp(logtab[readi].cycles);
+		printf(logtab[readi].fmt, logtab[readi].a1, logtab[readi].a2);
+		printf("\n");
+	}
+}
+
+/*
+	Identical to bcmdumplog, but output is based on tsf instead of cycles.
+
+	a1 is used to signify entering/exiting a routine.  When entering
+	the indent level is increased.  When exiting, the delta since entering
+	is printed and the indent level is bumped back out.
+*/
+void
+bcmdumptslog(struct bcmstrbuf *b)
+{
+	char *limit;
+	int j = 0;
+	int num;
+	uint us, ms, sec;
+	int skip;
+	char *lines = "| | | | | | | | | | | | | | | | | | | |";
+
+	limit = BCMSTRBUF_BUF(b) + BCMSTRBUF_LEN(b) - 80;
+
+	num = logi - readi;
+
+	if (num < 0)
+		num += LOGSIZE;
+
+	/* print in chronological order */
+	for (j = 0; j < num && (BCMSTRBUF_BUF(b) < limit); readi = (readi + 1) % LOGSIZE, j++) {
+		char *last_buf = BCMSTRBUF_BUF(b);
+		if (logtab[readi].fmt == NULL)
+			continue;
+
+		us = (logtab[readi].cycles % TSF_TICKS_PER_MS) * 1000 / TSF_TICKS_PER_MS;
+		ms = logtab[readi].cycles / TSF_TICKS_PER_MS;
+		sec = ms / 1000;
+		ms -= sec * 1000;
+
+		bcm_bprintf(b, "%04u.%03u.%03u ", sec, ms, us);
+
+		/* 2 spaces for each indent level */
+		bcm_bprintf(b, "%.*s", logtab[readi].indent * 2, lines);
+
+		/*
+		 * The following call to snprintf generates a compiler warning
+		 * due to -Wformat-security. However, the format string is coming
+		 * from internal callers rather than external data input, and is a
+		 * useful debugging tool serving a variety of diagnostics. Rather
+		 * than expand code size by replicating multiple functions with different
+		 * argument lists, or disabling the warning globally, let's consider
+		 * if we can just disable the warning for this one instance.
+		 */
+		bcm_bprintf(b, logtab[readi].fmt);
+
+		/* If a1 is ENTER or EXIT, print the + or - */
+		skip = 0;
+		if (logtab[readi].a1 == TS_ENTER) {
+			bcm_bprintf(b, " +");
+			skip++;
+		}
+		if (logtab[readi].a1 == TS_EXIT) {
+			bcm_bprintf(b, " -");
+			skip++;
+		}
+
+		/* else print the real a1 */
+		if (logtab[readi].a1 && !skip)
+			bcm_bprintf(b, "   %d", logtab[readi].a1);
+
+		/*
+		   If exiting routine, print a nicely formatted delta since entering.
+		   Otherwise, just print a2 normally.
+		*/
+		if (logtab[readi].a2) {
+			if (logtab[readi].a1 == TS_EXIT) {
+				int num_space = 75 - (BCMSTRBUF_BUF(b) - last_buf);
+				bcm_bprintf(b, "%*.s", num_space, "");
+				bcm_bprintf(b, "%5d usecs", logtab[readi].a2);
+			} else
+				bcm_bprintf(b, "  %d", logtab[readi].a2);
+		}
+		bcm_bprintf(b, "\n");
+		last_buf = BCMSTRBUF_BUF(b);
+	}
+}
+
+#endif	/* BCMTSTAMPEDLOGS */
+
+#if defined(BCMDBG) || defined(DHD_DEBUG)
+/* pretty hex print a pkt buffer chain */
+void
+prpkt(const char *msg, osl_t *osh, void *p0)
+{
+	void *p;
+
+	if (msg && (msg[0] != '\0'))
+		printf("%s:\n", msg);
+
+	for (p = p0; p; p = PKTNEXT(osh, p))
+		prhex(NULL, PKTDATA(osh, p), PKTLEN(osh, p));
+}
+#endif	/* BCMDBG || DHD_DEBUG */
+
+/* Takes an Ethernet frame and sets out-of-bound PKTPRIO.
+ * Also updates the inplace vlan tag if requested.
+ * For debugging, it returns an indication of what it did.
+ */
+uint
+BCMFASTPATH(pktsetprio)(void *pkt, bool update_vtag)
+{
+	struct ether_header *eh;
+	struct ethervlan_header *evh;
+	uint8 *pktdata;
+	uint priority = 0;
+	uint rc = 0;
+
+	pktdata = (uint8 *)PKTDATA(OSH_NULL, pkt);
+	ASSERT_FP(ISALIGNED((uintptr)pktdata, sizeof(uint16)));
+
+	eh = (struct ether_header *) pktdata;
+
+	if (eh->ether_type == hton16(ETHER_TYPE_8021Q)) {
+		uint16 vlan_tag;
+		uint vlan_prio, dscp_prio = 0;
+
+		evh = (struct ethervlan_header *)eh;
+
+		vlan_tag = ntoh16(evh->vlan_tag);
+		vlan_prio = (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
+
+		if ((evh->ether_type == hton16(ETHER_TYPE_IP)) ||
+			(evh->ether_type == hton16(ETHER_TYPE_IPV6))) {
+			uint8 *ip_body = pktdata + sizeof(struct ethervlan_header);
+			uint8 tos_tc = IP_TOS46(ip_body);
+			dscp_prio = tos_tc >> IPV4_TOS_PREC_SHIFT;
+		}
+
+		/* DSCP priority gets precedence over 802.1P (vlan tag) */
+		if (dscp_prio != 0) {
+			priority = dscp_prio;
+			rc |= PKTPRIO_VDSCP;
+		} else {
+			priority = vlan_prio;
+			rc |= PKTPRIO_VLAN;
+		}
+		/*
+		 * If the DSCP priority is not the same as the VLAN priority,
+		 * then overwrite the priority field in the vlan tag, with the
+		 * DSCP priority value. This is required for Linux APs because
+		 * the VLAN driver on Linux, overwrites the skb->priority field
+		 * with the priority value in the vlan tag
+		 */
+		if (update_vtag && (priority != vlan_prio)) {
+			vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT);
+			vlan_tag |= priority << VLAN_PRI_SHIFT;
+			evh->vlan_tag = hton16(vlan_tag);
+			rc |= PKTPRIO_UPD;
+		}
+#if defined(EAPOL_PKT_PRIO) || defined(DHD_LOSSLESS_ROAMING)
+	} else if (eh->ether_type == hton16(ETHER_TYPE_802_1X)) {
+		priority = PRIO_8021D_NC;
+		rc = PKTPRIO_DSCP;
+#endif /* EAPOL_PKT_PRIO || DHD_LOSSLESS_ROAMING */
+#if defined(PRIORITIZE_ARP)
+	} else if (eh->ether_type == hton16(ETHER_TYPE_ARP)) {
+		/* Certain Host stacks attempt disconnection on continous ARP timeouts. In
+		 * congested scenarios with traffic, ARP packets may not get chance
+		 * for transmission leading to disconnection. so prioritize it.
+		 */
+		priority = PRIO_8021D_NC;
+		rc = PKTPRIO_DSCP;
+#endif /* PRIORITIZE_ARP */
+#if defined(WLTDLS)
+	} else if (eh->ether_type == hton16(ETHER_TYPE_89_0D)) {
+		/* Bump up the priority for TDLS frames */
+		priority = PRIO_8021D_VI;
+		rc = PKTPRIO_DSCP;
+#endif /* WLTDLS */
+	} else if ((eh->ether_type == hton16(ETHER_TYPE_IP)) ||
+		(eh->ether_type == hton16(ETHER_TYPE_IPV6))) {
+		uint8 *ip_body = pktdata + sizeof(struct ether_header);
+		uint8 tos_tc = IP_TOS46(ip_body);
+		uint8 dscp = tos_tc >> IPV4_TOS_DSCP_SHIFT;
+		switch (dscp) {
+		case DSCP_EF:
+		case DSCP_VA:
+			priority = PRIO_8021D_VO;
+			break;
+		case DSCP_AF31:
+		case DSCP_AF32:
+		case DSCP_AF33:
+		case DSCP_CS3:
+			priority = PRIO_8021D_CL;
+			break;
+		case DSCP_AF21:
+		case DSCP_AF22:
+		case DSCP_AF23:
+			priority = PRIO_8021D_EE;
+			break;
+		case DSCP_AF11:
+		case DSCP_AF12:
+		case DSCP_AF13:
+		case DSCP_CS2:
+			priority = PRIO_8021D_BE;
+			break;
+#ifdef RFC8325_DSCP_CS6_TO_UP7
+		case DSCP_CS6:
+#endif /* RFC8325_DSCP_CS6_TO_UP7 */
+		case DSCP_CS7:
+			priority = PRIO_8021D_NC;
+			break;
+		default:
+			priority = tos_tc >> IPV4_TOS_PREC_SHIFT;
+			break;
+		}
+
+		rc |= PKTPRIO_DSCP;
+	}
+
+	ASSERT_FP(priority <= MAXPRIO);
+	PKTSETPRIO(pkt, priority);
+	return (rc | priority);
+}
+
+/* lookup user priority for specified DSCP */
+static uint8
+dscp2up(uint8 *up_table, uint8 dscp)
+{
+	uint8 user_priority = 255;
+
+	/* lookup up from table if parameters valid */
+	if (up_table != NULL && dscp < UP_TABLE_MAX) {
+		user_priority = up_table[dscp];
+	}
+
+	if (user_priority == 255) {	/* unknown user priority */
+
+		/* If the user_priority from the QoS Map table is unknown(i.e., 255), then
+		 * set the default user priority as PRIO_8021D_BE(0); Reference RFC 8325.
+		 */
+		user_priority = PRIO_8021D_BE; /* default priority */
+	}
+
+	return user_priority;
+}
+
+/* set user priority by QoS Map Set table (UP table), table size is UP_TABLE_MAX */
+uint
+BCMFASTPATH(pktsetprio_qms)(void *pkt, uint8* up_table, bool update_vtag)
+{
+	if (up_table) {
+		uint8 *pktdata;
+		uint pktlen;
+		uint8 dscp;
+		uint user_priority = 0;
+		uint rc = 0;
+
+		pktdata = (uint8 *)PKTDATA(OSH_NULL, pkt);
+		pktlen = PKTLEN(OSH_NULL, pkt);
+		if (pktgetdscp(pktdata, pktlen, &dscp)) {
+			rc = PKTPRIO_DSCP;
+			user_priority = dscp2up(up_table, dscp);
+			PKTSETPRIO(pkt, user_priority);
+		}
+#ifdef WL_CUSTOM_MAPPING_OF_DSCP
+		else {
+			return pktsetprio(pkt, update_vtag);
+		}
+#endif /* WL_CUSTOM_MAPPING_OF_DSCP */
+
+		return (rc | user_priority);
+	} else {
+		return pktsetprio(pkt, update_vtag);
+	}
+}
+
+/* Returns TRUE and DSCP if IP header found, FALSE otherwise.
+ */
+bool
+BCMFASTPATH(pktgetdscp)(uint8 *pktdata, uint pktlen, uint8 *dscp)
+{
+	struct ether_header *eh;
+	struct ethervlan_header *evh;
+	uint8 *ip_body;
+	bool rc = FALSE;
+
+	/* minimum length is ether header and IP header */
+	if (pktlen < (sizeof(struct ether_header) + IPV4_MIN_HEADER_LEN)) {
+		return FALSE;
+	}
+
+	eh = (struct ether_header *) pktdata;
+
+	if ((eh->ether_type == HTON16(ETHER_TYPE_IP)) ||
+		(eh->ether_type == HTON16(ETHER_TYPE_IPV6))) {
+		ip_body = pktdata + sizeof(struct ether_header);
+		*dscp = IP_DSCP46(ip_body);
+		rc = TRUE;
+	}
+	else if (eh->ether_type == HTON16(ETHER_TYPE_8021Q)) {
+		evh = (struct ethervlan_header *)eh;
+
+		/* minimum length is ethervlan header and IP header */
+		if (pktlen >= sizeof(struct ethervlan_header) + IPV4_MIN_HEADER_LEN &&
+			evh->ether_type == HTON16(ETHER_TYPE_IP)) {
+			ip_body = pktdata + sizeof(struct ethervlan_header);
+			*dscp = IP_DSCP46(ip_body);
+			rc = TRUE;
+		}
+	}
+
+	return rc;
+}
+
+/* usr_prio range from low to high with usr_prio value */
+static bool
+up_table_set(uint8 *up_table, uint8 usr_prio, uint8 low, uint8 high)
+{
+	int i;
+
+	if (usr_prio > 7 || low > high || low >= UP_TABLE_MAX || high >= UP_TABLE_MAX) {
+		return FALSE;
+	}
+
+	for (i = low; i <= high; i++) {
+		up_table[i] = usr_prio;
+	}
+
+	return TRUE;
+}
+
+/* set user priority table */
+int
+BCMFASTPATH(wl_set_up_table)(uint8 *up_table, bcm_tlv_t *qos_map_ie)
+{
+	uint8 len;
+
+	if (up_table == NULL || qos_map_ie == NULL) {
+		return BCME_ERROR;
+	}
+
+	/* clear table to check table was set or not */
+	memset(up_table, 0xff, UP_TABLE_MAX);
+
+	/* length of QoS Map IE must be 16+n*2, n is number of exceptions */
+	if (qos_map_ie != NULL && qos_map_ie->id == DOT11_MNG_QOS_MAP_ID &&
+			(len = qos_map_ie->len) >= QOS_MAP_FIXED_LENGTH &&
+			(len % 2) == 0) {
+		uint8 *except_ptr = (uint8 *)qos_map_ie->data;
+		uint8 except_len = len - QOS_MAP_FIXED_LENGTH;
+		uint8 *range_ptr = except_ptr + except_len;
+		int i;
+
+		/* fill in ranges */
+		for (i = 0; i < QOS_MAP_FIXED_LENGTH; i += 2) {
+			uint8 low = range_ptr[i];
+			uint8 high = range_ptr[i + 1];
+			if (low == 255 && high == 255) {
+				continue;
+			}
+
+			if (!up_table_set(up_table, i / 2, low, high)) {
+				/* clear the table on failure */
+				memset(up_table, 0xff, UP_TABLE_MAX);
+				return BCME_ERROR;
+			}
+		}
+
+		/* update exceptions */
+		for (i = 0; i < except_len; i += 2) {
+			uint8 dscp = except_ptr[i];
+			uint8 usr_prio = except_ptr[i+1];
+
+			/* exceptions with invalid dscp/usr_prio are ignored */
+			up_table_set(up_table, usr_prio, dscp, dscp);
+		}
+	}
+
+	return BCME_OK;
+}
+
+#ifndef BCM_BOOTLOADER
+/* The 0.5KB string table is not removed by compiler even though it's unused */
+
+static char bcm_undeferrstr[32];
+static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE;
+
+/* Convert the error codes into related error strings  */
+/* BCMRAMFN for BCME_LAST usage */
+const char *
+BCMRAMFN(bcmerrorstr)(int bcmerror)
+{
+	/* check if someone added a bcmerror code but forgot to add errorstring */
+	ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1));
+
+	if (bcmerror > 0 || bcmerror < BCME_LAST) {
+		snprintf(bcm_undeferrstr, sizeof(bcm_undeferrstr), "Undefined error %d", bcmerror);
+		return bcm_undeferrstr;
+	}
+
+	ASSERT(strlen(bcmerrorstrtable[-bcmerror]) < BCME_STRLEN);
+
+	return bcmerrorstrtable[-bcmerror];
+}
+
+#endif /* !BCM_BOOTLOADER */
+
+#ifdef BCMDBG_PKT   /* pkt logging for debugging */
+/* Add a packet to the pktlist */
+static void
+_pktlist_add(pktlist_info_t *pktlist, void *pkt, int line, char *file)
+{
+	uint16 i;
+	char *basename;
+#ifdef BCMDBG_PTRACE
+	uint16 *idx = PKTLIST_IDX(pkt);
+#endif /* BCMDBG_PTRACE */
+
+	ASSERT(pktlist->count < PKTLIST_SIZE);
+
+	/* Verify the packet is not already part of the list */
+	for (i = 0; i < pktlist->count; i++) {
+		if (pktlist->list[i].pkt == pkt)
+			ASSERT(0);
+	}
+	pktlist->list[pktlist->count].pkt = pkt;
+	pktlist->list[pktlist->count].line = line;
+
+	basename = strrchr(file, '/');
+	if (basename)
+		basename++;
+	else
+		basename = file;
+	pktlist->list[pktlist->count].file = basename;
+#ifdef BCMDBG_PTRACE
+	*idx = pktlist->count;
+	bzero(pktlist->list[pktlist->count].pkt_trace, PKTTRACE_MAX_BYTES);
+#endif /* BCMDBG_PTRACE */
+	pktlist->count++;
+
+	return;
+}
+
+void
+pktlist_add(pktlist_info_t *pktlist, void *pkt, int line, char *file)
+{
+	void *p;
+	for (p = pkt; p != NULL; p = PKTCLINK(p))
+		_pktlist_add(pktlist, p, line, file);
+}
+
+/* Remove a packet from the pktlist */
+static void
+_pktlist_remove(pktlist_info_t *pktlist, void *pkt)
+{
+	uint16 i;
+	uint16 num = pktlist->count;
+#ifdef BCMDBG_PTRACE
+	uint16 *idx = PKTLIST_IDX(pkt);
+
+	ASSERT((*idx) < pktlist->count);
+#endif /* BCMDBG_PTRACE */
+
+	/* find the index where pkt exists */
+	for (i = 0; i < num; i++) {
+		/* check for the existence of pkt in the list */
+		if (pktlist->list[i].pkt == pkt) {
+#ifdef BCMDBG_PTRACE
+			ASSERT((*idx) == i);
+#endif /* BCMDBG_PTRACE */
+			/* replace with the last element */
+			pktlist->list[i].pkt = pktlist->list[num-1].pkt;
+			pktlist->list[i].line = pktlist->list[num-1].line;
+			pktlist->list[i].file = pktlist->list[num-1].file;
+#ifdef BCMDBG_PTRACE
+			memcpy(pktlist->list[i].pkt_trace, pktlist->list[num-1].pkt_trace,
+				PKTTRACE_MAX_BYTES);
+			idx = PKTLIST_IDX(pktlist->list[i].pkt);
+			*idx = i;
+#endif /* BCMDBG_PTRACE */
+			pktlist->count--;
+			return;
+		}
+	}
+	ASSERT(0);
+}
+
+void
+pktlist_remove(pktlist_info_t *pktlist, void *pkt)
+{
+	void *p;
+	for (p = pkt; p != NULL; p = PKTCLINK(p))
+		_pktlist_remove(pktlist, p);
+}
+
+#ifdef BCMDBG_PTRACE
+static void
+_pktlist_trace(pktlist_info_t *pktlist, void *pkt, uint16 bit)
+{
+	uint16 *idx = PKTLIST_IDX(pkt);
+
+	ASSERT(((*idx) < pktlist->count) && (bit < PKTTRACE_MAX_BITS));
+	ASSERT(pktlist->list[(*idx)].pkt == pkt);
+
+	pktlist->list[(*idx)].pkt_trace[bit/NBBY] |= (1 << ((bit)%NBBY));
+
+}
+
+void
+pktlist_trace(pktlist_info_t *pktlist, void *pkt, uint16 bit)
+{
+	void *p;
+	for (p = pkt; p != NULL; p = PKTCLINK(p))
+		_pktlist_trace(pktlist, p, bit);
+}
+#endif /* BCMDBG_PTRACE */
+
+/* Dump the pktlist (and the contents of each packet if 'data'
+ * is set). 'buf' should be large enough
+ */
+
+char *
+pktlist_dump(pktlist_info_t *pktlist, char *buf)
+{
+	char *obuf = buf;
+	uint16 i;
+
+	if (buf != NULL)
+		buf += sprintf(buf, "Packet list dump:\n");
+	else
+		printf("Packet list dump:\n");
+
+	for (i = 0; i < (pktlist->count); i++) {
+		if (buf != NULL)
+			buf += sprintf(buf, "Pkt_addr: 0x%p Line: %d File: %s\t",
+				OSL_OBFUSCATE_BUF(pktlist->list[i].pkt), pktlist->list[i].line,
+				pktlist->list[i].file);
+		else
+			printf("Pkt_addr: 0x%p Line: %d File: %s\t",
+				OSL_OBFUSCATE_BUF(pktlist->list[i].pkt),
+				pktlist->list[i].line, pktlist->list[i].file);
+
+/* #ifdef NOTDEF  Remove this ifdef to print pkttag and pktdata */
+		if (buf != NULL) {
+			if (PKTTAG(pktlist->list[i].pkt)) {
+				/* Print pkttag */
+				buf += sprintf(buf, "Pkttag(in hex): ");
+				buf += bcm_format_hex(buf, PKTTAG(pktlist->list[i].pkt),
+					OSL_PKTTAG_SZ);
+			}
+			buf += sprintf(buf, "Pktdata(in hex): ");
+			buf += bcm_format_hex(buf, PKTDATA(OSH_NULL, pktlist->list[i].pkt),
+			                      PKTLEN(OSH_NULL, pktlist->list[i].pkt));
+		} else {
+			void *pkt = pktlist->list[i].pkt, *npkt;
+
+			printf("Pkt[%d] Dump:\n", i);
+			while (pkt) {
+				int hroom;
+				uint pktlen;
+				uchar *src;
+#ifdef BCMDBG_PTRACE
+				uint16 *idx = PKTLIST_IDX(pkt);
+
+				ASSERT((*idx) < pktlist->count);
+				prhex("Pkt Trace (in hex):", pktlist->list[(*idx)].pkt_trace,
+					PKTTRACE_MAX_BYTES);
+#endif /* BCMDBG_PTRACE */
+				npkt = (void *)PKTNEXT(OSH_NULL, pkt);
+				PKTSETNEXT(OSH_NULL, pkt, NULL);
+
+				src = (uchar *)(PKTTAG(pkt));
+				pktlen = PKTLEN(OSH_NULL, pkt);
+				hroom = PKTHEADROOM(OSH_NULL, pkt);
+
+				printf("Pkttag_addr: %p\n", OSL_OBFUSCATE_BUF(src));
+				if (src)
+					prhex("Pkttag(in hex): ", src, OSL_PKTTAG_SZ);
+				src = (uchar *) (PKTDATA(OSH_NULL, pkt));
+				printf("Pkthead_addr: %p len: %d\n",
+					OSL_OBFUSCATE_BUF(src - hroom), hroom);
+				prhex("Pkt headroom content(in hex): ", src - hroom, hroom);
+				printf("Pktdata_addr: %p len: %d\n",
+					OSL_OBFUSCATE_BUF(src), pktlen);
+				prhex("Pktdata(in hex): ", src, pktlen);
+
+				pkt = npkt;
+			}
+		}
+/* #endif  NOTDEF */
+
+		if (buf != NULL)
+			buf += sprintf(buf, "\n");
+		else
+			printf("\n");
+	}
+	return obuf;
+}
+#endif  /* BCMDBG_PKT */
+
+/* iovar table lookup */
+/* could mandate sorted tables and do a binary search */
+const bcm_iovar_t*
+bcm_iovar_lookup(const bcm_iovar_t *table, const char *name)
+{
+	const bcm_iovar_t *vi;
+	const char *lookup_name;
+
+	/* skip any ':' delimited option prefixes */
+	lookup_name = strrchr(name, ':');
+	if (lookup_name != NULL)
+		lookup_name++;
+	else
+		lookup_name = name;
+
+	ASSERT(table != NULL);
+
+	for (vi = table; vi->name; vi++) {
+		if (!strcmp(vi->name, lookup_name))
+			return vi;
+	}
+	/* ran to end of table */
+
+	return NULL; /* var name not found */
+}
+
+int
+bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, uint len, bool set)
+{
+	int bcmerror = 0;
+	BCM_REFERENCE(arg);
+
+	/* length check on io buf */
+	switch (vi->type) {
+	case IOVT_BOOL:
+	case IOVT_INT8:
+	case IOVT_INT16:
+	case IOVT_INT32:
+	case IOVT_UINT8:
+	case IOVT_UINT16:
+	case IOVT_UINT32:
+		/* all integers are int32 sized args at the ioctl interface */
+		if (len < sizeof(int)) {
+			bcmerror = BCME_BUFTOOSHORT;
+		}
+		break;
+
+	case IOVT_BUFFER:
+		/* buffer must meet minimum length requirement */
+		if (len < vi->minlen) {
+			bcmerror = BCME_BUFTOOSHORT;
+		}
+		break;
+
+	case IOVT_VOID:
+		if (!set) {
+			/* Cannot return nil... */
+			bcmerror = BCME_UNSUPPORTED;
+		}
+		break;
+
+	default:
+		/* unknown type for length check in iovar info */
+		ASSERT(0);
+		bcmerror = BCME_UNSUPPORTED;
+	}
+
+	return bcmerror;
+}
+
+/*
+ * Hierarchical Multiword bitmap based small id allocator.
+ *
+ * Multilevel hierarchy bitmap. (maximum 2 levels)
+ * First hierarchy uses a multiword bitmap to identify 32bit words in the
+ * second hierarchy that have at least a single bit set. Each bit in a word of
+ * the second hierarchy represents a unique ID that may be allocated.
+ *
+ * BCM_MWBMAP_ITEMS_MAX: Maximum number of IDs managed.
+ * BCM_MWBMAP_BITS_WORD: Number of bits in a bitmap word word
+ * BCM_MWBMAP_WORDS_MAX: Maximum number of bitmap words needed for free IDs.
+ * BCM_MWBMAP_WDMAP_MAX: Maximum number of bitmap wordss identifying first non
+ *                       non-zero bitmap word carrying at least one free ID.
+ * BCM_MWBMAP_SHIFT_OP:  Used in MOD, DIV and MUL operations.
+ * BCM_MWBMAP_INVALID_IDX: Value ~0U is treated as an invalid ID
+ *
+ * Design Notes:
+ * BCM_MWBMAP_USE_CNTSETBITS trades CPU for memory. A runtime count of how many
+ * bits are computed each time on allocation and deallocation, requiring 4
+ * array indexed access and 3 arithmetic operations. When not defined, a runtime
+ * count of set bits state is maintained. Upto 32 Bytes per 1024 IDs is needed.
+ * In a 4K max ID allocator, up to 128Bytes are hence used per instantiation.
+ * In a memory limited system e.g. dongle builds, a CPU for memory tradeoff may
+ * be used by defining BCM_MWBMAP_USE_CNTSETBITS.
+ *
+ * Note: wd_bitmap[] is statically declared and is not ROM friendly ... array
+ * size is fixed. No intention to support larger than 4K indice allocation. ID
+ * allocators for ranges smaller than 4K will have a wastage of only 12Bytes
+ * with savings in not having to use an indirect access, had it been dynamically
+ * allocated.
+ */
+#if defined(DONGLEBUILD)
+#define BCM_MWBMAP_USE_CNTSETBITS		/* runtime count set bits */
+#if defined(PCIEDEV_HOST_PKTID_AUDIT_ENABLED)
+#define BCM_MWBMAP_ITEMS_MAX	(38 * 1024)
+#else /* ! PCIEDEV_HOST_PKTID_AUDIT_ENABLED */
+#define BCM_MWBMAP_ITEMS_MAX	(7 * 1024)
+#endif /* PCIEDEV_HOST_PKTID_AUDIT_ENABLED */
+#else  /* ! DONGLEBUILD */
+#define BCM_MWBMAP_ITEMS_MAX    (64 * 1024)  /* May increase to 64K */
+#endif /*   DONGLEBUILD */
+
+#define BCM_MWBMAP_BITS_WORD    (NBITS(uint32))
+#define BCM_MWBMAP_WORDS_MAX    (BCM_MWBMAP_ITEMS_MAX / BCM_MWBMAP_BITS_WORD)
+#define BCM_MWBMAP_WDMAP_MAX    (BCM_MWBMAP_WORDS_MAX / BCM_MWBMAP_BITS_WORD)
+#define BCM_MWBMAP_SHIFT_OP     (5)
+#define BCM_MWBMAP_MODOP(ix)    ((ix) & (BCM_MWBMAP_BITS_WORD - 1))
+#define BCM_MWBMAP_DIVOP(ix)    ((ix) >> BCM_MWBMAP_SHIFT_OP)
+#define BCM_MWBMAP_MULOP(ix)    ((ix) << BCM_MWBMAP_SHIFT_OP)
+
+/* Redefine PTR() and/or HDL() conversion to invoke audit for debugging */
+#define BCM_MWBMAP_PTR(hdl)		((struct bcm_mwbmap *)(hdl))
+#define BCM_MWBMAP_HDL(ptr)		((void *)(ptr))
+
+#if defined(BCM_MWBMAP_DEBUG)
+#define BCM_MWBMAP_AUDIT(mwb) \
+	do { \
+		ASSERT((mwb != NULL) && \
+		       (((struct bcm_mwbmap *)(mwb))->magic == (void *)(mwb))); \
+		bcm_mwbmap_audit(mwb); \
+	} while (0)
+#define MWBMAP_ASSERT(exp)		ASSERT(exp)
+#define MWBMAP_DBG(x)           printf x
+#else   /* !BCM_MWBMAP_DEBUG */
+#define BCM_MWBMAP_AUDIT(mwb)   do {} while (0)
+#define MWBMAP_ASSERT(exp)		do {} while (0)
+#define MWBMAP_DBG(x)
+#endif  /* !BCM_MWBMAP_DEBUG */
+
+typedef struct bcm_mwbmap {     /* Hierarchical multiword bitmap allocator    */
+	uint16 wmaps;               /* Total number of words in free wd bitmap    */
+	uint16 imaps;               /* Total number of words in free id bitmap    */
+	int32  ifree;               /* Count of free indices. Used only in audits */
+	uint16 total;               /* Total indices managed by multiword bitmap  */
+
+	void * magic;               /* Audit handle parameter from user           */
+
+	uint32 wd_bitmap[BCM_MWBMAP_WDMAP_MAX]; /* 1st level bitmap of            */
+#if !defined(BCM_MWBMAP_USE_CNTSETBITS)
+	int8   wd_count[BCM_MWBMAP_WORDS_MAX];  /* free id running count, 1st lvl */
+#endif /*  ! BCM_MWBMAP_USE_CNTSETBITS */
+
+	uint32 id_bitmap[0];        /* Second level bitmap                        */
+} bcm_mwbmap_t;
+
+/* Incarnate a hierarchical multiword bitmap based small index allocator. */
+struct bcm_mwbmap *
+bcm_mwbmap_init(osl_t *osh, uint32 items_max)
+{
+	struct bcm_mwbmap * mwbmap_p;
+	uint32 wordix, size, words, extra;
+
+	/* Implementation Constraint: Uses 32bit word bitmap */
+	MWBMAP_ASSERT(BCM_MWBMAP_BITS_WORD == 32U);
+	MWBMAP_ASSERT(BCM_MWBMAP_SHIFT_OP == 5U);
+	MWBMAP_ASSERT(ISPOWEROF2(BCM_MWBMAP_ITEMS_MAX));
+	MWBMAP_ASSERT((BCM_MWBMAP_ITEMS_MAX % BCM_MWBMAP_BITS_WORD) == 0U);
+
+	ASSERT(items_max <= BCM_MWBMAP_ITEMS_MAX);
+
+	/* Determine the number of words needed in the multiword bitmap */
+	extra = BCM_MWBMAP_MODOP(items_max);
+	words = BCM_MWBMAP_DIVOP(items_max) + ((extra != 0U) ? 1U : 0U);
+
+	/* Allocate runtime state of multiword bitmap */
+	/* Note: wd_count[] or wd_bitmap[] are not dynamically allocated */
+	size = sizeof(bcm_mwbmap_t) + (sizeof(uint32) * words);
+	mwbmap_p = (bcm_mwbmap_t *)MALLOCZ(osh, size);
+	if (mwbmap_p == (bcm_mwbmap_t *)NULL) {
+		ASSERT(0);
+		goto error1;
+	}
+
+	/* Initialize runtime multiword bitmap state */
+	mwbmap_p->imaps = (uint16)words;
+	mwbmap_p->ifree = (int32)items_max;
+	mwbmap_p->total = (uint16)items_max;
+
+	/* Setup magic, for use in audit of handle */
+	mwbmap_p->magic = BCM_MWBMAP_HDL(mwbmap_p);
+
+	/* Setup the second level bitmap of free indices */
+	/* Mark all indices as available */
+	for (wordix = 0U; wordix < mwbmap_p->imaps; wordix++) {
+		mwbmap_p->id_bitmap[wordix] = (uint32)(~0U);
+#if !defined(BCM_MWBMAP_USE_CNTSETBITS)
+		mwbmap_p->wd_count[wordix] = BCM_MWBMAP_BITS_WORD;
+#endif /*  ! BCM_MWBMAP_USE_CNTSETBITS */
+	}
+
+	/* Ensure that extra indices are tagged as un-available */
+	if (extra) { /* fixup the free ids in last bitmap and wd_count */
+		uint32 * bmap_p = &mwbmap_p->id_bitmap[mwbmap_p->imaps - 1];
+		*bmap_p ^= (uint32)(~0U << extra); /* fixup bitmap */
+#if !defined(BCM_MWBMAP_USE_CNTSETBITS)
+		mwbmap_p->wd_count[mwbmap_p->imaps - 1] = (int8)extra; /* fixup count */
+#endif /*  ! BCM_MWBMAP_USE_CNTSETBITS */
+	}
+
+	/* Setup the first level bitmap hierarchy */
+	extra = BCM_MWBMAP_MODOP(mwbmap_p->imaps);
+	words = BCM_MWBMAP_DIVOP(mwbmap_p->imaps) + ((extra != 0U) ? 1U : 0U);
+
+	mwbmap_p->wmaps = (uint16)words;
+
+	for (wordix = 0U; wordix < mwbmap_p->wmaps; wordix++)
+		mwbmap_p->wd_bitmap[wordix] = (uint32)(~0U);
+	if (extra) {
+		uint32 * bmap_p = &mwbmap_p->wd_bitmap[mwbmap_p->wmaps - 1];
+		*bmap_p ^= (uint32)(~0U << extra); /* fixup bitmap */
+	}
+
+	return mwbmap_p;
+
+error1:
+	return BCM_MWBMAP_INVALID_HDL;
+}
+
+/* Release resources used by multiword bitmap based small index allocator. */
+void
+bcm_mwbmap_fini(osl_t * osh, struct bcm_mwbmap * mwbmap_hdl)
+{
+	bcm_mwbmap_t * mwbmap_p;
+
+	BCM_MWBMAP_AUDIT(mwbmap_hdl);
+	mwbmap_p = BCM_MWBMAP_PTR(mwbmap_hdl);
+
+	MFREE(osh, mwbmap_p, sizeof(struct bcm_mwbmap)
+			     + (sizeof(uint32) * mwbmap_p->imaps));
+	return;
+}
+
+/* Allocate a unique small index using a multiword bitmap index allocator.    */
+uint32
+BCMFASTPATH(bcm_mwbmap_alloc)(struct bcm_mwbmap * mwbmap_hdl)
+{
+	bcm_mwbmap_t * mwbmap_p;
+	uint32 wordix, bitmap;
+
+	BCM_MWBMAP_AUDIT(mwbmap_hdl);
+	mwbmap_p = BCM_MWBMAP_PTR(mwbmap_hdl);
+
+	/* Start with the first hierarchy */
+	for (wordix = 0; wordix < mwbmap_p->wmaps; ++wordix) {
+
+		bitmap = mwbmap_p->wd_bitmap[wordix]; /* get the word bitmap */
+
+		if (bitmap != 0U) {
+
+			uint32 count, bitix, *bitmap_p;
+
+			bitmap_p = &mwbmap_p->wd_bitmap[wordix];
+
+			/* clear all except trailing 1 */
+			if (bitmap != (1u << 31u)) {
+				bitmap = (uint32)(((int)(bitmap)) & (-((int)(bitmap))));
+			}
+			MWBMAP_ASSERT(C_bcm_count_leading_zeros(bitmap) ==
+			              bcm_count_leading_zeros(bitmap));
+			bitix = bcm_count_leading_zeros(bitmap); /* use asm clz */
+			bitix = (bitix <= (BCM_MWBMAP_BITS_WORD - 1)) ?
+					((BCM_MWBMAP_BITS_WORD - 1) - bitix) : 0;
+			wordix = BCM_MWBMAP_MULOP(wordix) + bitix;
+
+			/* Clear bit if wd count is 0, without conditional branch */
+#if defined(BCM_MWBMAP_USE_CNTSETBITS)
+			count = bcm_cntsetbits(mwbmap_p->id_bitmap[wordix]) - 1;
+#else  /* ! BCM_MWBMAP_USE_CNTSETBITS */
+			mwbmap_p->wd_count[wordix]--;
+			count = mwbmap_p->wd_count[wordix];
+			MWBMAP_ASSERT(count ==
+			              (bcm_cntsetbits(mwbmap_p->id_bitmap[wordix]) - 1));
+#endif /* ! BCM_MWBMAP_USE_CNTSETBITS */
+			MWBMAP_ASSERT(count >= 0);
+
+			/* clear wd_bitmap bit if id_map count is 0 */
+			bitmap = (uint32)(count == 0) << bitix;
+
+			MWBMAP_DBG((
+			    "Lvl1: bitix<%02u> wordix<%02u>: %08x ^ %08x = %08x wfree %d",
+			    bitix, wordix, *bitmap_p, bitmap, (*bitmap_p) ^ bitmap, count));
+
+			*bitmap_p ^= bitmap;
+
+			/* Use bitix in the second hierarchy */
+			bitmap_p = &mwbmap_p->id_bitmap[wordix];
+
+			bitmap = mwbmap_p->id_bitmap[wordix]; /* get the id bitmap */
+			MWBMAP_ASSERT(bitmap != 0U);
+
+			/* clear all except trailing 1 */
+			if (bitmap != (1u << 31u)) {
+				bitmap = (uint32)(((int)(bitmap)) & (-((int)(bitmap))));
+			}
+			MWBMAP_ASSERT(C_bcm_count_leading_zeros(bitmap) ==
+			              bcm_count_leading_zeros(bitmap));
+			bitix    = BCM_MWBMAP_MULOP(wordix)
+				 + (BCM_MWBMAP_BITS_WORD - 1)
+				 - bcm_count_leading_zeros(bitmap); /* use asm clz */
+
+			mwbmap_p->ifree--; /* decrement system wide free count */
+			MWBMAP_ASSERT(mwbmap_p->ifree >= 0);
+
+			MWBMAP_DBG((
+			    "Lvl2: bitix<%02u> wordix<%02u>: %08x ^ %08x = %08x ifree %d",
+			    bitix, wordix, *bitmap_p, bitmap, (*bitmap_p) ^ bitmap,
+			    mwbmap_p->ifree));
+
+			*bitmap_p ^= bitmap; /* mark as allocated = 1b0 */
+
+			return bitix;
+		}
+	}
+
+	ASSERT(mwbmap_p->ifree == 0);
+
+	return BCM_MWBMAP_INVALID_IDX;
+}
+
+/* Force an index at a specified position to be in use */
+void
+bcm_mwbmap_force(struct bcm_mwbmap * mwbmap_hdl, uint32 bitix)
+{
+	bcm_mwbmap_t * mwbmap_p;
+	uint32 count, wordix, bitmap, *bitmap_p;
+
+	BCM_MWBMAP_AUDIT(mwbmap_hdl);
+	mwbmap_p = BCM_MWBMAP_PTR(mwbmap_hdl);
+
+	ASSERT(bitix < mwbmap_p->total);
+
+	/* Start with second hierarchy */
+	wordix   = BCM_MWBMAP_DIVOP(bitix);
+	bitmap   = (uint32)(1U << BCM_MWBMAP_MODOP(bitix));
+	bitmap_p = &mwbmap_p->id_bitmap[wordix];
+
+	ASSERT((*bitmap_p & bitmap) == bitmap);
+
+	mwbmap_p->ifree--; /* update free count */
+	ASSERT(mwbmap_p->ifree >= 0);
+
+	MWBMAP_DBG(("Lvl2: bitix<%u> wordix<%u>: %08x ^ %08x = %08x ifree %d",
+	            bitix, wordix, *bitmap_p, bitmap, (*bitmap_p) ^ bitmap,
+	            mwbmap_p->ifree));
+
+	*bitmap_p ^= bitmap; /* mark as in use */
+
+	/* Update first hierarchy */
+	bitix    = wordix;
+
+	wordix   = BCM_MWBMAP_DIVOP(bitix);
+	bitmap_p = &mwbmap_p->wd_bitmap[wordix];
+
+#if defined(BCM_MWBMAP_USE_CNTSETBITS)
+	count = bcm_cntsetbits(mwbmap_p->id_bitmap[bitix]);
+#else  /* ! BCM_MWBMAP_USE_CNTSETBITS */
+	mwbmap_p->wd_count[bitix]--;
+	count = mwbmap_p->wd_count[bitix];
+	MWBMAP_ASSERT(count == bcm_cntsetbits(mwbmap_p->id_bitmap[bitix]));
+#endif /* ! BCM_MWBMAP_USE_CNTSETBITS */
+	MWBMAP_ASSERT(count >= 0);
+
+	bitmap   = (uint32)(count == 0) << BCM_MWBMAP_MODOP(bitix);
+
+	MWBMAP_DBG(("Lvl1: bitix<%02lu> wordix<%02u>: %08x ^ %08x = %08x wfree %d",
+	            BCM_MWBMAP_MODOP(bitix), wordix, *bitmap_p, bitmap,
+	            (*bitmap_p) ^ bitmap, count));
+
+	*bitmap_p ^= bitmap; /* mark as in use */
+
+	return;
+}
+
+/* Free a previously allocated index back into the multiword bitmap allocator */
+void
+BCMPOSTTRAPFASTPATH(bcm_mwbmap_free)(struct bcm_mwbmap * mwbmap_hdl, uint32 bitix)
+{
+	bcm_mwbmap_t * mwbmap_p;
+	uint32 wordix, bitmap, *bitmap_p;
+
+	BCM_MWBMAP_AUDIT(mwbmap_hdl);
+	mwbmap_p = BCM_MWBMAP_PTR(mwbmap_hdl);
+
+	ASSERT_FP(bitix < mwbmap_p->total);
+
+	/* Start with second level hierarchy */
+	wordix   = BCM_MWBMAP_DIVOP(bitix);
+	bitmap   = (1U << BCM_MWBMAP_MODOP(bitix));
+	bitmap_p = &mwbmap_p->id_bitmap[wordix];
+
+	ASSERT_FP((*bitmap_p & bitmap) == 0U);	/* ASSERT not a double free */
+
+	mwbmap_p->ifree++; /* update free count */
+	ASSERT_FP(mwbmap_p->ifree <= mwbmap_p->total);
+
+	MWBMAP_DBG(("Lvl2: bitix<%02u> wordix<%02u>: %08x | %08x = %08x ifree %d",
+	            bitix, wordix, *bitmap_p, bitmap, (*bitmap_p) | bitmap,
+	            mwbmap_p->ifree));
+
+	*bitmap_p |= bitmap; /* mark as available */
+
+	/* Now update first level hierarchy */
+
+	bitix    = wordix;
+
+	wordix   = BCM_MWBMAP_DIVOP(bitix); /* first level's word index */
+	bitmap   = (1U << BCM_MWBMAP_MODOP(bitix));
+	bitmap_p = &mwbmap_p->wd_bitmap[wordix];
+
+#if !defined(BCM_MWBMAP_USE_CNTSETBITS)
+	mwbmap_p->wd_count[bitix]++;
+#endif
+
+#if defined(BCM_MWBMAP_DEBUG)
+	{
+		uint32 count;
+#if defined(BCM_MWBMAP_USE_CNTSETBITS)
+		count = bcm_cntsetbits(mwbmap_p->id_bitmap[bitix]);
+#else  /*  ! BCM_MWBMAP_USE_CNTSETBITS */
+		count = mwbmap_p->wd_count[bitix];
+		MWBMAP_ASSERT(count == bcm_cntsetbits(mwbmap_p->id_bitmap[bitix]));
+#endif /*  ! BCM_MWBMAP_USE_CNTSETBITS */
+
+		MWBMAP_ASSERT(count <= BCM_MWBMAP_BITS_WORD);
+
+		MWBMAP_DBG(("Lvl1: bitix<%02u> wordix<%02u>: %08x | %08x = %08x wfree %d",
+		            bitix, wordix, *bitmap_p, bitmap, (*bitmap_p) | bitmap, count));
+	}
+#endif /* BCM_MWBMAP_DEBUG */
+
+	*bitmap_p |= bitmap;
+
+	return;
+}
+
+/* Fetch the toal number of free indices in the multiword bitmap allocator */
+uint32
+bcm_mwbmap_free_cnt(struct bcm_mwbmap * mwbmap_hdl)
+{
+	bcm_mwbmap_t * mwbmap_p;
+
+	BCM_MWBMAP_AUDIT(mwbmap_hdl);
+	mwbmap_p = BCM_MWBMAP_PTR(mwbmap_hdl);
+
+	ASSERT_FP(mwbmap_p->ifree >= 0);
+
+	return (uint32)mwbmap_p->ifree;
+}
+
+/* Determine whether an index is inuse or free */
+bool
+bcm_mwbmap_isfree(struct bcm_mwbmap * mwbmap_hdl, uint32 bitix)
+{
+	bcm_mwbmap_t * mwbmap_p;
+	uint32 wordix, bitmap;
+
+	BCM_MWBMAP_AUDIT(mwbmap_hdl);
+	mwbmap_p = BCM_MWBMAP_PTR(mwbmap_hdl);
+
+	ASSERT(bitix < mwbmap_p->total);
+
+	wordix   = BCM_MWBMAP_DIVOP(bitix);
+	bitmap   = (1U << BCM_MWBMAP_MODOP(bitix));
+
+	return ((mwbmap_p->id_bitmap[wordix] & bitmap) != 0U);
+}
+
+/* Debug dump a multiword bitmap allocator */
+void
+bcm_mwbmap_show(struct bcm_mwbmap * mwbmap_hdl)
+{
+	uint32 ix, count;
+	bcm_mwbmap_t * mwbmap_p;
+
+	BCM_MWBMAP_AUDIT(mwbmap_hdl);
+	mwbmap_p = BCM_MWBMAP_PTR(mwbmap_hdl);
+
+	printf("mwbmap_p %p wmaps %u imaps %u ifree %d total %u\n",
+		OSL_OBFUSCATE_BUF((void *)mwbmap_p),
+	       mwbmap_p->wmaps, mwbmap_p->imaps, mwbmap_p->ifree, mwbmap_p->total);
+	for (ix = 0U; ix < mwbmap_p->wmaps; ix++) {
+		printf("\tWDMAP:%2u. 0x%08x\t", ix, mwbmap_p->wd_bitmap[ix]);
+		bcm_bitprint32(mwbmap_p->wd_bitmap[ix]);
+		printf("\n");
+	}
+	for (ix = 0U; ix < mwbmap_p->imaps; ix++) {
+#if defined(BCM_MWBMAP_USE_CNTSETBITS)
+		count = bcm_cntsetbits(mwbmap_p->id_bitmap[ix]);
+#else  /* ! BCM_MWBMAP_USE_CNTSETBITS */
+		count = mwbmap_p->wd_count[ix];
+		MWBMAP_ASSERT(count == bcm_cntsetbits(mwbmap_p->id_bitmap[ix]));
+#endif /* ! BCM_MWBMAP_USE_CNTSETBITS */
+		printf("\tIDMAP:%2u. 0x%08x %02u\t", ix, mwbmap_p->id_bitmap[ix], count);
+		bcm_bitprint32(mwbmap_p->id_bitmap[ix]);
+		printf("\n");
+	}
+
+	return;
+}
+
+/* Audit a hierarchical multiword bitmap */
+void
+bcm_mwbmap_audit(struct bcm_mwbmap * mwbmap_hdl)
+{
+	bcm_mwbmap_t * mwbmap_p;
+	uint32 count, free_cnt = 0U, wordix, idmap_ix, bitix, *bitmap_p;
+
+	mwbmap_p = BCM_MWBMAP_PTR(mwbmap_hdl);
+
+	for (wordix = 0U; wordix < mwbmap_p->wmaps; ++wordix) {
+
+		bitmap_p = &mwbmap_p->wd_bitmap[wordix];
+
+		for (bitix = 0U; bitix < BCM_MWBMAP_BITS_WORD; bitix++) {
+			if ((*bitmap_p) & (1u << bitix)) {
+				idmap_ix = BCM_MWBMAP_MULOP(wordix) + bitix;
+#if defined(BCM_MWBMAP_USE_CNTSETBITS)
+				count = bcm_cntsetbits(mwbmap_p->id_bitmap[idmap_ix]);
+#else  /* ! BCM_MWBMAP_USE_CNTSETBITS */
+				count = mwbmap_p->wd_count[idmap_ix];
+				ASSERT(count == bcm_cntsetbits(mwbmap_p->id_bitmap[idmap_ix]));
+#endif /* ! BCM_MWBMAP_USE_CNTSETBITS */
+				ASSERT(count != 0U);
+				free_cnt += count;
+			}
+		}
+	}
+
+	ASSERT((int)free_cnt == mwbmap_p->ifree);
+	if (free_cnt != mwbmap_p->ifree) {
+		printf("Error: free_cnt != mwbmap_p->ifree\n");
+	}
+}
+
+/* END : Multiword bitmap based 64bit to Unique 32bit Id allocator. */
+
+/* Simple 16bit Id allocator using a stack implementation. */
+typedef struct id16_map {
+	uint32  failures;  /* count of failures */
+	void    *dbg;      /* debug placeholder */
+	uint16  total;     /* total number of ids managed by allocator */
+	uint16  start;     /* start value of 16bit ids to be managed */
+	int     stack_idx; /* index into stack of available ids */
+	uint16  stack[0];  /* stack of 16 bit ids */
+} id16_map_t;
+
+#define ID16_MAP_SZ(items)      (sizeof(id16_map_t) + \
+				     (sizeof(uint16) * (items)))
+
+#if defined(BCM_DBG)
+
+/* Uncomment BCM_DBG_ID16 to debug double free */
+/* #define BCM_DBG_ID16 */
+
+typedef struct id16_map_dbg {
+	uint16  total;
+	bool    avail[0];
+} id16_map_dbg_t;
+#define ID16_MAP_DBG_SZ(items)  (sizeof(id16_map_dbg_t) + \
+				     (sizeof(bool) * (items)))
+#define ID16_MAP_MSG(x)         print x
+#else
+#define ID16_MAP_MSG(x)
+#endif /* BCM_DBG */
+
+void * /* Construct an id16 allocator: [start_val16 .. start_val16+total_ids) */
+id16_map_init(osl_t *osh, uint16 total_ids, uint16 start_val16)
+{
+	uint16 idx, val16;
+	id16_map_t * id16_map;
+
+	ASSERT(total_ids > 0);
+
+	/* A start_val16 of ID16_UNDEFINED, allows the caller to fill the id16 map
+	 * with random values.
+	 */
+	ASSERT((start_val16 == ID16_UNDEFINED) ||
+	       (start_val16 + total_ids) < ID16_INVALID);
+
+	id16_map = (id16_map_t *) MALLOCZ(osh, ID16_MAP_SZ(total_ids));
+	if (id16_map == NULL) {
+		return NULL;
+	}
+
+	id16_map->total = total_ids;
+	id16_map->start = start_val16;
+	id16_map->failures = 0;
+	id16_map->dbg = NULL;
+
+	/*
+	 * Populate stack with 16bit id values, commencing with start_val16.
+	 * if start_val16 is ID16_UNDEFINED, then do not populate the id16 map.
+	 */
+	id16_map->stack_idx = -1;
+
+	if (id16_map->start != ID16_UNDEFINED) {
+		val16 = start_val16;
+
+		for (idx = 0; idx < total_ids; idx++, val16++) {
+			id16_map->stack_idx = idx;
+			id16_map->stack[id16_map->stack_idx] = val16;
+		}
+	}
+
+#if defined(BCM_DBG) && defined(BCM_DBG_ID16)
+	if (id16_map->start != ID16_UNDEFINED) {
+		id16_map->dbg = MALLOCZ(osh, ID16_MAP_DBG_SZ(total_ids));
+
+		if (id16_map->dbg) {
+			id16_map_dbg_t *id16_map_dbg = (id16_map_dbg_t *)id16_map->dbg;
+
+			id16_map_dbg->total = total_ids;
+			for (idx = 0; idx < total_ids; idx++) {
+				id16_map_dbg->avail[idx] = TRUE;
+			}
+		}
+	}
+#endif /* BCM_DBG && BCM_DBG_ID16 */
+
+	return (void *)id16_map;
+}
+
+void * /* Destruct an id16 allocator instance */
+id16_map_fini(osl_t *osh, void * id16_map_hndl)
+{
+	uint16 total_ids;
+	id16_map_t * id16_map;
+
+	if (id16_map_hndl == NULL)
+		return NULL;
+
+	id16_map = (id16_map_t *)id16_map_hndl;
+
+	total_ids = id16_map->total;
+	ASSERT(total_ids > 0);
+
+#if defined(BCM_DBG) && defined(BCM_DBG_ID16)
+	if (id16_map->dbg) {
+		MFREE(osh, id16_map->dbg, ID16_MAP_DBG_SZ(total_ids));
+	}
+#endif /* BCM_DBG && BCM_DBG_ID16 */
+
+	id16_map->total = 0;
+	MFREE(osh, id16_map, ID16_MAP_SZ(total_ids));
+
+	return NULL;
+}
+
+void
+id16_map_clear(void * id16_map_hndl, uint16 total_ids, uint16 start_val16)
+{
+	uint16 idx, val16;
+	id16_map_t * id16_map;
+
+	ASSERT(total_ids > 0);
+	/* A start_val16 of ID16_UNDEFINED, allows the caller to fill the id16 map
+	 * with random values.
+	 */
+	ASSERT((start_val16 == ID16_UNDEFINED) ||
+	       (start_val16 + total_ids) < ID16_INVALID);
+
+	id16_map = (id16_map_t *)id16_map_hndl;
+	if (id16_map == NULL) {
+		return;
+	}
+
+	id16_map->total = total_ids;
+	id16_map->start = start_val16;
+	id16_map->failures = 0;
+
+	/* Populate stack with 16bit id values, commencing with start_val16 */
+	id16_map->stack_idx = -1;
+
+	if (id16_map->start != ID16_UNDEFINED) {
+		val16 = start_val16;
+
+		for (idx = 0; idx < total_ids; idx++, val16++) {
+			id16_map->stack_idx = idx;
+			id16_map->stack[id16_map->stack_idx] = val16;
+		}
+	}
+
+#if defined(BCM_DBG) && defined(BCM_DBG_ID16)
+	if (id16_map->start != ID16_UNDEFINED) {
+		if (id16_map->dbg) {
+			id16_map_dbg_t *id16_map_dbg = (id16_map_dbg_t *)id16_map->dbg;
+
+			id16_map_dbg->total = total_ids;
+			for (idx = 0; idx < total_ids; idx++) {
+				id16_map_dbg->avail[idx] = TRUE;
+			}
+		}
+	}
+#endif /* BCM_DBG && BCM_DBG_ID16 */
+}
+
+uint16 /* Allocate a unique 16bit id */
+BCMFASTPATH(id16_map_alloc)(void * id16_map_hndl)
+{
+	uint16 val16;
+	id16_map_t * id16_map;
+
+	ASSERT_FP(id16_map_hndl != NULL);
+
+	id16_map = (id16_map_t *)id16_map_hndl;
+
+	ASSERT_FP(id16_map->total > 0);
+
+	if (id16_map->stack_idx < 0) {
+		id16_map->failures++;
+		return ID16_INVALID;
+	}
+
+	val16 = id16_map->stack[id16_map->stack_idx];
+	id16_map->stack_idx--;
+
+#if defined(BCM_DBG) && defined(BCM_DBG_ID16)
+	ASSERT_FP((id16_map->start == ID16_UNDEFINED) ||
+	       (val16 < (id16_map->start + id16_map->total)));
+
+	if (id16_map->dbg) { /* Validate val16 */
+		id16_map_dbg_t *id16_map_dbg = (id16_map_dbg_t *)id16_map->dbg;
+
+		ASSERT_FP(id16_map_dbg->avail[val16 - id16_map->start] == TRUE);
+		id16_map_dbg->avail[val16 - id16_map->start] = FALSE;
+	}
+#endif /* BCM_DBG && BCM_DBG_ID16 */
+
+	return val16;
+}
+
+void /* Free a 16bit id value into the id16 allocator */
+BCMFASTPATH(id16_map_free)(void * id16_map_hndl, uint16 val16)
+{
+	id16_map_t * id16_map;
+
+	ASSERT_FP(id16_map_hndl != NULL);
+
+	id16_map = (id16_map_t *)id16_map_hndl;
+
+#if defined(BCM_DBG) && defined(BCM_DBG_ID16)
+	ASSERT_FP((id16_map->start == ID16_UNDEFINED) ||
+	       (val16 < (id16_map->start + id16_map->total)));
+
+	if (id16_map->dbg) { /* Validate val16 */
+		id16_map_dbg_t *id16_map_dbg = (id16_map_dbg_t *)id16_map->dbg;
+
+		ASSERT_FP(id16_map_dbg->avail[val16 - id16_map->start] == FALSE);
+		id16_map_dbg->avail[val16 - id16_map->start] = TRUE;
+	}
+#endif /* BCM_DBG && BCM_DBG_ID16 */
+
+	id16_map->stack_idx++;
+	id16_map->stack[id16_map->stack_idx] = val16;
+}
+
+uint32 /* Returns number of failures to allocate an unique id16 */
+id16_map_failures(void * id16_map_hndl)
+{
+	ASSERT(id16_map_hndl != NULL);
+	return ((id16_map_t *)id16_map_hndl)->failures;
+}
+
+bool
+id16_map_audit(void * id16_map_hndl)
+{
+	int idx;
+	int insane = 0;
+	id16_map_t * id16_map;
+
+	ASSERT(id16_map_hndl != NULL);
+
+	id16_map = (id16_map_t *)id16_map_hndl;
+
+	ASSERT(id16_map->stack_idx >= -1);
+	ASSERT(id16_map->stack_idx < (int)id16_map->total);
+
+	if (id16_map->start == ID16_UNDEFINED)
+		goto done;
+
+	for (idx = 0; idx <= id16_map->stack_idx; idx++) {
+		ASSERT(id16_map->stack[idx] >= id16_map->start);
+		ASSERT(id16_map->stack[idx] < (id16_map->start + id16_map->total));
+
+#if defined(BCM_DBG) && defined(BCM_DBG_ID16)
+		if (id16_map->dbg) {
+			uint16 val16 = id16_map->stack[idx];
+			if (((id16_map_dbg_t *)(id16_map->dbg))->avail[val16] != TRUE) {
+				insane |= 1;
+				ID16_MAP_MSG(("id16_map<%p>: stack_idx %u invalid val16 %u\n",
+				              OSL_OBFUSATE_BUF(id16_map_hndl), idx, val16));
+			}
+		}
+#endif /* BCM_DBG && BCM_DBG_ID16 */
+	}
+
+#if defined(BCM_DBG) && defined(BCM_DBG_ID16)
+	if (id16_map->dbg) {
+		uint16 avail = 0; /* Audit available ids counts */
+		for (idx = 0; idx < id16_map_dbg->total; idx++) {
+			if (((id16_map_dbg_t *)(id16_map->dbg))->avail[idx16] == TRUE)
+				avail++;
+		}
+		if (avail && (avail != (id16_map->stack_idx + 1))) {
+			insane |= 1;
+			ID16_MAP_MSG(("id16_map<%p>: avail %u stack_idx %u\n",
+			              OSL_OBFUSCATE_BUF(id16_map_hndl),
+			              avail, id16_map->stack_idx));
+		}
+	}
+#endif /* BCM_DBG && BCM_DBG_ID16 */
+
+done:
+	/* invoke any other system audits */
+	return (!!insane);
+}
+
+/* END: Simple id16 allocator */
+
+void
+dll_pool_detach(void * osh, dll_pool_t * pool, uint16 elems_max, uint16 elem_size)
+{
+	uint32 mem_size;
+	mem_size = (uint32)sizeof(dll_pool_t) + ((uint32)elems_max * (uint32)elem_size);
+	if (pool) {
+		MFREE(osh, pool, mem_size);
+	}
+}
+
+dll_pool_t *
+dll_pool_init(void * osh, uint16 elems_max, uint16 elem_size)
+{
+	uint32 mem_size, i;
+	dll_pool_t * dll_pool_p;
+	dll_t * elem_p;
+
+	ASSERT(elem_size > sizeof(dll_t));
+
+	mem_size = (uint32)sizeof(dll_pool_t) + ((uint32)elems_max * (uint32)elem_size);
+
+	if ((dll_pool_p = (dll_pool_t *)MALLOCZ(osh, mem_size)) == NULL) {
+		ASSERT(0);
+		return dll_pool_p;
+	}
+
+	dll_init(&dll_pool_p->free_list);
+	dll_pool_p->elems_max = elems_max;
+	dll_pool_p->elem_size = elem_size;
+
+	elem_p = dll_pool_p->elements;
+	for (i = 0; i < elems_max; i++) {
+		dll_append(&dll_pool_p->free_list, elem_p);
+		elem_p = (dll_t *)((uintptr)elem_p + elem_size);
+	}
+
+	dll_pool_p->free_count = elems_max;
+
+	return dll_pool_p;
+}
+
+void *
+dll_pool_alloc(dll_pool_t * dll_pool_p)
+{
+	dll_t * elem_p;
+
+	if (dll_pool_p->free_count == 0) {
+		ASSERT(dll_empty(&dll_pool_p->free_list));
+		return NULL;
+	}
+
+	elem_p = dll_head_p(&dll_pool_p->free_list);
+	dll_delete(elem_p);
+	dll_pool_p->free_count -= 1;
+
+	return (void *)elem_p;
+}
+
+void
+BCMPOSTTRAPFN(dll_pool_free)(dll_pool_t * dll_pool_p, void * elem_p)
+{
+	dll_t * node_p = (dll_t *)elem_p;
+	dll_prepend(&dll_pool_p->free_list, node_p);
+	dll_pool_p->free_count += 1;
+}
+
+void
+dll_pool_free_tail(dll_pool_t * dll_pool_p, void * elem_p)
+{
+	dll_t * node_p = (dll_t *)elem_p;
+	dll_append(&dll_pool_p->free_list, node_p);
+	dll_pool_p->free_count += 1;
+}
+
+#ifdef BCMDBG
+void
+dll_pool_dump(dll_pool_t * dll_pool_p, dll_elem_dump elem_dump)
+{
+	dll_t * elem_p;
+	dll_t * next_p;
+	printf("dll_pool<%p> free_count<%u> elems_max<%u> elem_size<%u>\n",
+		OSL_OBFUSCATE_BUF(dll_pool_p), dll_pool_p->free_count,
+		dll_pool_p->elems_max, dll_pool_p->elem_size);
+
+	for (elem_p = dll_head_p(&dll_pool_p->free_list);
+		 !dll_end(&dll_pool_p->free_list, elem_p); elem_p = next_p) {
+
+		next_p = dll_next_p(elem_p);
+		printf("\telem<%p>\n", OSL_OBFUSCATE_BUF(elem_p));
+		if (elem_dump != NULL)
+			elem_dump((void *)elem_p);
+	}
+}
+#endif /* BCMDBG */
+
+#endif /* BCMDRIVER */
+
+#if defined(BCMDRIVER) || defined(WL_UNITTEST)
+
+#ifndef DONGLEBUILD
+/* triggers bcm_bprintf to print to kernel log */
+bool bcm_bprintf_bypass = FALSE;
+#endif /* !DONGLEBUILD */
+
+#if !(defined(_WIN32) || defined(NDIS))
+/* TODO: add vprintf to ndis OSL and remove this conditional */
+#define BCM_BPRINTF_ALLOW_NULL_B
+#endif
+
+/* Initialization of bcmstrbuf structure */
+void
+BCMPOSTTRAPFN(bcm_binit)(struct bcmstrbuf *b, char *buf, uint size)
+{
+#ifdef BCM_BPRINTF_ALLOW_NULL_B
+	/* pass NULL to struct bcmstrbuf *b to indicate the output is console */
+	if (b == NULL) {
+		return;
+	}
+#endif /* BCM_BPRINTF_ALLOW_NULL_B */
+
+	b->origsize = b->size = size;
+	b->origbuf = b->buf = buf;
+	if (size > 0) {
+		buf[0] = '\0';
+	}
+}
+
+/* Buffer sprintf wrapper to guard against buffer overflow */
+int
+BCMPOSTTRAPFN(bcm_bprintf)(struct bcmstrbuf *b, const char *fmt, ...)
+{
+	va_list ap;
+	int r;
+
+	va_start(ap, fmt);
+
+#ifdef BCM_BPRINTF_ALLOW_NULL_B
+	/* pass NULL to struct bcmstrbuf *b to indicate the output is console */
+	if (b == NULL) {
+		r = vprintf(fmt, ap);
+		goto exit;
+	}
+#endif /* BCM_BPRINTF_ALLOW_NULL_B */
+
+	r = vsnprintf(b->buf, b->size, fmt, ap);
+
+#ifndef DONGLEBUILD
+	if (bcm_bprintf_bypass == TRUE) {
+		printf("%s", b->buf);
+		goto exit;
+	}
+#endif /* !DONGLEBUILD */
+
+	/* Non Ansi C99 compliant returns -1,
+	 * Ansi compliant return r >= b->size,
+	 * bcmstdlib returns 0, handle all
+	 */
+	/* r == 0 is also the case when strlen(fmt) is zero.
+	 * typically the case when "" is passed as argument.
+	 */
+	if ((r == -1) || (r >= (int)b->size)) {
+		b->size = 0;
+	} else {
+		b->size -= (uint)r;
+		b->buf += r;
+	}
+
+exit:
+	va_end(ap);
+
+	return r;
+}
+
+void
+bcm_bprhex(struct bcmstrbuf *b, const char *msg, bool newline, const uint8 *buf, uint len)
+{
+	uint i;
+
+	if (msg != NULL && msg[0] != '\0')
+		bcm_bprintf(b, "%s", msg);
+	for (i = 0u; i < len; i ++)
+		bcm_bprintf(b, "%02X", buf[i]);
+	if (newline)
+		bcm_bprintf(b, "\n");
+}
+
+/* print the buffer in hex string format with the most significant byte first */
+void
+bcm_bprhex_msb(struct bcmstrbuf *b, const char *msg, bool newline,
+	const uint8 *buf, uint len)
+{
+	int i;
+
+	if (msg != NULL && msg[0] != '\0') {
+		bcm_bprintf(b, "%s", msg);
+	}
+	for (i = (int)len - 1; i >= 0; i --) {
+		bcm_bprintf(b, "%02X", buf[i]);
+	}
+	if (newline) {
+		bcm_bprintf(b, "\n");
+	}
+}
+
+void
+bcm_inc_bytes(uchar *num, int num_bytes, uint8 amount)
+{
+	int i;
+
+	for (i = 0; i < num_bytes; i++) {
+		num[i] += amount;
+		if (num[i] >= amount)
+			break;
+		amount = 1;
+	}
+}
+
+int
+bcm_cmp_bytes(const uchar *arg1, const uchar *arg2, uint8 nbytes)
+{
+	int i;
+
+	for (i = nbytes - 1; i >= 0; i--) {
+		if (arg1[i] != arg2[i])
+			return (arg1[i] - arg2[i]);
+	}
+	return 0;
+}
+
+void
+bcm_print_bytes(const char *name, const uchar *data, uint len)
+{
+	uint i;
+	int per_line = 0;
+
+	printf("%s: %d \n", name ? name : "", len);
+	for (i = 0u; i < len; i++) {
+		printf("%02x ", *data++);
+		per_line++;
+		if (per_line == 16) {
+			per_line = 0;
+			printf("\n");
+		}
+	}
+	printf("\n");
+}
+
+/* Search for an IE having a specific tag and an OUI type from a buffer.
+ * tlvs: buffer to search for IE
+ * tlvs_len: buffer length
+ * tag: IE tag
+ * oui: Specific OUI to match
+ * oui_len: length of the OUI
+ * type: OUI type
+ * Return the matched IE, else return null.
+*/
+bcm_tlv_t *
+bcm_find_ie(const uint8* tlvs, uint tlvs_len, uint8 tag, uint8 oui_len,
+	const char *oui, uint8 type)
+{
+	const bcm_tlv_t *ie;
+
+	COV_TAINTED_DATA_SINK(tlvs_len);
+	COV_NEG_SINK(tlvs_len);
+
+	/* Walk through the IEs looking for an OUI match */
+	while ((ie = bcm_parse_tlvs_advance(&tlvs, &tlvs_len, tag,
+		BCM_TLV_ADVANCE_TO))) {
+		if ((ie->len > oui_len) &&
+		    !bcmp(ie->data, oui, oui_len) &&
+			ie->data[oui_len] == type) {
+
+			COV_TAINTED_DATA_ARG(ie);
+
+			GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+			return (bcm_tlv_t *)(ie);		/* a match */
+			GCC_DIAGNOSTIC_POP();
+		}
+		/* Point to the next IE */
+		bcm_tlv_buffer_advance_past(ie, &tlvs, &tlvs_len);
+	}
+
+	return NULL;
+}
+
+/* Look for vendor-specific IE with specified OUI and optional type */
+bcm_tlv_t *
+bcm_find_vendor_ie(const  void *tlvs, uint tlvs_len, const char *voui, uint8 *type, uint type_len)
+{
+	const  bcm_tlv_t *ie;
+	uint8 ie_len;
+
+	COV_TAINTED_DATA_SINK(tlvs_len);
+	COV_NEG_SINK(tlvs_len);
+
+	ie = (const  bcm_tlv_t*)tlvs;
+
+	/* make sure we are looking at a valid IE */
+	if (ie == NULL || !bcm_valid_tlv(ie, tlvs_len)) {
+		return NULL;
+	}
+
+	/* Walk through the IEs looking for an OUI match */
+	do {
+		ie_len = ie->len;
+		if ((ie->id == DOT11_MNG_VS_ID) &&
+		    (ie_len >= (DOT11_OUI_LEN + type_len)) &&
+		    !bcmp(ie->data, voui, DOT11_OUI_LEN))
+		{
+			/* compare optional type */
+			if (type_len == 0 ||
+			    !bcmp(((const char *)ie->data) + DOT11_OUI_LEN, type, type_len)) {
+
+				COV_TAINTED_DATA_ARG(ie);
+
+				GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+				return (bcm_tlv_t *)(ie);		/* a match */
+				GCC_DIAGNOSTIC_POP();
+			}
+		}
+	} while ((ie = bcm_next_tlv(ie, &tlvs_len)) != NULL);
+
+	return NULL;
+}
+
+#if defined(WLTINYDUMP) || defined(BCMDBG) || defined(WLMSG_INFORM) || \
+	defined(WLMSG_ASSOC) || defined(WLMSG_PRPKT) || defined(WLMSG_WSEC)
+#define SSID_FMT_BUF_LEN	((4 * DOT11_MAX_SSID_LEN) + 1)
+
+int
+bcm_format_ssid(char* buf, const uchar ssid[], uint ssid_len)
+{
+	uint i, c;
+	char *p = buf;
+	char *endp = buf + SSID_FMT_BUF_LEN;
+
+	if (ssid_len > DOT11_MAX_SSID_LEN) ssid_len = DOT11_MAX_SSID_LEN;
+
+	for (i = 0; i < ssid_len; i++) {
+		c = (uint)ssid[i];
+		if (c == '\\') {
+			*p++ = '\\';
+			*p++ = '\\';
+		} else if (bcm_isprint((uchar)c)) {
+			*p++ = (char)c;
+		} else {
+			p += snprintf(p, (size_t)(endp - p), "\\x%02X", c);
+		}
+	}
+	*p = '\0';
+	ASSERT(p < endp);
+
+	return (int)(p - buf);
+}
+#endif /* WLTINYDUMP || BCMDBG || WLMSG_INFORM || WLMSG_ASSOC || WLMSG_PRPKT */
+
+#endif /* BCMDRIVER || WL_UNITTEST */
+
+/* Masking few bytes of MAC address per customer in all prints/eventlogs. */
+int
+BCMRAMFN(bcm_addrmask_set)(int enable)
+{
+#ifdef PRIVACY_MASK
+	struct ether_addr *privacy = privacy_addrmask_get();
+	if (enable) {
+		/* apply mask as (For SS)
+		 * orig		: 12:34:56:78:90:ab
+		 * masked	: 12:xx:xx:xx:x0:ab
+		 */
+		privacy->octet[1] = privacy->octet[2] =
+			privacy->octet[3] = 0;
+		privacy->octet[0] = privacy->octet[5] = 0xff;
+		privacy->octet[4] = 0x0f;
+	} else
+	{
+		/* No masking. All are 0xff. */
+		memcpy(privacy, &ether_bcast, sizeof(struct ether_addr));
+	}
+
+	return BCME_OK;
+#else
+	BCM_REFERENCE(enable);
+	return BCME_UNSUPPORTED;
+#endif /* PRIVACY_MASK */
+
+}
+
+int
+bcm_addrmask_get(int *val)
+{
+#ifdef PRIVACY_MASK
+	struct ether_addr *privacy = privacy_addrmask_get();
+	if (!eacmp(&ether_bcast, privacy)) {
+		*val = FALSE;
+	} else {
+		*val = TRUE;
+	}
+
+	return BCME_OK;
+#else
+	BCM_REFERENCE(val);
+	return BCME_UNSUPPORTED;
+#endif
+}
+
+uint64
+BCMRAMFN(bcm_ether_ntou64)(const struct ether_addr *ea)
+{
+	uint64 mac;
+	struct ether_addr addr;
+
+	memcpy(&addr, ea, sizeof(struct ether_addr));
+
+#ifdef PRIVACY_MASK
+	struct ether_addr *privacy = privacy_addrmask_get();
+	if (!ETHER_ISMULTI(ea)) {
+		*(uint32*)(&addr.octet[0]) &= *((uint32*)&privacy->octet[0]);
+		*(uint16*)(&addr.octet[4]) &= *((uint16*)&privacy->octet[4]);
+	}
+#endif /*  PRIVACY_MASK */
+
+	mac = ((uint64)HTON16(*((const uint16*)&addr.octet[4]))) << 32 |
+		HTON32(*((const uint32*)&addr.octet[0]));
+	return (mac);
+}
+
+char *
+bcm_ether_ntoa(const struct ether_addr *ea, char *buf)
+{
+	static const char hex[] =
+	  {
+		  '0', '1', '2', '3', '4', '5', '6', '7',
+		  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+	  };
+	const uint8 *octet = ea->octet;
+	char *p = buf;
+	int i;
+
+	for (i = 0; i < 6; i++, octet++) {
+		*p++ = hex[(*octet >> 4) & 0xf];
+		*p++ = hex[*octet & 0xf];
+		*p++ = ':';
+	}
+
+	*(p-1) = '\0';
+
+	return (buf);
+}
+
+/* Find the position of first bit set
+ * in the given number.
+ */
+int
+bcm_find_fsb(uint32 num)
+{
+	uint8 pos = 0;
+	if (!num)
+		return pos;
+	while (!(num & 1)) {
+		num >>= 1;
+		pos++;
+	}
+	return (pos+1);
+}
+
+/* TODO: need to pass in the buffer length for validation check */
+char *
+bcm_ip_ntoa(struct ipv4_addr *ia, char *buf)
+{
+	snprintf(buf, 16, "%d.%d.%d.%d",
+	         ia->addr[0], ia->addr[1], ia->addr[2], ia->addr[3]);
+	return (buf);
+}
+
+/* TODO: need to pass in the buffer length for validation check */
+char *
+bcm_ipv6_ntoa(void *ipv6, char *buf)
+{
+	/* Implementing RFC 5952 Sections 4 + 5 */
+	/* Not thoroughly tested */
+	uint16 tmp[8];
+	uint16 *a = &tmp[0];
+	char *p = buf;
+	int i, i_max = -1, cnt = 0, cnt_max = 1;
+	uint8 *a4 = NULL;
+	memcpy((uint8 *)&tmp[0], (uint8 *)ipv6, IPV6_ADDR_LEN);
+
+	for (i = 0; i < IPV6_ADDR_LEN/2; i++) {
+		if (a[i]) {
+			if (cnt > cnt_max) {
+				cnt_max = cnt;
+				i_max = i - cnt;
+			}
+			cnt = 0;
+		} else
+			cnt++;
+	}
+	if (cnt > cnt_max) {
+		cnt_max = cnt;
+		i_max = i - cnt;
+	}
+	if (i_max == 0 &&
+		/* IPv4-translated: ::ffff:0:a.b.c.d */
+		((cnt_max == 4 && a[4] == 0xffff && a[5] == 0) ||
+		/* IPv4-mapped: ::ffff:a.b.c.d */
+		(cnt_max == 5 && a[5] == 0xffff)))
+		a4 = (uint8*) (a + 6);
+
+	for (i = 0; i < IPV6_ADDR_LEN/2; i++) {
+		if ((uint8*) (a + i) == a4) {
+			snprintf(p, 17, ":%u.%u.%u.%u", a4[0], a4[1], a4[2], a4[3]);
+			break;
+		} else if (i == i_max) {
+			*p++ = ':';
+			i += cnt_max - 1;
+			p[0] = ':';
+			p[1] = '\0';
+		} else {
+			if (i)
+				*p++ = ':';
+			p += snprintf(p, 8, "%x", ntoh16(a[i]));
+		}
+	}
+
+	return buf;
+}
+
+#if !defined(BCMROMOFFLOAD_EXCLUDE_BCMUTILS_FUNCS)
+const unsigned char BCMPOST_TRAP_RODATA(bcm_ctype)[256] = {
+
+	_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,			/* 0-7 */
+	_BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C,
+	_BCM_C,	/* 8-15 */
+	_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,			/* 16-23 */
+	_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,			/* 24-31 */
+	_BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,		/* 32-39 */
+	_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,			/* 40-47 */
+	_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,			/* 48-55 */
+	_BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,			/* 56-63 */
+	_BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X,
+	_BCM_U|_BCM_X, _BCM_U, /* 64-71 */
+	_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,			/* 72-79 */
+	_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,			/* 80-87 */
+	_BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,			/* 88-95 */
+	_BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X,
+	_BCM_L|_BCM_X, _BCM_L, /* 96-103 */
+	_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */
+	_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */
+	_BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		/* 128-143 */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		/* 144-159 */
+	_BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
+	_BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,	/* 160-175 */
+	_BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,
+	_BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P,	/* 176-191 */
+	_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,
+	_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U,	/* 192-207 */
+	_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U,
+	_BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L,	/* 208-223 */
+	_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,
+	_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L,	/* 224-239 */
+	_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L,
+	_BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */
+};
+
+uint64
+bcm_strtoull(const char *cp, char **endp, uint base)
+{
+	uint64 result, last_result = 0, value;
+	bool minus;
+
+	minus = FALSE;
+
+	while (bcm_isspace(*cp))
+		cp++;
+
+	if (cp[0] == '+')
+		cp++;
+	else if (cp[0] == '-') {
+		minus = TRUE;
+		cp++;
+	}
+
+	if (base == 0) {
+		if (cp[0] == '0') {
+			if ((cp[1] == 'x') || (cp[1] == 'X')) {
+				base = 16;
+				cp = &cp[2];
+			} else {
+				base = 8;
+				cp = &cp[1];
+			}
+		} else
+			base = 10;
+	} else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) {
+		cp = &cp[2];
+	}
+
+	result = 0;
+
+	while (bcm_isxdigit(*cp) &&
+	       (value = (uint64)(bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10)) < base) {
+		result = result*base + value;
+		/* Detected overflow */
+		if (result < last_result && !minus) {
+			if (endp) {
+				/* Go to the end of current number */
+				while (bcm_isxdigit(*cp)) {
+					cp++;
+				}
+				*endp = DISCARD_QUAL(cp, char);
+			}
+			return (ulong)-1;
+		}
+		last_result = result;
+		cp++;
+	}
+
+	if (minus)
+		result = (ulong)(-(long)result);
+
+	if (endp)
+		*endp = DISCARD_QUAL(cp, char);
+
+	return (result);
+}
+
+ulong
+bcm_strtoul(const char *cp, char **endp, uint base)
+{
+	return (ulong) bcm_strtoull(cp, endp, base);
+}
+
+int
+bcm_atoi(const char *s)
+{
+	return (int)bcm_strtoul(s, NULL, 10);
+}
+
+/* return pointer to location of substring 'needle' in 'haystack' */
+char *
+bcmstrstr(const char *haystack, const char *needle)
+{
+	uint len, nlen;
+	uint i;
+
+	if ((haystack == NULL) || (needle == NULL))
+		return DISCARD_QUAL(haystack, char);
+
+	nlen = (uint)strlen(needle);
+	if (strlen(haystack) < nlen) {
+		return NULL;
+	}
+	len = (uint)strlen(haystack) - nlen + 1u;
+
+	for (i = 0u; i < len; i++)
+		if (memcmp(needle, &haystack[i], nlen) == 0)
+			return DISCARD_QUAL(&haystack[i], char);
+	return (NULL);
+}
+
+char *
+bcmstrnstr(const char *s, uint s_len, const char *substr, uint substr_len)
+{
+	for (; s_len >= substr_len; s++, s_len--)
+		if (strncmp(s, substr, substr_len) == 0)
+			return DISCARD_QUAL(s, char);
+
+	return NULL;
+}
+
+char *
+bcmstrcat(char *dest, const char *src)
+{
+	char *p;
+
+	p = dest + strlen(dest);
+
+	while ((*p++ = *src++) != '\0')
+		;
+
+	return (dest);
+}
+
+char *
+bcmstrncat(char *dest, const char *src, uint size)
+{
+	char *endp;
+	char *p;
+
+	p = dest + strlen(dest);
+	endp = p + size;
+
+	while (p != endp && (*p++ = *src++) != '\0')
+		;
+
+	return (dest);
+}
+
+/****************************************************************************
+* Function:   bcmstrtok
+*
+* Purpose:
+*  Tokenizes a string. This function is conceptually similiar to ANSI C strtok(),
+*  but allows strToken() to be used by different strings or callers at the same
+*  time. Each call modifies '*string' by substituting a NULL character for the
+*  first delimiter that is encountered, and updates 'string' to point to the char
+*  after the delimiter. Leading delimiters are skipped.
+*
+* Parameters:
+*  string      (mod) Ptr to string ptr, updated by token.
+*  delimiters  (in)  Set of delimiter characters.
+*  tokdelim    (out) Character that delimits the returned token. (May
+*                    be set to NULL if token delimiter is not required).
+*
+* Returns:  Pointer to the next token found. NULL when no more tokens are found.
+*****************************************************************************
+*/
+char *
+bcmstrtok(char **string, const char *delimiters, char *tokdelim)
+{
+	unsigned char *str;
+	unsigned long map[8];
+	int count;
+	char *nextoken;
+
+	if (tokdelim != NULL) {
+		/* Prime the token delimiter */
+		*tokdelim = '\0';
+	}
+
+	/* Clear control map */
+	for (count = 0; count < 8; count++) {
+		map[count] = 0;
+	}
+
+	/* Set bits in delimiter table */
+	do {
+		map[*delimiters >> 5] |= (1UL << (*delimiters & 31));
+	}
+	while (*delimiters++);
+
+	str = (unsigned char*)*string;
+
+	/* Find beginning of token (skip over leading delimiters). Note that
+	 * there is no token iff this loop sets str to point to the terminal
+	 * null (*str == '\0')
+	 */
+	while (((map[*str >> 5] & (1UL << (*str & 31))) && *str) || (*str == ' ')) {
+		str++;
+	}
+
+	nextoken = (char*)str;
+
+	/* Find the end of the token. If it is not the end of the string,
+	 * put a null there.
+	 */
+	for (; *str; str++) {
+		if (map[*str >> 5] & (1UL << (*str & 31))) {
+			if (tokdelim != NULL) {
+				*tokdelim = *str;
+			}
+
+			*str++ = '\0';
+			break;
+		}
+	}
+
+	*string = (char*)str;
+
+	/* Determine if a token has been found. */
+	if (nextoken == (char *) str) {
+		return NULL;
+	}
+	else {
+		return nextoken;
+	}
+}
+
+#define xToLower(C) \
+	((C >= 'A' && C <= 'Z') ? (char)((int)C - (int)'A' + (int)'a') : C)
+
+/****************************************************************************
+* Function:   bcmstricmp
+*
+* Purpose:    Compare to strings case insensitively.
+*
+* Parameters: s1 (in) First string to compare.
+*             s2 (in) Second string to compare.
+*
+* Returns:    Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if
+*             t1 > t2, when ignoring case sensitivity.
+*****************************************************************************
+*/
+int
+bcmstricmp(const char *s1, const char *s2)
+{
+	char dc, sc;
+
+	while (*s2 && *s1) {
+		dc = xToLower(*s1);
+		sc = xToLower(*s2);
+		if (dc < sc) return -1;
+		if (dc > sc) return 1;
+		s1++;
+		s2++;
+	}
+
+	if (*s1 && !*s2) return 1;
+	if (!*s1 && *s2) return -1;
+	return 0;
+}
+
+/****************************************************************************
+* Function:   bcmstrnicmp
+*
+* Purpose:    Compare to strings case insensitively, upto a max of 'cnt'
+*             characters.
+*
+* Parameters: s1  (in) First string to compare.
+*             s2  (in) Second string to compare.
+*             cnt (in) Max characters to compare.
+*
+* Returns:    Return 0 if the two strings are equal, -1 if t1 < t2 and 1 if
+*             t1 > t2, when ignoring case sensitivity.
+*****************************************************************************
+*/
+int
+bcmstrnicmp(const char* s1, const char* s2, int cnt)
+{
+	char dc, sc;
+
+	while (*s2 && *s1 && cnt) {
+		dc = xToLower(*s1);
+		sc = xToLower(*s2);
+		if (dc < sc) return -1;
+		if (dc > sc) return 1;
+		s1++;
+		s2++;
+		cnt--;
+	}
+
+	if (!cnt) return 0;
+	if (*s1 && !*s2) return 1;
+	if (!*s1 && *s2) return -1;
+	return 0;
+}
+
+/* parse a xx:xx:xx:xx:xx:xx format ethernet address */
+int
+bcm_ether_atoe(const char *p, struct ether_addr *ea)
+{
+	int i = 0;
+	char *ep;
+
+	for (;;) {
+		ea->octet[i++] = (char) bcm_strtoul(p, &ep, 16);
+		p = ep;
+		if (!*p++ || i == 6)
+			break;
+	}
+
+	return (i == 6);
+}
+
+/* parse a nnn.nnn.nnn.nnn format IPV4 address */
+int
+bcm_atoipv4(const char *p, struct ipv4_addr *ip)
+{
+
+	int i = 0;
+	char *c;
+	for (;;) {
+		ip->addr[i++] = (uint8)bcm_strtoul(p, &c, 0);
+		if (*c++ != '.' || i == IPV4_ADDR_LEN)
+			break;
+		p = c;
+	}
+	return (i == IPV4_ADDR_LEN);
+}
+#endif	/* !BCMROMOFFLOAD_EXCLUDE_BCMUTILS_FUNCS */
+
+const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}};
+const struct ether_addr BCMPOST_TRAP_RODATA(ether_null) = {{0, 0, 0, 0, 0, 0}};
+const struct ether_addr ether_ipv6_mcast = {{0x33, 0x33, 0x00, 0x00, 0x00, 0x01}};
+
+int
+ether_isbcast(const void *ea)
+{
+	return (memcmp(ea, &ether_bcast, sizeof(struct ether_addr)) == 0);
+}
+
+int
+BCMPOSTTRAPFN(ether_isnulladdr)(const void *ea)
+{
+	const uint8 *ea8 = (const uint8 *)ea;
+	return !(ea8[5] || ea8[4] || ea8[3] || ea8[2] || ea8[1] || ea8[0]);
+}
+
+#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER)
+/* registry routine buffer preparation utility functions:
+ * parameter order is like strlcpy, but returns count
+ * of bytes copied. Minimum bytes copied is null char(1)/wchar(2)
+ */
+ulong
+wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen)
+{
+	ulong copyct = 1;
+	ushort i;
+
+	if (abuflen == 0)
+		return 0;
+
+	/* wbuflen is in bytes */
+	wbuflen /= sizeof(ushort);
+
+	for (i = 0; i < wbuflen; ++i) {
+		if (--abuflen == 0)
+			break;
+		*abuf++ = (char) *wbuf++;
+		++copyct;
+	}
+	*abuf = '\0';
+
+	return copyct;
+}
+#endif /* CONFIG_USBRNDIS_RETAIL || NDIS_MINIPORT_DRIVER */
+
+#ifdef BCM_OBJECT_TRACE
+
+#define BCM_OBJECT_MERGE_SAME_OBJ	0
+
+/* some place may add / remove the object to trace list for Linux: */
+/* add:    osl_alloc_skb dev_alloc_skb skb_realloc_headroom dhd_start_xmit */
+/* remove: osl_pktfree dev_kfree_skb netif_rx */
+
+#if defined(__linux__)
+#define BCM_OBJDBG_COUNT          (1024 * 100)
+static spinlock_t dbgobj_lock;
+#define	BCM_OBJDBG_LOCK_INIT()    spin_lock_init(&dbgobj_lock)
+#define	BCM_OBJDBG_LOCK_DESTROY()
+#define	BCM_OBJDBG_LOCK           spin_lock_irqsave
+#define	BCM_OBJDBG_UNLOCK         spin_unlock_irqrestore
+#else
+#define BCM_OBJDBG_COUNT          (256)
+#define BCM_OBJDBG_LOCK_INIT()
+#define	BCM_OBJDBG_LOCK_DESTROY()
+#define BCM_OBJDBG_LOCK(x, y)
+#define BCM_OBJDBG_UNLOCK(x, y)
+#endif /* else OS */
+
+#define BCM_OBJDBG_ADDTOHEAD      0
+#define BCM_OBJDBG_ADDTOTAIL      1
+
+#define BCM_OBJDBG_CALLER_LEN     32
+struct bcm_dbgobj {
+	struct bcm_dbgobj *prior;
+	struct bcm_dbgobj *next;
+	uint32 flag;
+	void   *obj;
+	uint32 obj_sn;
+	uint32 obj_state;
+	uint32 line;
+	char   caller[BCM_OBJDBG_CALLER_LEN];
+};
+
+static struct bcm_dbgobj *dbgobj_freehead = NULL;
+static struct bcm_dbgobj *dbgobj_freetail = NULL;
+static struct bcm_dbgobj *dbgobj_objhead = NULL;
+static struct bcm_dbgobj *dbgobj_objtail = NULL;
+
+static uint32 dbgobj_sn = 0;
+static int dbgobj_count = 0;
+static struct bcm_dbgobj bcm_dbg_objs[BCM_OBJDBG_COUNT];
+
+void
+bcm_object_trace_init(void)
+{
+	int i = 0;
+	BCM_OBJDBG_LOCK_INIT();
+	bzero(&bcm_dbg_objs, sizeof(struct bcm_dbgobj) * BCM_OBJDBG_COUNT);
+	dbgobj_freehead = &bcm_dbg_objs[0];
+	dbgobj_freetail = &bcm_dbg_objs[BCM_OBJDBG_COUNT - 1];
+
+	for (i = 0; i < BCM_OBJDBG_COUNT; ++i) {
+		bcm_dbg_objs[i].next = (i == (BCM_OBJDBG_COUNT - 1)) ?
+			dbgobj_freehead : &bcm_dbg_objs[i + 1];
+		bcm_dbg_objs[i].prior = (i == 0) ?
+			dbgobj_freetail : &bcm_dbg_objs[i - 1];
+	}
+}
+
+void
+bcm_object_trace_deinit(void)
+{
+	if (dbgobj_objhead || dbgobj_objtail) {
+		printf("bcm_object_trace_deinit: not all objects are released\n");
+		ASSERT(0);
+	}
+	BCM_OBJDBG_LOCK_DESTROY();
+}
+
+static void
+bcm_object_rm_list(struct bcm_dbgobj **head, struct bcm_dbgobj **tail,
+	struct bcm_dbgobj *dbgobj)
+{
+	if ((dbgobj == *head) && (dbgobj == *tail)) {
+		*head = NULL;
+		*tail = NULL;
+	} else if (dbgobj == *head) {
+		*head = (*head)->next;
+	} else if (dbgobj == *tail) {
+		*tail = (*tail)->prior;
+	}
+	dbgobj->next->prior = dbgobj->prior;
+	dbgobj->prior->next = dbgobj->next;
+}
+
+static void
+bcm_object_add_list(struct bcm_dbgobj **head, struct bcm_dbgobj **tail,
+	struct bcm_dbgobj *dbgobj, int addtotail)
+{
+	if (!(*head) && !(*tail)) {
+		*head = dbgobj;
+		*tail = dbgobj;
+		dbgobj->next = dbgobj;
+		dbgobj->prior = dbgobj;
+	} else if ((*head) && (*tail)) {
+		(*tail)->next = dbgobj;
+		(*head)->prior = dbgobj;
+		dbgobj->next = *head;
+		dbgobj->prior = *tail;
+		if (addtotail == BCM_OBJDBG_ADDTOTAIL)
+			*tail = dbgobj;
+		else
+			*head = dbgobj;
+	} else {
+		ASSERT(0); /* can't be this case */
+	}
+}
+
+static INLINE void
+bcm_object_movetoend(struct bcm_dbgobj **head, struct bcm_dbgobj **tail,
+	struct bcm_dbgobj *dbgobj, int movetotail)
+{
+	if ((*head) && (*tail)) {
+		if (movetotail == BCM_OBJDBG_ADDTOTAIL) {
+			if (dbgobj != (*tail)) {
+				bcm_object_rm_list(head, tail, dbgobj);
+				bcm_object_add_list(head, tail, dbgobj, movetotail);
+			}
+		} else {
+			if (dbgobj != (*head)) {
+				bcm_object_rm_list(head, tail, dbgobj);
+				bcm_object_add_list(head, tail, dbgobj, movetotail);
+			}
+		}
+	} else {
+		ASSERT(0); /* can't be this case */
+	}
+}
+
+void
+bcm_object_trace_opr(void *obj, uint32 opt, const char *caller, int line)
+{
+	struct bcm_dbgobj *dbgobj;
+	unsigned long flags;
+
+	BCM_REFERENCE(flags);
+	BCM_OBJDBG_LOCK(&dbgobj_lock, flags);
+
+	if (opt == BCM_OBJDBG_ADD_PKT ||
+		opt == BCM_OBJDBG_ADD) {
+		dbgobj = dbgobj_objtail;
+		while (dbgobj) {
+			if (dbgobj->obj == obj) {
+				printf("bcm_object_trace_opr: obj %p allocated from %s(%d),"
+					" allocate again from %s(%d)\n",
+					dbgobj->obj,
+					dbgobj->caller, dbgobj->line,
+					caller, line);
+				ASSERT(0);
+				goto EXIT;
+			}
+			dbgobj = dbgobj->prior;
+			if (dbgobj == dbgobj_objtail)
+				break;
+		}
+
+#if BCM_OBJECT_MERGE_SAME_OBJ
+		dbgobj = dbgobj_freetail;
+		while (dbgobj) {
+			if (dbgobj->obj == obj) {
+				goto FREED_ENTRY_FOUND;
+			}
+			dbgobj = dbgobj->prior;
+			if (dbgobj == dbgobj_freetail)
+				break;
+		}
+#endif /* BCM_OBJECT_MERGE_SAME_OBJ */
+
+		dbgobj = dbgobj_freehead;
+#if BCM_OBJECT_MERGE_SAME_OBJ
+FREED_ENTRY_FOUND:
+#endif /* BCM_OBJECT_MERGE_SAME_OBJ */
+		if (!dbgobj) {
+			printf("bcm_object_trace_opr: already got %d objects ?????????????????\n",
+				BCM_OBJDBG_COUNT);
+			ASSERT(0);
+			goto EXIT;
+		}
+
+		bcm_object_rm_list(&dbgobj_freehead, &dbgobj_freetail, dbgobj);
+		dbgobj->obj = obj;
+		strlcpy(dbgobj->caller, caller, sizeof(dbgobj->caller));
+		dbgobj->line = line;
+		dbgobj->flag = 0;
+		if (opt == BCM_OBJDBG_ADD_PKT) {
+			dbgobj->obj_sn = dbgobj_sn++;
+			dbgobj->obj_state = 0;
+			/* first 4 bytes is pkt sn */
+			if (((unsigned long)PKTTAG(obj)) & 0x3)
+				printf("pkt tag address not aligned by 4: %p\n", PKTTAG(obj));
+			*(uint32*)PKTTAG(obj) = dbgobj->obj_sn;
+		}
+		bcm_object_add_list(&dbgobj_objhead, &dbgobj_objtail, dbgobj,
+			BCM_OBJDBG_ADDTOTAIL);
+
+		dbgobj_count++;
+
+	} else if (opt == BCM_OBJDBG_REMOVE) {
+		dbgobj = dbgobj_objtail;
+		while (dbgobj) {
+			if (dbgobj->obj == obj) {
+				if (dbgobj->flag) {
+					printf("bcm_object_trace_opr: rm flagged obj %p"
+						" flag 0x%08x from %s(%d)\n",
+						obj, dbgobj->flag, caller, line);
+				}
+				bcm_object_rm_list(&dbgobj_objhead, &dbgobj_objtail, dbgobj);
+				bzero(dbgobj->caller, sizeof(dbgobj->caller));
+				strlcpy(dbgobj->caller, caller, sizeof(dbgobj->caller));
+				dbgobj->line = line;
+				bcm_object_add_list(&dbgobj_freehead, &dbgobj_freetail, dbgobj,
+					BCM_OBJDBG_ADDTOTAIL);
+				dbgobj_count--;
+				goto EXIT;
+			}
+			dbgobj = dbgobj->prior;
+			if (dbgobj == dbgobj_objtail)
+				break;
+		}
+
+		dbgobj = dbgobj_freetail;
+		while (dbgobj && dbgobj->obj) {
+			if (dbgobj->obj == obj) {
+				printf("bcm_object_trace_opr: obj %p already freed"
+					" from from %s(%d),"
+					" try free again from %s(%d)\n",
+					obj,
+					dbgobj->caller, dbgobj->line,
+					caller, line);
+				//ASSERT(0); /* release same obj more than one time? */
+				goto EXIT;
+			}
+			dbgobj = dbgobj->prior;
+			if (dbgobj == dbgobj_freetail)
+				break;
+		}
+
+		printf("bcm_object_trace_opr: ################### release none-existing"
+			" obj %p from %s(%d)\n",
+			obj, caller, line);
+		//ASSERT(0); /* release same obj more than one time? */
+
+	}
+
+EXIT:
+	BCM_OBJDBG_UNLOCK(&dbgobj_lock, flags);
+	return;
+}
+
+void
+bcm_object_trace_upd(void *obj, void *obj_new)
+{
+	struct bcm_dbgobj *dbgobj;
+	unsigned long flags;
+
+	BCM_REFERENCE(flags);
+	BCM_OBJDBG_LOCK(&dbgobj_lock, flags);
+
+	dbgobj = dbgobj_objtail;
+	while (dbgobj) {
+		if (dbgobj->obj == obj) {
+			dbgobj->obj = obj_new;
+			if (dbgobj != dbgobj_objtail) {
+				bcm_object_movetoend(&dbgobj_objhead, &dbgobj_objtail,
+					dbgobj, BCM_OBJDBG_ADDTOTAIL);
+			}
+			goto EXIT;
+		}
+		dbgobj = dbgobj->prior;
+		if (dbgobj == dbgobj_objtail)
+			break;
+	}
+
+EXIT:
+	BCM_OBJDBG_UNLOCK(&dbgobj_lock, flags);
+	return;
+}
+
+void
+bcm_object_trace_chk(void *obj, uint32 chksn, uint32 sn,
+	const char *caller, int line)
+{
+	struct bcm_dbgobj *dbgobj;
+	unsigned long flags;
+
+	BCM_REFERENCE(flags);
+	BCM_OBJDBG_LOCK(&dbgobj_lock, flags);
+
+	dbgobj = dbgobj_objtail;
+	while (dbgobj) {
+		if ((dbgobj->obj == obj) &&
+			((!chksn) || (dbgobj->obj_sn == sn))) {
+			if (dbgobj != dbgobj_objtail) {
+				bcm_object_movetoend(&dbgobj_objhead, &dbgobj_objtail,
+					dbgobj, BCM_OBJDBG_ADDTOTAIL);
+			}
+			goto EXIT;
+		}
+		dbgobj = dbgobj->prior;
+		if (dbgobj == dbgobj_objtail)
+			break;
+	}
+
+	dbgobj = dbgobj_freetail;
+	while (dbgobj) {
+		if ((dbgobj->obj == obj) &&
+			((!chksn) || (dbgobj->obj_sn == sn))) {
+			printf("bcm_object_trace_chk: (%s:%d) obj %p (sn %d state %d)"
+				" was freed from %s(%d)\n",
+				caller, line,
+				dbgobj->obj, dbgobj->obj_sn, dbgobj->obj_state,
+				dbgobj->caller, dbgobj->line);
+			goto EXIT;
+		}
+		else if (dbgobj->obj == NULL) {
+			break;
+		}
+		dbgobj = dbgobj->prior;
+		if (dbgobj == dbgobj_freetail)
+			break;
+	}
+
+	printf("bcm_object_trace_chk: obj %p not found, check from %s(%d), chksn %s, sn %d\n",
+		obj, caller, line, chksn ? "yes" : "no", sn);
+	dbgobj = dbgobj_objtail;
+	while (dbgobj) {
+		printf("bcm_object_trace_chk: (%s:%d) obj %p sn %d was allocated from %s(%d)\n",
+				caller, line,
+				dbgobj->obj, dbgobj->obj_sn, dbgobj->caller, dbgobj->line);
+		dbgobj = dbgobj->prior;
+		if (dbgobj == dbgobj_objtail)
+			break;
+	}
+
+EXIT:
+	BCM_OBJDBG_UNLOCK(&dbgobj_lock, flags);
+	return;
+}
+
+void
+bcm_object_feature_set(void *obj, uint32 type, uint32 value)
+{
+	struct bcm_dbgobj *dbgobj;
+	unsigned long flags;
+
+	BCM_REFERENCE(flags);
+	BCM_OBJDBG_LOCK(&dbgobj_lock, flags);
+
+	dbgobj = dbgobj_objtail;
+	while (dbgobj) {
+		if (dbgobj->obj == obj) {
+			if (type == BCM_OBJECT_FEATURE_FLAG) {
+				if (value & BCM_OBJECT_FEATURE_CLEAR)
+					dbgobj->flag &= ~(value);
+				else
+					dbgobj->flag |= (value);
+			} else if (type == BCM_OBJECT_FEATURE_PKT_STATE) {
+				dbgobj->obj_state = value;
+			}
+			if (dbgobj != dbgobj_objtail) {
+				bcm_object_movetoend(&dbgobj_objhead, &dbgobj_objtail,
+					dbgobj, BCM_OBJDBG_ADDTOTAIL);
+			}
+			goto EXIT;
+		}
+		dbgobj = dbgobj->prior;
+		if (dbgobj == dbgobj_objtail)
+			break;
+	}
+
+	printf("bcm_object_feature_set: obj %p not found in active list\n", obj);
+	ASSERT(0);
+
+EXIT:
+	BCM_OBJDBG_UNLOCK(&dbgobj_lock, flags);
+	return;
+}
+
+int
+bcm_object_feature_get(void *obj, uint32 type, uint32 value)
+{
+	int rtn = 0;
+	struct bcm_dbgobj *dbgobj;
+	unsigned long flags;
+
+	BCM_REFERENCE(flags);
+	BCM_OBJDBG_LOCK(&dbgobj_lock, flags);
+
+	dbgobj = dbgobj_objtail;
+	while (dbgobj) {
+		if (dbgobj->obj == obj) {
+			if (type == BCM_OBJECT_FEATURE_FLAG) {
+				rtn = (dbgobj->flag & value) & (~BCM_OBJECT_FEATURE_CLEAR);
+			}
+			if (dbgobj != dbgobj_objtail) {
+				bcm_object_movetoend(&dbgobj_objhead, &dbgobj_objtail,
+					dbgobj, BCM_OBJDBG_ADDTOTAIL);
+			}
+			goto EXIT;
+		}
+		dbgobj = dbgobj->prior;
+		if (dbgobj == dbgobj_objtail)
+			break;
+	}
+
+	printf("bcm_object_feature_get: obj %p not found in active list\n", obj);
+	ASSERT(0);
+
+EXIT:
+	BCM_OBJDBG_UNLOCK(&dbgobj_lock, flags);
+	return rtn;
+}
+
+#endif /* BCM_OBJECT_TRACE */
+
+uint8 *
+BCMPOSTTRAPFN(bcm_write_tlv)(int type, const void *data, uint datalen, uint8 *dst)
+{
+	uint8 *new_dst = dst;
+	bcm_tlv_t *dst_tlv = (bcm_tlv_t *)dst;
+
+	/* dst buffer should always be valid */
+	ASSERT(dst);
+
+	/* data len must be within valid range */
+	ASSERT((datalen <= BCM_TLV_MAX_DATA_SIZE));
+
+	/* source data buffer pointer should be valid, unless datalen is 0
+	 * meaning no data with this TLV
+	 */
+	ASSERT((data != NULL) || (datalen == 0));
+
+	/* only do work if the inputs are valid
+	 * - must have a dst to write to AND
+	 * - datalen must be within range AND
+	 * - the source data pointer must be non-NULL if datalen is non-zero
+	 * (this last condition detects datalen > 0 with a NULL data pointer)
+	 */
+	if ((dst != NULL) &&
+	    ((datalen <= BCM_TLV_MAX_DATA_SIZE)) &&
+	    ((data != NULL) || (datalen == 0u))) {
+
+		/* write type, len fields */
+		dst_tlv->id = (uint8)type;
+		dst_tlv->len = (uint8)datalen;
+
+		/* if data is present, copy to the output buffer and update
+		 * pointer to output buffer
+		 */
+		if (datalen > 0u) {
+
+			memcpy(dst_tlv->data, data, datalen);
+		}
+
+		/* update the output destination poitner to point past
+		 * the TLV written
+		 */
+		new_dst = dst + BCM_TLV_HDR_SIZE + datalen;
+	}
+
+	return (new_dst);
+}
+
+uint8 *
+bcm_write_tlv_ext(uint8 type, uint8 ext, const void *data, uint8 datalen, uint8 *dst)
+{
+	uint8 *new_dst = dst;
+	bcm_tlv_ext_t *dst_tlv = (bcm_tlv_ext_t *)dst;
+
+	/* dst buffer should always be valid */
+	ASSERT(dst);
+
+	/* data len must be within valid range */
+	ASSERT(datalen <= BCM_TLV_EXT_MAX_DATA_SIZE);
+
+	/* source data buffer pointer should be valid, unless datalen is 0
+	 * meaning no data with this TLV
+	 */
+	ASSERT((data != NULL) || (datalen == 0));
+
+	/* only do work if the inputs are valid
+	 * - must have a dst to write to AND
+	 * - datalen must be within range AND
+	 * - the source data pointer must be non-NULL if datalen is non-zero
+	 * (this last condition detects datalen > 0 with a NULL data pointer)
+	 */
+	if ((dst != NULL) &&
+	    (datalen <= BCM_TLV_EXT_MAX_DATA_SIZE) &&
+	    ((data != NULL) || (datalen == 0))) {
+
+		/* write type, len fields */
+		dst_tlv->id = (uint8)type;
+		dst_tlv->ext = ext;
+		dst_tlv->len = 1 + (uint8)datalen;
+
+		/* if data is present, copy to the output buffer and update
+		 * pointer to output buffer
+		 */
+		if (datalen > 0) {
+			memcpy(dst_tlv->data, data, datalen);
+		}
+
+		/* update the output destination poitner to point past
+		 * the TLV written
+		 */
+		new_dst = dst + BCM_TLV_EXT_HDR_SIZE + datalen;
+	}
+
+	return (new_dst);
+}
+
+uint8 *
+BCMPOSTTRAPFN(bcm_write_tlv_safe)(int type, const void *data, uint datalen, uint8 *dst,
+	uint dst_maxlen)
+{
+	uint8 *new_dst = dst;
+
+	if ((datalen <= BCM_TLV_MAX_DATA_SIZE)) {
+
+		/* if len + tlv hdr len is more than destlen, don't do anything
+		 * just return the buffer untouched
+		 */
+		if ((datalen + BCM_TLV_HDR_SIZE) <= dst_maxlen) {
+
+			new_dst = bcm_write_tlv(type, data, datalen, dst);
+		}
+	}
+
+	return (new_dst);
+}
+
+uint8 *
+bcm_copy_tlv(const void *src, uint8 *dst)
+{
+	uint8 *new_dst = dst;
+	const bcm_tlv_t *src_tlv = (const bcm_tlv_t *)src;
+	uint totlen;
+
+	ASSERT(dst && src);
+	if (dst && src) {
+
+		totlen = BCM_TLV_HDR_SIZE + src_tlv->len;
+		memcpy(dst, src_tlv, totlen);
+		new_dst = dst + totlen;
+	}
+
+	return (new_dst);
+}
+
+uint8 *
+bcm_copy_tlv_safe(const void *src, uint8 *dst, uint dst_maxlen)
+{
+	uint8 *new_dst = dst;
+	const bcm_tlv_t *src_tlv = (const bcm_tlv_t *)src;
+
+	ASSERT(src);
+	if (bcm_valid_tlv(src_tlv, dst_maxlen)) {
+		new_dst = bcm_copy_tlv(src, dst);
+	}
+
+	return (new_dst);
+}
+
+#if !defined(BCMROMOFFLOAD_EXCLUDE_BCMUTILS_FUNCS)
+/*******************************************************************************
+ * crc8
+ *
+ * Computes a crc8 over the input data using the polynomial:
+ *
+ *       x^8 + x^7 +x^6 + x^4 + x^2 + 1
+ *
+ * The caller provides the initial value (either CRC8_INIT_VALUE
+ * or the previous returned value) to allow for processing of
+ * discontiguous blocks of data.  When generating the CRC the
+ * caller is responsible for complementing the final return value
+ * and inserting it into the byte stream.  When checking, a final
+ * return value of CRC8_GOOD_VALUE indicates a valid CRC.
+ *
+ * Reference: Dallas Semiconductor Application Note 27
+ *   Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
+ *     ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
+ *     ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
+ *
+ * ****************************************************************************
+ */
+
+static const uint8 crc8_table[256] = {
+    0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
+    0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
+    0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
+    0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
+    0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
+    0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
+    0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
+    0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
+    0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
+    0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
+    0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
+    0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
+    0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
+    0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
+    0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
+    0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
+    0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
+    0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
+    0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
+    0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
+    0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
+    0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
+    0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
+    0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
+    0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
+    0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
+    0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
+    0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
+    0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
+    0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
+    0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
+    0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
+};
+
+#define CRC_INNER_LOOP(n, c, x) \
+	(c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff]
+
+uint8
+hndcrc8(
+	const uint8 *pdata,	/* pointer to array of data to process */
+	uint  nbytes,	/* number of input data bytes to process */
+	uint8 crc	/* either CRC8_INIT_VALUE or previous return value */
+)
+{
+	/* hard code the crc loop instead of using CRC_INNER_LOOP macro
+	 * to avoid the undefined and unnecessary (uint8 >> 8) operation.
+	 */
+	while (nbytes-- > 0)
+		crc = crc8_table[(crc ^ *pdata++) & 0xff];
+
+	return crc;
+}
+
+/*******************************************************************************
+ * crc16
+ *
+ * Computes a crc16 over the input data using the polynomial:
+ *
+ *       x^16 + x^12 +x^5 + 1
+ *
+ * The caller provides the initial value (either CRC16_INIT_VALUE
+ * or the previous returned value) to allow for processing of
+ * discontiguous blocks of data.  When generating the CRC the
+ * caller is responsible for complementing the final return value
+ * and inserting it into the byte stream.  When checking, a final
+ * return value of CRC16_GOOD_VALUE indicates a valid CRC.
+ *
+ * Reference: Dallas Semiconductor Application Note 27
+ *   Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
+ *     ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
+ *     ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
+ *
+ * ****************************************************************************
+ */
+
+static const uint16 crc16_table[256] = {
+    0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
+    0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
+    0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
+    0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
+    0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
+    0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
+    0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
+    0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
+    0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
+    0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
+    0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
+    0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
+    0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
+    0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
+    0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
+    0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
+    0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
+    0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
+    0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
+    0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
+    0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
+    0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
+    0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
+    0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
+    0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
+    0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
+    0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
+    0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
+    0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
+    0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
+    0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
+    0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
+};
+
+uint16
+hndcrc16(
+    const uint8 *pdata,  /* pointer to array of data to process */
+    uint nbytes, /* number of input data bytes to process */
+    uint16 crc     /* either CRC16_INIT_VALUE or previous return value */
+)
+{
+	while (nbytes-- > 0)
+		CRC_INNER_LOOP(16, crc, *pdata++);
+	return crc;
+}
+
+static const uint32 BCMPOST_TRAP_RODATA(crc32_table)[256] = {
+    0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
+    0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+    0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+    0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+    0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
+    0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+    0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
+    0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+    0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+    0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+    0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
+    0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+    0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
+    0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+    0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+    0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+    0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
+    0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+    0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
+    0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+    0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+    0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+    0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
+    0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+    0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
+    0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+    0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+    0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+    0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
+    0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+    0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
+    0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+    0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+    0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+    0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+    0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+    0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
+    0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+    0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+    0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+    0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
+    0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+    0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
+    0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+    0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+    0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+    0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
+    0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+    0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
+    0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+    0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+    0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+    0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
+    0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+    0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
+    0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+    0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+    0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+    0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
+    0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+    0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
+    0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+    0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+    0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+};
+
+/*
+ * crc input is CRC32_INIT_VALUE for a fresh start, or previous return value if
+ * accumulating over multiple pieces.
+ */
+uint32
+BCMPOSTTRAPRAMFN(hndcrc32)(const uint8 *pdata, uint nbytes, uint32 crc)
+{
+	const uint8 *pend;
+	pend = pdata + nbytes;
+	while (pdata < pend)
+		CRC_INNER_LOOP(32, crc, *pdata++);
+
+	return crc;
+}
+
+/*
+ * Advance from the current 1-byte tag/1-byte length/variable-length value
+ * triple, to the next, returning a pointer to the next.
+ * If the current or next TLV is invalid (does not fit in given buffer length),
+ * NULL is returned.
+ * *buflen is not modified if the TLV elt parameter is invalid, or is decremented
+ * by the TLV parameter's length if it is valid.
+ */
+bcm_tlv_t *
+bcm_next_tlv(const bcm_tlv_t *elt, uint *buflen)
+{
+	uint len;
+
+	COV_TAINTED_DATA_SINK(buflen);
+	COV_NEG_SINK(buflen);
+
+	/* validate current elt */
+	if (!bcm_valid_tlv(elt, *buflen)) {
+		return NULL;
+	}
+
+	/* advance to next elt */
+	len = TLV_HDR_LEN + elt->len;
+	elt = (const  bcm_tlv_t*)((const uint8 *)elt + len);
+
+#if defined(__COVERITY__)
+	/* The 'len' value is tainted in Coverity because it is read from the tainted data pointed
+	 * to by 'elt'.  However, bcm_valid_tlv() verifies that the elt pointer is a valid element,
+	 * so its length, len = (TLV_HDR_LEN + elt->len), is in the bounds of the buffer.
+	 * Clearing the tainted attribute of 'len' for Coverity.
+	 */
+	__coverity_tainted_data_sanitize__(len);
+	if (len > *buflen) {
+		return NULL;
+	}
+#endif /* __COVERITY__ */
+
+	*buflen -= len;
+
+	/* validate next elt */
+	if (!bcm_valid_tlv(elt, *buflen)) {
+		return NULL;
+	}
+
+	COV_TAINTED_DATA_ARG(elt);
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	return (bcm_tlv_t *)(elt);
+	GCC_DIAGNOSTIC_POP();
+}
+
+/**
+ * Advance a const tlv buffer pointer and length up to the given tlv element pointer
+ * 'elt'.  The function checks that elt is a valid tlv; the elt pointer and data
+ * are all in the range of the buffer/length.
+ *
+ * @param elt      pointer to a valid bcm_tlv_t in the buffer
+ * @param buffer   pointer to a tlv buffer
+ * @param buflen   length of the buffer in bytes
+ *
+ * On return, if elt is not a tlv in the buffer bounds, the *buffer parameter
+ * will be set to NULL and *buflen parameter will be set to zero.  Otherwise,
+ * *buffer will point to elt, and *buflen will have been adjusted by the the
+ * difference between *buffer and elt.
+ */
+void
+bcm_tlv_buffer_advance_to(const bcm_tlv_t *elt, const uint8 **buffer, uint *buflen)
+{
+	uint new_buflen;
+	const uint8 *new_buffer;
+
+	/* model the input length value as a tainted and negative sink so
+	 * Coverity will complain about unvalidated or possibly length values
+	 */
+	COV_TAINTED_DATA_SINK(*buflen);
+	COV_NEG_SINK(*buflen);
+
+	new_buffer = (const uint8*)elt;
+
+	/* make sure the input buffer pointer is non-null, that (buffer + buflen) does not wrap,
+	 * and that the elt pointer is in the range of [buffer, buffer + buflen]
+	 */
+	if ((*buffer != NULL) &&
+	    ((uintptr)*buffer < ((uintptr)*buffer + *buflen)) &&
+	    (new_buffer >= *buffer) &&
+	    (new_buffer < (*buffer + *buflen))) {
+		/* delta between buffer and new_buffer is <= *buflen, so truncating cast to uint
+		 * from ptrdiff is ok
+		 */
+		uint delta = (uint)(new_buffer - *buffer);
+
+		/* New buffer length is old len minus the delta from the buffer start to elt.
+		 * The check just above guarantees that the subtractions does not underflow.
+		 */
+		new_buflen = *buflen - delta;
+
+		/* validate current elt */
+		if (bcm_valid_tlv(elt, new_buflen)) {
+			/* All good, so update the input/output parameters */
+			*buffer = new_buffer;
+			*buflen = new_buflen;
+			return;
+		}
+	}
+
+	/* something did not check out, clear out the buffer info */
+	*buffer = NULL;
+	*buflen = 0;
+
+	return;
+}
+
+/**
+ * Advance a const tlv buffer pointer and length past the given tlv element pointer
+ * 'elt'.  The function checks that elt is a valid tlv; the elt pointer and data
+ * are all in the range of the buffer/length.  The function also checks that the
+ * remaining buffer starts with a valid tlv.
+ *
+ * @param elt      pointer to a valid bcm_tlv_t in the buffer
+ * @param buffer   pointer to a tlv buffer
+ * @param buflen   length of the buffer in bytes
+ *
+ * On return, if elt is not a tlv in the buffer bounds, or the remaining buffer
+ * following the elt does not begin with a tlv in the buffer bounds, the *buffer
+ * parameter will be set to NULL and *buflen parameter will be set to zero.
+ * Otherwise, *buffer will point to the first byte past elt, and *buflen will
+ * have the remaining buffer length.
+ */
+void
+bcm_tlv_buffer_advance_past(const bcm_tlv_t *elt, const uint8 **buffer, uint *buflen)
+{
+	/* Start by advancing the buffer up to the given elt */
+	bcm_tlv_buffer_advance_to(elt, buffer, buflen);
+
+	/* if that did not work, bail out */
+	if (*buflen == 0) {
+		return;
+	}
+
+#if defined(__COVERITY__)
+	/* The elt has been verified by bcm_tlv_buffer_advance_to() to be a valid element,
+	 * so its elt->len is in the bounds of the buffer. The following check prevents
+	 * Coverity from flagging the (elt->data + elt->len) statement below as using a
+	 * tainted elt->len to index into array 'elt->data'.
+	 */
+	if (elt->len > *buflen) {
+		return;
+	}
+#endif /* __COVERITY__ */
+
+	/* We know we are advanced up to a good tlv.
+	 * Now just advance to the following tlv.
+	 */
+	elt = (const bcm_tlv_t*)(elt->data + elt->len);
+
+	bcm_tlv_buffer_advance_to(elt, buffer, buflen);
+
+	return;
+}
+
+/*
+ * Traverse a string of 1-byte tag/1-byte length/variable-length value
+ * triples, returning a pointer to the substring whose first element
+ * matches tag
+ */
+bcm_tlv_t *
+bcm_parse_tlvs(const void *buf, uint buflen, uint key)
+{
+	const bcm_tlv_t *elt;
+	uint totlen;
+
+	COV_TAINTED_DATA_SINK(buflen);
+	COV_NEG_SINK(buflen);
+
+	if ((elt = (const bcm_tlv_t*)buf) == NULL) {
+		return NULL;
+	}
+	totlen = buflen;
+
+	/* find tagged parameter */
+	while (totlen >= TLV_HDR_LEN) {
+		uint len = elt->len;
+
+		/* check if elt overruns buffer */
+		if (totlen < (len + TLV_HDR_LEN)) {
+			break;
+		}
+		/* did we find the ID? */
+		if ((elt->id == key) ||
+		    (elt->id == DOT11_MNG_ID_EXT_ID && len > 0 &&
+		     elt->data[0] + (uint)DOT11_MNG_ID_EXT_ID == key)) {
+			COV_TAINTED_DATA_ARG(elt);
+
+			GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+			return (bcm_tlv_t *)(elt);
+			GCC_DIAGNOSTIC_POP();
+		}
+		elt = (const bcm_tlv_t*)((const uint8*)elt + (len + TLV_HDR_LEN));
+		totlen -= (len + TLV_HDR_LEN);
+	}
+
+	return NULL;
+}
+
+/*
+ * Traverse a string of 1-byte tag/1-byte length/variable-length value
+ * triples, returning a pointer to the substring whose first element
+ * matches tag.
+ * The 'advance' parmeter specifies what to do to the parse buf/buflen values if a
+ * matching tlv is found:
+ *	BCM_TLV_ADVANCE_NONE - do nothing
+ *	BCM_TLV_ADVANCE_TO - move the buf up to the discovered tlv, and adjust buflen.
+ *	BCM_TLV_ADVANCE_PAST - move the buf past the discovered tlb, and adjust buflen.
+ * If a tlv is not found, no changes are made to buf/buflen
+ *
+ */
+const bcm_tlv_t *
+bcm_parse_tlvs_advance(const uint8 **buf, uint *buflen, uint key, bcm_tlv_advance_mode_t advance)
+{
+	const bcm_tlv_t *elt;
+
+	elt = bcm_parse_tlvs(*buf, *buflen, key);
+
+	if (elt == NULL) {
+		return elt;
+	}
+
+	if (advance == BCM_TLV_ADVANCE_TO) {
+		bcm_tlv_buffer_advance_to(elt, buf, buflen);
+	} else if (advance == BCM_TLV_ADVANCE_PAST) {
+		bcm_tlv_buffer_advance_past(elt, buf, buflen);
+	} else if (advance == BCM_TLV_ADVANCE_NONE) {
+		/* nothing to do */
+	} else {
+		/* there are only 3 modes, but just in case, zero the parse buffer pointer and
+		 * length to prevent infinite loops in callers that expect progress.
+		 */
+		ASSERT(0);
+		*buf = NULL;
+		*buflen = 0;
+	}
+
+	return elt;
+}
+
+bcm_tlv_t *
+bcm_parse_tlvs_dot11(const void *buf, uint buflen, uint key, bool id_ext)
+{
+	bcm_tlv_t *elt;
+	uint totlen;
+
+	COV_TAINTED_DATA_SINK(buflen);
+	COV_NEG_SINK(buflen);
+
+	/*
+	   ideally, we don't want to do that, but returning a const pointer
+	   from these parse function spreads casting everywhere in the code
+	*/
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	elt = (bcm_tlv_t*)buf;
+	GCC_DIAGNOSTIC_POP();
+
+	totlen = buflen;
+
+	/* find tagged parameter */
+	while (totlen >= TLV_HDR_LEN) {
+		uint len = elt->len;
+
+		/* validate remaining totlen */
+		if (totlen < (len + TLV_HDR_LEN)) {
+			break;
+		}
+
+		do {
+			if (id_ext) {
+				if (!DOT11_MNG_IE_ID_EXT_MATCH(elt, key))
+					break;
+			} else if (elt->id != key) {
+				break;
+			}
+
+			COV_TAINTED_DATA_ARG(elt);
+
+			return (bcm_tlv_t *)(elt);		/* a match */
+		} while (0);
+
+		elt = (bcm_tlv_t*)((uint8*)elt + (len + TLV_HDR_LEN));
+		totlen -= (len + TLV_HDR_LEN);
+	}
+
+	return NULL;
+}
+
+/*
+ * Traverse a string of 1-byte tag/1-byte length/variable-length value
+ * triples, returning a pointer to the substring whose first element
+ * matches tag
+ * return NULL if not found or length field < min_varlen
+ */
+bcm_tlv_t *
+bcm_parse_tlvs_min_bodylen(const  void *buf, uint buflen, uint key, uint min_bodylen)
+{
+	bcm_tlv_t * ret;
+	ret = bcm_parse_tlvs(buf, buflen, key);
+	if (ret == NULL || ret->len < min_bodylen) {
+		return NULL;
+	}
+	return ret;
+}
+
+/*
+ * Traverse a string of 1-byte tag/1-byte length/variable-length value
+ * triples, returning a pointer to the substring whose first element
+ * matches tag
+ * return NULL if not found or tlv size > max_len or < min_len
+ */
+bcm_tlv_t *
+bcm_parse_tlvs_minmax_len(const  void *buf, uint buflen, uint key,
+	uint min_len, uint max_len)
+{
+	bcm_tlv_t * ret;
+	ret = bcm_parse_tlvs(buf, buflen, key);
+	if (ret == NULL ||
+		(BCM_TLV_SIZE(ret) > max_len) ||
+		(BCM_TLV_SIZE(ret) < min_len)) {
+		return NULL;
+	}
+	return ret;
+}
+
+/*
+ * Traverse a string of 1-byte tag/1-byte length/variable-length value
+ * triples, returning a pointer to the substring whose first element
+ * matches tag.  Stop parsing when we see an element whose ID is greater
+ * than the target key.
+ */
+const  bcm_tlv_t *
+bcm_parse_ordered_tlvs(const  void *buf, uint buflen, uint key)
+{
+	const  bcm_tlv_t *elt;
+	uint totlen;
+
+	COV_TAINTED_DATA_SINK(buflen);
+	COV_NEG_SINK(buflen);
+
+	elt = (const  bcm_tlv_t*)buf;
+	totlen = buflen;
+
+	/* find tagged parameter */
+	while (totlen >= TLV_HDR_LEN) {
+		uint id = elt->id;
+		uint len = elt->len;
+
+		/* Punt if we start seeing IDs > than target key */
+		if (id > key) {
+			return (NULL);
+		}
+
+		/* validate remaining totlen */
+		if (totlen < (len + TLV_HDR_LEN)) {
+			break;
+		}
+		if (id == key) {
+			COV_TAINTED_DATA_ARG(elt);
+			return (elt);
+		}
+
+		elt = (const  bcm_tlv_t*)((const  uint8*)elt + (len + TLV_HDR_LEN));
+		totlen -= (len + TLV_HDR_LEN);
+	}
+	return NULL;
+}
+
+/**
+ * Return a const tlv buffer pointer and length representing the sub-buffer contained
+ * inside the given 'elt' starting at the given 'body_offset'.
+ * The function assumes that elt is a valid tlv; the elt pointer and data
+ * are all in the range of its parent buffer/length.
+ *
+ * @param elt         pointer to a valid bcm_tlv_t
+ * @param body_offset offset into the data body of elt
+ * @param buffer      on return, pointer to an offset in elt
+ * @param buflen      on return, length of the buffer to the end of elt
+ *
+ * On return, if body_offset is not less than the elt's body length, the *buffer parameter
+ * will be set to NULL and *buflen parameter will be set to zero.  Otherwise,
+ * *buffer will point to the sub-buffer at the body_offset, and *buflen be the remaining
+ * bytes in the body.
+ * E.g. Given a TLV with elt->len == 10, the call
+ * bcm_tlv_sub_buffer(elt, 4, &buffer, &buflen)
+ * will result with buffer = elt->data + 4, and buflen = 6.
+ */
+void
+bcm_tlv_sub_buffer(const bcm_tlv_t *elt, uint body_offset, const uint8 **buffer, uint8 *buflen)
+{
+	if (elt->len > body_offset) {
+		uint8 body_len = elt->len;
+
+#if defined(__COVERITY__)
+		/* The 'body_len' value is tainted in Coverity because it is read from
+		 * the tainted data pointed to by 'elt'. However, bcm_parse_tlvs() verifies
+		 * that the elt pointer is a valid element, so its body length is in the bounds
+		 * of the buffer.
+		 * Clearing the tainted attribute of 'body_len' for Coverity.
+		 */
+		__coverity_tainted_data_sanitize__(body_len);
+#endif /* __COVERITY__ */
+		*buflen = body_len - body_offset;
+		*buffer = elt->data + body_offset;
+	} else {
+		*buflen = 0u;
+		*buffer = NULL;
+	}
+}
+#endif	/* !BCMROMOFFLOAD_EXCLUDE_BCMUTILS_FUNCS */
+
+uint
+bcm_format_field(const bcm_bit_desc_ex_t *bd, uint32 flags, char* buf, uint len)
+{
+	uint i, slen = 0;
+	uint32 bit, mask;
+	const char *name;
+	mask = bd->mask;
+	if (len < 2 || !buf)
+		return 0;
+
+	buf[0] = '\0';
+
+	for (i = 0;  (name = bd->bitfield[i].name) != NULL; i++) {
+		bit = bd->bitfield[i].bit;
+		if ((flags & mask) == bit) {
+			slen = strlen(name);
+			if (memcpy_s(buf, len, name, slen + 1) != BCME_OK) {
+				slen = 0;
+			}
+			break;
+		}
+	}
+	return slen;
+}
+
+int
+bcm_format_flags(const bcm_bit_desc_t *bd, uint32 flags, char* buf, uint len)
+{
+	uint i;
+	char *p = buf;
+	char *end =  (buf + len);
+	char hexstr[16];
+	uint32 bit;
+	const char* name;
+	bool err = FALSE;
+
+	if (len < 2 || !buf)
+		return 0;
+
+	buf[0] = '\0';
+
+	for (i = 0; flags != 0; i++) {
+		bit = bd[i].bit;
+		name = bd[i].name;
+		if (bit == 0 && flags != 0) {
+			/* print any unnamed bits */
+			snprintf(hexstr, sizeof(hexstr), "0x%X", flags);
+			name = hexstr;
+			flags = 0;	/* exit loop */
+		} else if ((flags & bit) == 0) {
+			continue;
+		}
+		flags &= ~bit;
+
+		/* Print named bit. */
+		p += strlcpy(p, name, (size_t)(end - p));
+		if (p == end) {
+			/* Truncation error. */
+			err = TRUE;
+			break;
+		}
+
+		/* Add space delimiter if there are more bits. */
+		if (flags != 0) {
+			p += strlcpy(p, " ", (size_t)(end - p));
+			if (p == end) {
+				/* Truncation error. */
+				err = TRUE;
+				break;
+			}
+		}
+	}
+
+	/* indicate the str was too short */
+	if (err) {
+		ASSERT(len >= 2u);
+		buf[len - 2u] = '>';
+	}
+
+	return (int)(p - buf);
+}
+
+/* print out whcih bits in octet array 'addr' are set. bcm_bit_desc_t:bit is a bit offset. */
+int
+bcm_format_octets(const bcm_bit_desc_t *bd, uint bdsz,
+	const uint8 *addr, uint size, char *buf, uint len)
+{
+	uint i;
+	char *p = buf;
+	uint slen = 0, nlen = 0;
+	uint32 bit;
+	const char* name;
+	bool more = FALSE;
+
+	BCM_REFERENCE(size);
+
+	if (len < 2 || !buf)
+		return 0;
+
+	buf[0] = '\0';
+
+	for (i = 0; i < bdsz; i++) {
+		bit = bd[i].bit;
+		name = bd[i].name;
+		if (isset(addr, bit)) {
+			nlen = strlen(name);
+			slen += nlen;
+			/* need SPACE - for simplicity */
+			slen += 1;
+			/* need NULL as well */
+			if (len < slen + 1) {
+				more = TRUE;
+				break;
+			}
+			memcpy(p, name, nlen);
+			p += nlen;
+			p[0] = ' ';
+			p += 1;
+			p[0] = '\0';
+		}
+	}
+
+	if (more) {
+		p[0] = '>';
+		p += 1;
+		p[0] = '\0';
+	}
+
+	return (int)(p - buf);
+}
+
+/* Transform an hexadecimal string into binary.
+ * Output is limited to 64K.
+ * hex : string
+ * hex_len : string length
+ * buf : allocated output buffer
+ * buf_len : allocated size
+ * return : copied length, if successfull, 0 if error.
+ */
+uint16
+bcmhex2bin(const uint8* hex, uint hex_len, uint8 *buf, uint buf_len)
+{
+		uint i = 0;
+		uint16 out_len;
+		char tmp[] = "XX";
+		if (hex_len % 2) {
+			/* hex_len not even */
+			return 0;
+		}
+		/* check for hex radix */
+		if ((hex[0] == '0') && ((hex[1] == 'x') || (hex[1] == 'X'))) {
+			hex += 2;
+			hex_len -= 2;
+		}
+		if (hex_len/2 > 0xFFFF) {
+			/* exceed 64K buffer capacity */
+			return 0;
+		}
+		if ((out_len = hex_len/2) > buf_len) {
+			/* buf too short */
+			return 0;
+		}
+		do {
+			tmp[0] = *hex++;
+			tmp[1] = *hex++;
+			if (!bcm_isxdigit(tmp[0]) || !bcm_isxdigit(tmp[1])) {
+				/* char is not a 256-bit hex number	*/
+				return 0;
+			}
+			/* okay so far; make this piece a number */
+			buf[i] = (uint8) bcm_strtoul(tmp, NULL, 16);
+		} while (++i < out_len);
+		return out_len;
+}
+
+/* print bytes formatted as hex to a string. return the resulting string length */
+int
+bcm_format_hex(char *str, const void *bytes, uint len)
+{
+	uint i;
+	char *p = str;
+	const uint8 *src = (const uint8*)bytes;
+
+	for (i = 0; i < len; i++) {
+		p += snprintf(p, 3, "%02X", *src);
+		src++;
+	}
+	return (int)(p - str);
+}
+
+/* pretty hex print a contiguous buffer */
+void
+prhex(const char *msg, const uchar *buf, uint nbytes)
+{
+	char line[128], *p;
+	uint len = sizeof(line);
+	int nchar;
+	uint i;
+
+	if (msg && (msg[0] != '\0'))
+		printf("%s:\n", msg);
+
+	p = line;
+	for (i = 0; i < nbytes; i++) {
+		if (i % 16 == 0) {
+			nchar = snprintf(p, len, "  %04x: ", i);	/* line prefix */
+			p += nchar;
+			len -= (uint)nchar;
+		}
+		if (len > 0) {
+			nchar = snprintf(p, len, "%02x ", buf[i]);
+			p += nchar;
+			len -= (uint)nchar;
+		}
+
+		if (i % 16 == 15) {
+			printf("%s\n", line);		/* flush line */
+			p = line;
+			len = sizeof(line);
+		}
+	}
+
+	/* flush last partial line */
+	if (p != line)
+		printf("%s\n", line);
+}
+
+static const char *crypto_algo_names[] = {
+	"NONE",
+	"WEP1",
+	"TKIP",
+	"WEP128",
+	"AES_CCM",
+	"AES_OCB_MSDU",
+	"AES_OCB_MPDU",
+	"NALG",
+	"UNDEF",
+	"UNDEF",
+	"UNDEF",
+
+#ifdef BCMWAPI_WAI
+	"WAPI",
+#endif /* BCMWAPI_WAI */
+
+#ifndef BCMWAPI_WAI
+	"UNDEF",
+#endif
+	"PMK",
+	"BIP",
+	"AES_GCM",
+	"AES_CCM256",
+	"AES_GCM256",
+	"BIP_CMAC256",
+	"BIP_GMAC",
+	"BIP_GMAC256",
+	"UNDEF"
+};
+
+const char *
+bcm_crypto_algo_name(uint algo)
+{
+	return (algo < ARRAYSIZE(crypto_algo_names)) ? crypto_algo_names[algo] : "ERR";
+}
+
+#ifdef BCMDBG
+void
+deadbeef(void *p, uint len)
+{
+	static uint8 meat[] = { 0xde, 0xad, 0xbe, 0xef };
+
+	while (len-- > 0) {
+		*(uint8*)p = meat[((uintptr)p) & 3];
+		p = (uint8*)p + 1;
+	}
+}
+#endif /* BCMDBG */
+
+char *
+bcm_chipname(uint chipid, char *buf, uint len)
+{
+	const char *fmt;
+
+	fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
+	snprintf(buf, len, fmt, chipid);
+	return buf;
+}
+
+/* Produce a human-readable string for boardrev */
+char *
+bcm_brev_str(uint32 brev, char *buf)
+{
+	if (brev < 0x100)
+		snprintf(buf, 8, "%d.%d", (brev & 0xf0) >> 4, brev & 0xf);
+	else
+		snprintf(buf, 8, "%c%03x", ((brev & 0xf000) == 0x1000) ? 'P' : 'A', brev & 0xfff);
+
+	return (buf);
+}
+
+#define BUFSIZE_TODUMP_ATONCE 128 /* Buffer size */
+
+/* dump large strings to console */
+void
+printbig(char *buf)
+{
+	uint len, max_len;
+	char c;
+
+	len = (uint)strlen(buf);
+
+	max_len = BUFSIZE_TODUMP_ATONCE;
+
+	while (len > max_len) {
+		c = buf[max_len];
+		buf[max_len] = '\0';
+		printf("%s", buf);
+		buf[max_len] = c;
+
+		buf += max_len;
+		len -= max_len;
+	}
+	/* print the remaining string */
+	printf("%s\n", buf);
+	return;
+}
+
+/* routine to dump fields in a fileddesc structure */
+uint
+bcmdumpfields(bcmutl_rdreg_rtn read_rtn, void *arg0, uint arg1, struct fielddesc *fielddesc_array,
+	char *buf, uint32 bufsize)
+{
+	int ret;
+	uint filled_len;
+	uint len;
+	struct fielddesc *cur_ptr;
+
+	filled_len = 0;
+	cur_ptr = fielddesc_array;
+
+	while (bufsize > 1) {
+		if (cur_ptr->nameandfmt == NULL)
+			break;
+		/* check for snprintf overflow or error */
+		ret = snprintf(buf, bufsize, cur_ptr->nameandfmt,
+		               read_rtn(arg0, arg1, cur_ptr->offset));
+		if (ret < 0 || ret >= (int)bufsize) {
+			/* encoding error from snprintf */
+			len = bufsize - 1u;
+		} else {
+			len = (uint32)ret;
+		}
+
+		buf += len;
+		bufsize -= len;
+		filled_len += len;
+		cur_ptr++;
+	}
+	return filled_len;
+}
+
+uint
+bcm_mkiovar(const char *name, const char *data, uint datalen, char *buf, uint buflen)
+{
+	uint len;
+
+	len = (uint)strlen(name) + 1;
+
+	if ((len + datalen) > buflen)
+		return 0;
+
+	strlcpy(buf, name, buflen);
+
+	/* append data onto the end of the name string */
+	if (data && datalen != 0) {
+		memcpy(&buf[len], data, datalen);
+		len += datalen;
+	}
+
+	return len;
+}
+
+/* Quarter dBm units to mW
+ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
+ * Table is offset so the last entry is largest mW value that fits in
+ * a uint16.
+ */
+
+#define QDBM_OFFSET 153		/* Offset for first entry */
+#define QDBM_TABLE_LEN 40	/* Table size */
+
+/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
+ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
+ */
+#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
+
+/* Largest mW value that will round down to the last table entry,
+ * QDBM_OFFSET + QDBM_TABLE_LEN-1.
+ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
+ */
+#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
+
+static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
+/* qdBm:	+0	+1	+2	+3	+4	+5	+6	+7 */
+/* 153: */      6683,	7079,	7499,	7943,	8414,	8913,	9441,	10000,
+/* 161: */      10593,	11220,	11885,	12589,	13335,	14125,	14962,	15849,
+/* 169: */      16788,	17783,	18836,	19953,	21135,	22387,	23714,	25119,
+/* 177: */      26607,	28184,	29854,	31623,	33497,	35481,	37584,	39811,
+/* 185: */      42170,	44668,	47315,	50119,	53088,	56234,	59566,	63096
+};
+
+uint16
+bcm_qdbm_to_mw(uint8 qdbm)
+{
+	uint factor = 1;
+	int idx = qdbm - QDBM_OFFSET;
+
+	if (idx >= QDBM_TABLE_LEN) {
+		/* clamp to max uint16 mW value */
+		return 0xFFFF;
+	}
+
+	/* scale the qdBm index up to the range of the table 0-40
+	 * where an offset of 40 qdBm equals a factor of 10 mW.
+	 */
+	while (idx < 0) {
+		idx += 40;
+		factor *= 10;
+	}
+
+	/* return the mW value scaled down to the correct factor of 10,
+	 * adding in factor/2 to get proper rounding.
+	 */
+	return ((nqdBm_to_mW_map[idx] + factor/2) / factor);
+}
+
+uint8
+bcm_mw_to_qdbm(uint16 mw)
+{
+	uint8 qdbm;
+	int offset;
+	uint16 mw_uint = mw;
+	uint16 boundary;
+
+	/* handle boundary case */
+	if (mw_uint <= 1)
+		return 0;
+
+	offset = QDBM_OFFSET;
+
+	/* move mw into the range of the table */
+	while (mw_uint < QDBM_TABLE_LOW_BOUND) {
+		mw_uint *= 10;
+		offset -= 40;
+	}
+
+	for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) {
+		boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] -
+		                                    nqdBm_to_mW_map[qdbm])/2;
+		if (mw_uint < boundary) break;
+	}
+
+	qdbm += (uint8)offset;
+
+	return (qdbm);
+}
+
+uint
+BCMPOSTTRAPFN(bcm_bitcount)(const uint8 *bitmap, uint length)
+{
+	uint bitcount = 0, i;
+	uint8 tmp;
+	for (i = 0; i < length; i++) {
+		tmp = bitmap[i];
+		while (tmp) {
+			bitcount++;
+			tmp &= (tmp - 1);
+		}
+	}
+	return bitcount;
+}
+
+/* Count 0s or 1s in an octets list from 'from_bit' to 'to_bit' inclusively */
+uint
+bcm_count_bits(const uint8 *buf, uint buf_len, uint from_bit, uint to_bit, bool val_1)
+{
+	uint from;
+	uint to;
+	uint len;
+	uint8 tmp;
+	uint bits;
+
+	/* sanity check */
+	if (to_bit < from_bit) {
+		return 0u;
+	}
+
+	/* byte offset */
+	from = from_bit >> 3u;
+	to = to_bit >> 3u;
+	if (from >= buf_len || to >= buf_len) {
+		return 0u;
+	}
+
+	/* count 1s always */
+	len = to - from + 1u;
+	if (len == 1u) {
+		/* the only octet */
+		ASSERT(from == to);
+		tmp = buf[from];
+		tmp &= (0xffu << (from_bit & 7u));
+		tmp &= ~(0xffu << ((to_bit & 7u) + 1u));
+		bits = bcm_bitcount(&tmp, 1u);
+	} else {
+		ASSERT(len >= 2u);
+		/* the first octet */
+		tmp = buf[from];
+		tmp &= (0xffu << (from_bit & 7u));
+		bits = bcm_bitcount(&tmp, 1u);
+		/* the middle octet(s) */
+		if (len > 2u) {
+			bits += bcm_bitcount(&buf[from + 1u], len - 2u);
+		}
+		/* the last octet */
+		tmp = buf[to];
+		tmp &= ~(0xffu << ((to_bit & 7u) + 1u));
+		bits += bcm_bitcount(&tmp, 1u);
+	}
+
+	/* calc 0s if requested */
+	if (!val_1) {
+		bits = to_bit - from_bit + 1u - bits;
+	}
+
+	return bits;
+}
+
+static void
+dump_nvram(char *varbuf, int column, unsigned int n, unsigned int len)
+{
+	unsigned int m;
+	char vars[128];
+
+	if (((n==0) && (varbuf[0]=='#')) ||
+			((column==0) && (android_msg_level & ANDROID_INFO_LEVEL))) {
+		memset(vars, 0x00, sizeof(vars));
+		for (m=n; m<len && (m-n)<(sizeof(vars)-1); m++) {
+			if (varbuf[m] == '\n')
+				break;
+			vars[m-n] = varbuf[m];
+		}
+		printf("%s\n", vars);
+	}
+}
+
+/*
+ * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file and ending in a NUL.
+ * also accepts nvram files which are already in the format of <var1>=<value>\0\<var2>=<value2>\0
+ * Removes carriage returns, empty lines, comment lines, and converts newlines to NULs.
+ * Shortens buffer as needed and pads with NULs.  End of buffer is marked by two NULs.
+*/
+
+unsigned int
+process_nvram_vars(char *varbuf, unsigned int len)
+{
+	char *dp;
+	bool findNewline;
+	int column;
+	unsigned int buf_len, n;
+	unsigned int pad = 0;
+
+	dp = varbuf;
+
+	findNewline = FALSE;
+	column = 0;
+
+	dump_nvram(varbuf, 0, 0, len);
+	for (n = 0; n < len; n++) {
+		if (varbuf[n] == '\r')
+			continue;
+		if (findNewline && varbuf[n] != '\n')
+			continue;
+		findNewline = FALSE;
+		if (varbuf[n] == '#') {
+			findNewline = TRUE;
+			continue;
+		}
+		if (varbuf[n] == '\n') {
+			if (column == 0)
+				continue;
+			*dp++ = 0;
+			column = 0;
+			continue;
+		}
+		dump_nvram(varbuf, column, n, len);
+		*dp++ = varbuf[n];
+		column++;
+	}
+	buf_len = (unsigned int)(dp - varbuf);
+	if (buf_len % 4) {
+		pad = 4 - buf_len % 4;
+		if (pad && (buf_len + pad <= len)) {
+			buf_len += pad;
+		}
+	}
+
+	while (dp < varbuf + n)
+		*dp++ = 0;
+
+	return buf_len;
+}
+
+#ifndef setbit /* As in the header file */
+#ifdef BCMUTILS_BIT_MACROS_USE_FUNCS
+/* Set bit in byte array. */
+void
+setbit(void *array, uint bit)
+{
+	((uint8 *)array)[bit / NBBY] |= 1 << (bit % NBBY);
+}
+
+/* Clear bit in byte array. */
+void
+clrbit(void *array, uint bit)
+{
+	((uint8 *)array)[bit / NBBY] &= ~(1 << (bit % NBBY));
+}
+
+/* Test if bit is set in byte array. */
+bool
+isset(const void *array, uint bit)
+{
+	return (((const uint8 *)array)[bit / NBBY] & (1 << (bit % NBBY)));
+}
+
+/* Test if bit is clear in byte array. */
+bool
+isclr(const void *array, uint bit)
+{
+	return ((((const uint8 *)array)[bit / NBBY] & (1 << (bit % NBBY))) == 0);
+}
+#endif /* BCMUTILS_BIT_MACROS_USE_FUNCS */
+#endif /* setbit */
+
+void
+BCMPOSTTRAPFN(set_bitrange)(void *array, uint start, uint end, uint maxbit)
+{
+	uint startbyte = start/NBBY;
+	uint endbyte = end/NBBY;
+	uint i, startbytelastbit, endbytestartbit;
+
+	if (end >= start) {
+		if (endbyte - startbyte > 1) {
+			startbytelastbit = ((startbyte + 1) * NBBY) - 1;
+			endbytestartbit = endbyte * NBBY;
+			for (i = startbyte + 1; i < endbyte; i++)
+				((uint8 *)array)[i] = 0xFF;
+			for (i = start; i <= startbytelastbit; i++)
+				setbit(array, i);
+			for (i = endbytestartbit; i <= end; i++)
+				setbit(array, i);
+		} else {
+			for (i = start; i <= end; i++)
+				setbit(array, i);
+		}
+	} else {
+		set_bitrange(array, start, maxbit, maxbit);
+		set_bitrange(array, 0, end, maxbit);
+	}
+}
+
+void
+clr_bitrange(void *array, uint start, uint end, uint maxbit)
+{
+	uint startbyte = start/NBBY;
+	uint endbyte = end/NBBY;
+	uint i, startbytelastbit, endbytestartbit;
+
+	if (end >= start) {
+		if (endbyte - startbyte > 1) {
+			startbytelastbit = ((startbyte + 1) * NBBY) - 1;
+			endbytestartbit = endbyte * NBBY;
+			for (i = startbyte + 1; i < endbyte; i++)
+				((uint8 *)array)[i] = 0x0;
+			for (i = start; i <= startbytelastbit; i++)
+				clrbit(array, i);
+			for (i = endbytestartbit; i <= end; i++)
+				clrbit(array, i);
+		} else {
+			for (i = start; i <= end; i++)
+				clrbit(array, i);
+		}
+	} else {
+		clr_bitrange(array, start, maxbit, maxbit);
+		clr_bitrange(array, 0, end, maxbit);
+	}
+}
+
+/*
+ * This api (set_bitrange_int_access) as same as set_bitrange but uses int32 operation
+ * This api can be used in the place of set_bitrange but array should be word (32bit) alligned.
+ * This api has to be used when the memory being accessed has restrictions of
+ * not using them in 8bit (byte) mode and needing 32bit (word) mode.
+ */
+void
+set_bitrange_u32(void *array, uint start, uint end, uint maxbit)
+{
+	uint startword = start/SIZE_BITS32(uint32);
+	uint endword = end/SIZE_BITS32(uint32);
+	uint startwordstartbit = start % SIZE_BITS32(uint32);
+	uint endwordlastbit = end % SIZE_BITS32(uint32);
+	/* Used to caluculate bit number from MSB */
+	uint u32msbnum = SIZE_BITS32(uint32) - 1U;
+	uint i;
+	uint32 setbitsword;
+	uint32 u32max = ~0U;
+
+	ASSERT(ISALIGNED(array, sizeof(uint32))); /* array should be alligned for this API */
+
+	if (start > end) {
+		set_bitrange_u32(array, start, maxbit, maxbit);
+		set_bitrange_u32(array, 0U, end, maxbit);
+		return;
+	}
+
+	if (endword - startword) {
+		/* Setting MSB bits including startwordstartbit */
+		setbitsword = u32max << startwordstartbit;
+		((uint32 *)array)[startword] |= setbitsword;
+
+		/* Setting all bits in 'startword + 1' to 'endword - 1' */
+		for (i = startword + 1U; i <= endword - 1U; i++) {
+			((uint32 *)array)[i] = u32max;
+		}
+
+		/* Setting LSB bits including endwordlastbit */
+		setbitsword = u32max >> (u32msbnum - endwordlastbit);
+		((uint32 *)array)[endword] |= setbitsword;
+	} else { /* start and end are in same word */
+		/* Setting start bit to end bit including start and end bits */
+		setbitsword =
+			(u32max << startwordstartbit) & (u32max >> (u32msbnum - endwordlastbit));
+		((uint32 *)array)[startword] |= setbitsword;
+	}
+}
+
+/*
+ * This api (clr_bitrange_u32) as same as clr_bitrange but uses int32 operation
+ * This api can be used in the place of clr_bitrange but array should be word (32bit) alligned.
+ * This api has to be used when the memory being accessed has restrictions of
+ * not using them in 8bit (byte) mode and needing 32bit (word) mode.
+ */
+void
+clr_bitrange_u32(void *array, uint start, uint end, uint maxbit)
+{
+	uint startword = start/SIZE_BITS32(uint32);
+	uint endword = end/SIZE_BITS32(uint32);
+	uint startwordstartbit = start % SIZE_BITS32(uint32);
+	uint endwordlastbit = end % SIZE_BITS32(uint32);
+	/* Used to caluculate bit number from MSB */
+	uint u32msbnum = SIZE_BITS32(uint32) - 1U;
+	uint i;
+	uint32 clrbitsword;
+	uint32 u32max = ~0U;
+
+	ASSERT(ISALIGNED(array, sizeof(uint32))); /* array should be alligned for this API */
+
+	if (start > end) {
+		clr_bitrange_u32(array, start, maxbit, maxbit);
+		clr_bitrange_u32(array, 0U, end, maxbit);
+		return;
+	}
+
+	if (endword - startword) {
+		/* Clearing MSB bits including startwordstartbit */
+		clrbitsword = ~(u32max << startwordstartbit);
+		((uint32 *)array)[startword] &= clrbitsword;
+
+		/* Clearing all bits in 'startword + 1' to 'endword - 1' */
+		for (i = startword + 1U; i <= endword - 1U; i++) {
+			((uint32 *)array)[i] = 0U;
+		}
+
+		/* Clearing LSB bits including endwordlastbit */
+		clrbitsword = ~(u32max >> (u32msbnum - endwordlastbit));
+		((uint32 *)array)[endword] &= clrbitsword;
+	} else { /* start and end are in same word */
+		/* Clearing start bit to end bit including start and end bits */
+		clrbitsword =
+			~(u32max << startwordstartbit) | ~(u32max >> (u32msbnum - endwordlastbit));
+		((uint32 *)array)[startword] &= clrbitsword;
+	}
+}
+
+void
+bcm_bitprint32(const uint32 u32arg)
+{
+	int i;
+	for (i = NBITS(uint32) - 1; i >= 0; i--) {
+		if (isbitset(u32arg, i)) {
+			printf("1");
+		} else {
+			printf("0");
+		}
+
+		if ((i % NBBY) == 0) printf(" ");
+	}
+	printf("\n");
+}
+
+/* calculate checksum for ip header, tcp / udp header / data */
+uint16
+bcm_ip_cksum(uint8 *buf, uint32 len, uint32 sum)
+{
+	while (len > 1) {
+		sum += ((uint32)buf[0] << 8) | buf[1];
+		buf += 2;
+		len -= 2;
+	}
+
+	if (len > 0) {
+		sum += ((uint32)*buf) << 8;
+	}
+
+	while (sum >> 16) {
+		sum = (sum & 0xffff) + (sum >> 16);
+	}
+
+	return ((uint16)~sum);
+}
+
+/* calculate a + b where a is a 64 bit number and b is a 32 bit number */
+void
+bcm_add_64(uint32* r_hi, uint32* r_lo, uint32 offset)
+{
+	uint32 r1_lo = *r_lo;
+	(*r_lo) += offset;
+	if (*r_lo < r1_lo)
+		(*r_hi) ++;
+}
+
+/* calculate a - b where a is a 64 bit number and b is a 32 bit number */
+void
+bcm_sub_64(uint32* r_hi, uint32* r_lo, uint32 offset)
+{
+	uint32 r1_lo = *r_lo;
+	(*r_lo) -= offset;
+	if (*r_lo > r1_lo)
+		(*r_hi) --;
+}
+
+int
+BCMRAMFN(valid_bcmerror)(int e)
+{
+	return ((e <= 0) && (e >= BCME_LAST));
+}
+
+#ifdef DEBUG_COUNTER
+#if (OSL_SYSUPTIME_SUPPORT == TRUE)
+void counter_printlog(counter_tbl_t *ctr_tbl)
+{
+	uint32 now;
+
+	if (!ctr_tbl->enabled)
+		return;
+
+	now = OSL_SYSUPTIME();
+
+	if (now - ctr_tbl->prev_log_print > ctr_tbl->log_print_interval) {
+		uint8 i = 0;
+		printf("counter_print(%s %d):", ctr_tbl->name, now - ctr_tbl->prev_log_print);
+
+		for (i = 0; i < ctr_tbl->needed_cnt; i++) {
+			printf(" %u", ctr_tbl->cnt[i]);
+		}
+		printf("\n");
+
+		ctr_tbl->prev_log_print = now;
+		bzero(ctr_tbl->cnt, CNTR_TBL_MAX * sizeof(uint));
+	}
+}
+#else
+/* OSL_SYSUPTIME is not supported so no way to get time */
+#define counter_printlog(a) do {} while (0)
+#endif /* OSL_SYSUPTIME_SUPPORT == TRUE */
+#endif /* DEBUG_COUNTER */
+
+/* calculate partial checksum */
+uint32
+ip_cksum_partial(uint32 sum, uint8 *val8, uint32 count)
+{
+	uint32 i;
+	uint16 *val16 = (uint16 *)val8;
+
+	ASSERT(val8 != NULL);
+	/* partial chksum calculated on 16-bit values */
+	ASSERT((count % 2) == 0);
+
+	count /= 2;
+
+	for (i = 0; i < count; i++) {
+		sum += *val16++;
+	}
+	return sum;
+}
+
+/* calculate IP checksum */
+uint16
+ip_cksum(uint32 sum, uint8 *val8, uint32 count)
+{
+	uint16 *val16 = (uint16 *)val8;
+
+	ASSERT(val8 != NULL);
+
+	while (count > 1) {
+		sum += *val16++;
+		count -= 2;
+	}
+	/*  add left-over byte, if any */
+	if (count > 0) {
+		sum += (*(uint8 *)val16);
+	}
+
+	/*  fold 32-bit sum to 16 bits */
+	sum = (sum >> 16) + (sum & 0xffff);
+	sum += (sum >> 16);
+	return ((uint16)~sum);
+}
+
+/* calculate IPv4 header checksum
+ * - input ip points to IP header in network order
+ * - output cksum is in network order
+ */
+uint16
+ipv4_hdr_cksum(uint8 *ip, uint ip_len)
+{
+	uint32 sum = 0;
+	uint8 *ptr = ip;
+
+	ASSERT(ip != NULL);
+	ASSERT(ip_len >= IPV4_MIN_HEADER_LEN);
+
+	if (ip_len < IPV4_MIN_HEADER_LEN) {
+		return 0;
+	}
+
+	/* partial cksum skipping the hdr_chksum field */
+	sum = ip_cksum_partial(sum, ptr, OFFSETOF(struct ipv4_hdr, hdr_chksum));
+	ptr += OFFSETOF(struct ipv4_hdr, hdr_chksum) + 2;
+
+	/* return calculated chksum */
+	return ip_cksum(sum, ptr, ip_len - OFFSETOF(struct ipv4_hdr, src_ip));
+}
+
+/* calculate TCP header checksum using partial sum */
+static uint16
+tcp_hdr_chksum(uint32 sum, uint8 *tcp_hdr, uint16 tcp_len)
+{
+	uint8 *ptr = tcp_hdr;
+
+	ASSERT(tcp_hdr != NULL);
+	ASSERT(tcp_len >= TCP_MIN_HEADER_LEN);
+
+	/* partial TCP cksum skipping the chksum field */
+	sum = ip_cksum_partial(sum, ptr, OFFSETOF(struct bcmtcp_hdr, chksum));
+	ptr += OFFSETOF(struct bcmtcp_hdr, chksum) + 2;
+
+	/* return calculated chksum */
+	return ip_cksum(sum, ptr, tcp_len - OFFSETOF(struct bcmtcp_hdr, urg_ptr));
+}
+
+struct tcp_pseudo_hdr {
+	uint8   src_ip[IPV4_ADDR_LEN];  /* Source IP Address */
+	uint8   dst_ip[IPV4_ADDR_LEN];  /* Destination IP Address */
+	uint8	zero;
+	uint8	prot;
+	uint16	tcp_size;
+};
+
+/* calculate IPv4 TCP header checksum
+ * - input ip and tcp points to IP and TCP header in network order
+ * - output cksum is in network order
+ */
+uint16
+ipv4_tcp_hdr_cksum(uint8 *ip, uint8 *tcp, uint16 tcp_len)
+{
+	struct ipv4_hdr *ip_hdr = (struct ipv4_hdr *)ip;
+	struct tcp_pseudo_hdr tcp_ps;
+	uint32 sum = 0;
+
+	ASSERT(ip != NULL);
+	ASSERT(tcp != NULL);
+	ASSERT(tcp_len >= TCP_MIN_HEADER_LEN);
+
+	/* pseudo header cksum */
+	bzero(&tcp_ps, sizeof(tcp_ps));
+	memcpy(&tcp_ps.dst_ip, ip_hdr->dst_ip, IPV4_ADDR_LEN);
+	memcpy(&tcp_ps.src_ip, ip_hdr->src_ip, IPV4_ADDR_LEN);
+	tcp_ps.zero = 0;
+	tcp_ps.prot = ip_hdr->prot;
+	tcp_ps.tcp_size = hton16(tcp_len);
+	sum = ip_cksum_partial(sum, (uint8 *)&tcp_ps, sizeof(tcp_ps));
+
+	/* return calculated TCP header chksum */
+	return tcp_hdr_chksum(sum, tcp, tcp_len);
+}
+
+struct ipv6_pseudo_hdr {
+	uint8  saddr[IPV6_ADDR_LEN];
+	uint8  daddr[IPV6_ADDR_LEN];
+	uint16 payload_len;
+	uint8  zero;
+	uint8  next_hdr;
+};
+
+/* calculate IPv6 TCP header checksum
+ * - input ipv6 and tcp points to IPv6 and TCP header in network order
+ * - output cksum is in network order
+ */
+uint16
+ipv6_tcp_hdr_cksum(uint8 *ipv6, uint8 *tcp, uint16 tcp_len)
+{
+	struct ipv6_hdr *ipv6_hdr = (struct ipv6_hdr *)ipv6;
+	struct ipv6_pseudo_hdr ipv6_pseudo;
+	uint32 sum = 0;
+
+	ASSERT(ipv6 != NULL);
+	ASSERT(tcp != NULL);
+	ASSERT(tcp_len >= TCP_MIN_HEADER_LEN);
+
+	/* pseudo header cksum */
+	bzero((char *)&ipv6_pseudo, sizeof(ipv6_pseudo));
+	memcpy((char *)ipv6_pseudo.saddr, (char *)ipv6_hdr->saddr.addr,
+		sizeof(ipv6_pseudo.saddr));
+	memcpy((char *)ipv6_pseudo.daddr, (char *)ipv6_hdr->daddr.addr,
+		sizeof(ipv6_pseudo.daddr));
+	ipv6_pseudo.payload_len = ipv6_hdr->payload_len;
+	ipv6_pseudo.next_hdr = ipv6_hdr->nexthdr;
+	sum = ip_cksum_partial(sum, (uint8 *)&ipv6_pseudo, sizeof(ipv6_pseudo));
+
+	/* return calculated TCP header chksum */
+	return tcp_hdr_chksum(sum, tcp, tcp_len);
+}
+
+void *_bcmutils_dummy_fn = NULL;
+
+/* GROUP 1 --- start
+ * These function under GROUP 1 are general purpose functions to do complex number
+ * calculations and square root calculation.
+ */
+
+uint32 sqrt_int(uint32 value)
+{
+	uint32 root = 0, shift = 0;
+
+	/* Compute integer nearest to square root of input integer value */
+	for (shift = 0; shift < 32; shift += 2) {
+		if (((0x40000000u >> shift) + root) <= value) {
+			value -= ((0x40000000u >> shift) + root);
+			root = (root >> 1) | (0x40000000u >> shift);
+		}
+		else {
+			root = root >> 1;
+		}
+	}
+
+	/* round to the nearest integer */
+	if (root < value) ++root;
+
+	return root;
+}
+
+/* GROUP 1 --- end */
+
+/* read/write field in a consecutive bits in an octet array.
+ * 'addr' is the octet array's start byte address
+ * 'size' is the octet array's byte size
+ * 'stbit' is the value's start bit offset
+ * 'nbits' is the value's bit size
+ * This set of utilities are for convenience. Don't use them
+ * in time critical/data path as there's a great overhead in them.
+ */
+void
+setbits(uint8 *addr, uint size, uint stbit, uint nbits, uint32 val)
+{
+	uint fbyte = stbit >> 3;		/* first byte */
+	uint lbyte = (stbit + nbits - 1) >> 3;	/* last byte */
+	uint fbit = stbit & 7;			/* first bit in the first byte */
+	uint rbits = (nbits > 8 - fbit ?
+	              nbits - (8 - fbit) :
+	              0) & 7;			/* remaining bits of the last byte when not 0 */
+	uint8 mask;
+	uint byte;
+
+	BCM_REFERENCE(size);
+
+	ASSERT(fbyte < size);
+	ASSERT(lbyte < size);
+	ASSERT(nbits <= (sizeof(val) << 3));
+
+	/* all bits are in the same byte */
+	if (fbyte == lbyte) {
+		mask = ((1 << nbits) - 1) << fbit;
+		addr[fbyte] &= ~mask;
+		addr[fbyte] |= (uint8)(val << fbit);
+		return;
+	}
+
+	/* first partial byte */
+	if (fbit > 0) {
+		mask = (0xff << fbit);
+		addr[fbyte] &= ~mask;
+		addr[fbyte] |= (uint8)(val << fbit);
+		val >>= (8 - fbit);
+		nbits -= (8 - fbit);
+		fbyte ++;	/* first full byte */
+	}
+
+	/* last partial byte */
+	if (rbits > 0) {
+		mask = (1 << rbits) - 1;
+		addr[lbyte] &= ~mask;
+		addr[lbyte] |= (uint8)(val >> (nbits - rbits));
+		lbyte --;	/* last full byte */
+	}
+
+	/* remaining full byte(s) */
+	for (byte = fbyte; byte <= lbyte; byte ++) {
+		addr[byte] = (uint8)val;
+		val >>= 8;
+	}
+}
+
+uint32
+getbits(const uint8 *addr, uint size, uint stbit, uint nbits)
+{
+	uint fbyte = stbit >> 3u;		/* first byte */
+	uint lbyte = (stbit + nbits - 1u) >> 3u;	/* last byte */
+	uint fbit = stbit & 7u;			/* first bit in the first byte */
+	uint rbits = (nbits > 8u - fbit ?
+	              nbits - (8u - fbit) :
+	              0) & 7u;			/* remaining bits of the last byte when not 0 */
+	uint32 val = 0;
+	uint bits = 0;				/* bits in first partial byte */
+	uint8 mask;
+	uint byte;
+
+	BCM_REFERENCE(size);
+
+	ASSERT_FP(fbyte < size);
+	ASSERT_FP(lbyte < size);
+	ASSERT_FP(nbits <= (sizeof(val) << 3u));
+
+	/* all bits are in the same byte */
+	if (fbyte == lbyte) {
+		mask = ((1u << nbits) - 1u) << fbit;
+		val = ((uint32)addr[fbyte] & mask) >> fbit;
+		return val;
+	}
+
+	/* first partial byte */
+	if (fbit > 0) {
+		bits = 8u - fbit;
+		mask = (0xffu << fbit);
+		val |= ((uint32)addr[fbyte] & mask) >> fbit;
+		fbyte ++;	/* first full byte */
+	}
+
+	/* last partial byte */
+	if (rbits > 0) {
+		mask = (1u << rbits) - 1u;
+		val |= ((uint32)addr[lbyte] & mask) << (nbits - rbits);
+		lbyte --;	/* last full byte */
+	}
+
+	/* remaining full byte(s) */
+	for (byte = fbyte; byte <= lbyte; byte ++) {
+		val |= ((uint32)addr[byte] << (((byte - fbyte) << 3u) + bits));
+	}
+
+	return val;
+}
+
+#if defined(BCMDBG) || defined(WLMSG_ASSOC)
+/* support for getting 802.11 frame type/name based on frame kind */
+#define FK_NAME_DECL(x) {FC_##x, #x}
+static const struct {
+    uint fk;
+    const char *name;
+} bcm_80211_fk_names[] =  {
+	FK_NAME_DECL(ASSOC_REQ),
+	FK_NAME_DECL(ASSOC_RESP),
+	FK_NAME_DECL(REASSOC_REQ),
+	FK_NAME_DECL(REASSOC_RESP),
+	FK_NAME_DECL(PROBE_REQ),
+	FK_NAME_DECL(PROBE_RESP),
+	FK_NAME_DECL(BEACON),
+	FK_NAME_DECL(ATIM),
+	FK_NAME_DECL(DISASSOC),
+	FK_NAME_DECL(AUTH),
+	FK_NAME_DECL(DEAUTH),
+	FK_NAME_DECL(ACTION),
+	FK_NAME_DECL(ACTION_NOACK),
+	FK_NAME_DECL(CTL_TRIGGER),
+	FK_NAME_DECL(CTL_WRAPPER),
+	FK_NAME_DECL(BLOCKACK_REQ),
+	FK_NAME_DECL(BLOCKACK),
+	FK_NAME_DECL(PS_POLL),
+	FK_NAME_DECL(RTS),
+	FK_NAME_DECL(CTS),
+	FK_NAME_DECL(ACK),
+	FK_NAME_DECL(CF_END),
+	FK_NAME_DECL(CF_END_ACK),
+	FK_NAME_DECL(DATA),
+	FK_NAME_DECL(NULL_DATA),
+	FK_NAME_DECL(DATA_CF_ACK),
+	FK_NAME_DECL(QOS_DATA),
+	FK_NAME_DECL(QOS_NULL)
+};
+static const uint n_bcm_80211_fk_names = ARRAYSIZE(bcm_80211_fk_names);
+
+const char *bcm_80211_fk_name(uint fk)
+{
+	uint i;
+	for (i = 0; i < n_bcm_80211_fk_names; ++i) {
+		if (bcm_80211_fk_names[i].fk == fk) {
+			return bcm_80211_fk_names[i].name;
+		}
+	}
+	return "unknown";
+}
+#endif /* BCMDBG || WLMSG_ASSOC */
+
+#ifdef BCMDRIVER
+
+/** allocate variable sized data with 'size' bytes. note: vld should NOT be null.
+ */
+int
+bcm_vdata_alloc(osl_t *osh, var_len_data_t *vld, uint32 size)
+{
+	int ret = BCME_ERROR;
+	uint8 *dat = NULL;
+
+	if (vld == NULL) {
+		ASSERT(0);
+		goto done;
+	}
+
+	/* trying to allocate twice? */
+	if (vld->vdata != NULL) {
+		ASSERT(0);
+		goto done;
+	}
+
+	/* trying to allocate 0 size? */
+	if (size == 0) {
+		ASSERT(0);
+		ret = BCME_BADARG;
+		goto done;
+	}
+
+	dat = MALLOCZ(osh, size);
+	if (dat == NULL) {
+		ret = BCME_NOMEM;
+		goto done;
+	}
+	vld->vlen = size;
+	vld->vdata = dat;
+	ret = BCME_OK;
+done:
+	return ret;
+}
+
+/** free memory associated with variable sized data. note: vld should NOT be null.
+ */
+int
+bcm_vdata_free(osl_t *osh, var_len_data_t *vld)
+{
+	int ret = BCME_ERROR;
+
+	if (vld == NULL) {
+		ASSERT(0);
+		goto done;
+	}
+
+	if (vld->vdata) {
+		MFREE(osh, vld->vdata, vld->vlen);
+		vld->vlen = 0;
+		ret = BCME_OK;
+	}
+done:
+	return ret;
+}
+
+/* return TRUE if :
+ * - both buffers are of length 0
+ * OR
+ * - both buffers are NULL
+ * OR
+ * lengths and contents are the same.
+ */
+bool
+bcm_match_buffers(const uint8 *b1, uint b1_len, const uint8 *b2, uint b2_len)
+
+{
+	if (b1_len == 0 && b2_len == 0) {
+		return TRUE;
+	}
+
+	if (b1 == NULL && b2 == NULL) {
+		return TRUE;
+	}
+
+	/* If they are not both NULL, neither can be */
+	if (b1 == NULL || b2 == NULL) {
+		return FALSE;
+	}
+
+	if ((b1_len == b2_len) && !memcmp(b1, b2, b1_len)) {
+		return TRUE;
+	}
+	return FALSE;
+}
+
+#ifdef PRIVACY_MASK
+/* applies privacy mask on the input address itself */
+void
+BCMRAMFN(bcm_ether_privacy_mask)(struct ether_addr *addr)
+{
+	struct ether_addr *privacy = privacy_addrmask_get();
+	if (addr && !ETHER_ISMULTI(addr)) {
+		*(uint32*)(&(addr->octet[0])) &= *((uint32*)&privacy->octet[0]);
+		*(uint16*)(&(addr->octet[4])) &= *((uint16*)&privacy->octet[4]);
+	}
+}
+#endif /* PRIVACY_MASK */
+#endif /* BCMDRIVER */
+
+/* Count the number of elements not matching a given value in a null terminated array */
+int
+array_value_mismatch_count(uint8 value, uint8 *array, int array_size)
+{
+	int i;
+	int count = 0;
+
+	for (i = 0; i < array_size; i++) {
+		/* exit if a null terminator is found */
+		if (array[i] == 0) {
+			break;
+		}
+		if (array[i] != value) {
+			count++;
+		}
+	}
+	return count;
+}
+
+/* Count the number of non-zero elements in an uint8 array */
+int
+array_nonzero_count(uint8 *array, int array_size)
+{
+	return array_value_mismatch_count(0, array, array_size);
+}
+
+/* Count the number of non-zero elements in an int16 array */
+int
+array_nonzero_count_int16(int16 *array, int array_size)
+{
+	int i;
+	int count = 0;
+
+	for (i = 0; i < array_size; i++) {
+		if (array[i] != 0) {
+			count++;
+		}
+	}
+	return count;
+}
+
+/* Count the number of zero elements in an uint8 array */
+int
+array_zero_count(uint8 *array, int array_size)
+{
+	int i;
+	int count = 0;
+
+	for (i = 0; i < array_size; i++) {
+		if (array[i] == 0) {
+			count++;
+		}
+	}
+	return count;
+}
+
+/* Validate an array that can be 1 of 2 data types.
+ * One of array1 or array2 should be non-NULL.  The other should be NULL.
+ */
+static int
+verify_ordered_array(uint8 *array1, int16 *array2, int array_size,
+	int range_lo, int range_hi, bool err_if_no_zero_term, bool is_ordered)
+{
+	int ret;
+	int i;
+	int val = 0;
+	int prev_val = 0;
+
+	ret = err_if_no_zero_term ? BCME_NOTFOUND : BCME_OK;
+
+	/* Check that:
+	 * - values are in descending order.
+	 * - values are within the valid range.
+	 */
+	for (i = 0; i < array_size; i++) {
+		if (array1) {
+			val = (int)array1[i];
+		} else if (array2) {
+			val = (int)array2[i];
+		} else {
+			/* both array parameters are NULL */
+			return BCME_NOTFOUND;
+		}
+		if (val == 0) {
+			/* array is zero-terminated */
+			ret = BCME_OK;
+			break;
+		}
+
+		if (is_ordered && i > 0 && val > prev_val) {
+			/* array is not in descending order */
+			ret = BCME_BADOPTION;
+			break;
+		}
+		prev_val = val;
+
+		if (val < range_lo || val > range_hi) {
+			/* array value out of range */
+			ret = BCME_RANGE;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+/* Validate an ordered uint8 configuration array */
+int
+verify_ordered_array_uint8(uint8 *array, int array_size,
+	uint8 range_lo, uint8 range_hi)
+{
+	return verify_ordered_array(array, NULL, array_size, (int)range_lo, (int)range_hi,
+		TRUE, TRUE);
+}
+
+/* Validate an ordered int16 non-zero-terminated configuration array */
+int
+verify_ordered_array_int16(int16 *array, int array_size,
+	int16 range_lo, int16 range_hi)
+{
+	return verify_ordered_array(NULL, array, array_size, (int)range_lo, (int)range_hi,
+		FALSE, TRUE);
+}
+
+/* Validate all values in an array are in range */
+int
+verify_array_values(uint8 *array, int array_size,
+	int range_lo, int range_hi, bool zero_terminated)
+{
+	int ret = BCME_OK;
+	int i;
+	int val = 0;
+
+	/* Check that:
+	 * - values are in strict descending order.
+	 * - values are within the valid range.
+	 */
+	for (i = 0; i < array_size; i++) {
+		val = (int)array[i];
+		if (val == 0 && zero_terminated) {
+			ret = BCME_OK;
+			break;
+		}
+		if (val < range_lo || val > range_hi) {
+			/* array value out of range */
+			ret = BCME_RANGE;
+			break;
+		}
+	}
+	return ret;
+}
+
+/* Adds/replaces NVRAM variable with given value
+ * varbuf[in,out]   - Buffer with NVRAM variables (sequence of zero-terminated 'name=value' records,
+ *                    terminated with additional zero)
+ * buflen[in]       - Length of buffer (may, even should, have some unused space)
+ * variable[in]     - Variable to add/replace in 'name=value' form
+ * datalen[out,opt] - Optional output parameter - resulting length of data in buffer
+ * Returns TRUE on success, FALSE if buffer too short or variable specified incorrectly
+ */
+bool
+replace_nvram_variable(char *varbuf, unsigned int buflen, const char *variable,
+	unsigned int *datalen)
+{
+	char *p;
+	uint variable_heading_len, record_len, variable_record_len = strlen(variable) + 1;
+	char *buf_end = varbuf + buflen;
+	p = strchr(variable, '=');
+	if (!p) {
+		return FALSE;
+	}
+	/* Length of given variable name, followed by '=' */
+	variable_heading_len = (uint)((const char *)(p + 1) - variable);
+	/* Scanning NVRAM, record by record up to trailing 0 */
+	for (p = varbuf; *p; p += strlen(p) + 1) {
+		/* If given variable found - remove it */
+		if (!strncmp(p, variable, variable_heading_len)) {
+			record_len = strlen(p) + 1;
+			memmove_s(p, (size_t)(buf_end - p), p + record_len,
+				(size_t)(buf_end - (p + record_len)));
+		}
+	}
+	/* If buffer does not have space for given variable - return FALSE */
+	if ((p + variable_record_len + 1) > buf_end) {
+		return FALSE;
+	}
+	/* Copy given variable to end of buffer */
+	memmove_s(p, (size_t)(buf_end - p), variable, variable_record_len);
+	/* Adding trailing 0 */
+	p[variable_record_len] = 0;
+	/* Setting optional output parameter - length of data in buffer */
+	if (datalen) {
+		*datalen = (unsigned int)(p + variable_record_len + 1  - varbuf);
+	}
+	return TRUE;
+}
+
+/*
+ * Gets the ceil bit set to the nearest power of 2
+ * val[in]	- value for which nearest power of 2 bit set to be returned
+ * bitpos[out]	- the position of the nearest power of 2 bit set
+ */
+uint8
+bcm_get_ceil_pow_2(uint val)
+{
+	uint8 bitpos = 0;
+	ASSERT(val);
+	if (val & (val-1)) {
+		/* val is not powers of 2.
+		 * pad it, so that allocation will be aligned to
+		 * next immediate powers of 2.
+		 */
+		bitpos = 1;
+	}
+	while (val >>= 1) {
+		bitpos ++;
+	}
+	return (bitpos);
+}
+
+#if !defined(BCMDONGLEHOST)
+/** Initialization of varbuf structure */
+void
+varbuf_init(varbuf_t *b, char *buf, uint size)
+{
+	b->size = size;
+	b->base = b->buf = buf;
+}
+
+/** append a null terminated var=value string */
+int
+varbuf_append(varbuf_t *b, const char *fmt, ...)
+{
+	va_list ap;
+	int r;
+	size_t len;
+	char *s;
+
+	if (b->size < 2)
+	  return 0;
+
+	va_start(ap, fmt);
+	r = vsnprintf(b->buf, b->size, fmt, ap);
+	va_end(ap);
+
+	/* C99 snprintf behavior returns r >= size on overflow,
+	 * others return -1 on overflow.
+	 * All return -1 on format error.
+	 * We need to leave room for 2 null terminations, one for the current var
+	 * string, and one for final null of the var table. So check that the
+	 * strlen written, r, leaves room for 2 chars.
+	 */
+	if ((r == -1) || (r > (int)(b->size - 2))) {
+		b->size = 0;
+		return 0;
+	}
+
+	/* Remove any earlier occurrence of the same variable */
+	if ((s = strchr(b->buf, '=')) != NULL) {
+		len = (size_t)(s - b->buf);
+		for (s = b->base; s < b->buf;) {
+			if ((memcmp(s, b->buf, len) == 0) && s[len] == '=') {
+				len = strlen(s) + 1;
+				memmove(s, (s + len), (size_t)((b->buf + r + 1) - (s + len)));
+				b->buf -= len;
+				b->size += (unsigned int)len;
+				break;
+			}
+
+			while (*s++)
+				;
+		}
+	}
+
+	/* skip over this string's null termination */
+	r++;
+	b->size -= (uint)r;
+	b->buf += r;
+
+	return r;
+}
+
+#if defined(BCMDRIVER)
+/**
+ * Create variable table from memory.
+ * Return 0 on success, nonzero on error.
+ */
+int
+initvars_table(osl_t *osh, char *start, char *end, char **vars,
+	uint *count)
+{
+	uint c = (uint)(end - start);
+
+	/* do it only when there is more than just the null string */
+	if (c > 1) {
+		char *vp = MALLOCZ(osh, c);
+		ASSERT(vp != NULL);
+		if (!vp)
+			return BCME_NOMEM;
+		bcopy(start, vp, c);
+		*vars = vp;
+		*count = c;
+	}
+	else {
+		*vars = NULL;
+		*count = 0;
+	}
+
+	return 0;
+}
+#endif /* BCMDRIVER */
+
+#endif /* !BCMDONGLEHOST */
+
+/* bit shift operation in serialized buffer taking input bits % 8 */
+int buf_shift_right(uint8 *buf, uint16 len, uint8 bits)
+{
+	uint16 i;
+
+	if (len == 0 || (bits == 0) || (bits >= NBBY)) {
+		return BCME_BADARG;
+	}
+
+	for (i = len - 1u; i > 0; i--) {
+		buf[i] = (buf[i - 1u] << (NBBY - bits)) | (buf[i] >> bits);
+	}
+	buf[0] >>= bits;
+
+	return BCME_OK;
+}
+
+/* print the content of the 'buf' in hex string format */
+void
+prhexstr(const char *prefix, const uint8 *buf, uint len, bool newline)
+{
+	if (len > 0) {
+		uint i;
+
+		if (prefix != NULL) {
+			printf("%s", prefix);
+		}
+		for (i = 0; i < len; i ++) {
+			printf("%02X", buf[i]);
+		}
+		if (newline) {
+			printf("\n");
+		}
+	}
+}
+
+/* print the buffer in hex string format with the most significant byte first */
+void
+prhexstr_msb(const char *prefix, const uint8 *buf, uint len, bool newline)
+{
+	if (len > 0) {
+		int i;
+
+		if (prefix != NULL) {
+			printf("%s", prefix);
+		}
+		for (i = (int)len - 1; i >= 0; i --) {
+			printf("%02X", buf[i]);
+		}
+		if (newline) {
+			printf("\n");
+		}
+	}
+}
+
+#ifdef DONGLEBUILD
+static const char BCMPOST_TRAP_RODATA(bcm_print_string)[] = "%s";
+
+int
+BCMPOSTTRAPFN(print_string)(const char *str)
+{
+	return printf(bcm_print_string, str);
+}
+#endif /* DONGLEBUILD */
+
+#ifdef DBG_SEQ_LOG
+#define DBG_SEQ_SEQ_LOG_MAX 10000u
+
+#define DBG_SEQ_SEQ_START (1u << 12u)
+#define DBG_SEQ_SEQ_END   (1u << 13u)
+#define DBG_SEQ_SEQ_MASK   0xFFFu
+
+#define DBG_SEQ_SEQ_INC_UPDATE(id, seq, flags) \
+	do { \
+		g_dbg_seq_seq_idx[id]++; \
+		g_dbg_seq_seq_idx[id] %= DBG_SEQ_SEQ_LOG_MAX; \
+		g_dbg_seq_seq[id][g_dbg_seq_seq_idx[id]] = (seq & DBG_SEQ_SEQ_MASK) | flags; \
+	} while (0)
+
+uint16 g_dbg_seq_last_seq[DBG_SEQ_LOG_ID_MAX] = {0};
+uint16 g_dbg_seq_seq_exp[DBG_SEQ_LOG_ID_MAX] = {0};
+uint16 g_dbg_seq_seq_idx[DBG_SEQ_LOG_ID_MAX] = {0};
+uint16 g_dbg_seq_seq[DBG_SEQ_LOG_ID_MAX][DBG_SEQ_SEQ_LOG_MAX] = {0};
+uint32 g_dbg_seq_pkt[DBG_SEQ_SEQ_LOG_MAX] = {0};
+uint32 g_dbg_seq_pkt_prev_free[DBG_SEQ_SEQ_LOG_MAX] = {0};
+
+/**
+ * @brief Function to log the sequence numbers in a compreesed or uncompressed format.
+ *
+ * @param[in] id    Debug module ID. Refer to dbg_seq_log_id_t for possible values.
+ * @param[in] seq   Sequence number to log
+ * @param[in] arg1  User specific argument 1 to log
+ * @param[in] arg2  User specific argument 2 to log
+ */
+void dbg_seq_log_seq(dbg_seq_log_id_t id, uint16 seq, void *arg1, void *arg2)
+{
+#if DBG_SEQ_LOG_COMPRESSED
+	/* Storing the sequence numbers in compressed format */
+	if ((g_dbg_seq_seq[id][g_dbg_seq_seq_idx[id]] & DBG_SEQ_SEQ_START) &&
+			!(g_dbg_seq_seq[id][g_dbg_seq_seq_idx[id]] & DBG_SEQ_SEQ_END)) {
+		/* Continuation of the previous contigous logging */
+		if ((seq != g_dbg_seq_seq_exp[id]) || (seq == 0)) {
+			/* If we have received a dicontigous seq number or seq number restart then
+			 * close the logging and start new logging. If the seq numbers are
+			 * contigous, then we don't come here.
+			 */
+			if ((g_dbg_seq_seq[id][g_dbg_seq_seq_idx[id]] & DBG_SEQ_SEQ_MASK) ==
+					g_dbg_seq_last_seq[id]) {
+				/* If the contigous seq number count is just 1, then close the
+				 * current logging in the same index and start a new one.
+				 */
+				g_dbg_seq_seq[id][g_dbg_seq_seq_idx[id]] |= DBG_SEQ_SEQ_END;
+			} else {
+				/* If the contigous seq number count is > 1, then close the
+				 * current logging in the next index and start a new one.
+				 */
+				DBG_SEQ_SEQ_INC_UPDATE(id, g_dbg_seq_last_seq[id], DBG_SEQ_SEQ_END);
+			}
+			DBG_SEQ_SEQ_INC_UPDATE(id, seq, DBG_SEQ_SEQ_START);
+		}
+	} else {
+		/* Starting a fresh logging */
+		DBG_SEQ_SEQ_INC_UPDATE(id, seq, DBG_SEQ_SEQ_START);
+	}
+
+	g_dbg_seq_last_seq[id] = seq;
+	g_dbg_seq_seq_exp[id] = MODINC_POW2(seq, SEQNUM_MAX);
+#else
+	/* Storing the sequence numbers in un-compressed format */
+	DBG_SEQ_SEQ_INC_UPDATE(id, seq, (DBG_SEQ_SEQ_START | DBG_SEQ_SEQ_END));
+	g_dbg_seq_last_seq[id] = seq;
+
+	if (id == DBG_SEQ_LOG_ID_RX) {
+		g_dbg_seq_pkt[g_dbg_seq_seq_idx[id]] = (uint32)arg1;
+		g_dbg_seq_pkt_prev_free[g_dbg_seq_seq_idx[id]] = (uint32)arg2;
+	}
+#endif /* DBG_SEQ_LOG_COMPRESSED */
+}
+#endif /* DBG_SEQ_LOG */
+
+/* To be used in computing timestamps on log records. Applicable to dumps carrying
+ * enhanced timestamp records
+ * inputs:
+ * The latest Enhanced timestamp versioned message
+ * Log record time as a 64-bit value
+ * output:
+ * FW time of log record in ns
+ */
+
+#define BCMUTILS_EVENT_LOG_TS_CPU_FREQUENCY_MULTIPLE 1000u
+
+/* Adapted from version 1 timestamp computation in logprint.c:process_event_log_data() */
+static uint64
+bcmutils_event_log_compute_current_time_v1(ets_msg_t *ets_msg, uint32 log_record_time)
+{
+	uint32 base_cycles;
+	uint32 cpu_freq;
+	uint64 base_time;
+	int64 cycle_count_offset;
+
+	ets_msg_v1_t *ets_msg_v1 = (ets_msg_v1_t *)ets_msg;
+
+	/* ets_msg_v1->cyclecount is the ARM cycle count */
+	base_cycles = ets_msg_v1->cyclecount;
+	cpu_freq = ets_msg_v1->cpu_freq * BCMUTILS_EVENT_LOG_TS_CPU_FREQUENCY_MULTIPLE;
+
+	/* ets_msg_v1->timestamp is in ms and holds sys up time */
+	base_time = ets_msg_v1->timestamp;
+
+	cycle_count_offset = log_record_time - base_cycles;
+	if (cycle_count_offset >= 0) {
+		base_time += (log_record_time - base_cycles)/cpu_freq;
+	} else {
+		/* Negative cycle_count_offset == counter wrapped */
+		base_time += (log_record_time +
+				(0xffffffff - base_cycles))/cpu_freq;
+	}
+
+	/* basetime is in ms. convert to uint64 and return */
+	return base_time;
+}
+
+static uint64
+bcmutils_event_log_compute_current_time_v2(ets_msg_t *ets_msg, uint64 q4_log_record_time)
+{
+	ets_msg_v2_t *ets_msg_v2 = (ets_msg_v2_t *)ets_msg->data;
+	uint64 ets_msg_40bit_ptm_time = ets_msg_v2->ets_write_ptm_time & 0xFFFFFFFFFFULL;
+	uint64 el_40bit_log_record_time = q4_log_record_time << 8;
+
+	uint64 delta_time;
+
+	/* Corner case. The top 40 bits match indicating logging happened in the same time unit
+	 * as recorded RAW PTM time in the ETS message.
+	 */
+	if (q4_log_record_time == (ets_msg_40bit_ptm_time >> 8)) {
+		delta_time = 0;
+	} else {
+		delta_time = (el_40bit_log_record_time - ets_msg_40bit_ptm_time) &
+			0xFFFFFFFFFFULL;
+	}
+	return ets_msg_v2->sysuptime_ns + delta_time;
+}
+
+int
+bcmutils_event_log_compute_current_time(void *ets_msg, uint64 log_record_time, uint64 *current_time)
+{
+	ets_msg_t *ets_msg_ptr = (ets_msg_t *)ets_msg;
+
+	if (ets_msg_ptr == NULL) {
+		return BCME_ERROR;
+	}
+
+	if (ets_msg_ptr->version == ENHANCED_TS_MSG_VERSION_1) {
+		/* log record time is a 32-bit ARM cycle count */
+		*current_time = bcmutils_event_log_compute_current_time_v1(ets_msg_ptr,
+			(uint32) log_record_time);
+	} else if (ets_msg_ptr->version == ENHANCED_TS_MSG_VERSION_2) {
+		*current_time = bcmutils_event_log_compute_current_time_v2(ets_msg_ptr,
+			log_record_time);
+	} else {
+		return BCME_VERSION;
+	}
+
+	return BCME_OK;
+}
+
+#ifdef DBG_PKTID_POOLPKT_PROCESS
+uint16
+bcm_mwbmap_total_pktid(struct bcm_mwbmap * mwbmap_hdl)
+{
+	bcm_mwbmap_t * mwbmap_p;
+
+	BCM_MWBMAP_AUDIT(mwbmap_hdl);
+	mwbmap_p = BCM_MWBMAP_PTR(mwbmap_hdl);
+
+	return mwbmap_p->total;
+}
+#endif /* DBG_PKTID_POOLPKT_PROCESS */
+
+/**
+ * @brief Divide the uint64 dividend 'q' by 1,000
+ *
+ * @param[in] dividend
+ *
+ * @return    quotient
+ */
+uint64
+BCMPOSTTRAPFASTPATH(div_1K)(uint64 q)
+{
+	/** 1/1000 fractional bits: 0x004189374BC6A7EF(9DB)
+	 * shift until no leading zeros: 0x83126E97'8D4FDF3B S=9
+	 */
+
+	const uint64 d1 = 0x83126E97llu; // first 32 fractional bits
+	const uint64 d2 = 0x8D4FDF3Bllu; // second 32 fractional bits
+	const uint64 S  = 9llu;
+
+	uint64 a1;
+	uint64 a;  // answer
+	int carry;
+	uint32 a_low;
+	uint32 lo; // low 32 bits of quotient
+	uint32 hi; // high 32 bits of quotient
+
+	lo = (uint32)q;
+	hi = (uint32)(q >> 32u);
+
+	// fractional d1/d2 values truncate all lower order bits, so
+	// add a low order bit to make the fraction slightly higher than the
+	// exact 1/1000. This allows the final truncation of the answer to
+	// no come up short.
+	a1 = lo * (d1 + 1);
+	a  = hi * (d2 + 1) + a1;
+
+	// Detect carry
+	carry = (a < a1);
+
+	a_low = (uint32)(a >> 32u);
+
+	a = (hi * d1) + a_low;
+	if (carry) {
+		a += 0x100000000llu;
+	}
+	a = a >> S;
+
+	return a;
+}
+
+/**
+ * @brief Divide the uint64 dividend 'q' by 1,000,000
+ *
+ * @param[in] dividend
+ *
+ * @return    quotient
+ */
+uint64
+BCMPOSTTRAPFASTPATH(div_1M)(uint64 q)
+{
+	/** 1/1000000 fractional bits: 0x000010C6F7A0B5ED8D36B
+	 * shift until no leading zeros: 0x8637BD05'AF6C69B5 S=19
+	 */
+
+	const uint64 d1 = 0x8637BD05llu; // first 32 fractional bits
+	const uint64 d2 = 0xAF6C69B5llu; // second 32 fractional bits
+	const uint64 S = 19llu;
+
+	uint64 a1;
+	uint64 a;  // answer
+	int carry;
+	uint32 a_low;
+	uint32 lo; // low 32 bits of quotent
+	uint32 hi; // high 32 bits of quotent
+
+	lo = (uint32)q;
+	hi = (uint32)(q >> 32u);
+
+	// fractional d1/d2 values truncate all lower order bits, so
+	// add a low order bit to make the fraction slightly higher than the
+	// exact 1/1000. This allows the final truncation of the answer to
+	// no come up short.
+	a1 = lo * (d1 + 1);
+	a = hi * (d2 + 1) + a1;
+
+	// Detect carry
+	carry = (a < a1);
+
+	a_low = (uint32)(a >> 32u);
+
+	a = (hi * d1) + a_low;
+	if (carry) {
+		a += 0x100000000llu;
+	}
+	a = a >> S;
+
+	return a;
+}
+
+/* Add to adjust the 802.1x priority */
+void
+pktset8021xprio(void *pkt, int prio)
+{
+	struct ether_header *eh;
+	uint8 *pktdata;
+	if(prio == PKTPRIO(pkt))
+		return;
+	pktdata = (uint8 *)PKTDATA(OSH_NULL, pkt);
+	ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16)));
+	eh = (struct ether_header *) pktdata;
+	if (eh->ether_type == hton16(ETHER_TYPE_802_1X)) {
+		ASSERT(prio >= 0 && prio <= MAXPRIO);
+		PKTSETPRIO(pkt, prio);
+	}
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcmwifi_channels.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcmwifi_channels.c
@@ -0,0 +1,3352 @@
+/*
+ * Misc utility routines used by kernel or app-level.
+ * Contents are wifi-specific, used by any kernel or app-level
+ * software that might want wifi things as it grows.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Dual:>>
+ */
+
+#include <typedefs.h>
+#include <bcmutils.h>
+
+#ifdef BCMDRIVER
+#include <osl.h>
+#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
+#ifndef tolower
+#define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
+#endif
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#ifndef ASSERT
+#define ASSERT(exp)
+#endif
+#endif /* BCMDRIVER */
+
+#include <bcmwifi_channels.h>
+
+#if defined(WIN32) && (defined(BCMDLL) || defined(WLMDLL))
+#include <bcmstdlib.h>	/* For wlexe/Makefile.wlm_dll */
+#endif
+
+#include <802.11.h>
+#include <802.11ac.h>
+
+/* Definitions for D11AC capable (80MHz+) Chanspec type */
+
+/* Chanspec ASCII representation:
+ *
+ * [<band>'g']<channel>['/'<bandwidth>[<primary-sideband>]
+ *    ['/'<1st-channel-segment>'-'<2nd-channel-segment>]]
+ *
+ * <band>:
+ *      (optional) 2, 4, 5, 6 for 2.4GHz, 4GHz, 5GHz, and 6GHz respectively.
+ *      Default value is 2g if channel <= 14, otherwise 5g.
+ * <channel>:
+ *      channel number of the 20MHz channel,
+ *      or primary 20 MHz channel of 40MHz, 80MHz, 160MHz, 80+80MHz,
+ *      240MHz, 320MHz, or 160+160MHz channels.
+ * <bandwidth>:
+ *      (optional) 20, 40, 80, 160, 80+80, 240, 320, or 160+160. Default value is 20.
+ * <primary-sideband>:
+ *      'u' or 'l' (only for 2.4GHz band 40MHz)
+ *
+ *       For 2.4GHz band 40MHz channels, the same primary channel may be the
+ *       upper sideband for one 40MHz channel, and the lower sideband for an
+ *       overlapping 40MHz channel. The {u: upper, l: lower} primary sideband
+ *       indication disambiguates which 40MHz channel is being specified.
+ *
+ *       For 40MHz in the 5GHz or 6GHz band and all channel bandwidths greater than
+ *       40MHz, the U/L specification is not necessary or allowed since the channels are
+ *       non-overlapping and the primary 20MHz channel position is derived from its
+ *       position in the wide bandwidth channel.
+ * <1st-channel-segment>
+ * <2nd-channel-segment>:
+ *       Required for 80+80 or 160+160, otherwise not allowed.
+ *       These fields specify the center channel of the first and the second 80MHz
+ *       or 160MHz channels.
+ *
+ * In its simplest form, it is a 20MHz channel number, with the implied band
+ * of 2.4GHz if channel number <= 14, and 5GHz otherwise.
+ *
+ * To allow for backward compatibility with scripts, the old form for
+ * 40MHz channels is also allowed: <channel><primary-sideband>
+ *
+ * <channel>:
+ *	primary channel of 40MHz, channel <= 14 is 2GHz, otherwise 5GHz
+ * <primary-sideband>:
+ *	"U" for upper, "L" for lower (or lower case "u" "l")
+ *
+ * 5 GHz Examples:
+ *      Chanspec        BW        Center Ch  Channel Range  Primary Ch
+ *      5g8             20MHz     8          -              -
+ *      52              20MHz     52         -              -
+ *      52/40           40MHz     54         52-56          52
+ *      56/40           40MHz     54         52-56          56
+ *      52/80           80MHz     58         52-64          52
+ *      56/80           80MHz     58         52-64          56
+ *      60/80           80MHz     58         52-64          60
+ *      64/80           80MHz     58         52-64          64
+ *      52/160          160MHz    50         36-64          52
+ *      36/160          160MGz    50         36-64          36
+ *      36/80+80/42-106 80+80MHz  42,106     36-48,100-112  36
+ *
+ * 2 GHz Examples:
+ *      Chanspec        BW        Center Ch  Channel Range  Primary Ch
+ *      2g8             20MHz     8          -              -
+ *      8               20MHz     8          -              -
+ *      6               20MHz     6          -              -
+ *      6/40l           40MHz     8          6-10           6
+ *      6l              40MHz     8          6-10           6
+ *      6/40u           40MHz     4          2-6            6
+ *      6u              40MHz     4          2-6            6
+ */
+
+/* bandwidth ASCII string */
+static const char *wf_chspec_bw_str[] =
+{
+	"320",
+	"160+160",
+	"20",
+	"40",
+	"80",
+	"160",
+	"80+80",
+	"240"
+};
+
+static const uint16 wf_chspec_bw_mhz[] = {
+	320, 320, 20, 40, 80, 160, 160, 240
+};
+#define WF_NUM_BW ARRAYSIZE(wf_chspec_bw_mhz)
+
+/* 40MHz channels in 2.4GHz band */
+static const uint8 wf_2g_40m_chans[] = {
+	3, 4, 5, 6, 7, 8, 9, 10, 11
+};
+#define WF_NUM_2G_40M_CHANS ARRAYSIZE(wf_2g_40m_chans)
+
+/* 40MHz channels in 5GHz band */
+static const uint8 wf_5g_40m_chans[] = {
+	38, 46, 54, 62, 102, 110, 118, 126, 134, 142, 151, 159, 167, 175
+};
+#define WF_NUM_5G_40M_CHANS ARRAYSIZE(wf_5g_40m_chans)
+
+/* 80MHz channels in 5GHz band */
+static const uint8 wf_5g_80m_chans[] = {
+	42, 58, 106, 122, 138, 155, 171
+};
+#define WF_NUM_5G_80M_CHANS ARRAYSIZE(wf_5g_80m_chans)
+
+/* 160MHz channels in 5GHz band */
+static const uint8 wf_5g_160m_chans[] = {
+	50, 114, 163
+};
+#define WF_NUM_5G_160M_CHANS ARRAYSIZE(wf_5g_160m_chans)
+
+/** 80MHz channels in 6GHz band */
+#define WF_NUM_6G_80M_CHANS 14
+
+/** 160MHz channels in 6GHz band */
+#define WF_NUM_6G_160M_CHANS 7	/* TBD */
+
+/** 240MHz channels in 6GHz band */
+#define WF_NUM_6G_240M_CHANS 4 /* TBD */
+
+/** 320MHz channels in 6GHz band */
+#define WF_NUM_6G_320M_CHANS 3	/* TBD */
+
+/* Define the conditional macro to help with reducing the code size bloat
+ * in other branches and in trunk targets that don't need 11BE features...
+ */
+#define WFC_2VALS_EQ(var, val)	((var) == (val))
+
+/* compare bandwidth unconditionally for 11be related stuff */
+#ifdef WL11BE
+#define WFC_BW_EQ(bw, val)	WFC_2VALS_EQ(bw, val)
+#else
+#define WFC_BW_EQ(bw, val)	(FALSE)
+#endif
+
+/* compare bandwidth based on WFC_NON_CONT_CHAN */
+#ifdef WFC_NON_CONT_CHAN
+#define WFC_NCBW_EQ(bw, val)	WFC_2VALS_EQ(bw, val)
+#else
+#define WFC_NCBW_EQ(bw, val)	(FALSE)
+#endif
+
+static void wf_chanspec_iter_firstchan(wf_chanspec_iter_t *iter);
+static chanspec_bw_t wf_iter_next_bw(chanspec_bw_t bw);
+static bool wf_chanspec_iter_next_2g(wf_chanspec_iter_t *iter);
+static bool wf_chanspec_iter_next_5g(wf_chanspec_iter_t *iter);
+static int wf_chanspec_iter_next_5g_range(wf_chanspec_iter_t *iter, chanspec_bw_t bw);
+static void wf_chanspec_iter_6g_range_init(wf_chanspec_iter_t *iter, chanspec_bw_t bw);
+static bool wf_chanspec_iter_next_6g(wf_chanspec_iter_t *iter);
+
+/**
+ * Return the chanspec bandwidth in MHz
+ * Bandwidth of 160 MHz will be returned for 80+80MHz chanspecs.
+ *
+ * @param	chspec		chanspec_t
+ *
+ * @return	bandwidth of chspec in MHz units
+ */
+uint
+wf_bw_chspec_to_mhz(chanspec_t chspec)
+{
+	uint bw;
+
+	bw = (chspec & WL_CHANSPEC_BW_MASK) >> WL_CHANSPEC_BW_SHIFT;
+	return (bw >= WF_NUM_BW ? 0 : wf_chspec_bw_mhz[bw]);
+}
+
+/* bw in MHz, return the channel count from the center channel to the
+ * the channel at the edge of the band
+ */
+static uint
+center_chan_to_edge(chanspec_bw_t bw)
+{
+	uint delta = 0;
+
+	/* edge channels separated by BW - 10MHz on each side
+	 * delta from cf to edge is half of that,
+	 */
+	if (bw == WL_CHANSPEC_BW_40) {
+		/* 10 MHz */
+		delta = 2;
+	} else if (bw == WL_CHANSPEC_BW_80) {
+		/* 30 MHz */
+		delta = 6;
+	} else if (bw == WL_CHANSPEC_BW_160) {
+		/* 70 MHz */
+		delta = 14;
+	} else if (WFC_BW_EQ(bw, WL_CHANSPEC_BW_240)) {
+		/* 110 MHz */
+		delta = 22;
+	} else if (WFC_BW_EQ(bw, WL_CHANSPEC_BW_320)) {
+		/* 150 MHz */
+		delta = 30;
+	}
+	return delta;
+}
+
+/* return channel number of the low edge of the band
+ * given the center channel and BW
+ */
+static uint
+channel_low_edge(uint center_ch, chanspec_bw_t bw)
+{
+	return (center_ch - center_chan_to_edge(bw));
+}
+
+/* return side band number given center channel and primary20 channel
+ * return -1 on error
+ */
+static int
+channel_to_sb(uint center_ch, uint primary_ch, chanspec_bw_t bw)
+{
+	uint lowest = channel_low_edge(center_ch, bw);
+	uint sb;
+
+	if (primary_ch < lowest ||
+	    (primary_ch - lowest) % 4) {
+		/* bad primary channel lower than the low edge of the channel,
+		 * or not mult 4.
+		 */
+		return -1;
+	}
+
+	sb = ((primary_ch - lowest) / 4);
+
+	/* sb must be a index to a 20MHz channel in range */
+	if ((bw == WL_CHANSPEC_BW_20 && sb >= 1) ||
+	    (bw == WL_CHANSPEC_BW_40 && sb >= 2) ||
+	    (bw == WL_CHANSPEC_BW_80 && sb >= 4) ||
+	    (bw == WL_CHANSPEC_BW_160 && sb >= 8) ||
+	    (WFC_BW_EQ(bw, WL_CHANSPEC_BW_240) && sb >= 12) ||
+	    (WFC_BW_EQ(bw, WL_CHANSPEC_BW_320) && sb >= 16)) {
+		/* primary_ch must have been too high for the center_ch */
+		return -1;
+	}
+
+	return sb;
+}
+
+/* return primary20 channel given center channel and side band */
+static uint
+channel_to_primary20_chan(uint center_ch, chanspec_bw_t bw, uint sb)
+{
+	return (channel_low_edge(center_ch, bw) + sb * 4);
+}
+
+/* return index of 80MHz channel from channel number
+ * return -1 on error
+ */
+static int
+channel_80mhz_to_id(uint ch)
+{
+	uint i;
+	for (i = 0; i < WF_NUM_5G_80M_CHANS; i ++) {
+		if (ch == wf_5g_80m_chans[i])
+			return i;
+	}
+
+	return -1;
+}
+
+/* return index of the 6G 80MHz channel from channel number
+ * return -1 on error
+ */
+static int
+channel_6g_80mhz_to_id(uint ch)
+{
+	/* The 6GHz center channels start at 7, and have a spacing of 16 */
+	if (ch >= CH_MIN_6G_80M_CHANNEL &&
+	    ch <= CH_MAX_6G_80M_CHANNEL &&
+	    ((ch - CH_MIN_6G_80M_CHANNEL) % 16) == 0) {  // even multiple of 16
+		return (ch - CH_MIN_6G_80M_CHANNEL) / 16;
+	}
+
+	return -1;
+}
+
+/* return index of the 5G 160MHz channel from channel number
+ * return -1 on error
+ */
+static int
+channel_5g_160mhz_to_id(uint ch)
+{
+	uint i;
+	for (i = 0; i < WF_NUM_5G_160M_CHANS; i ++) {
+		if (ch == wf_5g_160m_chans[i]) {
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+/* return index of the 6G 160MHz channel from channel number
+ * return -1 on error
+ */
+static int
+channel_6g_160mhz_to_id(uint ch)
+{
+	/* The 6GHz center channels start at 15, and have a spacing of 32 */
+	if (ch >= CH_MIN_6G_160M_CHANNEL &&
+	    ch <= CH_MAX_6G_160M_CHANNEL &&
+	    ((ch - CH_MIN_6G_160M_CHANNEL) % 32) == 0) {
+		return (ch - CH_MIN_6G_160M_CHANNEL) / 32;
+	}
+
+	return -1;
+}
+
+/* return index of the 6G 240MHz channel from channel number
+ * return -1 on error
+ */
+static int
+channel_6g_240mhz_to_id(uint ch)
+{
+	/* The 6GHz center channels start at 23, and have a spacing of 48 */
+	if (ch >= CH_MIN_6G_240M_CHANNEL &&
+	    ch <= CH_MAX_6G_240M_CHANNEL &&
+	    ((ch - CH_MIN_6G_240M_CHANNEL) % 48) == 0) {
+		return (ch - CH_MIN_6G_240M_CHANNEL) / 48;
+	}
+
+	return -1;
+}
+
+/* return index of the 6G 320MHz channel from channel number
+ * return -1 on error
+ */
+static int
+channel_6g_320mhz_to_id(uint ch)
+{
+	/* The 6GHz center channels start at 31, and have a spacing of 64 */
+	if (ch >= CH_MIN_6G_320M_CHANNEL &&
+	    ch <= CH_MAX_6G_320M_CHANNEL &&
+	    ((ch - CH_MIN_6G_320M_CHANNEL) % 64) == 0) {
+		return (ch - CH_MIN_6G_320M_CHANNEL) / 64;
+	}
+
+	return -1;
+}
+
+/**
+ * This function returns the the 5GHz 80MHz center channel for the given chanspec 80MHz ID
+ *
+ * @param    chan_80MHz_id    80MHz chanspec ID
+ *
+ * @return   Return the center channel number, or 0 on error.
+ *
+ */
+static uint8
+wf_chspec_5G_id80_to_ch(uint8 chan_80MHz_id)
+{
+	if (chan_80MHz_id < WF_NUM_5G_80M_CHANS) {
+		return wf_5g_80m_chans[chan_80MHz_id];
+	}
+
+	return 0;
+}
+
+/**
+ * This function returns the the 6GHz 80MHz center channel for the given chanspec 80MHz ID
+ *
+ * @param    chan_80MHz_id    80MHz chanspec ID
+ *
+ * @return   Return the center channel number, or 0 on error.
+ *
+ */
+static uint8
+wf_chspec_6G_id80_to_ch(uint8 chan_80MHz_id)
+{
+	uint8 ch = 0;
+
+	if (chan_80MHz_id < WF_NUM_6G_80M_CHANS) {
+		/* The 6GHz center channels have a spacing of 16
+		 * starting from the first 80MHz center
+		 */
+		ch = CH_MIN_6G_80M_CHANNEL + (chan_80MHz_id * 16);
+	}
+
+	return ch;
+}
+
+/**
+ * This function returns the the 5GHz 160MHz center channel for the given chanspec 160MHz ID
+ *
+ * @param    chan_160MHz_id    160MHz chanspec ID
+ *
+ * @return   Return the center channel number, or 0 on error.
+ *
+ */
+static uint8
+wf_chspec_5G_id160_to_ch(uint8 chan_160MHz_id)
+{
+	if (chan_160MHz_id < WF_NUM_5G_160M_CHANS) {
+		return wf_5g_160m_chans[chan_160MHz_id];
+	}
+
+	return 0;
+}
+
+/**
+ * This function returns the the 6GHz 160MHz center channel for the given chanspec 160MHz ID
+ *
+ * @param    chan_160MHz_id    160MHz chanspec ID
+ *
+ * @return   Return the center channel number, or 0 on error.
+ *
+ */
+static uint8
+wf_chspec_6G_id160_to_ch(uint8 chan_160MHz_id)
+{
+	uint8 ch = 0;
+
+	if (chan_160MHz_id < WF_NUM_6G_160M_CHANS) {
+		/* The 6GHz center channels have a spacing of 32
+		 * starting from the first 160MHz center
+		 */
+		ch = CH_MIN_6G_160M_CHANNEL + (chan_160MHz_id * 32);
+	}
+
+	return ch;
+}
+
+/**
+ * This function returns the the 6GHz 240MHz center channel for the given chanspec 240MHz ID
+ *
+ * @param    chan_240MHz_id    240MHz chanspec ID
+ *
+ * @return   Return the center channel number, or 0 on error.
+ *
+ */
+static uint8
+wf_chspec_6G_id240_to_ch(uint8 chan_240MHz_id)
+{
+	uint8 ch = 0;
+
+	if (chan_240MHz_id < WF_NUM_6G_240M_CHANS) {
+		/* The 6GHz center channels have a spacing of 48
+		 * starting from the first 240MHz center
+		 */
+		ch = CH_MIN_6G_240M_CHANNEL + (chan_240MHz_id * 48);
+	}
+
+	return ch;
+}
+
+/* Retrive the chan_id and convert it to center channel */
+uint8
+wf_chspec_240_id2cch(chanspec_t chanspec)
+{
+	if (CHSPEC_BAND(chanspec) == WL_CHANSPEC_BAND_6G &&
+	    CHSPEC_BW(chanspec) == WL_CHANSPEC_BW_240) {
+		uint8 ch_id = CHSPEC_GE240_CHAN(chanspec);
+
+		return wf_chspec_6G_id240_to_ch(ch_id);
+	}
+	return 0;
+}
+
+/**
+ * This function returns the the 6GHz 320MHz center channel for the given chanspec 320MHz ID
+ *
+ * @param    chan_320MHz_id    320MHz chanspec ID
+ *
+ * @return   Return the center channel number, or 0 on error.
+ *
+ */
+static uint8
+wf_chspec_6G_id320_to_ch(uint8 chan_320MHz_id)
+{
+	uint8 ch = 0;
+
+	if (chan_320MHz_id < WF_NUM_6G_320M_CHANS) {
+		/* The 6GHz center channels have a spacing of 64
+		 * starting from the first 320MHz center
+		 */
+		ch = CH_MIN_6G_320M_CHANNEL + (chan_320MHz_id * 64);
+	}
+
+	return ch;
+}
+
+/* Retrive the chan_id and convert it to center channel */
+uint8
+wf_chspec_320_id2cch(chanspec_t chanspec)
+{
+	if (CHSPEC_BAND(chanspec) == WL_CHANSPEC_BAND_6G &&
+	    CHSPEC_BW(chanspec) == WL_CHANSPEC_BW_320) {
+		uint8 ch_id = CHSPEC_GE240_CHAN(chanspec);
+
+		return wf_chspec_6G_id320_to_ch(ch_id);
+	}
+	return 0;
+}
+
+/**
+ * Convert chanspec to ascii string, or formats hex of an invalid chanspec.
+ *
+ * @param	chspec   chanspec to format
+ * @param	buf      pointer to buf with room for at least CHANSPEC_STR_LEN bytes
+ *
+ * @return      Returns pointer to passed in buf. The buffer will have the ascii
+ *              representation of the given chspec, or "invalid 0xHHHH" where
+ *              0xHHHH is the hex representation of the invalid chanspec.
+ *
+ * @see		CHANSPEC_STR_LEN
+ *
+ * Wrapper function for wf_chspec_ntoa. In case of an error it puts
+ * the original chanspec in the output buffer, prepended with "invalid".
+ * Can be directly used in print routines as it takes care of null
+ */
+char *
+wf_chspec_ntoa_ex(chanspec_t chspec, char *buf)
+{
+	if (wf_chspec_ntoa(chspec, buf) == NULL)
+		snprintf(buf, CHANSPEC_STR_LEN, "invalid 0x%04x", chspec);
+	return buf;
+}
+
+/**
+ * Convert chanspec to ascii string, or return NULL on error.
+ *
+ * @param	chspec   chanspec to format
+ * @param	buf      pointer to buf with room for at least CHANSPEC_STR_LEN bytes
+ *
+ * @return      Returns pointer to passed in buf or NULL on error. On sucess, the buffer
+ *              will have the ascii representation of the given chspec.
+ *
+ * @see		CHANSPEC_STR_LEN
+ *
+ * Given a chanspec and a string buffer, format the chanspec as a
+ * string, and return the original pointer buf.
+ * Min buffer length must be CHANSPEC_STR_LEN.
+ * On error return NULL.
+ */
+char *
+wf_chspec_ntoa(chanspec_t chspec, char *buf)
+{
+	const char *band;
+	uint pri_chan;
+
+	if (wf_chspec_malformed(chspec))
+		return NULL;
+
+	band = "";
+
+	/* check for non-default band spec */
+	if (CHSPEC_IS2G(chspec) && CHSPEC_CHANNEL(chspec) > CH_MAX_2G_CHANNEL) {
+		band = "2g";
+	} else if (CHSPEC_IS5G(chspec) && CHSPEC_CHANNEL(chspec) <= CH_MAX_2G_CHANNEL) {
+		band = "5g";
+	} else if (CHSPEC_IS6G(chspec)) {
+		band = "6g";
+	}
+
+	/* primary20 channel */
+	pri_chan = wf_chspec_primary20_chan(chspec);
+
+	/* bandwidth and primary20 sideband */
+	if (CHSPEC_IS20(chspec)) {
+		snprintf(buf, CHANSPEC_STR_LEN, "%s%d", band, pri_chan);
+	} else if (CHSPEC_IS8080(chspec)) {
+		/* 80+80 */
+		uint ch0;
+		uint ch1;
+
+		/* get the center channels for each frequency segment */
+		if (CHSPEC_IS5G(chspec)) {
+			ch0 = wf_chspec_5G_id80_to_ch(CHSPEC_CHAN0(chspec));
+			ch1 = wf_chspec_5G_id80_to_ch(CHSPEC_CHAN1(chspec));
+		} else if (CHSPEC_IS6G(chspec)) {
+			ch0 = wf_chspec_6G_id80_to_ch(CHSPEC_CHAN0(chspec));
+			ch1 = wf_chspec_6G_id80_to_ch(CHSPEC_CHAN1(chspec));
+		} else {
+			return NULL;
+		}
+
+		/* Outputs a max of CHANSPEC_STR_LEN chars including '\0'  */
+		snprintf(buf, CHANSPEC_STR_LEN, "%s%d/80+80/%d-%d", band, pri_chan, ch0, ch1);
+	} else if (CHSPEC_IS240(chspec)) {
+		/* 240 */
+		const char *bw;
+
+		bw = wf_chspec_to_bw_str(chspec);
+
+		snprintf(buf, CHANSPEC_STR_LEN, "%s%d/%s", band, pri_chan, bw);
+	} else if (CHSPEC_IS320(chspec)) {
+		/* 320 */
+		const char *bw;
+
+		bw = wf_chspec_to_bw_str(chspec);
+
+		snprintf(buf, CHANSPEC_STR_LEN, "%s%d/%s", band, pri_chan, bw);
+	} else if (CHSPEC_IS160160(chspec)) {
+		/* 160+160 */
+		uint ch0;
+		uint ch1;
+
+		/* get the center channels for each frequency segment */
+		if (CHSPEC_IS5G(chspec)) {
+			ch0 = wf_chspec_5G_id160_to_ch(CHSPEC_CHAN0(chspec));
+			ch1 = wf_chspec_5G_id160_to_ch(CHSPEC_CHAN1(chspec));
+		} else if (CHSPEC_IS6G(chspec)) {
+			ch0 = wf_chspec_6G_id160_to_ch(CHSPEC_CHAN0(chspec));
+			ch1 = wf_chspec_6G_id160_to_ch(CHSPEC_CHAN1(chspec));
+		} else {
+			return NULL;
+		}
+
+		/* Outputs a max of CHANSPEC_STR_LEN chars including '\0'  */
+		snprintf(buf, CHANSPEC_STR_LEN, "%s%d/160+160/%d-%d", band, pri_chan, ch0, ch1);
+	} else {
+		const char *bw;
+		const char *sb = "";
+
+		bw = wf_chspec_to_bw_str(chspec);
+
+#ifdef CHANSPEC_NEW_40MHZ_FORMAT
+		/* primary20 sideband string if needed for 2g 40MHz */
+		if (CHSPEC_IS40(chspec) && CHSPEC_IS2G(chspec)) {
+			sb = CHSPEC_SB_UPPER(chspec) ? "u" : "l";
+		}
+
+		snprintf(buf, CHANSPEC_STR_LEN, "%s%d/%s%s", band, pri_chan, bw, sb);
+#else
+		/* primary20 sideband string instead of BW for 40MHz */
+		if (CHSPEC_IS40(chspec) && !CHSPEC_IS6G(chspec)) {
+			sb = CHSPEC_SB_UPPER(chspec) ? "u" : "l";
+			snprintf(buf, CHANSPEC_STR_LEN, "%s%d%s", band, pri_chan, sb);
+		} else {
+			snprintf(buf, CHANSPEC_STR_LEN, "%s%d/%s", band, pri_chan, bw);
+		}
+#endif /* CHANSPEC_NEW_40MHZ_FORMAT */
+	}
+
+	return (buf);
+}
+
+static int
+read_uint(const char **p, unsigned int *num)
+{
+	unsigned long val;
+	char *endp = NULL;
+
+	val = strtoul(*p, &endp, 10);
+	/* if endp is the initial pointer value, then a number was not read */
+	if (endp == *p)
+		return 0;
+
+	/* advance the buffer pointer to the end of the integer string */
+	*p = endp;
+	/* return the parsed integer */
+	*num = (unsigned int)val;
+
+	return 1;
+}
+
+/**
+ * Convert ascii string to chanspec
+ *
+ * @param	a     pointer to input string
+ *
+ * @return	Return > 0 if successful or 0 otherwise
+ */
+chanspec_t
+wf_chspec_aton(const char *a)
+{
+	chanspec_t chspec;
+	chanspec_band_t chspec_band;
+	chanspec_subband_t chspec_sb;
+	chanspec_bw_t chspec_bw;
+	uint bw;
+	uint num, pri_ch;
+	char c, sb_ul = '\0';
+
+	bw = 20;
+	chspec_sb = 0;
+
+	/* parse channel num or band */
+	if (!read_uint(&a, &num))
+		return 0;
+	/* if we are looking at a 'g', then the first number was a band */
+	c = tolower((int)a[0]);
+	if (c == 'g') {
+		a++; /* consume the char */
+
+		/* band must be "2", "5", or "6" */
+		if (num == 2)
+			chspec_band = WL_CHANSPEC_BAND_2G;
+		else if (num == 5)
+			chspec_band = WL_CHANSPEC_BAND_5G;
+		else if (num == 6)
+			chspec_band = WL_CHANSPEC_BAND_6G;
+		else
+			return 0;
+
+		/* read the channel number */
+		if (!read_uint(&a, &pri_ch))
+			return 0;
+
+		c = tolower((int)a[0]);
+	} else {
+		/* first number is channel, use default for band */
+		pri_ch = num;
+		chspec_band = ((pri_ch <= CH_MAX_2G_CHANNEL) ?
+		               WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);
+	}
+
+	if (c == '\0') {
+		/* default BW of 20MHz */
+		chspec_bw = WL_CHANSPEC_BW_20;
+		goto done_read;
+	}
+
+	a ++; /* consume the 'u','l', or '/' */
+
+	/* check 'u'/'l' */
+	if (c == 'u' || c == 'l') {
+		sb_ul = c;
+		chspec_bw = WL_CHANSPEC_BW_40;
+		goto done_read;
+	}
+
+	/* next letter must be '/' */
+	if (c != '/')
+		return 0;
+
+	/* read bandwidth */
+	if (!read_uint(&a, &bw))
+		return 0;
+
+	/* convert to chspec value */
+	if (bw == 20) {
+		chspec_bw = WL_CHANSPEC_BW_20;
+	} else if (bw == 40) {
+		chspec_bw = WL_CHANSPEC_BW_40;
+	} else if (bw == 80) {
+		chspec_bw = WL_CHANSPEC_BW_80;
+	} else if (bw == 160) {
+		chspec_bw = WL_CHANSPEC_BW_160;
+	} else if (WFC_BW_EQ(bw, 240)) {
+		chspec_bw = WL_CHANSPEC_BW_240;
+	} else if (WFC_BW_EQ(bw, 320)) {
+		chspec_bw = WL_CHANSPEC_BW_320;
+	} else {
+		return 0;
+	}
+
+	/* So far we have <band>g<chan>/<bw>
+	 * Can now be followed by u/l if bw = 40,
+	 */
+
+	c = tolower((int)a[0]);
+
+	/* if we have a 2g/40 channel, we should have a l/u spec now */
+	if (chspec_band == WL_CHANSPEC_BAND_2G && bw == 40) {
+		if (c == 'u' || c == 'l') {
+			a ++; /* consume the u/l char */
+			sb_ul = c;
+			goto done_read;
+		}
+	}
+
+	/* check for 80+80 or 160+160 */
+	if (c == '+') {
+		return 0;
+	}
+
+done_read:
+	/* skip trailing white space */
+	while (a[0] == ' ') {
+		a ++;
+	}
+
+	/* must be end of string */
+	if (a[0] != '\0')
+		return 0;
+
+	/* Now have all the chanspec string parts read;
+	 * chspec_band, pri_ch, chspec_bw, sb_ul.
+	 * chspec_band and chspec_bw are chanspec values.
+	 * Need to convert pri_ch, and sb_ul into
+	 * a center channel (or two) and sideband.
+	 */
+
+	/* if a sb u/l string was given, just use that,
+	 * guaranteed to be bw = 40 by string parse.
+	 */
+	if (sb_ul != '\0') {
+		if (sb_ul == 'l') {
+			chspec_sb = WL_CHANSPEC_CTL_SB_LLL;
+		} else if (sb_ul == 'u') {
+			chspec_sb = WL_CHANSPEC_CTL_SB_LLU;
+		}
+		chspec = wf_create_40MHz_chspec_primary_sb(pri_ch, chspec_sb, chspec_band);
+	} else if (chspec_bw == WL_CHANSPEC_BW_20) {
+		/* if the bw is 20, only need the primary channel and band */
+		chspec = wf_create_20MHz_chspec(pri_ch, chspec_band);
+	} else {
+		/* If the bw is 40/80/160/240/320 (and not 40MHz 2G), the channels are
+		 * non-overlapping in 5G or 6G bands. Each primary channel is contained
+		 * in only one higher bandwidth channel. The wf_create_chspec_from_primary()
+		 * will create the chanspec. 2G 40MHz is handled just above, assuming a {u,l}
+		 * sub-band spec was given.
+		 */
+		chspec = wf_create_chspec_from_primary(pri_ch, chspec_bw, chspec_band);
+	}
+
+	if (wf_chspec_malformed(chspec))
+		return 0;
+
+	return chspec;
+}
+
+/**
+ * Verify the chanspec is using a legal set of parameters, i.e. that the
+ * chanspec specified a band, bw, pri_sb and channel and that the
+ * combination could be legal given any set of circumstances.
+ *
+ * @param  chanspec   the chanspec to check
+ *
+ * @return Returns TRUE if the chanspec is malformed, FALSE if it looks good.
+ */
+bool
+#ifdef BCMPOSTTRAPFN
+BCMPOSTTRAPFN(wf_chspec_malformed)(chanspec_t chanspec)
+#else
+wf_chspec_malformed(chanspec_t chanspec)
+#endif
+{
+	uint chspec_bw = CHSPEC_BW(chanspec);
+	uint chspec_sb;
+
+	if (CHSPEC_IS2G(chanspec)) {
+		/* must be valid bandwidth for 2G */
+		if (!BW_LE40(chspec_bw)) {
+			return TRUE;
+		}
+
+		/* check for invalid channel number */
+		if (CHSPEC_CHANNEL(chanspec) == INVCHANNEL) {
+			return TRUE;
+		}
+	} else if (CHSPEC_IS5G(chanspec) || CHSPEC_IS6G(chanspec)) {
+		if (WFC_BW_EQ(chspec_bw, WL_CHANSPEC_BW_240)) {
+			uint ch_id;
+
+			ch_id = CHSPEC_GE240_CHAN(chanspec);
+
+			/* channel IDs in 240 must be in range */
+			if (CHSPEC_IS6G(chanspec)) {
+				if (ch_id >= WF_NUM_6G_240M_CHANS) {
+					/* bad 240MHz channel ID for the band */
+					return TRUE;
+				}
+			} else {
+				return TRUE;
+			}
+		} else if (WFC_BW_EQ(chspec_bw, WL_CHANSPEC_BW_320)) {
+			uint ch_id;
+
+			ch_id = CHSPEC_GE240_CHAN(chanspec);
+
+			/* channel IDs in 320 must be in range */
+			if (CHSPEC_IS6G(chanspec)) {
+				if (ch_id >= WF_NUM_6G_320M_CHANS) {
+					/* bad 320MHz channel ID for the band */
+					return TRUE;
+				}
+			} else {
+				return TRUE;
+			}
+		} else if (WFC_NCBW_EQ(chspec_bw, WL_CHANSPEC_BW_160160)) {
+			uint ch0_id, ch1_id;
+
+			ch0_id = CHSPEC_CHAN0(chanspec);
+			ch1_id = CHSPEC_CHAN1(chanspec);
+
+			/* channel IDs in 160+160 must be in range */
+			if (CHSPEC_IS5G(chanspec) &&
+			    (ch0_id >= WF_NUM_5G_160M_CHANS || ch1_id >= WF_NUM_5G_160M_CHANS)) {
+				/* bad 160MHz channel ID for the band */
+				return TRUE;
+			}
+			if (CHSPEC_IS6G(chanspec) &&
+			    (ch0_id >= WF_NUM_6G_160M_CHANS || ch1_id >= WF_NUM_6G_160M_CHANS)) {
+				/* bad 160MHz channel ID for the band */
+				return TRUE;
+			}
+		} else if (WFC_NCBW_EQ(chspec_bw, WL_CHANSPEC_BW_8080)) {
+			uint ch0_id, ch1_id;
+
+			ch0_id = CHSPEC_CHAN0(chanspec);
+			ch1_id = CHSPEC_CHAN1(chanspec);
+
+			/* channel IDs in 80+80 must be in range */
+			if (CHSPEC_IS5G(chanspec) &&
+			    (ch0_id >= WF_NUM_5G_80M_CHANS || ch1_id >= WF_NUM_5G_80M_CHANS)) {
+				/* bad 80MHz channel ID for the band */
+				return TRUE;
+			}
+			if (CHSPEC_IS6G(chanspec) &&
+			    (ch0_id >= WF_NUM_6G_80M_CHANS || ch1_id >= WF_NUM_6G_80M_CHANS)) {
+				/* bad 80MHz channel ID for the band */
+				return TRUE;
+			}
+		} else if (chspec_bw == WL_CHANSPEC_BW_20 || chspec_bw == WL_CHANSPEC_BW_40 ||
+		           chspec_bw == WL_CHANSPEC_BW_80 || chspec_bw == WL_CHANSPEC_BW_160) {
+
+			/* check for invalid channel number */
+			if (CHSPEC_CHANNEL(chanspec) == INVCHANNEL) {
+				return TRUE;
+			}
+		} else {
+			/* invalid bandwidth */
+			return TRUE;
+		}
+	} else {
+		/* must be a valid band */
+		return TRUE;
+	}
+
+	/* retrive sideband */
+	if ((WFC_BW_EQ(chspec_bw, WL_CHANSPEC_BW_240)) ||
+			(WFC_BW_EQ(chspec_bw, WL_CHANSPEC_BW_320))) {
+		chspec_sb = CHSPEC_GE240_SB(chanspec);
+	} else {
+		chspec_sb = CHSPEC_CTL_SB(chanspec);
+	}
+
+	/* side band needs to be consistent with bandwidth */
+	if (chspec_bw == WL_CHANSPEC_BW_20) {
+		if (chspec_sb != WL_CHANSPEC_CTL_SB_LLL)
+			return TRUE;
+	} else if (chspec_bw == WL_CHANSPEC_BW_40) {
+		if (chspec_sb > WL_CHANSPEC_CTL_SB_LLU)
+			return TRUE;
+	} else if (chspec_bw == WL_CHANSPEC_BW_80 ||
+	           WFC_NCBW_EQ(chspec_bw, WL_CHANSPEC_BW_8080)) {
+		/* both 80MHz and 80+80MHz use 80MHz side bands.
+		 * 80+80 SB info is relative to the primary 80MHz sub-band.
+		 */
+		if (chspec_sb > WL_CHANSPEC_CTL_SB_LUU)
+			return TRUE;
+	} else if (chspec_bw == WL_CHANSPEC_BW_160 ||
+	           WFC_NCBW_EQ(chspec_bw, WL_CHANSPEC_BW_160160)) {
+		ASSERT(chspec_sb <= WL_CHANSPEC_CTL_SB_UUU);
+	} else if (WFC_BW_EQ(chspec_bw, WL_CHANSPEC_BW_240)) {
+		/* FIXME: define the max sideband index */
+		ASSERT((chspec_sb >> WL_CHANSPEC_GE240_SB_SHIFT) <= 11);
+	} else if (WFC_BW_EQ(chspec_bw, WL_CHANSPEC_BW_320)) {
+		/* FIXME: define the max sideband index */
+		ASSERT((chspec_sb >> WL_CHANSPEC_GE240_SB_SHIFT) <= 15);
+	}
+
+	return FALSE;
+}
+
+/**
+ * Verify the chanspec specifies a valid channel according to 802.11.
+ *
+ * @param   chanspec     the chanspec to check
+ *
+ * @return  Returns TRUE if the chanspec is a valid 802.11 channel
+ */
+bool
+wf_chspec_valid(chanspec_t chanspec)
+{
+	chanspec_band_t chspec_band = CHSPEC_BAND(chanspec);
+	chanspec_bw_t chspec_bw = CHSPEC_BW(chanspec);
+	uint chspec_ch = -1;
+
+	if (wf_chspec_malformed(chanspec)) {
+		return FALSE;
+	}
+
+	if (WFC_BW_EQ(chspec_bw, WL_CHANSPEC_BW_240)) {
+		if (CHSPEC_IS6G(chanspec)) {
+			chspec_ch = wf_chspec_6G_id240_to_ch(CHSPEC_GE240_CHAN(chanspec));
+		} else {
+			return FALSE;
+		}
+	} else if (WFC_BW_EQ(chspec_bw, WL_CHANSPEC_BW_320)) {
+		if (CHSPEC_IS6G(chanspec)) {
+			chspec_ch = wf_chspec_6G_id320_to_ch(CHSPEC_GE240_CHAN(chanspec));
+		} else {
+			return FALSE;
+		}
+	} else {
+		chspec_ch = CHSPEC_CHANNEL(chanspec);
+	}
+
+	/* After the malformed check, we know that we have
+	 * a valid band field,
+	 * a valid bandwidth for the band,
+	 * and a valid sub-band value for the bandwidth.
+	 *
+	 * Since all sub-band specs are valid for any channel, the only thing remaining to
+	 * check is that
+	 *   the 20MHz channel,
+	 *   or the center channel for higher BW,
+	 *   or both center channels for an 80+80MHz channel,
+	 * are valid for the specified band.
+	 * Also, 80+80MHz channels need to be non-contiguous.
+	 */
+
+	if (chspec_bw == WL_CHANSPEC_BW_20) {
+
+		return wf_valid_20MHz_chan(chspec_ch, chspec_band);
+
+	} else if (chspec_bw == WL_CHANSPEC_BW_40) {
+
+		return wf_valid_40MHz_center_chan(chspec_ch, chspec_band);
+
+	} else if (chspec_bw == WL_CHANSPEC_BW_80) {
+
+		return wf_valid_80MHz_center_chan(chspec_ch, chspec_band);
+
+	} else if (chspec_bw == WL_CHANSPEC_BW_160) {
+
+		return wf_valid_160MHz_center_chan(chspec_ch, chspec_band);
+
+	} else if (WFC_BW_EQ(chspec_bw, WL_CHANSPEC_BW_240)) {
+
+		return wf_valid_240MHz_center_chan(chspec_ch, chspec_band);
+
+	} else if (WFC_BW_EQ(chspec_bw, WL_CHANSPEC_BW_320)) {
+
+		return wf_valid_320MHz_center_chan(chspec_ch, chspec_band);
+
+	} else if (WFC_NCBW_EQ(chspec_bw, WL_CHANSPEC_BW_8080)) {
+		uint16 ch0 = 0;
+		uint16 ch1 = 0;
+
+		/* get the center channels for each frequency segment */
+		if (CHSPEC_IS5G(chanspec)) {
+			ch0 = wf_chspec_5G_id80_to_ch(CHSPEC_CHAN0(chanspec));
+			ch1 = wf_chspec_5G_id80_to_ch(CHSPEC_CHAN1(chanspec));
+		} else if (CHSPEC_IS6G(chanspec)) {
+			ch0 = wf_chspec_6G_id80_to_ch(CHSPEC_CHAN0(chanspec));
+			ch1 = wf_chspec_6G_id80_to_ch(CHSPEC_CHAN1(chanspec));
+		} else {
+			return FALSE;
+		}
+
+		/* the two channels must be separated by more than 80MHz by VHT req */
+		if ((ch1 > ch0 + CH_80MHZ_APART) ||
+		    (ch0 > ch1 + CH_80MHZ_APART))
+			return TRUE;
+	} else if (WFC_NCBW_EQ(chspec_bw, WL_CHANSPEC_BW_160160)) {
+		uint16 ch0 = 0;
+		uint16 ch1 = 0;
+
+		/* get the center channels for each frequency segment */
+		if (CHSPEC_IS5G(chanspec)) {
+			ch0 = wf_chspec_5G_id160_to_ch(CHSPEC_CHAN0(chanspec));
+			ch1 = wf_chspec_5G_id160_to_ch(CHSPEC_CHAN1(chanspec));
+		} else if (CHSPEC_IS6G(chanspec)) {
+			ch0 = wf_chspec_6G_id160_to_ch(CHSPEC_CHAN0(chanspec));
+			ch1 = wf_chspec_6G_id160_to_ch(CHSPEC_CHAN1(chanspec));
+		} else {
+			return FALSE;
+		}
+
+		/* the two channels must be separated by more than 160MHz by EHT req */
+		if ((ch1 > ch0 + CH_160MHZ_APART) ||
+		    (ch0 > ch1 + CH_160MHZ_APART)) {
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+/* 5G band 20MHz channel ranges with even (+4) channel spacing */
+static const struct wf_iter_range wf_5g_iter_ranges[] = {
+	{36, 64},
+	{100, 144},
+	{149, 165}
+};
+
+#define RANGE_ID_INVAL 0xFFu
+enum wf_iter_state {
+	WF_ITER_INIT = 0,
+	WF_ITER_RUN  = 1,
+	WF_ITER_DONE = 2
+};
+
+/**
+ * @brief  Initialize a chanspec iteration structure.
+ */
+bool
+wf_chanspec_iter_init(wf_chanspec_iter_t *iter, chanspec_band_t band, chanspec_bw_t bw)
+{
+	if (iter == NULL) {
+		return FALSE;
+	}
+
+	/* Initialize the iter structure to the "DONE" state
+	 * in case the parameter validation fails.
+	 * If the validation fails then the iterator will return INVCHANSPEC as the current
+	 * chanspec, and wf_chanspec_iter_next() will return FALSE.
+	 */
+	memset(iter, 0, sizeof(*iter));
+	iter->state = WF_ITER_DONE;
+	iter->chanspec = INVCHANSPEC;
+
+	if (band != WL_CHANSPEC_BAND_2G &&
+	    band != WL_CHANSPEC_BAND_5G &&
+	    band != WL_CHANSPEC_BAND_6G) {
+		ASSERT(0);
+		return FALSE;
+	}
+
+	/* make sure the BW is unspecified (INVCHANSPEC), 20/40,
+	 * or (not 2g and 80/160)
+	 */
+	if (!(bw == INVCHANSPEC ||
+	      bw == WL_CHANSPEC_BW_20 ||
+	      bw == WL_CHANSPEC_BW_40 ||
+	      (band != WL_CHANSPEC_BAND_2G &&
+	       (bw == WL_CHANSPEC_BW_80 ||
+	        bw == WL_CHANSPEC_BW_160 ||
+		WFC_BW_EQ(bw, WL_CHANSPEC_BW_240) ||
+	        WFC_BW_EQ(bw, WL_CHANSPEC_BW_320))))) {
+
+		ASSERT(0);
+		return FALSE;
+	}
+
+	/* Validation of the params is successful so move to the "INIT" state to
+	 * allow the first wf_chanspec_iter_next() move the iteration to the first
+	 * chanspec in the set.
+	 */
+	iter->state = WF_ITER_INIT;
+	iter->band = band;
+	iter->bw = bw;
+	iter->range_id = RANGE_ID_INVAL;
+
+	return TRUE;
+}
+
+/**
+ * Start the iterator off from the 'init' state.
+ * The internal state is set up and advanced to the first chanspec.
+ */
+static void
+wf_chanspec_iter_firstchan(wf_chanspec_iter_t *iter)
+{
+	chanspec_band_t band = iter->band;
+	chanspec_bw_t bw = iter->bw;
+	chanspec_t chspec;
+
+	/* if BW unspecified (INVCHANSPEC), start with 20 MHz */
+	if (bw == INVCHANSPEC) {
+		bw = WL_CHANSPEC_BW_20;
+	}
+
+	/* calc the initial channel based on band */
+	if (band == WL_CHANSPEC_BAND_2G) {
+		/* 2g has overlapping 40MHz channels, so cannot just use the
+		 * wf_create_chspec_from_primary() fn.
+		 */
+		if (bw == WL_CHANSPEC_BW_20) {
+			chspec = wf_create_20MHz_chspec(CH_MIN_2G_CHANNEL, band);
+		} else {
+			chspec = (WL_CHANSPEC_BAND_2G | bw | WL_CHANSPEC_CTL_SB_L |
+			          CH_MIN_2G_40M_CHANNEL);
+		}
+	} else {
+		if (band == WL_CHANSPEC_BAND_5G) {
+			wf_chanspec_iter_next_5g_range(iter, bw);
+		} else {
+			wf_chanspec_iter_6g_range_init(iter, bw);
+		}
+		chspec = wf_create_chspec_from_primary(iter->range.start, bw, band);
+	}
+
+	iter->chanspec = chspec;
+}
+
+/**
+ * @brief Return the current chanspec of the iteration.
+ */
+chanspec_t
+wf_chanspec_iter_current(wf_chanspec_iter_t *iter)
+{
+	return iter->chanspec;
+}
+
+/**
+ * @brief Advance the iteration to the next chanspec in the set.
+ */
+bool
+wf_chanspec_iter_next(wf_chanspec_iter_t *iter, chanspec_t *chspec)
+{
+	bool ok = FALSE;
+	chanspec_band_t band = iter->band;
+
+	/* Handle the INIT and DONE states. Otherwise, we are in the RUN state
+	 * and will dispatch to the 'next' function for the appropriate band.
+	 */
+	if (iter->state == WF_ITER_INIT) {
+		iter->state = WF_ITER_RUN;
+		wf_chanspec_iter_firstchan(iter);
+		ok = TRUE;
+	} else if (iter->state == WF_ITER_DONE) {
+		ok = FALSE;
+	} else if (band == WL_CHANSPEC_BAND_2G) {
+		ok = wf_chanspec_iter_next_2g(iter);
+	} else if (band == WL_CHANSPEC_BAND_5G) {
+		ok = wf_chanspec_iter_next_5g(iter);
+	} else if (band == WL_CHANSPEC_BAND_6G) {
+		ok = wf_chanspec_iter_next_6g(iter);
+	}
+
+	/* Return the new chanspec if a pointer was provided.
+	 * In case the iteration is done, the return will be INVCHANSPEC.
+	 */
+	if (chspec != NULL) {
+		*chspec = iter->chanspec;
+	}
+
+	return ok;
+}
+
+/**
+ * When the iterator completes a particular bandwidth, this function
+ * returns the next BW, or INVCHANSPEC when done.
+ *
+ * Internal iterator helper.
+ */
+static chanspec_bw_t
+wf_iter_next_bw(chanspec_bw_t bw)
+{
+	switch (bw) {
+	case WL_CHANSPEC_BW_20:
+		bw = WL_CHANSPEC_BW_40;
+		break;
+	case WL_CHANSPEC_BW_40:
+		bw = WL_CHANSPEC_BW_80;
+		break;
+	case WL_CHANSPEC_BW_80:
+		bw = WL_CHANSPEC_BW_160;
+		break;
+#ifdef WL11BE
+	case WL_CHANSPEC_BW_160:
+		bw = WL_CHANSPEC_BW_240;
+		break;
+	case WL_CHANSPEC_BW_240:
+		bw = WL_CHANSPEC_BW_320;
+		break;
+#endif
+	default:
+		bw = INVCHANSPEC;
+		break;
+	}
+	return bw;
+}
+
+/**
+ * This is the _iter_next() helper for 2g band chanspec iteration.
+ */
+static bool
+wf_chanspec_iter_next_2g(wf_chanspec_iter_t *iter)
+{
+	chanspec_t chspec = iter->chanspec;
+	uint8 ch = CHSPEC_CHANNEL(chspec);
+
+	if (CHSPEC_IS20(chspec)) {
+		if (ch < CH_MAX_2G_CHANNEL) {
+			ch++;
+			chspec = wf_create_20MHz_chspec(ch, WL_CHANSPEC_BAND_2G);
+		} else if (iter->bw == INVCHANSPEC) {
+			/* hit the end of 20M channels, go to 40M if bw was unspecified */
+			ch = CH_MIN_2G_40M_CHANNEL;
+			chspec = wf_create_40MHz_chspec(LOWER_20_SB(ch), ch, WL_CHANSPEC_BAND_2G);
+		} else {
+			/* done */
+			iter->state = WF_ITER_DONE;
+			chspec = INVCHANSPEC;
+		}
+	} else {
+		/* step through low then high primary sideband, then next 40 center channel */
+		if (CHSPEC_SB_LOWER(iter->chanspec)) {
+			/* move from lower primary 20 to upper */
+			chspec = wf_create_40MHz_chspec(UPPER_20_SB(ch),
+			                                ch, WL_CHANSPEC_BAND_2G);
+		} else if (ch < CH_MAX_2G_40M_CHANNEL) {
+			/* move to next 40M center and lower primary 20 */
+			ch++;
+			chspec = wf_create_40MHz_chspec(LOWER_20_SB(ch),
+			                                ch, WL_CHANSPEC_BAND_2G);
+		} else {
+			/* done */
+			iter->state = WF_ITER_DONE;
+			chspec = INVCHANSPEC;
+		}
+	}
+
+	iter->chanspec = chspec;
+
+	return (chspec != INVCHANSPEC);
+}
+
+/**
+ * This is the _iter_next() helper for 5g band chanspec iteration.
+ * The 5g iterator uses ranges of primary 20MHz channels, and the current BW, to create
+ * each chanspec in the set.
+ * When a 5g range is exhausted, wf_chanspec_iter_next_5g_range() is called to get the next
+ * range appropriate to the current BW.
+ */
+static bool
+wf_chanspec_iter_next_5g(wf_chanspec_iter_t *iter)
+{
+	chanspec_t chspec = iter->chanspec;
+	chanspec_bw_t bw = CHSPEC_BW(chspec);
+	uint8 ch = wf_chspec_primary20_chan(chspec);
+	uint8 end = iter->range.end;
+
+	if (ch < end) {
+		/* not at the end of the current range, so
+		 * step to the next 20MHz channel and create the current BW
+		 * channel with that new primary 20MHz.
+		 */
+		ch += CH_20MHZ_APART;
+	} else if (wf_chanspec_iter_next_5g_range(iter, bw)) {
+		/* there was a new range in the current BW, so start at the beginning */
+		ch = iter->range.start;
+	} else if (iter->bw == INVCHANSPEC) {
+		/* hit the end of current bw, so move to the next bw */
+		bw = wf_iter_next_bw(bw);
+		if (bw != INVCHANSPEC) {
+			/* initialize the first range */
+			iter->range_id = RANGE_ID_INVAL;
+			wf_chanspec_iter_next_5g_range(iter, bw);
+			ch = iter->range.start;
+		} else {
+			/* no more BWs */
+			chspec = INVCHANSPEC;
+		}
+	} else {
+		/* no more channels, ranges, or BWs */
+		chspec = INVCHANSPEC;
+	}
+
+	/* if we are not at the end of the iteration, calc the next chanspec from components */
+	if (chspec != INVCHANSPEC) {
+		chspec = wf_create_chspec_from_primary(ch, bw, WL_CHANSPEC_BAND_5G);
+	}
+
+	iter->chanspec = chspec;
+	if (chspec != INVCHANSPEC) {
+		return TRUE;
+	} else {
+		iter->state = WF_ITER_DONE;
+		return FALSE;
+	}
+}
+
+/**
+ * Helper function to set up the next range of primary 20MHz channels to
+ * iterate over for the current BW. This will advance
+ *    iter->range_id
+ * and set up
+ *    iter->range.start
+ *    iter->range.end
+ * for the new range.
+ * Returns FALSE if there are no more ranges in the current BW.
+ */
+static int
+wf_chanspec_iter_next_5g_range(wf_chanspec_iter_t *iter, chanspec_bw_t bw)
+{
+	uint8 range_id = iter->range_id;
+	const uint8 *channels;
+	uint count;
+
+	if (bw == WL_CHANSPEC_BW_20) {
+		if (range_id == RANGE_ID_INVAL) {
+			range_id = 0;
+		} else {
+			range_id++;
+		}
+
+		if (range_id < ARRAYSIZE(wf_5g_iter_ranges)) {
+			iter->range_id = range_id;
+			iter->range = wf_5g_iter_ranges[range_id];
+			return TRUE;
+		}
+
+		return FALSE;
+	}
+
+	if (bw == WL_CHANSPEC_BW_40) {
+		channels = wf_5g_40m_chans;
+		count = WF_NUM_5G_40M_CHANS;
+	} else if (bw == WL_CHANSPEC_BW_80) {
+		channels = wf_5g_80m_chans;
+		count = WF_NUM_5G_80M_CHANS;
+	} else if (bw == WL_CHANSPEC_BW_160) {
+		channels = wf_5g_160m_chans;
+		count = WF_NUM_5G_160M_CHANS;
+	} else {
+		return FALSE;
+	}
+
+	if (range_id == RANGE_ID_INVAL) {
+		range_id = 0;
+	} else {
+		range_id++;
+	}
+	if (range_id < count) {
+		uint8 ch = channels[range_id];
+		uint offset = center_chan_to_edge(bw);
+
+		iter->range_id = range_id;
+		iter->range.start = ch - offset;
+		iter->range.end = ch + offset;
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+/**
+ * This is the _iter_next() helper for 6g band chanspec iteration.
+ * The 6g iterator uses ranges of primary 20MHz channels, and the current BW, to create
+ * each chanspec in the set.
+ * Each BW in 6g has one contiguous range of primary 20MHz channels. When a range is
+ * exhausted, the iterator moves to the next BW.
+ */
+static bool
+wf_chanspec_iter_next_6g(wf_chanspec_iter_t *iter)
+{
+	chanspec_t chspec = iter->chanspec;
+	chanspec_bw_t bw = CHSPEC_BW(chspec);
+	uint8 ch = wf_chspec_primary20_chan(chspec);
+	uint8 end = iter->range.end;
+
+	if (ch < end) {
+		/* not at the end of the current range, so
+		 * step to the next 20MHz channel and create the current BW
+		 * channel with that new primary 20MHz.
+		 */
+		ch += CH_20MHZ_APART;
+
+		/* try to create a valid channel of the current BW
+		 * with a primary20 'ch'
+		 */
+		chspec = wf_create_chspec_from_primary(ch, bw, WL_CHANSPEC_BAND_6G);
+
+		/* if chspec is INVCHANSPEC, then we hit the end
+		 * of the valid channels in the range.
+		 */
+	} else {
+		/* hit the end of the current range */
+		chspec = INVCHANSPEC;
+	}
+
+	/* if we are at the end of the current channel range
+	 * check if there is another BW to iterate
+	 * Note: (iter->bw == INVCHANSPEC) indicates an unspecified BW for the interation,
+	 * so it will iterate over all BWs.
+	 */
+	if (chspec == INVCHANSPEC &&
+	    iter->bw == INVCHANSPEC &&
+	    (bw = wf_iter_next_bw(bw)) != INVCHANSPEC) {
+		/* start the new bw with the first primary20 */
+		ch = iter->range.start;
+		chspec = wf_create_chspec_from_primary(ch, bw, WL_CHANSPEC_BAND_6G);
+	}
+
+	iter->chanspec = chspec;
+	if (chspec != INVCHANSPEC) {
+		return TRUE;
+	} else {
+		iter->state = WF_ITER_DONE;
+		return FALSE;
+	}
+}
+
+/**
+ * Helper used by wf_chanspec_iter_firstchan() to set up the first range of
+ * primary channels for the 6g band and for the BW being iterated.
+ */
+static void
+wf_chanspec_iter_6g_range_init(wf_chanspec_iter_t *iter, chanspec_bw_t bw)
+{
+	switch (bw) {
+	case WL_CHANSPEC_BW_20:
+	case WL_CHANSPEC_BW_40:
+	case WL_CHANSPEC_BW_80:
+	case WL_CHANSPEC_BW_160:
+#ifdef WL11BE
+	case WL_CHANSPEC_BW_240:
+	case WL_CHANSPEC_BW_320:
+#endif
+		iter->range.start = CH_MIN_6G_CHANNEL;
+		iter->range.end   = CH_MAX_6G_CHANNEL;
+		break;
+	default:
+		ASSERT(0);
+		break;
+	}
+}
+
+/**
+ * Verify that the channel is a valid 20MHz channel according to 802.11.
+ *
+ * @param  channel   20MHz channel number to validate
+ * @param  band      chanspec band
+ *
+ * @return Return TRUE if valid
+ */
+bool
+wf_valid_20MHz_chan(uint channel, chanspec_band_t band)
+{
+	if (band == WL_CHANSPEC_BAND_2G) {
+		/* simple range check for 2GHz */
+		return (channel >= CH_MIN_2G_CHANNEL &&
+		        channel <= CH_MAX_2G_CHANNEL);
+	} else if (band == WL_CHANSPEC_BAND_5G) {
+		const uint8 *center_ch = wf_5g_40m_chans;
+		uint num_ch = WF_NUM_5G_40M_CHANS;
+		uint i;
+
+		/* We don't have an array of legal 20MHz 5G channels, but they are
+		 * each side of the legal 40MHz channels.  Check the chanspec
+		 * channel against either side of the 40MHz channels.
+		 */
+		for (i = 0; i < num_ch; i ++) {
+			if (channel == (uint)LOWER_20_SB(center_ch[i]) ||
+			    channel == (uint)UPPER_20_SB(center_ch[i])) {
+				break; /* match found */
+			}
+		}
+
+		if (i == num_ch) {
+			/* check for channel 165 which is not the side band
+			 * of 40MHz 5G channel
+			 */
+			if (channel == 165) {
+				i = 0;
+			}
+
+			/* check for legacy JP channels on failure */
+			if (channel == 34 || channel == 38 ||
+			    channel == 42 || channel == 46) {
+				i = 0;
+			}
+		}
+
+		if (i < num_ch) {
+			/* match found */
+			return TRUE;
+		}
+	}
+
+	else if (band == WL_CHANSPEC_BAND_6G) {
+		/* Use the simple pattern of 6GHz 20MHz channels for validity check */
+		if ((channel >= CH_MIN_6G_CHANNEL &&
+		     channel <= CH_MAX_6G_CHANNEL) &&
+		    ((((channel - CH_MIN_6G_CHANNEL) % 4) == 0) || // even multiple of 4
+		     channel == 2)) { // Or the oddball channel 2
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+/**
+ * Verify that the center channel is a valid 40MHz center channel according to 802.11.
+ *
+ * @param  center_channel   40MHz center channel to validate
+ * @param  band             chanspec band
+ *
+ * @return Return TRUE if valid
+ */
+bool
+wf_valid_40MHz_center_chan(uint center_channel, chanspec_band_t band)
+{
+	if (band == WL_CHANSPEC_BAND_2G) {
+		/* simple range check for 2GHz */
+		return (center_channel >= CH_MIN_2G_40M_CHANNEL &&
+		        center_channel <= CH_MAX_2G_40M_CHANNEL);
+	} else if (band == WL_CHANSPEC_BAND_5G) {
+		uint i;
+
+		/* use the 5GHz lookup of 40MHz channels */
+		for (i = 0; i < WF_NUM_5G_40M_CHANS; i++) {
+			if (center_channel == wf_5g_40m_chans[i]) {
+				return TRUE;
+			}
+		}
+	}
+	else if (band == WL_CHANSPEC_BAND_6G) {
+		/* Use the simple pattern of 6GHz center channels */
+		if ((center_channel >= CH_MIN_6G_40M_CHANNEL &&
+		     center_channel <= CH_MAX_6G_40M_CHANNEL) &&
+		    ((center_channel - CH_MIN_6G_40M_CHANNEL) % 8) == 0) {  // even multiple of 8
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+/**
+ * Verify that the center channel is a valid 80MHz center channel according to 802.11.
+ *
+ * @param  center_channel   80MHz center channel to validate
+ * @param  band             chanspec band
+ *
+ * @return Return TRUE if valid
+ */
+bool
+wf_valid_80MHz_center_chan(uint center_channel, chanspec_band_t band)
+{
+	if (band == WL_CHANSPEC_BAND_5G) {
+		/* use the 80MHz ID lookup to validate the center channel */
+		if (channel_80mhz_to_id(center_channel) >= 0) {
+			return TRUE;
+		}
+	} else if (band == WL_CHANSPEC_BAND_6G) {
+		/* use the 80MHz ID lookup to validate the center channel */
+		if (channel_6g_80mhz_to_id(center_channel) >= 0) {
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+/**
+ * Verify that the center channel is a valid 160MHz center channel according to 802.11.
+ *
+ * @param  center_channel   160MHz center channel to validate
+ * @param  band             chanspec band
+ *
+ * @return Return TRUE if valid
+ */
+bool
+wf_valid_160MHz_center_chan(uint center_channel, chanspec_band_t band)
+{
+	if (band == WL_CHANSPEC_BAND_5G) {
+		uint i;
+
+		/* use the 5GHz lookup of 40MHz channels */
+		for (i = 0; i < WF_NUM_5G_160M_CHANS; i++) {
+			if (center_channel == wf_5g_160m_chans[i]) {
+				return TRUE;
+			}
+		}
+	} else if (band == WL_CHANSPEC_BAND_6G) {
+		/* Use the simple pattern of 6GHz center channels */
+		if ((center_channel >= CH_MIN_6G_160M_CHANNEL &&
+		     center_channel <= CH_MAX_6G_160M_CHANNEL) &&
+		    ((center_channel - CH_MIN_6G_160M_CHANNEL) % 32) == 0) { // even multiple of 32
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+/**
+ * Verify that the center channel is a valid 240MHz center channel according to 802.11.
+ *
+ * @param  center_channel   240MHz center channel to validate
+ * @param  band             chanspec band
+ *
+ * @return Return TRUE if valid
+ */
+bool
+wf_valid_240MHz_center_chan(uint center_channel, chanspec_band_t band)
+{
+	if (band == WL_CHANSPEC_BAND_6G) {
+		/* Use the simple pattern of 6GHz center channels */
+		if ((center_channel >= CH_MIN_6G_240M_CHANNEL &&
+		     center_channel <= CH_MAX_6G_240M_CHANNEL) &&
+		    ((center_channel - CH_MIN_6G_240M_CHANNEL) % 48) == 0) { // even multiple of 48
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+/**
+ * Verify that the center channel is a valid 320MHz center channel according to 802.11.
+ *
+ * @param  center_channel   320MHz center channel to validate
+ * @param  band             chanspec band
+ *
+ * @return Return TRUE if valid
+ */
+bool
+wf_valid_320MHz_center_chan(uint center_channel, chanspec_band_t band)
+{
+	if (band == WL_CHANSPEC_BAND_6G) {
+		/* Use the simple pattern of 6GHz center channels */
+		if ((center_channel >= CH_MIN_6G_320M_CHANNEL &&
+		     center_channel <= CH_MAX_6G_320M_CHANNEL) &&
+		    ((center_channel - CH_MIN_6G_320M_CHANNEL) % 64) == 0) { // even multiple of 64
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+/*
+ * This function returns TRUE if both the chanspec can co-exist in PHY.
+ * Addition to primary20 channel, the function checks for side band for 2g 40 channels
+ */
+bool
+wf_chspec_coexist(chanspec_t chspec1, chanspec_t chspec2)
+{
+	bool same_primary;
+
+	same_primary = (wf_chspec_primary20_chan(chspec1) == wf_chspec_primary20_chan(chspec2));
+
+	if (same_primary && CHSPEC_IS2G(chspec1)) {
+	    if (CHSPEC_IS40(chspec1) && CHSPEC_IS40(chspec2)) {
+	        return (CHSPEC_CTL_SB(chspec1) == CHSPEC_CTL_SB(chspec2));
+	    }
+	}
+	return same_primary;
+}
+
+/**
+ * Create a 20MHz chanspec for the given band.
+ *
+ * This function returns a 20MHz chanspec in the given band.
+ *
+ * @param	channel   20MHz channel number
+ * @param	band      a chanspec band (e.g. WL_CHANSPEC_BAND_2G)
+ *
+ * @return Returns a 20MHz chanspec, or IVNCHANSPEC in case of error.
+ */
+chanspec_t
+wf_create_20MHz_chspec(uint channel, chanspec_band_t band)
+{
+	chanspec_t chspec;
+
+	if (channel <= WL_CHANSPEC_CHAN_MASK &&
+	    (band == WL_CHANSPEC_BAND_2G ||
+	     band == WL_CHANSPEC_BAND_5G ||
+	     band == WL_CHANSPEC_BAND_6G)) {
+		chspec = band | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE | channel;
+		if (!wf_chspec_valid(chspec)) {
+			chspec = INVCHANSPEC;
+		}
+	} else {
+		chspec = INVCHANSPEC;
+	}
+
+	return chspec;
+}
+
+/**
+ * Returns the chanspec for a 40MHz channel given the primary 20MHz channel number,
+ * the center channel number, and the band.
+ *
+ * @param  primary_channel  primary 20Mhz channel
+ * @param  center_channel   center channel of the 40MHz channel
+ * @param  band             band of the 40MHz channel (chanspec_band_t value)
+ *
+ * The center_channel can be one of the 802.11 spec valid 40MHz chenter channels
+ * in the given band.
+ *
+ * @return returns a 40MHz chanspec, or INVCHANSPEC in case of error
+ */
+chanspec_t
+wf_create_40MHz_chspec(uint primary_channel, uint center_channel,
+                       chanspec_band_t band)
+{
+	int sb;
+
+	/* Calculate the sideband value for the center and primary channel.
+	 * Will return -1 if not a valid pair for 40MHz
+	 */
+	sb = channel_to_sb(center_channel, primary_channel, WL_CHANSPEC_BW_40);
+
+	/* return err if the sideband was bad or the center channel is not
+	 * valid for the given band.
+	 */
+	if (sb < 0 || !wf_valid_40MHz_center_chan(center_channel, band)) {
+		return INVCHANSPEC;
+	}
+
+	/* othewise construct and return the valid 40MHz chanspec */
+	return (chanspec_t)(center_channel | WL_CHANSPEC_BW_40 | band |
+	                    ((uint)sb << WL_CHANSPEC_CTL_SB_SHIFT));
+}
+
+/**
+ * Returns the chanspec for a 40MHz channel given the primary 20MHz channel number,
+ * the sub-band for the primary 20MHz channel, and the band.
+ *
+ * @param  primary_channel  primary 20Mhz channel
+ * @param  primary_subband  sub-band of the 20MHz primary channel (chanspec_subband_t value)
+ * @param  band             band of the 40MHz channel (chanspec_band_t value)
+ *
+ * The primary channel and sub-band should describe one of the 802.11 spec valid
+ * 40MHz channels in the given band.
+ *
+ * @return returns a 40MHz chanspec, or INVCHANSPEC in case of error
+ */
+chanspec_t
+wf_create_40MHz_chspec_primary_sb(uint primary_channel, chanspec_subband_t primary_subband,
+                                  chanspec_band_t band)
+{
+	uint center_channel;
+
+	/* find the center channel */
+	if (primary_subband == WL_CHANSPEC_CTL_SB_L) {
+		center_channel = primary_channel + CH_10MHZ_APART;
+	} else if (primary_subband == WL_CHANSPEC_CTL_SB_U) {
+		center_channel = primary_channel - CH_10MHZ_APART;
+	} else {
+		return INVCHANSPEC;
+	}
+
+	return wf_create_40MHz_chspec(primary_channel, center_channel, band);
+}
+
+/**
+ * Returns the chanspec for an 80MHz channel given the primary 20MHz channel number,
+ * the center channel number, and the band.
+ *
+ * @param  primary_channel  primary 20Mhz channel
+ * @param  center_channel   center channel of the 80MHz channel
+ * @param  band             band of the 80MHz channel (chanspec_band_t value)
+ *
+ * The center_channel can be one of {42, 58, 106, 122, 138, 155} for 5G,
+ * or {7 + 16*X for 0 <= X <= 13} for 6G.
+ *
+ * @return returns an 80MHz chanspec, or INVCHANSPEC in case of error
+ */
+chanspec_t
+wf_create_80MHz_chspec(uint primary_channel, uint center_channel,
+                       chanspec_band_t band)
+{
+	int sb;
+
+	/* Calculate the sideband value for the center and primary channel.
+	 * Will return -1 if not a valid pair for 80MHz
+	 */
+	sb = channel_to_sb(center_channel, primary_channel, WL_CHANSPEC_BW_80);
+
+	/* return err if the sideband was bad or the center channel is not
+	 * valid for the given band.
+	 */
+	if (sb < 0 || !wf_valid_80MHz_center_chan(center_channel, band)) {
+		return INVCHANSPEC;
+	}
+
+	/* othewise construct and return the valid 80MHz chanspec */
+	return (chanspec_t)(center_channel | WL_CHANSPEC_BW_80 | band |
+	                    ((uint)sb << WL_CHANSPEC_CTL_SB_SHIFT));
+}
+
+/**
+ * Returns the chanspec for an 160MHz channel given the primary 20MHz channel number,
+ * the center channel number, and the band.
+ *
+ * @param  primary_channel  primary 20Mhz channel
+ * @param  center_channel   center channel of the 160MHz channel
+ * @param  band             band of the 160MHz channel (chanspec_band_t value)
+ *
+ * The center_channel can be one of {50, 114} for 5G,
+ * or {15 + 32*X for 0 <= X <= 7} for 6G.
+ *
+ * @return returns an 160MHz chanspec, or INVCHANSPEC in case of error
+ */
+chanspec_t
+wf_create_160MHz_chspec(uint primary_channel, uint center_channel, chanspec_band_t band)
+{
+	int sb;
+
+	/* Calculate the sideband value for the center and primary channel.
+	 * Will return -1 if not a valid pair for 160MHz
+	 */
+	sb = channel_to_sb(center_channel, primary_channel, WL_CHANSPEC_BW_160);
+
+	/* return err if the sideband was bad or the center channel is not
+	 * valid for the given band.
+	 */
+	if (sb < 0 || !wf_valid_160MHz_center_chan(center_channel, band)) {
+		return INVCHANSPEC;
+	}
+
+	/* othewise construct and return the valid 160MHz chanspec */
+	return (chanspec_t)(center_channel | WL_CHANSPEC_BW_160 | band |
+	                    ((uint)sb << WL_CHANSPEC_CTL_SB_SHIFT));
+}
+
+/**
+ * Returns the chanspec for an 80+80MHz channel given the primary 20MHz channel number,
+ * the center channel numbers for each frequency segment, and the band.
+ *
+ * @param  primary_channel  primary 20 Mhz channel
+ * @param  chan0            center channel number of one frequency segment
+ * @param  chan1            center channel number of the other frequency segment
+ * @param  band             band of the 80+80 MHz channel (chanspec_band_t value)
+ *
+ * Parameters chan0 and chan1 are valid 80 MHz center channel numbers for the given band.
+ * The primary channel must be contained in one of the 80 MHz channels. This routine
+ * will determine which frequency segment is the primary 80 MHz segment.
+ *
+ * @return returns an 80+80 MHz chanspec, or INVCHANSPEC in case of error
+ *
+ * Refer to 802.11-2016 section 21.3.14 "Channelization".
+ */
+chanspec_t
+wf_create_8080MHz_chspec(uint primary_channel, uint chan0, uint chan1,
+                       chanspec_band_t band)
+{
+	int sb = 0;
+	chanspec_t chanspec = 0;
+	int chan0_id = -1, chan1_id = -1;
+	int seg0, seg1;
+
+	/* frequency segments need to be non-contiguous, so the channel separation needs
+	 * to be greater than 80MHz
+	 */
+	if ((uint)ABS((int)(chan0 - chan1)) <= CH_80MHZ_APART) {
+		return INVCHANSPEC;
+	}
+
+	if (band == WL_CHANSPEC_BAND_5G) {
+		chan0_id = channel_80mhz_to_id(chan0);
+		chan1_id = channel_80mhz_to_id(chan1);
+	} else if (band == WL_CHANSPEC_BAND_6G) {
+		chan0_id = channel_6g_80mhz_to_id(chan0);
+		chan1_id = channel_6g_80mhz_to_id(chan1);
+	}
+
+	/* make sure the channel numbers were valid */
+	if (chan0_id == -1 || chan1_id == -1) {
+		return INVCHANSPEC;
+	}
+
+	/* does the primary channel fit with the 1st 80MHz channel ? */
+	sb = channel_to_sb(chan0, primary_channel, WL_CHANSPEC_BW_80);
+	if (sb >= 0) {
+		/* yes, so chan0 is frequency segment 0, and chan1 is seg 1 */
+		seg0 = chan0_id;
+		seg1 = chan1_id;
+	} else {
+		/* no, so does the primary channel fit with the 2nd 80MHz channel ? */
+		sb = channel_to_sb(chan1, primary_channel, WL_CHANSPEC_BW_80);
+		if (sb < 0) {
+			/* no match for pri_ch to either 80MHz center channel */
+			return INVCHANSPEC;
+		}
+		/* swapped, so chan1 is frequency segment 0, and chan0 is seg 1 */
+		seg0 = chan1_id;
+		seg1 = chan0_id;
+	}
+
+	chanspec = ((seg0 << WL_CHANSPEC_CHAN0_SHIFT) |
+	            (seg1 << WL_CHANSPEC_CHAN1_SHIFT) |
+	            (sb << WL_CHANSPEC_CTL_SB_SHIFT) |
+	            WL_CHANSPEC_BW_8080 |
+	            band);
+
+	return chanspec;
+}
+
+/**
+ * Returns the chanspec for an 160+160MHz channel given the primary 20MHz channel number,
+ * the center channel numbers for each frequency segment, and the band.
+ *
+ * @param  primary_channel  primary 20 Mhz channel
+ * @param  chan0            center channel number of one frequency segment
+ * @param  chan1            center channel number of the other frequency segment
+ * @param  band             band of the 160+160 MHz channel (chanspec_band_t value)
+ *
+ * Parameters chan0 and chan1 are valid 160 MHz center channel numbers for the given band.
+ * The primary channel must be contained in one of the 160 MHz channels. This routine
+ * will determine which frequency segment is the primary 160 MHz segment.
+ *
+ * @return returns an 160+160 MHz chanspec, or INVCHANSPEC in case of error
+ *
+ * Refer to <TBD> "Channelization".
+ */
+chanspec_t
+wf_create_160160MHz_chspec(uint primary_channel, uint chan0, uint chan1,
+                           chanspec_band_t band)
+{
+	int sb = 0;
+	chanspec_t chanspec = 0;
+	int chan0_id = -1, chan1_id = -1;
+	int seg0, seg1;
+
+	/* frequency segments need to be non-contiguous, so the channel separation needs
+	 * to be greater than 160MHz
+	 */
+	if ((uint)ABS((int)(chan0 - chan1)) <= CH_160MHZ_APART) {
+		return INVCHANSPEC;
+	}
+
+	if (band == WL_CHANSPEC_BAND_5G) {
+		chan0_id = channel_5g_160mhz_to_id(chan0);
+		chan1_id = channel_5g_160mhz_to_id(chan1);
+	} else if (band == WL_CHANSPEC_BAND_6G) {
+		chan0_id = channel_6g_160mhz_to_id(chan0);
+		chan1_id = channel_6g_160mhz_to_id(chan1);
+	}
+
+	/* make sure the channel numbers were valid */
+	if (chan0_id == -1 || chan1_id == -1) {
+		return INVCHANSPEC;
+	}
+
+	/* does the primary channel fit with the 1st 160MHz channel ? */
+	sb = channel_to_sb(chan0, primary_channel, WL_CHANSPEC_BW_160);
+	if (sb >= 0) {
+		/* yes, so chan0 is frequency segment 0, and chan1 is seg 1 */
+		seg0 = chan0_id;
+		seg1 = chan1_id;
+	} else {
+		/* no, so does the primary channel fit with the 2nd 160MHz channel ? */
+		sb = channel_to_sb(chan1, primary_channel, WL_CHANSPEC_BW_160);
+		if (sb < 0) {
+			/* no match for pri_ch to either 160MHz center channel */
+			return INVCHANSPEC;
+		}
+		/* swapped, so chan1 is frequency segment 0, and chan0 is seg 1 */
+		seg0 = chan1_id;
+		seg1 = chan0_id;
+	}
+
+	chanspec = ((seg0 << WL_CHANSPEC_CHAN0_SHIFT) |
+	            (seg1 << WL_CHANSPEC_CHAN1_SHIFT) |
+	            (sb << WL_CHANSPEC_CTL_SB_SHIFT) |
+	            WL_CHANSPEC_BW_160160 |
+	            band);
+
+	return chanspec;
+}
+
+/**
+ * Returns the chanspec for an 240MHz channel given the primary 20MHz channel number,
+ * the center channel number, and the band.
+ *
+ * @param  primary_channel  primary 20 Mhz channel
+ * @param  chan             center channel number
+ * @param  band             band of the 240 MHz channel (chanspec_band_t value)
+ *
+ * @return returns an 240 MHz chanspec, or INVCHANSPEC in case of error
+ *
+ * Refer to <TBD> "Channelization".
+ */
+chanspec_t
+wf_create_240MHz_chspec(uint primary_channel, uint center_channel, chanspec_band_t band)
+{
+	int sb = 0;
+	chanspec_t chanspec = 0;
+	int chan_id = -1;
+
+	if (band == WL_CHANSPEC_BAND_6G) {
+		chan_id = channel_6g_240mhz_to_id(center_channel);
+	}
+
+	/* make sure the channel number were valid */
+	if (chan_id == -1) {
+		return INVCHANSPEC;
+	}
+
+	/* Calculate the sideband value for the center and primary channel.
+	 * Will return -1 if not a valid pair for 240MHz
+	 */
+	sb = channel_to_sb(center_channel, primary_channel, WL_CHANSPEC_BW_240);
+
+	/* return err if the sideband was bad or the center channel is not
+	 * valid for the given band.
+	 */
+	if (sb < 0 || !wf_valid_240MHz_center_chan(center_channel, band)) {
+		return INVCHANSPEC;
+	}
+
+	chanspec = ((chan_id << WL_CHANSPEC_GE240_CHAN_SHIFT) |
+	            (sb << WL_CHANSPEC_GE240_SB_SHIFT) |
+	            WL_CHANSPEC_BW_240 |
+	            band);
+
+	return chanspec;
+}
+
+/**
+ * Returns the chanspec for an 320MHz channel given the primary 20MHz channel number,
+ * the center channel number, and the band.
+ *
+ * @param  primary_channel  primary 20 Mhz channel
+ * @param  chan             center channel number
+ * @param  band             band of the 320 MHz channel (chanspec_band_t value)
+ *
+ * Parameters chan is valid 320 MHz center channel numbers for the given band.
+ * The primary channel must be contained in one of the 320 MHz channels.
+ *
+ * @return returns an 320 MHz chanspec, or INVCHANSPEC in case of error
+ *
+ * Refer to <TBD> "Channelization".
+ */
+chanspec_t
+wf_create_320MHz_chspec(uint primary_channel, uint center_channel, chanspec_band_t band)
+{
+	int sb = 0;
+	chanspec_t chanspec = 0;
+	int chan_id = -1;
+
+	if (band == WL_CHANSPEC_BAND_6G) {
+		chan_id = channel_6g_320mhz_to_id(center_channel);
+	}
+
+	/* make sure the channel number were valid */
+	if (chan_id == -1) {
+		return INVCHANSPEC;
+	}
+
+	/* Calculate the sideband value for the center and primary channel.
+	 * Will return -1 if not a valid pair for 320MHz
+	 */
+	sb = channel_to_sb(center_channel, primary_channel, WL_CHANSPEC_BW_320);
+
+	/* return err if the sideband was bad or the center channel is not
+	 * valid for the given band.
+	 */
+	if (sb < 0 || !wf_valid_320MHz_center_chan(center_channel, band)) {
+		return INVCHANSPEC;
+	}
+
+	chanspec = ((chan_id << WL_CHANSPEC_GE240_CHAN_SHIFT) |
+	            (sb << WL_CHANSPEC_GE240_SB_SHIFT) |
+	            WL_CHANSPEC_BW_320 |
+	            band);
+
+	return chanspec;
+}
+
+/**
+ * Returns the chanspec given the primary 20MHz channel number,
+ * the center channel number, channel width, and the band. The channel width
+ * must be 20, 40, 80, 160, 240 or 320 MHz.
+ * 80+80 or 160+160 MHz chanspec creation is not handled by this function,
+ * use wf_create_8080MHz_chspec() or wf_create_160160MHz_chspec()instead.
+ *
+ * @param  primary_channel  primary 20Mhz channel
+ * @param  center_channel   center channel of the channel
+ * @param  bw               width of the channel (chanspec_bw_t)
+ * @param  band             chanspec band of channel  (chanspec_band_t)
+ *
+ * The center_channel can be one of the 802.11 spec valid center channels
+ * for the given bandwidth in the given band.
+ *
+ * @return returns a chanspec, or INVCHANSPEC in case of error
+ */
+chanspec_t
+wf_create_chspec(uint primary_channel, uint center_channel,
+                 chanspec_bw_t bw, chanspec_band_t band)
+{
+	chanspec_t chspec = INVCHANSPEC;
+	int sb = -1;
+	uint sb_shift;
+
+	/* 20MHz channels have matching center and primary channels */
+	if (bw == WL_CHANSPEC_BW_20 && primary_channel == center_channel) {
+
+		sb = 0;
+
+	} else if (bw == WL_CHANSPEC_BW_40 ||
+		bw == WL_CHANSPEC_BW_80 ||
+		bw == WL_CHANSPEC_BW_160 ||
+		WFC_BW_EQ(bw, WL_CHANSPEC_BW_240) ||
+		WFC_BW_EQ(bw, WL_CHANSPEC_BW_320)) {
+
+		/* calculate the sub-band index */
+		sb = channel_to_sb(center_channel, primary_channel, bw);
+	}
+
+	/* if we have a good sub-band, assemble the chanspec, and use wf_chspec_valid()
+	 * to check it for correctness
+	 */
+	if (sb >= 0) {
+		if (WFC_BW_EQ(bw, WL_CHANSPEC_BW_240)) {
+			if (band == WL_CHANSPEC_BAND_6G) {
+				center_channel = channel_6g_240mhz_to_id(center_channel);
+				sb_shift = WL_CHANSPEC_GE240_SB_SHIFT;
+			} else {
+				return INVCHANSPEC;
+			}
+		} else if (WFC_BW_EQ(bw, WL_CHANSPEC_BW_320)) {
+			if (band == WL_CHANSPEC_BAND_6G) {
+				center_channel = channel_6g_320mhz_to_id(center_channel);
+				sb_shift = WL_CHANSPEC_GE240_SB_SHIFT;
+			} else {
+				return INVCHANSPEC;
+			}
+		} else {
+			sb_shift = WL_CHANSPEC_CTL_SB_SHIFT;
+		}
+		chspec = center_channel | band | bw |
+		        ((uint)sb << sb_shift);
+		if (!wf_chspec_valid(chspec)) {
+			chspec = INVCHANSPEC;
+		}
+	}
+
+	return chspec;
+}
+
+/**
+ * Returns the chanspec given the primary 20MHz channel number,
+ * channel width, and the band.
+ *
+ * @param  primary_channel  primary 20Mhz channel
+ * @param  bw               width of the channel (chanspec_bw_t)
+ * @param  band             chanspec band of channel  (chanspec_band_t)
+ *
+ * @return returns a chanspec, or INVCHANSPEC in case of error
+ *
+ * This function is a similar to wf_create_chspec() but does not require the
+ * center_channel parameter. As a result, it can not create 40MHz channels on
+ * the 2G band.
+ *
+ * This function supports creating 20MHz bandwidth chanspecs on any band.
+ *
+ * For the 2GHz band, 40MHz channels overlap, so two 40MHz channels may
+ * have the same primary 20MHz channel. This function will return INVCHANSPEC
+ * whenever called with a bandwidth of 40MHz or wider for the 2GHz band.
+ *
+ * 5GHz and 6GHz bands have non-overlapping 40/80/160 MHz channels, so a
+ * 20MHz primary channel uniquely specifies a wider channel in a given band.
+ *
+ * 80+80MHz channels also cannot be uniquely defined. This function will return
+ * INVCHANSPEC whenever bandwidth of WL_CHANSPEC_BW_8080.
+ */
+chanspec_t
+wf_create_chspec_from_primary(uint primary_channel, chanspec_bw_t bw, chanspec_band_t band)
+{
+	chanspec_t chspec = INVCHANSPEC;
+
+	if (bw == WL_CHANSPEC_BW_20) {
+		chspec = wf_create_20MHz_chspec(primary_channel, band);
+	} else if (band == WL_CHANSPEC_BAND_2G || band == WL_CHANSPEC_BAND_5G) {
+		/* For 5GHz, use the lookup tables for valid 40/80/160 center channels
+		 * and search for a center channel compatible with the given primary channel.
+		 */
+		const uint8 *center_ch = NULL;
+		uint num_ch, i;
+
+		if (band == WL_CHANSPEC_BAND_2G && bw == WL_CHANSPEC_BW_40) {
+			center_ch = wf_2g_40m_chans;
+			num_ch = WF_NUM_2G_40M_CHANS;
+		} else
+		if (bw == WL_CHANSPEC_BW_40) {
+			center_ch = wf_5g_40m_chans;
+			num_ch = WF_NUM_5G_40M_CHANS;
+		} else if (bw == WL_CHANSPEC_BW_80) {
+			center_ch = wf_5g_80m_chans;
+			num_ch = WF_NUM_5G_80M_CHANS;
+		} else if (bw == WL_CHANSPEC_BW_160) {
+			center_ch = wf_5g_160m_chans;
+			num_ch = WF_NUM_5G_160M_CHANS;
+		} else {
+			num_ch = 0;
+		}
+
+		for (i = 0; i < num_ch; i ++) {
+			chspec = wf_create_chspec(primary_channel, center_ch[i], bw, band);
+			if (chspec != INVCHANSPEC) {
+				break;
+			}
+		}
+	}
+	else if (band == WL_CHANSPEC_BAND_6G) {
+		/* For 6GHz, use a formula to calculate the valid 40/80/160 center channel from
+		 * the primary channel.
+		 */
+		uint ch_per_block;
+		uint mask;
+		uint base, center;
+
+		if (bw == WL_CHANSPEC_BW_40) {
+			ch_per_block = 8;
+		} else if (bw == WL_CHANSPEC_BW_80) {
+			ch_per_block = 16;
+		} else if (bw == WL_CHANSPEC_BW_160) {
+			ch_per_block = 32;
+		} else if (WFC_BW_EQ(bw, WL_CHANSPEC_BW_240)) {
+			ch_per_block = 48;
+		} else if (WFC_BW_EQ(bw, WL_CHANSPEC_BW_320)) {
+			ch_per_block = 64;
+		} else {
+			ch_per_block = 0;
+		}
+
+		if (ch_per_block) {
+			/* calculate the base of the block of channel numbers
+			 * covered by the given bw
+			 */
+			mask = ~(ch_per_block - 1);
+			base = 1 + ((primary_channel - 1) & mask);
+
+			/* calculate the center channel from the base channel */
+			center = base + center_chan_to_edge(bw);
+
+			chspec = wf_create_chspec(primary_channel, center, bw, band);
+		}
+	}
+
+	return chspec;
+}
+
+/**
+ * Return the primary 20MHz channel.
+ *
+ * This function returns the channel number of the primary 20MHz channel. For
+ * 20MHz channels this is just the channel number. For 40MHz or wider channels
+ * it is the primary 20MHz channel specified by the chanspec.
+ *
+ * @param	chspec    input chanspec
+ *
+ * @return Returns the channel number of the primary 20MHz channel
+ */
+uint8
+wf_chspec_primary20_chan(chanspec_t chspec)
+{
+	uint center_chan = INVCHANNEL;
+	chanspec_bw_t bw;
+	uint sb;
+
+	ASSERT(!wf_chspec_malformed(chspec));
+
+	/* Is there a sideband ? */
+	if (CHSPEC_IS20(chspec)) {
+		return CHSPEC_CHANNEL(chspec);
+	} else {
+		if ((CHSPEC_IS240(chspec)) || (CHSPEC_IS320(chspec))) {
+			sb = CHSPEC_GE240_SB(chspec) >> WL_CHANSPEC_GE240_SB_SHIFT;
+		} else {
+			sb = CHSPEC_CTL_SB(chspec) >> WL_CHANSPEC_CTL_SB_SHIFT;
+		}
+
+		if (CHSPEC_IS8080(chspec)) {
+			/* For an 80+80 MHz channel, the sideband 'sb' field is an 80 MHz sideband
+			 * (LL, LU, UL, LU) for the 80 MHz frequency segment 0.
+			 */
+
+			/* use bw 80MHz for the primary channel lookup */
+			bw = WL_CHANSPEC_BW_80;
+
+			/* convert from channel index to channel number */
+			if (CHSPEC_IS5G(chspec)) {
+				center_chan = wf_chspec_5G_id80_to_ch(CHSPEC_CHAN0(chspec));
+			} else if (CHSPEC_IS6G(chspec)) {
+				center_chan = wf_chspec_6G_id80_to_ch(CHSPEC_CHAN0(chspec));
+			}
+		} else if (CHSPEC_IS160160(chspec)) {
+			/* For an 160+160 MHz channel, the sideband 'sb' field is an 160MHz sideband
+			 * for the 160 MHz frequency segment 0.
+			 */
+
+			/* use bw 160MHz for the primary channel lookup */
+			bw = WL_CHANSPEC_BW_160;
+
+			/* convert from channel index to channel number */
+			if (CHSPEC_IS5G(chspec)) {
+				center_chan = wf_chspec_5G_id160_to_ch(CHSPEC_CHAN0(chspec));
+			} else if (CHSPEC_IS6G(chspec)) {
+				center_chan = wf_chspec_6G_id160_to_ch(CHSPEC_CHAN0(chspec));
+			}
+		} else if (CHSPEC_IS240(chspec)) {
+			/* use bw 240MHz for the primary channel lookup */
+			bw = WL_CHANSPEC_BW_240;
+
+			/* convert from channel index to channel number */
+			if (CHSPEC_IS6G(chspec)) {
+				center_chan = wf_chspec_6G_id240_to_ch(CHSPEC_GE240_CHAN(chspec));
+			}
+		} else if (CHSPEC_IS320(chspec)) {
+			/* use bw 320MHz for the primary channel lookup */
+			bw = WL_CHANSPEC_BW_320;
+
+			/* convert from channel index to channel number */
+			if (CHSPEC_IS6G(chspec)) {
+				center_chan = wf_chspec_6G_id320_to_ch(CHSPEC_GE240_CHAN(chspec));
+			}
+			/* What to return otherwise? */
+		}
+		else {
+			bw = CHSPEC_BW(chspec);
+			center_chan = CHSPEC_CHANNEL(chspec) >> WL_CHANSPEC_CHAN_SHIFT;
+		}
+
+		return (uint8)(channel_to_primary20_chan((uint8)center_chan, bw, sb));
+	}
+}
+
+/**
+ * Return the bandwidth string for a given chanspec
+ *
+ * This function returns the bandwidth string for the passed chanspec.
+ *
+ * @param	chspec    input chanspec
+ *
+ * @return Returns the bandwidth string:
+ *         "320", "160+160", "20", "40", "80", "160", "80+80", "240"
+ */
+const char *
+BCMRAMFN(wf_chspec_to_bw_str)(chanspec_t chspec)
+{
+	return wf_chspec_bw_str[(CHSPEC_BW(chspec) >> WL_CHANSPEC_BW_SHIFT)];
+}
+
+/**
+ * Return the primary 20MHz chanspec of a given chanspec
+ *
+ * This function returns the chanspec of the primary 20MHz channel. For 20MHz
+ * channels this is just the chanspec. For 40MHz or wider channels it is the
+ * chanspec of the primary 20MHz channel specified by the chanspec.
+ *
+ * @param	chspec    input chanspec
+ *
+ * @return Returns the chanspec of the primary 20MHz channel
+ */
+chanspec_t
+wf_chspec_primary20_chspec(chanspec_t chspec)
+{
+	chanspec_t pri_chspec = chspec;
+	uint8 pri_chan;
+
+	ASSERT(!wf_chspec_malformed(chspec));
+
+	/* Is there a sideband ? */
+	if (!CHSPEC_IS20(chspec)) {
+		pri_chan = wf_chspec_primary20_chan(chspec);
+		pri_chspec = pri_chan | WL_CHANSPEC_BW_20;
+		pri_chspec |= CHSPEC_BAND(chspec);
+	}
+	return pri_chspec;
+}
+
+/* return chanspec given primary 20MHz channel and bandwidth
+ * return 0 on error
+ * does not support 6G
+ */
+uint16
+wf_channel2chspec(uint pri_ch, uint bw)
+{
+	uint16 chspec;
+	const uint8 *center_ch = NULL;
+	int num_ch = 0;
+	int sb = -1;
+	int i = 0;
+
+	chspec = ((pri_ch <= CH_MAX_2G_CHANNEL) ? WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G);
+
+	chspec |= bw;
+
+	if (bw == WL_CHANSPEC_BW_40) {
+		if (pri_ch <= CH_MAX_2G_CHANNEL) {
+			center_ch = wf_2g_40m_chans;
+			num_ch = WF_NUM_2G_40M_CHANS;
+		} else {
+			center_ch = wf_5g_40m_chans;
+			num_ch = WF_NUM_5G_40M_CHANS;
+		}
+	} else if (bw == WL_CHANSPEC_BW_80) {
+		center_ch = wf_5g_80m_chans;
+		num_ch = WF_NUM_5G_80M_CHANS;
+	} else if (bw == WL_CHANSPEC_BW_160) {
+		center_ch = wf_5g_160m_chans;
+		num_ch = WF_NUM_5G_160M_CHANS;
+	} else if (bw == WL_CHANSPEC_BW_20) {
+		chspec |= pri_ch;
+		return chspec;
+	} else {
+		return 0;
+	}
+
+	for (i = 0; i < num_ch; i ++) {
+		sb = channel_to_sb(center_ch[i], pri_ch, (chanspec_bw_t)bw);
+		if (sb >= 0) {
+			chspec |= center_ch[i];
+			chspec |= (sb << WL_CHANSPEC_CTL_SB_SHIFT);
+			break;
+		}
+	}
+
+	/* check for no matching sb/center */
+	if (sb < 0) {
+		return 0;
+	}
+
+	return chspec;
+}
+
+/**
+ * Return the primary 40MHz chanspec or a 40MHz or wider channel
+ *
+ * This function returns the chanspec for the primary 40MHz of an 80MHz or wider channel.
+ * The primary 40MHz channel is the 40MHz sub-band that contains the primary 20MHz channel.
+ * The primary 20MHz channel of the returned 40MHz chanspec is the same as the primary 20MHz
+ * channel of the input chanspec.
+ *
+ * @param	chspec    input chanspec
+ *
+ * @return Returns the chanspec of the primary 20MHz channel
+ */
+chanspec_t
+wf_chspec_primary40_chspec(chanspec_t chspec)
+{
+	chanspec_t chspec40 = chspec;
+	uint center_chan;
+	uint sb;
+
+	ASSERT(!wf_chspec_malformed(chspec));
+
+	/* if the chanspec is > 80MHz, use the helper routine to find the primary 80 MHz channel */
+	if (CHSPEC_IS8080(chspec) || CHSPEC_IS160(chspec)) {
+		chspec = wf_chspec_primary80_chspec(chspec);
+	}
+
+	/* determine primary 40 MHz sub-channel of an 80 MHz chanspec */
+	if (CHSPEC_IS80(chspec)) {
+		center_chan = CHSPEC_CHANNEL(chspec);
+		sb = CHSPEC_CTL_SB(chspec);
+
+		if (sb < WL_CHANSPEC_CTL_SB_UL) {
+			/* Primary 40MHz is on lower side */
+			center_chan -= CH_20MHZ_APART;
+			/* sideband bits are the same for LL/LU and L/U */
+		} else {
+			/* Primary 40MHz is on upper side */
+			center_chan += CH_20MHZ_APART;
+			/* sideband bits need to be adjusted by UL offset */
+			sb -= WL_CHANSPEC_CTL_SB_UL;
+		}
+
+		/* Create primary 40MHz chanspec */
+		chspec40 = (CHSPEC_BAND(chspec) | WL_CHANSPEC_BW_40 |
+		            sb | center_chan);
+	}
+
+	return chspec40;
+}
+
+/**
+ * Return the chanspec band for a given frequency.
+ *
+ * @param  freq		frequency in MHz of the channel center
+ *
+ * @return  Returns chanspec band of frequency (chanspec_band_t)
+ */
+chanspec_band_t
+wf_mhz2chanspec_band(uint freq)
+{
+	chanspec_band_t band = INVCHANSPEC;
+
+	if (freq >= 2400u && freq <= 2500u) {
+		band = WL_CHANSPEC_BAND_2G;
+	} else if (freq >= 5000u && freq < 5935u) {
+		band = WL_CHANSPEC_BAND_5G;
+	} else if (freq >= 5935u && freq <= 7205u) {
+		band = WL_CHANSPEC_BAND_6G;
+	}
+
+	return band;
+}
+
+/**
+ * Return the channel number for a given frequency and base frequency.
+ *
+ * @param   freq            frequency in MHz of the channel center
+ * @param   start_factor    starting base frequency in 500 KHz units
+ *
+ * @return  Returns a channel number > 0, or -1 on error
+ *
+ * The returned channel number is relative to the given base frequency.
+ *
+ * The base frequency is specified as (start_factor * 500 kHz).
+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G, and WF_CHAN_FACTOR_6_G are
+ * defined for 2.4 GHz, 5 GHz, and 6 GHz bands.
+ *
+ * If the given base frequency is zero these base frequencies are assumed:
+ *
+ *              freq (GHz)  -> assumed base freq (GHz)
+ *  2G band   2.4   - 2.5      2.407
+ *  5G band   5.0   - 5.940    5.000
+ *  6G band   5.940 - 7.205    5.940
+ *
+ * It is an error if the start_factor is zero and the freq is not in one of
+ * these ranges.
+ *
+ * The returned channel will be in the range [1, 14] in the 2.4 GHz band,
+ * [1, 253] for 6 GHz band, or [1, 200] otherwise.
+ *
+ * It is an error if the start_factor is WF_CHAN_FACTOR_2_4_G and the
+ * frequency is not a 2.4 GHz channel. For any other start factor the frequency
+ * must be an even 5 MHz multiple greater than the base frequency.
+ *
+ * For a start_factor WF_CHAN_FACTOR_6_G, the frequency may be up to 7.205 MHz
+ * (channel 253). For any other start_factor, the frequence can be up to
+ * 1 GHz from the base freqency (channel 200).
+ *
+ * Reference 802.11-2016, section 17.3.8.3 and section 16.3.6.3
+ */
+int
+wf_mhz2channel(uint freq, uint start_factor)
+{
+	int ch = -1;
+	uint base;
+	int offset;
+
+	/* take the default channel start frequency */
+	if (start_factor == 0) {
+		if (freq >= 2400 && freq <= 2500) {
+			start_factor = WF_CHAN_FACTOR_2_4_G;
+		} else if (freq >= 5000 && freq < 5935) {
+			start_factor = WF_CHAN_FACTOR_5_G;
+		} else if (freq >= 5935 && freq <= 7205) {
+			start_factor = WF_CHAN_FACTOR_6_G;
+		}
+	}
+
+	if (freq == 2484 && start_factor == WF_CHAN_FACTOR_2_4_G) {
+		return 14;
+	} else if (freq == 5935 && start_factor == WF_CHAN_FACTOR_6_G) {
+		/* channel #2 is an oddball, 10MHz below chan #1 */
+		return 2;
+	} else if (freq == 5960 && start_factor == WF_CHAN_FACTOR_6_G) {
+		/* do not return ch #2 for the convetional location that #2 would appear */
+		return -1;
+	}
+
+	base = start_factor / 2;
+
+	if (freq < base) {
+		return -1;
+	}
+
+	offset = freq - base;
+	ch = offset / 5;
+
+	/* check that frequency is a 5MHz multiple from the base */
+	if (offset != (ch * 5))
+		return -1;
+
+	/* channel range checks */
+	if (start_factor == WF_CHAN_FACTOR_2_4_G) {
+		/* 2G should only be up to 13 here as 14 is
+		 * handled above as it is a non-5MHz offset
+		 */
+		if (ch > 13) {
+			ch = -1;
+		}
+	}
+	else if (start_factor == WF_CHAN_FACTOR_6_G) {
+		/* 6G has a higher channel range than 5G channelization specifies [1,200] */
+		if ((uint)ch > CH_MAX_6G_CHANNEL) {
+			ch = -1;
+		}
+	} else if (ch > 200) {
+			ch = -1;
+	}
+
+	return ch;
+}
+
+/**
+ * Return the center frequency in MHz of the given channel and base frequency.
+ *
+ * The channel number is interpreted relative to the given base frequency.
+ *
+ * The valid channel range is [1, 14] in the 2.4 GHz band, [1,253] in the 6 GHz
+ * band, and [1, 200] otherwise.
+ * The base frequency is specified as (start_factor * 500 kHz).
+ * Constants WF_CHAN_FACTOR_2_4_G, WF_CHAN_FACTOR_5_G, and WF_CHAN_FACTOR_6_G are
+ * defined for 2.4 GHz, 5 GHz, and 6 GHz bands.
+ * The channel range of [1, 14] is only checked for a start_factor of
+ * WF_CHAN_FACTOR_2_4_G (4814).
+ * Odd start_factors produce channels on .5 MHz boundaries, in which case
+ * the answer is rounded down to an integral MHz.
+ * -1 is returned for an out of range channel.
+ *
+ * Reference 802.11-2016, section 17.3.8.3 and section 16.3.6.3
+ *
+ * @param	channel       input channel number
+ * @param	start_factor  base frequency in 500 kHz units, e.g. 10000 for 5 GHz
+ *
+ * @return Returns a frequency in MHz
+ *
+ * @see  WF_CHAN_FACTOR_2_4_G
+ * @see  WF_CHAN_FACTOR_5_G
+ * @see  WF_CHAN_FACTOR_6_G
+ */
+int
+wf_channel2mhz(uint ch, uint start_factor)
+{
+	int freq;
+
+	if ((start_factor == WF_CHAN_FACTOR_2_4_G && (ch < 1 || ch > 14)) ||
+	    (start_factor == WF_CHAN_FACTOR_6_G && (ch < 1 || ch > 253)) ||
+	    (start_factor != WF_CHAN_FACTOR_6_G && (ch < 1 || ch > 200))) {
+		freq = -1;
+	} else if ((start_factor == WF_CHAN_FACTOR_2_4_G) && (ch == 14)) {
+		freq = 2484;
+	} else if ((start_factor == WF_CHAN_FACTOR_6_G) && (ch == 2)) {
+		freq = 5935;
+	} else {
+		freq = ch * 5 + start_factor / 2;
+	}
+
+	return freq;
+}
+
+static const uint16 sidebands[] = {
+	WL_CHANSPEC_CTL_SB_LLL, WL_CHANSPEC_CTL_SB_LLU,
+	WL_CHANSPEC_CTL_SB_LUL, WL_CHANSPEC_CTL_SB_LUU,
+	WL_CHANSPEC_CTL_SB_ULL, WL_CHANSPEC_CTL_SB_ULU,
+	WL_CHANSPEC_CTL_SB_UUL, WL_CHANSPEC_CTL_SB_UUU
+};
+
+/*
+ * Returns the chanspec 80Mhz channel corresponding to the following input
+ * parameters
+ *
+ *	primary_channel - primary 20Mhz channel
+ *	center_channel   - center frequecny of the 80Mhz channel
+ *
+ * The center_channel can be one of {42, 58, 106, 122, 138, 155}
+ *
+ * returns INVCHANSPEC in case of error
+ *
+ * does not support 6G
+ */
+chanspec_t
+wf_chspec_80(uint8 center_channel, uint8 primary_channel)
+{
+
+	chanspec_t chanspec = INVCHANSPEC;
+	chanspec_t chanspec_cur;
+	uint i;
+
+	for (i = 0; i < WF_NUM_SIDEBANDS_80MHZ; i++) {
+		chanspec_cur = CH80MHZ_CHSPEC(center_channel, sidebands[i]);
+		if (primary_channel == wf_chspec_primary20_chan(chanspec_cur)) {
+			chanspec = chanspec_cur;
+			break;
+		}
+	}
+	/* If the loop ended early, we are good, otherwise we did not
+	* find a 80MHz chanspec with the given center_channel that had a primary channel
+	*matching the given primary_channel.
+	*/
+	return chanspec;
+}
+
+/*
+ * Returns the 80+80 chanspec corresponding to the following input parameters
+ *
+ *    primary_20mhz - Primary 20 MHz channel
+ *    chan0 - center channel number of one frequency segment
+ *    chan1 - center channel number of the other frequency segment
+ *
+ * Parameters chan0 and chan1 are channel numbers in {42, 58, 106, 122, 138, 155}.
+ * The primary channel must be contained in one of the 80MHz channels. This routine
+ * will determine which frequency segment is the primary 80 MHz segment.
+ *
+ * Returns INVCHANSPEC in case of error.
+ *
+ * Refer to 802.11-2016 section 22.3.14 "Channelization".
+ *
+ * does not support 6G
+ */
+chanspec_t
+wf_chspec_get8080_chspec(uint8 primary_20mhz, uint8 chan0, uint8 chan1)
+{
+	int sb = 0;
+	uint16 chanspec = 0;
+	int chan0_id = 0, chan1_id = 0;
+	int seg0, seg1;
+
+	chan0_id = channel_80mhz_to_id(chan0);
+	chan1_id = channel_80mhz_to_id(chan1);
+
+	/* make sure the channel numbers were valid */
+	if (chan0_id == -1 || chan1_id == -1)
+		return INVCHANSPEC;
+
+	/* does the primary channel fit with the 1st 80MHz channel ? */
+	sb = channel_to_sb(chan0, primary_20mhz, WL_CHANSPEC_BW_80);
+	if (sb >= 0) {
+		/* yes, so chan0 is frequency segment 0, and chan1 is seg 1 */
+		seg0 = chan0_id;
+		seg1 = chan1_id;
+	} else {
+		/* no, so does the primary channel fit with the 2nd 80MHz channel ? */
+		sb = channel_to_sb(chan1, primary_20mhz, WL_CHANSPEC_BW_80);
+		if (sb < 0) {
+			/* no match for pri_ch to either 80MHz center channel */
+			return INVCHANSPEC;
+		}
+		/* swapped, so chan1 is frequency segment 0, and chan0 is seg 1 */
+		seg0 = chan1_id;
+		seg1 = chan0_id;
+	}
+
+	chanspec = ((seg0 << WL_CHANSPEC_CHAN0_SHIFT) |
+	            (seg1 << WL_CHANSPEC_CHAN1_SHIFT) |
+	            (sb << WL_CHANSPEC_CTL_SB_SHIFT) |
+	            WL_CHANSPEC_BW_8080 |
+	            WL_CHANSPEC_BAND_5G);
+
+	return chanspec;
+}
+
+/*
+ * Returns the center channel of the primary 80 MHz sub-band of the provided chanspec
+ */
+uint8
+wf_chspec_primary80_channel(chanspec_t chanspec)
+{
+	chanspec_t primary80_chspec;
+	uint8 primary80_chan;
+
+	primary80_chspec = wf_chspec_primary80_chspec(chanspec);
+
+	if (primary80_chspec == INVCHANSPEC) {
+		primary80_chan = INVCHANNEL;
+	} else {
+		primary80_chan = CHSPEC_CHANNEL(primary80_chspec);
+	}
+
+	return primary80_chan;
+}
+
+/*
+ * Returns the center channel of the secondary 80 MHz sub-band of the provided chanspec
+ */
+uint8
+wf_chspec_secondary80_channel(chanspec_t chanspec)
+{
+	chanspec_t secondary80_chspec;
+	uint8 secondary80_chan;
+
+	secondary80_chspec = wf_chspec_secondary80_chspec(chanspec);
+
+	if (secondary80_chspec == INVCHANSPEC) {
+		secondary80_chan = INVCHANNEL;
+	} else {
+		secondary80_chan = CHSPEC_CHANNEL(secondary80_chspec);
+	}
+
+	return secondary80_chan;
+}
+
+/*
+ * Returns the chanspec for the primary 80MHz sub-band of an 160MHz or 80+80 channel
+ */
+chanspec_t
+wf_chspec_primary80_chspec(chanspec_t chspec)
+{
+	chanspec_t chspec80;
+	uint center_chan;
+	uint sb;
+
+	ASSERT(!wf_chspec_malformed(chspec));
+
+	if (CHSPEC_IS80(chspec)) {
+		chspec80 = chspec;
+	}
+	else if (CHSPEC_IS8080(chspec)) {
+		sb = CHSPEC_CTL_SB(chspec);
+
+		/* primary sub-band is stored in seg0 */
+		if (CHSPEC_IS5G(chspec)) {
+			center_chan = wf_chspec_5G_id80_to_ch(CHSPEC_CHAN0(chspec));
+		} else if (CHSPEC_IS6G(chspec)) {
+			center_chan = wf_chspec_6G_id80_to_ch(CHSPEC_CHAN0(chspec));
+		} else {
+			center_chan = INVCHANNEL;
+		}
+
+		/* Create primary 80MHz chanspec */
+		chspec80 = (CHSPEC_BAND(chspec) | WL_CHANSPEC_BW_80 | sb | center_chan);
+	}
+	else if (CHSPEC_IS160(chspec)) {
+		center_chan = CHSPEC_CHANNEL(chspec);
+		sb = CHSPEC_CTL_SB(chspec);
+
+		if (sb < WL_CHANSPEC_CTL_SB_ULL) {
+			/* Primary 80MHz is on lower side */
+			center_chan -= CH_40MHZ_APART;
+		}
+		else {
+			/* Primary 80MHz is on upper side */
+			center_chan += CH_40MHZ_APART;
+			sb -= WL_CHANSPEC_CTL_SB_ULL;
+		}
+
+		/* Create primary 80MHz chanspec */
+		chspec80 = (CHSPEC_BAND(chspec) | WL_CHANSPEC_BW_80 | sb | center_chan);
+	}
+	else {
+		chspec80 = INVCHANSPEC;
+	}
+
+	return chspec80;
+}
+
+/*
+ * Returns the chanspec for the secondary 80MHz sub-band of an 160MHz or 80+80 channel
+ */
+chanspec_t
+wf_chspec_secondary80_chspec(chanspec_t chspec)
+{
+	chanspec_t chspec80;
+	uint center_chan;
+
+	ASSERT(!wf_chspec_malformed(chspec));
+
+	if (CHSPEC_IS8080(chspec)) {
+		/* secondary sub-band is stored in seg1 */
+		if (CHSPEC_IS5G(chspec)) {
+			center_chan = wf_chspec_5G_id80_to_ch(CHSPEC_CHAN1(chspec));
+		} else if (CHSPEC_IS6G(chspec)) {
+			center_chan = wf_chspec_6G_id80_to_ch(CHSPEC_CHAN1(chspec));
+		} else {
+			center_chan = INVCHANNEL;
+		}
+
+		/* Create secondary 80MHz chanspec */
+		chspec80 = (CHSPEC_BAND(chspec) |
+		            WL_CHANSPEC_BW_80 |
+		            WL_CHANSPEC_CTL_SB_LL |
+		            center_chan);
+	}
+	else if (CHSPEC_IS160(chspec)) {
+		center_chan = CHSPEC_CHANNEL(chspec);
+
+		if (CHSPEC_CTL_SB(chspec) < WL_CHANSPEC_CTL_SB_ULL) {
+			/* Primary 80MHz is on lower side, so the secondary is on
+			 * the upper side
+			 */
+			center_chan += CH_40MHZ_APART;
+		} else {
+			/* Primary 80MHz is on upper side, so the secondary is on
+			 * the lower side
+			 */
+			center_chan -= CH_40MHZ_APART;
+		}
+
+		/* Create secondary 80MHz chanspec */
+		chspec80 = (CHSPEC_BAND(chspec) |
+		            WL_CHANSPEC_BW_80 |
+		            WL_CHANSPEC_CTL_SB_LL |
+		            center_chan);
+	}
+	else {
+		chspec80 = INVCHANSPEC;
+	}
+
+	return chspec80;
+}
+
+/*
+ * For 160MHz or 80P80 chanspec, set ch[0]/ch[1] to be the low/high 80 Mhz channels
+ *
+ * For 20/40/80MHz chanspec, set ch[0] to be the center freq, and chan[1]=-1
+ */
+void
+wf_chspec_get_80p80_channels(chanspec_t chspec, uint8 *ch)
+{
+
+	if (CHSPEC_IS160(chspec)) {
+		uint8 center_chan = CHSPEC_CHANNEL(chspec);
+		ch[0] = center_chan - CH_40MHZ_APART;
+		ch[1] = center_chan + CH_40MHZ_APART;
+	}
+	else {
+		/* for 20, 40, and 80 Mhz */
+		ch[0] = CHSPEC_CHANNEL(chspec);
+		ch[1] = -1;
+	}
+	return;
+
+}
+
+/*
+ * Returns the center channel of the primary 160MHz sub-band of the provided chanspec
+ */
+uint8
+wf_chspec_primary160_channel(chanspec_t chanspec)
+{
+	chanspec_t primary160_chspec;
+	uint8 primary160_chan;
+
+	primary160_chspec = wf_chspec_primary160_chspec(chanspec);
+
+	if (primary160_chspec == INVCHANSPEC) {
+		primary160_chan = INVCHANNEL;
+	} else {
+		primary160_chan = CHSPEC_CHANNEL(primary160_chspec);
+	}
+
+	return primary160_chan;
+}
+
+/*
+ * Returns the chanspec for the primary 160MHz sub-band of an 240/320MHz or 160+160 channel
+ */
+chanspec_t
+wf_chspec_primary160_chspec(chanspec_t chspec)
+{
+	chanspec_t chspec160;
+	uint center_chan;
+	uint sb;
+
+	ASSERT(!wf_chspec_malformed(chspec));
+
+	if (CHSPEC_IS160(chspec)) {
+		chspec160 = chspec;
+	}
+	else if (CHSPEC_IS240(chspec)) {
+		uint8 ch_id = CHSPEC_GE240_CHAN(chspec);
+		center_chan = wf_chspec_240_id2cch(chspec);
+		sb = CHSPEC_GE240_SB(chspec) >> WL_CHANSPEC_GE240_SB_SHIFT;
+		/*
+		 * Identify the chanspec is of the form 160+80 or 80+160 from the channel ID.
+		 * Channel ID : even for 160+80 and odd for 80+160
+		 */
+		if ((!(ch_id & 0x1u)) && (sb < 8u)) {
+			/* Primary 160MHz is on lower side */
+			center_chan -= CH_40MHZ_APART;
+		} else if ((ch_id & 0x1u) && (sb >= 4u)) {
+			/* Primary 160MHz is on upper side */
+			center_chan += CH_40MHZ_APART;
+			sb -= 4u;
+		} else {
+			chspec160 = INVCHANSPEC;
+			goto done;
+		}
+
+		/* Create primary 160MHz chanspec */
+		chspec160 = (CHSPEC_BAND(chspec) |
+		             WL_CHANSPEC_BW_160 |
+		             (sb << WL_CHANSPEC_CTL_SB_SHIFT) |
+		             center_chan);
+	} else if (CHSPEC_IS320(chspec)) {
+		center_chan = wf_chspec_320_id2cch(chspec);
+		sb = CHSPEC_GE240_SB(chspec) >> WL_CHANSPEC_GE240_SB_SHIFT;
+
+		if (sb < 8u) {
+			/* Primary 160MHz is on lower side */
+			center_chan -= CH_80MHZ_APART;
+		}
+		else {
+			/* Primary 160MHz is on upper side */
+			center_chan += CH_80MHZ_APART;
+			sb -= 8u;
+		}
+
+		/* Create primary 160MHz chanspec */
+		chspec160 = (CHSPEC_BAND(chspec) |
+		             WL_CHANSPEC_BW_160 |
+		             (sb << WL_CHANSPEC_CTL_SB_SHIFT) |
+		             center_chan);
+	}
+	else {
+		chspec160 = INVCHANSPEC;
+	}
+done:
+	return chspec160;
+}
+
+/* Populates array with all 20MHz side bands of a given chanspec_t in the following order:
+ *		primary20, secondary20, two secondary40s, four secondary80s.
+ *    'chspec' is the chanspec of interest
+ *    'pext' must point to an uint8 array of long enough to hold all side bands of the given chspec
+ *
+ * Works with 20, 40, 80, and 160MHz chspec
+ */
+void
+wf_get_all_ext(chanspec_t chspec, uint8 *pext)
+{
+	chanspec_t t = (CHSPEC_IS160(chspec)) ? /* if bw > 80MHz */
+		wf_chspec_primary80_chspec(chspec) : (chspec); /* extract primary 80 */
+	/* primary20 channel as first element */
+	uint8 pri_ch = (pext)[0] = wf_chspec_primary20_chan(t);
+
+	if (CHSPEC_IS20(chspec)) {
+		return; /* nothing more to do since 20MHz chspec */
+	}
+	/* 20MHz EXT */
+	(pext)[1] = (IS_CTL_IN_L20(t) ? pri_ch + CH_20MHZ_APART : pri_ch - CH_20MHZ_APART);
+
+	if (CHSPEC_IS40(chspec)) {
+		return; /* nothing more to do since 40MHz chspec */
+	}
+	/* center 40MHz EXT */
+	t = wf_channel2chspec((IS_CTL_IN_L40(chspec) ?
+		pri_ch + CH_40MHZ_APART : pri_ch - CH_40MHZ_APART), WL_CHANSPEC_BW_40);
+	GET_ALL_SB(t, &((pext)[2])); /* get the 20MHz side bands in 40MHz EXT */
+
+	if (CHSPEC_IS80(chspec)) {
+		return; /* nothing more to do since 80MHz chspec */
+	}
+	t = CH80MHZ_CHSPEC(wf_chspec_secondary80_channel(chspec), WL_CHANSPEC_CTL_SB_LLL);
+	/* get the 20MHz side bands in 80MHz EXT (secondary) */
+	GET_ALL_SB(t, &((pext)[4]));
+}
+
+/*
+ * Given two chanspecs, returns true if they overlap.
+ * (Overlap: At least one 20MHz subband is common between the two chanspecs provided)
+ */
+bool wf_chspec_overlap(chanspec_t chspec0, chanspec_t chspec1)
+{
+	uint8 ch0, ch1;
+
+	if (CHSPEC_BAND(chspec0) != CHSPEC_BAND(chspec1)) {
+		return FALSE;
+	}
+
+	FOREACH_20_SB(chspec0, ch0) {
+		FOREACH_20_SB(chspec1, ch1) {
+			if ((uint)ABS(ch0 - ch1) < CH_20MHZ_APART) {
+				return TRUE;
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+uint8
+channel_bw_to_width(chanspec_t chspec)
+{
+	uint8 channel_width;
+
+	if (CHSPEC_IS80(chspec))
+		channel_width = VHT_OP_CHAN_WIDTH_80;
+	else if (CHSPEC_IS160(chspec))
+		channel_width = VHT_OP_CHAN_WIDTH_160;
+	else if (CHSPEC_IS8080(chspec))
+		channel_width = VHT_OP_CHAN_WIDTH_80_80;
+	else
+		channel_width = VHT_OP_CHAN_WIDTH_20_40;
+
+	return channel_width;
+}
+
+uint wf_chspec_first_20_sb(chanspec_t chspec)
+{
+	if (CHSPEC_IS80(chspec)) {
+		return LL_20_SB(CHSPEC_CHANNEL(chspec));
+	} else if (CHSPEC_IS40(chspec)) {
+		return LOWER_20_SB(CHSPEC_CHANNEL(chspec));
+	} else {
+		return CHSPEC_CHANNEL(chspec);
+	}
+}
+
+chanspec_t
+wf_create_chspec_sb(uint sb, uint center_channel, chanspec_bw_t bw, chanspec_band_t band)
+{
+	chanspec_t chspec;
+	if (sb > (WL_CHANSPEC_CTL_SB_MASK >> WL_CHANSPEC_CTL_SB_SHIFT)) {
+		return INVCHANSPEC;
+	}
+	chspec = center_channel | band | bw | ((uint)sb << WL_CHANSPEC_CTL_SB_SHIFT);
+	return wf_chspec_valid(chspec) ? chspec : INVCHANSPEC;
+}
+
+chanspec_t
+wf_create_8080MHz_chspec_sb(uint sb, uint chan0, uint chan1, chanspec_band_t band)
+{
+	int chan0_id, chan1_id, seg0, seg1;
+	chanspec_t chspec;
+
+	if (sb > (WL_CHANSPEC_CTL_SB_UUU >> WL_CHANSPEC_CTL_SB_SHIFT)) {
+		return INVCHANSPEC;
+	}
+	/* From here on sb is not an index, but value for SB field */
+	sb <<= WL_CHANSPEC_CTL_SB_SHIFT;
+
+	/* frequency segments need to be non-contiguous, so the channel
+	 * separation needs to be greater than 80MHz
+	 */
+	if ((uint)ABS((int)(chan0 - chan1)) <= CH_80MHZ_APART) {
+		return INVCHANSPEC;
+	}
+
+	if (band == WL_CHANSPEC_BAND_5G) {
+		chan0_id = channel_80mhz_to_id(chan0);
+		chan1_id = channel_80mhz_to_id(chan1);
+	} else if (band == WL_CHANSPEC_BAND_6G) {
+		chan0_id = channel_6g_80mhz_to_id(chan0);
+		chan1_id = channel_6g_80mhz_to_id(chan1);
+	} else {
+		return INVCHANSPEC;
+	}
+
+	/* make sure the channel numbers were valid */
+	if ((chan0_id == -1) || (chan1_id == -1)) {
+		return INVCHANSPEC;
+	}
+	/* Optionally swapping channel IDs to make sure that control subchannel
+	 * is in chan0
+	 */
+	if (sb < WL_CHANSPEC_CTL_SB_ULL) {
+		seg0 = chan0_id;
+		seg1 = chan1_id;
+	} else {
+		seg0 = chan1_id;
+		seg1 = chan0_id;
+		sb -= WL_CHANSPEC_CTL_SB_ULL;
+	}
+	chspec = ((seg0 << WL_CHANSPEC_CHAN0_SHIFT) |
+	         (seg1 << WL_CHANSPEC_CHAN1_SHIFT) |
+	         sb | WL_CHANSPEC_BW_8080 | band);
+	return wf_chspec_valid(chspec) ? chspec : INVCHANSPEC;
+}
+
+chanspec_t
+wf_create_160160MHz_chspec_sb(uint sb, uint chan0, uint chan1, chanspec_band_t band)
+{
+	int chan0_id, chan1_id, seg0, seg1;
+	chanspec_t chspec;
+
+	if (sb > (WL_CHANSPEC_CTL_SB_UUU >> WL_CHANSPEC_CTL_SB_SHIFT)) {
+		return INVCHANSPEC;
+	}
+	/* From here on sb is not an index, but value for SB field */
+	sb <<= WL_CHANSPEC_CTL_SB_SHIFT;
+
+	/* frequency segments need to be non-contiguous, so the channel
+	 * separation needs to be greater than 160MHz
+	 */
+	if ((uint)ABS((int)(chan0 - chan1)) <= CH_160MHZ_APART) {
+		return INVCHANSPEC;
+	}
+
+	if (band == WL_CHANSPEC_BAND_5G) {
+		chan0_id = channel_5g_160mhz_to_id(chan0);
+		chan1_id = channel_5g_160mhz_to_id(chan1);
+	} else if (band == WL_CHANSPEC_BAND_6G) {
+		chan0_id = channel_6g_160mhz_to_id(chan0);
+		chan1_id = channel_6g_160mhz_to_id(chan1);
+	} else {
+		return INVCHANSPEC;
+	}
+
+	/* make sure the channel numbers were valid */
+	if ((chan0_id == -1) || (chan1_id == -1)) {
+		return INVCHANSPEC;
+	}
+	/* Optionally swapping channel IDs to make sure that control subchannel
+	 * is in chan0
+	 */
+	if (sb < WL_CHANSPEC_CTL_SB_ULL) {
+		seg0 = chan0_id;
+		seg1 = chan1_id;
+	} else {
+		seg0 = chan1_id;
+		seg1 = chan0_id;
+		sb -= WL_CHANSPEC_CTL_SB_ULL;
+	}
+	chspec = ((seg0 << WL_CHANSPEC_CHAN0_SHIFT) |
+	         (seg1 << WL_CHANSPEC_CHAN1_SHIFT) |
+	         sb | WL_CHANSPEC_BW_160160 | band);
+	return wf_chspec_valid(chspec) ? chspec : INVCHANSPEC;
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcmwifi_radiotap.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcmwifi_radiotap.c
@@ -0,0 +1,1054 @@
+/*
+ * RadioTap utility routines for WL
+ * This file housing the functions use by
+ * wl driver.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Dual:>>
+ */
+
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <bcmwifi_channels.h>
+#include <hndd11.h>
+#include <bcmwifi_radiotap.h>
+
+const struct rtap_field rtap_parse_info[] = {
+	{8, 8}, /* 0:  IEEE80211_RADIOTAP_TSFT */
+	{1, 1}, /* 1:  IEEE80211_RADIOTAP_FLAGS */
+	{1, 1}, /* 2:  IEEE80211_RADIOTAP_RATE */
+	{4, 2}, /* 3:  IEEE80211_RADIOTAP_CHANNEL */
+	{2, 2}, /* 4:  IEEE80211_RADIOTAP_FHSS */
+	{1, 1}, /* 5:  IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
+	{1, 1}, /* 6:  IEEE80211_RADIOTAP_DBM_ANTNOISE */
+	{2, 2}, /* 7:  IEEE80211_RADIOTAP_LOCK_QUALITY */
+	{2, 2}, /* 8:  IEEE80211_RADIOTAP_TX_ATTENUATION */
+	{2, 2}, /* 9:  IEEE80211_RADIOTAP_DB_TX_ATTENUATION */
+	{1, 1}, /* 10: IEEE80211_RADIOTAP_DBM_TX_POWER */
+	{1, 1}, /* 11: IEEE80211_RADIOTAP_ANTENNA */
+	{1, 1}, /* 12: IEEE80211_RADIOTAP_DB_ANTSIGNAL */
+	{1, 1}, /* 13: IEEE80211_RADIOTAP_DB_ANTNOISE */
+	{0, 0}, /* 14: netbsd */
+	{2, 2}, /* 15: IEEE80211_RADIOTAP_TXFLAGS */
+	{0, 0}, /* 16: missing */
+	{1, 1}, /* 17: IEEE80211_RADIOTAP_RETRIES */
+	{8, 4}, /* 18: IEEE80211_RADIOTAP_XCHANNEL */
+	{3, 1}, /* 19: IEEE80211_RADIOTAP_MCS */
+	{8, 4}, /* 20: IEEE80211_RADIOTAP_AMPDU_STATUS */
+	{12, 2}, /* 21: IEEE80211_RADIOTAP_VHT */
+	{0, 0}, /* 22: */
+	{0, 0}, /* 23: */
+	{0, 0}, /* 24: */
+	{0, 0}, /* 25: */
+	{0, 0}, /* 26: */
+	{0, 0}, /* 27: */
+	{0, 0}, /* 28: */
+	{0, 0}, /* 29: IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE */
+	{6, 2}, /* 30: IEEE80211_RADIOTAP_VENDOR_NAMESPACE */
+	{0, 0}  /* 31: IEEE80211_RADIOTAP_EXT */
+};
+
+static int bitmap = 0;
+
+void
+radiotap_add_vendor_ns(ieee80211_radiotap_header_t *hdr);
+
+void
+radiotap_encode_multi_rssi(monitor_pkt_rxsts_t* rxsts, ieee80211_radiotap_header_t *hdr);
+void
+radiotap_encode_bw_signaling(uint16 mask, struct wl_rxsts* rxsts, ieee80211_radiotap_header_t *hdr);
+#ifdef MONITOR_DNGL_CONV
+void radiotap_encode_alignpad(ieee80211_radiotap_header_t *hdr, uint16 pad_req);
+#endif
+
+static const uint8 brcm_oui[] =  {0x00, 0x10, 0x18};
+
+static void
+wl_rtapParseReset(radiotap_parse_t *rtap)
+{
+	rtap->idx = 0;		/* reset parse index */
+	rtap->offset = 0;	/* reset current field pointer */
+}
+
+static void*
+wl_rtapParseFindField(radiotap_parse_t *rtap, uint search_idx)
+{
+	uint idx;	/* first bit index to parse */
+	uint32 btmap;	/* presence bitmap */
+	uint offset, field_offset;
+	uint align, len;
+	void *ptr = NULL;
+
+	if (search_idx > IEEE80211_RADIOTAP_EXT)
+		return ptr;
+
+	if (search_idx < rtap->idx)
+		wl_rtapParseReset(rtap);
+
+	btmap = rtap->hdr->it_present;
+	idx = rtap->idx;
+	offset = rtap->offset;
+
+	/* loop through each field index until we get to the target idx */
+	while (idx <= search_idx) {
+		/* if field 'idx' is present, update the offset and check for a match */
+		if ((1 << idx) & btmap) {
+			/* if we hit a field for which we have no parse info
+			 * we need to just bail out
+			 */
+			if (rtap_parse_info[idx].align == 0)
+				break;
+
+			/* step past any alignment padding */
+			align = rtap_parse_info[idx].align;
+			len = rtap_parse_info[idx].len;
+
+			/* ROUNDUP */
+			field_offset = ((offset + (align - 1)) / align) * align;
+
+			/* if this field is not in the boulds of the header
+			 * just bail out
+			 */
+			if (field_offset + len > rtap->fields_len)
+				break;
+
+			/* did we find the field? */
+			if (idx == search_idx)
+				ptr = (uint8*)rtap->fields + field_offset;
+
+			/* step past this field */
+			offset = field_offset + len;
+		}
+
+		idx++;
+	}
+
+	rtap->idx = idx;
+	rtap->offset = offset;
+
+	return ptr;
+}
+
+ratespec_t
+wl_calcRspecFromRTap(uint8 *rtap_header)
+{
+	ratespec_t rspec = 0;
+	radiotap_parse_t rtap;
+	uint8 rate = 0;
+	uint8 flags = 0;
+	int flags_present = FALSE;
+	uint8 mcs = 0;
+	uint8 mcs_flags = 0;
+	uint8 mcs_known = 0;
+	int mcs_present = FALSE;
+	void *p;
+
+	wl_rtapParseInit(&rtap, rtap_header);
+
+	p = wl_rtapParseFindField(&rtap, IEEE80211_RADIOTAP_FLAGS);
+	if (p != NULL) {
+		flags_present = TRUE;
+		flags = ((uint8*)p)[0];
+	}
+
+	p = wl_rtapParseFindField(&rtap, IEEE80211_RADIOTAP_RATE);
+	if (p != NULL)
+		rate = ((uint8*)p)[0];
+
+	p = wl_rtapParseFindField(&rtap, IEEE80211_RADIOTAP_MCS);
+	if (p != NULL) {
+		mcs_present = TRUE;
+		mcs_known = ((uint8*)p)[0];
+		mcs_flags = ((uint8*)p)[1];
+		mcs = ((uint8*)p)[2];
+	}
+
+	if (rate != 0) {
+		/* validate the DSSS rates 1,2,5.5,11 */
+		if (rate == 2 || rate == 4 || rate == 11 || rate == 22) {
+			rspec = LEGACY_RSPEC(rate) | WL_RSPEC_OVERRIDE_RATE;
+			if (flags_present && (flags & IEEE80211_RADIOTAP_F_SHORTPRE)) {
+				rspec |= WL_RSPEC_OVERRIDE_MODE | WL_RSPEC_SHORT_PREAMBLE;
+			}
+		}
+	} else if (mcs_present) {
+		/* validate the MCS value */
+		if (mcs <= 23 || mcs == 32) {
+			uint32 override = 0;
+			if (mcs_known &
+			    (IEEE80211_RADIOTAP_MCS_HAVE_GI |
+			     IEEE80211_RADIOTAP_MCS_HAVE_FMT |
+			     IEEE80211_RADIOTAP_MCS_HAVE_FEC)) {
+				override = WL_RSPEC_OVERRIDE_MODE;
+			}
+
+			rspec = HT_RSPEC(mcs) | WL_RSPEC_OVERRIDE_RATE;
+
+			if ((mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_GI) &&
+			    (mcs_flags & IEEE80211_RADIOTAP_MCS_SGI))
+				rspec |= WL_RSPEC_SGI;
+			if ((mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FMT) &&
+			    (mcs_flags & IEEE80211_RADIOTAP_MCS_FMT_GF))
+				rspec |= WL_RSPEC_SHORT_PREAMBLE;
+			if ((mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_FEC) &&
+			    (mcs_flags & IEEE80211_RADIOTAP_MCS_FEC_LDPC))
+				rspec |= WL_RSPEC_LDPC;
+
+			rspec |= override;
+		}
+	}
+
+	return rspec;
+}
+
+bool
+wl_rtapFlags(uint8 *rtap_header, uint8* flags)
+{
+	radiotap_parse_t rtap;
+	void *p;
+
+	wl_rtapParseInit(&rtap, rtap_header);
+
+	p = wl_rtapParseFindField(&rtap, IEEE80211_RADIOTAP_FLAGS);
+	if (p != NULL) {
+		*flags = ((uint8*)p)[0];
+	}
+
+	return (p != NULL);
+}
+
+void
+wl_rtapParseInit(radiotap_parse_t *rtap, uint8 *rtap_header)
+{
+	uint rlen;
+	uint32 *present_word;
+	struct ieee80211_radiotap_header *hdr = (struct ieee80211_radiotap_header*)rtap_header;
+
+	bzero(rtap, sizeof(radiotap_parse_t));
+
+	rlen = hdr->it_len; /* total space in rtap_header */
+
+	/* If a precence word has the IEEE80211_RADIOTAP_EXT bit set it indicates
+	 * that there is another precence word.
+	 * Step over the presence words until we find the end of the list
+	 */
+	present_word = &hdr->it_present;
+	/* remaining length in header past it_present */
+	rlen -= sizeof(struct ieee80211_radiotap_header);
+
+	while ((*present_word & (1<<IEEE80211_RADIOTAP_EXT)) && rlen >= 4) {
+		present_word++;
+		rlen -= 4;	/* account for 4 bytes of present_word */
+	}
+
+	rtap->hdr = hdr;
+	rtap->fields = (uint8*)(present_word + 1);
+	rtap->fields_len = rlen;
+	wl_rtapParseReset(rtap);
+}
+
+uint
+wl_radiotap_rx(struct dot11_header *mac_header,	wl_rxsts_t *rxsts, bsd_header_rx_t *bsd_header)
+{
+	int channel_frequency;
+	uint32 channel_flags;
+	uint8 flags;
+	uint8 *cp;
+	uint pad_len;
+	uint32 field_map;
+	uint16 fc;
+	uint bsd_header_len;
+	uint16 ampdu_flags = 0;
+
+	fc = LTOH16(mac_header->fc);
+	pad_len = 3;
+	field_map = WL_RADIOTAP_PRESENT_BASIC;
+
+	if (CHSPEC_IS2G(rxsts->chanspec)) {
+		channel_flags = IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN;
+		channel_frequency = wf_channel2mhz(wf_chspec_ctlchan(rxsts->chanspec),
+			WF_CHAN_FACTOR_2_4_G);
+	} else if (CHSPEC_IS5G(rxsts->chanspec)) {
+		channel_flags = IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM;
+		channel_frequency = wf_channel2mhz(wf_chspec_ctlchan(rxsts->chanspec),
+			WF_CHAN_FACTOR_5_G);
+	} else {
+		channel_flags = IEEE80211_CHAN_OFDM;
+		channel_frequency = wf_channel2mhz(wf_chspec_ctlchan(rxsts->chanspec),
+			WF_CHAN_FACTOR_6_G);
+	}
+
+	if ((rxsts->nfrmtype & WL_RXS_NFRM_AMPDU_FIRST) ||
+		(rxsts->nfrmtype & WL_RXS_NFRM_AMPDU_SUB)) {
+
+		ampdu_flags = IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN;
+	}
+
+	flags = IEEE80211_RADIOTAP_F_FCS;
+
+	if (rxsts->preamble == WL_RXS_PREAMBLE_SHORT)
+		flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+
+	if ((fc &  FC_WEP) == FC_WEP)
+		flags |= IEEE80211_RADIOTAP_F_WEP;
+
+	if ((fc & FC_MOREFRAG) == FC_MOREFRAG)
+		flags |= IEEE80211_RADIOTAP_F_FRAG;
+
+	if (rxsts->pkterror & WL_RXS_CRC_ERROR)
+		flags |= IEEE80211_RADIOTAP_F_BADFCS;
+
+	if (rxsts->encoding == WL_RXS_ENCODING_HT)
+		field_map = WL_RADIOTAP_PRESENT_HT;
+	else if (rxsts->encoding == WL_RXS_ENCODING_VHT)
+		field_map = WL_RADIOTAP_PRESENT_VHT;
+
+	bsd_header_len = sizeof(struct wl_radiotap_sna); /* start with sna size */
+	/* Test for signal/noise values and update length and field bitmap */
+	if (rxsts->signal == 0) {
+		field_map &= ~(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
+		pad_len = (pad_len - 1);
+		bsd_header_len--;
+	}
+
+	if (rxsts->noise == 0) {
+		field_map &= ~(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE);
+		pad_len = (pad_len - 1);
+		bsd_header_len--;
+	}
+
+	if (rxsts->encoding == WL_RXS_ENCODING_HT ||
+	    rxsts->encoding == WL_RXS_ENCODING_VHT) {
+		struct wl_radiotap_hdr *rtht = &bsd_header->hdr;
+		struct wl_radiotap_ht_tail *tail;
+
+		/*
+		 * Header length is complicated due to dynamic
+		 * presence of signal and noise fields
+		 * and padding for xchannel following
+		 * signal/noise/ant.
+		 * Start with length of wl_radiotap_ht plus
+		 * signal/noise/ant
+		 */
+		bsd_header_len += sizeof(struct wl_radiotap_hdr) + pad_len;
+		bsd_header_len += sizeof(struct wl_radiotap_xchan);
+		if (rxsts->nfrmtype == WL_RXS_NFRM_AMPDU_FIRST ||
+			rxsts->nfrmtype == WL_RXS_NFRM_AMPDU_SUB) {
+			bsd_header_len += sizeof(struct wl_radiotap_ampdu);
+		}
+		/* add the length of the tail end of the structure */
+		if (rxsts->encoding == WL_RXS_ENCODING_HT)
+			bsd_header_len += sizeof(struct wl_htmcs);
+		else if (rxsts->encoding == WL_RXS_ENCODING_VHT)
+			bsd_header_len += sizeof(struct wl_vhtmcs);
+		bzero((uint8 *)rtht, sizeof(*rtht));
+
+		rtht->ieee_radiotap.it_version = 0;
+		rtht->ieee_radiotap.it_pad = 0;
+		rtht->ieee_radiotap.it_len = (uint16)HTOL16(bsd_header_len);
+		rtht->ieee_radiotap.it_present = HTOL32(field_map);
+
+		rtht->tsft = HTOL64((uint64)rxsts->mactime);
+		rtht->flags = flags;
+		rtht->channel_freq = (uint16)HTOL16(channel_frequency);
+		rtht->channel_flags = (uint16)HTOL16(channel_flags);
+
+		cp = bsd_header->pad;
+		/* add in signal/noise/ant */
+		if (rxsts->signal != 0) {
+			*cp++ = (int8)rxsts->signal;
+			pad_len--;
+		}
+		if (rxsts->noise != 0) {
+			*cp++ = (int8)rxsts->noise;
+			pad_len--;
+		}
+		*cp++ = (int8)rxsts->antenna;
+		pad_len--;
+
+		tail = (struct wl_radiotap_ht_tail *)(bsd_header->ht);
+		/* Fill in XCHANNEL */
+		if (CHSPEC_IS40(rxsts->chanspec)) {
+			if (CHSPEC_SB_UPPER(rxsts->chanspec))
+				channel_flags |= IEEE80211_CHAN_HT40D;
+			else
+				channel_flags |= IEEE80211_CHAN_HT40U;
+		} else
+			channel_flags |= IEEE80211_CHAN_HT20;
+
+		tail->xc.xchannel_flags = HTOL32(channel_flags);
+		tail->xc.xchannel_freq = (uint16)HTOL16(channel_frequency);
+		tail->xc.xchannel_channel = wf_chspec_ctlchan(rxsts->chanspec);
+		tail->xc.xchannel_maxpower = (17*2);
+		/* fill in A-mpdu Status */
+		tail->ampdu.ref_num = mac_header->seq;
+		tail->ampdu.flags = ampdu_flags;
+		tail->ampdu.delimiter_crc = 0;
+		tail->ampdu.reserved = 0;
+
+		if (rxsts->encoding == WL_RXS_ENCODING_HT) {
+			tail->u.ht.mcs_index = rxsts->mcs;
+			tail->u.ht.mcs_known = (IEEE80211_RADIOTAP_MCS_HAVE_BW |
+			                        IEEE80211_RADIOTAP_MCS_HAVE_MCS |
+			                        IEEE80211_RADIOTAP_MCS_HAVE_GI |
+			                        IEEE80211_RADIOTAP_MCS_HAVE_FEC |
+			                        IEEE80211_RADIOTAP_MCS_HAVE_FMT);
+			tail->u.ht.mcs_flags = 0;
+
+			switch (rxsts->htflags & WL_RXS_HTF_BW_MASK) {
+			case WL_RXS_HTF_20L:
+				tail->u.ht.mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_20L;
+				break;
+			case WL_RXS_HTF_20U:
+				tail->u.ht.mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_20U;
+				break;
+			case WL_RXS_HTF_40:
+				tail->u.ht.mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_40;
+				break;
+			default:
+				tail->u.ht.mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_20;
+				break;
+			}
+
+			if (rxsts->htflags & WL_RXS_HTF_SGI)
+				tail->u.ht.mcs_flags |= IEEE80211_RADIOTAP_MCS_SGI;
+			if (rxsts->preamble & WL_RXS_PREAMBLE_HT_GF)
+				tail->u.ht.mcs_flags |= IEEE80211_RADIOTAP_MCS_FMT_GF;
+			if (rxsts->htflags & WL_RXS_HTF_LDPC)
+				tail->u.ht.mcs_flags |= IEEE80211_RADIOTAP_MCS_FEC_LDPC;
+		} else if (rxsts->encoding == WL_RXS_ENCODING_VHT) {
+			tail->u.vht.vht_known = (IEEE80211_RADIOTAP_VHT_HAVE_STBC |
+			                         IEEE80211_RADIOTAP_VHT_HAVE_TXOP_PS |
+			                         IEEE80211_RADIOTAP_VHT_HAVE_GI |
+			                         IEEE80211_RADIOTAP_VHT_HAVE_SGI_NSYM_DA |
+			                         IEEE80211_RADIOTAP_VHT_HAVE_LDPC_EXTRA |
+			                         IEEE80211_RADIOTAP_VHT_HAVE_BF |
+			                         IEEE80211_RADIOTAP_VHT_HAVE_BW |
+			                         IEEE80211_RADIOTAP_VHT_HAVE_GID |
+			                         IEEE80211_RADIOTAP_VHT_HAVE_PAID);
+
+			tail->u.vht.vht_flags = (uint8)HTOL16(rxsts->vhtflags);
+
+			switch (rxsts->bw) {
+			case WL_RXS_VHT_BW_20:
+				tail->u.vht.vht_bw = IEEE80211_RADIOTAP_VHT_BW_20;
+				break;
+			case WL_RXS_VHT_BW_40:
+				tail->u.vht.vht_bw = IEEE80211_RADIOTAP_VHT_BW_40;
+				break;
+			case WL_RXS_VHT_BW_20L:
+				tail->u.vht.vht_bw = IEEE80211_RADIOTAP_VHT_BW_20L;
+				break;
+			case WL_RXS_VHT_BW_20U:
+				tail->u.vht.vht_bw = IEEE80211_RADIOTAP_VHT_BW_20U;
+				break;
+			case WL_RXS_VHT_BW_80:
+				tail->u.vht.vht_bw = IEEE80211_RADIOTAP_VHT_BW_80;
+				break;
+			case WL_RXS_VHT_BW_40L:
+				tail->u.vht.vht_bw = IEEE80211_RADIOTAP_VHT_BW_40L;
+				break;
+			case WL_RXS_VHT_BW_40U:
+				tail->u.vht.vht_bw = IEEE80211_RADIOTAP_VHT_BW_40U;
+				break;
+			case WL_RXS_VHT_BW_20LL:
+				tail->u.vht.vht_bw = IEEE80211_RADIOTAP_VHT_BW_20LL;
+				break;
+			case WL_RXS_VHT_BW_20LU:
+				tail->u.vht.vht_bw = IEEE80211_RADIOTAP_VHT_BW_20LU;
+				break;
+			case WL_RXS_VHT_BW_20UL:
+				tail->u.vht.vht_bw = IEEE80211_RADIOTAP_VHT_BW_20UL;
+				break;
+			case WL_RXS_VHT_BW_20UU:
+				tail->u.vht.vht_bw = IEEE80211_RADIOTAP_VHT_BW_20UU;
+				break;
+			default:
+				tail->u.vht.vht_bw = IEEE80211_RADIOTAP_VHT_BW_20;
+				break;
+			}
+
+			tail->u.vht.vht_mcs_nss[0] = (rxsts->mcs << 4) |
+				(rxsts->nss & IEEE80211_RADIOTAP_VHT_NSS);
+			tail->u.vht.vht_mcs_nss[1] = 0;
+			tail->u.vht.vht_mcs_nss[2] = 0;
+			tail->u.vht.vht_mcs_nss[3] = 0;
+
+			tail->u.vht.vht_coding = rxsts->coding;
+			tail->u.vht.vht_group_id = rxsts->gid;
+			tail->u.vht.vht_partial_aid = HTOL16(rxsts->aid);
+		}
+	} else {
+		struct wl_radiotap_hdr *rtl = &bsd_header->hdr;
+
+		/*
+		 * Header length is complicated due to dynamic presence of signal and noise fields
+		 * Start with length of wl_radiotap_legacy plus signal/noise/ant
+		 */
+		bsd_header_len = sizeof(struct wl_radiotap_hdr) + pad_len;
+		bzero((uint8 *)rtl, sizeof(*rtl));
+
+		rtl->ieee_radiotap.it_version = 0;
+		rtl->ieee_radiotap.it_pad = 0;
+		rtl->ieee_radiotap.it_len = (uint16)HTOL16(bsd_header_len);
+		rtl->ieee_radiotap.it_present = HTOL32(field_map);
+
+		rtl->tsft = HTOL64((uint64)rxsts->mactime);
+		rtl->flags = flags;
+		rtl->u.rate = (uint8)rxsts->datarate;
+		rtl->channel_freq = (uint16)HTOL16(channel_frequency);
+		rtl->channel_flags = (uint16)HTOL16(channel_flags);
+
+		/* add in signal/noise/ant */
+		cp = bsd_header->pad;
+		if (rxsts->signal != 0)
+			*cp++ = (int8)rxsts->signal;
+		if (rxsts->noise != 0)
+			*cp++ = (int8)rxsts->noise;
+		*cp++ = (int8)rxsts->antenna;
+	}
+	return bsd_header_len;
+}
+
+static int
+wl_radiotap_rx_channel_frequency(wl_rxsts_t *rxsts)
+{
+	if (CHSPEC_IS2G(rxsts->chanspec)) {
+		return wf_channel2mhz(wf_chspec_ctlchan(rxsts->chanspec),
+			WF_CHAN_FACTOR_2_4_G);
+	} else if (CHSPEC_IS5G(rxsts->chanspec)) {
+		return wf_channel2mhz(wf_chspec_ctlchan(rxsts->chanspec),
+			WF_CHAN_FACTOR_5_G);
+	} else {
+		return wf_channel2mhz(wf_chspec_ctlchan(rxsts->chanspec),
+			WF_CHAN_FACTOR_6_G);
+	}
+}
+
+static uint16
+wl_radiotap_rx_channel_flags(wl_rxsts_t *rxsts)
+{
+	if (CHSPEC_IS2G(rxsts->chanspec)) {
+		return (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN);
+	} else if (CHSPEC_IS5G(rxsts->chanspec)) {
+		return (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM);
+	} else {
+		return (IEEE80211_CHAN_OFDM);
+	}
+}
+
+static uint8
+wl_radiotap_rx_flags(struct dot11_header *mac_header, wl_rxsts_t *rxsts)
+{
+	uint8 flags;
+	uint16 fc;
+
+	fc = ltoh16(mac_header->fc);
+
+	flags = IEEE80211_RADIOTAP_F_FCS;
+
+	if (rxsts->preamble == WL_RXS_PREAMBLE_SHORT)
+		flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+
+	if (fc & FC_WEP)
+		flags |= IEEE80211_RADIOTAP_F_WEP;
+
+	if (fc & FC_MOREFRAG)
+		flags |= IEEE80211_RADIOTAP_F_FRAG;
+
+	return flags;
+}
+
+uint
+wl_radiotap_rx_legacy(struct dot11_header *mac_header,
+	wl_rxsts_t *rxsts, ieee80211_radiotap_header_t *rtap_hdr)
+{
+	int channel_frequency;
+	uint16 channel_flags;
+	uint8 flags;
+	uint16 rtap_len = LTOH16(rtap_hdr->it_len);
+	wl_radiotap_legacy_t *rtl = (wl_radiotap_legacy_t *)((uint8*)rtap_hdr + rtap_len);
+
+	rtap_len += sizeof(wl_radiotap_legacy_t);
+	rtap_hdr->it_len = HTOL16(rtap_len);
+	rtap_hdr->it_present |= HTOL32(WL_RADIOTAP_PRESENT_LEGACY);
+
+	channel_frequency = (uint16)wl_radiotap_rx_channel_frequency(rxsts);
+	channel_flags = wl_radiotap_rx_channel_flags(rxsts);
+	flags = wl_radiotap_rx_flags(mac_header, rxsts);
+
+	rtl->basic.tsft_l = HTOL32(rxsts->mactime);
+	rtl->basic.tsft_h = 0;
+	rtl->basic.flags = flags;
+	rtl->basic.rate = (uint8)rxsts->datarate;
+	rtl->basic.channel_freq = (uint16)HTOL16(channel_frequency);
+	rtl->basic.channel_flags = HTOL16(channel_flags);
+	rtl->basic.signal = (int8)rxsts->signal;
+	rtl->basic.noise = (int8)rxsts->noise;
+	rtl->basic.antenna = (int8)rxsts->antenna;
+
+	return 0;
+}
+
+uint
+wl_radiotap_rx_ht(struct dot11_header *mac_header,
+                  wl_rxsts_t *rxsts, ieee80211_radiotap_header_t *rtap_hdr)
+{
+	int channel_frequency;
+	uint16 channel_flags;
+	uint32 xchannel_flags;
+	uint8 flags;
+
+	uint16 rtap_len = LTOH16(rtap_hdr->it_len);
+	wl_radiotap_ht_t *rtht = (wl_radiotap_ht_t *)((uint8*)rtap_hdr + rtap_len);
+
+	rtap_len += sizeof(wl_radiotap_ht_t);
+	rtap_hdr->it_len = HTOL16(rtap_len);
+	rtap_hdr->it_present |= HTOL32(WL_RADIOTAP_PRESENT_HT);
+
+	channel_frequency = (uint16)wl_radiotap_rx_channel_frequency(rxsts);
+	channel_flags = wl_radiotap_rx_channel_flags(rxsts);
+	flags = wl_radiotap_rx_flags(mac_header, rxsts);
+
+	rtht->basic.tsft_l = HTOL32(rxsts->mactime);
+	rtht->basic.tsft_h = 0;
+	rtht->basic.flags = flags;
+	rtht->basic.channel_freq = (uint16)HTOL16(channel_frequency);
+	rtht->basic.channel_flags = HTOL16(channel_flags);
+	rtht->basic.signal = (int8)rxsts->signal;
+	rtht->basic.noise = (int8)rxsts->noise;
+	rtht->basic.antenna = (uint8)rxsts->antenna;
+
+	/* xchannel */
+	xchannel_flags = (uint32)channel_flags;
+	if (CHSPEC_IS40(rxsts->chanspec)) {
+		if (CHSPEC_SB_UPPER(rxsts->chanspec))
+			xchannel_flags |= IEEE80211_CHAN_HT40D;
+		else {
+			xchannel_flags |= IEEE80211_CHAN_HT40U;
+		}
+	} else {
+		xchannel_flags |= IEEE80211_CHAN_HT20;
+	}
+
+	rtht->xchannel_flags = HTOL32(xchannel_flags);
+	rtht->xchannel_freq = (uint16)HTOL16(channel_frequency);
+	rtht->xchannel_channel = wf_chspec_ctlchan(rxsts->chanspec);
+	rtht->xchannel_maxpower = (17*2);
+
+	/* add standard MCS */
+	rtht->mcs_known = (IEEE80211_RADIOTAP_MCS_HAVE_BW |
+		IEEE80211_RADIOTAP_MCS_HAVE_MCS |
+		IEEE80211_RADIOTAP_MCS_HAVE_GI |
+		IEEE80211_RADIOTAP_MCS_HAVE_FEC |
+		IEEE80211_RADIOTAP_MCS_HAVE_FMT);
+
+	rtht->mcs_flags = 0;
+	switch (rxsts->htflags & WL_RXS_HTF_BW_MASK) {
+		case WL_RXS_HTF_20L:
+			rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_20L;
+			break;
+		case WL_RXS_HTF_20U:
+			rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_20U;
+			break;
+		case WL_RXS_HTF_40:
+			rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_40;
+			break;
+		default:
+			rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_20;
+	}
+
+	if (rxsts->htflags & WL_RXS_HTF_SGI) {
+		rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_SGI;
+	}
+	if (rxsts->preamble & WL_RXS_PREAMBLE_HT_GF) {
+		rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_FMT_GF;
+	}
+	if (rxsts->htflags & WL_RXS_HTF_LDPC) {
+		rtht->mcs_flags |= IEEE80211_RADIOTAP_MCS_FEC_LDPC;
+	}
+	rtht->mcs_index = rxsts->mcs;
+	rtht->ampdu_flags = 0;
+	rtht->ampdu_delim_crc = 0;
+
+	rtht->ampdu_ref_num = rxsts->ampdu_counter;
+
+	if (!(rxsts->nfrmtype & WL_RXS_NFRM_AMPDU_FIRST) &&
+		!(rxsts->nfrmtype & WL_RXS_NFRM_AMPDU_SUB)) {
+		rtht->ampdu_flags |= IEEE80211_RADIOTAP_AMPDU_IS_LAST;
+	} else {
+		rtht->ampdu_flags |= IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN;
+	}
+	return 0;
+}
+
+uint
+wl_radiotap_rx_vht(struct dot11_header *mac_header,
+                   wl_rxsts_t *rxsts, ieee80211_radiotap_header_t *rtap_hdr)
+{
+	int channel_frequency;
+	uint16 channel_flags;
+	uint8 flags;
+
+	uint16 rtap_len = LTOH16(rtap_hdr->it_len);
+	wl_radiotap_vht_t *rtvht = (wl_radiotap_vht_t *)((uint8*)rtap_hdr + rtap_len);
+
+	rtap_len += sizeof(wl_radiotap_vht_t);
+	rtap_hdr->it_len = HTOL16(rtap_len);
+	rtap_hdr->it_present |= HTOL32(WL_RADIOTAP_PRESENT_VHT);
+
+	channel_frequency = (uint16)wl_radiotap_rx_channel_frequency(rxsts);
+	channel_flags = wl_radiotap_rx_channel_flags(rxsts);
+	flags = wl_radiotap_rx_flags(mac_header, rxsts);
+
+	rtvht->basic.tsft_l = HTOL32(rxsts->mactime);
+	rtvht->basic.tsft_h = 0;
+	rtvht->basic.flags = flags;
+	rtvht->basic.channel_freq = (uint16)HTOL16(channel_frequency);
+	rtvht->basic.channel_flags = HTOL16(channel_flags);
+	rtvht->basic.signal = (int8)rxsts->signal;
+	rtvht->basic.noise = (int8)rxsts->noise;
+	rtvht->basic.antenna = (uint8)rxsts->antenna;
+
+	rtvht->vht_known = (IEEE80211_RADIOTAP_VHT_HAVE_STBC |
+		IEEE80211_RADIOTAP_VHT_HAVE_TXOP_PS |
+		IEEE80211_RADIOTAP_VHT_HAVE_GI |
+		IEEE80211_RADIOTAP_VHT_HAVE_SGI_NSYM_DA |
+		IEEE80211_RADIOTAP_VHT_HAVE_LDPC_EXTRA |
+		IEEE80211_RADIOTAP_VHT_HAVE_BF |
+		IEEE80211_RADIOTAP_VHT_HAVE_BW |
+		IEEE80211_RADIOTAP_VHT_HAVE_GID |
+		IEEE80211_RADIOTAP_VHT_HAVE_PAID);
+
+	STATIC_ASSERT(WL_RXS_VHTF_STBC ==
+		IEEE80211_RADIOTAP_VHT_STBC);
+	STATIC_ASSERT(WL_RXS_VHTF_TXOP_PS ==
+		IEEE80211_RADIOTAP_VHT_TXOP_PS);
+	STATIC_ASSERT(WL_RXS_VHTF_SGI ==
+		IEEE80211_RADIOTAP_VHT_SGI);
+	STATIC_ASSERT(WL_RXS_VHTF_SGI_NSYM_DA ==
+		IEEE80211_RADIOTAP_VHT_SGI_NSYM_DA);
+	STATIC_ASSERT(WL_RXS_VHTF_LDPC_EXTRA ==
+		IEEE80211_RADIOTAP_VHT_LDPC_EXTRA);
+	STATIC_ASSERT(WL_RXS_VHTF_BF ==
+		IEEE80211_RADIOTAP_VHT_BF);
+
+	rtvht->vht_flags = (uint8)HTOL16(rxsts->vhtflags);
+
+	STATIC_ASSERT(WL_RXS_VHT_BW_20 ==
+		IEEE80211_RADIOTAP_VHT_BW_20);
+	STATIC_ASSERT(WL_RXS_VHT_BW_40 ==
+		IEEE80211_RADIOTAP_VHT_BW_40);
+	STATIC_ASSERT(WL_RXS_VHT_BW_20L ==
+		IEEE80211_RADIOTAP_VHT_BW_20L);
+	STATIC_ASSERT(WL_RXS_VHT_BW_20U ==
+		IEEE80211_RADIOTAP_VHT_BW_20U);
+	STATIC_ASSERT(WL_RXS_VHT_BW_80 ==
+		IEEE80211_RADIOTAP_VHT_BW_80);
+	STATIC_ASSERT(WL_RXS_VHT_BW_40L ==
+		IEEE80211_RADIOTAP_VHT_BW_40L);
+	STATIC_ASSERT(WL_RXS_VHT_BW_40U ==
+		IEEE80211_RADIOTAP_VHT_BW_40U);
+	STATIC_ASSERT(WL_RXS_VHT_BW_20LL ==
+		IEEE80211_RADIOTAP_VHT_BW_20LL);
+	STATIC_ASSERT(WL_RXS_VHT_BW_20LU ==
+		IEEE80211_RADIOTAP_VHT_BW_20LU);
+	STATIC_ASSERT(WL_RXS_VHT_BW_20UL ==
+		IEEE80211_RADIOTAP_VHT_BW_20UL);
+	STATIC_ASSERT(WL_RXS_VHT_BW_20UU ==
+		IEEE80211_RADIOTAP_VHT_BW_20UU);
+
+	rtvht->vht_bw = rxsts->bw;
+
+	rtvht->vht_mcs_nss[0] = (rxsts->mcs << 4) |
+		(rxsts->nss & IEEE80211_RADIOTAP_VHT_NSS);
+	rtvht->vht_mcs_nss[1] = 0;
+	rtvht->vht_mcs_nss[2] = 0;
+	rtvht->vht_mcs_nss[3] = 0;
+
+	STATIC_ASSERT(WL_RXS_VHTF_CODING_LDCP ==
+		IEEE80211_RADIOTAP_VHT_CODING_LDPC);
+
+	rtvht->vht_coding = rxsts->coding;
+	rtvht->vht_group_id = rxsts->gid;
+	rtvht->vht_partial_aid = HTOL16(rxsts->aid);
+
+	rtvht->ampdu_flags = 0;
+	rtvht->ampdu_delim_crc = 0;
+	rtvht->ampdu_ref_num = HTOL32(rxsts->ampdu_counter);
+	if (!(rxsts->nfrmtype & WL_RXS_NFRM_AMPDU_FIRST) &&
+		!(rxsts->nfrmtype & WL_RXS_NFRM_AMPDU_SUB)) {
+		rtvht->ampdu_flags |= HTOL16(IEEE80211_RADIOTAP_AMPDU_IS_LAST);
+	} else {
+		rtvht->ampdu_flags |= HTOL16(IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN);
+	}
+
+	return 0;
+}
+
+/* Rx status to radiotap conversion of HE type */
+uint
+wl_radiotap_rx_he(struct dot11_header *mac_header, wl_rxsts_t *rxsts,
+		ieee80211_radiotap_header_t *rtap_hdr)
+{
+	int channel_frequency;
+	uint16 channel_flags;
+	uint8 flags;
+	uint16 rtap_len = LTOH16(rtap_hdr->it_len);
+	wl_radiotap_he_t *rthe = (wl_radiotap_he_t *)((uint8*)rtap_hdr + rtap_len);
+
+	rtap_len += sizeof(wl_radiotap_he_t);
+	rtap_hdr->it_len = HTOL16(rtap_len);
+	rtap_hdr->it_present |= HTOL32(WL_RADIOTAP_PRESENT_HE);
+
+	channel_frequency = (uint16)wl_radiotap_rx_channel_frequency(rxsts);
+	channel_flags = wl_radiotap_rx_channel_flags(rxsts);
+	flags = wl_radiotap_rx_flags(mac_header, rxsts);
+
+	rthe->basic.tsft_l = HTOL32(rxsts->mactime);
+	rthe->basic.tsft_h = 0;
+	rthe->basic.flags = flags;
+	rthe->basic.channel_freq = (uint16)HTOL16(channel_frequency);
+	rthe->basic.channel_flags = HTOL16(channel_flags);
+	rthe->basic.signal = (int8)rxsts->signal;
+	rthe->basic.noise = (int8)rxsts->noise;
+	rthe->basic.antenna = (uint8)rxsts->antenna;
+
+	rthe->ampdu_flags = 0;
+	rthe->ampdu_delim_crc = 0;
+	rthe->ampdu_ref_num = HTOL32(rxsts->ampdu_counter);
+	if (!(rxsts->nfrmtype & WL_RXS_NFRM_AMPDU_FIRST) &&
+		!(rxsts->nfrmtype & WL_RXS_NFRM_AMPDU_SUB)) {
+		rthe->ampdu_flags |= HTOL16(IEEE80211_RADIOTAP_AMPDU_IS_LAST);
+	} else {
+		rthe->ampdu_flags |= HTOL16(IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN);
+	}
+
+	rthe->data1 = HTOL16(rxsts->data1);
+	rthe->data2 = HTOL16(rxsts->data2);
+	rthe->data3 = HTOL16(rxsts->data3);
+	rthe->data4 = HTOL16(rxsts->data4);
+	rthe->data5 = HTOL16(rxsts->data5);
+	rthe->data6 = HTOL16(rxsts->data6);
+
+	return 0;
+}
+
+/* Rx status to radiotap conversion of EHT type */
+uint
+wl_radiotap_rx_eht(struct dot11_header *mac_header, wl_rxsts_t *rxsts,
+	ieee80211_radiotap_header_t *rtap_hdr)
+{
+	ASSERT(!"wl_radiotap_rx_eht: not implemented!");
+	return 0;
+}
+
+uint16
+wl_rxsts_to_rtap(monitor_pkt_rxsts_t *pkt_rxsts, void *payload,
+                 uint16 len, void* pout, uint16 pad_req)
+{
+	uint16 rtap_len = 0;
+	struct dot11_header* mac_header;
+	uint8* p = payload;
+	ieee80211_radiotap_header_t* rtap_hdr = (ieee80211_radiotap_header_t*)pout;
+	wl_rxsts_t* rxsts;
+
+	ASSERT(p && pkt_rxsts);
+	rxsts = pkt_rxsts->rxsts;
+	rtap_hdr->it_version = 0;
+	rtap_hdr->it_pad = 0;
+	rtap_hdr->it_len = HTOL16(sizeof(*rtap_hdr));
+	rtap_hdr->it_present = 0;
+	bitmap = 0;
+
+#ifdef MONITOR_DNGL_CONV
+	if (pad_req) {
+		radiotap_add_vendor_ns(rtap_hdr);
+	}
+#endif
+
+#ifdef BCM_MON_QDBM_RSSI
+	/* if per-core RSSI is present, add vendor element */
+	if (pkt_rxsts->corenum != 0) {
+		radiotap_add_vendor_ns(rtap_hdr);
+	}
+#endif
+	mac_header = (struct dot11_header *)(p);
+
+	if (rxsts->encoding == WL_RXS_ENCODING_EHT) {
+		wl_radiotap_rx_eht(mac_header, rxsts, rtap_hdr);
+	} else if (rxsts->encoding == WL_RXS_ENCODING_HE) {
+		wl_radiotap_rx_he(mac_header, rxsts, rtap_hdr);
+	} else if (rxsts->encoding == WL_RXS_ENCODING_VHT) {
+		wl_radiotap_rx_vht(mac_header, rxsts, rtap_hdr);
+	} else if (rxsts->encoding == WL_RXS_ENCODING_HT) {
+		wl_radiotap_rx_ht(mac_header, rxsts, rtap_hdr);
+	} else {
+		uint16 mask = ltoh16(mac_header->fc) & FC_KIND_MASK;
+		if (mask == FC_RTS || mask == FC_CTS) {
+			radiotap_add_vendor_ns(rtap_hdr);
+		}
+		wl_radiotap_rx_legacy(mac_header, rxsts, rtap_hdr);
+		if (mask == FC_RTS || mask == FC_CTS) {
+			radiotap_encode_bw_signaling(mask, rxsts, rtap_hdr);
+		}
+	}
+#ifdef BCM_MON_QDBM_RSSI
+	/* if per-core RSSI is present, add vendor element */
+	if (pkt_rxsts->corenum != 0) {
+		radiotap_encode_multi_rssi(pkt_rxsts, rtap_hdr);
+	}
+#endif
+#ifdef MONITOR_DNGL_CONV
+	if (pad_req) {
+		radiotap_encode_alignpad(rtap_hdr, pad_req);
+	}
+#endif
+	rtap_len = LTOH16(rtap_hdr->it_len);
+	len += rtap_len;
+
+#ifndef MONITOR_DNGL_CONV
+	if (len > MAX_MON_PKT_SIZE) {
+		return 0;
+	}
+	/* copy payload */
+	if (!(rxsts->nfrmtype & WL_RXS_NFRM_AMSDU_FIRST) &&
+			!(rxsts->nfrmtype & WL_RXS_NFRM_AMSDU_SUB)) {
+		memcpy((uint8*)pout + rtap_len, (uint8*)p, len - rtap_len);
+	}
+#endif
+#ifdef MONITOR_DNGL_CONV
+	return rtap_len;
+#else
+	return len;
+#endif
+}
+
+#ifdef BCM_MON_QDBM_RSSI
+void
+radiotap_encode_multi_rssi(monitor_pkt_rxsts_t* rxsts, ieee80211_radiotap_header_t *hdr)
+{
+	uint16 cur_len = LTOH16(hdr->it_len);
+	uint16 len = ROUNDUP(1 + rxsts->corenum * sizeof(monitor_pkt_rssi_t), 4);
+	int i = 0;
+	uint8 *vend_p = (uint8 *)hdr + cur_len;
+	radiotap_vendor_ns_t *vendor_ns = (radiotap_vendor_ns_t*)vend_p;
+	memcpy(vendor_ns->vend_oui, brcm_oui, sizeof(vendor_ns->vend_oui));
+	vendor_ns->sns = 1;
+	vendor_ns->skip_len = HTOL16(len);
+	vend_p += sizeof(*vendor_ns);
+	vend_p[0] = rxsts->corenum;
+	for (i = 0; i < rxsts->corenum; i++) {
+	  vend_p[2*i + 1] = rxsts->rxpwr[i].dBm;
+	  vend_p[2*i + 2] = rxsts->rxpwr[i].decidBm;
+	}
+	hdr->it_len = HTOL16(cur_len + sizeof(radiotap_vendor_ns_t) + len);
+}
+#endif /* BCM_CORE_RSSI */
+
+#ifdef MONITOR_DNGL_CONV
+#define AILIGN_4BYTES	(4u)
+void
+radiotap_encode_alignpad(ieee80211_radiotap_header_t *hdr, uint16 pad_req)
+{
+	uint16 cur_len = LTOH16(hdr->it_len);
+	uint8 *vend_p = (uint8 *)hdr + cur_len;
+	radiotap_vendor_ns_t *vendor_ns = (radiotap_vendor_ns_t*)vend_p;
+	uint16 len;
+	uint16 align_pad = 0;
+
+	memcpy(vendor_ns->vend_oui, brcm_oui, sizeof(vendor_ns->vend_oui));
+	vendor_ns->sns = WL_RADIOTAP_BRCM_PAD_SNS;
+	len = cur_len + sizeof(radiotap_vendor_ns_t);
+	if (len % AILIGN_4BYTES	!= 0) {
+		align_pad = (AILIGN_4BYTES - (len % AILIGN_4BYTES));
+	}
+	hdr->it_len = HTOL16(len + pad_req + align_pad);
+	vendor_ns->skip_len = HTOL16(pad_req + align_pad);
+}
+#endif /* MONITOR_DNGL_CONV */
+
+void
+radiotap_encode_bw_signaling(uint16 mask,
+                             struct wl_rxsts* rxsts, ieee80211_radiotap_header_t *hdr)
+{
+	uint16 cur_len = LTOH16(hdr->it_len);
+	uint8 *vend_p = (uint8 *)hdr + cur_len;
+	radiotap_vendor_ns_t *vendor_ns = (radiotap_vendor_ns_t  *)vend_p;
+	wl_radiotap_nonht_vht_t* nonht_vht;
+
+	memcpy(vendor_ns->vend_oui, brcm_oui, sizeof(vendor_ns->vend_oui));
+	vendor_ns->sns = 0;
+	vendor_ns->skip_len = sizeof(wl_radiotap_nonht_vht_t);
+	nonht_vht = (wl_radiotap_nonht_vht_t *)(vend_p + sizeof(*vendor_ns));
+
+	/* VHT b/w signalling */
+	bzero((uint8 *)nonht_vht, sizeof(wl_radiotap_nonht_vht_t));
+	nonht_vht->len = WL_RADIOTAP_NONHT_VHT_LEN;
+	nonht_vht->flags |= WL_RADIOTAP_F_NONHT_VHT_BW;
+	nonht_vht->bw = (uint8)rxsts->bw_nonht;
+
+	if (mask == FC_RTS) {
+		if (rxsts->vhtflags & WL_RXS_VHTF_DYN_BW_NONHT) {
+			nonht_vht->flags |= WL_RADIOTAP_F_NONHT_VHT_DYN_BW;
+		}
+	}
+	hdr->it_len = HTOL16(cur_len + sizeof(radiotap_vendor_ns_t) +
+	                     sizeof(wl_radiotap_nonht_vht_t));
+}
+
+void
+radiotap_add_vendor_ns(ieee80211_radiotap_header_t *hdr)
+{
+
+	uint32 * it_present = &hdr->it_present;
+	uint16 len = LTOH16(hdr->it_len);
+
+	/* if the last bitmap has a vendor ns, add a new one */
+	if (it_present[bitmap] & (1 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE)) {
+		it_present[bitmap] |= 1 << IEEE80211_RADIOTAP_EXT;
+		bitmap++;
+		/* align to 8 bytes */
+		if (bitmap%2) {
+			hdr->it_len = HTOL16(len + 8);
+		}
+		it_present[bitmap] = 1 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
+	} else {
+		it_present[bitmap] |= 1 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
+	}
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/bcmxtlv.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/bcmxtlv.c
@@ -0,0 +1,663 @@
+/*
+ * Driver O/S-independent utility routines
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Dual:>>
+ */
+
+#include <typedefs.h>
+#include <bcmdefs.h>
+
+#ifdef BCMDRIVER
+#include <osl.h>
+#else /* !BCMDRIVER */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifndef ASSERT
+#define ASSERT(exp)
+#endif
+#endif /* !BCMDRIVER */
+
+#include <bcmtlv.h>
+#include <bcmendian.h>
+#include <bcmutils.h>
+
+int
+BCMPOSTTRAPFN(bcm_xtlv_hdr_size)(bcm_xtlv_opts_t opts)
+{
+	int len = (int)OFFSETOF(bcm_xtlv_t, data); /* nominal */
+	if (opts & BCM_XTLV_OPTION_LENU8) --len;
+	if (opts & BCM_XTLV_OPTION_IDU8) --len;
+
+	return len;
+}
+
+bool
+bcm_valid_xtlv(const bcm_xtlv_t *elt, int buf_len, bcm_xtlv_opts_t opts)
+{
+	return elt != NULL &&
+	        buf_len >= bcm_xtlv_hdr_size(opts) &&
+		buf_len  >= bcm_xtlv_size(elt, opts);
+}
+
+int
+BCMPOSTTRAPFN(bcm_xtlv_size_for_data)(int dlen, bcm_xtlv_opts_t opts)
+{
+	int hsz;
+
+	hsz = bcm_xtlv_hdr_size(opts);
+	return ((opts & BCM_XTLV_OPTION_ALIGN32) ? ALIGN_SIZE(dlen + hsz, 4)
+		: (dlen + hsz));
+}
+
+int
+bcm_xtlv_size(const bcm_xtlv_t *elt, bcm_xtlv_opts_t opts)
+{
+	int size;	/* size including header, data, and any pad */
+	int len;	/* length wthout padding */
+
+	len = BCM_XTLV_LEN_EX(elt, opts);
+	size = bcm_xtlv_size_for_data(len, opts);
+	return size;
+}
+
+int
+bcm_xtlv_len(const bcm_xtlv_t *elt, bcm_xtlv_opts_t opts)
+{
+	const uint8 *lenp;
+	int len;
+
+	lenp = (const uint8 *)elt + OFFSETOF(bcm_xtlv_t, len); /* nominal */
+	if (opts & BCM_XTLV_OPTION_IDU8) {
+		--lenp;
+	}
+
+	if (opts & BCM_XTLV_OPTION_LENU8) {
+		len = *lenp;
+	} else if (opts & BCM_XTLV_OPTION_LENBE) {
+		len = (uint32)hton16(elt->len);
+	} else {
+		len = ltoh16_ua(lenp);
+	}
+
+	return len;
+}
+
+int
+bcm_xtlv_id(const bcm_xtlv_t *elt, bcm_xtlv_opts_t opts)
+{
+	int id = 0;
+	if (opts & BCM_XTLV_OPTION_IDU8) {
+		id =  *(const uint8 *)elt;
+	} else if (opts & BCM_XTLV_OPTION_IDBE) {
+		id = (uint32)hton16(elt->id);
+	} else {
+		id = ltoh16_ua((const uint8 *)elt);
+	}
+
+	return id;
+}
+
+bcm_xtlv_t *
+bcm_next_xtlv(const bcm_xtlv_t *elt, int *buflen, bcm_xtlv_opts_t opts)
+{
+	uint sz;
+
+	COV_TAINTED_DATA_SINK(buflen);
+	COV_NEG_SINK(buflen);
+
+	/* validate current elt */
+	if (!bcm_valid_xtlv(elt, *buflen, opts))
+		return NULL;
+
+	/* advance to next elt */
+	sz = BCM_XTLV_SIZE_EX(elt, opts);
+	elt = (const bcm_xtlv_t*)((const uint8 *)elt + sz);
+
+#if defined(__COVERITY__)
+	/* The 'sz' value is tainted in Coverity because it is read from the tainted data pointed
+	 * to by 'elt'.  However, bcm_valid_xtlv() verifies that the elt pointer is a valid element,
+	 * so its size, sz = BCM_XTLV_SIZE_EX(elt, opts), is in the bounds of the buffer.
+	 * Clearing the tainted attribute of 'sz' for Coverity.
+	 */
+	__coverity_tainted_data_sanitize__(sz);
+	if (sz > *buflen) {
+		return NULL;
+	}
+#endif /* __COVERITY__ */
+
+	*buflen -= sz;
+
+	/* validate next elt */
+	if (!bcm_valid_xtlv(elt, *buflen, opts))
+		return NULL;
+
+	COV_TAINTED_DATA_ARG(elt);
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST()
+	return (bcm_xtlv_t *)(elt);
+	GCC_DIAGNOSTIC_POP()
+}
+
+int
+bcm_xtlv_buf_init(bcm_xtlvbuf_t *tlv_buf, uint8 *buf, uint16 len, bcm_xtlv_opts_t opts)
+{
+	if (!tlv_buf || !buf || !len)
+		return BCME_BADARG;
+
+	tlv_buf->opts = opts;
+	tlv_buf->size = len;
+	tlv_buf->head = buf;
+	tlv_buf->buf  = buf;
+	return BCME_OK;
+}
+
+uint16
+bcm_xtlv_buf_len(bcm_xtlvbuf_t *tbuf)
+{
+	uint16 len;
+
+	if (tbuf)
+		len = (uint16)(tbuf->buf - tbuf->head);
+	else
+		len = 0;
+
+	return len;
+}
+
+uint16
+bcm_xtlv_buf_rlen(bcm_xtlvbuf_t *tbuf)
+{
+	uint16 rlen;
+	if (tbuf)
+		rlen = tbuf->size - bcm_xtlv_buf_len(tbuf);
+	else
+		rlen = 0;
+
+	return rlen;
+}
+
+uint8 *
+bcm_xtlv_buf(bcm_xtlvbuf_t *tbuf)
+{
+	return tbuf ? tbuf->buf : NULL;
+}
+
+uint8 *
+bcm_xtlv_head(bcm_xtlvbuf_t *tbuf)
+{
+	return tbuf ? tbuf->head : NULL;
+}
+
+void
+BCMPOSTTRAPFN(bcm_xtlv_pack_xtlv)(bcm_xtlv_t *xtlv, uint16 type, uint16 len, const uint8 *data,
+	bcm_xtlv_opts_t opts)
+{
+	uint8 *data_buf;
+	bcm_xtlv_opts_t mask = BCM_XTLV_OPTION_IDU8 | BCM_XTLV_OPTION_LENU8;
+
+	if (!(opts & mask)) {		/* default */
+		uint8 *idp = (uint8 *)xtlv;
+		uint8 *lenp = idp + sizeof(xtlv->id);
+		htol16_ua_store(type, idp);
+		htol16_ua_store(len, lenp);
+		data_buf = lenp + sizeof(uint16);
+	} else if ((opts & mask) == mask) { /* u8 id and u8 len */
+		uint8 *idp = (uint8 *)xtlv;
+		uint8 *lenp = idp + 1;
+		*idp = (uint8)type;
+		*lenp = (uint8)len;
+		data_buf = lenp + sizeof(uint8);
+	} else if (opts & BCM_XTLV_OPTION_IDU8) { /* u8 id, u16 len */
+		uint8 *idp = (uint8 *)xtlv;
+		uint8 *lenp = idp + 1;
+		*idp = (uint8)type;
+		htol16_ua_store(len, lenp);
+		data_buf = lenp + sizeof(uint16);
+	} else if (opts & BCM_XTLV_OPTION_LENU8) { /* u16 id, u8 len */
+		uint8 *idp = (uint8 *)xtlv;
+		uint8 *lenp = idp + sizeof(uint16);
+		htol16_ua_store(type, idp);
+		*lenp = (uint8)len;
+		data_buf = lenp + sizeof(uint8);
+	} else {
+		ASSERT(!"Unexpected xtlv option");
+		return;
+	}
+
+	if (opts & BCM_XTLV_OPTION_LENU8) {
+		ASSERT(len <= 0x00ff);
+		len &= 0xff;
+	}
+
+	if (data != NULL) {
+		memcpy(data_buf, data, len);
+	}
+}
+
+/* xtlv header is always packed in LE order */
+void
+bcm_xtlv_unpack_xtlv(const bcm_xtlv_t *xtlv, uint16 *type, uint16 *len,
+	const uint8 **data, bcm_xtlv_opts_t opts)
+{
+	if (type)
+		*type = (uint16)bcm_xtlv_id(xtlv, opts);
+	if (len)
+		*len = (uint16)bcm_xtlv_len(xtlv, opts);
+	if (data)
+		*data = (const uint8 *)xtlv + BCM_XTLV_HDR_SIZE_EX(opts);
+}
+
+int
+bcm_xtlv_put_data(bcm_xtlvbuf_t *tbuf, uint16 type, const uint8 *data, int n)
+{
+	bcm_xtlv_t *xtlv;
+	int size;
+
+	if (tbuf == NULL)
+		return BCME_BADARG;
+
+	size = bcm_xtlv_size_for_data(n, tbuf->opts);
+	if (bcm_xtlv_buf_rlen(tbuf) < size)
+		return BCME_NOMEM;
+
+	xtlv = (bcm_xtlv_t *)bcm_xtlv_buf(tbuf);
+	bcm_xtlv_pack_xtlv(xtlv, type, (uint16)n, data, tbuf->opts);
+	tbuf->buf += size; /* note: data may be NULL, reserves space */
+	return BCME_OK;
+}
+
+static int
+bcm_xtlv_put_int(bcm_xtlvbuf_t *tbuf, uint16 type, const uint8 *data, int n, int int_sz)
+{
+	bcm_xtlv_t *xtlv;
+	int xtlv_len;
+	uint8 *xtlv_data;
+	int err = BCME_OK;
+
+	if (tbuf == NULL) {
+		err = BCME_BADARG;
+		goto done;
+	}
+
+	xtlv = (bcm_xtlv_t *)bcm_xtlv_buf(tbuf);
+
+	/* put type and length in xtlv and reserve data space */
+	xtlv_len = n * int_sz;
+	err = bcm_xtlv_put_data(tbuf, type, NULL, xtlv_len);
+	if (err != BCME_OK)
+		goto done;
+
+	xtlv_data = (uint8 *)xtlv + bcm_xtlv_hdr_size(tbuf->opts);
+
+	/* write data w/ little-endianness into buffer - single loop, aligned access */
+	for (; n != 0; --n, xtlv_data += int_sz, data += int_sz) {
+		switch (int_sz) {
+		case sizeof(uint8):
+			break;
+		case sizeof(uint16):
+			{
+				uint16 v =  load16_ua(data);
+				htol16_ua_store(v, xtlv_data);
+				break;
+			}
+		case sizeof(uint32):
+			{
+				uint32 v = load32_ua(data);
+				htol32_ua_store(v, xtlv_data);
+				break;
+			}
+		case sizeof(uint64):
+			{
+				uint64 v = load64_ua(data);
+				htol64_ua_store(v, xtlv_data);
+				break;
+			}
+		default:
+			err = BCME_UNSUPPORTED;
+			goto done;
+		}
+	}
+
+done:
+	return err;
+}
+
+int
+bcm_xtlv_put16(bcm_xtlvbuf_t *tbuf, uint16 type, const uint16 *data, int n)
+{
+	return bcm_xtlv_put_int(tbuf, type, (const uint8 *)data, n, sizeof(uint16));
+}
+
+int
+bcm_xtlv_put32(bcm_xtlvbuf_t *tbuf, uint16 type, const uint32 *data, int n)
+{
+	return bcm_xtlv_put_int(tbuf, type, (const uint8 *)data, n, sizeof(uint32));
+}
+
+int
+bcm_xtlv_put64(bcm_xtlvbuf_t *tbuf, uint16 type, const uint64 *data, int n)
+{
+	return bcm_xtlv_put_int(tbuf, type, (const uint8 *)data, n, sizeof(uint64));
+}
+
+/*
+ *  upacks xtlv record from buf checks the type
+ *  copies data to callers buffer
+ *  advances tlv pointer to next record
+ *  caller's resposible for dst space check
+ */
+int
+bcm_unpack_xtlv_entry(const uint8 **tlv_buf, uint16 xpct_type, uint16 xpct_len,
+	uint8 *dst_data, bcm_xtlv_opts_t opts)
+{
+	const bcm_xtlv_t *ptlv = (const bcm_xtlv_t *)*tlv_buf;
+	uint16 len;
+	uint16 type;
+	const uint8 *data;
+
+	ASSERT(ptlv);
+
+	bcm_xtlv_unpack_xtlv(ptlv, &type, &len, &data, opts);
+	if (len) {
+		if ((type != xpct_type) || (len > xpct_len))
+			return BCME_BADARG;
+		if (dst_data && data)
+			memcpy(dst_data, data, len); /* copy data to dst */
+	}
+
+	*tlv_buf += BCM_XTLV_SIZE_EX(ptlv, opts);
+	return BCME_OK;
+}
+
+/*
+ *  packs user data into tlv record and advances tlv pointer to next xtlv slot
+ *  buflen is used for tlv_buf space check
+ */
+int
+bcm_pack_xtlv_entry(uint8 **tlv_buf, uint16 *buflen, uint16 type, uint16 len,
+	const uint8 *src_data, bcm_xtlv_opts_t opts)
+{
+	bcm_xtlv_t *ptlv = (bcm_xtlv_t *)*tlv_buf;
+	int size;
+
+	ASSERT(ptlv);
+
+	size = bcm_xtlv_size_for_data(len, opts);
+
+	/* copy data from tlv buffer to dst provided by user */
+	if (size > *buflen) {
+		return BCME_BADLEN;
+	}
+
+	bcm_xtlv_pack_xtlv(ptlv, type, len, src_data, opts);
+
+	/* advance callers pointer to tlv buff */
+	*tlv_buf = (uint8*)(*tlv_buf) + size;
+	/* decrement the len */
+	*buflen -= (uint16)size;
+	return BCME_OK;
+}
+
+/*
+ *  unpack all xtlv records from the issue a callback
+ *  to set function one call per found tlv record
+ */
+int
+bcm_unpack_xtlv_buf(void *ctx, const uint8 *tlv_buf, uint16 buflen, bcm_xtlv_opts_t opts,
+	bcm_xtlv_unpack_cbfn_t *cbfn)
+{
+	int res = BCME_OK;
+	const bcm_xtlv_t *ptlv;
+	uint16 len;
+	uint16 type;
+	const uint8 *data;
+	uint32 sbuflen = buflen;
+	uint32 hdr_size;	/* size of tlv header */
+	uint32 size;		/* size of tlv including header + data */
+
+	ASSERT(!buflen || tlv_buf);
+	ASSERT(!buflen || cbfn);
+
+	hdr_size = BCM_XTLV_HDR_SIZE_EX(opts);
+	while (sbuflen >= hdr_size) {
+		ptlv = (const bcm_xtlv_t *)tlv_buf;
+
+		bcm_xtlv_unpack_xtlv(ptlv, &type, &len, &data, opts);
+		size = bcm_xtlv_size_for_data(len, opts);
+
+		/* check for buffer overrun */
+		if (sbuflen < size) {
+			break;
+		}
+		sbuflen -= size;
+
+		if ((res = cbfn(ctx, data, type, len)) != BCME_OK) {
+			break;
+		}
+		tlv_buf += size;
+	}
+	return res;
+}
+
+int
+bcm_pack_xtlv_buf(void *ctx, uint8 *tlv_buf, uint16 buflen, bcm_xtlv_opts_t opts,
+	bcm_pack_xtlv_next_info_cbfn_t get_next, bcm_pack_xtlv_pack_next_cbfn_t pack_next,
+	int *outlen)
+{
+	int res = BCME_OK;
+	uint16 tlv_id;
+	uint16 tlv_len;
+	uint8 *startp;
+	uint8 *endp;
+	uint8 *buf;
+	bool more;
+	int size;
+	int hdr_size;
+
+	ASSERT(get_next && pack_next);
+
+	buf = tlv_buf;
+	startp = buf;
+	endp = (uint8 *)buf + buflen;
+	more = TRUE;
+	hdr_size = BCM_XTLV_HDR_SIZE_EX(opts);
+
+	while (more && (buf < endp)) {
+		more = get_next(ctx, &tlv_id, &tlv_len);
+		size = bcm_xtlv_size_for_data(tlv_len, opts);
+		if ((buf + size) > endp) {
+			res = BCME_BUFTOOSHORT;
+			goto done;
+		}
+
+		bcm_xtlv_pack_xtlv((bcm_xtlv_t *)buf, tlv_id, tlv_len, NULL, opts);
+		pack_next(ctx, tlv_id, tlv_len, buf + hdr_size);
+		buf += size;
+	}
+
+	if (more)
+		res = BCME_BUFTOOSHORT;
+
+done:
+	if (outlen) {
+		*outlen = (int)(buf - startp);
+	}
+	return res;
+}
+
+/*
+ *  pack xtlv buffer from memory according to xtlv_desc_t
+ */
+int
+bcm_pack_xtlv_buf_from_mem(uint8 **tlv_buf, uint16 *buflen, const xtlv_desc_t *items,
+	bcm_xtlv_opts_t opts)
+{
+	int res = BCME_OK;
+	uint8 *ptlv = *tlv_buf;
+
+	while (items->type != 0) {
+		if (items->len && items->ptr) {
+			res = bcm_pack_xtlv_entry(&ptlv, buflen, items->type,
+				items->len, items->ptr, opts);
+			if (res != BCME_OK)
+				break;
+		}
+		items++;
+	}
+
+	*tlv_buf = ptlv; /* update the external pointer */
+	return res;
+}
+
+/*
+ *  unpack xtlv buffer to memory according to xtlv_desc_t
+ *
+ */
+int
+bcm_unpack_xtlv_buf_to_mem(const uint8 *tlv_buf, int *buflen, xtlv_desc_t *items,
+	bcm_xtlv_opts_t opts)
+{
+	int res = BCME_OK;
+	const bcm_xtlv_t *elt;
+
+	elt =  bcm_valid_xtlv((const bcm_xtlv_t *)tlv_buf, *buflen, opts) ?
+		(const bcm_xtlv_t *)tlv_buf : NULL;
+	if (!elt || !items) {
+		res = BCME_BADARG;
+		return res;
+	}
+
+	for (; elt != NULL && res == BCME_OK; elt = bcm_next_xtlv(elt, buflen, opts)) {
+		/*  find matches in desc_t items  */
+		xtlv_desc_t *dst_desc = items;
+		uint16 len, type;
+		const uint8 *data;
+
+		bcm_xtlv_unpack_xtlv(elt, &type, &len, &data, opts);
+		while (dst_desc->type != 0) {
+			if (type == dst_desc->type) {
+				if (len != dst_desc->len) {
+					res = BCME_BADLEN;
+				} else {
+					memcpy(dst_desc->ptr, data, len);
+				}
+				break;
+			}
+			dst_desc++;
+		}
+	}
+
+	if (res == BCME_OK && *buflen != 0)		/* this does not look right */
+		res =  BCME_BUFTOOSHORT;
+
+	return res;
+}
+
+/*
+ * return data pointer of a given ID from xtlv buffer.
+ * If the specified xTLV ID is found, on return *datalen will contain
+ * the the data length of the xTLV ID.
+ */
+const uint8*
+bcm_get_data_from_xtlv_buf(const uint8 *tlv_buf, uint16 buflen, uint16 id,
+	uint16 *datalen, bcm_xtlv_opts_t opts)
+{
+	const uint8 *retptr = NULL;
+	uint16 type, len;
+	int size;
+	const bcm_xtlv_t *ptlv;
+	int sbuflen = buflen;
+	const uint8 *data;
+	int hdr_size;
+
+	COV_TAINTED_DATA_SINK(buflen);
+	COV_NEG_SINK(buflen);
+
+	hdr_size = BCM_XTLV_HDR_SIZE_EX(opts);
+
+	/* Init the datalength */
+	if (datalen) {
+		*datalen = 0;
+	}
+	while (sbuflen >= hdr_size) {
+		ptlv = (const bcm_xtlv_t *)tlv_buf;
+		bcm_xtlv_unpack_xtlv(ptlv, &type, &len, &data, opts);
+
+		size = bcm_xtlv_size_for_data(len, opts);
+		sbuflen -= size;
+		if (sbuflen < 0) /* buffer overrun? */
+			break;
+
+		if (id == type) {
+			retptr = data;
+			if (datalen)
+				*datalen = len;
+			break;
+		}
+
+		tlv_buf += size;
+	}
+
+	COV_TAINTED_DATA_ARG(retptr);
+
+	return retptr;
+}
+
+bcm_xtlv_t*
+bcm_xtlv_bcopy(const bcm_xtlv_t *src, bcm_xtlv_t *dst,
+	int src_buf_len, int dst_buf_len, bcm_xtlv_opts_t opts)
+{
+	bcm_xtlv_t *dst_next = NULL;
+	src =  (src && bcm_valid_xtlv(src, src_buf_len, opts)) ? src : NULL;
+	if (src && dst) {
+		uint16 type;
+		uint16 len;
+		const uint8 *data;
+		int size;
+		bcm_xtlv_unpack_xtlv(src, &type, &len, &data, opts);
+		size = bcm_xtlv_size_for_data(len, opts);
+		if (size <= dst_buf_len) {
+			bcm_xtlv_pack_xtlv(dst, type, len, data, opts);
+			dst_next = (bcm_xtlv_t *)((uint8 *)dst + size);
+		}
+	}
+
+	return dst_next;
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dbus.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dbus.c
@@ -0,0 +1,3533 @@
+/** @file dbus.c
+ *
+ * Hides details of USB / SDIO / SPI interfaces and OS details. It is intended to shield details and
+ * provide the caller with one common bus interface for all dongle devices. In practice, it is only
+ * used for USB interfaces. DBUS is not a protocol, but an abstraction layer.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Dual:>>
+ */
+
+#include <linux/usb.h>
+#include "osl.h"
+#include "dbus.h"
+#include <bcmutils.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_proto.h>
+#ifdef PROP_TXSTATUS /* a form of flow control between host and dongle */
+#include <dhd_wlfc.h>
+#endif
+#include <dhd_config.h>
+#ifdef WL_CFG80211
+#include <wl_cfg80211.h>
+#include <wl_cfgp2p.h>
+#endif
+
+#include <bcmdevs_legacy.h>
+#if defined(BCM_DNGL_EMBEDIMAGE)
+#include <bcmsrom_fmt.h>
+#include <trxhdr.h>
+#include <usbrdl.h>
+#include <bcmendian.h>
+#include <zutil.h>
+#include <sbpcmcia.h>
+#include <bcmnvram.h>
+#include <bcmdevs.h>
+#elif defined(BCM_REQUEST_FW)
+#include <bcmsrom_fmt.h>
+#include <trxhdr.h>
+#include <usbrdl.h>
+#include <bcmendian.h>
+#include <sbpcmcia.h>
+#include <bcmnvram.h>
+#include <bcmdevs.h>
+#endif /* #if defined(BCM_DNGL_EMBEDIMAGE) */
+#if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX)
+#include <linux/usb.h>
+#endif /* EHCI_FASTPATH_TX || EHCI_FASTPATH_RX */
+
+#if defined(BCM_DNGL_EMBEDIMAGE)
+/* zlib file format field ids etc from gzio.c */
+#define Z_DEFLATED     8
+#define ASCII_FLAG     0x01 /**< bit 0 set: file probably ascii text */
+#define HEAD_CRC       0x02 /**< bit 1 set: header CRC present */
+#define EXTRA_FIELD    0x04 /**< bit 2 set: extra field present */
+#define ORIG_NAME      0x08 /**< bit 3 set: original file name present */
+#define COMMENT        0x10 /**< bit 4 set: file comment present */
+#define RESERVED       0xE0 /**< bits 5..7: reserved */
+
+/* Rename define */
+#ifdef WL_FW_DECOMP
+#define UNZIP_ENAB(info)  1
+#else
+#define UNZIP_ENAB(info)  0
+
+#ifdef inflateInit2
+#undef inflateInit2
+#define inflateInit2(a, b)  Z_ERRNO
+#endif
+#define inflate(a, b)       Z_STREAM_ERROR
+#define inflateEnd(a)       do {} while (0)
+#define crc32(a, b, c)      -1
+#define free(a)             do {} while (0)
+#endif /* WL_FW_DECOMP */
+
+#elif defined(BCM_REQUEST_FW)
+#ifndef VARS_MAX
+#define VARS_MAX            8192
+#endif
+#endif /* #if defined(BCM_DNGL_EMBEDIMAGE) */
+
+#ifdef DBUS_USB_LOOPBACK
+extern bool is_loopback_pkt(void *buf);
+extern int matches_loopback_pkt(void *buf);
+#endif
+
+/** General info for all BUS types */
+typedef struct dbus_irbq {
+	dbus_irb_t *head;
+	dbus_irb_t *tail;
+	int cnt;
+} dbus_irbq_t;
+
+/**
+ * This private structure dhd_bus_t is also declared in dbus_usb_linux.c.
+ * All the fields must be consistent in both declarations.
+ */
+typedef struct dhd_bus {
+	dbus_pub_t   pub; /* MUST BE FIRST */
+	dhd_pub_t *dhd;
+
+	void        *cbarg;
+	dbus_callbacks_t *cbs; /**< callbacks to higher level, eg dhd_linux.c */
+	void        *bus_info;
+	dbus_intf_t *drvintf;  /**< callbacks to lower level, eg dbus_usb.c or dbus_usb_linux.c */
+	uint8       *fw;
+	int         fwlen;
+	uint32      errmask;
+	int         rx_low_watermark;  /**< avoid rx overflow by filling rx with free IRBs */
+	int         tx_low_watermark;
+	bool        txoff;
+	bool        txoverride;   /**< flow control related */
+	bool        rxoff;
+	bool        tx_timer_ticking;
+	uint ctl_completed;
+
+	dbus_irbq_t *rx_q;
+	dbus_irbq_t *tx_q;
+
+#ifdef BCMDBG
+	int         *txpend_q_hist;
+	int         *rxpend_q_hist;
+#endif /* BCMDBG */
+#ifdef EHCI_FASTPATH_RX
+	atomic_t    rx_outstanding;
+#endif
+	uint8        *nvram;
+	int          nvram_len;
+	uint8        *image;  /**< buffer for combine fw and nvram */
+	int          image_len;
+	uint8        *orig_fw;
+	int          origfw_len;
+	int          decomp_memsize;
+	dbus_extdl_t extdl;
+	int          nvram_nontxt;
+#if defined(BCM_REQUEST_FW)
+	void         *firmware;
+	void         *nvfile;
+#endif
+	char		*fw_path;		/* module_param: path to firmware image */
+	char		*nv_path;		/* module_param: path to nvram vars file */
+	uint64 last_suspend_end_time;
+} dhd_bus_t;
+
+struct exec_parms {
+	union {
+		/* Can consolidate same params, if need be, but this shows
+		 * group of parameters per function
+		 */
+		struct {
+			dbus_irbq_t  *q;
+			dbus_irb_t   *b;
+		} qenq;
+
+		struct {
+			dbus_irbq_t  *q;
+		} qdeq;
+	};
+};
+
+#define EXEC_RXLOCK(info, fn, a) \
+	info->drvintf->exec_rxlock(dhd_bus->bus_info, ((exec_cb_t)fn), ((struct exec_parms *) a))
+
+#define EXEC_TXLOCK(info, fn, a) \
+	info->drvintf->exec_txlock(dhd_bus->bus_info, ((exec_cb_t)fn), ((struct exec_parms *) a))
+
+/*
+ * Callbacks common for all BUS
+ */
+static void dbus_if_send_irb_timeout(void *handle, dbus_irb_tx_t *txirb);
+static void dbus_if_send_irb_complete(void *handle, dbus_irb_tx_t *txirb, int status);
+static void dbus_if_recv_irb_complete(void *handle, dbus_irb_rx_t *rxirb, int status);
+static void dbus_if_errhandler(void *handle, int err);
+static void dbus_if_ctl_complete(void *handle, int type, int status);
+static void dbus_if_state_change(void *handle, int state);
+static void *dbus_if_pktget(void *handle, uint len, bool send);
+static void dbus_if_pktfree(void *handle, void *p, bool send);
+static struct dbus_irb *dbus_if_getirb(void *cbarg, bool send);
+static void dbus_if_rxerr_indicate(void *handle, bool on);
+
+static int dbus_suspend(void *context);
+static int dbus_resume(void *context);
+static void * dhd_dbus_probe_cb(uint16 bus_no, uint16 slot, uint32 hdrlen);
+static void dhd_dbus_disconnect_cb(void *arg);
+static void dbus_detach(dhd_bus_t *pub);
+
+/** functions in this file that are called by lower DBUS levels, eg dbus_usb.c */
+static dbus_intf_callbacks_t dbus_intf_cbs = {
+	dbus_if_send_irb_timeout,
+	dbus_if_send_irb_complete,
+	dbus_if_recv_irb_complete,
+	dbus_if_errhandler,
+	dbus_if_ctl_complete,
+	dbus_if_state_change,
+	NULL,			/**< isr */
+	NULL,			/**< dpc */
+	NULL,			/**< watchdog */
+	dbus_if_pktget,
+	dbus_if_pktfree,
+	dbus_if_getirb,
+	dbus_if_rxerr_indicate
+};
+
+/*
+ * Need global for probe() and disconnect() since
+ * attach() is not called at probe and detach()
+ * can be called inside disconnect()
+ */
+static dbus_intf_t     *g_busintf = NULL;
+
+#if defined(BCM_REQUEST_FW)
+int8 *nonfwnvram = NULL; /**< stand-alone multi-nvram given with driver load */
+int nonfwnvramlen = 0;
+#endif /* #if defined(BCM_REQUEST_FW) */
+
+static void* q_enq(dbus_irbq_t *q, dbus_irb_t *b);
+static void* q_enq_exec(struct exec_parms *args);
+static dbus_irb_t*q_deq(dbus_irbq_t *q);
+static void* q_deq_exec(struct exec_parms *args);
+static int   dbus_tx_timer_init(dhd_bus_t *dhd_bus);
+static int   dbus_tx_timer_start(dhd_bus_t *dhd_bus, uint timeout);
+static int   dbus_tx_timer_stop(dhd_bus_t *dhd_bus);
+static int   dbus_irbq_init(dhd_bus_t *dhd_bus, dbus_irbq_t *q, int nq, int size_irb);
+static int   dbus_irbq_deinit(dhd_bus_t *dhd_bus, dbus_irbq_t *q, int size_irb);
+static int   dbus_rxirbs_fill(dhd_bus_t *dhd_bus);
+static int   dbus_send_irb(dbus_pub_t *pub, uint8 *buf, int len, void *pkt, void *info);
+
+#if (defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW))
+#if defined(BCM_REQUEST_FW)
+extern char * dngl_firmware;
+extern unsigned int dngl_fwlen;
+#endif  /* #if defined(BCM_REQUEST_FW) */
+#ifndef EXTERNAL_FW_PATH
+static int dbus_get_nvram(dhd_bus_t *dhd_bus);
+static int dbus_jumbo_nvram(dhd_bus_t *dhd_bus);
+static int dbus_select_nvram(dhd_bus_t *dhd_bus, int8 *jumbonvram, int jumbolen,
+uint16 boardtype, uint16 boardrev, int8 **nvram, int *nvram_len);
+#endif /* !EXTERNAL_FW_PATH */
+#ifndef BCM_REQUEST_FW
+static int dbus_zlib_decomp(dhd_bus_t *dhd_bus);
+extern void *dbus_zlib_calloc(int num, int size);
+extern void dbus_zlib_free(void *ptr);
+#endif
+#endif /* defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW) */
+
+/* function */
+void
+dbus_flowctrl_tx(void *dbi, bool on)
+{
+	dhd_bus_t *dhd_bus = dbi;
+
+	if (dhd_bus == NULL)
+		return;
+
+	DBUSTRACE(("%s on %d\n", __FUNCTION__, on));
+
+	if (dhd_bus->txoff == on)
+		return;
+
+	dhd_bus->txoff = on;
+
+	if (dhd_bus->cbs && dhd_bus->cbs->txflowcontrol)
+		dhd_bus->cbs->txflowcontrol(dhd_bus->cbarg, on);
+}
+
+/**
+ * if lower level DBUS signaled a rx error, more free rx IRBs should be allocated or flow control
+ * should kick in to make more free rx IRBs available.
+ */
+static void
+dbus_if_rxerr_indicate(void *handle, bool on)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) handle;
+
+	DBUSTRACE(("%s, on %d\n", __FUNCTION__, on));
+
+	if (dhd_bus == NULL)
+		return;
+
+	if (dhd_bus->txoverride == on)
+		return;
+
+	dhd_bus->txoverride = on;	/* flow control */
+
+	if (!on)
+		dbus_rxirbs_fill(dhd_bus);
+
+}
+
+/** q_enq()/q_deq() are executed with protection via exec_rxlock()/exec_txlock() */
+static void*
+q_enq(dbus_irbq_t *q, dbus_irb_t *b)
+{
+	ASSERT(q->tail != b);
+	ASSERT(b->next == NULL);
+	b->next = NULL;
+	if (q->tail) {
+		q->tail->next = b;
+		q->tail = b;
+	} else
+		q->head = q->tail = b;
+
+	q->cnt++;
+
+	return b;
+}
+
+static void*
+q_enq_exec(struct exec_parms *args)
+{
+	return q_enq(args->qenq.q, args->qenq.b);
+}
+
+static dbus_irb_t*
+q_deq(dbus_irbq_t *q)
+{
+	dbus_irb_t *b;
+
+	b = q->head;
+	if (b) {
+		q->head = q->head->next;
+		b->next = NULL;
+
+		if (q->head == NULL)
+			q->tail = q->head;
+
+		q->cnt--;
+	}
+	return b;
+}
+
+static void*
+q_deq_exec(struct exec_parms *args)
+{
+	return q_deq(args->qdeq.q);
+}
+
+/**
+ * called during attach phase. Status @ Dec 2012: this function does nothing since for all of the
+ * lower DBUS levels dhd_bus->drvintf->tx_timer_init is NULL.
+ */
+static int
+dbus_tx_timer_init(dhd_bus_t *dhd_bus)
+{
+	if (dhd_bus && dhd_bus->drvintf && dhd_bus->drvintf->tx_timer_init)
+		return dhd_bus->drvintf->tx_timer_init(dhd_bus->bus_info);
+	else
+		return DBUS_ERR;
+}
+
+static int
+dbus_tx_timer_start(dhd_bus_t *dhd_bus, uint timeout)
+{
+	if (dhd_bus == NULL)
+		return DBUS_ERR;
+
+	if (dhd_bus->tx_timer_ticking)
+		return DBUS_OK;
+
+	if (dhd_bus->drvintf && dhd_bus->drvintf->tx_timer_start) {
+		if (dhd_bus->drvintf->tx_timer_start(dhd_bus->bus_info, timeout) == DBUS_OK) {
+			dhd_bus->tx_timer_ticking = TRUE;
+			return DBUS_OK;
+		}
+	}
+
+	return DBUS_ERR;
+}
+
+static int
+dbus_tx_timer_stop(dhd_bus_t *dhd_bus)
+{
+	if (dhd_bus == NULL)
+		return DBUS_ERR;
+
+	if (!dhd_bus->tx_timer_ticking)
+		return DBUS_OK;
+
+	if (dhd_bus->drvintf && dhd_bus->drvintf->tx_timer_stop) {
+		if (dhd_bus->drvintf->tx_timer_stop(dhd_bus->bus_info) == DBUS_OK) {
+			dhd_bus->tx_timer_ticking = FALSE;
+			return DBUS_OK;
+		}
+	}
+
+	return DBUS_ERR;
+}
+
+/** called during attach phase. */
+static int
+dbus_irbq_init(dhd_bus_t *dhd_bus, dbus_irbq_t *q, int nq, int size_irb)
+{
+	int i;
+	dbus_irb_t *irb;
+
+	ASSERT(q);
+	ASSERT(dhd_bus);
+
+	for (i = 0; i < nq; i++) {
+		/* MALLOCZ dbus_irb_tx or dbus_irb_rx, but cast to simple dbus_irb_t linkedlist */
+		irb = (dbus_irb_t *) MALLOCZ(dhd_bus->pub.osh, size_irb);
+		if (irb == NULL) {
+			ASSERT(irb);
+			return DBUS_ERR;
+		}
+
+		/* q_enq() does not need to go through EXEC_xxLOCK() during init() */
+		q_enq(q, irb);
+	}
+
+	return DBUS_OK;
+}
+
+/** called during detach phase or when attach failed */
+static int
+dbus_irbq_deinit(dhd_bus_t *dhd_bus, dbus_irbq_t *q, int size_irb)
+{
+	dbus_irb_t *irb;
+
+	ASSERT(q);
+	ASSERT(dhd_bus);
+
+	/* q_deq() does not need to go through EXEC_xxLOCK()
+	 * during deinit(); all callbacks are stopped by this time
+	 */
+	while ((irb = q_deq(q)) != NULL) {
+		MFREE(dhd_bus->pub.osh, irb, size_irb);
+	}
+
+	if (q->cnt)
+		DBUSERR(("deinit: q->cnt=%d > 0\n", q->cnt));
+	return DBUS_OK;
+}
+
+/** multiple code paths require the rx queue to be filled with more free IRBs */
+static int
+dbus_rxirbs_fill(dhd_bus_t *dhd_bus)
+{
+	int err = DBUS_OK;
+
+#ifdef EHCI_FASTPATH_RX
+	while (atomic_read(&dhd_bus->rx_outstanding) < 100) /* TODO: Improve constant */
+	{
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
+		/* NOCOPY force new packet allocation */
+		optimize_submit_rx_request(&dhd_bus->pub, 1, NULL, NULL);
+#else
+		/* Copy mode - allocate own buffer to be reused */
+		void *buf = MALLOCZ(dhd_bus->pub.osh, 4000); /* usbos_info->rxbuf_len */
+		optimize_submit_rx_request(&dhd_bus->pub, 1, NULL, buf);
+		/* ME: Need to check result and set err = DBUS_ERR_RXDROP */
+#endif /* BCM_RPC_NOCOPY || BCM_RPC_RXNOCOPY */
+		atomic_inc(&dhd_bus->rx_outstanding);
+	}
+#else /* EHCI_FASTPATH_RX */
+
+	dbus_irb_rx_t *rxirb;
+	struct exec_parms args;
+
+	ASSERT(dhd_bus);
+	if (dhd_bus->pub.busstate != DBUS_STATE_UP) {
+		DBUSERR(("dbus_rxirbs_fill: DBUS not up \n"));
+		return DBUS_ERR;
+	} else if (!dhd_bus->drvintf || (dhd_bus->drvintf->recv_irb == NULL)) {
+		/* Lower edge bus interface does not support recv_irb().
+		 * No need to pre-submit IRBs in this case.
+		 */
+		return DBUS_ERR;
+	}
+
+	/* The dongle recv callback is freerunning without lock. So multiple callbacks(and this
+	 *  refill) can run in parallel. While the rxoff condition is triggered outside,
+	 *  below while loop has to check and abort posting more to avoid RPC rxq overflow.
+	 */
+	args.qdeq.q = dhd_bus->rx_q;
+	while ((!dhd_bus->rxoff) &&
+	       (rxirb = (EXEC_RXLOCK(dhd_bus, q_deq_exec, &args))) != NULL) {
+		err = dhd_bus->drvintf->recv_irb(dhd_bus->bus_info, rxirb);
+		if (err == DBUS_ERR_RXDROP || err == DBUS_ERR_RXFAIL) {
+			/* Add the the free rxirb back to the queue
+			 * and wait till later
+			 */
+			bzero(rxirb, sizeof(dbus_irb_rx_t));
+			args.qenq.q = dhd_bus->rx_q;
+			args.qenq.b = (dbus_irb_t *) rxirb;
+			EXEC_RXLOCK(dhd_bus, q_enq_exec, &args);
+			break;
+		} else if (err != DBUS_OK) {
+			int i = 0;
+			while (i++ < 100) {
+				DBUSERR(("%s :: memory leak for rxirb note?\n", __FUNCTION__));
+			}
+		}
+	}
+#endif /* EHCI_FASTPATH_RX */
+	return err;
+} /* dbus_rxirbs_fill */
+
+/** called when the DBUS interface state changed. */
+void
+dbus_flowctrl_rx(dbus_pub_t *pub, bool on)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+
+	if (dhd_bus == NULL)
+		return;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (dhd_bus->rxoff == on)
+		return;
+
+	dhd_bus->rxoff = on;
+
+	if (dhd_bus->pub.busstate == DBUS_STATE_UP) {
+		if (!on) {
+			/* post more irbs, resume rx if necessary */
+			dbus_rxirbs_fill(dhd_bus);
+			if (dhd_bus && dhd_bus->drvintf->recv_resume) {
+				dhd_bus->drvintf->recv_resume(dhd_bus->bus_info);
+			}
+		} else {
+			/* ??? cancell posted irbs first */
+
+			if (dhd_bus && dhd_bus->drvintf->recv_stop) {
+				dhd_bus->drvintf->recv_stop(dhd_bus->bus_info);
+			}
+		}
+	}
+}
+
+/**
+ * Several code paths in this file want to send a buffer to the dongle. This function handles both
+ * sending of a buffer or a pkt.
+ */
+static int
+dbus_send_irb(dbus_pub_t *pub, uint8 *buf, int len, void *pkt, void *info)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+	int err = DBUS_OK;
+#ifndef EHCI_FASTPATH_TX
+	dbus_irb_tx_t *txirb = NULL;
+	int txirb_pending;
+	struct exec_parms args;
+#endif /* EHCI_FASTPATH_TX */
+
+	if (dhd_bus == NULL)
+		return DBUS_ERR;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (dhd_bus->pub.busstate == DBUS_STATE_UP ||
+		dhd_bus->pub.busstate == DBUS_STATE_SLEEP) {
+#ifdef EHCI_FASTPATH_TX
+		struct ehci_qtd *qtd;
+		int token = EHCI_QTD_SET_CERR(3);
+		int len;
+
+		ASSERT(buf == NULL); /* Not handled */
+		ASSERT(pkt != NULL);
+
+		qtd = optimize_ehci_qtd_alloc(GFP_KERNEL);
+
+		if (qtd == NULL)
+			return DBUS_ERR;
+
+		len = PKTLEN(pub->osh, pkt);
+
+		len = ROUNDUP(len, sizeof(uint32));
+
+#ifdef BCMDBG
+		/* The packet length is already padded to not to be multiple of 512 bytes
+		 * in bcm_rpc_tp_buf_send_internal(), so it should not be 512*N bytes here.
+		 */
+		if (len % EHCI_BULK_PACKET_SIZE == 0) {
+			DBUSERR(("%s: len = %d (multiple of 512 bytes)\n", __FUNCTION__, len));
+			return DBUS_ERR_TXDROP;
+		}
+#endif /* BCMDBG */
+
+		optimize_qtd_fill_with_rpc(pub, 0, qtd, pkt, token, len);
+		err = optimize_submit_async(qtd, 0);
+
+		if (err) {
+			optimize_ehci_qtd_free(qtd);
+			err = DBUS_ERR_TXDROP;
+		}
+
+		/* ME: Add timeout? */
+#else
+		args.qdeq.q = dhd_bus->tx_q;
+		if (dhd_bus->drvintf)
+			txirb = EXEC_TXLOCK(dhd_bus, q_deq_exec, &args);
+
+		if (txirb == NULL) {
+			DBUSERR(("Out of tx dbus_bufs\n"));
+			return DBUS_ERR;
+		}
+
+		if (pkt != NULL) {
+			txirb->pkt = pkt;
+			txirb->buf = NULL;
+			txirb->len = 0;
+		} else if (buf != NULL) {
+			txirb->pkt = NULL;
+			txirb->buf = buf;
+			txirb->len = len;
+		} else {
+			ASSERT(0); /* Should not happen */
+		}
+		txirb->info = info;
+		txirb->arg = NULL;
+		txirb->retry_count = 0;
+
+		if (dhd_bus->drvintf && dhd_bus->drvintf->send_irb) {
+			/* call lower DBUS level send_irb function */
+			err = dhd_bus->drvintf->send_irb(dhd_bus->bus_info, txirb);
+			if (err == DBUS_ERR_TXDROP) {
+				/* tx fail and no completion routine to clean up, reclaim irb NOW */
+				DBUSERR(("%s: send_irb failed, status = %d\n", __FUNCTION__, err));
+				bzero(txirb, sizeof(dbus_irb_tx_t));
+				args.qenq.q = dhd_bus->tx_q;
+				args.qenq.b = (dbus_irb_t *) txirb;
+				EXEC_TXLOCK(dhd_bus, q_enq_exec, &args);
+			} else {
+				dbus_tx_timer_start(dhd_bus, DBUS_TX_TIMEOUT_INTERVAL);
+				txirb_pending = dhd_bus->pub.ntxq - dhd_bus->tx_q->cnt;
+#ifdef BCMDBG
+				dhd_bus->txpend_q_hist[txirb_pending]++;
+#endif /* BCMDBG */
+				if (txirb_pending > (dhd_bus->tx_low_watermark * 3)) {
+					dbus_flowctrl_tx(dhd_bus, TRUE);
+				}
+			}
+		}
+#endif /* EHCI_FASTPATH_TX */
+	} else {
+		err = DBUS_ERR_TXFAIL;
+		DBUSTRACE(("%s: bus down, send_irb failed\n", __FUNCTION__));
+	}
+
+	return err;
+} /* dbus_send_irb */
+
+#if (defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW))
+
+/**
+ * Before downloading a firmware image into the dongle, the validity of the image must be checked.
+ */
+static int
+check_file(osl_t *osh, unsigned char *headers)
+{
+	struct trx_header *trx;
+	int actual_len = -1;
+
+	/* Extract trx header */
+	trx = (struct trx_header *)headers;
+	if (ltoh32(trx->magic) != TRX_MAGIC) {
+		printf("Error: trx bad hdr %x\n", ltoh32(trx->magic));
+		return -1;
+	}
+
+	headers += SIZEOF_TRX(trx);
+
+	/* TRX V1: get firmware len */
+	/* TRX V2: get firmware len and DSG/CFG lengths */
+	if (ltoh32(trx->flag_version) & TRX_UNCOMP_IMAGE) {
+		actual_len = ltoh32(trx->offsets[TRX_OFFSETS_DLFWLEN_IDX]) +
+		                     SIZEOF_TRX(trx);
+#ifdef BCMTRXV2
+		if (ISTRX_V2(trx)) {
+			actual_len += ltoh32(trx->offsets[TRX_OFFSETS_DSG_LEN_IDX]) +
+				ltoh32(trx->offsets[TRX_OFFSETS_CFG_LEN_IDX]);
+		}
+#endif
+		return actual_len;
+	}  else {
+		printf("compressed image\n");
+	}
+
+	return -1;
+}
+
+#ifdef EXTERNAL_FW_PATH
+static int
+dbus_get_fw_nvram(dhd_bus_t *dhd_bus)
+{
+	int bcmerror = -1, i;
+	uint len, total_len;
+	void *nv_image = NULL, *fw_image = NULL;
+	char *nv_memblock = NULL, *fw_memblock = NULL;
+	char *bufp;
+	bool file_exists;
+	uint8 nvram_words_pad = 0;
+	uint memblock_size = 2048;
+	uint8 *memptr;
+	int	actual_fwlen;
+	struct trx_header *hdr;
+	uint32 img_offset = 0;
+	int offset = 0;
+	char *pfw_path = dhd_bus->fw_path;
+	char *pnv_path = dhd_bus->nv_path;
+
+	/* For Get nvram */
+	file_exists = ((pnv_path != NULL) && (pnv_path[0] != '\0'));
+	if (file_exists) {
+		nv_image = dhd_os_open_image1(dhd_bus->dhd, pnv_path);
+		if (nv_image == NULL) {
+			printf("%s: Open nvram file failed %s\n", __FUNCTION__, pnv_path);
+			goto err;
+		}
+	}
+	nv_memblock = MALLOC(dhd_bus->pub.osh, MAX_NVRAMBUF_SIZE);
+	if (nv_memblock == NULL) {
+		DBUSERR(("%s: Failed to allocate memory %d bytes\n",
+		           __FUNCTION__, MAX_NVRAMBUF_SIZE));
+		goto err;
+	}
+	len = dhd_os_get_image_block(nv_memblock, MAX_NVRAMBUF_SIZE, nv_image);
+	if (len > 0 && len < MAX_NVRAMBUF_SIZE) {
+		bufp = (char *)nv_memblock;
+		bufp[len] = 0;
+		dhd_bus->nvram_len = process_nvram_vars(bufp, len);
+		if (dhd_bus->nvram_len % 4)
+			nvram_words_pad = 4 - dhd_bus->nvram_len % 4;
+	} else {
+		DBUSERR(("%s: error reading nvram file: %d\n", __FUNCTION__, len));
+		bcmerror = DBUS_ERR_NVRAM;
+		goto err;
+	}
+	if (nv_image) {
+		dhd_os_close_image1(dhd_bus->dhd, nv_image);
+		nv_image = NULL;
+	}
+
+	/* For Get first block of fw to calculate total_len */
+	file_exists = ((pfw_path != NULL) && (pfw_path[0] != '\0'));
+	if (file_exists) {
+		fw_image = dhd_os_open_image1(dhd_bus->dhd, pfw_path);
+		if (fw_image == NULL) {
+			printf("%s: Open fw file failed %s\n", __FUNCTION__, pfw_path);
+			goto err;
+		}
+	}
+	memptr = fw_memblock = MALLOC(dhd_bus->pub.osh, memblock_size);
+	if (fw_memblock == NULL) {
+		DBUSERR(("%s: Failed to allocate memory %d bytes\n", __FUNCTION__,
+			memblock_size));
+		goto err;
+	}
+	len = dhd_os_get_image_block((char*)memptr, memblock_size, fw_image);
+	if ((actual_fwlen = check_file(dhd_bus->pub.osh, memptr)) <= 0) {
+		DBUSERR(("%s: bad firmware format!\n", __FUNCTION__));
+		goto err;
+	}
+
+	total_len = actual_fwlen + dhd_bus->nvram_len + nvram_words_pad;
+#if defined(CONFIG_DHD_USE_STATIC_BUF)
+	dhd_bus->image = (uint8*)DHD_OS_PREALLOC(dhd_bus->dhd,
+		DHD_PREALLOC_MEMDUMP_RAM, total_len);
+#else
+	dhd_bus->image = MALLOC(dhd_bus->pub.osh, total_len);
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+	dhd_bus->image_len = total_len;
+	if (dhd_bus->image == NULL) {
+		DBUSERR(("%s: malloc failed! size=%d\n", __FUNCTION__, total_len));
+		goto err;
+	}
+
+	/* Step1: Copy trx header + firmwre */
+	memptr = fw_memblock;
+	do {
+		if (len < 0) {
+			DBUSERR(("%s: dhd_os_get_image_block failed (%d)\n", __FUNCTION__, len));
+			bcmerror = BCME_ERROR;
+			goto err;
+		}
+		bcopy(memptr, dhd_bus->image+offset, len);
+		offset += len;
+	} while ((len = dhd_os_get_image_block((char*)memptr, memblock_size, fw_image)));
+	/* Step2: Copy NVRAM + pad */
+	hdr = (struct trx_header *)dhd_bus->image;
+	img_offset = SIZEOF_TRX(hdr) + hdr->offsets[TRX_OFFSETS_DLFWLEN_IDX];
+	bcopy(nv_memblock, (uint8 *)(dhd_bus->image + img_offset),
+		dhd_bus->nvram_len);
+	img_offset += dhd_bus->nvram_len;
+	if (nvram_words_pad) {
+		bzero(&dhd_bus->image[img_offset], nvram_words_pad);
+		img_offset += nvram_words_pad;
+	}
+#ifdef BCMTRXV2
+	/* Step3: Copy DSG/CFG for V2 */
+	if (ISTRX_V2(hdr) &&
+		(hdr->offsets[TRX_OFFSETS_DSG_LEN_IDX] ||
+		hdr->offsets[TRX_OFFSETS_CFG_LEN_IDX])) {
+		DBUSERR(("%s: fix me\n", __FUNCTION__));
+	}
+#endif /* BCMTRXV2 */
+	/* Step4: update TRX header for nvram size */
+	hdr = (struct trx_header *)dhd_bus->image;
+	hdr->len = htol32(total_len);
+	/* Pass the actual fw len */
+	hdr->offsets[TRX_OFFSETS_NVM_LEN_IDX] =
+		htol32(dhd_bus->nvram_len + nvram_words_pad);
+	/* Calculate CRC over header */
+	hdr->crc32 = hndcrc32((uint8 *)&hdr->flag_version,
+		SIZEOF_TRX(hdr) - OFFSETOF(struct trx_header, flag_version),
+		CRC32_INIT_VALUE);
+
+	/* Calculate CRC over data */
+	for (i = SIZEOF_TRX(hdr); i < total_len; ++i)
+			hdr->crc32 = hndcrc32((uint8 *)&dhd_bus->image[i], 1, hdr->crc32);
+	hdr->crc32 = htol32(hdr->crc32);
+
+	bcmerror = DBUS_OK;
+
+err:
+	if (fw_memblock)
+		MFREE(dhd_bus->pub.osh, fw_memblock, MAX_NVRAMBUF_SIZE);
+	if (fw_image)
+		dhd_os_close_image1(dhd_bus->dhd, fw_image);
+	if (nv_memblock)
+		MFREE(dhd_bus->pub.osh, nv_memblock, MAX_NVRAMBUF_SIZE);
+	if (nv_image)
+		dhd_os_close_image1(dhd_bus->dhd, nv_image);
+
+	return bcmerror;
+}
+
+/**
+ * during driver initialization ('attach') or after PnP 'resume', firmware needs to be loaded into
+ * the dongle
+ */
+static int
+dbus_do_download(dhd_bus_t *dhd_bus)
+{
+	int err = DBUS_OK;
+
+	err = dbus_get_fw_nvram(dhd_bus);
+	if (err) {
+		DBUSERR(("dbus_do_download: fail to get nvram %d\n", err));
+		return err;
+	}
+
+	if (dhd_bus->drvintf->dlstart && dhd_bus->drvintf->dlrun) {
+		err = dhd_bus->drvintf->dlstart(dhd_bus->bus_info,
+			dhd_bus->image, dhd_bus->image_len);
+		if (err == DBUS_OK) {
+			err = dhd_bus->drvintf->dlrun(dhd_bus->bus_info);
+		}
+	} else
+		err = DBUS_ERR;
+
+	if (dhd_bus->image) {
+#if defined(CONFIG_DHD_USE_STATIC_BUF)
+		DHD_OS_PREFREE(dhd_bus->dhd, dhd_bus->image, dhd_bus->image_len);
+#else
+		MFREE(dhd_bus->pub.osh, dhd_bus->image, dhd_bus->image_len);
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+		dhd_bus->image = NULL;
+		dhd_bus->image_len = 0;
+	}
+
+	return err;
+} /* dbus_do_download */
+#else
+
+/**
+ * It is easy for the user to pass one jumbo nvram file to the driver than a set of smaller files.
+ * The 'jumbo nvram' file format is essentially a set of nvram files. Before commencing firmware
+ * download, the dongle needs to be probed so that the correct nvram contents within the jumbo nvram
+ * file is selected.
+ */
+static int
+dbus_jumbo_nvram(dhd_bus_t *dhd_bus)
+{
+	int8 *nvram = NULL;
+	int nvram_len = 0;
+	int ret = DBUS_OK;
+	uint16 boardrev = 0xFFFF;
+	uint16 boardtype = 0xFFFF;
+
+	ret = dbus_select_nvram(dhd_bus, dhd_bus->extdl.vars, dhd_bus->extdl.varslen,
+		boardtype, boardrev, &nvram, &nvram_len);
+
+	if (ret == DBUS_JUMBO_BAD_FORMAT)
+			return DBUS_ERR_NVRAM;
+	else if (ret == DBUS_JUMBO_NOMATCH &&
+		(boardtype != 0xFFFF || boardrev  != 0xFFFF)) {
+			DBUSERR(("No matching NVRAM for boardtype 0x%02x boardrev 0x%02x\n",
+				boardtype, boardrev));
+			return DBUS_ERR_NVRAM;
+	}
+	dhd_bus->nvram = nvram;
+	dhd_bus->nvram_len =  nvram_len;
+
+	return DBUS_OK;
+}
+
+/** before commencing fw download, the correct NVRAM image to download has to be picked */
+static int
+dbus_get_nvram(dhd_bus_t *dhd_bus)
+{
+	int len, i;
+	struct trx_header *hdr;
+	int	actual_fwlen;
+	uint32 img_offset = 0;
+
+	dhd_bus->nvram_len = 0;
+	if (dhd_bus->extdl.varslen) {
+		if (DBUS_OK != dbus_jumbo_nvram(dhd_bus))
+			return DBUS_ERR_NVRAM;
+		DBUSERR(("NVRAM %d bytes downloaded\n", dhd_bus->nvram_len));
+	}
+#if defined(BCM_REQUEST_FW)
+	else if (nonfwnvram) {
+		dhd_bus->nvram = nonfwnvram;
+		dhd_bus->nvram_len = nonfwnvramlen;
+		DBUSERR(("NVRAM %d bytes downloaded\n", dhd_bus->nvram_len));
+	}
+#endif
+	if (dhd_bus->nvram) {
+		uint8 nvram_words_pad = 0;
+		/* Validate the format/length etc of the file */
+		if ((actual_fwlen = check_file(dhd_bus->pub.osh, dhd_bus->fw)) <= 0) {
+			DBUSERR(("%s: bad firmware format!\n", __FUNCTION__));
+			return DBUS_ERR_NVRAM;
+		}
+
+		if (!dhd_bus->nvram_nontxt) {
+			/* host supplied nvram could be in .txt format
+			* with all the comments etc...
+			*/
+			dhd_bus->nvram_len = process_nvram_vars(dhd_bus->nvram,
+				dhd_bus->nvram_len);
+		}
+		if (dhd_bus->nvram_len % 4)
+			nvram_words_pad = 4 - dhd_bus->nvram_len % 4;
+
+		len = actual_fwlen + dhd_bus->nvram_len + nvram_words_pad;
+#ifdef USBAP
+		/* Allocate virtual memory otherwise it might fail on embedded systems */
+		dhd_bus->image = VMALLOC(dhd_bus->pub.osh, len);
+#else
+#if defined(CONFIG_DHD_USE_STATIC_BUF)
+		dhd_bus->image = (uint8*)DHD_OS_PREALLOC(dhd_bus->dhd,
+			DHD_PREALLOC_MEMDUMP_RAM, len);
+#else
+		dhd_bus->image = MALLOCZ(dhd_bus->pub.osh, len);
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+#endif /* USBAP */
+		dhd_bus->image_len = len;
+		if (dhd_bus->image == NULL) {
+			DBUSERR(("%s: malloc failed!\n", __FUNCTION__));
+			return DBUS_ERR_NVRAM;
+		}
+		hdr = (struct trx_header *)dhd_bus->fw;
+		/* Step1: Copy trx header + firmwre */
+		img_offset = SIZEOF_TRX(hdr) + hdr->offsets[TRX_OFFSETS_DLFWLEN_IDX];
+		bcopy(dhd_bus->fw, dhd_bus->image, img_offset);
+		/* Step2: Copy NVRAM + pad */
+		bcopy(dhd_bus->nvram, (uint8 *)(dhd_bus->image + img_offset),
+			dhd_bus->nvram_len);
+		img_offset += dhd_bus->nvram_len;
+		if (nvram_words_pad) {
+			bzero(&dhd_bus->image[img_offset],
+				nvram_words_pad);
+			img_offset += nvram_words_pad;
+		}
+#ifdef BCMTRXV2
+		/* Step3: Copy DSG/CFG for V2 */
+		if (ISTRX_V2(hdr) &&
+			(hdr->offsets[TRX_OFFSETS_DSG_LEN_IDX] ||
+			hdr->offsets[TRX_OFFSETS_CFG_LEN_IDX])) {
+
+			bcopy(dhd_bus->fw + SIZEOF_TRX(hdr) +
+				hdr->offsets[TRX_OFFSETS_DLFWLEN_IDX] +
+				hdr->offsets[TRX_OFFSETS_NVM_LEN_IDX],
+				dhd_bus->image + img_offset,
+				hdr->offsets[TRX_OFFSETS_DSG_LEN_IDX] +
+				hdr->offsets[TRX_OFFSETS_CFG_LEN_IDX]);
+
+			/* Not needed */
+			img_offset += hdr->offsets[TRX_OFFSETS_DSG_LEN_IDX] +
+				hdr->offsets[TRX_OFFSETS_CFG_LEN_IDX];
+		}
+#endif /* BCMTRXV2 */
+		/* Step4: update TRX header for nvram size */
+		hdr = (struct trx_header *)dhd_bus->image;
+		hdr->len = htol32(len);
+		/* Pass the actual fw len */
+		hdr->offsets[TRX_OFFSETS_NVM_LEN_IDX] =
+			htol32(dhd_bus->nvram_len + nvram_words_pad);
+		/* Calculate CRC over header */
+		hdr->crc32 = hndcrc32((uint8 *)&hdr->flag_version,
+			SIZEOF_TRX(hdr) - OFFSETOF(struct trx_header, flag_version),
+			CRC32_INIT_VALUE);
+
+		/* Calculate CRC over data */
+		for (i = SIZEOF_TRX(hdr); i < len; ++i)
+				hdr->crc32 = hndcrc32((uint8 *)&dhd_bus->image[i], 1, hdr->crc32);
+		hdr->crc32 = htol32(hdr->crc32);
+	} else {
+		dhd_bus->image = dhd_bus->fw;
+		dhd_bus->image_len = (uint32)dhd_bus->fwlen;
+	}
+
+	return DBUS_OK;
+} /* dbus_get_nvram */
+
+/**
+ * during driver initialization ('attach') or after PnP 'resume', firmware needs to be loaded into
+ * the dongle
+ */
+static int
+dbus_do_download(dhd_bus_t *dhd_bus)
+{
+	int err = DBUS_OK;
+#ifndef BCM_REQUEST_FW
+	int decomp_override = 0;
+#endif
+#ifdef BCM_REQUEST_FW
+	uint16 boardrev = 0xFFFF, boardtype = 0xFFFF;
+	int8 *temp_nvram;
+	int temp_len;
+#endif
+
+#if defined(BCM_DNGL_EMBEDIMAGE)
+	if (dhd_bus->extdl.fw && (dhd_bus->extdl.fwlen > 0)) {
+		dhd_bus->fw = (uint8 *)dhd_bus->extdl.fw;
+		dhd_bus->fwlen = dhd_bus->extdl.fwlen;
+		DBUSERR(("dbus_do_download: using override firmmware %d bytes\n",
+			dhd_bus->fwlen));
+	} else
+		dbus_bus_fw_get(dhd_bus->bus_info, &dhd_bus->fw, &dhd_bus->fwlen,
+			&decomp_override);
+
+	if (!dhd_bus->fw) {
+		DBUSERR(("dbus_do_download: devid 0x%x / %d not supported\n",
+			dhd_bus->pub.attrib.devid, dhd_bus->pub.attrib.devid));
+		return DBUS_ERR;
+	}
+#elif defined(BCM_REQUEST_FW)
+	dhd_bus->firmware = dbus_get_fw_nvfile(dhd_bus->pub.attrib.devid,
+		dhd_bus->pub.attrib.chiprev, &dhd_bus->fw, &dhd_bus->fwlen,
+		DBUS_FIRMWARE, 0, 0, dhd_bus->fw_path);
+	if (!dhd_bus->firmware)
+		return DBUS_ERR;
+#endif /* defined(BCM_DNGL_EMBEDIMAGE) */
+
+	dhd_bus->image = dhd_bus->fw;
+	dhd_bus->image_len = (uint32)dhd_bus->fwlen;
+
+#ifndef BCM_REQUEST_FW
+	if (UNZIP_ENAB(dhd_bus) && !decomp_override) {
+		err = dbus_zlib_decomp(dhd_bus);
+		if (err) {
+			DBUSERR(("dbus_attach: fw decompress fail %d\n", err));
+			return err;
+		}
+	}
+#endif
+
+#if defined(BCM_REQUEST_FW)
+	/* check if nvram is provided as separte file */
+	nonfwnvram = NULL;
+	nonfwnvramlen = 0;
+	dhd_bus->nvfile = dbus_get_fw_nvfile(dhd_bus->pub.attrib.devid,
+		dhd_bus->pub.attrib.chiprev, (void *)&temp_nvram, &temp_len,
+		DBUS_NVFILE, boardtype, boardrev, dhd_bus->nv_path);
+	if (dhd_bus->nvfile) {
+		int8 *tmp = MALLOCZ(dhd_bus->pub.osh, temp_len);
+		if (tmp) {
+			bcopy(temp_nvram, tmp, temp_len);
+			nonfwnvram = tmp;
+			nonfwnvramlen = temp_len;
+		} else {
+			err = DBUS_ERR;
+			goto fail;
+		}
+	}
+#endif /* defined(BCM_REQUEST_FW) */
+
+	err = dbus_get_nvram(dhd_bus);
+	if (err) {
+		DBUSERR(("dbus_do_download: fail to get nvram %d\n", err));
+		return err;
+	}
+
+	if (dhd_bus->drvintf->dlstart && dhd_bus->drvintf->dlrun) {
+		err = dhd_bus->drvintf->dlstart(dhd_bus->bus_info,
+			dhd_bus->image, dhd_bus->image_len);
+
+		if (err == DBUS_OK)
+			err = dhd_bus->drvintf->dlrun(dhd_bus->bus_info);
+	} else
+		err = DBUS_ERR;
+
+	if (dhd_bus->nvram) {
+#ifdef USBAP
+		VMFREE(dhd_bus->pub.osh, dhd_bus->image, dhd_bus->image_len);
+#else
+#if defined(CONFIG_DHD_USE_STATIC_BUF)
+		DHD_OS_PREFREE(dhd_bus->dhd, dhd_bus->image, dhd_bus->image_len);
+#else
+		MFREE(dhd_bus->pub.osh, dhd_bus->image, dhd_bus->image_len);
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+#endif /* USBAP */
+		dhd_bus->image = dhd_bus->fw;
+		dhd_bus->image_len = (uint32)dhd_bus->fwlen;
+	}
+
+#ifndef BCM_REQUEST_FW
+	if (UNZIP_ENAB(dhd_bus) && (!decomp_override) && dhd_bus->orig_fw) {
+		MFREE(dhd_bus->pub.osh, dhd_bus->fw, dhd_bus->decomp_memsize);
+		dhd_bus->image = dhd_bus->fw = dhd_bus->orig_fw;
+		dhd_bus->image_len = dhd_bus->fwlen = dhd_bus->origfw_len;
+	}
+#endif
+
+#if defined(BCM_REQUEST_FW)
+fail:
+	if (dhd_bus->firmware) {
+		dbus_release_fw_nvfile(dhd_bus->firmware);
+		dhd_bus->firmware = NULL;
+	}
+	if (dhd_bus->nvfile) {
+		dbus_release_fw_nvfile(dhd_bus->nvfile);
+		dhd_bus->nvfile = NULL;
+	}
+	if (nonfwnvram) {
+		MFREE(dhd_bus->pub.osh, nonfwnvram, nonfwnvramlen);
+		nonfwnvram = NULL;
+		nonfwnvramlen = 0;
+	}
+#endif
+	return err;
+} /* dbus_do_download */
+#endif /* EXTERNAL_FW_PATH */
+#endif /* defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW) */
+
+/**
+ * This function is called when the sent irb times out without a tx response status.
+ * DBUS adds reliability by resending timed out IRBs DBUS_TX_RETRY_LIMIT times.
+ */
+static void
+dbus_if_send_irb_timeout(void *handle, dbus_irb_tx_t *txirb)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) handle;
+
+	if ((dhd_bus == NULL) || (dhd_bus->drvintf == NULL) || (txirb == NULL)) {
+		return;
+	}
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	/* Timeout in DBUS is fatal until we have a reproducible case. If the time out really
+	 * happen, then retry needs to be fixed to maintain the order of IRPs going out
+	 * (cancel in reverse order)
+	 */
+	return;
+
+} /* dbus_if_send_irb_timeout */
+
+/**
+ * When lower DBUS level signals that a send IRB completed, either successful or not, the higher
+ * level (eg dhd_linux.c) has to be notified, and transmit flow control has to be evaluated.
+ */
+static void
+dbus_if_send_irb_complete(void *handle, dbus_irb_tx_t *txirb, int status)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) handle;
+	int txirb_pending;
+	struct exec_parms args;
+	void *pktinfo;
+
+	if ((dhd_bus == NULL) || (txirb == NULL)) {
+		return;
+	}
+
+	DBUSTRACE(("%s: status = %d\n", __FUNCTION__, status));
+
+	dbus_tx_timer_stop(dhd_bus);
+
+	/* re-queue BEFORE calling send_complete which will assume that this irb
+	   is now available.
+	 */
+	pktinfo = txirb->info;
+	bzero(txirb, sizeof(dbus_irb_tx_t));
+	args.qenq.q = dhd_bus->tx_q;
+	args.qenq.b = (dbus_irb_t *) txirb;
+	EXEC_TXLOCK(dhd_bus, q_enq_exec, &args);
+
+	if (dhd_bus->pub.busstate != DBUS_STATE_DOWN) {
+		if ((status == DBUS_OK) || (status == DBUS_ERR_NODEVICE)) {
+			if (dhd_bus->cbs && dhd_bus->cbs->send_complete)
+				dhd_bus->cbs->send_complete(dhd_bus->cbarg, pktinfo,
+					status);
+
+			if (status == DBUS_OK) {
+				txirb_pending = dhd_bus->pub.ntxq - dhd_bus->tx_q->cnt;
+				if (txirb_pending)
+					dbus_tx_timer_start(dhd_bus, DBUS_TX_TIMEOUT_INTERVAL);
+				if ((txirb_pending < dhd_bus->tx_low_watermark) &&
+					dhd_bus->txoff && !dhd_bus->txoverride) {
+					dbus_flowctrl_tx(dhd_bus, OFF);
+				}
+			}
+		} else {
+			DBUSERR(("%s: %d WARNING freeing orphan pkt %p\n", __FUNCTION__, __LINE__,
+				pktinfo));
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_TXNOCOPY) || defined(BCM_RPC_TOC)
+			if (pktinfo)
+				if (dhd_bus->cbs && dhd_bus->cbs->send_complete)
+					dhd_bus->cbs->send_complete(dhd_bus->cbarg, pktinfo,
+						status);
+#else
+			dbus_if_pktfree(dhd_bus, (void*)pktinfo, TRUE);
+#endif /* defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_TXNOCOPY) || defined(BCM_RPC_TOC) */
+		}
+	} else {
+		DBUSERR(("%s: %d WARNING freeing orphan pkt %p\n", __FUNCTION__, __LINE__,
+			pktinfo));
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_TXNOCOPY) || defined(BCM_RPC_TOC)
+		if (pktinfo)
+			if (dhd_bus->cbs && dhd_bus->cbs->send_complete)
+				dhd_bus->cbs->send_complete(dhd_bus->cbarg, pktinfo,
+					status);
+#else
+		dbus_if_pktfree(dhd_bus, (void*)pktinfo, TRUE);
+#endif /* defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_TXNOCOPY) defined(BCM_RPC_TOC) */
+	}
+} /* dbus_if_send_irb_complete */
+
+/**
+ * When lower DBUS level signals that a receive IRB completed, either successful or not, the higher
+ * level (e.g. dhd_linux.c) has to be notified, and fresh free receive IRBs may have to be given
+ * to lower levels.
+ */
+static void
+dbus_if_recv_irb_complete(void *handle, dbus_irb_rx_t *rxirb, int status)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) handle;
+	int rxirb_pending;
+	struct exec_parms args;
+
+	if ((dhd_bus == NULL) || (rxirb == NULL)) {
+		return;
+	}
+	DBUSTRACE(("%s\n", __FUNCTION__));
+	if (dhd_bus->pub.busstate != DBUS_STATE_DOWN &&
+		dhd_bus->pub.busstate != DBUS_STATE_SLEEP) {
+		if (status == DBUS_OK) {
+			if ((rxirb->buf != NULL) && (rxirb->actual_len > 0)) {
+#ifdef DBUS_USB_LOOPBACK
+				if (is_loopback_pkt(rxirb->buf)) {
+					matches_loopback_pkt(rxirb->buf);
+				} else
+#endif
+				if (dhd_bus->cbs && dhd_bus->cbs->recv_buf) {
+					dhd_bus->cbs->recv_buf(dhd_bus->cbarg, rxirb->buf,
+					rxirb->actual_len);
+				}
+			} else if (rxirb->pkt != NULL) {
+				if (dhd_bus->cbs && dhd_bus->cbs->recv_pkt)
+					dhd_bus->cbs->recv_pkt(dhd_bus->cbarg, rxirb->pkt);
+			} else {
+				ASSERT(0); /* Should not happen */
+			}
+
+			rxirb_pending = dhd_bus->pub.nrxq - dhd_bus->rx_q->cnt - 1;
+#ifdef BCMDBG
+			dhd_bus->rxpend_q_hist[rxirb_pending]++;
+#endif /* BCMDBG */
+			if ((rxirb_pending <= dhd_bus->rx_low_watermark) &&
+				!dhd_bus->rxoff) {
+				DBUSTRACE(("Low watermark so submit more %d <= %d \n",
+					dhd_bus->rx_low_watermark, rxirb_pending));
+				dbus_rxirbs_fill(dhd_bus);
+			} else if (dhd_bus->rxoff)
+				DBUSTRACE(("rx flow controlled. not filling more. cut_rxq=%d\n",
+					dhd_bus->rx_q->cnt));
+		} else if (status == DBUS_ERR_NODEVICE) {
+			DBUSERR(("%s: %d status = %d, buf %p\n", __FUNCTION__, __LINE__, status,
+				rxirb->buf));
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
+			if (rxirb->buf) {
+				PKTFRMNATIVE(dhd_bus->pub.osh, rxirb->buf);
+				PKTFREE(dhd_bus->pub.osh, rxirb->buf, FALSE);
+			}
+#endif /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY || BCM_RPC_TOC */
+		} else {
+			if (status != DBUS_ERR_RXZLP)
+				DBUSERR(("%s: %d status = %d, buf %p\n", __FUNCTION__, __LINE__,
+					status, rxirb->buf));
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
+			if (rxirb->buf) {
+				PKTFRMNATIVE(dhd_bus->pub.osh, rxirb->buf);
+				PKTFREE(dhd_bus->pub.osh, rxirb->buf, FALSE);
+			}
+#endif /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY || BCM_RPC_TOC */
+		}
+	} else {
+		DBUSTRACE(("%s: DBUS down, ignoring recv callback. buf %p\n", __FUNCTION__,
+			rxirb->buf));
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
+		if (rxirb->buf) {
+			PKTFRMNATIVE(dhd_bus->pub.osh, rxirb->buf);
+			PKTFREE(dhd_bus->pub.osh, rxirb->buf, FALSE);
+		}
+#endif /* BCM_RPC_NOCOPY || BCM_RPC_TXNOCOPY || BCM_RPC_TOC */
+	}
+	if (dhd_bus->rx_q != NULL) {
+		bzero(rxirb, sizeof(dbus_irb_rx_t));
+		args.qenq.q = dhd_bus->rx_q;
+		args.qenq.b = (dbus_irb_t *) rxirb;
+		EXEC_RXLOCK(dhd_bus, q_enq_exec, &args);
+	} else
+		MFREE(dhd_bus->pub.osh, rxirb, sizeof(dbus_irb_tx_t));
+} /* dbus_if_recv_irb_complete */
+
+/**
+ *  Accumulate errors signaled by lower DBUS levels and signal them to higher (eg dhd_linux.c)
+ *  level.
+ */
+static void
+dbus_if_errhandler(void *handle, int err)
+{
+	dhd_bus_t *dhd_bus = handle;
+	uint32 mask = 0;
+
+	if (dhd_bus == NULL)
+		return;
+
+	switch (err) {
+		case DBUS_ERR_TXFAIL:
+			dhd_bus->pub.stats.tx_errors++;
+			mask |= ERR_CBMASK_TXFAIL;
+			break;
+		case DBUS_ERR_TXDROP:
+			dhd_bus->pub.stats.tx_dropped++;
+			mask |= ERR_CBMASK_TXFAIL;
+			break;
+		case DBUS_ERR_RXFAIL:
+			dhd_bus->pub.stats.rx_errors++;
+			mask |= ERR_CBMASK_RXFAIL;
+			break;
+		case DBUS_ERR_RXDROP:
+			dhd_bus->pub.stats.rx_dropped++;
+			mask |= ERR_CBMASK_RXFAIL;
+			break;
+		default:
+			break;
+	}
+
+	if (dhd_bus->cbs && dhd_bus->cbs->errhandler && (dhd_bus->errmask & mask))
+		dhd_bus->cbs->errhandler(dhd_bus->cbarg, err);
+}
+
+/**
+ * When lower DBUS level signals control IRB completed, higher level (eg dhd_linux.c) has to be
+ * notified.
+ */
+static void
+dbus_if_ctl_complete(void *handle, int type, int status)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) handle;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (dhd_bus == NULL) {
+		DBUSERR(("%s: dhd_bus is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	if (dhd_bus->pub.busstate != DBUS_STATE_DOWN) {
+		if (dhd_bus->cbs && dhd_bus->cbs->ctl_complete)
+			dhd_bus->cbs->ctl_complete(dhd_bus->cbarg, type, status);
+	}
+}
+
+/**
+ * Rx related functionality (flow control, posting of free IRBs to rx queue) is dependent upon the
+ * bus state. When lower DBUS level signals a change in the interface state, take appropriate action
+ * and forward the signaling to the higher (eg dhd_linux.c) level.
+ */
+static void
+dbus_if_state_change(void *handle, int state)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) handle;
+	int old_state;
+
+	if (dhd_bus == NULL)
+		return;
+
+	if (dhd_bus->pub.busstate == state)
+		return;
+	old_state = dhd_bus->pub.busstate;
+	if (state == DBUS_STATE_DISCONNECT) {
+		DBUSERR(("DBUS disconnected\n"));
+	}
+
+	/* Ignore USB SUSPEND while not up yet */
+	if (state == DBUS_STATE_SLEEP && old_state != DBUS_STATE_UP)
+		return;
+
+	DBUSTRACE(("dbus state change from %d to to %d\n", old_state, state));
+
+	/* Don't update state if it's PnP firmware re-download */
+	if (state != DBUS_STATE_PNP_FWDL)
+		dhd_bus->pub.busstate = state;
+	else
+		dbus_flowctrl_rx(handle, FALSE);
+	if (state == DBUS_STATE_SLEEP)
+		dbus_flowctrl_rx(handle, TRUE);
+	if (state == DBUS_STATE_UP) {
+		dbus_rxirbs_fill(dhd_bus);
+		dbus_flowctrl_rx(handle, FALSE);
+	}
+
+	if (dhd_bus->cbs && dhd_bus->cbs->state_change)
+		dhd_bus->cbs->state_change(dhd_bus->cbarg, state);
+}
+
+/** Forward request for packet from lower DBUS layer to higher layer (e.g. dhd_linux.c) */
+static void *
+dbus_if_pktget(void *handle, uint len, bool send)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) handle;
+	void *p = NULL;
+
+	if (dhd_bus == NULL)
+		return NULL;
+
+	if (dhd_bus->cbs && dhd_bus->cbs->pktget)
+		p = dhd_bus->cbs->pktget(dhd_bus->cbarg, len, send);
+	else
+		ASSERT(0);
+
+	return p;
+}
+
+/** Forward request to free packet from lower DBUS layer to higher layer (e.g. dhd_linux.c) */
+static void
+dbus_if_pktfree(void *handle, void *p, bool send)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) handle;
+
+	if (dhd_bus == NULL)
+		return;
+
+	if (dhd_bus->cbs && dhd_bus->cbs->pktfree)
+		dhd_bus->cbs->pktfree(dhd_bus->cbarg, p, send);
+	else
+		ASSERT(0);
+}
+
+/** Lower DBUS level requests either a send or receive IRB */
+static struct dbus_irb*
+dbus_if_getirb(void *cbarg, bool send)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) cbarg;
+	struct exec_parms args;
+	struct dbus_irb *irb;
+
+	if ((dhd_bus == NULL) || (dhd_bus->pub.busstate != DBUS_STATE_UP))
+		return NULL;
+
+	if (send == TRUE) {
+		args.qdeq.q = dhd_bus->tx_q;
+		irb = EXEC_TXLOCK(dhd_bus, q_deq_exec, &args);
+	} else {
+		args.qdeq.q = dhd_bus->rx_q;
+		irb = EXEC_RXLOCK(dhd_bus, q_deq_exec, &args);
+	}
+
+	return irb;
+}
+
+/* Register/Unregister functions are called by the main DHD entry
+ * point (e.g. module insertion) to link with the bus driver, in
+ * order to look for or await the device.
+ */
+
+static dbus_driver_t dhd_dbus = {
+	dhd_dbus_probe_cb,
+	dhd_dbus_disconnect_cb,
+	dbus_suspend,
+	dbus_resume
+};
+
+/**
+ * As part of initialization, higher level (eg dhd_linux.c) requests DBUS to prepare for
+ * action.
+ */
+int
+dhd_bus_register(void)
+{
+	int err;
+
+	DBUSTRACE(("%s: Enter\n", __FUNCTION__));
+
+	err = dbus_bus_register(&dhd_dbus, &g_busintf);
+
+	/* Device not detected */
+	if (err == DBUS_ERR_NODEVICE)
+		err = DBUS_OK;
+
+	return err;
+}
+
+dhd_pub_t *g_pub = NULL;
+bool net_attached = FALSE;
+void
+dhd_bus_unregister(void)
+{
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	DHD_MUTEX_LOCK();
+	if (g_pub) {
+		g_pub->dhd_remove = TRUE;
+		if (!g_pub->bus) {
+			dhd_dbus_disconnect_cb(g_pub->bus);
+		}
+	}
+	DHD_MUTEX_UNLOCK();
+	dbus_bus_deregister();
+}
+
+/** As part of initialization, data structures have to be allocated and initialized */
+dhd_bus_t *
+dbus_attach(osl_t *osh, int rxsize, int nrxq, int ntxq, dhd_pub_t *pub,
+	dbus_callbacks_t *cbs, dbus_extdl_t *extdl, struct shared_info *sh)
+{
+	dhd_bus_t *dhd_bus;
+	int err;
+
+	if ((g_busintf == NULL) || (g_busintf->attach == NULL) || (cbs == NULL))
+		return NULL;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if ((nrxq <= 0) || (ntxq <= 0))
+		return NULL;
+
+	dhd_bus = MALLOCZ(osh, sizeof(dhd_bus_t));
+	if (dhd_bus == NULL) {
+		DBUSERR(("%s: malloc failed %zu\n", __FUNCTION__, sizeof(dhd_bus_t)));
+		return NULL;
+	}
+
+	/* BUS-specific driver interface (at a lower DBUS level) */
+	dhd_bus->drvintf = g_busintf;
+	dhd_bus->cbarg = pub;
+	dhd_bus->cbs = cbs;
+
+	dhd_bus->pub.sh = sh;
+	dhd_bus->pub.osh = osh;
+	dhd_bus->pub.rxsize = rxsize;
+
+#ifdef EHCI_FASTPATH_RX
+	atomic_set(&dhd_bus->rx_outstanding, 0);
+#endif
+
+	dhd_bus->pub.nrxq = nrxq;
+	dhd_bus->rx_low_watermark = nrxq / 2;	/* keep enough posted rx urbs */
+	dhd_bus->pub.ntxq = ntxq;
+	dhd_bus->tx_low_watermark = ntxq / 4;	/* flow control when too many tx urbs posted */
+
+	dhd_bus->tx_q = MALLOCZ(osh, sizeof(dbus_irbq_t));
+	if (dhd_bus->tx_q == NULL)
+		goto error;
+	else {
+		err = dbus_irbq_init(dhd_bus, dhd_bus->tx_q, ntxq, sizeof(dbus_irb_tx_t));
+		if (err != DBUS_OK)
+			goto error;
+	}
+
+	dhd_bus->rx_q = MALLOCZ(osh, sizeof(dbus_irbq_t));
+	if (dhd_bus->rx_q == NULL)
+		goto error;
+	else {
+		err = dbus_irbq_init(dhd_bus, dhd_bus->rx_q, nrxq, sizeof(dbus_irb_rx_t));
+		if (err != DBUS_OK)
+			goto error;
+	}
+
+#ifdef BCMDBG
+	dhd_bus->txpend_q_hist = MALLOCZ(osh, dhd_bus->pub.ntxq * sizeof(int));
+	if (dhd_bus->txpend_q_hist == NULL)
+		goto error;
+
+	dhd_bus->rxpend_q_hist = MALLOCZ(osh, dhd_bus->pub.nrxq * sizeof(int));
+	if (dhd_bus->rxpend_q_hist == NULL)
+		goto error;
+#endif /* BCMDBG */
+
+	dhd_bus->bus_info = (void *)g_busintf->attach(&dhd_bus->pub,
+		dhd_bus, &dbus_intf_cbs);
+	if (dhd_bus->bus_info == NULL)
+		goto error;
+
+	dbus_tx_timer_init(dhd_bus);
+
+#if defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW)
+	/* Need to copy external image for re-download */
+	if (extdl && extdl->fw && (extdl->fwlen > 0)) {
+		dhd_bus->extdl.fw = MALLOCZ(osh, extdl->fwlen);
+		if (dhd_bus->extdl.fw) {
+			bcopy(extdl->fw, dhd_bus->extdl.fw, extdl->fwlen);
+			dhd_bus->extdl.fwlen = extdl->fwlen;
+		}
+	}
+
+	if (extdl && extdl->vars && (extdl->varslen > 0)) {
+		dhd_bus->extdl.vars = MALLOCZ(osh, extdl->varslen);
+		if (dhd_bus->extdl.vars) {
+			bcopy(extdl->vars, dhd_bus->extdl.vars, extdl->varslen);
+			dhd_bus->extdl.varslen = extdl->varslen;
+		}
+	}
+#endif /* defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW) */
+
+	return (dhd_bus_t *)dhd_bus;
+
+error:
+	DBUSERR(("%s: Failed\n", __FUNCTION__));
+	dbus_detach(dhd_bus);
+	return NULL;
+} /* dbus_attach */
+
+static void
+dbus_detach(dhd_bus_t *pub)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+	osl_t *osh;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (dhd_bus == NULL)
+		return;
+
+	dbus_tx_timer_stop(dhd_bus);
+
+	osh = pub->pub.osh;
+
+	if (dhd_bus->drvintf && dhd_bus->drvintf->detach)
+		 dhd_bus->drvintf->detach((dbus_pub_t *)dhd_bus, dhd_bus->bus_info);
+
+	if (dhd_bus->tx_q) {
+		dbus_irbq_deinit(dhd_bus, dhd_bus->tx_q, sizeof(dbus_irb_tx_t));
+		MFREE(osh, dhd_bus->tx_q, sizeof(dbus_irbq_t));
+		dhd_bus->tx_q = NULL;
+	}
+
+	if (dhd_bus->rx_q) {
+		dbus_irbq_deinit(dhd_bus, dhd_bus->rx_q, sizeof(dbus_irb_rx_t));
+		MFREE(osh, dhd_bus->rx_q, sizeof(dbus_irbq_t));
+		dhd_bus->rx_q = NULL;
+	}
+
+#ifdef BCMDBG
+	if (dhd_bus->txpend_q_hist)
+		MFREE(osh, dhd_bus->txpend_q_hist, dhd_bus->pub.ntxq * sizeof(int));
+	if (dhd_bus->rxpend_q_hist)
+		MFREE(osh, dhd_bus->rxpend_q_hist, dhd_bus->pub.nrxq * sizeof(int));
+#endif /* BCMDBG */
+
+	if (dhd_bus->extdl.fw && (dhd_bus->extdl.fwlen > 0)) {
+		MFREE(osh, dhd_bus->extdl.fw, dhd_bus->extdl.fwlen);
+		dhd_bus->extdl.fw = NULL;
+		dhd_bus->extdl.fwlen = 0;
+	}
+
+	if (dhd_bus->extdl.vars && (dhd_bus->extdl.varslen > 0)) {
+		MFREE(osh, dhd_bus->extdl.vars, dhd_bus->extdl.varslen);
+		dhd_bus->extdl.vars = NULL;
+		dhd_bus->extdl.varslen = 0;
+	}
+
+	MFREE(osh, dhd_bus, sizeof(dhd_bus_t));
+} /* dbus_detach */
+
+int dbus_dlneeded(dhd_bus_t *pub)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+	int dlneeded = DBUS_ERR;
+
+	if (!dhd_bus) {
+		DBUSERR(("%s: dhd_bus is NULL\n", __FUNCTION__));
+		return DBUS_ERR;
+	}
+
+	DBUSTRACE(("%s: state %d\n", __FUNCTION__, dhd_bus->pub.busstate));
+
+	if (dhd_bus->drvintf->dlneeded) {
+		dlneeded = dhd_bus->drvintf->dlneeded(dhd_bus->bus_info);
+	}
+	printf("%s: dlneeded=%d\n", __FUNCTION__, dlneeded);
+
+	/* dlneeded > 0: need to download
+	  * dlneeded = 0: downloaded
+	  * dlneeded < 0: bus error*/
+	return dlneeded;
+}
+
+#if (defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW))
+int dbus_download_firmware(dhd_bus_t *pub)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+	int err = DBUS_OK;
+
+	if (!dhd_bus) {
+		DBUSERR(("%s: dhd_bus is NULL\n", __FUNCTION__));
+		return DBUS_ERR;
+	}
+
+	DBUSTRACE(("%s: state %d\n", __FUNCTION__, dhd_bus->pub.busstate));
+
+	dhd_bus->pub.busstate = DBUS_STATE_DL_PENDING;
+	err = dbus_do_download(dhd_bus);
+	if (err == DBUS_OK) {
+		dhd_bus->pub.busstate = DBUS_STATE_DL_DONE;
+	} else {
+		DBUSERR(("%s: download failed (%d)\n", __FUNCTION__, err));
+	}
+
+	return err;
+}
+#endif /* BCM_DNGL_EMBEDIMAGE || BCM_REQUEST_FW */
+
+/**
+ * higher layer requests us to 'up' the interface to the dongle. Prerequisite is that firmware (not
+ * bootloader) must be active in the dongle.
+ */
+int
+dbus_up(struct dhd_bus *pub)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+	int err = DBUS_OK;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (dhd_bus == NULL) {
+		DBUSERR(("%s: dhd_bus is NULL\n", __FUNCTION__));
+		return DBUS_ERR;
+	}
+
+	if ((dhd_bus->pub.busstate == DBUS_STATE_DL_DONE) ||
+		(dhd_bus->pub.busstate == DBUS_STATE_DOWN) ||
+		(dhd_bus->pub.busstate == DBUS_STATE_SLEEP)) {
+		if (dhd_bus->drvintf && dhd_bus->drvintf->up) {
+			err = dhd_bus->drvintf->up(dhd_bus->bus_info);
+
+			if (err == DBUS_OK) {
+				dbus_rxirbs_fill(dhd_bus);
+			}
+		}
+	} else
+		err = DBUS_ERR;
+
+	return err;
+}
+
+/** higher layer requests us to 'down' the interface to the dongle. */
+int
+dbus_down(dbus_pub_t *pub)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (dhd_bus == NULL)
+		return DBUS_ERR;
+
+	dbus_tx_timer_stop(dhd_bus);
+
+	if (dhd_bus->pub.busstate == DBUS_STATE_UP ||
+		dhd_bus->pub.busstate == DBUS_STATE_SLEEP) {
+		if (dhd_bus->drvintf && dhd_bus->drvintf->down)
+			return dhd_bus->drvintf->down(dhd_bus->bus_info);
+	}
+
+	return DBUS_ERR;
+}
+
+int
+dbus_shutdown(dbus_pub_t *pub)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (dhd_bus == NULL)
+		return DBUS_ERR;
+
+	if (dhd_bus->drvintf && dhd_bus->drvintf->shutdown)
+		return dhd_bus->drvintf->shutdown(dhd_bus->bus_info);
+
+	return DBUS_OK;
+}
+
+int
+dbus_stop(struct dhd_bus *pub)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (dhd_bus == NULL)
+		return DBUS_ERR;
+
+	if (dhd_bus->pub.busstate == DBUS_STATE_UP ||
+		dhd_bus->pub.busstate == DBUS_STATE_SLEEP) {
+		if (dhd_bus->drvintf && dhd_bus->drvintf->stop)
+			return dhd_bus->drvintf->stop(dhd_bus->bus_info);
+	}
+
+	return DBUS_ERR;
+}
+
+int
+dbus_send_buf(dbus_pub_t *pub, uint8 *buf, int len, void *info)
+{
+	return dbus_send_irb(pub, buf, len, NULL, info);
+}
+
+static int
+dbus_send_pkt(dbus_pub_t *pub, void *pkt, void *info)
+{
+	return dbus_send_irb(pub, NULL, 0, pkt, info);
+}
+
+static int
+dbus_send_ctl(struct dhd_bus *pub, uint8 *buf, int len)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+
+	if (dhd_bus == NULL) {
+		DBUSERR(("%s: dhd_bus is NULL\n", __FUNCTION__));
+		return DBUS_ERR;
+	}
+
+	if (dhd_bus->pub.busstate == DBUS_STATE_UP ||
+		dhd_bus->pub.busstate == DBUS_STATE_SLEEP) {
+		if (dhd_bus->drvintf && dhd_bus->drvintf->send_ctl)
+			return dhd_bus->drvintf->send_ctl(dhd_bus->bus_info, buf, len);
+	} else {
+		DBUSERR(("%s: bustate=%d\n", __FUNCTION__, dhd_bus->pub.busstate));
+	}
+
+	return DBUS_ERR;
+}
+
+static int
+dbus_recv_ctl(struct dhd_bus *pub, uint8 *buf, int len)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+
+	if ((dhd_bus == NULL) || (buf == NULL))
+		return DBUS_ERR;
+
+	if (dhd_bus->pub.busstate == DBUS_STATE_UP ||
+		dhd_bus->pub.busstate == DBUS_STATE_SLEEP) {
+		if (dhd_bus->drvintf && dhd_bus->drvintf->recv_ctl)
+			return dhd_bus->drvintf->recv_ctl(dhd_bus->bus_info, buf, len);
+	} else {
+		DBUSERR(("%s: bustate=%d\n", __FUNCTION__, dhd_bus->pub.busstate));
+	}
+
+	return DBUS_ERR;
+}
+
+/** Only called via RPC (Dec 2012) */
+int
+dbus_recv_bulk(dbus_pub_t *pub, uint32 ep_idx)
+{
+#ifdef EHCI_FASTPATH_RX
+	/* 2nd bulk in not supported for EHCI_FASTPATH_RX */
+	ASSERT(0);
+#else
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+
+	dbus_irb_rx_t *rxirb;
+	struct exec_parms args;
+	int status;
+
+
+	if (dhd_bus == NULL)
+		return DBUS_ERR;
+
+	args.qdeq.q = dhd_bus->rx_q;
+	if (dhd_bus->pub.busstate == DBUS_STATE_UP) {
+		if (dhd_bus->drvintf && dhd_bus->drvintf->recv_irb_from_ep) {
+			if ((rxirb = (EXEC_RXLOCK(dhd_bus, q_deq_exec, &args))) != NULL) {
+				status = dhd_bus->drvintf->recv_irb_from_ep(dhd_bus->bus_info,
+					rxirb, ep_idx);
+				if (status == DBUS_ERR_RXDROP) {
+					bzero(rxirb, sizeof(dbus_irb_rx_t));
+					args.qenq.q = dhd_bus->rx_q;
+					args.qenq.b = (dbus_irb_t *) rxirb;
+					EXEC_RXLOCK(dhd_bus, q_enq_exec, &args);
+				}
+			}
+		}
+	}
+#endif /* EHCI_FASTPATH_RX */
+
+	return DBUS_ERR; /* ME DVV: This does not seem right :-) */
+}
+
+#ifdef INTR_EP_ENABLE
+/** only called by dhd_cdc.c (Dec 2012) */
+static int
+dbus_poll_intr(dbus_pub_t *pub)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+
+	int status = DBUS_ERR;
+
+	if (dhd_bus == NULL)
+		return DBUS_ERR;
+
+	if (dhd_bus->pub.busstate == DBUS_STATE_UP) {
+		if (dhd_bus->drvintf && dhd_bus->drvintf->recv_irb_from_ep) {
+			status = dhd_bus->drvintf->recv_irb_from_ep(dhd_bus->bus_info,
+				NULL, 0xff);
+		}
+	}
+	return status;
+}
+#endif /* INTR_EP_ENABLE */
+
+/** called by nobody (Dec 2012) */
+void *
+dbus_pktget(dbus_pub_t *pub, int len)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+
+	if ((dhd_bus == NULL) || (len < 0))
+		return NULL;
+
+	return PKTGET(dhd_bus->pub.osh, len, TRUE);
+}
+
+/** called by nobody (Dec 2012) */
+void
+dbus_pktfree(dbus_pub_t *pub, void* pkt)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+
+	if ((dhd_bus == NULL) || (pkt == NULL))
+		return;
+
+	PKTFREE(dhd_bus->pub.osh, pkt, TRUE);
+}
+
+/** called by nobody (Dec 2012) */
+int
+dbus_get_stats(dbus_pub_t *pub, dbus_stats_t *stats)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+
+	if ((dhd_bus == NULL) || (stats == NULL))
+		return DBUS_ERR;
+
+	bcopy(&dhd_bus->pub.stats, stats, sizeof(dbus_stats_t));
+
+	return DBUS_OK;
+}
+
+int
+dbus_get_attrib(dhd_bus_t *pub, dbus_attrib_t *attrib)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+	int err = DBUS_ERR;
+
+	if ((dhd_bus == NULL) || (attrib == NULL))
+		return DBUS_ERR;
+
+	if (dhd_bus->drvintf && dhd_bus->drvintf->get_attrib) {
+		err = dhd_bus->drvintf->get_attrib(dhd_bus->bus_info,
+		&dhd_bus->pub.attrib);
+	}
+
+	bcopy(&dhd_bus->pub.attrib, attrib, sizeof(dbus_attrib_t));
+	return err;
+}
+
+int
+dbus_get_device_speed(dbus_pub_t *pub)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+
+	if (dhd_bus == NULL)
+		return INVALID_SPEED;
+
+	return (dhd_bus->pub.device_speed);
+}
+
+int
+dbus_set_config(dbus_pub_t *pub, dbus_config_t *config)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+	int err = DBUS_ERR;
+
+	if ((dhd_bus == NULL) || (config == NULL))
+		return DBUS_ERR;
+
+	if (dhd_bus->drvintf && dhd_bus->drvintf->set_config) {
+		err = dhd_bus->drvintf->set_config(dhd_bus->bus_info,
+			config);
+
+		if ((config->config_id == DBUS_CONFIG_ID_AGGR_LIMIT) &&
+			(!err) &&
+			(dhd_bus->pub.busstate == DBUS_STATE_UP)) {
+			dbus_rxirbs_fill(dhd_bus);
+		}
+	}
+
+	return err;
+}
+
+int
+dbus_get_config(dbus_pub_t *pub, dbus_config_t *config)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+	int err = DBUS_ERR;
+
+	if ((dhd_bus == NULL) || (config == NULL))
+		return DBUS_ERR;
+
+	if (dhd_bus->drvintf && dhd_bus->drvintf->get_config) {
+		err = dhd_bus->drvintf->get_config(dhd_bus->bus_info,
+		config);
+	}
+
+	return err;
+}
+
+int
+dbus_set_errmask(dbus_pub_t *pub, uint32 mask)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+	int err = DBUS_OK;
+
+	if (dhd_bus == NULL)
+		return DBUS_ERR;
+
+	dhd_bus->errmask = mask;
+	return err;
+}
+
+int
+dbus_pnp_resume(dbus_pub_t *pub, int *fw_reload)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+	int err = DBUS_ERR;
+	bool fwdl = FALSE;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (dhd_bus == NULL)
+		return DBUS_ERR;
+
+	if (dhd_bus->pub.busstate == DBUS_STATE_UP) {
+		return DBUS_OK;
+	}
+
+#if defined(BCM_DNGL_EMBEDIMAGE)
+	if (dhd_bus->drvintf->device_exists &&
+		dhd_bus->drvintf->device_exists(dhd_bus->bus_info)) {
+		if (dhd_bus->drvintf->dlneeded) {
+			if (dhd_bus->drvintf->dlneeded(dhd_bus->bus_info)) {
+				err = dbus_do_download(dhd_bus);
+				if (err == DBUS_OK) {
+					fwdl = TRUE;
+				}
+				if (dhd_bus->pub.busstate == DBUS_STATE_DL_DONE)
+					dbus_up(&dhd_bus->pub);
+			}
+		}
+	} else {
+		return DBUS_ERR;
+	}
+#endif /* BCM_DNGL_EMBEDIMAGE */
+
+
+	if (dhd_bus->drvintf->pnp) {
+		err = dhd_bus->drvintf->pnp(dhd_bus->bus_info,
+			DBUS_PNP_RESUME);
+	}
+
+	if (dhd_bus->drvintf->recv_needed) {
+		if (dhd_bus->drvintf->recv_needed(dhd_bus->bus_info)) {
+			/* Refill after sleep/hibernate */
+			dbus_rxirbs_fill(dhd_bus);
+		}
+	}
+
+#if defined(BCM_DNGL_EMBEDIMAGE)
+	if (fwdl == TRUE) {
+		dbus_if_state_change(dhd_bus, DBUS_STATE_PNP_FWDL);
+	}
+#endif /* BCM_DNGL_EMBEDIMAGE */
+
+	if (fw_reload)
+		*fw_reload = fwdl;
+
+	return err;
+} /* dbus_pnp_resume */
+
+int
+dbus_pnp_sleep(dbus_pub_t *pub)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+	int err = DBUS_ERR;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (dhd_bus == NULL)
+		return DBUS_ERR;
+
+	dbus_tx_timer_stop(dhd_bus);
+
+	if (dhd_bus->drvintf && dhd_bus->drvintf->pnp) {
+		err = dhd_bus->drvintf->pnp(dhd_bus->bus_info,
+			DBUS_PNP_SLEEP);
+	}
+
+	return err;
+}
+
+int
+dbus_pnp_disconnect(dbus_pub_t *pub)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) pub;
+	int err = DBUS_ERR;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (dhd_bus == NULL)
+		return DBUS_ERR;
+
+	dbus_tx_timer_stop(dhd_bus);
+
+	if (dhd_bus->drvintf && dhd_bus->drvintf->pnp) {
+		err = dhd_bus->drvintf->pnp(dhd_bus->bus_info,
+			DBUS_PNP_DISCONNECT);
+	}
+
+	return err;
+}
+
+int
+dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name,
+	void *params, int plen, void *arg, int len, bool set)
+{
+	dhd_bus_t *dhd_bus = (dhd_bus_t *) dhdp->bus;
+	int err = DBUS_ERR;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (dhd_bus == NULL)
+		return DBUS_ERR;
+
+	if (dhd_bus->drvintf && dhd_bus->drvintf->iovar_op) {
+		err = dhd_bus->drvintf->iovar_op(dhd_bus->bus_info,
+			name, params, plen, arg, len, set);
+	}
+
+	return err;
+}
+
+#ifdef BCMDBG
+void
+dbus_hist_dump(dbus_pub_t *pub, struct bcmstrbuf *b)
+{
+	int i = 0, j = 0;
+	dbus_info_t *dbus_info = (dbus_info_t *) pub;
+
+	bcm_bprintf(b, "\nDBUS histogram\n");
+	bcm_bprintf(b, "txq\n");
+	for (i = 0; i < dbus_info->pub.ntxq; i++) {
+		if (dbus_info->txpend_q_hist[i]) {
+			bcm_bprintf(b, "%d: %d ", i, dbus_info->txpend_q_hist[i]);
+			j++;
+			if (j % 10 == 0) {
+				bcm_bprintf(b, "\n");
+			}
+		}
+	}
+
+	j = 0;
+	bcm_bprintf(b, "\nrxq\n");
+	for (i = 0; i < dbus_info->pub.nrxq; i++) {
+		if (dbus_info->rxpend_q_hist[i]) {
+			bcm_bprintf(b, "%d: %d ", i, dbus_info->rxpend_q_hist[i]);
+			j++;
+			if (j % 10 == 0) {
+				bcm_bprintf(b, "\n");
+			}
+		}
+	}
+	bcm_bprintf(b, "\n");
+
+	if (dbus_info->drvintf && dbus_info->drvintf->dump)
+		dbus_info->drvintf->dump(dbus_info->bus_info, b);
+}
+#endif /* BCMDBG */
+
+void *
+dhd_dbus_txq(const dbus_pub_t *pub)
+{
+	return NULL;
+}
+
+uint
+dhd_dbus_hdrlen(const dbus_pub_t *pub)
+{
+	return 0;
+}
+
+void *
+dbus_get_devinfo(dbus_pub_t *pub)
+{
+	return pub->dev_info;
+}
+
+#if (defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW)) && !defined(EXTERNAL_FW_PATH)
+static int
+dbus_select_nvram(dhd_bus_t *dhd_bus, int8 *jumbonvram, int jumbolen,
+uint16 boardtype, uint16 boardrev, int8 **nvram, int *nvram_len)
+{
+	/* Multi board nvram file format is contenation of nvram info with \r
+	*  The file format for two contatenated set is
+	*  \nBroadcom Jumbo Nvram file\nfirst_set\nsecond_set\nthird_set\n
+	*/
+	uint8 *nvram_start = NULL, *nvram_end = NULL;
+	uint8 *nvram_start_prev = NULL, *nvram_end_prev = NULL;
+	uint16 btype = 0, brev = 0;
+	int len  = 0;
+	char *field;
+
+	*nvram = NULL;
+	*nvram_len = 0;
+
+	if (strncmp(BCM_JUMBO_START, jumbonvram, strlen(BCM_JUMBO_START))) {
+		/* single nvram file in the native format */
+		DBUSTRACE(("%s: Non-Jumbo NVRAM File \n", __FUNCTION__));
+		*nvram = jumbonvram;
+		*nvram_len = jumbolen;
+		return DBUS_OK;
+	} else {
+		DBUSTRACE(("%s: Jumbo NVRAM File \n", __FUNCTION__));
+	}
+
+	/* sanity test the end of the config sets for proper ending */
+	if (jumbonvram[jumbolen - 1] != BCM_JUMBO_NVRAM_DELIMIT ||
+		jumbonvram[jumbolen - 2] != '\0') {
+		DBUSERR(("%s: Bad Jumbo NVRAM file format\n", __FUNCTION__));
+		return DBUS_JUMBO_BAD_FORMAT;
+	}
+
+	dhd_bus->nvram_nontxt = DBUS_NVRAM_NONTXT;
+
+	nvram_start = jumbonvram;
+
+	while (*nvram_start != BCM_JUMBO_NVRAM_DELIMIT && len < jumbolen) {
+
+		/* consume the  first file info line
+		* \nBroadcom Jumbo Nvram file\nfile1\n ...
+		*/
+		len ++;
+		nvram_start ++;
+	}
+
+	nvram_end = nvram_start;
+
+	/* search for "boardrev=0xabcd" and "boardtype=0x1234" information in
+	* the concatenated nvram config files /sets
+	*/
+
+	while (len < jumbolen) {
+
+		if (*nvram_end == '\0') {
+			/* end of a config set is marked by multiple null characters */
+			len ++;
+			nvram_end ++;
+			DBUSTRACE(("%s: NULL chr len = %d char = 0x%x\n", __FUNCTION__,
+				len, *nvram_end));
+			continue;
+
+		} else if (*nvram_end == BCM_JUMBO_NVRAM_DELIMIT) {
+
+			/* config set delimiter is reached */
+			/* check if next config set is present or not
+			*  return  if next config is not present
+			*/
+
+			/* start search the next config set */
+			nvram_start_prev = nvram_start;
+			nvram_end_prev = nvram_end;
+
+			nvram_end ++;
+			nvram_start = nvram_end;
+			btype = brev = 0;
+			DBUSTRACE(("%s: going to next record len = %d "
+					"char = 0x%x \n", __FUNCTION__, len, *nvram_end));
+			len ++;
+			if (len >= jumbolen) {
+
+				*nvram = nvram_start_prev;
+				*nvram_len = (int)(nvram_end_prev - nvram_start_prev);
+
+				DBUSTRACE(("%s: no more len = %d nvram_end = 0x%p",
+					__FUNCTION__, len, nvram_end));
+
+				return DBUS_JUMBO_NOMATCH;
+
+			} else {
+				continue;
+			}
+
+		} else {
+
+			DBUSTRACE(("%s: config str = %s\n", __FUNCTION__, nvram_end));
+
+			if (bcmp(nvram_end, "boardtype", strlen("boardtype")) == 0) {
+
+				field = strchr(nvram_end, '=');
+				field++;
+				btype = (uint16)bcm_strtoul(field, NULL, 0);
+
+				DBUSTRACE(("%s: btype = 0x%x boardtype = 0x%x \n", __FUNCTION__,
+					btype, boardtype));
+			}
+
+			if (bcmp(nvram_end, "boardrev", strlen("boardrev")) == 0) {
+
+				field = strchr(nvram_end, '=');
+				field++;
+				brev = (uint16)bcm_strtoul(field, NULL, 0);
+
+				DBUSTRACE(("%s: brev = 0x%x boardrev = 0x%x \n", __FUNCTION__,
+					brev, boardrev));
+			}
+			if (btype == boardtype && brev == boardrev) {
+				/* locate nvram config set end - ie.find '\r' char */
+				while (*nvram_end != BCM_JUMBO_NVRAM_DELIMIT)
+					nvram_end ++;
+				*nvram = nvram_start;
+				*nvram_len = (int) (nvram_end - nvram_start);
+				DBUSTRACE(("found len = %d nvram_start = 0x%p "
+					"nvram_end = 0x%p\n", *nvram_len, nvram_start, nvram_end));
+				return DBUS_OK;
+			}
+
+			len += (strlen(nvram_end) + 1);
+			nvram_end += (strlen(nvram_end) + 1);
+		}
+	}
+	return DBUS_JUMBO_NOMATCH;
+} /* dbus_select_nvram */
+
+#endif
+
+#if defined(BCM_DNGL_EMBEDIMAGE)
+
+/* store the global osh handle */
+static osl_t *osl_handle = NULL;
+
+/** this function is a combination of trx.c and bcmdl.c plus dbus adaptation */
+static int
+dbus_zlib_decomp(dhd_bus_t *dhd_bus)
+{
+
+	int method, flags, len, status;
+	unsigned int uncmp_len, uncmp_crc, dec_crc, crc_init;
+	struct trx_header *trx, *newtrx;
+	unsigned char *file = NULL;
+	unsigned char gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+	z_stream d_stream;
+	unsigned char unused;
+	int actual_len = -1;
+	unsigned char *headers;
+	unsigned int trxhdrsize, nvramsize, decomp_memsize, i;
+
+	(void)actual_len;
+	(void)unused;
+	(void)crc_init;
+
+	osl_handle = dhd_bus->pub.osh;
+	dhd_bus->orig_fw = NULL;
+
+	headers = dhd_bus->fw;
+	/* Extract trx header */
+	trx = (struct trx_header *)headers;
+	trxhdrsize = sizeof(struct trx_header);
+
+	if (ltoh32(trx->magic) != TRX_MAGIC) {
+		DBUSERR(("%s: Error: trx bad hdr %x\n", __FUNCTION__,
+			ltoh32(trx->magic)));
+		return -1;
+	}
+
+	headers += sizeof(struct trx_header);
+
+	if (ltoh32(trx->flag_version) & TRX_UNCOMP_IMAGE) {
+		actual_len = ltoh32(trx->offsets[TRX_OFFSETS_DLFWLEN_IDX]) +
+		                     sizeof(struct trx_header);
+		DBUSERR(("%s: not a compressed image\n", __FUNCTION__));
+		return 0;
+	} else {
+		/* Extract the gzip header info */
+		if ((*headers++ != gz_magic[0]) || (*headers++ != gz_magic[1])) {
+			DBUSERR(("%s: Error: gzip bad hdr\n", __FUNCTION__));
+			return -1;
+		}
+
+		method = (int) *headers++;
+		flags = (int) *headers++;
+
+		if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+			DBUSERR(("%s: Error: gzip bad hdr not a Z_DEFLATED file\n", __FUNCTION__));
+			return -1;
+		}
+	}
+
+	/* Discard time, xflags and OS code: */
+	for (len = 0; len < 6; len++)
+		unused = *headers++;
+
+	if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+		len = (uint32) *headers++;
+		len += ((uint32)*headers++)<<8;
+		/* len is garbage if EOF but the loop below will quit anyway */
+		while (len-- != 0) unused = *headers++;
+	}
+
+	if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+		while (*headers++ && (*headers != 0));
+	}
+
+	if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */
+		while (*headers++ && (*headers != 0));
+	}
+
+	if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */
+		for (len = 0; len < 2; len++) unused = *headers++;
+	}
+
+	headers++;	/* I need this, why ? */
+
+	/* create space for the uncompressed file */
+	/* the space is for trx header, uncompressed image  and nvram file */
+	/* with typical compression of 0.6, space double of firmware should be ok */
+
+	decomp_memsize = dhd_bus->fwlen * 2;
+	dhd_bus->decomp_memsize = decomp_memsize;
+	if (!(file = MALLOCZ(osl_handle, decomp_memsize))) {
+		DBUSERR(("%s: check_file : failed malloc\n", __FUNCTION__));
+		goto err;
+	}
+
+	/* Initialise the decompression struct */
+	d_stream.next_in = NULL;
+	d_stream.avail_in = 0;
+	d_stream.next_out = NULL;
+	d_stream.avail_out = decomp_memsize - trxhdrsize;
+	d_stream.zalloc = (alloc_func)0;
+	d_stream.zfree = (free_func)0;
+	if (inflateInit2(&d_stream, -15) != Z_OK) {
+		DBUSERR(("%s: Err: inflateInit2\n", __FUNCTION__));
+		goto err;
+	}
+
+	/* Inflate the code */
+	d_stream.next_in = headers;
+	d_stream.avail_in = ltoh32(trx->len);
+	d_stream.next_out = (unsigned char*)(file + trxhdrsize);
+
+	status = inflate(&d_stream, Z_SYNC_FLUSH);
+
+	if (status != Z_STREAM_END)	{
+		DBUSERR(("%s: Error: decompression failed\n", __FUNCTION__));
+		goto err;
+	}
+
+	uncmp_crc = *d_stream.next_in++;
+	uncmp_crc |= *d_stream.next_in++<<8;
+	uncmp_crc |= *d_stream.next_in++<<16;
+	uncmp_crc |= *d_stream.next_in++<<24;
+
+	uncmp_len = *d_stream.next_in++;
+	uncmp_len |= *d_stream.next_in++<<8;
+	uncmp_len |= *d_stream.next_in++<<16;
+	uncmp_len |= *d_stream.next_in++<<24;
+
+	actual_len = (int) (d_stream.next_in - (unsigned char *)trx);
+
+	inflateEnd(&d_stream);
+
+	/* Do a CRC32 on the uncompressed data */
+	crc_init = crc32(0L, Z_NULL, 0);
+	dec_crc = crc32(crc_init, file + trxhdrsize, uncmp_len);
+
+	if (dec_crc != uncmp_crc) {
+		DBUSERR(("%s: decompression: bad crc check \n", __FUNCTION__));
+		goto err;
+	}
+	else {
+		DBUSTRACE(("%s: decompression: good crc check \n", __FUNCTION__));
+	}
+
+	/* rebuild the new trx header and calculate crc */
+	newtrx = (struct trx_header *)file;
+	newtrx->magic = trx->magic;
+	/* add the uncompressed image flag */
+	newtrx->flag_version = trx->flag_version;
+	newtrx->flag_version  |= htol32(TRX_UNCOMP_IMAGE);
+	newtrx->offsets[TRX_OFFSETS_DLFWLEN_IDX] = htol32(uncmp_len);
+	newtrx->offsets[TRX_OFFSETS_JUMPTO_IDX] = trx->offsets[TRX_OFFSETS_JUMPTO_IDX];
+	newtrx->offsets[TRX_OFFSETS_NVM_LEN_IDX] = trx->offsets[TRX_OFFSETS_NVM_LEN_IDX];
+
+	nvramsize = ltoh32(trx->offsets[TRX_OFFSETS_NVM_LEN_IDX]);
+
+	/* the original firmware has nvram file appended */
+	/* copy the nvram file to uncompressed firmware */
+
+	if (nvramsize) {
+		if (nvramsize + uncmp_len > decomp_memsize) {
+			DBUSERR(("%s: nvram cannot be accomodated\n", __FUNCTION__));
+			goto err;
+		}
+		bcopy(d_stream.next_in, &file[uncmp_len], nvramsize);
+		uncmp_len += nvramsize;
+	}
+
+	/* add trx header size to uncmp_len */
+	uncmp_len += trxhdrsize;
+	/* PR14373 WAR: Pad to multiple of 4096 bytes */
+	uncmp_len = ROUNDUP(uncmp_len, 4096);
+	newtrx->len	= htol32(uncmp_len);
+
+	/* Calculate CRC over header */
+	newtrx->crc32 = hndcrc32((uint8 *)&newtrx->flag_version,
+	sizeof(struct trx_header) - OFFSETOF(struct trx_header, flag_version),
+	CRC32_INIT_VALUE);
+
+	/* Calculate CRC over data */
+	for (i = trxhdrsize; i < (uncmp_len); ++i)
+				newtrx->crc32 = hndcrc32((uint8 *)&file[i], 1, newtrx->crc32);
+	newtrx->crc32 = htol32(newtrx->crc32);
+
+	dhd_bus->orig_fw = dhd_bus->fw;
+	dhd_bus->origfw_len = dhd_bus->fwlen;
+	dhd_bus->image = dhd_bus->fw = file;
+	dhd_bus->image_len = dhd_bus->fwlen = uncmp_len;
+
+	return 0;
+
+err:
+	if (file)
+		free(file);
+	return -1;
+} /* dbus_zlib_decomp */
+
+void *
+dbus_zlib_calloc(int num, int size)
+{
+	uint *ptr;
+	uint totalsize;
+
+	if (osl_handle == NULL)
+		return NULL;
+
+	totalsize = (num * (size + 1));
+
+	ptr  = MALLOCZ(osl_handle, totalsize);
+
+	if (ptr == NULL)
+		return NULL;
+
+	/* store the size in the first integer space */
+
+	ptr[0] = totalsize;
+
+	return ((void *) &ptr[1]);
+}
+
+void
+dbus_zlib_free(void *ptr)
+{
+	uint totalsize;
+	uchar *memptr = (uchar *)ptr;
+
+	if (ptr && osl_handle) {
+		memptr -= sizeof(uint);
+		totalsize = *(uint *) memptr;
+		MFREE(osl_handle, memptr, totalsize);
+	}
+}
+
+#endif /* #if defined(BCM_DNGL_EMBEDIMAGE) */
+
+#define DBUS_NRXQ	50
+#define DBUS_NTXQ	100
+
+static void
+dhd_dbus_send_complete(void *handle, void *info, int status)
+{
+	dhd_pub_t *dhd = (dhd_pub_t *)handle;
+	void *pkt = info;
+
+	if ((dhd == NULL) || (pkt == NULL)) {
+		DBUSERR(("dhd or pkt is NULL\n"));
+		return;
+	}
+
+	if (status == DBUS_OK) {
+		dhd->dstats.tx_packets++;
+	} else {
+		DBUSERR(("TX error=%d\n", status));
+		dhd->dstats.tx_errors++;
+	}
+#ifdef PROP_TXSTATUS
+	if (DHD_PKTTAG_WLFCPKT(PKTTAG(pkt)) &&
+		(dhd_wlfc_txcomplete(dhd, pkt, status == 0) != WLFC_UNSUPPORTED)) {
+		return;
+	} else
+#endif /* PROP_TXSTATUS */
+	dhd_txcomplete(dhd, pkt, status == 0);
+	PKTFREE(dhd->osh, pkt, TRUE);
+}
+
+static void
+dhd_dbus_recv_pkt(void *handle, void *pkt)
+{
+	uchar reorder_info_buf[WLHOST_REORDERDATA_TOTLEN];
+	uint reorder_info_len;
+	uint pkt_count;
+	dhd_pub_t *dhd = (dhd_pub_t *)handle;
+	int ifidx = 0;
+
+	if (dhd == NULL) {
+		DBUSERR(("%s: dhd is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	/* If the protocol uses a data header, check and remove it */
+	if (dhd_prot_hdrpull(dhd, &ifidx, pkt, reorder_info_buf,
+		&reorder_info_len) != 0) {
+		DBUSERR(("rx protocol error\n"));
+		PKTFREE(dhd->osh, pkt, FALSE);
+		dhd->rx_errors++;
+		return;
+	}
+
+	if (reorder_info_len) {
+		/* Reordering info from the firmware */
+		dhd_process_pkt_reorder_info(dhd, reorder_info_buf, reorder_info_len,
+			&pkt, &pkt_count);
+		if (pkt_count == 0)
+			return;
+	}
+	else {
+		pkt_count = 1;
+	}
+	dhd_rx_frame(dhd, ifidx, pkt, pkt_count, 0);
+}
+
+static void
+dhd_dbus_recv_buf(void *handle, uint8 *buf, int len)
+{
+	dhd_pub_t *dhd = (dhd_pub_t *)handle;
+	void *pkt;
+
+	if (dhd == NULL) {
+		DBUSERR(("%s: dhd is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	if ((pkt = PKTGET(dhd->osh, len, FALSE)) == NULL) {
+		DBUSERR(("PKTGET (rx) failed=%d\n", len));
+		return;
+	}
+
+	bcopy(buf, PKTDATA(dhd->osh, pkt), len);
+	dhd_dbus_recv_pkt(dhd, pkt);
+}
+
+static void
+dhd_dbus_txflowcontrol(void *handle, bool onoff)
+{
+	dhd_pub_t *dhd = (dhd_pub_t *)handle;
+	bool wlfc_enabled = FALSE;
+
+	if (dhd == NULL) {
+		DBUSERR(("%s: dhd is NULL\n", __FUNCTION__));
+		return;
+	}
+
+#ifdef PROP_TXSTATUS
+	wlfc_enabled = (dhd_wlfc_flowcontrol(dhd, onoff, !onoff) != WLFC_UNSUPPORTED);
+#endif
+
+	if (!wlfc_enabled) {
+		dhd_txflowcontrol(dhd, ALL_INTERFACES, onoff);
+	}
+}
+
+static void
+dhd_dbus_errhandler(void *handle, int err)
+{
+}
+
+static void
+dhd_dbus_ctl_complete(void *handle, int type, int status)
+{
+	dhd_pub_t *dhd = (dhd_pub_t *)handle;
+
+	if (dhd == NULL) {
+		DBUSERR(("%s: dhd is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	if (type == DBUS_CBCTL_READ) {
+		if (status == DBUS_OK)
+			dhd->rx_ctlpkts++;
+		else
+			dhd->rx_ctlerrs++;
+	} else if (type == DBUS_CBCTL_WRITE) {
+		if (status == DBUS_OK)
+			dhd->tx_ctlpkts++;
+		else
+			dhd->tx_ctlerrs++;
+	}
+
+	dhd->bus->ctl_completed = TRUE;
+	dhd_os_ioctl_resp_wake(dhd);
+}
+
+static void
+dhd_dbus_state_change(void *handle, int state)
+{
+	dhd_pub_t *dhd = (dhd_pub_t *)handle;
+	unsigned long flags;
+	int wowl_dngldown = 0;
+
+	if (dhd == NULL) {
+		DBUSERR(("%s: dhd is NULL\n", __FUNCTION__));
+		return;
+	}
+#ifdef WL_EXT_WOWL
+	wowl_dngldown = dhd_conf_wowl_dngldown(dhd);
+#endif
+
+	if ((dhd->busstate == DHD_BUS_SUSPEND && state == DBUS_STATE_DOWN) ||
+			(dhd->hostsleep && wowl_dngldown)) {
+		DBUSERR(("%s: switch state %d to %d\n", __FUNCTION__, state, DBUS_STATE_SLEEP));
+		state = DBUS_STATE_SLEEP;
+	}
+	switch (state) {
+		case DBUS_STATE_DL_NEEDED:
+			DBUSERR(("%s: firmware request cannot be handled\n", __FUNCTION__));
+			break;
+		case DBUS_STATE_DOWN:
+			DHD_LINUX_GENERAL_LOCK(dhd, flags);
+			dhd_txflowcontrol(dhd, ALL_INTERFACES, ON);
+			DBUSTRACE(("%s: DBUS is down\n", __FUNCTION__));
+			dhd->busstate = DHD_BUS_DOWN;
+			DHD_LINUX_GENERAL_UNLOCK(dhd, flags);
+			break;
+		case DBUS_STATE_UP:
+			DBUSTRACE(("%s: DBUS is up\n", __FUNCTION__));
+			DHD_LINUX_GENERAL_LOCK(dhd, flags);
+			dhd_txflowcontrol(dhd, ALL_INTERFACES, OFF);
+			dhd->busstate = DHD_BUS_DATA;
+			DHD_LINUX_GENERAL_UNLOCK(dhd, flags);
+			break;
+		default:
+			break;
+	}
+
+	DBUSERR(("%s: DBUS current state=%d\n", __FUNCTION__, state));
+}
+
+static void *
+dhd_dbus_pktget(void *handle, uint len, bool send)
+{
+	dhd_pub_t *dhd = (dhd_pub_t *)handle;
+	void *p = NULL;
+
+	if (dhd == NULL) {
+		DBUSERR(("%s: dhd is NULL\n", __FUNCTION__));
+		return NULL;
+	}
+
+	if (send == TRUE) {
+		dhd_os_sdlock_txq(dhd);
+		p = PKTGET(dhd->osh, len, TRUE);
+		dhd_os_sdunlock_txq(dhd);
+	} else {
+		dhd_os_sdlock_rxq(dhd);
+		p = PKTGET(dhd->osh, len, FALSE);
+		dhd_os_sdunlock_rxq(dhd);
+	}
+
+	return p;
+}
+
+static void
+dhd_dbus_pktfree(void *handle, void *p, bool send)
+{
+	dhd_pub_t *dhd = (dhd_pub_t *)handle;
+
+	if (dhd == NULL) {
+		DBUSERR(("%s: dhd is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	if (send == TRUE) {
+#ifdef PROP_TXSTATUS
+		if (DHD_PKTTAG_WLFCPKT(PKTTAG(p)) &&
+			(dhd_wlfc_txcomplete(dhd, p, FALSE) != WLFC_UNSUPPORTED)) {
+			return;
+		}
+#endif /* PROP_TXSTATUS */
+
+		dhd_os_sdlock_txq(dhd);
+		PKTFREE(dhd->osh, p, TRUE);
+		dhd_os_sdunlock_txq(dhd);
+	} else {
+		dhd_os_sdlock_rxq(dhd);
+		PKTFREE(dhd->osh, p, FALSE);
+		dhd_os_sdunlock_rxq(dhd);
+	}
+}
+
+
+static dbus_callbacks_t dhd_dbus_cbs = {
+	dhd_dbus_send_complete,
+	dhd_dbus_recv_buf,
+	dhd_dbus_recv_pkt,
+	dhd_dbus_txflowcontrol,
+	dhd_dbus_errhandler,
+	dhd_dbus_ctl_complete,
+	dhd_dbus_state_change,
+	dhd_dbus_pktget,
+	dhd_dbus_pktfree
+};
+
+uint
+dhd_bus_chip(struct dhd_bus *bus)
+{
+	ASSERT(bus != NULL);
+	return bus->pub.attrib.devid;
+}
+
+uint
+dhd_bus_chiprev(struct dhd_bus *bus)
+{
+	ASSERT(bus);
+	ASSERT(bus != NULL);
+	return bus->pub.attrib.chiprev;
+}
+
+struct device *
+dhd_bus_to_dev(struct dhd_bus *bus)
+{
+	return dbus_get_dev();
+}
+
+void
+dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+{
+	bcm_bprintf(strbuf, "Bus USB\n");
+}
+
+void
+dhd_bus_clearcounts(dhd_pub_t *dhdp)
+{
+}
+
+int
+dhd_bus_txdata(struct dhd_bus *bus, void *pktbuf)
+{
+	DBUSTRACE(("%s\n", __FUNCTION__));
+	if (bus->txoff) {
+		DBUSTRACE(("txoff\n"));
+		return BCME_EPERM;
+	}
+	return dbus_send_pkt(&bus->pub, pktbuf, pktbuf);
+}
+
+int
+dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen)
+{
+	int timeleft = 0;
+	int ret = -1;
+
+	DBUSTRACE(("%s: Enter\n", __FUNCTION__));
+
+	if (bus->dhd->dongle_reset)
+		return -EIO;
+
+	bus->ctl_completed = FALSE;
+	ret = dbus_send_ctl(bus, (void *)msg, msglen);
+	if (ret) {
+		DBUSERR(("%s: dbus_send_ctl error %d\n", __FUNCTION__, ret));
+		return ret;
+	}
+
+	timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->ctl_completed);
+	if ((!timeleft) || (!bus->ctl_completed)) {
+		DBUSERR(("%s: Txctl timeleft %d ctl_completed %d\n",
+			__FUNCTION__, timeleft, bus->ctl_completed));
+		ret = -1;
+#ifdef OEM_ANDROID
+		bus->dhd->hang_reason = HANG_REASON_IOCTL_RESP_TIMEOUT_SCHED_ERROR;
+		dhd_os_send_hang_message(bus->dhd);
+#endif /* OEM_ANDROID */
+	}
+
+#ifdef INTR_EP_ENABLE
+	/* If the ctl write is successfully completed, wait for an acknowledgement
+	* that indicates that it is now ok to do ctl read from the dongle
+	*/
+	if (ret != -1) {
+		bus->ctl_completed = FALSE;
+		if (dbus_poll_intr(bus->pub)) {
+			DBUSERR(("%s: dbus_poll_intr not submitted\n", __FUNCTION__));
+		} else {
+			/* interrupt polling is sucessfully submitted. Wait for dongle to send
+			* interrupt
+			*/
+			timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->ctl_completed);
+			if (!timeleft) {
+				DBUSERR(("%s: intr poll wait timed out\n", __FUNCTION__));
+			}
+		}
+	}
+#endif /* INTR_EP_ENABLE */
+
+	return ret;
+}
+
+int
+dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen)
+{
+	int timeleft;
+	int ret = -1;
+
+	DBUSTRACE(("%s: Enter\n", __FUNCTION__));
+
+	if (bus->dhd->dongle_reset)
+		return -EIO;
+
+	bus->ctl_completed = FALSE;
+	ret = dbus_recv_ctl(bus, (uchar*)msg, msglen);
+	if (ret) {
+		DBUSERR(("%s: dbus_recv_ctl error %d\n", __FUNCTION__, ret));
+		goto done;
+	}
+
+	timeleft = dhd_os_ioctl_resp_wait(bus->dhd, &bus->ctl_completed);
+	if ((!timeleft) || (!bus->ctl_completed)) {
+		DBUSERR(("%s: Rxctl timeleft %d ctl_completed %d\n", __FUNCTION__,
+			timeleft, bus->ctl_completed));
+		ret = -ETIMEDOUT;
+		goto done;
+	}
+
+	/* XXX FIX: Must return cdc_len, not len, because after query_ioctl()
+	 * it subtracts sizeof(cdc_ioctl_t);  The other approach is
+	 * to have dbus_recv_ctl() return actual len.
+	 */
+	ret = msglen;
+
+done:
+	return ret;
+}
+
+static void
+dhd_dbus_advertise_bus_cleanup(dhd_pub_t *dhdp)
+{
+	unsigned long flags;
+	int timeleft;
+
+	DHD_LINUX_GENERAL_LOCK(dhdp, flags);
+	dhdp->busstate = DHD_BUS_DOWN_IN_PROGRESS;
+	DHD_LINUX_GENERAL_UNLOCK(dhdp, flags);
+
+	timeleft = dhd_os_busbusy_wait_negation(dhdp, &dhdp->dhd_bus_busy_state);
+	if ((timeleft == 0) || (timeleft == 1)) {
+		DBUSERR(("%s : Timeout due to dhd_bus_busy_state=0x%x\n",
+				__FUNCTION__, dhdp->dhd_bus_busy_state));
+		ASSERT(0);
+	}
+
+	return;
+}
+
+static void
+dhd_dbus_advertise_bus_remove(dhd_pub_t *dhdp)
+{
+	unsigned long flags;
+	int timeleft;
+
+	DHD_LINUX_GENERAL_LOCK(dhdp, flags);
+	if (dhdp->busstate != DHD_BUS_SUSPEND)
+		dhdp->busstate = DHD_BUS_REMOVE;
+	DHD_LINUX_GENERAL_UNLOCK(dhdp, flags);
+
+	timeleft = dhd_os_busbusy_wait_negation(dhdp, &dhdp->dhd_bus_busy_state);
+	if ((timeleft == 0) || (timeleft == 1)) {
+		DBUSERR(("%s : Timeout due to dhd_bus_busy_state=0x%x\n",
+				__FUNCTION__, dhdp->dhd_bus_busy_state));
+		ASSERT(0);
+	}
+
+	return;
+}
+
+int
+dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
+{
+	int bcmerror = 0;
+	unsigned long flags;
+	wifi_adapter_info_t *adapter = (wifi_adapter_info_t *)dhdp->adapter;
+
+	if (flag == TRUE) {
+		if (!dhdp->dongle_reset) {
+			DBUSERR(("%s: == Power OFF ==\n", __FUNCTION__));
+			dhd_dbus_advertise_bus_cleanup(dhdp);
+			dhd_os_wd_timer(dhdp, 0);
+#if !defined(IGNORE_ETH0_DOWN)
+			/* Force flow control as protection when stop come before ifconfig_down */
+			dhd_txflowcontrol(dhdp, ALL_INTERFACES, ON);
+#endif /* !defined(IGNORE_ETH0_DOWN) */
+			dbus_stop(dhdp->bus);
+
+			dhdp->dongle_reset = TRUE;
+			dhdp->up = FALSE;
+
+			DHD_LINUX_GENERAL_LOCK(dhdp, flags);
+			dhdp->busstate = DHD_BUS_DOWN;
+			DHD_LINUX_GENERAL_UNLOCK(dhdp, flags);
+			wifi_clr_adapter_status(adapter, WIFI_STATUS_FW_READY);
+
+			printf("%s:  WLAN OFF DONE\n", __FUNCTION__);
+			/* App can now remove power from device */
+		} else
+			bcmerror = BCME_ERROR;
+	} else {
+		/* App must have restored power to device before calling */
+		printf("\n\n%s: == WLAN ON ==\n", __FUNCTION__);
+		if (dhdp->dongle_reset) {
+			/* Turn on WLAN */
+			DHD_MUTEX_UNLOCK();
+			wait_event_interruptible_timeout(adapter->status_event,
+				wifi_get_adapter_status(adapter, WIFI_STATUS_FW_READY),
+				msecs_to_jiffies(DHD_FW_READY_TIMEOUT));
+			DHD_MUTEX_LOCK();
+			bcmerror = dbus_up(dhdp->bus);
+			if (bcmerror == BCME_OK) {
+				dhdp->dongle_reset = FALSE;
+				dhdp->up = TRUE;
+#if !defined(IGNORE_ETH0_DOWN)
+				/* Restore flow control  */
+				dhd_txflowcontrol(dhdp, ALL_INTERFACES, OFF);
+#endif
+				dhd_os_wd_timer(dhdp, dhd_watchdog_ms);
+
+				DBUSTRACE(("%s: WLAN ON DONE\n", __FUNCTION__));
+			} else {
+				DBUSERR(("%s: failed to dbus_up with code %d\n", __FUNCTION__, bcmerror));
+			}
+		}
+	}
+
+	return bcmerror;
+}
+
+void
+dhd_bus_update_fw_nv_path(struct dhd_bus *bus, char *pfw_path,
+	char *pnv_path, char *pclm_path, char *pconf_path)
+{
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (bus == NULL) {
+		DBUSERR(("%s: bus is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	bus->fw_path = pfw_path;
+	bus->nv_path = pnv_path;
+	bus->dhd->clm_path = pclm_path;
+	bus->dhd->conf_path = pconf_path;
+
+	dhd_conf_set_path_params(bus->dhd, bus->fw_path, bus->nv_path);
+
+}
+
+static int
+dhd_dbus_sync_dongle(dhd_pub_t *pub, int dlneeded)
+{
+	int ret = 0;
+
+	if (dlneeded == 0) {
+		ret = dbus_up(pub->bus);
+		if (ret) {
+			DBUSERR(("%s: dbus_up failed!!\n", __FUNCTION__));
+			goto exit;
+		}
+		ret = dhd_sync_with_dongle(pub);
+		if (ret < 0) {
+			DBUSERR(("%s: failed with code ret=%d\n", __FUNCTION__, ret));
+			goto exit;
+		}
+	}
+
+exit:
+	return ret;
+}
+
+static int
+dbus_suspend(void *context)
+{
+	int ret = 0;
+
+#if defined(LINUX)
+	dhd_bus_t *bus = (dhd_bus_t*)context;
+	unsigned long flags;
+
+	DBUSERR(("%s Enter\n", __FUNCTION__));
+	if (bus->dhd == NULL) {
+		DBUSERR(("bus not inited\n"));
+		return BCME_ERROR;
+	}
+	if (bus->dhd->prot == NULL) {
+		DBUSERR(("prot is not inited\n"));
+		return BCME_ERROR;
+	}
+
+	if (bus->dhd->up == FALSE) {
+		return BCME_OK;
+	}
+
+	DHD_LINUX_GENERAL_LOCK(bus->dhd, flags);
+	if (bus->dhd->busstate != DHD_BUS_DATA && bus->dhd->busstate != DHD_BUS_SUSPEND) {
+		DBUSERR(("not in a readystate to LPBK  is not inited\n"));
+		DHD_LINUX_GENERAL_UNLOCK(bus->dhd, flags);
+		return BCME_ERROR;
+	}
+	DHD_LINUX_GENERAL_UNLOCK(bus->dhd, flags);
+	if (bus->dhd->dongle_reset) {
+		DBUSERR(("Dongle is in reset state.\n"));
+		return -EIO;
+	}
+
+	DHD_LINUX_GENERAL_LOCK(bus->dhd, flags);
+	/* stop all interface network queue. */
+	dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, ON);
+	bus->dhd->busstate = DHD_BUS_SUSPEND;
+#if defined(LINUX) || defined(linux)
+	if (DHD_BUS_BUSY_CHECK_IN_TX(bus->dhd)) {
+		DBUSERR(("Tx Request is not ended\n"));
+		bus->dhd->busstate = DHD_BUS_DATA;
+		/* resume all interface network queue. */
+		dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, OFF);
+		DHD_LINUX_GENERAL_UNLOCK(bus->dhd, flags);
+		return -EBUSY;
+	}
+#endif /* LINUX || linux */
+	DHD_BUS_BUSY_SET_SUSPEND_IN_PROGRESS(bus->dhd);
+	DHD_LINUX_GENERAL_UNLOCK(bus->dhd, flags);
+
+	ret = dhd_os_check_wakelock_all(bus->dhd);
+
+	DHD_LINUX_GENERAL_LOCK(bus->dhd, flags);
+	if (ret) {
+		bus->dhd->busstate = DHD_BUS_DATA;
+		/* resume all interface network queue. */
+		dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, OFF);
+	} else {
+		bus->last_suspend_end_time = OSL_LOCALTIME_NS();
+	}
+	bus->dhd->hostsleep = HOSTSLEEP_DHD_SET;
+	DHD_BUS_BUSY_CLEAR_SUSPEND_IN_PROGRESS(bus->dhd);
+	dhd_os_busbusy_wake(bus->dhd);
+	DHD_LINUX_GENERAL_UNLOCK(bus->dhd, flags);
+
+#endif /* LINUX */
+	DBUSERR(("%s Exit ret=%d\n", __FUNCTION__, ret));
+	return ret;
+}
+
+static int
+dbus_resume(void *context)
+{
+	dhd_bus_t *bus = (dhd_bus_t*)context;
+	ulong flags;
+	int dlneeded = 0;
+	int ret = 0;
+
+	DBUSERR(("%s Enter\n", __FUNCTION__));
+
+	if (bus->dhd->up == FALSE) {
+		return BCME_OK;
+	}
+
+	dlneeded = dbus_dlneeded(bus);
+	if (dlneeded == 0) {
+		ret = dbus_up(bus);
+		if (ret) {
+			DBUSERR(("%s: dbus_up failed!!\n", __FUNCTION__));
+		}
+	}
+
+	DHD_LINUX_GENERAL_LOCK(bus->dhd, flags);
+	DHD_BUS_BUSY_SET_RESUME_IN_PROGRESS(bus->dhd);
+	DHD_LINUX_GENERAL_UNLOCK(bus->dhd, flags);
+
+	DHD_LINUX_GENERAL_LOCK(bus->dhd, flags);
+	DHD_BUS_BUSY_CLEAR_RESUME_IN_PROGRESS(bus->dhd);
+	bus->dhd->hostsleep = HOSTSLEEP_CLEAR;
+	bus->dhd->busstate = DHD_BUS_DATA;
+	dhd_os_busbusy_wake(bus->dhd);
+	/* resume all interface network queue. */
+	dhd_txflowcontrol(bus->dhd, ALL_INTERFACES, OFF);
+	DHD_LINUX_GENERAL_UNLOCK(bus->dhd, flags);
+//	dhd_conf_set_suspend_resume(bus->dhd, 0);
+
+	return 0;
+}
+
+/*
+ * hdrlen is space to reserve in pkt headroom for DBUS
+ */
+static void *
+dhd_dbus_probe_cb(uint16 bus_no, uint16 slot, uint32 hdrlen)
+{
+	osl_t *osh = NULL;
+	dhd_bus_t *bus = NULL;
+	dhd_pub_t *pub = NULL;
+	uint rxsz;
+	int dlneeded = 0, ret = DBUS_OK;
+	wifi_adapter_info_t *adapter = NULL;
+	bool net_attach_now = TRUE;
+
+	DBUSTRACE(("%s: Enter\n", __FUNCTION__));
+
+	adapter = dhd_wifi_platform_get_adapter(USB_BUS, bus_no, slot);
+
+	if (!g_pub) {
+		/* Ask the OS interface part for an OSL handle */
+		if (!(osh = osl_attach(NULL, USB_BUS, TRUE))) {
+			DBUSERR(("%s: OSL attach failed\n", __FUNCTION__));
+			goto fail;
+		}
+
+		/* Attach to the dhd/OS interface */
+		if (!(pub = dhd_attach(osh, bus, hdrlen, adapter))) {
+			DBUSERR(("%s: dhd_attach failed\n", __FUNCTION__));
+			goto fail;
+		}
+	} else {
+		pub = g_pub;
+		osh = pub->osh;
+	}
+
+	if (pub->bus) {
+		DBUSERR(("%s: wrong probe\n", __FUNCTION__));
+		goto fail;
+	}
+
+	rxsz = dhd_get_rxsz(pub);
+	bus = dbus_attach(osh, rxsz, DBUS_NRXQ, DBUS_NTXQ, pub, &dhd_dbus_cbs, NULL, NULL);
+	if (bus) {
+		pub->bus = bus;
+		bus->dhd = pub;
+
+		dlneeded = dbus_dlneeded(bus);
+		if (dlneeded >= 0 && !g_pub) {
+			dhd_conf_reset(pub);
+			dhd_conf_set_chiprev(pub, bus->pub.attrib.devid, bus->pub.attrib.chiprev);
+			dhd_conf_preinit(pub);
+		}
+
+#if defined(BCMDHD_MODULAR) && defined(INSMOD_FW_LOAD)
+		if (1)
+#else
+		if (g_pub || dhd_download_fw_on_driverload)
+#endif
+		{
+			if (dlneeded == 0)
+				wifi_set_adapter_status(adapter, WIFI_STATUS_FW_READY);
+#ifdef BCM_REQUEST_FW
+			else if (dlneeded > 0) {
+				struct dhd_conf *conf = pub->conf;
+				unsigned long flags;
+				bool suspended;
+				wifi_clr_adapter_status(adapter, WIFI_STATUS_FW_READY);
+				suspended = conf->suspended;
+				dhd_set_path(bus->dhd);
+				conf->suspended = suspended;
+				if (dbus_download_firmware(bus) != DBUS_OK)
+					goto fail;
+				DHD_LINUX_GENERAL_LOCK(pub, flags);
+				if (bus->dhd->busstate != DHD_BUS_SUSPEND)
+					bus->dhd->busstate = DHD_BUS_LOAD;
+				DHD_LINUX_GENERAL_UNLOCK(pub, flags);
+			}
+#endif
+			else {
+				goto fail;
+			}
+		}
+	}
+	else {
+		DBUSERR(("%s: dbus_attach failed\n", __FUNCTION__));
+		goto fail;
+	}
+
+#if defined(BCMDHD_MODULAR) && defined(INSMOD_FW_LOAD)
+	if (dlneeded > 0)
+		net_attach_now = FALSE;
+#endif
+
+	if (!net_attached && (net_attach_now || (dlneeded == 0))) {
+		if (dhd_dbus_sync_dongle(pub, dlneeded)) {
+			goto fail;
+		}
+		if (dhd_attach_net(bus->dhd, TRUE) != 0) {
+			DBUSERR(("%s: Net attach failed!!\n", __FUNCTION__));
+			goto fail;
+		}
+		pub->hang_report  = TRUE;
+#if defined(MULTIPLE_SUPPLICANT)
+		wl_android_post_init(); // terence 20120530: fix critical section in dhd_open and dhdsdio_probe
+#endif
+		net_attached = TRUE;
+	}
+	else if (net_attached && (pub->up == 1) && (dlneeded == 0)) {
+		// kernel resume case
+		pub->hostsleep = HOSTSLEEP_CLEAR;
+		ret = dhd_dbus_sync_dongle(pub, dlneeded);
+#ifdef WL_CFG80211
+		__wl_cfg80211_up_resume(pub);
+		wl_cfgp2p_start_p2p_device_resume(pub);
+#endif
+		dhd_conf_set_suspend_resume(pub, 0);
+		if (ret != DBUS_OK)
+			goto fail;
+	}
+
+	if (!g_pub) {
+		g_pub = pub;
+	}
+
+	DBUSTRACE(("%s: Exit\n", __FUNCTION__));
+	wifi_clr_adapter_status(adapter, WIFI_STATUS_BUS_DISCONNECTED);
+	if (net_attached) {
+		wifi_set_adapter_status(adapter, WIFI_STATUS_NET_ATTACHED);
+		wake_up_interruptible(&adapter->status_event);
+		/* This is passed to dhd_dbus_disconnect_cb */
+	}
+	return bus;
+
+fail:
+	if (pub && pub->bus) {
+		dbus_detach(pub->bus);
+		pub->bus = NULL;
+	}
+	/* Release resources in reverse order */
+	if (!g_pub) {
+		if (pub) {
+			dhd_detach(pub);
+			dhd_free(pub);
+		}
+		if (osh) {
+			osl_detach(osh);
+		}
+	}
+
+	printf("%s: Failed\n", __FUNCTION__);
+	return NULL;
+}
+
+static void
+dhd_dbus_disconnect_cb(void *arg)
+{
+	dhd_bus_t *bus = (dhd_bus_t *)arg;
+	dhd_pub_t *pub = g_pub;
+	osl_t *osh;
+	wifi_adapter_info_t *adapter = NULL;
+
+	adapter = (wifi_adapter_info_t *)pub->adapter;
+
+	if (pub && !pub->dhd_remove && bus == NULL) {
+		DBUSERR(("%s: bus is NULL\n", __FUNCTION__));
+		return;
+	}
+	if (!adapter) {
+		DBUSERR(("%s: adapter is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	printf("%s: Enter dhd_remove=%d on %s\n", __FUNCTION__,
+		pub->dhd_remove, adapter->name);
+	if (!pub->dhd_remove) {
+		/* Advertise bus remove during rmmod */
+		dhd_dbus_advertise_bus_remove(bus->dhd);
+		dbus_detach(pub->bus);
+		pub->bus = NULL;
+		wifi_set_adapter_status(adapter, WIFI_STATUS_BUS_DISCONNECTED);
+		wake_up_interruptible(&adapter->status_event);
+	} else {
+		osh = pub->osh;
+		dhd_detach(pub);
+		if (pub->bus) {
+			dbus_detach(pub->bus);
+			pub->bus = NULL;
+		}
+		dhd_free(pub);
+		g_pub = NULL;
+		net_attached = FALSE;
+		wifi_clr_adapter_status(adapter, WIFI_STATUS_NET_ATTACHED);
+		if (MALLOCED(osh)) {
+			DBUSERR(("%s: MEMORY LEAK %d bytes\n", __FUNCTION__, MALLOCED(osh)));
+		}
+		osl_detach(osh);
+	}
+
+	DBUSTRACE(("%s: Exit\n", __FUNCTION__));
+}
+
+int
+dhd_bus_sleep(dhd_pub_t *dhdp, bool sleep, uint32 *intstatus)
+{
+	wifi_adapter_info_t *adapter = (wifi_adapter_info_t *)dhdp->adapter;
+	s32 timeout = -1;
+	int err = 0;
+
+	timeout = wait_event_interruptible_timeout(adapter->status_event,
+		wifi_get_adapter_status(adapter, WIFI_STATUS_BUS_DISCONNECTED),
+		msecs_to_jiffies(12000));
+	if (timeout <= 0) {
+		err = -1;
+		DBUSERR(("%s: bus disconnected timeout\n", __FUNCTION__));
+	}
+
+	return err;
+}
+
+#ifdef LINUX_EXTERNAL_MODULE_DBUS
+
+static int __init
+bcm_dbus_module_init(void)
+{
+	printf("Inserting bcm_dbus module \n");
+	return 0;
+}
+
+static void __exit
+bcm_dbus_module_exit(void)
+{
+	printf("Removing bcm_dbus module \n");
+	return;
+}
+
+EXPORT_SYMBOL(dbus_pnp_sleep);
+EXPORT_SYMBOL(dhd_bus_register);
+EXPORT_SYMBOL(dbus_get_devinfo);
+#ifdef BCMDBG
+EXPORT_SYMBOL(dbus_hist_dump);
+#endif
+EXPORT_SYMBOL(dbus_detach);
+EXPORT_SYMBOL(dbus_get_attrib);
+EXPORT_SYMBOL(dbus_down);
+EXPORT_SYMBOL(dbus_pnp_resume);
+EXPORT_SYMBOL(dbus_set_config);
+EXPORT_SYMBOL(dbus_flowctrl_rx);
+EXPORT_SYMBOL(dbus_up);
+EXPORT_SYMBOL(dbus_get_device_speed);
+EXPORT_SYMBOL(dbus_send_pkt);
+EXPORT_SYMBOL(dbus_recv_ctl);
+EXPORT_SYMBOL(dbus_attach);
+EXPORT_SYMBOL(dhd_bus_unregister);
+
+MODULE_LICENSE("GPL");
+
+module_init(bcm_dbus_module_init);
+module_exit(bcm_dbus_module_exit);
+
+#endif  /* #ifdef LINUX_EXTERNAL_MODULE_DBUS */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dbus_usb.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dbus_usb.c
@@ -0,0 +1,1099 @@
+/*
+ * Dongle BUS interface for USB, OS independent
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Dual:>>
+ */
+
+/**
+ * @file @brief
+ * This file contains DBUS code that is USB, but not OS specific. DBUS is a Broadcom proprietary
+ * host specific abstraction layer.
+ */
+
+#include <osl.h>
+#include <bcmdefs.h>
+#include <bcmutils.h>
+#include <dbus.h>
+#include <usbrdl.h>
+#include <bcmdevs_legacy.h>
+#include <bcmdevs.h>
+#include <bcmendian.h>
+
+#if defined(BCM_DNGL_EMBEDIMAGE)
+#ifdef EMBED_IMAGE_43526a
+#include "rtecdc_43526a.h"
+#endif /* EMBED_IMAGE_43526a */
+#ifdef EMBED_IMAGE_43526b
+#include "rtecdc_43526b.h"
+#endif /* EMBED_IMAGE_43526b */
+#ifdef EMBED_IMAGE_GENERIC
+#include "rtecdc.h"
+#endif
+#endif /* BCM_DNGL_EMBEDIMAGE */
+
+uint dbus_msglevel = DBUS_ERROR_VAL;
+module_param(dbus_msglevel, int, 0);
+
+#define USB_DLIMAGE_RETRY_TIMEOUT    3000    /* retry Timeout */
+#define USB_SFLASH_DLIMAGE_SPINWAIT  150     /* in unit of ms */
+#define USB_SFLASH_DLIMAGE_LIMIT     2000    /* spinwait limit (ms) */
+#define POSTBOOT_ID                  0xA123  /* ID to detect if dongle has boot up */
+#define USB_RESETCFG_SPINWAIT        1       /* wait after resetcfg (ms) */
+#define USB_DEV_ISBAD(u)             (u->pub->attrib.devid == 0xDEAD)
+#define USB_DLGO_SPINWAIT            100     /* wait after DL_GO (ms) */
+#define TEST_CHIP                    0x4328
+
+/* driver info, initialized when bcmsdh_register is called */
+static dbus_driver_t drvinfo = {NULL, NULL, NULL, NULL};
+
+typedef struct {
+	dbus_pub_t  *pub;
+
+	void        *cbarg;
+	dbus_intf_callbacks_t *cbs;  /** callbacks into higher DBUS level (dbus.c) */
+	dbus_intf_t *drvintf;
+	void        *usbosl_info;
+	uint32      rdlram_base_addr;
+	uint32      rdlram_size;
+} usb_info_t;
+
+/*
+ * Callbacks common to all USB
+ */
+static void dbus_usb_disconnect(void *handle);
+static void dbus_usb_send_irb_timeout(void *handle, dbus_irb_tx_t *txirb);
+static void dbus_usb_send_irb_complete(void *handle, dbus_irb_tx_t *txirb, int status);
+static void dbus_usb_recv_irb_complete(void *handle, dbus_irb_rx_t *rxirb, int status);
+static void dbus_usb_errhandler(void *handle, int err);
+static void dbus_usb_ctl_complete(void *handle, int type, int status);
+static void dbus_usb_state_change(void *handle, int state);
+static struct dbus_irb* dbus_usb_getirb(void *handle, bool send);
+static void dbus_usb_rxerr_indicate(void *handle, bool on);
+#if !defined(BCM_REQUEST_FW)
+static int dbus_usb_resetcfg(usb_info_t *usbinfo);
+#endif
+static int dbus_usb_iovar_op(void *bus, const char *name,
+	void *params, uint plen, void *arg, uint len, bool set);
+static int dbus_iovar_process(usb_info_t* usbinfo, const char *name,
+                 void *params, int plen, void *arg, uint len, bool set);
+static int dbus_usb_doiovar(usb_info_t *bus, const bcm_iovar_t *vi, uint32 actionid,
+	const char *name, void *params, int plen, void *arg, uint len, int val_size);
+static int dhdusb_downloadvars(usb_info_t *bus, void *arg, int len);
+
+static int dbus_usb_dl_writeimage(usb_info_t *usbinfo, uint8 *fw, int fwlen);
+static int dbus_usb_dlstart(void *bus, uint8 *fw, int len);
+static int dbus_usb_dlneeded(void *bus);
+static int dbus_usb_dlrun(void *bus);
+static int dbus_usb_rdl_dwnld_state(usb_info_t *usbinfo);
+
+#ifdef BCM_DNGL_EMBEDIMAGE
+static bool dbus_usb_device_exists(void *bus);
+#endif
+
+/* OS specific */
+extern bool dbus_usbos_dl_cmd(void *info, uint8 cmd, void *buffer, int buflen);
+extern int dbus_usbos_wait(void *info, uint16 ms);
+extern int dbus_write_membytes(usb_info_t *usbinfo, bool set, uint32 address,
+	uint8 *data, uint size);
+extern bool dbus_usbos_dl_send_bulk(void *info, void *buffer, int len);
+extern int dbus_usbos_loopback_tx(void *usbos_info_ptr, int cnt, int size);
+
+/**
+ * These functions are called by the lower DBUS level (dbus_usb_os.c) to notify this DBUS level
+ * (dbus_usb.c) of an event.
+ */
+static dbus_intf_callbacks_t dbus_usb_intf_cbs = {
+	dbus_usb_send_irb_timeout,
+	dbus_usb_send_irb_complete,
+	dbus_usb_recv_irb_complete,
+	dbus_usb_errhandler,
+	dbus_usb_ctl_complete,
+	dbus_usb_state_change,
+	NULL,			/* isr */
+	NULL,			/* dpc */
+	NULL,			/* watchdog */
+	NULL,			/* dbus_if_pktget */
+	NULL, 			/* dbus_if_pktfree */
+	dbus_usb_getirb,
+	dbus_usb_rxerr_indicate
+};
+
+/* IOVar table */
+enum {
+	IOV_SET_DOWNLOAD_STATE = 1,
+	IOV_DBUS_MSGLEVEL,
+	IOV_MEMBYTES,
+	IOV_VARS,
+	IOV_LOOPBACK_TX
+};
+
+const bcm_iovar_t dhdusb_iovars[] = {
+	{"vars",	IOV_VARS,	0,	0, IOVT_BUFFER,	0 },
+	{"dbus_msglevel",	IOV_DBUS_MSGLEVEL,	0,	0, IOVT_UINT32,	0 },
+	{"dwnldstate",	IOV_SET_DOWNLOAD_STATE,	0,	0, IOVT_BOOL,	0 },
+	{"membytes",	IOV_MEMBYTES,	0,	0, IOVT_BUFFER,	2 * sizeof(int) },
+	{"usb_lb_txfer", IOV_LOOPBACK_TX, 0,    0, IOVT_BUFFER,    2 * sizeof(int) },
+	{NULL, 0, 0, 0, 0, 0 }
+};
+
+/*
+ * Need global for probe() and disconnect() since
+ * attach() is not called at probe and detach()
+ * can be called inside disconnect()
+ */
+static dbus_intf_t	*g_dbusintf = NULL;
+static dbus_intf_t	dbus_usb_intf; /** functions called by higher layer DBUS into lower layer */
+
+/*
+ * dbus_intf_t common to all USB
+ * These functions override dbus_usb_<os>.c.
+ */
+static void *dbus_usb_attach(dbus_pub_t *pub, void *cbarg, dbus_intf_callbacks_t *cbs);
+static void dbus_usb_detach(dbus_pub_t *pub, void *info);
+/* : g_usb_info needed for over-ridden functions
+ * since the bus argument is actually from dbus_usb_<os>.c.
+ */
+static void * dbus_usb_probe(uint16 bus_no, uint16 slot, uint32 hdrlen);
+
+/* functions */
+
+/**
+ * As part of DBUS initialization/registration, the higher level DBUS (dbus.c) needs to know what
+ * lower level DBUS functions to call (in both dbus_usb.c and dbus_usb_os.c).
+ */
+static void *
+dbus_usb_probe(uint16 bus_no, uint16 slot, uint32 hdrlen)
+{
+	DBUSTRACE(("%s(): \n", __FUNCTION__));
+	if (drvinfo.probe) {
+		if (g_dbusintf != NULL) {
+			/* First, initialize all lower-level functions as default
+			 * so that dbus.c simply calls directly to dbus_usb_os.c.
+			 */
+			bcopy(g_dbusintf, &dbus_usb_intf, sizeof(dbus_intf_t));
+
+			/* Second, selectively override functions we need, if any. */
+			dbus_usb_intf.attach = dbus_usb_attach;
+			dbus_usb_intf.detach = dbus_usb_detach;
+			dbus_usb_intf.iovar_op = dbus_usb_iovar_op;
+			dbus_usb_intf.dlstart = dbus_usb_dlstart;
+			dbus_usb_intf.dlneeded = dbus_usb_dlneeded;
+			dbus_usb_intf.dlrun = dbus_usb_dlrun;
+#ifdef BCM_DNGL_EMBEDIMAGE
+			dbus_usb_intf.device_exists = dbus_usb_device_exists;
+#endif
+		}
+
+		return drvinfo.probe(bus_no, slot, hdrlen);
+	}
+
+	return NULL;
+}
+
+static int
+dbus_usb_suspend(void *handle)
+{
+	DBUSTRACE(("%s(): \n", __FUNCTION__));
+
+	if (drvinfo.suspend)
+		return drvinfo.suspend(handle);
+
+	return BCME_OK;
+}
+
+static int
+dbus_usb_resume(void *handle)
+{
+	DBUSTRACE(("%s(): \n", __FUNCTION__));
+
+	if (drvinfo.resume)
+		drvinfo.resume(handle);
+
+	return 0;
+}
+
+static dbus_driver_t dhd_usb_dbus = {
+	dbus_usb_probe,
+	dbus_usb_disconnect,
+	dbus_usb_suspend,
+	dbus_usb_resume
+};
+
+/**
+ * On return, *intf contains this or lower-level DBUS functions to be called by higher
+ * level (dbus.c)
+ */
+int
+dbus_bus_register(dbus_driver_t *driver, dbus_intf_t **intf)
+{
+	int err;
+
+	DBUSTRACE(("%s(): \n", __FUNCTION__));
+	drvinfo = *driver;
+	*intf = &dbus_usb_intf;
+
+	err = dbus_bus_osl_register(&dhd_usb_dbus, &g_dbusintf);
+
+	ASSERT(g_dbusintf);
+	return err;
+}
+
+int
+dbus_bus_deregister()
+{
+	DBUSTRACE(("%s(): \n", __FUNCTION__));
+	return dbus_bus_osl_deregister();
+}
+
+/** initialization consists of registration followed by 'attach'. */
+void *
+dbus_usb_attach(dbus_pub_t *pub, void *cbarg, dbus_intf_callbacks_t *cbs)
+{
+	usb_info_t *usb_info;
+
+	DBUSTRACE(("%s(): \n", __FUNCTION__));
+
+	if ((g_dbusintf == NULL) || (g_dbusintf->attach == NULL))
+		return NULL;
+
+	/* Sanity check for BUS_INFO() */
+	ASSERT(OFFSETOF(usb_info_t, pub) == 0);
+
+	usb_info = MALLOC(pub->osh, sizeof(usb_info_t));
+	if (usb_info == NULL)
+		return NULL;
+
+	bzero(usb_info, sizeof(usb_info_t));
+
+	usb_info->pub = pub;
+	usb_info->cbarg = cbarg;
+	usb_info->cbs = cbs;
+
+	usb_info->usbosl_info = (dbus_pub_t *)g_dbusintf->attach(pub,
+		usb_info, &dbus_usb_intf_cbs);
+	if (usb_info->usbosl_info == NULL) {
+		MFREE(pub->osh, usb_info, sizeof(usb_info_t));
+		return NULL;
+	}
+
+	/* Save USB OS-specific driver entry points */
+	usb_info->drvintf = g_dbusintf;
+
+	pub->bus = usb_info;
+#if !defined(BCM_REQUEST_FW)
+	if (!dbus_usb_resetcfg(usb_info)) {
+		usb_info->pub->busstate = DBUS_STATE_DL_DONE;
+	}
+#endif
+	/* Return Lower layer info */
+	return (void *) usb_info->usbosl_info;
+}
+
+void
+dbus_usb_detach(dbus_pub_t *pub, void *info)
+{
+	usb_info_t *usb_info = (usb_info_t *) pub->bus;
+	osl_t *osh = pub->osh;
+
+	if (usb_info == NULL)
+		return;
+
+	if (usb_info->drvintf && usb_info->drvintf->detach)
+		usb_info->drvintf->detach(pub, usb_info->usbosl_info);
+
+	MFREE(osh, usb_info, sizeof(usb_info_t));
+}
+
+void
+dbus_usb_disconnect(void *handle)
+{
+	DBUSTRACE(("%s(): \n", __FUNCTION__));
+	if (drvinfo.remove)
+		drvinfo.remove(handle);
+}
+
+/**
+ * When the lower DBUS level (dbus_usb_os.c) signals this event, the higher DBUS level has to be
+ * notified.
+ */
+static void
+dbus_usb_send_irb_timeout(void *handle, dbus_irb_tx_t *txirb)
+{
+	usb_info_t *usb_info = (usb_info_t *) handle;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (usb_info == NULL)
+		return;
+
+	if (usb_info->cbs && usb_info->cbs->send_irb_timeout)
+		usb_info->cbs->send_irb_timeout(usb_info->cbarg, txirb);
+}
+
+/**
+ * When the lower DBUS level (dbus_usb_os.c) signals this event, the higher DBUS level has to be
+ * notified.
+ */
+static void
+dbus_usb_send_irb_complete(void *handle, dbus_irb_tx_t *txirb, int status)
+{
+	usb_info_t *usb_info = (usb_info_t *) handle;
+
+	if (usb_info == NULL)
+		return;
+
+	if (usb_info->cbs && usb_info->cbs->send_irb_complete)
+		usb_info->cbs->send_irb_complete(usb_info->cbarg, txirb, status);
+}
+
+/**
+ * When the lower DBUS level (dbus_usb_os.c) signals this event, the higher DBUS level has to be
+ * notified.
+ */
+static void
+dbus_usb_recv_irb_complete(void *handle, dbus_irb_rx_t *rxirb, int status)
+{
+	usb_info_t *usb_info = (usb_info_t *) handle;
+
+	if (usb_info == NULL)
+		return;
+
+	if (usb_info->cbs && usb_info->cbs->recv_irb_complete)
+		usb_info->cbs->recv_irb_complete(usb_info->cbarg, rxirb, status);
+}
+
+/** Lower DBUS level (dbus_usb_os.c) requests a free IRB. Pass this on to the higher DBUS level. */
+static struct dbus_irb*
+dbus_usb_getirb(void *handle, bool send)
+{
+	usb_info_t *usb_info = (usb_info_t *) handle;
+
+	if (usb_info == NULL)
+		return NULL;
+
+	if (usb_info->cbs && usb_info->cbs->getirb)
+		return usb_info->cbs->getirb(usb_info->cbarg, send);
+
+	return NULL;
+}
+
+/**
+ * When the lower DBUS level (dbus_usb_os.c) signals this event, the higher DBUS level has to be
+ * notified.
+ */
+static void
+dbus_usb_rxerr_indicate(void *handle, bool on)
+{
+	usb_info_t *usb_info = (usb_info_t *) handle;
+
+	if (usb_info == NULL)
+		return;
+
+	if (usb_info->cbs && usb_info->cbs->rxerr_indicate)
+		usb_info->cbs->rxerr_indicate(usb_info->cbarg, on);
+}
+
+/**
+ * When the lower DBUS level (dbus_usb_os.c) signals this event, the higher DBUS level has to be
+ * notified.
+ */
+static void
+dbus_usb_errhandler(void *handle, int err)
+{
+	usb_info_t *usb_info = (usb_info_t *) handle;
+
+	if (usb_info == NULL)
+		return;
+
+	if (usb_info->cbs && usb_info->cbs->errhandler)
+		usb_info->cbs->errhandler(usb_info->cbarg, err);
+}
+
+/**
+ * When the lower DBUS level (dbus_usb_os.c) signals this event, the higher DBUS level has to be
+ * notified.
+ */
+static void
+dbus_usb_ctl_complete(void *handle, int type, int status)
+{
+	usb_info_t *usb_info = (usb_info_t *) handle;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (usb_info == NULL) {
+		DBUSERR(("%s: usb_info is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	if (usb_info->cbs && usb_info->cbs->ctl_complete)
+		usb_info->cbs->ctl_complete(usb_info->cbarg, type, status);
+}
+
+/**
+ * When the lower DBUS level (dbus_usb_os.c) signals this event, the higher DBUS level has to be
+ * notified.
+ */
+static void
+dbus_usb_state_change(void *handle, int state)
+{
+	usb_info_t *usb_info = (usb_info_t *) handle;
+
+	if (usb_info == NULL)
+		return;
+
+	if (usb_info->cbs && usb_info->cbs->state_change)
+		usb_info->cbs->state_change(usb_info->cbarg, state);
+}
+
+/** called by higher DBUS level (dbus.c) */
+static int
+dbus_usb_iovar_op(void *bus, const char *name,
+	void *params, uint plen, void *arg, uint len, bool set)
+{
+	int err = DBUS_OK;
+
+	err = dbus_iovar_process((usb_info_t*)bus, name, params, plen, arg, len, set);
+	return err;
+}
+
+/** process iovar request from higher DBUS level */
+static int
+dbus_iovar_process(usb_info_t* usbinfo, const char *name,
+                 void *params, int plen, void *arg, uint len, bool set)
+{
+	const bcm_iovar_t *vi = NULL;
+	int bcmerror = 0;
+	int val_size;
+	uint32 actionid;
+
+	DBUSTRACE(("%s: Enter\n", __FUNCTION__));
+
+	ASSERT(name);
+
+	/* Get MUST have return space */
+	ASSERT(set || (arg && len));
+
+	/* Set does NOT take qualifiers */
+	ASSERT(!set || (!params && !plen));
+
+	/* Look up var locally; if not found pass to host driver */
+	if ((vi = bcm_iovar_lookup(dhdusb_iovars, name)) == NULL) {
+		/* Not Supported */
+		bcmerror = BCME_UNSUPPORTED;
+		DBUSTRACE(("%s: IOVAR %s is not supported\n", name, __FUNCTION__));
+		goto exit;
+
+	}
+
+	DBUSTRACE(("%s: %s %s, len %d plen %d\n", __FUNCTION__,
+	         name, (set ? "set" : "get"), len, plen));
+
+	/* set up 'params' pointer in case this is a set command so that
+	 * the convenience int and bool code can be common to set and get
+	 */
+	if (params == NULL) {
+		params = arg;
+		plen = len;
+	}
+
+	if (vi->type == IOVT_VOID)
+		val_size = 0;
+	else if (vi->type == IOVT_BUFFER)
+		val_size = len;
+	else
+		/* all other types are integer sized */
+		val_size = sizeof(int);
+
+	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+	bcmerror = dbus_usb_doiovar(usbinfo, vi, actionid,
+		name, params, plen, arg, len, val_size);
+
+exit:
+	return bcmerror;
+} /* dbus_iovar_process */
+
+static int
+dbus_usb_doiovar(usb_info_t *bus, const bcm_iovar_t *vi, uint32 actionid, const char *name,
+                void *params, int plen, void *arg, uint len, int val_size)
+{
+	int bcmerror = 0;
+	int32 int_val = 0;
+	int32 int_val2 = 0;
+	bool bool_val = 0;
+
+	DBUSTRACE(("%s: Enter, action %d name %s params %p plen %d arg %p len %d val_size %d\n",
+	           __FUNCTION__, actionid, name, params, plen, arg, len, val_size));
+
+	if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid))) != 0)
+		goto exit;
+
+	if (plen >= (int)sizeof(int_val))
+		bcopy(params, &int_val, sizeof(int_val));
+
+	if (plen >= (int)sizeof(int_val) * 2)
+		bcopy((void*)((uintptr)params + sizeof(int_val)), &int_val2, sizeof(int_val2));
+
+	bool_val = (int_val != 0) ? TRUE : FALSE;
+
+	switch (actionid) {
+
+	case IOV_SVAL(IOV_MEMBYTES):
+	case IOV_GVAL(IOV_MEMBYTES):
+	{
+		uint32 address;
+		uint size, dsize;
+		uint8 *data;
+
+		bool set = (actionid == IOV_SVAL(IOV_MEMBYTES));
+
+		ASSERT(plen >= 2*sizeof(int));
+
+		address = (uint32)int_val;
+		BCM_REFERENCE(address);
+		bcopy((char *)params + sizeof(int_val), &int_val, sizeof(int_val));
+		size = (uint)int_val;
+
+		/* Do some validation */
+		dsize = set ? plen - (2 * sizeof(int)) : len;
+		if (dsize < size) {
+			DBUSTRACE(("%s: error on %s membytes, addr 0x%08x size %d dsize %d\n",
+			           __FUNCTION__, (set ? "set" : "get"), address, size, dsize));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		DBUSTRACE(("%s: Request to %s %d bytes at address 0x%08x\n", __FUNCTION__,
+		          (set ? "write" : "read"), size, address));
+
+		/* Generate the actual data pointer */
+		data = set ? (uint8*)params + 2 * sizeof(int): (uint8*)arg;
+
+		/* Call to do the transfer */
+		bcmerror = dbus_usb_dl_writeimage(BUS_INFO(bus, usb_info_t), data, size);
+	}
+		break;
+
+	case IOV_SVAL(IOV_SET_DOWNLOAD_STATE):
+
+		if (bool_val == TRUE) {
+			bcmerror = dbus_usb_dlneeded(bus);
+			dbus_usb_rdl_dwnld_state(BUS_INFO(bus, usb_info_t));
+		} else {
+			usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t);
+			bcmerror = dbus_usb_dlrun(bus);
+			usbinfo->pub->busstate = DBUS_STATE_DL_DONE;
+		}
+		break;
+
+	case IOV_SVAL(IOV_VARS):
+		bcmerror = dhdusb_downloadvars(BUS_INFO(bus, usb_info_t), arg, len);
+		break;
+
+	case IOV_GVAL(IOV_DBUS_MSGLEVEL):
+		int_val = (int32)dbus_msglevel;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_DBUS_MSGLEVEL):
+		dbus_msglevel = int_val;
+		break;
+
+#ifdef DBUS_USB_LOOPBACK
+	case IOV_SVAL(IOV_LOOPBACK_TX):
+			bcmerror = dbus_usbos_loopback_tx(BUS_INFO(bus, usb_info_t), int_val,
+			  int_val2);
+			break;
+#endif
+	default:
+		bcmerror = BCME_UNSUPPORTED;
+		break;
+	}
+
+exit:
+	return bcmerror;
+} /* dbus_usb_doiovar */
+
+/** higher DBUS level (dbus.c) wants to set NVRAM variables in dongle */
+static int
+dhdusb_downloadvars(usb_info_t *bus, void *arg, int len)
+{
+	int bcmerror = 0;
+	uint32 varsize;
+	uint32 varaddr;
+	uint32 varsizew;
+
+	if (!len) {
+		bcmerror = BCME_BUFTOOSHORT;
+		goto err;
+	}
+
+	/* RAM size is not set. Set it at dbus_usb_dlneeded */
+	if (!bus->rdlram_size)
+		bcmerror = BCME_ERROR;
+
+	/* Even if there are no vars are to be written, we still need to set the ramsize. */
+	varsize = len ? ROUNDUP(len, 4) : 0;
+	varaddr = (bus->rdlram_size - 4) - varsize;
+
+	/* Write the vars list */
+	DBUSTRACE(("WriteVars: @%x varsize=%d\n", varaddr, varsize));
+	bcmerror = dbus_write_membytes(bus->usbosl_info, TRUE, (varaddr + bus->rdlram_base_addr),
+		arg, varsize);
+
+	/* adjust to the user specified RAM */
+	DBUSTRACE(("Usable memory size: %d\n", bus->rdlram_size));
+	DBUSTRACE(("Vars are at %d, orig varsize is %d\n", varaddr, varsize));
+
+	varsize = ((bus->rdlram_size - 4) - varaddr);
+
+	/*
+	 * Determine the length token:
+	 * Varsize, converted to words, in lower 16-bits, checksum in upper 16-bits.
+	 */
+	if (bcmerror) {
+		varsizew = 0;
+	} else {
+		varsizew = varsize / 4;
+		varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
+		varsizew = htol32(varsizew);
+	}
+
+	DBUSTRACE(("New varsize is %d, length token=0x%08x\n", varsize, varsizew));
+
+	/* Write the length token to the last word */
+	bcmerror = dbus_write_membytes(bus->usbosl_info, TRUE, ((bus->rdlram_size - 4) +
+		bus->rdlram_base_addr), (uint8*)&varsizew, 4);
+err:
+	return bcmerror;
+} /* dbus_usb_doiovar */
+
+#if !defined(BCM_REQUEST_FW)
+/**
+ * After downloading firmware into dongle and starting it, we need to know if the firmware is
+ * indeed up and running.
+ */
+static int
+dbus_usb_resetcfg(usb_info_t *usbinfo)
+{
+	void *osinfo;
+	bootrom_id_t id;
+	uint16 waittime = 0;
+
+	uint32 starttime = 0;
+	uint32 endtime = 0;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (usbinfo == NULL)
+		return DBUS_ERR;
+
+	osinfo = usbinfo->usbosl_info;
+	ASSERT(osinfo);
+
+	/* Give dongle chance to boot */
+	dbus_usbos_wait(osinfo, USB_SFLASH_DLIMAGE_SPINWAIT);
+	waittime = USB_SFLASH_DLIMAGE_SPINWAIT;
+	while (waittime < USB_DLIMAGE_RETRY_TIMEOUT) {
+
+		starttime = OSL_SYSUPTIME();
+
+		id.chip = 0xDEAD;       /* Get the ID */
+		dbus_usbos_dl_cmd(osinfo, DL_GETVER, &id, sizeof(bootrom_id_t));
+		id.chip = ltoh32(id.chip);
+
+		endtime = OSL_SYSUPTIME();
+		waittime += (endtime - starttime);
+
+		if (id.chip == POSTBOOT_ID)
+			break;
+	}
+
+	if (id.chip == POSTBOOT_ID) {
+		DBUSERR(("%s: download done. Bootup time = %d ms postboot chip 0x%x/rev 0x%x\n",
+			__FUNCTION__, waittime, id.chip, id.chiprev));
+
+		dbus_usbos_dl_cmd(osinfo, DL_RESETCFG, &id, sizeof(bootrom_id_t));
+
+		/* this wait may not be necessary */
+		dbus_usbos_wait(osinfo, USB_RESETCFG_SPINWAIT);
+		return DBUS_OK;
+	} else {
+		DBUSERR(("%s: Cannot talk to Dongle. Wait time = %d ms. Firmware is not UP \n",
+			__FUNCTION__, waittime));
+		return DBUS_ERR;
+	}
+
+	return DBUS_OK;
+}
+#endif
+
+/** before firmware download, the dongle has to be prepared to receive the fw image */
+static int
+dbus_usb_rdl_dwnld_state(usb_info_t *usbinfo)
+{
+	void *osinfo = usbinfo->usbosl_info;
+	rdl_state_t state;
+	int err = DBUS_OK;
+
+	/* 1) Prepare USB boot loader for runtime image */
+	dbus_usbos_dl_cmd(osinfo, DL_START, &state, sizeof(rdl_state_t));
+
+	state.state = ltoh32(state.state);
+	state.bytes = ltoh32(state.bytes);
+
+	/* 2) Check we are in the Waiting state */
+	if (state.state != DL_WAITING) {
+		DBUSERR(("%s: Failed to DL_START\n", __FUNCTION__));
+		err = DBUS_ERR;
+		goto fail;
+	}
+
+fail:
+	return err;
+}
+
+/**
+ * Dongle contains bootcode in ROM but firmware is (partially) contained in dongle RAM. Therefore,
+ * firmware has to be downloaded into dongle RAM.
+ */
+static int
+dbus_usb_dl_writeimage(usb_info_t *usbinfo, uint8 *fw, int fwlen)
+{
+	osl_t *osh = usbinfo->pub->osh;
+	void *osinfo = usbinfo->usbosl_info;
+	unsigned int sendlen, sent, dllen;
+	char *bulkchunk = NULL, *dlpos;
+	rdl_state_t state;
+	int err = DBUS_OK;
+	uint32 dl_trunk_size = RDL_CHUNK;
+
+	while (!bulkchunk) {
+		bulkchunk = MALLOC(osh, dl_trunk_size);
+		if (dl_trunk_size == RDL_CHUNK)
+			break;
+		if (!bulkchunk) {
+			dl_trunk_size /= 2;
+			if (dl_trunk_size < RDL_CHUNK)
+				dl_trunk_size = RDL_CHUNK;
+		}
+	}
+
+	if (bulkchunk == NULL) {
+		err = DBUS_ERR;
+		goto fail;
+	}
+
+	sent = 0;
+	dlpos = fw;
+	dllen = fwlen;
+
+	DBUSTRACE(("enter %s: fwlen=%d\n", __FUNCTION__, fwlen));
+
+	dbus_usbos_dl_cmd(osinfo, DL_GETSTATE, &state, sizeof(rdl_state_t));
+
+	/* 3) Load the image */
+	while ((sent < dllen)) {
+		/* Wait until the usb device reports it received all the bytes we sent */
+
+		/* add a timeout so we dont wait indefinetly */
+		if (sent < dllen) {
+			if ((dllen-sent) < dl_trunk_size)
+				sendlen = dllen-sent;
+			else
+				sendlen = dl_trunk_size;
+
+			/* simply avoid having to send a ZLP by ensuring we never have an even
+			 * multiple of 64
+			 */
+			if (!(sendlen % 64))
+				sendlen -= 4;
+
+			/* send data */
+			memcpy(bulkchunk, dlpos, sendlen);
+			if (!dbus_usbos_dl_send_bulk(osinfo, bulkchunk, sendlen)) {
+				err = DBUS_ERR;
+				goto fail;
+			}
+
+			dlpos += sendlen;
+			sent += sendlen;
+			DBUSTRACE(("%s: sendlen %d\n", __FUNCTION__, sendlen));
+		}
+
+		/* Wait for downloaded image crc check to complete in the dongle */
+		while (!dbus_usbos_dl_cmd(osinfo, DL_GETSTATE, &state, sizeof(rdl_state_t))) {
+			DBUSERR(("%s: DL_GETSTATE Failed xxxx\n", __FUNCTION__));
+			err = DBUS_ERR;
+			goto fail;
+		}
+
+		state.state = ltoh32(state.state);
+		state.bytes = ltoh32(state.bytes);
+
+		/* restart if an error is reported */
+		if ((state.state == DL_BAD_HDR) || (state.state == DL_BAD_CRC)) {
+			DBUSERR(("%s: Bad Hdr or Bad CRC\n", __FUNCTION__));
+			err = DBUS_ERR;
+			goto fail;
+		}
+
+	}
+fail:
+	if (bulkchunk)
+		MFREE(osh, bulkchunk, dl_trunk_size);
+
+	return err;
+} /* dbus_usb_dl_writeimage */
+
+/** Higher level DBUS layer (dbus.c) requests this layer to download image into dongle */
+static int
+dbus_usb_dlstart(void *bus, uint8 *fw, int len)
+{
+	usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t);
+	int err;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (usbinfo == NULL)
+		return DBUS_ERR;
+
+	if (USB_DEV_ISBAD(usbinfo))
+		return DBUS_ERR;
+
+	err = dbus_usb_rdl_dwnld_state(usbinfo);
+
+	if (DBUS_OK == err) {
+		err = dbus_usb_dl_writeimage(usbinfo, fw, len);
+		if (err == DBUS_OK)
+			usbinfo->pub->busstate = DBUS_STATE_DL_DONE;
+		else
+			usbinfo->pub->busstate = DBUS_STATE_DL_PENDING;
+	} else
+		usbinfo->pub->busstate = DBUS_STATE_DL_PENDING;
+
+	return err;
+}
+
+static bool
+dbus_usb_update_chipinfo(usb_info_t *usbinfo, uint32 chip)
+{
+	bool retval = TRUE;
+	/* based on the CHIP Id, store the ram size which is needed for NVRAM download. */
+	switch (chip) {
+		case 0x4360:
+		case 0xAA06:
+			usbinfo->rdlram_size = RDL_RAM_SIZE_4360;
+			usbinfo->rdlram_base_addr = RDL_RAM_BASE_4360;
+			break;
+		case 43569:
+			usbinfo->rdlram_size = RDL_RAM_SIZE_4350;
+			usbinfo->rdlram_base_addr = RDL_RAM_BASE_4350;
+			break;
+		case BCM4381_CHIP_ID:
+			usbinfo->rdlram_size = RDL_RAM_SIZE_4381;
+			usbinfo->rdlram_base_addr = RDL_RAM_BASE_4381;
+			break;
+
+		case BCM4382_CHIP_ID:
+			usbinfo->rdlram_size = RDL_RAM_SIZE_4382;
+			usbinfo->rdlram_base_addr = RDL_RAM_BASE_4382;
+			break;
+
+		case POSTBOOT_ID:
+			break;
+
+		default:
+			DBUSERR(("%s: Chip 0x%x Ram size is not known\n", __FUNCTION__, chip));
+			retval = FALSE;
+			break;
+
+	}
+
+	return retval;
+} /* dbus_usb_update_chipinfo */
+
+/** higher DBUS level (dbus.c) wants to know if firmware download is required. */
+static int
+dbus_usb_dlneeded(void *bus)
+{
+	usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t);
+	void *osinfo;
+	bootrom_id_t id;
+	int dl_needed = 1;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (usbinfo == NULL)
+		return DBUS_ERR;
+
+	osinfo = usbinfo->usbosl_info;
+	ASSERT(osinfo);
+
+	/* Check if firmware downloaded already by querying runtime ID */
+	id.chip = 0xDEAD;
+	dbus_usbos_dl_cmd(osinfo, DL_GETVER, &id, sizeof(bootrom_id_t));
+
+	id.chip = ltoh32(id.chip);
+	id.chiprev = ltoh32(id.chiprev);
+
+	if (FALSE == dbus_usb_update_chipinfo(usbinfo, id.chip)) {
+		dl_needed = DBUS_ERR;
+		goto exit;
+	}
+
+	DBUSERR(("%s: chip 0x%x rev 0x%x\n", __FUNCTION__, id.chip, id.chiprev));
+	if (id.chip == POSTBOOT_ID) {
+		/* This code is  needed to support two enumerations on USB1.1 scenario */
+		DBUSERR(("%s: Firmware already downloaded\n", __FUNCTION__));
+
+		dbus_usbos_dl_cmd(osinfo, DL_RESETCFG, &id, sizeof(bootrom_id_t));
+		dl_needed = DBUS_OK;
+		if (usbinfo->pub->busstate == DBUS_STATE_DL_PENDING)
+			usbinfo->pub->busstate = DBUS_STATE_DL_DONE;
+	} else {
+		usbinfo->pub->attrib.devid = id.chip;
+		usbinfo->pub->attrib.chiprev = id.chiprev;
+	}
+
+exit:
+	return dl_needed;
+}
+
+/** After issuing firmware download, higher DBUS level (dbus.c) wants to start the firmware. */
+static int
+dbus_usb_dlrun(void *bus)
+{
+	usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t);
+	void *osinfo;
+	rdl_state_t state;
+	int err = DBUS_OK;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (usbinfo == NULL)
+		return DBUS_ERR;
+
+	if (USB_DEV_ISBAD(usbinfo))
+		return DBUS_ERR;
+
+	osinfo = usbinfo->usbosl_info;
+	ASSERT(osinfo);
+
+	/* Check we are runnable */
+	dbus_usbos_dl_cmd(osinfo, DL_GETSTATE, &state, sizeof(rdl_state_t));
+
+	state.state = ltoh32(state.state);
+	state.bytes = ltoh32(state.bytes);
+
+	/* Start the image */
+	if (state.state == DL_RUNNABLE) {
+		DBUSTRACE(("%s: Issue DL_GO\n", __FUNCTION__));
+		dbus_usbos_dl_cmd(osinfo, DL_GO, &state, sizeof(rdl_state_t));
+
+		/* : Need this for 4326 for some reason
+		 * Same issue under both Linux/Windows
+		 */
+		if (usbinfo->pub->attrib.devid == TEST_CHIP)
+			dbus_usbos_wait(osinfo, USB_DLGO_SPINWAIT);
+
+//		dbus_usb_resetcfg(usbinfo);
+		/* The Donlge may go for re-enumeration. */
+	} else {
+		DBUSERR(("%s: Dongle not runnable\n", __FUNCTION__));
+		err = DBUS_ERR;
+	}
+
+	return err;
+}
+
+/**
+ * As preparation for firmware download, higher DBUS level (dbus.c) requests the firmware image
+ * to be used for the type of dongle detected. Directly called by dbus.c (so not via a callback
+ * construction)
+ */
+void
+dbus_bus_fw_get(void *bus, uint8 **fw, int *fwlen, int *decomp)
+{
+	usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t);
+	unsigned int devid;
+	unsigned int crev;
+
+	devid = usbinfo->pub->attrib.devid;
+	crev = usbinfo->pub->attrib.chiprev;
+	BCM_REFERENCE(crev);
+
+	*fw = NULL;
+	*fwlen = 0;
+
+	switch (devid) {
+	default:
+#ifdef EMBED_IMAGE_GENERIC
+		*fw = (uint8 *)dlarray;
+		*fwlen = sizeof(dlarray);
+#endif
+		break;
+	}
+} /* dbus_bus_fw_get */
+
+#ifdef BCM_DNGL_EMBEDIMAGE
+static bool
+dbus_usb_device_exists(void *bus)
+{
+	usb_info_t *usbinfo = BUS_INFO(bus, usb_info_t);
+	void *osinfo;
+	bootrom_id_t id;
+
+	DBUSTRACE(("%s\n", __FUNCTION__));
+
+	if (usbinfo == NULL)
+		return FALSE;
+
+	osinfo = usbinfo->usbosl_info;
+	ASSERT(osinfo);
+
+	id.chip = 0xDEAD;
+	/* Query device to see if we get a response */
+	dbus_usbos_dl_cmd(osinfo, DL_GETVER, &id, sizeof(bootrom_id_t));
+
+	usbinfo->pub->attrib.devid = id.chip;
+	if (id.chip == 0xDEAD)
+		return FALSE;
+	else
+		return TRUE;
+}
+#endif /* BCM_DNGL_EMBEDIMAGE */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dbus_usb_linux.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dbus_usb_linux.c
@@ -0,0 +1,4823 @@
+/*
+ * Dongle BUS interface
+ * USB Linux Implementation
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Dual:>>
+ */
+
+/**
+ * @file @brief
+ * This file contains DBUS code that is USB *and* OS (Linux) specific. DBUS is a Broadcom
+ * proprietary host specific abstraction layer.
+ */
+
+#include <typedefs.h>
+#include <osl.h>
+
+/**
+ * DBUS_LINUX_RXDPC is created for router platform performance tuning. A separate thread is created
+ * to handle USB RX and avoid the call chain getting too long and enhance cache hit rate.
+ *
+ * DBUS_LINUX_RXDPC setting is in wlconfig file.
+ */
+
+/*
+ * If DBUS_LINUX_RXDPC is off, spin_lock_bh() for CTFPOOL in
+ * linux_osl.c has to be changed to spin_lock_irqsave() because
+ * PKTGET/PKTFREE are no longer in bottom half.
+ *
+ * Right now we have another queue rpcq in wl_linux.c. Maybe we
+ * can eliminate that one to reduce the overhead.
+ *
+ * Enabling 2nd EP and DBUS_LINUX_RXDPC causing traffic from
+ * both EP's to be queued in the same rx queue. If we want
+ * RXDPC to work with 2nd EP. The EP for RPC call return
+ * should bypass the dpc and go directly up.
+ */
+
+/* #define DBUS_LINUX_RXDPC */
+
+/* Dbus histogram for ntxq, nrxq, dpc parameter tuning */
+/* #define DBUS_LINUX_HIST */
+
+#include <usbrdl.h>
+#include <bcmendian.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+#include <dbus.h>
+#include <bcmutils.h>
+#include <bcmdevs_legacy.h>
+#include <bcmdevs.h>
+#include <linux/usb.h>
+#include <usbrdl.h>
+#include <linux/firmware.h>
+#ifdef DBUS_LINUX_RXDPC
+#include <linux/sched.h>
+#endif
+#include <dngl_stats.h>
+#include <dhd.h>
+
+#if defined(USBOS_THREAD) || defined(USBOS_TX_THREAD)
+
+/**
+ * The usb-thread is designed to provide currency on multiprocessors and SMP linux kernels. On the
+ * dual cores platform, the WLAN driver, without threads, executed only on CPU0. The driver consumed
+ * almost of 100% on CPU0, while CPU1 remained idle. The behavior was observed on Broadcom's STB.
+ *
+ * The WLAN driver consumed most of CPU0 and not CPU1 because tasklets/queues, software irq, and
+ * hardware irq are executing from CPU0, only. CPU0 became the system's bottle-neck. TPUT is lower
+ * and system's responsiveness is slower.
+ *
+ * To improve system responsiveness and TPUT usb-thread was implemented. The system's threads could
+ * be scheduled to run on any core. One core could be processing data in the usb-layer and the other
+ * core could be processing data in the wl-layer.
+ */
+
+#include <linux/kthread.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/hardirq.h>
+#include <linux/list.h>
+#include <linux_osl.h>
+#endif /* USBOS_THREAD || USBOS_TX_THREAD */
+
+#ifdef DBUS_LINUX_RXDPC
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+#define RESCHED()   _cond_resched()
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+#define RESCHED()   cond_resched()
+#else
+#define RESCHED()   __cond_resched()
+#endif /* LINUX_VERSION_CODE  */
+#endif	/* DBUS_LINUX_RXDPC */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+#define KERNEL26
+#endif
+
+/**
+ * Starting with the 3.10 kernel release, dynamic PM support for USB is present whenever
+ * the kernel was built with CONFIG_PM_RUNTIME enabled. The CONFIG_USB_SUSPEND option has
+ * been eliminated.
+ */
+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21)) && defined(CONFIG_USB_SUSPEND)) ||\
+	((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)) && defined(CONFIG_PM_RUNTIME)) ||\
+	(LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
+/* For USB power management support, see Linux kernel: Documentation/usb/power-management.txt */
+#define USB_SUSPEND_AVAILABLE
+#endif
+
+static inline int usb_submit_urb_linux(struct urb *urb)
+{
+
+#ifdef BCM_MAX_URB_LEN
+	if (urb && (urb->transfer_buffer_length > BCM_MAX_URB_LEN)) {
+		DBUSERR(("URB transfer length=%d exceeded %d ra=%p\n", urb->transfer_buffer_length,
+		BCM_MAX_URB_LEN, CALL_SITE));
+		return DBUS_ERR;
+	}
+#endif
+
+#ifdef KERNEL26
+	return usb_submit_urb(urb, GFP_ATOMIC);
+#else
+	return usb_submit_urb(urb);
+#endif
+
+}
+
+#define USB_SUBMIT_URB(urb) usb_submit_urb_linux(urb)
+
+#ifdef KERNEL26
+
+#define USB_ALLOC_URB()				usb_alloc_urb(0, GFP_ATOMIC)
+#define USB_UNLINK_URB(urb)			(usb_kill_urb(urb))
+#define USB_FREE_URB(urb)			(usb_free_urb(urb))
+#define USB_REGISTER()				usb_register(&dbus_usbdev)
+#define USB_DEREGISTER()			usb_deregister(&dbus_usbdev)
+
+#ifdef USB_SUSPEND_AVAILABLE
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33))
+#define USB_AUTOPM_SET_INTERFACE(intf)		usb_autopm_set_interface(intf)
+#else
+#define USB_ENABLE_AUTOSUSPEND(udev)		usb_enable_autosuspend(udev)
+#define USB_DISABLE_AUTOSUSPEND(udev)       usb_disable_autosuspend(udev)
+#endif  /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33))  */
+
+#define USB_AUTOPM_GET_INTERFACE(intf)		usb_autopm_get_interface(intf)
+#define USB_AUTOPM_PUT_INTERFACE(intf)		usb_autopm_put_interface(intf)
+#define USB_AUTOPM_GET_INTERFACE_ASYNC(intf)	usb_autopm_get_interface_async(intf)
+#define USB_AUTOPM_PUT_INTERFACE_ASYNC(intf)	usb_autopm_put_interface_async(intf)
+#define USB_MARK_LAST_BUSY(dev)			usb_mark_last_busy(dev)
+
+#else /* USB_SUSPEND_AVAILABLE */
+
+#define USB_AUTOPM_GET_INTERFACE(intf)		do {} while (0)
+#define USB_AUTOPM_PUT_INTERFACE(intf)		do {} while (0)
+#define USB_AUTOPM_GET_INTERFACE_ASYNC(intf)	do {} while (0)
+#define USB_AUTOPM_PUT_INTERFACE_ASYNC(intf)	do {} while (0)
+#define USB_MARK_LAST_BUSY(dev)			do {} while (0)
+#endif /* USB_SUSPEND_AVAILABLE */
+
+#define USB_CONTROL_MSG(dev, pipe, request, requesttype, value, index, data, size, timeout) \
+	usb_control_msg((dev), (pipe), (request), (requesttype), (value), (index), \
+	(data), (size), (timeout))
+#define USB_BULK_MSG(dev, pipe, data, len, actual_length, timeout) \
+	usb_bulk_msg((dev), (pipe), (data), (len), (actual_length), (timeout))
+#define USB_BUFFER_ALLOC(dev, size, mem, dma)	usb_buffer_alloc(dev, size, mem, dma)
+#define USB_BUFFER_FREE(dev, size, data, dma)	usb_buffer_free(dev, size, data, dma)
+
+#ifdef WL_URB_ZPKT
+#define URB_QUEUE_BULK   URB_ZERO_PACKET
+#else
+#define URB_QUEUE_BULK   0
+#endif /* WL_URB_ZPKT */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0))
+#define CALLBACK_ARGS		struct urb *urb
+#define CALLBACK_ARGS_DATA	urb
+#else
+#define CALLBACK_ARGS		struct urb *urb, struct pt_regs *regs
+#define CALLBACK_ARGS_DATA	urb, regs
+#endif /* 5.18 */
+
+#define CONFIGDESC(usb)		(&((usb)->actconfig)->desc)
+#define IFPTR(usb, idx)		((usb)->actconfig->interface[idx])
+#define IFALTS(usb, idx)	(IFPTR((usb), (idx))->altsetting[0])
+#define IFDESC(usb, idx)	IFALTS((usb), (idx)).desc
+#define IFEPDESC(usb, idx, ep)	(IFALTS((usb), (idx)).endpoint[ep]).desc
+#ifdef DBUS_LINUX_RXDPC
+#define DAEMONIZE(a)		daemonize(a); allow_signal(SIGKILL); allow_signal(SIGTERM);
+#define SET_NICE(n)		set_user_nice(current, n)
+#endif
+
+#else /* KERNEL26 */
+
+#define USB_ALLOC_URB()				usb_alloc_urb(0)
+#define USB_UNLINK_URB(urb)			usb_unlink_urb(urb)
+#define USB_FREE_URB(urb)			(usb_free_urb(urb))
+#define USB_REGISTER()				usb_register(&dbus_usbdev)
+#define USB_DEREGISTER()			usb_deregister(&dbus_usbdev)
+#define USB_AUTOPM_GET_INTERFACE(intf)		do {} while (0)
+#define USB_AUTOPM_GET_INTERFACE_ASYNC(intf)	do {} while (0)
+#define USB_AUTOPM_PUT_INTERFACE_ASYNC(intf)	do {} while (0)
+#define USB_MARK_LAST_BUSY(dev)			do {} while (0)
+
+#define USB_CONTROL_MSG(dev, pipe, request, requesttype, value, index, data, size, timeout) \
+	usb_control_msg((dev), (pipe), (request), (requesttype), (value), (index), \
+	(data), (size), (timeout))
+#define USB_BUFFER_ALLOC(dev, size, mem, dma)  kmalloc(size, mem)
+#define USB_BUFFER_FREE(dev, size, data, dma)  kfree(data)
+
+#ifdef WL_URB_ZPKT
+#define URB_QUEUE_BULK   USB_QUEUE_BULK|URB_ZERO_PACKET
+#else
+#define URB_QUEUE_BULK   0
+#endif /*  WL_URB_ZPKT */
+
+#define CALLBACK_ARGS		struct urb *urb
+#define CALLBACK_ARGS_DATA	urb
+#define CONFIGDESC(usb)		((usb)->actconfig)
+#define IFPTR(usb, idx)		(&(usb)->actconfig->interface[idx])
+#define IFALTS(usb, idx)	((usb)->actconfig->interface[idx].altsetting[0])
+#define IFDESC(usb, idx)	IFALTS((usb), (idx))
+#define IFEPDESC(usb, idx, ep)	(IFALTS((usb), (idx)).endpoint[ep])
+
+#ifdef DBUS_LINUX_RXDPC
+#define DAEMONIZE(a)    daemonize();
+#define SET_NICE(n)     do {current->nice = (n);} while (0)
+#endif /* DBUS_LINUX_RXDPC */
+
+#endif /* KERNEL26 */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31))
+#define USB_SPEED_SUPER		5
+#endif  /* #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31)) */
+
+#define CONTROL_IF   0
+#define BULK_IF      0
+
+#ifdef BCMUSBDEV_COMPOSITE
+#define USB_COMPIF_MAX       4
+
+/* temp defines, should come from the standard usb.h file */
+#define USB_CLASS_WIRELESS	0xe0
+#define USB_CLASS_MISC		0xef
+#define USB_SUBCLASS_COMMON	0x02
+#define USB_PROTO_IAD		0x01
+#define USB_PROTO_VENDOR	0xff
+
+#define USB_QUIRK_NO_SET_INTF   0x04 /**< device does not support set_interface */
+#endif /* BCMUSBDEV_COMPOSITE */
+
+#define USB_SYNC_WAIT_TIMEOUT  300  /* ms */
+
+/* Private data kept in skb */
+#define SKB_PRIV(skb, idx)  (&((void **)skb->cb)[idx])
+#define SKB_PRIV_URB(skb)   (*(struct urb **)SKB_PRIV(skb, 0))
+
+#ifndef DBUS_USB_RXQUEUE_BATCH_ADD
+/** items to add each time within limit */
+#define DBUS_USB_RXQUEUE_BATCH_ADD            8
+#endif
+
+#ifndef DBUS_USB_RXQUEUE_LOWER_WATERMARK
+/** add a new batch req to rx queue when waiting item count reduce to this number */
+#define DBUS_USB_RXQUEUE_LOWER_WATERMARK      4
+#endif
+
+enum usbos_suspend_state {
+	USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /**< Device is busy, won't allow suspend */
+	USBOS_SUSPEND_STATE_SUSPEND_PENDING,   /**< Device is idle, can be suspended */
+	                                       /* Wating PM to suspend */
+	USBOS_SUSPEND_STATE_SUSPENDED          /**< Device suspended */
+};
+
+enum usbos_request_state {
+	USBOS_REQUEST_STATE_UNSCHEDULED = 0,	/**< USB TX request not scheduled */
+	USBOS_REQUEST_STATE_SCHEDULED,		/**< USB TX request given to TX thread */
+	USBOS_REQUEST_STATE_SUBMITTED		/**< USB TX request submitted */
+};
+
+typedef struct {
+	uint32 notification;
+	uint32 reserved;
+} intr_t;
+
+typedef struct {
+	dbus_pub_t *pub;
+
+	void *cbarg;
+	dbus_intf_callbacks_t *cbs;
+
+	/* Imported */
+	struct usb_device *usb;	/**< USB device pointer from OS */
+	struct urb *intr_urb; /**< URB for interrupt endpoint */
+	struct list_head req_rxfreeq;
+	struct list_head req_txfreeq;
+	struct list_head req_rxpostedq;	/**< Posted down to USB driver for RX */
+	struct list_head req_txpostedq;	/**< Posted down to USB driver for TX */
+	spinlock_t rxfree_lock; /**< Lock for rx free list */
+	spinlock_t txfree_lock; /**< Lock for tx free list */
+	spinlock_t rxposted_lock; /**< Lock for rx posted list */
+	spinlock_t txposted_lock; /**< Lock for tx posted list */
+	uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2; /**< Pipe numbers for USB I/O */
+	uint rxbuf_len;
+
+	struct list_head req_rxpendingq; /**< RXDPC: Pending for dpc to send up */
+	spinlock_t rxpending_lock;	/**< RXDPC: Lock for rx pending list */
+	long dpc_pid;
+	struct semaphore dpc_sem;
+	struct completion dpc_exited;
+	int rxpending;
+#if defined(BCMDBG) || defined(DBUS_LINUX_HIST)
+	int	dpc_cnt, dpc_pktcnt, dpc_maxpktcnt;
+#endif
+
+	struct urb               *ctl_urb;
+	int                      ctl_in_pipe, ctl_out_pipe;
+	struct usb_ctrlrequest   ctl_write;
+	struct usb_ctrlrequest   ctl_read;
+	struct semaphore         ctl_lock;     /* Lock for CTRL transfers via tx_thread */
+#ifdef USBOS_TX_THREAD
+	enum usbos_request_state ctl_state;
+#endif /* USBOS_TX_THREAD */
+
+	spinlock_t rxlock;      /**< Lock for rxq management */
+	spinlock_t txlock;      /**< Lock for txq management */
+
+	int intr_size;          /**< Size of interrupt message */
+	int interval;           /**< Interrupt polling interval */
+	intr_t intr;            /**< Data buffer for interrupt endpoint */
+
+	int maxps;
+	atomic_t txposted;
+	atomic_t rxposted;
+	atomic_t txallocated;
+	atomic_t rxallocated;
+	bool rxctl_deferrespok;	/**< Get a response for setup from dongle */
+
+	wait_queue_head_t wait;
+	bool waitdone;
+	int sync_urb_status;
+
+	struct urb *blk_urb; /**< Used for downloading embedded image */
+
+#if defined(BCMDBG) || defined(DBUS_LINUX_HIST)
+	int *txposted_hist;
+	int *rxposted_hist;
+#endif
+#ifdef USBOS_THREAD
+	spinlock_t              usbos_list_lock;
+	struct list_head        usbos_list;
+	struct list_head        usbos_free_list;
+	atomic_t                usbos_list_cnt;
+	wait_queue_head_t       usbos_queue_head;
+	struct task_struct      *usbos_kt;
+#endif /* USBOS_THREAD */
+
+#ifdef USBOS_TX_THREAD
+	spinlock_t              usbos_tx_list_lock;
+	struct list_head	usbos_tx_list;
+	wait_queue_head_t	usbos_tx_queue_head;
+	struct task_struct      *usbos_tx_kt;
+#endif /* USBOS_TX_THREAD */
+
+	struct dma_pool *qtd_pool; /**< QTD pool for USB optimization only */
+	int tx_ep, rx_ep, rx2_ep;  /**< EPs for USB optimization */
+	struct usb_device *usb_device; /**< USB device for optimization */
+#if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX) /** Linux USB AP related */
+	spinlock_t fastpath_lock;
+#endif
+} usbos_info_t;
+
+typedef struct urb_req {
+	void         *pkt;
+	int          buf_len;
+	struct urb   *urb;
+	void         *arg;
+	usbos_info_t *usbinfo;
+	struct list_head urb_list;
+} urb_req_t;
+
+#ifdef USBOS_THREAD
+typedef struct usbos_list_entry {
+	struct list_head    list;   /* must be first */
+	void               *urb_context;
+	int                 urb_length;
+	int                 urb_status;
+} usbos_list_entry_t;
+
+static void* dbus_usbos_thread_init(usbos_info_t *usbos_info);
+static void  dbus_usbos_thread_deinit(usbos_info_t *usbos_info);
+static void  dbus_usbos_dispatch_schedule(CALLBACK_ARGS);
+static int   dbus_usbos_thread_func(void *data);
+#endif /* USBOS_THREAD */
+
+#ifdef USBOS_TX_THREAD
+void* dbus_usbos_tx_thread_init(usbos_info_t *usbos_info);
+void  dbus_usbos_tx_thread_deinit(usbos_info_t *usbos_info);
+int   dbus_usbos_tx_thread_func(void *data);
+#endif /* USBOS_TX_THREAD */
+
+/* Shared Function prototypes */
+bool dbus_usbos_dl_cmd(usbos_info_t *usbinfo, uint8 cmd, void *buffer, int buflen);
+int dbus_usbos_wait(usbos_info_t *usbinfo, uint16 ms);
+bool dbus_usbos_dl_send_bulk(usbos_info_t *usbinfo, void *buffer, int len);
+int dbus_write_membytes(usbos_info_t *usbinfo, bool set, uint32 address, uint8 *data, uint size);
+
+/* Local function prototypes */
+static void dbus_usbos_send_complete(CALLBACK_ARGS);
+#ifdef DBUS_LINUX_RXDPC
+static void dbus_usbos_recv_dpc(usbos_info_t *usbos_info);
+static int dbus_usbos_dpc_thread(void *data);
+#endif /* DBUS_LINUX_RXDPC */
+static void dbus_usbos_recv_complete(CALLBACK_ARGS);
+static int  dbus_usbos_errhandler(void *bus, int err);
+static int  dbus_usbos_state_change(void *bus, int state);
+static void dbusos_stop(usbos_info_t *usbos_info);
+
+#ifdef KERNEL26
+static int dbus_usbos_probe(struct usb_interface *intf, const struct usb_device_id *id);
+static void dbus_usbos_disconnect(struct usb_interface *intf);
+#if defined(USB_SUSPEND_AVAILABLE)
+static int dbus_usbos_resume(struct usb_interface *intf);
+static int dbus_usbos_suspend(struct usb_interface *intf, pm_message_t message);
+/** at the moment, used for full dongle host driver only */
+static int dbus_usbos_reset_resume(struct usb_interface *intf);
+#endif /* USB_SUSPEND_AVAILABLE */
+#else /* KERNEL26 */
+static void *dbus_usbos_probe(struct usb_device *usb, unsigned int ifnum,
+	const struct usb_device_id *id);
+static void dbus_usbos_disconnect(struct usb_device *usb, void *ptr);
+#endif /* KERNEL26 */
+
+#ifdef USB_TRIGGER_DEBUG
+static bool dbus_usbos_ctl_send_debugtrig(usbos_info_t *usbinfo);
+#endif /* USB_TRIGGER_DEBUG */
+
+#ifdef KEEPIF_ON_DEVICE_RESET
+enum usb_dev_status {
+	USB_DEVICE_INIT = 0,
+	USB_DEVICE_RESETTED = 1,
+	USB_DEVICE_DISCONNECTED = 2,
+	USB_DEVICE_PROBED
+};
+static int dbus_usbos_usbreset_func(void *data);
+#endif /* KEEPIF_ON_DEVICE_RESET */
+
+/**
+ * have to disable missing-field-initializers warning as last element {} triggers it
+ * and different versions of kernel have different number of members so it is impossible
+ * to specify the initializer. BTW issuing the warning here is bug og GCC as  universal
+ * zero {0} specified in C99 standard as correct way of initialization of struct to all zeros
+ */
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
+	4 && __GNUC_MINOR__ >= 6))
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
+
+static struct usb_device_id devid_table[] = {
+	{ USB_DEVICE(BCM_DNGL_VID, 0x0000) }, /* Configurable via register() */
+#if defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW)
+	{ USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_4360) },
+	{ USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_43569) },
+	{ USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BL_PID_4381) },
+#endif
+#ifdef EXTENDED_VID_PID
+	EXTENDED_VID_PID,
+#endif /* EXTENDED_VID_PID */
+	{ USB_DEVICE(BCM_DNGL_VID, BCM_DNGL_BDC_PID) }, /* Default BDC */
+	{ }
+};
+
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \
+	4 && __GNUC_MINOR__ >= 6))
+#pragma GCC diagnostic pop
+#endif
+
+MODULE_DEVICE_TABLE(usb, devid_table);
+
+/** functions called by the Linux kernel USB subsystem */
+static struct usb_driver dbus_usbdev = {
+	name:           "dbus_usbdev"ADAPTER_IDX_STR,
+	probe:          dbus_usbos_probe,
+	disconnect:     dbus_usbos_disconnect,
+	id_table:       devid_table,
+#if defined(USB_SUSPEND_AVAILABLE)
+	suspend:        dbus_usbos_suspend,
+	resume:         dbus_usbos_resume,
+	reset_resume:	dbus_usbos_reset_resume,
+	/** Linux USB core will allow autosuspend for devices bound to this driver */
+	supports_autosuspend: 1
+#endif /* USB_SUSPEND_AVAILABLE */
+};
+
+/**
+ * This stores USB info during Linux probe callback since attach() is not called yet at this point
+ */
+typedef struct {
+	void    *usbos_info;
+	struct usb_device *usb; /**< USB device pointer from OS */
+	uint    rx_pipe;   /**< Pipe numbers for USB I/O */
+	uint    tx_pipe;   /**< Pipe numbers for USB I/O */
+	uint    intr_pipe; /**< Pipe numbers for USB I/O */
+	uint    rx_pipe2;  /**< Pipe numbers for USB I/O */
+	int     intr_size; /**< Size of interrupt message */
+	int     interval;  /**< Interrupt polling interval */
+	bool    dldone;
+	int     vid;
+	int     pid;
+	bool    dereged;
+	bool    disc_cb_done;
+	DEVICE_SPEED    device_speed;
+	enum usbos_suspend_state suspend_state;
+	struct usb_interface     *intf;
+#ifdef KEEPIF_ON_DEVICE_RESET
+	bool               keepif_on_devreset; /* if need keep network interface on dev reset */
+	bool               dev_resetted; /* if dev reset event occured */
+	enum dbus_state    busstate_bf_devreset; /* busstate before devreset */
+	atomic_t           usbdev_stat; /* usb device status: resetted? disconnected? re-probed? */
+	wait_queue_head_t  usbreset_queue_head; /* kernel thread waiting queue */
+	struct task_struct *usbreset_kt; /* kernel thread handle dev reset/probe event */
+#endif /* KEEPIF_ON_DEVICE_RESET */
+} probe_info_t;
+
+/* driver info, initialized when bcmsdh_register is called */
+static dbus_driver_t drvinfo = {NULL, NULL, NULL, NULL};
+
+/*
+ * USB Linux dbus_intf_t
+ */
+static void dbus_usbos_init_info(void);
+static void *dbus_usbos_intf_attach(dbus_pub_t *pub, void *cbarg, dbus_intf_callbacks_t *cbs);
+static void dbus_usbos_intf_detach(dbus_pub_t *pub, void *info);
+static int  dbus_usbos_intf_send_irb(void *bus, dbus_irb_tx_t *txirb);
+static int  dbus_usbos_intf_recv_irb(void *bus, dbus_irb_rx_t *rxirb);
+static int  dbus_usbos_intf_recv_irb_from_ep(void *bus, dbus_irb_rx_t *rxirb, uint32 ep_idx);
+static int  dbus_usbos_intf_cancel_irb(void *bus, dbus_irb_tx_t *txirb);
+static int  dbus_usbos_intf_send_ctl(void *bus, uint8 *buf, int len);
+static int  dbus_usbos_intf_recv_ctl(void *bus, uint8 *buf, int len);
+static int  dbus_usbos_intf_get_attrib(void *bus, dbus_attrib_t *attrib);
+static int  dbus_usbos_intf_up(void *bus);
+static int  dbus_usbos_intf_down(void *bus);
+static int  dbus_usbos_intf_stop(void *bus);
+static int  dbus_usbos_readreg(void *bus, uint32 regaddr, int datalen, uint32 *value);
+extern int dbus_usbos_loopback_tx(void *usbos_info_ptr, int cnt, int size);
+int dbus_usbos_writereg(void *bus, uint32 regaddr, int datalen, uint32 data);
+#if defined(BCMDBG) || defined(DBUS_LINUX_HIST)
+static void dbus_usbos_intf_dump(void *bus, struct bcmstrbuf *b);
+#endif /* BCMDBG || DBUS_LINUX_HIST */
+static int  dbus_usbos_intf_set_config(void *bus, dbus_config_t *config);
+static bool dbus_usbos_intf_recv_needed(void *bus);
+static void *dbus_usbos_intf_exec_rxlock(void *bus, exec_cb_t cb, struct exec_parms *args);
+static void *dbus_usbos_intf_exec_txlock(void *bus, exec_cb_t cb, struct exec_parms *args);
+#ifdef BCMUSBDEV_COMPOSITE
+static int dbus_usbos_intf_wlan(struct usb_device *usb);
+#endif /* BCMUSBDEV_COMPOSITE */
+
+/** functions called by dbus_usb.c */
+static dbus_intf_t dbus_usbos_intf = {
+	.attach = dbus_usbos_intf_attach,
+	.detach = dbus_usbos_intf_detach,
+	.up = dbus_usbos_intf_up,
+	.down = dbus_usbos_intf_down,
+	.send_irb = dbus_usbos_intf_send_irb,
+	.recv_irb = dbus_usbos_intf_recv_irb,
+	.cancel_irb = dbus_usbos_intf_cancel_irb,
+	.send_ctl = dbus_usbos_intf_send_ctl,
+	.recv_ctl = dbus_usbos_intf_recv_ctl,
+	.get_stats = NULL,
+	.get_attrib = dbus_usbos_intf_get_attrib,
+	.remove = NULL,
+	.resume = NULL,
+	.suspend = NULL,
+	.stop = dbus_usbos_intf_stop,
+	.reset = NULL,
+	.pktget = NULL,
+	.pktfree = NULL,
+	.iovar_op = NULL,
+#if defined(BCMDBG) || defined(DBUS_LINUX_HIST)
+	.dump = dbus_usbos_intf_dump,
+#else
+	.dump = NULL,
+#endif /* BCMDBG || DBUS_LINUX_HIST */
+	.set_config = dbus_usbos_intf_set_config,
+	.get_config = NULL,
+	.device_exists = NULL,
+	.dlneeded = NULL,
+	.dlstart = NULL,
+	.dlrun = NULL,
+	.recv_needed = dbus_usbos_intf_recv_needed,
+	.exec_rxlock = dbus_usbos_intf_exec_rxlock,
+	.exec_txlock = dbus_usbos_intf_exec_txlock,
+
+	.tx_timer_init = NULL,
+	.tx_timer_start = NULL,
+	.tx_timer_stop = NULL,
+
+	.sched_dpc = NULL,
+	.lock = NULL,
+	.unlock = NULL,
+	.sched_probe_cb = NULL,
+
+	.shutdown = NULL,
+
+	.recv_stop = NULL,
+	.recv_resume = NULL,
+
+	.recv_irb_from_ep = dbus_usbos_intf_recv_irb_from_ep,
+	.readreg = dbus_usbos_readreg
+};
+
+static probe_info_t    g_probe_info;
+static void            *disc_arg = NULL;
+
+#if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX)
+
+#define EHCI_PAGE_SIZE    4096
+
+/* Copies of structures located elsewhere. */
+/* ME: Unify (move to include file) */
+
+typedef struct {
+	dbus_pub_t *pub;
+	void *cbarg;
+	dbus_intf_callbacks_t *cbs;
+	dbus_intf_t *drvintf;
+	void *usbosl_info;
+} usb_info_t;
+
+/** General info for all BUS */
+typedef struct dbus_irbq {
+	dbus_irb_t *head;
+	dbus_irb_t *tail;
+	int cnt;
+} dbus_irbq_t;
+
+/**
+ * This private structure dbus_info_t is also declared in dbus.c.
+ * All the fields must be consistent in both declarations.
+ */
+typedef struct dbus_info {
+	dbus_pub_t pub; /* MUST BE FIRST */
+
+	void *cbarg;
+	dbus_callbacks_t *cbs;
+	void *bus_info;
+	dbus_intf_t *drvintf;
+	uint8 *fw;
+	int fwlen;
+	uint32 errmask;
+	int rx_low_watermark;
+	int tx_low_watermark;
+	bool txoff;
+	bool txoverride;
+	bool rxoff;
+	bool tx_timer_ticking;
+	dbus_irbq_t *rx_q;
+	dbus_irbq_t *tx_q;
+
+#ifdef BCMDBG
+	int *txpend_q_hist;
+	int *rxpend_q_hist;
+#endif /* BCMDBG */
+#ifdef EHCI_FASTPATH_RX
+	atomic_t rx_outstanding;
+#endif
+	uint8 *nvram;
+	int	nvram_len;
+	uint8 *image;	/**< buffer for combine fw and nvram */
+	int image_len;
+	uint8 *orig_fw;
+	int origfw_len;
+	int decomp_memsize;
+	dbus_extdl_t extdl;
+	int nvram_nontxt;
+} dbus_info_t;
+
+/* ME: Move to device extension */
+static atomic_t s_tx_pending;
+
+static int optimize_init(usbos_info_t *usbos_info, struct usb_device *usb, int out,
+	int in, int in2);
+static int optimize_deinit(usbos_info_t *usbos_info, struct usb_device *usb);
+#endif  /* #if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX) */
+
+static volatile int loopback_rx_cnt, loopback_tx_cnt;
+int loopback_size;
+bool is_loopback_pkt(void *buf);
+int matches_loopback_pkt(void *buf);
+
+/**
+ * multiple code paths in this file dequeue a URB request, this function makes sure that it happens
+ * in a concurrency save manner. Don't call this from a sleepable process context.
+ */
+static urb_req_t *
+dbus_usbos_qdeq(struct list_head *urbreq_q, spinlock_t *lock)
+{
+	unsigned long flags;
+	urb_req_t *req;
+
+	ASSERT(urbreq_q != NULL);
+
+	spin_lock_irqsave(lock, flags);
+
+	if (list_empty(urbreq_q)) {
+		req = NULL;
+	} else {
+		ASSERT(urbreq_q->next != NULL);
+		ASSERT(urbreq_q->next != urbreq_q);
+		GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+		req = list_entry(urbreq_q->next, urb_req_t, urb_list);
+		GCC_DIAGNOSTIC_POP();
+		list_del_init(&req->urb_list);
+	}
+
+	spin_unlock_irqrestore(lock, flags);
+
+	return req;
+}
+
+static void
+dbus_usbos_qenq(struct list_head *urbreq_q, urb_req_t *req, spinlock_t *lock)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(lock, flags);
+
+	list_add_tail(&req->urb_list, urbreq_q);
+
+	spin_unlock_irqrestore(lock, flags);
+}
+
+/**
+ * multiple code paths in this file remove a URB request from a list, this function makes sure that
+ * it happens in a concurrency save manner. Don't call this from a sleepable process context.
+ * Is quite similar to dbus_usbos_qdeq(), I wonder why this function is needed.
+ */
+static void
+dbus_usbos_req_del(urb_req_t *req, spinlock_t *lock)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(lock, flags);
+
+	list_del_init(&req->urb_list);
+
+	spin_unlock_irqrestore(lock, flags);
+}
+
+/**
+ * Driver requires a pool of URBs to operate. This function is called during
+ * initialization (attach phase), allocates a number of URBs, and puts them
+ * on the free (req_rxfreeq and req_txfreeq) queue
+ */
+static int
+dbus_usbos_urbreqs_alloc(usbos_info_t *usbos_info, uint32 count, bool is_rx)
+{
+	int i;
+	int allocated = 0;
+	int err = DBUS_OK;
+
+	for (i = 0; i < count; i++) {
+		urb_req_t *req;
+
+		req = MALLOC(usbos_info->pub->osh, sizeof(urb_req_t));
+		if (req == NULL) {
+			DBUSERR(("%s: MALLOC req failed\n", __FUNCTION__));
+			err = DBUS_ERR_NOMEM;
+			goto fail;
+		}
+		bzero(req, sizeof(urb_req_t));
+
+		req->urb = USB_ALLOC_URB();
+		if (req->urb == NULL) {
+			DBUSERR(("%s: USB_ALLOC_URB req->urb failed\n", __FUNCTION__));
+			err = DBUS_ERR_NOMEM;
+			goto fail;
+		}
+
+		INIT_LIST_HEAD(&req->urb_list);
+
+		if (is_rx) {
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
+			/* don't allocate now. Do it on demand */
+			req->pkt = NULL;
+#else
+			/* pre-allocate  buffers never to be released */
+			req->pkt = MALLOC(usbos_info->pub->osh, usbos_info->rxbuf_len);
+			if (req->pkt == NULL) {
+				DBUSERR(("%s: MALLOC req->pkt failed\n", __FUNCTION__));
+				err = DBUS_ERR_NOMEM;
+				goto fail;
+			}
+#endif
+			req->buf_len = usbos_info->rxbuf_len;
+			dbus_usbos_qenq(&usbos_info->req_rxfreeq, req, &usbos_info->rxfree_lock);
+		} else {
+			req->buf_len = 0;
+			dbus_usbos_qenq(&usbos_info->req_txfreeq, req, &usbos_info->txfree_lock);
+		}
+		allocated++;
+		continue;
+
+fail:
+		if (req) {
+			if (is_rx && req->pkt) {
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
+				/* req->pkt is NULL in "NOCOPY" mode */
+#else
+				MFREE(usbos_info->pub->osh, req->pkt, req->buf_len);
+#endif
+			}
+			if (req->urb) {
+				USB_FREE_URB(req->urb);
+			}
+			MFREE(usbos_info->pub->osh, req, sizeof(urb_req_t));
+		}
+		break;
+	}
+
+	atomic_add(allocated, is_rx ? &usbos_info->rxallocated : &usbos_info->txallocated);
+
+	if (is_rx) {
+		DBUSTRACE(("%s: add %d (total %d) rx buf, each has %d bytes\n", __FUNCTION__,
+			allocated, atomic_read(&usbos_info->rxallocated), usbos_info->rxbuf_len));
+	} else {
+		DBUSTRACE(("%s: add %d (total %d) tx req\n", __FUNCTION__,
+			allocated, atomic_read(&usbos_info->txallocated)));
+	}
+
+	return err;
+} /* dbus_usbos_urbreqs_alloc */
+
+/** Typically called during detach or when attach failed. Don't call until all URBs unlinked */
+static int
+dbus_usbos_urbreqs_free(usbos_info_t *usbos_info, bool is_rx)
+{
+	int rtn = 0;
+	urb_req_t *req;
+	struct list_head *req_q;
+	spinlock_t *lock;
+
+	if (is_rx) {
+		req_q = &usbos_info->req_rxfreeq;
+		lock = &usbos_info->rxfree_lock;
+	} else {
+		req_q = &usbos_info->req_txfreeq;
+		lock = &usbos_info->txfree_lock;
+	}
+
+	while ((req = dbus_usbos_qdeq(req_q, lock)) != NULL) {
+		if (is_rx) {
+			if (req->pkt) {
+				/* We do MFREE instead of PKTFREE because the pkt has been
+				 * converted to native already
+				 */
+				MFREE(usbos_info->pub->osh, req->pkt, req->buf_len);
+				req->buf_len = 0;
+			}
+		} else {
+			/* sending req should not be assigned pkt buffer */
+			ASSERT(req->pkt == NULL);
+		}
+
+		if (req->urb) {
+			USB_FREE_URB(req->urb);
+			req->urb = NULL;
+		}
+		MFREE(usbos_info->pub->osh, req, sizeof(urb_req_t));
+
+		rtn++;
+	}
+
+	return rtn;
+} /* dbus_usbos_urbreqs_free */
+
+/**
+ * called by Linux kernel on URB completion. Upper DBUS layer (dbus_usb.c) has to be notified of
+ * send completion.
+ */
+void
+dbus_usbos_send_complete(CALLBACK_ARGS)
+{
+	urb_req_t *req = urb->context;
+	dbus_irb_tx_t *txirb = req->arg;
+	usbos_info_t *usbos_info = req->usbinfo;
+	unsigned long flags;
+	int status = DBUS_OK;
+	int txposted;
+
+	USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
+
+	spin_lock_irqsave(&usbos_info->txlock, flags);
+
+	dbus_usbos_req_del(req, &usbos_info->txposted_lock);
+	txposted = atomic_dec_return(&usbos_info->txposted);
+#if defined(BCMDBG) || defined(DBUS_LINUX_HIST)
+	if (usbos_info->txposted_hist) {
+		usbos_info->txposted_hist[txposted]++;
+	}
+#endif /* BCMDBG || DBUS_LINUX_HIST */
+	if (unlikely (txposted < 0)) {
+		DBUSERR(("%s ERROR: txposted is negative (%d)!!\n", __FUNCTION__, txposted));
+	}
+	spin_unlock_irqrestore(&usbos_info->txlock, flags);
+
+	if (unlikely (urb->status)) {
+		status = DBUS_ERR_TXFAIL;
+		DBUSTRACE(("txfail status %d\n", urb->status));
+	}
+
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
+	/* sending req should not be assigned pkt buffer */
+	ASSERT(req->pkt == NULL);
+#endif
+	/*  txirb should always be set, except for ZLP. ZLP is reusing this callback function. */
+	if (txirb != NULL) {
+		if (txirb->send_buf != NULL) {
+			MFREE(usbos_info->pub->osh, txirb->send_buf, req->buf_len);
+			req->buf_len = 0;
+		}
+		if (likely (usbos_info->cbarg && usbos_info->cbs)) {
+			if (likely (usbos_info->cbs->send_irb_complete != NULL))
+			    usbos_info->cbs->send_irb_complete(usbos_info->cbarg, txirb, status);
+		}
+	}
+
+	dbus_usbos_qenq(&usbos_info->req_txfreeq, req, &usbos_info->txfree_lock);
+} /* dbus_usbos_send_complete */
+
+/**
+ * In order to receive USB traffic from the dongle, we need to supply the Linux kernel with a free
+ * URB that is going to contain received data.
+ */
+static int
+dbus_usbos_recv_urb_submit(usbos_info_t *usbos_info, dbus_irb_rx_t *rxirb,
+	uint32 ep_idx)
+{
+	urb_req_t *req;
+	int ret = DBUS_OK;
+	unsigned long flags;
+	void *p;
+	uint rx_pipe;
+	int rxposted;
+
+	BCM_REFERENCE(rxposted);
+
+	if (!(req = dbus_usbos_qdeq(&usbos_info->req_rxfreeq, &usbos_info->rxfree_lock))) {
+		DBUSTRACE(("%s No free URB!\n", __FUNCTION__));
+		return DBUS_ERR_RXDROP;
+	}
+
+	spin_lock_irqsave(&usbos_info->rxlock, flags);
+
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
+	req->pkt = rxirb->pkt = PKTGET(usbos_info->pub->osh, req->buf_len, FALSE);
+	if (!rxirb->pkt) {
+		DBUSERR(("%s: PKTGET failed\n", __FUNCTION__));
+		dbus_usbos_qenq(&usbos_info->req_rxfreeq, req, &usbos_info->rxfree_lock);
+		ret = DBUS_ERR_RXDROP;
+		goto fail;
+	}
+	/* consider the packet "native" so we don't count it as MALLOCED in the osl */
+	PKTTONATIVE(usbos_info->pub->osh, req->pkt);
+	rxirb->buf = NULL;
+	p = PKTDATA(usbos_info->pub->osh, req->pkt);
+#else
+	if (req->buf_len != usbos_info->rxbuf_len) {
+		ASSERT(req->pkt);
+		MFREE(usbos_info->pub->osh, req->pkt, req->buf_len);
+		DBUSTRACE(("%s: replace rx buff: old len %d, new len %d\n", __FUNCTION__,
+			req->buf_len, usbos_info->rxbuf_len));
+		req->buf_len = 0;
+		req->pkt = MALLOC(usbos_info->pub->osh, usbos_info->rxbuf_len);
+		if (req->pkt == NULL) {
+			DBUSERR(("%s: MALLOC req->pkt failed\n", __FUNCTION__));
+			ret = DBUS_ERR_NOMEM;
+			goto fail;
+		}
+		req->buf_len = usbos_info->rxbuf_len;
+	}
+	rxirb->buf = req->pkt;
+	p = rxirb->buf;
+#endif /* defined(BCM_RPC_NOCOPY) */
+	rxirb->buf_len = req->buf_len;
+	req->usbinfo = usbos_info;
+	req->arg = rxirb;
+	if (ep_idx == 0) {
+		rx_pipe = usbos_info->rx_pipe;
+	} else {
+		rx_pipe = usbos_info->rx_pipe2;
+		ASSERT(usbos_info->rx_pipe2);
+	}
+	/* Prepare the URB */
+	usb_fill_bulk_urb(req->urb, usbos_info->usb, rx_pipe,
+		p,
+		rxirb->buf_len,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
+		(void *)dbus_usbos_recv_complete, req);
+#else
+		(usb_complete_t)dbus_usbos_recv_complete, req);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) */
+		req->urb->transfer_flags |= URB_QUEUE_BULK;
+
+	if ((ret = USB_SUBMIT_URB(req->urb))) {
+		DBUSERR(("%s USB_SUBMIT_URB failed. status %d\n", __FUNCTION__, ret));
+		dbus_usbos_qenq(&usbos_info->req_rxfreeq, req, &usbos_info->rxfree_lock);
+		ret = DBUS_ERR_RXFAIL;
+		goto fail;
+	}
+	rxposted = atomic_inc_return(&usbos_info->rxposted);
+#if defined(BCMDBG) || defined(DBUS_LINUX_HIST)
+	if (usbos_info->rxposted_hist) {
+		usbos_info->rxposted_hist[rxposted]++;
+	}
+#endif /* BCMDBG || DBUS_LINUX_HIST */
+
+	dbus_usbos_qenq(&usbos_info->req_rxpostedq, req, &usbos_info->rxposted_lock);
+fail:
+	spin_unlock_irqrestore(&usbos_info->rxlock, flags);
+	return ret;
+} /* dbus_usbos_recv_urb_submit */
+
+#ifdef DBUS_LINUX_RXDPC
+
+static void
+dbus_usbos_recv_dpc(usbos_info_t *usbos_info)
+{
+	urb_req_t *req = NULL;
+	dbus_irb_rx_t *rxirb = NULL;
+	int dbus_status = DBUS_OK;
+	bool killed = (g_probe_info.suspend_state == USBOS_SUSPEND_STATE_SUSPEND_PENDING) ? 1 : 0;
+
+#if defined(BCMDBG) || defined(DBUS_LINUX_HIST)
+	int cnt = 0;
+
+	usbos_info->dpc_cnt++;
+#endif /* BCMDBG || DBUS_LINUX_HIST */
+
+	/* make it bounded if we think it can take too long */
+	while ((req = dbus_usbos_qdeq(&usbos_info->req_rxpendingq,
+		&usbos_info->rxpending_lock)) != NULL) {
+		struct urb *urb = req->urb;
+		rxirb = req->arg;
+
+		/* Handle errors */
+		if (urb->status) {
+			/*
+			 * Linux 2.4 disconnect: -ENOENT or -EILSEQ for CRC error; rmmod: -ENOENT
+			 * Linux 2.6 disconnect: -EPROTO, rmmod: -ESHUTDOWN
+			 */
+			if ((urb->status == -ENOENT && (!killed)) || urb->status == -ESHUTDOWN) {
+				/* NOTE: unlink() can not be called from URB callback().
+				 * Do not call dbusos_stop() here.
+				 */
+				dbus_usbos_state_change(usbos_info, DBUS_STATE_DOWN);
+			} else if (urb->status == -EPROTO) {
+			} else {
+				DBUSERR(("%s rx error %d\n", __FUNCTION__, urb->status));
+				dbus_usbos_errhandler(usbos_info, DBUS_ERR_RXFAIL);
+			}
+
+			/* On error, don't submit more URBs yet */
+			DBUSERR(("%s %d rx error %d\n", __FUNCTION__, __LINE__, urb->status));
+			rxirb->buf = NULL;
+			rxirb->actual_len = 0;
+			dbus_status = DBUS_ERR_RXFAIL;
+			goto fail;
+		}
+
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
+		/* detach the packet from the req */
+		req->pkt = NULL;
+#endif
+		/* Make the skb represent the received urb */
+		rxirb->actual_len = urb->actual_length;
+
+fail:
+		/* this is just a stats, we don't protect it with locks for now */
+		usbos_info->rxpending--;
+#if defined(BCMDBG) || defined(DBUS_LINUX_HIST)
+		cnt++;
+#endif /* BCMDBG || DBUS_LINUX_HIST */
+		if (usbos_info->cbarg && usbos_info->cbs &&
+			usbos_info->cbs->recv_irb_complete) {
+			usbos_info->cbs->recv_irb_complete(usbos_info->cbarg, rxirb, dbus_status);
+		}
+		dbus_usbos_qenq(&usbos_info->req_rxfreeq, req, &usbos_info->rxfree_lock);
+	}
+
+#if defined(BCMDBG) || defined(DBUS_LINUX_HIST)
+	usbos_info->dpc_pktcnt += cnt;
+	usbos_info->dpc_maxpktcnt = MAX(cnt, usbos_info->dpc_maxpktcnt);
+#endif /* BCMDBG || DBUS_LINUX_HIST */
+#ifdef DBUS_LINUX_HIST
+	{
+		static unsigned long last_dump = 0;
+
+		/* dump every 20 sec */
+		if (jiffies > (last_dump + 20*HZ)) {
+			dbus_usbos_intf_dump(usbos_info, NULL);
+			last_dump = jiffies;
+		}
+	}
+#endif /* DBUS_LINUX_HIST */
+} /* dbus_usbos_recv_dpc */
+
+static int
+dbus_usbos_dpc_thread(void *data)
+{
+	usbos_info_t *usbos_info = (usbos_info_t*)data;
+
+	DAEMONIZE("dbus_rx_dpc");
+	/* High priority for short response time. We will yield by ourselves. */
+	/* SET_NICE(-10); */
+
+	/* Run until signal received */
+	while (1) {
+		if (down_interruptible(&usbos_info->dpc_sem) == 0) {
+			dbus_usbos_recv_dpc(usbos_info);
+			RESCHED();
+		} else
+			break;
+	}
+
+	complete_and_exit(&usbos_info->dpc_exited, 0);
+	return 0;
+}
+
+#endif /* DBUS_LINUX_RXDPC */
+
+/**
+ * Called by worked thread when a 'receive URB' completed or Linux kernel when it returns a URB to
+ * this driver.
+ */
+static void
+dbus_usbos_recv_complete_handle(urb_req_t *req, int len, int status)
+{
+#ifdef DBUS_LINUX_RXDPC
+	usbos_info_t *usbos_info = req->usbinfo;
+	unsigned long flags;
+	int rxallocated, rxposted;
+
+	spin_lock_irqsave(&usbos_info->rxlock, flags);
+	/* detach the packet from the queue */
+	dbus_usbos_req_del(req, &usbos_info->rxposted_lock);
+	rxposted = atomic_dec_return(&usbos_info->rxposted);
+	rxallocated = atomic_read(&usbos_info->rxallocated);
+
+	/* Enqueue to rxpending queue */
+	usbos_info->rxpending++;
+	dbus_usbos_qenq(&usbos_info->req_rxpendingq, req, &usbos_info->rxpending_lock);
+	spin_unlock_irqrestore(&usbos_info->rxlock, flags);
+
+#error "RX req/buf appending-mode not verified for DBUS_LINUX_RXDPC because it was disabled"
+	if ((rxallocated < usbos_info->pub->nrxq) && (!status) &&
+		(rxposted == DBUS_USB_RXQUEUE_LOWER_WATERMARK)) {
+			DBUSTRACE(("%s: need more rx buf: rxallocated %d rxposted %d!\n",
+				__FUNCTION__, rxallocated, rxposted));
+			dbus_usbos_urbreqs_alloc(usbos_info,
+				MIN(DBUS_USB_RXQUEUE_BATCH_ADD,
+				usbos_info->pub->nrxq - rxallocated), TRUE);
+	}
+#error "Please verify above code works if you happened to enable DBUS_LINUX_RXDPC!!"
+
+	/* Wake up dpc for further processing */
+	ASSERT(usbos_info->dpc_pid >= 0);
+	up(&usbos_info->dpc_sem);
+#else
+	dbus_irb_rx_t *rxirb = req->arg;
+	usbos_info_t *usbos_info = req->usbinfo;
+	unsigned long flags;
+	int rxallocated, rxposted;
+	int dbus_status = DBUS_OK;
+	bool killed = (g_probe_info.suspend_state == USBOS_SUSPEND_STATE_SUSPEND_PENDING) ? 1 : 0;
+
+	spin_lock_irqsave(&usbos_info->rxlock, flags);
+	dbus_usbos_req_del(req, &usbos_info->rxposted_lock);
+	rxposted = atomic_dec_return(&usbos_info->rxposted);
+	rxallocated = atomic_read(&usbos_info->rxallocated);
+	spin_unlock_irqrestore(&usbos_info->rxlock, flags);
+
+	if ((rxallocated < usbos_info->pub->nrxq) && (!status) &&
+		(rxposted == DBUS_USB_RXQUEUE_LOWER_WATERMARK)) {
+			DBUSTRACE(("%s: need more rx buf: rxallocated %d rxposted %d!\n",
+				__FUNCTION__, rxallocated, rxposted));
+			dbus_usbos_urbreqs_alloc(usbos_info,
+				MIN(DBUS_USB_RXQUEUE_BATCH_ADD,
+				usbos_info->pub->nrxq - rxallocated), TRUE);
+	}
+
+	/* Handle errors */
+	if (status) {
+		/*
+		 * Linux 2.4 disconnect: -ENOENT or -EILSEQ for CRC error; rmmod: -ENOENT
+		 * Linux 2.6 disconnect: -EPROTO, rmmod: -ESHUTDOWN
+		 */
+		if ((status == -ENOENT && (!killed))|| status == -ESHUTDOWN) {
+			/* NOTE: unlink() can not be called from URB callback().
+			 * Do not call dbusos_stop() here.
+			 */
+			DBUSTRACE(("%s rx error %d\n", __FUNCTION__, status));
+			dbus_usbos_state_change(usbos_info, DBUS_STATE_DOWN);
+		} else if (status == -EPROTO) {
+			DBUSTRACE(("%s rx error %d\n", __FUNCTION__, status));
+		} else if (killed && (status == -EHOSTUNREACH || status == -ENOENT)) {
+			/* Device is suspended */
+		} else {
+			DBUSTRACE(("%s rx error %d\n", __FUNCTION__, status));
+			dbus_usbos_errhandler(usbos_info, DBUS_ERR_RXFAIL);
+		}
+
+		/* On error, don't submit more URBs yet */
+		rxirb->buf = NULL;
+		rxirb->actual_len = 0;
+		dbus_status = DBUS_ERR_RXFAIL;
+		goto fail;
+	}
+
+	/* Make the skb represent the received urb */
+	rxirb->actual_len = len;
+
+	if (rxirb->actual_len < sizeof(uint32)) {
+		DBUSTRACE(("small pkt len %d, process as ZLP\n", rxirb->actual_len));
+		dbus_status = DBUS_ERR_RXZLP;
+	}
+
+fail:
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
+	/* detach the packet from the queue */
+	req->pkt = NULL;
+#endif /* BCM_RPC_NOCOPY || BCM_RPC_RXNOCOPY */
+
+	if (usbos_info->cbarg && usbos_info->cbs) {
+		if (usbos_info->cbs->recv_irb_complete) {
+			usbos_info->cbs->recv_irb_complete(usbos_info->cbarg, rxirb, dbus_status);
+		}
+	}
+
+	dbus_usbos_qenq(&usbos_info->req_rxfreeq, req, &usbos_info->rxfree_lock);
+#endif /* DBUS_LINUX_RXDPC */
+
+	/* Mark the interface as busy to reset USB autosuspend timer */
+	USB_MARK_LAST_BUSY(usbos_info->usb);
+} /* dbus_usbos_recv_complete_handle */
+
+/** called by Linux kernel when it returns a URB to this driver */
+static void
+dbus_usbos_recv_complete(CALLBACK_ARGS)
+{
+#ifdef USBOS_THREAD
+	dbus_usbos_dispatch_schedule(CALLBACK_ARGS_DATA);
+#else /*  !USBOS_THREAD */
+	dbus_usbos_recv_complete_handle(urb->context, urb->actual_length, urb->status);
+#endif /*  USBOS_THREAD */
+}
+
+/**
+ * If Linux notifies our driver that a control read or write URB has completed, we should notify
+ * the DBUS layer above us (dbus_usb.c in this case).
+ */
+static void
+dbus_usbos_ctl_complete(usbos_info_t *usbos_info, int type, int urbstatus)
+{
+	int status = DBUS_ERR;
+
+	if (usbos_info == NULL)
+		return;
+
+	switch (urbstatus) {
+		case 0:
+			status = DBUS_OK;
+		break;
+		case -EINPROGRESS:
+		case -ENOENT:
+		default:
+#ifdef INTR_EP_ENABLE
+			DBUSERR(("%s:%d fail status %d bus:%d susp:%d intr:%d ctli:%d ctlo:%d\n",
+				__FUNCTION__, type, urbstatus,
+				usbos_info->pub->busstate, g_probe_info.suspend_state,
+				usbos_info->intr_urb_submitted, usbos_info->ctlin_urb_submitted,
+				usbos_info->ctlout_urb_submitted));
+#else
+			DBUSERR(("%s: failed with status %d\n", __FUNCTION__, urbstatus));
+			status = DBUS_ERR;
+		break;
+#endif /* INTR_EP_ENABLE */
+	}
+
+	if (usbos_info->cbarg && usbos_info->cbs) {
+		if (usbos_info->cbs->ctl_complete)
+			usbos_info->cbs->ctl_complete(usbos_info->cbarg, type, status);
+	}
+}
+
+/** called by Linux */
+static void
+dbus_usbos_ctlread_complete(CALLBACK_ARGS)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *)urb->context;
+
+	ASSERT(urb);
+	usbos_info = (usbos_info_t *)urb->context;
+
+	dbus_usbos_ctl_complete(usbos_info, DBUS_CBCTL_READ, urb->status);
+
+#ifdef USBOS_THREAD
+	if (usbos_info->rxctl_deferrespok) {
+		usbos_info->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_CLASS |
+		USB_RECIP_INTERFACE;
+		usbos_info->ctl_read.bRequest = 1;
+	}
+#endif
+
+	up(&usbos_info->ctl_lock);
+
+	USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
+}
+
+/** called by Linux */
+static void
+dbus_usbos_ctlwrite_complete(CALLBACK_ARGS)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *)urb->context;
+
+	ASSERT(urb);
+	usbos_info = (usbos_info_t *)urb->context;
+
+	dbus_usbos_ctl_complete(usbos_info, DBUS_CBCTL_WRITE, urb->status);
+
+#ifdef USBOS_TX_THREAD
+	usbos_info->ctl_state = USBOS_REQUEST_STATE_UNSCHEDULED;
+#endif /* USBOS_TX_THREAD */
+
+	up(&usbos_info->ctl_lock);
+
+	USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
+}
+
+#ifdef INTR_EP_ENABLE
+/** called by Linux */
+static void
+dbus_usbos_intr_complete(CALLBACK_ARGS)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *)urb->context;
+	bool killed = (g_probe_info.suspend_state == USBOS_SUSPEND_STATE_SUSPEND_PENDING) ? 1 : 0;
+
+	if (usbos_info == NULL || usbos_info->pub == NULL)
+		return;
+	if ((urb->status == -ENOENT && (!killed)) || urb->status == -ESHUTDOWN ||
+		urb->status == -ENODEV) {
+		dbus_usbos_state_change(usbos_info, DBUS_STATE_DOWN);
+	}
+
+	if (usbos_info->pub->busstate == DBUS_STATE_DOWN) {
+		DBUSERR(("%s: intr cb when DBUS down, ignoring\n", __FUNCTION__));
+		return;
+	}
+	dbus_usbos_ctl_complete(usbos_info, DBUS_CBINTR_POLL, urb->status);
+}
+#endif	/* INTR_EP_ENABLE */
+
+/**
+ * when the bus is going to sleep or halt, the Linux kernel requires us to take ownership of our
+ * URBs again. Multiple code paths in this file require a list of URBs to be cancelled in a
+ * concurrency save manner.
+ */
+static void
+dbus_usbos_unlink(struct list_head *urbreq_q, spinlock_t *lock)
+{
+	urb_req_t *req;
+
+	/* dbus_usbos_recv_complete() adds req back to req_freeq */
+	while ((req = dbus_usbos_qdeq(urbreq_q, lock)) != NULL) {
+		ASSERT(req->urb != NULL);
+		USB_UNLINK_URB(req->urb);
+	}
+}
+
+/** multiple code paths in this file require the bus to stop */
+static void
+dbus_usbos_cancel_all_urbs(usbos_info_t *usbos_info)
+{
+	int rxposted, txposted;
+
+	DBUSTRACE(("%s: unlink all URBs\n", __FUNCTION__));
+
+#ifdef USBOS_TX_THREAD
+	usbos_info->ctl_state = USBOS_REQUEST_STATE_UNSCHEDULED;
+
+	/* Yield the CPU to TX thread so all pending requests are submitted */
+	while (!list_empty(&usbos_info->usbos_tx_list)) {
+		wake_up_interruptible(&usbos_info->usbos_tx_queue_head);
+		OSL_SLEEP(10);
+	}
+#endif /* USBOS_TX_THREAD */
+
+	/* tell Linux kernel to cancel a single intr, ctl and blk URB */
+	if (usbos_info->intr_urb)
+		USB_UNLINK_URB(usbos_info->intr_urb);
+	if (usbos_info->ctl_urb)
+		USB_UNLINK_URB(usbos_info->ctl_urb);
+	if (usbos_info->blk_urb)
+		USB_UNLINK_URB(usbos_info->blk_urb);
+
+	dbus_usbos_unlink(&usbos_info->req_txpostedq, &usbos_info->txposted_lock);
+	dbus_usbos_unlink(&usbos_info->req_rxpostedq, &usbos_info->rxposted_lock);
+
+	/* Wait until the callbacks for all submitted URBs have been called, because the
+	 * handler needs to know is an USB suspend is in progress.
+	 */
+	SPINWAIT((atomic_read(&usbos_info->txposted) != 0 ||
+		atomic_read(&usbos_info->rxposted) != 0), 10000);
+
+	txposted = atomic_read(&usbos_info->txposted);
+	rxposted = atomic_read(&usbos_info->rxposted);
+	if (txposted != 0 || rxposted != 0) {
+		DBUSERR(("%s ERROR: REQs posted, rx=%d tx=%d!\n",
+			__FUNCTION__, rxposted, txposted));
+	}
+} /* dbus_usbos_cancel_all_urbs */
+
+/** multiple code paths require the bus to stop */
+static void
+dbusos_stop(usbos_info_t *usbos_info)
+{
+	urb_req_t *req;
+	int rxposted;
+	req = NULL;
+	BCM_REFERENCE(req);
+
+	ASSERT(usbos_info);
+
+#ifdef USB_TRIGGER_DEBUG
+	dbus_usbos_ctl_send_debugtrig(usbos_info);
+#endif /* USB_TRIGGER_DEBUG */
+	dbus_usbos_state_change(usbos_info, DBUS_STATE_DOWN);
+
+	dbus_usbos_cancel_all_urbs(usbos_info);
+
+#ifdef USBOS_THREAD
+	/* yield the CPU to rx packet thread */
+	while (1) {
+		if (atomic_read(&usbos_info->usbos_list_cnt) <= 0)	break;
+		wake_up_interruptible(&usbos_info->usbos_queue_head);
+		OSL_SLEEP(3);
+	}
+#endif /* USBOS_THREAD */
+
+	rxposted = atomic_read(&usbos_info->rxposted);
+	if (rxposted > 0) {
+		DBUSERR(("%s ERROR: rx REQs posted=%d in stop!\n", __FUNCTION__,
+			rxposted));
+	}
+
+	ASSERT(atomic_read(&usbos_info->txposted) == 0 && rxposted == 0);
+
+#ifdef DBUS_LINUX_RXDPC
+	/* Stop the dpc thread */
+	if (usbos_info->dpc_pid >= 0) {
+		KILL_PROC(usbos_info->dpc_pid, SIGTERM);
+		wait_for_completion(&usbos_info->dpc_exited);
+	}
+
+	/* Move pending reqs to free queue so they can be freed */
+	while ((req = dbus_usbos_qdeq(&usbos_info->req_rxpendingq,
+		&usbos_info->rxpending_lock)) != NULL) {
+		dbus_usbos_qenq(&usbos_info->req_rxfreeq, req,
+			&usbos_info->rxfree_lock);
+	}
+#endif /* DBUS_LINUX_RXDPC */
+} /* dbusos_stop */
+
+#if defined(USB_SUSPEND_AVAILABLE)
+
+/**
+ * Linux kernel sports a 'USB auto suspend' feature. See: http://lwn.net/Articles/373550/
+ * The suspend method is called by the Linux kernel to warn the driver that the device is going to
+ * be suspended.  If the driver returns a negative error code, the suspend will be aborted. If the
+ * driver returns 0, it must cancel all outstanding URBs (usb_kill_urb()) and not submit any more.
+ */
+static int
+dbus_usbos_suspend(struct usb_interface *intf,
+            pm_message_t message)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) g_probe_info.usbos_info;
+	int err = 0;
+
+	printf("%s Enter\n", __FUNCTION__);
+
+	/* DHD for full dongle model */
+	g_probe_info.suspend_state = USBOS_SUSPEND_STATE_SUSPEND_PENDING;
+	if (drvinfo.suspend && disc_arg)
+		err = drvinfo.suspend(disc_arg);
+	if (err) {
+		printf("%s: err=%d\n", __FUNCTION__, err);
+//		g_probe_info.suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE;
+//		return err;
+	}
+	usbos_info->pub->busstate = DBUS_STATE_SLEEP;
+
+	dbus_usbos_cancel_all_urbs((usbos_info_t*)g_probe_info.usbos_info);
+	g_probe_info.suspend_state = USBOS_SUSPEND_STATE_SUSPENDED;
+
+	printf("%s Exit err=%d\n", __FUNCTION__, err);
+	return err;
+}
+
+/**
+ * The resume method is called to tell the driver that the device has been resumed and the driver
+ * can return to normal operation.  URBs may once more be submitted.
+ */
+static int
+dbus_usbos_resume(struct usb_interface *intf)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) g_probe_info.usbos_info;
+
+	printf("%s Enter\n", __FUNCTION__);
+
+	g_probe_info.suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE;
+	if (drvinfo.resume && disc_arg)
+		drvinfo.resume(disc_arg);
+	usbos_info->pub->busstate = DBUS_STATE_UP;
+
+	printf("%s Exit\n", __FUNCTION__);
+	return 0;
+}
+
+/**
+* This function is directly called by the Linux kernel, when the suspended device has been reset
+* instead of being resumed
+*/
+static int
+dbus_usbos_reset_resume(struct usb_interface *intf)
+{
+	printf("%s Enter\n", __FUNCTION__);
+
+#ifdef KEEPIF_ON_DEVICE_RESET
+	if (g_probe_info.keepif_on_devreset) {
+		atomic_set(&g_probe_info.usbdev_stat, USB_DEVICE_RESETTED);
+		wake_up_interruptible(&g_probe_info.usbreset_queue_head);
+	} else
+#endif /* KEEPIF_ON_DEVICE_RESET */
+	{
+		g_probe_info.suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE;
+		if (drvinfo.resume && disc_arg)
+			drvinfo.resume(disc_arg);
+	}
+
+	printf("%s Exit\n", __FUNCTION__);
+	return 0;
+}
+
+#endif /* USB_SUSPEND_AVAILABLE */
+
+/**
+ * Called by Linux kernel at initialization time, kernel wants to know if our driver will accept the
+ * caller supplied USB interface. Note that USB drivers are bound to interfaces, and not to USB
+ * devices.
+ */
+#ifdef KERNEL26
+#define DBUS_USBOS_PROBE() static int dbus_usbos_probe(struct usb_interface *intf, const struct usb_device_id *id)
+#define DBUS_USBOS_DISCONNECT() static void dbus_usbos_disconnect(struct usb_interface *intf)
+#else
+#define DBUS_USBOS_PROBE() static void * dbus_usbos_probe(struct usb_device *usb, unsigned int ifnum, const struct usb_device_id *id)
+#define DBUS_USBOS_DISCONNECT() static void dbus_usbos_disconnect(struct usb_device *usb, void *ptr)
+#endif /* KERNEL26 */
+
+DBUS_USBOS_PROBE()
+{
+	int ep;
+	struct usb_endpoint_descriptor *endpoint;
+	int ret = 0;
+#ifdef KERNEL26
+	struct usb_device *usb = interface_to_usbdev(intf);
+#else
+	int claimed = 0;
+#endif
+	int num_of_eps;
+#ifdef BCMUSBDEV_COMPOSITE
+	int wlan_if = -1;
+	bool intr_ep = FALSE;
+#endif /* BCMUSBDEV_COMPOSITE */
+	wifi_adapter_info_t *adapter;
+
+	DHD_MUTEX_LOCK();
+
+	DBUSERR(("%s: bus num(busnum)=%d, slot num (portnum)=%d\n", __FUNCTION__,
+		usb->bus->busnum, usb->portnum));
+	adapter = dhd_wifi_platform_attach_adapter(USB_BUS, usb->bus->busnum,
+		usb->portnum, WIFI_STATUS_POWER_ON);
+	if (adapter == NULL) {
+		DBUSERR(("%s: can't find adapter info for this chip\n", __FUNCTION__));
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+#ifdef BCMUSBDEV_COMPOSITE
+	wlan_if = dbus_usbos_intf_wlan(usb);
+#ifdef KERNEL26
+	if ((wlan_if >= 0) && (IFPTR(usb, wlan_if) == intf))
+#else
+	if (wlan_if == ifnum)
+#endif /* KERNEL26 */
+	{
+#endif /* BCMUSBDEV_COMPOSITE */
+		g_probe_info.usb = usb;
+		g_probe_info.dldone = TRUE;
+#ifdef BCMUSBDEV_COMPOSITE
+	} else {
+		DBUSTRACE(("dbus_usbos_probe: skip probe for non WLAN interface\n"));
+		ret = BCME_UNSUPPORTED;
+		goto fail;
+	}
+#endif /* BCMUSBDEV_COMPOSITE */
+
+#ifdef KERNEL26
+	g_probe_info.intf = intf;
+#endif /* KERNEL26 */
+
+#ifdef BCMUSBDEV_COMPOSITE
+	if (IFDESC(usb, wlan_if).bInterfaceNumber > USB_COMPIF_MAX)
+#else
+	if (IFDESC(usb, CONTROL_IF).bInterfaceNumber)
+#endif /* BCMUSBDEV_COMPOSITE */
+	{
+		ret = -1;
+		goto fail;
+	}
+	if (id != NULL) {
+		g_probe_info.vid = id->idVendor;
+		g_probe_info.pid = id->idProduct;
+	}
+
+#ifdef KERNEL26
+	usb_set_intfdata(intf, &g_probe_info);
+#endif
+
+	/* Check that the device supports only one configuration */
+	if (usb->descriptor.bNumConfigurations != 1) {
+		ret = -1;
+		goto fail;
+	}
+
+	if (usb->descriptor.bDeviceClass != USB_CLASS_VENDOR_SPEC) {
+#ifdef BCMUSBDEV_COMPOSITE
+		if ((usb->descriptor.bDeviceClass != USB_CLASS_MISC) &&
+			(usb->descriptor.bDeviceClass != USB_CLASS_WIRELESS)) {
+#endif /* BCMUSBDEV_COMPOSITE */
+			ret = -1;
+			goto fail;
+#ifdef BCMUSBDEV_COMPOSITE
+		}
+#endif /* BCMUSBDEV_COMPOSITE */
+	}
+
+	/*
+	 * Only the BDC interface configuration is supported:
+	 *	Device class: USB_CLASS_VENDOR_SPEC
+	 *	if0 class: USB_CLASS_VENDOR_SPEC
+	 *	if0/ep0: control
+	 *	if0/ep1: bulk in
+	 *	if0/ep2: bulk out (ok if swapped with bulk in)
+	 */
+	if (CONFIGDESC(usb)->bNumInterfaces != 1) {
+#ifdef BCMUSBDEV_COMPOSITE
+		if (CONFIGDESC(usb)->bNumInterfaces > USB_COMPIF_MAX) {
+#endif /* BCMUSBDEV_COMPOSITE */
+			ret = -1;
+			goto fail;
+#ifdef BCMUSBDEV_COMPOSITE
+		}
+#endif /* BCMUSBDEV_COMPOSITE */
+	}
+
+	/* Check interface */
+#ifndef KERNEL26
+#ifdef BCMUSBDEV_COMPOSITE
+	if (usb_interface_claimed(IFPTR(usb, wlan_if)))
+#else
+	if (usb_interface_claimed(IFPTR(usb, CONTROL_IF)))
+#endif /* BCMUSBDEV_COMPOSITE */
+	{
+		ret = -1;
+		goto fail;
+	}
+#endif /* !KERNEL26 */
+
+#ifdef BCMUSBDEV_COMPOSITE
+	if ((IFDESC(usb, wlan_if).bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
+		IFDESC(usb, wlan_if).bInterfaceSubClass != 2 ||
+		IFDESC(usb, wlan_if).bInterfaceProtocol != 0xff) &&
+		(IFDESC(usb, wlan_if).bInterfaceClass != USB_CLASS_MISC ||
+		IFDESC(usb, wlan_if).bInterfaceSubClass != USB_SUBCLASS_COMMON ||
+		IFDESC(usb, wlan_if).bInterfaceProtocol != USB_PROTO_IAD))
+#else
+	if (IFDESC(usb, CONTROL_IF).bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
+		IFDESC(usb, CONTROL_IF).bInterfaceSubClass != 2 ||
+		IFDESC(usb, CONTROL_IF).bInterfaceProtocol != 0xff)
+#endif /* BCMUSBDEV_COMPOSITE */
+	{
+#ifdef BCMUSBDEV_COMPOSITE
+			DBUSERR(("%s: invalid control interface: class %d, subclass %d, proto %d\n",
+				__FUNCTION__,
+				IFDESC(usb, wlan_if).bInterfaceClass,
+				IFDESC(usb, wlan_if).bInterfaceSubClass,
+				IFDESC(usb, wlan_if).bInterfaceProtocol));
+#else
+			DBUSERR(("%s: invalid control interface: class %d, subclass %d, proto %d\n",
+				__FUNCTION__,
+				IFDESC(usb, CONTROL_IF).bInterfaceClass,
+				IFDESC(usb, CONTROL_IF).bInterfaceSubClass,
+				IFDESC(usb, CONTROL_IF).bInterfaceProtocol));
+#endif /* BCMUSBDEV_COMPOSITE */
+			ret = -1;
+			goto fail;
+	}
+
+	/* Check control endpoint */
+#ifdef BCMUSBDEV_COMPOSITE
+	endpoint = &IFEPDESC(usb, wlan_if, 0);
+#else
+	endpoint = &IFEPDESC(usb, CONTROL_IF, 0);
+#endif /* BCMUSBDEV_COMPOSITE */
+	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
+#ifdef BCMUSBDEV_COMPOSITE
+		if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
+			USB_ENDPOINT_XFER_BULK) {
+#endif /* BCMUSBDEV_COMPOSITE */
+			DBUSERR(("%s: invalid control endpoint %d\n",
+				__FUNCTION__, endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK));
+			ret = -1;
+			goto fail;
+#ifdef BCMUSBDEV_COMPOSITE
+		}
+#endif /* BCMUSBDEV_COMPOSITE */
+	}
+
+#ifdef BCMUSBDEV_COMPOSITE
+	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
+#endif /* BCMUSBDEV_COMPOSITE */
+		g_probe_info.intr_pipe =
+			usb_rcvintpipe(usb, endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+#ifdef BCMUSBDEV_COMPOSITE
+		intr_ep = TRUE;
+	}
+#endif /* BCMUSBDEV_COMPOSITE */
+
+#ifndef KERNEL26
+	/* Claim interface */
+#ifdef BCMUSBDEV_COMPOSITE
+	usb_driver_claim_interface(&dbus_usbdev, IFPTR(usb, wlan_if), &g_probe_info);
+#else
+	usb_driver_claim_interface(&dbus_usbdev, IFPTR(usb, CONTROL_IF), &g_probe_info);
+#endif /* BCMUSBDEV_COMPOSITE */
+	claimed = 1;
+#endif /* !KERNEL26 */
+	g_probe_info.rx_pipe = 0;
+	g_probe_info.rx_pipe2 = 0;
+	g_probe_info.tx_pipe = 0;
+#ifdef BCMUSBDEV_COMPOSITE
+	if (intr_ep)
+		ep = 1;
+	else
+		ep = 0;
+	num_of_eps = IFDESC(usb, wlan_if).bNumEndpoints - 1;
+#else
+	num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1;
+#endif /* BCMUSBDEV_COMPOSITE */
+
+	if ((num_of_eps != 2) && (num_of_eps != 3)) {
+#ifdef BCMUSBDEV_COMPOSITE
+		if (num_of_eps > 7)
+#endif /* BCMUSBDEV_COMPOSITE */
+			ASSERT(0);
+	}
+	/* Check data endpoints and get pipes */
+#ifdef BCMUSBDEV_COMPOSITE
+	for (; ep <= num_of_eps; ep++)
+#else
+	for (ep = 1; ep <= num_of_eps; ep++)
+#endif /* BCMUSBDEV_COMPOSITE */
+	{
+#ifdef BCMUSBDEV_COMPOSITE
+		endpoint = &IFEPDESC(usb, wlan_if, ep);
+#else
+		endpoint = &IFEPDESC(usb, BULK_IF, ep);
+#endif /* BCMUSBDEV_COMPOSITE */
+		if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
+		    USB_ENDPOINT_XFER_BULK) {
+			DBUSERR(("%s: invalid data endpoint %d\n",
+			           __FUNCTION__, ep));
+			ret = -1;
+			goto fail;
+		}
+
+		if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
+			/* direction: dongle->host */
+			if (!g_probe_info.rx_pipe) {
+				g_probe_info.rx_pipe = usb_rcvbulkpipe(usb,
+					(endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK));
+			} else {
+				g_probe_info.rx_pipe2 = usb_rcvbulkpipe(usb,
+					(endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK));
+			}
+
+		} else
+			g_probe_info.tx_pipe = usb_sndbulkpipe(usb, (endpoint->bEndpointAddress &
+			     USB_ENDPOINT_NUMBER_MASK));
+	}
+
+	/* Allocate interrupt URB and data buffer */
+	/* RNDIS says 8-byte intr, our old drivers used 4-byte */
+#ifdef BCMUSBDEV_COMPOSITE
+	g_probe_info.intr_size = (IFEPDESC(usb, wlan_if, 0).wMaxPacketSize == 16) ? 8 : 4;
+	g_probe_info.interval = IFEPDESC(usb, wlan_if, 0).bInterval;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 21))
+	usb->quirks |= USB_QUIRK_NO_SET_INTF;
+#endif
+#else
+	g_probe_info.intr_size = (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == 16) ? 8 : 4;
+	g_probe_info.interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
+#endif /* BCMUSBDEV_COMPOSITE */
+
+#ifndef KERNEL26
+	/* usb_fill_int_urb does the interval decoding in 2.6 */
+	if (usb->speed == USB_SPEED_HIGH)
+		g_probe_info.interval = 1 << (g_probe_info.interval - 1);
+#endif
+	if (usb->speed == USB_SPEED_SUPER) {
+		g_probe_info.device_speed = SUPER_SPEED;
+		DBUSERR(("super speed device detected\n"));
+	} else if (usb->speed == USB_SPEED_HIGH) {
+		g_probe_info.device_speed = HIGH_SPEED;
+		DBUSERR(("high speed device detected\n"));
+	} else {
+		g_probe_info.device_speed = FULL_SPEED;
+		DBUSERR(("full speed device detected\n"));
+	}
+#ifdef KEEPIF_ON_DEVICE_RESET
+	if (g_probe_info.keepif_on_devreset && g_probe_info.dev_resetted) {
+		atomic_set(&g_probe_info.usbdev_stat, USB_DEVICE_PROBED);
+		wake_up_interruptible(&g_probe_info.usbreset_queue_head);
+	} else
+#endif /* KEEPIF_ON_DEVICE_RESET */
+	if (g_probe_info.dereged == FALSE && drvinfo.probe) {
+		disc_arg = drvinfo.probe(usb->bus->busnum, usb->portnum, 0);
+	}
+
+	g_probe_info.disc_cb_done = FALSE;
+
+#ifdef KERNEL26
+	intf->needs_remote_wakeup = 1;
+#endif /* KERNEL26 */
+	DHD_MUTEX_UNLOCK();
+
+	/* Success */
+#ifdef KERNEL26
+	return DBUS_OK;
+#else
+	usb_inc_dev_use(usb);
+	return &g_probe_info;
+#endif
+
+fail:
+	printf("%s: Exit ret=%d\n", __FUNCTION__, ret);
+#ifdef BCMUSBDEV_COMPOSITE
+	if (ret != BCME_UNSUPPORTED)
+#endif /* BCMUSBDEV_COMPOSITE */
+		DBUSERR(("%s: failed with errno %d\n", __FUNCTION__, ret));
+#ifndef KERNEL26
+	if (claimed)
+#ifdef BCMUSBDEV_COMPOSITE
+		usb_driver_release_interface(&dbus_usbdev, IFPTR(usb, wlan_if));
+#else
+		usb_driver_release_interface(&dbus_usbdev, IFPTR(usb, CONTROL_IF));
+#endif /* BCMUSBDEV_COMPOSITE */
+#endif /* !KERNEL26 */
+
+	DHD_MUTEX_UNLOCK();
+#ifdef KERNEL26
+	usb_set_intfdata(intf, NULL);
+	return ret;
+#else
+	return NULL;
+#endif
+} /* dbus_usbos_probe */
+
+/** Called by Linux kernel, is the counter part of dbus_usbos_probe() */
+DBUS_USBOS_DISCONNECT()
+{
+#ifdef KERNEL26
+	struct usb_device *usb = interface_to_usbdev(intf);
+	probe_info_t *probe_usb_init_data = usb_get_intfdata(intf);
+#else
+	probe_info_t *probe_usb_init_data = (probe_info_t *) ptr;
+#endif
+	usbos_info_t *usbos_info;
+
+	DHD_MUTEX_LOCK();
+
+	DBUSERR(("%s: bus num(busnum)=%d, slot num (portnum)=%d\n", __FUNCTION__,
+		usb->bus->busnum, usb->portnum));
+
+	if (probe_usb_init_data) {
+		usbos_info = (usbos_info_t *) probe_usb_init_data->usbos_info;
+		if (usbos_info) {
+			if ((probe_usb_init_data->dereged == FALSE) && drvinfo.remove && disc_arg) {
+				bool remove_if = TRUE;
+#ifdef KEEPIF_ON_DEVICE_RESET
+				if (g_probe_info.keepif_on_devreset)
+					remove_if = FALSE;
+#endif /* KEEPIF_ON_DEVICE_RESET */
+				if (remove_if) {
+					drvinfo.remove(disc_arg);
+					disc_arg = NULL;
+					probe_usb_init_data->disc_cb_done = TRUE;
+				}
+			}
+		}
+	}
+
+	if (usb) {
+#ifndef KERNEL26
+#ifdef BCMUSBDEV_COMPOSITE
+		usb_driver_release_interface(&dbus_usbdev, IFPTR(usb, wlan_if));
+#else
+		usb_driver_release_interface(&dbus_usbdev, IFPTR(usb, CONTROL_IF));
+#endif /* BCMUSBDEV_COMPOSITE */
+		usb_dec_dev_use(usb);
+#endif /* !KERNEL26 */
+	}
+
+#ifdef KEEPIF_ON_DEVICE_RESET
+	if (g_probe_info.keepif_on_devreset && (!g_probe_info.dev_resetted)) {
+		atomic_set(&g_probe_info.usbdev_stat, USB_DEVICE_DISCONNECTED);
+		wake_up_interruptible(&g_probe_info.usbreset_queue_head);
+	}
+#endif /* KEEPIF_ON_DEVICE_RESET */
+
+	DHD_MUTEX_UNLOCK();
+} /* dbus_usbos_disconnect */
+
+#define LOOPBACK_PKT_START 0xBABE1234
+
+bool is_loopback_pkt(void *buf)
+{
+
+	uint32 *buf_ptr = (uint32 *) buf;
+
+	if (*buf_ptr == LOOPBACK_PKT_START)
+		return TRUE;
+	return FALSE;
+
+}
+
+int matches_loopback_pkt(void *buf)
+{
+	int i, j;
+	unsigned char *cbuf = (unsigned char *) buf;
+
+	for (i = 4; i < loopback_size; i++) {
+		if (cbuf[i] != (i % 256)) {
+			printf("%s: mismatch at i=%d %d : ", __FUNCTION__, i, cbuf[i]);
+			for (j = i; ((j < i+ 16) && (j < loopback_size)); j++) {
+				printf("%d ", cbuf[j]);
+			}
+			printf("\n");
+			return 0;
+		}
+	}
+	loopback_rx_cnt++;
+	return 1;
+}
+
+int dbus_usbos_loopback_tx(void *usbos_info_ptr, int cnt, int size)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) usbos_info_ptr;
+	unsigned char *buf;
+	int j;
+	void* p = NULL;
+	int rc, last_rx_cnt;
+	int tx_failed_cnt;
+	int max_size = 1650;
+	int usb_packet_size = 512;
+	int min_packet_size = 10;
+
+	if (size % usb_packet_size == 0) {
+		size = size - 1;
+		DBUSERR(("%s: overriding size=%d \n", __FUNCTION__, size));
+	}
+
+	if (size < min_packet_size) {
+		size = min_packet_size;
+		DBUSERR(("%s: overriding size=%d\n", __FUNCTION__, min_packet_size));
+	}
+	if (size > max_size) {
+		size = max_size;
+		DBUSERR(("%s: overriding size=%d\n", __FUNCTION__, max_size));
+	}
+
+	loopback_tx_cnt = 0;
+	loopback_rx_cnt = 0;
+	tx_failed_cnt = 0;
+	loopback_size   = size;
+
+	while (loopback_tx_cnt < cnt) {
+		uint32 *x;
+		int pkt_size = loopback_size;
+
+		p = PKTGET(usbos_info->pub->osh, pkt_size, TRUE);
+		if (p == NULL) {
+			DBUSERR(("%s:%d Failed to allocate packet sz=%d\n",
+			       __FUNCTION__, __LINE__, pkt_size));
+			return BCME_ERROR;
+		}
+		x = (uint32*) PKTDATA(usbos_info->pub->osh, p);
+		*x = LOOPBACK_PKT_START;
+		buf = (unsigned char*) x;
+		for (j = 4; j < pkt_size; j++) {
+			buf[j] = j % 256;
+		}
+		rc = dbus_send_buf(usbos_info->pub, buf, pkt_size, p);
+		if (rc != BCME_OK) {
+			DBUSERR(("%s:%d Freeing packet \n", __FUNCTION__, __LINE__));
+			PKTFREE(usbos_info->pub->osh, p, TRUE);
+			dbus_usbos_wait(usbos_info, 1);
+			tx_failed_cnt++;
+		} else {
+			loopback_tx_cnt++;
+			tx_failed_cnt = 0;
+		}
+		if (tx_failed_cnt == 5) {
+			DBUSERR(("%s : Failed to send loopback packets cnt=%d loopback_tx_cnt=%d\n",
+			 __FUNCTION__, cnt, loopback_tx_cnt));
+			break;
+		}
+	}
+	printf("Transmitted %d loopback packets of size %d\n", loopback_tx_cnt, loopback_size);
+
+	last_rx_cnt = loopback_rx_cnt;
+	while (loopback_rx_cnt < loopback_tx_cnt) {
+		dbus_usbos_wait(usbos_info, 1);
+		if (loopback_rx_cnt <= last_rx_cnt) {
+			DBUSERR(("%s: Matched rx cnt stuck at %d \n", __FUNCTION__, last_rx_cnt));
+			return BCME_ERROR;
+		}
+		last_rx_cnt = loopback_rx_cnt;
+	}
+	printf("Received %d loopback packets of size %d\n", loopback_tx_cnt, loopback_size);
+
+	return BCME_OK;
+} /* dbus_usbos_loopback_tx */
+
+/**
+ * Higher layer (dbus_usb.c) wants to transmit an I/O Request Block
+ *     @param[in] txirb txirb->pkt, if non-zero, contains a single or a chain of packets
+ */
+static int
+dbus_usbos_intf_send_irb(void *bus, dbus_irb_tx_t *txirb)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+	urb_req_t *req, *req_zlp = NULL;
+	int ret = DBUS_OK;
+	unsigned long flags;
+	void *pkt;
+	uint32 buffer_length;
+	uint8 *buf;
+
+	if ((usbos_info == NULL) || !usbos_info->tx_pipe) {
+		return DBUS_ERR;
+	}
+
+	if (txirb->pkt != NULL) {
+		buffer_length = pkttotlen(usbos_info->pub->osh, txirb->pkt);
+		/* In case of multiple packets the values below may be overwritten */
+		txirb->send_buf = NULL;
+		buf = PKTDATA(usbos_info->pub->osh, txirb->pkt);
+	} else { /* txirb->buf != NULL */
+		ASSERT(txirb->buf != NULL);
+		ASSERT(txirb->send_buf == NULL);
+		buffer_length = txirb->len;
+		buf = txirb->buf;
+	}
+
+	if (!(req = dbus_usbos_qdeq(&usbos_info->req_txfreeq, &usbos_info->txfree_lock))) {
+		DBUSERR(("%s No free URB!\n", __FUNCTION__));
+		return DBUS_ERR_TXDROP;
+	}
+
+	/* If not using standard Linux kernel functionality for handling Zero Length Packet(ZLP),
+	 * the dbus needs to generate ZLP when length is multiple of MaxPacketSize.
+	 */
+#ifndef WL_URB_ZPKT
+	if (!(buffer_length % usbos_info->maxps)) {
+		if (!(req_zlp =
+			dbus_usbos_qdeq(&usbos_info->req_txfreeq, &usbos_info->txfree_lock))) {
+			DBUSERR(("%s No free URB for ZLP!\n", __FUNCTION__));
+			dbus_usbos_qenq(&usbos_info->req_txfreeq, req, &usbos_info->txfree_lock);
+			return DBUS_ERR_TXDROP;
+		}
+
+		/* No txirb, so that dbus_usbos_send_complete can differentiate between
+		 * DATA and ZLP.
+		 */
+		req_zlp->arg = NULL;
+		req_zlp->usbinfo = usbos_info;
+		req_zlp->buf_len = 0;
+
+		usb_fill_bulk_urb(req_zlp->urb, usbos_info->usb, usbos_info->tx_pipe, NULL,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
+			0, (void *)dbus_usbos_send_complete, req_zlp);
+#else
+			0, (usb_complete_t)dbus_usbos_send_complete, req_zlp);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) */
+
+		req_zlp->urb->transfer_flags |= URB_QUEUE_BULK;
+	}
+#endif /* !WL_URB_ZPKT */
+
+#ifndef USBOS_TX_THREAD
+	/* Disable USB autosuspend until this request completes, request USB resume if needed.
+	 * Because this call runs asynchronously, there is no guarantee the bus is resumed before
+	 * the URB is submitted, and the URB might be dropped. Use USBOS_TX_THREAD to avoid
+	 * this.
+	 */
+	USB_AUTOPM_GET_INTERFACE_ASYNC(g_probe_info.intf);
+#endif /* !USBOS_TX_THREAD */
+
+	spin_lock_irqsave(&usbos_info->txlock, flags);
+
+	req->arg = txirb;
+	req->usbinfo = usbos_info;
+	req->buf_len = 0;
+
+	/* Prepare the URB */
+	if (txirb->pkt != NULL) {
+		uint32 pktlen;
+		uint8 *transfer_buf;
+
+		/* For multiple packets, allocate contiguous buffer and copy packet data to it */
+		if (PKTNEXT(usbos_info->pub->osh, txirb->pkt)) {
+			transfer_buf = MALLOC(usbos_info->pub->osh, buffer_length);
+			if (!transfer_buf) {
+				ret = DBUS_ERR_TXDROP;
+				DBUSERR(("fail to alloc to usb buffer\n"));
+				goto fail;
+			}
+
+			pkt = txirb->pkt;
+			txirb->send_buf = transfer_buf;
+			req->buf_len = buffer_length;
+
+			while (pkt) {
+				pktlen = PKTLEN(usbos_info->pub->osh, pkt);
+				bcopy(PKTDATA(usbos_info->pub->osh, pkt), transfer_buf, pktlen);
+				transfer_buf += pktlen;
+				pkt = PKTNEXT(usbos_info->pub->osh, pkt);
+			}
+
+			ASSERT(((uint8 *) txirb->send_buf + buffer_length) == transfer_buf);
+
+			/* Overwrite buf pointer with pointer to allocated contiguous transfer_buf
+			 */
+			buf = txirb->send_buf;
+		}
+	}
+
+	usb_fill_bulk_urb(req->urb, usbos_info->usb, usbos_info->tx_pipe, buf,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
+		buffer_length, (void *)dbus_usbos_send_complete, req);
+#else
+		buffer_length, (usb_complete_t)dbus_usbos_send_complete, req);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) */
+
+	req->urb->transfer_flags |= URB_QUEUE_BULK;
+
+#ifdef USBOS_TX_THREAD
+	/* Enqueue TX request, the TX thread will resume the bus if needed and submit
+	 * it asynchronously
+	 */
+	dbus_usbos_qenq(&usbos_info->usbos_tx_list, req, &usbos_info->usbos_tx_list_lock);
+	if (req_zlp != NULL) {
+		dbus_usbos_qenq(&usbos_info->usbos_tx_list, req_zlp,
+			&usbos_info->usbos_tx_list_lock);
+	}
+	spin_unlock_irqrestore(&usbos_info->txlock, flags);
+
+	wake_up_interruptible(&usbos_info->usbos_tx_queue_head);
+	return DBUS_OK;
+#else
+	if ((ret = USB_SUBMIT_URB(req->urb))) {
+		ret = DBUS_ERR_TXDROP;
+		goto fail;
+	}
+
+	dbus_usbos_qenq(&usbos_info->req_txpostedq, req, &usbos_info->txposted_lock);
+	atomic_inc(&usbos_info->txposted);
+
+	if (req_zlp != NULL) {
+		if ((ret = USB_SUBMIT_URB(req_zlp->urb))) {
+			DBUSERR(("failed to submit ZLP URB!\n"));
+			ASSERT(0);
+			ret = DBUS_ERR_TXDROP;
+			goto fail2;
+		}
+
+		dbus_usbos_qenq(&usbos_info->req_txpostedq, req_zlp, &usbos_info->txposted_lock);
+		/* Also increment txposted for zlp packet, as it will be decremented in
+		 * dbus_usbos_send_complete()
+		 */
+		atomic_inc(&usbos_info->txposted);
+	}
+
+	spin_unlock_irqrestore(&usbos_info->txlock, flags);
+	return DBUS_OK;
+#endif /* USBOS_TX_THREAD */
+
+fail:
+	if (txirb->send_buf != NULL) {
+		MFREE(usbos_info->pub->osh, txirb->send_buf, req->buf_len);
+		req->buf_len = 0;
+	}
+	dbus_usbos_qenq(&usbos_info->req_txfreeq, req, &usbos_info->txfree_lock);
+#ifndef USBOS_TX_THREAD
+fail2:
+#endif
+	if (req_zlp != NULL) {
+		dbus_usbos_qenq(&usbos_info->req_txfreeq, req_zlp, &usbos_info->txfree_lock);
+	}
+
+	spin_unlock_irqrestore(&usbos_info->txlock, flags);
+
+#ifndef USBOS_TX_THREAD
+	USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
+#endif /* !USBOS_TX_THREAD */
+
+	return ret;
+} /* dbus_usbos_intf_send_irb */
+
+/** Higher layer (dbus_usb.c) recycles a received (and used) packet. */
+static int
+dbus_usbos_intf_recv_irb(void *bus, dbus_irb_rx_t *rxirb)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+	int ret = DBUS_OK;
+
+	if (usbos_info == NULL)
+		return DBUS_ERR;
+
+	ret = dbus_usbos_recv_urb_submit(usbos_info, rxirb, 0);
+	return ret;
+}
+
+static int
+dbus_usbos_intf_recv_irb_from_ep(void *bus, dbus_irb_rx_t *rxirb, uint32 ep_idx)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+	int ret = DBUS_OK;
+
+	if (usbos_info == NULL)
+		return DBUS_ERR;
+
+#ifdef INTR_EP_ENABLE
+		/* By specifying the ep_idx value of 0xff, the cdc layer is asking to
+		* submit an interrupt URB
+		*/
+		if (rxirb == NULL && ep_idx == 0xff) {
+			/* submit intr URB */
+			if ((ret = USB_SUBMIT_URB(usbos_info->intr_urb)) < 0) {
+				DBUSERR(("%s intr USB_SUBMIT_URB failed, status %d\n",
+					__FUNCTION__, ret));
+			}
+			return ret;
+		}
+#else
+		if (rxirb == NULL) {
+			return DBUS_ERR;
+		}
+#endif /* INTR_EP_ENABLE */
+
+	ret = dbus_usbos_recv_urb_submit(usbos_info, rxirb, ep_idx);
+	return ret;
+}
+
+/** Higher layer (dbus_usb.c) want to cancel an IRB */
+static int
+dbus_usbos_intf_cancel_irb(void *bus, dbus_irb_tx_t *txirb)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+
+	if (usbos_info == NULL)
+		return DBUS_ERR;
+
+	/* : Need to implement */
+	return DBUS_ERR;
+}
+
+/** Only one CTL transfer can be pending at any time. This function may block. */
+static int
+dbus_usbos_intf_send_ctl(void *bus, uint8 *buf, int len)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+	uint16 size;
+#ifndef USBOS_TX_THREAD
+	int status;
+#endif /* USBOS_TX_THREAD */
+
+	if ((usbos_info == NULL) || (buf == NULL) || (len == 0))
+		return DBUS_ERR;
+
+	if (usbos_info->ctl_urb == NULL)
+		return DBUS_ERR;
+
+	/* Block until a pending CTL transfer has completed */
+	if (down_interruptible(&usbos_info->ctl_lock) != 0) {
+		return DBUS_ERR_TXCTLFAIL;
+	}
+
+#ifdef USBOS_TX_THREAD
+	ASSERT(usbos_info->ctl_state == USBOS_REQUEST_STATE_UNSCHEDULED);
+#else
+	/* Disable USB autosuspend until this request completes, request USB resume if needed.
+	 * Because this call runs asynchronously, there is no guarantee the bus is resumed before
+	 * the URB is submitted, and the URB might be dropped. Use USBOS_TX_THREAD to avoid
+	 * this.
+	 */
+	USB_AUTOPM_GET_INTERFACE_ASYNC(g_probe_info.intf);
+#endif /* USBOS_TX_THREAD */
+
+	size = len;
+	usbos_info->ctl_write.wLength = cpu_to_le16p(&size);
+	usbos_info->ctl_urb->transfer_buffer_length = size;
+
+	usb_fill_control_urb(usbos_info->ctl_urb,
+		usbos_info->usb,
+		usb_sndctrlpipe(usbos_info->usb, 0),
+		(unsigned char *) &usbos_info->ctl_write,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
+		buf, size, (void *)dbus_usbos_ctlwrite_complete, usbos_info);
+#else
+		buf, size, (usb_complete_t)dbus_usbos_ctlwrite_complete, usbos_info);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) */
+
+#ifdef USBOS_TX_THREAD
+	/* Enqueue CTRL request for transmission by the TX thread. The
+	 * USB bus will first be resumed if needed.
+	 */
+	usbos_info->ctl_state = USBOS_REQUEST_STATE_SCHEDULED;
+	wake_up_interruptible(&usbos_info->usbos_tx_queue_head);
+#else
+	status = USB_SUBMIT_URB(usbos_info->ctl_urb);
+	if (status < 0) {
+		DBUSERR(("%s: usb_submit_urb failed %d\n", __FUNCTION__, status));
+		up(&usbos_info->ctl_lock);
+
+		USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
+
+		return DBUS_ERR_TXCTLFAIL;
+	}
+#endif /* USBOS_TX_THREAD */
+
+	return DBUS_OK;
+} /* dbus_usbos_intf_send_ctl */
+
+/** This function does not seem to be called by anyone, including dbus_usb.c */
+static int
+dbus_usbos_intf_recv_ctl(void *bus, uint8 *buf, int len)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+	int status;
+	uint16 size;
+
+	if ((usbos_info == NULL) || (buf == NULL) || (len == 0))
+		return DBUS_ERR;
+
+	if (usbos_info->ctl_urb == NULL)
+		return DBUS_ERR;
+
+	/* Block until a pending CTRL transfer has completed */
+	if (down_interruptible(&usbos_info->ctl_lock) != 0) {
+		return DBUS_ERR_TXCTLFAIL;
+	}
+
+	/* Disable USB autosuspend until this request completes, request USB resume if needed. */
+	USB_AUTOPM_GET_INTERFACE_ASYNC(g_probe_info.intf);
+
+	size = len;
+	usbos_info->ctl_read.wLength = cpu_to_le16p(&size);
+	usbos_info->ctl_urb->transfer_buffer_length = size;
+
+	if (usbos_info->rxctl_deferrespok) {
+		/* BMAC model */
+		usbos_info->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_VENDOR |
+			USB_RECIP_INTERFACE;
+		usbos_info->ctl_read.bRequest = DL_DEFER_RESP_OK;
+	} else {
+		/* full dongle model */
+		usbos_info->ctl_read.bRequestType = USB_DIR_IN | USB_TYPE_CLASS |
+			USB_RECIP_INTERFACE;
+		usbos_info->ctl_read.bRequest = 1;
+	}
+
+	usb_fill_control_urb(usbos_info->ctl_urb,
+		usbos_info->usb,
+		usb_rcvctrlpipe(usbos_info->usb, 0),
+		(unsigned char *) &usbos_info->ctl_read,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
+		buf, size, (void *)dbus_usbos_ctlread_complete, usbos_info);
+#else
+		buf, size, (usb_complete_t)dbus_usbos_ctlread_complete, usbos_info);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0) */
+
+	status = USB_SUBMIT_URB(usbos_info->ctl_urb);
+	if (status < 0) {
+		DBUSERR(("%s: usb_submit_urb failed %d\n", __FUNCTION__, status));
+		up(&usbos_info->ctl_lock);
+
+		USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
+
+		return DBUS_ERR_RXCTLFAIL;
+	}
+
+	return DBUS_OK;
+}
+
+static int
+dbus_usbos_intf_get_attrib(void *bus, dbus_attrib_t *attrib)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+
+	if ((usbos_info == NULL) || (attrib == NULL))
+		return DBUS_ERR;
+
+	attrib->bustype = DBUS_USB;
+	attrib->vid = g_probe_info.vid;
+	attrib->pid = g_probe_info.pid;
+	attrib->devid = 0x4322;
+
+	/* : Need nchan for both TX and RX?;
+	 * BDC uses one RX pipe and one TX pipe
+	 * RPC may use two RX pipes and one TX pipe?
+	 */
+	attrib->nchan = 1;
+
+	/* MaxPacketSize for USB hi-speed bulk out is 512 bytes
+	 * and 64-bytes for full-speed.
+	 * When sending pkt > MaxPacketSize, Host SW breaks it
+	 * up into multiple packets.
+	 */
+	attrib->mtu = usbos_info->maxps;
+
+	return DBUS_OK;
+}
+
+/** Called by higher layer (dbus_usb.c) when it wants to 'up' the USB interface to the dongle */
+static int
+dbus_usbos_intf_up(void *bus)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+	uint16 ifnum;
+#ifdef BCMUSBDEV_COMPOSITE
+	int wlan_if = 0;
+#endif
+	if (usbos_info == NULL)
+		return DBUS_ERR;
+
+	if (usbos_info->usb == NULL)
+		return DBUS_ERR;
+
+#if defined(INTR_EP_ENABLE)
+	/* full dongle use intr EP, bmac doesn't use it */
+	if (usbos_info->intr_urb) {
+		int ret;
+
+		usb_fill_int_urb(usbos_info->intr_urb, usbos_info->usb,
+			usbos_info->intr_pipe, &usbos_info->intr,
+			usbos_info->intr_size, (usb_complete_t)dbus_usbos_intr_complete,
+			usbos_info, usbos_info->interval);
+
+		if ((ret = USB_SUBMIT_URB(usbos_info->intr_urb))) {
+			DBUSERR(("%s USB_SUBMIT_URB failed with status %d\n", __FUNCTION__, ret));
+			return DBUS_ERR;
+		}
+	}
+#endif	/* INTR_EP_ENABLE */
+
+	if (usbos_info->ctl_urb) {
+		usbos_info->ctl_in_pipe = usb_rcvctrlpipe(usbos_info->usb, 0);
+		usbos_info->ctl_out_pipe = usb_sndctrlpipe(usbos_info->usb, 0);
+
+#ifdef BCMUSBDEV_COMPOSITE
+		wlan_if = dbus_usbos_intf_wlan(usbos_info->usb);
+		ifnum = cpu_to_le16(IFDESC(usbos_info->usb, wlan_if).bInterfaceNumber);
+#else
+		ifnum = cpu_to_le16(IFDESC(usbos_info->usb, CONTROL_IF).bInterfaceNumber);
+#endif /* BCMUSBDEV_COMPOSITE */
+		/* CTL Write */
+		usbos_info->ctl_write.bRequestType =
+			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
+		usbos_info->ctl_write.bRequest = 0;
+		usbos_info->ctl_write.wValue = cpu_to_le16(0);
+		usbos_info->ctl_write.wIndex = cpu_to_le16p(&ifnum);
+
+		/* CTL Read */
+		usbos_info->ctl_read.bRequestType =
+			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
+		usbos_info->ctl_read.bRequest = 1;
+		usbos_info->ctl_read.wValue = cpu_to_le16(0);
+		usbos_info->ctl_read.wIndex = cpu_to_le16p(&ifnum);
+	}
+
+	/* Success, indicate usbos_info is fully up */
+	dbus_usbos_state_change(usbos_info, DBUS_STATE_UP);
+
+	return DBUS_OK;
+} /* dbus_usbos_intf_up */
+
+static int
+dbus_usbos_intf_down(void *bus)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+
+	if (usbos_info == NULL)
+		return DBUS_ERR;
+
+	dbusos_stop(usbos_info);
+	return DBUS_OK;
+}
+
+static int
+dbus_usbos_intf_stop(void *bus)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+
+	if (usbos_info == NULL)
+		return DBUS_ERR;
+
+	dbusos_stop(usbos_info);
+	return DBUS_OK;
+}
+
+#if defined(BCMDBG) || defined(DBUS_LINUX_HIST)
+static void
+dbus_usbos_intf_dump(void *bus, struct bcmstrbuf *b)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+	int i = 0, j = 0, rxposted, txposted;
+
+	rxposted = atomic_read(&usbos_info->rxposted);
+	txposted = atomic_read(&usbos_info->txposted);
+	if (b) {
+		bcm_bprintf(b, "\ndbus linux dump\n");
+		bcm_bprintf(b, "txposted %d rxposted %d\n",
+			txposted, rxposted);
+
+		bcm_bprintf(b, "RXDPC: dpc_cnt %d dpc_pktcnt %d dpc_maxpktcnt %d avg_dpc_pktcnt\n",
+			usbos_info->dpc_cnt, usbos_info->dpc_pktcnt,
+			usbos_info->dpc_maxpktcnt, usbos_info->dpc_cnt ?
+			(usbos_info->dpc_pktcnt/usbos_info->dpc_cnt):1);
+
+		/* Histogram */
+		bcm_bprintf(b, "txposted\n");
+	} else {
+		printf("\ndbus linux dump\n");
+		printf("txposted %d rxposted %d\n",
+			txposted, rxposted);
+		printf("RXDPC: dpc_cnt %d dpc_pktcnt %d dpc_maxpktcnt %d avg_dpc_pktcnt %d\n",
+			usbos_info->dpc_cnt, usbos_info->dpc_pktcnt,
+			usbos_info->dpc_maxpktcnt, usbos_info->dpc_cnt ?
+			(usbos_info->dpc_pktcnt/usbos_info->dpc_cnt):1);
+
+		/* Histogram */
+		printf("txposted\n");
+	}
+
+	for (i = 0; i < usbos_info->pub->ntxq; i++) {
+		if (usbos_info->txposted_hist == NULL) {
+			break;
+		}
+		if (usbos_info->txposted_hist[i]) {
+			if (b)
+				bcm_bprintf(b, "%d: %d ", i, usbos_info->txposted_hist[i]);
+			else
+				printf("%d: %d ", i, usbos_info->txposted_hist[i]);
+			j++;
+			if (j % 10 == 0) {
+				if (b)
+					bcm_bprintf(b, "\n");
+				else
+					printf("\n");
+			}
+		}
+	}
+
+	j = 0;
+	if (b)
+		bcm_bprintf(b, "\nrxposted\n");
+	else
+		printf("\nrxposted\n");
+	for (i = 0; i < usbos_info->pub->nrxq; i++) {
+		if (usbos_info->rxposted_hist == NULL) {
+			break;
+		}
+		if (usbos_info->rxposted_hist[i]) {
+			if (b)
+				bcm_bprintf(b, "%d: %d ", i, usbos_info->rxposted_hist[i]);
+			else
+				printf("%d: %d ", i, usbos_info->rxposted_hist[i]);
+			j++;
+			if (j % 10 == 0) {
+				if (b)
+					bcm_bprintf(b, "\n");
+				else
+					printf("\n");
+			}
+		}
+	}
+	if (b)
+		bcm_bprintf(b, "\n");
+	else
+		printf("\n");
+
+	return;
+}
+#endif /* BCMDBG || DBUS_LINUX_HIST */
+
+/** Called by higher layer (dbus_usb.c) */
+static int
+dbus_usbos_intf_set_config(void *bus, dbus_config_t *config)
+{
+	int err = DBUS_ERR;
+	usbos_info_t* usbos_info = bus;
+
+	if (config->config_id == DBUS_CONFIG_ID_RXCTL_DEFERRES) {
+		usbos_info->rxctl_deferrespok = config->rxctl_deferrespok;
+		err = DBUS_OK;
+	}
+#ifdef KEEPIF_ON_DEVICE_RESET
+	else if (config->config_id == DBUS_CONFIG_ID_KEEPIF_ON_DEVRESET) {
+		g_probe_info.keepif_on_devreset = config->general_param ? TRUE : FALSE;
+		err = DBUS_OK;
+	}
+#endif /* KEEPIF_ON_DEVICE_RESET */
+	else if (config->config_id == DBUS_CONFIG_ID_AGGR_LIMIT) {
+#ifndef BCM_FD_AGGR
+		/* DBUS_CONFIG_ID_AGGR_LIMIT shouldn't be called after probe stage */
+		ASSERT(disc_arg == NULL);
+#endif /* BCM_FD_AGGR */
+		ASSERT(config->aggr_param.maxrxsf > 0);
+		ASSERT(config->aggr_param.maxrxsize > 0);
+		if (config->aggr_param.maxrxsize > usbos_info->rxbuf_len) {
+			int state = usbos_info->pub->busstate;
+			dbus_usbos_unlink(&usbos_info->req_rxpostedq, &usbos_info->rxposted_lock);
+			while (atomic_read(&usbos_info->rxposted)) {
+				DBUSTRACE(("%s rxposted is %d, delay 1 ms\n", __FUNCTION__,
+					atomic_read(&usbos_info->rxposted)));
+				dbus_usbos_wait(usbos_info, 1);
+			}
+			usbos_info->rxbuf_len = config->aggr_param.maxrxsize;
+			dbus_usbos_state_change(usbos_info, state);
+		}
+		err = DBUS_OK;
+	}
+
+	return err;
+}
+
+#ifdef EHCI_FASTPATH_TX
+
+/**
+ * In some cases, the code must submit an URB and wait for its completion.
+ * Related: dbus_usbos_sync_complete()
+ */
+static int
+dbus_usbos_sync_wait(usbos_info_t *usbinfo, uint16 time)
+{
+	int ret;
+	int err = DBUS_OK;
+	int ms = time;
+
+	ret = wait_event_interruptible_timeout(usbinfo->wait,
+		usbinfo->waitdone == TRUE, (ms * HZ / 1000));
+
+	if ((usbinfo->waitdone == FALSE) || (usbinfo->sync_urb_status)) {
+		DBUSERR(("%s: timeout(%d) or urb err=0x%x\n",
+			__FUNCTION__, ret, usbinfo->sync_urb_status));
+		err = DBUS_ERR;
+		BCM_REFERENCE(ret);
+	}
+	usbinfo->waitdone = FALSE;
+	return err;
+}
+
+#endif /* EHCI_FASTPATH_TX */
+
+/** Called by dbus_usb.c when it wants to download firmware into the dongle */
+bool
+dbus_usbos_dl_cmd(usbos_info_t *usbinfo, uint8 cmd, void *buffer, int buflen)
+{
+	int transferred;
+	int index = 0;
+	char *tmpbuf;
+
+	if ((usbinfo == NULL) || (buffer == NULL) || (buflen == 0))
+		return FALSE;
+
+	/* PR82642: Input buffer on stack is causing failures
+	 * on some platforms (STB boxes)
+	 */
+	tmpbuf = (char *) MALLOC(usbinfo->pub->osh, buflen);
+	if (!tmpbuf) {
+		DBUSERR(("%s: Unable to allocate memory \n", __FUNCTION__));
+		return FALSE;
+	}
+
+#ifdef BCM_REQUEST_FW
+	/* Adopted from Windows layer dbus_usb_ndis.c to support USB3.0 core */
+	if (cmd == DL_GO) {
+		index = 1;
+	}
+#endif
+
+	/* Disable USB autosuspend until this request completes, request USB resume if needed. */
+	USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
+
+	transferred = USB_CONTROL_MSG(usbinfo->usb, usb_rcvctrlpipe(usbinfo->usb, 0),
+		cmd, (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE),
+		0, index,
+		(void*) tmpbuf, buflen, USB_CTRL_EP_TIMEOUT);
+	if (transferred == buflen) {
+		memcpy(buffer, tmpbuf, buflen);
+	} else {
+		DBUSERR(("%s: usb_control_msg failed %d\n", __FUNCTION__, transferred));
+	}
+
+	USB_AUTOPM_PUT_INTERFACE(g_probe_info.intf);
+
+	MFREE(usbinfo->pub->osh, tmpbuf, buflen);
+	return (transferred == buflen);
+}
+
+/**
+ * Called by dbus_usb.c when it wants to download a buffer into the dongle (eg as part of the
+ * download process, when writing nvram variables).
+ */
+int
+dbus_write_membytes(usbos_info_t* usbinfo, bool set, uint32 address, uint8 *data, uint size)
+{
+	hwacc_t hwacc;
+	int write_bytes = 4;
+	int status;
+	int retval = 0;
+
+	DBUSTRACE(("Enter:%s\n", __FUNCTION__));
+
+	/* Read is not supported */
+	if (set == 0) {
+		DBUSERR(("Currently read is not supported!!\n"));
+		return -1;
+	}
+
+	USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
+
+	hwacc.cmd = DL_CMD_WRHW;
+	hwacc.addr = address;
+
+	DBUSTRACE(("Address:%x size:%d", hwacc.addr, size));
+	do {
+		if (size >= 4) {
+			write_bytes = 4;
+		} else if (size >= 2) {
+			write_bytes = 2;
+		} else {
+			write_bytes = 1;
+		}
+
+		hwacc.len = write_bytes;
+
+		while (size >= write_bytes) {
+			hwacc.data = *((unsigned int*)data);
+
+			status = USB_CONTROL_MSG(usbinfo->usb, usb_sndctrlpipe(usbinfo->usb, 0),
+				DL_WRHW, (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE),
+				1, 0, (char *)&hwacc, sizeof(hwacc_t), USB_CTRL_EP_TIMEOUT);
+
+			if (status < 0) {
+				retval = -1;
+				DBUSERR((" Ctrl write hwacc failed w/status %d @ address:%x \n",
+					status, hwacc.addr));
+				goto err;
+			}
+
+			hwacc.addr += write_bytes;
+			data += write_bytes;
+			size -= write_bytes;
+		}
+	} while (size > 0);
+
+err:
+	USB_AUTOPM_PUT_INTERFACE(g_probe_info.intf);
+
+	return retval;
+} /* dbus_write_membytes */
+
+int
+dbus_usbos_readreg(void *bus, uint32 regaddr, int datalen, uint32 *value)
+{
+	usbos_info_t *usbinfo = (usbos_info_t *) bus;
+	int ret = DBUS_OK;
+	int transferred;
+	uint32 cmd;
+	hwacc_t	hwacc;
+
+	if (usbinfo == NULL)
+		return DBUS_ERR;
+
+	if (datalen == 1)
+		cmd = DL_RDHW8;
+	else if (datalen == 2)
+		cmd = DL_RDHW16;
+	else
+		cmd = DL_RDHW32;
+
+	USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
+
+	transferred = USB_CONTROL_MSG(usbinfo->usb, usb_rcvctrlpipe(usbinfo->usb, 0),
+		cmd, (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE),
+		(uint16)(regaddr), (uint16)(regaddr >> 16),
+		(void *) &hwacc, sizeof(hwacc_t), USB_CTRL_EP_TIMEOUT);
+
+	if (transferred >= sizeof(hwacc_t)) {
+		*value = hwacc.data;
+	} else {
+		DBUSERR(("%s: usb_control_msg failed %d\n", __FUNCTION__, transferred));
+		ret = DBUS_ERR;
+	}
+
+	USB_AUTOPM_PUT_INTERFACE(g_probe_info.intf);
+
+	return ret;
+} /* dbus_usbos_readreg */
+
+int
+dbus_usbos_writereg(void *bus, uint32 regaddr, int datalen, uint32 data)
+{
+	usbos_info_t *usbinfo = (usbos_info_t *) bus;
+	int ret = DBUS_OK;
+	int transferred;
+	uint32 cmd = DL_WRHW;
+	hwacc_t	hwacc;
+
+	if (usbinfo == NULL)
+		return DBUS_ERR;
+
+	USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
+
+	hwacc.cmd = DL_WRHW;
+	hwacc.addr = regaddr;
+	hwacc.data = data;
+	hwacc.len = datalen;
+
+	transferred = USB_CONTROL_MSG(usbinfo->usb, usb_sndctrlpipe(usbinfo->usb, 0),
+		cmd, (USB_DIR_OUT| USB_TYPE_VENDOR | USB_RECIP_INTERFACE),
+		1, 0,
+		(void *) &hwacc, sizeof(hwacc_t), USB_CTRL_EP_TIMEOUT);
+
+	if (transferred != sizeof(hwacc_t)) {
+		DBUSERR(("%s: usb_control_msg failed %d\n", __FUNCTION__, transferred));
+		ret = DBUS_ERR;
+	}
+
+	USB_AUTOPM_PUT_INTERFACE(g_probe_info.intf);
+
+	return ret;
+}
+
+int
+dbus_usbos_wait(usbos_info_t *usbinfo, uint16 ms)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0))
+	/* : Need to test under 2.6 kernel */
+	if (in_interrupt())
+		mdelay(ms);
+	else
+		msleep_interruptible(ms);
+#else
+	wait_ms(ms);
+#endif
+	return DBUS_OK;
+}
+
+/** Called by dbus_usb.c as part of the firmware download process */
+bool
+dbus_usbos_dl_send_bulk(usbos_info_t *usbinfo, void *buffer, int len)
+{
+#ifdef EHCI_FASTPATH_TX
+	int ret = DBUS_ERR;
+
+	struct ehci_qtd *qtd = optimize_ehci_qtd_alloc(GFP_KERNEL);
+	int token = EHCI_QTD_SET_CERR(3);
+
+	if (qtd == NULL)
+		goto fail;
+
+	optimize_qtd_fill_with_data(usbinfo->pub, 0, qtd, buffer, token, len);
+	optimize_submit_async(qtd, 0);
+
+	ret = dbus_usbos_sync_wait(usbinfo, USB_SYNC_WAIT_TIMEOUT);
+
+	return (ret == DBUS_OK);
+fail:
+	return FALSE;
+#else
+	bool ret = TRUE;
+	int status;
+	int transferred = 0;
+
+	if (usbinfo == NULL)
+		return DBUS_ERR;
+
+	USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
+
+	status = USB_BULK_MSG(usbinfo->usb, usbinfo->tx_pipe,
+		buffer, len,
+		&transferred, USB_BULK_EP_TIMEOUT);
+
+	if (status < 0) {
+		DBUSERR(("%s: usb_bulk_msg failed %d\n", __FUNCTION__, status));
+		ret = FALSE;
+	}
+
+	USB_AUTOPM_PUT_INTERFACE(g_probe_info.intf);
+
+	return ret;
+#endif /* EHCI_FASTPATH_TX */
+}
+
+static bool
+dbus_usbos_intf_recv_needed(void *bus)
+{
+	return FALSE;
+}
+
+/**
+ * Higher layer (dbus_usb.c) wants to execute a function on the condition that the rx spin lock has
+ * been acquired.
+ */
+static void*
+dbus_usbos_intf_exec_rxlock(void *bus, exec_cb_t cb, struct exec_parms *args)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+	void *ret;
+	unsigned long flags;
+
+	if (usbos_info == NULL)
+		return NULL;
+
+	spin_lock_irqsave(&usbos_info->rxlock, flags);
+	ret = cb(args);
+	spin_unlock_irqrestore(&usbos_info->rxlock, flags);
+
+	return ret;
+}
+
+static void*
+dbus_usbos_intf_exec_txlock(void *bus, exec_cb_t cb, struct exec_parms *args)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+	void *ret;
+	unsigned long flags;
+
+	if (usbos_info == NULL)
+		return NULL;
+
+	spin_lock_irqsave(&usbos_info->txlock, flags);
+	ret = cb(args);
+	spin_unlock_irqrestore(&usbos_info->txlock, flags);
+
+	return ret;
+}
+
+/**
+ * if an error condition was detected in this module, the higher DBUS layer (dbus_usb.c) has to
+ * be notified.
+ */
+int
+dbus_usbos_errhandler(void *bus, int err)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+
+	if (usbos_info == NULL)
+		return DBUS_ERR;
+
+	if (usbos_info->cbarg && usbos_info->cbs) {
+		if (usbos_info->cbs->errhandler)
+			usbos_info->cbs->errhandler(usbos_info->cbarg, err);
+	}
+
+	return DBUS_OK;
+}
+
+/**
+ * if a change in bus state was detected in this module, the higher DBUS layer (dbus_usb.c) has to
+ * be notified.
+ */
+int
+dbus_usbos_state_change(void *bus, int state)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) bus;
+
+	if (usbos_info == NULL)
+		return DBUS_ERR;
+
+	if (usbos_info->cbarg && usbos_info->cbs) {
+		if (usbos_info->cbs->state_change)
+			usbos_info->cbs->state_change(usbos_info->cbarg, state);
+	}
+
+	usbos_info->pub->busstate = state;
+	return DBUS_OK;
+}
+
+int
+dbus_bus_osl_register(dbus_driver_t *driver, dbus_intf_t **intf)
+{
+	bzero(&g_probe_info, sizeof(probe_info_t));
+
+	drvinfo = *driver;
+	*intf = &dbus_usbos_intf;
+
+	USB_REGISTER();
+
+#ifdef KEEPIF_ON_DEVICE_RESET
+	init_waitqueue_head(&g_probe_info.usbreset_queue_head);
+	atomic_set(&g_probe_info.usbdev_stat, USB_DEVICE_INIT);
+	g_probe_info.usbreset_kt = kthread_create(dbus_usbos_usbreset_func,
+		&g_probe_info, "usbreset-thread");
+	ASSERT(!IS_ERR(g_probe_info.usbreset_kt));
+	wake_up_process(g_probe_info.usbreset_kt);
+#endif /* KEEPIF_ON_DEVICE_RESET */
+
+	return DBUS_ERR_NODEVICE;
+}
+
+int
+dbus_bus_osl_deregister()
+{
+	g_probe_info.dereged = TRUE;
+
+	DHD_MUTEX_LOCK();
+#ifdef KEEPIF_ON_DEVICE_RESET
+	wake_up_interruptible(&g_probe_info.usbreset_queue_head);
+	kthread_stop(g_probe_info.usbreset_kt);
+#endif /* KEEPIF_ON_DEVICE_RESET */
+
+	if (drvinfo.remove && disc_arg && (g_probe_info.disc_cb_done == FALSE)) {
+		drvinfo.remove(disc_arg);
+		disc_arg = NULL;
+	}
+	DHD_MUTEX_UNLOCK();
+
+	USB_DEREGISTER();
+
+	return DBUS_OK;
+}
+
+static void
+dbus_usbos_init_info(void)
+{
+	usbos_info_t *usbos_info = g_probe_info.usbos_info;
+
+	if (!usbos_info) {
+		return;
+	}
+
+	/* Update USB Info */
+	usbos_info->usb = g_probe_info.usb;
+	usbos_info->rx_pipe = g_probe_info.rx_pipe;
+	usbos_info->rx_pipe2 = g_probe_info.rx_pipe2;
+	usbos_info->tx_pipe = g_probe_info.tx_pipe;
+	usbos_info->intr_pipe = g_probe_info.intr_pipe;
+	usbos_info->intr_size = g_probe_info.intr_size;
+	usbos_info->interval = g_probe_info.interval;
+	usbos_info->pub->device_speed = g_probe_info.device_speed;
+	usbos_info->pub->dev_info = g_probe_info.usb;
+	if (usbos_info->rx_pipe2) {
+		usbos_info->pub->attrib.has_2nd_bulk_in_ep = 1;
+	} else {
+		usbos_info->pub->attrib.has_2nd_bulk_in_ep = 0;
+	}
+
+	if (usbos_info->tx_pipe)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0))
+		usbos_info->maxps = usb_maxpacket(usbos_info->usb,
+			usbos_info->tx_pipe);
+#else
+		usbos_info->maxps = usb_maxpacket(usbos_info->usb,
+			usbos_info->tx_pipe, usb_pipeout(usbos_info->tx_pipe));
+#endif  /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 19, 0) */
+}
+
+void *
+dbus_usbos_intf_attach(dbus_pub_t *pub, void *cbarg, dbus_intf_callbacks_t *cbs)
+{
+	usbos_info_t *usbos_info;
+
+	if (g_probe_info.dldone == FALSE) {
+		DBUSERR(("%s: err device not downloaded!\n", __FUNCTION__));
+		return NULL;
+	}
+
+	/* Sanity check for BUS_INFO() */
+	ASSERT(OFFSETOF(usbos_info_t, pub) == 0);
+
+	usbos_info = MALLOC(pub->osh, sizeof(usbos_info_t));
+	if (usbos_info == NULL)
+		return NULL;
+
+	bzero(usbos_info, sizeof(usbos_info_t));
+
+	usbos_info->pub = pub;
+	usbos_info->cbarg = cbarg;
+	usbos_info->cbs = cbs;
+
+	/* Needed for disconnect() */
+	g_probe_info.usbos_info = usbos_info;
+	dbus_usbos_init_info();
+
+	INIT_LIST_HEAD(&usbos_info->req_rxfreeq);
+	INIT_LIST_HEAD(&usbos_info->req_txfreeq);
+	INIT_LIST_HEAD(&usbos_info->req_rxpostedq);
+	INIT_LIST_HEAD(&usbos_info->req_txpostedq);
+	spin_lock_init(&usbos_info->rxfree_lock);
+	spin_lock_init(&usbos_info->txfree_lock);
+	spin_lock_init(&usbos_info->rxposted_lock);
+	spin_lock_init(&usbos_info->txposted_lock);
+	spin_lock_init(&usbos_info->rxlock);
+	spin_lock_init(&usbos_info->txlock);
+
+	atomic_set(&usbos_info->rxposted, 0);
+	atomic_set(&usbos_info->txposted, 0);
+
+#ifdef DBUS_LINUX_RXDPC
+	INIT_LIST_HEAD(&usbos_info->req_rxpendingq);
+	spin_lock_init(&usbos_info->rxpending_lock);
+#endif /* DBUS_LINUX_RXDPC */
+
+#if defined(BCMDBG) || defined(DBUS_LINUX_HIST)
+	usbos_info->txposted_hist = MALLOC(pub->osh, (usbos_info->pub->ntxq+1) * sizeof(int));
+	if (usbos_info->txposted_hist) {
+		bzero(usbos_info->txposted_hist, (usbos_info->pub->ntxq+1) * sizeof(int));
+	}
+	usbos_info->rxposted_hist = MALLOC(pub->osh, (usbos_info->pub->nrxq+1) * sizeof(int));
+	if (usbos_info->rxposted_hist) {
+		bzero(usbos_info->rxposted_hist, (usbos_info->pub->nrxq+1) * sizeof(int));
+	}
+#endif
+#ifdef USB_DISABLE_INT_EP
+	/* PR 82639  Don't use interrupt EP */
+	usbos_info->intr_urb = NULL;
+#else
+	if (!(usbos_info->intr_urb = USB_ALLOC_URB())) {
+		DBUSERR(("%s: usb_alloc_urb (tx) failed\n", __FUNCTION__));
+		goto fail;
+	}
+#endif
+
+	if (!(usbos_info->ctl_urb = USB_ALLOC_URB())) {
+		DBUSERR(("%s: usb_alloc_urb (tx) failed\n", __FUNCTION__));
+		goto fail;
+	}
+
+	init_waitqueue_head(&usbos_info->wait);
+
+	if (!(usbos_info->blk_urb = USB_ALLOC_URB())) {	/* for embedded image downloading */
+		DBUSERR(("%s: usb_alloc_urb (tx) failed\n", __FUNCTION__));
+		goto fail;
+	}
+
+	usbos_info->rxbuf_len = (uint)usbos_info->pub->rxsize;
+
+#ifdef DBUS_LINUX_RXDPC		/* Initialize DPC thread */
+	sema_init(&usbos_info->dpc_sem, 0);
+	init_completion(&usbos_info->dpc_exited);
+	usbos_info->dpc_pid = kernel_thread(dbus_usbos_dpc_thread, usbos_info, 0);
+	if (usbos_info->dpc_pid < 0) {
+		DBUSERR(("%s: failed to create dpc thread\n", __FUNCTION__));
+		goto fail;
+	}
+#endif /* DBUS_LINUX_RXDPC */
+
+	atomic_set(&usbos_info->txallocated, 0);
+	if (DBUS_OK != dbus_usbos_urbreqs_alloc(usbos_info,
+		usbos_info->pub->ntxq, FALSE)) {
+		goto fail;
+	}
+
+	atomic_set(&usbos_info->rxallocated, 0);
+	if (DBUS_OK != dbus_usbos_urbreqs_alloc(usbos_info,
+#ifdef CTFPOOL
+		usbos_info->pub->nrxq,
+#else
+		MIN(DBUS_USB_RXQUEUE_BATCH_ADD, usbos_info->pub->nrxq),
+#endif
+		TRUE)) {
+		goto fail;
+	}
+
+	sema_init(&usbos_info->ctl_lock, 1);
+
+#ifdef USBOS_THREAD
+	if (dbus_usbos_thread_init(usbos_info) == NULL)
+		goto fail;
+#endif /* USBOS_THREAD */
+
+#ifdef USBOS_TX_THREAD
+	if (dbus_usbos_tx_thread_init(usbos_info) == NULL)
+		goto fail;
+#endif /* USBOS_TX_THREAD */
+
+#if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX)
+	spin_lock_init(&usbos_info->fastpath_lock);
+	if (optimize_init(usbos_info, usbos_info->usb, usbos_info->tx_pipe,
+		usbos_info->rx_pipe, usbos_info->rx_pipe2) != 0) {
+		DBUSERR(("%s: optimize_init failed!\n", __FUNCTION__));
+		goto fail;
+	}
+
+#endif /* EHCI_FASTPATH_TX || EHCI_FASTPATH_RX */
+
+	return (void *) usbos_info;
+fail:
+#ifdef DBUS_LINUX_RXDPC
+	if (usbos_info->dpc_pid >= 0) {
+		KILL_PROC(usbos_info->dpc_pid, SIGTERM);
+		wait_for_completion(&usbos_info->dpc_exited);
+	}
+#endif /* DBUS_LINUX_RXDPC */
+	if (usbos_info->intr_urb) {
+		USB_FREE_URB(usbos_info->intr_urb);
+		usbos_info->intr_urb = NULL;
+	}
+
+	if (usbos_info->ctl_urb) {
+		USB_FREE_URB(usbos_info->ctl_urb);
+		usbos_info->ctl_urb = NULL;
+	}
+
+#if defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW)
+	if (usbos_info->blk_urb) {
+		USB_FREE_URB(usbos_info->blk_urb);
+		usbos_info->blk_urb = NULL;
+	}
+#endif
+
+	dbus_usbos_urbreqs_free(usbos_info, TRUE);
+	atomic_set(&usbos_info->rxallocated, 0);
+	dbus_usbos_urbreqs_free(usbos_info, FALSE);
+	atomic_set(&usbos_info->txallocated, 0);
+
+	g_probe_info.usbos_info = NULL;
+
+	MFREE(pub->osh, usbos_info, sizeof(usbos_info_t));
+	return NULL;
+} /* dbus_usbos_intf_attach */
+
+void
+dbus_usbos_intf_detach(dbus_pub_t *pub, void *info)
+{
+	usbos_info_t *usbos_info = (usbos_info_t *) info;
+	osl_t *osh = pub->osh;
+
+	if (usbos_info == NULL) {
+		return;
+	}
+
+#ifdef USBOS_TX_THREAD
+	dbus_usbos_tx_thread_deinit(usbos_info);
+#endif /* USBOS_TX_THREAD */
+
+#if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX)
+	optimize_deinit(usbos_info, usbos_info->usb);
+#endif
+	/* Must unlink all URBs prior to driver unload;
+	 * otherwise an URB callback can occur after driver
+	 * has been de-allocated and rmmod'd
+	 */
+	dbusos_stop(usbos_info);
+
+	if (usbos_info->intr_urb) {
+		USB_FREE_URB(usbos_info->intr_urb);
+		usbos_info->intr_urb = NULL;
+	}
+
+	if (usbos_info->ctl_urb) {
+		USB_FREE_URB(usbos_info->ctl_urb);
+		usbos_info->ctl_urb = NULL;
+	}
+
+	if (usbos_info->blk_urb) {
+		USB_FREE_URB(usbos_info->blk_urb);
+		usbos_info->blk_urb = NULL;
+	}
+
+	dbus_usbos_urbreqs_free(usbos_info, TRUE);
+	atomic_set(&usbos_info->rxallocated, 0);
+	dbus_usbos_urbreqs_free(usbos_info, FALSE);
+	atomic_set(&usbos_info->txallocated, 0);
+
+#if defined(BCMDBG) || defined(DBUS_LINUX_HIST)
+	if (usbos_info->txposted_hist) {
+		MFREE(osh, usbos_info->txposted_hist, (usbos_info->pub->ntxq+1) * sizeof(int));
+	}
+	if (usbos_info->rxposted_hist) {
+		MFREE(osh, usbos_info->rxposted_hist, (usbos_info->pub->nrxq+1) * sizeof(int));
+	}
+#endif /* BCMDBG || DBUS_LINUX_HIST */
+#ifdef USBOS_THREAD
+	dbus_usbos_thread_deinit(usbos_info);
+#endif /* USBOS_THREAD */
+
+	g_probe_info.usbos_info = NULL;
+	MFREE(osh, usbos_info, sizeof(usbos_info_t));
+} /* dbus_usbos_intf_detach */
+
+#ifdef USBOS_TX_THREAD
+
+void*
+dbus_usbos_tx_thread_init(usbos_info_t *usbos_info)
+{
+	spin_lock_init(&usbos_info->usbos_tx_list_lock);
+	INIT_LIST_HEAD(&usbos_info->usbos_tx_list);
+	init_waitqueue_head(&usbos_info->usbos_tx_queue_head);
+
+	usbos_info->usbos_tx_kt = kthread_create(dbus_usbos_tx_thread_func,
+		usbos_info, "usb-tx-thread");
+
+	if (IS_ERR(usbos_info->usbos_tx_kt)) {
+		DBUSERR(("Thread Creation failed\n"));
+		return (NULL);
+	}
+
+	usbos_info->ctl_state = USBOS_REQUEST_STATE_UNSCHEDULED;
+	wake_up_process(usbos_info->usbos_tx_kt);
+
+	return (usbos_info->usbos_tx_kt);
+}
+
+void
+dbus_usbos_tx_thread_deinit(usbos_info_t *usbos_info)
+{
+	urb_req_t *req;
+
+	if (usbos_info->usbos_tx_kt) {
+		wake_up_interruptible(&usbos_info->usbos_tx_queue_head);
+		kthread_stop(usbos_info->usbos_tx_kt);
+	}
+
+	/* Move pending requests to free queue so they can be freed */
+	while ((req = dbus_usbos_qdeq(
+		&usbos_info->usbos_tx_list, &usbos_info->usbos_tx_list_lock)) != NULL) {
+		dbus_usbos_qenq(&usbos_info->req_txfreeq, req, &usbos_info->txfree_lock);
+	}
+}
+
+/**
+ * Allow USB in-band resume to block by submitting CTRL and DATA URBs on a separate thread.
+ */
+int
+dbus_usbos_tx_thread_func(void *data)
+{
+	usbos_info_t  *usbos_info = (usbos_info_t *)data;
+	urb_req_t     *req;
+	dbus_irb_tx_t *txirb;
+	int           ret;
+	unsigned long flags;
+
+#ifdef WL_THREADNICE
+	set_user_nice(current, WL_THREADNICE);
+#endif
+
+	while (1) {
+		/* Wait until there are URBs to submit */
+		wait_event_interruptible_timeout(
+			usbos_info->usbos_tx_queue_head,
+			!list_empty(&usbos_info->usbos_tx_list) ||
+			usbos_info->ctl_state == USBOS_REQUEST_STATE_SCHEDULED,
+			100);
+
+		if (kthread_should_stop())
+			break;
+
+		/* Submit CTRL URB if needed */
+		if (usbos_info->ctl_state == USBOS_REQUEST_STATE_SCHEDULED) {
+
+			/* Disable USB autosuspend until this request completes. If the
+			 * interface was suspended, this call blocks until it has been resumed.
+			 */
+			USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
+
+			usbos_info->ctl_state = USBOS_REQUEST_STATE_SUBMITTED;
+
+			ret = USB_SUBMIT_URB(usbos_info->ctl_urb);
+			if (ret != 0) {
+				DBUSERR(("%s CTRL USB_SUBMIT_URB failed, status %d\n",
+					__FUNCTION__, ret));
+
+				usbos_info->ctl_state = USBOS_REQUEST_STATE_UNSCHEDULED;
+				up(&usbos_info->ctl_lock);
+
+				USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
+			}
+		}
+
+		/* Submit all available TX URBs */
+		while ((req = dbus_usbos_qdeq(&usbos_info->usbos_tx_list,
+			&usbos_info->usbos_tx_list_lock)) != NULL) {
+
+			/* Disable USB autosuspend until this request completes. If the
+			 * interface was suspended, this call blocks until it has been resumed.
+			 */
+			USB_AUTOPM_GET_INTERFACE(g_probe_info.intf);
+
+			spin_lock_irqsave(&usbos_info->txlock, flags);
+
+			ret = USB_SUBMIT_URB(req->urb);
+			if (ret == 0) {
+				/* URB submitted successfully */
+				dbus_usbos_qenq(&usbos_info->req_txpostedq, req,
+					&usbos_info->txposted_lock);
+				atomic_inc(&usbos_info->txposted);
+			} else {
+				/* Submitting the URB failed. */
+				DBUSERR(("%s TX USB_SUBMIT_URB failed, status %d\n",
+					__FUNCTION__, ret));
+
+				USB_AUTOPM_PUT_INTERFACE_ASYNC(g_probe_info.intf);
+			}
+
+			spin_unlock_irqrestore(&usbos_info->txlock, flags);
+
+			if (ret != 0) {
+				/* Cleanup and notify higher layers */
+				dbus_usbos_qenq(&usbos_info->req_txfreeq, req,
+					&usbos_info->txfree_lock);
+
+				txirb = req->arg;
+				if (txirb->send_buf) {
+					MFREE(usbos_info->pub->osh, txirb->send_buf, req->buf_len);
+					req->buf_len = 0;
+				}
+
+				if (likely (usbos_info->cbarg && usbos_info->cbs)) {
+					if (likely (usbos_info->cbs->send_irb_complete != NULL))
+						usbos_info->cbs->send_irb_complete(
+							usbos_info->cbarg, txirb, DBUS_ERR_TXDROP);
+				}
+			}
+		}
+	}
+
+	return 0;
+} /* dbus_usbos_tx_thread_func */
+
+#endif /* USBOS_TX_THREAD */
+
+#ifdef USBOS_THREAD
+
+/**
+ * Increase system performance by creating a USB thread that runs parallel to other system
+ * activity.
+ */
+static void*
+dbus_usbos_thread_init(usbos_info_t *usbos_info)
+{
+	usbos_list_entry_t  *entry;
+	unsigned long       flags, ii;
+
+	spin_lock_init(&usbos_info->usbos_list_lock);
+	INIT_LIST_HEAD(&usbos_info->usbos_list);
+	INIT_LIST_HEAD(&usbos_info->usbos_free_list);
+	init_waitqueue_head(&usbos_info->usbos_queue_head);
+	atomic_set(&usbos_info->usbos_list_cnt, 0);
+
+	for (ii = 0; ii < (usbos_info->pub->nrxq + usbos_info->pub->ntxq); ii++) {
+		entry = MALLOC(usbos_info->pub->osh, sizeof(usbos_list_entry_t));
+		if (entry) {
+			spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
+			list_add_tail((struct list_head*) entry, &usbos_info->usbos_free_list);
+			spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
+		} else {
+			DBUSERR(("Failed to create list\n"));
+		}
+	}
+
+	usbos_info->usbos_kt = kthread_create(dbus_usbos_thread_func,
+		usbos_info, "usb-thread");
+
+	if (IS_ERR(usbos_info->usbos_kt)) {
+		DBUSERR(("Thread Creation failed\n"));
+		return (NULL);
+	}
+
+	wake_up_process(usbos_info->usbos_kt);
+
+	return (usbos_info->usbos_kt);
+}
+
+static void
+dbus_usbos_thread_deinit(usbos_info_t *usbos_info)
+{
+	struct list_head    *cur, *next;
+	usbos_list_entry_t  *entry;
+	unsigned long       flags;
+
+	if (usbos_info->usbos_kt) {
+		wake_up_interruptible(&usbos_info->usbos_queue_head);
+		kthread_stop(usbos_info->usbos_kt);
+	}
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	list_for_each_safe(cur, next, &usbos_info->usbos_list)
+	{
+		entry = list_entry(cur, struct usbos_list_entry, list);
+		/* detach this entry from the list and then free the entry */
+		spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
+		list_del(cur);
+		MFREE(usbos_info->pub->osh, entry, sizeof(usbos_list_entry_t));
+		spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
+	}
+
+	list_for_each_safe(cur, next, &usbos_info->usbos_free_list)
+	{
+		entry = list_entry(cur, struct usbos_list_entry, list);
+		/* detach this entry from the list and then free the entry */
+		spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
+		list_del(cur);
+		MFREE(usbos_info->pub->osh, entry, sizeof(usbos_list_entry_t));
+		spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
+	}
+	GCC_DIAGNOSTIC_POP();
+}
+
+/** Process completed URBs in a worker thread */
+static int
+dbus_usbos_thread_func(void *data)
+{
+	usbos_info_t        *usbos_info = (usbos_info_t *)data;
+	usbos_list_entry_t  *entry;
+	struct list_head    *cur, *next;
+	unsigned long       flags;
+
+#ifdef WL_THREADNICE
+	set_user_nice(current, WL_THREADNICE);
+#endif
+
+	while (1) {
+		/* If the list is empty, then go to sleep */
+		wait_event_interruptible_timeout
+		(usbos_info->usbos_queue_head,
+			atomic_read(&usbos_info->usbos_list_cnt) > 0,
+			100);
+
+		if (kthread_should_stop())
+			break;
+
+		spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
+
+		/* For each entry on the list, process it.  Remove the entry from
+		* the list when done.
+		*/
+		GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+		list_for_each_safe(cur, next, &usbos_info->usbos_list)
+		{
+			urb_req_t           *req;
+			int                 len;
+			int                 stat;
+			usbos_info_t        *usbos_info_local;
+
+			entry = list_entry(cur, struct usbos_list_entry, list);
+			if (entry == NULL)
+				break;
+
+			req = entry->urb_context;
+			len = entry->urb_length;
+			stat = entry->urb_status;
+			usbos_info_local = req->usbinfo;
+
+			/* detach this entry from the list and attach it to the free list */
+			list_del_init(cur);
+			spin_unlock_irqrestore(&usbos_info_local->usbos_list_lock, flags);
+
+			dbus_usbos_recv_complete_handle(req, len, stat);
+
+			spin_lock_irqsave(&usbos_info_local->usbos_list_lock, flags);
+
+			list_add_tail(cur, &usbos_info_local->usbos_free_list);
+
+			atomic_dec(&usbos_info_local->usbos_list_cnt);
+		}
+
+		spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
+
+	}
+	GCC_DIAGNOSTIC_POP();
+
+	return 0;
+} /* dbus_usbos_thread_func */
+
+/** Called on Linux calling URB callback, see dbus_usbos_recv_complete() */
+static void
+dbus_usbos_dispatch_schedule(CALLBACK_ARGS)
+{
+	urb_req_t           *req = urb->context;
+	usbos_info_t        *usbos_info = req->usbinfo;
+	usbos_list_entry_t  *entry;
+	unsigned long       flags;
+	struct list_head    *cur;
+
+	spin_lock_irqsave(&usbos_info->usbos_list_lock, flags);
+
+	cur   = usbos_info->usbos_free_list.next;
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	entry = list_entry(cur, struct usbos_list_entry, list);
+	GCC_DIAGNOSTIC_POP();
+
+	/* detach this entry from the free list and prepare it insert it to use list */
+	list_del_init(cur);
+
+	if (entry) {
+		entry->urb_context = urb->context;
+		entry->urb_length  = urb->actual_length;
+		entry->urb_status  = urb->status;
+
+		atomic_inc(&usbos_info->usbos_list_cnt);
+		list_add_tail(cur, &usbos_info->usbos_list);
+	} else {
+		DBUSERR(("!!!!!!OUT OF MEMORY!!!!!!!\n"));
+	}
+
+	spin_unlock_irqrestore(&usbos_info->usbos_list_lock, flags);
+
+	/* thread */
+	wake_up_interruptible(&usbos_info->usbos_queue_head);
+} /* dbus_usbos_dispatch_schedule */
+
+#endif /* USBOS_THREAD */
+
+#ifdef USB_TRIGGER_DEBUG
+static bool
+dbus_usbos_ctl_send_debugtrig(usbos_info_t* usbinfo)
+{
+	bootrom_id_t id;
+
+	if (usbinfo == NULL)
+		return FALSE;
+
+	id.chip = 0xDEAD;
+
+	dbus_usbos_dl_cmd(usbinfo, DL_DBGTRIG, &id, sizeof(bootrom_id_t));
+
+	/* ignore the result for now */
+	return TRUE;
+}
+#endif /* USB_TRIGGER_DEBUG */
+
+#if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX)
+
+/** New optimized code for USB AP. EHCI fastpath specific function. */
+void inline optimize_ehci_qtd_init(struct ehci_qtd *qtd, dma_addr_t dma)
+{
+	bzero(qtd, sizeof(*qtd));
+	wmb();
+	qtd->qtd_self = dma;
+	qtd->qtd_status = cpu_to_le32(EHCI_QTD_HALTED);
+	qtd->qtd_next = EHCI_NULL;
+	qtd->qtd_altnext = EHCI_NULL;
+	qtd->obj_next = NULL;
+	qtd->rpc = NULL;
+	/* qtd->buff = NULL; */
+	qtd->xacterrs = EHCI_QTD_XACTERR_MAX;
+	wmb();
+}
+
+/** EHCI fastpath specific function */
+struct ehci_qtd *optimize_ehci_qtd_alloc(gfp_t flags)
+{
+	struct ehci_qtd		*qtd;
+	dma_addr_t		dma;
+
+	usbos_info_t *usbos_info = g_probe_info.usbos_info;
+
+	struct dma_pool *pool = usbos_info->qtd_pool;
+
+	qtd = dma_pool_alloc(pool, flags, &dma);
+	if (qtd != NULL) {
+		/* ME: Only clear the necessary fields:
+		 * - hw
+		 * - chain of QTDs in mapped space
+		 */
+		optimize_ehci_qtd_init(qtd, dma);
+	}
+
+	return qtd;
+}
+
+/** EHCI fastpath specific function */
+void optimize_ehci_qtd_free(struct ehci_qtd *qtd)
+{
+	usbos_info_t *usbos_info = g_probe_info.usbos_info;
+	struct dma_pool *pool = usbos_info->qtd_pool;
+	dma_pool_free(pool, qtd, qtd->qtd_self);
+}
+
+/**
+ * EHCI fastpath specific function. Loosely follows qtd_copy_status
+ * Greatly simplified as there are only three options: normal, short read, and disaster
+ */
+static int
+get_qtd_status(struct ehci_qtd *qtd, int token, int *actual_length)
+{
+	int	status = -EINPROGRESS;
+
+	*actual_length += qtd->length - EHCI_QTD_GET_BYTES(token);
+
+	/* Short read is not an error */
+	if (unlikely (SHORT_READ_Q (token)))
+		status = -EREMOTEIO;
+
+	/* Check for serious problems */
+	if (token & EHCI_QTD_HALTED) {
+		status = -EPROTO;
+		if (token & (EHCI_QTD_BABBLE | EHCI_QTD_MISSEDMICRO | EHCI_QTD_BUFERR |
+			EHCI_QTD_XACTERR))
+			printk("EHCI Fastpath: Serious USB issue qtd %p token %08x --> status %d\n",
+				qtd, token, status);
+	}
+
+	return status;
+}
+
+/** This only works in the BCM embedded world (code uses primitive address mapping) */
+static void dump_qtd(struct ehci_qtd *qtd)
+{
+	printk("qtd_next %08x qtd_altnext %08x qtd_status %08x\n", qtd->qtd_next,
+		qtd->qtd_altnext, qtd->qtd_status);
+}
+
+static void dump_qh(struct ehci_qh *qh)
+{
+	struct ehci_qtd *qtd = (struct ehci_qtd *)(qh->qh_curqtd | 0xa0000000);
+	printk("EHCI Fastpath: QH %p Dump\n", qh);
+	printk("qtd_next %08x info1 %08x info2 %08x current %08x\n", qh->qh_link, qh->qh_endp,
+		qh->qh_endphub, qh->qh_curqtd);
+	printk("overlay\n");
+	dump_qtd((struct ehci_qtd *)&qh->ow_next);
+	while ((((int)qtd)&EHCI_NULL) == 0)
+	{
+		printk("QTD %p\n", qtd);
+		dump_qtd((struct ehci_qtd *)qtd);
+		qtd = (struct ehci_qtd *)(qtd->qtd_next | 0xa0000000);
+	}
+}
+
+/**
+ * EHCI fastpath specific function.
+ * This code assumes the caller holding a lock
+ * It is currently called from scan_async that should have the lock
+ * Lock shall be dropped around the actual completion, then reacquired
+ * This is a clean implementation of the qh_completions()
+ */
+static void
+ehci_bypass_callback(int pipeindex, struct ehci_qh *qh, spinlock_t *lock)
+{
+							/* Loop variables */
+	struct ehci_qtd		*qtd, 			/* current QTD */
+				*end = qh->dummy, 	/* "afterend" */
+				*next;
+	int			stopped;
+
+	/* ME: Obtain the same info in cleaner way */
+	usbos_info_t *usbos_info = g_probe_info.usbos_info;
+
+	/* printk("EHCI Fastpath: callback pipe %d QH %p lock %p\n", pipeindex, qh, lock); */
+
+	/*
+	 * This code should not require any interlocking with QTD additions
+	 * The additions never touch QH, we should never touch 'end'
+	 * Note that QTD additions will keep 'end' in place
+	 */
+	for (qtd = qh->first_qtd; qtd != end; qtd = next)
+	{
+		u32		status;		/* Status bits from QTD */
+
+		/* Get the status bits from the QTD */
+		rmb();
+		status = hc32_to_cpu(qtd->qtd_status);
+
+		if ((status & EHCI_QTD_ACTIVE) == 0) {
+			if (unlikely((status & EHCI_QTD_HALTED) != 0)) {
+				/* Retry transaction errors until we
+				 * reach the software xacterr limit
+				 */
+				if ((status & EHCI_QTD_XACTERR) &&
+					EHCI_QTD_GET_CERR(status) == 0 &&
+					--qtd->xacterrs > 0) {
+					/* Reset the token in the qtd and the
+					 * qh overlay (which still contains
+					 * the qtd) so that we pick up from
+					 * where we left off
+					 */
+					printk("EHCI Fastpath: detected XactErr "
+						"qtd %p len %d/%d retry %d\n",
+						qtd, qtd->length - EHCI_QTD_GET_BYTES(status),
+						qtd->length,
+						EHCI_QTD_XACTERR_MAX - qtd->xacterrs);
+
+					status &= ~EHCI_QTD_HALTED;
+					status |= EHCI_QTD_ACTIVE | EHCI_QTD_SET_CERR(3);
+					qtd->qtd_status = cpu_to_le32(status);
+					wmb();
+					qh->ow_status = cpu_to_le32(status);
+
+					break;
+				}
+
+				/* QTD processing was aborted - highly unlikely (never seen, so not
+				 * tested). In very new 2.6, we can retry. In 2.4 and older 2.6,
+				 * life sucks (the USB stack does the same)
+				 */
+				printk("EHCI Fastpath: QTD halted\n");
+				dump_qh(qh);
+				stopped = 1;
+			}
+		} else {
+			/* Inactive QTD is an afterend, finished the list */
+			break;
+		}
+
+		/* Remove the QTD from software QH. This should be done before dropping the lock
+		 * in for upper layer
+		 */
+		next = qtd->obj_next;
+		qh->first_qtd = next;
+
+		/* Upper layer processing. */
+		if (EHCI_QTD_GET_PID(status) == 0)  /* OUT (host->dongle) pipe */
+		{
+			if (qtd->rpc == NULL)
+			{
+				/* Download, just signal completion
+				 * ME: Use non-global OS handle
+				 * Code from dbus_usbos_sync_complete
+				 */
+				usbos_info->waitdone = TRUE;
+				wake_up_interruptible(&usbos_info->wait);
+				/* ME: Set to meaningful status */
+				usbos_info->sync_urb_status = 0;
+			} else {
+				/* RPC packet handling
+				 * First, relevant processing from dbus_if_send_irb_complete:
+				 * ME: Check for bus state here
+				 */
+
+				/* Now propagate to the RPC layer from dbus_usbos_send_complete:
+				 *  usbos_info->cbs->send_irb_complete(usbos_info->cbarg,
+				 *  txirb, status);
+				 */
+
+				/* From dbus_usb_send_irb_complete: */
+
+				/* usb_info_t *usb_info = (usb_info_t *) handle; */
+				usb_info_t *usb_info = (usb_info_t *) usbos_info->cbarg;
+				/* if(usb_info && usb_info->cbs && usb_info->cbs->send_irb_complete)
+				 * usb_info->cbs->send_irb_complete(usb_info->cbarg, txirb, status);
+				 */
+
+				/* From dbus_if_send_irb_complete
+				 * 	dbus_info_t *dbus_info = (dbus_info_t *) handle;
+				 */
+				dbus_info_t *dbus_info = (dbus_info_t *)usb_info->cbarg;
+				/* printk("RPC send completed %p %p %p\n", usbos_info,
+				 * 	usb_info, dbus_info);
+				 * dbus_tx_timer_stop(dbus_info);
+				 * if (txirb_pending)
+				 * 	dbus_tx_timer_start(dbus_info, DBUS_TX_TIMEOUT_INTERVAL);
+				 * pktinfo = txirb->info; // This is the same as the pkt :-)
+				 * if (dbus_info->cbs && dbus_info->cbs->send_complete)
+				 * dbus_info->cbs->send_complete(dbus_info->cbarg, pktinfo,
+				 *	status);
+				 */
+
+				/* Free the coalesce buffer, if multi-buffer packet only. Do not
+				 * rely on buff, as it might not even exist
+				 */
+				if (PKTNEXT(usbos_info->pub->osh, qtd->rpc)) {
+					/* ME: dma_unmap_single */
+					/* printk("k-Freeing %p\n", qtd->buff); */
+					kfree(qtd->buff);
+				}
+
+				if (dbus_info->cbs && dbus_info->cbs->send_complete)
+				{
+					atomic_dec(&s_tx_pending);
+					spin_unlock(lock);
+					/* printk("Sending to RPC qtd %p\n", qtd); */
+#if !(defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_TXNOCOPY) || defined(BCM_RPC_TOC))
+	#error Configuration not supported; read dbus_if_send_irb_complete for guidelines
+#endif
+					/* ME: Set to meaningful status */
+					dbus_info->cbs->send_complete(dbus_info->cbarg, qtd->rpc,
+						0);
+					if ((atomic_read(&s_tx_pending) < 16) &&
+						/* ME: 16 or dbus_info->tx_low_watermark? */
+						dbus_info->txoff && !dbus_info->txoverride) {
+						dbus_flowctrl_tx(dbus_info, OFF);
+					}
+					spin_lock(lock);
+
+					/* Things could have happened while the lock was gone,
+					 * resync to the hardware
+					 */
+					next = qh->first_qtd;
+					end = qh->dummy;
+				}
+			}
+
+			optimize_ehci_qtd_free(qtd);
+		} else {   /* IN (dongle->host) pipe */
+			/* Simulates the upstream travel */
+			usb_info_t *usb_info = (usb_info_t *) usbos_info->cbarg;
+			dbus_info_t *dbus_info = (dbus_info_t *)usb_info->cbarg;
+			/* unsigned long       flags; */
+			int actual_length = 0;
+
+			/* All our reads must be short */
+			if (!SHORT_READ_Q (status)) ASSERT(0);
+
+			/* Done with hardware, convert status to error codes */
+			status = get_qtd_status(qtd, status, &actual_length);
+
+			switch (status) {
+			/* success */
+			case 0:
+			case -EINPROGRESS:
+			case -EREMOTEIO:
+				status = 0;
+				break;
+
+			case -ECONNRESET:		/* canceled */
+			case -ENOENT:
+			case -EPROTO:
+				DBUSERR(("%s: ehci unlink. status %x\n", __FUNCTION__, status));
+				break;
+			}
+
+			if (g_probe_info.dereged) {
+				printk("%s: DBUS deregistering, ignoring recv callback\n",
+					__FUNCTION__);
+				return;
+			}
+
+			dma_unmap_single(
+				usbos_info->usb->bus->controller,
+				(dma_addr_t)qtd->qtd_buffer_hi[0],
+				actual_length,
+				DMA_FROM_DEVICE);
+
+			/* From dbus_usb_recv_irb_complete
+			 *
+			 * if (usb_info->cbs && usb_info->cbs->recv_irb_complete)
+			 * 	usb_info->cbs->recv_irb_complete(usb_info->cbarg, rxirb, status);
+			 */
+
+			/* From dbus_if_recv_irb_complete */
+			if (dbus_info->pub.busstate != DBUS_STATE_DOWN) {
+				if (status == 0) {
+					void *buf = qtd->rpc;
+
+					ASSERT(buf != NULL);
+					spin_unlock(lock);
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
+					/* Note that these ifdefs are indirectly coming from
+					 * dbus_usbos_recv_urb_submit The code itself is from
+					 * dbus_if_recv_irb_complete that makes the decision
+					 * at runtime, yet it is only pkt or buf depending on
+					 * the NOCOPY setup, never both :-)
+					 */
+					if (dbus_info->cbs && dbus_info->cbs->recv_pkt)
+						dbus_info->cbs->recv_pkt(dbus_info->cbarg, buf);
+#else
+					if (actual_length > 0) {
+						if (dbus_info->cbs && dbus_info->cbs->recv_buf)
+							dbus_info->cbs->recv_buf(dbus_info->cbarg,
+							buf, actual_length);
+					}
+#endif
+					spin_lock(lock);
+
+					/* Things could have happened while the lock was gone,
+					 * resync to the hardware
+					 */
+					next = qh->first_qtd;
+					end = qh->dummy;
+
+					/* Reinitialize this qtd since it will be reused. */
+					optimize_ehci_qtd_init(qtd, qtd->qtd_self);
+
+#if defined(BCM_RPC_NOCOPY) || defined(BCM_RPC_RXNOCOPY)
+					/* Note that these ifdefs are coming from
+					 * dbus_usbos_recv_urb_submit. In the NOCOPY configuration,
+					 * force an allocation of a new packet
+					 */
+					optimize_submit_rx_request(&dbus_info->pub, 1, qtd, NULL);
+
+#else
+					/* In the copy mode, simply reuse the buffer; upper level
+					 * had already consumed the data
+					 */
+					optimize_submit_rx_request(&dbus_info->pub, 1, qtd, buf);
+#endif
+					/* Not to free this qtd because it will be reused. */
+					continue;
+				}
+			} else {
+				printk("%s: DBUS down, ignoring recv callback\n", __FUNCTION__);
+			}
+			optimize_ehci_qtd_free(qtd);
+		}
+	}
+} /* ehci_bypass_callback */
+
+/** EHCI fastpath specific function */
+static void optimize_urb_callback(struct urb *urb)
+{
+	struct usb_ctrlrequest *req = urb->context;
+
+	kfree(req);
+	USB_FREE_URB(urb);
+}
+
+/**
+ * EHCI fastpath specific function. Shall be called under an external lock (currently RPC_TP_LOCK)
+ */
+static int optimize_submit_urb(struct usb_device *usb, void *ptr, int request)
+{
+	struct usb_ctrlrequest *req;
+	struct urb *urb;
+
+	if ((urb = USB_ALLOC_URB()) == NULL) {
+		printk("EHCI Fastpath: Error allocating URB in optimize_EP!");
+		return -ENOMEM;
+	}
+
+	if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) {
+		printk("EHCI Fastpath: Failed to allocate memory for control request in"
+			" optimize_EP!");
+		USB_FREE_URB(urb);
+		return -ENOMEM;
+	}
+
+	req->bRequestType = (USB_TYPE_VENDOR | USB_RECIP_OTHER);
+	req->bRequest = request;
+
+	/* Use this instead of a buffer */
+	req->wValue = ((int)ptr & 0xffff);
+	req->wIndex = ((((int)ptr)>>16) & 0xffff);
+	req->wLength = 0;
+
+	printk("EHCI Fastpath: usb_dev %p\n", usb);
+	printk("EHCI Fastpath: bus %p\n", usb->bus);
+	printk("EHCI Fastpath: Hub %p\n", usb->bus->root_hub);
+
+	usb_fill_control_urb(
+		urb,
+		usb->bus->root_hub,
+		usb_sndctrlpipe(usb->bus->root_hub, 0),
+		(void *)req,
+		NULL,
+		0,
+		optimize_urb_callback,
+		req);
+
+	USB_SUBMIT_URB(urb);
+
+	if (urb->status != 0) {
+		printk("EHCI Fastpath: Cannot submit URB in optimize_EP: %d\n", urb->status);
+	}
+
+	return urb->status;
+} /* optimize_submit_urb */
+
+/** EHCI fastpath specific function */
+static int epnum(int pipe)
+{
+	int epn = usb_pipeendpoint(pipe);
+	if (usb_pipein (pipe))
+		epn |= 0x10;
+	return epn;
+}
+
+/** EHCI fastpath specific function */
+static int optimize_init(usbos_info_t *usbos_info, struct usb_device *usb, int out, int in, int in2)
+{
+	int retval = -EPIPE;
+
+	atomic_set(&s_tx_pending, 0);
+	/* atomic_set(&s_rx_pending, 0); */
+
+	usbos_info->tx_ep = epnum(out);
+	usbos_info->rx_ep = epnum(in);
+	usbos_info->rx2_ep = epnum(in2);
+	usbos_info->usb_device = usb;
+
+	/* printk("EHCI Fastpath: Create pool %p %p %p\n", usb, usb->bus, usb->bus->controller); */
+
+	/* QTDs for bulk transfers - separate pool */
+	/* ME: Destroy pool */
+	usbos_info->qtd_pool = dma_pool_create("usbnet_qtd",
+		usb->bus->controller,
+		sizeof(struct ehci_qtd),
+		EHCI_QTD_ALIGN /* byte alignment (for hw parts) */,
+		4096 /* can't cross 4K */);
+	if (!usbos_info->qtd_pool) {
+		printk("EHCI Fastpath: Cannot create the QTD pool\n");
+		goto fail;
+	}
+
+	/* detaching the EP */
+	if (optimize_submit_urb(usb, usb, EHCI_SET_BYPASS_DEV) != 0)
+		goto fail;
+	optimize_submit_urb(usb, ehci_bypass_callback, EHCI_SET_BYPASS_CB);
+	optimize_submit_urb(usb, usbos_info->qtd_pool, EHCI_SET_BYPASS_POOL);
+#ifdef EHCI_FASTPATH_TX
+	optimize_submit_urb(usb, (void*)((0<<16)|usbos_info->tx_ep), EHCI_FASTPATH);
+#endif
+#ifdef EHCI_FASTPATH_RX
+	optimize_submit_urb(usb, (void*)((1<<16)|usbos_info->rx_ep),   EHCI_FASTPATH);
+#endif
+	/* ME: Later optimize_submit_urb(usb, ((2<<16)|s_rx2_ep), EHCI_FASTPATH); */
+
+	/* getting the QH */
+	printk("EHCI Fastpath: EP in %d EP in2 %d EP out %d\n", usbos_info->rx_ep,
+		usbos_info->rx2_ep, usbos_info->tx_ep);
+
+	return 0;
+
+fail:
+	return retval;
+} /* optimize_submit_urb */
+
+/** EHCI fastpath specific function */
+static int optimize_deinit_qtds(struct ehci_qh *qh, int coalesce_buf)
+{
+	usbos_info_t *usbos_info = g_probe_info.usbos_info;
+	struct ehci_qtd *qtd, *end, *next;
+	unsigned long	flags;
+
+	if (qh == NULL)
+		return 0;
+
+	end = qh->dummy;
+
+	printk("%s %d. qh = %p\n", __func__, __LINE__, qh);
+
+	spin_lock_irqsave(&usbos_info->fastpath_lock, flags);
+	for (qtd = qh->first_qtd; qtd != end; qtd = next) {
+		next = qtd->obj_next;
+		qh->first_qtd = next;
+
+		/* Free the coalesce buffer, if multi-buffer packet only. Do not
+		 * rely on buff, as it might not even exist
+		 */
+		if (coalesce_buf && PKTNEXT(usbos_info->pub->osh, qtd->rpc)) {
+			/* ME: dma_unmap_single */
+			printk("k-Freeing %p, ", qtd->buff);
+			kfree(qtd->buff);
+		}
+		printk("freeing qtd %p\n", qtd);
+
+		optimize_ehci_qtd_free(qtd);
+	}
+	spin_unlock_irqrestore(&usbos_info->fastpath_lock, flags);
+
+	return 0;
+}
+
+/** EHCI fastpath specific function. This code might deserve a separate file */
+static struct ehci_qh *
+get_ep(usbos_info_t *usbos_info, int ep)
+{
+#ifdef KERNEL26
+	struct usb_host_endpoint *epp = NULL;
+	switch (ep)
+	{
+	case 0: epp = usbos_info->usb_device->ep_out[usbos_info->tx_ep&0xf]; break;
+	case 1: epp = usbos_info->usb_device->ep_in[usbos_info->rx_ep&0xf]; break;
+	case 2: epp = usbos_info->usb_device->ep_in[usbos_info->rx2_ep&0xf]; break;
+	default: ASSERT(0);
+	}
+	if (epp != NULL)
+		return (struct ehci_qh *)epp->hcpriv;
+	else return NULL;
+#else
+	switch (ep)
+	{
+	case 0: return (struct ehci_qh *)(((struct hcd_dev*)(usbos_info->
+		usb_device->hcpriv))->ep[usbos_info->tx_ep]);
+	case 1: return (struct ehci_qh *)(((struct hcd_dev*)(usbos_info->
+		usb_device->hcpriv))->ep[usbos_info->rx_ep]);
+	case 2: return (struct ehci_qh *)(((struct hcd_dev*)(usbos_info->
+		usb_device->hcpriv))->ep[usbos_info->rx2_ep]);
+	default: ASSERT(0);
+	}
+	return NULL;
+#endif /* KERNEL26 */
+}
+
+/** EHCI fastpath specific function */
+int optimize_deinit(usbos_info_t *usbos_info, struct usb_device *usb)
+{
+	optimize_deinit_qtds(get_ep(usbos_info, 0), 1);
+	optimize_deinit_qtds(get_ep(usbos_info, 1), 0);
+#if defined(EHCI_FASTPATH_TX) || defined(EHCI_FASTPATH_RX)
+	optimize_submit_urb(usb, (void *)0, EHCI_CLR_EP_BYPASS);
+#endif
+	dma_pool_destroy(usbos_info->qtd_pool);
+	return 0;
+}
+
+/** EHCI fastpath specific function. Reassemble the segmented packet */
+static int
+optimize_gather(const dbus_pub_t *pub, void *pkt, void **buf)
+{
+	int len = 0;
+
+	void *transfer_buf = kmalloc(pkttotlen(pub->osh, pkt),
+		GFP_ATOMIC);
+	*buf = transfer_buf;
+
+	if (!transfer_buf) {
+		printk("fail to alloc to usb buffer\n");
+		return 0;
+	}
+
+	while (pkt) {
+		int pktlen = PKTLEN(pub->osh, pkt);
+		bcopy(PKTDATA(pub->osh, pkt), transfer_buf, pktlen);
+		transfer_buf += pktlen;
+		len += pktlen;
+		pkt = PKTNEXT(pub->osh, pkt);
+	}
+
+	/* printk("Coalesced a %d-byte buffer\n", len); */
+
+	return len;
+}
+
+/** EHCI fastpath specific function */
+int
+optimize_qtd_fill_with_rpc(const dbus_pub_t *pub, int epn,
+	struct ehci_qtd *qtd, void *rpc, int token, int len)
+{
+	void *data = NULL;
+
+	if (len == 0)
+		return optimize_qtd_fill_with_data(pub, epn, qtd, data, token, len);
+
+	ASSERT(rpc != NULL);
+	data = PKTDATA(pub->osh, rpc);
+	qtd->rpc = rpc;
+
+	if (PKTNEXT(pub->osh, rpc)) {
+		len = optimize_gather(pub, rpc, &data);
+		qtd->buff = data;
+	}
+
+	return optimize_qtd_fill_with_data(pub, epn, qtd, data, token, len);
+}
+
+/** EHCI fastpath specific function. Fill the QTD from the data buffer */
+int
+optimize_qtd_fill_with_data(const dbus_pub_t *pub, int epn,
+	struct ehci_qtd *qtd, void *data, int token, int len)
+{
+	int		i, bytes_fit, page_offset;
+	dma_addr_t	addr = 0;
+
+	/* struct usb_host_endpoint *ep = get_ep(epn); */
+	usbos_info_t *usbos_info = g_probe_info.usbos_info;
+
+	token |= (EHCI_QTD_ACTIVE | EHCI_QTD_IOC); /* Allow execution, force interrupt */
+
+	if (len > 0) {
+		addr = dma_map_single(
+			usbos_info->usb->bus->controller,
+			data,
+			len,
+			EHCI_QTD_GET_PID(token) ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+	}
+
+	qtd->qtd_buffer[0] = cpu_to_hc32((u32)addr);
+	/* Here qtd->qtd_buffer_hi[0] is leveraged to store addr value, which
+	 * is needed when invoking dma_unmap_single() in ehci_bypass_callback().
+	 * This is valid for EHCI 32bit only.
+	 */
+	qtd->qtd_buffer_hi[0] = cpu_to_hc32((u32)addr);
+	page_offset = (addr & (EHCI_PAGE_SIZE-1));
+	bytes_fit = EHCI_PAGE_SIZE - page_offset;
+	addr -= page_offset;
+	if (len < bytes_fit)
+		bytes_fit = len;
+	else {
+		addr +=  EHCI_PAGE_SIZE;
+
+		for (i = 1; bytes_fit < len && i < EHCI_QTD_NBUFFERS; i++) {
+			qtd->qtd_buffer[i] = cpu_to_hc32((u32)addr);
+			qtd->qtd_buffer_hi[i] = 0;
+			addr += EHCI_PAGE_SIZE;
+			if ((bytes_fit + EHCI_PAGE_SIZE) < len)
+				bytes_fit += EHCI_PAGE_SIZE;
+			else
+				bytes_fit = len;
+		}
+
+		if (bytes_fit != len)
+		{
+			/* ME: Handle long packets? Does not happen */
+			ASSERT(0);
+		}
+	}
+	qtd->qtd_status = cpu_to_hc32((bytes_fit << 16) | token);
+	qtd->length = bytes_fit;
+
+	return bytes_fit;
+} /* optimize_qtd_fill_with_data */
+
+/**
+ * EHCI fastpath specific function. Reimplementation of qh_append_tds(). Returns nonzero if too many
+ * requests pending.
+ */
+int
+optimize_submit_async(struct ehci_qtd *qtd, int epn)
+{
+	/* Clean implementation along the lines of qh_append_tds() */
+
+	struct ehci_qtd		*afterend; /* Element at the end of the QTD chain (after the
+					    * last useful one, "after-end")
+					    */
+	dma_addr_t		hw_addr;
+	__hc32			status;
+	unsigned long	flags;
+
+	usbos_info_t *usbos_info = g_probe_info.usbos_info;
+	struct ehci_qh *qh = get_ep(usbos_info, epn);
+	usb_info_t *usb_info = (usb_info_t *) usbos_info->cbarg;
+	dbus_info_t *dbus_info = (dbus_info_t *)usb_info->cbarg;
+
+	/* printk("Submit qtd %p to pipe %d (%p)\n", qtd, epn, qh); */
+	if (qh == NULL)
+	{
+		printk("EHCI Fastpath: Attempt of optimized submit to a non-optimized pipe\n");
+		return -1;
+	}
+
+	spin_lock_irqsave(&usbos_info->fastpath_lock, flags);
+
+	/* Limit outstanding - for rpc behavior only */
+	/* printk("QH qtd_status %08x\n", qh->hw->qtd_status); */
+
+	if ((qtd->qtd_status & (1<<8)) == 0)
+	{
+		atomic_inc(&s_tx_pending);
+		if (atomic_read(&s_tx_pending) > 16*2) /* (dbus_info->tx_low_watermark * 3)) */
+			dbus_flowctrl_tx(dbus_info, TRUE);
+	}
+
+	ASSERT(qh != NULL);
+
+	/* ME: Check for hardware availability here */
+
+	/*
+	 * Standard list processing trick:
+	 *   * old "afterend" is filled with the incoming data while still HALTed
+	 *   * new element is appended and prepared to serve as new afterend
+	 *   * now old afterend is activated
+	 * This way, HW never races the SW - no semaphores are necessary, as long as this function
+	 * is not reentered for the same QH
+	 */
+
+	/* Make new QTD to be HALTed, wait for it to actually happen */
+	status = qtd->qtd_status;
+	qtd->qtd_status = cpu_to_le32(EHCI_QTD_HALTED);
+	wmb();
+
+	/* Now copy all information from the new QTD to the old afterend,
+	 * except the own HW address
+	 */
+	afterend = qh->dummy;
+	hw_addr = afterend->qtd_self;
+	*afterend = *qtd;
+	afterend->qtd_self = hw_addr;
+
+	/* The new QTD is ready to serve as a new afterend, append it */
+	qh->dummy = qtd;
+	afterend->qtd_next = qtd->qtd_self;
+	afterend->qtd_altnext = qtd->qtd_self;  /* Always assume short read. Harmless in our case */
+	afterend->obj_next = qtd;
+
+	/* Wait for writes to happen and enable the old afterend (now containing the QTD data) */
+	wmb();
+	afterend->qtd_status = status;
+	wmb();
+
+	spin_unlock_irqrestore(&usbos_info->fastpath_lock, flags);
+
+	return 0;
+} /* optimize_submit_async */
+
+/** EHCI fastpath specific function. ME: Error return and handling */
+void
+optimize_submit_rx_request(const dbus_pub_t *pub, int epn, struct ehci_qtd *qtd_in,
+                                            void *buf)
+{
+	/* ME: Replace with getting usbos_info from pub */
+	usbos_info_t *usbos_info = g_probe_info.usbos_info;
+	int len = usbos_info->rxbuf_len;
+	void *pkt;
+	struct ehci_qtd *qtd;
+	int token = EHCI_QTD_SET_CERR(3) | EHCI_QTD_SET_PID(1);
+
+	if (qtd_in == NULL) {
+		qtd = optimize_ehci_qtd_alloc(GFP_KERNEL);
+		if (!qtd) {
+			printk("EHCI Fastpath: Out of QTDs\n");
+			return;
+		}
+	} else {
+		qtd = qtd_in;
+	}
+
+	if (buf == NULL)
+	{
+		/* NOCOPY, allocate own packet */
+		/* Follow dbus_usbos_recv_urb_submit */
+		pkt = PKTGET(usbos_info->pub->osh, len, FALSE);
+		if (pkt == NULL) {
+			printk("%s: PKTGET failed\n", __FUNCTION__);
+			optimize_ehci_qtd_free(qtd);
+			return;
+		}
+		/* consider the packet "native" so we don't count it as MALLOCED in the osl */
+		PKTTONATIVE(usbos_info->pub->osh, pkt);
+		qtd->rpc = pkt;
+		buf = PKTDATA(usbos_info->pub->osh, pkt);
+
+	} else {
+		qtd->rpc = buf;
+	}
+
+	optimize_qtd_fill_with_data(pub, epn, qtd, buf, token, len);
+	optimize_submit_async(qtd, epn);
+} /* optimize_submit_rx_request */
+
+#endif /* EHCI_FASTPATH_TX || EHCI_FASTPATH_RX */
+
+#ifdef BCM_REQUEST_FW
+
+struct request_fw_context {
+	const struct firmware *firmware;
+	struct semaphore lock;
+};
+
+/*
+ * Callback for dbus_request_firmware().
+ */
+static void
+dbus_request_firmware_done(const struct firmware *firmware, void *ctx)
+{
+	struct request_fw_context *context = (struct request_fw_context*)ctx;
+
+	/* Store the received firmware handle in the context and wake requester */
+	context->firmware = firmware;
+	up(&context->lock);
+}
+
+/*
+ * Send a firmware request and wait for completion.
+ *
+ * The use of the asynchronous version of request_firmware() is needed to avoid
+ * kernel oopses when we just come out of system hibernate.
+ */
+static int
+dbus_request_firmware(const char *name, const struct firmware **firmware)
+{
+	struct request_fw_context *context;
+	int ret;
+
+	context = kzalloc(sizeof(*context), GFP_KERNEL);
+	if (!context)
+		return -ENOMEM;
+
+	sema_init(&context->lock, 0);
+
+	ret = request_firmware_nowait(THIS_MODULE, true, name, &g_probe_info.usb->dev,
+	                              GFP_KERNEL, context, dbus_request_firmware_done);
+	if (ret) {
+		kfree(context);
+		return ret;
+	}
+
+	/* Wait for completion */
+	if (down_interruptible(&context->lock) != 0) {
+		kfree(context);
+		return -ERESTARTSYS;
+	}
+
+	*firmware = context->firmware;
+	kfree(context);
+
+	return *firmware != NULL ? 0 : -ENOENT;
+}
+
+#ifndef DHD_LINUX_STD_FW_API
+static void *
+dbus_get_fwfile(int devid, int chiprev, uint8 **fw, int *fwlen,
+	uint16 boardtype, uint16 boardrev, char *path)
+{
+	const struct firmware *firmware = NULL;
+	s8 *device_id = NULL;
+	s8 *chip_rev = "";
+	s8 file_name[64] = {0, };
+	int ret;
+
+	switch (devid) {
+		case BCM4381_CHIP_ID:
+			device_id = "4381";
+			switch (chiprev) {
+				case 1:
+					chip_rev = "a0";
+					break;
+				default:
+					break;
+			}
+			break;
+		case BCM4382_CHIP_ID:
+			device_id = "4382";
+			switch (chiprev) {
+				case 1:
+					chip_rev = "a0";
+					break;
+				default:
+					break;
+			}
+			break;
+
+		default:
+			DBUSERR(("unsupported device %x\n", devid));
+			return NULL;
+	}
+
+	/* Load firmware */
+	snprintf(file_name, sizeof(file_name), "brcm/bcm%s%s-usb.bin", device_id, chip_rev);
+
+	ret = dbus_request_firmware(path, &firmware);
+	if (ret) {
+		DBUSERR(("fail to request firmware %s\n", path));
+		return NULL;
+	} else
+		DBUSERR(("%s: %s (%zu bytes) open success\n", __FUNCTION__, path, firmware->size));
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	*fwlen = firmware->size;
+	*fw = (uint8 *)firmware->data;
+	return (void *)firmware;
+	GCC_DIAGNOSTIC_POP();
+}
+
+static void *
+dbus_get_nvfile(int devid, int chiprev, uint8 **fw, int *fwlen,
+	uint16 boardtype, uint16 boardrev, char *path)
+{
+	const struct firmware *firmware = NULL;
+	s8 *device_id = NULL;
+	s8 *chip_rev = "";
+	s8 file_name[64];
+	int ret;
+
+	switch (devid) {
+		case BCM4381_CHIP_ID:
+			device_id = "4381";
+			switch (chiprev) {
+				case 1:
+					chip_rev = "a0";
+					break;
+				default:
+					break;
+			}
+			break;
+		case BCM4382_CHIP_ID:
+			device_id = "4382";
+			switch (chiprev) {
+				case 1:
+					chip_rev = "a0";
+					break;
+				default:
+					break;
+			}
+			break;
+
+		default:
+			DBUSERR(("unsupported device %x\n", devid));
+			return NULL;
+	}
+
+	/* Load board specific nvram file */
+	snprintf(file_name, sizeof(file_name), "brcm/bcm%s%s-usb.nvm",
+	         device_id, chip_rev);
+
+	ret = dbus_request_firmware(path, &firmware);
+	if (ret) {
+		DBUSERR(("fail to request nvram %s\n", path));
+
+		/* Load generic nvram file */
+		snprintf(file_name, sizeof(file_name), "brcm/bcm%s%s.nvm",
+		         device_id, chip_rev);
+
+		ret = dbus_request_firmware(file_name, &firmware);
+		if (ret) {
+			DBUSERR(("fail to request nvram %s\n", path));
+			return NULL;
+		}
+	} else
+		DBUSERR(("%s: %s (%zu bytes) open success\n", __FUNCTION__, path, firmware->size));
+
+	*fwlen = firmware->size;
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	*fw = (uint8 *)firmware->data;
+	return (void *)firmware;
+	GCC_DIAGNOSTIC_POP();
+} /* dbus_get_fw_nvfile */
+
+void *
+dbus_get_fw_nvfile(int devid, int chiprev, uint8 **fw, int *fwlen, int type, uint16 boardtype,
+	uint16 boardrev, char *path)
+{
+	switch (type) {
+		case DBUS_FIRMWARE:
+			return dbus_get_fwfile(devid, chiprev, fw, fwlen, boardtype, boardrev, path);
+		case DBUS_NVFILE:
+			return dbus_get_nvfile(devid, chiprev, fw, fwlen, boardtype, boardrev, path);
+		default:
+			return NULL;
+	}
+}
+#else
+void *
+dbus_get_fw_nvfile(int devid, int chiprev, uint8 **fw, int *fwlen, int type, uint16 boardtype,
+	uint16 boardrev, char *path)
+{
+	const struct firmware *firmware = NULL;
+	int err = DBUS_OK;
+
+	err = dbus_request_firmware(path, &firmware);
+	if (err) {
+		DBUSERR(("fail to request firmware %s\n", path));
+		return NULL;
+	} else {
+		DBUSERR(("%s: %s (%zu bytes) open success\n",
+			__FUNCTION__, path, firmware->size));
+	}
+
+	*fwlen = firmware->size;
+	*fw = (uint8 *)firmware->data;
+	return (void *)firmware;
+}
+#endif
+
+void
+dbus_release_fw_nvfile(void *firmware)
+{
+	release_firmware((struct firmware *)firmware);
+}
+#endif /* BCM_REQUEST_FW */
+
+#ifdef BCMUSBDEV_COMPOSITE
+/**
+ * For a composite device the interface order is not guaranteed, scan the device struct for the WLAN
+ * interface.
+ */
+static int
+dbus_usbos_intf_wlan(struct usb_device *usb)
+{
+	int i, num_of_eps, ep, intf_wlan = -1;
+	int num_intf = CONFIGDESC(usb)->bNumInterfaces;
+	struct usb_endpoint_descriptor *endpoint;
+
+	for (i = 0; i < num_intf; i++) {
+		if (IFDESC(usb, i).bInterfaceClass != USB_CLASS_VENDOR_SPEC)
+			continue;
+		num_of_eps = IFDESC(usb, i).bNumEndpoints;
+
+		for (ep = 0; ep < num_of_eps; ep++) {
+			endpoint = &IFEPDESC(usb, i, ep);
+			if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
+				USB_ENDPOINT_XFER_BULK) {
+				intf_wlan = i;
+				break;
+			}
+		}
+		if (ep < num_of_eps)
+			break;
+	}
+
+	return intf_wlan;
+}
+#endif /* BCMUSBDEV_COMPOSITE */
+
+#ifdef KEEPIF_ON_DEVICE_RESET
+/* if keepif_on_devreset is set, and reset_resume or disconnect got called, we need de-register or
+ * register the usb driver to OS again; but this operation can't be called inside the reset_resume
+ * or disconnect callback, so introduce a kernel thread to do these work
+ */
+static int
+dbus_usbos_usbreset_func(void *data)
+{
+	enum usb_dev_status flag = USB_DEVICE_INIT;
+	usbos_info_t *usbos_info;
+
+	while (1) {
+		wait_event_interruptible_timeout(g_probe_info.usbreset_queue_head,
+			atomic_read(&g_probe_info.usbdev_stat), 100); /* 100 ms */
+
+		if (kthread_should_stop())
+			break;
+		if (!(usbos_info = g_probe_info.usbos_info))
+			continue;
+		if (!(flag = atomic_read(&g_probe_info.usbdev_stat)))
+			continue;
+
+		usbos_info = g_probe_info.usbos_info;
+		flag = atomic_read(&g_probe_info.usbdev_stat);
+		atomic_set(&g_probe_info.usbdev_stat, USB_DEVICE_INIT);
+
+		if ((flag == USB_DEVICE_RESETTED) || (flag == USB_DEVICE_DISCONNECTED)) {
+			DBUSERR(("Device reset, re-register USB driver\n"));
+			g_probe_info.dev_resetted = TRUE;
+			g_probe_info.busstate_bf_devreset = usbos_info->pub->busstate;
+			dbus_usbos_state_change(usbos_info, DBUS_STATE_DOWN);
+
+			g_probe_info.dereged = TRUE;
+			USB_DEREGISTER();
+			USB_REGISTER();
+			g_probe_info.dereged = FALSE;
+		} else if (flag == USB_DEVICE_PROBED) {
+			DBUSERR(("Device probed, but no need to initialize higher layer\n"));
+			g_probe_info.dev_resetted = FALSE;
+			dbus_usbos_init_info();
+			/* The device may have lost power, so a firmware download may be required */
+			dbus_usbos_state_change(usbos_info,
+				DBUS_STATE_DL_NEEDED);
+			g_probe_info.suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE;
+			dbus_usbos_state_change(usbos_info,
+				g_probe_info.busstate_bf_devreset);
+		}
+	}
+	return 0;
+}
+#endif /* KEEPIF_ON_DEVICE_RESET */
+
+#ifdef LINUX
+struct device * dbus_get_dev(void)
+{
+	return &g_probe_info.usb->dev;
+}
+#endif /* LINUX */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd.h
@@ -0,0 +1,4907 @@
+/*
+ * Header file describing the internal (inter-module) DHD interfaces.
+ *
+ * Provides type definitions and function prototypes used to link the
+ * DHD OS, bus, and protocol modules.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+/****************
+ * Common types *
+ */
+
+#ifndef _dhd_h_
+#define _dhd_h_
+
+#if defined(LINUX)
+#include <linux/firmware.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/ethtool.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+#include <linux/fs.h>
+#include <linux/namei.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
+#include <linux/sched/types.h>
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0) */
+#ifdef DHD_BUZZZ_LOG_ENABLED
+#include <dhd_buzzz.h>
+#endif /* DHD_BUZZZ_LOG_ENABLED */
+/* The kernel threading is sdio-specific */
+struct task_struct;
+struct sched_param;
+#if defined(BT_OVER_SDIO)
+#include <dhd_bt_interface.h>
+#endif /* defined (BT_OVER_SDIO) */
+int setScheduler(struct task_struct *p, int policy, struct sched_param *param);
+int get_scheduler_policy(struct task_struct *p);
+#else /* LINUX */
+#define ENOMEM		1
+#define EFAULT      2
+#define EINVAL		3
+#define EIO			4
+#define ETIMEDOUT	5
+#define ENODATA 6
+#define EREMOTEIO   7
+#define ENODEV      8
+#define ENOCSI		50	/* No CSI structure available */
+#define ERESTARTSYS 512
+#endif /* LINUX */
+#define MAX_EVENT	16
+
+#define ALL_INTERFACES	0xff
+
+/* H2D and D2H ring dump is enabled by default */
+#ifdef PCIE_FULL_DONGLE
+#define DHD_DUMP_PCIE_RINGS
+#endif /* PCIE_FULL_DONGLE */
+
+#include <osl.h>
+
+#include <wlioctl.h>
+#include <dhdioctl.h>
+#include <wlfc_proto.h>
+#include <hnd_armtrap.h>
+#if defined(DUMP_IOCTL_IOV_LIST) || defined(DHD_DEBUG)
+#include <bcmutils.h>
+#endif /* DUMP_IOCTL_IOV_LIST || DHD_DEBUG */
+
+#if defined(BCMWDF)
+#include <wdf.h>
+#include <WdfMiniport.h>
+#endif /* (BCMWDF)  */
+
+#ifdef WL_CFGVENDOR_SEND_HANG_EVENT
+#include <dnglioctl.h>
+#endif /* WL_CFGVENDOR_SEND_HANG_EVENT */
+#include <dngl_stats.h>
+#include <hnd_pktq.h>
+
+#ifdef DEBUG_DPC_THREAD_WATCHDOG
+#define MAX_RESCHED_CNT 600
+#endif /* DEBUG_DPC_THREAD_WATCHDOG */
+
+#if defined(LINUX) || defined(linux)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) && LINUX_VERSION_CODE < \
+	KERNEL_VERSION(3, 18, 0) || defined(CONFIG_BCMDHD_VENDOR_EXT))
+#ifndef WL_VENDOR_EXT_SUPPORT
+#define WL_VENDOR_EXT_SUPPORT
+#endif /* WL_VENDOR_EXT_SUPPORT */
+#endif /* 3.18 > KERNEL_VER >= 3.14 || defined(CONFIG_BCMDHD_VENDOR_EXT) */
+#endif /* defined (LINUX) || defined(linux) */
+
+#if defined(KEEP_ALIVE)
+/* Default KEEP_ALIVE Period is 55 sec to prevent AP from sending Keep Alive probe frame */
+#define KEEP_ALIVE_PERIOD 55000
+#define NULL_PKT_STR	"null_pkt"
+#endif /* KEEP_ALIVE */
+
+/* By default enabled from here, later the WQ code will be removed */
+#define DHD_USE_KTHREAD_FOR_LOGTRACE
+
+/* Forward decls */
+struct dhd_bus;
+struct dhd_prot;
+struct dhd_info;
+struct dhd_ioctl;
+struct dhd_dbg;
+struct dhd_ts;
+#ifdef DNGL_AXI_ERROR_LOGGING
+struct dhd_axi_error_dump;
+#endif /* DNGL_AXI_ERROR_LOGGING */
+
+/* The level of bus communication with the dongle */
+enum dhd_bus_state {
+	DHD_BUS_DOWN,		/* Not ready for frame transfers */
+	DHD_BUS_LOAD,		/* Download access only (CPU reset) */
+	DHD_BUS_DATA,		/* Ready for frame transfers */
+	DHD_BUS_SUSPEND,	/* Bus has been suspended */
+	DHD_BUS_DOWN_IN_PROGRESS,	/* Bus going Down */
+	DHD_BUS_REMOVE,	/* Bus has been removed */
+};
+
+/* The level of bus communication with the dongle */
+enum dhd_bus_devreset_type {
+	DHD_BUS_DEVRESET_ON = 0,	/* ON */
+	DHD_BUS_DEVRESET_OFF = 1,		/* OFF */
+	DHD_BUS_DEVRESET_FLR = 2,		/* FLR */
+	DHD_BUS_DEVRESET_FLR_FORCE_FAIL = 3,	/* FLR FORCE FAIL */
+	DHD_BUS_DEVRESET_QUIESCE = 4,		/* FLR */
+};
+
+/*
+ * Bit fields to Indicate clean up process that wait till they are finished.
+ * Future synchronizable processes can add their bit filed below and update
+ * their functionalities accordingly
+ */
+#define DHD_BUS_BUSY_IN_TX                   0x01
+#define DHD_BUS_BUSY_IN_SEND_PKT             0x02
+#define DHD_BUS_BUSY_IN_DPC                  0x04
+#define DHD_BUS_BUSY_IN_WD                   0x08
+#define DHD_BUS_BUSY_IN_IOVAR                0x10
+#define DHD_BUS_BUSY_IN_DHD_IOVAR            0x20
+#define DHD_BUS_BUSY_SUSPEND_IN_PROGRESS     0x40
+#define DHD_BUS_BUSY_RESUME_IN_PROGRESS      0x80
+#define DHD_BUS_BUSY_RPM_SUSPEND_IN_PROGRESS 0x100
+#define DHD_BUS_BUSY_RPM_SUSPEND_DONE        0x200
+#define DHD_BUS_BUSY_RPM_RESUME_IN_PROGRESS  0x400
+#define DHD_BUS_BUSY_RPM_ALL                 (DHD_BUS_BUSY_RPM_SUSPEND_DONE | \
+		DHD_BUS_BUSY_RPM_SUSPEND_IN_PROGRESS | \
+		DHD_BUS_BUSY_RPM_RESUME_IN_PROGRESS)
+#define DHD_BUS_BUSY_IN_CHECKDIED		0x800
+#define DHD_BUS_BUSY_IN_MEMDUMP			0x1000
+#define DHD_BUS_BUSY_IN_SSSRDUMP		0x2000
+#define DHD_BUS_BUSY_IN_LOGDUMP			0x4000
+#define DHD_BUS_BUSY_IN_HALDUMP			0x8000
+#define DHD_BUS_BUSY_IN_NAPI			0x10000
+#define DHD_BUS_BUSY_IN_DS_DEASSERT		0x20000
+#define DHD_BUS_BUSY_IN_DUMP_DONGLE_MEM		0x40000
+#define DHD_BUS_BUSY_IN_SYSFS_DUMP		0x80000
+#define DHD_BUS_BUSY_IN_PM_CALLBACK		0x100000
+
+#define DHD_BUS_BUSY_SET_IN_TX(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_TX
+#define DHD_BUS_BUSY_SET_IN_SEND_PKT(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_SEND_PKT
+#define DHD_BUS_BUSY_SET_IN_DPC(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_DPC
+#define DHD_BUS_BUSY_SET_IN_WD(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_WD
+#define DHD_BUS_BUSY_SET_IN_IOVAR(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_IOVAR
+#define DHD_BUS_BUSY_SET_IN_DHD_IOVAR(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_DHD_IOVAR
+#define DHD_BUS_BUSY_SET_SUSPEND_IN_PROGRESS(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_SUSPEND_IN_PROGRESS
+#define DHD_BUS_BUSY_SET_RESUME_IN_PROGRESS(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_RESUME_IN_PROGRESS
+#define DHD_BUS_BUSY_SET_RPM_SUSPEND_IN_PROGRESS(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_RPM_SUSPEND_IN_PROGRESS
+#define DHD_BUS_BUSY_SET_RPM_SUSPEND_DONE(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_RPM_SUSPEND_DONE
+#define DHD_BUS_BUSY_SET_RPM_RESUME_IN_PROGRESS(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_RPM_RESUME_IN_PROGRESS
+#define DHD_BUS_BUSY_SET_IN_CHECKDIED(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_CHECKDIED
+#define DHD_BUS_BUSY_SET_IN_MEMDUMP(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_MEMDUMP
+#define DHD_BUS_BUSY_SET_IN_SSSRDUMP(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_SSSRDUMP
+#define DHD_BUS_BUSY_SET_IN_LOGDUMP(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_LOGDUMP
+#define DHD_BUS_BUSY_SET_IN_HALDUMP(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_HALDUMP
+#define DHD_BUS_BUSY_SET_IN_NAPI(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_NAPI
+#define DHD_BUS_BUSY_SET_IN_DS_DEASSERT(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_DS_DEASSERT
+#define DHD_BUS_BUSY_SET_IN_DUMP_DONGLE_MEM(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_DUMP_DONGLE_MEM
+#define DHD_BUS_BUSY_SET_IN_SYSFS_DUMP(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_SYSFS_DUMP
+#define DHD_BUS_BUSY_SET_IN_PM_CALLBACK(dhdp) \
+	(dhdp)->dhd_bus_busy_state |= DHD_BUS_BUSY_IN_PM_CALLBACK
+
+#define DHD_BUS_BUSY_CLEAR_IN_TX(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_TX
+#define DHD_BUS_BUSY_CLEAR_IN_SEND_PKT(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_SEND_PKT
+#define DHD_BUS_BUSY_CLEAR_IN_DPC(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_DPC
+#define DHD_BUS_BUSY_CLEAR_IN_WD(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_WD
+#define DHD_BUS_BUSY_CLEAR_IN_IOVAR(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_IOVAR
+#define DHD_BUS_BUSY_CLEAR_IN_DHD_IOVAR(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_DHD_IOVAR
+#define DHD_BUS_BUSY_CLEAR_SUSPEND_IN_PROGRESS(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_SUSPEND_IN_PROGRESS
+#define DHD_BUS_BUSY_CLEAR_RESUME_IN_PROGRESS(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_RESUME_IN_PROGRESS
+#define DHD_BUS_BUSY_CLEAR_RPM_SUSPEND_IN_PROGRESS(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_RPM_SUSPEND_IN_PROGRESS
+#define DHD_BUS_BUSY_CLEAR_RPM_SUSPEND_DONE(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_RPM_SUSPEND_DONE
+#define DHD_BUS_BUSY_CLEAR_RPM_RESUME_IN_PROGRESS(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_RPM_RESUME_IN_PROGRESS
+#define DHD_BUS_BUSY_CLEAR_IN_CHECKDIED(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_CHECKDIED
+#define DHD_BUS_BUSY_CLEAR_IN_MEMDUMP(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_MEMDUMP
+#define DHD_BUS_BUSY_CLEAR_IN_SSSRDUMP(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_SSSRDUMP
+#define DHD_BUS_BUSY_CLEAR_IN_LOGDUMP(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_LOGDUMP
+#define DHD_BUS_BUSY_CLEAR_IN_HALDUMP(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_HALDUMP
+#define DHD_BUS_BUSY_CLEAR_IN_NAPI(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_NAPI
+#define DHD_BUS_BUSY_CLEAR_IN_DS_DEASSERT(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_DS_DEASSERT
+#define DHD_BUS_BUSY_CLEAR_IN_DUMP_DONGLE_MEM(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_DUMP_DONGLE_MEM
+#define DHD_BUS_BUSY_CLEAR_IN_SYSFS_DUMP(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_SYSFS_DUMP
+#define DHD_BUS_BUSY_CLEAR_IN_PM_CALLBACK(dhdp) \
+	(dhdp)->dhd_bus_busy_state &= ~DHD_BUS_BUSY_IN_PM_CALLBACK
+
+#define DHD_BUS_BUSY_CHECK_IN_TX(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_TX)
+#define DHD_BUS_BUSY_CHECK_IN_SEND_PKT(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_SEND_PKT)
+#define DHD_BUS_BUSY_CHECK_IN_DPC(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_DPC)
+#define DHD_BUS_BUSY_CHECK_IN_WD(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_WD)
+#define DHD_BUS_BUSY_CHECK_IN_IOVAR(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_IOVAR)
+#define DHD_BUS_BUSY_CHECK_IN_DHD_IOVAR(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_DHD_IOVAR)
+#define DHD_BUS_BUSY_CHECK_SUSPEND_IN_PROGRESS(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_SUSPEND_IN_PROGRESS)
+#define DHD_BUS_BUSY_CHECK_RESUME_IN_PROGRESS(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_RESUME_IN_PROGRESS)
+#define DHD_BUS_BUSY_CHECK_RPM_SUSPEND_IN_PROGRESS(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_RPM_SUSPEND_IN_PROGRESS)
+#define DHD_BUS_BUSY_CHECK_RPM_SUSPEND_DONE(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_RPM_SUSPEND_DONE)
+#define DHD_BUS_BUSY_CHECK_RPM_RESUME_IN_PROGRESS(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_RPM_RESUME_IN_PROGRESS)
+#define DHD_BUS_BUSY_CHECK_RPM_ALL(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_RPM_ALL)
+#define DHD_BUS_BUSY_CHECK_IN_CHECKDIED(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_CHECKDIED)
+#define DHD_BUS_BUSY_CHECK_IN_MEMDUMP(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_MEMDUMP)
+#define DHD_BUS_BUSY_CHECK_IN_SSSRDUMP(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_SSSRDUMP)
+#define DHD_BUS_BUSY_CHECK_IN_LOGDUMP(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_LOGDUMP)
+#define DHD_BUS_BUSY_CHECK_IN_HALDUMP(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_HALDUMP)
+#define DHD_BUS_BUSY_CHECK_IN_DS_DEASSERT(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_DS_DEASSERT)
+#define DHD_BUS_BUSY_CHECK_IN_DUMP_DONGLE_MEM(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_DUMP_DONGLE_MEM)
+#define DHD_BUS_BUSY_CHECK_IN_SYSFS_DUMP(dhdp) \
+	((dhdp)->dhd_bus_busy_state & DHD_BUS_BUSY_IN_SYSFS_DUMP)
+#define DHD_BUS_BUSY_CHECK_IDLE(dhdp) \
+	((dhdp)->dhd_bus_busy_state == 0)
+
+#define DHD_BUS_CHECK_SUSPEND_OR_SUSPEND_IN_PROGRESS(dhdp) \
+	((dhdp)->busstate == DHD_BUS_SUSPEND || DHD_BUS_BUSY_CHECK_SUSPEND_IN_PROGRESS(dhdp))
+
+#define DHD_BUS_CHECK_ANY_SUSPEND_IN_PROGRESS(dhdp) \
+		(DHD_BUS_BUSY_CHECK_SUSPEND_IN_PROGRESS(dhdp) || \
+		 DHD_BUS_BUSY_CHECK_RPM_SUSPEND_IN_PROGRESS(dhdp))
+
+#define DHD_BUS_CHECK_SUSPEND_OR_ANY_SUSPEND_IN_PROGRESS(dhdp) \
+	((dhdp)->busstate == DHD_BUS_SUSPEND || DHD_BUS_CHECK_ANY_SUSPEND_IN_PROGRESS(dhdp))
+
+#define DHD_BUS_CHECK_DOWN_OR_DOWN_IN_PROGRESS(dhdp) \
+		((dhdp)->busstate == DHD_BUS_DOWN || (dhdp)->busstate == DHD_BUS_DOWN_IN_PROGRESS || \
+		(dhdp)->busstate == DHD_BUS_REMOVE)
+
+#define DHD_BUS_CHECK_REMOVE(dhdp) \
+		((dhdp)->busstate == DHD_BUS_REMOVE)
+
+/* IOVar flags for common error checks */
+#define DHD_IOVF_PWRREQ_BYPASS	(1<<0) /* flags to prevent bp access during host sleep state */
+
+#define MAX_MTU_SZ (1600u)
+
+#ifdef PCIE_INB_DW
+#define DHD_CHECK_CFG_IN_PROGRESS(dhdp) \
+	((INBAND_DW_ENAB((dhdp)->bus)) ? dhd_check_cfg_in_progress(dhdp) : FALSE)
+#else
+#define DHD_CHECK_CFG_IN_PROGRESS(dhdp) FALSE
+#endif /* PCIE_INB_DW */
+
+#ifndef USEC_PER_SEC
+#define USEC_PER_SEC (1000 * 1000)
+#endif
+#ifndef MSEC_PER_SEC
+#define MSEC_PER_SEC 1000u
+#endif
+
+#define TIMESPEC64_TO_US(ts) \
+	(((ts).tv_sec * USEC_PER_SEC) + ((ts).tv_nsec / NSEC_PER_USEC))
+
+#if (defined(LINUX) || defined(linux))
+/* (u64)result = (u64)dividend / (u64)divisor */
+#define DIV_U64_BY_U64(dividend, divisor)	div64_u64(dividend, divisor)
+
+/* (u64)result = (u64)dividend / (u32)divisor */
+#define DIV_U64_BY_U32(dividend, divisor)	div_u64(dividend, divisor)
+
+/* Be careful while using this, as it divides dividend also
+ * (u32)remainder = (u64)dividend % (u32)divisor
+ * (u64)dividend = (u64)dividend / (u32)divisor
+ */
+#define DIV_AND_MOD_U64_BY_U32(dividend, divisor)	do_div(dividend, divisor)
+
+/* (u32)remainder = (u64)dividend % (u32)divisor */
+#define MOD_U64_BY_U32(dividend, divisor) ({				\
+	uint64 temp_dividend = (dividend);				\
+	uint32 rem = DIV_AND_MOD_U64_BY_U32(temp_dividend, (divisor));	\
+	rem;								\
+})
+
+#define SEC_USEC_FMT \
+	"%5llu.%06u"
+#else
+/* (u64)result = (u64)dividend / (u64)divisor */
+#define DIV_U64_BY_U64(dividend, divisor)	(uint64)(dividend) / (uint64)(divisor)
+
+/* (u64)result = (u64)dividend / (u32)divisor */
+#define DIV_U64_BY_U32(dividend, divisor)	(uint64)(dividend) / (uint32)(divisor)
+
+/* Be careful while using this, as it divides dividend also
+ * (u32)remainder = (u64)dividend % (u32)divisor
+ * (u64)dividend = (u64)dividend / (u32)divisor
+ */
+#define DIV_AND_MOD_U64_BY_U32(dividend, divisor) ({		\
+	uint32 rem = (uint64)(dividend) % (uint32)(divisor);	\
+	(dividend) = (uint64)(dividend) / (uint32)(divisor);	\
+	rem;							\
+})
+
+/* (u32)remainder = (u64)dividend % (u32)divisor */
+#define MOD_U64_BY_U32(dividend, divisor)	(uint32)((uint64)(dividend) % (uint32)(divisor))
+
+#define SEC_USEC_FMT \
+	"%015llu.%06u"
+#endif /* LINUX || linux */
+
+/* t: time in nano second */
+#define GET_SEC_USEC(t) \
+	DIV_U64_BY_U32(t, NSEC_PER_SEC), \
+	((uint32)(MOD_U64_BY_U32(t, NSEC_PER_SEC) / (uint32)NSEC_PER_USEC))
+
+/* Download Types */
+typedef enum download_type {
+	FW,
+	NVRAM,
+	CLM_BLOB,
+	TXCAP_BLOB
+} download_type_t;
+
+#if defined(NDIS)
+/* Firmware requested operation mode */
+#define STA_MASK			0x0001
+#define HOSTAPD_MASK		0x0002
+#define WFD_MASK			0x0004
+#define SOFTAP_FW_MASK	0x0008
+#define P2P_GO_ENABLED		0x0010
+#define P2P_GC_ENABLED		0x0020
+#define CONCURENT_MASK		0x00F0
+#endif /* #if defined(NDIS) */
+
+/* For supporting multiple interfaces */
+#define DHD_MAX_IFS			16
+#ifndef DHD_MAX_STATIC_IFS
+#define DHD_MAX_STATIC_IFS	1
+#endif
+#define DHD_DEL_IF			-0xE
+#define DHD_BAD_IF			-0xF
+#define DHD_DUMMY_INFO_IF	0xDEAF	/* Hack i/f to handle events from INFO Ring */
+/* XXX to avoid build error for NDIS for timebeing */
+#define DHD_EVENT_IF DHD_DUMMY_INFO_IF
+
+#if defined(LINUX) || defined(linux)
+enum dhd_op_flags {
+/* Firmware requested operation mode */
+	DHD_FLAG_STA_MODE				= (1 << (0)), /* STA only */
+	DHD_FLAG_HOSTAP_MODE				= (1 << (1)), /* SOFTAP only */
+	DHD_FLAG_P2P_MODE				= (1 << (2)), /* P2P Only */
+	/* STA + P2P */
+	DHD_FLAG_CONCURR_SINGLE_CHAN_MODE = (DHD_FLAG_STA_MODE | DHD_FLAG_P2P_MODE),
+	/* STA + SoftAP */
+	DHD_FLAG_CONCURR_STA_HOSTAP_MODE = (DHD_FLAG_STA_MODE | DHD_FLAG_HOSTAP_MODE),
+	/* XXX MULTI_CHAN mode is meaningful only if it is conccurncy mode */
+	DHD_FLAG_CONCURR_MULTI_CHAN_MODE		= (1 << (4)), /* STA + P2P */
+	/* Current P2P mode for P2P connection */
+	DHD_FLAG_P2P_GC_MODE				= (1 << (5)),
+	DHD_FLAG_P2P_GO_MODE				= (1 << (6)),
+	DHD_FLAG_MBSS_MODE				= (1 << (7)), /* MBSS in future */
+	DHD_FLAG_IBSS_MODE				= (1 << (8)),
+	DHD_FLAG_MFG_MODE				= (1 << (9)),
+	DHD_FLAG_RSDB_MODE				= (1 << (10)),
+	DHD_FLAG_MP2P_MODE				= (1 << (11))
+};
+#endif /* defined (LINUX) || defined(linux) */
+
+#if defined(BCMDONGLEHOST)
+#define DHD_OPMODE_SUPPORTED(dhd, opmode_flag) \
+	(dhd ? ((((dhd_pub_t *)dhd)->op_mode)  &  opmode_flag) : -1)
+#define DHD_OPMODE_STA_SOFTAP_CONCURR(dhd) \
+	(dhd ? (((((dhd_pub_t *)dhd)->op_mode) & DHD_FLAG_CONCURR_STA_HOSTAP_MODE) == \
+	DHD_FLAG_CONCURR_STA_HOSTAP_MODE) : 0)
+#else
+#define DHD_OPMODE_SUPPORTED(dhd, opmode_flag)  -1
+#define DHD_OPMODE_STA_SOFTAP_CONCURR(dhd)	0
+#endif /* defined (BCMDONGLEHOST) */
+
+/* Max sequential TX/RX Control timeouts to set HANG event */
+#ifndef MAX_CNTL_TX_TIMEOUT
+#define MAX_CNTL_TX_TIMEOUT 2
+#endif /* MAX_CNTL_TX_TIMEOUT */
+#ifndef MAX_CNTL_RX_TIMEOUT
+#define MAX_CNTL_RX_TIMEOUT 1
+#endif /* MAX_CNTL_RX_TIMEOUT */
+
+#define DHD_SCAN_ASSOC_ACTIVE_TIME	40 /* ms: Embedded default Active setting from DHD */
+#ifndef CUSTOM_SCAN_UNASSOC_ACTIVE_TIME
+#define DHD_SCAN_UNASSOC_ACTIVE_TIME	80 /* ms: Embedded def. Unassoc Active setting from DHD */
+#else
+#define DHD_SCAN_UNASSOC_ACTIVE_TIME	CUSTOM_SCAN_UNASSOC_ACTIVE_TIME
+#endif /* CUSTOM_SCAN_UNASSOC_ACTIVE_TIME */
+#define DHD_SCAN_HOME_TIME		45 /* ms: Embedded default Home time setting from DHD */
+#ifndef CUSTOM_SCAN_HOME_AWAY_TIME
+#define DHD_SCAN_HOME_AWAY_TIME	100 /* ms: Embedded default Home Away time setting from DHD */
+#else
+#define DHD_SCAN_HOME_AWAY_TIME CUSTOM_SCAN_HOME_AWAY_TIME /* ms: Custom setting from DHD */
+#endif /* CUSTOM_SCAN_HOME_AWAY_TIME */
+#ifndef CUSTOM_SCAN_PASSIVE_TIME
+#define DHD_SCAN_PASSIVE_TIME		130 /* ms: Embedded default Passive setting from DHD */
+#else
+#define DHD_SCAN_PASSIVE_TIME	CUSTOM_SCAN_PASSIVE_TIME /* ms: Custom Passive setting from DHD */
+#endif /* CUSTOM_SCAN_PASSIVE_TIME */
+
+#ifndef POWERUP_MAX_RETRY
+#define POWERUP_MAX_RETRY	3 /* how many times we retry to power up the chip */
+#endif
+#ifndef POWERUP_WAIT_MS
+#define POWERUP_WAIT_MS		2000 /* ms: time out in waiting wifi to come up */
+#endif
+/*
+ * MAX_NVRAMBUF_SIZE determines the size of the Buffer in the DHD that holds
+ * the NVRAM data. That is the size of the buffer pointed by bus->vars
+ * This also needs to be increased if NVRAM files size increases
+ */
+#define MAX_NVRAMBUF_SIZE	(32 * 1024) /* max nvram buf size */
+#define MAX_CLM_BUF_SIZE	(64 * 1024) /* max clm blob size */
+#define MAX_TXCAP_BUF_SIZE	(16 * 1024) /* max txcap blob size */
+#ifdef DHD_DEBUG
+#define DHD_JOIN_MAX_TIME_DEFAULT 10000 /* ms: Max time out for joining AP */
+#define DHD_SCAN_DEF_TIMEOUT 10000 /* ms: Max time out for scan in progress */
+#endif /* DHD_DEBUG */
+
+/* Enable Flow ring pre-memory allocation by default for Android */
+#ifdef OEM_ANDROID
+#define FLOW_RING_PREALLOC
+#endif /* OEM_ANDROID */
+
+#ifndef CONFIG_BCMDHD_FW_PATH
+#ifdef OEM_ANDROID
+#define CONFIG_BCMDHD_FW_PATH  "/system/vendor/etc/wifi/fw_bcmdhd.bin"
+#else
+#define CONFIG_BCMDHD_FW_PATH  "/var/run/rtecdc.bin"
+#endif /* OEM_ANDROID */
+#endif /* CONFIG_BCMDHD_FW_PATH */
+
+#ifndef CONFIG_BCMDHD_NVRAM_PATH
+#ifdef OEM_ANDROID
+#define CONFIG_BCMDHD_NVRAM_PATH  "/system/vendor/etc/wifi/bcmdhd.cal"
+#else
+#define CONFIG_BCMDHD_NVRAM_PATH  "/var/run/nvram.txt"
+#endif /* OEM_ANDROID */
+#endif /* CONFIG_BCMDHD_NVRAM_PATH */
+
+#ifndef CONFIG_BCMDHD_CLM_PATH
+#ifdef OEM_ANDROID
+#if defined(CUSTOMER_HW4) && defined(PLATFORM_SLP)
+#define CONFIG_BCMDHD_CLM_PATH "/lib/firmware/bcmdhd_clm.blob"
+#else
+#define CONFIG_BCMDHD_CLM_PATH "/etc/wifi/bcmdhd_clm.blob"
+#endif /* CUSTOMER_HW4 && PLATFORM_SLP */
+#elif defined(LINUX) || defined(linux)
+#define CONFIG_BCMDHD_CLM_PATH "/var/run/bcmdhd_clm.blob"
+#else
+/* clm download will fail on empty path */
+#define CONFIG_BCMDHD_CLM_PATH ""
+#endif /* OEM_ANDROID */
+#endif /* CONFIG_BCMDHD_CLM_PATH */
+
+#ifdef DHD_LINUX_STD_FW_API
+#ifndef CONFIG_BCMDHD_CONFIG_SAR_PATH
+#define CONFIG_BCMDHD_CONFIG_SAR_PATH  "sar_config.ini"
+#endif /* CONFIG_BCMDHD_CONFIG_SAR_PATH */
+#ifndef CONFIG_BCMDHD_CONFIG_PATH
+#define CONFIG_BCMDHD_CONFIG_PATH	"wlan_config.ini"
+#endif /* CONFIG_BCMDHD_CONFIG_PATH */
+#else
+#ifndef CONFIG_BCMDHD_CONFIG_SAR_PATH
+#ifdef OEM_ANDROID
+#define CONFIG_BCMDHD_CONFIG_SAR_PATH  "/system/vendor/etc/wifi/sar_config.ini"
+#else /* OEM_ANDROID */
+#define CONFIG_BCMDHD_CONFIG_SAR_PATH  "/var/run/sar_config.ini"
+#endif /* OEM_ANDROID */
+#endif /* CONFIG_BCMDHD_CONFIG_SAR_PATH */
+
+#ifndef CONFIG_BCMDHD_CONFIG_PATH
+#ifdef OEM_ANDROID
+#define CONFIG_BCMDHD_CONFIG_PATH  "/system/vendor/etc/wifi/wlan_config.ini"
+#else /* OEM_ANDROID */
+#define CONFIG_BCMDHD_CONFIG_PATH  "/var/run/wlan_config.ini"
+#endif /* OEM_ANDROID */
+#endif /* CONFIG_BCMDHD_CONFIG_PATH */
+#endif /* DHD_LINUX_STD_FW_API */
+
+#ifndef CONFIG_BCMDHD_MAP_PATH
+	#ifdef OEM_ANDROID
+		#define CONFIG_BCMDHD_MAP_PATH  "/system/vendor/etc/wifi/rtecdc.map"
+	#else // OEM_ANDROID
+		#define CONFIG_BCMDHD_MAP_PATH  "rtecdc.map"
+	#endif // OEM_ANDROID
+#endif /* CONFIG_BCMDHD_MAP_PATH */
+
+/* for file operation compatibility */
+#ifdef DHD_LINUX_STD_FW_API
+	// kernel has enable the corresponding API
+	#if defined(CONFIG_FW_LOADER) || (defined(CONFIG_FW_LOADER_MODULE) && defined(MODULE))
+		#ifndef DHD_FW_NAME
+		#define DHD_FW_NAME       CONFIG_BCMDHD_FW_PATH
+		#endif // DHD_FW_NAME
+		#ifndef DHD_NVRAM_NAME
+		#define DHD_NVRAM_NAME    CONFIG_BCMDHD_NVRAM_PATH
+		#endif // DHD_NVRAM_NAME
+		#ifndef DHD_CLM_NAME
+		#define DHD_CLM_NAME      CONFIG_BCMDHD_CLM_PATH
+		#endif // DHD_CLM_NAME
+		#ifndef DHD_MAP_NAME
+		#define DHD_MAP_NAME      CONFIG_BCMDHD_MAP_PATH
+		#endif // DHD_MAP_NAME
+		#ifndef FILTER_IE_NAME
+		#define FILTER_IE_NAME    "filter_ie"
+		#endif // FILTER_IE_NAME
+	#else // defined(CONFIG_FW_LOADER) || (defined(CONFIG_FW_LOADER_MODULE) && defined(MODULE))
+		#error "*Error, KERNEL does not enable the CONFIG_FW_LOADER(_MODULE) "\
+			"for DHD_LINUX_STD_FW_API!"
+	#endif // defined(CONFIG_FW_LOADER) || (defined(CONFIG_FW_LOADER_MODULE) && defined(MODULE))
+#else /* DHD_LINUX_STD_FW_API */
+	#ifndef DHD_SUPPORT_VFS_CALL
+		#error "*Error, Makefile should pick up either "\
+			"'DHD_LINUX_STD_FW_API' or 'DHD_SUPPORT_VFS_CALL'!"
+	#endif // DHD_SUPPORT_VFS_CALL
+#endif /* DHD_LINUX_STD_FW_API */
+
+#define WL_CCODE_NULL_COUNTRY  "#n"
+
+#define FW_VER_STR_LEN	128
+#define FWID_STR_LEN 256
+#define CLM_VER_STR_LEN 128
+#define BUS_API_REV_STR_LEN	128
+#define FW_VER_STR "Version"
+#define FWID_STR_1 "FWID: 01-"
+#define FWID_STR_2 "FWID=01-"
+extern char bus_api_revision[];
+
+enum dhd_bus_wake_state {
+	WAKE_LOCK_OFF			= 0,
+	WAKE_LOCK_PRIV			= 1,
+	WAKE_LOCK_DPC			= 2,
+	WAKE_LOCK_IOCTL			= 3,
+	WAKE_LOCK_DOWNLOAD		= 4,
+	WAKE_LOCK_TMOUT			= 5,
+	WAKE_LOCK_WATCHDOG		= 6,
+	WAKE_LOCK_LINK_DOWN_TMOUT	= 7,
+	WAKE_LOCK_PNO_FIND_TMOUT	= 8,
+	WAKE_LOCK_SOFTAP_SET		= 9,
+	WAKE_LOCK_SOFTAP_STOP		= 10,
+	WAKE_LOCK_SOFTAP_START		= 11,
+	WAKE_LOCK_SOFTAP_THREAD		= 12
+};
+
+enum {
+	EVENT_BUF_POOL_LOW = 32,
+	EVENT_BUF_POOL_MEDIUM = 64,
+	EVENT_BUF_POOL_HIGH = 128,
+	EVENT_BUF_POOL_HIGHEST = 256
+};
+
+#ifdef PCIE_INB_DW
+enum dhd_bus_ds_state {
+	DW_DEVICE_DS_INVALID		= -1,
+	DW_DEVICE_DS_DEV_SLEEP		= 0,
+	DW_DEVICE_DS_DEV_SLEEP_PEND	= 1,
+	DW_DEVICE_DS_DISABLED_WAIT	= 2,
+	DW_DEVICE_DS_DEV_WAKE		= 3,
+	DW_DEVICE_DS_ACTIVE		= 4,
+	DW_DEVICE_HOST_SLEEP_WAIT	= 5,
+	DW_DEVICE_HOST_SLEEP		= 6,
+	DW_DEVICE_HOST_WAKE_WAIT	= 7,
+	DW_DEVICE_DS_D3_INFORM_WAIT	= 8
+};
+#ifdef PCIE_INB_DSACK_EXT_WAIT
+/* DS ack timeout is 3sec, FW retry count is 5.
+ * 5times * 3sec = 15sec.
+ */
+#define DW_DS_ACK_RETRY_THRESHOLD		15u
+#endif /* PCIE_INB_DSACK_EXT_WAIT */
+#endif /* PCIE_INB_DW */
+
+enum dhd_prealloc_index {
+	DHD_PREALLOC_PROT			= 0,
+	DHD_PREALLOC_RXBUF			= 1,
+	DHD_PREALLOC_DATABUF			= 2,
+	DHD_PREALLOC_OSL_BUF			= 3,
+	DHD_PREALLOC_SKB_BUF = 4,
+	DHD_PREALLOC_WIPHY_ESCAN0		= 5,
+	DHD_PREALLOC_WIPHY_ESCAN1		= 6,
+	DHD_PREALLOC_DHD_INFO			= 7,
+	DHD_PREALLOC_DHD_WLFC_INFO		= 8,
+	DHD_PREALLOC_IF_FLOW_LKUP		= 9,
+	/* 10 */
+	DHD_PREALLOC_MEMDUMP_RAM		= 11,
+	DHD_PREALLOC_DHD_WLFC_HANGER		= 12,
+	DHD_PREALLOC_PKTID_MAP			= 13,	/* Deprecated */
+	DHD_PREALLOC_PKTID_MAP_IOCTL		= 14,	/* Deprecated */
+	DHD_PREALLOC_DHD_LOG_DUMP_BUF		= 15,
+	DHD_PREALLOC_DHD_LOG_DUMP_BUF_EX	= 16,
+	DHD_PREALLOC_DHD_PKTLOG_DUMP_BUF	= 17,	/* Deprecated */
+	DHD_PREALLOC_STAT_REPORT_BUF = 18,
+	DHD_PREALLOC_WL_ESCAN = 19,
+	DHD_PREALLOC_FW_VERBOSE_RING = 20,
+	DHD_PREALLOC_FW_EVENT_RING = 21,
+	DHD_PREALLOC_DHD_EVENT_RING = 22,
+	DHD_PREALLOC_NAN_EVENT_RING = 23
+};
+
+enum dhd_dongledump_mode {
+	DUMP_DISABLED		= 0,
+	DUMP_MEMONLY		= 1,
+	DUMP_MEMFILE		= 2,
+	DUMP_MEMFILE_BUGON	= 3,
+	DUMP_MEMFILE_MAX	= 4
+};
+
+#if defined(DHD_FILE_DUMP_EVENT) && defined(DHD_FW_COREDUMP)
+typedef enum dhd_dongledump_status {
+	DUMP_READY		= 0,
+	DUMP_IN_PROGRESS	= 1,
+	DUMP_FAILURE		= 2,
+	DUMP_NOT_READY		= 3
+} dhd_dongledump_status_t;
+#endif /* DHD_FILE_DUMP_EVENT && DHD_FW_COREDUMP */
+
+enum dhd_dongledump_type {
+	DUMP_TYPE_RESUMED_ON_TIMEOUT		= 1,
+	DUMP_TYPE_D3_ACK_TIMEOUT		= 2,
+	DUMP_TYPE_DONGLE_TRAP			= 3,
+	DUMP_TYPE_MEMORY_CORRUPTION		= 4,
+	DUMP_TYPE_PKTID_AUDIT_FAILURE		= 5,
+	DUMP_TYPE_PKTID_INVALID			= 6,
+	DUMP_TYPE_SCAN_TIMEOUT			= 7,
+	DUMP_TYPE_SCAN_BUSY			= 8,
+	DUMP_TYPE_BY_SYSDUMP			= 9,
+	DUMP_TYPE_BY_LIVELOCK			= 10,
+	DUMP_TYPE_AP_LINKUP_FAILURE		= 11,
+	DUMP_TYPE_AP_ABNORMAL_ACCESS		= 12,
+	DUMP_TYPE_CFG_VENDOR_TRIGGERED		= 13,
+	DUMP_TYPE_RESUMED_ON_TIMEOUT_TX		= 14,
+	DUMP_TYPE_RESUMED_ON_TIMEOUT_RX		= 15,
+	DUMP_TYPE_RESUMED_ON_INVALID_RING_RDWR	= 16,
+	DUMP_TYPE_TRANS_ID_MISMATCH		= 17,
+	DUMP_TYPE_IFACE_OP_FAILURE		= 18,
+	DUMP_TYPE_DONGLE_INIT_FAILURE		= 19,
+	DUMP_TYPE_READ_SHM_FAIL			= 20,
+	DUMP_TYPE_DONGLE_HOST_EVENT		= 21,
+	DUMP_TYPE_SMMU_FAULT			= 22,
+	DUMP_TYPE_RESUMED_UNKNOWN		= 23,
+	DUMP_TYPE_DUE_TO_BT			= 24,
+	DUMP_TYPE_LOGSET_BEYOND_RANGE		= 25,
+	DUMP_TYPE_BY_USER			= 26,
+	DUMP_TYPE_CTO_RECOVERY			= 27,
+	DUMP_TYPE_SEQUENTIAL_PRIVCMD_ERROR	= 28,
+	DUMP_TYPE_PROXD_TIMEOUT			= 29,
+	DUMP_TYPE_INBAND_DEVICE_WAKE_FAILURE	= 30,
+	DUMP_TYPE_PKTID_POOL_DEPLETED		= 31,
+	DUMP_TYPE_ESCAN_SYNCID_MISMATCH		= 32,
+	DUMP_TYPE_INVALID_SHINFO_NRFRAGS	= 33,
+	DUMP_TYPE_P2P_DISC_BUSY			= 34,
+	DUMP_TYPE_CONT_EXCESS_PM_AWAKE		= 35,
+	DUMP_TYPE_DONGLE_TRAP_DURING_WIFI_ONOFF	= 36,
+	DUMP_TYPE_BY_DSACK_HC_DUE_TO_ISR_DELAY	= 37,
+	DUMP_TYPE_BY_DSACK_HC_DUE_TO_DPC_DELAY	= 38
+};
+
+enum dhd_hang_reason {
+	HANG_REASON_MASK				= 0x8000,
+	HANG_REASON_IOCTL_RESP_TIMEOUT			= 0x8001,
+	HANG_REASON_DONGLE_TRAP				= 0x8002,
+	HANG_REASON_D3_ACK_TIMEOUT			= 0x8003,
+	HANG_REASON_BUS_DOWN				= 0x8004,
+	HANG_REASON_MSGBUF_LIVELOCK			= 0x8006,
+	HANG_REASON_IFACE_DEL_FAILURE			= 0x8007,
+	HANG_REASON_HT_AVAIL_ERROR			= 0x8008,
+	HANG_REASON_PCIE_RC_LINK_UP_FAIL		= 0x8009,
+	HANG_REASON_PCIE_PKTID_ERROR			= 0x800A,
+	HANG_REASON_IFACE_ADD_FAILURE			= 0x800B,
+	HANG_REASON_IOCTL_RESP_TIMEOUT_SCHED_ERROR	= 0x800C,
+	HANG_REASON_D3_ACK_TIMEOUT_SCHED_ERROR		= 0x800D,
+	HANG_REASON_SEQUENTIAL_PRIVCMD_ERROR		= 0x800E,
+	HANG_REASON_SCAN_BUSY				= 0x800F,
+	HANG_REASON_BSS_UP_FAILURE			= 0x8010,
+	HANG_REASON_BSS_DOWN_FAILURE			= 0x8011,
+	HANG_REASON_IOCTL_SUSPEND_ERROR			= 0x8012,
+	HANG_REASON_ESCAN_SYNCID_MISMATCH		= 0x8013,
+	HANG_REASON_SCAN_TIMEOUT			= 0x8014,
+	HANG_REASON_SCAN_TIMEOUT_SCHED_ERROR		= 0x8015,
+	HANG_REASON_P2P_DISC_BUSY			= 0x8016,
+	HANG_REASON_PCIE_LINK_DOWN_RC_DETECT		= 0x8805,
+	HANG_REASON_INVALID_EVENT_OR_DATA		= 0x8806,
+	HANG_REASON_UNKNOWN				= 0x8807,
+	HANG_REASON_PCIE_LINK_DOWN_EP_DETECT		= 0x8808,
+	HANG_REASON_PCIE_CTO_DETECT			= 0x8809,
+	HANG_REASON_SLEEP_FAILURE			= 0x880A,
+	HANG_REASON_DS_SKIP_TIMEOUT			= 0x880B,
+	HANG_REASON_BT2WL_REG_RESET			= 0x880C,
+	HANG_REASON_MAX					= 0x880D
+};
+
+#define WLC_E_DEAUTH_MAX_REASON 0x0FFF
+
+enum dhd_rsdb_scan_features {
+	/* Downgraded scan feature for AP active */
+	RSDB_SCAN_DOWNGRADED_AP_SCAN = 0x01,
+	/* Downgraded scan feature for P2P Discovery */
+	RSDB_SCAN_DOWNGRADED_P2P_DISC_SCAN = 0x02,
+	/* Enable channel pruning for ROAM SCAN */
+	RSDB_SCAN_DOWNGRADED_CH_PRUNE_ROAM = 0x10,
+	/* Enable channel pruning for any SCAN */
+	RSDB_SCAN_DOWNGRADED_CH_PRUNE_ALL  = 0x20
+};
+
+#define VENDOR_SEND_HANG_EXT_INFO_LEN (800 + 1)
+#ifdef DHD_EWPR_VER2
+#define VENDOR_SEND_HANG_EXT_INFO_VER 20181111
+#else
+#define VENDOR_SEND_HANG_EXT_INFO_VER 20170905
+#endif /* DHD_EWPR_VER2 */
+
+#define HANG_INFO_TRAP_T_NAME_MAX 6
+#define HANG_INFO_TRAP_T_REASON_IDX 0
+#define HANG_INFO_TRAP_T_SUBTYPE_IDX 2
+#define HANG_INFO_TRAP_T_OFFSET_IDX 3
+#define HANG_INFO_TRAP_T_EPC_IDX 4
+#define HANG_FIELD_STR_MAX_LEN 9
+#define HANG_FIELD_CNT_MAX 69
+#define HANG_FIELD_IF_FAILURE_CNT 10
+#define HANG_FIELD_IOCTL_RESP_TIMEOUT_CNT 8
+#define HANG_FIELD_TRAP_T_STACK_CNT_MAX 16
+#define HANG_FIELD_MISMATCH_CNT 10
+#define HANG_INFO_BIGDATA_KEY_STACK_CNT 4
+
+#define DEBUG_DUMP_TIME_BUF_LEN (22 + 1)
+/* delimiter between values */
+#define HANG_KEY_DEL    ' '
+#define HANG_RAW_DEL    '_'
+
+#ifdef DHD_EWPR_VER2
+#define HANG_INFO_BIGDATA_EXTRA_KEY 4
+#define HANG_INFO_TRAP_T_EXTRA_KEY_IDX 5
+#endif
+
+/* Packet alignment for most efficient SDIO (can change based on platform) */
+#ifndef DHD_SDALIGN
+#define DHD_SDALIGN	32
+#endif
+
+#define DHD_TX_CONTEXT_MASK 0xff
+#define DHD_TX_START_XMIT   0x01
+#define DHD_TX_SEND_PKT     0x02
+#define DHD_IF_SET_TX_ACTIVE(ifp, context)	\
+    ifp->tx_paths_active |= context;
+#define DHD_IF_CLR_TX_ACTIVE(ifp, context)	\
+    ifp->tx_paths_active &= ~context;
+#define DHD_IF_IS_TX_ACTIVE(ifp)	\
+	(ifp->tx_paths_active)
+/**
+ * DMA-able buffer parameters
+ * - dmaaddr_t is 32bits on a 32bit host.
+ *   dhd_dma_buf::pa may not be used as a sh_addr_t, bcm_addr64_t or uintptr
+ * - dhd_dma_buf::_alloced is ONLY for freeing a DMA-able buffer.
+ */
+typedef struct dhd_dma_buf {
+	void      *va;      /* virtual address of buffer */
+	uint32    len;      /* user requested buffer length */
+	dmaaddr_t pa;       /* physical address of buffer */
+	void      *dmah;    /* dma mapper handle */
+	void      *secdma;  /* secure dma sec_cma_info handle */
+	uint32    _alloced; /* actual size of buffer allocated with align and pad */
+} dhd_dma_buf_t;
+
+/* host reordering packts logic */
+/* followed the structure to hold the reorder buffers (void **p) */
+typedef struct reorder_info {
+	void **p;
+	uint8 flow_id;
+	uint8 cur_idx;
+	uint8 exp_idx;
+	uint8 max_idx;
+	uint8 pend_pkts;
+} reorder_info_t;
+
+/* throughput test packet format */
+typedef struct tput_pkt {
+	/* header */
+	uint8 mac_sta[ETHER_ADDR_LEN];
+	uint8 mac_ap[ETHER_ADDR_LEN];
+	uint16 pkt_type;
+	uint8 PAD[2];
+	/* data */
+	uint32 crc32;
+	uint32 pkt_id;
+	uint32 num_pkts;
+} tput_pkt_t;
+
+typedef enum {
+	TPUT_PKT_TYPE_NORMAL,
+	TPUT_PKT_TYPE_STOP
+} tput_pkt_type_t;
+
+#define TPUT_TEST_MAX_PAYLOAD 1500
+#define TPUT_TEST_WAIT_TIMEOUT_DEFAULT 5000
+
+#ifdef DHDTCPACK_SUPPRESS
+
+enum {
+	/* TCPACK suppress off */
+	TCPACK_SUP_OFF,
+	/* Replace TCPACK in txq when new coming one has higher ACK number. */
+	TCPACK_SUP_REPLACE,
+	/* TCPACK_SUP_REPLACE + delayed TCPACK TX unless ACK to PSH DATA.
+	 * This will give benefits to Half-Duplex bus interface(e.g. SDIO) that
+	 * 1. we are able to read TCP DATA packets first from the bus
+	 * 2. TCPACKs that don't need to hurry delivered remains longer in TXQ so can be suppressed.
+	 */
+	TCPACK_SUP_DELAYTX,
+	TCPACK_SUP_HOLD,
+	TCPACK_SUP_LAST_MODE
+};
+#endif /* DHDTCPACK_SUPPRESS */
+
+#if defined(BCM_ROUTER_DHD)
+#define DHD_DWM_TBL_SIZE           57
+/* DSCP WMM AC Mapping macros and structures */
+#define DHD_TRF_MGMT_DWM_FILTER_BIT                 0x8
+#define DHD_TRF_MGMT_DWM_PRIO_BITS                  0x7
+#define DHD_TRF_MGMT_DWM_FAVORED_BIT                0x10
+#define DHD_TRF_MGMT_DWM_PRIO(dwm_tbl_entry) ((dwm_tbl_entry) & DHD_TRF_MGMT_DWM_PRIO_BITS)
+#define DHD_TRF_MGMT_DWM_IS_FAVORED_SET(dwm_tbl_entry) \
+	((dwm_tbl_entry) & DHD_TRF_MGMT_DWM_FAVORED_BIT)
+#define DHD_TRF_MGMT_DWM_SET_FAVORED(dwm_tbl_entry) \
+	((dwm_tbl_entry) |= DHD_TRF_MGMT_DWM_FAVORED_BIT)
+#define DHD_TRF_MGMT_DWM_IS_FILTER_SET(dwm_tbl_entry) \
+	((dwm_tbl_entry) & DHD_TRF_MGMT_DWM_FILTER_BIT)
+#define DHD_TRF_MGMT_DWM_SET_FILTER(dwm_tbl_entry) \
+	((dwm_tbl_entry) |= DHD_TRF_MGMT_DWM_FILTER_BIT)
+
+typedef struct {
+	uint8 dhd_dwm_enabled;
+	uint8 dhd_dwm_tbl[DHD_DWM_TBL_SIZE];
+} dhd_trf_mgmt_dwm_tbl_t;
+#endif /* for BCM_ROUTER_DHD */
+
+#define DHD_NULL_CHK_AND_RET(cond) \
+	if (!cond) { \
+		DHD_ERROR(("%s " #cond " is NULL\n", __FUNCTION__)); \
+		return; \
+	}
+
+#define DHD_NULL_CHK_AND_RET_VAL(cond, value) \
+	if (!cond) { \
+		DHD_ERROR(("%s " #cond " is NULL\n", __FUNCTION__)); \
+		return value; \
+	}
+
+#define DHD_NULL_CHK_AND_GOTO(cond, label) \
+	if (!cond) { \
+		DHD_ERROR(("%s " #cond " is NULL\n", __FUNCTION__)); \
+		goto label; \
+	}
+
+/*
+ * Accumulating the queue lengths of all flowring queues in a parent object,
+ * to assert flow control, when the cummulative queue length crosses an upper
+ * threshold defined on a parent object. Upper threshold may be maintained
+ * at a station level, at an interface level, or at a dhd instance.
+ *
+ * cumm_ctr_t abstraction:
+ * cumm_ctr_t abstraction may be enhanced to use an object with a hysterisis
+ * pause on/off threshold callback.
+ * All macros use the address of the cummulative length in the parent objects.
+ *
+ * Cummulative counters in parent objects may be updated without spinlocks.
+ *
+ * If a cummulative queue length is desired across all flows
+ * belonging to either of (a station, or an interface or a dhd instance), then
+ * an atomic operation is required using an atomic_t cummulative counters or
+ * using a spinlock. BCM_ROUTER_DHD uses the Linux atomic_t construct.
+ */
+#if defined(BCM_ROUTER_DHD)
+
+typedef atomic_t cumm_ctr_t;       /* BCM_ROUTER_DHD Linux: atomic operations */
+#define DHD_CUMM_CTR_PTR(clen)     ((cumm_ctr_t*)(clen))
+#define DHD_CUMM_CTR(clen)         DHD_CUMM_CTR_PTR(clen) /* atomic accessor */
+#define DHD_CUMM_CTR_READ(clen)    atomic_read(DHD_CUMM_CTR(clen)) /* read */
+#define DHD_CUMM_CTR_INIT(clen)                                                \
+	ASSERT(DHD_CUMM_CTR_PTR(clen) != DHD_CUMM_CTR_PTR(NULL));                  \
+	atomic_set(DHD_CUMM_CTR(clen), 0);
+#define DHD_CUMM_CTR_INCR(clen)                                                \
+	ASSERT(DHD_CUMM_CTR_PTR(clen) != DHD_CUMM_CTR_PTR(NULL));                  \
+	atomic_add(1, DHD_CUMM_CTR(clen));                                         \
+	ASSERT(DHD_CUMM_CTR_READ(clen) != 0); /* ensure it does not wrap */
+#define DHD_CUMM_CTR_DECR(clen)                                                \
+	ASSERT(DHD_CUMM_CTR_PTR(clen) != DHD_CUMM_CTR_PTR(NULL));                  \
+	ASSERT(DHD_CUMM_CTR_READ(clen) > 0);                                       \
+	atomic_sub(1, DHD_CUMM_CTR(clen));
+
+#else  /* ! BCM_ROUTER_DHD */
+
+/* Cummulative length not supported. */
+typedef uint32 cumm_ctr_t;
+#define DHD_CUMM_CTR_PTR(clen)     ((cumm_ctr_t*)(clen))
+#define DHD_CUMM_CTR(clen)         *(DHD_CUMM_CTR_PTR(clen)) /* accessor */
+#define DHD_CUMM_CTR_READ(clen)    DHD_CUMM_CTR(clen) /* read access */
+#define DHD_CUMM_CTR_INIT(clen)                                                \
+	ASSERT(DHD_CUMM_CTR_PTR(clen) != DHD_CUMM_CTR_PTR(NULL));
+#define DHD_CUMM_CTR_INCR(clen)                                                \
+	ASSERT(DHD_CUMM_CTR_PTR(clen) != DHD_CUMM_CTR_PTR(NULL));
+#define DHD_CUMM_CTR_DECR(clen)                                                \
+	ASSERT(DHD_CUMM_CTR_PTR(clen) != DHD_CUMM_CTR_PTR(NULL));
+
+#endif /* ! BCM_ROUTER_DHD */
+
+#if defined(WLTDLS) && defined(PCIE_FULL_DONGLE)
+struct tdls_peer_node {
+	uint8 addr[ETHER_ADDR_LEN];
+	struct tdls_peer_node *next;
+};
+typedef struct tdls_peer_node tdls_peer_node_t;
+typedef struct {
+	tdls_peer_node_t *node;
+	uint8 tdls_peer_count;
+} tdls_peer_tbl_t;
+#endif /* defined(WLTDLS) && defined(PCIE_FULL_DONGLE) */
+
+typedef enum dhd_ring_id {
+	DEBUG_RING_ID_INVALID = 0x1,
+	FW_VERBOSE_RING_ID = 0x2,
+	DHD_EVENT_RING_ID = 0x3,
+	DRIVER_LOG_RING_ID = 0x4,
+	ROAM_STATS_RING_ID = 0x5,
+	BT_LOG_RING_ID = 0x6,
+	PACKET_LOG_RING_ID = 0x7,
+	DEBUG_DUMP_RING1_ID = 0x8,
+	DEBUG_DUMP_RING2_ID = 0x9,
+	MEM_DUMP_RING_ID = 0xa,
+	DEBUG_RING_ID_MAX = 0xb
+} dhd_ring_id_t;
+
+#define HEALTH_CHK_BUF_SIZE 256
+
+/* DEBUG_DUMP SUB COMMAND */
+enum {
+	CMD_DEFAULT,
+	CMD_UNWANTED,
+	CMD_DISCONNECTED,
+	CMD_MAX
+};
+
+#define DHD_DUMP_SUBSTR_UNWANTED	"_unwanted"
+#define DHD_DUMP_SUBSTR_DISCONNECTED	"_disconnected"
+
+#ifdef DNGL_AXI_ERROR_LOGGING
+#define DHD_DUMP_AXI_ERROR_FILENAME	"axi_error"
+#define DHD_DUMP_HAL_FILENAME_SUFFIX	"_hal"
+#endif /* DNGL_AXI_ERROR_LOGGING */
+
+#define FW_LOGSET_MASK_ALL 0xFFFFu
+
+#if defined(CUSTOMER_HW4)
+#ifndef DHD_COMMON_DUMP_PATH
+#define DHD_COMMON_DUMP_PATH	"/data/vendor/log/wifi/"
+#endif /* !DHD_COMMON_DUMP_PATH */
+#elif defined(CUSTOMER_HW7_DEBUG)
+#define DHD_COMMON_DUMP_PATH    PLATFORM_PATH
+#elif defined(CUSTOM_DHD_COMMON_DUMP_PATH)
+#define DHD_COMMON_DUMP_PATH	CUSTOM_DHD_COMMON_DUMP_PATH
+#elif defined(BOARD_HIKEY)
+#ifndef DHD_COMMON_DUMP_PATH
+#define DHD_COMMON_DUMP_PATH	"/data/misc/wifi/"
+#endif /* !DHD_COMMON_DUMP_PATH */
+#elif defined(OEM_ANDROID) && defined(__ARM_ARCH_7A__)
+#define DHD_COMMON_DUMP_PATH	"/data/vendor/wifi/"
+#elif defined(OEM_ANDROID) /* For Brix Live Image */
+#define DHD_COMMON_DUMP_PATH	"/installmedia/"
+#else /* Default */
+#define DHD_COMMON_DUMP_PATH	"/root/"
+#endif /* CUSTOMER_HW4 */
+
+#define DHD_MEMDUMP_LONGSTR_LEN 180
+
+struct cntry_locales_custom {
+	char iso_abbrev[WLC_CNTRY_BUF_SZ];      /* ISO 3166-1 country abbreviation */
+	char custom_locale[WLC_CNTRY_BUF_SZ];   /* Custom firmware locale */
+	int32 custom_locale_rev;                /* Custom local revisin default -1 */
+};
+
+#ifdef __linux__
+extern uint16 dhd_plat_align_rxbuf_size(uint16 rxbufpost_sz);
+#else
+static INLINE uint16 dhd_plat_align_rxbuf_size(uint16 rxbufpost_sz) { return rxbufpost_sz; }
+#endif /* !__linux__ */
+
+#if defined(LINUX) || defined(linux)
+int dhd_send_msg_to_daemon(struct sk_buff *skb, void *data, int size);
+#endif /* LINUX || linux */
+#ifdef REPORT_FATAL_TIMEOUTS
+typedef struct timeout_info {
+	void	*scan_timer_lock;
+	void	*join_timer_lock;
+	void	*cmd_timer_lock;
+	void	*bus_timer_lock;
+	uint32 scan_timeout_val;
+	uint32 join_timeout_val;
+	uint32 cmd_timeout_val;
+	uint32 bus_timeout_val;
+	bool scan_timer_active;
+	bool join_timer_active;
+	bool cmd_timer_active;
+	bool bus_timer_active;
+	osl_timer_t *scan_timer;
+	osl_timer_t *join_timer;
+	osl_timer_t *cmd_timer;
+	osl_timer_t *bus_timer;
+	uint32 cmd_request_id;
+	uint32 cmd;
+	uint32 cmd_join_error;
+	uint16 escan_syncid;
+	bool escan_aborted;
+	uint16 abort_syncid;
+} timeout_info_t;
+#endif /* REPORT_FATAL_TIMEOUTS */
+
+#ifdef DMAMAP_STATS
+typedef struct dmamap_stats {
+	uint64 txdata;
+	uint64 txdata_sz;
+	uint64 rxdata;
+	uint64 rxdata_sz;
+	uint64 ioctl_rx;
+	uint64 ioctl_rx_sz;
+	uint64 event_rx;
+	uint64 event_rx_sz;
+	uint64 info_rx;
+	uint64 info_rx_sz;
+	uint64 tsbuf_rx;
+	uint64 tsbuf_rx_sz;
+} dma_stats_t;
+#endif /* DMAMAP_STATS */
+
+/*  see wlfc_proto.h for tx status details */
+#define DHD_MAX_TX_STATUS_MSGS     9u
+
+#ifdef TX_STATUS_LATENCY_STATS
+typedef struct dhd_if_tx_status_latency {
+	/* total number of tx_status received on this interface */
+	uint64 num_tx_status;
+	/* cumulative tx_status latency for this interface */
+	uint64 cum_tx_status_latency;
+} dhd_if_tx_status_latency_t;
+#endif /* TX_STATUS_LATENCY_STATS */
+
+/* Bit in dhd_pub_t::gdb_proxy_stop_count set when firmware is stopped by GDB */
+#define GDB_PROXY_STOP_MASK 1
+
+/* Enable Reserve STA flowrings only for Android */
+#if defined(OEM_ANDROID)
+#define DHD_LIMIT_MULTI_CLIENT_FLOWRINGS
+#endif /* OEM_ANDROID */
+
+typedef enum {
+	FW_UNLOADED = 0,
+	FW_DOWNLOAD_IN_PROGRESS = 1,
+	FW_DOWNLOAD_DONE = 2
+} fw_download_status_t;
+
+#define PCIE_DB7_MAGIC_NUMBER_ISR_TRAP	0xdead0001
+#define PCIE_DB7_MAGIC_NUMBER_DPC_TRAP	0xdead0002
+#define PCIE_DB7_MAGIC_NUMBER_DPC_LPM	0xdead0003
+
+typedef struct dhd_db7_info {
+	bool	fw_db7w_trap;
+	bool	fw_db7w_trap_inprogress;
+	bool	fw_db7w_trap_recieved;
+	uint32	db7_magic_number;
+
+	uint32	debug_db7_send_cnt;
+	uint32	debug_db7_trap_cnt;
+	uint32	debug_db7_timing_error_cnt;
+	uint64	debug_db7_send_time;
+	uint64	debug_db7_trap_time;
+	uint64	debug_max_db7_dur;
+	uint64	debug_max_db7_send_time;
+	uint64	debug_max_db7_trap_time;
+} dhd_db7_info_t;
+
+typedef enum dhd_induce_error_states
+{
+	DHD_INDUCE_ERROR_CLEAR		= 0x0,
+	DHD_INDUCE_IOCTL_TIMEOUT	= 0x1,
+	DHD_INDUCE_D3_ACK_TIMEOUT	= 0x2,
+	DHD_INDUCE_LIVELOCK		= 0x3,
+	DHD_INDUCE_DROP_OOB_IRQ		= 0x4,
+	DHD_INDUCE_DROP_AXI_SIG		= 0x5,
+	DHD_INDUCE_TX_BIG_PKT		= 0x6,
+	DHD_INDUCE_IOCTL_SUSPEND_ERROR	= 0x7,
+	DHD_INDUCE_SCAN_TIMEOUT         = 0x8,
+	DHD_INDUCE_SCAN_TIMEOUT_SCHED_ERROR     = 0x9,
+	DHD_INDUCE_PKTID_INVALID_SAVE   = 0xA,
+	DHD_INDUCE_PKTID_INVALID_FREE   = 0xB,
+	DHD_INDUCE_PCIE_LINK_DOWN	= 0xC,
+	/* Big hammer induction */
+	DHD_INDUCE_BH_ON_FAIL_ONCE	= 0x10,
+	DHD_INDUCE_BH_ON_FAIL_ALWAYS	= 0x11,
+	DHD_INDUCE_BH_CBP_HANG		= 0x12,
+	DHD_INDUCE_P2P_DISC_BUSY	= 0x13,
+	DHD_INDUCE_PCIE_LINK_DOWN_IN_ISR	= 0x14,
+	DHD_INDUCE_ERROR_MAX
+} dhd_induce_error_states_t;
+
+#define MAX_MDRING_ITEM_DUMP	20
+
+#define MAX_RX_LAT_PRIO		8
+#define MAX_RX_LAT_HIST_BIN	50
+#define MAX_RXCPL_HISTORY	50
+#define	RX_LAT_TIME_SCALE	32
+#define	RX_LAT_BIN_SCALE	500
+
+typedef struct rx_cpl_history {
+	uint32 host_time;
+	uint32 ptm_high;
+	uint32 ptm_low;
+	uint32 rx_t0;
+	uint32 latency;
+	uint8 slice;
+	uint8 priority;
+	int8 rssi;
+} rx_cpl_history_t;
+
+typedef struct rx_cpl_lat_info {
+	rx_cpl_history_t rx_history[MAX_RXCPL_HISTORY];
+	uint32 rxcpl_hist_count;
+	uint32	rx_dur_2g[MAX_RX_LAT_PRIO][MAX_RX_LAT_HIST_BIN];
+	uint32	rx_dur_5g[MAX_RX_LAT_PRIO][MAX_RX_LAT_HIST_BIN];
+} rx_cpl_lat_info_t;
+
+#define MAX_TXCPL_HISTORY	50u
+typedef struct tx_cpl_history {
+	uint32 host_time;
+	uint32 ptm_high;
+	uint32 ptm_low;
+	uint16 latency;
+	uint16 flowid;
+	uint8 tid;
+} tx_cpl_history_t;
+
+typedef struct tx_cpl_info {
+	tx_cpl_history_t tx_history[MAX_TXCPL_HISTORY];
+	uint32 txcpl_hist_count;
+} tx_cpl_info_t;
+
+#define DHD_PTM_CLK_ID		0xEu		/* PTM clock ID; IDs 0-3 are used in tsync module */
+#define DHD_PTM_CLK_ID_MASK	0xF0000000u	/* Bitmask for clkid */
+#define DHD_PTM_CLK_ID_SHIFT	28u		/* Bitshift for clkid */
+
+#define DHD_PTM_GET_CLKID(ts) (((ts) & DHD_PTM_CLK_ID_MASK) >> DHD_PTM_CLK_ID_SHIFT)
+#define DHD_PTM_CLKID(ts) (DHD_PTM_GET_CLKID(ts) == DHD_PTM_CLK_ID)
+
+#ifdef DHD_USE_STATIC_CTRLBUF
+#define PKTFREE_CTRLBUF(osh, p, flag) PKTFREE_STATIC(osh, p, flag);
+#else
+#define PKTFREE_CTRLBUF(osh, p, flag) PKTFREE(osh, p, flag);
+#endif /* DHD_USE_STATIC_CTRLBUF */
+
+#define RX_PKTFREE(osh, pkt_type, p, flag) \
+do { \
+	if (ntoh16(pkt_type) == ETHER_TYPE_BRCM) { \
+		PKTFREE_CTRLBUF(osh, p, flag); \
+	} else { \
+		PKTCFREE(osh, p, flag); \
+	} \
+} while (0);
+
+#if defined(SHOW_LOGTRACE) && defined(DHD_USE_KTHREAD_FOR_LOGTRACE)
+/* Timestamps to trace dhd_logtrace_thread() */
+struct dhd_logtrace_thr_ts {
+	uint64 entry_time;
+	uint64 sem_down_time;
+	uint64 flush_time;
+	uint64 unexpected_break_time;
+	uint64 complete_time;
+};
+#endif /* SHOW_LOGTRACE && DHD_USE_KTHREAD_FOR_LOGTRACE */
+#ifdef SUPPORT_OTA_UPDATE
+#define MAX_EXT_INFO_LEN	10u
+typedef struct ota_update_info {
+	uint32 clm_len;
+	uint8 *clm_buf;
+	uint32 nvram_len;
+	uint8 *nvram_buf;
+	uint8 nvram_ext[MAX_EXT_INFO_LEN];
+} ota_update_info_t;
+#endif /* SUPPORT_OTA_UPDATE */
+/**
+ * Common structure for module and instance linkage.
+ * Instantiated once per hardware (dongle) instance that this DHD manages.
+ */
+typedef struct dhd_pub {
+	/* Linkage ponters */
+	osl_t *osh;		/* OSL handle */
+	struct dhd_bus *bus;	/* Bus module handle */
+	struct dhd_prot *prot;	/* Protocol module handle */
+	struct dhd_info  *info; /* Info module handle */
+	struct dhd_dbg *dbg;	/* Debugability module handle */
+#if defined(SHOW_LOGTRACE) && defined(DHD_USE_KTHREAD_FOR_LOGTRACE)
+	struct dhd_logtrace_thr_ts logtrace_thr_ts;
+#endif /* SHOW_LOGTRACE && DHD_USE_KTHREAD_FOR_LOGTRACE */
+
+	/* to NDIS developer, the structure dhd_common is redundant,
+	 * please do NOT merge it back from other branches !!!
+	 */
+
+#ifdef BCMDBUS
+	struct dbus_pub *dbus;
+#endif
+
+	/* Internal dhd items */
+	bool up;		/* Driver up/down (to OS) */
+#ifdef WL_CFG80211
+	spinlock_t up_lock;	/* Synchronization with CFG80211 down */
+#endif /* WL_CFG80211 */
+	bool txoff;		/* Transmit flow-controlled */
+	bool dongle_reset;  /* TRUE = DEVRESET put dongle into reset */
+	enum dhd_bus_state busstate;
+	uint dhd_bus_busy_state;	/* Bus busy state */
+	uint hdrlen;		/* Total DHD header length (proto + bus) */
+	uint maxctl;		/* Max size rxctl request from proto to bus */
+	uint rxsz;		/* Rx buffer size bus module should use */
+	uint8 wme_dp;	/* wme discard priority */
+#ifdef DNGL_AXI_ERROR_LOGGING
+	uint32 axierror_logbuf_addr;
+	bool axi_error;
+	struct dhd_axi_error_dump *axi_err_dump;
+#endif /* DNGL_AXI_ERROR_LOGGING */
+	/* Dongle media info */
+	bool iswl;		/* Dongle-resident driver is wl */
+	ulong drv_version;	/* Version of dongle-resident driver */
+	struct ether_addr mac;	/* MAC address obtained from dongle */
+	dngl_stats_t dstats;	/* Stats for dongle-based data */
+
+	/* Additional stats for the bus level */
+	ulong tx_packets;	/* Data packets sent to dongle */
+	ulong actual_tx_pkts;	/* Actual data packets sent to dongle */
+	ulong tot_txcpl;	/* Total Tx completion received */
+	ulong tx_dropped;	/* Data packets dropped in dhd */
+	ulong tx_multicast;	/* Multicast data packets sent to dongle */
+	ulong tx_errors;	/* Errors in sending data to dongle */
+	ulong tx_ctlpkts;	/* Control packets sent to dongle */
+	ulong tx_ctlerrs;	/* Errors sending control frames to dongle */
+	ulong rx_packets;	/* Packets sent up the network interface */
+	ulong rx_forward;	/* Packets forwarded at DHD driver level */
+	ulong rx_multicast;	/* Multicast packets sent up the network interface */
+	ulong rx_errors;	/* Errors processing rx data packets */
+	ulong rx_ctlpkts;	/* Control frames processed from dongle */
+	ulong rx_ctlerrs;	/* Errors in processing rx control frames */
+	ulong rx_dropped;	/* Packets dropped locally (no memory) */
+	ulong rx_flushed;  /* Packets flushed due to unscheduled sendup thread */
+	ulong wd_dpc_sched;   /* Number of times dhd dpc scheduled by watchdog timer */
+	ulong rx_pktgetfail; /* Number of PKTGET failures in DHD on RX */
+	ulong rx_pktgetpool_fail;	/* Number of PKTGET_POOL failures in DHD on RX */
+	ulong tx_pktgetfail; /* Number of PKTGET failures in DHD on TX */
+	ulong rx_readahead_cnt;	/* Number of packets where header read-ahead was used. */
+	ulong tx_realloc;	/* Number of tx packets we had to realloc for headroom */
+	ulong fc_packets;       /* Number of flow control pkts recvd */
+	ulong tx_big_packets;	/* Dropped data packets that are larger than MAX_MTU_SZ */
+	ulong tx_bytes;		/* total no. of bytes transmitted successfully */
+	ulong rx_bytes;		/* total no. of bytes received */
+#ifdef DMAMAP_STATS
+	/* DMA Mapping statistics */
+	dma_stats_t dma_stats;
+#endif /* DMAMAP_STATS */
+#ifdef WL_MONITOR
+	bool monitor_enable;
+#endif /* WL_MONITOR */
+	/* Last error return */
+	int bcmerror;
+	uint tickcnt;
+
+	/* Last error from dongle */
+	int dongle_error;
+
+	uint8 country_code[WLC_CNTRY_BUF_SZ];
+
+	/* Suspend disable flag and "in suspend" flag */
+	int suspend_disable_flag; /* "1" to disable all extra powersaving during suspend */
+	int in_suspend;			/* flag set to 1 when early suspend called */
+#ifdef PNO_SUPPORT
+	int pno_enable;			/* pno status : "1" is pno enable */
+	int pno_suspend;		/* pno suspend status : "1" is pno suspended */
+#endif /* PNO_SUPPORT */
+	/* DTIM skip value, default 0(or 1) means wake each DTIM
+	 * 3 means skip 2 DTIMs and wake up 3rd DTIM(9th beacon when AP DTIM is 3)
+	 */
+	int early_suspended;		/* Early suspend status */
+#if defined(PKT_FILTER_SUPPORT)
+	int dhcp_in_progress;		/* DHCP period */
+#endif /* PKT_FILTER_SUPPORT */
+	/* Pkt filter defination */
+	char * pktfilter[100];
+	int pktfilter_count;
+
+	wl_country_t dhd_cspec;		/* Current Locale info */
+#ifdef CUSTOM_COUNTRY_CODE
+	uint dhd_cflags;
+#endif /* CUSTOM_COUNTRY_CODE */
+#if defined(DHD_BLOB_EXISTENCE_CHECK)
+	bool is_blob;			/* Checking for existance of Blob file */
+#endif /* DHD_BLOB_EXISTENCE_CHECK */
+	bool force_country_change;
+	int	op_mode;				/* STA, HostAPD, WFD, SoftAP */
+
+#if defined(LINUX) || defined(linux)
+#if defined(OEM_ANDROID)
+	struct mutex wl_start_stop_lock; /* lock/unlock for Android start/stop */
+	struct mutex wl_softap_lock;		 /* lock/unlock for any SoftAP/STA settings */
+#endif /* defined(OEM_ANDROID) */
+#endif /* defined (LINUX) || defined(linux) */
+
+#ifdef NDIS
+	PDEVICE_OBJECT pdo;
+	PDEVICE_OBJECT fdo;
+	PDEVICE_OBJECT nextDeviceObj;
+#if defined(BCMWDF)
+	WDFDEVICE wdfDevice;
+#endif /* (BCMWDF)  */
+#endif /* NDIS */
+#ifdef PROP_TXSTATUS
+	bool	wlfc_enabled;
+	int	wlfc_mode;
+	void*	wlfc_state;
+	/*
+	Mode in which the dhd flow control shall operate. Must be set before
+	traffic starts to the device.
+	0 - Do not do any proptxtstatus flow control
+	1 - Use implied credit from a packet status
+	2 - Use explicit credit
+	3 - Only AMPDU hostreorder used. no wlfc.
+	*/
+	uint8	proptxstatus_mode;
+	bool	proptxstatus_txoff;
+	bool	proptxstatus_module_ignore;
+	bool	proptxstatus_credit_ignore;
+	bool	proptxstatus_txstatus_ignore;
+
+	bool	wlfc_rxpkt_chk;
+#ifdef LIMIT_BORROW
+	bool wlfc_borrow_allowed;
+#endif /* LIMIT_BORROW */
+	/*
+	 * implement below functions in each platform if needed.
+	 */
+	/* platform specific function whether to skip flow control */
+	bool (*skip_fc)(void * dhdp, uint8 ifx);
+	/* platform specific function for wlfc_enable and wlfc_deinit */
+	void (*plat_init)(void *dhd);
+	void (*plat_deinit)(void *dhd);
+#ifdef DHD_WLFC_THREAD
+	bool                wlfc_thread_go;
+#if defined(LINUX)
+	struct task_struct* wlfc_thread;
+	wait_queue_head_t   wlfc_wqhead;
+#else
+	#error "wlfc thread not enabled"
+#endif /* LINUX */
+#endif /* DHD_WLFC_THREAD */
+	uint32 simutx_limit;
+#endif /* PROP_TXSTATUS */
+#ifdef PNO_SUPPORT
+	void *pno_state;
+#endif
+#ifdef RTT_SUPPORT
+	void *rtt_state;
+	bool rtt_supported;
+#endif
+#ifdef ROAM_AP_ENV_DETECTION
+	bool	roam_env_detection;
+#endif
+	bool	dongle_isolation;
+	bool	is_pcie_watchdog_reset;
+
+/* Begin - Variables to track Bus Errors */
+	bool	dongle_trap_occured;	/* flag for sending HANG event to upper layer */
+	bool	iovar_timeout_occured;	/* flag to indicate iovar resumed on timeout */
+	bool	invalid_shinfo_nrfrags;	/* flag to indicate invlaid shinfo nrfrags */
+	bool	is_sched_error;		/* flag to indicate timeout due to scheduling issue */
+#ifdef PCIE_FULL_DONGLE
+	bool	d3ack_timeout_occured;	/* flag to indicate d3ack resumed on timeout */
+	bool	livelock_occured;	/* flag to indicate livelock occured */
+	bool	pktid_audit_failed;	/* flag to indicate pktid audit failure */
+	bool	pktid_invalid_occured;	/* flag to indicate invalid pktid */
+#endif /* PCIE_FULL_DONGLE */
+	bool	iface_op_failed;	/* flag to indicate interface operation failed */
+	bool	scan_timeout_occurred;	/* flag to indicate scan has timedout */
+	bool	scan_busy_occurred;	/* flag to indicate scan busy occurred */
+#ifdef BT_OVER_SDIO
+	bool	is_bt_recovery_required;
+#endif
+	bool	smmu_fault_occurred;	/* flag to indicate SMMU Fault */
+	bool	p2p_disc_busy_occurred;
+	bool	dongle_trap_during_wifi_onoff;	/* flag to indicate trap during wifi on/off */
+	bool	dsack_hc_due_to_isr_delay;	/* flag to indicate DSACK HC by ISR delay */
+	bool	dsack_hc_due_to_dpc_delay;	/* flag to indicate DSACK HC by DPC delay */
+/*
+ * Add any new variables to track Bus errors above
+ * this line. Also ensure that the variable is
+ * cleared from dhd_clear_bus_errors
+ */
+/* End - Variables to track Bus Errors */
+
+	int   hang_was_sent;
+	int   hang_was_pending;
+	int   rxcnt_timeout;		/* counter rxcnt timeout to send HANG */
+	int   txcnt_timeout;		/* counter txcnt timeout to send HANG */
+#ifdef BCMPCIE
+	int   d3ackcnt_timeout;		/* counter d3ack timeout to send HANG */
+#endif /* BCMPCIE */
+	bool hang_report;		/* enable hang report by default */
+	uint16 hang_reason;		/* reason codes for HANG event */
+#if defined(DHD_HANG_SEND_UP_TEST)
+	uint req_hang_type;
+#endif /* DHD_HANG_SEND_UP_TEST */
+#ifdef DHD_DETECT_CONSECUTIVE_MFG_HANG
+	uint hang_count;
+#endif /* DHD_DETECT_CONSECUTIVE_MFG_HANG */
+#ifdef WLTDLS
+	bool tdls_enable;
+#endif
+	struct reorder_info *reorder_bufs[WLHOST_REORDERDATA_MAXFLOWS];
+	#define WLC_IOCTL_MAXBUF_FWCAP	1024
+	char  fw_capabilities[WLC_IOCTL_MAXBUF_FWCAP];
+	#define DHD_IOCTL_MAXBUF_DHDCAP	1024
+	char  dhd_capabilities[DHD_IOCTL_MAXBUF_DHDCAP];
+	#define MAXSKBPEND 1024
+	void *skbbuf[MAXSKBPEND];
+	uint32 store_idx;
+	uint32 sent_idx;
+#ifdef DHDTCPACK_SUPPRESS
+	uint8 tcpack_sup_mode;		/* TCPACK suppress mode */
+	void *tcpack_sup_module;	/* TCPACK suppress module */
+	uint32 tcpack_sup_ratio;
+	uint32 tcpack_sup_delay;
+#endif /* DHDTCPACK_SUPPRESS */
+#if defined(ARP_OFFLOAD_SUPPORT)
+	uint32 arp_version;
+	bool hmac_updated;
+#endif
+#if defined(BCMSUP_4WAY_HANDSHAKE)
+	bool fw_4way_handshake;		/* Whether firmware will to do the 4way handshake. */
+#endif
+#ifdef DEBUG_DPC_THREAD_WATCHDOG
+	bool dhd_bug_on;
+#endif /* DEBUG_DPC_THREAD_WATCHDOG */
+#ifdef CUSTOM_SET_CPUCORE
+	struct task_struct * current_dpc;
+	struct task_struct * current_rxf;
+	int chan_isvht80;
+#endif /* CUSTOM_SET_CPUCORE */
+	void    *sta_pool;          /* pre-allocated pool of sta objects */
+	void    *staid_allocator;   /* allocator of sta indexes */
+#ifdef PCIE_FULL_DONGLE
+	bool	flow_rings_inited;	/* set this flag after initializing flow rings */
+#endif /* PCIE_FULL_DONGLE */
+	void    *flowid_allocator;  /* unique flowid allocator */
+	void    *htput_flowid_allocator;  /* unique htput flowid allocator */
+	uint16	htput_client_flow_rings;  /* current number of htput client flowrings */
+	uint16	htput_flow_ring_start;	  /* start index of htput flow rings */
+	void	*flow_ring_table;   /* flow ring table, include prot and bus info */
+	void	*if_flow_lkup;      /* per interface flowid lkup hash table */
+	void    *flowid_lock;       /* per os lock for flowid info protection */
+	void    *flowring_list_lock;       /* per os lock for flowring list protection */
+	uint8	max_multi_client_flow_rings;
+	osl_atomic_t multi_client_flow_rings;
+	uint32  num_h2d_rings;		/* Max h2d rings including static and dynamic rings */
+	uint32  max_tx_flowid;		/* used to validate flowid */
+	cumm_ctr_t cumm_ctr;        /* cumm queue length placeholder  */
+	cumm_ctr_t l2cumm_ctr;      /* level 2 cumm queue length placeholder */
+	uint32 d2h_sync_mode;       /* D2H DMA completion sync mode */
+	uint8  flow_prio_map[NUMPRIO];
+	uint8	flow_prio_map_type;
+	char enable_log[MAX_EVENT];
+	bool dma_d2h_ring_upd_support;
+	bool dma_h2d_ring_upd_support;
+	bool dma_ring_upd_overwrite;	/* host overwrites support setting */
+
+	bool idma_enable;
+	uint idma_inited;
+
+	bool ifrm_enable;			/* implicit frm enable */
+	uint ifrm_inited;			/* implicit frm init */
+
+	bool dar_enable;		/* use DAR registers */
+	uint dar_inited;
+
+	bool fast_delete_ring_support;		/* fast delete ring supported */
+
+#ifdef DHD_WMF
+	bool wmf_ucast_igmp;
+#ifdef DHD_IGMP_UCQUERY
+	bool wmf_ucast_igmp_query;
+#endif
+#ifdef DHD_UCAST_UPNP
+	bool wmf_ucast_upnp;
+#endif
+#endif /* DHD_WMF */
+#if defined(BCM_ROUTER_DHD)
+	dhd_trf_mgmt_dwm_tbl_t dhd_tm_dwm_tbl;
+#endif /* BCM_ROUTER_DHD */
+#ifdef DHD_L2_FILTER
+	unsigned long l2_filter_cnt;	/* for L2_FILTER ARP table timeout */
+#endif /* DHD_L2_FILTER */
+#ifdef DHD_SSSR_DUMP
+	bool sssr_inited;
+	bool force_sssr_init;
+	bool sssr_dump_collected;	/* Flag to indicate sssr dump is collected */
+	sssr_reg_info_cmn_t *sssr_reg_info;
+	uint8 *sssr_mempool;
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+	uint *sssr_d11_before[MAX_NUM_D11_CORES_WITH_SCAN];
+	uint *sssr_dig_buf_before;
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+	uint *sssr_d11_after[MAX_NUM_D11_CORES_WITH_SCAN];
+	bool sssr_d11_outofreset[MAX_NUM_D11_CORES_WITH_SCAN];
+	uint *sssr_dig_buf_after;
+	uint32 sssr_dump_mode;
+	bool collect_sssr;		/* Flag to indicate SSSR dump is required */
+	bool fis_triggered;
+#endif /* DHD_SSSR_DUMP */
+#ifdef DHD_SDTC_ETB_DUMP
+	etb_addr_info_t etb_addr_info;
+	uint8 *sdtc_etb_mempool;
+	uint sdtc_etb_dump_len;
+	bool sdtc_etb_inited;
+	bool collect_sdtc;		/* Flag to indicate SDTC dump is required */
+#endif /* DHD_SDTC_ETB_DUMP */
+	uint8 *soc_ram;
+	uint32 soc_ram_length;
+	uint32 memdump_type;
+#ifdef DHD_COREDUMP
+	uint8 *coredump_mem;
+	uint32 coredump_len;
+	char memdump_str[DHD_MEMDUMP_LONGSTR_LEN];
+#endif /* DHD_COREDUMP */
+#ifdef DHD_FW_COREDUMP
+	uint32 memdump_enabled;
+#ifdef DHD_DEBUG_UART
+	bool memdump_success;
+#endif	/* DHD_DEBUG_UART */
+#endif /* DHD_FW_COREDUMP */
+#ifdef PCIE_FULL_DONGLE
+#ifdef WLTDLS
+	tdls_peer_tbl_t peer_tbl;
+#endif /* WLTDLS */
+#if defined(LINUX) || defined(linux)
+	uint8 tx_in_progress;
+#endif /* LINUX || linux */
+#endif /* PCIE_FULL_DONGLE */
+#ifdef CACHE_FW_IMAGES
+	char	*cached_fw;
+	int	cached_fw_length;
+	char	*cached_nvram;
+	int	cached_nvram_length;
+	char	*cached_clm;
+	int	cached_clm_length;
+	char	*cached_txcap;
+	int	cached_txcap_length;
+#endif
+#ifdef KEEP_JP_REGREV
+/* XXX Needed by customer's request */
+	char vars_ccode[WLC_CNTRY_BUF_SZ];
+	uint vars_regrev;
+#endif /* KEEP_JP_REGREV */
+#ifdef WLTDLS
+	uint32 tdls_mode;
+#endif
+#ifdef GSCAN_SUPPORT
+	bool lazy_roam_enable;
+#endif
+#if defined(APF)
+	bool apf_set;
+#endif /* APF */
+	void *macdbg_info;
+#ifdef DHD_WET
+	void *wet_info;
+#endif
+	bool	h2d_phase_supported;
+	bool	force_dongletrap_on_bad_h2d_phase;
+	uint32	dongle_trap_data;
+	fw_download_status_t	fw_download_status;
+	trap_t	last_trap_info; /* trap info from the last trap */
+	uint8 rand_mac_oui[DOT11_OUI_LEN];
+#ifdef DHD_LOSSLESS_ROAMING
+	uint8 dequeue_prec_map;
+	uint8 prio_8021x;
+#endif
+	/* timesync link */
+	struct dhd_ts *ts;
+	bool	d2h_hostrdy_supported;
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+	atomic_t block_bus;
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+#if defined(DBG_PKT_MON) || defined(DHD_PKT_LOGGING)
+	bool d11_tx_status;
+#endif /* DBG_PKT_MON || DHD_PKT_LOGGING */
+	uint16 ndo_version;	/* ND offload version supported */
+#ifdef NDO_CONFIG_SUPPORT
+	bool ndo_enable;		/* ND offload feature enable */
+	bool ndo_host_ip_overflow;	/* # of host ip addr exceed FW capacity */
+	uint32 ndo_max_host_ip;		/* # of host ip addr supported by FW */
+#endif /* NDO_CONFIG_SUPPORT */
+#if defined(DHD_LOG_DUMP)
+	/* buffer to hold 'dhd dump' data before dumping to file */
+	uint8 *concise_dbg_buf;
+	uint64 last_file_posn;
+	int logdump_periodic_flush;
+#ifdef EWP_ECNTRS_LOGGING
+	void *ecntr_dbg_ring;
+#endif
+#ifdef EWP_RTT_LOGGING
+	void *rtt_dbg_ring;
+#endif
+#ifdef EWP_BCM_TRACE
+	void *bcm_trace_dbg_ring;
+#endif
+#ifdef DNGL_EVENT_SUPPORT
+	uint8 health_chk_event_data[HEALTH_CHK_BUF_SIZE];
+#endif
+	void *logdump_cookie;
+#endif /* DHD_LOG_DUMP */
+	uint32 dhd_console_ms; /** interval for polling the dongle for console (log) messages */
+	bool ext_trap_data_supported;
+	uint32 *extended_trap_data;
+#ifdef DUMP_IOCTL_IOV_LIST
+	/* dump iovar list */
+	dll_t dump_iovlist_head;
+	uint8 dump_iovlist_len;
+#endif /* DUMP_IOCTL_IOV_LIST */
+#ifdef REPORT_FATAL_TIMEOUTS
+	timeout_info_t *timeout_info;
+	uint16 esync_id; /* used to track escans */
+	osl_atomic_t set_ssid_rcvd; /* to track if WLC_E_SET_SSID is received during join IOVAR */
+	bool secure_join; /* field to note that the join is secure or not */
+#endif /* REPORT_FATAL_TIMEOUTS */
+#ifdef CUSTOM_SET_ANTNPM
+	uint32 mimo_ant_set;
+#endif /* CUSTOM_SET_ANTNPM */
+#ifdef CUSTOM_SET_OCLOFF
+	bool ocl_off;
+#endif /* CUSTOM_SET_OCLOFF */
+#ifdef DHD_DEBUG
+	/* memwaste feature */
+	dll_t mw_list_head; /* memwaste list head */
+	uint32 mw_id; /* memwaste list unique id */
+#endif /* DHD_DEBUG */
+#ifdef WLTDLS
+	spinlock_t tdls_lock;
+#endif /* WLTDLS */
+	uint pcie_txs_metadata_enable;
+	uint wbtext_policy;	/* wbtext policy of dongle */
+	bool wbtext_support;	/* for product policy only */
+#ifdef PCIE_OOB
+	bool	d2h_no_oob_dw;
+#endif /* PCIE_OOB */
+#ifdef PCIE_INB_DW
+	bool	d2h_inband_dw;
+	enum dhd_bus_ds_state	ds_state;
+#endif /* PCIE_INB_DW */
+	tput_test_t tput_data;
+	uint64 tput_start_ts;
+	uint64 tput_stop_ts;
+	uint dhd_watchdog_ms_backup;
+	bool wl_event_enabled;
+	bool logtrace_pkt_sendup;
+#ifdef GDB_PROXY
+	/* True if firmware runs under gdb control (this may cause timeouts at any point) */
+	bool gdb_proxy_active;
+	/* True if deadman_to shall be forced to 0 */
+	bool gdb_proxy_nodeadman;
+	/* Counter incremented at each firmware stop/go transition. LSB (GDB_PROXY_STOP_MASK)
+	 * is set when firmware is stopped, clear when running
+	 */
+	uint32 gdb_proxy_stop_count;
+#endif /* GDB_PROXY */
+	int debug_dump_subcmd;
+	uint64 debug_dump_time_sec;
+	bool hscb_enable;
+	uint64 logset_prsrv_mask;
+#ifdef DHD_PKT_LOGGING
+	struct dhd_pktlog *pktlog;
+	char debug_dump_time_pktlog_str[DEBUG_DUMP_TIME_BUF_LEN];
+	bool pktlog_debug;
+#endif /* DHD_PKT_LOGGING */
+#ifdef EWP_EDL
+	bool dongle_edl_support;
+	dhd_dma_buf_t edl_ring_mem;
+#endif /* EWP_EDL */
+#if defined(LINUX) || defined(linux)
+	struct mutex ndev_op_sync;
+#endif /* defined (LINUX) || defined(linux) */
+	bool debug_buf_dest_support;
+	uint32 debug_buf_dest_stat[DEBUG_BUF_DEST_MAX];
+#ifdef WL_CFGVENDOR_SEND_HANG_EVENT
+	char *hang_info;
+	int hang_info_cnt;
+	char debug_dump_time_hang_str[DEBUG_DUMP_TIME_BUF_LEN];
+#endif /* WL_CFGVENDOR_SEND_HANG_EVENT */
+	char debug_dump_time_str[DEBUG_DUMP_TIME_BUF_LEN];
+	void *event_log_filter;
+	uint tput_test_done;
+#if defined(LINUX) || defined(linux)
+	wait_queue_head_t tx_tput_test_wait;
+	wait_queue_head_t tx_completion_wait;
+#endif /* defined(LINUX) || defined(linux) */
+#if defined(DHD_H2D_LOG_TIME_SYNC)
+#define DHD_H2D_LOG_TIME_STAMP_MATCH	(10000) /* 10 Seconds */
+	/*
+	 * Interval for updating the dongle console message time stamp with the Host (DHD)
+	 * time stamp
+	 */
+	uint32 dhd_rte_time_sync_ms;
+#endif /* DHD_H2D_LOG_TIME_SYNC */
+	uint32 batch_tx_pkts_cmpl;
+	uint32 batch_tx_num_pkts;
+#ifdef DHD_DUMP_MNGR
+	struct _dhd_dump_file_manage *dump_file_manage;
+#endif /* DHD_DUMP_MNGR */
+	bool event_log_max_sets_queried;
+	uint32 event_log_max_sets;
+#ifdef DHD_STATUS_LOGGING
+	void *statlog;
+#endif /* DHD_STATUS_LOGGING */
+#ifdef DHD_MAP_PKTID_LOGGING
+	bool enable_pktid_log_dump;
+#endif /* DHD_MAP_PKTID_LOGGING */
+	bool extdtxs_in_txcpl;
+	bool hostrdy_after_init;
+	uint16 dhd_induce_error;
+	uint16 dhd_induce_bh_error;
+	int wlc_ver_major;
+	int wlc_ver_minor;
+#ifdef SUPPORT_SET_TID
+	uint8 tid_mode;
+	uint32 target_uid;
+	uint8 target_tid;
+#endif /* SUPPORT_SET_TID */
+#ifdef DHD_PKTDUMP_ROAM
+	void *pktcnts;
+#endif /* DHD_PKTDUMP_ROAM */
+	dhd_db7_info_t db7_trap;
+	bool fw_preinit;
+	bool ring_attached;
+	union {
+		wl_roam_stats_v1_t v1;
+	} roam_evt;
+	bool arpoe_enable;
+	bool arpol_configured;
+#ifdef DHD_TX_PROFILE
+	bool tx_profile_enab;
+	uint8 num_profiles;
+	dhd_tx_profile_protocol_t *protocol_filters;
+#endif /* defined(DHD_TX_PROFILE) */
+#ifdef DHD_MEM_STATS
+	void *mem_stats_lock;
+	uint64 txpath_mem;
+	uint64 rxpath_mem;
+#endif /* DHD_MEM_STATS */
+#ifdef DHD_LB_RXP
+	atomic_t lb_rxp_flow_ctrl;
+	uint32 lb_rxp_stop_thr;
+	uint32 lb_rxp_strt_thr;
+#endif /* DHD_LB_RXP */
+#ifdef DHD_LB_STATS
+	uint64 lb_rxp_stop_thr_hitcnt;
+	uint64 lb_rxp_strt_thr_hitcnt;
+	uint64 lb_rxp_napi_sched_cnt;
+	uint64 lb_rxp_napi_complete_cnt;
+	uint64 rx_dma_stall_hc_ignore_cnt;
+#endif /* DHD_LB_STATS */
+	bool check_trap_rot;
+	/* if FW supports host insertion of SFH LLC */
+	bool host_sfhllc_supported;
+#ifdef DHD_GRO_ENABLE_HOST_CTRL
+	bool permitted_gro;
+#endif /* DHD_GRO_ENABLE_HOST_CTRL */
+#ifdef WL_CFGVENDOR_SEND_ALERT_EVENT
+	uint32 alert_reason;		/* reason codes for alert event */
+#endif /* WL_CFGVENDOR_SEND_ALERT_EVENT */
+#ifdef DBG_PKT_MON
+	bool aml_enable;	/* aml(assoc mgmt frame logger) enable flags */
+#endif /* DBG_PKT_MON */
+	bool fw_mode_changed;
+	bool do_chip_bighammer;
+	uint chip_bighammer_count;
+	bool rx_cpl_lat_capable; /* FW supports latency posting in Rx cpl ring */
+	rx_cpl_lat_info_t rxcpl_lat_info; /* Rx Cpl latency information */
+	tx_cpl_info_t txcpl_info; /* TX completion timestamp info */
+#ifdef SUPPORT_OTA_UPDATE
+	ota_update_info_t ota_update_info;
+#endif /* SUPPORT_OTA_UPDATE */
+#ifdef CSI_SUPPORT
+	struct mutex         csi_lock;
+
+	struct sk_buff_head  csi_raw_skb_queue     ____cacheline_aligned;
+	struct work_struct   csi_raw_skb_work;
+
+	struct list_head     csi_list;
+	uint                 csi_count;
+
+	uint8                csi_init;
+	uint8                csi_version_capability;
+	uint8                csi_header_output_version;
+
+	uint16               csi_data_send_manner;
+	uint16               csi_notify_port;
+	uint32               csi_notify_ip;
+	uint32               csi_local_ip;
+
+	int32                packet_global_id_last;
+	uint32               padding_global_id;
+	uint32               packet_qty_duplicate;
+	uint32               packet_qty_missing;
+#endif /* CSI_SUPPORT */
+	bool stop_in_progress;
+#ifdef SYNA_SAR_CUSTOMER_PARAMETER
+	uint32 dhd_sar_mode;
+#endif /* SYNA_SAR_CUSTOMER_PARAMETER */
+
+	/* Pointer to Platform Layer */
+	void *plat_info;
+	uint32 plat_info_size;
+	bool htput_support;
+#ifdef FLOW_RING_PREALLOC
+	uint16 non_htput_total_flow_rings;
+#endif /* FLOW_RING_PREALLOC */
+	bool fw_lpm_support; /* fw supports LPM mode */
+	bool igmpo_enable; /* fw supports igmp offload */
+#ifdef DHD_SUPPORT_SPMI_MODE
+	uint dhd_spmi_mode;
+#endif /* DHD_SUPPORT_SPMI_MODE */
+	/* Flag to indicate H2D flowring phase nibble value support */
+	uint8 fr_phase_nibble;
+	bool mdring_capable; /* FW supports metadata ring cpl ring */
+	uint8 *mdring_info;  /* Saved metadta ring work items */
+	uint32 md_item_count; /* # of saved metadata work items */
+#if defined(DEVICE_TX_STUCK_DETECT) && defined(ASSOC_CHECK_SR)
+	/* is infra associated or not before suspend ? */
+	bool assoc_at_suspend;
+#endif /* DEVICE_TX_STUCK_DETECT && ASSOC_CHECK_SR */
+	uint32 p2p_disc_busy_cnt;
+	bool skip_memdump_map_read;
+#if defined(DHD_SI_WD_RESET)
+	bool si_wd;
+#endif
+#ifdef PKT_FILTER_SUPPORT
+	uint8 pfaoe_enab;
+#endif /* PKT_FILTER_SUPPORT */
+
+	char *clm_path;		/* module_param: path to clm vars file */
+	char *conf_path;		/* module_param: path to config vars file */
+	struct dhd_conf *conf;	/* Bus module handle */
+	void *adapter;			/* adapter information, interrupt, fw path etc. */
+	void *event_params;
+#ifdef WL_TIMER
+	void *timer_params;
+#endif /* WL_TIMER */
+#ifdef BCMDBUS
+	bool dhd_remove;
+#endif /* BCMDBUS */
+#ifdef WL_ESCAN
+	struct wl_escan_info *escan;
+#endif
+#if defined(WL_WIRELESS_EXT)
+	void *wext_info;
+#endif
+#ifdef WL_EXT_IAPSTA
+	void *iapsta_params;
+#endif
+	int hostsleep;
+#ifdef SENDPROB
+	bool recv_probereq;
+#endif
+#ifdef DHD_NOTIFY_MAC_CHANGED
+	bool skip_dhd_stop;
+#endif /* DHD_NOTIFY_MAC_CHANGED */
+#ifdef WL_EXT_GENL
+	void *zconf;
+#endif
+} dhd_pub_t;
+
+#if defined(__linux__)
+int dhd_wifi_platform_set_power(dhd_pub_t *pub, bool on);
+#else
+static INLINE int dhd_wifi_platform_set_power(dhd_pub_t *pub, bool on)  { return 0; }
+#endif /* __linux__ */
+
+#define MAX_WAKE_REASON_STATS	32u
+typedef struct {
+	uint rxwake;
+	uint rcwake;
+#ifdef DHD_WAKE_RX_STATUS
+	uint rx_bcast;
+	uint rx_arp;
+	uint rx_mcast;
+	uint rx_multi_ipv6;
+	uint rx_icmp;
+	uint rx_icmpv6;
+	uint rx_icmpv6_ra;
+	uint rx_icmpv6_na;
+	uint rx_icmpv6_ns;
+	uint rx_multi_ipv4;
+	uint rx_multi_other;
+	uint rx_ucast;
+#endif /* DHD_WAKE_RX_STATUS */
+#ifdef DHD_WAKE_EVENT_STATUS
+#ifdef CUSTOM_WAKE_REASON_STATS
+	int rc_event[MAX_WAKE_REASON_STATS];
+	int rc_event_idx;
+#else
+	uint rc_event[WLC_E_LAST];
+#endif /* CUSTOM_WAKE_REASON_STATS */
+#endif /* DHD_WAKE_EVENT_STATUS */
+} wake_counts_t;
+
+#if defined(PCIE_FULL_DONGLE)
+/*
+ * XXX: WARNING: dhd_wlfc.h also defines a dhd_pkttag_t
+ * making wlfc incompatible with PCIE_FULL DONGLE
+ */
+
+/* Packet Tag for PCIE Full Dongle DHD */
+typedef struct dhd_pkttag_fd {
+	uint16    flowid;   /* Flowring Id */
+	uint16    ifid;
+#ifdef DHD_SBN
+	uint8	  pkt_udr;
+	uint8	  pad;
+#endif /* DHD_SBN */
+#if defined(BCM_ROUTER_DHD) && defined(BCM_GMAC3)
+	uint16    dataoff;  /* start of packet */
+#endif /* BCM_ROUTER_DHD && BCM_GMAC3 */
+#ifndef DHD_PCIE_PKTID
+	uint16    dma_len;  /* pkt len for DMA_MAP/UNMAP */
+	dmaaddr_t pa;       /* physical address */
+	void      *dmah;    /* dma mapper handle */
+	void      *secdma; /* secure dma sec_cma_info handle */
+#endif /* !DHD_PCIE_PKTID */
+#if defined(TX_STATUS_LATENCY_STATS)
+	uint64	   q_time_us; /* time when tx pkt queued to flowring */
+#endif
+} dhd_pkttag_fd_t;
+
+/* Packet Tag for DHD PCIE Full Dongle */
+#define DHD_PKTTAG_FD(pkt)          ((dhd_pkttag_fd_t *)(PKTTAG(pkt)))
+
+#define DHD_PKT_GET_FLOWID(pkt)     ((DHD_PKTTAG_FD(pkt))->flowid)
+#define DHD_PKT_SET_FLOWID(pkt, pkt_flowid) \
+	DHD_PKTTAG_FD(pkt)->flowid = (uint16)(pkt_flowid)
+
+#define DHD_PKT_GET_DATAOFF(pkt)    ((DHD_PKTTAG_FD(pkt))->dataoff)
+#define DHD_PKT_SET_DATAOFF(pkt, pkt_dataoff) \
+	DHD_PKTTAG_FD(pkt)->dataoff = (uint16)(pkt_dataoff)
+
+#define DHD_PKT_GET_DMA_LEN(pkt)    ((DHD_PKTTAG_FD(pkt))->dma_len)
+#define DHD_PKT_SET_DMA_LEN(pkt, pkt_dma_len) \
+	DHD_PKTTAG_FD(pkt)->dma_len = (uint16)(pkt_dma_len)
+
+#define DHD_PKT_GET_PA(pkt)         ((DHD_PKTTAG_FD(pkt))->pa)
+#define DHD_PKT_SET_PA(pkt, pkt_pa) \
+	DHD_PKTTAG_FD(pkt)->pa = (dmaaddr_t)(pkt_pa)
+
+#define DHD_PKT_GET_DMAH(pkt)       ((DHD_PKTTAG_FD(pkt))->dmah)
+#define DHD_PKT_SET_DMAH(pkt, pkt_dmah) \
+	DHD_PKTTAG_FD(pkt)->dmah = (void *)(pkt_dmah)
+
+#define DHD_PKT_GET_SECDMA(pkt)    ((DHD_PKTTAG_FD(pkt))->secdma)
+#define DHD_PKT_SET_SECDMA(pkt, pkt_secdma) \
+	DHD_PKTTAG_FD(pkt)->secdma = (void *)(pkt_secdma)
+
+#if defined(TX_STATUS_LATENCY_STATS)
+#define DHD_PKT_GET_QTIME(pkt)    ((DHD_PKTTAG_FD(pkt))->q_time_us)
+#define DHD_PKT_SET_QTIME(pkt, pkt_q_time_us) \
+	DHD_PKTTAG_FD(pkt)->q_time_us = (uint64)(pkt_q_time_us)
+#endif
+#endif /* PCIE_FULL_DONGLE */
+
+#if defined(BCMWDF)
+typedef struct {
+	dhd_pub_t *dhd_pub;
+} dhd_workitem_context_t;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(dhd_workitem_context_t, dhd_get_dhd_workitem_context)
+#endif /* (BCMWDF)  */
+
+#if defined(LINUX) || defined(linux)
+#if defined(CONFIG_PM_SLEEP)
+
+	#define DHD_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
+	#define _DHD_PM_RESUME_WAIT(a, b) do {\
+			int retry = 0; \
+			SMP_RD_BARRIER_DEPENDS(); \
+			while (dhd_mmc_suspend && retry++ != b) { \
+				SMP_RD_BARRIER_DEPENDS(); \
+				wait_event_interruptible_timeout(a, !dhd_mmc_suspend, 1); \
+			} \
+		} 	while (0)
+	#define DHD_PM_RESUME_WAIT(a) 		_DHD_PM_RESUME_WAIT(a, 200)
+	#define DHD_PM_RESUME_WAIT_FOREVER(a) 	_DHD_PM_RESUME_WAIT(a, ~0)
+	#define DHD_PM_RESUME_RETURN_ERROR(a)   do { \
+			if (dhd_mmc_suspend) { \
+				printf("%s[%d]: mmc is still in suspend state!!!\n", \
+					__FUNCTION__, __LINE__); \
+				return a; \
+			} \
+		} while (0)
+	#define DHD_PM_RESUME_RETURN		do { if (dhd_mmc_suspend) return; } while (0)
+
+	#define DHD_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
+	#define SPINWAIT_SLEEP(a, exp, us) do { \
+		uint countdown = (us) + 9999; \
+		while ((exp) && (countdown >= 10000)) { \
+			wait_event_interruptible_timeout(a, FALSE, 1); \
+			countdown -= 10000; \
+		} \
+	} while (0)
+
+#else
+
+	#define DHD_PM_RESUME_WAIT_INIT(a)
+	#define DHD_PM_RESUME_WAIT(a)
+	#define DHD_PM_RESUME_WAIT_FOREVER(a)
+	#define DHD_PM_RESUME_RETURN_ERROR(a)
+	#define DHD_PM_RESUME_RETURN
+
+	#define DHD_SPINWAIT_SLEEP_INIT(a)
+	#define SPINWAIT_SLEEP(a, exp, us)  do { \
+		uint countdown = (us) + 9; \
+		while ((exp) && (countdown >= 10)) { \
+			OSL_DELAY(10);  \
+			countdown -= 10;  \
+		} \
+	} while (0)
+
+#endif /* CONFIG_PM_SLEEP */
+#else
+	#define DHD_SPINWAIT_SLEEP_INIT(a)
+	#define SPINWAIT_SLEEP(a, exp, us)  do { \
+		uint countdown = (us) + 9; \
+		while ((exp) && (countdown >= 10)) { \
+			OSL_DELAY(10);  \
+			countdown -= 10;  \
+		} \
+	} while (0)
+#endif /* defined (LINUX) || defined(linux) */
+
+#define DHD_IF_VIF	0x01	/* Virtual IF (Hidden from user) */
+
+#ifdef PNO_SUPPORT
+int dhd_pno_clean(dhd_pub_t *dhd);
+#endif /* PNO_SUPPORT */
+
+/*
+ *  Wake locks are an Android power management concept. They are used by applications and services
+ *  to request CPU resources.
+ */
+#if defined(linux) && defined(OEM_ANDROID)
+extern int dhd_os_wake_lock(dhd_pub_t *pub);
+extern int dhd_os_wake_unlock(dhd_pub_t *pub);
+extern int dhd_os_wake_lock_waive(dhd_pub_t *pub);
+extern int dhd_os_wake_lock_restore(dhd_pub_t *pub);
+extern void dhd_event_wake_lock(dhd_pub_t *pub);
+extern void dhd_event_wake_unlock(dhd_pub_t *pub);
+extern void dhd_pm_wake_lock_timeout(dhd_pub_t *pub, int val);
+extern void dhd_pm_wake_unlock(dhd_pub_t *pub);
+extern void dhd_txfl_wake_lock_timeout(dhd_pub_t *pub, int val);
+extern void dhd_txfl_wake_unlock(dhd_pub_t *pub);
+extern void dhd_nan_wake_lock_timeout(dhd_pub_t *pub, int val);
+extern void dhd_nan_wake_unlock(dhd_pub_t *pub);
+extern int dhd_os_wake_lock_timeout(dhd_pub_t *pub);
+extern int dhd_os_wake_lock_rx_timeout_enable(dhd_pub_t *pub, int val);
+extern int dhd_os_wake_lock_ctrl_timeout_enable(dhd_pub_t *pub, int val);
+extern int dhd_os_wake_lock_ctrl_timeout_cancel(dhd_pub_t *pub);
+extern int dhd_os_wd_wake_lock(dhd_pub_t *pub);
+extern int dhd_os_wd_wake_unlock(dhd_pub_t *pub);
+extern void dhd_os_wake_lock_init(struct dhd_info *dhd);
+extern void dhd_os_wake_lock_destroy(struct dhd_info *dhd);
+#ifdef DHD_USE_SCAN_WAKELOCK
+extern void dhd_os_scan_wake_lock_timeout(dhd_pub_t *pub, int val);
+extern void dhd_os_scan_wake_unlock(dhd_pub_t *pub);
+#endif /* BCMPCIE_SCAN_WAKELOCK */
+
+#ifdef WLEASYMESH
+extern int dhd_get_1905_almac(dhd_pub_t *dhdp, uint8 ifidx, uint8* ea, bool mcast);
+extern int dhd_set_1905_almac(dhd_pub_t *dhdp, uint8 ifidx, uint8* ea, bool mcast);
+#endif /* WLEASYMESH */
+
+inline static void MUTEX_LOCK_SOFTAP_SET_INIT(dhd_pub_t * dhdp)
+{
+#if defined(OEM_ANDROID)
+	mutex_init(&dhdp->wl_softap_lock);
+#endif /* OEM_ANDROID */
+}
+
+inline static void MUTEX_LOCK_SOFTAP_SET(dhd_pub_t * dhdp)
+{
+#if defined(OEM_ANDROID)
+	mutex_lock(&dhdp->wl_softap_lock);
+#endif /* OEM_ANDROID */
+}
+
+inline static void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t * dhdp)
+{
+#if defined(OEM_ANDROID)
+	mutex_unlock(&dhdp->wl_softap_lock);
+#endif /* OEM_ANDROID */
+}
+
+#ifdef DHD_DEBUG_WAKE_LOCK
+extern int dhd_wakelock_counter_get(dhd_pub_t *pub);
+extern int dhd_wakelock_wd_counter_get(dhd_pub_t *pub);
+
+#define DHD_OS_WAKE_LOCK(pub) \
+	do { \
+		printf("call wake_lock: %s %d (%d)\n", \
+			__FUNCTION__, __LINE__, dhd_wakelock_counter_get(pub)); \
+		dhd_os_wake_lock(pub); \
+	} while (0)
+#define DHD_OS_WAKE_UNLOCK(pub) \
+	do { \
+		printf("call wake_unlock: %s %d (%d)\n", \
+			__FUNCTION__, __LINE__, dhd_wakelock_counter_get(pub)); \
+		dhd_os_wake_unlock(pub); \
+	} while (0)
+#define DHD_EVENT_WAKE_LOCK(pub) \
+	do { \
+		printf("call event wake_lock: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_event_wake_lock(pub); \
+	} while (0)
+#define DHD_EVENT_WAKE_UNLOCK(pub) \
+	do { \
+		printf("call event wake_unlock: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_event_wake_unlock(pub); \
+	} while (0)
+#define DHD_PM_WAKE_LOCK_TIMEOUT(pub, val) \
+	do { \
+		printf("call pm_wake_timeout enable: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_pm_wake_lock_timeout(pub, val); \
+	} while (0)
+#define DHD_PM_WAKE_UNLOCK(pub) \
+	do { \
+		printf("call pm_wake unlock: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_pm_wake_unlock(pub); \
+	} while (0)
+#define DHD_TXFL_WAKE_LOCK_TIMEOUT(pub, val) \
+	do { \
+		printf("call txfl_wake_timeout enable: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_txfl_wake_lock_timeout(pub, val); \
+	} while (0)
+#define DHD_TXFL_WAKE_UNLOCK(pub) \
+	do { \
+		printf("call txfl_wake unlock: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_txfl_wake_unlock(pub); \
+	} while (0)
+#define DHD_NAN_WAKE_LOCK_TIMEOUT(pub, val) \
+	do { \
+		printf("call nan_wake_timeout enable: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_nan_wake_lock_timeout(pub, val); \
+	} while (0)
+#define DHD_NAN_WAKE_UNLOCK(pub) \
+	do { \
+		printf("call nan_wake unlock: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_nan_wake_unlock(pub); \
+	} while (0)
+#define DHD_OS_WAKE_LOCK_TIMEOUT(pub) \
+	do { \
+		printf("call wake_lock_timeout: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_os_wake_lock_timeout(pub); \
+	} while (0)
+#define DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(pub, val) \
+	do { \
+		printf("call dhd_wake_lock_rx_timeout_enable[%d]: %s %d\n", \
+			val, __FUNCTION__, __LINE__); \
+		dhd_os_wake_lock_rx_timeout_enable(pub, val); \
+	} while (0)
+#define DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(pub, val) \
+	do { \
+		printf("call dhd_wake_lock_ctrl_timeout_enable[%d]: %s %d\n", \
+			val, __FUNCTION__, __LINE__); \
+		dhd_os_wake_lock_ctrl_timeout_enable(pub, val); \
+	} while (0)
+#define DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_CANCEL(pub) \
+	do { \
+		printf("call dhd_wake_lock_ctrl_timeout_cancel: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_os_wake_lock_ctrl_timeout_cancel(pub); \
+	} while (0)
+#define DHD_OS_WAKE_LOCK_WAIVE(pub) \
+	do { \
+		printf("call dhd_wake_lock_waive: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_os_wake_lock_waive(pub); \
+	} while (0)
+#define DHD_OS_WAKE_LOCK_RESTORE(pub) \
+	do { \
+		printf("call dhd_wake_lock_restore: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_os_wake_lock_restore(pub); \
+	} while (0)
+#define DHD_OS_WAKE_LOCK_INIT(dhd) \
+	do { \
+		printf("call dhd_wake_lock_init: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_os_wake_lock_init(dhd); \
+	} while (0)
+#define DHD_OS_WAKE_LOCK_DESTROY(dhd) \
+	do { \
+		printf("call dhd_wake_dhd_lock_destroy: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_os_wake_lock_destroy(dhd); \
+	} while (0)
+#define DHD_OS_WD_WAKE_LOCK(pub) \
+	do { \
+		printf("call dhd_os_WD_wake_lock: %s %d (%d)\n", \
+			__FUNCTION__, __LINE__, dhd_wakelock_wd_counter_get(pub)); \
+		dhd_os_wd_wake_lock(pub); \
+	} while (0)
+#define DHD_OS_WD_WAKE_UNLOCK(pub) \
+	do { \
+		printf("call dhd_os_WD_wake_unlock: %s %d (%d)\n", \
+			__FUNCTION__, __LINE__, dhd_wakelock_wd_counter_get(pub)); \
+		dhd_os_wd_wake_unlock(pub); \
+	} while (0)
+#else
+#define DHD_OS_WAKE_LOCK(pub)			dhd_os_wake_lock(pub)
+#define DHD_OS_WAKE_UNLOCK(pub)		dhd_os_wake_unlock(pub)
+#define DHD_EVENT_WAKE_LOCK(pub)			dhd_event_wake_lock(pub)
+#define DHD_EVENT_WAKE_UNLOCK(pub)		dhd_event_wake_unlock(pub)
+#define DHD_PM_WAKE_LOCK_TIMEOUT(pub, val)  dhd_pm_wake_lock_timeout(pub, val)
+#define DHD_PM_WAKE_UNLOCK(pub) 			dhd_pm_wake_unlock(pub)
+#define DHD_TXFL_WAKE_LOCK_TIMEOUT(pub, val)	dhd_txfl_wake_lock_timeout(pub, val)
+#define DHD_TXFL_WAKE_UNLOCK(pub) 			dhd_txfl_wake_unlock(pub)
+#define DHD_NAN_WAKE_LOCK_TIMEOUT(pub, val)	dhd_nan_wake_lock_timeout(pub, val)
+#define DHD_NAN_WAKE_UNLOCK(pub)		dhd_nan_wake_unlock(pub)
+#define DHD_OS_WAKE_LOCK_TIMEOUT(pub)		dhd_os_wake_lock_timeout(pub)
+#define DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(pub, val) \
+	dhd_os_wake_lock_rx_timeout_enable(pub, val)
+#define DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(pub, val) \
+	dhd_os_wake_lock_ctrl_timeout_enable(pub, val)
+#define DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_CANCEL(pub) \
+	dhd_os_wake_lock_ctrl_timeout_cancel(pub)
+#define DHD_OS_WAKE_LOCK_WAIVE(pub)			dhd_os_wake_lock_waive(pub)
+#define DHD_OS_WAKE_LOCK_RESTORE(pub)		dhd_os_wake_lock_restore(pub)
+#define DHD_OS_WAKE_LOCK_INIT(dhd)		dhd_os_wake_lock_init(dhd);
+#define DHD_OS_WAKE_LOCK_DESTROY(dhd)		dhd_os_wake_lock_destroy(dhd);
+#define DHD_OS_WD_WAKE_LOCK(pub)		dhd_os_wd_wake_lock(pub)
+#define DHD_OS_WD_WAKE_UNLOCK(pub)		dhd_os_wd_wake_unlock(pub)
+#endif /* DHD_DEBUG_WAKE_LOCK */
+
+#ifdef DHD_USE_SCAN_WAKELOCK
+#ifdef DHD_DEBUG_SCAN_WAKELOCK
+#define DHD_OS_SCAN_WAKE_LOCK_TIMEOUT(pub, val) \
+	do { \
+		printf("call wake_lock_scan: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_os_scan_wake_lock_timeout(pub, val); \
+	} while (0)
+#define DHD_OS_SCAN_WAKE_UNLOCK(pub) \
+	do { \
+		printf("call wake_unlock_scan: %s %d\n", \
+			__FUNCTION__, __LINE__); \
+		dhd_os_scan_wake_unlock(pub); \
+	} while (0)
+#else
+#define DHD_OS_SCAN_WAKE_LOCK_TIMEOUT(pub, val)		dhd_os_scan_wake_lock_timeout(pub, val)
+#define DHD_OS_SCAN_WAKE_UNLOCK(pub)			dhd_os_scan_wake_unlock(pub)
+#endif /* DHD_DEBUG_SCAN_WAKELOCK */
+#else
+#define DHD_OS_SCAN_WAKE_LOCK_TIMEOUT(pub, val)
+#define DHD_OS_SCAN_WAKE_UNLOCK(pub)
+#endif /* DHD_USE_SCAN_WAKELOCK */
+
+#else
+
+/* Wake lock are used in Android only (until the Linux community accepts it) */
+#define DHD_OS_WAKE_LOCK(pub)
+#define DHD_OS_WAKE_UNLOCK(pub)
+#define DHD_EVENT_WAKE_LOCK(pub)
+#define DHD_EVENT_WAKE_UNLOCK(pub)
+#define DHD_PM_WAKE_LOCK_TIMEOUT(pub, val)
+#define DHD_PM_WAKE_UNLOCK(pub)
+#define DHD_TXFL_WAKE_LOCK_TIMEOUT(pub, val)
+#define DHD_TXFL_WAKE_UNLOCK(pub)
+#define DHD_NAN_WAKE_LOCK_TIMEOUT(pub, val)
+#define DHD_NAN_WAKE_UNLOCK(pub)
+#define DHD_OS_WD_WAKE_LOCK(pub)
+#define DHD_OS_WD_WAKE_UNLOCK(pub)
+#define DHD_OS_WAKE_LOCK_TIMEOUT(pub)
+#define DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(pub, val)	UNUSED_PARAMETER(val)
+#define DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(pub, val)	UNUSED_PARAMETER(val)
+#define DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_CANCEL(pub, val)
+#define DHD_OS_WAKE_LOCK_WAIVE(pub)
+#define DHD_OS_WAKE_LOCK_RESTORE(pub)
+#define DHD_OS_SCAN_WAKE_LOCK_TIMEOUT(pub, val)
+#define DHD_OS_SCAN_WAKE_UNLOCK(pub)
+#define DHD_OS_WAKE_LOCK_INIT(dhd)
+#define DHD_OS_WAKE_LOCK_DESTROY(dhd)
+
+#endif /* #defined(linux) && defined(OEM_ANDROID) */
+
+#ifdef BCMPCIE_OOB_HOST_WAKE
+#define OOB_WAKE_LOCK_TIMEOUT 500
+extern void dhd_os_oob_irq_wake_lock_timeout(dhd_pub_t *pub, int val);
+extern void dhd_os_oob_irq_wake_unlock(dhd_pub_t *pub);
+
+#define DHD_OS_OOB_IRQ_WAKE_LOCK_TIMEOUT(pub, val)	dhd_os_oob_irq_wake_lock_timeout(pub, val)
+#define DHD_OS_OOB_IRQ_WAKE_UNLOCK(pub)			dhd_os_oob_irq_wake_unlock(pub)
+#endif /* BCMPCIE_OOB_HOST_WAKE */
+
+/* The DHD_PACKET_TIMEOUT_MS & MAX_TX_TIMEOUT are used for wake_lock timeout
+ * to prevent the system from entering suspend during TX/RX frame processing.
+ * It can be adjusted depending on the host platform.
+ */
+#define DHD_MONITOR_TIMEOUT_MS	1000
+#ifndef DHD_PACKET_TIMEOUT_MS
+#define DHD_PACKET_TIMEOUT_MS	100
+#endif
+#define DHD_HANDSHAKE_TIMEOUT_MS	1000
+#define DHD_EVENT_TIMEOUT_MS	1500
+#define SCAN_WAKE_LOCK_TIMEOUT	10000
+#ifndef MAX_TX_TIMEOUT
+#define MAX_TX_TIMEOUT			100
+#endif
+
+/* Enum for IOCTL recieved status */
+typedef enum dhd_ioctl_recieved_status
+{
+	IOCTL_WAIT = 0,
+	IOCTL_RETURN_ON_SUCCESS,
+	IOCTL_RETURN_ON_TRAP,
+	IOCTL_RETURN_ON_BUS_STOP,
+	IOCTL_RETURN_ON_ERROR
+} dhd_ioctl_recieved_status_t;
+
+/* interface operations (register, remove) should be atomic, use this lock to prevent race
+ * condition among wifi on/off and interface operation functions
+ */
+#if defined(LINUX)
+void dhd_net_if_lock(struct net_device *dev);
+void dhd_net_if_unlock(struct net_device *dev);
+bool dhd_net_if_locked(struct net_device *dev);
+#endif /* LINUX */
+
+#if defined(LINUX) || defined(linux)
+#if defined(MULTIPLE_SUPPLICANT)
+extern void wl_android_post_init(void); // terence 20120530: fix critical section in dhd_open and dhdsdio_probe
+#endif /* MULTIPLE_SUPPLICANT */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) && defined(MULTIPLE_SUPPLICANT)
+extern struct mutex _dhd_mutex_lock_;
+#define DHD_MUTEX_IS_LOCK_RETURN() \
+	if (mutex_is_locked(&_dhd_mutex_lock_) != 0) { \
+		printf("%s : probe is already running! return.\n", __FUNCTION__); \
+		return -EBUSY;; \
+	}
+#define DHD_MUTEX_LOCK() \
+	do { \
+		if (mutex_is_locked(&_dhd_mutex_lock_) == 0) { \
+			printf("%s : no mutex held\n", __FUNCTION__); \
+		} else { \
+			printf("%s : mutex is locked!. wait for unlocking\n", __FUNCTION__); \
+		} \
+		mutex_lock(&_dhd_mutex_lock_); \
+		printf("%s : set mutex lock\n", __FUNCTION__); \
+	} while (0)
+#define DHD_MUTEX_UNLOCK() \
+	do { \
+		printf("%s : mutex is released.\n", __FUNCTION__); \
+		mutex_unlock(&_dhd_mutex_lock_); \
+	} while (0)
+#else
+#define DHD_MUTEX_IS_LOCK_RETURN(a)	do {} while (0)
+#define DHD_MUTEX_LOCK(a)	do {} while (0)
+#define DHD_MUTEX_UNLOCK(a)	do {} while (0)
+#endif
+#endif /* defined (LINUX) || defined(linux) */
+
+typedef enum dhd_attach_states
+{
+	DHD_ATTACH_STATE_INIT = 0x0,
+	DHD_ATTACH_STATE_NET_ALLOC = 0x1,
+	DHD_ATTACH_STATE_DHD_ALLOC = 0x2,
+	DHD_ATTACH_STATE_ADD_IF = 0x4,
+	DHD_ATTACH_STATE_PROT_ATTACH = 0x8,
+	DHD_ATTACH_STATE_WL_ATTACH = 0x10,
+	DHD_ATTACH_STATE_THREADS_CREATED = 0x20,
+	DHD_ATTACH_STATE_WAKELOCKS_INIT = 0x40,
+	DHD_ATTACH_STATE_CFG80211 = 0x80,
+	DHD_ATTACH_STATE_EARLYSUSPEND_DONE = 0x100,
+	DHD_ATTACH_TIMESYNC_ATTACH_DONE = 0x200,
+	DHD_ATTACH_LOGTRACE_INIT = 0x400,
+	DHD_ATTACH_STATE_LB_ATTACH_DONE = 0x800,
+	DHD_ATTACH_STATE_DONE = 0x1000
+} dhd_attach_states_t;
+
+/* Value -1 means we are unsuccessful in creating the kthread. */
+#define DHD_PID_KT_INVALID		-1
+/* Value -2 means we are unsuccessful in both creating the kthread and tasklet */
+#define DHD_PID_KT_TL_INVALID		-2
+
+/* default reporting period */
+#define ECOUNTERS_DEFAULT_PERIOD	0
+
+/* default number of reports. '0' indicates forever */
+#define ECOUNTERS_NUM_REPORTS		0
+
+typedef struct ecounters_cfg {
+	uint16 type;
+	uint16 if_slice_idx;
+	uint16 stats_rep;
+} ecounters_cfg_t;
+
+typedef struct event_ecounters_cfg {
+	uint16 event_id;
+	uint16 type;
+	uint16 if_slice_idx;
+	uint16 stats_rep;
+} event_ecounters_cfg_t;
+
+typedef struct ecountersv2_xtlv_list_elt {
+	/* Not quite the exact bcm_xtlv_t type as data could be pointing to other pieces in
+	 * memory at the time of parsing arguments.
+	 */
+	uint16 id;
+	uint16 len;
+	uint8 *data;
+	struct ecountersv2_xtlv_list_elt *next;
+} ecountersv2_xtlv_list_elt_t;
+
+typedef struct ecountersv2_processed_xtlv_list_elt {
+	uint8 *data;
+	struct ecountersv2_processed_xtlv_list_elt *next;
+} ecountersv2_processed_xtlv_list_elt;
+
+/*
+ * Exported from dhd OS modules (dhd_linux/dhd_ndis)
+ */
+
+/* Indication from bus module regarding presence/insertion of dongle.
+ * Return dhd_pub_t pointer, used as handle to OS module in later calls.
+ * Returned structure should have bus and prot pointers filled in.
+ * bus_hdrlen specifies required headroom for bus module header.
+ */
+extern dhd_pub_t *dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen
+#ifdef BCMDBUS
+	, void *adapter
+#endif
+);
+extern int dhd_attach_net(dhd_pub_t *dhdp, bool need_rtnl_lock);
+#if defined(WLP2P) && defined(WL_CFG80211)
+/* To allow attach/detach calls corresponding to p2p0 interface  */
+extern int dhd_attach_p2p(dhd_pub_t *);
+extern int dhd_detach_p2p(dhd_pub_t *);
+#endif /* WLP2P && WL_CFG80211 */
+extern int dhd_register_if(dhd_pub_t *dhdp, int idx, bool need_rtnl_lock);
+
+/* Indication from bus module regarding removal/absence of dongle */
+extern void dhd_detach(dhd_pub_t *dhdp);
+extern void dhd_free(dhd_pub_t *dhdp);
+extern void dhd_clear(dhd_pub_t *dhdp);
+
+/* Indication from bus module to change flow-control state */
+extern void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool on);
+
+#ifdef BCMDONGLEHOST
+/* Store the status of a connection attempt for later retrieval by an iovar */
+extern void dhd_store_conn_status(uint32 event, uint32 status, uint32 reason);
+#endif /* BCMDONGLEHOST */
+
+extern bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec);
+
+extern void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *rxp, int numpkt, uint8 chan);
+
+/* Return pointer to interface name */
+extern char *dhd_ifname(dhd_pub_t *dhdp, int idx);
+
+#ifdef DHD_UCODE_DOWNLOAD
+/* Returns the ucode path */
+extern char *dhd_get_ucode_path(dhd_pub_t *dhdp);
+#endif /* DHD_UCODE_DOWNLOAD */
+
+/* Request scheduling of the bus dpc */
+extern void dhd_sched_dpc(dhd_pub_t *dhdp);
+
+/* Notify tx completion */
+extern void dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success);
+#ifdef DHD_4WAYM4_FAIL_DISCONNECT
+extern void dhd_eap_txcomplete(dhd_pub_t *dhdp, void *txp, bool success, int ifidx);
+extern void dhd_cleanup_m4_state_work(dhd_pub_t *dhdp, int ifidx);
+#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+extern void dhd_bus_wakeup_work(dhd_pub_t *dhdp);
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+#define WIFI_FEATURE_INFRA              0x0001      /* Basic infrastructure mode        */
+#define WIFI_FEATURE_INFRA_5G           0x0002      /* Support for 5 GHz Band           */
+#define WIFI_FEATURE_HOTSPOT            0x0004      /* Support for GAS/ANQP             */
+#define WIFI_FEATURE_P2P                0x0008      /* Wifi-Direct                      */
+#define WIFI_FEATURE_SOFT_AP            0x0010      /* Soft AP                          */
+#define WIFI_FEATURE_GSCAN              0x0020      /* Google-Scan APIs                 */
+#define WIFI_FEATURE_NAN                0x0040      /* Neighbor Awareness Networking    */
+#define WIFI_FEATURE_D2D_RTT            0x0080      /* Device-to-device RTT             */
+#define WIFI_FEATURE_D2AP_RTT           0x0100      /* Device-to-AP RTT                 */
+#define WIFI_FEATURE_BATCH_SCAN         0x0200      /* Batched Scan (legacy)            */
+#define WIFI_FEATURE_PNO                0x0400      /* Preferred network offload        */
+#define WIFI_FEATURE_ADDITIONAL_STA     0x0800      /* Support for two STAs             */
+#define WIFI_FEATURE_TDLS               0x1000      /* Tunnel directed link setup       */
+#define WIFI_FEATURE_TDLS_OFFCHANNEL    0x2000      /* Support for TDLS off channel     */
+#define WIFI_FEATURE_EPR                0x4000      /* Enhanced power reporting         */
+#define WIFI_FEATURE_AP_STA             0x8000      /* Support for AP STA Concurrency   */
+#define WIFI_FEATURE_LINKSTAT           0x10000     /* Support for Linkstats            */
+#define WIFI_FEATURE_LOGGER             0x20000     /* WiFi Logger			*/
+#define WIFI_FEATURE_HAL_EPNO           0x40000	    /* WiFi PNO enhanced                */
+#define WIFI_FEATURE_RSSI_MONITOR       0x80000     /* RSSI Monitor                     */
+#define WIFI_FEATURE_MKEEP_ALIVE        0x100000    /* WiFi mkeep_alive			*/
+#define WIFI_FEATURE_CONFIG_NDO         0x200000    /* ND offload configure             */
+#define WIFI_FEATURE_TX_TRANSMIT_POWER  0x400000    /* Capture Tx transmit power levels */
+#define WIFI_FEATURE_CONTROL_ROAMING    0x800000    /* Enable/Disable firmware roaming  */
+#define WIFI_FEATURE_FILTER_IE          0x1000000   /* Probe req ie filter              */
+#define WIFI_FEATURE_SCAN_RAND          0x2000000   /* MAC & Prb SN randomization       */
+#define WIFI_FEATURE_SET_TX_POWER_LIMIT 0x4000000   /* Support Tx Power Limit setting   */
+#define WIFI_FEATURE_USE_BODY_HEAD_SAR  0x8000000   /* Support Body/Head Proximity SAR  */
+#define WIFI_FEATURE_SET_LATENCY_MODE   0x40000000  /* Support Latency mode setting     */
+#define WIFI_FEATURE_P2P_RAND_MAC       0x80000000  /* Support P2P MAC randomization    */
+#define WIFI_FEATURE_INVALID            0xFFFFFFFF  /* Invalid Feature                  */
+
+#define MAX_FEATURE_SET_CONCURRRENT_GROUPS  3
+
+#if defined(linux) || defined(LINUX) || defined(OEM_ANDROID)
+extern int dhd_dev_indoor_cfg(struct net_device *dev, u8 enable);
+extern int dhd_dev_get_feature_set(struct net_device *dev);
+extern int dhd_dev_get_feature_set_matrix(struct net_device *dev, int num);
+extern int dhd_dev_cfg_rand_mac_oui(struct net_device *dev, uint8 *oui);
+extern int dhd_update_rand_mac_addr(dhd_pub_t *dhd);
+#ifdef CUSTOM_FORCE_NODFS_FLAG
+extern int dhd_dev_set_nodfs(struct net_device *dev, uint nodfs);
+#endif /* CUSTOM_FORCE_NODFS_FLAG */
+#ifdef NDO_CONFIG_SUPPORT
+#ifndef NDO_MAX_HOST_IP_ENTRIES
+#define NDO_MAX_HOST_IP_ENTRIES	10
+#endif /* NDO_MAX_HOST_IP_ENTRIES */
+
+extern int dhd_dev_ndo_cfg(struct net_device *dev, u8 enable);
+extern int dhd_dev_ndo_update_inet6addr(struct net_device * dev);
+#endif /* NDO_CONFIG_SUPPORT */
+#endif /* (linux) || (LINUX) || (OEM_ANDROID) */
+extern int dhd_set_rand_mac_oui(dhd_pub_t *dhd);
+#ifdef GSCAN_SUPPORT
+extern int dhd_dev_set_lazy_roam_cfg(struct net_device *dev,
+             wlc_roam_exp_params_t *roam_param);
+extern int dhd_dev_lazy_roam_enable(struct net_device *dev, uint32 enable);
+extern int dhd_dev_set_lazy_roam_bssid_pref(struct net_device *dev,
+       wl_bssid_pref_cfg_t *bssid_pref, uint32 flush);
+#endif /* GSCAN_SUPPORT */
+#if defined(GSCAN_SUPPORT) || defined(ROAMEXP_SUPPORT)
+extern int dhd_dev_set_blacklist_bssid(struct net_device *dev, maclist_t *blacklist,
+    uint32 len, uint32 flush);
+extern int dhd_dev_set_whitelist_ssid(struct net_device *dev, wl_ssid_whitelist_t *whitelist,
+    uint32 len, uint32 flush);
+#endif /* GSCAN_SUPPORT || ROAMEXP_SUPPORT */
+
+/* OS independent layer functions */
+extern void dhd_os_dhdiovar_lock(dhd_pub_t *pub);
+extern void dhd_os_dhdiovar_unlock(dhd_pub_t *pub);
+void dhd_os_logdump_lock(dhd_pub_t *pub);
+void dhd_os_logdump_unlock(dhd_pub_t *pub);
+extern int dhd_os_proto_block(dhd_pub_t * pub);
+extern int dhd_os_proto_unblock(dhd_pub_t * pub);
+extern int dhd_os_ioctl_resp_wait(dhd_pub_t * pub, uint * condition);
+extern int dhd_os_ioctl_resp_wake(dhd_pub_t * pub);
+extern unsigned int dhd_os_get_ioctl_resp_timeout(void);
+extern void dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec);
+extern void dhd_os_ioctl_resp_lock(dhd_pub_t * pub);
+extern void dhd_os_ioctl_resp_unlock(dhd_pub_t * pub);
+extern int dhd_os_read_file(void *file, char *buf, uint32 size);
+extern int dhd_os_seek_file(void *file, int64 offset);
+#ifdef PCIE_FULL_DONGLE
+extern void dhd_wakeup_ioctl_event(dhd_pub_t *pub, dhd_ioctl_recieved_status_t reason);
+#else
+static INLINE void dhd_wakeup_ioctl_event(dhd_pub_t *pub, dhd_ioctl_recieved_status_t reason)
+{ printf("%s is NOT implemented for SDIO", __FUNCTION__); return; }
+#endif
+#ifdef SHOW_LOGTRACE
+/* Bound and delay are fine tuned after several experiments and these
+ * are the best case values to handle bombarding of console logs.
+ */
+#define DHD_EVENT_LOGTRACE_BOUND 10u
+#define DHD_EVENT_LOGTRACE_RESCHEDULE_DELAY_MS 10u
+#endif /* SHOW_LOGTRACE */
+int dhd_os_write_file_posn(void *fp, unsigned long *posn,
+		void *buf, unsigned long buflen);
+int dhd_msix_message_set(dhd_pub_t *dhdp, uint table_entry,
+    uint message_number, bool unmask);
+
+#ifdef DHD_DEBUG
+void dhd_convert_memdump_type_to_str(uint32 type, char *buf, size_t buf_len, int substr_type);
+#endif /* DHD_DEBUG */
+
+#ifdef DHD_COREDUMP
+void dhd_convert_hang_reason_to_str(uint32 reason, char *buf, size_t buf_len);
+#endif /* DHD_COREDUMP */
+
+extern void
+dhd_pcie_dump_core_regs(dhd_pub_t * pub, uint32 index, uint32 first_addr, uint32 last_addr);
+extern void wl_dhdpcie_dump_regs(void * context);
+
+#define DHD_OS_IOCTL_RESP_LOCK(x)
+#define DHD_OS_IOCTL_RESP_UNLOCK(x)
+
+#if defined(NDIS)
+#define dhd_os_open_image(a) wl_os_open_image(a)
+#define dhd_os_close_image(a) wl_os_close_image(a)
+#define dhd_os_get_image_block(a, b, c) wl_os_get_image_block(a, b, c)
+#define dhd_os_get_image_size(a) wl_os_get_image_size(a)
+extern void dhd_os_wakeind(dhd_pub_t * pub, uint32 *val);
+extern void dhd_bus_check_died(void *bus);
+extern void pci_save_state(osl_t *osh, uint32 *buffer);
+extern void pci_restore_state(osl_t *osh, uint32 *buffer);
+#endif /* #if defined(NDIS) */
+
+extern int dhd_os_get_image_block(char * buf, int len, void * image);
+extern int dhd_os_get_image_size(void * image);
+#if defined(BT_OVER_SDIO)
+extern int dhd_os_gets_image(dhd_pub_t *pub, char *str, int len, void *image);
+extern void dhdsdio_bus_usr_cnt_inc(dhd_pub_t *pub);
+extern void dhdsdio_bus_usr_cnt_dec(dhd_pub_t *pub);
+#endif /* (BT_OVER_SDIO) */
+extern void *dhd_os_open_image1(dhd_pub_t *pub, char *filename); /* rev1 function signature */
+extern void dhd_os_close_image1(dhd_pub_t *pub, void *image);
+extern void dhd_os_wd_timer(void *bus, uint wdtick);
+extern void dhd_os_sdlock(dhd_pub_t * pub);
+extern void dhd_os_sdunlock(dhd_pub_t * pub);
+extern void dhd_os_sdlock_txq(dhd_pub_t * pub);
+extern void dhd_os_sdunlock_txq(dhd_pub_t * pub);
+extern unsigned long dhd_os_sdlock_txoff(dhd_pub_t * pub);
+extern void dhd_os_sdunlock_txoff(dhd_pub_t * pub, unsigned long flags);
+extern void dhd_os_sdlock_rxq(dhd_pub_t * pub);
+extern void dhd_os_sdunlock_rxq(dhd_pub_t * pub);
+extern void dhd_os_sdlock_sndup_rxq(dhd_pub_t * pub);
+extern void dhd_os_tracelog(const char *format, ...);
+#ifdef DHDTCPACK_SUPPRESS
+extern unsigned long dhd_os_tcpacklock(dhd_pub_t *pub);
+extern void dhd_os_tcpackunlock(dhd_pub_t *pub, unsigned long flags);
+#endif /* DHDTCPACK_SUPPRESS */
+
+extern int dhd_customer_oob_irq_map(void *adapter, unsigned long *irq_flags_ptr);
+extern int dhd_customer_gpio_wlan_ctrl(void *adapter, int onoff);
+extern int dhd_custom_get_mac_address(void *adapter, unsigned char *buf);
+#if defined(CUSTOM_COUNTRY_CODE)
+extern void get_customized_country_code(void *adapter, char *country_iso_code,
+	wl_country_t *cspec, u32 flags);
+#else
+extern void get_customized_country_code(void *adapter, char *country_iso_code, wl_country_t *cspec);
+#endif /* CUSTOM_COUNTRY_CODE */
+
+#ifdef SYNA_SAR_CUSTOMER_PARAMETER
+
+enum sar_para_mode {
+	SAR_OFF          = 0,
+	HEAD_NORMAL      = 1,
+	HEAD_AIRPLANE    = 2,
+	GRIP_NORMAL      = 3,
+	GRIP_AIRPLANE    = 4,
+	BT_NORMAL        = 5,
+	BT_AIRPLANE      = 6,
+	HOTSPOT_NORMAL   = 7,
+	HOTSPOT_AIRPLANE = 8
+};
+
+typedef enum _eCountry_type {
+	SYNA_COUNTRY_TYPE_DEFAULT,
+	SYNA_COUNTRY_TYPE_FCC,
+	SYNA_COUNTRY_TYPE_EU,
+	SYNA_COUNTRY_TYPE_LATAM,
+	SYNA_COUNTRY_TYPE_CANADA,
+	SYNA_COUNTRY_TYPE_JAPAN,
+	SYNA_COUNTRY_TYPE_QTY,
+	SYNA_COUNTRY_TYPE_INVALID = SYNA_COUNTRY_TYPE_QTY
+} eCountry_flag_type;
+
+/* SAR parameters from dhd */
+typedef struct _dhd_sar_parameter {
+	sarctrl_set  dynamic;
+	sarctrl_set  grip;
+	sarctrl_set  bt;
+	sarctrl_set  hotspot;
+} dhd_sar_parameter;
+
+extern eCountry_flag_type syna_country_check_type(char *cntry);
+extern int syna_country_update_type_list(eCountry_flag_type type, char *list_str);
+
+extern int dhd_sar_init_parameter(dhd_pub_t *dhd, eCountry_flag_type type, int advance_mode,
+	char *list_str);
+extern int dhd_sar_reset_parameter(void);
+extern int dhd_sar_set_parameter(dhd_pub_t *dhd_pub, int advance_mode);
+
+#endif /* SYNA_SAR_CUSTOMER_PARAMETER */
+
+extern void dhd_os_sdunlock_sndup_rxq(dhd_pub_t * pub);
+extern void dhd_os_sdlock_eventq(dhd_pub_t * pub);
+extern void dhd_os_sdunlock_eventq(dhd_pub_t * pub);
+extern bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret);
+extern int dhd_os_send_hang_message(dhd_pub_t *dhdp);
+extern void dhd_set_version_info(dhd_pub_t *pub, char *fw);
+extern bool dhd_os_check_if_up(dhd_pub_t *pub);
+extern int dhd_os_check_wakelock(dhd_pub_t *pub);
+extern int dhd_os_check_wakelock_all(dhd_pub_t *pub);
+extern int dhd_get_instance(dhd_pub_t *pub);
+#ifdef CUSTOM_SET_CPUCORE
+extern void dhd_set_cpucore(dhd_pub_t *dhd, int set);
+#endif /* CUSTOM_SET_CPUCORE */
+
+#ifdef DHD_DETECT_CONSECUTIVE_MFG_HANG
+#define MAX_CONSECUTIVE_MFG_HANG_COUNT 2
+#endif /* DHD_DETECT_CONSECUTIVE_MFG_HANG */
+
+#if defined(KEEP_ALIVE)
+extern int dhd_keep_alive_onoff(dhd_pub_t *dhd);
+#endif /* KEEP_ALIVE */
+
+#if defined(DHD_FW_COREDUMP)
+#ifdef LINUX
+extern bool dhd_memdump_is_scheduled(dhd_pub_t *dhdp);
+#else
+static INLINE bool dhd_memdump_is_scheduled(dhd_pub_t *dhdp) { return FALSE; }
+#endif /* LINUX */
+void dhd_schedule_memdump(dhd_pub_t *dhdp, uint8 *buf, uint32 size);
+#endif /* DHD_FW_COREDUMP */
+
+#if defined(linux) || defined(LINUX)
+#ifdef DHD_LINUX_STD_FW_API
+int dhd_os_get_img_fwreq(const struct firmware **fw, char *file_path);
+void dhd_os_close_img_fwreq(const struct firmware *fw);
+#endif /* DHD_LINUX_STD_FW_API */
+#if defined(DHD_SSSR_DUMP)
+void dhd_write_sssr_dump(dhd_pub_t *dhdp, uint32 dump_mode);
+#endif /* DHD_SSSR_DUMP */
+#ifdef DNGL_AXI_ERROR_LOGGING
+void dhd_schedule_axi_error_dump(dhd_pub_t *dhdp, void *type);
+#endif /* DNGL_AXI_ERROR_LOGGING */
+#ifdef BCMPCIE
+void dhd_schedule_cto_recovery(dhd_pub_t *dhdp);
+#endif /* BCMPCIE */
+#else
+#if defined(DHD_SSSR_DUMP)
+static INLINE void dhd_write_sssr_dump(dhd_pub_t *dhd, uint32 dump_mode) { return; }
+#endif /* DHD_SSSR_DUMP */
+#ifdef DNGL_AXI_ERROR_LOGGING
+static INLINE void dhd_schedule_axi_error_dump(dhd_pub_t *dhdp, void *type) { return; }
+#endif /* DNGL_AXI_ERROR_LOGGING */
+/* For non-linux map dhd_schedule_cto_recovery to dhdpcie_cto_recovery_handler */
+#ifdef BCMPCIE
+#define dhd_schedule_cto_recovery(dhdp) dhdpcie_cto_recovery_handler(dhdp)
+#endif /* BCMPCIE */
+#endif /* linux || LINUX */
+
+#ifdef EWP_EDL
+#define EDL_SCHEDULE_DELAY 500 /* 500ms */
+#if defined(linux) || defined(LINUX)
+void dhd_schedule_edl_work(dhd_pub_t *dhdp, uint delay_ms);
+#else
+static INLINE void dhd_schedule_edl_work(dhd_pub_t *dhd, uint delay_ms) { return; }
+#endif /* linux || LINUX */
+#endif /* EWP_EDL */
+
+#ifdef SUPPORT_AP_POWERSAVE
+extern int dhd_set_ap_powersave(dhd_pub_t *dhdp, int ifidx, int enable);
+#endif /* SUPPORT_AP_POWERSAVE */
+
+#ifdef PKT_FILTER_SUPPORT
+#define DHD_UNICAST_FILTER_NUM		0
+#define DHD_BROADCAST_FILTER_NUM	1
+#define DHD_MULTICAST4_FILTER_NUM	2
+#define DHD_MULTICAST6_FILTER_NUM	3
+#define DHD_MDNS_FILTER_NUM		4
+#define DHD_ARP_FILTER_NUM		5
+#define DHD_BROADCAST_ARP_FILTER_NUM	6
+#define DHD_IP4BCAST_DROP_FILTER_NUM	7
+#define DHD_LLC_STP_DROP_FILTER_NUM	8
+#define DHD_LLC_XID_DROP_FILTER_NUM	9
+#define DHD_UDPNETBIOS_DROP_FILTER_NUM	10
+#define DISCARD_IPV4_MCAST	"102 1 6 IP4_H:16 0xf0 0xe0"
+#define DISCARD_IPV6_MCAST	"103 1 6 IP6_H:24 0xff 0xff"
+#define DISCARD_IPV4_BCAST	"107 1 6 IP4_H:16 0xffffffff 0xffffffff"
+#define DISCARD_LLC_STP		"108 1 6 ETH_H:14 0xFFFFFFFFFFFF 0xAAAA0300000C"
+#define DISCARD_LLC_XID		"109 1 6 ETH_H:14 0xFFFFFF 0x0001AF"
+#define DISCARD_UDPNETBIOS	"110 1 6 UDP_H:2 0xffff 0x0089"
+extern int dhd_os_enable_packet_filter(dhd_pub_t *dhdp, int val);
+extern void dhd_enable_packet_filter(int value, dhd_pub_t *dhd);
+extern int dhd_packet_filter_add_remove(dhd_pub_t *dhdp, int add_remove, int num);
+extern int net_os_enable_packet_filter(struct net_device *dev, int val);
+extern int net_os_rxfilter_add_remove(struct net_device *dev, int val, int num);
+
+#define MAX_PKTFLT_BUF_SIZE		2048
+#define MAX_PKTFLT_FIXED_PATTERN_SIZE	32
+#define MAX_PKTFLT_FIXED_BUF_SIZE	\
+	(WL_PKT_FILTER_FIXED_LEN + MAX_PKTFLT_FIXED_PATTERN_SIZE * 2)
+#define MAXPKT_ARG	16
+#endif /* PKT_FILTER_SUPPORT */
+
+extern bool dhd_support_sta_mode(dhd_pub_t *dhd);
+extern int write_to_file(dhd_pub_t *dhd, uint8 *buf, int size);
+
+#ifdef RSSI_MONITOR_SUPPORT
+extern int dhd_dev_set_rssi_monitor_cfg(struct net_device *dev, int start,
+             int8 max_rssi, int8 min_rssi);
+#endif /* RSSI_MONITOR_SUPPORT */
+
+#ifdef DHDTCPACK_SUPPRESS
+int dhd_dev_set_tcpack_sup_mode_cfg(struct net_device *dev, uint8 enable);
+#endif /* DHDTCPACK_SUPPRESS */
+
+#define DHD_RSSI_MONITOR_EVT_VERSION   1
+typedef struct {
+	uint8 version;
+	int8 cur_rssi;
+	struct ether_addr BSSID;
+} dhd_rssi_monitor_evt_t;
+
+typedef struct {
+	uint32 limit;		/* Expiration time (usec) */
+	uint32 increment;	/* Current expiration increment (usec) */
+	uint32 elapsed;		/* Current elapsed time (usec) */
+	uint32 tick;		/* O/S tick time (usec) */
+} dhd_timeout_t;
+
+#ifdef SHOW_LOGTRACE
+typedef struct {
+	uint  num_fmts;
+	char **fmts;
+	char *raw_fmts;
+	char *raw_sstr;
+	uint32 fmts_size;
+	uint32 raw_fmts_size;
+	uint32 raw_sstr_size;
+	uint32 ramstart;
+	uint32 rodata_start;
+	uint32 rodata_end;
+	char *rom_raw_sstr;
+	uint32 rom_raw_sstr_size;
+	uint32 rom_ramstart;
+	uint32 rom_rodata_start;
+	uint32 rom_rodata_end;
+} dhd_event_log_t;
+#endif /* SHOW_LOGTRACE */
+
+#if defined(APF)
+/*
+ * As per Google's current implementation, there will be only one APF filter.
+ * Therefore, userspace doesn't bother about filter id and because of that
+ * DHD has to manage the filter id.
+ */
+#define PKT_FILTER_APF_ID		200
+#define DHD_APF_LOCK(ndev)		dhd_apf_lock(ndev)
+#define DHD_APF_UNLOCK(ndev)		dhd_apf_unlock(ndev)
+
+extern void dhd_apf_lock(struct net_device *dev);
+extern void dhd_apf_unlock(struct net_device *dev);
+extern int dhd_dev_apf_get_version(struct net_device *ndev, uint32 *version);
+extern int dhd_dev_apf_get_max_len(struct net_device *ndev, uint32 *max_len);
+extern int dhd_dev_apf_add_filter(struct net_device *ndev, u8* program, uint32 program_len);
+extern int dhd_dev_apf_enable_filter(struct net_device *ndev);
+extern int dhd_dev_apf_disable_filter(struct net_device *ndev);
+extern int dhd_dev_apf_delete_filter(struct net_device *ndev);
+extern int dhd_dev_apf_read_filter_data(struct net_device *ndev, u8* buf, uint32 buf_len);
+#endif /* APF */
+
+extern void dhd_timeout_start(dhd_timeout_t *tmo, uint usec);
+extern int dhd_timeout_expired(dhd_timeout_t *tmo);
+
+extern int dhd_ifname2idx(struct dhd_info *dhd, char *name);
+#ifdef LINUX
+extern int dhd_net2idx(struct dhd_info *dhd, struct net_device *net);
+extern struct net_device * dhd_idx2net(void *pub, int ifidx);
+extern int net_os_send_hang_message(struct net_device *dev);
+extern int net_os_send_hang_message_reason(struct net_device *dev, const char *string_num);
+#endif
+extern bool dhd_wowl_cap(void *bus);
+extern int wl_host_event(dhd_pub_t *dhd_pub, int *idx, void *pktdata, uint pktlen,
+	wl_event_msg_t *, void **data_ptr,  void *);
+extern int wl_process_host_event(dhd_pub_t *dhd_pub, int *idx, void *pktdata, uint pktlen,
+	wl_event_msg_t *, void **data_ptr,  void *);
+extern void wl_event_to_host_order(wl_event_msg_t * evt);
+extern int wl_host_event_get_data(void *pktdata, uint pktlen, bcm_event_msg_u_t *evu);
+extern int dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifindex, wl_ioctl_t *ioc, void *buf, int len);
+extern int dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int cmd, void *arg, int len, uint8 set,
+                            int ifindex);
+extern int dhd_wl_ioctl_get_intiovar(dhd_pub_t *dhd_pub, char *name, uint *pval,
+	int cmd, uint8 set, int ifidx);
+extern int dhd_wl_ioctl_set_intiovar(dhd_pub_t *dhd_pub, char *name, uint val,
+	int cmd, uint8 set, int ifidx);
+extern void dhd_common_init(osl_t *osh);
+
+#if defined(linux) || defined(LINUX) || defined(OEM_ANDROID)
+extern int dhd_do_driver_init(struct net_device *net);
+#endif
+extern int dhd_event_ifadd(struct dhd_info *dhd, struct wl_event_data_if *ifevent,
+	char *name, uint8 *mac);
+extern int dhd_event_ifdel(struct dhd_info *dhd, struct wl_event_data_if *ifevent,
+	char *name, uint8 *mac);
+extern int dhd_event_ifchange(struct dhd_info *dhd, struct wl_event_data_if *ifevent,
+       char *name, uint8 *mac);
+#ifdef DHD_UPDATE_INTF_MAC
+extern int dhd_op_if_update(dhd_pub_t *dhdpub, int ifidx);
+#endif /* DHD_UPDATE_INTF_MAC */
+extern struct net_device* dhd_allocate_if(dhd_pub_t *dhdpub, int ifidx, const char *name,
+	uint8 *mac, uint8 bssidx, bool need_rtnl_lock, const char *dngl_name);
+extern int dhd_remove_if(dhd_pub_t *dhdpub, int ifidx, bool need_rtnl_lock);
+#ifdef WL_STATIC_IF
+extern s32 dhd_update_iflist_info(dhd_pub_t *dhdp, struct net_device *ndev, int ifidx,
+	uint8 *mac, uint8 bssidx, const char *dngl_name, int if_state);
+#endif /* WL_STATIC_IF */
+extern void dhd_vif_add(struct dhd_info *dhd, int ifidx, char * name);
+extern void dhd_vif_del(struct dhd_info *dhd, int ifidx);
+extern void dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx);
+extern void dhd_vif_sendup(struct dhd_info *dhd, int ifidx, uchar *cp, int len);
+
+/* Send packet to dongle via data channel */
+extern int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pkt);
+
+/* send up locally generated event */
+extern void dhd_sendup_event_common(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data);
+/* Send event to host */
+extern void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data);
+#ifdef LOG_INTO_TCPDUMP
+extern void dhd_sendup_log(dhd_pub_t *dhdp, void *data, int len);
+#endif /* LOG_INTO_TCPDUMP */
+#if defined(SHOW_LOGTRACE) && defined(EWP_EDL)
+void dhd_sendup_info_buf(dhd_pub_t *dhdp, uint8 *msg);
+#endif
+#if defined(WIFI_TURNON_USE_HALINIT)
+extern int dhd_open(struct net_device *net);
+#endif /* WIFI_TURNON_USE_HALINIT */
+#if defined(LINUX) || defined(linux)
+extern int dhd_stop(struct net_device *net);
+#endif /* LINUX */
+extern int dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag);
+extern uint dhd_bus_status(dhd_pub_t *dhdp);
+extern int  dhd_bus_start(dhd_pub_t *dhdp);
+extern int dhd_bus_suspend(dhd_pub_t *dhdpub);
+extern int dhd_bus_resume(dhd_pub_t *dhdpub, int stage);
+extern int dhd_bus_membytes(dhd_pub_t *dhdp, bool set, uint32 address, uint8 *data, uint size);
+extern void dhd_print_buf(void *pbuf, int len, int bytes_per_line);
+extern bool dhd_is_associated(dhd_pub_t *dhd, uint8 ifidx, int *retval);
+#if defined(LINUX) || defined(linux)
+extern bool dhd_scan_associated(dhd_pub_t *dhd, struct net_device *dev);
+#endif /* LINUX */
+#if defined(BCMSDIO) || defined(BCMPCIE)
+extern uint dhd_bus_chip_id(dhd_pub_t *dhdp);
+extern uint dhd_bus_chiprev_id(dhd_pub_t *dhdp);
+extern uint dhd_bus_chippkg_id(dhd_pub_t *dhdp);
+#endif /* defined(BCMSDIO) || defined(BCMPCIE) */
+#if defined(LINUX) || defined(linux)
+int dhd_bus_get_fw_mode(dhd_pub_t *dhdp);
+#else
+static INLINE int dhd_bus_get_fw_mode(dhd_pub_t *dhdp) { return 0; }
+#endif /* LINUX || linux */
+
+#if defined(KEEP_ALIVE)
+extern int dhd_keep_alive_onoff(dhd_pub_t *dhd);
+#endif /* KEEP_ALIVE */
+
+/* linux is defined for DHD EFI builds also,
+* since its cross-compiled for EFI from linux.
+* dbgring_lock apis are meant only for linux
+* to use mutexes, other OSes will continue to
+* use osl_spin_lock
+*/
+#if (defined(LINUX) || defined(linux))
+void *dhd_os_dbgring_lock_init(osl_t *osh);
+void dhd_os_dbgring_lock_deinit(osl_t *osh, void *mtx);
+unsigned long dhd_os_dbgring_lock(void *lock);
+void dhd_os_dbgring_unlock(void *lock, unsigned long flags);
+#endif
+
+#ifdef PCIE_INB_DW
+static INLINE int dhd_os_ds_enter_wait(dhd_pub_t * pub, uint * condition)
+{ return 1; }
+static INLINE int dhd_os_ds_enter_wake(dhd_pub_t * pub)
+{ return 0; }
+#endif /* PCIE_INB_DW */
+
+#define FWBOOT_INTR_TIMEOUT_MS 5000u
+
+#if defined(LINUX) || defined(linux)
+extern int dhd_os_busbusy_wait_negation(dhd_pub_t * pub, uint * condition);
+extern int dhd_os_busbusy_wake(dhd_pub_t * pub);
+extern void dhd_os_tx_completion_wake(dhd_pub_t *dhd);
+extern int dhd_os_busbusy_wait_condition(dhd_pub_t *pub, uint *var, uint condition);
+extern int dhd_os_d3ack_wait(dhd_pub_t * pub, uint * condition);
+extern int dhd_os_d3ack_wake(dhd_pub_t * pub);
+extern int dhd_os_dmaxfer_wait(dhd_pub_t *pub, uint *condition);
+extern int dhd_os_dmaxfer_wake(dhd_pub_t *pub);
+int dhd_os_busbusy_wait_bitmask(dhd_pub_t *pub, uint *var,
+		uint bitmask, uint condition);
+#ifdef PCIE_INB_DW
+extern int dhd_os_ds_exit_wait(dhd_pub_t * pub, uint * condition);
+extern int dhd_os_ds_exit_wake(dhd_pub_t * pub);
+#endif /* PCIE_INB_DW */
+int dhd_os_tput_test_wait(dhd_pub_t *pub, uint *condition, uint timeout_ms);
+int dhd_os_tput_test_wake(dhd_pub_t * pub);
+#else
+static INLINE int dhd_os_tput_test_wait(dhd_pub_t *pub, uint *condition,
+		uint timeout_ms)
+{ return 0; }
+static INLINE int dhd_os_tput_test_wake(dhd_pub_t * pub)
+{ return 0; }
+static INLINE int dhd_os_d3ack_wait(dhd_pub_t * pub, uint * condition)
+{ return dhd_os_ioctl_resp_wait(pub, condition); }
+static INLINE int dhd_os_d3ack_wake(dhd_pub_t * pub)
+{ return dhd_os_ioctl_resp_wake(pub); }
+#ifdef PCIE_INB_DW
+static INLINE int dhd_os_ds_exit_wait(dhd_pub_t * pub, uint * condition)
+{ DHD_ERROR(("%s is Not supported for this platform", __FUNCTION__)); return 0; }
+static INLINE int dhd_os_ds_exit_wake(dhd_pub_t * pub)
+{ DHD_ERROR(("%s is Not supported for this platform", __FUNCTION__)); return 0; }
+#endif /* PCIE_INB_DW */
+static INLINE int dhd_os_busbusy_wait_negation(dhd_pub_t * pub, uint * condition)
+{ return 1; }
+static INLINE int dhd_os_busbusy_wake(dhd_pub_t * pub)
+{ return 0; }
+static INLINE int dhd_os_busbusy_wait_condition(dhd_pub_t *pub, uint *var, uint condition)
+{ return 0; }
+static INLINE int dhd_os_dmaxfer_wait(dhd_pub_t *pub, uint *condition)
+{ return 0; }
+static INLINE int dhd_os_dmaxfer_wake(dhd_pub_t *pub)
+{ return 0; }
+static INLINE int dhd_os_busbusy_wait_bitmask(dhd_pub_t *pub, uint *var,
+		uint bitmask, uint condition)
+{ return 0; }
+#endif /* LINUX || linux */
+
+#if defined(LINUX) || defined(linux)
+/*
+ * Manage sta objects in an interface. Interface is identified by an ifindex and
+ * sta(s) within an interfaces are managed using a MacAddress of the sta.
+ */
+struct dhd_sta;
+extern bool dhd_sta_associated(dhd_pub_t *dhdp, uint32 bssidx, uint8 *mac);
+extern struct dhd_sta *dhd_find_sta(void *pub, int ifidx, void *ea);
+extern struct dhd_sta *dhd_findadd_sta(void *pub, int ifidx, void *ea);
+extern void dhd_del_all_sta(void *pub, int ifidx);
+extern void dhd_del_sta(void *pub, int ifidx, void *ea);
+extern void dhd_update_sta_chanspec_info(void *pub, int ifidx, const uint8 *ea,
+	chanspec_t chanspec);
+extern bool dhd_is_sta_htput(void *pub, int ifidx, void *ea);
+extern int dhd_get_ap_isolate(dhd_pub_t *dhdp, uint32 idx);
+extern int dhd_set_ap_isolate(dhd_pub_t *dhdp, uint32 idx, int val);
+extern int dhd_bssidx2idx(dhd_pub_t *dhdp, uint32 bssidx);
+extern struct net_device *dhd_linux_get_primary_netdev(dhd_pub_t *dhdp);
+#else /* LINUX */
+static INLINE bool dhd_sta_associated(dhd_pub_t *dhdp, uint32 bssidx, uint8 *mac)
+{ return FALSE;}
+static INLINE void* dhd_find_sta(void *pub, int ifidx, void *ea) { return NULL;}
+static INLINE void *dhd_findadd_sta(void *pub, int ifidx, void *ea) { return NULL; }
+static INLINE void dhd_del_all_sta(void *pub, int ifidx) { }
+static INLINE void dhd_del_sta(void *pub, int ifidx, void *ea) { }
+static INLINE void dhd_update_sta_chanspec_info(void *pub, int ifidx, const uint8 *ea,
+	chanspec_t chanspec) {}
+static INLINE bool dhd_is_sta_htput(void *pub, int ifidx, void *ea) { return FALSE; }
+static INLINE int dhd_get_ap_isolate(dhd_pub_t *dhdp, uint32 idx) { return 0; }
+static INLINE int dhd_set_ap_isolate(dhd_pub_t *dhdp, uint32 idx, int val) { return 0; }
+static INLINE int dhd_bssidx2idx(dhd_pub_t *dhdp, uint32 bssidx) { return 0; }
+#endif /* LINUX */
+
+#if defined(DHD_FILE_DUMP_EVENT) && defined(DHD_FW_COREDUMP)
+dhd_dongledump_status_t dhd_get_dump_status(dhd_pub_t *pub);
+void dhd_set_dump_status(dhd_pub_t *pub, dhd_dongledump_status_t status);
+#endif /* DHD_FILE_DUMP_EVENT && DHD_FW_COREDUMP */
+
+extern bool dhd_is_concurrent_mode(dhd_pub_t *dhd);
+int dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *param_buf, uint param_len,
+		char *res_buf, uint res_len, bool set);
+extern int dhd_getiovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf,
+		uint cmd_len, char **resptr, uint resp_len);
+
+#ifdef DHD_MCAST_REGEN
+extern int dhd_get_mcast_regen_bss_enable(dhd_pub_t *dhdp, uint32 idx);
+extern int dhd_set_mcast_regen_bss_enable(dhd_pub_t *dhdp, uint32 idx, int val);
+#endif
+typedef enum cust_gpio_modes {
+	WLAN_RESET_ON,
+	WLAN_RESET_OFF,
+	WLAN_POWER_ON,
+	WLAN_POWER_OFF
+} cust_gpio_modes_t;
+
+typedef struct dmaxref_mem_map {
+	dhd_dma_buf_t *srcmem;
+	dhd_dma_buf_t *dstmem;
+} dmaxref_mem_map_t;
+
+#if defined(OEM_ANDROID)
+extern int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag);
+extern int wl_iw_send_priv_event(struct net_device *dev, char *flag);
+#endif /* defined(OEM_ANDROID) */
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+extern void dhd_flush_rx_tx_wq(dhd_pub_t *dhdp);
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+/*
+ * Insmod parameters for debug/test
+ */
+
+/* Watchdog timer interval */
+extern uint dhd_watchdog_ms;
+extern bool dhd_os_wd_timer_enabled(void *bus);
+
+/** Default console output poll interval */
+extern uint dhd_console_ms;
+
+extern uint android_msg_level;
+extern uint config_msg_level;
+extern uint sd_msglevel;
+extern uint dump_msg_level;
+#ifdef BCMDBUS
+extern uint dbus_msglevel;
+#endif /* BCMDBUS */
+#ifdef WL_WIRELESS_EXT
+extern uint iw_msg_level;
+#endif
+#ifdef WL_CFG80211
+extern uint wl_dbg_level;
+#endif
+
+extern uint dhd_slpauto;
+
+/* Use interrupts */
+extern uint dhd_intr;
+
+/* Use polling */
+extern uint dhd_poll;
+
+/* ARP offload agent mode */
+extern uint dhd_arp_mode;
+
+/* Pkt filte enable control */
+extern uint dhd_pkt_filter_enable;
+
+/*  Pkt filter init setup */
+extern uint dhd_pkt_filter_init;
+
+/* Pkt filter mode control */
+extern uint dhd_master_mode;
+
+/* Roaming mode control */
+extern uint dhd_roam_disable;
+
+/* Roaming mode control */
+extern uint dhd_radio_up;
+
+/* TCM verification control */
+extern uint dhd_tcm_test_enable;
+
+/* TCM test status */
+typedef enum tcm_test_status {
+	TCM_TEST_NOT_RUN = 0,
+	TCM_TEST_FAILED = 1,
+	TCM_TEST_PASSED = 2
+} tcm_test_status_t;
+extern tcm_test_status_t dhd_tcm_test_status;
+
+/* TCM test mode */
+typedef enum tcm_test_mode {
+	TCM_TEST_MODE_DISABLE = 0,
+	TCM_TEST_MODE_ONCE = 1,
+	TCM_TEST_MODE_ALWAYS = 2
+} tcm_test_mode_t;
+extern tcm_test_mode_t dhd_tcm_test_mode;
+
+/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */
+extern int dhd_idletime;
+#ifdef DHD_USE_IDLECOUNT
+#define DHD_IDLETIME_TICKS 5
+#else
+#define DHD_IDLETIME_TICKS 1
+#endif /* DHD_USE_IDLECOUNT */
+
+/* SDIO Drive Strength */
+extern uint dhd_sdiod_drive_strength;
+
+/* triggers bcm_bprintf to print to kernel log */
+extern bool bcm_bprintf_bypass;
+
+/* Override to force tx queueing all the time */
+extern uint dhd_force_tx_queueing;
+
+/* Default bcn_timeout value is 4 */
+#define DEFAULT_BCN_TIMEOUT_VALUE	4
+#ifndef CUSTOM_BCN_TIMEOUT_SETTING
+#define CUSTOM_BCN_TIMEOUT_SETTING	DEFAULT_BCN_TIMEOUT_VALUE
+#endif
+
+/* Default KEEP_ALIVE Period is 55 sec to prevent AP from sending Keep Alive probe frame */
+#define DEFAULT_KEEP_ALIVE_VALUE 	55000 /* msec */
+#ifndef CUSTOM_KEEP_ALIVE_SETTING
+#define CUSTOM_KEEP_ALIVE_SETTING 	DEFAULT_KEEP_ALIVE_VALUE
+#endif /* DEFAULT_KEEP_ALIVE_VALUE */
+
+#define NULL_PKT_STR	"null_pkt"
+
+/* hooks for custom glom setting option via Makefile */
+#define DEFAULT_GLOM_VALUE 	-1
+#ifndef CUSTOM_GLOM_SETTING
+#define CUSTOM_GLOM_SETTING 	DEFAULT_GLOM_VALUE
+#endif
+#define WL_AUTO_ROAM_TRIGGER -75
+/* hooks for custom Roaming Trigger  setting via Makefile */
+#define DEFAULT_ROAM_TRIGGER_VALUE -75 /* dBm default roam trigger all band */
+#define DEFAULT_ROAM_TRIGGER_SETTING 	-1
+#ifndef CUSTOM_ROAM_TRIGGER_SETTING
+#define CUSTOM_ROAM_TRIGGER_SETTING 	DEFAULT_ROAM_TRIGGER_VALUE
+#endif
+
+/* hooks for custom Roaming Romaing  setting via Makefile */
+#define DEFAULT_ROAM_DELTA_VALUE  10 /* dBm default roam delta all band */
+#define DEFAULT_ROAM_DELTA_SETTING 	-1
+#ifndef CUSTOM_ROAM_DELTA_SETTING
+#define CUSTOM_ROAM_DELTA_SETTING 	DEFAULT_ROAM_DELTA_VALUE
+#endif
+
+/* hooks for custom PNO Event wake lock to guarantee enough time
+	for the Platform to detect Event before system suspended
+*/
+#define DEFAULT_PNO_EVENT_LOCK_xTIME 	2 	/* multiplay of DHD_PACKET_TIMEOUT_MS */
+#ifndef CUSTOM_PNO_EVENT_LOCK_xTIME
+#define CUSTOM_PNO_EVENT_LOCK_xTIME	 DEFAULT_PNO_EVENT_LOCK_xTIME
+#endif
+/* hooks for custom dhd_dpc_prio setting option via Makefile */
+#define DEFAULT_DHP_DPC_PRIO  1
+#ifndef CUSTOM_DPC_PRIO_SETTING
+#define CUSTOM_DPC_PRIO_SETTING 	DEFAULT_DHP_DPC_PRIO
+#endif
+
+#ifndef CUSTOM_LISTEN_INTERVAL
+#define CUSTOM_LISTEN_INTERVAL 		LISTEN_INTERVAL
+#endif /* CUSTOM_LISTEN_INTERVAL */
+
+#define DEFAULT_SUSPEND_BCN_LI_DTIM		3
+#ifndef CUSTOM_SUSPEND_BCN_LI_DTIM
+#define CUSTOM_SUSPEND_BCN_LI_DTIM		DEFAULT_SUSPEND_BCN_LI_DTIM
+#endif
+
+#ifdef OEM_ANDROID
+#ifndef BCN_TIMEOUT_IN_SUSPEND
+#define BCN_TIMEOUT_IN_SUSPEND			6 /* bcn timeout value in suspend mode */
+#endif
+#endif /* OEM_ANDROID */
+
+#ifndef CUSTOM_RXF_PRIO_SETTING
+#define CUSTOM_RXF_PRIO_SETTING		MAX((CUSTOM_DPC_PRIO_SETTING - 1), 1)
+#endif
+
+#define DEFAULT_WIFI_TURNOFF_DELAY		10
+#ifndef WIFI_TURNOFF_DELAY
+#define WIFI_TURNOFF_DELAY		DEFAULT_WIFI_TURNOFF_DELAY
+#endif /* WIFI_TURNOFF_DELAY */
+
+#define DEFAULT_WIFI_TURNON_DELAY		200
+#ifndef WIFI_TURNON_DELAY
+#define WIFI_TURNON_DELAY		DEFAULT_WIFI_TURNON_DELAY
+#endif /* WIFI_TURNON_DELAY */
+
+#ifdef BCMSDIO
+#define DEFAULT_DHD_WATCHDOG_INTERVAL_MS	10 /* msec */
+#else
+#define DEFAULT_DHD_WATCHDOG_INTERVAL_MS	0 /* msec */
+#endif
+#ifndef CUSTOM_DHD_WATCHDOG_MS
+#define CUSTOM_DHD_WATCHDOG_MS			DEFAULT_DHD_WATCHDOG_INTERVAL_MS
+#endif /* DEFAULT_DHD_WATCHDOG_INTERVAL_MS */
+
+#if defined(DHD_DEBUG)
+#ifdef OEM_ANDROID
+#define DEFAULT_DHD_CONSOLE_INTERVAL_MS		0 /* android by default disable console msgs */
+#else
+#define DEFAULT_DHD_CONSOLE_INTERVAL_MS		250 /* msec */
+#endif /* OEM_ANDROID */
+
+#ifndef CUSTOM_DHD_CONSOLE_MS
+#define CUSTOM_DHD_CONSOLE_MS			DEFAULT_DHD_CONSOLE_INTERVAL_MS
+#endif /* DEFAULT_DHD_WATCHDOG_INTERVAL_MS */
+#endif /* DHD_DEBUG */
+
+#define	DHD_INB_DW_DEASSERT_MS			250
+
+#define DEFAULT_ASSOC_RETRY_MAX			3
+#ifndef CUSTOM_ASSOC_RETRY_MAX
+#define CUSTOM_ASSOC_RETRY_MAX			DEFAULT_ASSOC_RETRY_MAX
+#endif /* DEFAULT_ASSOC_RETRY_MAX */
+
+#if defined(DISABLE_FRAMEBURST)
+#define DEFAULT_FRAMEBURST_SET			0
+#else
+#define DEFAULT_FRAMEBURST_SET			1
+#endif /* BCMSDIO */
+
+#ifndef CUSTOM_FRAMEBURST_SET
+#define CUSTOM_FRAMEBURST_SET			DEFAULT_FRAMEBURST_SET
+#endif /* CUSTOM_FRAMEBURST_SET */
+
+#ifdef WLTDLS
+#ifndef CUSTOM_TDLS_IDLE_MODE_SETTING
+#define CUSTOM_TDLS_IDLE_MODE_SETTING  60000 /* 60sec to tear down TDLS of not active */
+#endif
+#ifndef CUSTOM_TDLS_RSSI_THRESHOLD_HIGH
+#define CUSTOM_TDLS_RSSI_THRESHOLD_HIGH -70 /* rssi threshold for establishing TDLS link */
+#endif
+#ifndef CUSTOM_TDLS_RSSI_THRESHOLD_LOW
+#define CUSTOM_TDLS_RSSI_THRESHOLD_LOW -80 /* rssi threshold for tearing down TDLS link */
+#endif
+#ifndef CUSTOM_TDLS_PCKTCNT_THRESHOLD_HIGH
+#define CUSTOM_TDLS_PCKTCNT_THRESHOLD_HIGH 100 /* pkt/sec threshold for establishing TDLS link */
+#endif
+#ifndef CUSTOM_TDLS_PCKTCNT_THRESHOLD_LOW
+#define CUSTOM_TDLS_PCKTCNT_THRESHOLD_LOW 10 /* pkt/sec threshold for tearing down TDLS link */
+#endif
+#endif /* WLTDLS */
+
+#if defined(VSDB) || defined(ROAM_ENABLE)
+#define DEFAULT_BCN_TIMEOUT            6
+#else
+#define DEFAULT_BCN_TIMEOUT            4
+#endif
+
+#ifndef CUSTOM_BCN_TIMEOUT
+#define CUSTOM_BCN_TIMEOUT             DEFAULT_BCN_TIMEOUT
+#endif
+
+#define DEFAULT_BCN_TIMEOUT_IN_SUSPEND	10
+#ifndef CUSTOM_BCN_TIMEOUT_IN_SUSPEND
+#define CUSTOM_BCN_TIMEOUT_IN_SUSPEND	DEFAULT_BCN_TIMEOUT_IN_SUSPEND
+#endif /* CUSTOM_BCN_TIMEOUT_IN_SUSPEND */
+
+#define MAX_DTIM_SKIP_BEACON_INTERVAL	100 /* max allowed associated AP beacon for DTIM skip */
+#ifndef MAX_DTIM_ALLOWED_INTERVAL
+#define MAX_DTIM_ALLOWED_INTERVAL 600 /* max allowed total beacon interval for DTIM skip */
+#endif
+
+#ifdef OEM_ANDROID
+#ifndef MIN_DTIM_FOR_ROAM_THRES_EXTEND
+#define MIN_DTIM_FOR_ROAM_THRES_EXTEND	600 /* minimum dtim interval to extend roam threshold */
+#endif
+#endif /* OEM_ANDROID */
+
+#ifdef CONFIG_ROAM_RSSI_LIMIT
+extern int dhd_roam_rssi_limit_get(dhd_pub_t *dhd, int *lmt2g, int *lmt5g);
+extern int dhd_roam_rssi_limit_set(dhd_pub_t *dhd, int lmt2g, int lmt5g);
+#ifndef CUSTOM_ROAMRSSI_2G
+#define CUSTOM_ROAMRSSI_2G		ROAMRSSI_2G_DEFAULT
+#endif /* CUSTOM_ROAMRSSI_2G */
+#ifndef CUSTOM_ROAMRSSI_5G
+#define CUSTOM_ROAMRSSI_5G		ROAMRSSI_5G_DEFAULT
+#endif /* CUSTOM_ROAMRSSI_5G */
+#endif /* CONFIG_ROAM_RSSI_LIMIT */
+#ifdef CONFIG_ROAM_MIN_DELTA
+extern int dhd_roam_min_delta_get(dhd_pub_t *dhd, uint32 *dt2g, uint32 *dt5g);
+extern int dhd_roam_min_delta_set(dhd_pub_t *dhd, uint32 dt2g, uint32 dt5g);
+#ifndef CUSTOM_ROAM_MIN_DELTA
+#define CUSTOM_ROAM_MIN_DELTA		ROAM_MIN_DELTA_DEFAULT
+#endif /* CUSTOM_ROAM_MIN_DELTA */
+#endif /* CONFIG_ROAM_MIN_DELTA */
+
+#define NO_DTIM_SKIP 1
+#ifdef SDTEST
+/* Echo packet generator (SDIO), pkts/s */
+extern uint dhd_pktgen;
+
+/* Echo packet len (0 => sawtooth, max 1800) */
+extern uint dhd_pktgen_len;
+#define MAX_PKTGEN_LEN 1800
+#endif
+
+#ifdef BCMSLTGT
+/* Account for slow hardware (QT) */
+extern uint htclkratio;
+extern int dngl_xtalfreq;
+#endif
+
+/* optionally set by a module_param_string() */
+#define MOD_PARAM_PATHLEN	2048
+#define MOD_PARAM_INFOLEN	512
+#define MOD_PARAM_SRLEN		64
+
+#ifdef SOFTAP
+extern char fw_path2[MOD_PARAM_PATHLEN];
+#endif
+
+#if defined(SUPPORT_MULTIPLE_NVRAM) || defined(SUPPORT_MULTIPLE_CLMBLOB)
+#define MAX_HW_INFO_LEN   10u
+#define MAX_HW_EXT_LEN    (MAX_HW_INFO_LEN * 2)
+#define MAX_FILE_COUNT    8u
+#define MAX_FILE_LEN      90u
+#endif /* SUPPORT_MULTIPLE_NVRAM || SUPPORT_MULTIPLE_CLMBLOB */
+
+#ifndef VENDOR_PATH
+#if defined(CUSTOMER_HW4) && !defined(DHD_LINUX_STD_FW_API)
+#define VENDOR_PATH "/vendor/firmware/"
+#else /* CUSTOMER_HW4 */
+#define VENDOR_PATH ""
+#endif /* CUSTOMER_HW4 */
+#endif /* VENDOR_PATH */
+
+/* Platform path Name -
+ * Used to find out where to find the FW debug support files.
+ * 1) If the Platform Makefile mentions from where it should be
+ *    picked from use it.
+ * 2) If Platform Makefile does not mention anything,use the
+ *    scheme as mapped below
+ */
+#if !defined(PLATFORM_PATH)
+/* First Overrides */
+#if defined(DHD_LEGACY_FILE_PATH)
+/* If Legacy file path is to be used */
+#define PLATFORM_PATH	"/data/"
+#elif defined(PLATFORM_SLP)
+/* Path Name for SLP */
+#define PLATFORM_PATH	"/opt/etc/"
+#else
+/* End of Overrides, rely on what is dictated by Android */
+#if defined(CUSTOMER_HW4)
+#define PLATFORM_PATH	"/data/vendor/conn/"
+#else
+#define PLATFORM_PATH	"/data/misc/conn/"
+#endif /* CUSTOMER_HW4  */
+#define DHD_MAC_ADDR_EXPORT
+#define DHD_ADPS_BAM_EXPORT
+#define DHD_EXPORT_CNTL_FILE
+#define DHD_SOFTAP_DUAL_IF_INFO
+#define DHD_SEND_HANG_PRIVCMD_ERRORS
+#endif /* DHD_LEGACY_FILE_PATH */
+#endif /* !PLATFORM_PATH */
+
+#if defined(DHD_MAC_ADDR_EXPORT) || defined(DHD_MAC_ADDR_EXPORT_RO)
+extern struct ether_addr sysfs_mac_addr;
+#endif /* DHD_MAC_ADDR_EXPORT || DHD_MAC_ADDR_EXPORT_RO */
+
+#if defined(LINUX) || defined(linux)
+/* Flag to indicate if we should download firmware on driver load */
+extern uint dhd_download_fw_on_driverload;
+#ifndef BCMDBUS
+extern int allow_delay_fwdl;
+#endif /* !BCMDBUS */
+
+extern int dhd_process_cid_mac(dhd_pub_t *dhdp, bool prepost);
+extern int dhd_write_file(const char *filepath, char *buf, int buf_len);
+extern int dhd_read_file(const char *filepath, char *buf, int buf_len);
+extern int dhd_write_file_and_check(const char *filepath, char *buf, int buf_len);
+extern int dhd_file_delete(char *path);
+
+#ifdef READ_MACADDR
+extern int dhd_read_macaddr_from_file(dhd_pub_t *dhdp, struct ether_addr *dest_mac);
+extern int dhd_set_macaddr_from_file(dhd_pub_t *dhdp);
+#else
+static inline int dhd_read_macaddr_from_file(dhd_pub_t *dhdp,
+	struct ether_addr *dest_mac) { return 0; }
+static INLINE int dhd_set_macaddr_from_file(dhd_pub_t *dhdp) { return 0; }
+#endif /* READ_MACADDR */
+#ifdef WRITE_MACADDR
+extern int dhd_write_macaddr(struct ether_addr *mac);
+#else
+static INLINE int dhd_write_macaddr(struct ether_addr *mac) { return 0; }
+#endif /* WRITE_MACADDR */
+
+#if defined(USE_CID_CHECK) || defined(USE_DIRECT_VID_TAG)
+#if defined(BCM4361_CHIP) || defined(BCM4375_CHIP) || defined(BCM4389_CHIP_DEF)
+#define DHD_USE_CISINFO_FROM_OTP
+/* For COB, can't check CID/MAC in OTP, so, define it here */
+#define DHD_READ_CIS_FROM_BP
+#endif /* CONFIG_BCM4361 || CONFIG_BCM4375 || CONFIG_BCM4389_DEF */
+#define MAX_VNAME_LEN		64
+#define MAX_VID_LEN		8
+#define MODULE_NAME_INDEX_MAX	3
+#define MAX_EXTENSION 20
+typedef struct {
+	char cid_ext[MAX_EXTENSION];
+	char nvram_ext[MAX_EXTENSION];
+	char fw_ext[MAX_EXTENSION];
+} naming_info_t;
+extern uint32 cur_vid_info;
+#ifdef DHD_EXPORT_CNTL_FILE
+extern char cidinfostr[MAX_VNAME_LEN];
+#endif /* DHD_EXPORT_CNTL_FILE */
+extern int dhd_check_module_cid(dhd_pub_t *dhdp);
+#else
+static INLINE int dhd_check_module_cid(dhd_pub_t *dhdp) { return 0; }
+#endif /* USE_CID_CHECK || USE_DIRECT_VID_TAG */
+#ifdef USE_CID_CHECK
+extern char *dhd_get_cid_info(unsigned char *vid, int vid_length);
+#endif /* USE_CID_CHECK */
+#ifdef GET_MAC_FROM_OTP
+extern int dhd_check_module_mac(dhd_pub_t *dhdp);
+#else
+static INLINE int dhd_check_module_mac(dhd_pub_t *dhdp) { return 0; }
+#endif /* GET_MAC_FROM_OTP */
+
+#if defined(READ_MACADDR) || defined(WRITE_MACADDR) || defined(USE_CID_CHECK) || \
+	defined(GET_MAC_FROM_OTP)
+#define DHD_USE_CISINFO
+#endif /* READ_MACADDR || WRITE_MACADDR || USE_CID_CHECK || GET_MAC_FROM_OTP */
+
+#ifdef DHD_USE_CISINFO
+int dhd_read_cis(dhd_pub_t *dhdp);
+int dhd_read_otp_sw_rgn(dhd_pub_t *dhdp);
+void dhd_clear_cis(dhd_pub_t *dhdp);
+int dhd_alloc_cis(dhd_pub_t *dhdp);
+#if defined(SUPPORT_MULTIPLE_MODULE_CIS) && defined(USE_CID_CHECK)
+extern int dhd_check_module_b85a(void);
+extern int dhd_check_module_b90(void);
+#define BCM4359_MODULE_TYPE_B90B 1
+#define BCM4359_MODULE_TYPE_B90S 2
+#endif /* defined(SUPPORT_MULTIPLE_MODULE_CIS) && defined(USE_CID_CHECK) */
+#if defined(USE_CID_CHECK)
+extern int dhd_check_module_bcm(char *module_type, int index, bool *is_murata_fem);
+extern naming_info_t *
+dhd_find_naming_info(dhd_pub_t *dhdp, char *module_type);
+extern naming_info_t * dhd_find_naming_info_by_chip_rev(dhd_pub_t *dhdp, bool *is_murata_fem);
+#endif /* defined(USE_CID_CHECK) */
+#ifdef USE_DIRECT_VID_TAG
+#define VENDOR_OFF 1
+#define MD_REV_OFF 0
+#define A0_REV "_a0"
+#define B0_REV "_b0"
+#define C0_REV "_c0"
+#define C1_REV "_c1"
+extern int dhd_check_stored_module_info(char *vid);
+extern int concate_nvram_by_vid(dhd_pub_t *dhdp, char *nv_path, char *chipstr);
+#endif /* USE_DIRECT_VID_TAG */
+#if defined(USE_CID_CHECK) && defined(USE_DIRECT_VID_TAG)
+#error Please use USE_CID_CHECK/USE_DIRECT_VID_TAG exclusively
+#endif /* USE_CID_CHECK && USE_DIRECT_VID_TAG */
+#else
+static INLINE int dhd_read_cis(dhd_pub_t *dhdp) { return 0; }
+static INLINE int dhd_read_otp_sw_rgn(dhd_pub_t *dhdp) { return 0; }
+static INLINE void dhd_clear_cis(dhd_pub_t *dhdp) { }
+static INLINE int dhd_alloc_cis(dhd_pub_t *dhdp) { return 0; }
+#endif /* DHD_USE_CISINFO */
+
+#else /* LINUX || linux */
+static INLINE int dhd_process_cid_mac(dhd_pub_t *dhdp, bool prepost) { return 0; }
+#endif /* LINUX || linux */
+
+#if defined(WL_CFG80211) && defined(SUPPORT_DEEP_SLEEP)
+/* Flags to indicate if we distingish power off policy when
+ * user set the memu "Keep Wi-Fi on during sleep" to "Never"
+ */
+extern int trigger_deep_sleep;
+int dhd_deepsleep(struct net_device *dev, int flag);
+#endif /* WL_CFG80211 && SUPPORT_DEEP_SLEEP */
+
+extern void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar);
+extern void dhd_wait_event_wakeup(dhd_pub_t*dhd);
+
+#define IFLOCK_INIT(lock)       *lock = 0
+#define IFLOCK(lock)    while (InterlockedCompareExchange((lock), 1, 0))	\
+	NdisStallExecution(1);
+#define IFUNLOCK(lock)  InterlockedExchange((lock), 0)
+#define IFLOCK_FREE(lock)
+#define FW_SUPPORTED(dhd, capa) ((strstr(dhd->fw_capabilities, " " #capa " ") != NULL))
+#ifdef ARP_OFFLOAD_SUPPORT
+#define MAX_IPV4_ENTRIES	8
+void dhd_arp_offload_set(dhd_pub_t * dhd, int arp_mode);
+void dhd_arp_offload_enable(dhd_pub_t * dhd, int arp_enable);
+
+/* dhd_commn arp offload wrapers */
+void dhd_aoe_hostip_clr(dhd_pub_t *dhd, int idx);
+void dhd_aoe_arp_clr(dhd_pub_t *dhd, int idx);
+int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen, int idx);
+void dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr, int idx);
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+#ifdef WLTDLS
+int dhd_tdls_enable(struct net_device *dev, bool tdls_on, bool auto_on, struct ether_addr *mac);
+int dhd_tdls_set_mode(dhd_pub_t *dhd, bool wfd_mode);
+#ifdef PCIE_FULL_DONGLE
+int dhd_tdls_update_peer_info(dhd_pub_t *dhdp, wl_event_msg_t *event);
+int dhd_tdls_event_handler(dhd_pub_t *dhd_pub, wl_event_msg_t *event);
+int dhd_free_tdls_peer_list(dhd_pub_t *dhd_pub);
+#endif /* PCIE_FULL_DONGLE */
+#endif /* WLTDLS */
+
+/* Neighbor Discovery Offload Support */
+extern int dhd_ndo_enable(dhd_pub_t * dhd, int ndo_enable);
+int dhd_ndo_add_ip(dhd_pub_t *dhd, char* ipaddr, int idx);
+int dhd_ndo_remove_ip(dhd_pub_t *dhd, int idx);
+
+/* Enhanced ND offload support */
+uint16 dhd_ndo_get_version(dhd_pub_t *dhdp);
+int dhd_ndo_add_ip_with_type(dhd_pub_t *dhdp, char *ipv6addr, uint8 type, int idx);
+int dhd_ndo_remove_ip_by_addr(dhd_pub_t *dhdp, char *ipv6addr, int idx);
+int dhd_ndo_remove_ip_by_type(dhd_pub_t *dhdp, uint8 type, int idx);
+int dhd_ndo_unsolicited_na_filter_enable(dhd_pub_t *dhdp, int enable);
+
+/* ioctl processing for nl80211 */
+int dhd_ioctl_process(dhd_pub_t *pub, int ifidx, struct dhd_ioctl *ioc, void *data_buf);
+
+#if defined(SUPPORT_MULTIPLE_REVISION)
+extern int
+concate_revision(struct dhd_bus *bus, char *fwpath, char *nvpath);
+#endif /* SUPPORT_MULTIPLE_REVISION */
+void dhd_bus_update_fw_nv_path(struct dhd_bus *bus, char *pfw_path, char *pnv_path,
+											char *pclm_path, char *pconf_path);
+void dhd_set_bus_state(void *bus, uint32 state);
+
+/* Remove proper pkts(either one no-frag pkt or whole fragmented pkts) */
+typedef int (*f_droppkt_t)(dhd_pub_t *dhdp, int prec, void* p, bool bPktInQ);
+extern bool dhd_prec_drop_pkts(dhd_pub_t *dhdp, struct pktq *pq, int prec, f_droppkt_t fn);
+
+extern const uint8 wme_fifo2ac[];
+extern const uint8 prio2fifo[];
+#ifdef PROP_TXSTATUS
+int dhd_os_wlfc_block(dhd_pub_t *pub);
+int dhd_os_wlfc_unblock(dhd_pub_t *pub);
+#endif /* PROP_TXSTATUS */
+
+int dhd_os_socram_dump(struct net_device *dev, uint32 *dump_size);
+int dhd_os_get_socram_dump(struct net_device *dev, char **buf, uint32 *size);
+int dhd_common_socram_dump(dhd_pub_t *dhdp);
+
+int dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen);
+int dhd_counters(dhd_pub_t *dhdp, char *buf, int buflen);
+
+int dhd_os_get_version(struct net_device *dev, bool dhd_ver, char **buf, uint32 size);
+void dhd_get_memdump_filename(struct net_device *ndev, char *memdump_path, int len, char *fname);
+uint8* dhd_os_prealloc(dhd_pub_t *dhdpub, int section, uint size, bool kmalloc_if_fail);
+void dhd_os_prefree(dhd_pub_t *dhdpub, void *addr, uint size);
+
+#if defined(CONFIG_DHD_USE_STATIC_BUF)
+#define DHD_OS_PREALLOC(dhdpub, section, size) dhd_os_prealloc(dhdpub, section, size, FALSE)
+#define DHD_OS_PREFREE(dhdpub, addr, size) dhd_os_prefree(dhdpub, addr, size)
+#else
+#define DHD_OS_PREALLOC(dhdpub, section, size) MALLOC(dhdpub->osh, size)
+#define DHD_OS_PREFREE(dhdpub, addr, size) MFREE(dhdpub->osh, addr, size)
+#endif /* defined(CONFIG_DHD_USE_STATIC_BUF) */
+
+#ifdef USE_WFA_CERT_CONF
+enum {
+	SET_PARAM_BUS_TXGLOM_MODE,
+	SET_PARAM_ROAMOFF,
+#ifdef USE_WL_FRAMEBURST
+	SET_PARAM_FRAMEBURST,
+#endif /* USE_WL_FRAMEBURST */
+#ifdef USE_WL_TXBF
+	SET_PARAM_TXBF,
+#endif /* USE_WL_TXBF */
+#ifdef PROP_TXSTATUS
+	SET_PARAM_PROPTX,
+	SET_PARAM_PROPTXMODE,
+#endif /* PROP_TXSTATUS */
+	PARAM_LAST_VALUE
+};
+extern int sec_get_param_wfa_cert(dhd_pub_t *dhd, int mode, uint* read_val);
+#ifdef DHD_EXPORT_CNTL_FILE
+#define VALUENOTSET 0xFFFFFFFFu
+extern uint32 bus_txglom;
+extern uint32 roam_off;
+#ifdef USE_WL_FRAMEBURST
+extern uint32 frameburst;
+#endif /* USE_WL_FRAMEBURST */
+#ifdef USE_WL_TXBF
+extern uint32 txbf;
+#endif /* USE_WL_TXBF */
+#ifdef PROP_TXSTATUS
+extern uint32 proptx;
+#endif /* PROP_TXSTATUS */
+#endif /* DHD_EXPORT_CNTL_FILE */
+#endif /* USE_WFA_CERT_CONF */
+
+#if defined(BCM_ROUTER_DHD)
+#if defined(HNDCTF)
+bool dhd_ctf_hotbrc_check(dhd_pub_t *dhdp, uint8 *eh, int ifidx);
+void dhd_ctf_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
+bool dhd_l2_filter_chainable(dhd_pub_t *dhdp, uint8 *eh, int ifidx);
+bool dhd_wet_chainable(dhd_pub_t *dhdap);
+bool dhd_rx_pkt_chainable(dhd_pub_t *dhdp, int ifidx);
+#endif /* HNDCTF */
+extern void dhd_schedule_trap_log_dump(dhd_pub_t *dhdp,
+	uint8 *buf, uint32 size);
+/* When a new flowid is allocated/deallocated, inform dhd. */
+extern void dhd_add_flowid(dhd_pub_t * dhdp, int ifidx,
+                          uint8 ac_prio, void * ea, uint16 flowid);
+extern void dhd_del_flowid(dhd_pub_t * dhdp, int ifidx, uint16 flowid);
+#else  /* ! BCM_ROUTER_DHD */
+#define dhd_add_flowid(pub, ifidx, ac_prio, ea, flowid)  do {} while (0)
+#define dhd_del_flowid(pub, ifidx, flowid)               do {} while (0)
+bool dhd_wet_chainable(dhd_pub_t *dhdp);
+#endif /* ! BCM_ROUTER_DHD */
+
+extern unsigned long dhd_os_general_spin_lock(dhd_pub_t *pub);
+extern void dhd_os_general_spin_unlock(dhd_pub_t *pub, unsigned long flags);
+
+/** Miscellaenous DHD Spin Locks */
+
+/* Enable DHD general spin lock/unlock */
+#define DHD_GENERAL_LOCK(dhdp, flags) \
+	(flags) = dhd_os_general_spin_lock(dhdp)
+#define DHD_GENERAL_UNLOCK(dhdp, flags) \
+	dhd_os_general_spin_unlock((dhdp), (flags))
+
+/* Enable DHD timer spin lock/unlock */
+#define DHD_TIMER_LOCK(lock, flags)     (flags) = osl_spin_lock(lock)
+#define DHD_TIMER_UNLOCK(lock, flags)   osl_spin_unlock(lock, (flags))
+
+/* Enable DHD flowring spin lock/unlock */
+#define DHD_FLOWRING_LOCK(lock, flags)     (flags) = osl_spin_lock(lock)
+#define DHD_FLOWRING_UNLOCK(lock, flags)   osl_spin_unlock((lock), (flags))
+
+/* Enable DHD common flowring info spin lock/unlock */
+#define DHD_FLOWID_LOCK(lock, flags)       (flags) = osl_spin_lock(lock)
+#define DHD_FLOWID_UNLOCK(lock, flags)     osl_spin_unlock((lock), (flags))
+
+/* Enable DHD common flowring list spin lock/unlock */
+#define DHD_FLOWRING_LIST_LOCK(lock, flags)       (flags) = osl_spin_lock(lock)
+#define DHD_FLOWRING_LIST_UNLOCK(lock, flags)     osl_spin_unlock((lock), (flags))
+
+#define DHD_RING_LOCK(lock, flags)	(flags) = osl_spin_lock(lock)
+#define DHD_RING_UNLOCK(lock, flags)	osl_spin_unlock((lock), (flags))
+
+#define DHD_BUS_LP_STATE_LOCK(lock, flags)	(flags) = osl_spin_lock(lock)
+#define DHD_BUS_LP_STATE_UNLOCK(lock, flags)	osl_spin_unlock((lock), (flags))
+
+#define DHD_BAR1_SWITCH_LOCK(lock, flags)	(flags) = osl_spin_lock(lock)
+#define DHD_BAR1_SWITCH_UNLOCK(lock, flags)	osl_spin_unlock((lock), (flags))
+
+#define DHD_BUS_PWR_REQ_LOCK(lock, flags)	(flags) = osl_spin_lock(lock)
+#define DHD_BUS_PWR_REQ_UNLOCK(lock, flags)	osl_spin_unlock((lock), (flags))
+
+#ifdef PCIE_INB_DW
+#define DHD_BUS_DONGLE_DS_LOCK(lock, flags)	(flags) = osl_spin_lock(lock)
+#define DHD_BUS_DONGLE_DS_UNLOCK(lock, flags)	osl_spin_unlock((lock), (flags))
+#endif /* PCIE_INB_DW */
+
+/* Enable DHD backplane spin lock/unlock */
+#define DHD_BACKPLANE_ACCESS_LOCK(lock, flags)     (flags) = osl_spin_lock(lock)
+#define DHD_BACKPLANE_ACCESS_UNLOCK(lock, flags)   osl_spin_unlock((lock), (flags))
+
+#define DHD_BUS_INB_DW_LOCK(lock, flags)	(flags) = osl_spin_lock(lock)
+#define DHD_BUS_INB_DW_UNLOCK(lock, flags)	osl_spin_unlock((lock), (flags))
+
+/* Enable DHD TDLS peer list spin lock/unlock */
+#ifdef WLTDLS
+#define DHD_TDLS_LOCK(lock, flags)       (flags) = osl_spin_lock(lock)
+#define DHD_TDLS_UNLOCK(lock, flags)     osl_spin_unlock((lock), (flags))
+#endif /* WLTDLS */
+
+#define DHD_BUS_INB_DW_LOCK(lock, flags)	(flags) = osl_spin_lock(lock)
+#define DHD_BUS_INB_DW_UNLOCK(lock, flags)	osl_spin_unlock((lock), (flags))
+
+#ifdef DBG_PKT_MON
+/* Enable DHD PKT MON spin lock/unlock */
+#define DHD_PKT_MON_LOCK(lock, flags)     (flags) = osl_spin_lock(lock)
+#define DHD_PKT_MON_UNLOCK(lock, flags)   osl_spin_unlock(lock, (flags))
+#endif /* DBG_PKT_MON */
+
+#ifdef DHD_PKT_LOGGING
+/* Enable DHD PKT LOG spin lock/unlock */
+#define DHD_PKT_LOG_LOCK(lock, flags)     (flags) = osl_spin_lock(lock)
+#define DHD_PKT_LOG_UNLOCK(lock, flags)   osl_spin_unlock(lock, (flags))
+#endif /* DHD_PKT_LOGGING */
+
+#if defined(linux) || defined(LINUX)
+#define DHD_LINUX_GENERAL_LOCK(dhdp, flags)	DHD_GENERAL_LOCK(dhdp, flags)
+#define DHD_LINUX_GENERAL_UNLOCK(dhdp, flags)	DHD_GENERAL_UNLOCK(dhdp, flags)
+#else
+#define DHD_LINUX_GENERAL_LOCK(dhdp, flags)	do {BCM_REFERENCE(flags);} while (0)
+#define DHD_LINUX_GENERAL_UNLOCK(dhdp, flags)	do {BCM_REFERENCE(flags);} while (0)
+#endif
+
+#define DHD_BUS_INB_DW_LOCK(lock, flags)	(flags) = osl_spin_lock(lock)
+#define DHD_BUS_INB_DW_UNLOCK(lock, flags)	osl_spin_unlock((lock), (flags))
+
+#define DHD_RX_NAPI_QUEUE_LOCK(lock, flags)	(flags) = osl_spin_lock(lock)
+#define DHD_RX_NAPI_QUEUE_UNLOCK(lock, flags)	osl_spin_unlock((lock), (flags))
+
+#define DHD_UP_LOCK(lock, flags)	(flags) = osl_spin_lock(lock)
+#define DHD_UP_UNLOCK(lock, flags)	osl_spin_unlock((lock), (flags))
+
+#define DHD_WAKE_SPIN_LOCK(lock, flags)	(flags) = osl_spin_lock(lock)
+#define DHD_WAKE_SPIN_UNLOCK(lock, flags)	osl_spin_unlock((lock), (flags))
+
+/*
+ * Temporarily change log dump lock to spin_lock_irqsave as DHD_ERROR/DHD_LOG_MEM
+ * are being called from dhdpcie_bus_isr.
+ * This will be reverted after proper solution is implemented to handle isr prints
+ */
+#define DHD_LOG_DUMP_BUF_LOCK(lock, flags)	(flags) = osl_spin_lock_irq(lock)
+#define DHD_LOG_DUMP_BUF_UNLOCK(lock, flags)	osl_spin_unlock_irq((lock), (flags))
+
+#define DHD_PKT_WAKE_LOCK(lock, flags)	(flags) = osl_spin_lock(lock)
+#define DHD_PKT_WAKE_UNLOCK(lock, flags)	osl_spin_unlock((lock), (flags))
+
+/* wlan_oob_irq is called in hard irq context */
+#define DHD_OOB_IRQ_LOCK(lock, flags)	(flags) = osl_spin_lock_irq(lock)
+#define DHD_OOB_IRQ_UNLOCK(lock, flags)	osl_spin_unlock_irq((lock), (flags))
+
+#define DHD_IF_STA_LIST_LOCK(lock, flags)	(flags) = osl_spin_lock(lock)
+#define DHD_IF_STA_LIST_UNLOCK(lock, flags)	osl_spin_unlock((lock), (flags))
+
+#define DHD_DBG_RING_LOCK_INIT(osh)		osl_spin_lock_init(osh)
+#define DHD_DBG_RING_LOCK_DEINIT(osh, lock)	osl_spin_lock_deinit(osh, (lock))
+#define DHD_DBG_RING_LOCK(lock, flags)		(flags) = osl_spin_lock(lock)
+#define DHD_DBG_RING_UNLOCK(lock, flags)	osl_spin_unlock((lock), flags)
+
+#ifdef DHD_MEM_STATS
+/* memory stats lock/unlock */
+#define DHD_MEM_STATS_LOCK(lock, flags)     (flags) = osl_spin_lock(lock)
+#define DHD_MEM_STATS_UNLOCK(lock, flags)   osl_spin_unlock((lock), (flags))
+#endif /* DHD_MEM_STATS */
+
+extern void dhd_dump_to_kernelog(dhd_pub_t *dhdp);
+
+#if defined(LINUX) || defined(linux)
+extern void dhd_print_tasklet_status(dhd_pub_t *dhd);
+#ifdef PCIE_INB_DW
+extern bool dhd_check_cfg_in_progress(dhd_pub_t *dhdp);
+#endif
+#else
+static INLINE void dhd_print_tasklet_status(dhd_pub_t *dhd) { }
+static INLINE bool dhd_check_cfg_in_progress(dhd_pub_t *dhdp)
+{ return FALSE; }
+#endif /* LINUX | linux */
+
+#ifdef BCMDBUS
+extern uint dhd_get_rxsz(dhd_pub_t *pub);
+extern void dhd_set_path(dhd_pub_t *pub);
+extern void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
+extern void dhd_bus_clearcounts(dhd_pub_t *dhdp);
+#endif /* BCMDBUS */
+
+#ifdef DHD_L2_FILTER
+extern int dhd_get_parp_status(dhd_pub_t *dhdp, uint32 idx);
+extern int dhd_set_parp_status(dhd_pub_t *dhdp, uint32 idx, int val);
+extern int dhd_get_dhcp_unicast_status(dhd_pub_t *dhdp, uint32 idx);
+extern int dhd_set_dhcp_unicast_status(dhd_pub_t *dhdp, uint32 idx, int val);
+extern int dhd_get_block_ping_status(dhd_pub_t *dhdp, uint32 idx);
+extern int dhd_set_block_ping_status(dhd_pub_t *dhdp, uint32 idx, int val);
+extern int dhd_get_grat_arp_status(dhd_pub_t *dhdp, uint32 idx);
+extern int dhd_set_grat_arp_status(dhd_pub_t *dhdp, uint32 idx, int val);
+extern int dhd_get_block_tdls_status(dhd_pub_t *dhdp, uint32 idx);
+extern int dhd_set_block_tdls_status(dhd_pub_t *dhdp, uint32 idx, int val);
+#endif /* DHD_L2_FILTER */
+
+#if (defined(BCM_ROUTER_DHD) && defined(QOS_MAP_SET))
+extern int dhd_set_qosmap_up_table(dhd_pub_t *dhdp, uint32 idx, bcm_tlv_t *qos_map_ie);
+#endif /* BCM_ROUTER_DHD && QOS_MAP_SET */
+
+typedef struct wl_io_pport {
+	dhd_pub_t *dhd_pub;
+	uint ifidx;
+} wl_io_pport_t;
+
+typedef struct wl_evt_pport {
+	dhd_pub_t *dhd_pub;
+	int *ifidx;
+	void *pktdata;
+	uint data_len;
+	void **data_ptr;
+	void *raw_event;
+} wl_evt_pport_t;
+
+extern void *dhd_pub_shim(dhd_pub_t *dhd_pub);
+#ifdef DHD_FW_COREDUMP
+void* dhd_get_fwdump_buf(dhd_pub_t *dhd_pub, uint32 length);
+#endif /* DHD_FW_COREDUMP */
+
+#if defined(SET_XPS_CPUS)
+int dhd_xps_cpus_enable(struct net_device *net, int enable);
+int custom_xps_map_set(struct net_device *net, char *buf, size_t len);
+void custom_xps_map_clear(struct net_device *net);
+#endif
+
+#if defined(SET_RPS_CPUS)
+int dhd_rps_cpus_enable(struct net_device *net, int enable);
+int custom_rps_map_set(struct netdev_rx_queue *queue, char *buf, size_t len);
+void custom_rps_map_clear(struct netdev_rx_queue *queue);
+#define PRIMARY_INF 0
+#define VIRTUAL_INF 1
+#if defined(CONFIG_MACH_UNIVERSAL7420) || defined(CONFIG_SOC_EXYNOS8890)
+#define RPS_CPUS_MASK "10"
+#define RPS_CPUS_MASK_P2P "10"
+#define RPS_CPUS_MASK_IBSS "10"
+#define RPS_CPUS_WLAN_CORE_ID 4
+#else
+#if defined(DHD_TPUT_PATCH)
+#define RPS_CPUS_MASK "f"
+#define RPS_CPUS_MASK_P2P "f"
+#define RPS_CPUS_MASK_IBSS "f"
+#else
+#define RPS_CPUS_MASK "6"
+#define RPS_CPUS_MASK_P2P "6"
+#define RPS_CPUS_MASK_IBSS "6"
+#endif
+#endif /* CONFIG_MACH_UNIVERSAL7420 || CONFIG_SOC_EXYNOS8890 */
+#endif // endif
+
+int dhd_get_download_buffer(dhd_pub_t	*dhd, char *file_path, download_type_t component,
+	char ** buffer, int *length);
+
+void dhd_free_download_buffer(dhd_pub_t	*dhd, void *buffer, int length);
+
+int dhd_download_blob(dhd_pub_t *dhd, unsigned char *buf,
+		uint32 len, char *iovar);
+ 
+int dhd_download_apf(dhd_pub_t *dhd, unsigned char *buf,
+		uint32 len, char *iovar);
+
+int dhd_download_blob_cached(dhd_pub_t *dhd, char *file_path,
+	uint32 len, char *iovar);
+
+int dhd_apply_default_txcap(dhd_pub_t *dhd, char *txcap_path);
+int dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path);
+
+#ifdef SHOW_LOGTRACE
+int dhd_parse_logstrs_file(osl_t *osh, char *raw_fmts, int logstrs_size,
+		dhd_event_log_t *event_log);
+#ifdef DHD_LINUX_STD_FW_API
+int dhd_parse_map_file(osl_t *osh, const void *ptr, uint32 *ramstart,
+		uint32 *rodata_start, uint32 *rodata_end);
+#else
+int dhd_parse_map_file(osl_t *osh, void *file, uint32 *ramstart,
+		uint32 *rodata_start, uint32 *rodata_end);
+#endif /* DHD_LINUX_STD_FW_API */
+#ifdef PCIE_FULL_DONGLE
+int dhd_event_logtrace_infobuf_pkt_process(dhd_pub_t *dhdp, void *pktbuf,
+		dhd_event_log_t *event_data);
+#endif /* PCIE_FULL_DONGLE */
+#endif /* SHOW_LOGTRACE */
+
+/*
+ * control_logtrace:
+ * "0" -> do not print event log messages in any form
+ * "1" -> print event log messages as EL
+ * "2" -> print event log messages as formatted CONSOLE_E if logstrs.bin etc. files are available
+ */
+typedef enum logtrace_ctrl {
+	LOGTRACE_DISABLE = 0,
+	LOGTRACE_RAW_FMT = 1,
+	LOGTRACE_PARSED_FMT = 2
+} logtrace_ctrl_t;
+
+#define DEFAULT_CONTROL_LOGTRACE	LOGTRACE_PARSED_FMT
+#ifndef CUSTOM_CONTROL_LOGTRACE
+#define CUSTOM_CONTROL_LOGTRACE		DEFAULT_CONTROL_LOGTRACE
+#endif
+
+extern uint8 control_logtrace;
+
+#if defined(NDIS)
+bool dhd_is_device_removed(dhd_pub_t *dhd);
+#else
+#define dhd_is_device_removed(x) FALSE
+#define dhd_os_ind_firmware_stall(x)
+#endif /* defined(NDIS) */
+
+#if defined(DHD_FW_COREDUMP)
+#if defined(linux) || defined(LINUX)
+extern void dhd_get_memdump_info(dhd_pub_t *dhd);
+#else
+static INLINE void dhd_get_memdump_info(dhd_pub_t *dhd)
+{ return; }
+#endif /* linux || LINUX */
+#endif /* defined(DHD_FW_COREDUMP) */
+#ifdef BCMASSERT_LOG
+extern void dhd_get_assert_info(dhd_pub_t *dhd);
+#else
+static INLINE void dhd_get_assert_info(dhd_pub_t *dhd) { }
+#endif /* BCMASSERT_LOG */
+
+#if defined(LINUX) || defined(linux)
+#define DMAXFER_FREE(dhdp, dmap) dhd_schedule_dmaxfer_free(dhdp, dmap);
+#else  /* !(LINUX || linux) */
+#define DMAXFER_FREE(dhdp, dmmap) dmaxfer_free_prev_dmaaddr(dhdp, dmmap);
+#endif  /* linux || LINUX */
+
+#if defined(PCIE_FULL_DONGLE)
+extern void dmaxfer_free_prev_dmaaddr(dhd_pub_t *dhdp, dmaxref_mem_map_t *dmmap);
+void dhd_schedule_dmaxfer_free(dhd_pub_t *dhdp, dmaxref_mem_map_t *dmmap);
+
+extern int ring_size_version;
+
+extern uint h2d_max_txpost;
+extern uint h2d_htput_max_txpost;
+extern uint d2h_max_txcpl;
+
+extern uint h2d_max_rxpost;
+extern uint d2h_max_rxcpl;
+
+extern uint h2d_max_ctrlpost;
+extern uint d2h_max_ctrlcpl;
+
+extern uint rx_buf_burst;
+extern uint rx_bufpost_threshold;
+
+#endif  /* PCIE_FULL_DONGLE */
+
+#define DHD_LB_STATS_NOOP	do { /* noop */ } while (0)
+#if defined(DHD_LB_STATS)
+#include <bcmutils.h>
+extern void dhd_lb_stats_init(dhd_pub_t *dhd);
+extern void dhd_lb_stats_deinit(dhd_pub_t *dhd);
+extern void dhd_lb_stats_reset(dhd_pub_t *dhd);
+#ifdef DHD_MEM_STATS
+extern uint64 dhd_lb_mem_usage(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
+#endif /* DHD_MEM_STATS */
+extern void dhd_lb_stats_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
+extern void dhd_lb_stats_update_napi_histo(dhd_pub_t *dhdp, uint32 count);
+extern void dhd_lb_stats_update_txc_histo(dhd_pub_t *dhdp, uint32 count);
+extern void dhd_lb_stats_update_rxc_histo(dhd_pub_t *dhdp, uint32 count);
+extern void dhd_lb_stats_txc_percpu_cnt_incr(dhd_pub_t *dhdp);
+extern void dhd_lb_stats_rxc_percpu_cnt_incr(dhd_pub_t *dhdp);
+#define DHD_LB_STATS_INIT(dhdp)	dhd_lb_stats_init(dhdp)
+#define DHD_LB_STATS_DEINIT(dhdp) dhd_lb_stats_deinit(dhdp)
+/* Reset is called from common layer so it takes dhd_pub_t as argument */
+#define DHD_LB_STATS_RESET(dhdp) dhd_lb_stats_reset(dhdp)
+#define DHD_LB_STATS_CLR(x)	(x) = 0U
+#define DHD_LB_STATS_INCR(x)	(x) = (x) + 1
+#define DHD_LB_STATS_ADD(x, c)	(x) = (x) + (c)
+#define DHD_LB_STATS_PERCPU_ARR_INCR(x) \
+	{ \
+		int cpu = get_cpu(); put_cpu(); \
+		DHD_LB_STATS_INCR(x[cpu]); \
+	}
+#define DHD_LB_STATS_UPDATE_NAPI_HISTO(dhdp, x)	dhd_lb_stats_update_napi_histo(dhdp, x)
+#else /* !DHD_LB_STATS */
+#define DHD_LB_STATS_INIT(dhdp)	 DHD_LB_STATS_NOOP
+#define DHD_LB_STATS_DEINIT(dhdp) DHD_LB_STATS_NOOP
+#define DHD_LB_STATS_RESET(dhdp) DHD_LB_STATS_NOOP
+#define DHD_LB_STATS_CLR(x)	 DHD_LB_STATS_NOOP
+#define DHD_LB_STATS_INCR(x)	 DHD_LB_STATS_NOOP
+#define DHD_LB_STATS_ADD(x, c)	 DHD_LB_STATS_NOOP
+#define DHD_LB_STATS_PERCPU_ARR_INCR(x)	 DHD_LB_STATS_NOOP
+#define DHD_LB_STATS_UPDATE_NAPI_HISTO(dhd, x) DHD_LB_STATS_NOOP
+#endif /* !DHD_LB_STATS */
+
+#if defined(BCMDBG) && defined(DHD_MACDBG)
+extern void dhd_schedule_macdbg_dump(dhd_pub_t *dhdp);
+#endif /* BCMDBG && DHD_MACDBG */
+
+#ifdef DHD_SSSR_DUMP
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+#define DHD_SSSR_MEMPOOL_SIZE	(2 * 1024 * 1024) /* 2MB size */
+#else
+#define DHD_SSSR_MEMPOOL_SIZE	(1 * 1024 * 1024) /* 1MB size */
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+
+/* used in sssr_dump_mode */
+#define SSSR_DUMP_MODE_SSSR	0	/* dump both *before* and *after* files */
+#define SSSR_DUMP_MODE_FIS	1	/* dump *after* files only */
+
+extern int dhd_sssr_mempool_init(dhd_pub_t *dhd);
+extern void dhd_sssr_mempool_deinit(dhd_pub_t *dhd);
+extern int dhd_sssr_dump_init(dhd_pub_t *dhd);
+extern void dhd_sssr_dump_deinit(dhd_pub_t *dhd);
+extern int dhdpcie_sssr_dump(dhd_pub_t *dhd);
+extern void dhd_sssr_print_filepath(dhd_pub_t *dhd, char *path);
+extern int dhd_sssr_reg_info_init(dhd_pub_t *dhd);
+extern void dhd_sssr_reg_info_deinit(dhd_pub_t *dhd);
+extern uint dhd_sssr_dig_buf_size(dhd_pub_t *dhdp);
+extern uint dhd_sssr_dig_buf_addr(dhd_pub_t *dhdp);
+extern uint dhd_sssr_mac_buf_size(dhd_pub_t *dhdp, uint8 core_idx);
+extern uint dhd_sssr_mac_xmtaddress(dhd_pub_t *dhdp, uint8 core_idx);
+extern uint dhd_sssr_mac_xmtdata(dhd_pub_t *dhdp, uint8 core_idx);
+
+#define DHD_SSSR_MEMPOOL_INIT(dhdp)	dhd_sssr_mempool_init(dhdp)
+#define DHD_SSSR_MEMPOOL_DEINIT(dhdp) dhd_sssr_mempool_deinit(dhdp)
+#define DHD_SSSR_DUMP_INIT(dhdp)	dhd_sssr_dump_init(dhdp)
+#define DHD_SSSR_DUMP_DEINIT(dhdp) dhd_sssr_dump_deinit(dhdp)
+#define DHD_SSSR_PRINT_FILEPATH(dhdp, path) dhd_sssr_print_filepath(dhdp, path)
+#define DHD_SSSR_REG_INFO_INIT(dhdp)	dhd_sssr_reg_info_init(dhdp)
+#define DHD_SSSR_REG_INFO_DEINIT(dhdp) dhd_sssr_reg_info_deinit(dhdp)
+#else
+#define DHD_SSSR_MEMPOOL_INIT(dhdp)		do { /* noop */ } while (0)
+#define DHD_SSSR_MEMPOOL_DEINIT(dhdp)		do { /* noop */ } while (0)
+#define DHD_SSSR_DUMP_INIT(dhdp)		do { /* noop */ } while (0)
+#define DHD_SSSR_DUMP_DEINIT(dhdp)		do { /* noop */ } while (0)
+#define DHD_SSSR_PRINT_FILEPATH(dhdp, path)	do { /* noop */ } while (0)
+#define DHD_SSSR_REG_INFO_INIT(dhdp)		do { /* noop */ } while (0)
+#define DHD_SSSR_REG_INFO_DEINIT(dhdp)		do { /* noop */ } while (0)
+#endif /* DHD_SSSR_DUMP */
+
+#ifdef DHD_COREDUMP
+#define WLAN_DHD_MEMDUMP_SIZE	(3u * 1024u * 1024u)
+#ifdef DHD_SSSR_DUMP
+#define DHD_MEMDUMP_BUFFER_SIZE	(WLAN_DHD_MEMDUMP_SIZE + DHD_SSSR_MEMPOOL_SIZE)
+#else
+#define DHD_MEMDUMP_BUFFER_SIZE	(WLAN_DHD_MEMDUMP_SIZE)
+#endif
+extern int dhd_coredump_mempool_init(dhd_pub_t *dhd);
+extern void dhd_coredump_mempool_deinit(dhd_pub_t *dhd);
+#define DHD_COREDUMP_MEMPOOL_INIT(dhdp)		dhd_coredump_mempool_init(dhdp)
+#define DHD_COREDUMP_MEMPOOL_DEINIT(dhdp)	dhd_coredump_mempool_deinit(dhdp)
+#else
+#define DHD_COREDUMP_MEMPOOL_INIT(dhdp)		do { /* noop */ } while (0)
+#define DHD_COREDUMP_MEMPOOL_DEINIT(dhdp)	do { /* noop */ } while (0)
+#endif /* DHD_COREDUMP */
+
+#ifdef BCMPCIE
+extern int dhd_prot_debug_info_print(dhd_pub_t *dhd);
+extern bool dhd_bus_skip_clm(dhd_pub_t *dhdp);
+extern void dhd_pcie_dump_rc_conf_space_cap(dhd_pub_t *dhd);
+extern bool dhd_pcie_dump_int_regs(dhd_pub_t *dhd);
+extern bool dhd_pcie_check_lps_d3_acked(dhd_pub_t *dhd);
+void dhd_prot_ctrl_info_print(dhd_pub_t *dhd);
+#else
+#define dhd_prot_debug_info_print(x)
+static INLINE bool dhd_bus_skip_clm(dhd_pub_t *dhd_pub)
+{ return 0; }
+#endif /* BCMPCIE */
+
+#if defined(LINUX) || defined(linux)
+void dhd_show_kirqstats(dhd_pub_t *dhd);
+#else
+static INLINE void dhd_show_kirqstats(dhd_pub_t *dhd)
+{ return; }
+#endif /* defined(LINUX) || defined(linux) */
+
+/* Bitmask used for Join Timeout */
+#define WLC_SSID_MASK          0x01
+#define WLC_WPA_MASK           0x02
+
+#if defined(LINUX) || defined(linux)
+fw_download_status_t dhd_fw_download_status(dhd_pub_t *dhd_pub);
+extern int dhd_start_join_timer(dhd_pub_t *pub);
+extern int dhd_stop_join_timer(dhd_pub_t *pub);
+extern int dhd_start_scan_timer(dhd_pub_t *pub, bool is_escan);
+extern int dhd_stop_scan_timer(dhd_pub_t *pub, bool is_escan, uint16 sync_id);
+extern int dhd_start_cmd_timer(dhd_pub_t *pub);
+extern int dhd_stop_cmd_timer(dhd_pub_t *pub);
+extern int dhd_start_bus_timer(dhd_pub_t *pub);
+extern int dhd_stop_bus_timer(dhd_pub_t *pub);
+extern uint16 dhd_get_request_id(dhd_pub_t *pub);
+extern int dhd_set_request_id(dhd_pub_t *pub, uint16 id, uint32 cmd);
+extern void dhd_clear_join_error(dhd_pub_t *pub, uint32 mask);
+extern void dhd_get_scan_to_val(dhd_pub_t *pub, uint32 *to_val);
+extern void dhd_set_scan_to_val(dhd_pub_t *pub, uint32 to_val);
+extern void dhd_get_join_to_val(dhd_pub_t *pub, uint32 *to_val);
+extern void dhd_set_join_to_val(dhd_pub_t *pub, uint32 to_val);
+extern void dhd_get_cmd_to_val(dhd_pub_t *pub, uint32 *to_val);
+extern void dhd_set_cmd_to_val(dhd_pub_t *pub, uint32 to_val);
+extern void dhd_get_bus_to_val(dhd_pub_t *pub, uint32 *to_val);
+extern void dhd_set_bus_to_val(dhd_pub_t *pub, uint32 to_val);
+extern int dhd_start_timesync_timer(dhd_pub_t *pub);
+extern int dhd_stop_timesync_timer(dhd_pub_t *pub);
+#else
+static INLINE fw_download_status_t dhd_fw_download_status(dhd_pub_t *dhd_pub)
+{ return FW_UNLOADED; }
+static INLINE int dhd_start_join_timer(dhd_pub_t *pub) { return 0; }
+static INLINE int dhd_stop_join_timer(dhd_pub_t *pub) { return 0; }
+static INLINE int dhd_start_scan_timer(dhd_pub_t *pub, bool is_escan) { return 0; }
+static INLINE int dhd_stop_scan_timer(dhd_pub_t *pub, bool is_escan, uint16 sync_id) { return 0; }
+static INLINE int dhd_start_cmd_timer(dhd_pub_t *pub) { return 0; }
+static INLINE int dhd_stop_cmd_timer(dhd_pub_t *pub) { return 0; }
+static INLINE int dhd_start_bus_timer(dhd_pub_t *pub) { return 0; }
+static INLINE int dhd_stop_bus_timer(dhd_pub_t *pub) { return 0; }
+static INLINE uint16 dhd_get_request_id(dhd_pub_t *pub) {  return 0; }
+static INLINE int dhd_set_request_id(dhd_pub_t *pub, uint16 id) {  return 0; }
+static INLINE void dhd_clear_join_error(dhd_pub_t *pub, uint32 mask) {  return; }
+static INLINE void dhd_get_scan_to_val(dhd_pub_t *pub, uint32 *to_val) {  return; }
+static INLINE void dhd_set_scan_to_val(dhd_pub_t *pub, uint32 to_val) {  return; }
+static INLINE void dhd_get_join_to_val(dhd_pub_t *pub, uint32 *to_val) {  return; }
+static INLINE void dhd_set_join_to_val(dhd_pub_t *pub, uint32 to_val) {  return; }
+static INLINE void dhd_get_cmd_to_val(dhd_pub_t *pub, uint32 *to_val) {  return; }
+static INLINE void dhd_set_cmd_to_val(dhd_pub_t *pub, uint32 to_val) {  return; }
+static INLINE void dhd_get_bus_to_val(dhd_pub_t *pub, uint32 *to_val) {  return; }
+static INLINE void dhd_set_bus_to_val(dhd_pub_t *pub, uint32 to_val) {  return; }
+static INLINE int dhd_start_timesync_timer(dhd_pub_t *pub) { return 0; }
+static INLINE int dhd_stop_timesync_timer(dhd_pub_t *pub) { return 0; }
+#endif /* defined(LINUX) || defined(linux) */
+
+#ifdef DHD_PKTID_AUDIT_ENABLED
+#if defined(LINUX) || defined(linux)
+void dhd_pktid_error_handler(dhd_pub_t *dhdp);
+#else /* !(LINUX || linux) */
+static INLINE void dhd_pktid_error_handler(dhd_pub_t *dhdp) { ASSERT(0); }
+#endif /* LINUX || linux */
+#endif /* DHD_PKTID_AUDIT_ENABLED */
+
+#ifdef DHD_MAP_PKTID_LOGGING
+#if defined(LINUX) || defined(linux)
+extern void dhd_pktid_logging_dump(dhd_pub_t *dhdp);
+#else /* !(LINUX || linux) */
+static INLINE void dhd_pktid_logging_dump(dhd_pub_t *dhdp) { }
+#endif /* LINUX || linux */
+#endif /* DHD_MAP_PKTID_LOGGING */
+
+#define DHD_DISABLE_RUNTIME_PM(dhdp)
+#define DHD_ENABLE_RUNTIME_PM(dhdp)
+#define DHD_STOP_RPM_TIMER(dhdp)
+#define DHD_START_RPM_TIMER(dhdp)
+
+extern bool dhd_prot_is_h2d_ring_empty(dhd_pub_t *dhd, void *prot_info);
+extern void dhd_prot_dump_ring_ptrs(void *prot_info);
+extern bool dhd_prot_check_pending_ctrl_cmpls(dhd_pub_t *dhd);
+
+#if defined(LINUX) || defined(linux)
+#if defined(DHD_TRACE_WAKE_LOCK)
+void dhd_wk_lock_stats_dump(dhd_pub_t *dhdp);
+#endif
+#endif /* LINUX || linux */
+
+extern bool dhd_query_bus_erros(dhd_pub_t *dhdp);
+void dhd_clear_bus_errors(dhd_pub_t *dhdp);
+
+#if (defined(linux) || defined(LINUX)) && defined(CONFIG_64BIT)
+#define DHD_SUPPORT_64BIT
+#endif /* (linux || LINUX) && CONFIG_64BIT */
+
+static INLINE void dhd_schedule_reset(dhd_pub_t *dhdp) {;}
+
+extern void init_dhd_timeouts(dhd_pub_t *pub);
+extern void deinit_dhd_timeouts(dhd_pub_t *pub);
+
+typedef enum timeout_resons {
+	DHD_REASON_COMMAND_TO,
+	DHD_REASON_JOIN_TO,
+	DHD_REASON_SCAN_TO,
+	DHD_REASON_OQS_TO
+} timeout_reasons_t;
+
+#ifdef REPORT_FATAL_TIMEOUTS
+void dhd_send_trap_to_fw_for_timeout(dhd_pub_t * pub, timeout_reasons_t reason);
+#endif
+#if defined(PCIE_OOB) || defined(PCIE_INB_DW)
+extern int dhd_bus_set_device_wake(struct dhd_bus *bus, bool val);
+extern void dhd_bus_dw_deassert(dhd_pub_t *dhd);
+#endif /* defined(PCIE_OOB) || defined(PCIE_INB_DW) */
+extern void dhd_prhex(const char *msg, volatile uchar *buf, uint nbytes, uint32 dbg_level);
+int dhd_tput_test(dhd_pub_t *dhd, tput_test_t *tput_data);
+void dhd_tput_test_rx(dhd_pub_t *dhd, void *pkt);
+static INLINE int dhd_get_max_txbufs(dhd_pub_t *dhdp)
+{ return -1; }
+
+#ifdef FILTER_IE
+int dhd_read_from_file(dhd_pub_t *dhd);
+int dhd_parse_filter_ie(dhd_pub_t *dhd, uint8 *buf);
+int dhd_get_filter_ie_count(dhd_pub_t *dhd, uint8 *buf);
+int dhd_parse_oui(dhd_pub_t *dhd, uint8 *inbuf, uint8 *oui, int len);
+int dhd_check_valid_ie(dhd_pub_t *dhdp, uint8 *buf, int len);
+#endif /* FILTER_IE */
+
+uint16 dhd_prot_get_ioctl_trans_id(dhd_pub_t *dhdp);
+
+#ifdef SET_PCIE_IRQ_CPU_CORE
+enum {
+	DHD_AFFINITY_OFF = 0,
+	DHD_AFFINITY_TPUT_150MBPS,
+	DHD_AFFINITY_TPUT_300MBPS,
+	DHD_AFFINITY_LAST
+};
+
+extern void dhd_set_irq_cpucore(dhd_pub_t *dhdp, int affinity_cmd);
+#endif /* SET_PCIE_IRQ_CPU_CORE */
+#if defined(DHD_HANG_SEND_UP_TEST)
+extern void dhd_make_hang_with_reason(struct net_device *dev, const char *string_num);
+#endif /* DHD_HANG_SEND_UP_TEST */
+
+#ifdef DHD_WAKE_STATUS
+wake_counts_t* dhd_get_wakecount(dhd_pub_t *dhdp);
+#endif /* DHD_WAKE_STATUS */
+extern int dhd_get_random_bytes(uint8 *buf, uint len);
+
+#if defined(DHD_BLOB_EXISTENCE_CHECK)
+extern void dhd_set_blob_support(dhd_pub_t *dhdp, char *fw_path);
+#endif /* DHD_BLOB_EXISTENCE_CHECK */
+
+int dhd_get_preserve_log_numbers(dhd_pub_t *dhd, uint64 *logset_mask);
+
+#define DHD_WORD_TO_LEN_SHIFT		(2u)       /* WORD to BYTES SHIFT */
+
+#if defined(linux) || defined(LINUX)
+int dhd_export_debug_data(void *mem_buf, void *fp, const void *user_buf, uint32 buf_len, void *pos);
+#else
+static int dhd_export_debug_data(void *mem_buf, void *fp, const void *user_buf,
+	uint32 buf_len, void *pos)
+{ return 0; }
+#endif /* linux || LINUX */
+#if defined(linux) || defined(LINUX)
+#define DHD_PCIE_CONFIG_SAVE(bus)	pci_save_state(bus->dev)
+#define DHD_PCIE_CONFIG_RESTORE(bus)	pci_restore_state(bus->dev)
+#elif defined(NDIS)
+/* For EFI the pcie config space which is saved during init
+* is the one that should always be restored, so NOP for save
+*/
+#define DHD_PCIE_CONFIG_SAVE(bus)
+#define DHD_PCIE_CONFIG_RESTORE(bus)	dhdpcie_config_restore(bus, TRUE)
+#else
+#define DHD_PCIE_CONFIG_SAVE(bus)	do { /* noop */ } while (0)
+#define DHD_PCIE_CONFIG_RESTORE(bus)	do { /* noop */ } while (0)
+#endif /* linux || LINUX */
+
+typedef struct dhd_pkt_parse {
+	uint32 proto;	/* Network layer protocol */
+	uint32 t1;	/* n-tuple */
+	uint32 t2;
+} dhd_pkt_parse_t;
+
+/* ========= RING API functions : exposed to others ============= */
+#define DHD_RING_TYPE_FIXED		1
+#define DHD_RING_TYPE_SINGLE_IDX	2
+uint32 dhd_ring_get_hdr_size(void);
+void *dhd_ring_init(dhd_pub_t *dhdp, uint8 *buf, uint32 buf_size, uint32 elem_size,
+	uint32 elem_cnt, uint32 type);
+void dhd_ring_deinit(dhd_pub_t *dhdp, void *_ring);
+void *dhd_ring_get_first(void *_ring);
+void dhd_ring_free_first(void *_ring);
+void dhd_ring_set_read_idx(void *_ring, uint32 read_idx);
+void dhd_ring_set_write_idx(void *_ring, uint32 write_idx);
+uint32 dhd_ring_get_read_idx(void *_ring);
+uint32 dhd_ring_get_write_idx(void *_ring);
+void *dhd_ring_get_last(void *_ring);
+void *dhd_ring_get_next(void *_ring, void *cur);
+void *dhd_ring_get_prev(void *_ring, void *cur);
+void *dhd_ring_get_empty(void *_ring);
+int dhd_ring_get_cur_size(void *_ring);
+void dhd_ring_lock(void *ring, void *fist_ptr, void *last_ptr);
+void dhd_ring_lock_free(void *ring);
+void *dhd_ring_lock_get_first(void *_ring);
+void *dhd_ring_lock_get_last(void *_ring);
+int dhd_ring_lock_get_count(void *_ring);
+void dhd_ring_lock_free_first(void *ring);
+void dhd_ring_whole_lock(void *ring);
+void dhd_ring_whole_unlock(void *ring);
+
+#ifdef GDB_PROXY
+/** Firmware loaded and GDB proxy may access memory and registers */
+#define DHD_GDB_PROXY_PROBE_ACCESS_ENABLED		0x00000001
+/** Firmware loaded, access to it is enabled but it is not running yet */
+#define DHD_GDB_PROXY_PROBE_FIRMWARE_NOT_RUNNING	0x00000002
+/** Firmware is running */
+#define DHD_GDB_PROXY_PROBE_FIRMWARE_RUNNING		0x00000004
+/** Firmware was started in bootloader mode */
+#define DHD_GDB_PROXY_PROBE_BOOTLOADER_MODE		0x00000008
+/** Host memory code offload present */
+#define DHD_GDB_PROXY_PROBE_HOSTMEM_CODE		0x00000010
+/** Memory dump count field present */
+#define DHD_GDB_PROXY_PROBE_MEMDUMP_COUNT		0x00000020
+
+/* Data structure, returned by "gdb_proxy_probe" iovar */
+typedef struct dhd_gdb_proxy_probe_data {
+	uint32 data_len;		/* Length of data in structure */
+	uint32 magic;			/* Must contain DHD_IOCTL_MAGIC */
+	uint32 flags;			/* Set of DHD_GDB_PROXY_PROBE_... bits */
+	uint32 last_id;			/* 0 or proxy ID last set */
+	uint32 hostmem_code_win_base;	/* Hostmem code window start in ARM physical address space
+					 */
+	uint32 hostmem_code_win_length;	/* Hostmem code window length */
+	uint32 mem_dump_count;		/* Number of memory dumps made so far */
+} dhd_gdb_proxy_probe_data_t;
+
+/* Timeout loop brackets */
+/* Intended usage is to keep repeating timeoutable operation (operation that expected to
+ * succeed but may fail because of timeout) while timeout may be explained by firmware
+ * stop in gdb
+ * Example:
+ *	dhd_pub_t *dhd;
+ *	...
+ *	#ifdef GDB_PROXY
+ *	GDB_PROXY_TIMEOUT_DO(dhd) {
+ *		operation_that_may_succeed_or_timeout();
+ *	} GDB_PROXY_TIMEOUT_WHILE(operation_timed_out());
+ *	#else
+ *	operation_that_may_succeed_or_timeout();
+ *	#endif
+ *	...
+ *	if (operation_timed_out()) {
+ *		bang_memdump_crash_horror();
+ *	}
+ */
+/* Argument is pointer to dhd_pub_t structure */
+#define GDB_PROXY_TIMEOUT_DO(dhd)				\
+{								\
+	uint32 gdb_prev_stop_count;				\
+	dhd_pub_t *gdb_dhd = dhd;				\
+	do {							\
+		gdb_prev_stop_count = gdb_dhd->gdb_proxy_stop_count;
+
+/* Argument should evaluate to true if operation failed because of timeout */
+#define GDB_PROXY_TIMEOUT_WHILE(timeout_cond)							\
+	} while ((timeout_cond) && ((gdb_dhd->gdb_proxy_stop_count != gdb_prev_stop_count) ||	\
+				(gdb_dhd->gdb_proxy_stop_count & GDB_PROXY_STOP_MASK)));	\
+}
+#endif /* GDB_PROXY */
+
+#ifdef PKT_FILTER_SUPPORT
+extern int dhd_pktfilter_mode_change(dhd_pub_t * dhd, int enable);
+extern void dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg);
+extern void dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode);
+extern void dhd_pktfilter_offload_delete(dhd_pub_t *dhd, int id);
+#endif
+
+#ifdef DHD_DUMP_PCIE_RINGS
+extern int dhd_d2h_h2d_ring_dump(dhd_pub_t *dhd, void *file, const void *user_buf,
+	unsigned long *file_posn, bool file_write);
+#endif /* DHD_DUMP_PCIE_RINGS */
+
+#ifdef EWP_EDL
+#define DHD_EDL_RING_SIZE (D2HRING_EDL_MAX_ITEM * D2HRING_EDL_ITEMSIZE)
+int dhd_event_logtrace_process_edl(dhd_pub_t *dhdp, uint8 *data,
+		void *evt_decode_data);
+int dhd_edl_mem_init(dhd_pub_t *dhd);
+void dhd_edl_mem_deinit(dhd_pub_t *dhd);
+void dhd_prot_edl_ring_tcm_rd_update(dhd_pub_t *dhd);
+#define DHD_EDL_MEM_INIT(dhdp) dhd_edl_mem_init(dhdp)
+#define DHD_EDL_MEM_DEINIT(dhdp) dhd_edl_mem_deinit(dhdp)
+#define DHD_EDL_RING_TCM_RD_UPDATE(dhdp) \
+	dhd_prot_edl_ring_tcm_rd_update(dhdp)
+#else
+#define DHD_EDL_MEM_INIT(dhdp) do { /* noop */ } while (0)
+#define DHD_EDL_MEM_DEINIT(dhdp) do { /* noop */ } while (0)
+#define DHD_EDL_RING_TCM_RD_UPDATE(dhdp) do { /* noop */ } while (0)
+#endif /* EWP_EDL */
+
+#if defined(DHD_H2D_LOG_TIME_SYNC)
+void dhd_h2d_log_time_sync_deferred_wq_schedule(dhd_pub_t *dhdp);
+void dhd_h2d_log_time_sync(dhd_pub_t *dhdp);
+#endif /* DHD_H2D_LOG_TIME_SYNC */
+extern void dhd_cleanup_if(struct net_device *net);
+
+void dhd_schedule_logtrace(void *dhd_info);
+int dhd_print_fw_ver_from_file(dhd_pub_t *dhdp, char *fwpath);
+
+#if defined(LINUX) || defined(linux)
+/* configuration of ecounters. API's tp start/stop. currently supported only for linux */
+extern int dhd_ecounter_configure(dhd_pub_t *dhd, bool enable);
+extern int dhd_start_ecounters(dhd_pub_t *dhd);
+extern int dhd_stop_ecounters(dhd_pub_t *dhd);
+extern int dhd_start_event_ecounters(dhd_pub_t *dhd);
+extern int dhd_stop_event_ecounters(dhd_pub_t *dhd);
+#endif /* LINUX || linux */
+
+#define DHD_DUMP_TYPE_NAME_SIZE		32
+#define DHD_DUMP_FILE_PATH_SIZE		256
+#define DHD_DUMP_FILE_COUNT_MAX		5
+#define DHD_DUMP_TYPE_COUNT_MAX		10
+
+#ifdef DHD_DUMP_MNGR
+typedef struct _DFM_elem {
+	char type_name[DHD_DUMP_TYPE_NAME_SIZE];
+	char file_path[DHD_DUMP_FILE_COUNT_MAX][DHD_DUMP_FILE_PATH_SIZE];
+	int file_idx;
+} DFM_elem_t;
+
+typedef struct _dhd_dump_file_manage {
+	DFM_elem_t elems[DHD_DUMP_TYPE_COUNT_MAX];
+} dhd_dump_file_manage_t;
+
+extern void dhd_dump_file_manage_enqueue(dhd_pub_t *dhd, char *dump_path, char *fname);
+#endif /* DHD_DUMP_MNGR */
+
+#define HD_PREFIX_SIZE  2   /* hexadecimal prefix size */
+#define HD_BYTE_SIZE    2   /* hexadecimal byte size */
+
+#ifdef DNGL_AXI_ERROR_LOGGING
+extern void dhd_axi_error(dhd_pub_t *dhd);
+#ifdef DHD_USE_WQ_FOR_DNGL_AXI_ERROR
+extern void dhd_axi_error_dispatch(dhd_pub_t *dhdp);
+#endif /* DHD_USE_WQ_FOR_DNGL_AXI_ERROR */
+#endif /* DNGL_AXI_ERROR_LOGGING */
+
+#ifdef DHD_STATUS_LOGGING
+#include <dhd_statlog.h>
+#else
+#define ST(x)		0
+#define STDIR(x)	0
+#define DHD_STATLOG_CTRL(dhdp, stat, ifidx, reason) \
+	do { /* noop */ } while (0)
+#define DHD_STATLOG_DATA(dhdp, stat, ifidx, dir, cond) \
+	do { BCM_REFERENCE(cond); } while (0)
+#define DHD_STATLOG_DATA_RSN(dhdp, stat, ifidx, dir, reason) \
+	do { /* noop */ } while (0)
+#endif /* DHD_STATUS_LOGGING */
+
+#ifdef SUPPORT_SET_TID
+enum dhd_set_tid_mode {
+	/* Disalbe changing TID */
+	SET_TID_OFF = 0,
+	/* Change TID for all UDP frames */
+	SET_TID_ALL_UDP,
+	/* Change TID for UDP frames based on UID */
+	SET_TID_BASED_ON_UID
+};
+
+#define DEFAULT_SET_TID_TARGET_UID	0
+#define DEFAULT_SET_TID_TARGET_PRIO	0
+#if defined(linux) || defined(LINUX)
+extern void dhd_set_tid_based_on_uid(dhd_pub_t *dhdp, void *pkt);
+#else
+static INLINE void dhd_set_tid_based_on_uid(dhd_pub_t *dhdp, void *pkt) { return; }
+#endif /* linux || LINUX */
+#endif /* SUPPORT_SET_TID */
+
+#ifdef CONFIG_SILENT_ROAM
+extern int dhd_sroam_set_mon(dhd_pub_t *dhd, bool set);
+typedef wlc_sroam_info_v1_t wlc_sroam_info_t;
+#endif /* CONFIG_SILENT_ROAM */
+
+#ifdef DHD_DUMP_FILE_WRITE_FROM_KERNEL
+#define FILE_NAME_HAL_TAG	""
+#else
+#define FILE_NAME_HAL_TAG	"_hal" /* The tag name concatenated by HAL */
+#endif /* DHD_DUMP_FILE_WRITE_FROM_KERNEL */
+
+void dhd_bus_counters(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
+
+#define DHD_HISTOGRAM_ENTRIES	(14u)
+#define DHD_HISTOGRAM_SIZE	(sizeof(uint64) * DHD_HISTOGRAM_ENTRIES)
+
+void dhd_histo_update(dhd_pub_t *dhd, uint64 *histo, uint32 value);
+void dhd_histo_clear(dhd_pub_t *dhd, uint64 *histo);
+void dhd_histo_tag_dump(dhd_pub_t *dhd, struct bcmstrbuf *strbuf, char *tagname);
+void dhd_histo_dump(dhd_pub_t *dhd, struct bcmstrbuf *strbuf, uint64 *histo, char *histoname);
+uint64 *dhd_histo_init(dhd_pub_t *dhd);
+void dhd_histo_deinit(dhd_pub_t *dhd, uint64 *histo);
+
+/* Given a number 'n' returns 'm' that is next larger power of 2 after n */
+static inline uint32 next_larger_power2(uint32 num)
+{
+	if (num) {
+		num--;
+		num |= (num >> 1);
+		num |= (num >> 2);
+		num |= (num >> 4);
+		num |= (num >> 8);
+		num |= (num >> 16);
+	}
+	return (num + 1);
+}
+
+extern struct dhd_if * dhd_get_ifp(dhd_pub_t *dhdp, uint32 ifidx);
+uint8 dhd_d11_slices_num_get(dhd_pub_t *dhdp);
+
+extern void *dhd_get_roam_evt(dhd_pub_t *dhdp);
+#if defined(DISABLE_HE_ENAB) || defined(CUSTOM_CONTROL_HE_ENAB)
+extern int dhd_control_he_enab(dhd_pub_t * dhd, uint8 he_enab);
+extern uint8 control_he_enab;
+#endif /* DISABLE_HE_ENAB  || CUSTOM_CONTROL_HE_ENAB */
+
+#ifdef DHD_SDTC_ETB_DUMP
+
+#define DHD_SDTC_ETB_MEMPOOL_SIZE (33 * 1024)
+extern int dhd_sdtc_etb_mempool_init(dhd_pub_t *dhd);
+extern void dhd_sdtc_etb_mempool_deinit(dhd_pub_t *dhd);
+extern void dhd_sdtc_etb_init(dhd_pub_t *dhd);
+extern void dhd_sdtc_etb_deinit(dhd_pub_t *dhd);
+extern void dhd_sdtc_etb_dump(dhd_pub_t *dhd);
+extern int dhd_sdtc_etb_hal_file_dump(void *dev, const void *user_buf, uint32 len);
+#endif /* DHD_SDTC_ETB_DUMP */
+
+#ifdef DHD_TX_PROFILE
+/* whether or not a dhd_tx_profile_protocol_t matches with data in a packet */
+bool dhd_protocol_matches_profile(uint8 *p, int plen,
+	const dhd_tx_profile_protocol_t *proto, bool is_host_sfhllc);
+int dhd_tx_profile_attach(dhd_pub_t *dhdp);
+int dhd_tx_profile_detach(dhd_pub_t *dhdp);
+#endif /* defined (DHD_TX_PROFILE) */
+#if defined(DHD_LB_RXP)
+uint32 dhd_lb_rxp_process_qlen(dhd_pub_t *dhdp);
+/*
+ * To avoid OOM, Flow control will be kicked in when packet size in process_queue
+ * crosses LB_RXP_STOP_THR * rcpl ring size * 1500(pkt size) and will stop
+ * when it goes below LB_RXP_STRT_THR * rcpl ring size * 1500(pkt size)
+ * By default flow control is diabled. i.e tunables set to 0/0.
+ * to enable flow control, these tunables need to be passed from platform Makefiles.
+ */
+#ifndef LB_RXP_STOP_THR
+#define LB_RXP_STOP_THR 0
+#endif /* LB_RXP_STOP_THR */
+#ifndef LB_RXP_STRT_THR
+#define LB_RXP_STRT_THR 0
+#endif /* LB_RXP_STRT_THR */
+
+#endif /* DHD_LB_RXP */
+#ifdef DHD_SUPPORT_HDM
+extern bool hdm_trigger_init;
+extern int dhd_module_init_hdm(void);
+extern void dhd_hdm_wlan_sysfs_init(void);
+extern void dhd_hdm_wlan_sysfs_deinit(struct work_struct *);
+extern int hdm_wifi_support;
+#define SYSFS_DEINIT_MS 10
+#endif /* DHD_SUPPORT_HDM */
+
+#if defined(linux) || defined(LINUX)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) && defined(DHD_TCP_LIMIT_OUTPUT)
+void dhd_ctrl_tcp_limit_output_bytes(int level);
+#endif /* LINUX_VERSION_CODE > 4.19.0 && DHD_TCP_LIMIT_OUTPUT */
+#endif /* linux || LINUX */
+
+#if defined(__linux__)
+extern void dhd_schedule_delayed_dpc_on_dpc_cpu(dhd_pub_t *dhdp, ulong delay);
+extern void dhd_handle_pktdata(dhd_pub_t *dhdp, int ifidx, void *pkt, uint8 *pktdata,
+	uint32 pktid, uint32 pktlen, uint16 *pktfate, uint8 *dhd_udr, uint8 *dhd_igmp,
+	bool tx, int pkt_wake, bool pkt_log);
+#else
+static INLINE void dhd_schedule_delayed_dpc_on_dpc_cpu(dhd_pub_t *dhdp, ulong delay)
+	{ return; }
+static INLINE void dhd_handle_pktdata(dhd_pub_t *dhdp, int ifidx, void *pkt, uint8 *pktdata,
+	uint32 pktid, uint32 pktlen, uint16 *pktfate, uint8 *dhd_udr, uint8 *dhd_igmp,
+	bool tx, int pkt_wake, bool pkt_log) { return; }
+#endif /* __linux */
+
+#if defined(BCMPCIE) && defined(__linux__)
+extern int dhd_check_shinfo_nrfrags(dhd_pub_t *dhdp, void *pktbuf, dmaaddr_t *pa, uint32 pktid);
+#else
+static INLINE int dhd_check_shinfo_nrfrags(dhd_pub_t *dhdp, void *pktbuf, dmaaddr_t *pa,
+	uint32 pktid) { return BCME_OK; }
+#endif /* BCMPCIE && __linux__ */
+
+int dhd_schedule_socram_dump(dhd_pub_t *dhdp);
+
+extern int dhd_dev_set_accel_force_reg_on(struct net_device *dev);
+
+#if defined(DHD_DEBUGABILITY_LOG_DUMP_RING) || defined(DHD_DEBUGABILITY_EVENT_RING)
+#ifndef DEBUGABILITY
+#error "DHD_DEBUGABILITY_LOG_DUMP_RING or DHD_DEBUGABILITY_EVENT_RING without DEBUGABILITY"
+#endif /* DEBUGABILITY */
+#endif /* defined(DHD_DEBUGABILITY_LOG_DUMP_RING) || defined(DHD_DEBUGABILITY_EVENT_RING) */
+#ifdef WL_CFGVENDOR_SEND_ALERT_EVENT
+typedef enum dhd_alert_reason_codes {
+	ALERT_BCN_LOST = 0,
+	ALERT_TX_STALL = 1,
+	ALERT_RX_STALL = 2,
+	ALERT_IOCTL_TIMEOUT = 3,
+	ALERT_DONGLE_TRAP = 4,
+	ALERT_SCAN_STALL = 5,
+	ALERT_SCAN_ERR = 6,
+	ALERT_SCAN_BUSY = 7,
+	ALERT_FW_QUEUE_STALL = 8
+} dhd_alert_reason_codes_t;
+int dhd_os_send_alert_message(dhd_pub_t *dhdp);
+#endif /* WL_CFGVENDOR_SEND_ALERT_EVENT */
+
+#ifdef RX_PKT_POOL
+#define MAX_RX_PKT_POOL	(1024)
+void dhd_rx_pktpool_create(struct dhd_info *dhd, uint16 len);
+void * BCMFASTPATH(dhd_rxpool_pktget)(osl_t *osh, struct dhd_info *dhd, uint16 len);
+#endif /* RX_PKT_POOL */
+
+int dhd_rxf_thread(void *data);
+void dhd_sched_rxf(dhd_pub_t *dhdp, void *skb);
+int dhd_os_wake_lock_rx_timeout_enable(dhd_pub_t *pub, int val);
+
+#if defined(__linux__)
+#ifdef DHD_SUPPORT_VFS_CALL
+static INLINE struct file *dhd_filp_open(const char *filename, int flags, int mode)
+{
+	return filp_open(filename, flags, mode);
+}
+
+static INLINE int dhd_filp_close(void *image, void *id)
+{
+	return filp_close((struct file *)image, id);
+}
+
+static INLINE int dhd_i_size_read(const struct inode *inode)
+{
+	return i_size_read(inode);
+}
+
+static INLINE int dhd_kernel_read_compat(struct file *fp, loff_t pos, void *buf, size_t count)
+{
+	return kernel_read_compat(fp, pos, buf, count);
+}
+
+static INLINE int dhd_vfs_read(struct file *filep, char *buf, size_t size, loff_t *pos)
+{
+	return vfs_read(filep, buf, size, pos);
+}
+
+static INLINE int dhd_vfs_write(struct file *filep, char *buf, size_t size, loff_t *pos)
+{
+	return vfs_write(filep, buf, size, pos);
+}
+
+static INLINE int dhd_vfs_fsync(struct file *filep, int datasync)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
+	return vfs_fsync(filep, datasync);
+#else
+	return vfs_fsync(filep, filep->f_path.dentry, 0);
+#endif
+}
+
+static INLINE long dhd_vfs_size_read(struct file *fp)
+{
+	return dhd_i_size_read(file_inode(fp));
+}
+
+static INLINE int dhd_kern_path(char *name, int flags, struct path *file_path)
+{
+	return kern_path(name, flags, file_path);
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0))
+#define DHD_VFS_INODE(dir) (dir->d_inode)
+#else
+#define DHD_VFS_INODE(dir) d_inode(dir)
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) && \
+	(RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7, 6))
+#define DHD_VFS_UNLINK(dir, file_path, c) vfs_unlink(DHD_VFS_INODE(dir), file_path.dentry)
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0))
+#define DHD_VFS_UNLINK(dir, file_path, c)  \
+	vfs_unlink(mnt_idmap(file_path.mnt), DHD_VFS_INODE(dir), file_path.dentry, c)
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 12, 0))
+#define DHD_VFS_UNLINK(dir, file_path, c)  \
+	vfs_unlink(mnt_user_ns(file_path.mnt), DHD_VFS_INODE(dir), file_path.dentry, c)
+#else
+#define DHD_VFS_UNLINK(dir, file_path, c) vfs_unlink(DHD_VFS_INODE(dir), file_path.dentry, c)
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0) */
+#else
+#define DHD_VFS_UNLINK(dir, file_path, c) 0
+
+static INLINE struct file *dhd_filp_open(const char *filename, int flags, int mode)
+	{ printf("%s: DHD_SUPPORT_VFS_CALL not defined\n", __FUNCTION__); return NULL; }
+static INLINE int dhd_filp_close(void *image, void *id)
+	{ return 0; }
+static INLINE int dhd_i_size_read(const struct inode *inode)
+	{ return 0; }
+static INLINE int dhd_kernel_read_compat(struct file *fp, loff_t pos, void *buf, size_t count)
+	{ return 0; }
+static INLINE int dhd_vfs_read(struct file *filep, char *buf, size_t size, loff_t *pos)
+	{ return 0; }
+static INLINE int dhd_vfs_write(struct file *filep, char *buf, size_t size, loff_t *pos)
+	{ return 0; }
+static INLINE int dhd_vfs_fsync(struct file *filep, int datasync)
+	{ return 0; }
+static INLINE long dhd_vfs_size_read(struct file *fp)
+	{ return 0; }
+static INLINE int dhd_kern_path(char *name, int flags, struct path *file_path)
+	{ return 0; }
+#endif /* DHD_SUPPORT_VFS_CALL */
+#endif /* __linux__ */
+#ifdef WL_TWT
+extern int dhd_config_twt_event_mask_in_suspend(dhd_pub_t *dhdp, bool suspend);
+extern int dhd_send_twt_info_suspend(dhd_pub_t *dhdp, bool suspend);
+#endif /* WL_TWT */
+#if defined(DHD_WAKE_STATUS_PRINT) && defined(DHD_WAKE_RX_STATUS) && \
+	defined(DHD_WAKE_STATUS)
+void dhd_dump_wake_status(dhd_pub_t *dhdp, wake_counts_t *wcp, struct ether_header *eh);
+#endif /* DHD_WAKE_STATUS_PRINT && DHD_WAKE_RX_STATUS && DHD_WAKE_STATUS */
+#ifdef SUPPORT_OTA_UPDATE
+void dhd_ota_buf_clean(dhd_pub_t *dhdp);
+#endif /* SUPPORT_OTA_UPDATE */
+#if !defined(AP) && defined(WLP2P)
+extern uint32 dhd_get_concurrent_capabilites(dhd_pub_t *dhd);
+#endif
+#ifdef DHD_CUSTOM_CONFIG_RTS_IN_SUSPEND
+#ifndef CUSTOM_RETRUN_TO_SLEEP_TIME_SUSPEND
+#define CUSTOM_RETRUN_TO_SLEEP_TIME_SUSPEND 20
+#endif
+#ifndef CUSTOM_RETRUN_TO_SLEEP_TIME_DEFAULT
+#define CUSTOM_RETRUN_TO_SLEEP_TIME_DEFAULT 200
+#endif
+int dhd_config_rts_in_suspend(dhd_pub_t *dhdp, bool suspend);
+#endif /* DHD_CUSTOM_CONFIG_RTS_IN_SUSPEND */
+
+extern void dhd_unregister_net(struct net_device *net, bool need_rtnl_lock);
+extern int dhd_register_net(struct net_device *net, bool need_rtnl_lock);
+
+#if defined(DHD_HWTSTAMP)
+extern int dhd_hwtstamp_txtype(dhd_pub_t *dhdp);
+#endif /* DHD_HWTSTAMP */
+
+#ifdef WL_MONITOR
+void dhd_set_monitor(dhd_pub_t *pub, int ifidx, int val);
+#if defined(BCMSDIO) || defined(BCMDBUS)
+extern void dhd_rx_mon_pkt_sdio(dhd_pub_t *dhdp, void *pkt, int ifidx);
+bool dhd_monitor_enabled(dhd_pub_t *dhd, int ifidx);
+#endif /* BCMSDIO || BCMDBUS */
+#endif /* WL_MONITOR */
+int dhd_pm_callback(
+#ifdef DEVICE_PM_CALLBACK
+	dhd_pub_t *dhd,
+#else
+	struct notifier_block *nfb,
+#endif
+	unsigned long action, void *ignored);
+#endif /* _dhd_h_ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_bitpack.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_bitpack.h
@@ -0,0 +1,52 @@
+/*
+ * Bit packing and Base64 utils for EWP
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef __BITPACK_H_
+#define __BITPACK_H_
+
+#define BYTE_SIZE(a) ((a + 7)/8)
+
+extern int32 dhd_bit_pack(char *buf, int32 buf_len, int bit_offset, uint32 data, int32 bit_length);
+extern int32 dhd_base64_encode(char* in_buf, int32 in_buf_len, char* out_buf, int32 out_buf_len);
+#endif /* __BITPACK_H */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_bus.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_bus.h
@@ -0,0 +1,453 @@
+/*
+ * Header file describing the internal (inter-module) DHD interfaces.
+ *
+ * Provides type definitions and function prototypes used to link the
+ * DHD OS, bus, and protocol modules.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef _dhd_bus_h_
+#define _dhd_bus_h_
+
+extern int dbus_up(struct dhd_bus *pub);
+extern int dbus_stop(struct dhd_bus *pub);
+/*
+ * Exported from dhd bus module (dhd_usb, dhd_sdio)
+ */
+
+/* global variable for the bus */
+extern struct dhd_bus *g_dhd_bus;
+
+/* Indicate (dis)interest in finding dongles. */
+extern int dhd_bus_register(void);
+extern void dhd_bus_unregister(void);
+
+/* Download firmware image and nvram image */
+extern int dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh,
+	char *fw_path, char *nv_path, char *clm_path, char *conf_path);
+#if defined(BT_OVER_SDIO)
+extern int dhd_bus_download_btfw(struct dhd_bus *bus, osl_t *osh, char *btfw_path);
+#endif /* defined (BT_OVER_SDIO) */
+
+/* Stop bus module: clear pending frames, disable data flow */
+extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex);
+
+/* Initialize bus module: prepare for communication w/dongle */
+extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex);
+
+/* Get the Bus Idle Time */
+extern void dhd_bus_getidletime(dhd_pub_t *dhdp, int *idletime);
+
+/* Set the Bus Idle Time */
+extern void dhd_bus_setidletime(dhd_pub_t *dhdp, int idle_time);
+
+/* Send a data frame to the dongle.  Callee disposes of txp. */
+#ifdef BCMPCIE
+extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp, uint8 ifidx);
+#else
+extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp);
+#endif
+
+#ifdef BCMPCIE
+extern uint16 dhd_prot_get_rxbufpost_sz(dhd_pub_t *dhd);
+extern uint16 dhd_prot_get_rxbufpost_alloc_sz(dhd_pub_t *dhd);
+extern uint16 dhd_prot_get_h2d_rx_post_active(dhd_pub_t *dhd);
+extern uint16 dhd_prot_get_d2h_rx_cpln_active(dhd_pub_t *dhd);
+extern void dhdpcie_cto_recovery_handler(dhd_pub_t *dhd);
+#endif /* BCMPCIE */
+
+/* Send/receive a control message to/from the dongle.
+ * Expects caller to enforce a single outstanding transaction.
+ */
+extern int dhd_bus_txctl(struct dhd_bus *bus, uchar *msg, uint msglen);
+extern int dhd_bus_rxctl(struct dhd_bus *bus, uchar *msg, uint msglen);
+
+/* Watchdog timer function */
+extern bool dhd_bus_watchdog(dhd_pub_t *dhd);
+
+extern int dhd_bus_oob_intr_register(dhd_pub_t *dhdp);
+extern void dhd_bus_oob_intr_unregister(dhd_pub_t *dhdp);
+extern void dhd_bus_oob_intr_set(dhd_pub_t *dhdp, bool enable);
+extern int dhd_bus_get_oob_irq_num(dhd_pub_t *dhdp);
+extern struct device * dhd_bus_to_dev(struct dhd_bus *bus);
+extern void dhd_bus_dev_pm_stay_awake(dhd_pub_t *dhdpub);
+extern void dhd_bus_dev_pm_relax(dhd_pub_t *dhdpub);
+extern bool dhd_bus_dev_pm_enabled(dhd_pub_t *dhdpub);
+
+/* Device console input function */
+extern int dhd_bus_console_in(dhd_pub_t *dhd, uchar *msg, uint msglen);
+#ifdef CONSOLE_DPC
+extern int dhd_bus_txcons(dhd_pub_t *dhd, uchar *msg, uint msglen);
+#endif
+
+/* Deferred processing for the bus, return TRUE requests reschedule */
+extern bool dhd_bus_dpc(struct dhd_bus *bus);
+extern void dhd_bus_isr(bool * InterruptRecognized, bool * QueueMiniportHandleInterrupt, void *arg);
+
+/* Check for and handle local prot-specific iovar commands */
+extern int dhd_bus_iovar_op(dhd_pub_t *dhdp, const char *name,
+                            void *params, uint plen, void *arg, uint len, bool set);
+
+/* Add bus dump output to a buffer */
+extern void dhd_bus_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
+extern void dhd_bus_dump_flowring(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf);
+
+/* Clear any bus counters */
+extern void dhd_bus_clearcounts(dhd_pub_t *dhdp);
+
+/* return the dongle chipid */
+extern uint dhd_bus_chip(struct dhd_bus *bus);
+
+/* return the dongle chiprev */
+extern uint dhd_bus_chiprev(struct dhd_bus *bus);
+
+/* Set user-specified nvram parameters. */
+extern void dhd_bus_set_nvram_params(struct dhd_bus * bus, const char *nvram_params);
+
+extern void *dhd_bus_pub(struct dhd_bus *bus);
+extern void *dhd_bus_txq(struct dhd_bus *bus);
+extern void *dhd_bus_sih(struct dhd_bus *bus);
+extern uint dhd_bus_hdrlen(struct dhd_bus *bus);
+#ifdef BCMSDIO
+extern void dhd_bus_set_dotxinrx(struct dhd_bus *bus, bool val);
+/* return sdio io status */
+extern uint8 dhd_bus_is_ioready(struct dhd_bus *bus);
+#else
+#define dhd_bus_set_dotxinrx(a, b) do {} while (0)
+#endif
+
+#define DHD_SET_BUS_STATE_DOWN(_bus)  do { \
+	(_bus)->dhd->busstate = DHD_BUS_DOWN; \
+} while (0)
+
+/* Register a dummy SDIO client driver in order to be notified of new SDIO device */
+extern int dhd_bus_reg_sdio_notify(void* semaphore);
+extern void dhd_bus_unreg_sdio_notify(void);
+extern void dhd_txglom_enable(dhd_pub_t *dhdp, bool enable);
+extern int dhd_bus_get_ids(struct dhd_bus *bus, uint32 *bus_type, uint32 *bus_num,
+	uint32 *slot_num);
+
+#if defined(DHD_FW_COREDUMP) && (defined(BCMPCIE) || defined(BCMSDIO))
+extern int dhd_bus_mem_dump(dhd_pub_t *dhd);
+extern int dhd_bus_get_mem_dump(dhd_pub_t *dhdp);
+#else
+#define dhd_bus_mem_dump(x)
+#define dhd_bus_get_mem_dump(x)
+#endif /* DHD_FW_COREDUMP && (BCMPCIE || BCMSDIO) */
+
+#ifdef BCMPCIE
+enum {
+	/* Scratch buffer confiuguration update */
+	D2H_DMA_SCRATCH_BUF,
+	D2H_DMA_SCRATCH_BUF_LEN,
+
+	/* DMA Indices array buffers for: H2D WR and RD, and D2H WR and RD */
+	H2D_DMA_INDX_WR_BUF, /* update H2D WR dma indices buf base addr to dongle */
+	H2D_DMA_INDX_RD_BUF, /* update H2D RD dma indices buf base addr to dongle */
+	D2H_DMA_INDX_WR_BUF, /* update D2H WR dma indices buf base addr to dongle */
+	D2H_DMA_INDX_RD_BUF, /* update D2H RD dma indices buf base addr to dongle */
+
+	/* DHD sets/gets WR or RD index, in host's H2D and D2H DMA indices buffer */
+	H2D_DMA_INDX_WR_UPD, /* update H2D WR index in H2D WR dma indices buf */
+	H2D_DMA_INDX_RD_UPD, /* update H2D RD index in H2D RD dma indices buf */
+	D2H_DMA_INDX_WR_UPD, /* update D2H WR index in D2H WR dma indices buf */
+	D2H_DMA_INDX_RD_UPD, /* update D2H RD index in D2H RD dma indices buf */
+
+	/* DHD Indices array buffers and update for: H2D flow ring WR */
+	H2D_IFRM_INDX_WR_BUF, /* update H2D WR dma indices buf base addr to dongle */
+	H2D_IFRM_INDX_WR_UPD, /* update H2D WR dma indices buf base addr to dongle */
+
+	/* H2D and D2H Mailbox data update */
+	H2D_MB_DATA,
+	D2H_MB_DATA,
+
+	/* (Common) MsgBuf Ring configuration update */
+	RING_BUF_ADDR,       /* update ring base address to dongle */
+	RING_ITEM_LEN,       /* update ring item size to dongle */
+	RING_MAX_ITEMS,      /* update ring max items to dongle */
+
+	/* Update of WR or RD index, for a MsgBuf Ring */
+	RING_RD_UPD,         /* update ring read index from/to dongle */
+	RING_WR_UPD,         /* update ring write index from/to dongle */
+
+	TOTAL_LFRAG_PACKET_CNT,
+	MAX_HOST_RXBUFS,
+	HOST_API_VERSION,
+#ifdef D2H_MINIDUMP
+	DNGL_TO_HOST_TRAP_ADDR_LEN,
+#endif /* D2H_MINIDUMP */
+	DNGL_TO_HOST_TRAP_ADDR,
+	HOST_SCB_ADDR,		/* update host scb base address to dongle */
+	HOST_CAP2,		/* Host capability 2 flags */
+};
+
+typedef void (*dhd_mb_ring_t) (struct dhd_bus *, uint32);
+typedef void (*dhd_mb_ring_2_t) (struct dhd_bus *, uint32, bool);
+extern void dhd_bus_cmn_writeshared(struct dhd_bus *bus, void * data, uint32 len, uint8 type,
+	uint16 ringid);
+extern void dhd_bus_ringbell(struct dhd_bus *bus, uint32 value);
+extern void dhd_bus_ringbell_2(struct dhd_bus *bus, uint32 value, bool devwake);
+extern void dhd_bus_cmn_readshared(struct dhd_bus *bus, void* data, uint8 type, uint16 ringid);
+extern uint32 dhd_bus_get_sharedflags(struct dhd_bus *bus);
+extern void dhd_bus_rx_frame(struct dhd_bus *bus, void* pkt, int ifidx, uint pkt_count);
+extern void dhd_bus_start_queue(struct dhd_bus *bus);
+extern void dhd_bus_stop_queue(struct dhd_bus *bus);
+extern dhd_mb_ring_t dhd_bus_get_mbintr_fn(struct dhd_bus *bus);
+extern dhd_mb_ring_2_t dhd_bus_get_mbintr_2_fn(struct dhd_bus *bus);
+extern void dhd_bus_write_flow_ring_states(struct dhd_bus *bus,
+	void * data, uint16 flowid);
+extern void dhd_bus_read_flow_ring_states(struct dhd_bus *bus,
+	void * data, uint8 flowid);
+extern int dhd_bus_flow_ring_create_request(struct dhd_bus *bus, void *flow_ring_node);
+extern void dhd_bus_clean_flow_ring(struct dhd_bus *bus, void *flow_ring_node);
+extern void dhd_bus_flow_ring_create_response(struct dhd_bus *bus, uint16 flow_id, int32 status);
+extern int dhd_bus_flow_ring_delete_request(struct dhd_bus *bus, void *flow_ring_node);
+extern void dhd_bus_flow_ring_delete_response(struct dhd_bus *bus, uint16 flowid, uint32 status);
+extern int dhd_bus_flow_ring_flush_request(struct dhd_bus *bus, void *flow_ring_node);
+extern void dhd_bus_flow_ring_flush_response(struct dhd_bus *bus, uint16 flowid, uint32 status);
+extern uint32 dhd_bus_max_h2d_queues(struct dhd_bus *bus);
+extern int dhd_bus_schedule_queue(struct dhd_bus *bus, uint16 flow_id, bool txs,
+		uint32 bound, bool *is_qempty);
+
+#ifdef IDLE_TX_FLOW_MGMT
+extern void dhd_bus_flow_ring_resume_response(struct dhd_bus *bus, uint16 flowid, int32 status);
+#endif /* IDLE_TX_FLOW_MGMT */
+
+#ifdef BCMDBG
+extern void
+dhd_bus_flow_ring_cnt_update(struct dhd_bus *bus, uint16 flowid, uint32 txstatus);
+#endif
+
+#if defined(LINUX) || defined(linux)
+extern int dhdpcie_bus_start_host_dev(struct dhd_bus *bus);
+extern int dhdpcie_bus_stop_host_dev(struct dhd_bus *bus);
+extern int dhdpcie_bus_enable_device(struct dhd_bus *bus);
+extern int dhdpcie_bus_disable_device(struct dhd_bus *bus);
+extern int dhdpcie_bus_alloc_resource(struct dhd_bus *bus);
+extern void dhdpcie_bus_free_resource(struct dhd_bus *bus);
+extern bool dhdpcie_bus_dongle_attach(struct dhd_bus *bus);
+extern int dhd_bus_release_dongle(struct dhd_bus *bus);
+extern int dhd_bus_request_irq(struct dhd_bus *bus);
+extern int dhdpcie_get_pcieirq(struct dhd_bus *bus, unsigned int *irq);
+extern void dhd_bus_aer_config(struct dhd_bus *bus);
+#else
+static INLINE void dhd_bus_aer_config(struct dhd_bus *bus) { }
+#endif /* LINUX || linux */
+
+extern int dhdpcie_cto_init(struct dhd_bus *bus, bool enable);
+extern int dhdpcie_cto_cfg_init(struct dhd_bus *bus, bool enable);
+
+extern void dhdpcie_ssreset_dis_enum_rst(struct dhd_bus *bus);
+
+#ifdef DHD_FW_COREDUMP
+extern int dhd_dongle_mem_dump(void);
+#endif /* DHD_FW_COREDUMP */
+
+#ifdef IDLE_TX_FLOW_MGMT
+extern void dhd_bus_idle_tx_ring_suspend(dhd_pub_t *dhd, uint16 flow_ring_id);
+#endif /* IDLE_TX_FLOW_MGMT */
+extern void dhd_bus_handle_mb_data(struct dhd_bus *bus, uint32 d2h_mb_data);
+#endif /* BCMPCIE */
+
+/* dump the device trap informtation  */
+extern void dhd_bus_dump_trap_info(struct dhd_bus *bus, struct bcmstrbuf *b);
+extern void dhd_bus_copy_trap_sig(struct dhd_bus *bus,  trap_t *tr);
+#ifdef WL_CFGVENDOR_SEND_HANG_EVENT
+void copy_hang_info_linkdown(dhd_pub_t *dhd);
+void copy_ext_trap_sig(dhd_pub_t *dhd, trap_t *tr);
+void copy_hang_info_trap(dhd_pub_t *dhd);
+#endif /* WL_CFGVENDOR_SEND_HANG_EVENT */
+
+/* Function to set default min res mask */
+extern bool dhd_bus_set_default_min_res_mask(struct dhd_bus *bus);
+
+/* Function to reset PMU registers */
+extern void dhd_bus_pmu_reg_reset(dhd_pub_t *dhdp);
+
+extern void dhd_bus_ucode_download(struct dhd_bus *bus);
+
+extern int dhd_bus_readwrite_bp_addr(dhd_pub_t *dhdp, uint addr, uint size, uint* data, bool read);
+extern int dhd_get_idletime(dhd_pub_t *dhd);
+extern bool dhd_get_rpm_state(dhd_pub_t *dhd);
+extern void dhd_set_rpm_state(dhd_pub_t *dhd, bool state);
+#ifdef BCMPCIE
+extern void dhd_bus_dump_console_buffer(struct dhd_bus *bus);
+extern void dhd_bus_intr_count_dump(dhd_pub_t *dhdp);
+extern bool dhd_bus_query_dpc_sched_errors(dhd_pub_t *dhdp);
+extern int dhd_bus_dmaxfer_lpbk(dhd_pub_t *dhdp, uint32 type);
+extern bool dhd_bus_check_driver_up(void);
+extern int dhd_bus_get_cto(dhd_pub_t *dhdp);
+extern bool dhd_bus_get_read_shm(dhd_pub_t *dhdp);
+extern void dhd_bus_set_linkdown(dhd_pub_t *dhdp, bool val);
+extern int dhd_bus_get_linkdown(dhd_pub_t *dhdp);
+#if defined(CONFIG_ARCH_MSM) && defined(CONFIG_SEC_PCIE_L1SS)
+extern void dhd_bus_inform_ep_loaded_to_rc(dhd_pub_t *dhdp, bool up);
+#endif /* CONFIG_ARCH_MSM  && CONFIG_SEC_PCIE_L1SS */
+extern int dhd_bus_checkdied(struct dhd_bus *bus, char *data, uint size);
+#else
+#define dhd_bus_dump_console_buffer(x)
+static INLINE void dhd_bus_intr_count_dump(dhd_pub_t *dhdp) { UNUSED_PARAMETER(dhdp); }
+static INLINE bool dhd_bus_query_dpc_sched_errors(dhd_pub_t *dhdp) { return 0; }
+static INLINE int dhd_bus_dmaxfer_lpbk(dhd_pub_t *dhdp, uint32 type) { return 0; }
+static INLINE bool dhd_bus_check_driver_up(void) { return FALSE; }
+static INLINE void dhd_bus_set_linkdown(dhd_pub_t *dhdp, bool val) { }
+static INLINE int dhd_bus_get_linkdown(dhd_pub_t *dhdp) { return 0; }
+static INLINE int dhd_bus_get_cto(dhd_pub_t *dhdp) { return 0; }
+static INLINE bool dhd_bus_get_read_shm(dhd_pub_t *dhdp) { return 0; }
+static INLINE int dhd_bus_checkdied(struct dhd_bus *bus, char *data, uint size) { return 0; }
+#endif /* BCMPCIE */
+
+#if defined(BCMPCIE) && defined(EWP_ETD_PRSRV_LOGS)
+void dhdpcie_get_etd_preserve_logs(dhd_pub_t *dhd, uint8 *ext_trap_data,
+		void *event_decode_data);
+#endif
+
+extern uint16 dhd_get_chipid(struct dhd_bus *bus);
+extern uint16 dhd_get_chiprev(struct dhd_bus *bus);
+
+#ifdef DHD_WAKE_STATUS
+extern wake_counts_t* dhd_bus_get_wakecount(dhd_pub_t *dhd);
+extern int dhd_bus_get_bus_wake(dhd_pub_t * dhd);
+extern int dhd_bus_set_get_bus_wake(dhd_pub_t * dhd, int set);
+#if defined(BCMPCIE)
+extern int dhd_bus_set_get_bus_wake_pkt_dump(dhd_pub_t *dhd, int wake_pkt_dump);
+#endif /* BCMPCIE */
+#endif /* DHD_WAKE_STATUS */
+
+#ifdef BT_OVER_SDIO
+/*
+ * SDIO layer clock control functions exposed to be called from other layers.
+ * This is required especially in the case where the BUS is shared between
+ * BT and SDIO and we have to control the clock. The callers of this function
+ * are expected to hold the sdlock
+ */
+int __dhdsdio_clk_enable(struct dhd_bus *bus, bus_owner_t owner, int can_wait);
+int __dhdsdio_clk_disable(struct dhd_bus *bus, bus_owner_t owner, int can_wait);
+void dhdsdio_reset_bt_use_count(struct dhd_bus *bus);
+#endif /* BT_OVER_SDIO */
+
+int dhd_bus_perform_flr(struct dhd_bus *bus, bool force_fail);
+extern bool dhd_bus_get_flr_force_fail(struct dhd_bus *bus);
+
+extern bool dhd_bus_aspm_enable_rc_ep(struct dhd_bus *bus, bool enable);
+extern bool dhd_bus_is_aspm_enab_rc_ep(struct dhd_bus *bus);
+extern void dhd_bus_l1ss_enable_rc_ep(struct dhd_bus *bus, bool enable);
+extern bool dhd_bus_is_l1ss_enab_rc_ep(struct dhd_bus *bus);
+
+bool dhd_bus_is_multibp_capable(struct dhd_bus *bus);
+
+#ifdef BCMPCIE
+extern void dhdpcie_advertise_bus_cleanup(dhd_pub_t  *dhdp);
+extern void dhd_msgbuf_iovar_timeout_dump(dhd_pub_t *dhd);
+extern void dhdpcie_induce_cbp_hang(dhd_pub_t *dhd);
+extern void dhdpcie_busbusy_wait(dhd_pub_t *dhdp);
+extern int dhd_dump_flowrings(dhd_pub_t *dhdp, char *buf, int buflen);
+#endif /* BCMPCIE */
+
+extern bool dhd_bus_force_bt_quiesce_enabled(struct dhd_bus *bus);
+extern void dhd_bwm_bt_quiesce(struct dhd_bus *bus);
+extern void dhd_bwm_bt_resume(struct dhd_bus *bus);
+
+#ifdef DHD_SSSR_DUMP
+extern int dhd_bus_fis_trigger(dhd_pub_t *dhd);
+extern int dhd_bus_fis_dump(dhd_pub_t *dhd);
+#endif /* DHD_SSSR_DUMP */
+
+#ifdef PCIE_FULL_DONGLE
+extern int dhdpcie_set_dma_ring_indices(dhd_pub_t *dhd, int32 int_val);
+#endif /* PCIE_FULL_DONGLE */
+
+#ifdef D2H_MINIDUMP
+#ifndef DHD_FW_COREDUMP
+/* Minidump depends on DHD_FW_COREDUMP to dump minidup
+ * This dependency is intentional to avoid multiple work queue
+ * to dump the SOCRAM, minidum ..etc.
+ */
+#error "Minidump doesnot work as DHD_FW_COREDUMP is not defined"
+#endif /* DHD_FW_COREDUMP */
+#ifdef BCM_BUZZZ
+/*
+ * In pciedev_shared_t buzz_dbg_ptr and device_trap_debug_buffer_len
+ * are overloaded. So when BCM_BUZZZ is defined MINIDUMP should not be defined or
+ * vice versa.
+ */
+#error "Minidump doesnot work as BCM_BUZZZ is defined"
+#endif /* BCM_BUZZZ */
+extern bool dhd_bus_is_minidump_enabled(dhd_pub_t  *dhdp);
+dhd_dma_buf_t* dhd_prot_get_minidump_buf(dhd_pub_t *dhd);
+#endif /* D2H_MINIDUMP */
+
+#ifdef DHD_CFG80211_SUSPEND_RESUME
+extern void dhd_cfg80211_suspend(dhd_pub_t *dhdp);
+extern void dhd_cfg80211_resume(dhd_pub_t *dhdp);
+#endif /* DHD_CFG80211_SUSPEND_RESUME */
+
+#ifdef DHD_SDTC_ETB_DUMP
+extern int dhd_bus_get_etb_info(dhd_pub_t *dhd, uint32 etb_info_addr, etb_info_t *etb_info);
+extern int dhd_bus_get_sdtc_etb(dhd_pub_t *dhd, uint8 *sdtc_etb_mempool,
+	uint addr, uint read_bytes);
+#endif /* DHD_SDTC_ETB_DUMP */
+
+#ifndef BCMDBUS
+extern int dhd_socram_dump(struct dhd_bus *bus);
+#endif /* BCMDBUS */
+
+extern int dhdpcie_get_max_eventbufpost(struct dhd_bus *bus);
+
+#ifdef DHD_FLOW_RING_STATUS_TRACE
+extern void dhd_bus_flow_ring_status_isr_trace(dhd_pub_t *dhd);
+extern void dhd_bus_flow_ring_status_dpc_trace(dhd_pub_t *dhd);
+#endif /* DHD_FLOW_RING_STATUS_TRACE */
+
+extern bool dhd_bus_init_done(struct dhd_bus *bus);
+
+extern void dhdpcie_db7_trap(struct dhd_bus *bus);
+
+#if defined(NDIS)
+void * dhd_bus_get_socram_buf(struct dhd_bus *bus, struct dhd_pub *dhdp);
+#endif
+
+void dhd_bus_set_signature_path(struct dhd_bus *bus, char *sig_path);
+
+int dhdsdio_mpdu_init(dhd_pub_t *dhdp);
+
+#endif /* _dhd_bus_h_ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_ccode.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_ccode.c
@@ -0,0 +1,340 @@
+
+#ifdef CCODE_LIST
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+#endif /* COMFIG_COMPAT */
+#include <typedefs.h>
+#include <dhd_config.h>
+
+#ifdef BCMSDIO
+#define CCODE_43438
+#define CCODE_43436
+#define CCODE_43455C0
+#endif
+#if defined(BCMSDIO) || defined(BCMPCIE)
+#define CCODE_4356A2
+#define CCODE_4359C0
+#endif
+#if defined(BCMPCIE)
+//#define CCODE_4375B4
+#endif
+#ifdef BCMDBUS
+#define CCODE_4358U
+#endif
+
+#ifdef BCMSDIO
+#ifdef CCODE_43438
+const char ccode_43438[] = "RU/13";
+#else
+const char ccode_43438[] = "";
+#endif
+
+#ifdef CCODE_43436
+const char ccode_43436[] = \
+"AE/1 AR/1 AT/1 AU/2 "\
+"BE/1 BG/1 BN/1 "\
+"CA/2 CH/1 CN/38 CY/1 CZ/1 "\
+"DE/3 DK/1 "\
+"EE/1 ES/1 "\
+"FI/1 FR/1 "\
+"GB/1 GR/1 "\
+"HR/1 HU/1 "\
+"ID/5 IE/1 IS/1 IT/1 "\
+"JP/3 "\
+"KR/4 KW/1 "\
+"LI/1 LT/1 LU/1 LV/1 "\
+"MA/1 MT/1 MX/1 "\
+"NL/1 NO/1 "\
+"PL/1 PT/1 PY/1 "\
+"RO/1 RU/5 "\
+"SE/1 SI/1 SK/1 "\
+"TR/7 TW/2 "\
+"US/26 "\
+"XZ/11";
+#else
+const char ccode_43436[] = "";
+#endif
+
+#ifdef CCODE_43455C0
+const char ccode_43455c0[] = \
+"AE/6 AG/2 AI/1 AL/2 AS/12 AT/4 AU/6 AW/2 AZ/2 "\
+"BA/2 BD/1 BE/4 BG/4 BH/4 BM/12 BN/4 BR/2 BS/2 BY/3 "\
+"CA/2 CH/4 CN/38 CO/17 CR/17 CY/4 CZ/4 "\
+"DE/7 DK/4 "\
+"EC/21 EE/4 EG/13 ES/4 ET/2 "\
+"FI/4 FR/5 "\
+"GB/6 GD/2 GF/2 GP/2 GR/4 GT/1 GU/30 "\
+"HK/2 HR/4 HU/4 "\
+"ID/1 IE/5 IL/14 IN/3 IS/4 IT/4 "\
+"JO/3 JP/45 "\
+"KH/2 KR/96 KW/5 KY/3 "\
+"LA/2 LB/5 LI/4 LK/1 LS/2 LT/4 LU/3 LV/4 "\
+"MA/2 MC/1 MD/2 ME/2 MK/2 MN/1 MQ/2 MR/2 MT/4 MU/2 MV/3 MW/1 MX/44 MY/3 "\
+"NI/2 NL/4 NO/4 NZ/4 "\
+"OM/4 "\
+"PA/17 PE/20 PH/5 PL/4 PR/38 PT/4 PY/2 "\
+"Q2/993 "\
+"RE/2 RO/4 RS/2 RU/13 "\
+"SE/4 SI/4 SK/4 SV/25 "\
+"TH/5 TN/1 TR/7 TT/3 TW/65 "\
+"UA/8 US/988 "\
+"VA/2 VE/3 VG/2 VN/4 "\
+"XZ/11 "\
+"YT/2 "\
+"ZA/6";
+#else
+const char ccode_43455c0[] = "";
+#endif
+#endif
+
+#ifdef CCODE_4359C0
+const char ccode_4359c0[] = \
+"AD/1 AE/6 AG/2 AI/1 AL/3 AS/12 AT/21 AU/6 AW/2 AZ/8 "\
+"BA/4 BD/1 BE/19 BG/18 BH/4 BM/12 BN/4 BR/2 BS/2 BY/3 "\
+"CA/2 CN/38 CO/17 CR/17 CY/18 CZ/18 "\
+"DE/30 DK/19 "\
+"E0/32 EC/21 EE/18 EG/13 ES/21 ET/2 "\
+"FI/19 FR/21 "\
+"GB/996 GD/2 GE/1 GF/2 GP/2 GR/18 GT/1 GU/30 "\
+"HK/2 HR/18 HU/18 "\
+"ID/1 IE/21 IL/276 IN/3 IS/17 IT/20 "\
+"JO/3 JP/967 "\
+"KH/2 KR/70 KW/5 KY/3 "\
+"LA/2 LB/5 LI/17 LK/1 LS/2 LT/18 LU/18 LV/18 "\
+"MA/2 MC/2 MD/3 ME/5 MK/4 MN/1 MQ/2 MR/2 MT/18 MU/2 MV/3 MW/1 MX/44 MY/3 "\
+"NI/2 NL/19 NO/18 NZ/4 "\
+"OM/4 "\
+"PA/17 PE/20 PH/5 PL/18 PR/38 PT/20 PY/2 "\
+"Q1/947 Q2/993 "\
+"RE/2 RO/18 RS/4 RU/986 "\
+"SE/19 SI/18 SK/18 SM/1 SV/25 "\
+"TH/5 TN/1 TR/18 TT/3 TW/980 "\
+"UA/16 US/988 "\
+"VA/3 VE/3 VG/2 VN/4 "\
+"XZ/11 "\
+"YT/2 "\
+"ZA/6";
+#else
+const char ccode_4359c0[] = "";
+#endif
+
+#ifdef CCODE_4375B4
+const char ccode_4375b4[] = \
+"AE/6 AL/2 AM/1 AN/5 AR/21 AT/4 AU/6 AZ/2 "\
+"BA/2 BE/4 BG/4 BH/4 BN/4 BO/5 BR/17 BY/3 "\
+"CA/2 CH/4 CL/7 CN/38 CO/17 CR/17 CY/4 CZ/4 "\
+"DE/7 DK/4 DZ/2 EC/18 EE/4 EG/13 ES/4 "\
+"FI/4 FR/5 "\
+"GB/6 GR/4 "\
+"HK/999 HN/8 HR/4 HU/4 "\
+"ID/5 IE/5 IL/7 IN/3 IS/4 IT/4 "\
+"JO/3 JP/72 "\
+"KE/1 KR/96 KW/5 KZ/5 "\
+"LA/2 LB/5 LI/4 LK/2 LT/4 LU/4 LV/4 "\
+"MA/7 MC/1 ME/2 MK/2 MO/4 MT/4 MX/20 MY/19 "\
+"NL/4 NO/4 NZ/4 "\
+"OM/4 "\
+"PA/17 PE/20 PH/5 PK/2 PL/4 PR/20 PT/4 "\
+"RO/4 RU/62 "\
+"SA/5 SE/4 SG/12 SI/4 SK/4 SV/17 "\
+"TH/5 TN/1 TR/7 TT/3 TW/65 "\
+"UA/16 US/140 UY/10 "\
+"VE/3 VN/4 "\
+"XZ/11 "\
+"ZA/19";
+#else
+const char ccode_4375b4[] = "";
+#endif
+
+#ifdef CCODE_4358U
+const char ccode_4358u[] = \
+"BE/4 BR/4 "\
+"CA/2 CH/4 CN/38 CY/4 "\
+"DE/7 DK/4 "\
+"ES/4 "\
+"FI/4 FR/5 "\
+"GB/6 GR/4 "\
+"HK/2 HU/4 "\
+"IE/5 IL/7 IS/4 IT/4 "\
+"JP/72 "\
+"KE/0 KR/4 "\
+"MY/3 "\
+"NL/4 "\
+"PT/4 "\
+"SA/5 SE/4 SG/0 SZ/0 "\
+"TH/5 TR/7 TW/230 "\
+"US/0 "\
+"VN/4";
+#else
+const char ccode_4358u[] = "";
+#endif
+
+typedef struct ccode_list_map_t {
+	uint chip;
+	uint chiprev;
+	const char *ccode_list;
+	const char *ccode_ww;
+} ccode_list_map_t;
+
+const ccode_list_map_t ccode_list_map[] = {
+	/* ChipID		Chiprev		ccode  */
+#if defined(BCMSDIO) || defined(BCMPCIE)
+	{BCM4359_CHIP_ID,	9,	ccode_4359c0,	"XZ/11"},
+#endif
+#ifdef BCMSDIO
+	{BCM43430_CHIP_ID,	0,	ccode_43438,	""},
+	{BCM43430_CHIP_ID,	1,	ccode_43438,	""},
+	{BCM43430_CHIP_ID,	2,	ccode_43436,	""},
+	{BCM4345_CHIP_ID,	6,	ccode_43455c0,	"XZ/11"},
+	{BCM4345_CHIP_ID,	9,	ccode_43455c0,	"XZ/11"},
+#endif
+#ifdef BCMPCIE
+	{BCM4375_CHIP_ID,	5,	ccode_4375b4,	""},
+#endif
+#ifdef BCMDBUS
+	{BCM43569_CHIP_ID,	2,	ccode_4358u, "XZ/11"},
+#endif
+};
+
+/*
+ * [ccode]:[disable_6g_band][disable_5g_band][ww_2g_chan_only]
+ * [ccode]:[x][xxxx][x]
+ */
+const char ccode_all_map[] = \
+"AA:000002 "\
+"AU:E08203 "\
+"BH:F0E042 BR:00E002 "\
+"CA:00E203 CN:F0E042 "\
+"EU:E08002 "\
+"GB:E08002 "\
+"ID:F0F042 IL:F08002 IN:F08002 "\
+"JP:E00082 "\
+"KR:00E002 "\
+"NZ:E0E002 "\
+"PH:F0C002 "\
+"RU:E0C302 "\
+"SG:E0E002 "\
+"TR:F00882 TW:F0E043 "\
+"US:000003 "\
+"VN:F0E002 "\
+"ZA:F00882 ";
+
+typedef struct ccode_all_chip_t {
+	uint chip;
+	uint chiprev;
+} ccode_all_chip_t;
+
+const ccode_all_chip_t ccode_all_chip[] = {
+	/* ChipID		Chiprev  */
+//	{0,	0},
+#if defined(BCMSDIO) || defined(BCMPCIE)
+	{BCM43752_CHIP_ID,	4},
+	{BCM43756_CHIP_ID,	4},
+	{BCM43756_CHIP_ID,	6},
+#endif
+};
+
+int
+dhd_ccode_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec)
+{
+	int ret = -1, i;
+	uint chip = dhd->conf->chip, chiprev = dhd->conf->chiprev;
+	const char *ccode_list = NULL, *ccode_ww = NULL;
+	char *pch;
+
+	for (i=0; i<sizeof(ccode_list_map)/sizeof(ccode_list_map[0]); i++) {
+		const ccode_list_map_t* row = &ccode_list_map[i];
+		if (row->chip == chip && row->chiprev == chiprev) {
+			ccode_list = row->ccode_list;
+			ccode_ww = row->ccode_ww;
+			break;
+		}
+	}
+
+	if (ccode_list) {
+		pch = strstr(ccode_list, cspec->ccode);
+		if (pch) {
+			cspec->rev = (int)simple_strtol(pch+strlen(cspec->ccode)+1, NULL, 0);
+			ret = 0;
+		}
+	}
+
+	if (dhd->op_mode != DHD_FLAG_MFG_MODE) {
+		if (ret && ccode_ww && strlen(ccode_ww)>=4) {
+			memcpy(cspec->ccode, ccode_ww, 2);
+			cspec->rev = (int)simple_strtol(ccode_ww+3, NULL, 0);
+		}
+	}
+
+	return ret;
+}
+
+#define WW_2G_CHAN_ONLY_MASK	0x00000F
+#define DISABLE_5G_BAND_MASK	0x0FFFF0
+#define DISABLE_6G_BAND_MASK	0xF00000
+
+#define DISABLE_5G_BAND_OFFSET	4
+#define DISABLE_6G_BAND_OFFSET	20
+
+int
+dhd_ccode_map_country_all(dhd_pub_t *dhd, wl_country_t *cspec)
+{
+	int ret = -1, i;
+	struct dhd_conf *conf = dhd->conf;
+	wl_ccode_all_t *ccode_all = &dhd->conf->ccode_all;
+	uint chip = conf->chip, chiprev = conf->chiprev, val;
+	char *pch, *pick_tmp;
+	bool picked = FALSE;
+
+	if (conf->ccode_all_list) {
+		pch = strstr(conf->ccode_all_list, cspec->ccode);
+		if (!pch)
+			goto exit;
+		pick_tmp = bcmstrtok(&pch, ", ", 0);
+		if (!pick_tmp)
+			goto exit;
+		ccode_all->ww_2g_chan_only = 0x2;
+		ccode_all->disable_5g_band = 0;
+		ccode_all->disable_6g_band = 0;
+		pch = strstr(pick_tmp, "2g");
+		if (pch) {
+			ccode_all->ww_2g_chan_only = (int)simple_strtol(pch+strlen("2g"), NULL, 16);
+			picked = TRUE;
+		}
+		pch = strstr(pick_tmp, "5g");
+		if (pch) {
+			ccode_all->disable_5g_band = (int)simple_strtol(pch+strlen("5g"), NULL, 16);
+			picked = TRUE;
+		}
+		pch = strstr(pick_tmp, "6g");
+		if (pch) {
+			ccode_all->disable_6g_band = (int)simple_strtol(pch+strlen("6g"), NULL, 16);
+			picked = TRUE;
+		}
+		if (picked) {
+			memcpy(cspec->ccode, &ccode_all->cspec.ccode, WLC_CNTRY_BUF_SZ);
+			return 0;
+		}
+	}
+
+exit:
+	for (i=0; i<sizeof(ccode_all_chip)/sizeof(ccode_all_chip[0]); i++) {
+		const ccode_all_chip_t* row = &ccode_all_chip[i];
+		if ((row->chip == chip && row->chiprev == chiprev) ||
+				(row->chip == 0 && row->chiprev == 0)) {
+			pch = strstr(ccode_all_map, cspec->ccode);
+			if (pch) {
+				val = simple_strtol(pch+strlen(cspec->ccode)+1, NULL, 16);
+				ccode_all->ww_2g_chan_only = val & WW_2G_CHAN_ONLY_MASK;
+				ccode_all->disable_5g_band = (val & DISABLE_5G_BAND_MASK) >> DISABLE_5G_BAND_OFFSET;
+				ccode_all->disable_6g_band = (val & DISABLE_6G_BAND_MASK) >> DISABLE_6G_BAND_OFFSET;
+				memcpy(cspec->ccode, &ccode_all->cspec.ccode, WLC_CNTRY_BUF_SZ);
+				ret = 0;
+				break;
+			}
+		}
+	}
+
+	return ret;
+}
+#endif
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_cdc.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_cdc.c
@@ -0,0 +1,1060 @@
+/*
+ * DHD Protocol Module for CDC and BDC.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ *
+ * BDC is like CDC, except it includes a header for data packets to convey
+ * packet priority over the bus, and flags (e.g. to indicate checksum status
+ * for dongle offload.)
+ */
+
+#include <typedefs.h>
+#include <osl.h>
+
+#include <bcmutils.h>
+#include <bcmcdc.h>
+#include <bcmendian.h>
+
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_proto.h>
+#include <dhd_bus.h>
+#include <dhd_dbg.h>
+
+#ifdef EXT_STA
+#include <siutils.h>
+#include <wlc_cfg.h>
+#include <wlc_pub.h>
+#endif /* EXT_STA */
+
+#ifdef PROP_TXSTATUS
+#include <wlfc_proto.h>
+#include <dhd_wlfc.h>
+#endif
+
+#ifdef DHD_HWTSTAMP
+#include <dhd_linux_priv.h>
+#endif /* DHD_HWTSTAMP */
+#ifdef BCMDBUS
+#include <dhd_config.h>
+#endif /* BCMDBUS */
+
+#define RETRIES 2		/* # of retries to retrieve matching ioctl response */
+#define BUS_HEADER_LEN	(24+DHD_SDALIGN)	/* Must be at least SDPCM_RESERVE
+				 * defined in dhd_sdio.c (amount of header tha might be added)
+				 * plus any space that might be needed for alignment padding.
+				 */
+#define ROUND_UP_MARGIN	2048	/* Biggest SDIO block size possible for
+				 * round off at the end of buffer
+				 */
+
+/* This value is from Legacy chipsets */
+#define DEFAULT_WLC_API_VERSION_MAJOR	3
+#define DEFAULT_WLC_API_VERSION_MINOR	0
+
+typedef struct dhd_prot {
+	uint16 reqid;
+	uint8 pending;
+	uint32 lastcmd;
+	uint8 bus_header[BUS_HEADER_LEN];
+	cdc_ioctl_t msg;
+	unsigned char buf[WLC_IOCTL_MAXLEN + ROUND_UP_MARGIN];
+} dhd_prot_t;
+
+/* Network inteface mac for primary IF */
+char iface_wlan0_mac[ETHER_ADDR_STR_LEN] = {'\0'};
+module_param_string(iface_wlan0_mac, iface_wlan0_mac, ETHER_ADDR_STR_LEN, 0660);
+
+uint16
+dhd_prot_get_ioctl_trans_id(dhd_pub_t *dhdp)
+{
+	/* SDIO does not have ioctl_trans_id yet, so return -1 */
+	return -1;
+}
+
+static int
+dhdcdc_msg(dhd_pub_t *dhd)
+{
+	int err = 0;
+	dhd_prot_t *prot = dhd->prot;
+	int len = ltoh32(prot->msg.len) + sizeof(cdc_ioctl_t);
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+	DHD_OS_WAKE_LOCK(dhd);
+
+	/* NOTE : cdc->msg.len holds the desired length of the buffer to be
+	 *        returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
+	 *	  is actually sent to the dongle
+	 */
+	if (len > CDC_MAX_MSG_SIZE)
+		len = CDC_MAX_MSG_SIZE;
+
+	/* Send request */
+	err = dhd_bus_txctl(dhd->bus, (uchar*)&prot->msg, len);
+
+	DHD_OS_WAKE_UNLOCK(dhd);
+	return err;
+}
+
+static int
+dhdcdc_cmplt(dhd_pub_t *dhd, uint32 id, uint32 len)
+{
+	int ret;
+	int cdc_len = len + sizeof(cdc_ioctl_t);
+	dhd_prot_t *prot = dhd->prot;
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+	/*
+	 * prot->msg is the buffer used to send the ioctl msg in dhdcdc_msg and the same is
+	 * used for receiving the ioctl response.
+	 * As this buffer is not cleared after sending message and before re-using for receive
+	 * operation, problems are seen when bus errors occur.
+	 * Example:- An error is seen on the bus where a 0 byte pkt is received.
+	 * the bus-controller "layer below cdc" does not update the buffer in this 0 byte pkt case.
+	 * bus-controller layer calls the completion callback without any error and with the
+	 * same buffer.(no change)
+	 * This issue is seen on DBUS/USB + FPGA platforms
+	 * In this function if there is no update to the buffer, the stale id field of sent msg
+	 * matches to expected ID and further processing is done thinking that
+	 * proper response is received.
+	 * This is a generic problem and its a good idea to clear the buffer or atleast
+	 * the buffer's key value (ioctl ID within flags field in this case) before re-using it.
+	 *
+	 * To ensure that a new content is indeed received from the bus making flags = 0.
+	 * Note that ID=0 is invalid value.
+	 */
+	prot->msg.flags = 0;
+
+	do {
+		ret = dhd_bus_rxctl(dhd->bus, (uchar*)&prot->msg, cdc_len);
+		if (ret < 0)
+			break;
+	} while (CDC_IOC_ID(ltoh32(prot->msg.flags)) != id);
+
+	/* update ret to len on success */
+	if (ret == cdc_len) {
+		ret = len;
+	}
+
+	return ret;
+}
+
+/* XXX: due to overlays this should not be called directly; call dhd_wl_ioctl_cmd() instead */
+static int
+dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action)
+{
+	dhd_prot_t *prot = dhd->prot;
+	cdc_ioctl_t *msg = &prot->msg;
+	int ret = 0, retries = 0;
+	uint32 id, flags = 0;
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+	DHD_CTL(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len));
+
+	/* Respond "bcmerror" and "bcmerrorstr" with local cache */
+	if (cmd == WLC_GET_VAR && buf)
+	{
+		if (!strcmp((char *)buf, "bcmerrorstr"))
+		{
+			strlcpy((char *)buf, bcmerrorstr(dhd->dongle_error), len);
+			goto done;
+		}
+		else if (!strcmp((char *)buf, "bcmerror"))
+		{
+			*(int *)buf = dhd->dongle_error;
+			goto done;
+		}
+	}
+
+	if (ifidx >= DHD_MAX_IFS) {
+		DHD_ERROR(("%s: IF index %d Invalid for the dongle FW\n",
+			__FUNCTION__, ifidx));
+		return -EIO;
+	}
+
+	memset(msg, 0, sizeof(cdc_ioctl_t));
+
+#ifdef BCMSPI
+	/* 11bit gSPI bus allows 2048bytes of max-data.  We restrict 'len'
+	 * value which is 8Kbytes for various 'get' commands to 2000.  48 bytes are
+	 * left for sw headers and misc.
+	 */
+	if (len > 2000) {
+		DHD_ERROR(("dhdcdc_query_ioctl: len is truncated to 2000 bytes\n"));
+		len = 2000;
+	}
+#endif /* BCMSPI */
+	msg->cmd = htol32(cmd);
+	msg->len = htol32(len);
+	msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT);
+	CDC_SET_IF_IDX(msg, ifidx);
+	/* add additional action bits */
+	action &= WL_IOCTL_ACTION_MASK;
+	msg->flags |= (action << CDCF_IOC_ACTION_SHIFT);
+	msg->flags = htol32(msg->flags);
+
+	if (buf)
+		memcpy(prot->buf, buf, len);
+
+	if ((ret = dhdcdc_msg(dhd)) < 0) {
+		if (!dhd->hang_was_sent)
+		DHD_ERROR(("dhdcdc_query_ioctl: dhdcdc_msg failed w/status %d\n", ret));
+		goto done;
+	}
+
+retry:
+	/* wait for interrupt and get first fragment */
+	if ((ret = dhdcdc_cmplt(dhd, prot->reqid, len)) < 0)
+		goto done;
+
+	flags = ltoh32(msg->flags);
+	id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
+
+	if ((id < prot->reqid) && (++retries < RETRIES))
+		goto retry;
+	if (id != prot->reqid) {
+		DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
+		           dhd_ifname(dhd, ifidx), __FUNCTION__, id, prot->reqid));
+		ret = -EINVAL;
+		goto done;
+	}
+
+	/* Copy info buffer */
+	if (buf)
+	{
+		if (ret < (int)len)
+			len = ret;
+		memcpy(buf, (void*) prot->buf, len);
+	}
+
+	/* Check the ERROR flag */
+	if (flags & CDCF_IOC_ERROR)
+	{
+		ret = ltoh32(msg->status);
+		/* Cache error from dongle */
+		dhd->dongle_error = ret;
+	}
+
+done:
+	return ret;
+}
+
+#ifdef DHD_PM_CONTROL_FROM_FILE
+extern bool g_pm_control;
+#endif /* DHD_PM_CONTROL_FROM_FILE */
+
+/* XXX: due to overlays this should not be called directly; call dhd_wl_ioctl_cmd() instead */
+static int
+dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action)
+{
+	dhd_prot_t *prot = dhd->prot;
+	cdc_ioctl_t *msg = &prot->msg;
+	int ret = 0;
+	uint32 flags, id;
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+	DHD_CTL(("%s: cmd %d len %d\n", __FUNCTION__, cmd, len));
+
+	if (dhd->busstate == DHD_BUS_DOWN) {
+		DHD_ERROR(("%s : bus is down. we have nothing to do\n", __FUNCTION__));
+		return -EIO;
+	}
+
+	/* don't talk to the dongle if fw is about to be reloaded */
+	if (dhd->hang_was_sent) {
+		DHD_ERROR(("%s: HANG was sent up earlier. Not talking to the chip\n",
+			__FUNCTION__));
+		return -EIO;
+	}
+
+	if (cmd == WLC_SET_PM) {
+#ifdef DHD_PM_CONTROL_FROM_FILE
+		if (g_pm_control == TRUE) {
+			DHD_ERROR(("%s: SET PM ignored!(Requested:%d)\n",
+				__FUNCTION__, buf ? *(char *)buf : 0));
+			goto done;
+		}
+#endif /* DHD_PM_CONTROL_FROM_FILE */
+#ifdef DHD_PM_OVERRIDE
+		{
+			extern bool g_pm_override;
+			if (g_pm_override == TRUE) {
+				DHD_ERROR(("%s: PM override SET PM ignored!(Requested:%d)\n",
+					__FUNCTION__, buf ? *(char *)buf : 0));
+				goto done;
+			}
+		}
+#endif /* DHD_PM_OVERRIDE */
+		DHD_TRACE_HW4(("%s: SET PM to %d\n", __FUNCTION__, buf ? *(char *)buf : 0));
+	}
+
+	if (ifidx >= DHD_MAX_IFS) {
+		DHD_ERROR(("%s: IF index %d Invalid for the dongle FW\n",
+			__FUNCTION__, ifidx));
+		return -EIO;
+	}
+
+	memset(msg, 0, sizeof(cdc_ioctl_t));
+
+	msg->cmd = htol32(cmd);
+	msg->len = htol32(len);
+	msg->flags = (++prot->reqid << CDCF_IOC_ID_SHIFT);
+	CDC_SET_IF_IDX(msg, ifidx);
+	/* add additional action bits */
+	action &= WL_IOCTL_ACTION_MASK;
+	msg->flags |= (action << CDCF_IOC_ACTION_SHIFT) | CDCF_IOC_SET;
+	msg->flags = htol32(msg->flags);
+
+	if (buf)
+		memcpy(prot->buf, buf, len);
+
+	if ((ret = dhdcdc_msg(dhd)) < 0) {
+		DHD_ERROR(("%s: dhdcdc_msg failed w/status %d\n", __FUNCTION__, ret));
+		goto done;
+	}
+
+	if ((ret = dhdcdc_cmplt(dhd, prot->reqid, len)) < 0)
+		goto done;
+
+	flags = ltoh32(msg->flags);
+	id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT;
+
+	if (id != prot->reqid) {
+		DHD_ERROR(("%s: %s: unexpected request id %d (expected %d)\n",
+		           dhd_ifname(dhd, ifidx), __FUNCTION__, id, prot->reqid));
+		ret = -EINVAL;
+		goto done;
+	}
+
+	/* Copy fw response to buf */
+	if (buf) {
+		ASSERT(ret == len);
+		memcpy(buf, (void*) prot->buf, len);
+	}
+
+	/* Check the ERROR flag */
+	if (flags & CDCF_IOC_ERROR)
+	{
+		ret = ltoh32(msg->status);
+		/* Cache error from dongle */
+		dhd->dongle_error = ret;
+	}
+
+done:
+	return ret;
+}
+
+/* XXX: due to overlays this should not be called directly; call dhd_wl_ioctl() instead */
+int
+dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t * ioc, void * buf, int len)
+{
+	dhd_prot_t *prot = dhd->prot;
+	int ret = -1;
+	uint8 action;
+	static int error_cnt = 0;
+
+	if ((dhd->busstate == DHD_BUS_DOWN) || dhd->hang_was_sent) {
+		DHD_ERROR(("%s : bus is down. we have nothing to do - bs: %d, has: %d\n",
+				__FUNCTION__, dhd->busstate, dhd->hang_was_sent));
+		goto done;
+	}
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+	ASSERT(len <= WLC_IOCTL_MAXLEN);
+
+	if (len > WLC_IOCTL_MAXLEN)
+		goto done;
+
+	if (prot->pending == TRUE) {
+		DHD_ERROR(("CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n",
+			ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd,
+			(unsigned long)prot->lastcmd));
+		if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR)) {
+			DHD_TRACE(("iovar cmd=%s\n", buf ? (char*)buf : "\0"));
+		}
+		goto done;
+	}
+
+	prot->pending = TRUE;
+	prot->lastcmd = ioc->cmd;
+	action = ioc->set;
+	if (action & WL_IOCTL_ACTION_SET)
+		ret = dhdcdc_set_ioctl(dhd, ifidx, ioc->cmd, buf, len, action);
+	else {
+		ret = dhdcdc_query_ioctl(dhd, ifidx, ioc->cmd, buf, len, action);
+		if (ret > 0)
+			ioc->used = ret - sizeof(cdc_ioctl_t);
+	}
+	// terence 20130805: send hang event to wpa_supplicant
+	if (ret == -EIO) {
+		error_cnt++;
+		if (error_cnt > 2)
+			ret = -ETIMEDOUT;
+	} else
+		error_cnt = 0;
+
+	/* Too many programs assume ioctl() returns 0 on success */
+	if (ret >= 0)
+		ret = 0;
+	else {
+		cdc_ioctl_t *msg = &prot->msg;
+		ioc->needed = ltoh32(msg->len); /* len == needed when set/query fails from dongle */
+	}
+
+	/* Intercept the wme_dp ioctl here */
+	if ((!ret) && (ioc->cmd == WLC_SET_VAR) && (!strcmp(buf, "wme_dp"))) {
+		int slen, val = 0;
+
+		slen = strlen("wme_dp") + 1;
+		if (len >= (int)(slen + sizeof(int)))
+			bcopy(((char *)buf + slen), &val, sizeof(int));
+		dhd->wme_dp = (uint8) ltoh32(val);
+	}
+
+	prot->pending = FALSE;
+
+done:
+
+	return ret;
+}
+
+int
+dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name,
+                  void *params, int plen, void *arg, int len, bool set)
+{
+	return BCME_UNSUPPORTED;
+}
+
+void
+dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+{
+	if (!dhdp || !dhdp->prot) {
+		return;
+	}
+
+	bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid);
+#ifdef PROP_TXSTATUS
+	dhd_wlfc_dump(dhdp, strbuf);
+#endif
+}
+
+void
+dhd_prot_counters(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf,
+	bool print_ringinfo, bool print_pktidinfo)
+{
+	return;
+}
+
+void
+dhd_bus_counters(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+{
+	return;
+}
+
+/*	The FreeBSD PKTPUSH could change the packet buf pinter
+	so we need to make it changable
+*/
+#define PKTBUF pktbuf
+void
+dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *PKTBUF)
+{
+#ifdef BDC
+	struct bdc_header *h;
+#endif /* BDC */
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+#ifdef BDC
+	/* Push BDC header used to convey priority for buses that don't */
+
+	PKTPUSH(dhd->osh, PKTBUF, BDC_HEADER_LEN);
+
+	h = (struct bdc_header *)PKTDATA(dhd->osh, PKTBUF);
+
+	h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
+	if (PKTSUMNEEDED(PKTBUF))
+		h->flags |= BDC_FLAG_SUM_NEEDED;
+
+#ifdef EXT_STA
+	/* save pkt encryption exemption info for dongle */
+	h->flags &= ~BDC_FLAG_EXEMPT;
+	h->flags |= (WLPKTFLAG_EXEMPT_GET(WLPKTTAG(pktbuf)) & BDC_FLAG_EXEMPT);
+#endif /* EXT_STA */
+
+	h->priority = (PKTPRIO(PKTBUF) & BDC_PRIORITY_MASK);
+	h->flags2 = 0;
+	h->dataOffset = 0;
+#endif /* BDC */
+	BDC_SET_IF_IDX(h, ifidx);
+}
+#undef PKTBUF	/* Only defined in the above routine */
+
+uint
+dhd_prot_hdrlen(dhd_pub_t *dhd, void *PKTBUF)
+{
+	uint hdrlen = 0;
+#ifdef BDC
+	/* Length of BDC(+WLFC) headers pushed */
+	hdrlen = BDC_HEADER_LEN + (((struct bdc_header *)PKTBUF)->dataOffset * 4);
+#endif
+	return hdrlen;
+}
+
+int
+dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf, uchar *reorder_buf_info,
+	uint *reorder_info_len)
+{
+#ifdef BDC
+	struct bdc_header *h;
+#endif
+	uint8 data_offset = 0;
+	uint32 bdc_hdr_len = BDC_HEADER_LEN;
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+#ifdef BDC
+	if (reorder_info_len)
+		*reorder_info_len = 0;
+	/* Pop BDC header used to convey priority for buses that don't */
+
+	if (PKTLEN(dhd->osh, pktbuf) < BDC_HEADER_LEN) {
+		DHD_ERROR(("%s: rx data too short (%d < %d)\n", __FUNCTION__,
+		           PKTLEN(dhd->osh, pktbuf), BDC_HEADER_LEN));
+		return BCME_ERROR;
+	}
+
+	h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf);
+#ifdef DHD_HWTSTAMP
+	if (h->flags2 & BDC_FLAG2_TSF_FLAG) {
+		struct bdc_header_tsf *h_tsf = (struct bdc_header_tsf *)PKTDATA(dhd->osh, pktbuf);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
+		if (dhd->info->stmpconf.rx_filter) {
+			ktime_t tsf;
+			struct skb_shared_hwtstamps *tst;
+			tst = skb_hwtstamps(((struct sk_buff*)(pktbuf)));
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
+			tsf = (s64) h_tsf->tsf_h;
+			tsf = tsf << 32 | h_tsf->tsf_l;
+			/* Convert micro sec tsf to nano sec kernel hw timestamp */
+			tst->hwtstamp = tsf * 1000;
+#else
+			tsf.tv64 = (s64) h_tsf->tsf_h;
+			tsf.tv64 = tsf.tv64 << 32 | h_tsf->tsf_l;
+			/* Convert micro sec tsf to nano sec kernel hw timestamp */
+			tst->hwtstamp.tv64 = tsf.tv64 * 1000;
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) */
+		}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)) */
+		h_tsf->dataOffset = h_tsf->dataOffset - 2;
+		bdc_hdr_len = bdc_hdr_len + 8;
+	}
+#endif /* DHD_HWTSTAMP */
+	if (!ifidx) {
+		/* for tx packet, skip the analysis */
+		data_offset = h->dataOffset;
+		PKTPULL(dhd->osh, pktbuf, bdc_hdr_len);
+		goto exit;
+	}
+
+	*ifidx = BDC_GET_IF_IDX(h);
+
+	if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != BDC_PROTO_VER) {
+		DHD_ERROR(("%s: non-BDC packet received, flags = 0x%x\n",
+		           dhd_ifname(dhd, *ifidx), h->flags));
+		if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) == BDC_PROTO_VER_1)
+			h->dataOffset = 0;
+		else
+		return BCME_ERROR;
+	}
+
+	if (h->flags & BDC_FLAG_SUM_GOOD) {
+		DHD_INFO(("%s: BDC packet received with good rx-csum, flags 0x%x\n",
+		          dhd_ifname(dhd, *ifidx), h->flags));
+		PKTSETSUMGOOD(pktbuf, TRUE);
+	}
+
+	PKTSETPRIO(pktbuf, (h->priority & BDC_PRIORITY_MASK));
+	data_offset = h->dataOffset;
+	PKTPULL(dhd->osh, pktbuf, bdc_hdr_len);
+#endif /* BDC */
+
+#ifdef PROP_TXSTATUS
+	if (!DHD_PKTTAG_PKTDIR(PKTTAG(pktbuf))) {
+		/*
+		- parse txstatus only for packets that came from the firmware
+		*/
+		dhd_wlfc_parse_header_info(dhd, pktbuf, (data_offset << 2),
+			reorder_buf_info, reorder_info_len);
+
+#ifdef BCMDBUS
+#ifndef DHD_WLFC_THREAD
+		dhd_wlfc_commit_packets(dhd,
+			(f_commitpkt_t)dhd_bus_txdata, dhd->bus, NULL, FALSE);
+#endif /* DHD_WLFC_THREAD */
+#endif /* BCMDBUS */
+	}
+#endif /* PROP_TXSTATUS */
+
+exit:
+	PKTPULL(dhd->osh, pktbuf, (data_offset << 2));
+	return 0;
+}
+
+#ifdef DHD_LOSSLESS_ROAMING
+int dhd_update_sdio_data_prio_map(dhd_pub_t *dhdp)
+{
+	const uint8 prio2tid[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+
+	bcopy(prio2tid, dhdp->flow_prio_map, sizeof(uint8) * NUMPRIO);
+
+	return BCME_OK;
+}
+#endif // DHD_LOSSLESS_ROAMING
+
+int
+dhd_prot_attach(dhd_pub_t *dhd)
+{
+	dhd_prot_t *cdc;
+
+	if (!(cdc = (dhd_prot_t *)DHD_OS_PREALLOC(dhd, DHD_PREALLOC_PROT, sizeof(dhd_prot_t)))) {
+		DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
+		goto fail;
+	}
+	memset(cdc, 0, sizeof(dhd_prot_t));
+
+	/* ensure that the msg buf directly follows the cdc msg struct */
+	if ((uintptr)(&cdc->msg + 1) != (uintptr)cdc->buf) {
+		DHD_ERROR(("dhd_prot_t is not correctly defined\n"));
+		goto fail;
+	}
+
+	dhd->prot = cdc;
+#ifdef BDC
+	dhd->hdrlen += BDC_HEADER_LEN;
+#endif
+	dhd->maxctl = WLC_IOCTL_MAXLEN + sizeof(cdc_ioctl_t) + ROUND_UP_MARGIN;
+	return 0;
+
+fail:
+	if (cdc != NULL)
+		DHD_OS_PREFREE(dhd, cdc, sizeof(dhd_prot_t));
+	return BCME_NOMEM;
+}
+
+/* ~NOTE~ What if another thread is waiting on the semaphore?  Holding it? */
+void
+dhd_prot_detach(dhd_pub_t *dhd)
+{
+#ifdef PROP_TXSTATUS
+	dhd_wlfc_deinit(dhd);
+#endif
+	DHD_OS_PREFREE(dhd, dhd->prot, sizeof(dhd_prot_t));
+	dhd->prot = NULL;
+}
+
+void
+dhd_prot_dstats(dhd_pub_t *dhd)
+{
+	/*  copy bus stats */
+
+	dhd->dstats.tx_packets = dhd->tx_packets;
+	dhd->dstats.tx_errors = dhd->tx_errors;
+	dhd->dstats.rx_packets = dhd->rx_packets;
+	dhd->dstats.rx_errors = dhd->rx_errors;
+	dhd->dstats.rx_dropped = dhd->rx_dropped;
+	dhd->dstats.multicast = dhd->rx_multicast;
+	return;
+}
+
+int
+dhd_sync_with_dongle(dhd_pub_t *dhd)
+{
+	int ret = 0;
+	wlc_rev_info_t revinfo;
+	char buf[128];
+	u8 mac_addr[ETH_ALEN];
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+	if (iface_wlan0_mac[0]) {
+		bcm_ether_atoe(iface_wlan0_mac, (struct ether_addr *)mac_addr);
+		ret = dhd_iovar(dhd, 0, "cur_etheraddr", (char *)&mac_addr, ETHER_ADDR_LEN, NULL, 0,
+				TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret));
+			goto done;
+		}
+		memcpy(dhd->mac.octet, mac_addr, ETHER_ADDR_LEN);
+	} else {
+#ifndef OEM_ANDROID
+		/* Get the device MAC address */
+		strcpy(buf, "cur_etheraddr");
+		ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), FALSE, 0);
+		if (ret < 0)
+			goto done;
+		memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN);
+#endif /* OEM_ANDROID */
+	}
+
+#ifdef DHD_FW_COREDUMP
+	/* Check the memdump capability */
+	dhd_get_memdump_info(dhd);
+#endif /* DHD_FW_COREDUMP */
+
+#ifdef BCMASSERT_LOG
+	dhd_get_assert_info(dhd);
+#endif /* BCMASSERT_LOG */
+
+	/* Get the device rev info */
+	memset(&revinfo, 0, sizeof(revinfo));
+	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_REVINFO, &revinfo, sizeof(revinfo), FALSE, 0);
+	if (ret < 0)
+		goto done;
+#if defined(BCMDBUS)
+	if (dhd_download_fw_on_driverload) {
+		dhd_conf_reset(dhd);
+		dhd_conf_set_chiprev(dhd, revinfo.chipnum, revinfo.chiprev);
+		dhd_conf_preinit(dhd);
+		dhd_conf_read_config(dhd, dhd->conf_path);
+	}
+#endif /* BCMDBUS */
+
+	/* query for 'wlc_ver' to get version info from firmware */
+	/* memsetting to zero */
+	bzero(buf, sizeof(buf));
+	ret = bcm_mkiovar("wlc_ver", NULL, 0, buf, sizeof(buf));
+	if (ret == 0) {
+		ret = BCME_BUFTOOSHORT;
+		goto done;
+	}
+	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), FALSE, 0);
+	if (ret == BCME_UNSUPPORTED) {
+		dhd->wlc_ver_major = DEFAULT_WLC_API_VERSION_MAJOR;
+		dhd->wlc_ver_minor = DEFAULT_WLC_API_VERSION_MINOR;
+	} else if (ret < 0) {
+		DHD_ERROR(("%s failed %d\n", __FUNCTION__, ret));
+		goto done;
+	} else {
+		dhd->wlc_ver_major = ((wl_wlc_version_t*)buf)->wlc_ver_major;
+		dhd->wlc_ver_minor = ((wl_wlc_version_t*)buf)->wlc_ver_minor;
+	}
+	DHD_ERROR(("wlc_ver_major %d, wlc_ver_minor %d\n", dhd->wlc_ver_major, dhd->wlc_ver_minor));
+
+#if defined(BCMDBUS) && defined(BCMDHDUSB)
+	/* dbus_set_revinfo(dhd->dbus, revinfo.chipnum, revinfo.chiprev); */
+#endif /* BCMDBUS && BCMDHDUSB */
+
+	DHD_SSSR_DUMP_INIT(dhd);
+
+	dhd_process_cid_mac(dhd, TRUE);
+	ret = dhd_preinit_ioctls(dhd);
+	dhd_process_cid_mac(dhd, FALSE);
+
+	/* Always assumes wl for now */
+	dhd->iswl = TRUE;
+
+	/* XXX Could use WLC_GET_REVINFO to get driver version? */
+done:
+	return ret;
+}
+
+int dhd_prot_init(dhd_pub_t *dhd)
+{
+	return BCME_OK;
+}
+
+void
+dhd_prot_stop(dhd_pub_t *dhd)
+{
+/* Nothing to do for CDC */
+}
+
+static void
+dhd_get_hostreorder_pkts(void *osh, struct reorder_info *ptr, void **pkt,
+	uint32 *pkt_count, void **pplast, uint8 start, uint8 end)
+{
+	void *plast = NULL, *p;
+	uint32 pkt_cnt = 0;
+
+	if (ptr->pend_pkts == 0) {
+		DHD_REORDER(("%s: no packets in reorder queue \n", __FUNCTION__));
+		*pplast = NULL;
+		*pkt_count = 0;
+		*pkt = NULL;
+		return;
+	}
+	do {
+		p = (void *)(ptr->p[start]);
+		ptr->p[start] = NULL;
+
+		if (p != NULL) {
+			if (plast == NULL)
+				*pkt = p;
+			else
+				PKTSETNEXT(osh, plast, p);
+
+			plast = p;
+			pkt_cnt++;
+		}
+		start++;
+		if (start > ptr->max_idx)
+			start = 0;
+	} while (start != end);
+	*pplast = plast;
+	*pkt_count = pkt_cnt;
+	ptr->pend_pkts -= (uint8)pkt_cnt;
+}
+
+int
+dhd_process_pkt_reorder_info(dhd_pub_t *dhd, uchar *reorder_info_buf, uint reorder_info_len,
+	void **pkt, uint32 *pkt_count)
+{
+	uint8 flow_id, max_idx, cur_idx, exp_idx;
+	struct reorder_info *ptr;
+	uint8 flags;
+	void *cur_pkt, *plast = NULL;
+	uint32 cnt = 0;
+
+	if (pkt == NULL) {
+		if (pkt_count != NULL)
+			*pkt_count = 0;
+		return 0;
+	}
+
+	flow_id = reorder_info_buf[WLHOST_REORDERDATA_FLOWID_OFFSET];
+	flags = reorder_info_buf[WLHOST_REORDERDATA_FLAGS_OFFSET];
+
+	DHD_REORDER(("flow_id %d, flags 0x%02x, idx(%d, %d, %d)\n", flow_id, flags,
+		reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET],
+		reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET],
+		reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET]));
+
+	/* validate flags and flow id */
+	if (flags == 0xFF) {
+		DHD_ERROR(("%s: invalid flags...so ignore this packet\n", __FUNCTION__));
+		*pkt_count = 1;
+		return 0;
+	}
+
+	cur_pkt = *pkt;
+	*pkt = NULL;
+
+	ptr = dhd->reorder_bufs[flow_id];
+	if (flags & WLHOST_REORDERDATA_DEL_FLOW) {
+		uint32 buf_size = sizeof(struct reorder_info);
+
+		DHD_REORDER(("%s: Flags indicating to delete a flow id %d\n",
+			__FUNCTION__, flow_id));
+
+		if (ptr == NULL) {
+			DHD_REORDER(("%s: received flags to cleanup, but no flow (%d) yet\n",
+				__FUNCTION__, flow_id));
+			*pkt_count = 1;
+			*pkt = cur_pkt;
+			return 0;
+		}
+
+		dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast,
+			ptr->exp_idx, ptr->exp_idx);
+		/* set it to the last packet */
+		if (plast) {
+			PKTSETNEXT(dhd->osh, plast, cur_pkt);
+			cnt++;
+		}
+		else {
+			if (cnt != 0) {
+				DHD_ERROR(("%s: del flow: something fishy, pending packets %d\n",
+					__FUNCTION__, cnt));
+			}
+			*pkt = cur_pkt;
+			cnt = 1;
+		}
+		buf_size += ((ptr->max_idx + 1) * sizeof(void *));
+		MFREE(dhd->osh, ptr, buf_size);
+		dhd->reorder_bufs[flow_id] = NULL;
+		*pkt_count = cnt;
+		return 0;
+	}
+	/* all the other cases depend on the existance of the reorder struct for that flow id */
+	if (ptr == NULL) {
+		uint32 buf_size_alloc = sizeof(reorder_info_t);
+		max_idx = reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET];
+
+		buf_size_alloc += ((max_idx + 1) * sizeof(void*));
+		/* allocate space to hold the buffers, index etc */
+
+		DHD_REORDER(("%s: alloc buffer of size %d size, reorder info id %d, maxidx %d\n",
+			__FUNCTION__, buf_size_alloc, flow_id, max_idx));
+		ptr = (struct reorder_info *)MALLOC(dhd->osh, buf_size_alloc);
+		if (ptr == NULL) {
+			DHD_ERROR(("%s: Malloc failed to alloc buffer\n", __FUNCTION__));
+			*pkt_count = 1;
+			return 0;
+		}
+		bzero(ptr, buf_size_alloc);
+		dhd->reorder_bufs[flow_id] = ptr;
+		ptr->p = (void *)(ptr+1);
+		ptr->max_idx = max_idx;
+	}
+	/* XXX: validate cur, exp indices */
+	if (flags & WLHOST_REORDERDATA_NEW_HOLE)  {
+		DHD_REORDER(("%s: new hole, so cleanup pending buffers\n", __FUNCTION__));
+		if (ptr->pend_pkts) {
+			dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast,
+				ptr->exp_idx, ptr->exp_idx);
+			ptr->pend_pkts = 0;
+		}
+		ptr->cur_idx = reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET];
+		ptr->exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET];
+		ptr->max_idx = reorder_info_buf[WLHOST_REORDERDATA_MAXIDX_OFFSET];
+		ptr->p[ptr->cur_idx] = cur_pkt;
+		ptr->pend_pkts++;
+		*pkt_count = cnt;
+	}
+	else if (flags & WLHOST_REORDERDATA_CURIDX_VALID) {
+		cur_idx = reorder_info_buf[WLHOST_REORDERDATA_CURIDX_OFFSET];
+		exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET];
+
+		if ((exp_idx == ptr->exp_idx) && (cur_idx != ptr->exp_idx)) {
+			/* still in the current hole */
+			/* enqueue the current on the buffer chain */
+			if (ptr->p[cur_idx] != NULL) {
+				DHD_REORDER(("%s: HOLE: ERROR buffer pending..free it\n",
+					__FUNCTION__));
+				PKTFREE(dhd->osh, ptr->p[cur_idx], TRUE);
+				ptr->p[cur_idx] = NULL;
+			}
+			ptr->p[cur_idx] = cur_pkt;
+			ptr->pend_pkts++;
+			ptr->cur_idx = cur_idx;
+			DHD_REORDER(("%s: fill up a hole..pending packets is %d\n",
+				__FUNCTION__, ptr->pend_pkts));
+			*pkt_count = 0;
+			*pkt = NULL;
+		}
+		else if (ptr->exp_idx == cur_idx) {
+			/* got the right one ..flush from cur to exp and update exp */
+			DHD_REORDER(("%s: got the right one now, cur_idx is %d\n",
+				__FUNCTION__, cur_idx));
+			if (ptr->p[cur_idx] != NULL) {
+				DHD_REORDER(("%s: Error buffer pending..free it\n",
+					__FUNCTION__));
+				PKTFREE(dhd->osh, ptr->p[cur_idx], TRUE);
+				ptr->p[cur_idx] = NULL;
+			}
+			ptr->p[cur_idx] = cur_pkt;
+			ptr->pend_pkts++;
+
+			ptr->cur_idx = cur_idx;
+			ptr->exp_idx = exp_idx;
+
+			dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast,
+				cur_idx, exp_idx);
+			*pkt_count = cnt;
+			DHD_REORDER(("%s: freeing up buffers %d, still pending %d\n",
+				__FUNCTION__, cnt, ptr->pend_pkts));
+		}
+		else {
+			uint8 end_idx;
+			bool flush_current = FALSE;
+			/* both cur and exp are moved now .. */
+			DHD_REORDER(("%s:, flow %d, both moved, cur %d(%d), exp %d(%d)\n",
+				__FUNCTION__, flow_id, ptr->cur_idx, cur_idx,
+				ptr->exp_idx, exp_idx));
+			if (flags & WLHOST_REORDERDATA_FLUSH_ALL)
+				end_idx = ptr->exp_idx;
+			else
+				end_idx = exp_idx;
+
+			/* flush pkts first */
+			dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast,
+				ptr->exp_idx, end_idx);
+
+			if (cur_idx == ptr->max_idx) {
+				if (exp_idx == 0)
+					flush_current = TRUE;
+			} else {
+				if (exp_idx == cur_idx + 1)
+					flush_current = TRUE;
+			}
+			if (flush_current) {
+				if (plast)
+					PKTSETNEXT(dhd->osh, plast, cur_pkt);
+				else
+					*pkt = cur_pkt;
+				cnt++;
+			}
+			else {
+				ptr->p[cur_idx] = cur_pkt;
+				ptr->pend_pkts++;
+			}
+			ptr->exp_idx = exp_idx;
+			ptr->cur_idx = cur_idx;
+			*pkt_count = cnt;
+		}
+	}
+	else {
+		uint8 end_idx;
+		/* no real packet but update to exp_seq...that means explicit window move */
+		exp_idx = reorder_info_buf[WLHOST_REORDERDATA_EXPIDX_OFFSET];
+
+		DHD_REORDER(("%s: move the window, cur_idx is %d, exp is %d, new exp is %d\n",
+			__FUNCTION__, ptr->cur_idx, ptr->exp_idx, exp_idx));
+		if (flags & WLHOST_REORDERDATA_FLUSH_ALL)
+			end_idx =  ptr->exp_idx;
+		else
+			end_idx =  exp_idx;
+
+		dhd_get_hostreorder_pkts(dhd->osh, ptr, pkt, &cnt, &plast, ptr->exp_idx, end_idx);
+		if (plast)
+			PKTSETNEXT(dhd->osh, plast, cur_pkt);
+		else
+			*pkt = cur_pkt;
+		cnt++;
+		*pkt_count = cnt;
+		/* set the new expected idx */
+		ptr->exp_idx = exp_idx;
+	}
+	return 0;
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_cfg80211.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_cfg80211.c
@@ -0,0 +1,634 @@
+/*
+ * Linux cfg80211 driver - Dongle Host Driver (DHD) related
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <linux/vmalloc.h>
+#include <net/rtnetlink.h>
+
+#include <bcmutils.h>
+#include <wldev_common.h>
+#include <wl_cfg80211.h>
+#include <dhd_cfg80211.h>
+
+#ifdef PKT_FILTER_SUPPORT
+#include <dngl_stats.h>
+#include <dhd.h>
+#endif
+
+#ifdef PKT_FILTER_SUPPORT
+extern uint dhd_pkt_filter_enable;
+extern uint dhd_master_mode;
+extern void dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode);
+#endif
+
+static int dhd_dongle_up = FALSE;
+#define PKT_FILTER_BUF_SIZE 64
+
+#if defined(BCMDONGLEHOST)
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhdioctl.h>
+#include <wlioctl.h>
+#include <brcm_nl80211.h>
+#include <dhd_cfg80211.h>
+#endif /* defined(BCMDONGLEHOST) */
+
+static s32 wl_dongle_up(struct net_device *ndev);
+static s32 wl_dongle_down(struct net_device *ndev);
+#ifndef OEM_ANDROID
+static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
+#ifdef BCMSDIO /* glomming is a sdio specific feature */
+static s32 wl_dongle_glom(struct net_device *ndev, s32 glom, u32 dongle_align);
+#endif
+static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, s32 scan_unassoc_time);
+static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol);
+static s32 wl_pattern_atoh(s8 *src, s8 *dst);
+static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
+#endif /* !OEM_ANDROID */
+
+/**
+ * Function implementations
+ */
+
+s32 dhd_cfg80211_init(struct bcm_cfg80211 *cfg)
+{
+	dhd_dongle_up = FALSE;
+	return 0;
+}
+
+s32 dhd_cfg80211_deinit(struct bcm_cfg80211 *cfg)
+{
+	dhd_dongle_up = FALSE;
+	return 0;
+}
+
+s32 dhd_cfg80211_down(struct bcm_cfg80211 *cfg)
+{
+	struct net_device *ndev;
+	s32 err = 0;
+
+	WL_TRACE(("In\n"));
+	if (!dhd_dongle_up) {
+		WL_INFORM_MEM(("Dongle is already down\n"));
+		err = 0;
+		goto done;
+	}
+	ndev = bcmcfg_to_prmry_ndev(cfg);
+	wl_dongle_down(ndev);
+done:
+	return err;
+}
+
+s32 dhd_cfg80211_set_p2p_info(struct bcm_cfg80211 *cfg, int val)
+{
+	dhd_pub_t *dhd =  (dhd_pub_t *)(cfg->pub);
+	dhd->op_mode |= val;
+	WL_ERR(("Set : op_mode=0x%04x\n", dhd->op_mode));
+
+	return 0;
+}
+
+s32 dhd_cfg80211_clean_p2p_info(struct bcm_cfg80211 *cfg)
+{
+	dhd_pub_t *dhd =  (dhd_pub_t *)(cfg->pub);
+	dhd->op_mode &= ~(DHD_FLAG_P2P_GC_MODE | DHD_FLAG_P2P_GO_MODE);
+	WL_ERR(("Clean : op_mode=0x%04x\n", dhd->op_mode));
+
+	return 0;
+}
+#ifdef WL_STATIC_IF
+int32
+wl_cfg80211_update_iflist_info(struct bcm_cfg80211 *cfg, struct net_device *ndev,
+	int ifidx, uint8 *addr, int bssidx, char *name, int if_state)
+{
+		return dhd_update_iflist_info(cfg->pub, ndev, ifidx, addr, bssidx, name, if_state);
+}
+#endif /* WL_STATIC_IF */
+struct net_device* wl_cfg80211_allocate_if(struct bcm_cfg80211 *cfg, int ifidx, const char *name,
+	uint8 *mac, uint8 bssidx, const char *dngl_name)
+{
+	return dhd_allocate_if(cfg->pub, ifidx, name, mac, bssidx, FALSE, dngl_name);
+}
+
+int wl_cfg80211_register_if(struct bcm_cfg80211 *cfg,
+	int ifidx, struct net_device* ndev, bool rtnl_lock_reqd)
+{
+	return dhd_register_if(cfg->pub, ifidx, rtnl_lock_reqd);
+}
+
+int wl_cfg80211_remove_if(struct bcm_cfg80211 *cfg,
+	int ifidx, struct net_device* ndev, bool rtnl_lock_reqd)
+{
+	return dhd_remove_if(cfg->pub, ifidx, rtnl_lock_reqd);
+}
+
+void wl_cfg80211_cleanup_if(struct net_device *net)
+{
+	struct bcm_cfg80211 *cfg = wl_get_cfg(net);
+	BCM_REFERENCE(cfg);
+	dhd_cleanup_if(net);
+}
+
+struct net_device * dhd_cfg80211_netdev_free(struct net_device *ndev)
+{
+	struct bcm_cfg80211 *cfg;
+
+	if (ndev) {
+		cfg = wl_get_cfg(ndev);
+		if (ndev->ieee80211_ptr) {
+			MFREE(cfg->osh, ndev->ieee80211_ptr, sizeof(struct wireless_dev));
+			ndev->ieee80211_ptr = NULL;
+		}
+		free_netdev(ndev);
+		return NULL;
+	}
+
+	return ndev;
+}
+
+void dhd_netdev_free(struct net_device *ndev)
+{
+#ifdef WL_CFG80211
+	ndev = dhd_cfg80211_netdev_free(ndev);
+#endif
+	if (ndev)
+		free_netdev(ndev);
+}
+
+static s32
+wl_dongle_up(struct net_device *ndev)
+{
+	s32 err = 0;
+	u32 local_up = 0;
+#ifdef WLAN_ACCEL_BOOT
+	u32 bus_host_access = 1;
+	err = wldev_iovar_setint(ndev, "bus:host_access", bus_host_access);
+	if (unlikely(err)) {
+		WL_ERR(("bus:host_access(%d) error (%d)\n", bus_host_access, err));
+	}
+#endif /* WLAN_ACCEL_BOOT */
+	err = wldev_ioctl_set(ndev, WLC_UP, &local_up, sizeof(local_up));
+	if (unlikely(err)) {
+		WL_ERR(("WLC_UP error (%d)\n", err));
+	} else {
+		WL_INFORM_MEM(("wl up\n"));
+		dhd_dongle_up = TRUE;
+	}
+	return err;
+}
+
+static s32
+wl_dongle_down(struct net_device *ndev)
+{
+	s32 err = 0;
+	u32 local_down = 0;
+#ifdef WLAN_ACCEL_BOOT
+	u32 bus_host_access = 0;
+#endif /* WLAN_ACCEL_BOOT */
+
+	err = wldev_ioctl_set(ndev, WLC_DOWN, &local_down, sizeof(local_down));
+	if (unlikely(err)) {
+		WL_ERR(("WLC_DOWN error (%d)\n", err));
+	}
+#ifdef WLAN_ACCEL_BOOT
+	err = wldev_iovar_setint(ndev, "bus:host_access", bus_host_access);
+	if (unlikely(err)) {
+		WL_ERR(("bus:host_access(%d) error (%d)\n", bus_host_access, err));
+	}
+#endif /* WLAN_ACCEL_BOOT */
+	WL_INFORM_MEM(("wl down\n"));
+	dhd_dongle_up = FALSE;
+
+	return err;
+}
+
+#ifndef OEM_ANDROID
+static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode)
+{
+	s32 err = 0;
+
+	WL_TRACE(("In\n"));
+	err = wldev_ioctl_set(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode));
+	if (unlikely(err)) {
+		WL_ERR(("WLC_SET_PM error (%d)\n", err));
+	}
+	return err;
+}
+
+#ifdef BCMSDIO
+static s32
+wl_dongle_glom(struct net_device *ndev, s32 glom, u32 dongle_align)
+{
+	s32 err = 0;
+
+	/* Match Host and Dongle rx alignment */
+	err = wldev_iovar_setint(ndev, "bus:txglomalign", dongle_align);
+	if (unlikely(err)) {
+		WL_ERR(("txglomalign error (%d)\n", err));
+		goto dongle_glom_out;
+	}
+	/* disable glom option per default */
+	if (glom != DEFAULT_GLOM_VALUE) {
+		err = wldev_iovar_setint(ndev, "bus:txglom", glom);
+		if (unlikely(err)) {
+			WL_ERR(("txglom error (%d)\n", err));
+			goto dongle_glom_out;
+		}
+	}
+dongle_glom_out:
+	return err;
+}
+
+#endif /* BCMSDIO */
+#endif /* !OEM_ANDROID */
+
+s32
+wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
+{
+	s32 err = 0;
+
+	/* Setup timeout if Beacons are lost and roam is off to report link down */
+	if (roamvar) {
+		err = wldev_iovar_setint(ndev, "bcn_timeout", bcn_timeout);
+		if (unlikely(err)) {
+			WL_ERR(("bcn_timeout error (%d)\n", err));
+			goto dongle_rom_out;
+		}
+	}
+	/* Enable/Disable built-in roaming to allow supplicant to take care of roaming */
+	err = wldev_iovar_setint(ndev, "roam_off", roamvar);
+	if (unlikely(err)) {
+		WL_ERR(("roam_off error (%d)\n", err));
+		goto dongle_rom_out;
+	}
+	ROAMOFF_DBG_SAVE(ndev, SET_ROAM_FILS_TOGGLE, roamvar);
+dongle_rom_out:
+	return err;
+}
+
+#ifndef OEM_ANDROID
+static s32
+wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
+	s32 scan_unassoc_time)
+{
+	s32 err = 0;
+
+	err = wldev_ioctl_set(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
+		sizeof(scan_assoc_time));
+	if (err) {
+		if (err == -EOPNOTSUPP) {
+			WL_INFORM(("Scan assoc time is not supported\n"));
+		} else {
+			WL_ERR(("Scan assoc time error (%d)\n", err));
+		}
+		goto dongle_scantime_out;
+	}
+	err = wldev_ioctl_set(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
+		sizeof(scan_unassoc_time));
+	if (err) {
+		if (err == -EOPNOTSUPP) {
+			WL_INFORM(("Scan unassoc time is not supported\n"));
+		} else {
+			WL_ERR(("Scan unassoc time error (%d)\n", err));
+		}
+		goto dongle_scantime_out;
+	}
+
+dongle_scantime_out:
+	return err;
+}
+
+static s32
+wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
+{
+	s8 iovbuf[WLC_IOCTL_SMLEN];
+	s32 err = 0;
+	s32 len;
+	struct bcm_cfg80211 *cfg = wl_get_cfg(ndev);
+	dhd_pub_t *dhd = (dhd_pub_t *)(cfg->pub);
+
+	/* Set ARP offload */
+	len = bcm_mkiovar("arpoe", (char *)&arpoe, sizeof(arpoe), iovbuf, sizeof(iovbuf));
+	if (!len) {
+		WL_ERR(("%s: bcm_mkiovar failed:%d\n", __FUNCTION__, len));
+		return BCME_BADARG;
+	}
+	err = wldev_ioctl_set(ndev, WLC_SET_VAR, iovbuf, len);
+	if (err) {
+		if (err == -EOPNOTSUPP)
+			WL_INFORM(("arpoe is not supported\n"));
+		else
+			WL_ERR(("arpoe error (%d)\n", err));
+
+		goto dongle_offload_out;
+	}
+	len = bcm_mkiovar("arp_ol", (char *)&arp_ol, sizeof(arp_ol), iovbuf, sizeof(iovbuf));
+	if (!len) {
+		WL_ERR(("%s: bcm_mkiovar failed:%d\n", __FUNCTION__, len));
+		return BCME_BADARG;
+	}
+	err = wldev_ioctl_set(ndev, WLC_SET_VAR, iovbuf, len);
+	if (err) {
+		if (err == -EOPNOTSUPP)
+			WL_INFORM(("arp_ol is not supported\n"));
+		else
+			WL_ERR(("arp_ol error (%d)\n", err));
+
+		goto dongle_offload_out;
+	}
+
+	dhd->arpoe_enable = TRUE;
+	dhd->arpol_configured = TRUE;
+	WL_ERR(("arpoe:%d arpol:%d\n",
+		dhd->arpoe_enable, dhd->arpol_configured));
+
+dongle_offload_out:
+	return err;
+}
+
+static s32 wl_pattern_atoh(s8 *src, s8 *dst)
+{
+	int i;
+	if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
+		WL_ERR(("Mask invalid format. Needs to start with 0x\n"));
+		return -1;
+	}
+	src = src + 2;		/* Skip past 0x */
+	if (strlen(src) % 2 != 0) {
+		WL_ERR(("Mask invalid format. Needs to be of even length\n"));
+		return -1;
+	}
+
+	for (i = 0; *src != '\0'; i++) {
+		char num[3];
+		if ((num[0] = src[0]) != '\0') {
+			num[1] = src[1];
+		}
+		num[2] = '\0';
+		dst[i] = (u8) simple_strtoul(num, NULL, 16);
+		src += 2;
+	}
+
+	return i;
+}
+
+static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode)
+{
+	const s8 *str;
+	struct wl_pkt_filter pkt_filter;
+	struct wl_pkt_filter *pkt_filterp;
+	s32 buf_len;
+	s32 str_len;
+	u32 mask_size;
+	u32 pattern_size;
+	s8 buf[PKT_FILTER_BUF_SIZE] = {0};
+	s32 err = 0;
+
+	/* add a default packet filter pattern */
+	str = "pkt_filter_add";
+	str_len = strlen(str);
+	strlcpy(buf, str, sizeof(buf));
+	buf_len = str_len + 1;
+
+	pkt_filterp = (struct wl_pkt_filter *)(buf + str_len + 1);
+
+	/* Parse packet filter id. */
+	pkt_filter.id = htod32(100);
+
+	/* Parse filter polarity. */
+	pkt_filter.negate_match = htod32(0);
+
+	/* Parse filter type. */
+	pkt_filter.type = htod32(0);
+
+	/* Parse pattern filter offset. */
+	pkt_filter.u.pattern.offset = htod32(0);
+
+	/* Parse pattern filter mask. */
+	mask_size = htod32(wl_pattern_atoh("0xff",
+		(char *)pkt_filterp->u.pattern.
+		    mask_and_pattern));
+
+	if (mask_size == (typeof(mask_size))-1 ||
+		(mask_size > (PKT_FILTER_BUF_SIZE - (buf_len) +
+		WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN))) {
+		/* mask_size has to be equal to pattern_size */
+		err = -EINVAL;
+		goto dongle_filter_out;
+	}
+	/* Parse pattern filter pattern. */
+	pattern_size = htod32(wl_pattern_atoh("0x00",
+		(char *)&pkt_filterp->u.pattern.mask_and_pattern[mask_size]));
+
+	if (mask_size != pattern_size) {
+		WL_ERR(("Mask and pattern not the same size\n"));
+		err = -EINVAL;
+		goto dongle_filter_out;
+	}
+
+	pkt_filter.u.pattern.size_bytes = mask_size;
+	buf_len += WL_PKT_FILTER_FIXED_LEN;
+	buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
+
+	/* Keep-alive attributes are set in local
+	 * variable (keep_alive_pkt), and
+	 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
+	 * guarantee that the buffer is properly aligned.
+	 */
+	memcpy((char *)pkt_filterp, &pkt_filter,
+		WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
+
+	err = wldev_ioctl_set(ndev, WLC_SET_VAR, buf, buf_len);
+	if (err) {
+		if (err == -EOPNOTSUPP) {
+			WL_INFORM(("filter not supported\n"));
+		} else {
+			WL_ERR(("filter (%d)\n", err));
+		}
+		goto dongle_filter_out;
+	}
+
+	/* set mode to allow pattern */
+	err = wldev_iovar_setint(ndev, "pkt_filter_mode", filter_mode);
+	if (err) {
+		if (err == -EOPNOTSUPP) {
+			WL_INFORM(("filter_mode not supported\n"));
+		} else {
+			WL_ERR(("filter_mode (%d)\n", err));
+		}
+		goto dongle_filter_out;
+	}
+
+dongle_filter_out:
+	return err;
+}
+#endif /* !OEM_ANDROID */
+
+s32 dhd_config_dongle(struct bcm_cfg80211 *cfg)
+{
+#ifndef DHD_SDALIGN
+#define DHD_SDALIGN	32
+#endif
+	struct net_device *ndev;
+	s32 err = 0;
+	dhd_pub_t *dhd = NULL;
+#if !defined(OEM_ANDROID) && defined(BCMSDIO)
+	s32 glom = CUSTOM_GLOM_SETTING;
+	BCM_REFERENCE(glom);
+#endif
+
+	WL_TRACE(("In\n"));
+
+	ndev = bcmcfg_to_prmry_ndev(cfg);
+	dhd = (dhd_pub_t *)(cfg->pub);
+
+	err = wl_dongle_up(ndev);
+	if (unlikely(err)) {
+		WL_ERR(("wl_dongle_up failed\n"));
+		goto default_conf_out;
+	}
+
+	if (dhd && dhd->fw_preinit) {
+		/* Init config will be done by fw preinit context */
+		return BCME_OK;
+	}
+
+#ifndef OEM_ANDROID
+	err = wl_dongle_power(ndev, PM_FAST);
+	if (unlikely(err)) {
+		WL_ERR(("wl_dongle_power failed\n"));
+		goto default_conf_out;
+	}
+#ifdef BCMSDIO
+	err = wl_dongle_glom(ndev, glom, DHD_SDALIGN);
+	if (unlikely(err)) {
+		WL_ERR(("wl_dongle_glom failed\n"));
+		goto default_conf_out;
+	}
+#endif /* BCMSDIO */
+	err = wl_dongle_roam(ndev, (cfg->roam_on ? 0 : 1), 3);
+	if (unlikely(err)) {
+		WL_ERR(("wl_dongle_roam failed\n"));
+		goto default_conf_out;
+	}
+	wl_dongle_scantime(ndev, 40, 80);
+	wl_dongle_offload(ndev, 1, 0xf);
+	wl_dongle_filter(ndev, 1);
+#endif /* OEM_ANDROID */
+
+default_conf_out:
+
+	return err;
+
+}
+
+int dhd_cfgvendor_priv_string_handler(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev,
+	const struct bcm_nlmsg_hdr *nlioc, void *buf)
+{
+	struct net_device *ndev = NULL;
+	dhd_pub_t *dhd;
+	dhd_ioctl_t ioc = { 0, NULL, 0, 0, 0, 0, 0};
+	int ret = 0;
+	int8 index;
+
+	WL_TRACE(("entry: cmd = %d\n", nlioc->cmd));
+
+	dhd = cfg->pub;
+	DHD_OS_WAKE_LOCK(dhd);
+
+	ndev = wdev_to_wlc_ndev(wdev, cfg);
+	index = dhd_net2idx(dhd->info, ndev);
+	if (index == DHD_BAD_IF) {
+		WL_ERR(("Bad ifidx from wdev:%p\n", wdev));
+		ret = BCME_ERROR;
+		goto done;
+	}
+
+	ioc.cmd = nlioc->cmd;
+	ioc.len = nlioc->len;
+	ioc.set = nlioc->set;
+	ioc.driver = nlioc->magic;
+	ioc.buf = buf;
+	ret = dhd_ioctl_process(dhd, index, &ioc, buf);
+	if (ret) {
+		WL_TRACE(("dhd_ioctl_process return err %d\n", ret));
+		ret = OSL_ERROR(ret);
+		goto done;
+	}
+
+done:
+	DHD_OS_WAKE_UNLOCK(dhd);
+	return ret;
+}
+
+int
+dhd_set_wsec_info(dhd_pub_t *dhd, uint32 data, int tag)
+{
+	struct net_device *ndev;
+	uint32  wsec_info = data;
+	int ret = BCME_OK;
+
+	ndev = dhd_linux_get_primary_netdev(dhd);
+	if (!ndev) {
+		WL_ERR(("Cannot find primary netdev\n"));
+		return -ENODEV;
+	}
+	BCM_REFERENCE(wsec_info);
+#if defined(WL_CFG80211)
+	ret = wl_cfg80211_set_wsec_info(ndev, &wsec_info, sizeof(wsec_info), tag);
+	if (unlikely(ret)) {
+		WL_ERR(("Set wsec_info tag 0x%04x failed \n", tag));
+	}
+#endif /* WL_CFG80211 */
+
+	return ret;
+}
+
+#ifdef RPM_FAST_TRIGGER
+void
+dhd_trigger_rpm_fast(struct bcm_cfg80211 *cfg)
+{
+	dhd_pub_t *dhd = (dhd_pub_t *)cfg->pub;
+	dhdpcie_trigger_rpm_fast(dhd);
+}
+#endif /* RPM_FAST_TRIGGER */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_cfg80211.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_cfg80211.h
@@ -0,0 +1,72 @@
+/*
+ * Linux cfg80211 driver - Dongle Host Driver (DHD) related
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef __DHD_CFG80211__
+#define __DHD_CFG80211__
+
+#include <wl_cfg80211.h>
+#include <wl_cfgp2p.h>
+#include <brcm_nl80211.h>
+
+#ifndef WL_ERR
+#define WL_ERR CFG80211_ERR
+#endif
+#ifndef WL_TRACE
+#define WL_TRACE CFG80211_TRACE
+#endif
+
+s32 dhd_cfg80211_init(struct bcm_cfg80211 *cfg);
+s32 dhd_cfg80211_deinit(struct bcm_cfg80211 *cfg);
+s32 dhd_cfg80211_down(struct bcm_cfg80211 *cfg);
+s32 dhd_cfg80211_set_p2p_info(struct bcm_cfg80211 *cfg, int val);
+s32 dhd_cfg80211_clean_p2p_info(struct bcm_cfg80211 *cfg);
+s32 dhd_config_dongle(struct bcm_cfg80211 *cfg);
+int dhd_cfgvendor_priv_string_handler(struct bcm_cfg80211 *cfg,
+	struct wireless_dev *wdev, const struct bcm_nlmsg_hdr *nlioc, void  *data);
+s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout);
+int dhd_set_wsec_info(dhd_pub_t *dhd, uint32 data, int tag);
+#ifdef RPM_FAST_TRIGGER
+void dhd_trigger_rpm_fast(struct bcm_cfg80211 *cfg);
+#endif /* RPM_FAST_TRIGGER */
+#endif /* __DHD_CFG80211__ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_common.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_common.c
@@ -0,0 +1,12283 @@
+/*
+ * Broadcom Dongle Host Driver (DHD), common DHD core.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+#include <typedefs.h>
+#include <osl.h>
+
+#include <epivers.h>
+#include <bcmutils.h>
+#include <bcmstdlib_s.h>
+
+#include <bcmdevs.h>
+#include <bcmendian.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_ip.h>
+#include <bcmevent.h>
+#include <dhdioctl.h>
+#ifdef DHD_SDTC_ETB_DUMP
+#include <bcmiov.h>
+#endif /* DHD_SDTC_ETB_DUMP */
+
+#if defined(DHD_MACDBG) && defined(BCMDBG)
+#include <dhd_macdbg.h>
+#endif /* defined(DHD_MACDBG) && defined(BCMDBG) */
+
+#ifdef PCIE_FULL_DONGLE
+#include <bcmmsgbuf.h>
+#endif /* PCIE_FULL_DONGLE */
+
+#ifdef SHOW_LOGTRACE
+#include <event_log.h>
+#endif /* SHOW_LOGTRACE */
+
+#ifdef BCMPCIE
+#include <dhd_flowring.h>
+#endif
+
+#include <dhd_bus.h>
+#include <dhd_proto.h>
+#include <bcmsdbus.h>
+#include <dhd_dbg.h>
+#include <802.1d.h>
+#include <dhd_debug.h>
+#ifdef DHD_LOG_DUMP
+#include <dhd_log_dump.h>
+#endif
+#include <dhd_dbg_ring.h>
+#include <dhd_mschdbg.h>
+#include <msgtrace.h>
+#include <dhd_config.h>
+#include <wl_android.h>
+
+#ifdef WL_CFG80211
+#include <wl_cfg80211.h>
+#include <wl_cfgvif.h>
+#endif
+#if defined(OEM_ANDROID) && defined(PNO_SUPPORT)
+#include <dhd_pno.h>
+#endif /* (OEM_ANDROID) && (PNO_SUPPORT) */
+#ifdef RTT_SUPPORT
+#include <dhd_rtt.h>
+#endif
+
+#ifdef DNGL_EVENT_SUPPORT
+#include <dnglevent.h>
+#endif
+
+#ifdef IL_BIGENDIAN
+#include <bcmendian.h>
+#define htod32(i) (bcmswap32(i))
+#define htod16(i) (bcmswap16(i))
+#define dtoh32(i) (bcmswap32(i))
+#define dtoh16(i) (bcmswap16(i))
+#define htodchanspec(i) htod16(i)
+#define dtohchanspec(i) dtoh16(i)
+#else
+#define htod32(i) (i)
+#define htod16(i) (i)
+#define dtoh32(i) (i)
+#define dtoh16(i) (i)
+#define htodchanspec(i) (i)
+#define dtohchanspec(i) (i)
+#endif /* IL_BIGENDINA */
+
+#ifdef PROP_TXSTATUS
+#include <wlfc_proto.h>
+#include <dhd_wlfc.h>
+#endif
+
+#if defined(__linux__)
+#include <dhd_linux.h>
+#endif /* __linux__ */
+
+#ifdef DHD_WMF
+#include <dhd_wmf_linux.h>
+#endif /* DHD_WMF */
+
+#ifdef DHD_L2_FILTER
+#include <dhd_l2_filter.h>
+#endif /* DHD_L2_FILTER */
+
+#ifdef DHD_PSTA
+#include <dhd_psta.h>
+#endif /* DHD_PSTA */
+
+#ifdef DHD_WET
+#include <dhd_wet.h>
+#endif /* DHD_WET */
+#if defined(NDIS)
+#include <siutils.h>
+#endif
+
+#ifdef DHD_LOG_DUMP
+#include <dhd_dbg.h>
+#ifdef DHD_PKT_LOGGING
+#include <dhd_pktlog.h>
+#endif
+#endif /* DHD_LOG_DUMP */
+
+#ifdef CSI_SUPPORT
+#include <dhd_csi.h>
+#endif /* CSI_SUPPORT */
+
+#ifdef DHD_LOG_PRINT_RATE_LIMIT
+int log_print_threshold = 0;
+#endif /* DHD_LOG_PRINT_RATE_LIMIT */
+
+/* dhd_msg_level : a default level to print to dmesg buffer
+ * dhd_log_level : a default level to log to DLD or Ring
+ * To keep one level operation(dhd_msg_level) in HW4,
+ * dhd_msg_level and dhd_log_level have the same level
+ */
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+int dhd_msg_level = DHD_ERROR_VAL | DHD_EVENT_VAL
+#ifdef SYNAINTERNAL
+		| DHD_MSGTRACE_VAL
+		| DHD_FWLOG_VAL
+		| DHD_IOVAR_MEM_VAL
+#endif /* SYNAINTERNAL */
+#ifdef BOARD_HIKEY
+		| DHD_FWLOG_VAL
+#endif /* BOARD_HIKEY */
+#ifndef DHD_REDUCE_PM_LOG
+		| DHD_RPM_VAL
+#endif /* REDUCE_PM_LOG */
+	        | DHD_PKT_MON_VAL;
+int dhd_log_level = DHD_ERROR_VAL | DHD_EVENT_VAL
+#ifdef SYNAINTERNAL
+		| DHD_MSGTRACE_VAL
+#endif /* SYNAINTERNAL */
+		| DHD_RPM_VAL
+		| DHD_PKT_MON_VAL | DHD_FWLOG_VAL | DHD_IOVAR_MEM_VAL;
+#else
+/* For CUSTOMER_HW4/Hikey do not enable DHD_ERROR_MEM_VAL by default */
+int dhd_msg_level = DHD_ERROR_VAL | DHD_FWLOG_VAL;
+
+int dhd_log_level = DHD_ERROR_VAL | DHD_FWLOG_VAL | DHD_EVENT_VAL
+	/* For CUSTOMER_HW4 do not enable DHD_IOVAR_MEM_VAL by default */
+#if !defined(BOARD_HIKEY)
+	| DHD_IOVAR_MEM_VAL
+#endif
+#ifndef OEM_ANDROID
+	| DHD_MSGTRACE_VAL
+#endif /* OEM_ANDROID */
+	| DHD_RPM_VAL
+	| DHD_PKT_MON_VAL;
+
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
+
+#ifdef NDIS
+extern uint wl_msg_level;
+#endif
+
+#if defined(WL_WLC_SHIM)
+#include <wl_shim.h>
+#else
+#if defined(NDIS)
+#include <wl_port_if.h>
+#endif
+#endif /* WL_WLC_SHIM */
+
+#ifdef DHD_DEBUG
+#include <sdiovar.h>
+#endif /* DHD_DEBUG */
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+#include <linux/pm_runtime.h>
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+#if defined(DHD_LOGLEVEL) && !defined(DHD_DEBUG)
+#error "Log level control is supported only with DHD_DEBUG"
+#endif  /* defined(DHD_LOGLEVEL) && !defined(DHD_DEBUG) */
+
+#ifdef SOFTAP
+char fw_path2[MOD_PARAM_PATHLEN];
+extern bool softap_enabled;
+#endif
+#ifdef PROP_TXSTATUS
+extern int disable_proptx;
+#endif /* PROP_TXSTATUS */
+
+#ifdef REPORT_FATAL_TIMEOUTS
+/* Default timeout value in ms */
+#define BUS_TIMEOUT_DEFAULT     800
+#define CMD_TIMEOUT_DEFAULT     1200
+#define SCAN_TIMEOUT_DEFAULT    17000
+#define JOIN_TIMEOUT_DEFAULT    7500
+#endif /* REPORT_FATAL_TIMEOUTS */
+
+#ifdef SHOW_LOGTRACE
+#define BYTES_AHEAD_NUM		10	/* address in map file is before these many bytes */
+#define READ_NUM_BYTES		1000 /* read map file each time this No. of bytes */
+#define GO_BACK_FILE_POS_NUM_BYTES	100 /* set file pos back to cur pos */
+static char *ramstart_str = " text_start"; /* string in mapfile has addr ramstart */
+static char *rodata_start_str = " rodata_start"; /* string in mapfile has addr rodata start */
+static char *rodata_end_str = " rodata_end"; /* string in mapfile has addr rodata end */
+#define RAMSTART_BIT	0x01
+#define RDSTART_BIT		0x02
+#define RDEND_BIT		0x04
+#define ALL_MAP_VAL		(RAMSTART_BIT | RDSTART_BIT | RDEND_BIT)
+#endif /* SHOW_LOGTRACE */
+
+#ifdef SHOW_LOGTRACE
+#if defined(LINUX) || defined(linux)
+/* the fw file path is taken from either the module parameter at
+ * insmod time or is defined as a constant of different values
+ * for different platforms
+ */
+extern char *st_str_file_path;
+#else
+static char *st_str_file_path = "rtecdc.bin";
+#endif /* LINUX */
+#endif /* SHOW_LOGTRACE */
+
+#ifdef EWP_EDL
+typedef struct msg_hdr_edl {
+	uint32 infobuf_ver;
+	info_buf_payload_hdr_t pyld_hdr;
+	msgtrace_hdr_t trace_hdr;
+} msg_hdr_edl_t;
+#endif /* EWP_EDL */
+
+#define DHD_TPUT_MAX_TX_PKTS_BATCH	1000
+
+/* Last connection success/failure status */
+uint32 dhd_conn_event;
+uint32 dhd_conn_status;
+uint32 dhd_conn_reason;
+
+extern int dhd_iscan_request(void * dhdp, uint16 action);
+extern void dhd_ind_scan_confirm(void *h, bool status);
+extern int dhd_iscan_in_progress(void *h);
+void dhd_iscan_lock(void);
+void dhd_iscan_unlock(void);
+extern int dhd_change_mtu(dhd_pub_t *dhd, int new_mtu, int ifidx);
+
+#ifndef BCMDBUS
+extern int dhd_socram_dump(struct dhd_bus *bus);
+#endif /* BCMDBUS */
+
+extern void dhd_set_packet_filter(dhd_pub_t *dhd);
+
+#ifdef DNGL_EVENT_SUPPORT
+static void dngl_host_event_process(dhd_pub_t *dhdp, bcm_dngl_event_t *event,
+	bcm_dngl_event_msg_t *dngl_event, size_t pktlen);
+static int dngl_host_event(dhd_pub_t *dhdp, void *pktdata, bcm_dngl_event_msg_t *dngl_event,
+	size_t pktlen);
+#endif /* DNGL_EVENT_SUPPORT */
+
+#ifdef WL_CFGVENDOR_SEND_HANG_EVENT
+static void copy_hang_info_ioctl_timeout(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc);
+#endif /* WL_CFGVENDOR_SEND_HANG_EVENT */
+
+#ifdef REPORT_FATAL_TIMEOUTS
+static void dhd_set_join_error(dhd_pub_t *pub, uint32 mask);
+#endif /* REPORT_FATAL_TIMEOUTS */
+
+#ifdef DHD_SEND_HANG_IOCTL_SUSPEND_ERROR
+#define MAX_IOCTL_SUSPEND_ERROR	10
+static int ioctl_suspend_error = 0;
+#endif /* DHD_SEND_HANG_IOCTL_SUSPEND_ERROR */
+
+/* Should ideally read this from target(taken from wlu) */
+#define MAX_CHUNK_LEN 1408 /* 8 * 8 * 22 */
+
+#if defined(OEM_ANDROID)
+/* note these variables will be used with wext */
+bool ap_cfg_running = FALSE;
+bool ap_fw_loaded = FALSE;
+#endif /* defined(OEM_ANDROID) && defined(SOFTAP) */
+
+#ifdef WLEASYMESH
+extern int dhd_set_1905_almac(dhd_pub_t *dhdp, uint8 ifidx, uint8* ea, bool mcast);
+extern int dhd_get_1905_almac(dhd_pub_t *dhdp, uint8 ifidx, uint8* ea, bool mcast);
+#endif /* WLEASYMESH */
+
+#define CHIPID_MISMATCH	8
+
+#define DHD_VERSION "Dongle Host Driver, version " EPI_VERSION_STR EPI_COMMIT_ID "\n"
+
+#if defined(DHD_DEBUG) && defined(DHD_COMPILED)
+const char dhd_version[] = DHD_VERSION DHD_COMPILED " compiled on "
+			__DATE__ " at " __TIME__ "\n\0<TIMESTAMP>";
+#else
+const char dhd_version[] = DHD_VERSION;
+#endif /* DHD_DEBUG && DHD_COMPILED */
+
+char fw_version[FW_VER_STR_LEN] = "\0";
+char clm_version[CLM_VER_STR_LEN] = "\0";
+
+char bus_api_revision[BUS_API_REV_STR_LEN] = "\0";
+
+void dhd_set_timer(void *bus, uint wdtick);
+
+#if defined(BCM_ROUTER_DHD)
+static int traffic_mgmt_add_dwm_filter(dhd_pub_t *dhd,
+	trf_mgmt_filter_list_t * trf_mgmt_filter_list, int len);
+#endif
+
+static char* ioctl2str(uint32 ioctl);
+
+#ifdef DHD_LOGLEVEL
+void dhd_loglevel_set(dhd_loglevel_data_t *);
+void dhd_loglevel_get(dhd_loglevel_data_t *);
+#endif /* DHD_LOGLEVEL */
+
+/* IOVar table */
+enum {
+	IOV_VERSION = 1,
+	IOV_WLMSGLEVEL,
+	IOV_MSGLEVEL,
+	IOV_BCMERRORSTR,
+	IOV_BCMERROR,
+	IOV_WDTICK,
+	IOV_DUMP,
+	IOV_RESET_COUNTS,
+	IOV_LOGDUMP,
+	IOV_LOGCAL,
+	IOV_LOGSTAMP,
+	IOV_GPIOOB,
+	IOV_IOCTLTIMEOUT,
+	IOV_CONS,
+	IOV_DCONSOLE_POLL,
+#if defined(DHD_DEBUG)
+	IOV_DHD_JOIN_TIMEOUT_DBG,
+	IOV_SCAN_TIMEOUT,
+	IOV_MEM_DEBUG,
+#ifdef BCMPCIE
+	IOV_FLOW_RING_DEBUG,
+#endif /* BCMPCIE */
+#endif /* defined(DHD_DEBUG) */
+#ifdef PROP_TXSTATUS
+	IOV_PROPTXSTATUS_ENABLE,
+	IOV_PROPTXSTATUS_MODE,
+	IOV_PROPTXSTATUS_OPT,
+#ifdef QMONITOR
+	IOV_QMON_TIME_THRES,
+	IOV_QMON_TIME_PERCENT,
+#endif /* QMONITOR */
+	IOV_PROPTXSTATUS_MODULE_IGNORE,
+	IOV_PROPTXSTATUS_CREDIT_IGNORE,
+	IOV_PROPTXSTATUS_TXSTATUS_IGNORE,
+	IOV_PROPTXSTATUS_RXPKT_CHK,
+#endif /* PROP_TXSTATUS */
+	IOV_BUS_TYPE,
+	IOV_CHANGEMTU,
+	IOV_HOSTREORDER_FLOWS,
+#ifdef DHDTCPACK_SUPPRESS
+	IOV_TCPACK_SUPPRESS,
+#endif /* DHDTCPACK_SUPPRESS */
+#ifdef DHD_WMF
+	IOV_WMF_BSS_ENAB,
+	IOV_WMF_UCAST_IGMP,
+	IOV_WMF_MCAST_DATA_SENDUP,
+#ifdef WL_IGMP_UCQUERY
+	IOV_WMF_UCAST_IGMP_QUERY,
+#endif /* WL_IGMP_UCQUERY */
+#ifdef DHD_UCAST_UPNP
+	IOV_WMF_UCAST_UPNP,
+#endif /* DHD_UCAST_UPNP */
+	IOV_WMF_PSTA_DISABLE,
+#endif /* DHD_WMF */
+#if defined(BCM_ROUTER_DHD)
+	IOV_TRAFFIC_MGMT_DWM,
+#endif /* BCM_ROUTER_DHD */
+	IOV_AP_ISOLATE,
+#ifdef DHD_L2_FILTER
+	IOV_DHCP_UNICAST,
+	IOV_BLOCK_PING,
+	IOV_PROXY_ARP,
+	IOV_GRAT_ARP,
+	IOV_BLOCK_TDLS,
+#endif /* DHD_L2_FILTER */
+	IOV_DHD_IE,
+#ifdef DHD_PSTA
+	IOV_PSTA,
+#endif /* DHD_PSTA */
+#ifdef DHD_WET
+	IOV_WET,
+	IOV_WET_HOST_IPV4,
+	IOV_WET_HOST_MAC,
+#endif /* DHD_WET */
+	IOV_CFG80211_OPMODE,
+	IOV_ASSERT_TYPE,
+#if defined(NDIS)
+	IOV_WAKEIND,
+#endif /* NDIS */
+#if !defined(NDIS) && !defined(BCM_ROUTER_DHD)
+	IOV_LMTEST,
+#endif
+#ifdef DHD_MCAST_REGEN
+	IOV_MCAST_REGEN_BSS_ENABLE,
+#endif
+#if defined(DHD_MACDBG) && defined(BCMDBG)
+	IOV_MACDBG_PD11REGS,
+	IOV_MACDBG_REGLIST,
+	IOV_MACDBG_PSVMPMEMS,
+#endif /* defined(DHD_MACDBG) && defined(BCMDBG) */
+#ifdef SHOW_LOGTRACE
+	IOV_DUMP_TRACE_LOG,
+#endif /* SHOW_LOGTRACE */
+#ifdef REPORT_FATAL_TIMEOUTS
+	IOV_SCAN_TO,
+	IOV_JOIN_TO,
+	IOV_CMD_TO,
+	IOV_OQS_TO,
+#endif /* REPORT_FATAL_TIMEOUTS */
+	IOV_DONGLE_TRAP_TYPE,
+	IOV_DONGLE_TRAP_INFO,
+	IOV_BPADDR,
+	IOV_DUMP_DONGLE, /**< dumps core registers and d11 memories */
+#if defined(DHD_LOG_DUMP)
+	IOV_LOG_DUMP,
+#endif /* DHD_LOG_DUMP */
+	IOV_TPUT_TEST,
+	IOV_DEBUG_BUF_DEST_STAT,
+#ifdef DHD_DEBUG
+	IOV_INDUCE_ERROR,
+#endif /* DHD_DEBUG */
+	IOV_FIS_TRIGGER,
+#ifdef WL_IFACE_MGMT_CONF
+#ifdef WL_CFG80211
+#ifdef WL_NANP2P
+	IOV_CONC_DISC,
+#endif /* WL_NANP2P */
+#ifdef WL_IFACE_MGMT
+	IOV_IFACE_POLICY,
+#endif /* WL_IFACE_MGMT */
+#endif /* WL_CFG80211 */
+#endif /* WL_IFACE_MGMT_CONF */
+#ifdef RTT_GEOFENCE_CONT
+#if defined(RTT_SUPPORT) && defined(WL_NAN)
+	IOV_RTT_GEOFENCE_TYPE_OVRD,
+#endif /* RTT_SUPPORT && WL_NAN */
+#endif /* RTT_GEOFENCE_CONT */
+	IOV_FW_VBS,
+#ifdef DHD_TX_PROFILE
+	IOV_TX_PROFILE_TAG,
+	IOV_TX_PROFILE_ENABLE,
+	IOV_TX_PROFILE_DUMP,
+#endif /* defined(DHD_TX_PROFILE) */
+	IOV_CHECK_TRAP_ROT,
+#ifdef DHD_LOGLEVEL
+	IOV_LOGLEVEL,
+#endif /* DHD_LOGLEVEL */
+	IOV_COUNTERS,
+#ifdef BCMPCIE
+	IOV_DUMP_FLOWRINGS,
+#endif
+#ifdef SYNA_SAR_CUSTOMER_PARAMETER
+	IOV_SAR_MODE,
+#endif /* SYNA_SAR_CUSTOMER_PARAMETER */
+#ifdef CSI_SUPPORT
+	IOV_CSI_VERSION,
+	IOV_CSI_CONFIG,
+#endif /* CSI_SUPPORT */
+#if defined(EXT_REGD_INFO) && defined(WL_SELF_MANAGED_REGDOM)
+	IOV_REGULATORY_DUMP,
+#endif /* defined(EXT_REGD_INFO) && defined(WL_SELF_MANAGED_REGDOM) */
+#ifdef WLEASYMESH
+	IOV_1905_AL_UCAST,
+	IOV_1905_AL_MCAST,
+#endif /* WLEASYMESH */
+	IOV_LAST
+};
+
+const bcm_iovar_t dhd_iovars[] = {
+	/* name         varid                   flags   flags2 type     minlen */
+	{"version",	IOV_VERSION,		0,	0, IOVT_BUFFER,	0},
+	{"wlmsglevel",	IOV_WLMSGLEVEL,	0,	0,	IOVT_UINT32,	0 },
+#if defined(DHD_DEBUG) || defined(DHD_MSG_LEVEL_SUPPORT)
+	{"msglevel",	IOV_MSGLEVEL,		0,	0, IOVT_UINT32,	0},
+#endif /* DHD_DEBUG || DHD_MSG_LEVEL_SUPPORT */
+#ifdef DHD_DEBUG
+	{"mem_debug",   IOV_MEM_DEBUG,  0,      0,      IOVT_BUFFER,    0 },
+#ifdef BCMPCIE
+	{"flow_ring_debug", IOV_FLOW_RING_DEBUG, 0, 0, IOVT_BUFFER, 0 },
+#endif /* BCMPCIE */
+#ifdef NDIS
+	{"wlmsglevel",	IOV_WLMSGLEVEL,		0,	0, IOVT_UINT32,	0},
+#endif /* NDIS */
+#endif /* DHD_DEBUG */
+	{"bcmerrorstr", IOV_BCMERRORSTR,	0,	0, IOVT_BUFFER,	BCME_STRLEN},
+	{"bcmerror",	IOV_BCMERROR,		0,	0, IOVT_INT8,	0},
+	{"wdtick",	IOV_WDTICK,		0,	0, IOVT_UINT32,	0},
+	{"dump",	IOV_DUMP,		0,	0, IOVT_BUFFER,	DHD_IOCTL_MAXLEN_32K},
+	{"cons",	IOV_CONS,		0,	0, IOVT_BUFFER,	0},
+	{"dconpoll",	IOV_DCONSOLE_POLL,	0,	0, IOVT_UINT32,	0},
+	{"reset_cnts", 	IOV_RESET_COUNTS,	0,	0, IOVT_VOID,	0},
+#ifdef BCMPERFSTATS
+	{"logdump", IOV_LOGDUMP,		0,	0, IOVT_BUFFER,	DHD_IOCTL_MAXLEN},
+	{"logcal",	IOV_LOGCAL,		0,	0, IOVT_UINT32,	0},
+	{"logstamp",	IOV_LOGSTAMP,		0,	0, IOVT_BUFFER,	0},
+#endif
+	{"gpioob",	IOV_GPIOOB,		0,	0, IOVT_UINT32,	0},
+	{"ioctl_timeout", IOV_IOCTLTIMEOUT,	0,	0, IOVT_UINT32,	0},
+#ifdef PROP_TXSTATUS
+	{"proptx",	IOV_PROPTXSTATUS_ENABLE,	0,	0, IOVT_BOOL,	0 },
+	/*
+	set the proptxtstatus operation mode:
+	0 - Do not do any proptxtstatus flow control
+	1 - Use implied credit from a packet status
+	2 - Use explicit credit
+	*/
+	{"ptxmode",	IOV_PROPTXSTATUS_MODE,	0,	0, IOVT_UINT32,	0 },
+	{"proptx_opt", IOV_PROPTXSTATUS_OPT,	0,	0, IOVT_UINT32,	0 },
+#ifdef QMONITOR
+	{"qtime_thres",	IOV_QMON_TIME_THRES,	0,	0, IOVT_UINT32,	0 },
+	{"qtime_percent", IOV_QMON_TIME_PERCENT, 0,	0, IOVT_UINT32,	0 },
+#endif /* QMONITOR */
+	{"pmodule_ignore", IOV_PROPTXSTATUS_MODULE_IGNORE, 0, 0, IOVT_BOOL, 0 },
+	{"pcredit_ignore", IOV_PROPTXSTATUS_CREDIT_IGNORE, 0, 0, IOVT_BOOL, 0 },
+	{"ptxstatus_ignore", IOV_PROPTXSTATUS_TXSTATUS_IGNORE, 0, 0,  IOVT_BOOL, 0 },
+	{"rxpkt_chk", IOV_PROPTXSTATUS_RXPKT_CHK, 0, 0, IOVT_BOOL, 0 },
+#endif /* PROP_TXSTATUS */
+	{"bustype", IOV_BUS_TYPE, 0, 0, IOVT_UINT32, 0},
+	{"changemtu", IOV_CHANGEMTU, 0, 0, IOVT_UINT32, 0 },
+	{"host_reorder_flows", IOV_HOSTREORDER_FLOWS, 0, 0, IOVT_BUFFER,
+	(WLHOST_REORDERDATA_MAXFLOWS + 1) },
+#ifdef DHDTCPACK_SUPPRESS
+	{"tcpack_suppress",	IOV_TCPACK_SUPPRESS,	0,	0, IOVT_UINT8,	0 },
+#endif /* DHDTCPACK_SUPPRESS */
+#ifdef DHD_WMF
+	{"wmf_bss_enable", IOV_WMF_BSS_ENAB,	0,	0, IOVT_BOOL,	0 },
+	{"wmf_ucast_igmp", IOV_WMF_UCAST_IGMP,	0,	0, IOVT_BOOL,	0 },
+	{"wmf_mcast_data_sendup", IOV_WMF_MCAST_DATA_SENDUP,	0,	0, IOVT_BOOL,	0 },
+#ifdef WL_IGMP_UCQUERY
+	{"wmf_ucast_igmp_query", IOV_WMF_UCAST_IGMP_QUERY, (0), 0, IOVT_BOOL, 0 },
+#endif /* WL_IGMP_UCQUERY */
+#ifdef DHD_UCAST_UPNP
+	{"wmf_ucast_upnp", IOV_WMF_UCAST_UPNP, (0), 0, IOVT_BOOL, 0 },
+#endif /* DHD_UCAST_UPNP */
+	{"wmf_psta_disable", IOV_WMF_PSTA_DISABLE, (0), 0, IOVT_BOOL, 0 },
+#endif /* DHD_WMF */
+#if defined(BCM_ROUTER_DHD)
+	{"trf_mgmt_filters_add", IOV_TRAFFIC_MGMT_DWM, (0), 0, IOVT_BUFFER, 0},
+#endif /* BCM_ROUTER_DHD */
+#ifdef DHD_L2_FILTER
+	{"dhcp_unicast", IOV_DHCP_UNICAST, (0), 0, IOVT_BOOL, 0 },
+#endif /* DHD_L2_FILTER */
+	{"ap_isolate", IOV_AP_ISOLATE, (0), 0, IOVT_BOOL, 0},
+#ifdef DHD_L2_FILTER
+	{"block_ping", IOV_BLOCK_PING, (0), 0, IOVT_BOOL, 0},
+	{"proxy_arp", IOV_PROXY_ARP, (0), 0, IOVT_BOOL, 0},
+	{"grat_arp", IOV_GRAT_ARP, (0), 0, IOVT_BOOL, 0},
+	{"block_tdls", IOV_BLOCK_TDLS, (0), IOVT_BOOL, 0},
+#endif /* DHD_L2_FILTER */
+	{"dhd_ie", IOV_DHD_IE, (0), 0, IOVT_BUFFER, 0},
+#ifdef DHD_PSTA
+	/* PSTA/PSR Mode configuration. 0: DIABLED 1: PSTA 2: PSR */
+	{"psta", IOV_PSTA, 0, 0, IOVT_UINT32, 0},
+#endif /* DHD PSTA */
+#ifdef DHD_WET
+	/* WET Mode configuration. 0: DIABLED 1: WET */
+	{"wet", IOV_WET, 0, 0, IOVT_UINT32, 0},
+	{"wet_host_ipv4", IOV_WET_HOST_IPV4, 0, 0, IOVT_UINT32, 0},
+	{"wet_host_mac", IOV_WET_HOST_MAC, 0, 0, IOVT_BUFFER, 0},
+#endif /* DHD WET */
+	{"op_mode",	IOV_CFG80211_OPMODE,	0,	0, IOVT_UINT32,	0 },
+	{"assert_type", IOV_ASSERT_TYPE, (0), 0, IOVT_UINT32, 0},
+#if defined(NDIS)
+	{ "wowl_wakeind", IOV_WAKEIND, 0, 0, IOVT_UINT32, 0 },
+#endif /* NDIS */
+#if !defined(NDIS) && !defined(BCM_ROUTER_DHD)
+	{"lmtest", IOV_LMTEST,	0,	0, IOVT_UINT32,	0 },
+#endif
+#ifdef DHD_MCAST_REGEN
+	{"mcast_regen_bss_enable", IOV_MCAST_REGEN_BSS_ENABLE, 0, 0, IOVT_BOOL, 0},
+#endif
+#if defined(DHD_MACDBG) && defined(BCMDBG)
+	{"pd11regs", IOV_MACDBG_PD11REGS, 0, 0, IOVT_BUFFER, 0},
+	{"mreglist", IOV_MACDBG_REGLIST, 0, 0, IOVT_BUFFER, 0},
+	{"psvmpmems", IOV_MACDBG_PSVMPMEMS, 0, 0, IOVT_BUFFER, 0},
+#endif /* defined(DHD_MACDBG) && defined(BCMDBG) */
+#ifdef SHOW_LOGTRACE
+	{"dump_trace_buf", IOV_DUMP_TRACE_LOG,	0, 0, IOVT_BUFFER,	sizeof(trace_buf_info_t) },
+#endif /* SHOW_LOGTRACE */
+#ifdef REPORT_FATAL_TIMEOUTS
+	{"scan_timeout", IOV_SCAN_TO, 0, 0, IOVT_UINT32, 0 },
+	{"join_timeout", IOV_JOIN_TO, 0, 0, IOVT_UINT32, 0 },
+	{"cmd_timeout", IOV_CMD_TO, 0, 0, IOVT_UINT32, 0 },
+	{"oqs_timeout", IOV_OQS_TO, 0, 0, IOVT_UINT32, 0 },
+#endif /* REPORT_FATAL_TIMEOUTS */
+	{"trap_type", IOV_DONGLE_TRAP_TYPE, 0, 0, IOVT_UINT32, 0 },
+	{"trap_info", IOV_DONGLE_TRAP_INFO, 0, 0, IOVT_BUFFER, sizeof(trap_t) },
+#ifdef DHD_DEBUG
+	{"bpaddr", IOV_BPADDR,	0, 0, IOVT_BUFFER,	sizeof(sdreg_t) },
+#endif /* DHD_DEBUG */
+	{"dump_dongle", IOV_DUMP_DONGLE, 0, 0, IOVT_BUFFER,
+	MAX(sizeof(dump_dongle_in_t), sizeof(dump_dongle_out_t)) },
+#if defined(DHD_LOG_DUMP)
+	{"log_dump", IOV_LOG_DUMP,	0, 0, IOVT_UINT8, 0},
+#endif /* DHD_LOG_DUMP */
+	{"tput_test", IOV_TPUT_TEST, 0, 0, IOVT_BUFFER, sizeof(tput_test_t)},
+	{"debug_buf_dest_stat", IOV_DEBUG_BUF_DEST_STAT, 0, 0, IOVT_UINT32, 0 },
+#if defined(DHD_SSSR_DUMP)
+	{"fis_trigger", IOV_FIS_TRIGGER, 0, 0, IOVT_UINT32, 0},
+#endif
+#ifdef DHD_DEBUG
+	{"induce_error", IOV_INDUCE_ERROR, (0), 0, IOVT_UINT16, 0 },
+#endif /* DHD_DEBUG */
+#ifdef WL_IFACE_MGMT_CONF
+#ifdef WL_CFG80211
+#ifdef WL_NANP2P
+	{"conc_disc", IOV_CONC_DISC, (0), 0, IOVT_UINT16, 0 },
+#endif /* WL_NANP2P */
+#ifdef WL_IFACE_MGMT
+	{"if_policy", IOV_IFACE_POLICY, (0), 0, IOVT_BUFFER, sizeof(iface_mgmt_data_t)},
+#endif /* WL_IFACE_MGMT */
+#endif /* WL_CFG80211 */
+#endif /* WL_IFACE_MGMT_CONF */
+#ifdef RTT_GEOFENCE_CONT
+#if defined(RTT_SUPPORT) && defined(WL_NAN)
+	{"rtt_geofence_type_ovrd", IOV_RTT_GEOFENCE_TYPE_OVRD, (0), 0, IOVT_BOOL, 0},
+#endif /* RTT_SUPPORT && WL_NAN */
+#endif /* RTT_GEOFENCE_CONT */
+	{"fw_verbose", IOV_FW_VBS, 0, 0, IOVT_UINT32, 0},
+#ifdef DHD_TX_PROFILE
+	{"tx_profile_tag", IOV_TX_PROFILE_TAG, 0, 0, IOVT_BUFFER,
+	sizeof(dhd_tx_profile_protocol_t)},
+	{"tx_profile_enable",	IOV_TX_PROFILE_ENABLE,	0,	0,	IOVT_BOOL,	0},
+	{"tx_profile_dump",	IOV_TX_PROFILE_DUMP,	0,	0,	IOVT_UINT32,	0},
+#endif /* defined(DHD_TX_PROFILE) */
+	{"check_trap_rot", IOV_CHECK_TRAP_ROT, (0), 0, IOVT_BOOL, 0},
+#ifdef DHD_LOGLEVEL
+	{"loglevel", IOV_LOGLEVEL, (0), 0, IOVT_BUFFER, sizeof(dhd_loglevel_data_t)},
+#endif /* DHD_LOGLEVEL */
+	{"counters",	IOV_COUNTERS, 0, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN_32K},
+#ifdef BCMPCIE
+	{"dump_flowrings", IOV_DUMP_FLOWRINGS, 0, 0, IOVT_BUFFER, DHD_IOCTL_MAXLEN_32K},
+#endif
+#ifdef SYNA_SAR_CUSTOMER_PARAMETER
+	{"sarmode", IOV_SAR_MODE, (0), 0, IOVT_UINT32, 0},
+#endif /* SYNA_SAR_CUSTOMER_PARAMETER */
+#ifdef CSI_SUPPORT
+	{"csi_version", IOV_CSI_VERSION, 0, 0,	IOVT_UINT8,	sizeof(uint32)},
+	{"csi_config", IOV_CSI_CONFIG,	 0, 0,	IOVT_BUFFER,	sizeof(uint32)},
+#endif /* CSI_SUPPORT */
+#if defined(EXT_REGD_INFO) && defined(WL_SELF_MANAGED_REGDOM)
+	{"regulatory_dump", IOV_REGULATORY_DUMP, 0, 0, IOVT_UINT32, sizeof(uint32)},
+#endif /* defined(EXT_REGD_INFO) && defined(WL_SELF_MANAGED_REGDOM) */
+	/* --- add new iovars *ABOVE* this line --- */
+#ifdef WLEASYMESH
+	{"1905_al_ucast", IOV_1905_AL_UCAST, 0, 0, IOVT_BUFFER, ETHER_ADDR_LEN},
+	{"1905_al_mcast", IOV_1905_AL_MCAST, 0, 0, IOVT_BUFFER, ETHER_ADDR_LEN},
+#endif /* WLEASYMESH */
+	{NULL, 0, 0, 0, 0, 0 }
+};
+
+#define DHD_IOVAR_BUF_SIZE	128
+
+#if defined(LINUX) || defined(linux)
+fw_download_status_t
+dhd_fw_download_status(dhd_pub_t * dhd_pub)
+{
+	return dhd_pub->fw_download_status;
+}
+#endif
+
+bool
+dhd_query_bus_erros(dhd_pub_t *dhdp)
+{
+	bool ret = FALSE;
+
+	if (dhdp->dongle_trap_occured) {
+		DHD_ERROR_RLMT(("%s: FW TRAP has occurred, cannot proceed\n",
+			__FUNCTION__));
+		ret = TRUE;
+#ifdef OEM_ANDROID
+		dhdp->hang_reason = HANG_REASON_DONGLE_TRAP;
+		dhd_os_send_hang_message(dhdp);
+#endif /* OEM_ANDROID */
+	}
+
+	if (dhdp->iovar_timeout_occured) {
+		DHD_ERROR_RLMT(("%s: Resumed on timeout for previous IOVAR, cannot proceed\n",
+			__FUNCTION__));
+		ret = TRUE;
+	}
+
+#ifdef PCIE_FULL_DONGLE
+	if (dhdp->d3ack_timeout_occured) {
+		DHD_ERROR_RLMT(("%s: Resumed on timeout for previous D3ACK, cannot proceed\n",
+			__FUNCTION__));
+		ret = TRUE;
+	}
+	if (dhdp->livelock_occured) {
+		DHD_ERROR_RLMT(("%s: LIVELOCK occurred for previous msg, cannot proceed\n",
+			__FUNCTION__));
+		ret = TRUE;
+	}
+
+	if (dhdp->pktid_audit_failed) {
+		DHD_ERROR_RLMT(("%s: pktid_audit_failed, cannot proceed\n",
+			__FUNCTION__));
+		ret = TRUE;
+	}
+	if (dhdp->pktid_invalid_occured) {
+		DHD_ERROR_RLMT(("%s: invalid pktid, cannot proceed\n",
+			__FUNCTION__));
+		ret = TRUE;
+	}
+#endif /* PCIE_FULL_DONGLE */
+
+	if (dhdp->iface_op_failed) {
+		DHD_ERROR_RLMT(("%s: iface_op_failed, cannot proceed\n",
+			__FUNCTION__));
+		ret = TRUE;
+	}
+
+	if (dhdp->scan_timeout_occurred) {
+		DHD_ERROR_RLMT(("%s: scan_timeout_occurred, cannot proceed\n",
+			__FUNCTION__));
+		ret = TRUE;
+	}
+
+	if (dhdp->scan_busy_occurred) {
+		DHD_ERROR_RLMT(("%s: scan_busy_occurred, cannot proceed\n",
+			__FUNCTION__));
+		ret = TRUE;
+	}
+
+	if (dhdp->p2p_disc_busy_occurred) {
+		DHD_ERROR_RLMT(("%s: p2p_disc_busy_occurred, cannot proceed\n",
+			__FUNCTION__));
+		ret = TRUE;
+	}
+
+#ifdef DNGL_AXI_ERROR_LOGGING
+	if (dhdp->axi_error) {
+		DHD_ERROR_RLMT(("%s: AXI error occurred, cannot proceed\n",
+			__FUNCTION__));
+		ret = TRUE;
+	}
+#endif /* DNGL_AXI_ERROR_LOGGING */
+
+#ifdef BCMPCIE
+	if (dhd_bus_get_linkdown(dhdp)) {
+		/* pcie link down, so do chip big hammer */
+		DHD_ERROR_RLMT(("%s: set do_chip_bighammer\n", __FUNCTION__));
+		dhdp->do_chip_bighammer = TRUE;
+		DHD_ERROR_RLMT(("%s : PCIE Link down occurred, cannot proceed\n",
+			__FUNCTION__));
+		ret = TRUE;
+	}
+
+	if (dhd_bus_get_cto(dhdp)) {
+		DHD_ERROR_RLMT(("%s : CTO Recovery reported, cannot proceed\n",
+			__FUNCTION__));
+		ret = TRUE;
+	}
+
+	if (dhd_bus_get_read_shm(dhdp)) {
+		DHD_ERROR_RLMT(("%s : read shm check failed, cannot proceed\n",
+			__FUNCTION__));
+		ret = TRUE;
+	}
+#endif /* BCMPCIE */
+	return ret;
+}
+
+void
+dhd_clear_bus_errors(dhd_pub_t *dhdp)
+{
+	if (!dhdp)
+		return;
+
+	dhdp->dongle_reset = FALSE;
+	dhdp->dongle_trap_occured = FALSE;
+	dhdp->dsack_hc_due_to_isr_delay = FALSE;
+	dhdp->dsack_hc_due_to_dpc_delay = FALSE;
+	dhdp->iovar_timeout_occured = FALSE;
+#ifdef PCIE_FULL_DONGLE
+	dhdp->d3ack_timeout_occured = FALSE;
+	dhdp->livelock_occured = FALSE;
+	dhdp->pktid_audit_failed = FALSE;
+	dhdp->pktid_invalid_occured = FALSE;
+#endif
+	dhdp->iface_op_failed = FALSE;
+	dhdp->scan_timeout_occurred = FALSE;
+	dhdp->scan_busy_occurred = FALSE;
+	dhdp->p2p_disc_busy_occurred = FALSE;
+}
+
+#ifdef DHD_SSSR_DUMP
+
+/* This can be overwritten by module parameter defined in dhd_linux.c */
+#ifdef GDB_PROXY
+/* GDB Proxy can't connect to crashed firmware after SSSR dump is generated.
+ * SSSR dump generation disabled for GDB Proxy enabled firmware by default.
+ * Still it can be explicitly enabled by echo 1 > /sys/wifi/sssr_enab or by
+ * sssr_enab=1 in insmod command line
+ */
+uint sssr_enab = FALSE;
+#else /* GDB_PROXY */
+uint sssr_enab = TRUE;
+#endif /* else GDB_PROXY */
+
+#ifdef DHD_FIS_DUMP
+uint fis_enab = TRUE;
+#else
+uint fis_enab = FALSE;
+#endif /* DHD_FIS_DUMP */
+
+int
+dhd_sssr_mempool_init(dhd_pub_t *dhd)
+{
+#ifdef CONFIG_BCMDHD_PCIE
+	dhd->sssr_mempool = (uint8 *) VMALLOCZ(dhd->osh, DHD_SSSR_MEMPOOL_SIZE);
+#else
+	dhd->sssr_mempool = (uint8 *) MALLOCZ(dhd->osh, DHD_SSSR_MEMPOOL_SIZE);
+#endif /* CONFIG_BCMDHD_PCIE */
+	if (dhd->sssr_mempool == NULL) {
+		DHD_ERROR(("%s: MALLOC of sssr_mempool failed\n",
+			__FUNCTION__));
+		return BCME_ERROR;
+	}
+	return BCME_OK;
+}
+
+void
+dhd_sssr_mempool_deinit(dhd_pub_t *dhd)
+{
+	if (dhd->sssr_mempool) {
+#ifdef CONFIG_BCMDHD_PCIE
+		VMFREE(dhd->osh, dhd->sssr_mempool, DHD_SSSR_MEMPOOL_SIZE);
+#else
+		MFREE(dhd->osh, dhd->sssr_mempool, DHD_SSSR_MEMPOOL_SIZE);
+#endif /* CONFIG_BCMDHD_PCIE */
+		dhd->sssr_mempool = NULL;
+	}
+}
+
+int
+dhd_sssr_reg_info_init(dhd_pub_t *dhd)
+{
+	dhd->sssr_reg_info = (sssr_reg_info_cmn_t *) MALLOCZ(dhd->osh, sizeof(sssr_reg_info_cmn_t));
+	if (dhd->sssr_reg_info == NULL) {
+		DHD_ERROR(("%s: MALLOC of sssr_reg_info failed\n",
+			__FUNCTION__));
+		return BCME_ERROR;
+	}
+	return BCME_OK;
+}
+
+void
+dhd_sssr_reg_info_deinit(dhd_pub_t *dhd)
+{
+	if (dhd->sssr_reg_info) {
+		MFREE(dhd->osh, dhd->sssr_reg_info, sizeof(sssr_reg_info_cmn_t));
+		dhd->sssr_reg_info = NULL;
+	}
+}
+
+#ifdef DHD_PCIE_REG_ACCESS
+static void
+dhd_dump_sssr_reg_info_v2(dhd_pub_t *dhd)
+{
+	sssr_reg_info_cmn_t *sssr_reg_info_cmn = dhd->sssr_reg_info;
+	sssr_reg_info_v2_t *sssr_reg_info = (sssr_reg_info_v2_t *)&sssr_reg_info_cmn->rev2;
+	int i, j;
+	uint8 num_d11cores = dhd_d11_slices_num_get(dhd);
+	DHD_ERROR(("pmu_regs\n"));
+	DHD_ERROR(("pmuintmask0=0x%x pmuintmask1=0x%x resreqtimer=0x%x "
+		"macresreqtimer=0x%x macresreqtimer1=0x%x\n",
+		sssr_reg_info->pmu_regs.base_regs.pmuintmask0,
+		sssr_reg_info->pmu_regs.base_regs.pmuintmask1,
+		sssr_reg_info->pmu_regs.base_regs.resreqtimer,
+		sssr_reg_info->pmu_regs.base_regs.macresreqtimer,
+		sssr_reg_info->pmu_regs.base_regs.macresreqtimer1));
+	DHD_ERROR(("chipcommon_regs\n"));
+	DHD_ERROR(("intmask=0x%x powerctrl=0x%x clockcontrolstatus=0x%x powerctrl_mask=0x%x\n",
+		sssr_reg_info->chipcommon_regs.base_regs.intmask,
+		sssr_reg_info->chipcommon_regs.base_regs.powerctrl,
+		sssr_reg_info->chipcommon_regs.base_regs.clockcontrolstatus,
+		sssr_reg_info->chipcommon_regs.base_regs.powerctrl_mask));
+	DHD_ERROR(("arm_regs\n"));
+	DHD_ERROR(("clockcontrolstatus=0x%x clockcontrolstatus_val=0x%x"
+		" resetctrl=0x%x extrsrcreq=0x%x\n",
+		sssr_reg_info->arm_regs.base_regs.clockcontrolstatus,
+		sssr_reg_info->arm_regs.base_regs.clockcontrolstatus_val,
+		sssr_reg_info->arm_regs.wrapper_regs.resetctrl,
+		sssr_reg_info->arm_regs.wrapper_regs.extrsrcreq));
+	DHD_ERROR(("pcie_regs\n"));
+	DHD_ERROR(("ltrstate=0x%x clockcontrolstatus=0x%x "
+		"clockcontrolstatus_val=0x%x extrsrcreq=0x%x\n",
+		sssr_reg_info->pcie_regs.base_regs.ltrstate,
+		sssr_reg_info->pcie_regs.base_regs.clockcontrolstatus,
+		sssr_reg_info->pcie_regs.base_regs.clockcontrolstatus_val,
+		sssr_reg_info->pcie_regs.wrapper_regs.extrsrcreq));
+
+	for (i = 0; i < num_d11cores; i++) {
+		DHD_ERROR(("mac_regs core[%d]\n", i));
+		DHD_ERROR(("xmtaddress=0x%x xmtdata=0x%x clockcontrolstatus=0x%x "
+			"clockcontrolstatus_val=0x%x\n",
+			sssr_reg_info->mac_regs[i].base_regs.xmtaddress,
+			sssr_reg_info->mac_regs[i].base_regs.xmtdata,
+			sssr_reg_info->mac_regs[i].base_regs.clockcontrolstatus,
+			sssr_reg_info->mac_regs[i].base_regs.clockcontrolstatus_val));
+		DHD_ERROR(("resetctrl=0x%x extrsrcreq=0x%x ioctrl=0x%x\n",
+			sssr_reg_info->mac_regs[i].wrapper_regs.resetctrl,
+			sssr_reg_info->mac_regs[i].wrapper_regs.extrsrcreq,
+			sssr_reg_info->mac_regs[i].wrapper_regs.ioctrl));
+		for (j = 0; j < SSSR_D11_RESET_SEQ_STEPS; j++) {
+			DHD_ERROR(("ioctrl_resetseq_val[%d] 0x%x\n", j,
+				sssr_reg_info->mac_regs[i].wrapper_regs.ioctrl_resetseq_val[j]));
+		}
+		DHD_ERROR(("sr_size=0x%x\n", sssr_reg_info->mac_regs[i].sr_size));
+	}
+	DHD_ERROR(("dig_regs\n"));
+	DHD_ERROR(("dig_sr_addr=0x%x dig_sr_size=0x%x\n",
+		sssr_reg_info->dig_mem_info.dig_sr_addr,
+		sssr_reg_info->dig_mem_info.dig_sr_size));
+}
+
+static void
+dhd_dump_sssr_reg_info_v3(dhd_pub_t *dhd)
+{
+	sssr_reg_info_cmn_t *sssr_reg_info_cmn = dhd->sssr_reg_info;
+	sssr_reg_info_v3_t *sssr_reg_info = (sssr_reg_info_v3_t *)&sssr_reg_info_cmn->rev3;
+	int i;
+
+	dhd_dump_sssr_reg_info_v2(dhd);
+
+	DHD_ERROR(("FIS Enab in fw : %d\n", sssr_reg_info->fis_enab));
+
+	DHD_ERROR(("HWA regs for reset \n"));
+	DHD_ERROR(("clkenable 0x%x, clkgatingenable 0x%x, clkext 0x%x, "
+		"clkctlstatus 0x%x, ioctrl 0x%x, resetctrl 0x%x\n",
+		sssr_reg_info->hwa_regs.base_regs.clkenable,
+		sssr_reg_info->hwa_regs.base_regs.clkgatingenable,
+		sssr_reg_info->hwa_regs.base_regs.clkext,
+		sssr_reg_info->hwa_regs.base_regs.clkctlstatus,
+		sssr_reg_info->hwa_regs.wrapper_regs.ioctrl,
+		sssr_reg_info->hwa_regs.wrapper_regs.resetctrl));
+	DHD_ERROR(("HWA regs value seq for reset \n"));
+	for (i = 0; i < SSSR_HWA_RESET_SEQ_STEPS; i++) {
+		DHD_ERROR(("hwa_resetseq_val[%d] 0x%x\n", i,
+			sssr_reg_info->hwa_regs.hwa_resetseq_val[i]));
+	}
+}
+
+static void
+dhd_dump_sssr_reg_info_v1(dhd_pub_t *dhd)
+{
+	sssr_reg_info_cmn_t *sssr_reg_info_cmn = dhd->sssr_reg_info;
+	sssr_reg_info_v1_t *sssr_reg_info = (sssr_reg_info_v1_t *)&sssr_reg_info_cmn->rev1;
+	int i, j;
+	uint8 num_d11cores = dhd_d11_slices_num_get(dhd);
+
+	DHD_ERROR(("pmu_regs\n"));
+	DHD_ERROR(("pmuintmask0=0x%x pmuintmask1=0x%x resreqtimer=0x%x "
+		"macresreqtimer=0x%x macresreqtimer1=0x%x\n",
+		sssr_reg_info->pmu_regs.base_regs.pmuintmask0,
+		sssr_reg_info->pmu_regs.base_regs.pmuintmask1,
+		sssr_reg_info->pmu_regs.base_regs.resreqtimer,
+		sssr_reg_info->pmu_regs.base_regs.macresreqtimer,
+		sssr_reg_info->pmu_regs.base_regs.macresreqtimer1));
+	DHD_ERROR(("chipcommon_regs\n"));
+	DHD_ERROR(("intmask=0x%x powerctrl=0x%x clockcontrolstatus=0x%x powerctrl_mask=0x%x\n",
+		sssr_reg_info->chipcommon_regs.base_regs.intmask,
+		sssr_reg_info->chipcommon_regs.base_regs.powerctrl,
+		sssr_reg_info->chipcommon_regs.base_regs.clockcontrolstatus,
+		sssr_reg_info->chipcommon_regs.base_regs.powerctrl_mask));
+	DHD_ERROR(("arm_regs\n"));
+	DHD_ERROR(("clockcontrolstatus=0x%x clockcontrolstatus_val=0x%x"
+		" resetctrl=0x%x itopoobb=0x%x\n",
+		sssr_reg_info->arm_regs.base_regs.clockcontrolstatus,
+		sssr_reg_info->arm_regs.base_regs.clockcontrolstatus_val,
+		sssr_reg_info->arm_regs.wrapper_regs.resetctrl,
+		sssr_reg_info->arm_regs.wrapper_regs.itopoobb));
+	DHD_ERROR(("pcie_regs\n"));
+	DHD_ERROR(("ltrstate=0x%x clockcontrolstatus=0x%x "
+		"clockcontrolstatus_val=0x%x itopoobb=0x%x\n",
+		sssr_reg_info->pcie_regs.base_regs.ltrstate,
+		sssr_reg_info->pcie_regs.base_regs.clockcontrolstatus,
+		sssr_reg_info->pcie_regs.base_regs.clockcontrolstatus_val,
+		sssr_reg_info->pcie_regs.wrapper_regs.itopoobb));
+	DHD_ERROR(("vasip_regs\n"));
+	DHD_ERROR(("ioctrl=0x%x vasip_sr_addr=0x%x vasip_sr_size=0x%x\n",
+		sssr_reg_info->vasip_regs.wrapper_regs.ioctrl,
+		sssr_reg_info->vasip_regs.vasip_sr_addr,
+		sssr_reg_info->vasip_regs.vasip_sr_size));
+
+	for (i = 0; i < num_d11cores; i++) {
+		DHD_ERROR(("mac_regs core[%d]\n", i));
+		DHD_ERROR(("xmtaddress=0x%x xmtdata=0x%x clockcontrolstatus=0x%x "
+			"clockcontrolstatus_val=0x%x\n",
+			sssr_reg_info->mac_regs[i].base_regs.xmtaddress,
+			sssr_reg_info->mac_regs[i].base_regs.xmtdata,
+			sssr_reg_info->mac_regs[i].base_regs.clockcontrolstatus,
+			sssr_reg_info->mac_regs[i].base_regs.clockcontrolstatus_val));
+		DHD_ERROR(("resetctrl=0x%x itopoobb=0x%x ioctrl=0x%x\n",
+			sssr_reg_info->mac_regs[i].wrapper_regs.resetctrl,
+			sssr_reg_info->mac_regs[i].wrapper_regs.itopoobb,
+			sssr_reg_info->mac_regs[i].wrapper_regs.ioctrl));
+		for (j = 0; j < SSSR_D11_RESET_SEQ_STEPS; j++) {
+			DHD_ERROR(("ioctrl_resetseq_val[%d] 0x%x\n", j,
+				sssr_reg_info->mac_regs[i].wrapper_regs.ioctrl_resetseq_val[j]));
+		}
+		DHD_ERROR(("sr_size=0x%x\n", sssr_reg_info->mac_regs[i].sr_size));
+	}
+}
+
+#endif /* DHD_PCIE_REG_ACCESS */
+
+void
+dhd_dump_sssr_reg_info(dhd_pub_t *dhd)
+{
+#ifdef DHD_PCIE_REG_ACCESS
+	sssr_reg_info_cmn_t *sssr_reg_info_cmn = dhd->sssr_reg_info;
+	sssr_reg_info_v1_t *sssr_reg_info = (sssr_reg_info_v1_t *)&sssr_reg_info_cmn->rev1;
+
+	DHD_ERROR(("************** SSSR REG INFO start version:%d ****************\n",
+		sssr_reg_info->version));
+	switch (sssr_reg_info->version) {
+		case SSSR_REG_INFO_VER_3 :
+			dhd_dump_sssr_reg_info_v3(dhd);
+			break;
+		case SSSR_REG_INFO_VER_2 :
+			dhd_dump_sssr_reg_info_v2(dhd);
+			break;
+		default:
+			dhd_dump_sssr_reg_info_v1(dhd);
+			break;
+	}
+	DHD_ERROR(("************** SSSR REG INFO end ****************\n"));
+#endif /* DHD_PCIE_REG_ACCESS */
+}
+
+void dhdpcie_fill_sssr_reg_info(dhd_pub_t *dhd);
+
+int
+dhd_get_sssr_reg_info(dhd_pub_t *dhd)
+{
+	int ret;
+
+	if (dhd->force_sssr_init) {
+		dhdpcie_fill_sssr_reg_info(dhd);
+		dhd->force_sssr_init = FALSE;
+		goto done;
+	}
+
+	/* get sssr_reg_info from firmware */
+	ret = dhd_iovar(dhd, 0, "sssr_reg_info", NULL, 0,  (char *)dhd->sssr_reg_info,
+		sizeof(sssr_reg_info_cmn_t), FALSE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: sssr_reg_info failed (error=%d)\n",
+			__FUNCTION__, ret));
+		return BCME_ERROR;
+	}
+
+done:
+	dhd_dump_sssr_reg_info(dhd);
+	return BCME_OK;
+}
+
+uint32
+dhd_get_sssr_bufsize(dhd_pub_t *dhd)
+{
+	int i;
+	uint32 sssr_bufsize = 0;
+	uint8 num_d11cores;
+
+	num_d11cores = dhd_d11_slices_num_get(dhd);
+
+	switch (dhd->sssr_reg_info->rev2.version) {
+		case SSSR_REG_INFO_VER_3 :
+			/* intentional fall through */
+		case SSSR_REG_INFO_VER_2 :
+			for (i = 0; i < num_d11cores; i++) {
+				sssr_bufsize += dhd->sssr_reg_info->rev2.mac_regs[i].sr_size;
+			}
+			if ((dhd->sssr_reg_info->rev2.length >
+			 OFFSETOF(sssr_reg_info_v2_t, dig_mem_info)) &&
+			 dhd->sssr_reg_info->rev2.dig_mem_info.dig_sr_addr) {
+				sssr_bufsize += 0; /* TBD */
+			}
+			break;
+		case SSSR_REG_INFO_VER_1 :
+			for (i = 0; i < num_d11cores; i++) {
+				sssr_bufsize += dhd->sssr_reg_info->rev1.mac_regs[i].sr_size;
+			}
+			if (dhd->sssr_reg_info->rev1.vasip_regs.vasip_sr_size) {
+				sssr_bufsize += dhd->sssr_reg_info->rev1.vasip_regs.vasip_sr_size;
+			} else if ((dhd->sssr_reg_info->rev1.length > OFFSETOF(sssr_reg_info_v1_t,
+				dig_mem_info)) && dhd->sssr_reg_info->rev1.
+				dig_mem_info.dig_sr_addr) {
+				sssr_bufsize += dhd->sssr_reg_info->rev1.dig_mem_info.dig_sr_size;
+			}
+			break;
+		case SSSR_REG_INFO_VER_0 :
+			for (i = 0; i < num_d11cores; i++) {
+				sssr_bufsize += dhd->sssr_reg_info->rev0.mac_regs[i].sr_size;
+			}
+			if (dhd->sssr_reg_info->rev0.vasip_regs.vasip_sr_size) {
+				sssr_bufsize += dhd->sssr_reg_info->rev0.vasip_regs.vasip_sr_size;
+			}
+			break;
+		default :
+			DHD_ERROR(("invalid sssr_reg_ver"));
+			return BCME_UNSUPPORTED;
+	}
+
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+	/* Double the size as different dumps will be saved before and after SR */
+	sssr_bufsize = 2 * sssr_bufsize;
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+
+	return sssr_bufsize;
+}
+
+int
+dhd_sssr_dump_init(dhd_pub_t *dhd)
+{
+	int i;
+	uint32 sssr_bufsize;
+	uint32 mempool_used = 0;
+	uint8 num_d11cores = 0;
+	bool alloc_sssr = FALSE;
+	uint32 sr_size = 0;
+
+	dhd->sssr_inited = FALSE;
+	if (!sssr_enab) {
+		DHD_ERROR(("%s: sssr dump not inited as instructed by mod param\n", __FUNCTION__));
+		return BCME_OK;
+	}
+
+	/* check if sssr mempool is allocated */
+	if (dhd->sssr_mempool == NULL) {
+		DHD_ERROR(("%s: sssr_mempool is not allocated\n",
+			__FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	/* check if sssr mempool is allocated */
+	if (dhd->sssr_reg_info == NULL) {
+		DHD_ERROR(("%s: sssr_reg_info is not allocated\n",
+			__FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	/* Get SSSR reg info */
+	if (dhd_get_sssr_reg_info(dhd) != BCME_OK) {
+		DHD_ERROR(("%s: dhd_get_sssr_reg_info failed\n", __FUNCTION__));
+		DHD_CONS_ONLY(("DEBUG_SSSr: %s: dhd_get_sssr_reg_info failed\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	num_d11cores = dhd_d11_slices_num_get(dhd);
+	/* Validate structure version and length */
+	switch (dhd->sssr_reg_info->rev2.version) {
+		case SSSR_REG_INFO_VER_3 :
+			if (dhd->sssr_reg_info->rev3.length != sizeof(sssr_reg_info_v3_t)) {
+				DHD_ERROR(("%s: dhd->sssr_reg_info->rev2.length (%d : %d)"
+					 "mismatch on rev2\n", __FUNCTION__,
+					 (int)dhd->sssr_reg_info->rev3.length,
+					 (int)sizeof(sssr_reg_info_v3_t)));
+				return BCME_ERROR;
+			}
+			break;
+		case SSSR_REG_INFO_VER_2 :
+			if (dhd->sssr_reg_info->rev2.length != sizeof(sssr_reg_info_v2_t)) {
+				DHD_ERROR(("%s: dhd->sssr_reg_info->rev2.length (%d : %d)"
+					 "mismatch on rev2\n", __FUNCTION__,
+					 (int)dhd->sssr_reg_info->rev2.length,
+					 (int)sizeof(sssr_reg_info_v2_t)));
+				return BCME_ERROR;
+			}
+			break;
+		case SSSR_REG_INFO_VER_1 :
+			if (dhd->sssr_reg_info->rev1.length != sizeof(sssr_reg_info_v1_t)) {
+				DHD_ERROR(("%s: dhd->sssr_reg_info->rev1.length (%d : %d)"
+					 "mismatch on rev1\n", __FUNCTION__,
+					 (int)dhd->sssr_reg_info->rev1.length,
+					 (int)sizeof(sssr_reg_info_v1_t)));
+				return BCME_ERROR;
+			}
+			break;
+		case SSSR_REG_INFO_VER_0 :
+			if (dhd->sssr_reg_info->rev0.length != sizeof(sssr_reg_info_v0_t)) {
+				DHD_ERROR(("%s: dhd->sssr_reg_info->rev0.length (%d : %d)"
+					 "mismatch on rev0\n", __FUNCTION__,
+					 (int)dhd->sssr_reg_info->rev0.length,
+					 (int)sizeof(sssr_reg_info_v0_t)));
+				return BCME_ERROR;
+			}
+			break;
+		default :
+			DHD_ERROR(("invalid sssr_reg_ver"));
+			return BCME_UNSUPPORTED;
+	}
+
+	/* validate fifo size */
+	sssr_bufsize = dhd_get_sssr_bufsize(dhd);
+	if (sssr_bufsize > DHD_SSSR_MEMPOOL_SIZE) {
+		DHD_ERROR(("%s: sssr_bufsize(%d) is greater than sssr_mempool(%d)\n",
+			__FUNCTION__, (int)sssr_bufsize, DHD_SSSR_MEMPOOL_SIZE));
+		return BCME_ERROR;
+	}
+
+	/* init all pointers to NULL */
+	for (i = 0; i < num_d11cores; i++) {
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+		dhd->sssr_d11_before[i] = NULL;
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+		dhd->sssr_d11_after[i] = NULL;
+	}
+
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+	dhd->sssr_dig_buf_before = NULL;
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+	dhd->sssr_dig_buf_after = NULL;
+
+	/* Allocate memory */
+	for (i = 0; i < num_d11cores; i++) {
+		alloc_sssr = FALSE;
+		sr_size = 0;
+
+		switch (dhd->sssr_reg_info->rev2.version) {
+			case SSSR_REG_INFO_VER_3 :
+				/* intentional fall through */
+			case SSSR_REG_INFO_VER_2 :
+				if (dhd->sssr_reg_info->rev2.mac_regs[i].sr_size) {
+					alloc_sssr = TRUE;
+					sr_size = dhd->sssr_reg_info->rev2.mac_regs[i].sr_size;
+				}
+				break;
+			case SSSR_REG_INFO_VER_1 :
+				if (dhd->sssr_reg_info->rev1.mac_regs[i].sr_size) {
+					alloc_sssr = TRUE;
+					sr_size = dhd->sssr_reg_info->rev1.mac_regs[i].sr_size;
+				}
+				break;
+			case SSSR_REG_INFO_VER_0 :
+				if (dhd->sssr_reg_info->rev0.mac_regs[i].sr_size) {
+					alloc_sssr = TRUE;
+					sr_size = dhd->sssr_reg_info->rev0.mac_regs[i].sr_size;
+				}
+				break;
+			default :
+				DHD_ERROR(("invalid sssr_reg_ver"));
+				return BCME_UNSUPPORTED;
+		}
+
+		if (alloc_sssr) {
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+			dhd->sssr_d11_before[i] = (uint32 *)(dhd->sssr_mempool + mempool_used);
+			mempool_used += sr_size;
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+
+			dhd->sssr_d11_after[i] = (uint32 *)(dhd->sssr_mempool + mempool_used);
+			mempool_used += sr_size;
+		}
+	}
+
+	/* Allocate dump memory for VASIP (version 0 or 1) or digital core (version 0, 1, or 2) */
+	alloc_sssr = FALSE;
+	sr_size = 0;
+	switch (dhd->sssr_reg_info->rev2.version) {
+		case SSSR_REG_INFO_VER_3 :
+			/* intentional fall through */
+		case SSSR_REG_INFO_VER_2 :
+			if ((dhd->sssr_reg_info->rev2.length >
+			 OFFSETOF(sssr_reg_info_v2_t, dig_mem_info)) &&
+			 dhd->sssr_reg_info->rev2.dig_mem_info.dig_sr_addr) {
+				alloc_sssr = TRUE;
+				sr_size = dhd->sssr_reg_info->rev2.dig_mem_info.dig_sr_size;
+			}
+			break;
+		case SSSR_REG_INFO_VER_1 :
+			if (dhd->sssr_reg_info->rev1.vasip_regs.vasip_sr_size) {
+				alloc_sssr = TRUE;
+				sr_size = dhd->sssr_reg_info->rev1.vasip_regs.vasip_sr_size;
+			} else if ((dhd->sssr_reg_info->rev1.length > OFFSETOF(sssr_reg_info_v1_t,
+				dig_mem_info)) && dhd->sssr_reg_info->rev1.
+				dig_mem_info.dig_sr_addr) {
+				alloc_sssr = TRUE;
+				sr_size = dhd->sssr_reg_info->rev1.dig_mem_info.dig_sr_size;
+			}
+			break;
+		case SSSR_REG_INFO_VER_0 :
+			if (dhd->sssr_reg_info->rev0.vasip_regs.vasip_sr_size) {
+				alloc_sssr = TRUE;
+				sr_size = dhd->sssr_reg_info->rev0.vasip_regs.vasip_sr_size;
+			}
+			break;
+		default :
+			DHD_ERROR(("invalid sssr_reg_ver"));
+			return BCME_UNSUPPORTED;
+	}
+
+	if (alloc_sssr) {
+		dhd->sssr_dig_buf_after = (uint32 *)(dhd->sssr_mempool + mempool_used);
+		mempool_used += sr_size;
+
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+		/* DIG dump before suspend is not applicable. */
+		dhd->sssr_dig_buf_before = NULL;
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+	}
+
+	dhd->sssr_inited = TRUE;
+
+	return BCME_OK;
+
+}
+
+void
+dhd_sssr_dump_deinit(dhd_pub_t *dhd)
+{
+	int i;
+
+	dhd->sssr_inited = FALSE;
+	/* init all pointers to NULL */
+	for (i = 0; i < MAX_NUM_D11_CORES_WITH_SCAN; i++) {
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+		dhd->sssr_d11_before[i] = NULL;
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+		dhd->sssr_d11_after[i] = NULL;
+	}
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+	dhd->sssr_dig_buf_before = NULL;
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+	dhd->sssr_dig_buf_after = NULL;
+
+	return;
+}
+
+void
+dhd_sssr_print_filepath(dhd_pub_t *dhd, char *path)
+{
+	bool print_info = FALSE;
+	int dump_mode;
+
+	if (!dhd || !path) {
+		DHD_ERROR(("%s: dhd or memdump_path is NULL\n",
+			__FUNCTION__));
+		return;
+	}
+
+	if (!dhd->sssr_dump_collected) {
+		/* SSSR dump is not collected */
+		return;
+	}
+
+	dump_mode = dhd->sssr_dump_mode;
+
+	if (bcmstrstr(path, "core_0_before")) {
+		if (dhd->sssr_d11_outofreset[0] &&
+			dump_mode == SSSR_DUMP_MODE_SSSR) {
+			print_info = TRUE;
+		}
+	} else if (bcmstrstr(path, "core_0_after")) {
+		if (dhd->sssr_d11_outofreset[0]) {
+			print_info = TRUE;
+		}
+	} else if (bcmstrstr(path, "core_1_before")) {
+		if (dhd->sssr_d11_outofreset[1] &&
+			dump_mode == SSSR_DUMP_MODE_SSSR) {
+			print_info = TRUE;
+		}
+	} else if (bcmstrstr(path, "core_1_after")) {
+		if (dhd->sssr_d11_outofreset[1]) {
+			print_info = TRUE;
+		}
+	} else if (bcmstrstr(path, "core_2_before")) {
+		if (dhd->sssr_d11_outofreset[2] &&
+			dump_mode == SSSR_DUMP_MODE_SSSR) {
+			print_info = TRUE;
+		}
+	} else if (bcmstrstr(path, "core_2_after")) {
+		if (dhd->sssr_d11_outofreset[2]) {
+			print_info = TRUE;
+		}
+	} else {
+		print_info = TRUE;
+	}
+
+	if (print_info) {
+		DHD_ERROR(("%s: file_path = %s%s\n", __FUNCTION__,
+			path, FILE_NAME_HAL_TAG));
+	}
+}
+#endif /* DHD_SSSR_DUMP */
+
+#ifdef DHD_COREDUMP
+int
+dhd_coredump_mempool_init(dhd_pub_t *dhd)
+{
+	dhd->coredump_mem = (uint8*) VMALLOCZ(dhd->osh, DHD_MEMDUMP_BUFFER_SIZE);
+	if (dhd->coredump_mem == NULL) {
+		DHD_ERROR(("%s: VMALLOCZ of coredump_mem failed\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	dhd->coredump_len = DHD_MEMDUMP_BUFFER_SIZE;
+	return BCME_OK;
+}
+
+void
+dhd_coredump_mempool_deinit(dhd_pub_t *dhd)
+{
+	if (dhd->coredump_mem) {
+		VMFREE(dhd->osh, dhd->coredump_mem, DHD_MEMDUMP_BUFFER_SIZE);
+		dhd->coredump_mem = NULL;
+		dhd->coredump_len = 0;
+	}
+}
+
+#ifdef DHD_SSSR_DUMP
+dhd_coredump_t dhd_coredump_types[] = {
+	{DHD_COREDUMP_TYPE_SSSRDUMP_CORE0_BEFORE, 0, NULL},
+	{DHD_COREDUMP_TYPE_SSSRDUMP_CORE0_AFTER, 0, NULL},
+	{DHD_COREDUMP_TYPE_SSSRDUMP_CORE1_BEFORE, 0, NULL},
+	{DHD_COREDUMP_TYPE_SSSRDUMP_CORE1_AFTER, 0, NULL},
+	{DHD_COREDUMP_TYPE_SSSRDUMP_CORE2_BEFORE, 0, NULL},
+	{DHD_COREDUMP_TYPE_SSSRDUMP_CORE2_AFTER, 0, NULL},
+	{DHD_COREDUMP_TYPE_SSSRDUMP_DIG_BEFORE, 0, NULL},
+	{DHD_COREDUMP_TYPE_SSSRDUMP_DIG_AFTER, 0, NULL},
+	{DHD_COREDUMP_TYPE_SOCRAMDUMP, 0, NULL}
+};
+
+static int dhd_append_sssr_tlv(uint8 *buf_dst, int type_idx, int buf_remain)
+{
+	uint32 type_val, length_val;
+	uint32 *type, *length;
+	void *buf_src;
+	int total_size = 0, ret = 0;
+
+	/* DHD_COREDUMP_TYPE_SSSRDUMP_[CORE[0|1|2]|DIG]_[BEFORE|AFTER] */
+	type_val = dhd_coredump_types[type_idx].type;
+	length_val = dhd_coredump_types[type_idx].length;
+
+	if (length_val == 0) {
+		return 0;
+	}
+
+	type = (uint32*)buf_dst;
+	*type = type_val;
+	length = (uint32*)(buf_dst + sizeof(*type));
+	*length = length_val;
+
+	buf_dst += TLV_TYPE_LENGTH_SIZE;
+	total_size += TLV_TYPE_LENGTH_SIZE;
+
+	buf_src = dhd_coredump_types[type_idx].bufptr;
+	ret = memcpy_s(buf_dst, buf_remain, buf_src, *length);
+
+	if (ret) {
+		DHD_ERROR(("Failed to memcpy_s() for coredump.\n"));
+		return BCME_ERROR;
+	}
+
+	DHD_INFO(("%s: type: %u, length: %u\n",	__FUNCTION__, *type, *length));
+
+	total_size += *length;
+	return total_size;
+}
+
+/* reconstruct dump memory with socram and sssr dump as TLV format */
+int dhd_collect_coredump(dhd_pub_t *dhdp, dhd_dump_t *dump)
+{
+	uint8 *buf_ptr = dhdp->coredump_mem;
+	int buf_len = dhdp->coredump_len;
+	uint8 *socram_mem = dump->buf;
+	int socram_len = dump->bufsize;
+	int ret = 0, i = 0;
+	int total_size = 0;
+	uint32 *magic, *type, *length;
+	uint8 num_d11cores = 0, offset = 0;
+
+	/* SSSR dump */
+	if (!sssr_enab || !dhdp->collect_sssr) {
+		DHD_ERROR(("SSSR is not enabled or not collected yet.\n"));
+		return BCME_UNSUPPORTED;
+	}
+
+	/* SOCRAM dump start with magic code */
+	magic = (uint32*)buf_ptr;
+	*magic = DHD_COREDUMP_MAGIC;
+
+	/* DHD_COREDUMP_TYPE_SOCRAMDUMP */
+	type = (uint32*)(buf_ptr + sizeof(*magic));
+	*type = dhd_coredump_types[DHD_COREDUMP_TYPE_SOCRAMDUMP].type;
+	length = (uint32*)(buf_ptr + sizeof(*magic) + sizeof(*type));
+	*length = socram_len;
+
+	offset = sizeof(*magic) + sizeof(*type) + sizeof(*length);
+	ret = memcpy_s(buf_ptr + offset, buf_len - offset,
+		socram_mem, socram_len);
+
+	if (ret) {
+		DHD_ERROR(("Failed to memmove_s() for coredump.\n"));
+		return BCME_ERROR;
+	}
+	total_size = offset + socram_len;
+	buf_ptr += total_size;
+
+	DHD_ERROR(("%s: type: %u, length: %u\n", __FUNCTION__, *type, *length));
+
+	num_d11cores = dhd_d11_slices_num_get(dhdp);
+	for (i = 0; i < num_d11cores + 1; i++) {
+		int written_bytes = 0;
+		int type_idx = i * 2;
+		if ((i < num_d11cores) && (!dhdp->sssr_d11_outofreset[i])) {
+			continue;
+		}
+
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+		/* DHD_COREDUMP_TYPE_SSSRDUMP_[CORE[0|1|2]|DIG]_BEFORE */
+		written_bytes = dhd_append_sssr_tlv(buf_ptr, type_idx,
+			buf_len - total_size);
+		if (written_bytes == BCME_ERROR) {
+			return BCME_ERROR;
+		}
+		buf_ptr += written_bytes;
+		total_size += written_bytes;
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+
+		/* DHD_COREDUMP_TYPE_SSSRDUMP_[CORE[0|1|2]|DIG]_AFTER */
+		written_bytes = dhd_append_sssr_tlv(buf_ptr, type_idx + 1,
+			buf_len - total_size);
+		if (written_bytes == BCME_ERROR) {
+			return BCME_ERROR;
+		}
+		buf_ptr += written_bytes;
+		total_size += written_bytes;
+	}
+
+	dump->buf = dhdp->coredump_mem;
+	dump->bufsize = total_size;
+
+	return BCME_OK;
+}
+#endif /* DHD_SSSR_DUMP */
+#endif /* DHD_COREDUMP */
+
+#ifdef DHD_SDTC_ETB_DUMP
+/*
+ * sdtc: system debug trace controller
+ * etb: embedded trace buf
+ */
+void
+dhd_sdtc_etb_init(dhd_pub_t *dhd)
+{
+	bcm_iov_buf_t *iov_req = NULL;
+	etb_addr_info_t *p_etb_addr_info = NULL;
+	bcm_iov_buf_t *iov_resp = NULL;
+	uint8 *buf = NULL;
+	int ret = 0;
+	uint16 iovlen = 0;
+	uint16 version = 0;
+
+	BCM_REFERENCE(p_etb_addr_info);
+	dhd->sdtc_etb_inited = FALSE;
+
+	iov_req = MALLOCZ(dhd->osh, WLC_IOCTL_SMLEN);
+	if (iov_req == NULL) {
+		DHD_ERROR(("%s: Failed to alloc buffer for iovar request\n", __FUNCTION__));
+		goto exit;
+	}
+
+	buf = MALLOCZ(dhd->osh, WLC_IOCTL_MAXLEN);
+	if (buf == NULL) {
+		DHD_ERROR(("%s: Failed to alloc buffer for iovar response\n", __FUNCTION__));
+		goto exit;
+	}
+
+	/* fill header */
+	iov_req->version = WL_SDTC_IOV_VERSION;
+	iov_req->id = WL_SDTC_CMD_ETB_INFO;
+	iov_req->len = sizeof(etb_addr_info_t);
+	iovlen = OFFSETOF(bcm_iov_buf_t, data) + iov_req->len;
+
+	ret = dhd_iovar(dhd, 0, "sdtc", (char *)iov_req, iovlen,
+		(char *)buf, WLC_IOCTL_MAXLEN, FALSE);
+	if (ret < 0) {
+		DHD_ERROR(("%s failed to get sdtc etb_info %d\n", __FUNCTION__, ret));
+		goto exit;
+	}
+
+	version = dtoh16(*(uint16 *)buf);
+	/* Check for version */
+	if (version != WL_SDTC_IOV_VERSION) {
+		DHD_ERROR(("%s WL_SDTC_IOV_VERSION mis match\n", __FUNCTION__));
+		goto exit;
+	}
+	iov_resp = (bcm_iov_buf_t *)buf;
+	if (iov_resp->id == iov_req->id) {
+		p_etb_addr_info = (etb_addr_info_t*)iov_resp->data;
+		dhd->etb_addr_info.version = p_etb_addr_info->version;
+		dhd->etb_addr_info.len = p_etb_addr_info->len;
+		dhd->etb_addr_info.etbinfo_addr = p_etb_addr_info->etbinfo_addr;
+
+		DHD_ERROR(("%s etb_addr_info: ver:%d, len:%d, addr:0x%x\n", __FUNCTION__,
+			dhd->etb_addr_info.version, dhd->etb_addr_info.len,
+			dhd->etb_addr_info.etbinfo_addr));
+	} else {
+		DHD_ERROR(("%s Unknown CMD-ID (%d) as  response for request ID %d\n",
+			__FUNCTION__, iov_resp->id, iov_req->id));
+		goto exit;
+	}
+
+	/* since all the requirements for SDTC and ETB are met mark the capability as TRUE */
+	dhd->sdtc_etb_inited = TRUE;
+	DHD_ERROR(("%s sdtc_etb_inited: %d\n", __FUNCTION__, dhd->sdtc_etb_inited));
+exit:
+	if (iov_req) {
+		MFREE(dhd->osh, iov_req, WLC_IOCTL_SMLEN);
+	}
+	if (buf) {
+		MFREE(dhd->osh, buf, WLC_IOCTL_MAXLEN);
+	}
+	return;
+}
+
+void
+dhd_sdtc_etb_deinit(dhd_pub_t *dhd)
+{
+	dhd->sdtc_etb_inited = FALSE;
+	dhd->sdtc_etb_dump_len = 0;
+}
+
+int
+dhd_sdtc_etb_mempool_init(dhd_pub_t *dhd)
+{
+	dhd->sdtc_etb_dump_len = 0;
+	dhd->sdtc_etb_mempool = (uint8 *) MALLOCZ(dhd->osh, DHD_SDTC_ETB_MEMPOOL_SIZE);
+	if (dhd->sdtc_etb_mempool == NULL) {
+		DHD_ERROR(("%s: MALLOC of sdtc_etb_mempool failed\n",
+			__FUNCTION__));
+		return BCME_ERROR;
+	}
+	return BCME_OK;
+}
+
+void
+dhd_sdtc_etb_mempool_deinit(dhd_pub_t *dhd)
+{
+	if (dhd->sdtc_etb_mempool) {
+		MFREE(dhd->osh, dhd->sdtc_etb_mempool, DHD_SDTC_ETB_MEMPOOL_SIZE);
+		dhd->sdtc_etb_mempool = NULL;
+	}
+}
+#endif /* DHD_SDTC_ETB_DUMP */
+
+#ifdef DHD_FW_COREDUMP
+void* dhd_get_fwdump_buf(dhd_pub_t *dhd_pub, uint32 length)
+{
+	if (!dhd_pub->soc_ram) {
+#if defined(CONFIG_DHD_USE_STATIC_BUF) && defined(DHD_USE_STATIC_MEMDUMP)
+		dhd_pub->soc_ram = (uint8*)DHD_OS_PREALLOC(dhd_pub,
+			DHD_PREALLOC_MEMDUMP_RAM, length);
+#else
+		dhd_pub->soc_ram = (uint8*) MALLOC(dhd_pub->osh, length);
+
+		if ((dhd_pub->soc_ram == NULL) && CAN_SLEEP()) {
+			DHD_ERROR(("%s: Try to allocate virtual memory for fw crash snap shot.\n",
+				__FUNCTION__));
+			dhd_pub->soc_ram = (uint8*) VMALLOC(dhd_pub->osh, length);
+		}
+#endif /* CONFIG_DHD_USE_STATIC_BUF && DHD_USE_STATIC_MEMDUMP */
+	}
+
+	if (dhd_pub->soc_ram == NULL) {
+		DHD_ERROR(("%s: Failed to allocate memory for fw crash snap shot.\n",
+			__FUNCTION__));
+		dhd_pub->soc_ram_length = 0;
+	} else {
+		memset(dhd_pub->soc_ram, 0, length);
+		dhd_pub->soc_ram_length = length;
+	}
+
+	/* soc_ram free handled in dhd_{free,clear} */
+	return dhd_pub->soc_ram;
+}
+#endif /* DHD_FW_COREDUMP */
+
+/* to NDIS developer, the structure dhd_common is redundant,
+ * please do NOT merge it back from other branches !!!
+ */
+
+int
+dhd_common_socram_dump(dhd_pub_t *dhdp)
+{
+#ifndef BCMDBUS
+	return dhd_socram_dump(dhdp->bus);
+#else
+	return -1;
+#endif /* BCMDBUS */
+}
+
+static void
+dhd_dump_txrx_stats(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+{
+	/* TX Stats -- add any Tx counters in this section only */
+	bcm_bprintf(strbuf, "\nTX stats:\n=========\n");
+	bcm_bprintf(strbuf, "tx_packets %lu tx_bytes %lu tx_dropped %lu"
+		" tx_multicast %lu tx_errors %lu\n",
+		dhdp->tx_packets, dhdp->tx_bytes, dhdp->tx_dropped,
+		dhdp->tx_multicast, dhdp->tx_errors);
+	bcm_bprintf(strbuf, "tx_ctlpkts %lu tx_ctlerrs %lu\n",
+	            dhdp->tx_ctlpkts, dhdp->tx_ctlerrs);
+	bcm_bprintf(strbuf, "tx_realloc %lu tx_pktgetfail %lu tx_big_packets %lu\n",
+	            dhdp->tx_realloc, dhdp->tx_pktgetfail, dhdp->tx_big_packets);
+	/* ----------------------------------------------------- */
+
+	/* RX Stats -- add any Rx counters in this section only */
+	bcm_bprintf(strbuf, "\nRX stats:\n=========\n");
+	bcm_bprintf(strbuf, "rx_packets %lu rx_bytes %lu rx_forward"
+		" %lu rx_multicast %lu rx_errors %lu \n",
+		dhdp->rx_packets, dhdp->rx_bytes, dhdp->rx_forward,
+		dhdp->rx_multicast, dhdp->rx_errors);
+	bcm_bprintf(strbuf, "rx_ctlpkts %lu rx_ctlerrs %lu rx_dropped %lu\n",
+	            dhdp->rx_ctlpkts, dhdp->rx_ctlerrs, dhdp->rx_dropped);
+	bcm_bprintf(strbuf, "rx_readahead_cnt %lu rx_pktgetfail %lu rx_pktgetpool_fail %lu\n",
+	            dhdp->rx_readahead_cnt, dhdp->rx_pktgetfail, dhdp->rx_pktgetpool_fail);
+	bcm_bprintf(strbuf, "\n");
+	/* ----------------------------------------------------- */
+}
+
+#ifdef DHD_MEM_STATS
+static void
+dhd_dump_memstats(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+{
+	uint64 malloc_mem = 0;
+	uint64 total_txpath_mem = 0;
+	uint64 txpath_bkpq_len = 0;
+	uint64 txpath_bkpq_mem = 0;
+	uint64 total_dhd_mem = 0;
+
+	malloc_mem = MALLOCED(dhdp->osh);
+
+	UNUSED_PARAMETER(malloc_mem);
+	UNUSED_PARAMETER(total_txpath_mem);
+	UNUSED_PARAMETER(txpath_bkpq_len);
+	UNUSED_PARAMETER(txpath_bkpq_mem);
+
+#ifdef BCMPCIE
+	txpath_bkpq_len = dhd_active_tx_flowring_bkpq_len(dhdp);
+	/*
+	 * Instead of traversing the entire queue to find the skbs length,
+	 * considering MAX_MTU_SZ as lenth of each skb.
+	 */
+	txpath_bkpq_mem = (txpath_bkpq_len* MAX_MTU_SZ);
+	total_txpath_mem = dhdp->txpath_mem + txpath_bkpq_mem;
+
+	bcm_bprintf(strbuf, "\nDHD malloc memory_usage: %llubytes %lluKB\n",
+		malloc_mem, (malloc_mem / 1024));
+
+	bcm_bprintf(strbuf, "\nDHD tx-bkpq len: %llu memory_usage: %llubytes %lluKB\n",
+		txpath_bkpq_len, txpath_bkpq_mem, (txpath_bkpq_mem / 1024));
+	bcm_bprintf(strbuf, "DHD tx-path memory_usage: %llubytes %lluKB\n",
+		total_txpath_mem, (total_txpath_mem / 1024));
+
+	total_dhd_mem = malloc_mem + total_txpath_mem;
+#endif /* BCMPCIE */
+
+#if defined(DHD_LB_STATS)
+	total_dhd_mem += dhd_lb_mem_usage(dhdp, strbuf);
+#endif /* DHD_LB_STATS */
+	bcm_bprintf(strbuf, "\nDHD Total memory_usage: %llubytes %lluKB \n",
+		total_dhd_mem, (total_dhd_mem / 1024));
+}
+#endif /* DHD_MEM_STATS */
+
+int
+dhd_dump(dhd_pub_t *dhdp, char *buf, int buflen)
+{
+	struct bcmstrbuf b;
+	struct bcmstrbuf *strbuf = &b;
+
+	if (!dhdp || !dhdp->prot || !buf) {
+		return BCME_ERROR;
+	}
+
+	bcm_binit(strbuf, buf, buflen);
+
+	/* Base DHD info */
+	bcm_bprintf(strbuf, "%s\n", dhd_version);
+	bcm_bprintf(strbuf, "\n");
+	bcm_bprintf(strbuf, "pub.up %d pub.txoff %d pub.busstate %d\n",
+	            dhdp->up, dhdp->txoff, dhdp->busstate);
+#ifdef WBRC
+	bcm_bprintf(strbuf, "chip_bighammer_count:%d\n", dhdp->chip_bighammer_count);
+#endif /* WBRC */
+	bcm_bprintf(strbuf, "pub.hdrlen %u pub.maxctl %u pub.rxsz %u\n",
+	            dhdp->hdrlen, dhdp->maxctl, dhdp->rxsz);
+	bcm_bprintf(strbuf, "pub.iswl %d pub.drv_version %ld pub.mac "MACDBG"\n",
+	            dhdp->iswl, dhdp->drv_version, MAC2STRDBG(&dhdp->mac));
+	bcm_bprintf(strbuf, "pub.bcmerror %d tickcnt %u\n", dhdp->bcmerror, dhdp->tickcnt);
+
+	dhd_dump_txrx_stats(dhdp, strbuf);
+
+#ifdef DMAMAP_STATS
+	/* Add DMA MAP info */
+	bcm_bprintf(strbuf, "DMA MAP stats: \n");
+	bcm_bprintf(strbuf, "txdata: %lu size: %luK, rxdata: %lu size: %luK\n",
+			dhdp->dma_stats.txdata, KB(dhdp->dma_stats.txdata_sz),
+			dhdp->dma_stats.rxdata, KB(dhdp->dma_stats.rxdata_sz));
+#ifndef IOCTLRESP_USE_CONSTMEM
+	bcm_bprintf(strbuf, "IOCTL RX: %lu size: %luK ,",
+			dhdp->dma_stats.ioctl_rx, KB(dhdp->dma_stats.ioctl_rx_sz));
+#endif /* !IOCTLRESP_USE_CONSTMEM */
+	bcm_bprintf(strbuf, "EVENT RX: %lu size: %luK, INFO RX: %lu size: %luK, "
+			"TSBUF RX: %lu size %luK\n",
+			dhdp->dma_stats.event_rx, KB(dhdp->dma_stats.event_rx_sz),
+			dhdp->dma_stats.info_rx, KB(dhdp->dma_stats.info_rx_sz),
+			dhdp->dma_stats.tsbuf_rx, KB(dhdp->dma_stats.tsbuf_rx_sz));
+	bcm_bprintf(strbuf, "Total : %luK \n",
+			KB(dhdp->dma_stats.txdata_sz + dhdp->dma_stats.rxdata_sz +
+			dhdp->dma_stats.ioctl_rx_sz + dhdp->dma_stats.event_rx_sz +
+			dhdp->dma_stats.tsbuf_rx_sz));
+#endif /* DMAMAP_STATS */
+	bcm_bprintf(strbuf, "dhd_induce_error : %u\n", dhdp->dhd_induce_error);
+	/* Add any prot info */
+	dhd_prot_dump(dhdp, strbuf);
+	bcm_bprintf(strbuf, "\n");
+
+	/* Add any bus info */
+	dhd_bus_dump(dhdp, strbuf);
+#if defined(BCM_ROUTER_DHD) && defined(HNDCTF)
+	/* Add ctf info */
+	dhd_ctf_dump(dhdp, strbuf);
+#endif /* BCM_ROUTER_DHD && HNDCTF */
+
+#if defined(DHD_LB_STATS)
+	dhd_lb_stats_dump(dhdp, strbuf);
+#endif /* DHD_LB_STATS */
+
+#ifdef DHD_MEM_STATS
+	dhd_dump_memstats(dhdp, strbuf);
+#endif /* DHD_MEM_STATS */
+
+#if defined(DHD_MQ) && defined(DHD_MQ_STATS)
+	dhd_mqstats_dump(dhdp, strbuf);
+#endif
+
+#ifdef DHD_WET
+	if (dhd_get_wet_mode(dhdp)) {
+		bcm_bprintf(strbuf, "Wet Dump:\n");
+		dhd_wet_dump(dhdp, strbuf);
+		}
+#endif /* DHD_WET */
+
+	DHD_ERROR(("%s bufsize: %d free: %d\n", __FUNCTION__, buflen, strbuf->size));
+	/* return remaining buffer length */
+	return (!strbuf->size ? BCME_BUFTOOSHORT : strbuf->size);
+}
+
+int
+dhd_counters(dhd_pub_t *dhdp, char *buf, int buflen)
+{
+	struct bcmstrbuf bcmbuf;
+	struct bcmstrbuf *strbuf = &bcmbuf;
+
+	if (!dhdp || !dhdp->prot || !buf) {
+		return BCME_ERROR;
+	}
+
+	bcm_binit(strbuf, buf, buflen);
+
+	dhd_dump_txrx_stats(dhdp, strbuf);
+
+	dhd_bus_counters(dhdp, strbuf);
+
+#if defined(DHD_LB_STATS)
+	dhd_lb_stats_dump(dhdp, strbuf);
+#endif /* DHD_LB_STATS */
+
+#ifdef DHD_MEM_STATS
+	dhd_dump_memstats(dhdp, strbuf);
+#endif /* DHD_MEM_STATS */
+
+	return (!strbuf->size ? BCME_BUFTOOSHORT : strbuf->size);
+}
+
+void
+dhd_dump_to_kernelog(dhd_pub_t *dhdp)
+{
+	char buf[512];
+
+	DHD_ERROR(("F/W version: %s\n", fw_version));
+	bcm_bprintf_bypass = TRUE;
+	dhd_dump(dhdp, buf, sizeof(buf));
+	bcm_bprintf_bypass = FALSE;
+}
+
+int
+dhd_wl_ioctl_cmd(dhd_pub_t *dhd_pub, int cmd, void *arg, int len, uint8 set, int ifidx)
+{
+	wl_ioctl_t ioc;
+
+	ioc.cmd = cmd;
+	ioc.buf = arg;
+	ioc.len = len;
+	ioc.set = set;
+
+	return dhd_wl_ioctl(dhd_pub, ifidx, &ioc, arg, len);
+}
+
+int
+dhd_wl_ioctl_get_intiovar(dhd_pub_t *dhd_pub, char *name, uint *pval,
+	int cmd, uint8 set, int ifidx)
+{
+	char iovbuf[WLC_IOCTL_SMLEN];
+	int ret = -1;
+
+	memset(iovbuf, 0, sizeof(iovbuf));
+	if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) {
+		ret = dhd_wl_ioctl_cmd(dhd_pub, cmd, iovbuf, sizeof(iovbuf), set, ifidx);
+		if (!ret) {
+			*pval = ltoh32(*((uint*)iovbuf));
+		} else {
+			DHD_ERROR(("%s: get int iovar %s failed, ERR %d\n",
+				__FUNCTION__, name, ret));
+		}
+	} else {
+		DHD_ERROR(("%s: mkiovar %s failed\n",
+			__FUNCTION__, name));
+	}
+
+	return ret;
+}
+
+int
+dhd_wl_ioctl_set_intiovar(dhd_pub_t *dhd_pub, char *name, uint val,
+	int cmd, uint8 set, int ifidx)
+{
+	char iovbuf[WLC_IOCTL_SMLEN];
+	int ret = -1;
+	int lval = htol32(val);
+	uint len;
+
+	len = bcm_mkiovar(name, (char*)&lval, sizeof(lval), iovbuf, sizeof(iovbuf));
+
+	if (len) {
+		ret = dhd_wl_ioctl_cmd(dhd_pub, cmd, iovbuf, len, set, ifidx);
+		if (ret) {
+			DHD_ERROR(("%s: set int iovar %s failed, ERR %d\n",
+				__FUNCTION__, name, ret));
+		}
+	} else {
+		DHD_ERROR(("%s: mkiovar %s failed\n",
+			__FUNCTION__, name));
+	}
+
+	return ret;
+}
+
+static struct ioctl2str_s {
+	uint32 ioctl;
+	char *name;
+} ioctl2str_array[] = {
+	{WLC_UP, "UP"},
+	{WLC_DOWN, "DOWN"},
+	{WLC_SET_PROMISC, "SET_PROMISC"},
+	{WLC_SET_INFRA, "SET_INFRA"},
+	{WLC_SET_AUTH, "SET_AUTH"},
+	{WLC_SET_SSID, "SET_SSID"},
+	{WLC_RESTART, "RESTART"},
+	{WLC_SET_CHANNEL, "SET_CHANNEL"},
+	{WLC_SET_RATE_PARAMS, "SET_RATE_PARAMS"},
+	{WLC_SET_KEY, "SET_KEY"},
+	{WLC_SCAN, "SCAN"},
+	{WLC_DISASSOC, "DISASSOC"},
+	{WLC_REASSOC, "REASSOC"},
+	{WLC_SET_COUNTRY, "SET_COUNTRY"},
+	{WLC_SET_WAKE, "SET_WAKE"},
+	{WLC_SET_SCANSUPPRESS, "SET_SCANSUPPRESS"},
+	{WLC_SCB_DEAUTHORIZE, "SCB_DEAUTHORIZE"},
+	{WLC_SET_WSEC, "SET_WSEC"},
+	{WLC_SET_INTERFERENCE_MODE, "SET_INTERFERENCE_MODE"},
+	{WLC_SET_RADAR, "SET_RADAR"},
+	{0, NULL}
+};
+
+static char *
+ioctl2str(uint32 ioctl)
+{
+	struct ioctl2str_s *p = ioctl2str_array;
+
+	while (p->name != NULL) {
+		if (p->ioctl == ioctl) {
+			return p->name;
+		}
+		p++;
+	}
+
+	return "";
+}
+
+/**
+ * @param ioc          IO control struct, members are partially used by this function.
+ * @param buf [inout]  Contains parameters to send to dongle, contains dongle response on return.
+ * @param len          Maximum number of bytes that dongle is allowed to write into 'buf'.
+ */
+int
+dhd_wl_ioctl(dhd_pub_t *dhd_pub, int ifidx, wl_ioctl_t *ioc, void *buf, int len)
+{
+	int ret = BCME_ERROR;
+	unsigned long flags;
+#ifdef DUMP_IOCTL_IOV_LIST
+	dhd_iov_li_t *iov_li;
+#endif /* DUMP_IOCTL_IOV_LIST */
+#ifdef REPORT_FATAL_TIMEOUTS
+	wl_escan_params_v1_t *eparams;
+	uint8 *buf_ptr = (uint8 *)buf;
+	uint16 action = 0;
+#endif /* REPORT_FATAL_TIMEOUTS */
+	int hostsleep_set = 0;
+	int hostsleep_val = 0;
+
+	if (dhd_query_bus_erros(dhd_pub)) {
+		return -ENODEV;
+	}
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+	DHD_OS_WAKE_LOCK(dhd_pub);
+	if (pm_runtime_get_sync(dhd_bus_to_dev(dhd_pub->bus)) < 0) {
+		DHD_RPM(("%s: pm_runtime_get_sync error. \n", __FUNCTION__));
+		DHD_OS_WAKE_UNLOCK(dhd_pub);
+		return BCME_ERROR;
+	}
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+#ifdef WL_NAN
+#ifdef PROP_TXSTATUS_VSDB
+	/* pre enable wlfc before interface create */
+	if (ioc->cmd == WLC_GET_VAR && buf) {
+		char tmp_buf[64];
+		dhd_if_t *ifp = dhd_get_ifp(dhd_pub, ifidx);
+		int minlen = MIN(sizeof(tmp_buf) - 1, strlen(buf));
+		memset(tmp_buf, 0, sizeof(tmp_buf));
+		bcopy(buf, tmp_buf, minlen);
+		tmp_buf[minlen] = '\0';
+
+		if (strcmp("interface_create", tmp_buf) == 0) {
+			wl_cfg80211_set_wlfc(ifp->net, TRUE);
+		}
+	}
+#endif /* PROP_TXSTATUS_VSDB */
+#endif /* WL_NAN */
+
+#ifdef KEEPIF_ON_DEVICE_RESET
+	if (ioc->cmd == WLC_GET_VAR) {
+		dbus_config_t config;
+		config.general_param = 0;
+		if (buf) {
+			if (!strcmp(buf, "wowl_activate")) {
+				 /* 1 (TRUE) after decreased by 1 */
+				config.general_param = 2;
+			} else if (!strcmp(buf, "wowl_clear")) {
+				 /* 0 (FALSE) after decreased by 1 */
+				config.general_param = 1;
+			}
+		}
+		if (config.general_param) {
+			config.config_id = DBUS_CONFIG_ID_KEEPIF_ON_DEVRESET;
+			config.general_param--;
+			dbus_set_config(dhd_pub->dbus, &config);
+		}
+	}
+#endif /* KEEPIF_ON_DEVICE_RESET */
+
+	if (dhd_os_proto_block(dhd_pub))
+	{
+#ifdef DHD_LOG_DUMP
+		int slen, val, lval, min_len;
+		char *msg, tmp[64];
+
+		/* WLC_GET_VAR */
+		if (ioc->cmd == WLC_GET_VAR && buf) {
+			min_len = MIN(sizeof(tmp) - 1, strlen(buf));
+			memset(tmp, 0, sizeof(tmp));
+			bcopy(buf, tmp, min_len);
+			tmp[min_len] = '\0';
+		}
+#endif /* DHD_LOG_DUMP */
+
+#ifdef DHD_DISCONNECT_TRACE
+		if (WLC_DISASSOC == ioc->cmd || WLC_DOWN == ioc->cmd ||
+			WLC_DISASSOC_MYAP == ioc->cmd) {
+			DHD_ERROR(("IOCTL Disconnect WiFi: %d\n", ioc->cmd));
+		}
+#endif /* HW_DISCONNECT_TRACE */
+		/* logging of iovars that are send to the dongle, ./dhd msglevel +iovar */
+		if (ioc->set == TRUE) {
+			char *pars = (char *)buf; // points at user buffer
+			if (ioc->cmd == WLC_SET_VAR && buf) {
+				DHD_DNGL_IOVAR_SET(("iovar:%d: set %s", ifidx, pars));
+				if (ioc->len > 1 + sizeof(uint32)) {
+					// skip iovar name:
+					pars += strnlen(pars, ioc->len - 1 - sizeof(uint32));
+					pars++;               // skip NULL character
+				}
+			} else {
+				DHD_DNGL_IOVAR_SET(("ioctl:%d: set %d %s",
+					ifidx, ioc->cmd, ioctl2str(ioc->cmd)));
+			}
+			if (pars != NULL) {
+				DHD_DNGL_IOVAR_SET((" 0x%x\n", *(uint32*)pars));
+			} else {
+				DHD_DNGL_IOVAR_SET((" NULL\n"));
+			}
+		}
+
+		DHD_LINUX_GENERAL_LOCK(dhd_pub, flags);
+		if (DHD_BUS_CHECK_DOWN_OR_DOWN_IN_PROGRESS(dhd_pub)) {
+			DHD_INFO(("%s: returning as busstate=%d\n",
+				__FUNCTION__, dhd_pub->busstate));
+			DHD_LINUX_GENERAL_UNLOCK(dhd_pub, flags);
+			dhd_os_proto_unblock(dhd_pub);
+			return -ENODEV;
+		}
+		DHD_BUS_BUSY_SET_IN_IOVAR(dhd_pub);
+		DHD_LINUX_GENERAL_UNLOCK(dhd_pub, flags);
+
+#ifdef OEM_ANDROID
+		/*
+		 * If system suspend started before ioctl, after getting d3 ack,
+		 * it will check for wakelock and as ioctl will hold wakelock,
+		 * it will put bus back to d0 and bail out.
+		 * So the current ioctl should wait till it is bailed out.
+		 */
+		if (DHD_BUS_BUSY_CHECK_SUSPEND_IN_PROGRESS(dhd_pub)) {
+			int timeleft = 0;
+			DHD_PRINT(("%s: wait till system suspend bails out\n", __FUNCTION__));
+			/* wait till SUSPEND_IN_PROGRESS bit is cleared */
+			timeleft = dhd_os_busbusy_wait_bitmask(dhd_pub,
+					&dhd_pub->dhd_bus_busy_state,
+					DHD_BUS_BUSY_SUSPEND_IN_PROGRESS, 0);
+			if ((dhd_pub->dhd_bus_busy_state & DHD_BUS_BUSY_SUSPEND_IN_PROGRESS) != 0) {
+				DHD_ERROR(("%s: system suspend wait timed out(%d)"
+					" dhd_bus_busy_state=0x%x\n", __FUNCTION__, timeleft,
+					dhd_pub->dhd_bus_busy_state));
+			}
+		}
+#endif /* OEM_ANDROID */
+
+		DHD_LINUX_GENERAL_LOCK(dhd_pub, flags);
+		if (DHD_BUS_CHECK_SUSPEND_OR_ANY_SUSPEND_IN_PROGRESS(dhd_pub) ||
+			dhd_pub->dhd_induce_error == DHD_INDUCE_IOCTL_SUSPEND_ERROR) {
+			DHD_ERROR(("%s: bus is in suspend(%d) or suspending(0x%x) state!!\n",
+				__FUNCTION__, dhd_pub->busstate, dhd_pub->dhd_bus_busy_state));
+#ifdef DHD_SEND_HANG_IOCTL_SUSPEND_ERROR
+			ioctl_suspend_error++;
+			if (ioctl_suspend_error > MAX_IOCTL_SUSPEND_ERROR) {
+				dhd_pub->hang_reason = HANG_REASON_IOCTL_SUSPEND_ERROR;
+				dhd_os_send_hang_message(dhd_pub);
+				ioctl_suspend_error = 0;
+			}
+#endif /* DHD_SEND_HANG_IOCTL_SUSPEND_ERROR */
+			DHD_BUS_BUSY_CLEAR_IN_IOVAR(dhd_pub);
+			dhd_os_busbusy_wake(dhd_pub);
+			DHD_LINUX_GENERAL_UNLOCK(dhd_pub, flags);
+			dhd_os_proto_unblock(dhd_pub);
+			return -ENODEV;
+		}
+#ifdef DHD_SEND_HANG_IOCTL_SUSPEND_ERROR
+		ioctl_suspend_error = 0;
+#endif /* DHD_SEND_HANG_IOCTL_SUSPEND_ERROR */
+		DHD_LINUX_GENERAL_UNLOCK(dhd_pub, flags);
+
+#if defined(WL_WLC_SHIM)
+		{
+			struct wl_shim_node *shim = dhd_pub_shim(dhd_pub);
+
+			wl_io_pport_t io_pport;
+			io_pport.dhd_pub = dhd_pub;
+			io_pport.ifidx = ifidx;
+
+			ret = wl_shim_ioctl(shim, ioc, len, &io_pport);
+			if (ret != BCME_OK) {
+				DHD_TRACE(("%s: wl_shim_ioctl(%d) ERR %d\n",
+					__FUNCTION__, ioc->cmd, ret));
+			}
+		}
+#else
+#ifdef DUMP_IOCTL_IOV_LIST
+		if (ioc->cmd != WLC_GET_MAGIC && ioc->cmd != WLC_GET_VERSION && buf) {
+			if (!(iov_li = MALLOC(dhd_pub->osh, sizeof(*iov_li)))) {
+				DHD_ERROR(("iovar dump list item allocation Failed\n"));
+			} else {
+				iov_li->cmd = ioc->cmd;
+				if (buf)
+					bcopy((char *)buf, iov_li->buff, strlen((char *)buf)+1);
+				dhd_iov_li_append(dhd_pub, &dhd_pub->dump_iovlist_head,
+						&iov_li->list);
+			}
+		}
+#endif /* DUMP_IOCTL_IOV_LIST */
+
+#ifdef REPORT_FATAL_TIMEOUTS
+		/* fill in the sync_id to ensure that the scan timeout is always for the
+		* current running escan in the FW - the wl app does not fill in an
+		* incrementing number for sync_id, it only fills in a random number which
+		* increases the chance of 2 consecutive escans having the same sync id
+		* This should happen here after dhd_proto_block()
+		* is called, so that sync_id does not
+		* get incremented if 2 consecutive escans are fired in quick succession
+		*/
+		/* XXX Except that wl_cfgscan.c is having its own sync_id setting
+		 * and expectation, so that below cannot work with a wpa_supplicant!!
+		 * For now disable the REPORT_FATAL_TIMEOUTS flag.
+		 */
+		if ((ioc->cmd == WLC_SET_VAR &&
+				buf != NULL &&
+				strcmp("escan", buf) == 0)) {
+			eparams = (wl_escan_params_v1_t *) (buf_ptr + strlen("escan") + 1);
+			action = dtoh16(eparams->action);
+			if (action == WL_SCAN_ACTION_START) {
+				++dhd_pub->esync_id;
+				/* sync id of 0 is not used for escan,
+				* it is used to indicate
+				* a normal scan timer is running, so as
+				* to ensure that escan abort event
+				* does not cancel a normal scan timeout
+				*/
+				if (dhd_pub->esync_id == 0)
+					++dhd_pub->esync_id;
+				DHD_INFO(("%s:escan sync id set to = %u \n",
+					__FUNCTION__, dhd_pub->esync_id));
+				eparams->sync_id = htod16(dhd_pub->esync_id);
+			}
+		}
+#endif /* REPORT_FATAL_TIMEOUTS */
+
+		if (dhd_conf_check_hostsleep(dhd_pub, ioc->cmd, ioc->buf, len,
+				&hostsleep_set, &hostsleep_val, &ret))
+			goto exit;
+		ret = dhd_prot_ioctl(dhd_pub, ifidx, ioc, buf, len);
+		dhd_conf_get_hostsleep(dhd_pub, hostsleep_set, hostsleep_val, ret);
+
+#ifdef PROP_TXSTATUS_VSDB
+#if defined(WL_TWT) || defined(WL_TWT_HAL_IF)
+		if (ret == BCME_OK && (ioc->cmd == WLC_SET_VAR &&
+				buf != NULL &&
+				strcmp("twt", buf) == 0)) {
+			uint16 *type = (uint16 *)((uint8 *)buf + strlen("twt") + 1);
+			dhd_if_t *ifp = dhd_get_ifp(dhd_pub, ifidx);
+			wl_cfg80211_twt_update(ifp->net, *type);
+		}
+#endif /* WL_TWT_HAL_IF || WL_TWT */
+#endif /* PROP_TXSTATUS_VSDB */
+#ifdef DUMP_IOCTL_IOV_LIST
+		if (ret == -ETIMEDOUT) {
+			DHD_ERROR(("Last %d issued commands: Latest one is at bottom.\n",
+				IOV_LIST_MAX_LEN));
+			dhd_iov_li_print(&dhd_pub->dump_iovlist_head);
+		}
+#endif /* DUMP_IOCTL_IOV_LIST */
+#endif /* defined(WL_WLC_SHIM) */
+#ifdef WL_CFGVENDOR_SEND_HANG_EVENT
+		if (ret == -ETIMEDOUT) {
+			copy_hang_info_ioctl_timeout(dhd_pub, ifidx, ioc);
+		}
+#endif /* WL_CFGVENDOR_SEND_HANG_EVENT */
+#ifdef DHD_LOG_DUMP
+		if ((ioc->cmd == WLC_GET_VAR || ioc->cmd == WLC_SET_VAR) &&
+				buf != NULL) {
+			if (buf) {
+				lval = 0;
+				slen = strlen(buf) + 1;
+				msg = (char*)buf;
+				if (len >= slen + sizeof(lval)) {
+					if (ioc->cmd == WLC_GET_VAR) {
+						msg = tmp;
+						lval = *(int*)buf;
+					} else {
+						min_len = MIN(ioc->len - slen, sizeof(int));
+						bcopy((msg + slen), &lval, min_len);
+					}
+					if (!strncmp(msg, "cur_etheraddr",
+						strlen("cur_etheraddr"))) {
+						lval = 0;
+					}
+				}
+				DHD_IOVAR_LOG(dhd_pub, ioc->cmd, msg,
+					("%s: cmd: %d, msg: %s val: 0x%x,"
+					" len: %d, set: %d, txn-id: %d\n",
+					ioc->cmd == WLC_GET_VAR ?
+					"WLC_GET_VAR" : "WLC_SET_VAR",
+					ioc->cmd, msg, lval, ioc->len, ioc->set,
+					dhd_prot_get_ioctl_trans_id(dhd_pub)));
+			} else {
+				DHD_IOVAR_MEM(("%s: cmd: %d, len: %d, set: %d, txn-id: %d\n",
+					ioc->cmd == WLC_GET_VAR ? "WLC_GET_VAR" : "WLC_SET_VAR",
+					ioc->cmd, ioc->len, ioc->set,
+					dhd_prot_get_ioctl_trans_id(dhd_pub)));
+			}
+		} else {
+			slen = ioc->len;
+			if (buf != NULL && slen != 0) {
+				if (slen >= 4) {
+					val = *(int*)buf;
+				} else if (slen >= 2) {
+					val = *(short*)buf;
+				} else {
+					val = *(char*)buf;
+				}
+				/* Do not dump for WLC_GET_MAGIC and WLC_GET_VERSION */
+				if (ioc->cmd != WLC_GET_MAGIC && ioc->cmd != WLC_GET_VERSION) {
+					DHD_IOVAR_MEM(("WLC_IOCTL: cmd: %d, val: %d, len: %d, "
+						"set: %d\n", ioc->cmd, val, ioc->len, ioc->set));
+				}
+			} else {
+				DHD_IOVAR_MEM(("WLC_IOCTL: cmd: %d, buf is NULL\n", ioc->cmd));
+			}
+		}
+#endif /* DHD_LOG_DUMP */
+#if defined(OEM_ANDROID)
+		if (ret && dhd_pub->up) {
+			/* Send hang event only if dhd_open() was success */
+			dhd_os_check_hang(dhd_pub, ifidx, ret);
+		}
+
+		if (ret == -ETIMEDOUT && !dhd_pub->up) {
+			DHD_ERROR(("%s: 'resumed on timeout' error is "
+				"occurred before the interface does not"
+				" bring up\n", __FUNCTION__));
+		}
+#endif /* defined(OEM_ANDROID) */
+
+exit:
+		DHD_LINUX_GENERAL_LOCK(dhd_pub, flags);
+		DHD_BUS_BUSY_CLEAR_IN_IOVAR(dhd_pub);
+		dhd_os_busbusy_wake(dhd_pub);
+		DHD_LINUX_GENERAL_UNLOCK(dhd_pub, flags);
+
+#ifdef REPORT_FATAL_TIMEOUTS
+		if ((ret == BCME_OK && ioc->cmd == WLC_SET_VAR &&
+				buf != NULL &&
+				strcmp("escan", buf) == 0)) {
+			if (action == WL_SCAN_ACTION_START)
+				dhd_start_scan_timer(dhd_pub, TRUE);
+		}
+#endif /* REPORT_FATAL_TIMEOUTS */
+
+		dhd_os_proto_unblock(dhd_pub);
+
+#ifdef DETAIL_DEBUG_LOG_FOR_IOCTL
+		if (ret < 0) {
+			if ((ioc->cmd == WLC_GET_VAR || ioc->cmd == WLC_SET_VAR) &&
+					buf != NULL) {
+				if (ret == BCME_UNSUPPORTED || ret == BCME_NOTASSOCIATED) {
+					DHD_ERROR_MEM(("%s: %s: %s, %s\n",
+						__FUNCTION__, ioc->cmd == WLC_GET_VAR ?
+						"WLC_GET_VAR" : "WLC_SET_VAR",
+						buf? (char *)buf:"NO MESSAGE",
+						ret == BCME_UNSUPPORTED ? "UNSUPPORTED"
+						: "NOT ASSOCIATED"));
+				} else {
+					DHD_ERROR_MEM(("%s: %s: %s, ret = %d\n",
+						__FUNCTION__, ioc->cmd == WLC_GET_VAR ?
+						"WLC_GET_VAR" : "WLC_SET_VAR",
+						(char *)buf, ret));
+				}
+			} else {
+				if (ret == BCME_UNSUPPORTED || ret == BCME_NOTASSOCIATED) {
+					DHD_ERROR_MEM(("%s: WLC_IOCTL: cmd: %d, %s\n",
+						__FUNCTION__, ioc->cmd,
+						ret == BCME_UNSUPPORTED ? "UNSUPPORTED" :
+						"NOT ASSOCIATED"));
+				} else {
+					DHD_ERROR_MEM(("%s: WLC_IOCTL: cmd: %d, ret = %d\n",
+						__FUNCTION__, ioc->cmd, ret));
+				}
+			}
+		}
+#endif /* DETAIL_DEBUG_LOG_FOR_IOCTL */
+	}
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+	pm_runtime_mark_last_busy(dhd_bus_to_dev(dhd_pub->bus));
+	pm_runtime_put_autosuspend(dhd_bus_to_dev(dhd_pub->bus));
+
+	DHD_OS_WAKE_UNLOCK(dhd_pub);
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+#ifdef WL_MONITOR
+	/* Intercept monitor ioctl here, add/del monitor if */
+	if (ret == BCME_OK && ioc->cmd == WLC_SET_MONITOR) {
+		int val = 0;
+		if (buf != NULL && len != 0) {
+			if (len >= 4) {
+				val = *(int*)buf;
+			} else if (len >= 2) {
+				val = *(short*)buf;
+			} else {
+				val = *(char*)buf;
+			}
+		}
+		dhd_set_monitor(dhd_pub, ifidx, val);
+	}
+#endif /* WL_MONITOR */
+
+	return ret;
+}
+
+uint wl_get_port_num(wl_io_pport_t *io_pport)
+{
+	return 0;
+}
+
+/* Get bssidx from iovar params
+ * Input:   dhd_pub - pointer to dhd_pub_t
+ *	    params  - IOVAR params
+ * Output:  idx	    - BSS index
+ *	    val	    - ponter to the IOVAR arguments
+ */
+static int
+dhd_iovar_parse_bssidx(dhd_pub_t *dhd_pub, const char *params, uint32 *idx, const char **val)
+{
+	char *prefix = "bsscfg:";
+	uint32	bssidx;
+
+	if (!(strncmp(params, prefix, strlen(prefix)))) {
+		/* per bss setting should be prefixed with 'bsscfg:' */
+		const char *p = params + strlen(prefix);
+
+		/* Skip Name */
+		while (*p != '\0')
+			p++;
+		/* consider null */
+		p = p + 1;
+		bcopy(p, &bssidx, sizeof(uint32));
+		/* Get corresponding dhd index */
+		bssidx = dhd_bssidx2idx(dhd_pub, htod32(bssidx));
+
+		if (bssidx >= DHD_MAX_IFS) {
+			DHD_ERROR(("%s Wrong bssidx provided\n", __FUNCTION__));
+			return BCME_ERROR;
+		}
+
+		/* skip bss idx */
+		p += sizeof(uint32);
+		*val = p;
+		*idx = bssidx;
+	} else {
+		DHD_ERROR(("%s: bad parameter for per bss iovar\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	return BCME_OK;
+}
+
+#if defined(DHD_DEBUG) && defined(BCMDBUS)
+/* USB Device console input function */
+int dhd_bus_console_in(dhd_pub_t *dhd, uchar *msg, uint msglen)
+{
+	DHD_TRACE(("%s \n", __FUNCTION__));
+
+	return dhd_iovar(dhd, 0, "cons", msg, msglen, NULL, 0, TRUE);
+
+}
+#endif /* DHD_DEBUG && BCMDBUS  */
+
+#ifdef DHD_DEBUG
+int
+dhd_mem_debug(dhd_pub_t *dhd, uchar *msg, uint msglen)
+{
+	unsigned long int_arg = 0;
+	char *p;
+	char *end_ptr = NULL;
+	dhd_dbg_mwli_t *mw_li;
+	dll_t *item, *next;
+	/* check if mwalloc, mwquery or mwfree was supplied arguement with space */
+	p = bcmstrstr((char *)msg, " ");
+	if (p != NULL) {
+		/* space should be converted to null as separation flag for firmware */
+		*p = '\0';
+		/* store the argument in int_arg */
+		int_arg = bcm_strtoul(p+1, &end_ptr, 10);
+	}
+
+	if (!p && !strcmp(msg, "query")) {
+		/* lets query the list inetrnally */
+		if (dll_empty(dll_head_p(&dhd->mw_list_head))) {
+			DHD_ERROR(("memwaste list is empty, call mwalloc < size > to allocate\n"));
+		} else {
+			for (item = dll_head_p(&dhd->mw_list_head);
+					!dll_end(&dhd->mw_list_head, item); item = next) {
+				next = dll_next_p(item);
+				mw_li = (dhd_dbg_mwli_t *)CONTAINEROF(item, dhd_dbg_mwli_t, list);
+				DHD_ERROR(("item: <id=%d, size=%d>\n", mw_li->id, mw_li->size));
+			}
+		}
+	} else if (p && end_ptr && (*end_ptr == '\0') && !strcmp(msg, "alloc")) {
+		int32 alloc_handle;
+		/* convert size into KB and append as integer */
+		*((int32 *)(p+1)) = int_arg*1024;
+		*(p+1+sizeof(int32)) = '\0';
+
+		/* recalculated length -> 5 bytes for "alloc" + 4 bytes for size +
+		 * 1 bytes for null caracter
+		 */
+		msglen = strlen(msg) + sizeof(int32) + 1;
+		if (dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, msg, msglen+1, FALSE, 0) < 0) {
+			DHD_ERROR(("IOCTL failed for memdebug alloc\n"));
+		}
+
+		/* returned allocated handle from dongle, basically address of the allocated unit */
+		alloc_handle = *((int32 *)msg);
+
+		/* add a node in the list with tuple <id, handle, size> */
+		if (alloc_handle == 0) {
+			DHD_ERROR(("Reuqested size could not be allocated\n"));
+		} else if (!(mw_li = MALLOC(dhd->osh, sizeof(*mw_li)))) {
+			DHD_ERROR(("mw list item allocation Failed\n"));
+		} else {
+			mw_li->id = dhd->mw_id++;
+			mw_li->handle = alloc_handle;
+			mw_li->size = int_arg;
+			/* append the node in the list */
+			dll_append(&dhd->mw_list_head, &mw_li->list);
+		}
+	} else if (p && end_ptr && (*end_ptr == '\0') && !strcmp(msg, "free")) {
+		/* inform dongle to free wasted chunk */
+		int handle = 0;
+		int size = 0;
+		for (item = dll_head_p(&dhd->mw_list_head);
+				!dll_end(&dhd->mw_list_head, item); item = next) {
+			next = dll_next_p(item);
+			mw_li = (dhd_dbg_mwli_t *)CONTAINEROF(item, dhd_dbg_mwli_t, list);
+
+			if (mw_li->id == (int)int_arg) {
+				handle = mw_li->handle;
+				size = mw_li->size;
+				dll_delete(item);
+				MFREE(dhd->osh, mw_li, sizeof(*mw_li));
+				if (dll_empty(dll_head_p(&dhd->mw_list_head))) {
+					/* reset the id */
+					dhd->mw_id = 0;
+				}
+			}
+		}
+		if (handle) {
+			int len;
+			/* append the free handle and the chunk size in first 8 bytes
+			 * after the command and null character
+			 */
+			*((int32 *)(p+1)) = handle;
+			*((int32 *)((p+1)+sizeof(int32))) = size;
+			/* append null as terminator */
+			*(p+1+2*sizeof(int32)) = '\0';
+			/* recalculated length -> 4 bytes for "free" + 8 bytes for hadnle and size
+			 * + 1 bytes for null caracter
+			 */
+			len = strlen(msg) + 2*sizeof(int32) + 1;
+			/* send iovar to free the chunk */
+			if (dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, msg, len, FALSE, 0) < 0) {
+				DHD_ERROR(("IOCTL failed for memdebug free\n"));
+			}
+		} else {
+			DHD_ERROR(("specified id does not exist\n"));
+		}
+	} else {
+		/* for all the wrong argument formats */
+		return BCME_BADARG;
+	}
+	return 0;
+}
+extern void
+dhd_mw_list_delete(dhd_pub_t *dhd, dll_t *list_head)
+{
+	dll_t *item;
+	dhd_dbg_mwli_t *mw_li;
+	while (!(dll_empty(list_head))) {
+		item = dll_head_p(list_head);
+		mw_li = (dhd_dbg_mwli_t *)CONTAINEROF(item, dhd_dbg_mwli_t, list);
+		dll_delete(item);
+		MFREE(dhd->osh, mw_li, sizeof(*mw_li));
+	}
+}
+#ifdef BCMPCIE
+int
+dhd_flow_ring_debug(dhd_pub_t *dhd, char *msg, uint msglen)
+{
+	flow_ring_table_t *flow_ring_table;
+	char *cmd;
+	char *end_ptr = NULL;
+	uint8 prio;
+	uint16 flowid;
+	int i;
+	int ret = 0;
+	cmd = bcmstrstr(msg, " ");
+	BCM_REFERENCE(prio);
+	if (cmd != NULL) {
+		/* in order to use string operations append null */
+		*cmd = '\0';
+	} else {
+		DHD_ERROR(("missing: create/delete args\n"));
+		return BCME_ERROR;
+	}
+	if (cmd && !strcmp(msg, "create")) {
+		/* extract <"source address", "destination address", "priority"> */
+		uint8 sa[ETHER_ADDR_LEN], da[ETHER_ADDR_LEN];
+		BCM_REFERENCE(sa);
+		BCM_REFERENCE(da);
+		msg = msg + strlen("create") + 1;
+		/* fill ethernet source address */
+		for (i = 0; i < ETHER_ADDR_LEN; i++) {
+			sa[i] = (uint8)bcm_strtoul(msg, &end_ptr, 16);
+			if (*end_ptr == ':') {
+				msg = (end_ptr + 1);
+			} else if (i != 5) {
+				DHD_ERROR(("not a valid source mac addr\n"));
+				return BCME_ERROR;
+			}
+		}
+		if (*end_ptr != ' ') {
+			DHD_ERROR(("missing: destiantion mac id\n"));
+			return BCME_ERROR;
+		} else {
+			/* skip space */
+			msg = end_ptr + 1;
+		}
+		/* fill ethernet destination address */
+		for (i = 0; i < ETHER_ADDR_LEN; i++) {
+			da[i] = (uint8)bcm_strtoul(msg, &end_ptr, 16);
+			if (*end_ptr == ':') {
+				msg = (end_ptr + 1);
+			} else if (i != 5) {
+				DHD_ERROR(("not a valid destination  mac addr\n"));
+				return BCME_ERROR;
+			}
+		}
+		if (*end_ptr != ' ') {
+			DHD_ERROR(("missing: priority\n"));
+			return BCME_ERROR;
+		} else {
+			msg = end_ptr + 1;
+		}
+		/* parse priority */
+		prio = (uint8)bcm_strtoul(msg, &end_ptr, 10);
+		if (prio > MAXPRIO) {
+			DHD_ERROR(("%s: invalid priority. Must be between 0-7 inclusive\n",
+				__FUNCTION__));
+			return BCME_ERROR;
+		}
+
+		if (*end_ptr != '\0') {
+			DHD_ERROR(("msg not truncated with NULL character\n"));
+			return BCME_ERROR;
+		}
+		ret = dhd_flowid_debug_create(dhd, 0, prio, (char *)sa, (char *)da, &flowid);
+		if (ret != BCME_OK) {
+			DHD_ERROR(("%s: flowring creation failed ret: %d\n", __FUNCTION__, ret));
+			return BCME_ERROR;
+		}
+		return BCME_OK;
+
+	} else if (cmd && !strcmp(msg, "delete")) {
+		msg = msg + strlen("delete") + 1;
+		/* parse flowid */
+		flowid = (uint16)bcm_strtoul(msg, &end_ptr, 10);
+		if (*end_ptr != '\0') {
+			DHD_ERROR(("msg not truncated with NULL character\n"));
+			return BCME_ERROR;
+		}
+
+		/* Find flowid from ifidx 0 since this IOVAR creating flowring with ifidx 0 */
+		if (dhd_flowid_find_by_ifidx(dhd, 0, flowid) != BCME_OK)
+		{
+			DHD_ERROR(("%s : Deleting not created flowid: %u\n", __FUNCTION__, flowid));
+			return BCME_ERROR;
+		}
+
+		flow_ring_table = (flow_ring_table_t *)dhd->flow_ring_table;
+		ret = dhd_bus_flow_ring_delete_request(dhd->bus, (void *)&flow_ring_table[flowid]);
+		if (ret != BCME_OK) {
+			DHD_ERROR(("%s: flowring deletion failed ret: %d\n", __FUNCTION__, ret));
+			return BCME_ERROR;
+		}
+		return BCME_OK;
+	}
+	DHD_ERROR(("%s: neither create nor delete\n", __FUNCTION__));
+	return BCME_ERROR;
+}
+#endif /* BCMPCIE */
+#endif /* DHD_DEBUG */
+
+#ifdef SYNA_SAR_CUSTOMER_PARAMETER
+
+typedef struct _dhd_sar_parameters {
+	dhd_sar_parameter  other;
+	dhd_sar_parameter  fcc;
+	dhd_sar_parameter  eu;
+	dhd_sar_parameter  latam;
+	dhd_sar_parameter  canada;
+	dhd_sar_parameter  japan;
+} dhd_sar_parameters;
+
+static dhd_sar_parameters  gSAR_params;
+
+/* pick up usable parameters */
+static sarctrl_set *dhd_sar_ctrlset_get(
+		dhd_sar_parameter *dhd_sar_param, int advance_mode)
+{
+	sarctrl_set *sarctrl = NULL;
+
+	if (dhd_sar_param == NULL) {
+		DHD_ERROR(("%s: *invalid argument, sar_param=0x%p\n",
+		           __FUNCTION__, dhd_sar_param));
+	} else switch (advance_mode) {
+		case SAR_HEAD:
+			sarctrl = &dhd_sar_param->dynamic;
+			DHD_TRACE(("%s: dynamic=0x%p, sarctrl=0x%p, ver=%d,"
+			           " sarctrl_2g=0x%X, sarctrl_2g_2=0x%X\n",
+			           __FUNCTION__, dhd_sar_param, sarctrl, sarctrl->ver,
+			           sarctrl->basic.sarctrl_2g, sarctrl->basic.sarctrl_2g_2));
+			break;
+		case SAR_GRIP:
+			sarctrl = &dhd_sar_param->grip;
+			DHD_TRACE(("%s: grip=0x%p, sarctrl=0x%p, ver=%d,"
+			           " sarctrl_2g=0x%X, sarctrl_2g_2=0x%X\n",
+			           __FUNCTION__, dhd_sar_param, sarctrl, sarctrl->ver,
+			           sarctrl->basic.sarctrl_2g, sarctrl->basic.sarctrl_2g_2));
+			break;
+		case SAR_BT:
+			sarctrl = &dhd_sar_param->bt;
+			DHD_TRACE(("%s: bt=0x%p, sarctrl=0x%p, ver=%d,"
+			           " sarctrl_2g=0x%X, sarctrl_2g_2=0x%X\n",
+			           __FUNCTION__, dhd_sar_param, sarctrl, sarctrl->ver,
+			           sarctrl->basic.sarctrl_2g, sarctrl->basic.sarctrl_2g_2));
+			break;
+		case SAR_HOTSPOT:
+			sarctrl = &dhd_sar_param->hotspot;
+			DHD_TRACE(("%s: hotspot=0x%p, sarctrl=0x%p, ver=%d,"
+			           " sarctrl_2g=0x%X, sarctrl_2g_2=0x%X\n",
+			           __FUNCTION__, dhd_sar_param, sarctrl, sarctrl->ver,
+			           sarctrl->basic.sarctrl_2g, sarctrl->basic.sarctrl_2g_2));
+			break;
+		default:
+			DHD_ERROR(("%s: *Error, invalid advance_mode=%d\n",
+			           __FUNCTION__, advance_mode));
+	}
+
+	return sarctrl;
+}
+
+int dhd_sar_init_parameter(dhd_pub_t *dhd, eCountry_flag_type type, int advance_mode,
+	char *list_str)
+{
+	char          temp_str[16];
+	sarctrl_set  *sarctrl = NULL;
+	uint32       *txpwr_list = NULL;
+	char         *next = NULL;
+	int          len = 0, idx = 0;
+
+	if (list_str == NULL) {
+		DHD_ERROR(("%s: *Error, invalid parameber\n", __FUNCTION__));
+		return BCME_BADARG;
+	} else {
+		next = list_str;
+	}
+
+	switch (type) {
+		case SYNA_COUNTRY_TYPE_FCC:
+			sarctrl = dhd_sar_ctrlset_get(&gSAR_params.fcc, advance_mode);
+			break;
+		case SYNA_COUNTRY_TYPE_EU:
+			sarctrl = dhd_sar_ctrlset_get(&gSAR_params.eu, advance_mode);
+			break;
+		case SYNA_COUNTRY_TYPE_LATAM:
+			sarctrl = dhd_sar_ctrlset_get(&gSAR_params.latam, advance_mode);
+			break;
+		case SYNA_COUNTRY_TYPE_CANADA:
+			sarctrl = dhd_sar_ctrlset_get(&gSAR_params.canada, advance_mode);
+			break;
+		case SYNA_COUNTRY_TYPE_JAPAN:
+			sarctrl = dhd_sar_ctrlset_get(&gSAR_params.japan, advance_mode);
+			break;
+		case SYNA_COUNTRY_TYPE_DEFAULT:
+			sarctrl = dhd_sar_ctrlset_get(&gSAR_params.other, advance_mode);
+			break;
+		default:
+			DHD_ERROR(("%s: *Error, invalid type=%d\n", __FUNCTION__, type));
+			return BCME_UNSUPPORTED;
+			break;
+	}
+	if (!sarctrl) {
+		DHD_ERROR(("%s: *Error, invalid advance_mode=%d\n",
+		           __FUNCTION__, advance_mode));
+		return BCME_UNSUPPORTED;
+	}
+
+	/* change dhd_sar_parameter structure to uint32 array.
+	 * use txpwr_list pointer to fill the data
+	 * one by one in following loop code
+	 */
+	txpwr_list = (uint32 *)(&sarctrl->basic);
+	idx = 0;
+	while ((len = strcspn(next, " ,")) > 0) {
+		if (len >= sizeof(temp_str)) {
+			DHD_ERROR(("%s: init '%s' before ','/' ' is too long\n",
+			           __FUNCTION__, next));
+			return BCME_ERROR;
+		}
+		strlcpy(temp_str, next, sizeof(temp_str));
+		temp_str[len] = 0;
+		txpwr_list[idx] = (uint32)simple_strtoul(temp_str, NULL, 0);
+		DHD_TRACE(("%s: get txpwr[%d]=0x%x\n",
+		           __FUNCTION__, idx, txpwr_list[idx]));
+
+		if (idx == CONST_SARCTRL_SET_QTY) {
+			DHD_ERROR(("%s: too many parameters(more than %d): '%s'\n",
+			           __FUNCTION__, idx, list_str));
+			break;
+		}
+
+		idx++;
+		next += len;
+		next += strspn(next, " ,");
+	}
+
+#ifdef VSDB
+	if (FW_SUPPORTED(dhd, 6g)) {
+		sarctrl->ver = SAR_PARAM_6G_V3_VSDB | (idx << SAR_PARAM_NUM_OFFSET);
+	} else {
+		sarctrl->ver = SAR_PARAM_V1_VSDB | (idx << SAR_PARAM_NUM_OFFSET);
+	}
+	if (CONST_SARCTRL_SINGLE_SET_QTY != idx) {
+		DHD_ERROR(("%s: *Waring, idx=%d mismatch VSDB expect=%d\n",
+		           __FUNCTION__, idx, (int)CONST_SARCTRL_SINGLE_SET_QTY));
+	}
+#else /* VSDB */
+	if (FW_SUPPORTED(dhd, 6g)) {
+		sarctrl->ver = SAR_PARAM_6G_V4_RSDB | (idx << SAR_PARAM_NUM_OFFSET);
+	} else {
+		sarctrl->ver = SAR_PARAM_V2_RSDB | (idx << SAR_PARAM_NUM_OFFSET);
+	}
+	if (CONST_SARCTRL_SET_QTY != idx) {
+		DHD_ERROR(("%s: *Waring, idx=%d mismatch RSDB expect=%d\n",
+		           __FUNCTION__, idx, (int)CONST_SARCTRL_SET_QTY));
+	}
+#endif /* VSDB */
+
+	return 0;
+}
+
+int dhd_sar_reset_parameter(void)
+{
+	bzero(&gSAR_params, sizeof(gSAR_params));
+
+	return BCME_OK;
+}
+
+int dhd_sar_set_parameter(dhd_pub_t *dhd_pub, int advance_mode)
+{
+	int                 err = BCME_OK;
+	char                iovbuf[WLC_IOCTL_SMLEN];
+	wl_country_t       *cspec = NULL;
+	sarctrl_set         sarctrl_iov = { 0 }, *sarctrl = NULL;
+	eCountry_flag_type  type = SYNA_COUNTRY_TYPE_INVALID;
+	int sar_ver = 0, sar_param_num = 0;
+
+	if (dhd_pub == NULL) {
+		DHD_ERROR(("%s: bcm_mkiovar failed.", __FUNCTION__));
+		return BCME_BADARG;
+	} else if (SAR_DISABLE == advance_mode) {
+		DHD_ERROR(("%s: SKIP since disabled.", __FUNCTION__));
+		return BCME_OK;
+	}
+
+	memset(iovbuf, 0, sizeof(iovbuf));
+	if (0 >= bcm_mkiovar("country", NULL, 0, iovbuf, sizeof(iovbuf))) {
+		err = BCME_BUFTOOSHORT;
+		DHD_ERROR(("%s: sar country mkiovar failed.", __FUNCTION__));
+		return err;
+	}
+	err = dhd_wl_ioctl_cmd(dhd_pub, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0);
+	if (err) {
+		DHD_ERROR(("%s: country code get failed\n", __FUNCTION__));
+		return err;
+	}
+	cspec = (wl_country_t *)iovbuf;
+	type = syna_country_check_type(cspec->ccode);
+	switch (type) {
+		case SYNA_COUNTRY_TYPE_FCC:
+			sarctrl = dhd_sar_ctrlset_get(&gSAR_params.fcc, advance_mode);
+			break;
+		case SYNA_COUNTRY_TYPE_EU:
+			sarctrl = dhd_sar_ctrlset_get(&gSAR_params.eu, advance_mode);
+			break;
+		case SYNA_COUNTRY_TYPE_LATAM:
+			sarctrl = dhd_sar_ctrlset_get(&gSAR_params.latam, advance_mode);
+			break;
+		case SYNA_COUNTRY_TYPE_CANADA:
+			sarctrl = dhd_sar_ctrlset_get(&gSAR_params.canada, advance_mode);
+			break;
+		case SYNA_COUNTRY_TYPE_JAPAN:
+			sarctrl = dhd_sar_ctrlset_get(&gSAR_params.japan, advance_mode);
+			break;
+		default:
+			sarctrl = dhd_sar_ctrlset_get(&gSAR_params.other, advance_mode);
+			break;
+	}
+	/* check if parameters valid */
+	if ((!sarctrl) || (!sarctrl->ver)) {
+		DHD_ERROR(("%s: *warning, try default for country='%s'(type=%d)\n",
+		           __FUNCTION__, cspec->ccode, type));
+		sarctrl = dhd_sar_ctrlset_get(&gSAR_params.other, advance_mode);
+		if ((!sarctrl) || (!sarctrl->ver)) {
+			/* stop/block setting if customer not set parameters */
+			DHD_ERROR(("%s: *skip since parameter not set\n", __FUNCTION__));
+			return BCME_UNSUPPORTED;
+		}
+	}
+	DHD_TRACE(("%s: country='%s', type=%d, advance_mode=%d\n",
+	           __FUNCTION__, cspec->ccode, type, advance_mode));
+	/* Try to get sar version from FW */
+	err = dhd_iovar(dhd_pub, 0, "sar_params", NULL, 0,
+		(char *)&sarctrl_iov, sizeof(sarctrl_iov), FALSE);
+	if (err) {
+		/* Not support sar_params read */
+	} else {
+		sar_ver = sarctrl_iov.ver & SAR_PARAM_VER_MASK;
+		sar_param_num = (sarctrl_iov.ver & SAR_PARAM_NUM_MASK) >> SAR_PARAM_NUM_OFFSET;
+	}
+
+	memset(&sarctrl_iov, 0, sizeof(sarctrl_iov));
+	if (sar_ver == SAR_PARAM_DYN) {
+		int file_sar_num = (sarctrl->ver & SAR_PARAM_NUM_MASK) >> SAR_PARAM_NUM_OFFSET;
+		if (file_sar_num  != sar_param_num) {
+			DHD_ERROR(("%s: Need confirm SAR PARAMETERS configuration based on FW\n",
+				__FUNCTION__));
+			return BCME_BADARG;
+		}
+		sarctrl_iov.ver = sar_ver | (sar_param_num << SAR_PARAM_NUM_OFFSET);
+		err = memcpy_s(sarctrl_iov.sarctrl, MAX_SAR_PARAMS_NUM * sizeof(u32),
+			sarctrl->sarctrl, file_sar_num * sizeof(u32));
+		if (err) {
+			DHD_ERROR(("%s: memcpy error num = %d\n",
+				__FUNCTION__, file_sar_num));
+			return BCME_BADARG;
+		}
+	} else {
+		/* prepare IOVAR for old version */
+		sarctrl_iov.ver   = sarctrl->ver & SAR_PARAM_VER_MASK;
+		sarctrl_iov.basic = sarctrl->basic;
+		sarctrl_iov.rsdb  = sarctrl->rsdb;
+	}
+	DHD_TRACE(("%s: sarctrl_iov=0x%p, ver=%x, sarctrl_2g=0x%X, sarctrl_2g_2=0x%X\n",
+	           __FUNCTION__, &sarctrl_iov, sarctrl_iov.ver,
+	           sarctrl_iov.basic.sarctrl_2g,
+	           sarctrl_iov.basic.sarctrl_2g_2));
+	err = dhd_iovar(dhd_pub, 0, "sar_params", (char *)&sarctrl_iov,
+		sizeof(sarctrl_iov), NULL, 0, TRUE);
+	if (unlikely(err)) {
+		DHD_ERROR(("%s: Failed to set sar_params - error (%d)\n",
+		           __FUNCTION__, err));
+	}
+
+	return err;
+}
+
+int dhd_sar_set(dhd_pub_t *dhd_pub, int sar_val)
+{
+	sar_advance_modes sar_tx_power_val = SAR_DISABLE;
+	int airplane_mode = 0;
+	int err = 0;
+
+	/* Map Android TX power modes to power mode */
+	switch (sar_val) {
+		case SAR_OFF:
+			/* SAR disabled */
+			sar_tx_power_val = SAR_DISABLE;
+			airplane_mode = 0;
+			break;
+		case HEAD_NORMAL:
+			/* HEAD mode, Normal */
+			sar_tx_power_val = SAR_HEAD;
+			airplane_mode = 0;
+			break;
+		case HEAD_AIRPLANE:
+			/* HEAD mode, Airplane */
+			sar_tx_power_val = SAR_HEAD;
+			airplane_mode = 1;
+			break;
+		case GRIP_NORMAL:
+			/* GRIP mode, Normal */
+			sar_tx_power_val = SAR_GRIP;
+			airplane_mode = 0;
+			break;
+		case GRIP_AIRPLANE:
+			/* GRIP mode, Airplane */
+			sar_tx_power_val = SAR_GRIP;
+			airplane_mode = 1;
+			break;
+		case BT_NORMAL:
+			/* BT mode, Normal */
+			sar_tx_power_val = SAR_BT;
+			airplane_mode = 0;
+			break;
+		case BT_AIRPLANE:
+			/* BT mode, Airplane */
+			sar_tx_power_val = SAR_BT;
+			airplane_mode = 1;
+			break;
+		case HOTSPOT_NORMAL:
+			/* HOTSPOT mode, Normal */
+			sar_tx_power_val = SAR_HOTSPOT;
+			airplane_mode = 0;
+			break;
+		case HOTSPOT_AIRPLANE:
+			/* HOTSPOT mode, AIRPLANE */
+			sar_tx_power_val = SAR_HOTSPOT;
+			airplane_mode = 1;
+			break;
+		default:
+			DHD_ERROR(("%s: invalid wifi tx power scenario = %d\n",
+			        __FUNCTION__, sar_tx_power_val));
+			err = -EINVAL;
+			goto exit;
+	}
+
+	if (sar_tx_power_val) {
+		err = dhd_sar_set_parameter(dhd_pub, sar_tx_power_val);
+		if (!err) {
+			/* If dhd and FW all support this feature, it will return 0
+			 * DHD already set sar parameter to FW.
+			 * so only need to set sar_enable 1 to enable SAR
+			 */
+			sar_tx_power_val = 1;
+		} else if (err == BCME_UNSUPPORTED) {
+			/* If dhd or FW not support/set these parameters
+			 * use traditional way
+			 */
+			DHD_TRACE(("DHD/FW not support sar_param,"
+					"try to use SAR parameters in nvram"));
+		} else {
+			DHD_ERROR(("%s: Failed to set sar_params - error (%d)\n",
+			           __FUNCTION__, err));
+			goto exit;
+		}
+	}
+
+	DHD_TRACE(("%s: sar_mode %d airplane_mode %d\n",
+	           __FUNCTION__, sar_tx_power_val, airplane_mode));
+	err = dhd_iovar(dhd_pub, 0, "fccpwrlimit2g", (char *)&airplane_mode,
+	                sizeof(airplane_mode), NULL, 0, TRUE);
+	if (unlikely(err)) {
+		DHD_ERROR(("%s: Failed to set airplane_mode - error (%d)\n",
+		           __FUNCTION__, err));
+		goto exit;
+	}
+	err = dhd_iovar(dhd_pub, 0, "sar_enable", (char *)&sar_tx_power_val,
+	                sizeof(sar_tx_power_val), NULL, 0, TRUE);
+	if (unlikely(err)) {
+		DHD_ERROR(("%s: Failed to set sar_enable - error (%d)\n",
+		           __FUNCTION__, err));
+		goto exit;
+	}
+
+	/* Cache the tx power mode sent by the hal */
+	dhd_pub->dhd_sar_mode = sar_val;
+	DHD_TRACE(("%s: tx_power_mode %d SUCCESS\n", __FUNCTION__, sar_val));
+
+exit:
+	return err;
+
+}
+
+#endif /* SYNA_SAR_CUSTOMER_PARAMETER */
+
+static int
+dhd_doiovar(dhd_pub_t *dhd_pub, const bcm_iovar_t *vi, uint32 actionid, const char *name,
+            void *params, int plen, void *arg, uint len, int val_size)
+{
+	int bcmerror = 0;
+	int32 int_val = 0;
+	uint32 dhd_ver_len, bus_api_rev_len;
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+	DHD_TRACE(("%s: actionid = %d; name %s\n", __FUNCTION__, actionid, name));
+
+	if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid))) != 0)
+		goto exit;
+
+	if (plen >= (int)sizeof(int_val))
+		bcopy(params, &int_val, sizeof(int_val));
+
+	switch (actionid) {
+	case IOV_GVAL(IOV_VERSION):
+		/* Need to have checked buffer length */
+		dhd_ver_len = sizeof(dhd_version) - 1;
+		bus_api_rev_len = strlen(bus_api_revision);
+		if (len > dhd_ver_len + bus_api_rev_len) {
+			bcmerror = memcpy_s((char *)arg, len, dhd_version, dhd_ver_len);
+			if (bcmerror != BCME_OK) {
+				break;
+			}
+			bcmerror = memcpy_s((char *)arg + dhd_ver_len, len - dhd_ver_len,
+				bus_api_revision, bus_api_rev_len);
+			if (bcmerror != BCME_OK) {
+				break;
+			}
+			*((char *)arg + dhd_ver_len + bus_api_rev_len) = '\0';
+		}
+		break;
+
+	case IOV_GVAL(IOV_WLMSGLEVEL):
+		printf("android_msg_level=0x%x\n", android_msg_level);
+		printf("config_msg_level=0x%x\n", config_msg_level);
+#if defined(WL_WIRELESS_EXT)
+		int_val = (int32)iw_msg_level;
+		bcopy(&int_val, arg, val_size);
+		printf("iw_msg_level=0x%x\n", iw_msg_level);
+#endif
+#ifdef WL_CFG80211
+		int_val = (int32)wl_dbg_level;
+		bcopy(&int_val, arg, val_size);
+		printf("cfg_msg_level=0x%x\n", wl_dbg_level);
+#endif
+		break;
+
+	case IOV_SVAL(IOV_WLMSGLEVEL):
+		if (int_val & DHD_ANDROID_VAL) {
+			android_msg_level = (uint)(int_val & 0xFFFF);
+			printf("android_msg_level=0x%x\n", android_msg_level);
+		}
+		if (int_val & DHD_CONFIG_VAL) {
+			config_msg_level = (uint)(int_val & 0xFFFF);
+			printf("config_msg_level=0x%x\n", config_msg_level);
+		}
+#if defined(WL_WIRELESS_EXT)
+		if (int_val & DHD_IW_VAL) {
+			iw_msg_level = (uint)(int_val & 0xFFFF);
+			printf("iw_msg_level=0x%x\n", iw_msg_level);
+		}
+#endif
+#ifdef WL_CFG80211
+		if (int_val & DHD_CFG_VAL) {
+			wl_cfg80211_enable_trace((u32)(int_val & 0xFFFF));
+		}
+#endif
+		break;
+
+	case IOV_GVAL(IOV_MSGLEVEL):
+		int_val = (int32)dhd_msg_level;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_MSGLEVEL):
+		dhd_msg_level = int_val;
+		break;
+
+#ifdef DHD_LOGLEVEL
+	case IOV_GVAL(IOV_LOGLEVEL):
+		dhd_loglevel_get((dhd_loglevel_data_t *)arg);
+		break;
+
+	case IOV_SVAL(IOV_LOGLEVEL):
+		dhd_loglevel_set((dhd_loglevel_data_t *)arg);
+		break;
+#endif /* DHD_LOGLEVEL */
+	case IOV_GVAL(IOV_BCMERRORSTR):
+		bcm_strncpy_s((char *)arg, len, bcmerrorstr(dhd_pub->bcmerror), BCME_STRLEN);
+		((char *)arg)[BCME_STRLEN - 1] = 0x00;
+		break;
+
+	case IOV_GVAL(IOV_BCMERROR):
+		int_val = (int32)dhd_pub->bcmerror;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+#ifndef BCMDBUS
+	case IOV_GVAL(IOV_WDTICK):
+		int_val = (int32)dhd_watchdog_ms;
+		bcopy(&int_val, arg, val_size);
+		break;
+#endif /* !BCMDBUS */
+
+	case IOV_SVAL(IOV_WDTICK):
+		if (!dhd_pub->up) {
+			bcmerror = BCME_NOTUP;
+			break;
+		}
+
+		dhd_watchdog_ms = (uint)int_val;
+
+		dhd_os_wd_timer(dhd_pub, (uint)int_val);
+		break;
+
+	case IOV_GVAL(IOV_DUMP):
+		if (dhd_dump(dhd_pub, arg, len) <= 0)
+			bcmerror = BCME_ERROR;
+		else
+			bcmerror = BCME_OK;
+		break;
+
+#ifndef BCMDBUS
+	case IOV_GVAL(IOV_DCONSOLE_POLL):
+		int_val = (int32)dhd_pub->dhd_console_ms;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_DCONSOLE_POLL):
+		dhd_pub->dhd_console_ms = (uint)int_val;
+		break;
+
+#if defined(DHD_DEBUG)
+	case IOV_SVAL(IOV_CONS):
+		if (len > 0) {
+#ifdef CONSOLE_DPC
+			bcmerror = dhd_bus_txcons(dhd_pub, arg, len - 1);
+#else
+			bcmerror = dhd_bus_console_in(dhd_pub, arg, len - 1);
+#endif
+		}
+		break;
+#endif /* DHD_DEBUG */
+#endif /* !BCMDBUS */
+
+	case IOV_SVAL(IOV_RESET_COUNTS):
+		dhd_pub->tx_packets = dhd_pub->rx_packets = 0;
+		dhd_pub->tx_multicast = dhd_pub->rx_multicast = 0;
+		dhd_pub->tx_bytes = dhd_pub->rx_bytes = 0;
+		dhd_pub->tx_errors = dhd_pub->rx_errors = 0;
+		dhd_pub->tx_ctlpkts = dhd_pub->rx_ctlpkts = 0;
+		dhd_pub->tx_ctlerrs = dhd_pub->rx_ctlerrs = 0;
+		dhd_pub->tx_dropped = 0;
+		dhd_pub->rx_dropped = 0;
+		dhd_pub->tx_pktgetfail = 0;
+		dhd_pub->rx_pktgetfail = 0;
+		dhd_pub->rx_readahead_cnt = 0;
+		dhd_pub->tx_realloc = 0;
+		dhd_pub->wd_dpc_sched = 0;
+		dhd_pub->tx_big_packets = 0;
+		memset(&dhd_pub->dstats, 0, sizeof(dhd_pub->dstats));
+		dhd_bus_clearcounts(dhd_pub);
+#ifdef PROP_TXSTATUS
+		/* clear proptxstatus related counters */
+		dhd_wlfc_clear_counts(dhd_pub);
+#endif /* PROP_TXSTATUS */
+#if defined(DHD_LB_STATS)
+		DHD_LB_STATS_RESET(dhd_pub);
+#endif /* DHD_LB_STATS */
+		break;
+
+#ifdef BCMPERFSTATS
+	case IOV_GVAL(IOV_LOGDUMP): {
+		bcmdumplog((char*)arg, len);
+		break;
+	}
+
+	case IOV_SVAL(IOV_LOGCAL): {
+		bcmlog("Starting OSL_DELAY (%d usecs)", (uint)int_val, 0);
+		OSL_DELAY((uint)int_val);
+		bcmlog("Finished OSL_DELAY (%d usecs)", (uint)int_val, 0);
+		break;
+	}
+
+	case IOV_SVAL(IOV_LOGSTAMP): {
+		int int_val2;
+
+		if (plen >= 2 * sizeof(int)) {
+			bcopy((char *)params + sizeof(int_val), &int_val2, sizeof(int_val2));
+			bcmlog("User message %d %d", (uint)int_val, (uint)int_val2);
+		} else if (plen >= sizeof(int)) {
+			bcmlog("User message %d", (uint)int_val, 0);
+		} else {
+			bcmlog("User message", 0, 0);
+		}
+		break;
+	}
+#endif /* BCMPERFSTATS */
+
+	case IOV_GVAL(IOV_IOCTLTIMEOUT): {
+		int_val = (int32)dhd_os_get_ioctl_resp_timeout();
+		bcopy(&int_val, arg, sizeof(int_val));
+		break;
+	}
+
+	case IOV_SVAL(IOV_IOCTLTIMEOUT): {
+		if (int_val <= 0)
+			bcmerror = BCME_BADARG;
+		else
+			dhd_os_set_ioctl_resp_timeout((unsigned int)int_val);
+		break;
+	}
+
+#ifdef PROP_TXSTATUS
+	case IOV_GVAL(IOV_PROPTXSTATUS_ENABLE): {
+		bool wlfc_enab = FALSE;
+		bcmerror = dhd_wlfc_get_enable(dhd_pub, &wlfc_enab);
+		if (bcmerror != BCME_OK)
+			goto exit;
+		int_val = wlfc_enab ? 1 : 0;
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+	case IOV_SVAL(IOV_PROPTXSTATUS_ENABLE): {
+		bool wlfc_enab = FALSE;
+		bcmerror = dhd_wlfc_get_enable(dhd_pub, &wlfc_enab);
+		if (bcmerror != BCME_OK)
+			goto exit;
+
+		/* wlfc is already set as desired */
+		if (wlfc_enab == (int_val == 0 ? FALSE : TRUE))
+			goto exit;
+
+		if (int_val == TRUE && disable_proptx) {
+			disable_proptx = 0;
+		}
+
+		if (int_val == TRUE) {
+			uint32 up;
+			bcmerror = dhd_wlfc_init(dhd_pub);
+			/* set WLC_UP to update wlfc credit */
+			if (dhd_wl_ioctl_cmd(dhd_pub, WLC_UP, &up, sizeof(uint32), TRUE, 0) < 0) {
+				DHD_ERROR(("%s: WLC_UP return err\n", __FUNCTION__));
+			}
+		} else
+			bcmerror = dhd_wlfc_deinit(dhd_pub);
+
+		break;
+	}
+	case IOV_GVAL(IOV_PROPTXSTATUS_MODE):
+		bcmerror = dhd_wlfc_get_mode(dhd_pub, &int_val);
+		if (bcmerror != BCME_OK)
+			goto exit;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_PROPTXSTATUS_MODE):
+		dhd_wlfc_set_mode(dhd_pub, int_val);
+		break;
+#ifdef QMONITOR
+	case IOV_GVAL(IOV_QMON_TIME_THRES): {
+		int_val = dhd_qmon_thres(dhd_pub, FALSE, 0);
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+
+	case IOV_SVAL(IOV_QMON_TIME_THRES): {
+		dhd_qmon_thres(dhd_pub, TRUE, int_val);
+		break;
+	}
+
+	case IOV_GVAL(IOV_QMON_TIME_PERCENT): {
+		int_val = dhd_qmon_getpercent(dhd_pub);
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+#endif /* QMONITOR */
+
+	case IOV_GVAL(IOV_PROPTXSTATUS_MODULE_IGNORE):
+		bcmerror = dhd_wlfc_get_module_ignore(dhd_pub, &int_val);
+		if (bcmerror != BCME_OK)
+			goto exit;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_PROPTXSTATUS_MODULE_IGNORE):
+		dhd_wlfc_set_module_ignore(dhd_pub, int_val);
+		break;
+
+	case IOV_GVAL(IOV_PROPTXSTATUS_CREDIT_IGNORE):
+		bcmerror = dhd_wlfc_get_credit_ignore(dhd_pub, &int_val);
+		if (bcmerror != BCME_OK)
+			goto exit;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_PROPTXSTATUS_CREDIT_IGNORE):
+		dhd_wlfc_set_credit_ignore(dhd_pub, int_val);
+		break;
+
+	case IOV_GVAL(IOV_PROPTXSTATUS_TXSTATUS_IGNORE):
+		bcmerror = dhd_wlfc_get_txstatus_ignore(dhd_pub, &int_val);
+		if (bcmerror != BCME_OK)
+			goto exit;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_PROPTXSTATUS_TXSTATUS_IGNORE):
+		dhd_wlfc_set_txstatus_ignore(dhd_pub, int_val);
+		break;
+
+	case IOV_GVAL(IOV_PROPTXSTATUS_RXPKT_CHK):
+		bcmerror = dhd_wlfc_get_rxpkt_chk(dhd_pub, &int_val);
+		if (bcmerror != BCME_OK)
+			goto exit;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_PROPTXSTATUS_RXPKT_CHK):
+		dhd_wlfc_set_rxpkt_chk(dhd_pub, int_val);
+		break;
+
+#endif /* PROP_TXSTATUS */
+
+	case IOV_GVAL(IOV_BUS_TYPE):
+		/* The dhd application queries the driver to check if its usb or sdio.  */
+#ifdef BCMDBUS
+		int_val = BUS_TYPE_USB;
+#endif
+#ifdef BCMSDIO
+		int_val = BUS_TYPE_SDIO;
+#endif
+#ifdef PCIE_FULL_DONGLE
+		int_val = BUS_TYPE_PCIE;
+#endif
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_CHANGEMTU):
+		int_val &= 0xffff;
+		bcmerror = dhd_change_mtu(dhd_pub, int_val, 0);
+		break;
+
+	case IOV_GVAL(IOV_HOSTREORDER_FLOWS):
+	{
+		uint i = 0;
+		uint8 *ptr = (uint8 *)arg;
+		uint8 count = 0;
+
+		ptr++;
+		for (i = 0; i < WLHOST_REORDERDATA_MAXFLOWS; i++) {
+			if (dhd_pub->reorder_bufs[i] != NULL) {
+				*ptr = dhd_pub->reorder_bufs[i]->flow_id;
+				ptr++;
+				count++;
+			}
+		}
+		ptr = (uint8 *)arg;
+		*ptr = count;
+		break;
+	}
+#ifdef DHDTCPACK_SUPPRESS
+	case IOV_GVAL(IOV_TCPACK_SUPPRESS): {
+		int_val = (uint32)dhd_pub->tcpack_sup_mode;
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+	case IOV_SVAL(IOV_TCPACK_SUPPRESS): {
+		bcmerror = dhd_tcpack_suppress_set(dhd_pub, (uint8)int_val);
+		break;
+	}
+#endif /* DHDTCPACK_SUPPRESS */
+#ifdef DHD_WMF
+	case IOV_GVAL(IOV_WMF_BSS_ENAB): {
+		uint32	bssidx;
+		dhd_wmf_t *wmf;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: wmf_bss_enable: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		wmf = dhd_wmf_conf(dhd_pub, bssidx);
+		int_val = wmf->wmf_enable ? 1 :0;
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+	case IOV_SVAL(IOV_WMF_BSS_ENAB): {
+		/* Enable/Disable WMF */
+		uint32	bssidx;
+		dhd_wmf_t *wmf;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: wmf_bss_enable: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		ASSERT(val);
+		bcopy(val, &int_val, sizeof(uint32));
+		wmf = dhd_wmf_conf(dhd_pub, bssidx);
+		if (wmf->wmf_enable == int_val)
+			break;
+		if (int_val) {
+			/* Enable WMF */
+			if (dhd_wmf_instance_add(dhd_pub, bssidx) != BCME_OK) {
+				DHD_ERROR(("%s: Error in creating WMF instance\n",
+				__FUNCTION__));
+				break;
+			}
+			if (dhd_wmf_start(dhd_pub, bssidx) != BCME_OK) {
+				DHD_ERROR(("%s: Failed to start WMF\n", __FUNCTION__));
+				break;
+			}
+			wmf->wmf_enable = TRUE;
+		} else {
+			/* Disable WMF */
+			wmf->wmf_enable = FALSE;
+			dhd_wmf_stop(dhd_pub, bssidx);
+			dhd_wmf_instance_del(dhd_pub, bssidx);
+		}
+		break;
+	}
+	case IOV_GVAL(IOV_WMF_UCAST_IGMP):
+		int_val = dhd_pub->wmf_ucast_igmp ? 1 : 0;
+		bcopy(&int_val, arg, val_size);
+		break;
+	case IOV_SVAL(IOV_WMF_UCAST_IGMP):
+		if (dhd_pub->wmf_ucast_igmp == int_val)
+			break;
+
+		if (int_val >= OFF && int_val <= ON)
+			dhd_pub->wmf_ucast_igmp = int_val;
+		else
+			bcmerror = BCME_RANGE;
+		break;
+	case IOV_GVAL(IOV_WMF_MCAST_DATA_SENDUP):
+		int_val = dhd_wmf_mcast_data_sendup(dhd_pub, 0, FALSE, FALSE);
+		bcopy(&int_val, arg, val_size);
+		break;
+	case IOV_SVAL(IOV_WMF_MCAST_DATA_SENDUP):
+		dhd_wmf_mcast_data_sendup(dhd_pub, 0, TRUE, int_val);
+		break;
+
+#ifdef WL_IGMP_UCQUERY
+	case IOV_GVAL(IOV_WMF_UCAST_IGMP_QUERY):
+		int_val = dhd_pub->wmf_ucast_igmp_query ? 1 : 0;
+		bcopy(&int_val, arg, val_size);
+		break;
+	case IOV_SVAL(IOV_WMF_UCAST_IGMP_QUERY):
+		if (dhd_pub->wmf_ucast_igmp_query == int_val)
+			break;
+
+		if (int_val >= OFF && int_val <= ON)
+			dhd_pub->wmf_ucast_igmp_query = int_val;
+		else
+			bcmerror = BCME_RANGE;
+		break;
+#endif /* WL_IGMP_UCQUERY */
+#ifdef DHD_UCAST_UPNP
+	case IOV_GVAL(IOV_WMF_UCAST_UPNP):
+		int_val = dhd_pub->wmf_ucast_upnp ? 1 : 0;
+		bcopy(&int_val, arg, val_size);
+		break;
+	case IOV_SVAL(IOV_WMF_UCAST_UPNP):
+		if (dhd_pub->wmf_ucast_upnp == int_val)
+			break;
+
+		if (int_val >= OFF && int_val <= ON)
+			dhd_pub->wmf_ucast_upnp = int_val;
+		else
+			bcmerror = BCME_RANGE;
+		break;
+#endif /* DHD_UCAST_UPNP */
+
+	case IOV_GVAL(IOV_WMF_PSTA_DISABLE): {
+		uint32	bssidx;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, (char *)name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: ap isoalate: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		int_val = dhd_get_wmf_psta_disable(dhd_pub, bssidx);
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+
+	case IOV_SVAL(IOV_WMF_PSTA_DISABLE): {
+		uint32	bssidx;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, (char *)name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: ap isolate: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		ASSERT(val);
+		bcopy(val, &int_val, sizeof(uint32));
+		dhd_set_wmf_psta_disable(dhd_pub, bssidx, int_val);
+		break;
+	}
+#endif /* DHD_WMF */
+
+#if defined(BCM_ROUTER_DHD)
+	case IOV_SVAL(IOV_TRAFFIC_MGMT_DWM): {
+			trf_mgmt_filter_list_t   *trf_mgmt_filter_list =
+				(trf_mgmt_filter_list_t *)(arg);
+			bcmerror = traffic_mgmt_add_dwm_filter(dhd_pub, trf_mgmt_filter_list, len);
+		}
+		break;
+#endif /* BCM_ROUTER_DHD */
+
+#ifdef DHD_L2_FILTER
+	case IOV_GVAL(IOV_DHCP_UNICAST): {
+		uint32 bssidx;
+		const char *val;
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: IOV_DHCP_UNICAST: bad parameterand name = %s\n",
+				__FUNCTION__, name));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		int_val = dhd_get_dhcp_unicast_status(dhd_pub, bssidx);
+		memcpy(arg, &int_val, val_size);
+		break;
+	}
+	case IOV_SVAL(IOV_DHCP_UNICAST): {
+		uint32	bssidx;
+		const char *val;
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: IOV_DHCP_UNICAST: bad parameterand name = %s\n",
+				__FUNCTION__, name));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		memcpy(&int_val, val, sizeof(int_val));
+		bcmerror = dhd_set_dhcp_unicast_status(dhd_pub, bssidx, int_val ? 1 : 0);
+		break;
+	}
+	case IOV_GVAL(IOV_BLOCK_PING): {
+		uint32 bssidx;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: IOV_BLOCK_PING: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		int_val = dhd_get_block_ping_status(dhd_pub, bssidx);
+		memcpy(arg, &int_val, val_size);
+		break;
+	}
+	case IOV_SVAL(IOV_BLOCK_PING): {
+		uint32	bssidx;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: IOV_BLOCK_PING: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		memcpy(&int_val, val, sizeof(int_val));
+		bcmerror = dhd_set_block_ping_status(dhd_pub, bssidx, int_val ? 1 : 0);
+		break;
+	}
+	case IOV_GVAL(IOV_PROXY_ARP): {
+		uint32	bssidx;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: IOV_PROXY_ARP: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		int_val = dhd_get_parp_status(dhd_pub, bssidx);
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+	case IOV_SVAL(IOV_PROXY_ARP): {
+		uint32	bssidx;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: IOV_PROXY_ARP: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		bcopy(val, &int_val, sizeof(int_val));
+
+		/* Issue a iovar request to WL to update the proxy arp capability bit
+		 * in the Extended Capability IE of beacons/probe responses.
+		 */
+		bcmerror = dhd_iovar(dhd_pub, bssidx, "proxy_arp_advertise", val, sizeof(int_val),
+				NULL, 0, TRUE);
+		if (bcmerror == BCME_OK) {
+			dhd_set_parp_status(dhd_pub, bssidx, int_val ? 1 : 0);
+		}
+		break;
+	}
+	case IOV_GVAL(IOV_GRAT_ARP): {
+		uint32 bssidx;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: IOV_GRAT_ARP: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		int_val = dhd_get_grat_arp_status(dhd_pub, bssidx);
+		memcpy(arg, &int_val, val_size);
+		break;
+	}
+	case IOV_SVAL(IOV_GRAT_ARP): {
+		uint32	bssidx;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: IOV_GRAT_ARP: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		memcpy(&int_val, val, sizeof(int_val));
+		bcmerror = dhd_set_grat_arp_status(dhd_pub, bssidx, int_val ? 1 : 0);
+		break;
+	}
+	case IOV_GVAL(IOV_BLOCK_TDLS): {
+		uint32 bssidx;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: IOV_BLOCK_TDLS: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		int_val = dhd_get_block_tdls_status(dhd_pub, bssidx);
+		memcpy(arg, &int_val, val_size);
+		break;
+	}
+	case IOV_SVAL(IOV_BLOCK_TDLS): {
+		uint32	bssidx;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: IOV_BLOCK_TDLS: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		memcpy(&int_val, val, sizeof(int_val));
+		bcmerror = dhd_set_block_tdls_status(dhd_pub, bssidx, int_val ? 1 : 0);
+		break;
+	}
+#endif /* DHD_L2_FILTER */
+	case IOV_SVAL(IOV_DHD_IE): {
+		uint32	bssidx;
+		const char *val;
+#if (defined(BCM_ROUTER_DHD) && defined(QOS_MAP_SET))
+		uint8 ie_type;
+		bcm_tlv_t *qos_map_ie = NULL;
+		ie_setbuf_t *ie_getbufp = (ie_setbuf_t *)(arg+4);
+		ie_type = ie_getbufp->ie_buffer.ie_list[0].ie_data.id;
+#endif /* BCM_ROUTER_DHD && QOS_MAP_SET */
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: dhd ie: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+#if (defined(BCM_ROUTER_DHD) && defined(QOS_MAP_SET))
+		qos_map_ie = (bcm_tlv_t *)(&(ie_getbufp->ie_buffer.ie_list[0].ie_data));
+		if (qos_map_ie != NULL && (ie_type == DOT11_MNG_QOS_MAP_ID)) {
+				bcmerror = dhd_set_qosmap_up_table(dhd_pub, bssidx, qos_map_ie);
+		}
+#endif /* BCM_ROUTER_DHD && QOS_MAP_SET */
+		break;
+	}
+	case IOV_GVAL(IOV_AP_ISOLATE): {
+		uint32	bssidx;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: ap isoalate: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		int_val = dhd_get_ap_isolate(dhd_pub, bssidx);
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+	case IOV_SVAL(IOV_AP_ISOLATE): {
+		uint32	bssidx;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: ap isolate: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		ASSERT(val);
+		bcopy(val, &int_val, sizeof(uint32));
+		dhd_set_ap_isolate(dhd_pub, bssidx, int_val);
+		break;
+	}
+#ifdef DHD_PSTA
+	case IOV_GVAL(IOV_PSTA): {
+		int_val = dhd_get_psta_mode(dhd_pub);
+		bcopy(&int_val, arg, val_size);
+		break;
+		}
+	case IOV_SVAL(IOV_PSTA): {
+		if (int_val >= DHD_MODE_PSTA_DISABLED && int_val <= DHD_MODE_PSR) {
+			dhd_set_psta_mode(dhd_pub, int_val);
+		} else {
+			bcmerror = BCME_RANGE;
+		}
+		break;
+		}
+#endif /* DHD_PSTA */
+#ifdef DHD_WET
+	case IOV_GVAL(IOV_WET):
+		 int_val = dhd_get_wet_mode(dhd_pub);
+		 bcopy(&int_val, arg, val_size);
+		 break;
+
+	case IOV_SVAL(IOV_WET):
+		 if (int_val == 0 || int_val == 1) {
+			 dhd_set_wet_mode(dhd_pub, int_val);
+			 /* Delete the WET DB when disabled */
+			 if (!int_val) {
+				 dhd_wet_sta_delete_list(dhd_pub);
+			 }
+		 } else {
+			 bcmerror = BCME_RANGE;
+		 }
+				 break;
+	case IOV_SVAL(IOV_WET_HOST_IPV4):
+			dhd_set_wet_host_ipv4(dhd_pub, params, plen);
+			break;
+	case IOV_SVAL(IOV_WET_HOST_MAC):
+			dhd_set_wet_host_mac(dhd_pub, params, plen);
+		break;
+#endif /* DHD_WET */
+#ifdef DHD_MCAST_REGEN
+	case IOV_GVAL(IOV_MCAST_REGEN_BSS_ENABLE): {
+		uint32	bssidx;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, (char *)name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: mcast_regen_bss_enable: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		int_val = dhd_get_mcast_regen_bss_enable(dhd_pub, bssidx);
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+
+	case IOV_SVAL(IOV_MCAST_REGEN_BSS_ENABLE): {
+		uint32	bssidx;
+		const char *val;
+
+		if (dhd_iovar_parse_bssidx(dhd_pub, (char *)name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: mcast_regen_bss_enable: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		ASSERT(val);
+		bcopy(val, &int_val, sizeof(uint32));
+		dhd_set_mcast_regen_bss_enable(dhd_pub, bssidx, int_val);
+		break;
+	}
+#endif /* DHD_MCAST_REGEN */
+
+	case IOV_GVAL(IOV_CFG80211_OPMODE): {
+		int_val = (int32)dhd_pub->op_mode;
+		bcopy(&int_val, arg, sizeof(int_val));
+		break;
+		}
+	case IOV_SVAL(IOV_CFG80211_OPMODE): {
+		if (int_val <= 0)
+			bcmerror = BCME_BADARG;
+		else
+			dhd_pub->op_mode = int_val;
+		break;
+	}
+
+	case IOV_GVAL(IOV_ASSERT_TYPE):
+		int_val = g_assert_type;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_SVAL(IOV_ASSERT_TYPE):
+		g_assert_type = (uint32)int_val;
+		break;
+
+#if defined(NDIS)
+	case IOV_GVAL(IOV_WAKEIND):
+		dhd_os_wakeind(dhd_pub, &int_val);
+		bcopy(&int_val, arg, val_size);
+		break;
+#endif /* NDIS */
+
+#if !defined(NDIS) && !defined(BCM_ROUTER_DHD)
+	case IOV_GVAL(IOV_LMTEST): {
+		*(uint32 *)arg = (uint32)lmtest;
+		break;
+	}
+
+	case IOV_SVAL(IOV_LMTEST): {
+		uint32 val = *(uint32 *)arg;
+		if (val > 50)
+			bcmerror = BCME_BADARG;
+		else {
+			lmtest = (uint)val;
+			DHD_ERROR(("%s: lmtest %s\n",
+				__FUNCTION__, (lmtest == FALSE)? "OFF" : "ON"));
+		}
+		break;
+	}
+#endif /* !NDIS && !BCM_ROUTER_DHD */
+#if defined(DHD_MACDBG) && defined(BCMDBG)
+	case IOV_GVAL(IOV_MACDBG_PD11REGS):
+		bcmerror = dhd_macdbg_pd11regs(dhd_pub, params, plen, arg, len);
+		break;
+	case IOV_GVAL(IOV_MACDBG_REGLIST):
+		bcmerror = dhd_macdbg_reglist(dhd_pub, arg, len);
+		break;
+	case IOV_GVAL(IOV_MACDBG_PSVMPMEMS):
+		bcmerror = dhd_macdbg_psvmpmems(dhd_pub, params, plen, arg, len);
+		break;
+#endif /* defined(DHD_MACDBG) && defined(BCMDBG) */
+
+#ifdef SHOW_LOGTRACE
+	case IOV_GVAL(IOV_DUMP_TRACE_LOG): {
+		trace_buf_info_t *trace_buf_info = (trace_buf_info_t *)arg;
+		dhd_dbg_ring_t *dbg_verbose_ring = NULL;
+
+		dbg_verbose_ring = dhd_dbg_get_ring_from_ring_id(dhd_pub, FW_VERBOSE_RING_ID);
+		if (dbg_verbose_ring == NULL) {
+			DHD_ERROR(("dbg_verbose_ring is NULL\n"));
+			bcmerror = BCME_UNSUPPORTED;
+			break;
+		}
+
+		if (trace_buf_info != NULL) {
+			bzero(trace_buf_info, sizeof(trace_buf_info_t));
+			dhd_dbg_read_ring_into_trace_buf(dbg_verbose_ring, trace_buf_info);
+		} else {
+			DHD_ERROR(("%s: arg is NULL\n", __FUNCTION__));
+			bcmerror = BCME_NOMEM;
+		}
+		break;
+	}
+#endif /* SHOW_LOGTRACE */
+#ifdef REPORT_FATAL_TIMEOUTS
+	case IOV_GVAL(IOV_SCAN_TO): {
+		dhd_get_scan_to_val(dhd_pub, (uint32 *)&int_val);
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+	case IOV_SVAL(IOV_SCAN_TO): {
+		dhd_set_scan_to_val(dhd_pub, (uint32)int_val);
+		break;
+	}
+	case IOV_GVAL(IOV_JOIN_TO): {
+		dhd_get_join_to_val(dhd_pub, (uint32 *)&int_val);
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+	case IOV_SVAL(IOV_JOIN_TO): {
+		dhd_set_join_to_val(dhd_pub, (uint32)int_val);
+		break;
+	}
+	case IOV_GVAL(IOV_CMD_TO): {
+		dhd_get_cmd_to_val(dhd_pub, (uint32 *)&int_val);
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+	case IOV_SVAL(IOV_CMD_TO): {
+		dhd_set_cmd_to_val(dhd_pub, (uint32)int_val);
+		break;
+	}
+	case IOV_GVAL(IOV_OQS_TO): {
+		dhd_get_bus_to_val(dhd_pub, (uint32 *)&int_val);
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+	case IOV_SVAL(IOV_OQS_TO): {
+		dhd_set_bus_to_val(dhd_pub, (uint32)int_val);
+		break;
+	}
+#endif /* REPORT_FATAL_TIMEOUTS */
+	case IOV_GVAL(IOV_DONGLE_TRAP_TYPE):
+		if (dhd_pub->dongle_trap_occured)
+			int_val = ltoh32(dhd_pub->last_trap_info.type);
+		else
+			int_val = 0;
+		bcopy(&int_val, arg, val_size);
+		break;
+
+	case IOV_GVAL(IOV_DONGLE_TRAP_INFO):
+	{
+		struct bcmstrbuf strbuf;
+		bcm_binit(&strbuf, arg, len);
+		if (dhd_pub->dongle_trap_occured == FALSE) {
+			bcm_bprintf(&strbuf, "no trap recorded\n");
+			break;
+		}
+#ifndef BCMDBUS
+		dhd_bus_dump_trap_info(dhd_pub->bus, &strbuf);
+#endif /* BCMDBUS */
+		break;
+	}
+#ifdef DHD_DEBUG
+#if defined(BCMSDIO) || defined(BCMPCIE)
+
+	case IOV_GVAL(IOV_BPADDR):
+		{
+			sdreg_t sdreg;
+			uint32 addr, size;
+
+			memcpy(&sdreg, params, sizeof(sdreg));
+
+			addr = sdreg.offset;
+			size = sdreg.func;
+
+			bcmerror = dhd_bus_readwrite_bp_addr(dhd_pub, addr, size,
+				(uint *)&int_val, TRUE);
+
+			memcpy(arg, &int_val, sizeof(int32));
+
+			break;
+		}
+
+	case IOV_SVAL(IOV_BPADDR):
+		{
+			sdreg_t sdreg;
+			uint32 addr, size;
+
+			memcpy(&sdreg, params, sizeof(sdreg));
+
+			addr = sdreg.offset;
+			size = sdreg.func;
+
+			bcmerror = dhd_bus_readwrite_bp_addr(dhd_pub, addr, size,
+				(uint *)&sdreg.value,
+				FALSE);
+
+			break;
+		}
+#endif /* BCMSDIO || BCMPCIE */
+#ifdef BCMPCIE
+	case IOV_SVAL(IOV_FLOW_RING_DEBUG):
+		{
+			bcmerror = dhd_flow_ring_debug(dhd_pub, arg, len);
+			break;
+		}
+#endif /* BCMPCIE */
+	case IOV_SVAL(IOV_MEM_DEBUG):
+		if (len > 0) {
+			bcmerror = dhd_mem_debug(dhd_pub, arg, len - 1);
+		}
+		break;
+#endif /* DHD_DEBUG */
+#if defined(DHD_LOG_DUMP)
+	case IOV_GVAL(IOV_LOG_DUMP):
+		{
+			dhd_prot_debug_info_print(dhd_pub);
+			dhd_log_dump_trigger(dhd_pub, CMD_DEFAULT);
+			break;
+		}
+#endif /* DHD_LOG_DUMP */
+
+	case IOV_GVAL(IOV_TPUT_TEST):
+		{
+			tput_test_t *tput_data = NULL;
+			if (params && plen >= sizeof(tput_test_t)) {
+				tput_data = (tput_test_t *)params;
+				bcmerror = dhd_tput_test(dhd_pub, tput_data);
+			} else {
+				DHD_ERROR(("%s: tput test - no input params ! \n", __FUNCTION__));
+				bcmerror = BCME_BADARG;
+			}
+			break;
+		}
+	case IOV_GVAL(IOV_DEBUG_BUF_DEST_STAT):
+		{
+			if (dhd_pub->debug_buf_dest_support) {
+				debug_buf_dest_stat_t *debug_buf_dest_stat =
+					(debug_buf_dest_stat_t *)arg;
+				memcpy(debug_buf_dest_stat, dhd_pub->debug_buf_dest_stat,
+					sizeof(dhd_pub->debug_buf_dest_stat));
+			} else {
+				bcmerror = BCME_DISABLED;
+			}
+			break;
+		}
+
+#if defined(DHD_SSSR_DUMP)
+	case IOV_GVAL(IOV_FIS_TRIGGER):
+		bcmerror = dhd_bus_fis_trigger(dhd_pub);
+
+		if (bcmerror == BCME_OK) {
+			bcmerror = dhd_bus_fis_dump(dhd_pub);
+		}
+
+		int_val = bcmerror;
+		bcopy(&int_val, arg, val_size);
+		break;
+#endif /* defined(DHD_SSSR_DUMP) */
+
+#ifdef DHD_DEBUG
+	case IOV_SVAL(IOV_INDUCE_ERROR): {
+		if (int_val >= DHD_INDUCE_ERROR_MAX) {
+			DHD_ERROR(("%s: Invalid command : %u\n", __FUNCTION__, (uint16)int_val));
+		} else {
+			dhd_pub->dhd_induce_error = (uint16)int_val;
+#ifdef BCMPCIE
+			if (dhd_pub->dhd_induce_error == DHD_INDUCE_BH_CBP_HANG) {
+				dhdpcie_induce_cbp_hang(dhd_pub);
+			}
+			if (dhd_pub->dhd_induce_error == DHD_INDUCE_PCIE_LINK_DOWN) {
+				dhd_bus_set_linkdown(dhd_pub, TRUE);
+#ifdef OEM_ANDROID
+				dhd_pub->hang_reason = HANG_REASON_PCIE_LINK_DOWN_EP_DETECT;
+				dhd_os_send_hang_message(dhd_pub);
+#endif /* OEM_ANDROID */
+			}
+#endif /* BCMPCIE */
+		}
+		break;
+	}
+#endif /* DHD_DEBUG */
+#ifdef WL_IFACE_MGMT_CONF
+#ifdef WL_CFG80211
+#ifdef WL_NANP2P
+	case IOV_GVAL(IOV_CONC_DISC): {
+		int_val = wl_cfg80211_get_iface_conc_disc(
+			dhd_linux_get_primary_netdev(dhd_pub));
+		bcopy(&int_val, arg, sizeof(int_val));
+		break;
+	}
+	case IOV_SVAL(IOV_CONC_DISC): {
+		bcmerror = wl_cfg80211_set_iface_conc_disc(
+			dhd_linux_get_primary_netdev(dhd_pub), (uint8)int_val);
+		break;
+	}
+#endif /* WL_NANP2P */
+#ifdef WL_IFACE_MGMT
+	case IOV_GVAL(IOV_IFACE_POLICY): {
+		int_val = wl_cfg80211_get_iface_policy(
+		dhd_linux_get_primary_netdev(dhd_pub));
+		bcopy(&int_val, arg, sizeof(int_val));
+		break;
+	}
+	case IOV_SVAL(IOV_IFACE_POLICY): {
+		bcmerror = wl_cfg80211_set_iface_policy(
+			dhd_linux_get_primary_netdev(dhd_pub),
+			arg, len);
+		break;
+	}
+#endif /* WL_IFACE_MGMT */
+#endif /* WL_CFG80211 */
+#endif /* WL_IFACE_MGMT_CONF */
+#ifdef RTT_GEOFENCE_CONT
+#if defined(RTT_SUPPORT) && defined(WL_NAN)
+	case IOV_GVAL(IOV_RTT_GEOFENCE_TYPE_OVRD): {
+		bool enable = 0;
+		dhd_rtt_get_geofence_cont_ind(dhd_pub, &enable);
+		int_val = enable ? 1 : 0;
+		bcopy(&int_val, arg, val_size);
+		break;
+	}
+	case IOV_SVAL(IOV_RTT_GEOFENCE_TYPE_OVRD): {
+		bool enable = *(bool *)arg;
+		dhd_rtt_set_geofence_cont_ind(dhd_pub, enable);
+		break;
+	}
+#endif /* RTT_SUPPORT && WL_NAN */
+#endif /* RTT_GEOFENCE_CONT */
+	case IOV_GVAL(IOV_FW_VBS): {
+		*(uint32 *)arg = (uint32)dhd_dbg_get_fwverbose(dhd_pub);
+		break;
+	}
+
+	case IOV_SVAL(IOV_FW_VBS): {
+		if (int_val < 0) {
+			int_val = 0;
+		}
+		dhd_dbg_set_fwverbose(dhd_pub, (uint32)int_val);
+		break;
+	}
+
+#ifdef DHD_TX_PROFILE
+	case IOV_SVAL(IOV_TX_PROFILE_TAG):
+	{
+		/* note: under the current implementation only one type of packet may be
+		 * tagged per profile
+		 */
+		const dhd_tx_profile_protocol_t *protocol = NULL;
+		/* for example, we might have a profile of profile_index 6, but at
+		 * offset 2 from dhd_pub->protocol_filters.
+		 */
+		uint8 offset;
+
+		if (params == NULL) {
+			bcmerror = BCME_ERROR;
+			break;
+		}
+
+		protocol = (dhd_tx_profile_protocol_t *)params;
+
+		/* validate */
+		if (protocol->version != DHD_TX_PROFILE_VERSION) {
+			bcmerror = BCME_VERSION;
+			break;
+		}
+		if (protocol->profile_index > DHD_MAX_PROFILE_INDEX) {
+			DHD_ERROR(("%s:\tprofile index must be between 0 and %d\n",
+					__FUNCTION__, DHD_MAX_PROFILE_INDEX));
+			bcmerror = BCME_RANGE;
+			break;
+		}
+		if (protocol->layer != DHD_TX_PROFILE_DATA_LINK_LAYER && protocol->layer
+				!= DHD_TX_PROFILE_NETWORK_LAYER) {
+			DHD_ERROR(("%s:\tlayer must be %d or %d\n", __FUNCTION__,
+					DHD_TX_PROFILE_DATA_LINK_LAYER,
+					DHD_TX_PROFILE_NETWORK_LAYER));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		if (protocol->protocol_number > __UINT16_MAX__) {
+			DHD_ERROR(("%s:\tprotocol number must be <= %d\n", __FUNCTION__,
+					__UINT16_MAX__));
+			bcmerror = BCME_BADLEN;
+			break;
+		}
+
+		/* find the dhd_tx_profile_protocol_t */
+		for (offset = 0; offset < dhd_pub->num_profiles; offset++) {
+			if (dhd_pub->protocol_filters[offset].profile_index ==
+					protocol->profile_index) {
+				break;
+			}
+		}
+
+		if (offset >= DHD_MAX_PROFILES) {
+#if DHD_MAX_PROFILES > 1
+			DHD_ERROR(("%s:\tonly %d profiles supported at present\n",
+					__FUNCTION__, DHD_MAX_PROFILES));
+#else /* DHD_MAX_PROFILES > 1 */
+			DHD_ERROR(("%s:\tonly %d profile supported at present\n",
+					__FUNCTION__, DHD_MAX_PROFILES));
+			DHD_ERROR(("%s:\tthere is a profile of index %d\n", __FUNCTION__,
+					dhd_pub->protocol_filters->profile_index));
+#endif /* DHD_MAX_PROFILES > 1 */
+			bcmerror = BCME_NOMEM;
+			break;
+		}
+
+		/* memory already allocated in dhd_attach; just assign the value */
+		dhd_pub->protocol_filters[offset] = *protocol;
+
+		if (offset >= dhd_pub->num_profiles) {
+			dhd_pub->num_profiles = offset + 1;
+		}
+
+		break;
+	}
+
+	case IOV_SVAL(IOV_TX_PROFILE_ENABLE):
+		dhd_pub->tx_profile_enab = int_val ? TRUE : FALSE;
+		break;
+
+	case IOV_GVAL(IOV_TX_PROFILE_ENABLE):
+		int_val = dhd_pub->tx_profile_enab;
+		bcmerror = memcpy_s(arg, val_size, &int_val, sizeof(int_val));
+		break;
+
+	case IOV_SVAL(IOV_TX_PROFILE_DUMP):
+	{
+		const dhd_tx_profile_protocol_t *protocol = NULL;
+		uint8 offset;
+
+		for (offset = 0; offset < dhd_pub->num_profiles; offset++) {
+			if (dhd_pub->protocol_filters[offset].profile_index == int_val) {
+				protocol = &(dhd_pub->protocol_filters[offset]);
+				break;
+			}
+		}
+
+		if (protocol == NULL) {
+			DHD_ERROR(("%s:\tno profile with index %d\n", __FUNCTION__,
+					int_val));
+			bcmerror = BCME_ERROR;
+			break;
+		}
+
+		DHD_CONS_ONLY(("%s:\ttx_profile %s: %d\n", __FUNCTION__,
+			"profile_index", protocol->profile_index));
+		DHD_CONS_ONLY(("%s:\ttx_profile %s: %d\n", __FUNCTION__,
+			"layer", protocol->layer));
+		DHD_CONS_ONLY(("%s:\ttx_profile %s: %d\n", __FUNCTION__,
+			"protocol_number", protocol->protocol_number));
+		DHD_CONS_ONLY(("%s:\ttx_profile %s: %d\n", __FUNCTION__,
+			"src_port", protocol->src_port));
+		DHD_CONS_ONLY(("%s:\ttx_profile %s: %d\n", __FUNCTION__,
+			"dest_port", protocol->dest_port));
+
+		break;
+	}
+#endif /* defined(DHD_TX_PROFILE) */
+
+	case IOV_GVAL(IOV_CHECK_TRAP_ROT): {
+		int_val = dhd_pub->check_trap_rot? 1 : 0;
+		(void)memcpy_s(arg, val_size, &int_val, sizeof(int_val));
+		break;
+	}
+	case IOV_SVAL(IOV_CHECK_TRAP_ROT): {
+		dhd_pub->check_trap_rot = *(bool *)arg;
+		break;
+	}
+
+	case IOV_GVAL(IOV_COUNTERS):
+		if (dhd_counters(dhd_pub, arg, len) <= 0)
+			bcmerror = BCME_ERROR;
+		else
+			bcmerror = BCME_OK;
+		break;
+#ifdef BCMPCIE
+	case IOV_GVAL(IOV_DUMP_FLOWRINGS):
+		if (dhd_dump_flowrings(dhd_pub, arg, len) <= 0)
+			bcmerror = BCME_ERROR;
+		else
+			bcmerror = BCME_OK;
+		break;
+#endif /* BCMPCIE */
+#ifdef SYNA_SAR_CUSTOMER_PARAMETER
+	case IOV_GVAL(IOV_SAR_MODE):
+		int_val = dhd_pub->dhd_sar_mode;
+		(void)memcpy_s(arg, val_size, &int_val, sizeof(int_val));
+		break;
+	case IOV_SVAL(IOV_SAR_MODE):
+		dhd_sar_set(dhd_pub, int_val);
+		break;
+#endif /* SYNA_SAR_CUSTOMER_PARAMETER */
+
+#ifdef CSI_SUPPORT
+	case IOV_GVAL(IOV_CSI_VERSION):
+		bcmerror = dhd_csi_version(dhd_pub, arg, val_size, FALSE);
+		break;
+	case IOV_GVAL(IOV_CSI_CONFIG):
+		bcmerror = dhd_csi_config(dhd_pub, arg, val_size, FALSE);
+		break;
+	case IOV_SVAL(IOV_CSI_CONFIG):
+		bcmerror = dhd_csi_config(dhd_pub, arg, val_size, TRUE);
+		break;
+#endif /* CSI_SUPPORT */
+
+#if defined(EXT_REGD_INFO) && defined(WL_SELF_MANAGED_REGDOM)
+	case IOV_GVAL(IOV_REGULATORY_DUMP):
+	case IOV_SVAL(IOV_REGULATORY_DUMP):
+		bcmerror = wl_cfg80211_reg_dump_all("user check");
+		break;
+#endif /* defined(EXT_REGD_INFO) && defined(WL_SELF_MANAGED_REGDOM) */
+#ifdef WLEASYMESH
+	case IOV_SVAL(IOV_1905_AL_UCAST): {
+		uint32  bssidx;
+		const char *val;
+		uint8 ea[6] = {0};
+		if (dhd_iovar_parse_bssidx(dhd_pub, (char *)name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: 1905_al_ucast: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		bcopy(val, ea, ETHER_ADDR_LEN);
+		printf("IOV_1905_AL_UCAST:" MACDBG "\n", MAC2STRDBG(ea));
+		bcmerror = dhd_set_1905_almac(dhd_pub, bssidx, ea, FALSE);
+		break;
+	}
+	case IOV_GVAL(IOV_1905_AL_UCAST): {
+		uint32  bssidx;
+		const char *val;
+		if (dhd_iovar_parse_bssidx(dhd_pub, (char *)name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: 1905_al_ucast: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		bcmerror = dhd_get_1905_almac(dhd_pub, bssidx, arg, FALSE);
+		break;
+	}
+	case IOV_SVAL(IOV_1905_AL_MCAST): {
+		uint32  bssidx;
+		const char *val;
+		uint8 ea[6] = {0};
+		if (dhd_iovar_parse_bssidx(dhd_pub, (char *)name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: 1905_al_mcast: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+		bcopy(val, ea, ETHER_ADDR_LEN);
+		printf("IOV_1905_AL_MCAST:" MACDBG "\n", MAC2STRDBG(ea));
+		bcmerror = dhd_set_1905_almac(dhd_pub, bssidx, ea, TRUE);
+		break;
+	}
+	case IOV_GVAL(IOV_1905_AL_MCAST): {
+		uint32  bssidx;
+		const char *val;
+		if (dhd_iovar_parse_bssidx(dhd_pub, (char *)name, &bssidx, &val) != BCME_OK) {
+			DHD_ERROR(("%s: 1905_al_mcast: bad parameter\n", __FUNCTION__));
+			bcmerror = BCME_BADARG;
+			break;
+		}
+
+		bcmerror = dhd_get_1905_almac(dhd_pub, bssidx, arg, TRUE);
+		break;
+	}
+#endif /* WLEASYMESH */
+
+	default:
+		bcmerror = BCME_UNSUPPORTED;
+		break;
+	}
+
+exit:
+	DHD_TRACE(("%s: actionid %d, bcmerror %d\n", __FUNCTION__, actionid, bcmerror));
+	return bcmerror;
+}
+
+#ifdef BCMDONGLEHOST
+/* Store the status of a connection attempt for later retrieval by an iovar */
+void
+dhd_store_conn_status(uint32 event, uint32 status, uint32 reason)
+{
+	/* Do not overwrite a WLC_E_PRUNE with a WLC_E_SET_SSID
+	 * because an encryption/rsn mismatch results in both events, and
+	 * the important information is in the WLC_E_PRUNE.
+	 */
+	if (!(event == WLC_E_SET_SSID && status == WLC_E_STATUS_FAIL &&
+	      dhd_conn_event == WLC_E_PRUNE)) {
+		dhd_conn_event = event;
+		dhd_conn_status = status;
+		dhd_conn_reason = reason;
+	}
+}
+#else
+#error "BCMDONGLEHOST not defined"
+#endif /* BCMDONGLEHOST */
+
+bool
+dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec)
+{
+	void *p;
+	int eprec = -1;		/* precedence to evict from */
+	bool discard_oldest;
+
+	/* Fast case, precedence queue is not full and we are also not
+	 * exceeding total queue length
+	 */
+	if (!pktqprec_full(q, prec) && !pktq_full(q)) {
+		pktq_penq(q, prec, pkt);
+		return TRUE;
+	}
+
+	/* Determine precedence from which to evict packet, if any */
+	if (pktqprec_full(q, prec))
+		eprec = prec;
+	else if (pktq_full(q)) {
+		p = pktq_peek_tail(q, &eprec);
+		ASSERT(p);
+		if (eprec > prec || eprec < 0)
+			return FALSE;
+	}
+
+	/* Evict if needed */
+	if (eprec >= 0) {
+		/* Detect queueing to unconfigured precedence */
+		ASSERT(!pktqprec_empty(q, eprec));
+		discard_oldest = AC_BITMAP_TST(dhdp->wme_dp, eprec);
+		if (eprec == prec && !discard_oldest)
+			return FALSE;		/* refuse newer (incoming) packet */
+		/* Evict packet according to discard policy */
+		p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q, eprec);
+		ASSERT(p);
+#ifdef DHDTCPACK_SUPPRESS
+		if (dhd_tcpack_check_xmit(dhdp, p) == BCME_ERROR) {
+			DHD_ERROR(("%s %d: tcpack_suppress ERROR!!! Stop using it\n",
+				__FUNCTION__, __LINE__));
+			dhd_tcpack_suppress_set(dhdp, TCPACK_SUP_OFF);
+		}
+#endif /* DHDTCPACK_SUPPRESS */
+		PKTFREE(dhdp->osh, p, TRUE);
+	}
+
+	/* Enqueue */
+	p = pktq_penq(q, prec, pkt);
+	ASSERT(p);
+
+	return TRUE;
+}
+
+/*
+ * Functions to drop proper pkts from queue:
+ *	If one pkt in queue is non-fragmented, drop first non-fragmented pkt only
+ *	If all pkts in queue are all fragmented, find and drop one whole set fragmented pkts
+ *	If can't find pkts matching upper 2 cases, drop first pkt anyway
+ */
+bool
+dhd_prec_drop_pkts(dhd_pub_t *dhdp, struct pktq *pq, int prec, f_droppkt_t fn)
+{
+	struct pktq_prec *q = NULL;
+	void *p, *prev = NULL, *next = NULL, *first = NULL, *last = NULL, *prev_first = NULL;
+	pkt_frag_t frag_info;
+
+	ASSERT(dhdp && pq);
+	ASSERT(prec >= 0 && prec < pq->num_prec);
+
+	q = &pq->q[prec];
+	p = q->head;
+
+	if (p == NULL)
+		return FALSE;
+
+	while (p) {
+		frag_info = pkt_frag_info(dhdp->osh, p);
+		if (frag_info == DHD_PKT_FRAG_NONE) {
+			break;
+		} else if (frag_info == DHD_PKT_FRAG_FIRST) {
+			if (first) {
+				/* No last frag pkt, use prev as last */
+				last = prev;
+				break;
+			} else {
+				first = p;
+				prev_first = prev;
+			}
+		} else if (frag_info == DHD_PKT_FRAG_LAST) {
+			if (first) {
+				last = p;
+				break;
+			}
+		}
+
+		prev = p;
+		p = PKTLINK(p);
+	}
+
+	if ((p == NULL) || ((frag_info != DHD_PKT_FRAG_NONE) && !(first && last))) {
+		/* Not found matching pkts, use oldest */
+		prev = NULL;
+		p = q->head;
+		frag_info = 0;
+	}
+
+	if (frag_info == DHD_PKT_FRAG_NONE) {
+		first = last = p;
+		prev_first = prev;
+	}
+
+	p = first;
+	while (p) {
+		next = PKTLINK(p);
+		q->n_pkts--;
+		pq->n_pkts_tot--;
+
+#ifdef WL_TXQ_STALL
+		q->dequeue_count++;
+#endif
+
+		PKTSETLINK(p, NULL);
+
+		if (fn)
+			fn(dhdp, prec, p, TRUE);
+
+		if (p == last)
+			break;
+
+		p = next;
+	}
+
+	if (prev_first == NULL) {
+		if ((q->head = next) == NULL)
+			q->tail = NULL;
+	} else {
+		PKTSETLINK(prev_first, next);
+		if (!next)
+			q->tail = prev_first;
+	}
+
+	return TRUE;
+}
+
+static int
+dhd_iovar_op(dhd_pub_t *dhd_pub, const char *name,
+	void *params, int plen, void *arg, uint len, bool set)
+{
+	int bcmerror = 0;
+	uint val_size;
+	const bcm_iovar_t *vi = NULL;
+	uint32 actionid;
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+	ASSERT(name);
+
+	/* Get MUST have return space */
+	ASSERT(set || (arg && len));
+
+	/* Set does NOT take qualifiers */
+	ASSERT(!set || (!params && !plen));
+
+	if ((vi = bcm_iovar_lookup(dhd_iovars, name)) == NULL) {
+		bcmerror = BCME_UNSUPPORTED;
+		goto exit;
+	}
+
+	DHD_CTL(("%s: %s %s, len %d plen %d\n", __FUNCTION__,
+		name, (set ? "set" : "get"), len, plen));
+
+	/* set up 'params' pointer in case this is a set command so that
+	 * the convenience int and bool code can be common to set and get
+	 */
+	if (params == NULL) {
+		params = arg;
+		plen = len;
+	}
+
+	if (vi->type == IOVT_VOID)
+		val_size = 0;
+	else if (vi->type == IOVT_BUFFER)
+		val_size = len;
+	else
+		/* all other types are integer sized */
+		val_size = sizeof(int);
+
+	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
+
+	bcmerror = dhd_doiovar(dhd_pub, vi, actionid, name, params, plen, arg, len, val_size);
+
+exit:
+	return bcmerror;
+}
+
+int
+dhd_ioctl(dhd_pub_t * dhd_pub, dhd_ioctl_t *ioc, void *buf, uint buflen)
+{
+	int bcmerror = 0;
+	unsigned long flags;
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+	if (!buf) {
+		return BCME_BADARG;
+	}
+
+	dhd_os_dhdiovar_lock(dhd_pub);
+	switch (ioc->cmd) {
+		case DHD_GET_MAGIC:
+			if (buflen < sizeof(int))
+				bcmerror = BCME_BUFTOOSHORT;
+			else
+				*(int*)buf = DHD_IOCTL_MAGIC;
+			break;
+
+		case DHD_GET_VERSION:
+			if (buflen < sizeof(int))
+				bcmerror = BCME_BUFTOOSHORT;
+			else
+				*(int*)buf = DHD_IOCTL_VERSION;
+			break;
+
+		case DHD_GET_VAR:
+		case DHD_SET_VAR:
+			{
+				char *arg;
+				uint arglen;
+
+				DHD_LINUX_GENERAL_LOCK(dhd_pub, flags);
+				if (DHD_BUS_CHECK_DOWN_OR_DOWN_IN_PROGRESS(dhd_pub) &&
+					bcmstricmp((char *)buf, "devreset")) {
+					/* In platforms like FC19, the FW download is done via IOCTL
+					 * and should not return error for IOCTLs fired before FW
+					 * Download is done
+					 */
+					if (dhd_fw_download_status(dhd_pub) == FW_DOWNLOAD_DONE) {
+						DHD_ERROR(("%s: return as fw_download_status=%d\n",
+							__FUNCTION__,
+							dhd_fw_download_status(dhd_pub)));
+						DHD_LINUX_GENERAL_UNLOCK(dhd_pub, flags);
+						dhd_os_dhdiovar_unlock(dhd_pub);
+						return -ENODEV;
+					}
+				}
+				DHD_BUS_BUSY_SET_IN_DHD_IOVAR(dhd_pub);
+				DHD_LINUX_GENERAL_UNLOCK(dhd_pub, flags);
+
+				DHD_LINUX_GENERAL_LOCK(dhd_pub, flags);
+				if (DHD_BUS_CHECK_SUSPEND_OR_SUSPEND_IN_PROGRESS(dhd_pub)) {
+					/* If Suspend/Resume is tested via pcie_suspend IOVAR
+					 * then continue to execute the IOVAR, return from here for
+					 * other IOVARs, also include pciecfgreg and devreset to go
+					 * through.
+					 */
+					if (bcmstricmp((char *)buf, "pcie_suspend") &&
+					    bcmstricmp((char *)buf, "pciecfgreg") &&
+					    bcmstricmp((char *)buf, "devreset") &&
+					    bcmstricmp((char *)buf, "sdio_suspend")) {
+						DHD_ERROR(("%s: bus is in suspend(%d)"
+							"or suspending(0x%x) state\n",
+							__FUNCTION__, dhd_pub->busstate,
+							dhd_pub->dhd_bus_busy_state));
+						DHD_BUS_BUSY_CLEAR_IN_DHD_IOVAR(dhd_pub);
+						dhd_os_busbusy_wake(dhd_pub);
+						DHD_LINUX_GENERAL_UNLOCK(dhd_pub, flags);
+						dhd_os_dhdiovar_unlock(dhd_pub);
+						return -ENODEV;
+					}
+				}
+				/* During devreset ioctl, we call dhdpcie_advertise_bus_cleanup,
+				 * which will wait for all the busy contexts to get over for
+				 * particular time and call ASSERT if timeout happens. As during
+				 * devreset ioctal, we made DHD_BUS_BUSY_SET_IN_DHD_IOVAR,
+				 * to avoid ASSERT, clear the IOCTL busy state. "devreset" ioctl is
+				 * not used in Production platforms but only used in FC19 setups.
+				 */
+				if (!bcmstricmp((char *)buf, "devreset") ||
+#ifdef BCMPCIE
+				    (dhd_bus_is_multibp_capable(dhd_pub->bus) &&
+				    !bcmstricmp((char *)buf, "dwnldstate")) ||
+#endif /* BCMPCIE */
+				    FALSE)
+				{
+					DHD_BUS_BUSY_CLEAR_IN_DHD_IOVAR(dhd_pub);
+				}
+				DHD_LINUX_GENERAL_UNLOCK(dhd_pub, flags);
+
+				/* scan past the name to any arguments */
+				for (arg = buf, arglen = buflen; *arg && arglen; arg++, arglen--)
+					;
+
+				if (arglen == 0 || *arg) {
+					bcmerror = BCME_BUFTOOSHORT;
+					goto unlock_exit;
+				}
+
+				/* account for the NUL terminator */
+				arg++, arglen--;
+				/* call with the appropriate arguments */
+				if (ioc->cmd == DHD_GET_VAR) {
+					bcmerror = dhd_iovar_op(dhd_pub, buf, arg, arglen,
+							buf, buflen, IOV_GET);
+				} else {
+					bcmerror = dhd_iovar_op(dhd_pub, buf, NULL, 0,
+							arg, arglen, IOV_SET);
+				}
+				if (bcmerror != BCME_UNSUPPORTED) {
+					goto unlock_exit;
+				}
+
+				/* not in generic table, try protocol module */
+				if (ioc->cmd == DHD_GET_VAR) {
+					bcmerror = dhd_prot_iovar_op(dhd_pub, buf, arg,
+							arglen, buf, buflen, IOV_GET);
+				} else {
+					bcmerror = dhd_prot_iovar_op(dhd_pub, buf,
+							NULL, 0, arg, arglen, IOV_SET);
+				}
+				if (bcmerror != BCME_UNSUPPORTED) {
+					goto unlock_exit;
+				}
+
+				/* if still not found, try bus module */
+				if (ioc->cmd == DHD_GET_VAR) {
+					bcmerror = dhd_bus_iovar_op(dhd_pub, buf,
+							arg, arglen, buf, buflen, IOV_GET);
+				} else {
+					bcmerror = dhd_bus_iovar_op(dhd_pub, buf,
+							NULL, 0, arg, arglen, IOV_SET);
+				}
+				if (bcmerror != BCME_UNSUPPORTED) {
+					goto unlock_exit;
+				}
+
+			}
+			goto unlock_exit;
+
+		default:
+			bcmerror = BCME_UNSUPPORTED;
+	}
+	dhd_os_dhdiovar_unlock(dhd_pub);
+	return bcmerror;
+
+unlock_exit:
+	DHD_LINUX_GENERAL_LOCK(dhd_pub, flags);
+	DHD_BUS_BUSY_CLEAR_IN_DHD_IOVAR(dhd_pub);
+	dhd_os_busbusy_wake(dhd_pub);
+	DHD_LINUX_GENERAL_UNLOCK(dhd_pub, flags);
+	dhd_os_dhdiovar_unlock(dhd_pub);
+	return bcmerror;
+}
+
+#ifdef SHOW_EVENTS
+
+static void
+wl_show_roam_event(dhd_pub_t *dhd_pub, uint status, uint datalen,
+	const char *event_name, char *eabuf, void *event_data)
+{
+#ifdef REPORT_FATAL_TIMEOUTS
+	OSL_ATOMIC_SET(dhd_pub->osh, &dhd_pub->set_ssid_rcvd, TRUE);
+	dhd_clear_join_error(dhd_pub, WLC_SSID_MASK);
+#endif /* REPORT_FATAL_TIMEOUTS */
+	if (status == WLC_E_STATUS_SUCCESS) {
+		DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
+	} else {
+#ifdef REPORT_FATAL_TIMEOUTS
+		/*
+		 * For secure join if WLC_E_SET_SSID returns with any failure case,
+		 * donot expect WLC_E_PSK_SUP. So clear the mask.
+		 */
+		dhd_clear_join_error(dhd_pub, WLC_WPA_MASK);
+#endif /* REPORT_FATAL_TIMEOUTS */
+		if (status == WLC_E_STATUS_FAIL) {
+			DHD_EVENT(("MACEVENT: %s, failed status %d\n", event_name, status));
+		} else if (status == WLC_E_STATUS_NO_NETWORKS) {
+			if (datalen) {
+				uint8 id = *((uint8 *)event_data);
+				if (id != DOT11_MNG_PROPR_ID) {
+					wl_roam_event_t *roam_data =
+						(wl_roam_event_t *)event_data;
+					bcm_xtlv_t *tlv = (bcm_xtlv_t *)roam_data->xtlvs;
+					if (tlv->id == WLC_ROAM_NO_NETWORKS_TLV_ID) {
+						uint32 *fail_reason = (uint32 *)tlv->data;
+						switch (*fail_reason) {
+							case WLC_E_REASON_NO_NETWORKS:
+								DHD_EVENT(("MACEVENT: %s,"
+									" no networks found\n",
+									event_name));
+								break;
+							case WLC_E_REASON_NO_NETWORKS_BY_SCORE:
+								DHD_EVENT(("MACEVENT: %s,"
+								" no networks found by score\n",
+									event_name));
+								break;
+							default:
+								DHD_ERROR(("MACEVENT: %s,"
+								" unknown fail reason 0x%x\n",
+									event_name,
+									*fail_reason));
+								ASSERT(0);
+						}
+					} else {
+						DHD_EVENT(("MACEVENT: %s,"
+							" no networks found\n",
+							event_name));
+					}
+				} else {
+					DHD_EVENT(("MACEVENT: %s,"
+						" no networks found\n",
+						event_name));
+				}
+			} else {
+				DHD_EVENT(("MACEVENT: %s, no networks found\n",
+					event_name));
+			}
+		} else {
+			DHD_EVENT(("MACEVENT: %s, unexpected status %d\n",
+				event_name, (int)status));
+		}
+	}
+}
+
+static void
+wl_show_roam_cache_update_event(const char *name, uint status,
+	uint reason, uint datalen, void *event_data)
+{
+	wlc_roam_cache_update_event_t *cache_update;
+	uint16 len_of_tlvs;
+	void *val_tlv_ptr;
+	bcm_xtlv_t *val_xtlv;
+	char ntoa_buf[ETHER_ADDR_STR_LEN];
+	uint idx;
+	const char* reason_name = NULL;
+	const char* status_name = NULL;
+	static struct {
+		uint event;
+		const char *event_name;
+	} reason_names[] = {
+		{WLC_E_REASON_INITIAL_ASSOC, "INITIAL ASSOCIATION"},
+		{WLC_E_REASON_LOW_RSSI, "LOW_RSSI"},
+		{WLC_E_REASON_DEAUTH, "RECEIVED DEAUTHENTICATION"},
+		{WLC_E_REASON_DISASSOC, "RECEIVED DISASSOCATION"},
+		{WLC_E_REASON_BCNS_LOST, "BEACONS LOST"},
+		{WLC_E_REASON_BETTER_AP, "BETTER AP FOUND"},
+		{WLC_E_REASON_MINTXRATE, "STUCK AT MIN TX RATE"},
+		{WLC_E_REASON_BSSTRANS_REQ, "REQUESTED ROAM"},
+		{WLC_E_REASON_TXFAIL, "TOO MANY TXFAILURES"}
+	};
+
+	static struct {
+		uint event;
+		const char *event_name;
+	} status_names[] = {
+		{WLC_E_STATUS_SUCCESS, "operation was successful"},
+		{WLC_E_STATUS_FAIL, "operation failed"},
+		{WLC_E_STATUS_TIMEOUT, "operation timed out"},
+		{WLC_E_STATUS_NO_NETWORKS, "failed due to no matching network found"},
+		{WLC_E_STATUS_ABORT, "operation was aborted"},
+		{WLC_E_STATUS_NO_ACK, "protocol failure: packet not ack'd"},
+		{WLC_E_STATUS_UNSOLICITED, "AUTH or ASSOC packet was unsolicited"},
+		{WLC_E_STATUS_ATTEMPT, "attempt to assoc to an auto auth configuration"},
+		{WLC_E_STATUS_PARTIAL, "scan results are incomplete"},
+		{WLC_E_STATUS_NEWSCAN, "scan aborted by another scan"},
+		{WLC_E_STATUS_NEWASSOC, "scan aborted due to assoc in progress"},
+		{WLC_E_STATUS_11HQUIET, "802.11h quiet period started"},
+		{WLC_E_STATUS_SUPPRESS, "user disabled scanning"},
+		{WLC_E_STATUS_NOCHANS, "no allowable channels to scan"},
+		{WLC_E_STATUS_CS_ABORT, "abort channel select"},
+		{WLC_E_STATUS_ERROR, "request failed due to error"},
+		{WLC_E_STATUS_INVALID, "Invalid status code"}
+	};
+
+	UNUSED_PARAMETER(ntoa_buf);
+	UNUSED_PARAMETER(reason_name);
+	UNUSED_PARAMETER(status_name);
+
+	switch (reason) {
+	case WLC_ROAM_CACHE_UPDATE_NEW_ROAM_CACHE:
+		DHD_EVENT(("Current roam cache status %d, "
+			"reason for cache update is new roam cache\n", status));
+		break;
+	case WLC_ROAM_CACHE_UPDATE_JOIN:
+		DHD_EVENT(("Current roam cache status %d, "
+			"reason for cache update is start of join\n", status));
+		break;
+	case WLC_ROAM_CACHE_UPDATE_RSSI_DELTA:
+		DHD_EVENT(("Current roam cache status %d, "
+			"reason for cache update is delta in rssi\n", status));
+		break;
+	case WLC_ROAM_CACHE_UPDATE_MOTION_RSSI_DELTA:
+		DHD_EVENT(("Current roam cache status %d, "
+			"reason for cache update is motion delta in rssi\n", status));
+		break;
+	case WLC_ROAM_CACHE_UPDATE_CHANNEL_MISS:
+		DHD_EVENT(("Current roam cache status %d, "
+			"reason for cache update is missed channel\n", status));
+		break;
+	case WLC_ROAM_CACHE_UPDATE_START_SPLIT_SCAN:
+		DHD_EVENT(("Current roam cache status %d, "
+			"reason for cache update is start of split scan\n", status));
+		break;
+	case WLC_ROAM_CACHE_UPDATE_START_FULL_SCAN:
+		DHD_EVENT(("Current roam cache status %d, "
+			"reason for cache update is start of full scan\n", status));
+		break;
+	case WLC_ROAM_CACHE_UPDATE_INIT_ASSOC:
+		DHD_EVENT(("Current roam cache status %d, "
+			"reason for cache update is init association\n", status));
+		break;
+	case WLC_ROAM_CACHE_UPDATE_FULL_SCAN_FAILED:
+		DHD_EVENT(("Current roam cache status %d, "
+			"reason for cache update is failure in full scan\n", status));
+		break;
+	case WLC_ROAM_CACHE_UPDATE_NO_AP_FOUND:
+		DHD_EVENT(("Current roam cache status %d, "
+			"reason for cache update is empty scan result\n", status));
+		break;
+	case WLC_ROAM_CACHE_UPDATE_MISSING_AP:
+		DHD_EVENT(("Current roam cache status %d, "
+			"reason for cache update is missed ap\n", status));
+		break;
+	default:
+		DHD_EVENT(("Current roam cache status %d, "
+			"reason for cache update is unknown %d\n", status, reason));
+		break;
+	}
+
+	if (datalen < sizeof(wlc_roam_cache_update_event_t)) {
+		DHD_ERROR(("MACEVENT: %s, missing event data\n", name));
+		return;
+	}
+
+	cache_update = (wlc_roam_cache_update_event_t *)event_data;
+	val_tlv_ptr = (void *)cache_update->xtlvs;
+	len_of_tlvs = datalen - sizeof(wlc_roam_cache_update_event_t);
+	val_xtlv = (bcm_xtlv_t *)val_tlv_ptr;
+	if (val_xtlv->id != WL_RMC_RPT_CMD_DATA) {
+		DHD_ERROR(("MACEVENT: %s, unexpected xtlv id %d\n",
+			name, val_xtlv->id));
+		return;
+	}
+	val_tlv_ptr = (uint8 *)val_tlv_ptr + BCM_XTLV_HDR_SIZE;
+	len_of_tlvs = val_xtlv->len;
+
+	while (len_of_tlvs && len_of_tlvs > BCM_XTLV_HDR_SIZE) {
+		val_xtlv = (bcm_xtlv_t *)val_tlv_ptr;
+		switch (val_xtlv->id) {
+			case WL_RMC_RPT_XTLV_BSS_INFO:
+			{
+				rmc_bss_info_v1_t *bss_info = (rmc_bss_info_v1_t *)(val_xtlv->data);
+				DHD_EVENT(("\t Current BSS INFO:\n"));
+				DHD_EVENT(("\t\tRSSI: %d\n", bss_info->rssi));
+				DHD_EVENT(("\t\tNumber of full scans performed "
+					"on current BSS: %d\n", bss_info->fullscan_count));
+				for (idx = 0; idx < ARRAYSIZE(reason_names); idx++) {
+					if (reason_names[idx].event == bss_info->reason) {
+						reason_name = reason_names[idx].event_name;
+					}
+				}
+				DHD_EVENT(("\t\tReason code for last full scan: %s(%d)\n",
+					reason_name, bss_info->reason));
+				DHD_EVENT(("\t\tDelta between current time and "
+					"last full scan: %d\n", bss_info->time_full_scan));
+				for (idx = 0; idx < ARRAYSIZE(status_names); idx++) {
+					if (status_names[idx].event == bss_info->status)
+						status_name = status_names[idx].event_name;
+				}
+				DHD_EVENT(("\t\tLast status code for not roaming: %s(%d)\n",
+					status_name, bss_info->status));
+
+			}
+				break;
+			case WL_RMC_RPT_XTLV_CANDIDATE_INFO:
+			case WL_RMC_RPT_XTLV_USER_CACHE_INFO:
+			{
+				rmc_candidate_info_v1_t *candidate_info =
+					(rmc_candidate_info_v1_t *)(val_xtlv->data);
+				UNUSED_PARAMETER(candidate_info);
+				if (val_xtlv->id == WL_RMC_RPT_XTLV_CANDIDATE_INFO) {
+					DHD_EVENT(("\t Candidate INFO:\n"));
+				} else {
+					DHD_EVENT(("\t User Candidate INFO:\n"));
+				}
+				DHD_EVENT(("\t\tBSSID: %s\n",
+					bcm_ether_ntoa((const struct ether_addr *)
+					&candidate_info->bssid, ntoa_buf)));
+				DHD_EVENT(("\t\tRSSI: %d\n", candidate_info->rssi));
+				DHD_EVENT(("\t\tChannel: %d\n", candidate_info->ctl_channel));
+				DHD_EVENT(("\t\tDelta between current time and last "
+					"seen time: %d\n", candidate_info->time_last_seen));
+				DHD_EVENT(("\t\tBSS load: %d\n", candidate_info->bss_load));
+			}
+				break;
+			default:
+				DHD_ERROR(("MACEVENT: %s, unexpected xtlv id %d\n",
+					name, val_xtlv->id));
+				return;
+		}
+		val_tlv_ptr = (uint8 *)val_tlv_ptr + bcm_xtlv_size(val_xtlv,
+			BCM_XTLV_OPTION_NONE);
+		len_of_tlvs -= (uint16)bcm_xtlv_size(val_xtlv, BCM_XTLV_OPTION_NONE);
+	}
+}
+
+static void
+wl_show_host_event(dhd_pub_t *dhd_pub, wl_event_msg_t *event, void *event_data,
+	void *raw_event_ptr, char *eventmask)
+{
+	uint i, status, reason;
+	bool group = FALSE, flush_txq = FALSE, link = FALSE;
+	bool host_data = FALSE; /* prints  event data after the case  when set */
+	const char *auth_str;
+	const char *event_name;
+	const uchar *buf;
+	char err_msg[256], eabuf[ETHER_ADDR_STR_LEN];
+	uint event_type, flags, auth_type, datalen;
+
+	event_type = ntoh32(event->event_type);
+	flags = ntoh16(event->flags);
+	status = ntoh32(event->status);
+	reason = ntoh32(event->reason);
+	BCM_REFERENCE(reason);
+	auth_type = ntoh32(event->auth_type);
+	datalen = (event_data != NULL) ? ntoh32(event->datalen) : 0;
+
+	/* debug dump of event messages */
+	snprintf(eabuf, sizeof(eabuf), MACDBG, MAC2STRDBG(event->addr.octet));
+
+	event_name = bcmevent_get_name(event_type);
+	BCM_REFERENCE(event_name);
+
+	if (flags & WLC_EVENT_MSG_LINK)
+		link = TRUE;
+	if (flags & WLC_EVENT_MSG_GROUP)
+		group = TRUE;
+	if (flags & WLC_EVENT_MSG_FLUSHTXQ)
+		flush_txq = TRUE;
+
+	switch (event_type) {
+	case WLC_E_START:
+		DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
+		break;
+	case WLC_E_DEAUTH:
+	case WLC_E_DISASSOC:
+		DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
+#ifdef REPORT_FATAL_TIMEOUTS
+		dhd_clear_join_error(dhd_pub, WLC_SSID_MASK | WLC_WPA_MASK);
+#endif /* REPORT_FATAL_TIMEOUTS */
+		break;
+
+	case WLC_E_ASSOC_IND:
+	case WLC_E_REASSOC_IND:
+
+		DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
+#ifdef REPORT_FATAL_TIMEOUTS
+		if (status != WLC_E_STATUS_SUCCESS) {
+			dhd_clear_join_error(dhd_pub, WLC_SSID_MASK | WLC_WPA_MASK);
+		}
+#endif /* REPORT_FATAL_TIMEOUTS */
+
+		break;
+
+	case WLC_E_BSSID:
+		DHD_EVENT(("MACEVENT: %s, MAC %s, reason %d datalen %d\n", event_name,
+			eabuf, (int)reason, datalen));
+		break;
+
+	case WLC_E_ASSOC:
+	case WLC_E_REASSOC:
+		if (status == WLC_E_STATUS_SUCCESS) {
+			DHD_EVENT(("MACEVENT: %s, MAC %s, SUCCESS\n", event_name, eabuf));
+		} else if (status == WLC_E_STATUS_TIMEOUT) {
+			DHD_EVENT(("MACEVENT: %s, MAC %s, TIMEOUT\n", event_name, eabuf));
+		} else if (status == WLC_E_STATUS_FAIL) {
+			DHD_EVENT(("MACEVENT: %s, MAC %s, FAILURE, status %d reason %d\n",
+			       event_name, eabuf, (int)status, (int)reason));
+		} else if (status == WLC_E_STATUS_SUPPRESS) {
+			DHD_EVENT(("MACEVENT: %s, MAC %s, SUPPRESS\n", event_name, eabuf));
+		} else if (status == WLC_E_STATUS_NO_ACK) {
+			DHD_EVENT(("MACEVENT: %s, MAC %s, NOACK\n", event_name, eabuf));
+		} else {
+			DHD_EVENT(("MACEVENT: %s, MAC %s, unexpected status %d\n",
+			       event_name, eabuf, (int)status));
+		}
+#ifdef REPORT_FATAL_TIMEOUTS
+		if (status != WLC_E_STATUS_SUCCESS) {
+			dhd_clear_join_error(dhd_pub, WLC_SSID_MASK | WLC_WPA_MASK);
+		}
+#endif /* REPORT_FATAL_TIMEOUTS */
+
+		break;
+
+	case WLC_E_DEAUTH_IND:
+	case WLC_E_DISASSOC_IND:
+#ifdef REPORT_FATAL_TIMEOUTS
+		dhd_clear_join_error(dhd_pub, WLC_SSID_MASK | WLC_WPA_MASK);
+#endif /* REPORT_FATAL_TIMEOUTS */
+		DHD_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name, eabuf, (int)reason));
+		break;
+
+	case WLC_E_AUTH:
+	case WLC_E_AUTH_IND:
+		if (auth_type == DOT11_OPEN_SYSTEM)
+			auth_str = "Open System";
+		else if (auth_type == DOT11_SHARED_KEY)
+			auth_str = "Shared Key";
+		else if (auth_type == DOT11_SAE)
+			auth_str = "SAE";
+		else {
+			snprintf(err_msg, sizeof(err_msg), "AUTH unknown: %d", (int)auth_type);
+			auth_str = err_msg;
+		}
+
+		if (event_type == WLC_E_AUTH_IND) {
+			DHD_EVENT(("MACEVENT: %s, MAC %s, %s\n", event_name, eabuf, auth_str));
+		} else if (status == WLC_E_STATUS_SUCCESS) {
+			DHD_EVENT(("MACEVENT: %s, MAC %s, %s, SUCCESS\n",
+				event_name, eabuf, auth_str));
+		} else if (status == WLC_E_STATUS_TIMEOUT) {
+			DHD_EVENT(("MACEVENT: %s, MAC %s, %s, TIMEOUT\n",
+				event_name, eabuf, auth_str));
+		} else if (status == WLC_E_STATUS_FAIL) {
+			DHD_EVENT(("MACEVENT: %s, MAC %s, %s, FAILURE, status %d reason %d\n",
+			       event_name, eabuf, auth_str, (int)status, (int)reason));
+		} else if (status == WLC_E_STATUS_SUPPRESS) {
+			DHD_EVENT(("MACEVENT: %s, MAC %s, %s, SUPPRESS\n",
+			       event_name, eabuf, auth_str));
+		} else if (status == WLC_E_STATUS_NO_ACK) {
+			DHD_EVENT(("MACEVENT: %s, MAC %s, %s, NOACK\n",
+			       event_name, eabuf, auth_str));
+		} else {
+			DHD_EVENT(("MACEVENT: %s, MAC %s, %s, status %d reason %d\n",
+				event_name, eabuf, auth_str, (int)status, (int)reason));
+		}
+		BCM_REFERENCE(auth_str);
+#ifdef REPORT_FATAL_TIMEOUTS
+		if (status != WLC_E_STATUS_SUCCESS) {
+			dhd_clear_join_error(dhd_pub, WLC_SSID_MASK | WLC_WPA_MASK);
+		}
+#endif /* REPORT_FATAL_TIMEOUTS */
+
+		break;
+
+	case WLC_E_ROAM:
+		wl_show_roam_event(dhd_pub, status, datalen,
+			event_name, eabuf, event_data);
+		break;
+	case WLC_E_ROAM_START:
+		if (datalen >= sizeof(wlc_roam_start_event_t)) {
+			const wlc_roam_start_event_t *roam_start =
+				(wlc_roam_start_event_t *)event_data;
+			UNUSED_PARAMETER(roam_start);
+			DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d,"
+				" reason %d, auth %d, current bss rssi %d\n",
+				event_name, event_type, eabuf, (int)status, (int)reason,
+				(int)auth_type, (int)roam_start->rssi));
+		} else {
+			DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d\n",
+				event_name, event_type, eabuf, (int)status, (int)reason,
+				(int)auth_type));
+		}
+		break;
+	case WLC_E_ROAM_PREP:
+		if (datalen >= sizeof(wlc_roam_prep_event_t)) {
+			const wlc_roam_prep_event_t *roam_prep =
+				(wlc_roam_prep_event_t *)event_data;
+			UNUSED_PARAMETER(roam_prep);
+			DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d,"
+				" reason %d, auth %d, target bss rssi %d\n",
+				event_name, event_type, eabuf, (int)status, (int)reason,
+				(int)auth_type, (int)roam_prep->rssi));
+		} else {
+			DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d\n",
+				event_name, event_type, eabuf, (int)status, (int)reason,
+				(int)auth_type));
+		}
+		break;
+	case WLC_E_ROAM_CACHE_UPDATE:
+		DHD_EVENT(("MACEVENT: %s\n", event_name));
+		wl_show_roam_cache_update_event(event_name, status,
+			reason, datalen, event_data);
+		break;
+	case WLC_E_JOIN:
+	case WLC_E_SET_SSID:
+#ifdef REPORT_FATAL_TIMEOUTS
+		OSL_ATOMIC_SET(dhd_pub->osh, &dhd_pub->set_ssid_rcvd, TRUE);
+		dhd_clear_join_error(dhd_pub, WLC_SSID_MASK);
+#endif /* REPORT_FATAL_TIMEOUTS */
+		if (status == WLC_E_STATUS_SUCCESS) {
+			DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
+		} else {
+#ifdef REPORT_FATAL_TIMEOUTS
+			/*
+			 * For secure join if WLC_E_SET_SSID returns with any failure case,
+			 * donot expect WLC_E_PSK_SUP. So clear the mask.
+			 */
+			dhd_clear_join_error(dhd_pub, WLC_WPA_MASK);
+#endif /* REPORT_FATAL_TIMEOUTS */
+			if (status == WLC_E_STATUS_FAIL) {
+				DHD_EVENT(("MACEVENT: %s, failed status %d\n", event_name, status));
+			} else if (status == WLC_E_STATUS_NO_NETWORKS) {
+				DHD_EVENT(("MACEVENT: %s, no networks found\n", event_name));
+			} else {
+				DHD_EVENT(("MACEVENT: %s, unexpected status %d\n",
+					event_name, (int)status));
+			}
+		}
+		break;
+
+	case WLC_E_JOIN_START:
+		DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
+		break;
+
+	case WLC_E_BEACON_RX:
+		if (status == WLC_E_STATUS_SUCCESS) {
+			DHD_EVENT(("MACEVENT: %s, SUCCESS\n", event_name));
+		} else if (status == WLC_E_STATUS_FAIL) {
+			DHD_EVENT(("MACEVENT: %s, FAIL\n", event_name));
+		} else {
+			DHD_EVENT(("MACEVENT: %s, status %d\n", event_name, status));
+		}
+		break;
+
+	case WLC_E_LINK:
+		DHD_EVENT(("MACEVENT: %s %s flags:0x%x status:%d reason:%d\n",
+			event_name, link?"UP":"DOWN", flags, status, reason));
+#ifdef PCIE_FULL_DONGLE
+#ifdef REPORT_FATAL_TIMEOUTS
+		{
+			uint8 ifindex = (uint8)dhd_ifname2idx(dhd_pub->info, event->ifname);
+			uint8 role = dhd_flow_rings_ifindex2role(dhd_pub, ifindex);
+			if ((role == WLC_E_IF_ROLE_STA) && (!link)) {
+				dhd_clear_join_error(dhd_pub, WLC_SSID_MASK | WLC_WPA_MASK);
+			}
+		}
+#endif /* PCIE_FULL_DONGLE */
+#endif /* REPORT_FATAL_TIMEOUTS */
+		BCM_REFERENCE(link);
+		break;
+
+	case WLC_E_MIC_ERROR:
+		DHD_EVENT(("MACEVENT: %s, MAC %s, Group %d, Flush %d\n",
+		       event_name, eabuf, group, flush_txq));
+		BCM_REFERENCE(group);
+		BCM_REFERENCE(flush_txq);
+		break;
+
+	case WLC_E_ICV_ERROR:
+	case WLC_E_UNICAST_DECODE_ERROR:
+	case WLC_E_MULTICAST_DECODE_ERROR:
+		DHD_EVENT(("MACEVENT: %s, MAC %s\n",
+		       event_name, eabuf));
+		break;
+
+	case WLC_E_TXFAIL:
+		DHD_EVENT(("MACEVENT: %s, RA %s status %d\n", event_name, eabuf, status));
+		break;
+
+	case WLC_E_ASSOC_REQ_IE:
+	case WLC_E_ASSOC_RESP_IE:
+	case WLC_E_PMKID_CACHE:
+		DHD_EVENT(("MACEVENT: %s\n", event_name));
+		break;
+
+	case WLC_E_SCAN_COMPLETE:
+		DHD_EVENT(("MACEVENT: %s\n", event_name));
+#ifdef REPORT_FATAL_TIMEOUTS
+		dhd_stop_scan_timer(dhd_pub, FALSE, 0);
+#endif /* REPORT_FATAL_TIMEOUTS */
+		break;
+	case WLC_E_RSSI_LQM:
+	case WLC_E_PFN_NET_FOUND:
+	case WLC_E_PFN_NET_LOST:
+	case WLC_E_PFN_SCAN_COMPLETE:
+	case WLC_E_PFN_SCAN_NONE:
+	case WLC_E_PFN_SCAN_ALLGONE:
+	case WLC_E_PFN_GSCAN_FULL_RESULT:
+#ifdef WL_SCHED_SCAN
+	case WLC_E_PFN_PARTIAL_RESULT:
+#endif /* WL_SCHED_SCAN */
+	case WLC_E_PFN_SSID_EXT:
+		DHD_EVENT(("PNOEVENT: %s\n", event_name));
+		break;
+
+	case WLC_E_PFN_SCAN_BACKOFF:
+	case WLC_E_PFN_BSSID_SCAN_BACKOFF:
+		DHD_EVENT(("PNOEVENT: %s, status %d, reason %d\n",
+		           event_name, (int)status, (int)reason));
+		break;
+
+	case WLC_E_PSK_SUP:
+	case WLC_E_PRUNE:
+		DHD_EVENT(("MACEVENT: %s, status %d, reason %d\n",
+		           event_name, (int)status, (int)reason));
+#ifdef REPORT_FATAL_TIMEOUTS
+		dhd_clear_join_error(dhd_pub, WLC_WPA_MASK);
+#endif /* REPORT_FATAL_TIMEOUTS */
+		break;
+
+#ifdef WIFI_ACT_FRAME
+	case WLC_E_ACTION_FRAME:
+		DHD_TRACE(("MACEVENT: %s Bssid %s\n", event_name, eabuf));
+		break;
+	case WLC_E_ACTION_FRAME_COMPLETE:
+		if (datalen >= sizeof(uint32)) {
+			const uint32 *pktid = event_data;
+			BCM_REFERENCE(pktid);
+			DHD_EVENT(("MACEVENT: %s status %d, reason %d, pktid 0x%x\n",
+				event_name, (int)status, (int)reason, *pktid));
+		}
+		break;
+#endif /* WIFI_ACT_FRAME */
+
+#ifdef SHOW_LOGTRACE
+	case WLC_E_TRACE:
+	{
+		dhd_dbg_trace_evnt_handler(dhd_pub, event_data, raw_event_ptr, datalen);
+		break;
+	}
+#endif /* SHOW_LOGTRACE */
+
+	case WLC_E_RSSI: {
+		wl_event_data_rssi_t *e_data = (wl_event_data_rssi_t *)event_data;
+		UNUSED_PARAMETER(e_data);
+		DHD_EVENT(("MACEVENT: %s (RSSI=%d SNR=%d NF=%d)\n", event_name,
+			ntoh32(e_data->rssi), ntoh32(e_data->snr), ntoh32(e_data->noise)));
+		} break;
+
+	case WLC_E_SERVICE_FOUND:
+	case WLC_E_P2PO_ADD_DEVICE:
+	case WLC_E_P2PO_DEL_DEVICE:
+		DHD_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf));
+		break;
+
+	case WLC_E_CCA_CHAN_QUAL:
+		/* I would like to check here that datalen >= sizeof(cca_chan_qual_event_t)
+		 * but since definition of cca_chan_qual_event_t is different
+		 * between blazar and legacy firmware, I will
+		 * check only that datalen is bigger than 0.
+		 */
+		if (datalen >= sizeof(cca_chan_qual_event_t)) {
+			cca_chan_qual_event_t *cca_event =
+				(cca_chan_qual_event_t *)event_data;
+			if ((cca_event->id == WL_CHAN_QUAL_FULLPM_CCA) ||
+			    (cca_event->id == WL_CHAN_QUAL_FULLPM_CCA_OFDM_DESENSE) ||
+			    (cca_event->id == WL_CHAN_QUAL_FULLPM_CCA_ALL_DESENSE)) {
+				cca_only_chan_qual_event_t *cca_only_event =
+					(cca_only_chan_qual_event_t *)cca_event;
+				BCM_REFERENCE(cca_only_event);
+				DHD_EVENT((
+					"MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d,"
+					" channel 0x%02x\n",
+					event_name, event_type, eabuf, (int)status,
+					(int)reason, (int)auth_type, cca_event->chanspec));
+				DHD_EVENT((
+					"\tTOTAL (dur %dms me %dms notme %dms interf %dms"
+					" ts 0x%08x)\n",
+					cca_only_event->cca_busy_ext.duration,
+					cca_only_event->cca_busy_ext.congest_ibss,
+					cca_only_event->cca_busy_ext.congest_obss,
+					cca_only_event->cca_busy_ext.interference,
+					cca_only_event->cca_busy_ext.timestamp));
+				DHD_EVENT((
+					"\t  !PM (dur %dms me %dms notme %dms interf %dms)\n",
+					cca_only_event->cca_busy_nopm.duration,
+					cca_only_event->cca_busy_nopm.congest_ibss,
+					cca_only_event->cca_busy_nopm.congest_obss,
+					cca_only_event->cca_busy_nopm.interference));
+				DHD_EVENT((
+					"\t   PM (dur %dms me %dms notme %dms interf %dms)\n",
+					cca_only_event->cca_busy_pm.duration,
+					cca_only_event->cca_busy_pm.congest_ibss,
+					cca_only_event->cca_busy_pm.congest_obss,
+					cca_only_event->cca_busy_pm.interference));
+				if (cca_event->id == WL_CHAN_QUAL_FULLPM_CCA_OFDM_DESENSE) {
+					cca_only_chan_qual_event_v2_t *cca_event_v2 =
+						(cca_only_chan_qual_event_v2_t *)
+						cca_only_event;
+					if (cca_event->len >=
+						(STRUCT_SIZE_THROUGH(cca_event_v2, ofdm_desense) -
+						STRUCT_SIZE_THROUGH(cca_event_v2, len))) {
+						DHD_EVENT(("\t OFDM desense %d\n",
+							cca_event_v2->ofdm_desense));
+					} else {
+						DHD_EVENT(("\t OFDM desense: missing data\n"));
+					}
+				} else if (cca_event->id == WL_CHAN_QUAL_FULLPM_CCA_ALL_DESENSE) {
+					cca_only_chan_qual_event_v3_t *cca_event_v3 =
+						(cca_only_chan_qual_event_v3_t *)
+						cca_only_event;
+					if (cca_event->len >=
+						(STRUCT_SIZE_THROUGH(cca_event_v3, desense) -
+						STRUCT_SIZE_THROUGH(cca_event_v3, len))) {
+						DHD_EVENT(("\t OFDM desense %d BPHY desense %d"
+							" reason 0x%x)\n",
+							cca_event_v3->desense.ofdm_desense,
+							cca_event_v3->desense.bphy_desense,
+							cca_event_v3->desense.reason));
+					} else {
+						DHD_EVENT(("\t  PHY desense: missing data\n"));
+					}
+				}
+			} else if (cca_event->id == WL_CHAN_QUAL_FULL_CCA) {
+				DHD_EVENT((
+					"MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d,"
+					" channel 0x%02x (dur %dms ibss %dms obss %dms interf %dms"
+					" ts 0x%08x)\n",
+					event_name, event_type, eabuf, (int)status,
+					(int)reason, (int)auth_type, cca_event->chanspec,
+					cca_event->cca_busy_ext.duration,
+					cca_event->cca_busy_ext.congest_ibss,
+					cca_event->cca_busy_ext.congest_obss,
+					cca_event->cca_busy_ext.interference,
+					cca_event->cca_busy_ext.timestamp));
+			} else if (cca_event->id == WL_CHAN_QUAL_CCA) {
+				DHD_EVENT((
+					"MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d,"
+					" channel 0x%02x (dur %dms busy %dms ts 0x%08x)\n",
+					event_name, event_type, eabuf, (int)status,
+					(int)reason, (int)auth_type, cca_event->chanspec,
+					cca_event->cca_busy.duration,
+					cca_event->cca_busy.congest,
+					cca_event->cca_busy.timestamp));
+			} else if ((cca_event->id == WL_CHAN_QUAL_NF) ||
+			           (cca_event->id == WL_CHAN_QUAL_NF_LTE)) {
+				DHD_EVENT((
+					"MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d,"
+					" channel 0x%02x (NF[%d] %ddB)\n",
+					event_name, event_type, eabuf, (int)status,
+					(int)reason, (int)auth_type, cca_event->chanspec,
+					cca_event->id, cca_event->noise));
+			} else {
+				DHD_EVENT((
+					"MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d,"
+					" channel 0x%02x (unknown ID %d)\n",
+					event_name, event_type, eabuf, (int)status,
+					(int)reason, (int)auth_type, cca_event->chanspec,
+					cca_event->id));
+			}
+		}
+		break;
+	case WLC_E_ESCAN_RESULT:
+#if defined(NDIS)
+		break;
+#endif
+		if (datalen >= sizeof(wl_escan_result_v2_t)) {
+			const wl_escan_result_v2_t *escan_result =
+				(wl_escan_result_v2_t *)event_data;
+			BCM_REFERENCE(escan_result);
+#ifdef OEM_ANDROID
+			/* Because WLC_E_ESCAN_RESULT event log are being print too many.
+			* So, DHD_EVENT() changes to be used DHD_TRACE() in HW4 platform.
+			*/
+			DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d \n",
+				event_name, event_type, eabuf, (int)status));
+#else
+			DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d sync-id %u\n",
+				event_name, event_type, eabuf,
+				(int)status, dtoh16(escan_result->sync_id)));
+#endif
+#ifdef REPORT_FATAL_TIMEOUTS
+			/* a 'partial' status means the escan is still in progress
+			* any other status implies the escan has either finished or aborted
+			*/
+			if (status != WLC_E_STATUS_PARTIAL) {
+				unsigned long timeout_flags = 0;
+				uint16 syncid = dtoh16(escan_result->sync_id);
+				/* this is to take care of the specific case where
+				* escan event returns abort and is processed immediately
+				* by dhd before the escan iovar has returned. In that case
+				* if the iovar returns success, then we will be starting a
+				* timeout even though the escan has already been aborted !
+				* So the flag below is checked before starting the escan timeout
+				*/
+				if (dhd_pub->timeout_info) {
+					DHD_TIMER_LOCK(dhd_pub->timeout_info->scan_timer_lock,
+						timeout_flags);
+					if (!dhd_pub->timeout_info->scan_timer_active &&
+						syncid == dhd_pub->esync_id) {
+						dhd_pub->timeout_info->escan_aborted = TRUE;
+						dhd_pub->timeout_info->abort_syncid = syncid;
+						DHD_TIMER_UNLOCK(
+							dhd_pub->timeout_info->scan_timer_lock,
+							timeout_flags);
+						break;
+					} else {
+						dhd_pub->timeout_info->escan_aborted = FALSE;
+					}
+					DHD_TIMER_UNLOCK(dhd_pub->timeout_info->scan_timer_lock,
+						timeout_flags);
+				}
+				dhd_stop_scan_timer(dhd_pub, TRUE, dtoh16(escan_result->sync_id));
+			}
+#endif /* REPORT_FATAL_TIMEOUTS */
+		}
+		break;
+	case WLC_E_IF:
+		if (datalen >= sizeof(struct wl_event_data_if)) {
+			const struct wl_event_data_if *ifevent =
+				(struct wl_event_data_if *)event_data;
+			BCM_REFERENCE(ifevent);
+
+			DHD_EVENT(("MACEVENT: %s, opcode:0x%d  ifidx:%d role:%d\n",
+				event_name, ifevent->opcode, ifevent->ifidx, ifevent->role));
+		}
+		break;
+#ifdef SHOW_LOGTRACE
+	case WLC_E_MSCH:
+	{
+		wl_mschdbg_event_handler(dhd_pub, raw_event_ptr, reason, event_data, datalen);
+		break;
+	}
+#endif /* SHOW_LOGTRACE */
+
+	case WLC_E_PSK_AUTH:
+		DHD_EVENT(("MACEVENT: %s, RA %s status %d Reason:%d\n",
+			event_name, eabuf, status, reason));
+		break;
+	case WLC_E_AGGR_EVENT:
+		if (datalen >= sizeof(event_aggr_data_t)) {
+			const event_aggr_data_t *aggrbuf = event_data;
+			int j = 0, len = 0;
+			const uint8 *data = aggrbuf->data;
+			DHD_EVENT(("MACEVENT: %s, num of events %d total len %d sub events: ",
+				event_name, aggrbuf->num_events, aggrbuf->len));
+			for (j = 0; j < aggrbuf->num_events; j++)
+			{
+				const wl_event_msg_t * sub_event = (const wl_event_msg_t *)data;
+				if (len > aggrbuf->len) {
+					DHD_ERROR(("%s: Aggr events corrupted!",
+						__FUNCTION__));
+					break;
+				}
+				DHD_EVENT(("\n Event type: %d ", ntoh32(sub_event->event_type)));
+				len += ALIGN_SIZE((ntoh32(sub_event->datalen) +
+					sizeof(wl_event_msg_t)), sizeof(uint64));
+				buf = (const uchar *)(data + sizeof(wl_event_msg_t));
+				BCM_REFERENCE(buf);
+				DHD_EVENT((" data (%d) : ", ntoh32(sub_event->datalen)));
+				for (i = 0; i < ntoh32(sub_event->datalen); i++) {
+					DHD_EVENT((" 0x%02x ", buf[i]));
+				}
+				data = aggrbuf->data + len;
+			}
+			DHD_EVENT(("\n"));
+		}
+		break;
+	case WLC_E_PHY_CAL:
+		{
+			DHD_EVENT(("MACEVENT: %s, reason:%d\n", event_name, reason));
+			break;
+		}
+	case WLC_E_NAN_CRITICAL:
+		{
+			DHD_EVENT(("MACEVENT: %s, type:%d\n", event_name, reason));
+			break;
+		}
+	case WLC_E_NAN_NON_CRITICAL:
+		{
+			DHD_TRACE(("MACEVENT: %s, type:%d\n", event_name, reason));
+			break;
+		}
+	case WLC_E_PROXD:
+		if (datalen >= sizeof(wl_proxd_event_t)) {
+			const wl_proxd_event_t *proxd =
+				(wl_proxd_event_t*)event_data;
+			DHD_LOG_MEM(("MACEVENT: %s, event:%d, status:%d\n",
+				event_name, proxd->type, reason));
+		}
+		break;
+	case WLC_E_RPSNOA:
+		if (datalen >= sizeof(rpsnoa_stats_t)) {
+			const rpsnoa_stats_t *stat = event_data;
+			if (datalen == sizeof(*stat)) {
+				DHD_EVENT(("MACEVENT: %s, band %s, status %d, pps %d\n", event_name,
+					(stat->band == WLC_BAND_2G) ? "2G":"5G",
+					stat->state, stat->last_pps));
+			}
+		}
+		break;
+	case WLC_E_WA_LQM:
+		if (datalen >= sizeof(wl_event_wa_lqm_t)) {
+			const wl_event_wa_lqm_t *event_wa_lqm =
+				(wl_event_wa_lqm_t *)event_data;
+			const bcm_xtlv_t *subevent;
+			const wl_event_wa_lqm_basic_t *elqm_basic;
+
+			if ((event_wa_lqm->ver != WL_EVENT_WA_LQM_VER) ||
+			    (event_wa_lqm->len < sizeof(wl_event_wa_lqm_t) + BCM_XTLV_HDR_SIZE)) {
+				DHD_ERROR(("MACEVENT: %s invalid (ver=%d len=%d)\n",
+					event_name, event_wa_lqm->ver, event_wa_lqm->len));
+				break;
+			}
+
+			subevent = (const bcm_xtlv_t *)event_wa_lqm->subevent;
+			 if ((subevent->id != WL_EVENT_WA_LQM_BASIC) ||
+			     (subevent->len < sizeof(wl_event_wa_lqm_basic_t))) {
+				DHD_ERROR(("MACEVENT: %s invalid sub-type (id=%d len=%d)\n",
+					event_name, subevent->id, subevent->len));
+				break;
+			}
+
+			elqm_basic = (const wl_event_wa_lqm_basic_t *)subevent->data;
+			BCM_REFERENCE(elqm_basic);
+			DHD_EVENT(("MACEVENT: %s (RSSI=%d SNR=%d TxRate=%d RxRate=%d)\n",
+				event_name, elqm_basic->rssi, elqm_basic->snr,
+				elqm_basic->tx_rate, elqm_basic->rx_rate));
+		}
+		break;
+
+	case WLC_E_OBSS_DETECTION:
+		{
+			DHD_EVENT(("MACEVENT: %s, type:%d\n", event_name, reason));
+			break;
+		}
+
+	case WLC_E_AP_BCN_MUTE:
+		if (datalen >= sizeof(wlc_bcn_mute_miti_event_data_v1_t)) {
+			const wlc_bcn_mute_miti_event_data_v1_t
+				*bcn_mute_miti_evnt_data = event_data;
+			UNUSED_PARAMETER(bcn_mute_miti_evnt_data);
+			DHD_EVENT(("MACEVENT: %s, reason :%d uatbtt_count: %d\n",
+				event_name, reason, bcn_mute_miti_evnt_data->uatbtt_count));
+		}
+		break;
+#ifdef WL_TWT
+	case WLC_E_TWT:
+		DHD_EVENT(("MACEVENT: %s, type:%d\n", event_name, reason));
+		break;
+#endif /* WL_TWT */
+	case WLC_E_COUNTRY_CODE_CHANGED:
+		DHD_EVENT(("MACEVENT: %s: Country code changed to %s\n", event_name,
+			(char*)event_data));
+		break;
+#if defined(CSI_SUPPORT)
+	case WLC_E_CSI:
+		/* do not process here as the whole CSI event will
+		 * be direclty pass to CSI module for processing
+		 */
+		break;
+#endif /* CSI_SUPPORT */
+	case WLC_E_SCAN:
+		{
+			const char *scan_state;
+			UNUSED_PARAMETER(scan_state);
+			if (reason == WL_SCAN_START) {
+				scan_state = "WL_SCAN_START";
+			} else if (reason == WL_SCAN_END) {
+				scan_state = "WL_SCAN_END";
+			} else {
+				scan_state = "Unknown";
+			}
+			DHD_EVENT(("MACEVENT: %s: scan state %s\n", event_name, scan_state));
+			break;
+		}
+	case WLC_E_OWE_INFO:
+		DHD_EVENT(("MACEVENT: %s, MAC %s type:%d\n", event_name, eabuf, reason));
+		break;
+	default:
+		DHD_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d\n",
+		       event_name, event_type, eabuf, (int)status, (int)reason,
+		       (int)auth_type));
+		break;
+	}
+
+	/* show any appended data if message level is set to bytes or host_data is set */
+	if ((DHD_BYTES_ON() || (host_data == TRUE)) && DHD_EVENT_ON() && datalen) {
+		buf = (uchar *) event_data;
+		BCM_REFERENCE(buf);
+		DHD_EVENT((" data (%d) : ", datalen));
+		for (i = 0; i < datalen; i++) {
+			DHD_EVENT((" 0x%02x ", buf[i]));
+		}
+		DHD_EVENT(("\n"));
+	}
+} /* wl_show_host_event */
+#endif /* SHOW_EVENTS */
+
+#ifdef DNGL_EVENT_SUPPORT
+/* Check whether packet is a BRCM dngl event pkt. If it is, process event data. */
+int
+dngl_host_event(dhd_pub_t *dhdp, void *pktdata, bcm_dngl_event_msg_t *dngl_event, size_t pktlen)
+{
+	bcm_dngl_event_t *pvt_data = (bcm_dngl_event_t *)pktdata;
+
+	dngl_host_event_process(dhdp, pvt_data, dngl_event, pktlen);
+	return BCME_OK;
+}
+
+#ifdef PARSE_DONGLE_HOST_EVENT
+typedef struct hck_id_to_str_s {
+	uint32 id;
+	char *name;
+} hck_id_to_str_t;
+
+hck_id_to_str_t hck_sw_id_to_str[] = {
+	{WL_HC_DD_PCIE, "WL_HC_DD_PCIE"},
+	{WL_HC_DD_RX_DMA_STALL, "WL_HC_DD_RX_DMA_STALL"},
+	{WL_HC_DD_RX_STALL, "WL_HC_DD_RX_STALL"},
+	{WL_HC_DD_TX_STALL, "WL_HC_DD_TX_STALL"},
+	{WL_HC_DD_SCAN_STALL, "WL_HC_DD_SCAN_STALL"},
+	{WL_HC_DD_PHY, "WL_HC_DD_PHY"},
+	{WL_HC_DD_REINIT, "WL_HC_DD_REINIT"},
+	{WL_HC_DD_TXQ_STALL, "WL_HC_DD_TXQ_STALL"},
+	{0, NULL}
+};
+
+hck_id_to_str_t hck_pcie_module_to_str[] = {
+	{HEALTH_CHECK_PCIEDEV_INDUCED_IND, "PCIEDEV_INDUCED_IND"},
+	{HEALTH_CHECK_PCIEDEV_H2D_DMA_IND, "PCIEDEV_H2D_DMA_IND"},
+	{HEALTH_CHECK_PCIEDEV_D2H_DMA_IND, "PCIEDEV_D2H_DMA_IND"},
+	{HEALTH_CHECK_PCIEDEV_IOCTL_STALL_IND, "PCIEDEV_IOCTL_STALL_IND"},
+	{HEALTH_CHECK_PCIEDEV_D3ACK_STALL_IND, "PCIEDEV_D3ACK_STALL_IND"},
+	{HEALTH_CHECK_PCIEDEV_NODS_IND, "PCIEDEV_NODS_IND"},
+	{HEALTH_CHECK_PCIEDEV_LINKSPEED_FALLBACK_IND, "PCIEDEV_LINKSPEED_FALLBACK_IND"},
+	{HEALTH_CHECK_PCIEDEV_DSACK_STALL_IND, "PCIEDEV_DSACK_STALL_IND"},
+	{0, NULL}
+};
+
+hck_id_to_str_t hck_rx_stall_v2_to_str[] = {
+	{BCM_RX_HC_RESERVED, "BCM_RX_HC_RESERVED"},
+	{BCM_RX_HC_UNSPECIFIED, "BCM_RX_HC_UNSPECIFIED"},
+	{BCM_RX_HC_UNICAST_DECRYPT_FAIL, "BCM_RX_HC_UNICAST_DECRYPT_FAIL"},
+	{BCM_RX_HC_BCMC_DECRYPT_FAIL, "BCM_RX_HC_BCMC_DECRYPT_FAIL"},
+	{BCM_RX_HC_UNICAST_REPLAY, "BCM_RX_HC_UNICAST_REPLAY"},
+	{BCM_RX_HC_BCMC_REPLAY, "BCM_RX_HC_BCMC_REPLAY"},
+	{BCM_RX_HC_AMPDU_DUP, "BCM_RX_HC_AMPDU_DUP"},
+	{0, NULL}
+};
+
+static void
+dhd_print_dongle_hck_id(uint32 id, hck_id_to_str_t *hck)
+{
+	while (hck->name != NULL) {
+		if (hck->id == id) {
+			DHD_ERROR(("DONGLE_HCK_EVENT: %s\n", hck->name));
+			return;
+		}
+		hck++;
+	}
+}
+
+void
+dhd_parse_hck_common_sw_event(bcm_xtlv_t *wl_hc)
+{
+
+	wl_rx_hc_info_v2_t *hck_rx_stall_v2;
+	uint16 id;
+
+	id = ltoh16(wl_hc->id);
+
+	if (id == WL_HC_DD_RX_STALL_V2) {
+		/*  map the hck_rx_stall_v2 structure to the value of the XTLV */
+		hck_rx_stall_v2 =
+			(wl_rx_hc_info_v2_t*)wl_hc;
+		DHD_ERROR(("type:%d len:%d if_idx:%d ac:%d pkts:%d"
+			" drop:%d alert_th:%d reason:%d peer_ea:"MACF"\n",
+			hck_rx_stall_v2->type,
+			hck_rx_stall_v2->length,
+			hck_rx_stall_v2->if_idx,
+			hck_rx_stall_v2->ac,
+			hck_rx_stall_v2->rx_hc_pkts,
+			hck_rx_stall_v2->rx_hc_dropped_all,
+			hck_rx_stall_v2->rx_hc_alert_th,
+			hck_rx_stall_v2->reason,
+			ETHER_TO_MACF(hck_rx_stall_v2->peer_ea)));
+		dhd_print_dongle_hck_id(
+				ltoh32(hck_rx_stall_v2->reason),
+				hck_rx_stall_v2_to_str);
+	} else {
+		dhd_print_dongle_hck_id(ltoh16(wl_hc->id),
+				hck_sw_id_to_str);
+	}
+
+}
+
+#endif /* PARSE_DONGLE_HOST_EVENT */
+#ifdef HCHK_COMMON_SW_EVENT
+#ifdef WL_CFGVENDOR_SEND_ALERT_EVENT
+static void
+dhd_send_error_alert_event(dhd_pub_t *dhdp, bcm_xtlv_t *wl_hc)
+{
+	uint16 id;
+
+	id = ltoh16(wl_hc->id);
+
+	switch (id) {
+		case WL_HC_DD_RX_STALL:
+			dhdp->alert_reason = ALERT_RX_STALL;
+			break;
+		case WL_HC_DD_TX_STALL:
+			dhdp->alert_reason = ALERT_TX_STALL;
+			break;
+		case WL_HC_DD_SCAN_STALL:
+			dhdp->alert_reason = ALERT_SCAN_STALL;
+			break;
+		case WL_HC_DD_TXQ_STALL:
+			dhdp->alert_reason = ALERT_FW_QUEUE_STALL;
+			break;
+		default:
+			return;
+	}
+	dhd_os_send_alert_message(dhdp);
+}
+#endif /* WL_CFGVENDOR_SEND_ALERT_EVENT */
+#endif /* HCHK_COMMON_SW_EVENT */
+
+void
+dngl_host_event_process(dhd_pub_t *dhdp, bcm_dngl_event_t *event,
+	bcm_dngl_event_msg_t *dngl_event, size_t pktlen)
+{
+	uint8 *p = (uint8 *)(event + 1);
+	uint16 type = ntoh16_ua((void *)&dngl_event->event_type);
+	uint16 datalen = ntoh16_ua((void *)&dngl_event->datalen);
+	uint16 version = ntoh16_ua((void *)&dngl_event->version);
+	bool ignore_hc = FALSE;
+
+	DHD_EVENT(("VERSION:%d, EVENT TYPE:%d, DATALEN:%d\n", version, type, datalen));
+	if (datalen > (pktlen - sizeof(bcm_dngl_event_t) + ETHER_TYPE_LEN)) {
+		return;
+	}
+	if (version != BCM_DNGL_EVENT_MSG_VERSION) {
+		DHD_ERROR(("%s:version mismatch:%d:%d\n", __FUNCTION__,
+			version, BCM_DNGL_EVENT_MSG_VERSION));
+		return;
+	}
+	switch (type) {
+	   case DNGL_E_SOCRAM_IND:
+		{
+		   bcm_dngl_socramind_t *socramind_ptr = (bcm_dngl_socramind_t *)p;
+		   uint16 tag = ltoh32(socramind_ptr->tag);
+		   uint16 taglen = ltoh32(socramind_ptr->length);
+		   p = (uint8 *)socramind_ptr->value;
+		   DHD_EVENT(("Tag:%d Len:%d Datalen:%d\n", tag, taglen, datalen));
+		   switch (tag) {
+			case SOCRAM_IND_ASSERT_TAG:
+			    {
+				/*
+				* The payload consists of -
+				* null terminated function name padded till 32 bit boundary +
+				* Line number - (32 bits)
+				* Caller address (32 bits)
+				*/
+				char *fnname = (char *)p;
+				if (datalen < (ROUNDUP(strlen(fnname) + 1, sizeof(uint32)) +
+					sizeof(uint32) * 2)) {
+					DHD_ERROR(("Wrong length:%d\n", datalen));
+					return;
+				}
+				DHD_EVENT(("ASSRT Function:%s ", p));
+				p += ROUNDUP(strlen(p) + 1, sizeof(uint32));
+				DHD_EVENT(("Line:%d ", *(uint32 *)p));
+				p += sizeof(uint32);
+				DHD_EVENT(("Caller Addr:0x%x\n", *(uint32 *)p));
+#ifdef PARSE_DONGLE_HOST_EVENT
+				DHD_ERROR(("DONGLE_HCK_EVENT: SOCRAM_IND_ASSERT_TAG\n"));
+#endif /* PARSE_DONGLE_HOST_EVENT */
+				break;
+			    }
+			case SOCRAM_IND_TAG_HEALTH_CHECK:
+			   {
+				bcm_dngl_healthcheck_t *dngl_hc = (bcm_dngl_healthcheck_t *)p;
+				DHD_EVENT(("SOCRAM_IND_HEALTHCHECK_TAG:%d Len:%d datalen:%d\n",
+					ltoh32(dngl_hc->top_module_tag),
+					ltoh32(dngl_hc->top_module_len),
+					datalen));
+				if (DHD_EVENT_ON()) {
+					prhex("HEALTHCHECK", p, MIN(ltoh32(dngl_hc->top_module_len)
+						+ BCM_XTLV_HDR_SIZE, datalen));
+				}
+#ifdef DHD_LOG_DUMP
+				memset(dhdp->health_chk_event_data, 0, HEALTH_CHK_BUF_SIZE);
+				memcpy(dhdp->health_chk_event_data, p,
+						MIN(ltoh32(dngl_hc->top_module_len),
+						HEALTH_CHK_BUF_SIZE));
+#endif /* DHD_LOG_DUMP */
+				p = (uint8 *)dngl_hc->value;
+
+				switch (ltoh32(dngl_hc->top_module_tag)) {
+					case HEALTH_CHECK_TOP_LEVEL_MODULE_PCIEDEV_RTE:
+					   {
+						bcm_dngl_pcie_hc_t *pcie_hc;
+						pcie_hc = (bcm_dngl_pcie_hc_t *)p;
+						BCM_REFERENCE(pcie_hc);
+						if (ltoh32(dngl_hc->top_module_len) <
+								sizeof(bcm_dngl_pcie_hc_t)) {
+							DHD_ERROR(("Wrong length:%d\n",
+								ltoh32(dngl_hc->top_module_len)));
+							return;
+						}
+						DHD_EVENT(("%d:PCIE HC error:%d flag:0x%x,"
+							" control:0x%x\n",
+							ltoh32(pcie_hc->version),
+							ltoh32(pcie_hc->pcie_err_ind_type),
+							ltoh32(pcie_hc->pcie_flag),
+							ltoh32(pcie_hc->pcie_control_reg)));
+#ifdef PARSE_DONGLE_HOST_EVENT
+						dhd_print_dongle_hck_id(
+							ltoh32(pcie_hc->pcie_err_ind_type),
+								hck_pcie_module_to_str);
+#endif /* PARSE_DONGLE_HOST_EVENT */
+						break;
+					   }
+#ifdef HCHK_COMMON_SW_EVENT
+					case HCHK_SW_ENTITY_WL_PRIMARY:
+					case HCHK_SW_ENTITY_WL_SECONDARY:
+					{
+						bcm_xtlv_t *wl_hc = (bcm_xtlv_t*)p;
+
+						if (ltoh32(dngl_hc->top_module_len) <
+								sizeof(bcm_xtlv_t)) {
+							DHD_ERROR(("WL SW HC Wrong length:%d\n",
+								ltoh32(dngl_hc->top_module_len)));
+							return;
+						}
+						BCM_REFERENCE(wl_hc);
+						DHD_EVENT(("WL SW HC type %d len %d\n",
+						ltoh16(wl_hc->id), ltoh16(wl_hc->len)));
+#ifdef DHD_LB_STATS
+						if ((ltoh16(wl_hc->id) == WL_HC_DD_RX_DMA_STALL) &&
+							(dhdp->lb_rxp_stop_thr_hitcnt >
+							dhdp->lb_rxp_strt_thr_hitcnt)) {
+							ignore_hc = TRUE;
+							dhdp->rx_dma_stall_hc_ignore_cnt++;
+							DHD_ERROR(("%s:lb_rxp_stop_thr_hitcnt(%llu)"
+								" > lb_rxp_strt_thr_hitcnt(%llu)"
+								" rx_dma_stall_hc_ignore_cnt(%llu)"
+								"\n",
+								__FUNCTION__,
+								dhdp->lb_rxp_stop_thr_hitcnt,
+								dhdp->lb_rxp_strt_thr_hitcnt,
+								dhdp->rx_dma_stall_hc_ignore_cnt));
+						}
+#endif /* DHD_LB_STATS */
+
+#ifdef PARSE_DONGLE_HOST_EVENT
+						dhd_parse_hck_common_sw_event(wl_hc);
+#endif /* PARSE_DONGLE_HOST_EVENT */
+#ifdef WL_CFGVENDOR_SEND_ALERT_EVENT
+						dhd_send_error_alert_event(dhdp, wl_hc);
+#endif /* WL_CFGVENDOR_SEND_ALERT_EVENT */
+						break;
+
+					}
+#endif /* HCHK_COMMON_SW_EVENT */
+					default:
+					{
+						DHD_ERROR(("%s:Unknown module TAG:%d\n",
+						  __FUNCTION__,
+						  ltoh32(dngl_hc->top_module_tag)));
+						break;
+					}
+				}
+				break;
+			   }
+			default:
+			   DHD_ERROR(("%s:Unknown TAG\n", __FUNCTION__));
+			   if (p && DHD_EVENT_ON()) {
+				   prhex("SOCRAMIND", p, taglen);
+			   }
+			   break;
+		   }
+		   break;
+		}
+	case DNGL_E_SPMI_RESET_IND:
+		{
+			bcm_dngl_spmi_reset_ind_v1_t *spmi_reset_ind_v1_ptr =
+				(bcm_dngl_spmi_reset_ind_v1_t *)p;
+			uint16 ver = ltoh32(spmi_reset_ind_v1_ptr->version);
+			switch (ver) {
+			case DNGL_E_SPMI_RESET_IND_VERSION_1:
+			{
+				uint16 num_resets = ltoh32(spmi_reset_ind_v1_ptr->num_resets);
+				uint16 slave_idx = ltoh32(spmi_reset_ind_v1_ptr->slave_idx);
+				UNUSED_PARAMETER(num_resets);
+				UNUSED_PARAMETER(slave_idx);
+				DHD_EVENT(("DNGL_E_SPMI_RESET_IND resets=%u SPMI core=%u\n",
+					num_resets, slave_idx));
+				break;
+			}
+			default:
+				DHD_ERROR(("DNGL_E_SPMI_RESET_IND: unknown version\n"));
+				break;
+			}
+			break;
+		}
+	   default:
+		DHD_ERROR(("%s:Unknown DNGL Event Type:%d\n", __FUNCTION__, type));
+		if (p && DHD_EVENT_ON()) {
+			prhex("SOCRAMIND", p, datalen);
+		}
+		break;
+	}
+
+	/* Skip socram collection if ignore_hc is set */
+	if (!ignore_hc) {
+#ifndef BCMDBUS
+#ifdef DHD_FW_COREDUMP
+		if (dhdp->memdump_enabled) {
+			dhdp->memdump_type = DUMP_TYPE_DONGLE_HOST_EVENT;
+			if (
+#ifdef GDB_PROXY
+				!dhdp->gdb_proxy_active &&
+#endif /* GDB_PROXY */
+				dhd_schedule_socram_dump(dhdp)) {
+					DHD_ERROR(("%s: socram dump failed\n", __FUNCTION__));
+			}
+		}
+#else
+		dhd_dbg_send_urgent_evt(dhdp, p, datalen);
+#endif /* DHD_FW_COREDUMP */
+#endif /* !BCMDBUS */
+	}
+
+}
+
+#endif /* DNGL_EVENT_SUPPORT */
+
+/* Stub for now. Will become real function as soon as shim
+ * is being integrated to Android, Linux etc.
+ */
+#if !defined(NDIS)
+int
+wl_event_process_default(wl_event_msg_t *event, struct wl_evt_pport *evt_pport)
+{
+	return BCME_OK;
+}
+#endif
+
+int
+wl_event_process(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata,
+	uint pktlen, void **data_ptr, void *raw_event)
+{
+	wl_evt_pport_t evt_pport;
+	wl_event_msg_t event;
+	bcm_event_msg_u_t evu;
+	int ret;
+
+	/* make sure it is a BRCM event pkt and record event data */
+	ret = wl_host_event_get_data(pktdata, pktlen, &evu);
+	if (ret != BCME_OK) {
+		return ret;
+	}
+
+	memcpy(&event, &evu.event, sizeof(wl_event_msg_t));
+
+	/* convert event from network order to host order */
+	wl_event_to_host_order(&event);
+
+	/* record event params to evt_pport */
+	evt_pport.dhd_pub = dhd_pub;
+	evt_pport.ifidx = ifidx;
+	evt_pport.pktdata = pktdata;
+	evt_pport.data_ptr = data_ptr;
+	evt_pport.raw_event = raw_event;
+	evt_pport.data_len = pktlen;
+
+#if defined(WL_WLC_SHIM) && defined(WL_WLC_SHIM_EVENTS)
+	{
+		struct wl_shim_node *shim = dhd_pub_shim(dhd_pub);
+		if (shim) {
+			ret = wl_shim_event_process(shim, &event, &evt_pport);
+		} else {
+			/* events can come even before shim is initialized
+			 (when waiting for "wlc_ver" response)
+			 * handle them in a non-shim way.
+			 */
+			DHD_ERROR(("%s: Events coming before shim initialization!\n",
+				__FUNCTION__));
+			ret = wl_event_process_default(&event, &evt_pport);
+		}
+	}
+#else
+	ret = wl_event_process_default(&event, &evt_pport);
+#endif /* WL_WLC_SHIM && WL_WLC_SHIM_EVENTS */
+
+	return ret;
+} /* wl_event_process */
+
+/* Check whether packet is a BRCM event pkt. If it is, record event data. */
+int
+wl_host_event_get_data(void *pktdata, uint pktlen, bcm_event_msg_u_t *evu)
+{
+	int ret;
+
+	ret = is_wlc_event_frame(pktdata, pktlen, 0, evu);
+	if (ret != BCME_OK) {
+		DHD_ERROR(("%s: Invalid event frame, err = %d\n",
+			__FUNCTION__, ret));
+	}
+
+	return ret;
+}
+
+int
+wl_process_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, uint pktlen,
+	wl_event_msg_t *event, void **data_ptr, void *raw_event)
+{
+	bcm_event_t *pvt_data = (bcm_event_t *)pktdata;
+	bcm_event_msg_u_t evu;
+	uint8 *event_data;
+	uint32 type, status, datalen, reason;
+	uint16 flags;
+	uint evlen;
+	int ret = BCME_OK;
+	uint16 usr_subtype;
+#if defined(__linux__)
+	dhd_if_t *ifp = NULL;
+	BCM_REFERENCE(ifp);
+#endif /* DHD_POST_EAPOL_M1_AFTER_ROAM_EVT */
+
+	ret = wl_host_event_get_data(pktdata, pktlen, &evu);
+	if (ret != BCME_OK) {
+		return ret;
+	}
+
+	usr_subtype = ntoh16_ua((void *)&pvt_data->bcm_hdr.usr_subtype);
+	switch (usr_subtype) {
+	case BCMILCP_BCM_SUBTYPE_EVENT:
+		memcpy(event, &evu.event, sizeof(wl_event_msg_t));
+		*data_ptr = &pvt_data[1];
+		break;
+	case BCMILCP_BCM_SUBTYPE_DNGLEVENT:
+#ifdef DNGL_EVENT_SUPPORT
+		/* If it is a DNGL event process it first */
+		if (dngl_host_event(dhd_pub, pktdata, &evu.dngl_event, pktlen) == BCME_OK) {
+			/*
+			 * Return error purposely to prevent DNGL event being processed
+			 * as BRCM event
+			 */
+			return BCME_ERROR;
+		}
+#endif /* DNGL_EVENT_SUPPORT */
+		return BCME_NOTFOUND;
+	default:
+		return BCME_NOTFOUND;
+	}
+
+	/* start wl_event_msg process */
+	event_data = *data_ptr;
+	type = ntoh32_ua((void *)&event->event_type);
+	flags = ntoh16_ua((void *)&event->flags);
+	status = ntoh32_ua((void *)&event->status);
+	reason = ntoh32_ua((void *)&event->reason);
+	datalen = ntoh32_ua((void *)&event->datalen);
+	evlen = datalen + sizeof(bcm_event_t);
+
+	switch (type) {
+#ifdef PROP_TXSTATUS
+	case WLC_E_FIFO_CREDIT_MAP:
+		dhd_wlfc_enable(dhd_pub);
+		dhd_wlfc_FIFOcreditmap_event(dhd_pub, event_data);
+		WLFC_DBGMESG(("WLC_E_FIFO_CREDIT_MAP:(AC0,AC1,AC2,AC3),(BC_MC),(OTHER): "
+			"(%d,%d,%d,%d),(%d),(%d)\n", event_data[0], event_data[1],
+			event_data[2],
+			event_data[3], event_data[4], event_data[5]));
+		break;
+
+	case WLC_E_BCMC_CREDIT_SUPPORT:
+		dhd_wlfc_BCMCCredit_support_event(dhd_pub);
+		break;
+#ifdef LIMIT_BORROW
+	case WLC_E_ALLOW_CREDIT_BORROW:
+		dhd_wlfc_disable_credit_borrow_event(dhd_pub, event_data);
+		break;
+#endif /* LIMIT_BORROW */
+#endif /* PROP_TXSTATUS */
+
+	case WLC_E_ULP:
+		break;
+	case WLC_E_TDLS_PEER_EVENT:
+#if defined(WLTDLS) && defined(PCIE_FULL_DONGLE)
+		{
+			dhd_tdls_event_handler(dhd_pub, event);
+		}
+#endif
+		break;
+
+	case WLC_E_IF:
+		{
+		struct wl_event_data_if *ifevent = (struct wl_event_data_if *)event_data;
+#if defined(__linux__)
+		struct net_device *ndev = NULL;
+#endif /* __linux__ */
+
+		/* Ignore the event if NOIF is set */
+		if (ifevent->reserved & WLC_E_IF_FLAGS_BSSCFG_NOIF) {
+			DHD_ERROR(("WLC_E_IF: NO_IF set, event Ignored\r\n"));
+			return (BCME_UNSUPPORTED);
+		}
+#ifdef PCIE_FULL_DONGLE
+		dhd_update_interface_flow_info(dhd_pub, ifevent->ifidx,
+			ifevent->opcode, ifevent->role);
+#endif
+#ifdef PROP_TXSTATUS
+		{
+			uint8* ea = pvt_data->eth.ether_dhost;
+			WLFC_DBGMESG(("WLC_E_IF: idx:%d, action:%s, iftype:%s, ["MACDBG"]\n",
+				ifevent->ifidx,
+				((ifevent->opcode == WLC_E_IF_ADD) ? "ADD":"DEL"),
+				((ifevent->role == 0) ? "STA":"AP "),
+				MAC2STRDBG(ea)));
+			(void)ea;
+
+			if (ifevent->opcode == WLC_E_IF_CHANGE)
+				dhd_wlfc_interface_event(dhd_pub,
+					eWLFC_MAC_ENTRY_ACTION_UPDATE,
+					ifevent->ifidx, ifevent->role, ea);
+			else {
+#if defined(__linux__)
+				/* Early set interface "del_in_progress" to prevent from packets
+				 * flooding to interface which is going to be removed. That would
+				 * cause proptx transit_count not consistent and has entry
+				 * suppressed issue.
+				 */
+				if (ifevent->opcode == WLC_E_IF_DEL) {
+					unsigned long fl;
+					ifp = dhd_get_ifp(dhd_pub, ifevent->ifidx);
+					if (ifp && !ifp->static_if) {
+						DHD_GENERAL_LOCK(dhd_pub, fl);
+						ifp->del_in_progress = true;
+						DHD_GENERAL_UNLOCK(dhd_pub, fl);
+					}
+				}
+#endif /* __linux__ */
+
+				dhd_wlfc_interface_event(dhd_pub,
+					((ifevent->opcode == WLC_E_IF_ADD) ?
+					eWLFC_MAC_ENTRY_ACTION_ADD : eWLFC_MAC_ENTRY_ACTION_DEL),
+					ifevent->ifidx, ifevent->role, ea);
+			}
+
+			/* dhd already has created an interface by default, for 0 */
+			if (ifevent->ifidx == 0)
+				break;
+		}
+#endif /* PROP_TXSTATUS */
+
+		if (ifevent->ifidx > 0 && ifevent->ifidx < DHD_MAX_IFS) {
+			if (ifevent->opcode == WLC_E_IF_ADD) {
+				if (dhd_event_ifadd(dhd_pub->info, ifevent, event->ifname,
+					event->addr.octet)) {
+
+					DHD_ERROR(("%s: dhd_event_ifadd failed ifidx: %d  %s\n",
+						__FUNCTION__, ifevent->ifidx, event->ifname));
+					return (BCME_ERROR);
+				}
+#if defined(__linux__)
+				ndev = dhd_idx2net(dhd_pub, ifevent->ifidx);
+				if (ndev) {
+					dhd_clear_del_in_progress(dhd_pub, ndev);
+				}
+#endif /* __linux__ */
+			} else if (ifevent->opcode == WLC_E_IF_DEL) {
+#if defined(__linux__)
+				ndev = dhd_idx2net(dhd_pub, ifevent->ifidx);
+				if (ndev) {
+					dhd_set_del_in_progress(dhd_pub, ndev);
+					netif_tx_disable(ndev);
+				}
+#endif /* __linux__ */
+#ifdef PCIE_FULL_DONGLE
+				dhd_flow_rings_delete(dhd_pub,
+					(uint8)dhd_ifname2idx(dhd_pub->info, event->ifname));
+#endif /* PCIE_FULL_DONGLE */
+				dhd_event_ifdel(dhd_pub->info, ifevent, event->ifname,
+					event->addr.octet);
+			} else if (ifevent->opcode == WLC_E_IF_CHANGE) {
+#ifdef WL_CFG80211
+				dhd_event_ifchange(dhd_pub->info, ifevent, event->ifname,
+					event->addr.octet);
+#endif /* WL_CFG80211 */
+			}
+		} else {
+#if !defined(PROP_TXSTATUS) && !defined(PCIE_FULL_DONGLE) && defined(WL_CFG80211)
+			DHD_INFO(("%s: Invalid ifidx %d for %s\n",
+			   __FUNCTION__, ifevent->ifidx, event->ifname));
+#endif /* !PROP_TXSTATUS && !PCIE_FULL_DONGLE && WL_CFG80211 */
+		}
+			/* send up the if event: btamp user needs it */
+			*ifidx = dhd_ifname2idx(dhd_pub->info, event->ifname);
+			/* push up to external supp/auth */
+			dhd_event(dhd_pub->info, (char *)pvt_data, evlen, *ifidx);
+		break;
+	}
+
+	case WLC_E_NDIS_LINK:
+		break;
+	case WLC_E_PFN_NET_FOUND:
+	case WLC_E_PFN_SCAN_ALLGONE: /* share with WLC_E_PFN_BSSID_NET_LOST */
+	case WLC_E_PFN_NET_LOST:
+		break;
+#if defined(OEM_ANDROID) && defined(PNO_SUPPORT)
+	case WLC_E_PFN_BSSID_NET_FOUND:
+	case WLC_E_PFN_BEST_BATCHING:
+		dhd_pno_event_handler(dhd_pub, event, (void *)event_data);
+		break;
+#endif /* #if defined(OEM_ANDROID) && defined(PNO_SUPPORT) */
+#if defined(RTT_SUPPORT)
+	case WLC_E_PROXD:
+#ifndef WL_CFG80211
+#endif /* WL_CFG80211 */
+		break;
+#endif /* RTT_SUPPORT */
+		/* These are what external supplicant/authenticator wants */
+	case WLC_E_ASSOC_IND:
+	case WLC_E_AUTH_IND:
+	case WLC_E_REASSOC_IND:
+		dhd_findadd_sta(dhd_pub,
+			dhd_ifname2idx(dhd_pub->info, event->ifname),
+			&event->addr.octet);
+		break;
+#if !defined(BCMDBUS) && defined(DHD_FW_COREDUMP)
+	case WLC_E_PSM_WATCHDOG:
+		DHD_ERROR(("%s: WLC_E_PSM_WATCHDOG event received : \n", __FUNCTION__));
+		if (dhd_socram_dump(dhd_pub->bus) != BCME_OK) {
+			DHD_ERROR(("%s: socram dump ERROR : \n", __FUNCTION__));
+		}
+	break;
+#endif
+#ifdef DHD_WMF
+	case WLC_E_PSTA_PRIMARY_INTF_IND:
+		dhd_update_psta_interface_for_sta(dhd_pub, event->ifname,
+			(void *)(event->addr.octet), (void*) event_data);
+		break;
+#endif
+#ifdef BCM_ROUTER_DHD
+	case WLC_E_DPSTA_INTF_IND:
+		dhd_update_dpsta_interface_for_sta(dhd_pub, (uint8)dhd_ifname2idx(dhd_pub->info,
+			event->ifname), (void*) event_data);
+		break;
+#endif /* BCM_ROUTER_DHD */
+#if defined(DHD_MACDBG) && defined(BCMDBG)
+	case WLC_E_MACDBG:
+		dhd_macdbg_event_handler(dhd_pub, reason, event_data, datalen);
+		break;
+#endif /* defined(DHD_MACDBG) && defined(BCMDBG) */
+	case WLC_E_NATOE_NFCT:
+	break;
+	case WLC_E_SLOTTED_BSS_PEER_OP:
+		DHD_EVENT(("%s: WLC_E_SLOTTED_BSS_PEER_OP event received for peer: "
+			"" MACDBG ", status = %d\n",
+			__FUNCTION__, MAC2STRDBG(event->addr.octet), status));
+		if (status == WLC_E_STATUS_SLOTTED_PEER_ADD) {
+			dhd_findadd_sta(dhd_pub, dhd_ifname2idx(dhd_pub->info,
+				event->ifname), &event->addr.octet);
+		} else if (status == WLC_E_STATUS_SLOTTED_PEER_DEL) {
+			uint8 ifindex = (uint8)dhd_ifname2idx(dhd_pub->info, event->ifname);
+			BCM_REFERENCE(ifindex);
+			dhd_del_sta(dhd_pub, dhd_ifname2idx(dhd_pub->info,
+				event->ifname), &event->addr.octet);
+#ifdef PCIE_FULL_DONGLE
+			dhd_flow_rings_delete_for_peer(dhd_pub, ifindex,
+				(char *)&event->addr.octet[0]);
+#endif
+		} else {
+			DHD_ERROR(("%s: WLC_E_SLOTTED_BSS_PEER_OP: Status is not expected = %d\n",
+				__FUNCTION__, status));
+		}
+		break;
+#ifdef DHD_POST_EAPOL_M1_AFTER_ROAM_EVT
+	case WLC_E_REASSOC:
+		ifp = dhd_get_ifp(dhd_pub, event->ifidx);
+
+		if (!ifp)
+			break;
+
+		/* Consider both STA and GC due to CSA.
+		 * Drop EAPOL M1 frame only if roam is done to the same BSSID.
+		 * wpa_supplicant only handles different BSSID case.
+		 */
+		if ((status == WLC_E_STATUS_SUCCESS) &&
+			(IS_STA_IFACE(ndev_to_wdev(ifp->net)) ||
+			IS_P2P_GC(ndev_to_wdev(ifp->net))) &&
+			wl_cfg80211_is_event_from_connected_bssid(ifp->net, event, event->ifidx)) {
+			ifp->recv_reassoc_evt = TRUE;
+		}
+		break;
+#endif /* DHD_POST_EAPOL_M1_AFTER_ROAM_EVT */
+	case WLC_E_LINK:
+#ifdef PCIE_FULL_DONGLE
+		if (dhd_update_interface_link_status(dhd_pub, (uint8)dhd_ifname2idx(dhd_pub->info,
+			event->ifname), (uint8)flags) != BCME_OK) {
+			DHD_ERROR(("%s: dhd_update_interface_link_status Failed.\n",
+				__FUNCTION__));
+			break;
+		}
+		if (!flags) {
+			DHD_ERROR(("%s: Deleting all STA from assoc list and flowrings.\n",
+				__FUNCTION__));
+			/* Delete all sta and flowrings */
+			dhd_del_all_sta(dhd_pub, dhd_ifname2idx(dhd_pub->info, event->ifname));
+			dhd_flow_rings_delete(dhd_pub, (uint8)dhd_ifname2idx(dhd_pub->info,
+				event->ifname));
+		}
+#else
+#ifdef PROP_TXSTATUS
+		/* Link up */
+		if (flags) {
+			struct wl_event_data_if *ifevent = (struct wl_event_data_if *)event_data;
+			uint8* ea = pvt_data->eth.ether_dhost;
+			uint8 ifindex = (uint8)dhd_ifname2idx(dhd_pub->info, event->ifname);
+			DHD_ERROR(("WLC_E_LINK: idx:%d, action:%s, "
+			              "iftype:%s, ["MACDBG"]\n",
+			              ifevent->ifidx,
+			              ((flags) ? "UP":"DOWN"),
+			              ((ifevent->role == 0) ? "STA":"AP "),
+			              MAC2STRDBG(ea)));
+			(void)ea;
+
+			/* only need to handle STA here */
+			if (!ifevent->role) {
+				dhd_wlfc_interface_event(dhd_pub,
+					eWLFC_MAC_ENTRY_ACTION_DEL,
+					ifindex, ifevent->role, ea);
+				dhd_wlfc_interface_event(dhd_pub,
+					eWLFC_MAC_ENTRY_ACTION_ADD,
+					ifindex, ifevent->role, ea);
+			}
+		}
+#endif /* PROP_TXSTATUS */
+#endif /* PCIE_FULL_DONGLE */
+
+		/* fall through */
+		fallthrough;
+	case WLC_E_DEAUTH:
+	case WLC_E_DEAUTH_IND:
+	case WLC_E_DISASSOC:
+	case WLC_E_DISASSOC_IND:
+#ifdef PCIE_FULL_DONGLE
+		if (type != WLC_E_LINK) {
+			uint8 ifindex = (uint8)dhd_ifname2idx(dhd_pub->info, event->ifname);
+			uint8 role = dhd_flow_rings_ifindex2role(dhd_pub, ifindex);
+			uint8 del_sta = TRUE;
+#ifdef WL_CFG80211
+			if (role == WLC_E_IF_ROLE_STA &&
+				!wl_cfg80211_is_roam_offload(dhd_idx2net(dhd_pub, ifindex)) &&
+					!wl_cfg80211_is_event_from_connected_bssid(
+						dhd_idx2net(dhd_pub, ifindex), event, *ifidx)) {
+				del_sta = FALSE;
+			}
+#endif /* WL_CFG80211 */
+			DHD_EVENT(("%s: Link event %d, flags %x, status %x, "
+				"reason=%d, role %d, del_sta %d\n",
+				__FUNCTION__, type, flags, status,
+				reason, role, del_sta));
+
+			if (del_sta) {
+				DHD_EVENT(("%s: Deleting STA " MACDBG "\n",
+					__FUNCTION__, MAC2STRDBG(event->addr.octet)));
+
+				dhd_del_sta(dhd_pub, dhd_ifname2idx(dhd_pub->info,
+					event->ifname), &event->addr.octet);
+				/* Delete all flowrings for STA and P2P Client */
+				if (role == WLC_E_IF_ROLE_STA || role == WLC_E_IF_ROLE_P2P_CLIENT) {
+					dhd_flow_rings_delete(dhd_pub, ifindex);
+				} else {
+					dhd_flow_rings_delete_for_peer(dhd_pub, ifindex,
+						(char *)&event->addr.octet[0]);
+				}
+			}
+		}
+#endif /* PCIE_FULL_DONGLE */
+#ifdef DHD_POST_EAPOL_M1_AFTER_ROAM_EVT
+		ifp = dhd_get_ifp(dhd_pub, event->ifidx);
+		if (ifp) {
+			ifp->recv_reassoc_evt = FALSE;
+			ifp->post_roam_evt = FALSE;
+		}
+#endif /* DHD_POST_EAPOL_M1_AFTER_ROAM_EVT */
+		/* fall through */
+		fallthrough;
+	default:
+		*ifidx = dhd_ifname2idx(dhd_pub->info, event->ifname);
+#ifdef DHD_UPDATE_INTF_MAC
+		if ((WLC_E_LINK==type)&&(WLC_EVENT_MSG_LINK&flags)) {
+			dhd_event_ifchange(dhd_pub->info,
+			(struct wl_event_data_if *)event,
+			event->ifname,
+			event->addr.octet);
+		}
+#endif /* DHD_UPDATE_INTF_MAC */
+		/* push up to external supp/auth */
+		dhd_event(dhd_pub->info, (char *)pvt_data, evlen, *ifidx);
+		DHD_TRACE(("%s: MAC event %d, flags %x, status %x\n",
+			__FUNCTION__, type, flags, status));
+		BCM_REFERENCE(flags);
+		BCM_REFERENCE(status);
+		BCM_REFERENCE(reason);
+
+		break;
+	}
+#if defined(BCM_ROUTER_DHD) || defined(STBAP)
+	/* For routers, EAPD will be working on these events.
+	 * Overwrite interface name to that event is pushed
+	 * to host with its registered interface name
+	 */
+	memcpy(pvt_data->event.ifname, dhd_ifname(dhd_pub, *ifidx), IFNAMSIZ);
+#endif
+
+#ifdef DHD_STATUS_LOGGING
+	if (dhd_pub->statlog) {
+		dhd_statlog_process_event(dhd_pub, type, *ifidx,
+			status, reason, flags);
+	}
+#endif /* DHD_STATUS_LOGGING */
+
+#ifdef SHOW_EVENTS
+	if (DHD_FWLOG_ON() || DHD_EVENT_ON()) {
+		wl_show_host_event(dhd_pub, event,
+			(void *)event_data, raw_event, dhd_pub->enable_log);
+	}
+#endif /* SHOW_EVENTS */
+
+	return (ret);
+} /* wl_process_host_event */
+
+int
+wl_host_event(dhd_pub_t *dhd_pub, int *ifidx, void *pktdata, uint pktlen,
+	wl_event_msg_t *event, void **data_ptr, void *raw_event)
+{
+	return wl_process_host_event(dhd_pub, ifidx, pktdata, pktlen, event, data_ptr,
+			raw_event);
+}
+
+void
+dhd_print_buf(void *pbuf, int len, int bytes_per_line)
+{
+#ifdef DHD_DEBUG
+	int i, j = 0;
+	unsigned char *buf = pbuf;
+
+	if (bytes_per_line == 0) {
+		bytes_per_line = len;
+	}
+
+	for (i = 0; i < len; i++) {
+		printf("%2.2x", *buf++);
+		j++;
+		if (j == bytes_per_line) {
+			printf("\n");
+			j = 0;
+		} else {
+			printf(":");
+		}
+	}
+	printf("\n");
+#endif /* DHD_DEBUG */
+}
+#ifndef strtoul
+#define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
+#endif
+
+/* Convert user's input in hex pattern to byte-size mask */
+int
+wl_pattern_atoh(char *src, char *dst)
+{
+	int i;
+	if (strncmp(src, "0x", 2) != 0 &&
+	    strncmp(src, "0X", 2) != 0) {
+		DHD_ERROR(("Mask invalid format. Needs to start with 0x\n"));
+		return -1;
+	}
+	src = src + 2; /* Skip past 0x */
+	if (strlen(src) % 2 != 0) {
+		DHD_ERROR(("Mask invalid format. Needs to be of even length\n"));
+		return -1;
+	}
+	for (i = 0; *src != '\0'; i++) {
+		char num[3];
+		bcm_strncpy_s(num, sizeof(num), src, 2);
+		num[2] = '\0';
+		dst[i] = (uint8)strtoul(num, NULL, 16);
+		src += 2;
+	}
+	return i;
+}
+
+#if defined(PKT_FILTER_SUPPORT) || defined(DHD_PKT_LOGGING)
+int
+pattern_atoh_len(char *src, char *dst, int len)
+{
+	int i;
+	if (strncmp(src, "0x", HD_PREFIX_SIZE) != 0 &&
+			strncmp(src, "0X", HD_PREFIX_SIZE) != 0) {
+		DHD_ERROR(("Mask invalid format. Needs to start with 0x\n"));
+		return -1;
+	}
+	src = src + HD_PREFIX_SIZE; /* Skip past 0x */
+	if (strlen(src) % HD_BYTE_SIZE != 0) {
+		DHD_ERROR(("Mask invalid format. Needs to be of even length\n"));
+		return -1;
+	}
+	for (i = 0; *src != '\0'; i++) {
+		char num[HD_BYTE_SIZE + 1];
+
+		if (i > len - 1) {
+			DHD_ERROR(("pattern not in range, idx: %d len: %d\n", i, len));
+			return -1;
+		}
+		bcm_strncpy_s(num, sizeof(num), src, HD_BYTE_SIZE);
+		num[HD_BYTE_SIZE] = '\0';
+		dst[i] = (uint8)strtoul(num, NULL, 16);
+		src += HD_BYTE_SIZE;
+	}
+	return i;
+}
+#endif /* PKT_FILTER_SUPPORT || DHD_PKT_LOGGING */
+
+#ifdef PKT_FILTER_SUPPORT
+
+int
+dhd_pktfilter_mode_change(dhd_pub_t * dhd, int enable)
+{
+	int   rc = 0;
+	uint  operation_mode = PKT_FILTER_MODE_DISABLE;
+
+	operation_mode =  dhd_master_mode
+		| ((enable)?(0):(PKT_FILTER_MODE_DISABLE));
+
+	/* Contorl the master mode */
+	rc = dhd_wl_ioctl_set_intiovar(dhd,
+		"pkt_filter_mode", operation_mode, WLC_SET_VAR, TRUE, 0);
+
+	return rc;
+}
+
+void
+dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode)
+{
+	char				*argv[8];
+	int					i = 0;
+	const char			*str;
+	int					buf_len;
+	int					str_len;
+	char				*arg_save = 0, *arg_org = 0;
+	int					rc;
+	char				buf[32] = {0};
+	wl_pkt_filter_enable_t	enable_parm;
+	wl_pkt_filter_enable_t	* pkt_filterp;
+
+	if (!arg)
+		return;
+
+	if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) {
+		DHD_ERROR(("%s: malloc failed\n", __FUNCTION__));
+		goto fail;
+	}
+	arg_org = arg_save;
+	memcpy(arg_save, arg, strlen(arg) + 1);
+
+	argv[i] = bcmstrtok(&arg_save, " ", 0);
+
+	i = 0;
+	if (argv[i] == NULL) {
+		DHD_ERROR(("No args provided\n"));
+		goto fail;
+	}
+
+	str = "pkt_filter_enable";
+	str_len = strlen(str);
+	bcm_strncpy_s(buf, sizeof(buf) - 1, str, sizeof(buf) - 1);
+	buf[ sizeof(buf) - 1 ] = '\0';
+	buf_len = str_len + 1;
+
+	pkt_filterp = (wl_pkt_filter_enable_t *)(buf + str_len + 1);
+
+	/* Parse packet filter id. */
+	enable_parm.id = htod32(strtoul(argv[i], NULL, 0));
+	if (dhd_conf_del_pkt_filter(dhd, enable_parm.id))
+		goto fail;
+
+	/* Parse enable/disable value. */
+	enable_parm.enable = htod32(enable);
+
+	buf_len += sizeof(enable_parm);
+	memcpy((char *)pkt_filterp,
+	       &enable_parm,
+	       sizeof(enable_parm));
+
+	/* Enable/disable the specified filter. */
+	rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0);
+	rc = rc >= 0 ? 0 : rc;
+	if (rc) {
+		DHD_ERROR(("%s: failed to %s pktfilter %s, retcode = %d\n",
+		__FUNCTION__, enable?"enable":"disable", arg, rc));
+		dhd_set_packet_filter(dhd);
+		rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0);
+		rc = rc >= 0 ? 0 : rc;
+		if (rc) {
+			DHD_TRACE_HW4(("%s: 2nd retry failed to add pktfilter %s, retcode = %d\n",
+			__FUNCTION__, arg, rc));
+		} else {
+			DHD_TRACE_HW4(("%s: 2nd retry successfully added pktfilter %s\n",
+			__FUNCTION__, arg));
+		}
+	}
+	else
+		DHD_TRACE(("%s: successfully %s pktfilter %s\n",
+		__FUNCTION__, enable?"enable":"disable", arg));
+
+	/* Contorl the master mode */
+	rc = dhd_wl_ioctl_set_intiovar(dhd, "pkt_filter_mode",
+		master_mode, WLC_SET_VAR, TRUE, 0);
+	rc = rc >= 0 ? 0 : rc;
+	if (rc)
+		DHD_TRACE(("%s: failed to set pkt_filter_mode %d, retcode = %d\n",
+			__FUNCTION__, master_mode, rc));
+
+fail:
+	if (arg_org)
+		MFREE(dhd->osh, arg_org, strlen(arg) + 1);
+}
+
+/* Packet filter section: extended filters have named offsets, add table here */
+typedef struct {
+	char *name;
+	uint16 base;
+} wl_pfbase_t;
+
+static wl_pfbase_t basenames[] = { WL_PKT_FILTER_BASE_NAMES };
+
+static int
+wl_pkt_filter_base_parse(char *name)
+{
+	uint i;
+	char *bname, *uname;
+
+	for (i = 0; i < ARRAYSIZE(basenames); i++) {
+		bname = basenames[i].name;
+		for (uname = name; *uname; bname++, uname++) {
+			if (*bname != bcm_toupper(*uname)) {
+				break;
+			}
+		}
+		if (!*uname && !*bname) {
+			break;
+		}
+	}
+
+	if (i < ARRAYSIZE(basenames)) {
+		return basenames[i].base;
+	} else {
+		return -1;
+	}
+}
+
+void
+dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg)
+{
+	const char			*str;
+	wl_pkt_filter_t			pkt_filter;
+	wl_pkt_filter_t			*pkt_filterp;
+	int				buf_len;
+	int				str_len;
+	int				rc = -1;
+	uint32				mask_size;
+	uint32				pattern_size;
+	char				*argv[MAXPKT_ARG] = {0}, * buf = 0;
+	int				i = 0;
+	char				*arg_save = 0, *arg_org = 0;
+
+	if (!arg)
+		return;
+
+	if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) {
+		DHD_ERROR(("%s: malloc failed\n", __FUNCTION__));
+		goto fail;
+	}
+
+	arg_org = arg_save;
+
+	if (!(buf = MALLOC(dhd->osh, MAX_PKTFLT_BUF_SIZE))) {
+		DHD_ERROR(("%s: malloc failed\n", __FUNCTION__));
+		goto fail;
+	}
+
+	memset(buf, 0, MAX_PKTFLT_BUF_SIZE);
+	memcpy(arg_save, arg, strlen(arg) + 1);
+
+	if (strlen(arg) > MAX_PKTFLT_BUF_SIZE) {
+		DHD_ERROR(("Not enough buffer %d < %d\n", (int)strlen(arg), (int)sizeof(buf)));
+		goto fail;
+	}
+
+	argv[i] = bcmstrtok(&arg_save, " ", 0);
+	while (argv[i++]) {
+		if (i >= MAXPKT_ARG) {
+			DHD_ERROR(("Invalid args provided\n"));
+			goto fail;
+		}
+		argv[i] = bcmstrtok(&arg_save, " ", 0);
+	}
+
+	i = 0;
+	if (argv[i] == NULL) {
+		DHD_ERROR(("No args provided\n"));
+		goto fail;
+	}
+
+	str = "pkt_filter_add";
+	str_len = strlen(str);
+	bcm_strncpy_s(buf, MAX_PKTFLT_BUF_SIZE, str, str_len);
+	buf[ str_len ] = '\0';
+	buf_len = str_len + 1;
+
+	pkt_filterp = (wl_pkt_filter_t *) (buf + str_len + 1);
+
+	/* Parse packet filter id. */
+	pkt_filter.id = htod32(strtoul(argv[i], NULL, 0));
+
+	if (argv[++i] == NULL) {
+		DHD_ERROR(("Polarity not provided\n"));
+		goto fail;
+	}
+
+	/* Parse filter polarity. */
+	pkt_filter.negate_match = htod32(strtoul(argv[i], NULL, 0));
+
+	if (argv[++i] == NULL) {
+		DHD_ERROR(("Filter type not provided\n"));
+		goto fail;
+	}
+
+	/* Parse filter type. */
+	pkt_filter.type = htod32(strtoul(argv[i], NULL, 0));
+
+	if ((pkt_filter.type == 0) || (pkt_filter.type == 1)) {
+		if (argv[++i] == NULL) {
+			DHD_ERROR(("Offset not provided\n"));
+			goto fail;
+		}
+
+		/* Parse pattern filter offset. */
+		pkt_filter.u.pattern.offset = htod32(strtoul(argv[i], NULL, 0));
+
+		if (argv[++i] == NULL) {
+			DHD_ERROR(("Bitmask not provided\n"));
+			goto fail;
+		}
+
+		/* Parse pattern filter mask. */
+		rc  = wl_pattern_atoh(argv[i],
+			(char *) pkt_filterp->u.pattern.mask_and_pattern);
+
+		if (rc == -1) {
+			DHD_ERROR(("Rejecting: %s\n", argv[i]));
+			goto fail;
+		}
+		mask_size = htod32(rc);
+		if (argv[++i] == NULL) {
+			DHD_ERROR(("Pattern not provided\n"));
+			goto fail;
+		}
+
+		/* Parse pattern filter pattern. */
+		rc = wl_pattern_atoh(argv[i],
+			(char *) &pkt_filterp->u.pattern.mask_and_pattern[rc]);
+
+		if (rc == -1) {
+			DHD_ERROR(("Rejecting: %s\n", argv[i]));
+			goto fail;
+		}
+		pattern_size = htod32(rc);
+		if (mask_size != pattern_size) {
+			DHD_ERROR(("Mask and pattern not the same size\n"));
+			goto fail;
+		}
+
+		pkt_filter.u.pattern.size_bytes = mask_size;
+		buf_len += WL_PKT_FILTER_FIXED_LEN;
+		buf_len += (WL_PKT_FILTER_PATTERN_FIXED_LEN + 2 * rc);
+
+		/* Keep-alive attributes are set in local	variable (keep_alive_pkt), and
+		 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
+		 * guarantee that the buffer is properly aligned.
+		 */
+		memcpy((char *)pkt_filterp,
+			&pkt_filter,
+			WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);
+	} else if ((pkt_filter.type == 2) || (pkt_filter.type == 6)) {
+		int list_cnt = 0;
+		char *endptr = NULL;
+		wl_pkt_filter_pattern_listel_t *pf_el =
+			(wl_pkt_filter_pattern_listel_t *)&pkt_filterp->u.patlist.patterns[0];
+
+		while (argv[++i] != NULL) {
+			/* Check valid buffer size. */
+			if ((buf_len + MAX_PKTFLT_FIXED_BUF_SIZE) > MAX_PKTFLT_BUF_SIZE) {
+				DHD_ERROR(("buffer over length MAX_PKTFLT_FIXED_BUF_SIZE\n"));
+				goto fail;
+			}
+
+			/* Parse pattern filter base and offset. */
+			if (bcm_isdigit(*argv[i])) {
+				/* Numeric base */
+				rc = strtoul(argv[i], &endptr, 0);
+			} else {
+				endptr = strchr(argv[i], ':');
+				if (endptr) {
+					*endptr = '\0';
+					rc = wl_pkt_filter_base_parse(argv[i]);
+					if (rc == -1) {
+						DHD_ERROR(("Invalid base %s\n", argv[i]));
+						goto fail;
+					}
+					*endptr = ':';
+				}
+			}
+
+			if (endptr == NULL) {
+				DHD_ERROR(("Invalid [base:]offset format: %s\n", argv[i]));
+				goto fail;
+			}
+
+			if (*endptr == ':') {
+				pf_el->base_offs = htod16(rc);
+				rc = strtoul(endptr + 1, &endptr, 0);
+			} else {
+				/* Must have had a numeric offset only */
+				pf_el->base_offs = htod16(0);
+			}
+
+			if (*endptr) {
+				DHD_ERROR(("Invalid [base:]offset format: %s\n", argv[i]));
+				goto fail;
+			}
+			if (rc > 0x0000FFFF) {
+				DHD_ERROR(("Offset too large\n"));
+				goto fail;
+			}
+			pf_el->rel_offs = htod16(rc);
+
+			/* Clear match_flag (may be set in parsing which follows) */
+			pf_el->match_flags = htod16(0);
+
+			/* Parse pattern filter mask and pattern directly into ioctl buffer */
+			if (argv[++i] == NULL) {
+				DHD_ERROR(("Bitmask not provided\n"));
+				goto fail;
+			}
+			rc = wl_pattern_atoh(argv[i], (char*)pf_el->mask_and_data);
+			if ((rc == -1) || (rc > MAX_PKTFLT_FIXED_PATTERN_SIZE)) {
+				DHD_ERROR(("Rejecting: %s\n", argv[i]));
+				goto fail;
+			}
+			mask_size = htod16(rc);
+
+			if (argv[++i] == NULL) {
+				DHD_ERROR(("Pattern not provided\n"));
+				goto fail;
+			}
+
+			endptr = argv[i];
+			if (*endptr == '!') {
+				pf_el->match_flags =
+					htod16(WL_PKT_FILTER_MFLAG_NEG);
+				if (*(++endptr) == '\0') {
+					DHD_ERROR(("Pattern not provided\n"));
+					goto fail;
+				}
+			}
+			rc = wl_pattern_atoh(endptr, (char*)&pf_el->mask_and_data[rc]);
+			if ((rc == -1) || (rc > MAX_PKTFLT_FIXED_PATTERN_SIZE)) {
+				DHD_ERROR(("Rejecting: %s\n", argv[i]));
+				goto fail;
+			}
+			pattern_size = htod16(rc);
+
+			if (mask_size != pattern_size) {
+				DHD_ERROR(("Mask and pattern not the same size\n"));
+				goto fail;
+			}
+
+			pf_el->size_bytes = mask_size;
+
+			/* Account for the size of this pattern element */
+			buf_len += WL_PKT_FILTER_PATTERN_LISTEL_FIXED_LEN + 2 * rc;
+
+			/* Move to next element location in ioctl buffer */
+			pf_el = (wl_pkt_filter_pattern_listel_t*)
+				((uint8*)pf_el + WL_PKT_FILTER_PATTERN_LISTEL_FIXED_LEN + 2 * rc);
+
+			/* Count list element */
+			list_cnt++;
+		}
+
+		/* Account for initial fixed size, and copy initial fixed fields */
+		buf_len += WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_LIST_FIXED_LEN;
+
+		if (buf_len > MAX_PKTFLT_BUF_SIZE) {
+			DHD_ERROR(("buffer over length MAX_PKTFLT_BUF_SIZE\n"));
+			goto fail;
+		}
+
+		/* Update list count and total size */
+		pkt_filter.u.patlist.list_cnt = list_cnt;
+		pkt_filter.u.patlist.PAD1[0] = 0;
+		pkt_filter.u.patlist.totsize = buf + buf_len - (char*)pkt_filterp;
+		pkt_filter.u.patlist.totsize -= WL_PKT_FILTER_FIXED_LEN;
+
+		memcpy((char *)pkt_filterp, &pkt_filter,
+			WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_LIST_FIXED_LEN);
+	} else {
+		DHD_ERROR(("Invalid filter type %d\n", pkt_filter.type));
+		goto fail;
+	}
+
+	rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0);
+	rc = rc >= 0 ? 0 : rc;
+
+	if (rc)
+		DHD_ERROR(("%s: failed to add pktfilter %s, retcode = %d\n",
+		__FUNCTION__, arg, rc));
+	else
+		DHD_TRACE(("%s: successfully added pktfilter %s\n",
+		__FUNCTION__, arg));
+
+fail:
+	if (arg_org)
+		MFREE(dhd->osh, arg_org, strlen(arg) + 1);
+
+	if (buf)
+		MFREE(dhd->osh, buf, MAX_PKTFLT_BUF_SIZE);
+}
+
+void
+dhd_pktfilter_offload_delete(dhd_pub_t *dhd, int id)
+{
+	int ret;
+
+	ret = dhd_wl_ioctl_set_intiovar(dhd, "pkt_filter_delete",
+		id, WLC_SET_VAR, TRUE, 0);
+	if (ret < 0) {
+		DHD_ERROR(("%s: Failed to delete filter ID:%d, ret=%d\n",
+			__FUNCTION__, id, ret));
+	}
+	else
+		DHD_TRACE(("%s: successfully deleted pktfilter %d\n",
+		__FUNCTION__, id));
+}
+#endif /* PKT_FILTER_SUPPORT */
+
+/* ========================== */
+/* ==== ARP OFFLOAD SUPPORT = */
+/* ========================== */
+#ifdef ARP_OFFLOAD_SUPPORT
+void
+dhd_arp_offload_set(dhd_pub_t * dhd, int arp_mode)
+{
+	int retcode;
+
+	retcode = dhd_wl_ioctl_set_intiovar(dhd, "arp_ol",
+		arp_mode, WLC_SET_VAR, TRUE, 0);
+
+	retcode = retcode >= 0 ? 0 : retcode;
+	if (retcode) {
+		DHD_ERROR(("%s: failed to set ARP offload mode to 0x%x, retcode = %d\n",
+			__FUNCTION__, arp_mode, retcode));
+	} else {
+		DHD_ARPOE(("%s: successfully set ARP offload mode to 0x%x\n",
+			__FUNCTION__, arp_mode));
+		dhd->arpol_configured = TRUE;
+	}
+}
+
+void
+dhd_arp_offload_enable(dhd_pub_t * dhd, int arp_enable)
+{
+	int retcode;
+
+#ifdef DISABLE_ARP_OFFLOAD_ON_SOFTAP
+	/* IF SoftAP is enabled, do NOT enable ARP Offload */
+	if (dhd->pfaoe_enab && (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) && arp_enable) {
+		DHD_ERROR(("%s: Skip enabling ARP offload when SoftAP is enabled\n", __FUNCTION__));
+		return;
+	}
+#endif /* DISABLE_ARP_OFFLOAD_ON_SOFTAP */
+
+	if (!dhd->arpol_configured) {
+		/* If arpol is not applied, apply it */
+		dhd_arp_offload_set(dhd, dhd_arp_mode);
+	}
+
+	retcode = dhd_wl_ioctl_set_intiovar(dhd, "arpoe",
+		arp_enable, WLC_SET_VAR, TRUE, 0);
+	retcode = retcode >= 0 ? 0 : retcode;
+	if (retcode)
+		DHD_ERROR(("%s: failed to enabe ARP offload to %d, retcode = %d\n",
+			__FUNCTION__, arp_enable, retcode));
+	else
+#ifdef DHD_LOG_DUMP
+		DHD_LOG_MEM(("%s: successfully enabed ARP offload to %d\n",
+			__FUNCTION__, arp_enable));
+#else
+		DHD_ARPOE(("%s: successfully enabed ARP offload to %d\n",
+			__FUNCTION__, arp_enable));
+#endif /* DHD_LOG_DUMP */
+	if (arp_enable) {
+		uint32 version;
+		retcode = dhd_wl_ioctl_get_intiovar(dhd, "arp_version",
+			&version, WLC_GET_VAR, FALSE, 0);
+		if (retcode) {
+			DHD_INFO(("%s: fail to get version (maybe version 1:retcode = %d\n",
+				__FUNCTION__, retcode));
+			dhd->arp_version = 1;
+		}
+		else {
+			DHD_INFO(("%s: ARP Version= %x\n", __FUNCTION__, version));
+			dhd->arp_version = version;
+		}
+	}
+}
+
+/* XXX ANDREY: clear AOE arp_table  */
+void
+dhd_aoe_arp_clr(dhd_pub_t *dhd, int idx)
+{
+	int ret = 0;
+
+	if (dhd == NULL) return;
+	if (dhd->arp_version == 1)
+		idx = 0;
+
+	ret = dhd_iovar(dhd, idx, "arp_table_clear", NULL, 0, NULL, 0, TRUE);
+	if (ret < 0)
+		DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
+	else {
+#ifdef DHD_LOG_DUMP
+		DHD_LOG_MEM(("%s: ARP table clear\n", __FUNCTION__));
+#else
+		DHD_TRACE(("%s: ARP table clear\n", __FUNCTION__));
+#endif /* DHD_LOG_DUMP */
+	}
+	/* mac address isn't cleared here but it will be cleared after dongle off */
+	dhd->hmac_updated = 0;
+}
+
+/* XXX ANDREY: clear hostip table  */
+void
+dhd_aoe_hostip_clr(dhd_pub_t *dhd, int idx)
+{
+	int ret = 0;
+
+	if (dhd == NULL) return;
+	if (dhd->arp_version == 1)
+		idx = 0;
+
+	ret = dhd_iovar(dhd, idx, "arp_hostip_clear", NULL, 0, NULL, 0, TRUE);
+	if (ret < 0)
+		DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
+	else {
+#ifdef DHD_LOG_DUMP
+		DHD_LOG_MEM(("%s: ARP host ip clear\n", __FUNCTION__));
+#else
+		DHD_TRACE(("%s: ARP host ip clear\n", __FUNCTION__));
+#endif /* DHD_LOG_DUMP */
+	}
+}
+
+void
+dhd_arp_offload_add_ip(dhd_pub_t *dhd, uint32 ipaddr, int idx)
+{
+	int ret;
+
+	if (dhd == NULL) return;
+	if (dhd->arp_version == 1)
+		idx = 0;
+
+	ret = dhd_iovar(dhd, idx, "arp_hostip", (char *)&ipaddr, sizeof(ipaddr),
+			NULL, 0, TRUE);
+	if (ret < 0)
+		DHD_ERROR(("%s: ARP ip addr add failed, ret = %d\n", __FUNCTION__, ret));
+	else {
+		/* mac address is updated in the dongle */
+		dhd->hmac_updated = 1;
+#ifdef DHD_LOG_DUMP
+		DHD_LOG_MEM(("%s: ARP ip addr entry added \n", __FUNCTION__));
+#else
+		DHD_ARPOE(("%s: ARP ip addr entry added \n", __FUNCTION__));
+#endif /* DHD_LOG_DUMP */
+	}
+}
+
+int
+dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen, int idx)
+{
+	int ret, i;
+	uint32 *ptr32 = buf;
+	bool clr_bottom = FALSE;
+
+	if (!buf)
+		return -1;
+	if (dhd == NULL) return -1;
+	if (dhd->arp_version == 1)
+		idx = 0;
+
+	ret = dhd_iovar(dhd, idx, "arp_hostip", NULL, 0, (char *)buf, buflen,
+			FALSE);
+	if (ret) {
+		DHD_ERROR(("%s: ioctl WLC_GET_VAR error %d\n",
+		__FUNCTION__, ret));
+
+		return -1;
+	}
+
+	/* clean up the buf, ascii reminder */
+	for (i = 0; i < MAX_IPV4_ENTRIES; i++) {
+		if (!clr_bottom) {
+			if (*ptr32 == 0)
+				clr_bottom = TRUE;
+		} else {
+			*ptr32 = 0;
+		}
+		ptr32++;
+	}
+
+	return 0;
+}
+#endif /* ARP_OFFLOAD_SUPPORT  */
+
+/*
+ * Neighbor Discovery Offload: enable NDO feature
+ * Called  by ipv6 event handler when interface comes up/goes down
+ */
+int
+dhd_ndo_enable(dhd_pub_t * dhd, int ndo_enable)
+{
+	int retcode;
+
+	if (dhd == NULL)
+		return -1;
+
+#if defined(WL_CFG80211) && defined(WL_NAN)
+	if (wl_cfgnan_is_dp_active(dhd_linux_get_primary_netdev(dhd))) {
+		/* If nan dp is active, skip NDO */
+		DHD_INFO(("Active NAN DP, skip NDO\n"));
+		return 0;
+	}
+#endif /* WL_CFG80211 && WL_NAN */
+#ifdef WL_CFG80211
+	if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
+		/* NDO disable on STA+SOFTAP mode */
+		ndo_enable = FALSE;
+	}
+#endif /* WL_CFG80211 */
+	retcode = dhd_wl_ioctl_set_intiovar(dhd, "ndoe",
+		ndo_enable, WLC_SET_VAR, TRUE, 0);
+	if (retcode)
+		DHD_ERROR(("%s: failed to enabe ndo to %d, retcode = %d\n",
+			__FUNCTION__, ndo_enable, retcode));
+	else
+		DHD_TRACE(("%s: successfully enabed ndo offload to %d\n",
+			__FUNCTION__, ndo_enable));
+
+	return retcode;
+}
+
+/*
+ * Neighbor Discover Offload: enable NDO feature
+ * Called  by ipv6 event handler when interface comes up
+ */
+int
+dhd_ndo_add_ip(dhd_pub_t *dhd, char* ipv6addr, int idx)
+{
+	int iov_len = 0;
+	char iovbuf[DHD_IOVAR_BUF_SIZE];
+	int retcode;
+
+	if (dhd == NULL)
+		return -1;
+
+	iov_len = bcm_mkiovar("nd_hostip", (char *)ipv6addr,
+		IPV6_ADDR_LEN, iovbuf, sizeof(iovbuf));
+	if (!iov_len) {
+		DHD_ERROR(("%s: Insufficient iovar buffer size %zu \n",
+			__FUNCTION__, sizeof(iovbuf)));
+		return -1;
+	}
+	retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx);
+
+	if (retcode)
+		DHD_ERROR(("%s: ndo ip addr add failed, retcode = %d\n",
+		__FUNCTION__, retcode));
+	else
+		DHD_TRACE(("%s: ndo ipaddr entry added \n",
+		__FUNCTION__));
+
+	return retcode;
+}
+
+/*
+ * Neighbor Discover Offload: enable NDO feature
+ * Called  by ipv6 event handler when interface goes down
+ */
+int
+dhd_ndo_remove_ip(dhd_pub_t *dhd, int idx)
+{
+	int iov_len = 0;
+	char iovbuf[DHD_IOVAR_BUF_SIZE];
+	int retcode;
+
+	if (dhd == NULL)
+		return -1;
+
+	iov_len = bcm_mkiovar("nd_hostip_clear", NULL,
+		0, iovbuf, sizeof(iovbuf));
+	if (!iov_len) {
+		DHD_ERROR(("%s: Insufficient iovar buffer size %zu \n",
+			__FUNCTION__, sizeof(iovbuf)));
+		return -1;
+	}
+	retcode = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx);
+
+	if (retcode)
+		DHD_ERROR(("%s: ndo ip addr remove failed, retcode = %d\n",
+		__FUNCTION__, retcode));
+	else
+		DHD_TRACE(("%s: ndo ipaddr entry removed \n",
+		__FUNCTION__));
+
+	return retcode;
+}
+/* Enhanced ND offload */
+uint16
+dhd_ndo_get_version(dhd_pub_t *dhdp)
+{
+	char iovbuf[DHD_IOVAR_BUF_SIZE];
+	wl_nd_hostip_t ndo_get_ver;
+	int iov_len;
+	int retcode;
+	uint16 ver = 0;
+
+	if (dhdp == NULL) {
+		return BCME_ERROR;
+	}
+
+	memset(&iovbuf, 0, sizeof(iovbuf));
+	ndo_get_ver.version = htod16(WL_ND_HOSTIP_IOV_VER);
+	ndo_get_ver.op_type = htod16(WL_ND_HOSTIP_OP_VER);
+	ndo_get_ver.length = htod32(WL_ND_HOSTIP_FIXED_LEN + sizeof(uint16));
+	ndo_get_ver.u.version = 0;
+	iov_len = bcm_mkiovar("nd_hostip", (char *)&ndo_get_ver,
+		WL_ND_HOSTIP_FIXED_LEN + sizeof(uint16), iovbuf, sizeof(iovbuf));
+
+	if (!iov_len) {
+		DHD_ERROR(("%s: Insufficient iovar buffer size %zu \n",
+			__FUNCTION__, sizeof(iovbuf)));
+		return BCME_ERROR;
+	}
+
+	retcode = dhd_wl_ioctl_cmd(dhdp, WLC_GET_VAR, iovbuf, iov_len, FALSE, 0);
+
+	if (retcode) {
+		DHD_ERROR(("%s: failed, retcode = %d\n", __FUNCTION__, retcode));
+		/* ver iovar not supported. NDO version is 0 */
+		ver = 0;
+	} else {
+		wl_nd_hostip_t *ndo_ver_ret = (wl_nd_hostip_t *)iovbuf;
+
+		if ((dtoh16(ndo_ver_ret->version) == WL_ND_HOSTIP_IOV_VER) &&
+				(dtoh16(ndo_ver_ret->op_type) == WL_ND_HOSTIP_OP_VER) &&
+				(dtoh32(ndo_ver_ret->length) == WL_ND_HOSTIP_FIXED_LEN
+					+ sizeof(uint16))) {
+			/* nd_hostip iovar version */
+			ver = dtoh16(ndo_ver_ret->u.version);
+		}
+
+		DHD_TRACE(("%s: successfully get version: %d\n", __FUNCTION__, ver));
+	}
+
+	return ver;
+}
+
+int
+dhd_ndo_add_ip_with_type(dhd_pub_t *dhdp, char *ipv6addr, uint8 type, int idx)
+{
+	char iovbuf[DHD_IOVAR_BUF_SIZE];
+	wl_nd_hostip_t ndo_add_addr;
+	int iov_len;
+	int retcode;
+
+	if (dhdp == NULL || ipv6addr == 0) {
+		return BCME_ERROR;
+	}
+
+	/* wl_nd_hostip_t fixed param */
+	ndo_add_addr.version = htod16(WL_ND_HOSTIP_IOV_VER);
+	ndo_add_addr.op_type = htod16(WL_ND_HOSTIP_OP_ADD);
+	ndo_add_addr.length = htod32(WL_ND_HOSTIP_WITH_ADDR_LEN);
+	/* wl_nd_host_ip_addr_t param for add */
+	memcpy(&ndo_add_addr.u.host_ip.ip_addr, ipv6addr, IPV6_ADDR_LEN);
+	ndo_add_addr.u.host_ip.type = type;
+
+	iov_len = bcm_mkiovar("nd_hostip", (char *)&ndo_add_addr,
+		WL_ND_HOSTIP_WITH_ADDR_LEN, iovbuf, sizeof(iovbuf));
+	if (!iov_len) {
+		DHD_ERROR(("%s: Insufficient iovar buffer size %zu \n",
+			__FUNCTION__, sizeof(iovbuf)));
+		return BCME_ERROR;
+	}
+
+	retcode = dhd_wl_ioctl_cmd(dhdp, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx);
+	if (retcode) {
+		DHD_ERROR(("%s: failed, retcode = %d\n", __FUNCTION__, retcode));
+#ifdef NDO_CONFIG_SUPPORT
+		if (retcode == BCME_NORESOURCE) {
+			/* number of host ip addr exceeds FW capacity, Deactivate ND offload */
+			DHD_INFO(("%s: Host IP count exceed device capacity,"
+				"ND offload deactivated\n", __FUNCTION__));
+			dhdp->ndo_host_ip_overflow = TRUE;
+			dhd_ndo_enable(dhdp, FALSE);
+		}
+#endif /* NDO_CONFIG_SUPPORT */
+	} else {
+		DHD_TRACE(("%s: successfully added: %d\n", __FUNCTION__, retcode));
+	}
+
+	return retcode;
+}
+
+int
+dhd_ndo_remove_ip_by_addr(dhd_pub_t *dhdp, char *ipv6addr, int idx)
+{
+	char iovbuf[DHD_IOVAR_BUF_SIZE];
+	wl_nd_hostip_t ndo_del_addr;
+	int iov_len;
+	int retcode;
+
+	if (dhdp == NULL || ipv6addr == 0) {
+		return BCME_ERROR;
+	}
+
+	/* wl_nd_hostip_t fixed param */
+	ndo_del_addr.version = htod16(WL_ND_HOSTIP_IOV_VER);
+	ndo_del_addr.op_type = htod16(WL_ND_HOSTIP_OP_DEL);
+	ndo_del_addr.length = htod32(WL_ND_HOSTIP_WITH_ADDR_LEN);
+	/* wl_nd_host_ip_addr_t param for del */
+	memcpy(&ndo_del_addr.u.host_ip.ip_addr, ipv6addr, IPV6_ADDR_LEN);
+	ndo_del_addr.u.host_ip.type = 0;	/* don't care */
+
+	iov_len = bcm_mkiovar("nd_hostip", (char *)&ndo_del_addr,
+		WL_ND_HOSTIP_WITH_ADDR_LEN, iovbuf, sizeof(iovbuf));
+
+	if (!iov_len) {
+		DHD_ERROR(("%s: Insufficient iovar buffer size %zu \n",
+			__FUNCTION__, sizeof(iovbuf)));
+		return BCME_ERROR;
+	}
+
+	retcode = dhd_wl_ioctl_cmd(dhdp, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx);
+	if (retcode) {
+		DHD_ERROR(("%s: failed, retcode = %d\n", __FUNCTION__, retcode));
+	} else {
+		DHD_TRACE(("%s: successfully removed: %d\n", __FUNCTION__, retcode));
+	}
+
+	return retcode;
+}
+
+int
+dhd_ndo_remove_ip_by_type(dhd_pub_t *dhdp, uint8 type, int idx)
+{
+	char iovbuf[DHD_IOVAR_BUF_SIZE];
+	wl_nd_hostip_t ndo_del_addr;
+	int iov_len;
+	int retcode;
+
+	if (dhdp == NULL) {
+		return BCME_ERROR;
+	}
+
+	/* wl_nd_hostip_t fixed param */
+	ndo_del_addr.version = htod16(WL_ND_HOSTIP_IOV_VER);
+	if (type == WL_ND_IPV6_ADDR_TYPE_UNICAST) {
+		ndo_del_addr.op_type = htod16(WL_ND_HOSTIP_OP_DEL_UC);
+	} else if (type == WL_ND_IPV6_ADDR_TYPE_ANYCAST) {
+		ndo_del_addr.op_type = htod16(WL_ND_HOSTIP_OP_DEL_AC);
+	} else {
+		return BCME_BADARG;
+	}
+	ndo_del_addr.length = htod32(WL_ND_HOSTIP_FIXED_LEN);
+
+	iov_len = bcm_mkiovar("nd_hostip", (char *)&ndo_del_addr, WL_ND_HOSTIP_FIXED_LEN,
+			iovbuf, sizeof(iovbuf));
+
+	if (!iov_len) {
+		DHD_ERROR(("%s: Insufficient iovar buffer size %zu \n",
+			__FUNCTION__, sizeof(iovbuf)));
+		return BCME_ERROR;
+	}
+
+	retcode = dhd_wl_ioctl_cmd(dhdp, WLC_SET_VAR, iovbuf, iov_len, TRUE, idx);
+	if (retcode) {
+		DHD_ERROR(("%s: failed, retcode = %d\n", __FUNCTION__, retcode));
+	} else {
+		DHD_TRACE(("%s: successfully removed: %d\n", __FUNCTION__, retcode));
+	}
+
+	return retcode;
+}
+
+int
+dhd_ndo_unsolicited_na_filter_enable(dhd_pub_t *dhdp, int enable)
+{
+	char iovbuf[DHD_IOVAR_BUF_SIZE];
+	int iov_len;
+	int retcode;
+
+	if (dhdp == NULL) {
+		return BCME_ERROR;
+	}
+
+	iov_len = bcm_mkiovar("nd_unsolicited_na_filter", (char *)&enable, sizeof(int),
+			iovbuf, sizeof(iovbuf));
+
+	if (!iov_len) {
+		DHD_ERROR(("%s: Insufficient iovar buffer size %zu \n",
+			__FUNCTION__, sizeof(iovbuf)));
+		return BCME_ERROR;
+	}
+
+	retcode = dhd_wl_ioctl_cmd(dhdp, WLC_SET_VAR, iovbuf, iov_len, TRUE, 0);
+	if (retcode)
+		DHD_ERROR(("%s: failed to enable Unsolicited NA filter to %d, retcode = %d\n",
+			__FUNCTION__, enable, retcode));
+	else {
+		DHD_TRACE(("%s: successfully enabled Unsolicited NA filter to %d\n",
+			__FUNCTION__, enable));
+	}
+
+	return retcode;
+}
+#ifdef SIMPLE_ISCAN
+
+uint iscan_thread_id = 0;
+iscan_buf_t * iscan_chain = 0;
+
+iscan_buf_t *
+dhd_iscan_allocate_buf(dhd_pub_t *dhd, iscan_buf_t **iscanbuf)
+{
+	iscan_buf_t *iscanbuf_alloc = 0;
+	iscan_buf_t *iscanbuf_head;
+
+	DHD_ISCAN(("%s: Entered\n", __FUNCTION__));
+	dhd_iscan_lock();
+
+	iscanbuf_alloc = (iscan_buf_t*)MALLOC(dhd->osh, sizeof(iscan_buf_t));
+	if (iscanbuf_alloc == NULL)
+		goto fail;
+
+	iscanbuf_alloc->next = NULL;
+	iscanbuf_head = *iscanbuf;
+
+	DHD_ISCAN(("%s: addr of allocated node = 0x%X"
+		   "addr of iscanbuf_head = 0x%X dhd = 0x%X\n",
+		   __FUNCTION__, iscanbuf_alloc, iscanbuf_head, dhd));
+
+	if (iscanbuf_head == NULL) {
+		*iscanbuf = iscanbuf_alloc;
+		DHD_ISCAN(("%s: Head is allocated\n", __FUNCTION__));
+		goto fail;
+	}
+
+	while (iscanbuf_head->next)
+		iscanbuf_head = iscanbuf_head->next;
+
+	iscanbuf_head->next = iscanbuf_alloc;
+
+fail:
+	dhd_iscan_unlock();
+	return iscanbuf_alloc;
+}
+
+void
+dhd_iscan_free_buf(void *dhdp, iscan_buf_t *iscan_delete)
+{
+	iscan_buf_t *iscanbuf_free = 0;
+	iscan_buf_t *iscanbuf_prv = 0;
+	iscan_buf_t *iscanbuf_cur;
+	dhd_pub_t *dhd = dhd_bus_pub(dhdp);
+	DHD_ISCAN(("%s: Entered\n", __FUNCTION__));
+
+	dhd_iscan_lock();
+
+	iscanbuf_cur = iscan_chain;
+
+	/* If iscan_delete is null then delete the entire
+	 * chain or else delete specific one provided
+	 */
+	if (!iscan_delete) {
+		while (iscanbuf_cur) {
+			iscanbuf_free = iscanbuf_cur;
+			iscanbuf_cur = iscanbuf_cur->next;
+			iscanbuf_free->next = 0;
+			MFREE(dhd->osh, iscanbuf_free, sizeof(iscan_buf_t));
+		}
+		iscan_chain = 0;
+	} else {
+		while (iscanbuf_cur) {
+			if (iscanbuf_cur == iscan_delete)
+				break;
+			iscanbuf_prv = iscanbuf_cur;
+			iscanbuf_cur = iscanbuf_cur->next;
+		}
+		if (iscanbuf_prv)
+			iscanbuf_prv->next = iscan_delete->next;
+
+		iscan_delete->next = 0;
+		MFREE(dhd->osh, iscan_delete, sizeof(iscan_buf_t));
+
+		if (!iscanbuf_prv)
+			iscan_chain = 0;
+	}
+	dhd_iscan_unlock();
+}
+
+iscan_buf_t *
+dhd_iscan_result_buf(void)
+{
+	return iscan_chain;
+}
+
+int
+dhd_iscan_issue_request(void * dhdp, wl_iscan_params_t *pParams, uint32 size)
+{
+	int rc = -1;
+	dhd_pub_t *dhd = dhd_bus_pub(dhdp);
+	char *buf;
+	char iovar[] = "iscan";
+	uint32 allocSize = 0;
+	wl_ioctl_t ioctl;
+	int len;
+
+	if (pParams) {
+		allocSize = (size + strlen(iovar) + 1);
+		if ((allocSize < size) || (allocSize < strlen(iovar)))
+		{
+			DHD_ERROR(("%s: overflow - allocation size too large %d < %d + %d!\n",
+				__FUNCTION__, allocSize, size, strlen(iovar)));
+			goto cleanUp;
+		}
+		buf = MALLOC(dhd->osh, allocSize);
+
+		if (buf == NULL)
+			{
+			DHD_ERROR(("%s: malloc of size %d failed!\n", __FUNCTION__, allocSize));
+			goto cleanUp;
+			}
+		ioctl.cmd = WLC_SET_VAR;
+		len = bcm_mkiovar(iovar, (char *)pParams, size, buf, allocSize);
+		if (len == 0) {
+			rc = BCME_BUFTOOSHORT;
+			goto cleanUp;
+		}
+		rc = dhd_wl_ioctl(dhd, 0, &ioctl, buf, len);
+	}
+
+cleanUp:
+	if (buf) {
+		MFREE(dhd->osh, buf, allocSize);
+	}
+
+	return rc;
+}
+
+static int
+dhd_iscan_get_partial_result(void *dhdp, uint *scan_count)
+{
+	wl_iscan_results_t *list_buf;
+	wl_iscan_results_t list;
+	wl_scan_results_v109_t *results;
+	iscan_buf_t *iscan_cur;
+	int status = -1;
+	dhd_pub_t *dhd = dhd_bus_pub(dhdp);
+	int rc;
+	wl_ioctl_t ioctl;
+	int len;
+
+	DHD_ISCAN(("%s: Enter\n", __FUNCTION__));
+
+	iscan_cur = dhd_iscan_allocate_buf(dhd, &iscan_chain);
+	if (!iscan_cur) {
+		DHD_ERROR(("%s: Failed to allocate node\n", __FUNCTION__));
+		dhd_iscan_free_buf(dhdp, 0);
+		dhd_iscan_request(dhdp, WL_SCAN_ACTION_ABORT);
+		dhd_ind_scan_confirm(dhdp, FALSE);
+		goto fail;
+	}
+
+	dhd_iscan_lock();
+
+	memset(iscan_cur->iscan_buf, 0, WLC_IW_ISCAN_MAXLEN);
+	list_buf = (wl_iscan_results_t*)iscan_cur->iscan_buf;
+	results = &list_buf->results;
+	results->buflen = WL_ISCAN_RESULTS_FIXED_SIZE;
+	results->version = 0;
+	results->count = 0;
+
+	memset(&list, 0, sizeof(list));
+	list.results.buflen = htod32(WLC_IW_ISCAN_MAXLEN);
+	len = bcm_mkiovar("iscanresults", (char *)&list, WL_ISCAN_RESULTS_FIXED_SIZE,
+		iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN);
+	if (len == 0) {
+		dhd_iscan_free_buf(dhdp, 0);
+		dhd_iscan_request(dhdp, WL_SCAN_ACTION_ABORT);
+		dhd_ind_scan_confirm(dhdp, FALSE);
+		status = BCME_BUFTOOSHORT;
+		goto fail;
+	}
+	ioctl.cmd = WLC_GET_VAR;
+	ioctl.set = FALSE;
+	rc = dhd_wl_ioctl(dhd, 0, &ioctl, iscan_cur->iscan_buf, WLC_IW_ISCAN_MAXLEN);
+
+	results->buflen = dtoh32(results->buflen);
+	results->version = dtoh32(results->version);
+	*scan_count = results->count = dtoh32(results->count);
+	status = dtoh32(list_buf->status);
+	DHD_ISCAN(("%s: Got %d resuls status = (%x)\n", __FUNCTION__, results->count, status));
+
+	dhd_iscan_unlock();
+
+	if (!(*scan_count)) {
+		 /* TODO: race condition when FLUSH already called */
+		dhd_iscan_free_buf(dhdp, 0);
+	}
+fail:
+	return status;
+}
+
+#ifdef NDIS
+/* XXXX Following code had bit of OS dependency.
+ * Cleanup to move the OS dependency to other
+ * per port code so that iscan logic here can be
+ * leveraged across all OS's
+ */
+NDIS_EVENT iscan_event;
+HANDLE tHandle;
+NDIS_SPIN_LOCK	dhd_iscan_queue_lock;
+
+void
+dhd_iscan_lock(void)
+{
+	NdisAcquireSpinLock(&dhd_iscan_queue_lock);
+}
+
+void
+dhd_iscan_unlock(void)
+{
+	NdisReleaseSpinLock(&dhd_iscan_queue_lock);
+}
+
+void
+dhd_iscan_notify(void)
+{
+	DHD_ISCAN(("%s: Entered\n", __FUNCTION__));
+	NdisSetEvent(&iscan_event);
+}
+
+static void
+dhd_iscan_func(void *h)
+{
+	int status;
+	uint scan_count;
+	dhd_pub_t *dhd = dhd_bus_pub(h);
+
+	/* Read the priority from registry */
+	CeSetThreadPriority(GetCurrentThread(), 128);
+	DHD_ISCAN(("%s: thread created\n", __FUNCTION__));
+
+	while (TRUE) {
+		NdisWaitEvent(&iscan_event, 0);		/* wait forever */
+		NdisResetEvent(&iscan_event);		/* reset the event */
+		DHD_ISCAN(("%s: thread scheduled\n", __FUNCTION__));
+
+		status = dhd_iscan_get_partial_result(h, &scan_count);
+
+		if (status == WL_SCAN_RESULTS_PARTIAL) {
+			dhd_iscan_request(h, WL_SCAN_ACTION_CONTINUE);
+		} else if (status == WL_SCAN_RESULTS_SUCCESS) {
+			if (dhd_iscan_in_progress(h)) {
+				dhd_ind_scan_confirm(h, TRUE);
+			}
+		} else if (status == WL_SCAN_RESULTS_ABORTED ||
+			status == WL_SCAN_RESULTS_NO_MEM) {
+			dhd_iscan_request(h, WL_SCAN_ACTION_ABORT);
+			dhd_ind_scan_confirm(h, FALSE);
+		} else {
+			dhd_iscan_request(h, WL_SCAN_ACTION_ABORT);
+			dhd_ind_scan_confirm(h, FALSE);
+		}
+	}
+}
+
+int
+dhd_iscan_attach(void *dhdp)
+{
+	DHD_ISCAN(("%s: dhdp = 0x%x\n", __FUNCTION__, dhdp));
+
+	NdisInitializeEvent(&iscan_event);
+	NdisResetEvent(&iscan_event);
+	NdisAllocateSpinLock(&dhd_iscan_queue_lock);
+
+	/* XXX - should move to ndishared sublayer */
+	tHandle = CreateThread(NULL,
+		0,
+		(LPTHREAD_START_ROUTINE)dhd_iscan_func,
+		(void *)dhdp,
+		0,
+		&iscan_thread_id);
+
+	if (!iscan_thread_id)
+		return NDIS_STATUS_FAILURE;
+
+	return NDIS_STATUS_SUCCESS;
+}
+
+void
+dhd_iscan_deattach(void *dhdp)
+{
+	if (iscan_thread_id)
+	{
+	NdisFreeEvent(&iscan_event);
+	NdisFreeSpinLock(&dhd_iscan_queue_lock);
+	CloseHandle(tHandle);
+		iscan_thread_id = 0;
+	}
+}
+#endif /* NDIS */
+#endif /* SIMPLE_ISCAN */
+
+/*
+ * returns = TRUE if associated, FALSE if not associated
+ */
+bool dhd_is_associated(dhd_pub_t *dhd, uint8 ifidx, int *retval)
+{
+	char bssid[6], zbuf[6];
+	int ret = -1;
+
+	bzero(bssid, 6);
+	bzero(zbuf, 6);
+
+	ret  = dhd_wl_ioctl_cmd(dhd, WLC_GET_BSSID, (char *)&bssid,
+		ETHER_ADDR_LEN, FALSE, ifidx);
+	/* XXX:AS!!! res can be: -17(BCME_NOTASSOCIATED),-22(BCME_NORESOURCE), and 0(OK)
+	  OK - doesn't mean associated yet, the returned bssid
+	  still needs to be checked for non zero array
+	*/
+	DHD_TRACE((" %s WLC_GET_BSSID ioctl res = %d\n", __FUNCTION__, ret));
+
+	if (ret == BCME_NOTASSOCIATED) {
+		DHD_ERROR(("%s: WLC_GET_BSSID, NOT ASSOCIATED\n", __FUNCTION__));
+	}
+
+	if (retval)
+		*retval = ret;
+
+	if (ret < 0)
+		return FALSE;
+
+	if ((memcmp(bssid, zbuf, ETHER_ADDR_LEN) == 0)) {
+		DHD_TRACE(("%s: WLC_GET_BSSID ioctl returned zero bssid\n", __FUNCTION__));
+		return FALSE;
+	}
+	return TRUE;
+}
+
+#if defined(__linux__)
+/*
+ * returns = TRUE if anyone is associated, FALSE if all are disassociated
+ */
+bool dhd_scan_associated(dhd_pub_t *dhd, struct net_device *ndev)
+{
+	dhd_if_t *ifp = NULL;
+	u32 idx = 0;
+
+	for (idx = 0; idx < DHD_MAX_IFS; idx++) {
+		ifp = dhd_get_ifp(dhd, idx);
+		if (!ifp)
+			continue;
+		if (ifp->net == ndev)
+			continue;
+		if (!dhd_is_associated(dhd, idx, NULL))
+			continue;
+		return TRUE;
+	}
+
+	return FALSE;
+}
+#endif /* __linux__ */
+
+/* Check if the mode supports STA MODE */
+bool dhd_support_sta_mode(dhd_pub_t *dhd)
+{
+
+#ifdef  WL_CFG80211
+	if (!(dhd->op_mode & DHD_FLAG_STA_MODE))
+		return FALSE;
+	else
+#endif /* WL_CFG80211 */
+		return TRUE;
+}
+
+#if defined(KEEP_ALIVE)
+int dhd_keep_alive_onoff(dhd_pub_t *dhd)
+{
+	char				buf[32] = {0};
+	const char			*str;
+	wl_mkeep_alive_pkt_v1_t	mkeep_alive_pkt;
+	wl_mkeep_alive_pkt_v1_t	*mkeep_alive_pktp;
+	int					buf_len;
+	int					str_len;
+	int res					= -1;
+
+	if (!dhd_support_sta_mode(dhd))
+		return res;
+
+	DHD_TRACE(("%s execution\n", __FUNCTION__));
+
+	str = "mkeep_alive";
+	str_len = strlen(str);
+	strlcpy(buf, str, sizeof(buf));
+	mkeep_alive_pktp = (wl_mkeep_alive_pkt_v1_t *) (buf + str_len + 1);
+	bzero(&mkeep_alive_pkt, sizeof(mkeep_alive_pkt));
+	mkeep_alive_pkt.period_msec = dhd->conf->keep_alive_period;
+	buf_len = str_len + 1;
+	mkeep_alive_pkt.version = htod16(WL_MKEEP_ALIVE_VERSION_1);
+	mkeep_alive_pkt.length = htod16(WL_MKEEP_ALIVE_FIXED_LEN);
+	/* Setup keep alive zero for null packet generation */
+	mkeep_alive_pkt.keep_alive_id = 0;
+	mkeep_alive_pkt.len_bytes = 0;
+	buf_len += WL_MKEEP_ALIVE_FIXED_LEN;
+	/* Keep-alive attributes are set in local	variable (mkeep_alive_pkt), and
+	 * then memcpy'ed into buffer (mkeep_alive_pktp) since there is no
+	 * guarantee that the buffer is properly aligned.
+	 */
+	memcpy((char *)mkeep_alive_pktp, &mkeep_alive_pkt, WL_MKEEP_ALIVE_FIXED_LEN);
+
+	res = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0);
+
+	return res;
+}
+#endif /* defined(KEEP_ALIVE) */
+#if defined(OEM_ANDROID)
+#define	CSCAN_TLV_TYPE_SSID_IE	'S'
+/*
+ *  SSIDs list parsing from cscan tlv list
+ */
+int
+wl_parse_ssid_list_tlv(char** list_str, wlc_ssid_ext_t* ssid, int max, int *bytes_left)
+{
+	char* str;
+	int idx = 0;
+	uint8 len;
+
+	if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) {
+		DHD_ERROR(("%s error paramters\n", __FUNCTION__));
+		return BCME_BADARG;
+	}
+	str = *list_str;
+	while (*bytes_left > 0) {
+		if (str[0] != CSCAN_TLV_TYPE_SSID_IE) {
+			*list_str = str;
+			DHD_TRACE(("nssid=%d left_parse=%d %d\n", idx, *bytes_left, str[0]));
+			return idx;
+		}
+
+		if (idx >= max) {
+			DHD_ERROR(("%s number of SSIDs more than %d\n", __FUNCTION__, idx));
+			return BCME_BADARG;
+		}
+
+		/* Get proper CSCAN_TLV_TYPE_SSID_IE */
+		*bytes_left -= 1;
+		if (*bytes_left == 0) {
+			DHD_ERROR(("%s no length field.\n", __FUNCTION__));
+			return BCME_BADARG;
+		}
+		str += 1;
+		ssid[idx].rssi_thresh = 0;
+		ssid[idx].flags = 0;
+		len = str[0];
+		if (len == 0) {
+			/* Broadcast SSID */
+			ssid[idx].SSID_len = 0;
+			memset((char*)ssid[idx].SSID, 0x0, DOT11_MAX_SSID_LEN);
+			*bytes_left -= 1;
+			str += 1;
+
+			DHD_TRACE(("BROADCAST SCAN  left=%d\n", *bytes_left));
+		} else if (len <= DOT11_MAX_SSID_LEN) {
+			/* Get proper SSID size */
+			ssid[idx].SSID_len = len;
+			*bytes_left -= 1;
+			/* Get SSID */
+			if (ssid[idx].SSID_len > *bytes_left) {
+				DHD_ERROR(("%s out of memory range len=%d but left=%d\n",
+				__FUNCTION__, ssid[idx].SSID_len, *bytes_left));
+				return BCME_BADARG;
+			}
+			str += 1;
+			memcpy((char*)ssid[idx].SSID, str, ssid[idx].SSID_len);
+
+			*bytes_left -= ssid[idx].SSID_len;
+			str += ssid[idx].SSID_len;
+			ssid[idx].hidden = TRUE;
+
+			DHD_TRACE(("%s :size=%d left=%d\n",
+				(char*)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left));
+		} else {
+			DHD_ERROR(("### SSID size more than %d\n", str[0]));
+			return BCME_BADARG;
+		}
+		idx++;
+	}
+
+	*list_str = str;
+	return idx;
+}
+
+#if defined(WL_WIRELESS_EXT)
+/* Android ComboSCAN support */
+
+/*
+ *  data parsing from ComboScan tlv list
+*/
+int
+wl_iw_parse_data_tlv(char** list_str, void *dst, int dst_size, const char token,
+                     int input_size, int *bytes_left)
+{
+	char* str;
+	uint16 short_temp;
+	uint32 int_temp;
+
+	if ((list_str == NULL) || (*list_str == NULL) ||(bytes_left == NULL) || (*bytes_left < 0)) {
+		DHD_ERROR(("%s error paramters\n", __FUNCTION__));
+		return -1;
+	}
+	str = *list_str;
+
+	/* Clean all dest bytes */
+	memset(dst, 0, dst_size);
+	if (*bytes_left > 0) {
+
+		if (str[0] != token) {
+			DHD_TRACE(("%s NOT Type=%d get=%d left_parse=%d \n",
+				__FUNCTION__, token, str[0], *bytes_left));
+			return -1;
+		}
+
+		*bytes_left -= 1;
+		str += 1;
+
+		if (input_size == 1) {
+			memcpy(dst, str, input_size);
+		}
+		else if (input_size == 2) {
+			memcpy(dst, (char *)htod16(memcpy(&short_temp, str, input_size)),
+				input_size);
+		}
+		else if (input_size == 4) {
+			memcpy(dst, (char *)htod32(memcpy(&int_temp, str, input_size)),
+				input_size);
+		}
+
+		*bytes_left -= input_size;
+		str += input_size;
+		*list_str = str;
+		return 1;
+	}
+	return 1;
+}
+
+/*
+ *  channel list parsing from cscan tlv list
+*/
+int
+wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list,
+                             int channel_num, int *bytes_left)
+{
+	char* str;
+	int idx = 0;
+
+	if ((list_str == NULL) || (*list_str == NULL) ||(bytes_left == NULL) || (*bytes_left < 0)) {
+		DHD_ERROR(("%s error paramters\n", __FUNCTION__));
+		return -1;
+	}
+	str = *list_str;
+
+	while (*bytes_left > 0) {
+
+		if (str[0] != CSCAN_TLV_TYPE_CHANNEL_IE) {
+			*list_str = str;
+			DHD_TRACE(("End channel=%d left_parse=%d %d\n", idx, *bytes_left, str[0]));
+			return idx;
+		}
+		/* Get proper CSCAN_TLV_TYPE_CHANNEL_IE */
+		*bytes_left -= 1;
+		str += 1;
+
+		if (str[0] == 0) {
+			/* All channels */
+			channel_list[idx] = 0x0;
+		}
+		else {
+			channel_list[idx] = (uint16)str[0];
+			DHD_TRACE(("%s channel=%d \n", __FUNCTION__,  channel_list[idx]));
+		}
+		*bytes_left -= 1;
+		str += 1;
+
+		if (idx++ > 255) {
+			DHD_ERROR(("%s Too many channels \n", __FUNCTION__));
+			return -1;
+		}
+	}
+
+	*list_str = str;
+	return idx;
+}
+
+/* Parse a comma-separated list from list_str into ssid array, starting
+ * at index idx.  Max specifies size of the ssid array.  Parses ssids
+ * and returns updated idx; if idx >= max not all fit, the excess have
+ * not been copied.  Returns -1 on empty string, or on ssid too long.
+ */
+int
+wl_iw_parse_ssid_list(char** list_str, wlc_ssid_t* ssid, int idx, int max)
+{
+	char* str, *ptr;
+
+	if ((list_str == NULL) || (*list_str == NULL))
+		return -1;
+
+	for (str = *list_str; str != NULL; str = ptr) {
+
+		/* check for next TAG */
+		if (!strncmp(str, GET_CHANNEL, strlen(GET_CHANNEL))) {
+			*list_str	 = str + strlen(GET_CHANNEL);
+			return idx;
+		}
+
+		if ((ptr = strchr(str, ',')) != NULL) {
+			*ptr++ = '\0';
+		}
+
+		if (strlen(str) > DOT11_MAX_SSID_LEN) {
+			DHD_ERROR(("ssid <%s> exceeds %d\n", str, DOT11_MAX_SSID_LEN));
+			return -1;
+		}
+
+		if (strlen(str) == 0)
+			ssid[idx].SSID_len = 0;
+
+		if (idx < max) {
+			bzero(ssid[idx].SSID, sizeof(ssid[idx].SSID));
+			strlcpy((char*)ssid[idx].SSID, str, sizeof(ssid[idx].SSID));
+			ssid[idx].SSID_len = sizeof(ssid[idx].SSID);
+		}
+		idx++;
+	}
+	return idx;
+}
+
+/*
+ * Parse channel list from iwpriv CSCAN
+ */
+int
+wl_iw_parse_channel_list(char** list_str, uint16* channel_list, int channel_num)
+{
+	int num;
+	int val;
+	char* str;
+	char* endptr = NULL;
+
+	if ((list_str == NULL)||(*list_str == NULL))
+		return -1;
+
+	str = *list_str;
+	num = 0;
+	while (strncmp(str, GET_NPROBE, strlen(GET_NPROBE))) {
+		val = (int)strtoul(str, &endptr, 0);
+		if (endptr == str) {
+			printf("could not parse channel number starting at"
+				" substring \"%s\" in list:\n%s\n",
+				str, *list_str);
+			return -1;
+		}
+		str = endptr + strspn(endptr, " ,");
+
+		if (num == channel_num) {
+			DHD_ERROR(("too many channels (more than %d) in channel list:\n%s\n",
+				channel_num, *list_str));
+			return -1;
+		}
+
+		channel_list[num++] = (uint16)val;
+	}
+	*list_str = str;
+	return num;
+}
+#endif
+#endif /* defined(OEM_ANDROID) */
+
+#if defined(BCM_ROUTER_DHD)
+static int traffic_mgmt_add_dwm_filter(dhd_pub_t *dhd,
+	trf_mgmt_filter_list_t * trf_mgmt_filter_list, int len)
+{
+	int ret = 0;
+	uint32              i;
+	trf_mgmt_filter_t   *trf_mgmt_filter;
+	uint8               dwm_tbl_entry;
+	uint32              dscp = 0;
+	uint16              dwm_filter_enabled = 0;
+
+	/* Check parameter length is adequate */
+	if (len < (OFFSETOF(trf_mgmt_filter_list_t, filter) +
+		trf_mgmt_filter_list->num_filters * sizeof(trf_mgmt_filter_t))) {
+		ret = BCME_BUFTOOSHORT;
+		return ret;
+	}
+
+	bzero(&dhd->dhd_tm_dwm_tbl, sizeof(dhd_trf_mgmt_dwm_tbl_t));
+
+	for (i = 0; i < trf_mgmt_filter_list->num_filters; i++) {
+		trf_mgmt_filter = &trf_mgmt_filter_list->filter[i];
+
+		dwm_filter_enabled = (trf_mgmt_filter->flags & TRF_FILTER_DWM);
+
+		if (dwm_filter_enabled) {
+			dscp = trf_mgmt_filter->dscp;
+			if (dscp >= DHD_DWM_TBL_SIZE) {
+				ret = BCME_BADARG;
+			return ret;
+			}
+		}
+
+		dhd->dhd_tm_dwm_tbl.dhd_dwm_enabled = 1;
+		/* set WMM AC bits */
+		dwm_tbl_entry = (uint8) trf_mgmt_filter->priority;
+		DHD_TRF_MGMT_DWM_SET_FILTER(dwm_tbl_entry);
+
+		/* set favored bits */
+		if (trf_mgmt_filter->flags & TRF_FILTER_FAVORED)
+			DHD_TRF_MGMT_DWM_SET_FAVORED(dwm_tbl_entry);
+
+		dhd->dhd_tm_dwm_tbl.dhd_dwm_tbl[dscp] =  dwm_tbl_entry;
+	}
+	return ret;
+}
+#endif /* BCM_ROUTER_DHD */
+
+#ifdef DHD_LINUX_STD_FW_API
+int dhd_get_download_buffer(dhd_pub_t	*dhd, char *file_path, download_type_t component,
+	char ** buffer, int *length)
+{
+	int ret = BCME_ERROR;
+	const struct firmware *fw = NULL;
+#ifdef SUPPORT_OTA_UPDATE
+	uint8 *buf = NULL;
+	int len = 0;
+	ota_update_info_t *ota_info = &dhd->ota_update_info;
+#endif /* SUPPORT_OTA_UPDATE */
+
+#ifdef SUPPORT_OTA_UPDATE
+	if (component == CLM_BLOB) {
+		if (ota_info->clm_len) {
+			DHD_ERROR(("Using OTA CLM_BLOB\n"));
+			buf = ota_info->clm_buf;
+			len = ota_info->clm_len;
+		}
+	}
+	else if (component == NVRAM) {
+		if (ota_info->nvram_len) {
+			DHD_ERROR(("Using OTA NVRAM.\n"));
+			buf = ota_info->nvram_buf;
+			len = ota_info->nvram_len;
+		}
+	}
+#endif /* SUPPORT_OTA_UPDATE */
+
+#ifdef SUPPORT_OTA_UPDATE
+	if (len) {
+		*buffer = (char *)buf;
+		*length = len;
+	}
+	else
+#endif /* SUPPORT_OTA_UPDATE */
+	{
+		if (file_path) {
+			ret = dhd_os_get_img_fwreq(&fw, file_path);
+			if (ret < 0) {
+				DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n",
+					ret));
+				goto err;
+			} else {
+				if ((fw->size <= 0 || fw->size > *length)) {
+					DHD_ERROR(("fw->size = %zu, *length = %d\n", fw->size, *length));
+					*length = fw->size;
+					goto err;
+				}
+				*buffer = VMALLOCZ(dhd->osh, *length);
+				if (*buffer == NULL) {
+					DHD_ERROR(("%s: Failed to allocate memory %d bytes\n",
+						__FUNCTION__, (int)fw->size));
+					ret = BCME_NOMEM;
+					goto err;
+				}
+				*length = fw->size;
+				ret = memcpy_s(*buffer, fw->size, fw->data, fw->size);
+				if (ret != BCME_OK) {
+					DHD_ERROR(("%s: memcpy_s failed, err : %d\n",
+							__FUNCTION__, ret));
+					goto err;
+				}
+				ret = BCME_OK;
+			}
+		}
+	}
+err:
+	if (fw) {
+		dhd_os_close_img_fwreq(fw);
+	}
+	return ret;
+}
+
+#else
+
+/* Given filename and download type,  returns a buffer pointer and length
+* for download to f/w. Type can be FW or NVRAM.
+*
+*/
+int dhd_get_download_buffer(dhd_pub_t	*dhd, char *file_path, download_type_t component,
+	char ** buffer, int *length)
+{
+	int ret = BCME_ERROR;
+	int len = 0;
+	int file_len;
+	void *image = NULL;
+	uint8 *buf = NULL;
+
+	/* Point to cache if available. */
+#ifdef CACHE_FW_IMAGES
+	if (component == FW) {
+		if (dhd->cached_fw_length) {
+			len = dhd->cached_fw_length;
+			buf = dhd->cached_fw;
+		}
+	} else if (component == NVRAM) {
+		if (dhd->cached_nvram_length) {
+			len = dhd->cached_nvram_length;
+			buf = dhd->cached_nvram;
+		}
+	} else if (component == CLM_BLOB) {
+		if (dhd->cached_clm_length) {
+			len = dhd->cached_clm_length;
+			buf = dhd->cached_clm;
+		}
+	} else if (component == TXCAP_BLOB) {
+		if (dhd->cached_txcap_length) {
+			len = dhd->cached_txcap_length;
+			buf = dhd->cached_txcap;
+		}
+	} else {
+		DHD_ERROR(("%s: Invalid component arg %d\n",
+			__FUNCTION__, component));
+		ret = BCME_BADARG;
+		return ret;
+	}
+#endif /* CACHE_FW_IMAGES */
+	/* No Valid cache found on this call */
+	if (!len) {
+		file_len = *length;
+		*length = 0;
+
+		if (file_path) {
+			image = dhd_os_open_image1(dhd, file_path);
+			if (image == NULL) {
+				printf("%s: Open image file failed %s\n", __FUNCTION__, file_path);
+				goto err;
+			}
+		}
+		buf = MALLOCZ(dhd->osh, file_len);
+		if (buf == NULL) {
+			DHD_ERROR(("%s: Failed to allocate memory %d bytes\n",
+				__FUNCTION__, file_len));
+			ret = BCME_NOMEM;
+			goto err;
+		}
+
+		/* Download image */
+		len = dhd_os_get_image_block((char *)buf, file_len, image);
+		if ((len <= 0 || len > file_len)) {
+			MFREE(dhd->osh, buf, file_len);
+			goto err;
+		}
+	}
+
+	ret = BCME_OK;
+	*length = len;
+	*buffer = (char *)buf;
+
+	/* Cache if first call. */
+#ifdef CACHE_FW_IMAGES
+	if (component == FW) {
+		if (!dhd->cached_fw_length) {
+			dhd->cached_fw = buf;
+			dhd->cached_fw_length = len;
+		}
+	} else if (component == NVRAM) {
+		if (!dhd->cached_nvram_length) {
+			dhd->cached_nvram = buf;
+			dhd->cached_nvram_length = len;
+		}
+	} else if (component == CLM_BLOB) {
+		if (!dhd->cached_clm_length) {
+			dhd->cached_clm = buf;
+			dhd->cached_clm_length = len;
+		}
+	} else if (component == TXCAP_BLOB) {
+		if (!dhd->cached_txcap_length) {
+			dhd->cached_txcap = buf;
+			dhd->cached_txcap_length = len;
+		}
+	}
+#endif /* CACHE_FW_IMAGES */
+
+err:
+	if (image)
+		dhd_os_close_image1(dhd, image);
+
+	return ret;
+}
+#endif /* DHD_LINUX_STD_FW_API */
+
+int
+dhd_download_2_dongle(dhd_pub_t	*dhd, char *iovar, uint16 flag, uint16 dload_type,
+	unsigned char *dload_buf, int len)
+{
+	struct wl_dload_data *dload_ptr = (struct wl_dload_data *)dload_buf;
+	int err = 0;
+	int dload_data_offset;
+	static char iovar_buf[WLC_IOCTL_MEDLEN];
+	int iovar_len;
+
+	memset(iovar_buf, 0, sizeof(iovar_buf));
+
+	dload_data_offset = OFFSETOF(wl_dload_data_t, data);
+	dload_ptr->flag = (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT) | flag;
+	dload_ptr->dload_type = dload_type;
+	dload_ptr->len = htod32(len - dload_data_offset);
+	dload_ptr->crc = 0;
+	len = ROUNDUP(len, 8);
+
+	iovar_len = bcm_mkiovar(iovar, (char *)dload_buf,
+		(uint)len, iovar_buf, sizeof(iovar_buf));
+	if (iovar_len == 0) {
+		DHD_ERROR(("%s: insufficient buffer space passed to bcm_mkiovar for '%s' \n",
+		           __FUNCTION__, iovar));
+		return BCME_BUFTOOSHORT;
+	}
+
+	err = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovar_buf,
+			iovar_len, IOV_SET, 0);
+
+	return err;
+}
+
+int
+dhd_download_blob(dhd_pub_t *dhd, unsigned char *buf,
+		uint32 len, char *iovar)
+
+{
+	int chunk_len;
+#if (!defined(LINUX) && !defined(linux)) || defined(DHD_LINUX_STD_FW_API)
+	int cumulative_len = 0;
+#endif /* !LINUX && !linux || DHD_LINUX_STD_FW_API */
+	int size2alloc;
+	unsigned char *new_buf;
+	int err = 0, data_offset;
+	uint16 dl_flag = DL_BEGIN;
+
+	data_offset = OFFSETOF(wl_dload_data_t, data);
+	size2alloc = data_offset + MAX_CHUNK_LEN;
+	size2alloc = ROUNDUP(size2alloc, 8);
+
+	if ((new_buf = (unsigned char *)MALLOCZ(dhd->osh, size2alloc)) != NULL) {
+		do {
+#if (!defined(LINUX) && !defined(linux)) || defined(DHD_LINUX_STD_FW_API)
+			if (len >= MAX_CHUNK_LEN)
+				chunk_len = MAX_CHUNK_LEN;
+			else
+				chunk_len = len;
+
+			memcpy(new_buf + data_offset, buf + cumulative_len, chunk_len);
+			cumulative_len += chunk_len;
+#else
+			chunk_len = dhd_os_get_image_block((char *)(new_buf + data_offset),
+				MAX_CHUNK_LEN, buf);
+			if (chunk_len < 0) {
+				DHD_ERROR(("%s: dhd_os_get_image_block failed (%d)\n",
+					__FUNCTION__, chunk_len));
+				err = BCME_ERROR;
+				goto exit;
+			}
+#endif /* !LINUX && !linux || DHD_LINUX_STD_FW_API */
+			if (len - chunk_len == 0)
+				dl_flag |= DL_END;
+
+			err = dhd_download_2_dongle(dhd, iovar, dl_flag, DL_TYPE_CLM,
+				new_buf, data_offset + chunk_len);
+
+			dl_flag &= ~DL_BEGIN;
+
+			len = len - chunk_len;
+		} while ((len > 0) && (err == 0));
+#if (!defined(LINUX) && !defined(linux)) || defined(DHD_LINUX_STD_FW_API)
+		MFREE(dhd->osh, new_buf, size2alloc);
+#endif /* !LINUX && !linux */
+	} else {
+		err = BCME_NOMEM;
+	}
+#if (defined(LINUX) || defined(linux)) && !defined(DHD_LINUX_STD_FW_API)
+exit:
+	if (new_buf) {
+		MFREE(dhd->osh, new_buf, size2alloc);
+	}
+#endif /* LINUX || linux */
+	return err;
+}
+
+int
+dhd_download_apf(dhd_pub_t *dhd, unsigned char *buf,
+		uint32 len, char *iovar)
+{
+	int chunk_len;
+	int cumulative_len = 0;
+	int size2alloc;
+	unsigned char *new_buf = NULL;
+	int err = 0, data_offset;
+	uint16 dl_flag = DL_BEGIN;
+	uint16 dl_type = DL_TYPE_CLM;
+	bool split_iovar = FALSE;
+
+	if (iovar && strncmp(iovar, "txcapload", 9) != 0 &&
+		strncmp(iovar, "clmload", 7) != 0) {
+		split_iovar = TRUE;
+		dl_type = DL_TYPE_DRRBLOB;
+	}
+
+	data_offset = OFFSETOF(wl_dload_data_t, data);
+	size2alloc = data_offset + MAX_CHUNK_LEN;
+	size2alloc = ROUNDUP(size2alloc, 8);
+
+	if ((new_buf = (unsigned char *)MALLOCZ(dhd->osh, size2alloc)) != NULL) {
+		do {
+			if (split_iovar) {
+				/* there is no file handling in split iovar case */
+				if (len >= MAX_CHUNK_LEN) {
+					chunk_len = MAX_CHUNK_LEN;
+				} else {
+					chunk_len = len;
+				}
+				err = memcpy_s(new_buf + data_offset, MAX_CHUNK_LEN,
+					buf + cumulative_len, chunk_len);
+				if (err) {
+					DHD_ERROR(("%s: failed to copy chunk at len %u !\n",
+						__FUNCTION__, cumulative_len));
+					err = BCME_ERROR;
+					goto exit;
+				}
+				cumulative_len += chunk_len;
+			} else {
+#if !defined(__linux__) || defined(DHD_LINUX_STD_FW_API)
+				if (len >= MAX_CHUNK_LEN) {
+					chunk_len = MAX_CHUNK_LEN;
+				} else {
+					chunk_len = len;
+				}
+				err = memcpy_s(new_buf + data_offset, MAX_CHUNK_LEN,
+					buf + cumulative_len, chunk_len);
+				if (err) {
+					DHD_ERROR(("%s: failed to copy chunk at len %u !\n",
+						__FUNCTION__, cumulative_len));
+					err = BCME_ERROR;
+					goto exit;
+				}
+				cumulative_len += chunk_len;
+#else
+				chunk_len = dhd_os_get_image_block((char *)(new_buf + data_offset),
+					MAX_CHUNK_LEN, buf);
+				if (chunk_len < 0) {
+					DHD_ERROR(("%s: dhd_os_get_image_block failed (%d)\n",
+						__FUNCTION__, chunk_len));
+					err = BCME_ERROR;
+					goto exit;
+				}
+#endif /* !__linux__ || DHD_LINUX_STD_FW_API */
+			}
+			if (len - chunk_len == 0) {
+				dl_flag |= DL_END;
+			}
+
+			err = dhd_download_2_dongle(dhd, iovar, dl_flag, dl_type,
+				new_buf, data_offset + chunk_len);
+
+			dl_flag &= ~DL_BEGIN;
+
+			len = len - chunk_len;
+		} while ((len > 0) && (err == 0));
+	} else {
+		DHD_ERROR(("%s: Unable to alloc %u bytes of mem!\n", __FUNCTION__,
+			size2alloc));
+		err = BCME_NOMEM;
+	}
+
+exit:
+	if (new_buf) {
+		MFREE(dhd->osh, new_buf, size2alloc);
+	}
+	return err;
+}
+
+#if defined(CACHE_FW_IMAGES)
+int
+dhd_download_blob_cached(dhd_pub_t *dhd, char *file_path,
+	uint32 len, char *iovar)
+{
+	int ret = BCME_ERROR;
+	uint chunk_len, size2alloc, data_offset, file_offset;
+	unsigned char *pay_load, *dnld_buf;
+	char *memblock = NULL;
+	uint16 dl_flag = DL_BEGIN;
+	download_type_t dl_type;
+	uint32 memblock_len = len;
+
+	data_offset = OFFSETOF(wl_dload_data_t, data);
+	size2alloc = data_offset + MAX_CHUNK_LEN;
+	size2alloc = ROUNDUP(size2alloc, 8);
+	file_offset = 0;
+
+	if ((dnld_buf = MALLOCZ(dhd->osh, size2alloc)) == NULL) {
+		ret = BCME_NOMEM;
+		goto exit;
+	}
+	pay_load = (dnld_buf + data_offset);
+
+	if (!memcmp("clmload", iovar, strlen("clmload"))) {
+		dl_type = CLM_BLOB;
+	} else if (!memcmp("txcapload", iovar, strlen("txcapload"))) {
+		dl_type = TXCAP_BLOB;
+	} else {
+		DHD_ERROR(("%s Invalid iovar :%s \n", __FUNCTION__, iovar));
+		ret = BCME_BADARG;
+		goto exit;
+	}
+
+	ret = dhd_get_download_buffer(dhd, file_path, dl_type, &memblock, (int *)&len);
+	if (ret != BCME_OK) {
+		DHD_ERROR(("%s: error getting buffer for %s, %s \n", __FUNCTION__,
+			file_path, bcmerrorstr(ret)));
+		goto exit;
+	}
+
+	do {
+		chunk_len = MIN(len, MAX_CHUNK_LEN);
+		memcpy(pay_load, memblock + file_offset, chunk_len);
+		if (len - chunk_len == 0) {
+			dl_flag |= DL_END;
+		}
+
+		ret = dhd_download_2_dongle(dhd, iovar, dl_flag, DL_TYPE_CLM,
+			dnld_buf, data_offset + chunk_len);
+
+		dl_flag &= ~DL_BEGIN;
+		len = len - chunk_len;
+		file_offset += chunk_len;
+	} while ((len > 0) && (ret == 0));
+
+exit:
+	if (dnld_buf) {
+		MFREE(dhd->osh, dnld_buf, size2alloc);
+	}
+	if (memblock) {
+		dhd_free_download_buffer(dhd, memblock, memblock_len);
+	}
+
+	return ret;
+}
+
+int
+dhd_apply_default_txcap(dhd_pub_t  *dhd, char *path)
+{
+	int ret = BCME_ERROR;
+	ret = dhd_download_blob_cached(dhd, path, MAX_TXCAP_BUF_SIZE, "txcapload");
+	if (ret) {
+		DHD_ERROR(("%s: error downloading blob: %s \n", __FUNCTION__, bcmerrorstr(ret)));
+	}
+	return ret;
+}
+
+int
+dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path)
+{
+	char *clm_blob_path;
+	int len;
+	unsigned char *imgbuf = NULL;
+	int err = BCME_OK;
+	char iovbuf[WLC_IOCTL_SMLEN];
+	wl_country_t *cspec;
+
+	if (clm_path[0] != '\0') {
+		if (strlen(clm_path) > MOD_PARAM_PATHLEN) {
+			DHD_ERROR(("clm path exceeds max len\n"));
+			return BCME_ERROR;
+		}
+		clm_blob_path = clm_path;
+		DHD_TRACE(("clm path from module param:%s\n", clm_path));
+	} else {
+		clm_blob_path = VENDOR_PATH CONFIG_BCMDHD_CLM_PATH;
+	}
+
+	/* If CLM blob file is found on the filesystem, download the file.
+	* After CLM file download or If the blob file is not present,
+	* validate the country code before proceeding with the initialization.
+	* If country code is not valid, fail the initialization.
+	*/
+
+	imgbuf = dhd_os_open_image((char *)clm_blob_path);
+	if (imgbuf == NULL) {
+		DHD_ERROR(("%s: clm from path %s open fail\n", __func__, clm_path));
+		goto exit;
+	}
+
+	len = dhd_os_get_image_size(imgbuf);
+
+	if ((len > 0) && (len < MAX_CLM_BUF_SIZE) && imgbuf) {
+		len = bcm_mkiovar("country", NULL, 0, iovbuf, sizeof(iovbuf));
+		if (len == 0) {
+			err = BCME_BUFTOOSHORT;
+			goto exit;
+		}
+		err = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0);
+		if (err) {
+			DHD_ERROR(("%s: country code get failed\n", __FUNCTION__));
+			goto exit;
+		}
+
+		cspec = (wl_country_t *)iovbuf;
+		if ((strncmp(cspec->ccode, WL_CCODE_NULL_COUNTRY, WLC_CNTRY_BUF_SZ)) != 0) {
+			DHD_ERROR(("%s: CLM already exist in F/W, "
+				"new CLM data will be added to the end of existing CLM data!\n",
+				__FUNCTION__));
+		}
+
+		/* Found blob file. Download the file */
+		DHD_ERROR(("clm file download from %s \n", clm_blob_path));
+		if (imgbuf) {
+			dhd_os_close_image(imgbuf);
+			imgbuf = NULL;
+		}
+		err = dhd_download_blob_cached(dhd, clm_blob_path, MAX_CLM_BUF_SIZE, "clmload");
+		if (err) {
+			DHD_ERROR(("%s: CLM download failed err=%d\n", __FUNCTION__, err));
+			if (!dhd_bus_skip_clm(dhd)) {
+				/* Retrieve clmload_status and print */
+				len = bcm_mkiovar("clmload_status", NULL, 0, iovbuf,
+						sizeof(iovbuf));
+				if (len == 0) {
+					err = BCME_BUFTOOSHORT;
+					goto exit;
+				}
+				err = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf,
+					sizeof(iovbuf), FALSE, 0);
+				if (err) {
+					DHD_ERROR(("%s: clmload_status get failed err=%d \n",
+						__FUNCTION__, err));
+				} else {
+					DHD_ERROR(("%s: clmload_status: %d \n",
+						__FUNCTION__, *((int *)iovbuf)));
+					if (*((int *)iovbuf) == CHIPID_MISMATCH) {
+						DHD_ERROR(("Chip ID mismatch error \n"));
+					}
+				}
+				err = BCME_ERROR;
+				goto exit;
+			}
+		} else {
+			DHD_INFO(("%s: CLM download succeeded \n", __FUNCTION__));
+		}
+	} else {
+		DHD_INFO(("Skipping the clm download. len:%d memblk:%p \n", len, imgbuf));
+#ifdef DHD_USE_CLMINFO_PARSER
+		err = BCME_ERROR;
+		goto exit;
+#endif /* DHD_USE_CLMINFO_PARSER */
+	}
+
+	/* Verify country code */
+	len = bcm_mkiovar("country", NULL, 0, iovbuf, sizeof(iovbuf));
+	if (len == 0) {
+		err = BCME_BUFTOOSHORT;
+		goto exit;
+	}
+	err = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0);
+	if (err) {
+		DHD_ERROR(("%s: country code get failed\n", __FUNCTION__));
+		goto exit;
+	}
+
+	cspec = (wl_country_t *)iovbuf;
+	if ((strncmp(cspec->ccode, WL_CCODE_NULL_COUNTRY, WLC_CNTRY_BUF_SZ)) == 0) {
+		/* Country code not initialized or CLM download not proper */
+		DHD_ERROR(("country code not initialized\n"));
+		err = BCME_ERROR;
+	}
+exit:
+
+	if (imgbuf) {
+		dhd_os_close_image(imgbuf);
+	}
+
+	return err;
+}
+#else
+
+int
+dhd_apply_default_txcap(dhd_pub_t  *dhd, char *path)
+{
+	return 0;
+}
+
+int
+dhd_check_current_clm_data(dhd_pub_t *dhd)
+{
+	char iovbuf[WLC_IOCTL_SMLEN];
+	wl_country_t *cspec;
+	int err = BCME_OK;
+
+	memset(iovbuf, 0, sizeof(iovbuf));
+	err = bcm_mkiovar("country", NULL, 0, iovbuf, sizeof(iovbuf));
+	if (err == 0) {
+		err = BCME_BUFTOOSHORT;
+		DHD_ERROR(("%s: bcm_mkiovar failed.", __FUNCTION__));
+		return err;
+	}
+	err = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0);
+	if (err) {
+		DHD_ERROR(("%s: country code get failed\n", __FUNCTION__));
+		return err;
+	}
+	cspec = (wl_country_t *)iovbuf;
+	if ((strncmp(cspec->ccode, WL_CCODE_NULL_COUNTRY, WLC_CNTRY_BUF_SZ)) == 0) {
+		DHD_ERROR(("%s: ----- This FW is not included CLM data -----\n",
+			__FUNCTION__));
+		return FALSE;
+	}
+	DHD_ERROR(("%s: ----- This FW is included CLM data -----\n",
+		__FUNCTION__));
+	return TRUE;
+}
+
+int
+dhd_apply_default_clm(dhd_pub_t *dhd, char *clm_path)
+{
+	char *clm_blob_path;
+	int len = 0, memblock_len = 0;
+	char *memblock = NULL;
+	int err = BCME_OK;
+	char iovbuf[WLC_IOCTL_SMLEN];
+	int status = FALSE;
+#ifdef SUPPORT_OTA_UPDATE
+	ota_update_info_t *ota_info = &dhd->ota_update_info;
+#endif /* SUPPORT_OTA_UPDATE */
+
+	if (clm_path && clm_path[0] != '\0') {
+		if (strlen(clm_path) > MOD_PARAM_PATHLEN) {
+			DHD_ERROR(("clm path exceeds max len\n"));
+			return BCME_ERROR;
+		}
+		clm_blob_path = clm_path;
+		DHD_TRACE(("clm path from module param:%s\n", clm_path));
+	} else {
+#ifdef DHD_LINUX_STD_FW_API
+		clm_blob_path = DHD_CLM_NAME;
+#else
+		clm_blob_path = VENDOR_PATH CONFIG_BCMDHD_CLM_PATH;
+#endif /* DHD_LINUX_STD_FW_API */
+	}
+
+	/* If CLM blob file is found on the filesystem, download the file.
+	 * After CLM file download or If the blob file is not present,
+	 * validate the country code before proceeding with the initialization.
+	 * If country code is not valid, fail the initialization.
+	 */
+#if (!defined(LINUX) && !defined(linux)) || defined(DHD_LINUX_STD_FW_API)
+	len = MAX_CLM_BUF_SIZE;
+	dhd_get_download_buffer(dhd, clm_blob_path, CLM_BLOB, &memblock, &len);
+#ifdef DHD_LINUX_STD_FW_API
+	memblock_len = len;
+#else
+	memblock_len = MAX_CLM_BUF_SIZE;
+#endif /* DHD_LINUX_STD_FW_API */
+#else
+	memblock = dhd_os_open_image1(dhd, (char *)clm_blob_path);
+	len = dhd_os_get_image_size(memblock);
+	BCM_REFERENCE(memblock_len);
+#endif /* !LINUX && !linux || DHD_LINUX_STD_FW_API */
+
+#if defined(LINUX) || defined(linux)
+	if (memblock == NULL) {
+		printf("%s: Ignore clm file %s\n", __FUNCTION__, clm_path);
+#if defined(DHD_BLOB_EXISTENCE_CHECK)
+		if (!dhd->is_blob) {
+			status = dhd_check_current_clm_data(dhd);
+			if (status == TRUE) {
+				err = BCME_OK;
+			} else {
+				err = status;
+			}
+		}
+#endif /* DHD_BLOB_EXISTENCE_CHECK */
+		goto exit;
+	}
+#endif /* defined(LINUX) || defined(linux) */
+
+	if ((len > 0) && (len < MAX_CLM_BUF_SIZE) && memblock) {
+		status = dhd_check_current_clm_data(dhd);
+		if (status == TRUE) {
+#if defined(DHD_BLOB_EXISTENCE_CHECK)
+			if (dhd->op_mode != DHD_FLAG_MFG_MODE) {
+				if (dhd->is_blob) {
+					err = BCME_ERROR;
+				}
+				goto exit;
+			}
+#else
+			DHD_ERROR(("%s: CLM already exist in F/W, "
+				"new CLM data will be added to the end of existing CLM data!\n",
+				__FUNCTION__));
+#endif /* DHD_BLOB_EXISTENCE_CHECK */
+		} else if (status != FALSE) {
+			err = status;
+			goto exit;
+		}
+
+		/* Found blob file. Download the file */
+		DHD_TRACE(("clm file download from %s \n", clm_blob_path));
+		err = dhd_download_blob(dhd, (unsigned char*)memblock, len, "clmload");
+		if (err) {
+			DHD_ERROR(("%s: CLM download failed err=%d\n", __FUNCTION__, err));
+			/* Retrieve clmload_status and print */
+			memset(iovbuf, 0, sizeof(iovbuf));
+			len = bcm_mkiovar("clmload_status", NULL, 0, iovbuf, sizeof(iovbuf));
+			if (len == 0) {
+				err = BCME_BUFTOOSHORT;
+				goto exit;
+			}
+			err = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0);
+			if (err) {
+				DHD_ERROR(("%s: clmload_status get failed err=%d \n",
+					__FUNCTION__, err));
+			} else {
+				DHD_ERROR(("%s: clmload_status: %d \n",
+					__FUNCTION__, *((int *)iovbuf)));
+				if (*((int *)iovbuf) == CHIPID_MISMATCH) {
+					DHD_ERROR(("Chip ID mismatch error \n"));
+				}
+			}
+			err = BCME_ERROR;
+			goto exit;
+		} else {
+			DHD_ERROR(("%s: CLM download succeeded \n", __FUNCTION__));
+		}
+	} else {
+		DHD_INFO(("Skipping the clm download. len:%d memblk:%p \n", len, memblock));
+	}
+
+	/* Verify country code */
+	status = dhd_check_current_clm_data(dhd);
+
+	if (status != TRUE) {
+		/* Country code not initialized or CLM download not proper */
+		DHD_ERROR(("country code not initialized\n"));
+		err = status;
+	}
+exit:
+
+	if (memblock) {
+#ifdef SUPPORT_OTA_UPDATE
+		if (ota_info->clm_len) {
+			MFREE(dhd->osh, ota_info->clm_buf, ota_info->clm_len);
+			ota_info->clm_len = 0;
+		}
+		else
+#endif /* SUPPORT_OTA_UPDATE */
+		{
+#if (defined(LINUX) || defined(linux)) && !defined(DHD_LINUX_STD_FW_API)
+			dhd_os_close_image1(dhd, memblock);
+#else
+			dhd_free_download_buffer(dhd, memblock, memblock_len);
+#endif /* LINUX || linux */
+		}
+	}
+
+	return err;
+}
+#endif /* defined(CACHE_FW_IMAGES) */
+
+void dhd_free_download_buffer(dhd_pub_t	*dhd, void *buffer, int length)
+{
+#ifdef CACHE_FW_IMAGES
+	return;
+#endif
+#if defined(DHD_LINUX_STD_FW_API)
+	VMFREE(dhd->osh, buffer, length);
+#else
+	MFREE(dhd->osh, buffer, length);
+#endif /* DHD_LINUX_STD_FW_API */
+}
+
+#ifdef REPORT_FATAL_TIMEOUTS
+void
+init_dhd_timeouts(dhd_pub_t *pub)
+{
+	pub->timeout_info = MALLOC(pub->osh, sizeof(timeout_info_t));
+	if (pub->timeout_info == NULL) {
+		DHD_ERROR(("%s: Failed to alloc timeout_info\n", __FUNCTION__));
+	} else {
+		DHD_INFO(("Initializing dhd_timeouts\n"));
+		pub->timeout_info->scan_timer_lock = osl_spin_lock_init(pub->osh);
+		pub->timeout_info->join_timer_lock = osl_spin_lock_init(pub->osh);
+		pub->timeout_info->bus_timer_lock = osl_spin_lock_init(pub->osh);
+		pub->timeout_info->cmd_timer_lock = osl_spin_lock_init(pub->osh);
+		pub->timeout_info->scan_timeout_val = SCAN_TIMEOUT_DEFAULT;
+		pub->timeout_info->join_timeout_val = JOIN_TIMEOUT_DEFAULT;
+		pub->timeout_info->cmd_timeout_val = CMD_TIMEOUT_DEFAULT;
+		pub->timeout_info->bus_timeout_val = BUS_TIMEOUT_DEFAULT;
+		pub->timeout_info->scan_timer_active = FALSE;
+		pub->timeout_info->join_timer_active = FALSE;
+		pub->timeout_info->cmd_timer_active = FALSE;
+		pub->timeout_info->bus_timer_active = FALSE;
+		pub->timeout_info->cmd_join_error = FALSE;
+		pub->timeout_info->cmd_request_id = 0;
+		OSL_ATOMIC_SET(pub->osh, &pub->set_ssid_rcvd, FALSE);
+	}
+}
+
+void
+deinit_dhd_timeouts(dhd_pub_t *pub)
+{
+	/* stop the join, scan bus, cmd timers
+	 * as failing to do so may cause a kernel panic if
+	 * an rmmod is done
+	 */
+	if (!pub->timeout_info) {
+		DHD_ERROR(("%s timeout_info pointer is NULL\n", __FUNCTION__));
+		ASSERT(0);
+		return;
+	}
+	if (dhd_stop_scan_timer(pub, FALSE, 0)) {
+		DHD_ERROR(("%s dhd_stop_scan_timer failed\n", __FUNCTION__));
+		ASSERT(0);
+	}
+	if (dhd_stop_bus_timer(pub)) {
+		DHD_ERROR(("%s dhd_stop_bus_timer failed\n", __FUNCTION__));
+		ASSERT(0);
+	}
+	if (dhd_stop_cmd_timer(pub)) {
+		DHD_ERROR(("%s dhd_stop_cmd_timer failed\n", __FUNCTION__));
+		ASSERT(0);
+	}
+	if (dhd_stop_join_timer(pub)) {
+		DHD_ERROR(("%s dhd_stop_join_timer failed\n", __FUNCTION__));
+		ASSERT(0);
+	}
+
+	osl_spin_lock_deinit(pub->osh, pub->timeout_info->scan_timer_lock);
+	osl_spin_lock_deinit(pub->osh, pub->timeout_info->join_timer_lock);
+	osl_spin_lock_deinit(pub->osh, pub->timeout_info->bus_timer_lock);
+	osl_spin_lock_deinit(pub->osh, pub->timeout_info->cmd_timer_lock);
+	MFREE(pub->osh, pub->timeout_info, sizeof(timeout_info_t));
+}
+
+static void
+dhd_cmd_timeout(void *ctx)
+{
+	dhd_pub_t *pub = (dhd_pub_t *)ctx;
+	unsigned long flags;
+
+	if (!pub->timeout_info) {
+		DHD_ERROR(("DHD: timeout_info NULL\n"));
+		ASSERT(0);
+		return;
+	}
+
+	DHD_TIMER_LOCK(pub->timeout_info->cmd_timer_lock, flags);
+	if (pub->timeout_info && pub->timeout_info->cmd_timer_active) {
+		DHD_ERROR(("\nERROR COMMAND TIMEOUT TO:%d\n", pub->timeout_info->cmd_timeout_val));
+		DHD_TIMER_UNLOCK(pub->timeout_info->cmd_timer_lock, flags);
+#ifdef PCIE_OOB
+		/* Assert device_wake so that UART_Rx is available */
+		if (dhd_bus_set_device_wake(pub->bus, TRUE)) {
+			DHD_ERROR(("%s: dhd_bus_set_device_wake() failed\n", __FUNCTION__));
+			ASSERT(0);
+		}
+#endif /* PCIE_OOB */
+		if (dhd_stop_cmd_timer(pub)) {
+			DHD_ERROR(("%s: dhd_stop_cmd_timer() failed\n", __FUNCTION__));
+			ASSERT(0);
+		}
+		if (!dhd_query_bus_erros(pub))
+			dhd_send_trap_to_fw_for_timeout(pub, DHD_REASON_COMMAND_TO);
+	} else {
+		DHD_TIMER_UNLOCK(pub->timeout_info->cmd_timer_lock, flags);
+	}
+}
+
+int
+dhd_start_cmd_timer(dhd_pub_t *pub)
+{
+	int ret = BCME_OK;
+	unsigned long flags = 0;
+	uint32 cmd_to_ms;
+
+	if (!pub->timeout_info) {
+		DHD_ERROR(("DHD: timeout_info NULL\n"));
+		ret = BCME_ERROR;
+		ASSERT(0);
+		goto exit_null;
+	}
+	DHD_TIMER_LOCK(pub->timeout_info->cmd_timer_lock, flags);
+	cmd_to_ms = pub->timeout_info->cmd_timeout_val;
+
+	if (pub->timeout_info->cmd_timeout_val == 0) {
+		/* Disable Command timer timeout */
+		DHD_INFO(("DHD: Command Timeout Disabled\n"));
+		goto exit;
+	}
+	if (pub->timeout_info->cmd_timer_active) {
+		DHD_ERROR(("%s:Timer already active\n", __FUNCTION__));
+		ret = BCME_ERROR;
+		ASSERT(0);
+	} else {
+		pub->timeout_info->cmd_timer = osl_timer_init(pub->osh,
+			"cmd_timer", dhd_cmd_timeout, pub);
+		osl_timer_update(pub->osh, pub->timeout_info->cmd_timer,
+			cmd_to_ms, 0);
+		pub->timeout_info->cmd_timer_active = TRUE;
+	}
+	if (ret == BCME_OK) {
+		DHD_INFO(("%s Cmd Timer started\n", __FUNCTION__));
+	}
+exit:
+	DHD_TIMER_UNLOCK(pub->timeout_info->cmd_timer_lock, flags);
+exit_null:
+	return ret;
+}
+
+int
+dhd_stop_cmd_timer(dhd_pub_t *pub)
+{
+	int ret = BCME_OK;
+	unsigned long flags = 0;
+
+	if (!pub) {
+		DHD_ERROR(("DHD: pub NULL\n"));
+		ASSERT(0);
+		return BCME_ERROR;
+	}
+
+	if (!pub->timeout_info) {
+		DHD_ERROR(("DHD: timeout_info NULL\n"));
+		ret = BCME_ERROR;
+		ASSERT(0);
+		goto exit;
+	}
+	DHD_TIMER_LOCK(pub->timeout_info->cmd_timer_lock, flags);
+
+	if (pub->timeout_info->cmd_timer_active) {
+		osl_timer_del(pub->osh, pub->timeout_info->cmd_timer);
+		pub->timeout_info->cmd_timer_active = FALSE;
+	}
+	else {
+		DHD_INFO(("DHD: CMD timer is not active\n"));
+	}
+	if (ret == BCME_OK) {
+		DHD_INFO(("%s Cmd Timer Stopped\n", __FUNCTION__));
+	}
+	DHD_TIMER_UNLOCK(pub->timeout_info->cmd_timer_lock, flags);
+exit:
+	return ret;
+}
+
+static int
+__dhd_stop_join_timer(dhd_pub_t *pub)
+{
+	int ret = BCME_OK;
+	if (!pub) {
+		DHD_ERROR(("DHD: pub NULL\n"));
+		ASSERT(0);
+		return BCME_ERROR;
+	}
+	if (!pub->timeout_info) {
+		DHD_ERROR(("DHD: timeout_info NULL\n"));
+		ASSERT(0);
+		return BCME_ERROR;
+	}
+
+	if (pub->timeout_info->join_timer_active) {
+		osl_timer_del(pub->osh, pub->timeout_info->join_timer);
+		pub->timeout_info->join_timer_active = FALSE;
+		DHD_INFO(("%s join timer stopped\n", __FUNCTION__));
+	} else {
+		DHD_INFO(("%s join timer is not active\n", __FUNCTION__));
+	}
+
+	return ret;
+}
+
+static void
+dhd_join_timeout(void *ctx)
+{
+	dhd_pub_t *pub = (dhd_pub_t *)ctx;
+	unsigned long flags;
+
+	if (!pub->timeout_info) {
+		DHD_ERROR(("%s DHD: timeout_info NULL\n", __FUNCTION__));
+		ASSERT(0);
+		return;
+	}
+
+	DHD_TIMER_LOCK(pub->timeout_info->join_timer_lock, flags);
+	if (pub->timeout_info->join_timer_active) {
+		if (__dhd_stop_join_timer(pub)) {
+			DHD_ERROR(("%s: __dhd_stop_join_timer() failed\n", __FUNCTION__));
+			ASSERT(0);
+		}
+		if (pub->timeout_info->cmd_join_error) {
+			DHD_ERROR(("\n%s ERROR JOIN TIMEOUT TO:%d:0x%x\n", __FUNCTION__,
+				pub->timeout_info->join_timeout_val,
+				pub->timeout_info->cmd_join_error));
+			if (!dhd_query_bus_erros(pub)) {
+				dhd_send_trap_to_fw_for_timeout(pub, DHD_REASON_JOIN_TO);
+			}
+			pub->timeout_info->cmd_join_error = 0;
+		}
+	}
+	DHD_TIMER_UNLOCK(pub->timeout_info->join_timer_lock, flags);
+}
+
+int
+dhd_start_join_timer(dhd_pub_t *pub)
+{
+	int ret = BCME_OK;
+	unsigned long flags = 0;
+	uint32 join_to_ms;
+
+	if (!pub->timeout_info) {
+		DHD_ERROR(("%s DHD: timeout_info NULL\n", __FUNCTION__));
+		ret = BCME_ERROR;
+		ASSERT(0);
+		goto exit;
+	}
+
+	join_to_ms = pub->timeout_info->join_timeout_val;
+	DHD_TIMER_LOCK(pub->timeout_info->join_timer_lock, flags);
+	if (pub->timeout_info->join_timer_active) {
+		DHD_ERROR(("%s: stopping active timer\n", __FUNCTION__));
+		__dhd_stop_join_timer(pub);
+	}
+	if (pub->timeout_info->join_timeout_val == 0) {
+		/* Disable Join timer timeout */
+		DHD_INFO(("%s DHD: join timeout disabled\n", __FUNCTION__));
+	} else {
+		pub->timeout_info->join_timer = osl_timer_init(pub->osh,
+			"join_timer", dhd_join_timeout, pub);
+		osl_timer_update(pub->osh, pub->timeout_info->join_timer, join_to_ms, 0);
+		pub->timeout_info->join_timer_active = TRUE;
+		pub->timeout_info->cmd_join_error = 0;
+		dhd_set_join_error(pub, WLC_SSID_MASK);
+		if (pub->secure_join) {
+			dhd_set_join_error(pub, WLC_WPA_MASK);
+		}
+		DHD_ERROR(("%s: join timer started 0x%x\n", __FUNCTION__,
+			pub->timeout_info->cmd_join_error));
+	}
+	DHD_TIMER_UNLOCK(pub->timeout_info->join_timer_lock, flags);
+exit:
+	return ret;
+}
+
+int
+dhd_stop_join_timer(dhd_pub_t *pub)
+{
+	int ret = BCME_OK;
+	unsigned long flags;
+
+	if (!pub) {
+		DHD_ERROR(("%s DHD: pub NULL\n", __FUNCTION__));
+		ASSERT(0);
+		return BCME_ERROR;
+	}
+
+	DHD_TIMER_LOCK(pub->timeout_info->join_timer_lock, flags);
+	ret = __dhd_stop_join_timer(pub);
+	DHD_TIMER_UNLOCK(pub->timeout_info->join_timer_lock, flags);
+	return ret;
+}
+
+static void
+dhd_set_join_error(dhd_pub_t *pub, uint32 mask)
+{
+	DHD_INFO(("Setting join Error %d\n", mask));
+	if (pub->timeout_info) {
+		pub->timeout_info->cmd_join_error |= mask;
+	}
+}
+
+void
+dhd_clear_join_error(dhd_pub_t *pub, uint32 mask)
+{
+	unsigned long flags;
+
+	DHD_INFO(("%s clear join error %d\n", __FUNCTION__, mask));
+	if (!(pub->timeout_info)) {
+		return;
+	}
+
+	DHD_TIMER_LOCK(pub->timeout_info->join_timer_lock, flags);
+	pub->timeout_info->cmd_join_error &= ~mask;
+	/* If both WLC_SSID_MASK, WLC_WPA_MASK are received cancel the timer */
+	if (!(pub->timeout_info->cmd_join_error)) {
+		if (__dhd_stop_join_timer(pub)) {
+			DHD_ERROR(("%s: dhd_stop_join_timer failed\n", __FUNCTION__));
+			ASSERT(0);
+		}
+	}
+	DHD_TIMER_UNLOCK(pub->timeout_info->join_timer_lock, flags);
+}
+
+static void
+dhd_scan_timeout(void *ctx)
+{
+	dhd_pub_t *pub = (dhd_pub_t *)ctx;
+	unsigned long flags;
+
+	if (!pub) {
+		DHD_ERROR(("DHD: pub NULL\n"));
+		ASSERT(0);
+		return;
+	}
+
+	if (pub->timeout_info == NULL) {
+		DHD_ERROR(("timeout_info pointer is NULL\n"));
+		ASSERT(0);
+		return;
+	}
+	DHD_TIMER_LOCK(pub->timeout_info->scan_timer_lock, flags);
+	if (pub->timeout_info->scan_timer_active) {
+		DHD_ERROR(("\nERROR SCAN TIMEOUT TO:%d\n", pub->timeout_info->scan_timeout_val));
+		DHD_TIMER_UNLOCK(pub->timeout_info->scan_timer_lock, flags);
+		dhd_stop_scan_timer(pub, FALSE, 0);
+		if (!dhd_query_bus_erros(pub))
+			dhd_send_trap_to_fw_for_timeout(pub, DHD_REASON_SCAN_TO);
+	} else {
+		DHD_TIMER_UNLOCK(pub->timeout_info->scan_timer_lock, flags);
+	}
+}
+
+int
+dhd_start_scan_timer(dhd_pub_t *pub, bool is_escan)
+{
+	int ret = BCME_OK;
+	unsigned long flags = 0;
+	uint32 scan_to_ms;
+
+	if (!pub->timeout_info) {
+		DHD_ERROR(("DHD: timeout_info NULL\n"));
+		ret = BCME_ERROR;
+		ASSERT(0);
+		goto exit_null;
+	}
+	DHD_TIMER_LOCK(pub->timeout_info->scan_timer_lock, flags);
+	scan_to_ms = pub->timeout_info->scan_timeout_val;
+
+	if (is_escan) {
+		if (pub->timeout_info->escan_aborted &&
+				pub->esync_id == pub->timeout_info->abort_syncid) {
+			pub->timeout_info->escan_aborted = FALSE;
+			DHD_INFO(("%s: escan already aborted, do not start timer \n",
+				__FUNCTION__));
+			goto exit;
+		}
+		pub->timeout_info->escan_syncid = pub->esync_id;
+	} else {
+		pub->timeout_info->escan_syncid = 0;
+	}
+
+	if (pub->timeout_info->scan_timer_active) {
+		/* cancel any earlier running timer */
+		DHD_INFO(("%s:Timer already active, stopping it.\n", __FUNCTION__));
+		osl_timer_del(pub->osh, pub->timeout_info->scan_timer);
+		pub->timeout_info->scan_timer_active = FALSE;
+	}
+
+	if (pub->timeout_info->scan_timeout_val == 0) {
+		/* Disable Scan timer timeout */
+		DHD_INFO(("DHD: Scan Timeout Disabled\n"));
+	} else {
+		pub->timeout_info->scan_timer = osl_timer_init(pub->osh, "scan_timer",
+			dhd_scan_timeout, pub);
+		pub->timeout_info->scan_timer_active = TRUE;
+		osl_timer_update(pub->osh, pub->timeout_info->scan_timer, scan_to_ms, 0);
+		DHD_INFO(("%s Scan Timer started\n", __FUNCTION__));
+	}
+
+exit:
+	DHD_TIMER_UNLOCK(pub->timeout_info->scan_timer_lock, flags);
+exit_null:
+	return ret;
+}
+
+int
+dhd_stop_scan_timer(dhd_pub_t *pub, bool is_escan, uint16 sync_id)
+{
+	int ret = BCME_OK;
+	unsigned long flags = 0;
+
+	if (!pub) {
+		DHD_ERROR(("DHD: pub NULL\n"));
+		ASSERT(0);
+		return BCME_ERROR;
+	}
+
+	if (!pub->timeout_info) {
+		DHD_ERROR(("DHD: timeout_info NULL\n"));
+		ret = BCME_ERROR;
+		ASSERT(0);
+		goto exit_null;
+	}
+
+	DHD_TIMER_LOCK(pub->timeout_info->scan_timer_lock, flags);
+
+	if (pub->timeout_info->scan_timer_active) {
+		if (is_escan) {
+			if (sync_id == pub->timeout_info->escan_syncid) {
+				osl_timer_del(pub->osh, pub->timeout_info->scan_timer);
+				pub->timeout_info->scan_timer_active = FALSE;
+				DHD_INFO(("%s Scan Timer Stopped\n", __FUNCTION__));
+			}
+		} else {
+			osl_timer_del(pub->osh, pub->timeout_info->scan_timer);
+			pub->timeout_info->scan_timer_active = FALSE;
+			DHD_INFO(("%s Scan Timer Stopped\n", __FUNCTION__));
+		}
+
+	} else {
+		DHD_INFO(("DHD: SCAN timer is not active\n"));
+	}
+
+	DHD_TIMER_UNLOCK(pub->timeout_info->scan_timer_lock, flags);
+
+exit_null:
+	return ret;
+}
+
+static void
+dhd_bus_timeout(void *ctx)
+{
+	dhd_pub_t *pub = (dhd_pub_t *)ctx;
+	unsigned long flags;
+
+	if (pub->timeout_info == NULL) {
+		DHD_ERROR(("timeout_info pointer is NULL\n"));
+		ASSERT(0);
+		return;
+	}
+
+	DHD_TIMER_LOCK(pub->timeout_info->bus_timer_lock, flags);
+	if (pub->timeout_info && pub->timeout_info->bus_timer_active) {
+		DHD_ERROR(("\nERROR BUS TIMEOUT TO:%d\n", pub->timeout_info->bus_timeout_val));
+		DHD_TIMER_UNLOCK(pub->timeout_info->bus_timer_lock, flags);
+#ifdef PCIE_OOB
+		/* Assert device_wake so that UART_Rx is available */
+		if (dhd_bus_set_device_wake(pub->bus, TRUE)) {
+			DHD_ERROR(("%s: dhd_bus_set_device_wake() failed\n", __FUNCTION__));
+			ASSERT(0);
+		}
+#endif /* PCIE_OOB */
+		if (dhd_stop_bus_timer(pub)) {
+			DHD_ERROR(("%s: dhd_stop_bus_timer() failed\n", __FUNCTION__));
+			ASSERT(0);
+		}
+		if (!dhd_query_bus_erros(pub)) {
+			dhd_send_trap_to_fw_for_timeout(pub, DHD_REASON_OQS_TO);
+		}
+#ifdef BCMPCIE
+		dhd_msgbuf_iovar_timeout_dump(pub);
+#endif /* BCMPCIE */
+	} else {
+		DHD_TIMER_UNLOCK(pub->timeout_info->bus_timer_lock, flags);
+	}
+}
+
+int
+dhd_start_bus_timer(dhd_pub_t *pub)
+{
+	int ret = BCME_OK;
+	unsigned long flags = 0;
+	uint32 bus_to_ms;
+
+	if (!pub->timeout_info) {
+		DHD_ERROR(("DHD: timeout_info NULL\n"));
+		ret = BCME_ERROR;
+		ASSERT(0);
+		goto exit_null;
+	}
+	DHD_TIMER_LOCK(pub->timeout_info->bus_timer_lock, flags);
+	bus_to_ms = pub->timeout_info->bus_timeout_val;
+
+	if (pub->timeout_info->bus_timeout_val == 0) {
+		/* Disable Bus timer timeout */
+		DHD_INFO(("DHD: Bus Timeout Disabled\n"));
+		goto exit;
+	}
+	if (pub->timeout_info->bus_timer_active) {
+		DHD_ERROR(("%s:Timer already active\n", __FUNCTION__));
+		ret = BCME_ERROR;
+		ASSERT(0);
+	} else {
+		pub->timeout_info->bus_timer = osl_timer_init(pub->osh,
+			"bus_timer", dhd_bus_timeout, pub);
+		pub->timeout_info->bus_timer_active = TRUE;
+		osl_timer_update(pub->osh, pub->timeout_info->bus_timer, bus_to_ms, 0);
+	}
+	if (ret == BCME_OK) {
+		DHD_INFO(("%s: BUS Timer started\n", __FUNCTION__));
+	}
+exit:
+	DHD_TIMER_UNLOCK(pub->timeout_info->bus_timer_lock, flags);
+exit_null:
+	return ret;
+}
+
+int
+dhd_stop_bus_timer(dhd_pub_t *pub)
+{
+	int ret = BCME_OK;
+	unsigned long flags;
+
+	if (!pub) {
+		DHD_ERROR(("DHD: pub NULL\n"));
+		ASSERT(0);
+		return BCME_ERROR;
+	}
+
+	if (!pub->timeout_info) {
+		DHD_ERROR(("DHD: timeout_info NULL\n"));
+		ret = BCME_ERROR;
+		ASSERT(0);
+		goto exit;
+	}
+
+	DHD_TIMER_LOCK(pub->timeout_info->bus_timer_lock, flags);
+
+	if (pub->timeout_info->bus_timer_active) {
+		osl_timer_del(pub->osh, pub->timeout_info->bus_timer);
+		pub->timeout_info->bus_timer_active = FALSE;
+	}
+	else {
+		DHD_INFO(("DHD: BUS timer is not active\n"));
+	}
+	if (ret == BCME_OK) {
+		DHD_INFO(("%s: Bus Timer Stopped\n", __FUNCTION__));
+	}
+	DHD_TIMER_UNLOCK(pub->timeout_info->bus_timer_lock, flags);
+exit:
+	return ret;
+}
+
+int
+dhd_set_request_id(dhd_pub_t *pub, uint16 id, uint32 cmd)
+{
+	DHD_INFO(("%s: id:%d\n", __FUNCTION__, id));
+	if (pub->timeout_info) {
+		pub->timeout_info->cmd_request_id = id;
+		pub->timeout_info->cmd = cmd;
+		return BCME_OK;
+	} else {
+		return BCME_ERROR;
+	}
+}
+
+uint16
+dhd_get_request_id(dhd_pub_t *pub)
+{
+	if (pub->timeout_info) {
+		return (pub->timeout_info->cmd_request_id);
+	} else {
+		return 0;
+	}
+}
+
+void
+dhd_get_scan_to_val(dhd_pub_t *pub, uint32 *to_val)
+{
+	if (pub->timeout_info) {
+		*to_val = pub->timeout_info->scan_timeout_val;
+	} else {
+		*to_val = 0;
+	}
+}
+
+void
+dhd_set_scan_to_val(dhd_pub_t *pub, uint32 to_val)
+{
+	if (pub->timeout_info) {
+		DHD_INFO(("Setting scan TO val:%d\n", to_val));
+		pub->timeout_info->scan_timeout_val = to_val;
+	}
+}
+
+void
+dhd_get_join_to_val(dhd_pub_t *pub, uint32 *to_val)
+{
+	if (pub->timeout_info) {
+		*to_val = pub->timeout_info->join_timeout_val;
+	} else {
+		*to_val = 0;
+	}
+}
+
+void
+dhd_set_join_to_val(dhd_pub_t *pub, uint32 to_val)
+{
+	if (pub->timeout_info) {
+		DHD_INFO(("Setting join TO val:%d\n", to_val));
+		pub->timeout_info->join_timeout_val = to_val;
+	}
+}
+
+void
+dhd_get_cmd_to_val(dhd_pub_t *pub, uint32 *to_val)
+{
+	if (pub->timeout_info) {
+		*to_val = pub->timeout_info->cmd_timeout_val;
+	} else {
+		*to_val = 0;
+	}
+}
+
+void
+dhd_set_cmd_to_val(dhd_pub_t *pub, uint32 to_val)
+{
+	if (pub->timeout_info) {
+		DHD_INFO(("Setting cmd TO val:%d\n", to_val));
+		pub->timeout_info->cmd_timeout_val = to_val;
+	}
+}
+
+void
+dhd_get_bus_to_val(dhd_pub_t *pub, uint32 *to_val)
+{
+	if (pub->timeout_info) {
+		*to_val = pub->timeout_info->bus_timeout_val;
+	} else {
+		*to_val = 0;
+	}
+}
+
+void
+dhd_set_bus_to_val(dhd_pub_t *pub, uint32 to_val)
+{
+	if (pub->timeout_info) {
+		DHD_INFO(("Setting bus TO val:%d\n", to_val));
+		pub->timeout_info->bus_timeout_val = to_val;
+	}
+}
+#endif /* REPORT_FATAL_TIMEOUTS */
+
+#ifdef SHOW_LOGTRACE
+int
+dhd_parse_logstrs_file(osl_t *osh, char *raw_fmts, int logstrs_size,
+		dhd_event_log_t *event_log)
+{
+	uint32 *lognums = NULL;
+	char *logstrs = NULL;
+	logstr_trailer_t *trailer = NULL;
+	int ram_index = 0;
+	char **fmts = NULL;
+	int num_fmts = 0;
+	bool match_fail = TRUE;
+	int32 i = 0;
+	uint8 *pfw_id = NULL;
+	uint32 fwid = 0;
+	char fwid_str[FWID_STR_LEN];
+	uint32 hdr_logstrs_size = 0;
+#ifdef DHD_LINUX_STD_FW_API
+	int err = 0;
+	const struct firmware *fw = NULL;
+#else
+	void *file = NULL;
+	int file_len = 0;
+#endif /* DHD_LINUX_STD_FW_API */
+
+	/* Read last three words in the logstrs.bin file */
+	trailer = (logstr_trailer_t *) (raw_fmts + logstrs_size -
+		sizeof(logstr_trailer_t));
+	if (trailer->log_magic == LOGSTRS_MAGIC) {
+		/*
+		* logstrs.bin has a header.
+		*/
+		if (trailer->version == 1) {
+			logstr_header_v1_t *hdr_v1 = (logstr_header_v1_t *) (raw_fmts +
+					logstrs_size - sizeof(logstr_header_v1_t));
+			DHD_INFO(("%s: logstr header version = %u\n",
+					__FUNCTION__, hdr_v1->version));
+			num_fmts =	hdr_v1->rom_logstrs_offset / sizeof(uint32);
+			ram_index = (hdr_v1->ram_lognums_offset -
+				hdr_v1->rom_lognums_offset) / sizeof(uint32);
+			lognums = (uint32 *) &raw_fmts[hdr_v1->rom_lognums_offset];
+			logstrs = (char *)	 &raw_fmts[hdr_v1->rom_logstrs_offset];
+			hdr_logstrs_size = hdr_v1->logstrs_size;
+		} else if (trailer->version == 2) {
+			logstr_header_t *hdr = (logstr_header_t *) (raw_fmts + logstrs_size -
+					sizeof(logstr_header_t));
+			DHD_INFO(("%s: logstr header version = %u; flags = %x\n",
+					__FUNCTION__, hdr->version, hdr->flags));
+
+			/* For ver. 2 of the header, need to match fwid of
+			 *  both logstrs.bin and fw bin
+			 */
+#ifdef DHD_LINUX_STD_FW_API
+			err = dhd_os_get_img_fwreq(&fw, st_str_file_path);
+			if (err < 0) {
+				DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n",
+					err));
+				goto error;
+			}
+			memset(fwid_str, 0, sizeof(fwid_str));
+			err = memcpy_s(fwid_str, (sizeof(fwid_str) - 1),
+				&(fw->data[fw->size - (sizeof(fwid_str) - 1)]),
+				(sizeof(fwid_str) - 1));
+			if (err) {
+				DHD_ERROR(("%s: failed to copy raw_fmts, err=%d\n",
+					__FUNCTION__, err));
+				goto error;
+			}
+#else
+			/* read the FWID from fw bin */
+			file = dhd_os_open_image1(NULL, st_str_file_path);
+			if (!file) {
+				DHD_ERROR(("%s: cannot open fw file !\n", __FUNCTION__));
+				goto error;
+			}
+			file_len = dhd_os_get_image_size(file);
+			if (file_len <= 0) {
+				DHD_ERROR(("%s: bad fw file length !\n", __FUNCTION__));
+				goto error;
+			}
+			/* fwid is at the end of fw bin in string format */
+			if (dhd_os_seek_file(file, file_len - (sizeof(fwid_str) - 1)) < 0) {
+				DHD_ERROR(("%s: can't seek file \n", __FUNCTION__));
+				goto error;
+			}
+
+			memset(fwid_str, 0, sizeof(fwid_str));
+			if (dhd_os_get_image_block(fwid_str, sizeof(fwid_str) - 1, file) <= 0) {
+				DHD_ERROR(("%s: read fw file failed !\n", __FUNCTION__));
+				goto error;
+			}
+#endif /* DHD_LINUX_STD_FW_API */
+			pfw_id = (uint8 *)bcmstrnstr(fwid_str, sizeof(fwid_str) - 1,
+					FWID_STR_1, strlen(FWID_STR_1));
+			if (!pfw_id) {
+				pfw_id = (uint8 *)bcmstrnstr(fwid_str, sizeof(fwid_str) - 1,
+					FWID_STR_2, strlen(FWID_STR_2));
+				if (!pfw_id) {
+					DHD_ERROR(("%s: could not find id in FW bin!\n",
+							__FUNCTION__));
+					goto error;
+				}
+			}
+			/* search for the '-' in the fw id str, after which the
+			 * actual 4 byte fw id is present
+			 */
+			while (pfw_id && *pfw_id != '-') {
+				++pfw_id;
+			}
+			++pfw_id;
+			fwid = bcm_strtoul((char *)pfw_id, NULL, 16);
+
+			/* check if fw id in logstrs.bin matches the fw one */
+			if (hdr->fw_id != fwid) {
+				DHD_ERROR(("%s: logstr id does not match FW!"
+					"logstrs_fwid:0x%x, rtecdc_fwid:0x%x\n",
+					__FUNCTION__, hdr->fw_id, fwid));
+				goto error;
+			}
+			match_fail = FALSE;
+			num_fmts = hdr->rom_logstrs_offset / sizeof(uint32);
+			ram_index = (hdr->ram_lognums_offset -
+				hdr->rom_lognums_offset) / sizeof(uint32);
+			lognums = (uint32 *) &raw_fmts[hdr->rom_lognums_offset];
+			logstrs = (char *)	 &raw_fmts[hdr->rom_logstrs_offset];
+			hdr_logstrs_size = hdr->logstrs_size;
+
+error:
+#ifdef DHD_LINUX_STD_FW_API
+			if (fw) {
+				dhd_os_close_img_fwreq(fw);
+			}
+#else
+			if (file) {
+				dhd_os_close_image1(NULL, file);
+			}
+#endif /* DHD_LINUX_STD_FW_API */
+			if (match_fail) {
+				return BCME_DECERR;
+			}
+		} else {
+			DHD_ERROR(("%s: Invalid logstr version %u\n", __FUNCTION__,
+					trailer->version));
+			return BCME_ERROR;
+		}
+		if (logstrs_size != hdr_logstrs_size) {
+			DHD_ERROR(("%s: bad logstrs_size %d\n", __FUNCTION__, hdr_logstrs_size));
+			return BCME_ERROR;
+		}
+	} else {
+		/*
+		 * Legacy logstrs.bin format without header.
+		 */
+		num_fmts = *((uint32 *) (raw_fmts)) / sizeof(uint32);
+
+		/* Legacy RAM-only logstrs.bin format:
+		 *	  - RAM 'lognums' section
+		 *	  - RAM 'logstrs' section.
+		 *
+		 * 'lognums' is an array of indexes for the strings in the
+		 * 'logstrs' section. The first uint32 is an index to the
+		 * start of 'logstrs'. Therefore, if this index is divided
+		 * by 'sizeof(uint32)' it provides the number of logstr
+		 *	entries.
+		 */
+		ram_index = 0;
+		lognums = (uint32 *) raw_fmts;
+		logstrs = (char *) &raw_fmts[num_fmts << 2];
+	}
+	if (num_fmts) {
+		if (event_log->fmts != NULL) {
+			fmts = event_log->fmts;	/* reuse existing malloced fmts */
+		} else {
+			fmts = MALLOC(osh, num_fmts  * sizeof(char *));
+		}
+	}
+	if (fmts == NULL) {
+		DHD_ERROR(("%s: Failed to allocate fmts memory\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+	event_log->fmts_size = num_fmts  * sizeof(char *);
+	for (i = 0; i < num_fmts; i++) {
+		/* ROM lognums index into logstrs using 'rom_logstrs_offset' as a base
+		* (they are 0-indexed relative to 'rom_logstrs_offset').
+		*
+		* RAM lognums are already indexed to point to the correct RAM logstrs (they
+		* are 0-indexed relative to the start of the logstrs.bin file).
+		*/
+		if (i == ram_index) {
+			logstrs = raw_fmts;
+		}
+		fmts[i] = &logstrs[lognums[i]];
+	}
+	event_log->fmts = fmts;
+	event_log->raw_fmts_size = logstrs_size;
+	event_log->raw_fmts = raw_fmts;
+	event_log->num_fmts = num_fmts;
+	return BCME_OK;
+} /* dhd_parse_logstrs_file */
+
+#ifdef DHD_LINUX_STD_FW_API
+int dhd_parse_map_file(osl_t *osh, const void *ptr, uint32 *ramstart, uint32 *rodata_start,
+		uint32 *rodata_end)
+{
+	char *raw_fmts =  NULL, *raw_fmts_loc = NULL;
+	uint32 read_size = READ_NUM_BYTES, offset = 0;
+	int error = 0;
+	char * cptr = NULL;
+	char c;
+	uint8 count = 0;
+	uint32 size = 0;
+
+	*ramstart = 0;
+	*rodata_start = 0;
+	*rodata_end = 0;
+	size = (uint32)(((const struct firmware *)ptr)->size);
+
+	/* Allocate 1 byte more than read_size to terminate it with NULL */
+	raw_fmts = MALLOCZ(osh, read_size + 1);
+	if (raw_fmts == NULL) {
+		DHD_ERROR(("%s: Failed to allocate raw_fmts memory \n", __FUNCTION__));
+		goto fail;
+	}
+
+	/* read ram start, rodata_start and rodata_end values from map  file */
+	while (count != ALL_MAP_VAL)
+	{
+		/* Bound check for size before doing memcpy() */
+		if ((offset + read_size) > size) {
+			read_size = size - offset;
+		}
+
+		error = memcpy_s(raw_fmts, read_size,
+			(((const char *)((const struct firmware *)ptr)->data) + offset), read_size);
+		if (error) {
+			DHD_ERROR(("%s: failed to copy raw_fmts, err=%d\n",
+				__FUNCTION__, error));
+			goto fail;
+		}
+		/* End raw_fmts with NULL as strstr expects NULL terminated strings */
+		raw_fmts[read_size] = '\0';
+
+		/* Get ramstart address */
+		raw_fmts_loc = raw_fmts;
+		if (!(count & RAMSTART_BIT) &&
+			(cptr = bcmstrnstr(raw_fmts_loc, read_size, ramstart_str,
+			strlen(ramstart_str)))) {
+			cptr = cptr - BYTES_AHEAD_NUM;
+			sscanf(cptr, "%x %c text_start", ramstart, &c);
+			count |= RAMSTART_BIT;
+		}
+
+		/* Get ram rodata start address */
+		raw_fmts_loc = raw_fmts;
+		if (!(count & RDSTART_BIT) &&
+			(cptr = bcmstrnstr(raw_fmts_loc, read_size, rodata_start_str,
+			strlen(rodata_start_str)))) {
+			cptr = cptr - BYTES_AHEAD_NUM;
+			sscanf(cptr, "%x %c rodata_start", rodata_start, &c);
+			count |= RDSTART_BIT;
+		}
+
+		/* Get ram rodata end address */
+		raw_fmts_loc = raw_fmts;
+		if (!(count & RDEND_BIT) &&
+			(cptr = bcmstrnstr(raw_fmts_loc, read_size, rodata_end_str,
+			strlen(rodata_end_str)))) {
+			cptr = cptr - BYTES_AHEAD_NUM;
+			sscanf(cptr, "%x %c rodata_end", rodata_end, &c);
+			count |= RDEND_BIT;
+		}
+
+		if ((offset + read_size) >= size) {
+			break;
+		}
+
+		memset(raw_fmts, 0, read_size);
+		offset += (read_size - GO_BACK_FILE_POS_NUM_BYTES);
+	}
+
+fail:
+	if (raw_fmts) {
+		MFREE(osh, raw_fmts, read_size + 1);
+		raw_fmts = NULL;
+	}
+	if (count == ALL_MAP_VAL) {
+		return BCME_OK;
+	}
+	else {
+		DHD_ERROR(("%s: readmap error 0X%x \n", __FUNCTION__,
+				count));
+		return BCME_ERROR;
+	}
+} /* dhd_parse_map_file */
+#else
+int dhd_parse_map_file(osl_t *osh, void *file, uint32 *ramstart, uint32 *rodata_start,
+		uint32 *rodata_end)
+{
+	char *raw_fmts =  NULL, *raw_fmts_loc = NULL;
+	uint32 read_size = READ_NUM_BYTES;
+	int error = 0;
+	char * cptr = NULL;
+	char c;
+	uint8 count = 0;
+
+	*ramstart = 0;
+	*rodata_start = 0;
+	*rodata_end = 0;
+
+	/* Allocate 1 byte more than read_size to terminate it with NULL */
+	raw_fmts = MALLOCZ(osh, read_size + 1);
+	if (raw_fmts == NULL) {
+		DHD_ERROR(("%s: Failed to allocate raw_fmts memory \n", __FUNCTION__));
+		goto fail;
+	}
+
+	/* read ram start, rodata_start and rodata_end values from map  file */
+	while (count != ALL_MAP_VAL)
+	{
+		error = dhd_os_read_file(file, raw_fmts, read_size);
+		if (error < 0) {
+			DHD_ERROR(("%s: map file read failed err:%d \n", __FUNCTION__,
+					error));
+			goto fail;
+		}
+
+		/* End raw_fmts with NULL as strstr expects NULL terminated strings */
+		raw_fmts[read_size] = '\0';
+		/* Get ramstart address */
+		raw_fmts_loc = raw_fmts;
+		if (!(count & RAMSTART_BIT) &&
+			(cptr = bcmstrnstr(raw_fmts_loc, read_size, ramstart_str,
+			strlen(ramstart_str)))) {
+			cptr = cptr - BYTES_AHEAD_NUM;
+			sscanf(cptr, "%x %c text_start", ramstart, &c);
+			count |= RAMSTART_BIT;
+		}
+
+		/* Get ram rodata start address */
+		raw_fmts_loc = raw_fmts;
+		if (!(count & RDSTART_BIT) &&
+			(cptr = bcmstrnstr(raw_fmts_loc, read_size, rodata_start_str,
+			strlen(rodata_start_str)))) {
+			cptr = cptr - BYTES_AHEAD_NUM;
+			sscanf(cptr, "%x %c rodata_start", rodata_start, &c);
+			count |= RDSTART_BIT;
+		}
+
+		/* Get ram rodata end address */
+		raw_fmts_loc = raw_fmts;
+		if (!(count & RDEND_BIT) &&
+			(cptr = bcmstrnstr(raw_fmts_loc, read_size, rodata_end_str,
+			strlen(rodata_end_str)))) {
+			cptr = cptr - BYTES_AHEAD_NUM;
+			sscanf(cptr, "%x %c rodata_end", rodata_end, &c);
+			count |= RDEND_BIT;
+		}
+
+		if (error < (int)read_size) {
+			/*
+			* since we reset file pos back to earlier pos by
+			* GO_BACK_FILE_POS_NUM_BYTES bytes we won't reach EOF.
+			* The reason for this is if string is spreaded across
+			* bytes, the read function should not miss it.
+			* So if ret value is less than read_size, reached EOF don't read further
+			*/
+			break;
+		}
+		memset(raw_fmts, 0, read_size);
+		/*
+		* go back to predefined NUM of bytes so that we won't miss
+		* the string and  addr even if it comes as splited in next read.
+		*/
+		error = dhd_os_seek_file(file, -GO_BACK_FILE_POS_NUM_BYTES);
+		if (error < 0) {
+			DHD_ERROR(("%s: map file seek failed err:%d \n", __FUNCTION__,
+					error));
+			goto fail;
+		}
+	}
+
+fail:
+	if (raw_fmts) {
+		MFREE(osh, raw_fmts, read_size + 1);
+		raw_fmts = NULL;
+	}
+	if (count == ALL_MAP_VAL) {
+		return BCME_OK;
+	}
+	else {
+		DHD_ERROR(("%s: readmap error 0X%x \n", __FUNCTION__,
+				count));
+		return BCME_ERROR;
+	}
+
+} /* dhd_parse_map_file */
+#endif /* DHD_LINUX_STD_FW_API */
+
+#ifdef PCIE_FULL_DONGLE
+int
+dhd_event_logtrace_infobuf_pkt_process(dhd_pub_t *dhdp, void *pktbuf,
+		dhd_event_log_t *event_data)
+{
+	uint32 infobuf_version;
+	info_buf_payload_hdr_t *payload_hdr_ptr;
+	uint16 payload_hdr_type;
+	uint16 payload_hdr_length;
+
+	DHD_TRACE(("%s:Enter\n", __FUNCTION__));
+
+	if (PKTLEN(dhdp->osh, pktbuf) < sizeof(uint32)) {
+		DHD_ERROR(("%s: infobuf too small for version field\n",
+			__FUNCTION__));
+		goto exit;
+	}
+	infobuf_version = *((uint32 *)PKTDATA(dhdp->osh, pktbuf));
+	PKTPULL(dhdp->osh, pktbuf, sizeof(uint32));
+	if (infobuf_version != PCIE_INFOBUF_V1) {
+		DHD_ERROR(("%s: infobuf version %d is not PCIE_INFOBUF_V1\n",
+			__FUNCTION__, infobuf_version));
+		goto exit;
+	}
+
+	/* Version 1 infobuf has a single type/length (and then value) field */
+	if (PKTLEN(dhdp->osh, pktbuf) < sizeof(info_buf_payload_hdr_t)) {
+		DHD_ERROR(("%s: infobuf too small for v1 type/length  fields\n",
+			__FUNCTION__));
+		goto exit;
+	}
+	/* Process/parse the common info payload header (type/length) */
+	payload_hdr_ptr = (info_buf_payload_hdr_t *)PKTDATA(dhdp->osh, pktbuf);
+	payload_hdr_type = ltoh16(payload_hdr_ptr->type);
+	payload_hdr_length = ltoh16(payload_hdr_ptr->length);
+	if (payload_hdr_type != PCIE_INFOBUF_V1_TYPE_LOGTRACE) {
+		DHD_ERROR(("%s: payload_hdr_type %d is not V1_TYPE_LOGTRACE\n",
+			__FUNCTION__, payload_hdr_type));
+		goto exit;
+	}
+	PKTPULL(dhdp->osh, pktbuf, sizeof(info_buf_payload_hdr_t));
+
+	/* Validate that the specified length isn't bigger than the
+	 * provided data.
+	 */
+	if (payload_hdr_length > PKTLEN(dhdp->osh, pktbuf)) {
+		DHD_ERROR(("%s: infobuf logtrace length is bigger"
+			" than actual buffer data\n", __FUNCTION__));
+		goto exit;
+	}
+	dhd_dbg_trace_evnt_handler(dhdp, PKTDATA(dhdp->osh, pktbuf),
+		event_data, payload_hdr_length);
+
+	return BCME_OK;
+
+exit:
+	return BCME_ERROR;
+} /* dhd_event_logtrace_infobuf_pkt_process */
+#endif /* PCIE_FULL_DONGLE */
+#endif /* SHOW_LOGTRACE */
+
+#if defined(WLTDLS) && defined(PCIE_FULL_DONGLE)
+
+/* To handle the TDLS event in the dhd_common.c
+ */
+int dhd_tdls_event_handler(dhd_pub_t *dhd_pub, wl_event_msg_t *event)
+{
+	int ret = BCME_OK;
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST()
+	ret = dhd_tdls_update_peer_info(dhd_pub, event);
+	GCC_DIAGNOSTIC_POP()
+
+	return ret;
+}
+
+int dhd_free_tdls_peer_list(dhd_pub_t *dhd_pub)
+{
+	tdls_peer_node_t *cur = NULL, *prev = NULL;
+	if (!dhd_pub)
+		return BCME_ERROR;
+	cur = dhd_pub->peer_tbl.node;
+
+	if ((dhd_pub->peer_tbl.node == NULL) && !dhd_pub->peer_tbl.tdls_peer_count)
+		return BCME_ERROR;
+
+	while (cur != NULL) {
+		prev = cur;
+		cur = cur->next;
+		MFREE(dhd_pub->osh, prev, sizeof(tdls_peer_node_t));
+	}
+	dhd_pub->peer_tbl.tdls_peer_count = 0;
+	dhd_pub->peer_tbl.node = NULL;
+	return BCME_OK;
+}
+#endif	/* #if defined(WLTDLS) && defined(PCIE_FULL_DONGLE) */
+
+/* pretty hex print a contiguous buffer
+* based on the debug level specified
+*/
+void
+dhd_prhex(const char *msg, volatile uchar *buf, uint nbytes, uint32 dbg_level)
+{
+	char line[128], *p;
+	int len = sizeof(line);
+	int nchar;
+	uint i;
+
+	if (msg && (msg[0] != '\0')) {
+		if (dbg_level == DHD_ERROR_VAL) {
+			DHD_ERROR(("%s:\n", msg));
+		} else if (dbg_level == DHD_INFO_VAL) {
+			DHD_INFO(("%s:\n", msg));
+		} else if (dbg_level == DHD_TRACE_VAL) {
+			DHD_TRACE(("%s:\n", msg));
+		} else if (dbg_level == DHD_RPM_VAL) {
+			DHD_RPM(("%s:\n", msg));
+		}
+	}
+
+	p = line;
+	for (i = 0; i < nbytes; i++) {
+		if (i % 16 == 0) {
+			nchar = snprintf(p, len, "  %04x: ", i);	/* line prefix */
+			p += nchar;
+			len -= nchar;
+		}
+		if (len > 0) {
+			nchar = snprintf(p, len, "%02x ", buf[i]);
+			p += nchar;
+			len -= nchar;
+		}
+
+		if (i % 16 == 15) {
+			/* flush line */
+			if (dbg_level == DHD_ERROR_VAL) {
+				DHD_ERROR(("%s:\n", line));
+			} else if (dbg_level == DHD_INFO_VAL) {
+				DHD_INFO(("%s:\n", line));
+			} else if (dbg_level == DHD_TRACE_VAL) {
+				DHD_TRACE(("%s:\n", line));
+			} else if (dbg_level == DHD_RPM_VAL) {
+				DHD_RPM(("%s:\n", line));
+			}
+
+			p = line;
+			len = sizeof(line);
+		}
+	}
+
+	/* flush last partial line */
+	if (p != line) {
+		if (dbg_level == DHD_ERROR_VAL) {
+			DHD_ERROR(("%s:\n", line));
+		} else if (dbg_level == DHD_INFO_VAL) {
+			DHD_INFO(("%s:\n", line));
+		} else if (dbg_level == DHD_TRACE_VAL) {
+			DHD_TRACE(("%s:\n", line));
+		} else if (dbg_level == DHD_RPM_VAL) {
+			DHD_RPM(("%s:\n", line));
+		}
+	}
+}
+
+int
+dhd_tput_test(dhd_pub_t *dhd, tput_test_t *tput_data)
+{
+	struct ether_header ether_hdr;
+	tput_pkt_t tput_pkt;
+	void *pkt = NULL;
+	uint8 *pktdata = NULL;
+	uint32 pktsize = 0;
+	uint64 total_size = 0;
+	uint32 *crc = 0;
+	uint32 pktid = 0;
+	uint32 total_num_tx_pkts = 0;
+	int err = 0, err_exit = 0;
+	uint32 i = 0;
+	uint64 time_taken = 0;
+	int max_txbufs = 0;
+	uint32 n_batches = 0;
+	uint32 n_remain = 0;
+	uint8 tput_pkt_hdr_size = 0;
+	bool batch_cnt = FALSE;
+	bool tx_stop_pkt = FALSE;
+
+	if (tput_data->version != TPUT_TEST_T_VER ||
+		tput_data->length != TPUT_TEST_T_LEN) {
+		DHD_ERROR(("%s: wrong structure ver/len! \n", __FUNCTION__));
+		err_exit = BCME_BADARG;
+		goto exit_error;
+	}
+
+	if (dhd->tput_data.tput_test_running) {
+		DHD_ERROR(("%s: tput test already running ! \n", __FUNCTION__));
+		err_exit = BCME_BUSY;
+		goto exit_error;
+	}
+#ifdef PCIE_FULL_DONGLE
+	/*
+	 * 100 bytes to accommodate ether header and tput header. As of today
+	 * both occupy 30 bytes. Rest is reserved.
+	 */
+	if ((tput_data->payload_size > TPUT_TEST_MAX_PAYLOAD) ||
+		(tput_data->payload_size > (DHD_FLOWRING_RX_BUFPOST_PKTSZ - 100))) {
+		DHD_ERROR(("%s: payload size is too large! max_payload=%u rx_bufpost_size=%u\n",
+			__FUNCTION__, TPUT_TEST_MAX_PAYLOAD,
+			(DHD_FLOWRING_RX_BUFPOST_PKTSZ - 100)));
+		err_exit = BCME_BUFTOOLONG;
+		goto exit_error;
+	}
+#endif
+	max_txbufs = dhd_get_max_txbufs(dhd);
+	max_txbufs = MIN(max_txbufs, DHD_TPUT_MAX_TX_PKTS_BATCH);
+
+	if (!(tput_data->num_pkts > 0)) {
+		DHD_ERROR(("%s: invalid num_pkts: %d to tx\n",
+			__FUNCTION__, tput_data->num_pkts));
+		err_exit = BCME_ERROR;
+		goto exit_error;
+	}
+
+	memset(&dhd->tput_data, 0, sizeof(dhd->tput_data));
+	memcpy(&dhd->tput_data, tput_data, sizeof(*tput_data));
+	dhd->tput_data.pkts_bad = dhd->tput_data.pkts_good = 0;
+	dhd->tput_data.pkts_cmpl = 0;
+	dhd->tput_start_ts = dhd->tput_stop_ts = 0;
+
+	if (tput_data->flags & TPUT_TEST_USE_ETHERNET_HDR) {
+		pktsize = sizeof(ether_hdr) + sizeof(tput_pkt_t) +
+				(tput_data->payload_size - 12);
+	} else {
+		pktsize = sizeof(tput_pkt_t) +
+				(tput_data->payload_size - 12);
+	}
+
+	tput_pkt_hdr_size = (uint8)((uint8 *)&tput_pkt.crc32 -
+			(uint8 *)&tput_pkt.mac_sta);
+
+	/* mark the tput test as started */
+	dhd->tput_data.tput_test_running = TRUE;
+
+	if (tput_data->direction == TPUT_DIR_TX) {
+		/* for ethernet header */
+		memcpy(ether_hdr.ether_shost, tput_data->mac_sta, ETHER_ADDR_LEN);
+		memcpy(ether_hdr.ether_dhost, tput_data->mac_ap, ETHER_ADDR_LEN);
+		ether_hdr.ether_type = hton16(ETHER_TYPE_IP);
+
+		/* fill in the tput pkt */
+		memset(&tput_pkt, 0, sizeof(tput_pkt));
+		memcpy(tput_pkt.mac_ap, tput_data->mac_ap, ETHER_ADDR_LEN);
+		memcpy(tput_pkt.mac_sta, tput_data->mac_sta, ETHER_ADDR_LEN);
+		tput_pkt.pkt_type = hton16(TPUT_PKT_TYPE_NORMAL);
+		tput_pkt.num_pkts = hton32(tput_data->num_pkts);
+
+		if (tput_data->num_pkts > (uint32)max_txbufs) {
+			n_batches = tput_data->num_pkts / max_txbufs;
+			n_remain = tput_data->num_pkts % max_txbufs;
+		} else {
+			n_batches = 0;
+			n_remain = tput_data->num_pkts;
+		}
+		DHD_ERROR(("%s: num_pkts: %u n_batches: %u n_remain: %u\n",
+			__FUNCTION__, tput_data->num_pkts, n_batches, n_remain));
+
+		do {
+			/* reset before every batch */
+			dhd->batch_tx_pkts_cmpl = 0;
+			if (n_batches) {
+				dhd->batch_tx_num_pkts = max_txbufs;
+				--n_batches;
+			} else if (n_remain) {
+				dhd->batch_tx_num_pkts = n_remain;
+				n_remain = 0;
+			} else {
+				DHD_ERROR(("Invalid. This should not hit\n"));
+			}
+
+			dhd->tput_start_ts = OSL_SYSUPTIME_US();
+			for (i = 0; (i < dhd->batch_tx_num_pkts) || (tx_stop_pkt); ++i) {
+				pkt = PKTGET(dhd->osh, pktsize, TRUE);
+				if (!pkt) {
+					dhd->tput_data.tput_test_running = FALSE;
+					DHD_ERROR(("%s: PKTGET fails ! Not enough Tx buffers\n",
+						__FUNCTION__));
+					DHD_ERROR(("%s: pkts_good:%u; pkts_bad:%u; pkts_cmpl:%u\n",
+						__FUNCTION__, dhd->tput_data.pkts_good,
+						dhd->tput_data.pkts_bad, dhd->tput_data.pkts_cmpl));
+					err_exit = BCME_NOMEM;
+					goto exit_error;
+				}
+				pktdata = PKTDATA(dhd->osh, pkt);
+				PKTSETLEN(dhd->osh, pkt, pktsize);
+				memset(pktdata, 0, pktsize);
+				if (tput_data->flags & TPUT_TEST_USE_ETHERNET_HDR) {
+					memcpy(pktdata, &ether_hdr, sizeof(ether_hdr));
+					pktdata += sizeof(ether_hdr);
+				}
+				/* send stop pkt as last pkt */
+				if (tx_stop_pkt) {
+					tput_pkt.pkt_type = hton16(TPUT_PKT_TYPE_STOP);
+					tx_stop_pkt = FALSE;
+				} else
+					tput_pkt.pkt_type = hton16(TPUT_PKT_TYPE_NORMAL);
+				tput_pkt.pkt_id = hton32(pktid++);
+				tput_pkt.crc32 = 0;
+				memcpy(pktdata, &tput_pkt, sizeof(tput_pkt));
+				/* compute crc32 over the pkt-id, num-pkts and data fields */
+				crc = (uint32 *)(pktdata + tput_pkt_hdr_size);
+				*crc = hton32(hndcrc32(pktdata + tput_pkt_hdr_size + 4,
+						8 + (tput_data->payload_size - 12),
+						CRC32_INIT_VALUE));
+
+				err = dhd_sendpkt(dhd, 0, pkt);
+				if (err != BCME_OK) {
+					DHD_INFO(("%s: send pkt (id = %u) fails (err = %d) ! \n",
+						__FUNCTION__, pktid, err));
+					dhd->tput_data.pkts_bad++;
+				}
+				total_num_tx_pkts++;
+				if ((total_num_tx_pkts == tput_data->num_pkts) && (!tx_stop_pkt)) {
+					tx_stop_pkt = TRUE;
+				}
+			}
+			DHD_INFO(("%s: TX done, wait for completion...\n", __FUNCTION__));
+			if (!dhd_os_tput_test_wait(dhd, NULL,
+					TPUT_TEST_WAIT_TIMEOUT_DEFAULT)) {
+				dhd->tput_stop_ts = OSL_SYSUPTIME_US();
+				dhd->tput_data.tput_test_running = FALSE;
+				DHD_ERROR(("%s: TX completion timeout !"
+					" Total Tx pkts (including STOP) = %u; pkts cmpl = %u; \n",
+					__FUNCTION__, total_num_tx_pkts, dhd->batch_tx_pkts_cmpl));
+				err_exit = BCME_ERROR;
+				goto exit_error;
+			}
+			if ((dhd->tput_start_ts && dhd->tput_stop_ts &&
+				(dhd->tput_stop_ts > dhd->tput_start_ts)) || (time_taken)) {
+				if (!time_taken) {
+					time_taken = dhd->tput_stop_ts - dhd->tput_start_ts;
+				}
+			} else {
+				dhd->tput_data.tput_test_running = FALSE;
+				DHD_ERROR(("%s: bad timestamp while cal tx batch time\n",
+					__FUNCTION__));
+				err_exit = BCME_ERROR;
+				goto exit_error;
+			}
+			if (n_batches || n_remain) {
+				batch_cnt = TRUE;
+			} else {
+				batch_cnt = FALSE;
+			}
+		} while (batch_cnt);
+	} else {
+		/* TPUT_DIR_RX */
+		DHD_INFO(("%s: waiting for RX completion... \n", __FUNCTION__));
+		if (!dhd_os_tput_test_wait(dhd, NULL, tput_data->timeout_ms)) {
+			DHD_ERROR(("%s: RX completion timeout ! \n", __FUNCTION__));
+			dhd->tput_stop_ts = OSL_SYSUPTIME_US();
+		}
+	}
+
+	/* calculate the throughput in bits per sec */
+	if (dhd->tput_start_ts && dhd->tput_stop_ts &&
+		(dhd->tput_stop_ts > dhd->tput_start_ts)) {
+		time_taken = dhd->tput_stop_ts - dhd->tput_start_ts;
+		time_taken = DIV_U64_BY_U32(time_taken, MSEC_PER_SEC); /* convert to ms */
+		dhd->tput_data.time_ms = time_taken;
+		if (time_taken) {
+			total_size = pktsize * dhd->tput_data.pkts_cmpl * 8;
+			dhd->tput_data.tput_bps = DIV_U64_BY_U64(total_size, time_taken);
+			/* convert from ms to seconds */
+			dhd->tput_data.tput_bps = dhd->tput_data.tput_bps * 1000;
+		}
+	} else {
+		DHD_ERROR(("%s: bad timestamp !\n", __FUNCTION__));
+	}
+	DHD_INFO(("%s: DONE. tput = %llu bps, time = %llu ms\n", __FUNCTION__,
+		dhd->tput_data.tput_bps, dhd->tput_data.time_ms));
+
+	memcpy(tput_data, &dhd->tput_data, sizeof(dhd->tput_data));
+
+	dhd->tput_data.tput_test_running = FALSE;
+
+	err_exit = BCME_OK;
+
+exit_error:
+	DHD_ERROR(("%s: pkts_good = %u; pkts_bad = %u; pkts_cmpl = %u\n",
+		__FUNCTION__, dhd->tput_data.pkts_good,
+		dhd->tput_data.pkts_bad, dhd->tput_data.pkts_cmpl));
+
+	return err_exit;
+}
+
+void
+dhd_tput_test_rx(dhd_pub_t *dhd, void *pkt)
+{
+	uint8 *pktdata = NULL;
+	tput_pkt_t *tput_pkt = NULL;
+	uint32 crc = 0;
+	uint8 tput_pkt_hdr_size = 0;
+
+	pktdata = PKTDATA(dhd->osh, pkt);
+	if (dhd->tput_data.flags & TPUT_TEST_USE_ETHERNET_HDR)
+		pktdata += sizeof(struct ether_header);
+	tput_pkt = (tput_pkt_t *)pktdata;
+
+	/* record the timestamp of the first packet received */
+	if (dhd->tput_data.pkts_cmpl == 0) {
+		dhd->tput_start_ts = OSL_SYSUPTIME_US();
+	}
+
+	if (ntoh16(tput_pkt->pkt_type) != TPUT_PKT_TYPE_STOP &&
+			dhd->tput_data.pkts_cmpl <= dhd->tput_data.num_pkts) {
+		dhd->tput_data.pkts_cmpl++;
+	}
+	/* drop rx packets received beyond the specified # */
+	if (dhd->tput_data.pkts_cmpl > dhd->tput_data.num_pkts)
+		return;
+
+	DHD_TRACE(("%s: Rx tput test pkt, id = %u ; type = %u\n", __FUNCTION__,
+		ntoh32(tput_pkt->pkt_id), ntoh16(tput_pkt->pkt_type)));
+
+	/* discard if mac addr of AP/STA does not match the specified ones */
+	if ((memcmp(tput_pkt->mac_ap, dhd->tput_data.mac_ap,
+			ETHER_ADDR_LEN) != 0) ||
+		(memcmp(tput_pkt->mac_sta, dhd->tput_data.mac_sta,
+			ETHER_ADDR_LEN) != 0)) {
+		dhd->tput_data.pkts_bad++;
+		DHD_INFO(("%s: dropping tput pkt with id %u due to bad AP/STA mac !\n",
+			__FUNCTION__, ntoh32(tput_pkt->pkt_id)));
+		return;
+	}
+
+	tput_pkt_hdr_size = (uint8)((uint8 *)&tput_pkt->crc32 -
+			(uint8 *)&tput_pkt->mac_sta);
+	pktdata += tput_pkt_hdr_size + 4;
+	crc = hndcrc32(pktdata, 8 + (dhd->tput_data.payload_size - 12),
+			CRC32_INIT_VALUE);
+	if (crc != ntoh32(tput_pkt->crc32)) {
+		DHD_INFO(("%s: dropping tput pkt with id %u due to bad CRC !\n",
+			__FUNCTION__, ntoh32(tput_pkt->pkt_id)));
+		dhd->tput_data.pkts_bad++;
+		return;
+	}
+
+	if (ntoh16(tput_pkt->pkt_type) != TPUT_PKT_TYPE_STOP)
+		dhd->tput_data.pkts_good++;
+
+	/* if we have received the stop packet or all the # of pkts, we're done */
+	if (ntoh16(tput_pkt->pkt_type) == TPUT_PKT_TYPE_STOP ||
+			dhd->tput_data.pkts_cmpl == dhd->tput_data.num_pkts) {
+		dhd->tput_stop_ts = OSL_SYSUPTIME_US();
+		dhd_os_tput_test_wake(dhd);
+	}
+}
+
+#ifdef DUMP_IOCTL_IOV_LIST
+void
+dhd_iov_li_append(dhd_pub_t *dhd, dll_t *list_head, dll_t *node)
+{
+	dll_t *item;
+	dhd_iov_li_t *iov_li;
+	dhd->dump_iovlist_len++;
+
+	if (dhd->dump_iovlist_len == IOV_LIST_MAX_LEN+1) {
+		item = dll_head_p(list_head);
+		iov_li = (dhd_iov_li_t *)CONTAINEROF(item, dhd_iov_li_t, list);
+		dll_delete(item);
+		MFREE(dhd->osh, iov_li, sizeof(*iov_li));
+		dhd->dump_iovlist_len--;
+	}
+	dll_append(list_head, node);
+}
+
+void
+dhd_iov_li_print(dll_t *list_head)
+{
+	dhd_iov_li_t *iov_li;
+	dll_t *item, *next;
+	uint8 index = 0;
+	for (item = dll_head_p(list_head); !dll_end(list_head, item); item = next) {
+		next = dll_next_p(item);
+		iov_li = (dhd_iov_li_t *)CONTAINEROF(item, dhd_iov_li_t, list);
+		DHD_ERROR(("%d:cmd_name = %s, cmd = %d.\n", ++index, iov_li->buff, iov_li->cmd));
+	}
+}
+
+void
+dhd_iov_li_delete(dhd_pub_t *dhd, dll_t *list_head)
+{
+	dll_t *item;
+	dhd_iov_li_t *iov_li;
+	while (!(dll_empty(list_head))) {
+		item = dll_head_p(list_head);
+		iov_li = (dhd_iov_li_t *)CONTAINEROF(item, dhd_iov_li_t, list);
+		dll_delete(item);
+		MFREE(dhd->osh, iov_li, sizeof(*iov_li));
+	}
+}
+#endif /* DUMP_IOCTL_IOV_LIST */
+
+#ifdef EWP_EDL
+/* For now we are allocating memory for EDL ring using DMA_ALLOC_CONSISTENT
+* The reason being that, in hikey, if we try to DMA_MAP prealloced memory
+* it is failing with an 'out of space in SWIOTLB' error
+*/
+int
+dhd_edl_mem_init(dhd_pub_t *dhd)
+{
+	int ret = 0;
+
+	memset(&dhd->edl_ring_mem, 0, sizeof(dhd->edl_ring_mem));
+	ret = dhd_dma_buf_alloc(dhd, &dhd->edl_ring_mem, DHD_EDL_RING_SIZE);
+	if (ret != BCME_OK) {
+		DHD_ERROR(("%s: alloc of edl_ring_mem failed\n",
+			__FUNCTION__));
+		return BCME_ERROR;
+	}
+	return BCME_OK;
+}
+
+/*
+ * NOTE:- that dhd_edl_mem_deinit need NOT be called explicitly, because the dma_buf
+ * for EDL is freed during 'dhd_prot_detach_edl_rings' which is called during de-init.
+ */
+void
+dhd_edl_mem_deinit(dhd_pub_t *dhd)
+{
+	if (dhd->edl_ring_mem.va != NULL)
+		dhd_dma_buf_free(dhd, &dhd->edl_ring_mem);
+}
+
+int
+dhd_event_logtrace_process_edl(dhd_pub_t *dhdp, uint8 *data,
+		void *evt_decode_data)
+{
+	msg_hdr_edl_t *msg = NULL;
+	cmn_msg_hdr_t *cmn_msg_hdr = NULL;
+	uint8 *buf = NULL;
+
+	if (!data || !dhdp || !evt_decode_data) {
+		DHD_ERROR(("%s: invalid args ! \n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	/* format of data in each work item in the EDL ring:
+	* |cmn_msg_hdr_t |payload (var len)|cmn_msg_hdr_t|
+	* payload = |infobuf_ver(u32)|info_buf_payload_hdr_t|msgtrace_hdr_t|<var len data>|
+	*/
+	cmn_msg_hdr = (cmn_msg_hdr_t *)data;
+	msg = (msg_hdr_edl_t *)(data + sizeof(cmn_msg_hdr_t));
+	buf = (uint8 *)msg;
+	/* validate the fields */
+	if (ltoh32(msg->infobuf_ver) != PCIE_INFOBUF_V1) {
+		DHD_ERROR(("%s: Skipping msg with invalid infobuf ver (0x%x)"
+			" expected (0x%x)\n", __FUNCTION__,
+			msg->infobuf_ver, PCIE_INFOBUF_V1));
+		return BCME_VERSION;
+	}
+
+	/* in EDL, the request_id field of cmn_msg_hdr is overloaded to carry payload length */
+	if (sizeof(info_buf_payload_hdr_t) > cmn_msg_hdr->request_id) {
+		DHD_ERROR(("%s: infobuf too small for v1 type/length fields\n",
+			__FUNCTION__));
+		return BCME_BUFTOOLONG;
+	}
+
+	if (ltoh16(msg->pyld_hdr.type) != PCIE_INFOBUF_V1_TYPE_LOGTRACE) {
+		DHD_ERROR(("%s: payload_hdr_type %d is not V1_TYPE_LOGTRACE\n",
+			__FUNCTION__, ltoh16(msg->pyld_hdr.type)));
+		return BCME_BADOPTION;
+	}
+
+	if (ltoh16(msg->pyld_hdr.length) > cmn_msg_hdr->request_id) {
+		DHD_ERROR(("%s: infobuf logtrace length %u is bigger"
+			" than available buffer size %u\n", __FUNCTION__,
+			ltoh16(msg->pyld_hdr.length), cmn_msg_hdr->request_id));
+		return BCME_BADLEN;
+	}
+
+	/* dhd_dbg_trace_evnt_handler expects the data to start from msgtrace_hdr_t */
+	buf += sizeof(msg->infobuf_ver) + sizeof(msg->pyld_hdr);
+	dhd_dbg_trace_evnt_handler(dhdp, buf, evt_decode_data,
+		ltoh16(msg->pyld_hdr.length));
+
+	/*
+	 * check 'dhdp->logtrace_pkt_sendup' and if true alloc an skb
+	 * copy the event data to the skb and send it up the stack
+	 */
+	if (dhdp->logtrace_pkt_sendup) {
+		DHD_INFO(("%s: send up event log, len %u bytes\n", __FUNCTION__,
+				(uint32)(ltoh16(msg->pyld_hdr.length) +
+				sizeof(info_buf_payload_hdr_t) + 4)));
+		dhd_sendup_info_buf(dhdp, (uint8 *)msg);
+	}
+
+	return BCME_OK;
+}
+#endif /* EWP_EDL */
+
+#if defined(LINUX) && defined(SHOW_LOGTRACE)
+int
+dhd_print_fw_ver_from_file(dhd_pub_t *dhdp, char *fwpath)
+{
+	void *file = NULL;
+	int size = 0;
+	char buf[FW_VER_STR_LEN];
+	char *str = NULL;
+	int ret = BCME_OK;
+
+	if (!fwpath)
+		return BCME_BADARG;
+
+	file = dhd_os_open_image1(dhdp, fwpath);
+	if (!file) {
+		ret = BCME_ERROR;
+		goto exit;
+	}
+	size = dhd_os_get_image_size(file);
+	if (!size) {
+		ret = BCME_ERROR;
+		goto exit;
+	}
+
+	/* seek to the last 'X' bytes in the file */
+	if (dhd_os_seek_file(file, size - FW_VER_STR_LEN) != BCME_OK) {
+		ret = BCME_ERROR;
+		goto exit;
+	}
+
+	/* read the last 'X' bytes of the file to a buffer */
+	memset(buf, 0, FW_VER_STR_LEN);
+	if (dhd_os_get_image_block(buf, FW_VER_STR_LEN - 1, file) < 0) {
+		ret = BCME_ERROR;
+		goto exit;
+	}
+	/* search for 'Version' in the buffer */
+	str = bcmstrnstr(buf, FW_VER_STR_LEN, FW_VER_STR, strlen(FW_VER_STR));
+	if (!str) {
+		ret = BCME_ERROR;
+		goto exit;
+	}
+	/* go back in the buffer to the last ascii character */
+	while (str != buf &&
+		(*str >= ' ' && *str <= '~')) {
+		--str;
+	}
+	/* reverse the final decrement, so that str is pointing
+	* to the first ascii character in the buffer
+	*/
+	++str;
+
+	if (strlen(str) > (FW_VER_STR_LEN - 1)) {
+		ret = BCME_BADLEN;
+		goto exit;
+	}
+
+	DHD_ERROR(("FW version in file '%s': %s\n", fwpath, str));
+	/* copy to global variable, so that in case FW load fails, the
+	* core capture logs will contain FW version read from the file
+	*/
+	memset(fw_version, 0, FW_VER_STR_LEN);
+	strlcpy(fw_version, str, FW_VER_STR_LEN);
+
+exit:
+	if (file)
+		dhd_os_close_image1(dhdp, file);
+
+	return ret;
+}
+#endif /* LINUX && SHOW_LOGTRACE */
+
+#ifdef WL_CFGVENDOR_SEND_HANG_EVENT
+static void
+copy_hang_info_ioctl_timeout(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc)
+{
+	int remain_len;
+	int i;
+	int *cnt;
+	char *dest;
+	int bytes_written;
+	uint32 ioc_dwlen = 0;
+
+	if (!dhd || !dhd->hang_info) {
+		DHD_ERROR(("%s dhd=%p hang_info=%p\n",
+			__FUNCTION__, dhd, (dhd ? dhd->hang_info : NULL)));
+		return;
+	}
+
+	cnt = &dhd->hang_info_cnt;
+	dest = dhd->hang_info;
+
+	memset(dest, 0, VENDOR_SEND_HANG_EXT_INFO_LEN);
+	(*cnt) = 0;
+
+	bytes_written = 0;
+	remain_len = VENDOR_SEND_HANG_EXT_INFO_LEN - bytes_written;
+
+	get_debug_dump_time(dhd->debug_dump_time_hang_str);
+	copy_debug_dump_time(dhd->debug_dump_time_str, dhd->debug_dump_time_hang_str);
+
+	bytes_written += scnprintf(&dest[bytes_written], remain_len, "%d %d %s %d %d %d %d %d %d ",
+			HANG_REASON_IOCTL_RESP_TIMEOUT, VENDOR_SEND_HANG_EXT_INFO_VER,
+			dhd->debug_dump_time_hang_str,
+			ifidx, ioc->cmd, ioc->len, ioc->set, ioc->used, ioc->needed);
+	(*cnt) = HANG_FIELD_IOCTL_RESP_TIMEOUT_CNT;
+
+	clear_debug_dump_time(dhd->debug_dump_time_hang_str);
+
+	/* Access ioc->buf only if the ioc->len is more than 4 bytes */
+	ioc_dwlen = (uint32)(ioc->len / sizeof(uint32));
+	if (ioc_dwlen > 0) {
+		const uint32 *ioc_buf = (const uint32 *)ioc->buf;
+
+		remain_len = VENDOR_SEND_HANG_EXT_INFO_LEN - bytes_written;
+		GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+		bytes_written += scnprintf(&dest[bytes_written], remain_len,
+			"%08x", *(uint32 *)(ioc_buf++));
+		GCC_DIAGNOSTIC_POP();
+		(*cnt)++;
+		if ((*cnt) >= HANG_FIELD_CNT_MAX) {
+			return;
+		}
+
+		for (i = 1; i < ioc_dwlen && *cnt <= HANG_FIELD_CNT_MAX;
+			i++, (*cnt)++) {
+			remain_len = VENDOR_SEND_HANG_EXT_INFO_LEN - bytes_written;
+			GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+			bytes_written += scnprintf(&dest[bytes_written], remain_len, "%c%08x",
+				HANG_RAW_DEL, *(uint32 *)(ioc_buf++));
+			GCC_DIAGNOSTIC_POP();
+		}
+	}
+
+	DHD_INFO(("%s hang info len: %d data: %s\n",
+		__FUNCTION__, (int)strlen(dhd->hang_info), dhd->hang_info));
+}
+
+#endif /* WL_CFGVENDOR_SEND_HANG_EVENT */
+
+#if defined(DHD_H2D_LOG_TIME_SYNC)
+/*
+ * Helper function:
+ * Used for Dongle console message time syncing with Host printk
+ */
+void dhd_h2d_log_time_sync(dhd_pub_t *dhd)
+{
+	uint64 ts;
+
+	/*
+	 * local_clock() returns time in nano seconds.
+	 * Dongle understand only milli seconds time.
+	 */
+	ts = local_clock();
+	/* Nano seconds to milli seconds */
+	do_div(ts, 1000000);
+	if (dhd_wl_ioctl_set_intiovar(dhd,  "rte_timesync", ts, WLC_SET_VAR, TRUE, 0)) {
+		DHD_ERROR(("%s rte_timesync **** FAILED ****\n", __FUNCTION__));
+		/* Stopping HOST Dongle console time syncing */
+		dhd->dhd_rte_time_sync_ms = 0;
+	}
+}
+#endif /* DHD_H2D_LOG_TIME_SYNC */
+
+#if defined(LINUX) || defined(linux)
+/* configuations of ecounters to be enabled by default in FW */
+static ecounters_cfg_t ecounters_cfg_tbl[] = {
+	/* Global ecounters */
+	{ECOUNTERS_STATS_TYPES_FLAG_GLOBAL, 0x0, WL_IFSTATS_XTLV_BUS_PCIE},
+	// {ECOUNTERS_STATS_TYPES_FLAG_GLOBAL, 0x0, WL_IFSTATS_XTLV_TX_AMPDU_STATS},
+	// {ECOUNTERS_STATS_TYPES_FLAG_GLOBAL, 0x0, WL_IFSTATS_XTLV_RX_AMPDU_STATS},
+
+	/* Slice specific ecounters */
+	{ECOUNTERS_STATS_TYPES_FLAG_SLICE, 0x0, WL_SLICESTATS_XTLV_PERIODIC_STATE},
+	{ECOUNTERS_STATS_TYPES_FLAG_SLICE, 0x1, WL_SLICESTATS_XTLV_PERIODIC_STATE},
+	{ECOUNTERS_STATS_TYPES_FLAG_SLICE, 0x1, WL_IFSTATS_XTLV_WL_SLICE_BTCOEX},
+
+	/* Interface specific ecounters */
+	{ECOUNTERS_STATS_TYPES_FLAG_IFACE, 0x0, WL_IFSTATS_XTLV_IF_PERIODIC_STATE},
+	{ECOUNTERS_STATS_TYPES_FLAG_IFACE, 0x0, WL_IFSTATS_XTLV_GENERIC},
+	{ECOUNTERS_STATS_TYPES_FLAG_IFACE, 0x0, WL_IFSTATS_XTLV_INFRA_SPECIFIC},
+	{ECOUNTERS_STATS_TYPES_FLAG_IFACE, 0x0, WL_IFSTATS_XTLV_MGT_CNT},
+
+	/* secondary interface */
+	/* XXX REMOVE for temporal, will be enabled after decision
+	{ECOUNTERS_STATS_TYPES_FLAG_IFACE, 0x1, WL_IFSTATS_XTLV_IF_PERIODIC_STATE},
+	{ECOUNTERS_STATS_TYPES_FLAG_IFACE, 0x1, WL_IFSTATS_XTLV_GENERIC},
+	{ECOUNTERS_STATS_TYPES_FLAG_IFACE, 0x1, WL_IFSTATS_XTLV_INFRA_SPECIFIC},
+	{ECOUNTERS_STATS_TYPES_FLAG_IFACE, 0x1, WL_IFSTATS_XTLV_MGT_CNT},
+	*/
+};
+
+/* XXX: Same event id shall be defined in consecutive order in the below table */
+static event_ecounters_cfg_t event_ecounters_cfg_tbl[] = {
+	/* Interface specific event ecounters */
+	{WLC_E_DEAUTH_IND, ECOUNTERS_STATS_TYPES_FLAG_IFACE, 0x0, WL_IFSTATS_XTLV_IF_EVENT_STATS},
+};
+
+/* Accepts an argument to -s, -g or -f and creates an XTLV */
+int
+dhd_create_ecounters_params(dhd_pub_t *dhd, uint16 type, uint16 if_slice_idx,
+	uint16 stats_rep, uint8 **xtlv)
+{
+	uint8 *req_xtlv = NULL;
+	ecounters_stats_types_report_req_t *req;
+	bcm_xtlvbuf_t xtlvbuf, container_xtlvbuf;
+	ecountersv2_xtlv_list_elt_t temp;
+	uint16 xtlv_len = 0, total_len = 0;
+	int rc = BCME_OK;
+
+	/* fill in the stat type XTLV. For now there is no explicit TLV for the stat type. */
+	temp.id = stats_rep;
+	temp.len = 0;
+
+	/* Hence len/data = 0/NULL */
+	xtlv_len += temp.len + BCM_XTLV_HDR_SIZE;
+
+	/* Total length of the container */
+	total_len = BCM_XTLV_HDR_SIZE +
+		OFFSETOF(ecounters_stats_types_report_req_t, stats_types_req) + xtlv_len;
+
+	/* Now allocate a structure for the entire request */
+	if ((req_xtlv = (uint8 *)MALLOCZ(dhd->osh, total_len)) == NULL) {
+		rc = BCME_NOMEM;
+		goto fail;
+	}
+
+	/* container XTLV context */
+	bcm_xtlv_buf_init(&container_xtlvbuf, (uint8 *)req_xtlv, total_len,
+		BCM_XTLV_OPTION_ALIGN32);
+
+	/* Fill other XTLVs in the container. Leave space for XTLV headers */
+	req = (ecounters_stats_types_report_req_t *)(req_xtlv + BCM_XTLV_HDR_SIZE);
+	req->flags = type;
+	if (type == ECOUNTERS_STATS_TYPES_FLAG_SLICE) {
+		req->slice_mask = 0x1 << if_slice_idx;
+	} else if (type == ECOUNTERS_STATS_TYPES_FLAG_IFACE) {
+		req->if_index = if_slice_idx;
+	}
+
+	/* Fill remaining XTLVs */
+	bcm_xtlv_buf_init(&xtlvbuf, (uint8*) req->stats_types_req, xtlv_len,
+		BCM_XTLV_OPTION_ALIGN32);
+	if (bcm_xtlv_put_data(&xtlvbuf, temp.id, NULL, temp.len)) {
+		DHD_ERROR(("Error creating XTLV for requested stats type = %d\n", temp.id));
+		rc = BCME_ERROR;
+		goto fail;
+	}
+
+	/* fill the top level container and get done with the XTLV container */
+	rc = bcm_xtlv_put_data(&container_xtlvbuf, WL_ECOUNTERS_XTLV_REPORT_REQ, NULL,
+		bcm_xtlv_buf_len(&xtlvbuf) + OFFSETOF(ecounters_stats_types_report_req_t,
+		stats_types_req));
+
+	if (rc) {
+		DHD_ERROR(("Error creating parent XTLV for type = %d\n", req->flags));
+		goto fail;
+	}
+
+fail:
+	if (rc && req_xtlv) {
+		MFREE(dhd->osh, req_xtlv, total_len);
+		req_xtlv = NULL;
+	}
+
+	/* update the xtlv pointer */
+	*xtlv = req_xtlv;
+	return rc;
+}
+
+static int
+dhd_ecounter_autoconfig(dhd_pub_t *dhd)
+{
+	int rc = BCME_OK;
+	uint32 buf;
+	rc = dhd_iovar(dhd, 0, "ecounters_autoconfig", NULL, 0, (char *)&buf, sizeof(buf), FALSE);
+
+	if (rc != BCME_OK) {
+
+		if (rc != BCME_UNSUPPORTED) {
+			rc = BCME_OK;
+			DHD_ERROR(("%s Ecounter autoconfig in fw failed : %d\n", __FUNCTION__, rc));
+		} else {
+			DHD_ERROR(("%s Ecounter autoconfig in FW not supported\n", __FUNCTION__));
+		}
+	}
+
+	return rc;
+}
+
+int
+dhd_ecounter_configure(dhd_pub_t *dhd, bool enable)
+{
+	int rc = BCME_OK;
+	if (enable) {
+		if (dhd_ecounter_autoconfig(dhd) != BCME_OK) {
+			if ((rc = dhd_start_ecounters(dhd)) != BCME_OK) {
+				DHD_ERROR(("%s Ecounters start failed\n", __FUNCTION__));
+			} else if ((rc = dhd_start_event_ecounters(dhd)) != BCME_OK) {
+				DHD_ERROR(("%s Event_Ecounters start failed\n", __FUNCTION__));
+			}
+		}
+	} else {
+		if ((rc = dhd_stop_ecounters(dhd)) != BCME_OK) {
+			DHD_ERROR(("%s Ecounters stop failed\n", __FUNCTION__));
+		} else if ((rc = dhd_stop_event_ecounters(dhd)) != BCME_OK) {
+			DHD_ERROR(("%s Event_Ecounters stop failed\n", __FUNCTION__));
+		}
+	}
+	return rc;
+}
+
+int
+dhd_start_ecounters(dhd_pub_t *dhd)
+{
+	uint8 i = 0;
+	uint8 *start_ptr;
+	int rc = BCME_OK;
+	bcm_xtlv_t *elt;
+	ecounters_config_request_v2_t *req = NULL;
+	ecountersv2_processed_xtlv_list_elt *list_elt, *tail = NULL;
+	ecountersv2_processed_xtlv_list_elt *processed_containers_list = NULL;
+	uint16 total_processed_containers_len = 0;
+
+	for (i = 0; i < ARRAYSIZE(ecounters_cfg_tbl); i++) {
+		ecounters_cfg_t *ecounter_stat = &ecounters_cfg_tbl[i];
+
+		if ((list_elt = (ecountersv2_processed_xtlv_list_elt *)
+			MALLOCZ(dhd->osh, sizeof(*list_elt))) == NULL) {
+			DHD_ERROR(("Ecounters v2: No memory to process\n"));
+			goto fail;
+		}
+
+		rc = dhd_create_ecounters_params(dhd, ecounter_stat->type,
+			ecounter_stat->if_slice_idx, ecounter_stat->stats_rep, &list_elt->data);
+
+		if (rc) {
+			DHD_ERROR(("Ecounters v2: Could not process: stat: %d return code: %d\n",
+				ecounter_stat->stats_rep, rc));
+
+			/* Free allocated memory and go to fail to release any memories allocated
+			 * in previous iterations. Note that list_elt->data gets populated in
+			 * dhd_create_ecounters_params() and gets freed there itself.
+			 */
+			MFREE(dhd->osh, list_elt, sizeof(*list_elt));
+			list_elt = NULL;
+			goto fail;
+		}
+		elt = (bcm_xtlv_t *) list_elt->data;
+
+		/* Put the elements in the order they are processed */
+		if (processed_containers_list == NULL) {
+			processed_containers_list = list_elt;
+		} else {
+			tail->next = list_elt;
+		}
+		tail = list_elt;
+		/* Size of the XTLV returned */
+		total_processed_containers_len += BCM_XTLV_LEN(elt) + BCM_XTLV_HDR_SIZE;
+	}
+
+	/* Now create ecounters config request with totallength */
+	req = (ecounters_config_request_v2_t *)MALLOCZ(dhd->osh, sizeof(*req) +
+		total_processed_containers_len);
+
+	if (req == NULL) {
+		rc = BCME_NOMEM;
+		goto fail;
+	}
+
+	req->version = ECOUNTERS_VERSION_2;
+	req->logset = EVENT_LOG_SET_ECOUNTERS;
+	req->reporting_period = ECOUNTERS_DEFAULT_PERIOD;
+	req->num_reports = ECOUNTERS_NUM_REPORTS;
+	req->len = total_processed_containers_len +
+		OFFSETOF(ecounters_config_request_v2_t, ecounters_xtlvs);
+
+	/* Copy config */
+	start_ptr = req->ecounters_xtlvs;
+
+	/* Now go element by element in the list */
+	while (processed_containers_list) {
+		list_elt = processed_containers_list;
+
+		elt = (bcm_xtlv_t *)list_elt->data;
+
+		memcpy(start_ptr, list_elt->data, BCM_XTLV_LEN(elt) + BCM_XTLV_HDR_SIZE);
+		start_ptr += (size_t)(BCM_XTLV_LEN(elt) + BCM_XTLV_HDR_SIZE);
+		processed_containers_list = processed_containers_list->next;
+
+		/* Free allocated memories */
+		MFREE(dhd->osh, elt, elt->len + BCM_XTLV_HDR_SIZE);
+		MFREE(dhd->osh, list_elt, sizeof(*list_elt));
+	}
+
+	if ((rc = dhd_iovar(dhd, 0, "ecounters", (char *)req, req->len, NULL, 0, TRUE)) < 0) {
+		DHD_ERROR(("failed to start ecounters\n"));
+	}
+
+fail:
+	if (req) {
+		MFREE(dhd->osh, req, sizeof(*req) + total_processed_containers_len);
+	}
+
+	/* Now go element by element in the list */
+	while (processed_containers_list) {
+		list_elt = processed_containers_list;
+		elt = (bcm_xtlv_t *)list_elt->data;
+		processed_containers_list = processed_containers_list->next;
+
+		/* Free allocated memories */
+		MFREE(dhd->osh, elt, elt->len + BCM_XTLV_HDR_SIZE);
+		MFREE(dhd->osh, list_elt, sizeof(*list_elt));
+	}
+	return rc;
+}
+
+int
+dhd_stop_ecounters(dhd_pub_t *dhd)
+{
+	int rc = BCME_OK;
+	ecounters_config_request_v2_t *req;
+
+	/* Now create ecounters config request with totallength */
+	req = (ecounters_config_request_v2_t *)MALLOCZ(dhd->osh, sizeof(*req));
+
+	if (req == NULL) {
+		rc = BCME_NOMEM;
+		goto fail;
+	}
+
+	req->version = ECOUNTERS_VERSION_2;
+	req->len = OFFSETOF(ecounters_config_request_v2_t, ecounters_xtlvs);
+
+	if ((rc = dhd_iovar(dhd, 0, "ecounters", (char *)req, req->len, NULL, 0, TRUE)) < 0) {
+		DHD_ERROR(("failed to stop ecounters\n"));
+	}
+
+fail:
+	if (req) {
+		MFREE(dhd->osh, req, sizeof(*req));
+	}
+	return rc;
+}
+
+/* configured event_id_array for event ecounters */
+typedef struct event_id_array {
+	uint8	event_id;
+	uint8	str_idx;
+} event_id_array_t;
+
+/* get event id array only from event_ecounters_cfg_tbl[] */
+static inline int __dhd_event_ecounters_get_event_id_array(event_id_array_t *event_array)
+{
+	uint8 i;
+	uint8 idx = 0;
+	int32 prev_evt_id = -1;
+
+	for (i = 0; i < (uint8)ARRAYSIZE(event_ecounters_cfg_tbl); i++) {
+		if (prev_evt_id != event_ecounters_cfg_tbl[i].event_id) {
+			if (prev_evt_id >= 0)
+				idx++;
+			event_array[idx].event_id = event_ecounters_cfg_tbl[i].event_id;
+			event_array[idx].str_idx = i;
+		}
+		prev_evt_id = event_ecounters_cfg_tbl[i].event_id;
+	}
+	return idx;
+}
+
+/* One event id has limit xtlv num to request based on wl_ifstats_xtlv_id * 2 interface */
+#define ECNTRS_MAX_XTLV_NUM (31 * 2)
+
+int
+dhd_start_event_ecounters(dhd_pub_t *dhd)
+{
+	uint8 i, j = 0;
+	uint8 event_id_cnt = 0;
+	uint16 processed_containers_len = 0;
+	uint16 max_xtlv_len = 0;
+	int rc = BCME_OK;
+	uint8 *ptr;
+	uint8 *data;
+	event_id_array_t *id_array;
+	bcm_xtlv_t *elt = NULL;
+	event_ecounters_config_request_v2_t *req = NULL;
+
+	/* XXX: the size of id_array is limited by the size of event_ecounters_cfg_tbl */
+	id_array = (event_id_array_t *)MALLOCZ(dhd->osh, sizeof(event_id_array_t) *
+		ARRAYSIZE(event_ecounters_cfg_tbl));
+
+	if (id_array == NULL) {
+		rc = BCME_NOMEM;
+		goto fail;
+	}
+	event_id_cnt = __dhd_event_ecounters_get_event_id_array(id_array);
+
+	max_xtlv_len = ((BCM_XTLV_HDR_SIZE +
+		OFFSETOF(event_ecounters_config_request_v2_t, ecounters_xtlvs)) *
+		ECNTRS_MAX_XTLV_NUM);
+
+	/* Now create ecounters config request with max allowed length */
+	req = (event_ecounters_config_request_v2_t *)MALLOCZ(dhd->osh,
+		sizeof(event_ecounters_config_request_v2_t *) + max_xtlv_len);
+
+	if (req == NULL) {
+		rc = BCME_NOMEM;
+		goto fail;
+	}
+
+	for (i = 0; i <= event_id_cnt; i++) {
+		/* req initialization by event id */
+		req->version = ECOUNTERS_VERSION_2;
+		req->logset = EVENT_LOG_SET_ECOUNTERS;
+		req->event_id = id_array[i].event_id;
+		req->flags = EVENT_ECOUNTERS_FLAGS_ADD;
+		req->len = 0;
+		processed_containers_len = 0;
+
+		/* Copy config */
+		ptr = req->ecounters_xtlvs;
+
+		for (j = id_array[i].str_idx; j < (uint8)ARRAYSIZE(event_ecounters_cfg_tbl); j++) {
+			event_ecounters_cfg_t *event_ecounter_stat = &event_ecounters_cfg_tbl[j];
+			if (id_array[i].event_id != event_ecounter_stat->event_id)
+				break;
+
+			rc = dhd_create_ecounters_params(dhd, event_ecounter_stat->type,
+				event_ecounter_stat->if_slice_idx, event_ecounter_stat->stats_rep,
+				&data);
+
+			if (rc) {
+				DHD_ERROR(("%s: Could not process: stat: %d return code: %d\n",
+					__FUNCTION__, event_ecounter_stat->stats_rep, rc));
+				goto fail;
+			}
+
+			elt = (bcm_xtlv_t *)data;
+
+			memcpy(ptr, elt, BCM_XTLV_LEN(elt) + BCM_XTLV_HDR_SIZE);
+			ptr += (size_t)(BCM_XTLV_LEN(elt) + BCM_XTLV_HDR_SIZE);
+			processed_containers_len += BCM_XTLV_LEN(elt) + BCM_XTLV_HDR_SIZE;
+
+			/* Free allocated memories alloced by dhd_create_ecounters_params */
+			MFREE(dhd->osh, elt, elt->len + BCM_XTLV_HDR_SIZE);
+
+			if (processed_containers_len > max_xtlv_len) {
+				DHD_ERROR(("%s XTLV NUM IS OVERFLOWED THAN ALLOWED!!\n",
+					__FUNCTION__));
+				rc = BCME_BADLEN;
+				goto fail;
+			}
+		}
+
+		req->len = processed_containers_len +
+			OFFSETOF(event_ecounters_config_request_v2_t, ecounters_xtlvs);
+
+		DHD_INFO(("%s req version %d logset %d event_id %d flags %d len %d\n",
+			__FUNCTION__, req->version, req->logset, req->event_id,
+			req->flags, req->len));
+
+		rc = dhd_iovar(dhd, 0, "event_ecounters", (char *)req, req->len, NULL, 0, TRUE);
+
+		if (rc < 0) {
+			DHD_ERROR(("failed to start event_ecounters(event id %d) with rc %d\n",
+				req->event_id, rc));
+			goto fail;
+		}
+	}
+
+fail:
+	/* Free allocated memories */
+	if (req) {
+		MFREE(dhd->osh, req, sizeof(event_ecounters_config_request_v2_t *) + max_xtlv_len);
+	}
+	if (id_array) {
+		MFREE(dhd->osh, id_array, sizeof(event_id_array_t) *
+			ARRAYSIZE(event_ecounters_cfg_tbl));
+	}
+
+	return rc;
+}
+
+int
+dhd_stop_event_ecounters(dhd_pub_t *dhd)
+{
+	int rc = BCME_OK;
+	event_ecounters_config_request_v2_t *req;
+
+	/* Now create ecounters config request with totallength */
+	req = (event_ecounters_config_request_v2_t *)MALLOCZ(dhd->osh, sizeof(*req));
+
+	if (req == NULL) {
+		rc = BCME_NOMEM;
+		goto fail;
+	}
+
+	req->version = ECOUNTERS_VERSION_2;
+	req->flags = EVENT_ECOUNTERS_FLAGS_DEL_ALL;
+	req->len = OFFSETOF(event_ecounters_config_request_v2_t, ecounters_xtlvs);
+
+	if ((rc = dhd_iovar(dhd, 0, "event_ecounters", (char *)req, req->len, NULL, 0, TRUE)) < 0) {
+		DHD_ERROR(("failed to stop event_ecounters\n"));
+	}
+
+fail:
+	if (req) {
+		MFREE(dhd->osh, req, sizeof(*req));
+	}
+	return rc;
+}
+
+#ifdef DHD_TX_PROFILE
+int
+dhd_tx_profile_detach(dhd_pub_t *dhdp)
+{
+	int result = BCME_ERROR;
+
+	if (dhdp != NULL && dhdp->protocol_filters != NULL) {
+		MFREE(dhdp->osh, dhdp->protocol_filters, DHD_MAX_PROFILES *
+				sizeof(*(dhdp->protocol_filters)));
+		dhdp->protocol_filters = NULL;
+
+		result = BCME_OK;
+	}
+
+	return result;
+}
+
+int
+dhd_tx_profile_attach(dhd_pub_t *dhdp)
+{
+	int result = BCME_ERROR;
+
+	if (dhdp != NULL) {
+		dhdp->protocol_filters = (dhd_tx_profile_protocol_t*)MALLOCZ(dhdp->osh,
+				DHD_MAX_PROFILES * sizeof(*(dhdp->protocol_filters)));
+
+		if (dhdp->protocol_filters != NULL) {
+			result = BCME_OK;
+		}
+	}
+
+	if (result != BCME_OK) {
+		DHD_ERROR(("%s:\tMALLOC of tx profile protocol filters failed\n",
+			__FUNCTION__));
+	}
+
+	return result;
+}
+#endif /* defined(DHD_TX_PROFILE) */
+
+#endif /* LINUX || linux */
+
+#if defined(DISABLE_HE_ENAB) || defined(CUSTOM_CONTROL_HE_ENAB)
+int
+dhd_control_he_enab(dhd_pub_t * dhd, uint8 he_enab)
+{
+	int ret = BCME_OK;
+	bcm_xtlv_t *pxtlv = NULL;
+	uint8 mybuf[DHD_IOVAR_BUF_SIZE];
+	uint16 mybuf_len = sizeof(mybuf);
+	pxtlv = (bcm_xtlv_t *)mybuf;
+
+	ret = bcm_pack_xtlv_entry((uint8**)&pxtlv, &mybuf_len, WL_HE_CMD_ENAB, sizeof(he_enab),
+			&he_enab, BCM_XTLV_OPTION_ALIGN32);
+
+	if (ret != BCME_OK) {
+		ret = -EINVAL;
+		DHD_ERROR(("%s failed to pack he enab, err: %s\n", __FUNCTION__, bcmerrorstr(ret)));
+		return ret;
+	}
+
+	ret = dhd_iovar(dhd, 0, "he", (char *)&mybuf, sizeof(mybuf), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s he_enab (%d) set failed, err: %s\n",
+				__FUNCTION__, he_enab, bcmerrorstr(ret)));
+	} else {
+		DHD_ERROR(("%s he_enab (%d) set successed\n", __FUNCTION__, he_enab));
+	}
+
+	return ret;
+}
+#endif /* DISABLE_HE_ENAB || CUSTOM_CONTROL_HE_ENAB */
+
+#ifdef CONFIG_ROAM_RSSI_LIMIT
+int
+dhd_roam_rssi_limit_get(dhd_pub_t *dhd, int *lmt2g, int *lmt5g)
+{
+	wlc_roam_rssi_limit_t *plmt;
+	wlc_roam_rssi_lmt_info_v1_t *pinfo;
+	int ret = BCME_OK;
+	int plmt_len = sizeof(*pinfo) + ROAMRSSI_HDRLEN;
+
+	plmt = (wlc_roam_rssi_limit_t *)MALLOCZ(dhd->osh, plmt_len);
+	if (!plmt) {
+		DHD_ERROR(("%s Fail to malloc buffer\n", __FUNCTION__));
+		return BCME_NOMEM;
+	}
+
+	/* Get roam rssi limit */
+	ret = dhd_iovar(dhd, 0, "roam_rssi_limit", NULL, 0, (char *)plmt, plmt_len, FALSE);
+	if (ret < 0) {
+		DHD_ERROR(("%s Failed to Get roam_rssi_limit %d\n", __FUNCTION__, ret));
+		goto done;
+	}
+
+	if (plmt->ver != WLC_ROAM_RSSI_LMT_VER_1) {
+	    ret = BCME_VERSION;
+	    goto done;
+	}
+
+	pinfo = (wlc_roam_rssi_lmt_info_v1_t *)plmt->data;
+	*lmt2g = (int)pinfo->rssi_limit_2g;
+	*lmt5g = (int)pinfo->rssi_limit_5g;
+
+done:
+	if (plmt) {
+		MFREE(dhd->osh, plmt, plmt_len);
+	}
+	return ret;
+}
+
+int
+dhd_roam_rssi_limit_set(dhd_pub_t *dhd, int lmt2g, int lmt5g)
+{
+	wlc_roam_rssi_limit_t *plmt;
+	wlc_roam_rssi_lmt_info_v1_t *pinfo;
+	int ret = BCME_OK;
+	int plmt_len = sizeof(*pinfo) + ROAMRSSI_HDRLEN;
+
+	/* Sanity check RSSI limit Value */
+	if ((lmt2g < ROAMRSSI_2G_MIN) || (lmt2g > ROAMRSSI_2G_MAX)) {
+		DHD_ERROR(("%s Not In Range 2G ROAM RSSI Limit\n", __FUNCTION__));
+		return BCME_RANGE;
+	}
+	if ((lmt2g < ROAMRSSI_5G_MIN) || (lmt2g > ROAMRSSI_5G_MAX)) {
+		DHD_ERROR(("%s Not In Range 5G ROAM RSSI Limit\n", __FUNCTION__));
+		return BCME_RANGE;
+	}
+
+	plmt = (wlc_roam_rssi_limit_t *)MALLOCZ(dhd->osh, plmt_len);
+	if (!plmt) {
+		DHD_ERROR(("%s Fail to malloc buffer\n", __FUNCTION__));
+		return BCME_NOMEM;
+	}
+	plmt->ver = WLC_ROAM_RSSI_LMT_VER_1;
+	plmt->len = sizeof(*pinfo);
+	pinfo = (wlc_roam_rssi_lmt_info_v1_t *)plmt->data;
+	pinfo->rssi_limit_2g = (int16)lmt2g;
+	pinfo->rssi_limit_5g = (int16)lmt5g;
+
+	/* Set roam rssi limit */
+	ret = dhd_iovar(dhd, 0, "roam_rssi_limit", (char *)plmt, plmt_len, NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s Failed to Get roam_rssi_limit %d\n", __FUNCTION__, ret));
+		goto done;
+	}
+done:
+	if (plmt) {
+		MFREE(dhd->osh, plmt, plmt_len);
+	}
+	return ret;
+}
+#endif /* CONFIG_ROAM_RSSI_LIMIT */
+
+#ifdef CONFIG_ROAM_MIN_DELTA
+int
+dhd_roam_min_delta_get(dhd_pub_t *dhd, uint32 *dt2g, uint32 *dt5g)
+{
+	wlc_roam_min_delta_t *pmin_delta;
+	wlc_roam_min_delta_info_v1_t *pmin_delta_info;
+	int ret = BCME_OK;
+	int plen = sizeof(*pmin_delta_info) + ROAM_MIN_DELTA_HDRLEN;
+
+	pmin_delta = (wlc_roam_min_delta_t *)MALLOCZ(dhd->osh, plen);
+	if (!pmin_delta) {
+		DHD_ERROR(("%s Fail to malloc buffer\n", __FUNCTION__));
+		return BCME_NOMEM;
+	}
+
+	/* Get Minimum ROAM score delta */
+	ret = dhd_iovar(dhd, 0, "roam_min_delta", NULL, 0, (char *)pmin_delta, plen, FALSE);
+	if (ret < 0) {
+		DHD_ERROR(("%s Failed to Get roam_min_delta %d\n", __FUNCTION__, ret));
+		goto done;
+	}
+
+	if (pmin_delta->ver != WLC_ROAM_MIN_DELTA_VER_1) {
+		ret = BCME_VERSION;
+		goto done;
+	}
+
+	pmin_delta_info = (wlc_roam_min_delta_info_v1_t *)pmin_delta->data;
+	*dt2g = (uint32)pmin_delta_info->roam_min_delta_2g;
+	*dt5g = (uint32)pmin_delta_info->roam_min_delta_5g;
+
+done:
+	if (pmin_delta) {
+		MFREE(dhd->osh, pmin_delta, plen);
+	}
+	return ret;
+}
+
+int
+dhd_roam_min_delta_set(dhd_pub_t *dhd, uint32 dt2g, uint32 dt5g)
+{
+	wlc_roam_min_delta_t *pmin_delta;
+	wlc_roam_min_delta_info_v1_t *pmin_delta_info;
+	int ret = BCME_OK;
+	int plen = sizeof(*pmin_delta_info) + ROAM_MIN_DELTA_HDRLEN;
+
+	/* Sanity check Minimum ROAM score delta */
+	if ((dt2g > ROAM_MIN_DELTA_MAX) || (dt5g > ROAM_MIN_DELTA_MAX)) {
+		DHD_ERROR(("%s Not In Range Minimum ROAM score delta, 2G: %d, 5G: %d\n",
+			__FUNCTION__, dt2g, dt5g));
+		return BCME_RANGE;
+	}
+
+	pmin_delta = (wlc_roam_min_delta_t *)MALLOCZ(dhd->osh, plen);
+	if (!pmin_delta) {
+		DHD_ERROR(("%s Fail to malloc buffer\n", __FUNCTION__));
+		return BCME_NOMEM;
+	}
+	pmin_delta->ver = WLC_ROAM_MIN_DELTA_VER_1;
+	pmin_delta->len = sizeof(*pmin_delta_info);
+	pmin_delta_info = (wlc_roam_min_delta_info_v1_t *)pmin_delta->data;
+	pmin_delta_info->roam_min_delta_2g = (uint32)dt2g;
+	pmin_delta_info->roam_min_delta_5g = (uint32)dt5g;
+
+	/* Set Minimum ROAM score delta */
+	ret = dhd_iovar(dhd, 0, "roam_min_delta", (char *)pmin_delta, plen, NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s Failed to Set roam_min_delta %d\n", __FUNCTION__, ret));
+		goto done;
+	}
+done:
+	if (pmin_delta) {
+		MFREE(dhd->osh, pmin_delta, plen);
+	}
+	return ret;
+}
+#endif /* CONFIG_ROAM_MIN_DELTA */
+
+int
+dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *param_buf, uint param_len, char *res_buf,
+		uint res_len, bool set)
+{
+	char *buf = NULL;
+	uint input_len;
+	wl_ioctl_t ioc;
+	int ret;
+
+	if (res_len > WLC_IOCTL_MAXLEN || param_len > WLC_IOCTL_MAXLEN)
+		return BCME_BADARG;
+
+	input_len = strlen(name) + 1 + param_len;
+
+	/* WAR to fix GET iovar returning buf too short error
+	 * If param len is 0 for get iovar, increment input_len by sizeof(int)
+	 * to avoid the length check error in fw
+	 */
+	if (!set && !param_len) {
+		input_len += (uint) sizeof(int);
+	}
+	if (input_len > WLC_IOCTL_MAXLEN)
+		return BCME_BADARG;
+
+	buf = NULL;
+	if (set) {
+		if (res_buf || res_len != 0) {
+			DHD_ERROR(("%s: SET wrong arguemnet\n", __FUNCTION__));
+			ret = BCME_BADARG;
+			goto exit;
+		}
+		buf = MALLOCZ(pub->osh, input_len);
+		if (!buf) {
+			DHD_ERROR(("%s: mem alloc failed\n", __FUNCTION__));
+			ret = BCME_NOMEM;
+			goto exit;
+		}
+		ret = bcm_mkiovar(name, param_buf, param_len, buf, input_len);
+		if (!ret) {
+			ret = BCME_NOMEM;
+			goto exit;
+		}
+
+		ioc.cmd = WLC_SET_VAR;
+		ioc.buf = buf;
+		ioc.len = input_len;
+		ioc.set = set;
+
+		ret = dhd_wl_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len);
+	} else {
+		if (!res_buf || !res_len) {
+			DHD_ERROR(("%s: GET failed. resp_buf NULL or length 0.\n", __FUNCTION__));
+			ret = BCME_BADARG;
+			goto exit;
+		}
+
+		if (res_len < input_len) {
+			DHD_INFO(("%s: res_len(%d) < input_len(%d)\n", __FUNCTION__,
+					res_len, input_len));
+			buf = MALLOCZ(pub->osh, input_len);
+			if (!buf) {
+				DHD_ERROR(("%s: mem alloc failed\n", __FUNCTION__));
+				ret = BCME_NOMEM;
+				goto exit;
+			}
+			ret = bcm_mkiovar(name, param_buf, param_len, buf, input_len);
+			if (!ret) {
+				ret = BCME_NOMEM;
+				goto exit;
+			}
+
+			ioc.cmd = WLC_GET_VAR;
+			ioc.buf = buf;
+			ioc.len = input_len;
+			ioc.set = set;
+
+			ret = dhd_wl_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len);
+
+			if (ret == BCME_OK) {
+				memcpy(res_buf, buf, res_len);
+			}
+		} else {
+			memset(res_buf, 0, res_len);
+			ret = bcm_mkiovar(name, param_buf, param_len, res_buf, res_len);
+			if (!ret) {
+				ret = BCME_NOMEM;
+				goto exit;
+			}
+
+			ioc.cmd = WLC_GET_VAR;
+			ioc.buf = res_buf;
+			ioc.len = res_len;
+			ioc.set = set;
+
+			ret = dhd_wl_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len);
+		}
+	}
+exit:
+	if (buf) {
+		MFREE(pub->osh, buf, input_len);
+	}
+	return ret;
+}
+
+#ifdef DHD_DEBUG
+void
+dhd_convert_memdump_type_to_str(uint32 type, char *buf, size_t buf_len, int substr_type)
+{
+	char *type_str = NULL;
+
+	switch (type) {
+		case DUMP_TYPE_RESUMED_ON_TIMEOUT:
+			type_str = "resumed_on_timeout";
+			break;
+		case DUMP_TYPE_D3_ACK_TIMEOUT:
+			type_str = "D3_ACK_timeout";
+			break;
+		case DUMP_TYPE_DONGLE_TRAP:
+			type_str = "Dongle_Trap";
+			break;
+		case DUMP_TYPE_DONGLE_TRAP_DURING_WIFI_ONOFF:
+			type_str = "Dongle_Trap_During_Wifi_OnOff";
+			break;
+		case DUMP_TYPE_BY_DSACK_HC_DUE_TO_ISR_DELAY:
+			type_str = "Dongle_Trap_DSACK_HC_due_to_ISR_delay";
+			break;
+		case DUMP_TYPE_BY_DSACK_HC_DUE_TO_DPC_DELAY:
+			type_str = "Dongle_Trap_DSACK_HC_due_to_DPC_delay";
+			break;
+		case DUMP_TYPE_MEMORY_CORRUPTION:
+			type_str = "Memory_Corruption";
+			break;
+		case DUMP_TYPE_PKTID_AUDIT_FAILURE:
+			type_str = "PKTID_AUDIT_Fail";
+			break;
+		case DUMP_TYPE_PKTID_INVALID:
+			type_str = "PKTID_INVALID";
+			break;
+		case DUMP_TYPE_SCAN_TIMEOUT:
+			type_str = "SCAN_timeout";
+			break;
+		case DUMP_TYPE_SCAN_BUSY:
+			type_str = "SCAN_Busy";
+			break;
+		case DUMP_TYPE_BY_SYSDUMP:
+			if (substr_type == CMD_UNWANTED) {
+				type_str = "BY_SYSDUMP_FORUSER_unwanted";
+			} else if (substr_type == CMD_DISCONNECTED) {
+				type_str = "BY_SYSDUMP_FORUSER_disconnected";
+			} else {
+				type_str = "BY_SYSDUMP_FORUSER";
+			}
+			break;
+		case DUMP_TYPE_BY_LIVELOCK:
+			type_str = "BY_LIVELOCK";
+			break;
+		case DUMP_TYPE_AP_LINKUP_FAILURE:
+			type_str = "BY_AP_LINK_FAILURE";
+			break;
+		case DUMP_TYPE_AP_ABNORMAL_ACCESS:
+			type_str = "INVALID_ACCESS";
+			break;
+		case DUMP_TYPE_RESUMED_ON_TIMEOUT_RX:
+			type_str = "ERROR_RX_TIMED_OUT";
+			break;
+		case DUMP_TYPE_RESUMED_ON_TIMEOUT_TX:
+			type_str = "ERROR_TX_TIMED_OUT";
+			break;
+		case DUMP_TYPE_CFG_VENDOR_TRIGGERED:
+			type_str = "CFG_VENDOR_TRIGGERED";
+			break;
+		case DUMP_TYPE_RESUMED_ON_INVALID_RING_RDWR:
+			type_str = "BY_INVALID_RING_RDWR";
+			break;
+		case DUMP_TYPE_IFACE_OP_FAILURE:
+			type_str = "BY_IFACE_OP_FAILURE";
+			break;
+		case DUMP_TYPE_TRANS_ID_MISMATCH:
+			type_str = "BY_TRANS_ID_MISMATCH";
+			break;
+#ifdef DEBUG_DNGL_INIT_FAIL
+		case DUMP_TYPE_DONGLE_INIT_FAILURE:
+			type_str = "DONGLE_INIT_FAIL";
+			break;
+#endif /* DEBUG_DNGL_INIT_FAIL */
+		case DUMP_TYPE_DONGLE_HOST_EVENT:
+			type_str = "BY_DONGLE_HOST_EVENT";
+			break;
+		case DUMP_TYPE_SMMU_FAULT:
+			type_str = "SMMU_FAULT";
+			break;
+		case DUMP_TYPE_BY_USER:
+			type_str = "BY_USER";
+			break;
+		case DUMP_TYPE_LOGSET_BEYOND_RANGE:
+			type_str = "LOGSET_BEYOND_RANGE";
+			break;
+		case DUMP_TYPE_CTO_RECOVERY:
+			type_str = "CTO_RECOVERY";
+			break;
+		case DUMP_TYPE_SEQUENTIAL_PRIVCMD_ERROR:
+			type_str = "SEQUENTIAL_PRIVCMD_ERROR";
+			break;
+		case DUMP_TYPE_PROXD_TIMEOUT:
+			type_str = "PROXD_TIMEOUT";
+			break;
+		case DUMP_TYPE_INBAND_DEVICE_WAKE_FAILURE:
+			type_str = "INBAND_DEVICE_WAKE_FAILURE";
+			break;
+		case DUMP_TYPE_PKTID_POOL_DEPLETED:
+			type_str = "PKTID_POOL_DEPLETED";
+			break;
+		case DUMP_TYPE_ESCAN_SYNCID_MISMATCH:
+			type_str = "ESCAN_SYNCID_MISMATCH";
+			break;
+		case DUMP_TYPE_INVALID_SHINFO_NRFRAGS:
+			type_str = "INVALID_SHINFO_NRFRAGS";
+			break;
+		case DUMP_TYPE_P2P_DISC_BUSY:
+			type_str = "P2P_DISC_BUSY";
+			break;
+		case DUMP_TYPE_CONT_EXCESS_PM_AWAKE:
+			type_str = "CONT_EXCESS_PM_AWAKE";
+			break;
+		default:
+			type_str = "Unknown_type";
+			break;
+	}
+
+	strlcpy(buf, type_str, buf_len);
+}
+#endif /* DHD_DEBUG */
+
+#ifdef DHD_LOGLEVEL
+void dhd_loglevel_get(dhd_loglevel_data_t *level_data)
+{
+	level_data->dhd_print_lv = dhd_msg_level;
+	level_data->dhd_log_lv = dhd_log_level;
+	level_data->wl_print_lv = wl_cfg80211_get_print_level();
+	level_data->wl_log_lv = wl_cfg80211_get_log_level();
+}
+
+void dhd_loglevel_set(dhd_loglevel_data_t *level_data)
+{
+	if (level_data->type == DHD_LOGLEVEL_TYPE_ALL) {
+#ifdef WL_CFG80211
+		if (level_data->component == DHD_LOGLEVEL_COMP_WL) {
+			wl_cfg80211_enable_trace(level_data->wl_print_lv);
+			wl_cfg80211_enable_log_trace(TRUE, level_data->wl_log_lv);
+		} else
+#endif /* WL_CFG80211 */
+		{
+			dhd_msg_level = level_data->dhd_print_lv;
+			dhd_log_level = level_data->dhd_log_lv;
+		}
+	} else if (level_data->type == DHD_LOGLEVEL_TYPE_PRINT) {
+#ifdef WL_CFG80211
+		if (level_data->component == DHD_LOGLEVEL_COMP_WL) {
+			wl_cfg80211_enable_trace(level_data->wl_print_lv);
+		} else
+#endif /* WL_CFG80211 */
+		{
+			dhd_msg_level = level_data->dhd_print_lv;
+		}
+	} else if (level_data->type == DHD_LOGLEVEL_TYPE_LOG) {
+#ifdef WL_CFG80211
+		if (level_data->component == DHD_LOGLEVEL_COMP_WL) {
+			wl_cfg80211_enable_log_trace(TRUE, level_data->wl_log_lv);
+		} else
+#endif /* WL_CFG80211 */
+		{
+			dhd_log_level = level_data->dhd_log_lv;
+		}
+	}
+	DHD_ERROR(("%s: type:%u dhd_msg_level:0x%x dhd_log_level:0x%x\n",
+		__func__, level_data->type, dhd_msg_level, dhd_log_level));
+	DHD_ERROR(("%s: type:%u wl_dbg_level:0x%x wl_log_level:0x%x\n",
+		__func__, level_data->type, wl_dbg_level, wl_log_level));
+}
+#endif /* DHD_LOGLEVEL */
+
+#if defined(DHD_WAKE_STATUS_PRINT) && defined(DHD_WAKE_RX_STATUS) && \
+	defined(DHD_WAKE_STATUS)
+#ifdef BCMPCIE
+extern int bcmpcie_get_total_wake(struct dhd_bus *bus);
+#endif /* BCMPCIE */
+void
+dhd_dump_wake_status(dhd_pub_t *dhdp, wake_counts_t *wcp, struct ether_header *eh)
+{
+	uint wake = 0;
+
+	BCM_REFERENCE(wake);
+#ifdef BCMPCIE
+	wake = bcmpcie_get_total_wake(dhdp->bus);
+#endif /* BCMPCIE */
+
+	DHD_ERROR(("wake %u rxwake %u readctrlwake %u\n",
+		wake, wcp->rxwake, wcp->rcwake));
+	DHD_ERROR(("unicast %u muticast %u broadcast %u icmp %u\n",
+		wcp->rx_ucast, wcp->rx_mcast, wcp->rx_bcast, wcp->rx_icmp));
+	DHD_ERROR(("multi4 %u multi6 %u icmp6 %u multiother %u\n",
+		wcp->rx_multi_ipv4, wcp->rx_multi_ipv6, wcp->rx_icmpv6, wcp->rx_multi_other));
+	DHD_ERROR(("icmp6_ra %u, icmp6_na %u, icmp6_ns %u\n",
+		wcp->rx_icmpv6_ra, wcp->rx_icmpv6_na, wcp->rx_icmpv6_ns));
+	DHD_ERROR(("Src_mac: "MACDBG", Dst_mac: "MACDBG"\n",
+		MAC2STRDBG(eh->ether_shost), MAC2STRDBG(eh->ether_dhost)));
+	return;
+}
+#endif /* DHD_WAKE_STATUS_PRINT && DHD_WAKE_RX_STATUS && DHD_WAKE_STATUS */
+#ifdef SUPPORT_OTA_UPDATE
+void
+dhd_ota_buf_clean(dhd_pub_t *dhdp)
+{
+	ota_update_info_t *ota_info = &dhdp->ota_update_info;
+
+	if (ota_info->clm_buf) {
+		MFREE(dhdp->osh, ota_info->clm_buf, ota_info->clm_len);
+	}
+	if (ota_info->nvram_buf) {
+		MFREE(dhdp->osh, ota_info->nvram_buf, ota_info->nvram_len);
+	}
+	ota_info->nvram_len = 0;
+	ota_info->clm_len = 0;
+	return;
+}
+#endif /* SUPPORT_OTA_UPDATE */
+
+#if !defined(AP) && defined(WLP2P)
+/* From Android JerryBean release, the concurrent mode is enabled by default and the firmware
+ * name would be fw_bcmdhd.bin. So we need to determine whether P2P is enabled in the STA
+ * firmware and accordingly enable concurrent mode (Apply P2P settings). SoftAP firmware
+ * would still be named as fw_bcmdhd_apsta.
+ */
+uint32
+dhd_get_concurrent_capabilites(dhd_pub_t *dhd)
+{
+	int32 ret = 0;
+	char buf[WLC_IOCTL_SMLEN];
+	bool mchan_supported = FALSE;
+	/* if dhd->op_mode is already set for HOSTAP and Manufacturing
+	 * test mode, that means we only will use the mode as it is
+	 */
+	if (dhd->op_mode & (DHD_FLAG_HOSTAP_MODE | DHD_FLAG_MFG_MODE))
+		return 0;
+	if (FW_SUPPORTED(dhd, vsdb)) {
+		mchan_supported = TRUE;
+	}
+	if (!FW_SUPPORTED(dhd, p2p)) {
+		DHD_TRACE(("Chip does not support p2p\n"));
+		return 0;
+	} else {
+		/* Chip supports p2p but ensure that p2p is really implemented in firmware or not */
+		memset(buf, 0, sizeof(buf));
+		ret = dhd_iovar(dhd, 0, "p2p", NULL, 0, (char *)&buf,
+				sizeof(buf), FALSE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: Get P2P failed (error=%d)\n", __FUNCTION__, ret));
+			return 0;
+		} else {
+			if (buf[0] == 1) {
+				/* By default, chip supports single chan concurrency,
+				* now lets check for mchan
+				*/
+				ret = DHD_FLAG_CONCURR_SINGLE_CHAN_MODE;
+				if (mchan_supported)
+					ret |= DHD_FLAG_CONCURR_MULTI_CHAN_MODE;
+				if (FW_SUPPORTED(dhd, rsdb)) {
+					ret |= DHD_FLAG_RSDB_MODE;
+				}
+#ifdef WL_SUPPORT_MULTIP2P
+				if (FW_SUPPORTED(dhd, mp2p)) {
+					ret |= DHD_FLAG_MP2P_MODE;
+				}
+#endif /* WL_SUPPORT_MULTIP2P */
+#if defined(WL_CFG80211_P2P_DEV_IF)
+				return ret;
+#else
+				return 0;
+#endif
+			}
+		}
+	}
+	return 0;
+}
+#endif /* !defined(AP) && defined(WLP2P) */
+
+#ifdef SUPPORT_AP_POWERSAVE
+int dhd_set_ap_powersave(dhd_pub_t *dhdp, int ifidx, int enable)
+{
+	int32 pps = RXCHAIN_PWRSAVE_PPS;
+	int32 quiet_time = RXCHAIN_PWRSAVE_QUIET_TIME;
+	int32 stas_assoc_check = RXCHAIN_PWRSAVE_STAS_ASSOC_CHECK;
+	int ret;
+
+	if (enable) {
+		ret = dhd_iovar(dhdp, 0, "rxchain_pwrsave_enable", (char *)&enable, sizeof(enable),
+				NULL, 0, TRUE);
+		if (ret != BCME_OK) {
+			DHD_ERROR(("Failed to enable AP power save"));
+		}
+		ret = dhd_iovar(dhdp, 0, "rxchain_pwrsave_pps", (char *)&pps, sizeof(pps), NULL, 0,
+				TRUE);
+		if (ret != BCME_OK) {
+			DHD_ERROR(("Failed to set pps"));
+		}
+		ret = dhd_iovar(dhdp, 0, "rxchain_pwrsave_quiet_time", (char *)&quiet_time,
+				sizeof(quiet_time), NULL, 0, TRUE);
+		if (ret != BCME_OK) {
+			DHD_ERROR(("Failed to set quiet time"));
+		}
+		ret = dhd_iovar(dhdp, 0, "rxchain_pwrsave_stas_assoc_check",
+				(char *)&stas_assoc_check, sizeof(stas_assoc_check), NULL, 0, TRUE);
+		if (ret != BCME_OK) {
+			DHD_ERROR(("Failed to set stas assoc check"));
+		}
+	} else {
+		ret = dhd_iovar(dhdp, 0, "rxchain_pwrsave_enable", (char *)&enable, sizeof(enable),
+				NULL, 0, TRUE);
+		if (ret != BCME_OK) {
+			DHD_ERROR(("Failed to disable AP power save"));
+		}
+	}
+
+	return 0;
+}
+#endif /* SUPPORT_AP_POWERSAVE */
+#ifdef DHD_COREDUMP
+void
+dhd_convert_hang_reason_to_str(uint32 reason, char *buf, size_t buf_len)
+{
+	char *type_str = NULL;
+
+	switch (reason) {
+		case HANG_REASON_BUS_DOWN:
+			type_str = "BUS_DOWN";
+			break;
+		case HANG_REASON_PCIE_RC_LINK_UP_FAIL:
+			type_str = "PCIE_RC_LINK_UP_FAIL";
+			break;
+		case HANG_REASON_IOCTL_SUSPEND_ERROR:
+			type_str = "IOCTL_SUSPEND_ERROR";
+			break;
+		case HANG_REASON_PCIE_LINK_DOWN_RC_DETECT:
+			type_str = "PCIE_LINK_DOWN_RC_DETECT";
+			break;
+		case HANG_REASON_PCIE_LINK_DOWN_EP_DETECT:
+			type_str = "PCIE_LINK_DOWN_EP_DETECT";
+			break;
+		case HANG_REASON_MSGBUF_LIVELOCK:
+			type_str = "BY_LIVELOCK";
+			break;
+		case HANG_REASON_IOCTL_RESP_TIMEOUT:
+		case HANG_REASON_IOCTL_RESP_TIMEOUT_SCHED_ERROR:
+			type_str = "resumed_on_timeout";
+			break;
+		case HANG_REASON_D3_ACK_TIMEOUT:
+		case HANG_REASON_D3_ACK_TIMEOUT_SCHED_ERROR:
+			type_str = "D3_ACK_timeout";
+			break;
+		case HANG_REASON_DONGLE_TRAP:
+			type_str = "Dongle_Trap";
+			break;
+		case HANG_REASON_PCIE_PKTID_ERROR:
+			type_str = "PKTID_INVALID";
+			break;
+		case HANG_REASON_SCAN_TIMEOUT:
+		case HANG_REASON_SCAN_TIMEOUT_SCHED_ERROR:
+			type_str = "SCAN_timeout";
+			break;
+		case HANG_REASON_SCAN_BUSY:
+			type_str = "SCAN_Busy";
+			break;
+		case HANG_REASON_IFACE_DEL_FAILURE:
+		case HANG_REASON_IFACE_ADD_FAILURE:
+		case HANG_REASON_BSS_UP_FAILURE:
+		case HANG_REASON_BSS_DOWN_FAILURE:
+			type_str = "BY_IFACE_OP_FAILURE";
+			break;
+		case HANG_REASON_PCIE_CTO_DETECT:
+			type_str = "CTO_RECOVERY";
+			break;
+		case HANG_REASON_SEQUENTIAL_PRIVCMD_ERROR:
+			type_str = "SEQUENTIAL_PRIVCMD_ERROR";
+			break;
+		case HANG_REASON_ESCAN_SYNCID_MISMATCH:
+			type_str = "ESCAN_SYNCID_MISMATCH";
+			break;
+		case HANG_REASON_P2P_DISC_BUSY:
+			type_str = "P2P_DISC_BUSY";
+			break;
+		case HANG_REASON_DS_SKIP_TIMEOUT:
+			type_str = "DS_SKIP_TIMEOUT";
+			break;
+		case HANG_REASON_BT2WL_REG_RESET:
+			type_str = "BT2WL_REG_RESET";
+			break;
+		default:
+			type_str = "Unknown_type";
+			break;
+	}
+
+	strlcpy(buf, type_str, buf_len);
+}
+#endif /* DHD_COREDUMP */
+#ifdef DHD_CUSTOM_CONFIG_RTS_IN_SUSPEND
+int dhd_config_rts_in_suspend(dhd_pub_t *dhdp, bool suspend)
+{
+	int ret = BCME_OK;
+	uint return_to_sleep_time = 0;
+
+	int buf_len;
+	bcm_iov_buf_t *iov_buf = NULL;
+	wl_adps_suspend_v1_t *data = NULL;
+
+	if (!dhdp || dhdp->up == 0) {
+		return ret;
+	}
+
+	/* if it's not associated, skip to set */
+	if (!dhd_is_associated(dhdp, 0, NULL)) {
+		return ret;
+	}
+
+	if (suspend) {
+		return_to_sleep_time = CUSTOM_RETRUN_TO_SLEEP_TIME_SUSPEND;
+	}
+	else {
+		return_to_sleep_time = CUSTOM_RETRUN_TO_SLEEP_TIME_DEFAULT;
+	}
+
+	ret = dhd_iovar(dhdp, 0, "pm2_sleep_ret", (char *)&return_to_sleep_time,
+			sizeof(return_to_sleep_time), NULL, 0, TRUE);
+
+	if (ret < 0) {
+		DHD_ERROR(("%s set pm2_sleep_ret failed %d\n", __FUNCTION__, ret));
+		goto exit;
+	}
+
+	buf_len = OFFSETOF(bcm_iov_buf_t, data) + sizeof(*data);
+	iov_buf = MALLOCZ(dhdp->osh, buf_len);
+	if (iov_buf == NULL) {
+		DHD_ERROR(("%s - failed to alloc %d bytes for iov_buf\n",
+			__FUNCTION__, buf_len));
+		ret = BCME_NOMEM;
+		goto exit;
+	}
+
+	iov_buf->version = WL_ADPS_IOV_VER;
+	iov_buf->len = sizeof(*data);
+	iov_buf->id = WL_ADPS_IOV_SUSPEND;
+
+	data = (wl_adps_suspend_v1_t *)iov_buf->data;
+	data->version = ADPS_SUB_IOV_VERSION_1;
+	data->length = sizeof(*data);
+	data->suspend = suspend;
+
+	ret = dhd_iovar(dhdp, 0, "adps", (char *)iov_buf, buf_len,
+		NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s - fail to set adps suspend %d (%d)\n",
+				__FUNCTION__, suspend, ret));
+		goto exit;
+	}
+
+exit:
+	if (ret == BCME_OK) {
+		DHD_ERROR(("%s - Success to set RTS [%d] and ADPS suspend [%d].\n",
+				__FUNCTION__, return_to_sleep_time, suspend));
+	}
+	if (iov_buf) {
+		MFREE(dhdp->osh, iov_buf, buf_len);
+	}
+	return ret;
+}
+#endif /* DHD_CUSTOM_CONFIG_RTS_IN_SUSPEND */
+
+void
+dhd_histo_update(dhd_pub_t *dhd, uint64 *histo, uint32 value)
+{
+	uint64 *p;
+	uint64 *bin = histo;
+	uint32 bin_power = next_larger_power2(value);
+	if (histo == NULL) {
+		DHD_ERROR(("%s: histo is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	switch (bin_power) {
+		case   1: p = bin + 0; break;
+		case   2: p = bin + 1; break;
+		case   4: p = bin + 2; break;
+		case   8: p = bin + 3; break;
+		case  16: p = bin + 4; break;
+		case  32: p = bin + 5; break;
+		case  64: p = bin + 6; break;
+		case 128: p = bin + 7; break;
+		case 256: p = bin + 8; break;
+		case 512: p = bin + 9; break;
+		case 1024: p = bin + 10; break;
+		case 2048: p = bin + 11; break;
+		case 4096: p = bin + 12; break;
+		case 8192: p = bin + 13; break;
+		default : p = bin + 13; break;
+	}
+	ASSERT((p - bin) < DHD_HISTOGRAM_ENTRIES);
+	*p = *p + 1;
+	return;
+}
+
+void
+dhd_histo_clear(dhd_pub_t *dhd, uint64 *histo)
+{
+
+	if (histo == NULL) {
+		return;
+	}
+
+	bzero(histo, DHD_HISTOGRAM_SIZE);
+}
+
+void
+dhd_histo_tag_dump(dhd_pub_t *dhd, struct bcmstrbuf *strbuf, char *tagname)
+{
+	uint32 i;
+
+	bcm_bprintf(strbuf, "%20s: ", tagname);
+	for (i = 0; i < DHD_HISTOGRAM_ENTRIES; i++) {
+		bcm_bprintf(strbuf, "%10llu ", 1ULL<<i);
+	}
+	bcm_bprintf(strbuf, "\n");
+}
+
+void
+dhd_histo_dump(dhd_pub_t *dhd, struct bcmstrbuf *strbuf, uint64 *histo, char *histoname)
+{
+	uint32 i;
+
+	if (histo == NULL) {
+		return;
+	}
+
+	bcm_bprintf(strbuf, "%20s: ", histoname);
+	for (i = 0; i < DHD_HISTOGRAM_ENTRIES; i++) {
+		bcm_bprintf(strbuf, "%10llu ", histo[i]);
+	}
+	bcm_bprintf(strbuf, "\n");
+}
+
+uint64 *
+dhd_histo_init(dhd_pub_t *dhd)
+{
+	uint64 *histo;
+	histo = (uint64 *)MALLOCZ(dhd->osh, DHD_HISTOGRAM_SIZE);
+	if (histo == NULL) {
+		DHD_ERROR(("%s: unable to alloc histo\n", __FUNCTION__));
+	}
+	return histo;
+}
+
+void
+dhd_histo_deinit(dhd_pub_t *dhd, uint64 *histo)
+{
+	if (histo) {
+		MFREE(dhd->osh, histo, DHD_HISTOGRAM_SIZE);
+	}
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_config.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_config.c
@@ -0,0 +1,5566 @@
+
+#include <typedefs.h>
+#include <osl.h>
+
+#include <bcmendian.h>
+#include <bcmutils.h>
+#include <hndsoc.h>
+#include <bcmsdbus.h>
+#if defined(HW_OOB) || defined(FORCE_WOWLAN)
+#include <bcmdefs.h>
+#include <bcmsdh.h>
+#include <sdio.h>
+#include <sbchipc.h>
+#endif
+#ifdef DHDTCPACK_SUPPRESS
+#include <dhd_ip.h>
+#endif /* DHDTCPACK_SUPPRESS */
+#ifdef WL_CFG80211
+#include <wl_cfg80211.h>
+#endif
+
+#include <dhd_config.h>
+#include <dhd_dbg.h>
+#include <wl_android.h>
+#ifdef BCMPCIE
+#include <dhd_flowring.h>
+#endif
+
+#include <dhd_linux_priv.h>
+#if defined(BCMSDIO) || defined(BCMPCIE)
+#include <dhd_linux.h>
+#include <dhd_bus.h>
+#ifdef BCMSDIO
+#include <linux/mmc/core.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_func.h>
+#endif /* defined(BCMSDIO) */
+#endif
+
+uint config_msg_level = CONFIG_ERROR_LEVEL | CONFIG_MSG_LEVEL;
+uint dump_msg_level = 0;
+
+#define CONFIG_MSG(x, args...) \
+	do { \
+		if (config_msg_level & CONFIG_MSG_LEVEL) { \
+			printf("%s : " x, __func__, ## args); \
+		} \
+	} while (0)
+#define CONFIG_ERROR(x, args...) \
+	do { \
+		if (config_msg_level & CONFIG_ERROR_LEVEL) { \
+			printf("CONFIG-ERROR) %s : " x, __func__, ## args); \
+		} \
+	} while (0)
+#define CONFIG_TRACE(x, args...) \
+	do { \
+		if (config_msg_level & CONFIG_TRACE_LEVEL) { \
+			printf("CONFIG-TRACE) %s : " x, __func__, ## args); \
+		} \
+	} while (0)
+
+#define MAXSZ_BUF		4096
+#define MAXSZ_CONFIG	8192
+
+extern uint wl_reassoc_support;
+#ifdef BTC_WAR
+extern int btc_war;
+#endif /* BTC_WAR */
+#if defined(BCMSDIO) && defined(DYNAMIC_MAX_HDR_READ)
+extern uint firstread;
+#endif
+
+#if defined(PROP_TXSTATUS)
+#include <dhd_wlfc.h>
+#endif /* PROP_TXSTATUS */
+
+#define MAX_EVENT_BUF_NUM 16
+typedef struct eventmsg_buf {
+	u16 num;
+	struct {
+		u16 type;
+		bool set;
+	} event [MAX_EVENT_BUF_NUM];
+} eventmsg_buf_t;
+
+typedef struct chip_name_map_t {
+	uint chip;
+	uint chiprev;
+	char *chip_name;
+	char *module_name;
+} chip_name_map_t;
+
+const chip_name_map_t chip_name_map[] = {
+	/* ChipID			Chiprev	ChipName		ModuleName */
+#ifdef BCMSDIO
+	{BCM43430_CHIP_ID,	0,	"bcm43438a0",		""},
+	{BCM43430_CHIP_ID,	1,	"bcm43438a1",		""},
+	{BCM43430_CHIP_ID,	2,	"bcm43436b0",		""},
+	{BCM43012_CHIP_ID,	2,	"bcm43013c1_ag",	""},
+	{BCM4345_CHIP_ID,	6,	"bcm43455c0_ag",	""},
+	{BCM4345_CHIP_ID,	9,	"bcm43456c5_ag",	""},
+	{BCM4359_CHIP_ID,	9,	"bcm4359c0_ag",		""},
+	{BCM43752_CHIP_ID,	2,	"bcm43752a2_ag",	""},
+#endif
+#ifdef BCMPCIE
+	{BCM4359_CHIP_ID,	9,	"bcm4359c0_pcie_ag",	""},
+	{BCM43752_CHIP_ID,	2,	"bcm43752a2_pcie_ag",	""},
+	{BCM4375_CHIP_ID,	5,	"bcm4375b4_pcie_ag",	""},
+#endif
+#ifdef BCMDBUS
+	{BCM43569_CHIP_ID,	2,	"bcm4358u_ag",		""},
+#endif
+};
+
+typedef struct module_name_map_v2_t {
+	uint chip;
+	uint chiprev;
+	char *module_name;
+} module_name_map_v2_t;
+
+const module_name_map_v2_t module_name_map_v2[] = {
+	/* ChipID			Chiprev	ModuleName */
+#ifdef BCMSDIO
+	{BCM4381_CHIP_ID,	0,	""},
+	{BCM4381_CHIP_ID,	1,	""},
+	{BCM43752_CHIP_ID,	4,	""},
+	{BCM43756_CHIP_ID,	4,	""},
+	{BCM43756_CHIP_ID,	6,	""},
+	{BCM43711_CHIP_ID,	0,	""},
+	{BCM4382_CHIP_ID,	3,	""},
+#endif
+#ifdef BCMPCIE
+	{BCM4381_CHIP_ID,	0,	""},
+	{BCM4381_CHIP_ID,	1,	""},
+	{BCM43752_CHIP_ID,	4,	""},
+	{BCM43756_CHIP_ID,	4,	""},
+	{BCM43756_CHIP_ID,	6,	""},
+	{BCM43711_CHIP_ID,	0,	""},
+	{BCM4382_CHIP_ID,	3,	""},
+	{BCM4383_CHIP_ID,	2,	""},
+#endif
+#ifdef BCMDBUS
+	{BCM4381_CHIP_ID,	0,	""},
+	{BCM4381_CHIP_ID,	1,	""},
+	{BCM4382_CHIP_ID,	3,	""},
+#endif
+};
+
+typedef struct chip_name_map_v2_t {
+	uint chip;
+	uint chiprev;
+	char *chip_name;
+} chip_name_map_v2_t;
+
+const chip_name_map_v2_t chip_name_map_v2[] = {
+	/* ChipID			Chiprev	ChipName */
+	{BCM4381_CHIP_ID,	0,	"syn4381a0"},
+	{BCM4381_CHIP_ID,	1,	"syn4381a0"},
+	{BCM43752_CHIP_ID,	4,	"syn43756b0"},
+	{BCM43756_CHIP_ID,	4,	"syn43756b0"},
+	{BCM43756_CHIP_ID,	6,	"syn43756c0"},
+	{BCM43711_CHIP_ID,	0,	"syn43711a0"},
+	{BCM4382_CHIP_ID,	3,	"syn4382a0"},
+	{BCM4383_CHIP_ID,	2,	"syn4383a3"},
+};
+
+#ifdef UPDATE_MODULE_NAME
+typedef void (compat_func_t)(dhd_pub_t *dhd);
+typedef struct module_name_map_t {
+	uint devid;
+	uint chip;
+	uint chiprev;
+	uint svid;
+	uint ssid;
+	char *module_name;
+	char *chip_name;
+	compat_func_t *compat_func;
+} module_name_map_t;
+
+#if defined(BCMSDIO) || defined(BCMPCIE)
+static void dhd_conf_compat_vht(dhd_pub_t *dhd);
+#endif
+
+const module_name_map_t module_name_map[] = {
+	/* Devce ID			Chip ID			Chiprev	SVID	SSID
+	 *  ModuleName		ChipName			Compat function
+	 */
+#ifdef BCMSDIO
+	{BCM43751_CHIP_ID,	BCM43752_CHIP_ID,	2,	0, 0,
+		"ap6398s2",		"bcm4359c51a2_ag",	dhd_conf_compat_vht},
+	{BCM43751_CHIP_ID,	BCM43752_CHIP_ID,	2,	0, 0,
+		"ap6398sr32",	"bcm4359c51a2_ag",	dhd_conf_compat_vht},
+	{BCM43751_CHIP_ID,	BCM43752_CHIP_ID,	2,	0, 0,
+		"ap6398sv",		"bcm4359c51a2_ag",	dhd_conf_compat_vht},
+	{BCM43751_CHIP_ID,	BCM43752_CHIP_ID,	2,	0, 0,
+		"ap6398sv3",	"bcm4359c51a2_ag",	dhd_conf_compat_vht},
+#endif
+#ifdef BCMPCIE
+	{BCM43751_D11AX_ID,	BCM43752_CHIP_ID,	2,	0x179F, 0x003C,
+		"ap6398p2",		"bcm4359c51a2_pcie_ag",	dhd_conf_compat_vht},
+	{BCM43751_D11AX_ID,	BCM43752_CHIP_ID,	2,	0x17F9, 0x003C,
+		"ap6398p2",		"bcm4359c51a2_pcie_ag",	dhd_conf_compat_vht},
+	{BCM43751_D11AX_ID,	BCM43752_CHIP_ID,	2,	0x17F9, 0x003D,
+		"ap6398pr32",	"bcm4359c51a2_pcie_ag",	dhd_conf_compat_vht},
+	{BCM43751_D11AX_ID,	BCM43752_CHIP_ID,	2,	0x17F9, 0x003E,
+		"ap6398pv",		"bcm4359c51a2_pcie_ag",	dhd_conf_compat_vht},
+	{BCM43751_D11AX_ID,	BCM43752_CHIP_ID,	2,	0x17F9, 0x003F,
+		"ap6398pv3",	"bcm4359c51a2_pcie_ag",	dhd_conf_compat_vht},
+#endif
+};
+#endif
+
+#ifdef DHD_TPUT_PATCH
+extern int dhd_change_mtu(dhd_pub_t *dhd, int new_mtu, int ifidx);
+#endif
+
+#ifdef WL_CFG80211
+bool
+dhd_conf_legacy_chip_check(dhd_pub_t *dhd)
+{
+	uint chip = dhd->conf->chip;
+
+	if (chip == BCM43430_CHIP_ID || chip == BCM4345_CHIP_ID ||
+			chip == BCM4359_CHIP_ID ||
+			chip == BCM43569_CHIP_ID) {
+		return true;
+	}
+
+	return false;
+}
+
+bool
+dhd_conf_new_chip_check(dhd_pub_t *dhd)
+{
+	uint chip = dhd->conf->chip;
+
+	if (chip == BCM43430_CHIP_ID || chip == BCM4345_CHIP_ID ||
+			chip == BCM43569_CHIP_ID) {
+		return false;
+	}
+
+	return true;
+}
+
+bool
+dhd_conf_extsae_chip(dhd_pub_t *dhd)
+{
+	uint chip = dhd->conf->chip;
+
+	if (chip == BCM43569_CHIP_ID) {
+		return false;
+	}
+
+	return true;
+}
+#endif
+
+#ifdef BCMSDIO
+static void
+dhd_conf_disable_slpauto(dhd_pub_t *dhd)
+{
+	uint chip = dhd->conf->chip;
+
+	if (chip == BCM43430_CHIP_ID || chip == BCM4345_CHIP_ID ||
+			chip == BCM4359_CHIP_ID) {
+		dhd_slpauto = FALSE;
+	}
+	CONFIG_MSG("dhd_slpauto = %d\n", dhd_slpauto);
+}
+#endif
+
+void
+dhd_conf_free_chip_nv_path_list(wl_chip_nv_path_list_ctrl_t *chip_nv_list)
+{
+	CONFIG_TRACE("called\n");
+
+	if (chip_nv_list->m_chip_nv_path_head) {
+		CONFIG_TRACE("Free %p\n", chip_nv_list->m_chip_nv_path_head);
+		kfree(chip_nv_list->m_chip_nv_path_head);
+		chip_nv_list->m_chip_nv_path_head = NULL;
+	}
+	chip_nv_list->count = 0;
+}
+
+#if defined(BCMSDIO) || defined(BCMPCIE)
+typedef struct cis_tuple_format {
+	uint8	id;
+	uint8	len;	/* total length of tag and data */
+	uint8	tag;
+	uint8	data[1];
+} cis_tuple_format_t;
+#define SBSDIO_CIS_SIZE_LIMIT		0x200
+#define SBSDIO_TUPLE_SIZE_LIMIT		0xff
+#define CIS_TUPLE_ID_BRCM			0x80
+#define CIS_TUPLE_TAG_MACADDR		0x19
+#define CIS_TUPLE_ID_AMPAK			0x8e
+#define CIS_TUPLE_TAG_MODULE		0x41
+#define CIS_TUPLE_LENGTH		1
+#define CIS_TUPLE_HDR_LEN		2
+#endif
+
+#ifdef BCMSDIO
+void
+dhd_conf_get_otp(dhd_pub_t *dhd, bcmsdh_info_t *sdh, si_t *sih)
+{
+	int i, err = -1;
+	uint8 *cis, *ptr = 0;
+	uint8 mac_header[3] = {0x80, 0x07, 0x19};
+	cis_tuple_format_t *tuple;
+	int totlen, len;
+
+	if (!(cis = MALLOC(dhd->osh, SBSDIO_CIS_SIZE_LIMIT))) {
+		CONFIG_ERROR("cis malloc failed\n");
+	}
+	bzero(cis, SBSDIO_CIS_SIZE_LIMIT);
+
+	if ((err = bcmsdh_cis_read(sdh, 0, cis, SBSDIO_CIS_SIZE_LIMIT))) {
+		CONFIG_ERROR("cis read err %d\n", err);
+		MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT);
+		return;
+	}
+	tuple = (cis_tuple_format_t *)cis;
+	totlen = SBSDIO_CIS_SIZE_LIMIT;
+	if (config_msg_level & CONFIG_TRACE_LEVEL) {
+		prhex("CIS", &tuple->id, totlen);
+	}
+	while (totlen >= (tuple->len + CIS_TUPLE_HDR_LEN)) {
+		len = tuple->len;
+		if ((config_msg_level & CONFIG_TRACE_LEVEL) && tuple->id) {
+			prhex("TPL", &tuple->id, tuple->len + CIS_TUPLE_HDR_LEN);
+		}
+		if (tuple->id == 0xff || tuple->len == 0xff)
+			break;
+		if ((tuple->id == CIS_TUPLE_ID_BRCM) &&
+				(tuple->tag == CIS_TUPLE_TAG_MACADDR) &&
+				(totlen >= (int)(len + CIS_TUPLE_HDR_LEN))) {
+			memcpy(&dhd->conf->otp_mac, tuple->data, ETHER_ADDR_LEN);
+		}
+#ifdef GET_OTP_MODULE_NAME
+		else if (tuple->id == CIS_TUPLE_ID_AMPAK && (tuple->len) &&
+				tuple->tag == CIS_TUPLE_TAG_MODULE) {
+			int len = tuple->len - 1;
+			if (len <= sizeof(dhd->conf->module_name) - 1) {
+				strncpy(dhd->conf->module_name, tuple->data, len);
+				CONFIG_MSG("module_name=%s\n", dhd->conf->module_name);
+			} else {
+				CONFIG_ERROR("len is too long %d >= %d\n",
+					len, (int)sizeof(dhd->conf->module_name) - 1);
+			}
+		}
+#endif
+		tuple = (cis_tuple_format_t*)((uint8*)tuple + (len + CIS_TUPLE_HDR_LEN));
+		totlen -= (len + CIS_TUPLE_HDR_LEN);
+	}
+
+	if (!memcmp(&ether_null, &dhd->conf->otp_mac, ETHER_ADDR_LEN)) {
+		ptr = cis;
+		/* Special OTP */
+		if (bcmsdh_reg_read(sdh, SI_ENUM_BASE(sih), 4) == 0x16044330) {
+			for (i=0; i<SBSDIO_CIS_SIZE_LIMIT; i++) {
+				if (!memcmp(mac_header, ptr, 3)) {
+					memcpy(&dhd->conf->otp_mac, ptr+3, ETHER_ADDR_LEN);
+					break;
+				}
+				ptr++;
+			}
+		}
+	}
+
+	ASSERT(cis);
+	MFREE(dhd->osh, cis, SBSDIO_CIS_SIZE_LIMIT);
+}
+
+#ifdef SET_FWNV_BY_MAC
+void
+dhd_conf_free_mac_list(wl_mac_list_ctrl_t *mac_list)
+{
+	int i;
+
+	CONFIG_TRACE("called\n");
+	if (mac_list->m_mac_list_head) {
+		for (i=0; i<mac_list->count; i++) {
+			if (mac_list->m_mac_list_head[i].mac) {
+				CONFIG_TRACE("Free mac %p\n", mac_list->m_mac_list_head[i].mac);
+				kfree(mac_list->m_mac_list_head[i].mac);
+			}
+		}
+		CONFIG_TRACE("Free m_mac_list_head %p\n", mac_list->m_mac_list_head);
+		kfree(mac_list->m_mac_list_head);
+	}
+	mac_list->count = 0;
+}
+
+void
+dhd_conf_set_fw_name_by_mac(dhd_pub_t *dhd, char *fw_path)
+{
+	int i, j;
+	uint8 *mac = (uint8 *)&dhd->conf->otp_mac;
+	int fw_num=0, mac_num=0;
+	uint32 oui, nic;
+	wl_mac_list_t *mac_list;
+	wl_mac_range_t *mac_range;
+	int fw_type, fw_type_new;
+	char *name_ptr;
+
+	mac_list = dhd->conf->fw_by_mac.m_mac_list_head;
+	fw_num = dhd->conf->fw_by_mac.count;
+	if (!mac_list || !fw_num)
+		return;
+
+	oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]);
+	nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]);
+
+	/* find out the last '/' */
+	i = strlen(fw_path);
+	while (i > 0) {
+		if (fw_path[i] == '/') {
+			i++;
+			break;
+		}
+		i--;
+	}
+	name_ptr = &fw_path[i];
+
+	if (strstr(name_ptr, "_apsta"))
+		fw_type = FW_TYPE_APSTA;
+	else if (strstr(name_ptr, "_p2p"))
+		fw_type = FW_TYPE_P2P;
+	else if (strstr(name_ptr, "_mesh"))
+		fw_type = FW_TYPE_MESH;
+	else if (strstr(name_ptr, "_ezmesh"))
+		fw_type = FW_TYPE_EZMESH;
+	else if (strstr(name_ptr, "_es"))
+		fw_type = FW_TYPE_ES;
+	else if (strstr(name_ptr, "_mfg"))
+		fw_type = FW_TYPE_MFG;
+	else
+		fw_type = FW_TYPE_STA;
+
+	for (i=0; i<fw_num; i++) {
+		mac_num = mac_list[i].count;
+		mac_range = mac_list[i].mac;
+		if (strstr(mac_list[i].name, "_apsta"))
+			fw_type_new = FW_TYPE_APSTA;
+		else if (strstr(mac_list[i].name, "_p2p"))
+			fw_type_new = FW_TYPE_P2P;
+		else if (strstr(mac_list[i].name, "_mesh"))
+			fw_type_new = FW_TYPE_MESH;
+		else if (strstr(mac_list[i].name, "_ezmesh"))
+			fw_type_new = FW_TYPE_EZMESH;
+		else if (strstr(mac_list[i].name, "_es"))
+			fw_type_new = FW_TYPE_ES;
+		else if (strstr(mac_list[i].name, "_mfg"))
+			fw_type_new = FW_TYPE_MFG;
+		else
+			fw_type_new = FW_TYPE_STA;
+		if (fw_type != fw_type_new) {
+			CONFIG_MSG("fw_typ=%d != fw_type_new=%d\n", fw_type, fw_type_new);
+			continue;
+		}
+		for (j=0; j<mac_num; j++) {
+			if (oui == mac_range[j].oui) {
+				if (nic >= mac_range[j].nic_start && nic <= mac_range[j].nic_end) {
+					strcpy(name_ptr, mac_list[i].name);
+					CONFIG_MSG("matched oui=0x%06X, nic=0x%06X\n", oui, nic);
+					CONFIG_MSG("fw_path=%s\n", fw_path);
+					return;
+				}
+			}
+		}
+	}
+}
+
+void
+dhd_conf_set_nv_name_by_mac(dhd_pub_t *dhd, char *nv_path)
+{
+	int i, j;
+	uint8 *mac = (uint8 *)&dhd->conf->otp_mac;
+	int nv_num=0, mac_num=0;
+	uint32 oui, nic;
+	wl_mac_list_t *mac_list;
+	wl_mac_range_t *mac_range;
+	char *pnv_name;
+
+	mac_list = dhd->conf->nv_by_mac.m_mac_list_head;
+	nv_num = dhd->conf->nv_by_mac.count;
+	if (!mac_list || !nv_num)
+		return;
+
+	oui = (mac[0] << 16) | (mac[1] << 8) | (mac[2]);
+	nic = (mac[3] << 16) | (mac[4] << 8) | (mac[5]);
+
+	/* find out the last '/' */
+	i = strlen(nv_path);
+	while (i > 0) {
+		if (nv_path[i] == '/') break;
+		i--;
+	}
+	pnv_name = &nv_path[i+1];
+
+	for (i=0; i<nv_num; i++) {
+		mac_num = mac_list[i].count;
+		mac_range = mac_list[i].mac;
+		for (j=0; j<mac_num; j++) {
+			if (oui == mac_range[j].oui) {
+				if (nic >= mac_range[j].nic_start && nic <= mac_range[j].nic_end) {
+					strcpy(pnv_name, mac_list[i].name);
+					CONFIG_MSG("matched oui=0x%06X, nic=0x%06X\n", oui, nic);
+					CONFIG_MSG("nv_path=%s\n", nv_path);
+					return;
+				}
+			}
+		}
+	}
+}
+#endif
+
+bool
+dhd_conf_legacy_otp_chip(dhd_pub_t *dhd)
+{
+	uint chip;
+
+	chip = dhd->conf->chip;
+
+	if (chip == BCM43430_CHIP_ID || chip == BCM4345_CHIP_ID ||
+			chip == BCM4359_CHIP_ID || chip == BCM43012_CHIP_ID ||
+			chip == BCM43752_CHIP_ID ||
+			chip == BCM43756_CHIP_ID || chip == BCM43711_CHIP_ID) {
+		return true;
+	}
+
+	return false;
+}
+#endif
+
+#ifdef BCMPCIE
+bool
+dhd_conf_legacy_msi_chip(dhd_pub_t *dhd)
+{
+	uint chip;
+
+	chip = dhd->conf->chip;
+
+	if (chip == BCM4359_CHIP_ID) {
+		return true;
+	}
+
+	return false;
+}
+
+#if defined(BCMPCIE_CTO_PREVENTION)
+bool
+dhd_conf_legacy_cto_chip(uint16 chip)
+{
+	// enable CTO for new chip(4381 and 4382) to prevent unnecessary interrupt
+	if (chip == BCM4359_CHIP_ID ||
+			chip == BCM43752_CHIP_ID || chip == BCM4375_CHIP_ID ||
+			chip == BCM43756_CHIP_ID || chip == BCM43711_CHIP_ID) {
+		return true;
+	}
+
+	return false;
+}
+#endif
+#endif
+
+void
+dhd_conf_free_country_list(struct dhd_conf *conf)
+{
+	country_list_t *country = conf->country_head;
+	int count = 0;
+
+	CONFIG_TRACE("called\n");
+	while (country) {
+		CONFIG_TRACE("Free cspec %s\n", country->cspec.country_abbrev);
+		conf->country_head = country->next;
+		kfree(country);
+		country = conf->country_head;
+		count++;
+	}
+	CONFIG_TRACE("%d country released\n", count);
+}
+
+void
+dhd_conf_free_mchan_list(struct dhd_conf *conf)
+{
+	mchan_params_t *mchan = conf->mchan;
+	int count = 0;
+
+	CONFIG_TRACE("called\n");
+	while (mchan) {
+		CONFIG_TRACE("Free cspec %p\n", mchan);
+		conf->mchan = mchan->next;
+		kfree(mchan);
+		mchan = conf->mchan;
+		count++;
+	}
+	CONFIG_TRACE("%d mchan released\n", count);
+}
+
+const chip_name_map_t*
+dhd_conf_match_chip(dhd_pub_t *dhd)
+{
+	uint chip, chiprev;
+	int i;
+
+	chip = dhd->conf->chip;
+	chiprev = dhd->conf->chiprev;
+
+	for (i=0; i<sizeof(chip_name_map)/sizeof(chip_name_map[0]); i++) {
+		const chip_name_map_t *row = &chip_name_map[i];
+		if (row->chip == chip && row->chiprev == chiprev) {
+			return row;
+		}
+	}
+
+	return NULL;
+}
+
+const chip_name_map_v2_t*
+dhd_conf_match_chip_v2(dhd_pub_t *dhd)
+{
+	uint chip, chiprev;
+	int i;
+
+	chip = dhd->conf->chip;
+	chiprev = dhd->conf->chiprev;
+
+	for (i=0; i<sizeof(chip_name_map_v2)/sizeof(chip_name_map_v2[0]); i++) {
+		const chip_name_map_v2_t *row = &chip_name_map_v2[i];
+		if (row->chip == chip && row->chiprev == chiprev) {
+			return row;
+		}
+	}
+
+	return NULL;
+}
+
+const module_name_map_v2_t*
+dhd_conf_match_module_v2(dhd_pub_t *dhd)
+{
+	uint chip, chiprev;
+	int i;
+
+	chip = dhd->conf->chip;
+	chiprev = dhd->conf->chiprev;
+
+	for (i=0; i<sizeof(module_name_map_v2)/sizeof(module_name_map_v2[0]); i++) {
+		const module_name_map_v2_t *row = &module_name_map_v2[i];
+		if (row->chip == chip && row->chiprev == chiprev) {
+			return row;
+		}
+	}
+
+	return NULL;
+}
+
+#ifdef UPDATE_MODULE_NAME
+const module_name_map_t*
+dhd_conf_match_module(dhd_pub_t *dhd)
+{
+#ifdef BCMPCIE
+	uint svid, ssid;
+#endif
+#if defined(BCMSDIO) || defined(BCMPCIE)
+	uint devid, chip, chiprev;
+	int i;
+#endif
+
+#if defined(BCMSDIO) || defined(BCMPCIE)
+	devid = dhd->conf->devid;
+	chip = dhd->conf->chip;
+	chiprev = dhd->conf->chiprev;
+#endif
+#ifdef BCMPCIE
+	svid = dhd->conf->svid;
+	ssid = dhd->conf->ssid;
+#endif
+
+#ifdef BCMSDIO
+	for (i=0; i<sizeof(module_name_map)/sizeof(module_name_map[0]); i++) {
+		const module_name_map_t *row = &module_name_map[i];
+		if (row->devid == devid && row->chip == chip && row->chiprev == chiprev &&
+				!strcmp(row->module_name, dhd->conf->module_name)) {
+			return row;
+		}
+	}
+#endif
+
+#ifdef BCMPCIE
+	for (i=0; i<sizeof(module_name_map)/sizeof(module_name_map[0]); i++) {
+		const module_name_map_t *row = &module_name_map[i];
+		if (row->devid == devid && row->chip == chip && row->chiprev == chiprev &&
+				row->svid == svid && row->ssid == ssid) {
+			return row;
+		}
+	}
+#endif
+
+	return NULL;
+}
+#endif
+
+char *
+dhd_conf_get_chip_name(dhd_pub_t *dhd, bool *chip_map_v2)
+{
+#ifdef UPDATE_MODULE_NAME
+	const module_name_map_t *row_module = NULL;
+#endif
+	const chip_name_map_t *row_chip = NULL;
+	const chip_name_map_v2_t *row_chip_v2 = NULL;
+	char *name = NULL;
+
+	*chip_map_v2 = FALSE;
+#ifdef UPDATE_MODULE_NAME
+	row_module = dhd_conf_match_module(dhd);
+	if (row_module && strlen(row_module->chip_name)) {
+		name = row_module->chip_name;
+	} else
+#endif
+	{
+		row_chip = dhd_conf_match_chip(dhd);
+		if (row_chip && strlen(row_chip->chip_name)) {
+			name = row_chip->chip_name;
+		}
+		else {
+			row_chip_v2 = dhd_conf_match_chip_v2(dhd);
+			if (row_chip_v2 && strlen(row_chip_v2->chip_name)) {
+				name = row_chip_v2->chip_name;
+				*chip_map_v2 = TRUE;
+			}
+		}
+	}
+
+	return name;
+}
+
+char *
+dhd_conf_get_module_name(dhd_pub_t *dhd)
+{
+#if defined(BCMPCIE) && defined(UPDATE_MODULE_NAME)
+	const module_name_map_t *row_module = NULL;
+#endif
+	const chip_name_map_t *row_chip = NULL;
+	const module_name_map_v2_t *row_module_v2 = NULL;
+	char *name = NULL;
+
+#if defined(BCMPCIE) && defined(UPDATE_MODULE_NAME)
+	row_module = dhd_conf_match_module(dhd);
+	if (row_module && strlen(row_module->module_name)) {
+		name = row_module->module_name;
+	} else
+#endif
+	{
+		row_chip = dhd_conf_match_chip(dhd);
+		if (row_chip && strlen(row_chip->module_name)) {
+			name = row_chip->module_name;
+		}
+		else {
+			row_module_v2 = dhd_conf_match_module_v2(dhd);
+			if (row_module_v2 && strlen(row_module_v2->module_name)) {
+				name = row_module_v2->module_name;
+			}
+		}
+	}
+
+	return name;
+}
+
+void
+dhd_conf_set_fw_name_by_chip(dhd_pub_t *dhd, char *fw_path)
+{
+	int fw_type;
+	char *name_ptr, *chip_name = NULL;
+	bool chip_map_v2;
+	int i;
+
+	if (fw_path[0] == '\0') {
+#ifdef CONFIG_BCMDHD_FW_PATH
+		bcm_strncpy_s(fw_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1);
+		if (fw_path[0] == '\0')
+#endif
+		{
+			CONFIG_MSG("firmware path is null\n");
+			return;
+		}
+	}
+#ifndef FW_PATH_AUTO_SELECT
+	return;
+#endif
+
+	/* find out the last '/' */
+	i = strlen(fw_path);
+	while (i > 0) {
+		if (fw_path[i] == '/') {
+			i++;
+			break;
+		}
+		i--;
+	}
+	name_ptr = &fw_path[i];
+	if (strstr(name_ptr, "_apsta"))
+		fw_type = FW_TYPE_APSTA;
+	else if (strstr(name_ptr, "_p2p"))
+		fw_type = FW_TYPE_P2P;
+	else if (strstr(name_ptr, "_mesh"))
+		fw_type = FW_TYPE_MESH;
+	else if (strstr(name_ptr, "_ezmesh"))
+		fw_type = FW_TYPE_EZMESH;
+	else if (strstr(name_ptr, "_es"))
+		fw_type = FW_TYPE_ES;
+	else if (strstr(name_ptr, "_mfg"))
+		fw_type = FW_TYPE_MFG;
+	else if (strstr(name_ptr, "_minime"))
+		fw_type = FW_TYPE_MINIME;
+	else
+		fw_type = FW_TYPE_STA;
+#ifdef WLEASYMESH
+	if (dhd->conf->fw_type == FW_TYPE_EZMESH)
+		fw_type = FW_TYPE_EZMESH;
+#endif /* WLEASYMESH */
+
+	chip_name = dhd_conf_get_chip_name(dhd, &chip_map_v2);
+	if (chip_name) {
+		strcpy(name_ptr, "fw_");
+		strcat(name_ptr, chip_name);
+		if (chip_map_v2) {
+#ifdef BCMSDIO
+			strcat(name_ptr, "_sdio");
+#endif
+#ifdef BCMPCIE
+			strcat(name_ptr, "_pcie");
+#endif
+#if defined(BCMDBUS) && !defined(BCMUSBDEV_COMPOSITE)
+			strcat(name_ptr, "_usb");
+#endif
+		}
+#ifdef BCMUSBDEV_COMPOSITE
+		strcat(name_ptr, "_cusb");
+#endif
+		if (fw_type == FW_TYPE_APSTA)
+			strcat(name_ptr, "_apsta.bin");
+		else if (fw_type == FW_TYPE_P2P)
+			strcat(name_ptr, "_p2p.bin");
+		else if (fw_type == FW_TYPE_MESH)
+			strcat(name_ptr, "_mesh.bin");
+		else if (fw_type == FW_TYPE_EZMESH)
+			strcat(name_ptr, "_ezmesh.bin");
+		else if (fw_type == FW_TYPE_ES)
+			strcat(name_ptr, "_es.bin");
+		else if (fw_type == FW_TYPE_MFG)
+			strcat(name_ptr, "_mfg.bin");
+		else if (fw_type == FW_TYPE_MINIME)
+			strcat(name_ptr, "_minime.bin");
+		else
+			strcat(name_ptr, ".bin");
+	}
+
+	dhd->conf->fw_type = fw_type;
+
+#ifndef MINIME
+	if (fw_type == FW_TYPE_MINIME)
+		CONFIG_ERROR("***** Please enable MINIME in Makefile *****\n");
+#endif
+
+	CONFIG_TRACE("firmware_path=%s\n", fw_path);
+}
+
+void
+dhd_conf_set_clm_name_by_chip(dhd_pub_t *dhd, char *clm_path)
+{
+	char *name_ptr, *chip_name = NULL;
+	bool chip_map_v2;
+	int i;
+
+	if (clm_path[0] == '\0') {
+		CONFIG_MSG("clm path is null\n");
+		return;
+	}
+#ifndef FW_PATH_AUTO_SELECT
+	return;
+#endif
+
+	/* find out the last '/' */
+	i = strlen(clm_path);
+	while (i > 0) {
+		if (clm_path[i] == '/') {
+			i++;
+			break;
+		}
+		i--;
+	}
+	name_ptr = &clm_path[i];
+
+	chip_name = dhd_conf_get_chip_name(dhd, &chip_map_v2);
+	if (chip_name) {
+		strcpy(name_ptr, "clm_");
+		strcat(name_ptr, chip_name);
+		strcat(name_ptr, ".blob");
+	}
+
+	CONFIG_TRACE("clm_path=%s\n", clm_path);
+}
+
+void
+dhd_conf_set_nv_name_by_chip(dhd_pub_t *dhd, char *nv_path)
+{
+	uint chip, chiprev;
+	char *name_ptr, *module_name = NULL, nv_name[32];
+	int i;
+
+	chip = dhd->conf->chip;
+	chiprev = dhd->conf->chiprev;
+
+	if (nv_path[0] == '\0') {
+#ifdef CONFIG_BCMDHD_NVRAM_PATH
+		bcm_strncpy_s(nv_path, MOD_PARAM_PATHLEN-1, CONFIG_BCMDHD_NVRAM_PATH, MOD_PARAM_PATHLEN-1);
+		if (nv_path[0] == '\0')
+#endif
+		{
+			CONFIG_MSG("nvram path is null\n");
+			return;
+		}
+	}
+
+	/* find out the last '/' */
+	i = strlen(nv_path);
+	while (i > 0) {
+		if (nv_path[i] == '/') {
+			i++;
+			break;
+		}
+		i--;
+	}
+	name_ptr = &nv_path[i];
+
+	module_name = dhd_conf_get_module_name(dhd);
+	if (module_name) {
+		strcpy(name_ptr, "nvram_");
+		strcat(name_ptr, module_name);
+#ifdef BCMUSBDEV_COMPOSITE
+		strcat(name_ptr, "_cusb");
+#endif
+		strcat(name_ptr, ".txt");
+	}
+	strcpy(nv_name, name_ptr);
+
+#if defined(BCMSDIO) && defined(GET_OTP_MODULE_NAME)
+	if (strlen(dhd->conf->module_name)) {
+		strcpy(name_ptr, "nvram_");
+		strcat(name_ptr, dhd->conf->module_name);
+		strcat(name_ptr, ".txt");
+#ifdef COMPAT_OLD_MODULE
+		if (dhd->conf->chip == BCM4359_CHIP_ID) {
+			// compatible for AP6398S and AP6398SA
+#ifdef DHD_LINUX_STD_FW_API
+			const struct firmware *nv = NULL;
+			int ret = BCME_ERROR;
+			ret = dhd_os_get_img_fwreq(&nv, nv_path);
+			if (ret < 0) {
+				strcpy(name_ptr, nv_name);
+			}
+			if (nv) {
+				dhd_os_close_img_fwreq(nv);
+			}
+#else
+			struct file *fp;
+			fp = dhd_filp_open(nv_path, O_RDONLY, 0);
+			if (IS_ERR(fp) || (fp == NULL)) {
+				strcpy(name_ptr, nv_name);
+			} else {
+				dhd_filp_close((struct file *)fp, NULL);
+			}
+#endif
+		}
+#endif
+	}
+#endif
+
+	for (i=0; i<dhd->conf->nv_by_chip.count; i++) {
+		if (chip==dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chip &&
+				chiprev==dhd->conf->nv_by_chip.m_chip_nv_path_head[i].chiprev) {
+			strcpy(name_ptr, dhd->conf->nv_by_chip.m_chip_nv_path_head[i].name);
+			break;
+		}
+	}
+
+	CONFIG_TRACE("nvram_path=%s\n", nv_path);
+}
+
+void
+dhd_conf_copy_path(dhd_pub_t *dhd, char *dst_name, char *dst_path, char *src_path)
+{
+	int i;
+
+	if (src_path[0] == '\0') {
+		CONFIG_MSG("src_path is null\n");
+		return;
+	} else
+		strcpy(dst_path, src_path);
+
+	/* find out the last '/' */
+	i = strlen(dst_path);
+	while (i > 0) {
+		if (dst_path[i] == '/') {
+			i++;
+			break;
+		}
+		i--;
+	}
+	strcpy(&dst_path[i], dst_name);
+
+	CONFIG_TRACE("dst_path=%s\n", dst_path);
+}
+
+#ifdef CONFIG_PATH_AUTO_SELECT
+void
+dhd_conf_set_conf_name_by_chip(dhd_pub_t *dhd, char *conf_path)
+{
+	char *name_ptr, *chip_name = NULL;
+	bool chip_map_v2;
+	int i;
+
+	if (conf_path[0] == '\0') {
+		CONFIG_MSG("config path is null\n");
+		return;
+	}
+
+	/* find out the last '/' */
+	i = strlen(conf_path);
+	while (i > 0) {
+		if (conf_path[i] == '/') {
+			i++;
+			break;
+		}
+		i--;
+	}
+	name_ptr = &conf_path[i];
+
+	chip_name = dhd_conf_get_chip_name(dhd, &chip_map_v2);
+	if (chip_name) {
+		strcpy(name_ptr, "config_");
+		strcat(name_ptr, chip_name);
+		strcat(name_ptr, ".txt");
+	}
+
+	CONFIG_TRACE("config_path=%s\n", conf_path);
+}
+#endif
+
+#ifdef DHD_TPUT_PATCH
+void
+dhd_conf_set_tput_patch(dhd_pub_t *dhd)
+{
+	struct dhd_conf *conf = dhd->conf;
+
+	if (conf->tput_patch) {
+		conf->mtu = 1500;
+/* set pktsetsum false by default since this will cause to
+  * the checksum is wrong of downloaded file
+*/
+		conf->pktsetsum = FALSE;
+#ifdef BCMSDIO
+		conf->dhd_dpc_prio = 98;
+/* need to check if CPU can support multi-core first,
+ * so don't enable it by default.
+ */
+//		conf->dpc_cpucore = 2;
+//		conf->rxf_cpucore = 3;
+//		conf->disable_proptx = 1;
+		conf->frameburst = 1;
+#ifdef DYNAMIC_MAX_HDR_READ
+		conf->max_hdr_read = 256;
+		firstread = 256;
+#endif /* DYNAMIC_MAX_HDR_READ */
+		dhd_rxbound = 512;
+#endif /* BCMSDIO */
+#ifdef BCMPCIE
+#if defined(SET_XPS_CPUS)
+		conf->xps_cpus = TRUE;
+#endif /* SET_XPS_CPUS */
+#if defined(SET_RPS_CPUS)
+		conf->rps_cpus = TRUE;
+#endif /* SET_RPS_CPUS */
+		conf->flow_ring_queue_threshold = 2048;
+#endif /* BCMPCIE */
+#ifdef DHDTCPACK_SUPPRESS
+		conf->tcpack_sup_ratio = 15;
+		conf->tcpack_sup_delay = 10;
+#endif /* DHDTCPACK_SUPPRESS */
+	}
+	else {
+		conf->mtu = 0;
+		conf->pktsetsum = FALSE;
+#ifdef BCMSDIO
+		conf->dhd_dpc_prio = -1;
+		conf->disable_proptx = -1;
+		conf->frameburst = 1;
+#ifdef DYNAMIC_MAX_HDR_READ
+		conf->max_hdr_read = 0;
+		firstread = 32;
+#endif /* DYNAMIC_MAX_HDR_READ */
+		dhd_rxbound = 128;
+#endif /* BCMSDIO */
+#ifdef BCMPCIE
+#if defined(SET_XPS_CPUS)
+		conf->xps_cpus = FALSE;
+#endif /* SET_XPS_CPUS */
+#if defined(SET_RPS_CPUS)
+		conf->rps_cpus = FALSE;
+#endif /* SET_RPS_CPUS */
+		conf->flow_ring_queue_threshold = 2048;
+#endif /* BCMPCIE */
+#ifdef DHDTCPACK_SUPPRESS
+		conf->tcpack_sup_ratio = CUSTOM_TCPACK_SUPP_RATIO;
+		conf->tcpack_sup_delay = CUSTOM_TCPACK_DELAY_TIME;
+#endif /* DHDTCPACK_SUPPRESS */
+	}
+}
+
+void
+dhd_conf_dump_tput_patch(dhd_pub_t *dhd)
+{
+	struct dhd_conf *conf = dhd->conf;
+
+	CONFIG_TRACE("tput_patch=%d\n", conf->tput_patch);
+	CONFIG_TRACE("mtu=%d\n", conf->mtu);
+	CONFIG_TRACE("pktsetsum=%d\n", conf->pktsetsum);
+#ifdef DHDTCPACK_SUPPRESS
+	CONFIG_TRACE("tcpack_sup_ratio=%d\n", conf->tcpack_sup_ratio);
+	CONFIG_TRACE("tcpack_sup_delay=%d\n", conf->tcpack_sup_delay);
+#endif
+
+#ifdef BCMSDIO
+	CONFIG_TRACE("dhd_dpc_prio=%d\n", conf->dhd_dpc_prio);
+	CONFIG_TRACE("dhd_poll=%d\n", conf->dhd_poll);
+	CONFIG_TRACE("disable_proptx=%d\n", conf->disable_proptx);
+	CONFIG_TRACE("frameburst=%d\n", conf->frameburst);
+#ifdef DYNAMIC_MAX_HDR_READ
+	CONFIG_TRACE("max_hdr_read=%d\n", conf->max_hdr_read);
+	CONFIG_TRACE("firstread=%d\n", firstread);
+#endif
+	CONFIG_TRACE("dhd_rxbound=%d\n", dhd_rxbound);
+#endif
+
+#ifdef BCMPCIE
+	CONFIG_TRACE("flow_ring_queue_threshold=%d\n", conf->flow_ring_queue_threshold);
+#endif
+
+#if defined(SET_XPS_CPUS)
+	CONFIG_TRACE("xps_cpus=%d\n", conf->xps_cpus);
+#endif
+#if defined(SET_RPS_CPUS)
+	CONFIG_TRACE("rps_cpus=%d\n", conf->rps_cpus);
+#endif
+
+}
+#endif /* DHD_TPUT_PATCH */
+
+#ifdef DHD_REQUEST_FW_PATH
+#define FIRMWARE_CLASS_PATH "/sys/module/firmware_class/parameters/path"
+static void
+dhd_conf_get_filename(char *pFilename)
+{
+	const char *pName = NULL;
+
+	if ((pFilename) && (*pFilename)) {
+		// back/reverse search the '/'
+		pName = strrchr(pFilename, '/');
+		if (NULL == pName) {
+			pName = pFilename;
+		} else {
+			if (pName[1]) {
+				pName++;
+			} else {
+				pName = NULL;
+			}
+		}
+	}
+
+	if (pName)
+		strcpy(pFilename, pName);
+
+	return;
+}
+
+static void
+dhd_conf_add_filepath(dhd_pub_t *dhd, char *pFilename)
+{
+	char path[WLC_IOCTL_SMLEN];
+	char *name_ptr, *module_name = NULL;
+
+	if (strlen(pFilename)) {
+		name_ptr = path;
+		strcpy(name_ptr, "");
+#ifdef FW_AMPAK_PATH
+		strcat(name_ptr, "/");
+		strcat(name_ptr, FW_AMPAK_PATH);
+#endif
+#ifdef MODULE_PATH
+		module_name = dhd_conf_get_module_name(dhd);
+#endif
+		if (module_name) {
+			strcat(name_ptr, "/");
+			strcat(name_ptr, module_name);
+		}
+		strcat(name_ptr, "/");
+		strcat(name_ptr, pFilename);
+		strcpy(pFilename, path);
+	}
+
+	return;
+}
+#endif /* DHD_REQUEST_FW_PATH */
+
+void
+dhd_conf_set_path_params(dhd_pub_t *dhd, char *fw_path, char *nv_path)
+{
+	/* External conf takes precedence if specified */
+	dhd_conf_preinit(dhd);
+
+#ifdef DHD_REQUEST_FW_PATH
+	// preprocess the filename to only left 'name'
+	dhd_conf_get_filename(fw_path);
+	dhd_conf_get_filename(nv_path);
+	dhd_conf_get_filename(dhd->clm_path);
+	dhd_conf_get_filename(dhd->conf_path);
+#endif
+
+	if (dhd->conf_path[0] == '\0') {
+		dhd_conf_copy_path(dhd, "config.txt", dhd->conf_path, nv_path);
+	}
+	if (dhd->clm_path[0] == '\0') {
+		dhd_conf_copy_path(dhd, "clm.blob", dhd->clm_path, fw_path);
+	}
+#ifdef CONFIG_PATH_AUTO_SELECT
+	dhd_conf_set_conf_name_by_chip(dhd, dhd->conf_path);
+#endif
+
+	dhd_conf_set_fw_name_by_chip(dhd, fw_path);
+	dhd_conf_set_nv_name_by_chip(dhd, nv_path);
+	dhd_conf_set_clm_name_by_chip(dhd, dhd->clm_path);
+#ifdef SET_FWNV_BY_MAC
+	dhd_conf_set_fw_name_by_mac(dhd, fw_path);
+	dhd_conf_set_nv_name_by_mac(dhd, nv_path);
+#endif
+
+#ifdef DHD_REQUEST_FW_PATH
+	dhd_conf_add_filepath(dhd, fw_path);
+	dhd_conf_add_filepath(dhd, nv_path);
+	dhd_conf_add_filepath(dhd, dhd->clm_path);
+	dhd_conf_add_filepath(dhd, dhd->conf_path);
+#endif
+
+	CONFIG_MSG("Final fw_path=%s\n", fw_path);
+	CONFIG_MSG("Final nv_path=%s\n", nv_path);
+	CONFIG_MSG("Final clm_path=%s\n", dhd->clm_path);
+	CONFIG_MSG("Final conf_path=%s\n", dhd->conf_path);
+
+	dhd_conf_read_config(dhd, dhd->conf_path);
+#ifdef DHD_TPUT_PATCH
+	dhd_conf_dump_tput_patch(dhd);
+#endif
+}
+
+int
+dhd_conf_set_intiovar(dhd_pub_t *dhd, int ifidx, uint cmd, char *name, int val,
+	int def, bool down)
+{
+	int ret = -1;
+	char iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" + '\0' + bitvec  */
+
+	if (val >= def) {
+		if (down) {
+			if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, ifidx)) < 0)
+				CONFIG_ERROR("WLC_DOWN setting failed %d\n", ret);
+		}
+		if (cmd == WLC_SET_VAR) {
+			CONFIG_TRACE("set %s %d\n", name, val);
+			bcm_mkiovar(name, (char *)&val, sizeof(val), iovbuf, sizeof(iovbuf));
+			if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, ifidx)) < 0)
+				CONFIG_ERROR("%s setting failed %d\n", name, ret);
+		} else {
+			CONFIG_TRACE("set %s %d %d\n", name, cmd, val);
+			if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, &val, sizeof(val), TRUE, ifidx)) < 0)
+				CONFIG_ERROR("%s setting failed %d\n", name, ret);
+		}
+	}
+
+	return ret;
+}
+
+static int
+dhd_conf_set_bufiovar(dhd_pub_t *dhd, int ifidx, uint cmd, char *name,
+	char *buf, int len, bool down)
+{
+	char iovbuf[WLC_IOCTL_SMLEN];
+	s32 iovar_len;
+	int ret = -1;
+
+	if (down) {
+		if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, NULL, 0, TRUE, ifidx)) < 0)
+			CONFIG_ERROR("WLC_DOWN setting failed %d\n", ret);
+	}
+
+	if (cmd == WLC_SET_VAR) {
+		iovar_len = bcm_mkiovar(name, buf, len, iovbuf, sizeof(iovbuf));
+		if (iovar_len > 0)
+			ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, iovar_len, TRUE, ifidx);
+		else
+			ret = BCME_BUFTOOSHORT;
+		if (ret < 0)
+			CONFIG_ERROR("%s setting failed %d, len=%d\n", name, ret, len);
+	} else {
+		if ((ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, TRUE, ifidx)) < 0)
+			CONFIG_ERROR("%s setting failed %d\n", name, ret);
+	}
+
+	return ret;
+}
+
+static int
+dhd_conf_iovar_buf(dhd_pub_t *dhd, int ifidx, int cmd, char *name,
+	char *buf, int len)
+{
+	char *iovbuf = NULL;
+	int ret = -1, iovbuf_len = WLC_IOCTL_MEDLEN;
+	s32 iovar_len;
+
+	iovbuf = kmalloc(iovbuf_len, GFP_KERNEL);
+	if (iovbuf == NULL) {
+		CONFIG_ERROR("Failed to allocate buffer of %d bytes\n", iovbuf_len);
+		goto exit;
+	}
+
+	if (cmd == WLC_GET_VAR) {
+		if (bcm_mkiovar(name, buf, len, iovbuf, iovbuf_len)) {
+			ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, iovbuf_len, FALSE, ifidx);
+			if (!ret) {
+				memcpy(buf, iovbuf, len);
+			} else {
+				CONFIG_ERROR("get iovar %s failed %d\n", name, ret);
+			}
+		} else {
+			CONFIG_ERROR("mkiovar %s failed\n", name);
+		}
+	} else if (cmd == WLC_SET_VAR) {
+		iovar_len = bcm_mkiovar(name, buf, len, iovbuf, iovbuf_len);
+		if (iovar_len > 0)
+			ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, iovar_len, TRUE, ifidx);
+		else
+			ret = BCME_BUFTOOSHORT;
+		if (ret < 0)
+			CONFIG_ERROR("%s setting failed %d, len=%d\n", name, ret, len);
+	}
+
+exit:
+	if (iovbuf)
+		kfree(iovbuf);
+	return ret;
+}
+
+static int
+dhd_conf_get_iovar(dhd_pub_t *dhd, int ifidx, int cmd, char *name,
+	char *buf, int len)
+{
+	char iovbuf[WLC_IOCTL_SMLEN];
+	int ret = -1;
+
+	if (cmd == WLC_GET_VAR) {
+		if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) {
+			ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), FALSE, ifidx);
+			if (!ret) {
+				memcpy(buf, iovbuf, len);
+			} else {
+				CONFIG_ERROR("get iovar %s failed %d\n", name, ret);
+			}
+		} else {
+			CONFIG_ERROR("mkiovar %s failed\n", name);
+		}
+	} else {
+		ret = dhd_wl_ioctl_cmd(dhd, cmd, buf, len, FALSE, 0);
+		if (ret < 0)
+			CONFIG_ERROR("get iovar %s failed %d\n", name, ret);
+	}
+
+	return ret;
+}
+
+static int
+dhd_conf_intiovar(dhd_pub_t *dhd, int ifidx, uint cmd, char *name,
+	char *buf, int len)
+{
+	char iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" + '\0' + bitvec  */
+	int ret = -1, val;
+
+	if (cmd == WLC_SET_VAR) {
+		memcpy(&val, buf, len);
+		CONFIG_TRACE("set %s %d\n", name, val);
+		bcm_mkiovar(name, (char *)&val, sizeof(val), iovbuf, sizeof(iovbuf));
+		ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, ifidx);
+	}
+	else if (cmd == WLC_GET_VAR) {
+		if (bcm_mkiovar(name, NULL, 0, iovbuf, sizeof(iovbuf))) {
+			ret = dhd_wl_ioctl_cmd(dhd, cmd, iovbuf, sizeof(iovbuf), FALSE, ifidx);
+			if (!ret) {
+				memcpy(buf, iovbuf, len);
+				CONFIG_TRACE("get %s %d\n", name, *(int *)buf);
+			}
+		} else {
+			CONFIG_ERROR("mkiovar %s failed\n", name);
+		}
+	}
+
+	return ret;
+}
+
+static int
+dhd_conf_get_ioctl_ver(dhd_pub_t *dhd)
+{
+	int ret = 0;
+	s32 val = 0;
+
+	dhd->conf->ioctl_ver = WLC_IOCTL_VERSION;
+	ret = dhd_conf_get_iovar(dhd, 0, WLC_GET_VERSION, "WLC_GET_VERSION",
+		(char *)&val, sizeof(val));
+	if (ret) {
+		return ret;
+	}
+	val = dtoh32(val);
+	if (val != WLC_IOCTL_VERSION && val != 1) {
+		CONFIG_ERROR("Version mismatch, please upgrade. Got %d, expected %d or 1\n",
+			val, WLC_IOCTL_VERSION);
+		return BCME_VERSION;
+	}
+	dhd->conf->ioctl_ver = val;
+	CONFIG_TRACE("ioctl_ver=%d\n", dhd->conf->ioctl_ver);
+
+	return ret;
+}
+
+int
+dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec)
+{
+	int bcmerror = -1;
+
+	memset(cspec, 0, sizeof(wl_country_t));
+	bcm_mkiovar("country", NULL, 0, (char*)cspec, sizeof(wl_country_t));
+	if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cspec, sizeof(wl_country_t),
+			FALSE, 0)) < 0)
+		CONFIG_ERROR("country code getting failed %d\n", bcmerror);
+
+	return bcmerror;
+}
+
+static int
+dhd_conf_check_ccode_all(dhd_pub_t *dhd)
+{
+	int ret = -1;
+	wl_channels_in_country_t *cic;
+
+	cic = kmalloc(WLC_IOCTL_SMLEN, GFP_KERNEL);
+	if (!cic) {
+		CONFIG_ERROR("kmalloc failed for cic\n");
+		goto exit;
+	}
+	memset(cic, 0, WLC_IOCTL_SMLEN);
+	cic->buflen = WLC_IOCTL_SMLEN;
+	cic->count = 0;
+	strcpy(cic->country_abbrev, dhd->conf->ccode_all.cspec.ccode);
+	cic->band = WLC_BAND_2G;
+	cic->buflen = htod32(cic->buflen);
+	cic->band = htod32(cic->band);
+	cic->count = htod32(cic->count);
+	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_CHANNELS_IN_COUNTRY, (char *)cic,
+		WLC_IOCTL_SMLEN, FALSE, 0);
+exit:
+	if (ret)
+		memset(&dhd->conf->ccode_all, 0, sizeof(wl_ccode_all_t));
+	if (cic)
+		kfree(cic);
+
+	return ret;
+}
+
+static int
+dhd_conf_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec)
+{
+	int ret = -1;
+	struct dhd_conf *conf = dhd->conf;
+	country_list_t *country = conf->country_head;
+
+#ifdef CCODE_LIST
+	if (strlen(dhd->conf->ccode_all.cspec.ccode)) {
+		ret = dhd_ccode_map_country_all(dhd, cspec);
+	}
+	if (ret)
+		ret = dhd_ccode_map_country_list(dhd, cspec);
+#endif
+	while (country != NULL) {
+		if (!strncmp("**", country->cspec.country_abbrev, 2)) {
+			if (!strncmp("**", country->cspec.ccode, 2)) {
+				// **:**/0 => return user specified ccode if not found, but set regrev 0
+				cspec->rev = 0;
+				ret = 0;
+				break;
+			}
+			// **:XZ/11 => return XZ/11 if not found
+			memcpy(cspec->ccode, country->cspec.ccode, WLC_CNTRY_BUF_SZ);
+			cspec->rev = country->cspec.rev;
+			ret = 0;
+			break;
+		} else if (!strncmp(cspec->country_abbrev,
+				country->cspec.country_abbrev, 2)) {
+			memcpy(cspec->ccode, country->cspec.ccode, WLC_CNTRY_BUF_SZ);
+			cspec->rev = country->cspec.rev;
+			ret = 0;
+			break;
+		}
+		country = country->next;
+	}
+
+	return ret;
+}
+
+static int
+dhd_conf_set_country(dhd_pub_t *dhd, wl_country_t *cspec, bool no_ccode_evt)
+{
+	int bcmerror = -1;
+	struct net_device *net;
+	int bytes_written = 0;
+	char event_msg[32];
+
+	memset(&dhd->dhd_cspec, 0, sizeof(wl_country_t));
+
+	if (no_ccode_evt) {
+		net = dhd_idx2net(dhd, 0);
+		snprintf(event_msg, sizeof(event_msg), "wl event_msg %d 0", WLC_E_COUNTRY_CODE_CHANGED);
+		wl_android_ext_priv_cmd(net, event_msg, 0, &bytes_written);
+	}
+
+	CONFIG_MSG("set country %s, revision %d\n", cspec->ccode, cspec->rev);
+	bcmerror = dhd_conf_set_bufiovar(dhd, 0, WLC_SET_VAR, "country", (char *)cspec,
+		sizeof(wl_country_t), FALSE);
+	dhd_conf_get_country(dhd, cspec);
+	CONFIG_MSG("Country code: %s (%s/%d)\n",
+		cspec->country_abbrev, cspec->ccode, cspec->rev);
+
+	if (no_ccode_evt) {
+		snprintf(event_msg, sizeof(event_msg), "wl event_msg %d 1", WLC_E_COUNTRY_CODE_CHANGED);
+		wl_android_ext_priv_cmd(net, event_msg, 0, &bytes_written);
+	}
+
+	return bcmerror;
+}
+
+static int
+dhd_conf_rsdb_mode(dhd_pub_t *dhd, char *cmd, char *buf)
+{
+	wl_config_t rsdb_mode_cfg = {1, 0};
+
+	if (buf) {
+		rsdb_mode_cfg.config = (int)simple_strtol(buf, NULL, 0);
+		CONFIG_MSG("rsdb_mode %d\n", rsdb_mode_cfg.config);
+		dhd_conf_set_bufiovar(dhd, 0, WLC_SET_VAR, cmd, (char *)&rsdb_mode_cfg,
+			sizeof(rsdb_mode_cfg), TRUE);
+	}
+
+	return 0;
+}
+
+int
+dhd_conf_reg2args(dhd_pub_t *dhd, char *cmd, bool set, uint32 index, uint32 *val)
+{
+	char var[WLC_IOCTL_SMLEN];
+	uint32 int_val, len;
+	void *ptr = NULL;
+	int ret = 0;
+
+	len = sizeof(int_val);
+	int_val = htod32(index);
+	memset(var, 0, sizeof(var));
+	memcpy(var, (char *)&int_val, sizeof(int_val));
+
+	if (set) {
+		int_val = htod32(*val);
+		memcpy(&var[len], (char *)&int_val, sizeof(int_val));
+		len += sizeof(int_val);
+		dhd_conf_iovar_buf(dhd, 0, WLC_SET_VAR, cmd, var, sizeof(var));
+	} else {
+		ret = dhd_conf_iovar_buf(dhd, 0, WLC_GET_VAR, cmd, var, sizeof(var));
+		if (ret < 0)
+			return ret;
+		ptr = var;
+		*val = dtoh32(*(int *)ptr);
+	}
+
+	return ret;
+}
+
+static int
+dhd_conf_btc_params(dhd_pub_t *dhd, char *cmd, char *buf)
+{
+	int ret = BCME_OK;
+	uint32 cur_val;
+	int index = 0, mask = 0, value = 0;
+	/* btc_params=[index] [mask] [value]
+	  * btc_params=51 0x0080 0x0000
+	  * btc_params=51 0x0080 0x0080
+	  */
+
+	if (buf) {
+		sscanf(buf, "%d %x %x", &index, &mask, &value);
+	}
+
+	CONFIG_TRACE("%s%d mask=0x%04x value=0x%04x\n", cmd, index, mask, value);
+
+	ret = dhd_conf_reg2args(dhd, cmd, FALSE, index, &cur_val);
+	CONFIG_TRACE("%s%d = 0x%04x\n", cmd, index, cur_val);
+	cur_val &= (~mask);
+	cur_val |= value;
+
+	// need to WLC_UP before btc_params
+	dhd_conf_set_intiovar(dhd, 0, WLC_UP, "WLC_UP", 0, 0, FALSE);
+
+	CONFIG_TRACE("wl %s%d 0x%04x\n", cmd, index, cur_val);
+	ret = dhd_conf_reg2args(dhd, cmd, TRUE, index, &cur_val);
+
+	ret = dhd_conf_reg2args(dhd, cmd, FALSE, index, &cur_val);
+	CONFIG_MSG("%s%d = 0x%04x\n", cmd, index, cur_val);
+
+	return ret;
+}
+
+typedef struct sub_cmd_t {
+	char *name;
+	uint16 id;		/* id for the dongle f/w switch/case  */
+	uint16 type;		/* base type of argument IOVT_XXXX */
+} sub_cmd_t;
+
+/* wl he sub cmd list */
+static const sub_cmd_t he_cmd_list[] = {
+	{"enab", WL_HE_CMD_ENAB, IOVT_UINT8},
+	{"features", WL_HE_CMD_FEATURES, IOVT_UINT32},
+	{"bsscolor", WL_HE_CMD_BSSCOLOR, IOVT_UINT8},
+	{"partialbsscolor", WL_HE_CMD_PARTIAL_BSSCOLOR, IOVT_UINT8},
+	{"cap", WL_HE_CMD_CAP, IOVT_UINT8},
+	{"staid", WL_HE_CMD_STAID, IOVT_UINT16},
+	{"rtsdurthresh", WL_HE_CMD_RTSDURTHRESH, IOVT_UINT16},
+	{"peduration", WL_HE_CMD_PEDURATION, IOVT_UINT8},
+	{"testbed_mode", WL_HE_CMD_TESTBED_MODE, IOVT_UINT32},
+	{"omi_ulmu_throttle", WL_HE_CMD_OMI_ULMU_THROTTLE, IOVT_UINT16},
+	{"omi_dlmu_rr_mpf_map", WL_HE_CMD_OMI_DLMU_RSD_RCM_MPF_MAP, IOVT_UINT32},
+	{"ulmu_disable_policy", WL_HE_CMD_ULMU_DISABLE_POLICY, IOVT_UINT8},
+	{"sr_prohibit", WL_HE_CMD_SR_PROHIBIT, IOVT_UINT8},
+};
+
+static uint
+wl_he_iovt2len(uint iovt)
+{
+	switch (iovt) {
+	case IOVT_BOOL:
+	case IOVT_INT8:
+	case IOVT_UINT8:
+		return sizeof(uint8);
+	case IOVT_INT16:
+	case IOVT_UINT16:
+		return sizeof(uint16);
+	case IOVT_INT32:
+	case IOVT_UINT32:
+		return sizeof(uint32);
+	default:
+		/* ASSERT(0); */
+		return 0;
+	}
+}
+
+static int
+dhd_conf_he_cmd(dhd_pub_t * dhd, char *cmd, char *buf)
+{
+	int ret = BCME_OK, i;
+	bcm_xtlv_t *pxtlv = NULL;
+	uint8 mybuf[128];
+	uint16 he_id = -1, he_len = 0, mybuf_len = sizeof(mybuf);
+	uint32 he_val;
+	const sub_cmd_t *tpl = he_cmd_list;
+	char sub_cmd[32] = "", he_val_str[10] = "";
+
+	if (buf) {
+		sscanf(buf, "%s %s", sub_cmd, he_val_str);
+	}
+
+	for (i=0; i<ARRAY_SIZE(he_cmd_list); i++, tpl++) {
+		if (!strcmp(tpl->name, sub_cmd)) {
+			he_id = tpl->id;
+			he_len = wl_he_iovt2len(tpl->type);
+			break;
+		}
+	}
+	if (he_id < 0) {
+		CONFIG_ERROR("No he id found for %s\n", sub_cmd);
+		return 0;
+	}
+
+	pxtlv = (bcm_xtlv_t *)mybuf;
+
+	if (strlen(he_val_str)) {
+		he_val = simple_strtol(he_val_str, NULL, 0);
+		ret = bcm_pack_xtlv_entry((uint8**)&pxtlv, &mybuf_len, he_id,
+			he_len, (uint8 *)&he_val, BCM_XTLV_OPTION_ALIGN32);
+		if (ret != BCME_OK) {
+			CONFIG_ERROR("failed to pack he enab, err: %s\n", bcmerrorstr(ret));
+			return 0;
+		}
+		CONFIG_TRACE("he %s 0x%x\n", sub_cmd, he_val);
+		dhd_conf_set_bufiovar(dhd, 0, WLC_SET_VAR, cmd, (char *)&mybuf,
+			sizeof(mybuf), TRUE);
+	}
+
+	return 0;
+}
+
+#ifndef SUPPORT_RANDOM_MAC_SCAN
+int
+dhd_conf_scan_mac(dhd_pub_t * dhd, char *cmd, char *buf)
+{
+	uint8 buffer[WLC_IOCTL_SMLEN] = {0, };
+	wl_scanmac_t *sm = NULL;
+	wl_scanmac_enable_t *sm_enable = NULL;
+	int enable = 0, len = 0, ret = -1;
+	char sub_cmd[32], iovbuf[WLC_IOCTL_SMLEN];
+	s32 iovar_len;
+
+	memset(sub_cmd, 0, sizeof(sub_cmd));
+	if (buf) {
+		sscanf(buf, "%s %d", sub_cmd, &enable);
+	}
+
+	if (!strcmp(sub_cmd, "enable")) {
+		sm = (wl_scanmac_t *)buffer;
+		sm_enable = (wl_scanmac_enable_t *)sm->data;
+		sm->len = sizeof(*sm_enable);
+		sm_enable->enable = enable;
+		len = OFFSETOF(wl_scanmac_t, data) + sm->len;
+		sm->subcmd_id = WL_SCANMAC_SUBCMD_ENABLE;
+		CONFIG_TRACE("scanmac enable %d\n", sm_enable->enable);
+
+		iovar_len = bcm_mkiovar("scanmac", buffer, len, iovbuf, sizeof(iovbuf));
+		if (iovar_len > 0)
+			ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, iovar_len, TRUE, 0);
+		else
+			ret = BCME_BUFTOOSHORT;
+		if (ret == BCME_UNSUPPORTED)
+			CONFIG_TRACE("scanmac, UNSUPPORTED\n");
+		else if (ret != BCME_OK)
+			CONFIG_ERROR("%s setting failed %d, len=%d\n", "scanmac", ret, len);
+	}
+	else {
+		CONFIG_ERROR("wrong cmd \"%s %d\"\n", sub_cmd, enable);
+	}
+
+	return 0;
+}
+#endif
+
+static void
+dhd_conf_reset_country_all(dhd_pub_t *dhd)
+{
+	int val;
+	val = 2;
+	dhd_conf_intiovar(dhd, 0, WLC_SET_VAR, "ww_2g_chan_only", (char *)&val, sizeof(val));
+	val = 0;
+	dhd_conf_intiovar(dhd, 0, WLC_SET_VAR, "disable_5g_band", (char *)&val, sizeof(val));
+	val = 0;
+	dhd_conf_intiovar(dhd, 0, WLC_SET_VAR, "disable_6g_band", (char *)&val, sizeof(val));
+}
+
+static int
+dhd_conf_set_country_all(dhd_pub_t *dhd, wl_country_t *cspec)
+{
+	struct dhd_conf *conf = dhd->conf;
+	wl_ccode_all_t *ccode_all = &conf->ccode_all;
+	wl_country_t cspec_all;
+	int ret = -1;
+
+	CONFIG_MSG("%s:%s/%d(2g%x-5g%x-6g%x)\n",
+		cspec->country_abbrev, ccode_all->cspec.ccode, ccode_all->cspec.rev,
+		ccode_all->ww_2g_chan_only,
+		ccode_all->disable_5g_band, ccode_all->disable_6g_band);
+
+	memcpy(&cspec_all, &ccode_all->cspec, sizeof(wl_country_t));
+	ret = dhd_conf_set_country(dhd, &cspec_all, FALSE);
+	if (!ret) {
+		dhd_conf_intiovar(dhd, 0, WLC_SET_VAR, "ww_2g_chan_only",
+			(char *)&ccode_all->ww_2g_chan_only, sizeof(ccode_all->ww_2g_chan_only));
+		dhd_conf_intiovar(dhd, 0, WLC_SET_VAR, "disable_5g_band",
+			(char *)&ccode_all->disable_5g_band, sizeof(ccode_all->disable_5g_band));
+		dhd_conf_intiovar(dhd, 0, WLC_SET_VAR, "disable_6g_band",
+			(char *)&ccode_all->disable_6g_band, sizeof(ccode_all->disable_6g_band));
+	}
+
+	return ret;
+}
+
+bool
+dhd_conf_same_country(dhd_pub_t *dhd, char *buf)
+{
+	wl_ccode_all_t *ccode_all = &dhd->conf->ccode_all;
+	wl_country_t cspec = {{0}, 0, {0}};
+	wl_country_t cur_cspec = {{0}, 0, {0}};
+	uint32 ww_2g_chan_only = 0, disable_5g_band = 0, disable_6g_band = 0;
+	int ret;
+	bool match = TRUE;
+
+	strlcpy(cspec.country_abbrev, buf, WL_CCODE_LEN + 1);
+	strlcpy(cspec.ccode, buf, WL_CCODE_LEN + 1);
+	dhd_conf_map_country_list(dhd, &cspec);
+	dhd_conf_get_country(dhd, &cur_cspec);
+	if (!strncmp(cspec.ccode, ccode_all->cspec.ccode, 2) &&
+			!strncmp(cspec.ccode, cur_cspec.ccode, 2)) {
+		ret = dhd_conf_intiovar(dhd, 0, WLC_GET_VAR, "ww_2g_chan_only",
+			(char *)&ww_2g_chan_only, sizeof(ww_2g_chan_only));
+		if (!ret && ww_2g_chan_only != ccode_all->ww_2g_chan_only)
+			match = FALSE;	
+		ret = dhd_conf_intiovar(dhd, 0, WLC_GET_VAR, "disable_5g_band",
+			(char *)&disable_5g_band, sizeof(disable_5g_band));
+		if (!ret && disable_5g_band != ccode_all->disable_5g_band)
+			match = FALSE;
+		ret = dhd_conf_intiovar(dhd, 0, WLC_GET_VAR, "disable_6g_band",
+			(char *)&disable_6g_band, sizeof(disable_6g_band));
+		if (!ret && disable_6g_band != ccode_all->disable_6g_band)
+			match = FALSE;
+		if (match) {
+			CONFIG_MSG("%s/%d(2g%x-5g%x-6g%x) is already configured\n",
+				cur_cspec.ccode, cur_cspec.rev,
+				ww_2g_chan_only, disable_5g_band, disable_6g_band);
+			return TRUE;
+		}
+	}
+	if (!memcmp(&cspec.ccode, &cur_cspec.ccode, WL_CCODE_LEN) &&
+			(cspec.rev == cur_cspec.rev) &&
+			strncmp(cspec.ccode, ccode_all->cspec.ccode, 2)) {
+		CONFIG_MSG("country code = %s/%d is already configured\n",
+			cspec.ccode, cspec.rev);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+bool
+dhd_conf_same_country_diff_regrev(dhd_pub_t *dhd, char *buf)
+{
+	wl_country_t cur_cspec = {{0}, 0, {0}};
+	wl_country_t cspec = {{0}, 0, {0}};
+
+	strlcpy(cspec.country_abbrev, buf, WL_CCODE_LEN + 1);
+	strlcpy(cspec.ccode, buf, WL_CCODE_LEN + 1);
+	dhd_conf_map_country_list(dhd, &cspec);
+	dhd_conf_get_country(dhd, &cur_cspec);
+	if (!memcmp(&cspec.ccode, &cur_cspec.ccode, WL_CCODE_LEN) &&
+			(cspec.rev != cur_cspec.rev)) {
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+int
+dhd_conf_country(dhd_pub_t *dhd, char *cmd, char *buf)
+{
+	wl_ccode_all_t *ccode_all = &dhd->conf->ccode_all;
+	wl_country_t cspec = {{0}, 0, {0}};
+	bool no_ccode_evt;
+	int err = 0;
+
+	if (buf) {
+		if (dhd_conf_same_country(dhd, buf)) {
+			return 0;
+		}
+		strlcpy(cspec.country_abbrev, buf, WL_CCODE_LEN + 1);
+		strlcpy(cspec.ccode, buf, WL_CCODE_LEN + 1);
+		dhd_conf_map_country_list(dhd, &cspec);
+		if (!strncmp(cspec.ccode, ccode_all->cspec.ccode, 2))
+			err = dhd_conf_set_country_all(dhd, &cspec);
+		else {
+			if (strlen(dhd->conf->ccode_all.cspec.ccode)) {
+				dhd_conf_reset_country_all(dhd);
+			}
+			no_ccode_evt = dhd_conf_same_country_diff_regrev(dhd, buf);
+			err = dhd_conf_set_country(dhd, &cspec, no_ccode_evt);
+		}
+		dhd_conf_get_country(dhd, &dhd->dhd_cspec);
+	}
+
+	return err;
+}
+
+int
+dhd_conf_autocountry(dhd_pub_t *dhd, char *cmd, char *buf)
+{
+	struct net_device *net;
+	int bytes_written = 0;
+	char event_msg[32];
+	int enable = 0;
+
+	if (buf) {
+		sscanf(buf, "%d", &enable);
+	}
+
+	net = dhd_idx2net(dhd, 0);
+	snprintf(event_msg, sizeof(event_msg), "wl event_msg %d 0", WLC_E_COUNTRY_CODE_CHANGED);
+	wl_android_ext_priv_cmd(net, event_msg, 0, &bytes_written);
+
+	CONFIG_MSG("autocountry %d\n", enable);
+	dhd_conf_set_intiovar(dhd, 0, WLC_SET_VAR, "autocountry", enable, 0, FALSE);
+
+	snprintf(event_msg, sizeof(event_msg), "wl event_msg %d 1", WLC_E_COUNTRY_CODE_CHANGED);
+	wl_android_ext_priv_cmd(net, event_msg, 0, &bytes_written);
+
+	dhd_conf_country(dhd, "country", dhd->conf->cspec.country_abbrev);
+
+	return 0;
+}
+
+typedef int (tpl_parse_t)(dhd_pub_t *dhd, char *name, char *buf);
+
+typedef struct iovar_tpl_t {
+	int cmd;
+	char *name;
+	tpl_parse_t *parse;
+} iovar_tpl_t;
+
+const iovar_tpl_t iovar_tpl_list[] = {
+	{WLC_SET_VAR,	"rsdb_mode",	dhd_conf_rsdb_mode},
+	{WLC_SET_VAR,	"he",		dhd_conf_he_cmd},
+	{WLC_SET_VAR,	"btc_params",	dhd_conf_btc_params},
+#ifndef SUPPORT_RANDOM_MAC_SCAN
+	{WLC_SET_VAR,	"scanmac",		dhd_conf_scan_mac},
+#endif
+	{WLC_SET_VAR,	"country",		dhd_conf_country},
+	{WLC_SET_VAR,	"autocountry",	dhd_conf_autocountry},
+};
+
+static int iovar_tpl_parse(const iovar_tpl_t *tpl, int tpl_count,
+	dhd_pub_t *dhd, int cmd, char *name, char *buf)
+{
+	int i, ret = 0;
+
+	/* look for a matching code in the table */
+	for (i = 0; i < tpl_count; i++, tpl++) {
+		if (tpl->cmd == cmd && !strcmp(tpl->name, name))
+			break;
+	}
+	if (i < tpl_count && tpl->parse) {
+		ret = tpl->parse(dhd, name, buf);
+	} else {
+		ret = -1;
+	}
+
+	return ret;
+}
+
+bool
+dhd_conf_set_wl_cmd(dhd_pub_t *dhd, char *data, bool down)
+{
+	int cmd, val, ret = 0, len;
+	char name[32], *pch, *pick_tmp, *pick_tmp2, *pdata = NULL;
+
+	/* Process wl_preinit:
+	 * wl_preinit=[cmd]=[val], [cmd]=[val]
+	 * Ex: wl_preinit=86=0, mpc=0
+	 */
+
+	if (data == NULL)
+		return FALSE;
+
+	len = strlen(data);
+	pdata = kmalloc(len+1, GFP_KERNEL);
+	if (pdata == NULL) {
+		CONFIG_ERROR("Failed to allocate buffer of %d bytes\n", len+1);
+		goto exit;
+	}
+	memset(pdata, 0, len+1);
+	strcpy(pdata, data);
+
+	pick_tmp = pdata;
+	while (pick_tmp && (pick_tmp2 = bcmstrtok(&pick_tmp, ",", 0)) != NULL) {
+		char *pEnd;
+		pch = bcmstrtok(&pick_tmp2, "=", 0);
+		if (!pch)
+			break;
+		if (*pch == ' ') {
+			pch++;
+		}
+		memset(name, 0 , sizeof (name));
+		cmd = bcm_strtoul(pch, &pEnd, 0);
+		if (cmd == 0 || strlen(pEnd)) {
+			cmd = WLC_SET_VAR;
+			strcpy(name, pch);
+		}
+		pch = bcmstrtok(&pick_tmp2, ",", 0);
+		if (!pch) {
+			break;
+		}
+		ret = iovar_tpl_parse(iovar_tpl_list, ARRAY_SIZE(iovar_tpl_list),
+			dhd, cmd, name, pch);
+		if (ret) {
+			val = (int)simple_strtol(pch, NULL, 0);
+			dhd_conf_set_intiovar(dhd, 0, cmd, name, val, -1, down);
+		}
+	}
+
+exit:
+	if (pdata)
+		kfree(pdata);
+	return true;
+}
+
+int
+dhd_conf_get_band(dhd_pub_t *dhd)
+{
+	int band = -1;
+
+	if (dhd && dhd->conf)
+		band = dhd->conf->band;
+	else
+		CONFIG_ERROR("dhd or conf is NULL\n");
+
+	return band;
+}
+
+int
+dhd_conf_set_roam(dhd_pub_t *dhd, int ifidx)
+{
+	int bcmerror = -1;
+	struct dhd_conf *conf = dhd->conf;
+	uint wnm_bsstrans_resp = 0;
+
+	if (dhd->conf->chip == BCM4359_CHIP_ID) {
+		dhd_conf_get_iovar(dhd, ifidx, WLC_GET_VAR, "wnm_bsstrans_resp",
+			(char *)&wnm_bsstrans_resp, sizeof(wnm_bsstrans_resp));
+		if (wnm_bsstrans_resp == WL_BSSTRANS_POLICY_PRODUCT) {
+			dhd->wbtext_policy = WL_BSSTRANS_POLICY_ROAM_ALWAYS;
+			dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_VAR, "wnm_bsstrans_resp",
+				WL_BSSTRANS_POLICY_ROAM_ALWAYS, 0, FALSE);
+		}
+	}
+
+	dhd_roam_disable = conf->roam_off;
+	dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_VAR, "roam_off", dhd->conf->roam_off, 0, FALSE);
+
+	if (!conf->roam_off || !conf->roam_off_suspend) {
+		CONFIG_MSG("set roam_trigger %d\n", conf->roam_trigger[0]);
+		dhd_conf_set_bufiovar(dhd, ifidx, WLC_SET_ROAM_TRIGGER, "WLC_SET_ROAM_TRIGGER",
+			(char *)conf->roam_trigger, sizeof(conf->roam_trigger), FALSE);
+
+		CONFIG_MSG("set roam_scan_period %d\n", conf->roam_scan_period[0]);
+		dhd_conf_set_bufiovar(dhd, ifidx, WLC_SET_ROAM_SCAN_PERIOD, "WLC_SET_ROAM_SCAN_PERIOD",
+			(char *)conf->roam_scan_period, sizeof(conf->roam_scan_period), FALSE);
+
+		CONFIG_MSG("set roam_delta %d\n", conf->roam_delta[0]);
+		dhd_conf_set_bufiovar(dhd, ifidx, WLC_SET_ROAM_DELTA, "WLC_SET_ROAM_DELTA",
+			(char *)conf->roam_delta, sizeof(conf->roam_delta), FALSE);
+
+		dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_VAR, "fullroamperiod",
+			dhd->conf->fullroamperiod, 1, FALSE);
+	}
+
+	return bcmerror;
+}
+
+void
+dhd_conf_add_to_eventbuffer(struct eventmsg_buf *ev, u16 event, bool set)
+{
+	if (!ev || (event > WLC_E_LAST))
+		return;
+
+	if (ev->num < MAX_EVENT_BUF_NUM) {
+		ev->event[ev->num].type = event;
+		ev->event[ev->num].set = set;
+		ev->num++;
+	} else {
+		CONFIG_ERROR("evenbuffer doesn't support > %u events. Update"
+			" the define MAX_EVENT_BUF_NUM \n", MAX_EVENT_BUF_NUM);
+		ASSERT(0);
+	}
+}
+
+s32
+dhd_conf_apply_eventbuffer(dhd_pub_t *dhd, eventmsg_buf_t *ev)
+{
+	char eventmask[WL_EVENTING_MASK_LEN];
+	int i, ret = 0;
+
+	if (!ev || (!ev->num))
+		return -EINVAL;
+
+	/* Read event_msgs mask */
+	ret = dhd_conf_get_iovar(dhd, 0, WLC_GET_VAR, "event_msgs", eventmask,
+		sizeof(eventmask));
+	if (unlikely(ret)) {
+		CONFIG_ERROR("Get event_msgs error (%d)\n", ret);
+		goto exit;
+	}
+
+	/* apply the set bits */
+	for (i = 0; i < ev->num; i++) {
+		if (ev->event[i].set)
+			setbit(eventmask, ev->event[i].type);
+		else
+			clrbit(eventmask, ev->event[i].type);
+	}
+
+	/* Write updated Event mask */
+	ret = dhd_conf_set_bufiovar(dhd, 0, WLC_SET_VAR, "event_msgs", eventmask,
+		sizeof(eventmask), FALSE);
+	if (unlikely(ret)) {
+		CONFIG_ERROR("Set event_msgs error (%d)\n", ret);
+	}
+
+exit:
+	return ret;
+}
+
+static int
+dhd_conf_enable_roam_offload(dhd_pub_t *dhd, int enable)
+{
+	int err;
+	eventmsg_buf_t ev_buf;
+
+	if (dhd->conf->roam_off_suspend)
+		return 0;
+
+	err = dhd_conf_set_intiovar(dhd, 0, WLC_SET_VAR, "roam_offload", enable, 0, FALSE);
+	if (err)
+		return err;
+
+	bzero(&ev_buf, sizeof(eventmsg_buf_t));
+	dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_PSK_SUP, !enable);
+	dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_ASSOC_REQ_IE, !enable);
+	dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_ASSOC_RESP_IE, !enable);
+	dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_REASSOC, !enable);
+	dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_JOIN, !enable);
+	dhd_conf_add_to_eventbuffer(&ev_buf, WLC_E_ROAM, !enable);
+	err = dhd_conf_apply_eventbuffer(dhd, &ev_buf);
+
+	CONFIG_TRACE("roam_offload %d\n", enable);
+
+	return err;
+}
+
+void
+dhd_conf_set_bw_cap(dhd_pub_t *dhd)
+{
+	struct {
+		u32 band;
+		u32 bw_cap;
+	} param = {0, 0};
+
+	if (dhd->conf->bw_cap[0] >= 0) {
+		memset(&param, 0, sizeof(param));
+		param.band = WLC_BAND_2G;
+		param.bw_cap = (uint)dhd->conf->bw_cap[0];
+		CONFIG_MSG("set bw_cap 2g 0x%x\n", param.bw_cap);
+		dhd_conf_set_bufiovar(dhd, 0, WLC_SET_VAR, "bw_cap", (char *)&param,
+			sizeof(param), TRUE);
+	}
+
+	if (dhd->conf->bw_cap[1] >= 0) {
+		memset(&param, 0, sizeof(param));
+		param.band = WLC_BAND_5G;
+		param.bw_cap = (uint)dhd->conf->bw_cap[1];
+		CONFIG_MSG("set bw_cap 5g 0x%x\n", param.bw_cap);
+		dhd_conf_set_bufiovar(dhd, 0, WLC_SET_VAR, "bw_cap", (char *)&param,
+			sizeof(param), TRUE);
+	}
+}
+
+void
+dhd_conf_get_wme(dhd_pub_t *dhd, int ifidx, int mode, edcf_acparam_t *acp)
+{
+	int bcmerror = -1;
+	char iovbuf[WLC_IOCTL_SMLEN];
+	edcf_acparam_t *acparam;
+
+	bzero(iovbuf, sizeof(iovbuf));
+
+	/*
+	 * Get current acparams, using buf as an input buffer.
+	 * Return data is array of 4 ACs of wme params.
+	 */
+	if (mode == 0)
+		bcm_mkiovar("wme_ac_sta", NULL, 0, iovbuf, sizeof(iovbuf));
+	else
+		bcm_mkiovar("wme_ac_ap", NULL, 0, iovbuf, sizeof(iovbuf));
+	if ((bcmerror = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf),
+			FALSE, ifidx)) < 0) {
+		CONFIG_ERROR("wme_ac_sta getting failed %d\n", bcmerror);
+		return;
+	}
+	memcpy((char*)acp, iovbuf, sizeof(edcf_acparam_t)*AC_COUNT);
+
+	acparam = &acp[AC_BK];
+	CONFIG_TRACE("BK: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+		acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
+		acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+		acparam->TXOP);
+	acparam = &acp[AC_BE];
+	CONFIG_TRACE("BE: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+		acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
+		acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+		acparam->TXOP);
+	acparam = &acp[AC_VI];
+	CONFIG_TRACE("VI: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+		acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
+		acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+		acparam->TXOP);
+	acparam = &acp[AC_VO];
+	CONFIG_TRACE("VO: aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+		acparam->ACI, acparam->ACI&EDCF_AIFSN_MASK,
+		acparam->ECW&EDCF_ECWMIN_MASK, (acparam->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+		acparam->TXOP);
+
+	return;
+}
+
+void
+dhd_conf_update_wme(dhd_pub_t *dhd, int ifidx, int mode,
+	edcf_acparam_t *acparam_cur, int aci)
+{
+	int aifsn, ecwmin, ecwmax, txop;
+	edcf_acparam_t *acp;
+	struct dhd_conf *conf = dhd->conf;
+	wme_param_t *wme;
+
+	if (mode == 0)
+		wme = &conf->wme_sta;
+	else
+		wme = &conf->wme_ap;
+
+	/* Default value */
+	aifsn = acparam_cur->ACI&EDCF_AIFSN_MASK;
+	ecwmin = acparam_cur->ECW&EDCF_ECWMIN_MASK;
+	ecwmax = (acparam_cur->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT;
+	txop = acparam_cur->TXOP;
+
+	/* Modified value */
+	if (wme->aifsn[aci] > 0)
+		aifsn = wme->aifsn[aci];
+	if (wme->ecwmin[aci] > 0)
+		ecwmin = wme->ecwmin[aci];
+	if (wme->ecwmax[aci] > 0)
+		ecwmax = wme->ecwmax[aci];
+	if (wme->txop[aci] > 0)
+		txop = wme->txop[aci];
+
+	if (!(wme->aifsn[aci] || wme->ecwmin[aci] ||
+			wme->ecwmax[aci] || wme->txop[aci]))
+		return;
+
+	/* Update */
+	acp = acparam_cur;
+	acp->ACI = (acp->ACI & ~EDCF_AIFSN_MASK) | (aifsn & EDCF_AIFSN_MASK);
+	acp->ECW = ((ecwmax << EDCF_ECWMAX_SHIFT) & EDCF_ECWMAX_MASK) | (acp->ECW & EDCF_ECWMIN_MASK);
+	acp->ECW = ((acp->ECW & EDCF_ECWMAX_MASK) | (ecwmin & EDCF_ECWMIN_MASK));
+	acp->TXOP = txop;
+
+	CONFIG_MSG("wme_ac %s aci %d aifsn %d ecwmin %d ecwmax %d txop 0x%x\n",
+		mode?"ap":"sta", acp->ACI, acp->ACI&EDCF_AIFSN_MASK,
+		acp->ECW&EDCF_ECWMIN_MASK, (acp->ECW&EDCF_ECWMAX_MASK)>>EDCF_ECWMAX_SHIFT,
+		acp->TXOP);
+
+	/*
+	* Now use buf as an output buffer.
+	* Put WME acparams after "wme_ac\0" in buf.
+	* NOTE: only one of the four ACs can be set at a time.
+	*/
+	if (mode == 0)
+		dhd_conf_set_bufiovar(dhd, ifidx, WLC_SET_VAR, "wme_ac_sta", (char *)acp,
+			sizeof(edcf_acparam_t), FALSE);
+	else
+		dhd_conf_set_bufiovar(dhd, ifidx, WLC_SET_VAR, "wme_ac_ap", (char *)acp,
+			sizeof(edcf_acparam_t), FALSE);
+
+}
+
+void
+dhd_conf_set_wme(dhd_pub_t *dhd, int ifidx, int mode)
+{
+	edcf_acparam_t acparam_cur[AC_COUNT];
+
+	if (dhd && dhd->conf) {
+		if (!dhd->conf->force_wme_ac) {
+			CONFIG_TRACE("force_wme_ac is not enabled %d\n",
+				dhd->conf->force_wme_ac);
+			return;
+		}
+
+		CONFIG_TRACE("Before change:\n");
+		dhd_conf_get_wme(dhd, ifidx, mode, acparam_cur);
+
+		dhd_conf_update_wme(dhd, ifidx, mode, &acparam_cur[AC_BK], AC_BK);
+		dhd_conf_update_wme(dhd, ifidx, mode, &acparam_cur[AC_BE], AC_BE);
+		dhd_conf_update_wme(dhd, ifidx, mode, &acparam_cur[AC_VI], AC_VI);
+		dhd_conf_update_wme(dhd, ifidx, mode, &acparam_cur[AC_VO], AC_VO);
+
+		CONFIG_TRACE("After change:\n");
+		dhd_conf_get_wme(dhd, ifidx, mode, acparam_cur);
+	} else {
+		CONFIG_ERROR("dhd or conf is NULL\n");
+	}
+
+	return;
+}
+
+void
+dhd_conf_set_mchan_bw(dhd_pub_t *dhd, int p2p_mode, int miracast_mode)
+{
+	struct dhd_conf *conf = dhd->conf;
+	mchan_params_t *mchan = conf->mchan;
+	bool set = true;
+
+	while (mchan != NULL) {
+		set = true;
+		set &= (mchan->bw >= 0);
+		set &= ((mchan->p2p_mode == -1) | (mchan->p2p_mode == p2p_mode));
+		set &= ((mchan->miracast_mode == -1) | (mchan->miracast_mode == miracast_mode));
+		if (set) {
+			dhd_conf_set_intiovar(dhd, 0, WLC_SET_VAR, "mchan_bw", mchan->bw, 0, FALSE);
+		}
+		mchan = mchan->next;
+	}
+
+	return;
+}
+
+#ifdef PKT_FILTER_SUPPORT
+void
+dhd_conf_add_pkt_filter(dhd_pub_t *dhd)
+{
+	int i, j, magic_id;
+	char str[16], magic[20];
+#define MACS "%02x%02x%02x%02x%02x%02x"
+
+	/*  0) suspend_mode=1
+	 * Case 0: default is unicast pkt and event wake up
+	 * Case 1: no connection in suspend
+	 *   1) wl_suspend=52=0, 3=0
+	 *   2) wl_resume=2=0
+	 *   3) insuspend=0x7
+	 * Case 2: keep connection in suspend, but no pkt and event wake up
+	 *   1) dhd_master_mode=1
+	 *   2) pkt_filter_delete=100, 102, 103, 104, 105, 106, 107, 200
+	 *   3) pkt_filter_add=141 0 0 0 0xFFFFFFFFFFFF 0x000000000000
+	 *   4) insuspend=0x7
+	 *   5) rekey_offload=1
+	 * Case 3: magic pkt and event wake up
+	 *   1) dhd_master_mode=1
+	 *   2) pkt_filter_delete=100, 102, 103, 104, 105, 106, 107, 200
+	 *   3) magic_pkt_filter_add=141 0 1 12
+	 *   4) rekey_offload=1
+	 */
+	if (!dhd->conf->pkt_filter_cnt_default) {
+		dhd->conf->pkt_filter_cnt_default = dhd->pktfilter_count;
+		if (dhd->conf->magic_pkt_filter_add)
+			dhd->conf->magic_pkt_hdr_len = strlen(dhd->conf->magic_pkt_filter_add);
+	}
+	dhd->pktfilter_count = dhd->conf->pkt_filter_cnt_default;
+
+	for(i=0; i<dhd->conf->pkt_filter_add.count; i++) {
+		dhd->pktfilter[i+dhd->pktfilter_count] = dhd->conf->pkt_filter_add.filter[i];
+		CONFIG_MSG("%s\n", dhd->pktfilter[i+dhd->pktfilter_count]);
+	}
+	dhd->pktfilter_count += i;
+
+	if (dhd->conf->magic_pkt_filter_add) {
+		memset(magic, 0, sizeof(magic));
+		strncpy(magic, dhd->conf->magic_pkt_filter_add, dhd->conf->magic_pkt_hdr_len);
+		memset(dhd->conf->magic_pkt_filter_add, 0, MAGIC_PKT_FILTER_LEN);
+		strcpy(dhd->conf->magic_pkt_filter_add, magic);
+		magic_id = (int32)simple_strtol(magic, NULL, 10);
+		strcat(dhd->conf->magic_pkt_filter_add, " 0x");
+		strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");
+		for (j=0; j<16; j++)
+			strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");
+		strcat(dhd->conf->magic_pkt_filter_add, " 0x");
+		strcat(dhd->conf->magic_pkt_filter_add, "FFFFFFFFFFFF");
+		sprintf(str, MACS, MAC2STRDBG(dhd->mac.octet));
+		for (j=0; j<16; j++)
+			strncat(dhd->conf->magic_pkt_filter_add, str, 12);
+		dhd->pktfilter[dhd->pktfilter_count] = dhd->conf->magic_pkt_filter_add;
+		dhd_pktfilter_offload_delete(dhd, magic_id);
+		dhd_pktfilter_offload_set(dhd, dhd->pktfilter[dhd->pktfilter_count]);
+		dhd->pktfilter_count += 1;
+		CONFIG_MSG("%s\n", dhd->conf->magic_pkt_filter_add);
+	}
+}
+
+bool
+dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id)
+{
+	int i;
+
+	if (dhd && dhd->conf) {
+		for (i=0; i<dhd->conf->pkt_filter_del.count; i++) {
+			if (id == dhd->conf->pkt_filter_del.id[i]) {
+				CONFIG_MSG("%d\n", dhd->conf->pkt_filter_del.id[i]);
+				return true;
+			}
+		}
+		return false;
+	}
+	return false;
+}
+
+void
+dhd_conf_discard_pkt_filter(dhd_pub_t *dhd)
+{
+	dhd->pktfilter_count = 6;
+	dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = NULL;
+	dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF";
+	dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = "102 0 0 0 0xFFFFFF 0x01005E";
+	dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = "103 0 0 0 0xFFFF 0x3333";
+	dhd->pktfilter[DHD_MDNS_FILTER_NUM] = NULL;
+	/* Do not enable ARP to pkt filter if dhd_master_mode is false.*/
+	dhd->pktfilter[DHD_ARP_FILTER_NUM] = NULL;
+
+	/* IPv4 broadcast address XXX.XXX.XXX.255 */
+	dhd->pktfilter[dhd->pktfilter_count] = "110 0 0 12 0xFFFF00000000000000000000000000000000000000FF 0x080000000000000000000000000000000000000000FF";
+	dhd->pktfilter_count++;
+	/* discard IPv4 multicast address 224.0.0.0/4 */
+	dhd->pktfilter[dhd->pktfilter_count] = "111 0 0 12 0xFFFF00000000000000000000000000000000F0 0x080000000000000000000000000000000000E0";
+	dhd->pktfilter_count++;
+	/* discard IPv6 multicast address FF00::/8 */
+	dhd->pktfilter[dhd->pktfilter_count] = "112 0 0 12 0xFFFF000000000000000000000000000000000000000000000000FF 0x86DD000000000000000000000000000000000000000000000000FF";
+	dhd->pktfilter_count++;
+	/* discard Netbios pkt */
+	dhd->pktfilter[dhd->pktfilter_count] = "121 0 0 12 0xFFFF000000000000000000FF000000000000000000000000FFFF 0x0800000000000000000000110000000000000000000000000089";
+	dhd->pktfilter_count++;
+
+}
+#endif /* PKT_FILTER_SUPPORT */
+
+int
+dhd_conf_get_pm(dhd_pub_t *dhd)
+{
+	if (dhd && dhd->conf) {
+		return dhd->conf->pm;
+	}
+	return -1;
+}
+
+int
+dhd_conf_custom_mac(dhd_pub_t *dhd)
+{
+	char buf[WLC_IOCTL_SMLEN];
+	bool set_mac = FALSE;
+	int ret = 0;
+
+	memset(buf, 0, sizeof(buf));
+	if (dhd->info->iflist[0]->set_macaddress) {
+		set_mac = TRUE;
+		memcpy(buf, dhd->info->iflist[0]->mac_addr, ETHER_ADDR_LEN);
+		CONFIG_MSG("set custom MAC address %pM from SIOCSIFHWADDR\n", buf);
+	}
+#ifdef GET_CUSTOM_MAC_ENABLE
+#ifdef GET_CUSTOM_MAC_FROM_CONFIG
+	else if (memcmp(&ether_null, &dhd->conf->hw_ether, ETHER_ADDR_LEN)) {
+		set_mac = TRUE;
+		memcpy(buf, &dhd->conf->hw_ether, ETHER_ADDR_LEN);
+		CONFIG_MSG("set custom MAC address %pM from config\n", buf);
+	}
+#endif
+	else {
+		ret = wifi_platform_get_mac_addr(dhd->info->adapter, buf, 0);
+		if (!ret)
+			set_mac = TRUE;
+		else {
+			CONFIG_ERROR("can't get custom MAC address, ret=%d\n", ret);
+			ret = BCME_NOTUP;
+			goto done;
+		}
+	}
+#endif /* GET_CUSTOM_MAC_ENABLE */
+	if (set_mac) {
+		ret = dhd_iovar(dhd, 0, "cur_etheraddr", buf, ETHER_ADDR_LEN, NULL, 0,
+				TRUE);
+		if (ret < 0) {
+			CONFIG_ERROR("can't set MAC address , error=%d\n", ret);
+			ret = BCME_NOTUP;
+			goto done;
+		}
+	}
+
+done:
+	return ret;
+}
+
+int
+dhd_conf_check_hostsleep(dhd_pub_t *dhd, int cmd, void *buf, int len,
+	int *hostsleep_set, int *hostsleep_val, int *ret)
+{
+	if (dhd->conf->insuspend & (NO_TXCTL_IN_SUSPEND | WOWL_IN_SUSPEND)) {
+		int wowl_dngldown = 0;
+#ifdef WL_EXT_WOWL
+		wowl_dngldown = dhd_conf_wowl_dngldown(dhd);
+#endif
+		if (cmd == WLC_SET_VAR) {
+			char *psleep = NULL;
+			if (wowl_dngldown) {
+				psleep = strstr(buf, "wowl_activate");
+				if (psleep) {
+					*hostsleep_set = 1;
+					memcpy(hostsleep_val, psleep+strlen("wowl_activate")+1, sizeof(int));
+				}
+			} else {
+				psleep = strstr(buf, "hostsleep");
+				if (psleep) {
+					*hostsleep_set = 1;
+					memcpy(hostsleep_val, psleep+strlen("hostsleep")+1, sizeof(int));
+				}
+			}
+		}
+		if (dhd->hostsleep && (!*hostsleep_set || *hostsleep_val)) {
+			CONFIG_TRACE("block all none hostsleep clr cmd\n");
+			*ret = BCME_EPERM;
+			goto exit;
+		} else if (*hostsleep_set && *hostsleep_val) {
+			CONFIG_TRACE("hostsleep %d => %d\n", dhd->hostsleep, *hostsleep_val);
+			dhd->hostsleep = *hostsleep_val;
+			if (dhd->conf->insuspend & NO_TXDATA_IN_SUSPEND) {
+				dhd_txflowcontrol(dhd, ALL_INTERFACES, ON);
+			}
+			if (dhd->hostsleep == HOSTSLEEP_DHD_SET) {
+				*ret = 0;
+				goto exit;
+			}
+		} else if (dhd->hostsleep == HOSTSLEEP_DHD_SET && !*hostsleep_val) {
+			CONFIG_TRACE("hostsleep %d => %d\n", dhd->hostsleep, *hostsleep_val);
+			dhd->hostsleep = *hostsleep_val;
+			if (dhd->conf->insuspend & NO_TXDATA_IN_SUSPEND) {
+				dhd_txflowcontrol(dhd, ALL_INTERFACES, OFF);
+			}
+			*ret = 0;
+			goto exit;
+		}
+	}
+#ifdef NO_POWER_SAVE
+	if (cmd == WLC_SET_PM) {
+		if (*(const u32*)buf != 0) {
+			CONFIG_TRACE("skip PM\n");
+			*ret = BCME_OK;
+			goto exit;
+		}
+	} else if (cmd == WLC_SET_VAR) {
+		int cmd_len = strlen("mpc");
+		if (!strncmp(buf, "mpc", cmd_len)) {
+			if (*((u32 *)((u8*)buf+cmd_len+1)) != 0) {
+				CONFIG_TRACE("skip mpc\n");
+				*ret = BCME_OK;
+				goto exit;
+			}
+		}
+	}
+#endif
+
+	return 0;
+exit:
+	return -1;
+}
+
+void
+dhd_conf_get_hostsleep(dhd_pub_t *dhd,
+	int hostsleep_set, int hostsleep_val, int ret)
+{
+	if (dhd->conf->insuspend & (NO_TXCTL_IN_SUSPEND | WOWL_IN_SUSPEND)) {
+		if (hostsleep_set) {
+			if (hostsleep_val && ret) {
+				CONFIG_TRACE("reset hostsleep %d => 0\n", dhd->hostsleep);
+				dhd->hostsleep = HOSTSLEEP_CLEAR;
+				if (dhd->conf->insuspend & NO_TXDATA_IN_SUSPEND) {
+					dhd_txflowcontrol(dhd, ALL_INTERFACES, OFF);
+				}
+			} else if (!hostsleep_val && !ret) {
+				CONFIG_TRACE("set hostsleep %d => 0\n", dhd->hostsleep);
+				dhd->hostsleep = HOSTSLEEP_CLEAR;
+				if (dhd->conf->insuspend & NO_TXDATA_IN_SUSPEND) {
+					dhd_txflowcontrol(dhd, ALL_INTERFACES, OFF);
+				}
+			}
+		}
+	}
+}
+
+#ifdef WL_EXT_WOWL
+#define WL_WOWL_TCPFIN	(1 << 26)
+typedef struct wl_wowl_pattern2 {
+	char cmd[4];
+	wl_wowl_pattern_t wowl_pattern;
+} wl_wowl_pattern2_t;
+static int
+dhd_conf_wowl_pattern(dhd_pub_t *dhd, int ifidx, bool add, char *data)
+{
+	uint buf_len = 0;
+	int	id, type, polarity, offset;
+	char cmd[4]="\0", mask[128]="\0", pattern[128]="\0", mask_tmp[128]="\0", *pmask_tmp;
+	uint32 masksize, patternsize, pad_len = 0;
+	wl_wowl_pattern2_t *wowl_pattern2 = NULL;
+	char *mask_and_pattern;
+	int ret = 0, i, j, v;
+
+	if (data) {
+		if (add)
+			strcpy(cmd, "add");
+		else
+			strcpy(cmd, "clr");
+		if (!strcmp(cmd, "clr")) {
+			CONFIG_TRACE("wowl_pattern clr\n");
+			ret = dhd_conf_set_bufiovar(dhd, ifidx, WLC_SET_VAR, "wowl_pattern", cmd,
+				sizeof(cmd), FALSE);
+			goto exit;
+		}
+		sscanf(data, "%d %d %d %d %s %s", &id, &type, &polarity, &offset,
+			mask_tmp, pattern);
+		masksize = strlen(mask_tmp) -2;
+		CONFIG_TRACE("0 mask_tmp=%s, masksize=%d\n", mask_tmp, masksize);
+
+		// add pading
+		if (masksize % 16)
+			pad_len = (16 - masksize % 16);
+		for (i=0; i<pad_len; i++)
+			strcat(mask_tmp, "0");
+		masksize += pad_len;
+		CONFIG_TRACE("1 mask_tmp=%s, masksize=%d\n", mask_tmp, masksize);
+
+		// translate 0x00 to 0, others to 1
+		j = 0;
+		pmask_tmp = &mask_tmp[2];
+		for (i=0; i<masksize/2; i++) {
+			if(strncmp(&pmask_tmp[i*2], "00", 2))
+				pmask_tmp[j] = '1';
+			else
+				pmask_tmp[j] = '0';
+			j++;
+		}
+		pmask_tmp[j] = '\0';
+		masksize = masksize / 2;
+		CONFIG_TRACE("2 mask_tmp=%s, masksize=%d\n", mask_tmp, masksize);
+
+		// reorder per 8bits
+		pmask_tmp = &mask_tmp[2];
+		for (i=0; i<masksize/8; i++) {
+			char c;
+			for (j=0; j<4; j++) {
+				c = pmask_tmp[i*8+j];
+				pmask_tmp[i*8+j] = pmask_tmp[(i+1)*8-j-1];
+				pmask_tmp[(i+1)*8-j-1] = c;
+			}
+		}
+		CONFIG_TRACE("3 mask_tmp=%s, masksize=%d\n", mask_tmp, masksize);
+
+		// translate 8bits to 1byte
+		j = 0; v = 0;
+		pmask_tmp = &mask_tmp[2];
+		strcpy(mask, "0x");
+		for (i=0; i<masksize; i++) {
+			v = (v<<1) | (pmask_tmp[i]=='1');
+			if (((i+1)%4) == 0) {
+				if (v < 10)
+					mask[j+2] = v + '0';
+				else
+					mask[j+2] = (v-10) + 'a';
+				j++;
+				v = 0;
+			}
+		}
+		mask[j+2] = '\0';
+		masksize = j/2;
+		CONFIG_TRACE("4 mask=%s, masksize=%d\n", mask, masksize);
+
+		patternsize = (strlen(pattern)-2)/2;
+		buf_len = sizeof(wl_wowl_pattern2_t) + patternsize + masksize;
+		wowl_pattern2 = kmalloc(buf_len, GFP_KERNEL);
+		if (wowl_pattern2 == NULL) {
+			CONFIG_ERROR("Failed to allocate buffer of %d bytes\n", buf_len);
+			goto exit;
+		}
+		memset(wowl_pattern2, 0, sizeof(wl_wowl_pattern2_t));
+
+		strncpy(wowl_pattern2->cmd, cmd, sizeof(cmd));
+		wowl_pattern2->wowl_pattern.id = id;
+		wowl_pattern2->wowl_pattern.type = 0;
+		wowl_pattern2->wowl_pattern.offset = offset;
+		mask_and_pattern = (char*)wowl_pattern2 + sizeof(wl_wowl_pattern2_t);
+
+		wowl_pattern2->wowl_pattern.masksize = masksize;
+		ret = wl_pattern_atoh(mask, mask_and_pattern);
+		if (ret == -1) {
+			CONFIG_ERROR("rejecting mask=%s\n", mask);
+			goto exit;
+		}
+
+		mask_and_pattern += wowl_pattern2->wowl_pattern.masksize;
+		wowl_pattern2->wowl_pattern.patternoffset = sizeof(wl_wowl_pattern_t) +
+			wowl_pattern2->wowl_pattern.masksize;
+
+		wowl_pattern2->wowl_pattern.patternsize = patternsize;
+		ret = wl_pattern_atoh(pattern, mask_and_pattern);
+		if (ret == -1) {
+			CONFIG_ERROR("rejecting pattern=%s\n", pattern);
+			goto exit;
+		}
+
+		CONFIG_TRACE("%s %d %s %s\n", cmd, offset, mask, pattern);
+
+		ret = dhd_conf_set_bufiovar(dhd, ifidx, WLC_SET_VAR, "wowl_pattern",
+			(char *)wowl_pattern2, buf_len, FALSE);
+	}
+
+exit:
+	if (wowl_pattern2)
+		kfree(wowl_pattern2);
+	return ret;
+}
+
+static int
+dhd_conf_wowl_wakeind(dhd_pub_t *dhd, int ifidx, bool clear)
+{
+	s8 iovar_buf[WLC_IOCTL_SMLEN];
+	wl_wowl_wakeind_t *wake = NULL;
+	int ret = -1;
+	char clr[6]="clear", wakeind_str[32]="\0";
+
+	if (clear) {
+		CONFIG_TRACE("wowl_wakeind clear\n");
+		ret = dhd_conf_set_bufiovar(dhd, ifidx, WLC_SET_VAR, "wowl_wakeind",
+			clr, sizeof(clr), 0);
+	} else {
+		ret = dhd_conf_get_iovar(dhd, ifidx, WLC_GET_VAR, "wowl_wakeind",
+			iovar_buf, sizeof(iovar_buf));
+		if (!ret) {
+			wake = (wl_wowl_wakeind_t *) iovar_buf;
+			if (wake->ucode_wakeind & WL_WOWL_MAGIC)
+				strcpy(wakeind_str, "(MAGIC packet)");
+			if (wake->ucode_wakeind & WL_WOWL_NET)
+				strcpy(wakeind_str, "(Netpattern)");
+			if (wake->ucode_wakeind & WL_WOWL_DIS)
+				strcpy(wakeind_str, "(Disassoc/Deauth)");
+			if (wake->ucode_wakeind & WL_WOWL_BCN)
+				strcpy(wakeind_str, "(Loss of beacon)");
+			if (wake->ucode_wakeind & WL_WOWL_TCPKEEP_TIME)
+				strcpy(wakeind_str, "(TCPKA timeout)");
+			if (wake->ucode_wakeind & WL_WOWL_TCPKEEP_DATA)
+				strcpy(wakeind_str, "(TCPKA data)");
+			if (wake->ucode_wakeind & WL_WOWL_TCPFIN)
+				strcpy(wakeind_str, "(TCP FIN)");
+			CONFIG_MSG("wakeind=0x%x %s\n", wake->ucode_wakeind, wakeind_str);
+		}
+	}
+
+	return ret;
+}
+
+int
+dhd_conf_wowl_dngldown(dhd_pub_t *dhd)
+{
+	int wowl_dngldown = 0;
+#ifdef BCMDBUS
+	uint insuspend = 0;
+	insuspend = dhd_conf_get_insuspend(dhd, ALL_IN_SUSPEND);
+	if ((insuspend & WOWL_IN_SUSPEND) && dhd_master_mode) {
+		wowl_dngldown = dhd->conf->wowl_dngldown;
+	}
+#endif
+
+	return wowl_dngldown;
+}
+#endif
+
+int
+dhd_conf_mkeep_alive(dhd_pub_t *dhd, int ifidx, int id, int period,
+	char *packet, bool bcast)
+{
+	wl_mkeep_alive_pkt_v1_t *mkeep_alive_pktp;
+	int ret = 0, len_bytes=0, buf_len=0;
+	char *buf = NULL, *iovar_buf = NULL;
+	uint8 *pdata;
+
+	CONFIG_TRACE("id=%d, period=%d, packet=%s\n", id, period, packet);
+	if (period >= 0) {
+		buf = kmalloc(WLC_IOCTL_SMLEN, GFP_KERNEL);
+		if (buf == NULL) {
+			CONFIG_ERROR("Failed to allocate buffer of %d bytes\n", WLC_IOCTL_SMLEN);
+			goto exit;
+		}
+		iovar_buf = kmalloc(WLC_IOCTL_SMLEN, GFP_KERNEL);
+		if (iovar_buf == NULL) {
+			CONFIG_ERROR("Failed to allocate buffer of %d bytes\n", WLC_IOCTL_SMLEN);
+			goto exit;
+		}
+		mkeep_alive_pktp = (wl_mkeep_alive_pkt_v1_t *)buf;
+		mkeep_alive_pktp->version = htod16(WL_MKEEP_ALIVE_VERSION_1);
+		mkeep_alive_pktp->length = htod16(WL_MKEEP_ALIVE_FIXED_LEN);
+		mkeep_alive_pktp->keep_alive_id = id;
+		buf_len += WL_MKEEP_ALIVE_FIXED_LEN;
+		mkeep_alive_pktp->period_msec = period;
+		if (packet && strlen(packet)) {
+			len_bytes = wl_pattern_atoh(packet, (char *)mkeep_alive_pktp->data);
+			buf_len += len_bytes;
+			if (bcast) {
+				memcpy(mkeep_alive_pktp->data, &ether_bcast, ETHER_ADDR_LEN);
+			}
+			ret = dhd_conf_get_iovar(dhd, ifidx, WLC_GET_VAR, "cur_etheraddr",
+				iovar_buf, WLC_IOCTL_SMLEN);
+			if (!ret) {
+				pdata = mkeep_alive_pktp->data;
+				memcpy(pdata+6, iovar_buf, ETHER_ADDR_LEN);
+			}
+		}
+		mkeep_alive_pktp->len_bytes = htod16(len_bytes);
+		ret = dhd_conf_set_bufiovar(dhd, ifidx, WLC_SET_VAR, "mkeep_alive",
+			buf, buf_len, FALSE);
+	}
+
+exit:
+	if (buf)
+		kfree(buf);
+	if (iovar_buf)
+		kfree(iovar_buf);
+	return ret;
+}
+
+#ifdef ARP_OFFLOAD_SUPPORT
+void
+dhd_conf_set_garp(dhd_pub_t *dhd, int ifidx, uint32 ipa, bool enable)
+{
+	int i, len = 0, total_len = WLC_IOCTL_SMLEN;
+	char *iovar_buf = NULL, *packet = NULL;
+
+	if (!dhd->conf->garp || ifidx != 0 || !(dhd->op_mode & DHD_FLAG_STA_MODE))
+		return;
+
+	CONFIG_TRACE("enable=%d\n", enable);
+
+	if (enable) {
+		iovar_buf = kmalloc(total_len, GFP_KERNEL);
+		if (iovar_buf == NULL) {
+			CONFIG_ERROR("Failed to allocate buffer of %d bytes\n", total_len);
+			goto exit;
+		}
+		packet = kmalloc(total_len, GFP_KERNEL);
+		if (packet == NULL) {
+			CONFIG_ERROR("Failed to allocate buffer of %d bytes\n", total_len);
+			goto exit;
+		}
+		dhd_conf_get_iovar(dhd, ifidx, WLC_GET_VAR, "cur_etheraddr", iovar_buf, total_len);
+
+		len += snprintf(packet+len, total_len, "0xffffffffffff");
+		for (i=0; i<ETHER_ADDR_LEN; i++)
+			len += snprintf(packet+len, total_len, "%02x", iovar_buf[i]);
+		len += snprintf(packet+len, total_len, "08060001080006040001");
+		 // Sender Hardware Addr.
+		for (i=0; i<ETHER_ADDR_LEN; i++)
+			len += snprintf(packet+len, total_len, "%02x", iovar_buf[i]);
+		 // Sender IP Addr.
+		len += snprintf(packet+len, total_len, "%02x%02x%02x%02x",
+			ipa&0xff, (ipa>>8)&0xff, (ipa>>16)&0xff, (ipa>>24)&0xff);
+		 // Target Hardware Addr.
+		len += snprintf(packet+len, total_len, "ffffffffffff");
+		 // Target IP Addr.
+		len += snprintf(packet+len, total_len, "%02x%02x%02x%02x",
+			ipa&0xff, (ipa>>8)&0xff, (ipa>>16)&0xff, (ipa>>24)&0xff);
+		len += snprintf(packet+len, total_len, "000000000000000000000000000000000000");
+	}
+
+	dhd_conf_mkeep_alive(dhd, ifidx, 0, dhd->conf->keep_alive_period, packet, TRUE);
+
+exit:
+	if (iovar_buf)
+		kfree(iovar_buf);
+	if (packet)
+		kfree(packet);
+	return;
+}
+#endif
+
+uint
+dhd_conf_get_insuspend(dhd_pub_t *dhd, uint mask)
+{
+	uint insuspend = 0;
+
+	if (dhd->op_mode & DHD_FLAG_STA_MODE) {
+		insuspend = dhd->conf->insuspend &
+			(NO_EVENT_IN_SUSPEND | NO_TXDATA_IN_SUSPEND | NO_TXCTL_IN_SUSPEND |
+			ROAM_OFFLOAD_IN_SUSPEND | WOWL_IN_SUSPEND);
+	} else if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
+		insuspend = dhd->conf->insuspend &
+			(NO_EVENT_IN_SUSPEND | NO_TXDATA_IN_SUSPEND | NO_TXCTL_IN_SUSPEND |
+			AP_DOWN_IN_SUSPEND | AP_FILTER_IN_SUSPEND);
+	}
+
+	return (insuspend & mask);
+}
+
+static void
+dhd_conf_check_connection(dhd_pub_t *dhd, int ifidx, int suspend)
+{
+	struct dhd_conf *conf = dhd->conf;
+	struct ether_addr bssid;
+	wl_event_msg_t msg;
+	int pm;
+#ifdef WL_CFG80211
+	struct net_device *net;
+	unsigned long flags = 0;
+#endif /* defined(WL_CFG80211) */
+
+	if (suspend) {
+		memset(&bssid, 0, ETHER_ADDR_LEN);
+		dhd_wl_ioctl_cmd(dhd, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, FALSE, ifidx);
+		if (memcmp(&ether_null, &bssid, ETHER_ADDR_LEN))
+			memcpy(&conf->bssid_insuspend, &bssid, ETHER_ADDR_LEN);
+		else
+			memset(&conf->bssid_insuspend, 0, ETHER_ADDR_LEN);
+	}
+	else {
+		if (memcmp(&ether_null, &conf->bssid_insuspend, ETHER_ADDR_LEN)) {
+			memset(&bssid, 0, ETHER_ADDR_LEN);
+			dhd_wl_ioctl_cmd(dhd, WLC_GET_BSSID, &bssid, ETHER_ADDR_LEN, FALSE, ifidx);
+			if (memcmp(&ether_null, &bssid, ETHER_ADDR_LEN)) {
+				dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_PM, "WLC_SET_PM", 0, 0, FALSE);
+				dhd_conf_set_bufiovar(dhd, ifidx, WLC_SET_VAR, "send_nulldata",
+					(char *)&bssid, ETHER_ADDR_LEN, FALSE);
+				OSL_SLEEP(100);
+				if (conf->pm >= 0)
+					pm = conf->pm;
+				else
+					pm = PM_FAST;
+				dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_PM, "WLC_SET_PM", pm, 0, FALSE);
+			} else {
+				CONFIG_TRACE("send WLC_E_DEAUTH_IND event\n");
+				bzero(&msg, sizeof(wl_event_msg_t));
+				msg.ifidx = ifidx;
+				memcpy(&msg.addr, &conf->bssid_insuspend, ETHER_ADDR_LEN);
+				msg.event_type = hton32(WLC_E_DEAUTH_IND);
+				msg.status = 0;
+				msg.reason = hton32(DOT11_RC_DEAUTH_LEAVING);
+#ifdef WL_EVENT
+				wl_ext_event_send(dhd->event_params, &msg, NULL);
+#endif
+#ifdef WL_CFG80211
+				spin_lock_irqsave(&dhd->up_lock, flags);
+				net = dhd_idx2net(dhd, ifidx);
+				if (net && dhd->up) {
+					wl_cfg80211_event(net, &msg, NULL);
+				}
+				spin_unlock_irqrestore(&dhd->up_lock, flags);
+#endif /* defined(WL_CFG80211) */
+			}
+		}
+	}
+}
+
+#ifdef SUSPEND_EVENT
+static void
+dhd_conf_set_suspend_event(dhd_pub_t *dhd, int suspend)
+{
+	struct dhd_conf *conf = dhd->conf;
+	char suspend_eventmask[WL_EVENTING_MASK_LEN];
+
+	CONFIG_TRACE("Enter\n");
+	if (suspend) {
+#ifdef PROP_TXSTATUS
+#if defined(BCMSDIO) || defined(BCMDBUS)
+		if (dhd->wlfc_enabled) {
+			dhd_wlfc_deinit(dhd);
+			conf->wlfc = TRUE;
+		} else {
+			conf->wlfc = FALSE;
+		}
+#endif /* BCMSDIO || BCMDBUS */
+#endif /* PROP_TXSTATUS */
+		dhd_conf_get_iovar(dhd, 0, WLC_GET_VAR, "event_msgs",
+			conf->resume_eventmask, sizeof(conf->resume_eventmask));
+		memset(suspend_eventmask, 0, sizeof(suspend_eventmask));
+		setbit(suspend_eventmask, WLC_E_ESCAN_RESULT);
+		dhd_conf_set_bufiovar(dhd, 0, WLC_SET_VAR, "event_msgs",
+			suspend_eventmask, sizeof(suspend_eventmask), FALSE);
+	}
+	else {
+		dhd_conf_set_bufiovar(dhd, 0, WLC_SET_VAR, "event_msgs",
+			conf->resume_eventmask, sizeof(conf->resume_eventmask), FALSE);
+#ifdef PROP_TXSTATUS
+#if defined(BCMSDIO) || defined(BCMDBUS)
+		if (conf->wlfc) {
+			dhd_wlfc_init(dhd);
+			dhd_conf_set_intiovar(dhd, 0, WLC_UP, "WLC_UP", 0, 0, FALSE);
+		}
+#endif
+#endif /* PROP_TXSTATUS */
+	}
+
+}
+#endif
+
+int
+dhd_conf_suspend_resume_sta(dhd_pub_t *dhd, int ifidx, int suspend)
+{
+	struct dhd_conf *conf = dhd->conf;
+	uint insuspend = 0;
+	int pm;
+#ifdef WL_EXT_WOWL
+	int i;
+#endif
+
+	insuspend = dhd_conf_get_insuspend(dhd, ALL_IN_SUSPEND);
+	if (insuspend)
+		WL_MSG(dhd_ifname(dhd, ifidx), "suspend %d\n", suspend);
+
+	if (suspend) {
+		dhd_conf_check_connection(dhd, ifidx, suspend);
+		dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_VAR, "roam_off",
+			conf->roam_off_suspend, 0, FALSE);
+		dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_VAR, "bcn_li_dtim",
+			conf->suspend_bcn_li_dtim, 0, FALSE);
+		if (conf->pm_in_suspend >= 0)
+			pm = conf->pm_in_suspend;
+		else if (conf->pm >= 0)
+			pm = conf->pm;
+		else
+			pm = PM_FAST;
+		dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_PM, "WLC_SET_PM", pm, 0, FALSE);
+#ifdef WL_EXT_WOWL
+		if ((insuspend & WOWL_IN_SUSPEND) && dhd_master_mode) {
+			dhd_conf_wowl_pattern(dhd, ifidx, FALSE, "clr");
+			for(i=0; i<conf->pkt_filter_add.count; i++) {
+				dhd_conf_wowl_pattern(dhd, ifidx, TRUE, conf->pkt_filter_add.filter[i]);
+			}
+			CONFIG_MSG("wowl = 0x%x\n", conf->wowl);
+			dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_VAR, "wowl", conf->wowl, 0, FALSE);
+#ifdef BCMDBUS
+			CONFIG_MSG("wowl_dngldown = %d\n", conf->wowl_dngldown);
+			dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_VAR, "wowl_dngldown", conf->wowl_dngldown, 1, FALSE);
+#endif
+			dhd_conf_wowl_wakeind(dhd, ifidx, TRUE);
+		}
+#endif
+	}
+	else {
+		dhd_conf_get_iovar(dhd, ifidx, WLC_GET_PM, "WLC_GET_PM", (char *)&pm, sizeof(pm));
+		CONFIG_TRACE("PM in suspend = %d\n", pm);
+		if (conf->pm >= 0)
+			pm = conf->pm;
+		else
+			pm = PM_FAST;
+		dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_PM, "WLC_SET_PM", pm, 0, FALSE);
+#ifdef WL_EXT_WOWL
+		if (insuspend & WOWL_IN_SUSPEND) {
+			dhd_conf_wowl_wakeind(dhd, ifidx, FALSE);
+//			dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_VAR, "wowl_activate", 0, 0, FALSE);
+			dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_VAR, "wowl", 0, 0, FALSE);
+			dhd_conf_wowl_pattern(dhd, ifidx, FALSE, "clr");
+		}
+#endif
+		dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_VAR, "bcn_li_dtim", 0, 0, FALSE);
+		dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_VAR, "roam_off",
+			conf->roam_off, 0, FALSE);
+		dhd_conf_check_connection(dhd, ifidx, suspend);
+	}
+
+	return 0;
+}
+
+#ifndef WL_EXT_IAPSTA
+static int
+dhd_conf_suspend_resume_ap(dhd_pub_t *dhd, int ifidx, int suspend)
+{
+	uint insuspend = 0;
+
+	insuspend = dhd_conf_get_insuspend(dhd, ALL_IN_SUSPEND);
+	if (insuspend)
+		WL_MSG(dhd_ifname(dhd, ifidx), "suspend %d\n", suspend);
+
+	if (suspend) {
+		if (insuspend & AP_DOWN_IN_SUSPEND) {
+			dhd_conf_set_intiovar(dhd, ifidx, WLC_DOWN, "WLC_DOWN", 1, 0, FALSE);
+		}
+	} else {
+		if (insuspend & AP_DOWN_IN_SUSPEND) {
+			dhd_conf_set_intiovar(dhd, ifidx, WLC_UP, "WLC_UP", 0, 0, FALSE);
+		}
+	}
+
+	return 0;
+}
+#endif /* !WL_EXT_IAPSTA */
+
+static int
+dhd_conf_suspend_resume_bus(dhd_pub_t *dhd, int suspend)
+{
+	int ret = 0, hostsleep = HOSTSLEEP_DHD_SET, wowl_dngldown = 0;
+	char iovbuf[WLC_IOCTL_SMLEN];
+	uint insuspend = 0;
+	uint32 intstatus = 0;
+
+	insuspend = dhd_conf_get_insuspend(dhd, ALL_IN_SUSPEND);
+	if (insuspend)
+		CONFIG_MSG("suspend %d\n", suspend);
+
+	if (suspend) {
+		if (insuspend & (WOWL_IN_SUSPEND | NO_TXCTL_IN_SUSPEND)) {
+#ifdef WL_EXT_WOWL
+			hostsleep = HOSTSLEEP_FW_SET;
+			if ((insuspend & WOWL_IN_SUSPEND) && dhd_master_mode) {
+				dhd_conf_set_intiovar(dhd, 0, WLC_SET_VAR, "wowl_activate", 1, 0, FALSE);
+#ifdef BCMDBUS
+				wowl_dngldown = dhd->conf->wowl_dngldown;
+#endif
+			}
+#endif
+			if (!wowl_dngldown) {
+				dhd_conf_set_intiovar(dhd, 0, WLC_SET_VAR, "hostsleep", hostsleep, 0, FALSE);
+			}
+#ifdef BCMSDIO
+			ret = dhd_bus_sleep(dhd, TRUE, &intstatus);
+#endif
+#ifdef BCMPCIE
+			ret = dhd_bus_sleep(dhd, TRUE, NULL);
+#endif
+#ifdef BCMDBUS
+			if (wowl_dngldown) {
+				ret = dhd_bus_sleep(dhd, TRUE, NULL);
+			}
+#endif
+			CONFIG_MSG("ret = %d, intstatus = 0x%x\n", ret, intstatus);
+		}
+	} else {
+		if (insuspend & (WOWL_IN_SUSPEND | NO_TXCTL_IN_SUSPEND)) {
+			hostsleep = HOSTSLEEP_CLEAR;
+			CONFIG_TRACE("set hostsleep %d\n", hostsleep);
+			bcm_mkiovar("hostsleep", (char *)&hostsleep, sizeof(hostsleep), iovbuf, sizeof(iovbuf));
+			if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0)
+				CONFIG_TRACE("hostsleep setting failed %d\n", ret);
+		}
+	}
+
+	return 0;
+}
+
+int
+dhd_conf_set_suspend_resume(dhd_pub_t *dhd, int suspend)
+{
+	struct dhd_conf *conf = dhd->conf;
+	uint insuspend = 0;
+
+	insuspend = dhd_conf_get_insuspend(dhd, ALL_IN_SUSPEND);
+	if (insuspend)
+		CONFIG_MSG("op_mode %d, suspend %d, suspended %d, insuspend 0x%x, suspend_mode=%d\n",
+			dhd->op_mode, suspend, conf->suspended, insuspend, conf->suspend_mode);
+
+	if (conf->suspended == suspend || !dhd->up) {
+		return 0;
+	}
+
+	if (suspend) {
+		if (insuspend & (NO_EVENT_IN_SUSPEND|NO_TXCTL_IN_SUSPEND|WOWL_IN_SUSPEND)) {
+			if (conf->suspend_mode == PM_NOTIFIER)
+#ifdef WL_EXT_IAPSTA
+				wl_iapsta_wait_event_complete(dhd);
+#else
+				wl_ext_wait_event_complete(dhd, 0);
+#endif /* WL_EXT_IAPSTA */
+		}
+		if (insuspend & NO_TXDATA_IN_SUSPEND) {
+			dhd_txflowcontrol(dhd, ALL_INTERFACES, ON);
+		}
+#if defined(WL_CFG80211) || defined(WL_ESCAN)
+		if (insuspend & (NO_EVENT_IN_SUSPEND|NO_TXCTL_IN_SUSPEND|WOWL_IN_SUSPEND)) {
+			if (conf->suspend_mode == PM_NOTIFIER)
+				wl_ext_user_sync(dhd, 0, TRUE);
+		}
+#endif
+		if (insuspend & ROAM_OFFLOAD_IN_SUSPEND)
+			dhd_conf_enable_roam_offload(dhd, 2);
+#ifdef SUSPEND_EVENT
+		if (insuspend & NO_EVENT_IN_SUSPEND) {
+			dhd_conf_set_suspend_event(dhd, suspend);
+		}
+#endif
+#ifdef WL_EXT_IAPSTA
+		wl_iapsta_suspend_resume(dhd, suspend);
+#else
+		if (dhd->op_mode & DHD_FLAG_STA_MODE) {
+			dhd_conf_suspend_resume_sta(dhd, 0, suspend);
+		} else if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
+			dhd_conf_suspend_resume_ap(dhd, 0, suspend);
+		}
+#endif /* WL_EXT_IAPSTA */
+		dhd_conf_set_wl_cmd(dhd, conf->wl_suspend, FALSE);
+		dhd_conf_suspend_resume_bus(dhd, suspend);
+		conf->suspended = TRUE;
+	}
+	else {
+		dhd_conf_suspend_resume_bus(dhd, suspend);
+#ifdef SUSPEND_EVENT
+		if (insuspend & NO_EVENT_IN_SUSPEND) {
+			dhd_conf_set_suspend_event(dhd, suspend);
+		}
+#endif
+		if (insuspend & ROAM_OFFLOAD_IN_SUSPEND)
+			dhd_conf_enable_roam_offload(dhd, 0);
+		dhd_conf_set_wl_cmd(dhd, conf->wl_resume, FALSE);
+#ifdef WL_EXT_IAPSTA
+		wl_iapsta_suspend_resume(dhd, suspend);
+#else
+		if (dhd->op_mode & DHD_FLAG_STA_MODE) {
+			dhd_conf_suspend_resume_sta(dhd, 0, suspend);
+		} else if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
+			dhd_conf_suspend_resume_ap(dhd, 0, suspend);
+		}
+#endif /* WL_EXT_IAPSTA */
+#if defined(WL_CFG80211) || defined(WL_ESCAN)
+		if (insuspend & (NO_EVENT_IN_SUSPEND|NO_TXCTL_IN_SUSPEND|WOWL_IN_SUSPEND)) {
+			if (conf->suspend_mode == PM_NOTIFIER)
+				wl_ext_user_sync(dhd, 0, FALSE);
+		}
+#endif
+		if (insuspend & NO_TXDATA_IN_SUSPEND) {
+			dhd_txflowcontrol(dhd, ALL_INTERFACES, OFF);
+		}
+		conf->suspended = FALSE;
+	}
+
+	return 0;
+}
+
+#ifdef PROP_TXSTATUS
+int
+dhd_conf_get_disable_proptx(dhd_pub_t *dhd)
+{
+	struct dhd_conf *conf = dhd->conf;
+	int disable_proptx = -1;
+	int fw_proptx = 0;
+
+	/* check fw proptx priority:
+	  * 1st: check fw support by wl cap
+	  * 2nd: 4334/43340/43341/43241 support proptx but not show in wl cap, so enable it by default
+	  * 	   if you would like to disable it, please set disable_proptx=1 in config.txt
+	  * 3th: disable when proptxstatus not support in wl cap
+	  */
+	if (FW_SUPPORTED(dhd, proptxstatus)) {
+		fw_proptx = 1;
+	} else {
+		fw_proptx = 0;
+	}
+
+	/* returned disable_proptx value:
+	  * -1: disable in STA and enable in P2P(follow original dhd settings when PROP_TXSTATUS_VSDB enabled)
+	  * 0: depend on fw support
+	  * 1: always disable proptx
+	  */
+	if (conf->disable_proptx == 0) {
+		// check fw support as well
+		if (fw_proptx)
+			disable_proptx = 0;
+		else
+			disable_proptx = 1;
+	} else if (conf->disable_proptx >= 1) {
+		disable_proptx = 1;
+	} else {
+		// check fw support as well
+		if (fw_proptx)
+			disable_proptx = -1;
+		else
+			disable_proptx = 1;
+	}
+
+	CONFIG_MSG("fw_proptx=%d, disable_proptx=%d\n", fw_proptx, disable_proptx);
+
+	return disable_proptx;
+}
+#endif
+
+uint
+pick_config_vars(char *varbuf, uint len, uint start_pos, char *pickbuf, int picklen)
+{
+	bool findNewline, changenewline=FALSE, pick=FALSE;
+	int column;
+	uint n, pick_column=0;
+
+	findNewline = FALSE;
+	column = 0;
+
+	if (start_pos >= len) {
+		CONFIG_ERROR("wrong start pos\n");
+		return 0;
+	}
+
+	for (n = start_pos; n < len; n++) {
+		if (varbuf[n] == '\r')
+			continue;
+		if ((findNewline || changenewline) && varbuf[n] != '\n')
+			continue;
+		findNewline = FALSE;
+		if (varbuf[n] == '#') {
+			findNewline = TRUE;
+			continue;
+		}
+		if (varbuf[n] == '\\') {
+			changenewline = TRUE;
+			continue;
+		}
+		if (!changenewline && varbuf[n] == '\n') {
+			if (column == 0)
+				continue;
+			column = 0;
+			continue;
+		}
+		if (changenewline && varbuf[n] == '\n') {
+			changenewline = FALSE;
+			continue;
+		}
+
+		if (column==0 && !pick) { // start to pick
+			pick = TRUE;
+			column++;
+			pick_column = 0;
+		} else {
+			if (pick && column==0) { // stop to pick
+				pick = FALSE;
+				break;
+			} else
+				column++;
+		}
+		if (pick) {
+			if (varbuf[n] == 0x9)
+				continue;
+			if (pick_column >= picklen)
+				break;
+			pickbuf[pick_column] = varbuf[n];
+			pick_column++;
+		}
+	}
+
+	return n; // return current position
+}
+
+bool
+dhd_conf_read_chiprev(dhd_pub_t *dhd, int *chip_match,
+	char *full_param, uint len_param)
+{
+	char *data = full_param+len_param, *pick_tmp, *pch;
+	uint chip = 0, rev = 0;
+
+	/* Process chip, regrev:
+	 * chip=[chipid], rev==[rev]
+	 * Ex: chip=0x4359, rev=9
+	 */
+	if (!strncmp("chip=", full_param, len_param)) {
+		chip = (int)simple_strtol(data, NULL, 0);
+		pick_tmp = data;
+		pch = bcmstrstr(pick_tmp, "rev=");
+		if (pch) {
+			rev = (int)simple_strtol(pch+strlen("rev="), NULL, 0);
+		}
+		if (chip == dhd->conf->chip && rev == dhd->conf->chiprev)
+			*chip_match = 1;
+		else
+			*chip_match = 0;
+		CONFIG_MSG("chip=0x%x, rev=%d, chip_match=%d\n", chip, rev, *chip_match);
+	}
+
+	return TRUE;
+}
+
+bool
+dhd_conf_read_log_level(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	char *data = full_param+len_param;
+
+	if (!strncmp("dhd_msg_level=", full_param, len_param)) {
+		dhd_msg_level = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("dhd_msg_level = 0x%X\n", dhd_msg_level);
+	}
+	else if (!strncmp("dump_msg_level=", full_param, len_param)) {
+		dump_msg_level = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("dump_msg_level = 0x%X\n", dump_msg_level);
+	}
+#ifdef BCMSDIO
+	else if (!strncmp("sd_msglevel=", full_param, len_param)) {
+		sd_msglevel = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("sd_msglevel = 0x%X\n", sd_msglevel);
+	}
+#endif
+#ifdef BCMDBUS
+	else if (!strncmp("dbus_msglevel=", full_param, len_param)) {
+		dbus_msglevel = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("dbus_msglevel = 0x%X\n", dbus_msglevel);
+	}
+#endif
+	else if (!strncmp("android_msg_level=", full_param, len_param)) {
+		android_msg_level = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("android_msg_level = 0x%X\n", android_msg_level);
+	}
+	else if (!strncmp("config_msg_level=", full_param, len_param)) {
+		config_msg_level = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("config_msg_level = 0x%X\n", config_msg_level);
+	}
+#ifdef WL_CFG80211
+	else if (!strncmp("wl_dbg_level=", full_param, len_param)) {
+		wl_dbg_level = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("wl_dbg_level = 0x%X\n", wl_dbg_level);
+	}
+#endif
+#if defined(WL_WIRELESS_EXT)
+	else if (!strncmp("iw_msg_level=", full_param, len_param)) {
+		iw_msg_level = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("iw_msg_level = 0x%X\n", iw_msg_level);
+	}
+#endif
+#if defined(DHD_DEBUG)
+	else if (!strncmp("dhd_console_ms=", full_param, len_param)) {
+		dhd->dhd_console_ms = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("dhd_console_ms = %d\n", dhd->dhd_console_ms);
+	}
+#endif
+	else
+		return false;
+
+	return true;
+}
+
+void
+dhd_conf_read_wme_ac_value(wme_param_t *wme, char *pick, int ac_val)
+{
+	char *pick_tmp, *pch;
+
+	pick_tmp = pick;
+	pch = bcmstrstr(pick_tmp, "aifsn ");
+	if (pch) {
+		wme->aifsn[ac_val] = (int)simple_strtol(pch+strlen("aifsn "), NULL, 0);
+		CONFIG_MSG("ac_val=%d, aifsn=%d\n", ac_val, wme->aifsn[ac_val]);
+	}
+	pick_tmp = pick;
+	pch = bcmstrstr(pick_tmp, "ecwmin ");
+	if (pch) {
+		wme->ecwmin[ac_val] = (int)simple_strtol(pch+strlen("ecwmin "), NULL, 0);
+		CONFIG_MSG("ac_val=%d, ecwmin=%d\n", ac_val, wme->ecwmin[ac_val]);
+	}
+	pick_tmp = pick;
+	pch = bcmstrstr(pick_tmp, "ecwmax ");
+	if (pch) {
+		wme->ecwmax[ac_val] = (int)simple_strtol(pch+strlen("ecwmax "), NULL, 0);
+		CONFIG_MSG("ac_val=%d, ecwmax=%d\n", ac_val, wme->ecwmax[ac_val]);
+	}
+	pick_tmp = pick;
+	pch = bcmstrstr(pick_tmp, "txop ");
+	if (pch) {
+		wme->txop[ac_val] = (int)simple_strtol(pch+strlen("txop "), NULL, 0);
+		CONFIG_MSG("ac_val=%d, txop=0x%x\n", ac_val, wme->txop[ac_val]);
+	}
+
+}
+
+bool
+dhd_conf_read_wme_ac_params(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	struct dhd_conf *conf = dhd->conf;
+	char *data = full_param+len_param;
+
+	// wme_ac_sta_be=aifsn 1 ecwmin 2 ecwmax 3 txop 0x5e
+	// wme_ac_sta_vo=aifsn 1 ecwmin 1 ecwmax 1 txop 0x5e
+
+	if (!strncmp("force_wme_ac=", full_param, len_param)) {
+		conf->force_wme_ac = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("force_wme_ac = %d\n", conf->force_wme_ac);
+	}
+	else if (!strncmp("wme_ac_sta_be=", full_param, len_param)) {
+		dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BE);
+	}
+	else if (!strncmp("wme_ac_sta_bk=", full_param, len_param)) {
+		dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_BK);
+	}
+	else if (!strncmp("wme_ac_sta_vi=", full_param, len_param)) {
+		dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VI);
+	}
+	else if (!strncmp("wme_ac_sta_vo=", full_param, len_param)) {
+		dhd_conf_read_wme_ac_value(&conf->wme_sta, data, AC_VO);
+	}
+	else if (!strncmp("wme_ac_ap_be=", full_param, len_param)) {
+		dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BE);
+	}
+	else if (!strncmp("wme_ac_ap_bk=", full_param, len_param)) {
+		dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_BK);
+	}
+	else if (!strncmp("wme_ac_ap_vi=", full_param, len_param)) {
+		dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VI);
+	}
+	else if (!strncmp("wme_ac_ap_vo=", full_param, len_param)) {
+		dhd_conf_read_wme_ac_value(&conf->wme_ap, data, AC_VO);
+	}
+	else
+		return false;
+
+	return true;
+}
+
+#ifdef SET_FWNV_BY_MAC
+bool
+dhd_conf_read_fw_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	int i, j;
+	char *pch, *pick_tmp;
+	wl_mac_list_t *mac_list;
+	wl_mac_range_t *mac_range;
+	struct dhd_conf *conf = dhd->conf;
+	char *data = full_param+len_param;
+
+	/* Process fw_by_mac:
+	 * fw_by_mac=[fw_mac_num] \
+	 *  [fw_name1] [mac_num1] [oui1-1] [nic_start1-1] [nic_end1-1] \
+	 *                                    [oui1-1] [nic_start1-1] [nic_end1-1]... \
+	 *                                    [oui1-n] [nic_start1-n] [nic_end1-n] \
+	 *  [fw_name2] [mac_num2] [oui2-1] [nic_start2-1] [nic_end2-1] \
+	 *                                    [oui2-1] [nic_start2-1] [nic_end2-1]... \
+	 *                                    [oui2-n] [nic_start2-n] [nic_end2-n] \
+	 * Ex: fw_by_mac=2 \
+	 *  fw_bcmdhd1.bin 2 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \
+	 *  fw_bcmdhd2.bin 3 0x0022F4 0xE85408 0xE8549D 0x983B16 0x3557A9 0x35582A \
+	 *                           0x983B16 0x916157 0x916487
+	 */
+
+	if (!strncmp("fw_by_mac=", full_param, len_param)) {
+		dhd_conf_free_mac_list(&conf->fw_by_mac);
+		pick_tmp = data;
+		pch = bcmstrtok(&pick_tmp, " ", 0);
+		conf->fw_by_mac.count = (uint32)simple_strtol(pch, NULL, 0);
+		if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->fw_by_mac.count,
+				GFP_KERNEL))) {
+			conf->fw_by_mac.count = 0;
+			CONFIG_ERROR("kmalloc failed\n");
+		}
+		CONFIG_MSG("fw_count=%d\n", conf->fw_by_mac.count);
+		conf->fw_by_mac.m_mac_list_head = mac_list;
+		for (i=0; i<conf->fw_by_mac.count; i++) {
+			pch = bcmstrtok(&pick_tmp, " ", 0);
+			strcpy(mac_list[i].name, pch);
+			pch = bcmstrtok(&pick_tmp, " ", 0);
+			mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0);
+			CONFIG_MSG("name=%s, mac_count=%d\n",
+				mac_list[i].name, mac_list[i].count);
+			if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count,
+					GFP_KERNEL))) {
+				mac_list[i].count = 0;
+				CONFIG_ERROR("kmalloc failed\n");
+				break;
+			}
+			mac_list[i].mac = mac_range;
+			for (j=0; j<mac_list[i].count; j++) {
+				pch = bcmstrtok(&pick_tmp, " ", 0);
+				mac_range[j].oui = (uint32)simple_strtol(pch, NULL, 0);
+				pch = bcmstrtok(&pick_tmp, " ", 0);
+				mac_range[j].nic_start = (uint32)simple_strtol(pch, NULL, 0);
+				pch = bcmstrtok(&pick_tmp, " ", 0);
+				mac_range[j].nic_end = (uint32)simple_strtol(pch, NULL, 0);
+				CONFIG_MSG("oui=0x%06X, nic_start=0x%06X, nic_end=0x%06X\n",
+					mac_range[j].oui, mac_range[j].nic_start, mac_range[j].nic_end);
+			}
+		}
+	}
+	else
+		return false;
+
+	return true;
+}
+
+bool
+dhd_conf_read_nv_by_mac(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	int i, j;
+	char *pch, *pick_tmp;
+	wl_mac_list_t *mac_list;
+	wl_mac_range_t *mac_range;
+	struct dhd_conf *conf = dhd->conf;
+	char *data = full_param+len_param;
+
+	/* Process nv_by_mac:
+	 * [nv_by_mac]: The same format as fw_by_mac
+	 */
+	if (!strncmp("nv_by_mac=", full_param, len_param)) {
+		dhd_conf_free_mac_list(&conf->nv_by_mac);
+		pick_tmp = data;
+		pch = bcmstrtok(&pick_tmp, " ", 0);
+		conf->nv_by_mac.count = (uint32)simple_strtol(pch, NULL, 0);
+		if (!(mac_list = kmalloc(sizeof(wl_mac_list_t)*conf->nv_by_mac.count,
+				GFP_KERNEL))) {
+			conf->nv_by_mac.count = 0;
+			CONFIG_ERROR("kmalloc failed\n");
+		}
+		CONFIG_MSG("nv_count=%d\n", conf->nv_by_mac.count);
+		conf->nv_by_mac.m_mac_list_head = mac_list;
+		for (i=0; i<conf->nv_by_mac.count; i++) {
+			pch = bcmstrtok(&pick_tmp, " ", 0);
+			strcpy(mac_list[i].name, pch);
+			pch = bcmstrtok(&pick_tmp, " ", 0);
+			mac_list[i].count = (uint32)simple_strtol(pch, NULL, 0);
+			CONFIG_MSG("name=%s, mac_count=%d\n",
+				mac_list[i].name, mac_list[i].count);
+			if (!(mac_range = kmalloc(sizeof(wl_mac_range_t)*mac_list[i].count,
+					GFP_KERNEL))) {
+				mac_list[i].count = 0;
+				CONFIG_ERROR("kmalloc failed\n");
+				break;
+			}
+			mac_list[i].mac = mac_range;
+			for (j=0; j<mac_list[i].count; j++) {
+				pch = bcmstrtok(&pick_tmp, " ", 0);
+				mac_range[j].oui = (uint32)simple_strtol(pch, NULL, 0);
+				pch = bcmstrtok(&pick_tmp, " ", 0);
+				mac_range[j].nic_start = (uint32)simple_strtol(pch, NULL, 0);
+				pch = bcmstrtok(&pick_tmp, " ", 0);
+				mac_range[j].nic_end = (uint32)simple_strtol(pch, NULL, 0);
+				CONFIG_MSG("oui=0x%06X, nic_start=0x%06X, nic_end=0x%06X\n",
+					mac_range[j].oui, mac_range[j].nic_start, mac_range[j].nic_end);
+			}
+		}
+	}
+	else
+		return false;
+
+	return true;
+}
+#endif
+
+bool
+dhd_conf_read_nv_by_chip(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	int i;
+	char *pch, *pick_tmp;
+	wl_chip_nv_path_t *chip_nv_path;
+	struct dhd_conf *conf = dhd->conf;
+	char *data = full_param+len_param;
+
+	/* Process nv_by_chip:
+	 * nv_by_chip=[nv_chip_num] \
+	 *  [chip1] [chiprev1] [nv_name1] [chip2] [chiprev2] [nv_name2] \
+	 * Ex: nv_by_chip=2 \
+	 *  43430 0 nvram_ap6212.txt 43430 1 nvram_ap6212a.txt \
+	 */
+	if (!strncmp("nv_by_chip=", full_param, len_param)) {
+		dhd_conf_free_chip_nv_path_list(&conf->nv_by_chip);
+		pick_tmp = data;
+		pch = bcmstrtok(&pick_tmp, " ", 0);
+		conf->nv_by_chip.count = (uint32)simple_strtol(pch, NULL, 0);
+		if (!(chip_nv_path = kmalloc(sizeof(wl_chip_nv_path_t)*conf->nv_by_chip.count,
+				GFP_KERNEL))) {
+			conf->nv_by_chip.count = 0;
+			CONFIG_ERROR("kmalloc failed\n");
+		}
+		CONFIG_MSG("nv_by_chip_count=%d\n", conf->nv_by_chip.count);
+		conf->nv_by_chip.m_chip_nv_path_head = chip_nv_path;
+		for (i=0; i<conf->nv_by_chip.count; i++) {
+			pch = bcmstrtok(&pick_tmp, " ", 0);
+			chip_nv_path[i].chip = (uint32)simple_strtol(pch, NULL, 0);
+			pch = bcmstrtok(&pick_tmp, " ", 0);
+			chip_nv_path[i].chiprev = (uint32)simple_strtol(pch, NULL, 0);
+			pch = bcmstrtok(&pick_tmp, " ", 0);
+			strcpy(chip_nv_path[i].name, pch);
+			CONFIG_MSG("chip=0x%x, chiprev=%d, name=%s\n",
+				chip_nv_path[i].chip, chip_nv_path[i].chiprev, chip_nv_path[i].name);
+		}
+	}
+	else
+		return false;
+
+	return true;
+}
+
+bool
+dhd_conf_read_roam_params(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	struct dhd_conf *conf = dhd->conf;
+	char *data = full_param+len_param;
+
+	if (!strncmp("roam_off=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			conf->roam_off = 0;
+		else
+			conf->roam_off = 1;
+		CONFIG_MSG("roam_off = %d\n", conf->roam_off);
+	}
+	else if (!strncmp("roam_off_suspend=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			conf->roam_off_suspend = 0;
+		else
+			conf->roam_off_suspend = 1;
+		CONFIG_MSG("roam_off_suspend = %d\n", conf->roam_off_suspend);
+	}
+	else if (!strncmp("roam_trigger=", full_param, len_param)) {
+		conf->roam_trigger[0] = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("roam_trigger = %d\n", conf->roam_trigger[0]);
+	}
+	else if (!strncmp("roam_scan_period=", full_param, len_param)) {
+		conf->roam_scan_period[0] = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("roam_scan_period = %d\n", conf->roam_scan_period[0]);
+	}
+	else if (!strncmp("roam_delta=", full_param, len_param)) {
+		conf->roam_delta[0] = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("roam_delta = %d\n", conf->roam_delta[0]);
+	}
+	else if (!strncmp("fullroamperiod=", full_param, len_param)) {
+		conf->fullroamperiod = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("fullroamperiod = %d\n", conf->fullroamperiod);
+	}
+	else if (!strncmp("wl_reassoc_support=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			wl_reassoc_support = FALSE;
+		else
+			wl_reassoc_support = TRUE;
+		CONFIG_MSG("wl_reassoc_support = %d\n", wl_reassoc_support);
+	}
+#ifdef WL_SCHED_SCAN
+	else if (!strncmp("max_sched_scan_reqs=", full_param, len_param)) {
+		conf->max_sched_scan_reqs = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("max_sched_scan_reqs = %d\n", conf->max_sched_scan_reqs);
+	}
+#endif /* WL_SCHED_SCAN */
+	else
+		return false;
+
+	return true;
+}
+
+bool
+dhd_conf_read_country(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	struct dhd_conf *conf = dhd->conf;
+	country_list_t *country_next = NULL, *country;
+	int i, count = 0;
+	char *pch, *pick_tmp, *pick_tmp2;
+	char *data = full_param+len_param;
+	uint len_data = strlen(data);
+
+	/* Process country_list:
+	 * country_list=[country1]:[ccode1]/[regrev1],
+	 * [country2]:[ccode2]/[regrev2] \
+	 * Ex: country_list=US:US/0, TW:TW/1
+	 */
+	/* Process ccode_all_list:
+	 * ccode_all_list=[ccode1]:[2g1]-[5g1]-[6g1], [ccode2]:[2g2]-[5g2]-[6g2], \
+	 * Ex: ccode_all_list=AU:2g3-5g0820-6gE, TW:2g3-5g0E04-6gF, US:2g3
+	 */
+	if (!strncmp("ccode=", full_param, len_param)) {
+		len_data = min((uint)WLC_CNTRY_BUF_SZ, len_data);
+		memset(&conf->cspec, 0, sizeof(wl_country_t));
+		memcpy(conf->cspec.country_abbrev, data, len_data);
+		memcpy(conf->cspec.ccode, data, len_data);
+		CONFIG_MSG("ccode = %s\n", conf->cspec.ccode);
+	}
+	else if (!strncmp("regrev=", full_param, len_param)) {
+		conf->cspec.rev = (int32)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("regrev = %d\n", conf->cspec.rev);
+	}
+	else if (!strncmp("ccode_all=", full_param, len_param)) {
+		len_data = min((uint)WLC_CNTRY_BUF_SZ, len_data);
+		memset(&conf->ccode_all.cspec, 0, sizeof(wl_country_t));
+		memcpy(conf->ccode_all.cspec.country_abbrev, data, len_data);
+		memcpy(conf->ccode_all.cspec.ccode, data, len_data);
+		CONFIG_MSG("ccode_all = %s\n", conf->ccode_all.cspec.ccode);
+	}
+	else if (!strncmp("ccode_all_list=", full_param, len_param)) {
+		if (conf->ccode_all_list) {
+			kfree(conf->ccode_all_list);
+			conf->ccode_all_list = NULL;
+		}
+		if (!(conf->ccode_all_list = kzalloc(len_data+1, GFP_KERNEL))) {
+			CONFIG_ERROR("kmalloc failed\n");
+			return TRUE;
+		}
+		memcpy(conf->ccode_all_list, data, len_data);
+		CONFIG_MSG("ccode_all_list size = %d\n", len_data);
+	}
+	else if (!strncmp("country_list=", full_param, len_param)) {
+		dhd_conf_free_country_list(conf);
+		pick_tmp = data;
+		for (i=0; i<CONFIG_COUNTRY_LIST_SIZE; i++) {
+			pick_tmp2 = bcmstrtok(&pick_tmp, ", ", 0);
+			if (!pick_tmp2)
+				break;
+			pch = bcmstrtok(&pick_tmp2, ":", 0);
+			if (!pch)
+				break;
+			country = NULL;
+			if (!(country = kmalloc(sizeof(country_list_t), GFP_KERNEL))) {
+				CONFIG_ERROR("kmalloc failed\n");
+				break;
+			}
+			memset(country, 0, sizeof(country_list_t));
+
+			memcpy(country->cspec.country_abbrev, pch, 2);
+			pch = bcmstrtok(&pick_tmp2, "/", 0);
+			if (!pch) {
+				kfree(country);
+				break;
+			}
+			memcpy(country->cspec.ccode, pch, 2);
+			pch = bcmstrtok(&pick_tmp2, "/", 0);
+			if (!pch) {
+				kfree(country);
+				break;
+			}
+			country->cspec.rev = (int32)simple_strtol(pch, NULL, 10);
+			count++;
+			if (!conf->country_head) {
+				conf->country_head = country;
+				country_next = country;
+			} else {
+				country_next->next = country;
+				country_next = country;
+			}
+			CONFIG_TRACE("abbrev=%s, ccode=%s, regrev=%d\n",
+				country->cspec.country_abbrev, country->cspec.ccode, country->cspec.rev);
+		}
+		CONFIG_MSG("%d country in list\n", count);
+	}
+	else
+		return false;
+
+	return true;
+}
+
+bool
+dhd_conf_read_mchan_params(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	int i;
+	char *pch, *pick_tmp, *pick_tmp2;
+	struct dhd_conf *conf = dhd->conf;
+	mchan_params_t *mchan_next = NULL, *mchan;
+	char *data = full_param+len_param;
+
+	/* Process mchan_bw:
+	 * mchan_bw=[val]/[any/go/gc]/[any/source/sink]
+	 * Ex: mchan_bw=80/go/source, 30/gc/sink
+	 */
+	if (!strncmp("mchan_bw=", full_param, len_param)) {
+		dhd_conf_free_mchan_list(conf);
+		pick_tmp = data;
+		for (i=0; i<MCHAN_MAX_NUM; i++) {
+			pick_tmp2 = bcmstrtok(&pick_tmp, ", ", 0);
+			if (!pick_tmp2)
+				break;
+			pch = bcmstrtok(&pick_tmp2, "/", 0);
+			if (!pch)
+				break;
+
+			mchan = NULL;
+			if (!(mchan = kmalloc(sizeof(mchan_params_t), GFP_KERNEL))) {
+				CONFIG_ERROR("kmalloc failed\n");
+				break;
+			}
+			memset(mchan, 0, sizeof(mchan_params_t));
+
+			mchan->bw = (int)simple_strtol(pch, NULL, 0);
+			if (mchan->bw < 0 || mchan->bw > 100) {
+				CONFIG_ERROR("wrong bw %d\n", mchan->bw);
+				kfree(mchan);
+				break;
+			}
+
+			pch = bcmstrtok(&pick_tmp2, "/", 0);
+			if (!pch) {
+				kfree(mchan);
+				break;
+			} else {
+				if (bcmstrstr(pch, "any")) {
+					mchan->p2p_mode = -1;
+				} else if (bcmstrstr(pch, "go")) {
+					mchan->p2p_mode = WL_P2P_IF_GO;
+				} else if (bcmstrstr(pch, "gc")) {
+					mchan->p2p_mode = WL_P2P_IF_CLIENT;
+				}
+			}
+			pch = bcmstrtok(&pick_tmp2, "/", 0);
+			if (!pch) {
+				kfree(mchan);
+				break;
+			} else {
+				if (bcmstrstr(pch, "any")) {
+					mchan->miracast_mode = -1;
+				} else if (bcmstrstr(pch, "source")) {
+					mchan->miracast_mode = MIRACAST_SOURCE;
+				} else if (bcmstrstr(pch, "sink")) {
+					mchan->miracast_mode = MIRACAST_SINK;
+				}
+			}
+			if (!conf->mchan) {
+				conf->mchan = mchan;
+				mchan_next = mchan;
+			} else {
+				mchan_next->next = mchan;
+				mchan_next = mchan;
+			}
+			CONFIG_TRACE("mchan_bw=%d/%d/%d\n", mchan->bw,mchan->p2p_mode,
+				mchan->miracast_mode);
+		}
+	}
+	else
+		return false;
+
+	return true;
+}
+
+#ifdef PKT_FILTER_SUPPORT
+bool
+dhd_conf_read_pkt_filter(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	struct dhd_conf *conf = dhd->conf;
+	char *data = full_param+len_param;
+	char *pch, *pick_tmp;
+	int i;
+
+	/* Process pkt filter:
+	 * 1) pkt_filter_add=99 0 0 0 0x000000000000 0x000000000000
+	 * 2) pkt_filter_delete=100, 102, 103, 104, 105
+	 * 3) magic_pkt_filter_add=141 0 1 12
+	 */
+	if (!strncmp("dhd_master_mode=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			dhd_master_mode = FALSE;
+		else
+			dhd_master_mode = TRUE;
+		CONFIG_MSG("dhd_master_mode = %d\n", dhd_master_mode);
+	}
+	else if (!strncmp("pkt_filter_add=", full_param, len_param)) {
+		pick_tmp = data;
+		pch = bcmstrtok(&pick_tmp, ",.-", 0);
+		i=0;
+		while (pch != NULL && i<DHD_CONF_FILTER_MAX) {
+			strcpy(&conf->pkt_filter_add.filter[i][0], pch);
+			CONFIG_MSG("pkt_filter_add[%d][] = %s\n",
+				i, &conf->pkt_filter_add.filter[i][0]);
+			pch = bcmstrtok(&pick_tmp, ",.-", 0);
+			i++;
+		}
+		conf->pkt_filter_add.count = i;
+	}
+	else if (!strncmp("pkt_filter_delete=", full_param, len_param) ||
+			!strncmp("pkt_filter_del=", full_param, len_param)) {
+		pick_tmp = data;
+		pch = bcmstrtok(&pick_tmp, " ,.-", 0);
+		i=0;
+		while (pch != NULL && i<DHD_CONF_FILTER_MAX) {
+			conf->pkt_filter_del.id[i] = (uint32)simple_strtol(pch, NULL, 10);
+			pch = bcmstrtok(&pick_tmp, " ,.-", 0);
+			i++;
+		}
+		conf->pkt_filter_del.count = i;
+		CONFIG_MSG("pkt_filter_del id = ");
+		for (i=0; i<conf->pkt_filter_del.count; i++)
+			printk(KERN_CONT "%d ", conf->pkt_filter_del.id[i]);
+		printk(KERN_CONT "\n");
+	}
+	else if (!strncmp("magic_pkt_filter_add=", full_param, len_param)) {
+		if (conf->magic_pkt_filter_add) {
+			kfree(conf->magic_pkt_filter_add);
+			conf->magic_pkt_filter_add = NULL;
+		}
+		if (!(conf->magic_pkt_filter_add = kmalloc(MAGIC_PKT_FILTER_LEN, GFP_KERNEL))) {
+			CONFIG_ERROR("kmalloc failed\n");
+		} else {
+			memset(conf->magic_pkt_filter_add, 0, MAGIC_PKT_FILTER_LEN);
+			strcpy(conf->magic_pkt_filter_add, data);
+			CONFIG_MSG("magic_pkt_filter_add = %s\n", conf->magic_pkt_filter_add);
+		}
+	}
+	else
+		return false;
+
+	return true;
+}
+#endif
+
+#ifdef ISAM_PREINIT
+#if !defined(WL_EXT_IAPSTA)
+#error "WL_EXT_IAPSTA should be defined to enable ISAM_PREINIT"
+#endif /* !WL_EXT_IAPSTA */
+/*
+ * isam_init=mode [sta|ap|apsta|dualap] vifname [wlan1]
+ * isam_config=ifname [wlan0|wlan1] ssid [xxx] chan [x]
+		 hidden [y|n] maxassoc [x]
+		 amode [open|shared|wpapsk|wpa2psk|wpawpa2psk]
+		 emode [none|wep|tkip|aes|tkipaes]
+		 key [xxxxx]
+ * isam_enable=ifname [wlan0|wlan1]
+*/
+bool
+dhd_conf_read_isam(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	struct dhd_conf *conf = dhd->conf;
+	char *data = full_param+len_param;
+
+	if (!strncmp("isam_init=", full_param, len_param)) {
+		sprintf(conf->isam_init, "isam_init %s", data);
+		CONFIG_MSG("isam_init=%s\n", conf->isam_init);
+	}
+	else if (!strncmp("isam_config=", full_param, len_param)) {
+		sprintf(conf->isam_config, "isam_config %s", data);
+		CONFIG_MSG("isam_config=%s\n", conf->isam_config);
+	}
+	else if (!strncmp("isam_enable=", full_param, len_param)) {
+		sprintf(conf->isam_enable, "isam_enable %s", data);
+		CONFIG_MSG("isam_enable=%s\n", conf->isam_enable);
+	}
+	else
+		return false;
+
+	return true;
+}
+#endif
+
+#ifdef IDHCP
+bool
+dhd_conf_read_dhcp_params(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	struct dhd_conf *conf = dhd->conf;
+	char *data = full_param+len_param;
+	struct ipv4_addr ipa_set;
+
+	if (!strncmp("dhcpc_enable=", full_param, len_param)) {
+		conf->dhcpc_enable = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("dhcpc_enable = %d\n", conf->dhcpc_enable);
+	}
+	else if (!strncmp("dhcpd_enable=", full_param, len_param)) {
+		conf->dhcpd_enable = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("dhcpd_enable = %d\n", conf->dhcpd_enable);
+	}
+	else if (!strncmp("dhcpd_ip_addr=", full_param, len_param)) {
+		if (!bcm_atoipv4(data, &ipa_set)) {
+			CONFIG_ERROR("dhcpd_ip_addr adress setting failed.n");
+			return false;
+		}
+		memcpy(&conf->dhcpd_ip_addr, &ipa_set, sizeof(struct ipv4_addr));
+		CONFIG_MSG("dhcpd_ip_addr = %s\n", data);
+	}
+	else if (!strncmp("dhcpd_ip_mask=", full_param, len_param)) {
+		if (!bcm_atoipv4(data, &ipa_set)) {
+			CONFIG_ERROR("dhcpd_ip_mask adress setting failed\n");
+			return false;
+		}
+		memcpy(&conf->dhcpd_ip_mask, &ipa_set, sizeof(struct ipv4_addr));
+		CONFIG_MSG("dhcpd_ip_mask = %s\n", data);
+	}
+	else if (!strncmp("dhcpd_ip_start=", full_param, len_param)) {
+		if (!bcm_atoipv4(data, &ipa_set)) {
+			CONFIG_ERROR("dhcpd_ip_start adress setting failed\n");
+			return false;
+		}
+		memcpy(&conf->dhcpd_ip_start, &ipa_set, sizeof(struct ipv4_addr));
+		CONFIG_MSG("dhcpd_ip_start = %s\n", data);
+	}
+	else if (!strncmp("dhcpd_ip_end=", full_param, len_param)) {
+		if (!bcm_atoipv4(data, &ipa_set)) {
+			CONFIG_ERROR("dhcpd_ip_end adress setting failed\n");
+			return false;
+		}
+		memcpy(&conf->dhcpd_ip_end, &ipa_set, sizeof(struct ipv4_addr));
+		CONFIG_MSG("dhcpd_ip_end = %s\n", data);
+	}
+	else
+		return false;
+
+	return true;
+}
+#endif
+
+#ifdef BCMSDIO
+bool
+dhd_conf_read_sdio_params(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	struct dhd_conf *conf = dhd->conf;
+	char *data = full_param+len_param;
+
+	if (!strncmp("dhd_doflow=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			dhd_doflow = FALSE;
+		else
+			dhd_doflow = TRUE;
+		CONFIG_MSG("dhd_doflow = %d\n", dhd_doflow);
+	}
+	else if (!strncmp("dhd_slpauto=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1)) {
+			dhd_conf_disable_slpauto(dhd);
+		} else
+			dhd_slpauto = TRUE;
+		CONFIG_MSG("dhd_slpauto = %d\n", dhd_slpauto);
+	}
+	else if (!strncmp("use_rxchain=", full_param, len_param)) {
+		conf->use_rxchain = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("use_rxchain = %d\n", conf->use_rxchain);
+	}
+	else if (!strncmp("dhd_txminmax=", full_param, len_param)) {
+		conf->dhd_txminmax = (uint)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("dhd_txminmax = %d\n", conf->dhd_txminmax);
+	}
+	else if (!strncmp("txinrx_thres=", full_param, len_param)) {
+		conf->txinrx_thres = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("txinrx_thres = %d\n", conf->txinrx_thres);
+	}
+#ifdef DYNAMIC_MAX_HDR_READ
+	else if (!strncmp("max_hdr_read=", full_param, len_param)) {
+		conf->max_hdr_read = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("max_hdr_read = %d\n", conf->max_hdr_read);
+	}
+	else if (!strncmp("dhd_firstread=", full_param, len_param)) {
+		firstread = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("dhd_firstread = %d\n", firstread);
+	}
+#endif
+#if defined(HW_OOB)
+	else if (!strncmp("oob_enabled_later=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			conf->oob_enabled_later = FALSE;
+		else
+			conf->oob_enabled_later = TRUE;
+		CONFIG_MSG("oob_enabled_later = %d\n", conf->oob_enabled_later);
+	}
+#endif
+	else if (!strncmp("dpc_cpucore=", full_param, len_param)) {
+		conf->dpc_cpucore = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("dpc_cpucore = %d\n", conf->dpc_cpucore);
+	}
+	else if (!strncmp("rxf_cpucore=", full_param, len_param)) {
+		conf->rxf_cpucore = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("rxf_cpucore = %d\n", conf->rxf_cpucore);
+	}
+	else if (!strncmp("dhd_dpc_prio=", full_param, len_param)) {
+		conf->dhd_dpc_prio = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("dhd_dpc_prio = %d\n", conf->dhd_dpc_prio);
+	}
+#if defined(BCMSDIOH_TXGLOM)
+	else if (!strncmp("txglomsize=", full_param, len_param)) {
+		conf->txglomsize = (uint)simple_strtol(data, NULL, 10);
+		if (conf->txglomsize > SDPCM_MAXGLOM_SIZE)
+			conf->txglomsize = SDPCM_MAXGLOM_SIZE;
+		CONFIG_MSG("txglomsize = %d\n", conf->txglomsize);
+	}
+	else if (!strncmp("bus:rxglom=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			conf->bus_rxglom = FALSE;
+		else
+			conf->bus_rxglom = TRUE;
+		CONFIG_MSG("bus:rxglom = %d\n", conf->bus_rxglom);
+	}
+	else if (!strncmp("deferred_tx_len=", full_param, len_param)) {
+		conf->deferred_tx_len = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("deferred_tx_len = %d\n", conf->deferred_tx_len);
+	}
+	else if (!strncmp("txctl_tmo_fix=", full_param, len_param)) {
+		conf->txctl_tmo_fix = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("txctl_tmo_fix = %d\n", conf->txctl_tmo_fix);
+	}
+	else if (!strncmp("tx_max_offset=", full_param, len_param)) {
+		conf->tx_max_offset = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("tx_max_offset = %d\n", conf->tx_max_offset);
+	}
+	else if (!strncmp("txglom_mode=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			conf->txglom_mode = FALSE;
+		else
+			conf->txglom_mode = TRUE;
+		CONFIG_MSG("txglom_mode = %d\n", conf->txglom_mode);
+	}
+#if defined(SDIO_ISR_THREAD)
+	else if (!strncmp("intr_extn=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			conf->intr_extn = FALSE;
+		else
+			conf->intr_extn = TRUE;
+		CONFIG_MSG("intr_extn = %d\n", conf->intr_extn);
+	}
+#endif
+#ifdef BCMSDIO_RXLIM_POST
+	else if (!strncmp("rxlim_en=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			conf->rxlim_en = FALSE;
+		else
+			conf->rxlim_en = TRUE;
+		CONFIG_MSG("rxlim_en = %d\n", conf->rxlim_en);
+	}
+#endif
+#ifdef BCMSDIO_TXSEQ_SYNC
+	else if (!strncmp("txseq_sync=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			conf->txseq_sync = FALSE;
+		else
+			conf->txseq_sync = TRUE;
+		CONFIG_MSG("txseq_sync = %d\n", conf->txseq_sync);
+	}
+#endif
+#endif
+#ifdef MINIME
+	else if (!strncmp("ramsize=", full_param, len_param)) {
+		conf->ramsize = (uint32)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("ramsize = %d\n", conf->ramsize);
+	}
+#endif
+#ifdef BCMSDIO_INTSTATUS_WAR
+	else if (!strncmp("read_intr_mode=", full_param, len_param)) {
+		conf->read_intr_mode = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("read_intr_mode = %d\n", conf->read_intr_mode);
+	}
+#endif
+	else if (!strncmp("kso_try_max=", full_param, len_param)) {
+		conf->kso_try_max = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("kso_try_max = %d\n", conf->kso_try_max);
+	}
+	else if (!strncmp("dhd_idletime=", full_param, len_param)) {
+		dhd_idletime = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("dhd_idletime = %d\n", dhd_idletime);
+	}
+	else
+		return false;
+
+	return true;
+}
+#endif
+
+#ifdef BCMPCIE
+bool
+dhd_conf_read_pcie_params(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	struct dhd_conf *conf = dhd->conf;
+	char *data = full_param+len_param;
+
+	if (!strncmp("bus:deepsleep_disable=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			conf->bus_deepsleep_disable = 0;
+		else
+			conf->bus_deepsleep_disable = 1;
+		CONFIG_MSG("bus:deepsleep_disable = %d\n", conf->bus_deepsleep_disable);
+	}
+	else if (!strncmp("flow_ring_queue_threshold=", full_param, len_param)) {
+		conf->flow_ring_queue_threshold = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("flow_ring_queue_threshold = %d\n", conf->flow_ring_queue_threshold);
+	}
+	else if (!strncmp("d2h_intr_control=", full_param, len_param)) {
+		conf->d2h_intr_control = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("d2h_intr_control = %d\n", conf->d2h_intr_control);
+	}
+	else if (!strncmp("enq_hdr_pkt=", full_param, len_param)) {
+		conf->enq_hdr_pkt = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("enq_hdr_pkt = 0x%x\n", conf->enq_hdr_pkt);
+	}
+	else if (!strncmp("aspm=", full_param, len_param)) {
+		conf->aspm = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("aspm = %d\n", conf->aspm);
+	}
+	else if (!strncmp("l1ss=", full_param, len_param)) {
+		conf->l1ss = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("l1ss = %d\n", conf->l1ss);
+	}
+	else
+		return false;
+
+	return true;
+}
+#endif
+
+bool
+dhd_conf_read_pm_params(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	struct dhd_conf *conf = dhd->conf;
+	char *data = full_param+len_param;
+
+	if (!strncmp("deepsleep=", full_param, len_param)) {
+		if (!strncmp(data, "1", 1))
+			conf->deepsleep = TRUE;
+		else
+			conf->deepsleep = FALSE;
+		CONFIG_MSG("deepsleep = %d\n", conf->deepsleep);
+	}
+	else if (!strncmp("PM=", full_param, len_param)) {
+		conf->pm = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("PM = %d\n", conf->pm);
+	}
+	else if (!strncmp("pm_in_suspend=", full_param, len_param)) {
+		conf->pm_in_suspend = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("pm_in_suspend = %d\n", conf->pm_in_suspend);
+	}
+	else if (!strncmp("suspend_mode=", full_param, len_param)) {
+		conf->suspend_mode = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("suspend_mode = %d\n", conf->suspend_mode);
+		if (conf->suspend_mode == EARLY_SUSPEND)
+			conf->insuspend &= ~(NO_TXDATA_IN_SUSPEND | NO_TXCTL_IN_SUSPEND);
+		else if (conf->suspend_mode == PM_NOTIFIER ||
+				conf->suspend_mode == SUSPEND_MODE_2)
+			conf->insuspend |= (NO_TXDATA_IN_SUSPEND | NO_TXCTL_IN_SUSPEND);
+		CONFIG_MSG("insuspend = 0x%x\n", conf->insuspend);
+	}
+	else if (!strncmp("suspend_bcn_li_dtim=", full_param, len_param)) {
+		conf->suspend_bcn_li_dtim = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("suspend_bcn_li_dtim = %d\n", conf->suspend_bcn_li_dtim);
+	}
+	else if (!strncmp("xmit_in_suspend=", full_param, len_param)) {
+		if (!strncmp(data, "1", 1))
+			conf->insuspend &= ~NO_TXDATA_IN_SUSPEND;
+		else
+			conf->insuspend |= NO_TXDATA_IN_SUSPEND;
+		CONFIG_MSG("insuspend = 0x%x\n", conf->insuspend);
+	}
+	else if (!strncmp("insuspend=", full_param, len_param)) {
+		conf->insuspend = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("insuspend = 0x%x\n", conf->insuspend);
+	}
+#ifdef WL_EXT_WOWL
+	else if (!strncmp("wowl=", full_param, len_param)) {
+		conf->wowl = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("wowl = 0x%x\n", conf->wowl);
+	}
+#ifdef BCMDBUS
+	else if (!strncmp("wowl_dngldown=", full_param, len_param)) {
+		conf->wowl_dngldown = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("wowl_dngldown = 0x%x\n", conf->wowl_dngldown);
+	}
+#endif
+#endif
+	else if (!strncmp("rekey_offload=", full_param, len_param)) {
+		if (!strncmp(data, "1", 1))
+			conf->rekey_offload = TRUE;
+		else
+			conf->rekey_offload = FALSE;
+		CONFIG_MSG("rekey_offload = %d\n", conf->rekey_offload);
+	}
+	else
+		return false;
+
+	return true;
+}
+
+#ifdef GET_CUSTOM_MAC_FROM_CONFIG
+int
+bcm_str2hex(const char *p, char *ea, int size)
+{
+	int i = 0;
+	char *ep;
+
+	for (;;) {
+		ea[i++] = (char) bcm_strtoul(p, &ep, 16);
+		p = ep;
+		if (!*p++ || i == size)
+			break;
+	}
+
+	return (i == size);
+}
+#endif
+
+bool
+dhd_conf_read_others(dhd_pub_t *dhd, char *full_param, uint len_param)
+{
+	struct dhd_conf *conf = dhd->conf;
+	char *data = full_param+len_param;
+	char *pch, *pick_tmp;
+#ifdef GET_CUSTOM_MAC_FROM_CONFIG
+	struct ether_addr ea_addr;
+#endif
+
+	if (!strncmp("dhd_poll=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			conf->dhd_poll = 0;
+		else
+			conf->dhd_poll = 1;
+		CONFIG_MSG("dhd_poll = %d\n", conf->dhd_poll);
+	}
+	else if (!strncmp("dhd_watchdog_ms=", full_param, len_param)) {
+		dhd_watchdog_ms = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("dhd_watchdog_ms = %d\n", dhd_watchdog_ms);
+	}
+	else if (!strncmp("band=", full_param, len_param)) {
+		/* Process band:
+		 * band=a for 5GHz only and band=b for 2.4GHz only
+		 */
+		if (!strcmp(data, "b"))
+			conf->band = WLC_BAND_2G;
+		else if (!strcmp(data, "a"))
+			conf->band = WLC_BAND_5G;
+		else
+			conf->band = WLC_BAND_AUTO;
+		CONFIG_MSG("band = %d\n", conf->band);
+	}
+	else if (!strncmp("bw_cap_2g=", full_param, len_param)) {
+		conf->bw_cap[0] = (uint)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("bw_cap_2g = %d\n", conf->bw_cap[0]);
+	}
+	else if (!strncmp("bw_cap_5g=", full_param, len_param)) {
+		conf->bw_cap[1] = (uint)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("bw_cap_5g = %d\n", conf->bw_cap[1]);
+	}
+	else if (!strncmp("bw_cap=", full_param, len_param)) {
+		pick_tmp = data;
+		pch = bcmstrtok(&pick_tmp, " ,.-", 0);
+		if (pch != NULL) {
+			conf->bw_cap[0] = (uint32)simple_strtol(pch, NULL, 0);
+			CONFIG_MSG("bw_cap 2g = %d\n", conf->bw_cap[0]);
+		}
+		pch = bcmstrtok(&pick_tmp, " ,.-", 0);
+		if (pch != NULL) {
+			conf->bw_cap[1] = (uint32)simple_strtol(pch, NULL, 0);
+			CONFIG_MSG("bw_cap 5g = %d\n", conf->bw_cap[1]);
+		}
+	}
+	else if (!strncmp("ap_mchan_mode=", full_param, len_param)) {
+		conf->ap_mchan_mode = (uint)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("ap_mchan_mode = %d\n", conf->ap_mchan_mode);
+	}
+	else if (!strncmp("go_mchan_mode=", full_param, len_param)) {
+		conf->go_mchan_mode = (uint)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("go_mchan_mode = %d\n", conf->go_mchan_mode);
+	}
+	else if (!strncmp("csa=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			conf->csa = FALSE;
+		else
+			conf->csa = TRUE;
+		CONFIG_MSG("csa = %d\n", conf->csa);
+	}
+	else if (!strncmp("keep_alive_period=", full_param, len_param)) {
+		conf->keep_alive_period = (uint)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("keep_alive_period = %d\n", conf->keep_alive_period);
+	}
+#ifdef ARP_OFFLOAD_SUPPORT
+	else if (!strncmp("garp=", full_param, len_param)) {
+		if (!strncmp(data, "0", 1))
+			conf->garp = FALSE;
+		else
+			conf->garp = TRUE;
+		CONFIG_MSG("garp = %d\n", conf->garp);
+	}
+#endif
+	else if (!strncmp("srl=", full_param, len_param)) {
+		conf->srl = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("srl = %d\n", conf->srl);
+	}
+	else if (!strncmp("lrl=", full_param, len_param)) {
+		conf->lrl = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("lrl = %d\n", conf->lrl);
+	}
+	else if (!strncmp("bcn_timeout=", full_param, len_param)) {
+		conf->bcn_timeout= (uint)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("bcn_timeout = %d\n", conf->bcn_timeout);
+	}
+	else if (!strncmp("frameburst=", full_param, len_param)) {
+		conf->frameburst = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("frameburst = %d\n", conf->frameburst);
+	}
+	else if (!strncmp("disable_proptx=", full_param, len_param)) {
+		conf->disable_proptx = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("disable_proptx = %d\n", conf->disable_proptx);
+	}
+#ifdef DHDTCPACK_SUPPRESS
+	else if (!strncmp("tcpack_sup_mode=", full_param, len_param)) {
+		conf->tcpack_sup_mode = (uint)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("tcpack_sup_mode = %d\n", conf->tcpack_sup_mode);
+	}
+	else if (!strncmp("tcpack_sup_ratio=", full_param, len_param)) {
+		conf->tcpack_sup_ratio = (uint)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("tcpack_sup_ratio = %d\n", conf->tcpack_sup_ratio);
+	}
+	else if (!strncmp("tcpack_sup_delay=", full_param, len_param)) {
+		conf->tcpack_sup_delay = (uint)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("tcpack_sup_delay = %d\n", conf->tcpack_sup_delay);
+	}
+#endif
+	else if (!strncmp("pktprio8021x=", full_param, len_param)) {
+		conf->pktprio8021x = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("pktprio8021x = %d\n", conf->pktprio8021x);
+	}
+#if defined(BCMSDIO)
+	else if (!strncmp("dhd_txbound=", full_param, len_param)) {
+		dhd_txbound = (uint)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("dhd_txbound = %d\n", dhd_txbound);
+	}
+	else if (!strncmp("dhd_rxbound=", full_param, len_param)) {
+		dhd_rxbound = (uint)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("dhd_rxbound = %d\n", dhd_rxbound);
+	}
+#endif
+	else if (!strncmp("ctrl_resched=", full_param, len_param)) {
+		conf->ctrl_resched = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("ctrl_resched = %d\n", conf->ctrl_resched);
+	}
+	else if (!strncmp("rxcnt_timeout=", full_param, len_param)) {
+		conf->rxcnt_timeout = (int)simple_strtol(data, NULL, 10);
+		CONFIG_MSG("rxcnt_timeout = %d\n", conf->rxcnt_timeout);
+	}
+	else if (!strncmp("in4way=", full_param, len_param)) {
+		conf->in4way = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("in4way = 0x%x\n", conf->in4way);
+	}
+	else if (!strncmp("wl_pre_in4way=", full_param, len_param)) {
+		if (conf->wl_pre_in4way) {
+			kfree(conf->wl_pre_in4way);
+			conf->wl_pre_in4way = NULL;
+		}
+		if (!(conf->wl_pre_in4way = kmalloc(strlen(data)+1, GFP_KERNEL))) {
+			CONFIG_ERROR("kmalloc failed\n");
+		} else {
+			memset(conf->wl_pre_in4way, 0, strlen(data)+1);
+			strcpy(conf->wl_pre_in4way, data);
+			CONFIG_MSG("wl_pre_in4way = %s\n", conf->wl_pre_in4way);
+		}
+	}
+	else if (!strncmp("wl_post_in4way=", full_param, len_param)) {
+		if (conf->wl_post_in4way) {
+			kfree(conf->wl_post_in4way);
+			conf->wl_post_in4way = NULL;
+		}
+		if (!(conf->wl_post_in4way = kmalloc(strlen(data)+1, GFP_KERNEL))) {
+			CONFIG_ERROR("kmalloc failed\n");
+		} else {
+			memset(conf->wl_post_in4way, 0, strlen(data)+1);
+			strcpy(conf->wl_post_in4way, data);
+			CONFIG_MSG("wl_post_in4way = %s\n", conf->wl_post_in4way);
+		}
+	}
+#ifdef BTC_WAR
+	else if (!strncmp("btc_war=", full_param, len_param)) {
+		btc_war = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("btc_war = 0x%x\n", btc_war);
+	}
+#endif /* BTC_WAR */
+	else if (!strncmp("war=", full_param, len_param)) {
+		conf->war = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("war = 0x%x\n", conf->war);
+	}
+	else if (!strncmp("wl_preinit=", full_param, len_param)) {
+		if (conf->wl_preinit) {
+			kfree(conf->wl_preinit);
+			conf->wl_preinit = NULL;
+		}
+		if (!(conf->wl_preinit = kmalloc(strlen(data)+1, GFP_KERNEL))) {
+			CONFIG_ERROR("kmalloc failed\n");
+		} else {
+			memset(conf->wl_preinit, 0, strlen(data)+1);
+			strcpy(conf->wl_preinit, data);
+			CONFIG_MSG("wl_preinit = %s\n", conf->wl_preinit);
+		}
+	}
+	else if (!strncmp("wl_suspend=", full_param, len_param)) {
+		if (conf->wl_suspend) {
+			kfree(conf->wl_suspend);
+			conf->wl_suspend = NULL;
+		}
+		if (!(conf->wl_suspend = kmalloc(strlen(data)+1, GFP_KERNEL))) {
+			CONFIG_ERROR("kmalloc failed\n");
+		} else {
+			memset(conf->wl_suspend, 0, strlen(data)+1);
+			strcpy(conf->wl_suspend, data);
+			CONFIG_MSG("wl_suspend = %s\n", conf->wl_suspend);
+		}
+	}
+	else if (!strncmp("wl_resume=", full_param, len_param)) {
+		if (conf->wl_resume) {
+			kfree(conf->wl_resume);
+			conf->wl_resume = NULL;
+		}
+		if (!(conf->wl_resume = kmalloc(strlen(data)+1, GFP_KERNEL))) {
+			CONFIG_ERROR("kmalloc failed\n");
+		} else {
+			memset(conf->wl_resume, 0, strlen(data)+1);
+			strcpy(conf->wl_resume, data);
+			CONFIG_MSG("wl_resume = %s\n", conf->wl_resume);
+		}
+	}
+#ifdef GET_CUSTOM_MAC_FROM_CONFIG
+	else if (!strncmp("mac=", full_param, len_param)) {
+		if (!bcm_ether_atoe(data, &ea_addr)) {
+			CONFIG_ERROR("mac adress read error");
+			return false;
+		}
+		memcpy(&conf->hw_ether, &ea_addr, ETHER_ADDR_LEN);
+		CONFIG_MSG("mac = %s\n", data);
+	}
+#endif
+#ifdef PROPTX_MAXCOUNT
+	else if (!strncmp("proptx_maxcnt_2g=", full_param, len_param)) {
+		conf->proptx_maxcnt_2g = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("proptx_maxcnt_2g = %d\n", conf->proptx_maxcnt_2g);
+	}
+	else if (!strncmp("proptx_maxcnt_5g=", full_param, len_param)) {
+		conf->proptx_maxcnt_5g = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("proptx_maxcnt_5g = %d\n", conf->proptx_maxcnt_5g);
+	}
+#endif
+#ifdef TPUT_MONITOR
+	else if (!strncmp("tput_monitor_ms=", full_param, len_param)) {
+		conf->tput_monitor_ms = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("tput_monitor_ms = %d\n", conf->tput_monitor_ms);
+	}
+#ifdef BCMSDIO
+	else if (!strncmp("doflow_tput_thresh=", full_param, len_param)) {
+		conf->doflow_tput_thresh = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("doflow_tput_thresh = %d\n", conf->doflow_tput_thresh);
+		if (conf->doflow_tput_thresh > 0)
+			conf->tput_monitor_ms = 1000;
+	}
+#endif
+#endif
+#ifdef SCAN_SUPPRESS
+	else if (!strncmp("scan_intput=", full_param, len_param)) {
+		conf->scan_intput = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("scan_intput = 0x%x\n", conf->scan_intput);
+	}
+	else if (!strncmp("scan_tput_thresh=", full_param, len_param)) {
+		conf->scan_tput_thresh = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("scan_tput_thresh = %d\n", conf->scan_tput_thresh);
+		if (conf->scan_tput_thresh > 0)
+			conf->tput_monitor_ms = 1000;
+	}
+	else if (!strncmp("scan_busy_tmo=", full_param, len_param)) {
+		conf->scan_busy_tmo = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("scan_busy_tmo = %d\n", conf->scan_busy_tmo);
+	}
+	else if (!strncmp("scan_busy_thresh=", full_param, len_param)) {
+		conf->scan_busy_thresh = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("scan_busy_thresh = %d\n", conf->scan_busy_thresh);
+	}
+#endif
+#ifdef DHD_TPUT_PATCH
+	else if (!strncmp("tput_patch=", full_param, len_param)) {
+		if (!strncmp(data, "1", 1))
+			conf->tput_patch = TRUE;
+		else
+			conf->tput_patch = FALSE;
+		CONFIG_MSG("tput_patch = %d\n", conf->tput_patch);
+		dhd_conf_set_tput_patch(dhd);
+	}
+	else if (!strncmp("mtu=", full_param, len_param)) {
+		conf->mtu = (int)simple_strtol(data, NULL, 0);
+		CONFIG_MSG("mtu = %d\n", conf->mtu);
+	}
+	else if (!strncmp("pktsetsum=", full_param, len_param)) {
+		if (!strncmp(data, "1", 1))
+			conf->pktsetsum = TRUE;
+		else
+			conf->pktsetsum = FALSE;
+		CONFIG_MSG("pktsetsum = %d\n", conf->pktsetsum);
+	}
+#endif
+#ifdef SET_XPS_CPUS
+	else if (!strncmp("xps_cpus=", full_param, len_param)) {
+		if (!strncmp(data, "1", 1))
+			conf->xps_cpus = TRUE;
+		else
+			conf->xps_cpus = FALSE;
+		CONFIG_MSG("xps_cpus = %d\n", conf->xps_cpus);
+	}
+#endif
+#ifdef SET_RPS_CPUS
+	else if (!strncmp("rps_cpus=", full_param, len_param)) {
+		if (!strncmp(data, "1", 1))
+			conf->rps_cpus = TRUE;
+		else
+			conf->rps_cpus = FALSE;
+		CONFIG_MSG("rps_cpus = %d\n", conf->rps_cpus);
+	}
+#endif
+#ifdef CHECK_DOWNLOAD_FW
+	else if (!strncmp("fwchk=", full_param, len_param)) {
+		if (!strncmp(data, "1", 1))
+			conf->fwchk = TRUE;
+		else
+			conf->fwchk = FALSE;
+		CONFIG_MSG("fwchk = %d\n", conf->fwchk);
+	}
+#endif
+	else if (!strncmp("vndr_ie_assocreq=", full_param, len_param)) {
+		if (conf->vndr_ie_assocreq) {
+			kfree(conf->vndr_ie_assocreq);
+			conf->vndr_ie_assocreq = NULL;
+		}
+		if (!(conf->vndr_ie_assocreq = kmalloc(strlen(data)+1, GFP_KERNEL))) {
+			CONFIG_ERROR("kmalloc failed\n");
+		} else {
+			memset(conf->vndr_ie_assocreq, 0, strlen(data)+1);
+			strcpy(conf->vndr_ie_assocreq, data);
+			CONFIG_MSG("vndr_ie_assocreq = %s\n", conf->vndr_ie_assocreq);
+		}
+	}
+	else
+		return false;
+
+	return true;
+}
+
+int
+dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path)
+{
+	int bcmerror = -1, chip_match = -1;
+	uint len = 0, memblock_len = 0, start_pos=0, end_pos=0;
+	char *memblock = NULL;
+	char *bufp, *pick = NULL, *pch;
+	bool conf_file_exists;
+	uint len_param;
+
+	len = MAXSZ_CONFIG;
+
+	conf_file_exists = ((conf_path != NULL) && (conf_path[0] != '\0'));
+	if (!conf_file_exists) {
+		CONFIG_MSG("config path %s\n", conf_path);
+		return (0);
+	}
+
+	if (conf_file_exists)
+		bcmerror = dhd_get_download_buffer(dhd, conf_path, NVRAM, &memblock,
+			(int *)&len);
+	else
+		bcmerror = dhd_get_download_buffer(dhd, NULL, NVRAM, &memblock, (int *)&len);
+
+	if (bcmerror != BCME_OK) {
+		CONFIG_MSG("Ignore config file %s\n", conf_path);
+		goto err;
+	}
+
+	memblock_len = MAXSZ_CONFIG;
+
+	pick = MALLOC(dhd->osh, MAXSZ_BUF);
+	if (!pick) {
+		CONFIG_ERROR("Failed to allocate memory %d bytes\n", MAXSZ_BUF);
+		goto err;
+	}
+
+	/* Read variables */
+	if (len > 0 && len < MAXSZ_CONFIG) {
+		bufp = (char *)memblock;
+		bufp[len] = 0;
+
+		while (start_pos < len) {
+			memset(pick, 0, MAXSZ_BUF);
+			end_pos = pick_config_vars(bufp, len, start_pos, pick, MAXSZ_BUF);
+			if (end_pos - start_pos >= MAXSZ_BUF)
+				CONFIG_ERROR("out of buf to read MAXSIZ_BUF=%d\n", MAXSZ_BUF);
+			start_pos = end_pos;
+			pch = strchr(pick, '=');
+			if (pch != NULL) {
+				len_param = pch-pick+1;
+				if (len_param == strlen(pick)) {
+					CONFIG_ERROR("not a right parameter %s\n", pick);
+					continue;
+				}
+			} else {
+				CONFIG_ERROR("not a right parameter %s\n", pick);
+				continue;
+			}
+
+			dhd_conf_read_chiprev(dhd, &chip_match, pick, len_param);
+			if (!chip_match)
+				continue;
+
+			if (dhd_conf_read_log_level(dhd, pick, len_param))
+				continue;
+			else if (dhd_conf_read_roam_params(dhd, pick, len_param))
+				continue;
+			else if (dhd_conf_read_wme_ac_params(dhd, pick, len_param))
+				continue;
+#ifdef SET_FWNV_BY_MAC
+			else if (dhd_conf_read_fw_by_mac(dhd, pick, len_param))
+				continue;
+			else if (dhd_conf_read_nv_by_mac(dhd, pick, len_param))
+				continue;
+#endif
+			else if (dhd_conf_read_nv_by_chip(dhd, pick, len_param))
+				continue;
+			else if (dhd_conf_read_country(dhd, pick, len_param))
+				continue;
+			else if (dhd_conf_read_mchan_params(dhd, pick, len_param))
+				continue;
+#ifdef PKT_FILTER_SUPPORT
+			else if (dhd_conf_read_pkt_filter(dhd, pick, len_param))
+				continue;
+#endif /* PKT_FILTER_SUPPORT */
+#ifdef ISAM_PREINIT
+			else if (dhd_conf_read_isam(dhd, pick, len_param))
+				continue;
+#endif /* ISAM_PREINIT */
+#ifdef IDHCP
+			else if (dhd_conf_read_dhcp_params(dhd, pick, len_param))
+				continue;
+#endif /* IDHCP */
+#ifdef BCMSDIO
+			else if (dhd_conf_read_sdio_params(dhd, pick, len_param))
+				continue;
+#endif /* BCMSDIO */
+#ifdef BCMPCIE
+			else if (dhd_conf_read_pcie_params(dhd, pick, len_param))
+				continue;
+#endif /* BCMPCIE */
+			else if (dhd_conf_read_pm_params(dhd, pick, len_param))
+				continue;
+			else if (dhd_conf_read_others(dhd, pick, len_param))
+				continue;
+			else
+				continue;
+		}
+
+		bcmerror = 0;
+	} else {
+		CONFIG_ERROR("error reading config file: %d\n", len);
+		bcmerror = BCME_SDIO_ERROR;
+	}
+
+err:
+	if (pick)
+		MFREE(dhd->osh, pick, MAXSZ_BUF);
+
+	if (memblock)
+		dhd_free_download_buffer(dhd, memblock, memblock_len);
+
+	return bcmerror;
+}
+
+#if defined(BCMSDIO) || defined(BCMPCIE)
+void
+dhd_conf_set_devid(dhd_pub_t *dhd)
+{
+	wifi_adapter_info_t *adapter = NULL;
+	uint32 bus_type = -1;
+	uint32 bus_num = -1;
+	uint32 slot_num = -1;
+
+	dhd_bus_get_ids(dhd->bus, &bus_type, &bus_num, &slot_num);
+	adapter = dhd_wifi_platform_get_adapter(bus_type, bus_num, slot_num);
+	if (adapter) {
+#if defined(BCMSDIO)
+		dhd->conf->devid = adapter->sdio_func->device;
+#endif
+#if defined(BCMPCIE)
+		dhd->conf->devid = adapter->pci_dev->device;
+		dhd->conf->svid = adapter->pci_dev->subsystem_vendor;
+		dhd->conf->ssid = adapter->pci_dev->subsystem_device;
+#endif
+	} else {
+		CONFIG_ERROR("can't find adapter\n");
+	}
+
+	return;
+}
+#endif
+
+int
+dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev)
+{
+#if defined(BCMSDIO) || defined(BCMPCIE)
+	dhd_conf_set_devid(dhd);
+#endif
+	dhd->conf->chip = chip;
+	dhd->conf->chiprev = chiprev;
+
+#if defined(BCMSDIO)
+	CONFIG_MSG("devid=0x%x, chip=0x%x, chiprev=%d\n",
+		dhd->conf->devid, dhd->conf->chip, dhd->conf->chiprev);
+#endif
+#if defined(BCMPCIE)
+	CONFIG_MSG("devid=0x%x, chip=0x%x, chiprev=%d, svid=0x%04x, ssid=0x%04x\n",
+		dhd->conf->devid, dhd->conf->chip, dhd->conf->chiprev,
+		dhd->conf->svid, dhd->conf->ssid);
+#endif
+#if defined(BCMDBUS)
+	CONFIG_MSG("chip=0x%x, chiprev=%d\n", dhd->conf->chip, dhd->conf->chiprev);
+#endif
+
+	return 0;
+}
+
+uint
+dhd_conf_get_chip(void *context)
+{
+	dhd_pub_t *dhd = context;
+
+	if (dhd && dhd->conf)
+		return dhd->conf->chip;
+	return 0;
+}
+
+uint
+dhd_conf_get_chiprev(void *context)
+{
+	dhd_pub_t *dhd = context;
+
+	if (dhd && dhd->conf)
+		return dhd->conf->chiprev;
+	return 0;
+}
+
+#ifdef BCMSDIO
+void
+dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable)
+{
+	struct dhd_conf *conf = dhd->conf;
+
+	if (enable) {
+		// other parameters set in preinit or config.txt
+		if (conf->txglom_ext)
+			CONFIG_MSG("txglom_ext=%d, txglom_bucket_size=%d\n",
+				conf->txglom_ext, conf->txglom_bucket_size);
+		CONFIG_MSG("txglom_mode=%s\n",
+			conf->txglom_mode==SDPCM_TXGLOM_MDESC?"multi-desc":"copy");
+		CONFIG_MSG("txglomsize=%d, deferred_tx_len=%d\n",
+			conf->txglomsize, conf->deferred_tx_len);
+		CONFIG_MSG("txinrx_thres=%d, dhd_txminmax=%d\n",
+			conf->txinrx_thres, conf->dhd_txminmax);
+		CONFIG_MSG("tx_max_offset=%d, txctl_tmo_fix=%d\n",
+			conf->tx_max_offset, conf->txctl_tmo_fix);
+	} else {
+		// clear txglom parameters
+		conf->txglom_ext = FALSE;
+		conf->txglom_bucket_size = 0;
+		conf->txglomsize = 0;
+		conf->deferred_tx_len = 0;
+	}
+
+}
+
+static void
+dhd_conf_set_ampdu_mpdu(dhd_pub_t *dhd)
+{
+	uint chip = dhd->conf->chip;
+	char ampdu_mpdu[32] = "ampdu_mpdu=";
+	int val = -1;
+
+	if (chip == BCM43430_CHIP_ID || chip == BCM4345_CHIP_ID ||
+			chip == BCM4359_CHIP_ID || chip == BCM43012_CHIP_ID ||
+			chip == BCM4382_CHIP_ID) {
+		val = 16;
+	} else if (chip == BCM43752_CHIP_ID || chip == BCM43756_CHIP_ID ||
+			chip == BCM4381_CHIP_ID) {
+		val = 32;
+	}
+
+	if (val > 0) {
+		snprintf(ampdu_mpdu+strlen(ampdu_mpdu), sizeof(ampdu_mpdu), "%d", val);
+		dhd_conf_set_wl_cmd(dhd, ampdu_mpdu, TRUE);
+	}
+}
+
+#if defined(SDIO_ISR_THREAD)
+static void
+dhd_conf_set_intr_extn(dhd_pub_t *dhd)
+{
+	uint chip = dhd->conf->chip;
+
+	if (chip == BCM43012_CHIP_ID ||
+			chip == BCM4345_CHIP_ID ||
+			chip == BCM4359_CHIP_ID ||
+			chip == BCM43752_CHIP_ID ||
+			chip == BCM4375_CHIP_ID || chip == BCM43756_CHIP_ID ||
+			chip == BCM43711_CHIP_ID ||
+			chip == BCM4381_CHIP_ID || chip == BCM4382_CHIP_ID ||
+			chip == BCM4383_CHIP_ID) {
+		CONFIG_TRACE("enable intr_extn\n");
+		dhd->conf->intr_extn = TRUE;
+	}
+}
+#endif /* SDIO_ISR_THREAD */
+#endif
+
+static void
+dhd_conf_set_txbf(dhd_pub_t *dhd)
+{
+	uint chip = dhd->conf->chip;
+
+	if (chip == BCM4359_CHIP_ID ||
+			chip == BCM43569_CHIP_ID ||
+			chip == BCM43752_CHIP_ID ||
+			chip == BCM4375_CHIP_ID ||
+			chip == BCM43756_CHIP_ID ||
+			chip == BCM4382_CHIP_ID || chip == BCM4383_CHIP_ID) {
+		CONFIG_TRACE("enable txbf\n");
+		dhd_conf_set_intiovar(dhd, 0, WLC_SET_VAR, "txbf", 1, 0, FALSE);
+	}
+}
+
+static void
+dhd_conf_tput_improve(dhd_pub_t *dhd)
+{
+	struct dhd_conf *conf = dhd->conf;
+	uint chip = conf->chip;
+	uint chiprev = conf->chiprev;
+
+	if ((chip == BCM43430_CHIP_ID && chiprev == 2) ||
+			chip == BCM43012_CHIP_ID ||
+			chip == BCM4345_CHIP_ID ||
+			chip == BCM4359_CHIP_ID ||
+			chip == BCM43752_CHIP_ID ||
+			chip == BCM4375_CHIP_ID ||
+			chip == BCM43711_CHIP_ID || chip == BCM43756_CHIP_ID ||
+			chip == BCM4381_CHIP_ID || chip == BCM4382_CHIP_ID ||
+			chip == BCM4383_CHIP_ID) {
+		CONFIG_TRACE("enable tput parameters\n");
+#ifdef DHDTCPACK_SUPPRESS
+#ifdef BCMSDIO
+		conf->tcpack_sup_mode = TCPACK_SUP_REPLACE;
+#endif
+#endif
+#if defined(BCMSDIO)
+		dhd_rxbound = 128;
+		dhd_txbound = 64;
+#endif
+		conf->frameburst = 1;
+#ifdef BCMSDIO
+		conf->dhd_txminmax = -1;
+		conf->txinrx_thres = 128;
+#endif
+	}
+}
+
+#ifdef UPDATE_MODULE_NAME
+#if defined(BCMSDIO) || defined(BCMPCIE)
+static void
+dhd_conf_compat_vht(dhd_pub_t *dhd)
+{
+	char vht_features[] = "vht_features=0";
+
+	CONFIG_TRACE("Enter\n");
+
+	dhd_conf_set_wl_cmd(dhd, vht_features, TRUE);
+}
+#endif
+
+int
+dhd_conf_compat_func(dhd_pub_t *dhd)
+{
+	const module_name_map_t *row = NULL;
+
+	row = dhd_conf_match_module(dhd);
+	if (row && row->compat_func) {
+		row->compat_func(dhd);
+	}
+
+	return 0;
+}
+#endif
+
+void
+dhd_conf_preinit_ioctls_sta(dhd_pub_t *dhd, int ifidx)
+{
+	struct dhd_conf *conf = dhd->conf;
+	int pm;
+
+	dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_VAR, "bcn_timeout",
+		conf->bcn_timeout, 0, FALSE);
+#ifdef NO_POWER_SAVE
+	pm = PM_OFF;
+#else
+	if (conf->pm >= 0)
+		pm = conf->pm;
+	else
+		pm = PM_FAST;
+#endif
+	dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_PM, "WLC_SET_PM", pm, 0, FALSE);
+	dhd_conf_set_intiovar(dhd, ifidx, WLC_SET_VAR, "assoc_retry_max", 10, 0, FALSE);
+	dhd_conf_set_roam(dhd, ifidx);
+}
+
+#ifdef WL_CFG80211
+static void
+dhd_conf_postinit_cfg80211(dhd_pub_t *dhd, int ifidx)
+{
+	struct dhd_conf *conf = dhd->conf;
+	struct net_device *net = dhd_idx2net(dhd, ifidx);
+	struct bcm_cfg80211 *cfg = wl_get_cfg(net);
+
+#ifndef DISABLE_BUILTIN_ROAM
+	cfg->roam_on = conf->roam_off ? false : true;
+#endif
+	if (conf->roam_off)
+		cfg->roam_flags = 0;
+	else
+		cfg->roam_flags |= WL_ROAM_OFF_ON_CONCURRENT;
+
+#ifdef WL_SCHED_SCAN
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
+	if (conf->max_sched_scan_reqs > 0)
+		cfg->wdev->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+	else if (conf->max_sched_scan_reqs == 0)
+		cfg->wdev->wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+#else
+	if (conf->max_sched_scan_reqs > 0)
+		cfg->wdev->wiphy->max_sched_scan_reqs = 1;
+	else if (conf->max_sched_scan_reqs == 0)
+		cfg->wdev->wiphy->max_sched_scan_reqs = 0;
+#endif /* LINUX_VER < 4.12 */
+#endif /* WL_SCHED_SCAN */
+}
+#endif /* WL_CFG80211 */
+
+void
+dhd_conf_postinit_ioctls(dhd_pub_t *dhd)
+{
+	struct dhd_conf *conf = dhd->conf;
+#ifdef NO_POWER_SAVE
+	char wl_no_power_save[] = "mpc=0, 86=0";
+	dhd_conf_set_wl_cmd(dhd, wl_no_power_save, FALSE);
+#endif
+
+	dhd_conf_get_ioctl_ver(dhd);
+	dhd_conf_set_intiovar(dhd, 0, WLC_UP, "WLC_UP", 0, 0, FALSE);
+	dhd_conf_check_ccode_all(dhd);
+	dhd_conf_country(dhd, "country", conf->cspec.country_abbrev);
+
+	dhd_conf_set_intiovar(dhd, 0, WLC_SET_BAND, "WLC_SET_BAND", conf->band, 0, FALSE);
+	dhd_conf_set_intiovar(dhd, 0, WLC_SET_SRL, "WLC_SET_SRL", conf->srl, 0, FALSE);
+	dhd_conf_set_intiovar(dhd, 0, WLC_SET_LRL, "WLC_SET_LRL", conf->lrl, 0, FALSE);
+	dhd_conf_set_bw_cap(dhd);
+
+#if defined(BCMPCIE)
+	dhd_conf_set_intiovar(dhd, 0, WLC_SET_VAR, "bus:deepsleep_disable",
+		conf->bus_deepsleep_disable, 0, FALSE);
+#endif /* defined(BCMPCIE) */
+
+#ifdef IDHCP
+	dhd_conf_set_intiovar(dhd, 0, WLC_SET_VAR, "dhcpc_enable", conf->dhcpc_enable,
+		0, FALSE);
+	if (conf->dhcpd_enable >= 0) {
+		dhd_conf_set_bufiovar(dhd, 0, WLC_SET_VAR, "dhcpd_ip_addr",
+			(char *)&conf->dhcpd_ip_addr, sizeof(conf->dhcpd_ip_addr), FALSE);
+		dhd_conf_set_bufiovar(dhd, 0, WLC_SET_VAR, "dhcpd_ip_mask",
+			(char *)&conf->dhcpd_ip_mask, sizeof(conf->dhcpd_ip_mask), FALSE);
+		dhd_conf_set_bufiovar(dhd, 0, WLC_SET_VAR, "dhcpd_ip_start",
+			(char *)&conf->dhcpd_ip_start, sizeof(conf->dhcpd_ip_start), FALSE);
+		dhd_conf_set_bufiovar(dhd, 0, WLC_SET_VAR, "dhcpd_ip_end",
+			(char *)&conf->dhcpd_ip_end, sizeof(conf->dhcpd_ip_end), FALSE);
+		dhd_conf_set_intiovar(dhd, 0, WLC_SET_VAR, "dhcpd_enable",
+			conf->dhcpd_enable, 0, FALSE);
+	}
+#endif
+	dhd_conf_set_intiovar(dhd, 0, WLC_SET_FAKEFRAG, "WLC_SET_FAKEFRAG",
+		conf->frameburst, 0, FALSE);
+
+	dhd_conf_preinit_ioctls_sta(dhd, 0);
+#ifdef WL_CFG80211
+	dhd_conf_postinit_cfg80211(dhd, 0);
+#endif /* WL_CFG80211 */
+#if defined(BCMSDIO)
+	dhd_conf_set_ampdu_mpdu(dhd);
+#endif
+
+#ifdef DHD_TPUT_PATCH
+	if (dhd->conf->mtu)
+		dhd_change_mtu(dhd, dhd->conf->mtu, 0);
+#endif
+	dhd_conf_set_txbf(dhd);
+	if (conf->chip == BCM4375_CHIP_ID) {
+		char he_cmd[] = "110=1, nmode=1, vhtmode=1, he=enab 1";
+		dhd_conf_set_wl_cmd(dhd, he_cmd, TRUE);
+	}
+	if (conf->chip == BCM43752_CHIP_ID || conf->chip == BCM4359_CHIP_ID) {
+		char txack_alive[] = "txack_alive=0";
+		dhd_conf_set_wl_cmd(dhd, txack_alive, TRUE);
+	}
+#ifdef WLDWDS
+	{
+		char dwds[] = "dwds=1";
+		dhd_conf_set_wl_cmd(dhd, dwds, TRUE);
+	}
+#endif /* WLDWDS */
+#if defined(WLEASYMESH)
+	if (conf->fw_type == FW_TYPE_EZMESH) {
+		if (conf->chip == BCM4359_CHIP_ID) {
+			char ezmesh[] = "mbss=1, rsdb_mode=0";
+			dhd_conf_set_wl_cmd(dhd, ezmesh, TRUE);
+		} else {
+			char ezmesh[] = "mbss=1";
+			dhd_conf_set_wl_cmd(dhd, ezmesh, TRUE);
+		}
+	}
+#endif /* WLEASYMESH */
+#if defined(BCMSDIO) || defined(BCMPCIE)
+#if defined(BCMSDIO)
+	if (conf->devid == BCM43751_CHIP_ID)
+#elif defined(BCMPCIE)
+	if (conf->devid == BCM43751_D11AX_ID)
+#endif
+	{
+		if (FW_SUPPORTED(dhd, mbo)) {
+			char he_features[] = "he=enab 0,he=features 0";
+			dhd_conf_set_wl_cmd(dhd, he_features, TRUE);
+		}
+	}
+#endif
+#ifdef UPDATE_MODULE_NAME
+	dhd_conf_compat_func(dhd);
+#endif
+#ifndef SUPPORT_RANDOM_MAC_SCAN
+	{
+		char scanmac[] = "scanmac=enable 0";
+		dhd_conf_set_wl_cmd(dhd, scanmac, TRUE);
+	}
+#endif
+	if (conf->chip == BCM4381_CHIP_ID) {
+		char ampdu_hostreorder[] = "ampdu_hostreorder=1";
+		dhd_conf_set_wl_cmd(dhd, ampdu_hostreorder, TRUE);
+	}
+	dhd_conf_set_wl_cmd(dhd, conf->wl_preinit, TRUE);
+
+#ifndef WL_CFG80211
+	dhd_conf_set_intiovar(dhd, 0, WLC_UP, "WLC_UP", 0, 0, FALSE);
+#endif
+
+}
+
+void
+dhd_conf_free_preinit(dhd_pub_t *dhd)
+{
+	struct dhd_conf *conf = dhd->conf;
+
+#ifdef SET_FWNV_BY_MAC
+	dhd_conf_free_mac_list(&conf->fw_by_mac);
+	dhd_conf_free_mac_list(&conf->nv_by_mac);
+#endif
+	dhd_conf_free_chip_nv_path_list(&conf->nv_by_chip);
+	dhd_conf_free_country_list(conf);
+	if (conf->ccode_all_list) {
+		kfree(conf->ccode_all_list);
+		conf->ccode_all_list = NULL;
+	}
+	dhd_conf_free_mchan_list(conf);
+#ifdef PKT_FILTER_SUPPORT
+	if (conf->magic_pkt_filter_add) {
+		kfree(conf->magic_pkt_filter_add);
+		conf->magic_pkt_filter_add = NULL;
+	}
+	conf->magic_pkt_hdr_len = 0;
+	conf->pkt_filter_cnt_default = 0;
+#endif
+	if (conf->wl_preinit) {
+		kfree(conf->wl_preinit);
+		conf->wl_preinit = NULL;
+	}
+	if (conf->wl_suspend) {
+		kfree(conf->wl_suspend);
+		conf->wl_suspend = NULL;
+	}
+	if (conf->wl_resume) {
+		kfree(conf->wl_resume);
+		conf->wl_resume = NULL;
+	}
+	if (conf->wl_pre_in4way) {
+		kfree(conf->wl_pre_in4way);
+		conf->wl_pre_in4way = NULL;
+	}
+	if (conf->wl_post_in4way) {
+		kfree(conf->wl_post_in4way);
+		conf->wl_post_in4way = NULL;
+	}
+	if (conf->vndr_ie_assocreq) {
+		kfree(conf->vndr_ie_assocreq);
+		conf->vndr_ie_assocreq = NULL;
+	}
+}
+
+int
+dhd_conf_preinit(dhd_pub_t *dhd)
+{
+	struct dhd_conf *conf = dhd->conf;
+
+	CONFIG_TRACE("Enter\n");
+
+	dhd_conf_free_preinit(dhd);
+	conf->band = -1;
+	memset(&conf->bw_cap, -1, sizeof(conf->bw_cap));
+	conf->ap_mchan_mode = MCHAN_AUTO;
+	conf->go_mchan_mode = MCHAN_AUTO;
+	conf->csa = FALSE;
+	if (conf->chip == BCM4345_CHIP_ID || conf->chip == BCM4359_CHIP_ID ||
+			conf->chip == BCM43569_CHIP_ID ||
+			conf->chip == BCM4375_CHIP_ID) {
+		strcpy(conf->cspec.country_abbrev, "CN");
+		strcpy(conf->cspec.ccode, "CN");
+		conf->cspec.rev = 38;
+	}
+	else if ((conf->chip == BCM43752_CHIP_ID && conf->chiprev == 4) ||
+			conf->chip == BCM43756_CHIP_ID || conf->chip == BCM43711_CHIP_ID ||
+			conf->chip == BCM4381_CHIP_ID || conf->chip == BCM4382_CHIP_ID ||
+			conf->chip == BCM4383_CHIP_ID) {
+		strcpy(conf->cspec.country_abbrev, "US");
+		strcpy(conf->cspec.ccode, "US");
+		conf->cspec.rev = 0;
+	}
+	else {
+		strcpy(conf->cspec.country_abbrev, "CN");
+		strcpy(conf->cspec.ccode, "CN");
+		conf->cspec.rev = 0;
+	}
+	memset(&conf->ccode_all.cspec, 0, sizeof(wl_country_t));
+//	strcpy(conf->ccode_all.cspec.ccode, "AA");
+	conf->ccode_all.ww_2g_chan_only = 0x2;
+
+	conf->ioctl_ver = WLC_IOCTL_VERSION;
+	conf->roam_off = 1;
+	conf->roam_off_suspend = 1;
+	conf->roam_trigger[0] = -65;
+	conf->roam_trigger[1] = WLC_BAND_ALL;
+	conf->roam_scan_period[0] = 10;
+	conf->roam_scan_period[1] = WLC_BAND_ALL;
+	conf->roam_delta[0] = 10;
+	conf->roam_delta[1] = WLC_BAND_ALL;
+	conf->fullroamperiod = 20;
+#ifdef WL_SCHED_SCAN
+	conf->max_sched_scan_reqs = -1;
+#endif /* WL_SCHED_SCAN */
+	conf->keep_alive_period = 30000;
+#ifdef ARP_OFFLOAD_SUPPORT
+	conf->garp = FALSE;
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2))
+	wl_reassoc_support = TRUE;
+#endif
+	conf->force_wme_ac = 0;
+	memset(&conf->wme_sta, 0, sizeof(wme_param_t));
+	memset(&conf->wme_ap, 0, sizeof(wme_param_t));
+#ifdef PKT_FILTER_SUPPORT
+	memset(&conf->pkt_filter_add, 0, sizeof(conf_pkt_filter_add_t));
+	memset(&conf->pkt_filter_del, 0, sizeof(conf_pkt_filter_del_t));
+#endif
+	conf->srl = -1;
+	conf->lrl = -1;
+	conf->bcn_timeout = 16;
+	conf->disable_proptx = -1;
+	conf->dhd_poll = -1;
+#ifdef BCMSDIO
+	conf->use_rxchain = 0;
+	conf->bus_rxglom = TRUE;
+	conf->txglom_ext = FALSE;
+	conf->tx_max_offset = 0;
+	conf->txglomsize = SDPCM_DEFGLOM_SIZE;
+	conf->txctl_tmo_fix = 300;
+	conf->txglom_mode = SDPCM_TXGLOM_CPY;
+	conf->deferred_tx_len = 0;
+	conf->dhd_txminmax = 1;
+	conf->txinrx_thres = -1;
+#ifdef MINIME
+	conf->ramsize = 0x80000;
+#endif
+#if defined(SDIO_ISR_THREAD)
+	conf->intr_extn = FALSE;
+#endif
+#ifdef BCMSDIO_RXLIM_POST
+	conf->rxlim_en = FALSE;
+#endif
+#ifdef BCMSDIO_TXSEQ_SYNC
+	conf->txseq_sync = FALSE;
+#endif
+#if defined(HW_OOB)
+	conf->oob_enabled_later = FALSE;
+#endif
+#ifdef BCMSDIO_INTSTATUS_WAR
+	conf->read_intr_mode = 0;
+#endif
+	conf->kso_try_max = 0;
+#ifdef KSO_DEBUG
+	memset(&conf->kso_try_array, 0, sizeof(conf->kso_try_array));
+#endif
+#endif
+#ifdef BCMPCIE
+	conf->bus_deepsleep_disable = -1;
+	conf->flow_ring_queue_threshold = FLOW_RING_QUEUE_THRESHOLD;
+	conf->d2h_intr_method = -1;
+	conf->d2h_intr_control = -1;
+	conf->aspm = -1;
+	conf->l1ss = -1;
+	conf->enq_hdr_pkt = 0;
+#endif
+	conf->dpc_cpucore = -1;
+	conf->rxf_cpucore = -1;
+	conf->dhd_dpc_prio = -1;
+	conf->frameburst = -1;
+	conf->deepsleep = FALSE;
+	conf->pm = -1;
+	conf->pm_in_suspend = -1;
+	conf->insuspend = 0;
+	conf->suspend_mode = PM_NOTIFIER;
+#ifndef WL_CFG80211
+	conf->suspend_bcn_li_dtim = 3;
+#else
+	conf->suspend_bcn_li_dtim = -1;
+#endif
+	conf->rekey_offload = FALSE;
+#ifdef WL_EXT_WOWL
+	dhd_master_mode = TRUE;
+	conf->wowl = WL_WOWL_NET|WL_WOWL_DIS|WL_WOWL_BCN;
+#ifdef BCMDBUS
+	conf->wowl_dngldown = 0;
+#endif
+	conf->insuspend |= (WOWL_IN_SUSPEND | NO_TXDATA_IN_SUSPEND);
+#endif
+	if (conf->suspend_mode == PM_NOTIFIER || conf->suspend_mode == SUSPEND_MODE_2)
+		conf->insuspend |= (NO_TXDATA_IN_SUSPEND | NO_TXCTL_IN_SUSPEND);
+	conf->suspended = FALSE;
+	memset(&conf->bssid_insuspend, 0, ETHER_ADDR_LEN);
+#ifdef SUSPEND_EVENT
+	memset(&conf->resume_eventmask, 0, sizeof(conf->resume_eventmask));
+	conf->wlfc = FALSE;
+#endif
+#ifdef GET_CUSTOM_MAC_FROM_CONFIG
+	memset(&conf->hw_ether, 0, sizeof(conf->hw_ether));
+#endif
+#ifdef IDHCP
+	conf->dhcpc_enable = -1;
+	conf->dhcpd_enable = -1;
+#endif
+#ifdef DHDTCPACK_SUPPRESS
+#ifdef BCMPCIE
+	conf->tcpack_sup_mode = TCPACK_SUP_HOLD;
+#else
+	conf->tcpack_sup_mode = TCPACK_SUP_OFF;
+#endif
+	conf->tcpack_sup_ratio = CUSTOM_TCPACK_SUPP_RATIO;
+	conf->tcpack_sup_delay = CUSTOM_TCPACK_DELAY_TIME;
+#endif
+	conf->pktprio8021x = -1;
+	conf->ctrl_resched = 2;
+	conf->rxcnt_timeout = 3;
+	conf->in4way = STA_NO_SCAN_IN4WAY | STA_WAIT_DISCONNECTED |
+		AP_WAIT_STA_RECONNECT;
+#ifdef WL_EXT_RECONNECT
+	conf->in4way |= STA_REASSOC_RETRY;
+#endif
+	if (conf->chip == BCM43752_CHIP_ID)
+		conf->war = SET_CHAN_INCONN | FW_REINIT_INCSA | FW_REINIT_EMPTY_SCAN |
+			FW_REINIT_RXF0OVFL;
+	else if (conf->chip == BCM43711_CHIP_ID)
+		conf->war = SET_CHAN_INCONN;
+	else
+		conf->war = 0;
+#ifdef EAPOL_RESEND
+	conf->war |= RESEND_EAPOL_PKT;
+#endif
+#ifdef P2P_AP_CONCURRENT
+	conf->war |= P2P_AP_MAC_CONFLICT;
+#endif
+#ifdef PROPTX_MAXCOUNT
+	conf->proptx_maxcnt_2g = 46;
+	conf->proptx_maxcnt_5g = WL_TXSTATUS_FREERUNCTR_MASK;
+#endif /* DYNAMIC_PROPTX_MAXCOUNT */
+#ifdef TPUT_MONITOR
+	conf->tput_monitor_ms = 0;
+#ifdef BCMSDIO
+	if (conf->chip == BCM43752_CHIP_ID || conf->chip == BCM43756_CHIP_ID ||
+			conf->chip == BCM43711_CHIP_ID ||
+			conf->chip == BCM4381_CHIP_ID || conf->chip == BCM4382_CHIP_ID ||
+			conf->chip == BCM4383_CHIP_ID)
+		conf->doflow_tput_thresh = 200;
+	else
+		conf->doflow_tput_thresh = 9999;
+	if (conf->doflow_tput_thresh > 0 && conf->doflow_tput_thresh < 9999)
+		conf->tput_monitor_ms = 1000;
+#endif
+#endif
+#ifdef SCAN_SUPPRESS
+	conf->scan_intput = SCAN_CURCHAN_INTPUT;
+	conf->scan_busy_thresh = 10;
+	conf->scan_busy_tmo = 120;
+	if (conf->chip == BCM43752_CHIP_ID || conf->chip == BCM4375_CHIP_ID ||
+			conf->chip == BCM43756_CHIP_ID || conf->chip == BCM43711_CHIP_ID ||
+			conf->chip == BCM4381_CHIP_ID || conf->chip == BCM4382_CHIP_ID ||
+			conf->chip == BCM4383_CHIP_ID)
+		conf->scan_tput_thresh = 100;
+	else
+		conf->scan_tput_thresh = 9999;
+	if (conf->scan_tput_thresh > 0 && conf->scan_tput_thresh < 9999)
+		conf->tput_monitor_ms = 1000;
+#endif
+#ifdef DHD_TPUT_PATCH
+	conf->tput_patch = FALSE;
+	conf->mtu = 0;
+	conf->pktsetsum = FALSE;
+#endif
+#ifdef SET_XPS_CPUS
+	conf->xps_cpus = FALSE;
+#endif
+#ifdef SET_RPS_CPUS
+	conf->rps_cpus = FALSE;
+#endif
+#ifdef CHECK_DOWNLOAD_FW
+	conf->fwchk = FALSE;
+#endif
+#ifdef ISAM_PREINIT
+	memset(conf->isam_init, 0, sizeof(conf->isam_init));
+	memset(conf->isam_config, 0, sizeof(conf->isam_config));
+	memset(conf->isam_enable, 0, sizeof(conf->isam_enable));
+#endif
+#if defined(SDIO_ISR_THREAD)
+	dhd_conf_set_intr_extn(dhd);
+#endif
+	dhd_conf_tput_improve(dhd);
+#ifdef DHD_TPUT_PATCH
+	if (conf->chip == BCM43752_CHIP_ID || conf->chip == BCM4375_CHIP_ID ||
+			conf->chip == BCM43756_CHIP_ID || conf->chip == BCM43711_CHIP_ID ||
+			conf->chip == BCM4381_CHIP_ID || conf->chip == BCM4382_CHIP_ID ||
+			conf->chip == BCM4383_CHIP_ID) {
+		conf->tput_patch = TRUE;
+		dhd_conf_set_tput_patch(dhd);
+	}
+#endif
+
+#ifdef BCMSDIO
+	if (conf->txglomsize > SDPCM_MAXGLOM_SIZE)
+		conf->txglomsize = SDPCM_MAXGLOM_SIZE;
+#endif
+	init_waitqueue_head(&conf->event_complete);
+
+	return 0;
+}
+
+int
+dhd_conf_reset(dhd_pub_t *dhd)
+{
+	struct dhd_conf *conf = dhd->conf;
+
+	dhd_conf_free_preinit(dhd);
+	memset(conf, 0, sizeof(dhd_conf_t));
+	return 0;
+}
+
+int
+dhd_conf_attach(dhd_pub_t *dhd)
+{
+	dhd_conf_t *conf;
+
+	CONFIG_TRACE("Enter\n");
+
+	if (dhd->conf != NULL) {
+		CONFIG_MSG("config is attached before!\n");
+		return 0;
+	}
+	/* Allocate private bus interface state */
+	if (!(conf = MALLOC(dhd->osh, sizeof(dhd_conf_t)))) {
+		CONFIG_ERROR("MALLOC failed\n");
+		goto fail;
+	}
+	memset(conf, 0, sizeof(dhd_conf_t));
+
+	dhd->conf = conf;
+
+	return 0;
+
+fail:
+	if (conf != NULL)
+		MFREE(dhd->osh, conf, sizeof(dhd_conf_t));
+	return BCME_NOMEM;
+}
+
+void
+dhd_conf_detach(dhd_pub_t *dhd)
+{
+	struct dhd_conf *conf = dhd->conf;
+
+	CONFIG_TRACE("Enter\n");
+	if (dhd->conf) {
+		dhd_conf_free_preinit(dhd);
+		MFREE(dhd->osh, conf, sizeof(dhd_conf_t));
+	}
+	dhd->conf = NULL;
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_config.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_config.h
@@ -0,0 +1,493 @@
+
+#ifndef _dhd_config_
+#define _dhd_config_
+
+#include <bcmdevs.h>
+#include <siutils.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <wlioctl.h>
+#include <802.11.h>
+
+/* message levels */
+#define CONFIG_ERROR_LEVEL	(1 << 0)
+#define CONFIG_TRACE_LEVEL	(1 << 1)
+#define CONFIG_MSG_LEVEL	(1 << 0)
+
+#define FW_TYPE_STA     0
+#define FW_TYPE_APSTA   1
+#define FW_TYPE_P2P     2
+#define FW_TYPE_MESH    3
+#define FW_TYPE_EZMESH  4
+#define FW_TYPE_ES      5
+#define FW_TYPE_MFG     6
+#define FW_TYPE_MINIME  7
+
+#define FW_PATH_AUTO_SELECT 1
+#ifdef BCMDHD_MDRIVER
+#define CONFIG_PATH_AUTO_SELECT
+#else
+//#define CONFIG_PATH_AUTO_SELECT
+#endif
+extern char firmware_path[MOD_PARAM_PATHLEN];
+#ifdef RMMOD_POWER_DOWN_LATER
+extern atomic_t exit_in_progress;
+extern bool is_power_on;
+#endif
+#if defined(BCMSDIO)
+extern uint dhd_rxbound;
+extern uint dhd_txbound;
+#endif
+#ifdef BCMSDIO
+#define TXGLOM_RECV_OFFSET 8
+extern uint dhd_doflow;
+extern uint dhd_slpauto;
+#endif
+
+#ifdef SET_FWNV_BY_MAC
+typedef struct wl_mac_range {
+	uint32 oui;
+	uint32 nic_start;
+	uint32 nic_end;
+} wl_mac_range_t;
+
+typedef struct wl_mac_list {
+	int count;
+	wl_mac_range_t *mac;
+	char name[MOD_PARAM_PATHLEN];
+} wl_mac_list_t;
+
+typedef struct wl_mac_list_ctrl {
+	int count;
+	struct wl_mac_list *m_mac_list_head;
+} wl_mac_list_ctrl_t;
+#endif
+
+typedef struct wl_chip_nv_path {
+	uint chip;
+	uint chiprev;
+	char name[MOD_PARAM_PATHLEN];
+} wl_chip_nv_path_t;
+
+typedef struct wl_chip_nv_path_list_ctrl {
+	int count;
+	struct wl_chip_nv_path *m_chip_nv_path_head;
+} wl_chip_nv_path_list_ctrl_t;
+
+typedef struct wmes_param {
+	int aifsn[AC_COUNT];
+	int ecwmin[AC_COUNT];
+	int ecwmax[AC_COUNT];
+	int txop[AC_COUNT];
+} wme_param_t;
+
+#ifdef PKT_FILTER_SUPPORT
+#define DHD_CONF_FILTER_MAX	8
+#define PKT_FILTER_LEN 300
+#define MAGIC_PKT_FILTER_LEN 450
+typedef struct conf_pkt_filter_add {
+	uint32 count;
+	char filter[DHD_CONF_FILTER_MAX][PKT_FILTER_LEN];
+} conf_pkt_filter_add_t;
+
+typedef struct conf_pkt_filter_del {
+	uint32 count;
+	uint32 id[DHD_CONF_FILTER_MAX];
+} conf_pkt_filter_del_t;
+#endif
+
+#define CONFIG_COUNTRY_LIST_SIZE 500
+typedef struct country_list {
+	struct country_list *next;
+	wl_country_t cspec;
+} country_list_t;
+
+typedef struct wl_ccode_all {
+	wl_country_t cspec;
+	int32 ww_2g_chan_only;
+	int32 disable_5g_band;
+	int32 disable_6g_band;
+} wl_ccode_all_t;
+
+/* mchan_params */
+#define MCHAN_MAX_NUM 4
+#define MIRACAST_SOURCE	1
+#define MIRACAST_SINK	2
+typedef struct mchan_params {
+	struct mchan_params *next;
+	int bw;
+	int p2p_mode;
+	int miracast_mode;
+} mchan_params_t;
+
+typedef enum MCHAN_MODE {
+	MCHAN_AUTO = -1,	/* Auto selection by Chip */
+	MCHAN_SCC = 0,		/* Same Channel Concurrent */
+	MCHAN_SBSC = 1,		/* Same Band Same Channel concurrent */
+	MCHAN_MCC = 2,		/* Multiple Channel Concurrent */
+	MCHAN_RSDB = 3		/* RSDB concurrent */
+} mchan_mode_t;
+
+#ifdef SCAN_SUPPRESS
+enum scan_intput_flags {
+	NO_SCAN_INTPUT	= (1 << (0)),
+	SCAN_CURCHAN_INTPUT	= (1 << (1)),
+	SCAN_LIGHT_INTPUT	= (1 << (2)),
+};
+#endif
+
+enum war_flags {
+	SET_CHAN_INCONN	= (1 << (0)),
+	FW_REINIT_INCSA	= (1 << (1)),
+	FW_REINIT_EMPTY_SCAN	= (1 << (2)),
+	P2P_AP_MAC_CONFLICT	= (1 << (3)),
+	RESEND_EAPOL_PKT	= (1 << (4)),
+	FW_REINIT_RXF0OVFL	= (1 << (5))
+};
+
+enum in4way_flags {
+	STA_NO_SCAN_IN4WAY	= (1 << (0)),
+	STA_NO_BTC_IN4WAY	= (1 << (1)),
+	STA_WAIT_DISCONNECTED	= (1 << (2)),
+	AP_WAIT_STA_RECONNECT	= (1 << (3)),
+	STA_FAKE_SCAN_IN_CONNECT	= (1 << (4)),
+	STA_REASSOC_RETRY	= (1 << (5)),
+};
+
+enum in_suspend_flags {
+	NO_EVENT_IN_SUSPEND		= (1 << (0)),
+	NO_TXDATA_IN_SUSPEND	= (1 << (1)),
+	NO_TXCTL_IN_SUSPEND		= (1 << (2)),
+	AP_DOWN_IN_SUSPEND		= (1 << (3)),
+	ROAM_OFFLOAD_IN_SUSPEND	= (1 << (4)),
+	AP_FILTER_IN_SUSPEND	= (1 << (5)),
+	WOWL_IN_SUSPEND			= (1 << (6)),
+	ALL_IN_SUSPEND 			= 0xFFFFFFFF,
+};
+
+enum in_suspend_mode {
+	EARLY_SUSPEND = 0,
+	PM_NOTIFIER = 1,
+	SUSPEND_MODE_2 = 2
+};
+
+enum hostsleep_mode {
+	HOSTSLEEP_CLEAR = 0,
+	HOSTSLEEP_FW_SET = 1,
+	HOSTSLEEP_DHD_SET = 2,
+};
+
+enum conn_state {
+	CONN_STATE_IDLE = 0,
+	CONN_STATE_CONNECTING = 1,
+	CONN_STATE_AUTH_SAE_M1 = 2,
+	CONN_STATE_AUTH_SAE_M2 = 3,
+	CONN_STATE_AUTH_SAE_M3 = 4,
+	CONN_STATE_AUTH_SAE_M4 = 5,
+	CONN_STATE_ASSOCIATED = 6,
+	CONN_STATE_REQID = 7,
+	CONN_STATE_RSPID = 8,
+	CONN_STATE_WSC_START = 9,
+	CONN_STATE_WPS_M1 = 10,
+	CONN_STATE_WPS_M2 = 11,
+	CONN_STATE_WPS_M3 = 12,
+	CONN_STATE_WPS_M4 = 13,
+	CONN_STATE_WPS_M5 = 14,
+	CONN_STATE_WPS_M6 = 15,
+	CONN_STATE_WPS_M7 = 16,
+	CONN_STATE_WPS_M8 = 17,
+	CONN_STATE_WSC_DONE = 18,
+	CONN_STATE_4WAY_M1 = 19,
+	CONN_STATE_4WAY_M2 = 20,
+	CONN_STATE_4WAY_M3 = 21,
+	CONN_STATE_4WAY_M4 = 22,
+	CONN_STATE_ADD_KEY = 23,
+	CONN_STATE_CONNECTED = 24,
+	CONN_STATE_GROUPKEY_M1 = 25,
+	CONN_STATE_GROUPKEY_M2 = 26,
+};
+
+enum enq_pkt_type {
+	ENQ_PKT_TYPE_EAPOL	= (1 << (0)),
+	ENQ_PKT_TYPE_ARP	= (1 << (1)),
+	ENQ_PKT_TYPE_DHCP	= (1 << (2)),
+	ENQ_PKT_TYPE_ICMP	= (1 << (3)),
+};
+
+typedef struct dhd_conf {
+	uint devid;
+	uint chip;
+	uint chiprev;
+#if defined(BCMPCIE)
+	uint svid;
+	uint ssid;
+#endif
+#ifdef GET_OTP_MODULE_NAME
+	char module_name[16];
+#endif
+	struct ether_addr otp_mac;
+	int fw_type;
+#ifdef SET_FWNV_BY_MAC
+	wl_mac_list_ctrl_t fw_by_mac;
+	wl_mac_list_ctrl_t nv_by_mac;
+#endif
+	wl_chip_nv_path_list_ctrl_t nv_by_chip;
+	country_list_t *country_head;
+	char *ccode_all_list;
+	wl_ccode_all_t ccode_all;
+	int ioctl_ver;
+	int band;
+	int bw_cap[2];
+	int ap_mchan_mode;
+	int go_mchan_mode;
+	bool csa;
+	wl_country_t cspec;
+	uint roam_off;
+	uint roam_off_suspend;
+	int roam_trigger[2];
+	int roam_scan_period[2];
+	int roam_delta[2];
+	int fullroamperiod;
+#ifdef WL_SCHED_SCAN
+	int max_sched_scan_reqs;
+#endif /* WL_SCHED_SCAN */
+	uint keep_alive_period;
+	bool rekey_offload;
+#ifdef ARP_OFFLOAD_SUPPORT
+	bool garp;
+#endif
+	int force_wme_ac;
+	wme_param_t wme_sta;
+	wme_param_t wme_ap;
+#ifdef PKT_FILTER_SUPPORT
+	conf_pkt_filter_add_t pkt_filter_add;
+	conf_pkt_filter_del_t pkt_filter_del;
+	char *magic_pkt_filter_add;
+	int magic_pkt_hdr_len;
+	int pkt_filter_cnt_default;
+#endif
+	int srl;
+	int lrl;
+	uint bcn_timeout;
+	int disable_proptx;
+	int dhd_poll;
+#ifdef BCMSDIO
+	int use_rxchain;
+	bool bus_rxglom;
+	bool txglom_ext; /* Only for 43362/4330/43340/43341/43241 */
+	/* terence 20161011:
+	    1) conf->tx_max_offset = 1 to fix credict issue in adaptivity testing
+	    2) conf->tx_max_offset = 1 will cause to UDP Tx not work in rxglom supported,
+	        but not happened in sw txglom
+	*/
+	int tx_max_offset;
+	uint txglomsize;
+	int txctl_tmo_fix;
+	bool txglom_mode;
+	uint deferred_tx_len;
+	/*txglom_bucket_size:
+	 * 43362/4330: 1680
+	 * 43340/43341/43241: 1684
+	 */
+	int txglom_bucket_size;
+	int txinrx_thres;
+	int dhd_txminmax; // -1=DATABUFCNT(bus)
+#ifdef DYNAMIC_MAX_HDR_READ
+	int max_hdr_read;
+#endif
+	bool oob_enabled_later;
+#ifdef MINIME
+	uint32 ramsize;
+#endif
+#if defined(SDIO_ISR_THREAD)
+	bool intr_extn;
+#endif
+#ifdef BCMSDIO_RXLIM_POST
+	bool rxlim_en;
+#endif
+#ifdef BCMSDIO_TXSEQ_SYNC
+	bool txseq_sync;
+#endif
+#ifdef BCMSDIO_INTSTATUS_WAR
+	uint read_intr_mode;
+#endif
+	int kso_try_max;
+#ifdef KSO_DEBUG
+	uint kso_try_array[10];
+#endif
+#endif
+#ifdef BCMPCIE
+	int bus_deepsleep_disable;
+	int flow_ring_queue_threshold;
+	int d2h_intr_method;
+	int d2h_intr_control;
+	int enq_hdr_pkt;
+	int aspm;
+	int l1ss;
+#endif
+	int dpc_cpucore;
+	int rxf_cpucore;
+	int dhd_dpc_prio;
+	int frameburst;
+	bool deepsleep;
+	int pm;
+	int pm_in_suspend;
+	int suspend_mode;
+	int suspend_bcn_li_dtim;
+#ifdef DHDTCPACK_SUPPRESS
+	uint8 tcpack_sup_mode;
+	uint32 tcpack_sup_ratio;
+	uint32 tcpack_sup_delay;
+#endif
+	int pktprio8021x;
+	uint insuspend;
+	bool suspended;
+	struct ether_addr bssid_insuspend;
+#ifdef SUSPEND_EVENT
+	char resume_eventmask[WL_EVENTING_MASK_LEN];
+	bool wlfc;
+#endif
+#ifdef IDHCP
+	int dhcpc_enable;
+	int dhcpd_enable;
+	struct ipv4_addr dhcpd_ip_addr;
+	struct ipv4_addr dhcpd_ip_mask;
+	struct ipv4_addr dhcpd_ip_start;
+	struct ipv4_addr dhcpd_ip_end;
+#endif
+#ifdef ISAM_PREINIT
+	char isam_init[50];
+	char isam_config[300];
+	char isam_enable[50];
+#endif
+	int ctrl_resched;
+	uint rxcnt_timeout;
+	mchan_params_t *mchan;
+	char *wl_preinit;
+	char *wl_suspend;
+	char *wl_resume;
+	uint in4way;
+	char *wl_pre_in4way;
+	char *wl_post_in4way;
+	uint war;
+#ifdef WL_EXT_WOWL
+	uint wowl;
+#ifdef BCMDBUS
+	uint wowl_dngldown;
+#endif
+#endif
+#ifdef GET_CUSTOM_MAC_FROM_CONFIG
+	char hw_ether[62];
+#endif
+	wait_queue_head_t event_complete;
+#ifdef PROPTX_MAXCOUNT
+	int proptx_maxcnt_2g;
+	int proptx_maxcnt_5g;
+#endif /* DYNAMIC_PROPTX_MAXCOUNT */
+#ifdef TPUT_MONITOR
+	uint tput_monitor_ms;
+	struct osl_timespec tput_ts;
+	unsigned long last_tx;
+	unsigned long last_rx;
+#ifdef BCMSDIO
+	int32 doflow_tput_thresh;
+#endif
+#endif
+#ifdef SCAN_SUPPRESS
+	uint scan_intput;
+	int scan_busy_thresh;
+	int scan_busy_tmo;
+	int32 scan_tput_thresh;
+#endif
+#ifdef DHD_TPUT_PATCH
+	bool tput_patch;
+	int mtu;
+	bool pktsetsum;
+#endif
+#ifdef SET_XPS_CPUS
+	bool xps_cpus;
+#endif
+#ifdef SET_RPS_CPUS
+	bool rps_cpus;
+#endif
+#ifdef CHECK_DOWNLOAD_FW
+	bool fwchk;
+#endif
+	char *vndr_ie_assocreq;
+} dhd_conf_t;
+
+#ifdef BCMSDIO
+void dhd_conf_get_otp(dhd_pub_t *dhd, bcmsdh_info_t *sdh, si_t *sih);
+void dhd_conf_set_txglom_params(dhd_pub_t *dhd, bool enable);
+bool dhd_conf_legacy_otp_chip(dhd_pub_t *dhd);
+#endif
+#ifdef BCMPCIE
+bool dhd_conf_legacy_msi_chip(dhd_pub_t *dhd);
+#if defined(BCMPCIE_CTO_PREVENTION)
+bool dhd_conf_legacy_cto_chip(uint16 chip);
+#endif
+#endif
+#ifdef WL_CFG80211
+bool dhd_conf_legacy_chip_check(dhd_pub_t *dhd);
+bool dhd_conf_new_chip_check(dhd_pub_t *dhd);
+bool dhd_conf_extsae_chip(dhd_pub_t *dhd);
+#endif
+void dhd_conf_set_path_params(dhd_pub_t *dhd, char *fw_path, char *nv_path);
+int dhd_conf_set_intiovar(dhd_pub_t *dhd, int ifidx, uint cmd, char *name,
+	int val, int def, bool down);
+int dhd_conf_get_band(dhd_pub_t *dhd);
+bool dhd_conf_same_country(dhd_pub_t *dhd, char *buf);
+int dhd_conf_country(dhd_pub_t *dhd, char *cmd, char *buf);
+int dhd_conf_get_country(dhd_pub_t *dhd, wl_country_t *cspec);
+#ifdef CCODE_LIST
+int dhd_ccode_map_country_all(dhd_pub_t *dhd, wl_country_t *cspec);
+int dhd_ccode_map_country_list(dhd_pub_t *dhd, wl_country_t *cspec);
+#endif
+void dhd_conf_set_wme(dhd_pub_t *dhd, int ifidx, int mode);
+void dhd_conf_set_mchan_bw(dhd_pub_t *dhd, int go, int source);
+void dhd_conf_add_pkt_filter(dhd_pub_t *dhd);
+bool dhd_conf_del_pkt_filter(dhd_pub_t *dhd, uint32 id);
+void dhd_conf_discard_pkt_filter(dhd_pub_t *dhd);
+int dhd_conf_read_config(dhd_pub_t *dhd, char *conf_path);
+int dhd_conf_set_chiprev(dhd_pub_t *dhd, uint chip, uint chiprev);
+uint dhd_conf_get_chip(void *context);
+uint dhd_conf_get_chiprev(void *context);
+int dhd_conf_get_pm(dhd_pub_t *dhd);
+int dhd_conf_custom_mac(dhd_pub_t *dhd);
+int dhd_conf_reg2args(dhd_pub_t *dhd, char *cmd, bool set, uint32 index, uint32 *val);
+bool dhd_conf_set_wl_cmd(dhd_pub_t *dhd, char *data, bool down);
+int dhd_conf_check_hostsleep(dhd_pub_t *dhd, int cmd, void *buf, int len,
+	int *hostsleep_set, int *hostsleep_val, int *ret);
+void dhd_conf_get_hostsleep(dhd_pub_t *dhd,
+	int hostsleep_set, int hostsleep_val, int ret);
+int dhd_conf_mkeep_alive(dhd_pub_t *dhd, int ifidx, int id, int period,
+	char *packet, bool bcast);
+#ifdef ARP_OFFLOAD_SUPPORT
+void dhd_conf_set_garp(dhd_pub_t *dhd, int ifidx, uint32 ipa, bool enable);
+#endif
+#ifdef PROP_TXSTATUS
+int dhd_conf_get_disable_proptx(dhd_pub_t *dhd);
+#endif
+#ifdef TPUT_MONITOR
+void dhd_conf_tput_monitor(dhd_pub_t *dhd);
+#endif
+uint dhd_conf_get_insuspend(dhd_pub_t *dhd, uint mask);
+int dhd_conf_set_suspend_resume(dhd_pub_t *dhd, int suspend);
+void dhd_conf_postinit_ioctls(dhd_pub_t *dhd);
+void dhd_conf_preinit_ioctls_sta(dhd_pub_t *dhd, int ifidx);
+int dhd_conf_preinit(dhd_pub_t *dhd);
+int dhd_conf_reset(dhd_pub_t *dhd);
+int dhd_conf_attach(dhd_pub_t *dhd);
+void dhd_conf_detach(dhd_pub_t *dhd);
+void *dhd_get_pub(struct net_device *dev);
+int wl_pattern_atoh(char *src, char *dst);
+int dhd_conf_suspend_resume_sta(dhd_pub_t *dhd, int ifidx, int suspend);
+/* Add to adjust 802.1x priority */
+extern void pktset8021xprio(void *pkt, int prio);
+#if defined(BCMSDIO) || defined(BCMPCIE) || defined(BCMDBUS)
+extern int dhd_bus_sleep(dhd_pub_t *dhdp, bool sleep, uint32 *intstatus);
+#endif
+#ifdef WL_EXT_WOWL
+int dhd_conf_wowl_dngldown(dhd_pub_t *dhd);
+#endif
+#endif /* _dhd_config_ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_csi.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_csi.c
@@ -0,0 +1,1617 @@
+/*
+ * Broadcom Dongle Host Driver (DHD), Channel State information Module
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <linux/list.h>
+#include <linux/sort.h>
+#include <linux/inetdevice.h> /* for '__in_dev_get_rcu' */
+
+#include "osl.h"
+#include "bcmutils.h"
+#include "bcmendian.h"
+#include "linuxver.h"
+#include "dngl_stats.h"
+#include "wlioctl.h"
+#include "bcmevent.h"
+#include "dhd.h"
+#include "dhd_dbg.h"
+#include "dhd_csi.h"
+#include "dhd_linux.h"
+#include "bcmudp.h"
+#include "bcmdevs.h"
+
+/* For kernel < 3.12 */
+#ifndef list_last_entry
+#define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member)
+#endif /* list_last_entry */
+
+#ifdef BCMDHDUSB
+#define dhd_bus_chip_id(dhdp)    0x0
+#endif /* BCMDHDUSB */
+
+#ifdef CSI_SUPPORT
+
+#define SYNA_ALIGN_BYTES      (sizeof(uint32))
+#define SYNA_ALIGN_PADDING    (SYNA_ALIGN_BYTES -1LL)
+#define SYNA_ALIGN_MASK       (~SYNA_ALIGN_PADDING)
+#define SYNA_ALIGN(value) \
+(\
+	(SYNA_ALIGN_PADDING + ((long long int)(value))) \
+	& SYNA_ALIGN_MASK \
+)
+
+#define SYNA_SOCKET_PORT_DEFAULT           (9999)
+
+static const uint8  _gpMAC_zero[6] = {0, 0, 0, 0, 0, 0};
+static const uint8  gpDHD_csi_network_template[14 + 20 + 8] = {
+	/* ethernet header(14) */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x08, 0x00,
+	/* ip header(20) */
+	0x45, 0x00,
+	0x00, 0x00, /* len */
+	0x00, 0x00, /* id */
+	0x00, 0x00, /* flags */
+	0x40, /* ttl */
+	0x11, /* protocol */
+	0x00, 0x00, /* checksum */
+	8, 8, 8, 8, /* src ip */
+	127, 0, 0, 1, /* dst ip */
+	/* udp header(8) */
+	0x00, 0x00, /* src port */
+	0x00, 0x00, /* dst port */
+	0x00, 0x00, /* length */
+	0x00, 0x00, /* checksum */
+	/* real syna csi header start from here */
+};
+
+struct syna_csi_rx_mode_config {
+	uint32  mode;
+
+	uint8   data_version;
+	uint8   data_header_version_output;
+	uint16  port;
+	uint32  ip;
+};
+
+static const struct {
+	uint         error_code;
+	const char  *error_string;
+} CONST_CSI_ERROR_STRING[] = {
+	{SYNA_CSI_FLAG_ERROR_NONE, "NONE"},
+	{SYNA_CSI_FLAG_ERROR_FAILURE, "FAILURE"},
+	{SYNA_CSI_FLAG_ERROR_CHECKSUM, "WRONG_CHECKSUM"},
+	{SYNA_CSI_FLAG_ERROR_GENERIC, "ERROR_GENERIC"},
+	{SYNA_CSI_FLAG_ERROR_OTHER, "ERROR_OTHER"},
+
+	{SYNA_CSI_FLAG_ERROR_WRONG_CHANNEL, "WRONG_CHANNEL"},
+	{SYNA_CSI_FLAG_ERROR_WRONG_MODE, "WRONG_MODE"},
+
+	{SYNA_CSI_FLAG_ERROR_TX_FAIL, "TX_FAIL"},
+	{SYNA_CSI_FLAG_ERROR_TX_NO_ACK, "TX_NO_ACK"},
+
+	{SYNA_CSI_FLAG_ERROR_DATA_FEEDBACK_MISS, "NO_DATA_FEEDBACK"},
+	{SYNA_CSI_FLAG_ERROR_TX_FEEDBACK_MISS, "NO_TX_FEEDBACK"},
+	{SYNA_CSI_FLAG_ERROR_POWERSAVING, "ERROR_POWERSAVING"},
+
+	{SYNA_CSI_FLAG_ERROR_SUPPRESS, "SUPPRESSED"},
+	{SYNA_CSI_FLAG_ERROR_SUPP_PMQ, "SUPPRESSED_PMQ"},
+	{SYNA_CSI_FLAG_ERROR_SUPP_FLUSH, "SUPPRESSED_FLUSH"},
+	{SYNA_CSI_FLAG_ERROR_SUPP_FRAG, "SUPPRESSED_FRAG"},
+	{SYNA_CSI_FLAG_ERROR_SUPP_TBTT, "SUPPRESSED_TBTT"},
+	{SYNA_CSI_FLAG_ERROR_SUPP_BADCH, "SUPPRESSED_BADCH"},
+	{SYNA_CSI_FLAG_ERROR_SUPP_EXPTIME, "SUPPRESSED_EXPTIME"},
+	{SYNA_CSI_FLAG_ERROR_SUPP_UF, "SUPPRESSED_UF"},
+	{SYNA_CSI_FLAG_ERROR_SUPP_ABS, "SUPPRESSED_ABSENT"},
+	{SYNA_CSI_FLAG_ERROR_SUPP_PPS, "SUPPRESSED_PPS"},
+	{SYNA_CSI_FLAG_ERROR_SUPP_NOKEY, "SUPPRESSED_NOKEY"},
+	{SYNA_CSI_FLAG_ERROR_SUPP_DMA_XFER, "SUPPRESSED_DMA"},
+	{SYNA_CSI_FLAG_ERROR_SUPP_TWT, "SUPPRESSED_TWT"},
+
+	{SYNA_CSI_FLAG_ERROR_LAST, ""}
+};
+#define CONST_CSI_ERROR_STRING_SIZE    ARRAYSIZE(CONST_CSI_ERROR_STRING)
+
+static const char * dhd_csi_get_error_string(uint  error_code)
+{
+	const char  *error_string = NULL;
+	int i;
+
+	i = CONST_CSI_ERROR_STRING_SIZE - 1;
+	error_string = CONST_CSI_ERROR_STRING[i].error_string;
+	for (i = 0; i < (CONST_CSI_ERROR_STRING_SIZE - 1); i++) {
+		if (CONST_CSI_ERROR_STRING[i].error_code == error_code) {
+			error_string = CONST_CSI_ERROR_STRING[i].error_string;
+			break;
+		}
+	}
+
+	return error_string;
+}
+
+/* Different FW using different CSI data formats, and here
+ * the  DHD driver will directly convert input DATA to the
+ * common header format(latest full set version CSI header
+ * format which contains much more items), and then it will
+ * be converted to corresponding version CSI header which
+ * applicaiton required.
+ *
+ *        FW                   DHD-Driver                 Application
+ * dhd_cfr_header_rev_0 \
+ * dhd_cfr_header_rev_1  \                              / syna_csi_header_v1
+ * dhd_cfr_header_rev_2   --> syna_csi_common_header -->  syna_csi_header_v2
+ * dhd_cfr_header_rev_3  /                              \      ...
+ *     ...              /
+ */
+
+static struct csi_cfr_node *dhd_csi_allocate_pkt(dhd_pub_t *dhdp,
+                                                 uint       pkt_len)
+{
+	int                   ret = BCME_OK;
+	struct csi_cfr_node  *ptr = NULL;
+	uint8                *p = NULL;
+	uint                  total_size = 0;
+
+	if (SYNA_CSI_DATA_MODE_UDP_SOCKET == dhdp->csi_data_send_manner) {
+		void * skb = NULL;
+		total_size =   CONST_SYNA_CSI_CFR_NODE_LEN
+		             + sizeof(syna_csi_common_header)
+		             + pkt_len;
+		skb = PKTGET(dhdp->osh, total_size, TRUE);
+		if (!skb) {
+			DHD_ERROR(("%s-%d: *Error, malloc %d for cfr dump list error\n",
+			           __func__, __LINE__, total_size));
+			ret = BCME_NOMEM;
+			goto done;
+		}
+		p = PKTDATA(dhdp->osh, skb);
+		ptr = (struct csi_cfr_node *)p;
+		ptr->pNode = skb;
+		ptr->send_manner = dhdp->csi_data_send_manner;
+		ptr->total_size = total_size;
+		p += sizeof(struct csi_cfr_node);
+		ptr->pHeader_csi = (syna_csi_common_header *)p;
+	} else {
+		total_size =   sizeof(struct csi_cfr_node)
+		             + sizeof(syna_csi_common_header)
+		             + pkt_len;
+		p = MALLOCZ(dhdp->osh, total_size);
+		if (!p) {
+			DHD_ERROR(("%s-%d: *Error, malloc %d for cfr dump list error\n",
+			           __func__, __LINE__, total_size));
+			ret = BCME_NOMEM;
+			goto done;
+		}
+		ptr = (struct csi_cfr_node *)p;
+		ptr->pNode = p;
+		ptr->send_manner = dhdp->csi_data_send_manner;
+		ptr->total_size = total_size;
+		p += sizeof(struct csi_cfr_node);
+		ptr->pHeader_csi = (syna_csi_common_header *)p;
+	}
+
+done:
+	if (0 > ret) {
+		ptr = NULL;
+	}
+
+	return ptr;
+}
+
+static int dhd_csi_free_pkt(dhd_pub_t *dhdp,
+                            void      *p)
+{
+	struct csi_cfr_node  *ptr = p;
+	int                   ret = BCME_OK;
+
+	if (SYNA_CSI_DATA_MODE_UDP_SOCKET == ptr->send_manner) {
+		PKTFREE(dhdp->osh, ptr->pNode, FALSE);
+	} else {
+		MFREE(dhdp->osh, ptr->pNode, ptr->total_size);
+	}
+
+	return ret;
+}
+
+static int dhd_csi_data_output_common_to_v1(struct csi_cfr_node *ptr)
+{
+	syna_csi_common_header        *pCommon = ptr->pHeader_csi;
+	struct syna_csi_header_v1      v1, *pV1 = &(v1);
+	int                            len_common_header = 0;
+	int                            len_v1_header = 0;
+	int                            delta = 0;
+	int                            ret = BCME_OK;
+
+	len_common_header = sizeof(syna_csi_common_header);
+	len_v1_header     = sizeof(struct syna_csi_header_v1);
+
+	/* conversion from pCommon to pV1 */
+	memset(pV1, 0, len_v1_header);
+
+	pV1->magic_flag = pCommon->magic_flag;
+
+	pV1->version = pCommon->version;
+	pV1->format_type = pCommon->format_type;
+	pV1->fc = pCommon->frame_control;
+	pV1->flags = pCommon->flag_error;
+	if (SYNA_CSI_FLAG_FEATURE_FFT_NEGATIVE_FIRST & pCommon->flag_feature) {
+		pV1->flags |= SYNA_CSI_LEGACY_FLAG_FFT_NEGATIVE_FIRST;
+	}
+
+	memcpy(pV1->client_ea, pCommon->peer_mac,  ETHER_ADDR_LEN);
+	memcpy(pV1->bsscfg_ea, pCommon->local_mac, ETHER_ADDR_LEN);
+	pV1->band = pCommon->band;
+	pV1->bandwidth = pCommon->bandwidth;
+	pV1->channel = pCommon->channel;
+
+	pV1->report_tsf = pCommon->report_tsf;
+
+	pV1->num_txstream = pCommon->qty_txstream;
+	pV1->num_rxchain = pCommon->qty_rxchain;
+	pV1->num_subcarrier = pCommon->qty_subcarrier;
+
+	pV1->rssi = pCommon->rssi;
+	pV1->noise = pCommon->noise;
+	pV1->global_id = pCommon->global_id;
+
+	memcpy(pV1->rssi_ant, pCommon->rssi_ant, sizeof(pV1->rssi_ant));
+
+	pV1->data_length = pCommon->data_length;
+	pV1->data_checksum = pCommon->data_checksum;
+
+	/* length of 'pV1' is less than length of 'pCommon' */
+	delta  = len_common_header - len_v1_header;
+
+	ptr->pHeader_csi = (syna_csi_common_header *)(delta + ((unsigned char *)ptr->pHeader_csi));
+	memcpy(ptr->pHeader_csi, pV1, sizeof(struct syna_csi_header_v1));
+	ptr->convert_pull = delta;
+	ptr->length_data_total = pV1->data_length + sizeof(struct syna_csi_header_v1);
+
+	return ret;
+}
+
+static int dhd_csi_data_output_common_to_v2(struct csi_cfr_node *ptr)
+{
+	syna_csi_common_header      *pCommon = ptr->pHeader_csi;
+	struct syna_csi_header_v2    v2, *pV2 = &v2;
+	int                          delta = 0;
+	int                          ret = BCME_OK;
+
+	pCommon = ptr->pHeader_csi;
+
+	/* nothing to do when the 'syna_csi_common_header'
+	 * is mapping to the 'syna_csi_header_v2'
+	 */
+	UNUSED_PARAMETER(pCommon);
+	UNUSED_PARAMETER(pV2);
+	UNUSED_PARAMETER(delta);
+	return ret;
+}
+
+static int dhd_csi_data_output_convert(dhd_pub_t *dhdp, struct csi_cfr_node *ptr)
+{
+	int    ret = BCME_OK;
+
+	DHD_INFO(("%s: will convert common header version to version %d\n",
+	          __func__, dhdp->csi_header_output_version));
+
+	if (CONST_SYNA_CSI_COMMON_HEADER_VERSION
+	    != dhdp->csi_header_output_version) {
+		switch (dhdp->csi_header_output_version) {
+			case CONST_SYNA_CSI_HEADER_VERSION_V1:
+				ret = dhd_csi_data_output_common_to_v1(ptr);
+				break;
+			case CONST_SYNA_CSI_HEADER_VERSION_V2:
+				ret = dhd_csi_data_output_common_to_v2(ptr);
+				break;
+			default:
+				DHD_ERROR(("%s: ***Error, unknow error data"
+				           " header output version=%d\n",
+				           __func__,
+				           dhdp->csi_header_output_version));
+				ret = BCME_UNSUPPORTED;
+				break;
+		}
+	}
+
+	return ret;
+}
+
+static int dhd_csi_data_queue_notify(dhd_pub_t *dhdp, const char * func, int line)
+{
+	struct csi_cfr_node *ptr = NULL, *next = NULL;
+	int                  ret = BCME_OK;
+
+	mutex_lock(&dhdp->csi_lock);
+
+	if (list_empty(&dhdp->csi_list)) {
+		ret = BCME_ERROR;
+		goto done;
+	}
+
+	list_for_each_entry_safe(ptr, next, &dhdp->csi_list, list) {
+		struct ether_header *pEthernet = NULL;
+		struct ipv4_hdr     *pIP = NULL;
+		struct bcmudp_hdr   *pUDP = NULL;
+		int                  len = 0;
+
+		if ((!ptr->length_data_remain)
+		    || (SYNA_CSI_DATA_MODE_UDP_SOCKET != ptr->send_manner)) {
+			continue;
+		}
+
+		/* format of skb:
+		 *   alignment_padding(6)
+		 *   header_ethernet(14)
+		 *   header_ip(20)
+		 *   header_udp(8)
+		 *     csi_header(80)
+		 *     csi_data(N)
+		 */
+
+		/* cut from queue */
+		list_del(&ptr->list);
+		dhdp->csi_count--;
+
+		/* get pointer to fill */
+		len =   CONST_SYNA_CSI_CFR_NODE_LEN + ptr->convert_pull
+		      - CONST_SYNA_SOCKET_HEADER_BYTES;
+		PKTPULL(dhdp->osh, ptr->pNode, len);
+		pEthernet = (struct ether_header *)(PKTDATA(dhdp->osh, ptr->pNode));
+		pIP = (struct ipv4_hdr *)(ETHER_HDR_LEN + (uint8 *)(pEthernet));
+		pUDP = (struct bcmudp_hdr *)(IPV4_HLEN_MIN + (uint8 *)(pIP));
+
+		memcpy(pEthernet, gpDHD_csi_network_template, sizeof(gpDHD_csi_network_template));
+		/* UDP */
+		len = ptr->length_data_total;
+		len += UDP_HDR_LEN;
+		/* early change since psudo header counting use this */
+		if (dhdp->csi_notify_ip) {
+			memcpy(pIP->dst_ip, &(dhdp->csi_notify_ip), IPV4_ADDR_LEN);
+		}
+		pUDP->src_port = hton16(SYNA_SOCKET_PORT_DEFAULT);
+		/* memcpy(pIP->src_ip, &(dhdp->csi_local_ip), IPV4_ADDR_LEN); */
+		pUDP->dst_port = hton16(dhdp->csi_notify_port);
+		pUDP->len = hton16(len);
+		pUDP->chksum = 0x00;
+		/* psudo header includes:
+		 *    source_ip(4) + destination_ip(4)
+		 *  + 0x0011(protocol 2) + UDP_length(2)
+		 */
+		pUDP->chksum = ip_cksum(hton16(0x0011L + len), 0 - 8 + ((uint8 *)pUDP), len + 8);
+		/* IP */
+		len += IPV4_HLEN_MIN;
+		pIP->tot_len = hton16(len);
+		pIP->id = hton16(ptr->pHeader_csi->global_id);
+		pIP->hdr_chksum = 0x00;
+		pIP->hdr_chksum = ip_cksum(0x0, (uint8 *)pIP, IPV4_HLEN_MIN);
+		memcpy(pEthernet->ether_dhost, ptr->pHeader_csi->local_mac, 6);
+		memcpy(pEthernet->ether_shost, ptr->pHeader_csi->peer_mac, 6);
+
+		dhd_rx_frame(dhdp, ptr->ifidx, ptr->pNode, 1, 0x0);
+
+		ret += 1;
+	}
+
+done:
+	mutex_unlock(&dhdp->csi_lock);
+
+	return ret;
+}
+
+int dhd_csi_data_queue_polling(dhd_pub_t *dhdp, char *buf, uint count)
+{
+	struct csi_cfr_node *ptr = NULL, *next = NULL;
+	int   ret = BCME_OK;
+	char *pbuf = buf;
+	int   num = 0;
+	int   copy_len = 0;
+	int   left_data = 0;
+	int   total_copy_len = 0;
+
+	NULL_CHECK(dhdp, "dhdp is NULL", ret);
+
+	mutex_lock(&dhdp->csi_lock);
+	if (!list_empty(&dhdp->csi_list)) {
+		list_for_each_entry_safe(ptr, next, &dhdp->csi_list, list) {
+			/* do not touch 'ptr->pHeader_csi' since it's
+			 * format maybe already changed before send up
+			 */
+			if (ptr->length_data_remain) {
+				DHD_ERROR(("%s-%d: *Warning, data not ready "
+				           "for %02X:%02X:%02X:%02X:%02X:%02X,"
+				           " global_id=%d, length_data_total=%d, "
+				           "length_data_remain=%d\n",
+				           __func__, __LINE__,
+				           ptr->peer_mac[0], ptr->peer_mac[1],
+				           ptr->peer_mac[2], ptr->peer_mac[3],
+				           ptr->peer_mac[4], ptr->peer_mac[5],
+				           ptr->global_id,
+				           ptr->length_data_total,
+				           ptr->length_data_remain));
+				continue;
+			}
+
+			left_data =   ptr->length_data_total
+			            - ptr->length_data_copied;
+			copy_len = count;
+			if (0 > left_data) {
+				DHD_ERROR(("%s-%d: *Error, invalid case, "
+				           "total_len=%d, "
+				           "remain_len=%d, copied_len=%d\n",
+				           __func__, __LINE__,
+				           ptr->length_data_total,
+				           ptr->length_data_remain,
+				           ptr->length_data_copied));
+				copy_len = 0;
+			} else if (copy_len > left_data) {
+				copy_len = left_data;
+			}
+
+			DHD_TRACE(("%s-%d: Packet[%d]: "
+			           "left_room=%d, copy_len=%d, "
+			           "pNode_data_len=%d, pNode_reamin_len=%d, "
+			           "pNode_copied_len=%d, csi_count=%d\n",
+			           __func__, __LINE__,
+			           num, count, copy_len,
+			           ptr->length_data_total,
+			           ptr->length_data_remain,
+			           ptr->length_data_copied,
+			           dhdp->csi_count));
+
+			if (0 < copy_len) {
+				memcpy(pbuf,
+				       ptr->length_data_copied + (uint8 *)(ptr->pHeader_csi),
+				       copy_len);
+				ptr->length_data_copied += copy_len;
+				count -= copy_len;
+				pbuf  += copy_len;
+				num++;
+			}
+
+			if (ptr->length_data_copied >= ptr->length_data_total) {
+				list_del(&ptr->list);
+				dhd_csi_free_pkt(dhdp, ptr);
+				dhdp->csi_count--;
+			}
+
+			if (0 >= copy_len) {
+				break;
+			}
+		}
+	}
+	mutex_unlock(&dhdp->csi_lock);
+	total_copy_len = pbuf - buf;
+	DHD_TRACE(("%s-%d: dump %d record %d bytes\n",
+	           __func__, __LINE__, num, total_copy_len));
+
+	return total_copy_len;
+}
+
+static int dhd_csi_data_append(dhd_pub_t *dhdp, struct csi_cfr_node *ptr,
+                               uint32 data_length, uint32 remain_length,
+                               const uint8 *pData)
+{
+	syna_csi_common_header  *pEntry = NULL;
+	int                      error_status = 0;
+	int                      ret = BCME_OK;
+	int                      append_len = 0;
+
+	if ((!pData) || (!ptr)) {
+		DHD_ERROR(("%s-%d: *Error, invalid parameter, "
+		           "pData=0x%px, ptr=0x%px, pNode=0x%px\n",
+		           __func__, __LINE__,
+		           pData, ptr, ptr?(ptr->pNode):(NULL)));
+		ret = BCME_BADARG;
+		goto done;
+	} else {
+		pEntry = ptr->pHeader_csi;
+		error_status = pEntry->flag_error;
+	}
+	/* find the append length */
+	if (remain_length) {
+		append_len =   data_length
+		             - ptr->length_data_received
+		             - remain_length;
+	} else if (ptr->length_data_remain) {
+		append_len = ptr->length_data_remain;
+	} else if (SYNA_CSI_CFR_NODE_FREE_LEN(ptr) >= data_length) {
+		append_len = data_length;
+	}
+
+	DHD_TRACE(("%s-%d: data_length=%d, remain=%d, append=%d    "
+	           "pNode: pEntry=0x%px, global_id=%d, flags=0x%x, "
+	           "data_len=%d, remain_len=%d, copied_len=%d\n",
+	           __func__, __LINE__,
+	           data_length, remain_length, append_len,
+	           pEntry, pEntry->global_id, pEntry->flag_feature,
+	           pEntry->data_length,
+	           ptr->length_data_remain, ptr->length_data_copied));
+
+	/* copy and update */
+	if (append_len) {
+		memcpy((ptr->length_data_received + ((uint8 *)pEntry->data)),
+		       pData, append_len);
+		ptr->length_data_received += append_len;
+
+		if ((!error_status)
+		    && (!remain_length)
+		    && (pEntry->data_checksum)) {
+			uint16  data_checksum = 0;
+			uint    i;
+			pData = (uint8 *)pEntry->data;
+			for (i = 0; i < data_length; i++) {
+				data_checksum += pData[i];
+			}
+			if (data_checksum != pEntry->data_checksum) {
+				DHD_ERROR(("%s-%d: *Error, global_id=%d, "
+				           "error=0x%X, checksum=0x%X "
+				           "mismatch to FW=0x%X, "
+				           "data_length=%d, remain_length=%d, "
+				           "pData=0x%px\n",
+				           __func__, __LINE__,
+				           pEntry->global_id, error_status,
+				           data_checksum, pEntry->data_checksum,
+				           data_length, remain_length, pData));
+				pEntry->flag_error = SYNA_CSI_LEGACY_FLAG_ERROR_CHECKSUM;
+				prhex("DATA", pData, 16);
+			}
+		}
+	} else if (!error_status) {
+		/* some BC/MC manner may not have CSI DATA feedback */
+		if (pEntry->qty_subcarrier) {
+			DHD_ERROR(("%s-%d: *Error, no data append, "
+			           "total_size=%d, free_len=%d, "
+			           "in_data_length=%d, in_remain_length=%d, "
+			           "    Node: global_id=%d, flags=0x%X, "
+			           "received_length=%d, remain_length=%d\n",
+			           __func__, __LINE__,
+			           ptr->total_size,
+			           (int)SYNA_CSI_CFR_NODE_FREE_LEN(ptr),
+			           data_length, remain_length,
+			           pEntry->global_id, pEntry->flag_error,
+			           ptr->length_data_received, ptr->length_data_remain));
+		}
+	} else {
+		const char *  error_string = NULL;
+		error_string = dhd_csi_get_error_string(pEntry->flag_error);
+		UNUSED_PARAMETER(error_string);
+		/* FW reported errors can be DHD_ERROR() for output if needs */
+		DHD_INFO(("%s-%d: *Warning, error report, "
+		           "size=%d, free=%d, "
+		           "in_data_len=%d, in_remain_len=%d, "
+		           " Node: global_id=%d, flags=0x%X %s, "
+		           "received_length=%d, remain_len=%d\n",
+		           __func__, __LINE__,
+		           ptr->total_size,
+		           (int)SYNA_CSI_CFR_NODE_FREE_LEN(ptr),
+		           data_length, remain_length,
+		           pEntry->global_id,
+		           pEntry->flag_error, error_string,
+		           ptr->length_data_received, ptr->length_data_remain));
+	}
+
+	/* make this as final step to avoid packet early retrieved */
+	ptr->length_data_remain = remain_length;
+
+	/* mapping to expected header when receiving done */
+	if (!remain_length) {
+		ptr->length_data_copied = 0;
+		ptr->global_id = pEntry->global_id;
+		memcpy(ptr->peer_mac, pEntry->peer_mac, ETHER_ADDR_LEN);
+		dhd_csi_data_output_convert(dhdp, ptr);
+	}
+
+	ret = remain_length;
+done:
+	return ret;
+}
+
+static int dhd_csi_data_input_revision0(dhd_pub_t *dhdp, const wl_event_msg_t *event,
+	struct dhd_cfr_header_rev_0 *pCFR, const uint8 *pData)
+{
+	struct csi_cfr_node     *ptr = NULL;
+	syna_csi_common_header  *pEntry = NULL;
+	int                      ret = BCME_ERROR;
+	uint32                   remain_length = 0;
+	uint32                   data_length = 0;
+	uint64                   report_tsf = 0;
+	uint32                   chanspec = 0;
+
+	report_tsf = OSL_SYSUPTIME_US();
+
+	ptr = dhd_csi_allocate_pkt(dhdp, pCFR->cfr_dump_length);
+	if (!ptr) {
+		DHD_ERROR(("%s-%d: *Error, malloc cfr dump list error\n",
+		           __func__, __LINE__));
+		return BCME_NOMEM;
+	}
+	ptr->ifidx = event->ifidx;
+	pEntry = ptr->pHeader_csi;
+
+	DHD_TRACE(("%s-%d: ptr=0x%p, ptr=0x%px, pEntry=0x%px, "
+	           "delta=%d, header_size=%d\n",
+	           __func__, __LINE__, ptr, ptr, pEntry,
+	           (int)((uintptr)pEntry - (uintptr)ptr),
+	           (int)CONST_SYNA_CSI_CFR_NODE_LEN));
+
+	/* process one by one for alignment consideration */
+	memset(pEntry, 0, sizeof(syna_csi_common_header));
+
+	pEntry->magic_flag = CONST_SYNA_CSI_MAGIC_FLAG;
+	pEntry->version = CONST_SYNA_CSI_COMMON_HEADER_VERSION;
+	if (dhd_bus_chip_id(dhdp) == BCM43711_CHIP_ID) {
+		pEntry->format_type = SYNA_CSI_FORMAT_Q9;
+	} else {
+		pEntry->format_type = SYNA_CSI_FORMAT_Q8;
+	}
+	pEntry->frame_control = 0;
+	pEntry->global_id = dhdp->packet_global_id_last++;
+	pEntry->header_length = sizeof(syna_csi_common_header);
+	memcpy(pEntry->peer_mac, pCFR->peer_macaddr, ETHER_ADDR_LEN);
+	if (pCFR->status) {
+		pEntry->flag_error = SYNA_CSI_LEGACY_FLAG_ERROR_GENERIC;
+	}
+	if (!memcmp(_gpMAC_zero, pEntry->local_mac, ETHER_ADDR_LEN)) {
+		dhd_if_t  *ifp = dhd_get_ifp(dhdp, event->ifidx);
+		if (!ifp) {
+			DHD_ERROR(("%s-%d: *Error, get ifp error\n",
+			           __func__, __LINE__));
+		} else {
+			memcpy(pEntry->local_mac, ifp->mac_addr, ETHER_ADDR_LEN);
+		}
+	}
+
+	pEntry->qty_txstream = pCFR->sts;
+	pEntry->qty_rxchain = pCFR->num_rx;
+	pEntry->qty_subcarrier = ltoh16_ua(&(pCFR->num_carrier));
+	if (!pEntry->report_tsf) {
+		pEntry->report_tsf = report_tsf;
+	}
+
+	pEntry->band = SYNA_CSI_BAND_UNKNOWN;
+	pEntry->bandwidth = SYNA_CSI_BW_UNKNOWN;
+	pEntry->channel = 0;
+	if ((ret = dhd_iovar(dhdp, event->ifidx, "chanspec",
+	                     NULL, 0, (char*)&chanspec,
+	                     sizeof(chanspec), FALSE) == BCME_OK)) {
+		switch (CHSPEC_BAND(chanspec)) {
+		case WL_CHANSPEC_BAND_2G:
+			pEntry->band = SYNA_CSI_BAND_2G;
+			break;
+		case WL_CHANSPEC_BAND_5G:
+			pEntry->band = SYNA_CSI_BAND_5G;
+			break;
+		case WL_CHANSPEC_BAND_6G:
+			pEntry->band = SYNA_CSI_BAND_6G;
+			break;
+		default:
+			pEntry->band = SYNA_CSI_BAND_UNKNOWN;
+			break;
+		}
+
+		switch (CHSPEC_BW(chanspec)) {
+		case WL_CHANSPEC_BW_20:
+			pEntry->bandwidth = SYNA_CSI_BW_20MHz;
+			break;
+		case WL_CHANSPEC_BW_40:
+			pEntry->bandwidth = SYNA_CSI_BW_40MHz;
+			break;
+		case WL_CHANSPEC_BW_80:
+			pEntry->bandwidth = SYNA_CSI_BW_80MHz;
+			break;
+		case WL_CHANSPEC_BW_160:
+			pEntry->bandwidth = SYNA_CSI_BW_160MHz;
+			break;
+		case WL_CHANSPEC_BW_320:
+			pEntry->bandwidth = SYNA_CSI_BW_320MHz;
+			break;
+		default:
+			pEntry->bandwidth = SYNA_CSI_BAND_UNKNOWN;
+			break;
+		}
+
+		pEntry->channel = CHSPEC_CHANNEL(chanspec);
+	}
+	pEntry->rssi = pCFR->rssi;
+
+	pEntry->data_length = pCFR->cfr_dump_length;
+	pEntry->data_checksum = 0;
+
+	DHD_TRACE(("%s-%d: Entry data_size=%d, remain_size=%d, @%llu\n",
+	           __func__, __LINE__,
+	           ltoh32_ua(&(pCFR->cfr_dump_length)),
+	           ltoh32_ua(&(pCFR->remain_length)),
+	           ltoh64_ua(&(pEntry->report_tsf))));
+
+	data_length = ltoh32_ua(&(pCFR->cfr_dump_length));
+	remain_length = ltoh32_ua(&(pCFR->remain_length));
+
+	ptr->length_data_total = data_length + sizeof(syna_csi_common_header);
+	ptr->length_data_received = 0;
+	ptr->length_data_remain = 0;
+	ptr->length_data_copied = 0;
+
+	ret = dhd_csi_data_append(dhdp, ptr,
+	                          data_length, remain_length, pData);
+	if (0 <= ret) {
+		INIT_LIST_HEAD(&(ptr->list));
+		mutex_lock(&dhdp->csi_lock);
+		list_add_tail(&(ptr->list), &dhdp->csi_list);
+		dhdp->csi_count++;
+		mutex_unlock(&dhdp->csi_lock);
+	} else {
+		dhd_csi_free_pkt(dhdp, ptr);
+	}
+
+	return ret;
+}
+
+static int dhd_csi_data_input_revision1(dhd_pub_t *dhdp, const wl_event_msg_t *event,
+	struct dhd_cfr_header_rev_1 *pCFR, const uint8 *pData)
+{
+	struct csi_cfr_node     *ptr = NULL;
+	syna_csi_common_header  *pEntry = NULL;
+	int                      ret = BCME_ERROR;
+	uint32                   remain_length = 0;
+	uint32                   data_length = 0;
+	uint64                   report_tsf = 0;
+	uint32                   chanspec = 0;
+
+	report_tsf = OSL_SYSUPTIME_US();
+
+	ptr = dhd_csi_allocate_pkt(dhdp, pCFR->cfr_dump_length);
+	if (!ptr) {
+		DHD_ERROR(("%s-%d: *Error, malloc cfr dump list error\n",
+		           __func__, __LINE__));
+		return BCME_NOMEM;
+	}
+	ptr->ifidx = event->ifidx;
+	pEntry = ptr->pHeader_csi;
+
+	DHD_TRACE(("%s-%d: ptr=0x%p, ptr=0x%px, pEntry=0x%px, "
+	           "delta=%d, header_size=%d\n",
+	           __func__, __LINE__, ptr, ptr, pEntry,
+	           (int)((uintptr)pEntry - (uintptr)ptr),
+	           (int)CONST_SYNA_CSI_CFR_NODE_LEN));
+
+	/* process one by one for alignment consideration */
+	memset(pEntry, 0, sizeof(syna_csi_common_header));
+
+	pEntry->magic_flag = CONST_SYNA_CSI_MAGIC_FLAG;
+	pEntry->version = CONST_SYNA_CSI_COMMON_HEADER_VERSION;
+	pEntry->format_type = SYNA_CSI_FORMAT_Q8;
+	pEntry->frame_control = pCFR->fc;
+	pEntry->global_id = dhdp->packet_global_id_last++;
+	pEntry->header_length = sizeof(syna_csi_common_header);
+	memcpy(pEntry->peer_mac, pCFR->peer_macaddr, ETHER_ADDR_LEN);
+	if (pCFR->status) {
+		pEntry->flag_error = SYNA_CSI_LEGACY_FLAG_ERROR_GENERIC;
+	}
+	if (!memcmp(_gpMAC_zero, pEntry->local_mac, ETHER_ADDR_LEN)) {
+		dhd_if_t  *ifp = dhd_get_ifp(dhdp, event->ifidx);
+		if (!ifp) {
+			DHD_ERROR(("%s-%d: *Error, get ifp error\n",
+			           __func__, __LINE__));
+		} else {
+			memcpy(pEntry->local_mac, ifp->mac_addr, ETHER_ADDR_LEN);
+		}
+	}
+
+	pEntry->qty_txstream = pCFR->sts;
+	pEntry->qty_rxchain = pCFR->num_rx;
+	pEntry->qty_subcarrier = ltoh16_ua(&(pCFR->num_carrier));
+	pEntry->report_tsf = ltoh64_ua(&(pCFR->cfr_timestamp));
+	if (!pEntry->report_tsf) {
+		pEntry->report_tsf = report_tsf;
+	}
+
+	pEntry->band = SYNA_CSI_BAND_UNKNOWN;
+	pEntry->bandwidth = SYNA_CSI_BW_UNKNOWN;
+	pEntry->channel = 0;
+	if ((ret = dhd_iovar(dhdp, event->ifidx, "chanspec",
+	                     NULL, 0, (char*)&chanspec,
+	                     sizeof(chanspec), FALSE) == BCME_OK)) {
+		switch (CHSPEC_BAND(chanspec)) {
+		case WL_CHANSPEC_BAND_2G:
+			pEntry->band = SYNA_CSI_BAND_2G;
+			break;
+		case WL_CHANSPEC_BAND_5G:
+			pEntry->band = SYNA_CSI_BAND_5G;
+			break;
+		case WL_CHANSPEC_BAND_6G:
+			pEntry->band = SYNA_CSI_BAND_6G;
+			break;
+		default:
+			pEntry->band = SYNA_CSI_BAND_UNKNOWN;
+			break;
+		}
+
+		switch (CHSPEC_BW(chanspec)) {
+		case WL_CHANSPEC_BW_20:
+			pEntry->bandwidth = SYNA_CSI_BW_20MHz;
+			break;
+		case WL_CHANSPEC_BW_40:
+			pEntry->bandwidth = SYNA_CSI_BW_40MHz;
+			break;
+		case WL_CHANSPEC_BW_80:
+			pEntry->bandwidth = SYNA_CSI_BW_80MHz;
+			break;
+		case WL_CHANSPEC_BW_160:
+			pEntry->bandwidth = SYNA_CSI_BW_160MHz;
+			break;
+		case WL_CHANSPEC_BW_320:
+			pEntry->bandwidth = SYNA_CSI_BW_320MHz;
+			break;
+		default:
+			pEntry->bandwidth = SYNA_CSI_BAND_UNKNOWN;
+			break;
+		}
+
+		pEntry->channel = CHSPEC_CHANNEL(chanspec);
+	}
+	pEntry->rssi = pCFR->rssi;
+
+	pEntry->data_length = pCFR->cfr_dump_length;
+	pEntry->data_checksum = 0;
+
+	DHD_TRACE(("%s-%d: Entry data_size=%d, remain_size=%d, @%llu\n",
+	           __func__, __LINE__,
+	           ltoh32_ua(&(pCFR->cfr_dump_length)),
+	           ltoh32_ua(&(pCFR->remain_length)),
+	           ltoh64_ua(&(pEntry->report_tsf))));
+
+	data_length = ltoh32_ua(&(pCFR->cfr_dump_length));
+	remain_length = ltoh32_ua(&(pCFR->remain_length));
+
+	ptr->length_data_total = data_length + sizeof(syna_csi_common_header);
+	ptr->length_data_received = 0;
+	ptr->length_data_remain = 0;
+	ptr->length_data_copied = 0;
+
+	ret = dhd_csi_data_append(dhdp, ptr,
+	                          data_length, remain_length, pData);
+	if (0 <= ret) {
+		INIT_LIST_HEAD(&(ptr->list));
+		mutex_lock(&dhdp->csi_lock);
+		list_add_tail(&(ptr->list), &dhdp->csi_list);
+		dhdp->csi_count++;
+		mutex_unlock(&dhdp->csi_lock);
+	} else {
+		dhd_csi_free_pkt(dhdp, ptr);
+	}
+
+	return ret;
+}
+
+static int dhd_csi_data_input_revision2(dhd_pub_t *dhdp, const wl_event_msg_t *event,
+	struct dhd_cfr_header_rev_2 *pCFR, const uint8 *pData)
+{
+	struct csi_cfr_node     *ptr = NULL;
+	syna_csi_common_header  *pEntry = NULL;
+	int                      ret = BCME_ERROR;
+	uint32                   remain_length = 0;
+	uint32                   data_length = 0;
+	uint64                   report_tsf = 0;
+
+	report_tsf = OSL_SYSUPTIME_US();
+
+	if (SYNA_ALIGN_PADDING & (uintptr)pCFR) {
+		DHD_ERROR(("%s-%d: *Warning, pCFR=0x%px is not aligned!\n",
+		           __func__, __LINE__, pCFR));
+	}
+
+	ptr = dhd_csi_allocate_pkt(dhdp, pCFR->data_length);
+	if (!ptr) {
+		DHD_ERROR(("%s-%d: *Error, malloc cfr dump list error\n",
+		           __func__, __LINE__));
+		return BCME_NOMEM;
+	}
+	ptr->ifidx = event->ifidx;
+	pEntry = ptr->pHeader_csi;
+
+	DHD_TRACE(("%s-%d: ptr=0x%p, ptr=0x%px, pEntry=0x%px, "
+	           "delta=%d, header_size=%d\n",
+	           __func__, __LINE__, ptr, ptr, pEntry,
+	           (int)((uintptr)pEntry - (uintptr)ptr),
+	           (int)CONST_SYNA_CSI_CFR_NODE_LEN));
+
+	/* process one by one for alignment consideration */
+	memset(pEntry, 0, sizeof(syna_csi_common_header));
+
+	pEntry->magic_flag = CONST_SYNA_CSI_MAGIC_FLAG;
+	pEntry->version = CONST_SYNA_CSI_COMMON_HEADER_VERSION;
+	pEntry->format_type = pCFR->format_type;
+	pEntry->frame_control = pCFR->fc;
+	if (!pEntry->format_type) {
+		pEntry->format_type = SYNA_CSI_FORMAT_Q8;
+	}
+
+	pEntry->global_id = pCFR->global_id;
+	pEntry->header_length = sizeof(syna_csi_common_header);
+	pEntry->trigger_mode = 0;
+	pEntry->dot11_mode = SYNA_CSI_DOT11_UNKNOW;
+	if (-1 != dhdp->packet_global_id_last) {
+		uint32  delta = 0;
+
+		delta = ((pCFR->global_id + 0x10000UL) -
+			dhdp->packet_global_id_last) & 0xFFFFUL;
+		if (!delta) {
+			DHD_ERROR(("%s-%d: ***Warning, duplicate packet,"
+			           " id=%d\n",
+			           __func__, __LINE__,
+			           dhdp->packet_global_id_last));
+			dhdp->packet_qty_duplicate++;
+		} else if (1 < delta) {
+			DHD_ERROR(("%s-%d: ***Warning, packet missing, "
+			           "last_id=%d, now_id=%d, delta=%d\n",
+			           __func__, __LINE__,
+			           dhdp->packet_global_id_last,
+			           pCFR->global_id, delta));
+			dhdp->packet_qty_missing += delta - 1;
+		}
+	}
+	dhdp->packet_global_id_last = pCFR->global_id;
+
+	pEntry->report_tsf = pCFR->report_tsf;
+	pEntry->flag_error = pCFR->flags & SYNA_CSI_LEGACY_FLAG_ERROR_MASK;
+	memcpy(pEntry->peer_mac,  pCFR->client_ea, ETHER_ADDR_LEN);
+	memcpy(pEntry->local_mac, pCFR->bsscfg_ea, ETHER_ADDR_LEN);
+
+	if ((pCFR->status_compat) && (!pCFR->flags)) {
+		pEntry->flag_error = SYNA_CSI_LEGACY_FLAG_ERROR_GENERIC;
+		DHD_ERROR(("%s-%d: *Warning, status=0x%X, "
+		           " global_id=%d!\n",
+		           __func__, __LINE__,
+		           pCFR->status_compat,
+		           pCFR->global_id));
+	}
+	if (pCFR->flags & SYNA_CSI_LEGACY_FLAG_FFT_NEGATIVE_FIRST) {
+		pEntry->flag_feature = SYNA_CSI_FLAG_FEATURE_FFT_NEGATIVE_FIRST;
+	}
+	if (!pEntry->report_tsf) {
+		pEntry->report_tsf = report_tsf;
+	}
+	if (!memcmp(_gpMAC_zero, pEntry->local_mac, ETHER_ADDR_LEN)) {
+		dhd_if_t  *ifp = dhd_get_ifp(dhdp, event->ifidx);
+		if (!ifp) {
+			DHD_ERROR(("%s-%d: *Error, get ifp error\n",
+			           __func__, __LINE__));
+		} else {
+			memcpy(pEntry->local_mac, ifp->mac_addr, ETHER_ADDR_LEN);
+		}
+	}
+
+	pEntry->qty_txstream = pCFR->num_txstream;
+	pEntry->qty_rxchain = pCFR->num_rxchain;
+	pEntry->qty_subcarrier = pCFR->num_subcarrier;
+
+	pEntry->chipset_flag = 0;
+	pEntry->band = pCFR->band;
+	pEntry->side_band = 0;
+	pEntry->bandwidth = pCFR->bandwidth;
+	pEntry->channel = pCFR->channel;
+	pEntry->rx_rate = 0;
+
+	pEntry->rx_bandwidth = 0;
+	pEntry->rxchain_idx_mask = 0;
+	pEntry->rssi = pCFR->rssi;
+	pEntry->noise = pCFR->noise;
+	memcpy(pEntry->rssi_ant, pCFR->rssi_ant, sizeof(pEntry->rssi_ant));
+
+	pEntry->data_length = pCFR->data_length;
+	pEntry->data_checksum = pCFR->data_checksum;
+
+	DHD_TRACE(("%s-%d: Entry data_size=%d, remain_size=%d, @%llu\n",
+	           __func__, __LINE__,
+	           pCFR->data_length,
+	           pCFR->remain_length,
+	           pEntry->report_tsf));
+
+	data_length = pCFR->data_length;
+	remain_length = pCFR->remain_length;
+
+	ptr->length_data_total = data_length + sizeof(syna_csi_common_header);
+	ptr->length_data_received = 0;
+	ptr->length_data_remain = 0;
+	ptr->length_data_copied = 0;
+
+	ret = dhd_csi_data_append(dhdp, ptr,
+	                          data_length, remain_length, pData);
+	if (0 <= ret) {
+		INIT_LIST_HEAD(&(ptr->list));
+		mutex_lock(&dhdp->csi_lock);
+		list_add_tail(&(ptr->list), &dhdp->csi_list);
+		dhdp->csi_count++;
+		mutex_unlock(&dhdp->csi_lock);
+	} else {
+		dhd_csi_free_pkt(dhdp, ptr);
+	}
+
+	return ret;
+}
+
+static int dhd_csi_data_input_revision3(dhd_pub_t *dhdp, const wl_event_msg_t *event,
+	struct dhd_cfr_header_rev_3 *pCFR, const uint8 *pData)
+{
+	struct csi_cfr_node     *ptr = NULL;
+	syna_csi_common_header  *pEntry = NULL;
+	int                      ret = BCME_ERROR;
+	uint32                   remain_length = 0;
+	uint32                   data_length = 0;
+	uint64                   report_tsf = 0;
+
+	report_tsf = OSL_SYSUPTIME_US();
+
+	if (SYNA_ALIGN_PADDING & (uintptr)pCFR) {
+		DHD_ERROR(("%s-%d: *Warning, pCFR=0x%px is not aligned!\n",
+		           __func__, __LINE__, pCFR));
+	}
+
+	ptr = dhd_csi_allocate_pkt(dhdp, pCFR->data_length);
+	if (!ptr) {
+		DHD_ERROR(("%s-%d: *Error, malloc cfr dump list error\n",
+		           __func__, __LINE__));
+		return BCME_NOMEM;
+	}
+	ptr->ifidx = event->ifidx;
+	pEntry = ptr->pHeader_csi;
+
+	DHD_TRACE(("%s-%d: ptr=0x%p, ptr=0x%px, pEntry=0x%px, "
+	           "delta=%d, header_size=%d\n",
+	           __func__, __LINE__, ptr, ptr, pEntry,
+	           (int)((uintptr)pEntry - (uintptr)ptr),
+	           (int)CONST_SYNA_CSI_CFR_NODE_LEN));
+	/* process one by one for alignment consideration */
+	memcpy(pEntry, pCFR, sizeof(syna_csi_common_header));
+
+	pEntry->magic_flag = CONST_SYNA_CSI_MAGIC_FLAG;
+	pEntry->version = CONST_SYNA_CSI_COMMON_HEADER_VERSION;
+	if (!pEntry->format_type) {
+		pEntry->format_type = SYNA_CSI_FORMAT_Q8;
+	}
+
+	if (-1 != dhdp->packet_global_id_last) {
+		uint32  delta = 0;
+
+		delta = ((pCFR->global_id + 0x10000UL)
+			- dhdp->packet_global_id_last)
+			& 0xFFFFUL;
+		if (!delta) {
+			DHD_ERROR(("%s-%d: ***Warning, duplicate packet,"
+			           " id=%d\n",
+			           __func__, __LINE__,
+			           dhdp->packet_global_id_last));
+			dhdp->packet_qty_duplicate++;
+		} else if (1 < delta) {
+			DHD_ERROR(("%s-%d: ***Warning, packet missing, "
+			           "last_id=%d, now_id=%d, delta=%d\n",
+			           __func__, __LINE__,
+			           dhdp->packet_global_id_last,
+			           pCFR->global_id, delta));
+			dhdp->packet_qty_missing += delta - 1;
+		}
+	}
+	dhdp->packet_global_id_last = pCFR->global_id;
+
+	if ((pCFR->status_compat) && (!pCFR->flag_error)) {
+		pEntry->flag_error = SYNA_CSI_FLAG_ERROR_GENERIC;
+		DHD_ERROR(("%s-%d: *Warning, status=0x%X, "
+		           " global_id=%d!\n",
+		           __func__, __LINE__,
+		           pCFR->status_compat,
+		           pCFR->global_id));
+	}
+	if (!pEntry->report_tsf) {
+		pEntry->report_tsf = report_tsf;
+	}
+	if (!memcmp(_gpMAC_zero, pEntry->local_mac, ETHER_ADDR_LEN)) {
+		dhd_if_t  *ifp = dhd_get_ifp(dhdp, event->ifidx);
+		if (!ifp) {
+			DHD_ERROR(("%s-%d: *Error, get ifp error\n",
+			           __func__, __LINE__));
+		} else {
+			memcpy(pEntry->local_mac, ifp->mac_addr, ETHER_ADDR_LEN);
+		}
+	}
+
+	DHD_TRACE(("%s-%d: Entry data_size=%d, remain_size=%d, @%llu\n",
+	           __func__, __LINE__,
+	           pCFR->data_length,
+	           pCFR->remain_length,
+	           pEntry->report_tsf));
+
+	data_length = pCFR->data_length;
+	remain_length = pCFR->remain_length;
+
+	ptr->length_data_total = data_length + sizeof(syna_csi_common_header);
+	ptr->length_data_received = 0;
+	ptr->length_data_remain = 0;
+	ptr->length_data_copied = 0;
+
+	ret = dhd_csi_data_append(dhdp, ptr,
+	                          data_length, remain_length, pData);
+	if (0 <= ret) {
+		INIT_LIST_HEAD(&(ptr->list));
+		mutex_lock(&dhdp->csi_lock);
+		list_add_tail(&(ptr->list), &dhdp->csi_list);
+		dhdp->csi_count++;
+		mutex_unlock(&dhdp->csi_lock);
+	} else {
+		dhd_csi_free_pkt(dhdp, ptr);
+	}
+
+	return ret;
+}
+
+static int dhd_csi_event_handler(dhd_pub_t *dhdp, const wl_event_msg_t *event, uint8 *event_data)
+{
+	union dhd_cfr_header  cfr;
+	union dhd_cfr_header  *pCFR = NULL;
+	struct csi_cfr_node   *ptr = NULL, *next = NULL, *save_ptr = NULL;
+	const uint8  *pMAC = NULL, *pData = NULL;
+	uint8  version = 0xff;
+	uint32 data_length = 0, remain_length = 0;
+	int    ret = BCME_OK;
+
+	NULL_CHECK(dhdp, "dhdp is NULL", ret);
+
+	DHD_TRACE(("%s-%d: Enter\n", __func__, __LINE__));
+
+	if (!event_data) {
+		DHD_ERROR(("%s-%d: event_data is NULL\n",
+		           __func__, __LINE__));
+		ret = BCME_BADARG;
+		goto done;
+	}
+
+	pCFR = (union dhd_cfr_header *)event_data;
+	if (SYNA_ALIGN_PADDING & (uintptr)pCFR) {
+		memcpy(&cfr, event_data, sizeof(union dhd_cfr_header));
+		pCFR = &cfr;
+	}
+
+	if (pCFR->header_rev_0.status) {
+		DHD_INFO(("%s-%d: *Warning, status=0x%X "
+		          " may indicate error!\n",
+		          __func__, __LINE__,
+		          pCFR->header_rev_0.status));
+		/* TODO: need to abandon such case packet? */
+	}
+
+	version = pCFR->header_rev_0.version;
+	switch (version) {
+	case CONST_CFR_HEADER_REVISION_0:
+		pMAC = pCFR->header_rev_0.peer_macaddr;
+		remain_length = ltoh32_ua(&(pCFR->header_rev_0.remain_length));
+		data_length = ltoh32_ua(&(pCFR->header_rev_0.cfr_dump_length));
+		pData = (uint8 *)(sizeof(struct dhd_cfr_header_rev_0) + event_data);
+		break;
+	case CONST_CFR_HEADER_REVISION_1:
+		pMAC = pCFR->header_rev_1.peer_macaddr;
+		remain_length = ltoh32_ua(&(pCFR->header_rev_1.remain_length));
+		data_length = ltoh32_ua(&(pCFR->header_rev_1.cfr_dump_length));
+		pData = (uint8 *)(sizeof(struct dhd_cfr_header_rev_1) + event_data);
+		break;
+	case CONST_CFR_HEADER_REVISION_2:
+		pMAC = pCFR->header_rev_2.client_ea;
+		remain_length = pCFR->header_rev_2.remain_length;
+		data_length = pCFR->header_rev_2.data_length;
+		pData = (uint8 *)(sizeof(struct dhd_cfr_header_rev_2) + event_data);
+		break;
+	case CONST_CFR_HEADER_REVISION_3:
+		pMAC = pCFR->header_rev_3.peer_mac;
+		remain_length = pCFR->header_rev_3.remain_length;
+		data_length = pCFR->header_rev_3.data_length;
+		pData = (uint8 *)(sizeof(struct dhd_cfr_header_rev_3) + event_data);
+		break;
+	default:
+		DHD_ERROR(("%s-%d: CSI version=%d error\n",
+		           __func__, __LINE__, version));
+		ret = BCME_BADOPTION;
+		goto done;
+		break;
+	}
+
+	if (CONST_CSI_DATA_BYTES_MAX < remain_length) {
+		DHD_ERROR(("%s-%d: *Error, drop too big length, "
+		           "global_id=%d, version=%d, status=%d, "
+		           "data_length=%d(0x%X), remain_length=%d(0x%X) > %d\n",
+		           __func__, __LINE__,
+		           pCFR->header_rev_2.global_id,
+		           version, pCFR->header_rev_2.status_compat,
+		           data_length, data_length,
+		           remain_length, remain_length,
+		           (int)CONST_CSI_DATA_BYTES_MAX));
+		prhex("TOO_BIG_LENGTH", (uchar *)pCFR, 128);
+		ret = BCME_BADLEN;
+		goto done;
+	}
+
+	mutex_lock(&dhdp->csi_lock);
+	/* check if this addr exist */
+	if (!list_empty(&dhdp->csi_list)) {
+		list_for_each_entry_safe(ptr, next, &dhdp->csi_list, list) {
+			syna_csi_common_header *pEntry = ptr->pHeader_csi;
+			/* check if is new */
+			if (bcmp(&pEntry->peer_mac, pMAC, ETHER_ADDR_LEN) == 0) {
+				if (ptr->length_data_remain > 0) {
+					save_ptr = ptr;
+					break;
+				}
+			}
+		}
+	}
+	/* check if need to drop head packet */
+	if ((!save_ptr) && (dhdp->csi_count >= CONST_CSI_QUEUE_MAX_SIZE)) {
+		DHD_ERROR(("%s-%d: ***CSI data is full, drop pkt \n",
+		           __func__, __LINE__));
+		ptr = list_last_entry(&dhdp->csi_list, struct csi_cfr_node, list);
+		list_del_init(&ptr->list);
+		dhd_csi_free_pkt(dhdp, ptr);
+		dhdp->csi_count--;
+	}
+	mutex_unlock(&dhdp->csi_lock);
+
+	/* try to append new node if needs */
+	DHD_TRACE(("%s-%d: save_ptr=0x%px, version=%d\n",
+	           __func__, __LINE__, save_ptr, version));
+	if (!save_ptr) {
+		switch (version) {
+		case CONST_CFR_HEADER_REVISION_0:
+			ret = dhd_csi_data_input_revision0(
+				dhdp, event, &(pCFR->header_rev_0), pData);
+			break;
+		case CONST_CFR_HEADER_REVISION_1:
+			ret = dhd_csi_data_input_revision1(
+				dhdp, event, &(pCFR->header_rev_1), pData);
+			break;
+		case CONST_CFR_HEADER_REVISION_2:
+			ret = dhd_csi_data_input_revision2(
+				dhdp, event, &(pCFR->header_rev_2), pData);
+			break;
+		case CONST_CFR_HEADER_REVISION_3:
+			ret = dhd_csi_data_input_revision3(
+				dhdp, event, &(pCFR->header_rev_3), pData);
+			break;
+		default:
+			DHD_ERROR(("%s-%d: CSI version=%d error\n",
+			           __func__, __LINE__, version));
+			ret = BCME_BADOPTION;
+			goto done;
+			break;
+		}
+	} else {
+		ret = dhd_csi_data_append(dhdp, save_ptr,
+		                          data_length, remain_length, pData);
+	}
+
+	if (0 <= ret) {
+		ret = dhd_csi_data_queue_notify(dhdp, __func__, __LINE__);
+	}
+
+done:
+	return ret;
+}
+
+int dhd_csi_event_enqueue(dhd_pub_t  *dhdp, int ifidx, void *pktbuf)
+{
+	if ((!dhdp) || (!dhdp->csi_init)) {
+		DHD_ERROR(("%s-%d: *Error, NOT READY\n", __func__, __LINE__));
+		return BCME_NOTREADY;
+	}
+
+	skb_queue_tail(&dhdp->csi_raw_skb_queue, pktbuf);
+
+	schedule_work(&dhdp->csi_raw_skb_work);
+
+	return BCME_OK;
+}
+
+static void dhd_csi_event_dequeue(struct work_struct *work_data)
+{
+	dhd_pub_t        *dhdp = NULL;
+	uint32            qlen = 0;
+	struct sk_buff   *skb = NULL;
+	int               len = 0;
+	bcm_event_t      *pvt_data = NULL;
+	wl_event_msg_t    event;
+	uint8            *event_data = NULL;
+	int               ret = BCME_OK;
+
+	dhdp = container_of(work_data, dhd_pub_t, csi_raw_skb_work);
+
+	if ((!dhdp) || (!dhdp->csi_init)) {
+		DHD_ERROR(("%s-%d: *Error, NOT READY\n", __func__, __LINE__));
+		return;
+	}
+
+	qlen = skb_queue_len(&dhdp->csi_raw_skb_queue);
+	while (qlen--) {
+		skb = skb_dequeue(&dhdp->csi_raw_skb_queue);
+		if (!skb) {
+			DHD_ERROR(("%s: * invalid NULL skb\n", __func__));
+			continue;
+		}
+
+		/* In dhd_rx_frame, header is stripped using skb_pull
+		 * of size ETH_HLEN, so adjust pktlen accordingly
+		 */
+		len = skb->len + ETH_HLEN;
+		if (sizeof(struct dhd_cfr_header_rev_0) > len) {
+			DHD_ERROR(("%s: *Warning, skip too short pkt, len=%d\n", __func__, len));
+		} else {
+			pvt_data = (bcm_event_t *)skb_mac_header(skb);
+			/* copy to get aligned 'event', but can't for 'event_data' */
+			memcpy(&event, &(pvt_data->event), sizeof(wl_event_msg_t));
+			event_data = (uint8 *)(&pvt_data[1]);
+
+			ret = dhd_csi_event_handler(dhdp, &event, event_data);
+			if (BCME_OK != ret) {
+				DHD_ERROR(("%s: process event fail, ret=%d\n", __func__, ret));
+			}
+		}
+
+		/* Free up the packet. */
+#ifdef DHD_USE_STATIC_CTRLBUF
+		PKTFREE_STATIC(dhdp->osh, skb, FALSE);
+#else /* DHD_USE_STATIC_CTRLBUF */
+		PKTFREE(dhdp->osh, skb, FALSE);
+#endif /* DHD_USE_STATIC_CTRLBUF */
+	}
+}
+
+static void
+dhd_csi_clean_list(dhd_pub_t *dhdp)
+{
+	struct csi_cfr_node *ptr, *next;
+	int num = 0;
+
+	if (!dhdp) {
+		DHD_ERROR(("%s-%d: *Error, NULL POINTER\n",
+		           __func__, __LINE__));
+		return;
+	}
+
+	mutex_lock(&dhdp->csi_lock);
+	if (!list_empty(&dhdp->csi_list)) {
+		list_for_each_entry_safe(ptr, next, &dhdp->csi_list, list) {
+			list_del(&ptr->list);
+			num++;
+			dhd_csi_free_pkt(dhdp, ptr);
+		}
+	}
+	dhdp->csi_count = 0;
+	mutex_unlock(&dhdp->csi_lock);
+
+	DHD_TRACE(("%s-%d: Clean up %d record\n",
+	           __func__, __LINE__, num));
+}
+
+int dhd_csi_config(dhd_pub_t *dhdp, char *pBuf, uint length, bool is_set)
+{
+	struct syna_csi_rx_mode_config  *pRX_config = NULL;
+	int                              ret = BCME_OK;
+
+	if ((!dhdp) || (!pBuf) || (sizeof(uint32) > length)) {
+		DHD_ERROR(("%s-%d: *Error, Bad argument\n",
+		           __func__, __LINE__));
+		ret = BCME_BADARG;
+		goto done;
+	}
+
+	pRX_config = (struct syna_csi_rx_mode_config *)pBuf;
+
+	if (is_set) {
+		/* check mode */
+		if (SYNA_CSI_DATA_MODE_LAST <= pRX_config->mode) {
+			ret = BCME_BADOPTION;
+			goto done;
+		} else {
+			dhdp->csi_data_send_manner = pRX_config->mode;
+		}
+
+		/* initialize for new CSI trigger */
+		dhd_csi_clean_list(dhdp);
+		dhdp->packet_global_id_last = -1;
+		dhdp->packet_qty_duplicate = 0;
+		dhdp->packet_qty_missing = 0;
+		dhdp->csi_notify_ip = 0;
+		dhdp->csi_notify_port = 0;
+
+		/* try to get primary interface IP address */
+		if (dhdp) {
+			struct net_device  *ndev = NULL;
+			struct in_device   *in_dev = NULL;
+
+			ndev = dhd_linux_get_primary_netdev(dhdp);
+
+			rcu_read_lock();
+			in_dev = __in_dev_get_rcu(ndev);
+			if (in_dev) {
+				struct in_ifaddr *ifa = NULL;
+
+				for (ifa = in_dev->ifa_list;
+				     ifa != NULL;
+				     ifa = ifa->ifa_next) {
+					if (ifa->ifa_address) {
+						dhdp->csi_local_ip = ifa->ifa_address;
+						break;
+					}
+				}
+			}
+			rcu_read_unlock();
+		}
+
+		/* skip if no more parameter */
+		if ((length < (sizeof(uint32)+1)) || (!pRX_config->data_version))  {
+			goto done;
+		}
+
+		/* check DATA output version */
+		if (CONST_SYNA_CSI_HEADER_VERSION_V2 < pRX_config->data_header_version_output) {
+			DHD_ERROR(("%s-%d: *Error, invalid data header output version %d\n",
+			           __func__, __LINE__,
+			           pRX_config->data_header_version_output));
+			ret = BCME_BADOPTION;
+			goto done;
+		} else if (CONST_SYNA_CSI_HEADER_VERSION_V1 >
+			pRX_config->data_header_version_output) {
+			dhdp->csi_header_output_version = CONST_SYNA_CSI_HEADER_VERSION_V1;
+		} else {
+			dhdp->csi_header_output_version = pRX_config->data_header_version_output;
+		}
+
+		/* check if using socket manner to send up */
+		if (SYNA_CSI_DATA_MODE_UDP_SOCKET == pRX_config->mode) {
+			if (!dhdp->csi_notify_ip) {
+				dhdp->csi_notify_ip = dhdp->csi_local_ip;
+			} else {
+				dhdp->csi_notify_ip   = pRX_config->ip;
+			}
+			if (!dhdp->csi_notify_port) {
+				dhdp->csi_notify_port = SYNA_SOCKET_PORT_DEFAULT;
+			} else {
+				dhdp->csi_notify_port = pRX_config->port;
+			}
+		}
+	} else {
+		pRX_config->mode = dhdp->csi_data_send_manner;
+		if ((length > sizeof(uint32))) {
+			pRX_config->data_version = TRUE;
+			pRX_config->data_header_version_output = dhdp->csi_header_output_version;
+			pRX_config->ip   = dhdp->csi_notify_ip;
+			pRX_config->port = dhdp->csi_notify_port;
+		}
+	}
+
+done:
+	return ret;
+}
+
+int dhd_csi_version(dhd_pub_t *dhdp, char *pBuf, uint length, bool is_set)
+{
+	int  ret = BCME_OK;
+
+	if ((!dhdp) || (!pBuf) || (sizeof(uint8) > length)) {
+		DHD_ERROR(("%s-%d: *Error, Bad argument\n",
+		           __func__, __LINE__));
+		ret = BCME_BADARG;
+		goto done;
+	}
+
+	if (is_set) {
+		ret = BCME_BADOPTION;
+	} else {
+		memcpy(pBuf, &dhdp->csi_version_capability, sizeof(uint8));
+	}
+
+done:
+	return ret;
+}
+
+int dhd_csi_init(dhd_pub_t *dhdp)
+{
+	int err = BCME_OK;
+
+	NULL_CHECK(dhdp, "dhdp is NULL", err);
+
+	mutex_init(&(dhdp->csi_lock));
+
+	mutex_lock(&(dhdp->csi_lock));
+
+	skb_queue_head_init(&dhdp->csi_raw_skb_queue);
+	INIT_WORK(&dhdp->csi_raw_skb_work, dhd_csi_event_dequeue);
+
+	INIT_LIST_HEAD(&dhdp->csi_list);
+	dhdp->csi_count = 0;
+
+	dhdp->csi_version_capability = CONST_SYNA_CSI_HEADER_VERSION_V2;
+	/* default DATA CSI header output version */
+	dhdp->csi_header_output_version = CONST_CSI_HEADER_VERSION_OUTPUT_DEFAULT;
+	dhdp->csi_data_send_manner = SYNA_CSI_DATA_MODE_SYSFS;
+
+	dhdp->csi_init = 1;
+
+	mutex_unlock(&dhdp->csi_lock);
+
+	return err;
+}
+
+int
+dhd_csi_deinit(dhd_pub_t *dhdp)
+{
+	int err = BCME_OK;
+
+	NULL_CHECK(dhdp, "dhdp is NULL", err);
+
+	dhd_csi_clean_list(dhdp);
+
+	mutex_lock(&dhdp->csi_lock);
+
+	dhdp->csi_init = 0;
+
+	if (0 < skb_queue_len(&dhdp->csi_raw_skb_queue)) {
+		struct sk_buff  *skb = NULL;
+
+		while (NULL != (skb = skb_dequeue(&dhdp->csi_raw_skb_queue))) {
+#ifdef DHD_USE_STATIC_CTRLBUF
+			PKTFREE_STATIC(dhdp->osh, skb, FALSE);
+#else /* DHD_USE_STATIC_CTRLBUF */
+			PKTFREE(dhdp->osh, skb, FALSE);
+#endif /* DHD_USE_STATIC_CTRLBUF */
+		}
+	}
+	if (dhdp->csi_raw_skb_work.func) {
+		cancel_work_sync(&dhdp->csi_raw_skb_work);
+	}
+
+	mutex_unlock(&dhdp->csi_lock);
+
+	mutex_destroy(&dhdp->csi_lock);
+
+	return err;
+}
+
+#endif /* CSI_SUPPORT */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_csi.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_csi.h
@@ -0,0 +1,918 @@
+/*
+ * Broadcom Dongle Host Driver (DHD), Linux-specific network interface.
+ * Basically selected code segments from usb-cdc.c and usb-rndis.c
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef __DHD_CSI_H__
+#define __DHD_CSI_H__
+
+#ifdef CSI_SUPPORT
+
+/* Different FW using different CSI data formats, and here
+ * the  DHD driver will directly convert input DATA to the
+ * common header format(latest full set version CSI header
+ * format which contains much more items), and then it will
+ * be converted to corresponding version CSI header which
+ * applicaiton required.
+ *
+ *        FW                   DHD-Driver                 Application
+ * dhd_cfr_header_rev_0 \
+ * dhd_cfr_header_rev_1  \                              / syna_csi_header_v1
+ * dhd_cfr_header_rev_2   --> syna_csi_common_header -->  syna_csi_header_v2
+ * dhd_cfr_header_rev_3  /                              \      ...
+ *     ...              /
+ */
+
+/* definition for structure and API between APP and driver */
+enum eSyna_csi_data_mode_type {
+	SYNA_CSI_DATA_MODE_NONE = 0,
+	/* upper layer will fetch data by sysfs */
+	SYNA_CSI_DATA_MODE_SYSFS,
+	/* upper layer will fetch data by UDP socket */
+	SYNA_CSI_DATA_MODE_UDP_SOCKET,
+	SYNA_CSI_DATA_MODE_LAST
+};
+
+enum syna_csi_format_type {
+	SYNA_CSI_FORMAT_UNKNOWN = 0,
+	SYNA_CSI_FORMAT_Q8,  /* (9,9,5) Q8 floating point
+	                      * BCM4358/4359/4375x
+	                      */
+	SYNA_CSI_FORMAT_Q11, /* (12,12,6) Q11 floating point
+	                      * BCM4360/4366
+	                      */
+	SYNA_CSI_FORMAT_Q12, /* (13,13,0) Q12 fixed point
+	                      */
+	SYNA_CSI_FORMAT_Q13, /* (14,14,0) Q13 fixed point
+	                      * BCM4339/4345x/43013x
+	                      */
+	SYNA_CSI_FORMAT_Q9,  /* (10,10,5) Q9 fixed point
+	                      * BCM43711
+	                      */
+	SYNA_CSI_FORMAT_LAST
+};
+
+/* (9,9,5) Q8 floating point data format */
+#define _Q8_REAL_MA(t)         (0x000ff &((t)>>14))
+#define _Q8_REAL_SI(t)         (0x00001 &((t)>>22))
+#define _Q8_IMAGINARY_MA(t)    (0x000ff &((t)>> 5))
+#define _Q8_IMAGINARY_SI(t)    (0x00001 &((t)>>13))
+#define SYNA_CSI_DATA_Q8_REAL(t) \
+(((0 < _Q8_REAL_SI(t)) \
+	? (-1) \
+	: (1)) \
+	* ((int32)_Q8_REAL_MA(t)) \
+)
+#define SYNA_CSI_DATA_Q8_IMAGINARY(t) \
+(((0 < _Q8_IMAGINARY_SI(t)) \
+	? (-1) \
+	: (1)) \
+	* ((int32)_Q8_IMAGINARY_MA(t)) \
+)
+#define SYNA_CSI_DATA_Q8_EXP(t) \
+(((int8)(0xf8 \
+	& ((t) << 3))) \
+	>> 3 \
+)
+/* (10,10,5) Q9 floating point format */
+#define _Q9_REAL_MA(t)         (0x001ff &((t)>>15))
+#define _Q9_REAL_SI(t)         (0x00001 &((t)>>24))
+#define _Q9_IMAGINARY_MA(t)    (0x001ff &((t)>> 5))
+#define _Q9_IMAGINARY_SI(t)    (0x00001 &((t)>>14))
+#define SYNA_CSI_DATA_Q9_REAL(t) \
+(((0 < _Q9_REAL_SI(t)) \
+	? (-1) \
+	: (1)) \
+	* ((int32)_Q9_REAL_MA(t)) \
+)
+#define SYNA_CSI_DATA_Q9_IMAGINARY(t) \
+(((0 < _Q9_IMAGINARY_SI(t)) \
+	? (-1) \
+	: (1)) \
+	* ((int32)_Q9_IMAGINARY_MA(t)) \
+)
+#define SYNA_CSI_DATA_Q9_EXP(t) \
+(((int8)(0xf8 \
+	& ((t) << 3))) \
+	>> 3 \
+)
+/* (12,12,6) Q11 floating point format */
+#define _Q11_REAL_MA(t)         (0x007ff &((t)>>18))
+#define _Q11_REAL_SI(t)         (0x00001 &((t)>>29))
+#define _Q11_IMAGINARY_MA(t)    (0x007ff &((t)>> 6))
+#define _Q11_IMAGINARY_SI(t)    (0x00001 &((t)>>17))
+#define SYNA_CSI_DATA_Q11_REAL(t) \
+(((0 < _Q11_REAL_SI(t)) \
+	? (-1) \
+	: (1)) \
+	* ((int32)_Q11_REAL_MA(t)) \
+)
+#define SYNA_CSI_DATA_Q11_IMAGINARY(t) \
+(((0 < _Q11_IMAGINARY_SI(t)) \
+	? (-1) \
+	: (1)) \
+	* ((int32)_Q11_IMAGINARY_MA(t)) \
+)
+#define SYNA_CSI_DATA_Q11_EXP(t) \
+(((int8)(0xfc \
+	& ((t) << 2))) \
+	>> 2 \
+)
+/* (13,13,0) Q12 fixed point data format */
+#define SYNA_CSI_DATA_Q12_REAL(t) \
+(((int32)(0xfff80000 \
+	& ((t) << 6))) \
+	>> (13 + 6) \
+)
+#define SYNA_CSI_DATA_Q12_IMAGINARY(t) \
+(((int32)(0xfff80000 \
+	& ((t) << 19))) \
+	>> (0 + 19) \
+)
+/* (14,14,0) Q13 fixed point data format */
+#define SYNA_CSI_DATA_Q13_REAL(t) \
+(((int32)(0xfffc0000 \
+	& ((t) << 4))) \
+	>> (14 + 4) \
+)
+#define SYNA_CSI_DATA_Q13_IMAGINARY(t) \
+(((int32)(0xfffc0000 \
+	& ((t) << 18))) \
+	>> (0 + 18) \
+)
+
+/* 8bits */
+enum syna_csi_legacy_error_flag {
+	/* bit 0 ~ bit 7 are for error information */
+	SYNA_CSI_LEGACY_FLAG_ERROR_MASK = 0x007F,
+	SYNA_CSI_LEGACY_FLAG_ERROR_CHECKSUM = (1 << 0),
+	SYNA_CSI_LEGACY_FLAG_ERROR_GENERIC = (1 << 1),
+	SYNA_CSI_LEGACY_FLAG_ERROR_NO_ACK = (1 << 2),
+	SYNA_CSI_LEGACY_FLAG_ERROR_READ = (1 << 3),
+	SYNA_CSI_LEGACY_FLAG_ERROR_PS = (1 << 4),
+	/* subcarrier real position along FFT index: (total N=2*M subcarries)
+	 * -M, -(M-1), -(M-2), -(M-3),...,-1, 0, 1, 2,...M-1, M
+	 *
+	 *  Data Output order with positive part first(*default*):
+	 * 0, 1, 2,...M-1, M,	-M, -(M-1), -(M-2), -(M-3),...,-1,
+	 *
+	 *  Data Output order with negative part first:
+	 * -M, -(M-1), -(M-2), -(M-3),...,-1, 0, 1, 2,...M-1, M
+	 */
+	SYNA_CSI_LEGACY_FLAG_FFT_NEGATIVE_FIRST = (1 << 7),
+	SYNA_CSI_LEGACY_FLAG_ERROR_LAST
+};
+
+/* 16 bits */
+enum syna_csi_error_flag {
+	SYNA_CSI_FLAG_ERROR_NONE = 0x0,
+	SYNA_CSI_FLAG_ERROR_FAILURE = 1,
+	SYNA_CSI_FLAG_ERROR_CHECKSUM = 2,
+	SYNA_CSI_FLAG_ERROR_GENERIC = 3,
+	SYNA_CSI_FLAG_ERROR_OTHER = 4,
+
+	SYNA_CSI_FLAG_ERROR_WRONG_CHANNEL = 10,
+	SYNA_CSI_FLAG_ERROR_WRONG_MODE = 11,
+
+	SYNA_CSI_FLAG_ERROR_TX_FAIL = 20,
+	SYNA_CSI_FLAG_ERROR_TX_NO_ACK = 21,
+
+	SYNA_CSI_FLAG_ERROR_DATA_FEEDBACK_MISS = 30,
+	SYNA_CSI_FLAG_ERROR_DATA_FETCH = 31,
+	SYNA_CSI_FLAG_ERROR_DATA_CONVERT = 32,
+	SYNA_CSI_FLAG_ERROR_DATA_VERIFY = 33,
+	SYNA_CSI_FLAG_ERROR_DATA_LENGTH = 34,
+	SYNA_CSI_FLAG_ERROR_TX_FEEDBACK_MISS = 35,
+	SYNA_CSI_FLAG_ERROR_POWERSAVING = 36,
+	SYNA_CSI_FLAG_ERROR_UNKNOW_CHIPSET = 37,
+
+	/* active mode suppress */
+	SYNA_CSI_FLAG_ERROR_SUPPRESS = 100,
+	SYNA_CSI_FLAG_ERROR_SUPP_PMQ = 101,
+	SYNA_CSI_FLAG_ERROR_SUPP_FLUSH = 102,
+	SYNA_CSI_FLAG_ERROR_SUPP_FRAG = 103,
+	SYNA_CSI_FLAG_ERROR_SUPP_TBTT = 104,
+	SYNA_CSI_FLAG_ERROR_SUPP_BADCH = 105,
+	SYNA_CSI_FLAG_ERROR_SUPP_EXPTIME = 106,
+	SYNA_CSI_FLAG_ERROR_SUPP_UF = 107,
+	SYNA_CSI_FLAG_ERROR_SUPP_ABS = 108,
+	SYNA_CSI_FLAG_ERROR_SUPP_PPS = 109,
+	SYNA_CSI_FLAG_ERROR_SUPP_NOKEY = 110,
+	SYNA_CSI_FLAG_ERROR_SUPP_DMA_XFER = 111,
+	SYNA_CSI_FLAG_ERROR_SUPP_TWT = 112,
+
+	SYNA_CSI_FLAG_ERROR_LAST
+};
+
+/* 16 bits */
+enum syna_csi_feature_flag {
+	SYNA_CSI_FLAG_FEATURE_NONE = 0x0,
+	/* subcarrier real position along FFT index: (total N=2*M subcarries)
+	 * -M, -(M-1), -(M-2), -(M-3),...,-1, 0, 1, 2,...M-1, M
+	 *
+	 *  Data Output order with positive part first(*default*):
+	 * 0, 1, 2,...M-1, M,   -M, -(M-1), -(M-2), -(M-3),...,-1,
+	 *
+	 *  Data Output order with negative part first:
+	 * -M, -(M-1), -(M-2), -(M-3),...,-1, 0, 1, 2,...M-1, M
+	 */
+	SYNA_CSI_FLAG_FEATURE_FFT_NEGATIVE_FIRST = (0x1 << 0),
+	SYNA_CSI_FLAG_FEATURE_LAST
+};
+
+enum syna_csi_dot11_mode {
+	SYNA_CSI_DOT11_UNKNOW,
+	SYNA_CSI_DOT11_B,      /* 11b, CCK */
+	SYNA_CSI_DOT11_G,      /* 11g, legacy OFDM */
+	SYNA_CSI_DOT11_A,      /* 11a, legacy OFDM */
+	SYNA_CSI_DOT11_HT,     /* 11n, HT */
+	SYNA_CSI_DOT11_VHT,    /* 11ac, VHT */
+	SYNA_CSI_DOT11_HE,     /* 11ax, HE */
+	SYNA_CSI_DOT11_EHT,    /* 11be, EHT */
+	SYNA_CSI_DOT11_LAST
+};
+
+enum syna_csi_band_type {
+	SYNA_CSI_BAND_UNKNOWN = 0,
+	SYNA_CSI_BAND_2G,
+	SYNA_CSI_BAND_5G,
+	SYNA_CSI_BAND_6G,
+	SYNA_CSI_BAND_60G,
+	SYNA_CSI_BAND_LAST
+};
+
+enum syna_csi_sideband_type {
+	SYNA_CSI_SB_NONE = 0x0,
+	SYNA_CSI_SB_LLL  = (0x1 << 0),
+	SYNA_CSI_SB_LLU  = (0x1 << 1),
+	SYNA_CSI_SB_LUL  = (0x1 << 2),
+	SYNA_CSI_SB_LUU  = (0x1 << 3),
+	SYNA_CSI_SB_ULL  = (0x1 << 4),
+	SYNA_CSI_SB_ULU  = (0x1 << 5),
+	SYNA_CSI_SB_UUL  = (0x1 << 6),
+	SYNA_CSI_SB_UUU  = (0x1 << 7),
+	SYNA_CSI_SB_FULL = (0x1 << 16)
+};
+
+/* 32bits */
+enum syna_csi_rate_type {
+	SYNA_CSI_RATE_VALUE_MASK = 0x000000FF,
+	SYNA_CSI_RATE_MODE_MASK  = 0xFF000000,
+	SYNA_CSI_RATE_LEGACY     = 0x01000000, /* value part show as 500K unit,
+	                                        * for example,
+	                                        * 0x0100000C => 0x0C => 12 => 6Mbps
+	                                        */
+	SYNA_CSI_RATE_OFDM       = 0x02000000, /* value part show as 500K unit,
+	                                        * for example,
+	                                        * 0x02000030 => 0x30 => 48 => 24Mbps
+	                                        */
+	SYNA_CSI_RATE_HT_MCS     = 0x03000000, /* value part shown as HT MCS
+	                                        * index, for example,
+	                                        * 0x03000007 => HT 0x07 => HT mcs 7
+	                                        */
+	SYNA_CSI_RATE_VHT_MCS    = 0x04000000, /* value part shown as VHT MCS
+	                                        * index, for example,
+	                                        * 0x04000007 => VHT 0x07 => VHT mcs 7
+	                                        */
+	SYNA_CSI_RATE_HE_MCS     = 0x05000000, /* value part shown as HE MCS
+	                                        * index, for example,
+	                                        * 0x05000007 => HE 0x07 => HE mcs 7
+	                                        */
+	SYNA_CSI_RATE_EHT_MCS    = 0x06000000, /* value part shown as EHT MCS
+	                                        * index, for example,
+	                                        * 0x06000007 => EHT 0x07 => EHT mcs 7
+	                                        */
+	SYNA_CSI_RATE_FLAG_MASK  = 0x00FFFF00,
+	SYNA_CSI_RATE_LDPC       = 0x00000100,
+	SYNA_CSI_RATE_STBC       = 0x00000200,
+	SYNA_CSI_RATE_TXBF       = 0x00000400,
+	SYNA_CSI_RATE_DCM        = 0x00000800,
+	SYNA_CSI_RATE_GI_SHIFT   = 14,
+	SYNA_CSI_RATE_GI_MASK    = 0x00003000,
+	SYNA_CSI_RATE_GI_1       = 0x00001000,
+	SYNA_CSI_RATE_GI_2       = 0x00002000,
+	SYNA_CSI_RATE_GI_3       = 0x00003000
+};
+
+enum syna_csi_bandwidth_type {
+	SYNA_CSI_BW_UNKNOWN = 0x0,
+	SYNA_CSI_BW_5MHz    = (0x1 << 0),
+	SYNA_CSI_BW_10MHz   = (0x1 << 1),
+	SYNA_CSI_BW_20MHz   = (0x1 << 2),
+	SYNA_CSI_BW_40MHz   = (0x1 << 3),
+	SYNA_CSI_BW_80MHz   = (0x1 << 4),
+	SYNA_CSI_BW_160MHz  = (0x1 << 5),
+	SYNA_CSI_BW_320MHz  = (0x1 << 6)
+};
+
+/* 'SYNA' -> 'S'53, 'Y'59, 'N'4E, 'A'41 */
+#define CONST_SYNA_CSI_MAGIC_FLAG               0x414E5953
+
+/* CSI API common header structure (8 bytes alignment for 64bit system) */
+/* Version 1 'syna_csi_header' (8 bytes alignment for 64bit system) */
+#define CONST_SYNA_CSI_HEADER_VERSION_V1    0x01
+struct syna_csi_header_v1 {
+	/* byte 0 ~ 3 */
+	uint32  magic_flag;       /* flag for protecting and detecting header */
+
+	/* byte 4 ~ 7 */
+	uint8  version;           /* header version of this structure */
+	uint8  format_type;       /* data format type of current CSI packet,
+	                           * enumerated in 'syna_csi_format_type'
+	                           */
+	uint8  fc;                /* packet frame control type of current
+	                           * CSI data for further checking if it
+	                           * is correct expected result
+	                           */
+	uint8  flags;             /* flag may use for extra emendation
+	                           * which enumerated as 'syna_csi_flag'
+	                           */
+
+	/* byte 8 ~ 19 */
+	uint8  client_ea[6];      /* client MAC address */
+	uint8  bsscfg_ea[6];      /* BSSCFG address of current interface */
+
+	/* byte 20 ~ 23 */
+	uint8  band;              /* enumerated in 'syna_csi_band_type' */
+	uint8  bandwidth;         /* enumerated in 'syna_csi_bandwidth_type' */
+	uint16 channel;           /* channel number of corresponding band */
+
+	/* byte 24 ~ 31 */
+	uint64 report_tsf;        /* current CSI DATA RX timestamp */
+	/* byte 32 ~ 35 */
+
+	uint8  num_txstream;      /* peer side TX spatial steams */
+	uint8  num_rxchain;       /* number of RX side chain/antenna */
+	uint16 num_subcarrier;    /* Number of subcarrier */
+
+	/* byte 36 ~ 39 */
+	int8   rssi;              /* average RSSI, and goto check the
+	                           * 'rssi_ant' if this 'rssi' is zero
+	                           */
+	int8   noise;             /* average noise */
+	int16  global_id;         /* CSI frame global ID */
+
+	/* byte 40 ~ 47 */
+	int8   rssi_ant[8];       /* RSSI of each RX chain/antenna
+	                           * (Depends on solution, and some
+	                           * chipsets may only provide 'rssi'
+	                           * rather than 'rssi_ant')
+	                           */
+
+	/* byte 48 ~ 55 */
+	uint64 padding_future;    /* reserved */
+
+	/* byte 56 ~ 63 */
+	uint16 data_length;       /* the bytes of 'data[]' */
+	uint16 remain_length;     /* remain length of not received data */
+	uint16 copied_length;     /* the length has been copied to user */
+	uint16 data_checksum;     /* 'data[]' checksum, 0 - not used */
+
+	/* byte 64 ~ End */
+	uint32 data[0];           /* variable length according to the
+	                           * 'data_length', but the minimal
+	                           * valid data length will be
+	                           * decided by the 'num_txchains'
+	                           * 'num_rxchain' 'num_subcarrier'.
+	                           * For example, the index quantity
+	                           * of 'uint32' in the 11N 80MHz can
+	                           * be got via:
+	                           * 256 SubCarriers * 2 TXStream * 2 RXChain
+	                           * Note: 'data_length' is bytes quantity,
+	                           * and the 'data[]' array index range should
+	                           * be 0 ~ (data_length/4 - 1)
+	                           */
+};
+
+#define SYNA_CSI_PKT_V1_TOTAL_LEN(ptr) \
+(sizeof(struct syna_csi_header_v1) \
+	+ (((struct syna_csi_header_v1 *)(ptr))->data_length) \
+)
+
+/* Version 2 'syna_csi_header' (8 bytes alignment for 64bit system) */
+#define CONST_SYNA_CSI_HEADER_VERSION_V2    0x02
+struct syna_csi_header_v2 {
+	/* byte 0 ~ 3 */
+	uint32 magic_flag;        /* flag for protecting and detecting header */
+	/* byte 4 ~ 7 */
+	uint8  version;           /* header version of this structure */
+	uint8  format_type;       /* data format type of current CSI packet,
+	                           * enumerated in 'syna_csi_format_type'
+	                           */
+	uint16 frame_control;     /* packet frame control type of current
+	                           * CSI data for further checking if it
+	                           * is the expected result
+	                           */
+
+	/* byte 8 ~ 11 */
+	uint32 global_id;         /* CSI frame global ID */
+	/* byte 12 ~ 15 */
+	uint16 header_length;     /* total header length of 'syna_csi_header',
+	                           * and this offset can be used to find the
+	                           * right data[] offset among different
+	                           * version header structure.
+	                           */
+	uint8  trigger_mode;      /* active/passive working mode in the
+	                           *'eSyna_csi_trigger_mode'
+	                           */
+	uint8  dot11_mode;        /* 802.11 RX mode in 'syna_csi_dot11_mode' */
+
+	/* byte 16 ~ 23 */
+	uint64 report_tsf;        /* current CSI DATA RX/generated timestamp */
+
+	/* byte 24 ~ 27 */
+	uint16 flag_error;        /* error flag may use for extra emendation
+	                           * which enumerated as 'syna_csi_error_flag'
+	                           */
+	uint16 flag_feature;      /* feature flag in 'syna_csi_feature_flag' */
+	/* byte 28 ~ 39 */
+	uint8  peer_mac[6];       /* peer side transmitor MAC address */
+	uint8  local_mac[6];      /* local side receiver MAC address */
+
+	/* byte 40 ~ 43 */
+	uint8  qty_txstream;      /* peer side TX spatial steams */
+	uint8  qty_rxchain;       /* quantity of RX side chain/antenna */
+	uint16 qty_subcarrier;    /* quantity of sub-carriers */
+
+	/* byte 44 ~ 45 */
+	uint16 chipset_flag;      /* chipset flag */
+	/* byte 46 ~ 51 */
+	uint8  band;              /* enumerated in 'syna_csi_band_type' */
+	uint8  side_band;         /* side band in 'syna_csi_sideband_type' */
+	uint16 bandwidth;         /* PHY RX bandwidth which enumerated in
+	                           *'syna_csi_bandwidth_type'
+	                           */
+	uint16 channel;           /* channel number of corresponding band */
+	/* byte 52 ~ 55 */
+	uint32 rx_rate;           /* rate information as 'syna_csi_rate_type' */
+
+	/* byte 56 ~ 57 */
+	uint8  rx_bandwidth;      /* frame bandwidth which enumerated in
+	                           * 'syna_csi_bandwidth_type'
+	                           */
+	uint8  rxchain_idx_mask;  /* bit index based RX chain/antenna mask,
+	                           * 1 - core 0(bit0), 2 - core 1(bit1)
+	                           * 3 - core 0(bit0) + core 1(bit1)
+	                           */
+	/* byte 58 ~ 59 */
+	int8   rssi;              /* average RSSI (dBm), and goto check the
+	                           * 'rssi_ant' if this 'rssi' is zero
+	                           */
+	int8   noise;             /* average noise (dBm) */
+
+	/* byte 60 ~ 63 */
+	int8   rssi_ant[4];       /* RSSI of each RX chain/antenna
+	                           * (Depends on solution, and some
+	                           * chipsets may only provide 'rssi'
+	                           * rather than 'rssi_ant')
+	                           */
+
+	/* byte 64 ~ 75 */
+	uint8  padding[12];       /* reserved for reuse */
+
+	/* byte 76 ~ 79 */
+	uint16 data_length;       /* the bytes of 'data[]' */
+	uint16 data_checksum;     /* 'data[]' checksum, 0 - not used */
+
+	/* byte 80 ~ End */
+	uint32 data[0];           /* variable length according to the
+	                           * 'data_length', but the minimal
+	                           * valid data length will be
+	                           * decided by the 'num_txchains'
+	                           * 'num_rxchain' 'num_subcarrier'.
+	                           * For example, the index quantity
+	                           * of 'uint32' in the 11N 80MHz can
+	                           * be got via:
+	                           * 256 SubCarriers * 2 TXStream * 2 RXChain
+	                           * Note: 'data_length' is bytes quantity,
+	                           * and the 'data[]' array index range should
+	                           * be 0 ~ (data_length/4 - 1)
+	                           * It's better to use 'header_length' to
+	                           * count the 'data[]' offset to exclude
+	                           * different version header structure's
+	                           * difference.
+	                           */
+};
+
+#define SYNA_CSI_PKT_V2_TOTAL_LEN(ptr) \
+(sizeof(struct syna_csi_header_v2) \
+	+ (((struct syna_csi_header_v2 *)(ptr))->data_length) \
+)
+
+/* common header for transfering */
+typedef struct syna_csi_header_v2                  syna_csi_common_header;
+#define CONST_SYNA_CSI_COMMON_HEADER_VERSION       CONST_SYNA_CSI_HEADER_VERSION_V2
+#define SYNA_CSI_COMMON_PKT_TOTAL_LEN(ptr)         SYNA_CSI_PKT_V2_TOTAL_LEN(ptr)
+
+/* Output V1 CSI Header to upper layer by default for compatibility */
+#define CONST_CSI_HEADER_VERSION_OUTPUT_DEFAULT    CONST_SYNA_CSI_HEADER_VERSION_V1
+
+/* Maxinum csi file dump size */
+#define CONST_CSI_SYS_FILE_SIZE_MAX		(1024 * 32)
+/* maximun csi packet number stored here: 30Hz * 120 seconds * STA */
+#define CONST_CSI_MAX_STA_QTY			16
+#define CONST_CSI_QUEUE_MAX_SIZE		((1024 * 4) * CONST_CSI_MAX_STA_QTY)
+
+/* definition for structure and functions between driver and FW */
+/* revision 0 'dhd_cfr_header' (can only access by byte due to not aligned!) */
+#define CONST_CFR_HEADER_REVISION_0	0 /* cfr header version V0 */
+struct dhd_cfr_header_rev_0 {
+	uint8 status:4;     /* bit3-0 */
+	uint8 version:4;    /* bit7-4 */
+	/* Peer MAC address */
+	uint8 peer_macaddr[6];
+	/* Number of Space Time Streams */
+	uint8 sts;
+	/* Number of RX chain */
+	uint8 num_rx;
+	/* Number of subcarrier */
+	uint16 num_carrier;
+	/* Length of the CSI dump */
+	uint32 cfr_dump_length;
+	/* remain unsend CSI data length */
+	uint32 remain_length;
+	/* RSSI */
+	int8 rssi;
+	uint32 data[0];
+} __attribute__ ((packed));
+
+/* revision 1 'dhd_cfr_header' (can only access by byte due to not aligned!) */
+#define CONST_CFR_HEADER_REVISION_1	1 /* cfr header version V1 */
+struct dhd_cfr_header_rev_1 {
+	uint8 status:4;     /* bit3-0 */
+	uint8 version:4;    /* bit7-4 */
+	/* Peer MAC address */
+	uint8 peer_macaddr[6];
+	/* Number of Space Time Streams */
+	uint8 sts;
+	/* Number of RX chain */
+	uint8 num_rx;
+	/* Number of subcarrier */
+	uint16 num_carrier;
+	/* Length of the CSI dump */
+	uint32 cfr_dump_length;
+	/* remain unsend CSI data length */
+	uint32 remain_length;
+	/* RSSI */
+	int8 rssi;
+
+	/* Chip id. 1 for BCM43456/8 */
+	uint8 chip_id;
+	/* Frame control field */
+	uint8 fc;
+	/* Time stamp when CFR capture is taken,
+	 * in microseconds since the epoch
+	 */
+	uint64 cfr_timestamp;
+
+	uint32 data[0];
+} __attribute__ ((packed));
+
+/* revision 2 'dhd_cfr_header' (8 bytes alignment for 64bit system) */
+#define CONST_CFR_HEADER_REVISION_2	2 /* cfr header version V2 */
+struct dhd_cfr_header_rev_2 {
+	/* byte 0 ~ 7 */
+	uint8  status_compat:4;   /* bit3-0, current CSI data status: 0->good */
+	uint8  version_compat:4;  /* bit7-4, duplicate but compatible part */
+	uint8  padding_magic;
+	uint16 magic_flag;        /* flag for protecting and detecting header */
+
+	uint8  version;           /* header version of this structure */
+	uint8  format_type;       /* data format type of current CSI packet,
+	                           * enumerated in 'syna_csi_format_type'
+	                           */
+	uint8  fc;                /* packet frame control type of current
+	                           * CSI data for further checking if it
+	                           * is correct expected result
+	                           */
+	uint8  flags;             /* flag may use for extra emendation
+	                           * which enumerated as 'syna_csi_flag'
+	                           */
+
+	/* byte 8 ~ 19 */
+	uint8  client_ea[6];      /* client MAC address */
+	uint8  bsscfg_ea[6];      /* BSSCFG address of current interface */
+
+	/* byte 20 ~ 23 */
+	uint8  band;              /* enumerated in 'syna_csi_band_type' */
+	uint8  bandwidth;         /* enumerated in 'syna_csi_bandwidth_type' */
+	uint16 channel;           /* channel number of corresponding band */
+
+	/* byte 24 ~ 31 */
+	uint64 report_tsf;        /* current CSI DATA RX timestamp */
+
+	/* byte 32 ~ 35 */
+	uint8  num_txstream;      /* peer side TX spatial steams */
+	uint8  num_rxchain;       /* number of RX side chain/antenna */
+	uint16 num_subcarrier;    /* Number of subcarrier */
+
+	/* byte 36 ~ 39 */
+	int8   rssi;              /* average RSSI, and goto check the
+	                           * 'rssi_ant' if this 'rssi' is zero
+	                           */
+	int8   noise;             /* average noise */
+	int16  global_id;         /* CSI frame global ID */
+
+	/* byte 40 ~ 47 */
+	int8   rssi_ant[8];       /* RSSI of each RX chain/antenna
+	                           * (Depends on solution, and some
+	                           * chipsets may only provide 'rssi'
+	                           * rather than 'rssi_ant')
+	                           */
+
+	/* byte 48 ~ 55 */
+	uint64 padding_future;    /* reserved */
+
+	/* byte 56 ~ 63 */
+	uint16 data_length;       /* the bytes of 'data[]' */
+	uint16 remain_length;     /* the remain unsent length of 'data[]' */
+	uint16 padding_length;    /* reserved */
+	uint16 data_checksum;     /* 'data[]' checksum, 0 - not used */
+
+	/* byte 64 ~ End */
+	uint32 data[0];           /* variable according to 'data_length', but
+	                           * the minial valid data length will be
+	                           * decided by 'num_txchains', 'num_rxchain'
+	                           * 'num_subcarrier'. For example, the
+	                           * quantity of uint32(4 bytes) in the
+	                           * 11N 80MHz can be got via:
+	                           * 256 SubCarriers * 2 TXStream * 2 RXChain
+	                           */
+};
+
+/* revision 3 'dhd_cfr_header' (8 bytes alignment for 64bit system) */
+#define CONST_CFR_HEADER_REVISION_3	3 /* cfr header version V3 */
+struct dhd_cfr_header_rev_3 {
+	/* byte 0 ~ 3 */
+	uint8  status_compat:4;   /* bit3-0, current CSI data status: 0->good */
+	uint8  version_compat:4;  /* bit7-4, duplicate but compatible part */
+	uint8  padding_magic;     /* reserved for compatibility */
+	uint16 magic_flag;        /* flag for protecting and detecting header */
+	/* byte 4 ~ 7 */
+	uint8  version;           /* header version of this structure */
+	uint8  format_type;       /* data format type of current CSI packet,
+	                           * enumerated in 'syna_csi_format_type'
+	                           */
+	uint16 frame_control;     /* packet frame control type of current
+	                           * CSI data for further checking if it
+	                           * is the expected result
+	                           */
+
+	/* byte 8 ~ 11 */
+	uint32 global_id;         /* CSI frame global ID */
+	/* byte 12 ~ 15 */
+	uint16 header_length;     /* total header length of 'syna_csi_header',
+	                           * and this offset can be used to find the
+	                           * right data[] offset among different
+	                           * version header structure.
+	                           */
+	uint8  trigger_mode;      /* active/passive working mode in the
+	                           *'eSyna_csi_trigger_mode'
+	                           */
+	uint8  dot11_mode;        /* 802.11 RX mode in 'syna_csi_dot11_mode' */
+
+	/* byte 16 ~ 23 */
+	uint64 report_tsf;        /* current CSI DATA RX/generated timestamp */
+
+	/* byte 24 ~ 27 */
+	uint16 flag_error;        /* error flag may use for extra emendation
+	                           * which enumerated as 'syna_csi_error_flag'
+	                           */
+	uint16 flag_feature;      /* feature flag in 'syna_csi_feature_flag' */
+	/* byte 28 ~ 39 */
+	uint8  peer_mac[6];       /* peer side transmitor MAC address */
+	uint8  local_mac[6];      /* local side receiver MAC address */
+
+	/* byte 40 ~ 43 */
+	uint8  qty_txstream;      /* peer side TX spatial steams */
+	uint8  qty_rxchain;       /* quantity of RX side chain/antenna */
+	uint16 qty_subcarrier;    /* quantity of sub-carriers */
+
+	/* byte 44 ~ 45 */
+	uint16 chipset_flag;      /* chipset flag */
+	/* byte 46 ~ 51 */
+	uint8  band;              /* enumerated in 'syna_csi_band_type' */
+	uint8  side_band;         /* side band in 'syna_csi_sideband_type' */
+	uint16 bandwidth;         /* PHY RX bandwidth which enumerated in
+	                           *'syna_csi_bandwidth_type'
+	                           */
+	uint16 channel;           /* channel number of corresponding band */
+	/* byte 52 ~ 55 */
+	uint32 rx_rate;           /* rate information as 'syna_csi_rate_type' */
+
+	/* byte 56 ~ 57 */
+	uint8  rx_bandwidth;      /* frame bandwidth which enumerated in
+	                           * 'syna_csi_bandwidth_type'
+	                           */
+	uint8  rxchain_idx_mask;  /* bit index based RX chain/antenna mask,
+	                           * 1 - core 0(bit0), 2 - core 1(bit1)
+	                           * 3 - core 0(bit0) + core 1(bit1)
+	                           */
+	/* byte 58 ~ 59 */
+	int8   rssi;              /* average RSSI (dBm), and goto check the
+	                           * 'rssi_ant' if this 'rssi' is zero
+	                           */
+	int8   noise;             /* average noise (dBm) */
+
+	/* byte 60 ~ 63 */
+	int8   rssi_ant[4];       /* RSSI of each RX chain/antenna
+	                           * (Depends on solution, and some
+	                           * chipsets may only provide 'rssi'
+	                           * rather than 'rssi_ant')
+	                           */
+
+	/* byte 64 ~ 71 */
+	uint64 padding_future;    /* reserved for reuse */
+
+	/* byte 72 ~ 79 */
+	uint16 padding_data;      /* reserved for compatibility */
+	uint16 remain_length;     /* remain length of not received data */
+	uint16 data_length;       /* the bytes of 'data[]' */
+	uint16 data_checksum;     /* 'data[]' checksum, 0 - not used */
+
+	/* byte 80 ~ End */
+	uint32 data[0];           /* variable length according to the
+	                           * 'data_length', but the minimal
+	                           * valid data length will be
+	                           * decided by the 'num_txchains'
+	                           * 'num_rxchain' 'num_subcarrier'.
+	                           * For example, the index quantity
+	                           * of 'uint32' in the 11N 80MHz can
+	                           * be got via:
+	                           * 256 SubCarriers * 2 TXStream * 2 RXChain
+	                           * Note: 'data_length' is bytes quantity,
+	                           * and the 'data[]' array index range should
+	                           * be 0 ~ (data_length/4 - 1)
+	                           * It's better to use 'header_length' to
+	                           * count the 'data[]' offset to exclude
+	                           * different version header structure's
+	                           * difference.
+	                           */
+};
+
+/* union structure for decoding the version */
+union dhd_cfr_header {
+	struct dhd_cfr_header_rev_0  header_rev_0;
+	struct dhd_cfr_header_rev_1  header_rev_1;
+	struct dhd_cfr_header_rev_2  header_rev_2;
+	struct dhd_cfr_header_rev_3  header_rev_3;
+};
+#define CSI_CFG_PKT_LENGTH(pHeader) \
+(\
+	(CONST_CFR_HEADER_REVISION_0 == pHeader->header_rev_0.version) \
+	?(sizeof(struct dhd_cfr_header_rev_0) + ((pHeader)->header_rev_0.cfr_dump_length)) \
+	:(CONST_CFR_HEADER_REVISION_1 == pHeader->header_rev_0.version) \
+	?(sizeof(struct dhd_cfr_header_rev_1) + ((pHeader)->header_rev_1.cfr_dump_length)) \
+	:(CONST_CFR_HEADER_REVISION_2 == pHeader->header_rev_0.version) \
+	?(sizeof(struct dhd_cfr_header_rev_2) + ((pHeader)->header_rev_2.data_length)) \
+	:(CONST_CFR_HEADER_REVISION_3 == pHeader->header_rev_0.version) \
+	?(sizeof(struct dhd_cfr_header_rev_3) + ((pHeader)->header_rev_3.data_length)) \
+	:(0) \
+)
+#define CSI_CFR_MAXIMUM_LENGTH(data_len) \
+	(sizeof(union dhd_cfr_header) + data_len)
+
+/* 11ax/HE BW80 2x2 => 4bytes * (256*4)subcarries * 2txstream * 2rxchain */
+#define CONST_CSI_DATA_BYTES_MAX          (CSI_CFR_MAXIMUM_LENGTH((256*4) *2 *2 *4))
+
+#define CONST_SYNA_SOCKET_HEADER_BYTES    (14 + 20 + 8)
+
+struct csi_cfr_node {
+	struct list_head  list;
+	void   *pNode; /* recording current node pointer
+	                * especially for UDP data manner
+	                */
+
+	uint32  total_size;
+	uint16  ifidx;
+	uint16  send_manner;
+
+	/* for packet reference */
+	uint16  length_data_total;
+	uint16  length_data_received;
+	uint16  length_data_remain;
+	uint16  length_data_copied;
+	uint32  global_id;
+	 int16  convert_pull;
+	uint8   peer_mac[ETHER_ADDR_LEN];
+	uint8   padding[4];
+
+	/* layout for skb:
+	 *   alignment_padding(6)
+	 *   header_ethernet(14)
+	 *   header_ip(20)
+	 *   header_udp(8)
+	 *     csi_header(80)
+	 *     csi_data(N)
+	 */
+	uint8  network_padding[CONST_SYNA_SOCKET_HEADER_BYTES];
+	/* should make this be 8 bytes alignment */
+	syna_csi_common_header  *pHeader_csi;
+};
+
+#define CONST_SYNA_CSI_CFR_NODE_LEN          sizeof(struct csi_cfr_node)  /* 112 */
+
+#define CONST_SYNA_CSI_CFR_NODE_LEN_WITH_COMMON_HEADER(ptr, data_length) \
+(\
+	CONST_SYNA_CSI_CFR_NODE_LEN + data_length \
+)
+
+#define SYNA_CSI_CFR_NODE_FREE_LEN(ptr) \
+(\
+	((struct csi_cfr_node *)(ptr))->total_size \
+	- CONST_SYNA_CSI_CFR_NODE_LEN \
+)
+
+extern int dhd_csi_version(dhd_pub_t *dhdp, char *pBuf, uint length, bool is_set);
+extern int dhd_csi_config(dhd_pub_t *dhdp, char *buf, uint length, bool is_set);
+
+/* Function: change the upper layer fetching data manner
+ * Input:  uint  is_set        indicate it's set or get action
+ *         uint  type          the expected fetch type(ignore when get)
+ *         uint  param         extra param when set(UDP socket port)
+ * Output: <  0        error encounter
+ *         == 0        successful
+ *         >  0        corresponding 'fetch type' when get
+ */
+extern int dhd_csi_data_fetch_type_access(uint is_set, uint type, uint param);
+
+/* Function: parse the CSI event and convert to 'dhd_csi_header' format,
+ *           and queue the item into the common 'csi_cfr_queue'
+ * Input:  dhd_pub_t    *dhdp     context for operation
+ *         char         *buf      buffer for storing csi data
+ *         uint          count    total bytes available in 'buf'
+ * Output: <  0        error encounter
+ *         == 0        successful but no csi data in queue
+ *         >  0        bytes write into 'buf'
+ */
+extern int dhd_csi_data_queue_polling(dhd_pub_t *dhdp, char *buf, uint count);
+
+/* Function: push the skb packet into the CSI raw skb queue for later
+ *           processing since DPC context maybe atomic and can't do
+ *           'schedule'/interruptible work like IOVAR or printf
+ * Input:  dhd_pub_t  *dhdp       context for operation
+ *         int        *ifidx      interface index
+ *         void       *pktbuf     raw skb pointer
+ * Output: <  0        error encounter
+ *         == 0        successful
+ * Note:   the skb will be internally processed and freed if enqueue successfully
+ */
+extern int dhd_csi_event_enqueue(dhd_pub_t  *dhdp, int ifidx, void *pktbuf);
+
+/* Function: Initialize the CSI module
+ * Input:  dhd_pub_t      *dhdp          context for operation
+ * Output: <  0        error encounter
+ *         == 0        successful
+ */
+extern int dhd_csi_init(dhd_pub_t *dhdp);
+
+/* Function: Deinitialize the CSI module
+ * Input:  dhd_pub_t      *dhdp          context for operation
+ * Output: <  0        error encounter
+ *         == 0        successful
+ */
+extern int dhd_csi_deinit(dhd_pub_t *dhdp);
+
+#endif /* CSI_SUPPORT */
+
+#endif /* __DHD_CSI_H__ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_custom_gpio.c
@@ -0,0 +1,511 @@
+/*
+ * Customer code to add GPIO control during WLAN start/stop
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_linux.h>
+
+#include <wlioctl.h>
+
+#include <dhd_dbg.h>
+
+#ifndef BCMDONGLEHOST
+#include <wlc_pub.h>
+#include <wl_dbg.h>
+#else
+#define WL_ERROR(x) printf x
+#define WL_TRACE(x)
+#endif
+
+#if defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID)
+
+#if defined(BCMLXSDMMC)
+extern int sdioh_mmc_irq(int irq);
+#endif /* (BCMLXSDMMC)  */
+
+/* Customer specific Host GPIO defintion  */
+static int dhd_oob_gpio_num = -1;
+
+module_param(dhd_oob_gpio_num, int, 0644);
+MODULE_PARM_DESC(dhd_oob_gpio_num, "DHD oob gpio number");
+
+/* This function will return:
+ *  1) return :  Host gpio interrupt number per customer platform
+ *  2) irq_flags_ptr : Type of Host interrupt as Level or Edge
+ *
+ *  NOTE :
+ *  Customer should check his platform definitions
+ *  and his Host Interrupt spec
+ *  to figure out the proper setting for his platform.
+ *  Broadcom provides just reference settings as example.
+ *
+ */
+int dhd_customer_oob_irq_map(void *adapter, unsigned long *irq_flags_ptr)
+{
+	int  host_oob_irq = 0;
+
+#if defined(BOARD_HIKEY)
+	host_oob_irq = wifi_platform_get_irq_number(adapter, irq_flags_ptr);
+
+#else
+#if defined(CUSTOM_OOB_GPIO_NUM)
+	if (dhd_oob_gpio_num < 0) {
+		dhd_oob_gpio_num = CUSTOM_OOB_GPIO_NUM;
+	}
+#endif /* CUSTOMER_OOB_GPIO_NUM */
+
+	if (dhd_oob_gpio_num < 0) {
+		WL_ERROR(("%s: ERROR customer specific Host GPIO is NOT defined \n",
+		__FUNCTION__));
+		return (dhd_oob_gpio_num);
+	}
+
+	WL_ERROR(("%s: customer specific Host GPIO number is (%d)\n",
+	         __FUNCTION__, dhd_oob_gpio_num));
+
+#endif /* BOARD_HIKER */
+
+	return (host_oob_irq);
+}
+#endif /* defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID) */
+
+/* Customer function to control hw specific wlan gpios */
+int
+dhd_customer_gpio_wlan_ctrl(void *adapter, int onoff)
+{
+	int err = 0;
+
+	return err;
+}
+
+#ifdef GET_CUSTOM_MAC_ENABLE
+/* Function to get custom MAC address */
+int
+dhd_custom_get_mac_address(void *adapter, unsigned char *buf)
+{
+	int ret = 0;
+
+	WL_TRACE(("%s Enter\n", __FUNCTION__));
+	if (!buf)
+		return -EINVAL;
+
+	/* Customer access to MAC address stored outside of DHD driver */
+#if defined(BOARD_HIKEY) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
+	ret = wifi_platform_get_mac_addr(adapter, buf);
+#endif
+
+#ifdef EXAMPLE_GET_MAC
+	/* EXAMPLE code */
+	{
+		struct ether_addr ea_example = {{0x00, 0x11, 0x22, 0x33, 0x44, 0xFF}};
+		bcopy((char *)&ea_example, buf, sizeof(struct ether_addr));
+	}
+#endif /* EXAMPLE_GET_MAC */
+
+	return ret;
+}
+#endif /* GET_CUSTOM_MAC_ENABLE */
+
+#ifdef SYNA_SAR_CUSTOMER_PARAMETER
+struct customer_cntry_list {
+	eCountry_flag_type  type;
+	char                ccode[WLC_CNTRY_BUF_SZ];   /* Country code */
+};
+
+/* maximum: (A~Z+0~9) * (A~Z+0~9) = (26+10)*(26+10) = 1296 */
+#define MAX_COUNTRY_LIST        500
+struct customer_cntry_list syna_cntry_flag[MAX_COUNTRY_LIST] = {
+	/* FCC TYPE */
+	{SYNA_COUNTRY_TYPE_FCC, "AG"},
+	{SYNA_COUNTRY_TYPE_FCC, "AI"},
+	{SYNA_COUNTRY_TYPE_FCC, "AR"},
+	{SYNA_COUNTRY_TYPE_FCC, "AW"},
+	{SYNA_COUNTRY_TYPE_FCC, "BB"},
+	{SYNA_COUNTRY_TYPE_FCC, "BL"},
+	{SYNA_COUNTRY_TYPE_FCC, "BM"},
+	{SYNA_COUNTRY_TYPE_FCC, "BO"},
+	{SYNA_COUNTRY_TYPE_FCC, "BS"},
+	{SYNA_COUNTRY_TYPE_FCC, "BZ"},
+	{SYNA_COUNTRY_TYPE_FCC, "CA"},
+	{SYNA_COUNTRY_TYPE_FCC, "CL"},
+	{SYNA_COUNTRY_TYPE_FCC, "CO"},
+	{SYNA_COUNTRY_TYPE_FCC, "CR"},
+	{SYNA_COUNTRY_TYPE_FCC, "CW"},
+	{SYNA_COUNTRY_TYPE_FCC, "DO"},
+	{SYNA_COUNTRY_TYPE_FCC, "EC"},
+	{SYNA_COUNTRY_TYPE_FCC, "FM"},
+	{SYNA_COUNTRY_TYPE_FCC, "GT"},
+	{SYNA_COUNTRY_TYPE_FCC, "GU"},
+	{SYNA_COUNTRY_TYPE_FCC, "GY"},
+	{SYNA_COUNTRY_TYPE_FCC, "HN"},
+	{SYNA_COUNTRY_TYPE_FCC, "HT"},
+	{SYNA_COUNTRY_TYPE_FCC, "IN"},
+	{SYNA_COUNTRY_TYPE_FCC, "IR"},
+	{SYNA_COUNTRY_TYPE_FCC, "JM"},
+	{SYNA_COUNTRY_TYPE_FCC, "KH"},
+	{SYNA_COUNTRY_TYPE_FCC, "KN"},
+	{SYNA_COUNTRY_TYPE_FCC, "KR"},
+	{SYNA_COUNTRY_TYPE_FCC, "KY"},
+	{SYNA_COUNTRY_TYPE_FCC, "LC"},
+	{SYNA_COUNTRY_TYPE_FCC, "MF"},
+	{SYNA_COUNTRY_TYPE_FCC, "MP"},
+	{SYNA_COUNTRY_TYPE_FCC, "NI"},
+	{SYNA_COUNTRY_TYPE_FCC, "PA"},
+	{SYNA_COUNTRY_TYPE_FCC, "PE"},
+	{SYNA_COUNTRY_TYPE_FCC, "PG"},
+	{SYNA_COUNTRY_TYPE_FCC, "PM"},
+	{SYNA_COUNTRY_TYPE_FCC, "PW"},
+	{SYNA_COUNTRY_TYPE_FCC, "PR"},
+	{SYNA_COUNTRY_TYPE_FCC, "PY"},
+	{SYNA_COUNTRY_TYPE_FCC, "SR"},
+	{SYNA_COUNTRY_TYPE_FCC, "SV"},
+	{SYNA_COUNTRY_TYPE_FCC, "SX"},
+	{SYNA_COUNTRY_TYPE_FCC, "TC"},
+	{SYNA_COUNTRY_TYPE_FCC, "TT"},
+	{SYNA_COUNTRY_TYPE_FCC, "US"},
+	{SYNA_COUNTRY_TYPE_FCC, "UY"},
+	{SYNA_COUNTRY_TYPE_FCC, "VC"},
+	{SYNA_COUNTRY_TYPE_FCC, "VE"},
+	{SYNA_COUNTRY_TYPE_FCC, "VG"},
+	{SYNA_COUNTRY_TYPE_FCC, "VI"},
+	{SYNA_COUNTRY_TYPE_FCC, "VU"},
+	{SYNA_COUNTRY_TYPE_FCC, "WF"},
+	{SYNA_COUNTRY_TYPE_FCC, "WS"},
+	{SYNA_COUNTRY_TYPE_INVALID, ""}
+};
+
+static int gSyna_country_flag_qty = 55;
+
+static int syna_country_flag_find(char *cntry)
+{
+	char country[WLC_CNTRY_BUF_SZ];
+	int  ret = BCME_NOTFOUND;
+	int  n;
+
+	if (!cntry) {
+		DHD_ERROR(("%s: invalid cntry!\n", __FUNCTION__));
+		return BCME_BADARG;
+	} else {
+		n = strcspn(cntry, " ,");
+		if ((n != 2) && (n != 3)) {
+			DHD_ERROR(("%s: invalid n=%d!\n", __FUNCTION__, n));
+			return BCME_BUFTOOLONG;
+		} else {
+			strlcpy(country, cntry, WLC_CNTRY_BUF_SZ);
+			country[n] = '\0';
+			DHD_TRACE(("%s: here n=%d, country='%s'!\n",
+			           __FUNCTION__, n, country));
+		}
+	}
+
+	n = 0;
+	while ((MAX_COUNTRY_LIST > n) &&
+	       (SYNA_COUNTRY_TYPE_INVALID != syna_cntry_flag[n].type) &&
+	       (0 < strlen(syna_cntry_flag[n].ccode))) {
+		if (!strncmp(country, syna_cntry_flag[n].ccode, WLC_CNTRY_BUF_SZ)) {
+			ret = n;
+			break;
+		} else {
+			n++;
+		}
+	}
+
+	/* sync up the quantity for appending new item */
+	if ((MAX_COUNTRY_LIST > n) &&
+	    (SYNA_COUNTRY_TYPE_INVALID == syna_cntry_flag[n].type)) {
+		gSyna_country_flag_qty = n;
+		DHD_TRACE(("%s: update qty=%d!\n", __FUNCTION__, n));
+	}
+
+	return ret;
+}
+
+eCountry_flag_type syna_country_check_type(char *cntry)
+{
+	int ret = SYNA_COUNTRY_TYPE_INVALID;
+	int i;
+
+	i = syna_country_flag_find(cntry);
+	if (0 <= i) {
+		ret = syna_cntry_flag[i].type;
+	}
+
+	return ret;
+}
+
+int syna_country_update_type_list(eCountry_flag_type type, char *list_str)
+{
+	char   *next = NULL;
+	int     n = 0;
+	size_t  len;
+
+	if (SYNA_COUNTRY_TYPE_QTY <= type) {
+		return BCME_BADARG;
+	} else if ((next = list_str) == NULL) {
+		return BCME_BADARG;
+	}
+
+	while ((len = strcspn(next, " ,")) > 0) {
+		if (len >= WLC_CNTRY_BUF_SZ) {
+			DHD_ERROR(("%s: string '%s' before ',' or ' ' is too long\n",
+			           __FUNCTION__, next));
+			return BCME_ERROR;
+		}
+
+		n = syna_country_flag_find(next);
+		if (0 > n) {
+			if (BCME_NOTFOUND == n) {
+				if (MAX_COUNTRY_LIST <= (1 + gSyna_country_flag_qty)) {
+					DHD_ERROR(("%s: too many ccode(max=%d) list: '%s'\n",
+					           __FUNCTION__, MAX_COUNTRY_LIST, list_str));
+					break;
+				} else {
+					/* adopt this new item */
+					n = gSyna_country_flag_qty;
+					gSyna_country_flag_qty++;
+				}
+			} else {
+				DHD_ERROR(("%s: skip this invalid item '%s', err=%d\n",
+				           __FUNCTION__, next, n));
+			}
+		}
+
+		if (0 <= n) {
+			/* update or add a new item */
+			syna_cntry_flag[n].type = type;
+			strlcpy(syna_cntry_flag[n].ccode, next, WLC_CNTRY_BUF_SZ);
+			syna_cntry_flag[n].ccode[len] = '\0';
+			DHD_TRACE(("%s: cntry list [%d] type=%d ccode=%s\n",
+			           __FUNCTION__, n,
+			           syna_cntry_flag[n].type, syna_cntry_flag[n].ccode));
+
+			/* fill with a new blank item as terminate */
+			if ((gSyna_country_flag_qty == (n + 1)) &&
+				(MAX_COUNTRY_LIST > gSyna_country_flag_qty)) {
+				syna_cntry_flag[n+1].type = SYNA_COUNTRY_TYPE_INVALID;
+				syna_cntry_flag[n+1].ccode[0] = '\0';
+			}
+		}
+
+		next += len;
+		next += strspn(next, " ,");
+	}
+
+	return BCME_OK;
+}
+#endif /* SYNA_SAR_CUSTOMER_PARAMETER */
+
+#ifndef CUSTOMER_HW4
+/* Customized Locale table : OPTIONAL feature */
+const struct cntry_locales_custom translate_custom_table[] = {
+/* Table should be filled out based on custom platform regulatory requirement */
+#ifdef EXAMPLE_TABLE
+	{"",   "XY", 4},  /* Universal if Country code is unknown or empty */
+	{"US", "US", 69}, /* input ISO "US" to : US regrev 69 */
+	{"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */
+	{"EU", "EU", 5},  /* European union countries to : EU regrev 05 */
+	{"AT", "EU", 5},
+	{"BE", "EU", 5},
+	{"BG", "EU", 5},
+	{"CY", "EU", 5},
+	{"CZ", "EU", 5},
+	{"DK", "EU", 5},
+	{"EE", "EU", 5},
+	{"FI", "EU", 5},
+	{"FR", "EU", 5},
+	{"DE", "EU", 5},
+	{"GR", "EU", 5},
+	{"HU", "EU", 5},
+	{"IE", "EU", 5},
+	{"IT", "EU", 5},
+	{"LV", "EU", 5},
+	{"LI", "EU", 5},
+	{"LT", "EU", 5},
+	{"LU", "EU", 5},
+	{"MT", "EU", 5},
+	{"NL", "EU", 5},
+	{"PL", "EU", 5},
+	{"PT", "EU", 5},
+	{"RO", "EU", 5},
+	{"SK", "EU", 5},
+	{"SI", "EU", 5},
+	{"ES", "EU", 5},
+	{"SE", "EU", 5},
+	{"GB", "EU", 5},
+	{"KR", "XY", 3},
+	{"AU", "XY", 3},
+	{"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */
+	{"TW", "XY", 3},
+	{"AR", "XY", 3},
+	{"MX", "XY", 3},
+	{"IL", "IL", 0},
+	{"CH", "CH", 0},
+	{"TR", "TR", 0},
+	{"NO", "NO", 0},
+#endif /* EXMAPLE_TABLE */
+#if defined(BOARD_HIKEY)
+#if defined(BCM4335_CHIP)
+	{"",   "XZ", 11},  /* Universal if Country code is unknown or empty */
+#endif
+	{"AE", "AE", 1},
+	{"AR", "AR", 1},
+	{"AT", "AT", 1},
+	{"AU", "AU", 2},
+	{"BE", "BE", 1},
+	{"BG", "BG", 1},
+	{"BN", "BN", 1},
+	{"CA", "CA", 2},
+	{"CH", "CH", 1},
+	{"CY", "CY", 1},
+	{"CZ", "CZ", 1},
+	{"DE", "DE", 3},
+	{"DK", "DK", 1},
+	{"EE", "EE", 1},
+	{"ES", "ES", 1},
+	{"FI", "FI", 1},
+	{"FR", "FR", 1},
+	{"GB", "GB", 1},
+	{"GR", "GR", 1},
+	{"HR", "HR", 1},
+	{"HU", "HU", 1},
+	{"IE", "IE", 1},
+	{"IS", "IS", 1},
+	{"IT", "IT", 1},
+	{"ID", "ID", 1},
+	{"JP", "JP", 8},
+	{"KR", "KR", 24},
+	{"KW", "KW", 1},
+	{"LI", "LI", 1},
+	{"LT", "LT", 1},
+	{"LU", "LU", 1},
+	{"LV", "LV", 1},
+	{"MA", "MA", 1},
+	{"MT", "MT", 1},
+	{"MX", "MX", 1},
+	{"NL", "NL", 1},
+	{"NO", "NO", 1},
+	{"PL", "PL", 1},
+	{"PT", "PT", 1},
+	{"PY", "PY", 1},
+	{"RO", "RO", 1},
+	{"SE", "SE", 1},
+	{"SI", "SI", 1},
+	{"SK", "SK", 1},
+	{"TR", "TR", 7},
+	{"TW", "TW", 1},
+	{"IR", "XZ", 11},	/* Universal if Country code is IRAN, (ISLAMIC REPUBLIC OF) */
+	{"SD", "XZ", 11},	/* Universal if Country code is SUDAN */
+	{"SY", "XZ", 11},	/* Universal if Country code is SYRIAN ARAB REPUBLIC */
+	{"GL", "XZ", 11},	/* Universal if Country code is GREENLAND */
+	{"PS", "XZ", 11},	/* Universal if Country code is PALESTINIAN TERRITORY, OCCUPIED */
+	{"TL", "XZ", 11},	/* Universal if Country code is TIMOR-LESTE (EAST TIMOR) */
+	{"MH", "XZ", 11},	/* Universal if Country code is MARSHALL ISLANDS */
+#endif /* BOARD_HIKEY */
+};
+
+/* Customized Locale convertor
+*  input : ISO 3166-1 country abbreviation
+*  output: customized cspec
+*/
+void
+#ifdef CUSTOM_COUNTRY_CODE
+get_customized_country_code(void *adapter, char *country_iso_code,
+	wl_country_t *cspec, u32 flags)
+#else
+get_customized_country_code(void *adapter, char *country_iso_code, wl_country_t *cspec)
+#endif /* CUSTOM_COUNTRY_CODE */
+{
+#if defined(OEM_ANDROID)
+#if defined(BOARD_HIKEY) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
+
+	struct cntry_locales_custom *cloc_ptr;
+
+	if (!cspec)
+		return;
+#ifdef CUSTOM_COUNTRY_CODE
+	cloc_ptr = wifi_platform_get_country_code(adapter, country_iso_code, flags);
+#else
+	cloc_ptr = wifi_platform_get_country_code(adapter, country_iso_code);
+#endif /* CUSTOM_COUNTRY_CODE */
+
+	if (cloc_ptr) {
+		strlcpy(cspec->ccode, cloc_ptr->custom_locale, WLC_CNTRY_BUF_SZ);
+		cspec->rev = cloc_ptr->custom_locale_rev;
+	}
+	return;
+#else
+	int size, i;
+
+	size = ARRAYSIZE(translate_custom_table);
+
+	if (cspec == 0)
+		 return;
+
+	if (size == 0)
+		 return;
+
+	for (i = 0; i < size; i++) {
+		if (strcmp(country_iso_code, translate_custom_table[i].iso_abbrev) == 0) {
+			memcpy(cspec->ccode,
+				translate_custom_table[i].custom_locale, WLC_CNTRY_BUF_SZ);
+			cspec->rev = translate_custom_table[i].custom_locale_rev;
+			return;
+		}
+	}
+#ifdef EXAMPLE_TABLE
+	/* if no country code matched return first universal code from translate_custom_table */
+	memcpy(cspec->ccode, translate_custom_table[0].custom_locale, WLC_CNTRY_BUF_SZ);
+	cspec->rev = translate_custom_table[0].custom_locale_rev;
+#endif /* EXMAPLE_TABLE */
+	return;
+#endif /* (defined(CUSTOMER_HW2) || defined(BOARD_HIKEY)) &&
+	* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36))
+	*/
+#endif /* OEM_ANDROID */
+}
+#endif /* CUSTOMER_HW4 */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_custom_hikey.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_custom_hikey.c
@@ -0,0 +1,504 @@
+/*
+ * Platform Dependent file for Hikey
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/skbuff.h>
+#include <linux/fcntl.h>
+#include <linux/fs.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_WIFI_CONTROL_FUNC
+#include <linux/wlan_plat.h>
+#else
+#include <dhd_plat.h>
+#endif /* CONFIG_WIFI_CONTROL_FUNC */
+#include <dhd_dbg.h>
+#include <dhd.h>
+
+#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
+extern void dhd_exit_wlan_mem(void);
+extern int dhd_init_wlan_mem(void);
+extern void *dhd_wlan_mem_prealloc(int section, unsigned long size);
+#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
+
+#define HIKEY_PCIE_VENDOR_ID 0x19e5
+#define HIKEY_PCIE_DEVICE_ID 0x3660
+
+#ifndef WLAN_REG_ON_GPIO_DEFAULT
+#define WLAN_REG_ON_GPIO_DEFAULT	(-1)
+#endif /* WLAN_REG_ON_GPIO_DEFAULT */
+#ifndef WLAN_HOST_WAKE_GPIO_DEFAULT
+#define WLAN_HOST_WAKE_GPIO_DEFAULT	(-1)
+#endif /* WLAN_HOST_WAKE_GPIO_DEFAULT */
+
+#define DHD_GPIO_INVALID               (-1)
+
+static int wlan_reg_on = DHD_GPIO_INVALID;
+#ifdef BCMPCIE
+#ifndef DHD_DT_COMPAT_ENTRY
+#define DHD_DT_COMPAT_ENTRY		"android,bcmdhd_pcie"
+#endif /* DHD_DT_COMPAT_ENTRY */
+#define DHD_GPIO_REGON_NAME		"WLPCIE_REG_ON"
+#define DHD_GPIO_HOSTW_NAME		"WLPCIE_HOST_WAKE"
+#elif defined(BCMSDIO)
+#ifndef DHD_DT_COMPAT_ENTRY
+#define DHD_DT_COMPAT_ENTRY		"android,bcmdhd_sdio"
+#endif /* DHD_DT_COMPAT_ENTRY */
+#define DHD_GPIO_REGON_NAME		"WLSDIO_REG_ON"
+#define DHD_GPIO_HOSTW_NAME		"WLSDIO_HOST_WAKE"
+#else /* non-supported */
+#error Unsupport BUS type!
+#endif /* BCMPCIE */
+#define WIFI_WL_REG_ON_PROPNAME		"wl_reg_on"
+
+#ifdef DHD_USE_HOST_WAKE
+static int wlan_host_wake_up = DHD_GPIO_INVALID;
+static int wlan_host_wake_irq = 0;
+#define WIFI_WLAN_HOST_WAKE_PROPNAME    "wl_host_wake"
+#endif /* DHD_USE_HOST_WAKE */
+
+/********************************************************************** */
+/*  Customer specific declaration part (can without Marco protection)  */
+/********************************************************************** */
+#ifdef BCMPCIE
+/* for HIKEY platform PCIE renumerate */
+extern void kirin_pcie_power_on_atu_fixup(void) __attribute__ ((weak));
+extern int kirin_pcie_lp_ctrl(u32 enable) __attribute__ ((weak));
+#else /* BCMSDIO */
+/* For HIKEY SDIO card detect */
+extern int wifi_card_detect(void) __attribute__ ((weak));
+#endif /* BCMSDIO */
+
+void
+dhd_wifi_deinit_gpio(void)
+{
+#ifdef BCMPCIE
+	/* Disable ASPM before powering off */
+	if (kirin_pcie_lp_ctrl) {
+		kirin_pcie_lp_ctrl(0);
+	} else {
+		DHD_ERROR(("[%s] kirin_pcie_lp_ctrl is NULL. "
+			"ASPM may not work\n", __func__));
+	}
+#endif /* BCMPCIE */
+	if (gpio_direction_output(wlan_reg_on, 0)) {
+		DHD_ERROR(("%s: WL_REG_ON is failed to pull up\n", __FUNCTION__));
+	}
+	if (gpio_get_value(wlan_reg_on)) {
+		DHD_INFO(("WL_REG_ON on-step-2 : [%d]\n",
+			gpio_get_value(wlan_reg_on)));
+	}
+#ifdef DHD_USE_HOST_WAKE
+	if (wlan_host_wake_up >= 0) {
+		gpio_free(wlan_host_wake_up);
+	}
+#endif /* DHD_USE_HOST_WAKE */
+
+	if (wlan_reg_on >= 0) {
+		gpio_free(wlan_reg_on);
+	}
+}
+
+int
+dhd_wifi_init_gpio(void)
+{
+	int gpio_reg_on_val, ret;
+	/* ========== WLAN_PWR_EN ============ */
+	char *wlan_node = DHD_DT_COMPAT_ENTRY;
+	struct device_node *root_node = NULL;
+	struct regulator *vdda;
+	struct platform_device *pdev;
+
+	root_node = of_find_compatible_node(NULL, NULL, wlan_node);
+	if (root_node) {
+		wlan_reg_on = of_get_named_gpio(root_node, WIFI_WL_REG_ON_PROPNAME, 0);
+		struct platform_device *pdev = of_find_device_by_node(root_node);
+		vdda = devm_regulator_get(&pdev->dev, "vdda");
+		ret = regulator_enable(vdda);
+		if (ret)
+			dev_err(&pdev->dev, "cannot enable vdda regulator\n");
+#ifdef DHD_USE_HOST_WAKE
+		wlan_host_wake_up = of_get_named_gpio(root_node, WIFI_WLAN_HOST_WAKE_PROPNAME, 0);
+#endif /* DHD_USE_HOST_WAKE */
+	} else {
+		DHD_ERROR(("failed to get device node of BRCM WLAN, use default GPIOs\n"));
+		wlan_reg_on = WLAN_REG_ON_GPIO_DEFAULT;
+#ifdef DHD_USE_HOST_WAKE
+		wlan_host_wake_up = WLAN_HOST_WAKE_GPIO_DEFAULT;
+#endif /* DHD_USE_HOST_WAKE */
+	}
+
+	if (wlan_reg_on == DHD_GPIO_INVALID) {
+		DHD_ERROR(("%s: gpio_wlan_power('%s'): %d is not connected - skip\n",
+			__FUNCTION__, WIFI_WL_REG_ON_PROPNAME, wlan_reg_on));
+	} else {
+		/* ========== WLAN_PWR_EN ============ */
+		DHD_INFO(("%s: gpio_wlan_power('%s'): %d\n",
+			__FUNCTION__, WIFI_WL_REG_ON_PROPNAME, wlan_reg_on));
+
+		/*
+		 * For reg_on, gpio_request will fail if the gpio is configured to output-high
+		 * in the dts using gpio-hog, so do not return error for failure.
+		 */
+		if (gpio_request_one(wlan_reg_on, GPIOF_OUT_INIT_HIGH, DHD_GPIO_REGON_NAME)) {
+			DHD_ERROR(("%s: Failed to request gpio %d for WL_REG_ON, "
+			"might have configured in the dts\n",
+			__FUNCTION__, wlan_reg_on));
+		} else {
+			DHD_ERROR(("%s: gpio_request WL_REG_ON done - WLAN_EN: GPIO %d\n",
+				__FUNCTION__, wlan_reg_on));
+		}
+
+		gpio_reg_on_val = gpio_get_value_cansleep(wlan_reg_on);
+		DHD_ERROR(("%s: Initial WL_REG_ON: [%d]\n",
+			__FUNCTION__, gpio_reg_on_val));
+
+		if (gpio_reg_on_val == 0) {
+			DHD_INFO(("%s: WL_REG_ON is LOW, drive it HIGH\n", __FUNCTION__));
+			if (gpio_direction_output(wlan_reg_on, 1)) {
+				DHD_ERROR(("%s: WL_REG_ON is failed to pull up\n", __FUNCTION__));
+				return -EIO;
+			}
+			/* Wait for WIFI_TURNON_DELAY due to power stability */
+			msleep(WIFI_TURNON_DELAY);
+
+#ifdef BCMPCIE
+			/*
+			 * Call Kiric RC ATU fixup else si_attach will fail due to
+			 * improper BAR0/1 address translations
+			 */
+			if (kirin_pcie_power_on_atu_fixup) {
+				kirin_pcie_power_on_atu_fixup();
+			} else {
+				DHD_ERROR(("[%s] kirin_pcie_power_on_atu_fixup is NULL. "
+					"REG_ON may not work\n", __func__));
+			}
+			/* Enable ASPM after powering ON */
+			if (kirin_pcie_lp_ctrl) {
+				kirin_pcie_lp_ctrl(1);
+			} else {
+				DHD_ERROR(("[%s] kirin_pcie_lp_ctrl is NULL. "
+					"ASPM may not work\n", __func__));
+			}
+#endif /* BCMPCIE */
+		}
+	}
+
+#ifdef DHD_USE_HOST_WAKE
+	if (wlan_host_wake_up == DHD_GPIO_INVALID) {
+		DHD_ERROR(("%s: gpio_wlan_host_wake('%s'): %d, skip\n",
+		           __FUNCTION__, WIFI_WLAN_HOST_WAKE_PROPNAME, wlan_host_wake_up));
+		wlan_host_wake_irq = 0;
+	} else {
+		/* ========== WLAN_HOST_WAKE ============ */
+		DHD_ERROR(("%s: gpio_wlan_host_wake('%s'): %d\n",
+		           __FUNCTION__, WIFI_WLAN_HOST_WAKE_PROPNAME, wlan_host_wake_up));
+
+		if (gpio_request_one(wlan_host_wake_up, GPIOF_IN, DHD_GPIO_HOSTW_NAME)) {
+			DHD_ERROR(("%s: Failed to request gpio %d for WLAN_HOST_WAKE "
+				"might have configured in the dts\n",
+				__FUNCTION__, wlan_host_wake_up));
+			return -ENODEV;
+		} else {
+			DHD_ERROR(("%s: gpio_request WLAN_HOST_WAKE done"
+				" - WLAN_HOST_WAKE: GPIO %d\n",
+				__FUNCTION__, wlan_host_wake_up));
+		}
+
+		if (gpio_direction_input(wlan_host_wake_up)) {
+			DHD_ERROR(("%s: Failed to set WL_HOST_WAKE gpio direction\n", __func__));
+			return -EIO;
+		}
+
+		wlan_host_wake_irq = gpio_to_irq(wlan_host_wake_up);
+	}
+#endif /* DHD_USE_HOST_WAKE */
+	return 0;
+}
+
+int
+dhd_wlan_power(int onoff)
+{
+	DHD_INFO(("------------------------------------------------"));
+	DHD_INFO(("------------------------------------------------\n"));
+	DHD_ERROR(("%s Enter: power %s(gpio %d)\n", __func__, onoff ? "on" : "off", wlan_reg_on));
+
+#ifdef SKIP_REGON_GPIO
+	DHD_ERROR(("%s-%d: ***** skip action for REG_ON *****\n", __FUNCTION__, __LINE__));
+	return 0;
+#endif /* SKIP_REGON_GPIO */
+
+	if (wlan_reg_on == DHD_GPIO_INVALID) {
+		DHD_ERROR(("%s-%d: ***** REG_ON hard wired, skip *****\n", __FUNCTION__, __LINE__));
+		return BCME_OK;
+	}
+
+	if (onoff) {
+		if (gpio_direction_output(wlan_reg_on, 1)) {
+			DHD_ERROR(("%s: WL_REG_ON is failed to pull up\n", __FUNCTION__));
+			return -EIO;
+		}
+		if (gpio_get_value_cansleep(wlan_reg_on)) {
+			DHD_INFO(("WL_REG_ON on-step-2 : [%d]\n",
+				gpio_get_value_cansleep(wlan_reg_on)));
+		} else {
+			DHD_ERROR(("[%s] gpio value is 0. We need reinit.\n", __func__));
+			if (gpio_direction_output(wlan_reg_on, 1)) {
+				DHD_ERROR(("%s: WL_REG_ON is "
+					"failed to pull up\n", __func__));
+			}
+		}
+
+		/* Wait for WIFI_TURNON_DELAY due to power stability */
+		msleep(WIFI_TURNON_DELAY);
+		DHD_ERROR(("%s-%d: ON DELAY=%d\n", __FUNCTION__, __LINE__, WIFI_TURNON_DELAY));
+
+		/********************************************************************** */
+		/* START: customer can add some platform related initialization: START */
+		/********************************************************************** */
+#if defined(BCMPCIE)
+		/*
+		 * Call Kiric RC ATU fixup else si_attach will fail due to
+		 * improper BAR0/1 address translations
+		 */
+		if (kirin_pcie_power_on_atu_fixup) {
+			kirin_pcie_power_on_atu_fixup();
+		} else {
+			DHD_ERROR(("[%s] kirin_pcie_power_on_atu_fixup is NULL. "
+				"REG_ON may not work\n", __func__));
+		}
+		/* Enable ASPM after powering ON */
+		if (kirin_pcie_lp_ctrl) {
+			kirin_pcie_lp_ctrl(onoff);
+		} else {
+			DHD_ERROR(("[%s] kirin_pcie_lp_ctrl is NULL. "
+				"ASPM may not work\n", __func__));
+		}
+#endif /* defined(BCMPCIE) */
+
+		/********************************************************************** */
+		/*   END: customer can add some platform related initialization: END   */
+		/********************************************************************** */
+	} else {
+		/********************************************************************** */
+		/* START: customer can add some platform related initialization: START */
+		/********************************************************************** */
+#if defined(BCMPCIE)
+		/* Disable ASPM before powering off */
+		if (kirin_pcie_lp_ctrl) {
+			kirin_pcie_lp_ctrl(onoff);
+		} else {
+			DHD_ERROR(("[%s] kirin_pcie_lp_ctrl is NULL. "
+				"ASPM may not work\n", __func__));
+		}
+#endif /* defined(BCMPCIE) */
+		/********************************************************************** */
+		/*  END: customer can add some platform related deinitialization: END  */
+		/********************************************************************** */
+
+		if (gpio_direction_output(wlan_reg_on, 0)) {
+			DHD_ERROR(("%s: WL_REG_ON is failed to pull up\n", __FUNCTION__));
+			return -EIO;
+		}
+		if (gpio_get_value_cansleep(wlan_reg_on)) {
+			DHD_INFO(("WL_REG_ON on-step-2 : [%d]\n",
+				gpio_get_value_cansleep(wlan_reg_on)));
+		}
+	}
+	return 0;
+}
+
+static int
+dhd_wlan_reset(int onoff)
+{
+	return 0;
+}
+
+static int
+dhd_wlan_set_carddetect(int val)
+{
+	int ret = 0;
+
+	/********************************************************************** */
+	/* START: customer can add some platform related initialization: START */
+	/********************************************************************** */
+#if defined(BCMDHD_MODULAR)
+#ifdef BCMPCIE
+	/* PCIE patch here */
+#else /* BCMSDIO */
+#ifndef GKI_NO_KERNEL_BUS_PATCH
+	ret = wifi_card_detect();
+	if (0 > ret) {
+		DHD_ERROR(("%s-%d: * error hapen, ret=%d (ignore when remove)\n",
+		           __FUNCTION__, __LINE__, ret));
+	}
+#endif /* GKI_NO_KERNEL_BUS_PATCH */
+#endif /* BCMSDIO */
+#endif /* BCMDHD_MODULAR */
+	/********************************************************************** */
+	/*   END: customer can add some platform related initialization: END   */
+	/********************************************************************** */
+	return ret;
+}
+
+#ifdef DHD_USE_HOST_WAKE
+static int
+dhd_wlan_get_wake_irq(void)
+{
+	return gpio_to_irq(wlan_host_wake_up);
+}
+
+static int
+dhd_get_wlan_oob_gpio_level(void)
+{
+	return gpio_is_valid(wlan_host_wake_up) ?
+		gpio_get_value_cansleep(wlan_host_wake_up) : -1;
+}
+
+int
+dhd_get_wlan_oob_gpio(void)
+{
+	return dhd_get_wlan_oob_gpio_level();
+}
+#endif /* DHD_USE_HOST_WAKE */
+
+struct resource dhd_wlan_resources = {
+	.name	= "bcmdhd_wlan_irq",
+	.start	= 0, /* Dummy */
+	.end	= 0, /* Dummy */
+	.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_SHAREABLE |
+#ifdef BCMPCIE
+	IORESOURCE_IRQ_HIGHEDGE,
+#else /* non-BCMPCIE */
+	IORESOURCE_IRQ_HIGHLEVEL,
+#endif /* BCMPCIE */
+};
+
+struct wifi_platform_data dhd_wlan_control = {
+	.set_power	= dhd_wlan_power,
+	.set_reset	= dhd_wlan_reset,
+	.set_carddetect	= dhd_wlan_set_carddetect,
+#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
+	.mem_prealloc	= dhd_wlan_mem_prealloc,
+#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
+#ifdef DHD_USE_HOST_WAKE
+	.get_wake_irq   = dhd_wlan_get_wake_irq,
+	.get_oob_gpio_level   = dhd_get_wlan_oob_gpio_level,
+#endif /* DHD_USE_HOST_WAKE */
+};
+
+int
+dhd_wlan_init(void)
+{
+	int ret;
+
+	DHD_INFO(("%s: START.......\n", __FUNCTION__));
+#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
+	ret = dhd_init_wlan_mem();
+	if (ret < 0) {
+		DHD_ERROR(("%s: failed to alloc reserved memory,"
+				" ret=%d\n", __FUNCTION__, ret));
+		goto fail;
+	} else {
+		DHD_ERROR(("%s: Allocate reserved memory sucessfully,"
+		           " ret=%d\n", __FUNCTION__, ret));
+	}
+#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
+
+	ret = dhd_wifi_init_gpio();
+	if (ret < 0) {
+		DHD_ERROR(("%s: failed to initiate GPIO, ret=%d\n",
+			__FUNCTION__, ret));
+		goto fail;
+	}
+
+#ifdef DHD_USE_HOST_WAKE
+	dhd_wlan_resources.start = wlan_host_wake_irq;
+	dhd_wlan_resources.end = wlan_host_wake_irq;
+#endif /* DHD_USE_HOST_WAKE */
+
+fail:
+	DHD_INFO(("%s: FINISH.......\n", __FUNCTION__));
+	/* add to free gpio resource */
+	if (0 > ret) {
+		dhd_wifi_deinit_gpio();
+	}
+	return ret;
+}
+
+void
+dhd_wlan_deinit(void)
+{
+	dhd_wifi_deinit_gpio();
+
+#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
+	dhd_exit_wlan_mem();
+#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
+}
+
+uint32 dhd_plat_get_rc_vendor_id(void)
+{
+	return HIKEY_PCIE_VENDOR_ID;
+}
+
+uint32 dhd_plat_get_rc_device_id(void)
+{
+	return HIKEY_PCIE_DEVICE_ID;
+}
+
+#ifndef BCMDHD_MODULAR
+#if defined(CONFIG_DEFERRED_INITCALLS)
+deferred_module_init(dhd_wlan_init);
+#elif defined(late_initcall)
+late_initcall(dhd_wlan_init);
+#else /* default */
+module_init(dhd_wlan_init);
+#endif /* CONFIG_DEFERRED_INITCALLS */
+module_exit(dhd_wlan_deinit);
+#endif /* !BCMDHD_MODULAR */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_custom_memprealloc.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_custom_memprealloc.c
@@ -0,0 +1,503 @@
+/*
+ * Platform Dependent file for usage of Preallocted Memory
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/miscdevice.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/workqueue.h>
+#include <linux/unistd.h>
+#include <linux/bug.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#ifndef CONFIG_ARCH_EXYNOS
+#include <osl.h>
+#endif /* CONFIG_ARCH_EXYNOS */
+
+#ifdef CONFIG_BROADCOM_WIFI_RESERVED_MEM
+/* Please refer to 'enum dhd_prealloc_index' in dhd.h */
+#define WLAN_STATIC_SCAN_BUF0		5
+#define WLAN_STATIC_SCAN_BUF1		6
+#define WLAN_STATIC_DHD_INFO_BUF	7
+#define WLAN_STATIC_DHD_WLFC_BUF	8
+#define WLAN_STATIC_DHD_IF_FLOW_LKUP	9
+#define WLAN_STATIC_DHD_MEMDUMP_RAM	11
+#define WLAN_STATIC_DHD_WLFC_HANGER	12
+#define WLAN_STATIC_DHD_PKTID_MAP	13	/* Deprecated */
+#define WLAN_STATIC_DHD_PKTID_IOCTL_MAP	14	/* Deprecated */
+#define WLAN_STATIC_DHD_LOG_DUMP_BUF	15
+#define WLAN_STATIC_DHD_LOG_DUMP_BUF_EX	16
+#define WLAN_STATIC_DHD_PKTLOG_DUMP_BUF	17	/* Deprecated */
+
+#define WLAN_SCAN_BUF_SIZE		(64 * 1024)
+
+#define WLAN_DHD_INFO_BUF_SIZE		(64 * 1024)
+#define WLAN_DHD_WLFC_BUF_SIZE		(64 * 1024)
+#define WLAN_DHD_IF_FLOW_LKUP_SIZE	(64 * 1024)
+/* Have 2MB ramsize to accomodate future chips */
+#define WLAN_DHD_MEMDUMP_SIZE		(3 * 1024 * 1024)
+
+#define PREALLOC_WLAN_SEC_NUM		4
+#define PREALLOC_WLAN_BUF_NUM		160
+#define PREALLOC_WLAN_SECTION_HEADER	24
+
+#ifdef CONFIG_BCMDHD_PCIE
+#define DHD_SKB_1PAGE_BUFSIZE	(PAGE_SIZE*1)
+#define DHD_SKB_2PAGE_BUFSIZE	(PAGE_SIZE*2)
+#define DHD_SKB_4PAGE_BUFSIZE	(PAGE_SIZE*4)
+
+#define WLAN_SECTION_SIZE_0	(PREALLOC_WLAN_BUF_NUM * 128)
+#define WLAN_SECTION_SIZE_1	0
+#define WLAN_SECTION_SIZE_2	0
+#define WLAN_SECTION_SIZE_3	(PREALLOC_WLAN_BUF_NUM * 1024)
+
+#define DHD_SKB_1PAGE_BUF_NUM	0
+#define DHD_SKB_2PAGE_BUF_NUM	192
+#define DHD_SKB_4PAGE_BUF_NUM	0
+
+#else
+#define DHD_SKB_HDRSIZE		336
+#define DHD_SKB_1PAGE_BUFSIZE	((PAGE_SIZE*1)-DHD_SKB_HDRSIZE)
+#define DHD_SKB_2PAGE_BUFSIZE	((PAGE_SIZE*2)-DHD_SKB_HDRSIZE)
+#define DHD_SKB_4PAGE_BUFSIZE	((PAGE_SIZE*4)-DHD_SKB_HDRSIZE)
+
+#define WLAN_SECTION_SIZE_0	(PREALLOC_WLAN_BUF_NUM * 128)
+#define WLAN_SECTION_SIZE_1	(PREALLOC_WLAN_BUF_NUM * 128)
+#define WLAN_SECTION_SIZE_2	(PREALLOC_WLAN_BUF_NUM * 512)
+#define WLAN_SECTION_SIZE_3	(PREALLOC_WLAN_BUF_NUM * 1024)
+
+#define DHD_SKB_1PAGE_BUF_NUM	8
+#define DHD_SKB_2PAGE_BUF_NUM	8
+#define DHD_SKB_4PAGE_BUF_NUM	1
+#endif /* CONFIG_BCMDHD_PCIE */
+
+#define WLAN_SKB_1_2PAGE_BUF_NUM	((DHD_SKB_1PAGE_BUF_NUM) + \
+		(DHD_SKB_2PAGE_BUF_NUM))
+#define WLAN_SKB_BUF_NUM	((WLAN_SKB_1_2PAGE_BUF_NUM) + \
+		(DHD_SKB_4PAGE_BUF_NUM))
+
+#define WLAN_MAX_PKTID_ITEMS		(8192)
+#define WLAN_DHD_PKTID_MAP_HDR_SIZE	(20 + 4*(WLAN_MAX_PKTID_ITEMS + 1))
+#define WLAN_DHD_PKTID_MAP_ITEM_SIZE	(32)
+#define WLAN_DHD_PKTID_MAP_SIZE		((WLAN_DHD_PKTID_MAP_HDR_SIZE) + \
+		((WLAN_MAX_PKTID_ITEMS+1) * WLAN_DHD_PKTID_MAP_ITEM_SIZE))
+
+#define WLAN_MAX_PKTID_IOCTL_ITEMS	(32)
+#define WLAN_DHD_PKTID_IOCTL_MAP_HDR_SIZE	(20 + 4*(WLAN_MAX_PKTID_IOCTL_ITEMS + 1))
+#define WLAN_DHD_PKTID_IOCTL_MAP_ITEM_SIZE	(32)
+#define WLAN_DHD_PKTID_IOCTL_MAP_SIZE		((WLAN_DHD_PKTID_IOCTL_MAP_HDR_SIZE) + \
+		((WLAN_MAX_PKTID_IOCTL_ITEMS+1) * WLAN_DHD_PKTID_IOCTL_MAP_ITEM_SIZE))
+
+#define DHD_LOG_DUMP_BUF_SIZE	(1024 * 1024 * 4)
+#define DHD_LOG_DUMP_BUF_EX_SIZE	(1024 * 8)
+
+#define DHD_PKTLOG_DUMP_BUF_SIZE	(64 * 1024)
+
+#define WLAN_DHD_WLFC_HANGER_MAXITEMS		3072
+#define WLAN_DHD_WLFC_HANGER_ITEM_SIZE		32
+#define WLAN_DHD_WLFC_HANGER_SIZE	((WLAN_DHD_WLFC_HANGER_ITEM_SIZE) + \
+	((WLAN_DHD_WLFC_HANGER_MAXITEMS) * (WLAN_DHD_WLFC_HANGER_ITEM_SIZE)))
+
+static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];
+
+struct wlan_mem_prealloc {
+	void *mem_ptr;
+	unsigned long size;
+};
+
+static struct wlan_mem_prealloc wlan_mem_array[PREALLOC_WLAN_SEC_NUM] = {
+	{NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER)},
+	{NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER)},
+	{NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER)},
+	{NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER)}
+};
+
+static void *wlan_static_scan_buf0 = NULL;
+static void *wlan_static_scan_buf1 = NULL;
+static void *wlan_static_dhd_info_buf = NULL;
+#ifdef CONFIG_BCMDHD_PCIE
+static void *wlan_static_if_flow_lkup = NULL;
+#else
+static void *wlan_static_dhd_wlfc_buf = NULL;
+static void *wlan_static_dhd_wlfc_hanger = NULL;
+#endif /* CONFIG_BCMDHD_PCIE */
+#ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP
+static void *wlan_static_dhd_memdump_ram = NULL;
+#endif /* #ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP */
+static void *wlan_static_dhd_log_dump_buf = NULL;
+static void *wlan_static_dhd_log_dump_buf_ex = NULL;
+
+void dhd_exit_wlan_mem(void);
+
+void
+*dhd_wlan_mem_prealloc(int section, unsigned long size)
+{
+	if (section == PREALLOC_WLAN_SEC_NUM) {
+		return wlan_static_skb;
+	}
+
+	if (section == WLAN_STATIC_SCAN_BUF0) {
+		return wlan_static_scan_buf0;
+	}
+
+	if (section == WLAN_STATIC_SCAN_BUF1) {
+		return wlan_static_scan_buf1;
+	}
+
+	if (section == WLAN_STATIC_DHD_INFO_BUF) {
+		if (size > WLAN_DHD_INFO_BUF_SIZE) {
+			pr_err("request DHD_INFO size(%lu) is bigger than"
+				" static size(%d).\n", size,
+				WLAN_DHD_INFO_BUF_SIZE);
+			return NULL;
+		}
+		return wlan_static_dhd_info_buf;
+	}
+#ifdef CONFIG_BCMDHD_PCIE
+	if (section == WLAN_STATIC_DHD_IF_FLOW_LKUP)  {
+		if (size > WLAN_DHD_IF_FLOW_LKUP_SIZE) {
+			pr_err("request DHD_WLFC size(%lu) is bigger than"
+				" static size(%d).\n",
+				size, WLAN_DHD_WLFC_BUF_SIZE);
+			return NULL;
+		}
+		return wlan_static_if_flow_lkup;
+	}
+#else
+	if (section == WLAN_STATIC_DHD_WLFC_BUF)  {
+		if (size > WLAN_DHD_WLFC_BUF_SIZE) {
+			pr_err("request DHD_WLFC size(%lu) is bigger than"
+				" static size(%d).\n",
+				size, WLAN_DHD_WLFC_BUF_SIZE);
+			return NULL;
+		}
+		return wlan_static_dhd_wlfc_buf;
+	}
+
+	if (section == WLAN_STATIC_DHD_WLFC_HANGER) {
+		if (size > WLAN_DHD_WLFC_HANGER_SIZE) {
+			pr_err("request DHD_WLFC_HANGER size(%lu) is bigger than"
+				" static size(%d).\n",
+				size, WLAN_DHD_WLFC_HANGER_SIZE);
+			return NULL;
+		}
+		return wlan_static_dhd_wlfc_hanger;
+	}
+#endif /* CONFIG_BCMDHD_PCIE */
+#ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP
+	if (section == WLAN_STATIC_DHD_MEMDUMP_RAM) {
+		if (size > WLAN_DHD_MEMDUMP_SIZE) {
+			pr_err("request DHD_MEMDUMP_RAM size(%lu) is bigger"
+				" than static size(%d).\n",
+				size, WLAN_DHD_MEMDUMP_SIZE);
+			return NULL;
+		}
+		return wlan_static_dhd_memdump_ram;
+	}
+#endif /* CONFIG_BCMDHD_PREALLOC_MEMDUMP */
+	if (section == WLAN_STATIC_DHD_LOG_DUMP_BUF) {
+		if (size > DHD_LOG_DUMP_BUF_SIZE) {
+			pr_err("request DHD_LOG_DUMP_BUF size(%lu) is bigger then"
+				" static size(%d).\n",
+				size, DHD_LOG_DUMP_BUF_SIZE);
+			return NULL;
+		}
+		return wlan_static_dhd_log_dump_buf;
+	}
+
+	if (section == WLAN_STATIC_DHD_LOG_DUMP_BUF_EX) {
+		if (size > DHD_LOG_DUMP_BUF_EX_SIZE) {
+			pr_err("request DHD_LOG_DUMP_BUF_EX size(%lu) is bigger then"
+				" static size(%d).\n",
+				size, DHD_LOG_DUMP_BUF_EX_SIZE);
+			return NULL;
+		}
+		return wlan_static_dhd_log_dump_buf_ex;
+	}
+
+	if ((section < 0) || (section >= PREALLOC_WLAN_SEC_NUM)) {
+		return NULL;
+	}
+
+	if (wlan_mem_array[section].size < size) {
+		return NULL;
+	}
+
+	return wlan_mem_array[section].mem_ptr;
+}
+EXPORT_SYMBOL(dhd_wlan_mem_prealloc);
+
+#ifdef DHD_DUMP_BUF_KVMALLOC
+#ifdef CONFIG_ARCH_EXYNOS
+#define DUMP_BUF_MALLOC(size)   kvmalloc(size, GFP_KERNEL)
+#define DUMP_BUF_MFREE(addr)    kvfree(addr)
+#else
+#define DUMP_BUF_MALLOC(size)   KVMALLOC(NULL, size)
+#define DUMP_BUF_MFREE(addr)    KVFREE(NULL, addr)
+#endif /* CONFIG_ARCH_EXYNOS */
+#else
+#define DUMP_BUF_MALLOC(size)   kmalloc(size, GFP_KERNEL)
+#define DUMP_BUF_MFREE(addr)    kfree(addr)
+#endif /* DHD_DUMP_BUF_KVMALLOC */
+int
+dhd_init_wlan_mem(void)
+{
+	int i;
+	int j;
+
+#if !defined(CONFIG_BCMDHD_PCIE)
+	for (i = 0; i < DHD_SKB_1PAGE_BUF_NUM; i++) {
+		wlan_static_skb[i] = __dev_alloc_skb(DHD_SKB_1PAGE_BUFSIZE, GFP_KERNEL);
+		if (!wlan_static_skb[i]) {
+			pr_err("Failed to alloc 1PAGE SKB BUF\n");
+			goto err_skb_alloc;
+		}
+	}
+#endif /* !CONFIG_BCMDHD_PCIE */
+
+	for (i = DHD_SKB_1PAGE_BUF_NUM; i < WLAN_SKB_1_2PAGE_BUF_NUM; i++) {
+		wlan_static_skb[i] = __dev_alloc_skb(DHD_SKB_2PAGE_BUFSIZE, GFP_KERNEL);
+		if (!wlan_static_skb[i]) {
+			pr_err("Failed to alloc 2PAGE SKB BUF\n");
+			goto err_skb_alloc;
+		}
+	}
+
+#if !defined(CONFIG_BCMDHD_PCIE)
+	wlan_static_skb[i] = __dev_alloc_skb(DHD_SKB_4PAGE_BUFSIZE, GFP_KERNEL);
+	if (!wlan_static_skb[i]) {
+		pr_err("Failed to alloc 4PAGE SKB BUF\n");
+		goto err_skb_alloc;
+	}
+#endif /* !CONFIG_BCMDHD_PCIE */
+
+	for (i = 0; i < PREALLOC_WLAN_SEC_NUM; i++) {
+		if (wlan_mem_array[i].size > 0) {
+#ifdef CONFIG_BCMDHD_PCIE
+			wlan_mem_array[i].mem_ptr =
+				kvmalloc(wlan_mem_array[i].size, GFP_KERNEL);
+#else
+			wlan_mem_array[i].mem_ptr =
+				kmalloc(wlan_mem_array[i].size, GFP_KERNEL);
+#endif /* CONFIG_BCMDHD_PCIE */
+
+			if (!wlan_mem_array[i].mem_ptr) {
+				pr_err("Failed to mem_alloc for WLAN\n");
+				goto err_mem_alloc;
+			}
+		}
+	}
+
+#ifdef CONFIG_BCMDHD_PCIE
+	wlan_static_scan_buf0 = kvmalloc(WLAN_SCAN_BUF_SIZE, GFP_KERNEL);
+#else
+	wlan_static_scan_buf0 = kmalloc(WLAN_SCAN_BUF_SIZE, GFP_KERNEL);
+#endif /* CONFIG_BCMDHD_PCIE */
+	if (!wlan_static_scan_buf0) {
+		pr_err("Failed to alloc wlan_static_scan_buf0\n");
+		goto err_mem_alloc;
+	}
+
+#ifdef CONFIG_BCMDHD_PCIE
+	wlan_static_scan_buf1 = kvmalloc(WLAN_SCAN_BUF_SIZE, GFP_KERNEL);
+#else
+	wlan_static_scan_buf1 = kmalloc(WLAN_SCAN_BUF_SIZE, GFP_KERNEL);
+#endif /* CONFIG_BCMDHD_PCIE */
+	if (!wlan_static_scan_buf1) {
+		pr_err("Failed to alloc wlan_static_scan_buf1\n");
+		goto err_mem_alloc;
+	}
+
+	wlan_static_dhd_log_dump_buf = DUMP_BUF_MALLOC(DHD_LOG_DUMP_BUF_SIZE);
+	if (!wlan_static_dhd_log_dump_buf) {
+		pr_err("Failed to alloc wlan_static_dhd_log_dump_buf\n");
+		goto err_mem_alloc;
+	}
+
+	wlan_static_dhd_log_dump_buf_ex = DUMP_BUF_MALLOC(DHD_LOG_DUMP_BUF_EX_SIZE);
+	if (!wlan_static_dhd_log_dump_buf_ex) {
+		pr_err("Failed to alloc wlan_static_dhd_log_dump_buf_ex\n");
+		goto err_mem_alloc;
+	}
+
+#ifdef CONFIG_BCMDHD_PCIE
+	wlan_static_dhd_info_buf = kvmalloc(WLAN_DHD_INFO_BUF_SIZE, GFP_KERNEL);
+#else
+	wlan_static_dhd_info_buf = kmalloc(WLAN_DHD_INFO_BUF_SIZE, GFP_KERNEL);
+#endif /* CONFIG_BCMDHD_PCIE */
+	if (!wlan_static_dhd_info_buf) {
+		pr_err("Failed to alloc wlan_static_dhd_info_buf\n");
+		goto err_mem_alloc;
+	}
+
+#ifdef CONFIG_BCMDHD_PCIE
+	wlan_static_if_flow_lkup = kvmalloc(WLAN_DHD_IF_FLOW_LKUP_SIZE,
+		GFP_KERNEL);
+	if (!wlan_static_if_flow_lkup) {
+		pr_err("Failed to alloc wlan_static_if_flow_lkup\n");
+		goto err_mem_alloc;
+	}
+#else
+	wlan_static_dhd_wlfc_buf = kmalloc(WLAN_DHD_WLFC_BUF_SIZE,
+		GFP_KERNEL);
+	if (!wlan_static_dhd_wlfc_buf) {
+		pr_err("Failed to alloc wlan_static_dhd_wlfc_buf\n");
+		goto err_mem_alloc;
+	}
+
+	wlan_static_dhd_wlfc_hanger = kmalloc(WLAN_DHD_WLFC_HANGER_SIZE,
+		GFP_KERNEL);
+	if (!wlan_static_dhd_wlfc_hanger) {
+		pr_err("Failed to alloc wlan_static_dhd_wlfc_hanger\n");
+		goto err_mem_alloc;
+	}
+#endif /* CONFIG_BCMDHD_PCIE */
+
+#ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP
+	wlan_static_dhd_memdump_ram = DUMP_BUF_MALLOC(WLAN_DHD_MEMDUMP_SIZE);
+	if (!wlan_static_dhd_memdump_ram) {
+		pr_err("Failed to alloc wlan_static_dhd_memdump_ram\n");
+		goto err_mem_alloc;
+	}
+#endif /* CONFIG_BCMDHD_PREALLOC_MEMDUMP */
+
+	pr_err("%s: WIFI MEM Allocated\n", __FUNCTION__);
+	return 0;
+
+err_mem_alloc:
+	dhd_exit_wlan_mem();
+	return -ENOMEM;
+
+err_skb_alloc:
+	/*
+	 * When all the skb alloc buf couldn't alloced, free these buf with alloced size
+	 * dhd_exit_wlan_mem will free with total size (don't know alloced size)
+	 */
+	pr_err("Failed to skb_alloc for WLAN\n");
+	for (j = 0; j < i; j++) {
+		dev_kfree_skb(wlan_static_skb[j]);
+	}
+	return -ENOMEM;
+}
+
+EXPORT_SYMBOL(dhd_init_wlan_mem);
+
+void
+dhd_exit_wlan_mem(void)
+{
+	int i = 0;
+
+#ifdef CONFIG_BCMDHD_PREALLOC_MEMDUMP
+	if (wlan_static_dhd_memdump_ram) {
+		DUMP_BUF_MFREE(wlan_static_dhd_memdump_ram);
+	}
+#endif /* CONFIG_BCMDHD_PREALLOC_MEMDUMP */
+
+#ifdef CONFIG_BCMDHD_PCIE
+	if (wlan_static_if_flow_lkup) {
+		kvfree(wlan_static_if_flow_lkup);
+	}
+#else
+	if (wlan_static_dhd_wlfc_buf) {
+		kfree(wlan_static_dhd_wlfc_buf);
+	}
+
+	if (wlan_static_dhd_wlfc_hanger) {
+		kfree(wlan_static_dhd_wlfc_hanger);
+	}
+#endif /* CONFIG_BCMDHD_PCIE */
+	if (wlan_static_dhd_info_buf) {
+#ifdef CONFIG_BCMDHD_PCIE
+		kvfree(wlan_static_dhd_info_buf);
+#else
+		kfree(wlan_static_dhd_info_buf);
+#endif /* CONFIG_BCMDHD_PCIE */
+	}
+
+	if (wlan_static_dhd_log_dump_buf) {
+		DUMP_BUF_MFREE(wlan_static_dhd_log_dump_buf);
+	}
+
+	if (wlan_static_dhd_log_dump_buf_ex) {
+		DUMP_BUF_MFREE(wlan_static_dhd_log_dump_buf_ex);
+	}
+
+	if (wlan_static_scan_buf1) {
+#ifdef CONFIG_BCMDHD_PCIE
+		kvfree(wlan_static_scan_buf1);
+#else
+		kfree(wlan_static_scan_buf1);
+#endif /* CONFIG_BCMDHD_PCIE */
+	}
+
+	if (wlan_static_scan_buf0) {
+#ifdef CONFIG_BCMDHD_PCIE
+		kvfree(wlan_static_scan_buf0);
+#else
+		kfree(wlan_static_scan_buf0);
+#endif /* CONFIG_BCMDHD_PCIE */
+	}
+
+	for (i = 0; i < PREALLOC_WLAN_SEC_NUM; i++) {
+		if (wlan_mem_array[i].mem_ptr) {
+#ifdef CONFIG_BCMDHD_PCIE
+			kvfree(wlan_mem_array[i].mem_ptr);
+#else
+			kfree(wlan_mem_array[i].mem_ptr);
+#endif /* CONFIG_BCMDHD_PCIE */
+		}
+	}
+
+	for (i = 0; i < WLAN_SKB_BUF_NUM; i++) {
+		dev_kfree_skb(wlan_static_skb[i]);
+	}
+
+	return;
+}
+EXPORT_SYMBOL(dhd_exit_wlan_mem);
+#endif /* CONFIG_BROADCOM_WIFI_RESERVED_MEM */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_dbg.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_dbg.h
@@ -0,0 +1,590 @@
+/*
+ * Debug/trace/assert driver definitions for Dongle Host Driver.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef _dhd_dbg_
+#define _dhd_dbg_
+
+#if defined(NDIS)
+#include "wl_nddbg.h"
+#endif /* defined(NDIS) */
+#ifdef DHD_LOG_DUMP
+#include <dhd_log_dump.h>
+#endif
+
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+/* Only for writing to ring */
+#define DHD_INFO_RING(args)	DHD_ERROR(args)
+/* FW_VERBOSE RING */
+#define DHD_LOG_DUMP_FWLOG	DHD_LOG_DUMP_WRITE_EX
+#define DHD_LOG_DUMP_FWLOG_TS	DHD_LOG_DUMP_WRITE_EX_TS
+#else
+#define DHD_INFO_RING(args)
+/* DLD_BUF_TYPE_GENERAL */
+#define DHD_LOG_DUMP_FWLOG	DHD_LOG_DUMP_WRITE
+#define DHD_LOG_DUMP_FWLOG_TS	DHD_LOG_DUMP_WRITE_TS
+#endif
+
+#ifdef CUSTOM_PREFIX
+#define DBG_PRINT_PREFIX "[%s]"CUSTOM_PREFIX, OSL_GET_RTCTIME()
+#elif defined(CUSTOM_PREFIX_NORTCTIME)
+#define DBG_PRINT_PREFIX CUSTOM_PREFIX_NORTCTIME
+
+#define DBG_PRINT_SYSTEM_TIME pr_cont(DBG_PRINT_PREFIX)
+#define DHD_CONS_ONLY(args)	\
+do {	\
+	DBG_PRINT_SYSTEM_TIME;	\
+	pr_cont args;		\
+} while (0)
+#else
+#define DBG_PRINT_SYSTEM_TIME
+#define DHD_CONS_ONLY(args) do { printf args;} while (0)
+#endif /* CUSTOM_PREFIX */
+
+#if defined(BCMDBG) || defined(DHD_DEBUG)
+
+#if defined(NDIS)
+#define DHD_ERROR(args)		do {if (dhd_msg_level & DHD_ERROR_VAL) \
+					{printf args;  DHD_NDDBG_OUTPUT args;}} while (0)
+#define DHD_TRACE(args)		do {if (dhd_msg_level & DHD_TRACE_VAL) \
+					{printf args; DHD_NDDBG_OUTPUT args;}} while (0)
+#define DHD_INFO(args)		do {if (dhd_msg_level & DHD_INFO_VAL) \
+					{printf args; DHD_NDDBG_OUTPUT args;}} while (0)
+#define DHD_ERROR_ROAM(args)	DHD_ERROR(args)
+#else
+/* NON-NDIS cases */
+#ifdef DHD_LOG_DUMP
+/* !defined(DHD_EFI) and defined(DHD_LOG_DUMP) */
+#define DHD_ERROR(args)	\
+do {	\
+	if (dhd_msg_level & DHD_ERROR_VAL) {	\
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_ERROR_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;	\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+#define DHD_INFO(args)	\
+do {	\
+	if (dhd_msg_level & DHD_INFO_VAL) {	\
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_INFO_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;	\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+#else
+#define DHD_INFO(args)		do {if (dhd_msg_level & DHD_INFO_VAL) printf args;} while (0)
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
+#else /* DHD_LOG_DUMP */
+/* !defined(DHD_LOG_DUMP cases) */
+#define DHD_ERROR(args)		do {if (dhd_msg_level & DHD_ERROR_VAL) printf args;} while (0)
+#define DHD_INFO(args)		do {if (dhd_msg_level & DHD_INFO_VAL) printf args;} while (0)
+#define DHD_ERROR_ROAM(args)	DHD_ERROR(args)
+#endif /* DHD_LOG_DUMP */
+
+#define DHD_TRACE(args)		do {if (dhd_msg_level & DHD_TRACE_VAL) printf args;} while (0)
+#endif /* defined(NDIS) */
+
+#ifdef DHD_LOG_DUMP
+/* LOG_DUMP defines common to EFI and NON-EFI */
+/* NON-EFI builds with LOG DUMP enabled */
+#define DHD_ERROR_MEM(args) \
+do {	\
+	if (dhd_msg_level & DHD_ERROR_VAL) {	\
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_ERROR_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;		\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+#define DHD_IOVAR_MEM(args) \
+do {	\
+	if (dhd_msg_level & DHD_ERROR_VAL) {	\
+		if (dhd_msg_level & DHD_IOVAR_MEM_VAL) {	\
+			printf args;		\
+		}	\
+	}	\
+	if (dhd_log_level & DHD_ERROR_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;		\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+#define DHD_LOG_MEM(args) \
+do {	\
+	if (dhd_log_level & DHD_ERROR_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;		\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+
+#define DHD_EVENT(args) \
+do {	\
+	if (dhd_msg_level & DHD_EVENT_VAL) {	\
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_EVENT_VAL) {	\
+		DHD_LOG_DUMP_WRITE_PRSRV_TS;	\
+		DHD_LOG_DUMP_WRITE_PRSRV args;	\
+	}	\
+} while (0)
+#define DHD_PRSRV_MEM(args) \
+do {	\
+	if (dhd_msg_level & DHD_EVENT_VAL) {	\
+		if (dhd_msg_level & DHD_PRSRV_MEM_VAL) {	\
+			printf args;		\
+		}	\
+	}	\
+	if (dhd_log_level & DHD_EVENT_VAL) {	\
+		DHD_LOG_DUMP_WRITE_PRSRV_TS;		\
+		DHD_LOG_DUMP_WRITE_PRSRV args;	\
+	}	\
+} while (0)
+/* Re-using 'DHD_MSGTRACE_VAL' for controlling printing of ecounter binary event
+* logs to console and debug dump -- need to cleanup in the future to use separate
+* 'DHD_ECNTR_VAL' bitmap flag. 'DHD_MSGTRACE_VAL' will be defined only
+* for non-android builds.
+*/
+#define DHD_ECNTR_LOG(args) \
+do {	\
+	if (dhd_msg_level & DHD_EVENT_VAL) {	\
+		if (dhd_msg_level & DHD_MSGTRACE_VAL) { \
+			printf args;		\
+		}	\
+	}	\
+	if (dhd_log_level & DHD_EVENT_VAL) {	\
+		if (dhd_log_level & DHD_MSGTRACE_VAL) { \
+			DHD_LOG_DUMP_WRITE_TS;		\
+			DHD_LOG_DUMP_WRITE args;	\
+		}	\
+	}	\
+} while (0)
+#define DHD_ERROR_EX(args)					\
+do {										\
+	if (dhd_msg_level & DHD_ERROR_VAL) {    \
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_ERROR_VAL) {    \
+		DHD_LOG_DUMP_WRITE_EX_TS;	\
+		DHD_LOG_DUMP_WRITE_EX args;	\
+	}	\
+} while (0)
+#define DHD_MSGTRACE_LOG(args)	\
+do {	\
+	if (dhd_msg_level & DHD_MSGTRACE_VAL) {	\
+		printf args;		\
+	}	\
+	DHD_LOG_DUMP_WRITE_TS;		\
+	DHD_LOG_DUMP_WRITE args;	\
+} while (0)
+
+#define DHD_ERROR_ROAM(args)	\
+do {	\
+	if (dhd_msg_level & DHD_ERROR_VAL) {	\
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_ERROR_VAL) {	\
+		DHD_LOG_DUMP_WRITE_ROAM_TS;	\
+		DHD_LOG_DUMP_WRITE_ROAM args;	\
+	}	\
+} while (0)
+
+#define DHD_PKT_MON(args)	\
+do {	\
+	if (dhd_msg_level & DHD_PKT_MON_VAL) {	\
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_PKT_MON_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;	\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+
+#define DHD_CTL(args)	\
+do {	\
+	if (dhd_msg_level & DHD_CTL_VAL) {	\
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_CTL_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;	\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+
+#define DHD_TIMER(args)	\
+do {	\
+	if (dhd_msg_level & DHD_TIMER_VAL) {	\
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_TIMER_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;	\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+
+#define DHD_INTR(args)	\
+do {	\
+	if (dhd_msg_level & DHD_INTR_VAL) {	\
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_INTR_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;	\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+
+#define DHD_ISCAN(args)	\
+do {	\
+	if (dhd_msg_level & DHD_ISCAN_VAL) {	\
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_ISCAN_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;	\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+
+#define DHD_ARPOE(args)	\
+do {	\
+	if (dhd_msg_level & DHD_ARPOE_VAL) {	\
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_ARPOE_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;	\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+
+#define DHD_REORDER(args)	\
+do {	\
+	if (dhd_msg_level & DHD_REORDER_VAL) {	\
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_REORDER_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;	\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+
+#define DHD_PNO(args)	\
+do {	\
+	if (dhd_msg_level & DHD_PNO_VAL) {	\
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_PNO_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;	\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+
+#define DHD_RTT(args)	\
+do {	\
+	if (dhd_msg_level & DHD_RTT_VAL) {	\
+		printf args;		\
+	}	\
+	if (dhd_log_level & DHD_RTT_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;	\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+
+#define DHD_RPM(args)	\
+do { \
+	if (dhd_msg_level & DHD_RPM_VAL) {	\
+		printf args;	\
+	}	\
+	if (dhd_log_level & DHD_RPM_VAL) {	\
+		DHD_LOG_DUMP_WRITE_TS;	\
+		DHD_LOG_DUMP_WRITE args;	\
+	}	\
+} while (0)
+#else /* DHD_LOG_DUMP */
+/* !DHD_LOG_DUMP */
+#define DHD_MSGTRACE_LOG(args)  do {if (dhd_msg_level & DHD_MSGTRACE_VAL) printf args;} while (0)
+#define DHD_ERROR_MEM(args)	DHD_ERROR(args)
+#define DHD_IOVAR_MEM(args)	DHD_ERROR(args)
+#define DHD_LOG_MEM(args)	DHD_ERROR(args)
+#define DHD_EVENT(args)		do {if (dhd_msg_level & DHD_EVENT_VAL) printf args;} while (0)
+#define DHD_ECNTR_LOG(args)	DHD_EVENT(args)
+#define DHD_PRSRV_MEM(args)	DHD_EVENT(args)
+#define DHD_ERROR_EX(args)	DHD_ERROR(args)
+#define DHD_ERROR_ROAM(args)	DHD_ERROR(args)
+#define DHD_PKT_MON(args)	DHD_ERROR(args)
+#endif /* DHD_LOG_DUMP */
+
+#if !defined(DHD_LOG_DUMP)
+#define DHD_CTL(args)		do {if (dhd_msg_level & DHD_CTL_VAL) printf args;} while (0)
+#define DHD_TIMER(args)		do {if (dhd_msg_level & DHD_TIMER_VAL) printf args;} while (0)
+#define DHD_INTR(args)		do {if (dhd_msg_level & DHD_INTR_VAL) printf args;} while (0)
+#define DHD_ISCAN(args)		do {if (dhd_msg_level & DHD_ISCAN_VAL) printf args;} while (0)
+#define DHD_ARPOE(args)		do {if (dhd_msg_level & DHD_ARPOE_VAL) printf args;} while (0)
+#define DHD_REORDER(args)	do {if (dhd_msg_level & DHD_REORDER_VAL) printf args;} while (0)
+#define DHD_PNO(args)		do {if (dhd_msg_level & DHD_PNO_VAL) printf args;} while (0)
+#define DHD_RTT(args)		do {if (dhd_msg_level & DHD_RTT_VAL) printf args;} while (0)
+#define DHD_RPM(args)		do {if (dhd_msg_level & DHD_RPM_VAL) printf args;} while (0)
+#endif
+
+#define DHD_DATA(args)		do {if (dhd_msg_level & DHD_DATA_VAL) printf args;} while (0)
+#define DHD_HDRS(args)		do {if (dhd_msg_level & DHD_HDRS_VAL) printf args;} while (0)
+#define DHD_BYTES(args)		do {if (dhd_msg_level & DHD_BYTES_VAL) printf args;} while (0)
+#define DHD_GLOM(args)		do {if (dhd_msg_level & DHD_GLOM_VAL) printf args;} while (0)
+#define DHD_BTA(args)		do {if (dhd_msg_level & DHD_BTA_VAL) printf args;} while (0)
+
+#if defined(DHD_LOG_DUMP)
+#if defined(DHD_LOG_PRINT_RATE_LIMIT)
+
+#define DHD_FWLOG(args)	\
+do { \
+	if (dhd_msg_level & DHD_FWLOG_VAL) { \
+		if (control_logtrace && !log_print_threshold) \
+			printf args; \
+	} \
+	if (dhd_log_level & DHD_FWLOG_VAL) { \
+		DHD_LOG_DUMP_FWLOG_TS;	\
+		DHD_LOG_DUMP_FWLOG args; \
+	} \
+} while (0)
+
+#else /* DHD_LOG_PRINT_RATE_LIMIT */
+#define DHD_FWLOG(args)	\
+	do { \
+		if (dhd_msg_level & DHD_FWLOG_VAL) { \
+			if (control_logtrace) \
+				printf args; \
+			DHD_LOG_DUMP_WRITE args; \
+		} \
+	} while (0)
+#endif /* DHD_LOG_PRINT_RATE_LIMIT */
+#else /* DHD_LOG_DUMP */
+#if defined(NDIS) && (NDISVER >= 0x0630)
+#define DHD_FWLOG(args)		do {if (dhd_msg_level & DHD_FWLOG_VAL) \
+					{printf args;  DHD_NDDBG_OUTPUT args;}} while (0)
+#else
+#define DHD_FWLOG(args)		do {if (dhd_msg_level & DHD_FWLOG_VAL) printf args;} while (0)
+#endif /* defined(NDIS) && (NDISVER >= 0x0630) */
+#endif /* DHD_LOG_DUMP */
+
+#define DHD_DBGIF(args)		do {if (dhd_msg_level & DHD_DBGIF_VAL) printf args;} while (0)
+#define DHD_TXFLOWCTL(args)     DHD_RPM(args)
+
+#define DHD_TRACE_HW4	DHD_TRACE
+#define DHD_INFO_HW4	DHD_INFO
+#define DHD_ERROR_NO_HW4	DHD_ERROR
+
+#define DHD_ERROR_ON()		(dhd_msg_level & DHD_ERROR_VAL)
+#define DHD_TRACE_ON()		(dhd_msg_level & DHD_TRACE_VAL)
+#define DHD_INFO_ON()		(dhd_msg_level & DHD_INFO_VAL)
+#define DHD_DATA_ON()		(dhd_msg_level & DHD_DATA_VAL)
+#define DHD_CTL_ON()		(dhd_msg_level & DHD_CTL_VAL)
+#define DHD_TIMER_ON()		(dhd_msg_level & DHD_TIMER_VAL)
+#define DHD_HDRS_ON()		(dhd_msg_level & DHD_HDRS_VAL)
+#define DHD_BYTES_ON()		(dhd_msg_level & DHD_BYTES_VAL)
+#define DHD_INTR_ON()		(dhd_msg_level & DHD_INTR_VAL)
+#define DHD_GLOM_ON()		(dhd_msg_level & DHD_GLOM_VAL)
+#define DHD_EVENT_ON()		(dhd_msg_level & DHD_EVENT_VAL)
+#define DHD_BTA_ON()		(dhd_msg_level & DHD_BTA_VAL)
+#define DHD_ISCAN_ON()		(dhd_msg_level & DHD_ISCAN_VAL)
+#define DHD_ARPOE_ON()		(dhd_msg_level & DHD_ARPOE_VAL)
+#define DHD_REORDER_ON()	(dhd_msg_level & DHD_REORDER_VAL)
+#define DHD_NOCHECKDIED_ON()	(dhd_msg_level & DHD_NOCHECKDIED_VAL)
+#define DHD_PNO_ON()		(dhd_msg_level & DHD_PNO_VAL)
+#define DHD_RTT_ON()		(dhd_msg_level & DHD_RTT_VAL)
+#define DHD_MSGTRACE_ON()	(dhd_msg_level & DHD_MSGTRACE_VAL)
+#define DHD_FWLOG_ON()		(dhd_msg_level & DHD_FWLOG_VAL)
+#define DHD_DBGIF_ON()		(dhd_msg_level & DHD_DBGIF_VAL)
+#define DHD_PKT_MON_ON()	(dhd_msg_level & DHD_PKT_MON_VAL)
+#define DHD_PKT_MON_DUMP_ON()	(dhd_msg_level & DHD_PKT_MON_DUMP_VAL)
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+#define DHD_RPM_ON()		(dhd_msg_level & DHD_RPM_VAL)
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+#else /* defined(BCMDBG) || defined(DHD_DEBUG) */
+
+#if defined(NDIS)
+#define DHD_ERROR(args)		do {if (dhd_msg_level & DHD_ERROR_VAL) \
+					{printf args;  DHD_NDDBG_OUTPUT args;}} while (0)
+#define DHD_TRACE(args)		do {if (dhd_msg_level & DHD_TRACE_VAL) \
+					{DHD_NDDBG_OUTPUT args;}} while (0)
+#define DHD_INFO(args)		do {if (dhd_msg_level & DHD_INFO_VAL) \
+					{DHD_NDDBG_OUTPUT args;}} while (0)
+#else /* DHD_EFI && DHD_LOG_DUMP */
+
+#define DHD_ERROR(args)		do {if (dhd_msg_level & DHD_ERROR_VAL) \
+								printf args;} while (0)
+#define DHD_TRACE(args)
+#define DHD_INFO(args)
+#define DHD_ERROR_ROAM(args)	DHD_ERROR(args)
+#endif /* defined(NDIS) */
+
+#define DHD_DATA(args)
+#define DHD_CTL(args)
+#define DHD_TIMER(args)
+#define DHD_HDRS(args)
+#define DHD_BYTES(args)
+#define DHD_INTR(args)
+#define DHD_GLOM(args)
+
+#define DHD_EVENT(args)
+#define DHD_ECNTR_LOG(args)	DHD_EVENT(args)
+
+#define DHD_PRSRV_MEM(args)	DHD_EVENT(args)
+
+#define DHD_BTA(args)
+#define DHD_ISCAN(args)
+#define DHD_ARPOE(args)
+#define DHD_REORDER(args)
+#define DHD_PNO(args)
+#define DHD_RTT(args)
+#define DHD_PKT_MON(args)
+
+#define DHD_MSGTRACE_LOG(args)
+#define DHD_FWLOG(args)
+
+#define DHD_DBGIF(args)
+
+#define DHD_ERROR_MEM(args)	DHD_ERROR(args)
+#define DHD_IOVAR_MEM(args)	DHD_ERROR(args)
+#define DHD_LOG_MEM(args)	DHD_ERROR(args)
+#define DHD_ERROR_EX(args)	DHD_ERROR(args)
+#define DHD_ERROR_ROAM(args)    DHD_ERROR(args)
+#define DHD_RPM(args)		DHD_ERROR(args)
+#define DHD_TXFLOWCTL(args)     DHD_ERROR(args)
+#define DHD_TRACE_HW4	DHD_TRACE
+#define DHD_INFO_HW4	DHD_INFO
+#define DHD_ERROR_NO_HW4	DHD_ERROR
+
+#define DHD_ERROR_ON()		0
+#define DHD_TRACE_ON()		0
+#define DHD_INFO_ON()		0
+#define DHD_DATA_ON()		0
+#define DHD_CTL_ON()		0
+#define DHD_TIMER_ON()		0
+#define DHD_HDRS_ON()		0
+#define DHD_BYTES_ON()		0
+#define DHD_INTR_ON()		0
+#define DHD_GLOM_ON()		0
+#define DHD_EVENT_ON()		0
+#define DHD_BTA_ON()		0
+#define DHD_ISCAN_ON()		0
+#define DHD_ARPOE_ON()		0
+#define DHD_REORDER_ON()	0
+#define DHD_NOCHECKDIED_ON()	0
+#define DHD_PNO_ON()		0
+#define DHD_RTT_ON()		0
+#define DHD_PKT_MON_ON()	0
+#define DHD_PKT_MON_DUMP_ON()	0
+#define DHD_MSGTRACE_ON()	0
+#define DHD_FWLOG_ON()		0
+#define DHD_DBGIF_ON()		0
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+#define DHD_RPM_ON()		0
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+#endif /* defined(BCMDBG) || defined(DHD_DEBUG) */
+
+#define PRINT_RATE_LIMIT_PERIOD 5000000u /* 5s in units of us */
+#define DHD_ERROR_RLMT(args) \
+do {	\
+	if (dhd_msg_level & DHD_ERROR_VAL) {	\
+		static uint64 __err_ts = 0; \
+		static uint32 __err_cnt = 0; \
+		uint64 __cur_ts = 0; \
+		__cur_ts = OSL_SYSUPTIME_US(); \
+		if (__err_ts == 0 || (__cur_ts > __err_ts && \
+		(__cur_ts - __err_ts > PRINT_RATE_LIMIT_PERIOD))) { \
+			__err_ts = __cur_ts; \
+			DHD_ERROR(args);	\
+			DHD_ERROR(("[Repeats %u times]\n", __err_cnt)); \
+			__err_cnt = 0; \
+		} else { \
+			++__err_cnt; \
+		} \
+	}	\
+} while (0)
+
+/* even in non-BCMDBG builds, logging of dongle iovars should be available */
+#define DHD_DNGL_IOVAR_SET(args) \
+	do {if (dhd_msg_level & DHD_DNGL_IOVAR_SET_VAL) printf args;} while (0)
+
+#ifdef BCMPERFSTATS
+#define DHD_LOG(args)		do {if (dhd_msg_level & DHD_LOG_VAL) bcmlog args;} while (0)
+#else
+#define DHD_LOG(args)
+#endif
+
+#define DHD_BLOG(cp, size)
+
+#define DHD_NONE(args)
+extern int dhd_msg_level;
+extern int dhd_log_level;
+#ifdef DHD_LOG_PRINT_RATE_LIMIT
+extern int log_print_threshold;
+#endif /* DHD_LOG_PRINT_RATE_LIMIT */
+
+#ifdef DHD_IOVAR_LOG_FILTER_DUMP
+#define DHD_IOVAR_LOG_CHECK(dhd_pub, ioc_cmd, ioc_msg) \
+	dhd_iovar_log_dump_check(dhd_pub, ioc_cmd, ioc_msg)
+#else
+#define DHD_IOVAR_LOG_CHECK(dhd_pub, ioc_cmd, ioc_msg) TRUE
+#endif /* DHD_IOVAR_LOG_FILTER_DUMP */
+
+#define DHD_IOVAR_LOG(dhd_pub, ioc_cmd, ioc_msg, fmt) \
+	do { \
+		if (DHD_IOVAR_LOG_CHECK(dhd_pub, ioc_cmd, ioc_msg)) { \
+			DHD_IOVAR_MEM(fmt); \
+		} else { \
+			DHD_TRACE(fmt); \
+		} \
+	} while (0)
+
+/* DHD_PRINT - informational non-error messages which need to be always printed */
+#define DHD_PRINT	DHD_ERROR
+
+/* Defines msg bits */
+#include <dhdioctl.h>
+
+#endif /* _dhd_dbg_ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_dbg_ring.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_dbg_ring.c
@@ -0,0 +1,580 @@
+/*
+ * DHD debug ring API and structures - implementation
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+#include <typedefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_dbg.h>
+#include <dhd_dbg_ring.h>
+#include <dhd_debug.h>
+
+dhd_dbg_ring_t *
+dhd_dbg_ring_alloc_init(dhd_pub_t *dhd, uint16 ring_id,
+	char *ring_name, uint32 ring_sz, void *allocd_buf,
+	bool pull_inactive)
+{
+	dhd_dbg_ring_t *ring = NULL;
+	int ret = 0;
+	unsigned long flags = 0;
+
+	ring = MALLOCZ(dhd->osh, sizeof(dhd_dbg_ring_t));
+	if (!ring)
+		goto fail;
+
+	ret = dhd_dbg_ring_init(dhd, ring, ring_id,
+			(uint8 *)ring_name, ring_sz,
+			allocd_buf, pull_inactive);
+	if (ret != BCME_OK) {
+		DHD_ERROR(("%s: unable to init ring %s!\n",
+				__FUNCTION__, ring_name));
+		goto fail;
+	}
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+	ring->state = RING_ACTIVE;
+	ring->threshold = 0;
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+	return ring;
+
+fail:
+	if (ring) {
+		dhd_dbg_ring_deinit(dhd, ring);
+		ring->ring_buf = NULL;
+		ring->ring_size = 0;
+		MFREE(dhd->osh, ring, sizeof(dhd_dbg_ring_t));
+	}
+	return NULL;
+}
+
+void
+dhd_dbg_ring_dealloc_deinit(void **ring_ptr, dhd_pub_t *dhd)
+{
+	dhd_dbg_ring_t *ring = NULL;
+	dhd_dbg_ring_t **dbgring = (dhd_dbg_ring_t **)ring_ptr;
+
+	if (!dbgring)
+		return;
+
+	ring = *dbgring;
+
+	if (ring) {
+		dhd_dbg_ring_deinit(dhd, ring);
+		ring->ring_buf = NULL;
+		ring->ring_size = 0;
+		MFREE(dhd->osh, ring, sizeof(dhd_dbg_ring_t));
+		*dbgring = NULL;
+	}
+}
+
+int
+dhd_dbg_ring_init(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring, uint16 id, uint8 *name,
+		uint32 ring_sz, void *allocd_buf, bool pull_inactive)
+{
+	void *buf;
+	unsigned long flags = 0;
+
+	if (allocd_buf == NULL) {
+		/* for DEBUG_DUMP and MEM_DUMP, buffer can be NULL
+		 * since act as delayed allocation or fake rings
+		 */
+		if (id != DEBUG_DUMP_RING1_ID && id != DEBUG_DUMP_RING2_ID &&
+				id != MEM_DUMP_RING_ID) {
+			return BCME_NOMEM;
+		}
+		buf = NULL;
+	} else {
+		buf = allocd_buf;
+	}
+
+	ring->lock = DHD_DBG_RING_LOCK_INIT(dhdp->osh);
+
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+	ring->id = id;
+	strlcpy((char *)ring->name, (char *)name, sizeof(ring->name));
+	ring->ring_size = ring_sz;
+	ring->wp = ring->rp = 0;
+	ring->ring_buf = buf;
+	ring->threshold = DBGRING_FLUSH_THRESHOLD(ring);
+	ring->state = RING_SUSPEND;
+	ring->rem_len = 0;
+	ring->sched_pull = TRUE;
+	ring->pull_inactive = pull_inactive;
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+	return BCME_OK;
+}
+
+int
+dhd_dbg_ring_set_buf(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring, void *buf)
+{
+	unsigned long flags = 0;
+
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+	ring->ring_buf = buf;
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+	return BCME_OK;
+}
+void
+dhd_dbg_ring_deinit(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring)
+{
+	unsigned long flags = 0;
+
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+	ring->id = 0;
+	ring->name[0] = 0;
+	ring->wp = ring->rp = 0;
+	memset(&ring->stat, 0, sizeof(ring->stat));
+	ring->threshold = 0;
+	ring->state = RING_STOP;
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+	DHD_DBG_RING_LOCK_DEINIT(dhdp->osh, ring->lock);
+}
+
+void
+dhd_dbg_ring_sched_pull(dhd_dbg_ring_t *ring, uint32 pending_len,
+		os_pullreq_t pull_fn, void *os_pvt, const int id)
+{
+	unsigned long flags = 0;
+
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+	/* if the current pending size is bigger than threshold and
+	 * threshold is set
+	 */
+	if (ring->threshold > 0 &&
+	   (pending_len >= ring->threshold) && ring->sched_pull) {
+		/*
+		 * Update the state and release the lock before calling
+		 * the pull_fn. Do not transfer control to other layers
+		 * with locks held. If the call back again calls into
+		 * the same layer fro this context, can lead to deadlock.
+		 */
+		ring->sched_pull = FALSE;
+		DHD_DBG_RING_UNLOCK(ring->lock, flags);
+		pull_fn(os_pvt, id);
+	} else {
+		DHD_DBG_RING_UNLOCK(ring->lock, flags);
+	}
+}
+
+uint32
+dhd_dbg_ring_get_pending_len(dhd_dbg_ring_t *ring)
+{
+	uint32 pending_len = 0;
+	unsigned long flags = 0;
+
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+	if (ring->stat.written_bytes > ring->stat.read_bytes) {
+		pending_len = ring->stat.written_bytes - ring->stat.read_bytes;
+	} else if (ring->stat.written_bytes < ring->stat.read_bytes) {
+		pending_len = PENDING_LEN_MAX - ring->stat.read_bytes + ring->stat.written_bytes;
+	} else {
+		pending_len = 0;
+	}
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+	return pending_len;
+}
+
+#ifdef DHD_PKT_LOGGING_DBGRING
+int
+dhd_dbg_ring_update(void *dbg_ring, uint32 w_len)
+{
+	unsigned long flags;
+	dhd_dbg_ring_t *ring = (dhd_dbg_ring_t *)dbg_ring;
+
+	if (ring->id != PACKET_LOG_RING_ID) {
+		return BCME_UNSUPPORTED;
+	}
+
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+
+	if (ring->state != RING_ACTIVE) {
+		DHD_DBG_RING_UNLOCK(ring->lock, flags);
+		return BCME_OK;
+	}
+
+	/* update statistics */
+	ring->stat.written_records++;
+	ring->stat.written_bytes += w_len;
+	DHD_DBGIF(("%s : RING%d[%s] written_records %d, written_bytes %d, read_bytes=%d,"
+		" ring->threshold=%d, wp=%d, rp=%d\n", __FUNCTION__, ring->id, ring->name,
+		ring->stat.written_records, ring->stat.written_bytes, ring->stat.read_bytes,
+		ring->threshold, ring->wp, ring->rp));
+
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+	return BCME_OK;
+}
+#endif /* DHD_PKT_LOGGING_DBGRING */
+
+int
+dhd_dbg_ring_push(dhd_dbg_ring_t *ring, dhd_dbg_ring_entry_t *hdr, void *data)
+{
+	unsigned long flags;
+	uint32 w_len;
+	uint32 avail_size;
+	dhd_dbg_ring_entry_t *w_entry, *r_entry;
+	int ret;
+
+	if (!ring || !hdr || !data) {
+		return BCME_BADARG;
+	}
+
+#if defined(__linux__)
+	/* Prevents the case of accessing the ring buffer in the HardIRQ context.
+	 * If an interrupt arise after holding ring lock, It could try the same lock.
+	 * This is to use the ring lock as spin_lock_bh instead of spin_lock_irqsave.
+	 */
+	if (in_irq()) {
+		return BCME_BUSY;
+	}
+#endif /* defined(__linux__) */
+
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+
+	if (ring->state != RING_ACTIVE) {
+		DHD_DBG_RING_UNLOCK(ring->lock, flags);
+		return BCME_OK;
+	}
+
+	w_len = ENTRY_LENGTH(hdr);
+
+	DHD_DBGIF(("%s: RING%d[%s] hdr->len=%u, w_len=%u, wp=%d, rp=%d, ring_start=0x%p;"
+		" ring_size=%u\n",
+		__FUNCTION__, ring->id, ring->name, hdr->len, w_len, ring->wp, ring->rp,
+		ring->ring_buf, ring->ring_size));
+
+	if (w_len > ring->ring_size) {
+		DHD_DBG_RING_UNLOCK(ring->lock, flags);
+		DHD_ERROR(("%s: RING%d[%s] w_len=%u, ring_size=%u,"
+			" write size exceeds ring size !\n",
+			__FUNCTION__, ring->id, ring->name, w_len, ring->ring_size));
+		return BCME_ERROR;
+	}
+	/* Claim the space */
+	do {
+		avail_size = DBG_RING_CHECK_WRITE_SPACE(ring->rp, ring->wp, ring->ring_size);
+		if (avail_size <= w_len) {
+			/* Prepare the space */
+			if (ring->rp <= ring->wp) {
+				ring->tail_padded = TRUE;
+				ring->rem_len = ring->ring_size - ring->wp;
+				DHD_DBGIF(("%s: RING%d[%s] Insuffient tail space,"
+					" rp=%d, wp=%d, rem_len=%d, ring_size=%d,"
+					" avail_size=%d, w_len=%d\n", __FUNCTION__,
+					ring->id, ring->name, ring->rp, ring->wp,
+					ring->rem_len, ring->ring_size, avail_size,
+					w_len));
+
+				/* 0 pad insufficient tail space */
+				memset((uint8 *)ring->ring_buf + ring->wp, 0, ring->rem_len);
+				/* If read pointer is still at the beginning, make some room */
+				if (ring->rp == 0) {
+					r_entry = (dhd_dbg_ring_entry_t *)((uint8 *)ring->ring_buf +
+						ring->rp);
+					ring->rp += ENTRY_LENGTH(r_entry);
+					ring->stat.read_bytes += ENTRY_LENGTH(r_entry);
+					DHD_DBGIF(("%s: rp at 0, move by one entry length"
+						" (%u bytes)\n",
+						__FUNCTION__, (uint32)ENTRY_LENGTH(r_entry)));
+				}
+				if (ring->rp == ring->wp) {
+					ring->rp = 0;
+				}
+				ring->wp = 0;
+				DHD_DBGIF(("%s: new rp=%u, wp=%u\n",
+					__FUNCTION__, ring->rp, ring->wp));
+			} else {
+				/* Not enough space for new entry, free some up */
+				r_entry = (dhd_dbg_ring_entry_t *)((uint8 *)ring->ring_buf +
+					ring->rp);
+				/* check bounds before incrementing read ptr */
+				if (ring->rp + ENTRY_LENGTH(r_entry) >= ring->ring_size) {
+					DHD_DBGIF(("%s: RING%d[%s] rp points out of boundary,"
+						"ring->wp=%u, ring->rp=%u, ring->ring_size=%d\n",
+						__FUNCTION__, ring->id, ring->name, ring->wp,
+						ring->rp, ring->ring_size));
+					ASSERT(0);
+					DHD_DBG_RING_UNLOCK(ring->lock, flags);
+					return BCME_BUFTOOSHORT;
+				}
+				ring->rp += ENTRY_LENGTH(r_entry);
+				/* skip padding if there is one */
+				if (ring->tail_padded &&
+					((ring->rp + ring->rem_len) == ring->ring_size)) {
+					DHD_DBGIF(("%s: RING%d[%s] Found padding,"
+						" avail_size=%d, w_len=%d, set rp = 0\n",
+						__FUNCTION__,
+						ring->id, ring->name, avail_size, w_len));
+					ring->rp = 0;
+					ring->tail_padded = FALSE;
+					ring->rem_len = 0;
+				}
+				ring->stat.read_bytes += ENTRY_LENGTH(r_entry);
+				DHD_DBGIF(("%s: RING%d[%s] read_bytes=%d, wp=%d, rp=%d\n",
+					__FUNCTION__, ring->id, ring->name, ring->stat.read_bytes,
+					ring->wp, ring->rp));
+			}
+		} else {
+			break;
+		}
+	} while (TRUE);
+
+	/* check before writing to the ring */
+	if (ring->wp + w_len >= ring->ring_size) {
+		DHD_DBGIF(("%s: RING%d[%s] wp pointed out of ring boundary, "
+			"wp=%d, ring_size=%d, w_len=%u\n", __FUNCTION__, ring->id,
+			ring->name, ring->wp, ring->ring_size, w_len));
+		ASSERT(0);
+		DHD_DBG_RING_UNLOCK(ring->lock, flags);
+		return BCME_BUFTOOLONG;
+	}
+
+	w_entry = (dhd_dbg_ring_entry_t *)((uint8 *)ring->ring_buf + ring->wp);
+	/* header */
+	ret = memcpy_s(w_entry, avail_size, hdr, DBG_RING_ENTRY_SIZE);
+	if (ret) {
+		DHD_ERROR((" memcpy_s() error : %d, destsz: %d, n: %d\n",
+			ret, avail_size, (int)DBG_RING_ENTRY_SIZE));
+		return BCME_ERROR;
+	}
+	w_entry->len = hdr->len;
+	/* payload */
+	avail_size -= DBG_RING_ENTRY_SIZE;
+	ret = memcpy_s((char *)w_entry + DBG_RING_ENTRY_SIZE,
+		avail_size, data, w_entry->len);
+	if (ret) {
+		DHD_ERROR((" memcpy_s() error : %d, destsz: %d, n: %d\n",
+			ret, avail_size, w_entry->len));
+		return BCME_ERROR;
+	}
+	/* update write pointer */
+	ring->wp += w_len;
+
+	/* update statistics */
+	ring->stat.written_records++;
+	ring->stat.written_bytes += w_len;
+	DHD_DBGIF(("%s : RING%d[%s] written_records %d, written_bytes %d, read_bytes=%d,"
+		" ring->threshold=%d, wp=%d, rp=%d\n", __FUNCTION__, ring->id, ring->name,
+		ring->stat.written_records, ring->stat.written_bytes, ring->stat.read_bytes,
+		ring->threshold, ring->wp, ring->rp));
+
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+	return BCME_OK;
+}
+
+/*
+ * This function folds ring->lock, so callers of this function
+ * should not hold ring->lock.
+ */
+int
+dhd_dbg_ring_pull_single(dhd_dbg_ring_t *ring, void *data, uint32 buf_len, bool strip_header)
+{
+	dhd_dbg_ring_entry_t *r_entry = NULL;
+	uint32 rlen = 0;
+	char *buf = NULL;
+	unsigned long flags;
+
+	if (!ring || !data || buf_len <= 0) {
+		return 0;
+	}
+
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+	/* pull from ring is allowed for inactive (suspended) ring
+	 * in case of ecounters only, this is because, for ecounters
+	 * when a trap occurs the ring is suspended and data is then
+	 * pulled to dump it to a file. For other rings if ring is
+	 * not in active state return without processing (as before)
+	 */
+	if (!ring->pull_inactive && (ring->state != RING_ACTIVE)) {
+		goto exit;
+	}
+
+	if (ring->rp == ring->wp) {
+		goto exit;
+	}
+
+	DHD_DBGIF(("%s: RING%d[%s] buf_len=%u, wp=%d, rp=%d, ring_start=0x%p; ring_size=%u\n",
+		__FUNCTION__, ring->id, ring->name, buf_len, ring->wp, ring->rp,
+		ring->ring_buf, ring->ring_size));
+
+	r_entry = (dhd_dbg_ring_entry_t *)((uint8 *)ring->ring_buf + ring->rp);
+
+	/* Boundary Check */
+	rlen = ENTRY_LENGTH(r_entry);
+	if ((ring->rp + rlen) > ring->ring_size) {
+		DHD_DBGIF(("%s: entry len %d is out of boundary of ring size %d,"
+			" current ring %d[%s] - rp=%d\n", __FUNCTION__, rlen,
+			ring->ring_size, ring->id, ring->name, ring->rp));
+		rlen = 0;
+		goto exit;
+	}
+
+	if (strip_header) {
+		rlen = r_entry->len;
+		buf = (char *)r_entry + DBG_RING_ENTRY_SIZE;
+	} else {
+		rlen = ENTRY_LENGTH(r_entry);
+		buf = (char *)r_entry;
+	}
+	if (rlen > buf_len) {
+		DHD_DBGIF(("%s: buf len %d is too small for entry len %d\n",
+			__FUNCTION__, buf_len, rlen));
+		DHD_DBGIF(("%s: ring %d[%s] - ring size=%d, wp=%d, rp=%d\n",
+			__FUNCTION__, ring->id, ring->name, ring->ring_size,
+			ring->wp, ring->rp));
+		/* The state of ringbuffer is different between calculating buf_len
+		 * and current. ring->rp have chance to be update by pushing data
+		 * to ring buffer when unlocking after calculating buf_len.
+		 * But, It doesn't need to ASSERT because we only send up the
+		 * entries stored so far.
+		 */
+		rlen = 0;
+		goto exit;
+	}
+
+	memcpy(data, buf, rlen);
+	/* update ring context */
+	ring->rp += ENTRY_LENGTH(r_entry);
+	/* don't pass wp but skip padding if there is one */
+	if (ring->rp != ring->wp &&
+	    ring->tail_padded && ((ring->rp + ring->rem_len) >= ring->ring_size)) {
+		DHD_DBGIF(("%s: RING%d[%s] Found padding, rp=%d, wp=%d\n",
+			__FUNCTION__, ring->id, ring->name, ring->rp, ring->wp));
+		ring->rp = 0;
+		ring->tail_padded = FALSE;
+		ring->rem_len = 0;
+	}
+	if (ring->rp >= ring->ring_size) {
+		DHD_DBGIF(("%s: RING%d[%s] rp pointed out of ring boundary,"
+			" rp=%d, ring_size=%d\n", __FUNCTION__, ring->id,
+			ring->name, ring->rp, ring->ring_size));
+		ASSERT(0);
+		rlen = 0;
+		goto exit;
+	}
+	ring->stat.read_bytes += ENTRY_LENGTH(r_entry);
+	DHD_DBGIF(("%s RING%d[%s]read_bytes %d, wp=%d, rp=%d\n", __FUNCTION__,
+		ring->id, ring->name, ring->stat.read_bytes, ring->wp, ring->rp));
+
+exit:
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+	return rlen;
+}
+
+int
+dhd_dbg_ring_pull(dhd_dbg_ring_t *ring, void *data, uint32 buf_len,
+		bool strip_hdr, int *num_entries)
+{
+	int32 r_len, total_r_len = 0;
+	unsigned long flags;
+
+	if (!ring || !data)
+		return 0;
+
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+	if (!ring->pull_inactive && (ring->state != RING_ACTIVE)) {
+		DHD_DBG_RING_UNLOCK(ring->lock, flags);
+		return 0;
+	}
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+	while (buf_len > 0) {
+		r_len = dhd_dbg_ring_pull_single(ring, data, buf_len, strip_hdr);
+		if (r_len == 0)
+			break;
+		data = (uint8 *)data + r_len;
+		buf_len -= r_len;
+		total_r_len += r_len;
+		(*num_entries)++;
+	}
+
+	return total_r_len;
+}
+
+int
+dhd_dbg_ring_config(dhd_dbg_ring_t *ring, int log_level, uint32 threshold)
+{
+	unsigned long flags = 0;
+
+	if (!ring)
+		return BCME_BADADDR;
+
+	if (ring->state == RING_STOP)
+		return BCME_UNSUPPORTED;
+
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+
+	if (log_level == 0)
+		ring->state = RING_SUSPEND;
+	else
+		ring->state = RING_ACTIVE;
+
+	ring->log_level = log_level;
+	ring->threshold = MIN(threshold, DBGRING_FLUSH_THRESHOLD(ring));
+
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+	return BCME_OK;
+}
+
+void
+dhd_dbg_ring_start(dhd_dbg_ring_t *ring)
+{
+	if (!ring)
+		return;
+
+	/* Initialize the information for the ring */
+	ring->state = RING_SUSPEND;
+	ring->log_level = 0;
+	ring->rp = ring->wp = 0;
+	ring->threshold = 0;
+	memset(&ring->stat, 0, sizeof(struct ring_statistics));
+	memset(ring->ring_buf, 0, ring->ring_size);
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_dbg_ring.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_dbg_ring.h
@@ -0,0 +1,177 @@
+/*
+ * DHD debug ring header file - interface
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef __DHD_DBG_RING_H__
+#define __DHD_DBG_RING_H__
+
+#include <bcmutils.h>
+
+#if defined(LINUX)
+#define PACKED_STRUCT __attribute__ ((packed))
+#else
+#define PACKED_STRUCT
+#endif
+
+#define DBGRING_NAME_MAX 32
+
+enum dbg_ring_state {
+	RING_STOP = 0,  /* ring is not initialized */
+	RING_ACTIVE,    /* ring is live and logging */
+	RING_SUSPEND    /* ring is initialized but not logging */
+};
+
+/* each entry in dbg ring has below header, to handle
+ * variable length records in ring
+ */
+typedef struct dhd_dbg_ring_entry {
+	uint16 len; /* payload length excluding the header */
+	uint8 flags;
+	uint8 type; /* Per ring specific */
+	uint64 timestamp; /* present if has_timestamp bit is set. */
+} PACKED_STRUCT dhd_dbg_ring_entry_t;
+
+typedef struct dhd_dbg_ring_entry_pack {
+	uint32 magic;
+	int num_entries;
+} PACKED_STRUCT dhd_dbg_ring_entry_pack_t;
+
+struct ring_statistics {
+	/* number of bytes that was written to the buffer by driver */
+	uint32 written_bytes;
+	/* number of bytes that was read from the buffer by user land */
+	uint32 read_bytes;
+	/* number of records that was written to the buffer by driver */
+	uint32 written_records;
+};
+
+typedef struct dhd_dbg_ring_status {
+	uint8 name[DBGRING_NAME_MAX];
+	uint32 flags;
+	int ring_id; /* unique integer representing the ring */
+	/* total memory size allocated for the buffer */
+	uint32 ring_buffer_byte_size;
+	uint32 verbose_level;
+	/* number of bytes that was written to the buffer by driver */
+	uint32 written_bytes;
+	/* number of bytes that was read from the buffer by user land */
+	uint32 read_bytes;
+	/* number of records that was read from the buffer by user land */
+	uint32 written_records;
+} dhd_dbg_ring_status_t;
+
+typedef struct dhd_dbg_ring {
+	int     id;		/* ring id */
+	uint8   name[DBGRING_NAME_MAX]; /* name string */
+	uint32  ring_size;	/* numbers of item in ring */
+	uint32  wp;		/* write pointer */
+	uint32  rp;		/* read pointer */
+	uint32  rp_tmp;		/* tmp read pointer */
+	uint32  log_level;	/* log_level */
+	uint32  threshold;	/* threshold bytes */
+	void *  ring_buf;	/* pointer of actually ring buffer */
+	void *  lock;		/* lock for ring access */
+	struct ring_statistics stat;	/* statistics */
+	enum dbg_ring_state state;	/* ring state enum */
+	bool tail_padded;	/* writer does not have enough space */
+	uint32 rem_len;		/* number of bytes from wp_pad to end */
+	bool sched_pull;	/* schedule reader immediately */
+	bool pull_inactive;	/* pull contents from ring even if it is inactive */
+} dhd_dbg_ring_t;
+
+#define DBGRING_FLUSH_THRESHOLD(ring)		\
+	(ring->id != PACKET_LOG_RING_ID) ?		\
+	(ring->ring_size / 3u) : (ring->ring_size / 4u)
+#define RING_STAT_TO_STATUS(ring, status) \
+	do { \
+		/* status.name/ring->name are the same length so no need to check return value */ \
+		(void)memcpy_s(status.name, sizeof(status.name), ring->name, sizeof(ring->name)); \
+		status.ring_id = ring->id;     \
+		status.ring_buffer_byte_size = ring->ring_size;  \
+		status.written_bytes = ring->stat.written_bytes; \
+		status.written_records = ring->stat.written_records; \
+		status.read_bytes = ring->stat.read_bytes; \
+		status.verbose_level = ring->log_level; \
+	} while (0)
+
+#define DBG_RING_PACK_MAGIC 0xDBAADBAA
+#define DBG_RING_ENTRY_PACK_SIZE (sizeof(dhd_dbg_ring_entry_pack_t))
+#define DBG_RING_ENTRY_SIZE (sizeof(dhd_dbg_ring_entry_t))
+#define ENTRY_LENGTH(hdr) ((hdr)->len + DBG_RING_ENTRY_SIZE)
+#define PAYLOAD_MAX_LEN 65535
+#define PAYLOAD_RTT_MAX_LEN 1648u
+#define PAYLOAD_BCM_TRACE_MAX_LEN 1648u
+#define PENDING_LEN_MAX 0xFFFFFFFF
+#define DBG_RING_STATUS_SIZE (sizeof(dhd_dbg_ring_status_t))
+
+#define TXACTIVESZ(r, w, d)			(((r) <= (w)) ? ((w) - (r)) : ((d) - (r) + (w)))
+#define DBG_RING_READ_AVAIL_SPACE(w, r, d)		(((w) >= (r)) ? ((w) - (r)) : ((d) - (r)))
+#define DBG_RING_WRITE_SPACE_AVAIL_CONT(r, w, d)	(((w) >= (r)) ? ((d) - (w)) : ((r) - (w)))
+#define DBG_RING_WRITE_SPACE_AVAIL(r, w, d)		(d - (TXACTIVESZ(r, w, d)))
+#define DBG_RING_CHECK_WRITE_SPACE(r, w, d)		\
+		MIN(DBG_RING_WRITE_SPACE_AVAIL(r, w, d), DBG_RING_WRITE_SPACE_AVAIL_CONT(r, w, d))
+
+typedef void (*os_pullreq_t)(void *os_priv, const int ring_id);
+
+dhd_dbg_ring_t *dhd_dbg_ring_alloc_init(dhd_pub_t *dhd, uint16 ring_id,
+	char *ring_name, uint32 ring_sz, void *allocd_buf,
+	bool pull_inactive);
+void dhd_dbg_ring_dealloc_deinit(void **dbgring, dhd_pub_t *dhd);
+int dhd_dbg_ring_init(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring, uint16 id, uint8 *name,
+		uint32 ring_sz, void *allocd_buf, bool pull_inactive);
+void dhd_dbg_ring_deinit(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring);
+int dhd_dbg_ring_set_buf(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring, void *buf);
+#ifdef DHD_PKT_LOGGING_DBGRING
+int dhd_dbg_ring_update(void *dbg_ring, uint32 w_len);
+#endif /* DHD_PKT_LOGGING_DBGRING */
+int dhd_dbg_ring_push(dhd_dbg_ring_t *ring, dhd_dbg_ring_entry_t *hdr, void *data);
+int dhd_dbg_ring_pull(dhd_dbg_ring_t *ring, void *data, uint32 buf_len,
+		bool strip_hdr, int* num_entries);
+int dhd_dbg_ring_pull_single(dhd_dbg_ring_t *ring, void *data, uint32 buf_len,
+	bool strip_header);
+uint32 dhd_dbg_ring_get_pending_len(dhd_dbg_ring_t *ring);
+void dhd_dbg_ring_sched_pull(dhd_dbg_ring_t *ring, uint32 pending_len,
+		os_pullreq_t pull_fn, void *os_pvt, const int id);
+int dhd_dbg_ring_config(dhd_dbg_ring_t *ring, int log_level, uint32 threshold);
+void dhd_dbg_ring_start(dhd_dbg_ring_t *ring);
+#endif /* __DHD_DBG_RING_H__ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_debug.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_debug.c
@@ -0,0 +1,3685 @@
+/*
+ * DHD debugability support
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <typedefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_dbg.h>
+#include <dhd_dbg_ring.h>
+#include <dhd_debug.h>
+#include <dhd_mschdbg.h>
+#include <dhd_bus.h>
+
+#include <event_log.h>
+#include <event_trace.h>
+#include <msgtrace.h>
+#if defined(DBG_PKT_MON)
+#include <dhd_linux_priv.h>
+#include <dhd_linux_wq.h>
+#endif /* DBG_PKT_MON */
+#if defined(DHD_PKT_LOGGING) && defined(DHD_PKT_LOGGING_DBGRING)
+#include <dhd_pktlog.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
+#include <linux/sched/clock.h>
+#endif /* KENEL >=4.11 */
+#endif /* DHD_PKT_LOGGING && DHD_PKT_LOGGING_DBGRING */
+
+#if defined(DHD_EVENT_LOG_FILTER)
+#include <dhd_event_log_filter.h>
+#endif /* DHD_EVENT_LOG_FILTER */
+
+#ifdef WL_CFGVENDOR_CUST_ADVLOG
+void wl_cfgvendor_custom_advlog_roam_log(void *plog, uint32 armcycle);
+#endif /* WL_CFGVENDOR_CUST_ADVLOG */
+
+#if defined(NDIS)
+#if !defined(offsetof)
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif	/* !defined(offsetof) */
+
+#define container_of(ptr, type, member) \
+		(type *)((char *)(ptr) - offsetof(type, member))
+#endif /* NDIS */
+
+uint8 control_logtrace = CUSTOM_CONTROL_LOGTRACE;
+
+struct map_table {
+	uint16 fw_id;
+	uint16 host_id;
+	char *desc;
+};
+
+struct map_table event_map[] = {
+	{WLC_E_AUTH, WIFI_EVENT_AUTH_COMPLETE, "AUTH_COMPLETE"},
+	{WLC_E_ASSOC, WIFI_EVENT_ASSOC_COMPLETE, "ASSOC_COMPLETE"},
+	{TRACE_FW_AUTH_STARTED, WIFI_EVENT_FW_AUTH_STARTED, "AUTH STARTED"},
+	{TRACE_FW_ASSOC_STARTED, WIFI_EVENT_FW_ASSOC_STARTED, "ASSOC STARTED"},
+	{TRACE_FW_RE_ASSOC_STARTED, WIFI_EVENT_FW_RE_ASSOC_STARTED, "REASSOC STARTED"},
+	{TRACE_G_SCAN_STARTED, WIFI_EVENT_G_SCAN_STARTED, "GSCAN STARTED"},
+	{WLC_E_PFN_SCAN_COMPLETE, WIFI_EVENT_G_SCAN_COMPLETE, "GSCAN COMPLETE"},
+	{WLC_E_DISASSOC, WIFI_EVENT_DISASSOCIATION_REQUESTED, "DIASSOC REQUESTED"},
+	{WLC_E_REASSOC, WIFI_EVENT_RE_ASSOCIATION_REQUESTED, "REASSOC REQUESTED"},
+	{TRACE_ROAM_SCAN_STARTED, WIFI_EVENT_ROAM_REQUESTED, "ROAM REQUESTED"},
+	{WLC_E_BEACON_FRAME_RX, WIFI_EVENT_BEACON_RECEIVED, "BEACON Received"},
+	{TRACE_ROAM_SCAN_STARTED, WIFI_EVENT_ROAM_SCAN_STARTED, "ROAM SCAN STARTED"},
+	{TRACE_ROAM_SCAN_COMPLETE, WIFI_EVENT_ROAM_SCAN_COMPLETE, "ROAM SCAN COMPLETED"},
+	{TRACE_ROAM_AUTH_STARTED, WIFI_EVENT_ROAM_AUTH_STARTED, "ROAM AUTH STARTED"},
+	{WLC_E_AUTH, WIFI_EVENT_ROAM_AUTH_COMPLETE, "ROAM AUTH COMPLETED"},
+	{TRACE_FW_RE_ASSOC_STARTED, WIFI_EVENT_ROAM_ASSOC_STARTED, "ROAM ASSOC STARTED"},
+	{WLC_E_ASSOC, WIFI_EVENT_ROAM_ASSOC_COMPLETE, "ROAM ASSOC COMPLETED"},
+	{TRACE_ROAM_SCAN_COMPLETE, WIFI_EVENT_ROAM_SCAN_COMPLETE, "ROAM SCAN COMPLETED"},
+	{TRACE_BT_COEX_BT_SCO_START, WIFI_EVENT_BT_COEX_BT_SCO_START, "BT SCO START"},
+	{TRACE_BT_COEX_BT_SCO_STOP, WIFI_EVENT_BT_COEX_BT_SCO_STOP, "BT SCO STOP"},
+	{TRACE_BT_COEX_BT_SCAN_START, WIFI_EVENT_BT_COEX_BT_SCAN_START, "BT COEX SCAN START"},
+	{TRACE_BT_COEX_BT_SCAN_STOP, WIFI_EVENT_BT_COEX_BT_SCAN_STOP, "BT COEX SCAN STOP"},
+	{TRACE_BT_COEX_BT_HID_START, WIFI_EVENT_BT_COEX_BT_HID_START, "BT HID START"},
+	{TRACE_BT_COEX_BT_HID_STOP, WIFI_EVENT_BT_COEX_BT_HID_STOP, "BT HID STOP"},
+	{WLC_E_EAPOL_MSG, WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED, "FW EAPOL PKT RECEIVED"},
+	{TRACE_FW_EAPOL_FRAME_TRANSMIT_START, WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_START,
+	"FW EAPOL PKT TRANSMITED"},
+	{TRACE_FW_EAPOL_FRAME_TRANSMIT_STOP, WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP,
+	"FW EAPOL PKT TX STOPPED"},
+	{TRACE_BLOCK_ACK_NEGOTIATION_COMPLETE, WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE,
+	"BLOCK ACK NEGO COMPLETED"},
+};
+
+struct map_table event_tag_map[] = {
+	{TRACE_TAG_VENDOR_SPECIFIC, WIFI_TAG_VENDOR_SPECIFIC, "VENDOR SPECIFIC DATA"},
+	{TRACE_TAG_BSSID, WIFI_TAG_BSSID, "BSSID"},
+	{TRACE_TAG_ADDR, WIFI_TAG_ADDR, "ADDR_0"},
+	{TRACE_TAG_SSID, WIFI_TAG_SSID, "SSID"},
+	{TRACE_TAG_STATUS, WIFI_TAG_STATUS, "STATUS"},
+	{TRACE_TAG_CHANNEL_SPEC, WIFI_TAG_CHANNEL_SPEC, "CHANSPEC"},
+	{TRACE_TAG_WAKE_LOCK_EVENT, WIFI_TAG_WAKE_LOCK_EVENT, "WAKELOCK EVENT"},
+	{TRACE_TAG_ADDR1, WIFI_TAG_ADDR1, "ADDR_1"},
+	{TRACE_TAG_ADDR2, WIFI_TAG_ADDR2, "ADDR_2"},
+	{TRACE_TAG_ADDR3, WIFI_TAG_ADDR3, "ADDR_3"},
+	{TRACE_TAG_ADDR4, WIFI_TAG_ADDR4, "ADDR_4"},
+	{TRACE_TAG_TSF, WIFI_TAG_TSF, "TSF"},
+	{TRACE_TAG_IE, WIFI_TAG_IE, "802.11 IE"},
+	{TRACE_TAG_INTERFACE, WIFI_TAG_INTERFACE, "INTERFACE"},
+	{TRACE_TAG_REASON_CODE, WIFI_TAG_REASON_CODE, "REASON CODE"},
+	{TRACE_TAG_RATE_MBPS, WIFI_TAG_RATE_MBPS, "RATE"},
+};
+
+struct event_log_table {
+	int log_level;
+	uint16 tag;
+	uint8 set;
+	char *desc;
+};
+
+/* define log level per ring type */
+struct event_log_table fw_verbose_level_map[] = {
+	{1, EVENT_LOG_TAG_PCI_ERROR, EVENT_LOG_SET_BUS, "PCI_ERROR"},
+	{1, EVENT_LOG_TAG_PCI_WARN, EVENT_LOG_SET_PRSRV_BUS, "PCI_WARN"},
+	{1, EVENT_LOG_TAG_PCI_INFO, EVENT_LOG_SET_BUS, "PCI_INFO"},
+	{3, EVENT_LOG_TAG_PCI_DBG, EVENT_LOG_SET_BUS, "PCI_DEBUG"},
+	{2, EVENT_LOG_TAG_BEACON_LOG, EVENT_LOG_SET_PRSRV_CHATTY, "BEACON_LOG"},
+	{1, EVENT_LOG_TAG_WL_ASSOC_LOG, EVENT_LOG_SET_PRSRV, "ASSOC_LOG"},
+	{1, EVENT_LOG_TAG_WL_ROAM_LOG, EVENT_LOG_SET_PRSRV, "ROAM_LOG"},
+	{1, EVENT_LOG_TAG_TRACE_WL_INFO, EVENT_LOG_SET_WL, "WL INFO"},
+	{1, EVENT_LOG_TAG_TRACE_BTCOEX_INFO, EVENT_LOG_SET_WL, "BTCOEX INFO"},
+#ifdef DHD_RANDMAC_LOGGING
+	{1, EVENT_LOG_TAG_RANDMAC_ERR, EVENT_LOG_SET_PRSRV, "RANDMAC_ERR"},
+#endif /* DHD_RANDMAC_LOGGING */
+	{1, EVENT_LOG_TAG_SCAN_WARN, EVENT_LOG_SET_PRSRV_CHATTY, "SCAN_WARN"},
+	{2, EVENT_LOG_TAG_SCAN_ERROR, EVENT_LOG_SET_ERROR, "SCAN_ERROR"},
+	{1, EVENT_LOG_TAG_SCAN_TRACE_LOW, EVENT_LOG_SET_PRSRV, "SCAN_TRACE_LOW"},
+	{1, EVENT_LOG_TAG_SCAN_TRACE_HIGH, EVENT_LOG_SET_WL, "SCAN_TRACE_HIGH"},
+};
+
+/* reference tab table */
+uint ref_tag_tbl[EVENT_LOG_TAG_MAX + 1] = {0};
+
+typedef struct dhddbg_loglist_item {
+	dll_t list;
+	prcd_event_log_hdr_t prcd_log_hdr;
+} loglist_item_t;
+
+typedef struct dhbdbg_pending_item {
+	dll_t list;
+	dhd_dbg_ring_status_t ring_status;
+	dhd_dbg_ring_entry_t *ring_entry;
+} pending_item_t;
+
+/* trace log entry header user space processing */
+struct tracelog_header {
+	int magic_num;
+	int buf_size;
+	int seq_num;
+};
+#define TRACE_LOG_MAGIC_NUMBER 0xEAE47C06
+
+#ifdef DHD_PKT_LOGGING_DBGRING
+int
+dhd_dbg_update_to_ring(dhd_pub_t *dhdp, void *ring, uint32 w_len)
+{
+	return dhd_dbg_push_to_ring(dhdp, ((dhd_dbg_ring_t *)ring)->id, NULL, (void*)&w_len);
+}
+
+static uint32
+dhd_dbg_urgent_pull(dhd_pub_t *dhdp, dhd_dbg_ring_t *ring)
+{
+	uint32 pending_len = 0;
+	struct dhd_pktlog_ring *pktlog_ring;
+
+	if (ring->id != PACKET_LOG_RING_ID) {
+		return pending_len;
+	}
+
+	if (ring->stat.written_bytes > ring->stat.read_bytes) {
+		pending_len = ring->stat.written_bytes - ring->stat.read_bytes;
+	} else {
+		pending_len = 0;
+	}
+
+	pktlog_ring = dhdp->pktlog->pktlog_ring;
+	if (pktlog_ring->pktcount >= DHD_PACKET_LOG_RING_SUSPEND_THRESHOLD) {
+		dhd_pktlog_suspend(dhdp);
+	}
+
+	if (pending_len > ring->threshold) {
+		DHD_INFO(("%s: pending_len(%d) is exceeded threshold(%d), pktcount(%d)\n",
+			__FUNCTION__, pending_len, ring->threshold, pktlog_ring->pktcount));
+	}
+
+	return pending_len;
+}
+#endif /* DHD_PKT_LOGGING_DBGRING */
+
+#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
+int
+dhd_debug_dump_ring_push(dhd_pub_t *dhdp, int ring_id, uint32 len, void *data)
+{
+	dhd_dbg_ring_t *ring;
+	int ret = 0;
+	uint32 remain_len = 0;
+	char *cur_buf;
+	dhd_dbg_ring_entry_t msg_hdr;
+
+	if (!dhdp || !dhdp->dbg) {
+		return BCME_BADADDR;
+	}
+
+	if (!VALID_RING(ring_id)) {
+		DHD_ERROR(("%s : invalid ring_id : %d\n", __FUNCTION__, ring_id));
+		return BCME_RANGE;
+	}
+
+	ring = &dhdp->dbg->dbg_rings[ring_id];
+
+	remain_len = len;
+	cur_buf = data;
+
+	memset(&msg_hdr, 0, sizeof(msg_hdr));
+	while (remain_len > 0) {
+		msg_hdr.type = DBG_RING_ENTRY_DATA_TYPE;
+		msg_hdr.len = MIN(remain_len, DHD_DEBUG_DUMP_NETLINK_MAX);
+		ret = dhd_dbg_ring_push(ring, &msg_hdr, cur_buf);
+		if (ret == BCME_OK) {
+			cur_buf += msg_hdr.len;
+			remain_len -= msg_hdr.len;
+		}
+	}
+	return ret;
+}
+#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
+
+int
+dhd_dbg_push_to_ring(dhd_pub_t *dhdp, int ring_id, dhd_dbg_ring_entry_t *hdr, void *data)
+{
+	dhd_dbg_ring_t *ring;
+	int ret = 0;
+	uint32 pending_len = 0;
+
+	if (!dhdp || !dhdp->dbg) {
+		return BCME_BADADDR;
+	}
+
+	if (!VALID_RING(ring_id)) {
+		DHD_ERROR(("%s : invalid ring_id : %d\n", __FUNCTION__, ring_id));
+		return BCME_RANGE;
+	}
+
+	ring = &dhdp->dbg->dbg_rings[ring_id];
+
+#ifdef DHD_PKT_LOGGING_DBGRING
+	if (ring_id == PACKET_LOG_RING_ID) {
+		ret = dhd_dbg_ring_update(ring, *(uint32*)data);
+	} else
+#endif /* DHD_PKT_LOGGING_DBGRING */
+	{
+		ret = dhd_dbg_ring_push(ring, hdr, data);
+	}
+	if (ret != BCME_OK)
+		return ret;
+
+#ifdef DHD_PKT_LOGGING_DBGRING
+	pending_len = dhd_dbg_urgent_pull(dhdp, ring);
+#endif /* DHD_PKT_LOGGING_DBGRING */
+	if (pending_len == 0) {
+		pending_len = dhd_dbg_ring_get_pending_len(ring);
+	}
+	dhd_dbg_ring_sched_pull(ring, pending_len, dhdp->dbg->pullreq,
+		dhdp->dbg->private, ring->id);
+
+	return ret;
+}
+
+dhd_dbg_ring_t *
+dhd_dbg_get_ring_from_ring_id(dhd_pub_t *dhdp, int ring_id)
+{
+	if (!dhdp || !dhdp->dbg) {
+		return NULL;
+	}
+
+	if (!VALID_RING(ring_id)) {
+		DHD_ERROR(("%s : invalid ring_id : %d\n", __FUNCTION__, ring_id));
+		return NULL;
+	}
+
+	return &dhdp->dbg->dbg_rings[ring_id];
+}
+
+int
+dhd_dbg_pull_single_from_ring(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len,
+	bool strip_header)
+{
+	dhd_dbg_ring_t *ring;
+
+	if (!dhdp || !dhdp->dbg) {
+		return 0;
+	}
+
+	if (!VALID_RING(ring_id)) {
+		DHD_ERROR(("%s : invalid ring_id : %d\n", __FUNCTION__, ring_id));
+		return BCME_RANGE;
+	}
+
+	ring = &dhdp->dbg->dbg_rings[ring_id];
+
+	return dhd_dbg_ring_pull_single(ring, data, buf_len, strip_header);
+}
+
+#ifdef DHD_PKT_LOGGING_DBGRING
+extern int dhd_pktlog_dump_write(dhd_pub_t *dhdp, void *file,
+	const void *user_buf, uint32 *written_bytes);
+
+int
+dhd_dbg_pull_from_pktlog(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len)
+{
+	dhd_dbg_ring_entry_t *r_entry = NULL;
+	char *buf = NULL;
+	int ret = BCME_OK;
+	uint32 written_bytes = 0;
+
+	if (!dhdp || !dhdp->dbg) {
+		return 0;
+	}
+	if (!VALID_RING(ring_id)) {
+		DHD_DBGIF(("%s : invalid ring_id : %d\n", __FUNCTION__, ring_id));
+		return BCME_RANGE;
+	}
+	if (ring_id != PACKET_LOG_RING_ID) {
+		return BCME_UNSUPPORTED;
+	}
+
+	r_entry = (dhd_dbg_ring_entry_t *)data;
+	r_entry->len = buf_len - DBG_RING_ENTRY_SIZE;
+	written_bytes = (uint32)r_entry->len;
+	if (!written_bytes) {
+		return 0;
+	}
+
+	r_entry->type = DBG_RING_ENTRY_DATA_TYPE;
+	r_entry->flags = (DBG_RING_ENTRY_FLAGS_HAS_TIMESTAMP |
+		DBG_RING_ENTRY_FLAGS_HAS_BINARY);
+	r_entry->timestamp = local_clock();
+	r_entry->timestamp = DIV_U64_BY_U32(r_entry->timestamp, NSEC_PER_MSEC);
+	buf = (char*)data;
+
+	ret = dhd_pktlog_dump_write(dhdp, NULL, buf + DBG_RING_ENTRY_SIZE, &written_bytes);
+
+	if (ret != BCME_OK) {
+		DHD_DBGIF(("%s : pktlog_dump error\n", __FUNCTION__));
+		buf_len = 0;
+	} else {
+		r_entry->len = (uint16)written_bytes;
+		buf_len = r_entry->len + DBG_RING_ENTRY_SIZE;
+	}
+
+	return buf_len;
+}
+#endif /* DHD_PKT_LOGGING_DBGRING */
+
+int
+dhd_dbg_pull_from_ring(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len,
+		int *num_entries)
+{
+	dhd_dbg_ring_t *ring;
+
+	if (!dhdp || !dhdp->dbg)
+		return 0;
+	if (!VALID_RING(ring_id)) {
+		DHD_DBGIF(("%s : invalid ring_id : %d\n", __FUNCTION__, ring_id));
+		return BCME_RANGE;
+	}
+	ring = &dhdp->dbg->dbg_rings[ring_id];
+	return dhd_dbg_ring_pull(ring, data, buf_len, FALSE, num_entries);
+}
+
+static int
+dhd_dbg_msgtrace_seqchk(uint32 *prev, uint32 cur)
+{
+	/* normal case including wrap around */
+	if ((cur == 0 && *prev == 0xFFFFFFFF) || ((cur - *prev) == 1)) {
+		goto done;
+	} else if (cur == *prev) {
+		DHD_EVENT(("%s duplicate trace\n", __FUNCTION__));
+		return -1;
+	} else if (cur > *prev) {
+		DHD_EVENT(("%s lost %d packets\n", __FUNCTION__, cur - *prev));
+	} else {
+		DHD_EVENT(("%s seq out of order, dhd %d, dongle %d\n",
+			__FUNCTION__, *prev, cur));
+	}
+done:
+	*prev = cur;
+	return 0;
+}
+
+static void
+dhd_dbg_msgtrace_msg_parser(void *event_data)
+{
+	msgtrace_hdr_t *hdr;
+	char *data, *s;
+	static uint32 seqnum_prev = 0;
+
+	if (!event_data) {
+		DHD_ERROR(("%s: event_data is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	hdr = (msgtrace_hdr_t *)event_data;
+	data = (char *)event_data + MSGTRACE_HDRLEN;
+
+	/* There are 2 bytes available at the end of data */
+	data[ntoh16(hdr->len)] = '\0';
+
+	if (ntoh32(hdr->discarded_bytes) || ntoh32(hdr->discarded_printf)) {
+		DHD_DBGIF(("WLC_E_TRACE: [Discarded traces in dongle -->"
+			"discarded_bytes %d discarded_printf %d]\n",
+			ntoh32(hdr->discarded_bytes),
+			ntoh32(hdr->discarded_printf)));
+	}
+
+	if (dhd_dbg_msgtrace_seqchk(&seqnum_prev, ntoh32(hdr->seqnum)))
+		return;
+
+	/* Display the trace buffer. Advance from
+	 * \n to \n to avoid display big
+	 * printf (issue with Linux printk )
+	 */
+	while (*data != '\0' && (s = strstr(data, "\n")) != NULL) {
+		*s = '\0';
+		printf("[FWLOG] %s\n", data);
+		data = s+1;
+	}
+	if (*data)
+		printf("[FWLOG] %s", data);
+}
+#ifdef SHOW_LOGTRACE
+#define DATA_UNIT_FOR_LOG_CNT 4
+
+int
+replace_percent_p_to_x(char *fmt)
+{
+	int p_to_x_done = FALSE;
+
+	while (*fmt != '\0')
+	{
+		/* Skip characters will we see a % */
+		if (*fmt++ != '%')
+		{
+			continue;
+		}
+
+		/*
+		 * Skip any flags, field width and precision:
+		 *Flags: Followed by %
+		 * #, 0, -, ' ', +
+		 */
+		if (*fmt == '#')
+			fmt++;
+
+		if (*fmt == '0' || *fmt == '-' || *fmt == '+')
+			fmt++;
+
+		/*
+		 * Field width:
+		 * An optional decimal digit string (with non-zero first digit)
+		 * specifying a minimum field width
+		 */
+		while (*fmt && bcm_isdigit(*fmt))
+			fmt++;
+
+		/*
+		 * Precision:
+		 * An optional precision, in the form of a period ('.')  followed by an
+		 * optional decimal digit string.
+		 */
+		if (*fmt == '.')
+		{
+			fmt++;
+			while (*fmt && bcm_isdigit(*fmt)) fmt++;
+		}
+
+		/* If %p is seen, change it to %x */
+		if (*fmt == 'p')
+		{
+			*fmt = 'x';
+			p_to_x_done = TRUE;
+		}
+		if (*fmt)
+			fmt++;
+	}
+
+	return p_to_x_done;
+}
+
+/* To identify format of types %Ns where N >= 0 is a number */
+bool
+check_valid_string_format(char *curr_ptr)
+{
+	char *next_ptr;
+	if ((next_ptr = bcmstrstr(curr_ptr, "s")) != NULL) {
+		/* Default %s format */
+		if (curr_ptr == next_ptr) {
+			return TRUE;
+		}
+
+		/* Verify each charater between '%' and 's' is a valid number */
+		while (curr_ptr < next_ptr) {
+			if (bcm_isdigit(*curr_ptr) == FALSE) {
+				return FALSE;
+			}
+			curr_ptr++;
+		}
+
+		return TRUE;
+	} else {
+		return FALSE;
+	}
+}
+
+/* To identify format of non string format types */
+bool
+check_valid_non_string_format(char *curr_ptr)
+{
+	char *next_ptr;
+	char *next_fmt_stptr;
+	char valid_fmt_types[17] = {'d', 'i', 'x', 'X', 'c', 'p', 'u',
+			'f', 'F', 'e', 'E', 'g', 'G', 'o',
+			'a', 'A', 'n'};
+	int i;
+	bool valid = FALSE;
+
+	/* Check for next % in the fmt str */
+	next_fmt_stptr = bcmstrstr(curr_ptr, "%");
+
+	for (next_ptr = curr_ptr; *next_ptr != '\0'; next_ptr++) {
+		for (i = 0; i < (int)((sizeof(valid_fmt_types))/sizeof(valid_fmt_types[0])); i++) {
+			if (*next_ptr == valid_fmt_types[i]) {
+				/* Check whether format type found corresponds to current %
+				 * and not the next one, if exists.
+				 */
+				if ((next_fmt_stptr == NULL) ||
+						(next_fmt_stptr && (next_ptr < next_fmt_stptr))) {
+					/* Not validating for length/width fields in
+					 * format specifier.
+					 */
+					valid = TRUE;
+				}
+				goto done;
+			}
+		}
+	}
+
+done:
+	return valid;
+}
+
+#define MAX_NO_OF_ARG	16
+#define FMTSTR_SIZE	200
+#define ROMSTR_SIZE	268
+#define SIZE_LOC_STR	50
+#define LOG_PRINT_CNT_MAX	16u
+#define EL_MSEC_PER_SEC	1000
+#ifdef DHD_LOG_PRINT_RATE_LIMIT
+#ifdef DHD_DEBUG
+#undef MAX_LOG_PRINT_COUNT
+#define MAX_LOG_PRINT_COUNT   50000u
+#undef LOG_PRINT_THRESH
+#define LOG_PRINT_THRESH      (1u * USEC_PER_SEC)
+#else /* DHD_DEBUG */
+#ifndef MAX_LOG_PRINT_COUNT
+#define MAX_LOG_PRINT_COUNT   5000u
+#endif /* MAX_LOG_PRINT_COUNT */
+#ifndef LOG_PRINT_THRESH
+#define LOG_PRINT_THRESH      (1u * USEC_PER_SEC)
+#endif /* LOG_PRINT_THRESH */
+#endif /* DHD_DEBUG */
+#endif /* DHD_LOG_PRINT_RATE_LIMIT */
+#define EL_PARSE_VER	"V02"
+static uint64 verboselog_ts_saved = 0;
+
+bool
+dhd_dbg_process_event_log_hdr(event_log_hdr_t *log_hdr, prcd_event_log_hdr_t *prcd_log_hdr)
+{
+	event_log_extended_hdr_t *ext_log_hdr;
+	uint16 event_log_fmt_num;
+	uint8 event_log_hdr_type;
+	uint8 extended_fmtnum = 0;
+
+	/* Identify the type of event tag, payload type etc..  */
+	event_log_hdr_type = log_hdr->fmt_num & DHD_EVENT_LOG_HDR_MASK;
+	event_log_fmt_num = (log_hdr->fmt_num >> DHD_EVENT_LOG_FMT_NUM_OFFSET) &
+		DHD_EVENT_LOG_FMT_NUM_MASK;
+
+	switch (event_log_hdr_type) {
+		case DHD_OW_NB_EVENT_LOG_HDR:
+			prcd_log_hdr->ext_event_log_hdr = FALSE;
+			prcd_log_hdr->binary_payload = FALSE;
+			break;
+		case DHD_TW_NB_EVENT_LOG_HDR:
+			prcd_log_hdr->ext_event_log_hdr = TRUE;
+			prcd_log_hdr->binary_payload = FALSE;
+			break;
+		case DHD_BI_EVENT_LOG_HDR:
+			if (event_log_fmt_num == DHD_OW_BI_EVENT_FMT_NUM) {
+				prcd_log_hdr->ext_event_log_hdr = FALSE;
+				prcd_log_hdr->binary_payload = TRUE;
+			} else if (event_log_fmt_num == DHD_TW_BI_EVENT_FMT_NUM) {
+				prcd_log_hdr->ext_event_log_hdr = TRUE;
+				prcd_log_hdr->binary_payload = TRUE;
+			} else {
+				DHD_ERROR(("%s: invalid format number 0x%X\n",
+					__FUNCTION__, event_log_fmt_num));
+				return FALSE;
+			}
+			break;
+		case DHD_INVALID_EVENT_LOG_HDR:
+		default:
+			DHD_ERROR(("%s: invalid event log header type 0x%X\n",
+				__FUNCTION__, event_log_hdr_type));
+			return FALSE;
+	}
+
+	/* Parse extended and legacy event log headers and populate prcd_event_log_hdr_t */
+	if (prcd_log_hdr->ext_event_log_hdr) {
+		ext_log_hdr = (event_log_extended_hdr_t *)
+			((uint8 *)log_hdr - sizeof(event_log_hdr_t));
+		extended_fmtnum = (ext_log_hdr->extended_fmtnum & DHD_EXT_FMTNUM_MASK);
+	}
+	/* Parse extended event log tag */
+	if (prcd_log_hdr->ext_event_log_hdr) {
+		prcd_log_hdr->tag = ((ext_log_hdr->extended_tag &
+			DHD_TW_VALID_TAG_BITS_MASK) << DHD_TW_EVENT_LOG_TAG_OFFSET) | log_hdr->tag;
+	} else {
+		prcd_log_hdr->tag = log_hdr->tag;
+	}
+	/* Parse extended format number */
+	if ((event_log_hdr_type == DHD_TW_NB_EVENT_LOG_HDR) && (extended_fmtnum != 0)) {
+		prcd_log_hdr->fmt_num_raw = (extended_fmtnum << 16) | log_hdr->fmt_num;
+		prcd_log_hdr->fmt_num = (extended_fmtnum << 14) | event_log_fmt_num;
+
+	} else {
+		prcd_log_hdr->fmt_num_raw = log_hdr->fmt_num;
+		prcd_log_hdr->fmt_num = event_log_fmt_num;
+	}
+	prcd_log_hdr->count = log_hdr->count;
+
+	/* update arm cycle */
+	/*
+	 * For loegacy event tag :-
+	 * |payload........|Timestamp| Tag
+	 *
+	 * For extended event tag:-
+	 * |payload........|Timestamp|extended Tag| Tag.
+	 *
+	 */
+	prcd_log_hdr->armcycle = prcd_log_hdr->ext_event_log_hdr ?
+		*(uint32 *)(log_hdr - EVENT_TAG_TIMESTAMP_EXT_OFFSET) :
+		*(uint32 *)(log_hdr - EVENT_TAG_TIMESTAMP_OFFSET);
+
+	/* update event log data pointer address */
+	prcd_log_hdr->log_ptr =
+		(uint32 *)log_hdr - log_hdr->count - prcd_log_hdr->ext_event_log_hdr;
+
+	/* handle error cases above this */
+	return TRUE;
+}
+
+static void
+dhd_dbg_verboselog_handler(dhd_pub_t *dhdp, prcd_event_log_hdr_t *plog_hdr,
+		void *raw_event_ptr, uint32 logset, uint16 block, uint32* data)
+{
+	event_log_hdr_t *ts_hdr;
+	uint32 *log_ptr = plog_hdr->log_ptr;
+	char fmtstr_loc_buf[ROMSTR_SIZE] = { 0 };
+	uint32 rom_str_len = 0;
+	uint32 *ts_data;
+
+	if (!raw_event_ptr) {
+		return;
+	}
+
+	if (log_ptr < data) {
+		DHD_ERROR(("Invalid log pointer, logptr : %p data : %p \n", log_ptr, data));
+		return;
+	}
+
+	if (log_ptr > data) {
+		/* Get time stamp if it's updated */
+		ts_hdr = (event_log_hdr_t *)((char *)log_ptr - sizeof(event_log_hdr_t));
+		if (ts_hdr->tag == EVENT_LOG_TAG_TS) {
+			ts_data = (uint32 *)ts_hdr - ts_hdr->count;
+			if (ts_data >= data) {
+				verboselog_ts_saved = (uint64)ts_data[0];
+				DHD_MSGTRACE_LOG(("EVENT_LOG_TS[0x%08x]: SYS:%08x CPU:%08x\n",
+					ts_data[ts_hdr->count - 1], ts_data[0], ts_data[1]));
+			}
+		} else if (ts_hdr->tag == EVENT_LOG_TAG_ENHANCED_TS) {
+			ets_msg_v1_t *ets;
+			ets = (ets_msg_v1_t *)ts_hdr - ts_hdr->count;
+			if ((uint32*)ets >= data &&
+				ts_hdr->count >= (sizeof(ets_msg_v1_t) / sizeof(uint32)) &&
+				ets->version == ENHANCED_TS_MSG_VERSION_1) {
+				DHD_MSGTRACE_LOG(("EVENT_LOG_ENHANCED_TS_V1: "
+					"SYS:%08x CPU:%08x CPUFREQ:%u\n",
+					ets->timestamp, ets->cyclecount, ets->cpu_freq));
+			}
+		}
+	}
+
+	if (plog_hdr->tag == EVENT_LOG_TAG_ROM_PRINTF) {
+		rom_str_len = (plog_hdr->count - 1) * sizeof(uint32);
+		if (rom_str_len >= (ROMSTR_SIZE -1))
+			rom_str_len = ROMSTR_SIZE - 1;
+
+		/* copy all ascii data for ROM printf to local string */
+		memcpy(fmtstr_loc_buf, log_ptr, rom_str_len);
+		/* add end of line at last */
+		fmtstr_loc_buf[rom_str_len] = '\0';
+
+		DHD_MSGTRACE_LOG(("EVENT_LOG_ROM[0x%08x]: %s",
+				log_ptr[plog_hdr->count - 1], fmtstr_loc_buf));
+
+		if (!strlen(fmtstr_loc_buf)) {
+			DHD_ERROR(("%s fmt_str_loc_buf len can not be zero\n", __FUNCTION__));
+			return;
+		}
+
+		/* Add newline if missing */
+		if (fmtstr_loc_buf[strlen(fmtstr_loc_buf) - 1] != '\n')
+			DHD_MSGTRACE_LOG(("\n"));
+
+		return;
+	}
+
+	if (plog_hdr->tag == EVENT_LOG_TAG_MSCHPROFILE ||
+		plog_hdr->tag == EVENT_LOG_TAG_MSCHPROFILE_TLV) {
+		wl_mschdbg_verboselog_handler(dhdp, raw_event_ptr, plog_hdr, log_ptr);
+		return;
+	}
+
+	/* print the message out in a logprint  */
+	dhd_dbg_verboselog_printf(dhdp, plog_hdr, raw_event_ptr, log_ptr, logset, block);
+}
+
+void
+dhd_dbg_verboselog_printf(dhd_pub_t *dhdp, prcd_event_log_hdr_t *plog_hdr,
+	void *raw_event_ptr, uint32 *log_ptr, uint32 logset, uint16 block)
+{
+	dhd_event_log_t *raw_event = (dhd_event_log_t *)raw_event_ptr;
+	uint16 count;
+	int log_level, id;
+	char fmtstr_loc_buf[ROMSTR_SIZE] = { 0 };
+	char (*str_buf)[SIZE_LOC_STR] = NULL;
+	char *str_tmpptr = NULL;
+	uint32 addr = 0;
+	typedef union {
+		uint32 val;
+		char * addr;
+	} u_arg;
+	u_arg arg[MAX_NO_OF_ARG] = {{0}};
+	char *c_ptr = NULL;
+	struct bcmstrbuf b;
+#ifdef DHD_LOG_PRINT_RATE_LIMIT
+	static int log_print_count = 0;
+	static uint64 ts0 = 0;
+	uint64 ts1 = 0;
+#endif /* DHD_LOG_PRINT_RATE_LIMIT */
+
+	BCM_REFERENCE(arg);
+
+#ifdef DHD_LOG_PRINT_RATE_LIMIT
+	if (!ts0)
+		ts0 = OSL_SYSUPTIME_US();
+
+	ts1 = OSL_SYSUPTIME_US();
+
+	if (((ts1 - ts0) <= LOG_PRINT_THRESH) && (log_print_count >= MAX_LOG_PRINT_COUNT)) {
+		log_print_threshold = 1;
+		ts0 = 0;
+		log_print_count = 0;
+		DHD_ERROR(("%s: Log print water mark is reached,"
+			" console logs are dumped only to debug_dump file\n", __FUNCTION__));
+	} else if ((ts1 - ts0) > LOG_PRINT_THRESH) {
+		log_print_threshold = 0;
+		ts0 = 0;
+		log_print_count = 0;
+	}
+
+#endif /* DHD_LOG_PRINT_RATE_LIMIT */
+	/* print the message out in a logprint  */
+	if ((control_logtrace == LOGTRACE_RAW_FMT) || !(raw_event->fmts)) {
+		if (dhdp->dbg && dhdp->dbg->dbg_rings[FW_VERBOSE_RING_ID].state != RING_STOP) {
+			log_level = dhdp->dbg->dbg_rings[FW_VERBOSE_RING_ID].log_level;
+			for (id = 0; id < ARRAYSIZE(fw_verbose_level_map); id++) {
+				if ((fw_verbose_level_map[id].tag == plog_hdr->tag) &&
+					(fw_verbose_level_map[id].log_level > log_level))
+					return;
+			}
+		}
+		if (plog_hdr->binary_payload) {
+			DHD_ECNTR_LOG(("%d.%d EL:tag=%d len=%d fmt=0x%x",
+				(uint32)(log_ptr[plog_hdr->count - 1] / EL_MSEC_PER_SEC),
+				(uint32)(log_ptr[plog_hdr->count - 1] % EL_MSEC_PER_SEC),
+				plog_hdr->tag,
+				plog_hdr->count,
+				plog_hdr->fmt_num_raw));
+
+			for (count = 0; count < (plog_hdr->count - 1); count++) {
+				/* XXX: skip first line feed in case count 0 */
+				if (count && (count % LOG_PRINT_CNT_MAX == 0)) {
+					DHD_ECNTR_LOG(("\n\t%08x", log_ptr[count]));
+				} else {
+					DHD_ECNTR_LOG((" %08x", log_ptr[count]));
+				}
+			}
+			DHD_ECNTR_LOG(("\n"));
+		}
+		else {
+			bcm_binit(&b, fmtstr_loc_buf, FMTSTR_SIZE);
+			/* XXX: The 'hdr->count - 1' is dongle time */
+#ifndef OEM_ANDROID
+			bcm_bprintf(&b, "%06d.%03d EL: %d 0x%x",
+				(uint32)(log_ptr[plog_hdr->count - 1] / EL_MSEC_PER_SEC),
+				(uint32)(log_ptr[plog_hdr->count - 1] % EL_MSEC_PER_SEC),
+				plog_hdr->tag,
+				plog_hdr->fmt_num_raw);
+#else
+			bcm_bprintf(&b, "%06d.%03d EL:%s:%u:%u %d %d 0x%x",
+				(uint32)(log_ptr[plog_hdr->count - 1] / EL_MSEC_PER_SEC),
+				(uint32)(log_ptr[plog_hdr->count - 1] % EL_MSEC_PER_SEC),
+				EL_PARSE_VER, logset, block,
+				plog_hdr->tag,
+				plog_hdr->count,
+				plog_hdr->fmt_num_raw);
+#endif /* !OEM_ANDROID */
+			for (count = 0; count < (plog_hdr->count - 1); count++) {
+				bcm_bprintf(&b, " %x", log_ptr[count]);
+			}
+
+			/* ensure preserve fw logs go to debug_dump only in case of customer4 */
+			if (logset < dhdp->event_log_max_sets &&
+				((0x01ULL << logset) & dhdp->logset_prsrv_mask)) {
+				DHD_PRSRV_MEM(("%s\n", b.origbuf));
+			} else {
+				DHD_FWLOG(("%s\n", b.origbuf));
+#ifdef DHD_LOG_PRINT_RATE_LIMIT
+				log_print_count++;
+#endif /* DHD_LOG_PRINT_RATE_LIMIT */
+			}
+		}
+		return;
+	}
+
+	str_buf = MALLOCZ(dhdp->osh, (MAX_NO_OF_ARG * SIZE_LOC_STR));
+	if (!str_buf) {
+		DHD_ERROR(("%s: malloc failed str_buf\n", __FUNCTION__));
+		return;
+	}
+
+	if ((plog_hdr->fmt_num < raw_event->num_fmts) && (plog_hdr->binary_payload == FALSE)) {
+		if (plog_hdr->tag == EVENT_LOG_TAG_MSCHPROFILE) {
+			snprintf(fmtstr_loc_buf, FMTSTR_SIZE, "%s",
+				raw_event->fmts[plog_hdr->fmt_num]);
+			plog_hdr->count++;
+		} else {
+			snprintf(fmtstr_loc_buf, FMTSTR_SIZE, "CONSOLE_E:%u:%u %06d.%03d %s",
+				logset, block,
+				(uint32)(log_ptr[plog_hdr->count - 1] / EL_MSEC_PER_SEC),
+				(uint32)(log_ptr[plog_hdr->count - 1] % EL_MSEC_PER_SEC),
+				raw_event->fmts[plog_hdr->fmt_num]);
+		}
+		c_ptr = fmtstr_loc_buf;
+	} else {
+		/* for ecounters, don't print the error as it will flood */
+		if ((plog_hdr->fmt_num != DHD_OW_BI_EVENT_FMT_NUM) &&
+			(plog_hdr->fmt_num != DHD_TW_BI_EVENT_FMT_NUM)) {
+			DHD_ERROR(("%s: fmt number: 0x%x out of range\n",
+				__FUNCTION__, plog_hdr->fmt_num));
+		} else {
+			DHD_INFO(("%s: fmt number: 0x%x out of range\n",
+				__FUNCTION__, plog_hdr->fmt_num));
+		}
+
+		goto exit;
+	}
+
+	if (plog_hdr->binary_payload == FALSE && plog_hdr->count > MAX_NO_OF_ARG) {
+		DHD_INFO(("%s: plog_hdr->count(%d) out of range\n",
+			__FUNCTION__, plog_hdr->count));
+		goto exit;
+	}
+
+	/* print the format string which will be needed for debugging incorrect formats */
+	DHD_INFO(("%s: fmtstr_loc_buf = %s\n", __FUNCTION__, fmtstr_loc_buf));
+
+	/* Replace all %p to %x to handle 32 bit %p */
+	replace_percent_p_to_x(fmtstr_loc_buf);
+
+	for (count = 0; count < (plog_hdr->count - 1); count++) {
+		if (c_ptr != NULL)
+			if ((c_ptr = bcmstrstr(c_ptr, "%")) != NULL)
+				c_ptr++;
+
+		if (c_ptr != NULL) {
+			if (check_valid_string_format(c_ptr)) {
+				if ((raw_event->raw_sstr) &&
+					((log_ptr[count] > raw_event->rodata_start) &&
+					(log_ptr[count] < raw_event->rodata_end))) {
+					/* ram static string */
+					addr = log_ptr[count] - raw_event->rodata_start;
+					str_tmpptr = raw_event->raw_sstr + addr;
+					memcpy(str_buf[count], str_tmpptr,
+						SIZE_LOC_STR);
+					str_buf[count][SIZE_LOC_STR-1] = '\0';
+					arg[count].addr = str_buf[count];
+				} else if ((raw_event->rom_raw_sstr) &&
+						((log_ptr[count] >
+						raw_event->rom_rodata_start) &&
+						(log_ptr[count] <
+						raw_event->rom_rodata_end))) {
+					/* rom static string */
+					addr = log_ptr[count] - raw_event->rom_rodata_start;
+					str_tmpptr = raw_event->rom_raw_sstr + addr;
+					memcpy(str_buf[count], str_tmpptr,
+						SIZE_LOC_STR);
+					str_buf[count][SIZE_LOC_STR-1] = '\0';
+					arg[count].addr = str_buf[count];
+				} else {
+					/*
+					*  Dynamic string OR
+					* No data for static string.
+					* So store all string's address as string.
+					*/
+					snprintf(str_buf[count], SIZE_LOC_STR,
+						"(s)0x%x", log_ptr[count]);
+					arg[count].addr = str_buf[count];
+				}
+			} else if (check_valid_non_string_format(c_ptr)) {
+				/* Other than string format */
+				arg[count].val = log_ptr[count];
+			} else {
+				/* There is nothing copied after % or improper format specifier
+				 * after current %, because of not enough buffer size for complete
+				 * copy of original fmt string.
+				 * This is causing error mentioned below.
+				 * Error: "Please remove unsupported %\x00 in format string"
+				 * error(lib/vsprintf.c:1900 format_decode+0x3bc/0x470).
+				 * Refer to JIRA: SWWLAN-200629 for detailed info.
+				 *
+				 * Terminate the string at current .
+				 */
+				*(c_ptr - 1) = '\0';
+				break;
+			}
+		}
+	}
+
+	/* ensure preserve fw logs go to debug_dump only in case of customer4 */
+	if (logset < dhdp->event_log_max_sets &&
+			((0x01ULL << logset) & dhdp->logset_prsrv_mask)) {
+		if (dhd_msg_level & DHD_EVENT_VAL) {
+			if (dhd_msg_level & DHD_PRSRV_MEM_VAL)
+				printk(fmtstr_loc_buf, arg[0], arg[1], arg[2], arg[3],
+					arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10],
+					arg[11], arg[12], arg[13], arg[14], arg[15]);
+		}
+	} else {
+		if (dhd_msg_level & DHD_FWLOG_VAL) {
+			printk(fmtstr_loc_buf, arg[0], arg[1], arg[2], arg[3],
+				arg[4], arg[5], arg[6], arg[7], arg[8], arg[9], arg[10],
+				arg[11], arg[12], arg[13], arg[14], arg[15]);
+		}
+#ifdef DHD_LOG_PRINT_RATE_LIMIT
+		log_print_count++;
+#endif /* DHD_LOG_PRINT_RATE_LIMIT */
+	}
+
+exit:
+	MFREE(dhdp->osh, str_buf, (MAX_NO_OF_ARG * SIZE_LOC_STR));
+}
+
+#if defined(EWP_BCM_TRACE) || defined(EWP_RTT_LOGGING) || defined(EWP_ECNTRS_LOGGING)
+static int
+dhd_dbg_send_evtlog_to_ring(prcd_event_log_hdr_t *plog_hdr,
+	dhd_dbg_ring_entry_t *msg_hdr, dhd_dbg_ring_t *ring,
+	uint16 max_payload_len, uint8 *logbuf)
+{
+	event_log_hdr_t *log_hdr;
+	struct tracelog_header *logentry_header;
+	uint16 len_chk = 0;
+
+	BCM_REFERENCE(log_hdr);
+	BCM_REFERENCE(logentry_header);
+	/*
+	 * check msg hdr len before pushing.
+	 * FW msg_hdr.len includes length of event log hdr,
+	 * logentry header and payload.
+	 */
+	len_chk = (sizeof(*logentry_header) + sizeof(*log_hdr) +
+			max_payload_len);
+	/* account extended event log header(extended_event_log_hdr) */
+	if (plog_hdr->ext_event_log_hdr) {
+		len_chk += sizeof(*log_hdr);
+	}
+	if (msg_hdr->len > len_chk) {
+		DHD_ERROR(("%s: EVENT_LOG_VALIDATION_FAILS: "
+			"msg_hdr->len=%u, max allowed for %s=%u\n",
+			__FUNCTION__, msg_hdr->len, ring->name, len_chk));
+		return BCME_ERROR;
+	}
+	dhd_dbg_ring_push(ring, msg_hdr, logbuf);
+	return BCME_OK;
+}
+#endif /* EWP_BCM_TRACE || EWP_RTT_LOGGING || EWP_ECNTRS_LOGGING */
+
+void
+dhd_dbg_msgtrace_log_parser(dhd_pub_t *dhdp, void *event_data,
+	void *raw_event_ptr, uint datalen, bool msgtrace_hdr_present,
+	uint32 msgtrace_seqnum)
+{
+	msgtrace_hdr_t *hdr;
+	char *data, *tmpdata;
+	const uint32 log_hdr_len = sizeof(event_log_hdr_t);
+	uint32 log_pyld_len;
+	static uint32 seqnum_prev = 0;
+	event_log_hdr_t *log_hdr;
+	bool msg_processed = FALSE;
+	prcd_event_log_hdr_t prcd_log_hdr;
+	prcd_event_log_hdr_t *plog_hdr;
+	dll_t list_head, *cur;
+	loglist_item_t *log_item;
+	dhd_dbg_ring_entry_t msg_hdr;
+	char *logbuf;
+	struct tracelog_header *logentry_header;
+	uint ring_data_len = 0;
+	bool ecntr_pushed = FALSE;
+	bool rtt_pushed = FALSE;
+	bool bcm_trace_pushed = FALSE;
+	bool dll_inited = FALSE;
+	uint32 logset = 0;
+	uint16 block = 0;
+	bool event_log_max_sets_queried;
+	uint32 event_log_max_sets;
+	uint min_expected_len = 0;
+	uint16 len_chk = 0;
+	uint32 datalen_bak = datalen;
+	uint16 block_hdr_len;
+
+	BCM_REFERENCE(ecntr_pushed);
+	BCM_REFERENCE(rtt_pushed);
+	BCM_REFERENCE(bcm_trace_pushed);
+	BCM_REFERENCE(len_chk);
+
+	/* store event_logset_queried and event_log_max_sets in local variables
+	 * to avoid race conditions as they were set from different contexts(preinit)
+	 */
+	event_log_max_sets_queried = dhdp->event_log_max_sets_queried;
+	/* Make sure queried is read first with wmb and then max_sets,
+	 * as it is done in reverse order during preinit ioctls.
+	 */
+	OSL_SMP_WMB();
+	event_log_max_sets = dhdp->event_log_max_sets;
+
+	if (msgtrace_hdr_present)
+		min_expected_len = (MSGTRACE_HDRLEN + EVENT_LOG_BLOCK_LEN);
+	else
+		min_expected_len = EVENT_LOG_BLOCK_LEN;
+
+	/* log trace event consists of:
+	 * msgtrace header
+	 * event log block header
+	 * event log payload
+	 */
+	if (!event_data || (datalen <= min_expected_len)) {
+		DHD_ERROR(("%s: Not processing due to invalid event_data : %p or length : %d\n",
+			__FUNCTION__, event_data, datalen));
+		if (event_data && msgtrace_hdr_present) {
+			prhex("event_data dump", event_data, datalen);
+			tmpdata = (char *)event_data + MSGTRACE_HDRLEN;
+			if (tmpdata) {
+				DHD_ERROR(("EVENT_LOG_HDR[0x%x]: Set: 0x%08x length = %d\n",
+					ltoh16(*((uint16 *)(tmpdata+2))),
+					ltoh32(*((uint32 *)(tmpdata + 4))),
+					ltoh16(*((uint16 *)(tmpdata)))));
+			}
+		} else if (!event_data) {
+			DHD_ERROR(("%s: event_data is NULL, cannot dump prhex\n", __FUNCTION__));
+		}
+
+		return;
+	}
+
+	if (msgtrace_hdr_present) {
+		hdr = (msgtrace_hdr_t *)event_data;
+		data = (char *)event_data + MSGTRACE_HDRLEN;
+		datalen -= MSGTRACE_HDRLEN;
+		msgtrace_seqnum = ntoh32(hdr->seqnum);
+	} else {
+		data = (char *)event_data;
+	}
+
+	if (dhd_dbg_msgtrace_seqchk(&seqnum_prev, msgtrace_seqnum))
+		return;
+
+	/* Save the whole message to event log ring */
+	memset(&msg_hdr, 0, sizeof(dhd_dbg_ring_entry_t));
+	logbuf = VMALLOC(dhdp->osh, sizeof(*logentry_header) + datalen);
+	if (logbuf == NULL)
+		return;
+	logentry_header = (struct tracelog_header *)logbuf;
+	logentry_header->magic_num = TRACE_LOG_MAGIC_NUMBER;
+	logentry_header->buf_size = datalen;
+	logentry_header->seq_num = msgtrace_seqnum;
+	msg_hdr.type = DBG_RING_ENTRY_DATA_TYPE;
+
+	ring_data_len = datalen + sizeof(*logentry_header);
+
+	if ((sizeof(*logentry_header) + datalen) > PAYLOAD_MAX_LEN) {
+		DHD_ERROR(("%s:Payload len=%u exceeds max len\n", __FUNCTION__,
+			((uint)sizeof(*logentry_header) + datalen)));
+		goto exit;
+	}
+
+	msg_hdr.len = sizeof(*logentry_header) + datalen;
+	memcpy(logbuf + sizeof(*logentry_header), data, datalen);
+	DHD_DBGIF(("%s: datalen %d %d\n", __FUNCTION__, msg_hdr.len, datalen));
+
+	/* Print sequence number, originating set and length of received
+	 * event log buffer. Refer to event log buffer structure in
+	 * event_log.h
+	 */
+	DHD_MSGTRACE_LOG(("EVENT_LOG_HDR[0x%x]: Set: 0x%08x length = %d\n",
+		ltoh16(*((uint16 *)(data+2))), ltoh32(*((uint32 *)(data + 4))),
+		ltoh16(*((uint16 *)(data)))));
+
+	logset = ltoh32(*((uint32 *)(data + 4)));
+	block_hdr_len = ltoh16(*((uint16 *)(data)));
+
+	if (logset >= event_log_max_sets) {
+		DHD_ERROR(("%s logset: %d max: %d out of range queried: %d\n",
+			__FUNCTION__, logset, event_log_max_sets, event_log_max_sets_queried));
+#ifdef DHD_FW_COREDUMP
+		if (event_log_max_sets_queried && !dhd_memdump_is_scheduled(dhdp)) {
+			DHD_ERROR(("%s: collect socram for DUMP_TYPE_LOGSET_BEYOND_RANGE\n",
+				__FUNCTION__));
+			dhdp->memdump_type = DUMP_TYPE_LOGSET_BEYOND_RANGE;
+			dhd_bus_mem_dump(dhdp);
+		}
+#endif /* DHD_FW_COREDUMP */
+	}
+
+	block = ltoh16(*((uint16 *)(data + 2)));
+
+	data += EVENT_LOG_BLOCK_HDRLEN;
+	datalen -= EVENT_LOG_BLOCK_HDRLEN;
+
+	/* start parsing from the tail of packet
+	 * Sameple format of a meessage
+	 * 001d3c54 00000064 00000064 001d3c54 001dba08 035d6ce1 0c540639
+	 * 001d3c54 00000064 00000064 035d6d89 0c580439
+	 * 0x0c580439 -- 39 is tag, 04 is count, 580c is format number
+	 * all these uint32 values comes in reverse order as group as EL data
+	 * while decoding we can only parse from last to first
+	 * |<-                     datalen                     ->|
+	 * |----(payload and maybe more logs)----|event_log_hdr_t|
+	 * data                                  log_hdr
+	 */
+	dll_init(&list_head);
+	dll_inited = TRUE;
+
+	while (datalen > log_hdr_len) {
+		log_hdr = (event_log_hdr_t *)(data + datalen - log_hdr_len);
+		memset(&prcd_log_hdr, 0, sizeof(prcd_log_hdr));
+		if (!dhd_dbg_process_event_log_hdr(log_hdr, &prcd_log_hdr)) {
+			DHD_ERROR(("%s: Error while parsing event log header "
+				"set:%u block:%u block_hdr_len:%d "
+				"datalen:%u cur_datalen:%u msgtrace_hdr_present:%d\n",
+				__FUNCTION__, logset, block, block_hdr_len,
+				datalen_bak, datalen, msgtrace_hdr_present));
+			dhd_prhex("[event_data]", (char*)event_data, datalen_bak,
+				DHD_ERROR_VAL);
+			break;
+		}
+
+		/* skip zero padding at end of frame */
+		if (prcd_log_hdr.tag == EVENT_LOG_TAG_NULL) {
+			datalen -= log_hdr_len;
+			continue;
+		}
+		/* Check argument count (for non-ecounter events only),
+		 * any event log should contain at least
+		 * one argument (4 bytes) for arm cycle count and up to 16
+		 * arguments except EVENT_LOG_TAG_STATS which could use the
+		 * whole payload of 256 words
+		 */
+		if (prcd_log_hdr.count == 0) {
+			break;
+		}
+		/* Both tag_stats and proxd are binary payloads so skip
+		 * argument count check for these.
+		 */
+		if ((prcd_log_hdr.tag != EVENT_LOG_TAG_STATS) &&
+			(prcd_log_hdr.tag != EVENT_LOG_TAG_PROXD_SAMPLE_COLLECT) &&
+			(prcd_log_hdr.tag != EVENT_LOG_TAG_ROAM_ENHANCED_LOG) &&
+			(prcd_log_hdr.tag != EVENT_LOG_TAG_BCM_TRACE) &&
+			(prcd_log_hdr.count > MAX_NO_OF_ARG)) {
+			break;
+		}
+
+		log_pyld_len = (prcd_log_hdr.count + prcd_log_hdr.ext_event_log_hdr) *
+			DATA_UNIT_FOR_LOG_CNT;
+		/* log data should not cross the event data boundary */
+		if ((uint32)((char *)log_hdr - data) < log_pyld_len) {
+			break;
+		}
+		/* skip 4 bytes time stamp packet */
+		if (prcd_log_hdr.tag == EVENT_LOG_TAG_TS ||
+			prcd_log_hdr.tag == EVENT_LOG_TAG_ENHANCED_TS) {
+			if (datalen >= (log_pyld_len + log_hdr_len)) {
+				datalen -= (log_pyld_len + log_hdr_len);
+			} else {
+				DHD_ERROR(("%s: invalid length : %d < %d + %d\n",
+					__FUNCTION__, datalen, log_pyld_len, log_hdr_len));
+				datalen = 0;
+			}
+			continue;
+		}
+		if (!(log_item = VMALLOC(dhdp->osh, sizeof(*log_item)))) {
+			DHD_ERROR(("%s allocating log list item failed\n",
+				__FUNCTION__));
+			break;
+		}
+
+		log_item->prcd_log_hdr.tag = prcd_log_hdr.tag;
+		log_item->prcd_log_hdr.count = prcd_log_hdr.count;
+		log_item->prcd_log_hdr.fmt_num = prcd_log_hdr.fmt_num;
+		log_item->prcd_log_hdr.fmt_num_raw = prcd_log_hdr.fmt_num_raw;
+		log_item->prcd_log_hdr.armcycle = prcd_log_hdr.armcycle;
+		log_item->prcd_log_hdr.log_ptr = prcd_log_hdr.log_ptr;
+		log_item->prcd_log_hdr.payload_len = prcd_log_hdr.payload_len;
+		log_item->prcd_log_hdr.ext_event_log_hdr = prcd_log_hdr.ext_event_log_hdr;
+		log_item->prcd_log_hdr.binary_payload = prcd_log_hdr.binary_payload;
+
+		dll_insert(&log_item->list, &list_head);
+		if (datalen >= (log_pyld_len + log_hdr_len)) {
+			datalen -= (log_pyld_len + log_hdr_len);
+		} else {
+			DHD_ERROR(("%s: invalid length : %d < %d + %d\n",
+				__FUNCTION__, datalen, log_pyld_len, log_hdr_len));
+			datalen = 0;
+		}
+	}
+
+	while (!dll_empty(&list_head)) {
+		msg_processed = FALSE;
+		cur = dll_head_p(&list_head);
+
+		GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+		log_item = (loglist_item_t *)container_of(cur, loglist_item_t, list);
+		GCC_DIAGNOSTIC_POP();
+
+		plog_hdr = &log_item->prcd_log_hdr;
+#if defined(EWP_ECNTRS_LOGGING) && defined(DHD_LOG_DUMP)
+		/* Ecounter tag can be time_data or log_stats+binary paloaod */
+		if ((plog_hdr->tag == EVENT_LOG_TAG_ECOUNTERS_TIME_DATA) ||
+			((plog_hdr->tag == EVENT_LOG_TAG_STATS) &&
+			(plog_hdr->binary_payload))) {
+			if (!ecntr_pushed && dhd_log_dump_ecntr_enabled()) {
+				if (dhd_dbg_send_evtlog_to_ring(plog_hdr, &msg_hdr,
+					dhdp->ecntr_dbg_ring,
+					EVENT_LOG_MAX_BLOCK_SIZE, logbuf) != BCME_OK) {
+					goto exit;
+				}
+				ecntr_pushed = TRUE;
+			}
+		}
+#endif /* EWP_ECNTRS_LOGGING && DHD_LOG_DUMP */
+
+		if (plog_hdr->tag == EVENT_LOG_TAG_ROAM_ENHANCED_LOG) {
+			print_roam_enhanced_log(plog_hdr);
+			msg_processed = TRUE;
+		}
+#if defined(EWP_RTT_LOGGING) && defined(DHD_LOG_DUMP)
+		if ((plog_hdr->tag == EVENT_LOG_TAG_PROXD_SAMPLE_COLLECT) &&
+				plog_hdr->binary_payload) {
+			if (!rtt_pushed && dhd_log_dump_rtt_enabled()) {
+				if (dhd_dbg_send_evtlog_to_ring(plog_hdr, &msg_hdr,
+					dhdp->rtt_dbg_ring,
+					PAYLOAD_RTT_MAX_LEN, logbuf) != BCME_OK) {
+					goto exit;
+				}
+				rtt_pushed = TRUE;
+			}
+		}
+#endif /* EWP_RTT_LOGGING && DHD_LOG_DUMP */
+
+#ifdef EWP_BCM_TRACE
+		if ((logset == EVENT_LOG_SET_BCM_TRACE) && !bcm_trace_pushed &&
+			plog_hdr->binary_payload) {
+			if (dhd_dbg_send_evtlog_to_ring(plog_hdr, &msg_hdr,
+				dhdp->bcm_trace_dbg_ring,
+				PAYLOAD_BCM_TRACE_MAX_LEN, logbuf) != BCME_OK) {
+				goto exit;
+			}
+			bcm_trace_pushed = TRUE;
+		}
+#endif /* EWP_BCM_TRACE */
+
+#if defined(DHD_EVENT_LOG_FILTER)
+		if (plog_hdr->tag == EVENT_LOG_TAG_STATS) {
+			dhd_event_log_filter_event_handler(dhdp, plog_hdr, plog_hdr->log_ptr);
+		}
+#endif /* DHD_EVENT_LOG_FILTER */
+		if (!msg_processed) {
+			dhd_dbg_verboselog_handler(dhdp, plog_hdr, raw_event_ptr,
+				logset, block, (uint32 *)data);
+		}
+		dll_delete(cur);
+		VMFREE(dhdp->osh, log_item, sizeof(*log_item));
+
+	}
+	BCM_REFERENCE(log_hdr);
+exit:
+	while (dll_inited && (!dll_empty(&list_head))) {
+		cur = dll_head_p(&list_head);
+
+		GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+		log_item = (loglist_item_t *)container_of(cur, loglist_item_t, list);
+		GCC_DIAGNOSTIC_POP();
+
+		dll_delete(cur);
+		VMFREE(dhdp->osh, log_item, sizeof(*log_item));
+	}
+
+	VMFREE(dhdp->osh, logbuf, ring_data_len);
+}
+#else /* !SHOW_LOGTRACE */
+static INLINE void dhd_dbg_verboselog_handler(dhd_pub_t *dhdp,
+	prcd_event_log_hdr_t *plog_hdr, void *raw_event_ptr, uint32 logset, uint16 block,
+	uint32 *data) {};
+INLINE void dhd_dbg_msgtrace_log_parser(dhd_pub_t *dhdp,
+	void *event_data, void *raw_event_ptr, uint datalen,
+	bool msgtrace_hdr_present, uint32 msgtrace_seqnum) {};
+#endif /* SHOW_LOGTRACE */
+void
+dhd_dbg_trace_evnt_handler(dhd_pub_t *dhdp, void *event_data,
+		void *raw_event_ptr, uint datalen)
+{
+	msgtrace_hdr_t *hdr;
+
+	hdr = (msgtrace_hdr_t *)event_data;
+
+	if (hdr->version != MSGTRACE_VERSION) {
+		DHD_DBGIF(("%s unsupported MSGTRACE version, dhd %d, dongle %d\n",
+			__FUNCTION__, MSGTRACE_VERSION, hdr->version));
+		return;
+	}
+
+	if (hdr->trace_type == MSGTRACE_HDR_TYPE_MSG)
+		dhd_dbg_msgtrace_msg_parser(event_data);
+	else if (hdr->trace_type == MSGTRACE_HDR_TYPE_LOG)
+		dhd_dbg_msgtrace_log_parser(dhdp, event_data, raw_event_ptr, datalen, TRUE, 0);
+}
+
+/*
+ * dhd_dbg_set_event_log_tag : modify the state of an event log tag
+ */
+void
+dhd_dbg_set_event_log_tag(dhd_pub_t *dhdp, uint16 tag, uint8 set_num, uint8 is_set)
+{
+	wl_el_tag_params_t pars;
+	char *cmd = "event_log_tag_control";
+	char iovbuf[WLC_IOCTL_SMLEN] = { 0 };
+	int ret;
+
+	memset(&pars, 0, sizeof(pars));
+	pars.tag = tag;
+	pars.set = set_num;
+	pars.flags = (is_set) ? EVENT_LOG_TAG_FLAG_LOG : EVENT_LOG_TAG_FLAG_NONE;
+
+	if (!bcm_mkiovar(cmd, (char *)&pars, sizeof(pars), iovbuf, sizeof(iovbuf))) {
+		DHD_ERROR(("%s mkiovar failed\n", __FUNCTION__));
+		return;
+	}
+
+	ret = dhd_wl_ioctl_cmd(dhdp, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+	if (ret) {
+		DHD_ERROR(("%s set log tag iovar failed %d\n", __FUNCTION__, ret));
+	}
+}
+
+int
+dhd_dbg_set_configuration(dhd_pub_t *dhdp, int ring_id, int log_level, int flags, uint32 threshold)
+{
+	dhd_dbg_ring_t *ring;
+	uint8 set = 1;
+	int i, array_len = 0;
+	struct event_log_table *log_level_tbl = NULL;
+	if (!dhdp || !dhdp->dbg)
+		return BCME_BADADDR;
+
+	if (!VALID_RING(ring_id)) {
+		DHD_ERROR(("%s : invalid ring_id : %d\n", __FUNCTION__, ring_id));
+		return BCME_RANGE;
+	}
+
+	ring = &dhdp->dbg->dbg_rings[ring_id];
+	dhd_dbg_ring_config(ring, log_level, threshold);
+
+	if (log_level > 0)
+		set = TRUE;
+
+	if (ring->id == FW_VERBOSE_RING_ID) {
+		log_level_tbl = fw_verbose_level_map;
+		array_len = ARRAYSIZE(fw_verbose_level_map);
+	}
+
+	for (i = 0; i < array_len; i++) {
+		if (log_level == 0 || (log_level_tbl[i].log_level > log_level)) {
+			/* clear the reference per ring */
+			ref_tag_tbl[log_level_tbl[i].tag] &= ~(1 << ring_id);
+		} else {
+			/* set the reference per ring */
+			ref_tag_tbl[log_level_tbl[i].tag] |= (1 << ring_id);
+		}
+		set = (ref_tag_tbl[log_level_tbl[i].tag])? 1 : 0;
+		DHD_DBGIF(("%s TAG(%s) is %s for the ring(%s)\n", __FUNCTION__,
+			log_level_tbl[i].desc, (set)? "SET" : "CLEAR", ring->name));
+		dhd_dbg_set_event_log_tag(dhdp, log_level_tbl[i].tag,
+			log_level_tbl[i].set, set);
+	}
+	return BCME_OK;
+}
+
+int
+__dhd_dbg_get_ring_status(dhd_dbg_ring_t *ring, dhd_dbg_ring_status_t *get_ring_status)
+{
+	dhd_dbg_ring_status_t ring_status;
+	int ret = BCME_OK;
+
+	if (ring == NULL) {
+		return BCME_BADADDR;
+	}
+
+	bzero(&ring_status, sizeof(dhd_dbg_ring_status_t));
+	RING_STAT_TO_STATUS(ring, ring_status);
+	*get_ring_status = ring_status;
+
+	return ret;
+}
+
+/*
+* dhd_dbg_get_ring_status : get the ring status from the coresponding ring buffer
+* Return: An error code or 0 on success.
+*/
+
+int
+dhd_dbg_get_ring_status(dhd_pub_t *dhdp, int ring_id, dhd_dbg_ring_status_t *dbg_ring_status)
+{
+	int ret = BCME_OK;
+	int id = 0;
+	dhd_dbg_t *dbg;
+	dhd_dbg_ring_t *dbg_ring;
+	if (!dhdp || !dhdp->dbg)
+		return BCME_BADADDR;
+	dbg = dhdp->dbg;
+
+	for (id = DEBUG_RING_ID_INVALID + 1; id < DEBUG_RING_ID_MAX; id++) {
+		dbg_ring = &dbg->dbg_rings[id];
+		if (VALID_RING(dbg_ring->id) && (dbg_ring->id == ring_id)) {
+			__dhd_dbg_get_ring_status(dbg_ring, dbg_ring_status);
+			break;
+		}
+	}
+	if (!VALID_RING(id)) {
+		DHD_DBGIF(("%s : cannot find the ring_id : %d\n", __FUNCTION__, ring_id));
+		ret = BCME_NOTFOUND;
+	}
+	return ret;
+}
+
+#ifdef SHOW_LOGTRACE
+void
+dhd_dbg_read_ring_into_trace_buf(dhd_dbg_ring_t *ring, trace_buf_info_t *trace_buf_info)
+{
+	dhd_dbg_ring_status_t ring_status;
+	uint32 rlen = 0;
+
+	rlen = dhd_dbg_ring_pull_single(ring, trace_buf_info->buf, TRACE_LOG_BUF_MAX_SIZE, TRUE);
+
+	trace_buf_info->size = rlen;
+	trace_buf_info->availability = NEXT_BUF_NOT_AVAIL;
+	if (rlen == 0) {
+		trace_buf_info->availability = BUF_NOT_AVAILABLE;
+		return;
+	}
+
+	__dhd_dbg_get_ring_status(ring, &ring_status);
+
+	if (ring_status.written_bytes != ring_status.read_bytes) {
+		trace_buf_info->availability = NEXT_BUF_AVAIL;
+	}
+}
+#endif /* SHOW_LOGTRACE */
+
+/*
+* dhd_dbg_find_ring_id : return ring_id based on ring_name
+* Return: An invalid ring id for failure or valid ring id on success.
+*/
+
+int
+dhd_dbg_find_ring_id(dhd_pub_t *dhdp, char *ring_name)
+{
+	int id;
+	dhd_dbg_t *dbg;
+	dhd_dbg_ring_t *ring;
+
+	if (!dhdp || !dhdp->dbg)
+		return BCME_BADADDR;
+
+	dbg = dhdp->dbg;
+	for (id = DEBUG_RING_ID_INVALID + 1; id < DEBUG_RING_ID_MAX; id++) {
+		ring = &dbg->dbg_rings[id];
+		if (!strncmp((char *)ring->name, ring_name, sizeof(ring->name) - 1))
+			break;
+	}
+	return id;
+}
+
+/*
+* dhd_dbg_get_priv : get the private data of dhd dbugability module
+* Return : An NULL on failure or valid data address
+*/
+void *
+dhd_dbg_get_priv(dhd_pub_t *dhdp)
+{
+	if (!dhdp || !dhdp->dbg)
+		return NULL;
+	return dhdp->dbg->private;
+}
+
+/*
+* dhd_dbg_start : start and stop All of Ring buffers
+* Return: An error code or 0 on success.
+*/
+int
+dhd_dbg_start(dhd_pub_t *dhdp, bool start)
+{
+	int ret = BCME_OK;
+	int ring_id;
+	dhd_dbg_t *dbg;
+	dhd_dbg_ring_t *dbg_ring;
+	if (!dhdp)
+		return BCME_BADARG;
+	dbg = dhdp->dbg;
+
+	for (ring_id = DEBUG_RING_ID_INVALID + 1; ring_id < DEBUG_RING_ID_MAX; ring_id++) {
+		dbg_ring = &dbg->dbg_rings[ring_id];
+		if (!start) {
+			if (VALID_RING(dbg_ring->id)) {
+				dhd_dbg_ring_start(dbg_ring);
+			}
+		}
+	}
+	return ret;
+}
+
+/*
+ * dhd_dbg_send_urgent_evt: send the health check evt to Upper layer
+ *
+ * Return: An error code or 0 on success.
+ */
+
+int
+dhd_dbg_send_urgent_evt(dhd_pub_t *dhdp, const void *data, const uint32 len)
+{
+	dhd_dbg_t *dbg;
+	int ret = BCME_OK;
+	if (!dhdp || !dhdp->dbg)
+		return BCME_BADADDR;
+
+	dbg = dhdp->dbg;
+	if (dbg->urgent_notifier) {
+		dbg->urgent_notifier(dhdp, data, len);
+	}
+	return ret;
+}
+
+#if defined(DBG_PKT_MON) || defined(DHD_PKT_LOGGING)
+uint32
+__dhd_dbg_pkt_hash(uintptr_t pkt, uint32 pktid)
+{
+	uint32 __pkt;
+	uint32 __pktid;
+
+	__pkt = ((int)pkt) >= 0 ? (2 * pkt) : (-2 * pkt - 1);
+	__pktid = ((int)pktid) >= 0 ? (2 * pktid) : (-2 * pktid - 1);
+
+	return (__pkt >= __pktid ? (__pkt * __pkt + __pkt + __pktid) :
+			(__pkt + __pktid * __pktid));
+}
+
+#define __TIMESPEC64_TO_US(ts) \
+	(((ts).tv_sec * USEC_PER_SEC) + ((ts).tv_nsec / NSEC_PER_USEC))
+
+uint32
+__dhd_dbg_driver_ts_usec(void)
+{
+	struct osl_timespec ts;
+
+	osl_get_monotonic_boottime(&ts);
+	return ((uint32)(__TIMESPEC64_TO_US(ts)));
+}
+
+wifi_tx_packet_fate
+__dhd_dbg_map_tx_status_to_pkt_fate(uint16 status)
+{
+	wifi_tx_packet_fate pkt_fate;
+
+	switch (status) {
+		case WLFC_CTL_PKTFLAG_DISCARD:
+			pkt_fate = TX_PKT_FATE_ACKED;
+			break;
+		case WLFC_CTL_PKTFLAG_D11SUPPRESS:
+			/* intensional fall through */
+		case WLFC_CTL_PKTFLAG_WLSUPPRESS:
+			pkt_fate = TX_PKT_FATE_FW_QUEUED;
+			break;
+		case WLFC_CTL_PKTFLAG_TOSSED_BYWLC:
+			pkt_fate = TX_PKT_FATE_FW_DROP_INVALID;
+			break;
+		case WLFC_CTL_PKTFLAG_DISCARD_NOACK:
+			pkt_fate = TX_PKT_FATE_SENT;
+			break;
+		case WLFC_CTL_PKTFLAG_EXPIRED:
+			pkt_fate = TX_PKT_FATE_FW_DROP_EXPTIME;
+			break;
+		case WLFC_CTL_PKTFLAG_DROPPED:
+			pkt_fate = TX_PKT_FATE_DRV_DROP_OTHER;
+			break;
+		case WLFC_CTL_PKTFLAG_MKTFREE:
+			pkt_fate = TX_PKT_FATE_FW_PKT_FREE;
+			break;
+		case WLFC_CTL_PKTFLAG_MAX_SUP_RETR:
+			pkt_fate = TX_PKT_FATE_FW_MAX_SUP_RETR;
+			break;
+		case WLFC_CTL_PKTFLAG_FORCED_EXPIRED:
+			pkt_fate = TX_PKT_FATE_FW_FORCED_EXPIRED;
+			break;
+		default:
+			pkt_fate = TX_PKT_FATE_FW_DROP_OTHER;
+			break;
+	}
+
+	return pkt_fate;
+}
+#endif /* DBG_PKT_MON || DHD_PKT_LOGGING */
+
+#ifdef DBG_PKT_MON
+static int do_iovar_aml_enable(dhd_pub_t *dhdp, uint val);
+static void dhd_do_aml_disable(void *handle, void *event_info, u8 event);
+void dhd_schedule_aml_disable(dhd_pub_t *dhdp);
+
+static int
+do_iovar_aml_enable(dhd_pub_t *dhdp, uint val)
+{
+	wl_aml_iovar_t *iov_in;
+	wl_aml_iov_uint_data_t *subcmd;
+	int buf_size, alloc_len, ret = BCME_OK;
+
+	buf_size = OFFSETOF(wl_aml_iovar_t, data);
+	alloc_len = buf_size + sizeof(wl_aml_iov_uint_data_t);
+
+	iov_in = MALLOCZ(dhdp->osh, alloc_len);
+	if (!iov_in) {
+		DHD_ERROR(("%s: Error allocating %u bytes for aml enable\n",
+			__FUNCTION__, alloc_len));
+		return BCME_NOMEM;
+	}
+
+	iov_in->hdr.ver = htod16(WL_AML_IOV_VERSION_1_0);
+	iov_in->hdr.len = htod16(alloc_len);
+	iov_in->hdr.subcmd = htod16(WL_AML_SUBCMD_ENABLE);
+
+	if (val & ~(1u << WL_AML_ASSOC_ENABLE | 1u << WL_AML_ROAM_ENABLE)) {
+		ret = BCME_BADARG;
+		goto fail;
+	}
+
+	subcmd = (wl_aml_iov_uint_data_t *)iov_in->data;
+	subcmd->val = htod32(val);
+
+	ret = dhd_iovar(dhdp, 0, "aml", (char *)iov_in, alloc_len, NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s aml failed %d\n", __FUNCTION__, ret));
+		ret = BCME_ERROR;
+		goto fail;
+	}
+
+fail:
+	if (iov_in) {
+		MFREE(dhdp->osh, iov_in, alloc_len);
+	}
+
+	return ret;
+}
+
+static void dhd_do_aml_disable(void *handle, void *event_info, u8 event)
+{
+	dhd_info_t *dhd = (dhd_info_t *)handle;
+	dhd_pub_t *dhdp = NULL;
+	uint val = 0; /* Disabled */
+
+	dhdp = &dhd->pub;
+	if (!dhdp) {
+		DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	if (do_iovar_aml_enable(dhdp, val) == BCME_OK) {
+		dhdp->aml_enable = FALSE;
+	}
+
+	return;
+}
+
+void dhd_schedule_aml_disable(dhd_pub_t *dhdp)
+{
+	if (dhdp->dbg->pkt_mon.tx_pkt_state == PKT_MON_STOPPED &&
+			dhdp->dbg->pkt_mon.rx_pkt_state == PKT_MON_STOPPED) {
+		DHD_ERROR(("%s: scheduling aml iovar..\n", __FUNCTION__));
+		dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq, NULL,
+			DHD_WQ_WORK_AML_IOVAR, dhd_do_aml_disable, DHD_WQ_WORK_PRIORITY_HIGH);
+	}
+}
+
+static int
+__dhd_dbg_free_tx_pkts(dhd_pub_t *dhdp, dhd_dbg_tx_info_t *tx_pkts,
+	uint16 pkt_count)
+{
+	uint16 count;
+
+	count = 0;
+	while ((count < pkt_count) && tx_pkts) {
+		if (tx_pkts->info.pkt) {
+			PKTFREE(dhdp->osh, tx_pkts->info.pkt, TRUE);
+			/* Set NULL pointer after freeing for preventing dangling pointer problem */
+			tx_pkts->info.pkt = NULL;
+		}
+		tx_pkts++;
+		count++;
+	}
+
+	return BCME_OK;
+}
+
+static int
+__dhd_dbg_free_rx_pkts(dhd_pub_t *dhdp, dhd_dbg_rx_info_t *rx_pkts,
+	uint16 pkt_count)
+{
+	uint16 count;
+
+	count = 0;
+	while ((count < pkt_count) && rx_pkts) {
+		if (rx_pkts->info.pkt) {
+			PKTFREE(dhdp->osh, rx_pkts->info.pkt, TRUE);
+			/* Set NULL pointer after freeing for preventing dangling pointer problem */
+			rx_pkts->info.pkt = NULL;
+		}
+		rx_pkts++;
+		count++;
+	}
+
+	return BCME_OK;
+}
+
+void
+__dhd_dbg_dump_pkt_info(dhd_pub_t *dhdp, dhd_dbg_pkt_info_t *info)
+{
+	if (DHD_PKT_MON_DUMP_ON()) {
+		DHD_PKT_MON(("payload type   = %d\n", info->payload_type));
+		DHD_PKT_MON(("driver ts      = %u\n", info->driver_ts));
+		DHD_PKT_MON(("firmware ts    = %u\n", info->firmware_ts));
+		DHD_PKT_MON(("packet hash    = %u\n", info->pkt_hash));
+		DHD_PKT_MON(("packet length  = %zu\n", info->pkt_len));
+		DHD_PKT_MON(("packet address = %p\n", info->pkt));
+		DHD_PKT_MON(("packet data    = \n"));
+		if (DHD_PKT_MON_ON()) {
+			prhex(NULL, PKTDATA(dhdp->osh, info->pkt), info->pkt_len);
+		}
+	}
+}
+
+void
+__dhd_dbg_dump_tx_pkt_info(dhd_pub_t *dhdp, dhd_dbg_tx_info_t *tx_pkt,
+	uint16 count)
+{
+	if (DHD_PKT_MON_DUMP_ON()) {
+		DHD_PKT_MON(("\nTX (count: %d)\n", ++count));
+		DHD_PKT_MON(("packet fate    = %d\n", tx_pkt->fate));
+		__dhd_dbg_dump_pkt_info(dhdp, &tx_pkt->info);
+	}
+}
+
+void
+__dhd_dbg_dump_rx_pkt_info(dhd_pub_t *dhdp, dhd_dbg_rx_info_t *rx_pkt,
+	uint16 count)
+{
+	if (DHD_PKT_MON_DUMP_ON()) {
+		DHD_PKT_MON(("\nRX (count: %d)\n", ++count));
+		DHD_PKT_MON(("packet fate    = %d\n", rx_pkt->fate));
+		__dhd_dbg_dump_pkt_info(dhdp, &rx_pkt->info);
+	}
+}
+
+int
+dhd_dbg_attach_pkt_monitor(dhd_pub_t *dhdp,
+	dbg_mon_tx_pkts_t tx_pkt_mon,
+	dbg_mon_tx_status_t tx_status_mon,
+	dbg_mon_rx_pkts_t rx_pkt_mon)
+{
+
+	dhd_dbg_tx_report_t *tx_report = NULL;
+	dhd_dbg_rx_report_t *rx_report = NULL;
+	dhd_dbg_tx_info_t *tx_pkts = NULL;
+	dhd_dbg_rx_info_t *rx_pkts = NULL;
+	dhd_dbg_pkt_mon_state_t tx_pkt_state;
+	dhd_dbg_pkt_mon_state_t tx_status_state;
+	dhd_dbg_pkt_mon_state_t rx_pkt_state;
+	uint32 alloc_len;
+	int ret = BCME_OK;
+	unsigned long flags;
+
+	if (!dhdp || !dhdp->dbg) {
+		DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
+			dhdp, (dhdp ? dhdp->dbg : NULL)));
+		return -EINVAL;
+	}
+
+	DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
+	tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state;
+	tx_status_state = dhdp->dbg->pkt_mon.tx_pkt_state;
+	rx_pkt_state = dhdp->dbg->pkt_mon.rx_pkt_state;
+
+	if (PKT_MON_ATTACHED(tx_pkt_state) || PKT_MON_ATTACHED(tx_status_state) ||
+			PKT_MON_ATTACHED(rx_pkt_state)) {
+		DHD_PKT_MON(("%s(): packet monitor is already attached, "
+			"tx_pkt_state=%d, tx_status_state=%d, rx_pkt_state=%d\n",
+			__FUNCTION__, tx_pkt_state, tx_status_state, rx_pkt_state));
+		DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+		/* return success as the intention was to initialize packet monitor */
+		return BCME_OK;
+	}
+
+	/* allocate and initialize tx packet monitoring */
+	alloc_len = sizeof(*tx_report);
+	tx_report = (dhd_dbg_tx_report_t *)MALLOCZ(dhdp->osh, alloc_len);
+	if (unlikely(!tx_report)) {
+		DHD_ERROR(("%s(): could not allocate memory for - "
+			"dhd_dbg_tx_report_t\n", __FUNCTION__));
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	alloc_len = (sizeof(*tx_pkts) * MAX_FATE_LOG_LEN);
+	tx_pkts = (dhd_dbg_tx_info_t *)MALLOCZ(dhdp->osh, alloc_len);
+	if (unlikely(!tx_pkts)) {
+		DHD_ERROR(("%s(): could not allocate memory for - "
+			"dhd_dbg_tx_info_t\n", __FUNCTION__));
+		ret = -ENOMEM;
+		goto fail;
+	}
+	dhdp->dbg->pkt_mon.tx_report = tx_report;
+	dhdp->dbg->pkt_mon.tx_report->tx_pkts = tx_pkts;
+	dhdp->dbg->pkt_mon.tx_pkt_mon = tx_pkt_mon;
+	dhdp->dbg->pkt_mon.tx_status_mon = tx_status_mon;
+	dhdp->dbg->pkt_mon.tx_pkt_state = PKT_MON_ATTACHED;
+	dhdp->dbg->pkt_mon.tx_status_state = PKT_MON_ATTACHED;
+
+	/* allocate and initialze rx packet monitoring */
+	alloc_len = sizeof(*rx_report);
+	rx_report = (dhd_dbg_rx_report_t *)MALLOCZ(dhdp->osh, alloc_len);
+	if (unlikely(!rx_report)) {
+		DHD_ERROR(("%s(): could not allocate memory for - "
+			"dhd_dbg_rx_report_t\n", __FUNCTION__));
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	alloc_len = (sizeof(*rx_pkts) * MAX_FATE_LOG_LEN);
+	rx_pkts = (dhd_dbg_rx_info_t *)MALLOCZ(dhdp->osh, alloc_len);
+	if (unlikely(!rx_pkts)) {
+		DHD_ERROR(("%s(): could not allocate memory for - "
+			"dhd_dbg_rx_info_t\n", __FUNCTION__));
+		ret = -ENOMEM;
+		goto fail;
+	}
+	dhdp->dbg->pkt_mon.rx_report = rx_report;
+	dhdp->dbg->pkt_mon.rx_report->rx_pkts = rx_pkts;
+	dhdp->dbg->pkt_mon.rx_pkt_mon = rx_pkt_mon;
+	dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_ATTACHED;
+
+	DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+	DHD_PKT_MON(("%s(): packet monitor attach succeeded\n", __FUNCTION__));
+	return ret;
+
+fail:
+	/* tx packet monitoring */
+	if (tx_pkts) {
+		alloc_len = (sizeof(*tx_pkts) * MAX_FATE_LOG_LEN);
+		MFREE(dhdp->osh, tx_pkts, alloc_len);
+	}
+	if (tx_report) {
+		alloc_len = sizeof(*tx_report);
+		MFREE(dhdp->osh, tx_report, alloc_len);
+	}
+	dhdp->dbg->pkt_mon.tx_report = NULL;
+	dhdp->dbg->pkt_mon.tx_report->tx_pkts = NULL;
+	dhdp->dbg->pkt_mon.tx_pkt_mon = NULL;
+	dhdp->dbg->pkt_mon.tx_status_mon = NULL;
+	dhdp->dbg->pkt_mon.tx_pkt_state = PKT_MON_DETACHED;
+	dhdp->dbg->pkt_mon.tx_status_state = PKT_MON_DETACHED;
+
+	/* rx packet monitoring */
+	if (rx_pkts) {
+		alloc_len = (sizeof(*rx_pkts) * MAX_FATE_LOG_LEN);
+		MFREE(dhdp->osh, rx_pkts, alloc_len);
+	}
+	if (rx_report) {
+		alloc_len = sizeof(*rx_report);
+		MFREE(dhdp->osh, rx_report, alloc_len);
+	}
+	dhdp->dbg->pkt_mon.rx_report = NULL;
+	dhdp->dbg->pkt_mon.rx_report->rx_pkts = NULL;
+	dhdp->dbg->pkt_mon.rx_pkt_mon = NULL;
+	dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_DETACHED;
+
+	DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+	DHD_ERROR(("%s(): packet monitor attach failed\n", __FUNCTION__));
+	return ret;
+}
+
+int
+dhd_dbg_start_pkt_monitor(dhd_pub_t *dhdp)
+{
+	dhd_dbg_tx_report_t *tx_report;
+	dhd_dbg_rx_report_t *rx_report;
+	dhd_dbg_pkt_mon_state_t tx_pkt_state;
+	dhd_dbg_pkt_mon_state_t tx_status_state;
+	dhd_dbg_pkt_mon_state_t rx_pkt_state;
+	unsigned long flags;
+#ifdef DBG_PKT_MON_ROAM
+	/* assoc mgmt logging for assoc/roam is allowed by default */
+	uint32 enable = (1u << WL_AML_ROAM_ENABLE | 1u << WL_AML_ASSOC_ENABLE);
+#else
+	/* assoc mgmt logging for assoc is allowed by default */
+	uint32 enable = (1u << WL_AML_ASSOC_ENABLE);
+#endif
+
+	if (!dhdp || !dhdp->dbg) {
+		DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
+			dhdp, (dhdp ? dhdp->dbg : NULL)));
+		return -EINVAL;
+	}
+
+	if (do_iovar_aml_enable(dhdp, enable) == BCME_OK) {
+		dhdp->aml_enable = TRUE;
+	}
+
+	DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
+	tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state;
+	tx_status_state = dhdp->dbg->pkt_mon.tx_status_state;
+	rx_pkt_state = dhdp->dbg->pkt_mon.rx_pkt_state;
+
+	if (PKT_MON_DETACHED(tx_pkt_state) || PKT_MON_DETACHED(tx_status_state) ||
+			PKT_MON_DETACHED(rx_pkt_state)) {
+		DHD_PKT_MON(("%s(): packet monitor is not yet enabled, "
+			"tx_pkt_state=%d, tx_status_state=%d, rx_pkt_state=%d\n",
+			__FUNCTION__, tx_pkt_state, tx_status_state, rx_pkt_state));
+		DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+		return -EINVAL;
+	}
+
+	dhdp->dbg->pkt_mon.tx_pkt_state = PKT_MON_STARTING;
+	dhdp->dbg->pkt_mon.tx_status_state = PKT_MON_STARTING;
+	dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_STARTING;
+
+	tx_report = dhdp->dbg->pkt_mon.tx_report;
+	rx_report = dhdp->dbg->pkt_mon.rx_report;
+	if (!tx_report || !rx_report) {
+		DHD_PKT_MON(("%s(): tx_report=%p, rx_report=%p\n",
+			__FUNCTION__, tx_report, rx_report));
+		DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+		return -EINVAL;
+	}
+
+	tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state;
+	tx_status_state = dhdp->dbg->pkt_mon.tx_status_state;
+	rx_pkt_state = dhdp->dbg->pkt_mon.rx_pkt_state;
+
+	/* Safe to free packets as state pkt_state is STARTING */
+	__dhd_dbg_free_tx_pkts(dhdp, tx_report->tx_pkts, tx_report->pkt_pos);
+
+	__dhd_dbg_free_rx_pkts(dhdp, rx_report->rx_pkts, rx_report->pkt_pos);
+
+	/* reset array postion */
+	tx_report->pkt_pos = 0;
+	tx_report->status_pos = 0;
+	dhdp->dbg->pkt_mon.tx_pkt_state = PKT_MON_STARTED;
+	dhdp->dbg->pkt_mon.tx_status_state = PKT_MON_STARTED;
+
+	rx_report->pkt_pos = 0;
+	dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_STARTED;
+	DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+
+	DHD_PKT_MON(("%s(): packet monitor started\n", __FUNCTION__));
+	return BCME_OK;
+}
+
+int
+dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid, frame_type type, uint8 mgmt_acked)
+{
+	dhd_dbg_tx_report_t *tx_report;
+	dhd_dbg_tx_info_t *tx_pkts;
+	dhd_dbg_pkt_mon_state_t tx_pkt_state;
+	uint32 pkt_hash, driver_ts;
+	uint16 pkt_pos;
+	unsigned long flags;
+#if !defined(PCIE_FULL_DONGLE)
+	void *clone_pkt = NULL;
+#endif
+
+	if (!dhdp || !dhdp->dbg) {
+		DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
+			dhdp, (dhdp ? dhdp->dbg : NULL)));
+		return -EINVAL;
+	}
+
+	DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
+	tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state;
+	if (PKT_MON_STARTED(tx_pkt_state)) {
+		tx_report = dhdp->dbg->pkt_mon.tx_report;
+		pkt_pos = tx_report->pkt_pos;
+
+		if (!PKT_MON_PKT_FULL(pkt_pos)) {
+			tx_pkts = tx_report->tx_pkts;
+			pkt_hash = __dhd_dbg_pkt_hash((uintptr_t)pkt, pktid);
+			driver_ts = __dhd_dbg_driver_ts_usec();
+
+			if (type == FRAME_TYPE_80211_MGMT) {
+				tx_pkts[pkt_pos].info.pkt = pkt;
+				if (mgmt_acked) {
+					tx_pkts[pkt_pos].fate = TX_PKT_FATE_ACKED;
+				} else {
+					tx_pkts[pkt_pos].fate = TX_PKT_FATE_SENT;
+				}
+				tx_pkts[pkt_pos].info.pkt_len = PKTLEN(dhdp->osh, pkt);
+			} else {
+#if !defined(PCIE_FULL_DONGLE)
+				clone_pkt = PKTDUP(dhdp->osh, pkt);
+				skb_pull((struct sk_buff*)clone_pkt, SDIO_HLEN);
+				tx_pkts[pkt_pos].info.pkt = clone_pkt;
+				tx_pkts[pkt_pos].info.pkt_len =
+					PKTLEN(dhdp->osh, clone_pkt) - SDIO_HLEN;
+#else
+				tx_pkts[pkt_pos].info.pkt = PKTDUP(dhdp->osh, pkt);
+				tx_pkts[pkt_pos].info.pkt_len = PKTLEN(dhdp->osh, pkt);
+#endif
+				tx_pkts[pkt_pos].fate = TX_PKT_FATE_DRV_QUEUED;
+			}
+
+			tx_pkts[pkt_pos].info.pkt_hash = pkt_hash;
+			tx_pkts[pkt_pos].info.driver_ts = driver_ts;
+			tx_pkts[pkt_pos].info.firmware_ts = 0U;
+			tx_pkts[pkt_pos].info.payload_type = type;
+
+			tx_report->pkt_pos++;
+			/* TX mgmt packet is updated with the final fate reason,
+			 * so status_pos should be also increased.
+			 */
+			if (type == FRAME_TYPE_80211_MGMT) {
+				tx_report->status_pos++;
+			}
+		} else {
+			if (type == FRAME_TYPE_80211_MGMT) {
+				PKTFREE(dhdp->osh, pkt, TRUE);
+			}
+			dhdp->dbg->pkt_mon.tx_pkt_state = PKT_MON_STOPPED;
+			DHD_PKT_MON(("%s(): tx pkt logging stopped, reached "
+				"max limit\n", __FUNCTION__));
+			if (dhdp->aml_enable) {
+				dhd_schedule_aml_disable(dhdp);
+			}
+		}
+	}
+
+	DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+	return BCME_OK;
+}
+
+int
+dhd_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid,
+		uint16 status)
+{
+	dhd_dbg_tx_report_t *tx_report;
+	dhd_dbg_tx_info_t *tx_pkt;
+	dhd_dbg_pkt_mon_state_t tx_status_state;
+	wifi_tx_packet_fate pkt_fate;
+	uint32 pkt_hash, temp_hash;
+	uint16 pkt_pos, status_pos;
+	int16 count;
+	bool found = FALSE;
+	unsigned long flags;
+
+	if (!dhdp || !dhdp->dbg) {
+		DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
+			dhdp, (dhdp ? dhdp->dbg : NULL)));
+		return -EINVAL;
+	}
+
+	DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
+	tx_status_state = dhdp->dbg->pkt_mon.tx_status_state;
+	if (PKT_MON_STARTED(tx_status_state)) {
+		tx_report = dhdp->dbg->pkt_mon.tx_report;
+		pkt_pos = tx_report->pkt_pos;
+		status_pos = tx_report->status_pos;
+
+		if (!PKT_MON_STATUS_FULL(pkt_pos, status_pos)) {
+			pkt_hash = __dhd_dbg_pkt_hash((uintptr_t)pkt, pktid);
+			pkt_fate = __dhd_dbg_map_tx_status_to_pkt_fate(status);
+
+			/* best bet (in-order tx completion) */
+			count = status_pos;
+			tx_pkt = (((dhd_dbg_tx_info_t *)tx_report->tx_pkts) + status_pos);
+			while ((count < pkt_pos) && tx_pkt) {
+				temp_hash = tx_pkt->info.pkt_hash;
+				if (temp_hash == pkt_hash) {
+					tx_pkt->fate = pkt_fate;
+					tx_report->status_pos++;
+					found = TRUE;
+					break;
+				}
+				tx_pkt++;
+				count++;
+			}
+
+			/* search until beginning (handles out-of-order completion) */
+			if (!found) {
+				count = status_pos - 1;
+				tx_pkt = (((dhd_dbg_tx_info_t *)tx_report->tx_pkts) + count);
+				while ((count >= 0) && tx_pkt) {
+					temp_hash = tx_pkt->info.pkt_hash;
+					if (temp_hash == pkt_hash) {
+						tx_pkt->fate = pkt_fate;
+						tx_report->status_pos++;
+						found = TRUE;
+						break;
+					}
+					tx_pkt--;
+					count--;
+				}
+
+				if (!found) {
+					/* still couldn't match tx_status */
+					DHD_INFO(("%s(): couldn't match tx_status, pkt_pos=%u, "
+						"status_pos=%u, pkt_fate=%u\n", __FUNCTION__,
+						pkt_pos, status_pos, pkt_fate));
+				}
+			}
+		} else {
+			dhdp->dbg->pkt_mon.tx_status_state = PKT_MON_STOPPED;
+			DHD_PKT_MON(("%s(): tx_status logging stopped, reached "
+				"max limit\n", __FUNCTION__));
+		}
+	}
+
+	DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+	return BCME_OK;
+}
+
+int
+dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt, frame_type type)
+{
+	dhd_dbg_rx_report_t *rx_report;
+	dhd_dbg_rx_info_t *rx_pkts;
+	dhd_dbg_pkt_mon_state_t rx_pkt_state;
+	uint32 driver_ts;
+	uint16 pkt_pos;
+	unsigned long flags;
+
+	if (!dhdp || !dhdp->dbg) {
+		DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
+			dhdp, (dhdp ? dhdp->dbg : NULL)));
+		return -EINVAL;
+	}
+
+	DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
+	rx_pkt_state = dhdp->dbg->pkt_mon.rx_pkt_state;
+	if (PKT_MON_STARTED(rx_pkt_state)) {
+		rx_report = dhdp->dbg->pkt_mon.rx_report;
+		pkt_pos = rx_report->pkt_pos;
+
+		if (!PKT_MON_PKT_FULL(pkt_pos)) {
+			rx_pkts = rx_report->rx_pkts;
+			driver_ts = __dhd_dbg_driver_ts_usec();
+
+			if (type == FRAME_TYPE_80211_MGMT) {
+				rx_pkts[pkt_pos].info.pkt = pkt;
+			} else {
+				rx_pkts[pkt_pos].info.pkt = PKTDUP(dhdp->osh, pkt);
+			}
+			rx_pkts[pkt_pos].info.pkt_len = PKTLEN(dhdp->osh, pkt);
+			rx_pkts[pkt_pos].info.pkt_hash = 0U;
+			rx_pkts[pkt_pos].info.driver_ts = driver_ts;
+			rx_pkts[pkt_pos].info.firmware_ts = 0U;
+			rx_pkts[pkt_pos].info.payload_type = type;
+			rx_pkts[pkt_pos].fate = RX_PKT_FATE_SUCCESS;
+
+			rx_report->pkt_pos++;
+		} else {
+			if (type == FRAME_TYPE_80211_MGMT) {
+				PKTFREE(dhdp->osh, pkt, TRUE);
+			}
+			dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_STOPPED;
+			DHD_PKT_MON(("%s(): rx pkt logging stopped, reached "
+					"max limit\n", __FUNCTION__));
+			if (dhdp->aml_enable) {
+				dhd_schedule_aml_disable(dhdp);
+			}
+		}
+	}
+
+	DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+	return BCME_OK;
+}
+
+int
+dhd_dbg_stop_pkt_monitor(dhd_pub_t *dhdp)
+{
+	dhd_dbg_pkt_mon_state_t tx_pkt_state;
+	dhd_dbg_pkt_mon_state_t tx_status_state;
+	dhd_dbg_pkt_mon_state_t rx_pkt_state;
+	unsigned long flags;
+
+	if (!dhdp || !dhdp->dbg) {
+		DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
+			dhdp, (dhdp ? dhdp->dbg : NULL)));
+		return -EINVAL;
+	}
+
+	DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
+	tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state;
+	tx_status_state = dhdp->dbg->pkt_mon.tx_status_state;
+	rx_pkt_state = dhdp->dbg->pkt_mon.rx_pkt_state;
+
+	if (PKT_MON_DETACHED(tx_pkt_state) || PKT_MON_DETACHED(tx_status_state) ||
+			PKT_MON_DETACHED(rx_pkt_state)) {
+		DHD_PKT_MON(("%s(): packet monitor is not yet enabled, "
+			"tx_pkt_state=%d, tx_status_state=%d, rx_pkt_state=%d\n",
+			__FUNCTION__, tx_pkt_state, tx_status_state, rx_pkt_state));
+		DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+		return -EINVAL;
+	}
+	dhdp->dbg->pkt_mon.tx_pkt_state = PKT_MON_STOPPED;
+	dhdp->dbg->pkt_mon.tx_status_state = PKT_MON_STOPPED;
+	dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_STOPPED;
+	DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+
+	DHD_PKT_MON(("%s(): packet monitor stopped\n", __FUNCTION__));
+	return BCME_OK;
+}
+
+#define __COPY_TO_USER(to, from, n) \
+	do { \
+		int __ret; \
+		__ret = copy_to_user((void __user *)(to), (void *)(from), \
+				(unsigned long)(n)); \
+		if (unlikely(__ret)) { \
+			DHD_ERROR(("%s():%d: copy_to_user failed, ret=%d\n", \
+				__FUNCTION__, __LINE__, __ret)); \
+			return __ret; \
+		} \
+	} while (0);
+
+static wifi_tx_packet_fate
+__dhd_dbg_convert_fate(wifi_tx_packet_fate fate)
+{
+	wifi_tx_packet_fate new_fate = fate;
+
+	 /* To prevent SIG-ABORT, packet_fate > TX_PKT_FATE_DRV_DROP_OTHER */
+	if (fate > TX_PKT_FATE_DRV_DROP_OTHER) {
+		new_fate = TX_PKT_FATE_FW_DROP_OTHER;
+	}
+
+	return new_fate;
+}
+
+int
+dhd_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
+		uint16 req_count, uint16 *resp_count)
+{
+	dhd_dbg_tx_report_t *tx_report;
+	dhd_dbg_tx_info_t *tx_pkt, *ori_tx_pkt;
+	wifi_tx_report_t *ptr;
+	compat_wifi_tx_report_t *cptr;
+	dhd_dbg_pkt_mon_state_t tx_pkt_state;
+	dhd_dbg_pkt_mon_state_t tx_status_state;
+	uint16 pkt_count, count;
+	unsigned long flags;
+	dhd_dbg_tx_info_t *tmp_tx_pkt = NULL;
+	uint32 alloc_len, i, ret;
+
+	BCM_REFERENCE(ptr);
+	BCM_REFERENCE(cptr);
+
+	if (!dhdp || !dhdp->dbg) {
+		DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
+			dhdp, (dhdp ? dhdp->dbg : NULL)));
+		return -EINVAL;
+	}
+
+	DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
+	tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state;
+	tx_status_state = dhdp->dbg->pkt_mon.tx_status_state;
+	if (!PKT_MON_ATTACHED(tx_pkt_state) ||
+			!PKT_MON_ATTACHED(tx_status_state)) {
+		DHD_PKT_MON(("%s(): packet monitor is not yet enabled, "
+			"tx_pkt_state=%d, tx_status_state=%d\n", __FUNCTION__,
+			tx_pkt_state, tx_status_state));
+		DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+		return -EINVAL;
+	}
+
+	count = 0;
+	tx_report = dhdp->dbg->pkt_mon.tx_report;
+	ori_tx_pkt = tx_report->tx_pkts;
+	pkt_count = MIN(req_count, tx_report->status_pos);
+
+	alloc_len = (sizeof(*tmp_tx_pkt) * pkt_count);
+	tmp_tx_pkt = (dhd_dbg_tx_info_t *)MALLOCZ(dhdp->osh, alloc_len);
+	if (unlikely(!tmp_tx_pkt)) {
+		DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+		DHD_ERROR(("%s: failed to allocate tmp_tx_pkt", __FUNCTION__));
+		return -ENOMEM;
+	}
+	if ((ret = memcpy_s(tmp_tx_pkt, alloc_len, ori_tx_pkt, alloc_len))) {
+		DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+		DHD_ERROR(("%s: failed to copy tmp_tx_pkt ret:%d", __FUNCTION__, ret));
+		return -EINVAL;
+	}
+	for (i = 0; i < pkt_count; i++) {
+		tmp_tx_pkt[i].info.pkt = skb_copy((struct sk_buff*)ori_tx_pkt[i].info.pkt,
+			GFP_ATOMIC);
+		if (!tmp_tx_pkt[i].info.pkt) {
+			DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+			DHD_ERROR(("%s: failed to copy skb", __FUNCTION__));
+			return -ENOMEM;
+		}
+	}
+	tx_pkt = tmp_tx_pkt;
+	DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+
+#ifdef CONFIG_COMPAT
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0))
+	if (in_compat_syscall())
+#else
+	if (is_compat_task())
+#endif /* LINUX_VER >= 4.6 */
+	{
+		cptr = (compat_wifi_tx_report_t *)user_buf;
+		while ((count < pkt_count) && tx_pkt && cptr) {
+			compat_wifi_tx_report_t *comp_ptr = compat_ptr((uintptr_t) cptr);
+			compat_dhd_dbg_pkt_info_t compat_tx_pkt;
+			__dhd_dbg_dump_tx_pkt_info(dhdp, tx_pkt, count);
+			/* fate convert asscording to wifi_logger.h */
+			{
+				wifi_tx_packet_fate new_fate = tx_pkt->fate;
+				new_fate = __dhd_dbg_convert_fate(new_fate);
+				__COPY_TO_USER(&comp_ptr->fate, &new_fate, sizeof(new_fate));
+			}
+
+			compat_tx_pkt.payload_type = tx_pkt->info.payload_type;
+			compat_tx_pkt.pkt_len = tx_pkt->info.pkt_len;
+			compat_tx_pkt.driver_ts = tx_pkt->info.driver_ts;
+			compat_tx_pkt.firmware_ts = tx_pkt->info.firmware_ts;
+			compat_tx_pkt.pkt_hash = tx_pkt->info.pkt_hash;
+			__COPY_TO_USER(&comp_ptr->frame_inf.payload_type,
+				&compat_tx_pkt.payload_type,
+				OFFSETOF(compat_dhd_dbg_pkt_info_t, pkt_hash));
+			__COPY_TO_USER(comp_ptr->frame_inf.frame_content.ethernet_ii,
+				PKTDATA(dhdp->osh, tx_pkt->info.pkt), tx_pkt->info.pkt_len);
+
+			cptr++;
+			tx_pkt++;
+			count++;
+		}
+	} else
+#endif /* CONFIG_COMPAT */
+	{
+		ptr = (wifi_tx_report_t *)user_buf;
+		while ((count < pkt_count) && tx_pkt && ptr) {
+			__dhd_dbg_dump_tx_pkt_info(dhdp, tx_pkt, count);
+			/* fate convert asscording to wifi_logger.h */
+			{
+				wifi_tx_packet_fate new_fate = tx_pkt->fate;
+				new_fate = __dhd_dbg_convert_fate(new_fate);
+				__COPY_TO_USER(&ptr->fate, &new_fate, sizeof(new_fate));
+			}
+			__COPY_TO_USER(&ptr->frame_inf.payload_type,
+				&tx_pkt->info.payload_type,
+				OFFSETOF(dhd_dbg_pkt_info_t, pkt_hash));
+			__COPY_TO_USER(ptr->frame_inf.frame_content.ethernet_ii,
+				PKTDATA(dhdp->osh, tx_pkt->info.pkt), tx_pkt->info.pkt_len);
+
+			ptr++;
+			tx_pkt++;
+			count++;
+		}
+	}
+	*resp_count = pkt_count;
+
+	if (!pkt_count) {
+		DHD_ERROR(("%s(): no tx_status in tx completion messages, "
+			"make sure that 'd11status' is enabled in firmware, "
+			"status_pos=%u\n", __FUNCTION__, pkt_count));
+	}
+
+	for (i = 0; i < pkt_count; i++) {
+		PKTFREE(dhdp->osh, tmp_tx_pkt[i].info.pkt, TRUE);
+	}
+	MFREE(dhdp->osh, tmp_tx_pkt, alloc_len);
+
+	return BCME_OK;
+}
+
+int
+dhd_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
+		uint16 req_count, uint16 *resp_count)
+{
+	dhd_dbg_rx_report_t *rx_report;
+	dhd_dbg_rx_info_t *rx_pkt, *ori_rx_pkt;
+	wifi_rx_report_t *ptr;
+	compat_wifi_rx_report_t *cptr;
+	dhd_dbg_pkt_mon_state_t rx_pkt_state;
+	uint16 pkt_count, count;
+	unsigned long flags;
+	dhd_dbg_rx_info_t *tmp_rx_pkt = NULL;
+	uint32 alloc_len, i, ret = BCME_OK;
+
+	BCM_REFERENCE(ptr);
+	BCM_REFERENCE(cptr);
+
+	if (!dhdp || !dhdp->dbg) {
+		DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
+			dhdp, (dhdp ? dhdp->dbg : NULL)));
+		return -EINVAL;
+	}
+
+	DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
+	rx_pkt_state = dhdp->dbg->pkt_mon.rx_pkt_state;
+	if (!PKT_MON_ATTACHED(rx_pkt_state)) {
+		DHD_PKT_MON(("%s(): packet fetch is not allowed , "
+			"rx_pkt_state=%d\n", __FUNCTION__, rx_pkt_state));
+		DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+		return -EINVAL;
+	}
+
+	count = 0;
+	rx_report = dhdp->dbg->pkt_mon.rx_report;
+	ori_rx_pkt = rx_report->rx_pkts;
+	pkt_count = MIN(req_count, rx_report->pkt_pos);
+
+	alloc_len = (sizeof(*tmp_rx_pkt) * pkt_count);
+	tmp_rx_pkt = (dhd_dbg_rx_info_t *)MALLOCZ(dhdp->osh, alloc_len);
+	if (unlikely(!tmp_rx_pkt)) {
+		DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+		DHD_ERROR(("%s: failed to allocate tmp_rx_pkt", __FUNCTION__));
+		return -ENOMEM;
+	}
+	if ((ret = memcpy_s(tmp_rx_pkt, alloc_len, ori_rx_pkt, alloc_len))) {
+		DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+		DHD_ERROR(("%s: failed to copy tmp_rx_pkt ret:%d", __FUNCTION__, ret));
+		ret = -EINVAL;
+		goto exit;
+	}
+	for (i = 0; i < pkt_count; i++) {
+		tmp_rx_pkt[i].info.pkt = skb_copy((struct sk_buff*)ori_rx_pkt[i].info.pkt,
+			GFP_ATOMIC);
+		if (!tmp_rx_pkt[i].info.pkt) {
+			DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+			DHD_ERROR(("%s: failed to copy skb", __FUNCTION__));
+			ret = -ENOMEM;
+			goto exit;
+		}
+	}
+	rx_pkt = tmp_rx_pkt;
+	DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+
+#ifdef CONFIG_COMPAT
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0))
+	if (in_compat_syscall())
+#else
+	if (is_compat_task())
+#endif /* LINUX_VER >= 4.6 */
+	{
+		cptr = (compat_wifi_rx_report_t *)user_buf;
+		while ((count < pkt_count) && rx_pkt && cptr) {
+			compat_wifi_rx_report_t *comp_ptr = compat_ptr((uintptr_t) cptr);
+			compat_dhd_dbg_pkt_info_t compat_rx_pkt;
+			__dhd_dbg_dump_rx_pkt_info(dhdp, rx_pkt, count);
+			__COPY_TO_USER(&comp_ptr->fate, &rx_pkt->fate, sizeof(rx_pkt->fate));
+
+			compat_rx_pkt.payload_type = rx_pkt->info.payload_type;
+			compat_rx_pkt.pkt_len = rx_pkt->info.pkt_len;
+			compat_rx_pkt.driver_ts = rx_pkt->info.driver_ts;
+			compat_rx_pkt.firmware_ts = rx_pkt->info.firmware_ts;
+			compat_rx_pkt.pkt_hash = rx_pkt->info.pkt_hash;
+			__COPY_TO_USER(&comp_ptr->frame_inf.payload_type,
+				&compat_rx_pkt.payload_type,
+				OFFSETOF(compat_dhd_dbg_pkt_info_t, pkt_hash));
+			__COPY_TO_USER(comp_ptr->frame_inf.frame_content.ethernet_ii,
+				PKTDATA(dhdp->osh, rx_pkt->info.pkt), rx_pkt->info.pkt_len);
+
+			cptr++;
+			rx_pkt++;
+			count++;
+		}
+	} else
+#endif /* CONFIG_COMPAT */
+	{
+		ptr = (wifi_rx_report_t *)user_buf;
+		while ((count < pkt_count) && rx_pkt && ptr) {
+			__dhd_dbg_dump_rx_pkt_info(dhdp, rx_pkt, count);
+			__COPY_TO_USER(&ptr->fate, &rx_pkt->fate, sizeof(rx_pkt->fate));
+			__COPY_TO_USER(&ptr->frame_inf.payload_type,
+				&rx_pkt->info.payload_type,
+				OFFSETOF(dhd_dbg_pkt_info_t, pkt_hash));
+			__COPY_TO_USER(ptr->frame_inf.frame_content.ethernet_ii,
+				PKTDATA(dhdp->osh, rx_pkt->info.pkt), rx_pkt->info.pkt_len);
+
+			ptr++;
+			rx_pkt++;
+			count++;
+		}
+	}
+
+	*resp_count = pkt_count;
+
+exit:
+	for (i = 0; i < pkt_count; i++) {
+		PKTFREE(dhdp->osh, tmp_rx_pkt[i].info.pkt, TRUE);
+	}
+	MFREE(dhdp->osh, tmp_rx_pkt, alloc_len);
+
+	return ret;
+}
+
+int
+dhd_dbg_detach_pkt_monitor(dhd_pub_t *dhdp)
+{
+	dhd_dbg_tx_report_t *tx_report;
+	dhd_dbg_rx_report_t *rx_report;
+	dhd_dbg_pkt_mon_state_t tx_pkt_state;
+	dhd_dbg_pkt_mon_state_t tx_status_state;
+	dhd_dbg_pkt_mon_state_t rx_pkt_state;
+	unsigned long flags;
+
+	if (!dhdp || !dhdp->dbg) {
+		DHD_PKT_MON(("%s(): dhdp=%p, dhdp->dbg=%p\n", __FUNCTION__,
+			dhdp, (dhdp ? dhdp->dbg : NULL)));
+		return -EINVAL;
+	}
+
+	DHD_PKT_MON_LOCK(dhdp->dbg->pkt_mon_lock, flags);
+	tx_pkt_state = dhdp->dbg->pkt_mon.tx_pkt_state;
+	tx_status_state = dhdp->dbg->pkt_mon.tx_status_state;
+	rx_pkt_state = dhdp->dbg->pkt_mon.rx_pkt_state;
+
+	if (PKT_MON_DETACHED(tx_pkt_state) || PKT_MON_DETACHED(tx_status_state) ||
+			PKT_MON_DETACHED(rx_pkt_state)) {
+		DHD_PKT_MON(("%s(): packet monitor is already detached, "
+			"tx_pkt_state=%d, tx_status_state=%d, rx_pkt_state=%d\n",
+			__FUNCTION__, tx_pkt_state, tx_status_state, rx_pkt_state));
+		DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+		return -EINVAL;
+	}
+
+	tx_report = dhdp->dbg->pkt_mon.tx_report;
+	rx_report = dhdp->dbg->pkt_mon.rx_report;
+
+	/* free and de-initalize tx packet monitoring */
+	dhdp->dbg->pkt_mon.tx_pkt_state = PKT_MON_DETACHED;
+	dhdp->dbg->pkt_mon.tx_status_state = PKT_MON_DETACHED;
+	if (tx_report) {
+		if (tx_report->tx_pkts) {
+			__dhd_dbg_free_tx_pkts(dhdp, tx_report->tx_pkts,
+				tx_report->pkt_pos);
+			MFREE(dhdp->osh, tx_report->tx_pkts,
+				(sizeof(*tx_report->tx_pkts) * MAX_FATE_LOG_LEN));
+			dhdp->dbg->pkt_mon.tx_report->tx_pkts = NULL;
+		}
+		MFREE(dhdp->osh, tx_report, sizeof(*tx_report));
+		dhdp->dbg->pkt_mon.tx_report = NULL;
+	}
+	dhdp->dbg->pkt_mon.tx_pkt_mon = NULL;
+	dhdp->dbg->pkt_mon.tx_status_mon = NULL;
+
+	/* free and de-initalize rx packet monitoring */
+	dhdp->dbg->pkt_mon.rx_pkt_state = PKT_MON_DETACHED;
+	if (rx_report) {
+		if (rx_report->rx_pkts) {
+			__dhd_dbg_free_rx_pkts(dhdp, rx_report->rx_pkts,
+				rx_report->pkt_pos);
+			MFREE(dhdp->osh, rx_report->rx_pkts,
+				(sizeof(*rx_report->rx_pkts) * MAX_FATE_LOG_LEN));
+			dhdp->dbg->pkt_mon.rx_report->rx_pkts = NULL;
+		}
+		MFREE(dhdp->osh, rx_report, sizeof(*rx_report));
+		dhdp->dbg->pkt_mon.rx_report = NULL;
+	}
+	dhdp->dbg->pkt_mon.rx_pkt_mon = NULL;
+
+	DHD_PKT_MON_UNLOCK(dhdp->dbg->pkt_mon_lock, flags);
+	DHD_PKT_MON(("%s(): packet monitor detach succeeded\n", __FUNCTION__));
+	return BCME_OK;
+}
+#endif /* DBG_PKT_MON */
+
+#if defined(DBG_PKT_MON) || defined(DHD_PKT_LOGGING)
+/*
+ * XXX: WAR: Because of the overloading by DMA marker field,
+ * tx_status in TX completion message cannot be used. As a WAR,
+ * send d11 tx_status through unused status field of PCIe
+ * completion header.
+ */
+bool
+dhd_dbg_process_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid,
+		uint16 status)
+{
+	bool pkt_fate = TRUE;
+	if (dhdp->d11_tx_status) {
+		pkt_fate = (status == WLFC_CTL_PKTFLAG_DISCARD) ? TRUE : FALSE;
+		DHD_DBG_PKT_MON_TX_STATUS(dhdp, pkt, pktid, status);
+	}
+	return pkt_fate;
+}
+#else /* DBG_PKT_MON || DHD_PKT_LOGGING */
+bool
+dhd_dbg_process_tx_status(dhd_pub_t *dhdp, void *pkt,
+		uint32 pktid, uint16 status)
+{
+	return TRUE;
+}
+#endif /* DBG_PKT_MON || DHD_PKT_LOGGING */
+
+#define	EL_LOG_STR_LEN	512
+
+#define PRINT_CHN_PER_LINE 8
+#define PRINT_CHAN_LINE(cnt) \
+{\
+	cnt ++; \
+	if (cnt >= PRINT_CHN_PER_LINE) { \
+		DHD_ERROR(("%s\n", b.origbuf)); \
+		bcm_binit(&b, pr_buf, EL_LOG_STR_LEN); \
+		bcm_bprintf(&b, "%s: ", prefix); \
+		cnt = 0; \
+	} \
+}
+
+void print_roam_chan_list(char *prefix, uint chan_num, uint16 band_2g,
+	uint16 uni2a, uint8 uni3, uint8 *uni2c)
+{
+	struct bcmstrbuf b;
+	char pr_buf[EL_LOG_STR_LEN] = { 0 };
+	int cnt = 0;
+	int idx, idx2;
+
+	bcm_binit(&b, pr_buf, EL_LOG_STR_LEN);
+	bcm_bprintf(&b, "%s: count(%d)", prefix, chan_num);
+	/* 2G channnels */
+	for (idx = 0; idx < NBITS(uint16); idx++) {
+		if (BCM_BIT(idx) & band_2g) {
+			bcm_bprintf(&b, " %d", idx);
+			PRINT_CHAN_LINE(cnt);
+
+		}
+	}
+
+	/* 5G UNII BAND 1, UNII BAND 2A */
+	for (idx = 0; idx < NBITS(uint16); idx++) {
+		if (BCM_BIT(idx) & uni2a) {
+			bcm_bprintf(&b, " %u", ROAM_CHN_UNI_2A + idx * ROAM_CHN_SPACE);
+			PRINT_CHAN_LINE(cnt);
+		}
+	}
+
+	/* 5G UNII BAND 2C */
+	for (idx2 = 0; idx2 < 3; idx2++) {
+		for (idx = 0; idx < NBITS(uint8); idx++) {
+			if (BCM_BIT(idx) & uni2c[idx2]) {
+				bcm_bprintf(&b, " %u", ROAM_CHN_UNI_2C +
+					idx2 * ROAM_CHN_SPACE * NBITS(uint8) +
+					idx * ROAM_CHN_SPACE);
+				PRINT_CHAN_LINE(cnt);
+			}
+		}
+	}
+
+	/* 5G UNII BAND 3 */
+	for (idx = 0; idx < NBITS(uint8); idx++) {
+		if (BCM_BIT(idx) & uni3) {
+			bcm_bprintf(&b, " %u", ROAM_CHN_UNI_3 + idx * ROAM_CHN_SPACE);
+			PRINT_CHAN_LINE(cnt);
+		}
+	}
+
+	if (cnt != 0) {
+		DHD_ERROR(("%s\n", b.origbuf));
+	}
+}
+
+void pr_roam_scan_start_v1(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_scan_cmpl_v1(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_cmpl_v1(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_nbr_req_v1(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_nbr_rep_v1(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_bcn_req_v1(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_bcn_rep_v1(prcd_event_log_hdr_t *plog_hdr);
+
+void pr_roam_scan_start_v2(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_scan_cmpl_v2(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_nbr_rep_v2(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_bcn_rep_v2(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_btm_rep_v2(prcd_event_log_hdr_t *plog_hdr);
+
+void pr_roam_bcn_req_v3(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_bcn_rep_v3(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_btm_rep_v3(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_6g_novlp_rep_v3(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_wtc_btm_rep_v3(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_btm_query_v3(prcd_event_log_hdr_t *plog_hdr);
+
+void pr_roam_btm_resp_v4(prcd_event_log_hdr_t *plog_hdr);
+void pr_roam_btm_req_v4(prcd_event_log_hdr_t *plog_hdr);
+
+/* Will find an entity which has highest version of that ROAM_LOG id.
+ * ALL structure should support backward compatibility.
+ * { ROAM_LOG_VER, ROAM_LOG_ID, print ROAM_LOG function() },
+ */
+
+static const pr_roam_tbl_t roam_log_print_tbl[] =
+{
+	/* ROAM Scan Start */
+	{ROAM_LOG_VER_2, ROAM_LOG_SCANSTART, pr_roam_scan_start_v2},
+	{ROAM_LOG_VER_1, ROAM_LOG_SCANSTART, pr_roam_scan_start_v1},
+	/* ROAM Scan Completed */
+	{ROAM_LOG_VER_2, ROAM_LOG_SCAN_CMPLT, pr_roam_scan_cmpl_v2},
+	{ROAM_LOG_VER_1, ROAM_LOG_SCAN_CMPLT, pr_roam_scan_cmpl_v1},
+	/* ROAM Completed */
+	{ROAM_LOG_VER_1, ROAM_LOG_ROAM_CMPLT, pr_roam_cmpl_v1},
+	/* Neighbor Request */
+	{ROAM_LOG_VER_1, ROAM_LOG_NBR_REQ, pr_roam_nbr_req_v1},
+	/* Neighbor Report */
+	{ROAM_LOG_VER_2, ROAM_LOG_NBR_REP, pr_roam_nbr_rep_v2},
+	{ROAM_LOG_VER_1, ROAM_LOG_NBR_REP, pr_roam_nbr_rep_v1},
+	/* Beacon Request */
+	{ROAM_LOG_VER_3, ROAM_LOG_BCN_REQ, pr_roam_bcn_req_v3},
+	{ROAM_LOG_VER_1, ROAM_LOG_BCN_REQ, pr_roam_bcn_req_v1},
+	/* Beacon Report */
+	{ROAM_LOG_VER_3, ROAM_LOG_BCN_REP, pr_roam_bcn_rep_v3},
+	{ROAM_LOG_VER_2, ROAM_LOG_BCN_REP, pr_roam_bcn_rep_v2},
+	{ROAM_LOG_VER_1, ROAM_LOG_BCN_REP, pr_roam_bcn_rep_v1},
+	/* BTM Response */
+	{ROAM_LOG_VER_4, ROAM_LOG_BTM_REP, pr_roam_btm_resp_v4},
+	{ROAM_LOG_VER_3, ROAM_LOG_BTM_REP, pr_roam_btm_rep_v3},
+	{ROAM_LOG_VER_2, ROAM_LOG_BTM_REP, pr_roam_btm_rep_v2},
+	/* SCAN 6G no VLP channels */
+	{ROAM_LOG_VER_3, ROAM_LOG_6G_NOVLP_REP, pr_roam_6g_novlp_rep_v3},
+	/* BTM WTC Request/Response */
+	{ROAM_LOG_VER_3, ROAM_LOG_WTC_BTM_REP, pr_roam_wtc_btm_rep_v3},
+	/* BTM Query */
+	{ROAM_LOG_VER_3, ROAM_LOG_BTM_QUERY, pr_roam_btm_query_v3},
+	/* BTM Request */
+	{ROAM_LOG_VER_4, ROAM_LOG_BTM_REQ, pr_roam_btm_req_v4},
+
+	{0, PRSV_PERIODIC_ID_MAX, NULL}
+};
+
+void pr_roam_scan_start_v1(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_trig_v1_t *log = (roam_log_trig_v1_t *)plog_hdr->log_ptr;
+
+	DHD_ERROR_ROAM(("ROAM_LOG_SCANSTART time: %d,"
+		" version:%d reason: %d rssi:%d cu:%d result:%d\n",
+		plog_hdr->armcycle, log->hdr.version, log->reason,
+		log->rssi, log->current_cu, log->result));
+	if (log->reason == WLC_E_REASON_DEAUTH ||
+		log->reason == WLC_E_REASON_DISASSOC) {
+		DHD_ERROR_ROAM(("  ROAM_LOG_PRT_ROAM: RCVD reason:%d\n",
+			log->prt_roam.rcvd_reason));
+	} else if (log->reason == WLC_E_REASON_BSSTRANS_REQ) {
+		DHD_ERROR_ROAM(("  ROAM_LOG_BSS_REQ: mode:%d candidate:%d token:%d "
+			"duration disassoc:%d valid:%d term:%d\n",
+			log->bss_trans.req_mode, log->bss_trans.nbrlist_size,
+			log->bss_trans.token, log->bss_trans.disassoc_dur,
+			log->bss_trans.validity_dur, log->bss_trans.bss_term_dur));
+	}
+}
+
+void pr_roam_scan_cmpl_v1(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_scan_cmplt_v1_t *log = (roam_log_scan_cmplt_v1_t *)plog_hdr->log_ptr;
+	char chanspec_buf[CHANSPEC_STR_LEN];
+	int i;
+
+	DHD_ERROR_ROAM(("ROAM_LOG_SCAN_CMPL: time:%d version:%d"
+		"is_full:%d scan_count:%d score_delta:%d\n",
+		plog_hdr->armcycle, log->hdr.version, log->full_scan,
+		log->scan_count, log->score_delta));
+	DHD_ERROR_ROAM(("  ROAM_LOG_CUR_AP: " MACDBG "rssi:%d score:%d channel:%s\n",
+			MAC2STRDBG((uint8 *)&log->cur_info.addr),
+			log->cur_info.rssi,
+			log->cur_info.score,
+			wf_chspec_ntoa_ex(log->cur_info.chanspec, chanspec_buf)));
+	for (i = 0; i < log->scan_list_size; i++) {
+		DHD_ERROR_ROAM(("  ROAM_LOG_CANDIDATE %d: " MACDBG
+			"rssi:%d score:%d channel:%s TPUT:%dkbps\n",
+			i, MAC2STRDBG((uint8 *)&log->scan_list[i].addr),
+			log->scan_list[i].rssi, log->scan_list[i].score,
+			wf_chspec_ntoa_ex(log->scan_list[i].chanspec,
+			chanspec_buf),
+			log->scan_list[i].estm_tput != ROAM_LOG_INVALID_TPUT?
+			log->scan_list[i].estm_tput:0));
+	}
+}
+
+void pr_roam_cmpl_v1(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_cmplt_v1_t *log = (roam_log_cmplt_v1_t *)plog_hdr->log_ptr;
+	char chanspec_buf[CHANSPEC_STR_LEN];
+
+	DHD_ERROR_ROAM(("ROAM_LOG_ROAM_CMPL: time: %d, version:%d"
+		"status: %d reason: %d channel:%s retry:%d " MACDBG "\n",
+		plog_hdr->armcycle, log->hdr.version, log->status, log->reason,
+		wf_chspec_ntoa_ex(log->chanspec, chanspec_buf),
+		log->retry, MAC2STRDBG((uint8 *)&log->addr)));
+}
+
+void pr_roam_nbr_req_v1(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_nbrreq_v1_t *log = (roam_log_nbrreq_v1_t *)plog_hdr->log_ptr;
+
+	DHD_ERROR_ROAM(("ROAM_LOG_NBR_REQ: time: %d, version:%d token:%d\n",
+		plog_hdr->armcycle, log->hdr.version, log->token));
+}
+
+void pr_roam_nbr_rep_v1(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_nbrrep_v1_t *log = (roam_log_nbrrep_v1_t *)plog_hdr->log_ptr;
+
+	DHD_ERROR_ROAM(("ROAM_LOG_NBR_REP: time:%d, veresion:%d chan_num:%d\n",
+		plog_hdr->armcycle, log->hdr.version, log->channel_num));
+}
+
+void pr_roam_bcn_req_v1(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_bcnrpt_req_v1_t *log = (roam_log_bcnrpt_req_v1_t *)plog_hdr->log_ptr;
+
+	DHD_ERROR_ROAM(("ROAM_LOG_BCN_REQ: time:%d, version:%d ret:%d"
+		"class:%d num_chan:%d ",
+		plog_hdr->armcycle, log->hdr.version,
+		log->result, log->reg, log->channel));
+	DHD_ERROR_ROAM(("ROAM_LOG_BCN_REQ: mode:%d is_wild:%d duration:%d"
+		"ssid_len:%d\n", log->mode, log->bssid_wild,
+		log->duration, log->ssid_len));
+}
+
+void pr_roam_bcn_rep_v1(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_bcnrpt_rep_v1_t *log = (roam_log_bcnrpt_rep_v1_t *)plog_hdr->log_ptr;
+	DHD_ERROR_ROAM(("ROAM_LOG_BCN_REP: time:%d, verseion:%d count:%d\n",
+		plog_hdr->armcycle, log->hdr.version,
+		log->count));
+}
+
+void pr_roam_scan_start_v2(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_trig_v2_t *log = (roam_log_trig_v2_t *)plog_hdr->log_ptr;
+	DHD_ERROR_ROAM(("ROAM_LOG_SCANSTART time: %d,"
+		" version:%d reason: %d rssi:%d cu:%d result:%d full_scan:%d\n",
+		plog_hdr->armcycle, log->hdr.version, log->reason,
+		log->rssi, log->current_cu, log->result,
+		log->result?(-1):log->full_scan));
+	if (log->reason == WLC_E_REASON_DEAUTH ||
+		log->reason == WLC_E_REASON_DISASSOC) {
+		DHD_ERROR_ROAM(("  ROAM_LOG_PRT_ROAM: RCVD reason:%d\n",
+			log->prt_roam.rcvd_reason));
+	} else if (log->reason == WLC_E_REASON_LOW_RSSI) {
+		DHD_ERROR_ROAM((" ROAM_LOG_LOW_RSSI: threshold:%d\n",
+			log->low_rssi.rssi_threshold));
+	}
+}
+
+void pr_roam_scan_cmpl_v2(prcd_event_log_hdr_t *plog_hdr)
+{
+	int i;
+	roam_log_scan_cmplt_v2_t *log = (roam_log_scan_cmplt_v2_t *)plog_hdr->log_ptr;
+	char chanspec_buf[CHANSPEC_STR_LEN];
+
+	DHD_ERROR_ROAM(("ROAM_LOG_SCAN_CMPL: time:%d version:%d"
+		"scan_count:%d score_delta:%d\n",
+		plog_hdr->armcycle, log->hdr.version,
+		log->scan_count, log->score_delta));
+	DHD_ERROR_ROAM(("  ROAM_LOG_CUR_AP: " MACDBG "rssi:%d score:%d channel:%s\n",
+			MAC2STRDBG((uint8 *)&log->cur_info.addr),
+			log->cur_info.rssi,
+			log->cur_info.score,
+			wf_chspec_ntoa_ex(log->cur_info.chanspec, chanspec_buf)));
+	for (i = 0; i < log->scan_list_size; i++) {
+		DHD_ERROR_ROAM(("  ROAM_LOG_CANDIDATE %d: " MACDBG
+			"rssi:%d score:%d cu :%d channel:%s TPUT:%dkbps\n",
+			i, MAC2STRDBG((uint8 *)&log->scan_list[i].addr),
+			log->scan_list[i].rssi, log->scan_list[i].score,
+			log->scan_list[i].cu_avail ?
+			(log->scan_list[i].cu * 100 / WL_MAX_CHANNEL_USAGE) : WL_CU_NOT_AVAIL,
+			wf_chspec_ntoa_ex(log->scan_list[i].chanspec,
+			chanspec_buf),
+			log->scan_list[i].estm_tput != ROAM_LOG_INVALID_TPUT?
+			log->scan_list[i].estm_tput:0));
+	}
+	if (log->chan_num != 0) {
+		print_roam_chan_list("ROAM_LOG_SCAN_CHANLIST", log->chan_num,
+			log->band2g_chan_list, log->uni2a_chan_list,
+			log->uni3_chan_list, log->uni2c_chan_list);
+	}
+
+}
+
+void pr_roam_nbr_rep_v2(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_nbrrep_v2_t *log = (roam_log_nbrrep_v2_t *)plog_hdr->log_ptr;
+	DHD_ERROR_ROAM(("ROAM_LOG_NBR_REP: time:%d, veresion:%d chan_num:%d\n",
+		plog_hdr->armcycle, log->hdr.version, log->channel_num));
+	if (log->channel_num != 0) {
+		print_roam_chan_list("ROAM_LOG_NBR_REP_CHANLIST", log->channel_num,
+			log->band2g_chan_list, log->uni2a_chan_list,
+			log->uni3_chan_list, log->uni2c_chan_list);
+	}
+}
+
+void pr_roam_bcn_rep_v2(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_bcnrpt_rep_v2_t *log = (roam_log_bcnrpt_rep_v2_t *)plog_hdr->log_ptr;
+
+	DHD_ERROR_ROAM(("ROAM_LOG_BCN_REP: time:%d, verseion:%d count:%d mode:%d\n",
+		plog_hdr->armcycle, log->hdr.version,
+		log->count, log->reason));
+}
+
+void pr_roam_btm_rep_v2(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_btm_rep_v2_t *log = (roam_log_btm_rep_v2_t *)plog_hdr->log_ptr;
+	DHD_ERROR_ROAM(("ROAM_LOG_BTM_REP: time:%d version:%d req_mode:%d "
+		"status:%d ret:%d\n",
+		plog_hdr->armcycle, log->hdr.version,
+		log->req_mode, log->status, log->result));
+}
+
+void pr_roam_bcn_req_v3(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_bcnrpt_req_v3_t *log = (roam_log_bcnrpt_req_v3_t *)plog_hdr->log_ptr;
+
+	DHD_ERROR_ROAM(("ROAM_LOG_BCN_REQ: time:%d, version:%d ret:%d"
+		"class:%d %s ",
+		plog_hdr->armcycle, log->hdr.version,
+		log->result, log->reg, log->channel?"":"all_chan"));
+	DHD_ERROR_ROAM(("ROAM_LOG_BCN_REQ: mode:%d is_wild:%d duration:%d"
+		"ssid_len:%d\n", log->mode, log->bssid_wild,
+		log->duration, log->ssid_len));
+	if (log->channel_num != 0) {
+		print_roam_chan_list("ROAM_LOG_BCNREQ_SCAN_CHANLIST", log->channel_num,
+			log->band2g_chan_list, log->uni2a_chan_list,
+			log->uni3_chan_list, log->uni2c_chan_list);
+	}
+}
+
+static const char*
+pr_roam_bcn_rep_reason(uint16 reason_detail)
+{
+	static const char* reason_tbl[] = {
+		"BCNRPT_RSN_SUCCESS",
+		"BCNRPT_RSN_BADARG",
+		"BCNRPT_RSN_SCAN_ING",
+		"BCNRPT_RSN_SCAN_FAIL",
+		"UNKNOWN"
+	};
+
+	if (reason_detail >= ARRAYSIZE(reason_tbl)) {
+		DHD_ERROR_ROAM(("UNKNOWN Reason:%u\n", reason_detail));
+		ASSERT(0);
+		reason_detail = ARRAYSIZE(reason_tbl) - 1;
+
+	}
+	return reason_tbl[reason_detail];
+}
+
+void pr_roam_bcn_rep_v3(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_bcnrpt_rep_v3_t *log = (roam_log_bcnrpt_rep_v3_t *)plog_hdr->log_ptr;
+
+	DHD_ERROR_ROAM(("ROAM_LOG_BCN_REP: time:%d, verseion:%d count:%d mode:%d\n",
+		plog_hdr->armcycle, log->hdr.version,
+		log->count, log->reason));
+	DHD_ERROR_ROAM(("ROAM_LOG_BCN_REP: mode reason(%d):%s scan_stus:%u duration:%u\n",
+		log->reason_detail, pr_roam_bcn_rep_reason(log->reason_detail),
+		(log->reason_detail == BCNRPT_RSN_SCAN_FAIL)? log->scan_status:0,
+		log->duration));
+}
+
+void pr_roam_btm_rep_v3(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_btm_rep_v3_t *log = (roam_log_btm_rep_v3_t *)plog_hdr->log_ptr;
+	DHD_ERROR_ROAM(("ROAM_LOG_BTM_REP: time:%d version:%d req_mode:%d "
+		"status:%d ret:%d target:" MACDBG "\n",
+		plog_hdr->armcycle, log->hdr.version,
+		log->req_mode, log->status, log->result,
+		MAC2STRDBG((uint8 *)&log->target_addr)));
+}
+
+void
+pr_roam_btm_query_v3(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_btm_query_v3_t *log = (roam_log_btm_query_v3_t *)plog_hdr->log_ptr;
+	DHD_ERROR_ROAM(("ROAM_LOG_BTM_QUERY: time:%d version:%d token:%d reason:%d\n",
+		plog_hdr->armcycle, log->hdr.version, log->token, log->reason));
+}
+
+void
+pr_roam_6g_novlp_rep_v3(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_6g_novlp_v3_t *log = (roam_log_6g_novlp_v3_t *)plog_hdr->log_ptr;
+	char chanspec_buf[CHANSPEC_STR_LEN];
+
+	DHD_ERROR_ROAM(("ROAM_LOG_6G_NoVPL_Filtered: time:%d version:%d "
+		"CH:%s(0x%04x) BSSID:" MACDBG "\n",
+		plog_hdr->armcycle, log->hdr.version,
+		wf_chspec_ntoa_ex(log->chanspec, chanspec_buf),
+		log->chanspec, MAC2STRDBG((uint8 *)&log->bssid)));
+}
+
+void
+pr_roam_wtc_btm_rep_v3(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_wtc_btmrep_v3_t *log = (roam_log_wtc_btmrep_v3_t *)plog_hdr->log_ptr;
+
+	DHD_ERROR_ROAM(("ROAM_LOG_WTC: time:%d version:%d WTC BTM %s\n",
+		plog_hdr->armcycle, log->hdr.version,
+		(log->wtc_type == WTC_BTMREQ) ? "Request" : "Response"));
+
+	if (log->wtc_type == WTC_BTMREQ) {
+		DHD_ERROR_ROAM(("ROAM_LOG_WTC_CFG: mode:%d Scan mode:%d RSSI TH:%d "
+			"Candidate RSSI TH:%d %d %d\n",
+			log->wtcreq.mode, log->wtcreq.scantype,
+			log->wtcreq.rssithresh[WTC_BAND_2G],
+			log->wtcreq.ap_rssithresh[WTC_BAND_2G],
+			log->wtcreq.ap_rssithresh[WTC_BAND_5G],
+			log->wtcreq.ap_rssithresh[WTC_BAND_6G]));
+		if (log->wtcreq.status) {
+			DHD_ERROR_ROAM(("  Recvd invalid WTC Req len:%d ver:%d\n",
+				log->ie_length, log->wtc_ver));
+		} else {
+			DHD_ERROR_ROAM(("ROAM_LOG_WTC_REQ len:%d WTC ver:%d "
+				"Reason code:%d Subcode:%d duration:%d\n",
+				log->ie_length, log->wtc_ver,
+				log->wtcreq.rsn_code, log->wtcreq.subcode,
+				log->wtcreq.duration));
+		}
+	} else if (log->wtc_type == WTC_BTMRESP) {
+		DHD_ERROR_ROAM(("ROAM_LOG_WTC_RESP len:%d WTC ver:%d "
+			"Reason code:%d Resp status:%d\n",
+			log->ie_length, log->wtc_ver,
+			log->wtcresp.rsn_code, log->wtcresp.status));
+	}
+}
+/* ROAM logging BTM Request */
+void
+pr_roam_btm_req_v4(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_btm_req_v4_t *log = (roam_log_btm_req_v4_t *)plog_hdr->log_ptr;
+	int i;
+	DHD_ERROR_ROAM(("ROAM_LOG_BTM_REQ: time:%d version:%d req_mode:%d "
+		"token:%d candi:%d duration disassoc:%d valid:%d term:%d\n",
+		plog_hdr->armcycle, log->hdr.version,
+		log->req_mode, log->token, log->nbrlist_size,
+		log->disassoc_dur, log->validity_dur, log->bss_term_dur));
+	if (log->nbrlist_size) {
+		int max_idx = MIN(log->nbrlist_size, ROAM_NBR_RPT_LIST_SIZE);
+		for (i = 0; i < max_idx; i++) {
+			DHD_ERROR_ROAM(("   ROAM_LOG_NBR: [%d]" MACDBG " pref:0x%x\n",
+				i, MAC2STRDBG((uint8 *)&log->nbr_list[i].bssid),
+				log->nbr_list[i].preference));
+		}
+	}
+}
+/* ROAM logging BTM Response */
+void
+pr_roam_btm_resp_v4(prcd_event_log_hdr_t *plog_hdr)
+{
+	roam_log_btm_resp_v4_t *log = (roam_log_btm_resp_v4_t *)plog_hdr->log_ptr;
+	DHD_ERROR_ROAM(("ROAM_LOG_BTM_REP: time:%d version:%d req_mode:%d "
+		    "status:%d token:%d term_delay:%d ret:%d target:" MACDBG "\n",
+		    plog_hdr->armcycle, log->hdr.version,
+		    log->req_mode, log->status, log->token, log->term_delay, log->result,
+		    MAC2STRDBG((uint8 *)&log->target_addr)));
+}
+
+void
+print_roam_enhanced_log(prcd_event_log_hdr_t *plog_hdr)
+{
+	prsv_periodic_log_hdr_t *hdr = (prsv_periodic_log_hdr_t *)plog_hdr->log_ptr;
+	uint32 *ptr = (uint32 *)plog_hdr->log_ptr;
+	int i;
+	int loop_cnt = hdr->length / sizeof(uint32);
+	struct bcmstrbuf b;
+	char pr_buf[EL_LOG_STR_LEN] = { 0 };
+	const pr_roam_tbl_t *cur_elem = &roam_log_print_tbl[0];
+
+#ifdef WL_CFGVENDOR_CUST_ADVLOG
+	wl_cfgvendor_custom_advlog_roam_log(plog_hdr->log_ptr, plog_hdr->armcycle);
+#endif /* WL_CFGVENDOR_CUST_ADVLOG */
+
+	while (cur_elem && cur_elem->pr_func) {
+		if (hdr->version >= cur_elem->version &&
+			hdr->id == cur_elem->id) {
+			cur_elem->pr_func(plog_hdr);
+			return;
+		}
+		cur_elem++;
+	}
+
+	bcm_binit(&b, pr_buf, EL_LOG_STR_LEN);
+	bcm_bprintf(&b, "ROAM_LOG_UNKNOWN ID:%d ver:%d armcycle:%d",
+		hdr->id, hdr->version, plog_hdr->armcycle);
+	for (i = 0; i < loop_cnt && b.size > 0; i++) {
+		bcm_bprintf(&b, " %x", *ptr);
+		ptr++;
+	}
+	DHD_ERROR_ROAM(("%s\n", b.origbuf));
+}
+
+/*
+ * dhd_dbg_attach: initialziation of dhd dbugability module
+ *
+ * Return: An error code or 0 on success.
+ */
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+struct dhd_dbg_ring_buf g_ring_buf;
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
+int
+dhd_dbg_attach(dhd_pub_t *dhdp, dbg_pullreq_t os_pullreq,
+	dbg_urgent_noti_t os_urgent_notifier, void *os_priv)
+{
+	dhd_dbg_t *dbg = NULL;
+#if defined(DHD_DEBUGABILITY_LOG_DUMP_RING) || defined(DHD_DEBUGABILITY_EVENT_RING) || \
+	defined(DHD_PKT_LOGGING_DBGRING)
+	dhd_dbg_ring_t *ring = NULL;
+	int ring_id = 0;
+	void *buf = NULL;
+	int ret = BCME_ERROR;
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING || BTLOG ||
+	* DHD_DEBUGABILITY_EVENT_RING || DHD_PKT_LOGGING_DBGRING ||
+	* (DEBUGABILITY && CUSTOMER_HW6)
+	*/
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+	struct dhd_dbg_ring_buf *ring_buf;
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
+#ifdef DHD_PKT_LOGGING_DBGRING
+	dhd_pktlog_ring_t *pktlog_ring = NULL;
+#endif /* DHD_PKT_LOGGING_DBGRING */
+
+	dbg = VMALLOCZ(dhdp->osh, sizeof(dhd_dbg_t));
+	if (!dbg) {
+		DHD_ERROR(("%s:%d: VMALLOC failed for dbg, size %d\n",
+			__FUNCTION__, __LINE__, (uint32)sizeof(dhd_dbg_t)));
+		return BCME_NOMEM;
+	}
+
+#ifdef DHD_DEBUGABILITY_EVENT_RING
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+	buf = DHD_OS_PREALLOC(dhdp, DHD_PREALLOC_DHD_EVENT_RING, DHD_EVENT_RING_SIZE);
+#else
+	buf = VMALLOCZ(dhdp->osh, DHD_EVENT_RING_SIZE);
+#endif
+	if (!buf) {
+		DHD_ERROR(("%s:%d: VMALLOC failed for event_ring, size %d\n",
+			__FUNCTION__, __LINE__, DHD_EVENT_RING_SIZE));
+		ret = BCME_NOMEM;
+		goto error;
+	}
+	ret = dhd_dbg_ring_init(dhdp, &dbg->dbg_rings[DHD_EVENT_RING_ID],
+		DHD_EVENT_RING_ID, (uint8 *)DHD_EVENT_RING_NAME,
+		DHD_EVENT_RING_SIZE, buf, FALSE);
+	if (ret) {
+		goto error;
+	}
+#endif /* DHD_DEBUGABILITY_EVENT_RING */
+
+#if defined(DHD_DEBUGABILITY_LOG_DUMP_RING)
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+	buf = DHD_OS_PREALLOC(dhdp, DHD_PREALLOC_FW_VERBOSE_RING, FW_VERBOSE_RING_SIZE);
+#else
+	buf = VMALLOCZ(dhdp->osh, FW_VERBOSE_RING_SIZE);
+#endif
+	if (!buf) {
+		DHD_ERROR(("%s:%d: VMALLOC failed for fw_verbose_ring, size %d\n",
+			__FUNCTION__, __LINE__, FW_VERBOSE_RING_SIZE));
+		ret = BCME_NOMEM;
+		goto error;
+	}
+	ret = dhd_dbg_ring_init(dhdp, &dbg->dbg_rings[FW_VERBOSE_RING_ID],
+		FW_VERBOSE_RING_ID, (uint8 *)FW_VERBOSE_RING_NAME,
+		FW_VERBOSE_RING_SIZE, buf, FALSE);
+	if (ret) {
+		goto error;
+	}
+#endif
+
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+	buf = VMALLOCZ(dhdp->osh, DRIVER_LOG_RING_SIZE);
+	if (!buf) {
+		DHD_ERROR(("%s:%d: VMALLOC failed for driver_log_ring, size %d\n",
+			__FUNCTION__, __LINE__, DRIVER_LOG_RING_SIZE));
+		ret = BCME_NOMEM;
+		goto error;
+	}
+	ret = dhd_dbg_ring_init(dhdp, &dbg->dbg_rings[DRIVER_LOG_RING_ID],
+		DRIVER_LOG_RING_ID, (uint8 *)DRIVER_LOG_RING_NAME,
+		DRIVER_LOG_RING_SIZE, buf, FALSE);
+	if (ret) {
+		goto error;
+	}
+
+	buf = VMALLOCZ(dhdp->osh, ROAM_STATS_RING_SIZE);
+	if (!buf) {
+		DHD_ERROR(("%s:%d: VMALLOC failed for roam_stats_ring, size %d\n",
+			__FUNCTION__, __LINE__, ROAM_STATS_RING_SIZE));
+		ret = BCME_NOMEM;
+		goto error;
+	}
+	ret = dhd_dbg_ring_init(dhdp, &dbg->dbg_rings[ROAM_STATS_RING_ID],
+		ROAM_STATS_RING_ID, (uint8 *)ROAM_STATS_RING_NAME,
+		ROAM_STATS_RING_SIZE, buf, FALSE);
+	if (ret) {
+		goto error;
+	}
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
+
+#if defined(DHD_DEBUGABILITY_DEBUG_DUMP) || defined(DHD_HAL_RING_DUMP)
+	/*
+	 * delayed memory allocation. memory will be allocated when debug_dump is invoked
+	 * To prepare the ringbuffer in legacy HAL, we should initialize ring at this time
+	 */
+	ret = dhd_dbg_ring_init(dhdp, &dbg->dbg_rings[DEBUG_DUMP_RING1_ID],
+		DEBUG_DUMP_RING1_ID, (uint8 *)DEBUG_DUMP_RING1_NAME,
+		DEBUG_DUMP_RING1_SIZE, NULL, FALSE);
+	if (ret) {
+		DHD_ERROR(("%s: Failed to init debug ring1\n", __func__));
+		goto error;
+	}
+
+	ret = dhd_dbg_ring_init(dhdp, &dbg->dbg_rings[DEBUG_DUMP_RING2_ID],
+		DEBUG_DUMP_RING2_ID, (uint8 *)DEBUG_DUMP_RING2_NAME,
+		DEBUG_DUMP_RING2_SIZE, NULL, FALSE);
+	if (ret) {
+		DHD_ERROR(("%s: Failed to init debug ring2\n", __func__));
+		goto error;
+	}
+#endif /* defined(DHD_DEBUGABILITY_DEBUG_DUMP) || defined(DHD_HAL_RING_DUMP) */
+
+#if defined(DHD_HAL_RING_DUMP_MEMDUMP)
+	ret = dhd_dbg_ring_init(dhdp, &dbg->dbg_rings[MEM_DUMP_RING_ID], MEM_DUMP_RING_ID,
+			(uint8 *)MEM_DUMP_RING_NAME, MEM_DUMP_RING_SIZE, NULL, FALSE);
+	if (ret) {
+		DHD_ERROR(("%s: Failed to init mem dump ring\n", __func__));
+		goto error;
+	}
+#endif /* DHD_HAL_RING_DUMP_MEMDUMP */
+
+#ifdef DHD_PKT_LOGGING_DBGRING
+	if (dhdp && dhdp->pktlog && dhdp->pktlog->pktlog_ring) {
+		pktlog_ring = dhdp->pktlog->pktlog_ring;
+	}
+
+	if (!pktlog_ring) {
+		DHD_ERROR(("%s: pktlog_ring is NULL. return.\n", __FUNCTION__));
+		ret = BCME_NOMEM;
+		goto error;
+	}
+
+	buf = pktlog_ring->ring_info_mem;
+	if (!buf) {
+		DHD_ERROR(("%s: ring_info_mem is NULL. return.\n", __FUNCTION__));
+		ret = BCME_NOMEM;
+		goto error;
+	}
+
+	ret = dhd_dbg_ring_init(dhdp, &dbg->dbg_rings[PACKET_LOG_RING_ID],
+			PACKET_LOG_RING_ID, (uint8 *)DHD_PACKET_LOG_RING_NAME,
+			DHD_PACKET_LOG_RING_SIZE, buf, FALSE);
+	if (ret) {
+		goto error;
+	}
+
+	pktlog_ring->dbg_ring = &dbg->dbg_rings[PACKET_LOG_RING_ID];
+#endif /* DHD_PKT_LOGGING_DBGRING */
+	dbg->private = os_priv;
+	dbg->pullreq = os_pullreq;
+	dbg->urgent_notifier = os_urgent_notifier;
+	dhdp->dbg = dbg;
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+	ring_buf = &g_ring_buf;
+	ring_buf->dhd_pub = dhdp;
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
+
+	return BCME_OK;
+
+#if defined(DHD_DEBUGABILITY_LOG_DUMP_RING) || defined(DHD_DEBUGABILITY_EVENT_RING) || \
+	defined(DHD_PKT_LOGGING_DBGRING)
+error:
+	for (ring_id = DEBUG_RING_ID_INVALID + 1; ring_id < DEBUG_RING_ID_MAX; ring_id++) {
+		if (VALID_RING(dbg->dbg_rings[ring_id].id)) {
+			ring = &dbg->dbg_rings[ring_id];
+			dhd_dbg_ring_deinit(dhdp, ring);
+			if (ring->ring_buf) {
+#ifdef DHD_PKT_LOGGING_DBGRING
+				if (ring_id != PACKET_LOG_RING_ID)
+#endif /* DHD_PKT_LOGGING_DBGRING */
+				{
+#ifndef CONFIG_DHD_USE_STATIC_BUF
+					VMFREE(dhdp->osh, ring->ring_buf, ring->ring_size);
+#endif
+				}
+				ring->ring_buf = NULL;
+			}
+			ring->ring_size = 0;
+		}
+	}
+
+	VMFREE(dhdp->osh, dbg, sizeof(dhd_dbg_t));
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+	ring_buf = &g_ring_buf;
+	ring_buf->dhd_pub = NULL;
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
+
+	return ret;
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING || BTLOG ||
+	* DHD_DEBUGABILITY_EVENT_RING || DHD_PKT_LOGGING_DBGRING ||
+	* (DEBUGABILITY && CUSTOMER_HW6)
+	*/
+}
+
+/*
+ * dhd_dbg_detach: clean up dhd dbugability module
+ */
+void
+dhd_dbg_detach(dhd_pub_t *dhdp)
+{
+	dhd_dbg_t *dbg;
+	int ring_id;
+	dhd_dbg_ring_t *ring = NULL;
+
+	dbg = dhdp->dbg;
+	if (!dbg) {
+		return;
+	}
+
+	for (ring_id = DEBUG_RING_ID_INVALID + 1; ring_id < DEBUG_RING_ID_MAX; ring_id++) {
+		if (VALID_RING(dbg->dbg_rings[ring_id].id)) {
+			ring = &dbg->dbg_rings[ring_id];
+			dhd_dbg_ring_deinit(dhdp, ring);
+			if (ring->ring_buf) {
+#ifdef DHD_PKT_LOGGING_DBGRING
+				if (ring_id != PACKET_LOG_RING_ID)
+#endif /* DHD_PKT_LOGGING_DBGRING */
+				{
+#ifndef CONFIG_DHD_USE_STATIC_BUF
+					VMFREE(dhdp->osh, ring->ring_buf, ring->ring_size);
+#endif
+				}
+				ring->ring_buf = NULL;
+			}
+			ring->ring_size = 0;
+		}
+	}
+	VMFREE(dhdp->osh, dbg, sizeof(dhd_dbg_t));
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+	g_ring_buf.dhd_pub = NULL;
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
+}
+
+uint32
+dhd_dbg_get_fwverbose(dhd_pub_t *dhdp)
+{
+	if (dhdp && dhdp->dbg) {
+		return dhdp->dbg->dbg_rings[FW_VERBOSE_RING_ID].log_level;
+	}
+	return 0;
+}
+
+void
+dhd_dbg_set_fwverbose(dhd_pub_t *dhdp, uint32 new_val)
+{
+
+	if (dhdp && dhdp->dbg) {
+		dhdp->dbg->dbg_rings[FW_VERBOSE_RING_ID].log_level = new_val;
+	}
+}
+
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+void
+dhd_dbg_ring_write(int type, char *binary_data,
+		int binary_len, const char *fmt, ...)
+{
+	int len = 0;
+	va_list args;
+	struct dhd_dbg_ring_buf *ring_buf = NULL;
+	char tmp_buf[DHD_LOG_DUMP_MAX_TEMP_BUFFER_SIZE] = {0, };
+
+	ring_buf = &g_ring_buf;
+
+	va_start(args, fmt);
+	len = vsnprintf(tmp_buf, DHD_LOG_DUMP_MAX_TEMP_BUFFER_SIZE, fmt, args);
+	/* Non ANSI C99 compliant returns -1,
+	 * ANSI compliant return len >= DHD_LOG_DUMP_MAX_TEMP_BUFFER_SIZE
+	 */
+	va_end(args);
+	if (len < 0) {
+		return;
+	}
+
+	if (len >= DHD_LOG_DUMP_MAX_TEMP_BUFFER_SIZE) {
+		len = DHD_LOG_DUMP_MAX_TEMP_BUFFER_SIZE - 1;
+		tmp_buf[len] = '\0';
+	}
+
+	if (ring_buf->dhd_pub) {
+		dhd_pub_t *dhdp = (dhd_pub_t *)ring_buf->dhd_pub;
+		if (type == DRIVER_LOG_RING_ID || type == FW_VERBOSE_RING_ID ||
+				type == ROAM_STATS_RING_ID) {
+			if (DBG_RING_ACTIVE(dhdp, type)) {
+				dhd_os_push_push_ring_data(dhdp, type,
+						tmp_buf, strlen(tmp_buf));
+				return;
+			}
+		}
+	}
+	return;
+}
+
+#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
+void dhd_debug_dump_get_section_len(dhd_pub_t *dhdp, uint32 sec_len[])
+{
+	sec_len[LOG_DUMP_SECTION_TIMESTAMP] = dhd_get_time_str_len();
+#ifdef EWP_ECNTRS_LOGGING
+	sec_len[LOG_DUMP_SECTION_ECNTRS] = dhd_get_ecntrs_len(NULL, dhdp);
+#endif /* EWP_ECNTRS_LOGGING */
+	sec_len[LOG_DUMP_SECTION_DHD_DUMP] = dhd_get_dhd_dump_len(NULL, dhdp);
+#if defined(BCMPCIE)
+	sec_len[LOG_DUMP_SECTION_EXT_TRAP] = dhd_get_ext_trap_len(NULL, dhdp);
+#endif /* BCMPCIE */
+
+#if defined(DHD_FW_COREDUMP) && defined(DNGL_EVENT_SUPPORT)
+	sec_len[LOG_DUMP_SECTION_HEALTH_CHK] = dhd_get_health_chk_len(NULL, dhdp);
+#endif
+	sec_len[LOG_DUMP_SECTION_COOKIE] = dhd_get_cookie_log_len(NULL, dhdp);
+#ifdef DHD_DUMP_PCIE_RINGS
+	sec_len[LOG_DUMP_SECTION_RING] = dhd_get_flowring_len(NULL, dhdp);
+#endif
+#ifdef DHD_STATUS_LOGGING
+	sec_len[LOG_DUMP_SECTION_STATUS] = dhd_get_status_log_len(NULL, dhdp);
+#endif /* DHD_STATUS_LOGGING */
+#ifdef EWP_RTT_LOGGING
+	sec_len[LOG_DUMP_SECTION_RTT] = dhd_get_rtt_len(NULL, dhdp);
+#endif /* EWP_RTT_LOGGING */
+#ifdef DHD_MAP_PKTID_LOGGING
+	sec_len[LOG_DUMP_SECTION_PKTID_MAP_LOG] =
+		dhd_get_pktid_map_logging_len(NULL, dhdp, TRUE);
+	sec_len[LOG_DUMP_SECTION_PKTID_UNMAP_LOG] =
+		dhd_get_pktid_map_logging_len(NULL, dhdp, FALSE);
+#endif /* DHD_MAP_PKTID_LOGGING */
+
+	DHD_ERROR(("%s: TS:%d ECNTRS:%d DHD_DUMP:%d ETRAP:%d"
+		" HCK:%d CKI:%d FLOW:%d STATUS:%d RTT:%d PKTID_MAP:%d PKTID_UNMAP:%d\n",
+		__func__, sec_len[LOG_DUMP_SECTION_TIMESTAMP], sec_len[LOG_DUMP_SECTION_ECNTRS],
+		sec_len[LOG_DUMP_SECTION_DHD_DUMP], sec_len[LOG_DUMP_SECTION_EXT_TRAP],
+		sec_len[LOG_DUMP_SECTION_HEALTH_CHK], sec_len[LOG_DUMP_SECTION_COOKIE],
+		sec_len[LOG_DUMP_SECTION_RING], sec_len[LOG_DUMP_SECTION_STATUS],
+		sec_len[LOG_DUMP_SECTION_RTT], sec_len[LOG_DUMP_SECTION_PKTID_MAP_LOG],
+		sec_len[LOG_DUMP_SECTION_PKTID_UNMAP_LOG]));
+	return;
+}
+
+int dhd_debug_dump_buf_alloc(dhd_pub_t *dhdp, int id, char* name, int size)
+{
+	dhd_dbg_t *dbg = dhdp->dbg;
+	dhd_dbg_ring_t *ring = &dbg->dbg_rings[id];
+	char *buf = NULL;
+
+	if (!ring->ring_buf) {
+		buf = VMALLOCZ(dhdp->osh, size);
+		if (!buf) {
+			DHD_ERROR(("%s: Failed to alloc id:%d, size:%d\n", __func__, id, size));
+			return BCME_NOMEM;
+		}
+		dhd_dbg_ring_set_buf(dhdp, &dbg->dbg_rings[id], buf);
+		DHD_ERROR(("%s: success to allocate ring id:%d name:%s\n", __func__, id, name));
+	} else {
+		DHD_ERROR(("%s: already allocated id:%d name:%s\n", __func__, id, name));
+	}
+
+	return BCME_OK;
+}
+
+int dhd_debug_dump_to_ring(dhd_pub_t *dhdp)
+{
+	dhd_dbg_t *dbg = dhdp->dbg;
+	dhd_dbg_ring_t *dbg_ring;
+	int ret = BCME_OK;
+	int ring_num, id;
+	uint32 sec_len[LOG_DUMP_SECTION_MAX] = {0};
+	dhd_dbg_ring_status_t ring_status;
+	uint32 sync_retry;
+	unsigned long flags = 0;
+
+	ret = dhd_debug_dump_buf_alloc(dhdp, DEBUG_DUMP_RING1_ID,
+		DEBUG_DUMP_RING1_NAME, DEBUG_DUMP_RING1_SIZE);
+	if (ret) {
+		return ret;
+	}
+
+	ret = dhd_debug_dump_buf_alloc(dhdp, DEBUG_DUMP_RING2_ID,
+		DEBUG_DUMP_RING2_NAME, DEBUG_DUMP_RING2_SIZE);
+	if (ret) {
+		return ret;
+	}
+
+#ifdef DHD_MAP_PKTID_LOGGING
+	dhd_pktid_logging_dump(dhdp);
+#endif /* DHD_MAP_PKTID_LOGGING */
+	dhd_debug_dump_get_section_len(dhdp, sec_len);
+
+	ring_num = dhd_debug_dump_get_ring_num(LOG_DUMP_SECTION_TIMESTAMP);
+	if (dhd_print_time_str(NULL, NULL, sec_len[LOG_DUMP_SECTION_TIMESTAMP], &ring_num)) {
+		DHD_ERROR(("Error section: dhd_print_time_str\n"));
+	}
+#ifdef EWP_ECNTRS_LOGGING
+	if (dhd_print_ecntrs_data(NULL, dhdp, NULL, NULL,
+		sec_len[LOG_DUMP_SECTION_ECNTRS], NULL)) {
+		DHD_ERROR(("Error section: ECNTRS\n"));
+	}
+#endif /* EWP_ECNTRS_LOGGING */
+
+#ifdef DHD_STATUS_LOGGING
+	ring_num = dhd_debug_dump_get_ring_num(LOG_DUMP_SECTION_STATUS);
+	if (dhd_print_status_log_data(NULL, dhdp, NULL, NULL,
+		sec_len[LOG_DUMP_SECTION_STATUS], &ring_num)) {
+		DHD_ERROR(("Error section: STATUS_LOG\n"));
+	}
+#endif /* DHD_STATUS_LOGGING */
+#ifdef EWP_RTT_LOGGING
+	if (dhd_print_rtt_data(NULL, dhdp, NULL, NULL,
+		sec_len[LOG_DUMP_SECTION_RTT], NULL)) {
+		DHD_ERROR(("Error section: RTT_LOG\n"));
+	}
+#endif /* EWP_RTT_LOGGING */
+#ifdef DHD_MAP_PKTID_LOGGING
+	ring_num = dhd_debug_dump_get_ring_num(LOG_DUMP_SECTION_PKTID_MAP_LOG);
+	if (dhd_print_pktid_map_log_data(NULL, dhdp, NULL, NULL,
+		sec_len[LOG_DUMP_SECTION_PKTID_MAP_LOG], &ring_num, TRUE)) {
+		DHD_ERROR(("Error section: PKTID_MAP_LOG\n"));
+	}
+	ring_num = dhd_debug_dump_get_ring_num(LOG_DUMP_SECTION_PKTID_UNMAP_LOG);
+	if (dhd_print_pktid_map_log_data(NULL, dhdp, NULL, NULL,
+		sec_len[LOG_DUMP_SECTION_PKTID_UNMAP_LOG], &ring_num, FALSE)) {
+		DHD_ERROR(("Error section: PKTID_UNMAP_LOG\n"));
+	}
+#endif /* DHD_MAP_PKTID_LOGGING */
+	ring_num = dhd_debug_dump_get_ring_num(LOG_DUMP_SECTION_DHD_DUMP);
+	if (dhd_print_dump_data(NULL, dhdp, NULL, NULL,
+		sec_len[LOG_DUMP_SECTION_DHD_DUMP], &ring_num)) {
+		DHD_ERROR(("Error section: DHD_DUMP\n"));
+	}
+#if defined(BCMPCIE)
+	ring_num = dhd_debug_dump_get_ring_num(LOG_DUMP_SECTION_EXT_TRAP);
+	if (dhd_print_ext_trap_data(NULL, dhdp, NULL, NULL,
+		sec_len[LOG_DUMP_SECTION_EXT_TRAP], &ring_num)) {
+		DHD_ERROR(("Error section: EXT TRAP\n"));
+	}
+#endif /* BCMPCIE */
+#if defined(DHD_FW_COREDUMP) && defined(DNGL_EVENT_SUPPORT)
+	ring_num = dhd_debug_dump_get_ring_num(LOG_DUMP_SECTION_HEALTH_CHK);
+	if (dhd_print_health_chk_data(NULL, dhdp, NULL, NULL,
+		sec_len[LOG_DUMP_SECTION_HEALTH_CHK], &ring_num)) {
+		DHD_ERROR(("Error section: HEALTH CHECK\n"));
+	}
+#endif
+	ring_num = dhd_debug_dump_get_ring_num(LOG_DUMP_SECTION_COOKIE);
+	if (dhd_print_cookie_data(NULL, dhdp, NULL, NULL,
+		sec_len[LOG_DUMP_SECTION_COOKIE], &ring_num)) {
+		DHD_ERROR(("Error section: COOKIE DATA\n"));
+	}
+#ifdef DHD_DUMP_PCIE_RINGS
+	ring_num = dhd_debug_dump_get_ring_num(LOG_DUMP_SECTION_RING);
+	if (dhd_print_flowring_data(NULL, dhdp, NULL, NULL,
+		sec_len[LOG_DUMP_SECTION_RING], &ring_num)) {
+		DHD_ERROR(("Error section: FLOWRING_DUMP\n"));
+	}
+#endif
+	for (id = DEBUG_RING_ID_INVALID + 1; id < DEBUG_RING_ID_MAX; id++) {
+		dbg_ring = &dbg->dbg_rings[id];
+		if (VALID_RING(dbg_ring->id)) {
+			/* To sync up with the ringbuffer in legacy HAL */
+			dhd_os_trigger_get_ring_data(dhdp, dbg_ring->name);
+
+			sync_retry = 0;
+			while (sync_retry < DHD_DEBUG_DUMP_MAX_SYNC_CNT) {
+				DHD_DBG_RING_LOCK(dbg_ring->lock, flags);
+				__dhd_dbg_get_ring_status(dbg_ring, &ring_status);
+				DHD_DBG_RING_UNLOCK(dbg_ring->lock, flags);
+				if (ring_status.written_bytes == ring_status.read_bytes) {
+					break;
+				} else {
+					OSL_SLEEP(50);
+				}
+				sync_retry++;
+			}
+			DHD_ERROR(("%s: ring sync up name:%s w/r bytes(%u/%u) retry:%d\n",
+				__func__, dbg_ring->name, ring_status.written_bytes,
+				ring_status.read_bytes, sync_retry));
+		}
+	}
+	return ret;
+}
+#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_debug.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_debug.h
@@ -0,0 +1,962 @@
+/*
+ * DHD debugability header file
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef _dhd_debug_h_
+#define _dhd_debug_h_
+#include <event_log.h>
+#include <bcmutils.h>
+#include <dhd_dbg_ring.h>
+
+enum {
+	/* Feature set */
+	DBG_MEMORY_DUMP_SUPPORTED = (1 << (0)), /* Memory dump of FW */
+	DBG_PER_PACKET_TX_RX_STATUS_SUPPORTED = (1 << (1)), /* PKT Status */
+	DBG_CONNECT_EVENT_SUPPORTED = (1 << (2)), /* Connectivity Event */
+	DBG_POWER_EVENT_SUPOORTED = (1 << (3)), /* POWER of Driver */
+	DBG_WAKE_LOCK_SUPPORTED = (1 << (4)), /* WAKE LOCK of Driver */
+	DBG_VERBOSE_LOG_SUPPORTED = (1 << (5)), /* verbose log of FW */
+	DBG_HEALTH_CHECK_SUPPORTED = (1 << (6)), /* monitor the health of FW */
+	DBG_DRIVER_DUMP_SUPPORTED = (1 << (7)), /* dumps driver state */
+	DBG_PACKET_FATE_SUPPORTED = (1 << (8)), /* tracks connection packets' fate */
+	DBG_NAN_EVENT_SUPPORTED = (1 << (9)), /* NAN Events */
+	DBG_PACKET_LOG_SUPPORTED = (1 << (10)), /* Packet log with dbgring */
+};
+
+enum {
+	/* set for binary entries */
+	DBG_RING_ENTRY_FLAGS_HAS_BINARY = (1 << (0)),
+	/* set if 64 bits timestamp is present */
+	DBG_RING_ENTRY_FLAGS_HAS_TIMESTAMP = (1 << (1))
+};
+
+enum {
+	/* Verbose logging level to set for each debug ring buffer */
+	RING_LOG_LEVEL_NONE = 0,
+	RING_LOG_LEVEL_DEFAULT = 1,
+	RING_LOG_LEVEL_VERBOSE = 2,
+	RING_LOG_LEVEL_EXCESSIVE = 3
+};
+
+/* firmware verbose ring, ring id 1 */
+#define FW_VERBOSE_RING_NAME		"fw_verbose"
+#define FW_VERBOSE_RING_SIZE		(256 * 1024)
+/* firmware event ring, ring id 2 */
+#define FW_EVENT_RING_NAME		"fw_event"
+#define FW_EVENT_RING_SIZE		(64 * 1024)
+/* DHD connection event ring, ring id 3 */
+#define DHD_EVENT_RING_NAME		"dhd_event"
+#define DHD_EVENT_RING_SIZE		(64 * 1024)
+/* NAN event ring, ring id 4 */
+#define NAN_EVENT_RING_NAME		"nan_event"
+#define NAN_EVENT_RING_SIZE		(64 * 1024)
+
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+/* DHD driver log ring */
+#define DRIVER_LOG_RING_NAME		"driver_log"
+#define DRIVER_LOG_RING_SIZE		(256 * 1024)
+/* ROAM stats log ring */
+#define ROAM_STATS_RING_NAME		"roam_stats"
+#define ROAM_STATS_RING_SIZE		(64 * 1024)
+
+#define DEBUG_DUMP_RING1_NAME		"debug_dump1_"
+#define DEBUG_DUMP_RING1_SIZE		(2 * 1024 * 1024)
+
+#define DEBUG_DUMP_RING2_NAME		"debug_dump2_"
+#define DEBUG_DUMP_RING2_SIZE		(2 * 1024 * 1024)
+
+#define MEM_DUMP_RING_NAME		"mem_dump"
+#define MEM_DUMP_RING_SIZE		(3 * 1024 * 1024)
+
+#define DHD_DEBUG_DUMP_NETLINK_MAX	(1024 * 8)
+#define DHD_DEBUG_DUMP_MAX_SYNC_CNT	5u
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
+
+/* Packet log ring, ring id 7 */
+#ifdef DHD_PKT_LOGGING_DBGRING
+#define DHD_PACKET_LOG_RING_NAME	"packet_log"
+#define DHD_PACKET_LOG_RING_PKTS	MIN_PKTLOG_LEN
+#define DHD_PACKET_LOG_RING_SUSPEND_THRESHOLD	\
+	(DHD_PACKET_LOG_RING_PKTS * 8u / 10u)
+#define DHD_PACKET_LOG_RING_RESUME_THRESHOLD	\
+	(DHD_PACKET_LOG_RING_PKTS * 2u / 10u)
+#define DHD_PACKET_LOG_RING_SIZE	\
+	(DHD_PACKET_LOG_RING_PKTS * sizeof(dhd_pktlog_ring_info_t))
+#endif /* DHD_PKT_LOGGING_DBGRING */
+
+#define TLV_LOG_SIZE(tlv) ((tlv) ? (sizeof(tlv_log) + (tlv)->len) : 0)
+
+#define TLV_LOG_NEXT(tlv) \
+	((tlv) ? ((tlv_log *)((uint8 *)tlv + TLV_LOG_SIZE(tlv))) : 0)
+
+#define DBG_RING_STATUS_SIZE (sizeof(dhd_dbg_ring_status_t))
+
+#define VALID_RING(id)	\
+	((id > DEBUG_RING_ID_INVALID) && (id < DEBUG_RING_ID_MAX))
+
+#ifdef DEBUGABILITY
+#define DBG_RING_ACTIVE(dhdp, ring_id) \
+	((dhdp)->dbg && (dhdp)->dbg->dbg_rings[(ring_id)].state == RING_ACTIVE)
+#else
+#define DBG_RING_ACTIVE(dhdp, ring_id) 0
+#endif /* DEBUGABILITY */
+
+enum {
+	/* driver receive association command from kernel */
+	WIFI_EVENT_ASSOCIATION_REQUESTED	= 0,
+	WIFI_EVENT_AUTH_COMPLETE,
+	WIFI_EVENT_ASSOC_COMPLETE,
+	/* received firmware event indicating auth frames are sent */
+	WIFI_EVENT_FW_AUTH_STARTED,
+	/* received firmware event indicating assoc frames are sent */
+	WIFI_EVENT_FW_ASSOC_STARTED,
+	/* received firmware event indicating reassoc frames are sent */
+	WIFI_EVENT_FW_RE_ASSOC_STARTED,
+	WIFI_EVENT_DRIVER_SCAN_REQUESTED,
+	WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND,
+	WIFI_EVENT_DRIVER_SCAN_COMPLETE,
+	WIFI_EVENT_G_SCAN_STARTED,
+	WIFI_EVENT_G_SCAN_COMPLETE,
+	WIFI_EVENT_DISASSOCIATION_REQUESTED,
+	WIFI_EVENT_RE_ASSOCIATION_REQUESTED,
+	WIFI_EVENT_ROAM_REQUESTED,
+	/* received beacon from AP (event enabled only in verbose mode) */
+	WIFI_EVENT_BEACON_RECEIVED,
+	/* firmware has triggered a roam scan (not g-scan) */
+	WIFI_EVENT_ROAM_SCAN_STARTED,
+	/* firmware has completed a roam scan (not g-scan) */
+	WIFI_EVENT_ROAM_SCAN_COMPLETE,
+	/* firmware has started searching for roam candidates (with reason =xx) */
+	WIFI_EVENT_ROAM_SEARCH_STARTED,
+	/* firmware has stopped searching for roam candidates (with reason =xx) */
+	WIFI_EVENT_ROAM_SEARCH_STOPPED,
+	WIFI_EVENT_UNUSED_0,
+	/* received channel switch anouncement from AP */
+	WIFI_EVENT_CHANNEL_SWITCH_ANOUNCEMENT,
+	/* fw start transmit eapol frame, with EAPOL index 1-4 */
+	WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_START,
+	/* fw gives up eapol frame, with rate, success/failure and number retries */
+	WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP,
+	/* kernel queue EAPOL for transmission in driver with EAPOL index 1-4 */
+	WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED,
+	/* with rate, regardless of the fact that EAPOL frame is accepted or
+	 * rejected by firmware
+	 */
+	WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED,
+	WIFI_EVENT_UNUSED_1,
+	/* with rate, and eapol index, driver has received */
+	/* EAPOL frame and will queue it up to wpa_supplicant */
+	WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED,
+	/* with success/failure, parameters */
+	WIFI_EVENT_BLOCK_ACK_NEGOTIATION_COMPLETE,
+	WIFI_EVENT_BT_COEX_BT_SCO_START,
+	WIFI_EVENT_BT_COEX_BT_SCO_STOP,
+	/* for paging/scan etc..., when BT starts transmiting twice per BT slot */
+	WIFI_EVENT_BT_COEX_BT_SCAN_START,
+	WIFI_EVENT_BT_COEX_BT_SCAN_STOP,
+	WIFI_EVENT_BT_COEX_BT_HID_START,
+	WIFI_EVENT_BT_COEX_BT_HID_STOP,
+	/* firmware sends auth frame in roaming to next candidate */
+	WIFI_EVENT_ROAM_AUTH_STARTED,
+	/* firmware receive auth confirm from ap */
+	WIFI_EVENT_ROAM_AUTH_COMPLETE,
+	/* firmware sends assoc/reassoc frame in */
+	WIFI_EVENT_ROAM_ASSOC_STARTED,
+	/* firmware receive assoc/reassoc confirm from ap */
+	WIFI_EVENT_ROAM_ASSOC_COMPLETE,
+	/* firmware sends stop G_SCAN */
+	WIFI_EVENT_G_SCAN_STOP,
+	/* firmware indicates G_SCAN scan cycle started */
+	WIFI_EVENT_G_SCAN_CYCLE_STARTED,
+	/* firmware indicates G_SCAN scan cycle completed */
+	WIFI_EVENT_G_SCAN_CYCLE_COMPLETED,
+	/* firmware indicates G_SCAN scan start for a particular bucket */
+	WIFI_EVENT_G_SCAN_BUCKET_STARTED,
+	/* firmware indicates G_SCAN scan completed for particular bucket */
+	WIFI_EVENT_G_SCAN_BUCKET_COMPLETED,
+	/* Event received from firmware about G_SCAN scan results being available */
+	WIFI_EVENT_G_SCAN_RESULTS_AVAILABLE,
+	/* Event received from firmware with G_SCAN capabilities */
+	WIFI_EVENT_G_SCAN_CAPABILITIES,
+	/* Event received from firmware when eligible candidate is found */
+	WIFI_EVENT_ROAM_CANDIDATE_FOUND,
+	/* Event received from firmware when roam scan configuration gets enabled or disabled */
+	WIFI_EVENT_ROAM_SCAN_CONFIG,
+	/* firmware/driver timed out authentication */
+	WIFI_EVENT_AUTH_TIMEOUT,
+	/* firmware/driver timed out association */
+	WIFI_EVENT_ASSOC_TIMEOUT,
+	/* firmware/driver encountered allocation failure */
+	WIFI_EVENT_MEM_ALLOC_FAILURE,
+	/* driver added a PNO network in firmware */
+	WIFI_EVENT_DRIVER_PNO_ADD,
+	/* driver removed a PNO network in firmware */
+	WIFI_EVENT_DRIVER_PNO_REMOVE,
+	/* driver received PNO networks found indication from firmware */
+	WIFI_EVENT_DRIVER_PNO_NETWORK_FOUND,
+	/* driver triggered a scan for PNO networks */
+	WIFI_EVENT_DRIVER_PNO_SCAN_REQUESTED,
+	/* driver received scan results of PNO networks */
+	WIFI_EVENT_DRIVER_PNO_SCAN_RESULT_FOUND,
+	/* driver updated scan results from PNO candidates to cfg */
+	WIFI_EVENT_DRIVER_PNO_SCAN_COMPLETE
+};
+
+enum {
+	WIFI_TAG_VENDOR_SPECIFIC = 0, /* take a byte stream as parameter */
+	WIFI_TAG_BSSID, /* takes a 6 bytes MAC address as parameter */
+	WIFI_TAG_ADDR, /* takes a 6 bytes MAC address as parameter */
+	WIFI_TAG_SSID, /* takes a 32 bytes SSID address as parameter */
+	WIFI_TAG_STATUS, /* takes an integer as parameter */
+	WIFI_TAG_CHANNEL_SPEC, /* takes one or more wifi_channel_spec as parameter */
+	WIFI_TAG_WAKE_LOCK_EVENT, /* takes a wake_lock_event struct as parameter */
+	WIFI_TAG_ADDR1, /* takes a 6 bytes MAC address as parameter */
+	WIFI_TAG_ADDR2, /* takes a 6 bytes MAC address as parameter */
+	WIFI_TAG_ADDR3, /* takes a 6 bytes MAC address as parameter */
+	WIFI_TAG_ADDR4, /* takes a 6 bytes MAC address as parameter */
+	WIFI_TAG_TSF, /* take a 64 bits TSF value as parameter */
+	WIFI_TAG_IE,
+	/* take one or more specific 802.11 IEs parameter, IEs are in turn
+	 * indicated in TLV format as per 802.11 spec
+	 */
+	WIFI_TAG_INTERFACE,	/* take interface name as parameter */
+	WIFI_TAG_REASON_CODE,	/* take a reason code as per 802.11 as parameter */
+	WIFI_TAG_RATE_MBPS,	/* take a wifi rate in 0.5 mbps */
+	WIFI_TAG_REQUEST_ID,	/* take an integer as parameter */
+	WIFI_TAG_BUCKET_ID,	/* take an integer as parameter */
+	WIFI_TAG_GSCAN_PARAMS,	/* takes a wifi_scan_cmd_params struct as parameter */
+	WIFI_TAG_GSCAN_CAPABILITIES, /* takes a wifi_gscan_capabilities struct as parameter */
+	WIFI_TAG_SCAN_ID,	/* take an integer as parameter */
+	WIFI_TAG_RSSI,		/* takes s16 as parameter */
+	WIFI_TAG_CHANNEL,	/* takes u16 as parameter */
+	WIFI_TAG_LINK_ID,	/* take an integer as parameter */
+	WIFI_TAG_LINK_ROLE,	/* take an integer as parameter */
+	WIFI_TAG_LINK_STATE,	/* take an integer as parameter */
+	WIFI_TAG_LINK_TYPE,	/* take an integer as parameter */
+	WIFI_TAG_TSCO,		/* take an integer as parameter */
+	WIFI_TAG_RSCO,		/* take an integer as parameter */
+	WIFI_TAG_EAPOL_MESSAGE_TYPE /* take an integer as parameter */
+};
+
+/* NAN  events */
+typedef enum {
+	NAN_EVENT_INVALID = 0,
+	NAN_EVENT_CLUSTER_STARTED = 1,
+	NAN_EVENT_CLUSTER_JOINED = 2,
+	NAN_EVENT_CLUSTER_MERGED = 3,
+	NAN_EVENT_ROLE_CHANGED = 4,
+	NAN_EVENT_SCAN_COMPLETE = 5,
+	NAN_EVENT_STATUS_CHNG  = 6,
+	/* ADD new events before this line */
+	NAN_EVENT_MAX
+} nan_event_id_t;
+
+typedef struct {
+    uint16 tag;
+    uint16 len; /* length of value */
+    uint8 value[0];
+} tlv_log;
+
+typedef struct per_packet_status_entry {
+    uint8 flags;
+    uint8 tid; /* transmit or received tid */
+    uint16 MCS; /* modulation and bandwidth */
+	/*
+	* TX: RSSI of ACK for that packet
+	* RX: RSSI of packet
+	*/
+    uint8 rssi;
+    uint8 num_retries; /* number of attempted retries */
+    uint16 last_transmit_rate; /* last transmit rate in .5 mbps */
+	 /* transmit/reeive sequence for that MPDU packet */
+    uint16 link_layer_transmit_sequence;
+	/*
+	* TX: firmware timestamp (us) when packet is queued within firmware buffer
+	* for SDIO/HSIC or into PCIe buffer
+	* RX : firmware receive timestamp
+	*/
+    uint64 firmware_entry_timestamp;
+	/*
+	* firmware timestamp (us) when packet start contending for the
+	* medium for the first time, at head of its AC queue,
+	* or as part of an MPDU or A-MPDU. This timestamp is not updated
+	* for each retry, only the first transmit attempt.
+	*/
+    uint64 start_contention_timestamp;
+	/*
+	* fimrware timestamp (us) when packet is successfully transmitted
+	* or aborted because it has exhausted its maximum number of retries
+	*/
+	uint64 transmit_success_timestamp;
+	/*
+	* packet data. The length of packet data is determined by the entry_size field of
+	* the wifi_ring_buffer_entry structure. It is expected that first bytes of the
+	* packet, or packet headers only (up to TCP or RTP/UDP headers) will be copied into the ring
+	*/
+    uint8 *data;
+} per_packet_status_entry_t;
+
+#if defined(LINUX)
+#define PACKED_STRUCT __attribute__ ((packed))
+#else
+#define PACKED_STRUCT
+#endif
+
+#if defined(LINUX)
+typedef struct log_conn_event {
+    uint16 event;
+    tlv_log tlvs[0];
+	/*
+	* separate parameter structure per event to be provided and optional data
+	* the event_data is expected to include an official android part, with some
+	* parameter as transmit rate, num retries, num scan result found etc...
+	* as well, event_data can include a vendor proprietary part which is
+	* understood by the developer only.
+	*/
+} PACKED_STRUCT log_conn_event_t;
+#endif /* defined(LINUX) */
+
+/*
+ * Ring buffer name for power events ring. note that power event are extremely frequents
+ * and thus should be stored in their own ring/file so as not to clobber connectivity events
+ */
+
+typedef struct wake_lock_event {
+    uint32 status; /* 0 taken, 1 released */
+    uint32 reason; /* reason why this wake lock is taken */
+    char *name; /* null terminated */
+} wake_lock_event_t;
+
+typedef struct wifi_power_event {
+    uint16 event;
+    tlv_log *tlvs;
+} wifi_power_event_t;
+
+#define NAN_EVENT_VERSION 1
+typedef struct log_nan_event {
+    uint8 version;
+    uint8 pad;
+    uint16 event;
+    tlv_log *tlvs;
+} log_nan_event_t;
+
+/* entry type */
+enum {
+	DBG_RING_ENTRY_EVENT_TYPE = 1,
+	DBG_RING_ENTRY_PKT_TYPE,
+	DBG_RING_ENTRY_WAKE_LOCK_EVENT_TYPE,
+	DBG_RING_ENTRY_POWER_EVENT_TYPE,
+	DBG_RING_ENTRY_DATA_TYPE,
+	DBG_RING_ENTRY_NAN_EVENT_TYPE
+};
+
+struct log_level_table {
+	int log_level;
+	uint16 tag;
+	char *desc;
+};
+
+#ifdef OEM_ANDROID
+/*
+ * Assuming that the Ring lock is mutex, bailing out if the
+ * callers are from atomic context. On a long term, one has to
+ * schedule a job to execute in sleepable context so that
+ * contents are pushed to the ring.
+ */
+#define DBG_EVENT_LOG(dhdp, connect_state)					\
+{										\
+	do {									\
+		uint16 state = connect_state;					\
+		if (CAN_SLEEP() && DBG_RING_ACTIVE(dhdp, DHD_EVENT_RING_ID))			\
+			dhd_os_push_push_ring_data(dhdp, DHD_EVENT_RING_ID,	\
+				&state, sizeof(state));				\
+	} while (0);								\
+}
+#else
+#define DBG_EVENT_LOG(dhd, connect_state)
+#endif /* !OEM_ANDROID */
+
+/*
+ * Packet logging - HAL specific data
+ * XXX: These should be moved to wl_cfgvendor.h
+ */
+
+#define MD5_PREFIX_LEN				4
+#define MAX_FATE_LOG_LEN			32
+#define MAX_FRAME_LEN_ETHERNET		1518
+#define MAX_FRAME_LEN_80211_MGMT	2352 /* 802.11-2012 Fig. 8-34 */
+
+typedef enum {
+	/* Sent over air and ACKed. */
+	TX_PKT_FATE_ACKED,
+
+	/* Sent over air but not ACKed. (Normal for broadcast/multicast.) */
+	TX_PKT_FATE_SENT,
+
+	/* Queued within firmware, but not yet sent over air. */
+	TX_PKT_FATE_FW_QUEUED,
+
+	/*
+	 * Dropped by firmware as invalid. E.g. bad source address,
+	 * bad checksum, or invalid for current state.
+	 */
+	TX_PKT_FATE_FW_DROP_INVALID,
+
+	/* Dropped by firmware due to lifetime expiration. */
+	TX_PKT_FATE_FW_DROP_EXPTIME,
+
+	/*
+	 * Dropped by firmware for any other reason. Includes
+	 * frames that were sent by driver to firmware, but
+	 * unaccounted for by firmware.
+	 */
+	TX_PKT_FATE_FW_DROP_OTHER,
+
+	/* Queued within driver, not yet sent to firmware. */
+	TX_PKT_FATE_DRV_QUEUED,
+
+	/*
+	 * Dropped by driver as invalid. E.g. bad source address,
+	 * or invalid for current state.
+	 */
+	TX_PKT_FATE_DRV_DROP_INVALID,
+
+	/* Dropped by driver due to lack of buffer space. */
+	TX_PKT_FATE_DRV_DROP_NOBUFS,
+
+	/*  Dropped by driver for any other reason. */
+	TX_PKT_FATE_DRV_DROP_OTHER,
+
+	/* Packet free by firmware. */
+	TX_PKT_FATE_FW_PKT_FREE,
+
+	/* Firmware dropped the frame after suppress retries reached max */
+	TX_PKT_FATE_FW_MAX_SUP_RETR,
+
+	/* Firmware forced packet lifetime expiry */
+	TX_PKT_FATE_FW_FORCED_EXPIRED,
+
+#ifdef DHD_PKT_LOGGING_DBGRING
+	/* Indicate to wait for updating txfate. */
+	TX_PKT_FATE_DRV_WAIT_UPDATE = 0x80000000,
+#endif /* DHD_PKT_LOGGING_DBGRING */
+	} wifi_tx_packet_fate;
+
+typedef enum {
+	/* Valid and delivered to network stack (e.g., netif_rx()). */
+	RX_PKT_FATE_SUCCESS,
+
+	/* Queued within firmware, but not yet sent to driver. */
+	RX_PKT_FATE_FW_QUEUED,
+
+	/* Dropped by firmware due to host-programmable filters. */
+	RX_PKT_FATE_FW_DROP_FILTER,
+
+	/*
+	 * Dropped by firmware as invalid. E.g. bad checksum,
+	 * decrypt failed, or invalid for current state.
+	 */
+	RX_PKT_FATE_FW_DROP_INVALID,
+
+	/* Dropped by firmware due to lack of buffer space. */
+	RX_PKT_FATE_FW_DROP_NOBUFS,
+
+	/* Dropped by firmware for any other reason. */
+	RX_PKT_FATE_FW_DROP_OTHER,
+
+	/* Queued within driver, not yet delivered to network stack. */
+	RX_PKT_FATE_DRV_QUEUED,
+
+	/* Dropped by driver due to filter rules. */
+	RX_PKT_FATE_DRV_DROP_FILTER,
+
+	/* Dropped by driver as invalid. E.g. not permitted in current state. */
+	RX_PKT_FATE_DRV_DROP_INVALID,
+
+	/* Dropped by driver due to lack of buffer space. */
+	RX_PKT_FATE_DRV_DROP_NOBUFS,
+
+	/* Dropped by driver for any other reason. */
+	RX_PKT_FATE_DRV_DROP_OTHER,
+
+	/* Indicate RX Host Wake up packet. */
+	RX_PKT_FATE_WAKE_PKT,
+
+	} wifi_rx_packet_fate;
+
+typedef enum {
+	FRAME_TYPE_UNKNOWN,
+	FRAME_TYPE_ETHERNET_II,
+	FRAME_TYPE_80211_MGMT,
+	} frame_type;
+
+typedef struct wifi_frame_info {
+	/*
+	 * The type of MAC-layer frame that this frame_info holds.
+	 * - For data frames, use FRAME_TYPE_ETHERNET_II.
+	 * - For management frames, use FRAME_TYPE_80211_MGMT.
+	 * - If the type of the frame is unknown, use FRAME_TYPE_UNKNOWN.
+	 */
+	frame_type payload_type;
+
+	/*
+	 * The number of bytes included in |frame_content|. If the frame
+	 * contents are missing (e.g. RX frame dropped in firmware),
+	 * |frame_len| should be set to 0.
+	 */
+	size_t frame_len;
+
+	/*
+	 * Host clock when this frame was received by the driver (either
+	 *	outbound from the host network stack, or inbound from the
+	 *	firmware).
+	 *	- The timestamp should be taken from a clock which includes time
+	 *	  the host spent suspended (e.g. ktime_get_boottime()).
+	 *	- If no host timestamp is available (e.g. RX frame was dropped in
+	 *	  firmware), this field should be set to 0.
+	 */
+	uint32 driver_timestamp_usec;
+
+	/*
+	 * Firmware clock when this frame was received by the firmware
+	 *	(either outbound from the host, or inbound from a remote
+	 *	station).
+	 *	- The timestamp should be taken from a clock which includes time
+	 *	  firmware spent suspended (if applicable).
+	 *	- If no firmware timestamp is available (e.g. TX frame was
+	 *	  dropped by driver), this field should be set to 0.
+	 *	- Consumers of |frame_info| should _not_ assume any
+	 *	  synchronization between driver and firmware clocks.
+	 */
+	uint32 firmware_timestamp_usec;
+
+	/*
+	 * Actual frame content.
+	 * - Should be provided for TX frames originated by the host.
+	 * - Should be provided for RX frames received by the driver.
+	 * - Optionally provided for TX frames originated by firmware. (At
+	 *   discretion of HAL implementation.)
+	 * - Optionally provided for RX frames dropped in firmware. (At
+	 *   discretion of HAL implementation.)
+	 * - If frame content is not provided, |frame_len| should be set
+	 *   to 0.
+	 */
+	union {
+		char ethernet_ii[MAX_FRAME_LEN_ETHERNET];
+		char ieee_80211_mgmt[MAX_FRAME_LEN_80211_MGMT];
+	} frame_content;
+} wifi_frame_info_t;
+
+typedef struct wifi_tx_report {
+	/*
+	 * Prefix of MD5 hash of |frame_inf.frame_content|. If frame
+	 * content is not provided, prefix of MD5 hash over the same data
+	 * that would be in frame_content, if frame content were provided.
+	 */
+	char md5_prefix[MD5_PREFIX_LEN];
+	wifi_tx_packet_fate fate;
+	wifi_frame_info_t frame_inf;
+} wifi_tx_report_t;
+
+typedef struct wifi_rx_report {
+	/*
+	 * Prefix of MD5 hash of |frame_inf.frame_content|. If frame
+	 * content is not provided, prefix of MD5 hash over the same data
+	 * that would be in frame_content, if frame content were provided.
+	 */
+	char md5_prefix[MD5_PREFIX_LEN];
+	wifi_rx_packet_fate fate;
+	wifi_frame_info_t frame_inf;
+} wifi_rx_report_t;
+
+typedef struct compat_wifi_frame_info {
+	frame_type payload_type;
+
+	uint32 frame_len;
+
+	uint32 driver_timestamp_usec;
+
+	uint32 firmware_timestamp_usec;
+
+	union {
+		char ethernet_ii[MAX_FRAME_LEN_ETHERNET];
+		char ieee_80211_mgmt[MAX_FRAME_LEN_80211_MGMT];
+	} frame_content;
+} compat_wifi_frame_info_t;
+
+typedef struct compat_wifi_tx_report {
+	char md5_prefix[MD5_PREFIX_LEN];
+	wifi_tx_packet_fate fate;
+	compat_wifi_frame_info_t frame_inf;
+} compat_wifi_tx_report_t;
+
+typedef struct compat_wifi_rx_report {
+	char md5_prefix[MD5_PREFIX_LEN];
+	wifi_rx_packet_fate fate;
+	compat_wifi_frame_info_t frame_inf;
+} compat_wifi_rx_report_t;
+
+/*
+ * Packet logging - internal data
+ */
+
+typedef enum dhd_dbg_pkt_mon_state {
+	PKT_MON_INVALID = 0,
+	PKT_MON_ATTACHED,
+	PKT_MON_STARTING,
+	PKT_MON_STARTED,
+	PKT_MON_STOPPING,
+	PKT_MON_STOPPED,
+	PKT_MON_DETACHED,
+	} dhd_dbg_pkt_mon_state_t;
+
+typedef struct dhd_dbg_pkt_info {
+	frame_type payload_type;
+	size_t pkt_len;
+	uint32 driver_ts;
+	uint32 firmware_ts;
+	uint32 pkt_hash;
+	void *pkt;
+} dhd_dbg_pkt_info_t;
+
+typedef struct compat_dhd_dbg_pkt_info {
+	frame_type payload_type;
+	uint32 pkt_len;
+	uint32 driver_ts;
+	uint32 firmware_ts;
+	uint32 pkt_hash;
+	void *pkt;
+} compat_dhd_dbg_pkt_info_t;
+
+typedef struct dhd_dbg_tx_info
+{
+	wifi_tx_packet_fate fate;
+	dhd_dbg_pkt_info_t info;
+} dhd_dbg_tx_info_t;
+
+typedef struct dhd_dbg_rx_info
+{
+	wifi_rx_packet_fate fate;
+	dhd_dbg_pkt_info_t info;
+} dhd_dbg_rx_info_t;
+
+typedef struct dhd_dbg_tx_report
+{
+	dhd_dbg_tx_info_t *tx_pkts;
+	/* Indicates how many packets queued to send over the air */
+	uint16 pkt_pos;
+	/* Indicates how many packets sent over the air and received txstatus */
+	uint16 status_pos;
+} dhd_dbg_tx_report_t;
+
+typedef struct dhd_dbg_rx_report
+{
+	dhd_dbg_rx_info_t *rx_pkts;
+	/* Indicates how many packets sent over the air and received txstatus */
+	uint16 pkt_pos;
+} dhd_dbg_rx_report_t;
+
+typedef void (*dbg_pullreq_t)(void *os_priv, const int ring_id);
+typedef void (*dbg_urgent_noti_t) (dhd_pub_t *dhdp, const void *data, const uint32 len);
+typedef int (*dbg_mon_tx_pkts_t) (dhd_pub_t *dhdp, void *pkt, uint32 pktid,
+	frame_type type, uint8 mgmt_acked);
+typedef int (*dbg_mon_tx_status_t) (dhd_pub_t *dhdp, void *pkt,
+	uint32 pktid, uint16 status);
+typedef int (*dbg_mon_rx_pkts_t) (dhd_pub_t *dhdp, void *pkt, frame_type type);
+
+typedef struct dhd_dbg_pkt_mon
+{
+	dhd_dbg_tx_report_t *tx_report;
+	dhd_dbg_rx_report_t *rx_report;
+	dhd_dbg_pkt_mon_state_t tx_pkt_state;
+	dhd_dbg_pkt_mon_state_t tx_status_state;
+	dhd_dbg_pkt_mon_state_t rx_pkt_state;
+
+	/* call backs */
+	dbg_mon_tx_pkts_t tx_pkt_mon;
+	dbg_mon_tx_status_t tx_status_mon;
+	dbg_mon_rx_pkts_t rx_pkt_mon;
+} dhd_dbg_pkt_mon_t;
+
+typedef struct dhd_dbg {
+	dhd_dbg_ring_t dbg_rings[DEBUG_RING_ID_MAX];
+	void *private;          /* os private_data */
+	dhd_dbg_pkt_mon_t pkt_mon;
+	void *pkt_mon_lock; /* spin lock for packet monitoring */
+	dbg_pullreq_t pullreq;
+	dbg_urgent_noti_t urgent_notifier;
+} dhd_dbg_t;
+
+#define PKT_MON_ATTACHED(state) \
+		(((state) > PKT_MON_INVALID) && ((state) < PKT_MON_DETACHED))
+#define PKT_MON_DETACHED(state) \
+		(((state) == PKT_MON_INVALID) || ((state) == PKT_MON_DETACHED))
+#define PKT_MON_STARTED(state) ((state) == PKT_MON_STARTED)
+#define PKT_MON_STOPPED(state) ((state) == PKT_MON_STOPPED)
+#define PKT_MON_NOT_OPERATIONAL(state) \
+	(((state) != PKT_MON_STARTED) && ((state) != PKT_MON_STOPPED))
+#define PKT_MON_SAFE_TO_FREE(state) \
+	(((state) == PKT_MON_STARTING) || ((state) == PKT_MON_STOPPED))
+#define PKT_MON_PKT_FULL(pkt_count) ((pkt_count) >= MAX_FATE_LOG_LEN)
+#define PKT_MON_STATUS_FULL(pkt_count, status_count) \
+		(((status_count) >= (pkt_count)) || ((status_count) >= MAX_FATE_LOG_LEN))
+
+#ifdef DBG_PKT_MON
+#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid, type, mgmt_acked) \
+	do { \
+		if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.tx_pkt_mon && (pkt)) { \
+			(dhdp)->dbg->pkt_mon.tx_pkt_mon((dhdp), (pkt), \
+			(pktid), (type), (mgmt_acked)); \
+		} \
+	} while (0);
+#define DHD_DBG_PKT_MON_TX_STATUS(dhdp, pkt, pktid, status) \
+	do { \
+		if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.tx_status_mon && (pkt)) { \
+			(dhdp)->dbg->pkt_mon.tx_status_mon((dhdp), (pkt), (pktid), (status)); \
+		} \
+	} while (0);
+#define DHD_DBG_PKT_MON_RX(dhdp, pkt, type) \
+	do { \
+		if ((dhdp) && (dhdp)->dbg && (dhdp)->dbg->pkt_mon.rx_pkt_mon && (pkt)) { \
+			if (ntoh16((pkt)->protocol) != ETHER_TYPE_BRCM) { \
+				(dhdp)->dbg->pkt_mon.rx_pkt_mon((dhdp), (pkt), (type)); \
+			} \
+		} \
+	} while (0);
+
+#define DHD_DBG_PKT_MON_START(dhdp) \
+		dhd_os_dbg_start_pkt_monitor((dhdp));
+#define DHD_DBG_PKT_MON_STOP(dhdp) \
+		dhd_os_dbg_stop_pkt_monitor((dhdp));
+#else
+#define DHD_DBG_PKT_MON_TX(dhdp, pkt, pktid, type, mgmt_acked)
+#define DHD_DBG_PKT_MON_TX_STATUS(dhdp, pkt, pktid, status)
+#define DHD_DBG_PKT_MON_RX(dhdp, pkt, type)
+#define DHD_DBG_PKT_MON_START(dhdp)
+#define DHD_DBG_PKT_MON_STOP(dhdp)
+#endif /* DBG_PKT_MON */
+
+#ifdef DUMP_IOCTL_IOV_LIST
+typedef struct dhd_iov_li {
+	dll_t list;
+	uint32 cmd; /* command number */
+	char buff[100]; /* command name */
+} dhd_iov_li_t;
+#endif /* DUMP_IOCTL_IOV_LIST */
+
+#define IOV_LIST_MAX_LEN 5
+
+#ifdef DHD_DEBUG
+typedef struct {
+	dll_t list;
+	uint32 id; /* wasted chunk id */
+	uint32 handle; /* wasted chunk handle */
+	uint32 size; /* wasted chunk size */
+} dhd_dbg_mwli_t;
+#endif /* DHD_DEBUG */
+
+#define DHD_OW_BI_RAW_EVENT_LOG_FMT 0xFFFF
+
+/* LSB 2 bits of format number to identify the type of event log */
+#define DHD_EVENT_LOG_HDR_MASK 0x3
+
+#define DHD_EVENT_LOG_FMT_NUM_OFFSET 2
+#define DHD_EVENT_LOG_FMT_NUM_MASK 0x3FFF
+
+#define DHD_EXT_FMTNUM_MASK 0xF /* bits[3..0] used */
+/**
+ * OW:- one word
+ * TW:- two word
+ * NB:- non binary
+ * BI:- binary
+ */
+#define	DHD_OW_NB_EVENT_LOG_HDR 0
+#define DHD_TW_NB_EVENT_LOG_HDR 1
+#define DHD_BI_EVENT_LOG_HDR 3
+#define DHD_INVALID_EVENT_LOG_HDR 2
+
+#define DHD_TW_VALID_TAG_BITS_MASK 0xF
+#define DHD_OW_BI_EVENT_FMT_NUM 0x3FFF
+#define DHD_TW_BI_EVENT_FMT_NUM 0x3FFE
+
+#define DHD_TW_EVENT_LOG_TAG_OFFSET 8
+
+#define EVENT_TAG_TIMESTAMP_OFFSET 1
+#define EVENT_TAG_TIMESTAMP_EXT_OFFSET 2
+
+typedef struct prcd_event_log_hdr {
+	uint32 tag;		/* Event_log entry tag */
+	uint32 count;		/* Count of 4-byte entries */
+	uint32 fmt_num_raw;	/* Format number */
+	uint32 fmt_num;		/* Format number >> 2 */
+	uint32 armcycle;	/* global ARM CYCLE for TAG */
+	uint32 *log_ptr;	/* start of payload */
+	uint32	payload_len;
+	/* Extended event log header info
+	 * 0 - legacy, 1 - extended event log header present
+	 */
+	bool ext_event_log_hdr;
+	bool binary_payload;	/* 0 - non binary payload, 1 - binary payload */
+} prcd_event_log_hdr_t;		/* Processed event log header */
+
+/* dhd_dbg functions */
+extern void dhd_dbg_trace_evnt_handler(dhd_pub_t *dhdp, void *event_data,
+		void *raw_event_ptr, uint datalen);
+void dhd_dbg_msgtrace_log_parser(dhd_pub_t *dhdp, void *event_data,
+	void *raw_event_ptr, uint datalen, bool msgtrace_hdr_present,
+	uint32 msgtrace_seqnum);
+
+extern int dhd_dbg_attach(dhd_pub_t *dhdp, dbg_pullreq_t os_pullreq,
+	dbg_urgent_noti_t os_urgent_notifier, void *os_priv);
+extern void dhd_dbg_detach(dhd_pub_t *dhdp);
+extern int dhd_dbg_start(dhd_pub_t *dhdp, bool start);
+extern int dhd_dbg_set_configuration(dhd_pub_t *dhdp, int ring_id,
+		int log_level, int flags, uint32 threshold);
+extern int dhd_dbg_find_ring_id(dhd_pub_t *dhdp, char *ring_name);
+extern dhd_dbg_ring_t *dhd_dbg_get_ring_from_ring_id(dhd_pub_t *dhdp, int ring_id);
+extern void *dhd_dbg_get_priv(dhd_pub_t *dhdp);
+extern int dhd_dbg_send_urgent_evt(dhd_pub_t *dhdp, const void *data, const uint32 len);
+extern void dhd_dbg_verboselog_printf(dhd_pub_t *dhdp, prcd_event_log_hdr_t *plog_hdr,
+	void *raw_event_ptr, uint32 *log_ptr, uint32 logset, uint16 block);
+int dhd_dbg_pull_from_ring(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len,
+	int *num_entries);
+int dhd_dbg_pull_single_from_ring(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len,
+	bool strip_header);
+#ifdef DHD_PKT_LOGGING_DBGRING
+int dhd_dbg_update_to_ring(dhd_pub_t *dhdp, void *ring, uint32 w_len);
+int dhd_dbg_pull_from_pktlog(dhd_pub_t *dhdp, int ring_id, void *data, uint32 buf_len);
+void dhd_os_dbg_urgent_pullreq(void *os_priv, int ring_id);
+#endif /* DHD_PKT_LOGGING_DBGRING */
+#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
+int dhd_debug_dump_ring_push(dhd_pub_t *dhdp, int ring_id, uint32 len, void *data);
+#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
+int dhd_dbg_push_to_ring(dhd_pub_t *dhdp, int ring_id, dhd_dbg_ring_entry_t *hdr,
+		void *data);
+int __dhd_dbg_get_ring_status(dhd_dbg_ring_t *ring, dhd_dbg_ring_status_t *ring_status);
+int dhd_dbg_get_ring_status(dhd_pub_t *dhdp, int ring_id,
+		dhd_dbg_ring_status_t *dbg_ring_status);
+#ifdef SHOW_LOGTRACE
+void dhd_dbg_read_ring_into_trace_buf(dhd_dbg_ring_t *ring, trace_buf_info_t *trace_buf_info);
+#endif /* SHOW_LOGTRACE */
+
+#ifdef DBG_PKT_MON
+extern int dhd_dbg_attach_pkt_monitor(dhd_pub_t *dhdp,
+		dbg_mon_tx_pkts_t tx_pkt_mon,
+		dbg_mon_tx_status_t tx_status_mon,
+		dbg_mon_rx_pkts_t rx_pkt_mon);
+extern int dhd_dbg_start_pkt_monitor(dhd_pub_t *dhdp);
+extern int dhd_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt,
+		uint32 pktid, frame_type type, uint8 mgmt_acked);
+extern int dhd_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt,
+		uint32 pktid, uint16 status);
+extern int dhd_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt, frame_type type);
+extern int dhd_dbg_stop_pkt_monitor(dhd_pub_t *dhdp);
+extern int dhd_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
+		uint16 req_count, uint16 *resp_count);
+extern int dhd_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
+		uint16 req_count, uint16 *resp_count);
+extern int dhd_dbg_detach_pkt_monitor(dhd_pub_t *dhdp);
+#endif /* DBG_PKT_MON */
+
+extern bool dhd_dbg_process_tx_status(dhd_pub_t *dhdp, void *pkt,
+		uint32 pktid, uint16 status);
+
+/* os wrapper function */
+extern int dhd_os_dbg_attach(dhd_pub_t *dhdp);
+extern void dhd_os_dbg_detach(dhd_pub_t *dhdp);
+extern int dhd_os_dbg_register_callback(int ring_id,
+	void (*dbg_ring_sub_cb)(void *ctx, const int ring_id, const void *data,
+		const uint32 len, const dhd_dbg_ring_status_t dbg_ring_status));
+extern int dhd_os_dbg_register_urgent_notifier(dhd_pub_t *dhdp,
+	void (*urgent_noti)(void *ctx, const void *data, const uint32 len, const uint32 fw_len));
+
+extern int dhd_os_start_logging(dhd_pub_t *dhdp, char *ring_name, int log_level,
+		int flags, int time_intval, int threshold);
+extern int dhd_os_reset_logging(dhd_pub_t *dhdp);
+extern int dhd_os_suppress_logging(dhd_pub_t *dhdp, bool suppress);
+
+extern int dhd_os_get_ring_status(dhd_pub_t *dhdp, int ring_id,
+		dhd_dbg_ring_status_t *dbg_ring_status);
+extern int dhd_os_trigger_get_ring_data(dhd_pub_t *dhdp, char *ring_name);
+extern int dhd_os_push_push_ring_data(dhd_pub_t *dhdp, int ring_id, void *data, int32 data_len);
+extern int dhd_os_dbg_get_feature(dhd_pub_t *dhdp, int32 *features);
+
+#ifdef DBG_PKT_MON
+extern int dhd_os_dbg_attach_pkt_monitor(dhd_pub_t *dhdp);
+extern int dhd_os_dbg_start_pkt_monitor(dhd_pub_t *dhdp);
+extern int dhd_os_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt,
+	uint32 pktid, frame_type type, uint8 mgmt_acked);
+extern int dhd_os_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt,
+	uint32 pktid, uint16 status);
+extern int dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt,
+	frame_type type);
+extern int dhd_os_dbg_stop_pkt_monitor(dhd_pub_t *dhdp);
+extern int dhd_os_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp,
+	void __user *user_buf, uint16 req_count, uint16 *resp_count);
+extern int dhd_os_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp,
+	void __user *user_buf, uint16 req_count, uint16 *resp_count);
+extern int dhd_os_dbg_detach_pkt_monitor(dhd_pub_t *dhdp);
+#endif /* DBG_PKT_MON */
+
+#ifdef DUMP_IOCTL_IOV_LIST
+extern void dhd_iov_li_append(dhd_pub_t *dhd, dll_t *list_head, dll_t *node);
+extern void dhd_iov_li_print(dll_t *list_head);
+extern void dhd_iov_li_delete(dhd_pub_t *dhd, dll_t *list_head);
+#endif /* DUMP_IOCTL_IOV_LIST */
+
+#ifdef DHD_DEBUG
+extern void dhd_mw_list_delete(dhd_pub_t *dhd, dll_t *list_head);
+#endif /* DHD_DEBUG */
+
+void print_roam_enhanced_log(prcd_event_log_hdr_t *plog_hdr);
+
+typedef void (*print_roam_enhance_log_func)(prcd_event_log_hdr_t *plog_hdr);
+typedef struct _pr_roam_tbl {
+	uint8 version;
+	uint8 id;
+	print_roam_enhance_log_func pr_func;
+} pr_roam_tbl_t;
+
+extern uint32 dhd_dbg_get_fwverbose(dhd_pub_t *dhdp);
+extern void dhd_dbg_set_fwverbose(dhd_pub_t *dhdp, uint32 new_val);
+#endif /* _dhd_debug_h_ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_debug_linux.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_debug_linux.c
@@ -0,0 +1,640 @@
+/*
+ * DHD debugability Linux os layer
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <typedefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_dbg.h>
+#include <dhd_debug.h>
+
+#include <net/cfg80211.h>
+#include <wl_cfgvendor.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0)
+#include <linux/sched/clock.h>
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0) */
+#include <dhd_config.h>
+
+typedef void (*dbg_ring_send_sub_t)(void *ctx, const int ring_id, const void *data,
+	const uint32 len, const dhd_dbg_ring_status_t ring_status);
+typedef void (*dbg_urgent_noti_sub_t)(void *ctx, const void *data,
+	const uint32 len, const uint32 fw_len);
+
+static dbg_ring_send_sub_t ring_send_sub_cb[DEBUG_RING_ID_MAX];
+static dbg_urgent_noti_sub_t urgent_noti_sub_cb;
+typedef struct dhd_dbg_os_ring_info {
+	dhd_pub_t *dhdp;
+	int ring_id;
+	int log_level;
+	unsigned long interval;
+	struct delayed_work work;
+	uint64 tsoffset;
+} linux_dbgring_info_t;
+
+struct log_level_table dhd_event_map[] = {
+	{1, WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED, "DRIVER EAPOL TX REQ"},
+	{1, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED, "DRIVER EAPOL RX"},
+	{2, WIFI_EVENT_DRIVER_SCAN_REQUESTED, "SCAN_REQUESTED"},
+	{2, WIFI_EVENT_DRIVER_SCAN_COMPLETE, "SCAN COMPELETE"},
+	{3, WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND, "SCAN RESULT FOUND"},
+	{2, WIFI_EVENT_DRIVER_PNO_ADD, "PNO ADD"},
+	{2, WIFI_EVENT_DRIVER_PNO_REMOVE, "PNO REMOVE"},
+	{2, WIFI_EVENT_DRIVER_PNO_NETWORK_FOUND, "PNO NETWORK FOUND"},
+	{2, WIFI_EVENT_DRIVER_PNO_SCAN_REQUESTED, "PNO SCAN_REQUESTED"},
+	{1, WIFI_EVENT_DRIVER_PNO_SCAN_RESULT_FOUND, "PNO SCAN RESULT FOUND"},
+	{1, WIFI_EVENT_DRIVER_PNO_SCAN_COMPLETE, "PNO SCAN COMPELETE"}
+};
+
+static void
+debug_data_send(dhd_pub_t *dhdp, int ring_id, const void *data, const uint32 len,
+	const dhd_dbg_ring_status_t ring_status)
+{
+	struct net_device *ndev;
+	dbg_ring_send_sub_t ring_sub_send;
+	ndev = dhd_linux_get_primary_netdev(dhdp);
+
+	if (!ndev)
+		return;
+	if (!VALID_RING(ring_id))
+		return;
+	if (ring_send_sub_cb[ring_id]) {
+		ring_sub_send = ring_send_sub_cb[ring_id];
+		ring_sub_send(ndev, ring_id, data, len, ring_status);
+	}
+}
+
+static void
+dhd_os_dbg_urgent_notifier(dhd_pub_t *dhdp, const void *data, const uint32 len)
+{
+	struct net_device *ndev;
+	ndev = dhd_linux_get_primary_netdev(dhdp);
+	if (!ndev)
+		return;
+	if (urgent_noti_sub_cb) {
+		urgent_noti_sub_cb(ndev, data, len, dhdp->soc_ram_length);
+	}
+}
+
+static void
+dbg_ring_poll_worker(struct work_struct *work)
+{
+	struct delayed_work *d_work = to_delayed_work(work);
+	bool sched = TRUE;
+	dhd_dbg_ring_t *ring;
+	linux_dbgring_info_t *ring_info;
+	dhd_pub_t *dhdp;
+	int ringid;
+	dhd_dbg_ring_status_t ring_status;
+	void *buf, *buf_entries;
+	dhd_dbg_ring_entry_pack_t *pack_hdr;
+	dhd_dbg_ring_entry_t *hdr;
+	int32 buflen, rlen, remain_buflen;
+	int32 alloc_len;
+	unsigned long flags;
+
+	BCM_REFERENCE(hdr);
+
+	if (!CAN_SLEEP()) {
+		DHD_CONS_ONLY(("this context should be sleepable\n"));
+		sched = FALSE;
+		goto exit;
+	}
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	ring_info = container_of(d_work, linux_dbgring_info_t, work);
+	GCC_DIAGNOSTIC_POP();
+
+	dhdp = ring_info->dhdp;
+	ringid = ring_info->ring_id;
+
+	ring = &dhdp->dbg->dbg_rings[ringid];
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+	dhd_dbg_get_ring_status(dhdp, ringid, &ring_status);
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+#ifdef DHD_PKT_LOGGING_DBGRING
+	if (ringid == PACKET_LOG_RING_ID) {
+		struct net_device *ndev;
+		ndev = dhd_linux_get_primary_netdev(dhdp);
+		buflen = DBG_RING_ENTRY_SIZE;
+		buflen += dhd_os_get_pktlog_dump_size(ndev);
+		DHD_DBGIF(("%s: buflen: %d\n", __FUNCTION__, buflen));
+		alloc_len = buflen + DBG_RING_ENTRY_PACK_SIZE;
+	} else
+#endif /* DHD_PKT_LOGGING_DBGRING */
+	{
+		DHD_DBG_RING_LOCK(ring->lock, flags);
+		if (ring->wp > ring->rp) {
+			buflen = ring->wp - ring->rp;
+		} else if (ring->wp < ring->rp) {
+			buflen = ring->ring_size - ring->rp + ring->wp;
+		} else {
+			DHD_DBG_RING_UNLOCK(ring->lock, flags);
+			goto exit;
+		}
+
+		if (buflen > ring->ring_size) {
+			DHD_DBG_RING_UNLOCK(ring->lock, flags);
+			goto exit;
+		}
+		DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+		alloc_len = NLMSG_DEFAULT_SIZE;
+	}
+	buf = VMALLOCZ(dhdp->osh, alloc_len);
+
+	if (!buf) {
+		DHD_CONS_ONLY(("%s failed to allocate read buf\n", __FUNCTION__));
+		sched = FALSE;
+		goto exit;
+	}
+
+	pack_hdr = (dhd_dbg_ring_entry_pack_t *)buf;
+	pack_hdr->magic = DBG_RING_PACK_MAGIC;
+
+	buf_entries = (char *)buf + sizeof(dhd_dbg_ring_entry_pack_t);
+
+#ifdef DHD_PKT_LOGGING_DBGRING
+	if (ringid == PACKET_LOG_RING_ID) {
+		pack_hdr->num_entries = 1u;
+		rlen = dhd_dbg_pull_from_pktlog(dhdp, ringid, buf_entries, buflen);
+		DHD_DBGIF(("%s: rlen: %d\n", __FUNCTION__, rlen));
+		hdr = (dhd_dbg_ring_entry_t *)buf_entries;
+		while (rlen > 0) {
+			DHD_DBG_RING_LOCK(ring->lock, flags);
+			ring_status.read_bytes += (rlen - DBG_RING_ENTRY_SIZE);
+			ring->stat.read_bytes += (rlen - DBG_RING_ENTRY_SIZE);
+			if (ring->stat.read_bytes > ring->stat.written_bytes) {
+				DHD_DBGIF(("%s READ/WRITE counter mismatched!\n", __FUNCTION__));
+				ring->stat.read_bytes = ring->stat.written_bytes;
+			}
+			DHD_DBGIF(("%s RING%d[%s]read_bytes %d, written_bytes %d, "
+				"writen_records %d\n", __FUNCTION__, ring->id, ring->name,
+				ring->stat.read_bytes, ring->stat.written_bytes,
+				ring->stat.written_records));
+			DHD_DBG_RING_UNLOCK(ring->lock, flags);
+			/* offset fw ts to host ts */
+			hdr->timestamp += ring_info->tsoffset;
+			debug_data_send(dhdp, ringid, pack_hdr,
+					ENTRY_LENGTH(hdr) + DBG_RING_ENTRY_PACK_SIZE, ring_status);
+			rlen -= ENTRY_LENGTH(hdr);
+			hdr = (dhd_dbg_ring_entry_t *)((char *)hdr + ENTRY_LENGTH(hdr));
+		}
+	} else
+#endif /* DHD_PKT_LOGGING_DBGRING */
+	{
+		remain_buflen = buflen;
+		while (remain_buflen > 0) {
+			pack_hdr->num_entries = 0;
+			memset_s(buf_entries, NLMSG_DEFAULT_SIZE - DBG_RING_ENTRY_PACK_SIZE,
+				0, NLMSG_DEFAULT_SIZE - DBG_RING_ENTRY_PACK_SIZE);
+			/* Returns as much as possible with the size of the passed buffer
+			 * rlen means the total length of multiple entries including entry hdr
+			 */
+			rlen = dhd_dbg_pull_from_ring(dhdp, ringid, buf_entries,
+				NLMSG_DEFAULT_SIZE - DBG_RING_ENTRY_PACK_SIZE,
+				&pack_hdr->num_entries);
+			if (rlen <= 0) {
+				break;
+			}
+
+			DHD_DBG_RING_LOCK(ring->lock, flags);
+			ring_status.read_bytes += rlen;
+			DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+			/* payload length includes pack_hdr size */
+			debug_data_send(dhdp, ringid, pack_hdr,
+					rlen + DBG_RING_ENTRY_PACK_SIZE, ring_status);
+			remain_buflen -= rlen;
+		}
+	}
+
+	VMFREE(dhdp->osh, buf, alloc_len);
+
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+	if (!ring->sched_pull) {
+		ring->sched_pull = TRUE;
+	}
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+exit:
+	if (sched) {
+		/* retrigger the work at same interval */
+		if ((ring_info->interval)) {
+			if ((ring_status.written_bytes == ring_status.read_bytes) ||
+#ifdef DHD_PKT_LOGGING_DBGRING
+				(ringid == PACKET_LOG_RING_ID)) {
+#else
+				FALSE) {
+#endif /* DHD_PKT_LOGGING_DBGRING */
+				schedule_delayed_work(d_work, ring_info->interval);
+			}
+		}
+	}
+
+	return;
+}
+
+int
+dhd_os_dbg_register_callback(int ring_id, dbg_ring_send_sub_t callback)
+{
+	if (!VALID_RING(ring_id))
+		return BCME_RANGE;
+
+	ring_send_sub_cb[ring_id] = callback;
+	return BCME_OK;
+}
+
+int
+dhd_os_dbg_register_urgent_notifier(dhd_pub_t *dhdp, dbg_urgent_noti_sub_t urgent_noti_sub)
+{
+	if (!dhdp || !urgent_noti_sub)
+		return BCME_BADARG;
+	urgent_noti_sub_cb = urgent_noti_sub;
+
+	return BCME_OK;
+}
+
+int
+dhd_os_start_logging(dhd_pub_t *dhdp, char *ring_name, int log_level,
+	int flags, int time_intval, int threshold)
+{
+	int ret = BCME_OK;
+	int ring_id;
+	linux_dbgring_info_t *os_priv, *ring_info;
+
+	ring_id = dhd_dbg_find_ring_id(dhdp, ring_name);
+	if (!VALID_RING(ring_id))
+		return BCME_UNSUPPORTED;
+
+	DHD_ERROR(("%s , ring_id : %d log_level : %d, "
+			"time_intval : %d, threshod %d Bytes\n",
+			__FUNCTION__, ring_id, log_level, time_intval, threshold));
+
+	/* change the configuration */
+	ret = dhd_dbg_set_configuration(dhdp, ring_id, log_level, flags, threshold);
+	if (ret) {
+		DHD_ERROR(("dhd_set_configuration is failed : %d\n", ret));
+		return ret;
+	}
+
+	os_priv = dhd_dbg_get_priv(dhdp);
+	if (!os_priv)
+		return BCME_ERROR;
+	ring_info = &os_priv[ring_id];
+	ring_info->log_level = log_level;
+	if (time_intval == 0 || log_level == 0) {
+		ring_info->interval = 0;
+		cancel_delayed_work_sync(&ring_info->work);
+	} else {
+		ring_info->interval = msecs_to_jiffies(time_intval * MSEC_PER_SEC);
+		cancel_delayed_work_sync(&ring_info->work);
+		schedule_delayed_work(&ring_info->work, ring_info->interval);
+	}
+
+	return ret;
+}
+
+int
+dhd_os_reset_logging(dhd_pub_t *dhdp)
+{
+	int ret = BCME_OK;
+	int ring_id;
+	linux_dbgring_info_t *os_priv, *ring_info;
+
+	os_priv = dhd_dbg_get_priv(dhdp);
+	if (!os_priv)
+		return BCME_ERROR;
+
+	/* Stop all rings */
+	for (ring_id = DEBUG_RING_ID_INVALID + 1; ring_id < DEBUG_RING_ID_MAX; ring_id++) {
+		DHD_INFO(("%s: Stop ring buffer %d\n", __FUNCTION__, ring_id));
+
+		ring_info = &os_priv[ring_id];
+		/* log level zero makes stop logging on that ring */
+		ring_info->log_level = 0;
+		ring_info->interval = 0;
+		/* change the configuration */
+		ret = dhd_dbg_set_configuration(dhdp, ring_id, 0, 0, 0);
+		if (ret) {
+			DHD_ERROR(("dhd_set_configuration is failed : %d\n", ret));
+			return ret;
+		}
+		/* cancel any pending work */
+		cancel_delayed_work_sync(&ring_info->work);
+	}
+	return ret;
+}
+
+#define SUPPRESS_LOG_LEVEL 1
+int
+dhd_os_suppress_logging(dhd_pub_t *dhdp, bool suppress)
+{
+	int ret = BCME_OK;
+	int max_log_level;
+	int enable = (suppress) ? 0 : 1;
+	linux_dbgring_info_t *os_priv;
+
+	os_priv = dhd_dbg_get_priv(dhdp);
+	if (!os_priv)
+		return BCME_ERROR;
+
+	max_log_level = os_priv[FW_VERBOSE_RING_ID].log_level;
+
+	if (max_log_level == SUPPRESS_LOG_LEVEL) {
+		/* suppress the logging in FW not to wake up host while device in suspend mode */
+		ret = dhd_iovar(dhdp, 0, "logtrace", (char *)&enable, sizeof(enable), NULL, 0,
+				TRUE);
+		if (ret < 0 && (ret != BCME_UNSUPPORTED)) {
+			DHD_ERROR(("logtrace is failed : %d\n", ret));
+		}
+	}
+
+	return ret;
+}
+
+int
+dhd_os_get_ring_status(dhd_pub_t *dhdp, int ring_id, dhd_dbg_ring_status_t *dbg_ring_status)
+{
+	return dhd_dbg_get_ring_status(dhdp, ring_id, dbg_ring_status);
+}
+
+int
+dhd_os_trigger_get_ring_data(dhd_pub_t *dhdp, char *ring_name)
+{
+	int ret = BCME_OK;
+	int ring_id;
+	linux_dbgring_info_t *os_priv, *ring_info;
+	ring_id = dhd_dbg_find_ring_id(dhdp, ring_name);
+	if (!VALID_RING(ring_id))
+		return BCME_UNSUPPORTED;
+	os_priv = dhd_dbg_get_priv(dhdp);
+	if (os_priv) {
+		ring_info = &os_priv[ring_id];
+		if (ring_info->interval) {
+			cancel_delayed_work_sync(&ring_info->work);
+		}
+		schedule_delayed_work(&ring_info->work, 0);
+	} else {
+		DHD_ERROR(("%s : os_priv is NULL\n", __FUNCTION__));
+		ret = BCME_ERROR;
+	}
+	return ret;
+}
+
+int
+dhd_os_push_push_ring_data(dhd_pub_t *dhdp, int ring_id, void *data, int32 data_len)
+{
+	int ret = BCME_OK, i;
+	dhd_dbg_ring_entry_t msg_hdr;
+	log_conn_event_t *event_data = (log_conn_event_t *)data;
+	linux_dbgring_info_t *os_priv, *ring_info = NULL;
+
+	if (!VALID_RING(ring_id))
+		return BCME_UNSUPPORTED;
+	os_priv = dhd_dbg_get_priv(dhdp);
+
+	if (os_priv) {
+		ring_info = &os_priv[ring_id];
+	} else
+		return BCME_NORESOURCE;
+
+	memset(&msg_hdr, 0, sizeof(dhd_dbg_ring_entry_t));
+
+	if (ring_id == DHD_EVENT_RING_ID) {
+		msg_hdr.type = DBG_RING_ENTRY_EVENT_TYPE;
+		msg_hdr.flags |= DBG_RING_ENTRY_FLAGS_HAS_TIMESTAMP;
+		msg_hdr.flags |= DBG_RING_ENTRY_FLAGS_HAS_BINARY;
+		msg_hdr.timestamp = osl_localtime_ns();
+		/* convert to ms */
+		msg_hdr.timestamp = DIV_U64_BY_U32(msg_hdr.timestamp, NSEC_PER_MSEC);
+		msg_hdr.len = data_len;
+		/* filter the event for higher log level with current log level */
+		for (i = 0; i < ARRAYSIZE(dhd_event_map); i++) {
+			if ((dhd_event_map[i].tag == event_data->event) &&
+				dhd_event_map[i].log_level > ring_info->log_level) {
+				return ret;
+			}
+		}
+	}
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+	else if (ring_id == FW_VERBOSE_RING_ID || ring_id == DRIVER_LOG_RING_ID ||
+			ring_id == ROAM_STATS_RING_ID) {
+		msg_hdr.type = DBG_RING_ENTRY_DATA_TYPE;
+		msg_hdr.flags |= DBG_RING_ENTRY_FLAGS_HAS_TIMESTAMP;
+		msg_hdr.timestamp = osl_localtime_ns();
+		msg_hdr.timestamp = DIV_U64_BY_U32(msg_hdr.timestamp, NSEC_PER_MSEC);
+		msg_hdr.len = strlen(data);
+	}
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
+	ret = dhd_dbg_push_to_ring(dhdp, ring_id, &msg_hdr, event_data);
+	if (ret && ret != BCME_BUSY) {
+		DHD_ERROR(("%s : failed to push data into the ring (%d) with ret(%d)\n",
+			__FUNCTION__, ring_id, ret));
+	}
+
+	return ret;
+}
+
+#ifdef DBG_PKT_MON
+int
+dhd_os_dbg_attach_pkt_monitor(dhd_pub_t *dhdp)
+{
+	return dhd_dbg_attach_pkt_monitor(dhdp, dhd_os_dbg_monitor_tx_pkts,
+		dhd_os_dbg_monitor_tx_status, dhd_os_dbg_monitor_rx_pkts);
+}
+
+int
+dhd_os_dbg_start_pkt_monitor(dhd_pub_t *dhdp)
+{
+	return dhd_dbg_start_pkt_monitor(dhdp);
+}
+
+int
+dhd_os_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid,
+	frame_type type, uint8 mgmt_acked)
+{
+	return dhd_dbg_monitor_tx_pkts(dhdp, pkt, pktid, type, mgmt_acked);
+}
+
+int
+dhd_os_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid,
+	uint16 status)
+{
+	return dhd_dbg_monitor_tx_status(dhdp, pkt, pktid, status);
+}
+
+int
+dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt, frame_type type)
+{
+	return dhd_dbg_monitor_rx_pkts(dhdp, pkt, type);
+}
+
+int
+dhd_os_dbg_stop_pkt_monitor(dhd_pub_t *dhdp)
+{
+	return dhd_dbg_stop_pkt_monitor(dhdp);
+}
+
+int
+dhd_os_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
+	uint16 req_count, uint16 *resp_count)
+{
+	return dhd_dbg_monitor_get_tx_pkts(dhdp, user_buf, req_count, resp_count);
+}
+
+int
+dhd_os_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, void __user *user_buf,
+	uint16 req_count, uint16 *resp_count)
+{
+	return dhd_dbg_monitor_get_rx_pkts(dhdp, user_buf, req_count, resp_count);
+}
+
+int
+dhd_os_dbg_detach_pkt_monitor(dhd_pub_t *dhdp)
+{
+	return dhd_dbg_detach_pkt_monitor(dhdp);
+}
+#endif /* DBG_PKT_MON */
+
+int
+dhd_os_dbg_get_feature(dhd_pub_t *dhdp, int32 *features)
+{
+	int ret = BCME_OK;
+	/* XXX : we need to find a way to get the features for dbg */
+	*features = 0;
+#ifdef DEBUGABILITY
+#ifndef DEBUGABILITY_DISABLE_MEMDUMP
+	*features |= DBG_MEMORY_DUMP_SUPPORTED;
+#endif /* !DEBUGABILITY_DISABLE_MEMDUMP */
+	if (FW_SUPPORTED(dhdp, logtrace)) {
+		*features |= DBG_CONNECT_EVENT_SUPPORTED;
+		*features |= DBG_VERBOSE_LOG_SUPPORTED;
+	}
+	if (FW_SUPPORTED(dhdp, hchk)) {
+		*features |= DBG_HEALTH_CHECK_SUPPORTED;
+	}
+#ifdef DBG_PKT_MON
+	if (FW_SUPPORTED(dhdp, d11status)) {
+		*features |= DBG_PACKET_FATE_SUPPORTED;
+	}
+#endif /* DBG_PKT_MON */
+#endif /* DEBUGABILITY */
+#ifdef DHD_PKT_LOGGING_DBGRING
+	*features |= DBG_PACKET_LOG_SUPPORTED;
+#endif /* DHD_PKT_LOGGING_DBGRING */
+	return ret;
+}
+
+static void
+dhd_os_dbg_pullreq(void *os_priv, int ring_id)
+{
+	linux_dbgring_info_t *ring_info;
+
+	ring_info = &((linux_dbgring_info_t *)os_priv)[ring_id];
+	cancel_delayed_work(&ring_info->work);
+	schedule_delayed_work(&ring_info->work, 0);
+}
+
+#ifdef DHD_PKT_LOGGING_DBGRING
+void
+dhd_os_dbg_urgent_pullreq(void *os_priv, int ring_id)
+{
+	dhd_os_dbg_pullreq(os_priv, ring_id);
+}
+#endif /* DHD_PKT_LOGGING_DBGRING */
+
+int
+dhd_os_dbg_attach(dhd_pub_t *dhdp)
+{
+	int ret = BCME_OK;
+	linux_dbgring_info_t *os_priv, *ring_info;
+	int ring_id;
+
+	/* os_dbg data */
+	os_priv = VMALLOCZ(dhdp->osh, sizeof(*os_priv) * DEBUG_RING_ID_MAX);
+	if (!os_priv) {
+		DHD_ERROR(("%s:%d: VMALLOC failed for os_priv, size %d\n", __FUNCTION__,
+			__LINE__, (uint32)sizeof(*os_priv) * DEBUG_RING_ID_MAX));
+		return BCME_NOMEM;
+	}
+
+	for (ring_id = DEBUG_RING_ID_INVALID + 1; ring_id < DEBUG_RING_ID_MAX;
+	     ring_id++) {
+		ring_info = &os_priv[ring_id];
+		INIT_DELAYED_WORK(&ring_info->work, dbg_ring_poll_worker);
+		ring_info->dhdp = dhdp;
+		ring_info->ring_id = ring_id;
+	}
+
+	ret = dhd_dbg_attach(dhdp, dhd_os_dbg_pullreq, dhd_os_dbg_urgent_notifier, os_priv);
+	if (ret) {
+		VMFREE(dhdp->osh, os_priv, sizeof(*os_priv) * DEBUG_RING_ID_MAX);
+	}
+
+	return ret;
+}
+
+void
+dhd_os_dbg_detach(dhd_pub_t *dhdp)
+{
+	linux_dbgring_info_t *os_priv, *ring_info;
+	int ring_id;
+	/* free os_dbg data */
+	os_priv = dhd_dbg_get_priv(dhdp);
+	if (!os_priv)
+		return;
+	/* abort pending any job */
+	for (ring_id = DEBUG_RING_ID_INVALID + 1; ring_id < DEBUG_RING_ID_MAX; ring_id++) {
+		ring_info = &os_priv[ring_id];
+		if (ring_info->interval) {
+			ring_info->interval = 0;
+			cancel_delayed_work_sync(&ring_info->work);
+		}
+	}
+	VMFREE(dhdp->osh, os_priv, sizeof(*os_priv) * DEBUG_RING_ID_MAX);
+
+	return dhd_dbg_detach(dhdp);
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_event_log_filter.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_event_log_filter.c
@@ -0,0 +1,3277 @@
+/*
+ * Wifi dongle status Filter and Report
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+/*
+ * Filter MODULE and Report MODULE
+ */
+
+#include <typedefs.h>
+#include <osl.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_dbg.h>
+#include <dhd_debug.h>
+#include <event_log.h>
+#include <event_trace.h>
+#include <bcmtlv.h>
+#include <bcmwifi_channels.h>
+#include <dhd_event_log_filter.h>
+#include <wl_cfg80211.h>
+#include <dhd_bitpack.h>
+#include <dhd_pktlog.h>
+#ifdef DHD_STATUS_LOGGING
+#include <dhd_statlog.h>
+#endif /* DHD_STATUS_LOGGING */
+
+#ifdef IL_BIGENDIAN
+#include <bcmendian.h>
+#define htod32(i) (bcmswap32(i))
+#define htod16(i) (bcmswap16(i))
+#define dtoh32(i) (bcmswap32(i))
+#define dtoh16(i) (bcmswap16(i))
+#define htodchanspec(i) htod16(i)
+#define dtohchanspec(i) dtoh16(i)
+#else
+#define htod32(i) (i)
+#define htod16(i) (i)
+#define dtoh32(i) (i)
+#define dtoh16(i) (i)
+#define htodchanspec(i) (i)
+#define dtohchanspec(i) (i)
+#endif /* IL_BIGENDINAN */
+
+#define DHD_FILTER_ERR_INTERNAL(fmt, ...) DHD_ERROR(("EWPF-" fmt, ##__VA_ARGS__))
+#define DHD_FILTER_TRACE_INTERNAL(fmt, ...) DHD_INFO(("EWPF-" fmt, ##__VA_ARGS__))
+
+#define DHD_FILTER_ERR(x) DHD_FILTER_ERR_INTERNAL x
+#define DHD_FILTER_TRACE(x) DHD_FILTER_TRACE_INTERNAL x
+
+/* ========= EWP Filter functions ============= */
+//#define EWPF_DEBUG
+#define EWPF_DEBUG_BUF_LEN	512
+#define EWPF_VAL_CNT_PLINE	16
+
+#define EWPF_REPORT_MAX_DATA	32	/* MAX record per slice */
+
+#define EWPF_INVALID	(-1)
+#define EWPF_XTLV_INVALID		0
+
+#define EWPF_MAX_IDX_TYPE		4
+#define EWPF_IDX_TYPE_SLICE		1
+#define EWPF_IDX_TYPE_IFACE		2
+#define EWPF_IDX_TYPE_EVENT		3
+#define EWPF_IDX_TYPE_KEY_INFO		4
+
+#define EWPF_MAX_SLICE			2	/* MAX slice in dongle */
+#define EWPF_SLICE_MAIN			0	/* SLICE ID for 5GHZ */
+#define EWPF_SLICE_AUX			1	/* SLICE ID for 2GHZ */
+
+#define EWPF_MAX_IFACE			3	/* MAX IFACE supported */
+#define EWPF_MAX_EVENT			1	/* MAX EVENT counter supported */
+#define EWPF_MAX_KEY_INFO			1	/* MAX KEY INFO counter supported */
+
+#define EWPF_ARM_TO_MSEC		1
+#define EWPF_NO_UNIT_CONV		1
+#define EWPF_MSEC_TO_SEC		1000
+#define EWPF_USEC_TO_MSEC		1000
+#define EWPF_NSEC_TO_MSEC		1000000
+#define EWPF_USEC_TO_SEC		1000000
+#define EWPF_EPOCH				1000
+#define EWPF_NONSEC_TO_SEC		1000000000
+#define EWPF_REPORT_YEAR_MUL	10000
+#define EWPF_REPORT_MON_MUL		100
+#define EWPF_REPORT_HOUR_MUL	10000
+#define EWPF_REPORT_MIN_MUL		100
+#define EWPF_REPORT_MINUTES		60
+#define EWPF_REPORT_YEAR_BASE	1900
+
+#define EWPF_NO_ABS		FALSE
+#define EWPF_NEED_ABS		TRUE
+
+#define EWPF_MAX_INFO_TYPE	5
+#define EWPF_INFO_VER		0
+#define EWPF_INFO_TYPE		1
+#define EWPF_INFO_ECNT		2
+#define EWPF_INFO_IOVAR		3
+#define EWPF_INFO_CPLOG		4
+#define EWPF_INFO_DHDSTAT	5
+
+#define EWPF_UPDATE_ARM_CYCLE_OFFSET	1
+
+/* EWPF element of slice type */
+typedef struct {
+	uint32 armcycle; /* dongle arm cycle for this record */
+	union {
+		wl_periodic_compact_cntrs_v1_t compact_cntr_v1;
+		wl_periodic_compact_cntrs_v2_t compact_cntr_v2;
+		wl_periodic_compact_cntrs_v3_t compact_cntr_v3;
+		wl_periodic_compact_cntrs_v4_t compact_cntr_v4;
+	};
+	evt_hist_compact_toss_stats_v1_t hist_tx_toss_stat;
+	evt_hist_compact_toss_stats_v1_t hist_rx_toss_stat;
+	wlc_btc_stats_v4_t btc_stat;
+	wl_compact_he_cnt_wlc_v2_t compact_he_cnt;
+} EWPF_slc_elem_t;
+
+/* EWPF element for interface type */
+typedef struct {
+	uint32 armcycle; /* dongle arm cycle for this record */
+	wl_if_stats_t if_stat;
+	wl_lqm_t lqm;
+	wl_if_infra_stats_t infra;
+	wl_if_mgt_stats_t mgmt_stat;
+	wl_if_state_compact_t if_comp_stat;
+	wl_adps_dump_summary_v2_t adps_dump_summary;
+	wl_adps_energy_gain_v1_t adps_energy_gain;
+	wl_roam_stats_v1_t roam_stat;
+} EWPF_ifc_elem_t;
+
+typedef struct {
+	uint32 first_armcycle; /* first dongle arm cycle for this record */
+	uint32 updated_armcycle; /* last updated dongle arm cycle for this record */
+	wl_event_based_statistics_v4_t event_stat;
+} EWPF_event_elem_t;
+
+typedef struct {
+	uint32 first_armcycle; /* first dongle arm cycle for this record */
+	uint32 updated_armcycle; /* last updaated dongle arm cycle for this record */
+	key_update_info_v1_t key_update_info;
+} EWPF_key_info_elem_t;
+
+typedef struct {
+	uint32 first_armcycle; /* first dongle arm cycle for this record */
+	uint32 updated_armcycle; /* last updated dongle arm cycle for this record */
+	wl_roam_stats_v1_t roam_stat;
+} EWPF_roam_stats_event_elem_t;
+
+typedef struct {
+	int enabled;			/* enabled/disabled */
+	dhd_pub_t *dhdp;
+	uint32 tmp_armcycle;	/* global ARM CYCLE for TAG */
+	int idx_type;			/* 0 : SLICE, 1: IFACE */
+	int xtlv_idx;			/* Slice/Interface index : global for TAG */
+	void *s_ring[EWPF_MAX_SLICE];
+	void *i_ring[EWPF_MAX_IFACE];
+	void *e_ring[EWPF_MAX_EVENT];
+	void *k_ring[EWPF_MAX_KEY_INFO];
+
+	/* used by Report module */
+	uint8 last_bssid[ETHER_ADDR_LEN];	/* BSSID of last conencted/request */
+	int last_channel;
+	uint32 last_armcycle;	/* ARM CYCLE prior last connection */
+} EWP_filter_t;
+
+/* status gathering functions : XTLV callback functions */
+typedef int (*EWPF_filter_cb)(void *ctx, const uint8 *data, uint16 type, uint16 len);
+static int evt_xtlv_print_cb(void *ctx, const uint8 *data, uint16 type, uint16 len);
+static int evt_xtlv_copy_cb(void *ctx, const uint8 *data, uint16 type, uint16 len);
+static int evt_xtlv_idx_cb(void *ctx, const uint8 *data, uint16 type, uint16 len);
+static int evt_xtlv_type_cb(void *ctx, const uint8 *data, uint16 type, uint16 len);
+static int filter_main_cb(void *ctx, const uint8 *data, uint16 type, uint16 len);
+static int evt_xtlv_roam_cb(void *ctx, const uint8 *data, uint16 type, uint16 len);
+
+/* ========= Event Handler functions and its callbacks: ============= */
+typedef struct _EWPF_tbl {
+	uint16 xtlv_id; /* XTLV ID, to handle */
+	EWPF_filter_cb cb_func; /* specific call back function, usually for structre */
+	int idx_type;			/* structure specific info: belonged type */
+	int	max_idx;			/* structure specific info: ALLOWED MAX IDX */
+	uint32 offset; /* offset of structure in EWPF_elem-t, valid if cb is not null */
+	uint32 member_length;	/* MAX length of reserved for this structure */
+	struct _EWPF_tbl *tbl; /* sub table if XTLV map to XLTV */
+} EWPF_tbl_t;
+
+/* Context structre for XTLV callback */
+typedef struct {
+	dhd_pub_t *dhdp;
+	EWPF_tbl_t *tbl;
+} EWPF_ctx_t;
+
+#define SLICE_INFO(a) EWPF_IDX_TYPE_SLICE, EWPF_MAX_SLICE, OFFSETOF(EWPF_slc_elem_t, a), \
+	sizeof(((EWPF_slc_elem_t *)NULL)->a)
+#define IFACE_INFO(a) EWPF_IDX_TYPE_IFACE, EWPF_MAX_IFACE, OFFSETOF(EWPF_ifc_elem_t, a), \
+	sizeof(((EWPF_ifc_elem_t *)NULL)->a)
+#define EVENT_INFO(a) EWPF_IDX_TYPE_EVENT, EWPF_MAX_EVENT, OFFSETOF(EWPF_event_elem_t, a), \
+		sizeof(((EWPF_event_elem_t *)NULL)->a)
+#define KEY_INFO(a) EWPF_IDX_TYPE_KEY_INFO, EWPF_MAX_KEY_INFO, OFFSETOF(EWPF_key_info_elem_t, a), \
+		sizeof(((EWPF_key_info_elem_t *)NULL)->a)
+
+#define SLICE_U_SIZE(a) sizeof(((EWPF_slc_elem_t *)NULL)->a)
+#define SLICE_INFO_UNION(a) EWPF_IDX_TYPE_SLICE, EWPF_MAX_SLICE, OFFSETOF(EWPF_slc_elem_t, a)
+#define NONE_INFO(a) 0, 0, a, 0
+/* XTLV TBL for WL_SLICESTATS_XTLV_PERIODIC_STATE */
+static EWPF_tbl_t EWPF_periodic[] =
+{
+	{
+		WL_STATE_COMPACT_COUNTERS,
+		evt_xtlv_copy_cb,
+		SLICE_INFO(compact_cntr_v4),
+		NULL
+	},
+	{
+		WL_STATE_COMPACT_HE_COUNTERS,
+		evt_xtlv_copy_cb,
+		SLICE_INFO(compact_he_cnt),
+		NULL
+	},
+	{EWPF_XTLV_INVALID, NULL, NONE_INFO(0), NULL}
+};
+
+static EWPF_tbl_t EWPF_if_periodic[] =
+{
+	{
+		WL_STATE_IF_COMPACT_STATE,
+		evt_xtlv_copy_cb,
+		IFACE_INFO(if_comp_stat),
+		NULL
+	},
+	{
+		WL_STATE_IF_ADPS_STATE,
+		evt_xtlv_copy_cb,
+		IFACE_INFO(adps_dump_summary),
+		NULL
+	},
+	{
+		WL_STATE_IF_ADPS_ENERGY_GAIN,
+		evt_xtlv_copy_cb,
+		IFACE_INFO(adps_energy_gain),
+		NULL
+	},
+	{EWPF_XTLV_INVALID, NULL, NONE_INFO(0), NULL}
+};
+
+static EWPF_tbl_t EWPF_roam[] =
+{
+	{
+		WL_IFSTATS_XTLV_ROAM_STATS_EVENT,
+		evt_xtlv_print_cb,
+		NONE_INFO(0),
+		NULL
+	},
+	{
+		WL_IFSTATS_XTLV_ROAM_STATS_PERIODIC,
+		evt_xtlv_copy_cb,
+		IFACE_INFO(roam_stat),
+		NULL
+	},
+	{EWPF_XTLV_INVALID, NULL, NONE_INFO(0), NULL}
+};
+
+/* XTLV TBL for EVENT_LOG_TAG_STATS */
+static EWPF_tbl_t EWPF_main[] =
+{
+	/* MAIN XTLV */
+	{
+		WL_IFSTATS_XTLV_WL_SLICE,
+		evt_xtlv_type_cb,
+		NONE_INFO(0),
+		EWPF_main
+	},
+	{
+		WL_IFSTATS_XTLV_IF,
+		evt_xtlv_type_cb,
+		NONE_INFO(0),
+		EWPF_main
+	},
+	/* ID XTLVs */
+	{
+		WL_IFSTATS_XTLV_SLICE_INDEX,
+		evt_xtlv_idx_cb,
+		NONE_INFO(0),
+		NULL
+	},
+	{
+		WL_IFSTATS_XTLV_IF_INDEX,
+		evt_xtlv_idx_cb,
+		NONE_INFO(0),
+		NULL
+	},
+	/* NORMAL XTLVS */
+	{
+		WL_SLICESTATS_XTLV_PERIODIC_STATE,
+		NULL,
+		NONE_INFO(0),
+		EWPF_periodic
+	},
+	{
+		WL_IFSTATS_XTLV_IF_LQM,
+		evt_xtlv_copy_cb,
+		IFACE_INFO(lqm),
+		NULL
+	},
+	{
+		WL_IFSTATS_XTLV_GENERIC,
+		evt_xtlv_copy_cb,
+		IFACE_INFO(if_stat),
+		NULL
+	},
+	{
+		WL_IFSTATS_XTLV_MGT_CNT,
+		evt_xtlv_copy_cb,
+		IFACE_INFO(mgmt_stat),
+		NULL
+	},
+	{
+		WL_IFSTATS_XTLV_IF_PERIODIC_STATE,
+		NULL,
+		NONE_INFO(0),
+		EWPF_if_periodic
+	},
+	{
+		WL_IFSTATS_XTLV_INFRA_SPECIFIC,
+		evt_xtlv_copy_cb,
+		IFACE_INFO(infra),
+		NULL
+	},
+	{
+		WL_SLICESTATS_XTLV_HIST_TX_STATS,
+		evt_xtlv_copy_cb,
+		SLICE_INFO(hist_tx_toss_stat),
+		NULL
+	},
+	{
+		WL_SLICESTATS_XTLV_HIST_RX_STATS,
+		evt_xtlv_copy_cb,
+		SLICE_INFO(hist_rx_toss_stat),
+		NULL
+	},
+	{
+		WL_IFSTATS_XTLV_WL_SLICE_BTCOEX,
+		evt_xtlv_copy_cb,
+		SLICE_INFO(btc_stat),
+		NULL
+	},
+	{
+		WL_IFSTATS_XTLV_IF_EVENT_STATS,
+		evt_xtlv_copy_cb,
+		EVENT_INFO(event_stat),
+		NULL
+	},
+	{
+		WL_IFSTATS_XTLV_IF_EVENT_STATS,
+		evt_xtlv_print_cb,
+		NONE_INFO(0),
+		NULL
+	},
+	{
+		WL_IFSTATS_XTLV_KEY_PLUMB_INFO,
+		evt_xtlv_copy_cb,
+		KEY_INFO(key_update_info),
+		NULL
+	},
+	{
+		WL_IFSTATS_XTLV_ROAM_STATS_EVENT,
+		evt_xtlv_roam_cb,
+		NONE_INFO(0),
+		EWPF_roam
+	},
+	{
+		WL_IFSTATS_XTLV_ROAM_STATS_PERIODIC,
+		evt_xtlv_roam_cb,
+		IFACE_INFO(roam_stat),
+		EWPF_roam
+	},
+
+	{EWPF_XTLV_INVALID, NULL, NONE_INFO(0), NULL}
+};
+
+#if defined(DHD_EWPR_VER2) && defined(DHD_STATUS_LOGGING)
+
+#define EWP_DHD_STAT_SIZE 2
+
+uint8
+dhd_statlog_filter[] =
+{
+	ST(WLAN_POWER_ON),	/* Wi-Fi Power on */
+	ST(WLAN_POWER_OFF),	/* Wi-Fi Power off */
+	ST(ASSOC_START),	/* connect to the AP triggered by upper layer */
+	ST(AUTH_DONE),		/* complete to authenticate with the AP */
+	ST(ASSOC_REQ),		/* send or receive Assoc Req */
+	ST(ASSOC_RESP),		/* send or receive Assoc Resp */
+	ST(ASSOC_DONE),		/* complete to disconnect to the associated AP */
+	ST(DISASSOC_START),	/* disconnect to the associated AP by upper layer */
+	ST(DISASSOC_INT_START),	/* initiate the disassoc by DHD */
+	ST(DISASSOC_DONE),	/* complete to disconnect to the associated AP */
+	ST(DISASSOC),		/* send or receive Disassoc */
+	ST(DEAUTH),		/* send or receive Deauth */
+	ST(LINKDOWN),		/* receive the link down event */
+	ST(REASSOC_START),	/* reassoc the candidate AP */
+	ST(REASSOC_INFORM),	/* inform reassoc completion to upper layer */
+	ST(REASSOC_DONE),	/* complete to reassoc */
+	ST(EAPOL_M1),		/* send or receive the EAPOL M1 */
+	ST(EAPOL_M2),		/* send or receive the EAPOL M2 */
+	ST(EAPOL_M3),		/* send or receive the EAPOL M3 */
+	ST(EAPOL_M4),		/* send or receive the EAPOL M4 */
+	ST(EAPOL_GROUPKEY_M1),	/* send or receive the EAPOL Group key handshake M1 */
+	ST(EAPOL_GROUPKEY_M2),	/* send or receive the EAPOL Group key handshake M2 */
+	ST(EAP_REQ_IDENTITY),	/* send or receive the EAP REQ IDENTITY */
+	ST(EAP_RESP_IDENTITY),	/* send or receive the EAP RESP IDENTITY */
+	ST(EAP_REQ_TLS),	/* send or receive the EAP REQ TLS */
+	ST(EAP_RESP_TLS),	/* send or receive the EAP RESP TLS */
+	ST(EAP_REQ_LEAP),	/* send or receive the EAP REQ LEAP */
+	ST(EAP_RESP_LEAP),	/* send or receive the EAP RESP LEAP */
+	ST(EAP_REQ_TTLS),	/* send or receive the EAP REQ TTLS */
+	ST(EAP_RESP_TTLS),	/* send or receive the EAP RESP TTLS */
+	ST(EAP_REQ_AKA),	/* send or receive the EAP REQ AKA */
+	ST(EAP_RESP_AKA),	/* send or receive the EAP RESP AKA */
+	ST(EAP_REQ_PEAP),	/* send or receive the EAP REQ PEAP */
+	ST(EAP_RESP_PEAP),	/* send or receive the EAP RESP PEAP */
+	ST(EAP_REQ_FAST),	/* send or receive the EAP REQ FAST */
+	ST(EAP_RESP_FAST),	/* send or receive the EAP RESP FAST */
+	ST(EAP_REQ_PSK),	/* send or receive the EAP REQ PSK */
+	ST(EAP_RESP_PSK),	/* send or receive the EAP RESP PSK */
+	ST(EAP_REQ_AKAP),	/* send or receive the EAP REQ AKAP */
+	ST(EAP_RESP_AKAP),	/* send or receive the EAP RESP AKAP */
+	ST(EAP_SUCCESS),	/* send or receive the EAP SUCCESS */
+	ST(EAP_FAILURE),	/* send or receive the EAP FAILURE */
+	ST(EAPOL_START),	/* send or receive the EAPOL-START */
+	ST(WSC_START),		/* send or receive the WSC START */
+	ST(WSC_DONE),		/* send or receive the WSC DONE */
+	ST(WPS_M1),		/* send or receive the WPS M1 */
+	ST(WPS_M2),		/* send or receive the WPS M2 */
+	ST(WPS_M3),		/* send or receive the WPS M3 */
+	ST(WPS_M4),		/* send or receive the WPS M4 */
+	ST(WPS_M5),		/* send or receive the WPS M5 */
+	ST(WPS_M6),		/* send or receive the WPS M6 */
+	ST(WPS_M7),		/* send or receive the WPS M7 */
+	ST(WPS_M8),		/* send or receive the WPS M8 */
+	ST(8021X_OTHER),	/* send or receive the other 8021X frames */
+	ST(INSTALL_KEY),	/* install the key */
+	ST(DELETE_KEY),		/* remove the key */
+	ST(INSTALL_PMKSA),	/* install PMKID information */
+	ST(INSTALL_OKC_PMK),	/* install PMKID information for OKC */
+	ST(DHCP_DISCOVER),	/* send or recv DHCP Discover */
+	ST(DHCP_OFFER),		/* send or recv DHCP Offer */
+	ST(DHCP_REQUEST),	/* send or recv DHCP Request */
+	ST(DHCP_DECLINE),	/* send or recv DHCP Decline */
+	ST(DHCP_ACK),		/* send or recv DHCP ACK */
+	ST(DHCP_NAK),		/* send or recv DHCP NACK */
+	ST(DHCP_RELEASE),	/* send or recv DHCP Release */
+	ST(DHCP_INFORM),	/* send or recv DHCP Inform */
+	ST(REASSOC_SUCCESS),	/* reassociation success */
+	ST(REASSOC_FAILURE),	/* reassociation failure */
+	ST(AUTH_TIMEOUT),	/* authentication timeout */
+	ST(AUTH_FAIL),		/* authentication failure */
+	ST(AUTH_NO_ACK),	/* authentication failure due to no ACK */
+	ST(AUTH_OTHERS),	/* authentication failure with other status */
+	ST(ASSOC_TIMEOUT),	/* association timeout */
+	ST(ASSOC_FAIL),		/* association failure */
+	ST(ASSOC_NO_ACK),	/* association failure due to no ACK */
+	ST(ASSOC_ABORT),	/* association abort */
+	ST(ASSOC_UNSOLICITED),	/* association unsolicited */
+	ST(ASSOC_NO_NETWORKS),	/* association failure due to no networks */
+	ST(ASSOC_OTHERS),	/* association failure due to no networks */
+	ST(REASSOC_DONE_OTHERS)	/* complete to reassoc with other reason */
+};
+#endif /* DHD_EWPR_VER2 && DHD_STATUS_LOGGING  */
+
+/* ========= Module functions : exposed to others ============= */
+int
+dhd_event_log_filter_init(dhd_pub_t *dhdp, uint8 *buf, uint32 buf_size)
+{
+
+	EWP_filter_t *filter;
+	int idx;
+	uint32 req_size;
+	uint32 s_ring_size; /* slice ring */
+	uint32 i_ring_size; /* interface ring */
+	uint32 e_ring_size; /* event counter ring */
+	uint32 k_ring_size; /* key info ring */
+	uint8 *buf_ptr = buf;
+	EWPF_ctx_t ctx;
+	wl_event_based_statistics_v4_t dummy_event_stat;
+	key_update_info_v1_t dummy_key_update_info;
+#if defined(DHD_EWPR_VER2) && defined(DHD_STATUS_LOGGING)
+	stat_bdmask_req_t req;
+#endif /* DHD_EWPR_VER2 && DHD_STATUS_LOGGING */
+
+	DHD_FILTER_ERR(("STARTED\n"));
+
+	if (!dhdp || !buf) {
+		DHD_FILTER_ERR(("INVALID PTR: dhdp:%p buf:%p\n", dhdp, buf));
+		return BCME_ERROR;
+	}
+
+	i_ring_size = s_ring_size = e_ring_size = k_ring_size = dhd_ring_get_hdr_size();
+	s_ring_size += ((uint32)sizeof(EWPF_slc_elem_t)) * EWPF_REPORT_MAX_DATA;
+	i_ring_size += ((uint32)sizeof(EWPF_ifc_elem_t)) * EWPF_REPORT_MAX_DATA;
+	e_ring_size += ((uint32)sizeof(EWPF_event_elem_t)) * EWPF_REPORT_MAX_DATA;
+	k_ring_size += ((uint32)sizeof(EWPF_key_info_elem_t)) * EWPF_REPORT_MAX_DATA;
+
+	req_size = s_ring_size * EWPF_MAX_SLICE + i_ring_size * EWPF_MAX_IFACE +
+		e_ring_size * EWPF_MAX_EVENT + k_ring_size * EWPF_MAX_KEY_INFO;
+	req_size += (uint32)sizeof(EWP_filter_t);
+
+	if (buf_size < req_size) {
+		DHD_FILTER_ERR(("BUF SIZE IS TO SHORT: req:%d buf_size:%d\n",
+			req_size, buf_size));
+		return BCME_ERROR;
+	}
+
+	BCM_REFERENCE(dhdp);
+	filter = (EWP_filter_t *)buf;
+	buf_ptr += sizeof(EWP_filter_t);
+
+	/* initialize control block */
+	memset(filter, 0, sizeof(EWP_filter_t));
+
+	filter->idx_type = EWPF_INVALID;
+	filter->xtlv_idx = EWPF_INVALID;
+	filter->tmp_armcycle = 0;
+
+	for (idx = 0; idx < EWPF_MAX_SLICE; idx++) {
+		filter->s_ring[idx] = dhd_ring_init(dhdp, buf_ptr, s_ring_size,
+			sizeof(EWPF_slc_elem_t), EWPF_REPORT_MAX_DATA,
+			DHD_RING_TYPE_FIXED);
+		if (!filter->s_ring[idx]) {
+			DHD_FILTER_ERR(("FAIL TO INIT SLICE RING: %d\n", idx));
+			return BCME_ERROR;
+		}
+		buf_ptr += s_ring_size;
+	}
+
+	for (idx = 0; idx < EWPF_MAX_IFACE; idx++) {
+		filter->i_ring[idx] = dhd_ring_init(dhdp, buf_ptr, i_ring_size,
+			sizeof(EWPF_ifc_elem_t), EWPF_REPORT_MAX_DATA,
+			DHD_RING_TYPE_FIXED);
+		if (!filter->i_ring[idx]) {
+			DHD_FILTER_ERR(("FAIL TO INIT INTERFACE RING: %d\n", idx));
+			return BCME_ERROR;
+		}
+		buf_ptr += i_ring_size;
+	}
+
+	for (idx = 0; idx < EWPF_MAX_EVENT; idx++) {
+		filter->e_ring[idx] = dhd_ring_init(dhdp, buf_ptr, e_ring_size,
+			sizeof(EWPF_event_elem_t), EWPF_REPORT_MAX_DATA,
+			DHD_RING_TYPE_FIXED);
+		if (!filter->e_ring[idx]) {
+			DHD_FILTER_ERR(("FAIL TO INIT INTERFACE RING: %d\n", idx));
+			return BCME_ERROR;
+		}
+		buf_ptr += e_ring_size;
+	}
+
+	for (idx = 0; idx < EWPF_MAX_KEY_INFO; idx++) {
+		filter->k_ring[idx] = dhd_ring_init(dhdp, buf_ptr, k_ring_size,
+			sizeof(EWPF_key_info_elem_t), EWPF_REPORT_MAX_DATA,
+			DHD_RING_TYPE_FIXED);
+		if (!filter->k_ring[idx]) {
+			DHD_FILTER_ERR(("FAIL TO INIT INTERFACE RING: %d\n", idx));
+			return BCME_ERROR;
+		}
+		buf_ptr += k_ring_size;
+	}
+
+	dhdp->event_log_filter = filter;
+	filter->dhdp = dhdp;
+	filter->enabled = TRUE;
+
+	/*
+	 * put dummy element of event based encounters to prevent error
+	 * in case of no event happened when data collection is triggered
+	 */
+	ctx.dhdp = dhdp;
+	ctx.tbl = EWPF_main;
+	memset(&dummy_event_stat, 0x00, sizeof(dummy_event_stat));
+	evt_xtlv_copy_cb(&ctx, (uint8 *)&dummy_event_stat, WL_IFSTATS_XTLV_IF_EVENT_STATS,
+		sizeof(wl_event_based_statistics_v4_t));
+
+	memset(&dummy_key_update_info, 0x00, sizeof(dummy_key_update_info));
+	evt_xtlv_copy_cb(&ctx, (uint8 *)&dummy_key_update_info, WL_IFSTATS_XTLV_KEY_PLUMB_INFO,
+		sizeof(key_update_info_v1_t));
+
+#if defined(DHD_EWPR_VER2) && defined(DHD_STATUS_LOGGING)
+	/* create status filter for bigdata logging */
+	req.req_buf = dhd_statlog_filter;
+	req.req_buf_len = sizeof(dhd_statlog_filter);
+	dhd_statlog_generate_bdmask(dhdp, &req);
+#endif /* DHD_EWPR_VER2 && DHD_STATUS_LOGGING */
+
+	return BCME_OK;
+}
+
+void
+dhd_event_log_filter_deinit(dhd_pub_t *dhdp)
+{
+	EWP_filter_t *filter;
+	int idx;
+
+	if (!dhdp) {
+		return;
+	}
+
+	if (dhdp->event_log_filter) {
+		filter = (EWP_filter_t *)dhdp->event_log_filter;
+		for (idx = 0; idx < EWPF_MAX_SLICE; idx ++) {
+			dhd_ring_deinit(dhdp, filter->s_ring[idx]);
+		}
+		for (idx = 0; idx < EWPF_MAX_IFACE; idx ++) {
+			dhd_ring_deinit(dhdp, filter->i_ring[idx]);
+		}
+		for (idx = 0; idx < EWPF_MAX_EVENT; idx ++) {
+			dhd_ring_deinit(dhdp, filter->e_ring[idx]);
+		}
+		for (idx = 0; idx < EWPF_MAX_KEY_INFO; idx ++) {
+			dhd_ring_deinit(dhdp, filter->k_ring[idx]);
+		}
+		dhdp->event_log_filter = NULL;
+	}
+}
+
+void
+dhd_event_log_filter_notify_connect_request(dhd_pub_t *dhdp, uint8 *bssid, int channel)
+{
+	EWP_filter_t *filter;
+	void *last_elem;
+
+	if (!dhdp || !dhdp->event_log_filter) {
+		return;
+	}
+
+	filter = (EWP_filter_t *)dhdp->event_log_filter;
+	if (filter->enabled != TRUE) {
+		DHD_FILTER_ERR(("EWP Filter is not enabled\n"));
+		return;
+	}
+
+	memcpy(filter->last_bssid, bssid, ETHER_ADDR_LEN);
+	filter->last_channel = channel;
+
+	/* Refer STA interface */
+	last_elem = dhd_ring_get_last(filter->i_ring[0]);
+	if (last_elem == NULL) {
+		filter->last_armcycle = 0;
+	} else {
+		/* EXCLUDE before connect start */
+		filter->last_armcycle = *(uint32 *)last_elem + EWPF_EPOCH + 1;
+	}
+}
+
+void
+dhd_event_log_filter_notify_connect_done(dhd_pub_t *dhdp, uint8 *bssid, int roam)
+{
+	EWP_filter_t *filter;
+	void *last_elem;
+	int channel;
+	char buf[EWPF_DEBUG_BUF_LEN];
+	int ret;
+	uint32 armcycle;
+	struct channel_info *ci;
+
+	if (!dhdp || !dhdp->event_log_filter) {
+		return;
+	}
+
+	filter = (EWP_filter_t *)dhdp->event_log_filter;
+	if (filter->enabled != TRUE) {
+		DHD_FILTER_ERR(("EWP Filter is not enabled\n"));
+		return;
+	}
+
+	/* GET CHANNEL */
+	*(uint32 *)buf = htod32(EWPF_DEBUG_BUF_LEN);
+	ret = dhd_wl_ioctl_cmd(dhdp, WLC_GET_CHANNEL, buf, EWPF_DEBUG_BUF_LEN, FALSE, 0);
+	if (ret != BCME_OK) {
+		DHD_FILTER_ERR(("FAIL TO GET BSS INFO: %d\n", ret));
+		return;
+	}
+
+	ci = (struct channel_info *)(buf + sizeof(uint32));
+	channel = dtoh32(ci->hw_channel);
+	DHD_FILTER_TRACE(("CHANNEL:prev %d new:%d\n", filter->last_channel, channel));
+
+	memcpy(filter->last_bssid, bssid, ETHER_ADDR_LEN);
+	filter->last_channel = channel;
+	if (roam == FALSE) {
+		return;
+	}
+
+	/* update connect time for roam */
+	/* Refer STA interface */
+	last_elem = dhd_ring_get_last(filter->i_ring[0]);
+	if (last_elem == NULL) {
+		armcycle = 0;
+	} else {
+		/* EXCLUDE before roam done */
+		armcycle = *(uint32 *)last_elem + EWPF_EPOCH + 1;
+	}
+
+	filter->last_armcycle = armcycle;
+}
+
+static int
+evt_xtlv_print_cb(void *ctx, const uint8 *data, uint16 type, uint16 len)
+{
+	EWPF_ctx_t *cur_ctx = (EWPF_ctx_t *)ctx;
+	EWP_filter_t *filter = (EWP_filter_t *)cur_ctx->dhdp->event_log_filter;
+	uint32 armcycle = 0;
+	uint8 bssid[ETHER_ADDR_LEN];
+	uint32 initial_assoc_time = 0;
+	uint32 prev_roam_time = 0;
+	uint32 last_roam_event_type = 0;
+	uint32 last_roam_event_status = 0;
+	uint32 last_roam_event_reason = 0;
+	wl_wips_event_info_t wips_event;
+	bzero(&wips_event, sizeof(wips_event));
+
+	DHD_FILTER_TRACE(("%s type:%d %x len:%d %x\n", __FUNCTION__, type, type, len, len));
+
+	/* get current armcycle */
+	if (filter) {
+		armcycle = filter->tmp_armcycle;
+	}
+	if (type == WL_IFSTATS_XTLV_IF_EVENT_STATS) {
+		wl_event_based_statistics_v1_t *elem;
+
+		elem = (wl_event_based_statistics_v1_t *)(uintptr_t)data;
+		if (elem->txdeauthivalclass > 0) {
+			memcpy(bssid, &elem->BSSID, ETHER_ADDR_LEN);
+			DHD_ERROR(("DHD STA sent DEAUTH frame with invalid class : %d times"
+				", BSSID("MACDBG")\n", elem->txdeauthivalclass, MAC2STRDBG(bssid)));
+		}
+		if (elem->version == WL_EVENT_STATISTICS_VER_2) {
+			wl_event_based_statistics_v2_t *elem_v2;
+
+			elem_v2 = (wl_event_based_statistics_v2_t *)(uintptr_t)data;
+			memcpy(&wips_event.bssid, &elem_v2->last_deauth, ETHER_ADDR_LEN);
+			wips_event.misdeauth = elem_v2->misdeauth;
+			wips_event.current_RSSI = elem_v2->cur_rssi;
+			wips_event.deauth_RSSI = elem_v2->deauth_rssi;
+			wips_event.timestamp = elem_v2->timestamp;
+		} else if (elem->version == WL_EVENT_STATISTICS_VER_3) {
+			wl_event_based_statistics_v3_t *elem_v3;
+
+			elem_v3 = (wl_event_based_statistics_v3_t *)(uintptr_t)data;
+			memcpy(&wips_event.bssid, &elem_v3->last_deauth, ETHER_ADDR_LEN);
+			wips_event.misdeauth = elem_v3->misdeauth;
+			wips_event.current_RSSI = elem_v3->cur_rssi;
+			wips_event.deauth_RSSI = elem_v3->deauth_rssi;
+			wips_event.timestamp = elem_v3->timestamp;
+			/* roam statistics */
+			initial_assoc_time = elem_v3->initial_assoc_time;
+			prev_roam_time = elem_v3->prev_roam_time;
+			last_roam_event_type = elem_v3->last_roam_event_type;
+			last_roam_event_status = elem_v3->last_roam_event_status;
+			last_roam_event_reason = elem_v3->last_roam_event_reason;
+		} else if (elem->version == WL_EVENT_STATISTICS_VER_4) {
+			wl_event_based_statistics_v4_t *elem_v4;
+
+			elem_v4 = (wl_event_based_statistics_v4_t *)(uintptr_t)data;
+			memcpy(&wips_event.bssid, &elem_v4->last_deauth, ETHER_ADDR_LEN);
+			wips_event.misdeauth = elem_v4->misdeauth;
+			wips_event.current_RSSI = elem_v4->cur_rssi;
+			wips_event.deauth_RSSI = elem_v4->deauth_rssi;
+			wips_event.timestamp = elem_v4->timestamp;
+		}
+		if (wips_event.misdeauth > 1) {
+			DHD_ERROR(("WIPS attack!! cnt=%d, curRSSI=%d, deauthRSSI=%d "
+				", time=%d, MAC="MACDBG"\n",
+				wips_event.misdeauth, wips_event.current_RSSI,
+				wips_event.deauth_RSSI,	wips_event.timestamp,
+				MAC2STRDBG(&wips_event.bssid)));
+#if defined(WL_CFG80211) && defined(WL_WIPSEVT)
+			wl_cfg80211_wips_event_ext(&wips_event);
+#endif /* WL_CFG80211 && WL_WIPSEVT */
+		}
+	} else if (type == WL_IFSTATS_XTLV_ROAM_STATS_EVENT) {
+		wl_roam_stats_v1_t *roam_elem;
+		roam_elem = (wl_roam_stats_v1_t *)(uintptr_t)data;
+		if (roam_elem->version == WL_ROAM_STATS_VER_1) {
+			wl_roam_stats_v1_t *roam_elem_v1;
+
+			roam_elem_v1 = (wl_roam_stats_v1_t *)(uintptr_t)data;
+			/* roam statistics */
+			initial_assoc_time = roam_elem_v1->initial_assoc_time;
+			prev_roam_time = roam_elem_v1->prev_roam_time;
+			last_roam_event_type = roam_elem_v1->last_roam_event_type;
+			last_roam_event_status = roam_elem_v1->last_roam_event_status;
+			last_roam_event_reason = roam_elem_v1->last_roam_event_reason;
+		}
+	} else {
+		DHD_FILTER_ERR(("%s TYPE(%d) IS NOT SUPPORTED TO PRINT\n",
+			__FUNCTION__, type));
+		return BCME_ERROR;
+	}
+	if (initial_assoc_time > 0 && prev_roam_time > 0) {
+		DHD_ERROR(("Last roam event before disconnection : "
+			"current armcycle %d, initial assoc time %d, "
+			"last event time %d, type %d, status %d, reason %d\n",
+			armcycle, initial_assoc_time, prev_roam_time,
+			last_roam_event_type, last_roam_event_status,
+			last_roam_event_reason));
+	}
+
+	return BCME_OK;
+}
+
+#ifdef BCM_SDC
+static int
+evt_get_last_toss_hist(uint8 *ptr, const uint8 *data, uint16 len)
+{
+	bcm_xtlv_t *bcm_xtlv_desc = (bcm_xtlv_t *)data;
+	wl_hist_compact_toss_stats_v3_t *ewp_stats;
+	evt_hist_compact_toss_stats_v1_t bidata_stats;
+	int16 max_rcidx = EWPF_INVALID, secnd_rcidx = EWPF_INVALID;
+	uint16 cur_rnidx = 0, prev_rnidx = 0;
+	uint16 max_rccnt = 0, cur_rccnt = 0;
+	uint16 idx;
+
+	if (!ptr || !data) {
+		return BCME_ERROR;
+	}
+
+	if (bcm_xtlv_desc->len != sizeof(wl_hist_compact_toss_stats_v3_t)) {
+		DHD_FILTER_ERR(("%s : size is not matched  %d\n", __FUNCTION__,
+			bcm_xtlv_desc->len));
+		return BCME_ERROR;
+	}
+
+	ewp_stats = (wl_hist_compact_toss_stats_v3_t *)(&bcm_xtlv_desc->data[0]);
+	if (ewp_stats->htr_type == WL_STATE_HIST_TX_TOSS_REASONS) {
+		if (ewp_stats->version != WL_HIST_COMPACT_TOSS_STATS_TX_VER_3) {
+			DHD_FILTER_ERR(("%s : unsupported version %d (type: %d)\n",
+				__FUNCTION__, ewp_stats->version, ewp_stats->htr_type));
+			return BCME_ERROR;
+		}
+	} else if (ewp_stats->htr_type == WL_STATE_HIST_RX_TOSS_REASONS) {
+		if (ewp_stats->version != WL_HIST_COMPACT_TOSS_STATS_RX_VER_3) {
+			DHD_FILTER_ERR(("%s : unsupported version %d (type: %d)\n",
+				__FUNCTION__, ewp_stats->version, ewp_stats->htr_type));
+			return BCME_ERROR;
+		}
+	} else {
+		DHD_FILTER_ERR(("%s : unsupported type %d\n", __FUNCTION__,
+			ewp_stats->htr_type));
+		return BCME_ERROR;
+	}
+	/*
+	 * htr_rnidx is pointing the next empty slot to be used
+	 * Need to get previous index which is valid
+	 */
+	if (ewp_stats->htr_rnidx > 0) {
+		cur_rnidx = ewp_stats->htr_rnidx - 1;
+	} else {
+		cur_rnidx = WLC_HIST_TOSS_LEN - 1;
+	}
+	if (cur_rnidx > 0) {
+		prev_rnidx = cur_rnidx - 1;
+	} else {
+		prev_rnidx = WLC_HIST_TOSS_LEN - 1;
+	}
+	/*
+	 * Need to get largest count of toss reasons
+	 */
+	for (idx = 0; idx < WLC_HIST_TOSS_LEN; idx ++) {
+		cur_rccnt = (uint16)(ewp_stats->htr_rc[idx].toss_cnt);
+		DHD_FILTER_TRACE(("%s: idx %d htr_rc %04x cur_rccnt %d\n",
+			__FUNCTION__, idx, ewp_stats->htr_rc[idx].toss_reason, cur_rccnt));
+		if (ewp_stats->htr_rc_ts[idx] && max_rccnt < cur_rccnt) {
+			max_rccnt = cur_rccnt;
+			secnd_rcidx = max_rcidx;
+			max_rcidx = idx;
+			DHD_FILTER_TRACE(("%s: max_rcidx updated -"
+				"max_rcidx %d secnd_rcidx %d\n",
+				__FUNCTION__, max_rcidx, secnd_rcidx));
+		}
+	}
+
+	memset(&bidata_stats, 0x00, sizeof(bidata_stats));
+	bidata_stats.version = ewp_stats->version;
+	bidata_stats.htr_type = ewp_stats->htr_type;
+	bidata_stats.htr_num = ewp_stats->htr_num;
+	bidata_stats.htr_rn_last = *(uint32*)(&ewp_stats->htr_running[cur_rnidx]);
+	bidata_stats.htr_rn_ts_last = ewp_stats->htr_rn_ts[cur_rnidx];
+	bidata_stats.htr_rn_prev = *(uint32*)(&ewp_stats->htr_running[prev_rnidx]);
+	bidata_stats.htr_rn_ts_prev = ewp_stats->htr_rn_ts[prev_rnidx];
+	if (max_rcidx != EWPF_INVALID) {
+		bidata_stats.htr_rc_max = *(uint32*)(&ewp_stats->htr_rc[max_rcidx]);
+		bidata_stats.htr_rc_ts_max = ewp_stats->htr_rc_ts[max_rcidx];
+	}
+	if (secnd_rcidx != EWPF_INVALID) {
+		bidata_stats.htr_rc_secnd = *(uint32*)(&ewp_stats->htr_rc[secnd_rcidx]);
+		bidata_stats.htr_rc_ts_secnd = ewp_stats->htr_rc_ts[secnd_rcidx];
+	}
+	DHD_FILTER_TRACE(("%s: ver %d type %d num %d "
+		"htr_rn_last %d htr_rn_ts_last %d htr_rn_prev %d htr_rn_ts_prev %d "
+		"htr_rc_max %d htr_rc_ts_max %d htr_rc_secnd %d htr_rc_ts_secnd %d\n",
+		__FUNCTION__, bidata_stats.version,
+		bidata_stats.htr_type, bidata_stats.htr_num,
+		bidata_stats.htr_rn_last, bidata_stats.htr_rn_ts_last,
+		bidata_stats.htr_rn_prev, bidata_stats.htr_rn_ts_prev,
+		bidata_stats.htr_rc_max, bidata_stats.htr_rc_ts_max,
+		bidata_stats.htr_rc_secnd, bidata_stats.htr_rc_ts_secnd));
+
+	memcpy(ptr, &bidata_stats, sizeof(bidata_stats));
+
+	return BCME_OK;
+}
+#endif /* BCM_SDC */
+
+static int
+evt_xtlv_copy_cb(void *ctx, const uint8 *data, uint16 type, uint16 len)
+{
+	EWPF_ctx_t *cur_ctx = (EWPF_ctx_t *)ctx;
+	EWP_filter_t *filter = (EWP_filter_t *)cur_ctx->dhdp->event_log_filter;
+	uint32 *armcycle;
+	EWPF_tbl_t *tbl;
+	void *ring;
+	void *target;
+	uint8 *ptr;
+	int tbl_idx;
+	uint32 elem_size;
+
+	DHD_FILTER_TRACE(("%s type:%d %x len:%d %x\n", __FUNCTION__, type, type, len, len));
+
+	for (tbl_idx = 0; ; tbl_idx++) {
+		if (cur_ctx->tbl[tbl_idx].xtlv_id == EWPF_XTLV_INVALID) {
+			DHD_FILTER_ERR(("%s NOT SUPPORTED TYPE(%d)\n", __FUNCTION__, type));
+			return BCME_OK;
+		}
+		if (cur_ctx->tbl[tbl_idx].xtlv_id == type) {
+			tbl = &cur_ctx->tbl[tbl_idx];
+			break;
+		}
+	}
+
+	/* Set index type and xtlv_idx for event stats and key plumb info */
+	if (type == WL_IFSTATS_XTLV_IF_EVENT_STATS) {
+		filter->idx_type = EWPF_IDX_TYPE_EVENT;
+		filter->xtlv_idx = 0;
+		DHD_FILTER_TRACE(("EVENT XTLV\n"));
+	} else if (type == WL_IFSTATS_XTLV_KEY_PLUMB_INFO) {
+		filter->idx_type = EWPF_IDX_TYPE_KEY_INFO;
+		filter->xtlv_idx = 0;
+		DHD_FILTER_TRACE(("KEY INFO XTLV\n"));
+	}
+
+	/* Check Validation */
+	if (filter->idx_type == EWPF_INVALID ||
+		filter->xtlv_idx == EWPF_INVALID ||
+		filter->idx_type != tbl->idx_type ||
+		filter->xtlv_idx >= tbl->max_idx) {
+		DHD_FILTER_ERR(("XTLV VALIDATION FAILED: type:%x xtlv:%x idx:%d\n",
+			filter->idx_type, tbl->xtlv_id, filter->xtlv_idx));
+		return BCME_OK;
+	}
+
+	/* SET RING INFO */
+	if (filter->idx_type == EWPF_IDX_TYPE_SLICE) {
+		ring = filter->s_ring[filter->xtlv_idx];
+		elem_size = sizeof(EWPF_slc_elem_t);
+	} else if (filter->idx_type == EWPF_IDX_TYPE_IFACE) {
+		ring = filter->i_ring[filter->xtlv_idx];
+		elem_size = sizeof(EWPF_ifc_elem_t);
+	} else if (filter->idx_type == EWPF_IDX_TYPE_EVENT) {
+		DHD_FILTER_TRACE(("%s: EWPF_IDX_TYPE_EVENT FOUND\n",
+		__FUNCTION__));
+		ring = filter->e_ring[filter->xtlv_idx];
+		elem_size = sizeof(EWPF_event_elem_t);
+	} else if (filter->idx_type == EWPF_IDX_TYPE_KEY_INFO) {
+		DHD_FILTER_TRACE(("%s: EWPF_IDX_TYPE_KEY_INFO FOUND\n",
+		__FUNCTION__));
+		ring = filter->k_ring[filter->xtlv_idx];
+		elem_size = sizeof(EWPF_key_info_elem_t);
+	} else {
+		DHD_FILTER_TRACE(("%s unsupported idx_type:%d\n",
+			__FUNCTION__, filter->idx_type));
+		return BCME_OK;
+	}
+
+	/* Check armcycle epoch is changed */
+	target = dhd_ring_get_last(ring);
+	if (target != NULL) {
+		armcycle = (uint32 *)target;
+		if (*armcycle + EWPF_EPOCH <= filter->tmp_armcycle) {
+			/* EPOCH is changed (longer than 1sec) */
+			target = NULL;
+		} else if (*armcycle - EWPF_EPOCH >= filter->tmp_armcycle) {
+			/* dongle is rebooted */
+			target = NULL;
+		}
+	}
+
+	if (target == NULL) {
+		/* Get new idx */
+		target = dhd_ring_get_empty(ring);
+		if (target == NULL) {
+			/* no available slot due to oldest slot is locked */
+			DHD_FILTER_ERR(("SKIP to logging xltv(%x) due to locking\n", type));
+			return BCME_OK;
+		}
+
+		/* clean up target */
+		armcycle = (uint32 *)target;
+		memset(target, 0, elem_size);
+		memcpy(armcycle, &filter->tmp_armcycle, sizeof(*armcycle));
+	}
+
+#ifdef EWPF_DEBUG
+	DHD_FILTER_ERR(("idx:%d write_:%p %u %u\n",
+		filter->xtlv_idx, target, *armcycle, filter->tmp_armcycle));
+#endif
+
+	/* Additionally put updated armcycle for event based EWP */
+	if (filter->idx_type == EWPF_IDX_TYPE_EVENT ||
+		filter->idx_type == EWPF_IDX_TYPE_KEY_INFO) {
+		DHD_FILTER_TRACE(("%s: updated armcycle for event based EWP\n",
+		__FUNCTION__));
+		memcpy((uint32 *)(armcycle + EWPF_UPDATE_ARM_CYCLE_OFFSET),
+			&filter->tmp_armcycle, sizeof(*armcycle));
+	}
+
+	ptr = (uint8 *)target;
+
+#ifdef DHD_EWPR_VER2
+	if (tbl->xtlv_id == WL_SLICESTATS_XTLV_HIST_TX_STATS ||
+			tbl->xtlv_id == WL_SLICESTATS_XTLV_HIST_RX_STATS) {
+#ifdef BCM_SDC
+		int err;
+
+		DHD_FILTER_TRACE(("TOSS_REASONS received (%d)\n", tbl->xtlv_id));
+
+		err = evt_get_last_toss_hist(ptr + cur_ctx->tbl[tbl_idx].offset, data, len);
+		if (err) {
+			DHD_FILTER_ERR(("%s: get toss hist failed\n",
+				__FUNCTION__));
+			return BCME_ERROR;
+		}
+#else
+		DHD_FILTER_ERR(("%s: Unabled to copy hist TX/RX stats, BCM_SDC must be included\n",
+			__FUNCTION__));
+#endif /* BCM_SDC */
+	} else
+#endif /* DHD_EWPR_VER2 */
+	{
+		/* XXX multiversion shall be use same structure of old version */
+		if (len > cur_ctx->tbl[tbl_idx].member_length) {
+			DHD_FILTER_TRACE(("data Length is too big to save: (alloc = %d), "
+				"(data = %d)\n", cur_ctx->tbl[tbl_idx].member_length, len));
+			len = cur_ctx->tbl[tbl_idx].member_length;
+		}
+
+		memcpy(ptr + cur_ctx->tbl[tbl_idx].offset, data, len);
+	}
+	return BCME_OK;
+}
+
+static int
+evt_xtlv_idx_cb(void *ctx, const uint8 *data, uint16 type, uint16 len)
+{
+	EWPF_ctx_t *cur_ctx = (EWPF_ctx_t *)ctx;
+	EWP_filter_t *filter = (EWP_filter_t *)cur_ctx->dhdp->event_log_filter;
+
+	filter->xtlv_idx = data[0];
+
+	if (filter->idx_type == EWPF_IDX_TYPE_SLICE) {
+		if (type != WL_IFSTATS_XTLV_SLICE_INDEX ||
+			filter->xtlv_idx >= EWPF_MAX_SLICE) {
+			goto idx_fail;
+		}
+	} else if (filter->idx_type == EWPF_IDX_TYPE_IFACE) {
+		if (type != WL_IFSTATS_XTLV_IF_INDEX ||
+			filter->xtlv_idx >= EWPF_MAX_IFACE) {
+			DHD_FILTER_ERR(("CHANGE IFACE TO 0 in FORCE\n"));
+			return BCME_OK;
+		}
+	} else {
+		goto idx_fail;
+	}
+	return BCME_OK;
+
+idx_fail:
+	DHD_FILTER_ERR(("UNEXPECTED IDX XTLV: filter_type:%d input_type%x idx:%d\n",
+		filter->idx_type, type, filter->xtlv_idx));
+	filter->idx_type = EWPF_INVALID;
+	filter->xtlv_idx = EWPF_INVALID;
+	return BCME_OK;
+}
+
+static int
+evt_xtlv_type_cb(void *ctx, const uint8 *data, uint16 type, uint16 len)
+{
+	EWPF_ctx_t *cur_ctx = (EWPF_ctx_t *)ctx;
+	EWP_filter_t *filter = (EWP_filter_t *)cur_ctx->dhdp->event_log_filter;
+
+	if (type == WL_IFSTATS_XTLV_WL_SLICE) {
+		filter->idx_type = EWPF_IDX_TYPE_SLICE;
+		DHD_FILTER_TRACE(("SLICE XTLV\n"));
+	} else if (type == WL_IFSTATS_XTLV_IF) {
+		filter->idx_type = EWPF_IDX_TYPE_IFACE;
+		DHD_FILTER_TRACE(("IFACE XTLV\n"));
+	}
+
+	bcm_unpack_xtlv_buf(ctx, data, len,
+		BCM_XTLV_OPTION_ALIGN32, filter_main_cb);
+	return BCME_OK;
+}
+
+static int
+evt_xtlv_roam_cb(void *ctx, const uint8 *data, uint16 type, uint16 len)
+{
+
+	EWPF_ctx_t *cur_ctx = (EWPF_ctx_t *)ctx;
+	EWPF_tbl_t *new_tbl = EWPF_roam;
+	EWPF_ctx_t sub_ctx;
+	int idx;
+
+	for (idx = 0; ; idx++) {
+		if (new_tbl[idx].xtlv_id == EWPF_XTLV_INVALID) {
+			DHD_FILTER_TRACE(("%s NOT SUPPORTED TYPE(%d)\n", __FUNCTION__, type));
+			return BCME_OK;
+		}
+		if (new_tbl[idx].xtlv_id == type) {
+			break;
+		}
+	}
+
+	/* MULTI version may not applied */
+	if (len > sizeof(cur_ctx->dhdp->roam_evt)) {
+		DHD_FILTER_ERR(("data length is too big :max= %d, cur=%d\n",
+				(int)sizeof(cur_ctx->dhdp->roam_evt), len));
+		len = sizeof(cur_ctx->dhdp->roam_evt);
+	}
+
+	/* save latest roam event to report via get_bss_info */
+	(void)memcpy_s((char *)&cur_ctx->dhdp->roam_evt, sizeof(cur_ctx->dhdp->roam_evt),
+			data, len);
+
+	sub_ctx.dhdp = cur_ctx->dhdp;
+	sub_ctx.tbl = new_tbl;
+	new_tbl[idx].cb_func(&sub_ctx, data, type, len);
+	return BCME_OK;
+}
+
+static int
+filter_main_cb(void *ctx, const uint8 *data, uint16 type, uint16 len)
+{
+	EWPF_ctx_t *cur_ctx = (EWPF_ctx_t *)ctx;
+	EWPF_ctx_t sub_ctx;
+	int idx;
+	int err = BCME_OK;
+
+	DHD_FILTER_TRACE(("%s type:%x len:%d\n", __FUNCTION__, type, len));
+
+	sub_ctx.dhdp = cur_ctx->dhdp;
+	for (idx = 0; ; idx++) {
+		if (cur_ctx->tbl[idx].xtlv_id == EWPF_XTLV_INVALID) {
+			DHD_FILTER_TRACE(("%s NOT SUPPORTED TYPE(%d)\n", __FUNCTION__, type));
+			return BCME_OK;
+		}
+		if (cur_ctx->tbl[idx].xtlv_id == type) {
+			/* parse sub xtlv */
+			if (cur_ctx->tbl[idx].cb_func == NULL) {
+				sub_ctx.tbl = cur_ctx->tbl[idx].tbl;
+				err = bcm_unpack_xtlv_buf(&sub_ctx, data, len,
+						BCM_XTLV_OPTION_ALIGN32, filter_main_cb);
+				return err;
+			}
+
+			/* handle for structure/variable */
+			err = cur_ctx->tbl[idx].cb_func(ctx, data, type, len);
+			if (err != BCME_OK) {
+				return err;
+			}
+		}
+	}
+
+	return err;
+}
+
+void
+dhd_event_log_filter_event_handler(dhd_pub_t *dhdp, prcd_event_log_hdr_t *plog_hdr, uint32 *data)
+{
+	int err;
+	EWP_filter_t *filter;
+	EWPF_ctx_t ctx;
+
+	if (!dhdp->event_log_filter) {
+		DHD_FILTER_ERR(("NO FILTER MODULE\n"));
+		return;
+	}
+
+	if (!plog_hdr || !data) {
+		/* XXX Validation check is done by caller */
+		DHD_FILTER_ERR(("INVALID PARAMETER\n"));
+		return;
+	}
+
+	filter = (EWP_filter_t *)dhdp->event_log_filter;
+	if (filter->enabled != TRUE) {
+		DHD_FILTER_ERR(("FITLER IS NOT STARTED\n"));
+		return;
+	}
+
+	/* get ARMCYCLE */
+	filter->tmp_armcycle = plog_hdr->armcycle;
+	filter->idx_type = EWPF_INVALID;
+	filter->xtlv_idx = EWPF_INVALID;
+
+#ifdef EWPF_DEBUG
+	{
+		char buf[EWPF_DEBUG_BUF_LEN];
+		int idx;
+
+		memset(buf, 0, sizeof(buf));
+		DHD_FILTER_ERR(("tag %d(%x) count %d(%x)\n",
+			plog_hdr->tag, plog_hdr->tag, plog_hdr->count, plog_hdr->count));
+		for (idx = 0; idx < plog_hdr->count; idx++) {
+			sprintf(&buf[strlen(buf)], "%08x ", data[idx]);
+			if ((idx + 1) % EWPF_VAL_CNT_PLINE == 0) {
+				DHD_FILTER_ERR(("%s\n", buf));
+				memset(buf, 0, sizeof(buf));
+			}
+		}
+		if (strlen(buf) > 0) {
+			DHD_FILTER_ERR(("%s\n", buf));
+		}
+	}
+#endif /* EWPF_DEBUG */
+
+	ctx.dhdp = dhdp;
+	ctx.tbl = EWPF_main;
+	if ((err = bcm_unpack_xtlv_buf(
+		&ctx,
+		(const uint8 *)data,
+		(plog_hdr->count - 1) * sizeof(uint32),
+		BCM_XTLV_OPTION_ALIGN32,
+		filter_main_cb))) {
+		DHD_FILTER_ERR(("FAIL TO UNPACK XTLV: err(%d)\n", err));
+	}
+}
+/* ========= Private Command(Serialize) ============= */
+/* XXX REPORT MODULE will be done after discuss with customer */
+/* XXX Current implementation is temporal to verify FILTER MODULE works */
+//#define EWPR_DEBUG
+#ifdef EWPR_DEBUG
+#undef DHD_FILTER_TRACE
+#define DHD_FILTER_TRACE DHD_FILTER_ERR
+#endif /* EWPR_DEBUG */
+#define EWPR_DEBUG_BUF_LEN	512
+
+#define EWP_REPORT_ELEM_PRINT_BUF	256
+#define EWP_REPORT_NAME_MAX		64
+
+#ifdef DHD_EWPR_VER2
+#define EWP_REPORT_VERSION	0x20200722
+#define EWP_REPORT_SET_DEFAULT	0x01
+#define EWPR_CSDCLIENT_DIFF	10
+#define EWPR_INTERVAL	3
+#define EWPR_DELTA_CNT	1	/* 3 seconds before */
+#define EWPR_ARRAY_CNT	10	/* INTERVAL * ARRAY total 30 seconds to lock */
+#define EWPR_DELTA_LAST_POS		6
+
+#define INDEX_STR_SIZE		6
+#define	DHD_STAT_STR_SIZE	2
+#define REPORT_VERSION_STR_SIZE	8
+#define DELIMITER_LEN		1
+#else
+#define EWP_REPORT_VERSION	0x20170905
+#define EWPR_CSDCLIENT_DIFF	4
+#define EWPR_INTERVAL	3
+#define EWPR_ARRAY_CNT	10	/* INTERVAL * ARRAY total 30 seconds to lock */
+#endif /* DHD_EWPR_VER2 */
+
+#define EWPR_DELTA3_POS		3
+#define EWPR_DELTA2_POS		2
+#define EWPR_DELTA1_POS		1
+#define EWPR_NOW_POS		0
+
+#define EWPR_DELTA1_CNT	2	/* 6 seconds before */
+#define EWPR_DELTA2_CNT	5	/* 15 seconds before */
+#define EWPR_DELTA3_CNT	9	/* 27 seconds before */
+
+#define EWPR_CNT_PER_LINE	5
+
+/* EWP Reporter display format */
+#define EWP_DEC	1
+#define EWP_HEX	2
+#define EWP_BIN	3
+
+/* EWP Filter Data type */
+/* BASIC : signed + length */
+#define EWP_UINT8	2
+#define EWP_UINT16	4
+#define EWP_UINT32	8
+#define EWP_UINT64	16
+#define EWP_INT8	102
+#define EWP_INT16	104
+#define EWP_INT32	108
+#define EWP_BIT		201
+
+/* NON BAISC : need special handling */
+#define EWP_NON_BASIC	200
+#define EWP_DATE		201
+#define EWP_TIME		202
+#define EWP_BSSID		203
+#define EWP_OUI			204
+
+/* Delimiter between values */
+#define KEY_DEL	' '
+#define RAW_DEL '_'
+
+/* IOVAR BUF SIZE */
+#define EWPR_IOV_BUF_LEN	64
+
+typedef struct {
+	void *ring;				/* INPUT ring to lock */
+	void **elem_list;		/* OUTPUT elem ptr list for each delta */
+	uint32 max_armcycle;	/* IN/OUT arm cycle should be less than this */
+	uint32 min_armcycle;	/* IN/OUT arm cycle should be bigger than this */
+	uint32 max_period;		/* IN allowed time diff between first and last */
+	uint32 delta_cnt;		/* IN finding delta count */
+	uint32 *delta_list;		/* IN delta values to find */
+} ewpr_lock_param_t;
+
+#define MAX_MULTI_VER	4
+typedef struct {
+	uint32	version;		/* VERSION for multiple version struct */
+	uint32	offset;			/* offset of the member at the version */
+} ewpr_MVT_offset_elem_t;	/* elem for multi version type */
+
+typedef struct {
+	uint32	version_offset;		/* offset of version */
+	ewpr_MVT_offset_elem_t opv[MAX_MULTI_VER];	/* offset per version */
+} ewpr_MVT_offset_t;			/* multi_version type */
+
+typedef struct {
+	char name[EWP_REPORT_NAME_MAX];
+	int ring_type;		/* Ring Type : EWPF_IDX_TYPE_SLICE, EWPF_IDX_TYPE_IFACE */
+	int	is_multi_version;		/* is multi version */
+	union {
+		uint32 offset;			/* Offset from start of element structure */
+		ewpr_MVT_offset_t v_info;
+	};
+	int data_type;				/* Data type : one of EWP Filter Data Type */
+	int display_format;			/* Display format : one of EWP Reporter display */
+	int display_type;			/* MAX display BYTE : valid for HEX and BIN FORM */
+#ifdef DHD_EWPR_VER2
+	int info_type;			/* info type : EWPF_INFO_ECNT, EWPF_INFO_IOVAR, ... */
+	int display_bit_length;		/* packing bit : valid for BIN FORM */
+	int display_array_size;		/* array size */
+	int display_method;		/* serial or diff */
+	int unit_convert;		/* unit conversion
+					 * 0 or 1 : no conversion, put data as is
+					 * greater than 1, divide value by unit_convert
+					 */
+	bool need_abs;			/* need absolute function for negative value */
+#endif /* DHD_EWPR_VER2 */
+} ewpr_serial_info_t;
+
+/* offset defines */
+#define EWPR_CNT_VERSION_OFFSET \
+	OFFSETOF(EWPF_slc_elem_t, compact_cntr_v4)
+
+#define EWPR_CNT_V1_OFFSET(a) \
+	WL_PERIODIC_COMPACT_CNTRS_VER_1, \
+	(OFFSETOF(EWPF_slc_elem_t, compact_cntr_v1) + OFFSETOF(wl_periodic_compact_cntrs_v1_t, a))
+#define EWPR_CNT_V2_OFFSET(a) \
+	WL_PERIODIC_COMPACT_CNTRS_VER_2, \
+	(OFFSETOF(EWPF_slc_elem_t, compact_cntr_v2) + OFFSETOF(wl_periodic_compact_cntrs_v2_t, a))
+#define EWPR_CNT_V3_OFFSET(a) \
+	WL_PERIODIC_COMPACT_CNTRS_VER_3, \
+	(OFFSETOF(EWPF_slc_elem_t, compact_cntr_v3) + OFFSETOF(wl_periodic_compact_cntrs_v3_t, a))
+#define EWPR_CNT_V4_OFFSET(a) \
+	WL_PERIODIC_COMPACT_CNTRS_VER_4, \
+	(OFFSETOF(EWPF_slc_elem_t, compact_cntr_v4) + OFFSETOF(wl_periodic_compact_cntrs_v4_t, a))
+#define EWPR_STAT_OFFSET(a) \
+	(OFFSETOF(EWPF_ifc_elem_t, if_stat) + OFFSETOF(wl_if_stats_t, a))
+#define EWPR_INFRA_OFFSET(a) \
+	(OFFSETOF(EWPF_ifc_elem_t, infra) + OFFSETOF(wl_if_infra_stats_t, a))
+#define EWPR_MGMT_OFFSET(a) \
+	(OFFSETOF(EWPF_ifc_elem_t, mgmt_stat) + OFFSETOF(wl_if_mgt_stats_t, a))
+#define EWPR_LQM_OFFSET(a) \
+	(OFFSETOF(EWPF_ifc_elem_t, lqm) + OFFSETOF(wl_lqm_t, a))
+#define EWPR_SIGNAL_OFFSET(a) \
+	(EWPR_LQM_OFFSET(current_bss) + OFFSETOF(wl_rx_signal_metric_t, a))
+#define EWPR_IF_COMP_OFFSET(a) \
+	(OFFSETOF(EWPF_ifc_elem_t, if_comp_stat) + OFFSETOF(wl_if_state_compact_t, a))
+#define EWPR_EVENT_COUNTER_OFFSET(a) \
+	(OFFSETOF(EWPF_event_elem_t, event_stat) + OFFSETOF(wl_event_based_statistics_v4_t, a))
+#define EWPR_KEY_INFO_OFFSET(a) \
+	(OFFSETOF(EWPF_key_info_elem_t, key_update_info) + OFFSETOF(key_update_info_v1_t, a))
+#define EWPR_TX_TOSS_HIST_OFFSET(a) \
+	(OFFSETOF(EWPF_slc_elem_t, hist_tx_toss_stat) + \
+		OFFSETOF(evt_hist_compact_toss_stats_v1_t, a))
+#define EWPR_RX_TOSS_HIST_OFFSET(a) \
+	(OFFSETOF(EWPF_slc_elem_t, hist_rx_toss_stat) + \
+		OFFSETOF(evt_hist_compact_toss_stats_v1_t, a))
+#define EWPR_BTC_STAT_OFFSET(a) \
+	(OFFSETOF(EWPF_slc_elem_t, btc_stat) + \
+		OFFSETOF(wlc_btc_stats_v4_t, a))
+#define EWPR_COMPACT_HE_CNT_OFFSET(a) \
+	(OFFSETOF(EWPF_slc_elem_t, compact_he_cnt) + \
+		OFFSETOF(wl_compact_he_cnt_wlc_v2_t, a))
+#define EWPR_ROAM_STATS_PERIODIC_OFFSET(a) \
+	(OFFSETOF(EWPF_ifc_elem_t, roam_stat) + OFFSETOF(wl_roam_stats_v1_t, a))
+
+/* serail info type define */
+#define EWPR_SERIAL_CNT(a) {\
+	#a, EWPF_IDX_TYPE_SLICE, TRUE, \
+	.v_info = { EWPR_CNT_VERSION_OFFSET, \
+		{{EWPR_CNT_V1_OFFSET(a)}, \
+		{EWPR_CNT_V2_OFFSET(a)}, \
+		{EWPR_CNT_V3_OFFSET(a)}, \
+		{EWPR_CNT_V4_OFFSET(a)}}}, \
+	EWP_UINT32, EWP_HEX, EWP_UINT32}
+#define EWPR_SERIAL_CNT_16(a) {\
+	#a, EWPF_IDX_TYPE_SLICE, TRUE, \
+	.v_info = { EWPR_CNT_VERSION_OFFSET, \
+		{{EWPR_CNT_V1_OFFSET(a)}, \
+		{EWPR_CNT_V2_OFFSET(a)}, \
+		{EWPR_CNT_V3_OFFSET(a)}, \
+		{EWPR_CNT_V4_OFFSET(a)}}}, \
+	EWP_UINT32, EWP_HEX, EWP_UINT16}
+#define EWPR_SERIAL_STAT(a) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_STAT_OFFSET(a), \
+	EWP_UINT64, EWP_HEX, EWP_UINT32}
+#define EWPR_SERIAL_INFRA(a) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_INFRA_OFFSET(a), \
+	EWP_UINT32, EWP_HEX, EWP_UINT16}
+#define EWPR_SERIAL_MGMT(a) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_MGMT_OFFSET(a), \
+	EWP_UINT32, EWP_HEX, EWP_UINT16}
+#define EWPR_SERIAL_LQM(a) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_LQM_OFFSET(a), \
+	EWP_INT32, EWP_DEC, EWP_INT8}
+#define EWPR_SERIAL_SIGNAL(a) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_SIGNAL_OFFSET(a), \
+	EWP_INT32, EWP_DEC, EWP_INT8}
+#define EWPR_SERIAL_IFCOMP_8(a) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_IF_COMP_OFFSET(a), \
+	EWP_INT8, EWP_DEC, EWP_INT8}
+#define EWPR_SERIAL_IFCOMP_16(a) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_IF_COMP_OFFSET(a), \
+	EWP_UINT16, EWP_DEC, EWP_UINT16}
+#define EWPR_SERIAL_ARM(a) {\
+	"armcycle:" #a, EWPF_IDX_TYPE_##a, FALSE, {0, }, \
+	EWP_UINT32, EWP_DEC, EWP_UINT32}
+#define EWPR_SERIAL_NONE {"", EWPF_INVALID, FALSE, {0, }, 0, 0, 0}
+
+#ifdef DHD_EWPR_VER2
+
+#define RAW_BUFFER_SIZE		720u
+#define BASE64_BUFFER_SIZE	960u /* 33 percent larger than original binary data */
+#define EWPR_HEADER_SIZE	39u
+#define	EWPR_MAX_STR_SIZE	EWPR_HEADER_SIZE + EWPR_HEADER_SIZE
+
+#define EWPR_DISPLAY_METHOD_SINGLE	0
+#define EWPR_DISPLAY_METHOD_DIFF	1
+
+#define MAX_BIT_SIZE	8
+#define MAX_BIT_SHIFT	7
+
+#define INDEX_UNSPECIFIED 0u
+
+enum ewpr_context_type {
+	EWP_CONTEXT_TYPE_UNWANTED_NETWORK = 0,
+	EWP_CONTEXT_TYPE_ASSOC_FAIL = 1,
+	EWP_CONTEXT_TYPE_ABNORMAL_DISCONNECT = 2,
+	EWP_CONTEXT_TYPE_MAX = 3
+};
+
+enum ewpr_unwanted_net_sub_type {
+	EWP_UNWANT_NET_SUB_TYPE_UNSPECIFIED = 0,
+	EWP_UNWANT_NET_SUB_TYPE_ARP_FAIL = 1,
+	EWP_UNWANT_NET_SUB_TYPE_TXBAD = 2,
+	EWP_UNWANT_NET_SUB_TYPE_MAX = 3
+};
+
+enum ewpr_assoc_fail_sub_type {
+	EWP_ASSOC_FAIL_SUB_TYPE_UNSPECIFIED = 0,
+	EWP_ASSOC_FAIL_SUB_TYPE_DHCP_FAIL = 1,
+	EWP_ASSOC_FAIL_SUB_TYPE_EAP_FAIL = 2,
+	EWP_ASSOC_FAIL_SUB_TYPE_EAP_TIMEOUT = 3,
+	EWP_ASSOC_FAIL_SUB_TYPE_4WAY_FAIL = 4,
+	EWP_ASSOC_FAIL_SUB_TYPE_MAX = 5
+};
+
+enum ewpr_abnormal_disconnect_sub_type {
+	EWP_ABNRML_DISCONNCET_SUB_TYPE_UNSPECIFIED = 0,
+	EWP_ABNRML_DISCONNCET_SUB_TYPE_DISCONNECT_BY_HOST = 1,
+	EWP_ABNRML_DISCONNCET_SUB_TYPE_MAX = 2
+};
+
+typedef struct {
+	uint32 index1;
+	uint32 index2;
+	uint32 index3;
+	ewpr_serial_info_t *table;
+} ewpr_serial_context_info_t;
+
+#define EWPR_SINGLE_DEFAULT EWPR_DISPLAY_METHOD_SINGLE, EWPF_NO_UNIT_CONV
+#define EWPR_DIFF_DEFAULT EWPR_DISPLAY_METHOD_DIFF, EWPF_NO_UNIT_CONV
+
+#define EWPR_SINGLE_NSEC_TO_MSEC EWPR_DISPLAY_METHOD_SINGLE, EWPF_NSEC_TO_MSEC
+#define EWPR_SINGLE_USEC_TO_MSEC EWPR_DISPLAY_METHOD_SINGLE, EWPF_USEC_TO_MSEC
+#define EWPR_SINGLE_USEC_TO_SEC EWPR_DISPLAY_METHOD_SINGLE, EWPF_USEC_TO_SEC
+
+/* serail info type define */
+#define EWPR_SERIAL_CNT_V4_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_SLICE, TRUE, \
+	.v_info = { EWPR_CNT_VERSION_OFFSET, \
+		{{EWPR_CNT_V4_OFFSET(a)}}}, \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_STAT_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_STAT_OFFSET(a), \
+	EWP_UINT64, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_INFRA_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_INFRA_OFFSET(a), \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_MGMT_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_MGMT_OFFSET(a), \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_LQM_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_LQM_OFFSET(a), \
+	EWP_INT32, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_SIGNAL_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_SIGNAL_OFFSET(a), \
+	EWP_INT32, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_IFCOMP_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_IF_COMP_OFFSET(a), \
+	EWP_INT8, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_EVENT_COUNTER_16_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_EVENT, FALSE, .offset = EWPR_EVENT_COUNTER_OFFSET(a), \
+	EWP_UINT16, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_EVENT_COUNTER_32_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_EVENT, FALSE, .offset = EWPR_EVENT_COUNTER_OFFSET(a), \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_KEY_INFO_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_KEY_INFO, FALSE, .offset = EWPR_KEY_INFO_OFFSET(a), \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_ROAM_STATS_PERIODIC_OFFSET(a), \
+	EWP_UINT16, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_ROAM_STAT_PERIODIC_32_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_IFACE, FALSE, .offset = EWPR_ROAM_STATS_PERIODIC_OFFSET(a), \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_ARM_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_##a, FALSE, {0, }, \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_IOVAR_BIT(a, b) {\
+	#a, 0, 0, .offset = 0, \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_IOVAR, b, 1, EWPR_SINGLE_DEFAULT}
+#define EWPR_SERIAL_VERSION_BIT(a, b) {\
+	#a, 0, 0, .offset = 0, \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_VER, b, 1, EWPR_SINGLE_DEFAULT}
+#define EWPR_SERIAL_TYPE_BIT(a, b) {\
+	#a, 0, 0, .offset = 0, \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_TYPE, b, 1, EWPR_SINGLE_DEFAULT}
+#define EWPR_SERIAL_CPLOG_BIT(a, b, c) {\
+	#a, 0, 0, .offset = 0, \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_CPLOG, b, c, EWPR_SINGLE_DEFAULT}
+#define EWPR_SERIAL_DHDSTAT_BIT(a, b, c, d) {\
+	#a, 0, 0, .offset = 0, \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_DHDSTAT, b, c, d}
+#define EWPR_SERIAL_TX_TOSS_HIST_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_SLICE, FALSE, .offset = EWPR_TX_TOSS_HIST_OFFSET(a), \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_RX_TOSS_HIST_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_SLICE, FALSE, .offset = EWPR_RX_TOSS_HIST_OFFSET(a), \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_BTC_STAT_16_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_SLICE, FALSE, .offset = EWPR_BTC_STAT_OFFSET(a), \
+	EWP_UINT16, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_BTC_STAT_32_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_SLICE, FALSE, .offset = EWPR_BTC_STAT_OFFSET(a), \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+#define EWPR_SERIAL_COMPACT_HE_CNT_BIT(a, b, c, d) {\
+	#a, EWPF_IDX_TYPE_SLICE, FALSE, .offset = EWPR_COMPACT_HE_CNT_OFFSET(a), \
+	EWP_UINT32, EWP_BIN, EWP_BIT, EWPF_INFO_ECNT, b, c, d}
+
+#define EWPR_SERIAL_NONE_BIT {"", EWPF_INVALID, FALSE, {0, }, 0, 0, 0, 0, 0, 0, 0}
+
+#ifdef EWPR_DEBUG
+static void ewpr_print_byte_as_bits(char val);
+#endif /* EWPR_DEBUG */
+
+static int32
+ewpr_diff_bit_pack(ewpr_serial_info_t *info, char *buf, int buf_len,
+	void *_f_op, void *_s_op, int32 bit_offset);
+static int32
+ewpr_single_bit_pack(ewpr_serial_info_t *info, char *buf, int buf_len,
+	void *_ptr, int32 bit_offset);
+static int32
+ewpr_bit_pack_basic(char *buf, int buf_len, uint32 data, int32 format,
+	int32 display_type, int32 display_bit_length, int32 bit_offset);
+
+static char*
+ewpr_base64_encode(dhd_pub_t *dhdp, char* input, int32 length);
+#endif /* DHD_EWPR_VER2 */
+
+ewpr_serial_info_t
+ewpr_serial_CSDCLIENT_key_tbl[] = {
+	EWPR_SERIAL_STAT(txframe),
+	EWPR_SERIAL_STAT(txerror),
+	EWPR_SERIAL_STAT(rxframe),
+	EWPR_SERIAL_STAT(rxerror),
+	EWPR_SERIAL_STAT(txretrans),
+	EWPR_SERIAL_INFRA(rxbeaconmbss),
+	EWPR_SERIAL_CNT(txallfrm),
+	EWPR_SERIAL_CNT(rxrsptmout),
+	EWPR_SERIAL_CNT(rxbadplcp),
+	EWPR_SERIAL_CNT(rxcrsglitch),
+	EWPR_SERIAL_CNT(rxbadfcs),
+	EWPR_SERIAL_CNT_16(rxbeaconmbss),
+	EWPR_SERIAL_CNT_16(rxbeaconobss),
+	EWPR_SERIAL_NONE
+};
+
+ewpr_serial_info_t
+ewpr_serial_CSDCLIENT_diff_tbl[] = {
+	EWPR_SERIAL_STAT(txframe),
+	EWPR_SERIAL_STAT(txerror),
+	EWPR_SERIAL_STAT(rxframe),
+	EWPR_SERIAL_STAT(rxerror),
+	EWPR_SERIAL_STAT(txretrans),
+	EWPR_SERIAL_INFRA(rxbeaconmbss),
+	EWPR_SERIAL_MGMT(txassocreq),
+	EWPR_SERIAL_MGMT(txreassocreq),
+	EWPR_SERIAL_MGMT(txdisassoc),
+	EWPR_SERIAL_MGMT(rxdisassoc),
+	EWPR_SERIAL_MGMT(rxassocrsp),
+	EWPR_SERIAL_MGMT(rxreassocrsp),
+	EWPR_SERIAL_MGMT(txauth),
+	EWPR_SERIAL_MGMT(rxauth),
+	EWPR_SERIAL_MGMT(txdeauth),
+	EWPR_SERIAL_MGMT(rxdeauth),
+	EWPR_SERIAL_MGMT(txaction),
+	EWPR_SERIAL_MGMT(rxaction),
+	EWPR_SERIAL_CNT(txallfrm),
+	EWPR_SERIAL_CNT(rxrsptmout),
+	EWPR_SERIAL_CNT(rxbadplcp),
+	EWPR_SERIAL_CNT(rxcrsglitch),
+	EWPR_SERIAL_CNT(rxbadfcs),
+	EWPR_SERIAL_CNT_16(rxbeaconmbss),
+	EWPR_SERIAL_CNT_16(rxbeaconobss),
+	EWPR_SERIAL_NONE
+};
+
+ewpr_serial_info_t
+ewpr_serial_CSDCLIENT_array_tbl[] = {
+	EWPR_SERIAL_IFCOMP_8(rssi_sum),
+	EWPR_SERIAL_IFCOMP_8(snr),
+	EWPR_SERIAL_IFCOMP_8(noise_level),
+	EWPR_SERIAL_NONE
+};
+
+#ifdef EWPR_DEBUG
+ewpr_serial_info_t
+ewpr_serial_dbg_tbl[] = {
+	EWPR_SERIAL_ARM(IFACE),
+	EWPR_SERIAL_ARM(SLICE),
+	EWPR_SERIAL_NONE
+};
+#endif /* EWPR_DEBUG */
+
+#ifdef DHD_EWPR_VER2
+
+ewpr_serial_info_t
+ewpr_serial_bit_unwanted_network_default_tbl[] = {
+	EWPR_SERIAL_VERSION_BIT(version, 32),
+	EWPR_SERIAL_TYPE_BIT(type, 5),
+	EWPR_SERIAL_DHDSTAT_BIT(dhdstat_last_ts, 32, 1, EWPR_SINGLE_USEC_TO_SEC),
+	EWPR_SERIAL_DHDSTAT_BIT(dhdstat_last, 8, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_DHDSTAT_BIT(dhdstat_prev_ts, 32, 1, EWPR_SINGLE_USEC_TO_SEC),
+	EWPR_SERIAL_DHDSTAT_BIT(dhdstat_prev, 8, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_IOVAR_BIT(auth, 8),
+	EWPR_SERIAL_IOVAR_BIT(wsec, 8),
+	EWPR_SERIAL_IOVAR_BIT(mfp, 1),
+	EWPR_SERIAL_IOVAR_BIT(bip, 8),
+	EWPR_SERIAL_ARM_BIT(IFACE, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(txframe, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(txerror, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(rxframe, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(rxerror, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(txretrans, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txassocreq, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txreassocreq, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txdisassoc, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxdisassoc, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxassocrsp, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxreassocrsp, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txauth, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxauth, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txdeauth, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxdeauth, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txaction, 7, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxaction, 7, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(txallfrm, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxrsptmout, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxbadplcp, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxcrsglitch, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxbadfcs, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxbeaconmbss, 5, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxbeaconobss, 12, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(lqcm_report, 19, 6, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(tx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxretry, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxdup, 15, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(chswitch_cnt, 8, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(pm_dur, 12, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxholes, 15, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxundec, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxundec_mcst, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(replay, 12, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(replay_mcst, 12, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(pktfilter_discard, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(pktfilter_forward, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(mac_rxfilter, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_dcsn_map, 16, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_dcsn_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_a2dp_hiwat_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_datadelay_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_crtpri_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_pri_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(a2dpbuf5cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(a2dpbuf6cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(a2dpbuf7cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_32_BIT(bt_gnt_dur, 12, 3, EWPR_SINGLE_USEC_TO_MSEC),
+	EWPR_SERIAL_IFCOMP_BIT(rssi_sum, 7, 6, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_IFCOMP_BIT(snr, 7, 6, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_IFCOMP_BIT(noise_level, 7, 6, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_32_BIT(initial_assoc_time, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_32_BIT(prev_roam_time, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_32_BIT(last_roam_event_type, 8, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_32_BIT(last_roam_event_status, 6, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_32_BIT(last_roam_event_reason, 6, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(roam_success_cnt, 10, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(roam_fail_cnt, 10, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(roam_attempt_cnt, 11, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(max_roam_target_cnt, 5, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(min_roam_target_cnt, 5, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(max_cached_ch_cnt, 5, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(min_cached_ch_cnt, 5, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(partial_roam_scan_cnt, 11, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(full_roam_scan_cnt, 11, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_rxtrig_myaid, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_colormiss_cnt, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_rxmsta_back, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_txtbppdu, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_null_tbppdu, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_KEY_INFO_BIT(timestamp, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_KEY_INFO_BIT(algo, 6, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_KEY_INFO_BIT(key_flags, 16, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rn_ts_last, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rn_last, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rn_ts_prev, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rn_prev, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rc_ts_max, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rc_max, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rc_ts_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rc_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rn_ts_last, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rn_last, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rn_ts_prev, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rn_prev, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_ts_max, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_max, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_ts_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_CPLOG_BIT(packtlog, 22, 50),
+	EWPR_SERIAL_NONE
+};
+
+ewpr_serial_info_t
+ewpr_serial_bit_assoc_fail_default_tbl[] = {
+	EWPR_SERIAL_VERSION_BIT(version, 32),
+	EWPR_SERIAL_TYPE_BIT(type, 5),
+	EWPR_SERIAL_DHDSTAT_BIT(dhdstat_last_ts, 32, 1, EWPR_SINGLE_USEC_TO_SEC),
+	EWPR_SERIAL_DHDSTAT_BIT(dhdstat_last, 8, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_DHDSTAT_BIT(dhdstat_prev_ts, 32, 1, EWPR_SINGLE_USEC_TO_SEC),
+	EWPR_SERIAL_DHDSTAT_BIT(dhdstat_prev, 8, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_IOVAR_BIT(auth, 8),
+	EWPR_SERIAL_IOVAR_BIT(wsec, 8),
+	EWPR_SERIAL_IOVAR_BIT(mfp, 1),
+	EWPR_SERIAL_IOVAR_BIT(bip, 8),
+	EWPR_SERIAL_ARM_BIT(IFACE, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(txframe, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(txerror, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(rxframe, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(rxerror, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(txretrans, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txassocreq, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txreassocreq, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txdisassoc, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxdisassoc, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxassocrsp, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxreassocrsp, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txauth, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxauth, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txdeauth, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxdeauth, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txaction, 7, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxaction, 7, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(txallfrm, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxrsptmout, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxbadplcp, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxcrsglitch, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxbadfcs, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxbeaconmbss, 5, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxbeaconobss, 12, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(lqcm_report, 19, 6, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(tx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxretry, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxdup, 15, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(chswitch_cnt, 8, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(pm_dur, 12, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxholes, 15, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxundec, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxundec_mcst, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(replay, 12, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(replay_mcst, 12, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(pktfilter_discard, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(pktfilter_forward, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(mac_rxfilter, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_dcsn_map, 16, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_dcsn_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_a2dp_hiwat_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_datadelay_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_crtpri_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_pri_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(a2dpbuf5cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(a2dpbuf6cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(a2dpbuf7cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_32_BIT(bt_gnt_dur, 12, 3, EWPR_SINGLE_USEC_TO_MSEC),
+	EWPR_SERIAL_IFCOMP_BIT(rssi_sum, 7, 6, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_IFCOMP_BIT(snr, 7, 6, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_IFCOMP_BIT(noise_level, 7, 6, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_rxtrig_myaid, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_colormiss_cnt, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_rxmsta_back, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_txtbppdu, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_null_tbppdu, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_KEY_INFO_BIT(timestamp, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_KEY_INFO_BIT(algo, 6, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_KEY_INFO_BIT(key_flags, 16, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rn_ts_last, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rn_last, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rn_ts_prev, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rn_prev, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rc_ts_max, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rc_max, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rc_ts_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rc_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rn_ts_last, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rn_last, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rn_ts_prev, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rn_prev, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_ts_max, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_max, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_ts_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_CPLOG_BIT(packtlog, 22, 50),
+	EWPR_SERIAL_NONE
+};
+
+ewpr_serial_info_t
+ewpr_serial_bit_abnormal_disconnect_default_tbl[] = {
+	EWPR_SERIAL_VERSION_BIT(version, 32),
+	EWPR_SERIAL_TYPE_BIT(type, 5),
+	EWPR_SERIAL_DHDSTAT_BIT(dhdstat_last_ts, 32, 1, EWPR_SINGLE_USEC_TO_SEC),
+	EWPR_SERIAL_DHDSTAT_BIT(dhdstat_last, 8, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_DHDSTAT_BIT(dhdstat_prev_ts, 32, 1, EWPR_SINGLE_USEC_TO_SEC),
+	EWPR_SERIAL_DHDSTAT_BIT(dhdstat_prev, 8, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_IOVAR_BIT(auth, 8),
+	EWPR_SERIAL_IOVAR_BIT(wsec, 8),
+	EWPR_SERIAL_IOVAR_BIT(mfp, 1),
+	EWPR_SERIAL_IOVAR_BIT(bip, 8),
+	EWPR_SERIAL_ARM_BIT(IFACE, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(txframe, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(txerror, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(rxframe, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(rxerror, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_STAT_BIT(txretrans, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txassocreq, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txreassocreq, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txdisassoc, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxdisassoc, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxassocrsp, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxreassocrsp, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txauth, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxauth, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txdeauth, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxdeauth, 4, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(txaction, 7, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_MGMT_BIT(rxaction, 7, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(txallfrm, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxrsptmout, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxbadplcp, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxcrsglitch, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxbadfcs, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxbeaconmbss, 5, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxbeaconobss, 12, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(lqcm_report, 19, 6, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(tx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rx_toss_cnt, 18, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxretry, 17, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxdup, 15, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(chswitch_cnt, 8, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(pm_dur, 12, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxholes, 15, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxundec, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(rxundec_mcst, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(replay, 12, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(replay_mcst, 12, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(pktfilter_discard, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(pktfilter_forward, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_CNT_V4_BIT(mac_rxfilter, 16, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_dcsn_map, 16, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_dcsn_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_a2dp_hiwat_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_datadelay_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_crtpri_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(bt_pri_cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(a2dpbuf5cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(a2dpbuf6cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_16_BIT(a2dpbuf7cnt, 12, 3, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_BTC_STAT_32_BIT(bt_gnt_dur, 12, 3, EWPR_SINGLE_USEC_TO_MSEC),
+	EWPR_SERIAL_IFCOMP_BIT(rssi_sum, 7, 6, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_IFCOMP_BIT(snr, 7, 6, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_IFCOMP_BIT(noise_level, 7, 6, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_32_BIT(initial_assoc_time, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_32_BIT(prev_roam_time, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_32_BIT(last_roam_event_type, 8, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_32_BIT(last_roam_event_status, 6, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_32_BIT(last_roam_event_reason, 6, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(roam_success_cnt, 10, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(roam_fail_cnt, 10, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(roam_attempt_cnt, 11, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(max_roam_target_cnt, 5, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(min_roam_target_cnt, 5, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(max_cached_ch_cnt, 5, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(min_cached_ch_cnt, 5, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(partial_roam_scan_cnt, 11, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_ROAM_STAT_PERIODIC_16_BIT(full_roam_scan_cnt, 11, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_rxtrig_myaid, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_colormiss_cnt, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_rxmsta_back, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_txtbppdu, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_COMPACT_HE_CNT_BIT(he_null_tbppdu, 10, 6, EWPR_DIFF_DEFAULT),
+	EWPR_SERIAL_KEY_INFO_BIT(timestamp, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_KEY_INFO_BIT(algo, 6, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_KEY_INFO_BIT(key_flags, 16, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rn_ts_last, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rn_last, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rn_ts_prev, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rn_prev, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rc_ts_max, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rc_max, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rc_ts_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_TX_TOSS_HIST_BIT(htr_rc_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rn_ts_last, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rn_last, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rn_ts_prev, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rn_prev, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_ts_max, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_max, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_ts_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_RX_TOSS_HIST_BIT(htr_rc_secnd, 32, 1, EWPR_SINGLE_DEFAULT),
+	EWPR_SERIAL_CPLOG_BIT(packtlog, 22, 50),
+	EWPR_SERIAL_NONE
+};
+
+ewpr_serial_context_info_t ewpr_serial_context_info[] = {
+	{EWP_CONTEXT_TYPE_UNWANTED_NETWORK, EWP_UNWANT_NET_SUB_TYPE_UNSPECIFIED,
+	INDEX_UNSPECIFIED, &ewpr_serial_bit_unwanted_network_default_tbl[0]},
+	{EWP_CONTEXT_TYPE_UNWANTED_NETWORK, EWP_UNWANT_NET_SUB_TYPE_ARP_FAIL,
+	INDEX_UNSPECIFIED, &ewpr_serial_bit_unwanted_network_default_tbl[0]},
+	{EWP_CONTEXT_TYPE_UNWANTED_NETWORK, EWP_UNWANT_NET_SUB_TYPE_TXBAD,
+	INDEX_UNSPECIFIED, &ewpr_serial_bit_unwanted_network_default_tbl[0]},
+	{EWP_CONTEXT_TYPE_ASSOC_FAIL, EWP_ASSOC_FAIL_SUB_TYPE_UNSPECIFIED,
+	INDEX_UNSPECIFIED, &ewpr_serial_bit_assoc_fail_default_tbl[0]},
+	{EWP_CONTEXT_TYPE_ASSOC_FAIL, EWP_ASSOC_FAIL_SUB_TYPE_DHCP_FAIL,
+	INDEX_UNSPECIFIED, &ewpr_serial_bit_assoc_fail_default_tbl[0]},
+	{EWP_CONTEXT_TYPE_ASSOC_FAIL, EWP_ASSOC_FAIL_SUB_TYPE_EAP_FAIL,
+	INDEX_UNSPECIFIED, &ewpr_serial_bit_assoc_fail_default_tbl[0]},
+	{EWP_CONTEXT_TYPE_ASSOC_FAIL, EWP_ASSOC_FAIL_SUB_TYPE_EAP_TIMEOUT,
+	INDEX_UNSPECIFIED, &ewpr_serial_bit_assoc_fail_default_tbl[0]},
+	{EWP_CONTEXT_TYPE_ASSOC_FAIL, EWP_ASSOC_FAIL_SUB_TYPE_4WAY_FAIL,
+	INDEX_UNSPECIFIED, &ewpr_serial_bit_assoc_fail_default_tbl[0]},
+	{EWP_CONTEXT_TYPE_ABNORMAL_DISCONNECT, EWP_ABNRML_DISCONNCET_SUB_TYPE_UNSPECIFIED,
+	INDEX_UNSPECIFIED, &ewpr_serial_bit_abnormal_disconnect_default_tbl[0]},
+	{EWP_CONTEXT_TYPE_ABNORMAL_DISCONNECT, EWP_ABNRML_DISCONNCET_SUB_TYPE_DISCONNECT_BY_HOST,
+	INDEX_UNSPECIFIED, &ewpr_serial_bit_abnormal_disconnect_default_tbl[0]},
+	{EWP_CONTEXT_TYPE_MAX, INDEX_UNSPECIFIED, INDEX_UNSPECIFIED, NULL}
+};
+#endif /* DHD_EWPR_VER2 */
+
+int ewpr_set_period_lock(ewpr_lock_param_t *param);
+int ewpr_diff_serial(ewpr_serial_info_t *info, char *buf,
+	int buf_len, void *_f_op, void *_s_op, char del);
+int ewpr_single_serial(ewpr_serial_info_t *info, char *buf, int buf_len, void *ptr, char del);
+
+int
+ewpr_serial_basic(char *buf, int buf_len, uint32 data, int format, int display_type, char del)
+{
+	if (format == EWP_HEX) {
+		switch (display_type) {
+			case EWP_INT8:
+			case EWP_UINT8:
+				return scnprintf(buf, buf_len, "%c%02x", del, data & 0xff);
+			case EWP_INT16:
+			case EWP_UINT16:
+				return scnprintf(buf, buf_len, "%c%04x", del, data & 0xffff);
+			case EWP_INT32:
+			case EWP_UINT32:
+				return scnprintf(buf, buf_len, "%c%08x", del, data & 0xffffffff);
+			default:
+				DHD_FILTER_ERR(("INVALID TYPE for Serial:%d", display_type));
+				return 0;
+		}
+	}
+
+	if (format == EWP_DEC) {
+		int32 sdata = (int32) data;
+		switch (display_type) {
+			case EWP_INT8:
+			case EWP_UINT8:
+				return scnprintf(buf, buf_len, "%c%04d", del, sdata);
+			case EWP_INT16:
+			case EWP_UINT16:
+				return scnprintf(buf, buf_len, "%c%06d", del, sdata);
+			case EWP_INT32:
+			case EWP_UINT32:
+				return scnprintf(buf, buf_len, "%c%011d", del, sdata);
+			default:
+				DHD_FILTER_ERR(("INVALID TYPE for Serial:%d", display_type));
+				return 0;
+		}
+	}
+
+	if (format == EWP_BIN) {
+		int32 sdata = (int32) data;
+		switch (display_type) {
+			case EWP_BIT:
+				return scnprintf(buf, buf_len, "%c%011d", del, sdata);
+			default:
+				DHD_FILTER_ERR(("INVALID TYPE for Serial:%d", display_type));
+				return 0;
+		}
+	}
+
+	DHD_FILTER_ERR(("INVALID FORMAT for Serial:%d", format));
+	return 0;
+}
+
+static int
+ewpr_get_multi_offset(uint16 looking_version, ewpr_serial_info_t *info)
+{
+	int idx;
+	ewpr_MVT_offset_elem_t *opv;
+
+	DHD_FILTER_TRACE(("FINDING MULTI OFFSET: type = %s version = %d\n",
+		info->name, looking_version));
+	for (idx = 0; idx < MAX_MULTI_VER; idx ++) {
+		opv = &(info->v_info.opv[idx]);
+
+		/* END OF MULTI VERSION */
+		if (opv->version == 0) {
+			break;
+		}
+		if (looking_version == opv->version) {
+			return opv->offset;
+		}
+	}
+	/* return first version if no version is found */
+	return info->v_info.opv[0].offset;
+}
+int
+ewpr_single_serial(ewpr_serial_info_t *info, char *buf, int buf_len, void *_ptr, char del)
+{
+	uint32 sval = 0;
+	char *ptr = (char *)_ptr;
+	uint32 offset = EWPF_INVALID;
+	uint16	version;
+
+	if (info->is_multi_version == TRUE) {
+		version = *(uint16 *)((char *)_ptr + info->v_info.version_offset);
+		offset = ewpr_get_multi_offset(version, info);
+	} else {
+		offset = info->offset;
+	}
+
+	if (offset == EWPF_INVALID) {
+		DHD_FILTER_ERR(("INVALID TYPE to OFFSET:%s\n", info->name));
+		return 0;
+	}
+
+	ptr += offset;
+
+	switch (info->data_type) {
+		case EWP_INT8:
+			sval = *(int8 *)ptr;
+			break;
+		case EWP_UINT8:
+			sval = *(uint8 *)ptr;
+			break;
+		case EWP_INT16:
+			sval = *(int16 *)ptr;
+			break;
+		case EWP_UINT16:
+			sval = *(uint16 *)ptr;
+			break;
+		case EWP_INT32:
+			sval = *(int32 *)ptr;
+			break;
+		case EWP_UINT32:
+			sval = *(uint32 *)ptr;
+			break;
+		/* XXX UINT64 is used only for debug */
+#ifdef EWPR_DEBUG
+		case EWP_UINT64:
+			sval = (uint32)(*(uint64 *)ptr);
+			break;
+#endif /* EWPR_DEBUG */
+		case EWP_BIT:
+		default:
+			DHD_FILTER_ERR(("INVALID TYPE for Single Serial:%d", info->data_type));
+			return 0;
+	}
+
+	return ewpr_serial_basic(buf, buf_len, sval, info->display_format, info->display_type, del);
+}
+
+int
+ewpr_diff_serial(ewpr_serial_info_t *info,
+	char *buf, int buf_len, void *_f_op, void *_s_op, char del)
+{
+	char *f_op = (char *)_f_op;
+	char *s_op = (char *)_s_op;
+	uint32 diff;
+	uint32 offset = EWPF_INVALID;
+	uint16	version;
+
+	if (info->is_multi_version == TRUE) {
+		version = *(uint16 *)(f_op + info->v_info.version_offset);
+		offset = ewpr_get_multi_offset(version, info);
+	} else {
+		offset = info->offset;
+	}
+
+	if (offset == EWPF_INVALID) {
+		DHD_FILTER_ERR(("INVALID TYPE to OFFSET:%s\n", info->name));
+		return 0;
+	}
+
+	f_op = f_op + offset;
+	s_op = s_op + offset;
+
+	switch (info->data_type) {
+		case EWP_INT8:
+		case EWP_UINT8:
+			diff = *(uint8 *)f_op - *(uint8 *)s_op;
+			break;
+		case EWP_INT16:
+		case EWP_UINT16:
+			diff = *(uint16 *)f_op - *(uint16 *)s_op;
+			break;
+		case EWP_INT32:
+		case EWP_UINT32:
+			diff = *(uint32 *)f_op - *(uint32 *)s_op;
+			break;
+		case EWP_UINT64:
+			diff = (uint32)(*(uint64 *)f_op - *(uint64 *)s_op);
+			break;
+		case EWP_BIT:
+		default:
+			DHD_FILTER_ERR(("INVALID TYPE to DIFF:%d", info->data_type));
+			return 0;
+	}
+
+	return ewpr_serial_basic(buf, buf_len, diff, info->display_format, info->display_type, del);
+}
+
+#ifdef EWPR_DEBUG
+void
+ewpr_debug_dump(ewpr_serial_info_t *tbl, void **ring)
+{
+	void *elem;
+	int idx, idx2;
+	ewpr_serial_info_t *info;
+	char buf[EWPR_DEBUG_BUF_LEN];
+	uint32 bytes_written;
+	int lock_cnt;
+
+	for (idx = 0; strlen(tbl[idx].name) != 0; idx++) {
+		info = &tbl[idx];
+#ifdef DHD_EWPR_VER2
+		if (info->info_type != EWPF_INFO_ECNT) {
+			DHD_FILTER_ERR(("%s: unable to dump value\n", info->name));
+			break;
+		}
+#endif /* DHD_EWPR_VER2 */
+		memset(buf, 0, sizeof(buf));
+		lock_cnt = dhd_ring_lock_get_count(ring[info->ring_type - 1]);
+		elem = dhd_ring_lock_get_first(ring[info->ring_type - 1]);
+		bytes_written = scnprintf(buf, EWPR_DEBUG_BUF_LEN, "%s:", info->name);
+		for (idx2 = 0; elem && (idx2 < lock_cnt); idx2++) {
+			bytes_written += ewpr_single_serial(info, &buf[bytes_written],
+				EWPR_DEBUG_BUF_LEN - bytes_written, elem, KEY_DEL);
+			elem = dhd_ring_get_next(ring[info->ring_type - 1], elem);
+		}
+		DHD_FILTER_ERR(("%s\n", buf));
+	}
+}
+#endif /* EWPR_DEBUG */
+
+uint32
+dhd_event_log_filter_serialize(dhd_pub_t *dhdp, char *in_buf, uint32 tot_len, int type)
+{
+	EWP_filter_t *filter = (EWP_filter_t *)dhdp->event_log_filter;
+	void *ring[EWPF_MAX_IDX_TYPE];
+	char *ret_buf = in_buf;
+	int slice_id;
+	int iface_id;
+	int idx, idx2;
+	uint32 bytes_written = 0;
+	void *elem[EWPF_MAX_IDX_TYPE][EWPR_CSDCLIENT_DIFF];
+	void **elem_list;
+	int lock_cnt, lock_cnt2;
+	char *last_print;
+	void *arr_elem;
+	uint32 delta_list[EWPR_CSDCLIENT_DIFF];
+	ewpr_lock_param_t lock_param;
+	int print_name = FALSE;
+	char cookie_str[DEBUG_DUMP_TIME_BUF_LEN];
+	char iov_buf[EWPR_IOV_BUF_LEN];
+
+	if (type != 0) {
+		DHD_FILTER_ERR(("NOT SUPPORTED TYPE: %d\n", type));
+		return 0;
+	}
+
+	iface_id = 0; /* STA INTERFACE ONLY */
+	if (filter->last_channel <= CH_MAX_2G_CHANNEL) {
+		slice_id = EWPF_SLICE_AUX;
+	} else {
+		slice_id = EWPF_SLICE_MAIN;
+	}
+	ring[EWPF_IDX_TYPE_SLICE - 1] = filter->s_ring[slice_id];
+	ring[EWPF_IDX_TYPE_IFACE - 1] = filter->i_ring[iface_id];
+
+	/* Configure common LOCK parameter */
+	lock_param.max_armcycle = (uint32)EWPF_INVALID;
+	lock_param.min_armcycle = filter->last_armcycle;
+	lock_param.max_period = (EWPR_ARRAY_CNT - 1)* EWPR_INTERVAL;
+	lock_param.max_period *= EWPF_MSEC_TO_SEC * EWPF_ARM_TO_MSEC;
+	lock_param.delta_cnt = ARRAYSIZE(delta_list);
+	lock_param.delta_list = delta_list;
+
+	delta_list[EWPR_DELTA3_POS] = EWPR_DELTA3_CNT;
+	delta_list[EWPR_DELTA2_POS] = EWPR_DELTA2_CNT;
+	delta_list[EWPR_DELTA1_POS] = EWPR_DELTA1_CNT;
+	delta_list[EWPR_NOW_POS] = 0;
+	lock_param.ring = ring[EWPF_IDX_TYPE_IFACE -1];
+	lock_param.elem_list = elem[EWPF_IDX_TYPE_IFACE -1];
+	lock_cnt = ewpr_set_period_lock(&lock_param);
+	if (lock_cnt <= 0) {
+		DHD_FILTER_ERR(("FAIL TO GET IFACE LOCK: %d\n", iface_id));
+		bytes_written = 0;
+		goto finished;
+	}
+
+	delta_list[EWPR_DELTA3_POS] = EWPR_DELTA3_CNT;
+	delta_list[EWPR_DELTA2_POS] = EWPR_DELTA2_CNT;
+	delta_list[EWPR_DELTA1_POS] = EWPR_DELTA1_CNT;
+	delta_list[EWPR_NOW_POS] = 0;
+	lock_param.ring = ring[EWPF_IDX_TYPE_SLICE -1];
+	lock_param.elem_list = elem[EWPF_IDX_TYPE_SLICE -1];
+	lock_cnt2 = ewpr_set_period_lock(&lock_param);
+	if (lock_cnt2 <= 0) {
+		DHD_FILTER_ERR(("FAIL TO GET SLICE LOCK: %d\n", slice_id));
+		goto finished;
+	}
+
+	if (lock_cnt != lock_cnt2) {
+		DHD_FILTER_ERR(("Lock Count is Diff: iface:%d slice:%d\n", lock_cnt, lock_cnt2));
+		lock_cnt = MIN(lock_cnt, lock_cnt2);
+	}
+
+#ifdef EWPR_DEBUG
+	print_name = TRUE;
+	ewpr_debug_dump(ewpr_serial_dbg_tbl, ring);
+	ewpr_debug_dump(ewpr_serial_CSDCLIENT_diff_tbl, ring);
+	ewpr_debug_dump(ewpr_serial_CSDCLIENT_array_tbl, ring);
+#endif /* EWPR_DEBUG */
+
+	memset(ret_buf, 0, tot_len);
+	memset(cookie_str, 0, DEBUG_DUMP_TIME_BUF_LEN);
+	bytes_written = 0;
+	last_print = ret_buf;
+
+	/* XXX Counters BIG DATA not matched to file yet */
+	get_debug_dump_time(cookie_str);
+#ifdef DHD_LOG_DUMP
+	dhd_logdump_cookie_save(dhdp, cookie_str, "ECNT");
+#endif
+
+	/* KEY DATA */
+	bytes_written += scnprintf(&ret_buf[bytes_written],
+		tot_len - bytes_written, "%08x", EWP_REPORT_VERSION);
+	bytes_written += scnprintf(&ret_buf[bytes_written],
+		tot_len - bytes_written, "%c%s", KEY_DEL, cookie_str);
+	DHD_FILTER_ERR(("%d: %s\n", bytes_written, last_print));
+	last_print = &ret_buf[bytes_written];
+
+	for (idx = 0; strlen(ewpr_serial_CSDCLIENT_key_tbl[idx].name) != 0; idx++) {
+		ewpr_serial_info_t *info = &ewpr_serial_CSDCLIENT_key_tbl[idx];
+		elem_list = elem[info->ring_type - 1];
+		if (print_name) {
+			bytes_written += scnprintf(&ret_buf[bytes_written],
+				tot_len - bytes_written, " %s:", info->name);
+		}
+		bytes_written += ewpr_diff_serial(info, &ret_buf[bytes_written],
+			tot_len - bytes_written,
+			elem_list[EWPR_NOW_POS],
+			elem_list[EWPR_DELTA1_POS],
+			KEY_DEL);
+		if ((idx + 1) % EWPR_CNT_PER_LINE == 0) {
+			DHD_FILTER_ERR(("%d:%s\n", bytes_written, last_print));
+			last_print = &ret_buf[bytes_written];
+		}
+	}
+
+	/* RAW DATA */
+	/* XXX FIRST data shall use space:KEY delimiter */
+	bytes_written += scnprintf(&ret_buf[bytes_written],
+		tot_len - bytes_written, "%c%08x", KEY_DEL, EWP_REPORT_VERSION);
+	bytes_written += scnprintf(&ret_buf[bytes_written],
+		tot_len - bytes_written, "%c%s", RAW_DEL, cookie_str);
+
+	for (idx = 0; strlen(ewpr_serial_CSDCLIENT_diff_tbl[idx].name) != 0; idx++) {
+		ewpr_serial_info_t *info = &ewpr_serial_CSDCLIENT_diff_tbl[idx];
+		elem_list = elem[info->ring_type - 1];
+		if (print_name) {
+			bytes_written += scnprintf(&ret_buf[bytes_written],
+				tot_len - bytes_written, " %s:", info->name);
+		}
+		bytes_written += ewpr_diff_serial(info, &ret_buf[bytes_written],
+			tot_len - bytes_written,
+			elem_list[EWPR_NOW_POS],
+			elem_list[EWPR_DELTA1_POS],
+			RAW_DEL);
+		bytes_written += ewpr_diff_serial(info, &ret_buf[bytes_written],
+			tot_len - bytes_written,
+			elem_list[EWPR_DELTA1_POS],
+			elem_list[EWPR_DELTA2_POS],
+			RAW_DEL);
+		if ((idx + 1) % EWPR_CNT_PER_LINE == 0) {
+			DHD_FILTER_ERR(("%d:%s\n", bytes_written, last_print));
+			last_print = &ret_buf[bytes_written];
+		}
+	}
+
+	/* FILL BSS SPECIFIC DATA LATER */
+	if (dhd_iovar(dhdp, 0, "auth", NULL, 0, iov_buf, ARRAYSIZE(iov_buf), FALSE) < 0) {
+		DHD_FILTER_ERR(("fail to get auth\n"));
+		*(uint32 *)iov_buf = EWPF_INVALID;
+
+	}
+	bytes_written += scnprintf(&ret_buf[bytes_written],
+			tot_len - bytes_written, "%c%08x", RAW_DEL, *(uint32 *)iov_buf);
+
+	if (dhd_iovar(dhdp, 0, "wsec", NULL, 0, iov_buf, ARRAYSIZE(iov_buf), FALSE) < 0) {
+		DHD_FILTER_ERR(("fail to get wsec\n"));
+		*(uint32 *)iov_buf = EWPF_INVALID;
+
+	}
+	bytes_written += scnprintf(&ret_buf[bytes_written],
+			tot_len - bytes_written, "%c%08x", RAW_DEL, *(uint32 *)iov_buf);
+
+	if (dhd_iovar(dhdp, 0, "mfp", NULL, 0, iov_buf, ARRAYSIZE(iov_buf), FALSE) < 0) {
+		DHD_FILTER_ERR(("fail to get mfp\n"));
+		*(uint8 *)iov_buf = EWPF_INVALID;
+
+	}
+	bytes_written += scnprintf(&ret_buf[bytes_written],
+			tot_len - bytes_written, "%c%02x", RAW_DEL, *(uint8 *)iov_buf);
+
+	if (dhd_iovar(dhdp, 0, "bip", NULL, 0, iov_buf, ARRAYSIZE(iov_buf), FALSE) < 0) {
+		DHD_FILTER_ERR(("fail to get bip\n"));
+		*(uint8 *)iov_buf = EWPF_INVALID;
+	}
+	bytes_written += scnprintf(&ret_buf[bytes_written],
+			tot_len - bytes_written, "%c%02x", RAW_DEL, *(uint8 *)iov_buf);
+
+	for (idx = 0; strlen(ewpr_serial_CSDCLIENT_array_tbl[idx].name) != 0; idx++) {
+		ewpr_serial_info_t *info = &ewpr_serial_CSDCLIENT_array_tbl[idx];
+		if (print_name) {
+			bytes_written += scnprintf(&ret_buf[bytes_written],
+				tot_len - bytes_written, " %s:", info->name);
+		}
+		for (idx2 = 0; idx2 < EWPR_ARRAY_CNT - lock_cnt; idx2++) {
+			bytes_written += ewpr_serial_basic(&ret_buf[bytes_written],
+				tot_len - bytes_written, 0,
+				info->display_format, info->display_type, RAW_DEL);
+		}
+		arr_elem = elem[info->ring_type - 1][EWPR_DELTA3_POS];
+		for (; idx2 < EWPR_ARRAY_CNT; idx2++) {
+			if (arr_elem == NULL) {
+				DHD_FILTER_ERR(("ARR IS NULL : %d %p \n",
+					idx2, elem[info->ring_type - 1][EWPR_DELTA3_POS]));
+				break;
+			}
+			bytes_written += ewpr_single_serial(info, &ret_buf[bytes_written],
+				tot_len - bytes_written, arr_elem, RAW_DEL);
+			arr_elem = dhd_ring_get_next(ring[info->ring_type - 1], arr_elem);
+		}
+		DHD_FILTER_ERR(("%d:%s\n", bytes_written, last_print));
+		last_print = &ret_buf[bytes_written];
+	}
+
+finished:
+	DHD_FILTER_ERR(("RET LEN:%d\n", (int)strlen(ret_buf)));
+	dhd_ring_lock_free(ring[EWPF_IDX_TYPE_SLICE - 1]);
+	dhd_ring_lock_free(ring[EWPF_IDX_TYPE_IFACE - 1]);
+	return bytes_written;
+}
+
+int
+ewpr_set_period_lock(ewpr_lock_param_t *param)
+{
+	void *last;
+	void *first;
+	void *cur;
+	int lock_cnt;
+	int idx2;
+	int delta_idx;
+	uint32 last_armcycle;
+	uint32 first_armcycle;
+	uint32 cur_armcycle = 0;
+	void *ring = param->ring;
+
+	/* GET LATEST PTR */
+	last = dhd_ring_get_last(ring);
+	while (TRUE) {
+		if (last == NULL) {
+			DHD_FILTER_ERR(("NO LAST\n"));
+			return -1;
+		}
+		last_armcycle = *(uint32 *)last;
+		if (last_armcycle <= param->max_armcycle ||
+			last_armcycle + EWPF_EPOCH >= param->max_armcycle) {
+			break;
+		}
+		last = dhd_ring_get_prev(ring, last);
+	}
+
+	if (last_armcycle != param->max_armcycle) {
+		DHD_FILTER_TRACE(("MAX ARMCYCLE IS CHANGEd new:%u prev:%u\n",
+			last_armcycle, param->max_armcycle));
+		param->max_armcycle = last_armcycle;
+	}
+
+	if (last_armcycle < param->min_armcycle) {
+		param->min_armcycle = 0;
+	}
+
+	/* GET FIRST PTR */
+	first_armcycle = last_armcycle;
+	first = last;
+	while (TRUE) {
+		cur = dhd_ring_get_prev(ring, first);
+		if (cur == NULL) {
+			break;
+		}
+		cur_armcycle = *(uint32 *)cur;
+		if (cur_armcycle >= first_armcycle) {
+			DHD_FILTER_TRACE(("case 1: %u %u\n", first_armcycle, cur_armcycle));
+			/* dongle is rebooted */
+			break;
+		}
+		if (cur_armcycle + EWPF_EPOCH < param->min_armcycle) {
+			DHD_FILTER_TRACE(("case 2: %u %u\n", param->min_armcycle, cur_armcycle));
+			/* Reach Limitation */
+			break;
+		}
+		if (cur_armcycle + param->max_period + EWPF_EPOCH < last_armcycle) {
+			DHD_FILTER_TRACE(("case 3: %u %u\n", param->max_period, cur_armcycle));
+			/* exceed max period */
+			break;
+		}
+		first = cur;
+		first_armcycle = cur_armcycle;
+	}
+
+	if (first_armcycle != param->min_armcycle) {
+		DHD_FILTER_TRACE(("MIN ARMCYCLE IS CHANGEd new:%u prev:%u %u\n",
+			first_armcycle, param->min_armcycle, cur_armcycle));
+		param->min_armcycle = first_armcycle;
+	}
+
+	DHD_FILTER_TRACE(("ARM CYCLE of first(%u), last(%u)\n", first_armcycle, last_armcycle));
+
+	dhd_ring_lock(ring, first, last);
+
+	lock_cnt = dhd_ring_lock_get_count(ring);
+	if (lock_cnt <= 0) {
+		DHD_FILTER_ERR((" NO VALID RECORD : %d\n", lock_cnt));
+		return -1;
+	}
+	DHD_FILTER_TRACE(("Lock Count:%d\n", lock_cnt));
+
+	/* Validate delta position */
+	for (idx2 = 0; idx2 < param->delta_cnt - 1; idx2++) {
+		if (param->delta_list[idx2] >= param->delta_list[idx2 + 1]) {
+			DHD_FILTER_ERR(("INVALID DELTA at %d\n", idx2 + 1));
+			param->delta_list[idx2 + 1] = param->delta_list[idx2];
+		}
+	}
+
+	delta_idx = 0;
+	for (idx2 = 0; idx2 < lock_cnt && delta_idx < param->delta_cnt; idx2++) {
+		if (idx2 == 0) {
+			cur = dhd_ring_lock_get_last(ring);
+		} else {
+			cur = dhd_ring_get_prev(ring, cur);
+		}
+
+		if (idx2 >= param->delta_list[delta_idx]) {
+			param->elem_list[delta_idx] = cur;
+			delta_idx ++;
+		}
+	}
+
+	/* COPY last elem to rest of the list */
+	delta_idx--;
+	for (idx2 = delta_idx + 1; idx2 < param->delta_cnt; idx2++) {
+		param->elem_list[idx2] = cur;
+	}
+	return lock_cnt;
+}
+
+#ifdef DHD_EWPR_VER2
+static int
+ewpr_single_bit_pack(ewpr_serial_info_t * info, char * buf, int buf_len,
+	void * _ptr, int bit_offset)
+{
+	int32 sval = 0;
+	char *ptr = (char *)_ptr;
+	uint32 offset = EWPF_INVALID;
+	uint16	version;
+	bool is_signed = FALSE;
+
+	if (info->is_multi_version == TRUE) {
+		version = *(uint16 *)((char *)_ptr + info->v_info.version_offset);
+		offset = ewpr_get_multi_offset(version, info);
+	} else {
+		offset = info->offset;
+	}
+
+	if (offset == EWPF_INVALID) {
+		DHD_FILTER_ERR(("INVALID TYPE to OFFSET:%s\n", info->name));
+		return 0;
+	}
+
+	ptr += offset;
+
+	switch (info->data_type) {
+		case EWP_INT8:
+			sval = *(int8 *)ptr;
+			is_signed = TRUE;
+			break;
+		case EWP_UINT8:
+			sval = *(uint8 *)ptr;
+			break;
+		case EWP_INT16:
+			sval = *(int16 *)ptr;
+			is_signed = TRUE;
+			break;
+		case EWP_UINT16:
+			sval = *(uint16 *)ptr;
+			break;
+		case EWP_INT32:
+			sval = *(int32 *)ptr;
+			is_signed = TRUE;
+			break;
+		case EWP_UINT32:
+			sval = *(uint32 *)ptr;
+			break;
+#ifdef EWPR_DEBUG
+		case EWP_UINT64:
+			sval = (int32)(*(uint64 *)ptr);
+			break;
+#endif /* EWPR_DEBUG */
+		default:
+			DHD_FILTER_ERR(("INVALID TYPE for Single Serial:%d", info->data_type));
+			return 0;
+	}
+
+	/* convert negative value to positive before bit packing */
+	if (is_signed) {
+		if (sval < 0) {
+			DHD_FILTER_TRACE(("convert to positive value %d\n", sval));
+			sval = ABS(sval);
+		}
+	}
+
+	if (info->unit_convert > 1) {
+		DHD_FILTER_TRACE(("convert unit %d / %d\n", sval, info->unit_convert));
+		sval = sval / info->unit_convert;
+	}
+
+	if (is_signed) {
+		DHD_FILTER_TRACE(("%s : signed value : %d, bit length: %d",
+			info->name, sval, info->display_bit_length));
+	} else {
+		DHD_FILTER_TRACE(("%s : unsigned value : %u, bit length: %d",
+			info->name, sval, info->display_bit_length));
+	}
+
+	return ewpr_bit_pack_basic(buf, buf_len, sval, info->display_format,
+			info->display_type, info->display_bit_length, bit_offset);
+}
+
+static int
+ewpr_diff_bit_pack(ewpr_serial_info_t *info, char *buf, int buf_len,
+	void *_f_op, void *_s_op, int bit_offset)
+{
+	char *f_op = (char *)_f_op;
+	char *s_op = (char *)_s_op;
+	int32 diff;
+	uint32 offset = EWPF_INVALID;
+	uint16	version;
+
+	if (info->is_multi_version == TRUE) {
+		version = *(uint16 *)(f_op + info->v_info.version_offset);
+		offset = ewpr_get_multi_offset(version, info);
+	} else {
+		offset = info->offset;
+	}
+
+	if (offset == EWPF_INVALID) {
+		DHD_FILTER_ERR(("INVALID TYPE to OFFSET:%s\n", info->name));
+		return 0;
+	}
+
+	f_op = f_op + offset;
+	s_op = s_op + offset;
+
+	switch (info->data_type) {
+		case EWP_INT8:
+		case EWP_UINT8:
+			diff = *(uint8 *)f_op - *(uint8 *)s_op;
+			break;
+		case EWP_INT16:
+		case EWP_UINT16:
+			diff = *(uint16 *)f_op - *(uint16 *)s_op;
+			break;
+		case EWP_INT32:
+		case EWP_UINT32:
+			diff = *(uint32 *)f_op - *(uint32 *)s_op;
+			break;
+		case EWP_UINT64:
+			diff = (uint32)(*(uint64 *)f_op - *(uint64 *)s_op);
+			break;
+		default:
+			DHD_FILTER_ERR(("INVALID TYPE to DIFF:%d", info->data_type));
+			return 0;
+	}
+
+	if (diff < 0) {
+		DHD_FILTER_TRACE(("convert to positive value %d\n", diff));
+		diff = ABS(diff);
+	}
+
+	if (info->unit_convert > 1) {
+		DHD_FILTER_TRACE(("convert unit %d / %d\n", diff, info->unit_convert));
+		diff = diff / info->unit_convert;
+	}
+
+	DHD_FILTER_TRACE(("%s : value : %d, bit length: %d",
+		info->name, diff, info->display_bit_length));
+	return ewpr_bit_pack_basic(buf, buf_len, diff, info->display_format,
+		info->display_type, info->display_bit_length, bit_offset);
+}
+
+static int
+ewpr_bit_pack_basic(char *buf, int buf_len, uint32 data, int format, int display_type,
+	int display_bit_length, int bit_offset)
+{
+	if (format == EWP_BIN) {
+		uint32 sdata = (uint32) data;
+		switch (display_type) {
+			case EWP_BIT:
+				/* call bit packing */
+				return dhd_bit_pack(buf, buf_len, bit_offset,
+					sdata, display_bit_length);
+			default:
+				DHD_FILTER_ERR(("INVALID TYPE for Serial:%d", display_type));
+				return 0;
+		}
+	}
+
+	DHD_FILTER_ERR(("INVALID FORMAT for Serial:%d", format));
+	return 0;
+}
+
+static ewpr_serial_info_t*
+ewpr_find_context_info(int index1, int index2, int index3)
+{
+	int idx = 0;
+	ewpr_serial_info_t *context_info = NULL;
+
+	for (idx = 0; ewpr_serial_context_info[idx].table != NULL; idx++) {
+		if (index1 == ewpr_serial_context_info[idx].index1 &&
+				index2 == ewpr_serial_context_info[idx].index2 &&
+				index3 == ewpr_serial_context_info[idx].index3) {
+			context_info = ewpr_serial_context_info[idx].table;
+			break;
+		}
+	}
+
+	if (context_info == NULL) {
+		DHD_FILTER_ERR(("unable to find context info for index number: %02x:%02x:%02x\n",
+			index1, index2, index3));
+		return NULL;
+	}
+
+	return context_info;
+}
+
+static int
+ewpr_find_context_type(ewpr_serial_info_t* context_info)
+{
+	int idx = 0;
+	int context_type = BCME_ERROR;
+
+	/* index2, index3 are reserved */
+
+	for (idx = 0; ewpr_serial_context_info[idx].table != NULL; idx++) {
+		if (context_info == ewpr_serial_context_info[idx].table) {
+			context_type = idx;
+			break;
+		}
+	}
+
+	return context_type;
+}
+
+static uint32
+ewpr_scnprintf(char *buf, uint32 buf_len, uint32 input_len, char *data_type, char *fmt, ...)
+{
+	va_list args;
+
+	if (buf_len < input_len) {
+		DHD_FILTER_ERR(("%s: input length(%d) is larger than "
+			"remain buffer length(%d)\n", data_type,
+			input_len, buf_len));
+	}
+	va_start(args, fmt);
+	buf_len = vscnprintf(buf, buf_len, fmt, args);
+	va_end(args);
+
+	return buf_len;
+}
+
+uint32
+dhd_event_log_filter_serialize_bit(dhd_pub_t *dhdp, char *in_buf, uint32 tot_len,
+	int index1, int index2, int index3)
+{
+	EWP_filter_t *filter = (EWP_filter_t *)dhdp->event_log_filter;
+	void *ring[EWPF_MAX_IDX_TYPE];
+	char *ret_buf = in_buf;
+	int slice_id;
+	int iface_id;
+	int event_id;
+	int key_info_id;
+	int idx;
+	int idx2;
+	uint32 bytes_written = 0;
+	int bits_written = 0;
+	void *elem[EWPF_MAX_IDX_TYPE][EWPR_CSDCLIENT_DIFF];
+	void **elem_list;
+	int lock_cnt, lock_cnt2;
+	uint32 delta_list[EWPR_CSDCLIENT_DIFF];
+	ewpr_lock_param_t lock_param;
+	char cookie_str[DEBUG_DUMP_TIME_BUF_LEN];
+	char iov_buf[EWPR_IOV_BUF_LEN];
+	char *raw_buf = NULL;
+	char *raw_encode_buf = NULL;
+	int raw_buf_size;
+	int ret = 0;
+	ewpr_serial_info_t *context_info = NULL;
+	int context_type;
+#ifdef DHD_STATUS_LOGGING
+	uint32 conv_cnt = 0;
+#endif /* DHD_STATUS_LOGGING */
+
+#ifdef DHD_STATUS_LOGGING
+	stat_elem_t dhd_stat[EWP_DHD_STAT_SIZE];
+	stat_query_t query;
+
+	memset(&dhd_stat[0], 0x00, sizeof(stat_elem_t) * EWP_DHD_STAT_SIZE);
+#endif /* DHD_STATUS_LOGGING */
+
+	context_info = ewpr_find_context_info(index1, index2, index3);
+	if (!context_info) {
+		return bytes_written;
+	}
+
+	if (tot_len < EWPR_MAX_STR_SIZE) {
+		DHD_FILTER_ERR(("%s: insufficient buffer size %d\n",
+			__FUNCTION__, tot_len));
+		return bytes_written;
+	}
+
+	iface_id = 0; /* STA INTERFACE ONLY */
+	event_id = 0; /* COMMON ID */
+	key_info_id = 0; /* COMMON ID */
+	if (filter->last_channel <= CH_MAX_2G_CHANNEL) {
+		slice_id = EWPF_SLICE_AUX;
+	} else {
+		slice_id = EWPF_SLICE_MAIN;
+	}
+	ring[EWPF_IDX_TYPE_SLICE - 1] = filter->s_ring[slice_id];
+	ring[EWPF_IDX_TYPE_IFACE - 1] = filter->i_ring[iface_id];
+	ring[EWPF_IDX_TYPE_EVENT - 1] = filter->e_ring[event_id];
+	ring[EWPF_IDX_TYPE_KEY_INFO - 1] = filter->k_ring[key_info_id];
+
+	/* Configure common LOCK parameter */
+	lock_param.max_armcycle = (uint32)EWPF_INVALID;
+	lock_param.min_armcycle = filter->last_armcycle;
+	lock_param.max_period = (EWPR_ARRAY_CNT - 1)* EWPR_INTERVAL;
+	lock_param.max_period *= EWPF_MSEC_TO_SEC * EWPF_ARM_TO_MSEC;
+	lock_param.delta_cnt = ARRAYSIZE(delta_list);
+	lock_param.delta_list = delta_list;
+
+	for (idx = 0; idx < EWPR_CSDCLIENT_DIFF; idx++) {
+		delta_list[idx] = idx * EWPR_DELTA_CNT;
+	}
+
+	lock_param.ring = ring[EWPF_IDX_TYPE_IFACE -1];
+	lock_param.elem_list = elem[EWPF_IDX_TYPE_IFACE -1];
+	lock_cnt = ewpr_set_period_lock(&lock_param);
+	if (lock_cnt <= 0) {
+		DHD_FILTER_ERR(("FAIL TO GET IFACE LOCK: %d\n", iface_id));
+		bytes_written = 0;
+		goto finished;
+	}
+
+	for (idx = 0; idx < EWPR_CSDCLIENT_DIFF; idx++) {
+		delta_list[idx] = idx * EWPR_DELTA_CNT;
+	}
+
+	lock_param.ring = ring[EWPF_IDX_TYPE_SLICE -1];
+	lock_param.elem_list = elem[EWPF_IDX_TYPE_SLICE -1];
+	lock_cnt2 = ewpr_set_period_lock(&lock_param);
+	if (lock_cnt2 <= 0) {
+		DHD_FILTER_ERR(("FAIL TO GET SLICE LOCK: %d\n", slice_id));
+		goto finished;
+	}
+
+	if (lock_cnt != lock_cnt2) {
+		DHD_FILTER_ERR(("Lock Count is Diff: iface:%d slice:%d\n", lock_cnt, lock_cnt2));
+		lock_cnt = MIN(lock_cnt, lock_cnt2);
+	}
+
+	for (idx = 0; idx < EWPR_CSDCLIENT_DIFF; idx++) {
+		delta_list[idx] = idx * EWPR_DELTA_CNT;
+	}
+
+	lock_param.ring = ring[EWPF_IDX_TYPE_EVENT -1];
+	lock_param.elem_list = elem[EWPF_IDX_TYPE_EVENT -1];
+	lock_cnt = ewpr_set_period_lock(&lock_param);
+	if (lock_cnt <= 0) {
+		DHD_FILTER_ERR(("FAIL TO GET EVENT ECNT LOCK: %d\n", iface_id));
+		bytes_written = 0;
+		goto finished;
+	}
+
+	for (idx = 0; idx < EWPR_CSDCLIENT_DIFF; idx++) {
+		delta_list[idx] = idx * EWPR_DELTA_CNT;
+	}
+
+	lock_param.ring = ring[EWPF_IDX_TYPE_KEY_INFO -1];
+	lock_param.elem_list = elem[EWPF_IDX_TYPE_KEY_INFO -1];
+	lock_cnt = ewpr_set_period_lock(&lock_param);
+	if (lock_cnt <= 0) {
+		DHD_FILTER_ERR(("FAIL TO GET KEY INFO LOCK: %d\n", iface_id));
+		bytes_written = 0;
+		goto finished;
+	}
+
+#ifdef EWPR_DEBUG
+	ewpr_debug_dump(context_info, ring);
+#endif /* EWPR_DEBUG */
+
+	memset(ret_buf, 0, tot_len);
+	memset(cookie_str, 0, DEBUG_DUMP_TIME_BUF_LEN);
+	bytes_written = 0;
+	bits_written = 0;
+
+	/* XXX Counters BIG DATA not matched to file yet */
+	get_debug_dump_time(cookie_str);
+#ifdef DHD_LOG_DUMP
+	dhd_logdump_cookie_save(dhdp, cookie_str, "ECNT");
+#endif /* DHD_LOG_DUMP */
+
+	/* KEY DATA */
+	bytes_written += ewpr_scnprintf(&ret_buf[bytes_written],
+		tot_len - bytes_written, REPORT_VERSION_STR_SIZE,
+		"report version", "%08x", EWP_REPORT_VERSION);
+
+	bytes_written += ewpr_scnprintf(&ret_buf[bytes_written],
+		tot_len - bytes_written, DELIMITER_LEN + strlen(cookie_str),
+		"cookie string", "%c%s", KEY_DEL, cookie_str);
+
+	bytes_written += ewpr_scnprintf(&ret_buf[bytes_written],
+		tot_len - bytes_written, DELIMITER_LEN + INDEX_STR_SIZE,
+		"host trigger index", "%c%02x%02x%02x", KEY_DEL, index1, index2, index3);
+
+#ifdef DHD_STATUS_LOGGING
+	DHD_FILTER_TRACE(("print dhd_stat size:%d * %d, size of filter list: %d\n",
+		(uint32)sizeof(dhd_stat[0]), EWP_DHD_STAT_SIZE,
+		(uint32)sizeof(dhd_statlog_filter)));
+	query.req_buf = NULL;
+	query.req_buf_len = 0;
+	query.resp_buf = (char *)dhd_stat;
+	query.resp_buf_len = DHD_STATLOG_RING_SIZE(EWP_DHD_STAT_SIZE);
+	query.req_num = EWP_DHD_STAT_SIZE;
+	ret = dhd_statlog_get_latest_info(dhdp, (void *)&query);
+	if (ret < 0) {
+		DHD_FILTER_ERR(("fail to get dhd statlog - %d\n", ret));
+	}
+#ifdef EWPR_DEBUG
+	for (idx = 0; idx < EWP_DHD_STAT_SIZE; idx++) {
+		DHD_FILTER_TRACE(("DHD status index: %d, timestamp: %llu, stat: %d\n",
+			idx, dhd_stat[idx].ts, dhd_stat[idx].stat));
+	}
+#endif
+	bytes_written += ewpr_scnprintf(&ret_buf[bytes_written],
+		tot_len - bytes_written, DELIMITER_LEN + DHD_STAT_STR_SIZE,
+		"current dhd status", "%c%02x", KEY_DEL, dhd_stat[0].stat);
+
+	bytes_written += ewpr_scnprintf(&ret_buf[bytes_written],
+		tot_len - bytes_written, DELIMITER_LEN + DHD_STAT_STR_SIZE,
+		"previous dhd status", "%c%02x", KEY_DEL, dhd_stat[1].stat);
+#else
+	/* reserved for dhd status information */
+	bytes_written += ewpr_scnprintf(&ret_buf[bytes_written],
+		tot_len - bytes_written, DELIMITER_LEN + DHD_STAT_STR_SIZE,
+		"current dhd status", "%c%02x", KEY_DEL, 0x00);
+
+	bytes_written += ewpr_scnprintf(&ret_buf[bytes_written],
+		tot_len - bytes_written, DELIMITER_LEN + DHD_STAT_STR_SIZE,
+		"previous dhd status", "%c%02x", KEY_DEL, 0x00);
+#endif /* DHD_STATUS_LOGGING */
+
+	/* RAW DATA */
+	raw_buf = MALLOCZ(dhdp->osh, RAW_BUFFER_SIZE);
+
+	for (idx = 0; strlen(context_info[idx].name) != 0; idx++) {
+		ewpr_serial_info_t *info = &context_info[idx];
+		elem_list = elem[info->ring_type - 1];
+		DHD_FILTER_TRACE(("%s : array_size: %d\n", info->name, info->display_array_size));
+		switch (info->info_type) {
+			case EWPF_INFO_VER:
+				DHD_FILTER_TRACE(("write %s - value: %d\n", info->name,
+					EWP_REPORT_VERSION));
+				bits_written = dhd_bit_pack(raw_buf, RAW_BUFFER_SIZE, bits_written,
+					EWP_REPORT_VERSION, info->display_bit_length);
+				break;
+			case EWPF_INFO_TYPE:
+				context_type = ewpr_find_context_type(context_info);
+				if (context_type < 0) {
+					DHD_FILTER_ERR(("fail to get context_type - %d\n",
+						context_type));
+					break;
+				}
+				DHD_FILTER_TRACE(("write %s - value: %d\n", info->name,
+					(uint32)context_type));
+				bits_written = dhd_bit_pack(raw_buf, RAW_BUFFER_SIZE, bits_written,
+					(uint32)context_type, info->display_bit_length);
+				break;
+			case EWPF_INFO_DHDSTAT:
+				if (strcmp("dhdstat_last_ts", info->name) == 0) {
+#ifdef DHD_STATUS_LOGGING
+					if (info->unit_convert > 1) {
+						conv_cnt = dhd_stat[0].ts_tz / info->unit_convert;
+					} else {
+						conv_cnt = dhd_stat[0].ts_tz;
+					}
+					DHD_FILTER_TRACE(("DHD status last timestamp:"
+						" %llu, %u", dhd_stat[0].ts_tz,
+						conv_cnt));
+					bits_written = dhd_bit_pack(raw_buf, RAW_BUFFER_SIZE,
+						bits_written, conv_cnt,
+						info->display_bit_length);
+#else
+					DHD_FILTER_TRACE(("No DHD status log timestamp\n"));
+					bits_written = dhd_bit_pack(raw_buf, RAW_BUFFER_SIZE,
+						bits_written, 0x00, info->display_bit_length);
+#endif /* DHD_STATUS_LOGGING */
+				} else if (strcmp("dhdstat_last", info->name) == 0) {
+#ifdef DHD_STATUS_LOGGING
+					DHD_FILTER_TRACE(("DHD status last stat: %d(0x%02x)",
+						dhd_stat[0].stat, dhd_stat[0].stat));
+					bits_written = dhd_bit_pack(raw_buf, RAW_BUFFER_SIZE,
+						bits_written, (uint32)dhd_stat[0].stat,
+						info->display_bit_length);
+#else
+					DHD_FILTER_TRACE(("No DHD status log value\n"));
+					bits_written = dhd_bit_pack(raw_buf, RAW_BUFFER_SIZE,
+						bits_written, 0x00, info->display_bit_length);
+#endif /* DHD_STATUS_LOGGING */
+				} else if (strcmp("dhdstat_prev_ts", info->name) == 0) {
+#ifdef DHD_STATUS_LOGGING
+					if (info->unit_convert > 1) {
+						conv_cnt = dhd_stat[1].ts_tz / info->unit_convert;
+					} else {
+						conv_cnt = dhd_stat[1].ts_tz;
+					}
+					DHD_FILTER_TRACE(("DHD status prev timestamp:"
+						" %llu, %u", dhd_stat[1].ts_tz,
+						conv_cnt));
+					bits_written = dhd_bit_pack(raw_buf, RAW_BUFFER_SIZE,
+						bits_written, conv_cnt,
+						info->display_bit_length);
+#else
+					DHD_FILTER_TRACE(("No DHD status log timestamp\n"));
+					bits_written = dhd_bit_pack(raw_buf, RAW_BUFFER_SIZE,
+						bits_written, 0x00, info->display_bit_length);
+#endif /* DHD_STATUS_LOGGING */
+				} else if (strcmp("dhdstat_prev", info->name) == 0) {
+#ifdef DHD_STATUS_LOGGING
+					DHD_FILTER_TRACE(("DHD status prev stat: %d(0x%02x)",
+						dhd_stat[1].stat, dhd_stat[1].stat));
+					bits_written = dhd_bit_pack(raw_buf, RAW_BUFFER_SIZE,
+						bits_written, (uint32)dhd_stat[1].stat,
+						info->display_bit_length);
+#else
+					DHD_FILTER_TRACE(("No DHD status log value\n"));
+					bits_written = dhd_bit_pack(raw_buf, RAW_BUFFER_SIZE,
+						bits_written, 0x00, info->display_bit_length);
+#endif /* DHD_STATUS_LOGGING */
+				} else {
+					DHD_FILTER_ERR(("unknown dhdstat name - %s\n",
+						info->name));
+				}
+				break;
+			case EWPF_INFO_ECNT:
+				for (idx2 = 0; idx2 < info->display_array_size; idx2++) {
+					if (info->display_method == EWPR_DISPLAY_METHOD_SINGLE) {
+						bits_written = ewpr_single_bit_pack(info, raw_buf,
+							RAW_BUFFER_SIZE, elem_list[idx2],
+							bits_written);
+					} else {
+						bits_written = ewpr_diff_bit_pack(info, raw_buf,
+							RAW_BUFFER_SIZE, elem_list[idx2],
+							elem_list[idx2+1], bits_written);
+					}
+				}
+				break;
+			case EWPF_INFO_IOVAR:
+				if (dhd_iovar(dhdp, 0, info->name, NULL, 0, iov_buf,
+						ARRAYSIZE(iov_buf), FALSE) < 0) {
+					DHD_FILTER_ERR(("fail to get auth\n"));
+					*(uint32 *)iov_buf = EWPF_INVALID;
+				}
+				DHD_FILTER_TRACE(("write %s - value: %d\n", info->name,
+					*(uint8 *)iov_buf));
+				bits_written = dhd_bit_pack(raw_buf, RAW_BUFFER_SIZE,
+					bits_written, *(uint8 *)iov_buf,
+					info->display_bit_length);
+				break;
+			case EWPF_INFO_CPLOG:
+				DHD_FILTER_TRACE(("write compact packt log\n"));
+				ret = 0;
+#if defined(DHD_PKT_LOGGING) && defined(DHD_COMPACT_PKT_LOG)
+				ret = dhd_cpkt_log_proc(dhdp, raw_buf, RAW_BUFFER_SIZE,
+					bits_written, info->display_array_size);
+#endif /* DHD_PKT_LOGGING && DHD_COMPACT_PKT_LOG */
+				if (ret < 0) {
+					DHD_FILTER_ERR(("fail to get compact packet log - %d\n",
+						ret));
+					break;
+				}
+				/* update bit offset */
+				DHD_FILTER_TRACE(("%d bits written\n", ret));
+				if (ret > 0) {
+					bits_written = ret;
+				}
+				break;
+			default:
+				DHD_FILTER_ERR(("unsupported info type\n"));
+				break;
+		}
+		DHD_FILTER_TRACE(("%d bits written\n", bits_written));
+	}
+
+	/* encode data */
+	raw_buf_size = BYTE_SIZE(bits_written);
+	raw_encode_buf = ewpr_base64_encode(dhdp, raw_buf, raw_buf_size);
+
+#ifdef EWPR_DEBUG
+	DHD_FILTER_ERR(("raw_buf:\n"));
+	for (idx = 0; idx < raw_buf_size; idx++) {
+		ewpr_print_byte_as_bits(raw_buf[idx]);
+	}
+#endif /* EWPR_DEBUG */
+	DHD_FILTER_TRACE(("base64 encoding result:\n"));
+	DHD_FILTER_TRACE(("%s", raw_encode_buf));
+
+	bytes_written += ewpr_scnprintf(&ret_buf[bytes_written],
+		tot_len - bytes_written, DELIMITER_LEN + strlen(raw_encode_buf),
+		"base64 encoded raw data", "%c%s", KEY_DEL, raw_encode_buf);
+
+finished:
+	DHD_FILTER_ERR(("RET LEN:%d\n", (int)strlen(ret_buf)));
+	DHD_FILTER_TRACE(("ret_buf: %s", ret_buf));
+
+	dhd_ring_lock_free(ring[EWPF_IDX_TYPE_SLICE - 1]);
+	dhd_ring_lock_free(ring[EWPF_IDX_TYPE_IFACE - 1]);
+	dhd_ring_lock_free(ring[EWPF_IDX_TYPE_EVENT - 1]);
+	dhd_ring_lock_free(ring[EWPF_IDX_TYPE_KEY_INFO - 1]);
+
+	MFREE(dhdp->osh, raw_buf, RAW_BUFFER_SIZE);
+	MFREE(dhdp->osh, raw_encode_buf, BASE64_BUFFER_SIZE);
+	return bytes_written;
+}
+
+#ifdef EWPR_DEBUG
+static void
+ewpr_print_byte_as_bits(char val)
+{
+	int32 idx;
+	char buf[EWPR_DEBUG_BUF_LEN];
+	for (idx = 0; idx < MAX_BIT_SIZE; idx++) {
+		scnprintf(&buf[idx], EWPR_DEBUG_BUF_LEN-idx, "%c",
+			(val & (1 << (MAX_BIT_SHIFT-idx))) ? '1' : '0');
+	}
+	buf[MAX_BIT_SIZE] = 0x0;
+	DHD_FILTER_ERR(("%s\n", buf));
+}
+#endif /* EWPR_DEBUG */
+
+static char*
+ewpr_base64_encode(dhd_pub_t *dhdp, char* input, int32 length)
+{
+	/* set up a destination buffer large enough to hold the encoded data */
+	char *output = MALLOCZ(dhdp->osh, BASE64_BUFFER_SIZE);
+	int32 cnt = 0;
+
+	if (length > RAW_BUFFER_SIZE) {
+		DHD_FILTER_ERR(("%s: input data size is too big, size is limited to %d\n",
+			__FUNCTION__, RAW_BUFFER_SIZE));
+		length = RAW_BUFFER_SIZE;
+	}
+
+	cnt = dhd_base64_encode(input, length, output, BASE64_BUFFER_SIZE);
+	if (cnt == 0) {
+		DHD_FILTER_ERR(("%s: base64 encoding error\n", __FUNCTION__));
+	}
+	return output;
+}
+#endif /* DHD_EWPR_VER2 */
+
+#ifdef WLADPS_ENERGY_GAIN
+#define ADPS_GAIN_ENERGY_CONV_UNIT	100000	/* energy unit(10^-2) * dur unit(10^-3) */
+static int
+dhd_calculate_adps_energy_gain(wl_adps_energy_gain_v1_t *data)
+{
+	int i;
+	int energy_gain = 0;
+
+	/* energy unit: (uAh * 10^-2)/sec */
+	int pm0_idle_energy[MAX_BANDS] =
+		{ADPS_GAIN_2G_PM0_IDLE, ADPS_GAIN_5G_PM0_IDLE};
+	int txpspoll_energy[MAX_BANDS] =
+		{ADPS_GAIN_2G_TX_PSPOLL, ADPS_GAIN_5G_TX_PSPOLL};
+
+	if (data->version == 0 || data->length != sizeof(*data)) {
+		DHD_FILTER_ERR(("%s - invalid adps_energy_gain data\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	/* dur unit: mSec */
+	for (i = 0; i < MAX_BANDS; i++) {
+		energy_gain += (data->gain_data[i].pm_dur_gain * pm0_idle_energy[i]);
+		energy_gain -= (data->gain_data[i].step0_dur * txpspoll_energy[i]);
+	}
+	energy_gain /= ADPS_GAIN_ENERGY_CONV_UNIT;
+
+	if (energy_gain < 0) {
+		energy_gain = 0;
+	}
+
+	return energy_gain;
+}
+
+int dhd_event_log_filter_adps_energy_gain(dhd_pub_t *dhdp)
+{
+	int ret;
+
+	void *last_elem;
+	EWP_filter_t *filter;
+	EWPF_ifc_elem_t *ifc_elem;
+
+	if (!dhdp || !dhdp->event_log_filter) {
+		DHD_FILTER_ERR(("%s - dhdp or event_log_filter is NULL\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	filter = (EWP_filter_t *)dhdp->event_log_filter;
+
+	if (filter->enabled != TRUE) {
+		DHD_FILTER_ERR(("%s - EWP Filter is not enabled\n", __FUNCTION__));
+		return BCME_UNSUPPORTED;
+	}
+
+	/* Refer to STA interface */
+	last_elem = dhd_ring_get_last(filter->i_ring[0]);
+	if (last_elem == NULL) {
+		DHD_FILTER_ERR(("%s - last_elem is NULL\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	ifc_elem = (EWPF_ifc_elem_t *)last_elem;
+	ret = dhd_calculate_adps_energy_gain(&ifc_elem->adps_energy_gain);
+
+	return ret;
+}
+#endif /* WLADPS_ENERGY_GAIN */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_event_log_filter.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_event_log_filter.h
@@ -0,0 +1,75 @@
+/*
+ * Wifi dongle status Filter and Report
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef dhd_event_log_filter_h
+#define dhd_event_log_filter_h
+#include <dhd.h>
+#include <event_log_tag.h>
+#include <dhd_debug.h>
+
+typedef struct {
+	uint16	version;
+	uint8	htr_type;	/* from wl_slice_hist_XX_stats_xtlv_id */
+	uint8	htr_num;	/* number of elements in htr_running or htr_rc */
+	uint32	htr_rn_last;	/* last reasons along with seq, etc */
+	uint32	htr_rn_ts_last;	/* last time stamps corr to htr_rn_last */
+	uint32	htr_rn_prev;	/* last reasons along with seq, etc */
+	uint32	htr_rn_ts_prev;	/* last time stamps corr to htr_rn_prev */
+	uint32	htr_rc_max;	/* largest toss reasons and counts */
+	uint32	htr_rc_ts_max;	/* latest time stamp corr to htr_rc_max */
+	uint32	htr_rc_secnd;	/* second largest toss reasons and counts */
+	uint32	htr_rc_ts_secnd;	/* latest time stamps corr to htr_rc_second */
+} evt_hist_compact_toss_stats_v1_t;
+
+int dhd_event_log_filter_init(dhd_pub_t *dhdp, uint8 *buf, uint32 buf_size);
+void dhd_event_log_filter_deinit(dhd_pub_t *dhdp);
+void dhd_event_log_filter_event_handler(
+	dhd_pub_t *dhdp, prcd_event_log_hdr_t *plog_hdr, uint32 *data);
+
+void dhd_event_log_filter_notify_connect_request(dhd_pub_t *dhdp, uint8 *bssid, int channel);
+void dhd_event_log_filter_notify_connect_done(dhd_pub_t *dhdp, uint8 *bssid, int roam);
+#ifdef WLADPS_ENERGY_GAIN
+int dhd_event_log_filter_adps_energy_gain(dhd_pub_t *dhdp);
+#endif /* WLADPS_ENERGY_GAIN */
+#endif /* !dhd_event_log_filter_h */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_flowring.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_flowring.c
@@ -0,0 +1,1530 @@
+/*
+ * @file Broadcom Dongle Host Driver (DHD), Flow ring specific code at top level
+ *
+ * Flow rings are transmit traffic (=propagating towards antenna) related entities
+ *
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+/** XXX Twiki: [PCIeFullDongleArchitecture] */
+
+#include <typedefs.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <bcmdevs.h>
+
+#include <ethernet.h>
+#include <bcmevent.h>
+#include <dngl_stats.h>
+
+#include <dhd.h>
+
+#include <dhd_flowring.h>
+#include <dhd_bus.h>
+#include <dhd_proto.h>
+#include <dhd_dbg.h>
+#include <802.1d.h>
+#include <pcie_core.h>
+#include <bcmmsgbuf.h>
+#include <dhd_pcie.h>
+#include <dhd_config.h>
+
+static INLINE int dhd_flow_queue_throttle(flow_queue_t *queue);
+
+static INLINE uint16 dhd_flowid_find(dhd_pub_t *dhdp, uint8 ifindex,
+                                     uint8 prio, char *sa, char *da);
+
+static INLINE uint16 dhd_flowid_alloc(dhd_pub_t *dhdp, uint8 ifindex,
+                                      uint8 prio, char *sa, char *da);
+
+static INLINE int dhd_flowid_lookup(dhd_pub_t *dhdp, uint8 ifindex,
+                                uint8 prio, char *sa, char *da, uint16 *flowid);
+int dhd_flow_queue_overflow(flow_queue_t *queue, void *pkt);
+
+#define FLOW_QUEUE_PKT_NEXT(p)          PKTLINK(p)
+#define FLOW_QUEUE_PKT_SETNEXT(p, x)    PKTSETLINK((p), (x))
+
+const uint8 prio2ac[8] = { 0, 1, 1, 0, 2, 2, 3, 3 };
+const uint8 prio2tid[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+
+/** Queue overflow throttle. Return value: TRUE if throttle needs to be applied */
+static INLINE int
+dhd_flow_queue_throttle(flow_queue_t *queue)
+{
+#if defined(BCM_ROUTER_DHD)
+	/* Two tests
+	 * 1) Test whether overall level 2 (grandparent) cummulative threshold crossed.
+	 * 2) Or test whether queue's budget and overall cummulative threshold crossed.
+	 */
+	void *gp_clen_ptr = DHD_FLOW_QUEUE_L2CLEN_PTR(queue);
+	void *parent_clen_ptr = DHD_FLOW_QUEUE_CLEN_PTR(queue);
+	int gp_cumm_threshold = DHD_FLOW_QUEUE_L2THRESHOLD(queue);
+	int cumm_threshold = DHD_FLOW_QUEUE_THRESHOLD(queue);
+
+	int ret = ((DHD_CUMM_CTR_READ(gp_clen_ptr) > gp_cumm_threshold) ||
+		((DHD_FLOW_QUEUE_OVFL(queue, DHD_FLOW_QUEUE_MAX(queue))) &&
+		(DHD_CUMM_CTR_READ(parent_clen_ptr) > cumm_threshold)));
+	return ret;
+#else
+	return DHD_FLOW_QUEUE_FULL(queue);
+#endif /* ! BCM_ROUTER_DHD */
+}
+
+int
+BCMFASTPATH(dhd_flow_queue_overflow)(flow_queue_t *queue, void *pkt)
+{
+	return BCME_NORESOURCE;
+}
+
+/** Returns flow ring given a flowid */
+flow_ring_node_t *
+dhd_flow_ring_node(dhd_pub_t *dhdp, uint16 flowid)
+{
+	flow_ring_node_t * flow_ring_node;
+
+	ASSERT(dhdp != (dhd_pub_t*)NULL);
+	ASSERT(flowid <= dhdp->max_tx_flowid);
+	if (flowid > dhdp->max_tx_flowid) {
+		return NULL;
+	}
+
+	flow_ring_node = &(((flow_ring_node_t*)(dhdp->flow_ring_table))[flowid]);
+
+	ASSERT(flow_ring_node->flowid == flowid);
+	return flow_ring_node;
+}
+
+/** Returns 'backup' queue given a flowid */
+flow_queue_t *
+dhd_flow_queue(dhd_pub_t *dhdp, uint16 flowid)
+{
+	flow_ring_node_t * flow_ring_node = NULL;
+
+	flow_ring_node = dhd_flow_ring_node(dhdp, flowid);
+	if (flow_ring_node)
+		return &flow_ring_node->queue;
+	else
+		return NULL;
+}
+
+/* Flow ring's queue management functions */
+
+/** Reinitialize a flow ring's queue. */
+void
+dhd_flow_queue_reinit(dhd_pub_t *dhdp, flow_queue_t *queue, int max)
+{
+	ASSERT((queue != NULL) && (max > 0));
+
+	queue->head = queue->tail = NULL;
+	queue->len = 0;
+
+	/* Set queue's threshold and queue's parent cummulative length counter */
+	ASSERT(max > 1);
+	DHD_FLOW_QUEUE_SET_MAX(queue, max);
+	DHD_FLOW_QUEUE_SET_THRESHOLD(queue, max);
+	DHD_FLOW_QUEUE_SET_CLEN(queue, &dhdp->cumm_ctr);
+	DHD_FLOW_QUEUE_SET_L2CLEN(queue, &dhdp->l2cumm_ctr);
+
+	queue->failures = 0U;
+	queue->cb = &dhd_flow_queue_overflow;
+}
+
+/** Initialize a flow ring's queue, called on driver initialization. */
+void
+dhd_flow_queue_init(dhd_pub_t *dhdp, flow_queue_t *queue, int max)
+{
+	ASSERT((queue != NULL) && (max > 0));
+
+	dll_init(&queue->list);
+	dhd_flow_queue_reinit(dhdp, queue, max);
+}
+
+/** Register an enqueue overflow callback handler */
+void
+dhd_flow_queue_register(flow_queue_t *queue, flow_queue_cb_t cb)
+{
+	ASSERT(queue != NULL);
+	queue->cb = cb;
+}
+
+/**
+ * Enqueue an 802.3 packet at the back of a flow ring's queue. From there, it will travel later on
+ * to the flow ring itself.
+ */
+int
+BCMFASTPATH(dhd_flow_queue_enqueue)(dhd_pub_t *dhdp, flow_queue_t *queue, void *pkt)
+{
+	int ret = BCME_OK;
+
+	ASSERT(queue != NULL);
+
+	if (dhd_flow_queue_throttle(queue)) {
+		queue->failures++;
+		ret = (*queue->cb)(queue, pkt);
+		goto done;
+	}
+
+	if (queue->head) {
+		FLOW_QUEUE_PKT_SETNEXT(queue->tail, pkt);
+	} else {
+		queue->head = pkt;
+	}
+
+	FLOW_QUEUE_PKT_SETNEXT(pkt, NULL);
+
+	queue->tail = pkt; /* at tail */
+
+	queue->len++;
+	/* increment parent's cummulative length */
+	DHD_CUMM_CTR_INCR(DHD_FLOW_QUEUE_CLEN_PTR(queue));
+	/* increment grandparent's cummulative length */
+	DHD_CUMM_CTR_INCR(DHD_FLOW_QUEUE_L2CLEN_PTR(queue));
+
+done:
+	return ret;
+}
+
+int BCMFASTPATH
+(dhd_flow_queue_enqueue_head)(dhd_pub_t *dhdp, flow_queue_t *queue, void *pkt)
+{
+	int ret = BCME_OK;
+
+	ASSERT(queue != NULL);
+
+	if (dhd_flow_queue_throttle(queue)) {
+		queue->failures++;
+		ret = (*queue->cb)(queue, pkt);
+		goto done;
+	}
+
+	if (queue->head) {
+		FLOW_QUEUE_PKT_SETNEXT(pkt, queue->head);
+		queue->head = pkt;
+
+	} else {
+		queue->head = pkt;
+		FLOW_QUEUE_PKT_SETNEXT(pkt, NULL);
+		queue->tail = pkt; /* at tail */
+	}
+
+	queue->len++;
+	/* increment parent's cummulative length */
+	DHD_CUMM_CTR_INCR(DHD_FLOW_QUEUE_CLEN_PTR(queue));
+	/* increment grandparent's cummulative length */
+	DHD_CUMM_CTR_INCR(DHD_FLOW_QUEUE_L2CLEN_PTR(queue));
+
+done:
+	return ret;
+}
+
+/** Dequeue an 802.3 packet from a flow ring's queue, from head (FIFO) */
+void *
+BCMFASTPATH(dhd_flow_queue_dequeue)(dhd_pub_t *dhdp, flow_queue_t *queue)
+{
+	void * pkt;
+
+	ASSERT(queue != NULL);
+
+	pkt = queue->head; /* from head */
+
+	if (pkt == NULL) {
+		goto done;
+	}
+
+	queue->head = FLOW_QUEUE_PKT_NEXT(pkt);
+	if (queue->head == NULL)
+		queue->tail = NULL;
+
+	queue->len--;
+	/* decrement parent's cummulative length */
+	DHD_CUMM_CTR_DECR(DHD_FLOW_QUEUE_CLEN_PTR(queue));
+	/* decrement grandparent's cummulative length */
+	DHD_CUMM_CTR_DECR(DHD_FLOW_QUEUE_L2CLEN_PTR(queue));
+
+	FLOW_QUEUE_PKT_SETNEXT(pkt, NULL); /* dettach packet from queue */
+
+done:
+	return pkt;
+}
+
+/** Reinsert a dequeued 802.3 packet back at the head */
+void
+BCMFASTPATH(dhd_flow_queue_reinsert)(dhd_pub_t *dhdp, flow_queue_t *queue, void *pkt)
+{
+	if (queue->head == NULL) {
+		queue->tail = pkt;
+	}
+
+	FLOW_QUEUE_PKT_SETNEXT(pkt, queue->head);
+	queue->head = pkt;
+	queue->len++;
+	/* increment parent's cummulative length */
+	DHD_CUMM_CTR_INCR(DHD_FLOW_QUEUE_CLEN_PTR(queue));
+	/* increment grandparent's cummulative length */
+	DHD_CUMM_CTR_INCR(DHD_FLOW_QUEUE_L2CLEN_PTR(queue));
+}
+
+/** Fetch the backup queue for a flowring, and assign flow control thresholds */
+void
+dhd_flow_ring_config_thresholds(dhd_pub_t *dhdp, uint16 flowid,
+                     int queue_budget, int cumm_threshold, void *cumm_ctr,
+                     int l2cumm_threshold, void *l2cumm_ctr)
+{
+	flow_queue_t * queue = NULL;
+
+	ASSERT(dhdp != (dhd_pub_t*)NULL);
+	ASSERT(queue_budget > 1);
+	ASSERT(cumm_threshold > 1);
+	ASSERT(cumm_ctr != (void*)NULL);
+	ASSERT(l2cumm_threshold > 1);
+	ASSERT(l2cumm_ctr != (void*)NULL);
+
+	queue = dhd_flow_queue(dhdp, flowid);
+	if (queue) {
+		DHD_FLOW_QUEUE_SET_MAX(queue, queue_budget); /* Max queue length */
+
+		/* Set the queue's parent threshold and cummulative counter */
+		DHD_FLOW_QUEUE_SET_THRESHOLD(queue, cumm_threshold);
+		DHD_FLOW_QUEUE_SET_CLEN(queue, cumm_ctr);
+
+		/* Set the queue's grandparent threshold and cummulative counter */
+		DHD_FLOW_QUEUE_SET_L2THRESHOLD(queue, l2cumm_threshold);
+		DHD_FLOW_QUEUE_SET_L2CLEN(queue, l2cumm_ctr);
+	}
+}
+
+/*
+ * This function returns total number of flowrings that can be created for a INFRA STA.
+ * For prio2ac mapping, it will return 4, prio2ac[8] = { 0, 1, 1, 0, 2, 2, 3, 3 }
+ * For prio2tid mapping, it will return 8, prio2tid[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }
+ */
+uint8
+dhd_num_prio_supported_per_flow_ring(dhd_pub_t *dhdp)
+{
+	uint8 prio_count = 0;
+	int i;
+	/* Pick all elements one by one */
+	for (i = 0; i < NUMPRIO; i++)
+	{
+		/* Check if the picked element is already counted */
+		int j;
+		for (j = 0; j < i; j++) {
+			if (dhdp->flow_prio_map[i] == dhdp->flow_prio_map[j]) {
+				break;
+			}
+		}
+		/* If not counted earlier, then count it */
+		if (i == j) {
+			prio_count++;
+		}
+	}
+
+	return prio_count;
+}
+
+uint8
+dhd_get_max_multi_client_flow_rings(dhd_pub_t *dhdp)
+{
+	uint8 reserved_infra_sta_flow_rings = dhd_num_prio_supported_per_flow_ring(dhdp);
+	uint8 total_tx_flow_rings = (uint8)dhd_get_max_flow_rings(dhdp);
+	uint8 max_multi_client_flow_rings = total_tx_flow_rings - reserved_infra_sta_flow_rings;
+	return max_multi_client_flow_rings;
+}
+
+int
+dhd_flowid_map_init(dhd_pub_t *dhdp, uint16 max_tx_flow_rings)
+{
+	uint16 max_normal_tx_flow_rings = max_tx_flow_rings;
+
+	if (dhdp->htput_support) {
+		max_normal_tx_flow_rings = max_tx_flow_rings - HTPUT_TOTAL_FLOW_RINGS;
+	}
+
+	/* Construct a normal flowid allocator from FLOWID_RESERVED to
+	 * (max_normal_tx_flow_rings - 1)
+	 */
+	dhdp->flowid_allocator = id16_map_init(dhdp->osh, max_normal_tx_flow_rings,
+		FLOWID_RESERVED);
+	if (dhdp->flowid_allocator == NULL) {
+		DHD_ERROR(("%s: flowid allocator init failure\n", __FUNCTION__));
+		return BCME_NOMEM;
+	}
+
+	dhdp->htput_flowid_allocator = NULL;
+
+	if (dhdp->htput_support) {
+		if (HTPUT_TOTAL_FLOW_RINGS > 0) {
+			dhdp->htput_flow_ring_start = max_normal_tx_flow_rings + FLOWID_RESERVED;
+			/* Construct a htput flowid allocator from htput_flow_ring_start to
+			 * (htput_flow_ring_start + HTPUT_TOTAL_FLOW_RINGS - 1)
+			 */
+			dhdp->htput_flowid_allocator = id16_map_init(dhdp->osh,
+				HTPUT_TOTAL_FLOW_RINGS,	dhdp->htput_flow_ring_start);
+			if (dhdp->htput_flowid_allocator == NULL) {
+				DHD_ERROR(("%s: htput flowid allocator init failure\n",
+					__FUNCTION__));
+				return BCME_NOMEM;
+			}
+			dhdp->htput_client_flow_rings = 0u;
+		}
+	}
+
+	return BCME_OK;
+}
+
+void
+dhd_flowid_map_deinit(dhd_pub_t *dhdp)
+{
+	if (dhdp->flowid_allocator) {
+		dhdp->flowid_allocator = id16_map_fini(dhdp->osh, dhdp->flowid_allocator);
+	}
+	ASSERT(dhdp->flowid_allocator == NULL);
+
+	if (dhdp->htput_flowid_allocator) {
+		dhdp->htput_flowid_allocator = id16_map_fini(dhdp->osh,
+			dhdp->htput_flowid_allocator);
+		ASSERT(dhdp->htput_flowid_allocator == NULL);
+	}
+	dhdp->htput_client_flow_rings = 0u;
+
+	return;
+}
+
+/** Initializes data structures of multiple flow rings
+ * num_h2d_rings - max_h2d_rings including static and dynamic rings
+ */
+int
+dhd_flow_rings_init(dhd_pub_t *dhdp, uint32 num_h2d_rings)
+{
+	uint32 idx;
+	uint32 flow_ring_table_sz = 0;
+	uint32 if_flow_lkup_sz = 0;
+	flow_ring_table_t *flow_ring_table = NULL;
+	if_flow_lkup_t *if_flow_lkup = NULL;
+	void *lock = NULL;
+	void *list_lock = NULL;
+	unsigned long flags;
+	uint16 max_tx_flow_rings;
+
+	DHD_INFO(("%s\n", __FUNCTION__));
+
+	/*
+	 * Only 16-bit flowid map will be allocated for actual number of Tx flowrings
+	 * excluding common rings.
+	 * Rest all flowring data structure will be allocated for all num_h2d_rings.
+	 */
+	max_tx_flow_rings = dhd_get_max_flow_rings(dhdp);
+	if (dhd_flowid_map_init(dhdp, max_tx_flow_rings) != BCME_OK) {
+		DHD_ERROR(("%s: dhd_flowid_map_init failure\n", __FUNCTION__));
+		goto fail;
+	}
+
+	/* Any Tx flow id should not be > max_tx_flowid */
+	dhdp->max_tx_flowid = max_tx_flow_rings + FLOWID_RESERVED - 1;
+
+	/* Allocate a flow ring table, comprising of requested number of rings */
+	flow_ring_table_sz = (num_h2d_rings * sizeof(flow_ring_node_t));
+	flow_ring_table = (flow_ring_table_t *)MALLOCZ(dhdp->osh, flow_ring_table_sz);
+	if (flow_ring_table == NULL) {
+		DHD_ERROR(("%s: flow ring table alloc failure\n", __FUNCTION__));
+		goto fail;
+	}
+
+	/* Initialize flow ring table state */
+	DHD_CUMM_CTR_INIT(&dhdp->cumm_ctr);
+	DHD_CUMM_CTR_INIT(&dhdp->l2cumm_ctr);
+	bzero((uchar *)flow_ring_table, flow_ring_table_sz);
+	for (idx = 0; idx < num_h2d_rings; idx++) {
+		flow_ring_table[idx].status = FLOW_RING_STATUS_CLOSED;
+		flow_ring_table[idx].flowid = (uint16)idx;
+		flow_ring_table[idx].lock = osl_spin_lock_init(dhdp->osh);
+#ifdef IDLE_TX_FLOW_MGMT
+		flow_ring_table[idx].last_active_ts = OSL_SYSUPTIME();
+#endif /* IDLE_TX_FLOW_MGMT */
+		if (flow_ring_table[idx].lock == NULL) {
+			DHD_ERROR(("%s: Failed to init spinlock for queue!\n", __FUNCTION__));
+			goto fail;
+		}
+
+		dll_init(&flow_ring_table[idx].list);
+
+		/* Initialize the per flow ring backup queue */
+		dhd_flow_queue_init(dhdp, &flow_ring_table[idx].queue,
+		                    dhdp->conf->flow_ring_queue_threshold);
+	}
+
+	/* Allocate per interface hash table (for fast lookup from interface to flow ring) */
+	if_flow_lkup_sz = sizeof(if_flow_lkup_t) * DHD_MAX_IFS;
+	if_flow_lkup = (if_flow_lkup_t *)DHD_OS_PREALLOC(dhdp,
+		DHD_PREALLOC_IF_FLOW_LKUP, if_flow_lkup_sz);
+	if (if_flow_lkup == NULL) {
+		DHD_ERROR(("%s: if flow lkup alloc failure\n", __FUNCTION__));
+		goto fail;
+	}
+
+	/* Initialize per interface hash table */
+	for (idx = 0; idx < DHD_MAX_IFS; idx++) {
+		int hash_ix;
+		if_flow_lkup[idx].status = 0;
+		if_flow_lkup[idx].role = 0;
+		for (hash_ix = 0; hash_ix < DHD_FLOWRING_HASH_SIZE; hash_ix++)
+			if_flow_lkup[idx].fl_hash[hash_ix] = NULL;
+	}
+
+	lock = osl_spin_lock_init(dhdp->osh);
+	if (lock == NULL)
+		goto fail;
+
+	list_lock = osl_spin_lock_init(dhdp->osh);
+	if (list_lock == NULL)
+		goto lock_fail;
+
+	dhdp->flow_prio_map_type = DHD_FLOW_PRIO_AC_MAP;
+	bcopy(prio2ac, dhdp->flow_prio_map, sizeof(uint8) * NUMPRIO);
+
+	dhdp->max_multi_client_flow_rings = dhd_get_max_multi_client_flow_rings(dhdp);
+
+	OSL_ATOMIC_INIT(dhdp->osh, &dhdp->multi_client_flow_rings);
+
+#ifdef DHD_LOSSLESS_ROAMING
+	dhdp->dequeue_prec_map = ALLPRIO;
+#endif
+	/* Now populate into dhd pub */
+	DHD_FLOWID_LOCK(lock, flags);
+	dhdp->num_h2d_rings = num_h2d_rings;
+	dhdp->flow_ring_table = (void *)flow_ring_table;
+	dhdp->if_flow_lkup = (void *)if_flow_lkup;
+	dhdp->flowid_lock = lock;
+	dhdp->flow_rings_inited = TRUE;
+	dhdp->flowring_list_lock = list_lock;
+	DHD_FLOWID_UNLOCK(lock, flags);
+
+	DHD_INFO(("%s done\n", __FUNCTION__));
+	return BCME_OK;
+
+lock_fail:
+	/* deinit the spinlock */
+	osl_spin_lock_deinit(dhdp->osh, lock);
+
+fail:
+	/* Destruct the per interface flow lkup table */
+	if (if_flow_lkup != NULL) {
+		DHD_OS_PREFREE(dhdp, if_flow_lkup, if_flow_lkup_sz);
+	}
+	if (flow_ring_table != NULL) {
+		for (idx = 0; idx < num_h2d_rings; idx++) {
+			if (flow_ring_table[idx].lock != NULL)
+				osl_spin_lock_deinit(dhdp->osh, flow_ring_table[idx].lock);
+		}
+		MFREE(dhdp->osh, flow_ring_table, flow_ring_table_sz);
+	}
+	dhd_flowid_map_deinit(dhdp);
+
+	return BCME_NOMEM;
+}
+
+/** Deinit Flow Ring specific data structures */
+void dhd_flow_rings_deinit(dhd_pub_t *dhdp)
+{
+	uint16 idx;
+	uint32 flow_ring_table_sz;
+	uint32 if_flow_lkup_sz;
+	flow_ring_table_t *flow_ring_table;
+	unsigned long flags;
+	void *lock;
+
+	DHD_INFO(("dhd_flow_rings_deinit\n"));
+
+	if (!(dhdp->flow_rings_inited)) {
+		DHD_ERROR(("dhd_flow_rings not initialized!\n"));
+		return;
+	}
+
+	if (dhdp->flow_ring_table != NULL) {
+
+		ASSERT(dhdp->num_h2d_rings > 0);
+
+		DHD_FLOWID_LOCK(dhdp->flowid_lock, flags);
+		flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table;
+		dhdp->flow_ring_table = NULL;
+		DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+		for (idx = 0; idx < dhdp->num_h2d_rings; idx++) {
+			if (flow_ring_table[idx].active) {
+				dhd_bus_clean_flow_ring(dhdp->bus, &flow_ring_table[idx]);
+			}
+			ASSERT(DHD_FLOW_QUEUE_EMPTY(&flow_ring_table[idx].queue));
+
+			/* Deinit flow ring queue locks before destroying flow ring table */
+			if (flow_ring_table[idx].lock != NULL) {
+				osl_spin_lock_deinit(dhdp->osh, flow_ring_table[idx].lock);
+			}
+			flow_ring_table[idx].lock = NULL;
+
+		}
+
+		/* Destruct the flow ring table */
+		flow_ring_table_sz = dhdp->num_h2d_rings * sizeof(flow_ring_table_t);
+		MFREE(dhdp->osh, flow_ring_table, flow_ring_table_sz);
+	}
+
+	DHD_FLOWID_LOCK(dhdp->flowid_lock, flags);
+
+	/* Destruct the per interface flow lkup table */
+	if (dhdp->if_flow_lkup != NULL) {
+		if_flow_lkup_sz = sizeof(if_flow_lkup_t) * DHD_MAX_IFS;
+		bzero((uchar *)dhdp->if_flow_lkup, if_flow_lkup_sz);
+		DHD_OS_PREFREE(dhdp, dhdp->if_flow_lkup, if_flow_lkup_sz);
+		dhdp->if_flow_lkup = NULL;
+	}
+
+	/* Destruct the flowid allocator */
+	dhd_flowid_map_deinit(dhdp);
+
+	dhdp->num_h2d_rings = 0U;
+	bzero(dhdp->flow_prio_map, sizeof(uint8) * NUMPRIO);
+
+	dhdp->max_multi_client_flow_rings = 0U;
+
+	OSL_ATOMIC_INIT(dhdp->osh, &dhdp->multi_client_flow_rings);
+
+	lock = dhdp->flowid_lock;
+	dhdp->flowid_lock = NULL;
+
+	if (lock) {
+		DHD_FLOWID_UNLOCK(lock, flags);
+		osl_spin_lock_deinit(dhdp->osh, lock);
+	}
+
+	osl_spin_lock_deinit(dhdp->osh, dhdp->flowring_list_lock);
+	dhdp->flowring_list_lock = NULL;
+
+	ASSERT(dhdp->if_flow_lkup == NULL);
+	ASSERT(dhdp->flow_ring_table == NULL);
+	dhdp->flow_rings_inited = FALSE;
+}
+
+/** Uses hash table to quickly map from ifindex to a flow ring 'role' (STA/AP) */
+uint8
+dhd_flow_rings_ifindex2role(dhd_pub_t *dhdp, uint8 ifindex)
+{
+	if_flow_lkup_t *if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup;
+	ASSERT(if_flow_lkup);
+	return if_flow_lkup[ifindex].role;
+}
+
+#ifdef WLTDLS
+bool is_tdls_destination(dhd_pub_t *dhdp, uint8 *da)
+{
+	unsigned long flags;
+	tdls_peer_node_t *cur = NULL;
+
+	DHD_TDLS_LOCK(&dhdp->tdls_lock, flags);
+	/* Check only if tdls peer is added */
+	if (dhdp->peer_tbl.tdls_peer_count && !(ETHER_ISMULTI(da))) {
+		cur = dhdp->peer_tbl.node;
+
+		while (cur != NULL) {
+			if (!memcmp(da, cur->addr, ETHER_ADDR_LEN)) {
+				DHD_TDLS_UNLOCK(&dhdp->tdls_lock, flags);
+				return TRUE;
+			}
+			cur = cur->next;
+		}
+	}
+	DHD_TDLS_UNLOCK(&dhdp->tdls_lock, flags);
+	return FALSE;
+}
+#endif /* WLTDLS */
+
+/** Uses hash table to quickly map from ifindex+prio+da to a flow ring id */
+static INLINE uint16
+dhd_flowid_find(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, char *sa, char *da)
+{
+	int hash;
+	bool ismcast = FALSE;
+	flow_hash_info_t *cur;
+	if_flow_lkup_t *if_flow_lkup;
+	unsigned long flags;
+
+	ASSERT(ifindex < DHD_MAX_IFS);
+	if (ifindex >= DHD_MAX_IFS)
+		return FLOWID_INVALID;
+
+	DHD_FLOWID_LOCK(dhdp->flowid_lock, flags);
+	if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup;
+
+	ASSERT(if_flow_lkup);
+
+	if (DHD_IF_ROLE_GENERIC_STA(dhdp, ifindex)) {
+#ifdef WLTDLS
+		if (is_tdls_destination(dhdp, da)) {
+			hash = DHD_FLOWRING_HASHINDEX(da, prio);
+			cur = if_flow_lkup[ifindex].fl_hash[hash];
+			while (cur != NULL) {
+				if (!memcmp(cur->flow_info.da, da, ETHER_ADDR_LEN)) {
+					DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+					return cur->flowid;
+				}
+				cur = cur->next;
+			}
+			DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+			return FLOWID_INVALID;
+		}
+#endif /* WLTDLS */
+		/* For STA non TDLS dest and WDS dest flow ring id is mapped based on prio only */
+		cur = if_flow_lkup[ifindex].fl_hash[prio];
+		if (cur) {
+			DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+			return cur->flowid;
+		}
+	} else {
+
+		if (ETHER_ISMULTI(da) &&
+			TRUE) {
+			ismcast = TRUE;
+			hash = 0;
+		} else {
+			hash = DHD_FLOWRING_HASHINDEX(da, prio);
+		}
+
+		cur = if_flow_lkup[ifindex].fl_hash[hash];
+
+		while (cur) {
+			if ((ismcast && ETHER_ISMULTI(cur->flow_info.da)) ||
+				(!memcmp(cur->flow_info.da, da, ETHER_ADDR_LEN) &&
+				(cur->flow_info.tid == prio))) {
+				DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+				return cur->flowid;
+			}
+			cur = cur->next;
+		}
+	}
+	DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+
+	DHD_INFO(("%s: cannot find flowid\n", __FUNCTION__));
+	return FLOWID_INVALID;
+} /* dhd_flowid_find */
+
+static uint16
+dhd_flowid_map_alloc(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, char *da)
+{
+	uint16 flowid = FLOWID_INVALID;
+	ASSERT(dhdp->flowid_allocator != NULL);
+
+	/* P2P Connections are always 80Mhz */
+	if (DHD_IF_ROLE_P2PGC(dhdp, ifindex) ||
+	    DHD_IF_ROLE_P2PGO(dhdp, ifindex)) {
+		flowid = id16_map_alloc(dhdp->flowid_allocator);
+		return flowid;
+	}
+
+	if (dhdp->htput_flowid_allocator) {
+		if (prio == HTPUT_FLOW_RING_PRIO) {
+			if (DHD_IF_ROLE_GENERIC_STA(dhdp, ifindex)) {
+				/* For STA case, only one flowring per PRIO is created,
+				 * so no need to have a HTPUT counter variable for STA case.
+				 * If already HTPUT flowring is allocated for given HTPUT_PRIO,
+				 * then this function will not even get called as dhd_flowid_find
+				 * will take care assigning same for those HTPUT_PRIO packets.
+				 */
+				flowid = id16_map_alloc(dhdp->htput_flowid_allocator);
+			} else if (DHD_IF_ROLE_MULTI_CLIENT(dhdp, ifindex) && !ETHER_ISMULTI(da) &&
+				dhd_is_sta_htput(dhdp, ifindex, (uint8 *)da)) {
+				/* Use HTPUT flowrings for only HTPUT_NUM_CLIENT_FLOW_RINGS */
+				if (dhdp->htput_client_flow_rings < HTPUT_NUM_CLIENT_FLOW_RINGS) {
+					flowid = id16_map_alloc(dhdp->htput_flowid_allocator);
+					/* increment htput client counter */
+					if (flowid != FLOWID_INVALID) {
+						dhdp->htput_client_flow_rings++;
+					}
+				}
+			}
+		}
+	}
+
+	BCM_REFERENCE(flowid);
+
+	/*
+	 * For HTPUT case, if the high throughput flowrings are already allocated
+	 * for the given role, the control comes here.
+	 */
+	if (flowid == FLOWID_INVALID) {
+		flowid = id16_map_alloc(dhdp->flowid_allocator);
+	}
+
+	return flowid;
+}
+
+/** Create unique Flow ID, called when a flow ring is created. */
+static INLINE uint16
+dhd_flowid_alloc(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, char *sa, char *da)
+{
+	flow_hash_info_t *fl_hash_node, *cur;
+	if_flow_lkup_t *if_flow_lkup;
+	int hash;
+	uint16 flowid;
+	unsigned long flags;
+
+	fl_hash_node = (flow_hash_info_t *) MALLOCZ(dhdp->osh, sizeof(flow_hash_info_t));
+	if (fl_hash_node == NULL) {
+		DHD_ERROR(("%s: flow_hash_info_t memory allocation failed \n", __FUNCTION__));
+		return FLOWID_INVALID;
+	}
+	memcpy(fl_hash_node->flow_info.da, da, sizeof(fl_hash_node->flow_info.da));
+
+	DHD_FLOWID_LOCK(dhdp->flowid_lock, flags);
+	flowid = dhd_flowid_map_alloc(dhdp, ifindex, prio, da);
+	DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+
+	if (flowid == FLOWID_INVALID) {
+		MFREE(dhdp->osh, fl_hash_node,  sizeof(flow_hash_info_t));
+		DHD_ERROR_RLMT(("%s: cannot get free flowid \n", __FUNCTION__));
+		return FLOWID_INVALID;
+	}
+
+	fl_hash_node->flowid = flowid;
+	fl_hash_node->flow_info.tid = prio;
+	fl_hash_node->flow_info.ifindex = ifindex;
+	fl_hash_node->next = NULL;
+
+	DHD_FLOWID_LOCK(dhdp->flowid_lock, flags);
+	if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup;
+
+	if (DHD_IF_ROLE_GENERIC_STA(dhdp, ifindex)) {
+		/* For STA/GC non TDLS dest and WDS dest we allocate entry based on prio only */
+#ifdef WLTDLS
+		if (is_tdls_destination(dhdp, da)) {
+			hash = DHD_FLOWRING_HASHINDEX(da, prio);
+			cur = if_flow_lkup[ifindex].fl_hash[hash];
+			if (cur) {
+				while (cur->next) {
+					cur = cur->next;
+				}
+				cur->next = fl_hash_node;
+			} else {
+				if_flow_lkup[ifindex].fl_hash[hash] = fl_hash_node;
+			}
+		} else
+#endif /* WLTDLS */
+			if_flow_lkup[ifindex].fl_hash[prio] = fl_hash_node;
+	} else {
+
+		/* For bcast/mcast assign first slot in in interface */
+		hash = (ETHER_ISMULTI(da) &&
+			TRUE) ?  0 : DHD_FLOWRING_HASHINDEX(da, prio);
+
+		cur = if_flow_lkup[ifindex].fl_hash[hash];
+		if (cur) {
+			while (cur->next) {
+				cur = cur->next;
+			}
+			cur->next = fl_hash_node;
+		} else
+			if_flow_lkup[ifindex].fl_hash[hash] = fl_hash_node;
+	}
+	DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+
+	DHD_INFO(("%s: allocated flowid %d\n", __FUNCTION__, fl_hash_node->flowid));
+
+	if (fl_hash_node->flowid > dhdp->max_tx_flowid) {
+		DHD_ERROR(("%s: flowid=%d max_tx_flowid=%d ifindex=%d prio=%d role=%d\n",
+			__FUNCTION__, fl_hash_node->flowid, dhdp->max_tx_flowid,
+			ifindex, prio, if_flow_lkup[ifindex].role));
+		dhd_prhex("da", (uchar *)da, ETHER_ADDR_LEN, DHD_ERROR_VAL);
+		dhd_prhex("sa", (uchar *)sa, ETHER_ADDR_LEN, DHD_ERROR_VAL);
+		return FLOWID_INVALID;
+	}
+
+	return fl_hash_node->flowid;
+} /* dhd_flowid_alloc */
+
+/** Get flow ring ID, if not present try to create one */
+static INLINE int
+dhd_flowid_lookup(dhd_pub_t *dhdp, uint8 ifindex,
+                  uint8 prio, char *sa, char *da, uint16 *flowid)
+{
+	uint16 id;
+	flow_ring_node_t *flow_ring_node;
+	flow_ring_table_t *flow_ring_table;
+	unsigned long flags;
+	int ret;
+
+	DHD_TRACE(("%s\n", __FUNCTION__));
+
+	if (!dhdp->flow_ring_table) {
+		return BCME_ERROR;
+	}
+
+	ASSERT(ifindex < DHD_MAX_IFS);
+	if (ifindex >= DHD_MAX_IFS)
+		return BCME_BADARG;
+
+	flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table;
+
+	id = dhd_flowid_find(dhdp, ifindex, prio, sa, da);
+
+	if (id == FLOWID_INVALID || (id > dhdp->max_tx_flowid)) {
+		bool if_role_multi_client;
+		if_flow_lkup_t *if_flow_lkup;
+		if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup;
+
+		if (!if_flow_lkup[ifindex].status)
+			return BCME_ERROR;
+
+		/* check role for multi client case */
+		if_role_multi_client = DHD_IF_ROLE_MULTI_CLIENT(dhdp, ifindex);
+
+		/* Abort Flowring creation if multi client flowrings crossed the threshold */
+#ifdef DHD_LIMIT_MULTI_CLIENT_FLOWRINGS
+		if (if_role_multi_client &&
+			(OSL_ATOMIC_READ(dhdp->osh, &dhdp->multi_client_flow_rings) >=
+				dhdp->max_multi_client_flow_rings)) {
+			DHD_ERROR_RLMT(("%s: Max multi client flow rings reached: %d:%d\n",
+				__FUNCTION__,
+				OSL_ATOMIC_READ(dhdp->osh, &dhdp->multi_client_flow_rings),
+				dhdp->max_multi_client_flow_rings));
+			return BCME_ERROR;
+		}
+#endif /* DHD_LIMIT_MULTI_CLIENT_FLOWRINGS */
+
+		/* Do not create Flowring if peer is not associated */
+#if (defined(linux) || defined(LINUX)) && defined(PCIE_FULL_DONGLE)
+		if (if_role_multi_client && !ETHER_ISMULTI(da) &&
+			!dhd_sta_associated(dhdp, ifindex, (uint8 *)da)) {
+			DHD_ERROR_RLMT(("%s: Skip send pkt without peer addition\n", __FUNCTION__));
+			return BCME_ERROR;
+		}
+#endif /* (linux || LINUX) && PCIE_FULL_DONGLE */
+
+		id = dhd_flowid_alloc(dhdp, ifindex, prio, sa, da);
+		if (id == FLOWID_INVALID) {
+			DHD_ERROR_RLMT(("%s: alloc flowid ifindex %u status %u\n",
+				__FUNCTION__, ifindex, if_flow_lkup[ifindex].status));
+			return BCME_ERROR;
+		}
+
+		ASSERT(id <= dhdp->max_tx_flowid);
+
+		/* Only after flowid alloc, increment multi_client_flow_rings */
+		if (if_role_multi_client) {
+			OSL_ATOMIC_INC(dhdp->osh, &dhdp->multi_client_flow_rings);
+		}
+
+		/* register this flowid in dhd_pub */
+		dhd_add_flowid(dhdp, ifindex, prio, da, id);
+
+		flow_ring_node = (flow_ring_node_t *) &flow_ring_table[id];
+
+		DHD_FLOWRING_LOCK(flow_ring_node->lock, flags);
+
+		/* Init Flow info */
+		memcpy(flow_ring_node->flow_info.sa, sa, sizeof(flow_ring_node->flow_info.sa));
+		memcpy(flow_ring_node->flow_info.da, da, sizeof(flow_ring_node->flow_info.da));
+		flow_ring_node->flow_info.tid = prio;
+		flow_ring_node->flow_info.ifindex = ifindex;
+		flow_ring_node->active = TRUE;
+		flow_ring_node->status = FLOW_RING_STATUS_CREATE_PENDING;
+
+#ifdef DEVICE_TX_STUCK_DETECT
+		flow_ring_node->tx_cmpl = flow_ring_node->tx_cmpl_prev = OSL_SYSUPTIME();
+		flow_ring_node->stuck_count = 0;
+#endif /* DEVICE_TX_STUCK_DETECT */
+#ifdef TX_STATUS_LATENCY_STATS
+		flow_ring_node->flow_info.num_tx_status = 0;
+		flow_ring_node->flow_info.cum_tx_status_latency = 0;
+		flow_ring_node->flow_info.num_tx_pkts = 0;
+#endif /* TX_STATUS_LATENCY_STATS */
+#ifdef BCMDBG
+		bzero(&flow_ring_node->flow_info.tx_status[0],
+			sizeof(uint32) * DHD_MAX_TX_STATUS_MSGS);
+#endif
+		DHD_FLOWRING_UNLOCK(flow_ring_node->lock, flags);
+
+		/* Create and inform device about the new flow */
+		if (dhd_bus_flow_ring_create_request(dhdp->bus, (void *)flow_ring_node)
+				!= BCME_OK) {
+			DHD_FLOWRING_LOCK(flow_ring_node->lock, flags);
+			flow_ring_node->status = FLOW_RING_STATUS_CLOSED;
+			flow_ring_node->active = FALSE;
+			DHD_FLOWRING_UNLOCK(flow_ring_node->lock, flags);
+			DHD_ERROR(("%s: create error %d\n", __FUNCTION__, id));
+			return BCME_ERROR;
+		}
+
+		*flowid = id;
+		return BCME_OK;
+	} else {
+		/* if the Flow id was found in the hash */
+
+		if (id > dhdp->max_tx_flowid) {
+			DHD_ERROR(("%s: Invalid flow id : %u, max_tx_flowid : %u\n",
+				__FUNCTION__, id, dhdp->max_tx_flowid));
+			*flowid = FLOWID_INVALID;
+			ASSERT(0);
+			return BCME_ERROR;
+		}
+
+		flow_ring_node = (flow_ring_node_t *) &flow_ring_table[id];
+		DHD_FLOWRING_LOCK(flow_ring_node->lock, flags);
+
+		/*
+		 * If the flow_ring_node is in Open State or Status pending state then
+		 * we can return the Flow id to the caller.If the flow_ring_node is in
+		 * FLOW_RING_STATUS_PENDING this means the creation is in progress and
+		 * hence the packets should be queued.
+		 *
+		 * If the flow_ring_node is in FLOW_RING_STATUS_DELETE_PENDING Or
+		 * FLOW_RING_STATUS_CLOSED, then we should return Error.
+		 * Note that if the flowing is being deleted we would mark it as
+		 * FLOW_RING_STATUS_DELETE_PENDING.  Now before Dongle could respond and
+		 * before we mark it as FLOW_RING_STATUS_CLOSED we could get tx packets.
+		 * We should drop the packets in that case.
+		 * The decission to return OK should NOT be based on 'active' variable, beause
+		 * active is made TRUE when a flow_ring_node gets allocated and is made
+		 * FALSE when the flow ring gets removed and does not reflect the True state
+		 * of the Flow ring.
+		 * In case if IDLE_TX_FLOW_MGMT is defined, we have to handle two more flowring
+		 * states. If the flow_ring_node's status is FLOW_RING_STATUS_SUSPENDED, the flowid
+		 * is to be returned and from dhd_bus_txdata, the flowring would be resumed again.
+		 * The status FLOW_RING_STATUS_RESUME_PENDING, is equivalent to
+		 * FLOW_RING_STATUS_CREATE_PENDING.
+		 */
+		if (flow_ring_node->status == FLOW_RING_STATUS_DELETE_PENDING ||
+			flow_ring_node->status == FLOW_RING_STATUS_CLOSED) {
+			*flowid = FLOWID_INVALID;
+			ret = BCME_ERROR;
+		} else {
+			*flowid = id;
+			ret = BCME_OK;
+		}
+
+		DHD_FLOWRING_UNLOCK(flow_ring_node->lock, flags);
+		return ret;
+	} /* Flow Id found in the hash */
+} /* dhd_flowid_lookup */
+
+int
+dhd_flowid_find_by_ifidx(dhd_pub_t *dhdp, uint8 ifindex, uint16 flowid)
+{
+	int hashidx = 0;
+	bool found = FALSE;
+	flow_hash_info_t *cur;
+	if_flow_lkup_t *if_flow_lkup;
+	unsigned long flags;
+
+	if (!dhdp->flow_ring_table) {
+		DHD_ERROR(("%s : dhd->flow_ring_table is NULL\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	DHD_FLOWID_LOCK(dhdp->flowid_lock, flags);
+	if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup;
+	for (hashidx = 0; hashidx < DHD_FLOWRING_HASH_SIZE; hashidx++) {
+		cur = if_flow_lkup[ifindex].fl_hash[hashidx];
+		if (cur) {
+			if (cur->flowid == flowid) {
+				found = TRUE;
+			}
+
+			while (!found && cur) {
+				if (cur->flowid == flowid) {
+					found = TRUE;
+					break;
+				}
+				cur = cur->next;
+			}
+
+			if (found) {
+				DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+				return BCME_OK;
+			}
+		}
+	}
+	DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+
+	return BCME_ERROR;
+}
+
+int
+dhd_flowid_debug_create(dhd_pub_t *dhdp, uint8 ifindex,
+	uint8 prio, char *sa, char *da, uint16 *flowid)
+{
+	return dhd_flowid_lookup(dhdp, ifindex, prio, sa, da, flowid);
+}
+
+/**
+ * Assign existing or newly created flowid to an 802.3 packet. This flowid is later on used to
+ * select the flowring to send the packet to the dongle.
+ */
+int
+BCMFASTPATH(dhd_flowid_update)(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio, void *pktbuf)
+{
+	uint8 *pktdata = (uint8 *)PKTDATA(dhdp->osh, pktbuf);
+	struct ether_header *eh = (struct ether_header *)pktdata;
+	uint16 flowid = 0;
+
+	ASSERT(ifindex < DHD_MAX_IFS);
+
+	if (ifindex >= DHD_MAX_IFS) {
+		return BCME_BADARG;
+	}
+
+	if (!dhdp->flowid_allocator) {
+		DHD_ERROR(("%s: Flow ring not intited yet  \n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	if (dhd_flowid_lookup(dhdp, ifindex, prio, (char *)eh->ether_shost, (char *)eh->ether_dhost,
+		&flowid) != BCME_OK) {
+		return BCME_ERROR;
+	}
+
+	DHD_INFO(("%s: prio %d flowid %d\n", __FUNCTION__, prio, flowid));
+
+	/* Tag the packet with flowid */
+	DHD_PKT_SET_FLOWID(pktbuf, flowid);
+	return BCME_OK;
+}
+
+static void
+dhd_flowid_map_free(dhd_pub_t *dhdp, uint8 ifindex, uint16 flowid)
+{
+	if (dhdp->htput_flowid_allocator) {
+		if (DHD_IS_FLOWID_HTPUT(dhdp, flowid)) {
+			id16_map_free(dhdp->htput_flowid_allocator, flowid);
+			/* decrement htput client counter */
+			if (DHD_IF_ROLE_MULTI_CLIENT(dhdp, ifindex)) {
+				dhdp->htput_client_flow_rings--;
+			}
+			return;
+		}
+	}
+
+	id16_map_free(dhdp->flowid_allocator, flowid);
+
+	return;
+}
+
+void
+dhd_flowid_free(dhd_pub_t *dhdp, uint8 ifindex, uint16 flowid)
+{
+	int hashix;
+	bool found = FALSE;
+	flow_hash_info_t *cur, *prev;
+	if_flow_lkup_t *if_flow_lkup;
+	unsigned long flags;
+	bool if_role_multi_client;
+
+	ASSERT(ifindex < DHD_MAX_IFS);
+	if (ifindex >= DHD_MAX_IFS)
+		return;
+
+	DHD_FLOWID_LOCK(dhdp->flowid_lock, flags);
+	if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup;
+
+	if_role_multi_client = DHD_IF_ROLE_MULTI_CLIENT(dhdp, ifindex);
+
+	for (hashix = 0; hashix < DHD_FLOWRING_HASH_SIZE; hashix++) {
+
+		cur = if_flow_lkup[ifindex].fl_hash[hashix];
+
+		if (cur) {
+			if (cur->flowid == flowid) {
+				found = TRUE;
+			}
+
+			prev = NULL;
+			while (!found && cur) {
+				if (cur->flowid == flowid) {
+					found = TRUE;
+					break;
+				}
+				prev = cur;
+				cur = cur->next;
+			}
+			if (found) {
+				if (!prev) {
+					if_flow_lkup[ifindex].fl_hash[hashix] = cur->next;
+				} else {
+					prev->next = cur->next;
+				}
+
+				/* Decrement multi_client_flow_rings */
+				if (if_role_multi_client) {
+					if (OSL_ATOMIC_READ(dhdp->osh,
+						&dhdp->multi_client_flow_rings)) {
+						OSL_ATOMIC_DEC(dhdp->osh,
+							&dhdp->multi_client_flow_rings);
+					}
+				}
+
+				/* deregister flowid from dhd_pub. */
+				dhd_del_flowid(dhdp, ifindex, flowid);
+
+				dhd_flowid_map_free(dhdp, ifindex, flowid);
+				MFREE(dhdp->osh, cur, sizeof(flow_hash_info_t));
+				DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+
+				return;
+			}
+		}
+	}
+
+	DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+	DHD_ERROR(("%s: could not free flow ring hash entry flowid %d\n",
+	           __FUNCTION__, flowid));
+} /* dhd_flowid_free */
+
+/**
+ * Delete all Flow rings associated with the given interface. Is called when eg the dongle
+ * indicates that a wireless link has gone down.
+ */
+void
+dhd_flow_rings_delete(dhd_pub_t *dhdp, uint8 ifindex)
+{
+	uint32 id;
+	flow_ring_table_t *flow_ring_table;
+
+	DHD_ERROR(("%s: ifindex %u\n", __FUNCTION__, ifindex));
+
+	ASSERT(ifindex < DHD_MAX_IFS);
+	if (ifindex >= DHD_MAX_IFS)
+		return;
+
+	if (!dhdp->flow_ring_table)
+		return;
+
+	flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table;
+	for (id = 0; id < dhdp->num_h2d_rings; id++) {
+		if (flow_ring_table[id].active &&
+			(flow_ring_table[id].flow_info.ifindex == ifindex) &&
+			(flow_ring_table[id].status == FLOW_RING_STATUS_OPEN)) {
+			dhd_bus_flow_ring_delete_request(dhdp->bus,
+			                                 (void *) &flow_ring_table[id]);
+		}
+	}
+}
+
+void
+dhd_update_multicilent_flow_rings(dhd_pub_t *dhdp, uint8 ifindex, bool increment)
+{
+	uint32 id;
+	flow_ring_table_t *flow_ring_table;
+
+	DHD_ERROR(("%s: ifindex %u\n", __FUNCTION__, ifindex));
+
+	ASSERT(ifindex < DHD_MAX_IFS);
+	if (ifindex >= DHD_MAX_IFS)
+		return;
+
+	if (!dhdp->flow_ring_table)
+		return;
+
+	flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table;
+	for (id = 0; id < dhdp->num_h2d_rings; id++) {
+		if (flow_ring_table[id].active &&
+			(flow_ring_table[id].flow_info.ifindex == ifindex) &&
+			(flow_ring_table[id].status == FLOW_RING_STATUS_OPEN)) {
+			if (increment) {
+				if (OSL_ATOMIC_READ(dhdp->osh, &dhdp->multi_client_flow_rings) <
+					dhdp->max_multi_client_flow_rings) {
+					OSL_ATOMIC_INC(dhdp->osh, &dhdp->multi_client_flow_rings);
+				} else {
+					DHD_ERROR(("%s: multi_client_flow_rings:%u"
+						" reached max:%d\n", __FUNCTION__,
+						OSL_ATOMIC_READ(dhdp->osh,
+						&dhdp->multi_client_flow_rings),
+						dhdp->max_multi_client_flow_rings));
+				}
+			} else {
+				if (OSL_ATOMIC_READ(dhdp->osh, &dhdp->multi_client_flow_rings)) {
+					OSL_ATOMIC_DEC(dhdp->osh, &dhdp->multi_client_flow_rings);
+				} else {
+					DHD_ERROR(("%s: multi_client_flow_rings:%u"
+						" reached ZERO\n", __FUNCTION__,
+						OSL_ATOMIC_READ(dhdp->osh,
+						&dhdp->multi_client_flow_rings)));
+				}
+			}
+		}
+	}
+}
+void
+dhd_flow_rings_flush(dhd_pub_t *dhdp, uint8 ifindex)
+{
+	uint32 id;
+	flow_ring_table_t *flow_ring_table;
+
+	DHD_INFO(("%s: ifindex %u\n", __FUNCTION__, ifindex));
+
+	ASSERT(ifindex < DHD_MAX_IFS);
+	if (ifindex >= DHD_MAX_IFS)
+		return;
+
+	if (!dhdp->flow_ring_table)
+		return;
+	flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table;
+
+	for (id = 0; id < dhdp->num_h2d_rings; id++) {
+		if (flow_ring_table[id].active &&
+			(flow_ring_table[id].flow_info.ifindex == ifindex) &&
+			(flow_ring_table[id].status == FLOW_RING_STATUS_OPEN)) {
+			dhd_bus_flow_ring_flush_request(dhdp->bus,
+			                                 (void *) &flow_ring_table[id]);
+		}
+	}
+}
+
+/** Delete flow ring(s) for given peer address. */
+void
+dhd_flow_rings_delete_for_peer(dhd_pub_t *dhdp, uint8 ifindex, char *addr)
+{
+	uint32 id;
+	flow_ring_table_t *flow_ring_table;
+
+	DHD_INFO(("%s: ifindex %u\n", __FUNCTION__, ifindex));
+
+	ASSERT(ifindex < DHD_MAX_IFS);
+	if (ifindex >= DHD_MAX_IFS)
+		return;
+
+	if (!dhdp->flow_ring_table)
+		return;
+
+	flow_ring_table = (flow_ring_table_t *)dhdp->flow_ring_table;
+	for (id = 0; id < dhdp->num_h2d_rings; id++) {
+		/*
+		 * Send flowring delete request even if flowring status is
+		 * FLOW_RING_STATUS_CREATE_PENDING, to handle cases where DISASSOC_IND
+		 * event comes ahead of flowring create response.
+		 * Otherwise the flowring will not be deleted later as there will not be any
+		 * DISASSOC_IND event. With this change, when create response event comes to DHD,
+		 * it will change the status to FLOW_RING_STATUS_OPEN and soon delete response
+		 * event will come, upon which DHD will delete the flowring.
+		 */
+		if (flow_ring_table[id].active &&
+			(flow_ring_table[id].flow_info.ifindex == ifindex) &&
+			(!memcmp(flow_ring_table[id].flow_info.da, addr, ETHER_ADDR_LEN)) &&
+			((flow_ring_table[id].status == FLOW_RING_STATUS_OPEN) ||
+			(flow_ring_table[id].status == FLOW_RING_STATUS_CREATE_PENDING))) {
+			DHD_INFO(("%s: deleting flowid %d\n",
+				__FUNCTION__, flow_ring_table[id].flowid));
+			dhd_bus_flow_ring_delete_request(dhdp->bus,
+				(void *) &flow_ring_table[id]);
+		}
+	}
+}
+
+/** Handles interface ADD, CHANGE, DEL indications from the dongle */
+void
+dhd_update_interface_flow_info(dhd_pub_t *dhdp, uint8 ifindex,
+                               uint8 op, uint8 role)
+{
+	if_flow_lkup_t *if_flow_lkup;
+	unsigned long flags;
+
+	ASSERT(ifindex < DHD_MAX_IFS);
+	if (ifindex >= DHD_MAX_IFS)
+		return;
+
+	DHD_INFO(("%s: ifindex %u op %u role is %u \n",
+	          __FUNCTION__, ifindex, op, role));
+	if (!dhdp->flowid_allocator) {
+		DHD_ERROR(("%s: Flow ring not intited yet  \n", __FUNCTION__));
+		return;
+	}
+
+	DHD_FLOWID_LOCK(dhdp->flowid_lock, flags);
+	if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup;
+
+	if (op == WLC_E_IF_ADD || op == WLC_E_IF_CHANGE) {
+		DHD_ERROR(("%s: ifindex:%d previous role:%d new role:%d\n",
+			__FUNCTION__, ifindex, if_flow_lkup[ifindex].role, role));
+		if_flow_lkup[ifindex].role = role;
+#ifdef PCIE_FULL_DONGLE
+		if (op == WLC_E_IF_CHANGE) {
+			bool increment = DHD_IF_ROLE_MULTI_CLIENT(dhdp, ifindex);
+			dhd_update_multicilent_flow_rings(dhdp, ifindex, increment);
+		}
+#endif /* PCIE_FULL_DONGLE */
+
+		if (role == WLC_E_IF_ROLE_WDS) {
+			/**
+			 * WDS role does not send WLC_E_LINK event after interface is up.
+			 * So to create flowrings for WDS, make status as TRUE in WLC_E_IF itself.
+			 * same is true while making the status as FALSE.
+			 * TODO: Fix FW to send WLC_E_LINK for WDS role aswell. So that all the
+			 * interfaces are handled uniformly.
+			 */
+			if_flow_lkup[ifindex].status = TRUE;
+			DHD_INFO(("%s: Mcast Flow ring for ifindex %d role is %d \n",
+			          __FUNCTION__, ifindex, role));
+		}
+	} else	if ((op == WLC_E_IF_DEL) && (role == WLC_E_IF_ROLE_WDS)) {
+		if_flow_lkup[ifindex].status = FALSE;
+		DHD_INFO(("%s: cleanup all Flow rings for ifindex %d role is %d \n",
+		          __FUNCTION__, ifindex, role));
+	}
+	DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+}
+
+/** Handles a STA 'link' indication from the dongle */
+int
+dhd_update_interface_link_status(dhd_pub_t *dhdp, uint8 ifindex, uint8 status)
+{
+	if_flow_lkup_t *if_flow_lkup;
+	unsigned long flags;
+
+	ASSERT(ifindex < DHD_MAX_IFS);
+	if (ifindex >= DHD_MAX_IFS)
+		return BCME_BADARG;
+
+	DHD_INFO(("%s: ifindex %d status %d\n", __FUNCTION__, ifindex, status));
+
+	DHD_FLOWID_LOCK(dhdp->flowid_lock, flags);
+	if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup;
+
+	if (status) {
+		if_flow_lkup[ifindex].status = TRUE;
+	} else {
+		if_flow_lkup[ifindex].status = FALSE;
+	}
+
+	DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+
+	return BCME_OK;
+}
+
+/** Update flow priority mapping, called on IOVAR */
+int dhd_update_flow_prio_map(dhd_pub_t *dhdp, uint8 map)
+{
+	uint16 flowid;
+	flow_ring_node_t *flow_ring_node;
+
+	if (map > DHD_FLOW_PRIO_LLR_MAP)
+		return BCME_BADOPTION;
+
+	/* Check if we need to change prio map */
+	if (map == dhdp->flow_prio_map_type)
+		return BCME_OK;
+
+	/* If any ring is active we cannot change priority mapping for flow rings */
+	for (flowid = 0; flowid < dhdp->num_h2d_rings; flowid++) {
+		flow_ring_node = DHD_FLOW_RING(dhdp, flowid);
+		if (flow_ring_node->active)
+			return BCME_EPERM;
+	}
+
+	/* Inform firmware about new mapping type */
+	if (BCME_OK != dhd_flow_prio_map(dhdp, &map, TRUE))
+		return BCME_ERROR;
+
+	/* update internal structures */
+	dhdp->flow_prio_map_type = map;
+	if (dhdp->flow_prio_map_type == DHD_FLOW_PRIO_TID_MAP)
+		bcopy(prio2tid, dhdp->flow_prio_map, sizeof(uint8) * NUMPRIO);
+	else
+		bcopy(prio2ac, dhdp->flow_prio_map, sizeof(uint8) * NUMPRIO);
+
+	dhdp->max_multi_client_flow_rings = dhd_get_max_multi_client_flow_rings(dhdp);
+
+	return BCME_OK;
+}
+
+/** Inform firmware on updated flow priority mapping, called on IOVAR */
+int dhd_flow_prio_map(dhd_pub_t *dhd, uint8 *map, bool set)
+{
+	uint8 iovbuf[WLC_IOCTL_SMLEN];
+	int len;
+	uint32 val;
+	if (!set) {
+		bzero(&iovbuf, sizeof(iovbuf));
+		len = bcm_mkiovar("bus:fl_prio_map", NULL, 0, (char*)iovbuf, sizeof(iovbuf));
+		if (len == 0) {
+			return BCME_BUFTOOSHORT;
+		}
+		if (dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0) < 0) {
+			DHD_ERROR(("%s: failed to get fl_prio_map\n", __FUNCTION__));
+			return BCME_ERROR;
+		}
+		*map = iovbuf[0];
+		return BCME_OK;
+	}
+	val = (uint32)map[0];
+	len = bcm_mkiovar("bus:fl_prio_map", (char *)&val, sizeof(val),
+		(char*)iovbuf, sizeof(iovbuf));
+	if (len == 0) {
+		return BCME_BUFTOOSHORT;
+	}
+	if (dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, len, TRUE, 0) < 0) {
+		DHD_ERROR(("%s: failed to set fl_prio_map \n",
+			__FUNCTION__));
+		return BCME_ERROR;
+	}
+	return BCME_OK;
+}
+
+uint32
+dhd_active_tx_flowring_bkpq_len(dhd_pub_t *dhd)
+{
+	unsigned long list_lock_flags;
+	dll_t *item, *prev;
+	flow_ring_node_t *flow_ring_node;
+	dhd_bus_t *bus = dhd->bus;
+	uint32 active_tx_flowring_qlen = 0;
+
+	DHD_FLOWRING_LIST_LOCK(bus->dhd->flowring_list_lock, list_lock_flags);
+
+	for (item = dll_tail_p(&bus->flowring_active_list);
+			!dll_end(&bus->flowring_active_list, item); item = prev) {
+
+		prev = dll_prev_p(item);
+
+		flow_ring_node = dhd_constlist_to_flowring(item);
+		if (flow_ring_node->active) {
+			DHD_INFO(("%s :%d\n", __FUNCTION__, flow_ring_node->queue.len));
+			active_tx_flowring_qlen += flow_ring_node->queue.len;
+		}
+	}
+	DHD_FLOWRING_LIST_UNLOCK(bus->dhd->flowring_list_lock, list_lock_flags);
+	return active_tx_flowring_qlen;
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_flowring.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_flowring.h
@@ -0,0 +1,329 @@
+/*
+ * @file Header file describing the flow rings DHD interfaces.
+ *
+ * Flow rings are transmit traffic (=propagating towards antenna) related entities.
+ *
+ * Provides type definitions and function prototypes used to create, delete and manage flow rings at
+ * high level.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+/** XXX Twiki: [PCIeFullDongleArchitecture] */
+
+/****************
+ * Common types *
+ */
+
+#ifndef _dhd_flowrings_h_
+#define _dhd_flowrings_h_
+
+/* Max pkts held in a flow ring's backup queue */
+#define FLOW_RING_QUEUE_THRESHOLD       (2048)
+
+/* Number of H2D common rings */
+#define FLOW_RING_COMMON                BCMPCIE_H2D_COMMON_MSGRINGS
+
+#define FLOWID_INVALID                  (ID16_INVALID)
+#define FLOWID_RESERVED                 (FLOW_RING_COMMON)
+
+#define FLOW_RING_STATUS_OPEN           0
+#define FLOW_RING_STATUS_CREATE_PENDING	1
+#define FLOW_RING_STATUS_CLOSED         2
+#define FLOW_RING_STATUS_DELETE_PENDING 3
+#define FLOW_RING_STATUS_FLUSH_PENDING  4
+
+#ifdef IDLE_TX_FLOW_MGMT
+#define FLOW_RING_STATUS_SUSPENDED	5
+#define FLOW_RING_STATUS_RESUME_PENDING	6
+#endif /* IDLE_TX_FLOW_MGMT */
+#define FLOW_RING_STATUS_STA_FREEING    7
+
+#define HTPUT_FLOW_RING_PRIO		PRIO_8021D_BE
+#define HTPUT_NUM_STA_FLOW_RINGS	1u
+#define HTPUT_NUM_CLIENT_FLOW_RINGS	3u
+#define HTPUT_TOTAL_FLOW_RINGS		(HTPUT_NUM_STA_FLOW_RINGS + HTPUT_NUM_CLIENT_FLOW_RINGS)
+#define DHD_IS_FLOWID_HTPUT(pub, flowid) \
+	((pub)->htput_support && (flowid >= (pub)->htput_flow_ring_start) && \
+	((uint16)flowid < ((pub)->htput_flow_ring_start + HTPUT_TOTAL_FLOW_RINGS)))
+
+#if defined(FLOW_RING_PREALLOC)
+#define MAX_FLOW_RINGS 64
+#endif /* FLOW_RING_PREALLOC */
+
+#define DHD_FLOWRING_RX_BUFPOST_PKTSZ	2048
+
+#define DHD_FLOWRING_RX_BUFPOST_PKTSZ_MAX 4096
+
+#define DHD_FLOWRING_TX_BIG_PKT_SIZE	(3700u)
+
+#define DHD_FLOW_PRIO_AC_MAP		0
+#define DHD_FLOW_PRIO_TID_MAP		1
+/* Flow ring prority map for lossless roaming */
+#define DHD_FLOW_PRIO_LLR_MAP		2
+
+/* Hashing a MacAddress for lkup into a per interface flow hash table */
+#define DHD_FLOWRING_HASH_SIZE    256
+#define	DHD_FLOWRING_HASHINDEX(ea, prio) \
+	       ((((uint8 *)(ea))[3] ^ ((uint8 *)(ea))[4] ^ ((uint8 *)(ea))[5] ^ ((uint8)(prio))) \
+		% DHD_FLOWRING_HASH_SIZE)
+
+#define DHD_IF_ROLE(pub, idx)		(((if_flow_lkup_t *)(pub)->if_flow_lkup)[idx].role)
+#define DHD_IF_ROLE_AP(pub, idx)	(DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_AP)
+#define DHD_IF_ROLE_STA(pub, idx)	(DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_STA)
+#define DHD_IF_ROLE_P2PGC(pub, idx)	(DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_P2P_CLIENT)
+#define DHD_IF_ROLE_P2PGO(pub, idx)	(DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_P2P_GO)
+#define DHD_IF_ROLE_WDS(pub, idx)	(DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_WDS)
+#define DHD_IF_ROLE_IBSS(pub, idx)	(DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_IBSS)
+#define DHD_IF_ROLE_NAN(pub, idx)	(DHD_IF_ROLE(pub, idx) == WLC_E_IF_ROLE_NAN)
+
+#define DHD_IF_ROLE_GENERIC_STA(pub, idx) \
+	(DHD_IF_ROLE_STA(pub, idx) || DHD_IF_ROLE_P2PGC(pub, idx) || DHD_IF_ROLE_WDS(pub, idx))
+
+#define DHD_IF_ROLE_MULTI_CLIENT(pub, idx) \
+	(DHD_IF_ROLE_AP(pub, idx) || DHD_IF_ROLE_P2PGO(pub, idx) ||\
+		DHD_IF_ROLE_NAN(pub, idx))
+
+#define DHD_FLOW_RING(dhdp, flowid) \
+	(flow_ring_node_t *)&(((flow_ring_node_t *)((dhdp)->flow_ring_table))[flowid])
+
+struct flow_queue;
+
+/* Flow Ring Queue Enqueue overflow callback */
+typedef int (*flow_queue_cb_t)(struct flow_queue * queue, void * pkt);
+
+/**
+ * Each flow ring has an associated (tx flow controlled) queue. 802.3 packets are transferred
+ * between queue and ring. A packet from the host stack is first added to the queue, and in a later
+ * stage transferred to the flow ring. Packets in the queue are dhd owned, whereas packets in the
+ * flow ring are device owned.
+ */
+typedef struct flow_queue {
+	dll_t  list;                /* manage a flowring queue in a double linked list */
+	void * head;                /* first packet in the queue */
+	void * tail;                /* last packet in the queue */
+	uint16 len;                 /* number of packets in the queue */
+	uint16 max;                 /* maximum or min budget (used in cumm) */
+	uint32 threshold;           /* parent's cummulative length threshold */
+	void * clen_ptr;            /* parent's cummulative length counter */
+	uint32 failures;            /* enqueue failures due to queue overflow */
+	flow_queue_cb_t cb;         /* callback invoked on threshold crossing */
+	uint32 l2threshold;         /* grandparent's (level 2) cummulative length threshold */
+	void * l2clen_ptr;          /* grandparent's (level 2) cummulative length counter */
+} flow_queue_t;
+
+#define DHD_FLOW_QUEUE_LEN(queue)       ((int)(queue)->len)
+#define DHD_FLOW_QUEUE_MAX(queue)       ((int)(queue)->max)
+#define DHD_FLOW_QUEUE_THRESHOLD(queue) ((int)(queue)->threshold)
+#define DHD_FLOW_QUEUE_L2THRESHOLD(queue) ((int)(queue)->l2threshold)
+#define DHD_FLOW_QUEUE_EMPTY(queue)     ((queue)->len == 0)
+#define DHD_FLOW_QUEUE_FAILURES(queue)  ((queue)->failures)
+
+#define DHD_FLOW_QUEUE_AVAIL(queue)     ((int)((queue)->max - (queue)->len))
+#define DHD_FLOW_QUEUE_FULL(queue)      ((queue)->len >= (queue)->max)
+
+#define DHD_FLOW_QUEUE_OVFL(queue, budget)  \
+	(((queue)->len) > budget)
+
+#define DHD_FLOW_QUEUE_SET_MAX(queue, budget) \
+	((queue)->max) = ((budget) - 1)
+
+/* Queue's cummulative threshold. */
+#define DHD_FLOW_QUEUE_SET_THRESHOLD(queue, cumm_threshold) \
+	((queue)->threshold) = ((cumm_threshold) - 1)
+
+/* Queue's cummulative length object accessor. */
+#define DHD_FLOW_QUEUE_CLEN_PTR(queue)  ((queue)->clen_ptr)
+
+/* Set a queue's cumm_len point to a parent's cumm_ctr_t cummulative length */
+#define DHD_FLOW_QUEUE_SET_CLEN(queue, parent_clen_ptr)  \
+	((queue)->clen_ptr) = (void *)(parent_clen_ptr)
+
+/* Queue's level 2 cummulative threshold. */
+#define DHD_FLOW_QUEUE_SET_L2THRESHOLD(queue, l2cumm_threshold) \
+	((queue)->l2threshold) = ((l2cumm_threshold) - 1)
+
+/* Queue's level 2 cummulative length object accessor. */
+#define DHD_FLOW_QUEUE_L2CLEN_PTR(queue)  ((queue)->l2clen_ptr)
+
+/* Set a queue's level 2 cumm_len point to a grandparent's cumm_ctr_t cummulative length */
+#define DHD_FLOW_QUEUE_SET_L2CLEN(queue, grandparent_clen_ptr)  \
+	((queue)->l2clen_ptr) = (void *)(grandparent_clen_ptr)
+
+#if defined(BCMDBG)
+#define DHD_FLOWRING_TXSTATUS_CNT_UPDATE(bus, flowid, txstatus) \
+		dhd_bus_flow_ring_cnt_update(bus, flowid, txstatus)
+#else
+#define DHD_FLOWRING_TXSTATUS_CNT_UPDATE(bus, flowid, txstatus)
+#endif /* BCMDBG */
+
+/* Pkttag not compatible with PROP_TXSTATUS or WLFC */
+typedef struct dhd_pkttag_fr {
+	uint16  flowid;
+	uint16  ifid;
+} dhd_pkttag_fr_t;
+
+#define DHD_PKTTAG_SET_IFID(tag, idx)       ((tag)->ifid = (uint16)(idx))
+#define DHD_PKTTAG_SET_PA(tag, pa)          ((tag)->physaddr = (pa))
+#define DHD_PKTTAG_SET_PA_LEN(tag, palen)   ((tag)->pa_len = (palen))
+#define DHD_PKTTAG_IFID(tag)                ((tag)->ifid)
+#define DHD_PKTTAG_PA(tag)                  ((tag)->physaddr)
+#define DHD_PKTTAG_PA_LEN(tag)              ((tag)->pa_len)
+
+/** each flow ring is dedicated to a tid/sa/da combination */
+typedef struct flow_info {
+	uint8		tid;
+	uint8		ifindex;
+	uchar		sa[ETHER_ADDR_LEN];
+	uchar		da[ETHER_ADDR_LEN];
+#if defined(BCMDBG)
+	uint32		tx_status[DHD_MAX_TX_STATUS_MSGS];
+#endif
+#ifdef TX_STATUS_LATENCY_STATS
+	/* total number of tx_status received on this flowid */
+	uint64           num_tx_status;
+	/* cumulative tx_status latency for this flowid */
+	uint64          cum_tx_status_latency;
+	/* num tx packets sent on this flowring */
+	uint64		num_tx_pkts;
+#endif /* TX_STATUS_LATENCY_STATS */
+} flow_info_t;
+
+/** a flow ring is used for outbound (towards antenna) 802.3 packets */
+typedef struct flow_ring_node {
+	dll_t		list;  /* manage a constructed flowring in a dll, must be at first place */
+	flow_queue_t	queue; /* queues packets before they enter the flow ring, flow control */
+	bool		active;
+	uint8		status;
+	/*
+	 * flowid: unique ID of a flow ring, which can either be unicast or broadcast/multicast. For
+	 * unicast flow rings, the flow id accelerates ARM 802.3->802.11 header translation.
+	 */
+	uint16		flowid;
+	flow_info_t	flow_info;
+	void		*prot_info;
+	void		*lock; /* lock for flowring access protection */
+
+#ifdef IDLE_TX_FLOW_MGMT
+	uint64		last_active_ts; /* contains last active timestamp */
+#endif /* IDLE_TX_FLOW_MGMT */
+#ifdef DEVICE_TX_STUCK_DETECT
+	/* Time stamp(msec) when last time a Tx packet completion is received on this flow ring */
+	uint32		tx_cmpl;
+	/*
+	 * Holds the tx_cmpl which was read during the previous
+	 * iteration of the stuck detection algo
+	 */
+	uint32		tx_cmpl_prev;
+	/* counter to decide if this particlur flow is stuck or not */
+	uint32		stuck_count;
+#endif /* DEVICE_TX_STUCK_DETECT */
+} flow_ring_node_t;
+
+typedef flow_ring_node_t flow_ring_table_t;
+
+typedef struct flow_hash_info {
+	uint16			flowid;
+	flow_info_t		flow_info;
+	struct flow_hash_info	*next;
+} flow_hash_info_t;
+
+typedef struct if_flow_lkup {
+	bool		status;
+	uint8		role; /* Interface role: STA/AP */
+	flow_hash_info_t *fl_hash[DHD_FLOWRING_HASH_SIZE]; /* Lkup Hash table */
+} if_flow_lkup_t;
+
+static INLINE flow_ring_node_t *
+dhd_constlist_to_flowring(dll_t *item)
+{
+	return ((flow_ring_node_t *)item);
+}
+
+/* Exported API */
+
+/* Flow ring's queue management functions */
+extern flow_ring_node_t * dhd_flow_ring_node(dhd_pub_t *dhdp, uint16 flowid);
+extern flow_queue_t * dhd_flow_queue(dhd_pub_t *dhdp, uint16 flowid);
+
+extern void dhd_flow_queue_init(dhd_pub_t *dhdp, flow_queue_t *queue, int max);
+extern void dhd_flow_queue_reinit(dhd_pub_t *dhdp, flow_queue_t *queue, int max);
+extern void dhd_flow_queue_register(flow_queue_t *queue, flow_queue_cb_t cb);
+extern int  dhd_flow_queue_enqueue(dhd_pub_t *dhdp, flow_queue_t *queue, void *pkt);
+extern int  dhd_flow_queue_enqueue_head(dhd_pub_t *dhdp, flow_queue_t *queue, void *pkt);
+extern void * dhd_flow_queue_dequeue(dhd_pub_t *dhdp, flow_queue_t *queue);
+extern void dhd_flow_queue_reinsert(dhd_pub_t *dhdp, flow_queue_t *queue, void *pkt);
+
+extern void dhd_flow_ring_config_thresholds(dhd_pub_t *dhdp, uint16 flowid,
+                          int queue_budget, int cumm_threshold, void *cumm_ctr,
+                          int l2cumm_threshold, void *l2cumm_ctr);
+extern int  dhd_flow_rings_init(dhd_pub_t *dhdp, uint32 num_h2d_rings);
+
+extern void dhd_flow_rings_deinit(dhd_pub_t *dhdp);
+
+extern int dhd_flowid_update(dhd_pub_t *dhdp, uint8 ifindex, uint8 prio,
+                void *pktbuf);
+extern int dhd_flowid_debug_create(dhd_pub_t *dhdp, uint8 ifindex,
+	uint8 prio, char *sa, char *da, uint16 *flowid);
+extern int dhd_flowid_find_by_ifidx(dhd_pub_t *dhdp, uint8 ifidex, uint16 flowid);
+
+extern void dhd_flowid_free(dhd_pub_t *dhdp, uint8 ifindex, uint16 flowid);
+
+extern void dhd_flow_rings_delete(dhd_pub_t *dhdp, uint8 ifindex);
+extern void dhd_update_multicilent_flow_rings(dhd_pub_t *dhdp, uint8 ifindex,
+	bool increment);
+extern void dhd_flow_rings_flush(dhd_pub_t *dhdp, uint8 ifindex);
+
+extern void dhd_flow_rings_delete_for_peer(dhd_pub_t *dhdp, uint8 ifindex,
+                char *addr);
+
+/* Handle Interface ADD, DEL operations */
+extern void dhd_update_interface_flow_info(dhd_pub_t *dhdp, uint8 ifindex,
+                uint8 op, uint8 role);
+
+/* Handle a STA interface link status update */
+extern int dhd_update_interface_link_status(dhd_pub_t *dhdp, uint8 ifindex,
+                uint8 status);
+extern int dhd_flow_prio_map(dhd_pub_t *dhd, uint8 *map, bool set);
+extern int dhd_update_flow_prio_map(dhd_pub_t *dhdp, uint8 map);
+extern uint32 dhd_active_tx_flowring_bkpq_len(dhd_pub_t *dhdp);
+extern uint8 dhd_flow_rings_ifindex2role(dhd_pub_t *dhdp, uint8 ifindex);
+#endif /* _dhd_flowrings_h_ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_gpio.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_gpio.c
@@ -0,0 +1,551 @@
+
+#include <osl.h>
+#include <dhd_linux.h>
+#include <linux/gpio.h>
+#ifdef BCMDHD_DTS
+#include <linux/of_gpio.h>
+#endif
+#ifdef BCMDHD_PLATDEV
+#include <linux/platform_device.h>
+#endif
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/crypto.h>
+#include <linux/scatterlist.h>
+#include <linux/uaccess.h>
+#include <crypto/hash.h>
+#include <crypto/kpp.h>
+#include <crypto/dh.h>
+#include <crypto/kdf_sp800108.h>
+#include <linux/string.h>
+#include <linux/skbuff.h>
+
+#ifdef BCMDHD_DTS
+/* This is sample code in dts file.
+bcmdhd_wlan {
+	compatible = "android,bcmdhd_wlan";
+	gpio_wl_reg_on = <&gpio GPIOH_4 GPIO_ACTIVE_HIGH>;
+	gpio_wl_host_wake = <&gpio GPIOZ_15 GPIO_ACTIVE_HIGH>;
+};
+*/
+#define DHD_DT_COMPAT_ENTRY		"linux,bcmdhd_wlan"
+#define GPIO_WL_REG_ON_PROPNAME		"gpio_wl_reg_on" ADAPTER_IDX_STR
+#define GPIO_WL_HOST_WAKE_PROPNAME	"gpio_wl_host_wake" ADAPTER_IDX_STR
+#endif
+#define GPIO_WL_REG_ON_NAME 	"WL_REG_ON" ADAPTER_IDX_STR
+#define GPIO_WL_HOST_WAKE_NAME	"WL_HOST_WAKE" ADAPTER_IDX_STR
+
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+#if defined(BCMDHD_MDRIVER) && !defined(DHD_STATIC_IN_DRIVER)
+extern void *dhd_wlan_mem_prealloc(uint bus_type, int index,
+	int section, unsigned long size);
+#else
+extern void *dhd_wlan_mem_prealloc(int section, unsigned long size);
+#endif
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+
+#if defined(BCMPCIE) && defined(PCIE_ATU_FIXUP)
+extern void pcie_power_on_atu_fixup(void);
+#endif
+
+#define CONFIG_TXT "/usr/lib/firmware/config.txt"
+#define NVRAM_TXT "/usr/lib/firmware/nvram.txt"
+#define SHA256_HASH_SIZE 32
+
+const unsigned char sha256_config[] = {
+    0xbb, 0x35, 0xf2, 0xeb, 0x32, 0x81, 0x59, 0x7b,
+    0x28, 0x43, 0x1b, 0x04, 0xc1, 0xc7, 0xf2, 0xbc,
+    0x22, 0x38, 0xbb, 0x0d, 0xa7, 0xfc, 0xd6, 0x89,
+    0x5b, 0xec, 0x47, 0x8e, 0x56, 0x6f, 0x5b, 0xf6
+};
+
+const unsigned char sha256_nvram[] = {
+    0x58, 0x84, 0x30, 0xb4, 0xc2, 0xc1, 0x67, 0xca,
+    0x03, 0x5f, 0x17, 0xda, 0x74, 0x78, 0xbe, 0xc3,
+    0xd4, 0x92, 0x24, 0x87, 0x15, 0x26, 0x10, 0xd3,
+    0x85, 0xd5, 0xcc, 0xb8, 0xf7, 0xc0, 0xa7, 0x5f
+};
+
+static long calculate_sha256(const char *filename, unsigned char *output) {
+
+    struct file *file;
+    struct shash_desc *sdesc;
+    struct crypto_shash *tfm;
+    unsigned char *buffer;
+    size_t len;
+    long rc;
+
+    file = filp_open(filename, O_RDONLY, 0);
+    if (IS_ERR(file)) {
+        pr_err("Failed to open file: %ld\n", PTR_ERR(file));
+        return PTR_ERR(file);
+    }
+
+    buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+    if (!buffer) {
+        filp_close(file, NULL);
+        return -ENOMEM;
+    }
+
+    len = kernel_read(file, buffer, PAGE_SIZE, &file->f_pos);
+    if (len < 0) {
+        pr_err("Failed to read file: %ld\n", len);
+        kfree(buffer);
+        filp_close(file, NULL);
+        return len;
+    }
+
+    tfm = crypto_alloc_shash("sha256", 0, 0);
+    if (IS_ERR(tfm)) {
+        pr_err("Failed to allocate SHA256 hash context\n");
+        kfree(buffer);
+        filp_close(file, NULL);
+        return PTR_ERR(tfm);
+    }
+
+    sdesc = kmalloc(sizeof(*sdesc) + crypto_shash_descsize(tfm), GFP_KERNEL);
+    if (!sdesc) {
+        pr_err("Failed to allocate shash_desc\n");
+        crypto_free_shash(tfm);
+        kfree(buffer);
+        filp_close(file, NULL);
+        return -ENOMEM;
+    }
+
+    sdesc->tfm = tfm;
+
+    rc = crypto_shash_init(sdesc);
+    if (rc) {
+        pr_err("SHA256 init failed\n");
+        kfree(sdesc);
+        crypto_free_shash(tfm);
+        kfree(buffer);
+        filp_close(file, NULL);
+        return rc;
+    }
+
+    rc = crypto_shash_update(sdesc, buffer, len);
+    if (rc) {
+        pr_err("SHA256 update failed\n");
+        kfree(sdesc);
+        crypto_free_shash(tfm);
+        kfree(buffer);
+        filp_close(file, NULL);
+        return rc;
+    }
+
+    rc = crypto_shash_final(sdesc, output);
+    if (rc) {
+        pr_err("SHA256 final failed\n");
+    }
+
+    kfree(sdesc);
+    crypto_free_shash(tfm);
+    kfree(buffer);
+    filp_close(file, NULL);
+    return rc;
+}
+
+static int
+dhd_wlan_set_power(wifi_adapter_info_t *adapter, int on)
+{
+	int gpio_wl_reg_on = adapter->gpio_wl_reg_on;
+	int err = 0;
+
+	if (on) {
+		printf("======== PULL WL_REG_ON(%d) HIGH! ========\n", gpio_wl_reg_on);
+		if (gpio_wl_reg_on >= 0) {
+			err = gpio_direction_output(gpio_wl_reg_on, 1);
+			if (err) {
+				printf("%s: WL_REG_ON didn't output high\n", __FUNCTION__);
+				return -EIO;
+			}
+		}
+#if defined(BCMPCIE) && defined(PCIE_ATU_FIXUP)
+		mdelay(100);
+		pcie_power_on_atu_fixup();
+#endif
+#ifdef BUS_POWER_RESTORE
+#ifdef BCMPCIE
+		if (adapter->pci_dev) {
+			mdelay(100);
+			printf("======== pci_set_power_state PCI_D0! ========\n");
+			pci_set_power_state(adapter->pci_dev, PCI_D0);
+			if (adapter->pci_saved_state)
+				pci_load_and_free_saved_state(adapter->pci_dev, &adapter->pci_saved_state);
+			pci_restore_state(adapter->pci_dev);
+			err = pci_enable_device(adapter->pci_dev);
+			if (err < 0)
+				printf("%s: PCI enable device failed", __FUNCTION__);
+			pci_set_master(adapter->pci_dev);
+		}
+#endif /* BCMPCIE */
+#endif /* BUS_POWER_RESTORE */
+		/* Lets customer power to get stable */
+	} else {
+#ifdef BUS_POWER_RESTORE
+#ifdef BCMPCIE
+		if (adapter->pci_dev) {
+			printf("======== pci_set_power_state PCI_D3hot! ========\n");
+			pci_save_state(adapter->pci_dev);
+			adapter->pci_saved_state = pci_store_saved_state(adapter->pci_dev);
+			if (pci_is_enabled(adapter->pci_dev))
+				pci_disable_device(adapter->pci_dev);
+			pci_set_power_state(adapter->pci_dev, PCI_D3hot);
+		}
+#endif /* BCMPCIE */
+#endif /* BUS_POWER_RESTORE */
+		printf("======== PULL WL_REG_ON(%d) LOW! ========\n", gpio_wl_reg_on);
+		if (gpio_wl_reg_on >= 0) {
+			err = gpio_direction_output(gpio_wl_reg_on, 0);
+			if (err) {
+				printf("%s: WL_REG_ON didn't output low\n", __FUNCTION__);
+				return -EIO;
+			}
+		}
+	}
+
+	return err;
+}
+
+static int
+dhd_wlan_set_reset(int onoff)
+{
+	return 0;
+}
+
+static int
+dhd_wlan_set_carddetect(wifi_adapter_info_t *adapter, int present)
+{
+	int err = 0;
+
+	if (present) {
+#if defined(BCMSDIO)
+		printf("======== Card detection to detect SDIO card! ========\n");
+#ifdef CUSTOMER_HW_PLATFORM
+		err = sdhci_force_presence_change(&sdmmc_channel, 1);
+#endif /* CUSTOMER_HW_PLATFORM */
+#elif defined(BCMPCIE)
+		printf("======== Card detection to detect PCIE card! ========\n");
+#endif
+	} else {
+#if defined(BCMSDIO)
+		printf("======== Card detection to remove SDIO card! ========\n");
+#ifdef CUSTOMER_HW_PLATFORM
+		err = sdhci_force_presence_change(&sdmmc_channel, 0);
+#endif /* CUSTOMER_HW_PLATFORM */
+#elif defined(BCMPCIE)
+		printf("======== Card detection to remove PCIE card! ========\n");
+#endif
+	}
+
+	return err;
+}
+
+static int
+dhd_wlan_get_mac_addr(wifi_adapter_info_t *adapter,
+	unsigned char *buf, int ifidx)
+{
+	int err = -1;
+
+	if (ifidx == 0) {
+		/* Here is for wlan0 MAC address and please enable CONFIG_BCMDHD_CUSTOM_MAC in Makefile */
+#ifdef EXAMPLE_GET_MAC
+		struct ether_addr ea_example = {{0x00, 0x11, 0x22, 0x33, 0x44, 0xFF}};
+		bcopy((char *)&ea_example, buf, sizeof(struct ether_addr));
+#endif /* EXAMPLE_GET_MAC */
+	}
+	else if (ifidx == 1) {
+		/* Here is for wlan1 MAC address and please enable CUSTOM_MULTI_MAC in Makefile */
+#ifdef EXAMPLE_GET_MAC
+		struct ether_addr ea_example = {{0x02, 0x11, 0x22, 0x33, 0x44, 0x55}};
+		bcopy((char *)&ea_example, buf, sizeof(struct ether_addr));
+#endif /* EXAMPLE_GET_MAC */
+	}
+	else {
+		printf("%s: invalid ifidx=%d\n", __FUNCTION__, ifidx);
+	}
+
+	printf("======== %s err=%d ========\n", __FUNCTION__, err);
+
+	return err;
+}
+
+static struct cntry_locales_custom brcm_wlan_translate_custom_table[] = {
+	/* Table should be filled out based on custom platform regulatory requirement */
+#ifdef EXAMPLE_TABLE
+	{"",   "XT", 49},  /* Universal if Country code is unknown or empty */
+	{"US", "US", 0},
+#endif /* EXMAPLE_TABLE */
+};
+
+#ifdef CUSTOM_FORCE_NODFS_FLAG
+struct cntry_locales_custom brcm_wlan_translate_nodfs_table[] = {
+#ifdef EXAMPLE_TABLE
+	{"",   "XT", 50},  /* Universal if Country code is unknown or empty */
+	{"US", "US", 0},
+#endif /* EXMAPLE_TABLE */
+};
+#endif
+
+static void *dhd_wlan_get_country_code(char *ccode
+#ifdef CUSTOM_FORCE_NODFS_FLAG
+	, u32 flags
+#endif
+)
+{
+	struct cntry_locales_custom *locales;
+	int size;
+	int i;
+
+	if (!ccode)
+		return NULL;
+
+#ifdef CUSTOM_FORCE_NODFS_FLAG
+	if (flags & WLAN_PLAT_NODFS_FLAG) {
+		locales = brcm_wlan_translate_nodfs_table;
+		size = ARRAY_SIZE(brcm_wlan_translate_nodfs_table);
+	} else {
+#endif
+		locales = brcm_wlan_translate_custom_table;
+		size = ARRAY_SIZE(brcm_wlan_translate_custom_table);
+#ifdef CUSTOM_FORCE_NODFS_FLAG
+	}
+#endif
+
+	for (i = 0; i < size; i++)
+		if (strcmp(ccode, locales[i].iso_abbrev) == 0)
+			return &locales[i];
+	return NULL;
+}
+
+struct wifi_platform_data dhd_wlan_control = {
+	.set_power	= dhd_wlan_set_power,
+	.set_reset	= dhd_wlan_set_reset,
+	.set_carddetect	= dhd_wlan_set_carddetect,
+	.get_mac_addr	= dhd_wlan_get_mac_addr,
+#ifdef CONFIG_DHD_USE_STATIC_BUF
+	.mem_prealloc	= dhd_wlan_mem_prealloc,
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+	.get_country_code = dhd_wlan_get_country_code,
+};
+
+static int
+dhd_wlan_init_gpio(wifi_adapter_info_t *adapter)
+{
+
+	unsigned char sha256_config_out[SHA256_HASH_SIZE];
+	unsigned char sha256_nvram_out[SHA256_HASH_SIZE];
+
+	if (calculate_sha256(CONFIG_TXT, sha256_config_out) != 0) {
+		return -EFAULT;
+	}
+
+	if (memcmp(sha256_config_out, sha256_config, sizeof(sha256_config_out)) != 0) {
+		return -EFAULT;
+	}
+
+	if (calculate_sha256(NVRAM_TXT, sha256_nvram_out) != 0) {
+		return -EFAULT;
+	}
+
+	if (memcmp(sha256_nvram_out, sha256_nvram, sizeof(sha256_nvram_out)) != 0) {
+		return -EFAULT;
+	}
+
+#ifdef BCMDHD_DTS
+	char wlan_node[32];
+	struct device_node *root_node = NULL;
+#endif
+	int err = 0;
+	int gpio_wl_reg_on = -1;
+#ifdef CUSTOMER_OOB
+	int gpio_wl_host_wake = -1;
+	int host_oob_irq = -1;
+	uint host_oob_irq_flags = 0;
+#endif
+
+	/* Please check your schematic and fill right GPIO number which connected to
+	* WL_REG_ON and WL_HOST_WAKE.
+	*/
+#ifdef BCMDHD_DTS
+#ifdef BCMDHD_PLATDEV
+	if (adapter->pdev) {
+		root_node = adapter->pdev->dev.of_node;
+		strcpy(wlan_node, root_node->name);
+	} else {
+		printf("%s: adapter->pdev is NULL\n", __FUNCTION__);
+		return -1;
+	}
+#else
+	strcpy(wlan_node, DHD_DT_COMPAT_ENTRY);
+	root_node = of_find_compatible_node(NULL, NULL, wlan_node);
+#endif
+	printf("======== Get GPIO from DTS(%s) ========\n", wlan_node);
+	if (root_node) {
+		gpio_wl_reg_on = of_get_named_gpio(root_node, GPIO_WL_REG_ON_PROPNAME, 0);
+#ifdef CUSTOMER_OOB
+		gpio_wl_host_wake = of_get_named_gpio(root_node, GPIO_WL_HOST_WAKE_PROPNAME, 0);
+#endif
+	} else
+#endif
+	{
+		gpio_wl_reg_on = -1;
+#ifdef CUSTOMER_OOB
+		gpio_wl_host_wake = -1;
+#endif
+	}
+
+	if (gpio_wl_reg_on >= 0) {
+		err = gpio_request(gpio_wl_reg_on, GPIO_WL_REG_ON_NAME);
+		if (err < 0) {
+			printf("%s: gpio_request(%d) for WL_REG_ON failed %d\n",
+				__FUNCTION__, gpio_wl_reg_on, err);
+			gpio_wl_reg_on = -1;
+		}
+#if defined(BCMPCIE) && defined(PCIE_ATU_FIXUP)
+		printf("======== PULL WL_REG_ON(%d) HIGH! ========\n", gpio_wl_reg_on);
+		err = gpio_direction_output(gpio_wl_reg_on, 1);
+		if (err) {
+			printf("%s: WL_REG_ON didn't output high\n", __FUNCTION__);
+			gpio_wl_reg_on = -1;
+		} else {
+			OSL_SLEEP(WIFI_TURNON_DELAY);
+		}
+		pcie_power_on_atu_fixup();
+#endif
+	}
+	adapter->gpio_wl_reg_on = gpio_wl_reg_on;
+
+#ifdef CUSTOMER_OOB
+	adapter->gpio_wl_host_wake = -1;
+	if (gpio_wl_host_wake >= 0) {
+		err = gpio_request(gpio_wl_host_wake, GPIO_WL_HOST_WAKE_NAME);
+		if (err < 0) {
+			printf("%s: gpio_request(%d) for WL_HOST_WAKE failed %d\n",
+				__FUNCTION__, gpio_wl_host_wake, err);
+			return -1;
+		}
+		adapter->gpio_wl_host_wake = gpio_wl_host_wake;
+		err = gpio_direction_input(gpio_wl_host_wake);
+		if (err < 0) {
+			printf("%s: gpio_direction_input(%d) for WL_HOST_WAKE failed %d\n",
+				__FUNCTION__, gpio_wl_host_wake, err);
+			gpio_free(gpio_wl_host_wake);
+			return -1;
+		}
+		host_oob_irq = gpio_to_irq(gpio_wl_host_wake);
+		if (host_oob_irq < 0) {
+			printf("%s: gpio_to_irq(%d) for WL_HOST_WAKE failed %d\n",
+				__FUNCTION__, gpio_wl_host_wake, host_oob_irq);
+			gpio_free(gpio_wl_host_wake);
+			return -1;
+		}
+	}
+
+#ifdef HW_OOB
+#ifdef HW_OOB_LOW_LEVEL
+	host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_SHAREABLE;
+#else
+	host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE;
+#endif
+#else
+	host_oob_irq_flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_SHAREABLE;
+#endif
+	host_oob_irq_flags &= IRQF_TRIGGER_MASK;
+
+	adapter->irq_num = host_oob_irq;
+	adapter->intr_flags = host_oob_irq_flags;
+	printf("%s: WL_HOST_WAKE=%d, oob_irq=%d, oob_irq_flags=0x%x\n", __FUNCTION__,
+		gpio_wl_host_wake, host_oob_irq, host_oob_irq_flags);
+#endif /* CUSTOMER_OOB */
+	printf("%s: WL_REG_ON=%d\n", __FUNCTION__, gpio_wl_reg_on);
+
+	return 0;
+}
+
+static void
+dhd_wlan_deinit_gpio(wifi_adapter_info_t *adapter)
+{
+	int gpio_wl_reg_on = adapter->gpio_wl_reg_on;
+#ifdef CUSTOMER_OOB
+	int gpio_wl_host_wake = adapter->gpio_wl_host_wake;
+#endif
+
+	if (gpio_wl_reg_on >= 0) {
+		printf("%s: gpio_free(WL_REG_ON %d)\n", __FUNCTION__, gpio_wl_reg_on);
+		gpio_free(gpio_wl_reg_on);
+		adapter->gpio_wl_reg_on = -1;
+	}
+#ifdef CUSTOMER_OOB
+	if (gpio_wl_host_wake >= 0) {
+		printf("%s: gpio_free(WL_HOST_WAKE %d)\n", __FUNCTION__, gpio_wl_host_wake);
+		gpio_free(gpio_wl_host_wake);
+		adapter->gpio_wl_host_wake = -1;
+	}
+#endif /* CUSTOMER_OOB */
+}
+
+#if defined(BCMDHD_MDRIVER)
+static void
+dhd_wlan_init_adapter(wifi_adapter_info_t *adapter)
+{
+#ifdef ADAPTER_IDX
+	adapter->index = ADAPTER_IDX;
+	if (adapter->index == 0) {
+		adapter->bus_num = 1;
+		adapter->slot_num = 1;
+	} else if (adapter->index == 1) {
+		adapter->bus_num = 2;
+		adapter->slot_num = 1;
+	}
+#ifdef BCMSDIO
+	adapter->bus_type = SDIO_BUS;
+#elif defined(BCMPCIE)
+	adapter->bus_type = PCI_BUS;
+#elif defined(BCMDBUS)
+	adapter->bus_type = USB_BUS;
+#endif
+	printf("bus_type=%d, bus_num=%d, slot_num=%d\n",
+		adapter->bus_type, adapter->bus_num, adapter->slot_num);
+#endif /* ADAPTER_IDX */
+
+#ifdef DHD_STATIC_IN_DRIVER
+	adapter->index = 0;
+#elif !defined(ADAPTER_IDX)
+#ifdef BCMSDIO
+	adapter->index = 0;
+#elif defined(BCMPCIE)
+	adapter->index = 1;
+#elif defined(BCMDBUS)
+	adapter->index = 2;
+#endif
+#endif /* DHD_STATIC_IN_DRIVER */
+}
+#endif /* BCMDHD_MDRIVER */
+
+int
+dhd_wlan_init_plat_data(wifi_adapter_info_t *adapter)
+{
+	int err = 0;
+
+#ifdef BCMDHD_MDRIVER
+	dhd_wlan_init_adapter(adapter);
+#endif /* BCMDHD_MDRIVER */
+
+	err = dhd_wlan_init_gpio(adapter);
+	if (err)
+		goto exit;
+
+exit:
+	return err;
+}
+
+void
+dhd_wlan_deinit_plat_data(wifi_adapter_info_t *adapter)
+{
+	dhd_wlan_deinit_gpio(adapter);
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_ip.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_ip.c
@@ -0,0 +1,1455 @@
+/*
+ * IP Packet Parser Module.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+#include <typedefs.h>
+#include <osl.h>
+
+#include <ethernet.h>
+#include <vlan.h>
+#include <802.3.h>
+#include <bcmip.h>
+#include <bcmendian.h>
+
+#include <dhd.h>
+#include <dhd_dbg.h>
+
+#include <dhd_ip.h>
+#include <dhd_config.h>
+
+#if defined(DHDTCPACK_SUPPRESS) || defined(DHDTCPSYNC_FLOOD_BLK)
+#include <dhd_bus.h>
+#include <dhd_proto.h>
+#include <bcmtcp.h>
+#endif /* DHDTCPACK_SUPPRESS || DHDTCPSYNC_FLOOD_BLK */
+
+/* special values */
+/* 802.3 llc/snap header */
+static const uint8 llc_snap_hdr[SNAP_HDR_LEN] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+
+pkt_frag_t pkt_frag_info(osl_t *osh, void *p)
+{
+	uint8 *frame;
+	int length;
+	uint8 *pt;			/* Pointer to type field */
+	uint16 ethertype;
+	struct ipv4_hdr *iph;		/* IP frame pointer */
+	int ipl;			/* IP frame length */
+	uint16 iph_frag;
+
+	ASSERT(osh && p);
+
+	frame = PKTDATA(osh, p);
+	length = PKTLEN(osh, p);
+
+	/* Process Ethernet II or SNAP-encapsulated 802.3 frames */
+	if (length < ETHER_HDR_LEN) {
+		DHD_INFO(("%s: short eth frame (%d)\n", __FUNCTION__, length));
+		return DHD_PKT_FRAG_NONE;
+	} else if (ntoh16(*(uint16 *)(frame + ETHER_TYPE_OFFSET)) >= ETHER_TYPE_MIN) {
+		/* Frame is Ethernet II */
+		pt = frame + ETHER_TYPE_OFFSET;
+	} else if (length >= ETHER_HDR_LEN + SNAP_HDR_LEN + ETHER_TYPE_LEN &&
+	           !bcmp(llc_snap_hdr, frame + ETHER_HDR_LEN, SNAP_HDR_LEN)) {
+		pt = frame + ETHER_HDR_LEN + SNAP_HDR_LEN;
+	} else {
+		DHD_INFO(("%s: non-SNAP 802.3 frame\n", __FUNCTION__));
+		return DHD_PKT_FRAG_NONE;
+	}
+
+	ethertype = ntoh16(*(uint16 *)pt);
+
+	/* Skip VLAN tag, if any */
+	if (ethertype == ETHER_TYPE_8021Q) {
+		pt += VLAN_TAG_LEN;
+
+		if (pt + ETHER_TYPE_LEN > frame + length) {
+			DHD_INFO(("%s: short VLAN frame (%d)\n", __FUNCTION__, length));
+			return DHD_PKT_FRAG_NONE;
+		}
+
+		ethertype = ntoh16(*(uint16 *)pt);
+	}
+
+	if (ethertype != ETHER_TYPE_IP) {
+		DHD_INFO(("%s: non-IP frame (ethertype 0x%x, length %d)\n",
+			__FUNCTION__, ethertype, length));
+		return DHD_PKT_FRAG_NONE;
+	}
+
+	iph = (struct ipv4_hdr *)(pt + ETHER_TYPE_LEN);
+	ipl = (uint)(length - (pt + ETHER_TYPE_LEN - frame));
+
+	/* We support IPv4 only */
+	if ((ipl < IPV4_OPTIONS_OFFSET) || (IP_VER(iph) != IP_VER_4)) {
+		DHD_INFO(("%s: short frame (%d) or non-IPv4\n", __FUNCTION__, ipl));
+		return DHD_PKT_FRAG_NONE;
+	}
+
+	iph_frag = ntoh16(iph->frag);
+
+	if (iph_frag & IPV4_FRAG_DONT) {
+		return DHD_PKT_FRAG_NONE;
+	} else if ((iph_frag & IPV4_FRAG_MORE) == 0) {
+		return DHD_PKT_FRAG_LAST;
+	} else {
+		return (iph_frag & IPV4_FRAG_OFFSET_MASK)? DHD_PKT_FRAG_CONT : DHD_PKT_FRAG_FIRST;
+	}
+}
+
+#ifdef DHDTCPACK_SUPPRESS
+
+typedef struct {
+	void *pkt_in_q;		/* TCP ACK packet that is already in txq or DelayQ */
+	void *pkt_ether_hdr;	/* Ethernet header pointer of pkt_in_q */
+	int ifidx;
+	uint8 supp_cnt;
+	dhd_pub_t *dhdp;
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
+	timer_list_compat_t timer;
+#else
+	struct tasklet_hrtimer timer;
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
+} tcpack_info_t;
+
+typedef struct _tdata_psh_info_t {
+	uint32 end_seq;			/* end seq# of a received TCP PSH DATA pkt */
+	struct _tdata_psh_info_t *next;	/* next pointer of the link chain */
+} tdata_psh_info_t;
+
+typedef struct {
+	struct {
+		uint8 src[IPV4_ADDR_LEN];	/* SRC ip addrs of this TCP stream */
+		uint8 dst[IPV4_ADDR_LEN];	/* DST ip addrs of this TCP stream */
+	} ip_addr;
+	struct {
+		uint8 src[TCP_PORT_LEN];	/* SRC tcp ports of this TCP stream */
+		uint8 dst[TCP_PORT_LEN];	/* DST tcp ports of this TCP stream */
+	} tcp_port;
+	tdata_psh_info_t *tdata_psh_info_head;	/* Head of received TCP PSH DATA chain */
+	tdata_psh_info_t *tdata_psh_info_tail;	/* Tail of received TCP PSH DATA chain */
+	uint32 last_used_time;	/* The last time this tcpdata_info was used(in ms) */
+} tcpdata_info_t;
+
+/* TCPACK SUPPRESS module */
+typedef struct {
+	int tcpack_info_cnt;
+	tcpack_info_t tcpack_info_tbl[TCPACK_INFO_MAXNUM];	/* Info of TCP ACK to send */
+	int tcpdata_info_cnt;
+	tcpdata_info_t tcpdata_info_tbl[TCPDATA_INFO_MAXNUM];	/* Info of received TCP DATA */
+	tdata_psh_info_t *tdata_psh_info_pool;	/* Pointer to tdata_psh_info elements pool */
+	tdata_psh_info_t *tdata_psh_info_free;	/* free tdata_psh_info elements chain in pool */
+#ifdef DHDTCPACK_SUP_DBG
+	int psh_info_enq_num;	/* Number of free TCP PSH DATA info elements in pool */
+#endif /* DHDTCPACK_SUP_DBG */
+} tcpack_sup_module_t;
+
+#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
+counter_tbl_t tack_tbl = {"tcpACK", 0, 1000, 10, {0, }, 1};
+#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
+
+static void
+_tdata_psh_info_pool_enq(tcpack_sup_module_t *tcpack_sup_mod,
+	tdata_psh_info_t *tdata_psh_info)
+{
+	if ((tcpack_sup_mod == NULL) || (tdata_psh_info == NULL)) {
+		DHD_ERROR(("%s %d: ERROR %p %p\n", __FUNCTION__, __LINE__,
+			tcpack_sup_mod, tdata_psh_info));
+		return;
+	}
+
+	ASSERT(tdata_psh_info->next == NULL);
+	tdata_psh_info->next = tcpack_sup_mod->tdata_psh_info_free;
+	tcpack_sup_mod->tdata_psh_info_free = tdata_psh_info;
+#ifdef DHDTCPACK_SUP_DBG
+	tcpack_sup_mod->psh_info_enq_num++;
+#endif
+}
+
+static tdata_psh_info_t*
+_tdata_psh_info_pool_deq(tcpack_sup_module_t *tcpack_sup_mod)
+{
+	tdata_psh_info_t *tdata_psh_info = NULL;
+
+	if (tcpack_sup_mod == NULL) {
+		DHD_ERROR(("%s %d: ERROR %p\n", __FUNCTION__, __LINE__,
+			tcpack_sup_mod));
+		return NULL;
+	}
+
+	tdata_psh_info = tcpack_sup_mod->tdata_psh_info_free;
+	if (tdata_psh_info == NULL)
+		DHD_ERROR(("%s %d: Out of tdata_disc_grp\n", __FUNCTION__, __LINE__));
+	else {
+		tcpack_sup_mod->tdata_psh_info_free = tdata_psh_info->next;
+		tdata_psh_info->next = NULL;
+#ifdef DHDTCPACK_SUP_DBG
+		tcpack_sup_mod->psh_info_enq_num--;
+#endif /* DHDTCPACK_SUP_DBG */
+	}
+
+	return tdata_psh_info;
+}
+
+#ifdef BCMSDIO
+static int _tdata_psh_info_pool_init(dhd_pub_t *dhdp,
+	tcpack_sup_module_t *tcpack_sup_mod)
+{
+	tdata_psh_info_t *tdata_psh_info_pool = NULL;
+	uint i;
+
+	DHD_TRACE(("%s %d: Enter\n", __FUNCTION__, __LINE__));
+
+	if (tcpack_sup_mod == NULL)
+		return BCME_ERROR;
+
+	ASSERT(tcpack_sup_mod->tdata_psh_info_pool == NULL);
+	ASSERT(tcpack_sup_mod->tdata_psh_info_free == NULL);
+
+	tdata_psh_info_pool =
+		MALLOC(dhdp->osh, sizeof(tdata_psh_info_t) * TCPDATA_PSH_INFO_MAXNUM);
+
+	if (tdata_psh_info_pool == NULL)
+		return BCME_NOMEM;
+	bzero(tdata_psh_info_pool, sizeof(tdata_psh_info_t) * TCPDATA_PSH_INFO_MAXNUM);
+#ifdef DHDTCPACK_SUP_DBG
+	tcpack_sup_mod->psh_info_enq_num = 0;
+#endif /* DHDTCPACK_SUP_DBG */
+
+	/* Enqueue newly allocated tcpdata psh info elements to the pool */
+	for (i = 0; i < TCPDATA_PSH_INFO_MAXNUM; i++)
+		_tdata_psh_info_pool_enq(tcpack_sup_mod, &tdata_psh_info_pool[i]);
+
+	ASSERT(tcpack_sup_mod->tdata_psh_info_free != NULL);
+	tcpack_sup_mod->tdata_psh_info_pool = tdata_psh_info_pool;
+
+	return BCME_OK;
+}
+
+static void _tdata_psh_info_pool_deinit(dhd_pub_t *dhdp,
+	tcpack_sup_module_t *tcpack_sup_mod)
+{
+	uint i;
+	tdata_psh_info_t *tdata_psh_info;
+
+	DHD_TRACE(("%s %d: Enter\n", __FUNCTION__, __LINE__));
+
+	if (tcpack_sup_mod == NULL) {
+		DHD_ERROR(("%s %d: ERROR tcpack_sup_mod NULL!\n",
+			__FUNCTION__, __LINE__));
+		return;
+	}
+
+	for (i = 0; i < tcpack_sup_mod->tcpdata_info_cnt; i++) {
+		tcpdata_info_t *tcpdata_info = &tcpack_sup_mod->tcpdata_info_tbl[i];
+		/* Return tdata_psh_info elements allocated to each tcpdata_info to the pool */
+		while ((tdata_psh_info = tcpdata_info->tdata_psh_info_head)) {
+			tcpdata_info->tdata_psh_info_head = tdata_psh_info->next;
+			tdata_psh_info->next = NULL;
+			_tdata_psh_info_pool_enq(tcpack_sup_mod, tdata_psh_info);
+		}
+		tcpdata_info->tdata_psh_info_tail = NULL;
+	}
+#ifdef DHDTCPACK_SUP_DBG
+	DHD_ERROR(("%s %d: PSH INFO ENQ %d\n",
+		__FUNCTION__, __LINE__, tcpack_sup_mod->psh_info_enq_num));
+#endif /* DHDTCPACK_SUP_DBG */
+
+	i = 0;
+	/* Be sure we recollected all tdata_psh_info elements */
+	while ((tdata_psh_info = tcpack_sup_mod->tdata_psh_info_free)) {
+		tcpack_sup_mod->tdata_psh_info_free = tdata_psh_info->next;
+		tdata_psh_info->next = NULL;
+		i++;
+	}
+	ASSERT(i == TCPDATA_PSH_INFO_MAXNUM);
+	MFREE(dhdp->osh, tcpack_sup_mod->tdata_psh_info_pool,
+		sizeof(tdata_psh_info_t) * TCPDATA_PSH_INFO_MAXNUM);
+
+	return;
+}
+#endif /* BCMSDIO */
+
+#ifdef BCMPCIE
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
+static void dhd_tcpack_send(ulong data)
+#else
+static enum hrtimer_restart dhd_tcpack_send(struct hrtimer *timer)
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
+{
+	tcpack_sup_module_t *tcpack_sup_mod;
+	tcpack_info_t *cur_tbl;
+	dhd_pub_t *dhdp;
+	int ifidx;
+	void* pkt;
+	unsigned long flags;
+
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
+	cur_tbl = (tcpack_info_t *)data;
+#else
+	cur_tbl = container_of(timer, tcpack_info_t, timer.timer);
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
+
+	if (!cur_tbl) {
+		goto done;
+	}
+
+	dhdp = cur_tbl->dhdp;
+	if (!dhdp) {
+		goto done;
+	}
+
+	flags = dhd_os_tcpacklock(dhdp);
+
+	if (unlikely(dhdp->tcpack_sup_mode != TCPACK_SUP_HOLD)) {
+		dhd_os_tcpackunlock(dhdp, flags);
+		goto done;
+	}
+
+	tcpack_sup_mod = dhdp->tcpack_sup_module;
+	if (!tcpack_sup_mod) {
+		DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n",
+			__FUNCTION__, __LINE__));
+		dhd_os_tcpackunlock(dhdp, flags);
+		goto done;
+	}
+	pkt = cur_tbl->pkt_in_q;
+	ifidx = cur_tbl->ifidx;
+	if (!pkt) {
+		dhd_os_tcpackunlock(dhdp, flags);
+		goto done;
+	}
+	cur_tbl->pkt_in_q = NULL;
+	cur_tbl->pkt_ether_hdr = NULL;
+	cur_tbl->ifidx = 0;
+	cur_tbl->supp_cnt = 0;
+	if (--tcpack_sup_mod->tcpack_info_cnt < 0) {
+		DHD_ERROR(("%s %d: ERROR!!! tcp_ack_info_cnt %d\n",
+			__FUNCTION__, __LINE__, tcpack_sup_mod->tcpack_info_cnt));
+	}
+
+	dhd_os_tcpackunlock(dhdp, flags);
+
+	dhd_sendpkt(dhdp, ifidx, pkt);
+
+done:
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
+	return;
+#else
+	return HRTIMER_NORESTART;
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
+}
+#endif /* BCMPCIE */
+
+int dhd_tcpack_suppress_set(dhd_pub_t *dhdp, uint8 mode)
+{
+	int ret = BCME_OK;
+	unsigned long flags;
+	tcpack_sup_module_t *tcpack_sup_module;
+	uint8 invalid_mode = FALSE;
+	int prev_mode;
+	int i = 0;
+
+	flags = dhd_os_tcpacklock(dhdp);
+	tcpack_sup_module = dhdp->tcpack_sup_module;
+	prev_mode = dhdp->tcpack_sup_mode;
+
+	if (prev_mode == mode) {
+		DHD_ERROR(("%s %d: already set to %d\n", __FUNCTION__, __LINE__, mode));
+		goto exit;
+	}
+
+	invalid_mode |= (mode >= TCPACK_SUP_LAST_MODE);
+#ifdef BCMSDIO
+	invalid_mode |= (mode == TCPACK_SUP_HOLD);
+#endif /* BCMSDIO */
+#ifdef BCMPCIE
+	invalid_mode |= ((mode == TCPACK_SUP_REPLACE) || (mode == TCPACK_SUP_DELAYTX));
+#endif /* BCMPCIE */
+
+	if (invalid_mode) {
+		DHD_ERROR(("%s %d: Invalid TCP ACK Suppress mode %d\n",
+			__FUNCTION__, __LINE__, mode));
+		ret = BCME_BADARG;
+		goto exit;
+	}
+
+	printf("%s: TCP ACK Suppress mode %d -> mode %d\n",
+		__FUNCTION__, dhdp->tcpack_sup_mode, mode);
+	printf("%s: TCPACK_INFO_MAXNUM=%d, TCPDATA_INFO_MAXNUM=%d\n",
+		__FUNCTION__, TCPACK_INFO_MAXNUM, TCPDATA_INFO_MAXNUM);
+
+	/* Pre-process routines to change a new mode as per previous mode */
+	switch (prev_mode) {
+		case TCPACK_SUP_OFF:
+			if (tcpack_sup_module == NULL) {
+				tcpack_sup_module = MALLOC(dhdp->osh, sizeof(tcpack_sup_module_t));
+				if (tcpack_sup_module == NULL) {
+					DHD_ERROR(("%s[%d]: Failed to allocate the new memory for "
+						"tcpack_sup_module\n", __FUNCTION__, __LINE__));
+					dhdp->tcpack_sup_mode = TCPACK_SUP_OFF;
+					ret = BCME_NOMEM;
+					goto exit;
+				}
+				dhdp->tcpack_sup_module = tcpack_sup_module;
+			}
+			bzero(tcpack_sup_module, sizeof(tcpack_sup_module_t));
+			break;
+#ifdef BCMSDIO
+		case TCPACK_SUP_DELAYTX:
+			if (tcpack_sup_module) {
+				/* We won't need tdata_psh_info pool and
+				 * tcpddata_info_tbl anymore
+				 */
+				_tdata_psh_info_pool_deinit(dhdp, tcpack_sup_module);
+				tcpack_sup_module->tcpdata_info_cnt = 0;
+				bzero(tcpack_sup_module->tcpdata_info_tbl,
+					sizeof(tcpdata_info_t) * TCPDATA_INFO_MAXNUM);
+			}
+
+			/* For half duplex bus interface, tx precedes rx by default */
+			if (dhdp->bus) {
+				dhd_bus_set_dotxinrx(dhdp->bus, TRUE);
+			}
+
+			if (tcpack_sup_module == NULL) {
+				DHD_ERROR(("%s[%d]: tcpack_sup_module should not be NULL\n",
+					__FUNCTION__, __LINE__));
+				dhdp->tcpack_sup_mode = TCPACK_SUP_OFF;
+				goto exit;
+			}
+			break;
+#endif /* BCMSDIO */
+	}
+
+	/* Update a new mode */
+	dhdp->tcpack_sup_mode = mode;
+
+	/* Process for a new mode */
+	switch (mode) {
+		case TCPACK_SUP_OFF:
+			ASSERT(tcpack_sup_module != NULL);
+			/* Clean up timer/data structure for
+			 * any remaining/pending packet or timer.
+			 */
+			if (tcpack_sup_module) {
+				/* Check if previous mode is TCAPACK_SUP_HOLD */
+				if (prev_mode == TCPACK_SUP_HOLD) {
+					for (i = 0; i < TCPACK_INFO_MAXNUM; i++) {
+						tcpack_info_t *tcpack_info_tbl =
+							&tcpack_sup_module->tcpack_info_tbl[i];
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
+						del_timer(&tcpack_info_tbl->timer);
+#else
+						hrtimer_cancel(&tcpack_info_tbl->timer.timer);
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
+						if (tcpack_info_tbl->pkt_in_q) {
+							PKTFREE(dhdp->osh,
+								tcpack_info_tbl->pkt_in_q, TRUE);
+							tcpack_info_tbl->pkt_in_q = NULL;
+						}
+					}
+				}
+				MFREE(dhdp->osh, tcpack_sup_module, sizeof(tcpack_sup_module_t));
+				dhdp->tcpack_sup_module = NULL;
+			} else {
+				DHD_ERROR(("%s[%d]: tcpack_sup_module should not be NULL\n",
+					__FUNCTION__, __LINE__));
+			}
+			break;
+#ifdef BCMSDIO
+		case TCPACK_SUP_REPLACE:
+			/* There is nothing to configure for this mode */
+			break;
+		case TCPACK_SUP_DELAYTX:
+			ret = _tdata_psh_info_pool_init(dhdp, tcpack_sup_module);
+			if (ret != BCME_OK) {
+				DHD_ERROR(("%s %d: pool init fail with %d\n",
+					__FUNCTION__, __LINE__, ret));
+				break;
+			}
+			if (dhdp->bus) {
+				dhd_bus_set_dotxinrx(dhdp->bus, FALSE);
+			}
+			break;
+#endif /* BCMSDIO */
+#ifdef BCMPCIE
+		case TCPACK_SUP_HOLD:
+			dhdp->tcpack_sup_ratio = dhdp->conf->tcpack_sup_ratio;
+			dhdp->tcpack_sup_delay = dhdp->conf->tcpack_sup_delay;
+			for (i = 0; i < TCPACK_INFO_MAXNUM; i++) {
+				tcpack_info_t *tcpack_info_tbl =
+					&tcpack_sup_module->tcpack_info_tbl[i];
+				tcpack_info_tbl->dhdp = dhdp;
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
+				init_timer_compat(&tcpack_info_tbl->timer, dhd_tcpack_send,
+					tcpack_info_tbl);
+#else
+				tasklet_hrtimer_init(&tcpack_info_tbl->timer,
+					dhd_tcpack_send, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
+			}
+			break;
+#endif /* BCMPCIE */
+	}
+
+exit:
+	dhd_os_tcpackunlock(dhdp, flags);
+	return ret;
+}
+
+void
+dhd_tcpack_info_tbl_clean(dhd_pub_t *dhdp)
+{
+	tcpack_sup_module_t *tcpack_sup_mod = dhdp->tcpack_sup_module;
+	int i;
+	unsigned long flags;
+
+	if (dhdp->tcpack_sup_mode == TCPACK_SUP_OFF)
+		goto exit;
+
+	flags = dhd_os_tcpacklock(dhdp);
+
+	if (!tcpack_sup_mod) {
+		DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n",
+			__FUNCTION__, __LINE__));
+		dhd_os_tcpackunlock(dhdp, flags);
+		goto exit;
+	}
+
+	if (dhdp->tcpack_sup_mode == TCPACK_SUP_HOLD) {
+		for (i = 0; i < TCPACK_INFO_MAXNUM; i++) {
+			if (tcpack_sup_mod->tcpack_info_tbl[i].pkt_in_q) {
+				PKTFREE(dhdp->osh, tcpack_sup_mod->tcpack_info_tbl[i].pkt_in_q,
+					TRUE);
+				tcpack_sup_mod->tcpack_info_tbl[i].pkt_in_q = NULL;
+				tcpack_sup_mod->tcpack_info_tbl[i].pkt_ether_hdr = NULL;
+				tcpack_sup_mod->tcpack_info_tbl[i].ifidx = 0;
+				tcpack_sup_mod->tcpack_info_tbl[i].supp_cnt = 0;
+			}
+		}
+	} else {
+		tcpack_sup_mod->tcpack_info_cnt = 0;
+		bzero(tcpack_sup_mod->tcpack_info_tbl, sizeof(tcpack_info_t) * TCPACK_INFO_MAXNUM);
+	}
+
+	dhd_os_tcpackunlock(dhdp, flags);
+
+	if (dhdp->tcpack_sup_mode == TCPACK_SUP_HOLD) {
+		for (i = 0; i < TCPACK_INFO_MAXNUM; i++) {
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
+			del_timer_sync(&tcpack_sup_mod->tcpack_info_tbl[i].timer);
+#else
+			hrtimer_cancel(&tcpack_sup_mod->tcpack_info_tbl[i].timer.timer);
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
+		}
+	}
+
+exit:
+	return;
+}
+
+inline int dhd_tcpack_check_xmit(dhd_pub_t *dhdp, void *pkt)
+{
+	uint8 i;
+	tcpack_sup_module_t *tcpack_sup_mod;
+	tcpack_info_t *tcpack_info_tbl;
+	int tbl_cnt;
+	int ret = BCME_OK;
+	void *pdata;
+	uint32 pktlen;
+	unsigned long flags;
+
+	if (dhdp->tcpack_sup_mode == TCPACK_SUP_OFF)
+		goto exit;
+
+	pdata = PKTDATA(dhdp->osh, pkt);
+	pktlen = PKTLEN(dhdp->osh, pkt) - dhd_prot_hdrlen(dhdp, pdata);
+
+	if (pktlen < TCPACKSZMIN || pktlen > TCPACKSZMAX) {
+		DHD_TRACE(("%s %d: Too short or long length %d to be TCP ACK\n",
+			__FUNCTION__, __LINE__, pktlen));
+		goto exit;
+	}
+
+	flags = dhd_os_tcpacklock(dhdp);
+	tcpack_sup_mod = dhdp->tcpack_sup_module;
+
+	if (!tcpack_sup_mod) {
+		DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n", __FUNCTION__, __LINE__));
+		ret = BCME_ERROR;
+		dhd_os_tcpackunlock(dhdp, flags);
+		goto exit;
+	}
+	tbl_cnt = tcpack_sup_mod->tcpack_info_cnt;
+	tcpack_info_tbl = tcpack_sup_mod->tcpack_info_tbl;
+
+	ASSERT(tbl_cnt <= TCPACK_INFO_MAXNUM);
+
+	for (i = 0; i < tbl_cnt; i++) {
+		if (tcpack_info_tbl[i].pkt_in_q == pkt) {
+			DHD_TRACE(("%s %d: pkt %p sent out. idx %d, tbl_cnt %d\n",
+				__FUNCTION__, __LINE__, pkt, i, tbl_cnt));
+			/* This pkt is being transmitted so remove the tcp_ack_info of it. */
+			if (i < tbl_cnt - 1) {
+				bcopy(&tcpack_info_tbl[tbl_cnt - 1],
+					&tcpack_info_tbl[i], sizeof(tcpack_info_t));
+			}
+			bzero(&tcpack_info_tbl[tbl_cnt - 1], sizeof(tcpack_info_t));
+			if (--tcpack_sup_mod->tcpack_info_cnt < 0) {
+				DHD_ERROR(("%s %d: ERROR!!! tcp_ack_info_cnt %d\n",
+					__FUNCTION__, __LINE__, tcpack_sup_mod->tcpack_info_cnt));
+				ret = BCME_ERROR;
+			}
+			break;
+		}
+	}
+	dhd_os_tcpackunlock(dhdp, flags);
+
+exit:
+	return ret;
+}
+
+static INLINE bool dhd_tcpdata_psh_acked(dhd_pub_t *dhdp, uint8 *ip_hdr,
+	uint8 *tcp_hdr, uint32 tcp_ack_num)
+{
+	tcpack_sup_module_t *tcpack_sup_mod;
+	int i;
+	tcpdata_info_t *tcpdata_info = NULL;
+	tdata_psh_info_t *tdata_psh_info = NULL;
+	bool ret = FALSE;
+
+	if (dhdp->tcpack_sup_mode != TCPACK_SUP_DELAYTX)
+		goto exit;
+
+	tcpack_sup_mod = dhdp->tcpack_sup_module;
+
+	if (!tcpack_sup_mod) {
+		DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n", __FUNCTION__, __LINE__));
+		goto exit;
+	}
+
+	DHD_TRACE(("%s %d: IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR
+		" TCP port %d %d, ack %u\n", __FUNCTION__, __LINE__,
+		IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_SRC_IP_OFFSET])),
+		IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_DEST_IP_OFFSET])),
+		ntoh16_ua(&tcp_hdr[TCP_SRC_PORT_OFFSET]),
+		ntoh16_ua(&tcp_hdr[TCP_DEST_PORT_OFFSET]),
+		tcp_ack_num));
+
+	for (i = 0; i < tcpack_sup_mod->tcpdata_info_cnt; i++) {
+		tcpdata_info_t *tcpdata_info_tmp = &tcpack_sup_mod->tcpdata_info_tbl[i];
+		DHD_TRACE(("%s %d: data info[%d], IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR
+			" TCP port %d %d\n", __FUNCTION__, __LINE__, i,
+			IPV4_ADDR_TO_STR(ntoh32_ua(tcpdata_info_tmp->ip_addr.src)),
+			IPV4_ADDR_TO_STR(ntoh32_ua(tcpdata_info_tmp->ip_addr.dst)),
+			ntoh16_ua(tcpdata_info_tmp->tcp_port.src),
+			ntoh16_ua(tcpdata_info_tmp->tcp_port.dst)));
+
+		/* If either IP address or TCP port number does not match, skip. */
+		if (memcmp(&ip_hdr[IPV4_SRC_IP_OFFSET],
+			tcpdata_info_tmp->ip_addr.dst, IPV4_ADDR_LEN) == 0 &&
+			memcmp(&ip_hdr[IPV4_DEST_IP_OFFSET],
+			tcpdata_info_tmp->ip_addr.src, IPV4_ADDR_LEN) == 0 &&
+			memcmp(&tcp_hdr[TCP_SRC_PORT_OFFSET],
+			tcpdata_info_tmp->tcp_port.dst, TCP_PORT_LEN) == 0 &&
+			memcmp(&tcp_hdr[TCP_DEST_PORT_OFFSET],
+			tcpdata_info_tmp->tcp_port.src, TCP_PORT_LEN) == 0) {
+			tcpdata_info = tcpdata_info_tmp;
+			break;
+		}
+	}
+
+	if (tcpdata_info == NULL) {
+		DHD_TRACE(("%s %d: no tcpdata_info!\n", __FUNCTION__, __LINE__));
+		goto exit;
+	}
+
+	if (tcpdata_info->tdata_psh_info_head == NULL) {
+		DHD_TRACE(("%s %d: No PSH DATA to be acked!\n", __FUNCTION__, __LINE__));
+	}
+
+	while ((tdata_psh_info = tcpdata_info->tdata_psh_info_head)) {
+		if (IS_TCPSEQ_GE(tcp_ack_num, tdata_psh_info->end_seq)) {
+			DHD_TRACE(("%s %d: PSH ACKED! %u >= %u\n",
+				__FUNCTION__, __LINE__, tcp_ack_num, tdata_psh_info->end_seq));
+			tcpdata_info->tdata_psh_info_head = tdata_psh_info->next;
+			tdata_psh_info->next = NULL;
+			_tdata_psh_info_pool_enq(tcpack_sup_mod, tdata_psh_info);
+			ret = TRUE;
+		} else
+			break;
+	}
+	if (tdata_psh_info == NULL)
+		tcpdata_info->tdata_psh_info_tail = NULL;
+
+#ifdef DHDTCPACK_SUP_DBG
+	DHD_TRACE(("%s %d: PSH INFO ENQ %d\n",
+		__FUNCTION__, __LINE__, tcpack_sup_mod->psh_info_enq_num));
+#endif /* DHDTCPACK_SUP_DBG */
+
+exit:
+	return ret;
+}
+
+bool
+dhd_tcpack_suppress(dhd_pub_t *dhdp, void *pkt)
+{
+	uint8 *new_ether_hdr;	/* Ethernet header of the new packet */
+	uint16 new_ether_type;	/* Ethernet type of the new packet */
+	uint8 *new_ip_hdr;		/* IP header of the new packet */
+	uint8 *new_tcp_hdr;		/* TCP header of the new packet */
+	uint32 new_ip_hdr_len;	/* IP header length of the new packet */
+	uint32 cur_framelen;
+	uint32 new_tcp_ack_num;		/* TCP acknowledge number of the new packet */
+	uint16 new_ip_total_len;	/* Total length of IP packet for the new packet */
+	uint32 new_tcp_hdr_len;		/* TCP header length of the new packet */
+	tcpack_sup_module_t *tcpack_sup_mod;
+	tcpack_info_t *tcpack_info_tbl;
+	int i;
+	bool ret = FALSE;
+	bool set_dotxinrx = TRUE;
+	unsigned long flags;
+
+	if (dhdp->tcpack_sup_mode == TCPACK_SUP_OFF)
+		goto exit;
+
+	new_ether_hdr = PKTDATA(dhdp->osh, pkt);
+	cur_framelen = PKTLEN(dhdp->osh, pkt);
+
+	if (cur_framelen < TCPACKSZMIN || cur_framelen > TCPACKSZMAX) {
+		DHD_TRACE(("%s %d: Too short or long length %d to be TCP ACK\n",
+			__FUNCTION__, __LINE__, cur_framelen));
+		goto exit;
+	}
+
+	new_ether_type = new_ether_hdr[12] << 8 | new_ether_hdr[13];
+
+	if (new_ether_type != ETHER_TYPE_IP) {
+		DHD_TRACE(("%s %d: Not a IP packet 0x%x\n",
+			__FUNCTION__, __LINE__, new_ether_type));
+		goto exit;
+	}
+
+	DHD_TRACE(("%s %d: IP pkt! 0x%x\n", __FUNCTION__, __LINE__, new_ether_type));
+
+	new_ip_hdr = new_ether_hdr + ETHER_HDR_LEN;
+	cur_framelen -= ETHER_HDR_LEN;
+
+	ASSERT(cur_framelen >= IPV4_MIN_HEADER_LEN);
+
+	new_ip_hdr_len = IPV4_HLEN(new_ip_hdr);
+	if (IP_VER(new_ip_hdr) != IP_VER_4 || IPV4_PROT(new_ip_hdr) != IP_PROT_TCP) {
+		DHD_TRACE(("%s %d: Not IPv4 nor TCP! ip ver %d, prot %d\n",
+			__FUNCTION__, __LINE__, IP_VER(new_ip_hdr), IPV4_PROT(new_ip_hdr)));
+		goto exit;
+	}
+
+	new_tcp_hdr = new_ip_hdr + new_ip_hdr_len;
+	cur_framelen -= new_ip_hdr_len;
+
+	ASSERT(cur_framelen >= TCP_MIN_HEADER_LEN);
+
+	DHD_TRACE(("%s %d: TCP pkt!\n", __FUNCTION__, __LINE__));
+
+	/* is it an ack ? Allow only ACK flag, not to suppress others. */
+	if (new_tcp_hdr[TCP_FLAGS_OFFSET] != TCP_FLAG_ACK) {
+		DHD_TRACE(("%s %d: Do not touch TCP flag 0x%x\n",
+			__FUNCTION__, __LINE__, new_tcp_hdr[TCP_FLAGS_OFFSET]));
+		goto exit;
+	}
+
+	new_ip_total_len = ntoh16_ua(&new_ip_hdr[IPV4_PKTLEN_OFFSET]);
+	new_tcp_hdr_len = 4 * TCP_HDRLEN(new_tcp_hdr[TCP_HLEN_OFFSET]);
+
+	/* This packet has TCP data, so just send */
+	if (new_ip_total_len > new_ip_hdr_len + new_tcp_hdr_len) {
+		DHD_TRACE(("%s %d: Do nothing for TCP DATA\n", __FUNCTION__, __LINE__));
+		goto exit;
+	}
+
+	ASSERT(new_ip_total_len == new_ip_hdr_len + new_tcp_hdr_len);
+
+	new_tcp_ack_num = ntoh32_ua(&new_tcp_hdr[TCP_ACK_NUM_OFFSET]);
+
+	DHD_TRACE(("%s %d: TCP ACK with zero DATA length"
+		" IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR" TCP port %d %d\n",
+		__FUNCTION__, __LINE__,
+		IPV4_ADDR_TO_STR(ntoh32_ua(&new_ip_hdr[IPV4_SRC_IP_OFFSET])),
+		IPV4_ADDR_TO_STR(ntoh32_ua(&new_ip_hdr[IPV4_DEST_IP_OFFSET])),
+		ntoh16_ua(&new_tcp_hdr[TCP_SRC_PORT_OFFSET]),
+		ntoh16_ua(&new_tcp_hdr[TCP_DEST_PORT_OFFSET])));
+
+	/* Look for tcp_ack_info that has the same ip src/dst addrs and tcp src/dst ports */
+	flags = dhd_os_tcpacklock(dhdp);
+#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
+	counter_printlog(&tack_tbl);
+	tack_tbl.cnt[0]++;
+#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
+
+	tcpack_sup_mod = dhdp->tcpack_sup_module;
+	tcpack_info_tbl = tcpack_sup_mod->tcpack_info_tbl;
+
+	if (!tcpack_sup_mod) {
+		DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n", __FUNCTION__, __LINE__));
+		ret = BCME_ERROR;
+		dhd_os_tcpackunlock(dhdp, flags);
+		goto exit;
+	}
+
+	if (dhd_tcpdata_psh_acked(dhdp, new_ip_hdr, new_tcp_hdr, new_tcp_ack_num)) {
+		/* This TCPACK is ACK to TCPDATA PSH pkt, so keep set_dotxinrx TRUE */
+#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
+		tack_tbl.cnt[5]++;
+#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
+	} else
+		set_dotxinrx = FALSE;
+
+	for (i = 0; i < tcpack_sup_mod->tcpack_info_cnt; i++) {
+		void *oldpkt;	/* TCPACK packet that is already in txq or DelayQ */
+		uint8 *old_ether_hdr, *old_ip_hdr, *old_tcp_hdr;
+		uint32 old_ip_hdr_len, old_tcp_hdr_len;
+		uint32 old_tcpack_num;	/* TCP ACK number of old TCPACK packet in Q */
+
+		if ((oldpkt = tcpack_info_tbl[i].pkt_in_q) == NULL) {
+			DHD_ERROR(("%s %d: Unexpected error!! cur idx %d, ttl cnt %d\n",
+				__FUNCTION__, __LINE__, i, tcpack_sup_mod->tcpack_info_cnt));
+			break;
+		}
+
+		if (PKTDATA(dhdp->osh, oldpkt) == NULL) {
+			DHD_ERROR(("%s %d: oldpkt data NULL!! cur idx %d, ttl cnt %d\n",
+				__FUNCTION__, __LINE__, i, tcpack_sup_mod->tcpack_info_cnt));
+			break;
+		}
+
+		old_ether_hdr = tcpack_info_tbl[i].pkt_ether_hdr;
+		old_ip_hdr = old_ether_hdr + ETHER_HDR_LEN;
+		old_ip_hdr_len = IPV4_HLEN(old_ip_hdr);
+		old_tcp_hdr = old_ip_hdr + old_ip_hdr_len;
+		old_tcp_hdr_len = 4 * TCP_HDRLEN(old_tcp_hdr[TCP_HLEN_OFFSET]);
+
+		DHD_TRACE(("%s %d: oldpkt %p[%d], IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR
+			" TCP port %d %d\n", __FUNCTION__, __LINE__, oldpkt, i,
+			IPV4_ADDR_TO_STR(ntoh32_ua(&old_ip_hdr[IPV4_SRC_IP_OFFSET])),
+			IPV4_ADDR_TO_STR(ntoh32_ua(&old_ip_hdr[IPV4_DEST_IP_OFFSET])),
+			ntoh16_ua(&old_tcp_hdr[TCP_SRC_PORT_OFFSET]),
+			ntoh16_ua(&old_tcp_hdr[TCP_DEST_PORT_OFFSET])));
+
+		/* If either of IP address or TCP port number does not match, skip.
+		 * Note that src/dst addr fields in ip header are contiguous being 8 bytes in total.
+		 * Also, src/dst port fields in TCP header are contiguous being 4 bytes in total.
+		 */
+		if (memcmp(&new_ip_hdr[IPV4_SRC_IP_OFFSET],
+			&old_ip_hdr[IPV4_SRC_IP_OFFSET], IPV4_ADDR_LEN * 2) ||
+			memcmp(&new_tcp_hdr[TCP_SRC_PORT_OFFSET],
+			&old_tcp_hdr[TCP_SRC_PORT_OFFSET], TCP_PORT_LEN * 2))
+			continue;
+
+		old_tcpack_num = ntoh32_ua(&old_tcp_hdr[TCP_ACK_NUM_OFFSET]);
+
+		if (IS_TCPSEQ_GT(new_tcp_ack_num, old_tcpack_num)) {
+			/* New packet has higher TCP ACK number, so it replaces the old packet */
+			if (new_ip_hdr_len == old_ip_hdr_len &&
+				new_tcp_hdr_len == old_tcp_hdr_len) {
+				ASSERT(memcmp(new_ether_hdr, old_ether_hdr, ETHER_HDR_LEN) == 0);
+				bcopy(new_ip_hdr, old_ip_hdr, new_ip_total_len);
+				PKTFREE(dhdp->osh, pkt, FALSE);
+				DHD_TRACE(("%s %d: TCP ACK replace %u -> %u\n",
+					__FUNCTION__, __LINE__, old_tcpack_num, new_tcp_ack_num));
+#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
+				tack_tbl.cnt[2]++;
+#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
+				ret = TRUE;
+			} else {
+#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
+				tack_tbl.cnt[6]++;
+#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
+				DHD_TRACE(("%s %d: lenth mismatch %d != %d || %d != %d"
+					" ACK %u -> %u\n", __FUNCTION__, __LINE__,
+					new_ip_hdr_len, old_ip_hdr_len,
+					new_tcp_hdr_len, old_tcp_hdr_len,
+					old_tcpack_num, new_tcp_ack_num));
+			}
+		} else if (new_tcp_ack_num == old_tcpack_num) {
+			set_dotxinrx = TRUE;
+			/* TCPACK retransmission */
+#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
+			tack_tbl.cnt[3]++;
+#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
+		} else {
+			DHD_TRACE(("%s %d: ACK number reverse old %u(0x%p) new %u(0x%p)\n",
+				__FUNCTION__, __LINE__, old_tcpack_num, oldpkt,
+				new_tcp_ack_num, pkt));
+		}
+		dhd_os_tcpackunlock(dhdp, flags);
+		goto exit;
+	}
+
+	if (i == tcpack_sup_mod->tcpack_info_cnt && i < TCPACK_INFO_MAXNUM) {
+		/* No TCPACK packet with the same IP addr and TCP port is found
+		 * in tcp_ack_info_tbl. So add this packet to the table.
+		 */
+		DHD_TRACE(("%s %d: Add pkt 0x%p(ether_hdr 0x%p) to tbl[%d]\n",
+			__FUNCTION__, __LINE__, pkt, new_ether_hdr,
+			tcpack_sup_mod->tcpack_info_cnt));
+
+		tcpack_info_tbl[tcpack_sup_mod->tcpack_info_cnt].pkt_in_q = pkt;
+		tcpack_info_tbl[tcpack_sup_mod->tcpack_info_cnt].pkt_ether_hdr = new_ether_hdr;
+		tcpack_sup_mod->tcpack_info_cnt++;
+#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
+		tack_tbl.cnt[1]++;
+#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
+	} else {
+		ASSERT(i == tcpack_sup_mod->tcpack_info_cnt);
+		DHD_TRACE(("%s %d: No empty tcp ack info tbl\n",
+			__FUNCTION__, __LINE__));
+	}
+	dhd_os_tcpackunlock(dhdp, flags);
+
+exit:
+	/* Unless TCPACK_SUP_DELAYTX, dotxinrx is alwasy TRUE, so no need to set here */
+	if (dhdp->tcpack_sup_mode == TCPACK_SUP_DELAYTX && set_dotxinrx)
+		dhd_bus_set_dotxinrx(dhdp->bus, TRUE);
+
+	return ret;
+}
+
+bool
+dhd_tcpdata_info_get(dhd_pub_t *dhdp, void *pkt)
+{
+	uint8 *ether_hdr;	/* Ethernet header of the new packet */
+	uint16 ether_type;	/* Ethernet type of the new packet */
+	uint8 *ip_hdr;		/* IP header of the new packet */
+	uint8 *tcp_hdr;		/* TCP header of the new packet */
+	uint32 ip_hdr_len;	/* IP header length of the new packet */
+	uint32 cur_framelen;
+	uint16 ip_total_len;	/* Total length of IP packet for the new packet */
+	uint32 tcp_hdr_len;		/* TCP header length of the new packet */
+	uint32 tcp_seq_num;		/* TCP sequence number of the new packet */
+	uint16 tcp_data_len;	/* TCP DATA length that excludes IP and TCP headers */
+	uint32 end_tcp_seq_num;	/* TCP seq number of the last byte in the new packet */
+	tcpack_sup_module_t *tcpack_sup_mod;
+	tcpdata_info_t *tcpdata_info = NULL;
+	tdata_psh_info_t *tdata_psh_info;
+
+	int i;
+	bool ret = FALSE;
+	unsigned long flags;
+
+	if (dhdp->tcpack_sup_mode != TCPACK_SUP_DELAYTX)
+		goto exit;
+
+	ether_hdr = PKTDATA(dhdp->osh, pkt);
+	cur_framelen = PKTLEN(dhdp->osh, pkt);
+
+	ether_type = ether_hdr[12] << 8 | ether_hdr[13];
+
+	if (ether_type != ETHER_TYPE_IP) {
+		DHD_TRACE(("%s %d: Not a IP packet 0x%x\n",
+			__FUNCTION__, __LINE__, ether_type));
+		goto exit;
+	}
+
+	DHD_TRACE(("%s %d: IP pkt! 0x%x\n", __FUNCTION__, __LINE__, ether_type));
+
+	ip_hdr = ether_hdr + ETHER_HDR_LEN;
+	cur_framelen -= ETHER_HDR_LEN;
+
+	if (cur_framelen < IPV4_MIN_HEADER_LEN) {
+		DHD_ERROR(("%s %d: cur_framelen(%d) < IPV4_MIN_HEADER_LEN\n", __FUNCTION__,
+			__LINE__, cur_framelen));
+		goto exit;
+	}
+
+	ip_hdr_len = IPV4_HLEN(ip_hdr);
+	if (IP_VER(ip_hdr) != IP_VER_4 || IPV4_PROT(ip_hdr) != IP_PROT_TCP) {
+		DHD_TRACE(("%s %d: Not IPv4 nor TCP! ip ver %d, prot %d\n",
+			__FUNCTION__, __LINE__, IP_VER(ip_hdr), IPV4_PROT(ip_hdr)));
+		goto exit;
+	}
+
+	tcp_hdr = ip_hdr + ip_hdr_len;
+	cur_framelen -= ip_hdr_len;
+
+	ASSERT(cur_framelen >= TCP_MIN_HEADER_LEN);
+	if (cur_framelen < TCP_MIN_HEADER_LEN) {
+		DHD_TRACE(("%s %d: cur_framelen is less than TCP_MIN_HEADER_LEN\n",
+			__FUNCTION__, __LINE__));
+		goto exit;
+	}
+
+	DHD_TRACE(("%s %d: TCP pkt!\n", __FUNCTION__, __LINE__));
+
+	ip_total_len = ntoh16_ua(&ip_hdr[IPV4_PKTLEN_OFFSET]);
+	tcp_hdr_len = 4 * TCP_HDRLEN(tcp_hdr[TCP_HLEN_OFFSET]);
+
+	/* This packet is mere TCP ACK, so do nothing */
+	if (ip_total_len == ip_hdr_len + tcp_hdr_len) {
+		DHD_TRACE(("%s %d: Do nothing for no data TCP ACK\n", __FUNCTION__, __LINE__));
+		goto exit;
+	}
+
+	ASSERT(ip_total_len > ip_hdr_len + tcp_hdr_len);
+
+	if ((tcp_hdr[TCP_FLAGS_OFFSET] & TCP_FLAG_PSH) == 0) {
+		DHD_TRACE(("%s %d: Not interested TCP DATA packet\n", __FUNCTION__, __LINE__));
+		goto exit;
+	}
+
+	DHD_TRACE(("%s %d: TCP DATA with nonzero DATA length"
+		" IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR" TCP port %d %d, flag 0x%x\n",
+		__FUNCTION__, __LINE__,
+		IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_SRC_IP_OFFSET])),
+		IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_DEST_IP_OFFSET])),
+		ntoh16_ua(&tcp_hdr[TCP_SRC_PORT_OFFSET]),
+		ntoh16_ua(&tcp_hdr[TCP_DEST_PORT_OFFSET]),
+		tcp_hdr[TCP_FLAGS_OFFSET]));
+
+	flags = dhd_os_tcpacklock(dhdp);
+	tcpack_sup_mod = dhdp->tcpack_sup_module;
+
+	if (!tcpack_sup_mod) {
+		DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n", __FUNCTION__, __LINE__));
+		ret = BCME_ERROR;
+		dhd_os_tcpackunlock(dhdp, flags);
+		goto exit;
+	}
+
+	/* Look for tcpdata_info that has the same ip src/dst addrs and tcp src/dst ports */
+	i = 0;
+	while (i < tcpack_sup_mod->tcpdata_info_cnt) {
+		tcpdata_info_t *tdata_info_tmp = &tcpack_sup_mod->tcpdata_info_tbl[i];
+		uint32 now_in_ms = OSL_SYSUPTIME();
+		DHD_TRACE(("%s %d: data info[%d], IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR
+			" TCP port %d %d\n", __FUNCTION__, __LINE__, i,
+			IPV4_ADDR_TO_STR(ntoh32_ua(tdata_info_tmp->ip_addr.src)),
+			IPV4_ADDR_TO_STR(ntoh32_ua(tdata_info_tmp->ip_addr.dst)),
+			ntoh16_ua(tdata_info_tmp->tcp_port.src),
+			ntoh16_ua(tdata_info_tmp->tcp_port.dst)));
+
+		/* If both IP address and TCP port number match, we found it so break.
+		 * Note that src/dst addr fields in ip header are contiguous being 8 bytes in total.
+		 * Also, src/dst port fields in TCP header are contiguous being 4 bytes in total.
+		 */
+		if (memcmp(&ip_hdr[IPV4_SRC_IP_OFFSET],
+			(void *)&tdata_info_tmp->ip_addr, IPV4_ADDR_LEN * 2) == 0 &&
+			memcmp(&tcp_hdr[TCP_SRC_PORT_OFFSET],
+			(void *)&tdata_info_tmp->tcp_port, TCP_PORT_LEN * 2) == 0) {
+			tcpdata_info = tdata_info_tmp;
+			tcpdata_info->last_used_time = now_in_ms;
+			break;
+		}
+
+		if (now_in_ms - tdata_info_tmp->last_used_time > TCPDATA_INFO_TIMEOUT) {
+			tdata_psh_info_t *tdata_psh_info_tmp;
+			tcpdata_info_t *last_tdata_info;
+
+			while ((tdata_psh_info_tmp = tdata_info_tmp->tdata_psh_info_head)) {
+				tdata_info_tmp->tdata_psh_info_head = tdata_psh_info_tmp->next;
+				tdata_psh_info_tmp->next = NULL;
+				DHD_TRACE(("%s %d: Clean tdata_psh_info(end_seq %u)!\n",
+					__FUNCTION__, __LINE__, tdata_psh_info_tmp->end_seq));
+				_tdata_psh_info_pool_enq(tcpack_sup_mod, tdata_psh_info_tmp);
+			}
+#ifdef DHDTCPACK_SUP_DBG
+			DHD_ERROR(("%s %d: PSH INFO ENQ %d\n",
+				__FUNCTION__, __LINE__, tcpack_sup_mod->psh_info_enq_num));
+#endif /* DHDTCPACK_SUP_DBG */
+			tcpack_sup_mod->tcpdata_info_cnt--;
+			ASSERT(tcpack_sup_mod->tcpdata_info_cnt >= 0);
+
+			last_tdata_info =
+				&tcpack_sup_mod->tcpdata_info_tbl[tcpack_sup_mod->tcpdata_info_cnt];
+			if (i < tcpack_sup_mod->tcpdata_info_cnt) {
+				ASSERT(last_tdata_info != tdata_info_tmp);
+				bcopy(last_tdata_info, tdata_info_tmp, sizeof(tcpdata_info_t));
+			}
+			bzero(last_tdata_info, sizeof(tcpdata_info_t));
+			DHD_INFO(("%s %d: tcpdata_info(idx %d) is aged out. ttl cnt is now %d\n",
+				__FUNCTION__, __LINE__, i, tcpack_sup_mod->tcpdata_info_cnt));
+			/* Don't increase "i" here, so that the prev last tcpdata_info is checked */
+		} else
+			 i++;
+	}
+
+	tcp_seq_num = ntoh32_ua(&tcp_hdr[TCP_SEQ_NUM_OFFSET]);
+	tcp_data_len = ip_total_len - ip_hdr_len - tcp_hdr_len;
+	end_tcp_seq_num = tcp_seq_num + tcp_data_len;
+
+	if (tcpdata_info == NULL) {
+		ASSERT(i == tcpack_sup_mod->tcpdata_info_cnt);
+		if (i >= TCPDATA_INFO_MAXNUM) {
+			DHD_TRACE(("%s %d: tcp_data_info_tbl FULL! %d %d"
+				" IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR" TCP port %d %d\n",
+				__FUNCTION__, __LINE__, i, tcpack_sup_mod->tcpdata_info_cnt,
+				IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_SRC_IP_OFFSET])),
+				IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_DEST_IP_OFFSET])),
+				ntoh16_ua(&tcp_hdr[TCP_SRC_PORT_OFFSET]),
+				ntoh16_ua(&tcp_hdr[TCP_DEST_PORT_OFFSET])));
+			dhd_os_tcpackunlock(dhdp, flags);
+			goto exit;
+		}
+		tcpdata_info = &tcpack_sup_mod->tcpdata_info_tbl[i];
+
+		/* No TCP flow with the same IP addr and TCP port is found
+		 * in tcp_data_info_tbl. So add this flow to the table.
+		 */
+		DHD_INFO(("%s %d: Add data info to tbl[%d]: IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR
+			" TCP port %d %d\n",
+			__FUNCTION__, __LINE__, tcpack_sup_mod->tcpdata_info_cnt,
+			IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_SRC_IP_OFFSET])),
+			IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_DEST_IP_OFFSET])),
+			ntoh16_ua(&tcp_hdr[TCP_SRC_PORT_OFFSET]),
+			ntoh16_ua(&tcp_hdr[TCP_DEST_PORT_OFFSET])));
+		/* Note that src/dst addr fields in ip header are contiguous being 8 bytes in total.
+		 * Also, src/dst port fields in TCP header are contiguous being 4 bytes in total.
+		 */
+		bcopy(&ip_hdr[IPV4_SRC_IP_OFFSET], (void *)&tcpdata_info->ip_addr,
+			IPV4_ADDR_LEN * 2);
+		bcopy(&tcp_hdr[TCP_SRC_PORT_OFFSET], (void *)&tcpdata_info->tcp_port,
+			TCP_PORT_LEN * 2);
+
+		tcpdata_info->last_used_time = OSL_SYSUPTIME();
+		tcpack_sup_mod->tcpdata_info_cnt++;
+	}
+
+	ASSERT(tcpdata_info != NULL);
+
+	tdata_psh_info = _tdata_psh_info_pool_deq(tcpack_sup_mod);
+#ifdef DHDTCPACK_SUP_DBG
+	DHD_TRACE(("%s %d: PSH INFO ENQ %d\n",
+		__FUNCTION__, __LINE__, tcpack_sup_mod->psh_info_enq_num));
+#endif /* DHDTCPACK_SUP_DBG */
+
+	if (tdata_psh_info == NULL) {
+		DHD_ERROR(("%s %d: No more free tdata_psh_info!!\n", __FUNCTION__, __LINE__));
+		ret = BCME_ERROR;
+		dhd_os_tcpackunlock(dhdp, flags);
+		goto exit;
+	}
+	tdata_psh_info->end_seq = end_tcp_seq_num;
+
+#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
+	tack_tbl.cnt[4]++;
+#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
+
+	DHD_TRACE(("%s %d: TCP PSH DATA recvd! end seq %u\n",
+		__FUNCTION__, __LINE__, tdata_psh_info->end_seq));
+
+	ASSERT(tdata_psh_info->next == NULL);
+
+	if (tcpdata_info->tdata_psh_info_head == NULL)
+		tcpdata_info->tdata_psh_info_head = tdata_psh_info;
+	else {
+		ASSERT(tcpdata_info->tdata_psh_info_tail);
+		tcpdata_info->tdata_psh_info_tail->next = tdata_psh_info;
+	}
+	tcpdata_info->tdata_psh_info_tail = tdata_psh_info;
+
+	dhd_os_tcpackunlock(dhdp, flags);
+
+exit:
+	return ret;
+}
+
+bool
+dhd_tcpack_hold(dhd_pub_t *dhdp, void *pkt, int ifidx)
+{
+	uint8 *new_ether_hdr;	/* Ethernet header of the new packet */
+	uint16 new_ether_type;	/* Ethernet type of the new packet */
+	uint8 *new_ip_hdr;		/* IP header of the new packet */
+	uint8 *new_tcp_hdr;		/* TCP header of the new packet */
+	uint32 new_ip_hdr_len;	/* IP header length of the new packet */
+	uint32 cur_framelen;
+	uint32 new_tcp_ack_num;		/* TCP acknowledge number of the new packet */
+	uint16 new_ip_total_len;	/* Total length of IP packet for the new packet */
+	uint32 new_tcp_hdr_len;		/* TCP header length of the new packet */
+	tcpack_sup_module_t *tcpack_sup_mod;
+	tcpack_info_t *tcpack_info_tbl;
+	int i, free_slot = TCPACK_INFO_MAXNUM;
+	bool hold = FALSE;
+	unsigned long flags;
+
+	if (dhdp->tcpack_sup_mode != TCPACK_SUP_HOLD) {
+		goto exit;
+	}
+
+	if (dhdp->tcpack_sup_ratio == 1) {
+		goto exit;
+	}
+
+	new_ether_hdr = PKTDATA(dhdp->osh, pkt);
+	cur_framelen = PKTLEN(dhdp->osh, pkt);
+
+	if (cur_framelen < TCPACKSZMIN || cur_framelen > TCPACKSZMAX) {
+		DHD_TRACE(("%s %d: Too short or long length %d to be TCP ACK\n",
+			__FUNCTION__, __LINE__, cur_framelen));
+		goto exit;
+	}
+
+	new_ether_type = new_ether_hdr[12] << 8 | new_ether_hdr[13];
+
+	if (new_ether_type != ETHER_TYPE_IP) {
+		DHD_TRACE(("%s %d: Not a IP packet 0x%x\n",
+			__FUNCTION__, __LINE__, new_ether_type));
+		goto exit;
+	}
+
+	DHD_TRACE(("%s %d: IP pkt! 0x%x\n", __FUNCTION__, __LINE__, new_ether_type));
+
+	new_ip_hdr = new_ether_hdr + ETHER_HDR_LEN;
+	cur_framelen -= ETHER_HDR_LEN;
+
+	ASSERT(cur_framelen >= IPV4_MIN_HEADER_LEN);
+
+	new_ip_hdr_len = IPV4_HLEN(new_ip_hdr);
+	if (IP_VER(new_ip_hdr) != IP_VER_4 || IPV4_PROT(new_ip_hdr) != IP_PROT_TCP) {
+		DHD_TRACE(("%s %d: Not IPv4 nor TCP! ip ver %d, prot %d\n",
+			__FUNCTION__, __LINE__, IP_VER(new_ip_hdr), IPV4_PROT(new_ip_hdr)));
+		goto exit;
+	}
+
+	new_tcp_hdr = new_ip_hdr + new_ip_hdr_len;
+	cur_framelen -= new_ip_hdr_len;
+
+	ASSERT(cur_framelen >= TCP_MIN_HEADER_LEN);
+
+	DHD_TRACE(("%s %d: TCP pkt!\n", __FUNCTION__, __LINE__));
+
+	/* is it an ack ? Allow only ACK flag, not to suppress others. */
+	if (new_tcp_hdr[TCP_FLAGS_OFFSET] != TCP_FLAG_ACK) {
+		DHD_TRACE(("%s %d: Do not touch TCP flag 0x%x\n",
+			__FUNCTION__, __LINE__, new_tcp_hdr[TCP_FLAGS_OFFSET]));
+		goto exit;
+	}
+
+	new_ip_total_len = ntoh16_ua(&new_ip_hdr[IPV4_PKTLEN_OFFSET]);
+	new_tcp_hdr_len = 4 * TCP_HDRLEN(new_tcp_hdr[TCP_HLEN_OFFSET]);
+
+	/* This packet has TCP data, so just send */
+	if (new_ip_total_len > new_ip_hdr_len + new_tcp_hdr_len) {
+		DHD_TRACE(("%s %d: Do nothing for TCP DATA\n", __FUNCTION__, __LINE__));
+		goto exit;
+	}
+
+	ASSERT(new_ip_total_len == new_ip_hdr_len + new_tcp_hdr_len);
+
+	new_tcp_ack_num = ntoh32_ua(&new_tcp_hdr[TCP_ACK_NUM_OFFSET]);
+
+	DHD_TRACE(("%s %d: TCP ACK with zero DATA length"
+		" IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR" TCP port %d %d\n",
+		__FUNCTION__, __LINE__,
+		IPV4_ADDR_TO_STR(ntoh32_ua(&new_ip_hdr[IPV4_SRC_IP_OFFSET])),
+		IPV4_ADDR_TO_STR(ntoh32_ua(&new_ip_hdr[IPV4_DEST_IP_OFFSET])),
+		ntoh16_ua(&new_tcp_hdr[TCP_SRC_PORT_OFFSET]),
+		ntoh16_ua(&new_tcp_hdr[TCP_DEST_PORT_OFFSET])));
+
+	/* Look for tcp_ack_info that has the same ip src/dst addrs and tcp src/dst ports */
+	flags = dhd_os_tcpacklock(dhdp);
+
+	tcpack_sup_mod = dhdp->tcpack_sup_module;
+	tcpack_info_tbl = tcpack_sup_mod->tcpack_info_tbl;
+
+	if (!tcpack_sup_mod) {
+		DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n", __FUNCTION__, __LINE__));
+		dhd_os_tcpackunlock(dhdp, flags);
+		goto exit;
+	}
+
+	hold = TRUE;
+
+	for (i = 0; i < TCPACK_INFO_MAXNUM; i++) {
+		void *oldpkt;	/* TCPACK packet that is already in txq or DelayQ */
+		uint8 *old_ether_hdr, *old_ip_hdr, *old_tcp_hdr;
+		uint32 old_ip_hdr_len;
+		uint32 old_tcpack_num;	/* TCP ACK number of old TCPACK packet in Q */
+
+		if ((oldpkt = tcpack_info_tbl[i].pkt_in_q) == NULL) {
+			if (free_slot == TCPACK_INFO_MAXNUM) {
+				free_slot = i;
+			}
+			continue;
+		}
+
+		if (PKTDATA(dhdp->osh, oldpkt) == NULL) {
+			DHD_ERROR(("%s %d: oldpkt data NULL!! cur idx %d\n",
+				__FUNCTION__, __LINE__, i));
+			hold = FALSE;
+			dhd_os_tcpackunlock(dhdp, flags);
+			goto exit;
+		}
+
+		old_ether_hdr = tcpack_info_tbl[i].pkt_ether_hdr;
+		old_ip_hdr = old_ether_hdr + ETHER_HDR_LEN;
+		old_ip_hdr_len = IPV4_HLEN(old_ip_hdr);
+		old_tcp_hdr = old_ip_hdr + old_ip_hdr_len;
+
+		DHD_TRACE(("%s %d: oldpkt %p[%d], IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR
+			" TCP port %d %d\n", __FUNCTION__, __LINE__, oldpkt, i,
+			IPV4_ADDR_TO_STR(ntoh32_ua(&old_ip_hdr[IPV4_SRC_IP_OFFSET])),
+			IPV4_ADDR_TO_STR(ntoh32_ua(&old_ip_hdr[IPV4_DEST_IP_OFFSET])),
+			ntoh16_ua(&old_tcp_hdr[TCP_SRC_PORT_OFFSET]),
+			ntoh16_ua(&old_tcp_hdr[TCP_DEST_PORT_OFFSET])));
+
+		/* If either of IP address or TCP port number does not match, skip. */
+		if (memcmp(&new_ip_hdr[IPV4_SRC_IP_OFFSET],
+			&old_ip_hdr[IPV4_SRC_IP_OFFSET], IPV4_ADDR_LEN * 2) ||
+			memcmp(&new_tcp_hdr[TCP_SRC_PORT_OFFSET],
+			&old_tcp_hdr[TCP_SRC_PORT_OFFSET], TCP_PORT_LEN * 2)) {
+			continue;
+		}
+
+		old_tcpack_num = ntoh32_ua(&old_tcp_hdr[TCP_ACK_NUM_OFFSET]);
+
+		if (IS_TCPSEQ_GE(new_tcp_ack_num, old_tcpack_num)) {
+			tcpack_info_tbl[i].supp_cnt++;
+			if (tcpack_info_tbl[i].supp_cnt >= dhdp->tcpack_sup_ratio) {
+				tcpack_info_tbl[i].pkt_in_q = NULL;
+				tcpack_info_tbl[i].pkt_ether_hdr = NULL;
+				tcpack_info_tbl[i].ifidx = 0;
+				tcpack_info_tbl[i].supp_cnt = 0;
+				hold = FALSE;
+			} else {
+				tcpack_info_tbl[i].pkt_in_q = pkt;
+				tcpack_info_tbl[i].pkt_ether_hdr = new_ether_hdr;
+				tcpack_info_tbl[i].ifidx = ifidx;
+			}
+			PKTFREE(dhdp->osh, oldpkt, TRUE);
+		} else {
+			PKTFREE(dhdp->osh, pkt, TRUE);
+		}
+		dhd_os_tcpackunlock(dhdp, flags);
+
+		if (!hold) {
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
+			del_timer_sync(&tcpack_info_tbl[i].timer);
+#else
+			hrtimer_cancel(&tcpack_sup_mod->tcpack_info_tbl[i].timer.timer);
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
+		}
+		goto exit;
+	}
+
+	if (free_slot < TCPACK_INFO_MAXNUM) {
+		/* No TCPACK packet with the same IP addr and TCP port is found
+		 * in tcp_ack_info_tbl. So add this packet to the table.
+		 */
+		DHD_TRACE(("%s %d: Add pkt 0x%p(ether_hdr 0x%p) to tbl[%d]\n",
+			__FUNCTION__, __LINE__, pkt, new_ether_hdr,
+			free_slot));
+
+		tcpack_info_tbl[free_slot].pkt_in_q = pkt;
+		tcpack_info_tbl[free_slot].pkt_ether_hdr = new_ether_hdr;
+		tcpack_info_tbl[free_slot].ifidx = ifidx;
+		tcpack_info_tbl[free_slot].supp_cnt = 1;
+#ifndef TCPACK_SUPPRESS_HOLD_HRT
+		mod_timer(&tcpack_sup_mod->tcpack_info_tbl[free_slot].timer,
+			jiffies + msecs_to_jiffies(dhdp->tcpack_sup_delay));
+#else
+		tasklet_hrtimer_start(&tcpack_sup_mod->tcpack_info_tbl[free_slot].timer,
+			ktime_set(0, dhdp->tcpack_sup_delay*1000000),
+			HRTIMER_MODE_REL);
+#endif /* TCPACK_SUPPRESS_HOLD_HRT */
+		tcpack_sup_mod->tcpack_info_cnt++;
+	} else {
+		hold = FALSE;
+		DHD_TRACE(("%s %d: No empty tcp ack info tbl\n",
+			__FUNCTION__, __LINE__));
+	}
+	dhd_os_tcpackunlock(dhdp, flags);
+
+exit:
+	return hold;
+}
+#endif /* DHDTCPACK_SUPPRESS */
+
+#ifdef DHDTCPSYNC_FLOOD_BLK
+tcp_hdr_flag_t
+dhd_tcpdata_get_flag(dhd_pub_t *dhdp, void *pkt)
+{
+	uint8 *ether_hdr;	/* Ethernet header of the new packet */
+	uint16 ether_type;	/* Ethernet type of the new packet */
+	uint8 *ip_hdr;		/* IP header of the new packet */
+	uint8 *tcp_hdr;		/* TCP header of the new packet */
+	uint32 ip_hdr_len;	/* IP header length of the new packet */
+	uint32 cur_framelen;
+	uint8 flags;
+
+	ether_hdr = PKTDATA(dhdp->osh, pkt);
+	cur_framelen = PKTLEN(dhdp->osh, pkt);
+
+	ether_type = ether_hdr[12] << 8 | ether_hdr[13];
+
+	if (ether_type != ETHER_TYPE_IP) {
+		DHD_TRACE(("%s %d: Not a IP packet 0x%x\n",
+			__FUNCTION__, __LINE__, ether_type));
+		return FLAG_OTHERS;
+	}
+
+	ip_hdr = ether_hdr + ETHER_HDR_LEN;
+	cur_framelen -= ETHER_HDR_LEN;
+
+	if (cur_framelen < IPV4_MIN_HEADER_LEN) {
+		return FLAG_OTHERS;
+	}
+
+	ip_hdr_len = IPV4_HLEN(ip_hdr);
+	if (IP_VER(ip_hdr) != IP_VER_4 || IPV4_PROT(ip_hdr) != IP_PROT_TCP) {
+		DHD_TRACE(("%s %d: Not IPv4 nor TCP! ip ver %d, prot %d\n",
+			__FUNCTION__, __LINE__, IP_VER(ip_hdr), IPV4_PROT(ip_hdr)));
+		return FLAG_OTHERS;
+	}
+
+	tcp_hdr = ip_hdr + ip_hdr_len;
+
+	flags = (uint8)tcp_hdr[TCP_FLAGS_OFFSET];
+
+	if (flags & TCP_FLAG_SYN) {
+		if (flags & TCP_FLAG_ACK) {
+			return FLAG_SYNCACK;
+		}
+		return FLAG_SYNC;
+	}
+	return FLAG_OTHERS;
+}
+#endif /* DHDTCPSYNC_FLOOD_BLK */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_ip.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_ip.h
@@ -0,0 +1,115 @@
+/*
+ * Header file describing the common ip parser function.
+ *
+ * Provides type definitions and function prototypes used to parse ip packet.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef _dhd_ip_h_
+#define _dhd_ip_h_
+
+#if defined(DHDTCPACK_SUPPRESS) || defined(DHDTCPSYNC_FLOOD_BLK)
+#include <dngl_stats.h>
+#include <bcmutils.h>
+#include <dhd.h>
+#endif /* DHDTCPACK_SUPPRESS || DHDTCPSYNC_FLOOD_BLK */
+
+typedef enum pkt_frag
+{
+	DHD_PKT_FRAG_NONE = 0,
+	DHD_PKT_FRAG_FIRST,
+	DHD_PKT_FRAG_CONT,
+	DHD_PKT_FRAG_LAST
+} pkt_frag_t;
+
+extern pkt_frag_t pkt_frag_info(osl_t *osh, void *p);
+
+#ifdef DHDTCPSYNC_FLOOD_BLK
+typedef enum tcp_hdr_flags {
+	FLAG_SYNC,
+	FLAG_SYNCACK,
+	FLAG_RST,
+	FLAG_OTHERS
+} tcp_hdr_flag_t;
+
+extern tcp_hdr_flag_t dhd_tcpdata_get_flag(dhd_pub_t *dhdp, void *pkt);
+#endif /* DHDTCPSYNC_FLOOD_BLK */
+
+#ifdef DHDTCPACK_SUPPRESS
+#define	TCPACKSZMIN	(ETHER_HDR_LEN + IPV4_MIN_HEADER_LEN + TCP_MIN_HEADER_LEN)
+/* Size of MAX possible TCP ACK packet. Extra bytes for IP/TCP option fields */
+#define	TCPACKSZMAX	(TCPACKSZMIN + 100)
+
+/* Max number of TCP streams that have own src/dst IP addrs and TCP ports */
+#ifndef TCPACK_INFO_MAXNUM
+#define TCPACK_INFO_MAXNUM 40
+#endif
+#ifndef TCPDATA_INFO_MAXNUM
+#define TCPDATA_INFO_MAXNUM 40
+#endif
+#define TCPDATA_PSH_INFO_MAXNUM (16 * TCPDATA_INFO_MAXNUM)
+
+#define TCPDATA_INFO_TIMEOUT 5000	/* Remove tcpdata_info if inactive for this time (in ms) */
+
+#define DEFAULT_TCPACK_SUPP_RATIO 3
+#ifndef CUSTOM_TCPACK_SUPP_RATIO
+#define CUSTOM_TCPACK_SUPP_RATIO DEFAULT_TCPACK_SUPP_RATIO
+#endif /* CUSTOM_TCPACK_SUPP_RATIO */
+
+#define DEFAULT_TCPACK_DELAY_TIME 10 /* ms */
+#ifndef CUSTOM_TCPACK_DELAY_TIME
+#define CUSTOM_TCPACK_DELAY_TIME DEFAULT_TCPACK_DELAY_TIME
+#endif /* CUSTOM_TCPACK_DELAY_TIME */
+
+extern int dhd_tcpack_suppress_set(dhd_pub_t *dhdp, uint8 on);
+extern void dhd_tcpack_info_tbl_clean(dhd_pub_t *dhdp);
+extern int dhd_tcpack_check_xmit(dhd_pub_t *dhdp, void *pkt);
+extern bool dhd_tcpack_suppress(dhd_pub_t *dhdp, void *pkt);
+extern bool dhd_tcpdata_info_get(dhd_pub_t *dhdp, void *pkt);
+extern bool dhd_tcpack_hold(dhd_pub_t *dhdp, void *pkt, int ifidx);
+/* #define DHDTCPACK_SUP_DBG */
+#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
+extern counter_tbl_t tack_tbl;
+#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
+#endif /* DHDTCPACK_SUPPRESS */
+
+#endif /* _dhd_ip_h_ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -0,0 +1,24641 @@
+/*
+ * Broadcom Dongle Host Driver (DHD), Linux-specific network interface.
+ * Basically selected code segments from usb-cdc.c and usb-rndis.c
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <linux/ctype.h>
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+#ifdef SHOW_LOGTRACE
+#include <linux/syscalls.h>
+#include <event_log.h>
+#endif /* SHOW_LOGTRACE */
+
+#if defined(PCIE_FULL_DONGLE) || defined(SHOW_LOGTRACE)
+#include <bcmmsgbuf.h>
+#endif /* PCIE_FULL_DONGLE */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/etherdevice.h>
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/ethtool.h>
+#include <linux/fcntl.h>
+#include <linux/ip.h>
+#include <linux/reboot.h>
+#include <linux/notifier.h>
+#include <linux/irq.h>
+#if defined(CONFIG_TIZEN)
+#include <linux/net_stat_tizen.h>
+#endif /* CONFIG_TIZEN */
+#include <net/addrconf.h>
+#ifdef ENABLE_ADAPTIVE_SCHED
+#include <linux/cpufreq.h>
+#endif /* ENABLE_ADAPTIVE_SCHED */
+#include <linux/rtc.h>
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+#include <dhd_linux_priv.h>
+
+#include <epivers.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <bcmdevs.h>
+#include <bcmdevs_legacy.h>    /* need to still support chips no longer in trunk firmware */
+#include <bcmiov.h>
+#include <bcmstdlib_s.h>
+
+#include <ethernet.h>
+#include <bcmevent.h>
+#include <vlan.h>
+#include <802.3.h>
+
+#include <dhd_linux_wq.h>
+#include <dhd.h>
+#include <dhd_linux_tx.h>
+#include <dhd_linux.h>
+#include <dhd_linux_pktdump.h>
+#ifdef DHD_WET
+#include <dhd_wet.h>
+#endif /* DHD_WET */
+#ifdef PCIE_FULL_DONGLE
+#include <dhd_flowring.h>
+#endif
+#include <dhd_bus.h>
+#include <dhd_proto.h>
+#include <dhd_config.h>
+#ifdef WL_ESCAN
+#include <wl_escan.h>
+#endif
+#include <dhd_dbg.h>
+#include <dhd_dbg_ring.h>
+#include <dhd_debug.h>
+#ifdef DHD_LOG_DUMP
+#include <dhd_log_dump.h>
+#endif
+#if defined(WL_CFG80211)
+#include <wl_cfg80211.h>
+#include <wl_cfgvif.h>
+#ifdef WL_BAM
+#include <wl_bam.h>
+#endif	/* WL_BAM */
+#endif	/* WL_CFG80211 */
+#ifdef PNO_SUPPORT
+#include <dhd_pno.h>
+#endif
+#ifdef RTT_SUPPORT
+#include <dhd_rtt.h>
+#endif
+
+#include <dhd_linux_sock_qos.h>
+
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+#endif
+
+#ifdef DHD_WMF
+#include <dhd_wmf_linux.h>
+#endif /* DHD_WMF */
+
+#ifdef DHD_L2_FILTER
+#include <bcmicmp.h>
+#include <bcm_l2_filter.h>
+#include <dhd_l2_filter.h>
+#endif /* DHD_L2_FILTER */
+
+#ifdef DHD_PSTA
+#include <dhd_psta.h>
+#endif /* DHD_PSTA */
+
+#ifdef AMPDU_VO_ENABLE
+/* XXX: Enabling VO AMPDU to reduce FER */
+#include <802.1d.h>
+#endif /* AMPDU_VO_ENABLE */
+
+#if defined(DHDTCPACK_SUPPRESS) || defined(DHDTCPSYNC_FLOOD_BLK)
+#include <dhd_ip.h>
+#endif /* DHDTCPACK_SUPPRESS || DHDTCPSYNC_FLOOD_BLK */
+#include <dhd_daemon.h>
+#ifdef DHD_PKT_LOGGING
+#include <dhd_pktlog.h>
+#endif /* DHD_PKT_LOGGING */
+#ifdef DHD_4WAYM4_FAIL_DISCONNECT
+#include <eapol.h>
+#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
+#ifdef DHD_DEBUG_PAGEALLOC
+typedef void (*page_corrupt_cb_t)(void *handle, void *addr_corrupt, size_t len);
+void dhd_page_corrupt_cb(void *handle, void *addr_corrupt, size_t len);
+extern void register_page_corrupt_cb(page_corrupt_cb_t cb, void* handle);
+#endif /* DHD_DEBUG_PAGEALLOC */
+
+#ifdef ENABLE_DHD_GRO
+#include <net/sch_generic.h>
+#endif /* ENABLE_DHD_GRO */
+
+#ifndef EVENT_LOG_RATE_HC_THRESHOLD
+/* FW checking period is 1 second, and once log quantity exceeds this
+ * threshold, FW will directly trap to indicate, so enlarge this
+ */
+#ifdef DHD_DEBUG
+#define EVENT_LOG_RATE_HC_THRESHOLD    99999999
+#else /* DHD_DEBUG */
+#define EVENT_LOG_RATE_HC_THRESHOLD    50000
+#endif /* DHD_DEBUG */
+#endif /* EVENT_LOG_RATE_HC_THRESHOLD */
+
+#define IP_PROT_RESERVED	0xFF
+
+#ifdef DHD_MQ
+#define MQ_MAX_QUEUES AC_COUNT
+#define MQ_MAX_CPUS 16
+int enable_mq = TRUE;
+module_param(enable_mq, int, 0644);
+int mq_select_disable = FALSE;
+#endif
+
+#if defined(DHD_LB)
+#if !defined(PCIE_FULL_DONGLE)
+#error "DHD Loadbalancing only supported on PCIE_FULL_DONGLE"
+#endif /* !PCIE_FULL_DONGLE */
+#endif /* DHD_LB */
+
+#if defined(DHD_LB_RXP) || defined(DHD_LB_TXP) || defined(DHD_LB_STATS)
+#if !defined(DHD_LB)
+#error "DHD loadbalance derivatives are supported only if DHD_LB is defined"
+#endif /* !DHD_LB */
+#endif /* DHD_LB_RXP || DHD_LB_TXP || DHD_LB_STATS */
+
+#ifdef DHD_4WAYM4_FAIL_DISCONNECT
+static void dhd_m4_state_handler(struct work_struct * work);
+#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
+
+#if defined(DHD_FILE_DUMP_EVENT) && defined(DHD_FW_COREDUMP)
+static int dhd_wait_for_file_dump(dhd_pub_t *dhdp);
+#endif /* DHD_FILE_DUMP_EVENT && DHD_FW_COREDUMP */
+
+#ifdef FIX_CPU_MIN_CLOCK
+#include <linux/pm_qos.h>
+#endif /* FIX_CPU_MIN_CLOCK */
+
+#ifdef PROP_TXSTATUS
+#include <wlfc_proto.h>
+#include <dhd_wlfc.h>
+#endif
+
+#if defined(OEM_ANDROID)
+#include <wl_android.h>
+#endif
+
+/* Maximum STA per radio */
+#if defined(BCM_ROUTER_DHD)
+#define DHD_MAX_STA     128
+#else
+#define DHD_MAX_STA     32
+#endif /* BCM_ROUTER_DHD */
+
+#if defined(IFACE_HANG_FORCE_DEV_CLOSE) && defined(HANG_DELAY_BEFORE_DEV_CLOSE)
+#ifndef WAIT_FOR_DEV_CLOSE_MAX
+#define WAIT_FOR_DEV_CLOSE_MAX 50
+#endif /* WAIT_FOR_DEV_CLOSE_MAX */
+#endif /* IFACE_HANG_FORCE_DEV_CLOSE && HANG_DELAY_BEFORE_DEV_CLOSE */
+
+#if (defined(BCM_ROUTER_DHD) && defined(HNDCTF))
+#include <ctf/hndctf.h>
+
+#ifdef CTFPOOL
+#define RXBUFPOOLSZ		2048
+#define	RXBUFSZ			DHD_FLOWRING_RX_BUFPOST_PKTSZ /* packet data buffer size */
+#endif /* CTFPOOL */
+#endif /* BCM_ROUTER_DHD && HNDCTF */
+
+#if defined(BCMDBG) && defined(DHD_MACDBG)
+#include <dhd_macdbg.h>
+#endif /* BCMDBG && DHD_MACDBG */
+
+#ifdef DHD_EVENT_LOG_FILTER
+#include <dhd_event_log_filter.h>
+#endif /* DHD_EVENT_LOG_FILTER */
+
+#ifdef DHDTCPSYNC_FLOOD_BLK
+static void dhd_blk_tsfl_handler(struct work_struct * work);
+#endif /* DHDTCPSYNC_FLOOD_BLK */
+
+#ifdef DHD_TX_PROFILE
+#include <bcmarp.h>
+#include <bcmicmp.h>
+#include <bcmudp.h>
+#include <bcmproto.h>
+#endif /* defined(DHD_TX_PROFILE) */
+
+#ifdef CSI_SUPPORT
+#include <dhd_csi.h>
+#endif /* CSI_SUPPORT */
+
+#include <dhd_plat.h>
+
+#ifdef OEM_ANDROID
+#ifdef SET_RANDOM_MAC_SOFTAP
+#ifndef CONFIG_DHD_SET_RANDOM_MAC_VAL
+#define CONFIG_DHD_SET_RANDOM_MAC_VAL	0x001A11
+#endif
+static u32 vendor_oui = CONFIG_DHD_SET_RANDOM_MAC_VAL;
+#endif /* SET_RANDOM_MAC_SOFTAP */
+#endif /* OEM_ANDROID */
+
+#ifdef PKT_FILTER_SUPPORT
+uint dhd_pfaoe_enab = 0;
+module_param(dhd_pfaoe_enab, uint, 0660);
+#endif /* PKT_FILTER_SUPPORT */
+
+#ifdef DISABLE_6G_SUPPORT
+uint dhd_disable_6g = 0;
+module_param(dhd_disable_6g, uint, 0660);
+#endif /* DISABLE_6G_SUPPORT */
+
+#if defined(BCM_ROUTER_DHD)
+/*
+ * Queue budget: Minimum number of packets that a queue must be allowed to hold
+ * to prevent starvation.
+ */
+#define DHD_QUEUE_BUDGET_DEFAULT    (256)
+int dhd_queue_budget = DHD_QUEUE_BUDGET_DEFAULT;
+
+module_param(dhd_queue_budget, int, 0);
+
+/*
+ * Per station pkt threshold: Sum total of all packets in the backup queues of
+ * flowrings belonging to the station, not including packets already admitted
+ * to flowrings.
+ */
+#define DHD_STA_THRESHOLD_DEFAULT   (2048)
+int dhd_sta_threshold = DHD_STA_THRESHOLD_DEFAULT;
+module_param(dhd_sta_threshold, int, 0);
+
+/*
+ * Per interface pkt threshold: Sum total of all packets in the backup queues of
+ * flowrings belonging to the interface, not including packets already admitted
+ * to flowrings.
+ */
+#define DHD_IF_THRESHOLD_DEFAULT   (2048 * 32)
+int dhd_if_threshold = DHD_IF_THRESHOLD_DEFAULT;
+module_param(dhd_if_threshold, int, 0);
+#endif /* BCM_ROUTER_DHD */
+
+/* XXX: where does this belong? */
+/* XXX: this needs to reviewed for host OS. */
+const uint8 wme_fifo2ac[] = { 0, 1, 2, 3, 1, 1 };
+const uint8 prio2fifo[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
+
+#ifdef ARP_OFFLOAD_SUPPORT
+void aoe_update_host_ipv4_table(dhd_pub_t *dhd_pub, u32 ipa, bool add, int idx);
+static int dhd_inetaddr_notifier_call(struct notifier_block *this,
+	unsigned long event, void *ptr);
+static struct notifier_block dhd_inetaddr_notifier = {
+	.notifier_call = dhd_inetaddr_notifier_call
+};
+/* to make sure we won't register the same notifier twice, otherwise a loop is likely to be
+ * created in the kernel notifier link list (with 'next' pointing to itself)
+ */
+static bool dhd_inetaddr_notifier_registered = FALSE;
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+#if defined(CONFIG_IPV6) && defined(IPV6_NDO_SUPPORT)
+int dhd_inet6addr_notifier_call(struct notifier_block *this,
+	unsigned long event, void *ptr);
+static struct notifier_block dhd_inet6addr_notifier = {
+	.notifier_call = dhd_inet6addr_notifier_call
+};
+/* to make sure we won't register the same notifier twice, otherwise a loop is likely to be
+ * created in kernel notifier link list (with 'next' pointing to itself)
+ */
+static bool dhd_inet6addr_notifier_registered = FALSE;
+#endif /* CONFIG_IPV6 && IPV6_NDO_SUPPORT */
+
+#if defined(CONFIG_PM_SLEEP)
+#include <linux/suspend.h>
+volatile bool dhd_mmc_suspend = FALSE;
+DECLARE_WAIT_QUEUE_HEAD(dhd_dpc_wait);
+#ifdef ENABLE_WAKEUP_PKT_DUMP
+volatile bool dhd_mmc_wake = FALSE;
+long long temp_raw;
+#endif /* ENABLE_WAKEUP_PKT_DUMP */
+#endif /* defined(CONFIG_PM_SLEEP) */
+
+#if defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID) || defined(FORCE_WOWLAN)
+extern void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable);
+#endif /* defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID) */
+#if defined(OEM_ANDROID)
+static void dhd_hang_process(struct work_struct *work_data);
+#endif /* OEM_ANDROID */
+MODULE_LICENSE("GPL and additional rights");
+
+#if defined(MULTIPLE_SUPPLICANT)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25))
+DEFINE_MUTEX(_dhd_mutex_lock_);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25)) */
+#endif
+
+#include <dhd_bus.h>
+
+/* XXX Set up an MTU change notifier per linux/notifier.h? */
+#ifndef PROP_TXSTATUS
+#define DBUS_RX_BUFFER_SIZE_DHD(net)	(net->mtu + net->hard_header_len + dhd->pub.hdrlen)
+#else
+#define DBUS_RX_BUFFER_SIZE_DHD(net)	(net->mtu + net->hard_header_len + dhd->pub.hdrlen + 128)
+#endif
+
+#ifdef PROP_TXSTATUS
+extern bool dhd_wlfc_skip_fc(void * dhdp, uint8 idx);
+extern void dhd_wlfc_plat_init(void *dhd);
+extern void dhd_wlfc_plat_deinit(void *dhd);
+#endif /* PROP_TXSTATUS */
+#ifdef USE_DYNAMIC_F2_BLKSIZE
+extern uint sd_f2_blocksize;
+extern int dhdsdio_func_blocksize(dhd_pub_t *dhd, int function_num, int block_size);
+#endif /* USE_DYNAMIC_F2_BLKSIZE */
+
+/* Linux wireless extension support */
+#if defined(WL_WIRELESS_EXT)
+#include <wl_iw.h>
+#endif /* defined(WL_WIRELESS_EXT) */
+
+#if defined(CONFIG_PARTIALSUSPEND_SLP) && !defined(DHD_USE_PM_SLEEP)
+/* XXX SLP use defferent earlysuspend header file and some functions
+ * But most of meaning is same as Android
+ */
+#include <linux/partialsuspend_slp.h>
+#define CONFIG_HAS_EARLYSUSPEND
+#define DHD_USE_EARLYSUSPEND
+#define register_early_suspend		register_pre_suspend
+#define unregister_early_suspend	unregister_pre_suspend
+#define early_suspend				pre_suspend
+#define EARLY_SUSPEND_LEVEL_BLANK_SCREEN		50
+#else
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
+#include <linux/earlysuspend.h>
+#endif /* defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) */
+#endif /* CONFIG_PARTIALSUSPEND_SLP && !DHD_USE_PM_SLEEP */
+
+#if defined(APF)
+void dhd_dev_pkt_filter_stats(struct net_device *ndev, int pkt_filter_id);
+static int _dhd_apf_add_filter(struct net_device *ndev, uint32 filter_id, u8* program,
+	uint32 program_len);
+static int _dhd_apf_config_filter(struct net_device *ndev, uint32 filter_id, uint32 mode,
+	uint32 enable);
+static int _dhd_apf_delete_filter(struct net_device *ndev, uint32 filter_id);
+static int _dhd_apf_read_filter_data(struct net_device *ndev, uint32 filter_id, u8* buf,
+	uint32 buf_len);
+#endif /* APF */
+
+#ifdef DHD_FW_COREDUMP
+static void dhd_mem_dump(void *dhd_info, void *event_info, u8 event);
+#endif /* DHD_FW_COREDUMP */
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+#include <linux/workqueue.h>
+#include <linux/pm_runtime.h>
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+#ifdef DHD_DEBUG_UART
+#include <linux/kmod.h>
+#define DHD_DEBUG_UART_EXEC_PATH	"/system/bin/wldu"
+static void dhd_debug_uart_exec_rd(void *handle, void *event_info, u8 event);
+static void dhd_debug_uart_exec(dhd_pub_t *dhdp, char *cmd);
+#endif	/* DHD_DEBUG_UART */
+
+static int dhd_reboot_callback(struct notifier_block *this, unsigned long code, void *unused);
+static struct notifier_block dhd_reboot_notifier = {
+	.notifier_call = dhd_reboot_callback,
+	.priority = 1,
+};
+
+dhd_pub_t	*g_dhd_pub = NULL;
+
+#if defined(BT_OVER_SDIO)
+#include "dhd_bt_interface.h"
+#endif /* defined (BT_OVER_SDIO) */
+
+#if defined(DHD_ENABLE_S2MPU)
+#include <soc/samsung/exynos-s2mpu.h>
+#endif /* DHD_ENABLE_S2MPU */
+
+#if defined(DHD_HWTSTAMP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
+#include <linux/net_tstamp.h>
+#endif /* defined(DHD_HWTSTAMP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)) */
+
+#ifdef WL_STATIC_IF
+bool dhd_is_static_ndev(dhd_pub_t *dhdp, struct net_device *ndev);
+#endif /* WL_STATIC_IF */
+
+atomic_t exit_in_progress = ATOMIC_INIT(0);
+atomic_t reboot_in_progress = ATOMIC_INIT(-1);
+
+static void dhd_process_daemon_msg(struct sk_buff *skb);
+static void dhd_destroy_to_notifier_skt(void);
+static int dhd_create_to_notifier_skt(void);
+static struct sock *nl_to_event_sk = NULL;
+int sender_pid = 0;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
+struct netlink_kernel_cfg dhd_netlink_cfg = {
+	.groups = 1,
+	.input = dhd_process_daemon_msg,
+};
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) */
+
+#if defined(BT_OVER_SDIO)
+/* Flag to indicate if driver is initialized */
+uint dhd_driver_init_done = TRUE;
+#else
+/* Flag to indicate if driver is initialized */
+uint dhd_driver_init_done = FALSE;
+#endif
+/* Flag to indicate if we should download firmware on driver load */
+uint dhd_download_fw_on_driverload = TRUE;
+
+/* Definitions to provide path to the firmware and nvram
+ * example nvram_path[MOD_PARAM_PATHLEN]="/projects/wlan/nvram.txt"
+ */
+#ifdef DHD_LINUX_STD_FW_API
+char firmware_path[MOD_PARAM_PATHLEN] = DHD_FW_NAME;
+char nvram_path[MOD_PARAM_PATHLEN] = DHD_NVRAM_NAME;
+char clm_path[MOD_PARAM_PATHLEN];
+char config_path[MOD_PARAM_PATHLEN];
+#else
+char firmware_path[MOD_PARAM_PATHLEN] = CONFIG_BCMDHD_FW_PATH;
+char nvram_path[MOD_PARAM_PATHLEN] = CONFIG_BCMDHD_NVRAM_PATH;
+char clm_path[MOD_PARAM_PATHLEN];
+char config_path[MOD_PARAM_PATHLEN];
+#endif /* DHD_LINUX_STD_FW_API */
+char signature_path[MOD_PARAM_PATHLEN];
+#ifdef DHD_UCODE_DOWNLOAD
+char ucode_path[MOD_PARAM_PATHLEN];
+#endif /* DHD_UCODE_DOWNLOAD */
+
+module_param_string(clm_path, clm_path, MOD_PARAM_PATHLEN, 0660);
+
+/* backup buffer for firmware and nvram path */
+char fw_bak_path[MOD_PARAM_PATHLEN];
+char nv_bak_path[MOD_PARAM_PATHLEN];
+
+/* information string to keep firmware, chio, cheip version info visiable from log */
+char info_string[MOD_PARAM_INFOLEN];
+module_param_string(info_string, info_string, MOD_PARAM_INFOLEN, 0444);
+
+#ifdef SYNA_SAR_CUSTOMER_PARAMETER
+char config_sar_path[MOD_PARAM_PATHLEN] = CONFIG_BCMDHD_CONFIG_SAR_PATH;
+module_param_string(config_sar_path, config_sar_path, MOD_PARAM_PATHLEN, 0660);
+#endif /* SYNA_SAR_CUSTOMER_PARAMETER */
+int op_mode = 0;
+int disable_proptx = 0;
+module_param(op_mode, int, 0644);
+#if defined(OEM_ANDROID)
+extern int wl_control_wl_start(struct net_device *dev);
+#if defined(BCMLXSDMMC) || defined(BCMDBUS)
+struct semaphore dhd_registration_sem;
+#endif /* BCMXSDMMC */
+#endif /* defined(OEM_ANDROID) */
+void dhd_generate_rand_mac_addr(struct ether_addr *ea_addr);
+
+#ifdef EWP_EDL
+int host_edl_support = TRUE;
+module_param(host_edl_support, int, 0644);
+#endif
+
+/* deferred handlers */
+static void dhd_ifadd_event_handler(void *handle, void *event_info, u8 event);
+static void dhd_ifdel_event_handler(void *handle, void *event_info, u8 event);
+static void dhd_set_mac_addr_handler(void *handle, void *event_info, u8 event);
+static void dhd_set_mcast_list_handler(void *handle, void *event_info, u8 event);
+static void dhd_ndev_upd_features_handler(void *handle, void *event_info, u8 event);
+#ifdef BCM_ROUTER_DHD
+static void dhd_inform_dhd_monitor_handler(void *handle, void *event_info, u8 event);
+#endif
+
+#if defined(CONFIG_DHD_USE_STATIC_BUF) && defined(DHD_STATIC_IN_DRIVER)
+extern int dhd_static_buf_init(void);
+extern void dhd_static_buf_exit(void);
+#endif /* CONFIG_DHD_USE_STATIC_BUF && DHD_STATIC_IN_DRIVER */
+#ifdef DHD_UPDATE_INTF_MAC
+static void dhd_ifupdate_event_handler(void *handle, void *event_info, u8 event);
+#endif /* DHD_UPDATE_INTF_MAC */
+#if defined(CONFIG_IPV6) && defined(IPV6_NDO_SUPPORT)
+static void dhd_inet6_work_handler(void *dhd_info, void *event_data, u8 event);
+#endif /* CONFIG_IPV6 && IPV6_NDO_SUPPORT */
+#ifdef WL_CFG80211
+extern void dhd_netdev_free(struct net_device *ndev);
+#endif /* WL_CFG80211 */
+static dhd_if_t * dhd_get_ifp_by_ndev(dhd_pub_t *dhdp, struct net_device *ndev);
+#if defined(WLDWDS) && defined(FOURADDR_AUTO_BRG)
+static void dhd_bridge_dev_set(dhd_info_t *dhd, int ifidx, struct net_device *dev);
+#endif /* defiend(WLDWDS) && defined(FOURADDR_AUTO_BRG) */
+
+#if (defined(DHD_WET) || defined(DHD_MCAST_REGEN) || defined(DHD_L2_FILTER))
+/* update rx_pkt_chainable state of dhd interface */
+static void dhd_update_rx_pkt_chainable_state(dhd_pub_t* dhdp, uint32 idx);
+#endif /* DHD_WET || DHD_MCAST_REGEN || DHD_L2_FILTER */
+
+/* Error bits */
+module_param(dhd_msg_level, int, 0644);
+#if defined(WL_WIRELESS_EXT)
+module_param(iw_msg_level, int, 0);
+#endif
+#ifdef WL_CFG80211
+module_param(wl_dbg_level, int, 0);
+#endif
+module_param(android_msg_level, int, 0);
+module_param(config_msg_level, int, 0);
+
+#ifdef ARP_OFFLOAD_SUPPORT
+/* ARP offload agent mode : Enable ARP Host Auto-Reply and ARP Peer Auto-Reply */
+/* XXX ARP HOST Auto Reply can cause dongle trap at VSDB situation */
+/* XXX ARP OL SNOOP can be used to more good quility */
+
+#ifdef ENABLE_ARP_SNOOP_MODE
+uint dhd_arp_mode = (ARP_OL_AGENT | ARP_OL_PEER_AUTO_REPLY | ARP_OL_SNOOP | ARP_OL_HOST_AUTO_REPLY |
+		ARP_OL_UPDATE_HOST_CACHE);
+#else
+uint dhd_arp_mode = ARP_OL_AGENT | ARP_OL_PEER_AUTO_REPLY | ARP_OL_UPDATE_HOST_CACHE;
+#endif /* ENABLE_ARP_SNOOP_MODE */
+
+module_param(dhd_arp_mode, uint, 0);
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+/* Disable Prop tx */
+module_param(disable_proptx, int, 0644);
+/* load firmware and/or nvram values from the filesystem */
+module_param_string(firmware_path, firmware_path, MOD_PARAM_PATHLEN, 0660);
+module_param_string(nvram_path, nvram_path, MOD_PARAM_PATHLEN, 0660);
+module_param_string(config_path, config_path, MOD_PARAM_PATHLEN, 0);
+module_param_string(signature_path, signature_path, MOD_PARAM_PATHLEN, 0660);
+#ifdef DHD_UCODE_DOWNLOAD
+module_param_string(ucode_path, ucode_path, MOD_PARAM_PATHLEN, 0660);
+#endif /* DHD_UCODE_DOWNLOAD */
+
+/* wl event forwarding */
+#ifdef WL_EVENT_ENAB
+uint wl_event_enable = true;
+#else
+uint wl_event_enable = false;
+#endif /* WL_EVENT_ENAB */
+module_param(wl_event_enable, uint, 0660);
+
+/* wl event forwarding */
+#ifdef LOGTRACE_PKT_SENDUP
+uint logtrace_pkt_sendup = true;
+#else
+uint logtrace_pkt_sendup = false;
+#endif /* LOGTRACE_PKT_SENDUP */
+module_param(logtrace_pkt_sendup, uint, 0660);
+
+/* Watchdog interval */
+/* extend watchdog expiration to 2 seconds when DPC is running */
+#define WATCHDOG_EXTEND_INTERVAL (2000)
+
+uint dhd_watchdog_ms = CUSTOM_DHD_WATCHDOG_MS;
+module_param(dhd_watchdog_ms, uint, 0);
+
+#if defined(DHD_DEBUG)
+/* Console poll interval */
+#ifdef SYNAINTERNAL
+uint dhd_console_ms = 250;
+#else
+uint dhd_console_ms = CUSTOM_DHD_CONSOLE_MS;
+#endif /* SYNAINTERNAL */
+module_param(dhd_console_ms, uint, 0644);
+#else
+uint dhd_console_ms = 0;
+#endif /* DHD_DEBUG */
+
+uint dhd_slpauto = TRUE;
+module_param(dhd_slpauto, uint, 0);
+
+#ifdef PKT_FILTER_SUPPORT
+/* Global Pkt filter enable control */
+uint dhd_pkt_filter_enable = TRUE;
+module_param(dhd_pkt_filter_enable, uint, 0);
+#endif
+
+/* Pkt filter init setup */
+uint dhd_pkt_filter_init = 0;
+module_param(dhd_pkt_filter_init, uint, 0);
+
+/* Pkt filter mode control */
+#ifdef GAN_LITE_NAT_KEEPALIVE_FILTER
+uint dhd_master_mode = FALSE;
+#else
+uint dhd_master_mode = FALSE;
+#endif /* GAN_LITE_NAT_KEEPALIVE_FILTER */
+module_param(dhd_master_mode, uint, 0);
+
+int dhd_watchdog_prio = 0;
+module_param(dhd_watchdog_prio, int, 0);
+
+/* DPC thread priority */
+int dhd_dpc_prio = CUSTOM_DPC_PRIO_SETTING;
+module_param(dhd_dpc_prio, int, 0);
+
+#if !defined(BCMDBUS)
+extern int dhd_dongle_ramsize;
+module_param(dhd_dongle_ramsize, int, 0);
+#endif /* !BCMDBUS */
+
+#ifdef WL_CFG80211
+int passive_channel_skip = 0;
+module_param(passive_channel_skip, int, (S_IRUSR|S_IWUSR));
+#endif /* WL_CFG80211 */
+static dhd_if_t * dhd_get_ifp_by_ndev(dhd_pub_t *dhdp, struct net_device *ndev);
+
+#ifdef DHD_MSI_SUPPORT
+uint enable_msi = TRUE;
+module_param(enable_msi, uint, 0);
+#endif /* PCIE_FULL_DONGLE */
+
+#ifdef DHD_SSSR_DUMP
+int dhdpcie_sssr_dump_get_before_after_len(dhd_pub_t *dhd, uint32 *arr_len);
+module_param(sssr_enab, uint, 0);
+module_param(fis_enab, uint, 0);
+#endif /* DHD_SSSR_DUMP */
+
+/* Keep track of number of instances */
+static int dhd_found = 0;
+static int instance_base = 0; /* Starting instance number */
+module_param(instance_base, int, 0644);
+
+#if defined(DHD_LB_RXP) && defined(PCIE_FULL_DONGLE)
+/*
+ * Rx path process budget(dhd_napi_weight) number of packets in one go and hands over
+ * the packets to network stack.
+ *
+ * dhd_dpc tasklet is the producer(packets received from dongle) and dhd_napi_poll()
+ * is the consumer. The maximum number of packets that can be received from the dongle
+ * at any given point of time are D2HRING_RXCMPLT_MAX_ITEM.
+ * Also DHD will always post fresh rx buffers to dongle while processing rx completions.
+ *
+ * The consumer must consume the packets at equal are better rate than the producer.
+ * i.e if dhd_napi_poll() does not process at the same rate as the producer(dhd_dpc),
+ * rx_process_queue depth increases, which can even consume the entire system memory.
+ * Such situation will be tacken care by rx flow control.
+ *
+ * Device drivers are strongly advised to not use bigger value than NAPI_POLL_WEIGHT
+ */
+static int dhd_napi_weight = NAPI_POLL_WEIGHT;
+module_param(dhd_napi_weight, int, 0644);
+#endif /* DHD_LB_RXP && PCIE_FULL_DONGLE */
+
+#ifdef PCIE_FULL_DONGLE
+extern uint h2d_max_txpost;
+module_param(h2d_max_txpost, uint, 0644);
+
+extern uint h2d_htput_max_txpost;
+module_param(h2d_htput_max_txpost, uint, 0644);
+
+extern uint d2h_max_txcpl;
+module_param(d2h_max_txcpl, uint, 0644);
+
+extern uint h2d_max_ctrlpost;
+module_param(h2d_max_ctrlpost, uint, 0644);
+extern uint d2h_max_ctrlcpl;
+module_param(d2h_max_ctrlcpl, uint, 0644);
+
+extern uint h2d_max_rxpost;
+module_param(h2d_max_rxpost, uint, 0644);
+extern uint d2h_max_rxcpl;
+module_param(d2h_max_rxcpl, uint, 0644);
+
+extern uint rx_buf_burst;
+module_param(rx_buf_burst, uint, 0644);
+
+extern uint rx_bufpost_threshold;
+module_param(rx_bufpost_threshold, uint, 0644);
+
+#ifdef AGG_H2D_DB
+extern bool agg_h2d_db_enab;
+module_param(agg_h2d_db_enab, bool, 0644);
+extern uint agg_h2d_db_timeout;
+module_param(agg_h2d_db_timeout, uint, 0644);
+extern uint agg_h2d_db_inflight_thresh;
+module_param(agg_h2d_db_inflight_thresh, uint, 0644);
+#endif /* AGG_H2D_DB */
+
+extern uint dma_ring_indices;
+module_param(dma_ring_indices, uint, 0644);
+
+extern bool h2d_phase;
+module_param(h2d_phase, bool, 0644);
+extern bool force_trap_bad_h2d_phase;
+module_param(force_trap_bad_h2d_phase, bool, 0644);
+#endif /* PCIE_FULL_DONGLE */
+
+#ifdef FORCE_TPOWERON
+/*
+ * On Fire's reference platform, coming out of L1.2,
+ * there is a constant delay of 45us between CLKREQ# and stable REFCLK
+ * Due to this delay, with tPowerOn < 50
+ * there is a chance of the refclk sense to trigger on noise.
+ *
+ * 0x29 when written to L1SSControl2 translates to 50us.
+ */
+#define FORCE_TPOWERON_50US 0x29
+uint32 tpoweron_scale = FORCE_TPOWERON_50US; /* default 50us */
+module_param(tpoweron_scale, uint, 0644);
+#endif /* FORCE_TPOWERON */
+
+#ifdef SHOW_LOGTRACE
+#ifdef DHD_LINUX_STD_FW_API
+static char *logstrs_path = "logstrs.bin";
+char *st_str_file_path = "rtecdc.bin";
+static char *map_file_path = "rtecdc.map";
+static char *rom_st_str_file_path = "roml.bin";
+static char *rom_map_file_path = "roml.map";
+#else
+static char *logstrs_path = PLATFORM_PATH"logstrs.bin";
+char *st_str_file_path = PLATFORM_PATH"rtecdc.bin";
+static char *map_file_path = PLATFORM_PATH"rtecdc.map";
+static char *rom_st_str_file_path = PLATFORM_PATH"roml.bin";
+static char *rom_map_file_path = PLATFORM_PATH"roml.map";
+#endif /* DHD_LINUX_STD_FW_API */
+
+static char *ram_file_str = "rtecdc";
+static char *rom_file_str = "roml";
+
+module_param(logstrs_path, charp, S_IRUGO);
+module_param(st_str_file_path, charp, S_IRUGO);
+module_param(map_file_path, charp, S_IRUGO);
+module_param(rom_st_str_file_path, charp, S_IRUGO);
+module_param(rom_map_file_path, charp, S_IRUGO);
+
+static int dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp);
+static int dhd_read_map(osl_t *osh, char *fname, uint32 *ramstart, uint32 *rodata_start,
+	uint32 *rodata_end);
+static int dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file,
+	char *map_file);
+#endif /* SHOW_LOGTRACE */
+
+#ifdef D2H_MINIDUMP
+void dhd_d2h_minidump(dhd_pub_t *dhdp);
+#endif /* D2H_MINIDUMP */
+
+#ifdef DHD_TX_PROFILE
+/* process layer 3 headers, to ultimately determine if a
+ * dhd_tx_profile_protocol_t matches
+ */
+static int process_layer3_headers(uint8 **p, int plen, uint16 *type);
+
+/* process layer 2 headers, to ultimately determine if a
+ * dhd_tx_profile_protocol_t matches
+ */
+static int process_layer2_headers(uint8 **p, int *plen, uint16 *type, bool is_host_sfhllc);
+
+/* whether or not a dhd_tx_profile_protocol_t matches with data in a packet */
+bool dhd_protocol_matches_profile(uint8 *p, int plen, const
+		dhd_tx_profile_protocol_t *proto, bool is_host_sfhllc);
+#endif /* defined(DHD_TX_PROFILE) */
+
+#define PATH_BANDLOCK_INFO PLATFORM_PATH".bandlock.info"
+
+static void dhd_set_bandlock(dhd_pub_t * dhd);
+
+#ifdef WL_CFGVENDOR_SEND_ALERT_EVENT
+void dhd_alert_process(struct work_struct *work_data);
+#endif /* WL_CFGVENDOR_SEND_ALERT_EVENT */
+
+#ifdef USE_WFA_CERT_CONF
+int g_frameburst = 1;
+#endif /* USE_WFA_CERT_CONF */
+
+static int dhd_get_pend_8021x_cnt(dhd_info_t *dhd);
+
+#ifdef PCIE_FULL_DONGLE
+#define DHD_IF_STA_LIST_LOCK_INIT(lock) spin_lock_init(lock)
+
+#if defined(DHD_IGMP_UCQUERY) || defined(DHD_UCAST_UPNP)
+static struct list_head * dhd_sta_list_snapshot(dhd_info_t *dhd, dhd_if_t *ifp,
+	struct list_head *snapshot_list);
+static void dhd_sta_list_snapshot_free(dhd_info_t *dhd, struct list_head *snapshot_list);
+#define DHD_IF_WMF_UCFORWARD_LOCK(dhd, ifp, slist) ({ dhd_sta_list_snapshot(dhd, ifp, slist); })
+#define DHD_IF_WMF_UCFORWARD_UNLOCK(dhd, slist) ({ dhd_sta_list_snapshot_free(dhd, slist); })
+#endif /* DHD_IGMP_UCQUERY || DHD_UCAST_UPNP */
+#endif /* PCIE_FULL_DONGLE */
+
+/* hostwake delay after d3 enter in ms */
+#define D3_HOSTWAKE_DELAY	200
+
+/* Control fw roaming */
+#ifdef BCMCCX
+uint dhd_roam_disable = 0;
+#else
+#ifdef OEM_ANDROID
+uint dhd_roam_disable = 0;
+#else
+uint dhd_roam_disable = 1;
+#endif
+#endif /* BCMCCX */
+
+#ifdef BCMDBGFS
+extern void dhd_dbgfs_init(dhd_pub_t *dhdp);
+extern void dhd_dbgfs_remove(void);
+#endif
+
+#ifdef BCMPCIE
+/* Tx/Rx/Ctrl cpl/post bounds */
+extern uint dhd_tx_cpl_bound;
+extern uint dhd_rx_cpl_post_bound;
+extern uint dhd_tx_post_bound;
+extern uint dhd_ctrl_cpl_post_bound;
+
+module_param(dhd_tx_cpl_bound, uint, 0);
+module_param(dhd_rx_cpl_post_bound, uint, 0);
+module_param(dhd_tx_post_bound, uint, 0);
+module_param(dhd_ctrl_cpl_post_bound, uint, 0);
+#endif /* BCMPCIE */
+
+/* Enable TX status metadta report: 0=disable 1=enable 2=debug */
+static uint pcie_txs_metadata_enable = 0;
+module_param(pcie_txs_metadata_enable, int, 0);
+
+/* Control radio state */
+uint dhd_radio_up = 1;
+
+/* Network inteface name */
+char iface_name[IFNAMSIZ] = {'\0'};
+module_param_string(iface_name, iface_name, IFNAMSIZ, 0);
+
+/* The following are specific to the SDIO dongle */
+
+/* IOCTL response timeout */
+int dhd_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT;
+
+/* DS Exit response timeout */
+int ds_exit_timeout_msec = DS_EXIT_TIMEOUT;
+
+/* Idle timeout for backplane clock */
+int dhd_idletime = DHD_IDLETIME_TICKS;
+module_param(dhd_idletime, int, 0);
+
+/* Use polling */
+uint dhd_poll = FALSE;
+module_param(dhd_poll, uint, 0);
+
+/* Use interrupts */
+uint dhd_intr = TRUE;
+module_param(dhd_intr, uint, 0);
+
+/* SDIO Drive Strength (in milliamps) */
+uint dhd_sdiod_drive_strength = 6;
+module_param(dhd_sdiod_drive_strength, uint, 0);
+
+#ifdef BCMSDIO
+/* Tx/Rx bounds */
+extern uint dhd_txbound;
+extern uint dhd_rxbound;
+module_param(dhd_txbound, uint, 0);
+module_param(dhd_rxbound, uint, 0);
+
+/* Deferred transmits */
+extern uint dhd_deferred_tx;
+module_param(dhd_deferred_tx, uint, 0);
+
+#endif /* BCMSDIO */
+
+#ifdef BCMSLTGT
+#ifdef BCMFPGA_HW
+/* For FPGA use fixed htclkration as 30 */
+uint htclkratio = 30;
+#else
+uint htclkratio = 1;
+#endif /* BCMFPGA_HW */
+module_param(htclkratio, uint, 0);
+
+int dngl_xtalfreq = 0;
+module_param(dngl_xtalfreq, int, 0);
+#endif /* BCMSLTGT */
+
+#ifdef SDTEST
+/* Echo packet generator (pkts/s) */
+uint dhd_pktgen = 0;
+module_param(dhd_pktgen, uint, 0);
+
+/* Echo packet len (0 => sawtooth, max 2040) */
+uint dhd_pktgen_len = 0;
+module_param(dhd_pktgen_len, uint, 0);
+#endif /* SDTEST */
+
+#if defined(BCMSUP_4WAY_HANDSHAKE)
+/* Use in dongle supplicant for 4-way handshake */
+#if defined(WLFBT) || defined(WL_ENABLE_IDSUP)
+/* Enable idsup by default (if supported in fw) */
+uint dhd_use_idsup = 1;
+#else
+uint dhd_use_idsup = 0;
+#endif /* WLFBT || WL_ENABLE_IDSUP */
+module_param(dhd_use_idsup, uint, 0);
+#endif /* BCMSUP_4WAY_HANDSHAKE */
+
+#ifndef BCMDBUS
+#if defined(OEM_ANDROID)
+/* Allow delayed firmware download for debug purpose */
+int allow_delay_fwdl = FALSE;
+#elif defined(BCM_ROUTER_DHD)
+/* Allow delayed firmware download for debug purpose */
+int allow_delay_fwdl = FALSE;
+#else
+int allow_delay_fwdl = TRUE;
+#endif /* OEM_ANDROID */
+module_param(allow_delay_fwdl, int, 0);
+#endif /* !BCMDBUS */
+
+#ifdef GDB_PROXY
+/* Adds/replaces deadman_to= in NVRAM file with deadman_to=0 */
+static uint nodeadman = 0;
+module_param(nodeadman, uint, 0);
+#endif /* GDB_PROXY */
+
+#ifdef ECOUNTER_PERIODIC_DISABLE
+uint enable_ecounter = FALSE;
+#else
+uint enable_ecounter = TRUE;
+#endif
+module_param(enable_ecounter, uint, 0);
+
+#ifdef BCMQT_HW
+int qt_flr_reset = FALSE;
+module_param(qt_flr_reset, int, 0);
+
+int qt_dngl_timeout = 0; // dongle attach timeout in ms
+module_param(qt_dngl_timeout, int, 0);
+#endif /* BCMQT_HW */
+
+#ifdef DHD_SUPPORT_SPMI_MODE
+uint spmi_mode = 0;
+module_param(spmi_mode, uint, 0644);
+#endif /* DHD_SUPPORT_SPMI_MODE */
+
+/* TCM verification flag */
+uint dhd_tcm_test_enable = FALSE;
+module_param(dhd_tcm_test_enable, uint, 0644);
+
+tcm_test_status_t dhd_tcm_test_status = TCM_TEST_NOT_RUN;
+tcm_test_mode_t dhd_tcm_test_mode = TCM_TEST_MODE_ALWAYS;
+
+extern char dhd_version[];
+extern char fw_version[];
+extern char clm_version[];
+
+int dhd_net_bus_devreset(struct net_device *dev, uint8 flag);
+static void dhd_net_if_lock_local(dhd_info_t *dhd);
+static void dhd_net_if_unlock_local(dhd_info_t *dhd);
+static void dhd_suspend_lock(dhd_pub_t *dhdp);
+static void dhd_suspend_unlock(dhd_pub_t *dhdp);
+
+/* Monitor interface */
+int dhd_monitor_init(void *dhd_pub);
+int dhd_monitor_uninit(void);
+
+#ifdef DHD_PM_CONTROL_FROM_FILE
+bool g_pm_control;
+#ifdef DHD_EXPORT_CNTL_FILE
+uint32 pmmode_val = 0xFF;
+#endif /* DHD_EXPORT_CNTL_FILE */
+void sec_control_pm(dhd_pub_t *dhd, uint *);
+#endif /* DHD_PM_CONTROL_FROM_FILE */
+
+#if defined(WL_WIRELESS_EXT)
+struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev);
+#endif /* defined(WL_WIRELESS_EXT) */
+
+#ifdef DHD_PM_OVERRIDE
+bool g_pm_override;
+#endif /* DHD_PM_OVERRIDE */
+
+#ifndef BCMDBUS
+static void dhd_dpc(ulong data);
+#endif /* !BCMDBUS */
+/* forward decl */
+extern int dhd_wait_pend8021x(struct net_device *dev);
+void dhd_os_wd_timer_extend(void *bus, bool extend);
+
+#ifdef TOE
+#ifndef BDC
+#error TOE requires BDC
+#endif /* !BDC */
+static int dhd_toe_get(dhd_info_t *dhd, int idx, uint32 *toe_ol);
+static int dhd_toe_set(dhd_info_t *dhd, int idx, uint32 toe_ol);
+#endif /* TOE */
+
+#ifdef DHD_MAP_LOGGING
+void dhd_smmu_fault_handler(uint32 axid, ulong fault_addr);
+#endif /* DHD_MAP_LOGGING */
+
+#if defined(DHD_ENABLE_S2MPU)
+int s2mpufd_notifier_callback(struct s2mpufd_notifier_block *block,
+		struct s2mpufd_notifier_info *info);
+static void dhd_module_s2mpu_register(struct device *dev);
+#endif /* DHD_ENABLE_S2MPU */
+#ifdef DHD_REGISTER_SMMU_FAULT_HANDLER
+extern int pcie_sysmmu_add_fault_handler(struct notifier_block *pcie_sysmmu_nb);
+static int sysmmu_notifier_callback(struct notifier_block *nb, unsigned long addr,
+	void *flag);
+static struct notifier_block dhd_pcie_sysmmu_nb = {
+	.notifier_call = sysmmu_notifier_callback
+};
+#endif /* DHD_REGISTER_SMMU_FAULT_HANDLER */
+
+static int dhd_suspend_resume_helper(struct dhd_info *dhd, int val, int force);
+#if defined(DHD_FILE_DUMP_EVENT) && defined(DHD_FW_COREDUMP)
+static void dhd_dump_proc(struct work_struct *work_data);
+#endif /* DHD_FILE_DUMP_EVENT && DHD_FW_COREDUMP */
+
+#if defined(BCMSDIO)
+extern void dhd_bus_check_srmemsize(dhd_pub_t *dhdp);
+#endif /* BCMSDIO */
+
+#ifdef CUSTOM_EVENT_PM_WAKE
+void
+dhd_set_excess_pm_awake(dhd_pub_t *dhd, bool suspend)
+{
+	int ret = 0;
+	uint32 iovar_val = 0;   /* Disable the excess PM notify */
+	char *iovar_name;
+
+#ifdef CUSTOM_EVENT_PM_PERCENT
+	iovar_name = "excess_pm_period";
+#else
+	iovar_name = "const_awake_thresh";
+	iovar_val = CUSTOM_EVENT_PM_WAKE;
+#endif /* CUSTOM_EVENT_PM_PERCENT */
+
+	if (suspend) {
+		iovar_val = CUSTOM_EVENT_PM_WAKE * 4;
+	}
+
+	ret = dhd_iovar(dhd, 0, iovar_name, (char *)&iovar_val,
+			sizeof(iovar_val), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s set %s failed %d\n", __FUNCTION__, iovar_name, ret));
+	}
+	return;
+}
+void
+dhd_init_excess_pm_awake(dhd_pub_t *dhd)
+{
+	int ret = 0;
+	uint32 pm_awake_thresh = CUSTOM_EVENT_PM_WAKE;
+#ifdef CUSTOM_EVENT_PM_PERCENT
+	uint32 pm_awake_percent = CUSTOM_EVENT_PM_PERCENT;
+
+	ret = dhd_iovar(dhd, 0, "excess_pm_percent", (char *)&pm_awake_percent,
+			sizeof(pm_awake_percent), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s set excess_pm_percent failed %d\n", __FUNCTION__, ret));
+	}
+	pm_awake_thresh = 0;    /* Disable the excess PM notify */
+#endif /* CUSTOM_EVENT_PM_PERCENT */
+	ret = dhd_iovar(dhd, 0, "const_awake_thresh", (char *)&pm_awake_thresh,
+			sizeof(pm_awake_thresh), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s set const_awake_thresh failed %d\n", __FUNCTION__, ret));
+	}
+
+	return;
+}
+#endif /* CUSTOM_EVENT_PM_WAKE */
+
+#if defined(CONFIG_PM_SLEEP)
+#ifdef WL_TWT
+#define TWT_NOMINAL_RESUME	(5U * 1024U) /* 5ms */
+
+int dhd_send_twt_info_suspend(dhd_pub_t *dhdp, bool suspend)
+{
+	int ret = BCME_OK;
+	wl_twt_info_t ti;
+	u8 buf[WLC_IOCTL_SMLEN] = {0};
+
+	uint8 *pbuf = buf;
+	uint16 param_len  = sizeof(buf);
+
+	bzero(&ti, sizeof(ti));
+	ti.version = WL_TWT_INFO_VER;
+	ti.length = sizeof(ti.version) + sizeof(ti.length);
+
+	if (!dhdp || dhdp->up == 0) {
+		return ret;
+	}
+
+	/* if it's not associated, skip send info */
+	if (!dhd_is_associated(dhdp, 0, NULL)) {
+		return ret;
+	}
+
+	/* Default values, Overide Below */
+	ti.infodesc.flow_id = 0xFF;
+	ti.desc.next_twt_h = 0xFFFFFFFF;
+	ti.desc.next_twt_l = 0xFFFFFFFF;
+
+	/* Set allTWT info suspend, ConfigID = 0 */
+	ti.configID = 0;
+
+	/* resume TWT session in resume */
+	if (suspend == FALSE) {
+		/* Resume TWT session */
+		ti.infodesc.next_twt_h = htod32((u32)((u64)TWT_NOMINAL_RESUME >> 32));
+		ti.infodesc.next_twt_l = htod32((u32)TWT_NOMINAL_RESUME);
+		ti.infodesc.flow_flags |= WL_TWT_INFO_FLAG_RESUME;
+	}
+
+	/* Packing parameters */
+	ret = bcm_pack_xtlv_entry(&pbuf, &param_len, WL_TWT_CMD_INFO,
+			sizeof(ti), (uint8 *)&ti, BCM_XTLV_OPTION_ALIGN32);
+	if (ret != BCME_OK) {
+		DHD_ERROR(("%s : parameter packing error \n", __FUNCTION__));
+		return ret;
+	}
+
+	ret = dhd_iovar(dhdp, 0, "twt", buf, sizeof(buf) - param_len, NULL, 0, TRUE);
+	if (ret) {
+		DHD_ERROR(("%s : TWT info failed ret : %d\n", __FUNCTION__, ret));
+	}
+	return ret;
+
+}
+int dhd_config_twt_event_mask_in_suspend(dhd_pub_t *dhdp, bool suspend)
+{
+	int ret = BCME_OK;
+	u8 buf[WLC_IOCTL_SMLEN] = {0};
+	eventmsgs_ext_t *eventmask_msg = NULL;
+
+	int msglen = WL_EVENTING_MASK_EXT_LEN + EVENTMSGS_EXT_STRUCT_SIZE;
+
+	if (!dhdp || dhdp->up == 0) {
+		return ret;
+	}
+
+	/* if it's not associated in suspend, skip teardown */
+	if (suspend && !dhd_is_associated(dhdp, 0, NULL)) {
+		return ret;
+	}
+
+	/* TWT_E_TWT event mask configuration */
+	eventmask_msg = (eventmsgs_ext_t *)MALLOC(dhdp->osh, msglen);
+	if (eventmask_msg == NULL) {
+		DHD_ERROR(("%s : failed to allocate for event_msg_ext\n", __FUNCTION__));
+		return ret;
+	}
+
+	bzero(eventmask_msg, msglen);
+	eventmask_msg->ver = EVENTMSGS_VER;
+	eventmask_msg->len = ROUNDUP(WLC_E_LAST, NBBY)/NBBY;
+
+	/* Read event_msgs_ext mask */
+	ret = dhd_iovar(dhdp, 0, "event_msgs_ext", (char *)eventmask_msg, msglen, buf,
+			WLC_IOCTL_SMLEN, FALSE);
+	/* event_msgs_ext must be supported */
+	if (ret != BCME_OK) {
+		DHD_ERROR(("%s read event mask ext failed %d\n", __FUNCTION__, ret));
+		goto fail;
+	}
+
+	bcopy(buf, eventmask_msg, msglen);
+
+	/* suspend */
+	if (suspend) {
+		/* Clear TWT EVENT bit mask */
+		clrbit(eventmask_msg->mask, WLC_E_TWT);
+	} else {
+	/* resume */
+		/* Set TWT EVENT bit mask */
+		setbit(eventmask_msg->mask, WLC_E_TWT);
+	}
+
+	/* Write updated Event mask */
+	eventmask_msg->ver = EVENTMSGS_VER;
+	eventmask_msg->command = EVENTMSGS_SET_MASK;
+	eventmask_msg->len = WL_EVENTING_MASK_EXT_LEN;
+
+	ret = dhd_iovar(dhdp, 0, "event_msgs_ext", (char *)eventmask_msg, msglen,
+			NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s write event mask ext failed %d\n", __FUNCTION__, ret));
+		goto fail;
+	}
+
+fail:
+	if (eventmask_msg) {
+		MFREE(dhdp->osh, eventmask_msg, msglen);
+	}
+
+	return ret;
+
+}
+#endif /* WL_TWT */
+
+int dhd_pm_callback(
+#ifdef DEVICE_PM_CALLBACK
+	dhd_pub_t *dhd,
+#else
+	struct notifier_block *nfb,
+#endif
+	unsigned long action, void *ignored)
+{
+	int ret = NOTIFY_DONE;
+	bool suspend = FALSE;
+	dhd_info_t *dhdinfo;
+	unsigned long flags = 0;
+#ifndef DEVICE_PM_CALLBACK
+	dhd_pub_t *dhd;
+#endif
+	struct dhd_conf *conf;
+	int suspend_mode;
+#if defined(BCMDBUS) && defined(WL_EXT_WOWL)
+	int wowl_dngldown = 0;
+#endif
+
+	BCM_REFERENCE(dhdinfo);
+	BCM_REFERENCE(suspend);
+
+#ifdef DEVICE_PM_CALLBACK
+	dhdinfo = dhd->info;
+#else
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhdinfo = container_of(nfb, struct dhd_info, pm_notifier);
+	GCC_DIAGNOSTIC_POP();
+
+	dhd = &dhdinfo->pub;
+	if (!dhd->up) {
+		return ret;
+	}
+#endif
+	conf = dhd->conf;
+	suspend_mode = conf->suspend_mode;
+
+	DHD_GENERAL_LOCK(dhd, flags);
+#if defined(BCMDBUS) && defined(WL_EXT_WOWL)
+	wowl_dngldown = dhd_conf_wowl_dngldown(dhd);
+	if (!wowl_dngldown)
+#endif
+	DHD_BUS_BUSY_SET_IN_PM_CALLBACK(dhd);
+	DHD_GENERAL_UNLOCK(dhd, flags);
+
+	switch (action) {
+	case PM_HIBERNATION_PREPARE:
+	case PM_SUSPEND_PREPARE:
+		suspend = TRUE;
+		break;
+
+	case PM_POST_HIBERNATION:
+	case PM_POST_SUSPEND:
+		suspend = FALSE;
+		break;
+	}
+
+	if(!dhd->early_suspended && suspend_mode != PM_NOTIFIER) {
+		suspend_mode = PM_NOTIFIER;
+		conf->suspend_mode = PM_NOTIFIER;
+		conf->insuspend |= (NO_TXDATA_IN_SUSPEND | NO_TXCTL_IN_SUSPEND);
+		printf("%s: switch suspend_mode to %d\n", __FUNCTION__, suspend_mode);
+	}
+	printf("%s: action=%ld, suspend=%d, suspend_mode=%d\n",
+		__FUNCTION__, action, suspend, suspend_mode);
+	if (suspend) {
+#ifdef WL_TWT
+		dhd_config_twt_event_mask_in_suspend(dhd, TRUE);
+		dhd_send_twt_info_suspend(dhd, TRUE);
+#endif /* WL_TWT */
+		DHD_OS_WAKE_LOCK_WAIVE(dhd);
+		if (suspend_mode == PM_NOTIFIER)
+			dhd_suspend_resume_helper(dhdinfo, suspend, 0);
+#ifdef DHD_CUSTOM_CONFIG_RTS_IN_SUSPEND
+		dhd_config_rts_in_suspend(dhd, suspend);
+#endif /* DHD_CUSTOM_CONFIG_RTS_IN_SUSPEND */
+#if defined(SUPPORT_P2P_GO_PS) && defined(PROP_TXSTATUS)
+		dhd_wlfc_suspend(dhd);
+#endif /* defined(SUPPORT_P2P_GO_PS) && defined(PROP_TXSTATUS) */
+		if (suspend_mode == PM_NOTIFIER || suspend_mode == SUSPEND_MODE_2)
+			dhd_conf_set_suspend_resume(dhd, suspend);
+		DHD_OS_WAKE_LOCK_RESTORE(dhd);
+	} else {
+#ifdef BCMDBUS
+		if (dhd->busstate == DHD_BUS_DATA) {
+#endif
+		if (suspend_mode == PM_NOTIFIER || suspend_mode == SUSPEND_MODE_2)
+			dhd_conf_set_suspend_resume(dhd, suspend);
+#if defined(SUPPORT_P2P_GO_PS) && defined(PROP_TXSTATUS)
+		dhd_wlfc_resume(dhd);
+#endif /* defined(SUPPORT_P2P_GO_PS) && defined(PROP_TXSTATUS) */
+#ifdef CUSTOM_EVENT_PM_WAKE
+		dhd_set_excess_pm_awake(dhd, suspend);
+#endif /* CUSTOM_EVENT_PM_WAKE */
+#ifdef DHD_CUSTOM_CONFIG_RTS_IN_SUSPEND
+		dhd_config_rts_in_suspend(dhd, suspend);
+#endif /* DHD_CUSTOM_CONFIG_RTS_IN_SUSPEND */
+		if (suspend_mode == PM_NOTIFIER)
+			dhd_suspend_resume_helper(dhdinfo, suspend, 0);
+#ifdef BCMDBUS
+		} else {
+#if defined(BCMDBUS) && defined(WL_EXT_WOWL)
+			if (wowl_dngldown) {
+				printf("%s: reset power\n", __FUNCTION__);
+				dhd_wifi_platform_set_power(dhd, FALSE);
+				dhd_wifi_platform_set_power(dhd, TRUE);
+			} else
+#endif
+			{
+				printf("%s: skip resume since bus suspeneded\n", __FUNCTION__);
+			}
+		}
+#endif
+	}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && (LINUX_VERSION_CODE <= \
+	KERNEL_VERSION(2, 6, 39))
+	dhd_mmc_suspend = suspend;
+	smp_mb();
+#endif
+
+	DHD_GENERAL_LOCK(dhd, flags);
+	DHD_BUS_BUSY_CLEAR_IN_PM_CALLBACK(dhd);
+	DHD_GENERAL_UNLOCK(dhd, flags);
+	return ret;
+}
+
+#ifndef DEVICE_PM_CALLBACK
+/* to make sure we won't register the same notifier twice, otherwise a loop is likely to be
+ * created in kernel notifier link list (with 'next' pointing to itself)
+ */
+static bool dhd_pm_notifier_registered = FALSE;
+
+extern int register_pm_notifier(struct notifier_block *nb);
+extern int unregister_pm_notifier(struct notifier_block *nb);
+#endif /* DEVICE_PM_CALLBACK */
+#endif /* CONFIG_PM_SLEEP */
+
+#if defined(DHD_H2D_LOG_TIME_SYNC)
+static void
+dhd_deferred_work_rte_log_time_sync(void *handle, void *event_info, u8 event);
+#endif /* DHD_H2D_LOG_TIME_SYNC */
+
+/** Clear the dhd net_device's private structure. */
+static inline void
+dhd_dev_priv_clear(struct net_device * dev)
+{
+	dhd_dev_priv_t * dev_priv;
+	ASSERT(dev != (struct net_device *)NULL);
+	dev_priv = DHD_DEV_PRIV(dev);
+	dev_priv->dhd = (dhd_info_t *)NULL;
+	dev_priv->ifp = (dhd_if_t *)NULL;
+	dev_priv->ifidx = DHD_BAD_IF;
+	dev_priv->lkup = (void *)NULL;
+}
+
+/** Setup the dhd net_device's private structure. */
+static inline void
+dhd_dev_priv_save(struct net_device * dev, dhd_info_t * dhd, dhd_if_t * ifp,
+                  int ifidx)
+{
+	dhd_dev_priv_t * dev_priv;
+	ASSERT(dev != (struct net_device *)NULL);
+	dev_priv = DHD_DEV_PRIV(dev);
+	dev_priv->dhd = dhd;
+	dev_priv->ifp = ifp;
+	dev_priv->ifidx = ifidx;
+}
+
+/* Return interface pointer */
+struct dhd_if * dhd_get_ifp(dhd_pub_t *dhdp, uint32 ifidx)
+{
+	ASSERT(ifidx < DHD_MAX_IFS);
+
+	if (!dhdp || !dhdp->info || ifidx >= DHD_MAX_IFS)
+		return NULL;
+
+	return dhdp->info->iflist[ifidx];
+}
+
+#ifdef WLEASYMESH
+int
+dhd_set_1905_almac(dhd_pub_t *dhdp, uint8 ifidx, uint8* ea, bool mcast)
+{
+	dhd_if_t *ifp;
+
+	ASSERT(ea != NULL);
+	ifp = dhd_get_ifp(dhdp, ifidx);
+	if (ifp == NULL) {
+		return BCME_ERROR;
+	}
+	if (mcast) {
+		memcpy(ifp->_1905_al_mcast, ea, ETHER_ADDR_LEN);
+	} else {
+		memcpy(ifp->_1905_al_ucast, ea, ETHER_ADDR_LEN);
+	}
+	return BCME_OK;
+}
+int
+dhd_get_1905_almac(dhd_pub_t *dhdp, uint8 ifidx, uint8* ea, bool mcast)
+{
+	dhd_if_t *ifp;
+
+	ASSERT(ea != NULL);
+	ifp = dhd_get_ifp(dhdp, ifidx);
+	if (ifp == NULL) {
+		return BCME_ERROR;
+	}
+	if (mcast) {
+		memcpy(ea, ifp->_1905_al_mcast, ETHER_ADDR_LEN);
+	} else {
+		memcpy(ea, ifp->_1905_al_ucast, ETHER_ADDR_LEN);
+	}
+	return BCME_OK;
+}
+#endif /* WLEASYMESH */
+
+#ifdef PCIE_FULL_DONGLE
+
+/** Dummy objects are defined with state representing bad|down.
+ * Performance gains from reducing branch conditionals, instruction parallelism,
+ * dual issue, reducing load shadows, avail of larger pipelines.
+ * Use DHD_XXX_NULL instead of (dhd_xxx_t *)NULL, whenever an object pointer
+ * is accessed via the dhd_sta_t.
+ */
+
+/* Dummy dhd_info object */
+dhd_info_t dhd_info_null = {
+	.pub = {
+	         .info = &dhd_info_null,
+#ifdef DHDTCPACK_SUPPRESS
+	         .tcpack_sup_mode = TCPACK_SUP_REPLACE,
+#endif /* DHDTCPACK_SUPPRESS */
+#if defined(BCM_ROUTER_DHD)
+	         .dhd_tm_dwm_tbl = { .dhd_dwm_enabled = TRUE },
+#endif
+	         .up = FALSE,
+	         .busstate = DHD_BUS_DOWN
+	}
+};
+#define DHD_INFO_NULL (&dhd_info_null)
+#define DHD_PUB_NULL  (&dhd_info_null.pub)
+
+/* Dummy netdevice object */
+struct net_device dhd_net_dev_null = {
+	.reg_state = NETREG_UNREGISTERED
+};
+#define DHD_NET_DEV_NULL (&dhd_net_dev_null)
+
+/* Dummy dhd_if object */
+dhd_if_t dhd_if_null = {
+#ifdef WMF
+	.wmf = { .wmf_enable = TRUE },
+#endif
+	.info = DHD_INFO_NULL,
+	.net = DHD_NET_DEV_NULL,
+	.idx = DHD_BAD_IF
+};
+#define DHD_IF_NULL  (&dhd_if_null)
+
+/* XXX should we use the sta_pool[0] object as DHD_STA_NULL? */
+#define DHD_STA_NULL ((dhd_sta_t *)NULL)
+
+/** Interface STA list management. */
+
+/** Alloc/Free a dhd_sta object from the dhd instances' sta_pool. */
+static void dhd_sta_free(dhd_pub_t *pub, dhd_sta_t *sta);
+static dhd_sta_t * dhd_sta_alloc(dhd_pub_t * dhdp);
+
+/* Delete a dhd_sta or flush all dhd_sta in an interface's sta_list. */
+static void dhd_if_del_sta_list(dhd_if_t * ifp);
+
+/* Construct/Destruct a sta pool. */
+static int dhd_sta_pool_init(dhd_pub_t *dhdp, int max_sta);
+static void dhd_sta_pool_fini(dhd_pub_t *dhdp, int max_sta);
+/* Clear the pool of dhd_sta_t objects for built-in type driver */
+static void dhd_sta_pool_clear(dhd_pub_t *dhdp, int max_sta);
+
+/** Reset a dhd_sta object and free into the dhd pool. */
+static void
+dhd_sta_free(dhd_pub_t * dhdp, dhd_sta_t * sta)
+{
+	int prio;
+
+	ASSERT((sta != DHD_STA_NULL) && (sta->idx != ID16_INVALID));
+
+	ASSERT((dhdp->staid_allocator != NULL) && (dhdp->sta_pool != NULL));
+
+	/*
+	 * Flush and free all packets in all flowring's queues belonging to sta.
+	 * Packets in flow ring will be flushed later.
+	 */
+	for (prio = 0; prio < (int)NUMPRIO; prio++) {
+		uint16 flowid = sta->flowid[prio];
+
+		if (flowid != FLOWID_INVALID) {
+			unsigned long flags;
+			flow_ring_node_t * flow_ring_node;
+
+#ifdef DHDTCPACK_SUPPRESS
+			/* Clean tcp_ack_info_tbl in order to prevent access to flushed pkt,
+			 * when there is a newly coming packet from network stack.
+			 */
+			dhd_tcpack_info_tbl_clean(dhdp);
+#endif /* DHDTCPACK_SUPPRESS */
+
+			flow_ring_node = dhd_flow_ring_node(dhdp, flowid);
+			if (flow_ring_node) {
+				flow_queue_t *queue = &flow_ring_node->queue;
+
+				DHD_FLOWRING_LOCK(flow_ring_node->lock, flags);
+				flow_ring_node->status = FLOW_RING_STATUS_STA_FREEING;
+
+				if (!DHD_FLOW_QUEUE_EMPTY(queue)) {
+					void * pkt;
+					while ((pkt = dhd_flow_queue_dequeue(dhdp, queue)) !=
+						NULL) {
+						PKTFREE(dhdp->osh, pkt, TRUE);
+					}
+				}
+
+				DHD_FLOWRING_UNLOCK(flow_ring_node->lock, flags);
+				ASSERT(DHD_FLOW_QUEUE_EMPTY(queue));
+			}
+		}
+
+		sta->flowid[prio] = FLOWID_INVALID;
+	}
+
+	id16_map_free(dhdp->staid_allocator, sta->idx);
+	DHD_CUMM_CTR_INIT(&sta->cumm_ctr);
+	sta->ifp = DHD_IF_NULL; /* dummy dhd_if object */
+	sta->ifidx = DHD_BAD_IF;
+	sta->chanspec = 0;
+	bzero(sta->ea.octet, ETHER_ADDR_LEN);
+	INIT_LIST_HEAD(&sta->list);
+	sta->idx = ID16_INVALID; /* implying free */
+}
+
+/** Allocate a dhd_sta object from the dhd pool. */
+static dhd_sta_t *
+dhd_sta_alloc(dhd_pub_t * dhdp)
+{
+	uint16 idx;
+	dhd_sta_t * sta;
+	dhd_sta_pool_t * sta_pool;
+
+	ASSERT((dhdp->staid_allocator != NULL) && (dhdp->sta_pool != NULL));
+
+	idx = id16_map_alloc(dhdp->staid_allocator);
+	if (idx == ID16_INVALID) {
+		DHD_ERROR(("%s: cannot get free staid\n", __FUNCTION__));
+		return DHD_STA_NULL;
+	}
+
+	sta_pool = (dhd_sta_pool_t *)(dhdp->sta_pool);
+	sta = &sta_pool[idx];
+
+	ASSERT((sta->idx == ID16_INVALID) &&
+	       (sta->ifp == DHD_IF_NULL) && (sta->ifidx == DHD_BAD_IF));
+
+	DHD_CUMM_CTR_INIT(&sta->cumm_ctr);
+
+	sta->idx = idx; /* implying allocated */
+
+	return sta;
+}
+
+/** Delete all STAs in an interface's STA list. */
+static void
+dhd_if_del_sta_list(dhd_if_t *ifp)
+{
+	dhd_sta_t *sta, *next;
+	unsigned long flags;
+
+	DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags);
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	list_for_each_entry_safe(sta, next, &ifp->sta_list, list) {
+		GCC_DIAGNOSTIC_POP();
+		list_del(&sta->list);
+		dhd_sta_free(&ifp->info->pub, sta);
+	}
+
+	DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags);
+
+	return;
+}
+
+/** Construct a pool of dhd_sta_t objects to be used by interfaces. */
+static int
+dhd_sta_pool_init(dhd_pub_t *dhdp, int max_sta)
+{
+	int idx, prio, sta_pool_memsz;
+	dhd_sta_t * sta;
+	dhd_sta_pool_t * sta_pool;
+	void * staid_allocator;
+
+	ASSERT(dhdp != (dhd_pub_t *)NULL);
+	ASSERT((dhdp->staid_allocator == NULL) && (dhdp->sta_pool == NULL));
+
+	/* dhd_sta objects per radio are managed in a table. id#0 reserved. */
+	staid_allocator = id16_map_init(dhdp->osh, max_sta, 1);
+	if (staid_allocator == NULL) {
+		DHD_ERROR(("%s: sta id allocator init failure\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	/* Pre allocate a pool of dhd_sta objects (one extra). */
+	sta_pool_memsz = ((max_sta + 1) * sizeof(dhd_sta_t)); /* skip idx 0 */
+	sta_pool = (dhd_sta_pool_t *)MALLOC(dhdp->osh, sta_pool_memsz);
+	if (sta_pool == NULL) {
+		DHD_ERROR(("%s: sta table alloc failure\n", __FUNCTION__));
+		id16_map_fini(dhdp->osh, staid_allocator);
+		return BCME_ERROR;
+	}
+
+	dhdp->sta_pool = sta_pool;
+	dhdp->staid_allocator = staid_allocator;
+
+	/* Initialize all sta(s) for the pre-allocated free pool. */
+	bzero((uchar *)sta_pool, sta_pool_memsz);
+	for (idx = max_sta; idx >= 1; idx--) { /* skip sta_pool[0] */
+		sta = &sta_pool[idx];
+		sta->idx = id16_map_alloc(staid_allocator);
+		ASSERT(sta->idx <= max_sta);
+	}
+
+	/* Now place them into the pre-allocated free pool. */
+	for (idx = 1; idx <= max_sta; idx++) {
+		sta = &sta_pool[idx];
+		for (prio = 0; prio < (int)NUMPRIO; prio++) {
+			sta->flowid[prio] = FLOWID_INVALID; /* Flow rings do not exist */
+		}
+		dhd_sta_free(dhdp, sta);
+	}
+
+	return BCME_OK;
+}
+
+/** Destruct the pool of dhd_sta_t objects.
+ * Caller must ensure that no STA objects are currently associated with an if.
+ */
+static void
+dhd_sta_pool_fini(dhd_pub_t *dhdp, int max_sta)
+{
+	dhd_sta_pool_t * sta_pool = (dhd_sta_pool_t *)dhdp->sta_pool;
+
+	if (sta_pool) {
+		int idx;
+		int sta_pool_memsz = ((max_sta + 1) * sizeof(dhd_sta_t));
+		for (idx = 1; idx <= max_sta; idx++) {
+			ASSERT(sta_pool[idx].ifp == DHD_IF_NULL);
+			ASSERT(sta_pool[idx].idx == ID16_INVALID);
+		}
+		MFREE(dhdp->osh, dhdp->sta_pool, sta_pool_memsz);
+	}
+
+	id16_map_fini(dhdp->osh, dhdp->staid_allocator);
+	dhdp->staid_allocator = NULL;
+}
+
+/* Clear the pool of dhd_sta_t objects for built-in type driver */
+static void
+dhd_sta_pool_clear(dhd_pub_t *dhdp, int max_sta)
+{
+	int idx, prio, sta_pool_memsz;
+	dhd_sta_t * sta;
+	dhd_sta_pool_t * sta_pool;
+	void *staid_allocator;
+
+	if (!dhdp) {
+		DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	sta_pool = (dhd_sta_pool_t *)dhdp->sta_pool;
+	staid_allocator = dhdp->staid_allocator;
+
+	if (!sta_pool) {
+		DHD_ERROR(("%s: sta_pool is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	if (!staid_allocator) {
+		DHD_ERROR(("%s: staid_allocator is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	/* clear free pool */
+	sta_pool_memsz = ((max_sta + 1) * sizeof(dhd_sta_t));
+	bzero((uchar *)sta_pool, sta_pool_memsz);
+
+	/* dhd_sta objects per radio are managed in a table. id#0 reserved. */
+	id16_map_clear(staid_allocator, max_sta, 1);
+
+	/* Initialize all sta(s) for the pre-allocated free pool. */
+	for (idx = max_sta; idx >= 1; idx--) { /* skip sta_pool[0] */
+		sta = &sta_pool[idx];
+		sta->idx = id16_map_alloc(staid_allocator);
+		ASSERT(sta->idx <= max_sta);
+	}
+	/* Now place them into the pre-allocated free pool. */
+	for (idx = 1; idx <= max_sta; idx++) {
+		sta = &sta_pool[idx];
+		for (prio = 0; prio < (int)NUMPRIO; prio++) {
+			sta->flowid[prio] = FLOWID_INVALID; /* Flow rings do not exist */
+		}
+		dhd_sta_free(dhdp, sta);
+	}
+}
+
+/*
+ * Lockless variant of dhd_find_sta()
+ * Find STA with MAC address ea in an interface's STA list.
+ */
+dhd_sta_t *
+__dhd_find_sta(dhd_if_t *ifp, void *pub, int ifidx, void *ea)
+{
+	dhd_sta_t *sta;
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	list_for_each_entry(sta, &ifp->sta_list, list) {
+		GCC_DIAGNOSTIC_POP();
+		if (!memcmp(sta->ea.octet, ea, ETHER_ADDR_LEN)) {
+			DHD_INFO(("%s: Found STA " MACDBG "\n",
+				__FUNCTION__, MAC2STRDBG((char *)ea)));
+			return sta;
+		}
+	}
+
+	return DHD_STA_NULL;
+}
+
+/** Find STA with MAC address ea in an interface's STA list. */
+dhd_sta_t *
+dhd_find_sta(void *pub, int ifidx, void *ea)
+{
+	dhd_sta_t *sta;
+	dhd_if_t *ifp;
+	unsigned long flags;
+
+	ifp = dhd_get_ifp((dhd_pub_t *)pub, ifidx);
+	if (ifp == NULL)
+		return DHD_STA_NULL;
+
+	DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags);
+
+	sta = __dhd_find_sta(ifp, pub, ifidx, ea);
+
+	DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags);
+
+	return sta;
+}
+
+/*
+ * Lockless variant of dhd_add_sta()
+ * Add STA into the interface's STA list.
+ */
+dhd_sta_t *
+__dhd_add_sta(dhd_if_t *ifp, void *pub, int ifidx, void *ea)
+{
+	dhd_sta_t *sta;
+
+	if (!memcmp(ifp->net->dev_addr, ea, ETHER_ADDR_LEN)) {
+		DHD_ERROR(("%s: Serious FAILURE, receive own MAC %pM !!\n", __FUNCTION__, ea));
+		return DHD_STA_NULL;
+	}
+
+	sta = dhd_sta_alloc((dhd_pub_t *)pub);
+	if (sta == DHD_STA_NULL) {
+		DHD_ERROR(("%s: Alloc failed\n", __FUNCTION__));
+		return DHD_STA_NULL;
+	}
+
+	memcpy(sta->ea.octet, ea, ETHER_ADDR_LEN);
+
+	/* link the sta and the dhd interface */
+	sta->ifp = ifp;
+	sta->ifidx = ifidx;
+#ifdef DHD_WMF
+	sta->psta_prim = NULL;
+#endif
+	INIT_LIST_HEAD(&sta->list);
+
+	list_add_tail(&sta->list, &ifp->sta_list);
+
+	DHD_ERROR(("%s: Adding  STA " MACDBG "\n",
+		__FUNCTION__, MAC2STRDBG((char *)ea)));
+
+	return sta;
+}
+
+/** Add STA into the interface's STA list. */
+dhd_sta_t *
+dhd_add_sta(void *pub, int ifidx, void *ea)
+{
+	dhd_sta_t *sta;
+	dhd_if_t *ifp;
+	unsigned long flags;
+
+	ifp = dhd_get_ifp((dhd_pub_t *)pub, ifidx);
+	if (ifp == NULL)
+		return DHD_STA_NULL;
+
+	DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags);
+
+	sta = __dhd_add_sta(ifp, pub, ifidx, ea);
+
+	DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags);
+
+	return sta;
+}
+
+/** Delete all STAs from the interface's STA list. */
+void
+dhd_del_all_sta(void *pub, int ifidx)
+{
+	dhd_sta_t *sta, *next;
+	dhd_if_t *ifp;
+	unsigned long flags;
+
+	ifp = dhd_get_ifp((dhd_pub_t *)pub, ifidx);
+	if (ifp == NULL)
+		return;
+
+	DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags);
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	list_for_each_entry_safe(sta, next, &ifp->sta_list, list) {
+		GCC_DIAGNOSTIC_POP();
+		list_del(&sta->list);
+		dhd_sta_free(&ifp->info->pub, sta);
+#ifdef DHD_L2_FILTER
+		if (ifp->parp_enable) {
+			/* clear Proxy ARP cache of specific Ethernet Address */
+			bcm_l2_filter_arp_table_update(((dhd_pub_t*)pub)->osh,
+					ifp->phnd_arp_table, FALSE,
+					sta->ea.octet, FALSE, ((dhd_pub_t*)pub)->tickcnt);
+		}
+#endif /* DHD_L2_FILTER */
+	}
+
+	DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags);
+
+	return;
+}
+
+/** Delete STA from the interface's STA list. */
+void
+dhd_del_sta(void *pub, int ifidx, void *ea)
+{
+	dhd_sta_t *sta, *next;
+	dhd_if_t *ifp;
+	unsigned long flags;
+
+	ASSERT(ea != NULL);
+	ifp = dhd_get_ifp((dhd_pub_t *)pub, ifidx);
+	if (ifp == NULL)
+		return;
+
+	DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags);
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	list_for_each_entry_safe(sta, next, &ifp->sta_list, list) {
+		GCC_DIAGNOSTIC_POP();
+		if (!memcmp(sta->ea.octet, ea, ETHER_ADDR_LEN)) {
+			DHD_ERROR(("%s: Deleting STA " MACDBG "\n",
+				__FUNCTION__, MAC2STRDBG(sta->ea.octet)));
+			list_del(&sta->list);
+			dhd_sta_free(&ifp->info->pub, sta);
+		}
+	}
+
+	DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags);
+#ifdef DHD_L2_FILTER
+	if (ifp->parp_enable) {
+		/* clear Proxy ARP cache of specific Ethernet Address */
+		bcm_l2_filter_arp_table_update(((dhd_pub_t*)pub)->osh, ifp->phnd_arp_table, FALSE,
+			ea, FALSE, ((dhd_pub_t*)pub)->tickcnt);
+	}
+#endif /* DHD_L2_FILTER */
+	return;
+}
+
+/** Add STA if it doesn't exist. Not reentrant. */
+dhd_sta_t*
+dhd_findadd_sta(void *pub, int ifidx, void *ea)
+{
+	dhd_sta_t *sta;
+	dhd_if_t *ifp;
+	unsigned long flags;
+
+	ASSERT(ea != NULL);
+	ifp = dhd_get_ifp((dhd_pub_t *)pub, ifidx);
+	if (ifp == NULL)
+		return DHD_STA_NULL;
+
+	DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags);
+	sta = __dhd_find_sta(ifp, pub, ifidx, ea);
+
+	if (!sta) {
+		/* Add entry */
+		sta = __dhd_add_sta(ifp, pub, ifidx, ea);
+	}
+	DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags);
+
+	return sta;
+}
+
+void
+dhd_update_sta_chanspec_info(void *pub, int ifidx, const uint8 *ea, chanspec_t chanspec)
+{
+	dhd_sta_t *sta;
+	dhd_if_t *ifp;
+	unsigned long flags;
+
+	ASSERT(ea != NULL);
+	ifp = dhd_get_ifp((dhd_pub_t *)pub, ifidx);
+	if (ifp == NULL) {
+		DHD_ERROR(("%s: NULL ifp for ifidx:%d\n", __FUNCTION__, ifidx));
+		return;
+	}
+
+	DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags);
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	sta = __dhd_find_sta(ifp, pub, ifidx, (void *)ea);
+	GCC_DIAGNOSTIC_POP();
+
+	if (sta) {
+		sta->chanspec = chanspec;
+		DHD_ERROR(("%s: updated chanspec:0x%x for STA:" MACDBG "\n",
+			__FUNCTION__, sta->chanspec, MAC2STRDBG(sta->ea.octet)));
+	} else {
+		DHD_ERROR(("%s: found no STA:" MACDBG "\n",
+			__FUNCTION__, MAC2STRDBG(ea)));
+	}
+	DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags);
+
+}
+
+bool
+dhd_is_sta_htput(void *pub, int ifidx, void *ea)
+{
+#ifdef WL_CFG80211
+	dhd_sta_t *sta;
+	dhd_if_t *ifp;
+	unsigned long flags;
+	bool htput = FALSE;
+
+	/* For non-AP role, chanspec will not be updated and always use htput */
+	if (!DHD_IF_ROLE_AP((dhd_pub_t *)pub, ifidx)) {
+		DHD_ERROR(("%s: non-AP role, set htput\n", __FUNCTION__));
+		htput = TRUE;
+		return htput;
+	}
+
+	ASSERT(ea != NULL);
+	ifp = dhd_get_ifp((dhd_pub_t *)pub, ifidx);
+	if (ifp == NULL) {
+		DHD_ERROR(("%s: NULL ifp for ifidx:%d\n", __FUNCTION__, ifidx));
+		return htput;
+	}
+
+	DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags);
+	sta = __dhd_find_sta(ifp, pub, ifidx, ea);
+	/* Set htput for 160 Mhz */
+	if (sta) {
+		if (CHSPEC_IS160(sta->chanspec)) {
+			htput = TRUE;
+		}
+		DHD_ERROR(("%s: ifidx:%d htput:%d chanspec:0x%x of STA:" MACDBG "\n",
+			__FUNCTION__, ifidx, htput, sta->chanspec, MAC2STRDBG(sta->ea.octet)));
+	} else {
+		DHD_ERROR(("%s: found no STA " MACDBG "\n",
+			__FUNCTION__, MAC2STRDBG(ea)));
+	}
+	DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags);
+
+	return htput;
+#else
+	/* For Non-CFG builds, always create HTPUT flowrings ,
+	 * as dhd_update_sta_chanspec_info will not be called.
+	*/
+	return TRUE;
+#endif /* WL_CFG80211 */
+}
+
+#if defined(DHD_IGMP_UCQUERY) || defined(DHD_UCAST_UPNP)
+static struct list_head *
+dhd_sta_list_snapshot(dhd_info_t *dhd, dhd_if_t *ifp, struct list_head *snapshot_list)
+{
+	unsigned long flags;
+	dhd_sta_t *sta, *snapshot;
+
+	INIT_LIST_HEAD(snapshot_list);
+
+	DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags);
+
+	list_for_each_entry(sta, &ifp->sta_list, list) {
+		/* allocate one and add to snapshot */
+		snapshot = (dhd_sta_t *)MALLOC(dhd->pub.osh, sizeof(dhd_sta_t));
+		if (snapshot == NULL) {
+			DHD_ERROR(("%s: Cannot allocate memory\n", __FUNCTION__));
+			continue;
+		}
+
+		memcpy(snapshot->ea.octet, sta->ea.octet, ETHER_ADDR_LEN);
+
+		INIT_LIST_HEAD(&snapshot->list);
+		list_add_tail(&snapshot->list, snapshot_list);
+	}
+
+	DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags);
+
+	return snapshot_list;
+}
+
+static void
+dhd_sta_list_snapshot_free(dhd_info_t *dhd, struct list_head *snapshot_list)
+{
+	dhd_sta_t *sta, *next;
+
+	list_for_each_entry_safe(sta, next, snapshot_list, list) {
+		list_del(&sta->list);
+		MFREE(dhd->pub.osh, sta, sizeof(dhd_sta_t));
+	}
+}
+#endif /* DHD_IGMP_UCQUERY || DHD_UCAST_UPNP */
+
+#else
+static inline void dhd_if_del_sta_list(dhd_if_t *ifp) {}
+static inline int dhd_sta_pool_init(dhd_pub_t *dhdp, int max_sta) { return BCME_OK; }
+static inline void dhd_sta_pool_fini(dhd_pub_t *dhdp, int max_sta) {}
+static inline void dhd_sta_pool_clear(dhd_pub_t *dhdp, int max_sta) {}
+dhd_sta_t *dhd_findadd_sta(void *pub, int ifidx, void *ea) { return NULL; }
+dhd_sta_t *dhd_find_sta(void *pub, int ifidx, void *ea) { return NULL; }
+void dhd_del_sta(void *pub, int ifidx, void *ea) {}
+void dhd_update_sta_chanspec_info(void *pub, int ifidx, const uint8 *ea,
+	chanspec_t chanspec) {}
+bool dhd_is_sta_htput(void *pub, int ifidx, void *ea) { return FALSE; }
+#endif /* PCIE_FULL_DONGLE */
+
+#ifdef BCM_ROUTER_DHD
+/** Bind a flowid to the dhd_sta's flowid table. */
+void
+dhd_add_flowid(dhd_pub_t * dhdp, int ifidx, uint8 ac_prio, void * ea,
+                uint16 flowid)
+{
+	int prio;
+	dhd_if_t * ifp;
+	dhd_sta_t * sta;
+	flow_queue_t * queue;
+
+	ASSERT((dhdp != (dhd_pub_t *)NULL) && (ea != NULL));
+
+	/* Fetch the dhd_if object given the if index */
+	ifp = dhd_get_ifp(dhdp, ifidx);
+	if (ifp == (dhd_if_t *)NULL) /* ifp fetched from dhdp iflist[] */
+		return;
+
+	/* Intializing the backup queue parameters */
+	if (DHD_IF_ROLE_WDS(dhdp, ifidx) ||
+#ifdef DHD_WET
+		WET_ENABLED(dhdp) ||
+#endif /* DHD_WET */
+		0) {
+		queue = dhd_flow_queue(dhdp, flowid);
+		dhd_flow_ring_config_thresholds(dhdp, flowid,
+			dhd_queue_budget, queue->max, DHD_FLOW_QUEUE_CLEN_PTR(queue),
+			dhd_if_threshold, (void *)&ifp->cumm_ctr);
+		return;
+	} else if ((sta = dhd_find_sta(dhdp, ifidx, ea)) == DHD_STA_NULL) {
+		/* Fetch the station with a matching Mac address. */
+		/* Update queue's grandparent cummulative length threshold */
+		if (ETHER_ISMULTI((char *)ea)) {
+			queue = dhd_flow_queue(dhdp, flowid);
+			if (ifidx != 0 && DHD_IF_ROLE_STA(dhdp, ifidx)) {
+				/* Use default dhdp->cumm_ctr and dhdp->l2cumm_ctr,
+				 * in PSTA mode the ifp will be deleted but we don't delete
+				 * the PSTA flowring.
+				 */
+				dhd_flow_ring_config_thresholds(dhdp, flowid,
+					queue->max, queue->max, DHD_FLOW_QUEUE_CLEN_PTR(queue),
+					dhd_if_threshold, DHD_FLOW_QUEUE_L2CLEN_PTR(queue));
+			}
+			else if (DHD_FLOW_QUEUE_L2CLEN_PTR(queue) != (void *)&ifp->cumm_ctr) {
+				dhd_flow_ring_config_thresholds(dhdp, flowid,
+					queue->max, queue->max, DHD_FLOW_QUEUE_CLEN_PTR(queue),
+					dhd_if_threshold, (void *)&ifp->cumm_ctr);
+			}
+		}
+		return;
+	}
+
+	/* Set queue's min budget and queue's parent cummulative length threshold */
+	dhd_flow_ring_config_thresholds(dhdp, flowid, dhd_queue_budget,
+	                                dhd_sta_threshold, (void *)&sta->cumm_ctr,
+	                                dhd_if_threshold, (void *)&ifp->cumm_ctr);
+
+	/* Populate the flowid into the stations flowid table, for all packet
+	 * priorities that would match the given flow's ac priority.
+	 */
+	for (prio = 0; prio < (int)NUMPRIO; prio++) {
+		if (dhdp->flow_prio_map[prio] == ac_prio) {
+			/* flowring shared for all these pkt prio */
+			sta->flowid[prio] = flowid;
+		}
+	}
+}
+
+/** Unbind a flowid to the sta's flowid table. */
+void
+dhd_del_flowid(dhd_pub_t * dhdp, int ifidx, uint16 flowid)
+{
+	int prio;
+	dhd_if_t * ifp;
+	dhd_sta_t * sta;
+	unsigned long flags;
+
+	/* Fetch the dhd_if object given the if index */
+	ifp = dhd_get_ifp(dhdp, ifidx);
+	if (ifp == (dhd_if_t *)NULL) /* ifp fetched from dhdp iflist[] */
+		return;
+
+	/* Walk all stations and delete clear any station's reference to flowid */
+	DHD_IF_STA_LIST_LOCK(&ifp->sta_list_lock, flags);
+
+	list_for_each_entry(sta, &ifp->sta_list, list) {
+		for (prio = 0; prio < (int)NUMPRIO; prio++) {
+			if (sta->flowid[prio] == flowid) {
+				sta->flowid[prio] = FLOWID_INVALID;
+			}
+		}
+	}
+
+	DHD_IF_STA_LIST_UNLOCK(&ifp->sta_list_lock, flags);
+}
+#endif /* BCM_ROUTER_DHD */
+
+#if defined(DNGL_AXI_ERROR_LOGGING) && defined(DHD_USE_WQ_FOR_DNGL_AXI_ERROR)
+void
+dhd_axi_error_dispatch(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = dhdp->info;
+	schedule_work(&dhd->axi_error_dispatcher_work);
+}
+
+static void dhd_axi_error_dispatcher_fn(struct work_struct * work)
+{
+	struct dhd_info *dhd =
+		container_of(work, struct dhd_info, axi_error_dispatcher_work);
+	dhd_axi_error(&dhd->pub);
+}
+#endif /* DNGL_AXI_ERROR_LOGGING && DHD_USE_WQ_FOR_DNGL_AXI_ERROR */
+
+/** Returns dhd iflist index corresponding the the bssidx provided by apps */
+int dhd_bssidx2idx(dhd_pub_t *dhdp, uint32 bssidx)
+{
+	dhd_if_t *ifp;
+	dhd_info_t *dhd = dhdp->info;
+	int i;
+
+	ASSERT(bssidx < DHD_MAX_IFS);
+	ASSERT(dhdp);
+
+	for (i = 0; i < DHD_MAX_IFS; i++) {
+		ifp = dhd->iflist[i];
+		if (ifp && (ifp->bssidx == bssidx)) {
+			DHD_TRACE(("Index manipulated for %s from %d to %d\n",
+				ifp->name, bssidx, i));
+			break;
+		}
+	}
+	return i;
+}
+
+int dhd_process_cid_mac(dhd_pub_t *dhdp, bool prepost)
+{
+	uint chipid = 0;
+	int ret = BCME_OK;
+#ifndef BCMDBUS
+	chipid = dhd_bus_chip_id(dhdp);
+#endif /* BCMDBUS */
+	if (prepost) { /* pre process */
+		ret = dhd_alloc_cis(dhdp);
+		if (ret != BCME_OK) {
+			return ret;
+		}
+		switch (chipid) {
+#ifndef DHD_READ_CIS_FROM_BP
+			case BCM4389_CHIP_GRPID:
+				/* BCM4389B0 or higher rev is used new otp iovar */
+				dhd_read_otp_sw_rgn(dhdp);
+				break;
+#endif /* !DHD_READ_CIS_FROM_BP */
+			default:
+				dhd_read_cis(dhdp);
+				break;
+		}
+		dhd_check_module_cid(dhdp);
+		dhd_check_module_mac(dhdp);
+		dhd_set_macaddr_from_file(dhdp);
+	} else { /* post process */
+		dhd_write_macaddr(&dhdp->mac);
+		dhd_clear_cis(dhdp);
+	}
+
+	return BCME_OK;
+}
+
+// terence 20160615: fix building error if ARP_OFFLOAD_SUPPORT removed
+#if defined(PKT_FILTER_SUPPORT)
+#if defined(ARP_OFFLOAD_SUPPORT) && !defined(GAN_LITE_NAT_KEEPALIVE_FILTER)
+static bool
+_turn_on_arp_filter(dhd_pub_t *dhd, int op_mode_param)
+{
+	bool _apply = FALSE;
+	/* In case of IBSS mode, apply arp pkt filter */
+	if (op_mode_param & DHD_FLAG_IBSS_MODE) {
+		_apply = TRUE;
+		goto exit;
+	}
+	/* In case of P2P GO or GC, apply pkt filter to pass arp pkt to host */
+	if (op_mode_param & (DHD_FLAG_P2P_GC_MODE | DHD_FLAG_P2P_GO_MODE)) {
+		_apply = TRUE;
+		goto exit;
+	}
+
+#ifdef ALLOW_PKTFILTER_ON_CONCURRENT_MODE
+	/* In case of SoftAP, apply pkt filter to pass arp pkt to host
+		* Turn on to pass the test cases of packet filter validation
+	*/
+	if (dhd->pfaoe_enab && op_mode_param & DHD_FLAG_HOSTAP_MODE) {
+			_apply = TRUE;
+			goto exit;
+	}
+#endif /* ALLOW_PKTFILTER_ON_CONCURRENT_MODE */
+
+exit:
+	return _apply;
+}
+#endif /* !GAN_LITE_NAT_KEEPALIVE_FILTER */
+
+void
+dhd_set_packet_filter(dhd_pub_t *dhd)
+{
+	int i;
+
+	DHD_TRACE(("%s: enter\n", __FUNCTION__));
+	if (dhd_pkt_filter_enable) {
+		for (i = 0; i < dhd->pktfilter_count; i++) {
+			dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]);
+		}
+	}
+}
+
+void
+dhd_enable_packet_filter(int value, dhd_pub_t *dhd)
+{
+	int i;
+
+	DHD_ERROR(("%s: enter, value = %d\n", __FUNCTION__, value));
+#ifndef ALLOW_PKTFILTER_ON_CONCURRENT_MODE
+	if (!dhd->pfaoe_enab && (dhd->op_mode & (DHD_FLAG_HOSTAP_MODE | DHD_FLAG_P2P_GO_MODE)) && value &&
+			!dhd_conf_get_insuspend(dhd, AP_FILTER_IN_SUSPEND)) {
+		DHD_ERROR(("%s: DHD_FLAG_HOSTAP_MODE or DHD_FLAG_P2P_GO_MODE\n", __FUNCTION__));
+		return;
+	}
+#endif /* ALLOW_PKTFILTER_ON_CONCURRENT_MODE */
+	if (value)
+		dhd_conf_add_pkt_filter(dhd);
+	/* 1 - Enable packet filter, only allow unicast packet to send up */
+	/* 0 - Disable packet filter */
+	if (dhd_pkt_filter_enable && (!value ||
+	    (dhd_support_sta_mode(dhd) && !dhd->dhcp_in_progress) ||
+	    dhd_conf_get_insuspend(dhd, AP_FILTER_IN_SUSPEND)))
+	{
+		for (i = 0; i < dhd->pktfilter_count; i++) {
+// terence 20160615: fix building error if ARP_OFFLOAD_SUPPORT removed
+#if defined(ARP_OFFLOAD_SUPPORT) && !defined(GAN_LITE_NAT_KEEPALIVE_FILTER)
+			if (value && (i == DHD_ARP_FILTER_NUM) &&
+				!_turn_on_arp_filter(dhd, dhd->op_mode)) {
+				DHD_TRACE(("Do not turn on ARP white list pkt filter:"
+					"val %d, cnt %d, op_mode 0x%x\n",
+					value, i, dhd->op_mode));
+				continue;
+			}
+#endif /* !GAN_LITE_NAT_KEEPALIVE_FILTER */
+#ifdef APSTA_BLOCK_ARP_DURING_DHCP
+			if (value && (i == DHD_BROADCAST_ARP_FILTER_NUM) &&
+				dhd->pktfilter[DHD_BROADCAST_ARP_FILTER_NUM]) {
+				/* XXX: BROADCAST_ARP_FILTER is only for the
+				 * STA/SoftAP concurrent mode (Please refer to RB:90348)
+				 * Remove the filter for other cases explicitly
+				 */
+				DHD_ERROR(("%s: Remove the DHD_BROADCAST_ARP_FILTER\n",
+					__FUNCTION__));
+				dhd_packet_filter_add_remove(dhd, FALSE,
+					DHD_BROADCAST_ARP_FILTER_NUM);
+			}
+#endif /* APSTA_BLOCK_ARP_DURING_DHCP */
+#ifdef APSTA_BLOCK_ARP_DURING_EARLYSUSPEND
+			if (dhd->pfaoe_enab && value && (i == DHD_BROADCAST_ARP_FILTER_NUM) &&
+				DHD_OPMODE_STA_SOFTAP_CONCURR(dhd) &&
+				!dhd->pktfilter[DHD_BROADCAST_ARP_FILTER_NUM]) {
+				char *filterp;
+				/* XXX: BROADCAST_ARP_FILTER is only for the
+				* STA/SoftAP concurrent mode
+				* Add the filter when entering early suspend
+				* in case of STA/SoftAP concurrent
+				*/
+				DHD_ERROR(("%s: Add to block ARP broadcast frames\n",
+					__FUNCTION__));
+				filterp = "106 1 6 ETH_H:0 0xFFFFFFFFFFFF0000000000000806"
+				" 0xFFFFFFFFFFFF0000000000000806";
+				if (FW_SUPPORTED((dhd), pf6)) {
+					dhd->pktfilter[i] = filterp;
+					dhd_pktfilter_offload_set(dhd, dhd->pktfilter[i]);
+				}
+			}
+			else if (dhd->pfaoe_enab && !value &&
+					(i == DHD_BROADCAST_ARP_FILTER_NUM) &&
+					DHD_OPMODE_STA_SOFTAP_CONCURR(dhd) &&
+					dhd->pktfilter[DHD_BROADCAST_ARP_FILTER_NUM])
+			{
+				/* XXX: BROADCAST_ARP_FILTER is only for the
+				* STA/SoftAP concurrent mode
+				* Remove the filter when exiting early suspend
+				* in case of STA/SoftAP concurrent
+				*/
+				DHD_ERROR(("%s: Remove the DHD_BROADCAST_ARP_FILTER\n",
+					__FUNCTION__));
+				if (FW_SUPPORTED((dhd), pf6)) {
+					if (dhd->pktfilter[i] != NULL) {
+						dhd_pktfilter_offload_enable(dhd,
+							dhd->pktfilter[i], value, FALSE);
+						dhd_pktfilter_offload_delete(dhd, 106);
+						dhd->pktfilter[i] = NULL;
+						continue;
+					}
+				}
+			}
+#endif /* APSTA_BLOCK_ARP_DURING_EARLYSUSPEND */
+			dhd_pktfilter_offload_enable(dhd, dhd->pktfilter[i],
+				value, dhd_master_mode);
+		}
+
+		/* post set mode for enable case */
+		if (value) {
+			dhd_pktfilter_mode_change(dhd, value);
+		}
+	}
+}
+
+int
+dhd_packet_filter_add_remove(dhd_pub_t *dhdp, int add_remove, int num)
+{
+	char *filterp = NULL;
+	int filter_id = 0;
+
+	switch (num) {
+		case DHD_BROADCAST_FILTER_NUM:
+			filterp = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF";
+			filter_id = 101;
+			break;
+		case DHD_MULTICAST4_FILTER_NUM:
+			filter_id = 102;
+			if (FW_SUPPORTED((dhdp), pf6)) {
+				if (dhdp->pktfilter[num] != NULL) {
+					dhd_pktfilter_offload_delete(dhdp, filter_id);
+					dhdp->pktfilter[num] = NULL;
+				}
+				if (!add_remove) {
+					filterp = DISCARD_IPV4_MCAST;
+					add_remove = 1;
+					break;
+				}
+			} /* XXX: intend omitting else case */
+			filterp = "102 0 0 0 0xFFFFFF 0x01005E";
+			break;
+		case DHD_MULTICAST6_FILTER_NUM:
+			filter_id = 103;
+			if (FW_SUPPORTED((dhdp), pf6)) {
+				if (dhdp->pktfilter[num] != NULL) {
+					dhd_pktfilter_offload_delete(dhdp, filter_id);
+					dhdp->pktfilter[num] = NULL;
+				}
+				if (!add_remove) {
+					filterp = DISCARD_IPV6_MCAST;
+					add_remove = 1;
+					break;
+				}
+			} /* XXX: intend omitting else case */
+			filterp = "103 0 0 0 0xFFFF 0x3333";
+			break;
+		case DHD_MDNS_FILTER_NUM:
+			filterp = "104 0 0 0 0xFFFFFFFFFFFF 0x01005E0000FB";
+			filter_id = 104;
+			break;
+		case DHD_ARP_FILTER_NUM:
+			filterp = "105 0 0 12 0xFFFF 0x0806";
+			filter_id = 105;
+			break;
+		case DHD_BROADCAST_ARP_FILTER_NUM:
+			filterp = "106 0 0 0 0xFFFFFFFFFFFF0000000000000806"
+				" 0xFFFFFFFFFFFF0000000000000806";
+			filter_id = 106;
+			break;
+		default:
+			return -EINVAL;
+	}
+
+	/* Add filter */
+	if (add_remove) {
+		dhdp->pktfilter[num] = filterp;
+		dhd_pktfilter_offload_set(dhdp, dhdp->pktfilter[num]);
+	} else { /* Delete filter */
+		if (dhdp->pktfilter[num] != NULL) {
+			dhd_pktfilter_offload_delete(dhdp, filter_id);
+			dhdp->pktfilter[num] = NULL;
+		}
+	}
+
+	return 0;
+}
+#endif /* PKT_FILTER_SUPPORT */
+
+static int dhd_set_suspend(int value, dhd_pub_t *dhd)
+{
+	/* wl_pkt_filter_enable_t	enable_parm; */
+	int ret = 0;
+#if defined(DHD_USE_EARLYSUSPEND) || defined(DHD_USE_PM_SLEEP)
+	uint nd_ra_filter = 0;
+#endif /* DHD_USE_EARLYSUSPEND || DHD_USE_PM_SLEEP */
+#ifdef PASS_ALL_MCAST_PKTS
+	struct dhd_info *dhdinfo;
+	uint32 allmulti;
+	uint i;
+#endif /* PASS_ALL_MCAST_PKTS */
+#ifdef DYNAMIC_SWOOB_DURATION
+#ifndef CUSTOM_INTR_WIDTH
+#define CUSTOM_INTR_WIDTH 100
+	int intr_width = 0;
+#endif /* CUSTOM_INTR_WIDTH */
+#endif /* DYNAMIC_SWOOB_DURATION */
+#ifdef WL_CFG80211
+	struct net_device *dev = dhd_linux_get_primary_netdev(dhd);
+#endif /* WL_CFG80211 */
+#if defined(DHD_BCN_TIMEOUT_IN_SUSPEND) && (defined(DHD_USE_EARLYSUSPEND) || \
+	defined(DHD_USE_PM_SLEEP))
+	/* CUSTOM_BCN_TIMEOUT_IN_SUSPEND in suspend, otherwise CUSTOM_BCN_TIMEOUT */
+	int bcn_timeout = CUSTOM_BCN_TIMEOUT;
+#endif /* DHD_BCN_TIMEOUT_IN_SUSPEND && (DHD_USE_EARLYSUSPEND || DHD_USE_PM_SLEEP) */
+
+	BCM_REFERENCE(ret);
+	if (!dhd)
+		return -ENODEV;
+
+#ifdef PASS_ALL_MCAST_PKTS
+	dhdinfo = dhd->info;
+#endif /* PASS_ALL_MCAST_PKTS */
+
+	DHD_TRACE(("%s: enter, value = %d in_suspend=%d\n",
+		__FUNCTION__, value, dhd->in_suspend));
+
+	dhd_suspend_lock(dhd);
+
+#ifdef CUSTOM_SET_CPUCORE
+	DHD_TRACE(("%s set cpucore(suspend%d)\n", __FUNCTION__, value));
+	/* set specific cpucore */
+	dhd_set_cpucore(dhd, TRUE);
+#endif /* CUSTOM_SET_CPUCORE */
+	if (dhd->up) {
+		if (value && dhd->in_suspend) {
+				dhd->early_suspended = 1;
+				/* Kernel suspended */
+				DHD_ERROR(("%s: force extra Suspend setting \n", __FUNCTION__));
+
+#ifdef PKT_FILTER_SUPPORT
+				/* Enable packet filter,
+				 * only allow unicast packet to send up
+				 */
+				dhd_enable_packet_filter(1, dhd);
+#endif /* PKT_FILTER_SUPPORT */
+#ifdef APF
+				dhd_dev_apf_enable_filter(dhd_linux_get_primary_netdev(dhd));
+#endif /* APF */
+#ifdef ARP_OFFLOAD_SUPPORT
+				if (dhd->arpoe_enable) {
+					dhd_arp_offload_enable(dhd, TRUE);
+				}
+#endif /* ARP_OFFLOAD_SUPPORT */
+#ifdef PASS_ALL_MCAST_PKTS
+				for (i = 0; i < DHD_MAX_IFS; i++) {
+					struct net_device *ndev = NULL;
+					if (!dhdinfo->iflist[i] || !dhdinfo->iflist[i]->net) {
+						continue;
+					}
+
+					ndev = dhdinfo->iflist[i]->net;
+#ifdef WL_CFG80211
+					if (ndev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO ||
+						ndev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP) {
+						allmulti = 1;
+						DHD_LOG_MEM(("%s: IF[%s] is AP/GO, set allmulti.\n",
+							__FUNCTION__, ndev->name));
+					} else
+#endif /* WL_CFG80211 */
+					{
+						allmulti = 0;
+					}
+
+					ret = dhd_iovar(dhd, i, "allmulti",
+						(char *)&allmulti,
+						sizeof(allmulti),
+						NULL, 0, TRUE);
+					if (ret < 0) {
+						DHD_ERROR(("%s allmulti failed %d\n",
+							__FUNCTION__, ret));
+					}
+				}
+#endif /* PASS_ALL_MCAST_PKTS */
+
+#if defined(DHD_USE_EARLYSUSPEND) || defined(DHD_USE_PM_SLEEP)
+#ifdef NDO_CONFIG_SUPPORT
+				if (dhd->ndo_enable) {
+					if (!dhd->ndo_host_ip_overflow) {
+						/* enable ND offload on suspend */
+						ret = dhd_ndo_enable(dhd, TRUE);
+						if (ret < 0) {
+							DHD_ERROR(("%s: failed to enable NDO\n",
+								__FUNCTION__));
+						}
+					} else {
+						DHD_INFO(("%s: NDO disabled on suspend due to"
+								"HW capacity\n", __FUNCTION__));
+					}
+				}
+#endif /* NDO_CONFIG_SUPPORT */
+#ifndef APF
+				if (FW_SUPPORTED(dhd, ndoe))
+#else
+				if (FW_SUPPORTED(dhd, ndoe) && !FW_SUPPORTED(dhd, apf))
+#endif /* APF */
+				{
+					/* enable IPv6 RA filter in  firmware during suspend */
+					nd_ra_filter = 1;
+					ret = dhd_iovar(dhd, 0, "nd_ra_filter_enable",
+							(char *)&nd_ra_filter, sizeof(nd_ra_filter),
+							NULL, 0, TRUE);
+					if (ret < 0)
+						DHD_ERROR(("failed to set nd_ra_filter (%d)\n",
+							ret));
+				}
+				dhd_os_suppress_logging(dhd, TRUE);
+#ifdef DYNAMIC_SWOOB_DURATION
+				intr_width = CUSTOM_INTR_WIDTH;
+				ret = dhd_iovar(dhd, 0, "bus:intr_width", (char *)&intr_width,
+						sizeof(intr_width), NULL, 0, TRUE);
+				if (ret < 0) {
+					DHD_ERROR(("failed to set intr_width (%d)\n", ret));
+				}
+#endif /* DYNAMIC_SWOOB_DURATION */
+#ifdef CUSTOM_EVENT_PM_WAKE
+				dhd_set_excess_pm_awake(dhd, TRUE);
+#endif /* CUSTOM_EVENT_PM_WAKE */
+#endif /* DHD_USE_EARLYSUSPEND || DHD_USE_PM_SLEEP */
+#ifdef WL_CFG80211
+				wl_cfg80211_soft_suspend(dev, TRUE);
+#endif /* WL_CFG80211 */
+			} else {
+				dhd->early_suspended = 0;
+				/* Kernel resumed  */
+				DHD_ERROR(("%s: Remove extra suspend setting \n", __FUNCTION__));
+#ifdef DYNAMIC_SWOOB_DURATION
+				intr_width = 0;
+				ret = dhd_iovar(dhd, 0, "bus:intr_width", (char *)&intr_width,
+						sizeof(intr_width), NULL, 0, TRUE);
+				if (ret < 0) {
+					DHD_ERROR(("failed to set intr_width (%d)\n", ret));
+				}
+#endif /* DYNAMIC_SWOOB_DURATION */
+#ifdef ARP_OFFLOAD_SUPPORT
+				if (dhd->arpoe_enable) {
+					dhd_arp_offload_enable(dhd, FALSE);
+				}
+#endif /* ARP_OFFLOAD_SUPPORT */
+#ifdef PKT_FILTER_SUPPORT
+				/* disable pkt filter */
+				dhd_enable_packet_filter(0, dhd);
+#endif /* PKT_FILTER_SUPPORT */
+#ifdef APF
+				dhd_dev_apf_disable_filter(dhd_linux_get_primary_netdev(dhd));
+#endif /* APF */
+#ifdef PASS_ALL_MCAST_PKTS
+				allmulti = 1;
+				for (i = 0; i < DHD_MAX_IFS; i++) {
+					if (dhdinfo->iflist[i] && dhdinfo->iflist[i]->net)
+						ret = dhd_iovar(dhd, i, "allmulti",
+								(char *)&allmulti,
+								sizeof(allmulti), NULL,
+								0, TRUE);
+					if (ret < 0) {
+						DHD_ERROR(("%s: allmulti failed:%d\n",
+								__FUNCTION__, ret));
+					}
+				}
+#endif /* PASS_ALL_MCAST_PKTS */
+#if defined(DHD_USE_EARLYSUSPEND) || defined(DHD_USE_PM_SLEEP)
+#ifdef NDO_CONFIG_SUPPORT
+				if (dhd->ndo_enable) {
+					/* Disable ND offload on resume */
+					ret = dhd_ndo_enable(dhd, FALSE);
+					if (ret < 0) {
+						DHD_ERROR(("%s: failed to disable NDO\n",
+							__FUNCTION__));
+					}
+				}
+#endif /* NDO_CONFIG_SUPPORT */
+#ifndef APF
+				if (FW_SUPPORTED(dhd, ndoe))
+#else
+				if (FW_SUPPORTED(dhd, ndoe) && !FW_SUPPORTED(dhd, apf))
+#endif /* APF */
+				{
+					/* disable IPv6 RA filter in  firmware during suspend */
+					nd_ra_filter = 0;
+					ret = dhd_iovar(dhd, 0, "nd_ra_filter_enable",
+							(char *)&nd_ra_filter, sizeof(nd_ra_filter),
+							NULL, 0, TRUE);
+					if (ret < 0) {
+						DHD_ERROR(("failed to set nd_ra_filter (%d)\n",
+							ret));
+					}
+				}
+				dhd_os_suppress_logging(dhd, FALSE);
+#ifdef CUSTOM_EVENT_PM_WAKE
+				dhd_set_excess_pm_awake(dhd, FALSE);
+#endif /* CUSTOM_EVENT_PM_WAKE */
+#endif /* DHD_USE_EARLYSUSPEND || DHD_USE_PM_SLEEP */
+#ifdef WL_CFG80211
+				wl_cfg80211_soft_suspend(dev, FALSE);
+#endif /* WL_CFG80211 */
+			}
+	}
+	dhd_suspend_unlock(dhd);
+
+	return 0;
+}
+
+static int dhd_suspend_resume_helper(struct dhd_info *dhd, int val, int force)
+{
+	dhd_pub_t *dhdp = &dhd->pub;
+	int ret = 0;
+
+#if !defined(DHD_USE_PM_SLEEP)
+	DHD_OS_WAKE_LOCK(dhdp);
+#endif /* !defined(DHD_USE_PM_SLEEP) */
+
+	/* Set flag when early suspend was called */
+	dhdp->in_suspend = val;
+	if ((force || !dhdp->suspend_disable_flag) &&
+		(dhd_support_sta_mode(dhdp) || dhd_conf_get_insuspend(dhdp, ALL_IN_SUSPEND)))
+	{
+		ret = dhd_set_suspend(val, dhdp);
+	}
+
+#if !defined(DHD_USE_PM_SLEEP)
+	DHD_OS_WAKE_UNLOCK(dhdp);
+#endif /* !defined(DHD_USE_PM_SLEEP) */
+
+	return ret;
+}
+
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
+static void dhd_early_suspend(struct early_suspend *h)
+{
+	struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend);
+	DHD_TRACE_HW4(("%s: enter\n", __FUNCTION__));
+
+	if (dhd && (dhd->pub.conf->suspend_mode == EARLY_SUSPEND ||
+			dhd->pub.conf->suspend_mode == SUSPEND_MODE_2)) {
+		dhd_suspend_resume_helper(dhd, 1, 0);
+		if (dhd->pub.conf->suspend_mode == EARLY_SUSPEND)
+			dhd_conf_set_suspend_resume(&dhd->pub, 1);
+	}
+}
+
+static void dhd_late_resume(struct early_suspend *h)
+{
+	struct dhd_info *dhd = container_of(h, struct dhd_info, early_suspend);
+	DHD_TRACE_HW4(("%s: enter\n", __FUNCTION__));
+
+	if (dhd && (dhd->pub.conf->suspend_mode == EARLY_SUSPEND ||
+			dhd->pub.conf->suspend_mode == SUSPEND_MODE_2)) {
+		dhd_conf_set_suspend_resume(&dhd->pub, 0);
+		if (dhd->pub.conf->suspend_mode == EARLY_SUSPEND)
+			dhd_suspend_resume_helper(dhd, 0, 0);
+	}
+}
+#endif /* CONFIG_HAS_EARLYSUSPEND && DHD_USE_EARLYSUSPEND */
+
+/*
+ * Generalized timeout mechanism.  Uses spin sleep with exponential back-off until
+ * the sleep time reaches one jiffy, then switches over to task delay.  Usage:
+ *
+ *      dhd_timeout_start(&tmo, usec);
+ *      while (!dhd_timeout_expired(&tmo))
+ *              if (poll_something())
+ *                      break;
+ *      if (dhd_timeout_expired(&tmo))
+ *              fatal();
+ */
+
+void
+dhd_timeout_start(dhd_timeout_t *tmo, uint usec)
+{
+#ifdef BCMQT
+	tmo->limit = usec * htclkratio;
+#else
+	tmo->limit = usec;
+#endif
+	tmo->increment = 0;
+	tmo->elapsed = 0;
+	tmo->tick = 10 * USEC_PER_MSEC;	/* 10 msec */
+}
+
+int
+dhd_timeout_expired(dhd_timeout_t *tmo)
+{
+	/* Does nothing the first call */
+	if (tmo->increment == 0) {
+		tmo->increment = USEC_PER_MSEC;	/* Start with 1 msec */
+		return 0;
+	}
+
+	if (tmo->elapsed >= tmo->limit)
+		return 1;
+
+	DHD_INFO(("%s: CAN_SLEEP():%d tmo->increment=%ld msec\n",
+		__FUNCTION__, CAN_SLEEP(), tmo->increment / USEC_PER_MSEC));
+
+	CAN_SLEEP() ? OSL_SLEEP(tmo->increment / USEC_PER_MSEC) : OSL_DELAY(tmo->increment);
+
+	/* Till tmo->tick, the delay will be in 2x, after that delay will be constant
+	 * tmo->tick (10 msec), till timer elapses.
+	 */
+	tmo->increment = (tmo->increment >= tmo->tick) ? tmo->tick : (tmo->increment * 2);
+
+	/* Add the delay that's about to take place */
+#ifdef BCMQT
+	tmo->elapsed += tmo->increment * htclkratio;
+#else
+	tmo->elapsed += tmo->increment;
+#endif
+
+	return 0;
+}
+
+int
+dhd_net2idx(dhd_info_t *dhd, struct net_device *net)
+{
+	int i = 0;
+
+	if (!dhd) {
+		DHD_ERROR(("%s : DHD_BAD_IF return\n", __FUNCTION__));
+		return DHD_BAD_IF;
+	}
+
+	while (i < DHD_MAX_IFS) {
+		if (dhd->iflist[i] && dhd->iflist[i]->net && (dhd->iflist[i]->net == net))
+			return i;
+		i++;
+	}
+
+	return DHD_BAD_IF;
+}
+
+struct net_device * dhd_idx2net(void *pub, int ifidx)
+{
+	struct dhd_pub *dhd_pub = (struct dhd_pub *)pub;
+	struct dhd_info *dhd_info;
+
+	if (!dhd_pub || ifidx < 0 || ifidx >= DHD_MAX_IFS)
+		return NULL;
+	dhd_info = dhd_pub->info;
+	if (dhd_info && dhd_info->iflist[ifidx])
+		return dhd_info->iflist[ifidx]->net;
+	return NULL;
+}
+
+int
+dhd_ifname2idx(dhd_info_t *dhd, char *name)
+{
+	int i = DHD_MAX_IFS;
+
+	ASSERT(dhd);
+
+	if (name == NULL || *name == '\0')
+		return 0;
+
+	while (--i > 0)
+		if (dhd->iflist[i] && !strncmp(dhd->iflist[i]->dngl_name, name, IFNAMSIZ))
+				break;
+
+	DHD_TRACE(("%s: return idx %d for \"%s\"\n", __FUNCTION__, i, name));
+
+	return i;	/* default - the primary interface */
+}
+
+char *
+dhd_ifname(dhd_pub_t *dhdp, int ifidx)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+
+	ASSERT(dhd);
+
+	if (ifidx < 0 || ifidx >= DHD_MAX_IFS) {
+		DHD_ERROR(("%s: ifidx %d out of range\n", __FUNCTION__, ifidx));
+		return "<if_bad>";
+	}
+
+	if (dhd->iflist[ifidx] == NULL) {
+		DHD_ERROR(("%s: null i/f %d\n", __FUNCTION__, ifidx));
+		return "<if_null>";
+	}
+
+	if (dhd->iflist[ifidx]->net)
+		return dhd->iflist[ifidx]->net->name;
+
+	return "<if_none>";
+}
+
+uint8 *
+dhd_bssidx2bssid(dhd_pub_t *dhdp, int idx)
+{
+	int i;
+	dhd_info_t *dhd = (dhd_info_t *)dhdp;
+
+	ASSERT(dhd);
+	for (i = 0; i < DHD_MAX_IFS; i++)
+	if (dhd->iflist[i] && dhd->iflist[i]->bssidx == idx)
+		return dhd->iflist[i]->mac_addr;
+
+	return NULL;
+}
+
+static void
+_dhd_set_multicast_list(dhd_info_t *dhd, int ifidx)
+{
+	struct net_device *dev;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+	struct netdev_hw_addr *ha;
+#else
+	struct dev_mc_list *mclist;
+#endif
+	uint32 allmulti, cnt;
+
+	wl_ioctl_t ioc;
+	char *buf, *bufp;
+	uint buflen;
+	int ret;
+
+#ifdef MCAST_LIST_ACCUMULATION
+	int i;
+	uint32 cnt_iface[DHD_MAX_IFS];
+	cnt = 0;
+	allmulti = 0;
+
+	for (i = 0; i < DHD_MAX_IFS; i++) {
+		if (dhd->iflist[i]) {
+			dev = dhd->iflist[i]->net;
+			if (!dev)
+				continue;
+			netif_addr_lock_bh(dev);
+			cnt_iface[i] = netdev_mc_count(dev);
+			cnt += cnt_iface[i];
+			netif_addr_unlock_bh(dev);
+
+			/* Determine initial value of allmulti flag */
+			allmulti |= (dev->flags & IFF_ALLMULTI) ? TRUE : FALSE;
+		}
+	}
+#else /* !MCAST_LIST_ACCUMULATION */
+	if (!dhd->iflist[ifidx]) {
+		DHD_ERROR(("%s : dhd->iflist[%d] was NULL\n", __FUNCTION__, ifidx));
+		return;
+	}
+	dev = dhd->iflist[ifidx]->net;
+	if (!dev)
+		return;
+	netif_addr_lock_bh(dev);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+	cnt = netdev_mc_count(dev);
+#else
+	cnt = dev->mc_count;
+#endif /* LINUX_VERSION_CODE */
+
+	netif_addr_unlock_bh(dev);
+
+	/* Determine initial value of allmulti flag */
+	allmulti = (dev->flags & IFF_ALLMULTI) ? TRUE : FALSE;
+#endif /* MCAST_LIST_ACCUMULATION */
+
+#ifdef PASS_ALL_MCAST_PKTS
+	if (!dhd->pub.early_suspended) {
+		allmulti = TRUE;
+	}
+#endif /* PASS_ALL_MCAST_PKTS */
+
+	/* Send down the multicast list first. */
+
+	/* XXX Not using MAXMULTILIST to avoid including wlc_pub.h; but
+	 * maybe we should?  (Or should that be in wlioctl.h instead?)
+	 */
+
+	buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETHER_ADDR_LEN);
+	if (!(bufp = buf = MALLOC(dhd->pub.osh, buflen))) {
+		DHD_ERROR(("%s: out of memory for mcast_list, cnt %d\n",
+		           dhd_ifname(&dhd->pub, ifidx), cnt));
+		return;
+	}
+
+	strlcpy(bufp, "mcast_list", buflen);
+	bufp += strlen("mcast_list") + 1;
+
+	cnt = htol32(cnt);
+	memcpy(bufp, &cnt, sizeof(cnt));
+	bufp += sizeof(cnt);
+
+#ifdef MCAST_LIST_ACCUMULATION
+	for (i = 0; i < DHD_MAX_IFS; i++) {
+		if (dhd->iflist[i]) {
+			DHD_TRACE(("_dhd_set_multicast_list: ifidx %d\n", i));
+			dev = dhd->iflist[i]->net;
+
+			netif_addr_lock_bh(dev);
+			GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+			netdev_for_each_mc_addr(ha, dev) {
+				GCC_DIAGNOSTIC_POP();
+				if (!cnt_iface[i])
+					break;
+				memcpy(bufp, ha->addr, ETHER_ADDR_LEN);
+				bufp += ETHER_ADDR_LEN;
+				DHD_TRACE(("_dhd_set_multicast_list: cnt "
+					"%d " MACDBG "\n",
+					cnt_iface[i], MAC2STRDBG(ha->addr)));
+				cnt_iface[i]--;
+			}
+			netif_addr_unlock_bh(dev);
+		}
+	}
+#else /* !MCAST_LIST_ACCUMULATION */
+	netif_addr_lock_bh(dev);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	netdev_for_each_mc_addr(ha, dev) {
+		GCC_DIAGNOSTIC_POP();
+		if (!cnt)
+			break;
+		memcpy(bufp, ha->addr, ETHER_ADDR_LEN);
+		bufp += ETHER_ADDR_LEN;
+		cnt--;
+	}
+#else
+	for (mclist = dev->mc_list; (mclist && (cnt > 0));
+			cnt--, mclist = mclist->next) {
+		memcpy(bufp, (void *)mclist->dmi_addr, ETHER_ADDR_LEN);
+		bufp += ETHER_ADDR_LEN;
+	}
+#endif /* LINUX_VERSION_CODE */
+	netif_addr_unlock_bh(dev);
+#endif /* MCAST_LIST_ACCUMULATION */
+
+	memset(&ioc, 0, sizeof(ioc));
+	ioc.cmd = WLC_SET_VAR;
+	ioc.buf = buf;
+	ioc.len = buflen;
+	ioc.set = TRUE;
+
+	ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+	if (ret < 0) {
+		DHD_ERROR(("%s: set mcast_list failed, cnt %d\n",
+			dhd_ifname(&dhd->pub, ifidx), cnt));
+		allmulti = cnt ? TRUE : allmulti;
+	}
+
+	MFREE(dhd->pub.osh, buf, buflen);
+
+	/* Now send the allmulti setting.  This is based on the setting in the
+	 * net_device flags, but might be modified above to be turned on if we
+	 * were trying to set some addresses and dongle rejected it...
+	 */
+
+	allmulti = htol32(allmulti);
+	ret = dhd_iovar(&dhd->pub, ifidx, "allmulti", (char *)&allmulti,
+			sizeof(allmulti), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: set allmulti %d failed\n",
+		           dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti)));
+	}
+
+	/* Finally, pick up the PROMISC flag as well, like the NIC driver does */
+
+#ifdef MCAST_LIST_ACCUMULATION
+	allmulti = 0;
+	for (i = 0; i < DHD_MAX_IFS; i++) {
+		if (dhd->iflist[i]) {
+			dev = dhd->iflist[i]->net;
+			allmulti |= (dev->flags & IFF_PROMISC) ? TRUE : FALSE;
+		}
+	}
+#else
+	allmulti = (dev->flags & IFF_PROMISC) ? TRUE : FALSE;
+#endif /* MCAST_LIST_ACCUMULATION */
+
+	allmulti = htol32(allmulti);
+
+	memset(&ioc, 0, sizeof(ioc));
+	ioc.cmd = WLC_SET_PROMISC;
+	ioc.buf = &allmulti;
+	ioc.len = sizeof(allmulti);
+	ioc.set = TRUE;
+
+	ret = dhd_wl_ioctl(&dhd->pub, ifidx, &ioc, ioc.buf, ioc.len);
+	if (ret < 0) {
+		DHD_ERROR(("%s: set promisc %d failed\n",
+		           dhd_ifname(&dhd->pub, ifidx), ltoh32(allmulti)));
+	}
+}
+
+int
+_dhd_set_mac_address(dhd_info_t *dhd, int ifidx, uint8 *addr, bool skip_stop)
+{
+#if defined(DHD_NOTIFY_MAC_CHANGED) && defined(WL_STATIC_IF)
+	struct net_device *net = NULL;
+	struct bcm_cfg80211 *cfg = NULL;
+#endif /* DHD_NOTIFY_MAC_CHANGED && WL_STATIC_IF */
+	int ret;
+
+#ifdef DHD_NOTIFY_MAC_CHANGED
+#ifdef WL_STATIC_IF
+	net = dhd_idx2net(&dhd->pub, ifidx);
+	if (net)
+		cfg = wl_get_cfg(net);
+	if (cfg && wl_cfg80211_static_if(cfg, net)) {
+		skip_stop = FALSE;
+		WL_MSG(dhd_ifname(&dhd->pub, ifidx), "set skip_stop %d\n", skip_stop);
+	}
+#endif /* WL_STATIC_IF */
+
+	if (skip_stop) {
+		WL_MSG(dhd_ifname(&dhd->pub, ifidx), "close dev for mac changing\n");
+		dhd->pub.skip_dhd_stop = TRUE;
+		dev_close(dhd->iflist[ifidx]->net);
+	}
+#endif /* DHD_NOTIFY_MAC_CHANGED */
+
+	ret = dhd_iovar(&dhd->pub, ifidx, "cur_etheraddr", (char *)addr,
+			ETHER_ADDR_LEN, NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: set cur_etheraddr %pM failed ret=%d\n",
+			dhd_ifname(&dhd->pub, ifidx), addr, ret));
+		goto exit;
+	} else {
+		DEV_ADDR_SET((dhd->iflist[ifidx]->net), addr);
+		if (ifidx == 0)
+			memcpy(dhd->pub.mac.octet, addr, ETHER_ADDR_LEN);
+		WL_MSG(dhd_ifname(&dhd->pub, ifidx), "MACID %pM is overwritten\n", addr);
+	}
+
+exit:
+#ifdef DHD_NOTIFY_MAC_CHANGED
+	if (skip_stop) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
+		ret = dev_open(dhd->iflist[ifidx]->net, NULL);
+#else
+		ret = dev_open(dhd->iflist[ifidx]->net);
+#endif
+		dhd->pub.skip_dhd_stop = FALSE;
+		WL_MSG(dhd_ifname(&dhd->pub, ifidx), "notify mac changed done\n");
+	}
+#endif /* DHD_NOTIFY_MAC_CHANGED */
+
+	return ret;
+}
+
+int dhd_update_rand_mac_addr(dhd_pub_t *dhd)
+{
+	struct ether_addr mac_addr;
+	dhd_generate_rand_mac_addr(&mac_addr);
+	if (_dhd_set_mac_address(dhd->info, 0, mac_addr.octet, TRUE) != 0) {
+		DHD_ERROR(("randmac setting failed\n"));
+#ifdef STA_RANDMAC_ENFORCED
+		return  BCME_BADADDR;
+#endif /* STA_RANDMAC_ENFORCED */
+	}
+	return BCME_OK;
+}
+
+#ifdef BCM_ROUTER_DHD
+void dhd_update_dpsta_interface_for_sta(dhd_pub_t* dhdp, int ifidx, void* event_data)
+{
+	struct wl_dpsta_intf_event *dpsta_prim_event = (struct wl_dpsta_intf_event *)event_data;
+	dhd_if_t *ifp = dhdp->info->iflist[ifidx];
+
+	if (dpsta_prim_event->intf_type == WL_INTF_DWDS) {
+		ifp->primsta_dwds = TRUE;
+	} else {
+		ifp->primsta_dwds = FALSE;
+	}
+}
+#endif /* BCM_ROUTER_DHD */
+
+#ifdef DHD_WMF
+void dhd_update_psta_interface_for_sta(dhd_pub_t* dhdp, char* ifname, void* ea,
+		void* event_data)
+{
+	struct wl_psta_primary_intf_event *psta_prim_event =
+			(struct wl_psta_primary_intf_event*)event_data;
+	dhd_sta_t *psta_interface =  NULL;
+	dhd_sta_t *sta = NULL;
+	uint8 ifindex;
+	ASSERT(ifname);
+	ASSERT(psta_prim_event);
+	ASSERT(ea);
+
+	ifindex = (uint8)dhd_ifname2idx(dhdp->info, ifname);
+	sta = dhd_find_sta(dhdp, ifindex, ea);
+	if (sta != NULL) {
+		psta_interface = dhd_find_sta(dhdp, ifindex,
+				(void *)(psta_prim_event->prim_ea.octet));
+		if (psta_interface != NULL) {
+			sta->psta_prim = psta_interface;
+		}
+	}
+}
+
+/* Get wmf_psta_disable configuration configuration */
+int dhd_get_wmf_psta_disable(dhd_pub_t *dhdp, uint32 idx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+	ASSERT(idx < DHD_MAX_IFS);
+	ifp = dhd->iflist[idx];
+	return ifp->wmf_psta_disable;
+}
+
+/* Set wmf_psta_disable configuration configuration */
+int dhd_set_wmf_psta_disable(dhd_pub_t *dhdp, uint32 idx, int val)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+	ASSERT(idx < DHD_MAX_IFS);
+	ifp = dhd->iflist[idx];
+	ifp->wmf_psta_disable = val;
+	return 0;
+}
+#endif /* DHD_WMF */
+
+#ifdef DHD_PSTA
+/* Get psta/psr configuration configuration */
+int dhd_get_psta_mode(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = dhdp->info;
+	return (int)dhd->psta_mode;
+}
+/* Set psta/psr configuration configuration */
+int dhd_set_psta_mode(dhd_pub_t *dhdp, uint32 val)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd->psta_mode = val;
+	return 0;
+}
+#endif /* DHD_PSTA */
+
+#if (defined(DHD_WET) || defined(DHD_MCAST_REGEN) || defined(DHD_L2_FILTER))
+static void
+dhd_update_rx_pkt_chainable_state(dhd_pub_t* dhdp, uint32 idx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(idx < DHD_MAX_IFS);
+
+	ifp = dhd->iflist[idx];
+
+	if (
+#ifdef DHD_L2_FILTER
+		(ifp->block_ping) ||
+#endif
+#ifdef DHD_WET
+		(dhd->wet_mode) ||
+#endif
+#ifdef DHD_MCAST_REGEN
+		(ifp->mcast_regen_bss_enable) ||
+#endif
+		FALSE) {
+		ifp->rx_pkt_chainable = FALSE;
+	}
+}
+#endif /* DHD_WET || DHD_MCAST_REGEN || DHD_L2_FILTER */
+
+#ifdef DHD_WET
+/* Get wet configuration configuration */
+int dhd_get_wet_mode(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = dhdp->info;
+	return (int)dhd->wet_mode;
+}
+
+/* Set wet configuration configuration */
+int dhd_set_wet_mode(dhd_pub_t *dhdp, uint32 val)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd->wet_mode = val;
+	dhd_update_rx_pkt_chainable_state(dhdp, 0);
+	return 0;
+}
+#endif /* DHD_WET */
+
+#if defined(WL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
+int32 dhd_role_to_nl80211_iftype(int32 role)
+{
+	switch (role) {
+	case WLC_E_IF_ROLE_STA:
+		return NL80211_IFTYPE_STATION;
+	case WLC_E_IF_ROLE_AP:
+		return NL80211_IFTYPE_AP;
+	case WLC_E_IF_ROLE_WDS:
+		return NL80211_IFTYPE_WDS;
+	case WLC_E_IF_ROLE_P2P_GO:
+		return NL80211_IFTYPE_P2P_GO;
+	case WLC_E_IF_ROLE_P2P_CLIENT:
+		return NL80211_IFTYPE_P2P_CLIENT;
+	case WLC_E_IF_ROLE_IBSS:
+	case WLC_E_IF_ROLE_NAN:
+		return NL80211_IFTYPE_ADHOC;
+	default:
+		return NL80211_IFTYPE_UNSPECIFIED;
+	}
+}
+#endif /* WL_CFG80211 && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */
+
+static void
+dhd_ifadd_event_handler(void *handle, void *event_info, u8 event)
+{
+	dhd_info_t *dhd = handle;
+	dhd_if_event_t *if_event = event_info;
+	int ifidx, bssidx;
+	int ret = 0;
+#if defined(WL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
+	struct wl_if_event_info info;
+#endif /* WL_CFG80211 && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */
+	struct net_device *ndev = NULL;
+
+	BCM_REFERENCE(ret);
+	if (event != DHD_WQ_WORK_IF_ADD) {
+		DHD_ERROR(("%s: unexpected event \n", __FUNCTION__));
+		return;
+	}
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd info not available \n", __FUNCTION__));
+		return;
+	}
+
+	if (!if_event) {
+		DHD_ERROR(("%s: event data is null \n", __FUNCTION__));
+		return;
+	}
+
+	dhd_net_if_lock_local(dhd);
+
+	ifidx = if_event->event.ifidx;
+	bssidx = if_event->event.bssidx;
+	DHD_TRACE(("%s: registering if with ifidx %d\n", __FUNCTION__, ifidx));
+
+#if defined(WL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
+	if (if_event->event.ifidx > 0) {
+		u8 *mac_addr;
+		bzero(&info, sizeof(info));
+		info.ifidx = ifidx;
+		info.bssidx = bssidx;
+		info.role = if_event->event.role;
+		strlcpy(info.name, if_event->name, sizeof(info.name));
+		if (is_valid_ether_addr(if_event->mac)) {
+			mac_addr = if_event->mac;
+		} else {
+			mac_addr = NULL;
+		}
+
+		if ((ndev = wl_cfg80211_post_ifcreate(dhd->pub.info->iflist[0]->net,
+			&info, mac_addr, NULL, true)) == NULL) {
+			/* Do the post interface create ops */
+			DHD_ERROR(("Post ifcreate ops failed. Returning \n"));
+			ret = BCME_ERROR;
+			goto done;
+		}
+	}
+#else
+	/* This path is for non-android case */
+	/* The interface name in host and in event msg are same */
+	/* if name in event msg is used to create dongle if list on host */
+	ndev = dhd_allocate_if(&dhd->pub, ifidx, if_event->name,
+		if_event->mac, bssidx, TRUE, if_event->name);
+	if (!ndev) {
+		DHD_ERROR(("%s: net device alloc failed  \n", __FUNCTION__));
+		ret = BCME_NOMEM;
+		goto done;
+	}
+
+	ret = dhd_register_if(&dhd->pub, ifidx, TRUE);
+	if (ret != BCME_OK) {
+		DHD_ERROR(("%s: dhd_register_if failed\n", __FUNCTION__));
+		dhd_remove_if(&dhd->pub, ifidx, TRUE);
+		goto done;
+	}
+
+#endif /* WL_CFG80211 && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */
+
+#ifndef PCIE_FULL_DONGLE
+	/* Turn on AP isolation in the firmware for interfaces operating in AP mode */
+	if (FW_SUPPORTED((&dhd->pub), ap) && (if_event->event.role != WLC_E_IF_ROLE_STA)) {
+		uint32 var_int =  1;
+		ret = dhd_iovar(&dhd->pub, ifidx, "ap_isolate", (char *)&var_int, sizeof(var_int),
+				NULL, 0, TRUE);
+		if (ret != BCME_OK) {
+			DHD_ERROR(("%s: Failed to set ap_isolate to dongle\n", __FUNCTION__));
+			dhd_remove_if(&dhd->pub, ifidx, TRUE);
+		}
+	}
+#endif /* PCIE_FULL_DONGLE */
+
+done:
+
+	MFREE(dhd->pub.osh, if_event, sizeof(dhd_if_event_t));
+#if defined(WLDWDS) && defined(FOURADDR_AUTO_BRG)
+	if (ndev) {
+		dhd_bridge_dev_set(dhd, ifidx, ndev);
+	} else {
+		DHD_ERROR(("Netdev not found! Do nothing.\n"));
+	}
+#endif /* defiend(WLDWDS) && defined(FOURADDR_AUTO_BRG) */
+
+	dhd_net_if_unlock_local(dhd);
+}
+
+static void
+dhd_ifdel_event_handler(void *handle, void *event_info, u8 event)
+{
+	dhd_info_t *dhd = handle;
+	int ifidx;
+	dhd_if_event_t *if_event = event_info;
+
+	if (event != DHD_WQ_WORK_IF_DEL) {
+		DHD_ERROR(("%s: unexpected event \n", __FUNCTION__));
+		return;
+	}
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd info not available \n", __FUNCTION__));
+		return;
+	}
+
+	if (!if_event) {
+		DHD_ERROR(("%s: event data is null \n", __FUNCTION__));
+		return;
+	}
+
+	dhd_net_if_lock_local(dhd);
+
+	ifidx = if_event->event.ifidx;
+	DHD_TRACE(("Removing interface with idx %d\n", ifidx));
+	if (!dhd->pub.info->iflist[ifidx]) {
+		/* No matching netdev found */
+		DHD_ERROR(("Netdev not found! Do nothing.\n"));
+		goto done;
+	}
+#if defined(WLDWDS) && defined(FOURADDR_AUTO_BRG)
+	dhd_bridge_dev_set(dhd, ifidx, NULL);
+#endif /* defiend(WLDWDS) && defined(FOURADDR_AUTO_BRG) */
+
+#if defined(WL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
+	if (if_event->event.ifidx > 0) {
+		/* Do the post interface del ops */
+		if (wl_cfg80211_post_ifdel(dhd->pub.info->iflist[ifidx]->net,
+				true, if_event->event.ifidx) != 0) {
+			DHD_TRACE(("Post ifdel ops failed. Returning \n"));
+			goto done;
+		}
+	}
+#else
+	/* For non-cfg80211 drivers */
+	dhd_remove_if(&dhd->pub, ifidx, TRUE);
+
+#endif /* WL_CFG80211 && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) */
+
+done:
+	MFREE(dhd->pub.osh, if_event, sizeof(dhd_if_event_t));
+	dhd_net_if_unlock_local(dhd);
+}
+
+#ifdef DHD_UPDATE_INTF_MAC
+static void
+dhd_ifupdate_event_handler(void *handle, void *event_info, u8 event)
+{
+	dhd_info_t *dhd = handle;
+	int ifidx;
+	dhd_if_event_t *if_event = event_info;
+
+	if (event != DHD_WQ_WORK_IF_UPDATE) {
+		DHD_ERROR(("%s: unexpected event \n", __FUNCTION__));
+		return;
+	}
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd info not available \n", __FUNCTION__));
+		return;
+	}
+
+	if (!if_event) {
+		DHD_ERROR(("%s: event data is null \n", __FUNCTION__));
+		return;
+	}
+
+	dhd_net_if_lock_local(dhd);
+	DHD_OS_WAKE_LOCK(&dhd->pub);
+
+	ifidx = if_event->event.ifidx;
+	DHD_TRACE(("%s: Update interface with idx %d\n", __FUNCTION__, ifidx));
+
+	dhd_op_if_update(&dhd->pub, ifidx);
+
+	MFREE(dhd->pub.osh, if_event, sizeof(dhd_if_event_t));
+
+	DHD_OS_WAKE_UNLOCK(&dhd->pub);
+	dhd_net_if_unlock_local(dhd);
+}
+
+int dhd_op_if_update(dhd_pub_t *dhdpub, int ifidx)
+{
+	dhd_info_t *    dhdinfo = NULL;
+	dhd_if_t   *    ifp = NULL;
+	int             ret = 0;
+	char            buf[128];
+
+	if ((NULL==dhdpub)||(NULL==dhdpub->info)) {
+		DHD_ERROR(("%s: *** DHD handler is NULL!\n", __FUNCTION__));
+		return -1;
+	} else {
+		dhdinfo = (dhd_info_t *)dhdpub->info;
+		ifp = dhdinfo->iflist[ifidx];
+		if (NULL==ifp) {
+		    DHD_ERROR(("%s: *** ifp handler is NULL!\n", __FUNCTION__));
+		    return -2;
+		}
+	}
+
+	DHD_TRACE(("%s: idx %d\n", __FUNCTION__, ifidx));
+	// Get MAC address
+	strcpy(buf, "cur_etheraddr");
+	ret = dhd_wl_ioctl_cmd(&dhdinfo->pub, WLC_GET_VAR, buf, sizeof(buf), FALSE, ifp->idx);
+	if (0>ret) {
+		DHD_ERROR(("Failed to upudate the MAC address for itf=%s, ret=%d\n", ifp->name, ret));
+		// avoid collision
+		dhdinfo->iflist[ifp->idx]->mac_addr[5] += 1;
+		// force locally administrate address
+		ETHER_SET_LOCALADDR(&dhdinfo->iflist[ifp->idx]->mac_addr);
+	} else {
+		DHD_EVENT(("Got mac for itf %s, idx %d, MAC=%02X:%02X:%02X:%02X:%02X:%02X\n",
+		           ifp->name, ifp->idx,
+		           (unsigned char)buf[0], (unsigned char)buf[1], (unsigned char)buf[2],
+		           (unsigned char)buf[3], (unsigned char)buf[4], (unsigned char)buf[5]));
+		memcpy(dhdinfo->iflist[ifp->idx]->mac_addr, buf, ETHER_ADDR_LEN);
+		if (dhdinfo->iflist[ifp->idx]->net) {
+			dev_addr_set(dhdinfo->iflist[ifp->idx]->net, buf);
+		}
+	}
+
+	return ret;
+}
+#endif /* DHD_UPDATE_INTF_MAC */
+
+static void
+dhd_set_mac_addr_handler(void *handle, void *event_info, u8 event)
+{
+	dhd_info_t *dhd = handle;
+	int ifidx = (int)((long int)event_info);
+	dhd_if_t *ifp = NULL;
+
+	if (event != DHD_WQ_WORK_SET_MAC) {
+		DHD_ERROR(("%s: unexpected event \n", __FUNCTION__));
+	}
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd info not available \n", __FUNCTION__));
+		return;
+	}
+
+#ifdef DHD_NOTIFY_MAC_CHANGED
+	rtnl_lock();
+#endif /* DHD_NOTIFY_MAC_CHANGED */
+	dhd_net_if_lock_local(dhd);
+	DHD_OS_WAKE_LOCK(&dhd->pub);
+
+	ifp = dhd->iflist[ifidx];
+
+	// terence 20160907: fix for not able to set mac when wlan0 is down
+	if (ifp == NULL || !ifp->set_macaddress) {
+		goto done;
+	}
+	if (ifp == NULL || !dhd->pub.up) {
+		DHD_ERROR(("%s: interface info not available/down \n", __FUNCTION__));
+		goto done;
+	}
+
+	ifp->set_macaddress = FALSE;
+
+	if (_dhd_set_mac_address(dhd, ifp->idx, ifp->mac_addr, TRUE) == 0)
+		DHD_INFO(("%s: MACID is overwritten\n",	__FUNCTION__));
+	else
+		DHD_ERROR(("%s: _dhd_set_mac_address() failed\n", __FUNCTION__));
+
+done:
+	DHD_OS_WAKE_UNLOCK(&dhd->pub);
+	dhd_net_if_unlock_local(dhd);
+#ifdef DHD_NOTIFY_MAC_CHANGED
+	rtnl_unlock();
+#endif /* DHD_NOTIFY_MAC_CHANGED */
+}
+
+static void
+dhd_ndev_upd_features_handler(void *handle, void *event_info, u8 event)
+{
+	struct net_device *net = event_info;
+
+	if (event != DHD_WQ_WORK_NDEV_UPD_FEATURES) {
+		DHD_ERROR(("%s: unexpected event \n", __FUNCTION__));
+		return;
+	}
+	if (!net) {
+		DHD_ERROR(("%s: event data is null \n", __FUNCTION__));
+		return;
+	}
+	rtnl_lock();
+	netdev_update_features(net);
+	rtnl_unlock();
+}
+
+static void
+dhd_ndev_upd_features(dhd_info_t *dhd, struct net_device *net)
+{
+	dhd_deferred_schedule_work(dhd->dhd_deferred_wq, (void *)net,
+		DHD_WQ_WORK_NDEV_UPD_FEATURES, dhd_ndev_upd_features_handler,
+		DHD_WQ_WORK_PRIORITY_HIGH);
+}
+
+static void
+dhd_set_mcast_list_handler(void *handle, void *event_info, u8 event)
+{
+	dhd_info_t *dhd = handle;
+	int ifidx = (int)((long int)event_info);
+	dhd_if_t *ifp = NULL;
+
+	if (event != DHD_WQ_WORK_SET_MCAST_LIST) {
+		DHD_ERROR(("%s: unexpected event \n", __FUNCTION__));
+		return;
+	}
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd info not available \n", __FUNCTION__));
+		return;
+	}
+
+	dhd_net_if_lock_local(dhd);
+	DHD_OS_WAKE_LOCK(&dhd->pub);
+
+	ifp = dhd->iflist[ifidx];
+
+	if (ifp == NULL || !dhd->pub.up) {
+		DHD_ERROR(("%s: interface info not available/down \n", __FUNCTION__));
+		goto done;
+	}
+
+	ifidx = ifp->idx;
+
+#ifdef MCAST_LIST_ACCUMULATION
+	ifidx = 0;
+#endif /* MCAST_LIST_ACCUMULATION */
+
+	_dhd_set_multicast_list(dhd, ifidx);
+	DHD_INFO(("%s: set multicast list for if %d\n", __FUNCTION__, ifidx));
+
+done:
+	DHD_OS_WAKE_UNLOCK(&dhd->pub);
+	dhd_net_if_unlock_local(dhd);
+}
+
+static int
+dhd_set_mac_address(struct net_device *dev, void *addr)
+{
+	int ret = 0;
+
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	struct sockaddr *sa = (struct sockaddr *)addr;
+	int ifidx;
+	dhd_if_t *dhdif;
+#ifdef WL_STATIC_IF
+	struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+#endif /* WL_STATIC_IF */
+	dhd_pub_t *dhdp = &dhd->pub;
+	bool addr_chngd = TRUE;
+
+	BCM_REFERENCE(ifidx);
+	BCM_REFERENCE(addr_chngd);
+
+	DHD_TRACE(("%s \n", __func__));
+
+	dhdif = dhd_get_ifp_by_ndev(dhdp, dev);
+	if (!dhdif) {
+		return -ENODEV;
+	}
+	ifidx = dhdif->idx;
+	dhd_net_if_lock_local(dhd);
+	if (memcmp(dhdif->mac_addr, sa->sa_data, ETHER_ADDR_LEN) == 0) {
+		addr_chngd = FALSE;
+	}
+	memcpy(dhdif->mac_addr, sa->sa_data, ETHER_ADDR_LEN);
+	dhdif->set_macaddress = TRUE;
+	dhd_net_if_unlock_local(dhd);
+
+	WL_MSG(dev->name, "macaddr = %pM\n", dhdif->mac_addr);
+#ifdef WL_CFG80211
+	/* Check wdev->iftype for the role */
+	if (wl_cfg80211_macaddr_sync_reqd(dev)) {
+		/* Supplicant and certain user layer applications expect macaddress to be
+		 * set once the context returns. so set it from the same context
+		 */
+#ifdef WL_STATIC_IF
+		if (wl_cfg80211_static_if(cfg, dev) && !(dev->flags & IFF_UP)) {
+			/* In softap case, the macaddress will be applied before interface up
+			 * and hence curether_addr can't be done at this stage (no fw iface
+			 * available). Store the address and return. macaddr will be applied
+			 * from interface create context.
+			 */
+			DEV_ADDR_SET(dev, dhdif->mac_addr);
+			return ret;
+		}
+#endif /* WL_STATIC_IF */
+		wl_cfg80211_handle_macaddr_change(dev, dhdif->mac_addr);
+		ret = _dhd_set_mac_address(dhd, ifidx, dhdif->mac_addr, TRUE);
+		if ((ret == BCME_OK) && (addr_chngd == TRUE)) {
+			/* Notify Dev/Address change to upperlayer */
+			netdev_state_change(dev);
+		}
+		return ret;
+	}
+#endif /* WL_CFG80211 */
+
+	dhd_deferred_schedule_work(dhd->dhd_deferred_wq, (void *)((long int)ifidx),
+		DHD_WQ_WORK_SET_MAC, dhd_set_mac_addr_handler, DHD_WQ_WORK_PRIORITY_LOW);
+	return ret;
+}
+
+static void
+dhd_set_multicast_list(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	int ifidx;
+
+	ifidx = dhd_net2idx(dhd, dev);
+	if (ifidx == DHD_BAD_IF)
+		return;
+
+	dhd->iflist[ifidx]->set_multicast = TRUE;
+	dhd_deferred_schedule_work(dhd->dhd_deferred_wq, (void *)((long int)ifidx),
+		DHD_WQ_WORK_SET_MCAST_LIST, dhd_set_mcast_list_handler, DHD_WQ_WORK_PRIORITY_LOW);
+
+	// terence 20160907: fix for not able to set mac when wlan0 is down
+	dhd_deferred_schedule_work(dhd->dhd_deferred_wq, (void *)((long int)ifidx),
+		DHD_WQ_WORK_SET_MAC, dhd_set_mac_addr_handler, DHD_WQ_WORK_PRIORITY_LOW);
+}
+
+#ifdef DHD_UCODE_DOWNLOAD
+/* Get ucode path */
+char *
+dhd_get_ucode_path(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = dhdp->info;
+	return dhd->uc_path;
+}
+#endif /* DHD_UCODE_DOWNLOAD */
+
+#ifdef PROP_TXSTATUS
+int
+dhd_os_wlfc_block(dhd_pub_t *pub)
+{
+	dhd_info_t *di = (dhd_info_t *)(pub->info);
+	ASSERT(di != NULL);
+	/* terence 20161229: don't do spin lock if proptx not enabled */
+	if (disable_proptx)
+		return 1;
+#ifdef BCMDBUS
+	spin_lock_irqsave(&di->wlfc_spinlock, di->wlfc_lock_flags);
+#else
+	spin_lock_bh(&di->wlfc_spinlock);
+#endif /* BCMDBUS */
+	return 1;
+}
+
+int
+dhd_os_wlfc_unblock(dhd_pub_t *pub)
+{
+	dhd_info_t *di = (dhd_info_t *)(pub->info);
+
+	ASSERT(di != NULL);
+	/* terence 20161229: don't do spin lock if proptx not enabled */
+	if (disable_proptx)
+		return 1;
+#ifdef BCMDBUS
+	spin_unlock_irqrestore(&di->wlfc_spinlock, di->wlfc_lock_flags);
+#else
+	spin_unlock_bh(&di->wlfc_spinlock);
+#endif /* BCMDBUS */
+	return 1;
+}
+
+#endif /* PROP_TXSTATUS */
+
+void
+dhd_netif_rx_ni(struct sk_buff * skb)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 18, 0)
+	/* Do not call netif_recieve_skb as this workqueue scheduler is
+	 * not from NAPI Also as we are not in INTR context, do not call
+	 * netif_rx, instead call netif_rx_ni (for kerenl >= 2.6) which
+	 * does netif_rx, disables irq, raise NET_IF_RX softirq and
+	 * enables interrupts back
+	 */
+	netif_rx_ni(skb);
+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) */
+	netif_rx(skb);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0) */
+}
+
+/*  This routine do not support Packet chain feature, Currently tested for
+ *  proxy arp feature
+ */
+int dhd_sendup(dhd_pub_t *dhdp, int ifidx, void *p)
+{
+	struct sk_buff *skb;
+	void *skbhead = NULL;
+	void *skbprev = NULL;
+	dhd_if_t *ifp;
+	ASSERT(!PKTISCHAINED(p));
+	skb = PKTTONATIVE(dhdp->osh, p);
+
+	ifp = dhdp->info->iflist[ifidx];
+	skb->dev = ifp->net;
+	skb->protocol = eth_type_trans(skb, skb->dev);
+
+	if (in_interrupt()) {
+		bcm_object_trace_opr(skb, BCM_OBJDBG_REMOVE,
+			__FUNCTION__, __LINE__);
+		netif_rx(skb);
+	} else {
+		if (dhdp->info->rxthread_enabled) {
+			if (!skbhead) {
+				skbhead = skb;
+			} else {
+				PKTSETNEXT(dhdp->osh, skbprev, skb);
+			}
+			skbprev = skb;
+		} else {
+			/* If the receive is not processed inside an ISR,
+			 * the softirqd must be woken explicitly to service
+			 * the NET_RX_SOFTIRQ.	In 2.6 kernels, this is handled
+			 * by netif_rx_ni(), but in earlier kernels, we need
+			 * to do it manually.
+			 */
+			bcm_object_trace_opr(skb, BCM_OBJDBG_REMOVE,
+				__FUNCTION__, __LINE__);
+#if defined(WL_MONITOR) && defined(BCMSDIO)
+			if (dhd_monitor_enabled(dhdp, ifidx))
+				dhd_rx_mon_pkt_sdio(dhdp, skb, ifidx);
+			else
+#endif /* WL_MONITOR && BCMSDIO */
+			dhd_netif_rx_ni(skb);
+		}
+	}
+
+	if (dhdp->info->rxthread_enabled && skbhead)
+		dhd_sched_rxf(dhdp, skbhead);
+
+	return BCME_OK;
+}
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+void dhd_start_xmit_wq_adapter(struct work_struct *ptr)
+{
+	struct dhd_rx_tx_work *work;
+	netdev_tx_t ret;
+	dhd_info_t *dhd;
+	struct dhd_bus * bus;
+
+	work = container_of(ptr, struct dhd_rx_tx_work, work);
+
+	dhd = DHD_DEV_INFO(work->net);
+
+	bus = dhd->pub.bus;
+
+	if (atomic_read(&dhd->pub.block_bus)) {
+		kfree_skb(work->skb);
+		kfree(work);
+		dhd_netif_start_queue(bus);
+		return;
+	}
+
+	if (pm_runtime_get_sync(dhd_bus_to_dev(bus)) >= 0) {
+		ret = dhd_start_xmit(work->skb, work->net);
+		pm_runtime_mark_last_busy(dhd_bus_to_dev(bus));
+		pm_runtime_put_autosuspend(dhd_bus_to_dev(bus));
+	}
+	kfree(work);
+	dhd_netif_start_queue(bus);
+
+	if (ret)
+		netdev_err(work->net,
+			   "error: dhd_start_xmit():%d\n", ret);
+}
+
+netdev_tx_t
+BCMFASTPATH(dhd_start_xmit_wrapper)(struct sk_buff *skb, struct net_device *net)
+{
+	struct dhd_rx_tx_work *start_xmit_work;
+	netdev_tx_t ret;
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+
+	if (dhd->pub.busstate == DHD_BUS_SUSPEND) {
+		DHD_RPM(("%s: wakeup the bus using workqueue.\n", __FUNCTION__));
+
+		dhd_netif_stop_queue(dhd->pub.bus);
+
+		start_xmit_work = (struct dhd_rx_tx_work*)
+			kmalloc(sizeof(*start_xmit_work), GFP_ATOMIC);
+
+		if (!start_xmit_work) {
+			netdev_err(net,
+				   "error: failed to alloc start_xmit_work\n");
+			ret = -ENOMEM;
+			goto exit;
+		}
+
+		INIT_WORK(&start_xmit_work->work, dhd_start_xmit_wq_adapter);
+		start_xmit_work->skb = skb;
+		start_xmit_work->net = net;
+		queue_work(dhd->tx_wq, &start_xmit_work->work);
+		ret = NET_XMIT_SUCCESS;
+
+	} else if (dhd->pub.busstate == DHD_BUS_DATA) {
+		ret = dhd_start_xmit(skb, net);
+	} else {
+		/* when bus is down */
+		ret = -ENODEV;
+	}
+
+exit:
+	return ret;
+}
+void
+dhd_bus_wakeup_work(dhd_pub_t *dhdp)
+{
+	struct dhd_rx_tx_work *rx_work;
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+
+	rx_work = kmalloc(sizeof(*rx_work), GFP_ATOMIC);
+	if (!rx_work) {
+		DHD_ERROR(("%s: start_rx_work alloc error. \n", __FUNCTION__));
+		return;
+	}
+
+	INIT_WORK(&rx_work->work, dhd_rx_wq_wakeup);
+	rx_work->pub = dhdp;
+	queue_work(dhd->rx_wq, &rx_work->work);
+
+}
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+#if (defined(BCM_ROUTER_DHD) && defined(HNDCTF))
+
+/* Dump CTF stats */
+void
+dhd_ctf_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+{
+	dhd_info_t *dhd = dhdp->info;
+
+	bcm_bprintf(strbuf, "CTF stats:\n");
+	ctf_dump(dhd->cih, strbuf);
+}
+
+bool
+BCMFASTPATH(dhd_rx_pkt_chainable)(dhd_pub_t *dhdp, int ifidx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp = dhd->iflist[ifidx];
+
+	return ifp->rx_pkt_chainable;
+}
+
+/* Returns FALSE if block ping is enabled */
+bool
+BCMFASTPATH(dhd_l2_filter_chainable)(dhd_pub_t *dhdp, uint8 *eh, int ifidx)
+{
+#ifdef DHD_L2_FILTER
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp = dhd->iflist[ifidx];
+	ASSERT(ifp != NULL);
+	return ifp->block_ping ? FALSE : TRUE;
+#else
+	return TRUE;
+#endif /* DHD_L2_FILTER */
+}
+/* Returns FALSE if WET is enabled */
+bool
+BCMFASTPATH(dhd_wet_chainable)(dhd_pub_t *dhdp)
+{
+#ifdef DHD_WET
+	return (!WET_ENABLED(dhdp));
+#else
+	return TRUE;
+#endif
+}
+
+/* Returns TRUE if hot bridge entry for this da is present */
+bool
+BCMFASTPATH(dhd_ctf_hotbrc_check)(dhd_pub_t *dhdp, uint8 *eh, int ifidx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp = dhd->iflist[ifidx];
+
+	ASSERT(ifp != NULL);
+
+	if (!dhd->brc_hot)
+		return FALSE;
+
+	return CTF_HOTBRC_CMP(dhd->brc_hot, (eh), (void *)(ifp->net));
+}
+
+/*
+ * Try to forward the complete packet chain through CTF.
+ * If unsuccessful,
+ *   - link the chain by skb->next
+ *   - change the pnext to the 2nd packet of the chain
+ *   - the chained packets will be sent up to the n/w stack
+ */
+static inline int32
+BCMFASTPATH(dhd_ctf_forward)(dhd_info_t *dhd, struct sk_buff *skb, void **pnext)
+{
+	dhd_pub_t *dhdp = &dhd->pub;
+	void *p, *n;
+	void *old_pnext;
+
+	/* try cut thru first */
+	if (!CTF_ENAB(dhd->cih) || (ctf_forward(dhd->cih, skb, skb->dev) == BCME_ERROR)) {
+		/* Fall back to slow path if ctf is disabled or if ctf_forward fails */
+
+		/* clear skipct flag before sending up */
+		PKTCLRSKIPCT(dhdp->osh, skb);
+
+#ifdef CTFPOOL
+		/* allocate and add a new skb to the pkt pool */
+		if (PKTISFAST(dhdp->osh, skb))
+			osl_ctfpool_add(dhdp->osh);
+
+		/* clear fast buf flag before sending up */
+		PKTCLRFAST(dhdp->osh, skb);
+
+		/* re-init the hijacked field */
+		CTFPOOLPTR(dhdp->osh, skb) = NULL;
+#endif /* CTFPOOL */
+
+		/* link the chained packets by skb->next */
+		if (PKTISCHAINED(skb)) {
+			old_pnext = *pnext;
+			PKTFRMNATIVE(dhdp->osh, skb);
+			p = (void *)skb;
+			FOREACH_CHAINED_PKT(p, n) {
+				PKTCLRCHAINED(dhdp->osh, p);
+				PKTCCLRFLAGS(p);
+				if (p == (void *)skb)
+					PKTTONATIVE(dhdp->osh, p);
+				if (n)
+					PKTSETNEXT(dhdp->osh, p, n);
+				else
+					PKTSETNEXT(dhdp->osh, p, old_pnext);
+			}
+			*pnext = PKTNEXT(dhdp->osh, skb);
+			PKTSETNEXT(dhdp->osh, skb, NULL);
+		}
+		return (BCME_ERROR);
+	}
+
+	return (BCME_OK);
+}
+#endif /* BCM_ROUTER_DHD && HNDCTF */
+
+#ifdef DHD_MCAST_REGEN
+/*
+ * Description: This function is called to do the reverse translation
+ *
+ * Input    eh - pointer to the ethernet header
+ */
+int32
+dhd_mcast_reverse_translation(struct ether_header *eh)
+{
+	uint8 *iph;
+	uint32 dest_ip;
+
+	iph = (uint8 *)eh + ETHER_HDR_LEN;
+	dest_ip = ntoh32(*((uint32 *)(iph + IPV4_DEST_IP_OFFSET)));
+
+	/* Only IP packets are handled */
+	if (eh->ether_type != hton16(ETHER_TYPE_IP))
+		return BCME_ERROR;
+
+	/* Non-IPv4 multicast packets are not handled */
+	if (IP_VER(iph) != IP_VER_4)
+		return BCME_ERROR;
+
+	/*
+	 * The packet has a multicast IP and unicast MAC. That means
+	 * we have to do the reverse translation
+	 */
+	if (IPV4_ISMULTI(dest_ip) && !ETHER_ISMULTI(&eh->ether_dhost)) {
+		ETHER_FILL_MCAST_ADDR_FROM_IP(eh->ether_dhost, dest_ip);
+		return BCME_OK;
+	}
+
+	return BCME_ERROR;
+}
+#endif /* MCAST_REGEN */
+
+void
+dhd_dpc_tasklet_dispatcher_work(struct work_struct * work)
+{
+	struct delayed_work *dw = to_delayed_work(work);
+	struct dhd_info *dhd;
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd = container_of(dw, struct dhd_info, dhd_dpc_dispatcher_work);
+	GCC_DIAGNOSTIC_POP();
+
+	DHD_INFO(("%s:\n", __FUNCTION__));
+
+	tasklet_schedule(&dhd->tasklet);
+}
+
+void
+dhd_schedule_delayed_dpc_on_dpc_cpu(dhd_pub_t *dhdp, ulong delay)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+	int dpc_cpu = atomic_read(&dhd->dpc_cpu);
+	DHD_INFO(("%s:\n", __FUNCTION__));
+
+	/* scheduler will take care of scheduling to appropriate cpu if dpc_cpu is not online */
+	schedule_delayed_work_on(dpc_cpu, &dhd->dhd_dpc_dispatcher_work, delay);
+
+	return;
+}
+
+#ifdef SHOW_LOGTRACE
+static int
+dhd_event_logtrace_pkt_process(dhd_pub_t *dhdp, struct sk_buff * skb)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+	int ret = BCME_OK;
+	uint datalen;
+	bcm_event_msg_u_t evu;
+	void *data = NULL;
+	void *pktdata = NULL;
+	bcm_event_t *pvt_data;
+	uint pktlen;
+
+	DHD_TRACE(("%s:Enter\n", __FUNCTION__));
+
+	/* In dhd_rx_frame, header is stripped using skb_pull
+	 * of size ETH_HLEN, so adjust pktlen accordingly
+	 */
+	pktlen = skb->len + ETH_HLEN;
+
+	pktdata = (void *)skb_mac_header(skb);
+	ret = wl_host_event_get_data(pktdata, pktlen, &evu);
+
+	if (ret != BCME_OK) {
+		DHD_ERROR(("%s: wl_host_event_get_data err = %d\n",
+			__FUNCTION__, ret));
+		goto exit;
+	}
+
+	datalen = ntoh32(evu.event.datalen);
+
+	pvt_data = (bcm_event_t *)pktdata;
+	data = &pvt_data[1];
+
+	dhd_dbg_trace_evnt_handler(dhdp, data, &dhd->event_data, datalen);
+
+exit:
+	return ret;
+}
+
+/*
+ * dhd_event_logtrace_process_items processes
+ * each skb from evt_trace_queue.
+ * Returns TRUE if more packets to be processed
+ * else returns FALSE
+ */
+
+static int
+dhd_event_logtrace_process_items(dhd_info_t *dhd)
+{
+	dhd_pub_t *dhdp;
+	struct sk_buff *skb;
+	uint32 qlen;
+	uint32 process_len;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd info not available \n", __FUNCTION__));
+		return 0;
+	}
+
+	dhdp = &dhd->pub;
+
+	if (!dhdp) {
+		DHD_ERROR(("%s: dhd pub is null \n", __FUNCTION__));
+		return 0;
+	}
+
+	qlen = skb_queue_len(&dhd->evt_trace_queue);
+	process_len = MIN(qlen, DHD_EVENT_LOGTRACE_BOUND);
+
+	/* Run while loop till bound is reached or skb queue is empty */
+	while (process_len--) {
+		int ifid = 0;
+		skb = skb_dequeue(&dhd->evt_trace_queue);
+		if (skb == NULL) {
+			DHD_ERROR(("%s: skb is NULL, which is not valid case\n",
+				__FUNCTION__));
+			break;
+		}
+		BCM_REFERENCE(ifid);
+#ifdef PCIE_FULL_DONGLE
+		/* Check if pkt is from INFO ring or WLC_E_TRACE */
+		ifid = DHD_PKTTAG_IFID((dhd_pkttag_fr_t *)PKTTAG(skb));
+		if (ifid == DHD_DUMMY_INFO_IF) {
+			/* Process logtrace from info rings */
+			dhd_event_logtrace_infobuf_pkt_process(dhdp, skb, &dhd->event_data);
+		} else
+#endif /* PCIE_FULL_DONGLE */
+		{
+			/* Processing WLC_E_TRACE case OR non PCIE PCIE_FULL_DONGLE case */
+			dhd_event_logtrace_pkt_process(dhdp, skb);
+		}
+
+		/* Dummy sleep so that scheduler kicks in after processing any logprints */
+		OSL_SLEEP(0);
+
+		/* Send packet up if logtrace_pkt_sendup is TRUE */
+		if (dhdp->logtrace_pkt_sendup) {
+#ifdef DHD_USE_STATIC_CTRLBUF
+			/* If bufs are allocated via static buf pool
+			 * and logtrace_pkt_sendup enabled, make a copy,
+			 * free the local one and send the copy up.
+			 */
+			void *npkt = PKTDUP(dhdp->osh, skb);
+			/* Clone event and send it up */
+			PKTFREE_STATIC(dhdp->osh, skb, FALSE);
+			if (npkt) {
+				skb = npkt;
+			} else {
+				DHD_ERROR(("skb clone failed. dropping logtrace pkt.\n"));
+				/* Packet is already freed, go to next packet */
+				continue;
+			}
+#endif /* DHD_USE_STATIC_CTRLBUF */
+#ifdef PCIE_FULL_DONGLE
+			/* For infobuf packets as if is DHD_DUMMY_INFO_IF,
+			 * to send skb to network layer, assign skb->dev with
+			 * Primary interface n/w device
+			 */
+			if (ifid == DHD_DUMMY_INFO_IF) {
+				skb = PKTTONATIVE(dhdp->osh, skb);
+				skb->dev = dhd->iflist[0]->net;
+			}
+#endif /* PCIE_FULL_DONGLE */
+			/* Send pkt UP */
+			dhd_netif_rx_ni(skb);
+		} else	{
+			/* Don't send up. Free up the packet. */
+			PKTFREE_CTRLBUF(dhdp->osh, skb, FALSE);
+		}
+	}
+
+	/* Reschedule if more packets to be processed */
+	return (qlen >= DHD_EVENT_LOGTRACE_BOUND);
+}
+
+#ifdef DHD_USE_KTHREAD_FOR_LOGTRACE
+static int
+dhd_logtrace_thread(void *data)
+{
+	tsk_ctl_t *tsk = (tsk_ctl_t *)data;
+	dhd_info_t *dhd = (dhd_info_t *)tsk->parent;
+	dhd_pub_t *dhdp = (dhd_pub_t *)&dhd->pub;
+	int ret;
+
+	while (1) {
+		dhdp->logtrace_thr_ts.entry_time = OSL_LOCALTIME_NS();
+		if (!binary_sema_down(tsk)) {
+			dhdp->logtrace_thr_ts.sem_down_time = OSL_LOCALTIME_NS();
+			SMP_RD_BARRIER_DEPENDS();
+
+			/* Check terminated before processing the items */
+			if (tsk->terminated) {
+				DHD_ERROR(("%s: task terminated\n", __FUNCTION__));
+				goto exit;
+			}
+
+			if (dhd->pub.dongle_reset == FALSE) {
+				do {
+#ifdef EWP_EDL
+					/* check if EDL is being used */
+					if (dhd->pub.dongle_edl_support) {
+						ret = dhd_prot_process_edl_complete(&dhd->pub,
+								&dhd->event_data);
+					} else {
+						ret = dhd_event_logtrace_process_items(dhd);
+					}
+#else
+					ret = dhd_event_logtrace_process_items(dhd);
+#endif /* EWP_EDL */
+					/* if ret > 0, bound has reached so to be fair to other
+					 * processes need to yield the scheduler.
+					 * The comment above yield()'s definition says:
+					 * If you want to use yield() to wait for something,
+					 * use wait_event().
+					 * If you want to use yield() to be 'nice' for others,
+					 * use cond_resched().
+					 * If you still want to use yield(), do not!
+					 */
+					if (ret > 0) {
+						cond_resched();
+						OSL_SLEEP(DHD_EVENT_LOGTRACE_RESCHEDULE_DELAY_MS);
+					} else if (ret < 0) {
+						DHD_ERROR(("%s: ERROR should not reach here\n",
+							__FUNCTION__));
+					}
+				} while (ret > 0);
+			}
+			/* Check terminated in case of dongle_reset */
+			if (tsk->terminated) {
+				DHD_ERROR(("%s: task terminated\n", __FUNCTION__));
+				goto exit;
+			}
+			if (tsk->flush_ind) {
+				DHD_ERROR(("%s: flushed\n", __FUNCTION__));
+				dhdp->logtrace_thr_ts.flush_time = OSL_LOCALTIME_NS();
+				tsk->flush_ind = 0;
+				complete(&tsk->flushed);
+			}
+		} else {
+			DHD_ERROR(("%s: unexpted break\n", __FUNCTION__));
+			dhdp->logtrace_thr_ts.unexpected_break_time = OSL_LOCALTIME_NS();
+			break;
+		}
+	}
+exit:
+	complete_and_exit(&tsk->completed, 0);
+	dhdp->logtrace_thr_ts.complete_time = OSL_LOCALTIME_NS();
+}
+#else
+static void
+dhd_event_logtrace_process(struct work_struct * work)
+{
+/* Ignore compiler warnings due to -Werror=cast-qual */
+	struct delayed_work *dw = to_delayed_work(work);
+	struct dhd_info *dhd;
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd = container_of(dw, struct dhd_info, event_log_dispatcher_work);
+	GCC_DIAGNOSTIC_POP();
+
+#ifdef EWP_EDL
+	if (dhd->pub.dongle_edl_support) {
+		ret = dhd_prot_process_edl_complete(&dhd->pub, &dhd->event_data);
+	} else {
+		ret = dhd_event_logtrace_process_items(dhd);
+	}
+#else
+	ret = dhd_event_logtrace_process_items(dhd);
+#endif /* EWP_EDL */
+
+	if (ret > 0) {
+		schedule_delayed_work(&(dhd)->event_log_dispatcher_work,
+			msecs_to_jiffies(DHD_EVENT_LOGTRACE_RESCHEDULE_DELAY_MS));
+	}
+	return;
+}
+#endif /* DHD_USE_KTHREAD_FOR_LOGTRACE */
+
+void
+dhd_schedule_logtrace(void *dhd_info)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dhd_info;
+
+#ifdef DHD_USE_KTHREAD_FOR_LOGTRACE
+	if (dhd->thr_logtrace_ctl.thr_pid >= 0) {
+		binary_sema_up(&dhd->thr_logtrace_ctl);
+	} else {
+		DHD_ERROR(("%s: thr_logtrace_ctl(%ld) not inited\n", __FUNCTION__,
+			dhd->thr_logtrace_ctl.thr_pid));
+	}
+#else
+	schedule_delayed_work(&dhd->event_log_dispatcher_work, 0);
+#endif /* DHD_USE_KTHREAD_FOR_LOGTRACE */
+	return;
+}
+
+void
+dhd_cancel_logtrace_process_sync(dhd_info_t *dhd)
+{
+#ifdef DHD_USE_KTHREAD_FOR_LOGTRACE
+	tsk_ctl_t *tsk = &dhd->thr_logtrace_ctl;
+
+	if (tsk->parent && tsk->thr_pid >= 0) {
+		PROC_STOP_USING_BINARY_SEMA(tsk);
+	} else {
+		DHD_ERROR(("%s: thr_logtrace_ctl(%ld) not inited\n",
+			__FUNCTION__, tsk->thr_pid));
+	}
+#else
+	cancel_delayed_work_sync(&dhd->event_log_dispatcher_work);
+#endif /* DHD_USE_KTHREAD_FOR_LOGTRACE */
+}
+
+void
+dhd_flush_logtrace_process(dhd_info_t *dhd)
+{
+#ifdef DHD_USE_KTHREAD_FOR_LOGTRACE
+	if (dhd->thr_logtrace_ctl.thr_pid >= 0) {
+		PROC_FLUSH_USING_BINARY_SEMA(&dhd->thr_logtrace_ctl);
+	} else {
+		DHD_ERROR(("%s: thr_logtrace_ctl(%ld) not inited\n", __FUNCTION__,
+			dhd->thr_logtrace_ctl.thr_pid));
+	}
+#else
+	flush_delayed_work(&dhd->event_log_dispatcher_work);
+#endif /* DHD_USE_KTHREAD_FOR_LOGTRACE */
+}
+
+int
+dhd_init_logtrace_process(dhd_info_t *dhd)
+{
+#ifdef DHD_USE_KTHREAD_FOR_LOGTRACE
+	dhd->thr_logtrace_ctl.thr_pid = DHD_PID_KT_INVALID;
+	PROC_START(dhd_logtrace_thread, dhd, &dhd->thr_logtrace_ctl, 0, "dhd_logtrace_thread");
+	if (dhd->thr_logtrace_ctl.thr_pid < 0) {
+		DHD_ERROR(("%s: init logtrace process failed\n", __FUNCTION__));
+		return BCME_ERROR;
+	} else {
+		DHD_ERROR(("%s: thr_logtrace_ctl(%ld) not inited\n", __FUNCTION__,
+			dhd->thr_logtrace_ctl.thr_pid));
+	}
+#else
+	INIT_DELAYED_WORK(&dhd->event_log_dispatcher_work, dhd_event_logtrace_process);
+#endif /* DHD_USE_KTHREAD_FOR_LOGTRACE */
+	return BCME_OK;
+}
+
+int
+dhd_reinit_logtrace_process(dhd_info_t *dhd)
+{
+#ifdef DHD_USE_KTHREAD_FOR_LOGTRACE
+	/* Re-init only if PROC_STOP from dhd_stop was called
+	 * which can be checked via thr_pid
+	 */
+	if (dhd->thr_logtrace_ctl.thr_pid < 0) {
+		PROC_START(dhd_logtrace_thread, dhd, &dhd->thr_logtrace_ctl,
+			0, "dhd_logtrace_thread");
+		if (dhd->thr_logtrace_ctl.thr_pid < 0) {
+			DHD_ERROR(("%s: reinit logtrace process failed\n", __FUNCTION__));
+			return BCME_ERROR;
+		} else {
+		DHD_ERROR(("%s: thr_logtrace_ctl(%ld) not inited\n", __FUNCTION__,
+			dhd->thr_logtrace_ctl.thr_pid));
+	}
+	}
+#else
+	/* No need to re-init for WQ as calcel_delayed_work_sync will
+	 * will not delete the WQ
+	 */
+#endif /* DHD_USE_KTHREAD_FOR_LOGTRACE */
+	return BCME_OK;
+}
+
+void
+dhd_event_logtrace_enqueue(dhd_pub_t *dhdp, int ifidx, void *pktbuf)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+	BCM_REFERENCE(dhd);
+
+#ifdef PCIE_FULL_DONGLE
+	/* Add ifidx in the PKTTAG */
+	DHD_PKTTAG_SET_IFID((dhd_pkttag_fr_t *)PKTTAG(pktbuf), ifidx);
+#endif /* PCIE_FULL_DONGLE */
+	skb_queue_tail(&dhd->evt_trace_queue, pktbuf);
+
+	dhd_schedule_logtrace(dhd);
+}
+
+void
+dhd_event_logtrace_flush_queue(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+	struct sk_buff *skb;
+
+	while ((skb = skb_dequeue(&dhd->evt_trace_queue)) != NULL) {
+		PKTFREE_CTRLBUF(dhdp->osh, skb, FALSE);
+	}
+}
+
+#ifdef EWP_EDL
+void
+dhd_sendup_info_buf(dhd_pub_t *dhdp, uint8 *msg)
+{
+	struct sk_buff *skb = NULL;
+	uint32 pktsize = 0;
+	void *pkt = NULL;
+	info_buf_payload_hdr_t *infobuf = NULL;
+	dhd_info_t *dhd = dhdp->info;
+	uint8 *pktdata = NULL;
+
+	if (!msg)
+		return;
+
+	/* msg = |infobuf_ver(u32)|info_buf_payload_hdr_t|msgtrace_hdr_t|<var len data>| */
+	infobuf = (info_buf_payload_hdr_t *)(msg + sizeof(uint32));
+	pktsize = (uint32)(ltoh16(infobuf->length) + sizeof(info_buf_payload_hdr_t) +
+			sizeof(uint32));
+	pkt = PKTGET(dhdp->osh, pktsize, FALSE);
+	if (!pkt) {
+		DHD_ERROR(("%s: skb alloc failed ! not sending event log up.\n", __FUNCTION__));
+	} else {
+		PKTSETLEN(dhdp->osh, pkt, pktsize);
+		pktdata = PKTDATA(dhdp->osh, pkt);
+		memcpy(pktdata, msg, pktsize);
+		/* For infobuf packets assign skb->dev with
+		 * Primary interface n/w device
+		 */
+		skb = PKTTONATIVE(dhdp->osh, pkt);
+		skb->dev = dhd->iflist[0]->net;
+		/* Send pkt UP */
+		dhd_netif_rx_ni(skb);
+	}
+}
+#endif /* EWP_EDL */
+#endif /* SHOW_LOGTRACE */
+
+#ifdef EWP_EDL
+static void
+dhd_edl_process_work(struct work_struct *work)
+{
+	struct delayed_work *dw = to_delayed_work(work);
+	struct dhd_info *dhd_info;
+	/* Ignore compiler warnings due to -Werror=cast-qual */
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd_info = container_of(dw, struct dhd_info, edl_dispatcher_work);
+	GCC_DIAGNOSTIC_POP();
+
+	if (dhd_info)
+		dhd_prot_process_edl_complete(&dhd_info->pub, &dhd_info->event_data);
+}
+
+void
+dhd_schedule_edl_work(dhd_pub_t *dhdp, uint delay_ms)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+	schedule_delayed_work(&dhd->edl_dispatcher_work, msecs_to_jiffies(delay_ms));
+}
+#endif /* EWP_EDL */
+
+#ifdef ENABLE_WAKEUP_PKT_DUMP
+static void
+update_wake_pkt_info(struct sk_buff *skb)
+{
+	struct iphdr *ip_header;
+	struct ipv6hdr *ipv6_header;
+	struct udphdr *udp_header;
+	struct tcphdr *tcp_header;
+	uint16 dport = 0;
+
+	ip_header = (struct iphdr *)(skb->data);
+
+	temp_raw |= ((long long)ntoh16(skb->protocol)) << 48;
+
+	DHD_INFO(("eth_hdr(skb)->h_dest : %pM\n", eth_hdr(skb)->h_dest));
+	if (eth_hdr(skb)->h_dest[0] & 0x01) {
+		temp_raw |= (long long)1 << 39;
+	}
+
+	if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) {
+		wl_event_msg_t event;
+		bcm_event_msg_u_t evu;
+		int ret;
+		uint event_type;
+
+		ret = wl_host_event_get_data(
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+			skb_mac_header(skb),
+#else
+			skb->mac.raw,
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22) */
+			skb->len, &evu);
+		if (ret != BCME_OK) {
+			DHD_ERROR(("%s: wl_host_event_get_data err = %d\n",
+				__FUNCTION__, ret));
+		}
+
+		memcpy(&event, &evu.event, sizeof(wl_event_msg_t));
+		event_type = ntoh32_ua((void *)&event.event_type);
+
+		temp_raw |= (long long)event_type << 40;
+	} else if (ntoh16(skb->protocol) == ETHER_TYPE_IP ||
+			ntoh16(skb->protocol) == ETHER_TYPE_IPV6) {
+		if (ip_header->version == 6) {
+			ipv6_header = (struct ipv6hdr *)ip_header;
+			temp_raw |= ((long long)ipv6_header->nexthdr) << 40;
+			dport = 0;
+
+			if (ipv6_header->daddr.s6_addr[0] & 0xff) {
+				temp_raw |= (long long)1 << 38;
+			}
+
+			DHD_INFO(("IPv6 [%x]%pI6c > %pI6c:%d\n",
+				ip_header->protocol, &(ipv6_header->saddr.s6_addr),
+				&(ipv6_header->daddr.s6_addr), dport));
+		} else if (ip_header->version == 4) {
+			temp_raw |= ((long long)ip_header->protocol) << 40;
+
+#define IP_HDR_OFFSET	((char *)ip_header + IPV4_HLEN(ip_header))
+			if (ip_header->protocol == IPPROTO_TCP) {
+				tcp_header = (struct tcphdr *)IP_HDR_OFFSET;
+				dport = ntohs(tcp_header->dest);
+			}
+			else if (ip_header->protocol == IPPROTO_UDP) {
+				udp_header = (struct udphdr *)IP_HDR_OFFSET;
+				dport = ntohs(udp_header->dest);
+			}
+
+			if (ipv4_is_multicast(ip_header->daddr)) {
+				temp_raw |= (long long)1 << 38;
+			}
+
+			DHD_INFO(("IP [%x] %pI4 > %pI4:%d\n",
+				ip_header->protocol, &(ip_header->saddr),
+				&(ip_header->daddr), dport));
+		}
+
+		temp_raw |= (long long)dport << 16;
+	}
+}
+#endif /* ENABLE_WAKEUP_PKT_DUMP */
+
+#if defined(BCMPCIE)
+int
+dhd_check_shinfo_nrfrags(dhd_pub_t *dhdp, void *pktbuf,
+	dmaaddr_t *pa, uint32 pktid)
+{
+	struct sk_buff *skb;
+	struct skb_shared_info *shinfo;
+
+	if (!pktbuf)
+		return BCME_ERROR;
+
+	skb = PKTTONATIVE(dhdp->osh, pktbuf);
+	shinfo = skb_shinfo(skb);
+
+	if (shinfo->nr_frags) {
+#ifdef BCMDMA64OSL
+		DHD_ERROR(("!!Invalid nr_frags: %u pa.loaddr: 0x%llx pa.hiaddr: 0x%llx "
+			"skb: 0x%llx skb_data: 0x%llx skb_head: 0x%llx skb_tail: 0x%llx "
+			"skb_end: 0x%llx skb_len: %u shinfo: 0x%llx pktid: %u\n",
+			shinfo->nr_frags, (uint64)(pa->loaddr), (uint64)(pa->hiaddr),
+			(uint64)skb, (uint64)(skb->data), (uint64)(skb->head), (uint64)(skb->tail),
+			(uint64)(skb->end), skb->len, (uint64)shinfo, pktid));
+#else
+		DHD_ERROR(("!!Invalid nr_frags: %u "
+			"skb: 0x%x skb_data: 0x%x skb_head: 0x%x skb_tail: 0x%x "
+			"skb_end: 0x%x skb_len: %u shinfo: 0x%x pktid: %u\n",
+			shinfo->nr_frags,
+			(uint)skb, (uint)(skb->data), (uint)(skb->head), (uint)(skb->tail),
+			(uint)(skb->end), skb->len, (uint)shinfo, pktid));
+#endif /* BCMDMA64OSL */
+		prhex("shinfo", (char*)shinfo, sizeof(struct skb_shared_info));
+		if (!dhd_query_bus_erros(dhdp)) {
+#ifdef DHD_FW_COREDUMP
+			/* Collect socram dump */
+			if (dhdp->memdump_enabled) {
+				/* collect core dump */
+				dhdp->memdump_type = DUMP_TYPE_INVALID_SHINFO_NRFRAGS;
+				dhd_bus_mem_dump(dhdp);
+			} else
+#endif /* DHD_FW_COREDUMP */
+			{
+				shinfo->nr_frags = 0;
+				/* In production case, free the packet and continue
+				 * if nfrags is corrupted. Whereas in non-production
+				 * case collect memdump and call BUG_ON().
+				 */
+				PKTCFREE(dhdp->osh, pktbuf, FALSE);
+			}
+		}
+		return BCME_ERROR;
+	}
+	return BCME_OK;
+}
+#endif /* BCMPCIE */
+
+void
+dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx)
+{
+	/* Linux version has nothing to do */
+	return;
+}
+
+int dhd_os_tput_test_wait(dhd_pub_t *pub, uint *condition,
+		uint timeout_ms)
+{
+	int timeout;
+
+	/* Convert timeout in millsecond to jiffies */
+	timeout = msecs_to_jiffies(timeout_ms);
+	pub->tput_test_done = FALSE;
+	condition = (uint *)&pub->tput_test_done;
+	timeout = wait_event_timeout(pub->tx_tput_test_wait,
+		(*condition), timeout);
+
+	return timeout;
+}
+
+int dhd_os_tput_test_wake(dhd_pub_t * pub)
+{
+	OSL_SMP_WMB();
+	pub->tput_test_done = TRUE;
+	OSL_SMP_WMB();
+	wake_up(&(pub->tx_tput_test_wait));
+	return 0;
+}
+
+static struct net_device_stats *
+dhd_get_stats(struct net_device *net)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+	dhd_pub_t *dhdp;
+	dhd_if_t *ifp;
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+	if (!dhd) {
+		DHD_ERROR(("%s : dhd is NULL\n", __FUNCTION__));
+		goto error;
+	}
+
+	dhdp = &dhd->pub;
+	if (!dhdp) {
+		DHD_ERROR(("%s : dhdp is NULL\n", __FUNCTION__));
+		goto error;
+	}
+
+	if (OSL_ATOMIC_READ(dhdp->osh, &reboot_in_progress) > -1) {
+		DHD_ERROR(("%s : reboot_in_progress\n", __FUNCTION__));
+		goto error;
+	}
+
+	ifp = dhd_get_ifp_by_ndev(&dhd->pub, net);
+	if (!ifp) {
+		/* return empty stats */
+		DHD_ERROR(("%s: BAD_IF\n", __FUNCTION__));
+		goto error;
+	}
+
+	if (dhd->pub.up) {
+		/* Use the protocol to get dongle stats */
+		dhd_prot_dstats(&dhd->pub);
+	}
+	return &ifp->stats;
+
+error:
+	memset(&net->stats, 0, sizeof(net->stats));
+	return &net->stats;
+}
+
+#ifndef BCMDBUS
+static int
+dhd_watchdog_thread(void *data)
+{
+	tsk_ctl_t *tsk = (tsk_ctl_t *)data;
+	dhd_info_t *dhd = (dhd_info_t *)tsk->parent;
+	/* This thread doesn't need any user-level access,
+	 * so get rid of all our resources
+	 */
+	if (dhd_watchdog_prio > 0) {
+		struct sched_param param;
+		param.sched_priority = (dhd_watchdog_prio < MAX_RT_PRIO)?
+			dhd_watchdog_prio:(MAX_RT_PRIO-1);
+		setScheduler(current, SCHED_FIFO, &param);
+	}
+
+	while (1) {
+		if (down_interruptible (&tsk->sema) == 0) {
+			unsigned long flags;
+			unsigned long jiffies_at_start = jiffies;
+			unsigned long time_lapse;
+#ifdef BCMPCIE
+			DHD_OS_WD_WAKE_LOCK(&dhd->pub);
+#endif /* BCMPCIE */
+
+			SMP_RD_BARRIER_DEPENDS();
+			if (tsk->terminated) {
+#ifdef BCMPCIE
+				DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
+#endif /* BCMPCIE */
+				break;
+			}
+
+			if (dhd->pub.dongle_reset == FALSE) {
+				DHD_TIMER(("%s:\n", __FUNCTION__));
+				dhd_analyze_sock_flows(dhd, dhd_watchdog_ms);
+				dhd_bus_watchdog(&dhd->pub);
+
+#if defined(BCM_ROUTER_DHD) && defined(CTFPOOL)
+				/* allocate and add a new skb to the pkt pool */
+				if (CTF_ENAB(dhd->cih))
+					osl_ctfpool_replenish(dhd->pub.osh, CTFPOOL_REFILL_THRESH);
+#endif /* BCM_ROUTER_DHD && CTFPOOL */
+
+				DHD_GENERAL_LOCK(&dhd->pub, flags);
+				/* Count the tick for reference */
+				dhd->pub.tickcnt++;
+#ifdef DHD_L2_FILTER
+				dhd_l2_filter_watchdog(&dhd->pub);
+#endif /* DHD_L2_FILTER */
+				time_lapse = jiffies - jiffies_at_start;
+
+				/* Reschedule the watchdog */
+				if (dhd->wd_timer_valid) {
+					mod_timer(&dhd->timer,
+					    jiffies +
+					    msecs_to_jiffies(dhd_watchdog_ms) -
+					    min(msecs_to_jiffies(dhd_watchdog_ms), time_lapse));
+				}
+				DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+			}
+#ifdef BCMPCIE
+			DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
+#endif /* BCMPCIE */
+		} else {
+			break;
+		}
+	}
+
+	complete_and_exit(&tsk->completed, 0);
+}
+
+static void dhd_watchdog(ulong data)
+{
+	dhd_info_t *dhd = (dhd_info_t *)data;
+	unsigned long flags;
+
+	if (dhd->pub.dongle_reset) {
+		return;
+	}
+
+	if (dhd->thr_wdt_ctl.thr_pid >= 0) {
+		up(&dhd->thr_wdt_ctl.sema);
+		return;
+	}
+
+#ifdef BCMPCIE
+	DHD_OS_WD_WAKE_LOCK(&dhd->pub);
+#endif /* BCMPCIE */
+	/* Call the bus module watchdog */
+	dhd_bus_watchdog(&dhd->pub);
+
+	DHD_GENERAL_LOCK(&dhd->pub, flags);
+	/* Count the tick for reference */
+	dhd->pub.tickcnt++;
+
+#ifdef DHD_L2_FILTER
+	dhd_l2_filter_watchdog(&dhd->pub);
+#endif /* DHD_L2_FILTER */
+	/* Reschedule the watchdog */
+	if (dhd->wd_timer_valid)
+		mod_timer(&dhd->timer, jiffies + msecs_to_jiffies(dhd_watchdog_ms));
+	DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+#ifdef BCMPCIE
+	DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
+#endif /* BCMPCIE */
+#if defined(BCM_ROUTER_DHD) && defined(CTFPOOL)
+	    /* allocate and add a new skb to the pkt pool */
+	    if (CTF_ENAB(dhd->cih))
+			osl_ctfpool_replenish(dhd->pub.osh, CTFPOOL_REFILL_THRESH);
+#endif /* BCM_ROUTER_DHD && CTFPOOL */
+}
+
+#ifdef ENABLE_ADAPTIVE_SCHED
+static void
+dhd_sched_policy(int prio)
+{
+	struct sched_param param;
+	if (cpufreq_quick_get(0) <= CUSTOM_CPUFREQ_THRESH) {
+		param.sched_priority = 0;
+		setScheduler(current, SCHED_NORMAL, &param);
+	} else {
+		if (get_scheduler_policy(current) != SCHED_FIFO) {
+			param.sched_priority = (prio < MAX_RT_PRIO)? prio : (MAX_RT_PRIO-1);
+			setScheduler(current, SCHED_FIFO, &param);
+		}
+	}
+}
+#endif /* ENABLE_ADAPTIVE_SCHED */
+#ifdef DEBUG_CPU_FREQ
+static int dhd_cpufreq_notifier(struct notifier_block *nb, unsigned long val, void *data)
+{
+	dhd_info_t *dhd = container_of(nb, struct dhd_info, freq_trans);
+	struct cpufreq_freqs *freq = data;
+	if (dhd) {
+		if (!dhd->new_freq)
+			goto exit;
+		if (val == CPUFREQ_POSTCHANGE) {
+			DHD_ERROR(("cpu freq is changed to %u kHZ on CPU %d\n",
+				freq->new, freq->cpu));
+			*per_cpu_ptr(dhd->new_freq, freq->cpu) = freq->new;
+		}
+	}
+exit:
+	return 0;
+}
+#endif /* DEBUG_CPU_FREQ */
+
+static int
+dhd_dpc_thread(void *data)
+{
+	tsk_ctl_t *tsk = (tsk_ctl_t *)data;
+	dhd_info_t *dhd = (dhd_info_t *)tsk->parent;
+
+	/* This thread doesn't need any user-level access,
+	 * so get rid of all our resources
+	 */
+	if (dhd_dpc_prio > 0)
+	{
+		struct sched_param param;
+		param.sched_priority = (dhd_dpc_prio < MAX_RT_PRIO)?dhd_dpc_prio:(MAX_RT_PRIO-1);
+		setScheduler(current, SCHED_FIFO, &param);
+	}
+
+#ifdef CUSTOM_DPC_CPUCORE
+	set_cpus_allowed_ptr(current, cpumask_of(CUSTOM_DPC_CPUCORE));
+#endif
+#ifdef CUSTOM_SET_CPUCORE
+	dhd->pub.current_dpc = current;
+#endif /* CUSTOM_SET_CPUCORE */
+	/* Run until signal received */
+	while (1) {
+		if (dhd->pub.conf->dpc_cpucore >= 0) {
+			printf("%s: set dpc_cpucore %d\n", __FUNCTION__, dhd->pub.conf->dpc_cpucore);
+			set_cpus_allowed_ptr(current, cpumask_of(dhd->pub.conf->dpc_cpucore));
+			dhd->pub.conf->dpc_cpucore = -1;
+		}
+		if (dhd->pub.conf->dhd_dpc_prio >= 0) {
+			struct sched_param param;
+			printf("%s: set dhd_dpc_prio %d\n", __FUNCTION__, dhd->pub.conf->dhd_dpc_prio);
+			param.sched_priority = (dhd->pub.conf->dhd_dpc_prio < MAX_RT_PRIO)?
+				dhd->pub.conf->dhd_dpc_prio:(MAX_RT_PRIO-1);
+			setScheduler(current, SCHED_FIFO, &param);
+			dhd->pub.conf->dhd_dpc_prio = -1;
+		}
+		if (!binary_sema_down(tsk)) {
+#ifdef ENABLE_ADAPTIVE_SCHED
+			dhd_sched_policy(dhd_dpc_prio);
+#endif /* ENABLE_ADAPTIVE_SCHED */
+			SMP_RD_BARRIER_DEPENDS();
+			if (tsk->terminated) {
+				DHD_OS_WAKE_UNLOCK(&dhd->pub);
+				break;
+			}
+
+			/* Call bus dpc unless it indicated down (then clean stop) */
+			if (dhd->pub.busstate != DHD_BUS_DOWN) {
+#ifdef DEBUG_DPC_THREAD_WATCHDOG
+				int resched_cnt = 0;
+#endif /* DEBUG_DPC_THREAD_WATCHDOG */
+				dhd_os_wd_timer_extend(&dhd->pub, TRUE);
+				while (dhd_bus_dpc(dhd->pub.bus)) {
+					/* process all data */
+#ifdef DEBUG_DPC_THREAD_WATCHDOG
+					resched_cnt++;
+					if (resched_cnt > MAX_RESCHED_CNT) {
+						DHD_INFO(("%s Calling msleep to"
+							"let other processes run. \n",
+							__FUNCTION__));
+						dhd->pub.dhd_bug_on = true;
+						resched_cnt = 0;
+						OSL_SLEEP(1);
+					}
+#endif /* DEBUG_DPC_THREAD_WATCHDOG */
+				}
+				dhd_os_wd_timer_extend(&dhd->pub, FALSE);
+				DHD_OS_WAKE_UNLOCK(&dhd->pub);
+			} else {
+				if (dhd->pub.up)
+					dhd_bus_stop(dhd->pub.bus, TRUE);
+				DHD_OS_WAKE_UNLOCK(&dhd->pub);
+			}
+		} else {
+			break;
+		}
+	}
+	complete_and_exit(&tsk->completed, 0);
+}
+
+#ifdef BCMPCIE
+void dhd_dpc_enable(dhd_pub_t *dhdp)
+{
+#if defined(DHD_LB_RXP) || defined(DHD_LB_TXP)
+	dhd_info_t *dhd;
+
+	if (!dhdp || !dhdp->info)
+		return;
+	dhd = dhdp->info;
+#endif /* DHD_LB_RXP || DHD_LB_TXP */
+
+#ifdef DHD_LB_RXP
+	__skb_queue_head_init(&dhd->rx_pend_queue);
+	skb_queue_head_init(&dhd->rx_emerge_queue);
+#endif /* DHD_LB_RXP */
+
+#ifdef DHD_LB_TXP
+	skb_queue_head_init(&dhd->tx_pend_queue);
+#endif /* DHD_LB_TXP */
+}
+#endif /* BCMPCIE */
+
+#ifdef BCMPCIE
+void
+dhd_dpc_kill(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd;
+
+	if (!dhdp) {
+		return;
+	}
+
+	dhd = dhdp->info;
+
+	if (!dhd) {
+		return;
+	}
+
+	if (dhd->thr_dpc_ctl.thr_pid < 0) {
+		tasklet_kill(&dhd->tasklet);
+		DHD_ERROR(("%s: tasklet disabled\n", __FUNCTION__));
+	}
+
+	cancel_delayed_work_sync(&dhd->dhd_dpc_dispatcher_work);
+#ifdef DHD_LB
+#ifdef DHD_LB_RXP
+	cancel_work_sync(&dhd->rx_napi_dispatcher_work);
+	__skb_queue_purge(&dhd->rx_pend_queue);
+	skb_queue_purge(&dhd->rx_emerge_queue);
+#endif /* DHD_LB_RXP */
+#ifdef DHD_LB_TXP
+	cancel_work_sync(&dhd->tx_dispatcher_work);
+	skb_queue_purge(&dhd->tx_pend_queue);
+	tasklet_kill(&dhd->tx_tasklet);
+#endif /* DHD_LB_TXP */
+#endif /* DHD_LB */
+}
+
+void
+dhd_dpc_tasklet_kill(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd;
+
+	if (!dhdp) {
+		return;
+	}
+
+	dhd = dhdp->info;
+
+	if (!dhd) {
+		return;
+	}
+
+	if (dhd->thr_dpc_ctl.thr_pid < 0) {
+		tasklet_kill(&dhd->tasklet);
+	}
+}
+#endif /* BCMPCIE */
+
+static void
+dhd_dpc(ulong data)
+{
+	dhd_info_t *dhd = (dhd_info_t *)data;
+	int curr_cpu = get_cpu();
+
+	put_cpu();
+
+	/* Store current cpu as dpc_cpu */
+	atomic_set(&dhd->dpc_cpu, curr_cpu);
+
+	/* this (tasklet) can be scheduled in dhd_sched_dpc[dhd_linux.c]
+	 * down below , wake lock is set,
+	 * the tasklet is initialized in dhd_attach()
+	 */
+	/* Call bus dpc unless it indicated down (then clean stop) */
+	if (dhd->pub.busstate != DHD_BUS_DOWN) {
+#if defined(DHD_LB_STATS) && defined(PCIE_FULL_DONGLE)
+		DHD_LB_STATS_INCR(dhd->dhd_dpc_cnt);
+#endif /* DHD_LB_STATS && PCIE_FULL_DONGLE */
+		if (dhd_bus_dpc(dhd->pub.bus)) {
+			tasklet_schedule(&dhd->tasklet);
+			dhd_plat_report_bh_sched(dhd->pub.plat_info, 1);
+		} else {
+			dhd_plat_report_bh_sched(dhd->pub.plat_info, 0);
+		}
+	} else {
+		dhd_bus_stop(dhd->pub.bus, TRUE);
+	}
+
+	/* Store as prev_dpc_cpu, which will be used in Rx load balancing for deciding candidacy */
+	atomic_set(&dhd->prev_dpc_cpu, curr_cpu);
+
+}
+
+void
+dhd_sched_dpc(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+
+	if (dhd->thr_dpc_ctl.thr_pid >= 0) {
+		DHD_OS_WAKE_LOCK(dhdp);
+		/* If the semaphore does not get up,
+		* wake unlock should be done here
+		*/
+		if (!binary_sema_up(&dhd->thr_dpc_ctl)) {
+			DHD_OS_WAKE_UNLOCK(dhdp);
+		}
+		return;
+	} else {
+		tasklet_schedule(&dhd->tasklet);
+	}
+}
+#endif /* BCMDBUS */
+
+#ifdef TOE
+/* Retrieve current toe component enables, which are kept as a bitmap in toe_ol iovar */
+static int
+dhd_toe_get(dhd_info_t *dhd, int ifidx, uint32 *toe_ol)
+{
+	char buf[32];
+	int ret;
+
+	ret = dhd_iovar(&dhd->pub, ifidx, "toe_ol", NULL, 0, (char *)&buf, sizeof(buf), FALSE);
+
+	if (ret < 0) {
+		if (ret == -EIO) {
+			DHD_ERROR(("%s: toe not supported by device\n", dhd_ifname(&dhd->pub,
+				ifidx)));
+			return -EOPNOTSUPP;
+		}
+
+		DHD_INFO(("%s: could not get toe_ol: ret=%d\n", dhd_ifname(&dhd->pub, ifidx), ret));
+		return ret;
+	}
+
+	memcpy(toe_ol, buf, sizeof(uint32));
+	return 0;
+}
+
+/* Set current toe component enables in toe_ol iovar, and set toe global enable iovar */
+static int
+dhd_toe_set(dhd_info_t *dhd, int ifidx, uint32 toe_ol)
+{
+	int toe, ret;
+
+	/* Set toe_ol as requested */
+	ret = dhd_iovar(&dhd->pub, ifidx, "toe_ol", (char *)&toe_ol, sizeof(toe_ol), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: could not set toe_ol: ret=%d\n",
+			dhd_ifname(&dhd->pub, ifidx), ret));
+		return ret;
+	}
+
+	/* Enable toe globally only if any components are enabled. */
+	toe = (toe_ol != 0);
+	ret = dhd_iovar(&dhd->pub, ifidx, "toe", (char *)&toe, sizeof(toe), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: could not set toe: ret=%d\n", dhd_ifname(&dhd->pub, ifidx), ret));
+		return ret;
+	}
+
+	return 0;
+}
+#endif /* TOE */
+
+#if defined(WL_CFG80211) && defined(NUM_SCB_MAX_PROBE)
+void dhd_set_scb_probe(dhd_pub_t *dhd)
+{
+	wl_scb_probe_t scb_probe;
+	char iovbuf[WL_EVENTING_MASK_LEN + sizeof(wl_scb_probe_t)];
+	int ret;
+
+	if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
+		return;
+	}
+
+	ret = dhd_iovar(dhd, 0, "scb_probe", NULL, 0, iovbuf, sizeof(iovbuf), FALSE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: GET max_scb_probe failed\n", __FUNCTION__));
+	}
+
+	memcpy(&scb_probe, iovbuf, sizeof(wl_scb_probe_t));
+
+	scb_probe.scb_max_probe = NUM_SCB_MAX_PROBE;
+
+	ret = dhd_iovar(dhd, 0, "scb_probe", (char *)&scb_probe, sizeof(wl_scb_probe_t), NULL, 0,
+			TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: max_scb_probe setting failed\n", __FUNCTION__));
+		return;
+	}
+}
+#endif /* WL_CFG80211 && NUM_SCB_MAX_PROBE */
+
+static void
+dhd_ethtool_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+
+	snprintf(info->driver, sizeof(info->driver), "wl");
+	snprintf(info->version, sizeof(info->version), "%lu", dhd->pub.drv_version);
+}
+
+#ifdef DHD_HWTSTAMP
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
+static int
+dhd_ethtool_get_ts_info(struct net_device *net, struct ethtool_ts_info *info)
+{
+	info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE |
+		SOF_TIMESTAMPING_RX_HARDWARE |
+		SOF_TIMESTAMPING_RAW_HARDWARE;
+
+	info->phc_index = -1;
+	info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
+	info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
+		(1 << HWTSTAMP_FILTER_ALL);
+	return 0;
+}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)) */
+#endif /* DHD_HWTSTAMP */
+
+struct ethtool_ops dhd_ethtool_ops = {
+	.get_drvinfo = dhd_ethtool_get_drvinfo,
+#ifdef DHD_HWTSTAMP
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
+	.get_ts_info = dhd_ethtool_get_ts_info,
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)) */
+#endif /* DHD_HWTSTAMP */
+};
+
+static int
+dhd_ethtool(dhd_info_t *dhd, void *uaddr)
+{
+	struct ethtool_drvinfo info;
+	char drvname[sizeof(info.driver)];
+	uint32 cmd;
+#ifdef TOE
+	struct ethtool_value edata;
+	uint32 toe_cmpnt, csum_dir;
+	int ret;
+#endif
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+	/* all ethtool calls start with a cmd word */
+	if (copy_from_user(&cmd, uaddr, sizeof (uint32)))
+		return -EFAULT;
+
+	switch (cmd) {
+	case ETHTOOL_GDRVINFO:
+		/* Copy out any request driver name */
+		bzero(&info.driver, sizeof(info.driver));
+		if (copy_from_user(&info, uaddr, sizeof(info)))
+			return -EFAULT;
+		if (info.driver[sizeof(info.driver) - 1] != '\0') {
+			DHD_ERROR(("%s: Exceeds the size of info.driver"
+				"truncating last byte with null\n", __FUNCTION__));
+			info.driver[sizeof(info.driver) - 1] = '\0';
+		}
+		strlcpy(drvname, info.driver, sizeof(drvname));
+
+		/* clear struct for return */
+		memset(&info, 0, sizeof(info));
+		info.cmd = cmd;
+
+		/* if dhd requested, identify ourselves */
+		if (strcmp(drvname, "?dhd") == 0) {
+			snprintf(info.driver, sizeof(info.driver), "dhd");
+			strlcpy(info.version, EPI_VERSION_STR, sizeof(info.version));
+		}
+
+		/* otherwise, require dongle to be up */
+		else if (!dhd->pub.up) {
+			DHD_ERROR(("%s: dongle is not up\n", __FUNCTION__));
+			return -ENODEV;
+		}
+
+		/* finally, report dongle driver type */
+		else if (dhd->pub.iswl)
+			snprintf(info.driver, sizeof(info.driver), "wl");
+		else
+			snprintf(info.driver, sizeof(info.driver), "xx");
+
+		snprintf(info.version, sizeof(info.version), "%lu", dhd->pub.drv_version);
+		if (copy_to_user(uaddr, &info, sizeof(info)))
+			return -EFAULT;
+		DHD_CTL(("%s: given %*s, returning %s\n", __FUNCTION__,
+		         (int)sizeof(drvname), drvname, info.driver));
+		break;
+
+#ifdef TOE
+	/* Get toe offload components from dongle */
+	case ETHTOOL_GRXCSUM:
+	case ETHTOOL_GTXCSUM:
+		if ((ret = dhd_toe_get(dhd, 0, &toe_cmpnt)) < 0)
+			return ret;
+
+		csum_dir = (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
+
+		edata.cmd = cmd;
+		edata.data = (toe_cmpnt & csum_dir) ? 1 : 0;
+
+		if (copy_to_user(uaddr, &edata, sizeof(edata)))
+			return -EFAULT;
+		break;
+
+	/* Set toe offload components in dongle */
+	case ETHTOOL_SRXCSUM:
+	case ETHTOOL_STXCSUM:
+		if (copy_from_user(&edata, uaddr, sizeof(edata)))
+			return -EFAULT;
+
+		/* Read the current settings, update and write back */
+		if ((ret = dhd_toe_get(dhd, 0, &toe_cmpnt)) < 0)
+			return ret;
+
+		csum_dir = (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL;
+
+		if (edata.data != 0)
+			toe_cmpnt |= csum_dir;
+		else
+			toe_cmpnt &= ~csum_dir;
+
+		if ((ret = dhd_toe_set(dhd, 0, toe_cmpnt)) < 0)
+			return ret;
+
+		/* If setting TX checksum mode, tell Linux the new mode */
+		if (cmd == ETHTOOL_STXCSUM) {
+			if (edata.data)
+				dhd->iflist[0]->net->features |= NETIF_F_IP_CSUM;
+			else
+				dhd->iflist[0]->net->features &= ~NETIF_F_IP_CSUM;
+		}
+
+		break;
+#endif /* TOE */
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	return 0;
+}
+
+#if defined(DHD_HWTSTAMP)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
+int
+dhd_hwtstamp_txtype(dhd_pub_t *dhdp)
+{
+	int ret = BCME_OK;
+
+	if (!dhdp || !dhdp->info) {
+		return ret;
+	}
+
+	return dhdp->info->stmpconf.tx_type;
+}
+
+static int
+dhd_hwtstamp_set(dhd_info_t *dhd, void *uaddr)
+{
+	struct hwtstamp_config stmpconf;
+
+	if (copy_from_user(&stmpconf, uaddr, sizeof(stmpconf)))
+		return -EFAULT;
+
+	if (stmpconf.flags)
+		return -EINVAL;
+
+	if (stmpconf.tx_type != HWTSTAMP_TX_ON &&
+	    stmpconf.tx_type != HWTSTAMP_TX_OFF)
+		return -ERANGE;
+
+	switch (stmpconf.rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		/* fall through */
+	case HWTSTAMP_FILTER_ALL:
+		break;
+	default:
+		return -ERANGE;
+	}
+	memcpy(&dhd->stmpconf, &stmpconf, sizeof(stmpconf));
+	return copy_to_user(uaddr, &stmpconf, sizeof(stmpconf)) ?
+		-EFAULT : 0;
+}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)) */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+static int
+dhd_hwtstamp_get(dhd_info_t *dhd, void *uaddr)
+{
+	return copy_to_user(uaddr, &dhd->stmpconf, sizeof(struct hwtstamp_config)) ?
+		-EFAULT : 0;
+}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) */
+#endif /* DHD_HWTSTAMP */
+
+/* XXX function to detect that FW is dead and send Event up */
+static bool dhd_check_hang(struct net_device *net, dhd_pub_t *dhdp, int error)
+{
+#if defined(OEM_ANDROID)
+	if (!dhdp) {
+		DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__));
+		return FALSE;
+	}
+
+	if (!dhdp->up)
+		return FALSE;
+
+#if (!defined(BCMDBUS) && !defined(BCMPCIE))
+	if (dhdp->info->thr_dpc_ctl.thr_pid < 0) {
+		DHD_ERROR(("%s : skipped due to negative pid - unloading?\n", __FUNCTION__));
+		return FALSE;
+	}
+#endif /* BCMDBUS */
+
+	if ((error == -ETIMEDOUT) || (error == -EREMOTEIO) ||
+		((dhdp->busstate == DHD_BUS_DOWN) && (!dhdp->dongle_reset))) {
+		if (dhdp->stop_in_progress || atomic_read(&exit_in_progress)) {
+			DHD_ERROR(("%s dhd_stop or module exit in progress\n", __func__));
+			return FALSE;
+		}
+#ifdef BCMPCIE
+		DHD_ERROR(("%s: Event HANG send up due to  re=%d te=%d d3acke=%d e=%d s=%d\n",
+			__FUNCTION__, dhdp->rxcnt_timeout, dhdp->txcnt_timeout,
+			dhdp->d3ackcnt_timeout, error, dhdp->busstate));
+#else
+		DHD_ERROR(("%s: Event HANG send up due to  re=%d te=%d e=%d s=%d\n", __FUNCTION__,
+			dhdp->rxcnt_timeout, dhdp->txcnt_timeout, error, dhdp->busstate));
+#endif /* BCMPCIE */
+		if (dhdp->hang_reason == 0) {
+			if (dhdp->dongle_trap_occured) {
+				dhdp->hang_reason = HANG_REASON_DONGLE_TRAP;
+#ifdef BCMPCIE
+			} else if (dhdp->d3ackcnt_timeout) {
+				dhdp->hang_reason = dhdp->is_sched_error ?
+					HANG_REASON_D3_ACK_TIMEOUT_SCHED_ERROR :
+					HANG_REASON_D3_ACK_TIMEOUT;
+#endif /* BCMPCIE */
+			} else {
+				dhdp->hang_reason = dhdp->is_sched_error ?
+					HANG_REASON_IOCTL_RESP_TIMEOUT_SCHED_ERROR :
+					HANG_REASON_IOCTL_RESP_TIMEOUT;
+			}
+		}
+		printf("%s\n", info_string);
+		printf("MAC %pM\n", &dhdp->mac);
+		net_os_send_hang_message(net);
+		return TRUE;
+	}
+#endif /* OEM_ANDROID */
+	return FALSE;
+}
+
+#if defined(DBG_PKT_MON)
+#ifdef PCIE_FULL_DONGLE
+void
+dhd_80211_mon_pkt(dhd_pub_t *dhdp, host_rxbuf_cmpl_t* msg, void *pkt, int ifidx)
+{
+	/* Distinguish rx/tx frame */
+	wl_aml_header_v1_t hdr;
+
+	hdr = *(wl_aml_header_v1_t *)PKTDATA(dhdp->osh, pkt);
+	PKTPULL(dhdp->osh, pkt, sizeof(hdr));
+	if (hdr.flags & WL_AML_F_DIRECTION) {
+		bool ack = !!(hdr.flags & WL_AML_F_ACKED);
+		DHD_DBG_PKT_MON_TX(dhdp, pkt, 0, FRAME_TYPE_80211_MGMT, (uint8)ack);
+	} else {
+		DHD_DBG_PKT_MON_RX(dhdp, (struct sk_buff *)pkt, FRAME_TYPE_80211_MGMT);
+	}
+}
+#else
+bool
+dhd_80211_mon_pkt(dhd_pub_t *dhdp, void *pkt, int ifidx)
+{
+	/* Distinguish rx/tx frame */
+	wl_aml_header_v1_t hdr;
+
+	hdr = *(wl_aml_header_v1_t *)PKTDATA(dhdp->osh, pkt);
+	if (hdr.version == WL_AML_HEADER_VERSION) {
+		if (hdr.flags & WL_AML_F_MGMT) {
+			PKTPULL(dhdp->osh, pkt, sizeof(hdr));
+			if (hdr.flags & WL_AML_F_DIRECTION) {
+				bool ack = !!(hdr.flags & WL_AML_F_ACKED);
+				DHD_DBG_PKT_MON_TX(dhdp, pkt, 0, FRAME_TYPE_80211_MGMT, (uint8)ack);
+			} else {
+				DHD_DBG_PKT_MON_RX(dhdp, (struct sk_buff *)pkt,
+					FRAME_TYPE_80211_MGMT);
+			}
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+#endif /* PCIE_FULL_DONGLE */
+#endif /* DBG_PKT_MON */
+
+#if defined(BT_OVER_SDIO)
+
+void
+dhdsdio_bus_usr_cnt_inc(dhd_pub_t *dhdp)
+{
+	dhdp->info->bus_user_count++;
+}
+
+void
+dhdsdio_bus_usr_cnt_dec(dhd_pub_t *dhdp)
+{
+	dhdp->info->bus_user_count--;
+}
+
+/* Return values:
+ * Success: Returns 0
+ * Failure: Returns -1 or errono code
+ */
+int
+dhd_bus_get(wlan_bt_handle_t handle, bus_owner_t owner)
+{
+	dhd_pub_t *dhdp = (dhd_pub_t *)handle;
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+	int ret = 0;
+
+	mutex_lock(&dhd->bus_user_lock);
+	++dhd->bus_user_count;
+	if (dhd->bus_user_count < 0) {
+		DHD_ERROR(("%s(): bus_user_count is negative, which is invalid\n", __FUNCTION__));
+		ret = -1;
+		goto exit;
+	}
+
+	if (dhd->bus_user_count == 1) {
+
+		dhd->pub.hang_was_sent = 0;
+
+		/* First user, turn on WL_REG, start the bus */
+		DHD_ERROR(("%s(): First user Turn On WL_REG & start the bus", __FUNCTION__));
+
+		if (!wifi_platform_set_power(dhd->adapter, TRUE, WIFI_TURNON_DELAY)) {
+			/* Enable F1 */
+			ret = dhd_bus_resume(dhdp, 0);
+			if (ret) {
+				DHD_ERROR(("%s(): Failed to enable F1, err=%d\n",
+					__FUNCTION__, ret));
+				goto exit;
+			}
+		}
+
+		/* XXX Some DHD modules (e.g. cfg80211) configures operation mode based on firmware
+		 * name. This is indeed a hack but we have to make it work properly before we have
+		 * a better solution
+		 */
+		dhd_update_fw_nv_path(dhd);
+		/* update firmware and nvram path to sdio bus */
+		dhd_bus_update_fw_nv_path(dhd->pub.bus,
+			dhd->fw_path, dhd->nv_path);
+		/* download the firmware, Enable F2 */
+		/* TODO: Should be done only in case of FW switch */
+		ret = dhd_bus_devreset(dhdp, FALSE);
+		dhd_bus_resume(dhdp, 1);
+		if (!ret) {
+			if (dhd_sync_with_dongle(&dhd->pub) < 0) {
+				DHD_ERROR(("%s(): Sync with dongle failed!!\n", __FUNCTION__));
+				ret = -EFAULT;
+			}
+		} else {
+			DHD_ERROR(("%s(): Failed to download, err=%d\n", __FUNCTION__, ret));
+		}
+	} else {
+		DHD_ERROR(("%s(): BUS is already acquired, just increase the count %d \r\n",
+			__FUNCTION__, dhd->bus_user_count));
+	}
+exit:
+	mutex_unlock(&dhd->bus_user_lock);
+	return ret;
+}
+EXPORT_SYMBOL(dhd_bus_get);
+
+/* Return values:
+ * Success: Returns 0
+ * Failure: Returns -1 or errono code
+ */
+int
+dhd_bus_put(wlan_bt_handle_t handle, bus_owner_t owner)
+{
+	dhd_pub_t *dhdp = (dhd_pub_t *)handle;
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+	int ret = 0;
+	BCM_REFERENCE(owner);
+
+	mutex_lock(&dhd->bus_user_lock);
+	--dhd->bus_user_count;
+	if (dhd->bus_user_count < 0) {
+		DHD_ERROR(("%s(): bus_user_count is negative, which is invalid\n", __FUNCTION__));
+		dhd->bus_user_count = 0;
+		ret = -1;
+		goto exit;
+	}
+
+	if (dhd->bus_user_count == 0) {
+		/* Last user, stop the bus and turn Off WL_REG */
+		DHD_ERROR(("%s(): There are no owners left Trunf Off WL_REG & stop the bus \r\n",
+			__FUNCTION__));
+#ifdef PROP_TXSTATUS
+		if (dhd->pub.wlfc_enabled) {
+			dhd_wlfc_deinit(&dhd->pub);
+		}
+#endif /* PROP_TXSTATUS */
+#ifdef PNO_SUPPORT
+		if (dhd->pub.pno_state) {
+			dhd_pno_deinit(&dhd->pub);
+		}
+#endif /* PNO_SUPPORT */
+#ifdef RTT_SUPPORT
+		if (dhd->pub.rtt_state) {
+			dhd_rtt_deinit(&dhd->pub);
+		}
+#endif /* RTT_SUPPORT */
+		ret = dhd_bus_devreset(dhdp, TRUE);
+		if (!ret) {
+			dhd_bus_suspend(dhdp);
+			wifi_platform_set_power(dhd->adapter, FALSE, WIFI_TURNOFF_DELAY);
+		}
+	} else {
+		DHD_ERROR(("%s(): Other owners using bus, decrease the count %d \r\n",
+			__FUNCTION__, dhd->bus_user_count));
+	}
+exit:
+	mutex_unlock(&dhd->bus_user_lock);
+	return ret;
+}
+EXPORT_SYMBOL(dhd_bus_put);
+
+int
+dhd_net_bus_get(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	return dhd_bus_get(&dhd->pub, WLAN_MODULE);
+}
+
+int
+dhd_net_bus_put(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	return dhd_bus_put(&dhd->pub, WLAN_MODULE);
+}
+
+/*
+ * Function to enable the Bus Clock
+ * Returns BCME_OK on success and BCME_xxx on failure
+ *
+ * This function is not callable from non-sleepable context
+ */
+int dhd_bus_clk_enable(wlan_bt_handle_t handle, bus_owner_t owner)
+{
+	dhd_pub_t *dhdp = (dhd_pub_t *)handle;
+
+	int ret;
+
+	dhd_os_sdlock(dhdp);
+	/*
+	 * The second argument is TRUE, that means, we expect
+	 * the function to "wait" until the clocks are really
+	 * available
+	 */
+	ret = __dhdsdio_clk_enable(dhdp->bus, owner, TRUE);
+	dhd_os_sdunlock(dhdp);
+
+	return ret;
+}
+EXPORT_SYMBOL(dhd_bus_clk_enable);
+
+/*
+ * Function to disable the Bus Clock
+ * Returns BCME_OK on success and BCME_xxx on failure
+ *
+ * This function is not callable from non-sleepable context
+ */
+int dhd_bus_clk_disable(wlan_bt_handle_t handle, bus_owner_t owner)
+{
+	dhd_pub_t *dhdp = (dhd_pub_t *)handle;
+
+	int ret;
+
+	dhd_os_sdlock(dhdp);
+	/*
+	 * The second argument is TRUE, that means, we expect
+	 * the function to "wait" until the clocks are really
+	 * disabled
+	 */
+	ret = __dhdsdio_clk_disable(dhdp->bus, owner, TRUE);
+	dhd_os_sdunlock(dhdp);
+
+	return ret;
+}
+EXPORT_SYMBOL(dhd_bus_clk_disable);
+
+/*
+ * Function to reset bt_use_count counter to zero.
+ *
+ * This function is not callable from non-sleepable context
+ */
+void dhd_bus_reset_bt_use_count(wlan_bt_handle_t handle)
+{
+	dhd_pub_t *dhdp = (dhd_pub_t *)handle;
+
+	/* take the lock and reset bt use count */
+	dhd_os_sdlock(dhdp);
+	dhdsdio_reset_bt_use_count(dhdp->bus);
+	dhd_os_sdunlock(dhdp);
+}
+EXPORT_SYMBOL(dhd_bus_reset_bt_use_count);
+
+void dhd_bus_retry_hang_recovery(wlan_bt_handle_t handle)
+{
+	dhd_pub_t *dhdp = (dhd_pub_t *)handle;
+	dhd_info_t *dhd = (dhd_info_t*)dhdp->info;
+
+	dhdp->hang_was_sent = 0;
+
+	dhd_os_send_hang_message(&dhd->pub);
+}
+EXPORT_SYMBOL(dhd_bus_retry_hang_recovery);
+#endif /* BT_OVER_SDIO */
+
+void dhd_unregister_net(struct net_device *net, bool need_rtnl_lock)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+	if (need_rtnl_lock) {
+		rtnl_lock();
+		cfg80211_unregister_netdevice(net);
+		rtnl_unlock();
+	} else {
+		cfg80211_unregister_netdevice(net);
+	}
+#else
+	if (need_rtnl_lock) {
+		unregister_netdev(net);
+	} else {
+		unregister_netdevice(net);
+	}
+#endif /* KERNEL_VER >= KERNEL_VERSION(5, 15, 0) */
+	return;
+}
+
+int dhd_register_net(struct net_device *net, bool need_rtnl_lock)
+{
+	int err = 0;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+	if (need_rtnl_lock) {
+		rtnl_lock();
+		err = cfg80211_register_netdevice(net);
+		rtnl_unlock();
+	} else {
+		err = cfg80211_register_netdevice(net);
+	}
+#else
+	if (need_rtnl_lock) {
+		err = register_netdev(net);
+	} else {
+		err = register_netdevice(net);
+	}
+#endif /* KERNEL_VER >= KERNEL_VERSION(5, 15, 0) */
+	return err;
+}
+
+#ifdef WL_MONITOR
+bool
+dhd_monitor_enabled(dhd_pub_t *dhd, int ifidx)
+{
+	return (dhd->info->monitor_type != 0);
+}
+
+typedef struct dhd_mon_dev_priv {
+	dhd_info_t *dhd;
+	struct net_device_stats stats;
+} dhd_mon_dev_priv_t;
+
+#define DHD_MON_DEV_PRIV_SIZE		(sizeof(dhd_mon_dev_priv_t))
+#define DHD_MON_DEV_PRIV(dev)		((dhd_mon_dev_priv_t *)DEV_PRIV(dev))
+#define DHD_MON_DEV_INFO(dev)		(((dhd_mon_dev_priv_t *)DEV_PRIV(dev))->dhd)
+#define DHD_MON_DEV_STATS(dev)		(((dhd_mon_dev_priv_t *)DEV_PRIV(dev))->stats)
+
+static netdev_tx_t
+dhd_monitor_start(struct sk_buff *skb, struct net_device *dev)
+{
+	PKTFREE(NULL, skb, FALSE);
+	return NETDEV_TX_OK;
+}
+
+#ifdef WL_CFG80211_MONITOR
+static int
+dhd_set_monitor_ioctl(dhd_pub_t *dhdp, bool val)
+{
+	dhd_info_t *dhd = dhdp->info;
+	int ret = 0;
+	uint monitor = (uint)val;
+
+	DHD_TRACE(("%s: val %d\n", __FUNCTION__, val));
+
+	if ((ret = dhd_wl_ioctl_cmd(dhdp, WLC_SET_MONITOR, &monitor,
+			sizeof(monitor), TRUE, 0)) != 0) {
+		DHD_ERROR(("%s Failed to set monitor mode, err %d\n",
+			__FUNCTION__, ret));
+	} else {
+		dhd_net_if_lock_local(dhd);
+		dhd->monitor_type = monitor;
+		dhd_net_if_unlock_local(dhd);
+	}
+
+	return ret;
+}
+
+static int
+dhd_monitor_open(struct net_device *net)
+{
+	int ret = 0;
+	dhd_info_t *dhd = DHD_MON_DEV_INFO(net);
+	uint32 scan_suppress = FALSE;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd info not available \n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	if (!dhd->pub.monitor_enable) {
+		DHD_ERROR(("%s: Monitor mode is not enabled in FW cap\n",
+			__FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	ret = dhd_set_monitor_ioctl(&dhd->pub, TRUE);
+	if (ret) {
+		DHD_ERROR(("%s: Set monitor mode IOCTL failed.\n", __FUNCTION__));
+		return ret;
+	}
+
+	if (FW_SUPPORTED((&dhd->pub), monitor)) {
+		scan_suppress = TRUE;
+		/* Set the SCAN SUPPRESS Flag in the firmware to disable scan in Monitor mode */
+		ret = dhd_iovar(&dhd->pub, 0, "scansuppress", (char *)&scan_suppress,
+			sizeof(scan_suppress), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: scansuppress set failed, ret=%d\n", __FUNCTION__, ret));
+		}
+	}
+
+	return ret;
+}
+
+static int
+dhd_monitor_stop(struct net_device *net)
+{
+	int ret = 0;
+	dhd_info_t *dhd = DHD_MON_DEV_INFO(net);
+	uint32 scan_suppress = FALSE;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd info not available \n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	if (!dhd->pub.monitor_enable) {
+		DHD_ERROR(("%s: Monitor mode is not enabled in FW cap\n",
+			__FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	if (FW_SUPPORTED((&dhd->pub), monitor)) {
+		scan_suppress = FALSE;
+		/* Unset the SCAN SUPPRESS Flag in the firmware to enable scan */
+		ret = dhd_iovar(&dhd->pub, 0, "scansuppress", (char *)&scan_suppress,
+				sizeof(scan_suppress), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: scansuppress set failed, ret=%d\n", __FUNCTION__, ret));
+		}
+	}
+
+	ret = dhd_set_monitor_ioctl(&dhd->pub, FALSE);
+	if (ret) {
+		DHD_ERROR(("%s: Set monitor mode IOCTL failed.\n", __FUNCTION__));
+		return ret;
+	}
+
+	return ret;
+}
+#endif /* WL_CFG80211_MONITOR */
+
+static int
+dhd_monitor_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	return 0;
+}
+
+static struct net_device_stats*
+dhd_monitor_get_stats(struct net_device *dev)
+{
+	return &DHD_MON_DEV_STATS(dev);
+}
+
+static const struct net_device_ops netdev_monitor_ops =
+{
+	.ndo_start_xmit = dhd_monitor_start,
+	.ndo_get_stats = dhd_monitor_get_stats,
+#ifdef WL_CFG80211_MONITOR
+	.ndo_open = dhd_monitor_open,
+	.ndo_stop = dhd_monitor_stop,
+#endif /* WL_CFG80211_MONITOR */
+	.ndo_do_ioctl = dhd_monitor_ioctl
+};
+
+static void
+dhd_add_monitor_if(dhd_info_t *dhd)
+{
+	struct net_device *dev;
+	char *devname;
+#ifdef HOST_RADIOTAP_CONV
+	dhd_pub_t *dhdp = (dhd_pub_t *)&dhd->pub;
+#endif /* HOST_RADIOTAP_CONV */
+	dhd_mon_dev_priv_t *dev_priv;
+
+	BCM_REFERENCE(dev_priv);
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd info not available \n", __FUNCTION__));
+		return;
+	}
+
+	if (dhd->monitor_dev) {
+		DHD_ERROR(("%s: monitor i/f already exists", __FUNCTION__));
+		return;
+	}
+
+	dev = alloc_etherdev(DHD_MON_DEV_PRIV_SIZE);
+	if (!dev) {
+		DHD_ERROR(("%s: alloc wlif failed\n", __FUNCTION__));
+		return;
+	}
+
+	devname = "radiotap";
+
+	snprintf(dev->name, sizeof(dev->name), "%s%u", devname, dhd->unit);
+
+#ifndef ARPHRD_IEEE80211_PRISM  /* From Linux 2.4.18 */
+#define ARPHRD_IEEE80211_PRISM 802
+#endif
+
+#ifndef ARPHRD_IEEE80211_RADIOTAP
+#define ARPHRD_IEEE80211_RADIOTAP	803 /* IEEE 802.11 + radiotap header */
+#endif /* ARPHRD_IEEE80211_RADIOTAP */
+
+	dev->type = ARPHRD_IEEE80211_RADIOTAP;
+
+	dev->netdev_ops = &netdev_monitor_ops;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 9))
+	/* as priv_destructor calls free_netdev, no need to set need_free_netdev */
+	dev->needs_free_netdev = 0;
+	dev->priv_destructor = free_netdev;
+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 9) */
+	dev->destructor = free_netdev;
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 9) */
+
+	/* XXX: This is called from IOCTL path, in this case, rtnl_lock is already taken.
+	 * So, register_netdev() shouldn't be called. It leads to deadlock.
+	 * To avoid deadlock due to rtnl_lock(), register_netdevice() should be used.
+	 */
+	if (register_netdevice(dev)) {
+		DHD_ERROR(("%s, register_netdev failed for %s\n",
+			__FUNCTION__, dev->name));
+		free_netdev(dev);
+		return;
+	}
+
+#ifdef HOST_RADIOTAP_CONV
+	bcmwifi_monitor_create(&dhd->monitor_info);
+	bcmwifi_set_corerev_major(dhd->monitor_info, dhdpcie_get_corerev_major(dhdp));
+	bcmwifi_set_corerev_minor(dhd->monitor_info, dhdpcie_get_corerev_minor(dhdp));
+#endif /* HOST_RADIOTAP_CONV */
+	dhd->monitor_dev = dev;
+#ifdef WL_CFG80211_MONITOR
+	dev_priv = DHD_MON_DEV_PRIV(dev);
+	dev_priv->dhd = dhd;
+	bzero(&dev_priv->stats, sizeof(dev_priv->stats));
+#endif /* WL_CFG80211_MONITOR */
+}
+
+static void
+dhd_del_monitor_if(dhd_info_t *dhd)
+{
+	dhd_mon_dev_priv_t *dev_priv;
+
+	BCM_REFERENCE(dev_priv);
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd info not available \n", __FUNCTION__));
+		return;
+	}
+
+	if (!dhd->monitor_dev) {
+		DHD_ERROR(("%s: monitor i/f doesn't exist\n", __FUNCTION__));
+		return;
+	}
+#ifdef WL_CFG80211_MONITOR
+	dhd->monitor_type = FALSE;
+	dev_priv = DHD_MON_DEV_PRIV(dhd->monitor_dev);
+	dev_priv->dhd = (dhd_info_t *)NULL;
+	bzero(&dev_priv->stats, sizeof(dev_priv->stats));
+#endif /* WL_CFG80211_MONITOR */
+
+	if (dhd->monitor_dev) {
+		if (dhd->monitor_dev->reg_state == NETREG_UNINITIALIZED) {
+			free_netdev(dhd->monitor_dev);
+		} else {
+			if (rtnl_is_locked()) {
+				unregister_netdevice(dhd->monitor_dev);
+			} else {
+				unregister_netdev(dhd->monitor_dev);
+			}
+		}
+		dhd->monitor_dev = NULL;
+	}
+#ifdef HOST_RADIOTAP_CONV
+	if (dhd->monitor_info) {
+		bcmwifi_monitor_delete(dhd->monitor_info);
+		dhd->monitor_info = NULL;
+	}
+#endif /* HOST_RADIOTAP_CONV */
+}
+
+void
+dhd_set_monitor(dhd_pub_t *pub, int ifidx, int val)
+{
+	dhd_info_t *dhd = pub->info;
+
+	DHD_TRACE(("%s: val %d\n", __FUNCTION__, val));
+
+	dhd_net_if_lock_local(dhd);
+	if (!val) {
+			/* Delete monitor */
+			dhd_del_monitor_if(dhd);
+	} else {
+			/* Add monitor */
+			dhd_add_monitor_if(dhd);
+	}
+	dhd->monitor_type = val;
+	dhd_net_if_unlock_local(dhd);
+}
+#endif /* WL_MONITOR */
+
+#if defined(DHD_H2D_LOG_TIME_SYNC)
+/*
+ * Helper function:
+ * Used for RTE console message time syncing with Host printk
+ */
+void dhd_h2d_log_time_sync_deferred_wq_schedule(dhd_pub_t *dhdp)
+{
+	dhd_info_t *info = dhdp->info;
+
+	/* Ideally the "state" should be always TRUE */
+	dhd_deferred_schedule_work(info->dhd_deferred_wq, NULL,
+			DHD_WQ_WORK_H2D_CONSOLE_TIME_STAMP_MATCH,
+			dhd_deferred_work_rte_log_time_sync,
+			DHD_WQ_WORK_PRIORITY_LOW);
+}
+
+void
+dhd_deferred_work_rte_log_time_sync(void *handle, void *event_info, u8 event)
+{
+	dhd_info_t *dhd_info = handle;
+	dhd_pub_t *dhd;
+
+	if (event != DHD_WQ_WORK_H2D_CONSOLE_TIME_STAMP_MATCH) {
+		DHD_ERROR(("%s: unexpected event \n", __FUNCTION__));
+		return;
+	}
+
+	if (!dhd_info) {
+		DHD_ERROR(("%s: dhd info not available \n", __FUNCTION__));
+		return;
+	}
+
+	dhd = &dhd_info->pub;
+
+	/*
+	 * Function to send IOVAR for console timesyncing
+	 * between Host and Dongle.
+	 * If the IOVAR fails,
+	 * 1. dhd_rte_time_sync_ms is set to 0 and
+	 * 2. HOST Dongle console time sync will *not* happen.
+	 */
+	dhd_h2d_log_time_sync(dhd);
+}
+#endif /* DHD_H2D_LOG_TIME_SYNC */
+
+int dhd_ioctl_process(dhd_pub_t *pub, int ifidx, dhd_ioctl_t *ioc, void *data_buf)
+{
+	int bcmerror = BCME_OK;
+	int buflen = 0;
+	struct net_device *net;
+
+	net = dhd_idx2net(pub, ifidx);
+	if (!net) {
+		bcmerror = BCME_BADARG;
+		/*
+		 * The netdev pointer is bad means the DHD can't communicate
+		 * to higher layers, so just return from here
+		 */
+		return bcmerror;
+	}
+
+	/* check for local dhd ioctl and handle it */
+	if (ioc->driver == DHD_IOCTL_MAGIC) {
+		if (data_buf) {
+			/* Return error if nvram size is too big */
+			if (!bcmstricmp((char *)data_buf, "vars")) {
+				DHD_ERROR(("%s: nvram len(%d) MAX_NVRAMBUF_SIZE(%d)\n",
+					__FUNCTION__, ioc->len, MAX_NVRAMBUF_SIZE));
+				if (ioc->len > MAX_NVRAMBUF_SIZE) {
+					DHD_ERROR(("%s: nvram len(%d) > MAX_NVRAMBUF_SIZE(%d)\n",
+						__FUNCTION__, ioc->len, MAX_NVRAMBUF_SIZE));
+					bcmerror = BCME_BUFTOOLONG;
+					goto done;
+				}
+				buflen = ioc->len;
+			} else if (!bcmstricmp((char *)data_buf, "dump") ||
+				!bcmstricmp((char *)data_buf, "counters") ||
+				!bcmstricmp((char *)data_buf, "dump_flowrings")) {
+				buflen = MIN(ioc->len, DHD_IOCTL_MAXLEN_32K);
+			} else {
+				/* This is a DHD IOVAR, truncate buflen to DHD_IOCTL_MAXLEN */
+				buflen = MIN(ioc->len, DHD_IOCTL_MAXLEN);
+			}
+		}
+		bcmerror = dhd_ioctl((void *)pub, ioc, data_buf, buflen);
+		if (bcmerror)
+			pub->bcmerror = bcmerror;
+		goto done;
+	}
+
+	/* This is a WL IOVAR, truncate buflen to WLC_IOCTL_MAXLEN */
+	if (data_buf)
+		buflen = MIN(ioc->len, WLC_IOCTL_MAXLEN);
+
+#ifndef BCMDBUS
+	/* send to dongle (must be up, and wl). */
+	if (pub->busstate == DHD_BUS_DOWN || pub->busstate == DHD_BUS_LOAD) {
+		if ((!pub->dongle_trap_occured) && allow_delay_fwdl) {
+			int ret;
+			if (atomic_read(&exit_in_progress)) {
+				DHD_ERROR(("%s module exit in progress\n", __func__));
+				bcmerror = BCME_DONGLE_DOWN;
+				goto done;
+			}
+			ret = dhd_bus_start(pub);
+			if (ret != 0) {
+				DHD_ERROR(("%s: failed with code %d\n", __FUNCTION__, ret));
+				bcmerror = BCME_DONGLE_DOWN;
+				goto done;
+			}
+		} else {
+			bcmerror = BCME_DONGLE_DOWN;
+			goto done;
+		}
+	}
+
+	if (!pub->iswl) {
+		bcmerror = BCME_DONGLE_DOWN;
+		goto done;
+	}
+#endif /* !BCMDBUS */
+
+	/*
+	 * Flush the TX queue if required for proper message serialization:
+	 * Intercept WLC_SET_KEY IOCTL - serialize M4 send and set key IOCTL to
+	 * prevent M4 encryption and
+	 * intercept WLC_DISASSOC IOCTL - serialize WPS-DONE and WLC_DISASSOC IOCTL to
+	 * prevent disassoc frame being sent before WPS-DONE frame.
+	 */
+	if (ioc->cmd == WLC_SET_KEY ||
+	    (ioc->cmd == WLC_SET_VAR && data_buf != NULL &&
+	     strncmp("wsec_key", data_buf, 9) == 0) ||
+	    (ioc->cmd == WLC_SET_VAR && data_buf != NULL &&
+	     strncmp("bsscfg:wsec_key", data_buf, 15) == 0) ||
+	    ioc->cmd == WLC_DISASSOC)
+		dhd_wait_pend8021x(net);
+
+	if ((ioc->cmd == WLC_SET_VAR || ioc->cmd == WLC_GET_VAR) &&
+		data_buf != NULL && strncmp("rpc_", data_buf, 4) == 0) {
+		bcmerror = BCME_UNSUPPORTED;
+		goto done;
+	}
+
+	/* XXX this typecast is BAD !!! */
+	bcmerror = dhd_wl_ioctl(pub, ifidx, (wl_ioctl_t *)ioc, data_buf, buflen);
+
+#ifdef REPORT_FATAL_TIMEOUTS
+	/* ensure that the timeouts/flags are started/set after the ioctl returns success */
+	if (bcmerror == BCME_OK) {
+		if (ioc->cmd == WLC_SET_WPA_AUTH) {
+			int wpa_auth;
+
+			wpa_auth = *((int *)ioc->buf);
+			DHD_INFO(("wpa_auth:%d\n", wpa_auth));
+			if (wpa_auth != WPA_AUTH_DISABLED) {
+				/* If AP is with security then enable
+				* WLC_E_PSK_SUP event checking
+				*/
+				pub->secure_join = TRUE;
+			} else {
+				/* If AP is with open then disable
+				* WLC_E_PSK_SUP event checking
+				*/
+				pub->secure_join = FALSE;
+			}
+		}
+
+		if (ioc->cmd == WLC_SET_AUTH) {
+			int auth;
+			auth = *((int *)ioc->buf);
+			DHD_INFO(("Auth:%d\n", auth));
+
+			if (auth != WL_AUTH_OPEN_SYSTEM) {
+				/* If AP is with security then enable
+				* WLC_E_PSK_SUP event checking
+				*/
+				pub->secure_join = TRUE;
+			} else {
+				/* If AP is with open then disable WLC_E_PSK_SUP event checking */
+				pub->secure_join = FALSE;
+			}
+		}
+
+		if (ioc->cmd == WLC_SET_SSID) {
+			char iov_buf[WLC_IOCTL_SMLEN];
+			wlc_bsscfg_info_t *info = (wlc_bsscfg_info_t *)iov_buf;
+			int  ret = BCME_OK;
+			/* we may apply join timer for STA only */
+			ret = dhd_iovar(pub, ifidx, "bsscfg_info", NULL, 0,
+			                (char *)iov_buf, sizeof(iov_buf), FALSE);
+			if (BCME_OK <= ret) {
+				if (BSSCFG_GENERIC_AP == info->subtype) {
+					ret = BCME_NOTSTA;
+				}
+			}
+			/* not apply for AP */
+			if (BCME_OK <= ret) {
+				bool set_ssid_rcvd = OSL_ATOMIC_READ(pub->osh, &pub->set_ssid_rcvd);
+				if ((!set_ssid_rcvd) && (!pub->secure_join)) {
+					dhd_start_join_timer(pub);
+				} else {
+					DHD_ERROR(("%s: didnot start join timer."
+						"open join, set_ssid_rcvd: %d secure_join: %d\n",
+						__FUNCTION__, set_ssid_rcvd, pub->secure_join));
+					OSL_ATOMIC_SET(pub->osh, &pub->set_ssid_rcvd, FALSE);
+				}
+			}
+		}
+
+		if (ioc->cmd == WLC_SCAN) {
+			dhd_start_scan_timer(pub, 0);
+		}
+	}
+#endif  /* REPORT_FATAL_TIMEOUTS */
+
+done:
+#if defined(OEM_ANDROID)
+	dhd_check_hang(net, pub, bcmerror);
+#endif /* OEM_ANDROID */
+
+	return bcmerror;
+}
+
+/* XXX For the moment, local ioctls will return BCM errors */
+/* XXX Others return linux codes, need to be changed... */
+/**
+ * Called by the OS (optionally via a wrapper function).
+ * @param net  Linux per dongle instance
+ * @param ifr  Linux request structure
+ * @param cmd  e.g. SIOCETHTOOL
+ */
+static int
+dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+	dhd_ioctl_t ioc;
+	int bcmerror = 0;
+	int ifidx;
+	int ret;
+	void *local_buf = NULL;           /**< buffer in kernel space */
+	void __user *ioc_buf_user = NULL; /**< buffer in user space */
+	u16 buflen = 0;
+
+	if (atomic_read(&exit_in_progress)) {
+		DHD_ERROR(("%s module exit in progress\n", __func__));
+		bcmerror = BCME_DONGLE_DOWN;
+		return OSL_ERROR(bcmerror);
+	}
+
+	DHD_OS_WAKE_LOCK(&dhd->pub);
+
+#if defined(OEM_ANDROID)
+	/* Interface up check for built-in type */
+	if (!dhd_download_fw_on_driverload && dhd->pub.up == FALSE) {
+		DHD_ERROR(("%s: Interface is down \n", __FUNCTION__));
+		DHD_OS_WAKE_UNLOCK(&dhd->pub);
+		return OSL_ERROR(BCME_NOTUP);
+	}
+#endif /* (OEM_ANDROID) */
+
+	ifidx = dhd_net2idx(dhd, net);
+	DHD_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __FUNCTION__, ifidx, cmd));
+
+#if defined(WL_STATIC_IF)
+	/* skip for static ndev when it is down */
+	if (dhd_is_static_ndev(&dhd->pub, net) && !(net->flags & IFF_UP)) {
+		DHD_OS_WAKE_UNLOCK(&dhd->pub);
+		return -1;
+	}
+#endif /* WL_STATIC_iF */
+
+	if (ifidx == DHD_BAD_IF) {
+		DHD_ERROR(("%s: BAD IF\n", __FUNCTION__));
+		DHD_OS_WAKE_UNLOCK(&dhd->pub);
+		return -1;
+	}
+
+#if defined(WL_WIRELESS_EXT)
+	/* linux wireless extensions */
+	if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) {
+		/* may recurse, do NOT lock */
+		ret = wl_iw_ioctl(net, ifr, cmd);
+		DHD_OS_WAKE_UNLOCK(&dhd->pub);
+		return ret;
+	}
+#endif /* defined(WL_WIRELESS_EXT) */
+
+	if (cmd == SIOCETHTOOL) {
+		ret = dhd_ethtool(dhd, (void*)ifr->ifr_data);
+		DHD_OS_WAKE_UNLOCK(&dhd->pub);
+		return ret;
+	}
+
+#if defined(DHD_HWTSTAMP)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
+	/* Set hardware timestamp configuration */
+	if (cmd == SIOCSHWTSTAMP) {
+		ret = dhd_hwtstamp_set(dhd, (void*)ifr->ifr_data);
+		DHD_OS_WAKE_UNLOCK(&dhd->pub);
+		return ret;
+	}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)) */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+	/* Get hardware timestamp configuration */
+	if (cmd == SIOCGHWTSTAMP) {
+		ret = dhd_hwtstamp_get(dhd, (void*)ifr->ifr_data);
+		DHD_OS_WAKE_UNLOCK(&dhd->pub);
+		return ret;
+	}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) */
+#endif /* DHD_HWTSTAMP */
+
+#if defined(OEM_ANDROID)
+	if (cmd == SIOCDEVPRIVATE+1) {
+		ret = wl_android_priv_cmd(net, ifr);
+		dhd_check_hang(net, &dhd->pub, ret);
+		DHD_OS_WAKE_UNLOCK(&dhd->pub);
+		return ret;
+	}
+
+#endif /* OEM_ANDROID */
+
+	if (cmd != SIOCDEVPRIVATE) {
+		DHD_OS_WAKE_UNLOCK(&dhd->pub);
+		return -EOPNOTSUPP;
+	}
+
+	memset(&ioc, 0, sizeof(ioc));
+
+#ifdef CONFIG_COMPAT
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0))
+	if (in_compat_syscall())
+#else
+	if (is_compat_task())
+#endif /* LINUX_VER >= 4.6 */
+	{
+		compat_wl_ioctl_t compat_ioc;
+		if (copy_from_user(&compat_ioc, ifr->ifr_data, sizeof(compat_wl_ioctl_t))) {
+			bcmerror = BCME_BADADDR;
+			goto done;
+		}
+		ioc.cmd = compat_ioc.cmd;
+		ioc.buf = compat_ptr(compat_ioc.buf);
+		ioc.len = compat_ioc.len;
+		ioc.set = compat_ioc.set;
+		ioc.used = compat_ioc.used;
+		ioc.needed = compat_ioc.needed;
+		/* To differentiate between wl and dhd read 4 more byes */
+		if ((copy_from_user(&ioc.driver, (char *)ifr->ifr_data + sizeof(compat_wl_ioctl_t),
+			sizeof(uint)) != 0)) {
+			bcmerror = BCME_BADADDR;
+			goto done;
+		}
+	} else
+#endif /* CONFIG_COMPAT */
+	{
+		/* Copy the ioc control structure part of ioctl request */
+		if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) {
+			bcmerror = BCME_BADADDR;
+			goto done;
+		}
+
+		/* To differentiate between wl and dhd read 4 more byes */
+		if ((copy_from_user(&ioc.driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t),
+			sizeof(uint)) != 0)) {
+			bcmerror = BCME_BADADDR;
+			goto done;
+		}
+	}
+
+	if (!capable(CAP_NET_ADMIN)) {
+		bcmerror = BCME_EPERM;
+		goto done;
+	}
+
+	/* Take backup of ioc.buf and restore later */
+	ioc_buf_user = ioc.buf;
+
+	if (ioc.len > 0) {
+		/*
+		* some IOVARs in DHD require 32K user memory. So allocate the
+		* maximum local buffer.
+		*
+		* For IOVARS which donot require 32K user memory, dhd_ioctl_process()
+		* takes care of trimming the length to DHD_IOCTL_MAXLEN(16K). So that DHD
+		* will not overflow the buffer size while updating the buffer.
+		*/
+#ifdef DHD_USE_KMEM_CACHE_USERCOPY
+		buflen = MIN(ioc.len, KMEM_CACHE_USERCOPY_MAXLEN_32K-1);
+		if (!(local_buf = KMEM_CACHE_ALLOC_USERCOPY(dhd->pub.osh)))
+#else
+		buflen = MIN(ioc.len, DHD_IOCTL_MAXLEN_32K);
+		if (!(local_buf = MALLOC(dhd->pub.osh, buflen+1)))
+#endif /* DHD_USE_KMEM_CACHE_USERCOPY */
+		{
+			bcmerror = BCME_NOMEM;
+			goto done;
+		}
+
+		if (copy_from_user(local_buf, ioc.buf, buflen)) {
+			bcmerror = BCME_BADADDR;
+			goto done;
+		}
+
+		*((char *)local_buf + buflen) = '\0';
+
+		/* For some platforms accessing userspace memory
+		 * of ioc.buf is causing kernel panic, so to avoid that
+		 * make ioc.buf pointing to kernel space memory local_buf
+		 */
+		ioc.buf = local_buf;
+	}
+
+#if defined(OEM_ANDROID)
+	/* Skip all the non DHD iovars (wl iovars) after f/w hang */
+	if (ioc.driver != DHD_IOCTL_MAGIC && dhd->pub.hang_was_sent) {
+		DHD_TRACE(("%s: HANG was sent up earlier\n", __FUNCTION__));
+		DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(&dhd->pub, DHD_EVENT_TIMEOUT_MS);
+		bcmerror = BCME_DONGLE_DOWN;
+		goto done;
+	}
+#endif /* OEM_ANDROID */
+
+	bcmerror = dhd_ioctl_process(&dhd->pub, ifidx, &ioc, local_buf);
+
+	/* Restore back userspace pointer to ioc.buf */
+	ioc.buf = ioc_buf_user;
+	if (!bcmerror && buflen && local_buf && ioc.buf) {
+		if (copy_to_user(ioc.buf, local_buf, buflen))
+			bcmerror = -EFAULT;
+	}
+
+done:
+	if (local_buf) {
+#ifdef DHD_USE_KMEM_CACHE_USERCOPY
+		KMEM_CACHE_FREE_USERCOPY(dhd->pub.osh, local_buf);
+#else
+		MFREE(dhd->pub.osh, local_buf, buflen+1);
+#endif /* DHD_USE_KMEM_CACHE_USERCOPY */
+	}
+
+	DHD_OS_WAKE_UNLOCK(&dhd->pub);
+
+	return OSL_ERROR(bcmerror);
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+static int
+dhd_siocdevprivate(struct net_device *net, struct ifreq *ifr,
+	void __user *data, int cmd)
+{
+	return dhd_ioctl_entry(net, ifr, cmd);
+}
+#endif /* LINUX_VERSION_CODE >= 5.15.0 */
+
+#if defined(WL_CFG80211) && defined(SUPPORT_DEEP_SLEEP)
+/* Flags to indicate if we distingish power off policy when
+ * user set the memu "Keep Wi-Fi on during sleep" to "Never"
+ */
+int trigger_deep_sleep = 0;
+#endif /* WL_CFG80211 && SUPPORT_DEEP_SLEEP */
+
+#ifdef FIX_CPU_MIN_CLOCK
+static int dhd_init_cpufreq_fix(dhd_info_t *dhd)
+{
+	if (dhd) {
+		mutex_init(&dhd->cpufreq_fix);
+		dhd->cpufreq_fix_status = FALSE;
+	}
+	return 0;
+}
+
+static void dhd_fix_cpu_freq(dhd_info_t *dhd)
+{
+	mutex_lock(&dhd->cpufreq_fix);
+	if (dhd && !dhd->cpufreq_fix_status) {
+		pm_qos_add_request(&dhd->dhd_cpu_qos, PM_QOS_CPU_FREQ_MIN, 300000);
+#ifdef FIX_BUS_MIN_CLOCK
+		pm_qos_add_request(&dhd->dhd_bus_qos, PM_QOS_BUS_THROUGHPUT, 400000);
+#endif /* FIX_BUS_MIN_CLOCK */
+		DHD_ERROR(("pm_qos_add_requests called\n"));
+
+		dhd->cpufreq_fix_status = TRUE;
+	}
+	mutex_unlock(&dhd->cpufreq_fix);
+}
+
+static void dhd_rollback_cpu_freq(dhd_info_t *dhd)
+{
+	mutex_lock(&dhd ->cpufreq_fix);
+	if (dhd && dhd->cpufreq_fix_status != TRUE) {
+		mutex_unlock(&dhd->cpufreq_fix);
+		return;
+	}
+
+	pm_qos_remove_request(&dhd->dhd_cpu_qos);
+#ifdef FIX_BUS_MIN_CLOCK
+	pm_qos_remove_request(&dhd->dhd_bus_qos);
+#endif /* FIX_BUS_MIN_CLOCK */
+	DHD_ERROR(("pm_qos_add_requests called\n"));
+
+	dhd->cpufreq_fix_status = FALSE;
+	mutex_unlock(&dhd->cpufreq_fix);
+}
+#endif /* FIX_CPU_MIN_CLOCK */
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+static int
+dhd_ioctl_entry_wrapper(struct net_device *net, struct ifreq *ifr, int cmd)
+{
+	int error;
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+
+	if (atomic_read(&dhd->pub.block_bus))
+		return -EHOSTDOWN;
+
+	if (pm_runtime_get_sync(dhd_bus_to_dev(dhd->pub.bus)) < 0)
+		return BCME_ERROR;
+
+	error = dhd_ioctl_entry(net, ifr, cmd);
+
+	pm_runtime_mark_last_busy(dhd_bus_to_dev(dhd->pub.bus));
+	pm_runtime_put_autosuspend(dhd_bus_to_dev(dhd->pub.bus));
+
+	return error;
+}
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) && defined(DHD_TCP_LIMIT_OUTPUT)
+void
+dhd_ctrl_tcp_limit_output_bytes(int level)
+{
+	if (level == 0) {
+		init_net.ipv4.sysctl_tcp_limit_output_bytes = TCP_DEFAULT_LIMIT_OUTPUT;
+	} else if (level == 1) {
+		init_net.ipv4.sysctl_tcp_limit_output_bytes = DHD_TCP_LIMIT_OUTPUT_BYTES;
+	}
+}
+#endif /* LINUX_VERSION_CODE > 4.19.0 && DHD_TCP_LIMIT_OUTPUT */
+
+void
+dhd_force_collect_socram_during_wifi_onoff(dhd_pub_t *dhdp)
+{
+#ifdef OEM_ANDROID
+#ifdef DHD_FW_COREDUMP
+	if (dhdp->memdump_enabled && (dhdp->busstate != DHD_BUS_DOWN)) {
+#ifdef DHD_SSSR_DUMP
+		dhdp->collect_sssr = TRUE;
+#endif /* DHD_SSSR_DUMP */
+		dhdp->memdump_type = DUMP_TYPE_DONGLE_TRAP_DURING_WIFI_ONOFF;
+		dhd_bus_mem_dump(dhdp);
+	}
+#endif /* DHD_FW_COREDUMP */
+#endif /* OEM_ANDROID */
+}
+
+int
+dhd_stop(struct net_device *net)
+{
+	int ifidx = 0;
+	bool skip_reset = false;
+#ifdef WL_CFG80211
+	unsigned long flags = 0;
+#ifdef WL_STATIC_IF
+	struct bcm_cfg80211 *cfg = wl_get_cfg(net);
+#endif /* WL_STATIC_IF */
+#endif /* WL_CFG80211 */
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+	int timeleft = 0;
+	uint32 bitmask = (uint32)-1;
+
+	DHD_OS_WAKE_LOCK(&dhd->pub);
+	WL_MSG(net->name, "Enter\n");
+	dhd->pub.rxcnt_timeout = 0;
+	dhd->pub.txcnt_timeout = 0;
+
+#ifdef BCMPCIE
+	dhd->pub.d3ackcnt_timeout = 0;
+#endif /* BCMPCIE */
+
+	/* Synchronize between the stop and rx path */
+	dhd->pub.stop_in_progress = true;
+	OSL_SMP_WMB();
+
+#ifdef DHD_COREDUMP
+	if (DHD_BUS_BUSY_CHECK_IN_HALDUMP(&dhd->pub)) {
+		DHD_ERROR(("%s: Cancel the triggerd HAL dump.\n", __FUNCTION__));
+		DHD_BUS_BUSY_CLEAR_IN_HALDUMP(&dhd->pub);
+	}
+	bitmask = ~(DHD_BUS_BUSY_IN_HALDUMP);
+#endif /* DHD_COREDUMP */
+	timeleft = dhd_os_busbusy_wait_bitmask(&dhd->pub,
+			&dhd->pub.dhd_bus_busy_state,
+			bitmask, 0);
+	if (dhd->pub.dhd_bus_busy_state & bitmask) {
+		DHD_ERROR(("%s: Timed out(%d) dhd_bus_busy_state=0x%x\n",
+				__FUNCTION__, timeleft, dhd->pub.dhd_bus_busy_state));
+	}
+
+	mutex_lock(&dhd->pub.ndev_op_sync);
+	if (dhd->pub.up == 0) {
+		goto exit;
+	}
+#if defined(DHD_HANG_SEND_UP_TEST)
+	if (dhd->pub.req_hang_type) {
+		DHD_ERROR(("%s, Clear HANG test request 0x%x\n",
+			__FUNCTION__, dhd->pub.req_hang_type));
+		dhd->pub.req_hang_type = 0;
+	}
+#endif /* DHD_HANG_SEND_UP_TEST */
+
+#if defined(WLAN_ACCEL_BOOT)
+	if (!dhd->wl_accel_force_reg_on && dhd_query_bus_erros(&dhd->pub)) {
+		DHD_ERROR(("%s: set force reg on\n", __FUNCTION__));
+		dhd->wl_accel_force_reg_on = TRUE;
+	}
+#endif /* WLAN_ACCEL_BOOT */
+
+#ifdef FIX_CPU_MIN_CLOCK
+	if (dhd_get_fw_mode(dhd) == DHD_FLAG_HOSTAP_MODE)
+		dhd_rollback_cpu_freq(dhd);
+#endif /* FIX_CPU_MIN_CLOCK */
+
+	ifidx = dhd_net2idx(dhd, net);
+	BCM_REFERENCE(ifidx);
+
+	DHD_ERROR(("%s: ######### called for ifidx=%d #########\n", __FUNCTION__, ifidx));
+
+#if defined(WL_STATIC_IF) && defined(WL_CFG80211)
+	/* If static if is operational, don't reset the chip */
+	if ((!dhd->pub.hang_was_sent) && (wl_cfg80211_static_if_active(cfg) ||
+		(wl_cfgvif_get_iftype_count(cfg, WL_IF_TYPE_AP)) > 0)) {
+		WL_MSG(net->name, "static if operational. skip chip reset.\n");
+		skip_reset = true;
+		wl_cfg80211_sta_ifdown(net);
+		goto exit;
+	}
+#endif /* WL_STATIC_IF && WL_CFG80211 */
+#ifdef DHD_NOTIFY_MAC_CHANGED
+	if (!dhd->pub.hang_was_sent && dhd->pub.skip_dhd_stop) {
+		WL_MSG(net->name, "skip chip reset.\n");
+		skip_reset = true;
+#if defined(WL_CFG80211)
+		wl_cfg80211_sta_ifdown(net);
+#endif /* WL_CFG80211 */
+		goto exit;
+	}
+#endif /* DHD_NOTIFY_MAC_CHANGED */
+
+#ifdef WL_CFG80211
+	if (ifidx == 0) {
+		dhd_if_t *ifp;
+		wl_cfg80211_down(net);
+
+		DHD_ERROR(("%s: making dhdpub up FALSE\n", __FUNCTION__));
+#ifdef WL_CFG80211
+		/* Disable Runtime PM before interface down */
+		DHD_STOP_RPM_TIMER(&dhd->pub);
+
+		DHD_UP_LOCK(&dhd->pub.up_lock, flags);
+		dhd->pub.up = 0;
+		DHD_UP_UNLOCK(&dhd->pub.up_lock, flags);
+#else
+		dhd->pub.up = 0;
+#endif /* WL_CFG80211 */
+#if defined(BCMPCIE) && defined(CONFIG_ARCH_MSM) && defined(CONFIG_SEC_PCIE_L1SS)
+		dhd_bus_inform_ep_loaded_to_rc(&dhd->pub, dhd->pub.up);
+#endif /* BCMPCIE && CONFIG_ARCH_MSM && CONFIG_SEC_PCIE_L1SS */
+
+		ifp = dhd->iflist[0];
+		/*
+		 * For CFG80211: Clean up all the left over virtual interfaces
+		 * when the primary Interface is brought down. [ifconfig wlan0 down]
+		 */
+		if (!dhd_download_fw_on_driverload) {
+			DHD_STATLOG_CTRL(&dhd->pub, ST(WLAN_POWER_OFF), ifidx, 0);
+			if ((dhd->dhd_state & DHD_ATTACH_STATE_ADD_IF) &&
+				(dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)) {
+				int i;
+#ifdef DHD_4WAYM4_FAIL_DISCONNECT
+				dhd_cleanup_m4_state_work(&dhd->pub, ifidx);
+#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
+#ifdef DHD_PKTDUMP_ROAM
+				dhd_dump_pkt_clear(&dhd->pub);
+#endif /* DHD_PKTDUMP_ROAM */
+
+				dhd_net_if_lock_local(dhd);
+				for (i = 1; i < DHD_MAX_IFS; i++)
+					dhd_remove_if(&dhd->pub, i, FALSE);
+
+				if (ifp && ifp->net) {
+					dhd_if_del_sta_list(ifp);
+				}
+#ifdef ARP_OFFLOAD_SUPPORT
+				if (dhd_inetaddr_notifier_registered) {
+					dhd_inetaddr_notifier_registered = FALSE;
+					unregister_inetaddr_notifier(&dhd_inetaddr_notifier);
+				}
+#endif /* ARP_OFFLOAD_SUPPORT */
+#if defined(CONFIG_IPV6) && defined(IPV6_NDO_SUPPORT)
+				if (dhd_inet6addr_notifier_registered) {
+					dhd_inet6addr_notifier_registered = FALSE;
+					unregister_inet6addr_notifier(&dhd_inet6addr_notifier);
+				}
+#endif /* CONFIG_IPV6 && IPV6_NDO_SUPPORT */
+				dhd_net_if_unlock_local(dhd);
+			}
+#if 0
+			// terence 20161024: remove this to prevent dev_close() get stuck in dhd_hang_process
+			cancel_work_sync(dhd->dhd_deferred_wq);
+#endif
+
+#ifdef SHOW_LOGTRACE
+			/* Wait till event logs work/kthread finishes */
+			dhd_cancel_logtrace_process_sync(dhd);
+#endif /* SHOW_LOGTRACE */
+
+#ifdef EWP_EDL
+			cancel_delayed_work_sync(&dhd->edl_dispatcher_work);
+#endif
+
+#if defined(DHD_LB_RXP)
+			__skb_queue_purge(&dhd->rx_pend_queue);
+			skb_queue_purge(&dhd->rx_emerge_queue);
+#endif /* DHD_LB_RXP */
+
+#if defined(DHD_LB_TXP)
+			skb_queue_purge(&dhd->tx_pend_queue);
+#endif /* DHD_LB_TXP */
+		}
+#ifdef DHDTCPACK_SUPPRESS
+		dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_OFF);
+#endif /* DHDTCPACK_SUPPRESS */
+#if defined(DHD_LB_RXP)
+		if (ifp && ifp->net == dhd->rx_napi_netdev) {
+			DHD_INFO(("%s napi<%p> disabled ifp->net<%p,%s>\n",
+				__FUNCTION__, &dhd->rx_napi_struct, net, net->name));
+			skb_queue_purge(&dhd->rx_napi_queue);
+			napi_disable(&dhd->rx_napi_struct);
+			netif_napi_del(&dhd->rx_napi_struct);
+			dhd->rx_napi_netdev = NULL;
+		}
+#endif /* DHD_LB_RXP */
+	}
+#endif /* WL_CFG80211 */
+
+#ifdef PROP_TXSTATUS
+	dhd_wlfc_cleanup(&dhd->pub, NULL, 0);
+#endif
+#ifdef SHOW_LOGTRACE
+	if (!dhd_download_fw_on_driverload) {
+		/* Release the skbs from queue for WLC_E_TRACE event */
+		dhd_event_logtrace_flush_queue(&dhd->pub);
+		if (dhd->dhd_state & DHD_ATTACH_LOGTRACE_INIT) {
+			if (dhd->event_data.fmts) {
+				MFREE(dhd->pub.osh, dhd->event_data.fmts,
+					dhd->event_data.fmts_size);
+			}
+			if (dhd->event_data.raw_fmts) {
+				MFREE(dhd->pub.osh, dhd->event_data.raw_fmts,
+					dhd->event_data.raw_fmts_size);
+			}
+			if (dhd->event_data.raw_sstr) {
+				MFREE(dhd->pub.osh, dhd->event_data.raw_sstr,
+					dhd->event_data.raw_sstr_size);
+			}
+			if (dhd->event_data.rom_raw_sstr) {
+				MFREE(dhd->pub.osh, dhd->event_data.rom_raw_sstr,
+					dhd->event_data.rom_raw_sstr_size);
+			}
+			dhd->dhd_state &= ~DHD_ATTACH_LOGTRACE_INIT;
+		}
+	}
+#endif /* SHOW_LOGTRACE */
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+	/* Stop all ring buffer */
+	dhd_os_reset_logging(&dhd->pub);
+#endif
+#ifdef DHD_PKT_LOGGING_DBGRING
+	if (dhd_pktlog_ring_reinit(&dhd->pub) != BCME_OK) {
+		DHD_ERROR(("%s: dhd_pktlog_ring_reinit() error.\n", __FUNCTION__));
+	}
+#endif /* DHD_PKT_LOGGING_DBGRING */
+#ifdef APF
+	dhd_dev_apf_delete_filter(net);
+#endif /* APF */
+#ifdef CUSTOM_EVENT_PM_WAKE
+	/* Clear EXCESS_PM_PERIOD explicitly when Wi-Fi turn off */
+	dhd_set_excess_pm_awake(&dhd->pub, FALSE);
+#endif /* CUSTOM_EVENT_PM_WAKE */
+
+	/* Stop the protocol module */
+	dhd_prot_stop(&dhd->pub);
+
+	OLD_MOD_DEC_USE_COUNT;
+exit:
+	if (skip_reset == false) {
+#ifdef WL_ESCAN
+		if (ifidx == 0) {
+			wl_escan_down(net);
+		}
+#endif /* WL_ESCAN */
+		if (ifidx == 0 && !dhd_download_fw_on_driverload) {
+#if defined(WLAN_ACCEL_BOOT)
+			if (dhd->pub.dongle_trap_during_wifi_onoff) {
+				DHD_ERROR(("%s: force collect socram due to trap "
+					"during wifi on/off.\n", __FUNCTION__));
+				dhd_force_collect_socram_during_wifi_onoff(&dhd->pub);
+				dhd->pub.dongle_trap_during_wifi_onoff = 0;
+			}
+
+			wl_android_wifi_accel_off(net, dhd->wl_accel_force_reg_on);
+#else
+#if defined(BT_OVER_SDIO)
+			dhd_bus_put(&dhd->pub, WLAN_MODULE);
+			wl_android_set_wifi_on_flag(FALSE);
+#else
+			wl_android_wifi_off(net, TRUE);
+#ifdef WL_EXT_IAPSTA
+			wl_ext_iapsta_dettach_netdev(net, ifidx);
+#endif /* WL_EXT_IAPSTA */
+#ifdef WL_ESCAN
+			wl_escan_event_dettach(net, ifidx);
+#endif /* WL_ESCAN */
+#ifdef WL_EVENT
+			wl_ext_event_dettach_netdev(net, ifidx);
+#endif /* WL_EVENT */
+#endif /* BT_OVER_SDIO */
+#endif /* WLAN_ACCEL_BOOT */
+		}
+#ifdef SUPPORT_DEEP_SLEEP
+		else {
+			/* CSP#505233: Flags to indicate if we distingish
+			 * power off policy when user set the memu
+			 * "Keep Wi-Fi on during sleep" to "Never"
+			 */
+			if (trigger_deep_sleep) {
+				dhd_deepsleep(net, 1);
+				trigger_deep_sleep = 0;
+			}
+		}
+#endif /* SUPPORT_DEEP_SLEEP */
+		dhd->pub.hang_was_sent = 0;
+		dhd->pub.hang_was_pending = 0;
+
+		/* Clear country spec for for built-in type driver */
+		if (!dhd_download_fw_on_driverload) {
+			dhd->pub.dhd_cspec.country_abbrev[0] = 0x00;
+			dhd->pub.dhd_cspec.rev = 0;
+			dhd->pub.dhd_cspec.ccode[0] = 0x00;
+		}
+
+#ifdef BCMDBGFS
+		dhd_dbgfs_remove();
+#endif
+	}
+
+	DHD_OS_WAKE_UNLOCK(&dhd->pub);
+
+	/* Destroy wakelock */
+	if (!dhd_download_fw_on_driverload &&
+		(dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT) &&
+		(skip_reset == false)) {
+		DHD_OS_WAKE_LOCK_DESTROY(dhd);
+		dhd->dhd_state &= ~DHD_ATTACH_STATE_WAKELOCKS_INIT;
+	}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) && defined(DHD_TCP_LIMIT_OUTPUT)
+	dhd_ctrl_tcp_limit_output_bytes(0);
+#endif /* LINUX_VERSION_CODE > 4.19.0 && DHD_TCP_LIMIT_OUTPUT */
+	WL_MSG(net->name, "Exit\n");
+
+	mutex_unlock(&dhd->pub.ndev_op_sync);
+	/* Clear stop in progress flag */
+	dhd->pub.stop_in_progress = false;
+	return 0;
+}
+
+#if defined(OEM_ANDROID) && defined(WL_CFG80211) && (defined(USE_INITIAL_2G_SCAN) || \
+	defined(USE_INITIAL_SHORT_DWELL_TIME))
+extern bool g_first_broadcast_scan;
+#endif /* OEM_ANDROID && WL_CFG80211 && (USE_INITIAL_2G_SCAN || USE_INITIAL_SHORT_DWELL_TIME) */
+
+#ifdef WL11U
+static int dhd_interworking_enable(dhd_pub_t *dhd)
+{
+	uint32 enable = true;
+	int ret = BCME_OK;
+
+	ret = dhd_iovar(dhd, 0, "interworking", (char *)&enable, sizeof(enable), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: enableing interworking failed, ret=%d\n", __FUNCTION__, ret));
+	}
+
+	return ret;
+}
+#endif /* WL11u */
+
+#if defined(WLAN_ACCEL_BOOT)
+void
+dhd_verify_firmware_mode_change(dhd_info_t *dhd)
+{
+	int current_mode = 0;
+
+	dhd->pub.fw_mode_changed = FALSE;
+
+	DHD_ERROR(("%s: do_chip_bighammer:%d\n", __FUNCTION__, dhd->pub.do_chip_bighammer));
+	/*
+	 * check for the FW change
+	 * previous FW mode - dhd->pub.op_mode remember the previous mode
+	 * current mode - update fw/nv path, get current FW  mode from dhd->fw_path
+	 */
+	dhd_update_fw_nv_path(dhd);
+#ifdef WL_MONITOR
+	DHD_INFO(("%s : check monitor mode with fw_path : %s\n", __FUNCTION__, dhd->fw_path));
+
+	if (strstr(dhd->fw_path, "_mon") != NULL) {
+		DHD_ERROR(("%s : monitor mode is enabled, set force reg on\n", __FUNCTION__));
+		dhd->wl_accel_force_reg_on = TRUE;
+		dhd->pub.fw_mode_changed = TRUE;
+		return;
+	} else if (dhd->pub.monitor_enable == TRUE) {
+		DHD_ERROR(("%s : monitor was enabled, changed to other fw_mode\n", __FUNCTION__));
+		dhd->wl_accel_force_reg_on = TRUE;
+		dhd->pub.fw_mode_changed = TRUE;
+		return;
+	}
+#endif /* WL_MONITOR */
+	current_mode = dhd_get_fw_mode(dhd);
+
+	DHD_ERROR(("%s: current_mode 0x%x, prev_opmode 0x%x\n", __FUNCTION__,
+		current_mode, dhd->pub.op_mode));
+
+	if (!(dhd->pub.op_mode & current_mode)) {
+		DHD_ERROR(("%s: firmware path has changed, set force reg on\n", __FUNCTION__));
+		dhd->wl_accel_force_reg_on = TRUE;
+		dhd->pub.fw_mode_changed = TRUE;
+	}
+}
+#endif /* WLAN_ACCEL_BOOT */
+
+void
+dhd_force_collect_init_fail_dumps(dhd_pub_t *dhdp)
+{
+#ifndef SKIP_FORCE_INIT_DUMP
+#ifdef OEM_ANDROID
+
+#if defined(CUSTOMER_HW7_DEBUG)
+#ifdef DEBUG_DNGL_INIT_FAIL
+	/* As HAL is not inited, do force crash and collect from host dram */
+	dhdp->memdump_enabled = DUMP_MEMONLY;
+#else
+	DHD_ERROR(("%s: As DEBUG_DNGL_INIT_FAIL is not enabled, and HAL not inited,"
+		" cannot collect dumps\n", __FUNCTION__));
+	return;
+#endif /* DEBUG_DNGL_INIT_FAIL */
+#endif /* CUSTOMER_HW7_DEBUG */
+
+#ifdef DHD_FW_COREDUMP
+	/* save core dump or write to a file */
+	if (dhdp->memdump_enabled && (dhdp->busstate != DHD_BUS_DOWN)) {
+#ifdef DHD_SSSR_DUMP
+		if (!dhdp->sssr_inited) {
+			DHD_ERROR(("%s: #### force init SSSR ###\n", __FUNCTION__));
+			dhdp->force_sssr_init = TRUE;
+			/* Hard code sssr_reg_info for 4389 */
+			DHD_SSSR_DUMP_INIT(dhdp);
+			/* force collect FIS */
+			fis_enab = TRUE;
+		}
+		dhdp->collect_sssr = TRUE;
+#endif /* DHD_SSSR_DUMP */
+		dhdp->memdump_type = DUMP_TYPE_DONGLE_INIT_FAILURE;
+		dhd_bus_mem_dump(dhdp);
+	}
+#endif /* DHD_FW_COREDUMP */
+#endif /* OEM_ANDROID */
+#endif /* SKIP_FORCE_INIT_DUMP */
+}
+
+int
+dhd_open(struct net_device *net)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+#ifdef TOE
+	uint32 toe_ol;
+#endif
+	int ifidx;
+	int32 ret = 0;
+#if defined(OOB_INTR_ONLY)
+	uint32 bus_type = -1;
+	uint32 bus_num = -1;
+	uint32 slot_num = -1;
+	wifi_adapter_info_t *adapter = NULL;
+#endif
+#if defined(WL_EXT_IAPSTA) && defined(ISAM_PREINIT)
+	int bytes_written = 0;
+#endif
+
+#if defined(PREVENT_REOPEN_DURING_HANG)
+	/* WAR : to prevent calling dhd_open abnormally in quick succession after hang event */
+	if (dhd->pub.hang_was_sent == 1) {
+		DHD_ERROR(("%s: HANG was sent up earlier\n", __FUNCTION__));
+		/* Force to bring down WLAN interface in case dhd_stop() is not called
+		 * from the upper layer when HANG event is triggered.
+		 */
+		if (!dhd_download_fw_on_driverload && dhd->pub.up == 1) {
+			DHD_ERROR(("%s: WLAN interface is not brought down\n", __FUNCTION__));
+			dhd_stop(net);
+		} else {
+			return -1;
+		}
+	}
+#endif /* PREVENT_REOPEN_DURING_HANG */
+
+	/* clear to run TCM test once per dhd_open() */
+	if (dhd_tcm_test_mode != TCM_TEST_MODE_ONCE) {
+		dhd_tcm_test_status = TCM_TEST_NOT_RUN;
+	}
+
+	mutex_lock(&dhd->pub.ndev_op_sync);
+
+#ifdef SCAN_SUPPRESS
+	wl_ext_reset_scan_busy(&dhd->pub);
+#endif
+
+	if (dhd->pub.up == 1) {
+		/* already up */
+		WL_MSG(net->name, "Primary net_device is already up\n");
+		mutex_unlock(&dhd->pub.ndev_op_sync);
+		return BCME_OK;
+	}
+
+	if (!dhd_download_fw_on_driverload) {
+#if defined(WLAN_ACCEL_BOOT)
+		if (!dhd->wl_accel_force_reg_on && dhd_query_bus_erros(&dhd->pub)) {
+			DHD_ERROR(("%s: set force reg on\n", __FUNCTION__));
+			dhd->wl_accel_force_reg_on = TRUE;
+		}
+		if (!dhd->wl_accel_force_reg_on && !DHD_BUS_BUSY_CHECK_IDLE(&dhd->pub)) {
+			DHD_ERROR(("%s: clear dhd_bus_busy_state: 0x%x\n",
+					__FUNCTION__, dhd->pub.dhd_bus_busy_state));
+			dhd->pub.dhd_bus_busy_state = 0;
+			dhd->wl_accel_force_reg_on = TRUE;
+		}
+#endif /* WLAN_ACCEL_BOOT */
+		if (!dhd_driver_init_done) {
+			DHD_ERROR(("%s: WLAN driver is not initialized\n", __FUNCTION__));
+			mutex_unlock(&dhd->pub.ndev_op_sync);
+			return -1;
+		}
+	}
+
+	WL_MSG(net->name, "Enter\n");
+	DHD_ERROR(("%s\n", dhd_version));
+	if (ANDROID_VERSION > 0)
+		printf("ANDROID_VERSION = %d\n", ANDROID_VERSION);
+	/* Init wakelock */
+	if (!dhd_download_fw_on_driverload) {
+		if (!(dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT)) {
+			DHD_OS_WAKE_LOCK_INIT(dhd);
+			dhd->dhd_state |= DHD_ATTACH_STATE_WAKELOCKS_INIT;
+		}
+
+#ifdef SHOW_LOGTRACE
+		skb_queue_head_init(&dhd->evt_trace_queue);
+
+		if (!(dhd->dhd_state & DHD_ATTACH_LOGTRACE_INIT)) {
+			ret = dhd_init_logstrs_array(dhd->pub.osh, &dhd->event_data);
+			if (ret == BCME_OK) {
+				dhd_init_static_strs_array(dhd->pub.osh, &dhd->event_data,
+					st_str_file_path, map_file_path);
+#ifdef DHD_LOAD_ROML_FILES
+				dhd_init_static_strs_array(dhd->pub.osh, &dhd->event_data,
+					rom_st_str_file_path, rom_map_file_path);
+#endif /* DHD_LOAD_ROML_FILES */
+				dhd->dhd_state |= DHD_ATTACH_LOGTRACE_INIT;
+			}
+		}
+#endif /* SHOW_LOGTRACE */
+	}
+
+	DHD_OS_WAKE_LOCK(&dhd->pub);
+	dhd->pub.dongle_trap_occured = 0;
+	dhd->pub.dsack_hc_due_to_isr_delay = 0;
+	dhd->pub.dsack_hc_due_to_dpc_delay = 0;
+	dhd->pub.dongle_trap_during_wifi_onoff = 0;
+	dhd->pub.hang_was_sent = 0;
+	dhd->pub.hang_was_pending = 0;
+	dhd->pub.hang_reason = 0;
+	dhd->pub.iovar_timeout_occured = 0;
+#ifdef PCIE_FULL_DONGLE
+	dhd->pub.d3ack_timeout_occured = 0;
+	dhd->pub.livelock_occured = 0;
+	dhd->pub.pktid_audit_failed = 0;
+	dhd->pub.pktid_invalid_occured = 0;
+#endif /* PCIE_FULL_DONGLE */
+	dhd->pub.iface_op_failed = 0;
+	dhd->pub.scan_timeout_occurred = 0;
+	dhd->pub.scan_busy_occurred = 0;
+	dhd->pub.p2p_disc_busy_occurred = 0;
+	dhd->pub.smmu_fault_occurred = 0;
+#ifdef DHD_LOSSLESS_ROAMING
+	dhd->pub.dequeue_prec_map = ALLPRIO;
+#endif
+#ifdef DHD_SSSR_DUMP
+	dhd->pub.collect_sssr = FALSE;
+#endif /* DHD_SSSR_DUMP */
+#ifdef DHD_SDTC_ETB_DUMP
+	dhd->pub.collect_sdtc = FALSE;
+#endif /* DHD_SDTC_ETB_DUMP */
+#ifdef DHD_GRO_ENABLE_HOST_CTRL
+	dhd->pub.permitted_gro = TRUE;
+#endif /* DHD_GRO_ENABLE_HOST_CTRL */
+#if defined(DHD_FILE_DUMP_EVENT) && defined(DHD_FW_COREDUMP)
+	dhd_set_dump_status(&dhd->pub, DUMP_NOT_READY);
+#endif /* DHD_FILE_DUMP_EVENT && DHD_FW_COREDUMP */
+
+#if 0
+	/*
+	 * Force start if ifconfig_up gets called before START command
+	 *  We keep WEXT's wl_control_wl_start to provide backward compatibility
+	 *  This should be removed in the future
+	 */
+	ret = wl_control_wl_start(net);
+	if (ret != 0) {
+		DHD_ERROR(("%s: failed with code %d\n", __FUNCTION__, ret));
+		ret = -1;
+		goto exit;
+	}
+
+#endif /* defined(OEM_ANDROID) && !defined(WL_CFG80211) */
+
+	ifidx = dhd_net2idx(dhd, net);
+	DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx));
+
+	if (ifidx < 0) {
+		DHD_ERROR(("%s: Error: called with invalid IF\n", __FUNCTION__));
+		ret = -1;
+		goto exit;
+	}
+
+	if (!dhd->iflist[ifidx]) {
+		DHD_ERROR(("%s: Error: called when IF already deleted\n", __FUNCTION__));
+		ret = -1;
+		goto exit;
+	}
+
+	DHD_ERROR(("%s: ######### called for ifidx=%d #########\n", __FUNCTION__, ifidx));
+
+	dhd->pub.p2p_disc_busy_cnt = 0;
+#if defined(WLAN_ACCEL_BOOT)
+	dhd_verify_firmware_mode_change(dhd);
+#endif /* WLAN_ACCEL_BOOT */
+
+	if (ifidx == 0) {
+		atomic_set(&dhd->pend_8021x_cnt, 0);
+		if (!dhd_download_fw_on_driverload) {
+			DHD_STATLOG_CTRL(&dhd->pub, ST(WLAN_POWER_ON), ifidx, 0);
+#ifdef WL_EVENT
+			wl_ext_event_attach_netdev(net, ifidx, dhd->iflist[ifidx]->bssidx);
+#endif /* WL_EVENT */
+#ifdef WL_ESCAN
+			wl_escan_event_attach(net, ifidx);
+#endif /* WL_ESCAN */
+#ifdef WL_EXT_IAPSTA
+			wl_ext_iapsta_attach_netdev(net, ifidx, dhd->iflist[ifidx]->bssidx);
+#endif /* WL_EXT_IAPSTA */
+#if defined(USE_INITIAL_2G_SCAN) || defined(USE_INITIAL_SHORT_DWELL_TIME)
+			g_first_broadcast_scan = TRUE;
+#endif /* USE_INITIAL_2G_SCAN || USE_INITIAL_SHORT_DWELL_TIME */
+#ifdef SHOW_LOGTRACE
+			/* dhd_cancel_logtrace_process_sync is called in dhd_stop
+			 * for built-in models. Need to start logtrace kthread before
+			 * calling wifi on, because once wifi is on, EDL will be in action
+			 * any moment, and if kthread is not active, FW event logs will
+			 * not be available
+			 */
+			if (dhd_reinit_logtrace_process(dhd) != BCME_OK) {
+				goto exit;
+			}
+#endif /* SHOW_LOGTRACE */
+#if defined(WLAN_ACCEL_BOOT)
+			ret = wl_android_wifi_accel_on(net, dhd->wl_accel_force_reg_on);
+			/* Enable wl_accel_force_reg_on if ON fails, else disable it */
+			if (ret) {
+				dhd->wl_accel_force_reg_on = TRUE;
+			} else {
+				dhd->wl_accel_force_reg_on = FALSE;
+			}
+#else
+#if defined(BT_OVER_SDIO)
+			ret = dhd_bus_get(&dhd->pub, WLAN_MODULE);
+			wl_android_set_wifi_on_flag(TRUE);
+#else
+			ret = wl_android_wifi_on(net);
+#endif /* BT_OVER_SDIO */
+#endif /* WLAN_ACCEL_BOOT */
+			if (ret != 0) {
+				DHD_ERROR(("%s : wl_android_wifi_on failed (%d)\n",
+					__FUNCTION__, ret));
+				/* Set chip big hammer */
+				dhd->pub.do_chip_bighammer = TRUE;
+				ret = -1;
+				goto exit;
+			}
+		}
+#ifdef SUPPORT_DEEP_SLEEP
+		else {
+			/* Flags to indicate if we distingish
+			 * power off policy when user set the memu
+			 * "Keep Wi-Fi on during sleep" to "Never"
+			 */
+			if (trigger_deep_sleep) {
+#if defined(USE_INITIAL_2G_SCAN) || defined(USE_INITIAL_SHORT_DWELL_TIME)
+				g_first_broadcast_scan = TRUE;
+#endif /* USE_INITIAL_2G_SCAN || USE_INITIAL_SHORT_DWELL_TIME */
+				dhd_deepsleep(net, 0);
+				trigger_deep_sleep = 0;
+			}
+		}
+#endif /* SUPPORT_DEEP_SLEEP */
+#ifdef FIX_CPU_MIN_CLOCK
+		if (dhd_get_fw_mode(dhd) == DHD_FLAG_HOSTAP_MODE) {
+			dhd_init_cpufreq_fix(dhd);
+			dhd_fix_cpu_freq(dhd);
+		}
+#endif /* FIX_CPU_MIN_CLOCK */
+#if defined(OOB_INTR_ONLY)
+		if (dhd->pub.conf->dpc_cpucore >= 0) {
+			dhd_bus_get_ids(dhd->pub.bus, &bus_type, &bus_num, &slot_num);
+			adapter = dhd_wifi_platform_get_adapter(bus_type, bus_num, slot_num);
+			if (adapter) {
+				printf("%s: set irq affinity hit %d\n", __FUNCTION__, dhd->pub.conf->dpc_cpucore);
+				irq_set_affinity_hint(adapter->irq_num, cpumask_of(dhd->pub.conf->dpc_cpucore));
+			}
+		}
+#endif
+
+		if (dhd->pub.busstate != DHD_BUS_DATA) {
+#ifdef BCMDBUS
+			dhd_set_path(&dhd->pub);
+			DHD_MUTEX_UNLOCK();
+			wait_event_interruptible_timeout(dhd->adapter->status_event,
+				wifi_get_adapter_status(dhd->adapter, WIFI_STATUS_FW_READY),
+				msecs_to_jiffies(DHD_FW_READY_TIMEOUT));
+			DHD_MUTEX_LOCK();
+			if ((ret = dbus_up(dhd->pub.bus)) != 0) {
+				DHD_ERROR(("%s: failed to dbus_up with code %d\n", __FUNCTION__, ret));
+				goto exit;
+			} else {
+				dhd->pub.busstate = DHD_BUS_DATA;
+			}
+			if ((ret = dhd_sync_with_dongle(&dhd->pub)) < 0) {
+				DHD_ERROR(("%s: failed with code %d\n", __FUNCTION__, ret));
+				goto exit;
+			}
+#else
+			/* try to bring up bus */
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+			if (pm_runtime_get_sync(dhd_bus_to_dev(dhd->pub.bus)) >= 0) {
+				ret = dhd_bus_start(&dhd->pub);
+				pm_runtime_mark_last_busy(dhd_bus_to_dev(dhd->pub.bus));
+				pm_runtime_put_autosuspend(dhd_bus_to_dev(dhd->pub.bus));
+			}
+#else
+			ret = dhd_bus_start(&dhd->pub);
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+			if (ret) {
+				DHD_ERROR(("%s: failed with code %d\n", __FUNCTION__, ret));
+				ret = -1;
+				goto exit;
+			}
+#endif /* !BCMDBUS */
+
+		}
+#ifdef WL_EXT_IAPSTA
+		wl_ext_iapsta_attach_name(net, ifidx);
+#endif
+
+#ifdef BT_OVER_SDIO
+		if (dhd->pub.is_bt_recovery_required) {
+			DHD_ERROR(("%s: Send Hang Notification 2 to BT\n", __FUNCTION__));
+			bcmsdh_btsdio_process_dhd_hang_notification(TRUE);
+		}
+		dhd->pub.is_bt_recovery_required = FALSE;
+#endif
+
+		/* dhd_sync_with_dongle has been called in dhd_bus_start or wl_android_wifi_on */
+		DEV_ADDR_SET(net, dhd->pub.mac.octet);
+		(void)memcpy_s(dhd_linux_get_primary_netdev(&dhd->pub)->perm_addr, ETHER_ADDR_LEN,
+			dhd->pub.mac.octet, ETHER_ADDR_LEN);
+
+#ifdef TOE
+		/* Get current TOE mode from dongle */
+		if (dhd_toe_get(dhd, ifidx, &toe_ol) >= 0 && (toe_ol & TOE_TX_CSUM_OL) != 0) {
+			dhd->iflist[ifidx]->net->features |= NETIF_F_IP_CSUM;
+		} else {
+			dhd->iflist[ifidx]->net->features &= ~NETIF_F_IP_CSUM;
+		}
+#endif /* TOE */
+
+#ifdef DHD_LB
+#ifdef ENABLE_DHD_GRO
+		dhd->iflist[ifidx]->net->features |= NETIF_F_GRO;
+#endif /* ENABLE_DHD_GRO */
+
+#if defined(DHD_LB_RXP)
+		__skb_queue_head_init(&dhd->rx_pend_queue);
+		skb_queue_head_init(&dhd->rx_emerge_queue);
+		if (dhd->rx_napi_netdev == NULL) {
+			dhd->rx_napi_netdev = dhd->iflist[ifidx]->net;
+			memset(&dhd->rx_napi_struct, 0, sizeof(struct napi_struct));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0)
+			netif_napi_add_weight(dhd->rx_napi_netdev, &dhd->rx_napi_struct,
+				dhd_napi_poll, dhd_napi_weight);
+#else
+			netif_napi_add(dhd->rx_napi_netdev, &dhd->rx_napi_struct,
+				dhd_napi_poll, dhd_napi_weight);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 0) */
+			DHD_INFO(("%s napi<%p> enabled ifp->net<%p,%s> dhd_napi_weight: %d\n",
+				__FUNCTION__, &dhd->rx_napi_struct, net,
+				net->name, dhd_napi_weight));
+			napi_enable(&dhd->rx_napi_struct);
+			DHD_INFO(("%s load balance init rx_napi_struct\n", __FUNCTION__));
+			skb_queue_head_init(&dhd->rx_napi_queue);
+			__skb_queue_head_init(&dhd->rx_process_queue);
+		} /* rx_napi_netdev == NULL */
+#endif /* DHD_LB_RXP */
+
+#if defined(DHD_LB_TXP)
+		/* Use the variant that uses locks */
+		skb_queue_head_init(&dhd->tx_pend_queue);
+#endif /* DHD_LB_TXP */
+		dhd->dhd_lb_candidacy_override = FALSE;
+#endif /* DHD_LB */
+		dhd_ndev_upd_features(dhd, net);
+#ifdef DHD_PM_OVERRIDE
+		g_pm_override = FALSE;
+#endif /* DHD_PM_OVERRIDE */
+#if defined(WL_CFG80211)
+		if (unlikely(wl_cfg80211_up(net))) {
+			DHD_ERROR(("%s: failed to bring up cfg80211\n", __FUNCTION__));
+			ret = -1;
+			goto exit;
+		}
+		if (!dhd_download_fw_on_driverload) {
+#ifdef ARP_OFFLOAD_SUPPORT
+			dhd->pend_ipaddr = 0;
+			if (!dhd_inetaddr_notifier_registered) {
+				dhd_inetaddr_notifier_registered = TRUE;
+				register_inetaddr_notifier(&dhd_inetaddr_notifier);
+			}
+#endif /* ARP_OFFLOAD_SUPPORT */
+#if defined(CONFIG_IPV6) && defined(IPV6_NDO_SUPPORT)
+			if (!dhd_inet6addr_notifier_registered) {
+				dhd_inet6addr_notifier_registered = TRUE;
+				register_inet6addr_notifier(&dhd_inet6addr_notifier);
+			}
+#endif /* CONFIG_IPV6 && IPV6_NDO_SUPPORT */
+		}
+
+#if defined(DHD_CONTROL_PCIE_ASPM_WIFI_TURNON)
+		dhd_bus_aspm_enable_rc_ep(dhd->pub.bus, TRUE);
+#endif /* DHD_CONTROL_PCIE_ASPM_WIFI_TURNON */
+#if defined(DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON)
+		dhd_irq_set_affinity(&dhd->pub, cpumask_of(0));
+#endif /* DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */
+#if defined(NUM_SCB_MAX_PROBE)
+		dhd_set_scb_probe(&dhd->pub);
+#endif /* NUM_SCB_MAX_PROBE */
+#endif /* WL_CFG80211 */
+#ifdef WL_ESCAN
+		if (unlikely(wl_escan_up(net))) {
+			DHD_ERROR(("%s: failed to bring up escan\n", __FUNCTION__));
+			ret = -1;
+			goto exit;
+		}
+#endif /* WL_ESCAN */
+#if defined(ISAM_PREINIT)
+		if (!dhd_download_fw_on_driverload) {
+			if (dhd->pub.conf) {
+				wl_android_ext_priv_cmd(net, dhd->pub.conf->isam_init, 0, &bytes_written);
+				wl_android_ext_priv_cmd(net, dhd->pub.conf->isam_config, 0, &bytes_written);
+				wl_android_ext_priv_cmd(net, dhd->pub.conf->isam_enable, 0, &bytes_written);
+			}
+		}
+#endif
+	}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) && defined(DHD_TCP_LIMIT_OUTPUT)
+	dhd_ctrl_tcp_limit_output_bytes(1);
+#endif /* LINUX_VERSION_CODE > 4.19.0 && DHD_TCP_LIMIT_OUTPUT */
+
+	dhd->pub.up = 1;
+#if defined(BCMPCIE) && defined(CONFIG_ARCH_MSM) && defined(CONFIG_SEC_PCIE_L1SS)
+	dhd_bus_inform_ep_loaded_to_rc(&dhd->pub, dhd->pub.up);
+#endif /* BCMPCIE && CONFIG_ARCH_MSM  && CONFIG_SEC_PCIE_L1SS */
+	DHD_START_RPM_TIMER(&dhd->pub);
+
+	if (wl_event_enable) {
+		/* For wl utility to receive events */
+		dhd->pub.wl_event_enabled = true;
+	} else {
+		dhd->pub.wl_event_enabled = false;
+	}
+
+	if (logtrace_pkt_sendup) {
+		/* For any deamon to recieve logtrace */
+		dhd->pub.logtrace_pkt_sendup = true;
+	} else {
+		dhd->pub.logtrace_pkt_sendup = false;
+	}
+
+	OLD_MOD_INC_USE_COUNT;
+
+#ifdef BCMDBGFS
+	dhd_dbgfs_init(&dhd->pub);
+#endif
+
+exit:
+	mutex_unlock(&dhd->pub.ndev_op_sync);
+
+	if (dhd_query_bus_erros(&dhd->pub)) {
+		ret = BCME_ERROR;
+	}
+
+	if (ret) {
+		if (ret != BCME_NOMEM) {
+			dhd_force_collect_init_fail_dumps(&dhd->pub);
+		} else {
+			DHD_ERROR(("%s: skip collect dump in case of BCME_NOMEM\n",
+					__FUNCTION__));
+			ret = BCME_ERROR;
+		}
+		dhd_stop(net);
+	} else {
+#if defined(ENABLE_INSMOD_NO_FW_LOAD) && defined(NO_POWER_OFF_AFTER_OPEN)
+		dhd_download_fw_on_driverload = TRUE;
+		dhd_driver_init_done = TRUE;
+#elif defined(ENABLE_INSMOD_NO_FW_LOAD) && defined(ENABLE_INSMOD_NO_POWER_OFF)
+		dhd_download_fw_on_driverload = FALSE;
+		dhd_driver_init_done = TRUE;
+#endif
+	}
+
+	DHD_OS_WAKE_UNLOCK(&dhd->pub);
+
+#if defined(SUPPORT_OTA_UPDATE) && defined(WLAN_ACCEL_BOOT)
+	if (ret == BCME_OK) {
+		(void)dhd_ota_buf_clean(&dhd->pub);
+	}
+#endif /* SUPPORT_OTA_UPDATE  && WLAN_ACCEL_BOOT */
+	WL_MSG(net->name, "Exit ret=%d\n", ret);
+	return ret;
+}
+
+/*
+ * ndo_start handler for primary ndev
+ */
+static int
+dhd_pri_open(struct net_device *net)
+{
+	s32 ret;
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+
+	DHD_MUTEX_IS_LOCK_RETURN();
+	DHD_MUTEX_LOCK();
+	BCM_REFERENCE(dhd);
+	ret = dhd_open(net);
+	if (unlikely(ret)) {
+		DHD_ERROR(("Failed to open primary dev ret %d\n", ret));
+		DHD_MUTEX_UNLOCK();
+		return ret;
+	}
+
+#ifdef WL_CFG80211_MONITOR
+	dhd_net_if_lock_local(dhd);
+	/* Add monitor */
+	dhd_add_monitor_if(dhd);
+	dhd_net_if_unlock_local(dhd);
+#endif /* WL_CFG80211_MONITOR */
+
+	/* Allow transmit calls */
+	dhd_tx_start_queues(net);
+	WL_MSG(net->name, "tx queue started\n");
+
+#if defined(SET_RPS_CPUS)
+	dhd_rps_cpus_enable(net, TRUE);
+#endif
+
+#if defined(SET_XPS_CPUS)
+	dhd_xps_cpus_enable(net, TRUE);
+#endif
+	DHD_MUTEX_UNLOCK();
+
+	return ret;
+}
+
+/*
+ * ndo_stop handler for primary ndev
+ */
+static int
+dhd_pri_stop(struct net_device *net)
+{
+	s32 ret;
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+
+	BCM_REFERENCE(dhd);
+	/* Set state and stop OS transmissions */
+	dhd_tx_stop_queues(net);
+	WL_MSG(net->name, "tx queue stopped\n");
+
+#ifdef WL_CFG80211_MONITOR
+	dhd_net_if_lock_local(dhd);
+	/* Del monitor */
+	dhd_del_monitor_if(dhd);
+	dhd_net_if_unlock_local(dhd);
+#endif /* WL_CFG80211_MONITOR */
+
+	ret = dhd_stop(net);
+	if (unlikely(ret)) {
+		DHD_ERROR(("dhd_stop failed: %d\n", ret));
+		return ret;
+	}
+
+	return ret;
+}
+
+#ifdef PCIE_INB_DW
+bool
+dhd_check_cfg_in_progress(dhd_pub_t *dhdp)
+{
+#if defined(WL_CFG80211)
+	return wl_cfg80211_check_in_progress(dhd_linux_get_primary_netdev(dhdp));
+#endif /* WL_CFG80211 */
+	return FALSE;
+}
+#endif
+
+#if defined(WL_STATIC_IF) && defined(WL_CFG80211)
+/*
+ * For static I/Fs, the firmware interface init
+ * is done from the IFF_UP context.
+ */
+static int
+dhd_static_if_open(struct net_device *net)
+{
+	s32 ret = 0;
+	struct bcm_cfg80211 *cfg;
+	struct net_device *primary_netdev = NULL;
+#ifdef WLEASYMESH
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+#endif /* WLEASYMESH */
+
+	DHD_MUTEX_LOCK();
+	cfg = wl_get_cfg(net);
+	primary_netdev = bcmcfg_to_prmry_ndev(cfg);
+
+	if (!wl_cfg80211_static_if(cfg, net)) {
+		WL_MSG(net->name, "non-static interface ..do nothing\n");
+		ret = BCME_OK;
+		goto done;
+	}
+
+	WL_MSG(net->name, "Enter\n");
+	/* Ensure fw is initialized. If it is already initialized,
+	 * dhd_open will return success.
+	 */
+#ifdef WLEASYMESH
+	WL_MSG(net->name, "switch to EasyMesh fw\n");
+	dhd->pub.conf->fw_type = FW_TYPE_EZMESH;
+	ret = dhd_stop(primary_netdev);
+	if (unlikely(ret)) {
+		printf("===>%s, Failed to close primary dev ret %d\n", __FUNCTION__, ret);
+		goto done;
+	}
+	OSL_SLEEP(1);
+#endif /* WLEASYMESH */
+	ret = dhd_open(primary_netdev);
+	if (unlikely(ret)) {
+		DHD_ERROR(("Failed to open primary dev ret %d\n", ret));
+		goto done;
+	}
+
+	ret = wl_cfg80211_static_if_open(net);
+	if (ret == BCME_OK) {
+		/* Allow transmit calls */
+		netif_start_queue(net);
+	}
+	dhd_clear_del_in_progress(cfg->pub, net);
+done:
+	WL_MSG(net->name, "Exit ret=%d\n", ret);
+	DHD_MUTEX_UNLOCK();
+	return ret;
+}
+
+static int
+dhd_static_if_stop(struct net_device *net)
+{
+	struct bcm_cfg80211 *cfg;
+	struct net_device *primary_netdev = NULL;
+	int ret = BCME_OK;
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+
+	WL_MSG(net->name, "Enter\n");
+
+	cfg = wl_get_cfg(net);
+	if (!wl_cfg80211_static_if(cfg, net)) {
+		DHD_TRACE(("non-static interface (%s)..do nothing \n", net->name));
+		return BCME_OK;
+	}
+#ifdef DHD_NOTIFY_MAC_CHANGED
+	if (dhd->pub.skip_dhd_stop) {
+		WL_MSG(net->name, "Exit skip stop\n");
+		return BCME_OK;
+	}
+#endif /* DHD_NOTIFY_MAC_CHANGED */
+
+	dhd_set_del_in_progress(cfg->pub, net);
+	/* Ensure queue is disabled */
+	netif_tx_disable(net);
+
+	dhd_net_if_lock_local(dhd);
+	ret = wl_cfg80211_static_if_close(net);
+	dhd_net_if_unlock_local(dhd);
+
+	if (dhd->pub.up == 0) {
+		/* If fw is down, return */
+		DHD_ERROR(("fw down\n"));
+		return BCME_OK;
+	}
+	/* If STA iface is not in operational, invoke dhd_close from this
+	* context.
+	*/
+	primary_netdev = bcmcfg_to_prmry_ndev(cfg);
+#ifdef WLEASYMESH
+	if (dhd->pub.conf->fw_type == FW_TYPE_EZMESH) {
+		WL_MSG(net->name, "switch to STA fw\n");
+		dhd->pub.conf->fw_type = FW_TYPE_STA;
+	} else
+#endif /* WLEASYMESH */
+	if (!(primary_netdev->flags & IFF_UP)) {
+		ret = dhd_stop(primary_netdev);
+	} else {
+		DHD_ERROR(("Skipped dhd_stop, as sta is operational\n"));
+	}
+	WL_MSG(net->name, "Exit ret=%d\n", ret);
+
+	return ret;
+}
+#endif /* WL_STATIC_IF && WL_CF80211 */
+
+int dhd_do_driver_init(struct net_device *net)
+{
+	dhd_info_t *dhd = NULL;
+	int ret = 0;
+
+	if (!net) {
+		DHD_ERROR(("Primary Interface not initialized \n"));
+		return -EINVAL;
+	}
+
+	DHD_MUTEX_IS_LOCK_RETURN();
+	DHD_MUTEX_LOCK();
+
+	/*  && defined(OEM_ANDROID) && defined(BCMSDIO) */
+	dhd = DHD_DEV_INFO(net);
+
+	/* If driver is already initialized, do nothing
+	 */
+	if (dhd->pub.busstate == DHD_BUS_DATA) {
+		DHD_TRACE(("Driver already Inititalized. Nothing to do"));
+		goto exit;
+	}
+
+	if (dhd_open(net) < 0) {
+		DHD_ERROR(("Driver Init Failed \n"));
+		ret = -1;
+		goto exit;
+	}
+
+exit:
+	DHD_MUTEX_UNLOCK();
+	return ret;
+}
+
+int
+dhd_event_ifadd(dhd_info_t *dhdinfo, wl_event_data_if_t *ifevent, char *name, uint8 *mac)
+{
+
+#ifdef WL_CFG80211
+		if (wl_cfg80211_notify_ifadd(dhd_linux_get_primary_netdev(&dhdinfo->pub),
+			ifevent->ifidx, name, mac, ifevent->bssidx, ifevent->role) == BCME_OK)
+		return BCME_OK;
+#endif
+
+	/* handle IF event caused by wl commands, SoftAP, WEXT and
+	 * anything else. This has to be done asynchronously otherwise
+	 * DPC will be blocked (and iovars will timeout as DPC has no chance
+	 * to read the response back)
+	 */
+	if (ifevent->ifidx > 0) {
+		dhd_if_event_t *if_event = MALLOC(dhdinfo->pub.osh, sizeof(dhd_if_event_t));
+		if (if_event == NULL) {
+			DHD_ERROR(("dhd_event_ifadd: Failed MALLOC, malloced %d bytes",
+				MALLOCED(dhdinfo->pub.osh)));
+			return BCME_NOMEM;
+		}
+
+		memcpy(&if_event->event, ifevent, sizeof(if_event->event));
+		memcpy(if_event->mac, mac, ETHER_ADDR_LEN);
+		strlcpy(if_event->name, name, sizeof(if_event->name));
+		dhd_deferred_schedule_work(dhdinfo->dhd_deferred_wq, (void *)if_event,
+			DHD_WQ_WORK_IF_ADD, dhd_ifadd_event_handler, DHD_WQ_WORK_PRIORITY_LOW);
+	}
+
+	return BCME_OK;
+}
+
+int
+dhd_event_ifdel(dhd_info_t *dhdinfo, wl_event_data_if_t *ifevent, char *name, uint8 *mac)
+{
+	dhd_if_event_t *if_event;
+
+#ifdef WL_CFG80211
+		if (wl_cfg80211_notify_ifdel(dhd_linux_get_primary_netdev(&dhdinfo->pub),
+			ifevent->ifidx, name, mac, ifevent->bssidx) == BCME_OK)
+		return BCME_OK;
+#endif /* WL_CFG80211 */
+
+	/* handle IF event caused by wl commands, SoftAP, WEXT and
+	 * anything else
+	 */
+	if_event = MALLOC(dhdinfo->pub.osh, sizeof(dhd_if_event_t));
+	if (if_event == NULL) {
+		DHD_ERROR(("dhd_event_ifdel: malloc failed for if_event, malloced %d bytes",
+			MALLOCED(dhdinfo->pub.osh)));
+		return BCME_NOMEM;
+	}
+	memcpy(&if_event->event, ifevent, sizeof(if_event->event));
+	memcpy(if_event->mac, mac, ETHER_ADDR_LEN);
+	strlcpy(if_event->name, name, sizeof(if_event->name));
+	dhd_deferred_schedule_work(dhdinfo->dhd_deferred_wq, (void *)if_event, DHD_WQ_WORK_IF_DEL,
+		dhd_ifdel_event_handler, DHD_WQ_WORK_PRIORITY_LOW);
+
+	return BCME_OK;
+}
+
+int
+dhd_event_ifchange(dhd_info_t *dhdinfo, wl_event_data_if_t *ifevent, char *name, uint8 *mac)
+{
+#ifdef DHD_UPDATE_INTF_MAC
+	dhd_if_event_t *if_event;
+#endif /* DHD_UPDATE_INTF_MAC */
+
+#ifdef WL_CFG80211
+	wl_cfg80211_notify_ifchange(dhd_linux_get_primary_netdev(&dhdinfo->pub),
+		ifevent->ifidx, name, mac, ifevent->bssidx);
+#endif /* WL_CFG80211 */
+
+#ifdef DHD_UPDATE_INTF_MAC
+	/* handle IF event caused by wl commands, SoftAP, WEXT, MBSS and
+	 * anything else
+	 */
+	if_event = MALLOC(dhdinfo->pub.osh, sizeof(dhd_if_event_t));
+	if (if_event == NULL) {
+		DHD_ERROR(("dhd_event_ifdel: malloc failed for if_event, malloced %d bytes",
+			MALLOCED(dhdinfo->pub.osh)));
+		return BCME_NOMEM;
+	}
+	memcpy(&if_event->event, ifevent, sizeof(if_event->event));
+	// construct a change event
+	if_event->event.ifidx = dhd_ifname2idx(dhdinfo, name);
+	if_event->event.opcode = WLC_E_IF_CHANGE;
+	memcpy(if_event->mac, mac, ETHER_ADDR_LEN);
+	strncpy(if_event->name, name, IFNAMSIZ);
+	if_event->name[IFNAMSIZ - 1] = '\0';
+	dhd_deferred_schedule_work(dhdinfo->dhd_deferred_wq, (void *)if_event, DHD_WQ_WORK_IF_UPDATE,
+		dhd_ifupdate_event_handler, DHD_WQ_WORK_PRIORITY_LOW);
+#endif /* DHD_UPDATE_INTF_MAC */
+
+	return BCME_OK;
+}
+
+/* This API maps ndev to ifp inclusive of static IFs */
+static dhd_if_t *
+dhd_get_ifp_by_ndev(dhd_pub_t *dhdp, struct net_device *ndev)
+{
+	dhd_if_t *ifp = NULL;
+#ifdef WL_STATIC_IF
+	u32 ifidx = (DHD_MAX_IFS + DHD_MAX_STATIC_IFS - 1);
+#else
+	u32 ifidx = (DHD_MAX_IFS - 1);
+#endif /* WL_STATIC_IF */
+
+	dhd_info_t *dhdinfo = (dhd_info_t *)dhdp->info;
+	do {
+		ifp = dhdinfo->iflist[ifidx];
+		if (ifp && (ifp->net == ndev)) {
+			DHD_TRACE(("match found for %s. ifidx:%d\n",
+				ndev->name, ifidx));
+			return ifp;
+		}
+	} while (ifidx--);
+
+	DHD_ERROR(("no entry found for %s\n", ndev->name));
+	return NULL;
+}
+
+bool
+dhd_is_static_ndev(dhd_pub_t *dhdp, struct net_device *ndev)
+{
+	dhd_if_t *ifp = NULL;
+
+	if (!dhdp || !ndev) {
+		DHD_ERROR(("wrong input\n"));
+		ASSERT(0);
+		return false;
+	}
+
+	ifp = dhd_get_ifp_by_ndev(dhdp, ndev);
+	return (ifp && (ifp->static_if == true));
+}
+
+#ifdef WL_STATIC_IF
+/* In some cases, while registering I/F, the actual ifidx, bssidx and dngl_name
+ * are not known. For e.g: static i/f case. This function lets to update it once
+ * it is known.
+ */
+s32
+dhd_update_iflist_info(dhd_pub_t *dhdp, struct net_device *ndev, int ifidx,
+	uint8 *mac, uint8 bssidx, const char *dngl_name, int if_state)
+{
+	dhd_info_t *dhdinfo = (dhd_info_t *)dhdp->info;
+	dhd_if_t *ifp, *ifp_new;
+	s32 cur_idx;
+	dhd_dev_priv_t * dev_priv;
+
+	DHD_TRACE(("[STATIC_IF] update ifinfo for state:%d ifidx:%d\n",
+			if_state, ifidx));
+
+	ASSERT(dhdinfo && (ifidx < (DHD_MAX_IFS + DHD_MAX_STATIC_IFS)));
+	if (ifidx < 0 || ifidx >= (DHD_MAX_IFS + DHD_MAX_STATIC_IFS)) {
+		return -EINVAL;
+	}
+
+	if ((ifp = dhd_get_ifp_by_ndev(dhdp, ndev)) == NULL) {
+		return -ENODEV;
+	}
+	cur_idx = ifp->idx;
+
+	if (if_state == NDEV_STATE_OS_IF_CREATED) {
+		/* mark static if */
+		ifp->static_if = TRUE;
+		return BCME_OK;
+	}
+
+	ifp_new = dhdinfo->iflist[ifidx];
+	if (ifp_new && (ifp_new != ifp)) {
+		/* There should be only one entry for a given ifidx. */
+		DHD_ERROR(("ifp ptr already present for ifidx:%d\n", ifidx));
+		ASSERT(0);
+		dhdp->hang_reason = HANG_REASON_IFACE_ADD_FAILURE;
+#ifdef OEM_ANDROID
+		net_os_send_hang_message(ifp->net);
+#endif /* OEM_ANDROID */
+		return -EINVAL;
+	}
+
+	/* For static if delete case, cleanup the if before ifidx update */
+	if ((if_state == NDEV_STATE_FW_IF_DELETED) ||
+		(if_state == NDEV_STATE_FW_IF_FAILED)) {
+		dhd_cleanup_if(ifp->net);
+		dev_priv = DHD_DEV_PRIV(ndev);
+		dev_priv->ifidx = ifidx;
+	}
+
+	/* update the iflist ifidx slot with cached info */
+	dhdinfo->iflist[ifidx] = ifp;
+	dhdinfo->iflist[cur_idx] = NULL;
+
+	/* update the values */
+	ifp->idx = ifidx;
+	ifp->bssidx = bssidx;
+
+	if (if_state == NDEV_STATE_FW_IF_CREATED) {
+		dhd_dev_priv_save(ndev, dhdinfo, ifp, ifidx);
+		/* initialize the dongle provided if name */
+		if (dngl_name) {
+			strncpy(ifp->dngl_name, dngl_name, IFNAMSIZ);
+		} else if (ndev->name[0] != '\0') {
+			strncpy(ifp->dngl_name, ndev->name, IFNAMSIZ);
+		}
+		if (mac != NULL && ifp->set_macaddress == FALSE) {
+			/* To and fro locations have same size - ETHER_ADDR_LEN */
+			(void)memcpy_s(&ifp->mac_addr, ETHER_ADDR_LEN, mac, ETHER_ADDR_LEN);
+		}
+#ifdef WL_EVENT
+		wl_ext_event_attach_netdev(ndev, ifidx, bssidx);
+#endif /* WL_EVENT */
+#ifdef WL_ESCAN
+		wl_escan_event_attach(ndev, ifidx);
+#endif /* WL_ESCAN */
+#ifdef WL_EXT_IAPSTA
+		wl_ext_iapsta_ifadding(ndev, ifidx);
+		wl_ext_iapsta_attach_netdev(ndev, ifidx, bssidx);
+		wl_ext_iapsta_attach_name(ndev, ifidx);
+#endif /* WL_EXT_IAPSTA */
+	}
+	else if (if_state == NDEV_STATE_FW_IF_DELETED) {
+#ifdef WL_EXT_IAPSTA
+		wl_ext_iapsta_dettach_netdev(ndev, cur_idx);
+#endif /* WL_EXT_IAPSTA */
+#ifdef WL_ESCAN
+		wl_escan_event_dettach(ndev, cur_idx);
+#endif /* WL_ESCAN */
+#ifdef WL_EVENT
+		wl_ext_event_dettach_netdev(ndev, cur_idx);
+#endif /* WL_EVENT */
+	}
+	DHD_INFO(("[STATIC_IF] ifp ptr updated for ifidx:%d curidx:%d if_state:%d\n",
+		ifidx, cur_idx, if_state));
+	return BCME_OK;
+}
+#endif /* WL_STATIC_IF */
+
+/* unregister and free the existing net_device interface (if any) in iflist and
+ * allocate a new one. the slot is reused. this function does NOT register the
+ * new interface to linux kernel. dhd_register_if does the job
+ */
+struct net_device*
+dhd_allocate_if(dhd_pub_t *dhdpub, int ifidx, const char *name,
+	uint8 *mac, uint8 bssidx, bool need_rtnl_lock, const char *dngl_name)
+{
+	dhd_info_t *dhdinfo = (dhd_info_t *)dhdpub->info;
+	dhd_if_t *ifp;
+
+	ASSERT(dhdinfo && (ifidx < (DHD_MAX_IFS + DHD_MAX_STATIC_IFS)));
+	if (!dhdinfo || ifidx < 0 || ifidx >= (DHD_MAX_IFS + DHD_MAX_STATIC_IFS)) {
+		return NULL;
+	}
+
+	ifp = dhdinfo->iflist[ifidx];
+
+	if (ifp != NULL) {
+		if (ifp->net != NULL) {
+			DHD_ERROR(("%s: free existing IF %s ifidx:%d \n",
+				__FUNCTION__, ifp->net->name, ifidx));
+
+			if (ifidx == 0) {
+				/* For primary ifidx (0), there shouldn't be
+				 * any netdev present already.
+				 */
+				DHD_ERROR(("Primary ifidx populated already\n"));
+				ASSERT(0);
+				return NULL;
+			}
+
+			dhd_dev_priv_clear(ifp->net); /* clear net_device private */
+
+			/* in unregister_netdev case, the interface gets freed by net->destructor
+			 * (which is set to free_netdev)
+			 */
+#if defined(CONFIG_TIZEN)
+			net_stat_tizen_unregister(ifp->net);
+#endif /* CONFIG_TIZEN */
+			if (ifp->net->reg_state == NETREG_UNINITIALIZED) {
+				free_netdev(ifp->net);
+			} else {
+				dhd_tx_stop_queues(ifp->net);
+				dhd_unregister_net(ifp->net, need_rtnl_lock);
+			}
+			ifp->net = NULL;
+		}
+	} else {
+		ifp = MALLOC(dhdinfo->pub.osh, sizeof(dhd_if_t));
+		if (ifp == NULL) {
+			DHD_ERROR(("%s: OOM - dhd_if_t(%zu)\n", __FUNCTION__, sizeof(dhd_if_t)));
+			return NULL;
+		}
+	}
+
+	memset(ifp, 0, sizeof(dhd_if_t));
+	ifp->info = dhdinfo;
+	ifp->idx = ifidx;
+	ifp->bssidx = bssidx;
+	ifp->del_in_progress = FALSE;
+#ifdef DHD_MCAST_REGEN
+	ifp->mcast_regen_bss_enable = FALSE;
+#endif
+	/* set to TRUE rx_pkt_chainable at alloc time */
+	ifp->rx_pkt_chainable = TRUE;
+
+	if (mac != NULL)
+		memcpy(&ifp->mac_addr, mac, ETHER_ADDR_LEN);
+
+	/* Allocate etherdev, including space for private structure */
+#ifdef DHD_MQ
+	if (enable_mq) {
+		ifp->net = alloc_etherdev_mq(DHD_DEV_PRIV_SIZE, MQ_MAX_QUEUES);
+	} else {
+		ifp->net = alloc_etherdev(DHD_DEV_PRIV_SIZE);
+	}
+#else
+	ifp->net = alloc_etherdev(DHD_DEV_PRIV_SIZE);
+#endif /* DHD_MQ */
+
+	if (ifp->net == NULL) {
+		DHD_ERROR(("%s: OOM - alloc_etherdev(%zu)\n", __FUNCTION__, sizeof(dhdinfo)));
+		goto fail;
+	}
+
+	/* Setup the dhd interface's netdevice private structure. */
+	dhd_dev_priv_save(ifp->net, dhdinfo, ifp, ifidx);
+
+	if (name && name[0]) {
+		strlcpy(ifp->net->name, name, IFNAMSIZ);
+	}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 9))
+	/* as priv_destructor calls free_netdev, no need to set need_free_netdev */
+	ifp->net->needs_free_netdev = 0;
+#ifdef WL_CFG80211
+	if (ifidx == 0)
+		ifp->net->priv_destructor = free_netdev;
+	else
+		ifp->net->priv_destructor = dhd_netdev_free;
+#else
+	ifp->net->priv_destructor = free_netdev;
+#endif /* WL_CFG80211 */
+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 9) */
+#ifdef WL_CFG80211
+	if (ifidx == 0)
+		ifp->net->destructor = free_netdev;
+	else
+		ifp->net->destructor = dhd_netdev_free;
+#else
+	ifp->net->destructor = free_netdev;
+#endif /* WL_CFG80211 */
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 9) */
+	strlcpy(ifp->name, ifp->net->name, sizeof(ifp->name));
+	dhdinfo->iflist[ifidx] = ifp;
+
+/* initialize the dongle provided if name */
+	if (dngl_name) {
+		strlcpy(ifp->dngl_name, dngl_name, sizeof(ifp->dngl_name));
+	} else if (name) {
+		strlcpy(ifp->dngl_name, name, sizeof(ifp->dngl_name));
+	}
+
+#ifdef PCIE_FULL_DONGLE
+	/* Initialize STA info list */
+	INIT_LIST_HEAD(&ifp->sta_list);
+	DHD_IF_STA_LIST_LOCK_INIT(&ifp->sta_list_lock);
+#endif /* PCIE_FULL_DONGLE */
+
+#ifdef DHD_L2_FILTER
+	ifp->phnd_arp_table = init_l2_filter_arp_table(dhdpub->osh);
+	ifp->parp_allnode = TRUE;
+#endif /* DHD_L2_FILTER */
+
+#if (defined(BCM_ROUTER_DHD) && defined(QOS_MAP_SET))
+	ifp->qosmap_up_table = ((uint8*)MALLOCZ(dhdpub->osh, UP_TABLE_MAX));
+	ifp->qosmap_up_table_enable = FALSE;
+#endif /* BCM_ROUTER_DHD && QOS_MAP_SET */
+
+	DHD_CUMM_CTR_INIT(&ifp->cumm_ctr);
+
+#ifdef DHD_4WAYM4_FAIL_DISCONNECT
+	INIT_DELAYED_WORK(&ifp->m4state_work, dhd_m4_state_handler);
+#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
+
+#ifdef DHD_POST_EAPOL_M1_AFTER_ROAM_EVT
+	ifp->recv_reassoc_evt = FALSE;
+	ifp->post_roam_evt = FALSE;
+#endif /* DHD_POST_EAPOL_M1_AFTER_ROAM_EVT */
+
+#ifdef DHDTCPSYNC_FLOOD_BLK
+	INIT_WORK(&ifp->blk_tsfl_work, dhd_blk_tsfl_handler);
+	dhd_reset_tcpsync_info_by_ifp(ifp);
+#endif /* DHDTCPSYNC_FLOOD_BLK */
+
+	return ifp->net;
+
+fail:
+	if (ifp != NULL) {
+		if (ifp->net != NULL) {
+#if defined(DHD_LB_RXP) && defined(PCIE_FULL_DONGLE)
+			if (ifp->net == dhdinfo->rx_napi_netdev) {
+				napi_disable(&dhdinfo->rx_napi_struct);
+				netif_napi_del(&dhdinfo->rx_napi_struct);
+				skb_queue_purge(&dhdinfo->rx_napi_queue);
+				dhdinfo->rx_napi_netdev = NULL;
+			}
+#endif /* DHD_LB_RXP && PCIE_FULL_DONGLE */
+			dhd_dev_priv_clear(ifp->net);
+			free_netdev(ifp->net);
+			ifp->net = NULL;
+		}
+		MFREE(dhdinfo->pub.osh, ifp, sizeof(*ifp));
+	}
+	dhdinfo->iflist[ifidx] = NULL;
+	return NULL;
+}
+
+static void
+dhd_cleanup_ifp(dhd_pub_t *dhdp, dhd_if_t *ifp)
+{
+#ifdef PCIE_FULL_DONGLE
+	s32 ifidx = 0;
+	if_flow_lkup_t *if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup;
+#endif /* PCIE_FULL_DONGLE */
+
+	if (ifp != NULL) {
+		if ((ifp->idx < 0) || (ifp->idx >= DHD_MAX_IFS)) {
+			DHD_ERROR(("Wrong idx:%d \n", ifp->idx));
+			ASSERT(0);
+			return;
+		}
+#ifdef DHD_L2_FILTER
+		bcm_l2_filter_arp_table_update(dhdpub->osh, ifp->phnd_arp_table, TRUE,
+			NULL, FALSE, dhdpub->tickcnt);
+		deinit_l2_filter_arp_table(dhdpub->osh, ifp->phnd_arp_table);
+		ifp->phnd_arp_table = NULL;
+#endif /* DHD_L2_FILTER */
+
+#if (defined(BCM_ROUTER_DHD) && defined(QOS_MAP_SET))
+		MFREE(dhdpub->osh, ifp->qosmap_up_table, UP_TABLE_MAX);
+		ifp->qosmap_up_table = NULL;
+		ifp->qosmap_up_table_enable = FALSE;
+#endif /* BCM_ROUTER_DHD && QOS_MAP_SET */
+
+		dhd_if_del_sta_list(ifp);
+#ifdef PCIE_FULL_DONGLE
+		/* Delete flowrings of virtual interface */
+		ifidx = ifp->idx;
+		if ((ifidx != 0) &&
+		    ((if_flow_lkup != NULL) && (if_flow_lkup[ifidx].role != WLC_E_IF_ROLE_AP))) {
+			dhd_flow_rings_delete(dhdp, ifidx);
+		}
+#endif /* PCIE_FULL_DONGLE */
+	}
+}
+
+void
+dhd_cleanup_if(struct net_device *net)
+{
+	dhd_info_t *dhdinfo = DHD_DEV_INFO(net);
+	dhd_pub_t *dhdp = &dhdinfo->pub;
+	dhd_if_t *ifp;
+
+	ifp = dhd_get_ifp_by_ndev(dhdp, net);
+	if (ifp) {
+		if (ifp->idx >= DHD_MAX_IFS) {
+			DHD_ERROR(("Wrong ifidx: %p, %d\n", ifp, ifp->idx));
+			ASSERT(0);
+			return;
+		}
+		dhd_cleanup_ifp(dhdp, ifp);
+	}
+}
+
+/* unregister and free the the net_device interface associated with the indexed
+ * slot, also free the slot memory and set the slot pointer to NULL
+ */
+#define DHD_TX_COMPLETION_TIMEOUT 5000
+int
+dhd_remove_if(dhd_pub_t *dhdpub, int ifidx, bool need_rtnl_lock)
+{
+	dhd_info_t *dhdinfo = (dhd_info_t *)dhdpub->info;
+	dhd_if_t *ifp;
+	unsigned long flags;
+	long timeout;
+
+	ifp = dhdinfo->iflist[ifidx];
+
+	if (ifp != NULL) {
+#ifdef DHD_4WAYM4_FAIL_DISCONNECT
+		cancel_delayed_work_sync(&ifp->m4state_work);
+#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
+
+#ifdef DHDTCPSYNC_FLOOD_BLK
+		cancel_work_sync(&ifp->blk_tsfl_work);
+#endif /* DHDTCPSYNC_FLOOD_BLK */
+
+		dhd_cleanup_ifp(dhdpub, ifp);
+#ifdef WL_STATIC_IF
+		if (ifp->static_if) {
+			/* static IF will be handled in detach */
+			DHD_TRACE(("Skip del iface for static interface\n"));
+			return BCME_OK;
+		}
+#endif /* WL_STATIC_IF */
+		if (ifp->net != NULL) {
+			DHD_ERROR(("deleting interface '%s' idx %d\n", ifp->net->name, ifp->idx));
+
+			DHD_GENERAL_LOCK(dhdpub, flags);
+			ifp->del_in_progress = TRUE;
+			DHD_GENERAL_UNLOCK(dhdpub, flags);
+
+			/* If TX is in progress, hold the if del */
+			if (DHD_IF_IS_TX_ACTIVE(ifp)) {
+				DHD_INFO(("TX in progress. Wait for it to be complete."));
+				timeout = wait_event_timeout(dhdpub->tx_completion_wait,
+					((ifp->tx_paths_active & DHD_TX_CONTEXT_MASK) == 0),
+					msecs_to_jiffies(DHD_TX_COMPLETION_TIMEOUT));
+				if (!timeout) {
+					/* Tx completion timeout. Attempt proceeding ahead */
+					DHD_ERROR(("Tx completion timed out!\n"));
+					ASSERT(0);
+				}
+			} else {
+				DHD_TRACE(("No outstanding TX!\n"));
+			}
+			dhdinfo->iflist[ifidx] = NULL;
+			/* in unregister_netdev case, the interface gets freed by net->destructor
+			 * (which is set to free_netdev)
+			 */
+			if (ifp->net->reg_state == NETREG_UNINITIALIZED) {
+				free_netdev(ifp->net);
+			} else {
+				netif_tx_disable(ifp->net);
+
+#if defined(SET_RPS_CPUS)
+				custom_rps_map_clear(ifp->net->_rx);
+#endif /* SET_RPS_CPUS */
+#if (defined(BCM_ROUTER_DHD) && defined(HNDCTF))
+				if (dhdinfo->cih)
+					ctf_dev_unregister(dhdinfo->cih, ifp->net);
+#endif /* BCM_ROUTER_DHD && HNDCTF */
+
+#if (defined(DHDTCPACK_SUPPRESS) && defined(BCMPCIE))
+				dhd_tcpack_suppress_set(dhdpub, TCPACK_SUP_OFF);
+#endif /* DHDTCPACK_SUPPRESS && BCMPCIE */
+				dhd_unregister_net(ifp->net, need_rtnl_lock);
+#if defined(WLDWDS) && defined(WL_EXT_IAPSTA)
+				if (ifp->dwds) {
+					wl_ext_iapsta_dettach_dwds_netdev(ifp->net, ifidx, ifp->bssidx);
+				} else
+#endif /* WLDWDS && WL_EXT_IAPSTA */
+				{
+#ifdef WL_EXT_IAPSTA
+					wl_ext_iapsta_dettach_netdev(ifp->net, ifidx);
+#endif /* WL_EXT_IAPSTA */
+#ifdef WL_ESCAN
+					wl_escan_event_dettach(ifp->net, ifidx);
+#endif /* WL_ESCAN */
+#ifdef WL_EVENT
+					wl_ext_event_dettach_netdev(ifp->net, ifidx);
+#endif /* WL_EVENT */
+				}
+			}
+			ifp->net = NULL;
+		}
+#ifdef DHD_WMF
+		dhd_wmf_cleanup(dhdpub, ifidx);
+#endif /* DHD_WMF */
+		DHD_CUMM_CTR_INIT(&ifp->cumm_ctr);
+
+		MFREE(dhdinfo->pub.osh, ifp, sizeof(*ifp));
+		ifp = NULL;
+	}
+
+	return BCME_OK;
+}
+
+#if (defined(BCM_ROUTER_DHD) && defined(QOS_MAP_SET))
+int
+dhd_set_qosmap_up_table(dhd_pub_t *dhdp, uint32 idx, bcm_tlv_t *qos_map_ie)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(idx < DHD_MAX_IFS);
+	ifp = dhd->iflist[idx];
+
+	if (!ifp)
+	    return BCME_ERROR;
+
+	wl_set_up_table(ifp->qosmap_up_table, qos_map_ie);
+	ifp->qosmap_up_table_enable = TRUE;
+
+	return BCME_OK;
+}
+#endif /* BCM_ROUTER_DHD && QOS_MAP_SET */
+
+static struct net_device_ops dhd_ops_pri = {
+	.ndo_open = dhd_pri_open,
+	.ndo_stop = dhd_pri_stop,
+	.ndo_get_stats = dhd_get_stats,
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+	.ndo_do_ioctl = dhd_ioctl_entry_wrapper,
+	.ndo_start_xmit = dhd_start_xmit_wrapper,
+#else
+	.ndo_do_ioctl = dhd_ioctl_entry,
+	.ndo_start_xmit = dhd_start_xmit,
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+	.ndo_eth_ioctl = dhd_ioctl_entry,
+	.ndo_siocdevprivate = dhd_siocdevprivate,
+#endif
+	.ndo_set_mac_address = dhd_set_mac_address,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
+	.ndo_set_rx_mode = dhd_set_multicast_list,
+#else
+	.ndo_set_multicast_list = dhd_set_multicast_list,
+#endif
+#ifdef DHD_MQ
+	.ndo_select_queue = dhd_select_queue
+#endif
+};
+
+static struct net_device_ops dhd_ops_virt = {
+#if defined(WL_CFG80211) && defined(WL_STATIC_IF)
+	.ndo_open = dhd_static_if_open,
+	.ndo_stop = dhd_static_if_stop,
+#endif
+	.ndo_get_stats = dhd_get_stats,
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+	.ndo_do_ioctl = dhd_ioctl_entry_wrapper,
+	.ndo_start_xmit = dhd_start_xmit_wrapper,
+#else
+	.ndo_do_ioctl = dhd_ioctl_entry,
+	.ndo_start_xmit = dhd_start_xmit,
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0))
+	.ndo_eth_ioctl = dhd_ioctl_entry,
+	.ndo_siocdevprivate = dhd_siocdevprivate,
+#endif
+	.ndo_set_mac_address = dhd_set_mac_address,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
+	.ndo_set_rx_mode = dhd_set_multicast_list,
+#else
+	.ndo_set_multicast_list = dhd_set_multicast_list,
+#endif
+};
+
+#if (defined(BCM_ROUTER_DHD) && defined(HNDCTF))
+static void
+dhd_ctf_detach(ctf_t *ci, void *arg)
+{
+	dhd_info_t *dhd = (dhd_info_t *)arg;
+	dhd->cih = NULL;
+
+#ifdef CTFPOOL
+	/* free the buffers in fast pool */
+	osl_ctfpool_cleanup(dhd->pub.osh);
+#endif /* CTFPOOL */
+
+	return;
+}
+#endif /* BCM_ROUTER_DHD && HNDCTF */
+
+int
+dhd_os_write_file_posn(void *fp, unsigned long *posn, void *buf,
+		unsigned long buflen)
+{
+	loff_t wr_posn = *posn;
+
+	if (!fp || !buf || buflen == 0)
+		return -1;
+
+	if (dhd_vfs_write((struct file *)fp, buf, buflen, &wr_posn) < 0)
+		return -1;
+
+	*posn = wr_posn;
+	return 0;
+}
+
+int
+dhd_os_read_file(void *file, char *buf, uint32 size)
+{
+	struct file *filep = (struct file *)file;
+
+	if (!file || !buf)
+		return -1;
+
+	return dhd_vfs_read(filep, buf, size, &filep->f_pos);
+}
+
+int
+dhd_os_seek_file(void *file, int64 offset)
+{
+	struct file *filep = (struct file *)file;
+	if (!file)
+		return -1;
+
+	/* offset can be -ve */
+	filep->f_pos = filep->f_pos + offset;
+
+	return 0;
+}
+
+#ifdef SHOW_LOGTRACE
+#ifdef DHD_COREDUMP
+static int
+dhd_lookup_map(osl_t *osh, char *fname, uint32 pc, char *pc_fn,
+		uint32 lr, char *lr_fn)
+{
+#ifdef DHD_LINUX_STD_FW_API
+	const struct firmware *fw = NULL;
+	uint32 size = 0, mem_offset = 0;
+#else
+	struct file *filep = NULL;
+#ifdef get_fs
+	mm_segment_t fs;
+#endif /* get_fs */
+#endif /* DHD_LINUX_STD_FW_API */
+	char *raw_fmts = NULL, *raw_fmts_loc = NULL, *cptr = NULL;
+	uint32 read_size = READ_NUM_BYTES;
+	int err = BCME_ERROR;
+	uint32 addr = 0, addr1 = 0, addr2 = 0;
+	char type = '?', type1 = '?', type2 = '?';
+	char func[DHD_FUNC_STR_LEN] = "\0";
+	char func1[DHD_FUNC_STR_LEN] = "\0";
+	char func2[DHD_FUNC_STR_LEN] = "\0";
+	uint8 count = 0;
+	int num, len = 0, offset;
+
+	BCM_REFERENCE(type1);
+	DHD_TRACE(("%s: fname %s pc 0x%x lr 0x%x \n",
+		__FUNCTION__, fname, pc, lr));
+	if (fname == NULL) {
+		DHD_ERROR(("%s: ERROR fname is NULL \n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	/* Allocate 1 byte more than read_size to terminate it with NULL */
+	raw_fmts = MALLOCZ(osh, read_size + 1);
+	if (raw_fmts == NULL) {
+		DHD_ERROR(("%s: Failed to allocate raw_fmts memory \n",
+			__FUNCTION__));
+		return BCME_ERROR;
+	}
+
+#ifdef DHD_LINUX_STD_FW_API
+	err = dhd_os_get_img_fwreq(&fw, fname);
+	if (err < 0) {
+		DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n",
+			err));
+		goto fail;
+	}
+	size = fw->size;
+#else
+#ifdef get_fs
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+#endif /* get_fs */
+	filep = dhd_filp_open(fname, O_RDONLY, 0);
+	if (IS_ERR(filep) || (filep == NULL)) {
+		DHD_ERROR(("%s: Failed to open %s \n",  __FUNCTION__, fname));
+		goto fail;
+	}
+#endif /* DHD_LINUX_STD_FW_API */
+
+	if (pc_fn == NULL) {
+		count |= PC_FOUND_BIT;
+	}
+	if (lr_fn == NULL) {
+		count |= LR_FOUND_BIT;
+	}
+	while (count != ALL_ADDR_VAL)
+	{
+#ifdef DHD_LINUX_STD_FW_API
+		/* Bound check for size before doing memcpy() */
+		if ((mem_offset + read_size) > size) {
+			read_size = size - mem_offset;
+		}
+
+		err = memcpy_s(raw_fmts, read_size,
+			((char *)(fw->data) + mem_offset), read_size);
+		if (err) {
+			DHD_ERROR(("%s: failed to copy raw_fmts, err=%d\n",
+				__FUNCTION__, err));
+			goto fail;
+		}
+#else
+		err = dhd_os_read_file(filep, raw_fmts, read_size);
+		if (err < 0) {
+			DHD_ERROR(("%s: map file read failed err:%d \n",
+				__FUNCTION__, err));
+			goto fail;
+		}
+
+#endif /* DHD_LINUX_STD_FW_API */
+		/* End raw_fmts with NULL as strstr expects NULL terminated
+		* strings
+		*/
+		raw_fmts[read_size] = '\0';
+		raw_fmts_loc = raw_fmts;
+		offset = 0;
+
+		while ((count != ALL_ADDR_VAL) && (offset < read_size))
+		{
+			cptr = bcmstrtok(&raw_fmts_loc, "\n", 0);
+			if (cptr == NULL) {
+				DHD_TRACE(("%s: cptr is NULL, offset %d"
+					" raw_fmts_loc %s \n",
+					__FUNCTION__, offset, raw_fmts_loc));
+				break;
+			}
+			DHD_TRACE(("%s: %s \n", __FUNCTION__, cptr));
+			if ((type2 == 'A') ||
+				(type2 == 'T') ||
+				(type2 == 'W')) {
+				addr1 = addr2;
+				type1 = type2;
+				(void)memcpy_s(func1, DHD_FUNC_STR_LEN,
+					func2, DHD_FUNC_STR_LEN);
+				DHD_TRACE(("%s: %x %c %s \n",
+					__FUNCTION__, addr1, type1, func1));
+			}
+			len = strlen(cptr);
+			num = sscanf(cptr, "%x %c %79s", &addr, &type, func);
+			DHD_TRACE(("%s: num %d addr %x type %c func %s \n",
+				__FUNCTION__, num, addr, type, func));
+			if (num == 3) {
+				addr2 = addr;
+				type2 = type;
+				(void)memcpy_s(func2, DHD_FUNC_STR_LEN,
+					func, DHD_FUNC_STR_LEN);
+			}
+
+			if (!(count & PC_FOUND_BIT) &&
+				(pc >= addr1 && pc < addr2)) {
+				if ((cptr = strchr(func1, '$')) != NULL) {
+					(void)strncpy(func, cptr + 1,
+						DHD_FUNC_STR_LEN - 1);
+				} else {
+					(void)memcpy_s(func, DHD_FUNC_STR_LEN,
+						func1, DHD_FUNC_STR_LEN);
+				}
+				if ((cptr = strstr(func, "__bcmromfn"))
+					!= NULL) {
+					*cptr = 0;
+				}
+				if (pc > addr1) {
+					sprintf(pc_fn, "%.68s+0x%x",
+						func, pc - addr1);
+				} else {
+					(void)memcpy_s(pc_fn, DHD_FUNC_STR_LEN,
+						func, DHD_FUNC_STR_LEN);
+				}
+				count |= PC_FOUND_BIT;
+				DHD_INFO(("%s: found addr1 %x pc %x"
+					" addr2 %x \n",
+					__FUNCTION__, addr1, pc, addr2));
+			}
+			if (!(count & LR_FOUND_BIT) &&
+				(lr >= addr1 && lr < addr2)) {
+				if ((cptr = strchr(func1, '$')) != NULL) {
+					(void)strncpy(func, cptr + 1,
+						DHD_FUNC_STR_LEN - 1);
+				} else {
+					(void)memcpy_s(func, DHD_FUNC_STR_LEN,
+						func1, DHD_FUNC_STR_LEN);
+				}
+				if ((cptr = strstr(func, "__bcmromfn"))
+					!= NULL) {
+					*cptr = 0;
+				}
+				if (lr > addr1) {
+					sprintf(lr_fn, "%.68s+0x%x",
+						func, lr - addr1);
+				} else {
+					(void)memcpy_s(lr_fn, DHD_FUNC_STR_LEN,
+						func, DHD_FUNC_STR_LEN);
+				}
+				count |= LR_FOUND_BIT;
+				DHD_INFO(("%s: found addr1 %x lr %x"
+					" addr2 %x \n",
+					__FUNCTION__, addr1, lr, addr2));
+			}
+			offset += (len + 1);
+		}
+#ifdef DHD_LINUX_STD_FW_API
+		if ((mem_offset + read_size) >= size) {
+			break;
+		}
+
+		memset(raw_fmts, 0, read_size);
+		mem_offset += (read_size -(len + 1));
+#else
+		if (err < (int)read_size) {
+			/*
+			* since we reset file pos back to earlier pos by
+			* bytes of one line we won't reach EOF.
+			* The reason for this is if string is spreaded across
+			* bytes, the read function should not miss it.
+			* So if ret value is less than read_size, reached EOF
+			* don't read further
+			*/
+			break;
+		}
+		memset(raw_fmts, 0, read_size);
+		/*
+		* go back to bytes of one line so that we won't miss
+		* the string and addr even if it comes as splited in next read.
+		*/
+		dhd_os_seek_file(filep, -(len + 1));
+#endif /* DHD_LINUX_STD_FW_API */
+		DHD_TRACE(("%s: seek %d \n", __FUNCTION__, -(len + 1)));
+	}
+
+fail:
+#ifdef DHD_LINUX_STD_FW_API
+	if (fw) {
+		dhd_os_close_img_fwreq(fw);
+	}
+#else
+	if (!IS_ERR(filep))
+		dhd_filp_close(filep, NULL);
+
+#ifdef get_fs
+	set_fs(fs);
+#endif /* get_fs */
+#endif /* DHD_LINUX_STD_FW_API */
+	if (!(count & PC_FOUND_BIT)) {
+		sprintf(pc_fn, "0x%08x", pc);
+	}
+	if (!(count & LR_FOUND_BIT)) {
+		sprintf(lr_fn, "0x%08x", lr);
+	}
+	if (raw_fmts) {
+		MFREE(osh, raw_fmts, read_size + 1);
+	}
+	return err;
+}
+#endif /* DHD_COREDUMP */
+
+#ifdef DHD_LINUX_STD_FW_API
+static int
+dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp)
+{
+	char *raw_fmts =  NULL;
+	int logstrs_size = 0;
+	int error = 0;
+	const struct firmware *fw = NULL;
+
+	if (control_logtrace != LOGTRACE_PARSED_FMT) {
+		DHD_ERROR_NO_HW4(("%s : turned off logstr parsing\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	error = dhd_os_get_img_fwreq(&fw, logstrs_path);
+	if (error < 0) {
+		DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n",
+			error));
+		goto fail;
+	}
+
+	logstrs_size = (int)fw->size;
+	if (logstrs_size == 0) {
+		DHD_ERROR(("%s: return as logstrs_size is 0\n", __FUNCTION__));
+		goto fail;
+	}
+
+	if (temp->raw_fmts != NULL) {
+		raw_fmts = temp->raw_fmts;	/* reuse already malloced raw_fmts */
+	} else {
+		raw_fmts = MALLOC(osh, logstrs_size);
+		if (raw_fmts == NULL) {
+			DHD_ERROR(("%s: Failed to allocate memory \n", __FUNCTION__));
+			goto fail;
+		}
+		temp->raw_fmts = raw_fmts;
+		temp->raw_fmts_size = logstrs_size;
+	}
+	error = memcpy_s(raw_fmts, logstrs_size, (const char *)(fw->data), logstrs_size);
+	if (error) {
+		DHD_ERROR(("%s: failed to copy raw_fmts, err=%d\n",
+			__FUNCTION__, error));
+		goto fail;
+	}
+	if (dhd_parse_logstrs_file(osh, raw_fmts, logstrs_size, temp) == BCME_OK) {
+		dhd_os_close_img_fwreq(fw);
+		DHD_ERROR(("%s: return ok\n", __FUNCTION__));
+		return BCME_OK;
+	}
+
+fail:
+	if (fw) {
+		dhd_os_close_img_fwreq(fw);
+	}
+	if (raw_fmts) {
+		MFREE(osh, raw_fmts, logstrs_size);
+	}
+	if (temp->fmts != NULL) {
+		MFREE(osh, temp->fmts, temp->num_fmts * sizeof(char *));
+	}
+
+	temp->fmts = NULL;
+	temp->raw_fmts = NULL;
+
+	return BCME_ERROR;
+}
+
+static int
+dhd_read_map(osl_t *osh, char *fname, uint32 *ramstart, uint32 *rodata_start,
+		uint32 *rodata_end)
+{
+	int err = BCME_ERROR;
+	const struct firmware *fw = NULL;
+
+	if (fname == NULL) {
+		DHD_ERROR(("%s: ERROR fname is NULL \n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	err = dhd_os_get_img_fwreq(&fw, fname);
+	if (err < 0) {
+		DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n",
+			err));
+		goto fail;
+	}
+
+	if ((err = dhd_parse_map_file(osh, fw, ramstart,
+			rodata_start, rodata_end)) < 0) {
+		goto fail;
+	}
+
+fail:
+	if (fw) {
+		dhd_os_close_img_fwreq(fw);
+	}
+
+	return err;
+}
+
+static int
+dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, char *map_file)
+{
+	char *raw_fmts =  NULL;
+	uint32 logstrs_size = 0;
+	int error = 0;
+	uint32 ramstart = 0;
+	uint32 rodata_start = 0;
+	uint32 rodata_end = 0;
+	uint32 logfilebase = 0;
+	const struct firmware *fw = NULL;
+
+	error = dhd_read_map(osh, map_file, &ramstart, &rodata_start, &rodata_end);
+	if (error != BCME_OK) {
+		DHD_ERROR(("readmap Error!! \n"));
+		/* don't do event log parsing in actual case */
+		if (strstr(str_file, ram_file_str) != NULL) {
+			temp->raw_sstr = NULL;
+		} else if (strstr(str_file, rom_file_str) != NULL) {
+			temp->rom_raw_sstr = NULL;
+		}
+		return error;
+	}
+	DHD_ERROR(("ramstart: 0x%x, rodata_start: 0x%x, rodata_end:0x%x\n",
+		ramstart, rodata_start, rodata_end));
+
+	/* Full file size is huge. Just read required part */
+	logstrs_size = rodata_end - rodata_start;
+	logfilebase = rodata_start - ramstart;
+
+	if (logstrs_size == 0) {
+		DHD_ERROR(("%s: return as logstrs_size is 0\n", __FUNCTION__));
+		goto fail1;
+	}
+
+	if (strstr(str_file, ram_file_str) != NULL && temp->raw_sstr != NULL) {
+		raw_fmts = temp->raw_sstr;	/* reuse already malloced raw_fmts */
+	} else if (strstr(str_file, rom_file_str) != NULL && temp->rom_raw_sstr != NULL) {
+		raw_fmts = temp->rom_raw_sstr;	/* reuse already malloced raw_fmts */
+	} else {
+		raw_fmts = MALLOC(osh, logstrs_size);
+
+		if (raw_fmts == NULL) {
+			DHD_ERROR(("%s: Failed to allocate raw_fmts memory \n", __FUNCTION__));
+			goto fail;
+		}
+	}
+
+	error = dhd_os_get_img_fwreq(&fw, str_file);
+	if (error < 0 || (fw == NULL) || (fw->size < logfilebase)) {
+		DHD_ERROR(("dhd_os_get_img(Request Firmware API) error : %d\n",
+			error));
+		goto fail;
+	}
+
+	error = memcpy_s(raw_fmts, logstrs_size, (const char *)((fw->data) + logfilebase),
+		logstrs_size);
+	if (error) {
+		DHD_ERROR(("%s: failed to copy raw_fmts, err=%d\n",
+			__FUNCTION__, error));
+		goto fail;
+	}
+
+	if (strstr(str_file, ram_file_str) != NULL) {
+		temp->raw_sstr = raw_fmts;
+		temp->raw_sstr_size = logstrs_size;
+		temp->rodata_start = rodata_start;
+		temp->rodata_end = rodata_end;
+	} else if (strstr(str_file, rom_file_str) != NULL) {
+		temp->rom_raw_sstr = raw_fmts;
+		temp->rom_raw_sstr_size = logstrs_size;
+		temp->rom_rodata_start = rodata_start;
+		temp->rom_rodata_end = rodata_end;
+	}
+
+	if (fw) {
+		dhd_os_close_img_fwreq(fw);
+	}
+
+	return BCME_OK;
+
+fail:
+	if (raw_fmts) {
+		MFREE(osh, raw_fmts, logstrs_size);
+	}
+
+fail1:
+	if (fw) {
+		dhd_os_close_img_fwreq(fw);
+	}
+
+	if (strstr(str_file, ram_file_str) != NULL) {
+		temp->raw_sstr = NULL;
+	} else if (strstr(str_file, rom_file_str) != NULL) {
+		temp->rom_raw_sstr = NULL;
+	}
+
+	return error;
+} /* dhd_init_static_strs_array */
+#else
+static int
+dhd_init_logstrs_array(osl_t *osh, dhd_event_log_t *temp)
+{
+	struct file *filep = NULL;
+#ifdef get_fs
+	mm_segment_t fs;
+#endif /* get_fs */
+	char *raw_fmts =  NULL;
+	int logstrs_size = 0;
+
+	if (control_logtrace != LOGTRACE_PARSED_FMT) {
+		DHD_ERROR_NO_HW4(("%s : turned off logstr parsing\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+#ifdef get_fs
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+#endif /* get_fs */
+
+	filep = dhd_filp_open(logstrs_path, O_RDONLY, 0);
+
+	if (IS_ERR(filep) || (filep == NULL)) {
+		DHD_ERROR_NO_HW4(("%s: Failed to open the file %s \n",
+			__FUNCTION__, logstrs_path));
+		goto fail;
+	}
+
+	logstrs_size = dhd_vfs_size_read(filep);
+
+	if (logstrs_size == 0) {
+		DHD_ERROR(("%s: return as logstrs_size is 0\n", __FUNCTION__));
+		goto fail1;
+	}
+
+	if (temp->raw_fmts != NULL) {
+		raw_fmts = temp->raw_fmts;	   /* reuse already malloced raw_fmts */
+	} else {
+		raw_fmts = MALLOC(osh, logstrs_size);
+		if (raw_fmts == NULL) {
+			DHD_ERROR(("%s: Failed to allocate memory \n", __FUNCTION__));
+			goto fail;
+		}
+		temp->raw_fmts = raw_fmts;
+		temp->raw_fmts_size = logstrs_size;
+	}
+
+	if (dhd_vfs_read(filep, raw_fmts, logstrs_size, &filep->f_pos) != logstrs_size) {
+		DHD_ERROR_NO_HW4(("%s: Failed to read file %s\n", __FUNCTION__, logstrs_path));
+		goto fail;
+	}
+
+	if (dhd_parse_logstrs_file(osh, raw_fmts, logstrs_size, temp)
+			== BCME_OK) {
+		dhd_filp_close(filep, NULL);
+#ifdef get_fs
+		set_fs(fs);
+#endif /* get_fs */
+		return BCME_OK;
+	}
+
+	fail:
+	if (raw_fmts) {
+		MFREE(osh, raw_fmts, logstrs_size);
+	}
+	if (temp->fmts != NULL) {
+		MFREE(osh, temp->fmts, temp->num_fmts * sizeof(char *));
+	}
+
+	fail1:
+	if (!IS_ERR(filep))
+		dhd_filp_close(filep, NULL);
+
+#ifdef get_fs
+	set_fs(fs);
+#endif /* get_fs */
+	temp->fmts = NULL;
+	temp->raw_fmts = NULL;
+
+	return BCME_ERROR;
+}
+
+static int
+dhd_read_map(osl_t *osh, char *fname, uint32 *ramstart, uint32 *rodata_start,
+		uint32 *rodata_end)
+{
+	struct file *filep = NULL;
+#ifdef get_fs
+	mm_segment_t fs;
+#endif /* get_fs */
+	int err = BCME_ERROR;
+
+	if (fname == NULL) {
+		DHD_ERROR(("%s: ERROR fname is NULL \n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+#ifdef get_fs
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+#endif /* get_fs */
+
+	filep = dhd_filp_open(fname, O_RDONLY, 0);
+	if (IS_ERR(filep) || (filep == NULL)) {
+		DHD_ERROR_NO_HW4(("%s: Failed to open %s \n",  __FUNCTION__, fname));
+		goto fail;
+	}
+
+	if ((err = dhd_parse_map_file(osh, filep, ramstart,
+			rodata_start, rodata_end)) < 0)
+		goto fail;
+
+fail:
+	if (!IS_ERR(filep))
+		dhd_filp_close(filep, NULL);
+
+#ifdef get_fs
+	set_fs(fs);
+#endif /* get_fs */
+
+	return err;
+}
+
+static int
+dhd_init_static_strs_array(osl_t *osh, dhd_event_log_t *temp, char *str_file, char *map_file)
+{
+	struct file *filep = NULL;
+#ifdef get_fs
+	mm_segment_t fs;
+#endif /* get_fs */
+	char *raw_fmts =  NULL;
+	uint32 logstrs_size = 0;
+	int error = 0;
+	uint32 ramstart = 0;
+	uint32 rodata_start = 0;
+	uint32 rodata_end = 0;
+	uint32 logfilebase = 0;
+
+	error = dhd_read_map(osh, map_file, &ramstart, &rodata_start, &rodata_end);
+	if (error != BCME_OK) {
+		DHD_ERROR(("readmap Error!! \n"));
+		/* don't do event log parsing in actual case */
+		if (strstr(str_file, ram_file_str) != NULL) {
+			temp->raw_sstr = NULL;
+		} else if (strstr(str_file, rom_file_str) != NULL) {
+			temp->rom_raw_sstr = NULL;
+		}
+		return error;
+	}
+	DHD_ERROR(("ramstart: 0x%x, rodata_start: 0x%x, rodata_end:0x%x\n",
+		ramstart, rodata_start, rodata_end));
+
+#ifdef get_fs
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+#endif /* get_fs */
+
+	filep = dhd_filp_open(str_file, O_RDONLY, 0);
+	if (IS_ERR(filep) || (filep == NULL)) {
+		DHD_ERROR(("%s: Failed to open the file %s \n",  __FUNCTION__, str_file));
+		goto fail;
+	}
+
+	if (TRUE) {
+		/* Full file size is huge. Just read required part */
+		logstrs_size = rodata_end - rodata_start;
+		logfilebase = rodata_start - ramstart;
+	}
+
+	if (logstrs_size == 0) {
+		DHD_ERROR(("%s: return as logstrs_size is 0\n", __FUNCTION__));
+		goto fail1;
+	}
+
+	if (strstr(str_file, ram_file_str) != NULL && temp->raw_sstr != NULL) {
+		raw_fmts = temp->raw_sstr;	/* reuse already malloced raw_fmts */
+	} else if (strstr(str_file, rom_file_str) != NULL && temp->rom_raw_sstr != NULL) {
+		raw_fmts = temp->rom_raw_sstr;	/* reuse already malloced raw_fmts */
+	} else {
+		raw_fmts = MALLOC(osh, logstrs_size);
+
+		if (raw_fmts == NULL) {
+			DHD_ERROR(("%s: Failed to allocate raw_fmts memory \n", __FUNCTION__));
+			goto fail;
+		}
+	}
+
+	if (TRUE) {
+		error = generic_file_llseek(filep, logfilebase, SEEK_SET);
+		if (error < 0) {
+			DHD_ERROR(("%s: %s llseek failed %d \n", __FUNCTION__, str_file, error));
+			goto fail;
+		}
+	}
+
+	error = dhd_vfs_read(filep, raw_fmts, logstrs_size, (&filep->f_pos));
+	if (error != logstrs_size) {
+		DHD_ERROR(("%s: %s read failed %d \n", __FUNCTION__, str_file, error));
+		goto fail;
+	}
+
+	if (strstr(str_file, ram_file_str) != NULL) {
+		temp->raw_sstr = raw_fmts;
+		temp->raw_sstr_size = logstrs_size;
+		temp->rodata_start = rodata_start;
+		temp->rodata_end = rodata_end;
+	} else if (strstr(str_file, rom_file_str) != NULL) {
+		temp->rom_raw_sstr = raw_fmts;
+		temp->rom_raw_sstr_size = logstrs_size;
+		temp->rom_rodata_start = rodata_start;
+		temp->rom_rodata_end = rodata_end;
+	} else {
+		if (raw_fmts) {
+			MFREE(osh, raw_fmts, logstrs_size);
+		}
+	}
+
+	dhd_filp_close(filep, NULL);
+#ifdef get_fs
+	set_fs(fs);
+#endif /* get_fs */
+
+	return BCME_OK;
+
+fail:
+	if (raw_fmts) {
+		MFREE(osh, raw_fmts, logstrs_size);
+	}
+
+fail1:
+	if (!IS_ERR(filep))
+		dhd_filp_close(filep, NULL);
+
+#ifdef get_fs
+	set_fs(fs);
+#endif /* get_fs */
+
+	if (strstr(str_file, ram_file_str) != NULL) {
+		temp->raw_sstr = NULL;
+	} else if (strstr(str_file, rom_file_str) != NULL) {
+		temp->rom_raw_sstr = NULL;
+	}
+
+	return error;
+} /* dhd_init_static_strs_array */
+#endif /* DHD_LINUX_STD_FW_API */
+#endif /* SHOW_LOGTRACE */
+
+#ifdef BCMDBUS
+uint
+dhd_get_rxsz(dhd_pub_t *pub)
+{
+	struct net_device *net = NULL;
+	dhd_info_t *dhd = NULL;
+	uint rxsz;
+
+	/* Assign rxsz for dbus_attach */
+	dhd = pub->info;
+	net = dhd->iflist[0]->net;
+	net->hard_header_len = ETH_HLEN + pub->hdrlen;
+	rxsz = DBUS_RX_BUFFER_SIZE_DHD(net);
+
+	return rxsz;
+}
+
+void
+dhd_set_path(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = NULL;
+
+	dhd = pub->info;
+
+	/* try to download image and nvram to the dongle */
+	if	(dhd_update_fw_nv_path(dhd) && dhd->pub.bus) {
+		DHD_INFO(("%s: fw %s, nv %s, conf %s\n",
+			__FUNCTION__, dhd->fw_path, dhd->nv_path, dhd->conf_path));
+		dhd_bus_update_fw_nv_path(dhd->pub.bus,
+				dhd->fw_path, dhd->nv_path, dhd->clm_path, dhd->conf_path);
+	}
+}
+#endif
+
+/** Called once for each hardware (dongle) instance that this DHD manages */
+dhd_pub_t *
+dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen
+#ifdef BCMDBUS
+	, void *data
+#endif
+)
+{
+	dhd_info_t *dhd = NULL;
+	struct net_device *net = NULL;
+	char if_name[IFNAMSIZ] = {'\0'};
+#if defined(BCMSDIO) || defined(BCMPCIE)
+	uint32 bus_type = -1;
+	uint32 bus_num = -1;
+	uint32 slot_num = -1;
+	wifi_adapter_info_t *adapter = NULL;
+#elif defined(BCMDBUS)
+	wifi_adapter_info_t *adapter = data;
+#endif
+#ifdef SHOW_LOGTRACE
+	int ret;
+#endif /* SHOW_LOGTRACE && !OEM_ANDROID */
+
+	dhd_attach_states_t dhd_state = DHD_ATTACH_STATE_INIT;
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+#ifdef PCIE_FULL_DONGLE
+	ASSERT(sizeof(dhd_pkttag_fd_t) <= OSL_PKTTAG_SZ);
+	ASSERT(sizeof(dhd_pkttag_fr_t) <= OSL_PKTTAG_SZ);
+#endif /* PCIE_FULL_DONGLE */
+
+	/* will implement get_ids for DBUS later */
+#if defined(BCMSDIO) || defined(BCMPCIE)
+	dhd_bus_get_ids(bus, &bus_type, &bus_num, &slot_num);
+	adapter = dhd_wifi_platform_get_adapter(bus_type, bus_num, slot_num);
+#endif
+
+	/* Allocate primary dhd_info */
+	dhd = wifi_platform_prealloc(adapter, DHD_PREALLOC_DHD_INFO, sizeof(dhd_info_t));
+	if (dhd == NULL) {
+		dhd = MALLOC(osh, sizeof(dhd_info_t));
+		if (dhd == NULL) {
+			DHD_ERROR(("%s: OOM - alloc dhd_info\n", __FUNCTION__));
+			goto dhd_null_flag;
+		}
+	}
+	memset(dhd, 0, sizeof(dhd_info_t));
+	dhd_state |= DHD_ATTACH_STATE_DHD_ALLOC;
+
+	dhd->unit = dhd_found + instance_base; /* do not increment dhd_found, yet */
+
+	dhd->pub.osh = osh;
+#ifdef DUMP_IOCTL_IOV_LIST
+	dll_init(&(dhd->pub.dump_iovlist_head));
+#endif /* DUMP_IOCTL_IOV_LIST */
+
+	dhd->pub.dhd_console_ms = dhd_console_ms; /* assigns default value */
+
+	dhd->adapter = adapter;
+	dhd->pub.adapter = (void *)adapter;
+#ifdef BT_OVER_SDIO
+	dhd->pub.is_bt_recovery_required = FALSE;
+	mutex_init(&dhd->bus_user_lock);
+#endif /* BT_OVER_SDIO */
+
+	g_dhd_pub = &dhd->pub;
+
+#ifdef DHD_DEBUG
+	dll_init(&(dhd->pub.mw_list_head));
+#endif /* DHD_DEBUG */
+
+	/*
+	 * Attach DHD Core Layer to Platform Layer. For non
+	 * Embedded environment, where there is no dependency on platform
+	 * layer, dhd_get_plat_info_size can return 0, if the platform
+	 * layer does not exist or chooses not to implement it.
+	 */
+	dhd->pub.plat_info_size = dhd_plat_get_info_size();
+	if (dhd->pub.plat_info_size) {
+		dhd->pub.plat_info = MALLOCZ(osh, dhd->pub.plat_info_size);
+	}
+
+#ifdef CUSTOM_COUNTRY_CODE
+#ifdef CUSTOM_FORCE_NODFS_FLAG
+	dhd->pub.dhd_cflags |= WLAN_PLAT_NODFS_FLAG;
+	dhd->pub.force_country_change = TRUE;
+#endif /* CUSTOM_FORCE_NODFS_FLAG */
+	get_customized_country_code(dhd->adapter,
+		dhd->pub.dhd_cspec.country_abbrev, &dhd->pub.dhd_cspec,
+		dhd->pub.dhd_cflags);
+#endif /* CUSTOM_COUNTRY_CODE */
+#ifndef BCMDBUS
+	dhd->thr_dpc_ctl.thr_pid = DHD_PID_KT_TL_INVALID;
+	dhd->thr_wdt_ctl.thr_pid = DHD_PID_KT_INVALID;
+#ifdef DHD_WET
+	dhd->pub.wet_info = dhd_get_wet_info(&dhd->pub);
+#endif /* DHD_WET */
+
+#ifdef CSI_SUPPORT
+	dhd_csi_init(&dhd->pub);
+#endif /* CSI_SUPPORT */
+
+	/* Initialize thread based operation and lock */
+	sema_init(&dhd->sdsem, 1);
+#endif /* BCMDBUS */
+#if defined(WL_MONITOR) && defined(HOST_RADIOTAP_CONV)
+	dhd->host_radiotap_conv = FALSE;
+#endif /* WL_MONITOR */
+	dhd->pub.pcie_txs_metadata_enable = pcie_txs_metadata_enable;
+
+	/* Link to info module */
+	dhd->pub.info = dhd;
+
+	/* Link to bus module */
+	dhd->pub.bus = bus;
+	dhd->pub.hdrlen = bus_hdrlen;
+	dhd->pub.txoff = FALSE;
+#ifdef CHECK_TRAP_ROT
+	dhd->pub.check_trap_rot = TRUE;
+#else
+	dhd->pub.check_trap_rot = FALSE;
+#endif /* CHECK_TRAP_ROT */
+
+#ifdef PKT_FILTER_SUPPORT
+	dhd->pub.pfaoe_enab = dhd_pfaoe_enab;
+#endif /* PKT_FILTER_SUPPORT */
+
+#ifdef WBRC
+	dhd->pub.chip_bighammer_count = 0;
+#endif /* WBRC */
+
+	/* dhd_conf must be attached after linking dhd to dhd->pub.info,
+	 * because dhd_detech will check .info is NULL or not.
+	*/
+	if (dhd_conf_attach(&dhd->pub) != 0) {
+		DHD_ERROR(("dhd_conf_attach failed\n"));
+		goto fail;
+	}
+#ifndef BCMDBUS
+	dhd_conf_reset(&dhd->pub);
+	dhd_conf_set_chiprev(&dhd->pub, dhd_bus_chip(bus), dhd_bus_chiprev(bus));
+	dhd_conf_preinit(&dhd->pub);
+#endif /* !BCMDBUS */
+
+	/* Some DHD modules (e.g. cfg80211) configures operation mode based on firmware name.
+	 * This is indeed a hack but we have to make it work properly before we have a better
+	 * solution
+	 */
+	dhd_update_fw_nv_path(dhd);
+
+	/* Set network interface name if it was provided as module parameter */
+	if (iface_name[0]) {
+		int len;
+		char ch;
+		strlcpy(if_name, iface_name, sizeof(if_name));
+		len = strlen(if_name);
+		ch = if_name[len - 1];
+		if ((ch > '9' || ch < '0') && (len < IFNAMSIZ - 2)) {
+			strncat(if_name, "%d", sizeof(if_name) - len - 1);
+		}
+	}
+
+	/* Passing NULL to dngl_name to ensure host gets if_name in dngl_name member */
+	net = dhd_allocate_if(&dhd->pub, 0, if_name, NULL, 0, TRUE, NULL);
+	if (net == NULL) {
+		goto fail;
+	}
+	mutex_init(&dhd->pub.ndev_op_sync);
+
+	dhd_state |= DHD_ATTACH_STATE_ADD_IF;
+#ifdef DHD_L2_FILTER
+	/* initialize the l2_filter_cnt */
+	dhd->pub.l2_filter_cnt = 0;
+#endif
+	net->netdev_ops = NULL;
+
+	mutex_init(&dhd->dhd_iovar_mutex);
+	sema_init(&dhd->proto_sem, 1);
+
+#if defined(DHD_HANG_SEND_UP_TEST)
+	dhd->pub.req_hang_type = 0;
+#endif /* DHD_HANG_SEND_UP_TEST */
+
+#ifdef PROP_TXSTATUS
+	spin_lock_init(&dhd->wlfc_spinlock);
+
+	dhd->pub.skip_fc = dhd_wlfc_skip_fc;
+	dhd->pub.plat_init = dhd_wlfc_plat_init;
+	dhd->pub.plat_deinit = dhd_wlfc_plat_deinit;
+
+#ifdef DHD_WLFC_THREAD
+	init_waitqueue_head(&dhd->pub.wlfc_wqhead);
+	dhd->pub.wlfc_thread = kthread_create(dhd_wlfc_transfer_packets, &dhd->pub, "wlfc-thread");
+	if (IS_ERR(dhd->pub.wlfc_thread)) {
+		DHD_ERROR(("create wlfc thread failed\n"));
+		goto fail;
+	} else {
+		wake_up_process(dhd->pub.wlfc_thread);
+	}
+#endif /* DHD_WLFC_THREAD */
+#endif /* PROP_TXSTATUS */
+
+	/* Initialize other structure content */
+	/* XXX Some of this goes away, leftover from USB */
+	/* XXX Some could also move to bus_init()? */
+	init_waitqueue_head(&dhd->ioctl_resp_wait);
+	init_waitqueue_head(&dhd->pub.tx_tput_test_wait);
+	init_waitqueue_head(&dhd->d3ack_wait);
+#ifdef PCIE_INB_DW
+	init_waitqueue_head(&dhd->ds_exit_wait);
+#endif /* PCIE_INB_DW */
+	init_waitqueue_head(&dhd->ctrl_wait);
+	init_waitqueue_head(&dhd->dhd_bus_busy_state_wait);
+	init_waitqueue_head(&dhd->dmaxfer_wait);
+	init_waitqueue_head(&dhd->pub.tx_completion_wait);
+	dhd->pub.dhd_bus_busy_state = 0;
+	/* Initialize the spinlocks */
+	spin_lock_init(&dhd->sdlock);
+	spin_lock_init(&dhd->txqlock);
+	spin_lock_init(&dhd->dhd_lock);
+	spin_lock_init(&dhd->txoff_lock);
+	spin_lock_init(&dhd->rxf_lock);
+#ifdef WLTDLS
+	spin_lock_init(&dhd->pub.tdls_lock);
+#endif /* WLTDLS */
+#if defined(RXFRAME_THREAD)
+	dhd->rxthread_enabled = TRUE;
+#endif /* defined(RXFRAME_THREAD) */
+
+#ifdef DHDTCPACK_SUPPRESS
+	spin_lock_init(&dhd->tcpack_lock);
+#endif /* DHDTCPACK_SUPPRESS */
+
+	/* Initialize Wakelock stuff */
+	spin_lock_init(&dhd->wakelock_spinlock);
+	spin_lock_init(&dhd->wakelock_evt_spinlock);
+	DHD_OS_WAKE_LOCK_INIT(dhd);
+	dhd->wakelock_counter = 0;
+	/* wakelocks prevent a system from going into a low power state */
+#ifdef CONFIG_HAS_WAKELOCK
+	dhd_wake_lock_init(dhd->wl_wdwake, dhd_bus_to_dev(bus), "wlan_wd_wake");
+#endif /* CONFIG_HAS_WAKELOCK */
+
+#if defined(OEM_ANDROID)
+	mutex_init(&dhd->dhd_net_if_mutex);
+	mutex_init(&dhd->dhd_suspend_mutex);
+#if defined(APF)
+	mutex_init(&dhd->dhd_apf_mutex);
+#endif /* APF */
+#endif /* defined(OEM_ANDROID) */
+	dhd_state |= DHD_ATTACH_STATE_WAKELOCKS_INIT;
+
+	/* Attach and link in the protocol */
+	if (dhd_prot_attach(&dhd->pub) != 0) {
+		DHD_ERROR(("dhd_prot_attach failed\n"));
+		goto fail;
+	}
+	dhd_state |= DHD_ATTACH_STATE_PROT_ATTACH;
+
+#ifdef WL_CFG80211
+	spin_lock_init(&dhd->pub.up_lock);
+	/* Attach and link in the cfg80211 */
+	if (unlikely(wl_cfg80211_attach(net, &dhd->pub))) {
+		DHD_ERROR(("wl_cfg80211_attach failed\n"));
+		goto fail;
+	}
+
+	dhd_monitor_init(&dhd->pub);
+	dhd_state |= DHD_ATTACH_STATE_CFG80211;
+#endif
+
+#ifdef SHOW_LOGTRACE
+	if (dhd_download_fw_on_driverload) {
+		ret = dhd_init_logstrs_array(osh, &dhd->event_data);
+		if (ret == BCME_OK) {
+			dhd_init_static_strs_array(osh, &dhd->event_data, st_str_file_path,
+				map_file_path);
+#ifdef DHD_LOAD_ROML_FILES
+			dhd_init_static_strs_array(osh, &dhd->event_data, rom_st_str_file_path,
+				rom_map_file_path);
+#endif /* DHD_LOAD_ROML_FILES */
+			dhd_state |= DHD_ATTACH_LOGTRACE_INIT;
+		}
+	}
+#endif /* SHOW_LOGTRACE */
+
+#ifdef WL_EVENT
+	if (wl_ext_event_attach(net) != 0) {
+		DHD_ERROR(("wl_ext_event_attach failed\n"));
+		goto fail;
+	}
+#endif /* WL_EVENT */
+#ifdef WL_TIMER
+	if (wl_timer_attach(net) != 0) {
+		DHD_ERROR(("wl_ext_timer_attach failed\n"));
+		goto fail;
+	}
+#endif /* WL_TIMER */
+#ifdef WL_ESCAN
+	/* Attach and link in the escan */
+	if (wl_escan_attach(net) != 0) {
+		DHD_ERROR(("wl_escan_attach failed\n"));
+		goto fail;
+	}
+#endif /* WL_ESCAN */
+#ifdef WL_EXT_IAPSTA
+	if (wl_ext_iapsta_attach(net) != 0) {
+		DHD_ERROR(("wl_ext_iapsta_attach failed\n"));
+		goto fail;
+	}
+#endif /* WL_EXT_IAPSTA */
+#ifdef WL_EXT_GENL
+	if (wl_ext_genl_init(net)) {
+		DHD_ERROR(("wl_ext_genl_init failed\n"));
+		goto fail;
+	}
+#endif
+#if defined(WL_WIRELESS_EXT)
+	/* Attach and link in the iw */
+	if (wl_iw_attach(net) != 0) {
+		DHD_ERROR(("wl_iw_attach failed\n"));
+		goto fail;
+	}
+	dhd_state |= DHD_ATTACH_STATE_WL_ATTACH;
+#endif /* defined(WL_WIRELESS_EXT) */
+
+#ifdef DHD_LOG_DUMP
+	dhd_log_dump_init(&dhd->pub);
+#endif /* DHD_LOG_DUMP */
+#ifdef DHD_PKTDUMP_ROAM
+	dhd_dump_pkt_init(&dhd->pub);
+#endif /* DHD_PKTDUMP_ROAM */
+#ifdef DHD_PKT_LOGGING
+	dhd_os_attach_pktlog(&dhd->pub);
+#endif /* DHD_PKT_LOGGING */
+
+	/* attach debug if support */
+	if (dhd_os_dbg_attach(&dhd->pub)) {
+		DHD_ERROR(("%s debug module attach failed\n", __FUNCTION__));
+		goto fail;
+	}
+#ifdef DEBUGABILITY
+#if !defined(OEM_ANDROID) && defined(SHOW_LOGTRACE)
+	/* enable verbose ring to support dump_trace_buf */
+	dhd_os_start_logging(&dhd->pub, FW_VERBOSE_RING_NAME, 3, 0, 0, 0);
+#endif /* !OEM_ANDROID && SHOW_LOGTRACE */
+
+#ifdef DBG_PKT_MON
+	dhd->pub.dbg->pkt_mon_lock = osl_spin_lock_init(dhd->pub.osh);
+#ifdef DBG_PKT_MON_INIT_DEFAULT
+	dhd_os_dbg_attach_pkt_monitor(&dhd->pub);
+#endif /* DBG_PKT_MON_INIT_DEFAULT */
+#endif /* DBG_PKT_MON */
+
+#endif /* DEBUGABILITY */
+
+#ifdef DHD_MEM_STATS
+	dhd->pub.mem_stats_lock = osl_spin_lock_init(dhd->pub.osh);
+	dhd->pub.txpath_mem = 0;
+	dhd->pub.rxpath_mem = 0;
+#endif /* DHD_MEM_STATS */
+
+#ifdef DHD_STATUS_LOGGING
+	dhd->pub.statlog = dhd_attach_statlog(&dhd->pub, MAX_STATLOG_ITEM,
+		MAX_STATLOG_REQ_ITEM, STATLOG_LOGBUF_LEN);
+	if (dhd->pub.statlog == NULL) {
+		DHD_ERROR(("%s: alloc statlog failed\n", __FUNCTION__));
+	}
+#endif /* DHD_STATUS_LOGGING */
+
+#ifdef RX_PKT_POOL
+	dhd_rx_pktpool_init(dhd);
+#endif /* RX_PKT_POOL */
+#ifdef WL_CFGVENDOR_SEND_HANG_EVENT
+	dhd->pub.hang_info = MALLOCZ(osh, VENDOR_SEND_HANG_EXT_INFO_LEN);
+	if (dhd->pub.hang_info == NULL) {
+		DHD_ERROR(("%s: alloc hang_info failed\n", __FUNCTION__));
+		goto fail;
+	}
+#endif /* WL_CFGVENDOR_SEND_HANG_EVENT */
+
+	if (dhd_sta_pool_init(&dhd->pub, DHD_MAX_STA) != BCME_OK) {
+		DHD_ERROR(("%s: Initializing %u sta\n", __FUNCTION__, DHD_MAX_STA));
+		goto fail;
+	}
+
+#ifdef BCM_ROUTER_DHD
+#if defined(HNDCTF)
+	dhd->cih = ctf_attach(dhd->pub.osh, "dhd", &dhd_msg_level, dhd_ctf_detach, dhd);
+	if (!dhd->cih) {
+		DHD_ERROR(("%s: ctf_attach() failed\n", __FUNCTION__));
+	}
+#ifdef CTFPOOL
+	{
+		int poolsz = RXBUFPOOLSZ;
+		if (CTF_ENAB(dhd->cih) && (osl_ctfpool_init(dhd->pub.osh,
+			poolsz, RXBUFSZ + BCMEXTRAHDROOM) < 0)) {
+			DHD_ERROR(("%s: osl_ctfpool_init() failed\n", __FUNCTION__));
+		}
+	}
+#endif /* CTFPOOL */
+#endif /* HNDCTF */
+#endif /* BCM_ROUTER_DHD */
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+	dhd->tx_wq = alloc_workqueue("bcmdhd-tx-wq", WQ_HIGHPRI | WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+	if (!dhd->tx_wq) {
+		DHD_ERROR(("%s: alloc_workqueue(bcmdhd-tx-wq) failed\n", __FUNCTION__));
+		goto fail;
+	}
+	dhd->rx_wq = alloc_workqueue("bcmdhd-rx-wq", WQ_HIGHPRI | WQ_UNBOUND | WQ_MEM_RECLAIM, 1);
+	if (!dhd->rx_wq) {
+		DHD_ERROR(("%s: alloc_workqueue(bcmdhd-rx-wq) failed\n", __FUNCTION__));
+		destroy_workqueue(dhd->tx_wq);
+		dhd->tx_wq = NULL;
+		goto fail;
+	}
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+#ifndef BCMDBUS
+	/* Set up the watchdog timer */
+	init_timer_compat(&dhd->timer, dhd_watchdog, dhd);
+	dhd->default_wd_interval = dhd_watchdog_ms;
+
+	if (dhd_watchdog_prio >= 0) {
+		/* Initialize watchdog thread */
+		PROC_START(dhd_watchdog_thread, dhd, &dhd->thr_wdt_ctl, 0, "dhd_watchdog_thread");
+		if (dhd->thr_wdt_ctl.thr_pid < 0) {
+			goto fail;
+		}
+
+	} else {
+		dhd->thr_wdt_ctl.thr_pid = -1;
+	}
+
+	/* Set up the bottom half handler */
+	if (dhd_dpc_prio >= 0) {
+		/* Initialize DPC thread */
+		PROC_START(dhd_dpc_thread, dhd, &dhd->thr_dpc_ctl, 0, "dhd_dpc");
+		if (dhd->thr_dpc_ctl.thr_pid < 0) {
+			goto fail;
+		}
+	} else {
+		/*  use tasklet for dpc */
+		tasklet_init(&dhd->tasklet, dhd_dpc, (ulong)dhd);
+		dhd->thr_dpc_ctl.thr_pid = -1;
+	}
+
+	if (dhd->rxthread_enabled) {
+		bzero(&dhd->pub.skbbuf[0], sizeof(void *) * MAXSKBPEND);
+		/* Initialize RXF thread */
+		PROC_START(dhd_rxf_thread, dhd, &dhd->thr_rxf_ctl, 0, "dhd_rxf");
+		if (dhd->thr_rxf_ctl.thr_pid < 0) {
+			goto fail;
+		}
+	}
+#endif /* !BCMDBUS */
+
+#ifdef SHOW_LOGTRACE
+	skb_queue_head_init(&dhd->evt_trace_queue);
+
+	/* Create ring proc entries */
+	dhd_dbg_ring_proc_create(&dhd->pub);
+#endif /* SHOW_LOGTRACE */
+
+	dhd_state |= DHD_ATTACH_STATE_THREADS_CREATED;
+
+#if defined(CONFIG_PM_SLEEP) && !defined(DEVICE_PM_CALLBACK)
+	if (!dhd_pm_notifier_registered) {
+		dhd_pm_notifier_registered = TRUE;
+		dhd->pm_notifier.notifier_call = dhd_pm_callback;
+		dhd->pm_notifier.priority = 10;
+		register_pm_notifier(&dhd->pm_notifier);
+	}
+
+#endif /* CONFIG_PM_SLEEP */
+
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
+	dhd->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 20;
+	dhd->early_suspend.suspend = dhd_early_suspend;
+	dhd->early_suspend.resume = dhd_late_resume;
+	register_early_suspend(&dhd->early_suspend);
+	dhd_state |= DHD_ATTACH_STATE_EARLYSUSPEND_DONE;
+#endif /* CONFIG_HAS_EARLYSUSPEND && DHD_USE_EARLYSUSPEND */
+
+#ifdef ARP_OFFLOAD_SUPPORT
+	dhd->pend_ipaddr = 0;
+	if (!dhd_inetaddr_notifier_registered) {
+		dhd_inetaddr_notifier_registered = TRUE;
+		register_inetaddr_notifier(&dhd_inetaddr_notifier);
+	}
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+#if defined(CONFIG_IPV6) && defined(IPV6_NDO_SUPPORT)
+	if (!dhd_inet6addr_notifier_registered) {
+		dhd_inet6addr_notifier_registered = TRUE;
+		register_inet6addr_notifier(&dhd_inet6addr_notifier);
+	}
+#endif /* CONFIG_IPV6 && IPV6_NDO_SUPPORT */
+	dhd->dhd_deferred_wq = dhd_deferred_work_init((void *)dhd);
+#if defined(OEM_ANDROID)
+	INIT_WORK(&dhd->dhd_hang_process_work, dhd_hang_process);
+#endif /* OEM_ANDROID */
+#ifdef DEBUG_CPU_FREQ
+	dhd->new_freq = alloc_percpu(int);
+	dhd->freq_trans.notifier_call = dhd_cpufreq_notifier;
+	cpufreq_register_notifier(&dhd->freq_trans, CPUFREQ_TRANSITION_NOTIFIER);
+#endif
+#ifdef DHDTCPACK_SUPPRESS
+#ifdef BCMSDIO
+	dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_DELAYTX);
+#elif defined(BCMPCIE)
+	/* xxx : In case of PCIe based Samsung Android project, enable TCP ACK Suppress
+	 *       when throughput is higher than threshold, following rps_cpus setting.
+	 */
+	dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_HOLD);
+#else
+	dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_OFF);
+#endif /* BCMSDIO */
+#endif /* DHDTCPACK_SUPPRESS */
+
+#if defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW)
+#endif /* defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW) */
+
+#ifdef DHD_DEBUG_PAGEALLOC
+	register_page_corrupt_cb(dhd_page_corrupt_cb, &dhd->pub);
+#endif /* DHD_DEBUG_PAGEALLOC */
+
+	INIT_DELAYED_WORK(&dhd->dhd_dpc_dispatcher_work, dhd_dpc_tasklet_dispatcher_work);
+
+#if defined(DHD_LB)
+#if defined(DHD_LB_HOST_CTRL)
+	dhd->permitted_primary_cpu = FALSE;
+#endif /* DHD_LB_HOST_CTRL */
+	dhd_lb_set_default_cpus(dhd);
+	DHD_LB_STATS_INIT(&dhd->pub);
+
+	/* Initialize the CPU Masks */
+	if (dhd_cpumasks_init(dhd) == 0) {
+		/* Now we have the current CPU maps, run through candidacy */
+		dhd_select_cpu_candidacy(dhd);
+
+		/* Register the call backs to CPU Hotplug sub-system */
+		dhd_register_cpuhp_callback(dhd);
+
+	} else {
+		/*
+		* We are unable to initialize CPU masks, so candidacy algorithm
+		* won't run, but still Load Balancing will be honoured based
+		* on the CPUs allocated for a given job statically during init
+		*/
+		dhd->cpu_notifier.notifier_call = NULL;
+		DHD_ERROR(("%s():dhd_cpumasks_init failed CPUs for JOB would be static\n",
+			__FUNCTION__));
+	}
+
+#ifdef DHD_LB_TXP
+#ifdef DHD_LB_TXP_DEFAULT_ENAB
+	/* Trun ON the feature by default */
+	atomic_set(&dhd->lb_txp_active, 1);
+#else
+	/* Trun OFF the feature by default */
+	atomic_set(&dhd->lb_txp_active, 0);
+#endif /* DHD_LB_TXP_DEFAULT_ENAB */
+#endif /* DHD_LB_TXP */
+
+#ifdef DHD_LB_RXP
+	/* Trun ON the feature by default */
+	atomic_set(&dhd->lb_rxp_active, 1);
+#endif /* DHD_LB_RXP */
+
+	/* Initialize the Load Balancing Tasklets and Napi object */
+#if defined(DHD_LB_RXP)
+	__skb_queue_head_init(&dhd->rx_pend_queue);
+	skb_queue_head_init(&dhd->rx_emerge_queue);
+	skb_queue_head_init(&dhd->rx_napi_queue);
+	__skb_queue_head_init(&dhd->rx_process_queue);
+	/* Initialize the work that dispatches NAPI job to a given core */
+	INIT_WORK(&dhd->rx_napi_dispatcher_work, dhd_rx_napi_dispatcher_work);
+	DHD_INFO(("%s load balance init rx_napi_queue\n", __FUNCTION__));
+	/* Initialize the work that dispatches DPC tasklet to a given core */
+#endif /* DHD_LB_RXP */
+
+#if defined(DHD_LB_TXP)
+	INIT_WORK(&dhd->tx_dispatcher_work, dhd_tx_dispatcher_work);
+	skb_queue_head_init(&dhd->tx_pend_queue);
+	/* Initialize the work that dispatches TX job to a given core */
+	tasklet_init(&dhd->tx_tasklet,
+		dhd_lb_tx_handler, (ulong)(dhd));
+	DHD_INFO(("%s load balance init tx_pend_queue\n", __FUNCTION__));
+#endif /* DHD_LB_TXP */
+
+	dhd_state |= DHD_ATTACH_STATE_LB_ATTACH_DONE;
+#endif /* DHD_LB */
+
+#ifdef CSI_SUPPORT
+	dhd_csi_init(&dhd->pub);
+#endif /* CSI_SUPPORT */
+
+#if defined(DNGL_AXI_ERROR_LOGGING) && defined(DHD_USE_WQ_FOR_DNGL_AXI_ERROR)
+	INIT_WORK(&dhd->axi_error_dispatcher_work, dhd_axi_error_dispatcher_fn);
+#endif /* DNGL_AXI_ERROR_LOGGING && DHD_USE_WQ_FOR_DNGL_AXI_ERROR */
+
+#if defined(BCMDBG) && defined(DHD_MACDBG)
+	if (dhd_macdbg_attach(&dhd->pub) != BCME_OK) {
+		DHD_ERROR(("%s: dhd_macdbg_attach fail\n", __FUNCTION__));
+		goto fail;
+	}
+#endif /* BCMDBG && DHD_MACDBG */
+
+#ifdef REPORT_FATAL_TIMEOUTS
+	init_dhd_timeouts(&dhd->pub);
+#endif /* REPORT_FATAL_TIMEOUTS */
+#if defined(BCMPCIE)
+	dhd->pub.extended_trap_data = MALLOCZ(osh, BCMPCIE_EXT_TRAP_DATA_MAXLEN);
+	if (dhd->pub.extended_trap_data == NULL) {
+		DHD_ERROR(("%s: Failed to alloc extended_trap_data\n", __FUNCTION__));
+	}
+#ifdef DNGL_AXI_ERROR_LOGGING
+	dhd->pub.axi_err_dump = MALLOCZ(osh, sizeof(dhd_axi_error_dump_t));
+	if (dhd->pub.axi_err_dump == NULL) {
+		DHD_ERROR(("%s: Failed to alloc axi_err_dump\n", __FUNCTION__));
+	}
+#endif /* DNGL_AXI_ERROR_LOGGING */
+#endif /* BCMPCIE */
+
+#ifdef SHOW_LOGTRACE
+	if (dhd_init_logtrace_process(dhd) != BCME_OK) {
+		goto fail;
+	}
+#endif /* SHOW_LOGTRACE */
+
+#ifdef EWP_EDL
+	INIT_DELAYED_WORK(&dhd->edl_dispatcher_work, dhd_edl_process_work);
+#endif
+
+	DHD_COREDUMP_MEMPOOL_INIT(&dhd->pub);
+	DHD_SSSR_MEMPOOL_INIT(&dhd->pub);
+	DHD_SSSR_REG_INFO_INIT(&dhd->pub);
+
+#ifdef DHD_SDTC_ETB_DUMP
+	dhd_sdtc_etb_mempool_init(&dhd->pub);
+#endif /* DHD_SDTC_ETB_DUMP */
+
+#ifdef EWP_EDL
+	if (host_edl_support) {
+		if (DHD_EDL_MEM_INIT(&dhd->pub) != BCME_OK) {
+			host_edl_support = FALSE;
+		}
+	}
+#endif /* EWP_EDL */
+
+	dhd_init_sock_flows_buf(dhd, dhd_watchdog_ms);
+
+	(void)dhd_sysfs_init(dhd);
+
+#ifdef GDB_PROXY
+	dhd->pub.gdb_proxy_nodeadman = nodeadman != 0;
+#endif /* GDB_PROXY */
+	dhd_state |= DHD_ATTACH_STATE_DONE;
+	dhd->dhd_state = dhd_state;
+
+	dhd_found++;
+
+#ifdef DHD_FW_COREDUMP
+	/* Set memdump default values */
+#if defined(OEM_ANDROID)
+#ifdef DHD_COREDUMP
+	dhd->pub.memdump_enabled = DUMP_MEMFILE;
+#else
+	dhd->pub.memdump_enabled = DUMP_MEMFILE_BUGON;
+#endif /* DHD_COREDUMP */
+#else
+	dhd->pub.memdump_enabled = DUMP_MEMFILE;
+#endif /* OEM_ANDROID */
+	/* Check the memdump capability */
+	dhd_get_memdump_info(&dhd->pub);
+#endif /* DHD_FW_COREDUMP */
+
+#ifdef DHD_DUMP_MNGR
+	dhd->pub.dump_file_manage =
+		(dhd_dump_file_manage_t *)MALLOCZ(dhd->pub.osh, sizeof(dhd_dump_file_manage_t));
+	if (unlikely(!dhd->pub.dump_file_manage)) {
+		DHD_ERROR(("%s(): could not allocate memory for - "
+					"dhd_dump_file_manage_t\n", __FUNCTION__));
+	}
+#endif /* DHD_DUMP_MNGR */
+
+#ifdef RTT_SUPPORT
+	if (dhd_rtt_attach(&dhd->pub)) {
+		DHD_ERROR(("dhd_rtt_attach has failed\n"));
+		goto fail;
+	}
+#endif /* RTT_SUPPORT */
+
+#ifdef DHD_TX_PROFILE
+	if (dhd_tx_profile_attach(&dhd->pub) != BCME_OK) {
+		DHD_ERROR(("%s:\tdhd_tx_profile_attach has failed\n", __FUNCTION__));
+		goto fail;
+	}
+#endif /* defined(DHD_TX_PROFILE) */
+
+#ifdef WL_CFGVENDOR_SEND_ALERT_EVENT
+	INIT_WORK(&dhd->dhd_alert_process_work, dhd_alert_process);
+#endif /* WL_CFGVENDOR_SEND_ALERT_EVENT */
+#if defined(DHD_ENABLE_S2MPU)
+	dhd_module_s2mpu_register(dhd_bus_to_dev(bus));
+#endif /* DHD_ENABLE_S2MPU */
+#ifdef DHD_REGISTER_SMMU_FAULT_HANDLER
+	pcie_sysmmu_add_fault_handler(&dhd_pcie_sysmmu_nb);
+#endif /* DHD_REGISTER_SMMU_FAULT_HANDLER */
+#if defined(DHD_FILE_DUMP_EVENT) && defined(DHD_FW_COREDUMP)
+	OSL_ATOMIC_SET(dhd->pub.osh, &dhd->dump_status, DUMP_NOT_READY);
+	INIT_WORK(&dhd->dhd_dump_proc_work, dhd_dump_proc);
+#endif /* DHD_FILE_DUMP_EVENT && DHD_FW_COREDUMP */
+
+	return &dhd->pub;
+
+fail:
+	if (dhd_state >= DHD_ATTACH_STATE_DHD_ALLOC) {
+		DHD_TRACE(("%s: Calling dhd_detach dhd_state 0x%x &dhd->pub %p\n",
+			__FUNCTION__, dhd_state, &dhd->pub));
+		dhd->dhd_state = dhd_state;
+		dhd_detach(&dhd->pub);
+		dhd_free(&dhd->pub);
+	}
+
+dhd_null_flag:
+	return NULL;
+}
+
+int dhd_get_fw_mode(dhd_info_t *dhdinfo)
+{
+	if (strstr(dhdinfo->fw_path, "_apsta") != NULL)
+		return DHD_FLAG_HOSTAP_MODE;
+	if (strstr(dhdinfo->fw_path, "_p2p") != NULL)
+		return DHD_FLAG_P2P_MODE;
+	if (strstr(dhdinfo->fw_path, "_ibss") != NULL)
+		return DHD_FLAG_IBSS_MODE;
+	if (strstr(dhdinfo->fw_path, "_mfg") != NULL)
+		return DHD_FLAG_MFG_MODE;
+
+	return DHD_FLAG_STA_MODE;
+}
+
+int dhd_bus_get_fw_mode(dhd_pub_t *dhdp)
+{
+	return dhd_get_fw_mode(dhdp->info);
+}
+
+extern char * nvram_get(const char *name);
+bool dhd_update_fw_nv_path(dhd_info_t *dhdinfo)
+{
+	int fw_len;
+	int nv_len;
+	int clm_len;
+	int conf_len;
+	int sig_len;
+	const char *fw = NULL;
+	const char *nv = NULL;
+	const char *clm = NULL;
+	const char *conf = NULL;
+#ifdef DHD_UCODE_DOWNLOAD
+	int uc_len;
+	const char *uc = NULL;
+#endif /* DHD_UCODE_DOWNLOAD */
+	wifi_adapter_info_t *adapter = dhdinfo->adapter;
+	int fw_path_len = sizeof(dhdinfo->fw_path);
+	int nv_path_len = sizeof(dhdinfo->nv_path);
+	int clm_path_len = sizeof(dhdinfo->clm_path);
+	int sig_path_len = sizeof(dhdinfo->sig_path);
+
+	/* Update firmware and nvram path. The path may be from adapter info or module parameter
+	 * The path from adapter info is used for initialization only (as it won't change).
+	 *
+	 * The firmware_path/nvram_path module parameter may be changed by the system at run
+	 * time. When it changes we need to copy it to dhdinfo->fw_path. Also Android private
+	 * command may change dhdinfo->fw_path. As such we need to clear the path info in
+	 * module parameter after it is copied. We won't update the path until the module parameter
+	 * is changed again (first character is not '\0')
+	 */
+
+	/* set default firmware and nvram path for built-in type driver */
+//	if (!dhd_download_fw_on_driverload) {
+#ifdef DHD_LINUX_STD_FW_API
+		fw = DHD_FW_NAME;
+		nv = DHD_NVRAM_NAME;
+#else
+#ifdef CONFIG_BCMDHD_FW_PATH
+		fw = VENDOR_PATH CONFIG_BCMDHD_FW_PATH;
+#endif /* CONFIG_BCMDHD_FW_PATH */
+#ifdef CONFIG_BCMDHD_NVRAM_PATH
+		nv = VENDOR_PATH CONFIG_BCMDHD_NVRAM_PATH;
+#endif /* CONFIG_BCMDHD_NVRAM_PATH */
+#endif /* DHD_LINUX_STD_FW_API */
+//	}
+
+	/* check if we need to initialize the path */
+	if (dhdinfo->fw_path[0] == '\0') {
+		if (adapter && adapter->fw_path && adapter->fw_path[0] != '\0') {
+			fw = adapter->fw_path;
+		}
+	}
+
+	if (dhdinfo->nv_path[0] == '\0') {
+		if (adapter && adapter->nv_path && adapter->nv_path[0] != '\0')
+			nv = adapter->nv_path;
+	}
+	if (dhdinfo->clm_path[0] == '\0') {
+		if (adapter && adapter->clm_path && adapter->clm_path[0] != '\0')
+			clm = adapter->clm_path;
+	}
+	if (dhdinfo->conf_path[0] == '\0') {
+		if (adapter && adapter->conf_path && adapter->conf_path[0] != '\0')
+			conf = adapter->conf_path;
+	}
+
+	/* Use module parameter if it is valid, EVEN IF the path has not been initialized
+	 *
+	 * TODO: need a solution for multi-chip, can't use the same firmware for all chips
+	 */
+	if (firmware_path[0] != '\0') {
+		/* Newline is getting added sometimes when firmware_path module parameter
+		 * is updated via command line using echo command, due to which
+		 * file not found error is seen, hence replacing '\n' with '\0'.
+		 */
+		if (firmware_path[strlen(firmware_path)-1] == '\n') {
+			firmware_path[strlen(firmware_path)-1] = '\0';
+		}
+		fw = firmware_path;
+	}
+
+	if (nvram_path[0] != '\0') {
+		if (nvram_path[strlen(nvram_path)-1] == '\n') {
+			nvram_path[strlen(nvram_path)-1] = '\0';
+		}
+		nv = nvram_path;
+	}
+
+	if (clm_path[0] != '\0') {
+		if (clm_path[strlen(clm_path)-1] == '\n') {
+			clm_path[strlen(clm_path)-1] = '\0';
+		}
+		clm = clm_path;
+	}
+
+	if (config_path[0] != '\0') {
+		if (config_path[strlen(config_path)-1] == '\n') {
+			config_path[strlen(config_path)-1] = '\0';
+		}
+		conf = config_path;
+	}
+
+	if (signature_path[0] != '\0') {
+		if (signature_path[strlen(signature_path) - 1] == '\n') {
+			signature_path[strlen(signature_path) - 1] = '\0';
+		}
+	}
+
+#ifdef DHD_UCODE_DOWNLOAD
+	if (ucode_path[0] != '\0')
+		uc = ucode_path;
+#endif /* DHD_UCODE_DOWNLOAD */
+
+#ifdef BCM_ROUTER_DHD
+	if (!fw) {
+		char var[32];
+
+		snprintf(var, sizeof(var), "firmware_path%d", dhdinfo->unit);
+		fw = nvram_get(var);
+	}
+	if (!nv) {
+		char var[32];
+
+		snprintf(var, sizeof(var), "nvram_path%d", dhdinfo->unit);
+		nv = nvram_get(var);
+	}
+	DHD_ERROR(("dhd:%d: fw path:%s nv path:%s\n", dhdinfo->unit, fw, nv));
+#endif
+
+	if (fw && fw[0] != '\0') {
+		fw_len = strlen(fw);
+		if (fw_len >= fw_path_len) {
+			DHD_ERROR(("fw path len exceeds max len of dhdinfo->fw_path\n"));
+			return FALSE;
+		}
+		strlcpy(dhdinfo->fw_path, fw, fw_path_len);
+	}
+	if (nv && nv[0] != '\0') {
+		nv_len = strlen(nv);
+		if (nv_len >= nv_path_len) {
+			DHD_ERROR(("nvram path len exceeds max len of dhdinfo->nv_path\n"));
+			return FALSE;
+		}
+		memset(dhdinfo->nv_path, 0, nv_path_len);
+		strlcpy(dhdinfo->nv_path, nv, nv_path_len);
+#ifdef DHD_USE_SINGLE_NVRAM_FILE
+		/* Remove "_net" or "_mfg" tag from current nvram path */
+		{
+			char *nvram_tag = "nvram_";
+			char *ext_tag = ".txt";
+			char *sp_nvram = strnstr(dhdinfo->nv_path, nvram_tag, nv_path_len);
+			bool valid_buf = sp_nvram && ((uint32)(sp_nvram + strlen(nvram_tag) +
+				strlen(ext_tag) - dhdinfo->nv_path) <= nv_path_len);
+			if (valid_buf) {
+				char *sp = sp_nvram + strlen(nvram_tag) - 1;
+				uint32 padding_size = (uint32)(dhdinfo->nv_path +
+					nv_path_len - sp);
+				memset(sp, 0, padding_size);
+				strncat(dhdinfo->nv_path, ext_tag, strlen(ext_tag));
+				nv_len = strlen(dhdinfo->nv_path);
+				DHD_INFO(("%s: new nvram path = %s\n",
+					__FUNCTION__, dhdinfo->nv_path));
+			} else if (sp_nvram) {
+				DHD_ERROR(("%s: buffer space for nvram path is not enough\n",
+					__FUNCTION__));
+				return FALSE;
+			} else {
+				DHD_ERROR(("%s: Couldn't find the nvram tag. current"
+					" nvram path = %s\n", __FUNCTION__, dhdinfo->nv_path));
+			}
+		}
+#endif /* DHD_USE_SINGLE_NVRAM_FILE */
+	}
+	/* CLM blob */
+	if (clm && clm[0] != '\0') {
+		clm_len = strlen(clm);
+		if (clm_len >= clm_path_len) {
+			DHD_ERROR(("clm path len exceeds max len of dhdinfo->clm_path\n"));
+			return FALSE;
+		}
+		strlcpy(dhdinfo->clm_path, clm, clm_path_len);
+	}
+
+	if (conf && conf[0] != '\0') {
+		conf_len = strlen(conf);
+		if (conf_len >= sizeof(dhdinfo->conf_path)) {
+			DHD_ERROR(("config path len exceeds max len of dhdinfo->conf_path\n"));
+			return FALSE;
+		}
+		strncpy(dhdinfo->conf_path, conf, sizeof(dhdinfo->conf_path));
+		if (dhdinfo->conf_path[conf_len-1] == '\n')
+		       dhdinfo->conf_path[conf_len-1] = '\0';
+	}
+	if (signature_path[0] != '\0') {
+		sig_len = strlen(signature_path);
+		if (sig_len >= sig_path_len) {
+			DHD_ERROR(("signature path len exceeds max len of dhdinfo->sig_path\n"));
+			return FALSE;
+		}
+		strlcpy(dhdinfo->sig_path, signature_path, sig_path_len);
+	}
+
+#ifdef DHD_UCODE_DOWNLOAD
+	if (uc && uc[0] != '\0') {
+		uc_len = strlen(uc);
+		if (uc_len >= sizeof(dhdinfo->uc_path)) {
+			DHD_ERROR(("uc path len exceeds max len of dhdinfo->uc_path\n"));
+			return FALSE;
+		}
+		strlcpy(dhdinfo->uc_path, uc, sizeof(dhdinfo->uc_path));
+	}
+#endif /* DHD_UCODE_DOWNLOAD */
+
+#if 0
+	/* clear the path in module parameter */
+	if (dhd_download_fw_on_driverload) {
+		firmware_path[0] = '\0';
+		nvram_path[0] = '\0';
+		signature_path[0] = '\0';
+	}
+#endif
+#ifdef DHD_UCODE_DOWNLOAD
+	ucode_path[0] = '\0';
+	DHD_ERROR(("ucode path: %s\n", dhdinfo->uc_path));
+#endif /* DHD_UCODE_DOWNLOAD */
+
+#ifndef BCMEMBEDIMAGE
+	/* fw_path and nv_path are not mandatory for BCMEMBEDIMAGE */
+	if (dhdinfo->fw_path[0] == '\0') {
+		DHD_ERROR(("firmware path not found\n"));
+		return FALSE;
+	}
+	if (dhdinfo->nv_path[0] == '\0') {
+		DHD_ERROR(("nvram path not found\n"));
+		return FALSE;
+	}
+#endif /* BCMEMBEDIMAGE */
+
+	return TRUE;
+}
+
+#if defined(BT_OVER_SDIO)
+extern bool dhd_update_btfw_path(dhd_info_t *dhdinfo, char* btfw_path)
+{
+	int fw_len;
+	const char *fw = NULL;
+	wifi_adapter_info_t *adapter = dhdinfo->adapter;
+
+	/* Update bt firmware path. The path may be from adapter info or module parameter
+	 * The path from adapter info is used for initialization only (as it won't change).
+	 *
+	 * The btfw_path module parameter may be changed by the system at run
+	 * time. When it changes we need to copy it to dhdinfo->btfw_path. Also Android private
+	 * command may change dhdinfo->btfw_path. As such we need to clear the path info in
+	 * module parameter after it is copied. We won't update the path until the module parameter
+	 * is changed again (first character is not '\0')
+	 */
+
+	/* set default firmware and nvram path for built-in type driver */
+	if (!dhd_download_fw_on_driverload) {
+#ifdef CONFIG_BCMDHD_BTFW_PATH
+		fw = CONFIG_BCMDHD_BTFW_PATH;
+#endif /* CONFIG_BCMDHD_FW_PATH */
+	}
+
+	/* check if we need to initialize the path */
+	if (dhdinfo->btfw_path[0] == '\0') {
+		if (adapter && adapter->btfw_path && adapter->btfw_path[0] != '\0')
+			fw = adapter->btfw_path;
+	}
+
+	/* Use module parameter if it is valid, EVEN IF the path has not been initialized
+	 */
+	if (btfw_path[0] != '\0')
+		fw = btfw_path;
+
+	if (fw && fw[0] != '\0') {
+		fw_len = strlen(fw);
+		if (fw_len >= sizeof(dhdinfo->btfw_path)) {
+			DHD_ERROR(("fw path len exceeds max len of dhdinfo->btfw_path\n"));
+			return FALSE;
+		}
+		strlcpy(dhdinfo->btfw_path, fw, sizeof(dhdinfo->btfw_path));
+	}
+
+	/* clear the path in module parameter */
+	btfw_path[0] = '\0';
+
+	if (dhdinfo->btfw_path[0] == '\0') {
+		DHD_ERROR(("bt firmware path not found\n"));
+		return FALSE;
+	}
+
+	return TRUE;
+}
+#endif /* defined (BT_OVER_SDIO) */
+
+#if defined(BT_OVER_SDIO)
+wlan_bt_handle_t dhd_bt_get_pub_hndl(void)
+{
+	DHD_ERROR(("%s: g_dhd_pub %p\n", __FUNCTION__, g_dhd_pub));
+	/* assuming that dhd_pub_t type pointer is available from a global variable */
+	return (wlan_bt_handle_t) g_dhd_pub;
+} EXPORT_SYMBOL(dhd_bt_get_pub_hndl);
+
+int dhd_download_btfw(wlan_bt_handle_t handle, char* btfw_path)
+{
+	int ret = -1;
+	dhd_pub_t *dhdp = (dhd_pub_t *)handle;
+	dhd_info_t *dhd = (dhd_info_t*)dhdp->info;
+
+	/* Download BT firmware image to the dongle */
+	if (dhd->pub.busstate == DHD_BUS_DATA && dhd_update_btfw_path(dhd, btfw_path)) {
+		DHD_INFO(("%s: download btfw from: %s\n", __FUNCTION__, dhd->btfw_path));
+		ret = dhd_bus_download_btfw(dhd->pub.bus, dhd->pub.osh, dhd->btfw_path);
+		if (ret < 0) {
+			DHD_ERROR(("%s: failed to download btfw from: %s\n",
+				__FUNCTION__, dhd->btfw_path));
+			return ret;
+		}
+	}
+	return ret;
+} EXPORT_SYMBOL(dhd_download_btfw);
+#endif /* defined (BT_OVER_SDIO) */
+
+#ifndef BCMDBUS
+int
+dhd_bus_start(dhd_pub_t *dhdp)
+{
+	int ret = -1;
+	dhd_info_t *dhd = (dhd_info_t*)dhdp->info;
+	unsigned long flags;
+
+#if defined(DHD_DEBUG) && defined(BCMSDIO)
+	int fw_download_start = 0, fw_download_end = 0, f2_sync_start = 0, f2_sync_end = 0;
+#endif /* DHD_DEBUG && BCMSDIO */
+	ASSERT(dhd);
+
+	DHD_TRACE(("Enter %s:\n", __FUNCTION__));
+	dhdp->memdump_type = 0;
+	dhdp->dongle_trap_occured = 0;
+	dhd->pub.dsack_hc_due_to_isr_delay = 0;
+	dhd->pub.dsack_hc_due_to_dpc_delay = 0;
+	dhdp->dongle_trap_during_wifi_onoff = 0;
+#ifdef DHD_SSSR_DUMP
+	dhdp->collect_sssr = FALSE;
+#endif /* DHD_SSSR_DUMP */
+#ifdef DHD_SDTC_ETB_DUMP
+	dhdp->collect_sdtc = FALSE;
+#endif /* DHD_SDTC_ETB_DUMP */
+#if defined(BCMPCIE)
+	if (dhdp->extended_trap_data) {
+		memset(dhdp->extended_trap_data, 0, BCMPCIE_EXT_TRAP_DATA_MAXLEN);
+	}
+#endif /* BCMPCIE */
+#ifdef DHD_SSSR_DUMP
+	/* Flag to indicate sssr dump is collected */
+	dhdp->sssr_dump_collected = 0;
+#endif /* DHD_SSSR_DUMP */
+	dhdp->iovar_timeout_occured = 0;
+#ifdef PCIE_FULL_DONGLE
+	dhdp->d3ack_timeout_occured = 0;
+	dhdp->livelock_occured = 0;
+	dhdp->pktid_audit_failed = 0;
+	dhdp->pktid_invalid_occured = 0;
+#endif /* PCIE_FULL_DONGLE */
+	dhd->pub.iface_op_failed = 0;
+	dhd->pub.scan_timeout_occurred = 0;
+	dhd->pub.scan_busy_occurred = 0;
+	dhd->pub.p2p_disc_busy_occurred = 0;
+	/* Retain BH induced errors and clear induced error during initialize */
+	if (dhd->pub.dhd_induce_error) {
+		dhd->pub.dhd_induce_bh_error = dhd->pub.dhd_induce_error;
+	}
+	dhd->pub.dhd_induce_error = DHD_INDUCE_ERROR_CLEAR;
+#ifdef DHD_MAP_PKTID_LOGGING
+	dhd->pub.enable_pktid_log_dump = FALSE;
+#endif /* DHD_MAP_PKTID_LOGGING */
+#ifdef DHD_SUPPORT_SPMI_MODE
+	dhd->pub.dhd_spmi_mode = spmi_mode;
+#endif /* DHD_SUPPORT_SPMI_MODE */
+	dhd->pub.tput_test_done = FALSE;
+
+	dhd->pub.p2p_disc_busy_cnt = 0;
+#ifdef PROP_TXSTATUS
+	dhd->pub.simutx_limit = WL_TXSTATUS_FREERUNCTR_MASK;
+#endif /* PROP_TXSTATUS */
+	/* try to download image and nvram to the dongle */
+	if  (dhd->pub.busstate == DHD_BUS_DOWN && dhd_update_fw_nv_path(dhd)) {
+		/* Indicate FW Download has not yet done */
+		dhd->pub.fw_download_status = FW_DOWNLOAD_IN_PROGRESS;
+		DHD_INFO(("%s download fw %s, nv %s, conf %s\n",
+			__FUNCTION__, dhd->fw_path, dhd->nv_path, dhd->conf_path));
+#if defined(DHD_DEBUG) && defined(BCMSDIO)
+		fw_download_start = OSL_SYSUPTIME();
+#endif /* DHD_DEBUG && BCMSDIO */
+		dhd_bus_set_signature_path(dhd->pub.bus, dhd->sig_path);
+		ret = dhd_bus_download_firmware(dhd->pub.bus, dhd->pub.osh,
+			dhd->fw_path, dhd->nv_path, dhd->clm_path, dhd->conf_path);
+#if defined(DHD_DEBUG) && defined(BCMSDIO)
+		fw_download_end = OSL_SYSUPTIME();
+#endif /* DHD_DEBUG && BCMSDIO */
+		if (ret < 0) {
+			DHD_ERROR(("%s: failed to download firmware %s\n",
+			          __FUNCTION__, dhd->fw_path));
+			return ret;
+		}
+		/* Indicate FW Download has succeeded */
+		dhd->pub.fw_download_status = FW_DOWNLOAD_DONE;
+	}
+	if (dhd->pub.busstate != DHD_BUS_LOAD) {
+		return -ENETDOWN;
+	}
+
+#ifdef BCMSDIO
+	dhd_os_sdlock(dhdp);
+#endif /* BCMSDIO */
+
+	/* Start the watchdog timer */
+	dhd->pub.tickcnt = 0;
+	dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms);
+
+	/* Bring up the bus */
+	if ((ret = dhd_bus_init(&dhd->pub, FALSE)) != 0) {
+
+		DHD_ERROR(("%s, dhd_bus_init failed %d\n", __FUNCTION__, ret));
+#ifdef BCMSDIO
+		dhd_os_sdunlock(dhdp);
+#endif /* BCMSDIO */
+		return ret;
+	}
+#if defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID) || defined(BCMPCIE_OOB_HOST_WAKE)
+	/* Host registration for OOB interrupt */
+	if (dhd_bus_oob_intr_register(dhdp)) {
+		/* deactivate timer and wait for the handler to finish */
+#if !defined(BCMPCIE_OOB_HOST_WAKE)
+		DHD_GENERAL_LOCK(&dhd->pub, flags);
+		dhd->wd_timer_valid = FALSE;
+		DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+		del_timer_sync(&dhd->timer);
+
+#endif /* !BCMPCIE_OOB_HOST_WAKE */
+		DHD_STOP_RPM_TIMER(&dhd->pub);
+
+		DHD_ERROR(("%s Host failed to register for OOB\n", __FUNCTION__));
+		DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
+		return -ENODEV;
+	}
+
+#if defined(BCMPCIE_OOB_HOST_WAKE)
+	dhd_bus_oob_intr_set(dhdp, TRUE);
+#else
+	/* Enable oob at firmware */
+	dhd_enable_oob_intr(dhd->pub.bus, TRUE);
+#endif /* BCMPCIE_OOB_HOST_WAKE */
+#elif defined(FORCE_WOWLAN)
+	/* Enable oob at firmware */
+	dhd_enable_oob_intr(dhd->pub.bus, TRUE);
+#endif /* OOB_INTR_ONLY || BCMSPI_ANDROID || BCMPCIE_OOB_HOST_WAKE */
+#ifdef PCIE_FULL_DONGLE
+	{
+		/* max_h2d_rings includes H2D common rings */
+		uint32 max_h2d_rings = dhd_bus_max_h2d_queues(dhd->pub.bus);
+
+		DHD_INFO(("%s: Initializing %u h2drings\n", __FUNCTION__,
+			max_h2d_rings));
+		if ((ret = dhd_flow_rings_init(&dhd->pub, max_h2d_rings)) != BCME_OK) {
+#ifdef BCMSDIO
+			dhd_os_sdunlock(dhdp);
+#endif /* BCMSDIO */
+			return ret;
+		}
+	}
+#endif /* PCIE_FULL_DONGLE */
+
+	/* set default value for now. Will be updated again in dhd_preinit_ioctls()
+	 * after querying FW
+	 */
+	dhdp->event_log_max_sets = NUM_EVENT_LOG_SETS;
+	dhdp->event_log_max_sets_queried = FALSE;
+
+	dhdp->smmu_fault_occurred = 0;
+#ifdef DNGL_AXI_ERROR_LOGGING
+	dhdp->axi_error = FALSE;
+#endif /* DNGL_AXI_ERROR_LOGGING */
+
+	/* Do protocol initialization necessary for IOCTL/IOVAR */
+	ret = dhd_prot_init(&dhd->pub);
+	if (unlikely(ret) != BCME_OK) {
+		DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
+		return ret;
+	}
+
+	/* If bus is not ready, can't come up */
+	if (dhd->pub.busstate != DHD_BUS_DATA) {
+		DHD_GENERAL_LOCK(&dhd->pub, flags);
+		dhd->wd_timer_valid = FALSE;
+		DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+		del_timer_sync(&dhd->timer);
+		DHD_ERROR(("%s failed bus is not ready\n", __FUNCTION__));
+		DHD_STOP_RPM_TIMER(&dhd->pub);
+#ifdef BCMSDIO
+		dhd_os_sdunlock(dhdp);
+#endif /* BCMSDIO */
+		DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
+		return -ENODEV;
+	}
+
+#ifdef BCMSDIO
+	dhd_os_sdunlock(dhdp);
+#endif /* BCMSDIO */
+
+	/* Bus is ready, query any dongle information */
+	/* XXX Since dhd_sync_with_dongle can sleep, should module count surround it? */
+#if defined(DHD_DEBUG) && defined(BCMSDIO)
+	f2_sync_start = OSL_SYSUPTIME();
+#endif /* DHD_DEBUG && BCMSDIO */
+	if ((ret = dhd_sync_with_dongle(&dhd->pub)) < 0) {
+		DHD_GENERAL_LOCK(&dhd->pub, flags);
+		dhd->wd_timer_valid = FALSE;
+		DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+		del_timer_sync(&dhd->timer);
+		DHD_ERROR(("%s failed to sync with dongle\n", __FUNCTION__));
+		DHD_OS_WD_WAKE_UNLOCK(&dhd->pub);
+		return ret;
+	}
+
+#if defined(BCMPCIE)
+	/* XXX: JIRA SWWLAN-139454: Added L1ss enable
+	 * after firmware download completion due to link down issue
+	 * JIRA SWWLAN-142236: Amendment - Changed L1ss enable point
+	 */
+	DHD_RPM(("%s: Enable L1ss EP side\n", __FUNCTION__));
+	dhd_plat_l1ss_ctrl(1);
+#endif /* BCMPCIE */
+
+#if defined(DHD_DEBUG) && defined(BCMSDIO)
+	f2_sync_end = OSL_SYSUPTIME();
+	DHD_ERROR(("Time taken for FW download and F2 ready is: %d msec\n",
+			(fw_download_end - fw_download_start) + (f2_sync_end - f2_sync_start)));
+#endif /* DHD_DEBUG && BCMSDIO */
+
+#ifdef ARP_OFFLOAD_SUPPORT
+	if (dhd->pend_ipaddr) {
+#ifdef AOE_IP_ALIAS_SUPPORT
+		/* XXX Assume pending ip address is belong to primary interface */
+		aoe_update_host_ipv4_table(&dhd->pub, dhd->pend_ipaddr, TRUE, 0);
+#endif /* AOE_IP_ALIAS_SUPPORT */
+		dhd->pend_ipaddr = 0;
+	}
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+#if defined(BCM_ROUTER_DHD)
+	bzero(&dhd->pub.dhd_tm_dwm_tbl, sizeof(dhd_trf_mgmt_dwm_tbl_t));
+#endif /* BCM_ROUTER_DHD */
+	return 0;
+}
+#endif /* !BCMDBUS */
+
+#ifdef WLTDLS
+int _dhd_tdls_enable(dhd_pub_t *dhd, bool tdls_on, bool auto_on, struct ether_addr *mac)
+{
+	uint32 tdls = tdls_on;
+	int ret = 0;
+	uint32 tdls_auto_op = 0;
+	uint32 tdls_idle_time = CUSTOM_TDLS_IDLE_MODE_SETTING;
+	int32 tdls_rssi_high = CUSTOM_TDLS_RSSI_THRESHOLD_HIGH;
+	int32 tdls_rssi_low = CUSTOM_TDLS_RSSI_THRESHOLD_LOW;
+	uint32 tdls_pktcnt_high = CUSTOM_TDLS_PCKTCNT_THRESHOLD_HIGH;
+	uint32 tdls_pktcnt_low = CUSTOM_TDLS_PCKTCNT_THRESHOLD_LOW;
+
+	BCM_REFERENCE(mac);
+	if (!FW_SUPPORTED(dhd, tdls))
+		return BCME_UNSUPPORTED;
+
+	if (dhd->tdls_enable == tdls_on)
+		goto auto_mode;
+	ret = dhd_iovar(dhd, 0, "tdls_enable", (char *)&tdls, sizeof(tdls), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: tdls %d failed %d\n", __FUNCTION__, tdls, ret));
+		goto exit;
+	}
+	dhd->tdls_enable = tdls_on;
+auto_mode:
+
+	tdls_auto_op = auto_on;
+	ret = dhd_iovar(dhd, 0, "tdls_auto_op", (char *)&tdls_auto_op, sizeof(tdls_auto_op), NULL,
+			0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: tdls_auto_op failed %d\n", __FUNCTION__, ret));
+		goto exit;
+	}
+
+	if (tdls_auto_op) {
+		ret = dhd_iovar(dhd, 0, "tdls_idle_time", (char *)&tdls_idle_time,
+				sizeof(tdls_idle_time), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: tdls_idle_time failed %d\n", __FUNCTION__, ret));
+			goto exit;
+		}
+		ret = dhd_iovar(dhd, 0, "tdls_rssi_high", (char *)&tdls_rssi_high,
+				sizeof(tdls_rssi_high), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: tdls_rssi_high failed %d\n", __FUNCTION__, ret));
+			goto exit;
+		}
+		ret = dhd_iovar(dhd, 0, "tdls_rssi_low", (char *)&tdls_rssi_low,
+				sizeof(tdls_rssi_low), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: tdls_rssi_low failed %d\n", __FUNCTION__, ret));
+			goto exit;
+		}
+		ret = dhd_iovar(dhd, 0, "tdls_trigger_pktcnt_high", (char *)&tdls_pktcnt_high,
+				sizeof(tdls_pktcnt_high), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: tdls_trigger_pktcnt_high failed %d\n", __FUNCTION__, ret));
+			goto exit;
+		}
+		ret = dhd_iovar(dhd, 0, "tdls_trigger_pktcnt_low", (char *)&tdls_pktcnt_low,
+				sizeof(tdls_pktcnt_low), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: tdls_trigger_pktcnt_low failed %d\n", __FUNCTION__, ret));
+			goto exit;
+		}
+	}
+
+exit:
+	return ret;
+}
+
+int dhd_tdls_enable(struct net_device *dev, bool tdls_on, bool auto_on, struct ether_addr *mac)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	int ret = 0;
+	if (dhd)
+		ret = _dhd_tdls_enable(&dhd->pub, tdls_on, auto_on, mac);
+	else
+		ret = BCME_ERROR;
+	return ret;
+}
+
+int
+dhd_tdls_set_mode(dhd_pub_t *dhd, bool wfd_mode)
+{
+	int ret = 0;
+	bool auto_on = false;
+	uint32 mode =  wfd_mode;
+
+#ifdef ENABLE_TDLS_AUTO_MODE
+	if (wfd_mode) {
+		auto_on = false;
+	} else {
+		auto_on = true;
+	}
+#else
+	auto_on = false;
+#endif /* ENABLE_TDLS_AUTO_MODE */
+	ret = _dhd_tdls_enable(dhd, false, auto_on, NULL);
+	if (ret < 0) {
+		DHD_ERROR(("Disable tdls_auto_op failed. %d\n", ret));
+		return ret;
+	}
+
+	ret = dhd_iovar(dhd, 0, "tdls_wfd_mode", (char *)&mode, sizeof(mode), NULL, 0, TRUE);
+	if ((ret < 0) && (ret != BCME_UNSUPPORTED)) {
+		DHD_ERROR(("%s: tdls_wfd_mode faile_wfd_mode %d\n", __FUNCTION__, ret));
+		return ret;
+	}
+
+	ret = _dhd_tdls_enable(dhd, true, auto_on, NULL);
+	if (ret < 0) {
+		DHD_ERROR(("enable tdls_auto_op failed. %d\n", ret));
+		return ret;
+	}
+
+	dhd->tdls_mode = mode;
+	return ret;
+}
+#ifdef PCIE_FULL_DONGLE
+int dhd_tdls_update_peer_info(dhd_pub_t *dhdp, wl_event_msg_t *event)
+{
+	dhd_pub_t *dhd_pub = dhdp;
+	tdls_peer_node_t *cur = dhd_pub->peer_tbl.node;
+	tdls_peer_node_t *new = NULL, *prev = NULL;
+	int ifindex = dhd_ifname2idx(dhd_pub->info, event->ifname);
+	uint8 *da = (uint8 *)&event->addr.octet[0];
+	bool connect = FALSE;
+	uint32 reason = ntoh32(event->reason);
+	unsigned long flags;
+
+	/* No handling needed for peer discovered reason */
+	if (reason == WLC_E_TDLS_PEER_DISCOVERED) {
+		return BCME_ERROR;
+	}
+	if (reason == WLC_E_TDLS_PEER_CONNECTED)
+		connect = TRUE;
+	else if (reason == WLC_E_TDLS_PEER_DISCONNECTED)
+		connect = FALSE;
+	else
+	{
+		DHD_ERROR(("%s: TDLS Event reason is unknown\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+	if (ifindex == DHD_BAD_IF)
+		return BCME_ERROR;
+
+	if (connect) {
+		while (cur != NULL) {
+			if (!memcmp(da, cur->addr, ETHER_ADDR_LEN)) {
+				DHD_ERROR(("%s: TDLS Peer exist already %d\n",
+					__FUNCTION__, __LINE__));
+				return BCME_ERROR;
+			}
+			cur = cur->next;
+		}
+
+		new = MALLOC(dhd_pub->osh, sizeof(tdls_peer_node_t));
+		if (new == NULL) {
+			DHD_ERROR(("%s: Failed to allocate memory\n", __FUNCTION__));
+			return BCME_ERROR;
+		}
+		memcpy(new->addr, da, ETHER_ADDR_LEN);
+		DHD_TDLS_LOCK(&dhdp->tdls_lock, flags);
+		new->next = dhd_pub->peer_tbl.node;
+		dhd_pub->peer_tbl.node = new;
+		dhd_pub->peer_tbl.tdls_peer_count++;
+		DHD_ERROR(("%s: Add TDLS peer, count=%d " MACDBG "\n",
+			__FUNCTION__, dhd_pub->peer_tbl.tdls_peer_count,
+			MAC2STRDBG((char *)da)));
+		DHD_TDLS_UNLOCK(&dhdp->tdls_lock, flags);
+
+	} else {
+		while (cur != NULL) {
+			if (!memcmp(da, cur->addr, ETHER_ADDR_LEN)) {
+				dhd_flow_rings_delete_for_peer(dhd_pub, (uint8)ifindex, da);
+				DHD_TDLS_LOCK(&dhdp->tdls_lock, flags);
+				if (prev)
+					prev->next = cur->next;
+				else
+					dhd_pub->peer_tbl.node = cur->next;
+				MFREE(dhd_pub->osh, cur, sizeof(tdls_peer_node_t));
+				dhd_pub->peer_tbl.tdls_peer_count--;
+				DHD_ERROR(("%s: Remove TDLS peer, count=%d " MACDBG "\n",
+					__FUNCTION__, dhd_pub->peer_tbl.tdls_peer_count,
+					MAC2STRDBG((char *)da)));
+				DHD_TDLS_UNLOCK(&dhdp->tdls_lock, flags);
+				return BCME_OK;
+			}
+			prev = cur;
+			cur = cur->next;
+		}
+		DHD_ERROR(("%s: TDLS Peer Entry Not found\n", __FUNCTION__));
+	}
+	return BCME_OK;
+}
+#endif /* PCIE_FULL_DONGLE */
+#endif /* BCMDBUS */
+
+bool dhd_is_concurrent_mode(dhd_pub_t *dhd)
+{
+	if (!dhd)
+		return FALSE;
+
+	if (dhd->op_mode & DHD_FLAG_CONCURR_MULTI_CHAN_MODE)
+		return TRUE;
+	else if ((dhd->op_mode & DHD_FLAG_CONCURR_SINGLE_CHAN_MODE) ==
+		DHD_FLAG_CONCURR_SINGLE_CHAN_MODE)
+		return TRUE;
+	else
+		return FALSE;
+}
+
+#if defined(WLADPS)
+#ifdef WL_BAM
+static int
+dhd_check_adps_bad_ap(dhd_pub_t *dhd)
+{
+	struct net_device *ndev;
+	struct bcm_cfg80211 *cfg;
+	struct wl_profile *profile;
+	struct ether_addr bssid;
+
+	if (!dhd_is_associated(dhd, 0, NULL)) {
+		DHD_ERROR(("%s - not associated\n", __FUNCTION__));
+		return BCME_OK;
+	}
+
+	ndev = dhd_linux_get_primary_netdev(dhd);
+	if (!ndev) {
+		DHD_ERROR(("%s: Cannot find primary netdev\n", __FUNCTION__));
+		return -ENODEV;
+	}
+
+	cfg = wl_get_cfg(ndev);
+	if (!cfg) {
+		DHD_ERROR(("%s: Cannot find cfg\n", __FUNCTION__));
+		return -EINVAL;
+	}
+
+	profile = wl_get_profile_by_netdev(cfg, ndev);
+	if (!profile) {
+		DHD_ERROR(("%s : Cannot get profile\n", __FUNCTION__));
+		return -EINVAL;
+	}
+
+	memcpy(bssid.octet, profile->bssid, ETHER_ADDR_LEN);
+	if (wl_adps_bad_ap_check(cfg, &bssid)) {
+		if (wl_adps_enabled(cfg, ndev)) {
+			wl_adps_set_suspend(cfg, ndev, ADPS_SUSPEND);
+		}
+	}
+
+	return BCME_OK;
+}
+#endif	/* WL_BAM */
+
+int
+dhd_enable_adps(dhd_pub_t *dhd, uint8 on)
+{
+	int i;
+	int len;
+	int ret = BCME_OK;
+
+	bcm_iov_buf_t *iov_buf = NULL;
+	wl_adps_params_v1_t *data = NULL;
+
+	len = OFFSETOF(bcm_iov_buf_t, data) + sizeof(*data);
+	iov_buf = MALLOC(dhd->osh, len);
+	if (iov_buf == NULL) {
+		DHD_ERROR(("%s - failed to allocate %d bytes for iov_buf\n", __FUNCTION__, len));
+		ret = BCME_NOMEM;
+		goto exit;
+	}
+
+	iov_buf->version = WL_ADPS_IOV_VER;
+	iov_buf->len = sizeof(*data);
+	iov_buf->id = WL_ADPS_IOV_MODE;
+
+	data = (wl_adps_params_v1_t *)iov_buf->data;
+	data->version = ADPS_SUB_IOV_VERSION_1;
+	data->length = sizeof(*data);
+	data->mode = on;
+
+	for (i = 1; i <= MAX_BANDS; i++) {
+		data->band = i;
+		ret = dhd_iovar(dhd, 0, "adps", (char *)iov_buf, len, NULL, 0, TRUE);
+		if (ret < 0) {
+			if (ret == BCME_UNSUPPORTED) {
+				DHD_ERROR(("%s adps, UNSUPPORTED\n", __FUNCTION__));
+				ret = BCME_OK;
+				goto exit;
+			}
+			else {
+				DHD_ERROR(("%s fail to set adps %s for band %d (%d)\n",
+					__FUNCTION__, on ? "On" : "Off", i, ret));
+				goto exit;
+			}
+		}
+	}
+
+#ifdef WL_BAM
+	if (on) {
+		dhd_check_adps_bad_ap(dhd);
+	}
+#endif	/* WL_BAM */
+
+exit:
+	if (iov_buf) {
+		MFREE(dhd->osh, iov_buf, len);
+	}
+	return ret;
+}
+#endif /* WLADPS */
+
+int
+dhd_get_preserve_log_numbers(dhd_pub_t *dhd, uint64 *logset_mask)
+{
+	wl_el_set_type_t logset_type, logset_op;
+	wl_el_set_all_type_v1_t *logset_all_type_op = NULL;
+	bool use_logset_all_type = FALSE;
+	int ret = BCME_ERROR;
+	int err = 0;
+	uint8 i = 0;
+	int el_set_all_type_len;
+
+	if (!dhd || !logset_mask)
+		return BCME_BADARG;
+
+	el_set_all_type_len = OFFSETOF(wl_el_set_all_type_v1_t, set_type) +
+		(sizeof(wl_el_set_type_v1_t) * dhd->event_log_max_sets);
+
+	logset_all_type_op = (wl_el_set_all_type_v1_t *) MALLOC(dhd->osh, el_set_all_type_len);
+	if (logset_all_type_op == NULL) {
+		DHD_ERROR(("%s: failed to allocate %d bytes for logset_all_type_op\n",
+			__FUNCTION__, el_set_all_type_len));
+		return BCME_NOMEM;
+	}
+
+	*logset_mask = 0;
+	memset(&logset_type, 0, sizeof(logset_type));
+	memset(&logset_op, 0, sizeof(logset_op));
+#if defined(EVENT_LOG_SET_TYPE_VERSION_0)
+	logset_type.version = htod16(EVENT_LOG_SET_TYPE_VERSION_0);
+#else
+	logset_type.version = htod16(EVENT_LOG_SET_TYPE_CURRENT_VERSION);
+#endif
+	logset_type.len = htod16(sizeof(wl_el_set_type_t));
+
+	/* Try with set = event_log_max_sets, if fails, use legacy event_log_set_type */
+	logset_type.set = dhd->event_log_max_sets;
+	err = dhd_iovar(dhd, 0, "event_log_set_type", (char *)&logset_type, sizeof(logset_type),
+		(char *)logset_all_type_op, el_set_all_type_len, FALSE);
+	if (err == BCME_OK) {
+		DHD_ERROR(("%s: use optimised use_logset_all_type\n", __FUNCTION__));
+		use_logset_all_type = TRUE;
+	}
+
+	for (i = 0; i < dhd->event_log_max_sets; i++) {
+		if (use_logset_all_type) {
+			logset_op.type = logset_all_type_op->set_type[i].type_val;
+		} else {
+			logset_type.set = i;
+			err = dhd_iovar(dhd, 0, "event_log_set_type", (char *)&logset_type,
+				sizeof(logset_type), (char *)&logset_op, sizeof(logset_op), FALSE);
+		}
+		/* the iovar may return 'unsupported' error if a log set number is not present
+		* in the fw, so we should not return on error !
+		*/
+		if (err == BCME_OK &&
+				logset_op.type == EVENT_LOG_SET_TYPE_PRSRV) {
+			*logset_mask |= 0x01ULL << i;
+			ret = BCME_OK;
+			DHD_INFO(("[INIT] logset:%d is preserve/chatty\n", i));
+		}
+	}
+
+	MFREE(dhd->osh, logset_all_type_op, el_set_all_type_len);
+	return ret;
+}
+
+#ifndef OEM_ANDROID
+/* For non-android FC modular builds, override firmware preinited values */
+void
+dhd_override_fwprenit(dhd_pub_t * dhd)
+{
+	int ret = 0;
+
+	{
+		/* Disable bcn_li_bcn */
+		uint32 bcn_li_bcn = 0;
+		ret = dhd_iovar(dhd, 0, "bcn_li_bcn", (char *)&bcn_li_bcn,
+				sizeof(bcn_li_bcn), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: bcn_li_bcn failed:%d\n",
+				__FUNCTION__, ret));
+		}
+	}
+
+	{
+		/* Enable apsta */
+		uint32 apsta = 1;
+		ret = dhd_iovar(dhd, 0, "apsta", (char *)&apsta,
+				sizeof(apsta), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: apsta failed:%d\n",
+				__FUNCTION__, ret));
+		}
+	}
+
+	{
+		int ap_mode = 0;
+		if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_AP, (char *)&ap_mode,
+			sizeof(ap_mode), TRUE, 0)) < 0) {
+			DHD_ERROR(("%s: set apmode failed :%d\n", __FUNCTION__, ret));
+		}
+	}
+	{
+		/* Set PowerSave mode */
+		uint power_mode = PM_FAST;
+		(void) dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode,
+				sizeof(power_mode), TRUE, 0);
+	}
+}
+#endif /* !OEM_ANDROID */
+
+int
+dhd_get_fw_capabilities(dhd_pub_t * dhd)
+{
+
+	int ret = 0;
+	uint32 cap_buf_size = sizeof(dhd->fw_capabilities);
+	memset(dhd->fw_capabilities, 0, cap_buf_size);
+	ret = dhd_iovar(dhd, 0, "cap", NULL, 0, dhd->fw_capabilities, (cap_buf_size - 1),
+		FALSE);
+
+	if (ret < 0) {
+		DHD_ERROR(("%s: Get Capability failed (error=%d)\n",
+		__FUNCTION__, ret));
+		return ret;
+	}
+
+	memmove(&dhd->fw_capabilities[1], dhd->fw_capabilities, (cap_buf_size - 1));
+	dhd->fw_capabilities[0] = ' ';
+	dhd->fw_capabilities[cap_buf_size - 2] = ' ';
+	dhd->fw_capabilities[cap_buf_size - 1] = '\0';
+
+	return 0;
+}
+
+int
+dhd_optimised_preinit_ioctls(dhd_pub_t * dhd)
+{
+	int ret = 0;
+	/*  Room for "event_msgs_ext" + '\0' + bitvec  */
+	char iovbuf[WL_EVENTING_MASK_EXT_LEN + EVENTMSGS_EXT_STRUCT_SIZE + 16];
+	char *mask;
+	uint8 msglen;
+	eventmsgs_ext_t *eventmask_msg = NULL;
+	uint32 event_log_max_sets = 0;
+	char* iov_buf = NULL;
+	/* XXX: Use ret2 for return check of IOVARS that might return BCME_UNSUPPORTED,
+	*	based on FW build tag.
+	*/
+	int ret2 = 0;
+#if defined(WL_MONITOR) && defined(HOST_RADIOTAP_CONV)
+	uint monitor = 0;
+	dhd_info_t *dhdinfo = (dhd_info_t*)dhd->info;
+#endif /* WL_MONITOR */
+#if defined(BCMSUP_4WAY_HANDSHAKE)
+	uint32 sup_wpa = 1;
+#endif /* BCMSUP_4WAY_HANDSHAKE */
+
+	uint32 frameburst = CUSTOM_FRAMEBURST_SET;
+	uint wnm_bsstrans_resp = 0;
+#ifdef DHD_BUS_MEM_ACCESS
+	uint32 enable_memuse = 1;
+#endif /* DHD_BUS_MEM_ACCESS */
+#ifdef DHD_PM_CONTROL_FROM_FILE
+	uint power_mode = PM_FAST;
+#endif /* DHD_PM_CONTROL_FROM_FILE */
+	char buf[WLC_IOCTL_SMLEN];
+	char *ptr;
+#ifdef ROAM_ENABLE
+	uint roamvar = 0;
+#ifdef ROAM_AP_ENV_DETECTION
+	int roam_env_mode = 0;
+#endif /* ROAM_AP_ENV_DETECTION */
+#endif /* ROAM_ENABLE */
+#if defined(SOFTAP)
+	uint dtim = 1;
+#endif
+/* xxx andrey tmp fix for dk8000 build error  */
+	struct ether_addr p2p_ea;
+#ifdef BCMPCIE_OOB_HOST_WAKE
+	uint32 hostwake_oob = 0;
+#endif /* BCMPCIE_OOB_HOST_WAKE */
+	wl_wlc_version_t wlc_ver;
+#ifdef CUSTOM_OCL_RSSI_VAL
+	int ocl_rssi_threshold = CUSTOM_OCL_RSSI_VAL;
+#endif /* CUSTOM_OCL_RSSI_VAL */
+
+#if defined(WBTEXT) && defined(RRM_BCNREQ_MAX_CHAN_TIME)
+	uint32 rrm_bcn_req_thrtl_win = RRM_BCNREQ_MAX_CHAN_TIME * 2;
+	uint32 rrm_bcn_req_max_off_chan_time = RRM_BCNREQ_MAX_CHAN_TIME;
+#endif /* WBTEXT && RRM_BCNREQ_MAX_CHAN_TIME */
+
+#ifdef DISABLE_6G_SUPPORT
+	uint32 enable_6g = 0;
+#endif /* DISABLE_6G_SUPPORT */
+
+	uint32 d3_hostwake_delay = D3_HOSTWAKE_DELAY;
+#ifdef SUPPORT_MULTIPLE_CLMBLOB
+	char customer_clm_file_name[MAX_FILE_LEN] = {0, };
+#endif /* SUPPORT_MULTIPLE_CLMBLOB */
+	char* apply_clm;
+
+#ifdef PKT_FILTER_SUPPORT
+	dhd_pkt_filter_enable = TRUE;
+#endif /* PKT_FILTER_SUPPORT */
+#ifdef APF
+	dhd->apf_set = FALSE;
+#endif /* APF */
+#ifdef CUSTOM_SET_OCLOFF
+	dhd->ocl_off = FALSE;
+#endif /* CUSTOM_SET_OCLOFF */
+#ifdef SUPPORT_SET_TID
+	dhd->tid_mode = SET_TID_OFF;
+	dhd->target_uid = 0;
+	dhd->target_tid = 0;
+#endif /* SUPPORT_SET_TID */
+	DHD_TRACE(("Enter %s\n", __FUNCTION__));
+	dhd->op_mode = 0;
+
+#ifdef ARP_OFFLOAD_SUPPORT
+	/* arpoe will be applied from the supsend context */
+	dhd->arpoe_enable = TRUE;
+	dhd->arpol_configured = FALSE;
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+	/* clear AP flags */
+#if defined(CUSTOM_COUNTRY_CODE)
+	dhd->dhd_cflags &= ~WLAN_PLAT_AP_FLAG;
+#endif /* CUSTOM_COUNTRY_CODE */
+
+	/* query for 'ver' to get version info from firmware */
+	memset(buf, 0, sizeof(buf));
+	ptr = buf;
+	ret = dhd_iovar(dhd, 0, "ver", NULL, 0, (char *)&buf, sizeof(buf), FALSE);
+	if (ret < 0)
+		DHD_ERROR(("%s failed %d\n", __FUNCTION__, ret));
+	else {
+		bcmstrtok(&ptr, "\n", 0);
+		/* Print fw version info */
+		strncpy(fw_version, buf, FW_VER_STR_LEN);
+		fw_version[FW_VER_STR_LEN-1] = '\0';
+	}
+
+	/* query for 'wlc_ver' to get version info from firmware */
+	/* memsetting to zero */
+	memset_s(&wlc_ver, sizeof(wl_wlc_version_t), 0,
+		sizeof(wl_wlc_version_t));
+	ret = dhd_iovar(dhd, 0, "wlc_ver", NULL, 0, (char *)&wlc_ver,
+			sizeof(wl_wlc_version_t), FALSE);
+	if (ret < 0)
+		DHD_ERROR(("%s failed %d\n", __FUNCTION__, ret));
+	else {
+		dhd->wlc_ver_major = wlc_ver.wlc_ver_major;
+		dhd->wlc_ver_minor = wlc_ver.wlc_ver_minor;
+	}
+// mark flag for later blob checking
+	/* Set op_mode as MFG_MODE if WLTEST is present in "wl ver" */
+	if (strstr(fw_version, "WLTEST") != NULL) {
+		DHD_ERROR(("%s: wl ver has WLTEST, setting op_mode as DHD_FLAG_MFG_MODE\n",
+			__FUNCTION__));
+		op_mode = DHD_FLAG_MFG_MODE;
+	}
+	/* get a capabilities from firmware */
+	ret = dhd_get_fw_capabilities(dhd);
+
+	if (ret < 0) {
+		DHD_ERROR(("%s: Get Capability failed (error=%d)\n",
+			__FUNCTION__, ret));
+		goto done;
+	}
+
+	if ((!op_mode && dhd_get_fw_mode(dhd->info) == DHD_FLAG_MFG_MODE) ||
+		(op_mode == DHD_FLAG_MFG_MODE)) {
+		dhd->op_mode = DHD_FLAG_MFG_MODE;
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+		/* disable runtimePM by default in MFG mode. */
+		pm_runtime_disable(dhd_bus_to_dev(dhd->bus));
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+		/* Check and adjust IOCTL response timeout for Manufactring firmware */
+		dhd_os_set_ioctl_resp_timeout(MFG_IOCTL_RESP_TIMEOUT);
+		DHD_ERROR(("%s : Set IOCTL response time for Manufactring Firmware\n",
+			__FUNCTION__));
+
+#if defined(ARP_OFFLOAD_SUPPORT)
+		dhd->arpoe_enable = FALSE;
+#endif /* ARP_OFFLOAD_SUPPORT */
+#ifdef PKT_FILTER_SUPPORT
+		dhd_pkt_filter_enable = FALSE;
+#endif /* PKT_FILTER_SUPPORT */
+#ifndef CUSTOM_SET_ANTNPM
+		if (FW_SUPPORTED(dhd, rsdb)) {
+			wl_config_t rsdb_mode;
+			memset(&rsdb_mode, 0, sizeof(rsdb_mode));
+			ret = dhd_iovar(dhd, 0, "rsdb_mode", (char *)&rsdb_mode, sizeof(rsdb_mode),
+				NULL, 0, TRUE);
+			if (ret < 0) {
+				DHD_ERROR(("%s Disable rsdb_mode is failed ret= %d\n",
+					__FUNCTION__, ret));
+			}
+		}
+#endif /* !CUSTOM_SET_ANTNPM */
+	} else {
+		uint32 concurrent_mode = 0;
+		dhd_os_set_ioctl_resp_timeout(IOCTL_RESP_TIMEOUT);
+		DHD_INFO(("%s : Set IOCTL response time.\n", __FUNCTION__));
+
+		BCM_REFERENCE(concurrent_mode);
+
+		dhd->op_mode = DHD_FLAG_STA_MODE;
+
+		BCM_REFERENCE(p2p_ea);
+#if !defined(AP) && defined(WLP2P)
+		if ((concurrent_mode = dhd_get_concurrent_capabilites(dhd))) {
+			dhd->op_mode |= concurrent_mode;
+		}
+
+		/* Check if we are enabling p2p */
+		if (dhd->op_mode & DHD_FLAG_P2P_MODE) {
+			memcpy(&p2p_ea, &dhd->mac, ETHER_ADDR_LEN);
+			ETHER_SET_LOCALADDR(&p2p_ea);
+			ret = dhd_iovar(dhd, 0, "p2p_da_override", (char *)&p2p_ea, sizeof(p2p_ea),
+					NULL, 0, TRUE);
+			if (ret < 0)
+				DHD_ERROR(("%s p2p_da_override ret= %d\n", __FUNCTION__, ret));
+			else
+				DHD_INFO(("dhd_preinit_ioctls: p2p_da_override succeeded\n"));
+		}
+#endif /* !defined(AP) && defined(WLP2P) */
+
+	}
+
+#ifdef BCMPCIE_OOB_HOST_WAKE
+	ret = dhd_iovar(dhd, 0, "bus:hostwake_oob", NULL, 0, (char *)&hostwake_oob,
+		sizeof(hostwake_oob), FALSE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: hostwake_oob IOVAR not present, proceed\n", __FUNCTION__));
+	} else {
+		if (hostwake_oob == 0) {
+			DHD_ERROR(("%s: hostwake_oob is not enabled in the NVRAM, STOP\n",
+				__FUNCTION__));
+			ret = BCME_UNSUPPORTED;
+			goto done;
+		} else {
+			DHD_ERROR(("%s: hostwake_oob enabled\n", __FUNCTION__));
+		}
+	}
+#endif /* BCMPCIE_OOB_HOST_WAKE */
+
+#ifdef DNGL_AXI_ERROR_LOGGING
+	ret = dhd_iovar(dhd, 0, "axierror_logbuf_addr", NULL, 0, (char *)&dhd->axierror_logbuf_addr,
+		sizeof(dhd->axierror_logbuf_addr), FALSE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: axierror_logbuf_addr IOVAR not present, proceed\n", __FUNCTION__));
+		dhd->axierror_logbuf_addr = 0;
+	} else {
+		DHD_ERROR(("%s: axierror_logbuf_addr : 0x%x\n",
+			__FUNCTION__, dhd->axierror_logbuf_addr));
+	}
+#endif /* DNGL_AXI_ERROR_LOGGING */
+
+	ret = dhd_conf_custom_mac(dhd);
+	if (ret)
+		goto done;
+	else
+	{
+		/* Get the default device MAC address directly from firmware */
+		ret = dhd_iovar(dhd, 0, "cur_etheraddr", NULL, 0, (char *)&buf, sizeof(buf), FALSE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: can't get MAC address , error=%d\n", __FUNCTION__, ret));
+			ret = BCME_NOTUP;
+			goto done;
+		}
+
+		DHD_ERROR(("%s: use firmware generated mac_address "MACDBG"\n",
+			__FUNCTION__, MAC2STRDBG(&buf)));
+
+#ifdef MACADDR_PROVISION_ENFORCED
+		if (ETHER_IS_LOCALADDR(buf)) {
+			DHD_ERROR(("%s: error! not using provision mac addr!\n", __FUNCTION__));
+			ret = BCME_BADADDR;
+			goto done;
+		}
+#endif /* MACADDR_PROVISION_ENFORCED */
+
+		/* Update public MAC address after reading from Firmware */
+		memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN);
+	}
+
+	if (ETHER_ISNULLADDR(dhd->mac.octet)) {
+		DHD_ERROR(("%s: NULL MAC address during pre-init\n", __FUNCTION__));
+		ret = BCME_BADADDR;
+		goto done;
+	} else {
+		(void)memcpy_s(dhd_linux_get_primary_netdev(dhd)->perm_addr, ETHER_ADDR_LEN,
+			dhd->mac.octet, ETHER_ADDR_LEN);
+	}
+#if defined(WL_STA_ASSOC_RAND) && defined(WL_STA_INIT_RAND)
+	/* Set cur_etheraddr of primary interface to randomized address to ensure
+	 * that any action frame transmission will happen using randomized macaddr
+	 * primary netdev->perm_addr will hold the original factory MAC.
+	 */
+#ifdef WL_STA_INIT_RAND_CTRL
+	if (dhd_sta_init_rand)
+#endif /* WL_STA_INIT_RAND_CTRL */
+	{
+		if ((ret = dhd_update_rand_mac_addr(dhd)) < 0) {
+			DHD_ERROR(("%s: failed to set random macaddress\n", __FUNCTION__));
+			goto done;
+		}
+	}
+#endif /* WL_STA_ASSOC_RAND && WL_STA_INIT_RAND */
+
+#ifdef SUPPORT_MULTIPLE_CLMBLOB
+	if (dhd_get_platform_naming_for_nvram_clmblob_file(CLM_BLOB,
+			customer_clm_file_name) == BCME_OK) {
+		apply_clm = customer_clm_file_name;
+	}
+	else
+#endif /* SUPPORT_MULTIPLE_CLMBLOB */
+	{
+		apply_clm = dhd->info->clm_path;
+	}
+
+	if ((ret = dhd_apply_default_clm(dhd, apply_clm)) < 0) {
+		DHD_ERROR(("%s: CLM set failed. Ignore and continue initialization.\n",
+			__FUNCTION__));
+	}
+
+	DHD_ERROR(("Firmware up: op_mode=0x%04x, MAC="MACDBG"\n",
+		dhd->op_mode, MAC2STRDBG(dhd->mac.octet)));
+#if defined(DHD_BLOB_EXISTENCE_CHECK)
+	if (!dhd->is_blob)
+#endif /* DHD_BLOB_EXISTENCE_CHECK */
+	{
+		/* get a ccode and revision for the country code */
+#if defined(CUSTOM_COUNTRY_CODE)
+		get_customized_country_code(dhd->info->adapter, dhd->dhd_cspec.country_abbrev,
+			&dhd->dhd_cspec, dhd->dhd_cflags);
+#else
+		get_customized_country_code(dhd->info->adapter, dhd->dhd_cspec.country_abbrev,
+			&dhd->dhd_cspec);
+#endif /* CUSTOM_COUNTRY_CODE */
+	}
+
+#if defined(RXFRAME_THREAD) && defined(RXTHREAD_ONLYSTA)
+	if (dhd->op_mode == DHD_FLAG_HOSTAP_MODE)
+		dhd->info->rxthread_enabled = FALSE;
+	else
+		dhd->info->rxthread_enabled = TRUE;
+#endif
+
+#if defined(CUSTOM_COUNTRY_CODE_XZ)
+	/* Set initial country code to XZ */
+	strlcpy(dhd->dhd_cspec.country_abbrev, "XZ", WLC_CNTRY_BUF_SZ);
+	strlcpy(dhd->dhd_cspec.ccode, "XZ", WLC_CNTRY_BUF_SZ);
+	DHD_ERROR(("%s: Set initial country code to XZ(World Wide Safe)\n", __FUNCTION__));
+#endif /* CUSTOM_COUNTRY_CODE_XZ */
+	/* Set Country code  */
+	if (dhd->dhd_cspec.ccode[0] != 0) {
+		ret = dhd_iovar(dhd, 0, "country", (char *)&dhd->dhd_cspec, sizeof(wl_country_t),
+				NULL, 0, TRUE);
+		if (ret < 0)
+			DHD_ERROR(("%s: country code setting failed\n", __FUNCTION__));
+	}
+
+#if defined(ROAM_ENABLE)
+#ifdef USE_WFA_CERT_CONF
+	if (sec_get_param_wfa_cert(dhd, SET_PARAM_ROAMOFF, &roamvar) == BCME_OK) {
+		DHD_ERROR(("%s: read roam_off param =%d\n", __FUNCTION__, roamvar));
+	}
+#endif /* USE_WFA_CERT_CONF */
+	/* Disable built-in roaming to allowed ext supplicant to take care of roaming */
+	ret = dhd_iovar(dhd, 0, "roam_off", (char *)&roamvar, sizeof(roamvar), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s roam_off failed %d\n", __FUNCTION__, ret));
+	}
+#ifdef WL_CFG80211
+	ROAMOFF_DBG_SAVE(dhd_linux_get_primary_netdev(dhd), SET_ROAM_PREINIT, roamvar);
+#endif /* WL_CFG80211 */
+#ifdef ROAM_AP_ENV_DETECTION
+	/* Changed to GET iovar to read roam_env_mode */
+	dhd->roam_env_detection = FALSE;
+	ret = dhd_iovar(dhd, 0, "roam_env_detection", NULL, 0, (char *)&roam_env_mode,
+			sizeof(roam_env_mode), FALSE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: roam_env_detection IOVAR not present\n", __FUNCTION__));
+	} else {
+		if (roam_env_mode == AP_ENV_INDETERMINATE) {
+			dhd->roam_env_detection = TRUE;
+		}
+	}
+#endif /* ROAM_AP_ENV_DETECTION */
+#ifdef CONFIG_ROAM_RSSI_LIMIT
+	ret = dhd_roam_rssi_limit_set(dhd, CUSTOM_ROAMRSSI_2G, CUSTOM_ROAMRSSI_5G);
+	if (ret < 0) {
+		DHD_ERROR(("%s set roam_rssi_limit failed ret %d\n", __FUNCTION__, ret));
+	}
+#endif /* CONFIG_ROAM_RSSI_LIMIT */
+#ifdef CONFIG_ROAM_MIN_DELTA
+	ret = dhd_roam_min_delta_set(dhd, CUSTOM_ROAM_MIN_DELTA, CUSTOM_ROAM_MIN_DELTA);
+	if (ret < 0) {
+		DHD_ERROR(("%s set roam_min_delta failed ret %d\n", __FUNCTION__, ret));
+	}
+#endif /* CONFIG_ROAM_MIN_DELTA */
+#endif /* ROAM_ENABLE */
+#ifdef CUSTOM_EVENT_PM_WAKE
+	dhd_init_excess_pm_awake(dhd);
+#endif	/* CUSTOM_EVENT_PM_WAKE */
+
+#ifdef WLTDLS
+	dhd->tdls_enable = FALSE;
+	/* query tdls_eable */
+	ret = dhd_iovar(dhd, 0, "tdls_enable", NULL, 0, (char *)&dhd->tdls_enable,
+		sizeof(dhd->tdls_enable), FALSE);
+	DHD_ERROR(("%s: tdls_enable=%d ret=%d\n", __FUNCTION__, dhd->tdls_enable, ret));
+#endif /* WLTDLS */
+
+#ifdef DHD_PM_CONTROL_FROM_FILE
+	sec_control_pm(dhd, &power_mode);
+#endif /* DHD_PM_CONTROL_FROM_FILE */
+
+#ifdef EVENT_LOG_RATE_HC
+	ret = dhd_iovar(dhd, 0, "event_log_rate_hc", (char *)&event_log_rate_hc,
+		sizeof(event_log_rate_hc), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s event_log_rate_hc set failed %d\n", __FUNCTION__, ret));
+	} else  {
+		DHD_ERROR(("%s event_log_rate_hc set with threshold:%d\n", __FUNCTION__,
+			event_log_rate_hc));
+	}
+#endif /* EVENT_LOG_RATE_HC */
+
+#ifdef MIMO_ANT_SETTING
+	dhd_sel_ant_from_file(dhd);
+#endif /* MIMO_ANT_SETTING */
+
+#if defined(OEM_ANDROID) && defined(SOFTAP)
+	if (ap_fw_loaded == TRUE) {
+		dhd_wl_ioctl_cmd(dhd, WLC_SET_DTIMPRD, (char *)&dtim, sizeof(dtim), TRUE, 0);
+	}
+#endif /* defined(OEM_ANDROID) && defined(SOFTAP) */
+
+#if defined(KEEP_ALIVE)
+	/* Set Keep Alive : be sure to use FW with -keepalive */
+	if (!(dhd->op_mode &
+		(DHD_FLAG_HOSTAP_MODE | DHD_FLAG_MFG_MODE))) {
+		if ((ret = dhd_keep_alive_onoff(dhd)) < 0)
+			DHD_ERROR(("%s set keeplive failed %d\n",
+			__FUNCTION__, ret));
+	}
+#endif /* defined(KEEP_ALIVE) */
+
+	ret = dhd_iovar(dhd, 0, "event_log_max_sets", NULL, 0, (char *)&event_log_max_sets,
+		sizeof(event_log_max_sets), FALSE);
+	if (ret == BCME_OK) {
+		dhd->event_log_max_sets = event_log_max_sets;
+	} else {
+		dhd->event_log_max_sets = NUM_EVENT_LOG_SETS;
+	}
+	BCM_REFERENCE(iovbuf);
+	/* Make sure max_sets is set first with wmb and then sets_queried,
+	 * this will be used during parsing the logsets in the reverse order.
+	 */
+	OSL_SMP_WMB();
+	dhd->event_log_max_sets_queried = TRUE;
+	DHD_ERROR(("%s: event_log_max_sets: %d ret: %d\n",
+		__FUNCTION__, dhd->event_log_max_sets, ret));
+#ifdef DHD_BUS_MEM_ACCESS
+	ret = dhd_iovar(dhd, 0, "enable_memuse", (char *)&enable_memuse,
+			sizeof(enable_memuse), iovbuf, sizeof(iovbuf), FALSE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: enable_memuse is failed ret=%d\n",
+			__FUNCTION__, ret));
+	} else {
+		DHD_ERROR(("%s: enable_memuse = %d\n",
+			__FUNCTION__, enable_memuse));
+	}
+#endif /* DHD_BUS_MEM_ACCESS */
+
+#ifdef USE_WFA_CERT_CONF
+#ifdef USE_WL_FRAMEBURST
+	 if (sec_get_param_wfa_cert(dhd, SET_PARAM_FRAMEBURST, &frameburst) == BCME_OK) {
+		DHD_ERROR(("%s, read frameburst param=%d\n", __FUNCTION__, frameburst));
+	 }
+#endif /* USE_WL_FRAMEBURST */
+	 g_frameburst = frameburst;
+#endif /* USE_WFA_CERT_CONF */
+
+#ifdef DISABLE_WL_FRAMEBURST_SOFTAP
+	/* Disable Framebursting for SofAP */
+	if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
+		frameburst = 0;
+	}
+#endif /* DISABLE_WL_FRAMEBURST_SOFTAP */
+
+	BCM_REFERENCE(frameburst);
+#if defined(USE_WL_FRAMEBURST) || defined(DISABLE_WL_FRAMEBURST_SOFTAP)
+	/* frameburst is set to 1 by preinit fw, change if otherwise */
+	if (frameburst != 1) {
+		/* Set frameburst to value */
+		if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_FAKEFRAG, (char *)&frameburst,
+			sizeof(frameburst), TRUE, 0)) < 0) {
+			DHD_INFO(("%s frameburst not supported	%d\n", __FUNCTION__, ret));
+		}
+	}
+#endif /* USE_WL_FRAMEBURST || DISABLE_WL_FRAMEBURST_SOFTAP */
+
+	iov_buf = (char*)MALLOC(dhd->osh, WLC_IOCTL_SMLEN);
+	if (iov_buf == NULL) {
+		DHD_ERROR(("failed to allocate %d bytes for iov_buf\n", WLC_IOCTL_SMLEN));
+		ret = BCME_NOMEM;
+		goto done;
+	}
+
+	/* make up event mask ext message iovar for event larger than 128 */
+	msglen = WL_EVENTING_MASK_EXT_LEN + EVENTMSGS_EXT_STRUCT_SIZE;
+	eventmask_msg = (eventmsgs_ext_t*)MALLOC(dhd->osh, msglen);
+	if (eventmask_msg == NULL) {
+		DHD_ERROR(("failed to allocate %d bytes for event_msg_ext\n", msglen));
+		ret = BCME_NOMEM;
+		goto done;
+	}
+	bzero(eventmask_msg, msglen);
+	eventmask_msg->ver = EVENTMSGS_VER;
+	eventmask_msg->len = ROUNDUP(WLC_E_LAST, NBBY)/NBBY;
+
+	/* Read event_msgs_ext mask */
+	ret = dhd_iovar(dhd, 0, "event_msgs_ext", (char *)eventmask_msg, msglen, iov_buf,
+			WLC_IOCTL_SMLEN, FALSE);
+
+	/* event_msgs_ext must be supported */
+	if (ret != BCME_OK) {
+		DHD_ERROR(("%s read event mask ext failed %d\n", __FUNCTION__, ret));
+		goto done;
+	}
+
+	bcopy(iov_buf, eventmask_msg, msglen);
+	/* make up event mask ext message iovar for event larger than 128 */
+	mask = eventmask_msg->mask;
+
+	/* Setup event_msgs */
+	setbit(mask, WLC_E_COUNTRY_CODE_CHANGED);
+
+	/* Write updated Event mask */
+	eventmask_msg->ver = EVENTMSGS_VER;
+	eventmask_msg->command = EVENTMSGS_SET_MASK;
+	eventmask_msg->len = WL_EVENTING_MASK_EXT_LEN;
+	ret = dhd_iovar(dhd, 0, "event_msgs_ext", (char *)eventmask_msg, msglen, NULL, 0,
+			TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s write event mask ext failed %d\n", __FUNCTION__, ret));
+		goto done;
+	}
+
+#if defined(BCMSUP_4WAY_HANDSHAKE)
+	/* Read 4-way handshake requirements */
+	if (dhd_use_idsup == 1) {
+		ret = dhd_iovar(dhd, 0, "sup_wpa", (char *)&sup_wpa, sizeof(sup_wpa),
+				(char *)&iovbuf, sizeof(iovbuf), FALSE);
+		/* sup_wpa iovar returns NOTREADY status on some platforms using modularized
+		 * in-dongle supplicant.
+		 */
+		if (ret >= 0 || ret == BCME_NOTREADY)
+			dhd->fw_4way_handshake = TRUE;
+		DHD_TRACE(("4-way handshake mode is: %d\n", dhd->fw_4way_handshake));
+	}
+#endif /* BCMSUP_4WAY_HANDSHAKE */
+
+#if defined(PCIE_FULL_DONGLE) && defined(DHD_LOSSLESS_ROAMING)
+	dhd_update_flow_prio_map(dhd, DHD_FLOW_PRIO_LLR_MAP);
+#endif /* defined(PCIE_FULL_DONGLE) && defined(DHD_LOSSLESS_ROAMING) */
+
+#if defined(BCMPCIE) && defined(EAPOL_PKT_PRIO)
+	dhd_update_flow_prio_map(dhd, DHD_FLOW_PRIO_LLR_MAP);
+#endif /* defined(BCMPCIE) && defined(EAPOL_PKT_PRIO) */
+
+#if defined(BCMSDIO) && defined(DHD_LOSSLESS_ROAMING)
+	dhd_update_sdio_data_prio_map(dhd);
+#endif /* BCMSDIO && DHD_LOSSLESS_ROAMING */
+
+#ifdef ARP_OFFLOAD_SUPPORT
+	DHD_ERROR(("arp_enable:%d arp_ol:%d\n",
+		dhd->arpoe_enable, dhd->arpol_configured));
+#endif /* ARP_OFFLOAD_SUPPORT */
+	/*
+	 * Retaining pktfilter fotr temporary, once fw preinit includes this,
+	 * this will be removed. Caution is to skip the pktfilter check during
+	 * each pktfilter removal.
+	 */
+#ifdef PKT_FILTER_SUPPORT
+	/* Setup default defintions for pktfilter , enable in suspend */
+	if (dhd_master_mode) {
+		dhd->pktfilter_count = 6;
+		dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = NULL;
+		if (!FW_SUPPORTED(dhd, pf6)) {
+			dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = NULL;
+			dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = NULL;
+		} else {
+			/* Immediately pkt filter TYPE 6 Discard IPv4/IPv6 Multicast Packet */
+			dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = DISCARD_IPV4_MCAST;
+			dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = DISCARD_IPV6_MCAST;
+		}
+		/* apply APP pktfilter */
+		dhd->pktfilter[DHD_ARP_FILTER_NUM] = "105 0 0 12 0xFFFF 0x0806";
+
+#ifdef BLOCK_IPV6_PACKET
+		/* Setup filter to allow only IPv4 unicast frames */
+		dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = "100 0 0 0 "
+			HEX_PREF_STR UNI_FILTER_STR ZERO_ADDR_STR ETHER_TYPE_STR IPV6_FILTER_STR
+			" "
+			HEX_PREF_STR ZERO_ADDR_STR ZERO_ADDR_STR ETHER_TYPE_STR ZERO_TYPE_STR;
+#else
+		/* Setup filter to allow only unicast */
+		dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = "100 0 0 0 0x01 0x00";
+#endif /* BLOCK_IPV6_PACKET */
+
+#ifdef PASS_IPV4_SUSPEND
+		/* XXX customer want to get IPv4 multicast packets */
+		dhd->pktfilter[DHD_MDNS_FILTER_NUM] = "104 0 0 0 0xFFFFFF 0x01005E";
+#else
+		/* Add filter to pass multicastDNS packet and NOT filter out as Broadcast */
+		dhd->pktfilter[DHD_MDNS_FILTER_NUM] = NULL;
+#endif /* PASS_IPV4_SUSPEND */
+		if (FW_SUPPORTED(dhd, pf6)) {
+			/* Immediately pkt filter TYPE 6 Dicard Broadcast IP packet */
+			dhd->pktfilter[DHD_IP4BCAST_DROP_FILTER_NUM] = DISCARD_IPV4_BCAST;
+			/* Immediately pkt filter TYPE 6 Dicard Cisco STP packet */
+			dhd->pktfilter[DHD_LLC_STP_DROP_FILTER_NUM] = DISCARD_LLC_STP;
+			/* Immediately pkt filter TYPE 6 Dicard Cisco XID protocol */
+			dhd->pktfilter[DHD_LLC_XID_DROP_FILTER_NUM] = DISCARD_LLC_XID;
+			/* Immediately pkt filter TYPE 6 Dicard NETBIOS packet(port 137) */
+			dhd->pktfilter[DHD_UDPNETBIOS_DROP_FILTER_NUM] = DISCARD_UDPNETBIOS;
+			dhd->pktfilter_count = 11;
+		}
+
+#ifdef GAN_LITE_NAT_KEEPALIVE_FILTER
+		dhd->pktfilter_count = 4;
+		/* Setup filter to block broadcast and NAT Keepalive packets */
+		/* discard all broadcast packets */
+		dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = "100 0 0 0 0xffffff 0xffffff";
+		/* discard NAT Keepalive packets */
+		dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = "102 0 0 36 0xffffffff 0x11940009";
+		/* discard NAT Keepalive packets */
+		dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = "104 0 0 38 0xffffffff 0x11940009";
+		dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = NULL;
+#endif /* GAN_LITE_NAT_KEEPALIVE_FILTER */
+	} else
+		dhd_conf_discard_pkt_filter(dhd);
+	dhd_conf_add_pkt_filter(dhd);
+
+#if defined(SOFTAP)
+	if (ap_fw_loaded) {
+		/* XXX Andrey: fo SOFTAP disable pkt filters (if there were any )  */
+		dhd_enable_packet_filter(0, dhd);
+	}
+#endif /* defined(SOFTAP) */
+	dhd_set_packet_filter(dhd);
+#endif /* PKT_FILTER_SUPPORT */
+
+	/* query for 'clmver' to get clm version info from firmware */
+	bzero(buf, sizeof(buf));
+	ret = dhd_iovar(dhd, 0, "clmver", NULL, 0, buf, sizeof(buf), FALSE);
+	if (ret < 0)
+		DHD_ERROR(("%s clmver failed %d\n", __FUNCTION__, ret));
+	else {
+		char *ver_temp_buf = NULL, *ver_date_buf = NULL;
+		int len;
+
+		if ((ver_temp_buf = bcmstrstr(buf, "Data:")) == NULL) {
+			DHD_ERROR(("Couldn't find \"Data:\"\n"));
+		} else {
+			ver_date_buf = bcmstrstr(buf, "Creation:");
+			ptr = (ver_temp_buf + strlen("Data:"));
+			if ((ver_temp_buf = bcmstrtok(&ptr, "\n", 0)) == NULL) {
+				DHD_ERROR(("Couldn't find New line character\n"));
+			} else {
+				memset(clm_version, 0, CLM_VER_STR_LEN);
+				len = snprintf(clm_version, CLM_VER_STR_LEN - 1, "%s", ver_temp_buf);
+				if (ver_date_buf) {
+					ptr = (ver_date_buf + strlen("Creation:"));
+					ver_date_buf = bcmstrtok(&ptr, "\n", 0);
+					if (ver_date_buf)
+						snprintf(clm_version+len, CLM_VER_STR_LEN-1-len,
+							" (%s)", ver_date_buf);
+				}
+				DHD_INFO(("CLM version = %s\n", clm_version));
+			}
+		}
+
+		if (strlen(clm_version)) {
+			DHD_INFO(("CLM version = %s\n", clm_version));
+		} else {
+			DHD_ERROR(("Couldn't find CLM version!\n"));
+		}
+
+	}
+	dhd_set_version_info(dhd, fw_version);
+
+#ifdef WRITE_WLANINFO
+	do {
+		uint len = MAX_NVRAMBUF_SIZE;
+		char *memblock = NULL;
+
+		dhd_get_download_buffer(dhd, dhd->info->nv_path, NVRAM, &memblock, (int *)&len);
+		if ((len <= 0 || len > MAX_NVRAMBUF_SIZE)) {
+			DHD_ERROR(("Can't open nvram info, skip save wifiver info\n"));
+			break;
+		}
+
+		sec_save_wlinfo(fw_version, EPI_VERSION_STR, memblock, clm_version);
+		if (memblock) {
+			dhd_free_download_buffer(dhd, memblock, len);
+		}
+	} while (0);
+#endif /* WRITE_WLANINFO */
+
+#ifdef GEN_SOFTAP_INFO_FILE
+	sec_save_softap_info();
+#endif /* GEN_SOFTAP_INFO_FILE */
+
+#ifdef PNO_SUPPORT
+	if (!dhd->pno_state) {
+		dhd_pno_init(dhd);
+	}
+#endif
+
+#ifdef RTT_SUPPORT
+	if (dhd->rtt_state) {
+		ret = dhd_rtt_init(dhd);
+		if (ret < 0) {
+			DHD_ERROR(("%s failed to initialize RTT\n", __FUNCTION__));
+		}
+	}
+#endif
+
+#ifdef FILTER_IE
+	/* Failure to configure filter IE is not a fatal error, ignore it. */
+	if (FW_SUPPORTED(dhd, fie) &&
+		!(dhd->op_mode & (DHD_FLAG_HOSTAP_MODE | DHD_FLAG_MFG_MODE))) {
+		dhd_read_from_file(dhd);
+	}
+#endif /* FILTER_IE */
+
+#ifdef NDO_CONFIG_SUPPORT
+	dhd->ndo_enable = FALSE;
+	dhd->ndo_host_ip_overflow = FALSE;
+	dhd->ndo_max_host_ip = NDO_MAX_HOST_IP_ENTRIES;
+#endif /* NDO_CONFIG_SUPPORT */
+
+	/* ND offload version supported */
+	dhd->ndo_version = dhd_ndo_get_version(dhd);
+
+	/* check dongle supports wbtext (product policy) or not */
+	dhd->wbtext_support = FALSE;
+	if (dhd_wl_ioctl_get_intiovar(dhd, "wnm_bsstrans_resp", &wnm_bsstrans_resp,
+			WLC_GET_VAR, FALSE, 0) != BCME_OK) {
+		DHD_ERROR(("failed to get wnm_bsstrans_resp\n"));
+	}
+	dhd->wbtext_policy = wnm_bsstrans_resp;
+	if (dhd->wbtext_policy == WL_BSSTRANS_POLICY_PRODUCT_WBTEXT) {
+		dhd->wbtext_support = TRUE;
+	}
+#ifndef WBTEXT
+	/* driver can turn off wbtext feature through makefile */
+	if (dhd->wbtext_support) {
+		if (dhd_wl_ioctl_set_intiovar(dhd, "wnm_bsstrans_resp",
+				WL_BSSTRANS_POLICY_ROAM_ALWAYS,
+				WLC_SET_VAR, FALSE, 0) != BCME_OK) {
+			DHD_ERROR(("failed to disable WBTEXT\n"));
+		}
+	}
+#endif /* !WBTEXT */
+
+#ifdef DHD_NON_DMA_M2M_CORRUPTION
+	/* check pcie non dma loopback */
+	if (dhd->op_mode == DHD_FLAG_MFG_MODE &&
+		(dhd_bus_dmaxfer_lpbk(dhd, M2M_NON_DMA_LPBK) < 0)) {
+			goto done;
+	}
+#endif /* DHD_NON_DMA_M2M_CORRUPTION */
+
+#ifdef CUSTOM_ASSOC_TIMEOUT
+	/* set recreate_bi_timeout to increase assoc timeout :
+	* 20 * 100TU * 1024 / 1000 = 2 secs
+	* (beacon wait time = recreate_bi_timeout * beacon_period * 1024 / 1000)
+	*/
+	if (dhd_wl_ioctl_set_intiovar(dhd, "recreate_bi_timeout",
+			CUSTOM_ASSOC_TIMEOUT,
+			WLC_SET_VAR, TRUE, 0) != BCME_OK) {
+		DHD_ERROR(("failed to set assoc timeout\n"));
+	}
+#endif /* CUSTOM_ASSOC_TIMEOUT */
+
+	BCM_REFERENCE(ret2);
+#if defined(WBTEXT) && defined(RRM_BCNREQ_MAX_CHAN_TIME)
+	if (dhd_iovar(dhd, 0, "rrm_bcn_req_thrtl_win",
+		(char *)&rrm_bcn_req_thrtl_win, sizeof(rrm_bcn_req_thrtl_win),
+		NULL, 0, TRUE) < 0) {
+		DHD_ERROR(("failed to set RRM BCN request thrtl_win\n"));
+	}
+	if (dhd_iovar(dhd, 0, "rrm_bcn_req_max_off_chan_time",
+		(char *)&rrm_bcn_req_max_off_chan_time, sizeof(rrm_bcn_req_max_off_chan_time),
+		NULL, 0, TRUE) < 0) {
+		DHD_ERROR(("failed to set RRM BCN Request max_off_chan_time\n"));
+	}
+#endif /* WBTEXT && RRM_BCNREQ_MAX_CHAN_TIME */
+#ifdef WL_MONITOR
+#ifdef HOST_RADIOTAP_CONV
+	/* 'Wl monitor' IOVAR is fired to check whether the FW supports radiotap conversion or not.
+	 * This is indicated through MSB(1<<31) bit, based on which host radiotap conversion
+	 * will be enabled or disabled.
+	 * 0 - Host supports Radiotap conversion.
+	 * 1 - FW supports Radiotap conversion.
+	 */
+	bcm_mkiovar("monitor", (char *)&monitor, sizeof(monitor), iovbuf, sizeof(iovbuf));
+	if ((ret2 = dhd_wl_ioctl_cmd(dhd, WLC_GET_MONITOR, iovbuf,
+		sizeof(iovbuf), FALSE, 0)) == 0) {
+		memcpy(&monitor, iovbuf, sizeof(monitor));
+		dhdinfo->host_radiotap_conv = (monitor & HOST_RADIOTAP_CONV_BIT) ? TRUE : FALSE;
+	} else {
+		DHD_ERROR(("%s Failed to get monitor mode, err %d\n",
+			__FUNCTION__, ret2));
+	}
+#endif /* HOST_RADIOTAP_CONV */
+	if (FW_SUPPORTED(dhd, monitor)) {
+		dhd->monitor_enable = TRUE;
+		DHD_ERROR(("%s: Monitor mode is enabled in FW cap\n", __FUNCTION__));
+	} else {
+		dhd->monitor_enable = FALSE;
+		DHD_ERROR(("%s: Monitor mode is not enabled in FW cap\n", __FUNCTION__));
+	}
+#endif /* WL_MONITOR */
+
+	/* store the preserve log set numbers */
+	if (dhd_get_preserve_log_numbers(dhd, &dhd->logset_prsrv_mask)
+			!= BCME_OK) {
+		DHD_ERROR(("%s: Failed to get preserve log # !\n", __FUNCTION__));
+	}
+
+#ifdef CUSTOM_OCL_RSSI_VAL
+	if (ocl_rssi_threshold != FW_OCL_RSSI_THRESH_INITVAL) {
+		ret = dhd_iovar(dhd, 0, "ocl_rssi_threshold", (char *)&ocl_rssi_threshold,
+			sizeof(ocl_rssi_threshold), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("failed to set ocl_rssi_threshold ret %d\n", ret));
+		}
+	}
+#endif /* CUSTOM_OCL_RSSI_VAL */
+
+	if (dhd_iovar(dhd, 0, "bus:d3_hostwake_delay", (char *)&d3_hostwake_delay,
+		sizeof(d3_hostwake_delay), NULL, 0, TRUE) < 0) {
+		DHD_ERROR(("%s: d3_hostwake_delay IOVAR not present, proceed\n", __FUNCTION__));
+	} else {
+		DHD_ERROR(("%s: d3_hostwake_delay enabled\n", __FUNCTION__));
+	}
+
+	dhd->fr_phase_nibble = TRUE;
+	if (dhd_iovar(dhd, 0, "bus:fr_phase_nibble", (char *)&dhd->fr_phase_nibble,
+		sizeof(dhd->fr_phase_nibble), NULL, 0, TRUE) < 0) {
+		dhd->fr_phase_nibble = FALSE;
+		DHD_ERROR(("%s: fr_phase_nibble IOVAR not present, proceed\n", __FUNCTION__));
+	} else {
+		DHD_ERROR(("%s: fr_phase_nibble enabled\n", __FUNCTION__));
+	}
+
+#ifdef DISABLE_6G_SUPPORT
+	if (dhd_disable_6g) {
+		ret = dhd_iovar(dhd, 0, "6g_enable", (char *)&enable_6g,
+			sizeof(enable_6g), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s 6g_enable set failed %d\n", __FUNCTION__, ret));
+		}
+	}
+#endif /* DISABLE_6G_SUPPORT */
+
+#ifndef OEM_ANDROID
+	/* For non-android FC modular builds, override firmware preinited values */
+	dhd_override_fwprenit(dhd);
+#endif /* !OEM_ANDROID */
+	dhd_set_bandlock(dhd);
+
+#ifdef DHD_WAKE_EVENT_STATUS
+#ifdef CUSTOM_WAKE_REASON_STATS
+	/* Initialization */
+	if (dhd_bus_get_wakecount(dhd)) {
+		int i = 0;
+		wake_counts_t *wcp = dhd_bus_get_wakecount(dhd);
+
+		wcp->rc_event_idx = 0;
+		for (i = 0; i < MAX_WAKE_REASON_STATS; i++) {
+			wcp->rc_event[i] = -1;
+		}
+	}
+#endif /* CUSTOM_WAKE_REASON_STATS */
+#endif /* DHD_WAKE_EVENT_STATUS */
+
+#ifdef WL_UWB_COEX
+#ifdef WL_UWB_COEX_DEF_ENABLE
+	ret = wl_cfg_uwb_coex_enable(dhd_linux_get_primary_netdev(dhd),
+		TRUE, UWB_COEX_CH_MIN, UWB_COEX_CH_MAX);
+	if (ret != BCME_OK) {
+		DHD_ERROR(("Failed to set UWB Coex (%d)\n", ret));
+	}
+#endif /* WL_UWB_COEX_DEF_ENABLE */
+#endif /* WL_UWB_COEX */
+
+done:
+	if (eventmask_msg) {
+		MFREE(dhd->osh, eventmask_msg, msglen);
+	}
+	if (iov_buf) {
+		MFREE(dhd->osh, iov_buf, WLC_IOCTL_SMLEN);
+	}
+	return ret;
+}
+
+int
+dhd_legacy_preinit_ioctls(dhd_pub_t *dhd)
+{
+	int ret = 0;
+	/*  Room for "event_msgs_ext" + '\0' + bitvec  */
+	char iovbuf[WL_EVENTING_MASK_EXT_LEN + EVENTMSGS_EXT_STRUCT_SIZE + 16];
+	char *mask;
+	uint32 buf_key_b4_m4 = 1;
+	uint8 msglen;
+	eventmsgs_ext_t *eventmask_msg = NULL;
+	uint32 event_log_max_sets = 0;
+	char* iov_buf = NULL;
+	/* XXX: Use ret2 for return check of IOVARS that might return BCME_UNSUPPORTED,
+	*	based on FW build tag.
+	*/
+	int ret2 = 0;
+	uint32 wnm_cap = 0;
+#if defined(WL_MONITOR) && defined(HOST_RADIOTAP_CONV)
+	uint monitor = 0;
+	dhd_info_t *dhdinfo = (dhd_info_t*)dhd->info;
+#endif /* WL_MONITOR */
+#if defined(BCMSUP_4WAY_HANDSHAKE)
+	uint32 sup_wpa = 1;
+#endif /* BCMSUP_4WAY_HANDSHAKE */
+#if defined(CUSTOM_AMPDU_BA_WSIZE)
+	uint32 ampdu_ba_wsize = 0;
+#endif
+#if defined(CUSTOM_AMPDU_MPDU)
+	int32 ampdu_mpdu = 0;
+#endif
+#if defined(CUSTOM_AMPDU_RELEASE)
+	int32 ampdu_release = 0;
+#endif
+#if defined(CUSTOM_AMSDU_AGGSF)
+	int32 amsdu_aggsf = 0;
+#endif
+
+#if defined(BCMSDIO) || defined(BCMDBUS)
+#ifdef PROP_TXSTATUS
+	int wlfc_enable = TRUE;
+#ifndef DISABLE_11N
+	uint32 hostreorder = 1;
+	uint wl_down = 1;
+#endif /* DISABLE_11N */
+#endif /* PROP_TXSTATUS */
+#endif /* defined(BCMSDIO) || defined(BCMDBUS) */
+
+#ifndef PCIE_FULL_DONGLE
+	uint32 wl_ap_isolate;
+#endif /* PCIE_FULL_DONGLE */
+	uint32 frameburst = CUSTOM_FRAMEBURST_SET;
+	uint wnm_bsstrans_resp = 0;
+#ifdef SUPPORT_SET_CAC
+#ifdef CUSTOMER_HW4
+	/* Off by default */
+	uint32 cac = 0;
+#else
+	uint32 cac = 1;
+#endif /* CUSTOMER_HW4 */
+#endif /* SUPPORT_SET_CAC */
+#ifdef DHD_BUS_MEM_ACCESS
+	uint32 enable_memuse = 1;
+#endif /* DHD_BUS_MEM_ACCESS */
+#if defined(SUPPORT_2G_VHT) || defined(SUPPORT_5G_1024QAM_VHT)
+	uint32 vht_features = 0; /* init to 0, will be set based on each support */
+#endif /* SUPPORT_2G_VHT || SUPPORT_5G_1024QAM_VHT */
+
+#ifdef OEM_ANDROID
+#ifdef DHD_ENABLE_LPC
+	uint32 lpc = 1;
+#endif /* DHD_ENABLE_LPC */
+	uint power_mode = PM_FAST;
+#ifdef ASSOC_PREFER_RSSI_THRESH
+	int assoc_pref_rssi_thresh = ASSOC_PREFER_RSSI_THRESH;
+#endif /* ASSOC_PREFER_RSSI_THRESH */
+#ifdef HIGHBANDROAM_ENABLE
+	int highbandroam_enable = 1;
+#endif /* HIGHBANDROAM_ENABLE */
+#if defined(BCMSDIO)
+	uint32 dongle_align = DHD_SDALIGN;
+	uint32 glom = CUSTOM_GLOM_SETTING;
+#endif /* defined(BCMSDIO) */
+	uint bcn_timeout = CUSTOM_BCN_TIMEOUT;
+	uint scancache_enab = TRUE;
+#ifdef ENABLE_BCN_LI_BCN_WAKEUP
+	uint32 bcn_li_bcn = 1;
+#endif /* ENABLE_BCN_LI_BCN_WAKEUP */
+	uint retry_max = CUSTOM_ASSOC_RETRY_MAX;
+	int scan_assoc_time = DHD_SCAN_ASSOC_ACTIVE_TIME;
+	int scan_unassoc_time = DHD_SCAN_UNASSOC_ACTIVE_TIME;
+	int scan_passive_time = DHD_SCAN_PASSIVE_TIME;
+	char buf[WLC_IOCTL_SMLEN];
+	char *ptr;
+	uint32 listen_interval = CUSTOM_LISTEN_INTERVAL; /* Default Listen Interval in Beacons */
+#ifdef DHD_RANDMAC_LOGGING
+	uint privacy_mask = 0;
+#endif /* DHD_RANDMAC_LOGGING */
+#ifdef ROAM_ENABLE
+	uint roamvar = 0;
+	int roam_trigger[2] = {CUSTOM_ROAM_TRIGGER_SETTING, WLC_BAND_ALL};
+	int roam_scan_period[2] = {10, WLC_BAND_ALL};
+	int roam_delta[2] = {CUSTOM_ROAM_DELTA_SETTING, WLC_BAND_ALL};
+#ifdef ROAM_AP_ENV_DETECTION
+	int roam_env_mode = AP_ENV_INDETERMINATE;
+#endif /* ROAM_AP_ENV_DETECTION */
+#ifdef FULL_ROAMING_SCAN_PERIOD_60_SEC
+	int roam_fullscan_period = 60;
+#else /* FULL_ROAMING_SCAN_PERIOD_60_SEC */
+	int roam_fullscan_period = 120;
+#endif /* FULL_ROAMING_SCAN_PERIOD_60_SEC */
+#ifdef DISABLE_BCNLOSS_ROAM
+	uint roam_bcnloss_off = 1;
+#endif /* DISABLE_BCNLOSS_ROAM */
+#else
+#ifdef DISABLE_BUILTIN_ROAM
+	uint roamvar = 1;
+#endif /* DISABLE_BUILTIN_ROAM */
+#endif /* ROAM_ENABLE */
+
+#if defined(SOFTAP)
+	uint dtim = 1;
+#endif
+/* xxx andrey tmp fix for dk8000 build error  */
+#if (defined(AP) && !defined(WLP2P)) || (!defined(AP) && defined(WL_CFG80211))
+	struct ether_addr p2p_ea;
+#endif
+#ifdef BCMCCX
+	uint32 ccx = 1;
+#endif
+#ifdef SOFTAP_UAPSD_OFF
+	uint32 wme_apsd = 0;
+#endif /* SOFTAP_UAPSD_OFF */
+#if (defined(AP) || defined(WLP2P)) && !defined(SOFTAP_AND_GC)
+	uint32 apsta = 1; /* Enable APSTA mode */
+#elif defined(SOFTAP_AND_GC)
+	uint32 apsta = 0;
+	int ap_mode = 1;
+#endif /* (defined(AP) || defined(WLP2P)) && !defined(SOFTAP_AND_GC) */
+#ifdef OKC_SUPPORT
+	uint32 okc = 1;
+#endif
+
+#ifdef DISABLE_11N
+	uint32 nmode = 0;
+#endif /* DISABLE_11N */
+
+#if defined(DISABLE_11AC)
+	uint32 vhtmode = 0;
+#endif /* DISABLE_11AC */
+#ifdef USE_WL_TXBF
+	uint32 txbf = 1;
+#endif /* USE_WL_TXBF */
+#ifdef DISABLE_TXBFR
+	uint32 txbf_bfr_cap = 0;
+#endif /* DISABLE_TXBFR */
+#ifdef AMPDU_VO_ENABLE
+	/* XXX: Enabling VO AMPDU to reduce FER */
+	struct ampdu_tid_control tid;
+#endif
+#if defined(PROP_TXSTATUS)
+#ifdef USE_WFA_CERT_CONF
+	uint32 proptx = 0;
+#endif /* USE_WFA_CERT_CONF */
+	uint32 simutx_limit = WL_TXSTATUS_FREERUNCTR_MASK;
+#endif /* PROP_TXSTATUS */
+#ifdef DHD_SET_FW_HIGHSPEED
+	uint32 ack_ratio = 250;
+	uint32 ack_ratio_depth = 64;
+#endif /* DHD_SET_FW_HIGHSPEED */
+#ifdef DISABLE_11N_PROPRIETARY_RATES
+	uint32 ht_features = 0;
+#endif /* DISABLE_11N_PROPRIETARY_RATES */
+#ifdef DISABLE_PRUNED_SCAN
+	uint32 scan_features = 0;
+#endif /* DISABLE_PRUNED_SCAN */
+#ifdef BCMPCIE_OOB_HOST_WAKE
+	uint32 hostwake_oob = 0;
+#endif /* BCMPCIE_OOB_HOST_WAKE */
+#ifdef EVENT_LOG_RATE_HC
+	/* threshold number of lines per second */
+	uint32 event_log_rate_hc = EVENT_LOG_RATE_HC_THRESHOLD;
+#endif /* EVENT_LOG_RATE_HC */
+#endif  /* OEM_ANDROID */
+#if defined(WBTEXT) && defined(WBTEXT_BTMDELTA)
+	uint32 btmdelta = WBTEXT_BTMDELTA;
+#endif /* WBTEXT && WBTEXT_BTMDELTA */
+#if defined(WBTEXT) && defined(RRM_BCNREQ_MAX_CHAN_TIME)
+	uint32 rrm_bcn_req_thrtl_win = RRM_BCNREQ_MAX_CHAN_TIME * 2;
+	uint32 rrm_bcn_req_max_off_chan_time = RRM_BCNREQ_MAX_CHAN_TIME;
+#endif /* WBTEXT && RRM_BCNREQ_MAX_CHAN_TIME */
+#ifdef CUSTOM_PSPRETEND_THR
+	uint32 pspretend_thr = CUSTOM_PSPRETEND_THR;
+#endif
+#if (defined(DHD_8021X_DUMP) && defined(SHOW_LOGTRACE)) || defined(DEBUGABILITY)
+	wl_el_tag_params_t *el_tag = NULL;
+#endif /* DHD_8021X_DUMP */
+
+#ifdef DISABLE_6G_SUPPORT
+	uint32 enable_6g = 0;
+#endif /* DISABLE_6G_SUPPORT */
+
+	uint32 d3_hostwake_delay = D3_HOSTWAKE_DELAY;
+
+	BCM_REFERENCE(iovbuf);
+	DHD_TRACE(("Enter %s\n", __FUNCTION__));
+
+#ifdef ARP_OFFLOAD_SUPPORT
+	/* arpoe will be applied from the supsend context */
+	dhd->arpoe_enable = TRUE;
+	dhd->arpol_configured = FALSE;
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+#ifdef OEM_ANDROID
+#ifdef PKT_FILTER_SUPPORT
+	dhd_pkt_filter_enable = TRUE;
+#endif /* PKT_FILTER_SUPPORT */
+#ifdef APF
+	dhd->apf_set = FALSE;
+#endif /* APF */
+#ifdef CUSTOM_SET_OCLOFF
+	dhd->ocl_off = FALSE;
+#endif /* CUSTOM_SET_OCLOFF */
+#ifdef SUPPORT_SET_TID
+	dhd->tid_mode = SET_TID_OFF;
+	dhd->target_uid = 0;
+	dhd->target_tid = 0;
+#endif /* SUPPORT_SET_TID */
+#ifdef DHDTCPACK_SUPPRESS
+	dhd_tcpack_suppress_set(dhd, dhd->conf->tcpack_sup_mode);
+#endif
+	dhd->op_mode = 0;
+
+	/* clear AP flags */
+#if defined(CUSTOM_COUNTRY_CODE)
+	dhd->dhd_cflags &= ~WLAN_PLAT_AP_FLAG;
+#endif /* CUSTOM_COUNTRY_CODE */
+
+	/* query for 'ver' to get version info from firmware */
+	memset(buf, 0, sizeof(buf));
+	ptr = buf;
+	ret = dhd_iovar(dhd, 0, "ver", NULL, 0, (char *)&buf, sizeof(buf), FALSE);
+	if (ret < 0)
+		DHD_ERROR(("%s failed %d\n", __FUNCTION__, ret));
+	else {
+		bcmstrtok(&ptr, "\n", 0);
+		/* Print fw version info */
+		strncpy(fw_version, buf, FW_VER_STR_LEN);
+		fw_version[FW_VER_STR_LEN-1] = '\0';
+	}
+
+// mark flag for later blob checking
+	/* Set op_mode as MFG_MODE if WLTEST is present in "wl ver" */
+	if (strstr(fw_version, "WLTEST") != NULL) {
+		DHD_ERROR(("%s: wl ver has WLTEST, setting op_mode as DHD_FLAG_MFG_MODE\n",
+			__FUNCTION__));
+		op_mode = DHD_FLAG_MFG_MODE;
+	}
+
+	if ((!op_mode && dhd_get_fw_mode(dhd->info) == DHD_FLAG_MFG_MODE) ||
+		(op_mode == DHD_FLAG_MFG_MODE)) {
+		dhd->op_mode = DHD_FLAG_MFG_MODE;
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+		/* disable runtimePM by default in MFG mode. */
+		pm_runtime_disable(dhd_bus_to_dev(dhd->bus));
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+		/* Check and adjust IOCTL response timeout for Manufactring firmware */
+		dhd_os_set_ioctl_resp_timeout(MFG_IOCTL_RESP_TIMEOUT);
+		DHD_ERROR(("%s : Set IOCTL response time for Manufactring Firmware\n",
+			__FUNCTION__));
+	} else {
+		dhd_os_set_ioctl_resp_timeout(IOCTL_RESP_TIMEOUT);
+		DHD_INFO(("%s : Set IOCTL response time.\n", __FUNCTION__));
+	}
+#ifdef BCMPCIE_OOB_HOST_WAKE
+	ret = dhd_iovar(dhd, 0, "bus:hostwake_oob", NULL, 0, (char *)&hostwake_oob,
+		sizeof(hostwake_oob), FALSE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: hostwake_oob IOVAR not present, proceed\n", __FUNCTION__));
+	} else {
+		if (hostwake_oob == 0) {
+			DHD_ERROR(("%s: hostwake_oob is not enabled in the NVRAM, STOP\n",
+				__FUNCTION__));
+			ret = BCME_UNSUPPORTED;
+			goto done;
+		} else {
+			DHD_ERROR(("%s: hostwake_oob enabled\n", __FUNCTION__));
+		}
+	}
+#endif /* BCMPCIE_OOB_HOST_WAKE */
+
+#ifdef DNGL_AXI_ERROR_LOGGING
+	ret = dhd_iovar(dhd, 0, "axierror_logbuf_addr", NULL, 0, (char *)&dhd->axierror_logbuf_addr,
+		sizeof(dhd->axierror_logbuf_addr), FALSE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: axierror_logbuf_addr IOVAR not present, proceed\n", __FUNCTION__));
+		dhd->axierror_logbuf_addr = 0;
+	} else {
+		DHD_INFO(("%s: axierror_logbuf_addr : 0x%x\n",
+			__FUNCTION__, dhd->axierror_logbuf_addr));
+	}
+#endif /* DNGL_AXI_ERROR_LOGGING */
+
+#ifdef EVENT_LOG_RATE_HC
+	ret = dhd_iovar(dhd, 0, "event_log_rate_hc", (char *)&event_log_rate_hc,
+		sizeof(event_log_rate_hc), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s event_log_rate_hc set failed %d\n", __FUNCTION__, ret));
+	} else  {
+		DHD_ERROR(("%s event_log_rate_hc set with threshold:%d\n", __FUNCTION__,
+			event_log_rate_hc));
+	}
+#endif /* EVENT_LOG_RATE_HC */
+
+	ret = dhd_conf_custom_mac(dhd);
+	if (ret)
+		goto done;
+	else
+	{
+		/* Get the default device MAC address directly from firmware */
+		ret = dhd_iovar(dhd, 0, "cur_etheraddr", NULL, 0, (char *)&buf, sizeof(buf), FALSE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: can't get MAC address , error=%d\n", __FUNCTION__, ret));
+			ret = BCME_NOTUP;
+			goto done;
+		}
+
+		DHD_ERROR(("%s: use firmware generated mac_address "MACDBG"\n",
+			__FUNCTION__, MAC2STRDBG(&buf)));
+
+#ifdef MACADDR_PROVISION_ENFORCED
+		if (ETHER_IS_LOCALADDR(buf)) {
+			DHD_ERROR(("%s: error! not using provision mac addr!\n", __FUNCTION__));
+			ret = BCME_BADADDR;
+			goto done;
+		}
+#endif /* MACADDR_PROVISION_ENFORCED */
+
+		/* Update public MAC address after reading from Firmware */
+		memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN);
+	}
+
+	if (ETHER_ISNULLADDR(dhd->mac.octet)) {
+		DHD_ERROR(("%s: NULL MAC address during pre-init\n", __FUNCTION__));
+		ret = BCME_BADADDR;
+		goto done;
+	} else {
+		(void)memcpy_s(dhd_linux_get_primary_netdev(dhd)->perm_addr, ETHER_ADDR_LEN,
+			dhd->mac.octet, ETHER_ADDR_LEN);
+	}
+#if defined(WL_STA_ASSOC_RAND) && defined(WL_STA_INIT_RAND)
+	/* Set cur_etheraddr of primary interface to randomized address to ensure
+	 * that any action frame transmission will happen using randomized macaddr
+	 * primary netdev->perm_addr will hold the original factory MAC.
+	 */
+#ifdef WL_STA_INIT_RAND_CTRL
+	if (dhd_sta_init_rand)
+#endif /* WL_STA_INIT_RAND_CTRL */
+	{
+		if ((ret = dhd_update_rand_mac_addr(dhd)) < 0) {
+			DHD_ERROR(("%s: failed to set macaddress\n", __FUNCTION__));
+			goto done;
+		}
+	}
+#endif /* WL_STA_ASSOC_RAND && WL_STA_INIT_RAND */
+#ifdef BCMDBUS
+	if (dhd->info->clm_path[0] == '\0') {
+		if ((strlen(clm_path) > MOD_PARAM_PATHLEN) ||
+			(strlen(clm_path) >= sizeof(dhd->info->clm_path))) {
+			DHD_ERROR(("%s clm path exceeds max len\n", __FUNCTION__));
+			ret = BCME_BADLEN;
+			goto done;
+		}
+		strlcpy(dhd->info->clm_path, clm_path, sizeof(dhd->info->clm_path));
+	}
+#endif /* BCMDBUS */
+
+	if ((ret = dhd_apply_default_clm(dhd, dhd->info->clm_path)) < 0) {
+		DHD_ERROR(("%s: CLM set failed. Ignore and continue initialization.\n",
+			__FUNCTION__));
+	}
+
+	/* get a capabilities from firmware */
+	{
+		uint32 cap_buf_size = sizeof(dhd->fw_capabilities);
+		memset(dhd->fw_capabilities, 0, cap_buf_size);
+		ret = dhd_iovar(dhd, 0, "cap", NULL, 0, dhd->fw_capabilities, (cap_buf_size - 1),
+				FALSE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: Get Capability failed (error=%d)\n",
+				__FUNCTION__, ret));
+			return 0;
+		}
+
+		memmove(&dhd->fw_capabilities[1], dhd->fw_capabilities, (cap_buf_size - 1));
+		dhd->fw_capabilities[0] = ' ';
+		dhd->fw_capabilities[cap_buf_size - 2] = ' ';
+		dhd->fw_capabilities[cap_buf_size - 1] = '\0';
+	}
+
+	if ((!op_mode && dhd_get_fw_mode(dhd->info) == DHD_FLAG_HOSTAP_MODE) ||
+		(op_mode == DHD_FLAG_HOSTAP_MODE)) {
+#ifdef SET_RANDOM_MAC_SOFTAP
+		uint rand_mac;
+#endif /* SET_RANDOM_MAC_SOFTAP */
+		dhd->op_mode = DHD_FLAG_HOSTAP_MODE;
+#ifdef PKT_FILTER_SUPPORT
+		if (dhd_conf_get_insuspend(dhd, AP_FILTER_IN_SUSPEND))
+			dhd_pkt_filter_enable = TRUE;
+		else
+			dhd_pkt_filter_enable = FALSE;
+#endif
+#ifdef SET_RANDOM_MAC_SOFTAP
+		rand_mac = RANDOM32();
+		iovbuf[0] = (unsigned char)(vendor_oui >> 16) | 0x02;	/* local admin bit */
+		iovbuf[1] = (unsigned char)(vendor_oui >> 8);
+		iovbuf[2] = (unsigned char)vendor_oui;
+		iovbuf[3] = (unsigned char)(rand_mac & 0x0F) | 0xF0;
+		iovbuf[4] = (unsigned char)(rand_mac >> 8);
+		iovbuf[5] = (unsigned char)(rand_mac >> 16);
+
+		ret = dhd_iovar(dhd, 0, "cur_etheraddr", (char *)&iovbuf, ETHER_ADDR_LEN, NULL, 0,
+				TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: can't set MAC address , error=%d\n", __FUNCTION__, ret));
+		} else
+			memcpy(dhd->mac.octet, iovbuf, ETHER_ADDR_LEN);
+#endif /* SET_RANDOM_MAC_SOFTAP */
+#if defined(USE_DYNAMIC_F2_BLKSIZE) && defined(DYNAMIC_F2_BLKSIZE_FOR_NONLEGACY)
+		dhdsdio_func_blocksize(dhd, 2, DYNAMIC_F2_BLKSIZE_FOR_NONLEGACY);
+#endif /* USE_DYNAMIC_F2_BLKSIZE */
+#ifdef SUPPORT_AP_POWERSAVE
+		dhd_set_ap_powersave(dhd, 0, TRUE);
+#endif /* SUPPORT_AP_POWERSAVE */
+#ifdef SOFTAP_UAPSD_OFF
+		ret = dhd_iovar(dhd, 0, "wme_apsd", (char *)&wme_apsd, sizeof(wme_apsd), NULL, 0,
+				TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: set wme_apsd 0 fail (error=%d)\n",
+				__FUNCTION__, ret));
+		}
+#endif /* SOFTAP_UAPSD_OFF */
+
+		/* set AP flag for specific country code of SOFTAP */
+#if defined(CUSTOM_COUNTRY_CODE)
+		dhd->dhd_cflags |= WLAN_PLAT_AP_FLAG | WLAN_PLAT_NODFS_FLAG;
+#endif /* CUSTOM_COUNTRY_CODE */
+	} else if ((!op_mode && dhd_get_fw_mode(dhd->info) == DHD_FLAG_MFG_MODE) ||
+		(op_mode == DHD_FLAG_MFG_MODE)) {
+#if defined(ARP_OFFLOAD_SUPPORT)
+		dhd->arpoe_enable = FALSE;
+#endif /* ARP_OFFLOAD_SUPPORT */
+#ifdef PKT_FILTER_SUPPORT
+		dhd_pkt_filter_enable = FALSE;
+#endif /* PKT_FILTER_SUPPORT */
+		dhd->op_mode = DHD_FLAG_MFG_MODE;
+#if defined(USE_DYNAMIC_F2_BLKSIZE) && defined(DYNAMIC_F2_BLKSIZE_FOR_NONLEGACY)
+		/* XXX The 'wl counters' command triggers SDIO bus error
+		 * if F2 block size is greater than 128 bytes using 4354A1
+		 * manufacturing firmware. To avoid this problem, F2 block
+		 * size is set to 128 bytes only for DHD_FLAG_MFG_MODE.
+		 * There is no problem for other chipset since big data
+		 * transcation through SDIO bus is not happened during
+		 * manufacturing test.
+		 */
+		dhdsdio_func_blocksize(dhd, 2, DYNAMIC_F2_BLKSIZE_FOR_NONLEGACY);
+#endif /* USE_DYNAMIC_F2_BLKSIZE */
+#ifndef CUSTOM_SET_ANTNPM
+		if (FW_SUPPORTED(dhd, rsdb)) {
+			wl_config_t rsdb_mode;
+			memset(&rsdb_mode, 0, sizeof(rsdb_mode));
+			ret = dhd_iovar(dhd, 0, "rsdb_mode", (char *)&rsdb_mode, sizeof(rsdb_mode),
+				NULL, 0, TRUE);
+			if (ret < 0) {
+				DHD_ERROR(("%s Disable rsdb_mode is failed ret= %d\n",
+					__FUNCTION__, ret));
+			}
+		}
+#endif /* !CUSTOM_SET_ANTNPM */
+	} else {
+		uint32 concurrent_mode = 0;
+		if ((!op_mode && dhd_get_fw_mode(dhd->info) == DHD_FLAG_P2P_MODE) ||
+			(op_mode == DHD_FLAG_P2P_MODE)) {
+#ifdef PKT_FILTER_SUPPORT
+			dhd_pkt_filter_enable = FALSE;
+#endif
+			dhd->op_mode = DHD_FLAG_P2P_MODE;
+		} else if ((!op_mode && dhd_get_fw_mode(dhd->info) == DHD_FLAG_IBSS_MODE) ||
+			(op_mode == DHD_FLAG_IBSS_MODE)) {
+			dhd->op_mode = DHD_FLAG_IBSS_MODE;
+		} else
+			dhd->op_mode = DHD_FLAG_STA_MODE;
+#if !defined(AP) && defined(WLP2P)
+		if (dhd->op_mode != DHD_FLAG_IBSS_MODE &&
+			(concurrent_mode = dhd_get_concurrent_capabilites(dhd))) {
+			dhd->op_mode |= concurrent_mode;
+		}
+
+		/* Check if we are enabling p2p */
+		if (dhd->op_mode & DHD_FLAG_P2P_MODE) {
+			ret = dhd_iovar(dhd, 0, "apsta", (char *)&apsta, sizeof(apsta), NULL, 0,
+					TRUE);
+			if (ret < 0)
+				DHD_ERROR(("%s APSTA for P2P failed ret= %d\n", __FUNCTION__, ret));
+
+#if defined(SOFTAP_AND_GC)
+		if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_AP,
+			(char *)&ap_mode, sizeof(ap_mode), TRUE, 0)) < 0) {
+				DHD_ERROR(("%s WLC_SET_AP failed %d\n", __FUNCTION__, ret));
+		}
+#endif
+			memcpy(&p2p_ea, &dhd->mac, ETHER_ADDR_LEN);
+			ETHER_SET_LOCALADDR(&p2p_ea);
+			ret = dhd_iovar(dhd, 0, "p2p_da_override", (char *)&p2p_ea, sizeof(p2p_ea),
+					NULL, 0, TRUE);
+			if (ret < 0)
+				DHD_ERROR(("%s p2p_da_override ret= %d\n", __FUNCTION__, ret));
+			else
+				DHD_INFO(("dhd_preinit_ioctls: p2p_da_override succeeded\n"));
+		}
+#else
+	(void)concurrent_mode;
+#endif /* !defined(AP) && defined(WLP2P) */
+	}
+
+#ifdef DISABLE_PRUNED_SCAN
+	if (FW_SUPPORTED(dhd, rsdb)) {
+		ret = dhd_iovar(dhd, 0, "scan_features", (char *)&scan_features,
+				sizeof(scan_features), iovbuf, sizeof(iovbuf), FALSE);
+		if (ret < 0) {
+			if (ret == BCME_UNSUPPORTED) {
+				DHD_ERROR(("%s get scan_features, UNSUPPORTED\n",
+					__FUNCTION__));
+			} else {
+				DHD_ERROR(("%s get scan_features err(%d)\n",
+					__FUNCTION__, ret));
+			}
+
+		} else {
+			memcpy(&scan_features, iovbuf, 4);
+			scan_features &= ~RSDB_SCAN_DOWNGRADED_CH_PRUNE_ROAM;
+			ret = dhd_iovar(dhd, 0, "scan_features", (char *)&scan_features,
+					sizeof(scan_features), NULL, 0, TRUE);
+			if (ret < 0) {
+				DHD_ERROR(("%s set scan_features err(%d)\n",
+					__FUNCTION__, ret));
+			}
+		}
+	}
+#endif /* DISABLE_PRUNED_SCAN */
+
+	DHD_ERROR(("Firmware up: op_mode=0x%04x, MAC="MACDBG"\n",
+		dhd->op_mode, MAC2STRDBG(dhd->mac.octet)));
+#if defined(DHD_BLOB_EXISTENCE_CHECK)
+	if (!dhd->is_blob)
+#endif /* DHD_BLOB_EXISTENCE_CHECK */
+	{
+		/* get a ccode and revision for the country code */
+#if defined(CUSTOM_COUNTRY_CODE)
+		get_customized_country_code(dhd->info->adapter, dhd->dhd_cspec.country_abbrev,
+			&dhd->dhd_cspec, dhd->dhd_cflags);
+#else
+		get_customized_country_code(dhd->info->adapter, dhd->dhd_cspec.country_abbrev,
+			&dhd->dhd_cspec);
+#endif /* CUSTOM_COUNTRY_CODE */
+	}
+
+#if defined(RXFRAME_THREAD) && defined(RXTHREAD_ONLYSTA)
+	if (dhd->op_mode == DHD_FLAG_HOSTAP_MODE)
+		dhd->info->rxthread_enabled = FALSE;
+	else
+		dhd->info->rxthread_enabled = TRUE;
+#endif
+
+#if defined(CUSTOM_COUNTRY_CODE_XZ)
+	/* Set initial country code to XZ */
+	strlcpy(dhd->dhd_cspec.country_abbrev, "XZ", WLC_CNTRY_BUF_SZ);
+	strlcpy(dhd->dhd_cspec.ccode, "XZ", WLC_CNTRY_BUF_SZ);
+	DHD_ERROR(("%s: Set initial country code to XZ(World Wide Safe)\n", __FUNCTION__));
+#endif /* CUSTOM_COUNTRY_CODE_XZ */
+	/* Set Country code  */
+	if (dhd->dhd_cspec.ccode[0] != 0) {
+		ret = dhd_iovar(dhd, 0, "country", (char *)&dhd->dhd_cspec, sizeof(wl_country_t),
+				NULL, 0, TRUE);
+		if (ret < 0)
+			DHD_ERROR(("%s: country code setting failed\n", __FUNCTION__));
+	}
+
+#if defined(DISABLE_11AC)
+	ret = dhd_iovar(dhd, 0, "vhtmode", (char *)&vhtmode, sizeof(vhtmode), NULL, 0, TRUE);
+	if (ret < 0)
+		DHD_ERROR(("%s wl vhtmode 0 failed %d\n", __FUNCTION__, ret));
+#endif /* DISABLE_11AC */
+
+	/* Set Listen Interval */
+	ret = dhd_iovar(dhd, 0, "assoc_listen", (char *)&listen_interval, sizeof(listen_interval),
+			NULL, 0, TRUE);
+	if (ret < 0)
+		DHD_ERROR(("%s assoc_listen failed %d\n", __FUNCTION__, ret));
+
+#if defined(ROAM_ENABLE) || defined(DISABLE_BUILTIN_ROAM)
+#ifdef USE_WFA_CERT_CONF
+	if (sec_get_param_wfa_cert(dhd, SET_PARAM_ROAMOFF, &roamvar) == BCME_OK) {
+		DHD_ERROR(("%s: read roam_off param =%d\n", __FUNCTION__, roamvar));
+	}
+#endif /* USE_WFA_CERT_CONF */
+	/* Disable built-in roaming to allowed ext supplicant to take care of roaming */
+	ret = dhd_iovar(dhd, 0, "roam_off", (char *)&roamvar, sizeof(roamvar), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s roam_off failed %d\n", __FUNCTION__, ret));
+	}
+	ROAMOFF_DBG_SAVE(dhd_linux_get_primary_netdev(dhd), SET_ROAM_PREINIT, roamvar);
+#endif /* ROAM_ENABLE || DISABLE_BUILTIN_ROAM */
+#if defined(ROAM_ENABLE)
+#ifdef DISABLE_BCNLOSS_ROAM
+	ret = dhd_iovar(dhd, 0, "roam_bcnloss_off", (char *)&roam_bcnloss_off,
+			sizeof(roam_bcnloss_off), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s roam_bcnloss_off failed %d\n", __FUNCTION__, ret));
+	}
+#endif /* DISABLE_BCNLOSS_ROAM */
+	if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_TRIGGER, roam_trigger,
+		sizeof(roam_trigger), TRUE, 0)) < 0)
+		DHD_ERROR(("%s: roam trigger set failed %d\n", __FUNCTION__, ret));
+	if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_SCAN_PERIOD, roam_scan_period,
+		sizeof(roam_scan_period), TRUE, 0)) < 0)
+		DHD_ERROR(("%s: roam scan period set failed %d\n", __FUNCTION__, ret));
+	if ((dhd_wl_ioctl_cmd(dhd, WLC_SET_ROAM_DELTA, roam_delta,
+		sizeof(roam_delta), TRUE, 0)) < 0)
+		DHD_ERROR(("%s: roam delta set failed %d\n", __FUNCTION__, ret));
+	ret = dhd_iovar(dhd, 0, "fullroamperiod", (char *)&roam_fullscan_period,
+			sizeof(roam_fullscan_period), NULL, 0, TRUE);
+	if (ret < 0)
+		DHD_ERROR(("%s: roam fullscan period set failed %d\n", __FUNCTION__, ret));
+#ifdef ROAM_AP_ENV_DETECTION
+	if (roam_trigger[0] == WL_AUTO_ROAM_TRIGGER) {
+		if (dhd_iovar(dhd, 0, "roam_env_detection", (char *)&roam_env_mode,
+				sizeof(roam_env_mode), NULL, 0, TRUE) == BCME_OK)
+			dhd->roam_env_detection = TRUE;
+		else
+			dhd->roam_env_detection = FALSE;
+	}
+#endif /* ROAM_AP_ENV_DETECTION */
+#ifdef CONFIG_ROAM_RSSI_LIMIT
+	ret = dhd_roam_rssi_limit_set(dhd, CUSTOM_ROAMRSSI_2G, CUSTOM_ROAMRSSI_5G);
+	if (ret < 0) {
+		DHD_ERROR(("%s set roam_rssi_limit failed ret %d\n", __FUNCTION__, ret));
+	}
+#endif /* CONFIG_ROAM_RSSI_LIMIT */
+#ifdef CONFIG_ROAM_MIN_DELTA
+	ret = dhd_roam_min_delta_set(dhd, CUSTOM_ROAM_MIN_DELTA, CUSTOM_ROAM_MIN_DELTA);
+	if (ret < 0) {
+		DHD_ERROR(("%s set roam_min_delta failed ret %d\n", __FUNCTION__, ret));
+	}
+#endif /* CONFIG_ROAM_MIN_DELTA */
+#endif /* ROAM_ENABLE */
+
+#ifdef CUSTOM_EVENT_PM_WAKE
+	dhd_init_excess_pm_awake(dhd);
+#endif	/* CUSTOM_EVENT_PM_WAKE */
+#ifdef OKC_SUPPORT
+	dhd_iovar(dhd, 0, "okc_enable", (char *)&okc, sizeof(okc), NULL, 0, TRUE);
+#endif
+#ifdef BCMCCX
+	dhd_iovar(dhd, 0, "ccx_enable", (char *)&ccx, sizeof(ccx), NULL, 0, TRUE);
+#endif /* BCMCCX */
+
+#ifdef WLTDLS
+	dhd->tdls_enable = FALSE;
+	dhd_tdls_set_mode(dhd, false);
+#endif /* WLTDLS */
+
+#ifdef DHD_ENABLE_LPC
+	/* Set lpc 1 */
+	ret = dhd_iovar(dhd, 0, "lpc", (char *)&lpc, sizeof(lpc), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s Set lpc failed  %d\n", __FUNCTION__, ret));
+
+		if (ret == BCME_NOTDOWN) {
+			uint wl_down = 1;
+			ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN,
+				(char *)&wl_down, sizeof(wl_down), TRUE, 0);
+			DHD_ERROR(("%s lpc fail WL_DOWN : %d, lpc = %d\n", __FUNCTION__, ret, lpc));
+
+			ret = dhd_iovar(dhd, 0, "lpc", (char *)&lpc, sizeof(lpc), NULL, 0, TRUE);
+			DHD_ERROR(("%s Set lpc ret --> %d\n", __FUNCTION__, ret));
+		}
+	}
+#endif /* DHD_ENABLE_LPC */
+
+#ifdef WLADPS
+	if (dhd->op_mode & DHD_FLAG_STA_MODE) {
+		if ((ret = dhd_enable_adps(dhd, ADPS_MODE_PM2_ONLY)) != BCME_OK &&
+			(ret != BCME_UNSUPPORTED)) {
+			DHD_ERROR(("%s dhd_enable_adps failed %d\n",
+				__FUNCTION__, ret));
+		}
+	}
+#endif /* WLADPS */
+
+#ifdef DHD_PM_CONTROL_FROM_FILE
+	sec_control_pm(dhd, &power_mode);
+#else
+	/* Set PowerSave mode */
+	(void) dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0);
+#endif /* DHD_PM_CONTROL_FROM_FILE */
+#ifdef ASSOC_PREFER_RSSI_THRESH
+	ret = dhd_iovar(dhd, 0, "assoc_pref_rssi_thresh", (char *)&assoc_pref_rssi_thresh,
+		sizeof(assoc_pref_rssi_thresh), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s set assoc_pref_rssi_thresh failed %d\n", __FUNCTION__, ret));
+	}
+#endif /* ASSOC_PREFER_RSSI_THRESH */
+#ifdef HIGHBANDROAM_ENABLE
+	ret = dhd_iovar(dhd, 0, "highbandroam", (char *)&highbandroam_enable,
+			sizeof(highbandroam_enable), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s set highbandroam_enable failed %d\n", __FUNCTION__, ret));
+	}
+#endif /* ASSOC_PREFER_RSSI_THRESH */
+#if defined(BCMSDIO)
+	/* Match Host and Dongle rx alignment */
+	ret = dhd_iovar(dhd, 0, "bus:txglomalign", (char *)&dongle_align, sizeof(dongle_align),
+			NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s set bus:txglomalign failed %d\n", __FUNCTION__, ret));
+	}
+
+#ifdef USE_WFA_CERT_CONF
+	if (sec_get_param_wfa_cert(dhd, SET_PARAM_BUS_TXGLOM_MODE, &glom) == BCME_OK) {
+		DHD_ERROR(("%s, read txglom param =%d\n", __FUNCTION__, glom));
+	}
+#endif /* USE_WFA_CERT_CONF */
+	if (glom != DEFAULT_GLOM_VALUE) {
+		DHD_INFO(("%s set glom=0x%X\n", __FUNCTION__, glom));
+		ret = dhd_iovar(dhd, 0, "bus:txglom", (char *)&glom, sizeof(glom), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s set bus:txglom failed %d\n", __FUNCTION__, ret));
+		}
+	}
+#ifdef PROP_TXSTATUS
+	ret = dhd_iovar(dhd, 0, "bus:simutx_limit", NULL, 0,
+		(char *)&simutx_limit, sizeof(simutx_limit), FALSE);
+	dhd->simutx_limit = WL_TXSTATUS_FREERUNCTR_MASK;
+	if (ret == 0) {
+		dhd->simutx_limit = simutx_limit;
+	}
+#endif /* PROP_TXSTATUS */
+#endif /* defined(BCMSDIO) */
+
+	/* Setup timeout if Beacons are lost and roam is off to report link down */
+	ret = dhd_iovar(dhd, 0, "bcn_timeout", (char *)&bcn_timeout, sizeof(bcn_timeout),
+			NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s set bcn_timeout failed %d\n", __FUNCTION__, ret));
+	}
+
+	/* Setup assoc_retry_max count to reconnect target AP in dongle */
+	ret = dhd_iovar(dhd, 0, "assoc_retry_max", (char *)&retry_max, sizeof(retry_max),
+			NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s set assoc_retry_max failed %d\n", __FUNCTION__, ret));
+	}
+
+#if defined(AP) && !defined(WLP2P)
+	ret = dhd_iovar(dhd, 0, "apsta", (char *)&apsta, sizeof(apsta), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s set apsta failed %d\n", __FUNCTION__, ret));
+	}
+
+#endif /* defined(AP) && !defined(WLP2P) */
+
+#ifdef MIMO_ANT_SETTING
+	dhd_sel_ant_from_file(dhd);
+#endif /* MIMO_ANT_SETTING */
+
+#if defined(OEM_ANDROID) && defined(SOFTAP)
+	if (ap_fw_loaded == TRUE) {
+		dhd_wl_ioctl_cmd(dhd, WLC_SET_DTIMPRD, (char *)&dtim, sizeof(dtim), TRUE, 0);
+	}
+#endif /* defined(OEM_ANDROID) && defined(SOFTAP) */
+
+#if defined(KEEP_ALIVE)
+	{
+	/* Set Keep Alive : be sure to use FW with -keepalive */
+	int res;
+
+#if defined(OEM_ANDROID) && defined(SOFTAP)
+	if (ap_fw_loaded == FALSE)
+#endif /* defined(OEM_ANDROID) && defined(SOFTAP) */
+		if (!(dhd->op_mode &
+			(DHD_FLAG_HOSTAP_MODE | DHD_FLAG_MFG_MODE))) {
+			if ((res = dhd_keep_alive_onoff(dhd)) < 0)
+				DHD_ERROR(("%s set keeplive failed %d\n",
+				__FUNCTION__, res));
+		}
+	}
+#endif /* defined(KEEP_ALIVE) */
+
+#ifdef USE_WL_TXBF
+	ret = dhd_iovar(dhd, 0, "txbf", (char *)&txbf, sizeof(txbf), NULL, 0, TRUE);
+	if (ret < 0)
+		DHD_ERROR(("%s Set txbf failed  %d\n", __FUNCTION__, ret));
+
+#endif /* USE_WL_TXBF */
+
+	ret = dhd_iovar(dhd, 0, "scancache", (char *)&scancache_enab, sizeof(scancache_enab), NULL,
+			0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s Set scancache failed %d\n", __FUNCTION__, ret));
+	}
+
+#else /* OEM_ANDROID */
+#ifdef BCMDBUS
+	if (dhd->info->clm_path[0] == '\0') {
+		if (strlen(clm_path) > MOD_PARAM_PATHLEN) {
+			DHD_ERROR(("%s clm path exceeds max len\n", __FUNCTION__));
+			ret = BCME_BADLEN;
+			goto done;
+		}
+		strlcpy(dhd->info->clm_path, clm_path, strlen(clm_path)+1);
+	}
+#endif /* BCMDBUS */
+	if ((ret = dhd_apply_default_clm(dhd, dhd->info->clm_path)) < 0) {
+		DHD_ERROR(("%s: CLM set failed. Ignore and continue initialization.\n",
+			__FUNCTION__));
+	}
+
+#if defined(KEEP_ALIVE)
+	if (!(dhd->op_mode &
+		(DHD_FLAG_HOSTAP_MODE | DHD_FLAG_MFG_MODE))) {
+		if ((ret = dhd_keep_alive_onoff(dhd)) < 0)
+			DHD_ERROR(("%s set keeplive failed %d\n",
+			__FUNCTION__, ret));
+	}
+#endif
+
+	/* get a capabilities from firmware */
+	memset(dhd->fw_capabilities, 0, sizeof(dhd->fw_capabilities));
+	ret = dhd_iovar(dhd, 0, "cap", NULL, 0, dhd->fw_capabilities, sizeof(dhd->fw_capabilities),
+			FALSE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: Get Capability failed (error=%d)\n",
+			__FUNCTION__, ret));
+		goto done;
+	}
+#endif  /* OEM_ANDROID */
+
+	ret = dhd_iovar(dhd, 0, "event_log_max_sets", NULL, 0, (char *)&event_log_max_sets,
+		sizeof(event_log_max_sets), FALSE);
+	if (ret == BCME_OK) {
+		dhd->event_log_max_sets = event_log_max_sets;
+	} else {
+		dhd->event_log_max_sets = NUM_EVENT_LOG_SETS;
+	}
+	/* Make sure max_sets is set first with wmb and then sets_queried,
+	 * this will be used during parsing the logsets in the reverse order.
+	 */
+	OSL_SMP_WMB();
+	dhd->event_log_max_sets_queried = TRUE;
+	DHD_ERROR(("%s: event_log_max_sets: %d ret: %d\n",
+		__FUNCTION__, dhd->event_log_max_sets, ret));
+#ifdef DHD_BUS_MEM_ACCESS
+	ret = dhd_iovar(dhd, 0, "enable_memuse", (char *)&enable_memuse,
+			sizeof(enable_memuse), iovbuf, sizeof(iovbuf), FALSE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: enable_memuse is failed ret=%d\n",
+			__FUNCTION__, ret));
+	} else {
+		DHD_ERROR(("%s: enable_memuse = %d\n",
+			__FUNCTION__, enable_memuse));
+	}
+#endif /* DHD_BUS_MEM_ACCESS */
+
+#ifdef DISABLE_TXBFR
+	ret = dhd_iovar(dhd, 0, "txbf_bfr_cap", (char *)&txbf_bfr_cap, sizeof(txbf_bfr_cap), NULL,
+			0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s Clear txbf_bfr_cap failed  %d\n", __FUNCTION__, ret));
+	}
+#endif /* DISABLE_TXBFR */
+
+#ifdef USE_WFA_CERT_CONF
+#ifdef USE_WL_FRAMEBURST
+	 if (sec_get_param_wfa_cert(dhd, SET_PARAM_FRAMEBURST, &frameburst) == BCME_OK) {
+		DHD_ERROR(("%s, read frameburst param=%d\n", __FUNCTION__, frameburst));
+	 }
+#endif /* USE_WL_FRAMEBURST */
+	 g_frameburst = frameburst;
+#endif /* USE_WFA_CERT_CONF */
+#ifdef DISABLE_WL_FRAMEBURST_SOFTAP
+	/* Disable Framebursting for SofAP */
+	if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
+		frameburst = 0;
+	}
+#endif /* DISABLE_WL_FRAMEBURST_SOFTAP */
+	/* Set frameburst to value */
+	if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_FAKEFRAG, (char *)&frameburst,
+		sizeof(frameburst), TRUE, 0)) < 0) {
+		DHD_INFO(("%s frameburst not supported  %d\n", __FUNCTION__, ret));
+	}
+#ifdef DHD_SET_FW_HIGHSPEED
+	/* Set ack_ratio */
+	ret = dhd_iovar(dhd, 0, "ack_ratio", (char *)&ack_ratio, sizeof(ack_ratio), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s Set ack_ratio failed  %d\n", __FUNCTION__, ret));
+	}
+
+	/* Set ack_ratio_depth */
+	ret = dhd_iovar(dhd, 0, "ack_ratio_depth", (char *)&ack_ratio_depth,
+			sizeof(ack_ratio_depth), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s Set ack_ratio_depth failed  %d\n", __FUNCTION__, ret));
+	}
+#endif /* DHD_SET_FW_HIGHSPEED */
+
+	iov_buf = (char*)MALLOC(dhd->osh, WLC_IOCTL_SMLEN);
+	if (iov_buf == NULL) {
+		DHD_ERROR(("failed to allocate %d bytes for iov_buf\n", WLC_IOCTL_SMLEN));
+		ret = BCME_NOMEM;
+		goto done;
+	}
+
+	BCM_REFERENCE(ret2);
+
+#if defined(CUSTOM_AMPDU_BA_WSIZE)
+	/* Set ampdu ba wsize to 64 or 16 */
+#ifdef CUSTOM_AMPDU_BA_WSIZE
+	ampdu_ba_wsize = CUSTOM_AMPDU_BA_WSIZE;
+#endif
+	if (ampdu_ba_wsize != 0) {
+		ret = dhd_iovar(dhd, 0, "ampdu_ba_wsize", (char *)&ampdu_ba_wsize,
+				sizeof(ampdu_ba_wsize), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s Set ampdu_ba_wsize to %d failed  %d\n",
+				__FUNCTION__, ampdu_ba_wsize, ret));
+		}
+	}
+#endif /* CUSTOM_AMPDU_BA_WSIZE */
+
+#if defined(CUSTOM_AMPDU_MPDU)
+	ampdu_mpdu = CUSTOM_AMPDU_MPDU;
+#ifdef BCMSDIO
+	ret = dhdsdio_mpdu_init(dhd);
+	if (0 != ret)
+		ampdu_mpdu = ret;
+#endif
+	if (ampdu_mpdu != 0 && (ampdu_mpdu <= ampdu_ba_wsize)) {
+		ret = dhd_iovar(dhd, 0, "ampdu_mpdu", (char *)&ampdu_mpdu, sizeof(ampdu_mpdu),
+				NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s Set ampdu_mpdu to %d failed  %d\n",
+				__FUNCTION__, CUSTOM_AMPDU_MPDU, ret));
+		}
+	}
+#endif /* CUSTOM_AMPDU_MPDU */
+
+#if defined(CUSTOM_AMPDU_RELEASE)
+	ampdu_release = CUSTOM_AMPDU_RELEASE;
+	if (ampdu_release != 0 && (ampdu_release <= ampdu_ba_wsize)) {
+		ret = dhd_iovar(dhd, 0, "ampdu_release", (char *)&ampdu_release,
+				sizeof(ampdu_release), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s Set ampdu_release to %d failed  %d\n",
+				__FUNCTION__, CUSTOM_AMPDU_RELEASE, ret));
+		}
+	}
+#endif /* CUSTOM_AMPDU_RELEASE */
+
+#if defined(CUSTOM_AMSDU_AGGSF)
+	amsdu_aggsf = CUSTOM_AMSDU_AGGSF;
+	if (amsdu_aggsf != 0) {
+		ret = dhd_iovar(dhd, 0, "amsdu_aggsf", (char *)&amsdu_aggsf, sizeof(amsdu_aggsf),
+				NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s Set amsdu_aggsf to %d failed  %d\n",
+				__FUNCTION__, CUSTOM_AMSDU_AGGSF, ret));
+		}
+	}
+#endif /* CUSTOM_AMSDU_AGGSF */
+
+#if defined(BCMSUP_4WAY_HANDSHAKE)
+	/* Read 4-way handshake requirements */
+	if (dhd_use_idsup == 1) {
+		ret = dhd_iovar(dhd, 0, "sup_wpa", (char *)&sup_wpa, sizeof(sup_wpa),
+				(char *)&iovbuf, sizeof(iovbuf), FALSE);
+		/* sup_wpa iovar returns NOTREADY status on some platforms using modularized
+		 * in-dongle supplicant.
+		 */
+		if (ret >= 0 || ret == BCME_NOTREADY)
+			dhd->fw_4way_handshake = TRUE;
+		DHD_TRACE(("4-way handshake mode is: %d\n", dhd->fw_4way_handshake));
+	}
+#endif /* BCMSUP_4WAY_HANDSHAKE */
+#if defined(SUPPORT_2G_VHT) || defined(SUPPORT_5G_1024QAM_VHT)
+	ret = dhd_iovar(dhd, 0, "vht_features", (char *)&vht_features, sizeof(vht_features),
+			(char *)&vht_features, sizeof(vht_features), FALSE);
+	if (ret < 0) {
+		DHD_ERROR(("%s vht_features get failed %d\n", __FUNCTION__, ret));
+		vht_features = 0;
+	} else {
+#ifdef SUPPORT_2G_VHT
+		vht_features |= 0x3; /* 2G support */
+#endif /* SUPPORT_2G_VHT */
+#ifdef SUPPORT_5G_1024QAM_VHT
+		vht_features |= 0x6; /* 5G 1024 QAM support */
+#endif /* SUPPORT_5G_1024QAM_VHT */
+	}
+	if (vht_features) {
+		ret = dhd_iovar(dhd, 0, "vht_features", (char *)&vht_features, sizeof(vht_features),
+				NULL, 0, TRUE);
+		if (ret < 0) {
+			if (ret == BCME_NOTDOWN) {
+				uint wl_down = 1;
+				ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN,
+					(char *)&wl_down, sizeof(wl_down), TRUE, 0);
+				DHD_ERROR(("%s vht_features fail WL_DOWN : %d,"
+					" vht_features = 0x%x\n",
+					__FUNCTION__, ret, vht_features));
+
+				ret = dhd_iovar(dhd, 0, "vht_features", (char *)&vht_features,
+						sizeof(vht_features), NULL, 0, TRUE);
+
+				DHD_ERROR(("%s vht_features set. ret --> %d\n", __FUNCTION__, ret));
+			}
+			if (ret != BCME_BADOPTION) {
+				DHD_ERROR(("%s vht_features set failed %d\n", __FUNCTION__, ret));
+			} else {
+				DHD_INFO(("%s vht_features ret(%d) - need to check BANDLOCK\n",
+					__FUNCTION__, ret));
+			}
+		}
+	}
+#endif /* SUPPORT_2G_VHT || SUPPORT_5G_1024QAM_VHT */
+#ifdef DISABLE_11N_PROPRIETARY_RATES
+	ret = dhd_iovar(dhd, 0, "ht_features", (char *)&ht_features, sizeof(ht_features), NULL, 0,
+			TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s ht_features set failed %d\n", __FUNCTION__, ret));
+	}
+#endif /* DISABLE_11N_PROPRIETARY_RATES */
+#if defined(DISABLE_HE_ENAB) || defined(CUSTOM_CONTROL_HE_ENAB)
+#if defined(DISABLE_HE_ENAB)
+	/* XXX DISABLE_HE_ENAB has higher priority than CUSTOM_CONTROL_HE_ENAB */
+	control_he_enab = 0;
+#endif /* DISABLE_HE_ENAB */
+	dhd_control_he_enab(dhd, control_he_enab);
+#endif /* DISABLE_HE_ENAB || CUSTOM_CONTROL_HE_ENAB */
+
+#ifdef DISABLE_6G_SUPPORT
+	if (dhd_disable_6g) {
+		ret = dhd_iovar(dhd, 0, "6g_enable", (char *)&enable_6g,
+			sizeof(enable_6g), NULL, 0, TRUE);
+		if (ret < 0) {
+			DHD_ERROR(("%s 6g_enable set failed %d\n", __FUNCTION__, ret));
+		}
+	}
+#endif /* DISABLE_6G_SUPPORT */
+
+#ifdef CUSTOM_PSPRETEND_THR
+	/* Turn off MPC in AP mode */
+	ret = dhd_iovar(dhd, 0, "pspretend_threshold", (char *)&pspretend_thr,
+			sizeof(pspretend_thr), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s pspretend_threshold for HostAPD failed  %d\n",
+			__FUNCTION__, ret));
+	}
+#endif
+
+	/* XXX Enable firmware key buffering before sent 4-way M4 */
+	ret = dhd_iovar(dhd, 0, "buf_key_b4_m4", (char *)&buf_key_b4_m4, sizeof(buf_key_b4_m4),
+			NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s buf_key_b4_m4 set failed %d\n", __FUNCTION__, ret));
+	}
+#ifdef SUPPORT_SET_CAC
+	ret = dhd_iovar(dhd, 0, "cac", (char *)&cac, sizeof(cac), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s Failed to set cac to %d, %d\n", __FUNCTION__, cac, ret));
+	}
+#endif /* SUPPORT_SET_CAC */
+	/* make up event mask ext message iovar for event larger than 128 */
+	msglen = WL_EVENTING_MASK_EXT_LEN + EVENTMSGS_EXT_STRUCT_SIZE;
+	eventmask_msg = (eventmsgs_ext_t*)MALLOC(dhd->osh, msglen);
+	if (eventmask_msg == NULL) {
+		DHD_ERROR(("failed to allocate %d bytes for event_msg_ext\n", msglen));
+		ret = BCME_NOMEM;
+		goto done;
+	}
+	bzero(eventmask_msg, msglen);
+	eventmask_msg->ver = EVENTMSGS_VER;
+	eventmask_msg->len = ROUNDUP(WLC_E_LAST, NBBY)/NBBY;
+
+	/* Read event_msgs_ext mask */
+	ret = dhd_iovar(dhd, 0, "event_msgs_ext", (char *)eventmask_msg, msglen, iov_buf,
+			WLC_IOCTL_SMLEN, FALSE);
+
+	/* event_msgs_ext must be supported */
+	if (ret != BCME_OK) {
+		DHD_ERROR(("%s read event mask ext failed %d\n", __FUNCTION__, ret));
+		goto done;
+	}
+
+	bcopy(iov_buf, eventmask_msg, msglen);
+	/* make up event mask ext message iovar for event larger than 128 */
+	mask = eventmask_msg->mask;
+
+	/* Setup event_msgs */
+	setbit(mask, WLC_E_SET_SSID);
+	setbit(mask, WLC_E_PRUNE);
+	setbit(mask, WLC_E_AUTH);
+	setbit(mask, WLC_E_AUTH_IND);
+	setbit(mask, WLC_E_ASSOC);
+	setbit(mask, WLC_E_REASSOC);
+	setbit(mask, WLC_E_REASSOC_IND);
+	if (!(dhd->op_mode & DHD_FLAG_IBSS_MODE))
+		setbit(mask, WLC_E_DEAUTH);
+	setbit(mask, WLC_E_DEAUTH_IND);
+	setbit(mask, WLC_E_DISASSOC_IND);
+	setbit(mask, WLC_E_DISASSOC);
+	setbit(mask, WLC_E_JOIN);
+	setbit(mask, WLC_E_START);
+	setbit(mask, WLC_E_ASSOC_IND);
+	setbit(mask, WLC_E_PSK_SUP);
+	setbit(mask, WLC_E_LINK);
+	setbit(mask, WLC_E_MIC_ERROR);
+	setbit(mask, WLC_E_ASSOC_REQ_IE);
+	setbit(mask, WLC_E_ASSOC_RESP_IE);
+#ifdef LIMIT_BORROW
+	setbit(mask, WLC_E_ALLOW_CREDIT_BORROW);
+#endif
+#ifndef WL_CFG80211
+	setbit(mask, WLC_E_PMKID_CACHE);
+//	setbit(mask, WLC_E_TXFAIL); // terence 20181106: remove unnecessary event
+#endif
+	setbit(mask, WLC_E_JOIN_START);
+	setbit(mask, WLC_E_OWE_INFO);
+//	setbit(mask, WLC_E_SCAN_COMPLETE); // terence 20150628: remove redundant event
+#ifdef DHD_DEBUG
+	setbit(mask, WLC_E_SCAN_CONFIRM_IND);
+#endif
+#ifdef PNO_SUPPORT
+	setbit(mask, WLC_E_PFN_NET_FOUND);
+	setbit(mask, WLC_E_PFN_BEST_BATCHING);
+	setbit(mask, WLC_E_PFN_BSSID_NET_FOUND);
+	setbit(mask, WLC_E_PFN_BSSID_NET_LOST);
+#endif /* PNO_SUPPORT */
+	/* enable dongle roaming event */
+#ifdef WL_CFG80211
+#if !defined(ROAM_EVT_DISABLE)
+	setbit(mask, WLC_E_ROAM);
+#endif /* !ROAM_EVT_DISABLE */
+	setbit(mask, WLC_E_BSSID);
+#endif /* WL_CFG80211 */
+#ifdef BCMCCX
+	setbit(mask, WLC_E_ADDTS_IND);
+	setbit(mask, WLC_E_DELTS_IND);
+#endif /* BCMCCX */
+#ifdef WLTDLS
+	setbit(mask, WLC_E_TDLS_PEER_EVENT);
+#endif /* WLTDLS */
+#ifdef RTT_SUPPORT
+	setbit(mask, WLC_E_PROXD);
+#endif /* RTT_SUPPORT */
+#ifdef WL_ESCAN
+	setbit(mask, WLC_E_ESCAN_RESULT);
+#endif /* WL_ESCAN */
+#if !defined(WL_CFG80211) && !defined(OEM_ANDROID)
+	setbit(mask, WLC_E_ESCAN_RESULT);
+#endif
+#ifdef WL_CFG80211
+	setbit(mask, WLC_E_ESCAN_RESULT);
+	setbit(mask, WLC_E_AP_STARTED);
+	setbit(mask, WLC_E_ACTION_FRAME_RX);
+	if (dhd->op_mode & DHD_FLAG_P2P_MODE) {
+		setbit(mask, WLC_E_P2P_DISC_LISTEN_COMPLETE);
+	}
+#endif /* WL_CFG80211 */
+
+#if defined(SHOW_LOGTRACE) && defined(LOGTRACE_FROM_FILE)
+	if (dhd_logtrace_from_file(dhd)) {
+		setbit(mask, WLC_E_TRACE);
+	} else {
+		clrbit(mask, WLC_E_TRACE);
+	}
+#elif defined(SHOW_LOGTRACE)
+	setbit(mask, WLC_E_TRACE);
+#else
+	clrbit(mask, WLC_E_TRACE);
+#endif /* defined(SHOW_LOGTRACE) && defined(LOGTRACE_FROM_FILE) */
+
+	setbit(mask, WLC_E_CSA_COMPLETE_IND);
+#ifdef DHD_WMF
+	setbit(mask, WLC_E_PSTA_PRIMARY_INTF_IND);
+#endif
+#ifdef CUSTOM_EVENT_PM_WAKE
+	setbit(mask, WLC_E_EXCESS_PM_WAKE_EVENT);
+#endif	/* CUSTOM_EVENT_PM_WAKE */
+#ifdef DHD_LOSSLESS_ROAMING
+	setbit(mask, WLC_E_ROAM_PREP);
+#endif
+	/* nan events */
+	setbit(mask, WLC_E_NAN);
+#if defined(PCIE_FULL_DONGLE) && defined(DHD_LOSSLESS_ROAMING)
+	dhd_update_flow_prio_map(dhd, DHD_FLOW_PRIO_LLR_MAP);
+#endif /* defined(PCIE_FULL_DONGLE) && defined(DHD_LOSSLESS_ROAMING) */
+
+#if defined(BCMPCIE) && defined(EAPOL_PKT_PRIO)
+	dhd_update_flow_prio_map(dhd, DHD_FLOW_PRIO_LLR_MAP);
+#endif /* defined(BCMPCIE) && defined(EAPOL_PKT_PRIO) */
+
+#if defined(BCMSDIO) && defined(DHD_LOSSLESS_ROAMING)
+	dhd_update_sdio_data_prio_map(dhd);
+#endif /* BCMSDIO && DHD_LOSSLESS_ROAMING */
+
+#ifdef RSSI_MONITOR_SUPPORT
+	setbit(mask, WLC_E_RSSI_LQM);
+#endif /* RSSI_MONITOR_SUPPORT */
+#ifdef GSCAN_SUPPORT
+	setbit(mask, WLC_E_PFN_GSCAN_FULL_RESULT);
+	setbit(mask, WLC_E_PFN_SCAN_COMPLETE);
+	setbit(mask, WLC_E_PFN_SSID_EXT);
+	setbit(mask, WLC_E_ROAM_EXP_EVENT);
+#endif /* GSCAN_SUPPORT */
+	setbit(mask, WLC_E_RSSI_LQM);
+#ifdef DBG_PKT_MON
+	setbit(mask, WLC_E_ROAM_PREP);
+#endif /* DBG_PKT_MON */
+#ifdef BCM_ROUTER_DHD
+	setbit(mask, WLC_E_DPSTA_INTF_IND);
+#endif /* BCM_ROUTER_DHD */
+	setbit(mask, WLC_E_SLOTTED_BSS_PEER_OP);
+#ifdef WL_BCNRECV
+	setbit(mask, WLC_E_BCNRECV_ABORTED);
+#endif /* WL_BCNRECV */
+#ifdef WL_MBO
+	setbit(mask, WLC_E_MBO);
+#endif /* WL_MBO */
+#ifdef WL_CAC_TS
+	setbit(mask, WLC_E_ADDTS_IND);
+	setbit(mask, WLC_E_DELTS_IND);
+#endif /* WL_BCNRECV */
+	setbit(mask, WLC_E_COUNTRY_CODE_CHANGED);
+#ifdef CSI_SUPPORT
+	setbit(mask, WLC_E_CSI);
+#endif /* CSI_SUPPORT */
+
+	setbit(mask, WLC_E_FIFO_CREDIT_MAP);
+	/* Write updated Event mask */
+	eventmask_msg->ver = EVENTMSGS_VER;
+	eventmask_msg->command = EVENTMSGS_SET_MASK;
+	eventmask_msg->len = WL_EVENTING_MASK_EXT_LEN;
+	ret = dhd_iovar(dhd, 0, "event_msgs_ext", (char *)eventmask_msg, msglen, NULL, 0,
+			TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s write event mask ext failed %d\n", __FUNCTION__, ret));
+		goto done;
+	}
+
+#if defined(DHD_8021X_DUMP) && defined(SHOW_LOGTRACE)
+	/* Enabling event log trace for EAP events */
+	el_tag = (wl_el_tag_params_t *)MALLOC(dhd->osh, sizeof(wl_el_tag_params_t));
+	if (el_tag == NULL) {
+		DHD_ERROR(("failed to allocate %d bytes for event_msg_ext\n",
+				(int)sizeof(wl_el_tag_params_t)));
+		ret = BCME_NOMEM;
+		goto done;
+	}
+	el_tag->tag = EVENT_LOG_TAG_4WAYHANDSHAKE;
+	el_tag->set = 1;
+	el_tag->flags = EVENT_LOG_TAG_FLAG_LOG;
+	ret = dhd_iovar(dhd, 0, "event_log_tag_control", (char *)el_tag, sizeof(*el_tag), NULL,
+			0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s set event_log_tag_control fail %d\n", __FUNCTION__, ret));
+	}
+#endif /* DHD_8021X_DUMP */
+
+#ifdef DEBUGABILITY
+	/* Enabling event log trace for roam stats events */
+	el_tag = (wl_el_tag_params_t *)MALLOC(dhd->osh, sizeof(wl_el_tag_params_t));
+	if (el_tag == NULL) {
+		DHD_ERROR(("failed to allocate %d bytes for event_msg_ext\n",
+			(int)sizeof(wl_el_tag_params_t)));
+		ret = BCME_NOMEM;
+		goto done;
+	}
+	el_tag->tag = EVENT_LOG_TAG_ROAM_ENHANCED_LOG;
+	el_tag->set = 1;
+	el_tag->flags = EVENT_LOG_TAG_FLAG_LOG;
+	ret = dhd_iovar(dhd, 0, "event_log_tag_control", (char *)el_tag, sizeof(*el_tag), NULL,
+			0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s set event_log_tag_control fail %d\n", __FUNCTION__, ret));
+	}
+#endif /* DEBUGABILITY */
+
+#ifdef DHD_RANDMAC_LOGGING
+	if (FW_SUPPORTED((dhd), event_log)) {
+		if (dhd_iovar(dhd, 0, "privacy_mask", (char *)&privacy_mask, sizeof(privacy_mask),
+			NULL, 0, TRUE) < 0) {
+			DHD_ERROR(("failed to set privacy mask\n"));
+		}
+	} else {
+		/* Don't enable feature to prevent macaddr print in clr text */
+		DHD_ERROR(("skip privacy_mask set. event_log not enabled\n"));
+	}
+#endif /* DHD_RANDMAC_LOGGING */
+
+#ifdef OEM_ANDROID
+	dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_CHANNEL_TIME, (char *)&scan_assoc_time,
+			sizeof(scan_assoc_time), TRUE, 0);
+	dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_UNASSOC_TIME, (char *)&scan_unassoc_time,
+			sizeof(scan_unassoc_time), TRUE, 0);
+	dhd_wl_ioctl_cmd(dhd, WLC_SET_SCAN_PASSIVE_TIME, (char *)&scan_passive_time,
+			sizeof(scan_passive_time), TRUE, 0);
+
+#ifdef ARP_OFFLOAD_SUPPORT
+	DHD_ERROR(("arp_enable:%d arp_ol:%d\n",
+		dhd->arpoe_enable, dhd->arpol_configured));
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+#ifdef PKT_FILTER_SUPPORT
+	/* Setup default defintions for pktfilter , enable in suspend */
+	if (dhd_master_mode) {
+		dhd->pktfilter_count = 6;
+		dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = NULL;
+		if (!FW_SUPPORTED(dhd, pf6)) {
+			dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = NULL;
+			dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = NULL;
+		} else {
+			/* Immediately pkt filter TYPE 6 Discard IPv4/IPv6 Multicast Packet */
+			dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = DISCARD_IPV4_MCAST;
+			dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = DISCARD_IPV6_MCAST;
+		}
+		/* apply APP pktfilter */
+		dhd->pktfilter[DHD_ARP_FILTER_NUM] = "105 0 0 12 0xFFFF 0x0806";
+
+#ifdef BLOCK_IPV6_PACKET
+		/* Setup filter to allow only IPv4 unicast frames */
+		dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = "100 0 0 0 "
+			HEX_PREF_STR UNI_FILTER_STR ZERO_ADDR_STR ETHER_TYPE_STR IPV6_FILTER_STR
+			" "
+			HEX_PREF_STR ZERO_ADDR_STR ZERO_ADDR_STR ETHER_TYPE_STR ZERO_TYPE_STR;
+#else
+		/* Setup filter to allow only unicast */
+		dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = "100 0 0 0 0x01 0x00";
+#endif /* BLOCK_IPV6_PACKET */
+
+#ifdef PASS_IPV4_SUSPEND
+		/* XXX customer want to get IPv4 multicast packets */
+		dhd->pktfilter[DHD_MDNS_FILTER_NUM] = "104 0 0 0 0xFFFFFF 0x01005E";
+#else
+		/* Add filter to pass multicastDNS packet and NOT filter out as Broadcast */
+		dhd->pktfilter[DHD_MDNS_FILTER_NUM] = NULL;
+#endif /* PASS_IPV4_SUSPEND */
+		if (FW_SUPPORTED(dhd, pf6)) {
+			/* Immediately pkt filter TYPE 6 Dicard Broadcast IP packet */
+			dhd->pktfilter[DHD_IP4BCAST_DROP_FILTER_NUM] = DISCARD_IPV4_BCAST;
+			dhd->pktfilter_count = 8;
+		}
+
+#ifdef GAN_LITE_NAT_KEEPALIVE_FILTER
+		dhd->pktfilter_count = 4;
+		/* Setup filter to block broadcast and NAT Keepalive packets */
+		/* discard all broadcast packets */
+		dhd->pktfilter[DHD_UNICAST_FILTER_NUM] = "100 0 0 0 0xffffff 0xffffff";
+		/* discard NAT Keepalive packets */
+		dhd->pktfilter[DHD_BROADCAST_FILTER_NUM] = "102 0 0 36 0xffffffff 0x11940009";
+		/* discard NAT Keepalive packets */
+		dhd->pktfilter[DHD_MULTICAST4_FILTER_NUM] = "104 0 0 38 0xffffffff 0x11940009";
+		dhd->pktfilter[DHD_MULTICAST6_FILTER_NUM] = NULL;
+#endif /* GAN_LITE_NAT_KEEPALIVE_FILTER */
+	} else
+		dhd_conf_discard_pkt_filter(dhd);
+	dhd_conf_add_pkt_filter(dhd);
+
+#if defined(SOFTAP)
+	if (ap_fw_loaded) {
+		/* XXX Andrey: fo SOFTAP disable pkt filters (if there were any )  */
+		dhd_enable_packet_filter(0, dhd);
+	}
+#endif /* defined(SOFTAP) */
+	dhd_set_packet_filter(dhd);
+#endif /* PKT_FILTER_SUPPORT */
+#ifdef DISABLE_11N
+	ret = dhd_iovar(dhd, 0, "nmode", (char *)&nmode, sizeof(nmode), NULL, 0, TRUE);
+	if (ret < 0)
+		DHD_ERROR(("%s wl nmode 0 failed %d\n", __FUNCTION__, ret));
+#endif /* DISABLE_11N */
+
+#ifdef ENABLE_BCN_LI_BCN_WAKEUP
+	ret = dhd_iovar(dhd, 0, "bcn_li_bcn", (char *)&bcn_li_bcn, sizeof(bcn_li_bcn),
+			NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s: set bcn_li_bcn failed %d\n", __FUNCTION__, ret));
+	}
+#endif /* ENABLE_BCN_LI_BCN_WAKEUP */
+#ifdef AMPDU_VO_ENABLE
+	/* XXX: Enabling VO AMPDU to reduce FER */
+	tid.tid = PRIO_8021D_VO; /* Enable TID(6) for voice */
+	tid.enable = TRUE;
+	ret = dhd_iovar(dhd, 0, "ampdu_tid", (char *)&tid, sizeof(tid), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s ampdu_tid %d\n", __FUNCTION__, ret));
+	}
+
+	tid.tid = PRIO_8021D_NC; /* Enable TID(7) for voice */
+	tid.enable = TRUE;
+	ret = dhd_iovar(dhd, 0, "ampdu_tid", (char *)&tid, sizeof(tid), NULL, 0, TRUE);
+	if (ret < 0) {
+		DHD_ERROR(("%s ampdu_tid %d\n", __FUNCTION__, ret));
+	}
+#endif
+#if defined(SOFTAP_TPUT_ENHANCE)
+	if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE) {
+#if defined(BCMSDIO)
+		dhd_bus_setidletime(dhd, (int)100);
+#endif /* BCMSDIO */
+#ifdef DHDTCPACK_SUPPRESS
+		dhd_tcpack_suppress_set(dhd, TCPACK_SUP_OFF);
+#endif
+
+#if defined(BCMSDIO)
+		memset(buf, 0, sizeof(buf));
+		ret = dhd_iovar(dhd, 0, "bus:txglom_auto_control", NULL, 0, buf, sizeof(buf),
+				FALSE);
+		if (ret < 0) {
+			glom = 0;
+			ret = dhd_iovar(dhd, 0, "bus:txglom", (char *)&glom, sizeof(glom),
+					NULL, 0, TRUE);
+			if (ret < 0) {
+				DHD_ERROR(("%s bus:txglom failed %d\n", __FUNCTION__, ret));
+			}
+		} else {
+			if (buf[0] == 0) {
+				glom = 1;
+				ret = dhd_iovar(dhd, 0, "bus:txglom_auto_control", (char *)&glom,
+						sizeof(glom), NULL, 0, TRUE);
+				if (ret < 0) {
+					DHD_ERROR(("%s bus:txglom_auto_control failed %d\n",
+						__FUNCTION__, ret));
+				}
+			}
+		}
+#endif /* BCMSDIO */
+	}
+#endif /* SOFTAP_TPUT_ENHANCE */
+	/* query for 'clmver' to get clm version info from firmware */
+	bzero(buf, sizeof(buf));
+	ret = dhd_iovar(dhd, 0, "clmver", NULL, 0, buf, sizeof(buf), FALSE);
+	if (ret < 0)
+		DHD_ERROR(("%s clmver failed %d\n", __FUNCTION__, ret));
+	else {
+		char *ver_temp_buf = NULL, *ver_date_buf = NULL;
+		int len;
+
+		if ((ver_temp_buf = bcmstrstr(buf, "Data:")) == NULL) {
+			DHD_ERROR(("Couldn't find \"Data:\"\n"));
+		} else {
+			ver_date_buf = bcmstrstr(buf, "Creation:");
+			ptr = (ver_temp_buf + strlen("Data:"));
+			if ((ver_temp_buf = bcmstrtok(&ptr, "\n", 0)) == NULL) {
+				DHD_ERROR(("Couldn't find New line character\n"));
+			} else {
+				memset(clm_version, 0, CLM_VER_STR_LEN);
+				len = snprintf(clm_version, CLM_VER_STR_LEN - 1, "%s", ver_temp_buf);
+				if (ver_date_buf) {
+					ptr = (ver_date_buf + strlen("Creation:"));
+					ver_date_buf = bcmstrtok(&ptr, "\n", 0);
+					if (ver_date_buf)
+						snprintf(clm_version+len, CLM_VER_STR_LEN-1-len,
+							" (%s)", ver_date_buf);
+				}
+				DHD_INFO(("CLM version = %s\n", clm_version));
+			}
+		}
+
+		if (strlen(clm_version)) {
+			DHD_INFO(("CLM version = %s\n", clm_version));
+		} else {
+			DHD_ERROR(("Couldn't find CLM version!\n"));
+		}
+	}
+	dhd_set_version_info(dhd, fw_version);
+
+#ifdef WRITE_WLANINFO
+	do {
+		uint len = MAX_NVRAMBUF_SIZE;
+		char *memblock = NULL;
+
+		dhd_get_download_buffer(dhd, dhd->info->nv_path, NVRAM, &memblock, (int *)&len);
+		if ((len <= 0 || len > MAX_NVRAMBUF_SIZE)) {
+			DHD_ERROR(("Can't open nvram info, skip save wifiver info\n"));
+			break;
+		}
+
+		sec_save_wlinfo(fw_version, EPI_VERSION_STR, memblock, clm_version);
+		if (memblock) {
+			dhd_free_download_buffer(dhd, memblock, len);
+		}
+	} while (0);
+#endif /* WRITE_WLANINFO */
+
+#endif /* defined(OEM_ANDROID) */
+#ifdef GEN_SOFTAP_INFO_FILE
+	sec_save_softap_info();
+#endif /* GEN_SOFTAP_INFO_FILE */
+
+#if defined(BCMSDIO)
+	dhd_txglom_enable(dhd, dhd->conf->bus_rxglom);
+#endif /* defined(BCMSDIO) */
+
+#if defined(BCMSDIO) || defined(BCMDBUS)
+#ifdef PROP_TXSTATUS
+	if (disable_proptx ||
+#ifdef PROP_TXSTATUS_VSDB
+		/* enable WLFC only if the firmware is VSDB when it is in STA mode */
+		(dhd->op_mode != DHD_FLAG_HOSTAP_MODE &&
+		 dhd->op_mode != DHD_FLAG_IBSS_MODE) ||
+#endif /* PROP_TXSTATUS_VSDB */
+		FALSE) {
+		wlfc_enable = FALSE;
+	}
+	ret = dhd_conf_get_disable_proptx(dhd);
+	if (ret == 0){
+		disable_proptx = 0;
+		wlfc_enable = TRUE;
+	} else if (ret >= 1) {
+		disable_proptx = 1;
+		wlfc_enable = FALSE;
+		/* terence 20161229: we should set ampdu_hostreorder=0 when disable_proptx=1 */
+		hostreorder = 0;
+	}
+
+#if defined(PROP_TXSTATUS)
+#ifdef USE_WFA_CERT_CONF
+	if (sec_get_param_wfa_cert(dhd, SET_PARAM_PROPTX, &proptx) == BCME_OK) {
+		DHD_ERROR(("%s , read proptx param=%d\n", __FUNCTION__, proptx));
+		wlfc_enable = proptx;
+	}
+#endif /* USE_WFA_CERT_CONF */
+#endif /* PROP_TXSTATUS */
+
+#ifndef DISABLE_11N
+	ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, (char *)&wl_down, sizeof(wl_down), TRUE, 0);
+	ret2 = dhd_iovar(dhd, 0, "ampdu_hostreorder", (char *)&hostreorder, sizeof(hostreorder),
+			NULL, 0, TRUE);
+	if (ret2 < 0) {
+		DHD_ERROR(("%s wl ampdu_hostreorder failed %d\n", __FUNCTION__, ret2));
+		if (ret2 != BCME_UNSUPPORTED)
+			ret = ret2;
+
+		if (ret == BCME_NOTDOWN) {
+			uint wl_down = 1;
+			ret2 = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, (char *)&wl_down,
+				sizeof(wl_down), TRUE, 0);
+			DHD_ERROR(("%s ampdu_hostreorder fail WL_DOWN : %d, hostreorder :%d\n",
+				__FUNCTION__, ret2, hostreorder));
+
+			ret2 = dhd_iovar(dhd, 0, "ampdu_hostreorder", (char *)&hostreorder,
+					sizeof(hostreorder), NULL, 0, TRUE);
+			DHD_ERROR(("%s wl ampdu_hostreorder. ret --> %d\n", __FUNCTION__, ret2));
+			if (ret2 != BCME_UNSUPPORTED)
+					ret = ret2;
+		}
+		if (ret2 != BCME_OK)
+			hostreorder = 0;
+	}
+#endif /* DISABLE_11N */
+
+#ifdef READ_CONFIG_FROM_FILE
+	dhd_preinit_config(dhd, 0, CONFIG_BCMDHD_CONFIG_PATH);
+#endif /* READ_CONFIG_FROM_FILE */
+
+	if (wlfc_enable) {
+		dhd_wlfc_init(dhd);
+		/* terence 20161229: enable ampdu_hostreorder if tlv enabled */
+		dhd_conf_set_intiovar(dhd, 0, WLC_SET_VAR, "ampdu_hostreorder", 1, 0, TRUE);
+	}
+#ifndef DISABLE_11N
+	else if (hostreorder)
+		dhd_wlfc_hostreorder_init(dhd);
+#endif /* DISABLE_11N */
+#else
+	/* terence 20161229: disable ampdu_hostreorder if PROP_TXSTATUS not defined */
+	printf("%s: not define PROP_TXSTATUS\n", __FUNCTION__);
+	dhd_conf_set_intiovar(dhd, 0, WLC_SET_VAR, "ampdu_hostreorder", 0, 0, TRUE);
+#endif /* PROP_TXSTATUS */
+#endif /* BCMSDIO || BCMDBUS */
+
+#if defined(SYNA_SAR_CUSTOMER_PARAMETER) && defined(READ_CONFIG_FROM_FILE)
+	dhd_sar_reset_parameter();
+	dhd_preinit_config(dhd, 0, config_sar_path);
+#endif /* SYNA_SAR_CUSTOMER_PARAMETER && READ_CONFIG_FROM_FILE */
+
+#ifndef PCIE_FULL_DONGLE
+	/* For FD we need all the packets at DHD to handle intra-BSS forwarding */
+	if (FW_SUPPORTED(dhd, ap)) {
+		wl_ap_isolate = AP_ISOLATE_SENDUP_ALL;
+		ret = dhd_iovar(dhd, 0, "ap_isolate", (char *)&wl_ap_isolate, sizeof(wl_ap_isolate),
+				NULL, 0, TRUE);
+		if (ret < 0)
+			DHD_ERROR(("%s failed %d\n", __FUNCTION__, ret));
+	}
+#endif /* PCIE_FULL_DONGLE */
+#ifdef PNO_SUPPORT
+	if (!dhd->pno_state) {
+		dhd_pno_init(dhd);
+	}
+#endif
+
+#ifdef RTT_SUPPORT
+	if (dhd->rtt_state) {
+		ret = dhd_rtt_init(dhd);
+		if (ret < 0) {
+			DHD_ERROR(("%s failed to initialize RTT\n", __FUNCTION__));
+		}
+	}
+#endif
+#ifdef FILTER_IE
+	/* Failure to configure filter IE is not a fatal error, ignore it. */
+	if (FW_SUPPORTED(dhd, fie) &&
+		!(dhd->op_mode & (DHD_FLAG_HOSTAP_MODE | DHD_FLAG_MFG_MODE))) {
+		dhd_read_from_file(dhd);
+	}
+#endif /* FILTER_IE */
+#ifdef WL11U
+	dhd_interworking_enable(dhd);
+#endif /* WL11U */
+
+#ifdef NDO_CONFIG_SUPPORT
+	dhd->ndo_enable = FALSE;
+	dhd->ndo_host_ip_overflow = FALSE;
+	dhd->ndo_max_host_ip = NDO_MAX_HOST_IP_ENTRIES;
+#endif /* NDO_CONFIG_SUPPORT */
+
+	/* ND offload version supported */
+	dhd->ndo_version = dhd_ndo_get_version(dhd);
+	if (dhd->ndo_version > 0) {
+		DHD_INFO(("%s: ndo version %d\n", __FUNCTION__, dhd->ndo_version));
+
+#ifdef NDO_CONFIG_SUPPORT
+		/* enable Unsolicited NA filter */
+		ret = dhd_ndo_unsolicited_na_filter_enable(dhd, 1);
+		if (ret < 0) {
+			DHD_ERROR(("%s failed to enable Unsolicited NA filter\n", __FUNCTION__));
+		}
+#endif /* NDO_CONFIG_SUPPORT */
+	}
+
+	/* check dongle supports wbtext (product policy) or not */
+	dhd->wbtext_support = FALSE;
+	if (dhd_wl_ioctl_get_intiovar(dhd, "wnm_bsstrans_resp", &wnm_bsstrans_resp,
+			WLC_GET_VAR, FALSE, 0) != BCME_OK) {
+		DHD_ERROR(("failed to get wnm_bsstrans_resp\n"));
+	}
+	dhd->wbtext_policy = wnm_bsstrans_resp;
+	if (dhd->wbtext_policy == WL_BSSTRANS_POLICY_PRODUCT_WBTEXT) {
+		dhd->wbtext_support = TRUE;
+	}
+#ifndef WBTEXT
+	/* driver can turn off wbtext feature through makefile */
+	if (dhd->wbtext_support) {
+		if (dhd_wl_ioctl_set_intiovar(dhd, "wnm_bsstrans_resp",
+				WL_BSSTRANS_POLICY_ROAM_ALWAYS,
+				WLC_SET_VAR, FALSE, 0) != BCME_OK) {
+			DHD_ERROR(("failed to disable WBTEXT\n"));
+		}
+	}
+#endif /* !WBTEXT */
+
+#ifdef DHD_NON_DMA_M2M_CORRUPTION
+	/* check pcie non dma loopback */
+	if (dhd->op_mode == DHD_FLAG_MFG_MODE &&
+		(dhd_bus_dmaxfer_lpbk(dhd, M2M_NON_DMA_LPBK) < 0)) {
+			goto done;
+	}
+#endif /* DHD_NON_DMA_M2M_CORRUPTION */
+
+	/* WNM capabilities */
+	wnm_cap = 0
+#ifdef WL11U
+		| WL_WNM_BSSTRANS | WL_WNM_NOTIF
+#endif
+#ifdef WBTEXT
+		| WL_WNM_BSSTRANS | WL_WNM_MAXIDLE
+#endif
+		;
+#if defined(WL_MBO) && defined(WL_OCE)
+	if (FW_SUPPORTED(dhd, estm)) {
+		wnm_cap |= WL_WNM_ESTM;
+	}
+#endif /* WL_MBO && WL_OCE */
+	if ((ret2 = dhd_iovar(dhd, 0, "wnm", (char *)&wnm_cap, sizeof(wnm_cap),
+		NULL, 0, TRUE)) < 0) {
+		DHD_ERROR(("failed to set WNM capabilities %x, err %d\n", wnm_cap, ret2));
+	}
+
+#ifdef CUSTOM_ASSOC_TIMEOUT
+	/* set recreate_bi_timeout to increase assoc timeout :
+	* 20 * 100TU * 1024 / 1000 = 2 secs
+	* (beacon wait time = recreate_bi_timeout * beacon_period * 1024 / 1000)
+	*/
+	if (dhd_wl_ioctl_set_intiovar(dhd, "recreate_bi_timeout",
+			CUSTOM_ASSOC_TIMEOUT,
+			WLC_SET_VAR, TRUE, 0) != BCME_OK) {
+		DHD_ERROR(("failed to set assoc timeout\n"));
+	}
+#endif /* CUSTOM_ASSOC_TIMEOUT */
+
+#if defined(WBTEXT) && defined(WBTEXT_BTMDELTA)
+	if (dhd_iovar(dhd, 0, "wnm_btmdelta", (char *)&btmdelta, sizeof(btmdelta),
+			NULL, 0, TRUE) < 0) {
+		DHD_ERROR(("failed to set BTM delta\n"));
+	}
+#endif /* WBTEXT && WBTEXT_BTMDELTA */
+#if defined(WBTEXT) && defined(RRM_BCNREQ_MAX_CHAN_TIME)
+	if (dhd_iovar(dhd, 0, "rrm_bcn_req_thrtl_win",
+		(char *)&rrm_bcn_req_thrtl_win, sizeof(rrm_bcn_req_thrtl_win),
+		NULL, 0, TRUE) < 0) {
+		DHD_ERROR(("failed to set RRM BCN request thrtl_win\n"));
+	}
+	if (dhd_iovar(dhd, 0, "rrm_bcn_req_max_off_chan_time",
+		(char *)&rrm_bcn_req_max_off_chan_time, sizeof(rrm_bcn_req_max_off_chan_time),
+		NULL, 0, TRUE) < 0) {
+		DHD_ERROR(("failed to set RRM BCN Request max_off_chan_time\n"));
+	}
+#endif /* WBTEXT && RRM_BCNREQ_MAX_CHAN_TIME */
+
+#ifdef WL_MONITOR
+#ifdef HOST_RADIOTAP_CONV
+	/* 'Wl monitor' IOVAR is fired to check whether the FW supports radiotap conversion or not.
+	 * This is indicated through MSB(1<<31) bit, based on which host radiotap conversion
+	 * will be enabled or disabled.
+	 * 0 - Host supports Radiotap conversion.
+	 * 1 - FW supports Radiotap conversion.
+	 */
+	bcm_mkiovar("monitor", (char *)&monitor, sizeof(monitor), iovbuf, sizeof(iovbuf));
+	if ((ret2 = dhd_wl_ioctl_cmd(dhd, WLC_GET_MONITOR, iovbuf,
+		sizeof(iovbuf), FALSE, 0)) == 0) {
+		memcpy(&monitor, iovbuf, sizeof(monitor));
+		dhdinfo->host_radiotap_conv = (monitor & HOST_RADIOTAP_CONV_BIT) ? TRUE : FALSE;
+	} else {
+		DHD_ERROR(("%s Failed to get monitor mode, err %d\n",
+			__FUNCTION__, ret2));
+	}
+#endif /* HOST_RADIOTAP_CONV */
+	if (FW_SUPPORTED(dhd, monitor)) {
+		dhd->monitor_enable = TRUE;
+		DHD_ERROR(("%s: Monitor mode is enabled in FW cap\n", __FUNCTION__));
+	} else {
+		dhd->monitor_enable = FALSE;
+		DHD_ERROR(("%s: Monitor mode is not enabled in FW cap\n", __FUNCTION__));
+	}
+#endif /* WL_MONITOR */
+
+	/* store the preserve log set numbers */
+	if (dhd_get_preserve_log_numbers(dhd, &dhd->logset_prsrv_mask)
+			!= BCME_OK) {
+		DHD_ERROR(("%s: Failed to get preserve log # !\n", __FUNCTION__));
+	}
+
+	if (FW_SUPPORTED(dhd, ecounters) && enable_ecounter) {
+		dhd_ecounter_configure(dhd, TRUE);
+	}
+
+#ifndef OEM_ANDROID
+	/* For non-android FC modular builds, override firmware preinited values */
+	dhd_override_fwprenit(dhd);
+#endif /* !OEM_ANDROID */
+
+	dhd_set_bandlock(dhd);
+
+#ifdef WL_UWB_COEX
+#ifdef WL_UWB_COEX_DEF_ENABLE
+	ret = wl_cfg_uwb_coex_enable(dhd_linux_get_primary_netdev(dhd),
+		TRUE, UWB_COEX_CH_MIN, UWB_COEX_CH_MAX);
+	if (ret != BCME_OK) {
+		DHD_ERROR(("Failed to set UWB Coex (%d)\n", ret));
+	}
+#endif /* WL_UWB_COEX_DEF_ENABLE */
+#endif /* WL_UWB_COEX */
+
+	if (dhd_iovar(dhd, 0, "bus:d3_hostwake_delay", (char *)&d3_hostwake_delay,
+		sizeof(d3_hostwake_delay), NULL, 0, TRUE) < 0) {
+		DHD_ERROR(("%s: d3_hostwake_delay IOVAR not present, proceed\n", __FUNCTION__));
+	} else {
+		DHD_ERROR(("%s: d3_hostwake_delay enabled\n", __FUNCTION__));
+	}
+
+#if defined(BCMSDIO)
+	/* check if srmemsize consitant at fw and dhd side */
+	dhd_bus_check_srmemsize(dhd);
+#endif /* BCMSDIO */
+
+done:
+
+	if (eventmask_msg) {
+		MFREE(dhd->osh, eventmask_msg, msglen);
+	}
+	if (iov_buf) {
+		MFREE(dhd->osh, iov_buf, WLC_IOCTL_SMLEN);
+	}
+#if (defined(DHD_8021X_DUMP) && defined(SHOW_LOGTRACE)) || defined(DEBUGABILITY)
+	if (el_tag) {
+		MFREE(dhd->osh, el_tag, sizeof(wl_el_tag_params_t));
+	}
+#endif /* DHD_8021X_DUMP */
+	return ret;
+}
+
+#if defined(BCMPCIE)
+/* Deafult enable preinit optimisation */
+#define DHD_PREINIT_OPTIMISATION
+#endif /* BCMPCIE */
+
+int
+dhd_preinit_ioctls(dhd_pub_t *dhd)
+{
+	int ret = 0;
+
+#ifdef DHD_PREINIT_OPTIMISATION
+	int preinit_status = 0;
+	ret = dhd_iovar(dhd, 0, "preinit_status", NULL, 0, (char *)&preinit_status,
+		sizeof(preinit_status), FALSE);
+
+	if (ret == BCME_OK) {
+		DHD_ERROR(("%s: preinit_status IOVAR present, use optimised preinit\n",
+			__FUNCTION__));
+		dhd->fw_preinit = TRUE;
+		ret = dhd_optimised_preinit_ioctls(dhd);
+	} else if (ret == BCME_UNSUPPORTED) {
+		DHD_ERROR(("%s: preinit_status IOVAR not supported, use legacy preinit\n",
+			__FUNCTION__));
+		dhd->fw_preinit = FALSE;
+		ret = dhd_legacy_preinit_ioctls(dhd);
+	} else {
+		DHD_ERROR(("%s: preinit_status IOVAR returned err(%d), ABORT\n",
+			__FUNCTION__, ret));
+	}
+#else
+	dhd->fw_preinit = FALSE;
+	ret = dhd_legacy_preinit_ioctls(dhd);
+#endif /* DHD_PREINIT_OPTIMISATION */
+
+	if (!ret && dhd_query_bus_erros(dhd)) {
+		DHD_ERROR(("%s: retrun error due to query errors\n", __FUNCTION__));
+		ret = BCME_ERROR;
+	}
+	if (!ret)
+		dhd_conf_postinit_ioctls(dhd);
+
+	return ret;
+}
+
+int
+dhd_getiovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf,
+	uint cmd_len, char **resptr, uint resp_len)
+{
+	int len = resp_len;
+	int ret;
+	char *buf = *resptr;
+	wl_ioctl_t ioc;
+	if (resp_len > WLC_IOCTL_MAXLEN)
+		return BCME_BADARG;
+
+	memset(buf, 0, resp_len);
+
+	ret = bcm_mkiovar(name, cmd_buf, cmd_len, buf, len);
+	if (ret == 0) {
+		return BCME_BUFTOOSHORT;
+	}
+
+	memset(&ioc, 0, sizeof(ioc));
+
+	ioc.cmd = WLC_GET_VAR;
+	ioc.buf = buf;
+	ioc.len = len;
+	ioc.set = 0;
+
+	ret = dhd_wl_ioctl(pub, ifidx, &ioc, ioc.buf, ioc.len);
+
+	return ret;
+}
+
+int dhd_change_mtu(dhd_pub_t *dhdp, int new_mtu, int ifidx)
+{
+	struct dhd_info *dhd = dhdp->info;
+	struct net_device *dev = NULL;
+
+	ASSERT(dhd && dhd->iflist[ifidx]);
+	dev = dhd->iflist[ifidx]->net;
+	ASSERT(dev);
+
+#ifndef DHD_TPUT_PATCH
+	if (netif_running(dev)) {
+		DHD_ERROR(("%s: Must be down to change its MTU\n", dev->name));
+		return BCME_NOTDOWN;
+	}
+#endif
+
+#define DHD_MIN_MTU 1500
+#define DHD_MAX_MTU 1752
+
+	if ((new_mtu < DHD_MIN_MTU) || (new_mtu > DHD_MAX_MTU)) {
+		DHD_ERROR(("%s: MTU size %d is invalid.\n", __FUNCTION__, new_mtu));
+		return BCME_BADARG;
+	}
+
+	dev->mtu = new_mtu;
+	return 0;
+}
+
+#if defined(DHD_FILE_DUMP_EVENT) && defined(DHD_FW_COREDUMP)
+static int dhd_wait_for_file_dump(dhd_pub_t *dhdp)
+{
+	int ret = BCME_OK;
+	struct net_device *primary_ndev;
+#ifdef WL_CFG80211
+	struct bcm_cfg80211 *cfg;
+#endif /* WL_CFG80211 */
+	unsigned long flags = 0;
+	primary_ndev = dhd_linux_get_primary_netdev(dhdp);
+
+	if (!primary_ndev) {
+		DHD_ERROR(("%s: Cannot find primary netdev\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+#ifdef WL_CFG80211
+	cfg = wl_get_cfg(primary_ndev);
+
+	if (!cfg) {
+		DHD_ERROR(("%s: Cannot find cfg\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+#endif /* WL_CFG80211 */
+
+	if (dhdp->stop_in_progress) {
+		DHD_ERROR(("%s: dhd_stop in progress\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	DHD_GENERAL_LOCK(dhdp, flags);
+	if (DHD_BUS_CHECK_DOWN_OR_DOWN_IN_PROGRESS(dhdp)) {
+		DHD_BUS_BUSY_CLEAR_IN_HALDUMP(dhdp);
+		dhd_os_busbusy_wake(dhdp);
+		DHD_GENERAL_UNLOCK(dhdp, flags);
+		DHD_ERROR(("%s: bus is down! can't collect log dump. \n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+	DHD_BUS_BUSY_SET_IN_HALDUMP(dhdp);
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+
+#ifdef WL_CFG80211
+	DHD_OS_WAKE_LOCK(dhdp);
+	/* check for hal started and only then send event if not clear dump state here */
+	if (wl_cfg80211_is_hal_started(cfg)) {
+		int timeleft = 0;
+
+		DHD_ERROR(("[DUMP] %s: HAL started. send urgent event\n", __FUNCTION__));
+#ifdef DHD_MAP_PKTID_LOGGING
+		dhd_pktid_logging_dump(dhdp);
+#endif /* DHD_MAP_PKTID_LOGGING */
+		dhd_dbg_send_urgent_evt(dhdp, NULL, 0);
+
+		DHD_ERROR(("%s: wait to clear dhd_bus_busy_state: 0x%x\n",
+			__FUNCTION__, dhdp->dhd_bus_busy_state));
+		timeleft = dhd_os_busbusy_wait_bitmask(dhdp,
+				&dhdp->dhd_bus_busy_state, DHD_BUS_BUSY_IN_HALDUMP, 0);
+		if ((dhdp->dhd_bus_busy_state & DHD_BUS_BUSY_IN_HALDUMP) != 0) {
+			DHD_ERROR(("%s: Timed out(%d) dhd_bus_busy_state=0x%x\n",
+					__FUNCTION__, timeleft, dhdp->dhd_bus_busy_state));
+			dhd_set_dump_status(dhdp, DUMP_FAILURE);
+			ret = BCME_ERROR;
+		}
+	} else {
+		DHD_ERROR(("[DUMP] %s: HAL Not started. skip urgent event\n", __FUNCTION__));
+		ret = BCME_ERROR;
+	}
+	DHD_OS_WAKE_UNLOCK(dhdp);
+#endif /* WL_CFG80211 */
+
+	/* In case of dhd_os_busbusy_wait_bitmask() timeout,
+	 * hal dump bit will not be cleared. Hence clearing it here.
+	 */
+	DHD_GENERAL_LOCK(dhdp, flags);
+	DHD_BUS_BUSY_CLEAR_IN_HALDUMP(dhdp);
+	dhd_os_busbusy_wake(dhdp);
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+
+	return ret;
+}
+#endif /* DHD_FILE_DUMP_EVENT && DHD_FW_CORE_DUMP */
+
+#ifdef ARP_OFFLOAD_SUPPORT
+/* add or remove AOE host ip(s) (up to 8 IPs on the interface)  */
+/* XXX add operation is more efficent */
+void
+aoe_update_host_ipv4_table(dhd_pub_t *dhd_pub, u32 ipa, bool add, int idx)
+{
+	u32 ipv4_buf[MAX_IPV4_ENTRIES]; /* temp save for AOE host_ip table */
+	int i;
+	int ret;
+
+	bzero(ipv4_buf, sizeof(ipv4_buf));
+
+	/* display what we've got */
+	ret = dhd_arp_get_arp_hostip_table(dhd_pub, ipv4_buf, sizeof(ipv4_buf), idx);
+	DHD_ARPOE(("%s: hostip table read from Dongle:\n", __FUNCTION__));
+#ifdef AOE_DBG
+	dhd_print_buf(ipv4_buf, 32, 4); /* max 8 IPs 4b each */
+#endif
+	/* now we saved hoste_ip table, clr it in the dongle AOE */
+	dhd_aoe_hostip_clr(dhd_pub, idx);
+
+	if (ret) {
+		DHD_ERROR(("%s failed\n", __FUNCTION__));
+		return;
+	}
+
+	for (i = 0; i < MAX_IPV4_ENTRIES; i++) {
+		if (add && (ipv4_buf[i] == 0)) {
+				ipv4_buf[i] = ipa;
+				add = FALSE; /* added ipa to local table  */
+				DHD_ARPOE(("%s: Saved new IP in temp arp_hostip[%d]\n",
+				__FUNCTION__, i));
+		} else if (ipv4_buf[i] == ipa) {
+			ipv4_buf[i]	= 0;
+			DHD_ARPOE(("%s: removed IP:%x from temp table %d\n",
+				__FUNCTION__, ipa, i));
+		}
+
+		if (ipv4_buf[i] != 0) {
+			/* add back host_ip entries from our local cache */
+			dhd_arp_offload_add_ip(dhd_pub, ipv4_buf[i], idx);
+			DHD_ARPOE(("%s: added IP:%x to dongle arp_hostip[%d]\n\n",
+				__FUNCTION__, ipv4_buf[i], i));
+		}
+	}
+#ifdef AOE_DBG
+	/* see the resulting hostip table */
+	dhd_arp_get_arp_hostip_table(dhd_pub, ipv4_buf, sizeof(ipv4_buf), idx);
+	DHD_ARPOE(("%s: read back arp_hostip table:\n", __FUNCTION__));
+	dhd_print_buf(ipv4_buf, 32, 4); /* max 8 IPs 4b each */
+#endif
+}
+
+/* XXX this function is only for IP address */
+/*
+ * Notification mechanism from kernel to our driver. This function is called by the Linux kernel
+ * whenever there is an event related to an IP address.
+ * ptr : kernel provided pointer to IP address that has changed
+ */
+static int dhd_inetaddr_notifier_call(struct notifier_block *this,
+	unsigned long event,
+	void *ptr)
+{
+	struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
+
+	dhd_info_t *dhd;
+	dhd_pub_t *dhd_pub;
+	int idx;
+
+	if (!ifa || !(ifa->ifa_dev->dev))
+		return NOTIFY_DONE;
+
+	/* Filter notifications meant for non Broadcom devices */
+	if ((ifa->ifa_dev->dev->netdev_ops != &dhd_ops_pri) &&
+	    (ifa->ifa_dev->dev->netdev_ops != &dhd_ops_virt)) {
+#if defined(WL_ENABLE_P2P_IF)
+		if (!wl_cfgp2p_is_ifops(ifa->ifa_dev->dev->netdev_ops))
+#endif /* WL_ENABLE_P2P_IF */
+			return NOTIFY_DONE;
+	}
+
+	dhd = DHD_DEV_INFO(ifa->ifa_dev->dev);
+	if (!dhd)
+		return NOTIFY_DONE;
+
+	dhd_pub = &dhd->pub;
+
+	if (!dhd_pub->arpoe_enable) {
+		DHD_ERROR(("arpoe_enable not set"));
+		return NOTIFY_DONE;
+	}
+
+	if (dhd_pub->arp_version == 1) {
+		idx = 0;
+	} else {
+		for (idx = 0; idx < DHD_MAX_IFS; idx++) {
+			if (dhd->iflist[idx] && dhd->iflist[idx]->net == ifa->ifa_dev->dev)
+			break;
+		}
+		if (idx < DHD_MAX_IFS)
+			DHD_TRACE(("ifidx : %p %s %d\n", dhd->iflist[idx]->net,
+				dhd->iflist[idx]->name, dhd->iflist[idx]->idx));
+		else {
+			DHD_ERROR(("Cannot find ifidx for(%s) set to 0\n", ifa->ifa_label));
+			idx = 0;
+		}
+	}
+
+	switch (event) {
+		case NETDEV_UP:
+			DHD_ARPOE(("%s: [%s] Up IP: 0x%x\n",
+				__FUNCTION__, ifa->ifa_label, ifa->ifa_address));
+
+			/*
+			 * Skip if Bus is not in a state to transport the IOVAR
+			 * (or) the Dongle is not ready.
+			 */
+			if (DHD_BUS_CHECK_DOWN_OR_DOWN_IN_PROGRESS(&dhd->pub) ||
+				dhd->pub.busstate ==  DHD_BUS_LOAD) {
+				DHD_ERROR(("%s: bus not ready, exit NETDEV_UP : %d\n",
+					__FUNCTION__, dhd->pub.busstate));
+				if (dhd->pend_ipaddr) {
+					DHD_ERROR(("%s: overwrite pending ipaddr: 0x%x\n",
+						__FUNCTION__, dhd->pend_ipaddr));
+				}
+				dhd->pend_ipaddr = ifa->ifa_address;
+				break;
+			}
+
+#ifdef AOE_IP_ALIAS_SUPPORT
+			/* XXX HOSTAPD will be rerturned at first */
+			DHD_ARPOE(("%s:add aliased IP to AOE hostip cache\n",
+				__FUNCTION__));
+			aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, TRUE, idx);
+#endif /* AOE_IP_ALIAS_SUPPORT */
+			dhd_conf_set_garp(dhd_pub, idx, ifa->ifa_address, TRUE);
+			break;
+
+		case NETDEV_DOWN:
+			DHD_ARPOE(("%s: [%s] Down IP: 0x%x\n",
+				__FUNCTION__, ifa->ifa_label, ifa->ifa_address));
+			dhd->pend_ipaddr = 0;
+#ifdef AOE_IP_ALIAS_SUPPORT
+			/* XXX HOSTAPD will be rerturned at first */
+			DHD_ARPOE(("%s:interface is down, AOE clr all for this if\n",
+				__FUNCTION__));
+			if ((dhd_pub->op_mode & DHD_FLAG_HOSTAP_MODE) ||
+				(ifa->ifa_dev->dev != dhd_linux_get_primary_netdev(dhd_pub))) {
+				aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, FALSE, idx);
+			} else
+#endif /* AOE_IP_ALIAS_SUPPORT */
+			{
+				/* XXX clear ALL arp and hostip tables */
+				dhd_aoe_hostip_clr(&dhd->pub, idx);
+				dhd_aoe_arp_clr(&dhd->pub, idx);
+			}
+			dhd_conf_set_garp(dhd_pub, idx, ifa->ifa_address, FALSE);
+			break;
+
+		default:
+			DHD_ARPOE(("%s: do noting for [%s] Event: %lu\n",
+				__func__, ifa->ifa_label, event));
+			break;
+	}
+	return NOTIFY_DONE;
+}
+#endif /* ARP_OFFLOAD_SUPPORT */
+
+#if defined(CONFIG_IPV6) && defined(IPV6_NDO_SUPPORT)
+/* Neighbor Discovery Offload: defered handler */
+static void
+dhd_inet6_work_handler(void *dhd_info, void *event_data, u8 event)
+{
+	struct ipv6_work_info_t *ndo_work = (struct ipv6_work_info_t *)event_data;
+	dhd_info_t *dhd = (dhd_info_t *)dhd_info;
+	dhd_pub_t *dhdp;
+	int ret;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: invalid dhd_info\n", __FUNCTION__));
+		goto done;
+	}
+	dhdp = &dhd->pub;
+
+	if (event != DHD_WQ_WORK_IPV6_NDO) {
+		DHD_ERROR(("%s: unexpected event\n", __FUNCTION__));
+		goto done;
+	}
+
+	if (!ndo_work) {
+		DHD_ERROR(("%s: ipv6 work info is not initialized\n", __FUNCTION__));
+		return;
+	}
+
+	switch (ndo_work->event) {
+		case NETDEV_UP:
+#ifndef NDO_CONFIG_SUPPORT
+			DHD_TRACE(("%s: Enable NDO \n ", __FUNCTION__));
+			ret = dhd_ndo_enable(dhdp, TRUE);
+			if (ret < 0) {
+				DHD_ERROR(("%s: Enabling NDO Failed %d\n", __FUNCTION__, ret));
+			}
+#endif /* !NDO_CONFIG_SUPPORT */
+			DHD_TRACE(("%s: Add a host ip for NDO\n", __FUNCTION__));
+			if (dhdp->ndo_version > 0) {
+				/* inet6 addr notifier called only for unicast address */
+				ret = dhd_ndo_add_ip_with_type(dhdp, &ndo_work->ipv6_addr[0],
+					WL_ND_IPV6_ADDR_TYPE_UNICAST, ndo_work->if_idx);
+			} else {
+				ret = dhd_ndo_add_ip(dhdp, &ndo_work->ipv6_addr[0],
+					ndo_work->if_idx);
+			}
+			if (ret < 0) {
+				DHD_ERROR(("%s: Adding a host ip for NDO failed %d\n",
+					__FUNCTION__, ret));
+			}
+			break;
+		case NETDEV_DOWN:
+			if (dhdp->ndo_version > 0) {
+				DHD_TRACE(("%s: Remove a host ip for NDO\n", __FUNCTION__));
+				ret = dhd_ndo_remove_ip_by_addr(dhdp,
+					&ndo_work->ipv6_addr[0], ndo_work->if_idx);
+			} else {
+				DHD_TRACE(("%s: Clear host ip table for NDO \n", __FUNCTION__));
+				ret = dhd_ndo_remove_ip(dhdp, ndo_work->if_idx);
+			}
+			if (ret < 0) {
+				DHD_ERROR(("%s: Removing host ip for NDO failed %d\n",
+					__FUNCTION__, ret));
+				goto done;
+			}
+#ifdef NDO_CONFIG_SUPPORT
+			if (dhdp->ndo_host_ip_overflow) {
+				ret = dhd_dev_ndo_update_inet6addr(
+					dhd_idx2net(dhdp, ndo_work->if_idx));
+				if ((ret < 0) && (ret != BCME_NORESOURCE)) {
+					DHD_ERROR(("%s: Updating host ip for NDO failed %d\n",
+						__FUNCTION__, ret));
+					goto done;
+				}
+			}
+#else /* !NDO_CONFIG_SUPPORT */
+			DHD_TRACE(("%s: Disable NDO\n ", __FUNCTION__));
+			ret = dhd_ndo_enable(dhdp, FALSE);
+			if (ret < 0) {
+				DHD_ERROR(("%s: disabling NDO Failed %d\n", __FUNCTION__, ret));
+				goto done;
+			}
+#endif /* NDO_CONFIG_SUPPORT */
+			break;
+
+		default:
+			DHD_ERROR(("%s: unknown notifier event \n", __FUNCTION__));
+			break;
+	}
+done:
+
+	/* free ndo_work. alloced while scheduling the work */
+	if (ndo_work) {
+		kfree(ndo_work);
+	}
+
+	return;
+} /* dhd_init_logstrs_array */
+
+/*
+ * Neighbor Discovery Offload: Called when an interface
+ * is assigned with ipv6 address.
+ * Handles only primary interface
+ */
+int dhd_inet6addr_notifier_call(struct notifier_block *this, unsigned long event, void *ptr)
+{
+	dhd_info_t *dhd;
+	dhd_pub_t *dhdp;
+	struct inet6_ifaddr *inet6_ifa = ptr;
+	struct ipv6_work_info_t *ndo_info;
+	int idx = 0;
+
+	/* Filter notifications meant for non Broadcom devices */
+	if (inet6_ifa->idev->dev->netdev_ops != &dhd_ops_pri) {
+			return NOTIFY_DONE;
+	}
+
+	dhd = DHD_DEV_INFO(inet6_ifa->idev->dev);
+	if (!dhd) {
+		return NOTIFY_DONE;
+	}
+	dhdp = &dhd->pub;
+
+	idx = dhd_net2idx(dhd, inet6_ifa->idev->dev);
+	if ((idx >= 0 && idx < DHD_MAX_IFS)
+#if defined(WL_CFG80211)
+		&& IS_STA_IFACE(ndev_to_wdev(inet6_ifa->idev->dev))
+#endif /* WL_CFG80211 */
+		&& 1) {
+		DHD_TRACE(("ifidx : %p %s %d\n", dhd->iflist[idx]->net,
+			dhd->iflist[idx]->name, dhd->iflist[idx]->idx));
+	} else {
+		return NOTIFY_DONE;
+	}
+
+	/* FW capability */
+	if (!FW_SUPPORTED(dhdp, ndoe)) {
+		return NOTIFY_DONE;
+	}
+
+	ndo_info = (struct ipv6_work_info_t *)kzalloc(sizeof(struct ipv6_work_info_t), GFP_ATOMIC);
+	if (!ndo_info) {
+		DHD_ERROR(("%s: ipv6 work alloc failed\n", __FUNCTION__));
+		return NOTIFY_DONE;
+	}
+
+	/* fill up ndo_info */
+	ndo_info->event = event;
+	ndo_info->if_idx = idx;
+	memcpy(ndo_info->ipv6_addr, &inet6_ifa->addr, IPV6_ADDR_LEN);
+
+	/* defer the work to thread as it may block kernel */
+	dhd_deferred_schedule_work(dhd->dhd_deferred_wq, (void *)ndo_info, DHD_WQ_WORK_IPV6_NDO,
+		dhd_inet6_work_handler, DHD_WQ_WORK_PRIORITY_LOW);
+	return NOTIFY_DONE;
+}
+#endif /* CONFIG_IPV6 && IPV6_NDO_SUPPORT */
+
+/* Network attach to be invoked from the bus probe handlers */
+int
+dhd_attach_net(dhd_pub_t *dhdp, bool need_rtnl_lock)
+{
+	struct net_device *primary_ndev;
+#ifdef GET_CUSTOM_MAC_ENABLE
+	char hw_ether[62];
+#endif /* GET_CUSTOM_MAC_ENABLE */
+#if defined(GET_CUSTOM_MAC_ENABLE) || defined(GET_OTP_MAC_ENABLE)
+	int ret = BCME_ERROR;
+#endif /* GET_CUSTOM_MAC_ENABLE || GET_OTP_MAC_ENABLE */
+
+	BCM_REFERENCE(primary_ndev);
+
+#ifdef GET_CUSTOM_MAC_ENABLE
+	ret = wifi_platform_get_mac_addr(dhdp->adapter, hw_ether, 0);
+	if (!ret)
+		bcopy(hw_ether, dhdp->mac.octet, ETHER_ADDR_LEN);
+#endif /* GET_CUSTOM_MAC_ENABLE */
+
+#ifdef GET_OTP_MAC_ENABLE
+	if (ret && memcmp(&ether_null, &dhdp->conf->otp_mac, ETHER_ADDR_LEN))
+		bcopy(&dhdp->conf->otp_mac, &dhdp->mac, ETHER_ADDR_LEN);
+#endif /* GET_OTP_MAC_ENABLE */
+
+	/* Register primary net device */
+	if (dhd_register_if(dhdp, 0, need_rtnl_lock) != 0) {
+		return BCME_ERROR;
+	}
+
+#if defined(WL_CFG80211)
+	primary_ndev =  dhd_linux_get_primary_netdev(dhdp);
+	if (wl_cfg80211_net_attach(primary_ndev) < 0) {
+		/* fail the init */
+		dhd_remove_if(dhdp, 0, TRUE);
+		return BCME_ERROR;
+	}
+#endif /* WL_CFG80211 */
+	return BCME_OK;
+}
+
+int
+dhd_register_if(dhd_pub_t *dhdp, int ifidx, bool need_rtnl_lock)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+	dhd_if_t *ifp;
+	struct net_device *net = NULL;
+	int err = 0;
+	uint8 temp_addr[ETHER_ADDR_LEN] = { 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33 };
+	unsigned long flags;
+
+	DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx));
+
+	if (dhd == NULL || dhd->iflist[ifidx] == NULL) {
+		DHD_ERROR(("%s: Invalid Interface\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	ASSERT(dhd && dhd->iflist[ifidx]);
+	ifp = dhd->iflist[ifidx];
+	net = ifp->net;
+	ASSERT(net && (ifp->idx == ifidx));
+
+	ASSERT(!net->netdev_ops);
+	net->netdev_ops = &dhd_ops_virt;
+
+	/* Ok, link into the network layer... */
+	if (ifidx == 0) {
+		/*
+		 * device functions for the primary interface only
+		 */
+		net->netdev_ops = &dhd_ops_pri;
+		if (!ETHER_ISNULLADDR(dhd->pub.mac.octet))
+			memcpy(temp_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN);
+	} else {
+		/*
+		 * We have to use the primary MAC for virtual interfaces
+		 */
+		memcpy(temp_addr, ifp->mac_addr, ETHER_ADDR_LEN);
+#if defined(OEM_ANDROID)
+		/*
+		 * Android sets the locally administered bit to indicate that this is a
+		 * portable hotspot.  This will not work in simultaneous AP/STA mode,
+		 * nor with P2P.  Need to set the Donlge's MAC address, and then use that.
+		 */
+		if (!memcmp(temp_addr, dhd->iflist[0]->mac_addr,
+			ETHER_ADDR_LEN)) {
+			DHD_ERROR(("%s interface [%s]: set locally administered bit in MAC\n",
+			__func__, net->name));
+			temp_addr[0] |= 0x02;
+		}
+#endif /* defined(OEM_ANDROID) */
+	}
+
+	net->hard_header_len = ETH_HLEN + dhd->pub.hdrlen;
+
+	net->ethtool_ops = &dhd_ethtool_ops;
+
+#if defined(WL_WIRELESS_EXT)
+#if WIRELESS_EXT < 19
+	net->get_wireless_stats = dhd_get_wireless_stats;
+#endif /* WIRELESS_EXT < 19 */
+#if WIRELESS_EXT > 12
+	net->wireless_handlers = &wl_iw_handler_def;
+#endif /* WIRELESS_EXT > 12 */
+#endif /* defined(WL_WIRELESS_EXT) */
+
+	/* XXX Set up an MTU change notifier as per linux/notifier.h? */
+	dhd->pub.rxsz = DBUS_RX_BUFFER_SIZE_DHD(net);
+
+#ifdef WLMESH
+	if (ifidx >= 2 && dhdp->conf->fw_type == FW_TYPE_MESH) {
+		temp_addr[4] ^= 0x80;
+		temp_addr[4] += ifidx;
+		temp_addr[5] += ifidx;
+	}
+#endif
+	/*
+	 * XXX Linux 2.6.25 does not like a blank MAC address, so use a
+	 * dummy address until the interface is brought up.
+	 */
+	DEV_ADDR_SET(net, temp_addr);
+
+	if (ifidx == 0)
+		printf("%s\n", dhd_version);
+	else {
+#ifdef WL_EXT_IAPSTA
+		wl_ext_iapsta_update_net_device(net, ifidx);
+#endif /* WL_EXT_IAPSTA */
+		if (dhd->pub.up == 1) {
+			memcpy(temp_addr, net->dev_addr, ETHER_ADDR_LEN);
+			if (_dhd_set_mac_address(dhd, ifidx, temp_addr, FALSE) == 0)
+				DHD_INFO(("%s: MACID is overwritten\n", __FUNCTION__));
+			else
+				DHD_ERROR(("%s: _dhd_set_mac_address() failed\n", __FUNCTION__));
+		}
+	}
+
+	err = dhd_register_net(net, need_rtnl_lock);
+	if (err != 0) {
+		DHD_ERROR(("couldn't register the net device [%s], err %d\n", net->name, err));
+		goto fail;
+	}
+
+#if (defined(BCM_ROUTER_DHD) && defined(HNDCTF))
+	if ((ctf_dev_register(dhd->cih, net, FALSE) != BCME_OK) ||
+	    (ctf_enable(dhd->cih, net, TRUE, &dhd->brc_hot) != BCME_OK)) {
+		DHD_ERROR(("%s:%d: ctf_dev_register/ctf_enable failed for interface %d\n",
+			__FUNCTION__, __LINE__, ifidx));
+		goto fail;
+	}
+#endif /* BCM_ROUTER_DHD && HNDCTF */
+
+#if defined(WLDWDS) && defined(WL_EXT_IAPSTA)
+	if (ifp->dwds) {
+		wl_ext_iapsta_attach_dwds_netdev(net, ifidx, ifp->bssidx);
+	} else
+#endif /* WLDWDS && WL_EXT_IAPSTA */
+	{
+#ifdef WL_EVENT
+		wl_ext_event_attach_netdev(net, ifidx, ifp->bssidx);
+#endif /* WL_EVENT */
+#ifdef WL_ESCAN
+		wl_escan_event_attach(net, ifidx);
+#endif /* WL_ESCAN */
+#ifdef WL_EXT_IAPSTA
+		wl_ext_iapsta_attach_netdev(net, ifidx, ifp->bssidx);
+		wl_ext_iapsta_attach_name(net, ifidx);
+#endif /* WL_EXT_IAPSTA */
+	}
+
+#if defined(CONFIG_TIZEN)
+	net_stat_tizen_register(net);
+#endif /* CONFIG_TIZEN */
+
+	DHD_CONS_ONLY(("Register interface [%s]  MAC: "MACDBG"\n\n", net->name,
+		MAC2STRDBG(net->dev_addr)));
+
+#if defined(OEM_ANDROID) && (defined(BCMPCIE) || defined(BCMLXSDMMC) || defined(BCMDBUS))
+	if (ifidx == 0) {
+#if defined(BCMLXSDMMC) && !defined(DHD_PRELOAD)
+		up(&dhd_registration_sem);
+#endif /* BCMLXSDMMC */
+		if (!dhd_download_fw_on_driverload) {
+#ifdef WL_CFG80211
+			wl_terminate_event_handler(net);
+#endif /* WL_CFG80211 */
+#if defined(DHD_LB_RXP)
+			__skb_queue_purge(&dhd->rx_pend_queue);
+			skb_queue_purge(&dhd->rx_emerge_queue);
+#endif /* DHD_LB_RXP */
+
+#if defined(DHD_LB_TXP)
+			skb_queue_purge(&dhd->tx_pend_queue);
+#endif /* DHD_LB_TXP */
+
+#ifdef SHOW_LOGTRACE
+			/* Release the skbs from queue for WLC_E_TRACE event */
+			dhd_event_logtrace_flush_queue(dhdp);
+#endif /* SHOW_LOGTRACE */
+
+#if defined(BCMPCIE) && defined(DHDTCPACK_SUPPRESS)
+			dhd_tcpack_suppress_set(dhdp, TCPACK_SUP_OFF);
+#endif /* BCMPCIE && DHDTCPACK_SUPPRESS */
+
+#if defined(WLAN_ACCEL_BOOT)
+			/*
+			 * Make Wifi suspended after boot up with forge_reg_on true
+			 * This will download fw when ifconfig wlan0 up sequence
+			 */
+			wl_android_wifi_off(net, TRUE);
+			dhd->wl_accel_force_reg_on = TRUE;
+			/* Module init time clear do_chip_bighammer */
+			dhd->pub.do_chip_bighammer = FALSE;
+#else
+			/* Turn off Wifi after boot up */
+#if defined(BT_OVER_SDIO)
+			dhd_bus_put(&dhd->pub, WLAN_MODULE);
+			wl_android_set_wifi_on_flag(FALSE);
+#else
+			wl_android_wifi_off(net, TRUE);
+#endif /* BT_OVER_SDIO */
+#endif /* WLAN_ACCEL_BOOT */
+
+		}
+	}
+#endif /* OEM_ANDROID && (BCMPCIE || (BCMLXSDMMC) */
+
+	DHD_GENERAL_LOCK(dhdp, flags);
+	ifp->del_in_progress = FALSE;
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+
+	return 0;
+
+fail:
+	net->netdev_ops = NULL;
+	return err;
+}
+
+void
+dhd_bus_detach(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd;
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+	if (dhdp) {
+		dhd = (dhd_info_t *)dhdp->info;
+		if (dhd) {
+
+			/*
+			 * In case of Android cfg80211 driver, the bus is down in dhd_stop,
+			 *  calling stop again will cuase SD read/write errors.
+			 */
+			if (dhd->pub.busstate != DHD_BUS_DOWN && dhd_download_fw_on_driverload) {
+				/* Stop the protocol module */
+				dhd_prot_stop(&dhd->pub);
+
+				/* Stop the bus module */
+#ifdef BCMDBUS
+				/* Force Dongle terminated */
+				if (dhd_wl_ioctl_cmd(dhdp, WLC_TERMINATED, NULL, 0, TRUE, 0) < 0)
+					DHD_ERROR(("%s Setting WLC_TERMINATED failed\n",
+						__FUNCTION__));
+				dbus_stop(dhd->pub.bus);
+				DHD_ERROR(("%s: making DHD_BUS_DOWN\n", __FUNCTION__));
+				dhd->pub.busstate = DHD_BUS_DOWN;
+#else
+				dhd_bus_stop(dhd->pub.bus, TRUE);
+#endif /* BCMDBUS */
+			}
+
+#if defined(OOB_INTR_ONLY) || defined(BCMSPI_ANDROID) || defined(BCMPCIE_OOB_HOST_WAKE)
+			dhd_bus_oob_intr_unregister(dhdp);
+#endif /* OOB_INTR_ONLY || BCMSPI_ANDROID || BCMPCIE_OOB_HOST_WAKE */
+		}
+	}
+}
+
+void dhd_detach(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd;
+	unsigned long flags;
+	int timer_valid = FALSE;
+	struct net_device *dev = NULL;
+	dhd_if_t *ifp;
+#ifdef WL_CFG80211
+	struct bcm_cfg80211 *cfg = NULL;
+#endif /* WL_CFG80211 */
+#ifdef WL_STATIC_IF
+	dhd_if_t *ifp_static;
+	struct net_device *dev_static = NULL;
+#endif /* WL_STATIC_IF */
+
+	if (!dhdp)
+		return;
+
+	dhd = (dhd_info_t *)dhdp->info;
+	if (!dhd)
+		return;
+
+	/* primary interface 0 */
+	ifp = dhd->iflist[0];
+	if (ifp && ifp->net) {
+		dev = ifp->net;
+	}
+
+	if (dev) {
+		rtnl_lock();
+#if defined(WL_CFG80211) && defined(WL_STATIC_IF)
+		if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) {
+			wl_cfg80211_static_if_dev_close(dev);
+		}
+#endif /* WL_CFG80211 && WL_STATIC_IF */
+		if (dev->flags & IFF_UP) {
+			/* If IFF_UP is still up, it indicates that
+			 * "ifconfig wlan0 down" hasn't been called.
+			 * So invoke dev_close explicitly here to
+			 * bring down the interface.
+			 */
+			DHD_TRACE(("IFF_UP flag is up. Enforcing dev_close from detach \n"));
+			dev_close(dev);
+		}
+		rtnl_unlock();
+	}
+
+#ifdef WL_STATIC_IF
+	/* static interface */
+	ifp_static = dhd->iflist[WL_STATIC_IFIDX];
+
+	if (ifp_static && ifp_static->net) {
+		dev_static = ifp_static->net;
+	}
+
+	if (dev_static) {
+		rtnl_lock();
+		if (dev_static->flags & IFF_UP) {
+			DHD_TRACE(("IFF_UP flag is up. Enforcing dev_close from detach \n"));
+			dev_close(dev_static);
+		}
+		rtnl_unlock();
+	}
+#endif /* WL_STATIC_IF */
+
+	DHD_TRACE(("%s: Enter state 0x%x\n", __FUNCTION__, dhd->dhd_state));
+
+	/* XXX	kernel panic issue when first bootup time,
+	 *	 rmmod without interface down make unnecessary hang event.
+	 */
+	DHD_ERROR(("%s: making dhdpub up FALSE\n", __FUNCTION__));
+	dhd->pub.up = 0;
+	if (!(dhd->dhd_state & DHD_ATTACH_STATE_DONE)) {
+		/* Give sufficient time for threads to start running in case
+		 * dhd_attach() has failed
+		 */
+		OSL_SLEEP(100);
+	}
+#ifdef DHD_WET
+	dhd_free_wet_info(&dhd->pub, dhd->pub.wet_info);
+#endif /* DHD_WET */
+
+#ifdef PROP_TXSTATUS
+#ifdef DHD_WLFC_THREAD
+	if (dhd->pub.wlfc_thread) {
+		kthread_stop(dhd->pub.wlfc_thread);
+		dhdp->wlfc_thread_go = TRUE;
+		wake_up_interruptible(&dhdp->wlfc_wqhead);
+	}
+	dhd->pub.wlfc_thread = NULL;
+#endif /* DHD_WLFC_THREAD */
+#endif /* PROP_TXSTATUS */
+
+	if (dhd->dhd_state & DHD_ATTACH_STATE_PROT_ATTACH) {
+
+#if defined(OEM_ANDROID) || !defined(BCMSDIO)
+		dhd_bus_detach(dhdp);
+#endif /* OEM_ANDROID || !BCMSDIO */
+#ifndef PCIE_FULL_DONGLE
+#if defined(OEM_ANDROID) || !defined(BCMSDIO)
+		if (dhdp->prot)
+			dhd_prot_detach(dhdp);
+#endif /* OEM_ANDROID || !BCMSDIO */
+#endif /* !PCIE_FULL_DONGLE */
+	}
+
+#ifdef ARP_OFFLOAD_SUPPORT
+	if (dhd_inetaddr_notifier_registered) {
+		dhd_inetaddr_notifier_registered = FALSE;
+		unregister_inetaddr_notifier(&dhd_inetaddr_notifier);
+	}
+#endif /* ARP_OFFLOAD_SUPPORT */
+#if defined(CONFIG_IPV6) && defined(IPV6_NDO_SUPPORT)
+	if (dhd_inet6addr_notifier_registered) {
+		dhd_inet6addr_notifier_registered = FALSE;
+		unregister_inet6addr_notifier(&dhd_inet6addr_notifier);
+	}
+#endif /* CONFIG_IPV6 && IPV6_NDO_SUPPORT */
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
+	if (dhd->dhd_state & DHD_ATTACH_STATE_EARLYSUSPEND_DONE) {
+		if (dhd->early_suspend.suspend)
+			unregister_early_suspend(&dhd->early_suspend);
+	}
+#endif /* CONFIG_HAS_EARLYSUSPEND && DHD_USE_EARLYSUSPEND */
+
+#if defined(WL_WIRELESS_EXT)
+	if (dhd->dhd_state & DHD_ATTACH_STATE_WL_ATTACH) {
+		/* Detatch and unlink in the iw */
+		wl_iw_detach(dev);
+	}
+#endif /* defined(WL_WIRELESS_EXT) */
+#ifdef WL_EXT_GENL
+	wl_ext_genl_deinit(dev);
+#endif
+#ifdef WL_EXT_IAPSTA
+	wl_ext_iapsta_dettach(dev);
+#endif /* WL_EXT_IAPSTA */
+#ifdef WL_ESCAN
+	wl_escan_detach(dev);
+#endif /* WL_ESCAN */
+#ifdef WL_TIMER
+	wl_timer_dettach(dhdp);
+#endif /* WL_TIMER */
+#ifdef WL_EVENT
+	wl_ext_event_dettach(dhdp);
+#endif /* WL_EVENT */
+
+	/* delete all interfaces, start with virtual  */
+	if (dhd->dhd_state & DHD_ATTACH_STATE_ADD_IF) {
+		int i = 1;
+
+		/* Cleanup virtual interfaces */
+		dhd_net_if_lock_local(dhd);
+		for (i = 1; i < DHD_MAX_IFS; i++) {
+			if (dhd->iflist[i]) {
+				dhd_remove_if(&dhd->pub, i, TRUE);
+			}
+		}
+		dhd_net_if_unlock_local(dhd);
+
+		/* 'ifp' indicates primary interface 0, clean it up. */
+		if (ifp && ifp->net) {
+#if (defined(BCM_ROUTER_DHD) && defined(HNDCTF))
+			if (dhd->cih)
+				ctf_dev_unregister(dhd->cih, ifp->net);
+#endif /* BCM_ROUTER_DHD && HNDCTF */
+
+#ifdef WL_CFG80211
+			cfg = wl_get_cfg(ifp->net);
+#endif
+			/* in unregister_netdev case, the interface gets freed by net->destructor
+			 * (which is set to free_netdev)
+			 */
+			if (ifp->net->reg_state == NETREG_UNINITIALIZED) {
+				free_netdev(ifp->net);
+			} else {
+#ifdef SET_RPS_CPUS
+				custom_rps_map_clear(ifp->net->_rx);
+#endif /* SET_RPS_CPUS */
+				netif_tx_disable(ifp->net);
+				dhd_unregister_net(ifp->net, true);
+			}
+#ifdef PCIE_FULL_DONGLE
+			ifp->net = DHD_NET_DEV_NULL;
+#else
+			ifp->net = NULL;
+#endif /* PCIE_FULL_DONGLE */
+#if defined(BCMSDIO) && !defined(OEM_ANDROID)
+			dhd_bus_detach(dhdp);
+
+			if (dhdp->prot)
+				dhd_prot_detach(dhdp);
+#endif /* BCMSDIO && !OEM_ANDROID */
+
+#ifdef DHD_WMF
+			dhd_wmf_cleanup(dhdp, 0);
+#endif /* DHD_WMF */
+#ifdef DHD_L2_FILTER
+			bcm_l2_filter_arp_table_update(dhdp->osh, ifp->phnd_arp_table, TRUE,
+				NULL, FALSE, dhdp->tickcnt);
+			deinit_l2_filter_arp_table(dhdp->osh, ifp->phnd_arp_table);
+			ifp->phnd_arp_table = NULL;
+#endif /* DHD_L2_FILTER */
+
+#if (defined(BCM_ROUTER_DHD) && defined(QOS_MAP_SET))
+			MFREE(dhdp->osh, ifp->qosmap_up_table, UP_TABLE_MAX);
+			ifp->qosmap_up_table_enable = FALSE;
+#endif /* BCM_ROUTER_DHD && QOS_MAP_SET */
+
+			dhd_if_del_sta_list(ifp);
+
+			MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
+			ifp = NULL;
+#ifdef WL_CFG80211
+			if (cfg && cfg->wdev)
+				cfg->wdev->netdev = NULL;
+#endif /* WL_CFG80211 */
+#ifdef WL_STATIC_IF
+			if (ifp_static) {
+				dhd_if_del_sta_list(ifp_static);
+				MFREE(dhd->pub.osh, ifp_static, sizeof(*ifp_static));
+				ifp_static = NULL;
+			}
+#endif /* WL_STATIC_IF */
+		}
+	}
+
+	/* Clear the watchdog timer */
+	DHD_GENERAL_LOCK(&dhd->pub, flags);
+	timer_valid = dhd->wd_timer_valid;
+	dhd->wd_timer_valid = FALSE;
+	DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+	if (timer_valid)
+		del_timer_sync(&dhd->timer);
+	DHD_STOP_RPM_TIMER(&dhd->pub);
+
+#ifdef BCMDBUS
+	tasklet_kill(&dhd->tasklet);
+#else
+	if (dhd->dhd_state & DHD_ATTACH_STATE_THREADS_CREATED) {
+		if (dhd->thr_wdt_ctl.thr_pid >= 0) {
+			PROC_STOP(&dhd->thr_wdt_ctl);
+		}
+
+		if (dhd->rxthread_enabled && dhd->thr_rxf_ctl.thr_pid >= 0) {
+			PROC_STOP(&dhd->thr_rxf_ctl);
+		}
+
+		if (dhd->thr_dpc_ctl.thr_pid >= 0) {
+			PROC_STOP(&dhd->thr_dpc_ctl);
+		} else
+		{
+			tasklet_kill(&dhd->tasklet);
+		}
+	}
+#endif /* BCMDBUS */
+
+	cancel_delayed_work_sync(&dhd->dhd_dpc_dispatcher_work);
+#ifdef DHD_LB
+	if (dhd->dhd_state & DHD_ATTACH_STATE_LB_ATTACH_DONE) {
+		/* Clear the flag first to avoid calling the cpu notifier */
+		dhd->dhd_state &= ~DHD_ATTACH_STATE_LB_ATTACH_DONE;
+
+		/* Kill the Load Balancing Tasklets */
+#ifdef DHD_LB_RXP
+		cancel_work_sync(&dhd->rx_napi_dispatcher_work);
+		__skb_queue_purge(&dhd->rx_pend_queue);
+		skb_queue_purge(&dhd->rx_emerge_queue);
+#endif /* DHD_LB_RXP */
+#ifdef DHD_LB_TXP
+		cancel_work_sync(&dhd->tx_dispatcher_work);
+		tasklet_kill(&dhd->tx_tasklet);
+		__skb_queue_purge(&dhd->tx_pend_queue);
+#endif /* DHD_LB_TXP */
+
+		/* Unregister from CPU Hotplug framework */
+		dhd_unregister_cpuhp_callback(dhd);
+
+		dhd_cpumasks_deinit(dhd);
+		DHD_LB_STATS_DEINIT(&dhd->pub);
+	}
+#endif /* DHD_LB */
+
+#if defined(DNGL_AXI_ERROR_LOGGING) && defined(DHD_USE_WQ_FOR_DNGL_AXI_ERROR)
+	cancel_work_sync(&dhd->axi_error_dispatcher_work);
+#endif /* DNGL_AXI_ERROR_LOGGING && DHD_USE_WQ_FOR_DNGL_AXI_ERROR */
+
+	DHD_SSSR_REG_INFO_DEINIT(&dhd->pub);
+	DHD_SSSR_MEMPOOL_DEINIT(&dhd->pub);
+	DHD_COREDUMP_MEMPOOL_DEINIT(&dhd->pub);
+
+#ifdef DHD_SDTC_ETB_DUMP
+	dhd_sdtc_etb_mempool_deinit(&dhd->pub);
+#endif /* DHD_SDTC_ETB_DUMP */
+
+#ifdef RX_PKT_POOL
+	dhd_rx_pktpool_deinit(dhd);
+#endif
+
+#ifdef WL_CFG80211
+	if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211) {
+		if (!cfg) {
+			DHD_ERROR(("cfg NULL!\n"));
+			ASSERT(0);
+		} else {
+			wl_cfg80211_detach(cfg);
+			dhd_monitor_uninit();
+		}
+	}
+#endif
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+	destroy_workqueue(dhd->tx_wq);
+	dhd->tx_wq = NULL;
+	destroy_workqueue(dhd->rx_wq);
+	dhd->rx_wq = NULL;
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+#ifdef DEBUGABILITY
+	if (dhdp->dbg) {
+#ifdef DBG_PKT_MON
+		dhd_os_dbg_detach_pkt_monitor(dhdp);
+		osl_spin_lock_deinit(dhd->pub.osh, dhd->pub.dbg->pkt_mon_lock);
+#endif /* DBG_PKT_MON */
+	}
+#endif /* DEBUGABILITY */
+	if (dhdp->dbg) {
+		dhd_os_dbg_detach(dhdp);
+	}
+#ifdef DHD_MEM_STATS
+	osl_spin_lock_deinit(dhd->pub.osh, dhd->pub.mem_stats_lock);
+#endif /* DHD_MEM_STATS */
+
+#ifdef DHD_PKT_LOGGING
+	dhd_os_detach_pktlog(dhdp);
+#endif /* DHD_PKT_LOGGING */
+#ifdef DHD_STATUS_LOGGING
+	dhd_detach_statlog(dhdp);
+#endif /* DHD_STATUS_LOGGING */
+#ifdef DHD_PKTDUMP_ROAM
+	dhd_dump_pkt_deinit(dhdp);
+#endif /* DHD_PKTDUMP_ROAM */
+#ifdef WL_CFGVENDOR_SEND_HANG_EVENT
+	if (dhd->pub.hang_info) {
+		MFREE(dhd->pub.osh, dhd->pub.hang_info, VENDOR_SEND_HANG_EXT_INFO_LEN);
+	}
+#endif /* WL_CFGVENDOR_SEND_HANG_EVENT */
+#ifdef SHOW_LOGTRACE
+	/* Release the skbs from queue for WLC_E_TRACE event */
+	dhd_event_logtrace_flush_queue(dhdp);
+
+	/* Wait till event logtrace context finishes */
+	dhd_cancel_logtrace_process_sync(dhd);
+
+	/* Remove ring proc entries */
+	dhd_dbg_ring_proc_destroy(&dhd->pub);
+
+	if (dhd->dhd_state & DHD_ATTACH_LOGTRACE_INIT) {
+		if (dhd->event_data.fmts) {
+			MFREE(dhd->pub.osh, dhd->event_data.fmts,
+					dhd->event_data.fmts_size);
+		}
+		if (dhd->event_data.raw_fmts) {
+			MFREE(dhd->pub.osh, dhd->event_data.raw_fmts,
+					dhd->event_data.raw_fmts_size);
+		}
+		if (dhd->event_data.raw_sstr) {
+			MFREE(dhd->pub.osh, dhd->event_data.raw_sstr,
+					dhd->event_data.raw_sstr_size);
+		}
+		if (dhd->event_data.rom_raw_sstr) {
+			MFREE(dhd->pub.osh, dhd->event_data.rom_raw_sstr,
+					dhd->event_data.rom_raw_sstr_size);
+		}
+		dhd->dhd_state &= ~DHD_ATTACH_LOGTRACE_INIT;
+	}
+#endif /* SHOW_LOGTRACE */
+#ifdef PNO_SUPPORT
+	if (dhdp->pno_state)
+		dhd_pno_deinit(dhdp);
+#endif
+#ifdef RTT_SUPPORT
+	if (dhdp->rtt_state) {
+		dhd_rtt_detach(dhdp);
+	}
+#endif
+#if defined(CONFIG_PM_SLEEP) && !defined(DEVICE_PM_CALLBACK)
+	if (dhd_pm_notifier_registered) {
+		unregister_pm_notifier(&dhd->pm_notifier);
+		dhd_pm_notifier_registered = FALSE;
+	}
+#endif /* CONFIG_PM_SLEEP */
+
+#ifdef DEBUG_CPU_FREQ
+		if (dhd->new_freq)
+			free_percpu(dhd->new_freq);
+		dhd->new_freq = NULL;
+		cpufreq_unregister_notifier(&dhd->freq_trans, CPUFREQ_TRANSITION_NOTIFIER);
+#endif
+#ifdef CONFIG_HAS_WAKELOCK
+	dhd->wakelock_wd_counter = 0;
+	dhd_wake_lock_destroy(dhd->wl_wdwake);
+#endif /* CONFIG_HAS_WAKELOCK */
+	if (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT) {
+		DHD_TRACE(("wd wakelock count:%d\n", dhd->wakelock_wd_counter));
+		DHD_OS_WAKE_LOCK_DESTROY(dhd);
+	}
+
+#ifdef DHDTCPACK_SUPPRESS
+	/* This will free all MEM allocated for TCPACK SUPPRESS */
+	dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_OFF);
+#endif /* DHDTCPACK_SUPPRESS */
+
+#ifdef PCIE_FULL_DONGLE
+	dhd_flow_rings_deinit(dhdp);
+	if (dhdp->prot)
+		dhd_prot_detach(dhdp);
+#endif
+
+#ifdef EWP_EDL
+	if (host_edl_support) {
+		DHD_EDL_MEM_DEINIT(dhdp);
+		host_edl_support = FALSE;
+	}
+#endif /* EWP_EDL */
+
+#if defined(WLTDLS) && defined(PCIE_FULL_DONGLE)
+		dhd_free_tdls_peer_list(dhdp);
+#endif
+
+#if (defined(BCM_ROUTER_DHD) && defined(HNDCTF))
+	/* Release CTF pool ONLY after the prot layer is dettached and
+	 * pkts, possibly from fast ctfpool are freed into ctfpool/kernel
+	 */
+#ifdef CTFPOOL
+	/* free the buffers in fast pool */
+	osl_ctfpool_cleanup(dhd->pub.osh);
+#endif /* CTFPOOL */
+
+	/* free ctf resources */
+	if (dhd->cih)
+		ctf_detach(dhd->cih);
+#endif /* BCM_ROUTER_DHD && HNDCTF */
+#if defined(BCMDBG) && defined(DHD_MACDBG)
+	dhd_macdbg_detach(dhdp);
+#endif /* BCMDBG && DHD_MACDBG */
+
+#ifdef DUMP_IOCTL_IOV_LIST
+	dhd_iov_li_delete(dhdp, &(dhdp->dump_iovlist_head));
+#endif /* DUMP_IOCTL_IOV_LIST */
+#ifdef DHD_DEBUG
+	/* memory waste feature list initilization */
+	dhd_mw_list_delete(dhdp, &(dhdp->mw_list_head));
+#endif /* DHD_DEBUG */
+#ifdef WL_MONITOR
+	dhd_del_monitor_if(dhd);
+#endif /* WL_MONITOR */
+
+	if (work_pending(&dhd->dhd_hang_process_work))
+		cancel_work_sync(&dhd->dhd_hang_process_work);
+
+	/* Prefer adding de-init code above this comment unless necessary.
+	 * The idea is to cancel work queue, sysfs and flags at the end.
+	 */
+	dhd_deferred_work_deinit(dhd->dhd_deferred_wq);
+	dhd->dhd_deferred_wq = NULL;
+
+	/* log dump related buffers should be freed after wq is purged */
+#ifdef DHD_LOG_DUMP
+	dhd_log_dump_deinit(&dhd->pub);
+#endif /* DHD_LOG_DUMP */
+#if defined(BCMPCIE)
+	if (dhdp->extended_trap_data)
+	{
+		MFREE(dhdp->osh, dhdp->extended_trap_data, BCMPCIE_EXT_TRAP_DATA_MAXLEN);
+		dhdp->extended_trap_data = NULL;
+	}
+#ifdef DNGL_AXI_ERROR_LOGGING
+	if (dhdp->axi_err_dump)
+	{
+		MFREE(dhdp->osh, dhdp->axi_err_dump, sizeof(dhd_axi_error_dump_t));
+		dhdp->axi_err_dump = NULL;
+	}
+#endif /* DNGL_AXI_ERROR_LOGGING */
+#endif /* BCMPCIE */
+
+#ifdef EWP_EDL
+	cancel_delayed_work_sync(&dhd->edl_dispatcher_work);
+#endif
+
+	(void)dhd_deinit_sock_flows_buf(dhd);
+
+#ifdef CSI_SUPPORT
+	dhd_csi_deinit(dhdp);
+#endif /* CSI_SUPPORT */
+
+#ifdef DHD_DUMP_MNGR
+	if (dhd->pub.dump_file_manage) {
+		MFREE(dhd->pub.osh, dhd->pub.dump_file_manage,
+				sizeof(dhd_dump_file_manage_t));
+	}
+#endif /* DHD_DUMP_MNGR */
+
+	dhd_sysfs_exit(dhd);
+	dhd->pub.fw_download_status = FW_UNLOADED;
+
+#if defined(BT_OVER_SDIO)
+	mutex_destroy(&dhd->bus_user_lock);
+#endif /* BT_OVER_SDIO */
+
+#ifdef DHD_TX_PROFILE
+	(void)dhd_tx_profile_detach(dhdp);
+#endif /* defined(DHD_TX_PROFILE) */
+#ifdef WL_CFGVENDOR_SEND_ALERT_EVENT
+	cancel_work_sync(&dhd->dhd_alert_process_work);
+#endif /* WL_CFGVENDOR_SEND_ALERT_EVENT */
+#if defined(DHD_FILE_DUMP_EVENT) && defined(DHD_FW_COREDUMP)
+	cancel_work_sync(&dhd->dhd_dump_proc_work);
+#endif /* DHD_FILE_DUMP_EVENT && DHD_FW_COREDUMP */
+	dhd_conf_detach(dhdp);
+} /* dhd_detach */
+
+void
+dhd_free(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd;
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+	if (dhdp) {
+		int i;
+		for (i = 0; i < ARRAYSIZE(dhdp->reorder_bufs); i++) {
+			if (dhdp->reorder_bufs[i]) {
+				reorder_info_t *ptr;
+				uint32 buf_size = sizeof(struct reorder_info);
+
+				ptr = dhdp->reorder_bufs[i];
+
+				buf_size += ((ptr->max_idx + 1) * sizeof(void*));
+				DHD_REORDER(("free flow id buf %d, maxidx is %d, buf_size %d\n",
+					i, ptr->max_idx, buf_size));
+
+				MFREE(dhdp->osh, dhdp->reorder_bufs[i], buf_size);
+			}
+		}
+
+		dhd_sta_pool_fini(dhdp, DHD_MAX_STA);
+
+		dhd = (dhd_info_t *)dhdp->info;
+		if (dhdp->soc_ram) {
+#if defined(CONFIG_DHD_USE_STATIC_BUF) && defined(DHD_USE_STATIC_MEMDUMP)
+			DHD_OS_PREFREE(dhdp, dhdp->soc_ram, dhdp->soc_ram_length);
+#else
+			if (is_vmalloc_addr(dhdp->soc_ram)) {
+				VMFREE(dhdp->osh, dhdp->soc_ram, dhdp->soc_ram_length);
+			}
+			else {
+				MFREE(dhdp->osh, dhdp->soc_ram, dhdp->soc_ram_length);
+			}
+#endif /* CONFIG_DHD_USE_STATIC_BUF && DHD_USE_STATIC_MEMDUMP */
+			dhdp->soc_ram = NULL;
+		}
+#ifdef CACHE_FW_IMAGES
+		if (dhdp->cached_fw) {
+			MFREE(dhdp->osh, dhdp->cached_fw, dhdp->bus->ramsize);
+		}
+
+		if (dhdp->cached_nvram) {
+			MFREE(dhdp->osh, dhdp->cached_nvram, MAX_NVRAMBUF_SIZE);
+		}
+#endif
+#ifdef SUPPORT_OTA_UPDATE
+		(void)dhd_ota_buf_clean(dhdp);
+#endif /* SUPPORT_OTA_UPDATE */
+		if (dhd != NULL) {
+#ifdef REPORT_FATAL_TIMEOUTS
+			deinit_dhd_timeouts(&dhd->pub);
+#endif /* REPORT_FATAL_TIMEOUTS */
+
+			/* Free Platform Layer allocations */
+			if (dhd->pub.plat_info) {
+				MFREE(dhdp->osh, dhdp->plat_info, dhdp->plat_info_size);
+			}
+
+			/* If pointer is allocated by dhd_os_prealloc then avoid MFREE */
+			if (dhd != (dhd_info_t *)dhd_os_prealloc(dhdp,
+					DHD_PREALLOC_DHD_INFO, 0, FALSE))
+				MFREE(dhd->pub.osh, dhd, sizeof(*dhd));
+			dhd = NULL;
+		}
+	}
+}
+
+void
+dhd_clear(dhd_pub_t *dhdp)
+{
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+	if (dhdp) {
+		int i;
+#ifdef DHDTCPACK_SUPPRESS
+		/* Clean up timer/data structure for any remaining/pending packet or timer. */
+		dhd_tcpack_info_tbl_clean(dhdp);
+#endif /* DHDTCPACK_SUPPRESS */
+		for (i = 0; i < ARRAYSIZE(dhdp->reorder_bufs); i++) {
+			if (dhdp->reorder_bufs[i]) {
+				reorder_info_t *ptr;
+				uint32 buf_size = sizeof(struct reorder_info);
+
+				ptr = dhdp->reorder_bufs[i];
+
+				buf_size += ((ptr->max_idx + 1) * sizeof(void*));
+				DHD_REORDER(("free flow id buf %d, maxidx is %d, buf_size %d\n",
+					i, ptr->max_idx, buf_size));
+
+				MFREE(dhdp->osh, dhdp->reorder_bufs[i], buf_size);
+			}
+		}
+
+		dhd_sta_pool_clear(dhdp, DHD_MAX_STA);
+
+		if (dhdp->soc_ram) {
+#if defined(CONFIG_DHD_USE_STATIC_BUF) && defined(DHD_USE_STATIC_MEMDUMP)
+			DHD_OS_PREFREE(dhdp, dhdp->soc_ram, dhdp->soc_ram_length);
+#else
+			if (is_vmalloc_addr(dhdp->soc_ram)) {
+				VMFREE(dhdp->osh, dhdp->soc_ram, dhdp->soc_ram_length);
+			}
+			else {
+				MFREE(dhdp->osh, dhdp->soc_ram, dhdp->soc_ram_length);
+			}
+#endif /* CONFIG_DHD_USE_STATIC_BUF && DHD_USE_STATIC_MEMDUMP */
+			dhdp->soc_ram = NULL;
+		}
+	}
+}
+
+static void
+dhd_module_cleanup(void)
+{
+#ifdef DHD_SR_FIX
+	uint wl_down = 1;
+	int ret = 0;
+#endif /* DHD_SR_FIX */
+
+#if defined(ENABLE_NOT_LOAD_DHD_MODULE)
+	DHD_ERROR(("%s ##### Do not clean-up due to secondary build\n", __FUNCTION__));
+	return;
+#endif /* ENABLE_NOT_LOAD_DHD_MODULE */
+	printf("%s: Enter\n", __FUNCTION__);
+
+#ifdef DHD_SR_FIX
+	ret = dhd_wl_ioctl_cmd(g_dhd_pub, WLC_DOWN,
+		(char *)&wl_down, sizeof(wl_down), TRUE, 0);
+	DHD_ERROR(("%s WL_DOWN : %d\n", __FUNCTION__, ret));
+#endif /* DHD_SR_FIX */
+
+	dhd_bus_unregister();
+
+#if defined(OEM_ANDROID)
+	wl_android_exit();
+#endif /* OEM_ANDROID */
+
+	dhd_wifi_platform_unregister_drv();
+#if defined(CONFIG_DHD_USE_STATIC_BUF) && defined(DHD_STATIC_IN_DRIVER)
+	dhd_static_buf_exit();
+#endif /* CONFIG_DHD_USE_STATIC_BUF && DHD_STATIC_IN_DRIVER */
+	printf("%s: Exit\n", __FUNCTION__);
+}
+
+static void __exit
+dhd_module_exit(void)
+{
+#if defined(ENABLE_NOT_LOAD_DHD_MODULE)
+	DHD_ERROR(("%s ##### Do not unload driver due to secondary build\n", __FUNCTION__));
+	return;
+#endif /* ENABLE_NOT_LOAD_DHD_MODULE */
+	atomic_set(&exit_in_progress, 1);
+#ifdef DHD_BUZZZ_LOG_ENABLED
+	dhd_buzzz_detach();
+#endif /* DHD_BUZZZ_LOG_ENABLED */
+	dhd_module_cleanup();
+	unregister_reboot_notifier(&dhd_reboot_notifier);
+	dhd_destroy_to_notifier_skt();
+}
+
+#if defined(CONFIG_ARCH_WAIPIO) || defined(CONFIG_SOC_S5E9925)
+extern bool devid_mismatch;
+#endif /* CONFIG_ARCH_WAIPIO || CONFIG_SOC_S5E9925 */
+
+static int
+_dhd_module_init(void)
+{
+	int err;
+	int retry = POWERUP_MAX_RETRY;
+
+	printk(KERN_ERR PERCENT_S DHD_LOG_PREFIXS "%s: in %s\n",
+		PRINTF_SYSTEM_TIME, __FUNCTION__, dhd_version);
+	if (ANDROID_VERSION > 0)
+		printf("ANDROID_VERSION = %d\n", ANDROID_VERSION);
+#if defined(CONFIG_DHD_USE_STATIC_BUF) && defined(DHD_STATIC_IN_DRIVER)
+	err = dhd_static_buf_init();
+	if (err) {
+		goto exit;
+	}
+#endif /* CONFIG_DHD_USE_STATIC_BUF && DHD_STATIC_IN_DRIVER */
+
+#ifdef DHD_BUZZZ_LOG_ENABLED
+	dhd_buzzz_attach();
+#endif /* DHD_BUZZZ_LOG_ENABLED */
+
+#if defined(BCM_ROUTER_DHD)
+	{	/* XXX Should we maintain nvram budget/thresholds per 5G|2G radio? */
+		char * var;
+		if ((var = getvar(NULL, "dhd_queue_budget")) != NULL) {
+			dhd_queue_budget = bcm_strtoul(var, NULL, 0);
+		}
+		DHD_ERROR(("dhd_queue_budget = %d\n", dhd_queue_budget));
+
+		if ((var = getvar(NULL, "dhd_sta_threshold")) != NULL) {
+			dhd_sta_threshold = bcm_strtoul(var, NULL, 0);
+		}
+		DHD_ERROR(("dhd_sta_threshold = %d\n", dhd_sta_threshold));
+
+		if ((var = getvar(NULL, "dhd_if_threshold")) != NULL) {
+			dhd_if_threshold = bcm_strtoul(var, NULL, 0);
+		}
+		DHD_ERROR(("dhd_if_threshold = %d\n", dhd_if_threshold));
+	}
+#endif /* BCM_ROUTER_DHD */
+
+	if (firmware_path[0] != '\0') {
+		strlcpy(fw_bak_path, firmware_path, sizeof(fw_bak_path));
+	}
+
+	if (nvram_path[0] != '\0') {
+		strlcpy(nv_bak_path, nvram_path, sizeof(nv_bak_path));
+	}
+
+	do {
+		err = dhd_wifi_platform_register_drv();
+		if (!err) {
+			register_reboot_notifier(&dhd_reboot_notifier);
+			dhd_create_to_notifier_skt();
+			break;
+		} else {
+			if (err == -ENXIO) {
+				DHD_ERROR(("%s: driver is disabled\n", __FUNCTION__));
+				break;
+			}
+#if defined(CONFIG_ARCH_WAIPIO) || defined(CONFIG_SOC_S5E9925)
+			if (devid_mismatch == TRUE) {
+				DHD_ERROR(("%s: Devid is mismatch, don't retry\n",
+						__FUNCTION__));
+				break;
+			}
+#endif /* CONFIG_ARCH_WAIPIO || CONFIG_SOC_S5E9925 */
+			DHD_ERROR(("%s: Failed to load the driver, try cnt %d\n",
+				__FUNCTION__, retry));
+			strlcpy(firmware_path, fw_bak_path, sizeof(firmware_path));
+			strlcpy(nvram_path, nv_bak_path, sizeof(nvram_path));
+		}
+	} while (retry--);
+
+#if defined(CONFIG_ARCH_WAIPIO) || defined(CONFIG_SOC_S5E9925)
+	if (devid_mismatch == TRUE) {
+		DHD_ERROR(("%s: Return true if devid is mismatch \n", __FUNCTION__));
+		return 0;
+	}
+#endif /* CONFIG_ARCH_WAIPIO || CONFIG_SOC_S5E9925 */
+
+	if (err) {
+		DHD_ERROR(("%s: Failed to load driver max retry reached**\n", __FUNCTION__));
+	} else {
+		if (!dhd_download_fw_on_driverload) {
+			dhd_driver_init_done = TRUE;
+		}
+	}
+
+#if defined(CONFIG_DHD_USE_STATIC_BUF) && defined(DHD_STATIC_IN_DRIVER)
+exit:
+	if (err)
+		dhd_static_buf_exit();
+#endif /* CONFIG_DHD_USE_STATIC_BUF && DHD_STATIC_IN_DRIVER */
+	printf("%s: Exit err=%d\n", __FUNCTION__, err);
+	return err;
+}
+
+static int
+dhd_module_init(void)
+{
+	int err;
+
+#if defined(ENABLE_NOT_LOAD_DHD_MODULE)
+	DHD_ERROR(("%s ##### Do not load driver due to secondary build\n", __FUNCTION__));
+	return 0;
+#endif /* ENABLE_NOT_LOAD_DHD_MODULE */
+	err = _dhd_module_init();
+#ifdef DHD_SUPPORT_HDM
+	if (hdm_wifi_support && err && !dhd_download_fw_on_driverload) {
+		dhd_hdm_wlan_sysfs_init();
+		err = 0;
+	}
+#endif /* DHD_SUPPORT_HDM */
+#if defined(BCMDHD_MODULAR) && defined(DHD_MODULE_INIT_FORCE_SUCCESS)
+	err = 0;
+#endif /* BCMDHD_MODULAR && DHD_MODULE_INIT_FORCE_SUCCESS */
+	return err;
+
+}
+
+#ifdef DHD_SUPPORT_HDM
+bool hdm_trigger_init = FALSE;
+struct delayed_work hdm_sysfs_wq;
+
+int
+dhd_module_init_hdm(void)
+{
+	int err = 0;
+
+	hdm_trigger_init = TRUE;
+
+	if (dhd_driver_init_done) {
+		DHD_INFO(("%s : Module is already inited\n", __FUNCTION__));
+		return err;
+	}
+
+	err = _dhd_module_init();
+
+	/* remove sysfs file after module load properly */
+	if (!err && !dhd_download_fw_on_driverload) {
+		INIT_DELAYED_WORK(&hdm_sysfs_wq, dhd_hdm_wlan_sysfs_deinit);
+		schedule_delayed_work(&hdm_sysfs_wq, msecs_to_jiffies(SYSFS_DEINIT_MS));
+	}
+
+	hdm_trigger_init = FALSE;
+	return err;
+}
+#endif /* DHD_SUPPORT_HDM */
+
+static int
+dhd_reboot_callback(struct notifier_block *this, unsigned long code, void *unused)
+{
+	dhd_pub_t *dhdp = g_dhd_pub;
+
+	BCM_REFERENCE(dhdp);
+	DHD_ERROR(("%s: code = %ld\n", __FUNCTION__, code));
+#ifdef OEM_ANDROID
+	if (!OSL_ATOMIC_INC_AND_TEST(dhdp->osh, &reboot_in_progress)) {
+		DHD_ERROR(("%s: Skip duplicated reboot callback!\n", __FUNCTION__));
+		return NOTIFY_DONE;
+	}
+
+	dhd_module_cleanup();
+#else
+	if (code == SYS_RESTART) {
+		dhd_module_cleanup();
+	}
+#endif /* OEM_ANDROID */
+	return NOTIFY_DONE;
+}
+
+#if defined(CONFIG_DEFERRED_INITCALLS) && !defined(EXYNOS_PCIE_MODULE_PATCH)
+/* XXX To decrease the device boot time, deferred_module_init() macro can be
+ * used. The detailed principle and implemenation of deferred_module_init()
+ * is found at http://elinux.org/Deferred_Initcalls
+ * To enable this feature for module build, it needs to add another
+ * deferred_module_init() definition to include/linux/init.h in Linux Kernel.
+ * #define deferred_module_init(fn)	module_init(fn)
+ */
+#if defined(CONFIG_ARCH_MSM) || defined(CONFIG_ARCH_EXYNOS)
+deferred_module_init_sync(dhd_module_init);
+#else /* defined(CONFIG_ARCH_MSM) || defined(CONFIG_ARCH_EXYNOS) */
+deferred_module_init(dhd_module_init);
+#endif /* CONFIG_ARCH_MSM || CONFIG_ARCH_EXYNOS */
+#elif defined(USE_LATE_INITCALL_SYNC)
+late_initcall_sync(dhd_module_init);
+#elif defined(late_initcall)
+late_initcall(dhd_module_init);
+#else /* default */
+module_init(dhd_module_init);
+#endif /* CONFIG_DEFERRED_INITCALLS */
+
+module_exit(dhd_module_exit);
+
+/* For the Exynos platform, the WLAN_REG_ON pin is connected to an expander GPIO such as PMIC.
+ * The WLAN_REG_ON pin initialization failed
+ * if the Wi-Fi module is loaded before the PMIC module is loaded.
+ * Add the MODULE_SOFTDEP macro to load the Wi-Fi module after the PMIC module is loaded.
+ */
+#if defined(CONFIG_SOC_S5E9925)
+MODULE_SOFTDEP("pre: acpm-mfd-bus");
+#endif /* CONFIG_SOC_S5E9925 */
+
+/*
+ * OS specific functions required to implement DHD driver in OS independent way
+ */
+int
+dhd_os_proto_block(dhd_pub_t *pub)
+{
+	dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		down(&dhd->proto_sem);
+
+		return 1;
+	}
+
+	return 0;
+}
+
+int
+dhd_os_proto_unblock(dhd_pub_t *pub)
+{
+	dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		up(&dhd->proto_sem);
+		return 1;
+	}
+
+	return 0;
+}
+
+void
+dhd_os_dhdiovar_lock(dhd_pub_t *pub)
+{
+	dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		mutex_lock(&dhd->dhd_iovar_mutex);
+	}
+}
+
+void
+dhd_os_dhdiovar_unlock(dhd_pub_t *pub)
+{
+	dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		mutex_unlock(&dhd->dhd_iovar_mutex);
+	}
+}
+
+void
+dhd_os_logdump_lock(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = NULL;
+
+	if (!pub)
+		return;
+
+	dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		mutex_lock(&dhd->logdump_lock);
+	}
+}
+
+void
+dhd_os_logdump_unlock(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = NULL;
+
+	if (!pub)
+		return;
+
+	dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		mutex_unlock(&dhd->logdump_lock);
+	}
+}
+
+unsigned int
+dhd_os_get_ioctl_resp_timeout(void)
+{
+	return ((unsigned int)dhd_ioctl_timeout_msec);
+}
+
+void
+dhd_os_set_ioctl_resp_timeout(unsigned int timeout_msec)
+{
+	dhd_ioctl_timeout_msec = (int)timeout_msec;
+}
+
+int
+dhd_os_ioctl_resp_wait(dhd_pub_t *pub, uint *condition)
+{
+	dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+	int timeout;
+
+	/* Convert timeout in millsecond to jiffies */
+	timeout = msecs_to_jiffies(dhd_ioctl_timeout_msec);
+
+#ifdef BCMQT_HW
+	DHD_ERROR(("%s, Timeout wait until %d mins (%d ms) in QT mode\n",
+		__FUNCTION__, (dhd_ioctl_timeout_msec / (60 * 1000)), dhd_ioctl_timeout_msec));
+#endif /* BCMQT_HW */
+
+	timeout = wait_event_timeout(dhd->ioctl_resp_wait, (*condition), timeout);
+
+	return timeout;
+}
+
+int
+dhd_os_ioctl_resp_wake(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	wake_up(&dhd->ioctl_resp_wait);
+	return 0;
+}
+
+int
+dhd_os_d3ack_wait(dhd_pub_t *pub, uint *condition)
+{
+	dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+	int timeout;
+
+	/* Convert timeout in millsecond to jiffies */
+	timeout = msecs_to_jiffies(D3_ACK_RESP_TIMEOUT);
+#ifdef BCMSLTGT
+	timeout *= htclkratio;
+#endif /* BCMSLTGT */
+
+	timeout = wait_event_timeout(dhd->d3ack_wait, (*condition), timeout);
+
+	return timeout;
+}
+
+#ifdef PCIE_INB_DW
+int
+dhd_os_ds_exit_wait(dhd_pub_t *pub, uint *condition)
+{
+	dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+	int timeout;
+
+	/* Convert timeout in millsecond to jiffies */
+	timeout = msecs_to_jiffies(ds_exit_timeout_msec);
+#ifdef BCMSLTGT
+	timeout *= htclkratio;
+#endif /* BCMSLTGT */
+
+	timeout = wait_event_timeout(dhd->ds_exit_wait, (*condition), timeout);
+
+	return timeout;
+}
+
+int
+dhd_os_ds_exit_wake(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	wake_up_all(&dhd->ds_exit_wait);
+	return 0;
+}
+
+#endif /* PCIE_INB_DW */
+
+int
+dhd_os_d3ack_wake(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	wake_up(&dhd->d3ack_wait);
+	return 0;
+}
+
+int
+dhd_os_busbusy_wait_negation(dhd_pub_t *pub, uint *condition)
+{
+	dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+	int timeout;
+
+	/* Wait for bus usage contexts to gracefully exit within some timeout value
+	 * Set time out to little higher than dhd_ioctl_timeout_msec,
+	 * so that IOCTL timeout should not get affected.
+	 */
+	/* Convert timeout in millsecond to jiffies */
+	timeout = msecs_to_jiffies(DHD_BUS_BUSY_TIMEOUT);
+
+	timeout = wait_event_timeout(dhd->dhd_bus_busy_state_wait, !(*condition), timeout);
+
+	return timeout;
+}
+
+/*
+ * Wait until the condition *var == condition is met.
+ * Returns 0 if the @condition evaluated to false after the timeout elapsed
+ * Returns 1 if the @condition evaluated to true
+ */
+int
+dhd_os_busbusy_wait_condition(dhd_pub_t *pub, uint *var, uint condition)
+{
+	dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+	int timeout;
+
+	/* Convert timeout in millsecond to jiffies */
+	timeout = msecs_to_jiffies(DHD_BUS_BUSY_TIMEOUT);
+
+	timeout = wait_event_timeout(dhd->dhd_bus_busy_state_wait, (*var == condition), timeout);
+
+	return timeout;
+}
+
+/*
+ * Wait until the '(*var & bitmask) == condition' is met.
+ * Returns 0 if the @condition evaluated to false after the timeout elapsed
+ * Returns 1 if the @condition evaluated to true
+ */
+int
+dhd_os_busbusy_wait_bitmask(dhd_pub_t *pub, uint *var,
+		uint bitmask, uint condition)
+{
+	dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+	int timeout;
+
+	/* Convert timeout in millsecond to jiffies */
+	timeout = msecs_to_jiffies(DHD_BUS_BUSY_TIMEOUT);
+
+	timeout = wait_event_timeout(dhd->dhd_bus_busy_state_wait,
+			((*var & bitmask) == condition), timeout);
+
+	return timeout;
+}
+
+int
+dhd_os_dmaxfer_wait(dhd_pub_t *pub, uint *condition)
+{
+	int ret = 0;
+	dhd_info_t * dhd = (dhd_info_t *)(pub->info);
+	int timeout;
+
+	timeout = msecs_to_jiffies(IOCTL_DMAXFER_TIMEOUT);
+
+	ret = wait_event_timeout(dhd->dmaxfer_wait, (*condition), timeout);
+
+	return ret;
+
+}
+
+int
+dhd_os_dmaxfer_wake(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	wake_up(&dhd->dmaxfer_wait);
+	return 0;
+}
+
+/* Fix compilation error for FC11 */
+INLINE int
+dhd_os_busbusy_wake(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	/* Call wmb() to make sure before waking up the other event value gets updated */
+	OSL_SMP_WMB();
+	wake_up(&dhd->dhd_bus_busy_state_wait);
+	return 0;
+}
+
+void
+dhd_os_wd_timer_extend(void *bus, bool extend)
+{
+#ifndef BCMDBUS
+	dhd_pub_t *pub = bus;
+	dhd_info_t *dhd = (dhd_info_t *)pub->info;
+
+	if (extend)
+		dhd_os_wd_timer(bus, WATCHDOG_EXTEND_INTERVAL);
+	else
+		dhd_os_wd_timer(bus, dhd->default_wd_interval);
+#endif /* !BCMDBUS */
+}
+
+void
+dhd_os_wd_timer(void *bus, uint wdtick)
+{
+#ifndef BCMDBUS
+	dhd_pub_t *pub = bus;
+	dhd_info_t *dhd = (dhd_info_t *)pub->info;
+	unsigned long flags;
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd NULL\n", __FUNCTION__));
+		return;
+	}
+
+	DHD_GENERAL_LOCK(pub, flags);
+
+	/* don't start the wd until fw is loaded */
+	if (pub->busstate == DHD_BUS_DOWN) {
+		DHD_GENERAL_UNLOCK(pub, flags);
+#ifdef BCMSDIO
+		if (!wdtick) {
+			DHD_OS_WD_WAKE_UNLOCK(pub);
+		}
+#endif /* BCMSDIO */
+		return;
+	}
+
+	/* Totally stop the timer */
+	if (!wdtick && dhd->wd_timer_valid == TRUE) {
+		dhd->wd_timer_valid = FALSE;
+		DHD_GENERAL_UNLOCK(pub, flags);
+		del_timer_sync(&dhd->timer);
+#ifdef BCMSDIO
+		DHD_OS_WD_WAKE_UNLOCK(pub);
+#endif /* BCMSDIO */
+		return;
+	}
+
+	if (wdtick) {
+#ifdef BCMSDIO
+		DHD_OS_WD_WAKE_LOCK(pub);
+		dhd_watchdog_ms = (uint)wdtick;
+#endif /* BCMSDIO */
+		/* Re arm the timer, at last watchdog period */
+		mod_timer(&dhd->timer, jiffies + msecs_to_jiffies(dhd_watchdog_ms));
+		dhd->wd_timer_valid = TRUE;
+	}
+	DHD_GENERAL_UNLOCK(pub, flags);
+#endif /* BCMDBUS */
+}
+
+#ifdef DHD_LINUX_STD_FW_API
+int
+dhd_os_get_img_fwreq(const struct firmware **fw, char *file_path)
+{
+	int ret = BCME_ERROR;
+
+	ret = request_firmware(fw, file_path, dhd_bus_to_dev(g_dhd_pub->bus));
+	if (ret < 0) {
+		DHD_ERROR(("%s: request_firmware %s err: %d\n", __FUNCTION__, file_path, ret));
+		/* convert to BCME_NOTFOUND error for error handling */
+		ret = BCME_NOTFOUND;
+	} else
+		DHD_ERROR(("%s: %s (%zu bytes) open success\n", __FUNCTION__, file_path, (*fw)->size));
+
+	return ret;
+}
+
+void
+dhd_os_close_img_fwreq(const struct firmware *fw)
+{
+	release_firmware(fw);
+}
+#endif /* DHD_LINUX_STD_FW_API */
+
+void *
+dhd_os_open_image1(dhd_pub_t *pub, char *filename)
+{
+	struct file *fp;
+	int size;
+
+	fp = dhd_filp_open(filename, O_RDONLY, 0);
+
+	/*
+	 * 2.6.11 (FC4) supports dhd_filp_open() but later revs don't?
+	 * Alternative:
+	 * fp = open_namei(AT_FDCWD, filename, O_RD, 0);
+	 * ???
+	 */
+	 if (IS_ERR(fp) || (fp == NULL)) {
+		 fp = NULL;
+		 goto err;
+	 }
+
+	 if (!S_ISREG(file_inode(fp)->i_mode)) {
+		 DHD_ERROR(("%s: %s is not regular file\n", __FUNCTION__, filename));
+		 fp = NULL;
+		 goto err;
+	 }
+
+	 size = dhd_i_size_read(file_inode(fp));
+	 if (size <= 0) {
+		 DHD_ERROR(("%s: %s file size invalid %d\n", __FUNCTION__, filename, size));
+		 fp = NULL;
+		 goto err;
+	 }
+
+	 DHD_ERROR(("%s: %s (%d bytes) open success\n", __FUNCTION__, filename, size));
+
+err:
+	 return fp;
+}
+
+int
+dhd_os_get_image_block(char *buf, int len, void *image)
+{
+	struct file *fp = (struct file *)image;
+	int rdlen;
+	int size;
+
+	if (!image) {
+		return 0;
+	}
+
+	size = dhd_i_size_read(file_inode(fp));
+	rdlen = dhd_kernel_read_compat(fp, fp->f_pos, buf, MIN(len, size));
+
+	if (len >= size && size != rdlen) {
+		return -EIO;
+	}
+
+	if (rdlen > 0) {
+		fp->f_pos += rdlen;
+	}
+
+	return rdlen;
+}
+
+#if defined(BT_OVER_SDIO)
+int
+dhd_os_gets_image(dhd_pub_t *pub, char *str, int len, void *image)
+{
+	struct file *fp = (struct file *)image;
+	int rd_len;
+	uint str_len = 0;
+	char *str_end = NULL;
+
+	if (!image)
+		return 0;
+
+	rd_len = dhd_kernel_read_compat(fp, fp->f_pos, str, len);
+	str_end = strnchr(str, len, '\n');
+	if (str_end == NULL) {
+		goto err;
+	}
+	str_len = (uint)(str_end - str);
+
+	/* Advance file pointer past the string length */
+	fp->f_pos += str_len + 1;
+	bzero(str_end, rd_len - str_len);
+
+err:
+	return str_len;
+}
+#endif /* defined (BT_OVER_SDIO) */
+
+int
+dhd_os_get_image_size(void *image)
+{
+	struct file *fp = (struct file *)image;
+	int size;
+	if (!image) {
+		return 0;
+	}
+
+	size = dhd_i_size_read(file_inode(fp));
+
+	return size;
+}
+
+void
+dhd_os_close_image1(dhd_pub_t *pub, void *image)
+{
+	if (image) {
+		dhd_filp_close((struct file *)image, NULL);
+	}
+}
+
+void
+dhd_os_sdlock(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd;
+
+	dhd = (dhd_info_t *)(pub->info);
+
+#ifdef BCMDBUS
+	spin_lock_bh(&dhd->sdlock);
+#else
+	if (dhd_dpc_prio >= 0)
+		down(&dhd->sdsem);
+	else
+		spin_lock_bh(&dhd->sdlock);
+#endif /* !BCMDBUS */
+}
+
+void
+dhd_os_sdunlock(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd;
+
+	dhd = (dhd_info_t *)(pub->info);
+
+#ifdef BCMDBUS
+	spin_unlock_bh(&dhd->sdlock);
+#else
+	if (dhd_dpc_prio >= 0)
+		up(&dhd->sdsem);
+	else
+		spin_unlock_bh(&dhd->sdlock);
+#endif /* !BCMDBUS */
+}
+
+#ifdef DHDTCPACK_SUPPRESS
+unsigned long
+dhd_os_tcpacklock(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd;
+	unsigned long flags = 0;
+
+	dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+#ifdef BCMSDIO
+		spin_lock_bh(&dhd->tcpack_lock);
+#else
+		flags = osl_spin_lock(&dhd->tcpack_lock);
+#endif /* BCMSDIO */
+	}
+
+	return flags;
+}
+
+void
+dhd_os_tcpackunlock(dhd_pub_t *pub, unsigned long flags)
+{
+	dhd_info_t *dhd;
+
+#ifdef BCMSDIO
+	BCM_REFERENCE(flags);
+#endif /* BCMSDIO */
+
+	dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+#ifdef BCMSDIO
+		spin_unlock_bh(&dhd->tcpack_lock);
+#else
+		osl_spin_unlock(&dhd->tcpack_lock, flags);
+#endif /* BCMSDIO */
+	}
+}
+#endif /* DHDTCPACK_SUPPRESS */
+
+uint8* dhd_os_prealloc(dhd_pub_t *dhdpub, int section, uint size, bool kmalloc_if_fail)
+{
+	uint8* buf;
+	gfp_t flags = CAN_SLEEP() ? GFP_KERNEL: GFP_ATOMIC;
+
+	buf = (uint8*)wifi_platform_prealloc(dhdpub->info->adapter, section, size);
+	if (buf == NULL && kmalloc_if_fail)
+		buf = kmalloc(size, flags);
+
+	return buf;
+}
+
+void dhd_os_prefree(dhd_pub_t *dhdpub, void *addr, uint size)
+{
+}
+
+#if defined(WL_WIRELESS_EXT)
+struct iw_statistics *
+dhd_get_wireless_stats(struct net_device *dev)
+{
+	int res = 0;
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+
+	if (!dhd->pub.up) {
+		return NULL;
+	}
+
+	if (!(dev->flags & IFF_UP)) {
+		return NULL;
+	}
+
+	res = wl_iw_get_wireless_stats(dev, &dhd->iw.wstats);
+
+	if (res == 0)
+		return &dhd->iw.wstats;
+	else
+		return NULL;
+}
+#endif /* defined(WL_WIRELESS_EXT) */
+
+/* send up locally generated event */
+void
+dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, void *data)
+{
+	switch (ntoh32(event->event_type)) {
+	/* Handle error case or further events here */
+	default:
+		break;
+	}
+}
+
+#ifdef LOG_INTO_TCPDUMP
+void
+dhd_sendup_log(dhd_pub_t *dhdp, void *data, int data_len)
+{
+	struct sk_buff *p, *skb;
+	uint32 pktlen;
+	int len;
+	dhd_if_t *ifp;
+	dhd_info_t *dhd;
+	uchar *skb_data;
+	int ifidx = 0;
+	struct ether_header eth;
+
+	pktlen = sizeof(eth) + data_len;
+	dhd = dhdp->info;
+
+	if ((p = PKTGET(dhdp->osh, pktlen, FALSE))) {
+		ASSERT(ISALIGNED((uintptr)PKTDATA(dhdp->osh, p), sizeof(uint32)));
+
+		bcopy(&dhdp->mac, &eth.ether_dhost, ETHER_ADDR_LEN);
+		bcopy(&dhdp->mac, &eth.ether_shost, ETHER_ADDR_LEN);
+		ETHER_TOGGLE_LOCALADDR(&eth.ether_shost);
+		eth.ether_type = hton16(ETHER_TYPE_BRCM);
+
+		bcopy((void *)&eth, PKTDATA(dhdp->osh, p), sizeof(eth));
+		bcopy(data, PKTDATA(dhdp->osh, p) + sizeof(eth), data_len);
+		skb = PKTTONATIVE(dhdp->osh, p);
+		skb_data = skb->data;
+		len = skb->len;
+
+		ifidx = dhd_ifname2idx(dhd, "wlan0");
+		ifp = dhd->iflist[ifidx];
+		if (ifp == NULL)
+			 ifp = dhd->iflist[0];
+
+		ASSERT(ifp);
+		skb->dev = ifp->net;
+		skb->protocol = eth_type_trans(skb, skb->dev);
+		skb->data = skb_data;
+		skb->len = len;
+
+		/* Strip header, count, deliver upward */
+		skb_pull(skb, ETH_HLEN);
+
+		bcm_object_trace_opr(skb, BCM_OBJDBG_REMOVE,
+			__FUNCTION__, __LINE__);
+		/* Send the packet */
+		if (in_interrupt()) {
+			netif_rx(skb);
+		} else {
+			dhd_netif_rx_ni(skb);
+		}
+	} else {
+		/* Could not allocate a sk_buf */
+		DHD_ERROR(("%s: unable to alloc sk_buf\n", __FUNCTION__));
+	}
+}
+#endif /* LOG_INTO_TCPDUMP */
+
+void dhd_wait_for_event(dhd_pub_t *dhd, bool *lockvar)
+{
+#if defined(BCMSDIO)
+	struct dhd_info *dhdinfo =  dhd->info;
+
+	int timeout = msecs_to_jiffies(IOCTL_RESP_TIMEOUT);
+
+	dhd_os_sdunlock(dhd);
+	wait_event_timeout(dhdinfo->ctrl_wait, (*lockvar == FALSE), timeout);
+	dhd_os_sdlock(dhd);
+#endif /* defined(BCMSDIO) */
+	return;
+}
+
+void dhd_wait_event_wakeup(dhd_pub_t *dhd)
+{
+#if defined(BCMSDIO)
+	struct dhd_info *dhdinfo =  dhd->info;
+	if (waitqueue_active(&dhdinfo->ctrl_wait))
+		wake_up(&dhdinfo->ctrl_wait);
+#endif
+	return;
+}
+
+#if defined(BCMSDIO) || defined(BCMPCIE) || defined(BCMDBUS)
+int
+dhd_net_bus_devreset(struct net_device *dev, uint8 flag)
+{
+	int ret;
+
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+	if (pm_runtime_get_sync(dhd_bus_to_dev(dhd->pub.bus)) < 0)
+		return BCME_ERROR;
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+	if (flag == TRUE) {
+#ifndef WL_CFG80211
+		/* Issue wl down command for non-cfg before resetting the chip */
+		if (dhd_wl_ioctl_cmd(&dhd->pub, WLC_DOWN, NULL, 0, TRUE, 0) < 0) {
+			DHD_TRACE(("%s: wl down failed\n", __FUNCTION__));
+		}
+#endif /* !WL_CFG80211 */
+#ifdef PROP_TXSTATUS
+		if (dhd->pub.wlfc_enabled) {
+			dhd_wlfc_deinit(&dhd->pub);
+		}
+#endif /* PROP_TXSTATUS */
+#ifdef PNO_SUPPORT
+		if (dhd->pub.pno_state) {
+			dhd_pno_deinit(&dhd->pub);
+		}
+#endif
+#ifdef RTT_SUPPORT
+		if (dhd->pub.rtt_state) {
+			dhd_rtt_deinit(&dhd->pub);
+		}
+#endif /* RTT_SUPPORT */
+
+		DHD_SSSR_DUMP_DEINIT(&dhd->pub);
+#ifdef DHD_SDTC_ETB_DUMP
+		if (dhd->pub.sdtc_etb_inited) {
+			dhd_sdtc_etb_deinit(&dhd->pub);
+		}
+#endif /* DHD_SDTC_ETB_DUMP */
+/*
+ * XXX Detach only if the module is not attached by default at dhd_attach.
+ * If attached by default, we need to keep it till dhd_detach, so that
+ * module is not detached at wifi on/off
+ */
+#if defined(DBG_PKT_MON) && !defined(DBG_PKT_MON_INIT_DEFAULT)
+		dhd_os_dbg_detach_pkt_monitor(&dhd->pub);
+#endif /* DBG_PKT_MON */
+	}
+
+#ifdef BCMSDIO
+	/* XXX Some DHD modules (e.g. cfg80211) configures operation mode based on firmware name.
+	 * This is indeed a hack but we have to make it work properly before we have a better
+	 * solution
+	 */
+	if (!flag) {
+		dhd_update_fw_nv_path(dhd);
+		/* update firmware and nvram path to sdio bus */
+		dhd_bus_update_fw_nv_path(dhd->pub.bus,
+			dhd->fw_path, dhd->nv_path, dhd->clm_path, dhd->conf_path);
+	}
+#endif /* BCMSDIO */
+#if defined(BCMPCIE)
+	/* XXX: JIRA SWWLAN-139454: Added L1ss enable
+	 * after firmware download completion due to link down issue
+	 * JIRA SWWLAN-142236: Amendment - Changed L1ss enable point
+	 */
+	if (flag == FALSE && dhd->pub.busstate == DHD_BUS_DOWN) {
+		DHD_RPM(("%s Disable L1ss EP side\n", __FUNCTION__));
+		dhd_plat_l1ss_ctrl(0);
+	}
+#endif /* BCMPCIE */
+
+	ret = dhd_bus_devreset(&dhd->pub, flag);
+
+	if (!ret && dhd_query_bus_erros(&dhd->pub)) {
+		DHD_ERROR(("%s: retrun error due to query errors\n", __FUNCTION__));
+		ret = BCME_ERROR;
+	}
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+	pm_runtime_mark_last_busy(dhd_bus_to_dev(dhd->pub.bus));
+	pm_runtime_put_autosuspend(dhd_bus_to_dev(dhd->pub.bus));
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+	if (flag) {
+		/* Clear some flags for recovery logic */
+		dhd->pub.dongle_trap_occured = 0;
+		dhd->pub.dsack_hc_due_to_isr_delay = 0;
+		dhd->pub.dsack_hc_due_to_dpc_delay = 0;
+		dhd->pub.iovar_timeout_occured = 0;
+#ifdef PCIE_FULL_DONGLE
+		dhd->pub.d3ack_timeout_occured = 0;
+		dhd->pub.livelock_occured = 0;
+		dhd->pub.pktid_audit_failed = 0;
+		dhd->pub.pktid_invalid_occured = 0;
+#endif /* PCIE_FULL_DONGLE */
+		dhd->pub.smmu_fault_occurred = 0;
+		dhd->pub.iface_op_failed = 0;
+		dhd->pub.scan_timeout_occurred = 0;
+		dhd->pub.scan_busy_occurred = 0;
+		dhd->pub.p2p_disc_busy_occurred = 0;
+	}
+
+	dhd->pub.p2p_disc_busy_cnt = 0;
+
+	if (ret == BCME_NOMEM) {
+		DHD_ERROR(("%s: skip collect dump in case of BCME_NOMEM\n",
+				__FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	if ((ret == BCME_NOMEM) || (ret == BCME_NOTFOUND)) {
+		DHD_ERROR(("%s: skip collect dump in case of BCME_NOMEM or BCME_NOTFOUND\n",
+				__FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	if (ret) {
+		DHD_ERROR(("%s: dhd_bus_devreset: %d\n", __FUNCTION__, ret));
+		dhd_force_collect_init_fail_dumps(&dhd->pub);
+	}
+
+	return ret;
+}
+
+#if defined(BCMSDIO) || defined(BCMPCIE)
+int
+dhd_net_bus_suspend(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	uint bitmask = 0xFFFFFFFF;
+	int timeleft = 0;
+	unsigned long flags = 0;
+	int ret = 0;
+
+	DHD_GENERAL_LOCK(&dhd->pub, flags);
+	if (!DHD_BUS_BUSY_CHECK_IDLE(&dhd->pub)) {
+		DHD_BUS_BUSY_SET_SUSPEND_IN_PROGRESS(&dhd->pub);
+		DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+		DHD_ERROR(("%s: wait to clear dhd_bus_busy_state: 0x%x\n",
+			__FUNCTION__, dhd->pub.dhd_bus_busy_state));
+		timeleft = dhd_os_busbusy_wait_bitmask(&dhd->pub,
+				&dhd->pub.dhd_bus_busy_state, bitmask,
+				DHD_BUS_BUSY_SUSPEND_IN_PROGRESS);
+		if ((timeleft == 0) || (timeleft == 1)) {
+			DHD_ERROR(("%s: Timed out dhd_bus_busy_state=0x%x\n",
+				__FUNCTION__, dhd->pub.dhd_bus_busy_state));
+			ASSERT(0);
+		}
+	} else {
+		DHD_BUS_BUSY_SET_SUSPEND_IN_PROGRESS(&dhd->pub);
+		DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+	}
+
+	ret = dhd_bus_suspend(&dhd->pub);
+
+	DHD_GENERAL_LOCK(&dhd->pub, flags);
+	DHD_BUS_BUSY_CLEAR_SUSPEND_IN_PROGRESS(&dhd->pub);
+	dhd_os_busbusy_wake(&dhd->pub);
+	DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+
+	return ret;
+}
+
+int
+dhd_net_bus_resume(struct net_device *dev, uint8 stage)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	unsigned long flags = 0;
+	int ret = 0;
+
+	DHD_GENERAL_LOCK(&dhd->pub, flags);
+	DHD_BUS_BUSY_SET_RESUME_IN_PROGRESS(&dhd->pub);
+	DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+
+	ret = dhd_bus_resume(&dhd->pub, stage);
+
+	DHD_GENERAL_LOCK(&dhd->pub, flags);
+	DHD_BUS_BUSY_CLEAR_RESUME_IN_PROGRESS(&dhd->pub);
+	dhd_os_busbusy_wake(&dhd->pub);
+	DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+
+	return ret;
+}
+
+#endif /* BCMSDIO || BCMPCIE */
+#endif /* BCMSDIO || BCMPCIE || BCMDBUS */
+
+int net_os_set_suspend_disable(struct net_device *dev, int val)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	int ret = 0;
+
+	if (dhd) {
+		ret = dhd->pub.suspend_disable_flag;
+		dhd->pub.suspend_disable_flag = val;
+	}
+	return ret;
+}
+
+int net_os_set_suspend(struct net_device *dev, int val, int force)
+{
+	int ret = 0;
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+
+	if (dhd && (dhd->pub.conf->suspend_mode == EARLY_SUSPEND ||
+			dhd->pub.conf->suspend_mode == SUSPEND_MODE_2)) {
+		if (dhd->pub.conf->suspend_mode == EARLY_SUSPEND && !val)
+			dhd_conf_set_suspend_resume(&dhd->pub, val);
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
+		ret = dhd_set_suspend(val, &dhd->pub);
+#else
+		ret = dhd_suspend_resume_helper(dhd, val, force);
+#endif
+#ifdef WL_CFG80211
+		wl_cfg80211_update_power_mode(dev);
+#endif
+		if (dhd->pub.conf->suspend_mode == EARLY_SUSPEND && val)
+			dhd_conf_set_suspend_resume(&dhd->pub, val);
+	}
+	return ret;
+}
+
+#ifdef PKT_FILTER_SUPPORT
+/* XXX RB:4238 Change net_os_set_packet_filter() function name to net_os_enable_packet_filter()
+ * previous code do 'set' & 'enable' in one fucntion.
+ * but from now on, we are going to separate 'set' and 'enable' feature.
+ *  - set : net_os_rxfilter_add_remove() -> dhd_set_packet_filter() -> dhd_pktfilter_offload_set()
+ *  - enable : net_os_enable_packet_filter() -> dhd_enable_packet_filter()
+ *                                                              -> dhd_pktfilter_offload_enable()
+ */
+int dhd_os_enable_packet_filter(dhd_pub_t *dhdp, int val)
+
+{
+	int ret = 0;
+
+	/* Packet filtering is set only if we still in early-suspend and
+	 * we need either to turn it ON or turn it OFF
+	 * We can always turn it OFF in case of early-suspend, but we turn it
+	 * back ON only if suspend_disable_flag was not set
+	*/
+	if (dhdp && dhdp->up) {
+		if (dhdp->in_suspend) {
+			if (!val || (val && !dhdp->suspend_disable_flag))
+				dhd_enable_packet_filter(val, dhdp);
+		}
+	}
+	return ret;
+}
+
+/* function to enable/disable packet for Network device */
+int net_os_enable_packet_filter(struct net_device *dev, int val)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+
+	DHD_INFO(("%s: val = %d\n", __FUNCTION__, val));
+	return dhd_os_enable_packet_filter(&dhd->pub, val);
+}
+#endif /* PKT_FILTER_SUPPORT */
+
+int
+dhd_dev_init_ioctl(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	int ret;
+
+	if ((ret = dhd_sync_with_dongle(&dhd->pub)) < 0)
+		goto done;
+
+done:
+	return ret;
+}
+
+int
+dhd_dev_get_feature_set(struct net_device *dev)
+{
+	dhd_info_t *ptr = *(dhd_info_t **)netdev_priv(dev);
+	dhd_pub_t *dhd = (&ptr->pub);
+	int feature_set = 0;
+
+	/* tdls capability or othters can be missed because of initialization */
+	if (dhd_get_fw_capabilities(dhd) < 0) {
+		DHD_ERROR(("Capabilities rechecking fail\n"));
+	}
+
+	if (FW_SUPPORTED(dhd, sta))
+		feature_set |= WIFI_FEATURE_INFRA;
+	if (FW_SUPPORTED(dhd, dualband))
+		feature_set |= WIFI_FEATURE_INFRA_5G;
+	if (FW_SUPPORTED(dhd, p2p))
+		feature_set |= WIFI_FEATURE_P2P;
+	if (dhd->op_mode & DHD_FLAG_HOSTAP_MODE)
+		feature_set |= WIFI_FEATURE_SOFT_AP;
+	if (FW_SUPPORTED(dhd, tdls))
+		feature_set |= WIFI_FEATURE_TDLS;
+	if (FW_SUPPORTED(dhd, vsdb))
+		feature_set |= WIFI_FEATURE_TDLS_OFFCHANNEL;
+	if (FW_SUPPORTED(dhd, nan)) {
+		feature_set |= WIFI_FEATURE_NAN;
+		/* NAN is essentail for d2d rtt */
+		if (FW_SUPPORTED(dhd, rttd2d))
+			feature_set |= WIFI_FEATURE_D2D_RTT;
+	}
+#ifdef RTT_SUPPORT
+	if (dhd->rtt_supported) {
+		feature_set |= WIFI_FEATURE_D2D_RTT;
+		feature_set |= WIFI_FEATURE_D2AP_RTT;
+	}
+#endif /* RTT_SUPPORT */
+#ifdef LINKSTAT_SUPPORT
+	feature_set |= WIFI_FEATURE_LINKSTAT;
+#endif /* LINKSTAT_SUPPORT */
+
+#if defined(PNO_SUPPORT) && !defined(DISABLE_ANDROID_PNO)
+	if (dhd_is_pno_supported(dhd)) {
+		feature_set |= WIFI_FEATURE_PNO;
+#ifdef BATCH_SCAN
+		/* Deprecated */
+		feature_set |= WIFI_FEATURE_BATCH_SCAN;
+#endif /* BATCH_SCAN */
+#ifdef GSCAN_SUPPORT
+		/* terence 20171115: remove to get GTS PASS
+		 * com.google.android.gts.wifi.WifiHostTest#testWifiScannerBatchTimestamp
+		 */
+#ifndef DISABLE_ANDROID_GSCAN
+//		feature_set |= WIFI_FEATURE_GSCAN;
+#endif /* DISABLE_ANDROID_GSCAN */
+//		feature_set |= WIFI_FEATURE_HAL_EPNO;
+#endif /* GSCAN_SUPPORT */
+	}
+#endif /* PNO_SUPPORT && !DISABLE_ANDROID_PNO */
+#ifdef RSSI_MONITOR_SUPPORT
+	if (FW_SUPPORTED(dhd, rssi_mon)) {
+		feature_set |= WIFI_FEATURE_RSSI_MONITOR;
+	}
+#endif /* RSSI_MONITOR_SUPPORT */
+#ifdef WL11U
+	feature_set |= WIFI_FEATURE_HOTSPOT;
+#endif /* WL11U */
+#ifdef KEEP_ALIVE
+	feature_set |= WIFI_FEATURE_MKEEP_ALIVE;
+#endif /* KEEP_ALIVE */
+#ifdef NDO_CONFIG_SUPPORT
+	feature_set |= WIFI_FEATURE_CONFIG_NDO;
+#endif /* NDO_CONFIG_SUPPORT */
+#ifdef SUPPORT_RANDOM_MAC_SCAN
+	feature_set |= WIFI_FEATURE_SCAN_RAND;
+#endif /* SUPPORT_RANDOM_MAC_SCAN */
+#ifdef FILTER_IE
+	if (FW_SUPPORTED(dhd, fie)) {
+		feature_set |= WIFI_FEATURE_FILTER_IE;
+	}
+#endif /* FILTER_IE */
+#ifdef ROAMEXP_SUPPORT
+	 feature_set |= WIFI_FEATURE_CONTROL_ROAMING;
+#endif /* ROAMEXP_SUPPORT */
+#ifdef WL_P2P_RAND
+	feature_set |= WIFI_FEATURE_P2P_RAND_MAC;
+#endif /* WL_P2P_RAND */
+#ifdef WL_SAR_TX_POWER
+	feature_set |= WIFI_FEATURE_SET_TX_POWER_LIMIT;
+	feature_set |= WIFI_FEATURE_USE_BODY_HEAD_SAR;
+#endif /* WL_SAR_TX_POWER */
+#ifdef WL_STATIC_IF
+	feature_set |= WIFI_FEATURE_AP_STA;
+#endif /* WL_STATIC_IF */
+#ifdef WL_LATENCY_MODE
+	feature_set |= WIFI_FEATURE_SET_LATENCY_MODE;
+#endif /* WL_LATENCY_MODE */
+	return feature_set;
+}
+
+int
+dhd_dev_indoor_cfg(struct net_device *dev, u8 enable)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	int ret = 0, ifidx = 0;
+	uint indoor = enable;
+
+	ifidx = dhd_net2idx(dhd, dev);
+	if (ifidx == DHD_BAD_IF) {
+		DHD_ERROR(("%s: bad ifidx\n", __FUNCTION__));
+		ret = -ENODEV;
+		goto exit;
+	}
+
+	ret = dhd_wl_ioctl_set_intiovar(dhdp, "indoor", indoor, WLC_SET_VAR,
+			TRUE, ifidx);
+	if (ret != BCME_OK) {
+		DHD_ERROR(("%s: Unable to set INDOOR %d, ret=%d\n", __FUNCTION__, indoor, ret));
+	}
+
+exit:
+	return ret;
+}
+
+int
+dhd_dev_get_feature_set_matrix(struct net_device *dev, int num)
+{
+	int feature_set_full;
+	int ret = 0;
+
+	feature_set_full = dhd_dev_get_feature_set(dev);
+
+	/* Common feature set for all interface */
+	ret = (feature_set_full & WIFI_FEATURE_INFRA) |
+		(feature_set_full & WIFI_FEATURE_INFRA_5G) |
+		(feature_set_full & WIFI_FEATURE_D2D_RTT) |
+		(feature_set_full & WIFI_FEATURE_D2AP_RTT) |
+		(feature_set_full & WIFI_FEATURE_RSSI_MONITOR) |
+		(feature_set_full & WIFI_FEATURE_EPR);
+
+	/* Specific feature group for each interface */
+	switch (num) {
+	case 0:
+		ret |= (feature_set_full & WIFI_FEATURE_P2P) |
+			/* Not supported yet */
+			/* (feature_set_full & WIFI_FEATURE_NAN) | */
+			(feature_set_full & WIFI_FEATURE_TDLS) |
+			(feature_set_full & WIFI_FEATURE_PNO) |
+			(feature_set_full & WIFI_FEATURE_HAL_EPNO) |
+			(feature_set_full & WIFI_FEATURE_BATCH_SCAN) |
+			(feature_set_full & WIFI_FEATURE_GSCAN) |
+			(feature_set_full & WIFI_FEATURE_HOTSPOT) |
+			(feature_set_full & WIFI_FEATURE_ADDITIONAL_STA);
+		break;
+
+	case 1:
+		ret |= (feature_set_full & WIFI_FEATURE_P2P);
+		/* Not yet verified NAN with P2P */
+		/* (feature_set_full & WIFI_FEATURE_NAN) | */
+		break;
+
+	case 2:
+		ret |= (feature_set_full & WIFI_FEATURE_NAN) |
+			(feature_set_full & WIFI_FEATURE_TDLS) |
+			(feature_set_full & WIFI_FEATURE_TDLS_OFFCHANNEL);
+		break;
+
+	default:
+		ret = WIFI_FEATURE_INVALID;
+		DHD_ERROR(("%s: Out of index(%d) for get feature set\n", __FUNCTION__, num));
+		break;
+	}
+
+	return ret;
+}
+
+#if defined(CUSTOM_FORCE_NODFS_FLAG) && defined(CUSTOM_COUNTRY_CODE)
+int
+dhd_dev_set_nodfs(struct net_device *dev, u32 nodfs)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	bool force_ccode_change = FALSE;
+	UNUSED_PARAMETER(force_ccode_change);
+
+	if (nodfs && !(dhd->pub.dhd_cflags & WLAN_PLAT_NODFS_FLAG)) {
+		dhd->pub.dhd_cflags |= WLAN_PLAT_NODFS_FLAG;
+		force_ccode_change = TRUE;
+	} else if (!nodfs && (dhd->pub.dhd_cflags & WLAN_PLAT_NODFS_FLAG)) {
+		dhd->pub.dhd_cflags &= ~WLAN_PLAT_NODFS_FLAG;
+		force_ccode_change = TRUE;
+	}
+
+#ifdef SKIP_CCODE_FOR_SAME_DFS_FLAG
+	if (force_ccode_change == FALSE) {
+		DHD_ERROR(("No change in dfs flags. dfs:%d\n", !!nodfs));
+		return 0;
+	}
+#endif /* SKIP_CCODE_FOR_SAME_DFS_FLAG */
+
+	DHD_ERROR(("Force country change. dfs:%d \n", !!nodfs));
+	dhd->pub.force_country_change = TRUE;
+	return 0;
+}
+#endif /* CUSTOM_FORCE_NODFS_FLAG && CUSTOM_COUNTRY_CODE */
+
+#ifdef NDO_CONFIG_SUPPORT
+int
+dhd_dev_ndo_cfg(struct net_device *dev, u8 enable)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	int ret = 0;
+
+	if (enable) {
+		/* enable ND offload feature (will be enabled in FW on suspend) */
+		dhdp->ndo_enable = TRUE;
+
+		/* Update changes of anycast address & DAD failed address */
+		ret = dhd_dev_ndo_update_inet6addr(dev);
+		if ((ret < 0) && (ret != BCME_NORESOURCE)) {
+			DHD_ERROR(("%s: failed to update host ip addr: %d\n", __FUNCTION__, ret));
+			return ret;
+		}
+	} else {
+		/* disable ND offload feature */
+		dhdp->ndo_enable = FALSE;
+
+		/* disable ND offload in FW */
+		ret = dhd_ndo_enable(dhdp, FALSE);
+		if (ret < 0) {
+			DHD_ERROR(("%s: failed to disable NDO: %d\n", __FUNCTION__, ret));
+		}
+	}
+	return ret;
+}
+
+static int
+dhd_dev_ndo_get_valid_inet6addr_count(struct inet6_dev *inet6)
+{
+	struct inet6_ifaddr *ifa;
+	struct ifacaddr6 *acaddr = NULL;
+	int addr_count = 0;
+
+	/* lock */
+	read_lock_bh(&inet6->lock);
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	/* Count valid unicast address */
+	list_for_each_entry(ifa, &inet6->addr_list, if_list) {
+		GCC_DIAGNOSTIC_POP();
+		if ((ifa->flags & IFA_F_DADFAILED) == 0) {
+			addr_count++;
+		}
+	}
+
+	/* Count anycast address */
+	acaddr = inet6->ac_list;
+	while (acaddr) {
+		addr_count++;
+		acaddr = acaddr->aca_next;
+	}
+
+	/* unlock */
+	read_unlock_bh(&inet6->lock);
+
+	return addr_count;
+}
+
+int
+dhd_dev_ndo_update_inet6addr(struct net_device *dev)
+{
+	dhd_info_t *dhd;
+	dhd_pub_t *dhdp;
+	struct inet6_dev *inet6;
+	struct inet6_ifaddr *ifa;
+	struct ifacaddr6 *acaddr = NULL;
+	struct in6_addr *ipv6_addr = NULL;
+	int cnt, i;
+	int ret = BCME_OK;
+
+	/*
+	 * this function evaulates host ip address in struct inet6_dev
+	 * unicast addr in inet6_dev->addr_list
+	 * anycast addr in inet6_dev->ac_list
+	 * while evaluating inet6_dev, read_lock_bh() is required to prevent
+	 * access on null(freed) pointer.
+	 */
+
+	if (dev) {
+		inet6 = dev->ip6_ptr;
+		if (!inet6) {
+			DHD_ERROR(("%s: Invalid inet6_dev\n", __FUNCTION__));
+			return BCME_ERROR;
+		}
+
+		dhd = DHD_DEV_INFO(dev);
+		if (!dhd) {
+			DHD_ERROR(("%s: Invalid dhd_info\n", __FUNCTION__));
+			return BCME_ERROR;
+		}
+		dhdp = &dhd->pub;
+
+		if (dhd_net2idx(dhd, dev) != 0) {
+			DHD_ERROR(("%s: Not primary interface\n", __FUNCTION__));
+			return BCME_ERROR;
+		}
+	} else {
+		DHD_ERROR(("%s: Invalid net_device\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	/* Check host IP overflow */
+	cnt = dhd_dev_ndo_get_valid_inet6addr_count(inet6);
+	if (cnt > dhdp->ndo_max_host_ip) {
+		if (!dhdp->ndo_host_ip_overflow) {
+			dhdp->ndo_host_ip_overflow = TRUE;
+			/* Disable ND offload in FW */
+			DHD_INFO(("%s: Host IP overflow, disable NDO\n", __FUNCTION__));
+			ret = dhd_ndo_enable(dhdp, FALSE);
+		}
+
+		return ret;
+	}
+
+	/*
+	 * Allocate ipv6 addr buffer to store addresses to be added/removed.
+	 * driver need to lock inet6_dev while accessing structure. but, driver
+	 * cannot use ioctl while inet6_dev locked since it requires scheduling
+	 * hence, copy addresses to the buffer and do ioctl after unlock.
+	 */
+	ipv6_addr = (struct in6_addr *)MALLOC(dhdp->osh,
+		sizeof(struct in6_addr) * dhdp->ndo_max_host_ip);
+	if (!ipv6_addr) {
+		DHD_ERROR(("%s: failed to alloc ipv6 addr buffer\n", __FUNCTION__));
+		return BCME_NOMEM;
+	}
+
+	/* Find DAD failed unicast address to be removed */
+	cnt = 0;
+	read_lock_bh(&inet6->lock);
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	list_for_each_entry(ifa, &inet6->addr_list, if_list) {
+		GCC_DIAGNOSTIC_POP();
+		/* DAD failed unicast address */
+		if ((ifa->flags & IFA_F_DADFAILED) &&
+			(cnt < dhdp->ndo_max_host_ip)) {
+				memcpy(&ipv6_addr[cnt], &ifa->addr, sizeof(struct in6_addr));
+				cnt++;
+		}
+	}
+	read_unlock_bh(&inet6->lock);
+
+	/* Remove DAD failed unicast address */
+	for (i = 0; i < cnt; i++) {
+		DHD_INFO(("%s: Remove DAD failed addr\n", __FUNCTION__));
+		ret = dhd_ndo_remove_ip_by_addr(dhdp, (char *)&ipv6_addr[i], 0);
+		if (ret < 0) {
+			goto done;
+		}
+	}
+
+	/* Remove all anycast address */
+	ret = dhd_ndo_remove_ip_by_type(dhdp, WL_ND_IPV6_ADDR_TYPE_ANYCAST, 0);
+	if (ret < 0) {
+		goto done;
+	}
+
+	/*
+	 * if ND offload was disabled due to host ip overflow,
+	 * attempt to add valid unicast address.
+	 */
+	if (dhdp->ndo_host_ip_overflow) {
+		/* Find valid unicast address */
+		cnt = 0;
+		read_lock_bh(&inet6->lock);
+		GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+		list_for_each_entry(ifa, &inet6->addr_list, if_list) {
+			GCC_DIAGNOSTIC_POP();
+			/* valid unicast address */
+			if (!(ifa->flags & IFA_F_DADFAILED) &&
+				(cnt < dhdp->ndo_max_host_ip)) {
+					memcpy(&ipv6_addr[cnt], &ifa->addr,
+						sizeof(struct in6_addr));
+					cnt++;
+			}
+		}
+		read_unlock_bh(&inet6->lock);
+
+		/* Add valid unicast address */
+		for (i = 0; i < cnt; i++) {
+			ret = dhd_ndo_add_ip_with_type(dhdp,
+				(char *)&ipv6_addr[i], WL_ND_IPV6_ADDR_TYPE_UNICAST, 0);
+			if (ret < 0) {
+				goto done;
+			}
+		}
+	}
+
+	/* Find anycast address */
+	cnt = 0;
+	read_lock_bh(&inet6->lock);
+	acaddr = inet6->ac_list;
+	while (acaddr) {
+		if (cnt < dhdp->ndo_max_host_ip) {
+			memcpy(&ipv6_addr[cnt], &acaddr->aca_addr, sizeof(struct in6_addr));
+			cnt++;
+		}
+		acaddr = acaddr->aca_next;
+	}
+	read_unlock_bh(&inet6->lock);
+
+	/* Add anycast address */
+	for (i = 0; i < cnt; i++) {
+		ret = dhd_ndo_add_ip_with_type(dhdp,
+			(char *)&ipv6_addr[i], WL_ND_IPV6_ADDR_TYPE_ANYCAST, 0);
+		if (ret < 0) {
+			goto done;
+		}
+	}
+
+	/* Now All host IP addr were added successfully */
+	if (dhdp->ndo_host_ip_overflow) {
+		dhdp->ndo_host_ip_overflow = FALSE;
+		if (dhdp->in_suspend) {
+			/* drvier is in (early) suspend state, need to enable ND offload in FW */
+			DHD_INFO(("%s: enable NDO\n", __FUNCTION__));
+			ret = dhd_ndo_enable(dhdp, TRUE);
+		}
+	}
+
+done:
+	if (ipv6_addr) {
+		MFREE(dhdp->osh, ipv6_addr, sizeof(struct in6_addr) * dhdp->ndo_max_host_ip);
+	}
+
+	return ret;
+}
+
+#endif /* NDO_CONFIG_SUPPORT */
+
+#ifdef PNO_SUPPORT
+/* Linux wrapper to call common dhd_pno_stop_for_ssid */
+int
+dhd_dev_pno_stop_for_ssid(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+
+	return (dhd_pno_stop_for_ssid(&dhd->pub));
+}
+/* Linux wrapper to call common dhd_pno_set_for_ssid */
+int
+dhd_dev_pno_set_for_ssid(struct net_device *dev, wlc_ssid_ext_t* ssids_local, int nssid,
+	uint16  scan_fr, int pno_repeat, int pno_freq_expo_max, uint16 *channel_list, int nchan)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+
+	return (dhd_pno_set_for_ssid(&dhd->pub, ssids_local, nssid, scan_fr,
+		pno_repeat, pno_freq_expo_max, channel_list, nchan));
+}
+
+/* Linux wrapper to call common dhd_pno_enable */
+int
+dhd_dev_pno_enable(struct net_device *dev, int enable)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+
+	return (dhd_pno_enable(&dhd->pub, enable));
+}
+
+/* Linux wrapper to call common dhd_pno_set_for_hotlist */
+int
+dhd_dev_pno_set_for_hotlist(struct net_device *dev, wl_pfn_bssid_t *p_pfn_bssid,
+	struct dhd_pno_hotlist_params *hotlist_params)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	return (dhd_pno_set_for_hotlist(&dhd->pub, p_pfn_bssid, hotlist_params));
+}
+/* Linux wrapper to call common dhd_dev_pno_stop_for_batch */
+int
+dhd_dev_pno_stop_for_batch(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	return (dhd_pno_stop_for_batch(&dhd->pub));
+}
+
+/* Linux wrapper to call common dhd_dev_pno_set_for_batch */
+int
+dhd_dev_pno_set_for_batch(struct net_device *dev, struct dhd_pno_batch_params *batch_params)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	return (dhd_pno_set_for_batch(&dhd->pub, batch_params));
+}
+
+/* Linux wrapper to call common dhd_dev_pno_get_for_batch */
+int
+dhd_dev_pno_get_for_batch(struct net_device *dev, char *buf, int bufsize)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	return (dhd_pno_get_for_batch(&dhd->pub, buf, bufsize, PNO_STATUS_NORMAL));
+}
+#endif /* PNO_SUPPORT */
+
+#if defined(PNO_SUPPORT)
+#ifdef GSCAN_SUPPORT
+bool
+dhd_dev_is_legacy_pno_enabled(struct net_device *dev)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_is_legacy_pno_enabled(&dhd->pub));
+}
+
+int
+dhd_dev_set_epno(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	if (!dhd) {
+		return BCME_ERROR;
+	}
+	return dhd_pno_set_epno(&dhd->pub);
+}
+int
+dhd_dev_flush_fw_epno(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	if (!dhd) {
+		return BCME_ERROR;
+	}
+	return dhd_pno_flush_fw_epno(&dhd->pub);
+}
+
+/* Linux wrapper to call common dhd_pno_set_cfg_gscan */
+int
+dhd_dev_pno_set_cfg_gscan(struct net_device *dev, dhd_pno_gscan_cmd_cfg_t type,
+ void *buf, bool flush)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_pno_set_cfg_gscan(&dhd->pub, type, buf, flush));
+}
+
+/* Linux wrapper to call common dhd_pno_get_gscan */
+void *
+dhd_dev_pno_get_gscan(struct net_device *dev, dhd_pno_gscan_cmd_cfg_t type,
+                      void *info, uint32 *len)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_pno_get_gscan(&dhd->pub, type, info, len));
+}
+
+/* Linux wrapper to call common dhd_wait_batch_results_complete */
+int
+dhd_dev_wait_batch_results_complete(struct net_device *dev)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_wait_batch_results_complete(&dhd->pub));
+}
+
+/* Linux wrapper to call common dhd_pno_lock_batch_results */
+int
+dhd_dev_pno_lock_access_batch_results(struct net_device *dev)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_pno_lock_batch_results(&dhd->pub));
+}
+/* Linux wrapper to call common dhd_pno_unlock_batch_results */
+void
+dhd_dev_pno_unlock_access_batch_results(struct net_device *dev)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_pno_unlock_batch_results(&dhd->pub));
+}
+
+/* Linux wrapper to call common dhd_pno_initiate_gscan_request */
+int
+dhd_dev_pno_run_gscan(struct net_device *dev, bool run, bool flush)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_pno_initiate_gscan_request(&dhd->pub, run, flush));
+}
+
+/* Linux wrapper to call common dhd_pno_enable_full_scan_result */
+int
+dhd_dev_pno_enable_full_scan_result(struct net_device *dev, bool real_time_flag)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_pno_enable_full_scan_result(&dhd->pub, real_time_flag));
+}
+
+/* Linux wrapper to call common dhd_handle_hotlist_scan_evt */
+void *
+dhd_dev_hotlist_scan_event(struct net_device *dev,
+      const void  *data, int *send_evt_bytes, hotlist_type_t type, u32 *buf_len)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_handle_hotlist_scan_evt(&dhd->pub, data, send_evt_bytes, type, buf_len));
+}
+
+/* Linux wrapper to call common dhd_process_full_gscan_result */
+void *
+dhd_dev_process_full_gscan_result(struct net_device *dev,
+const void  *data, uint32 len, int *send_evt_bytes)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_process_full_gscan_result(&dhd->pub, data, len, send_evt_bytes));
+}
+
+void
+dhd_dev_gscan_hotlist_cache_cleanup(struct net_device *dev, hotlist_type_t type)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	dhd_gscan_hotlist_cache_cleanup(&dhd->pub, type);
+
+	return;
+}
+
+int
+dhd_dev_gscan_batch_cache_cleanup(struct net_device *dev)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_gscan_batch_cache_cleanup(&dhd->pub));
+}
+
+/* Linux wrapper to call common dhd_retreive_batch_scan_results */
+int
+dhd_dev_retrieve_batch_scan(struct net_device *dev)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_retreive_batch_scan_results(&dhd->pub));
+}
+
+/* Linux wrapper to call common dhd_pno_process_epno_result */
+void * dhd_dev_process_epno_result(struct net_device *dev,
+	const void  *data, uint32 event, int *send_evt_bytes)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_pno_process_epno_result(&dhd->pub, data, event, send_evt_bytes));
+}
+
+int
+dhd_dev_set_lazy_roam_cfg(struct net_device *dev,
+             wlc_roam_exp_params_t *roam_param)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	wl_roam_exp_cfg_t roam_exp_cfg;
+	int err;
+
+	if (!roam_param) {
+		return BCME_BADARG;
+	}
+
+	DHD_INFO(("a_band_boost_thr %d a_band_penalty_thr %d\n",
+	      roam_param->a_band_boost_threshold, roam_param->a_band_penalty_threshold));
+	DHD_INFO(("a_band_boost_factor %d a_band_penalty_factor %d cur_bssid_boost %d\n",
+	      roam_param->a_band_boost_factor, roam_param->a_band_penalty_factor,
+	      roam_param->cur_bssid_boost));
+	DHD_INFO(("alert_roam_trigger_thr %d a_band_max_boost %d\n",
+	      roam_param->alert_roam_trigger_threshold, roam_param->a_band_max_boost));
+
+	memcpy(&roam_exp_cfg.params, roam_param, sizeof(*roam_param));
+	roam_exp_cfg.version = ROAM_EXP_CFG_VERSION_1;
+	roam_exp_cfg.flags = ROAM_EXP_CFG_PRESENT;
+	if (dhd->pub.lazy_roam_enable) {
+		roam_exp_cfg.flags |= ROAM_EXP_ENABLE_FLAG;
+	}
+	err = dhd_iovar(&dhd->pub, 0, "roam_exp_params",
+			(char *)&roam_exp_cfg, sizeof(roam_exp_cfg), NULL, 0,
+			TRUE);
+	if (err < 0) {
+		DHD_ERROR(("%s : Failed to execute roam_exp_params %d\n", __FUNCTION__, err));
+	}
+	return err;
+}
+
+int
+dhd_dev_lazy_roam_enable(struct net_device *dev, uint32 enable)
+{
+	int err;
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	wl_roam_exp_cfg_t roam_exp_cfg;
+
+	memset(&roam_exp_cfg, 0, sizeof(roam_exp_cfg));
+	roam_exp_cfg.version = ROAM_EXP_CFG_VERSION_1;
+	if (enable) {
+		roam_exp_cfg.flags = ROAM_EXP_ENABLE_FLAG;
+	}
+
+	err = dhd_iovar(&dhd->pub, 0, "roam_exp_params",
+			(char *)&roam_exp_cfg, sizeof(roam_exp_cfg), NULL, 0,
+			TRUE);
+	if (err < 0) {
+		DHD_ERROR(("%s : Failed to execute roam_exp_params %d\n", __FUNCTION__, err));
+	} else {
+		dhd->pub.lazy_roam_enable = (enable != 0);
+	}
+	return err;
+}
+
+int
+dhd_dev_set_lazy_roam_bssid_pref(struct net_device *dev,
+       wl_bssid_pref_cfg_t *bssid_pref, uint32 flush)
+{
+	int err;
+	uint len;
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	bssid_pref->version = BSSID_PREF_LIST_VERSION_1;
+	/* By default programming bssid pref flushes out old values */
+	bssid_pref->flags = (flush && !bssid_pref->count) ? ROAM_EXP_CLEAR_BSSID_PREF: 0;
+	len = sizeof(wl_bssid_pref_cfg_t);
+	if (bssid_pref->count) {
+		len += (bssid_pref->count - 1) * sizeof(wl_bssid_pref_list_t);
+	}
+	err = dhd_iovar(&dhd->pub, 0, "roam_exp_bssid_pref",
+			(char *)bssid_pref, len, NULL, 0, TRUE);
+	if (err != BCME_OK) {
+		DHD_ERROR(("%s : Failed to execute roam_exp_bssid_pref %d\n", __FUNCTION__, err));
+	}
+	return err;
+}
+#endif /* GSCAN_SUPPORT */
+
+#if defined(GSCAN_SUPPORT) || defined(ROAMEXP_SUPPORT)
+int
+dhd_dev_set_blacklist_bssid(struct net_device *dev, maclist_t *blacklist,
+    uint32 len, uint32 flush)
+{
+	int err;
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	int macmode;
+
+	if (blacklist) {
+		err = dhd_wl_ioctl_cmd(&(dhd->pub), WLC_SET_MACLIST, (char *)blacklist,
+				len, TRUE, 0);
+		if (err != BCME_OK) {
+			DHD_ERROR(("%s : WLC_SET_MACLIST failed %d\n", __FUNCTION__, err));
+			return err;
+		}
+	}
+	/* By default programming blacklist flushes out old values */
+	macmode = (flush && !blacklist) ? WLC_MACMODE_DISABLED : WLC_MACMODE_DENY;
+	err = dhd_wl_ioctl_cmd(&(dhd->pub), WLC_SET_MACMODE, (char *)&macmode,
+	              sizeof(macmode), TRUE, 0);
+	if (err != BCME_OK) {
+		DHD_ERROR(("%s : WLC_SET_MACMODE failed %d\n", __FUNCTION__, err));
+	}
+	return err;
+}
+
+int
+dhd_dev_set_whitelist_ssid(struct net_device *dev, wl_ssid_whitelist_t *ssid_whitelist,
+    uint32 len, uint32 flush)
+{
+	int err;
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	wl_ssid_whitelist_t whitelist_ssid_flush;
+
+	if (!ssid_whitelist) {
+		if (flush) {
+			ssid_whitelist = &whitelist_ssid_flush;
+			ssid_whitelist->ssid_count = 0;
+		} else {
+			DHD_ERROR(("%s : Nothing to do here\n", __FUNCTION__));
+			return BCME_BADARG;
+		}
+	}
+	ssid_whitelist->version = SSID_WHITELIST_VERSION_1;
+	ssid_whitelist->flags = flush ? ROAM_EXP_CLEAR_SSID_WHITELIST : 0;
+	err = dhd_iovar(&dhd->pub, 0, "roam_exp_ssid_whitelist", (char *)ssid_whitelist, len, NULL,
+			0, TRUE);
+	if (err != BCME_OK) {
+		if (err == BCME_UNSUPPORTED) {
+			DHD_ERROR(("%s : roam_exp_bssid_pref, UNSUPPORTED \n", __FUNCTION__));
+		} else {
+			DHD_ERROR(("%s : Failed to execute roam_exp_bssid_pref %d\n",
+				__FUNCTION__, err));
+		}
+	}
+	return err;
+}
+#endif /* GSCAN_SUPPORT || ROAMEXP_SUPPORT */
+#endif /* defined(OEM_ANDROID) && defined(PNO_SUPPORT) */
+
+#ifdef RSSI_MONITOR_SUPPORT
+int
+dhd_dev_set_rssi_monitor_cfg(struct net_device *dev, int start,
+             int8 max_rssi, int8 min_rssi)
+{
+	int err;
+	wl_rssi_monitor_cfg_t rssi_monitor;
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	rssi_monitor.version = RSSI_MONITOR_VERSION_1;
+	rssi_monitor.max_rssi = max_rssi;
+	rssi_monitor.min_rssi = min_rssi;
+	rssi_monitor.flags = start ? 0: RSSI_MONITOR_STOP;
+	err = dhd_iovar(&dhd->pub, 0, "rssi_monitor", (char *)&rssi_monitor, sizeof(rssi_monitor),
+			NULL, 0, TRUE);
+	if (err < 0 && err != BCME_UNSUPPORTED) {
+		DHD_ERROR(("%s : Failed to execute rssi_monitor %d\n", __FUNCTION__, err));
+	}
+	return err;
+}
+#endif /* RSSI_MONITOR_SUPPORT */
+
+#ifdef DHDTCPACK_SUPPRESS
+int
+dhd_dev_set_tcpack_sup_mode_cfg(struct net_device *dev, uint8 enable)
+{
+	int err;
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	err = dhd_tcpack_suppress_set(&dhd->pub, enable);
+	if (err != BCME_OK) {
+		DHD_ERROR(("%s : Failed to set tcpack_suppress mode: %d\n", __FUNCTION__, err));
+	}
+	return err;
+}
+#endif /* DHDTCPACK_SUPPRESS */
+
+int
+dhd_dev_cfg_rand_mac_oui(struct net_device *dev, uint8 *oui)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	dhd_pub_t *dhdp = &dhd->pub;
+
+	if (!dhdp || !oui) {
+		DHD_ERROR(("NULL POINTER : %s\n",
+			__FUNCTION__));
+		return BCME_ERROR;
+	}
+	if (ETHER_ISMULTI(oui)) {
+		DHD_ERROR(("Expected unicast OUI\n"));
+		return BCME_ERROR;
+	} else {
+		uint8 *rand_mac_oui = dhdp->rand_mac_oui;
+		memcpy(rand_mac_oui, oui, DOT11_OUI_LEN);
+		DHD_ERROR(("Random MAC OUI to be used - "MACOUIDBG"\n",
+			MACOUI2STRDBG(rand_mac_oui)));
+	}
+	return BCME_OK;
+}
+
+int
+dhd_set_rand_mac_oui(dhd_pub_t *dhd)
+{
+	int err;
+	wl_pfn_macaddr_cfg_t wl_cfg;
+	uint8 *rand_mac_oui = dhd->rand_mac_oui;
+
+	memset(&wl_cfg.macaddr, 0, ETHER_ADDR_LEN);
+	memcpy(&wl_cfg.macaddr, rand_mac_oui, DOT11_OUI_LEN);
+	wl_cfg.version = WL_PFN_MACADDR_CFG_VER;
+	if (ETHER_ISNULLADDR(&wl_cfg.macaddr)) {
+		wl_cfg.flags = 0;
+	} else {
+		wl_cfg.flags = (WL_PFN_MAC_OUI_ONLY_MASK | WL_PFN_SET_MAC_UNASSOC_MASK);
+	}
+
+	DHD_ERROR(("Setting rand mac oui to FW - "MACOUIDBG"\n",
+		MACOUI2STRDBG(rand_mac_oui)));
+
+	err = dhd_iovar(dhd, 0, "pfn_macaddr", (char *)&wl_cfg, sizeof(wl_cfg), NULL, 0, TRUE);
+	if (err < 0) {
+		DHD_ERROR(("%s : failed to execute pfn_macaddr %d\n", __FUNCTION__, err));
+	}
+	return err;
+}
+
+#if defined(RTT_SUPPORT) && defined(WL_CFG80211)
+/* Linux wrapper to call common dhd_pno_set_cfg_gscan */
+int
+dhd_dev_rtt_set_cfg(struct net_device *dev, void *buf)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_rtt_set_cfg(&dhd->pub, buf));
+}
+
+int
+dhd_dev_rtt_cancel_cfg(struct net_device *dev, struct ether_addr *mac_list, int mac_cnt)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_rtt_stop(&dhd->pub, mac_list, mac_cnt));
+}
+
+int
+dhd_dev_rtt_register_noti_callback(struct net_device *dev, void *ctx, dhd_rtt_compl_noti_fn noti_fn)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_rtt_register_noti_callback(&dhd->pub, ctx, noti_fn));
+}
+
+int
+dhd_dev_rtt_unregister_noti_callback(struct net_device *dev, dhd_rtt_compl_noti_fn noti_fn)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_rtt_unregister_noti_callback(&dhd->pub, noti_fn));
+}
+
+int
+dhd_dev_rtt_capability(struct net_device *dev, rtt_capabilities_t *capa)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+
+	return (dhd_rtt_capability(&dhd->pub, capa));
+}
+
+int
+dhd_dev_rtt_avail_channel(struct net_device *dev, wifi_channel_info *channel_info)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	return (dhd_rtt_avail_channel(&dhd->pub, channel_info));
+}
+
+int
+dhd_dev_rtt_enable_responder(struct net_device *dev, wifi_channel_info *channel_info)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	return (dhd_rtt_enable_responder(&dhd->pub, channel_info));
+}
+
+int dhd_dev_rtt_cancel_responder(struct net_device *dev)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	return (dhd_rtt_cancel_responder(&dhd->pub));
+}
+
+#endif /* RTT_SUPPORT */
+
+#if defined(APF)
+static void _dhd_apf_lock_local(dhd_info_t *dhd)
+{
+	if (dhd) {
+		mutex_lock(&dhd->dhd_apf_mutex);
+	}
+}
+
+static void _dhd_apf_unlock_local(dhd_info_t *dhd)
+{
+	if (dhd) {
+		mutex_unlock(&dhd->dhd_apf_mutex);
+	}
+}
+
+#define APF_PKT_DLOAD "apf_pkt_dload"
+#define APF_PKT_LOAD_ENAB(ndev)		is_apf_pkt_load_supported(ndev)
+bool is_apf_pkt_load_supported(struct net_device *ndev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(ndev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	bool ret = FALSE;
+	int result, ifidx;
+	char cmd[] = APF_PKT_DLOAD;
+
+	ifidx = dhd_net2idx(dhd, ndev);
+	if (ifidx == DHD_BAD_IF) {
+		DHD_ERROR(("%s: bad ifidx\n", __FUNCTION__));
+		goto exit;
+	}
+
+	result = dhd_wl_ioctl_cmd(dhdp, WLC_SET_VAR, cmd, (u32)sizeof(cmd), TRUE, ifidx);
+	if (result != BCME_UNSUPPORTED)
+		ret = TRUE;
+
+exit:
+	return ret;
+}
+
+static int
+_dhd_apf_add_filter(struct net_device *ndev, uint32 filter_id, u8* program, uint32 program_len)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(ndev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	wl_pkt_filter_t * pkt_filterp;
+	wl_apf_program_t *apf_program;
+	char *buf = NULL;
+	u32 cmd_len, buf_len, max_len;
+	int ifidx, ret = BCME_OK;
+	char cmd[] = "pkt_filter_add";
+	char cmd_new[] = APF_PKT_DLOAD;
+	bool apf_pkt_load_enab = APF_PKT_LOAD_ENAB(ndev);
+
+	ifidx = dhd_net2idx(dhd, ndev);
+	if (ifidx == DHD_BAD_IF) {
+		DHD_ERROR(("%s: bad ifidx\n", __FUNCTION__));
+		ret = -ENODEV;
+		goto exit;
+	}
+	if (dhd_conf_del_pkt_filter(dhdp, filter_id))
+		goto exit;
+
+	if (apf_pkt_load_enab)
+		cmd_len = sizeof(cmd_new);
+	else
+		cmd_len = sizeof(cmd);
+
+	/* Check if the program_len is more than the expected len or if the program is NULL,
+	 * then return from here.
+	 */
+	ret = dhd_wl_ioctl_get_intiovar(dhdp, "apf_size_limit", &max_len, WLC_GET_VAR,
+		FALSE, ifidx);
+	if (unlikely(ret)) {
+		DHD_ERROR(("%s: failed to get APF size limit, ret=%d\n", __FUNCTION__, ret));
+		goto exit;
+	}
+	if ((program_len > max_len) || (program == NULL)) {
+		DHD_ERROR(("%s Invalid program_len: %d, program: %pK\n", __FUNCTION__,
+			program_len, program));
+		ret = -EINVAL;
+		goto exit;
+	}
+
+	buf_len = cmd_len + WL_PKT_FILTER_FIXED_LEN + WL_APF_PROGRAM_FIXED_LEN + program_len;
+	buf = MALLOCZ(dhdp->osh, buf_len);
+	if (unlikely(!buf)) {
+		DHD_ERROR(("%s: MALLOC failure, %d bytes\n", __FUNCTION__, buf_len));
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	if (apf_pkt_load_enab)
+		ret = memcpy_s(buf, buf_len, cmd_new, cmd_len);
+	else
+		ret = memcpy_s(buf, buf_len, cmd, cmd_len);
+	if (unlikely(ret)) {
+		goto exit;
+	}
+
+	pkt_filterp = (wl_pkt_filter_t *) (buf + cmd_len);
+	pkt_filterp->id = htod32(filter_id);
+	pkt_filterp->negate_match = htod32(FALSE);
+	pkt_filterp->type = htod32(WL_PKT_FILTER_TYPE_APF_MATCH);
+
+	apf_program = &pkt_filterp->u.apf_program;
+	apf_program->version = htod16(WL_APF_INTERNAL_VERSION);
+	apf_program->instr_len = htod16(program_len);
+	ret = memcpy_s(apf_program->instrs, program_len, program, program_len);
+	if (unlikely(ret)) {
+		goto exit;
+	}
+
+	if (apf_pkt_load_enab) {
+		ret = dhd_download_apf(dhdp, (uint8 *)buf + strlen(cmd_new) + 1,
+			buf_len - (strlen(cmd_new) + 1), cmd_new);
+	} else {
+		ret = dhd_wl_ioctl_cmd(dhdp, WLC_SET_VAR, buf, buf_len, TRUE, ifidx);
+	}
+	if (unlikely(ret)) {
+		DHD_ERROR(("%s: failed to add APF filter, id=%d, ret=%d\n", __FUNCTION__,
+			filter_id, ret));
+		goto exit;
+	}
+
+exit:
+	if (buf) {
+		MFREE(dhdp->osh, buf, buf_len);
+	}
+	return ret;
+}
+
+static int
+_dhd_apf_config_filter(struct net_device *ndev, uint32 filter_id, uint32 mode, uint32 enable)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(ndev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	wl_pkt_filter_enable_t * pkt_filterp;
+	char *buf = NULL;
+	u32 cmd_len, buf_len;
+	int ifidx, ret;
+	char cmd[] = "pkt_filter_enable";
+
+	ifidx = dhd_net2idx(dhd, ndev);
+	if (ifidx == DHD_BAD_IF) {
+		DHD_ERROR(("%s: bad ifidx\n", __FUNCTION__));
+		ret = -ENODEV;
+		goto exit;
+	}
+
+	cmd_len = sizeof(cmd);
+	buf_len = cmd_len + (u32)sizeof(*pkt_filterp);
+
+	buf = MALLOCZ(dhdp->osh, buf_len);
+	if (unlikely(!buf)) {
+		DHD_ERROR(("%s: MALLOC failure, %d bytes\n", __FUNCTION__, buf_len));
+		ret = -ENOMEM;
+		goto exit;
+	}
+
+	ret = memcpy_s(buf, buf_len, cmd, cmd_len);
+	if (unlikely(ret)) {
+		goto exit;
+	}
+
+	pkt_filterp = (wl_pkt_filter_enable_t *) (buf + cmd_len);
+	pkt_filterp->id = htod32(filter_id);
+	pkt_filterp->enable = htod32(enable);
+
+	ret = dhd_wl_ioctl_cmd(dhdp, WLC_SET_VAR, buf, buf_len, TRUE, ifidx);
+	if (unlikely(ret)) {
+		DHD_ERROR(("%s: failed to enable APF filter, id=%d, ret=%d\n", __FUNCTION__,
+			filter_id, ret));
+		goto exit;
+	}
+
+	ret = dhd_wl_ioctl_set_intiovar(dhdp, "pkt_filter_mode", dhd_master_mode, WLC_SET_VAR,
+		TRUE, ifidx);
+	if (unlikely(ret)) {
+		DHD_ERROR(("%s: failed to set APF filter mode, id=%d, ret=%d\n", __FUNCTION__,
+			filter_id, ret));
+		goto exit;
+	}
+
+exit:
+	if (buf) {
+		MFREE(dhdp->osh, buf, buf_len);
+	}
+	return ret;
+}
+
+static int
+_dhd_apf_delete_filter(struct net_device *ndev, uint32 filter_id)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(ndev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	int ifidx, ret;
+
+	ifidx = dhd_net2idx(dhd, ndev);
+	if (ifidx == DHD_BAD_IF) {
+		DHD_ERROR(("%s: bad ifidx\n", __FUNCTION__));
+		return -ENODEV;
+	}
+
+	ret = dhd_wl_ioctl_set_intiovar(dhdp, "pkt_filter_delete", htod32(filter_id),
+		WLC_SET_VAR, TRUE, ifidx);
+	if (unlikely(ret)) {
+		DHD_ERROR(("%s: failed to delete APF filter, id=%d, ret=%d\n", __FUNCTION__,
+			filter_id, ret));
+		return ret;
+	}
+
+	return ret;
+}
+
+static int
+_dhd_apf_read_filter_data(struct net_device *ndev, uint32 filter_id, u8* buf, uint32 buf_len)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(ndev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	wl_apf_program_t *apf_program;
+	u32 cmd_len, max_len;
+	int ifidx, ret;
+	char cmd[] = "apf_buf_get";
+
+	ifidx = dhd_net2idx(dhd, ndev);
+	if (ifidx == DHD_BAD_IF) {
+		DHD_ERROR(("%s: bad ifidx\n", __FUNCTION__));
+		return -ENODEV;
+	}
+
+	/* Check if the provided buffer is large enough to store the filter data or
+	 * if the buffer is NULL, then return from here.
+	 */
+	ret = dhd_wl_ioctl_get_intiovar(dhdp, "apf_size_limit", &max_len,
+		WLC_GET_VAR, FALSE, ifidx);
+	if (unlikely(ret)) {
+		DHD_ERROR(("%s: failed to get APF size limit, ret=%d\n",
+			__FUNCTION__, ret));
+		return ret;
+	}
+	if ((buf_len < (WL_APF_PROGRAM_FIXED_LEN + max_len)) || (buf == NULL)) {
+		DHD_ERROR(("%s: Invalid buf_len=%d or buf=%pK\n", __FUNCTION__, buf_len, buf));
+		return -EINVAL;
+	}
+
+	/* Get APF filter data from the dongle */
+	cmd_len = sizeof(cmd);
+	ret = memcpy_s(buf, buf_len, cmd, cmd_len);
+	if (unlikely(ret)) {
+		return ret;
+	}
+	*(buf + cmd_len) = htod32(filter_id);
+	ret = dhd_wl_ioctl_cmd(dhdp, WLC_GET_VAR, buf, buf_len, FALSE, ifidx);
+	if (unlikely(ret)) {
+		DHD_ERROR(("%s: failed to read APF filter data, id=%d, ret=%d\n", __FUNCTION__,
+			filter_id, ret));
+		return ret;
+	}
+
+	/* Validate structure version */
+	apf_program = (wl_apf_program_t *)buf;
+	if (apf_program->version != WL_APF_INTERNAL_VERSION) {
+		DHD_ERROR(("%s: incorrect version, version=%d, expected version=%d\n",
+			__FUNCTION__, apf_program->version, WL_APF_INTERNAL_VERSION));
+		return BCME_VERSION;
+	}
+
+	return ret;
+}
+
+void dhd_apf_lock(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	_dhd_apf_lock_local(dhd);
+}
+
+void dhd_apf_unlock(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	_dhd_apf_unlock_local(dhd);
+}
+
+int
+dhd_dev_apf_get_version(struct net_device *ndev, uint32 *version)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(ndev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	int ifidx, ret;
+
+	if (!FW_SUPPORTED(dhdp, apf)) {
+		DHD_ERROR(("%s: firmware doesn't support APF\n", __FUNCTION__));
+		/* Notify Android framework that APF is not supported by setting version as zero. */
+		*version = 0;
+		return BCME_OK;
+	}
+
+	ifidx = dhd_net2idx(dhd, ndev);
+	if (ifidx == DHD_BAD_IF) {
+		DHD_ERROR(("%s: bad ifidx\n", __FUNCTION__));
+		return -ENODEV;
+	}
+
+	ret = dhd_wl_ioctl_get_intiovar(dhdp, "apf_ver", version, WLC_GET_VAR, FALSE, ifidx);
+	if (unlikely(ret)) {
+		DHD_ERROR(("%s: failed to get APF version, ret=%d\n", __FUNCTION__, ret));
+		return ret;
+	}
+
+	return ret;
+}
+
+int
+dhd_dev_apf_get_max_len(struct net_device *ndev, uint32 *max_len)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(ndev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	int ifidx, ret;
+
+	if (!FW_SUPPORTED(dhdp, apf)) {
+		DHD_ERROR(("%s: firmware doesn't support APF\n", __FUNCTION__));
+		*max_len = 0;
+		return BCME_OK;
+	}
+
+	ifidx = dhd_net2idx(dhd, ndev);
+	if (ifidx == DHD_BAD_IF) {
+		DHD_ERROR(("%s bad ifidx\n", __FUNCTION__));
+		return -ENODEV;
+	}
+
+	ret = dhd_wl_ioctl_get_intiovar(dhdp, "apf_size_limit", max_len, WLC_GET_VAR, FALSE, ifidx);
+	if (unlikely(ret)) {
+		DHD_ERROR(("%s: failed to get APF size limit, ret=%d\n", __FUNCTION__, ret));
+		return ret;
+	}
+
+	return ret;
+}
+
+int
+dhd_dev_apf_add_filter(struct net_device *ndev, u8* program,
+	uint32 program_len)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(ndev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	int ret;
+
+	DHD_ERROR(("%s: id %d\n", __func__, PKT_FILTER_APF_ID));
+
+	DHD_APF_LOCK(ndev);
+
+	if (!APF_PKT_LOAD_ENAB(ndev)) {
+		/* delete, if filter already exists */
+		if (dhdp->apf_set) {
+			ret = _dhd_apf_delete_filter(ndev, PKT_FILTER_APF_ID);
+			if (unlikely(ret)) {
+				goto exit;
+			}
+			dhdp->apf_set = FALSE;
+ 		}
+ 	}
+
+	ret = _dhd_apf_add_filter(ndev, PKT_FILTER_APF_ID, program, program_len);
+	if (ret) {
+		goto exit;
+	}
+	dhdp->apf_set = TRUE;
+
+	if (dhdp->in_suspend && dhdp->apf_set && !(dhdp->op_mode & DHD_FLAG_HOSTAP_MODE)) {
+		/* Driver is still in (early) suspend state and during this time Android
+		 * framework updated the filter program. As there will not be another
+		 * early suspend notification, enable back the APF filter with the new
+		 * filter program to avoid unnecessary host wake-ups.
+		 */
+		ret = _dhd_apf_config_filter(ndev, PKT_FILTER_APF_ID,
+			PKT_FILTER_MODE_FORWARD_ON_MATCH, TRUE);
+		if (ret) {
+			goto exit;
+		}
+	}
+exit:
+	DHD_APF_UNLOCK(ndev);
+
+	return ret;
+}
+
+void
+dhd_dev_pkt_filter_stats(struct net_device *ndev, int pkt_filter_id)
+{
+	int getbuf[64];
+	wl_pkt_filter_stats_t *stats;
+	wldev_iovar_getbuf_bsscfg(ndev, "pkt_filter_stats", &pkt_filter_id,
+			sizeof(pkt_filter_id), getbuf, sizeof(getbuf),
+			0, NULL);
+	stats = (wl_pkt_filter_stats_t *) getbuf;
+
+	DHD_ERROR(("%s: id %d, matched %d, discarded %d, forwarded %d\n",
+			__func__, pkt_filter_id,
+			dtoh32(stats->num_pkts_matched),
+			dtoh32(stats->num_pkts_discarded),
+			dtoh32(stats->num_pkts_forwarded)));
+}
+
+int
+dhd_dev_apf_enable_filter(struct net_device *ndev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(ndev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	int ret = 0;
+	bool nan_dp_active = false;
+
+	DHD_ERROR(("%s: apf_set %d, op_mode 0x%x, nan_dp_active %d\n", __func__,
+		dhdp->apf_set, dhdp->op_mode, nan_dp_active));
+
+	DHD_APF_LOCK(ndev);
+
+#ifdef WL_NAN
+	nan_dp_active = wl_cfgnan_is_dp_active(ndev);
+#endif /* WL_NAN */
+
+	if (dhdp->apf_set && (!(dhdp->op_mode & DHD_FLAG_HOSTAP_MODE) && !nan_dp_active)) {
+		DHD_ERROR(("%s: id %d Enable\n", __func__, PKT_FILTER_APF_ID));
+		ret = _dhd_apf_config_filter(ndev, PKT_FILTER_APF_ID,
+			PKT_FILTER_MODE_FORWARD_ON_MATCH, TRUE);
+		dhd_dev_pkt_filter_stats(ndev, PKT_FILTER_APF_ID);
+	}
+
+	DHD_APF_UNLOCK(ndev);
+
+	return ret;
+}
+
+int
+dhd_dev_apf_disable_filter(struct net_device *ndev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(ndev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	int ret = 0;
+
+	DHD_ERROR(("%s: apf_set %d\n", __func__, dhdp->apf_set));
+
+	DHD_APF_LOCK(ndev);
+
+	if (dhdp->apf_set) {
+		DHD_ERROR(("%s: id %d Disable\n", __func__, PKT_FILTER_APF_ID));
+		ret = _dhd_apf_config_filter(ndev, PKT_FILTER_APF_ID,
+			PKT_FILTER_MODE_FORWARD_ON_MATCH, FALSE);
+		dhd_dev_pkt_filter_stats(ndev, PKT_FILTER_APF_ID);
+	}
+
+	DHD_APF_UNLOCK(ndev);
+
+	return ret;
+}
+
+int
+dhd_dev_apf_delete_filter(struct net_device *ndev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(ndev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	int ret = 0;
+
+	DHD_ERROR(("%s: id %d\n", __func__, PKT_FILTER_APF_ID));
+
+	DHD_APF_LOCK(ndev);
+
+	if (dhdp->apf_set) {
+		ret = _dhd_apf_delete_filter(ndev, PKT_FILTER_APF_ID);
+		if (!ret) {
+			dhdp->apf_set = FALSE;
+		}
+	}
+
+	DHD_APF_UNLOCK(ndev);
+
+	return ret;
+}
+
+int
+dhd_dev_apf_read_filter_data(struct net_device *ndev, u8* buf, uint32 buf_len)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(ndev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	int ret = 0;
+	bool apf_disabled = FALSE;
+
+	DHD_APF_LOCK(ndev);
+
+	if (!dhdp->apf_set) {
+		DHD_ERROR(("%s: APF filter is not programmed\n", __FUNCTION__));
+		goto exit;
+	}
+
+	/* As per the requirement, APF filter needs to be stopped while reading the filter data.
+	 * Otherwise the APF counters could be wrong. Therefore disable the APF filter, if driver
+	 * is in (early) suspend state.
+	 */
+	if (dhdp->in_suspend) {
+		ret = _dhd_apf_config_filter(ndev, PKT_FILTER_APF_ID,
+			PKT_FILTER_MODE_FORWARD_ON_MATCH, FALSE);
+		if (unlikely(ret)) {
+			DHD_ERROR(("%s: failed to disable APF filter, ret=%d\n",
+				__FUNCTION__, ret));
+			goto exit;
+		}
+		apf_disabled = TRUE;
+	}
+
+	ret = _dhd_apf_read_filter_data(ndev, PKT_FILTER_APF_ID, buf, buf_len);
+	if (unlikely(ret)) {
+		goto exit;
+	}
+
+exit:
+	/* Re-enable the filter if got disabled above */
+	if (apf_disabled && _dhd_apf_config_filter(ndev, PKT_FILTER_APF_ID,
+			PKT_FILTER_MODE_FORWARD_ON_MATCH, TRUE)) {
+		DHD_ERROR(("%s: failed to enable APF filter, ret=%d\n", __FUNCTION__, ret));
+	}
+
+	DHD_APF_UNLOCK(ndev);
+
+	return ret;
+}
+#endif /* APF */
+
+#if defined(OEM_ANDROID)
+static void dhd_hang_process(struct work_struct *work_data)
+{
+	struct net_device *dev;
+#ifdef IFACE_HANG_FORCE_DEV_CLOSE
+	struct net_device *ndev;
+	uint8 i = 0;
+#endif /* IFACE_HANG_FORCE_DEV_CLOSE */
+	struct dhd_info *dhd;
+	dhd_pub_t *dhdp;
+#ifdef WL_CFG80211
+	struct bcm_cfg80211 *cfg;
+#endif /* WL_CFG80211 */
+
+	/* Ignore compiler warnings due to -Werror=cast-qual */
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd = container_of(work_data, dhd_info_t, dhd_hang_process_work);
+	GCC_DIAGNOSTIC_POP();
+	dhdp = &dhd->pub;
+
+	dev = dhd_linux_get_primary_netdev(dhdp);
+
+	if (!dev) {
+		DHD_ERROR(("%s: Cannot find primary netdev\n", __FUNCTION__));
+		dhdp->hang_was_sent = 0;
+		return;
+	}
+#ifdef WL_CFG80211
+	cfg = wl_get_cfg(dev);
+	if (!cfg) {
+		DHD_ERROR(("%s: Cannot find cfg\n", __FUNCTION__));
+		dhdp->hang_was_sent = 0;
+		return;
+	}
+	/* Skip sending HANG event to framework if driver is not ready */
+	if (!wl_get_drv_status(cfg, READY, dev)) {
+		DHD_ERROR(("%s: device is not ready\n", __FUNCTION__));
+		dhdp->hang_was_sent = 0;
+		return;
+	}
+#endif /* WL_CFG80211 */
+#if defined(WL_WIRELESS_EXT)
+	wl_iw_send_priv_event(dev, "HANG");
+#endif
+#if defined(WL_CFG80211)
+	wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED);
+#endif
+
+#ifdef IFACE_HANG_FORCE_DEV_CLOSE
+	/*
+	 * In case of wif scan only mode, upper layer doesn't handle hang
+	 * So dev_close need to be called explicitly
+	 */
+#ifdef HANG_DELAY_BEFORE_DEV_CLOSE
+	{
+		int wait_cnt = WAIT_FOR_DEV_CLOSE_MAX;
+		while (dev && (dev->flags & IFF_UP) && (wait_cnt > 0)) {
+			wait_cnt--;
+			OSL_SLEEP(10);
+		}
+		DHD_ERROR(("dev->name : %s wait for interface down done, wait_cnt:%d\n",
+			((dev == NULL) ? "null" : dev->name), wait_cnt));
+	}
+#endif /* HANG_DELAY_BEFORE_DEV_CLOSE */
+
+	rtnl_lock();
+	for (i = 0; i < DHD_MAX_IFS && dhd; i++) {
+		ndev = dhd->iflist[i] ? dhd->iflist[i]->net : NULL;
+		if (ndev && (ndev->flags & IFF_UP)) {
+			DHD_ERROR(("ndev->name : %s dev close\n",
+					ndev->name));
+#ifdef ENABLE_INSMOD_NO_FW_LOAD
+			dhd_download_fw_on_driverload = FALSE;
+#endif
+			dev_close(ndev);
+		}
+	}
+	rtnl_unlock();
+#endif /* IFACE_HANG_FORCE_DEV_CLOSE */
+}
+
+#if defined(CONFIG_ARCH_EXYNOS) && defined(BCMPCIE)
+extern dhd_pub_t *link_recovery;
+void dhd_host_recover_link(void)
+{
+	DHD_ERROR(("****** %s ******\n", __FUNCTION__));
+	link_recovery->hang_reason = HANG_REASON_PCIE_LINK_DOWN_RC_DETECT;
+	dhd_bus_set_linkdown(link_recovery, TRUE);
+	dhd_os_send_hang_message(link_recovery);
+}
+EXPORT_SYMBOL(dhd_host_recover_link);
+#endif /* CONFIG_ARCH_EXYNOS && BCMPCIE */
+
+/*
+ * Note that this function should be called in both interrupt and process context
+ * Therefore, Keep it simple, and use workqueue for complex/time-consuming work
+ */
+int dhd_os_send_hang_message(dhd_pub_t *dhdp)
+{
+	int ret = 0;
+	dhd_info_t *dhd_info = NULL;
+
+	if (!dhdp) {
+		DHD_ERROR(("%s: dhdp is null\n", __FUNCTION__));
+		return -EINVAL;
+	}
+
+	dhd_info = (dhd_info_t *)dhdp->info;
+	BCM_REFERENCE(dhd_info);
+#ifdef DHD_FW_COREDUMP
+	if (dhdp->memdump_enabled == DUMP_MEMFILE_BUGON &&
+		(dhdp->hang_reason == HANG_REASON_PCIE_LINK_DOWN_RC_DETECT ||
+		dhdp->hang_reason == HANG_REASON_PCIE_LINK_DOWN_EP_DETECT)) {
+			DHD_ERROR(("%s: BUG_ON for pcie link down memdump_enabled:%d\n",
+				__FUNCTION__, dhdp->memdump_enabled));
+			BUG_ON(1);
+	}
+#endif /* DHD_FW_COREDUMP */
+#if defined(WLAN_ACCEL_BOOT)
+	if (!dhd_info->wl_accel_force_reg_on) {
+		DHD_ERROR(("%s: set force reg on\n", __FUNCTION__));
+		dhd_info->wl_accel_force_reg_on = TRUE;
+	}
+#endif /* WLAN_ACCEL_BOOT */
+
+	if (!dhdp->hang_report) {
+		DHD_ERROR(("%s: hang_report is disabled\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	if (dhdp->stop_in_progress) {
+		DHD_ERROR(("%s: dhd_stop in progress\n", __FUNCTION__));
+		return BCME_OK;
+	}
+
+#if defined(WL_CFG80211) && (defined(DHD_FILE_DUMP_EVENT) || defined(DHD_COREDUMP))
+	if (dhd_info->scheduled_memdump) {
+		DHD_ERROR_RLMT(("[DUMP]:%s, memdump in progress. return\n", __FUNCTION__));
+		dhdp->hang_was_pending = 1;
+		return BCME_OK;
+	}
+#endif /* WL_CFG80211 && (DHD_FILE_DUMP_EVENT || DHD_COREDUMP) */
+
+#if defined(DHD_HANG_SEND_UP_TEST)
+	if (dhdp->req_hang_type) {
+		DHD_ERROR(("%s, Clear HANG test request 0x%x\n",
+			__FUNCTION__, dhdp->req_hang_type));
+		dhdp->req_hang_type = 0;
+	}
+#endif /* DHD_HANG_SEND_UP_TEST */
+
+	if (!dhdp->hang_was_sent) {
+#ifdef DHD_DETECT_CONSECUTIVE_MFG_HANG
+		if (dhdp->op_mode & DHD_FLAG_MFG_MODE) {
+			dhdp->hang_count++;
+			if (dhdp->hang_count >= MAX_CONSECUTIVE_MFG_HANG_COUNT) {
+				DHD_ERROR(("%s, Consecutive hang from Dongle :%u\n",
+					__FUNCTION__, dhdp->hang_count));
+				BUG_ON(1);
+			}
+		}
+#endif /* DHD_DETECT_CONSECUTIVE_MFG_HANG */
+#ifdef DHD_DEBUG_UART
+		/* If PCIe lane has broken, execute the debug uart application
+		 * to gether a ramdump data from dongle via uart
+		 */
+		if (!dhdp->info->duart_execute) {
+			dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq,
+					(void *)dhdp, DHD_WQ_WORK_DEBUG_UART_DUMP,
+					dhd_debug_uart_exec_rd, DHD_WQ_WORK_PRIORITY_HIGH);
+		}
+#endif	/* DHD_DEBUG_UART */
+		dhdp->hang_was_sent = 1;
+#ifdef BT_OVER_SDIO
+		dhdp->is_bt_recovery_required = TRUE;
+#endif
+		schedule_work(&dhdp->info->dhd_hang_process_work);
+		DHD_ERROR(("%s: Event HANG send up due to  re=%d te=%d s=%d\n", __FUNCTION__,
+			dhdp->rxcnt_timeout, dhdp->txcnt_timeout, dhdp->busstate));
+		printf("%s\n", info_string);
+		printf("MAC %pM\n", &dhdp->mac);
+	}
+	return ret;
+}
+
+int net_os_send_hang_message(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	int ret = 0;
+
+	if (dhd) {
+		/* Report FW problem when enabled */
+		if (dhd->pub.hang_report) {
+#ifdef BT_OVER_SDIO
+			if (netif_running(dev))
+#endif /* BT_OVER_SDIO */
+			{
+				ret = dhd_os_send_hang_message(&dhd->pub);
+			}
+#ifdef BT_OVER_SDIO
+			DHD_ERROR(("%s: HANG -> Reset BT\n", __FUNCTION__));
+			bcmsdh_btsdio_process_dhd_hang_notification(!netif_running(dev));
+#endif /* BT_OVER_SDIO */
+		} else {
+			DHD_ERROR(("%s: FW HANG ignored (for testing purpose) and not sent up\n",
+				__FUNCTION__));
+		}
+	}
+	return ret;
+}
+
+int net_os_send_hang_message_reason(struct net_device *dev, const char *string_num)
+{
+	dhd_info_t *dhd = NULL;
+	dhd_pub_t *dhdp = NULL;
+	int reason;
+
+	dhd = DHD_DEV_INFO(dev);
+	if (dhd) {
+		dhdp = &dhd->pub;
+	}
+
+	if (!dhd || !dhdp) {
+		return 0;
+	}
+
+	reason = bcm_strtoul(string_num, NULL, 0);
+	DHD_INFO(("%s: Enter, reason=0x%x\n", __FUNCTION__, reason));
+
+	if ((reason <= HANG_REASON_MASK) || (reason >= HANG_REASON_MAX)) {
+		reason = 0;
+	}
+
+	dhdp->hang_reason = reason;
+
+	return net_os_send_hang_message(dev);
+}
+#endif /* OEM_ANDROID */
+
+int dhd_net_wifi_platform_set_power(struct net_device *dev, bool on, unsigned long delay_msec)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	return wifi_platform_set_power(dhd->adapter, on, delay_msec);
+}
+
+int dhd_wifi_platform_set_power(dhd_pub_t *pub, bool on)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	unsigned long delay_msec = on ? WIFI_TURNON_DELAY : WIFI_TURNOFF_DELAY;
+	return wifi_platform_set_power(dhd->adapter, on, delay_msec);
+}
+
+bool dhd_force_country_change(struct net_device *dev)
+{
+#if defined(CUSTOM_FORCE_NODFS_FLAG) && defined(CUSTOM_COUNTRY_CODE)
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+
+	if (dhd && dhd->pub.up && dhd->pub.force_country_change) {
+		DHD_ERROR(("force country change\n"));
+		return TRUE;
+	}
+#endif /* CUSTOM_FORCE_NODFS_FLAG && CUSTOM_COUNTRY_CODE */
+	DHD_ERROR(("skip force country change\n"));
+	return FALSE;
+}
+
+void dhd_get_customized_country_code(struct net_device *dev, char *country_iso_code,
+	wl_country_t *cspec)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+#if defined(DHD_BLOB_EXISTENCE_CHECK)
+	if (!dhd->pub.is_blob)
+#endif /* DHD_BLOB_EXISTENCE_CHECK */
+	{
+#if defined(CUSTOM_COUNTRY_CODE)
+		get_customized_country_code(dhd->adapter, country_iso_code, cspec,
+			dhd->pub.dhd_cflags);
+#else
+		get_customized_country_code(dhd->adapter, country_iso_code, cspec);
+#endif /* CUSTOM_COUNTRY_CODE */
+	}
+#if defined(DHD_BLOB_EXISTENCE_CHECK) && !defined(CUSTOM_COUNTRY_CODE)
+	else {
+		/* Replace the ccode to XZ if ccode is undefined country or world
+		 * domain
+		 */
+		if ((strncmp(country_iso_code, "", WLC_CNTRY_BUF_SZ) == 0) ||
+				(strncmp(country_iso_code, "00", WLC_CNTRY_BUF_SZ) == 0)) {
+			strlcpy(country_iso_code, "XZ", WLC_CNTRY_BUF_SZ);
+			strlcpy(cspec->country_abbrev, country_iso_code, WLC_CNTRY_BUF_SZ);
+			strlcpy(cspec->ccode, country_iso_code, WLC_CNTRY_BUF_SZ);
+			DHD_ERROR(("%s: ccode change to %s\n", __FUNCTION__, country_iso_code));
+		}
+	}
+#endif /* DHD_BLOB_EXISTENCE_CHECK && !CUSTOM_COUNTRY_CODE */
+
+#ifdef KEEP_JP_REGREV
+/* XXX Needed by customer's request */
+	if (strncmp(country_iso_code, "JP", 3) == 0) {
+#if defined(DHD_BLOB_EXISTENCE_CHECK)
+		if (dhd->pub.is_blob) {
+			if (strncmp(dhd->pub.vars_ccode, "J1", 3) == 0) {
+				memcpy(cspec->ccode, dhd->pub.vars_ccode,
+					sizeof(dhd->pub.vars_ccode));
+			}
+		} else
+#endif /* DHD_BLOB_EXISTENCE_CHECK */
+		{
+			if (strncmp(dhd->pub.vars_ccode, "JP", 3) == 0) {
+				cspec->rev = dhd->pub.vars_regrev;
+			}
+		}
+	}
+#endif /* KEEP_JP_REGREV */
+	BCM_REFERENCE(dhd);
+}
+
+void dhd_bus_country_set(struct net_device *dev, wl_country_t *cspec, bool notify)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+#ifdef WL_CFG80211
+	struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+#endif
+
+	if (dhd && dhd->pub.up) {
+		memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t));
+		dhd->pub.force_country_change = FALSE;
+#ifdef WL_CFG80211
+		wl_update_wiphybands(cfg, notify);
+#endif
+	}
+}
+
+void dhd_bus_band_set(struct net_device *dev, uint band)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+#ifdef WL_CFG80211
+	struct bcm_cfg80211 *cfg = wl_get_cfg(dev);
+#endif
+	if (dhd && dhd->pub.up) {
+#ifdef WL_CFG80211
+		wl_update_wiphybands(cfg, true);
+#endif
+	}
+}
+
+int dhd_net_set_fw_path(struct net_device *dev, char *fw)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+
+	if (!fw || fw[0] == '\0')
+		return -EINVAL;
+
+	strlcpy(dhd->fw_path, fw, sizeof(dhd->fw_path));
+
+#if defined(OEM_ANDROID) && defined(SOFTAP)
+	if (strstr(fw, "apsta") != NULL) {
+		DHD_INFO(("GOT APSTA FIRMWARE\n"));
+		ap_fw_loaded = TRUE;
+	} else {
+		DHD_INFO(("GOT STA FIRMWARE\n"));
+		ap_fw_loaded = FALSE;
+	}
+#endif /* defined(OEM_ANDROID) && defined(SOFTAP) */
+	return 0;
+}
+
+void dhd_net_if_lock(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	dhd_net_if_lock_local(dhd);
+}
+
+void dhd_net_if_unlock(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	dhd_net_if_unlock_local(dhd);
+}
+
+bool dhd_net_if_locked(struct net_device *dev)
+{
+	bool locked = FALSE;
+
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	if (dhd) {
+		if (mutex_is_locked(&dhd->dhd_net_if_mutex))
+			locked = TRUE;
+	}
+	return locked;
+}
+
+static void dhd_net_if_lock_local(dhd_info_t *dhd)
+{
+#if defined(OEM_ANDROID)
+	if (dhd)
+		mutex_lock(&dhd->dhd_net_if_mutex);
+#endif
+}
+
+static void dhd_net_if_unlock_local(dhd_info_t *dhd)
+{
+#if defined(OEM_ANDROID)
+	if (dhd)
+		mutex_unlock(&dhd->dhd_net_if_mutex);
+#endif
+}
+
+static void dhd_suspend_lock(dhd_pub_t *pub)
+{
+#if defined(OEM_ANDROID)
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	if (dhd)
+		mutex_lock(&dhd->dhd_suspend_mutex);
+#endif
+}
+
+static void dhd_suspend_unlock(dhd_pub_t *pub)
+{
+#if defined(OEM_ANDROID)
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	if (dhd)
+		mutex_unlock(&dhd->dhd_suspend_mutex);
+#endif
+}
+
+unsigned long dhd_os_general_spin_lock(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	unsigned long flags = 0;
+
+	if (dhd) {
+		flags = osl_spin_lock(&dhd->dhd_lock);
+	}
+
+	return flags;
+}
+
+void dhd_os_general_spin_unlock(dhd_pub_t *pub, unsigned long flags)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		osl_spin_unlock(&dhd->dhd_lock, flags);
+	}
+}
+
+static int
+dhd_get_pend_8021x_cnt(dhd_info_t *dhd)
+{
+	return (atomic_read(&dhd->pend_8021x_cnt));
+}
+
+#define MAX_WAIT_FOR_8021X_TX	100
+
+int
+dhd_wait_pend8021x(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	int timeout = msecs_to_jiffies(10);
+	int ntimes = MAX_WAIT_FOR_8021X_TX;
+	int pend = dhd_get_pend_8021x_cnt(dhd);
+
+	while (ntimes && pend) {
+		if (pend) {
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(timeout);
+			set_current_state(TASK_RUNNING);
+			ntimes--;
+		}
+		pend = dhd_get_pend_8021x_cnt(dhd);
+	}
+	if (ntimes == 0)
+	{
+		atomic_set(&dhd->pend_8021x_cnt, 0);
+		WL_MSG(dev->name, "TIMEOUT\n");
+	}
+	return pend;
+}
+
+#if defined(BCM_ROUTER_DHD) || defined(DHD_DEBUG)
+int write_file(const char * file_name, uint32 flags, uint8 *buf, int size)
+{
+	int ret = 0;
+	struct file *fp = NULL;
+#ifdef get_fs
+	mm_segment_t old_fs;
+#endif /* get_fs */
+	loff_t pos = 0;
+
+#ifdef get_fs
+	/* change to KERNEL_DS address limit */
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+#endif /* get_fs */
+
+	/* open file to write */
+	fp = dhd_filp_open(file_name, flags, 0664);
+	if (IS_ERR(fp) || (fp == NULL)) {
+		DHD_ERROR(("open file error, err = %ld\n", PTR_ERR(fp)));
+		goto exit;
+	}
+
+	/* Write buf to file */
+	ret = dhd_vfs_write(fp, buf, size, &pos);
+	if (ret < 0) {
+		DHD_ERROR(("write file error, err = %d\n", ret));
+		goto exit;
+	}
+
+	/* Sync file from filesystem to physical media */
+	ret = dhd_vfs_fsync(fp, 0);
+	if (ret < 0) {
+		DHD_ERROR(("sync file error, error = %d\n", ret));
+		goto exit;
+	}
+	ret = BCME_OK;
+
+exit:
+	/* close file before return */
+	if (!IS_ERR(fp))
+		dhd_filp_close(fp, current->files);
+
+#ifdef get_fs
+	/* restore previous address limit */
+	set_fs(old_fs);
+#endif /* get_fs */
+
+	return ret;
+}
+#endif /* BCM_ROUTER_DHD || DHD_DEBUG */
+
+#ifdef DHD_DEBUG
+void
+dhd_get_memdump_filename(struct net_device *ndev, char *memdump_path, int len, char *fname)
+{
+	char memdump_type[DHD_MEMDUMP_TYPE_STR_LEN];
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(ndev);
+	dhd_pub_t *dhdp = &dhd->pub;
+
+	/* Init file name */
+	memset(memdump_path, 0, len);
+	memset(memdump_type, 0, DHD_MEMDUMP_TYPE_STR_LEN);
+#ifdef DHD_LOG_DUMP
+	dhd_convert_memdump_type_to_str(dhdp->memdump_type, memdump_type, DHD_MEMDUMP_TYPE_STR_LEN,
+		dhdp->debug_dump_subcmd);
+	clear_debug_dump_time(dhdp->debug_dump_time_str);
+	get_debug_dump_time(dhdp->debug_dump_time_str);
+#endif /* DHD_LOG_DUMP */
+	snprintf(memdump_path, len, "%s%s_%s_" "%s",
+		DHD_COMMON_DUMP_PATH, fname, memdump_type,  dhdp->debug_dump_time_str);
+
+	if (strstr(fname, "sssr_dump")) {
+		DHD_SSSR_PRINT_FILEPATH(dhdp, memdump_path);
+	} else {
+		DHD_ERROR(("%s: file_path = %s%s\n", __FUNCTION__,
+			memdump_path, FILE_NAME_HAL_TAG));
+	}
+}
+
+int
+write_dump_to_file(dhd_pub_t *dhd, uint8 *buf, int size, char *fname)
+{
+	int ret = 0;
+	char memdump_path[DHD_MEMDUMP_PATH_STR_LEN];
+	char memdump_type[DHD_MEMDUMP_TYPE_STR_LEN];
+	uint32 file_mode;
+
+	/* Init file name */
+	memset(memdump_path, 0, DHD_MEMDUMP_PATH_STR_LEN);
+	memset(memdump_type, 0, DHD_MEMDUMP_TYPE_STR_LEN);
+#ifdef DHD_LOG_DUMP
+	dhd_convert_memdump_type_to_str(dhd->memdump_type, memdump_type, DHD_MEMDUMP_TYPE_STR_LEN,
+			dhd->debug_dump_subcmd);
+	clear_debug_dump_time(dhd->debug_dump_time_str);
+	get_debug_dump_time(dhd->debug_dump_time_str);
+#endif /* DHD_LOG_DUMP */
+
+	snprintf(memdump_path, sizeof(memdump_path), "%s%s_%s_" "%s",
+		DHD_COMMON_DUMP_PATH, fname, memdump_type, dhd->debug_dump_time_str);
+#if defined(BOARD_HIKEY)
+	file_mode = O_CREAT | O_WRONLY | O_SYNC;
+#elif defined(OEM_ANDROID) && defined(__ARM_ARCH_7A__)
+	file_mode = O_CREAT | O_WRONLY;
+#elif defined(OEM_ANDROID)
+	/* Extra flags O_DIRECT and O_SYNC are required for Brix Android, as we are
+	 * calling BUG_ON immediately after collecting the socram dump.
+	 * So the file write operation should directly write the contents into the
+	 * file instead of caching it. O_TRUNC flag ensures that file will be re-written
+	 * instead of appending.
+	 */
+	file_mode = O_CREAT | O_WRONLY | O_SYNC;
+	{
+		struct file *fp = dhd_filp_open(memdump_path, file_mode, 0664);
+		/* Check if it is live Brix image having /installmedia, else use /data */
+		if (IS_ERR(fp) || (fp == NULL)) {
+			DHD_ERROR(("open file %s, try /data/\n", memdump_path));
+			snprintf(memdump_path, sizeof(memdump_path), "%s%s_%s_" "%s",
+				"/data/", fname, memdump_type,  dhd->debug_dump_time_str);
+		} else {
+			dhd_filp_close(fp, NULL);
+		}
+	}
+#else
+	file_mode = O_CREAT | O_WRONLY;
+#endif /* BOARD_HIKEY */
+
+	/* print SOCRAM dump file path */
+	DHD_ERROR(("%s: file_path = %s\n", __FUNCTION__, memdump_path));
+
+#ifdef DHD_LOG_DUMP
+	dhd_print_buf_addr(dhd, "write_dump_to_file", buf, size);
+#endif /* DHD_LOG_DUMP */
+
+	/* Write file */
+	ret = write_file(memdump_path, file_mode, buf, size);
+
+#ifdef DHD_DUMP_MNGR
+	if (ret == BCME_OK) {
+		dhd_dump_file_manage_enqueue(dhd, memdump_path, fname);
+	}
+#endif /* DHD_DUMP_MNGR */
+
+	return ret;
+}
+#endif /* DHD_DEBUG */
+
+int dhd_os_wake_lock_timeout(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	unsigned long flags;
+	int ret = 0;
+
+	if (dhd && (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT)) {
+		DHD_WAKE_SPIN_LOCK(&dhd->wakelock_spinlock, flags);
+		ret = dhd->wakelock_rx_timeout_enable > dhd->wakelock_ctrl_timeout_enable ?
+			dhd->wakelock_rx_timeout_enable : dhd->wakelock_ctrl_timeout_enable;
+#ifdef CONFIG_HAS_WAKELOCK
+#ifdef DHD_DEBUG_WAKE_LOCK
+		printf("%s: rx_timeout=%dms, ctrl_timeout=%dms\n", __FUNCTION__,
+		dhd->wakelock_rx_timeout_enable, dhd->wakelock_ctrl_timeout_enable);
+#endif
+		if (dhd->wakelock_rx_timeout_enable)
+			dhd_wake_lock_timeout(dhd->wl_rxwake,
+				msecs_to_jiffies(dhd->wakelock_rx_timeout_enable));
+		if (dhd->wakelock_ctrl_timeout_enable)
+			dhd_wake_lock_timeout(dhd->wl_ctrlwake,
+				msecs_to_jiffies(dhd->wakelock_ctrl_timeout_enable));
+#endif
+		dhd->wakelock_rx_timeout_enable = 0;
+		dhd->wakelock_ctrl_timeout_enable = 0;
+		DHD_WAKE_SPIN_UNLOCK(&dhd->wakelock_spinlock, flags);
+	}
+	return ret;
+}
+
+int net_os_wake_lock_timeout(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	int ret = 0;
+
+	if (dhd)
+		ret = dhd_os_wake_lock_timeout(&dhd->pub);
+	return ret;
+}
+
+int dhd_os_wake_lock_ctrl_timeout_enable(dhd_pub_t *pub, int val)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	unsigned long flags;
+
+	if (dhd && (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT)) {
+		DHD_WAKE_SPIN_LOCK(&dhd->wakelock_spinlock, flags);
+		if (val > dhd->wakelock_ctrl_timeout_enable)
+			dhd->wakelock_ctrl_timeout_enable = val;
+		DHD_WAKE_SPIN_UNLOCK(&dhd->wakelock_spinlock, flags);
+	}
+	return 0;
+}
+
+int dhd_os_wake_lock_ctrl_timeout_cancel(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	unsigned long flags;
+
+	if (dhd && (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT)) {
+		DHD_WAKE_SPIN_LOCK(&dhd->wakelock_spinlock, flags);
+		dhd->wakelock_ctrl_timeout_enable = 0;
+#ifdef CONFIG_HAS_WAKELOCK
+		if (dhd_wake_lock_active(dhd->wl_ctrlwake))
+			dhd_wake_unlock(dhd->wl_ctrlwake);
+#endif
+		DHD_WAKE_SPIN_UNLOCK(&dhd->wakelock_spinlock, flags);
+	}
+	return 0;
+}
+
+int net_os_wake_lock_ctrl_timeout_enable(struct net_device *dev, int val)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	int ret = 0;
+
+	if (dhd)
+		ret = dhd_os_wake_lock_ctrl_timeout_enable(&dhd->pub, val);
+	return ret;
+}
+
+#if defined(DHD_TRACE_WAKE_LOCK)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
+#include <linux/hashtable.h>
+/* Define 2^5 = 32 bucket size hash table */
+DEFINE_HASHTABLE(wklock_history, 5);
+#else
+#include <linux/hash.h>
+/* Define 2^5 = 32 bucket size hash table */
+struct hlist_head wklock_history[32] = { [0 ... 31] = HLIST_HEAD_INIT };
+#endif /* KERNEL_VER >= KERNEL_VERSION(3, 7, 0) */
+
+atomic_t trace_wklock_onoff;
+static struct wk_trace_record *find_wklock_entry(unsigned long addr)
+{
+	struct wk_trace_record *wklock_info;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	hash_for_each_possible(wklock_history, wklock_info, wklock_node, addr)
+#else
+	struct hlist_node *entry;
+	int index = hash_long(addr, ilog2(ARRAY_SIZE(wklock_history)));
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	hlist_for_each_entry(wklock_info, entry, &wklock_history[index], wklock_node)
+#endif /* KERNEL_VER >= KERNEL_VERSION(3, 7, 0) */
+	{
+		GCC_DIAGNOSTIC_POP();
+		if (wklock_info->addr == addr) {
+			return wklock_info;
+		}
+	}
+	return NULL;
+}
+
+static inline void dhd_wk_lock_rec_dump(void)
+{
+	int bkt;
+	struct wk_trace_record *wklock_info;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	hash_for_each(wklock_history, bkt, wklock_info, wklock_node)
+#else
+	struct hlist_node *entry = NULL;
+	int max_index = ARRAY_SIZE(wklock_history);
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	for (bkt = 0; bkt < max_index; bkt++)
+		hlist_for_each_entry(wklock_info, entry, &wklock_history[bkt], wklock_node)
+#endif /* KERNEL_VER >= KERNEL_VERSION(3, 7, 0) */
+		{
+			GCC_DIAGNOSTIC_POP();
+			switch (wklock_info->lock_type) {
+				case DHD_WAKE_LOCK:
+					DHD_ERROR(("wakelock lock : %pS  lock_counter : %llu \n",
+						(void *)wklock_info->addr, wklock_info->counter));
+					break;
+				case DHD_WAKE_UNLOCK:
+					DHD_ERROR(("wakelock unlock : %pS,"
+						" unlock_counter : %llu \n",
+						(void *)wklock_info->addr, wklock_info->counter));
+					break;
+				case DHD_WAIVE_LOCK:
+					DHD_ERROR(("wakelock waive : %pS  before_waive : %llu \n",
+						(void *)wklock_info->addr, wklock_info->counter));
+					break;
+				case DHD_RESTORE_LOCK:
+					DHD_ERROR(("wakelock restore : %pS, after_waive : %llu \n",
+						(void *)wklock_info->addr, wklock_info->counter));
+					break;
+			}
+		}
+}
+
+static void dhd_wk_lock_trace_init(struct dhd_info *dhd)
+{
+	unsigned long flags;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
+	int i;
+#endif /* KERNEL_VER >= KERNEL_VERSION(3, 7, 0) */
+
+	DHD_WAKE_SPIN_LOCK(&dhd->wakelock_spinlock, flags);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
+	hash_init(wklock_history);
+#else
+	for (i = 0; i < ARRAY_SIZE(wklock_history); i++)
+		INIT_HLIST_HEAD(&wklock_history[i]);
+#endif /* KERNEL_VER >= KERNEL_VERSION(3, 7, 0) */
+	DHD_WAKE_SPIN_UNLOCK(&dhd->wakelock_spinlock, flags);
+	atomic_set(&trace_wklock_onoff, 1);
+}
+
+static void dhd_wk_lock_trace_deinit(struct dhd_info *dhd)
+{
+	int bkt;
+	struct wk_trace_record *wklock_info;
+	struct hlist_node *tmp;
+	unsigned long flags;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
+	struct hlist_node *entry = NULL;
+	int max_index = ARRAY_SIZE(wklock_history);
+#endif /* KERNEL_VER >= KERNEL_VERSION(3, 7, 0) */
+
+	DHD_WAKE_SPIN_LOCK(&dhd->wakelock_spinlock, flags);
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
+	hash_for_each_safe(wklock_history, bkt, tmp, wklock_info, wklock_node)
+#else
+	for (bkt = 0; bkt < max_index; bkt++)
+		hlist_for_each_entry_safe(wklock_info, entry, tmp,
+			&wklock_history[bkt], wklock_node)
+#endif /* KERNEL_VER >= KERNEL_VERSION(3, 7, 0)) */
+		{
+			GCC_DIAGNOSTIC_POP();
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
+			hash_del(&wklock_info->wklock_node);
+#else
+			hlist_del_init(&wklock_info->wklock_node);
+#endif /* KERNEL_VER >= KERNEL_VERSION(3, 7, 0)) */
+			kfree(wklock_info);
+		}
+	DHD_WAKE_SPIN_UNLOCK(&dhd->wakelock_spinlock, flags);
+}
+
+void dhd_wk_lock_stats_dump(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(dhdp->info);
+	unsigned long flags;
+
+	DHD_ERROR(("DHD Printing wl_wake Lock/Unlock Record \r\n"));
+	DHD_WAKE_SPIN_LOCK(&dhd->wakelock_spinlock, flags);
+	dhd_wk_lock_rec_dump();
+	DHD_WAKE_SPIN_UNLOCK(&dhd->wakelock_spinlock, flags);
+
+}
+#endif /* ! DHD_TRACE_WAKE_LOCK */
+
+int dhd_os_wake_lock(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	unsigned long flags;
+	int ret = 0;
+
+	if (dhd && (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT)) {
+		DHD_WAKE_SPIN_LOCK(&dhd->wakelock_spinlock, flags);
+		if (dhd->wakelock_counter == 0 && !dhd->waive_wakelock) {
+#ifdef CONFIG_HAS_WAKELOCK
+			dhd_wake_lock(dhd->wl_wifi);
+#elif defined(BCMSDIO)
+			dhd_bus_dev_pm_stay_awake(pub);
+#endif
+		}
+#ifdef DHD_TRACE_WAKE_LOCK
+		if (atomic_read(&trace_wklock_onoff)) {
+			STORE_WKLOCK_RECORD(DHD_WAKE_LOCK);
+		}
+#endif /* DHD_TRACE_WAKE_LOCK */
+		dhd->wakelock_counter++;
+		ret = dhd->wakelock_counter;
+		DHD_WAKE_SPIN_UNLOCK(&dhd->wakelock_spinlock, flags);
+	}
+
+	return ret;
+}
+
+void dhd_event_wake_lock(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+#ifdef CONFIG_HAS_WAKELOCK
+		dhd_wake_lock(dhd->wl_evtwake);
+#elif defined(BCMSDIO)
+		dhd_bus_dev_pm_stay_awake(pub);
+#endif
+	}
+}
+
+void
+dhd_pm_wake_lock_timeout(dhd_pub_t *pub, int val)
+{
+#ifdef CONFIG_HAS_WAKELOCK
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		dhd_wake_lock_timeout(dhd->wl_pmwake, msecs_to_jiffies(val));
+	}
+#endif /* CONFIG_HAS_WAKE_LOCK */
+}
+
+void
+dhd_nan_wake_lock_timeout(dhd_pub_t *pub, int val)
+{
+#ifdef CONFIG_HAS_WAKELOCK
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		dhd_wake_lock_timeout(dhd->wl_nanwake, msecs_to_jiffies(val));
+	}
+#endif /* CONFIG_HAS_WAKE_LOCK */
+}
+
+int net_os_wake_lock(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	int ret = 0;
+
+	if (dhd)
+		ret = dhd_os_wake_lock(&dhd->pub);
+	return ret;
+}
+
+int dhd_os_wake_unlock(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	unsigned long flags;
+	int ret = 0;
+
+	dhd_os_wake_lock_timeout(pub);
+	if (dhd && (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT)) {
+		DHD_WAKE_SPIN_LOCK(&dhd->wakelock_spinlock, flags);
+
+		if (dhd->wakelock_counter > 0) {
+			dhd->wakelock_counter--;
+#ifdef DHD_TRACE_WAKE_LOCK
+			if (atomic_read(&trace_wklock_onoff)) {
+				STORE_WKLOCK_RECORD(DHD_WAKE_UNLOCK);
+			}
+#endif /* DHD_TRACE_WAKE_LOCK */
+			if (dhd->wakelock_counter == 0 && !dhd->waive_wakelock) {
+#ifdef CONFIG_HAS_WAKELOCK
+				dhd_wake_unlock(dhd->wl_wifi);
+#elif defined(BCMSDIO)
+				dhd_bus_dev_pm_relax(pub);
+#endif
+			}
+			ret = dhd->wakelock_counter;
+		}
+		DHD_WAKE_SPIN_UNLOCK(&dhd->wakelock_spinlock, flags);
+	}
+	return ret;
+}
+
+void dhd_event_wake_unlock(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+#ifdef CONFIG_HAS_WAKELOCK
+		dhd_wake_unlock(dhd->wl_evtwake);
+#elif defined(BCMSDIO)
+		dhd_bus_dev_pm_relax(pub);
+#endif
+	}
+}
+
+void dhd_pm_wake_unlock(dhd_pub_t *pub)
+{
+#ifdef CONFIG_HAS_WAKELOCK
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		/* if wl_pmwake is active, unlock it */
+		if (dhd_wake_lock_active(dhd->wl_pmwake)) {
+			dhd_wake_unlock(dhd->wl_pmwake);
+		}
+	}
+#endif /* CONFIG_HAS_WAKELOCK */
+}
+
+void dhd_txfl_wake_unlock(dhd_pub_t *pub)
+{
+#ifdef CONFIG_HAS_WAKELOCK
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		/* if wl_txflwake is active, unlock it */
+		if (dhd_wake_lock_active(dhd->wl_txflwake)) {
+			dhd_wake_unlock(dhd->wl_txflwake);
+		}
+	}
+#endif /* CONFIG_HAS_WAKELOCK */
+}
+
+void dhd_nan_wake_unlock(dhd_pub_t *pub)
+{
+#ifdef CONFIG_HAS_WAKELOCK
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		/* if wl_nanwake is active, unlock it */
+		if (dhd_wake_lock_active(dhd->wl_nanwake)) {
+			dhd_wake_unlock(dhd->wl_nanwake);
+		}
+	}
+#endif /* CONFIG_HAS_WAKELOCK */
+}
+
+int dhd_os_check_wakelock(dhd_pub_t *pub)
+{
+#if defined(CONFIG_HAS_WAKELOCK) || defined(BCMSDIO)
+#if defined(CONFIG_HAS_WAKELOCK)
+	int l1, l2;
+	int c, lock_active;
+#endif /* CONFIG_HAS_WAKELOCK */
+	dhd_info_t *dhd;
+
+	if (!pub)
+		return 0;
+	dhd = (dhd_info_t *)(pub->info);
+	if (!dhd) {
+		return 0;
+	}
+#endif /* CONFIG_HAS_WAKELOCK || BCMSDIO */
+
+#ifdef CONFIG_HAS_WAKELOCK
+	c = dhd->wakelock_counter;
+	l1 = dhd_wake_lock_active(dhd->wl_wifi);
+	l2 = dhd_wake_lock_active(dhd->wl_wdwake);
+	lock_active = (l1 || l2);
+	/* Indicate to the SD Host to avoid going to suspend if internal locks are up */
+	if (lock_active) {
+		DHD_ERROR(("%s wakelock c-%d wl-%d wd-%d\n",
+			__FUNCTION__, c, l1, l2));
+		return 1;
+	}
+#elif defined(BCMSDIO)
+	if (dhd && (dhd->wakelock_counter > 0) && dhd_bus_dev_pm_enabled(pub)) {
+		DHD_ERROR(("%s wakelock c-%d\n", __FUNCTION__, dhd->wakelock_counter));
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+int
+dhd_os_check_wakelock_all(dhd_pub_t *pub)
+{
+#if defined(CONFIG_HAS_WAKELOCK) || defined(BCMSDIO)
+#if defined(CONFIG_HAS_WAKELOCK)
+	int l1, l2, l3, l4, l7, l8, l9, l10;
+	int l5 = 0, l6 = 0;
+	int c, lock_active;
+#endif /* CONFIG_HAS_WAKELOCK */
+	dhd_info_t *dhd;
+
+	if (!pub) {
+		return 0;
+	}
+	if (pub->up == 0) {
+		DHD_ERROR(("%s: skip as down in progress\n", __FUNCTION__));
+		return 0;
+	}
+	dhd = (dhd_info_t *)(pub->info);
+	if (!dhd) {
+		return 0;
+	}
+#endif /* CONFIG_HAS_WAKELOCK || BCMSDIO */
+
+#ifdef CONFIG_HAS_WAKELOCK
+	c = dhd->wakelock_counter;
+	l1 = dhd_wake_lock_active(dhd->wl_wifi);
+	l2 = dhd_wake_lock_active(dhd->wl_wdwake);
+	l3 = dhd_wake_lock_active(dhd->wl_rxwake);
+	l4 = dhd_wake_lock_active(dhd->wl_ctrlwake);
+	l7 = dhd_wake_lock_active(dhd->wl_evtwake);
+#ifdef BCMPCIE_OOB_HOST_WAKE
+	l5 = dhd_wake_lock_active(dhd->wl_intrwake);
+#endif /* BCMPCIE_OOB_HOST_WAKE */
+#ifdef DHD_USE_SCAN_WAKELOCK
+	l6 = dhd_wake_lock_active(dhd->wl_scanwake);
+#endif /* DHD_USE_SCAN_WAKELOCK */
+	l8 = dhd_wake_lock_active(dhd->wl_pmwake);
+	l9 = dhd_wake_lock_active(dhd->wl_txflwake);
+	l10 = dhd_wake_lock_active(dhd->wl_nanwake);
+	lock_active = (l1 || l2 || l3 || l4 || l5 || l6 || l7 || l8 || l9 || l10);
+
+	/* Indicate to the Host to avoid going to suspend if internal locks are up */
+	DHD_ERROR(("%s wakelock c-%d wl-%d wd-%d rx-%d "
+		"ctl-%d intr-%d scan-%d evt-%d, pm-%d, txfl-%d nan-%d\n",
+		__FUNCTION__, c, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10));
+	if (lock_active) {
+#ifdef RPM_FAST_TRIGGER
+		if (pub->rpm_fast_trigger && l4) {
+			DHD_ERROR(("%s : reset rpm_fast_trigger becasue of wl_ctrlwake activated\n",
+					__FUNCTION__));
+			pub->rpm_fast_trigger = FALSE;
+		}
+#endif /* RPM_FAST_TRIGGER */
+		return 1;
+	}
+#elif defined(BCMSDIO)
+	if (dhd && (dhd->wakelock_counter > 0) && dhd_bus_dev_pm_enabled(pub)) {
+		DHD_ERROR(("%s wakelock c-%d\n", __FUNCTION__, dhd->wakelock_counter));
+		return 1;
+	}
+#endif /* defined(BCMSDIO) */
+	return 0;
+}
+
+int net_os_wake_unlock(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	int ret = 0;
+
+	if (dhd)
+		ret = dhd_os_wake_unlock(&dhd->pub);
+	return ret;
+}
+
+int dhd_os_wd_wake_lock(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	unsigned long flags;
+	int ret = 0;
+
+	if (dhd) {
+		DHD_WAKE_SPIN_LOCK(&dhd->wakelock_spinlock, flags);
+		if (dhd->wakelock_wd_counter == 0 && !dhd->waive_wakelock) {
+#ifdef CONFIG_HAS_WAKELOCK
+			/* if wakelock_wd_counter was never used : lock it at once */
+			dhd_wake_lock(dhd->wl_wdwake);
+#endif
+		}
+		dhd->wakelock_wd_counter++;
+		ret = dhd->wakelock_wd_counter;
+		DHD_WAKE_SPIN_UNLOCK(&dhd->wakelock_spinlock, flags);
+	}
+	return ret;
+}
+
+int dhd_os_wd_wake_unlock(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	unsigned long flags;
+	int ret = 0;
+
+	if (dhd) {
+		DHD_WAKE_SPIN_LOCK(&dhd->wakelock_spinlock, flags);
+		if (dhd->wakelock_wd_counter > 0) {
+			dhd->wakelock_wd_counter = 0;
+			if (!dhd->waive_wakelock) {
+#ifdef CONFIG_HAS_WAKELOCK
+				dhd_wake_unlock(dhd->wl_wdwake);
+#endif
+			}
+		}
+		DHD_WAKE_SPIN_UNLOCK(&dhd->wakelock_spinlock, flags);
+	}
+	return ret;
+}
+
+#ifdef BCMPCIE_OOB_HOST_WAKE
+void
+dhd_os_oob_irq_wake_lock_timeout(dhd_pub_t *pub, int val)
+{
+#ifdef CONFIG_HAS_WAKELOCK
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		dhd_wake_lock_timeout(dhd->wl_intrwake, msecs_to_jiffies(val));
+	}
+#endif /* CONFIG_HAS_WAKELOCK */
+}
+
+void
+dhd_os_oob_irq_wake_unlock(dhd_pub_t *pub)
+{
+#ifdef CONFIG_HAS_WAKELOCK
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		/* if wl_intrwake is active, unlock it */
+		if (dhd_wake_lock_active(dhd->wl_intrwake)) {
+			dhd_wake_unlock(dhd->wl_intrwake);
+		}
+	}
+#endif /* CONFIG_HAS_WAKELOCK */
+}
+#endif /* BCMPCIE_OOB_HOST_WAKE */
+
+#ifdef DHD_USE_SCAN_WAKELOCK
+void
+dhd_os_scan_wake_lock_timeout(dhd_pub_t *pub, int val)
+{
+#ifdef CONFIG_HAS_WAKELOCK
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		dhd_wake_lock_timeout(dhd->wl_scanwake, msecs_to_jiffies(val));
+	}
+#endif /* CONFIG_HAS_WAKELOCK */
+}
+
+void
+dhd_os_scan_wake_unlock(dhd_pub_t *pub)
+{
+#ifdef CONFIG_HAS_WAKELOCK
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		/* if wl_scanwake is active, unlock it */
+		if (dhd_wake_lock_active(dhd->wl_scanwake)) {
+			dhd_wake_unlock(dhd->wl_scanwake);
+		}
+	}
+#endif /* CONFIG_HAS_WAKELOCK */
+}
+#endif /* DHD_USE_SCAN_WAKELOCK */
+
+/* waive wakelocks for operations such as IOVARs in suspend function, must be closed
+ * by a paired function call to dhd_wakelock_restore. returns current wakelock counter
+ */
+int dhd_os_wake_lock_waive(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	unsigned long flags;
+	int ret = 0;
+
+	if (dhd && (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT)) {
+		DHD_WAKE_SPIN_LOCK(&dhd->wakelock_spinlock, flags);
+
+		/* dhd_wakelock_waive/dhd_wakelock_restore must be paired */
+		if (dhd->waive_wakelock == FALSE) {
+#ifdef DHD_TRACE_WAKE_LOCK
+			if (atomic_read(&trace_wklock_onoff)) {
+				STORE_WKLOCK_RECORD(DHD_WAIVE_LOCK);
+			}
+#endif /* DHD_TRACE_WAKE_LOCK */
+			/* record current lock status */
+			dhd->wakelock_before_waive = dhd->wakelock_counter;
+			dhd->waive_wakelock = TRUE;
+		}
+		ret = dhd->wakelock_wd_counter;
+		DHD_WAKE_SPIN_UNLOCK(&dhd->wakelock_spinlock, flags);
+	}
+	return ret;
+}
+
+int dhd_os_wake_lock_restore(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	unsigned long flags;
+	int ret = 0;
+
+	if (!dhd)
+		return 0;
+	if ((dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT) == 0)
+		return 0;
+
+	DHD_WAKE_SPIN_LOCK(&dhd->wakelock_spinlock, flags);
+
+	/* dhd_wakelock_waive/dhd_wakelock_restore must be paired */
+	if (!dhd->waive_wakelock)
+		goto exit;
+
+	dhd->waive_wakelock = FALSE;
+	/* if somebody else acquires wakelock between dhd_wakelock_waive/dhd_wakelock_restore,
+	 * we need to make it up by calling dhd_wake_lock or pm_stay_awake. or if somebody releases
+	 * the lock in between, do the same by calling dhd_wake_unlock or pm_relax
+	 */
+#ifdef DHD_TRACE_WAKE_LOCK
+	if (atomic_read(&trace_wklock_onoff)) {
+		STORE_WKLOCK_RECORD(DHD_RESTORE_LOCK);
+	}
+#endif /* DHD_TRACE_WAKE_LOCK */
+
+	if (dhd->wakelock_before_waive == 0 && dhd->wakelock_counter > 0) {
+#ifdef CONFIG_HAS_WAKELOCK
+		dhd_wake_lock(dhd->wl_wifi);
+#elif defined(BCMSDIO)
+		dhd_bus_dev_pm_stay_awake(&dhd->pub);
+#endif
+	} else if (dhd->wakelock_before_waive > 0 && dhd->wakelock_counter == 0) {
+#ifdef CONFIG_HAS_WAKELOCK
+		dhd_wake_unlock(dhd->wl_wifi);
+#elif defined(BCMSDIO)
+		dhd_bus_dev_pm_relax(&dhd->pub);
+#endif
+	}
+	dhd->wakelock_before_waive = 0;
+exit:
+	ret = dhd->wakelock_wd_counter;
+	DHD_WAKE_SPIN_UNLOCK(&dhd->wakelock_spinlock, flags);
+	return ret;
+}
+
+void dhd_os_wake_lock_init(struct dhd_info *dhd)
+{
+	DHD_TRACE(("%s: initialize wake_lock_counters\n", __FUNCTION__));
+	dhd->wakelock_counter = 0;
+	dhd->wakelock_rx_timeout_enable = 0;
+	dhd->wakelock_ctrl_timeout_enable = 0;
+	/* wakelocks prevent a system from going into a low power state */
+#ifdef CONFIG_HAS_WAKELOCK
+	dhd_wake_lock_init(dhd->wl_wifi, dhd_bus_to_dev(dhd->pub.bus), "wlan_wake");
+	dhd_wake_lock_init(dhd->wl_rxwake, dhd_bus_to_dev(dhd->pub.bus), "wlan_rx_wake");
+	dhd_wake_lock_init(dhd->wl_ctrlwake, dhd_bus_to_dev(dhd->pub.bus), "wlan_ctrl_wake");
+	dhd_wake_lock_init(dhd->wl_evtwake, dhd_bus_to_dev(dhd->pub.bus), "wlan_evt_wake");
+	dhd_wake_lock_init(dhd->wl_pmwake, dhd_bus_to_dev(dhd->pub.bus), "wlan_pm_wake");
+	dhd_wake_lock_init(dhd->wl_txflwake, dhd_bus_to_dev(dhd->pub.bus), "wlan_txfl_wake");
+#ifdef BCMPCIE_OOB_HOST_WAKE
+	dhd_wake_lock_init(dhd->wl_intrwake, dhd_bus_to_dev(dhd->pub.bus), "wlan_oob_irq_wake");
+#endif /* BCMPCIE_OOB_HOST_WAKE */
+#ifdef DHD_USE_SCAN_WAKELOCK
+	dhd_wake_lock_init(dhd->wl_scanwake, dhd_bus_to_dev(dhd->pub.bus), "wlan_scan_wake");
+#endif /* DHD_USE_SCAN_WAKELOCK */
+	dhd_wake_lock_init(dhd->wl_nanwake, dhd_bus_to_dev(dhd->pub.bus), "wlan_nan_wake");
+#endif /* CONFIG_HAS_WAKELOCK */
+#ifdef DHD_TRACE_WAKE_LOCK
+	dhd_wk_lock_trace_init(dhd);
+#endif /* DHD_TRACE_WAKE_LOCK */
+}
+
+void dhd_os_wake_lock_destroy(struct dhd_info *dhd)
+{
+	DHD_TRACE(("%s: deinit wake_lock_counters\n", __FUNCTION__));
+#ifdef CONFIG_HAS_WAKELOCK
+	dhd->wakelock_counter = 0;
+	dhd->wakelock_rx_timeout_enable = 0;
+	dhd->wakelock_ctrl_timeout_enable = 0;
+	dhd_wake_lock_destroy(dhd->wl_wifi);
+	dhd_wake_lock_destroy(dhd->wl_rxwake);
+	dhd_wake_lock_destroy(dhd->wl_ctrlwake);
+	dhd_wake_lock_destroy(dhd->wl_evtwake);
+	dhd_wake_lock_destroy(dhd->wl_pmwake);
+	dhd_wake_lock_destroy(dhd->wl_txflwake);
+#ifdef BCMPCIE_OOB_HOST_WAKE
+	dhd_wake_lock_destroy(dhd->wl_intrwake);
+#endif /* BCMPCIE_OOB_HOST_WAKE */
+#ifdef DHD_USE_SCAN_WAKELOCK
+	dhd_wake_lock_destroy(dhd->wl_scanwake);
+#endif /* DHD_USE_SCAN_WAKELOCK */
+	dhd_wake_lock_destroy(dhd->wl_nanwake);
+#ifdef DHD_TRACE_WAKE_LOCK
+	dhd_wk_lock_trace_deinit(dhd);
+#endif /* DHD_TRACE_WAKE_LOCK */
+#else /* !CONFIG_HAS_WAKELOCK */
+	if (dhd->wakelock_counter > 0) {
+		DHD_ERROR(("%s: wake lock count=%d\n",
+			__FUNCTION__, dhd->wakelock_counter));
+		while (dhd_os_wake_unlock(&dhd->pub));
+	}
+#endif /* CONFIG_HAS_WAKELOCK */
+}
+
+bool dhd_os_check_if_up(dhd_pub_t *pub)
+{
+	if (!pub)
+		return FALSE;
+	return pub->up;
+}
+
+/* function to collect firmware, chip id and chip version info */
+void dhd_set_version_info(dhd_pub_t *dhdp, char *fw)
+{
+	int i;
+
+	i = snprintf(info_string, sizeof(info_string),
+		"  Driver: %s\n%s  Firmware: %s\n%s  CLM: %s ",
+		EPI_VERSION_STR,
+		DHD_LOG_PREFIXS, fw,
+		DHD_LOG_PREFIXS, clm_version);
+	printf("%s\n", info_string);
+
+	if (!dhdp)
+		return;
+
+	i += snprintf(&info_string[i], sizeof(info_string) - i,
+		"\n%s  Chip: %x Rev %x", DHD_LOG_PREFIXS, dhd_conf_get_chip(dhdp),
+		dhd_conf_get_chiprev(dhdp));
+#if defined(USE_CID_CHECK)
+	i += snprintf(&info_string[i], sizeof(info_string) - i,
+		" VID %x", cur_vid_info);
+#endif /* USE_CID_CHECK */
+}
+
+int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd)
+{
+	int ifidx;
+	int ret = 0;
+	dhd_info_t *dhd = NULL;
+
+	if (!net || !DEV_PRIV(net)) {
+		DHD_ERROR(("%s invalid parameter net %p dev_priv %p\n",
+			__FUNCTION__, net, DEV_PRIV(net)));
+		return -EINVAL;
+	}
+
+	dhd = DHD_DEV_INFO(net);
+	if (!dhd)
+		return -EINVAL;
+
+	ifidx = dhd_net2idx(dhd, net);
+	if (ifidx == DHD_BAD_IF) {
+		DHD_ERROR(("%s bad ifidx\n", __FUNCTION__));
+		return -ENODEV;
+	}
+
+	DHD_OS_WAKE_LOCK(&dhd->pub);
+
+	ret = dhd_wl_ioctl(&dhd->pub, ifidx, ioc, ioc->buf, ioc->len);
+	dhd_check_hang(net, &dhd->pub, ret);
+
+	DHD_OS_WAKE_UNLOCK(&dhd->pub);
+
+	return ret;
+}
+
+bool dhd_os_check_hang(dhd_pub_t *dhdp, int ifidx, int ret)
+{
+	struct net_device *net;
+
+	net = dhd_idx2net(dhdp, ifidx);
+	if (!net) {
+		DHD_ERROR(("%s : Invalid index : %d\n", __FUNCTION__, ifidx));
+		return -EINVAL;
+	}
+
+	return dhd_check_hang(net, dhdp, ret);
+}
+
+/* Return instance */
+int dhd_get_instance(dhd_pub_t *dhdp)
+{
+	return dhdp->info->unit;
+}
+
+#if defined(WL_CFG80211) && defined(SUPPORT_DEEP_SLEEP)
+#define MAX_TRY_CNT             5 /* Number of tries to disable deepsleep */
+int dhd_deepsleep(struct net_device *dev, int flag)
+{
+	char iovbuf[20];
+	uint powervar = 0;
+	dhd_info_t *dhd;
+	dhd_pub_t *dhdp;
+	int cnt = 0;
+	int ret = 0;
+
+	dhd = DHD_DEV_INFO(dev);
+	dhdp = &dhd->pub;
+
+	switch (flag) {
+		case 1 :  /* Deepsleep on */
+			DHD_ERROR(("[WiFi] Deepsleep On\n"));
+			/* give some time to sysioc_work before deepsleep */
+			OSL_SLEEP(200);
+#ifdef PKT_FILTER_SUPPORT
+		/* disable pkt filter */
+		dhd_enable_packet_filter(0, dhdp);
+#endif /* PKT_FILTER_SUPPORT */
+			/* Disable MPC */
+			powervar = 0;
+			ret = dhd_iovar(dhdp, 0, "mpc", (char *)&powervar, sizeof(powervar), NULL,
+					0, TRUE);
+			if (ret) {
+				DHD_ERROR(("%s: mpc failed:%d\n", __FUNCTION__, ret));
+			}
+			/* Enable Deepsleep */
+			powervar = 1;
+			ret = dhd_iovar(dhdp, 0, "deepsleep", (char *)&powervar, sizeof(powervar),
+					NULL, 0, TRUE);
+			if (ret) {
+				DHD_ERROR(("%s: deepsleep failed:%d\n", __FUNCTION__, ret));
+			}
+			break;
+
+		case 0: /* Deepsleep Off */
+			DHD_ERROR(("[WiFi] Deepsleep Off\n"));
+
+			/* Disable Deepsleep */
+			for (cnt = 0; cnt < MAX_TRY_CNT; cnt++) {
+				powervar = 0;
+				ret = dhd_iovar(dhdp, 0, "deepsleep", (char *)&powervar,
+						sizeof(powervar), NULL, 0, TRUE);
+				if (ret) {
+					DHD_ERROR(("%s: deepsleep failed:%d\n", __FUNCTION__, ret));
+				}
+
+				ret = dhd_iovar(dhdp, 0, "deepsleep", (char *)&powervar,
+						sizeof(powervar), iovbuf, sizeof(iovbuf), FALSE);
+				if (ret < 0) {
+					DHD_ERROR(("the error of dhd deepsleep status"
+						" ret value :%d\n", ret));
+				} else {
+					if (!(*(int *)iovbuf)) {
+						DHD_ERROR(("deepsleep mode is 0,"
+							" count: %d\n", cnt));
+						break;
+					}
+				}
+			}
+
+			/* Enable MPC */
+			powervar = 1;
+			ret = dhd_iovar(dhdp, 0, "mpc", (char *)&powervar, sizeof(powervar),
+					NULL, 0, TRUE);
+			if (ret) {
+				DHD_ERROR(("%s: mpc failed:%d\n", __FUNCTION__, ret));
+			}
+			break;
+	}
+
+	return 0;
+}
+#endif /* WL_CFG80211 && SUPPORT_DEEP_SLEEP */
+
+#ifdef PROP_TXSTATUS
+
+void dhd_wlfc_plat_init(void *dhd)
+{
+#ifdef USE_DYNAMIC_F2_BLKSIZE
+	dhdsdio_func_blocksize((dhd_pub_t *)dhd, 2, sd_f2_blocksize);
+#endif /* USE_DYNAMIC_F2_BLKSIZE */
+	return;
+}
+
+void dhd_wlfc_plat_deinit(void *dhd)
+{
+#ifdef USE_DYNAMIC_F2_BLKSIZE
+	dhdsdio_func_blocksize((dhd_pub_t *)dhd, 2, sd_f2_blocksize);
+#endif /* USE_DYNAMIC_F2_BLKSIZE */
+	return;
+}
+
+bool dhd_wlfc_skip_fc(void * dhdp, uint8 idx)
+{
+#ifdef SKIP_WLFC_ON_CONCURRENT
+
+#ifdef WL_CFG80211
+	struct net_device * net =  dhd_idx2net((dhd_pub_t *)dhdp, idx);
+	if (net)
+	/* enable flow control in vsdb mode */
+	return !(wl_cfg80211_is_concurrent_mode(net));
+#else
+	return TRUE; /* skip flow control */
+#endif /* WL_CFG80211 */
+
+#else
+	return FALSE;
+#endif /* SKIP_WLFC_ON_CONCURRENT */
+	return FALSE;
+}
+#endif /* PROP_TXSTATUS */
+
+#ifdef BCMDBGFS
+#include <linux/debugfs.h>
+
+typedef struct dhd_dbgfs {
+	struct dentry	*debugfs_dir;
+	struct dentry	*debugfs_mem;
+	dhd_pub_t	*dhdp;
+	uint32		size;
+} dhd_dbgfs_t;
+
+dhd_dbgfs_t g_dbgfs;
+
+extern uint32 dhd_readregl(void *bp, uint32 addr);
+extern uint32 dhd_writeregl(void *bp, uint32 addr, uint32 data);
+
+static int
+dhd_dbg_state_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t
+dhd_dbg_state_read(struct file *file, char __user *ubuf,
+                       size_t count, loff_t *ppos)
+{
+	ssize_t rval;
+	uint32 tmp;
+	loff_t pos = *ppos;
+	size_t ret;
+
+	if (pos < 0)
+		return -EINVAL;
+	if (pos >= g_dbgfs.size || !count)
+		return 0;
+	if (count > g_dbgfs.size - pos)
+		count = g_dbgfs.size - pos;
+
+	/* XXX: The user can request any length they want, but they are getting 4 bytes */
+	/* Basically enforce aligned 4 byte reads. It's up to the user to work out the details */
+	tmp = dhd_readregl(g_dbgfs.dhdp->bus, file->f_pos & (~3));
+
+	ret = copy_to_user(ubuf, &tmp, 4);
+	if (ret == count)
+		return -EFAULT;
+
+	count -= ret;
+	*ppos = pos + count;
+	rval = count;
+
+	return rval;
+}
+
+static ssize_t
+dhd_debugfs_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos)
+{
+	loff_t pos = *ppos;
+	size_t ret;
+	uint32 buf;
+
+	if (pos < 0)
+		return -EINVAL;
+	if (pos >= g_dbgfs.size || !count)
+		return 0;
+	if (count > g_dbgfs.size - pos)
+		count = g_dbgfs.size - pos;
+
+	ret = copy_from_user(&buf, ubuf, sizeof(uint32));
+	if (ret == count)
+		return -EFAULT;
+
+	/* XXX: The user can request any length they want, but they are getting 4 bytes */
+	/* Basically enforce aligned 4 byte writes. It's up to the user to work out the details */
+	dhd_writeregl(g_dbgfs.dhdp->bus, file->f_pos & (~3), buf);
+
+	return count;
+}
+
+loff_t
+dhd_debugfs_lseek(struct file *file, loff_t off, int whence)
+{
+	loff_t pos = -1;
+
+	switch (whence) {
+		case 0:
+			pos = off;
+			break;
+		case 1:
+			pos = file->f_pos + off;
+			break;
+		case 2:
+			pos = g_dbgfs.size - off;
+	}
+	return (pos < 0 || pos > g_dbgfs.size) ? -EINVAL : (file->f_pos = pos);
+}
+
+static const struct file_operations dhd_dbg_state_ops = {
+	.read   = dhd_dbg_state_read,
+	.write	= dhd_debugfs_write,
+	.open   = dhd_dbg_state_open,
+	.llseek	= dhd_debugfs_lseek
+};
+
+static void dhd_dbgfs_create(void)
+{
+	if (g_dbgfs.debugfs_dir) {
+		g_dbgfs.debugfs_mem = debugfs_create_file("mem", 0644, g_dbgfs.debugfs_dir,
+			NULL, &dhd_dbg_state_ops);
+	}
+}
+
+void dhd_dbgfs_init(dhd_pub_t *dhdp)
+{
+	g_dbgfs.dhdp = dhdp;
+	g_dbgfs.size = 0x20000000; /* Allow access to various cores regs */
+
+	g_dbgfs.debugfs_dir = debugfs_create_dir("dhd", 0);
+	if (IS_ERR(g_dbgfs.debugfs_dir)) {
+		g_dbgfs.debugfs_dir = NULL;
+		return;
+	}
+
+	dhd_dbgfs_create();
+
+	return;
+}
+
+void dhd_dbgfs_remove(void)
+{
+	debugfs_remove(g_dbgfs.debugfs_mem);
+	debugfs_remove(g_dbgfs.debugfs_dir);
+
+	bzero((unsigned char *) &g_dbgfs, sizeof(g_dbgfs));
+}
+#endif /* BCMDBGFS */
+
+#ifdef CUSTOM_SET_CPUCORE
+void dhd_set_cpucore(dhd_pub_t *dhd, int set)
+{
+	int e_dpc = 0, e_rxf = 0, retry_set = 0;
+
+	if (!(dhd->chan_isvht80)) {
+		DHD_ERROR(("%s: chan_status(%d) cpucore!!!\n", __FUNCTION__, dhd->chan_isvht80));
+		return;
+	}
+
+	if (DPC_CPUCORE && dhd->current_dpc) {
+		do {
+			if (set == TRUE) {
+				e_dpc = set_cpus_allowed_ptr(dhd->current_dpc,
+					cpumask_of(DPC_CPUCORE));
+			} else {
+				e_dpc = set_cpus_allowed_ptr(dhd->current_dpc,
+					cpumask_of(PRIMARY_CPUCORE));
+			}
+			if (retry_set++ > MAX_RETRY_SET_CPUCORE) {
+				DHD_ERROR(("%s: dpc(%d) invalid cpu!\n", __FUNCTION__, e_dpc));
+				return;
+			}
+			if (e_dpc < 0)
+				OSL_SLEEP(1);
+		} while (e_dpc < 0);
+	}
+	if (RXF_CPUCORE && dhd->current_rxf) {
+		do {
+			if (set == TRUE) {
+				e_rxf = set_cpus_allowed_ptr(dhd->current_rxf,
+					cpumask_of(RXF_CPUCORE));
+			} else {
+				e_rxf = set_cpus_allowed_ptr(dhd->current_rxf,
+					cpumask_of(PRIMARY_CPUCORE));
+			}
+			if (retry_set++ > MAX_RETRY_SET_CPUCORE) {
+				DHD_ERROR(("%s: rxf(%d) invalid cpu!\n", __FUNCTION__, e_rxf));
+				return;
+			}
+			if (e_rxf < 0)
+				OSL_SLEEP(1);
+		} while (e_rxf < 0);
+	}
+	DHD_TRACE(("%s: set(%d) cpucore success!\n", __FUNCTION__, set));
+
+	return;
+}
+#endif /* CUSTOM_SET_CPUCORE */
+
+#ifdef DHD_MCAST_REGEN
+/* Get interface specific ap_isolate configuration */
+int dhd_get_mcast_regen_bss_enable(dhd_pub_t *dhdp, uint32 idx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(idx < DHD_MAX_IFS);
+
+	ifp = dhd->iflist[idx];
+
+	return ifp->mcast_regen_bss_enable;
+}
+
+/* Set interface specific mcast_regen configuration */
+int dhd_set_mcast_regen_bss_enable(dhd_pub_t *dhdp, uint32 idx, int val)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(idx < DHD_MAX_IFS);
+
+	ifp = dhd->iflist[idx];
+
+	ifp->mcast_regen_bss_enable = val;
+
+	/* Disable rx_pkt_chain feature for interface, if mcast_regen feature
+	 * is enabled
+	 */
+	dhd_update_rx_pkt_chainable_state(dhdp, idx);
+	return BCME_OK;
+}
+#endif	/* DHD_MCAST_REGEN */
+
+/* Get interface specific ap_isolate configuration */
+int dhd_get_ap_isolate(dhd_pub_t *dhdp, uint32 idx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(idx < DHD_MAX_IFS);
+
+	ifp = dhd->iflist[idx];
+
+	return ifp->ap_isolate;
+}
+
+/* Set interface specific ap_isolate configuration */
+int dhd_set_ap_isolate(dhd_pub_t *dhdp, uint32 idx, int val)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(idx < DHD_MAX_IFS);
+
+	ifp = dhd->iflist[idx];
+
+	if (ifp)
+		ifp->ap_isolate = val;
+
+	return 0;
+}
+
+#ifdef DHD_FW_COREDUMP
+bool dhd_memdump_is_scheduled(dhd_pub_t *dhdp)
+{
+	return dhdp->info->scheduled_memdump;
+}
+
+void dhd_schedule_memdump(dhd_pub_t *dhdp, uint8 *buf, uint32 size)
+{
+	dhd_dump_t *dump = NULL;
+	unsigned long flags = 0;
+	dhd_info_t *dhd_info = NULL;
+#if defined(DHD_LOG_DUMP) && !defined(DHD_DUMP_FILE_WRITE_FROM_KERNEL)
+	log_dump_type_t type = DLD_BUF_TYPE_ALL;
+#endif /* DHD_LOG_DUMP && !DHD_DUMP_FILE_WRITE_FROM_KERNEL */
+
+	dhd_info = (dhd_info_t *)dhdp->info;
+	dump = (dhd_dump_t *)MALLOC(dhdp->osh, sizeof(dhd_dump_t));
+	if (dump == NULL) {
+		DHD_ERROR(("%s: dhd dump memory allocation failed\n", __FUNCTION__));
+		return;
+	}
+	dump->buf = buf;
+	dump->bufsize = size;
+#ifdef BCMPCIE
+	dhd_get_hscb_info(dhdp, (void*)(&dump->hscb_buf),
+			(uint32 *)(&dump->hscb_bufsize));
+#else
+	dump->hscb_bufsize = 0;
+#endif /* BCMPCIE */
+
+#ifdef DHD_LOG_DUMP
+	dhd_print_buf_addr(dhdp, "memdump", buf, size);
+#if !defined(DHD_DUMP_FILE_WRITE_FROM_KERNEL)
+	/* Print out buffer infomation */
+	dhd_log_dump_buf_addr(dhdp, &type);
+#endif /* !DHD_DUMP_FILE_WRITE_FROM_KERNEL */
+#endif /* DHD_LOG_DUMP */
+
+	if ((dhdp->memdump_type == DUMP_TYPE_DONGLE_INIT_FAILURE) ||
+		(dhdp->memdump_type == DUMP_TYPE_DUE_TO_BT) ||
+		(dhdp->memdump_type == DUMP_TYPE_SMMU_FAULT) ||
+		(dhdp->memdump_type == DUMP_TYPE_DONGLE_TRAP_DURING_WIFI_ONOFF))
+	{
+		dhd_info->scheduled_memdump = FALSE;
+		dhd_mem_dump((void *)dhdp->info, (void *)dump, 0);
+		/* No need to collect debug dump for init failure */
+		if (dhdp->memdump_type == DUMP_TYPE_DONGLE_INIT_FAILURE ||
+			dhdp->memdump_type == DUMP_TYPE_DONGLE_TRAP_DURING_WIFI_ONOFF) {
+			return;
+		}
+#ifdef DHD_LOG_DUMP
+		{
+			log_dump_type_t *flush_type = NULL;
+			/* for dongle init fail cases, 'dhd_mem_dump' does
+			 * not call 'dhd_log_dump', so call it here.
+			*/
+			flush_type = MALLOCZ(dhdp->osh,
+				sizeof(log_dump_type_t));
+			if (flush_type) {
+				*flush_type = DLD_BUF_TYPE_ALL;
+				DHD_ERROR(("%s: calling log dump.. \n", __FUNCTION__));
+				dhd_log_dump(dhdp->info, flush_type, 0);
+			}
+		}
+#endif /* DHD_LOG_DUMP */
+		return;
+	}
+
+	dhd_info->scheduled_memdump = TRUE;
+
+	/* bus busy bit for mem dump will be cleared in mem dump
+	* work item context, after mem dump file is written
+	*/
+	DHD_GENERAL_LOCK(dhdp, flags);
+	DHD_BUS_BUSY_SET_IN_MEMDUMP(dhdp);
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+	DHD_ERROR(("%s: scheduling mem dump.. \n", __FUNCTION__));
+	dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq, (void *)dump,
+		DHD_WQ_WORK_SOC_RAM_DUMP, dhd_mem_dump, DHD_WQ_WORK_PRIORITY_HIGH);
+}
+#ifdef DHD_SSSR_DUMP
+#define DUMP_SSSR_DUMP_MAX_COUNT	8
+#endif
+#ifdef DHD_COREDUMP
+#ifdef DHD_LINUX_STD_FW_API
+char map_path[PATH_MAX] = DHD_MAP_NAME;
+#else
+#ifndef CONFIG_BCMDHD_MAP_PATH
+char map_path[PATH_MAX] = PLATFORM_PATH"rtecdc.map";
+#else
+char map_path[PATH_MAX] = VENDOR_PATH CONFIG_BCMDHD_MAP_PATH;
+#endif /* CONFIG_BCMDHD_MAP_PATH */
+#endif /* DHD_LINUX_STD_FW_API */
+extern int dhd_collect_coredump(dhd_pub_t *dhdp, dhd_dump_t *dump);
+#endif /* DHD_COREDUMP */
+
+static void
+dhd_mem_dump(void *handle, void *event_info, u8 event)
+{
+	dhd_info_t *dhd = handle;
+	dhd_pub_t *dhdp = NULL;
+	unsigned long flags = 0;
+#if defined(DHD_LOG_DUMP)
+#if defined(DHD_FILE_DUMP_EVENT) || defined(DHD_DEBUGABILITY_DEBUG_DUMP)
+	log_dump_type_t type = DLD_BUF_TYPE_ALL;
+#endif /* DHD_FILE_DUMP_EVENT || DHD_DEBUGABILITY_DEBUG_DUMP */
+#endif /* DHD_LOG_DUMP */
+
+#if defined(DHD_FILE_DUMP_EVENT) || (defined(DHD_SSSR_COREDUMP) && \
+	defined(DHD_COREDUMP))
+	int ret = 0;
+#endif /* DHD_FILE_DUMP_EVENT || DHD_SSSR_COREDUMP && DHD_COREDUMP */
+	dhd_dump_t *dump = NULL;
+#ifdef DHD_COREDUMP
+	char pc_fn[DHD_FUNC_STR_LEN] = "\0";
+	char lr_fn[DHD_FUNC_STR_LEN] = "\0";
+	trap_t *tr;
+#endif /* DHD_COREDUMP */
+	uint32 memdump_type;
+
+	DHD_ERROR(("%s: ENTER \n", __FUNCTION__));
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	dhdp = &dhd->pub;
+	if (!dhdp) {
+		DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__));
+		return;
+	}
+	/* to keep it in case other memdump overwrites it */
+	memdump_type = dhdp->memdump_type;
+
+	DHD_GENERAL_LOCK(dhdp, flags);
+	if (DHD_BUS_CHECK_DOWN_OR_DOWN_IN_PROGRESS(dhdp)) {
+		DHD_GENERAL_UNLOCK(dhdp, flags);
+		DHD_ERROR(("%s: bus is down! can't collect mem dump. \n", __FUNCTION__));
+		goto exit;
+	}
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+
+	dump = (dhd_dump_t *)event_info;
+	if (!dump) {
+		DHD_ERROR(("%s: dump is NULL\n", __FUNCTION__));
+		goto exit;
+	}
+
+#ifdef DHD_SSSR_DUMP
+	DHD_ERROR(("%s: sssr_enab=%d dhdp->sssr_inited=%d dhdp->collect_sssr=%d\n",
+		__FUNCTION__, sssr_enab, dhdp->sssr_inited, dhdp->collect_sssr));
+	if (sssr_enab && dhdp->sssr_inited && dhdp->collect_sssr) {
+		uint32 arr_len[DUMP_SSSR_DUMP_MAX_COUNT];
+
+		if (fis_enab && dhdp->sssr_reg_info->rev3.fis_enab) {
+			int bcmerror = dhd_bus_fis_trigger(dhdp);
+
+			if (bcmerror == BCME_OK) {
+				dhd_bus_fis_dump(dhdp);
+			} else {
+				DHD_ERROR(("%s: FIS trigger failed: %d\n",
+					__FUNCTION__, bcmerror));
+			}
+		} else	{
+			DHD_ERROR(("%s: FIS not enabled (%d:%d), collect legacy sssr\n",
+				__FUNCTION__, fis_enab, dhdp->sssr_reg_info->rev3.fis_enab));
+			dhdpcie_sssr_dump(dhdp);
+		}
+#ifndef DHD_FIS_DUMP
+		/* Reset fis_enab flag after fis collection which was set for init failure debug */
+		fis_enab = FALSE;
+#endif /* DHD_FIS_DUMP */
+		/* Print sssr buffer address for debugging */
+		if (dhdp->sssr_dump_collected) {
+			dhdpcie_sssr_dump_get_before_after_len(dhdp, arr_len);
+		}
+	}
+#endif /* DHD_SSSR_DUMP */
+
+#ifdef DHD_SDTC_ETB_DUMP
+	if (dhdp->collect_sdtc) {
+		dhd_sdtc_etb_dump(dhdp);
+		dhdp->collect_sdtc = FALSE;
+	}
+#endif /* DHD_SDTC_ETB_DUMP */
+
+#if (defined(DHD_FILE_DUMP_EVENT) || defined(DHD_DEBUGABILITY_DEBUG_DUMP))
+	if (dhdp->memdump_enabled == DUMP_MEMONLY) {
+		DHD_ERROR(("%s: Force BUG_ON for memdump_enabled:%d\n",
+			__FUNCTION__, dhdp->memdump_enabled));
+		BUG_ON(1);
+	}
+
+#ifdef DHD_LOG_DUMP
+	if (dhd_log_flush(dhdp, &type) < 0) {
+		DHD_ERROR(("%s: Failed to flush Preserve/FW logs\n",
+			__FUNCTION__));
+	}
+#endif /* DHD_LOG_DUMP */
+
+#if defined(DHD_FILE_DUMP_EVENT)
+	ret = dhd_wait_for_file_dump(dhdp);
+	if (ret) {
+		DHD_ERROR(("%s: file_dump failed.\n", __FUNCTION__));
+#ifdef BOARD_HIKEY
+		/* For Hikey do force kernel write of socram if HAL dump fails */
+		if (write_dump_to_file(&dhd->pub, dump->buf, dump->bufsize, "mem_dump")) {
+			DHD_ERROR(("%s: writing SoC_RAM dump to the file failed\n", __FUNCTION__));
+		}
+#endif /* BOARD_HIKEY */
+	}
+	dhdp->skip_memdump_map_read = FALSE;
+#elif defined(DHD_DEBUGABILITY_DEBUG_DUMP)
+	dhd_debug_dump_to_ring(dhdp);
+#endif /* DHD_FILE_DUMP_EVENT */
+#endif /* (DHD_FILE_DUMP_EVENT || DHD_DEBUGABILITY_DEBUG_DUMP) */
+
+#ifdef DHD_COREDUMP
+	memset_s(dhdp->memdump_str, DHD_MEMDUMP_LONGSTR_LEN, 0, DHD_MEMDUMP_LONGSTR_LEN);
+
+	if (dhdp->dsack_hc_due_to_isr_delay) {
+		memdump_type = DUMP_TYPE_BY_DSACK_HC_DUE_TO_ISR_DELAY;
+	} else if (dhdp->dsack_hc_due_to_dpc_delay) {
+		memdump_type = DUMP_TYPE_BY_DSACK_HC_DUE_TO_DPC_DELAY;
+	}
+
+#ifdef DHD_LOG_DUMP
+	dhd_convert_memdump_type_to_str(memdump_type, dhdp->memdump_str,
+		DHD_MEMDUMP_LONGSTR_LEN, dhdp->debug_dump_subcmd);
+#endif /* DHD_LOG_DUMP */
+
+	if (memdump_type == DUMP_TYPE_DONGLE_TRAP &&
+		dhdp->dongle_trap_occured == TRUE) {
+		if (!dhdp->dsack_hc_due_to_isr_delay &&
+				!dhdp->dsack_hc_due_to_dpc_delay) {
+			tr = &dhdp->last_trap_info;
+			dhd_lookup_map(dhdp->osh, map_path,
+					ltoh32(tr->epc), pc_fn, ltoh32(tr->r14), lr_fn);
+			sprintf(&dhdp->memdump_str[strlen(dhdp->memdump_str)],
+				"_%.79s_%.79s", pc_fn, lr_fn);
+		}
+	}
+	DHD_ERROR(("%s: dump reason: %s\n", __FUNCTION__, dhdp->memdump_str));
+
+#ifdef DHD_SSSR_COREDUMP
+	ret = dhd_collect_coredump(dhdp, dump);
+	if (ret == BCME_ERROR) {
+		DHD_ERROR(("%s: dhd_collect_coredump() failed.\n", __FUNCTION__));
+		goto exit;
+	} else if (ret == BCME_UNSUPPORTED) {
+		DHD_LOG_MEM(("%s: Unable to collect SSSR dumps. Skip it.\n",
+			__FUNCTION__));
+	}
+#endif /* DHD_SSSR_COREDUMP */
+	if (memdump_type == DUMP_TYPE_BY_SYSDUMP) {
+		DHD_LOG_MEM(("%s: coredump is not supported for BY_SYSDUMP/non trap cases\n",
+			__FUNCTION__));
+	} else {
+		DHD_ERROR(("%s: writing SoC_RAM dump\n", __FUNCTION__));
+		if (wifi_platform_set_coredump(dhd->adapter, dump->buf,
+			dump->bufsize, dhdp->memdump_str)) {
+			DHD_ERROR(("%s: writing SoC_RAM dump failed\n", __FUNCTION__));
+#ifdef DHD_DEBUG_UART
+			dhd->pub.memdump_success = FALSE;
+#endif  /* DHD_DEBUG_UART */
+		}
+	}
+#endif /* DHD_COREDUMP */
+
+	/*
+	 * If kernel does not have file write access enabled
+	 * then skip writing dumps to files.
+	 * The dumps will be pushed to HAL layer which will
+	 * write into files
+	 */
+#ifdef DHD_DUMP_FILE_WRITE_FROM_KERNEL
+
+#ifdef D2H_MINIDUMP
+	/* dump minidump */
+	if (dhd_bus_is_minidump_enabled(dhdp)) {
+		dhd_d2h_minidump(&dhd->pub);
+	} else {
+		DHD_ERROR(("minidump is not enabled\n"));
+	}
+#endif /* D2H_MINIDUMP */
+
+	if (write_dump_to_file(&dhd->pub, dump->buf, dump->bufsize, "mem_dump")) {
+		DHD_ERROR(("%s: writing SoC_RAM dump to the file failed\n", __FUNCTION__));
+#ifdef DHD_DEBUG_UART
+		dhd->pub.memdump_success = FALSE;
+#endif	/* DHD_DEBUG_UART */
+	}
+
+	if (dump->hscb_buf && dump->hscb_bufsize) {
+		if (write_dump_to_file(&dhd->pub, dump->hscb_buf,
+			dump->hscb_bufsize, "mem_dump_hscb")) {
+			DHD_ERROR(("%s: writing HSCB dump to the file failed\n", __FUNCTION__));
+#ifdef DHD_DEBUG_UART
+			dhd->pub.memdump_success = FALSE;
+#endif	/* DHD_DEBUG_UART */
+		}
+	}
+
+#if !defined(DHD_PKT_LOGGING) && defined(DHD_LOG_DUMP)
+	clear_debug_dump_time(dhdp->debug_dump_time_str);
+#endif /* !DHD_PKT_LOGGING && DHD_LOG_DUMP */
+
+	/* directly call dhd_log_dump for debug_dump collection from the mem_dump work queue
+	* context, no need to schedule another work queue for log dump. In case of
+	* user initiated DEBUG_DUMP wpa_cli command (DUMP_TYPE_BY_SYSDUMP),
+	* cfg layer is itself scheduling the log_dump work queue.
+	* that path is not disturbed. If 'dhd_mem_dump' is called directly then we will not
+	* collect debug_dump as it may be called from non-sleepable context.
+	*/
+#ifdef DHD_LOG_DUMP
+	if (dhd->scheduled_memdump &&
+		memdump_type != DUMP_TYPE_BY_SYSDUMP) {
+		log_dump_type_t *flush_type = MALLOCZ(dhdp->osh,
+				sizeof(log_dump_type_t));
+		if (flush_type) {
+			*flush_type = DLD_BUF_TYPE_ALL;
+			DHD_ERROR(("%s: calling log dump.. \n", __FUNCTION__));
+			dhd_log_dump(dhd, flush_type, 0);
+		}
+	}
+#endif /* DHD_LOG_DUMP */
+
+	/* before calling bug on, wait for other logs to be dumped.
+	* we cannot wait in case dhd_mem_dump is called directly
+	* as it may not be from a sleepable context
+	*/
+	if (dhd->scheduled_memdump) {
+		uint bitmask = 0;
+		int timeleft = 0;
+#ifdef DHD_SSSR_DUMP
+		bitmask |= DHD_BUS_BUSY_IN_SSSRDUMP;
+#endif
+		if (bitmask != 0) {
+			DHD_ERROR(("%s: wait to clear dhd_bus_busy_state: 0x%x\n",
+				__FUNCTION__, dhdp->dhd_bus_busy_state));
+			timeleft = dhd_os_busbusy_wait_bitmask(dhdp,
+					&dhdp->dhd_bus_busy_state, bitmask, 0);
+			if ((timeleft == 0) || (timeleft == 1)) {
+				DHD_ERROR(("%s: Timed out dhd_bus_busy_state=0x%x\n",
+					__FUNCTION__, dhdp->dhd_bus_busy_state));
+			}
+		}
+	}
+#endif /* DHD_DUMP_FILE_WRITE_FROM_KERNEL */
+
+	if (dhd->pub.memdump_enabled == DUMP_MEMFILE_BUGON &&
+#ifdef DHD_LOG_DUMP
+		memdump_type != DUMP_TYPE_BY_SYSDUMP &&
+#endif /* DHD_LOG_DUMP */
+		memdump_type != DUMP_TYPE_BY_USER &&
+#ifdef DHD_DEBUG_UART
+		dhd->pub.memdump_success == TRUE &&
+#endif	/* DHD_DEBUG_UART */
+#ifdef DNGL_EVENT_SUPPORT
+		memdump_type != DUMP_TYPE_DONGLE_HOST_EVENT &&
+#endif /* DNGL_EVENT_SUPPORT */
+		memdump_type != DUMP_TYPE_CFG_VENDOR_TRIGGERED) {
+#ifdef SHOW_LOGTRACE
+		/* Wait till logtrace context is flushed */
+		dhd_flush_logtrace_process(dhd);
+#endif /* SHOW_LOGTRACE */
+
+#ifdef EWP_EDL
+		cancel_delayed_work_sync(&dhd->edl_dispatcher_work);
+#endif
+
+		printf("%s\n", info_string);
+		printf("MAC %pM\n", &dhdp->mac);
+		DHD_ERROR(("%s: call BUG_ON \n", __FUNCTION__));
+#ifdef DHD_USE_WARN_RATHER_THAN_BUG_ON
+		WARN_ON(1);
+#else // DHD_USE_WARN_RATHER_THAN_BUG_ON
+//		BUG_ON(1);
+#endif // DHD_USE_WARN_RATHER_THAN_BUG_ON
+	}
+
+exit:
+	if (dump) {
+		MFREE(dhd->pub.osh, dump, sizeof(dhd_dump_t));
+	}
+	DHD_GENERAL_LOCK(dhdp, flags);
+	DHD_BUS_BUSY_CLEAR_IN_MEMDUMP(&dhd->pub);
+	dhd_os_busbusy_wake(dhdp);
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+	dhd->scheduled_memdump = FALSE;
+
+#ifdef OEM_ANDROID
+	if (dhdp->hang_was_pending) {
+		DHD_ERROR(("%s: Send pending HANG event...\n", __FUNCTION__));
+		dhd_os_send_hang_message(dhdp);
+		dhdp->hang_was_pending = 0;
+	}
+#endif /* OEM_ANDROID */
+	DHD_ERROR(("%s: EXIT \n", __FUNCTION__));
+
+	return;
+}
+#endif /* DHD_FW_COREDUMP */
+
+#ifdef D2H_MINIDUMP
+void
+dhd_d2h_minidump(dhd_pub_t *dhdp)
+{
+	char d2h_minidump[128];
+	dhd_dma_buf_t *minidump_buf;
+
+	minidump_buf = dhd_prot_get_minidump_buf(dhdp);
+	if (minidump_buf->va == NULL) {
+		DHD_ERROR(("%s: minidump_buf is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	/* Init file name */
+	memset(d2h_minidump, 0, sizeof(d2h_minidump));
+	snprintf(d2h_minidump, sizeof(d2h_minidump), "%s", "d2h_minidump");
+
+	if (write_dump_to_file(dhdp, (uint8 *)minidump_buf->va, minidump_buf->len, d2h_minidump)) {
+		DHD_ERROR(("%s: failed to dump d2h_minidump to file\n", __FUNCTION__));
+	}
+}
+#endif /* D2H_MINIDUMP */
+
+#ifdef DHD_SSSR_DUMP
+uint
+dhd_sssr_dig_buf_size(dhd_pub_t *dhdp)
+{
+	uint dig_buf_size = 0;
+
+	/* SSSR register information structure v0 and v1 shares most except dig_mem */
+	switch (dhdp->sssr_reg_info->rev2.version) {
+		case SSSR_REG_INFO_VER_3:
+			/* intentional fall through */
+		case SSSR_REG_INFO_VER_2 :
+			if ((dhdp->sssr_reg_info->rev2.length >
+			 OFFSETOF(sssr_reg_info_v2_t, dig_mem_info)) &&
+			 dhdp->sssr_reg_info->rev2.dig_mem_info.dig_sr_size) {
+				dig_buf_size = dhdp->sssr_reg_info->rev2.dig_mem_info.dig_sr_size;
+			}
+			break;
+		case SSSR_REG_INFO_VER_1 :
+			if (dhdp->sssr_reg_info->rev1.vasip_regs.vasip_sr_size) {
+				dig_buf_size = dhdp->sssr_reg_info->rev1.vasip_regs.vasip_sr_size;
+			} else if ((dhdp->sssr_reg_info->rev1.length >
+			 OFFSETOF(sssr_reg_info_v1_t, dig_mem_info)) &&
+			 dhdp->sssr_reg_info->rev1.dig_mem_info.dig_sr_size) {
+				dig_buf_size = dhdp->sssr_reg_info->rev1.dig_mem_info.dig_sr_size;
+			}
+			break;
+		case SSSR_REG_INFO_VER_0 :
+			if (dhdp->sssr_reg_info->rev0.vasip_regs.vasip_sr_size) {
+				dig_buf_size = dhdp->sssr_reg_info->rev0.vasip_regs.vasip_sr_size;
+			}
+			break;
+		default :
+			DHD_ERROR(("invalid sssr_reg_ver"));
+			return BCME_UNSUPPORTED;
+	}
+
+	return dig_buf_size;
+}
+
+uint
+dhd_sssr_dig_buf_addr(dhd_pub_t *dhdp)
+{
+	uint dig_buf_addr = 0;
+
+	/* SSSR register information structure v0 and v1 shares most except dig_mem */
+	switch (dhdp->sssr_reg_info->rev2.version) {
+		case SSSR_REG_INFO_VER_3 :
+			/* intentional fall through */
+		case SSSR_REG_INFO_VER_2 :
+			if ((dhdp->sssr_reg_info->rev2.length >
+			 OFFSETOF(sssr_reg_info_v2_t, dig_mem_info)) &&
+			 dhdp->sssr_reg_info->rev2.dig_mem_info.dig_sr_size) {
+				dig_buf_addr = dhdp->sssr_reg_info->rev2.dig_mem_info.dig_sr_addr;
+			}
+			break;
+		case SSSR_REG_INFO_VER_1 :
+			if (dhdp->sssr_reg_info->rev1.vasip_regs.vasip_sr_size) {
+				dig_buf_addr = dhdp->sssr_reg_info->rev1.vasip_regs.vasip_sr_addr;
+			} else if ((dhdp->sssr_reg_info->rev1.length >
+			 OFFSETOF(sssr_reg_info_v1_t, dig_mem_info)) &&
+			 dhdp->sssr_reg_info->rev1.dig_mem_info.dig_sr_size) {
+				dig_buf_addr = dhdp->sssr_reg_info->rev1.dig_mem_info.dig_sr_addr;
+			}
+			break;
+		case SSSR_REG_INFO_VER_0 :
+			if (dhdp->sssr_reg_info->rev0.vasip_regs.vasip_sr_size) {
+				dig_buf_addr = dhdp->sssr_reg_info->rev0.vasip_regs.vasip_sr_addr;
+			}
+			break;
+		default :
+			DHD_ERROR(("invalid sssr_reg_ver"));
+			return BCME_UNSUPPORTED;
+	}
+
+	return dig_buf_addr;
+}
+
+uint
+dhd_sssr_mac_buf_size(dhd_pub_t *dhdp, uint8 core_idx)
+{
+	uint mac_buf_size = 0;
+	uint8 num_d11cores;
+
+	num_d11cores = dhd_d11_slices_num_get(dhdp);
+
+	/* SSSR register information structure v0 and v1 shares most except dig_mem */
+	if (core_idx < num_d11cores) {
+		switch (dhdp->sssr_reg_info->rev2.version) {
+			case SSSR_REG_INFO_VER_3 :
+				/* intentional fall through */
+			case SSSR_REG_INFO_VER_2 :
+				mac_buf_size = dhdp->sssr_reg_info->rev2.mac_regs[core_idx].sr_size;
+				break;
+			case SSSR_REG_INFO_VER_1 :
+				mac_buf_size = dhdp->sssr_reg_info->rev1.mac_regs[core_idx].sr_size;
+				break;
+			case SSSR_REG_INFO_VER_0 :
+				mac_buf_size = dhdp->sssr_reg_info->rev0.mac_regs[core_idx].sr_size;
+				break;
+			default :
+				DHD_ERROR(("invalid sssr_reg_ver"));
+				return BCME_UNSUPPORTED;
+		}
+	}
+
+	return mac_buf_size;
+}
+
+uint
+dhd_sssr_mac_xmtaddress(dhd_pub_t *dhdp, uint8 core_idx)
+{
+	uint xmtaddress = 0;
+	uint8 num_d11cores;
+
+	num_d11cores = dhd_d11_slices_num_get(dhdp);
+
+	/* SSSR register information structure v0 and v1 shares most except dig_mem */
+	if (core_idx < num_d11cores) {
+		switch (dhdp->sssr_reg_info->rev2.version) {
+			case SSSR_REG_INFO_VER_3 :
+				/* intentional fall through */
+			case SSSR_REG_INFO_VER_2 :
+				xmtaddress = dhdp->sssr_reg_info->rev2.
+					mac_regs[core_idx].base_regs.xmtaddress;
+				break;
+			case SSSR_REG_INFO_VER_1 :
+				xmtaddress = dhdp->sssr_reg_info->rev1.
+					mac_regs[core_idx].base_regs.xmtaddress;
+				break;
+			case SSSR_REG_INFO_VER_0 :
+				xmtaddress = dhdp->sssr_reg_info->rev0.
+					mac_regs[core_idx].base_regs.xmtaddress;
+				break;
+			default :
+				DHD_ERROR(("invalid sssr_reg_ver"));
+				return BCME_UNSUPPORTED;
+		}
+	}
+
+	return xmtaddress;
+}
+
+uint
+dhd_sssr_mac_xmtdata(dhd_pub_t *dhdp, uint8 core_idx)
+{
+	uint xmtdata = 0;
+	uint8 num_d11cores;
+
+	num_d11cores = dhd_d11_slices_num_get(dhdp);
+
+	/* SSSR register information structure v0 and v1 shares most except dig_mem */
+	if (core_idx < num_d11cores) {
+		switch (dhdp->sssr_reg_info->rev2.version) {
+			case SSSR_REG_INFO_VER_3 :
+				/* intentional fall through */
+			case SSSR_REG_INFO_VER_2 :
+				xmtdata = dhdp->sssr_reg_info->rev2.
+					mac_regs[core_idx].base_regs.xmtdata;
+				break;
+			case SSSR_REG_INFO_VER_1 :
+				xmtdata = dhdp->sssr_reg_info->rev1.
+					mac_regs[core_idx].base_regs.xmtdata;
+				break;
+			case SSSR_REG_INFO_VER_0 :
+				xmtdata = dhdp->sssr_reg_info->rev0.
+					mac_regs[core_idx].base_regs.xmtdata;
+				break;
+			default :
+				DHD_ERROR(("invalid sssr_reg_ver"));
+				return BCME_UNSUPPORTED;
+		}
+	}
+
+	return xmtdata;
+}
+
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+int
+dhd_sssr_dump_dig_buf_before(void *dev, const void *user_buf, uint32 len)
+{
+	dhd_info_t *dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+	dhd_pub_t *dhdp = &dhd_info->pub;
+	int pos = 0, ret = BCME_ERROR;
+	uint dig_buf_size = 0;
+
+	dig_buf_size = dhd_sssr_dig_buf_size(dhdp);
+
+	if (dhdp->sssr_dig_buf_before && (dhdp->sssr_dump_mode == SSSR_DUMP_MODE_SSSR)) {
+		ret = dhd_export_debug_data((char *)dhdp->sssr_dig_buf_before,
+			NULL, user_buf, dig_buf_size, &pos);
+	}
+	return ret;
+}
+
+int
+dhd_sssr_dump_d11_buf_before(void *dev, const void *user_buf, uint32 len, int core)
+{
+	dhd_info_t *dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+	dhd_pub_t *dhdp = &dhd_info->pub;
+	int pos = 0, ret = BCME_ERROR;
+
+	if (dhdp->sssr_d11_before[core] &&
+		dhdp->sssr_d11_outofreset[core] &&
+		(dhdp->sssr_dump_mode == SSSR_DUMP_MODE_SSSR)) {
+		ret = dhd_export_debug_data((char *)dhdp->sssr_d11_before[core],
+			NULL, user_buf, len, &pos);
+	}
+	return ret;
+}
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+
+int
+dhd_sssr_dump_dig_buf_after(void *dev, const void *user_buf, uint32 len)
+{
+	dhd_info_t *dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+	dhd_pub_t *dhdp = &dhd_info->pub;
+	int pos = 0, ret = BCME_ERROR;
+	uint dig_buf_size = 0;
+
+	dig_buf_size = dhd_sssr_dig_buf_size(dhdp);
+
+	if (dhdp->sssr_dig_buf_after) {
+		ret = dhd_export_debug_data((char *)dhdp->sssr_dig_buf_after,
+			NULL, user_buf, dig_buf_size, &pos);
+	}
+	return ret;
+}
+
+int
+dhd_sssr_dump_d11_buf_after(void *dev, const void *user_buf, uint32 len, int core)
+{
+	dhd_info_t *dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+	dhd_pub_t *dhdp = &dhd_info->pub;
+	int pos = 0, ret = BCME_ERROR;
+
+	if (dhdp->sssr_d11_after[core] &&
+		dhdp->sssr_d11_outofreset[core]) {
+		ret = dhd_export_debug_data((char *)dhdp->sssr_d11_after[core],
+			NULL, user_buf, len, &pos);
+	}
+	return ret;
+}
+
+void
+dhd_sssr_dump_to_file(dhd_info_t* dhdinfo)
+{
+	dhd_info_t *dhd = dhdinfo;
+	dhd_pub_t *dhdp;
+	int i;
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+	char before_sr_dump[128];
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+	char after_sr_dump[128];
+	unsigned long flags = 0;
+	uint dig_buf_size = 0;
+	uint8 num_d11cores = 0;
+	uint d11_buf_size = 0;
+
+	DHD_ERROR(("%s: ENTER \n", __FUNCTION__));
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	dhdp = &dhd->pub;
+
+	DHD_GENERAL_LOCK(dhdp, flags);
+	DHD_BUS_BUSY_SET_IN_SSSRDUMP(dhdp);
+	if (DHD_BUS_CHECK_DOWN_OR_DOWN_IN_PROGRESS(dhdp)) {
+		DHD_GENERAL_UNLOCK(dhdp, flags);
+		DHD_ERROR(("%s: bus is down! can't collect sssr dump. \n", __FUNCTION__));
+		goto exit;
+	}
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+
+	num_d11cores = dhd_d11_slices_num_get(dhdp);
+
+	for (i = 0; i < num_d11cores; i++) {
+		/* Init file name */
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+		memset(before_sr_dump, 0, sizeof(before_sr_dump));
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+		memset(after_sr_dump, 0, sizeof(after_sr_dump));
+
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+		snprintf(before_sr_dump, sizeof(before_sr_dump), "%s_%d_%s",
+			"sssr_dump_core", i, "before_SR");
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+		snprintf(after_sr_dump, sizeof(after_sr_dump), "%s_%d_%s",
+			"sssr_dump_core", i, "after_SR");
+
+		d11_buf_size = dhd_sssr_mac_buf_size(dhdp, i);
+
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+		if (dhdp->sssr_d11_before[i] && dhdp->sssr_d11_outofreset[i] &&
+			(dhdp->sssr_dump_mode == SSSR_DUMP_MODE_SSSR)) {
+			if (write_dump_to_file(dhdp, (uint8 *)dhdp->sssr_d11_before[i],
+				d11_buf_size, before_sr_dump)) {
+				DHD_ERROR(("%s: writing SSSR MAIN dump before to the file failed\n",
+					__FUNCTION__));
+			}
+		}
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+
+		if (dhdp->sssr_d11_after[i] && dhdp->sssr_d11_outofreset[i]) {
+			if (write_dump_to_file(dhdp, (uint8 *)dhdp->sssr_d11_after[i],
+				d11_buf_size, after_sr_dump)) {
+				DHD_ERROR(("%s: writing SSSR AUX dump after to the file failed\n",
+					__FUNCTION__));
+			}
+		}
+	}
+
+	dig_buf_size = dhd_sssr_dig_buf_size(dhdp);
+
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+	if (dhdp->sssr_dig_buf_before && (dhdp->sssr_dump_mode == SSSR_DUMP_MODE_SSSR)) {
+		if (write_dump_to_file(dhdp, (uint8 *)dhdp->sssr_dig_buf_before,
+			dig_buf_size, "sssr_dump_dig_before_SR")) {
+			DHD_ERROR(("%s: writing SSSR Dig dump before to the file failed\n",
+				__FUNCTION__));
+		}
+	}
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+
+	if (dhdp->sssr_dig_buf_after) {
+		if (write_dump_to_file(dhdp, (uint8 *)dhdp->sssr_dig_buf_after,
+			dig_buf_size, "sssr_dump_dig_after_SR")) {
+			DHD_ERROR(("%s: writing SSSR Dig VASIP dump after to the file failed\n",
+			 __FUNCTION__));
+		}
+	}
+
+exit:
+	DHD_GENERAL_LOCK(dhdp, flags);
+	DHD_BUS_BUSY_CLEAR_IN_SSSRDUMP(dhdp);
+	dhd_os_busbusy_wake(dhdp);
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+}
+
+void
+dhd_write_sssr_dump(dhd_pub_t *dhdp, uint32 dump_mode)
+{
+#if defined(DHD_DUMP_FILE_WRITE_FROM_KERNEL)
+	dhdp->sssr_dump_mode = dump_mode;
+#endif /* DHD_DUMP_FILE_WRITE_FROM_KERNEL */
+
+	/*
+	 * If kernel does not have file write access enabled
+	 * then skip writing dumps to files.
+	 * The dumps will be pushed to HAL layer which will
+	 * write into files
+	 */
+#if !defined(DHD_DUMP_FILE_WRITE_FROM_KERNEL)
+	return;
+#else
+	/*
+	 * dhd_mem_dump -> dhd_sssr_dump -> dhd_write_sssr_dump
+	 * Without workqueue -
+	 * DUMP_TYPE_DONGLE_INIT_FAILURE/DUMP_TYPE_DUE_TO_BT/DUMP_TYPE_SMMU_FAULT
+	 * : These are called in own handler, not in the interrupt context
+	 * With workqueue - all other DUMP_TYPEs : dhd_mem_dump is called in workqueue
+	 * Thus, it doesn't neeed to dump SSSR in workqueue
+	 */
+	DHD_ERROR(("%s: writing sssr dump to file... \n", __FUNCTION__));
+	dhd_sssr_dump_to_file(dhdp->info);
+#endif /* !DHD_DUMP_FILE_WRITE_FROM_KERNEL */
+}
+#endif /* DHD_SSSR_DUMP */
+
+#ifdef DHD_SDTC_ETB_DUMP
+void
+dhd_sdtc_etb_dump(dhd_pub_t *dhd)
+{
+	etb_info_t etb_info;
+	uint8 *sdtc_etb_dump;
+	uint8 *sdtc_etb_mempool;
+	int ret = 0;
+
+	if (!dhd->sdtc_etb_inited) {
+		DHD_ERROR(("%s, SDTC ETB dump not supported\n", __FUNCTION__));
+		return;
+	}
+
+	bzero(&etb_info, sizeof(etb_info));
+
+	if ((ret = dhd_bus_get_etb_info(dhd, dhd->etb_addr_info.etbinfo_addr, &etb_info))) {
+		DHD_ERROR(("%s: failed to get etb info %d\n", __FUNCTION__, ret));
+		return;
+	}
+
+	if (etb_info.addr == (uint32)-1) {
+		DHD_ERROR(("%s: invalid etbinfo.addr 0x%x Hence donot collect SDTC ETB\n",
+			__FUNCTION__, etb_info.addr));
+		return;
+	}
+
+	if (etb_info.read_bytes == 0) {
+		DHD_ERROR(("%s ETB is of zero size. Hence donot collect SDTC ETB\n", __FUNCTION__));
+		return;
+	}
+
+	DHD_ERROR(("%s etb_info ver:%d len:%d rwp:%d etb_full:%d etb:addr:0x%x, len:%d\n",
+		__FUNCTION__, etb_info.version, etb_info.len,
+		etb_info.read_write_p, etb_info.etb_full,
+		etb_info.addr, etb_info.read_bytes));
+
+	/*
+	 * etb mempool format = etb_info + etb
+	 */
+	dhd->sdtc_etb_dump_len = etb_info.read_bytes + sizeof(etb_info);
+	if (dhd->sdtc_etb_dump_len > DHD_SDTC_ETB_MEMPOOL_SIZE) {
+		DHD_ERROR(("%s etb_dump_len: %d is more than the alloced %d.Hence cannot collect\n",
+			__FUNCTION__, dhd->sdtc_etb_dump_len, DHD_SDTC_ETB_MEMPOOL_SIZE));
+		return;
+	}
+	sdtc_etb_mempool = dhd->sdtc_etb_mempool;
+	memcpy(sdtc_etb_mempool, &etb_info, sizeof(etb_info));
+	sdtc_etb_dump = sdtc_etb_mempool + sizeof(etb_info);
+	if ((ret = dhd_bus_get_sdtc_etb(dhd, sdtc_etb_dump, etb_info.addr, etb_info.read_bytes))) {
+		DHD_ERROR(("%s: error to get SDTC ETB ret: %d\n", __FUNCTION__, ret));
+		return;
+	}
+
+	dhd_print_buf_addr(dhd, "sdtc_etb_dump", (uint8 *)sdtc_etb_mempool, dhd->sdtc_etb_dump_len);
+	/*
+	 * If kernel does not have file write access enabled
+	 * then skip writing dumps to files.
+	 * The dumps will be pushed to HAL layer which will
+	 * write into files
+	 */
+#ifdef DHD_DUMP_FILE_WRITE_FROM_KERNEL
+	if (write_dump_to_file(dhd, (uint8 *)sdtc_etb_mempool,
+		dhd->sdtc_etb_dump_len, "sdtc_etb_dump")) {
+		DHD_ERROR(("%s: failed to dump sdtc_etb to file\n",
+			__FUNCTION__));
+	}
+#endif /* DHD_DUMP_FILE_WRITE_FROM_KERNEL */
+}
+
+int
+dhd_sdtc_etb_hal_file_dump(void *dev, const void *user_buf, uint32 len)
+{
+	dhd_info_t *dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+	dhd_pub_t *dhdp = &dhd_info->pub;
+	int pos = 0, ret = BCME_ERROR;
+
+	if (dhdp->sdtc_etb_dump_len) {
+		ret = dhd_export_debug_data((char *)dhdp->sdtc_etb_mempool,
+			NULL, user_buf, dhdp->sdtc_etb_dump_len, &pos);
+	} else {
+		DHD_ERROR(("%s ETB is of zero size. Hence donot collect SDTC ETB\n", __FUNCTION__));
+	}
+	DHD_ERROR(("%s, done ret: %d\n", __FUNCTION__, ret));
+	return ret;
+}
+#endif /* DHD_SDTC_ETB_DUMP */
+
+/* This function writes data to the file pointed by fp, OR
+ * copies data to the user buffer sent by upper layer(HAL).
+ */
+int
+dhd_export_debug_data(void *mem_buf, void *fp, const void *user_buf, uint32 buf_len, void *pos)
+{
+	int ret = BCME_OK;
+#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
+	struct dhd_dbg_ring_buf *ring_buf;
+#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
+
+	if (fp) {
+		ret = dhd_vfs_write(fp, mem_buf, buf_len, (loff_t *)pos);
+		if (ret < 0) {
+			DHD_ERROR(("write file error, err = %d\n", ret));
+			goto exit;
+		}
+	} else if (user_buf) {
+#ifdef CONFIG_COMPAT
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0))
+		if (in_compat_syscall())
+#else
+		if (is_compat_task())
+#endif /* LINUX_VER >= 4.6 */
+		{
+			void * usr_ptr =  compat_ptr((uintptr_t) user_buf);
+			ret = copy_to_user((void *)((uintptr_t)usr_ptr + (*(int *)pos)),
+				mem_buf, buf_len);
+			if (ret) {
+				DHD_ERROR(("failed to copy into user buffer : %d\n", ret));
+				goto exit;
+			}
+		}
+		else
+#endif /* CONFIG_COMPAT */
+		{
+			ret = copy_to_user((void *)((uintptr_t)user_buf + (*(int *)pos)),
+				mem_buf, buf_len);
+			if (ret) {
+				DHD_ERROR(("failed to copy into user buffer : %d\n", ret));
+				goto exit;
+			}
+		}
+		(*(int *)pos) += buf_len;
+	}
+#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
+	else {
+		ring_buf = &g_ring_buf;
+		if (ring_buf->dhd_pub) {
+			ret = dhd_debug_dump_ring_push(ring_buf->dhd_pub, (*(int *)pos),
+				buf_len, mem_buf);
+			if (ret != BCME_OK) {
+				DHD_ERROR(("%s: ring push failed ret:%d\n", __func__, ret));
+			}
+		}
+	}
+#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
+exit:
+	return ret;
+}
+
+#ifdef BCM_ROUTER_DHD
+void dhd_schedule_trap_log_dump(dhd_pub_t *dhdp,
+	uint8 *buf, uint32 size)
+{
+	dhd_write_file_t *wf = NULL;
+	wf = (dhd_write_file_t *)MALLOC(dhdp->osh, sizeof(dhd_write_file_t));
+	if (wf == NULL) {
+		DHD_ERROR(("%s: dhd write file memory allocation failed\n", __FUNCTION__));
+		return;
+	}
+	snprintf(wf->file_path, sizeof(wf->file_path), "%s", "/tmp/failed_if.txt");
+	wf->file_flags = O_CREAT | O_WRONLY | O_SYNC;
+	wf->buf = buf;
+	wf->bufsize = size;
+	dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq, (void *)wf,
+		DHD_WQ_WORK_INFORM_DHD_MON, dhd_inform_dhd_monitor_handler,
+		DHD_WQ_WORK_PRIORITY_HIGH);
+}
+
+/* Returns the pid of a the userspace process running with the given name */
+static struct task_struct *
+_get_task_info(const char *pname)
+{
+	struct task_struct *task;
+	if (!pname)
+		return NULL;
+
+	for_each_process(task) {
+		if (strcmp(pname, task->comm) == 0)
+			return task;
+	}
+
+	return NULL;
+}
+
+#define DHD_MONITOR_NS	"dhd_monitor"
+extern void emergency_restart(void);
+
+static void
+dhd_inform_dhd_monitor_handler(void *handle, void *event_info, u8 event)
+{
+	dhd_info_t *dhd = handle;
+	dhd_write_file_t *wf = event_info;
+	struct task_struct *monitor_task;
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return;
+	}
+	if (!event_info) {
+		DHD_ERROR(("%s: File info is NULL\n", __FUNCTION__));
+		return;
+	}
+	if (!wf->buf) {
+		DHD_ERROR(("%s: Unable to get failed interface name\n", __FUNCTION__));
+		goto exit;
+	}
+	if (write_file(wf->file_path, wf->file_flags, wf->buf, wf->bufsize)) {
+		DHD_ERROR(("%s: writing to the file failed\n", __FUNCTION__));
+	}
+exit:
+	MFREE(dhd->pub.osh, wf, sizeof(dhd_write_file_t));
+
+	/* check if dhd_monitor is running */
+	monitor_task = _get_task_info(DHD_MONITOR_NS);
+	if (monitor_task == NULL) {
+		/* If dhd_monitor is not running, handle recovery from here */
+
+		char *val = nvram_get("watchdog");
+		if (val && bcm_atoi(val)) {
+			/* watchdog enabled, so reboot */
+			DHD_ERROR(("%s: Dongle(wl%d) trap detected. Restarting the system\n",
+				__FUNCTION__, dhd->unit));
+
+			mdelay(1000);
+			emergency_restart();
+			while (1)
+				cpu_relax();
+		} else {
+			DHD_ERROR(("%s: Dongle(wl%d) trap detected. No watchdog.\n",
+			   __FUNCTION__, dhd->unit));
+		}
+
+		return;
+	}
+
+	/* If monitor daemon is running, let's signal the monitor for recovery */
+	DHD_ERROR(("%s: Dongle(wl%d) trap detected. Send signal to dhd_monitor.\n",
+		__FUNCTION__, dhd->unit));
+
+	send_sig_info(SIGUSR1, (void *)1L, monitor_task);
+}
+#endif /* BCM_ROUTER_DHD */
+
+#if defined(BCMDBG) && defined(DHD_MACDBG)
+#define DUMPMAC_BUF_SZ (128 * 1024)
+#define DUMPMAC_FILENAME_SZ 32
+
+static void
+_dhd_schedule_macdbg_dump(void *handle, void *event_info, u8 event)
+{
+	dhd_info_t *dhd = handle;
+	dhd_pub_t *dhdp = &dhd->pub;
+#ifndef BCM_ROUTER_DHD
+	char *dumpbuf = NULL;
+	int dumpbuf_len = 0;
+	uint16 dump_signature;
+	char dumpfilename[DUMPMAC_FILENAME_SZ] = {0, };
+#endif /* BCM_ROUTER_DHD */
+
+	ASSERT(event == DHD_WQ_WORK_MACDBG);
+	BCM_REFERENCE(event_info);
+
+	DHD_ERROR(("%s: Dongle(wl%d) macreg dump scheduled\n",
+		__FUNCTION__, dhd->unit));
+
+	DHD_OS_WAKE_LOCK(dhdp);
+
+	/* Make sure dongle stops running to avoid race condition in reading mac registers */
+	(void) dhd_wl_ioctl_set_intiovar(dhdp, "bus:disconnect", 99, WLC_SET_VAR, TRUE, 0);
+
+	/* In router, skip macregs dump as dhd_monitor will dump them */
+#ifndef BCM_ROUTER_DHD
+	dumpbuf = (char *)MALLOCZ(dhdp->osh, DUMPMAC_BUF_SZ);
+	if (dumpbuf) {
+		/* Write macdump to a file */
+
+		/* Get dump file signature */
+		dump_signature = (uint16)OSL_RAND();
+
+		/* PSMr */
+		if (dhd_macdbg_dumpmac(dhdp, dumpbuf, DUMPMAC_BUF_SZ,
+			&dumpbuf_len, FALSE) == BCME_OK) {
+			snprintf(dumpfilename, DUMPMAC_FILENAME_SZ,
+				"/tmp/d11reg_dump_%04X.txt", dump_signature);
+			DHD_ERROR(("%s: PSMr macreg dump to %s\n", __FUNCTION__, dumpfilename));
+			/* Write to a file */
+			if (write_file(dumpfilename, (O_CREAT | O_WRONLY | O_SYNC),
+				dumpbuf, dumpbuf_len)) {
+				DHD_ERROR(("%s: writing mac dump to the file failed\n",
+					__FUNCTION__));
+			}
+			memset(dumpbuf, 0, DUMPMAC_BUF_SZ);
+			memset(dumpfilename, 0, DUMPMAC_FILENAME_SZ);
+			dumpbuf_len = 0;
+		}
+
+		/* PSMx */
+		if (dhd_macdbg_dumpmac(dhdp, dumpbuf, DUMPMAC_BUF_SZ,
+			&dumpbuf_len, TRUE) == BCME_OK) {
+			snprintf(dumpfilename, DUMPMAC_FILENAME_SZ,
+				"/tmp/d11regx_dump_%04X.txt", dump_signature);
+			DHD_ERROR(("%s: PSMx macreg dump to %s\n", __FUNCTION__, dumpfilename));
+			/* Write to a file */
+			if (write_file(dumpfilename, (O_CREAT | O_WRONLY | O_SYNC),
+				dumpbuf, dumpbuf_len)) {
+				DHD_ERROR(("%s: writing mac dump to the file failed\n",
+					__FUNCTION__));
+			}
+			memset(dumpbuf, 0, DUMPMAC_BUF_SZ);
+			memset(dumpfilename, 0, DUMPMAC_FILENAME_SZ);
+			dumpbuf_len = 0;
+		}
+
+		/* SVMP */
+		if (dhd_macdbg_dumpsvmp(dhdp, dumpbuf, DUMPMAC_BUF_SZ,
+			&dumpbuf_len) == BCME_OK) {
+			snprintf(dumpfilename, DUMPMAC_FILENAME_SZ,
+				"/tmp/svmp_dump_%04X.txt", dump_signature);
+			DHD_ERROR(("%s: SVMP mems dump to %s\n", __FUNCTION__, dumpfilename));
+			/* Write to a file */
+			if (write_file(dumpfilename, (O_CREAT | O_WRONLY | O_SYNC),
+				dumpbuf, dumpbuf_len)) {
+				DHD_ERROR(("%s: writing svmp dump to the file failed\n",
+					__FUNCTION__));
+			}
+			memset(dumpbuf, 0, DUMPMAC_BUF_SZ);
+			memset(dumpfilename, 0, DUMPMAC_FILENAME_SZ);
+			dumpbuf_len = 0;
+		}
+
+		MFREE(dhdp->osh, dumpbuf, DUMPMAC_BUF_SZ);
+	} else {
+		DHD_ERROR(("%s: print macdump\n", __FUNCTION__));
+		/* Just printf the dumps */
+		(void) dhd_macdbg_dumpmac(dhdp, NULL, 0, NULL, FALSE); /* PSMr */
+		(void) dhd_macdbg_dumpmac(dhdp, NULL, 0, NULL, TRUE); /* PSMx */
+		(void) dhd_macdbg_dumpsvmp(dhdp, NULL, 0, NULL);
+	}
+#endif /* BCM_ROUTER_DHD */
+
+	DHD_OS_WAKE_UNLOCK(dhdp);
+	dhd_deferred_work_set_skip(dhd->dhd_deferred_wq,
+		DHD_WQ_WORK_MACDBG, FALSE);
+}
+
+void
+dhd_schedule_macdbg_dump(dhd_pub_t *dhdp)
+{
+	DHD_ERROR(("%s: Dongle(wl%d) schedule macreg dump\n",
+		__FUNCTION__, dhdp->info->unit));
+
+	dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq, NULL,
+		DHD_WQ_WORK_MACDBG, _dhd_schedule_macdbg_dump, DHD_WQ_WORK_PRIORITY_LOW);
+	dhd_deferred_work_set_skip(dhdp->info->dhd_deferred_wq,
+		DHD_WQ_WORK_MACDBG, TRUE);
+}
+#endif /* BCMDBG && DHD_MACDBG */
+
+/*
+ * This call is to get the memdump size so that,
+ * halutil can alloc that much buffer in user space.
+ */
+int
+dhd_os_socram_dump(struct net_device *dev, uint32 *dump_size)
+{
+	int ret = BCME_OK;
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	dhd_pub_t *dhdp = &dhd->pub;
+
+	if (dhdp->busstate == DHD_BUS_DOWN) {
+		DHD_ERROR(("%s: bus is down\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	if (DHD_BUS_CHECK_SUSPEND_OR_SUSPEND_IN_PROGRESS(dhdp)) {
+		DHD_ERROR(("%s: bus is in suspend(%d) or suspending(0x%x) state, so skip\n",
+			__FUNCTION__, dhdp->busstate, dhdp->dhd_bus_busy_state));
+		return BCME_ERROR;
+	}
+	ret = dhd_common_socram_dump(dhdp);
+	if (ret == BCME_OK) {
+		*dump_size = dhdp->soc_ram_length;
+	}
+	return ret;
+}
+
+/*
+ * This is to get the actual memdup after getting the memdump size
+ */
+int
+dhd_os_get_socram_dump(struct net_device *dev, char **buf, uint32 *size)
+{
+	int ret = BCME_OK;
+	int orig_len = 0;
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	if (buf == NULL)
+		return BCME_ERROR;
+	orig_len = *size;
+	if (dhdp->soc_ram) {
+		if (orig_len >= dhdp->soc_ram_length) {
+			*buf = dhdp->soc_ram;
+			*size = dhdp->soc_ram_length;
+		} else {
+			ret = BCME_BUFTOOSHORT;
+			DHD_ERROR(("The length of the buffer is too short"
+				" to save the memory dump with %d\n", dhdp->soc_ram_length));
+		}
+	} else {
+		DHD_ERROR(("socram_dump is not ready to get\n"));
+		ret = BCME_NOTREADY;
+	}
+	return ret;
+}
+
+#ifdef DHD_MAP_PKTID_LOGGING
+uint32
+dhd_get_pktid_map_logging_len(void *ndev, dhd_pub_t *dhdp, bool is_map)
+{
+	dhd_info_t *dhd_info;
+	log_dump_section_hdr_t sec_hdr;
+	uint32 length = 0;
+
+	if (ndev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)ndev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp || !dhdp->enable_pktid_log_dump)
+		return length;
+
+	length = dhd_pktid_buf_len(dhdp, is_map) + sizeof(sec_hdr);
+	return length;
+}
+
+int
+dhd_print_pktid_map_log_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, void *pos, bool is_map)
+{
+	dhd_info_t *dhd_info;
+
+	if (dev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp) {
+		return BCME_ERROR;
+	}
+
+	return dhd_write_pktid_log_dump(dhdp, user_buf, fp, len, pos, is_map);
+}
+#endif /* DHD_MAP_PKTID_LOGGING */
+
+int
+dhd_os_get_version(struct net_device *dev, bool dhd_ver, char **buf, uint32 size)
+{
+	char *fw_str;
+
+	if (size == 0)
+		return BCME_BADARG;
+
+	fw_str = strstr(info_string, "Firmware: ");
+	if (fw_str == NULL) {
+		return BCME_ERROR;
+	}
+
+	bzero(*buf, size);
+	if (dhd_ver) {
+		strlcpy(*buf, dhd_version, size);
+	} else {
+		strlcpy(*buf, fw_str, size);
+	}
+	return BCME_OK;
+}
+
+#ifdef DHD_PKT_LOGGING
+int
+dhd_os_get_pktlog_dump(void *dev, const void *user_buf, uint32 len)
+{
+#ifdef DHD_PKT_LOGGING_DBGRING
+	/* With DHD_PKT_LOGGING_DBGRING, this path is not allowed. */
+	return BCME_UNSUPPORTED;
+#else
+	int ret = BCME_OK;
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	if (user_buf == NULL) {
+		DHD_ERROR(("%s(): user buffer is NULL\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	ret = dhd_pktlog_dump_write_memory(dhdp, user_buf, len);
+	if (ret < 0) {
+		DHD_ERROR(("%s(): fail to dump pktlog, err = %d\n", __FUNCTION__, ret));
+		return ret;
+	}
+	return ret;
+#endif /* DHD_PKT_LOGGING_DBGRING */
+}
+
+spinlock_t *
+dhd_os_get_pktlog_lock(dhd_pub_t *dhdp)
+{
+	return dhdp->pktlog->pktlog_ring->pktlog_ring_lock;
+}
+
+uint32
+dhd_os_get_pktlog_dump_size(struct net_device *dev)
+{
+	int ret = 0;
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	dhd_pub_t *dhdp = &dhd->pub;
+
+	ret = dhd_pktlog_get_dump_length(dhdp);
+	if (ret < 0) {
+		DHD_ERROR(("%s(): fail to get pktlog size, err = %d\n",
+			__FUNCTION__, ret));
+		return 0;
+	}
+	return ret;
+}
+
+void
+dhd_os_get_pktlogdump_filename(struct net_device *dev, char *dump_path, int len)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	dhd_pub_t *dhdp = &dhd->pub;
+
+	dhd_pktlog_get_filename(dhdp, dump_path, len);
+}
+#endif /* DHD_PKT_LOGGING */
+#ifdef DNGL_AXI_ERROR_LOGGING
+int
+dhd_os_get_axi_error_dump(void *dev, const void *user_buf, uint32 len)
+{
+	int ret = BCME_OK;
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+	dhd_pub_t *dhdp = &dhd->pub;
+	loff_t pos = 0;
+	if (user_buf == NULL) {
+		DHD_ERROR(("%s(): user buffer is NULL\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	ret = dhd_export_debug_data((char *)dhdp->axi_err_dump,
+			NULL, user_buf, sizeof(dhd_axi_error_dump_t), &pos);
+
+	if (ret < 0) {
+		DHD_ERROR(("%s(): fail to dump pktlog, err = %d\n", __FUNCTION__, ret));
+		return ret;
+	}
+	return ret;
+}
+
+int
+dhd_os_get_axi_error_dump_size(struct net_device *dev)
+{
+	int size = -1;
+
+	size = sizeof(dhd_axi_error_dump_t);
+	if (size < 0) {
+		DHD_ERROR(("%s(): fail to get axi error size, err = %d\n", __FUNCTION__, size));
+	}
+	return size;
+}
+
+void
+dhd_os_get_axi_error_filename(struct net_device *dev, char *dump_path, int len)
+{
+	snprintf(dump_path, len, "%s",
+		DHD_COMMON_DUMP_PATH DHD_DUMP_AXI_ERROR_FILENAME);
+}
+#endif /* DNGL_AXI_ERROR_LOGGING */
+#ifdef DHD_WMF
+/* Returns interface specific WMF configuration */
+dhd_wmf_t* dhd_wmf_conf(dhd_pub_t *dhdp, uint32 idx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(idx < DHD_MAX_IFS);
+
+	ifp = dhd->iflist[idx];
+	return &ifp->wmf;
+}
+#endif /* DHD_WMF */
+
+#if defined(BCM_ROUTER_DHD)
+void traffic_mgmt_pkt_set_prio(dhd_pub_t *dhdp, void * pktbuf)
+{
+	struct ether_header *eh;
+	struct ethervlan_header *evh;
+	uint8 *pktdata, *ip_body;
+	uint8  dwm_filter;
+	uint8 tos_tc = 0;
+	uint8 dscp   = 0;
+	pktdata = (uint8 *)PKTDATA(dhdp->osh, pktbuf);
+	eh = (struct ether_header *) pktdata;
+	ip_body = NULL;
+
+	if (dhdp->dhd_tm_dwm_tbl.dhd_dwm_enabled) {
+		if (eh->ether_type == hton16(ETHER_TYPE_8021Q)) {
+			evh = (struct ethervlan_header *)eh;
+			if ((evh->ether_type == hton16(ETHER_TYPE_IP)) ||
+				(evh->ether_type == hton16(ETHER_TYPE_IPV6))) {
+				ip_body = pktdata + sizeof(struct ethervlan_header);
+			}
+		} else if ((eh->ether_type == hton16(ETHER_TYPE_IP)) ||
+			(eh->ether_type == hton16(ETHER_TYPE_IPV6))) {
+			ip_body = pktdata + sizeof(struct ether_header);
+		}
+		if (ip_body) {
+			tos_tc = IP_TOS46(ip_body);
+			dscp = tos_tc >> IPV4_TOS_DSCP_SHIFT;
+		}
+
+		if (dscp < DHD_DWM_TBL_SIZE) {
+			dwm_filter = dhdp->dhd_tm_dwm_tbl.dhd_dwm_tbl[dscp];
+			if (DHD_TRF_MGMT_DWM_IS_FILTER_SET(dwm_filter)) {
+				PKTSETPRIO(pktbuf, DHD_TRF_MGMT_DWM_PRIO(dwm_filter));
+			}
+		}
+	}
+}
+#endif /* BCM_ROUTER_DHD */
+
+bool dhd_sta_associated(dhd_pub_t *dhdp, uint32 bssidx, uint8 *mac)
+{
+	return dhd_find_sta(dhdp, bssidx, mac) ? TRUE : FALSE;
+}
+
+#ifdef DHD_L2_FILTER
+arp_table_t*
+dhd_get_ifp_arp_table_handle(dhd_pub_t *dhdp, uint32 bssidx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(bssidx < DHD_MAX_IFS);
+
+	ifp = dhd->iflist[bssidx];
+	return ifp->phnd_arp_table;
+}
+
+int dhd_get_parp_status(dhd_pub_t *dhdp, uint32 idx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(idx < DHD_MAX_IFS);
+
+	ifp = dhd->iflist[idx];
+
+	if (ifp)
+		return ifp->parp_enable;
+	else
+		return FALSE;
+}
+
+/* Set interface specific proxy arp configuration */
+int dhd_set_parp_status(dhd_pub_t *dhdp, uint32 idx, int val)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+	ASSERT(idx < DHD_MAX_IFS);
+	ifp = dhd->iflist[idx];
+
+	if (!ifp)
+	    return BCME_ERROR;
+
+	/* At present all 3 variables are being
+	 * handled at once
+	 */
+	ifp->parp_enable = val;
+	ifp->parp_discard = val;
+	ifp->parp_allnode = val;
+
+	/* Flush ARP entries when disabled */
+	if (val == FALSE) {
+		bcm_l2_filter_arp_table_update(dhdp->osh, ifp->phnd_arp_table, TRUE, NULL,
+			FALSE, dhdp->tickcnt);
+	}
+	return BCME_OK;
+}
+
+bool dhd_parp_discard_is_enabled(dhd_pub_t *dhdp, uint32 idx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(idx < DHD_MAX_IFS);
+
+	ifp = dhd->iflist[idx];
+
+	ASSERT(ifp);
+	return ifp->parp_discard;
+}
+
+bool
+dhd_parp_allnode_is_enabled(dhd_pub_t *dhdp, uint32 idx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(idx < DHD_MAX_IFS);
+
+	ifp = dhd->iflist[idx];
+
+	ASSERT(ifp);
+
+	return ifp->parp_allnode;
+}
+
+int dhd_get_dhcp_unicast_status(dhd_pub_t *dhdp, uint32 idx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(idx < DHD_MAX_IFS);
+
+	ifp = dhd->iflist[idx];
+
+	ASSERT(ifp);
+
+	return ifp->dhcp_unicast;
+}
+
+int dhd_set_dhcp_unicast_status(dhd_pub_t *dhdp, uint32 idx, int val)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+	ASSERT(idx < DHD_MAX_IFS);
+	ifp = dhd->iflist[idx];
+
+	ASSERT(ifp);
+
+	ifp->dhcp_unicast = val;
+	return BCME_OK;
+}
+
+int dhd_get_block_ping_status(dhd_pub_t *dhdp, uint32 idx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(idx < DHD_MAX_IFS);
+
+	ifp = dhd->iflist[idx];
+
+	ASSERT(ifp);
+
+	return ifp->block_ping;
+}
+
+int dhd_set_block_ping_status(dhd_pub_t *dhdp, uint32 idx, int val)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+	ASSERT(idx < DHD_MAX_IFS);
+	ifp = dhd->iflist[idx];
+
+	ASSERT(ifp);
+
+	ifp->block_ping = val;
+	/* Disable rx_pkt_chain feature for interface if block_ping option is
+	 * enabled
+	 */
+	dhd_update_rx_pkt_chainable_state(dhdp, idx);
+	return BCME_OK;
+}
+
+int dhd_get_grat_arp_status(dhd_pub_t *dhdp, uint32 idx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(idx < DHD_MAX_IFS);
+
+	ifp = dhd->iflist[idx];
+
+	ASSERT(ifp);
+
+	return ifp->grat_arp;
+}
+
+int dhd_set_grat_arp_status(dhd_pub_t *dhdp, uint32 idx, int val)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+	ASSERT(idx < DHD_MAX_IFS);
+	ifp = dhd->iflist[idx];
+
+	ASSERT(ifp);
+
+	ifp->grat_arp = val;
+
+	return BCME_OK;
+}
+
+int dhd_get_block_tdls_status(dhd_pub_t *dhdp, uint32 idx)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+
+	ASSERT(idx < DHD_MAX_IFS);
+
+	ifp = dhd->iflist[idx];
+
+	ASSERT(ifp);
+
+	return ifp->block_tdls;
+}
+
+int dhd_set_block_tdls_status(dhd_pub_t *dhdp, uint32 idx, int val)
+{
+	dhd_info_t *dhd = dhdp->info;
+	dhd_if_t *ifp;
+	ASSERT(idx < DHD_MAX_IFS);
+	ifp = dhd->iflist[idx];
+
+	ASSERT(ifp);
+
+	ifp->block_tdls = val;
+
+	return BCME_OK;
+}
+#endif /* DHD_L2_FILTER */
+
+#if defined(SET_XPS_CPUS)
+int dhd_xps_cpus_enable(struct net_device *net, int enable)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+	dhd_if_t *ifp;
+	int ifidx;
+	char * XPS_CPU_SETBUF;
+
+	ifidx = dhd_net2idx(dhd, net);
+	if (ifidx == DHD_BAD_IF) {
+		DHD_ERROR(("%s bad ifidx\n", __FUNCTION__));
+		return -ENODEV;
+	}
+
+	if (!dhd->pub.conf->xps_cpus)
+		return -ENODEV;
+
+	if (ifidx == PRIMARY_INF) {
+		if (dhd->pub.op_mode == DHD_FLAG_IBSS_MODE) {
+			DHD_INFO(("%s : set for IBSS.\n", __FUNCTION__));
+			XPS_CPU_SETBUF = RPS_CPUS_MASK_IBSS;
+		} else {
+			DHD_INFO(("%s : set for BSS.\n", __FUNCTION__));
+			XPS_CPU_SETBUF = RPS_CPUS_MASK;
+		}
+	} else if (ifidx == VIRTUAL_INF) {
+		DHD_INFO(("%s : set for P2P.\n", __FUNCTION__));
+		XPS_CPU_SETBUF = RPS_CPUS_MASK_P2P;
+	} else {
+		DHD_ERROR(("%s : Invalid index : %d.\n", __FUNCTION__, ifidx));
+		return -EINVAL;
+	}
+
+	ifp = dhd->iflist[ifidx];
+	if (ifp) {
+		if (enable) {
+			DHD_INFO(("%s : set xps_cpus as [%s]\n", __FUNCTION__, XPS_CPU_SETBUF));
+			custom_xps_map_set(ifp->net, XPS_CPU_SETBUF, strlen(XPS_CPU_SETBUF));
+		} else {
+			custom_xps_map_clear(ifp->net);
+		}
+	} else {
+		DHD_ERROR(("%s : ifp is NULL!!\n", __FUNCTION__));
+		return -ENODEV;
+	}
+	return BCME_OK;
+}
+
+int custom_xps_map_set(struct net_device *net, char *buf, size_t len)
+{
+	cpumask_var_t mask;
+	int err;
+
+	DHD_INFO(("%s : Entered.\n", __FUNCTION__));
+
+	if (!alloc_cpumask_var(&mask, GFP_KERNEL)) {
+		DHD_ERROR(("%s : alloc_cpumask_var fail.\n", __FUNCTION__));
+		return -ENOMEM;
+	}
+
+	err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits);
+	if (err) {
+		free_cpumask_var(mask);
+		DHD_ERROR(("%s : bitmap_parse fail.\n", __FUNCTION__));
+		return err;
+	}
+
+	err = netif_set_xps_queue(net, mask, 0);
+
+	free_cpumask_var(mask);
+
+	if (0 == err)
+		WL_MSG(net->name, "Done. mapping cpu\n");
+
+	return err;
+}
+
+void custom_xps_map_clear(struct net_device *net)
+{
+    struct xps_dev_maps *dev_maps;
+
+	DHD_INFO(("%s : Entered.\n", __FUNCTION__));
+
+    rcu_read_lock();
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0))
+	dev_maps = rcu_dereference(net->xps_maps[XPS_CPUS]);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
+	dev_maps = rcu_dereference(net->xps_cpus_map);
+#else
+    dev_maps = rcu_dereference(net->xps_maps);
+#endif
+    rcu_read_unlock();
+
+	if (dev_maps) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0))
+		RCU_INIT_POINTER(net->xps_maps[XPS_CPUS], NULL);
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
+		RCU_INIT_POINTER(net->xps_cpus_map, NULL);
+#else
+		RCU_INIT_POINTER(net->xps_maps, NULL);
+#endif
+		kfree_rcu(dev_maps, rcu);
+		DHD_INFO(("%s : xps_cpus map clear.\n", __FUNCTION__));
+	}
+}
+#endif // endif
+
+#if defined(SET_RPS_CPUS)
+int dhd_rps_cpus_enable(struct net_device *net, int enable)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+	dhd_if_t *ifp;
+	int ifidx;
+	char * RPS_CPU_SETBUF;
+
+	ifidx = dhd_net2idx(dhd, net);
+	if (ifidx == DHD_BAD_IF) {
+		DHD_ERROR(("%s bad ifidx\n", __FUNCTION__));
+		return -ENODEV;
+	}
+
+	if (!dhd->pub.conf->rps_cpus)
+		return -ENODEV;
+
+	if (ifidx == PRIMARY_INF) {
+		if (dhd->pub.op_mode == DHD_FLAG_IBSS_MODE) {
+			DHD_INFO(("%s : set for IBSS.\n", __FUNCTION__));
+			RPS_CPU_SETBUF = RPS_CPUS_MASK_IBSS;
+		} else {
+			DHD_INFO(("%s : set for BSS.\n", __FUNCTION__));
+			RPS_CPU_SETBUF = RPS_CPUS_MASK;
+		}
+	} else if (ifidx == VIRTUAL_INF) {
+		DHD_INFO(("%s : set for P2P.\n", __FUNCTION__));
+		RPS_CPU_SETBUF = RPS_CPUS_MASK_P2P;
+	} else {
+		DHD_ERROR(("%s : Invalid index : %d.\n", __FUNCTION__, ifidx));
+		return -EINVAL;
+	}
+
+	ifp = dhd->iflist[ifidx];
+	if (ifp) {
+		if (enable) {
+			DHD_INFO(("%s : set rps_cpus as [%s]\n", __FUNCTION__, RPS_CPU_SETBUF));
+			custom_rps_map_set(ifp->net->_rx, RPS_CPU_SETBUF, strlen(RPS_CPU_SETBUF));
+		} else {
+			custom_rps_map_clear(ifp->net->_rx);
+		}
+	} else {
+		DHD_ERROR(("%s : ifp is NULL!!\n", __FUNCTION__));
+		return -ENODEV;
+	}
+	return BCME_OK;
+}
+
+int custom_rps_map_set(struct netdev_rx_queue *queue, char *buf, size_t len)
+{
+	struct rps_map *old_map, *map;
+	cpumask_var_t mask;
+	int err, cpu, i;
+	static DEFINE_SPINLOCK(rps_map_lock);
+
+	DHD_INFO(("%s : Entered.\n", __FUNCTION__));
+
+	if (!alloc_cpumask_var(&mask, GFP_KERNEL)) {
+		DHD_ERROR(("%s : alloc_cpumask_var fail.\n", __FUNCTION__));
+		return -ENOMEM;
+	}
+
+	err = bitmap_parse(buf, len, cpumask_bits(mask), nr_cpumask_bits);
+	if (err) {
+		free_cpumask_var(mask);
+		DHD_ERROR(("%s : bitmap_parse fail.\n", __FUNCTION__));
+		return err;
+	}
+
+	map = kzalloc(max_t(unsigned int,
+		RPS_MAP_SIZE(cpumask_weight(mask)), L1_CACHE_BYTES),
+		GFP_KERNEL);
+	if (!map) {
+		free_cpumask_var(mask);
+		DHD_ERROR(("%s : map malloc fail.\n", __FUNCTION__));
+		return -ENOMEM;
+	}
+
+	i = 0;
+	for_each_cpu(cpu, mask) {
+		map->cpus[i++] = cpu;
+	}
+
+	if (i) {
+		map->len = i;
+	} else {
+		kfree(map);
+		map = NULL;
+		free_cpumask_var(mask);
+		DHD_ERROR(("%s : mapping cpu fail.\n", __FUNCTION__));
+		return -1;
+	}
+
+	spin_lock(&rps_map_lock);
+	old_map = rcu_dereference_protected(queue->rps_map,
+		lockdep_is_held(&rps_map_lock));
+	rcu_assign_pointer(queue->rps_map, map);
+	spin_unlock(&rps_map_lock);
+
+	if (map) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+		static_key_slow_inc(&rps_needed.key);
+#else
+		static_key_slow_inc(&rps_needed);
+#endif
+	}
+	if (old_map) {
+		kfree_rcu(old_map, rcu);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0))
+		static_key_slow_dec(&rps_needed.key);
+#else
+		static_key_slow_dec(&rps_needed);
+#endif
+	}
+	free_cpumask_var(mask);
+
+	DHD_INFO(("%s : Done. mapping cpu nummber : %d\n", __FUNCTION__, map->len));
+	return map->len;
+}
+
+void custom_rps_map_clear(struct netdev_rx_queue *queue)
+{
+	struct rps_map *map;
+
+	DHD_INFO(("%s : Entered.\n", __FUNCTION__));
+
+	map = rcu_dereference_protected(queue->rps_map, 1);
+	if (map) {
+		RCU_INIT_POINTER(queue->rps_map, NULL);
+		kfree_rcu(map, rcu);
+		DHD_INFO(("%s : rps_cpus map clear.\n", __FUNCTION__));
+	}
+}
+#endif // endif
+
+#ifdef DHD_DEBUG_PAGEALLOC
+/* XXX Additional Kernel implemenation is needed to use this function at
+ * the top of the check_poison_mem() function in mm/debug-pagealloc.c file.
+ * Please check if below codes are implemenated your Linux Kernel first.
+ *
+ * - mm/debug-pagealloc.c
+ *
+ * // for DHD_DEBUG_PAGEALLOC
+ * typedef void (*page_corrupt_cb_t)(void *handle, void *addr_corrupt, uint addr_len);
+ * page_corrupt_cb_t corrupt_cb = NULL;
+ * void *corrupt_cb_handle = NULL;
+ *
+ * void register_page_corrupt_cb(page_corrupt_cb_t cb, void *handle)
+ * {
+ *      corrupt_cb = cb;
+ *      corrupt_cb_handle = handle;
+ * }
+ * EXPORT_SYMBOL(register_page_corrupt_cb);
+ *
+ * extern void dhd_page_corrupt_cb(void *handle, void *addr_corrupt, size_t len);
+ *
+ * static void check_poison_mem(unsigned char *mem, size_t bytes)
+ * {
+ * ......
+ *
+ *      if (!__ratelimit(&ratelimit))
+ *               return;
+ *      else if (start == end && single_bit_flip(*start, PAGE_POISON))
+ *              printk(KERN_ERR "pagealloc: single bit error\n");
+ *      else
+ *              printk(KERN_ERR "pagealloc: memory corruption\n");
+ *
+ *      print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1, start,
+ *              end - start + 1, 1);
+ *
+ *      // for DHD_DEBUG_PAGEALLOC
+ *      dhd_page_corrupt_cb(corrupt_cb_handle, start, end - start + 1);
+ *
+ *      dump_stack();
+ * }
+ *
+ */
+
+void
+dhd_page_corrupt_cb(void *handle, void *addr_corrupt, size_t len)
+{
+	dhd_pub_t *dhdp = (dhd_pub_t *)handle;
+
+	DHD_ERROR(("%s: Got dhd_page_corrupt_cb 0x%p %d\n",
+		__FUNCTION__, addr_corrupt, (uint32)len));
+
+	DHD_OS_WAKE_LOCK(dhdp);
+	prhex("Page Corruption:", addr_corrupt, len);
+	dhd_dump_to_kernelog(dhdp);
+#if defined(BCMPCIE) && defined(DHD_FW_COREDUMP)
+	/* Load the dongle side dump to host memory and then BUG_ON() */
+	dhdp->memdump_enabled = DUMP_MEMONLY;
+	dhdp->memdump_type = DUMP_TYPE_MEMORY_CORRUPTION;
+	dhd_bus_mem_dump(dhdp);
+#endif /* BCMPCIE && DHD_FW_COREDUMP */
+	DHD_OS_WAKE_UNLOCK(dhdp);
+}
+EXPORT_SYMBOL(dhd_page_corrupt_cb);
+#endif /* DHD_DEBUG_PAGEALLOC */
+
+#if defined(BCMPCIE) && defined(DHD_PKTID_AUDIT_ENABLED)
+void
+dhd_pktid_error_handler(dhd_pub_t *dhdp)
+{
+	unsigned long flags = 0;
+
+	DHD_GENERAL_LOCK(dhdp, flags);
+	if (DHD_BUS_CHECK_DOWN_OR_DOWN_IN_PROGRESS(dhdp)) {
+		DHD_GENERAL_UNLOCK(dhdp, flags);
+		DHD_ERROR(("%s: bus is down!\n", __FUNCTION__));
+		return;
+	}
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+	DHD_ERROR(("%s: Got Pkt Id Audit failure \n", __FUNCTION__));
+	DHD_OS_WAKE_LOCK(dhdp);
+	dhd_dump_to_kernelog(dhdp);
+#ifdef DHD_FW_COREDUMP
+	/* Load the dongle side dump to host memory */
+	if (dhdp->memdump_enabled == DUMP_DISABLED) {
+		dhdp->memdump_enabled = DUMP_MEMFILE;
+	}
+	dhdp->memdump_type = DUMP_TYPE_PKTID_AUDIT_FAILURE;
+	dhd_bus_mem_dump(dhdp);
+#endif /* DHD_FW_COREDUMP */
+#ifdef OEM_ANDROID
+	/* XXX Send HANG event to Android Framework for recovery */
+	dhdp->hang_reason = HANG_REASON_PCIE_PKTID_ERROR;
+	dhd_os_check_hang(dhdp, 0, -EREMOTEIO);
+#endif /* OEM_ANDROID */
+	DHD_OS_WAKE_UNLOCK(dhdp);
+}
+#endif /* BCMPCIE && DHD_PKTID_AUDIT_ENABLED */
+
+struct net_device *
+dhd_linux_get_primary_netdev(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = dhdp->info;
+
+	if (dhd->iflist[0] && dhd->iflist[0]->net)
+		return dhd->iflist[0]->net;
+	else
+		return NULL;
+}
+
+static int
+dhd_create_to_notifier_skt(void)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
+	/* Kernel 3.7 onwards this API accepts only 3 arguments. */
+	/* Kernel version 3.6 is a special case which accepts 4 arguments */
+	nl_to_event_sk = netlink_kernel_create(&init_net, BCM_NL_USER, &dhd_netlink_cfg);
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
+	/* Kernel version 3.5 and below use this old API format */
+	nl_to_event_sk = netlink_kernel_create(&init_net, BCM_NL_USER, 0,
+			dhd_process_daemon_msg, NULL, THIS_MODULE);
+#else
+	nl_to_event_sk = netlink_kernel_create(&init_net, BCM_NL_USER, THIS_MODULE,
+			&dhd_netlink_cfg);
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0)) */
+	if (!nl_to_event_sk)
+	{
+		DHD_CONS_ONLY(("Error creating socket.\n"));
+		return -1;
+	}
+	DHD_INFO(("nl_to socket created successfully...\n"));
+	return 0;
+}
+
+void
+dhd_destroy_to_notifier_skt(void)
+{
+	DHD_INFO(("Destroying nl_to socket\n"));
+	netlink_kernel_release(nl_to_event_sk);
+}
+
+static void
+dhd_recv_msg_from_daemon(struct sk_buff *skb)
+{
+	struct nlmsghdr *nlh;
+	bcm_to_info_t *cmd;
+
+	nlh = (struct nlmsghdr *)skb->data;
+	cmd = (bcm_to_info_t *)nlmsg_data(nlh);
+	if ((cmd->magic == BCM_TO_MAGIC) && (cmd->reason == REASON_DAEMON_STARTED)) {
+		sender_pid = ((struct nlmsghdr *)(skb->data))->nlmsg_pid;
+		DHD_INFO(("DHD Daemon Started\n"));
+	}
+}
+
+int
+dhd_send_msg_to_daemon(struct sk_buff *skb, void *data, int size)
+{
+	struct nlmsghdr *nlh;
+	struct sk_buff *skb_out;
+	int ret = BCME_ERROR;
+
+	BCM_REFERENCE(skb);
+	if (sender_pid == 0) {
+		DHD_INFO(("Invalid PID 0\n"));
+		skb_out = NULL;
+		goto err;
+	}
+
+	if ((skb_out = nlmsg_new(size, 0)) == NULL) {
+		DHD_ERROR(("%s: skb alloc failed\n", __FUNCTION__));
+		ret = BCME_NOMEM;
+		goto err;
+	}
+	nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, size, 0);
+	if (nlh == NULL) {
+		DHD_ERROR(("%s: nlmsg_put failed\n", __FUNCTION__));
+		goto err;
+	}
+	NETLINK_CB(skb_out).dst_group = 0; /* Unicast */
+	(void)memcpy_s(nlmsg_data(nlh), size, (char *)data, size);
+
+	if ((ret = nlmsg_unicast(nl_to_event_sk, skb_out, sender_pid)) < 0) {
+		DHD_ERROR(("Error sending message, ret:%d\n", ret));
+		/* skb is already freed inside nlmsg_unicast() on error case */
+		/* explicitly making skb_out to NULL to avoid double free */
+		skb_out = NULL;
+		goto err;
+	}
+	return BCME_OK;
+err:
+	if (skb_out) {
+		nlmsg_free(skb_out);
+	}
+	return ret;
+}
+
+static void
+dhd_process_daemon_msg(struct sk_buff *skb)
+{
+	bcm_to_info_t to_info;
+
+	to_info.magic = BCM_TO_MAGIC;
+	to_info.reason = REASON_DAEMON_STARTED;
+	to_info.trap = NO_TRAP;
+
+	dhd_recv_msg_from_daemon(skb);
+	dhd_send_msg_to_daemon(skb, &to_info, sizeof(to_info));
+}
+
+#ifdef REPORT_FATAL_TIMEOUTS
+static void
+dhd_send_trap_to_fw(dhd_pub_t * pub, int reason, int trap)
+{
+	bcm_to_info_t to_info;
+
+	to_info.magic = BCM_TO_MAGIC;
+	to_info.reason = reason;
+	to_info.trap = trap;
+
+	DHD_ERROR(("Sending Event reason:%d trap:%d\n", reason, trap));
+	dhd_send_msg_to_daemon(NULL, (void *)&to_info, sizeof(bcm_to_info_t));
+}
+
+void
+dhd_send_trap_to_fw_for_timeout(dhd_pub_t * pub, timeout_reasons_t reason)
+{
+	int to_reason;
+	int trap = NO_TRAP;
+	switch (reason) {
+		case DHD_REASON_COMMAND_TO:
+			to_reason = REASON_COMMAND_TO;
+			trap = DO_TRAP;
+			break;
+		case DHD_REASON_JOIN_TO:
+			to_reason = REASON_JOIN_TO;
+			trap = DO_TRAP;
+			break;
+		case DHD_REASON_SCAN_TO:
+			to_reason = REASON_SCAN_TO;
+			trap = DO_TRAP;
+			break;
+		case DHD_REASON_OQS_TO:
+			to_reason = REASON_OQS_TO;
+			trap = DO_TRAP;
+			break;
+		default:
+			to_reason = REASON_UNKOWN;
+	}
+	dhd_send_trap_to_fw(pub, to_reason, trap);
+}
+#endif /* REPORT_FATAL_TIMEOUTS */
+
+char*
+dhd_dbg_get_system_timestamp(void)
+{
+	static char timebuf[DEBUG_DUMP_TIME_BUF_LEN];
+	struct osl_timespec tv;
+	unsigned long local_time;
+	struct rtc_time tm;
+
+	memset_s(timebuf, DEBUG_DUMP_TIME_BUF_LEN, 0, DEBUG_DUMP_TIME_BUF_LEN);
+	osl_do_gettimeofday(&tv);
+	local_time = (u32)(tv.tv_sec - (sys_tz.tz_minuteswest * 60));
+	rtc_time_to_tm(local_time, &tm);
+	snprintf(timebuf, DEBUG_DUMP_TIME_BUF_LEN,
+			"%02d-%02d-%02d/%02d:%02d:%02d.%04lu",
+			tm.tm_year - 100, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
+			tm.tm_sec, tv.tv_usec);
+	return timebuf;
+}
+
+char*
+dhd_log_dump_get_timestamp(void)
+{
+	static char buf[32];
+	u64 ts_nsec;
+	unsigned long rem_nsec;
+
+	ts_nsec = local_clock();
+	rem_nsec = DIV_AND_MOD_U64_BY_U32(ts_nsec, NSEC_PER_SEC);
+	snprintf(buf, sizeof(buf), "%5lu.%06lu",
+		(unsigned long)ts_nsec, rem_nsec / NSEC_PER_USEC);
+
+	return buf;
+}
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+void
+dhd_flush_rx_tx_wq(dhd_pub_t *dhdp)
+{
+	dhd_info_t * dhd;
+
+	if (dhdp) {
+		dhd = dhdp->info;
+		if (dhd) {
+			flush_workqueue(dhd->tx_wq);
+			flush_workqueue(dhd->rx_wq);
+		}
+	}
+
+	return;
+}
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+#ifdef DHD_DEBUG_UART
+bool
+dhd_debug_uart_is_running(struct net_device *dev)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+
+	if (dhd->duart_execute) {
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+static void
+dhd_debug_uart_exec_rd(void *handle, void *event_info, u8 event)
+{
+	dhd_pub_t *dhdp = handle;
+	dhd_debug_uart_exec(dhdp, "rd");
+}
+
+static void
+dhd_debug_uart_exec(dhd_pub_t *dhdp, char *cmd)
+{
+	int ret;
+
+	char *argv[] = {DHD_DEBUG_UART_EXEC_PATH, cmd, NULL};
+	char *envp[] = {"HOME=/", "TERM=linux", "PATH=/sbin:/system/bin", NULL};
+
+#ifdef DHD_FW_COREDUMP
+	if (dhdp->memdump_enabled == DUMP_MEMFILE_BUGON)
+#endif
+	{
+		if (dhdp->hang_reason == HANG_REASON_PCIE_LINK_DOWN_RC_DETECT ||
+			dhdp->hang_reason == HANG_REASON_PCIE_LINK_DOWN_EP_DETECT ||
+#ifdef DHD_FW_COREDUMP
+			dhdp->memdump_success == FALSE ||
+#endif
+			FALSE) {
+			dhdp->info->duart_execute = TRUE;
+			DHD_ERROR(("DHD: %s - execute %s %s\n",
+				__FUNCTION__, DHD_DEBUG_UART_EXEC_PATH, cmd));
+			ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
+			DHD_ERROR(("DHD: %s - %s %s ret = %d\n",
+				__FUNCTION__, DHD_DEBUG_UART_EXEC_PATH, cmd, ret));
+			dhdp->info->duart_execute = FALSE;
+
+#ifdef DHD_LOG_DUMP
+			if (dhdp->memdump_type != DUMP_TYPE_BY_SYSDUMP)
+#endif
+			{
+				BUG_ON(1);
+			}
+		}
+	}
+}
+#endif	/* DHD_DEBUG_UART */
+
+#if defined(DHD_BLOB_EXISTENCE_CHECK)
+#ifdef DHD_LINUX_STD_FW_API
+void
+dhd_set_blob_support(dhd_pub_t *dhdp, char *fw_path)
+{
+	char *filepath = DHD_CLM_NAME;
+	const struct firmware *fw = NULL;
+	int ret = 0;
+
+	ret = dhd_os_get_img_fwreq(&fw, filepath);
+	if (ret < 0) {
+		DHD_ERROR(("%s: ----- blob file doesn't exist (%s) -----\n", __FUNCTION__,
+			filepath));
+		dhdp->is_blob = FALSE;
+	} else {
+		DHD_ERROR(("%s: ----- blob file exists (%s) -----\n", __FUNCTION__, filepath));
+		dhdp->is_blob = TRUE;
+#if defined(CONCATE_BLOB)
+		strncat(fw_path, "_blob", strlen("_blob"));
+#else
+		BCM_REFERENCE(fw_path);
+#endif /* SKIP_CONCATE_BLOB */
+		dhd_os_close_img_fwreq(fw);
+	}
+}
+#else
+void
+dhd_set_blob_support(dhd_pub_t *dhdp, char *fw_path)
+{
+	struct file *fp;
+	char *filepath = dhdp->info->clm_path;
+
+	fp = dhd_filp_open(filepath, O_RDONLY, 0);
+	if (IS_ERR(fp) || (fp == NULL)) {
+		DHD_ERROR(("%s: ----- blob file doesn't exist (%s) -----\n", __FUNCTION__,
+			filepath));
+		dhdp->is_blob = FALSE;
+	} else {
+		DHD_ERROR(("%s: ----- blob file exists (%s) -----\n", __FUNCTION__, filepath));
+		dhdp->is_blob = TRUE;
+#if defined(CONCATE_BLOB)
+		strncat(fw_path, "_blob", strlen("_blob"));
+#else
+		BCM_REFERENCE(fw_path);
+#endif /* SKIP_CONCATE_BLOB */
+		dhd_filp_close(fp, NULL);
+	}
+}
+#endif /* DHD_LINUX_STD_FW_API */
+#endif /* DHD_BLOB_EXISTENCE_CHECK */
+
+#if defined(PCIE_FULL_DONGLE)
+/** test / loopback */
+void
+dmaxfer_free_dmaaddr_handler(void *handle, void *event_info, u8 event)
+{
+	dmaxref_mem_map_t *dmmap = (dmaxref_mem_map_t *)event_info;
+	dhd_info_t *dhd_info = (dhd_info_t *)handle;
+
+	if (event != DHD_WQ_WORK_DMA_LB_MEM_REL) {
+		DHD_ERROR(("%s: unexpected event \n", __FUNCTION__));
+		return;
+	}
+	if (dhd_info == NULL) {
+		DHD_ERROR(("%s: invalid dhd_info\n", __FUNCTION__));
+		return;
+	}
+	if (dmmap == NULL) {
+		DHD_ERROR(("%s: dmmap is null\n", __FUNCTION__));
+		return;
+	}
+	dmaxfer_free_prev_dmaaddr(&dhd_info->pub, dmmap);
+}
+
+void
+dhd_schedule_dmaxfer_free(dhd_pub_t *dhdp, dmaxref_mem_map_t *dmmap)
+{
+	dhd_info_t *dhd_info = dhdp->info;
+
+	dhd_deferred_schedule_work(dhd_info->dhd_deferred_wq, (void *)dmmap,
+		DHD_WQ_WORK_DMA_LB_MEM_REL, dmaxfer_free_dmaaddr_handler, DHD_WQ_WORK_PRIORITY_LOW);
+}
+#endif /* PCIE_FULL_DONGLE */
+/* ---------------------------- End of sysfs implementation ------------------------------------- */
+
+int
+dhd_write_file(const char *filepath, char *buf, int buf_len)
+{
+	struct file *fp = NULL;
+#ifdef get_fs
+	mm_segment_t old_fs;
+#endif /* get_fs */
+	int ret = 0;
+
+#ifdef get_fs
+	/* change to KERNEL_DS address limit */
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+#endif /* get_fs */
+
+	/* File is always created. */
+	fp = dhd_filp_open(filepath, O_RDWR | O_CREAT, 0664);
+	if (IS_ERR(fp) || (fp == NULL)) {
+		DHD_ERROR(("%s: Couldn't open file '%s' err %ld\n",
+			__FUNCTION__, filepath, PTR_ERR(fp)));
+		ret = BCME_ERROR;
+	} else {
+		if (fp->f_mode & FMODE_WRITE) {
+			ret = dhd_vfs_write(fp, buf, buf_len, &fp->f_pos);
+			if (ret < 0) {
+				DHD_ERROR(("%s: Couldn't write file '%s'\n",
+					__FUNCTION__, filepath));
+				ret = BCME_ERROR;
+			} else {
+				ret = BCME_OK;
+			}
+		}
+		dhd_filp_close(fp, NULL);
+	}
+
+#ifdef get_fs
+	/* restore previous address limit */
+	set_fs(old_fs);
+#endif /* get_fs */
+
+	return ret;
+}
+
+int
+dhd_read_file(const char *filepath, char *buf, int buf_len)
+{
+	struct file *fp = NULL;
+#ifdef get_fs
+	mm_segment_t old_fs;
+#endif /* get_fs */
+	int ret;
+
+#ifdef get_fs
+	/* change to KERNEL_DS address limit */
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+#endif /* get_fs */
+
+	fp = dhd_filp_open(filepath, O_RDONLY, 0);
+	if (IS_ERR(fp) || (fp == NULL)) {
+#ifdef get_fs
+		set_fs(old_fs);
+#endif /* get_fs */
+		DHD_ERROR(("%s: File %s doesn't exist\n", __FUNCTION__, filepath));
+		return BCME_ERROR;
+	}
+
+	ret = dhd_kernel_read_compat(fp, 0, buf, buf_len);
+	dhd_filp_close(fp, NULL);
+
+#ifdef get_fs
+	/* restore previous address limit */
+	set_fs(old_fs);
+#endif /* get_fs */
+
+	/* Return the number of bytes read */
+	if (ret > 0) {
+		/* Success to read */
+		ret = 0;
+	} else {
+		DHD_ERROR(("%s: Couldn't read the file %s, ret=%d\n",
+			__FUNCTION__, filepath, ret));
+		ret = BCME_ERROR;
+	}
+
+	return ret;
+}
+
+int
+dhd_write_file_and_check(const char *filepath, char *buf, int buf_len)
+{
+	int ret;
+
+	ret = dhd_write_file(filepath, buf, buf_len);
+	if (ret < 0) {
+		return ret;
+	}
+
+	/* Read the file again and check if the file size is not zero */
+	memset(buf, 0, buf_len);
+	ret = dhd_read_file(filepath, buf, buf_len);
+
+	return ret;
+}
+
+#ifdef FILTER_IE
+int dhd_read_from_file(dhd_pub_t *dhd)
+{
+	int ret = 0;
+#ifdef DHD_LINUX_STD_FW_API
+	const struct firmware *fw = NULL;
+	char *filepath = FILTER_IE_PATH;
+	int filelen = 0;
+#else
+	int nread = 0;
+	void *fd;
+#endif /* DHD_LINUX_STD_FW_API */
+	uint8 *buf;
+	NULL_CHECK(dhd, "dhd is NULL", ret);
+
+	buf = MALLOCZ(dhd->osh, FILE_BLOCK_READ_SIZE);
+	if (!buf) {
+		DHD_ERROR(("error: failed to alllocate buf.\n"));
+		return BCME_NOMEM;
+	}
+
+	/* open file to read */
+#ifdef DHD_LINUX_STD_FW_API
+	ret = dhd_os_get_img_fwreq(&fw, filepath);
+	if (ret < 0) {
+		DHD_ERROR(("dhd_os_get_img_fwreq(%s) error : %d\n",
+			filepath, ret));
+		goto exit;
+	}
+
+	filelen = fw->size;
+	if (filelen == 0) {
+		DHD_ERROR(("error: zero length file.failed to read\n"));
+		ret = BCME_ERROR;
+		goto exit;
+	}
+
+	ret = memcpy_s(buf, FILE_BLOCK_READ_SIZE, fw->data, fw->size);
+	if (ret < 0) {
+		DHD_ERROR((" memcpy_s() error : %d\n", ret));
+		goto exit;
+	}
+
+	ret = dhd_parse_filter_ie(dhd, buf);
+	if (ret < 0) {
+		DHD_ERROR(("error: failed to parse filter ie\n"));
+	}
+#else
+	fd = dhd_os_open_image1(dhd, FILTER_IE_PATH);
+	if (!fd) {
+		DHD_ERROR(("No filter file(not an error), filter path%s\n", FILTER_IE_PATH));
+		ret = BCME_EPERM;
+		goto exit;
+	}
+	nread = dhd_os_get_image_block(buf, (FILE_BLOCK_READ_SIZE - 1), fd);
+	if (nread > 0) {
+		buf[nread] = '\0';
+		if ((ret = dhd_parse_filter_ie(dhd, buf)) < 0) {
+			DHD_ERROR(("error: failed to parse filter ie\n"));
+		}
+	} else {
+		DHD_ERROR(("error: zero length file.failed to read\n"));
+		ret = BCME_ERROR;
+	}
+#endif /* DHD_LINUX_STD_FW_API */
+exit:
+#ifdef DHD_LINUX_STD_FW_API
+	if (fw) {
+		dhd_os_close_img_fwreq(fw);
+	}
+#else
+	dhd_os_close_image1(dhd, fd);
+#endif /* DHD_LINUX_STD_FW_API */
+	if (buf) {
+		MFREE(dhd->osh, buf, FILE_BLOCK_READ_SIZE);
+	}
+	return ret;
+}
+
+int dhd_get_filter_ie_count(dhd_pub_t *dhdp, uint8* buf)
+{
+	uint8* pstr = buf;
+	int element_count = 0;
+
+	if (buf == NULL) {
+		return BCME_ERROR;
+	}
+
+	while (*pstr != '\0') {
+		if (*pstr == '\n') {
+			element_count++;
+		}
+		pstr++;
+	}
+	/*
+	 * New line character must not be present after last line.
+	 * To count last line
+	 */
+	element_count++;
+
+	return element_count;
+}
+
+int dhd_parse_oui(dhd_pub_t *dhd, uint8 *inbuf, uint8 *oui, int len)
+{
+	uint8 i, j, msb, lsb, oui_len = 0;
+	/*
+	 * OUI can vary from 3 bytes to 5 bytes.
+	 * While reading from file as ascii input it can
+	 * take maximum size of 14 bytes and minumum size of
+	 * 8 bytes including ":"
+	 * Example 5byte OUI <AB:DE:BE:CD:FA>
+	 * Example 3byte OUI <AB:DC:EF>
+	 */
+
+	if ((inbuf == NULL) || (len < 8) || (len > 14)) {
+		DHD_ERROR(("error: failed to parse OUI \n"));
+		return BCME_ERROR;
+	}
+
+	for (j = 0, i = 0; i < len; i += 3, ++j) {
+		if (!bcm_isxdigit(inbuf[i]) || !bcm_isxdigit(inbuf[i + 1])) {
+			DHD_ERROR(("error: invalid OUI format \n"));
+			return BCME_ERROR;
+		}
+		msb = inbuf[i] > '9' ? bcm_toupper(inbuf[i]) - 'A' + 10 : inbuf[i] - '0';
+		lsb = inbuf[i + 1] > '9' ? bcm_toupper(inbuf[i + 1]) -
+			'A' + 10 : inbuf[i + 1] - '0';
+		oui[j] = (msb << 4) | lsb;
+	}
+	/* Size of oui.It can vary from 3/4/5 */
+	oui_len = j;
+
+	return oui_len;
+}
+
+int dhd_check_valid_ie(dhd_pub_t *dhdp, uint8* buf, int len)
+{
+	int i = 0;
+
+	while (i < len) {
+		if (!bcm_isdigit(buf[i])) {
+			DHD_ERROR(("error: non digit value found in filter_ie \n"));
+			return BCME_ERROR;
+		}
+		i++;
+	}
+
+	return BCME_OK;
+}
+
+int dhd_parse_filter_ie(dhd_pub_t *dhd, uint8 *buf)
+{
+	int element_count = 0, i = 0, oui_size = 0, ret = 0;
+	uint16 bufsize, buf_space_left, id = 0, len = 0;
+	uint16 filter_iovsize, all_tlvsize;
+	wl_filter_ie_tlv_t *p_ie_tlv = NULL;
+	wl_filter_ie_iov_v1_t *p_filter_iov = (wl_filter_ie_iov_v1_t *) NULL;
+	char *token = NULL, *ele_token = NULL, *oui_token = NULL, *type = NULL;
+	uint8 data[20];
+
+	element_count = dhd_get_filter_ie_count(dhd, buf);
+	DHD_INFO(("total element count %d \n", element_count));
+	/* Calculate the whole buffer size */
+	filter_iovsize = sizeof(wl_filter_ie_iov_v1_t) + FILTER_IE_BUFSZ;
+	p_filter_iov = MALLOCZ(dhd->osh, filter_iovsize);
+
+	if (p_filter_iov == NULL) {
+		DHD_ERROR(("error: failed to allocate %d bytes of memory\n", filter_iovsize));
+		return BCME_ERROR;
+	}
+
+	/* setup filter iovar header */
+	p_filter_iov->version = WL_FILTER_IE_VERSION_1;
+	p_filter_iov->len = filter_iovsize;
+	p_filter_iov->fixed_length = p_filter_iov->len - FILTER_IE_BUFSZ;
+	p_filter_iov->pktflag = FC_PROBE_REQ;
+	p_filter_iov->option = WL_FILTER_IE_CHECK_SUB_OPTION;
+	/* setup TLVs */
+	bufsize = filter_iovsize - WL_FILTER_IE_IOV_HDR_SIZE; /* adjust available size for TLVs */
+	p_ie_tlv = (wl_filter_ie_tlv_t *)&p_filter_iov->tlvs[0];
+	buf_space_left = bufsize;
+
+	while ((i < element_count) && (buf != NULL)) {
+		len = 0;
+		/* token contains one line of input data */
+		token = bcmstrtok((char**)&buf, "\n", NULL);
+		if (token == NULL) {
+			break;
+		}
+		if ((ele_token = bcmstrstr(token, ",")) == NULL) {
+		/* only element id is present */
+			if (dhd_check_valid_ie(dhd, token, strlen(token)) == BCME_ERROR) {
+				DHD_ERROR(("error: Invalid element id \n"));
+				ret = BCME_ERROR;
+				goto exit;
+			}
+			id = bcm_atoi((char*)token);
+			data[len++] = WL_FILTER_IE_SET;
+		} else {
+			/* oui is present */
+			ele_token = bcmstrtok(&token, ",", NULL);
+			if ((ele_token == NULL) || (dhd_check_valid_ie(dhd, ele_token,
+				strlen(ele_token)) == BCME_ERROR)) {
+				DHD_ERROR(("error: Invalid element id \n"));
+				ret = BCME_ERROR;
+				goto exit;
+			}
+			id =  bcm_atoi((char*)ele_token);
+			data[len++] = WL_FILTER_IE_SET;
+			if ((oui_token = bcmstrstr(token, ",")) == NULL) {
+				oui_size = dhd_parse_oui(dhd, token, &(data[len]), strlen(token));
+				if (oui_size == BCME_ERROR) {
+					DHD_ERROR(("error: Invalid OUI \n"));
+					ret = BCME_ERROR;
+					goto exit;
+				}
+				len += oui_size;
+			} else {
+				/* type is present */
+				oui_token = bcmstrtok(&token, ",", NULL);
+				if ((oui_token == NULL) || ((oui_size =
+					dhd_parse_oui(dhd, oui_token,
+					&(data[len]), strlen(oui_token))) == BCME_ERROR)) {
+					DHD_ERROR(("error: Invalid OUI \n"));
+					ret = BCME_ERROR;
+					goto exit;
+				}
+				len += oui_size;
+				if ((type = bcmstrstr(token, ",")) == NULL) {
+					if (dhd_check_valid_ie(dhd, token,
+						strlen(token)) == BCME_ERROR) {
+						DHD_ERROR(("error: Invalid type \n"));
+						ret = BCME_ERROR;
+						goto exit;
+					}
+					data[len++] = bcm_atoi((char*)token);
+				} else {
+					/* subtype is present */
+					type = bcmstrtok(&token, ",", NULL);
+					if ((type == NULL) || (dhd_check_valid_ie(dhd, type,
+						strlen(type)) == BCME_ERROR)) {
+						DHD_ERROR(("error: Invalid type \n"));
+						ret = BCME_ERROR;
+						goto exit;
+					}
+					data[len++] = bcm_atoi((char*)type);
+					/* subtype is last element */
+					if ((token == NULL) || (*token == '\0') ||
+						(dhd_check_valid_ie(dhd, token,
+						strlen(token)) == BCME_ERROR)) {
+						DHD_ERROR(("error: Invalid subtype \n"));
+						ret = BCME_ERROR;
+						goto exit;
+					}
+					data[len++] = bcm_atoi((char*)token);
+				}
+			}
+		}
+		ret = bcm_pack_xtlv_entry((uint8 **)&p_ie_tlv,
+			&buf_space_left, id, len, data, BCM_XTLV_OPTION_ALIGN32);
+		if (ret != BCME_OK) {
+			DHD_ERROR(("%s : bcm_pack_xtlv_entry() failed ,"
+				"status=%d\n", __FUNCTION__, ret));
+			goto exit;
+		}
+		i++;
+	}
+	if (i == 0) {
+		/* file is empty or first line is blank */
+		DHD_ERROR(("error: filter_ie file is empty or first line is blank \n"));
+		ret = BCME_ERROR;
+		goto exit;
+	}
+	/* update the iov header, set len to include all TLVs + header */
+	all_tlvsize = (bufsize - buf_space_left);
+	p_filter_iov->len = htol16(all_tlvsize + WL_FILTER_IE_IOV_HDR_SIZE);
+	ret = dhd_iovar(dhd, 0, "filter_ie", (void *)p_filter_iov,
+			p_filter_iov->len, NULL, 0, TRUE);
+	if (ret != BCME_OK) {
+		DHD_ERROR(("error: IOVAR failed, status=%d\n", ret));
+	}
+exit:
+	/* clean up */
+	if (p_filter_iov) {
+		MFREE(dhd->osh, p_filter_iov, filter_iovsize);
+	}
+	return ret;
+}
+#endif /* FILTER_IE */
+#ifdef DHD_WAKE_STATUS
+wake_counts_t*
+dhd_get_wakecount(dhd_pub_t *dhdp)
+{
+#ifdef BCMDBUS
+	return NULL;
+#else
+	return dhd_bus_get_wakecount(dhdp);
+#endif /* BCMDBUS */
+}
+#endif /* DHD_WAKE_STATUS */
+
+int
+dhd_get_random_bytes(uint8 *buf, uint len)
+{
+#ifdef BCMPCIE
+	get_random_bytes(buf, len);
+#endif /* BCMPCIE */
+	return BCME_OK;
+}
+
+#if defined(DHD_HANG_SEND_UP_TEST)
+void
+dhd_make_hang_with_reason(struct net_device *dev, const char *string_num)
+{
+	dhd_info_t *dhd = NULL;
+	dhd_pub_t *dhdp = NULL;
+	uint reason = HANG_REASON_MAX;
+	uint32 fw_test_code = 0;
+	dhd = DHD_DEV_INFO(dev);
+
+	if (dhd) {
+		dhdp = &dhd->pub;
+	}
+
+	if (!dhd || !dhdp) {
+		return;
+	}
+
+	reason = (uint) bcm_strtoul(string_num, NULL, 0);
+	DHD_ERROR(("Enter %s, reason=0x%x\n", __FUNCTION__,  reason));
+
+	if (reason == 0) {
+		if (dhdp->req_hang_type) {
+			DHD_ERROR(("%s, Clear HANG test request 0x%x\n",
+				__FUNCTION__, dhdp->req_hang_type));
+			dhdp->req_hang_type = 0;
+			return;
+		} else {
+			DHD_ERROR(("%s, No requested HANG test\n", __FUNCTION__));
+			return;
+		}
+	} else if ((reason <= HANG_REASON_MASK) || (reason >= HANG_REASON_MAX)) {
+		DHD_ERROR(("Invalid HANG request, reason 0x%x\n", reason));
+		return;
+	}
+
+	if (dhdp->req_hang_type != 0) {
+		DHD_ERROR(("Already HANG requested for test\n"));
+		return;
+	}
+
+	switch (reason) {
+		case HANG_REASON_IOCTL_RESP_TIMEOUT:
+			DHD_ERROR(("Make HANG!!!: IOCTL response timeout(0x%x)\n", reason));
+			dhdp->req_hang_type = reason;
+			fw_test_code = 102; /* resumed on timeour */
+			(void) dhd_wl_ioctl_set_intiovar(dhdp, "bus:disconnect", fw_test_code,
+				WLC_SET_VAR, TRUE, 0);
+			break;
+		case HANG_REASON_DONGLE_TRAP:
+			DHD_ERROR(("Make HANG!!!: Dongle trap (0x%x)\n", reason));
+			dhdp->req_hang_type = reason;
+			fw_test_code = 99; /* dongle trap */
+			(void) dhd_wl_ioctl_set_intiovar(dhdp, "bus:disconnect", fw_test_code,
+				WLC_SET_VAR, TRUE, 0);
+			break;
+		case HANG_REASON_D3_ACK_TIMEOUT:
+			DHD_ERROR(("Make HANG!!!: D3 ACK timeout (0x%x)\n", reason));
+			dhdp->req_hang_type = reason;
+			break;
+		case HANG_REASON_BUS_DOWN:
+			DHD_ERROR(("Make HANG!!!: BUS down(0x%x)\n", reason));
+			dhdp->req_hang_type = reason;
+			break;
+		case HANG_REASON_PCIE_LINK_DOWN_RC_DETECT:
+		case HANG_REASON_PCIE_LINK_DOWN_EP_DETECT:
+		case HANG_REASON_MSGBUF_LIVELOCK:
+			dhdp->req_hang_type = 0;
+			DHD_ERROR(("Does not support requested HANG(0x%x)\n", reason));
+			break;
+		case HANG_REASON_IFACE_DEL_FAILURE:
+			dhdp->req_hang_type = 0;
+			DHD_ERROR(("Does not support requested HANG(0x%x)\n", reason));
+			break;
+		case HANG_REASON_HT_AVAIL_ERROR:
+			dhdp->req_hang_type = 0;
+			DHD_ERROR(("PCIe does not support requested HANG(0x%x)\n", reason));
+			break;
+		case HANG_REASON_PCIE_RC_LINK_UP_FAIL:
+			DHD_ERROR(("Make HANG!!!:Link Up(0x%x)\n", reason));
+			dhdp->req_hang_type = reason;
+			break;
+		default:
+			dhdp->req_hang_type = 0;
+			DHD_ERROR(("Unknown HANG request (0x%x)\n", reason));
+			break;
+	}
+}
+#endif /* DHD_HANG_SEND_UP_TEST */
+
+#ifdef DHD_TX_PROFILE
+static int
+process_layer2_headers(uint8 **p, int *plen, uint16 *type, bool is_host_sfhllc)
+{
+	int err = BCME_OK;
+
+	if (*type < ETHER_TYPE_MIN) {
+		struct dot3_mac_llc_snap_header *sh = (struct dot3_mac_llc_snap_header *)*p;
+
+		if (bcmp(&sh->dsap, llc_snap_hdr, SNAP_HDR_LEN) == 0) {
+			*type = ntoh16(sh->type);
+			if (*type == ETHER_TYPE_8021Q ||
+				(is_host_sfhllc && *type != ETHER_TYPE_8021Q)) {
+				*p += sizeof(struct dot3_mac_llc_snap_header);
+				if ((*plen -= sizeof(struct dot3_mac_llc_snap_header)) <= 0) {
+					err = BCME_ERROR;
+				}
+			}
+			else {
+				struct dot3_mac_llc_snapvlan_header *svh = (struct
+					dot3_mac_llc_snapvlan_header *)*p;
+
+				*type = ntoh16(svh->ether_type);
+				*p += sizeof(struct dot3_mac_llc_snapvlan_header);
+				if ((*plen -= sizeof(struct dot3_mac_llc_snapvlan_header)) <= 0) {
+					err = BCME_ERROR;
+				}
+			}
+		}
+		else {
+			err = BCME_ERROR;
+		}
+	}
+	else {
+		if (*type == ETHER_TYPE_8021Q) {
+			struct ethervlan_header *evh = (struct ethervlan_header *)*p;
+
+			*type = ntoh16(evh->ether_type);
+			*p += ETHERVLAN_HDR_LEN;
+			if ((*plen -= ETHERVLAN_HDR_LEN) <= 0) {
+				err = BCME_ERROR;
+			}
+		}
+		else {
+			*p += ETHER_HDR_LEN;
+			if ((*plen -= ETHER_HDR_LEN) <= 0) {
+				err = BCME_ERROR;
+			}
+		}
+	}
+
+	return err;
+}
+
+static int
+process_layer3_headers(uint8 **p, int plen, uint16 *type)
+{
+	int err = BCME_OK;
+
+	if (*type == ETHER_TYPE_IP) {
+		struct ipv4_hdr *iph = (struct ipv4_hdr *)*p;
+		uint16 len = IPV4_HLEN(iph);
+		if ((plen -= len) <= 0) {
+			err = BCME_ERROR;
+		} else if (IP_VER(iph) == IP_VER_4 && len >= IPV4_MIN_HEADER_LEN) {
+			*type = IPV4_PROT(iph);
+			*p += len;
+		} else {
+			err = BCME_ERROR;
+		}
+	} else if (*type == ETHER_TYPE_IPV6) {
+		struct ipv6_hdr *ip6h = (struct ipv6_hdr *)*p;
+		if ((plen -= IPV6_MIN_HLEN) <= 0) {
+			err = BCME_ERROR;
+		} else if (IP_VER(ip6h) == IP_VER_6) {
+			*type = IPV6_PROT(ip6h);
+			*p += IPV6_MIN_HLEN;
+			if (IPV6_EXTHDR(*type)) {
+				uint8 proto_6 = 0;
+				int32 exth_len = ipv6_exthdr_len(*p, &proto_6);
+				if (exth_len < 0 || ((plen -= exth_len) <= 0)) {
+					err = BCME_ERROR;
+				} else {
+					*type = proto_6;
+					*p += exth_len;
+				}
+			}
+		} else {
+			err = BCME_ERROR;
+		}
+	}
+
+	return err;
+}
+
+bool
+dhd_protocol_matches_profile(uint8 *p, int plen, const dhd_tx_profile_protocol_t
+		*proto, bool is_host_sfhllc)
+{
+	struct ether_header *eh = NULL;
+	bool result = FALSE;
+	uint16 type = 0, ether_type = 0;
+
+	ASSERT(proto != NULL);
+	ASSERT(p != NULL);
+
+	if (plen <= 0) {
+		result = FALSE;
+	} else {
+		eh = (struct ether_header *)p;
+		type = ntoh16(eh->ether_type);
+		if (type < ETHER_TYPE_MIN && is_host_sfhllc) {
+			struct dot3_mac_llc_snap_header *dot3 =
+				(struct dot3_mac_llc_snap_header *)p;
+			ether_type = ntoh16(dot3->type);
+		} else {
+			ether_type = type;
+		}
+
+		if (proto->layer == DHD_TX_PROFILE_DATA_LINK_LAYER &&
+				proto->protocol_number == ether_type) {
+			result = TRUE;
+		} else if (process_layer2_headers(&p, &plen, &type, is_host_sfhllc) != BCME_OK) {
+			/* pass 'type' instead of 'ether_type' to process_layer2_headers
+			 * because process_layer2_headers will take care of extraction
+			 * of protocol types if llc snap header is present, based on
+			 * the condition (type < ETHER_TYPE_MIN)
+			 */
+			result = FALSE;
+		} else if (proto->layer == DHD_TX_PROFILE_DATA_LINK_LAYER) {
+			result = proto->protocol_number == type;
+		} else if (proto->layer != DHD_TX_PROFILE_NETWORK_LAYER) {
+			result = FALSE;
+		} else if (process_layer3_headers(&p, plen, &type) != BCME_OK) {
+			result = FALSE;
+		} else if (proto->protocol_number == type) {
+			/* L4, only check TCP/UDP case */
+			if ((type == IP_PROT_TCP) || (type == IP_PROT_UDP)) {
+				/* src/dst port are the first two uint16 fields in both tcp/udp
+				 * hdr
+				 */
+				struct bcmudp_hdr *hdr = (struct bcmudp_hdr *)p;
+
+				/* note that a src_port or dest_port of zero counts as a match
+				 */
+				result = ((proto->src_port == 0) || (proto->src_port ==
+					ntoh16(hdr->src_port))) && ((proto->dest_port == 0) ||
+					(proto->dest_port == ntoh16(hdr->dst_port)));
+			} else {
+				/* at this point we know we are dealing with layer 3, and we
+				 * know we are not dealing with TCP or UDP; this is considered a
+				 * match
+				 */
+				result = TRUE;
+			}
+		}
+	}
+
+	return result;
+}
+#endif /* defined(DHD_TX_PROFILE) */
+
+#ifdef BCMPCIE
+#define KIRQ_PRINT_BUF_LEN 256
+
+void
+dhd_print_kirqstats(dhd_pub_t *dhd, unsigned int irq_num)
+{
+	unsigned long flags = 0;
+	struct irq_desc *desc;
+	int i;          /* cpu iterator */
+	struct bcmstrbuf strbuf;
+	char tmp_buf[KIRQ_PRINT_BUF_LEN];
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0))
+	desc = irq_to_desc(irq_num);
+#else // (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0))
+	desc = irq_data_to_desc(irq_get_irq_data(irq_num));
+#endif // (LINUX_VERSION_CODE < KERNEL_VERSION(5, 11, 0))
+	if (!desc) {
+		DHD_ERROR(("%s : irqdesc is not found \n", __FUNCTION__));
+		return;
+	}
+	bcm_binit(&strbuf, tmp_buf, KIRQ_PRINT_BUF_LEN);
+	raw_spin_lock_irqsave(&desc->lock, flags);
+	bcm_bprintf(&strbuf, "dhd irq %u:", irq_num);
+	for_each_online_cpu(i)
+		bcm_bprintf(&strbuf, "%10u ",
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 10, 0)
+			desc->kstat_irqs ? per_cpu(desc->kstat_irqs->cnt, i) : 0);
+#else
+			desc->kstat_irqs ? *per_cpu_ptr(desc->kstat_irqs, i) : 0);
+#endif /* LINUX VERSION > 6.10.0 */
+	if (desc->irq_data.chip) {
+		if (desc->irq_data.chip->name)
+			bcm_bprintf(&strbuf, " %8s", desc->irq_data.chip->name);
+		else
+			bcm_bprintf(&strbuf, " %8s", "-");
+	} else {
+		bcm_bprintf(&strbuf, " %8s", "None");
+	}
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0))
+	if (desc->irq_data.domain)
+		bcm_bprintf(&strbuf, " %d", (int)desc->irq_data.hwirq);
+#ifdef CONFIG_GENERIC_IRQ_SHOW_LEVEL
+	bcm_bprintf(&strbuf, " %-8s", irqd_is_level_type(&desc->irq_data) ? "Level" : "Edge");
+#endif
+#endif /* LINUX VERSION > 3.1.0 */
+
+	if (desc->name)
+		bcm_bprintf(&strbuf, "-%-8s", desc->name);
+
+	DHD_ERROR(("%s\n", strbuf.origbuf));
+	raw_spin_unlock_irqrestore(&desc->lock, flags);
+#endif /* LINUX VERSION > 2.6.28 */
+}
+#endif /* BCMPCIE */
+
+void
+dhd_show_kirqstats(dhd_pub_t *dhd)
+{
+	unsigned int irq = -1;
+#ifdef BCMPCIE
+	dhdpcie_get_pcieirq(dhd->bus, &irq);
+#endif /* BCMPCIE */
+#ifdef BCMSDIO
+	irq = ((wifi_adapter_info_t *)dhd->info->adapter)->irq_num;
+#endif /* BCMSDIO */
+	if (irq != -1) {
+#ifdef BCMPCIE
+		DHD_ERROR(("DUMP data kernel irq stats : \n"));
+		dhd_print_kirqstats(dhd, irq);
+#endif /* BCMPCIE */
+#ifdef BCMSDIO
+		DHD_ERROR(("DUMP data/host wakeup kernel irq stats : \n"));
+#endif /* BCMSDIO */
+	}
+#ifdef BCMPCIE_OOB_HOST_WAKE
+	irq = dhd_bus_get_oob_irq_num(dhd);
+	if (irq) {
+		DHD_ERROR(("DUMP PCIE host wakeup kernel irq stats : \n"));
+		dhd_print_kirqstats(dhd, irq);
+	}
+#endif /* BCMPCIE_OOB_HOST_WAKE */
+}
+
+void
+dhd_print_tasklet_status(dhd_pub_t *dhd)
+{
+	dhd_info_t *dhdinfo;
+
+	if (!dhd) {
+		DHD_ERROR(("%s : DHD is null\n", __FUNCTION__));
+		return;
+	}
+
+	dhdinfo = dhd->info;
+
+	if (!dhdinfo) {
+		DHD_ERROR(("%s : DHD INFO is null \n", __FUNCTION__));
+		return;
+	}
+
+	DHD_ERROR(("DHD Tasklet status : 0x%lx\n", dhdinfo->tasklet.state));
+#ifndef BCMDBUS
+	DHD_ERROR(("DPC thread thr_pid: %ld\n", dhdinfo->thr_dpc_ctl.thr_pid));
+#endif /* BCMDBUS */
+}
+
+#if defined(DHD_MQ) && defined(DHD_MQ_STATS)
+void
+dhd_mqstats_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+{
+	dhd_info_t *dhd = NULL;
+	int i = 0, j = 0;
+
+	if (!dhdp || !strbuf)
+		return;
+
+	dhd = dhdp->info;
+	bcm_bprintf(strbuf, "\nMQ STATS:\n=========\n");
+
+	bcm_bprintf(strbuf, "\nTx packet arrival AC histogram:\n");
+	bcm_bprintf(strbuf, "AC_BE    \tAC_BK    \tAC_VI    \tAC_VO\n");
+	bcm_bprintf(strbuf, "-----    \t-----    \t-----    \t-----\n");
+	for (i = 0; i < AC_COUNT; i++)
+		bcm_bprintf(strbuf, "%-10d\t", dhd->pktcnt_per_ac[i]);
+
+	bcm_bprintf(strbuf, "\n\nTx packet arrival Q-AC histogram:\n");
+	bcm_bprintf(strbuf, "\tAC_BE    \tAC_BK    \tAC_VI    \tAC_VO\n");
+	bcm_bprintf(strbuf, "\t-----    \t-----    \t-----    \t-----");
+	for (i = 0; i < MQ_MAX_QUEUES; i++) {
+		bcm_bprintf(strbuf, "\nQ%d\t", i);
+		for (j = 0; j < AC_COUNT; j++)
+			bcm_bprintf(strbuf, "%-8d\t", dhd->pktcnt_qac_histo[i][j]);
+	}
+
+	bcm_bprintf(strbuf, "\n\nTx Q-CPU scheduling histogram:\n");
+	bcm_bprintf(strbuf, "\t");
+	for (i = 0; i < nr_cpu_ids; i++)
+		bcm_bprintf(strbuf, "CPU%d    \t", i);
+	for (i = 0; i < MQ_MAX_QUEUES; i++) {
+		bcm_bprintf(strbuf, "\nQ%d\t", i);
+		for (j = 0; j < nr_cpu_ids; j++)
+			bcm_bprintf(strbuf, "%-8d\t", dhd->cpu_qstats[i][j]);
+	}
+	bcm_bprintf(strbuf, "\n");
+}
+#endif /* DHD_MQ && DHD_MQ_STATS */
+
+#ifdef DHD_MAP_LOGGING
+/* Will be called from SMMU fault handler */
+void
+dhd_smmu_fault_handler(uint32 axid, ulong fault_addr)
+{
+	dhd_pub_t *dhdp = (dhd_pub_t *)g_dhd_pub;
+	uint32 irq = (uint32)-1;
+
+	DHD_ERROR(("%s: Trigger SMMU Fault\n", __FUNCTION__));
+	DHD_ERROR(("%s: axid:0x%x, fault_addr:0x%lx", __FUNCTION__, axid, fault_addr));
+	dhdp->smmu_fault_occurred = TRUE;
+#ifdef DNGL_AXI_ERROR_LOGGING
+	dhdp->axi_error = TRUE;
+	dhdp->axi_err_dump->axid = axid;
+	dhdp->axi_err_dump->fault_address = fault_addr;
+#endif /* DNGL_AXI_ERROR_LOGGING */
+
+	/* Disable PCIe IRQ */
+	dhdpcie_get_pcieirq(dhdp->bus, &irq);
+	if (irq != (uint32)-1) {
+		disable_irq_nosync(irq);
+	}
+
+	/* Take debug information first */
+	DHD_OS_WAKE_LOCK(dhdp);
+	dhd_prot_smmu_fault_dump(dhdp);
+	DHD_OS_WAKE_UNLOCK(dhdp);
+
+	/* Take AXI information if possible */
+#ifdef DNGL_AXI_ERROR_LOGGING
+#ifdef DHD_USE_WQ_FOR_DNGL_AXI_ERROR
+	dhd_axi_error_dispatch(dhdp);
+#else
+	dhd_axi_error(dhdp);
+#endif /* DHD_USE_WQ_FOR_DNGL_AXI_ERROR */
+#endif /* DNGL_AXI_ERROR_LOGGING */
+}
+EXPORT_SYMBOL(dhd_smmu_fault_handler);
+#endif /* DHD_MAP_LOGGING */
+
+#ifdef DHD_PKT_LOGGING
+int
+dhd_pktlog_debug_dump(dhd_pub_t *dhdp)
+{
+	struct net_device *primary_ndev;
+	struct bcm_cfg80211 *cfg;
+	unsigned long flags = 0;
+
+	primary_ndev = dhd_linux_get_primary_netdev(dhdp);
+	if (!primary_ndev) {
+		DHD_ERROR(("%s: Cannot find primary netdev\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	cfg = wl_get_cfg(primary_ndev);
+	if (!cfg) {
+		DHD_ERROR(("%s: Cannot find cfg\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	DHD_GENERAL_LOCK(dhdp, flags);
+	if (DHD_BUS_BUSY_CHECK_IN_HALDUMP(dhdp)) {
+		DHD_GENERAL_UNLOCK(dhdp, flags);
+		DHD_ERROR(("%s: HAL dump is already triggered \n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	DHD_BUS_BUSY_SET_IN_HALDUMP(dhdp);
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+	DHD_OS_WAKE_LOCK(dhdp);
+
+	if (wl_cfg80211_is_hal_started(cfg)) {
+		dhdp->pktlog_debug = TRUE;
+		dhd_dbg_send_urgent_evt(dhdp, NULL, 0);
+	} else {
+		DHD_ERROR(("[DUMP] %s: HAL Not started. skip urgent event\n", __FUNCTION__));
+	}
+	DHD_OS_WAKE_UNLOCK(dhdp);
+	/* In case of dhd_os_busbusy_wait_bitmask() timeout,
+	 * hal dump bit will not be cleared. Hence clearing it here.
+	 */
+	DHD_GENERAL_LOCK(dhdp, flags);
+	DHD_BUS_BUSY_CLEAR_IN_HALDUMP(dhdp);
+	dhd_os_busbusy_wake(dhdp);
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+
+	return BCME_OK;
+}
+
+void
+dhd_pktlog_dump(void *handle, void *event_info, u8 event)
+{
+	dhd_info_t *dhd = handle;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	if (dhd_pktlog_dump_write_file(&dhd->pub)) {
+		DHD_ERROR(("%s: writing pktlog dump file failed\n", __FUNCTION__));
+		return;
+	}
+}
+
+void
+dhd_schedule_pktlog_dump(dhd_pub_t *dhdp)
+{
+	dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq,
+			(void*)NULL, DHD_WQ_WORK_PKTLOG_DUMP,
+			dhd_pktlog_dump, DHD_WQ_WORK_PRIORITY_HIGH);
+}
+#endif /* DHD_PKT_LOGGING */
+
+#ifdef DHDTCPSYNC_FLOOD_BLK
+static void dhd_blk_tsfl_handler(struct work_struct * work)
+{
+	dhd_if_t *ifp = NULL;
+	dhd_pub_t *dhdp = NULL;
+	/* Ignore compiler warnings due to -Werror=cast-qual */
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	ifp = container_of(work, dhd_if_t, blk_tsfl_work);
+	GCC_DIAGNOSTIC_POP();
+
+	if (ifp) {
+		dhdp = &ifp->info->pub;
+		if (dhdp) {
+			if ((dhdp->op_mode & DHD_FLAG_P2P_GO_MODE)||
+				(dhdp->op_mode & DHD_FLAG_HOSTAP_MODE)) {
+				DHD_ERROR(("Disassoc due to TCP SYNC FLOOD ATTACK\n"));
+				wl_cfg80211_del_all_sta(ifp->net, WLAN_REASON_UNSPECIFIED);
+			} else if ((dhdp->op_mode & DHD_FLAG_P2P_GC_MODE)||
+				(dhdp->op_mode & DHD_FLAG_STA_MODE)) {
+				DHD_ERROR(("Diconnect due to TCP SYNC FLOOD ATTACK\n"));
+				wl_cfg80211_disassoc(ifp->net, WLAN_REASON_UNSPECIFIED);
+			}
+			ifp->disconnect_tsync_flood = TRUE;
+		}
+	}
+}
+void dhd_reset_tcpsync_info_by_ifp(dhd_if_t *ifp)
+{
+	ifp->tsync_rcvd = 0;
+	ifp->tsyncack_txed = 0;
+	ifp->last_sync = DIV_U64_BY_U32(OSL_LOCALTIME_NS(), NSEC_PER_SEC);
+}
+void dhd_reset_tcpsync_info_by_dev(struct net_device *dev)
+{
+	dhd_if_t *ifp = NULL;
+	if (dev) {
+		ifp = DHD_DEV_IFP(dev);
+	}
+	if (ifp) {
+		ifp->tsync_rcvd = 0;
+		ifp->tsyncack_txed = 0;
+		ifp->last_sync = DIV_U64_BY_U32(OSL_LOCALTIME_NS(), NSEC_PER_SEC);
+		ifp->tsync_per_sec = 0;
+		ifp->disconnect_tsync_flood = FALSE;
+	}
+}
+#endif /* DHDTCPSYNC_FLOOD_BLK */
+
+#ifdef DHD_4WAYM4_FAIL_DISCONNECT
+static void dhd_m4_state_handler(struct work_struct *work)
+{
+	dhd_if_t *ifp = NULL;
+	/* Ignore compiler warnings due to -Werror=cast-qual */
+	struct delayed_work *dw = to_delayed_work(work);
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	ifp = container_of(dw, dhd_if_t, m4state_work);
+	GCC_DIAGNOSTIC_POP();
+
+	if (ifp && ifp->net &&
+		(OSL_ATOMIC_READ(ifp->info->pub->osh, &ifp->m4state) == M4_TXFAILED)) {
+		DHD_ERROR(("Disassoc for 4WAY_HANDSHAKE_TIMEOUT at %s\n",
+				ifp->net->name));
+		wl_cfg80211_disassoc(ifp->net, WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT);
+	}
+}
+
+void
+dhd_cleanup_m4_state_work(dhd_pub_t *dhdp, int ifidx)
+{
+	dhd_info_t *dhdinfo;
+	dhd_if_t *ifp;
+
+	if ((ifidx < 0) || (ifidx >= DHD_MAX_IFS)) {
+		DHD_ERROR(("%s: invalid ifidx %d\n", __FUNCTION__, ifidx));
+		return;
+	}
+
+	dhdinfo = (dhd_info_t *)(dhdp->info);
+	if (!dhdinfo) {
+		DHD_ERROR(("%s: dhdinfo is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	ifp = dhdinfo->iflist[ifidx];
+	if (ifp) {
+		cancel_delayed_work_sync(&ifp->m4state_work);
+	}
+}
+#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
+
+/*
+ * DHD RING
+ */
+#define DHD_RING_ERR_INTERNAL(fmt, ...) DHD_ERROR(("EWPF-" fmt, ##__VA_ARGS__))
+#define DHD_RING_TRACE_INTERNAL(fmt, ...) DHD_INFO(("EWPF-" fmt, ##__VA_ARGS__))
+
+#define DHD_RING_ERR(x) DHD_RING_ERR_INTERNAL x
+#define DHD_RING_TRACE(x) DHD_RING_TRACE_INTERNAL x
+
+#define DHD_RING_MAGIC 0x20170910
+#define DHD_RING_IDX_INVALID	0xffffffff
+
+#define DHD_RING_SYNC_LOCK_INIT(osh)		osl_spin_lock_init(osh)
+#define DHD_RING_SYNC_LOCK_DEINIT(osh, lock)	osl_spin_lock_deinit(osh, lock)
+#define DHD_RING_SYNC_LOCK(lock, flags)		(flags) = osl_spin_lock(lock)
+#define DHD_RING_SYNC_UNLOCK(lock, flags)	osl_spin_unlock(lock, flags)
+
+typedef struct {
+	uint32 elem_size;
+	uint32 elem_cnt;
+	uint32 write_idx;	/* next write index, -1 : not started */
+	uint32 read_idx;	/* next read index, -1 : not start */
+
+	/* protected elements during serialization */
+	int lock_idx;	/* start index of locked, element will not be overried */
+	int lock_count; /* number of locked, from lock idx */
+
+	/* saved data elements */
+	void *elem;
+} dhd_fixed_ring_info_t;
+
+typedef struct {
+	uint32 elem_size;
+	uint32 elem_cnt;
+	uint32 idx;		/* -1 : not started */
+	uint32 rsvd;		/* reserved for future use */
+
+	/* protected elements during serialization */
+	atomic_t ring_locked;
+	/* check the overwriting */
+	uint32 ring_overwrited;
+
+	/* saved data elements */
+	void *elem;
+} dhd_singleidx_ring_info_t;
+
+typedef struct {
+	uint32 magic;
+	uint32 type;
+	void *ring_sync; /* spinlock for sync */
+	union {
+		dhd_fixed_ring_info_t fixed;
+		dhd_singleidx_ring_info_t single;
+	};
+} dhd_ring_info_t;
+
+uint32
+dhd_ring_get_hdr_size(void)
+{
+	return sizeof(dhd_ring_info_t);
+}
+
+void *
+dhd_ring_init(dhd_pub_t *dhdp, uint8 *buf, uint32 buf_size, uint32 elem_size,
+	uint32 elem_cnt, uint32 type)
+{
+	dhd_ring_info_t *ret_ring;
+
+	if (!buf) {
+		DHD_RING_ERR(("NO RING BUFFER\n"));
+		return NULL;
+	}
+
+	if (buf_size < dhd_ring_get_hdr_size() + elem_size * elem_cnt) {
+		DHD_RING_ERR(("RING SIZE IS TOO SMALL\n"));
+		return NULL;
+	}
+
+	if (type != DHD_RING_TYPE_FIXED && type != DHD_RING_TYPE_SINGLE_IDX) {
+		DHD_RING_ERR(("UNSUPPORTED RING TYPE\n"));
+		return NULL;
+	}
+
+	ret_ring = (dhd_ring_info_t *)buf;
+	ret_ring->type = type;
+	ret_ring->ring_sync = (void *)DHD_RING_SYNC_LOCK_INIT(dhdp->osh);
+	ret_ring->magic = DHD_RING_MAGIC;
+
+	if (type == DHD_RING_TYPE_FIXED) {
+		ret_ring->fixed.read_idx = DHD_RING_IDX_INVALID;
+		ret_ring->fixed.write_idx = DHD_RING_IDX_INVALID;
+		ret_ring->fixed.lock_idx = DHD_RING_IDX_INVALID;
+		ret_ring->fixed.elem = buf + sizeof(dhd_ring_info_t);
+		ret_ring->fixed.elem_size = elem_size;
+		ret_ring->fixed.elem_cnt = elem_cnt;
+	} else {
+		ret_ring->single.idx = DHD_RING_IDX_INVALID;
+		atomic_set(&ret_ring->single.ring_locked, 0);
+		ret_ring->single.ring_overwrited = 0;
+		ret_ring->single.rsvd = 0;
+		ret_ring->single.elem = buf + sizeof(dhd_ring_info_t);
+		ret_ring->single.elem_size = elem_size;
+		ret_ring->single.elem_cnt = elem_cnt;
+	}
+
+	return ret_ring;
+}
+
+void
+dhd_ring_deinit(dhd_pub_t *dhdp, void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	if (!ring) {
+		return;
+	}
+
+	if (ring->magic != DHD_RING_MAGIC) {
+		return;
+	}
+
+	if (ring->type != DHD_RING_TYPE_FIXED &&
+		ring->type != DHD_RING_TYPE_SINGLE_IDX) {
+		return;
+	}
+
+	DHD_RING_SYNC_LOCK_DEINIT(dhdp->osh, ring->ring_sync);
+	ring->ring_sync = NULL;
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		dhd_fixed_ring_info_t *fixed = &ring->fixed;
+		memset(fixed->elem, 0, fixed->elem_size * fixed->elem_cnt);
+		fixed->elem_size = fixed->elem_cnt = 0;
+	} else {
+		dhd_singleidx_ring_info_t *single = &ring->single;
+		memset(single->elem, 0, single->elem_size * single->elem_cnt);
+		single->elem_size = single->elem_cnt = 0;
+	}
+	ring->type = 0;
+	ring->magic = 0;
+}
+
+static inline uint32
+__dhd_ring_ptr2idx(void *ring, void *ptr, char *sig, uint32 type)
+{
+	uint32 diff;
+	uint32 ret_idx = (uint32)DHD_RING_IDX_INVALID;
+	uint32 elem_size, elem_cnt;
+	void *elem;
+
+	if (type == DHD_RING_TYPE_FIXED) {
+		dhd_fixed_ring_info_t *fixed = (dhd_fixed_ring_info_t *)ring;
+		elem_size = fixed->elem_size;
+		elem_cnt = fixed->elem_cnt;
+		elem = fixed->elem;
+	} else if (type == DHD_RING_TYPE_SINGLE_IDX) {
+		dhd_singleidx_ring_info_t *single = (dhd_singleidx_ring_info_t *)ring;
+		elem_size = single->elem_size;
+		elem_cnt = single->elem_cnt;
+		elem = single->elem;
+	} else {
+		DHD_RING_ERR(("UNSUPPORTED RING TYPE %d\n", type));
+		return ret_idx;
+	}
+
+	if (ptr < elem) {
+		DHD_RING_ERR(("INVALID POINTER %s:%p, ring->elem:%p\n", sig, ptr, elem));
+		return ret_idx;
+	}
+	diff = (uint32)((uint8 *)ptr - (uint8 *)elem);
+	if (diff % elem_size != 0) {
+		DHD_RING_ERR(("INVALID POINTER %s:%p, ring->elem:%p\n", sig, ptr, elem));
+		return ret_idx;
+	}
+	ret_idx = diff / elem_size;
+	if (ret_idx >= elem_cnt) {
+		DHD_RING_ERR(("INVALID POINTER max:%d cur:%d\n", elem_cnt, ret_idx));
+	}
+	return ret_idx;
+}
+
+/* Sub functions for fixed ring */
+/* get counts between two indexes of ring buffer (internal only) */
+static inline int
+__dhd_fixed_ring_get_count(dhd_fixed_ring_info_t *ring, int start, int end)
+{
+	if (start == DHD_RING_IDX_INVALID || end == DHD_RING_IDX_INVALID) {
+		return 0;
+	}
+
+	return (ring->elem_cnt + end - start) % ring->elem_cnt + 1;
+}
+
+static inline int
+__dhd_fixed_ring_get_cur_size(dhd_fixed_ring_info_t *ring)
+{
+	return __dhd_fixed_ring_get_count(ring, ring->read_idx, ring->write_idx);
+}
+
+static inline void *
+__dhd_fixed_ring_get_first(dhd_fixed_ring_info_t *ring)
+{
+	if (ring->read_idx == DHD_RING_IDX_INVALID) {
+		return NULL;
+	}
+	return (uint8 *)ring->elem + (ring->elem_size * ring->read_idx);
+}
+
+static inline void
+__dhd_fixed_ring_free_first(dhd_fixed_ring_info_t *ring)
+{
+	uint32 next_idx;
+
+	if (ring->read_idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("EMPTY RING\n"));
+		return;
+	}
+
+	next_idx = (ring->read_idx + 1) % ring->elem_cnt;
+	if (ring->read_idx == ring->write_idx) {
+		/* Become empty */
+		ring->read_idx = ring->write_idx = DHD_RING_IDX_INVALID;
+		return;
+	}
+
+	ring->read_idx = next_idx;
+	return;
+}
+
+static inline void *
+__dhd_fixed_ring_get_last(dhd_fixed_ring_info_t *ring)
+{
+	if (ring->read_idx == DHD_RING_IDX_INVALID) {
+		return NULL;
+	}
+	return (uint8 *)ring->elem + (ring->elem_size * ring->write_idx);
+}
+
+static inline void *
+__dhd_fixed_ring_get_empty(dhd_fixed_ring_info_t *ring)
+{
+	uint32 tmp_idx;
+
+	if (ring->read_idx == DHD_RING_IDX_INVALID) {
+		ring->read_idx = ring->write_idx = 0;
+		return (uint8 *)ring->elem;
+	}
+
+	/* check next index is not locked */
+	tmp_idx = (ring->write_idx + 1) % ring->elem_cnt;
+	if (ring->lock_idx == tmp_idx) {
+		return NULL;
+	}
+
+	ring->write_idx = tmp_idx;
+	if (ring->write_idx == ring->read_idx) {
+		/* record is full, drop oldest one */
+		ring->read_idx = (ring->read_idx + 1) % ring->elem_cnt;
+
+	}
+	return (uint8 *)ring->elem + (ring->elem_size * ring->write_idx);
+}
+
+static inline void *
+__dhd_fixed_ring_get_next(dhd_fixed_ring_info_t *ring, void *prev, uint32 type)
+{
+	uint32 cur_idx;
+
+	if (ring->read_idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("EMPTY RING\n"));
+		return NULL;
+	}
+
+	cur_idx = __dhd_ring_ptr2idx(ring, prev, "NEXT", type);
+	if (cur_idx >= ring->elem_cnt) {
+		return NULL;
+	}
+
+	if (cur_idx == ring->write_idx) {
+		/* no more new record */
+		return NULL;
+	}
+
+	cur_idx = (cur_idx + 1) % ring->elem_cnt;
+	return (uint8 *)ring->elem + ring->elem_size * cur_idx;
+}
+
+static inline void *
+__dhd_fixed_ring_get_prev(dhd_fixed_ring_info_t *ring, void *prev, uint32 type)
+{
+	uint32 cur_idx;
+
+	if (ring->read_idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("EMPTY RING\n"));
+		return NULL;
+	}
+	cur_idx = __dhd_ring_ptr2idx(ring, prev, "PREV", type);
+	if (cur_idx >= ring->elem_cnt) {
+		return NULL;
+	}
+	if (cur_idx == ring->read_idx) {
+		/* no more new record */
+		return NULL;
+	}
+
+	cur_idx = (cur_idx + ring->elem_cnt - 1) % ring->elem_cnt;
+	return (uint8 *)ring->elem + ring->elem_size * cur_idx;
+}
+
+static inline void
+__dhd_fixed_ring_lock(dhd_fixed_ring_info_t *ring, void *first_ptr, void *last_ptr, uint32 type)
+{
+	uint32 first_idx;
+	uint32 last_idx;
+	uint32 ring_filled_cnt;
+	uint32 tmp_cnt;
+
+	if (ring->read_idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("EMPTY RING\n"));
+		return;
+	}
+
+	if (first_ptr) {
+		first_idx = __dhd_ring_ptr2idx(ring, first_ptr, "LCK FIRST", type);
+		if (first_idx >= ring->elem_cnt) {
+			return;
+		}
+	} else {
+		first_idx = ring->read_idx;
+	}
+
+	if (last_ptr) {
+		last_idx = __dhd_ring_ptr2idx(ring, last_ptr, "LCK LAST", type);
+		if (last_idx >= ring->elem_cnt) {
+			return;
+		}
+	} else {
+		last_idx = ring->write_idx;
+	}
+
+	ring_filled_cnt = __dhd_fixed_ring_get_count(ring, ring->read_idx, ring->write_idx);
+	tmp_cnt = __dhd_fixed_ring_get_count(ring, ring->read_idx, first_idx);
+	if (tmp_cnt > ring_filled_cnt) {
+		DHD_RING_ERR(("LOCK FIRST IS TO EMPTY ELEM: write: %d read: %d cur:%d\n",
+			ring->write_idx, ring->read_idx, first_idx));
+		return;
+	}
+
+	tmp_cnt = __dhd_fixed_ring_get_count(ring, ring->read_idx, last_idx);
+	if (tmp_cnt > ring_filled_cnt) {
+		DHD_RING_ERR(("LOCK LAST IS TO EMPTY ELEM: write: %d read: %d cur:%d\n",
+			ring->write_idx, ring->read_idx, last_idx));
+		return;
+	}
+
+	ring->lock_idx = first_idx;
+	ring->lock_count = __dhd_fixed_ring_get_count(ring, first_idx, last_idx);
+	return;
+}
+
+static inline void
+__dhd_fixed_ring_lock_free(dhd_fixed_ring_info_t *ring)
+{
+	if (ring->read_idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("EMPTY RING\n"));
+		return;
+	}
+
+	ring->lock_idx = DHD_RING_IDX_INVALID;
+	ring->lock_count = 0;
+	return;
+}
+static inline void *
+__dhd_fixed_ring_lock_get_first(dhd_fixed_ring_info_t *ring)
+{
+	if (ring->read_idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("EMPTY RING\n"));
+		return NULL;
+	}
+	if (ring->lock_idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("NO LOCK POINT\n"));
+		return NULL;
+	}
+	return (uint8 *)ring->elem + ring->elem_size * ring->lock_idx;
+}
+
+static inline void *
+__dhd_fixed_ring_lock_get_last(dhd_fixed_ring_info_t *ring)
+{
+	int lock_last_idx;
+	if (ring->read_idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("EMPTY RING\n"));
+		return NULL;
+	}
+	if (ring->lock_idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("NO LOCK POINT\n"));
+		return NULL;
+	}
+
+	lock_last_idx = (ring->lock_idx + ring->lock_count - 1) % ring->elem_cnt;
+	return (uint8 *)ring->elem + ring->elem_size * lock_last_idx;
+}
+
+static inline int
+__dhd_fixed_ring_lock_get_count(dhd_fixed_ring_info_t *ring)
+{
+	if (ring->read_idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("EMPTY RING\n"));
+		return BCME_ERROR;
+	}
+	if (ring->lock_idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("NO LOCK POINT\n"));
+		return BCME_ERROR;
+	}
+	return ring->lock_count;
+}
+
+static inline void
+__dhd_fixed_ring_lock_free_first(dhd_fixed_ring_info_t *ring)
+{
+	if (ring->read_idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("EMPTY RING\n"));
+		return;
+	}
+	if (ring->lock_idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("NO LOCK POINT\n"));
+		return;
+	}
+
+	ring->lock_count--;
+	if (ring->lock_count <= 0) {
+		ring->lock_idx = DHD_RING_IDX_INVALID;
+	} else {
+		ring->lock_idx = (ring->lock_idx + 1) % ring->elem_cnt;
+	}
+	return;
+}
+
+static inline void
+__dhd_fixed_ring_set_read_idx(dhd_fixed_ring_info_t *ring, uint32 idx)
+{
+	ring->read_idx = idx;
+}
+
+static inline void
+__dhd_fixed_ring_set_write_idx(dhd_fixed_ring_info_t *ring, uint32 idx)
+{
+	ring->write_idx = idx;
+}
+
+static inline uint32
+__dhd_fixed_ring_get_read_idx(dhd_fixed_ring_info_t *ring)
+{
+	return ring->read_idx;
+}
+
+static inline uint32
+__dhd_fixed_ring_get_write_idx(dhd_fixed_ring_info_t *ring)
+{
+	return ring->write_idx;
+}
+
+/* Sub functions for single index ring */
+static inline void *
+__dhd_singleidx_ring_get_first(dhd_singleidx_ring_info_t *ring)
+{
+	uint32 tmp_idx = 0;
+
+	if (ring->idx == DHD_RING_IDX_INVALID) {
+		return NULL;
+	}
+
+	if (ring->ring_overwrited) {
+		tmp_idx = (ring->idx + 1) % ring->elem_cnt;
+	}
+
+	return (uint8 *)ring->elem + (ring->elem_size * tmp_idx);
+}
+
+static inline void *
+__dhd_singleidx_ring_get_last(dhd_singleidx_ring_info_t *ring)
+{
+	if (ring->idx == DHD_RING_IDX_INVALID) {
+		return NULL;
+	}
+
+	return (uint8 *)ring->elem + (ring->elem_size * ring->idx);
+}
+
+static inline void *
+__dhd_singleidx_ring_get_empty(dhd_singleidx_ring_info_t *ring)
+{
+	if (ring->idx == DHD_RING_IDX_INVALID) {
+		ring->idx = 0;
+		return (uint8 *)ring->elem;
+	}
+
+	/* check the lock is held */
+	if (atomic_read(&ring->ring_locked)) {
+		return NULL;
+	}
+
+	/* check the index rollover */
+	if (!ring->ring_overwrited && ring->idx == (ring->elem_cnt - 1)) {
+		ring->ring_overwrited = 1;
+	}
+
+	ring->idx = (ring->idx + 1) % ring->elem_cnt;
+
+	return (uint8 *)ring->elem + (ring->elem_size * ring->idx);
+}
+
+static inline void *
+__dhd_singleidx_ring_get_next(dhd_singleidx_ring_info_t *ring, void *prev, uint32 type)
+{
+	uint32 cur_idx;
+
+	if (ring->idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("EMPTY RING\n"));
+		return NULL;
+	}
+
+	cur_idx = __dhd_ring_ptr2idx(ring, prev, "NEXT", type);
+	if (cur_idx >= ring->elem_cnt) {
+		return NULL;
+	}
+
+	if (cur_idx == ring->idx) {
+		/* no more new record */
+		return NULL;
+	}
+
+	cur_idx = (cur_idx + 1) % ring->elem_cnt;
+
+	return (uint8 *)ring->elem + ring->elem_size * cur_idx;
+}
+
+static inline void *
+__dhd_singleidx_ring_get_prev(dhd_singleidx_ring_info_t *ring, void *prev, uint32 type)
+{
+	uint32 cur_idx;
+
+	if (ring->idx == DHD_RING_IDX_INVALID) {
+		DHD_RING_ERR(("EMPTY RING\n"));
+		return NULL;
+	}
+	cur_idx = __dhd_ring_ptr2idx(ring, prev, "PREV", type);
+	if (cur_idx >= ring->elem_cnt) {
+		return NULL;
+	}
+
+	if (!ring->ring_overwrited && cur_idx == 0) {
+		/* no more new record */
+		return NULL;
+	}
+
+	cur_idx = (cur_idx + ring->elem_cnt - 1) % ring->elem_cnt;
+	if (ring->ring_overwrited && cur_idx == ring->idx) {
+		/* no more new record */
+		return NULL;
+	}
+
+	return (uint8 *)ring->elem + ring->elem_size * cur_idx;
+}
+
+static inline void
+__dhd_singleidx_ring_whole_lock(dhd_singleidx_ring_info_t *ring)
+{
+	if (!atomic_read(&ring->ring_locked)) {
+		atomic_set(&ring->ring_locked, 1);
+	}
+}
+
+static inline void
+__dhd_singleidx_ring_whole_unlock(dhd_singleidx_ring_info_t *ring)
+{
+	if (atomic_read(&ring->ring_locked)) {
+		atomic_set(&ring->ring_locked, 0);
+	}
+}
+
+/* Get first element : oldest element */
+void *
+dhd_ring_get_first(void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	void *ret = NULL;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return NULL;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		ret = __dhd_fixed_ring_get_first(&ring->fixed);
+	}
+	if (ring->type == DHD_RING_TYPE_SINGLE_IDX) {
+		ret = __dhd_singleidx_ring_get_first(&ring->single);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+	return ret;
+}
+
+/* Free first element : oldest element */
+void
+dhd_ring_free_first(void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		__dhd_fixed_ring_free_first(&ring->fixed);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+}
+
+void
+dhd_ring_set_read_idx(void *_ring, uint32 read_idx)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		__dhd_fixed_ring_set_read_idx(&ring->fixed, read_idx);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+}
+
+void
+dhd_ring_set_write_idx(void *_ring, uint32 write_idx)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		__dhd_fixed_ring_set_write_idx(&ring->fixed, write_idx);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+}
+
+uint32
+dhd_ring_get_read_idx(void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	uint32 read_idx = DHD_RING_IDX_INVALID;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return read_idx;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		read_idx = __dhd_fixed_ring_get_read_idx(&ring->fixed);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+
+	return read_idx;
+}
+
+uint32
+dhd_ring_get_write_idx(void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	uint32 write_idx = DHD_RING_IDX_INVALID;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return write_idx;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		write_idx = __dhd_fixed_ring_get_write_idx(&ring->fixed);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+
+	return write_idx;
+}
+
+/* Get latest element */
+void *
+dhd_ring_get_last(void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	void *ret = NULL;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return NULL;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		ret = __dhd_fixed_ring_get_last(&ring->fixed);
+	}
+	if (ring->type == DHD_RING_TYPE_SINGLE_IDX) {
+		ret = __dhd_singleidx_ring_get_last(&ring->single);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+	return ret;
+}
+
+/* Get next point can be written
+ * will overwrite which doesn't read
+ * will return NULL if next pointer is locked.
+ */
+void *
+dhd_ring_get_empty(void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	void *ret = NULL;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return NULL;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		ret = __dhd_fixed_ring_get_empty(&ring->fixed);
+	}
+	if (ring->type == DHD_RING_TYPE_SINGLE_IDX) {
+		ret = __dhd_singleidx_ring_get_empty(&ring->single);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+	return ret;
+}
+
+void *
+dhd_ring_get_next(void *_ring, void *cur)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	void *ret = NULL;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return NULL;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		ret = __dhd_fixed_ring_get_next(&ring->fixed, cur, ring->type);
+	}
+	if (ring->type == DHD_RING_TYPE_SINGLE_IDX) {
+		ret = __dhd_singleidx_ring_get_next(&ring->single, cur, ring->type);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+	return ret;
+}
+
+void *
+dhd_ring_get_prev(void *_ring, void *cur)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	void *ret = NULL;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return NULL;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		ret = __dhd_fixed_ring_get_prev(&ring->fixed, cur, ring->type);
+	}
+	if (ring->type == DHD_RING_TYPE_SINGLE_IDX) {
+		ret = __dhd_singleidx_ring_get_prev(&ring->single, cur, ring->type);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+	return ret;
+}
+
+int
+dhd_ring_get_cur_size(void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	int cnt = 0;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return cnt;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		cnt = __dhd_fixed_ring_get_cur_size(&ring->fixed);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+	return cnt;
+}
+
+/* protect element between lock_ptr and write_idx */
+void
+dhd_ring_lock(void *_ring, void *first_ptr, void *last_ptr)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		__dhd_fixed_ring_lock(&ring->fixed, first_ptr, last_ptr, ring->type);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+}
+
+/* free all lock */
+void
+dhd_ring_lock_free(void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		__dhd_fixed_ring_lock_free(&ring->fixed);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+}
+
+void *
+dhd_ring_lock_get_first(void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	void *ret = NULL;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return NULL;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		ret = __dhd_fixed_ring_lock_get_first(&ring->fixed);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+	return ret;
+}
+
+void *
+dhd_ring_lock_get_last(void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	void *ret = NULL;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return NULL;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		ret = __dhd_fixed_ring_lock_get_last(&ring->fixed);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+	return ret;
+}
+
+int
+dhd_ring_lock_get_count(void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	int ret = BCME_ERROR;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return ret;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		ret = __dhd_fixed_ring_lock_get_count(&ring->fixed);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+	return ret;
+}
+
+/* free first locked element */
+void
+dhd_ring_lock_free_first(void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_FIXED) {
+		__dhd_fixed_ring_lock_free_first(&ring->fixed);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+}
+
+void
+dhd_ring_whole_lock(void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_SINGLE_IDX) {
+		__dhd_singleidx_ring_whole_lock(&ring->single);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+}
+
+void
+dhd_ring_whole_unlock(void *_ring)
+{
+	dhd_ring_info_t *ring = (dhd_ring_info_t *)_ring;
+	unsigned long flags;
+
+	if (!ring || ring->magic != DHD_RING_MAGIC) {
+		DHD_RING_ERR(("%s :INVALID RING INFO\n", __FUNCTION__));
+		return;
+	}
+
+	DHD_RING_SYNC_LOCK(ring->ring_sync, flags);
+	if (ring->type == DHD_RING_TYPE_SINGLE_IDX) {
+		__dhd_singleidx_ring_whole_unlock(&ring->single);
+	}
+	DHD_RING_SYNC_UNLOCK(ring->ring_sync, flags);
+}
+/* END of DHD RING */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0))
+#define DHD_VFS_INODE(dir) (dir->d_inode)
+#else
+#define DHD_VFS_INODE(dir) d_inode(dir)
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0) */
+
+#if ((defined DHD_DUMP_MNGR) || (defined DNGL_AXI_ERROR_LOGGING))
+int
+dhd_file_delete(char *path)
+{
+	struct path file_path = {.dentry = 0};
+	int err;
+	struct dentry *dir;
+
+	err = dhd_kern_path(path, 0, &file_path);
+
+	if (err < 0) {
+		DHD_ERROR(("Failed to get kern-path delete file: %s error: %d\n", path, err));
+		return err;
+	}
+	if (
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
+		!d_is_file(file_path.dentry) ||
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(4, 1, 0))
+		d_really_is_negative(file_path.dentry) ||
+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(4, 1, 0) */
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0) */
+		FALSE)
+	{
+		err = -EINVAL;
+	} else {
+		dir = dget_parent(file_path.dentry);
+
+		if (!IS_ERR(dir)) {
+			err = DHD_VFS_UNLINK(dir, file_path, NULL);
+			dput(dir);
+		} else {
+			err = PTR_ERR(dir);
+		}
+	}
+
+	path_put(&file_path);
+
+	if (err < 0) {
+		DHD_ERROR(("Failed to delete file: %s error: %d\n", path, err));
+	}
+
+	return err;
+}
+#endif
+
+#ifdef DHD_DUMP_MNGR
+static int
+dhd_dump_file_manage_idx(dhd_dump_file_manage_t *fm_ptr, char *fname)
+{
+	int i;
+	int fm_idx = -1;
+
+	for (i = 0; i < DHD_DUMP_TYPE_COUNT_MAX; i++) {
+		/* XXX dump file manager enqueues the type name to empty slot,
+		 * so it's impossible that empty slot is in the middle.
+		 */
+		if (strlen(fm_ptr->elems[i].type_name) == 0) {
+			fm_idx = i;
+			break;
+		}
+		if (!(strncmp(fname, fm_ptr->elems[i].type_name, strlen(fname)))) {
+			fm_idx = i;
+			break;
+		}
+	}
+
+	if (fm_idx == -1) {
+		return fm_idx;
+	}
+
+	if (strlen(fm_ptr->elems[fm_idx].type_name) == 0) {
+		strncpy(fm_ptr->elems[fm_idx].type_name, fname, DHD_DUMP_TYPE_NAME_SIZE);
+		fm_ptr->elems[fm_idx].type_name[DHD_DUMP_TYPE_NAME_SIZE - 1] = '\0';
+		fm_ptr->elems[fm_idx].file_idx = 0;
+	}
+
+	return fm_idx;
+}
+
+/*
+ * dhd_dump_file_manage_enqueue - enqueue dump file path
+ * and delete odest file if file count is max.
+ */
+void
+dhd_dump_file_manage_enqueue(dhd_pub_t *dhd, char *dump_path, char *fname)
+{
+	int fm_idx;
+	int fp_idx;
+	dhd_dump_file_manage_t *fm_ptr;
+	DFM_elem_t *elem;
+
+	if (!dhd || !dhd->dump_file_manage) {
+		DHD_ERROR(("%s(): dhdp=%p dump_file_manage=%p\n",
+			__FUNCTION__, dhd, (dhd ? dhd->dump_file_manage : NULL)));
+		return;
+	}
+
+	fm_ptr = dhd->dump_file_manage;
+
+	/* find file_manage idx */
+	DHD_INFO(("%s(): fname: %s dump_path: %s\n", __FUNCTION__, fname, dump_path));
+	if ((fm_idx = dhd_dump_file_manage_idx(fm_ptr, fname)) < 0) {
+		DHD_ERROR(("%s(): Out of file manager entries, fname: %s\n",
+			__FUNCTION__, fname));
+		return;
+	}
+
+	elem = &fm_ptr->elems[fm_idx];
+	fp_idx = elem->file_idx;
+	DHD_INFO(("%s(): fm_idx: %d fp_idx: %d path: %s\n",
+		__FUNCTION__, fm_idx, fp_idx, elem->file_path[fp_idx]));
+
+	/* delete oldest file */
+	if (strlen(elem->file_path[fp_idx]) != 0) {
+		if (dhd_file_delete(elem->file_path[fp_idx]) < 0) {
+			DHD_ERROR(("%s(): Failed to delete file: %s\n",
+				__FUNCTION__, elem->file_path[fp_idx]));
+		} else {
+			DHD_ERROR(("%s(): Successed to delete file: %s\n",
+				__FUNCTION__, elem->file_path[fp_idx]));
+		}
+	}
+
+	/* save dump file path */
+	strncpy(elem->file_path[fp_idx], dump_path, DHD_DUMP_FILE_PATH_SIZE);
+	elem->file_path[fp_idx][DHD_DUMP_FILE_PATH_SIZE - 1] = '\0';
+
+	/* change file index to next file index */
+	elem->file_idx = (elem->file_idx + 1) % DHD_DUMP_FILE_COUNT_MAX;
+}
+#endif /* DHD_DUMP_MNGR */
+
+#ifdef DNGL_AXI_ERROR_LOGGING
+static void
+dhd_axi_error_dump(void *handle, void *event_info, u8 event)
+{
+	dhd_info_t *dhd = (dhd_info_t *)handle;
+	dhd_pub_t *dhdp = NULL;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		goto exit;
+	}
+
+	dhdp = &dhd->pub;
+	if (!dhdp) {
+		DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__));
+		goto exit;
+	}
+
+	/**
+	 * First save axi error information to a file
+	 * because panic should happen right after this.
+	 * After dhd reset, dhd reads the file, and do hang event process
+	 * to send axi error stored on the file to Bigdata server
+	 */
+	if (dhdp->axi_err_dump->etd_axi_error_v1.version != HND_EXT_TRAP_AXIERROR_VERSION_1) {
+		DHD_ERROR(("%s: Invalid AXI version: 0x%x\n",
+			__FUNCTION__, dhdp->axi_err_dump->etd_axi_error_v1.version));
+	}
+
+	DHD_OS_WAKE_LOCK(dhdp);
+#ifdef DHD_FW_COREDUMP
+#ifdef DHD_SSSR_DUMP
+	DHD_ERROR(("%s : Set collect_sssr as TRUE\n", __FUNCTION__));
+	dhdp->collect_sssr = TRUE;
+#endif /* DHD_SSSR_DUMP */
+	DHD_ERROR(("%s: scheduling mem dump.. \n", __FUNCTION__));
+	dhd_schedule_memdump(dhdp, dhdp->soc_ram, dhdp->soc_ram_length);
+#endif /* DHD_FW_COREDUMP */
+	DHD_OS_WAKE_UNLOCK(dhdp);
+
+exit:
+	/* Trigger kernel panic after taking necessary dumps */
+	BUG_ON(1);
+}
+
+void dhd_schedule_axi_error_dump(dhd_pub_t *dhdp, void *type)
+{
+	DHD_ERROR(("%s: scheduling axi_error_dump.. \n", __FUNCTION__));
+	dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq,
+		type, DHD_WQ_WORK_AXI_ERROR_DUMP,
+		dhd_axi_error_dump, DHD_WQ_WORK_PRIORITY_HIGH);
+}
+#endif /* DNGL_AXI_ERROR_LOGGING */
+
+#ifdef SUPPORT_SET_TID
+/*
+ * Set custom TID value for UDP frame based on UID value.
+ * This will be triggered by android private command below.
+ * DRIVER SET_TID <Mode:uint8> <Target UID:uint32> <Custom TID:uint8>
+ * Mode 0(SET_TID_OFF) : Disable changing TID
+ * Mode 1(SET_TID_ALL_UDP) : Change TID for all UDP frames
+ * Mode 2(SET_TID_BASED_ON_UID) : Change TID for UDP frames based on target UID
+*/
+void
+dhd_set_tid_based_on_uid(dhd_pub_t *dhdp, void *pkt)
+{
+	struct ether_header *eh = NULL;
+	struct sock *sk = NULL;
+	uint8 *pktdata = NULL;
+	uint8 *ip_hdr = NULL;
+	uint8 cur_prio;
+	uint8 prio;
+	uint32 uid;
+
+	if (dhdp->tid_mode == SET_TID_OFF) {
+		return;
+	}
+
+	pktdata = (uint8 *)PKTDATA(dhdp->osh, pkt);
+	eh = (struct ether_header *) pktdata;
+	ip_hdr = (uint8 *)eh + ETHER_HDR_LEN;
+
+	if (IPV4_PROT(ip_hdr) != IP_PROT_UDP) {
+		return;
+	}
+
+	cur_prio = PKTPRIO(pkt);
+	prio = dhdp->target_tid;
+	uid = dhdp->target_uid;
+
+	if ((cur_prio == prio) ||
+		(cur_prio != PRIO_8021D_BE)) {
+			return;
+	}
+
+	sk = ((struct sk_buff*)(pkt))->sk;
+
+	if ((dhdp->tid_mode == SET_TID_ALL_UDP) ||
+		(sk && (uid == __kuid_val(sock_i_uid(sk))))) {
+		PKTSETPRIO(pkt, prio);
+	}
+}
+#endif /* SUPPORT_SET_TID */
+
+#ifdef BCMPCIE
+static void
+dhd_cto_recovery_handler(void *handle, void *event_info, u8 event)
+{
+	dhd_info_t *dhd = handle;
+	dhd_pub_t *dhdp = NULL;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		BUG_ON(1);
+		return;
+	}
+
+	dhdp = &dhd->pub;
+	if (dhdp->dhd_induce_error == DHD_INDUCE_BH_CBP_HANG) {
+		DHD_ERROR(("%s: skip cto recovery for DHD_INDUCE_BH_CBP_HANG\n",
+			__FUNCTION__));
+		return;
+	}
+	dhdpcie_cto_recovery_handler(dhdp);
+}
+
+void
+dhd_schedule_cto_recovery(dhd_pub_t *dhdp)
+{
+	if (dhdp->up == FALSE) {
+		DHD_ERROR(("%s : skip scheduling cto because dhd is not up\n",
+				__FUNCTION__));
+		return;
+	}
+
+	if (dhdp->info->scheduled_memdump) {
+		DHD_ERROR(("%s, memdump in progress\n", __FUNCTION__));
+		return;
+	}
+
+	DHD_ERROR(("%s: scheduling cto recovery.. \n", __FUNCTION__));
+	dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq,
+		NULL, DHD_WQ_WORK_CTO_RECOVERY,
+		dhd_cto_recovery_handler, DHD_WQ_WORK_PRIORITY_HIGH);
+}
+#endif /* BCMPCIE */
+
+#ifdef DHD_WIFI_SHUTDOWN
+void wifi_plat_dev_drv_shutdown(struct platform_device *pdev)
+{
+	dhd_pub_t *dhd_pub = NULL;
+	dhd_info_t *dhd_info = NULL;
+	dhd_if_t *dhd_if = NULL;
+
+	DHD_ERROR(("%s enter\n", __FUNCTION__));
+	dhd_pub = g_dhd_pub;
+
+	if (dhd_os_check_if_up(dhd_pub)) {
+		dhd_info = (dhd_info_t *)dhd_pub->info;
+		dhd_if = dhd_info->iflist[0];
+		ASSERT(dhd_if);
+		ASSERT(dhd_if->net);
+		if (dhd_if && dhd_if->net) {
+			dhd_stop(dhd_if->net);
+		}
+	}
+}
+#endif /* DHD_WIFI_SHUTDOWN */
+
+#ifdef DHD_CFG80211_SUSPEND_RESUME
+void
+dhd_cfg80211_suspend(dhd_pub_t *dhdp)
+{
+	struct net_device *net = dhd_idx2net((dhd_pub_t *)dhdp, 0);
+	struct bcm_cfg80211 *cfg = wl_get_cfg(net);
+	wl_cfg80211_suspend(cfg);
+}
+
+void
+dhd_cfg80211_resume(dhd_pub_t *dhdp)
+{
+	struct net_device * net = dhd_idx2net((dhd_pub_t *)dhdp, 0);
+	struct bcm_cfg80211 *cfg = wl_get_cfg(net);
+	wl_cfg80211_resume(cfg);
+}
+#endif /* DHD_CFG80211_SUSPEND_RESUME */
+
+void
+dhd_generate_rand_mac_addr(struct ether_addr *ea_addr)
+{
+	RANDOM_BYTES(ea_addr->octet, ETHER_ADDR_LEN);
+	/* restore mcast and local admin bits to 0 and 1 */
+	ETHER_SET_UNICAST(ea_addr->octet);
+	ETHER_SET_LOCALADDR(ea_addr->octet);
+	DHD_ERROR(("%s:generated new MAC="MACDBG" \n",
+		__FUNCTION__, MAC2STRDBG(ea_addr->octet)));
+	return;
+}
+
+void *
+dhd_get_roam_evt(dhd_pub_t *dhdp)
+{
+#if defined(DHD_PUB_ROAM_EVT)
+	return (void *)&(dhdp->roam_evt);
+#else
+	return NULL;
+#endif /* DHD_PUB_ROAM_EVT */
+}
+
+/* BANDLOCK_FILE is for Hikey only and BANDLOCK has a priority than BANDLOCK_FILE */
+static void dhd_set_bandlock(dhd_pub_t * dhd)
+{
+#if defined(BANDLOCK)
+	int band = BANDLOCK;
+	if (dhd_wl_ioctl_cmd(dhd, WLC_SET_BAND, &band, sizeof(band), TRUE, 0) < 0) {
+		DHD_ERROR(("%s: set band(%d) error\n", __FUNCTION__, band));
+	}
+#elif defined(BANDLOCK_FILE)
+	int band;
+	char val[2] = {0, 0};
+	if (dhd_read_file(PATH_BANDLOCK_INFO, (char *)val, sizeof(char)) == BCME_OK) {
+		band = bcm_atoi(val);
+		if (dhd_wl_ioctl_cmd(dhd, WLC_SET_BAND, &band, sizeof(band), TRUE, 0) < 0) {
+			DHD_ERROR(("%s: set band(%d) error\n", __FUNCTION__, band));
+		}
+	}
+#endif /* BANDLOCK */
+}
+
+void
+dhd_set_del_in_progress(dhd_pub_t *dhdp, struct net_device *ndev)
+{
+	dhd_if_t *ifp = NULL;
+	unsigned long flags;
+
+	DHD_ERROR(("%s\n", __FUNCTION__));
+	ifp = dhd_get_ifp_by_ndev(dhdp, ndev);
+	if (ifp == NULL) {
+		DHD_ERROR(("DHD Iface Info corresponding to %s not found\n", ndev->name));
+		return;
+	}
+
+	DHD_GENERAL_LOCK(dhdp, flags);
+	ifp->del_in_progress = TRUE;
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+}
+
+void
+dhd_clear_del_in_progress(dhd_pub_t *dhdp, struct net_device *ndev)
+{
+	dhd_if_t *ifp = NULL;
+	unsigned long flags;
+
+	DHD_ERROR(("%s\n", __FUNCTION__));
+	ifp = dhd_get_ifp_by_ndev(dhdp, ndev);
+	if (ifp == NULL) {
+		DHD_ERROR(("DHD Iface Info corresponding to %s not found\n", ndev->name));
+		return;
+	}
+
+	DHD_GENERAL_LOCK(dhdp, flags);
+	ifp->del_in_progress = FALSE;
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+}
+
+#ifdef PCIE_FULL_DONGLE
+/* API to delete flowings and Stations
+* corresponding to the interface(ndev)
+*/
+void
+dhd_net_del_flowrings_sta(dhd_pub_t *dhd, struct net_device *ndev)
+{
+	dhd_if_t *ifp = NULL;
+
+	ifp = dhd_get_ifp_by_ndev(dhd, ndev);
+	if (ifp == NULL) {
+		DHD_ERROR(("DHD Iface Info corresponding to %s not found\n", ndev->name));
+		return;
+	}
+
+	/* For now called only in iface delete path..
+	* Add reason codes if this API need to be reused in any other paths.
+	*/
+	DHD_ERROR(("%s:Clean up IFACE idx %d due to interface delete\n",
+		__FUNCTION__, ifp->idx));
+
+	dhd_del_all_sta(dhd, ifp->idx);
+	/* Try to resume if already suspended or suspend in progress */
+	dhd_flow_rings_delete(dhd, ifp->idx);
+}
+#if defined(WBRC) && defined(WBRC_BT2WL_RESET)
+void
+dhd_wbrc_wl_trap(void)
+{
+	dhd_pub_t *dhdp = g_dhd_pub;
+
+	dhdpcie_db7_trap(dhdp->bus);
+	/* set that dongle trap has occured to stop other contests from firing IOVARS */
+	dhdp->dongle_trap_occured = TRUE;
+#ifdef OEM_ANDROID
+	/* Set chip big hammer */
+	dhdp->do_chip_bighammer = TRUE;
+	dhdp->hang_reason = HANG_REASON_BT2WL_REG_RESET;
+	dhd_os_send_hang_message(dhdp);
+#endif /* OEM_ANDROID */
+}
+#endif /* WBRC && WBRC_BT2WL_RESET */
+#endif /* PCIE_FULL_DONGLE */
+
+#ifndef BCMDBUS
+static void
+dhd_deferred_socram_dump(void *handle, void *event_info, u8 event)
+{
+#ifndef BCMDBUS
+	dhd_pub_t *dhdp = (dhd_pub_t *)event_info;
+	DHD_ERROR(("%s ... scheduled to collect memdump over bus\n", __FUNCTION__));
+	dhd_socram_dump(dhdp->bus);
+#else
+	DHD_ERROR(("%s Not collecting socram dump for BCMDBUS\n", __FUNCTION__));
+	return;
+#endif /* BCMDBUS */
+}
+
+int
+dhd_schedule_socram_dump(dhd_pub_t *dhdp)
+{
+	int ret = 0;
+	ret = dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq, (void *)dhdp,
+		DHD_WQ_WORK_SOC_RAM_COLLECT, dhd_deferred_socram_dump, DHD_WQ_WORK_PRIORITY_HIGH);
+	return ret;
+}
+#endif
+
+#ifdef WL_CFGVENDOR_SEND_ALERT_EVENT
+void dhd_alert_process(struct work_struct *work_data)
+{
+	struct net_device *dev;
+	dhd_info_t *dhd_info = NULL;
+	dhd_pub_t *dhdp = NULL;
+
+	/* Ignore compiler warnings due to -Werror=cast-qual */
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd_info = container_of(work_data, dhd_info_t, dhd_alert_process_work);
+	GCC_DIAGNOSTIC_POP();
+	dhdp = &dhd_info->pub;
+
+	if (!dhdp) {
+		DHD_ERROR(("dhd is NULL\n"));
+		return;
+	}
+	dev = dhd_linux_get_primary_netdev(dhdp);
+
+	if (dev) {
+		wl_cfg80211_alert(dev);
+	}
+}
+
+int dhd_os_send_alert_message(dhd_pub_t *dhdp)
+{
+	int ret = 0;
+	dhd_info_t *dhd_info = NULL;
+#ifdef WL_CFG80211
+	struct net_device *primary_ndev;
+	struct bcm_cfg80211 *cfg;
+#endif /* WL_CFG80211 */
+
+	if (!dhdp) {
+		DHD_ERROR(("dhdp is null\n"));
+		return -EINVAL;
+	}
+
+	dhd_info = (dhd_info_t *)dhdp->info;
+	BCM_REFERENCE(dhd_info);
+
+#ifdef WL_CFG80211
+	primary_ndev = dhd_linux_get_primary_netdev(dhdp);
+	if (!primary_ndev) {
+		DHD_ERROR(("Cannot find primary netdev\n"));
+		return -ENODEV;
+	}
+	cfg = wl_get_cfg(primary_ndev);
+	if (!cfg) {
+		DHD_ERROR(("Cannot find cfg\n"));
+		return -EINVAL;
+	}
+
+	/* Skip sending ALERT event to framework if driver is not ready */
+	if (!wl_get_drv_status(cfg, READY, primary_ndev)) {
+		DHD_ERROR(("device is not ready\n"));
+		return -ENODEV;
+	}
+
+	schedule_work(&dhdp->info->dhd_alert_process_work);
+#endif /* WL_CFG80211 */
+
+	return ret;
+}
+#endif /* WL_CFGVENDOR_SEND_ALERT_EVENT */
+int
+dhd_dev_set_accel_force_reg_on(struct net_device *dev)
+{
+#if defined(WLAN_ACCEL_BOOT)
+	dhd_info_t *dhd_info = *(dhd_info_t **)netdev_priv(dev);
+
+	if (dhd_info && !dhd_info->wl_accel_force_reg_on) {
+		DHD_ERROR(("%s: set force reg on\n", __FUNCTION__));
+		dhd_info->wl_accel_force_reg_on = TRUE;
+	}
+#endif /* WLAN_ACCEL_BOOT */
+
+	return BCME_OK;
+}
+#ifdef TPUT_DEBUG_DUMP
+bool dhd_get_napi_sched_cnt(dhd_pub_t * dhdp,
+	uint32 **napi_cnts, uint32 **txp_cnts, uint32 **tx_start_cnts)
+{
+	struct dhd_info  *dhd = NULL;
+	if (!dhdp) {
+		WL_ERR(("Invaslid dhd_pub\n"));
+		return FALSE;
+	}
+
+	dhd = dhdp->info;
+
+	if (!dhd) {
+		WL_ERR(("Invaslid dhd_info\n"));
+		return FALSE;
+	}
+
+	*napi_cnts =  dhd->napi_percpu_run_cnt;
+	*txp_cnts = dhd->txp_percpu_run_cnt;
+	*tx_start_cnts = dhd->tx_start_percpu_run_cnt;
+
+	return TRUE;
+}
+#endif /* TPUT_DEBUG_DUMP */
+
+#if defined(DHD_ENABLE_S2MPU)
+/*
+ * return
+ * S2MPUFD_NOTIFY_BAD : watchdog reset
+ * S2MPUFD_NOTIFY_OK  : No watchdog reset
+ */
+int s2mpufd_notifier_callback(struct s2mpufd_notifier_block *block,
+		struct s2mpufd_notifier_info *info)
+{
+	int ret = S2MPUFD_NOTIFY_OK;
+
+	DHD_ERROR(("%s: fault_addr:0x%lx, rw:%d, len:%d, type:%d \n",
+			__FUNCTION__, info->fault_addr, info->fault_rw,
+			info->fault_len, info->fault_type));
+	dhd_smmu_fault_handler(0, info->fault_addr);
+
+	DHD_ERROR(("%s: return : %d\n", __FUNCTION__, ret));
+
+	return ret;
+}
+
+static void dhd_module_s2mpu_register(struct device *dev)
+{
+	struct s2mpufd_notifier_block *s2mpu_nb = NULL;
+
+	DHD_ERROR(("%s: Enter\n", __FUNCTION__));
+
+	s2mpu_nb = devm_kzalloc(dev, sizeof(struct s2mpufd_notifier_block), GFP_KERNEL);
+	if (!s2mpu_nb) {
+		DHD_ERROR(("%s: devm_kzalloc fail\n", __FUNCTION__));
+		return;
+	}
+
+	s2mpu_nb->subsystem = "PCIE_GEN2";
+	s2mpu_nb->notifier_call = s2mpufd_notifier_callback;
+	s2mpufd_notifier_call_register(s2mpu_nb);
+}
+#endif /* DHD_ENABLE_S2MPU */
+
+#ifdef DHD_REGISTER_SMMU_FAULT_HANDLER
+#define SYSMMU_NOTIFY_SKIP_PANIC 3
+static int sysmmu_notifier_callback(struct notifier_block *nb, unsigned long addr,
+		void *flag)
+{
+	int fault_info = *(int *)flag;
+	DHD_ERROR(("%s: Fault ADDR 0x%lx - %s\n", __FUNCTION__, addr,
+			(fault_info & 0x1) ? "WRITE" : "READ"));
+	dhd_smmu_fault_handler(0, addr);
+	return SYSMMU_NOTIFY_SKIP_PANIC;
+}
+#endif /* DHD_REGISTER_SMMU_FAULT_HANDLER */
+
+#if defined(DHD_FILE_DUMP_EVENT) && defined(DHD_FW_COREDUMP)
+dhd_dongledump_status_t dhd_get_dump_status(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	return OSL_ATOMIC_READ(pub->osh, &dhd->dump_status);
+}
+
+void dhd_set_dump_status(dhd_pub_t *pub, dhd_dongledump_status_t dump_status)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	OSL_ATOMIC_SET(pub->osh, &dhd->dump_status, dump_status);
+}
+
+static void dhd_dump_proc(struct work_struct *work_data)
+{
+	dhd_info_t *dhd_info = NULL;
+	dhd_pub_t *dhdp = NULL;
+	unsigned long flags = 0;
+
+	/* Ignore compiler warnings due to -Werror=cast-qual */
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd_info = container_of(work_data, dhd_info_t, dhd_dump_proc_work);
+	GCC_DIAGNOSTIC_POP();
+
+	if (!dhd_info || ((dhdp = &dhd_info->pub) == NULL)) {
+		DHD_ERROR(("dhd is NULL\n"));
+		return;
+	}
+
+	DHD_GENERAL_LOCK(dhdp, flags);
+	DHD_BUS_BUSY_SET_IN_SYSFS_DUMP(dhdp);
+#ifdef DHD_LOG_DUMP
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+	dhd_log_dump_trigger(dhdp, CMD_DEFAULT);
+	DHD_GENERAL_LOCK(dhdp, flags);
+#endif /* DHD_LOG_DUMP */
+	DHD_BUS_BUSY_CLEAR_IN_SYSFS_DUMP(dhdp);
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+}
+#endif /* DHD_FILE_DUMP_EVENT && DHD_FW_COREDUMP */
+
+void *dhd_get_pub(struct net_device *dev)
+{
+	dhd_info_t *dhdinfo = *(dhd_info_t **)netdev_priv(dev);
+	if (dhdinfo)
+		return (void *)&dhdinfo->pub;
+	else {
+		printf("%s: null dhdinfo\n", __FUNCTION__);
+		return NULL;
+	}
+}
+
+void *dhd_get_conf(struct net_device *dev)
+{
+	dhd_info_t *dhdinfo = *(dhd_info_t **)netdev_priv(dev);
+	if (dhdinfo)
+		return (void *)dhdinfo->pub.conf;
+	else {
+		printf("%s: null dhdinfo\n", __FUNCTION__);
+		return NULL;
+	}
+}
+
+bool dhd_os_wd_timer_enabled(void *bus)
+{
+	dhd_pub_t *pub = bus;
+	dhd_info_t *dhd = (dhd_info_t *)pub->info;
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd NULL\n", __FUNCTION__));
+		return FALSE;
+	}
+	return dhd->wd_timer_valid;
+}
+
+#if defined(WLDWDS) && defined(FOURADDR_AUTO_BRG)
+/* This function is to automatically add/del interface to the bridged dev that priamy dev is in */
+static void
+dhd_bridge_dev_set(dhd_info_t *dhd, int ifidx, struct net_device *dev)
+{
+	struct net_device *pdev = NULL, *br_dev = NULL;
+	int i, err = 0;
+
+	if (dev) {
+		/* search the primary interface wlan1(wl0.1) with same bssidx */
+		for (i = 0; i < ifidx; i++) {
+			if (dhd->iflist[i]->bssidx == dhd->iflist[ifidx]->bssidx) {
+				pdev = dhd->pub.info->iflist[i]->net;
+				WL_MSG(dev->name, "found primary dev %s\n", pdev->name);
+				break;
+			}
+		}
+		if (!pdev) {
+			WL_MSG(dev->name, "can not find primary dev\n");
+			return;
+		}
+	} else {
+		pdev = dhd->iflist[ifidx]->net;
+	}
+
+	/* if primary net device is bridged */
+	if (pdev->priv_flags & IFF_BRIDGE_PORT) {
+		rtnl_lock();
+		/* get bridge device */
+		br_dev = netdev_master_upper_dev_get(pdev);
+		if (br_dev) {
+			const struct net_device_ops *ops = br_dev->netdev_ops;
+			if (ops) {
+				if (dev) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
+					err = ops->ndo_add_slave(br_dev, dev, NULL);
+#else
+					err = ops->ndo_add_slave(br_dev, dev);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0) */
+					if (err)
+						WL_MSG(dev->name, "add to %s failed %d\n", br_dev->name, err);
+					else
+						WL_MSG(dev->name, "slave added to %s\n", br_dev->name);
+					/* Also bring wds0.x interface up automatically */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0))
+					dev_change_flags(dev, dev->flags | IFF_UP, NULL);
+#else
+					dev_change_flags(dev, dev->flags | IFF_UP);
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0) */
+				} else {
+					err = ops->ndo_del_slave(br_dev, pdev);
+					if (err)
+						WL_MSG(pdev->name, "del from %s failed %d\n", br_dev->name, err);
+					else
+						WL_MSG(pdev->name, "slave deleted from %s\n", br_dev->name);
+				}
+			}
+		}
+		else {
+			WL_MSG(pdev->name, "not bridged\n");
+		}
+		rtnl_unlock();
+	}
+	else {
+		WL_MSG(pdev->name, "not bridged\n");
+	}
+}
+#endif /* WLDWDS && FOURADDR_AUTO_BRG */
+
+#ifdef DHD_DEBUG_WAKE_LOCK
+int
+dhd_wakelock_counter_get(dhd_pub_t *pub)
+{
+	return ((dhd_info_t *)pub)->wakelock_counter;
+}
+
+int
+dhd_wakelock_wd_counter_get(dhd_pub_t *pub)
+{
+	return ((dhd_info_t *)pub)->wakelock_wd_counter;
+}
+#endif /* DHD_DEBUG_WAKE_LOCK */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux.h
@@ -0,0 +1,658 @@
+/*
+ * DHD Linux header file (dhd_linux exports for cfg80211 and other components)
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+/* wifi platform functions for power, interrupt and pre-alloc, either
+ * from Android-like platform device data, or Broadcom wifi platform
+ * device data.
+ *
+ */
+#ifndef __DHD_LINUX_H__
+#define __DHD_LINUX_H__
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <dngl_stats.h>
+#ifdef DHD_LOG_DUMP
+#include <dhd_log_dump.h>
+#endif
+#include <dhd.h>
+#ifdef DHD_WMF
+#include <dhd_wmf_linux.h>
+#endif
+/* Linux wireless extension support */
+#if defined(WL_WIRELESS_EXT)
+#include <wl_iw.h>
+#endif /* defined(WL_WIRELESS_EXT) */
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
+#include <linux/earlysuspend.h>
+#endif /* defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND) */
+
+#ifdef BCMPCIE
+#include <bcmmsgbuf.h>
+#endif /* BCMPCIE */
+
+#ifdef PCIE_FULL_DONGLE
+#include <etd.h>
+#endif /* PCIE_FULL_DONGLE */
+
+#ifdef CONFIG_IRQ_HISTORY
+#include <linux/power/irq_history.h>
+#endif /* CONFIG_IRQ_HISTORY */
+
+#if defined(OEM_ANDROID)
+#include <linux/nl80211.h>
+#endif /* OEM_ANDROID */
+
+#ifdef WL_MONITOR
+#ifdef HOST_RADIOTAP_CONV
+#include <bcmwifi_monitor.h>
+#else
+#define MAX_RADIOTAP_SIZE      256 /* Maximum size to hold HE Radiotap header format */
+#define MAX_MON_PKT_SIZE       (4096 + MAX_RADIOTAP_SIZE)
+#endif /* HOST_RADIOTAP_CONV */
+#endif /* WL_MONITOR */
+
+/* dongle status */
+enum wifi_adapter_status {
+	WIFI_STATUS_POWER_ON = 0,
+	WIFI_STATUS_FW_READY,
+	WIFI_STATUS_NET_ATTACHED,
+	WIFI_STATUS_BUS_DISCONNECTED
+};
+#define wifi_chk_adapter_status(adapter, stat) (test_bit(stat, &(adapter)->status))
+#define wifi_get_adapter_status(adapter, stat) (test_bit(stat, &(adapter)->status))
+#define wifi_set_adapter_status(adapter, stat) (set_bit(stat, &(adapter)->status))
+#define wifi_clr_adapter_status(adapter, stat) (clear_bit(stat, &(adapter)->status))
+#define wifi_chg_adapter_status(adapter, stat) (change_bit(stat, &(adapter)->status))
+
+#ifdef DHD_COREDUMP
+#define PC_FOUND_BIT 0x01
+#define LR_FOUND_BIT 0x02
+#define ALL_ADDR_VAL (PC_FOUND_BIT | LR_FOUND_BIT)
+#define READ_NUM_BYTES 1000
+#define DHD_FUNC_STR_LEN 80
+
+#define DHD_COREDUMP_MAGIC 0xDDCEDACF
+#define TLV_TYPE_LENGTH_SIZE	(8u)
+/* coredump is composed as following TLV format.
+ * Type(32bit) | Length(32bit) | Value(x bit)
+ * e.g) socram type | length | socram dump
+ *      sssr core1 type | length | sssr core1 dump
+ *      ...
+ */
+enum coredump_types {
+	DHD_COREDUMP_TYPE_SSSRDUMP_CORE0_BEFORE = 0,
+	DHD_COREDUMP_TYPE_SSSRDUMP_CORE0_AFTER,
+	DHD_COREDUMP_TYPE_SSSRDUMP_CORE1_BEFORE,
+	DHD_COREDUMP_TYPE_SSSRDUMP_CORE1_AFTER,
+	DHD_COREDUMP_TYPE_SSSRDUMP_CORE2_BEFORE,
+	DHD_COREDUMP_TYPE_SSSRDUMP_CORE2_AFTER,
+	DHD_COREDUMP_TYPE_SSSRDUMP_DIG_BEFORE,
+	DHD_COREDUMP_TYPE_SSSRDUMP_DIG_AFTER,
+	DHD_COREDUMP_TYPE_SOCRAMDUMP
+};
+
+#ifdef DHD_SSSR_DUMP
+typedef struct dhd_coredump {
+	uint32 type;
+	uint32 length;
+	void *bufptr;
+} dhd_coredump_t;
+#endif /* DHD_SSSR_DUMP */
+#endif /* DHD_COREDUMP */
+
+#ifdef BCMDBUS
+#define DBUS_NRXQ	50
+#define DBUS_NTXQ	100
+#endif /* BCMDBUS */
+
+#ifdef DHD_WAKE_RX_STATUS
+#define ETHER_ICMP6_HEADER	20
+#define ETHER_IPV6_SADDR (ETHER_ICMP6_HEADER + 2)
+#define ETHER_IPV6_DAADR (ETHER_IPV6_SADDR + IPV6_ADDR_LEN)
+#define ETHER_ICMPV6_TYPE (ETHER_IPV6_DAADR + IPV6_ADDR_LEN)
+#endif /* DHD_WAKE_RX_STATUS */
+
+#ifdef SUPPORT_AP_POWERSAVE
+#define RXCHAIN_PWRSAVE_PPS			10
+#define RXCHAIN_PWRSAVE_QUIET_TIME		10
+#define RXCHAIN_PWRSAVE_STAS_ASSOC_CHECK	0
+#endif /* SUPPORT_AP_POWERSAVE */
+
+#define DHD_REGISTRATION_TIMEOUT  12000  /* msec : allowed time to finished dhd registration */
+#define DHD_FW_READY_TIMEOUT  5000  /* msec : allowed time to finished fw download */
+
+/* FW initialised value for ocl_rssi_threshold */
+#define FW_OCL_RSSI_THRESH_INITVAL -75
+
+#if defined(DHD_TRACE_WAKE_LOCK)
+typedef enum dhd_wklock_type {
+	DHD_WAKE_LOCK,
+	DHD_WAKE_UNLOCK,
+	DHD_WAIVE_LOCK,
+	DHD_RESTORE_LOCK
+} dhd_wklock_t;
+
+struct wk_trace_record {
+	unsigned long addr;	            /* Address of the instruction */
+	dhd_wklock_t lock_type;         /* lock_type */
+	unsigned long long counter;		/* counter information */
+	struct hlist_node wklock_node;  /* hash node */
+};
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
+#define HASH_ADD(hashtable, node, key) \
+	do { \
+		hash_add(hashtable, node, key); \
+	} while (0);
+#else
+#define HASH_ADD(hashtable, node, key) \
+	do { \
+		int index = hash_long(key, ilog2(ARRAY_SIZE(hashtable))); \
+		hlist_add_head(node, &hashtable[index]); \
+	} while (0);
+#endif /* KERNEL_VER < KERNEL_VERSION(3, 7, 0) */
+
+#define STORE_WKLOCK_RECORD(wklock_type) \
+	do { \
+		struct wk_trace_record *wklock_info = NULL; \
+		unsigned long func_addr = (unsigned long)__builtin_return_address(0); \
+		wklock_info = find_wklock_entry(func_addr); \
+		if (wklock_info) { \
+			if (wklock_type == DHD_WAIVE_LOCK || wklock_type == DHD_RESTORE_LOCK) { \
+				wklock_info->counter = dhd->wakelock_counter; \
+			} else { \
+				wklock_info->counter++; \
+			} \
+		} else { \
+			wklock_info = kzalloc(sizeof(*wklock_info), GFP_ATOMIC); \
+			if (!wklock_info) {\
+				DHD_ERROR(("Can't allocate wk_trace_record \n")); \
+			} else { \
+				wklock_info->addr = func_addr; \
+				wklock_info->lock_type = wklock_type; \
+				if (wklock_type == DHD_WAIVE_LOCK || \
+						wklock_type == DHD_RESTORE_LOCK) { \
+					wklock_info->counter = dhd->wakelock_counter; \
+				} else { \
+					wklock_info->counter++; \
+				} \
+				HASH_ADD(wklock_history, &wklock_info->wklock_node, func_addr); \
+			} \
+		} \
+	} while (0);
+
+#else
+#define STORE_WKLOCK_RECORD(wklock_type)
+#endif /* DHD_TRACE_WAKE_LOCK */
+
+#ifdef ENABLE_ADAPTIVE_SCHED
+#define DEFAULT_CPUFREQ_THRESH		1000000	/* threshold frequency : 1000000 = 1GHz */
+#ifndef CUSTOM_CPUFREQ_THRESH
+#define CUSTOM_CPUFREQ_THRESH	DEFAULT_CPUFREQ_THRESH
+#endif /* CUSTOM_CPUFREQ_THRESH */
+#endif /* ENABLE_ADAPTIVE_SCHED */
+
+/* enable HOSTIP cache update from the host side when an eth0:N is up */
+#define AOE_IP_ALIAS_SUPPORT 1
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) && defined(DHD_TCP_LIMIT_OUTPUT)
+#ifndef DHD_TCP_LIMIT_OUTPUT_BYTES
+#define DHD_TCP_LIMIT_OUTPUT_BYTES (4 * 1024 * 1024)
+#endif /* DHD_TCP_LIMIT_OUTPUT_BYTES */
+#ifndef TCP_DEFAULT_LIMIT_OUTPUT
+#define TCP_DEFAULT_LIMIT_OUTPUT (256 * 1024)
+#endif /* TSQ_DEFAULT_LIMIT_OUTPUT */
+#endif /* LINUX_VERSION_CODE > 4.19.0 && DHD_TCP_LIMIT_OUTPUT */
+
+#define DHD_MEMDUMP_TYPE_STR_LEN 32
+#define DHD_MEMDUMP_PATH_STR_LEN 128
+
+typedef struct wifi_adapter_info {
+	const char	*name;
+	uint		irq_num;
+	uint		intr_flags;
+	const char	*fw_path;
+	const char	*nv_path;
+	const char	*clm_path;
+	const char	*conf_path;
+	void		*wifi_plat_data;	/* wifi ctrl func, for backward compatibility */
+	uint		bus_type;
+	uint		bus_num;
+	uint		slot_num;
+	int			index;
+	int 		gpio_wl_reg_on;
+#ifdef CUSTOMER_OOB
+	int 		gpio_wl_host_wake;
+#endif
+	wait_queue_head_t status_event;
+	unsigned long status;
+#if defined(BT_OVER_SDIO)
+	const char	*btfw_path;
+#endif /* defined (BT_OVER_SDIO) */
+#if defined(BCMSDIO)
+	struct sdio_func *sdio_func;
+#endif /* BCMSDIO */
+#if defined(BCMPCIE)
+	struct pci_dev *pci_dev;
+	struct pci_saved_state *pci_saved_state;
+#endif /* BCMPCIE */
+#ifdef BCMDHD_PLATDEV
+	struct platform_device *pdev;
+#endif /* BCMDHD_PLATDEV */
+} wifi_adapter_info_t;
+
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+#include <linux/wlan_plat.h>
+#else
+#include <dhd_plat.h>
+#endif /* CONFIG_WIFI_CONTROL_FUNC */
+
+typedef struct bcmdhd_wifi_platdata {
+	uint				num_adapters;
+	wifi_adapter_info_t	*adapters;
+} bcmdhd_wifi_platdata_t;
+
+/** Per STA params. A list of dhd_sta objects are managed in dhd_if */
+typedef struct dhd_sta {
+	cumm_ctr_t cumm_ctr;    /* cummulative queue length of child flowrings */
+	uint16 flowid[NUMPRIO]; /* allocated flow ring ids (by priority) */
+	void * ifp;             /* associated dhd_if */
+	struct ether_addr ea;   /* stations ethernet mac address */
+	struct list_head list;  /* link into dhd_if::sta_list */
+	int idx;                /* index of self in dhd_pub::sta_pool[] */
+	int ifidx;              /* index of interface in dhd */
+#ifdef DHD_WMF
+	struct dhd_sta *psta_prim; /* primary index of psta interface */
+#endif /* DHD_WMF */
+	chanspec_t chanspec;	/* sta chanspec info */
+} dhd_sta_t;
+typedef dhd_sta_t dhd_sta_pool_t;
+
+#ifdef DHD_4WAYM4_FAIL_DISCONNECT
+typedef enum {
+	NONE_4WAY,
+	M1_4WAY,
+	M2_4WAY,
+	M3_4WAY,
+	M4_4WAY
+} msg_4way_t;
+typedef enum {
+	M3_RXED,
+	M4_TXFAILED
+} msg_4way_state_t;
+#define MAX_4WAY_TIMEOUT_MS 2000
+#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
+
+#if defined(DHD_LB)
+/* Dynamic CPU selection for load balancing. */
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/notifier.h>
+#include <linux/workqueue.h>
+#include <asm/atomic.h>
+
+/* FIXME: Make this a module param or a sysfs. */
+#if !defined(DHD_LB_PRIMARY_CPUS)
+#define DHD_LB_PRIMARY_CPUS     0x0 /* Big CPU coreids mask */
+#endif
+#if !defined(DHD_LB_SECONDARY_CPUS)
+#define DHD_LB_SECONDARY_CPUS   0xFE /* Little CPU coreids mask */
+#endif
+
+#define HIST_BIN_SIZE	9
+
+#if defined(DHD_LB_TXP)
+/* Pkttag not compatible with PROP_TXSTATUS or WLFC */
+typedef struct dhd_tx_lb_pkttag_fr {
+	struct net_device *net;
+	int ifidx;
+} dhd_tx_lb_pkttag_fr_t;
+
+#define DHD_LB_TX_PKTTAG_SET_NETDEV(tag, netdevp)	((tag)->net = netdevp)
+#define DHD_LB_TX_PKTTAG_NETDEV(tag)			((tag)->net)
+
+#define DHD_LB_TX_PKTTAG_SET_IFIDX(tag, ifidx)	((tag)->ifidx = ifidx)
+#define DHD_LB_TX_PKTTAG_IFIDX(tag)		((tag)->ifidx)
+#endif /* DHD_LB_TXP */
+#endif /* DHD_LB */
+
+#define FILE_DUMP_MAX_WAIT_TIME 4000
+
+#ifdef IL_BIGENDIAN
+#include <bcmendian.h>
+#define htod32(i) (bcmswap32(i))
+#define htod16(i) (bcmswap16(i))
+#define dtoh32(i) (bcmswap32(i))
+#define dtoh16(i) (bcmswap16(i))
+#define htodchanspec(i) htod16(i)
+#define dtohchanspec(i) dtoh16(i)
+#else
+#define htod32(i) (i)
+#define htod16(i) (i)
+#define dtoh32(i) (i)
+#define dtoh16(i) (i)
+#define htodchanspec(i) (i)
+#define dtohchanspec(i) (i)
+#endif /* IL_BIGENDINA */
+
+#ifdef BLOCK_IPV6_PACKET
+#define HEX_PREF_STR	"0x"
+#define UNI_FILTER_STR	"010000000000"
+#define ZERO_ADDR_STR	"000000000000"
+#define ETHER_TYPE_STR	"0000"
+#define IPV6_FILTER_STR	"20"
+#define ZERO_TYPE_STR	"00"
+#endif /* BLOCK_IPV6_PACKET */
+
+#if defined(OEM_ANDROID) && defined(SOFTAP)
+extern bool ap_cfg_running;
+extern bool ap_fw_loaded;
+#endif
+
+#if defined(OEM_ANDROID) && defined(BCMPCIE)
+extern int dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd, int *dtim_period, int *bcn_interval);
+#else
+extern int dhd_get_suspend_bcn_li_dtim(dhd_pub_t *dhd);
+#endif /* OEM_ANDROID && BCMPCIE */
+
+#ifdef CUSTOMER_HW4
+#ifdef MIMO_ANT_SETTING
+#ifdef DHD_EXPORT_CNTL_FILE
+extern unsigned long antsel;
+#endif /* DHD_EXPORT_CNTL_FILE */
+extern int dhd_sel_ant_from_file(dhd_pub_t *dhd);
+#endif /* MIMO_ANT_SETTING */
+#ifdef WRITE_WLANINFO
+#define MAX_VERSION_LEN		512
+#ifdef DHD_EXPORT_CNTL_FILE
+extern char version_info[MAX_VERSION_LEN];
+#endif /* DHD_EXPORT_CNTL_FILE */
+extern uint32 sec_save_wlinfo(char *firm_ver, char *dhd_ver, char *nvram_p, char *clm_ver);
+#endif /* WRITE_WLANINFO */
+#ifdef LOGTRACE_FROM_FILE
+extern int dhd_logtrace_from_file(dhd_pub_t *dhd);
+#ifdef DHD_EXPORT_CNTL_FILE
+extern unsigned long logtrace_val;
+#endif /* DHD_EXPORT_CNTL_FILE */
+#endif /* LOGTRACE_FROM_FILE */
+#ifdef GEN_SOFTAP_INFO_FILE
+#define SOFTAP_INFO_BUF_SZ 512
+#ifdef DHD_EXPORT_CNTL_FILE
+extern char softapinfostr[SOFTAP_INFO_BUF_SZ];
+#endif /* DHD_EXPORT_CNTL_FILE */
+extern uint32 sec_save_softap_info(void);
+#endif /* GEN_SOFTAP_INFO_FILE */
+#endif /* CUSTOMER_HW4 */
+
+#ifdef DHD_SEND_HANG_PRIVCMD_ERRORS
+extern uint32 report_hang_privcmd_err;
+#endif /* DHD_SEND_HANG_PRIVCMD_ERRORS */
+
+#if defined(SOFTAP_TPUT_ENHANCE)
+extern void dhd_bus_setidletime(dhd_pub_t *dhdp, int idle_time);
+extern void dhd_bus_getidletime(dhd_pub_t *dhdp, int* idle_time);
+#endif /* SOFTAP_TPUT_ENHANCE */
+
+#if defined(BCM_ROUTER_DHD)
+void traffic_mgmt_pkt_set_prio(dhd_pub_t *dhdp, void * pktbuf);
+#endif /* BCM_ROUTER_DHD */
+
+typedef struct dhd_if_event {
+	struct list_head	list;
+	wl_event_data_if_t	event;
+	char			name[IFNAMSIZ+1];
+	uint8			mac[ETHER_ADDR_LEN];
+} dhd_if_event_t;
+
+/* Interface control information */
+typedef struct dhd_if {
+	struct dhd_info *info;			/* back pointer to dhd_info */
+	/* OS/stack specifics */
+	struct net_device *net;
+	int				idx;			/* iface idx in dongle */
+	uint			subunit;		/* subunit */
+	uint8			mac_addr[ETHER_ADDR_LEN];	/* assigned MAC address */
+	bool			set_macaddress;
+	bool			set_multicast;
+	uint8			bssidx;			/* bsscfg index for the interface */
+	bool			attached;		/* Delayed attachment when unset */
+	bool			txflowcontrol;	/* Per interface flow control indicator */
+	char			name[IFNAMSIZ+1]; /* linux interface name */
+	char			dngl_name[IFNAMSIZ+1]; /* corresponding dongle interface name */
+	struct net_device_stats stats;
+#ifdef DHD_WMF
+	dhd_wmf_t		wmf;		/* per bsscfg wmf setting */
+	bool	wmf_psta_disable;		/* enable/disable MC pkt to each mac
+						 * of MC group behind PSTA
+						 */
+#endif /* DHD_WMF */
+#ifdef PCIE_FULL_DONGLE
+	struct list_head sta_list;		/* sll of associated stations */
+	spinlock_t	sta_list_lock;		/* lock for manipulating sll */
+#endif /* PCIE_FULL_DONGLE */
+	uint32  ap_isolate;			/* ap-isolation settings */
+#ifdef DHD_L2_FILTER
+	bool parp_enable;
+	bool parp_discard;
+	bool parp_allnode;
+	arp_table_t *phnd_arp_table;
+	/* for Per BSS modification */
+	bool dhcp_unicast;
+	bool block_ping;
+	bool grat_arp;
+	bool block_tdls;
+#endif /* DHD_L2_FILTER */
+#if (defined(BCM_ROUTER_DHD) && defined(QOS_MAP_SET))
+	uint8	 *qosmap_up_table;		/* user priority table, size is UP_TABLE_MAX */
+	bool qosmap_up_table_enable;	/* flag set only when app want to set additional UP */
+#endif /* BCM_ROUTER_DHD && QOS_MAP_SET */
+#ifdef DHD_MCAST_REGEN
+	bool mcast_regen_bss_enable;
+#endif
+	bool rx_pkt_chainable;		/* set all rx packet to chainable config by default */
+	cumm_ctr_t cumm_ctr;		/* cummulative queue length of child flowrings */
+#ifdef BCM_ROUTER_DHD
+	bool	primsta_dwds;		/* DWDS status of primary sta interface */
+#endif /* BCM_ROUTER_DHD */
+	uint8 tx_paths_active;
+	bool del_in_progress;
+	bool static_if;			/* used to avoid some operations on static_if */
+#ifdef DHD_4WAYM4_FAIL_DISCONNECT
+	struct delayed_work m4state_work;
+	atomic_t m4state;
+#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
+#ifdef DHDTCPSYNC_FLOOD_BLK
+	uint32 tsync_rcvd;
+	uint32 tsyncack_txed;
+	u64 last_sync;
+	struct work_struct  blk_tsfl_work;
+	uint32 tsync_per_sec;
+	bool disconnect_tsync_flood;
+#endif /* DHDTCPSYNC_FLOOD_BLK */
+#ifdef DHD_POST_EAPOL_M1_AFTER_ROAM_EVT
+	bool recv_reassoc_evt;
+	bool post_roam_evt;
+#endif /* DHD_POST_EAPOL_M1_AFTER_ROAM_EVT */
+#ifdef WLDWDS
+	bool dwds;	/* DWDS interface */
+#endif /* WLDWDS */
+#ifdef WLEASYMESH
+	uint8 _1905_al_ucast[ETHER_ADDR_LEN];
+	uint8 _1905_al_mcast[ETHER_ADDR_LEN];
+#endif /* WLEASYMESH */
+} dhd_if_t;
+
+struct ipv6_work_info_t {
+	uint8			if_idx;
+	char			ipv6_addr[IPV6_ADDR_LEN];
+	unsigned long		event;
+};
+
+typedef struct dhd_dump {
+	uint8 *buf;
+	int bufsize;
+	uint8 *hscb_buf;
+	int hscb_bufsize;
+} dhd_dump_t;
+#ifdef DNGL_AXI_ERROR_LOGGING
+typedef struct dhd_axi_error_dump {
+	ulong fault_address;
+	uint32 axid;
+	struct hnd_ext_trap_axi_error_v1 etd_axi_error_v1;
+} dhd_axi_error_dump_t;
+#endif /* DNGL_AXI_ERROR_LOGGING */
+#ifdef BCM_ROUTER_DHD
+typedef struct dhd_write_file {
+	char file_path[64];
+	uint32 file_flags;
+	uint8 *buf;
+	int bufsize;
+} dhd_write_file_t;
+#endif
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+struct dhd_rx_tx_work {
+	struct work_struct work;
+	struct sk_buff *skb;
+	struct net_device *net;
+	struct dhd_pub *pub;
+};
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+#ifdef FILTER_IE
+#ifdef DHD_LINUX_STD_FW_API
+#define FILTER_IE_PATH "filter_ie"
+#else
+#define FILTER_IE_PATH "/vendor/etc/wifi/filter_ie"
+#endif /* DHD_LINUX_STD_FW_API */
+#define FILTER_IE_BUFSZ 1024 /* ioc buffsize for FILTER_IE */
+#define FILE_BLOCK_READ_SIZE 256
+#define WL_FILTER_IE_IOV_HDR_SIZE OFFSETOF(wl_filter_ie_iov_v1_t, tlvs)
+#endif /* FILTER_IE */
+
+#define NULL_CHECK(p, s, err)  \
+do { \
+	if (!(p)) { \
+		DHD_ERROR(("NULL POINTER (%s) : %s\n", __FUNCTION__, (s))); \
+		err = BCME_ERROR; \
+		return err; \
+	} \
+} while (0)
+
+int dhd_wifi_platform_register_drv(void);
+void dhd_wifi_platform_unregister_drv(void);
+wifi_adapter_info_t* dhd_wifi_platform_attach_adapter(uint32 bus_type,
+	uint32 bus_num, uint32 slot_num, unsigned long status);
+wifi_adapter_info_t* dhd_wifi_platform_get_adapter(uint32 bus_type, uint32 bus_num,
+	uint32 slot_num);
+int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on, unsigned long msec);
+int wifi_platform_bus_enumerate(wifi_adapter_info_t *adapter, bool device_present);
+int wifi_platform_get_irq_number(wifi_adapter_info_t *adapter, unsigned long *irq_flags_ptr);
+extern int wifi_platform_get_irq_level(wifi_adapter_info_t *adapter);
+int wifi_platform_get_mac_addr(wifi_adapter_info_t *adapter, unsigned char *buf, int ifidx);
+#ifdef DHD_COREDUMP
+int wifi_platform_set_coredump(wifi_adapter_info_t *adapter, const char *buf, int buf_len,
+	const char *info);
+#endif /* DHD_COREDUMP */
+#ifdef CUSTOM_COUNTRY_CODE
+void *wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode,
+	u32 flags);
+#else
+void *wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode);
+#endif /* CUSTOM_COUNTRY_CODE */
+void* wifi_platform_prealloc(wifi_adapter_info_t *adapter, int section, unsigned long size);
+void* wifi_platform_get_prealloc_func_ptr(wifi_adapter_info_t *adapter);
+
+int dhd_get_fw_mode(struct dhd_info *dhdinfo);
+bool dhd_update_fw_nv_path(struct dhd_info *dhdinfo);
+#ifdef BCM_ROUTER_DHD
+void dhd_update_dpsta_interface_for_sta(dhd_pub_t* dhdp, int ifidx, void* event_data);
+#endif /* BCM_ROUTER_DHD */
+#ifdef DHD_WMF
+dhd_wmf_t* dhd_wmf_conf(dhd_pub_t *dhdp, uint32 idx);
+int dhd_get_wmf_psta_disable(dhd_pub_t *dhdp, uint32 idx);
+int dhd_set_wmf_psta_disable(dhd_pub_t *dhdp, uint32 idx, int val);
+void dhd_update_psta_interface_for_sta(dhd_pub_t *dhdp, char* ifname,
+		void* mac_addr, void* event_data);
+#endif /* DHD_WMF */
+
+#if defined(BT_OVER_SDIO)
+int dhd_net_bus_get(struct net_device *dev);
+int dhd_net_bus_put(struct net_device *dev);
+#endif /* BT_OVER_SDIO */
+#if defined(WLADPS)
+#define ADPS_ENABLE	1
+#define ADPS_DISABLE	0
+#define ADPS_MODE_PM2_ONLY	3
+
+int dhd_enable_adps(dhd_pub_t *dhd, uint8 on);
+#endif
+#ifdef DHDTCPSYNC_FLOOD_BLK
+extern void dhd_reset_tcpsync_info_by_ifp(dhd_if_t *ifp);
+extern void dhd_reset_tcpsync_info_by_dev(struct net_device *dev);
+#endif /* DHDTCPSYNC_FLOOD_BLK */
+extern void dhd_set_del_in_progress(dhd_pub_t *dhdp, struct net_device * ndev);
+extern void dhd_clear_del_in_progress(dhd_pub_t *dhdp, struct net_device * ndev);
+#ifdef PCIE_FULL_DONGLE
+extern void dhd_net_del_flowrings_sta(dhd_pub_t * dhd, struct net_device * ndev);
+#endif /* PCIE_FULL_DONGLE */
+int dhd_get_fw_capabilities(dhd_pub_t * dhd);
+#ifdef BCMDBUS
+int dhd_dbus_txdata(dhd_pub_t *dhdp, void *pktbuf);
+#endif
+void dhd_event_logtrace_enqueue(dhd_pub_t *dhdp, int ifidx, void *pktbuf);
+#if defined(SUPPORT_MULTIPLE_NVRAM) || defined(SUPPORT_MULTIPLE_CLMBLOB)
+int dhd_get_platform_naming_for_nvram_clmblob_file(download_type_t component, char* file_name);
+#ifdef USE_CID_CHECK
+void dhd_set_platform_ext_name_for_chip_version(char* chip_version);
+#endif /* USE_CID_CHECK */
+#endif /* SUPPORT_MULTIPLE_NVRAM || SUPPORT_MULTIPLE_CLMBLOB */
+void dhd_netif_rx_ni(struct sk_buff * skb);
+#if defined(DBG_PKT_MON) && !defined(PCIE_FULL_DONGLE)
+extern bool dhd_80211_mon_pkt(dhd_pub_t *dhdp, void *pkt, int ifidx);
+#endif /* DBG_PKT_MON */
+
+#endif /* __DHD_LINUX_H__ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux_exportfs.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux_exportfs.c
@@ -0,0 +1,3792 @@
+/*
+ * Broadcom Dongle Host Driver (DHD), Linux-specific network interface
+ * Basically selected code segments from usb-cdc.c and usb-rndis.c
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+#include <linux/kobject.h>
+#include <linux/proc_fs.h>
+#include <linux/sysfs.h>
+#include <osl.h>
+#include <dhd.h>
+#include <dhd_dbg.h>
+#include <dhd_linux_priv.h>
+#include <dhd_proto.h>
+#if defined(WL_BAM)
+#include <wl_bam.h>
+#endif	/* WL_BAM */
+#ifdef PWRSTATS_SYSFS
+#include <wldev_common.h>
+#endif /* PWRSTATS_SYSFS */
+#ifdef WL_CFG80211
+#include <wl_cfg80211.h>
+#endif /* WL_CFG80211 */
+#ifdef CSI_SUPPORT
+#include <dhd_csi.h>
+#endif /* CSI_SUPPORT */
+
+#ifdef SHOW_LOGTRACE
+extern dhd_pub_t* g_dhd_pub;
+#if defined(DEBUGABILITY) || defined(EWP_ECNTRS_LOGGING) || defined(EWP_RTT_LOGGING)
+static int dhd_ring_proc_open(struct inode *inode, struct file *file);
+ssize_t dhd_ring_proc_read(struct file *file, char *buffer, size_t tt, loff_t *loff);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0))
+static const struct file_operations dhd_ring_proc_ops = {
+	.open = dhd_ring_proc_open,
+	.read = dhd_ring_proc_read,
+	.release = single_release,
+};
+#else
+static const struct proc_ops dhd_ring_proc_ops = {
+	.proc_open = dhd_ring_proc_open,
+	.proc_read = dhd_ring_proc_read,
+	.proc_release = single_release,
+};
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0) */
+
+static int
+dhd_ring_proc_open(struct inode *inode, struct file *file)
+{
+	int ret = BCME_ERROR;
+	if (inode) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0))
+		ret = single_open(file, 0, pde_data(inode));
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
+		ret = single_open(file, 0, PDE_DATA(inode));
+#else
+		/* This feature is not supported for lower kernel versions */
+		ret = single_open(file, 0, NULL);
+#endif
+	} else {
+		DHD_ERROR(("%s: inode is NULL\n", __FUNCTION__));
+	}
+	return ret;
+}
+
+ssize_t
+dhd_ring_proc_read(struct file *file, char __user *buffer, size_t tt, loff_t *loff)
+{
+	trace_buf_info_t *trace_buf_info;
+	int ret = BCME_ERROR;
+	dhd_dbg_ring_t *ring = (dhd_dbg_ring_t *)((struct seq_file *)(file->private_data))->private;
+
+	if (ring == NULL) {
+		DHD_ERROR(("%s: ring is NULL\n", __FUNCTION__));
+		return ret;
+	}
+
+	ASSERT(g_dhd_pub);
+
+	trace_buf_info = (trace_buf_info_t *)MALLOCZ(g_dhd_pub->osh, sizeof(trace_buf_info_t));
+	if (trace_buf_info) {
+		dhd_dbg_read_ring_into_trace_buf(ring, trace_buf_info);
+		if (!buffer || (MIN(trace_buf_info->size, tt) > TRACE_LOG_BUF_MAX_SIZE)) {
+			DHD_ERROR(("%s: size %zu tt %zu trace_buf_sz %d\n", __FUNCTION__,
+				MIN(trace_buf_info->size, tt), tt, trace_buf_info->size));
+			ret = -ENOMEM;
+			goto exit;
+		}
+		if (copy_to_user(buffer, (void*)trace_buf_info->buf,
+				MIN(trace_buf_info->size, tt))) {
+			ret = -EFAULT;
+			goto exit;
+		}
+		if (trace_buf_info->availability == BUF_NOT_AVAILABLE)
+			ret = BUF_NOT_AVAILABLE;
+		else
+			ret = trace_buf_info->size;
+	} else
+		DHD_ERROR(("%s: Memory allocation Failed\n", __FUNCTION__));
+
+exit:
+	if (trace_buf_info) {
+		MFREE(g_dhd_pub->osh, trace_buf_info, sizeof(trace_buf_info_t));
+	}
+	return ret;
+}
+#endif /* DEBUGABILITY || EWP_ECNTRS_LOGGING || EWP_RTT_LOGGING */
+
+void
+dhd_dbg_ring_proc_create(dhd_pub_t *dhdp)
+{
+#ifdef DEBUGABILITY
+	dhd_dbg_ring_t *dbg_verbose_ring = NULL;
+
+	dbg_verbose_ring = dhd_dbg_get_ring_from_ring_id(dhdp, FW_VERBOSE_RING_ID);
+	if (dbg_verbose_ring) {
+		if (!proc_create_data("dhd_trace", S_IRUSR, NULL, &dhd_ring_proc_ops,
+			dbg_verbose_ring)) {
+			DHD_ERROR(("Failed to create /proc/dhd_trace procfs interface\n"));
+		} else {
+			DHD_INFO(("Created /proc/dhd_trace procfs interface\n"));
+		}
+	} else {
+		DHD_ERROR(("dbg_verbose_ring is NULL, /proc/dhd_trace not created\n"));
+	}
+#endif /* DEBUGABILITY */
+
+#ifdef EWP_ECNTRS_LOGGING
+	if (!proc_create_data("dhd_ecounters", S_IRUSR, NULL, &dhd_ring_proc_ops,
+		dhdp->ecntr_dbg_ring)) {
+		DHD_ERROR(("Failed to create /proc/dhd_ecounters procfs interface\n"));
+	} else {
+		DHD_INFO(("Created /proc/dhd_ecounters procfs interface\n"));
+	}
+#endif /* EWP_ECNTRS_LOGGING */
+
+#ifdef EWP_RTT_LOGGING
+	if (!proc_create_data("dhd_rtt", S_IRUSR, NULL, &dhd_ring_proc_ops,
+		dhdp->rtt_dbg_ring)) {
+		DHD_ERROR(("Failed to create /proc/dhd_rtt procfs interface\n"));
+	} else {
+		DHD_INFO(("Created /proc/dhd_rtt procfs interface\n"));
+	}
+#endif /* EWP_RTT_LOGGING */
+}
+
+void
+dhd_dbg_ring_proc_destroy(dhd_pub_t *dhdp)
+{
+#ifdef DEBUGABILITY
+	remove_proc_entry("dhd_trace", NULL);
+#endif /* DEBUGABILITY */
+
+#ifdef EWP_ECNTRS_LOGGING
+	remove_proc_entry("dhd_ecounters", NULL);
+#endif /* EWP_ECNTRS_LOGGING */
+
+#ifdef EWP_RTT_LOGGING
+	remove_proc_entry("dhd_rtt", NULL);
+#endif /* EWP_RTT_LOGGING */
+
+}
+#endif /* SHOW_LOGTRACE */
+
+/* ----------------------------------------------------------------------------
+ * Infrastructure code for sysfs interface support for DHD
+ *
+ * What is sysfs interface?
+ * https://www.kernel.org/doc/Documentation/filesystems/sysfs.txt
+ *
+ * Why sysfs interface?
+ * This is the Linux standard way of changing/configuring Run Time parameters
+ * for a driver. We can use this interface to control "linux" specific driver
+ * parameters.
+ *
+ * -----------------------------------------------------------------------------
+ */
+
+#if defined(DHD_TRACE_WAKE_LOCK)
+extern atomic_t trace_wklock_onoff;
+
+/* Function to show the history buffer */
+static ssize_t
+show_wklock_trace(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+	dhd_info_t *dhd = (dhd_info_t *)dev;
+
+	buf[ret] = '\n';
+	buf[ret+1] = 0;
+
+	dhd_wk_lock_stats_dump(&dhd->pub);
+	return ret+1;
+}
+
+/* Function to enable/disable wakelock trace */
+static ssize_t
+wklock_trace_onoff(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long onoff;
+	dhd_info_t *dhd = (dhd_info_t *)dev;
+	BCM_REFERENCE(dhd);
+
+	onoff = bcm_strtoul(buf, NULL, 10);
+	if (onoff != 0 && onoff != 1) {
+		return -EINVAL;
+	}
+
+	atomic_set(&trace_wklock_onoff, onoff);
+	if (atomic_read(&trace_wklock_onoff)) {
+		DHD_ERROR(("ENABLE WAKLOCK TRACE\n"));
+	} else {
+		DHD_ERROR(("DISABLE WAKELOCK TRACE\n"));
+	}
+
+	return (ssize_t)(onoff+1);
+}
+#endif /* DHD_TRACE_WAKE_LOCK */
+
+#ifdef DHD_LOG_DUMP
+extern int logdump_periodic_flush;
+extern int logdump_ecntr_enable;
+static ssize_t
+show_logdump_periodic_flush(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+	unsigned long val;
+
+	val = logdump_periodic_flush;
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%lu \n", val);
+	return ret;
+}
+
+static ssize_t
+logdump_periodic_flush_onoff(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long val;
+
+	val = bcm_strtoul(buf, NULL, 10);
+
+	sscanf(buf, "%lu", &val);
+	if (val != 0 && val != 1) {
+		 return -EINVAL;
+	}
+	logdump_periodic_flush = val;
+	return count;
+}
+
+static ssize_t
+show_logdump_ecntr(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+	unsigned long val;
+
+	val = logdump_ecntr_enable;
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%lu \n", val);
+	return ret;
+}
+
+static ssize_t
+logdump_ecntr_onoff(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long val;
+
+	val = bcm_strtoul(buf, NULL, 10);
+
+	sscanf(buf, "%lu", &val);
+	if (val != 0 && val != 1) {
+		 return -EINVAL;
+	}
+	logdump_ecntr_enable = val;
+	return count;
+}
+
+#endif /* DHD_LOG_DUMP */
+
+extern uint enable_ecounter;
+static ssize_t
+show_enable_ecounter(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+	unsigned long onoff;
+
+	onoff = enable_ecounter;
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%lu \n",
+		onoff);
+	return ret;
+}
+
+static ssize_t
+ecounter_onoff(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long onoff;
+	dhd_info_t *dhd = (dhd_info_t *)dev;
+	dhd_pub_t *dhdp;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return count;
+	}
+	dhdp = &dhd->pub;
+	if (!FW_SUPPORTED(dhdp, ecounters)) {
+		DHD_ERROR(("%s: ecounters not supported by FW\n", __FUNCTION__));
+		return count;
+	}
+
+	onoff = bcm_strtoul(buf, NULL, 10);
+
+	sscanf(buf, "%lu", &onoff);
+	if (onoff != 0 && onoff != 1) {
+		return -EINVAL;
+	}
+
+	if (enable_ecounter == onoff) {
+		DHD_ERROR(("%s: ecounters already %d\n", __FUNCTION__, enable_ecounter));
+		return count;
+	}
+
+	enable_ecounter = onoff;
+	dhd_ecounter_configure(dhdp, enable_ecounter);
+
+	return count;
+}
+
+#ifdef DHD_SSSR_DUMP
+static ssize_t
+show_sssr_enab(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+	unsigned long onoff;
+
+	onoff = sssr_enab;
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%lu \n",
+		onoff);
+	return ret;
+}
+
+static ssize_t
+set_sssr_enab(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long onoff;
+
+	onoff = bcm_strtoul(buf, NULL, 10);
+
+	sscanf(buf, "%lu", &onoff);
+	if (onoff != 0 && onoff != 1) {
+		return -EINVAL;
+	}
+
+	sssr_enab = (uint)onoff;
+
+	return count;
+}
+
+static ssize_t
+show_fis_enab(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+	unsigned long onoff;
+
+	onoff = fis_enab;
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%lu \n",
+		onoff);
+	return ret;
+}
+
+static ssize_t
+set_fis_enab(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long onoff;
+
+	onoff = bcm_strtoul(buf, NULL, 10);
+
+	sscanf(buf, "%lu", &onoff);
+	if (onoff != 0 && onoff != 1) {
+		return -EINVAL;
+	}
+
+	fis_enab = (uint)onoff;
+
+	return count;
+}
+#endif /* DHD_SSSR_DUMP */
+
+#define FMT_BUFSZ	32
+extern char firmware_path[];
+
+static ssize_t
+show_firmware_path(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%s\n", firmware_path);
+
+	return ret;
+}
+
+static ssize_t
+store_firmware_path(struct dhd_info *dev, const char *buf, size_t count)
+{
+	char fmt_spec[FMT_BUFSZ] = "";
+
+	if ((int)strlen(buf) >= MOD_PARAM_PATHLEN) {
+		return -EINVAL;
+	}
+
+	snprintf(fmt_spec, FMT_BUFSZ, "%%%ds", MOD_PARAM_PATHLEN - 1);
+	sscanf(buf, fmt_spec, firmware_path);
+
+	return count;
+}
+
+extern char nvram_path[];
+
+static ssize_t
+show_nvram_path(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%s\n", nvram_path);
+
+	return ret;
+}
+
+static ssize_t
+store_nvram_path(struct dhd_info *dev, const char *buf, size_t count)
+{
+	char fmt_spec[FMT_BUFSZ] = "";
+
+	if ((int)strlen(buf) >= MOD_PARAM_PATHLEN) {
+		return -EINVAL;
+	}
+
+	snprintf(fmt_spec, FMT_BUFSZ, "%%%ds", MOD_PARAM_PATHLEN - 1);
+	sscanf(buf, fmt_spec, nvram_path);
+
+	return count;
+}
+
+extern char signature_path[];
+
+static ssize_t
+show_signature_path(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%s\n", signature_path);
+
+	return ret;
+}
+
+static ssize_t
+store_signature_path(struct dhd_info *dev, const char *buf, size_t count)
+{
+	char fmt_spec[FMT_BUFSZ] = "";
+
+	if ((int)strlen(buf) >= MOD_PARAM_PATHLEN) {
+		return -EINVAL;
+	}
+
+	snprintf(fmt_spec, FMT_BUFSZ, "%%%ds", MOD_PARAM_PATHLEN - 1);
+	sscanf(buf, fmt_spec, signature_path);
+
+	return count;
+}
+
+#ifdef PWRSTATS_SYSFS
+typedef struct wl_pwrstats_sysfs {
+	uint64	current_ts;
+	uint64	pm_cnt;
+	uint64	pm_dur;
+	uint64	pm_last_entry_us;
+	uint64	awake_cnt;
+	uint64	awake_dur;
+	uint64	awake_last_entry_us;
+	uint64	l0_cnt;
+	uint64	l0_dur_us;
+	uint64	l1_cnt;
+	uint64	l1_dur_us;
+	uint64	l1_1_cnt;
+	uint64	l1_1_dur_us;
+	uint64	l1_2_cnt;
+	uint64	l1_2_dur_us;
+	uint64	l2_cnt;
+	uint64	l2_dur_us;
+} wl_pwrstats_sysfs_t;
+
+uint64 last_delta = 0;
+wl_pwrstats_sysfs_t accumstats = {0, };
+wl_pwrstats_sysfs_t laststats = {0, };
+static const char pwrstr_cnt[] = "count:";
+static const char pwrstr_dur[] = "duration_usec:";
+static const char pwrstr_ts[] = "last_entry_timestamp_usec:";
+
+ssize_t print_pwrstats_cum(char *buf)
+{
+	ssize_t ret = 0;
+
+	ret += scnprintf(buf, PAGE_SIZE, "WIFI\n");
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "AWAKE:\n");
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_cnt,
+		accumstats.awake_cnt);
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_dur,
+		accumstats.awake_dur);
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_ts,
+		laststats.awake_last_entry_us);
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "ASLEEP:\n");
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_cnt,
+		accumstats.pm_cnt);
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_dur,
+		accumstats.pm_dur);
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_ts,
+		laststats.pm_last_entry_us);
+
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\nWIFI-PCIE\n");
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "L0:\n");
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_cnt,
+		accumstats.l0_cnt);
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_dur,
+		accumstats.l0_dur_us);
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "L1:\n");
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_cnt,
+		accumstats.l1_cnt);
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_dur,
+		accumstats.l1_dur_us);
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "L1_1:\n");
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_cnt,
+		accumstats.l1_1_cnt);
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_dur,
+		accumstats.l1_1_dur_us);
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "L1_2:\n");
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_cnt,
+		accumstats.l1_2_cnt);
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_dur,
+		accumstats.l1_2_dur_us);
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "L2:\n");
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_cnt,
+		accumstats.l2_cnt);
+	ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%s 0x%0llx\n", pwrstr_dur,
+		accumstats.l2_dur_us);
+
+	return ret;
+}
+
+void update_pwrstats_cum(uint64 *accum, uint64 *last, uint64 *now, bool force)
+{
+	if (accum) { /* accumulation case, ex; counts, duration */
+		if (*now < *last) {
+			if (force) {
+				/* force update for pm_cnt/awake_cnt and PCIE stats */
+				*accum += *now;
+				*last = *now;
+			}
+		} else {
+			*accum += (*now - *last);
+			*last = *now;
+		}
+	} else if (*now != 0) { /* last entry timestamp case */
+		*last = *now + last_delta;
+	}
+}
+
+static const uint16 pwrstats_req_type[] = {
+	WL_PWRSTATS_TYPE_PCIE,
+	WL_PWRSTATS_TYPE_PM_ACCUMUL
+};
+#define PWRSTATS_REQ_TYPE_NUM	sizeof(pwrstats_req_type) / sizeof(uint16)
+#define PWRSTATS_IOV_BUF_LEN	OFFSETOF(wl_pwrstats_t, data) \
+	+ sizeof(uint32) * PWRSTATS_REQ_TYPE_NUM \
+	+ sizeof(wl_pwr_pcie_stats_t) \
+	+ sizeof(wl_pwr_pm_accum_stats_v1_t) \
+	+ (uint)strlen("pwrstats") + 1
+
+#ifdef BCMPCIE
+extern uint64 dhdpcie_get_last_suspend_time(dhd_pub_t *dhdp);
+#endif /* BCMPCIE */
+
+#ifdef BCMSDIO
+extern uint64 dhdsdio_get_last_suspend_time(dhd_pub_t *dhdp);
+#endif /* BCMSDIO */
+
+uint64
+dhd_get_last_suspend_time(dhd_pub_t *dhdp)
+{
+#if defined(BCMPCIE)
+	return dhdpcie_get_last_suspend_time(dhdp);
+#elif defined(BCMSDIO)
+	return dhdsdio_get_last_suspend_time(dhdp);
+#else
+	return 0;
+#endif
+}
+
+static ssize_t
+show_pwrstats_path(struct dhd_info *dev, char *buf)
+{
+	int err = 0;
+	void *p_data = NULL;
+	ssize_t ret = 0;
+	dhd_info_t *dhd = (dhd_info_t *)dev;
+	struct net_device *ndev = dhd_linux_get_primary_netdev(&dhd->pub);
+	char *iovar_buf = NULL;
+	wl_pwrstats_query_t *p_query = NULL;
+	wl_pwrstats_sysfs_t pwrstats_sysfs = {0, };
+	wl_pwrstats_t *pwrstats;
+	uint len, taglen, i;
+	uint16 type;
+	uint64 ts_sec, ts_usec, time_delta;
+
+	ASSERT(g_dhd_pub);
+
+	/* Even if dongle is in D3 state,
+	 * ASLEEP duration should be updated with estimated value.
+	 */
+	if (!dhd_os_check_if_up(&dhd->pub)) {
+		if (dhd->pub.busstate == DHD_BUS_SUSPEND) {
+			static uint64 last_suspend_end_time = 0;
+			uint64 curr_time = 0, estimated_pm_dur = 0;
+
+			if (last_suspend_end_time <
+					dhd_get_last_suspend_time(&dhd->pub)) {
+				last_suspend_end_time = dhd_get_last_suspend_time(&dhd->pub);
+			}
+
+			curr_time = OSL_LOCALTIME_NS();
+			if (curr_time >= last_suspend_end_time) {
+				estimated_pm_dur = DIV_U64_BY_U32(
+					(curr_time - last_suspend_end_time), NSEC_PER_USEC);
+				estimated_pm_dur += laststats.pm_dur;
+
+				update_pwrstats_cum(&accumstats.pm_dur, &laststats.pm_dur,
+					&estimated_pm_dur, FALSE);
+				last_suspend_end_time = curr_time;
+			}
+		}
+		ret = print_pwrstats_cum(buf);
+		goto done; /* Not ready yet */
+	}
+
+	len = PWRSTATS_IOV_BUF_LEN;
+	iovar_buf = (char *)MALLOCZ(g_dhd_pub->osh, len);
+	if (iovar_buf == NULL) {
+		DHD_ERROR(("%s Fail to malloc buffer\n", __FUNCTION__));
+		goto done;
+	}
+
+	/* Alloc req buffer */
+	len = OFFSETOF(wl_pwrstats_query_t, type) +
+		PWRSTATS_REQ_TYPE_NUM * sizeof(uint16);
+	p_query = (wl_pwrstats_query_t *)MALLOCZ(g_dhd_pub->osh, len);
+	if (p_query == NULL) {
+		DHD_ERROR(("%s Fail to malloc buffer\n", __FUNCTION__));
+		goto done;
+	}
+
+	/* Build a list of types */
+	p_query->length = PWRSTATS_REQ_TYPE_NUM;
+	for (i = 0; i < PWRSTATS_REQ_TYPE_NUM; i++) {
+		p_query->type[i] = pwrstats_req_type[i];
+	}
+
+	/* Query with desired type list */
+	err = wldev_iovar_getbuf(ndev, "pwrstats", p_query, len,
+		iovar_buf, PWRSTATS_IOV_BUF_LEN, NULL);
+	if (err != BCME_OK) {
+		DHD_ERROR(("error (%d) - size = %zu\n", err, sizeof(wl_pwrstats_t)));
+		ret = print_pwrstats_cum(buf);
+		goto done;
+	}
+
+	/* Check version */
+	pwrstats = (wl_pwrstats_t *) iovar_buf;
+	if (dtoh16(pwrstats->version) != WL_PWRSTATS_VERSION) {
+		DHD_ERROR(("PWRSTATS Version mismatch\n"));
+		goto done;
+	}
+
+	/* Parse TLVs */
+	len = dtoh16(pwrstats->length) - WL_PWR_STATS_HDRLEN;
+	p_data = pwrstats->data;
+	do {
+		type = dtoh16(((uint16*)p_data)[0]);
+		taglen = dtoh16(((uint16*)p_data)[1]);
+
+		if ((taglen < BCM_XTLV_HDR_SIZE) || (taglen > len)) {
+			DHD_ERROR(("Bad len %d for tag %d, remaining len %d\n",
+					taglen, type, len));
+			goto done;
+		}
+
+		if (taglen & 0xF000) {
+			DHD_ERROR(("Resrved bits in len %d for tag %d, remaining len %d\n",
+					taglen, type, len));
+			goto done;
+		}
+
+		switch (type) {
+		case WL_PWRSTATS_TYPE_PCIE:
+		{
+			wl_pwr_pcie_stats_t *stats =
+				(wl_pwr_pcie_stats_t *)p_data;
+
+			if (taglen < sizeof(wl_pwr_pcie_stats_t)) {
+				DHD_ERROR(("Short len for %d: %d < %d\n",
+					type, taglen, (int)sizeof(wl_pwr_pcie_stats_t)));
+				goto done;
+			}
+
+			if (dtoh32(stats->pcie.l0_cnt) == 0) {
+				DHD_ERROR(("link stats are not supported for this pcie core\n"));
+			}
+
+			pwrstats_sysfs.l0_cnt = dtoh32(stats->pcie.l0_cnt);
+			pwrstats_sysfs.l0_dur_us = dtoh32(stats->pcie.l0_usecs);
+			pwrstats_sysfs.l1_cnt = dtoh32(stats->pcie.l1_cnt);
+			pwrstats_sysfs.l1_dur_us = dtoh32(stats->pcie.l1_usecs);
+			pwrstats_sysfs.l1_1_cnt = dtoh32(stats->pcie.l1_1_cnt);
+			pwrstats_sysfs.l1_1_dur_us = dtoh32(stats->pcie.l1_1_usecs);
+			pwrstats_sysfs.l1_2_cnt = dtoh32(stats->pcie.l1_2_cnt);
+			pwrstats_sysfs.l1_2_dur_us = dtoh32(stats->pcie.l1_2_usecs);
+			pwrstats_sysfs.l2_cnt = dtoh32(stats->pcie.l2_cnt);
+			pwrstats_sysfs.l2_dur_us = dtoh32(stats->pcie.l2_usecs);
+		}
+		break;
+
+		case WL_PWRSTATS_TYPE_PM_ACCUMUL:
+		{
+			wl_pwr_pm_accum_stats_v1_t *stats =
+				(wl_pwr_pm_accum_stats_v1_t *)p_data;
+
+			if (taglen < sizeof(wl_pwr_pm_accum_stats_v1_t)) {
+				DHD_ERROR(("Short len for %d: %d < %d\n", type,
+					taglen, (int)sizeof(wl_pwr_pm_accum_stats_v1_t)));
+				goto done;
+			}
+
+			pwrstats_sysfs.current_ts =
+				dtoh64(stats->accum_data.current_ts);
+			pwrstats_sysfs.pm_cnt =
+				dtoh64(stats->accum_data.pm_cnt);
+			pwrstats_sysfs.pm_dur =
+				dtoh64(stats->accum_data.pm_dur);
+			pwrstats_sysfs.pm_last_entry_us =
+				dtoh64(stats->accum_data.pm_last_entry_us);
+			pwrstats_sysfs.awake_cnt =
+				dtoh64(stats->accum_data.awake_cnt);
+			pwrstats_sysfs.awake_dur =
+				dtoh64(stats->accum_data.awake_dur);
+			pwrstats_sysfs.awake_last_entry_us =
+				dtoh64(stats->accum_data.awake_last_entry_us);
+		}
+		break;
+
+		default:
+			DHD_ERROR(("Skipping uknown %d-byte tag %d\n", taglen, type));
+			break;
+		}
+
+		/* Adjust length to account for padding, but don't exceed total len */
+		taglen = (ROUNDUP(taglen, 4) > len) ? len : ROUNDUP(taglen, 4);
+		len -= taglen;
+		*(uint8**)&p_data += taglen;
+	} while (len >= BCM_XTLV_HDR_SIZE);
+
+	/* [awake|pm]_last_entry_us are provided based on host timestamp.
+	 * These are calculated by dongle timestamp + (delta time of host & dongle)
+	 * If the newly calculated delta time is more than 1 second gap from
+	 * the existing delta time, it is updated to compensate more accurately.
+	 */
+	OSL_GET_LOCALTIME(&ts_sec, &ts_usec);
+	time_delta = ts_sec * USEC_PER_SEC + ts_usec - pwrstats_sysfs.current_ts;
+	if ((time_delta > last_delta) &&
+			((time_delta - last_delta) > USEC_PER_SEC)) {
+		last_delta = time_delta;
+	}
+
+	update_pwrstats_cum(&accumstats.awake_cnt, &laststats.awake_cnt,
+			&pwrstats_sysfs.awake_cnt, TRUE);
+	update_pwrstats_cum(&accumstats.awake_dur, &laststats.awake_dur,
+			&pwrstats_sysfs.awake_dur, FALSE);
+	update_pwrstats_cum(&accumstats.pm_cnt, &laststats.pm_cnt, &pwrstats_sysfs.pm_cnt,
+			TRUE);
+	update_pwrstats_cum(&accumstats.pm_dur, &laststats.pm_dur, &pwrstats_sysfs.pm_dur,
+			FALSE);
+	update_pwrstats_cum(NULL, &laststats.awake_last_entry_us,
+			&pwrstats_sysfs.awake_last_entry_us, FALSE);
+	update_pwrstats_cum(NULL, &laststats.pm_last_entry_us,
+			&pwrstats_sysfs.pm_last_entry_us, FALSE);
+
+	update_pwrstats_cum(&accumstats.l0_cnt, &laststats.l0_cnt, &pwrstats_sysfs.l0_cnt,
+			TRUE);
+	update_pwrstats_cum(&accumstats.l0_dur_us, &laststats.l0_dur_us,
+			&pwrstats_sysfs.l0_dur_us, TRUE);
+	update_pwrstats_cum(&accumstats.l1_cnt, &laststats.l1_cnt, &pwrstats_sysfs.l1_cnt,
+			TRUE);
+	update_pwrstats_cum(&accumstats.l1_dur_us, &laststats.l1_dur_us,
+			&pwrstats_sysfs.l1_dur_us, TRUE);
+	update_pwrstats_cum(&accumstats.l1_1_cnt, &laststats.l1_1_cnt,
+			&pwrstats_sysfs.l1_1_cnt, TRUE);
+	update_pwrstats_cum(&accumstats.l1_1_dur_us, &laststats.l1_1_dur_us,
+			&pwrstats_sysfs.l1_1_dur_us, TRUE);
+	update_pwrstats_cum(&accumstats.l1_2_cnt, &laststats.l1_2_cnt,
+			&pwrstats_sysfs.l1_2_cnt, TRUE);
+	update_pwrstats_cum(&accumstats.l1_2_dur_us, &laststats.l1_2_dur_us,
+			&pwrstats_sysfs.l1_2_dur_us, TRUE);
+	update_pwrstats_cum(&accumstats.l2_cnt, &laststats.l2_cnt, &pwrstats_sysfs.l2_cnt,
+			TRUE);
+	update_pwrstats_cum(&accumstats.l2_dur_us, &laststats.l2_dur_us,
+			&pwrstats_sysfs.l2_dur_us, TRUE);
+
+	ret = print_pwrstats_cum(buf);
+done:
+	if (p_query) {
+		MFREE(g_dhd_pub->osh, p_query, len);
+	}
+	if (iovar_buf) {
+		MFREE(g_dhd_pub->osh, iovar_buf, PWRSTATS_IOV_BUF_LEN);
+	}
+
+	return ret;
+}
+#endif /* PWRSTATS_SYSFS */
+
+static ssize_t
+show_tcm_test_mode(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+	unsigned long mode;
+
+	mode = dhd_tcm_test_mode;
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%lu \n",
+		mode);
+	return ret;
+}
+
+static ssize_t
+set_tcm_test_mode(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long mode;
+
+	mode = bcm_strtoul(buf, NULL, 10);
+
+	sscanf(buf, "%lu", &mode);
+	if (mode > TCM_TEST_MODE_ALWAYS) {
+		return -EINVAL;
+	}
+
+	/* reset with the mode change */
+	if (dhd_tcm_test_mode != mode) {
+		dhd_tcm_test_status = TCM_TEST_NOT_RUN;
+	}
+
+	dhd_tcm_test_mode = (uint)mode;
+
+	return count;
+}
+
+/*
+ * Generic Attribute Structure for DHD.
+ * If we have to add a new sysfs entry under /sys/bcm-dhd/, we have
+ * to instantiate an object of type dhd_attr,  populate it with
+ * the required show/store functions (ex:- dhd_attr_cpumask_primary)
+ * and add the object to default_attrs[] array, that gets registered
+ * to the kobject of dhd (named bcm-dhd).
+ */
+
+struct dhd_attr {
+	struct attribute attr;
+	ssize_t(*show)(struct dhd_info *, char *);
+	ssize_t(*store)(struct dhd_info *, const char *, size_t count);
+};
+
+#if defined(DHD_TRACE_WAKE_LOCK)
+static struct dhd_attr dhd_attr_wklock =
+	__ATTR(wklock_trace, 0660, show_wklock_trace, wklock_trace_onoff);
+#endif /* defined(DHD_TRACE_WAKE_LOCK */
+
+#ifdef DHD_LOG_DUMP
+static struct dhd_attr dhd_attr_logdump_periodic_flush =
+     __ATTR(logdump_periodic_flush, 0660, show_logdump_periodic_flush,
+		logdump_periodic_flush_onoff);
+static struct dhd_attr dhd_attr_logdump_ecntr =
+	__ATTR(logdump_ecntr_enable, 0660, show_logdump_ecntr,
+		logdump_ecntr_onoff);
+#endif /* DHD_LOG_DUMP */
+
+static struct dhd_attr dhd_attr_ecounters =
+	__ATTR(ecounters, 0660, show_enable_ecounter, ecounter_onoff);
+
+#ifdef DHD_SSSR_DUMP
+static struct dhd_attr dhd_attr_sssr_enab =
+	__ATTR(sssr_enab, 0660, show_sssr_enab, set_sssr_enab);
+static struct dhd_attr dhd_attr_fis_enab =
+	__ATTR(fis_enab, 0660, show_fis_enab, set_fis_enab);
+#endif /* DHD_SSSR_DUMP */
+
+static struct dhd_attr dhd_attr_firmware_path =
+	__ATTR(firmware_path, 0660, show_firmware_path, store_firmware_path);
+
+static struct dhd_attr dhd_attr_nvram_path =
+	__ATTR(nvram_path, 0660, show_nvram_path, store_nvram_path);
+
+static struct dhd_attr dhd_attr_sig_path =
+	__ATTR(signature_path, 0660, show_signature_path, store_signature_path);
+
+#ifdef PWRSTATS_SYSFS
+static struct dhd_attr dhd_attr_pwrstats_path =
+	__ATTR(power_stats, 0664, show_pwrstats_path, NULL);
+#endif /* PWRSTATS_SYSFS */
+
+static struct dhd_attr dhd_attr_tcm_test_mode =
+	__ATTR(tcm_test_mode, 0660, show_tcm_test_mode, set_tcm_test_mode);
+
+#define to_dhd(k) container_of(k, struct dhd_info, dhd_kobj)
+#define to_attr(a) container_of(a, struct dhd_attr, attr)
+
+#if defined(DHD_MAC_ADDR_EXPORT) || defined(DHD_MAC_ADDR_EXPORT_RO)
+struct ether_addr sysfs_mac_addr;
+static ssize_t
+show_mac_addr(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, MACF,
+		(uint32)sysfs_mac_addr.octet[0], (uint32)sysfs_mac_addr.octet[1],
+		(uint32)sysfs_mac_addr.octet[2], (uint32)sysfs_mac_addr.octet[3],
+		(uint32)sysfs_mac_addr.octet[4], (uint32)sysfs_mac_addr.octet[5]);
+
+	return ret;
+}
+
+static ssize_t
+set_mac_addr(struct dhd_info *dev, const char *buf, size_t count)
+{
+	if (!bcm_ether_atoe(buf, &sysfs_mac_addr)) {
+		DHD_ERROR(("Invalid Mac Address \n"));
+		return -EINVAL;
+	}
+
+	DHD_ERROR(("Mac Address set with "MACDBG"\n", MAC2STRDBG(&sysfs_mac_addr)));
+
+	return count;
+}
+
+static struct dhd_attr dhd_attr_macaddr =
+	__ATTR(mac_addr, 0660, show_mac_addr, set_mac_addr);
+#endif /* DHD_MAC_ADDR_EXPORT || DHD_MAC_ADDR_EXPORT_RO */
+
+#ifdef DHD_FW_COREDUMP
+/*
+ * XXX The filename to store memdump is defined for each platform.
+ * - The default path of CUSTOMER_HW4 device is "PLATFORM_PATH/.memdump.info"
+ * - Brix platform will take default path "/installmedia/.memdump.info"
+ * New platforms can add their ifdefs accordingly below.
+ */
+
+#ifdef CONFIG_X86
+#if defined(OEM_ANDROID)
+#define MEMDUMPINFO_LIVE PLATFORM_PATH".memdump.info"
+#define MEMDUMPINFO_INST "/data/.memdump.info"
+#define MEMDUMPINFO MEMDUMPINFO_LIVE
+#else /* FC19 and Others */
+#define MEMDUMPINFO PLATFORM_PATH".memdump.info"
+#endif /* OEM_ANDROID */
+#else /* For non x86 platforms */
+#define MEMDUMPINFO PLATFORM_PATH".memdump.info"
+#endif /* CONFIG_X86 */
+
+uint32
+get_mem_val_from_file(void)
+{
+	struct file *fp = NULL;
+	uint32 mem_val = DUMP_MEMFILE_MAX;
+	char *p_mem_val = NULL;
+	char *filepath = MEMDUMPINFO;
+	int ret = 0;
+
+	/* Read memdump info from the file */
+	fp = dhd_filp_open(filepath, O_RDONLY, 0);
+	if (IS_ERR(fp) || (fp == NULL)) {
+		DHD_ERROR(("%s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
+#if defined(CONFIG_X86) && defined(OEM_ANDROID)
+		/* Check if it is Live Brix Image */
+		if (strcmp(filepath, MEMDUMPINFO_LIVE) != 0) {
+			goto done;
+		}
+		/* Try if it is Installed Brix Image */
+		filepath = MEMDUMPINFO_INST;
+		DHD_ERROR(("%s: Try File [%s]\n", __FUNCTION__, filepath));
+		fp = dhd_filp_open(filepath, O_RDONLY, 0);
+		if (IS_ERR(fp) || (fp == NULL)) {
+			DHD_ERROR(("%s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
+			goto done;
+		}
+#else /* Non Brix Android platform */
+		goto done;
+#endif /* CONFIG_X86 && OEM_ANDROID */
+	}
+
+	/* Handle success case */
+	ret = dhd_kernel_read_compat(fp, 0, (char *)&mem_val, sizeof(uint32));
+	if (ret < 0) {
+		DHD_ERROR(("%s: File read error, ret=%d\n", __FUNCTION__, ret));
+		dhd_filp_close(fp, NULL);
+		goto done;
+	}
+
+	p_mem_val = (char*)&mem_val;
+	p_mem_val[sizeof(uint32) - 1] = '\0';
+	mem_val = bcm_atoi(p_mem_val);
+
+	dhd_filp_close(fp, NULL);
+
+done:
+	return mem_val;
+}
+
+void dhd_get_memdump_info(dhd_pub_t *dhd)
+{
+#ifndef DHD_EXPORT_CNTL_FILE
+	uint32 mem_val = DUMP_MEMFILE_MAX;
+
+	mem_val = get_mem_val_from_file();
+	if (mem_val != DUMP_MEMFILE_MAX)
+		dhd->memdump_enabled = mem_val;
+#ifdef DHD_INIT_DEFAULT_MEMDUMP
+	if (mem_val == 0 || mem_val == DUMP_MEMFILE_MAX)
+		mem_val = DUMP_MEMFILE_BUGON;
+#endif /* DHD_INIT_DEFAULT_MEMDUMP */
+#else
+#ifdef DHD_INIT_DEFAULT_MEMDUMP
+	if (dhd->memdump_enabled == 0 || dhd->memdump_enabled == DUMP_MEMFILE_MAX)
+		dhd->memdump_enabled = DUMP_MEMFILE;
+#endif /* DHD_INIT_DEFAULT_MEMDUMP */
+#endif /* !DHD_EXPORT_CNTL_FILE */
+#ifdef BCMQT
+	/* In QT environment collecting memdump on FW TRAP, IOVAR timeouts,
+	 * is taking more time and makes system unresponsive so disabling it.
+	 * if needed memdump can be collected through 'dhd upload' command.
+	*/
+	dhd->memdump_enabled = DUMP_DISABLED;
+#endif
+#ifdef DHD_DETECT_CONSECUTIVE_MFG_HANG
+	/* override memdump_enabled value to avoid once trap issues */
+	if (dhd_bus_get_fw_mode(dhd) == DHD_FLAG_MFG_MODE &&
+			(dhd->memdump_enabled == DUMP_MEMONLY ||
+			dhd->memdump_enabled == DUMP_MEMFILE_BUGON)) {
+		dhd->memdump_enabled = DUMP_MEMFILE;
+		DHD_ERROR(("%s : Override memdump_value to %d\n",
+				__FUNCTION__, dhd->memdump_enabled));
+	}
+#endif /* DHD_DETECT_CONSECUTIVE_MFG_HANG */
+	DHD_ERROR(("%s: MEMDUMP ENABLED = %u\n", __FUNCTION__, dhd->memdump_enabled));
+}
+
+static ssize_t
+show_memdump_info(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+	dhd_pub_t *dhdp;
+
+	if (!dev) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return ret;
+	}
+
+	dhdp = &dev->pub;
+	ret = scnprintf(buf, PAGE_SIZE -1, "%u\n", dhdp->memdump_enabled);
+	return ret;
+}
+
+static ssize_t
+set_memdump_info(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long memval;
+	dhd_pub_t *dhdp;
+
+	if (!dev) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return count;
+	}
+	dhdp = &dev->pub;
+
+	memval = bcm_strtoul(buf, NULL, 10);
+	sscanf(buf, "%lu", &memval);
+
+	dhdp->memdump_enabled = (uint32)memval;
+
+	DHD_ERROR(("%s: MEMDUMP ENABLED = %u\n", __FUNCTION__, dhdp->memdump_enabled));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_memdump =
+	__ATTR(memdump, 0660, show_memdump_info, set_memdump_info);
+#endif /* DHD_FW_COREDUMP */
+
+#ifdef BCMASSERT_LOG
+/*
+ * XXX The filename to store assert type is defined for each platform.
+ * New platforms can add their ifdefs accordingly below.
+ */
+#define ASSERTINFO PLATFORM_PATH".assert.info"
+
+int
+get_assert_val_from_file(void)
+{
+	struct file *fp = NULL;
+	char *filepath = ASSERTINFO;
+	char *p_mem_val = NULL;
+	int mem_val = -1;
+
+	/*
+	 * Read assert info from the file
+	 * 0: Trigger Kernel crash by panic()
+	 * 1: Print out the logs and don't trigger Kernel panic. (default)
+	 * 2: Trigger Kernel crash by BUG()
+	 * File doesn't exist: Keep default value (1).
+	 */
+	fp = dhd_filp_open(filepath, O_RDONLY, 0);
+	if (IS_ERR(fp) || (fp == NULL)) {
+		DHD_ERROR(("%s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
+	} else {
+		int ret = dhd_kernel_read_compat(fp, 0, (char *)&mem_val, sizeof(uint32));
+		if (ret < 0) {
+			DHD_ERROR(("%s: File read error, ret=%d\n", __FUNCTION__, ret));
+		} else {
+			p_mem_val = (char *)&mem_val;
+			p_mem_val[sizeof(uint32) - 1] = '\0';
+			mem_val = bcm_atoi(p_mem_val);
+			DHD_ERROR(("%s: ASSERT ENABLED = %d\n", __FUNCTION__, mem_val));
+		}
+		dhd_filp_close(fp, NULL);
+	}
+
+	mem_val = (mem_val >= 0) ? mem_val : 0;
+	return mem_val;
+}
+
+void dhd_get_assert_info(dhd_pub_t *dhd)
+{
+#ifndef DHD_EXPORT_CNTL_FILE
+	int mem_val = -1;
+
+	mem_val = get_assert_val_from_file();
+
+	g_assert_type = mem_val;
+#endif /* !DHD_EXPORT_CNTL_FILE */
+}
+
+#ifdef DHD_EXPORT_CNTL_FILE
+static ssize_t
+show_assert_info(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	if (!dev) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return ret;
+	}
+
+	ret = scnprintf(buf, PAGE_SIZE -1, "%d\n", g_assert_type);
+	return ret;
+
+}
+
+static ssize_t
+set_assert_info(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long assert_val;
+
+	assert_val = bcm_strtoul(buf, NULL, 10);
+	sscanf(buf, "%lu", &assert_val);
+
+	g_assert_type = (uint32)assert_val;
+
+	DHD_ERROR(("%s: ASSERT ENABLED = %lu\n", __FUNCTION__, assert_val));
+	return count;
+
+}
+
+static struct dhd_attr dhd_attr_assert =
+	__ATTR(assert, 0660, show_assert_info, set_assert_info);
+#endif /* DHD_EXPORT_CNTL_FILE */
+#endif /* BCMASSERT_LOG */
+
+#ifdef DHD_EXPORT_CNTL_FILE
+#if defined(WRITE_WLANINFO)
+static ssize_t
+show_wifiver_info(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE -1, "%s", version_info);
+	return ret;
+}
+
+static ssize_t
+set_wifiver_info(struct dhd_info *dev, const char *buf, size_t count)
+{
+	DHD_ERROR(("Do not set version info\n"));
+	return -EINVAL;
+}
+
+static struct dhd_attr dhd_attr_wifiver =
+	__ATTR(wifiver, 0660, show_wifiver_info, set_wifiver_info);
+#endif /* WRITE_WLANINFO */
+
+#if defined(USE_CID_CHECK) || defined(USE_DIRECT_VID_TAG)
+char cidinfostr[MAX_VNAME_LEN];
+
+static ssize_t
+show_cid_info(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+#ifdef USE_DIRECT_VID_TAG
+	ret = scnprintf(buf, PAGE_SIZE -1, "%x%x", cidinfostr[VENDOR_OFF], cidinfostr[MD_REV_OFF]);
+#endif /* USE_DIRECT_VID_TAG */
+#ifdef USE_CID_CHECK
+	ret = scnprintf(buf, PAGE_SIZE -1, "%s", cidinfostr);
+#endif /* USE_CID_CHECK */
+	return ret;
+}
+
+static ssize_t
+set_cid_info(struct dhd_info *dev, const char *buf, size_t count)
+{
+#ifdef USE_DIRECT_VID_TAG
+	uint32 stored_vid = 0, md_rev = 0, vendor = 0;
+	uint32 vendor_mask = 0x00FF;
+
+	stored_vid = bcm_strtoul(buf, NULL, 16);
+
+	DHD_ERROR(("%s : stored_vid : 0x%x\n", __FUNCTION__, stored_vid));
+	md_rev = stored_vid & vendor_mask;
+	vendor = stored_vid >> 8;
+
+	memset(cidinfostr, 0, sizeof(cidinfostr));
+
+	cidinfostr[MD_REV_OFF] = (char)md_rev;
+	cidinfostr[VENDOR_OFF] = (char)vendor;
+	DHD_INFO(("CID string %x%x\n", cidinfostr[VENDOR_OFF], cidinfostr[MD_REV_OFF]));
+#endif /* USE_DIRECT_VID_TAG */
+#ifdef USE_CID_CHECK
+	int len = strlen(buf) + 1;
+	int maxstrsz;
+	maxstrsz = MAX_VNAME_LEN;
+
+	scnprintf(cidinfostr, ((len > maxstrsz) ? maxstrsz : len), "%s", buf);
+	DHD_INFO(("%s : CID info string\n", cidinfostr));
+#endif /* USE_CID_CHECK */
+	return count;
+}
+
+static struct dhd_attr dhd_attr_cidinfo =
+	__ATTR(cid, 0660, show_cid_info, set_cid_info);
+#endif /* USE_CID_CHECK || USE_DIRECT_VID_TAG */
+
+#if defined(GEN_SOFTAP_INFO_FILE)
+char softapinfostr[SOFTAP_INFO_BUF_SZ];
+static ssize_t
+show_softap_info(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE -1, "%s", softapinfostr);
+	return ret;
+}
+
+static ssize_t
+set_softap_info(struct dhd_info *dev, const char *buf, size_t count)
+{
+	DHD_ERROR(("Do not set sofap related info\n"));
+	return -EINVAL;
+}
+
+static struct dhd_attr dhd_attr_softapinfo =
+	__ATTR(softap, 0660, show_softap_info, set_softap_info);
+#endif /* GEN_SOFTAP_INFO_FILE */
+
+#if defined(MIMO_ANT_SETTING)
+unsigned long antsel;
+
+static ssize_t
+show_ant_info(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE -1, "%lu\n", antsel);
+	return ret;
+}
+
+static ssize_t
+set_ant_info(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long ant_val;
+
+	ant_val = bcm_strtoul(buf, NULL, 10);
+	sscanf(buf, "%lu", &ant_val);
+
+	/*
+	 * Check value
+	 * 0 - Not set, handle same as file not exist
+	 */
+	if (ant_val > 3) {
+		DHD_ERROR(("[WIFI_SEC] %s: Set Invalid value %lu \n",
+			__FUNCTION__, ant_val));
+		return -EINVAL;
+	}
+
+	antsel = ant_val;
+	DHD_ERROR(("[WIFI_SEC] %s: Set Antinfo val = %lu \n", __FUNCTION__, antsel));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_antinfo =
+	__ATTR(ant, 0660, show_ant_info, set_ant_info);
+#endif /* MIMO_ANT_SETTING */
+
+#ifdef DHD_PM_CONTROL_FROM_FILE
+extern uint32 pmmode_val;
+static ssize_t
+show_pm_info(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	if (pmmode_val == 0xFF) {
+		ret = scnprintf(buf, PAGE_SIZE -1, "PM mode is not set\n");
+	} else {
+		ret = scnprintf(buf, PAGE_SIZE -1, "%u\n", pmmode_val);
+	}
+	return ret;
+}
+
+static ssize_t
+set_pm_info(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long pm_val;
+
+	pm_val = bcm_strtoul(buf, NULL, 10);
+	sscanf(buf, "%lu", &pm_val);
+
+	if (pm_val > 2) {
+		DHD_ERROR(("[WIFI_SEC] %s: Set Invalid value %lu \n",
+			__FUNCTION__, pm_val));
+		return -EINVAL;
+	}
+
+	pmmode_val = (uint32)pm_val;
+	DHD_ERROR(("[WIFI_SEC] %s: Set pminfo val = %u\n", __FUNCTION__, pmmode_val));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_pminfo =
+	__ATTR(pm, 0660, show_pm_info, set_pm_info);
+#endif /* DHD_PM_CONTROL_FROM_FILE */
+
+#ifdef LOGTRACE_FROM_FILE
+unsigned long logtrace_val = 1;
+
+static ssize_t
+show_logtrace_info(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE -1, "%lu\n", logtrace_val);
+	return ret;
+}
+
+static ssize_t
+set_logtrace_info(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long onoff;
+
+	onoff = bcm_strtoul(buf, NULL, 10);
+	sscanf(buf, "%lu", &onoff);
+
+	if (onoff > 2) {
+		DHD_ERROR(("[WIFI_SEC] %s: Set Invalid value %lu \n",
+			__FUNCTION__, onoff));
+		return -EINVAL;
+	}
+
+	logtrace_val = onoff;
+	DHD_ERROR(("[WIFI_SEC] %s: LOGTRACE On/Off from sysfs = %lu\n",
+		__FUNCTION__, logtrace_val));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_logtraceinfo =
+	__ATTR(logtrace, 0660, show_logtrace_info, set_logtrace_info);
+#endif /* LOGTRACE_FROM_FILE */
+
+#ifdef  USE_WFA_CERT_CONF
+#ifdef BCMSDIO
+uint32 bus_txglom = VALUENOTSET;
+
+static ssize_t
+show_bustxglom(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	if (bus_txglom == VALUENOTSET) {
+		ret = scnprintf(buf, PAGE_SIZE - 1, "%s\n", "bustxglom not set from sysfs");
+	} else {
+		ret = scnprintf(buf, PAGE_SIZE -1, "%u\n", bus_txglom);
+	}
+	return ret;
+}
+
+static ssize_t
+set_bustxglom(struct dhd_info *dev, const char *buf, size_t count)
+{
+	uint32 onoff;
+
+	onoff = (uint32)bcm_atoi(buf);
+	sscanf(buf, "%u", &onoff);
+
+	if (onoff > 2) {
+		DHD_ERROR(("[WIFI_SEC] %s: Set Invalid value %u \n",
+			__FUNCTION__, onoff));
+		return -EINVAL;
+	}
+
+	bus_txglom = onoff;
+	DHD_ERROR(("[WIFI_SEC] %s: BUS TXGLOM On/Off from sysfs = %u\n",
+			__FUNCTION__, bus_txglom));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_bustxglom =
+	__ATTR(bustxglom, 0660, show_bustxglom, set_bustxglom);
+#endif /* BCMSDIO */
+
+#if defined(ROAM_ENABLE) || defined(DISABLE_BUILTIN_ROAM)
+uint32 roam_off = VALUENOTSET;
+
+static ssize_t
+show_roamoff(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	if (roam_off == VALUENOTSET) {
+		ret = scnprintf(buf, PAGE_SIZE -1, "%s\n", "roam_off not set from sysfs");
+	} else {
+		ret = scnprintf(buf, PAGE_SIZE -1, "%u\n", roam_off);
+	}
+	return ret;
+}
+
+static ssize_t
+set_roamoff(struct dhd_info *dev, const char *buf, size_t count)
+{
+	uint32 onoff;
+
+	onoff = bcm_atoi(buf);
+	sscanf(buf, "%u", &onoff);
+
+	if (onoff > 2) {
+		DHD_ERROR(("[WIFI_SEC] %s: Set Invalid value %u \n",
+			__FUNCTION__, onoff));
+		return -EINVAL;
+	}
+
+	roam_off = onoff;
+	DHD_ERROR(("[WIFI_SEC] %s: ROAM On/Off from sysfs = %u\n",
+		__FUNCTION__, roam_off));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_roamoff =
+	__ATTR(roamoff, 0660, show_roamoff, set_roamoff);
+#endif /* ROAM_ENABLE || DISABLE_BUILTIN_ROAM */
+
+#ifdef USE_WL_FRAMEBURST
+uint32 frameburst = VALUENOTSET;
+
+static ssize_t
+show_frameburst(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	if (frameburst == VALUENOTSET) {
+		ret = scnprintf(buf, PAGE_SIZE -1, "%s\n", "frameburst not set from sysfs");
+	} else {
+		ret = scnprintf(buf, PAGE_SIZE -1, "%u\n", frameburst);
+	}
+	return ret;
+}
+
+static ssize_t
+set_frameburst(struct dhd_info *dev, const char *buf, size_t count)
+{
+	uint32 onoff;
+
+	onoff = bcm_atoi(buf);
+	sscanf(buf, "%u", &onoff);
+
+	if (onoff > 2) {
+		DHD_ERROR(("[WIFI_SEC] %s: Set Invalid value %u \n",
+			__FUNCTION__, onoff));
+		return -EINVAL;
+	}
+
+	frameburst = onoff;
+	DHD_ERROR(("[WIFI_SEC] %s: FRAMEBURST On/Off from sysfs = %u\n",
+		__FUNCTION__, frameburst));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_frameburst =
+	__ATTR(frameburst, 0660, show_frameburst, set_frameburst);
+#endif /* USE_WL_FRAMEBURST */
+
+#ifdef USE_WL_TXBF
+uint32 txbf = VALUENOTSET;
+
+static ssize_t
+show_txbf(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	if (txbf == VALUENOTSET) {
+		ret = scnprintf(buf, PAGE_SIZE -1, "%s\n", "txbf not set from sysfs");
+	} else {
+		ret = scnprintf(buf, PAGE_SIZE -1, "%u\n", txbf);
+	}
+	return ret;
+}
+
+static ssize_t
+set_txbf(struct dhd_info *dev, const char *buf, size_t count)
+{
+	uint32 onoff;
+
+	onoff = bcm_atoi(buf);
+	sscanf(buf, "%u", &onoff);
+
+	if (onoff > 2) {
+		DHD_ERROR(("[WIFI_SEC] %s: Set Invalid value %u \n",
+			__FUNCTION__, onoff));
+		return -EINVAL;
+	}
+
+	txbf = onoff;
+	DHD_ERROR(("[WIFI_SEC] %s: FRAMEBURST On/Off from sysfs = %u\n",
+		__FUNCTION__, txbf));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_txbf =
+	__ATTR(txbf, 0660, show_txbf, set_txbf);
+#endif /* USE_WL_TXBF */
+
+#ifdef PROP_TXSTATUS
+uint32 proptx = VALUENOTSET;
+
+static ssize_t
+show_proptx(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	if (proptx == VALUENOTSET) {
+		ret = scnprintf(buf, PAGE_SIZE -1, "%s\n", "proptx not set from sysfs");
+	} else {
+		ret = scnprintf(buf, PAGE_SIZE -1, "%u\n", proptx);
+	}
+	return ret;
+}
+
+static ssize_t
+set_proptx(struct dhd_info *dev, const char *buf, size_t count)
+{
+	uint32 onoff;
+
+	onoff = bcm_strtoul(buf, NULL, 10);
+	sscanf(buf, "%u", &onoff);
+
+	if (onoff > 2) {
+		DHD_ERROR(("[WIFI_SEC] %s: Set Invalid value %u \n",
+			__FUNCTION__, onoff));
+		return -EINVAL;
+	}
+
+	proptx = onoff;
+	DHD_ERROR(("[WIFI_SEC] %s: FRAMEBURST On/Off from sysfs = %u\n",
+		__FUNCTION__, txbf));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_proptx =
+	__ATTR(proptx, 0660, show_proptx, set_proptx);
+
+#endif /* PROP_TXSTATUS */
+#endif /* USE_WFA_CERT_CONF */
+#endif /* DHD_EXPORT_CNTL_FILE */
+
+#if defined(WL_BAM)
+#define BAD_AP_MAC_ADDR_ELEMENT_NUM	6
+#define MACF_READ	"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
+wl_bad_ap_mngr_t *g_bad_ap_mngr = NULL;
+
+static ssize_t
+show_adps_bam_list(struct dhd_info *dev, char *buf)
+{
+	int offset = 0;
+	ssize_t ret = 0;
+
+	wl_bad_ap_info_t *bad_ap;
+	wl_bad_ap_info_entry_t *entry;
+
+	if (g_bad_ap_mngr == NULL)
+		return ret;
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	list_for_each_entry(entry, &g_bad_ap_mngr->list, list) {
+		bad_ap = &entry->bad_ap;
+
+		ret = scnprintf(buf + offset, PAGE_SIZE - 1, MACF"\n",
+			bad_ap->bssid.octet[0], bad_ap->bssid.octet[1],
+			bad_ap->bssid.octet[2], bad_ap->bssid.octet[3],
+			bad_ap->bssid.octet[4], bad_ap->bssid.octet[5]);
+
+		offset += ret;
+	}
+	GCC_DIAGNOSTIC_POP();
+
+	return offset;
+}
+
+static ssize_t
+store_adps_bam_list(struct dhd_info *dev, const char *buf, size_t count)
+{
+	int ret;
+	size_t len;
+	int offset;
+	char tmp[128];
+	wl_bad_ap_info_t bad_ap;
+
+	if (g_bad_ap_mngr == NULL)
+		return count;
+
+	len = count;
+	offset = 0;
+	do {
+		ret = sscanf(buf + offset, MACF_READ"\n",
+			&bad_ap.bssid.octet[0], &bad_ap.bssid.octet[1],
+			&bad_ap.bssid.octet[2], &bad_ap.bssid.octet[3],
+			&bad_ap.bssid.octet[4], &bad_ap.bssid.octet[5]);
+		if (ret != BAD_AP_MAC_ADDR_ELEMENT_NUM) {
+			DHD_ERROR(("%s - fail to parse bad ap data\n", __FUNCTION__));
+			return -EINVAL;
+		}
+
+		ret = wl_bad_ap_mngr_add(g_bad_ap_mngr, &bad_ap);
+		if (ret < 0)
+			return ret;
+
+		ret = snprintf(tmp, ARRAYSIZE(tmp), MACF"\n",
+			bad_ap.bssid.octet[0], bad_ap.bssid.octet[1],
+			bad_ap.bssid.octet[2], bad_ap.bssid.octet[3],
+			bad_ap.bssid.octet[4], bad_ap.bssid.octet[5]);
+		if (ret < 0) {
+			DHD_ERROR(("%s - fail to get bad ap data length(%d)\n", __FUNCTION__, ret));
+			return ret;
+		}
+
+		len -= ret;
+		offset += ret;
+	} while (len > 0);
+
+	return count;
+}
+
+static struct dhd_attr dhd_attr_adps_bam =
+	__ATTR(bad_ap_list, 0660, show_adps_bam_list, store_adps_bam_list);
+#endif	/* WL_BAM */
+
+uint32 report_hang_privcmd_err = 1;
+
+#ifdef DHD_SEND_HANG_PRIVCMD_ERRORS
+static ssize_t
+show_hang_privcmd_err(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%u\n", report_hang_privcmd_err);
+	return ret;
+}
+
+static ssize_t
+set_hang_privcmd_err(struct dhd_info *dev, const char *buf, size_t count)
+{
+	uint32 val;
+
+	val = bcm_atoi(buf);
+	sscanf(buf, "%u", &val);
+
+	report_hang_privcmd_err = val ? 1 : 0;
+	DHD_INFO(("%s: Set report HANG for private cmd error: %d\n",
+		__FUNCTION__, report_hang_privcmd_err));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_hang_privcmd_err =
+	__ATTR(hang_privcmd_err, 0660, show_hang_privcmd_err, set_hang_privcmd_err);
+#endif /* DHD_SEND_HANG_PRIVCMD_ERRORS */
+
+#if defined(SHOW_LOGTRACE)
+static ssize_t
+show_control_logtrace(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n", control_logtrace);
+	return ret;
+}
+
+static ssize_t
+set_control_logtrace(struct dhd_info *dev, const char *buf, size_t count)
+{
+	uint32 val;
+
+	val = bcm_atoi(buf);
+
+	control_logtrace = val;
+	DHD_ERROR(("%s: Set control logtrace: %d\n", __FUNCTION__, control_logtrace));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_control_logtrace =
+__ATTR(control_logtrace, 0660, show_control_logtrace, set_control_logtrace);
+#endif /* SHOW_LOGTRACE */
+
+#if defined(DISABLE_HE_ENAB) || defined(CUSTOM_CONTROL_HE_ENAB)
+uint8 control_he_enab = 1;
+#endif /* DISABLE_HE_ENAB || CUSTOM_CONTROL_HE_ENAB */
+
+#ifdef RX_PKT_POOL
+static ssize_t
+show_max_rx_pkt_pool(struct dhd_info *dhd, char *buf)
+{
+	ssize_t ret = 0;
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return ret;
+	}
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n", dhd->rx_pkt_pool.max_size);
+	return ret;
+}
+
+static ssize_t
+set_max_rx_pkt_pool(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	uint32 val;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return count;
+	}
+
+	val = bcm_atoi(buf);
+
+	dhd->rx_pkt_pool.max_size = ((val > MAX_RX_PKT_POOL) &&
+		(val <= (MAX_RX_PKT_POOL * 8))) ? val : MAX_RX_PKT_POOL;
+	DHD_ERROR(("%s: MAX_RX_PKT_POOL: %d\n", __FUNCTION__, dhd->rx_pkt_pool.max_size));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_max_rx_pkt_pool=
+__ATTR(dhd_max_rx_pkt_pool, 0660, show_max_rx_pkt_pool, set_max_rx_pkt_pool);
+#endif /* RX_PKT_POOL */
+
+#ifdef PCIE_FULL_DONGLE
+static ssize_t
+dhd_set_aspm_enab(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	unsigned long aspm_enab;
+	dhd_pub_t *dhdp = &dhd->pub;
+
+	aspm_enab = bcm_strtoul(buf, NULL, 10);
+
+	sscanf(buf, "%lu", &aspm_enab);
+	if (aspm_enab != 0 && aspm_enab != 1) {
+		return -EINVAL;
+	}
+	dhd_bus_aspm_enable_rc_ep(dhdp->bus, aspm_enab);
+
+	return count;
+}
+
+static ssize_t
+show_aspm_enab(struct dhd_info *dhd, char *buf)
+{
+	ssize_t ret = 0;
+	bool aspm_enab;
+	dhd_pub_t *dhdp = &dhd->pub;
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return ret;
+	}
+
+	aspm_enab = dhd_bus_is_aspm_enab_rc_ep(dhdp->bus);
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n", aspm_enab);
+
+	return ret;
+}
+
+static struct dhd_attr dhd_attr_aspm_enab =
+__ATTR(aspm_enab, 0660, show_aspm_enab, dhd_set_aspm_enab);
+
+static ssize_t
+dhd_set_l1ss_enab(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	unsigned long l1ss_enab;
+	dhd_pub_t *dhdp = &dhd->pub;
+
+	l1ss_enab = bcm_strtoul(buf, NULL, 10);
+
+	sscanf(buf, "%lu", &l1ss_enab);
+	if (l1ss_enab != 0 && l1ss_enab != 1) {
+		return -EINVAL;
+	}
+	dhd_bus_l1ss_enable_rc_ep(dhdp->bus, l1ss_enab);
+	return count;
+}
+
+static ssize_t
+show_l1ss_enab(struct dhd_info *dhd, char *buf)
+{
+	ssize_t ret = 0;
+	bool l1ss_enab;
+	dhd_pub_t *dhdp = &dhd->pub;
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return ret;
+	}
+
+	l1ss_enab = dhd_bus_is_l1ss_enab_rc_ep(dhdp->bus);
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n", l1ss_enab);
+
+	return ret;
+}
+
+static struct dhd_attr dhd_attr_l1ss_enab =
+__ATTR(l1ss_enab, 0660, show_l1ss_enab, dhd_set_l1ss_enab);
+#endif /* PCIE_FULL_DONGLE */
+
+#ifdef RPM_FAST_TRIGGER
+static ssize_t
+dhd_show_fast_rpm_thresh(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+	unsigned long val;
+
+	val = dhd_fast_runtimepm_ms;
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%lu \n", val);
+	return ret;
+}
+
+static ssize_t
+dhd_set_fast_rpm_thresh(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long val;
+
+	val = bcm_strtoul(buf, NULL, 10);
+
+	sscanf(buf, "%lu", &val);
+	/* Ensure fast RPM threashold is lesser than regular RPM threshold */
+	if (val == 0 || val >= dhd_runtimepm_ms) {
+		 return -EINVAL;
+	}
+	dhd_fast_runtimepm_ms = val;
+	return count;
+}
+static struct dhd_attr dhd_attr_fast_rpm_thresh =
+__ATTR(fast_rpm_thresh, 0660, dhd_show_fast_rpm_thresh, dhd_set_fast_rpm_thresh);
+#endif /* RPM_FAST_TRIGGER */
+
+#if defined(CUSTOM_CONTROL_HE_ENAB)
+static ssize_t
+show_control_he_enab(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n", control_he_enab);
+	return ret;
+}
+
+static ssize_t
+set_control_he_enab(struct dhd_info *dev, const char *buf, size_t count)
+{
+	uint32 val;
+
+	val = bcm_atoi(buf);
+
+	control_he_enab = val ? 1 : 0;
+	DHD_ERROR(("%s: Set control he enab: %d\n", __FUNCTION__, control_he_enab));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_control_he_enab=
+__ATTR(control_he_enab, 0660, show_control_he_enab, set_control_he_enab);
+#endif /* CUSTOM_CONTROL_HE_ENAB */
+
+#if defined(WLAN_ACCEL_BOOT)
+static ssize_t
+show_wl_accel_force_reg_on(struct dhd_info *dhd, char *buf)
+{
+	ssize_t ret = 0;
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return ret;
+	}
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n", dhd->wl_accel_force_reg_on);
+	return ret;
+}
+
+static ssize_t
+set_wl_accel_force_reg_on(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	uint32 val;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return count;
+	}
+
+	val = bcm_atoi(buf);
+
+	dhd->wl_accel_force_reg_on = val ? 1 : 0;
+	DHD_ERROR(("%s: wl_accel_force_reg_on: %d\n", __FUNCTION__, dhd->wl_accel_force_reg_on));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_wl_accel_force_reg_on=
+__ATTR(wl_accel_force_reg_on, 0660, show_wl_accel_force_reg_on, set_wl_accel_force_reg_on);
+#endif /* WLAN_ACCEL_BOOT */
+
+#if defined(AGG_H2D_DB)
+extern bool agg_h2d_db_enab;
+extern uint32 agg_h2d_db_timeout;
+extern uint32 agg_h2d_db_inflight_thresh;
+
+static ssize_t
+show_agg_h2d_db_enab(struct dhd_info *dhd, char *buf)
+{
+	ssize_t ret = 0;
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return ret;
+	}
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n", agg_h2d_db_enab);
+	return ret;
+}
+
+static ssize_t
+set_agg_h2d_db_enab(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	uint32 val;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return count;
+	}
+
+	val = bcm_atoi(buf);
+
+	agg_h2d_db_enab = val ? TRUE : FALSE;
+	DHD_ERROR(("%s: agg_h2d_db_timeout: %d\n", __FUNCTION__, agg_h2d_db_enab));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_agg_h2d_db_enab =
+__ATTR(agg_h2d_db_enab, 0660, show_agg_h2d_db_enab, set_agg_h2d_db_enab);
+
+static ssize_t
+show_agg_h2d_db_inflight_thresh(struct dhd_info *dhd, char *buf)
+{
+	ssize_t ret = 0;
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return ret;
+	}
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n", agg_h2d_db_inflight_thresh);
+	return ret;
+}
+
+static ssize_t
+set_agg_h2d_db_inflight_thresh(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	uint32 val;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return count;
+	}
+
+	val = bcm_atoi(buf);
+
+	agg_h2d_db_inflight_thresh = val;
+	DHD_ERROR(("%s: agg_h2d_db_timeout: %d\n", __FUNCTION__, agg_h2d_db_inflight_thresh));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_agg_h2d_db_inflight_thresh =
+__ATTR(agg_h2d_db_inflight_thresh, 0660, show_agg_h2d_db_inflight_thresh,
+	set_agg_h2d_db_inflight_thresh);
+
+static ssize_t
+show_agg_h2d_db_timeout(struct dhd_info *dhd, char *buf)
+{
+	ssize_t ret = 0;
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return ret;
+	}
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n", agg_h2d_db_timeout);
+	return ret;
+}
+
+static ssize_t
+set_agg_h2d_db_timeout(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	uint32 val;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return count;
+	}
+
+	val = bcm_atoi(buf);
+
+	agg_h2d_db_timeout = val;
+	DHD_ERROR(("%s: agg_h2d_db_timeout: %d\n", __FUNCTION__, agg_h2d_db_timeout));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_agg_h2d_db_timeout =
+__ATTR(agg_h2d_db_timeout, 0660, show_agg_h2d_db_timeout, set_agg_h2d_db_timeout);
+#endif /* WLAN_ACCEL_BOOT */
+/*
+ * Dumps the lock and other state information useful for debug
+ *
+ */
+static ssize_t
+dhd_debug_dump_stateinfo(struct dhd_info *dhd, char *buf)
+{
+	u32 buf_size = PAGE_SIZE - 1;
+	u8 *ptr = buf;
+	ssize_t len = 0;
+
+	len += scnprintf(ptr, buf_size, "[DHD]\nlock info:\n");
+#ifdef BT_OVER_SDIO
+	len += scnprintf((ptr+len), (buf_size-len), "bus_user_lock:\n",
+			mutex_is_locked(&dhd->bus_user_lock));
+#endif /* BT_OVER_SDIO */
+
+#ifdef WL_CFG80211
+	len += wl_cfg80211_debug_data_dump(dhd_linux_get_primary_netdev(&dhd->pub),
+			(ptr + len), (buf_size - len));
+#endif /* WL_CFG80211 */
+
+	/* Ensure buffer ends with null char */
+	buf[len] = '\0';
+	return len + 1;
+}
+static struct dhd_attr dhd_attr_dhd_debug_data =
+__ATTR(dump_stateinfo, 0660, dhd_debug_dump_stateinfo, NULL);
+
+#ifdef WL_CFG80211
+#define SUBLOGLEVEL 20
+#define SUBLOGLEVELZ ((SUBLOGLEVEL) + (1))
+
+static const struct {
+	u32 log_level;
+	char *sublogname;
+} sublogname_map[] = {
+	{WL_DBG_ERR, "ERR"},
+	{WL_DBG_INFO, "INFO"},
+	{WL_DBG_DBG, "DBG"},
+	{WL_DBG_SCAN, "SCAN"},
+	{WL_DBG_TRACE, "TRACE"},
+	{WL_DBG_P2P_ACTION, "P2PACTION"},
+	{WL_DBG_PNO, "PNO"}
+};
+
+/**
+* Format : echo "SCAN:1 DBG:1" > /sys/wifi/wl_dbg_level
+* to turn on SCAN and DBG log.
+* To turn off SCAN partially, echo "SCAN:0" > /sys/wifi/wl_dbg_level
+* To see current setting of debug level,
+* cat /sys/wifi/wl_dbg_level
+*/
+static ssize_t
+show_wl_debug_level(struct dhd_info *dhd, char *buf)
+{
+	char *param;
+	char tbuf[SUBLOGLEVELZ * ARRAYSIZE(sublogname_map)];
+	uint i;
+	ssize_t ret = 0;
+
+	bzero(tbuf, sizeof(tbuf));
+	param = &tbuf[0];
+	for (i = 0; i < ARRAYSIZE(sublogname_map); i++) {
+		param += snprintf(param, sizeof(tbuf) - 1, "%s:%d ",
+			sublogname_map[i].sublogname,
+			(wl_dbg_level & sublogname_map[i].log_level) ? 1 : 0);
+	}
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%s \n", tbuf);
+	return ret;
+}
+
+static ssize_t
+set_wl_debug_level(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	char tbuf[SUBLOGLEVELZ * ARRAYSIZE(sublogname_map)], sublog[SUBLOGLEVELZ];
+	char *params, *token, *colon;
+	uint i, tokens, log_on = 0;
+	size_t minsize = min_t(size_t, (sizeof(tbuf) - 1), count);
+
+	bzero(tbuf, sizeof(tbuf));
+	bzero(sublog, sizeof(sublog));
+	strlcpy(tbuf, buf, minsize);
+
+	DHD_INFO(("current wl_dbg_level %d \n", wl_dbg_level));
+
+	tbuf[minsize] = '\0';
+	params = &tbuf[0];
+	colon = strchr(params, '\n');
+	if (colon != NULL)
+		*colon = '\0';
+	while ((token = strsep(&params, " ")) != NULL) {
+		bzero(sublog, sizeof(sublog));
+		if (token == NULL || !*token)
+			break;
+		if (*token == '\0')
+			continue;
+		colon = strchr(token, ':');
+		if (colon != NULL) {
+			*colon = ' ';
+		}
+		tokens = sscanf(token, "%"SIZE_CONST_STRING(SUBLOGLEVEL)"s %u", sublog, &log_on);
+		if (colon != NULL)
+			*colon = ':';
+
+		if (tokens == 2) {
+				for (i = 0; i < ARRAYSIZE(sublogname_map); i++) {
+					if (!strncmp(sublog, sublogname_map[i].sublogname,
+						strlen(sublogname_map[i].sublogname))) {
+						if (log_on) {
+							wl_dbg_level |=
+							(sublogname_map[i].log_level);
+							wl_log_level |=
+							(sublogname_map[i].log_level);
+						} else {
+							wl_dbg_level &=
+							~(sublogname_map[i].log_level);
+							wl_log_level &=
+							~(sublogname_map[i].log_level);
+						}
+					}
+				}
+		} else
+			DHD_ERROR(("%s: can't parse '%s' as a "
+			       "SUBMODULE:LEVEL (%d tokens)\n",
+			       tbuf, token, tokens));
+
+	}
+	DHD_ERROR(("changed wl_dbg_level %d \n", wl_dbg_level));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_wl_dbg_level =
+__ATTR(wl_dbg_level, 0660, show_wl_debug_level, set_wl_debug_level);
+#endif /* WL_CFG80211 */
+
+static ssize_t
+show_dhd_console_ms(struct dhd_info *dhd, char *buf)
+{
+	dhd_pub_t *dhdp;
+	ssize_t ret = 0;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return -EINVAL;
+	}
+	dhdp = &dhd->pub;
+
+	ret = scnprintf(buf, PAGE_SIZE -1, "%u\n", dhdp->dhd_console_ms);
+
+	return ret;
+}
+
+static ssize_t
+set_dhd_console_ms(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	dhd_pub_t *dhdp;
+	uint32 val;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return -EINVAL;
+	}
+	dhdp = &dhd->pub;
+
+	val = bcm_atoi(buf);
+
+	dhdp->dhd_console_ms = val;
+	DHD_ERROR(("%s: dhd_console_ms: %d\n", __FUNCTION__, dhdp->dhd_console_ms));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_dhd_console_ms =
+	__ATTR(dhd_console_ms, 0660, show_dhd_console_ms, set_dhd_console_ms);
+
+static ssize_t
+show_dhd_watchdog_ms(struct dhd_info *dhd, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE -1, "%u\n", dhd_watchdog_ms);
+
+	return ret;
+}
+
+static ssize_t
+set_dhd_watchdog_ms(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	uint32 val;
+
+	val = bcm_atoi(buf);
+
+	dhd_watchdog_ms = val;
+	DHD_ERROR(("%s: dhd_console_ms: %d\n", __FUNCTION__, dhd_watchdog_ms));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_dhd_watchdog_ms =
+	__ATTR(dhd_watchdog_ms, 0660, show_dhd_watchdog_ms, set_dhd_watchdog_ms);
+
+static ssize_t
+show_tput_monitor_ms(struct dhd_info *dhd, char *buf)
+{
+	dhd_pub_t *dhdp;
+	ssize_t ret = 0;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return -EINVAL;
+	}
+	dhdp = &dhd->pub;
+
+	ret = scnprintf(buf, PAGE_SIZE -1, "%u\n", dhdp->conf->tput_monitor_ms);
+
+	return ret;
+}
+
+static ssize_t
+set_tput_monitor_ms(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	dhd_pub_t *dhdp;
+	uint32 val;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return -EINVAL;
+	}
+	dhdp = &dhd->pub;
+
+	val = bcm_atoi(buf);
+
+	dhdp->conf->tput_monitor_ms = val;
+	DHD_ERROR(("%s: tput_monitor_ms: %d\n", __FUNCTION__, dhdp->conf->tput_monitor_ms));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_tput_monitor_ms =
+	__ATTR(tput_monitor_ms, 0660, show_tput_monitor_ms, set_tput_monitor_ms);
+
+static const struct {
+	u32 log_level;
+	char *sublogname;
+} config_msg_name_map[] = {
+	{CONFIG_ERROR_LEVEL, "ERROR"},
+	{CONFIG_TRACE_LEVEL, "TRACE"}
+};
+
+static ssize_t
+show_config_msg_level(struct dhd_info *dhd, char *buf)
+{
+	char *param;
+	char tbuf[SUBLOGLEVELZ * ARRAYSIZE(config_msg_name_map)];
+	uint i;
+	ssize_t ret = 0;
+
+	bzero(tbuf, sizeof(tbuf));
+	param = &tbuf[0];
+	for (i = 0; i < ARRAYSIZE(config_msg_name_map); i++) {
+		param += snprintf(param, sizeof(tbuf) - 1, "%s:%d ",
+			config_msg_name_map[i].sublogname,
+			(config_msg_level & config_msg_name_map[i].log_level) ? 1 : 0);
+	}
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%s \n", tbuf);
+	return ret;
+}
+
+static ssize_t
+set_config_msg_level(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	char tbuf[SUBLOGLEVELZ * ARRAYSIZE(config_msg_name_map)], sublog[SUBLOGLEVELZ];
+	char *params, *token, *colon;
+	uint i, tokens, log_on = 0;
+	size_t minsize = min_t(size_t, (sizeof(tbuf) - 1), count);
+
+	bzero(tbuf, sizeof(tbuf));
+	bzero(sublog, sizeof(sublog));
+	strlcpy(tbuf, buf, minsize);
+
+	DHD_INFO(("current config_msg_level %d \n", config_msg_level));
+
+	tbuf[minsize] = '\0';
+	params = &tbuf[0];
+	colon = strchr(params, '\n');
+	if (colon != NULL)
+		*colon = '\0';
+	while ((token = strsep(&params, " ")) != NULL) {
+		bzero(sublog, sizeof(sublog));
+		if (token == NULL || !*token)
+			break;
+		if (*token == '\0')
+			continue;
+		colon = strchr(token, ':');
+		if (colon != NULL) {
+			*colon = ' ';
+		}
+		tokens = sscanf(token, "%"SIZE_CONST_STRING(SUBLOGLEVEL)"s %u", sublog, &log_on);
+		if (colon != NULL)
+			*colon = ':';
+
+		if (tokens == 2) {
+			for (i = 0; i < ARRAYSIZE(config_msg_name_map); i++) {
+				if (!strncmp(sublog, config_msg_name_map[i].sublogname,
+					strlen(config_msg_name_map[i].sublogname))) {
+					if (log_on) {
+						config_msg_level |=
+						(config_msg_name_map[i].log_level);
+					} else {
+						config_msg_level &=
+						~(config_msg_name_map[i].log_level);
+					}
+				}
+			}
+		} else
+			DHD_ERROR(("%s: can't parse '%s' as a "
+			       "SUBMODULE:LEVEL (%d tokens)\n",
+			       tbuf, token, tokens));
+
+	}
+	DHD_ERROR(("changed config_msg_level %d \n", config_msg_level));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_config_msg_level =
+__ATTR(config_msg_level, 0660, show_config_msg_level, set_config_msg_level);
+
+static const struct {
+	u32 log_level;
+	char *sublogname;
+} dhd_msg_name_map[] = {
+	{DHD_ERROR_VAL, "ERROR"},
+	{DHD_TRACE_VAL, "TRACE"},
+	{DHD_INFO_VAL, "INFO"},
+	{DHD_DATA_VAL, "DATA"},
+	{DHD_CTL_VAL, "CTRL"},
+	{DHD_TIMER_VAL, "TIMER"},
+	{DHD_INTR_VAL, "INTR"},
+	{DHD_GLOM_VAL, "GLOM"},
+	{DHD_EVENT_VAL, "EVENT"},
+	{DHD_PNO_VAL, "PNO"},
+	{DHD_RTT_VAL, "RTT"},
+	{DHD_FWLOG_VAL, "FWLOG"},
+	{DHD_RPM_VAL, "RPM"}
+};
+
+static ssize_t
+show_dhd_msg_level(struct dhd_info *dhd, char *buf)
+{
+	char *param;
+	char tbuf[SUBLOGLEVELZ * ARRAYSIZE(dhd_msg_name_map)];
+	uint i;
+	ssize_t ret = 0;
+
+	bzero(tbuf, sizeof(tbuf));
+	param = &tbuf[0];
+	for (i = 0; i < ARRAYSIZE(dhd_msg_name_map); i++) {
+		param += snprintf(param, sizeof(tbuf) - 1, "%s:%d ",
+			dhd_msg_name_map[i].sublogname,
+			(dhd_msg_level & dhd_msg_name_map[i].log_level) ? 1 : 0);
+	}
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%s \n", tbuf);
+	return ret;
+}
+
+static ssize_t
+set_dhd_msg_level(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	char tbuf[SUBLOGLEVELZ * ARRAYSIZE(dhd_msg_name_map)], sublog[SUBLOGLEVELZ];
+	char *params, *token, *colon;
+	uint i, tokens, log_on = 0;
+	size_t minsize = min_t(size_t, (sizeof(tbuf) - 1), count);
+
+	bzero(tbuf, sizeof(tbuf));
+	bzero(sublog, sizeof(sublog));
+	strlcpy(tbuf, buf, minsize);
+
+	DHD_INFO(("current dhd_msg_level %d \n", dhd_msg_level));
+
+	tbuf[minsize] = '\0';
+	params = &tbuf[0];
+	colon = strchr(params, '\n');
+	if (colon != NULL)
+		*colon = '\0';
+	while ((token = strsep(&params, " ")) != NULL) {
+		bzero(sublog, sizeof(sublog));
+		if (token == NULL || !*token)
+			break;
+		if (*token == '\0')
+			continue;
+		colon = strchr(token, ':');
+		if (colon != NULL) {
+			*colon = ' ';
+		}
+		tokens = sscanf(token, "%"SIZE_CONST_STRING(SUBLOGLEVEL)"s %u", sublog, &log_on);
+		if (colon != NULL)
+			*colon = ':';
+
+		if (tokens == 2) {
+			for (i = 0; i < ARRAYSIZE(dhd_msg_name_map); i++) {
+				if (!strncmp(sublog, dhd_msg_name_map[i].sublogname,
+					strlen(dhd_msg_name_map[i].sublogname))) {
+					if (log_on) {
+						dhd_msg_level |=
+						(dhd_msg_name_map[i].log_level);
+					} else {
+						dhd_msg_level &=
+						~(dhd_msg_name_map[i].log_level);
+					}
+				}
+			}
+		} else
+			DHD_ERROR(("%s: can't parse '%s' as a "
+			       "SUBMODULE:LEVEL (%d tokens)\n",
+			       tbuf, token, tokens));
+
+	}
+	DHD_ERROR(("changed dhd_msg_level %d \n", dhd_msg_level));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_dhd_msg_level =
+__ATTR(dhd_msg_level, 0660, show_dhd_msg_level, set_dhd_msg_level);
+
+static const struct {
+	u32 log_level;
+	char *sublogname;
+} dump_msg_name_map[] = {
+	{DUMP_EAPOL_VAL, "EAPOL"},
+	{DUMP_ARP_VAL, "ARP"},
+	{DUMP_DHCP_VAL, "DHCP"},
+	{DUMP_ICMP_VAL, "ICMP"},
+	{DUMP_DNS_VAL, "DNS"},
+	{DUMP_TRX_VAL, "TRX"}
+};
+
+static ssize_t
+show_dump_msg_level(struct dhd_info *dhd, char *buf)
+{
+	char *param;
+	char tbuf[SUBLOGLEVELZ * ARRAYSIZE(dump_msg_name_map)];
+	uint i;
+	ssize_t ret = 0;
+
+	bzero(tbuf, sizeof(tbuf));
+	param = &tbuf[0];
+	for (i = 0; i < ARRAYSIZE(dump_msg_name_map); i++) {
+		param += snprintf(param, sizeof(tbuf) - 1, "%s:%d ",
+			dump_msg_name_map[i].sublogname,
+			(dump_msg_level & dump_msg_name_map[i].log_level) ? 1 : 0);
+	}
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%s \n", tbuf);
+	return ret;
+}
+
+static ssize_t
+set_dump_msg_level(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	char tbuf[SUBLOGLEVELZ * ARRAYSIZE(dump_msg_name_map)], sublog[SUBLOGLEVELZ];
+	char *params, *token, *colon;
+	uint i, tokens, log_on = 0;
+	size_t minsize = min_t(size_t, (sizeof(tbuf) - 1), count);
+
+	bzero(tbuf, sizeof(tbuf));
+	bzero(sublog, sizeof(sublog));
+	strlcpy(tbuf, buf, minsize);
+
+	DHD_INFO(("current dump_msg_level %d \n", dump_msg_level));
+
+	tbuf[minsize] = '\0';
+	params = &tbuf[0];
+	colon = strchr(params, '\n');
+	if (colon != NULL)
+		*colon = '\0';
+	while ((token = strsep(&params, " ")) != NULL) {
+		bzero(sublog, sizeof(sublog));
+		if (token == NULL || !*token)
+			break;
+		if (*token == '\0')
+			continue;
+		colon = strchr(token, ':');
+		if (colon != NULL) {
+			*colon = ' ';
+		}
+		tokens = sscanf(token, "%"SIZE_CONST_STRING(SUBLOGLEVEL)"s %u", sublog, &log_on);
+		if (colon != NULL)
+			*colon = ':';
+
+		if (tokens == 2) {
+			for (i = 0; i < ARRAYSIZE(dump_msg_name_map); i++) {
+				if (!strncmp(sublog, dump_msg_name_map[i].sublogname,
+					strlen(dump_msg_name_map[i].sublogname))) {
+					if (log_on) {
+						dump_msg_level |=
+						(dump_msg_name_map[i].log_level);
+					} else {
+						dump_msg_level &=
+						~(dump_msg_name_map[i].log_level);
+					}
+				}
+			}
+		} else
+			DHD_ERROR(("%s: can't parse '%s' as a "
+			       "SUBMODULE:LEVEL (%d tokens)\n",
+			       tbuf, token, tokens));
+
+	}
+	DHD_ERROR(("changed dump_msg_level %d \n", dump_msg_level));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_dump_msg_level =
+__ATTR(dump_msg_level, 0660, show_dump_msg_level, set_dump_msg_level);
+
+static const struct {
+	u32 log_level;
+	char *sublogname;
+} android_msg_name_map[] = {
+	{ANDROID_ERROR_LEVEL, "ERROR"},
+	{ANDROID_TRACE_LEVEL, "TRACE"},
+	{ANDROID_INFO_LEVEL, "INFO"},
+	{ANDROID_SCAN_LEVEL, "SCAN"},
+	{ANDROID_DBG_LEVEL, "DBG"},
+	{ANDROID_TPUT_LEVEL, "TPUT"},
+	{ANDROID_AMPDU_LEVEL, "AMPDU"},
+	{ANDROID_TVPM_LEVEL, "TVPM"},
+	{ANDROID_BTC_LEVEL, "BTC"},
+	{ANDROID_SWDIV_LEVEL, "SWDIV"}
+};
+
+static ssize_t
+show_android_msg_level(struct dhd_info *dhd, char *buf)
+{
+	char *param;
+	char tbuf[SUBLOGLEVELZ * ARRAYSIZE(android_msg_name_map)];
+	uint i;
+	ssize_t ret = 0;
+
+	bzero(tbuf, sizeof(tbuf));
+	param = &tbuf[0];
+	for (i = 0; i < ARRAYSIZE(android_msg_name_map); i++) {
+		param += snprintf(param, sizeof(tbuf) - 1, "%s:%d ",
+			android_msg_name_map[i].sublogname,
+			(android_msg_level & android_msg_name_map[i].log_level) ? 1 : 0);
+	}
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%s \n", tbuf);
+	return ret;
+}
+
+static ssize_t
+set_android_msg_level(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	char tbuf[SUBLOGLEVELZ * ARRAYSIZE(android_msg_name_map)], sublog[SUBLOGLEVELZ];
+	char *params, *token, *colon;
+	uint i, tokens, log_on = 0;
+	size_t minsize = min_t(size_t, (sizeof(tbuf) - 1), count);
+
+	bzero(tbuf, sizeof(tbuf));
+	bzero(sublog, sizeof(sublog));
+	strlcpy(tbuf, buf, minsize);
+
+	DHD_INFO(("current android_msg_level %d \n", android_msg_level));
+
+	tbuf[minsize] = '\0';
+	params = &tbuf[0];
+	colon = strchr(params, '\n');
+	if (colon != NULL)
+		*colon = '\0';
+	while ((token = strsep(&params, " ")) != NULL) {
+		bzero(sublog, sizeof(sublog));
+		if (token == NULL || !*token)
+			break;
+		if (*token == '\0')
+			continue;
+		colon = strchr(token, ':');
+		if (colon != NULL) {
+			*colon = ' ';
+		}
+		tokens = sscanf(token, "%"SIZE_CONST_STRING(SUBLOGLEVEL)"s %u", sublog, &log_on);
+		if (colon != NULL)
+			*colon = ':';
+
+		if (tokens == 2) {
+			for (i = 0; i < ARRAYSIZE(android_msg_name_map); i++) {
+				if (!strncmp(sublog, android_msg_name_map[i].sublogname,
+					strlen(android_msg_name_map[i].sublogname))) {
+					if (log_on) {
+						android_msg_level |=
+						(android_msg_name_map[i].log_level);
+					} else {
+						android_msg_level &=
+						~(android_msg_name_map[i].log_level);
+					}
+				}
+			}
+		} else
+			DHD_ERROR(("%s: can't parse '%s' as a "
+			       "SUBMODULE:LEVEL (%d tokens)\n",
+			       tbuf, token, tokens));
+
+	}
+	DHD_ERROR(("changed android_msg_level %d \n", android_msg_level));
+	return count;
+}
+
+static struct dhd_attr dhd_attr_android_msg_level =
+__ATTR(android_msg_level, 0660, show_android_msg_level, set_android_msg_level);
+
+#if defined(DHD_FILE_DUMP_EVENT) && defined(DHD_FW_COREDUMP)
+#define DUMP_TRIGGER	1
+
+static ssize_t
+show_dhd_dump_in_progress(struct dhd_info *dhd, char *buf)
+{
+	size_t ret = 0;
+	dhd_dongledump_status_t dump_status;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	dump_status = dhd_get_dump_status(&dhd->pub);
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d \n", dump_status);
+
+	return ret;
+}
+
+static ssize_t
+set_dhd_dump_in_progress(struct dhd_info *dhd, const char *buf, size_t count)
+{
+	uint32 input;
+	dhd_dongledump_status_t dump_status;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return count;
+	}
+
+	dump_status = dhd_get_dump_status(&dhd->pub);
+	if (dump_status == DUMP_NOT_READY || dump_status == DUMP_IN_PROGRESS) {
+		DHD_ERROR(("%s: Could not start dongle dump: %d\n",
+			__FUNCTION__, dump_status));
+		goto exit;
+	}
+
+	input = bcm_atoi(buf);
+	if (input == DUMP_TRIGGER) {
+		DHD_INFO(("%s: Trigger dongle dump\n", __FUNCTION__));
+		dhd_set_dump_status(&dhd->pub, DUMP_IN_PROGRESS);
+		schedule_work(&dhd->dhd_dump_proc_work);
+	}
+	else {
+		DHD_ERROR(("%s: Invalid value %d\n", __FUNCTION__, input));
+	}
+
+exit:
+	return count;
+}
+
+static struct dhd_attr dhd_attr_dump_in_progress =
+__ATTR(dump_in_progress, 0660, show_dhd_dump_in_progress, set_dhd_dump_in_progress);
+#endif /* DHD_FILE_DUMP_EVENT && DHD_FW_COREDUMP */
+
+#ifdef DHD_DUMP_START_COMMAND
+static ssize_t
+trigger_dhd_dump_start_command(struct dhd_info *dhd, char *buf)
+{
+	ssize_t ret = 0;
+	DHD_ERROR(("%s: dump_start command delivered.\n", __FUNCTION__));
+	return ret;
+}
+
+static struct dhd_attr dhd_attr_dump_start_command =
+	__ATTR(dump_start, 0664, trigger_dhd_dump_start_command, NULL);
+#endif /* DHD_DUMP_START_COMMAND */
+
+/* Attribute object that gets registered with "wifi" kobject tree */
+static struct attribute *default_file_attrs[] = {
+#if defined(DHD_MAC_ADDR_EXPORT) || defined(DHD_MAC_ADDR_EXPORT_RO)
+	&dhd_attr_macaddr.attr,
+#endif /* DHD_MAC_ADDR_EXPORT || DHD_MAC_ADDR_EXPORT_RO */
+#ifdef DHD_FW_COREDUMP
+	&dhd_attr_memdump.attr,
+#endif /* DHD_FW_COREDUMP */
+#ifdef DHD_EXPORT_CNTL_FILE
+#ifdef BCMASSERT_LOG
+	&dhd_attr_assert.attr,
+#endif /* BCMASSERT_LOG */
+#ifdef WRITE_WLANINFO
+	&dhd_attr_wifiver.attr,
+#endif /* WRITE_WLANINFO */
+#if defined(USE_CID_CHECK) || defined(USE_DIRECT_VID_TAG)
+	&dhd_attr_cidinfo.attr,
+#endif /* USE_CID_CHECK || USE_DIRECT_VID_TAG */
+#ifdef GEN_SOFTAP_INFO_FILE
+	&dhd_attr_softapinfo.attr,
+#endif /* GEN_SOFTAP_INFO_FILE */
+#ifdef MIMO_ANT_SETTING
+	&dhd_attr_antinfo.attr,
+#endif /* MIMO_ANT_SETTING */
+#ifdef DHD_PM_CONTROL_FROM_FILE
+	&dhd_attr_pminfo.attr,
+#endif /* DHD_PM_CONTROL_FROM_FILE */
+#ifdef LOGTRACE_FROM_FILE
+	&dhd_attr_logtraceinfo.attr,
+#endif /* LOGTRACE_FROM_FILE */
+#ifdef USE_WFA_CERT_CONF
+#ifdef BCMSDIO
+	&dhd_attr_bustxglom.attr,
+#endif /* BCMSDIO */
+	&dhd_attr_roamoff.attr,
+#ifdef USE_WL_FRAMEBURST
+	&dhd_attr_frameburst.attr,
+#endif /* USE_WL_FRAMEBURST */
+#ifdef USE_WL_TXBF
+	&dhd_attr_txbf.attr,
+#endif /* USE_WL_TXBF */
+#ifdef PROP_TXSTATUS
+	&dhd_attr_proptx.attr,
+#endif /* PROP_TXSTATUS */
+#endif /* USE_WFA_CERT_CONF */
+#endif /* DHD_EXPORT_CNTL_FILE */
+#if defined(WL_BAM)
+	&dhd_attr_adps_bam.attr,
+#endif	/* WL_BAM */
+#ifdef DHD_SEND_HANG_PRIVCMD_ERRORS
+	&dhd_attr_hang_privcmd_err.attr,
+#endif /* DHD_SEND_HANG_PRIVCMD_ERRORS */
+#if defined(SHOW_LOGTRACE)
+	&dhd_attr_control_logtrace.attr,
+#endif /* SHOW_LOGTRACE */
+#if defined(DHD_TRACE_WAKE_LOCK)
+	&dhd_attr_wklock.attr,
+#endif
+#ifdef DHD_LOG_DUMP
+	&dhd_attr_logdump_periodic_flush.attr,
+	&dhd_attr_logdump_ecntr.attr,
+#endif
+	&dhd_attr_ecounters.attr,
+#ifdef DHD_SSSR_DUMP
+	&dhd_attr_sssr_enab.attr,
+	&dhd_attr_fis_enab.attr,
+#endif /* DHD_SSSR_DUMP */
+	&dhd_attr_firmware_path.attr,
+	&dhd_attr_nvram_path.attr,
+#if defined(CUSTOM_CONTROL_HE_ENAB)
+	&dhd_attr_control_he_enab.attr,
+#endif /* CUSTOM_CONTROL_HE_ENAB */
+#if defined(WLAN_ACCEL_BOOT)
+	&dhd_attr_wl_accel_force_reg_on.attr,
+#endif /* WLAN_ACCEL_BOOT */
+#ifdef PWRSTATS_SYSFS
+	&dhd_attr_pwrstats_path.attr,
+#endif /* PWRSTATS_SYSFS */
+#if defined(WL_CFG80211)
+	&dhd_attr_wl_dbg_level.attr,
+#endif /* WL_CFG80211 */
+	&dhd_attr_dhd_console_ms.attr,
+	&dhd_attr_dhd_watchdog_ms.attr,
+	&dhd_attr_tput_monitor_ms.attr,
+	&dhd_attr_config_msg_level.attr,
+	&dhd_attr_dhd_msg_level.attr,
+	&dhd_attr_dump_msg_level.attr,
+	&dhd_attr_android_msg_level.attr,
+#if defined(DHD_FILE_DUMP_EVENT) && defined(DHD_FW_COREDUMP)
+	&dhd_attr_dump_in_progress.attr,
+#endif /* DHD_FILE_DUMP_EVENT && DHD_FW_COREDUMP */
+#ifdef DHD_DUMP_START_COMMAND
+	&dhd_attr_dump_start_command.attr,
+#endif /* DHD_DUMP_START_COMMAND */
+	&dhd_attr_dhd_debug_data.attr,
+#if defined(AGG_H2D_DB)
+	&dhd_attr_agg_h2d_db_enab.attr,
+	&dhd_attr_agg_h2d_db_inflight_thresh.attr,
+	&dhd_attr_agg_h2d_db_timeout.attr,
+#endif /* AGG_H2D_DB */
+#if defined(RX_PKT_POOL)
+	&dhd_attr_max_rx_pkt_pool.attr,
+#endif /* RX_PKT_POOL */
+#ifdef PCIE_FULL_DONGLE
+	&dhd_attr_aspm_enab.attr,
+	&dhd_attr_l1ss_enab.attr,
+#endif /* PCIE_FULL_DONGLE */
+#ifdef RPM_FAST_TRIGGER
+	&dhd_attr_fast_rpm_thresh.attr,
+#endif /* RPM_FAST_TRIGGER */
+	&dhd_attr_sig_path.attr,
+	&dhd_attr_tcm_test_mode.attr,
+	NULL
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
+static const struct attribute_group default_group = {
+	.attrs = default_file_attrs
+};
+static const struct attribute_group *default_groups[] = {
+	&default_group,
+	NULL
+};
+#endif /* LINUX_VER >= 5.18 */
+/*
+ * wifi kobject show function, the "attr" attribute specifices to which
+ * node under "sys/wifi" the show function is called.
+ */
+static ssize_t dhd_show(struct kobject *kobj, struct attribute *attr, char *buf)
+{
+	dhd_info_t *dhd;
+	struct dhd_attr *d_attr;
+	int ret;
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd = to_dhd(kobj);
+	d_attr = to_attr(attr);
+	GCC_DIAGNOSTIC_POP();
+
+	if (d_attr->show)
+		ret = d_attr->show(dhd, buf);
+	else
+		ret = -EIO;
+
+	return ret;
+}
+
+/*
+ * wifi kobject show function, the "attr" attribute specifices to which
+ * node under "sys/wifi" the store function is called.
+ */
+static ssize_t dhd_store(struct kobject *kobj, struct attribute *attr,
+	const char *buf, size_t count)
+{
+	dhd_info_t *dhd;
+	struct dhd_attr *d_attr;
+	int ret;
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd = to_dhd(kobj);
+	d_attr = to_attr(attr);
+	GCC_DIAGNOSTIC_POP();
+
+	if (d_attr->store)
+		ret = d_attr->store(dhd, buf, count);
+	else
+		ret = -EIO;
+
+	return ret;
+
+}
+
+static const struct sysfs_ops dhd_sysfs_ops = {
+	.show = dhd_show,
+	.store = dhd_store,
+};
+
+static struct kobj_type dhd_ktype = {
+	.sysfs_ops = &dhd_sysfs_ops,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
+	.default_groups = default_groups,
+#else
+	.default_attrs = default_file_attrs,
+#endif /* LINUX_VER >= 5.18 */
+};
+
+/*
+ * sysfs for dhd_lb
+ */
+#ifdef DHD_LB
+#if defined(DHD_LB_TXP)
+static ssize_t
+show_lbtxp(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+	unsigned long onoff;
+	dhd_info_t *dhd = (dhd_info_t *)dev;
+
+	onoff = atomic_read(&dhd->lb_txp_active);
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%lu \n",
+		onoff);
+	return ret;
+}
+
+static ssize_t
+lbtxp_onoff(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long onoff;
+	dhd_info_t *dhd = (dhd_info_t *)dev;
+	int i;
+
+	onoff = bcm_strtoul(buf, NULL, 10);
+
+	sscanf(buf, "%lu", &onoff);
+	if (onoff != 0 && onoff != 1) {
+		return -EINVAL;
+	}
+	atomic_set(&dhd->lb_txp_active, onoff);
+
+	/* Since the scheme is changed clear the counters */
+	for (i = 0; i < NR_CPUS; i++) {
+		DHD_LB_STATS_CLR(dhd->txp_percpu_run_cnt[i]);
+		DHD_LB_STATS_CLR(dhd->tx_start_percpu_run_cnt[i]);
+	}
+
+	return count;
+}
+
+static struct dhd_attr dhd_attr_lbtxp =
+	__ATTR(lbtxp, 0660, show_lbtxp, lbtxp_onoff);
+#endif /* DHD_LB_TXP */
+
+#if defined(DHD_LB_RXP)
+static ssize_t
+show_lbrxp(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+	unsigned long onoff;
+	dhd_info_t *dhd = (dhd_info_t *)dev;
+
+	onoff = atomic_read(&dhd->lb_rxp_active);
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%lu \n",
+		onoff);
+	return ret;
+}
+
+static ssize_t
+lbrxp_onoff(struct dhd_info *dev, const char *buf, size_t count)
+{
+	unsigned long onoff;
+	dhd_info_t *dhd = (dhd_info_t *)dev;
+
+	onoff = bcm_strtoul(buf, NULL, 10);
+
+	sscanf(buf, "%lu", &onoff);
+	if (onoff != 0 && onoff != 1) {
+		return -EINVAL;
+	}
+	atomic_set(&dhd->lb_rxp_active, onoff);
+
+	return count;
+}
+static struct dhd_attr dhd_attr_lbrxp =
+	__ATTR(lbrxp, 0660, show_lbrxp, lbrxp_onoff);
+
+static ssize_t
+get_lb_rxp_stop_thr(struct dhd_info *dev, char *buf)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dev;
+	dhd_pub_t *dhdp;
+	ssize_t ret = 0;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return -EINVAL;
+	}
+	dhdp = &dhd->pub;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%u \n",
+		(dhdp->lb_rxp_stop_thr / D2HRING_RXCMPLT_MAX_ITEM));
+	return ret;
+}
+
+#define ONE_GB (1024 * 1024 * 1024)
+
+static ssize_t
+set_lb_rxp_stop_thr(struct dhd_info *dev, const char *buf, size_t count)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dev;
+	dhd_pub_t *dhdp;
+	uint32 lb_rxp_stop_thr;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return -EINVAL;
+	}
+	dhdp = &dhd->pub;
+
+	lb_rxp_stop_thr = (uint32)bcm_strtoul(buf, NULL, 10);
+	sscanf(buf, "%u", &lb_rxp_stop_thr);
+
+	/* disable lb_rxp flow ctrl */
+	if (lb_rxp_stop_thr == 0) {
+		dhdp->lb_rxp_stop_thr = 0;
+		dhdp->lb_rxp_strt_thr = 0;
+		atomic_set(&dhd->pub.lb_rxp_flow_ctrl, FALSE);
+		return count;
+	}
+	/* 1. by the time lb_rxp_stop_thr gets into picture,
+	 * DHD RX path should not consume more than 1GB
+	 * 2. lb_rxp_stop_thr should always be more than dhdp->lb_rxp_strt_thr
+	 */
+	if (((lb_rxp_stop_thr *
+		D2HRING_RXCMPLT_MAX_ITEM *
+		dhd_prot_get_rxbufpost_sz(dhdp)) > ONE_GB) ||
+		(lb_rxp_stop_thr <= (dhdp->lb_rxp_strt_thr / D2HRING_RXCMPLT_MAX_ITEM))) {
+		return -EINVAL;
+	}
+
+	dhdp->lb_rxp_stop_thr = (D2HRING_RXCMPLT_MAX_ITEM * lb_rxp_stop_thr);
+	return count;
+}
+
+static struct dhd_attr dhd_attr_lb_rxp_stop_thr =
+	__ATTR(lbrxp_stop_thr, 0660, get_lb_rxp_stop_thr, set_lb_rxp_stop_thr);
+
+static ssize_t
+get_lb_rxp_strt_thr(struct dhd_info *dev, char *buf)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dev;
+	dhd_pub_t *dhdp;
+	ssize_t ret = 0;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return -EINVAL;
+	}
+	dhdp = &dhd->pub;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%u \n",
+		(dhdp->lb_rxp_strt_thr / D2HRING_RXCMPLT_MAX_ITEM));
+	return ret;
+}
+
+static ssize_t
+set_lb_rxp_strt_thr(struct dhd_info *dev, const char *buf, size_t count)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dev;
+	dhd_pub_t *dhdp;
+	uint32 lb_rxp_strt_thr;
+
+	if (!dhd) {
+		DHD_ERROR(("%s: dhd is NULL\n", __FUNCTION__));
+		return -EINVAL;
+	}
+	dhdp = &dhd->pub;
+
+	lb_rxp_strt_thr = (uint32)bcm_strtoul(buf, NULL, 10);
+	sscanf(buf, "%u", &lb_rxp_strt_thr);
+
+	/* disable lb_rxp flow ctrl */
+	if (lb_rxp_strt_thr == 0) {
+		dhdp->lb_rxp_strt_thr = 0;
+		dhdp->lb_rxp_stop_thr = 0;
+		atomic_set(&dhd->pub.lb_rxp_flow_ctrl, FALSE);
+		return count;
+	}
+	/* should be less than dhdp->lb_rxp_stop_thr */
+	if ((lb_rxp_strt_thr <= 0) ||
+		(lb_rxp_strt_thr >= (dhdp->lb_rxp_stop_thr / D2HRING_RXCMPLT_MAX_ITEM))) {
+		return -EINVAL;
+	}
+	dhdp->lb_rxp_strt_thr = (D2HRING_RXCMPLT_MAX_ITEM * lb_rxp_strt_thr);
+	return count;
+}
+static struct dhd_attr dhd_attr_lb_rxp_strt_thr =
+	__ATTR(lbrxp_strt_thr, 0660, get_lb_rxp_strt_thr, set_lb_rxp_strt_thr);
+
+#endif /* DHD_LB_RXP */
+
+static ssize_t
+show_candidacy_override(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1,
+			"%d\n", (int)dev->dhd_lb_candidacy_override);
+	return ret;
+}
+
+static ssize_t
+set_candidacy_override(struct dhd_info *dev, const char *buf, size_t count)
+{
+
+	int val = 0;
+	val = bcm_atoi(buf);
+
+	if (val > 0) {
+		dev->dhd_lb_candidacy_override = TRUE;
+	} else {
+		dev->dhd_lb_candidacy_override = FALSE;
+	}
+
+	DHD_ERROR(("set dhd_lb_candidacy_override %d\n", dev->dhd_lb_candidacy_override));
+	return count;
+}
+
+static struct dhd_attr dhd_candidacy_override =
+__ATTR(candidacy_override, 0660, show_candidacy_override, set_candidacy_override);
+
+static ssize_t
+show_primary_mask(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1,
+			"%02lx\n", *cpumask_bits(dev->cpumask_primary));
+	return ret;
+}
+
+static ssize_t
+set_primary_mask(struct dhd_info *dev, const char *buf, size_t count)
+{
+	int ret;
+
+	cpumask_var_t primary_mask;
+
+	if (!alloc_cpumask_var(&primary_mask, GFP_KERNEL)) {
+		DHD_ERROR(("Can't allocate cpumask vars\n"));
+		return count;
+	}
+
+	cpumask_clear(primary_mask);
+	ret = cpumask_parse(buf, primary_mask);
+	if (ret < 0) {
+		DHD_ERROR(("Setting cpumask failed ret = %d\n", ret));
+		return count;
+	}
+
+	cpumask_clear(dev->cpumask_primary);
+	cpumask_or(dev->cpumask_primary, dev->cpumask_primary, primary_mask);
+
+	DHD_ERROR(("set cpumask results cpumask_primary 0x%2lx\n",
+		*cpumask_bits(dev->cpumask_primary)));
+
+	dhd_select_cpu_candidacy(dev);
+	return count;
+}
+
+static struct dhd_attr dhd_primary_mask =
+__ATTR(primary_mask, 0660, show_primary_mask, set_primary_mask);
+
+static ssize_t
+show_secondary_mask(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1,
+			"%02lx\n", *cpumask_bits(dev->cpumask_secondary));
+	return ret;
+}
+
+static ssize_t
+set_secondary_mask(struct dhd_info *dev, const char *buf, size_t count)
+{
+	int ret;
+
+	cpumask_var_t secondary_mask;
+
+	if (!alloc_cpumask_var(&secondary_mask, GFP_KERNEL)) {
+		DHD_ERROR(("Can't allocate cpumask vars\n"));
+		return count;
+	}
+
+	cpumask_clear(secondary_mask);
+
+	ret = cpumask_parse(buf, secondary_mask);
+
+	if (ret < 0) {
+		DHD_ERROR(("Setting cpumask failed ret = %d\n", ret));
+		return count;
+	}
+
+	cpumask_clear(dev->cpumask_secondary);
+	cpumask_or(dev->cpumask_secondary, dev->cpumask_secondary, secondary_mask);
+
+	DHD_ERROR(("set cpumask results cpumask_secondary 0x%2lx\n",
+		*cpumask_bits(dev->cpumask_secondary)));
+
+	dhd_select_cpu_candidacy(dev);
+
+	return count;
+}
+
+static struct dhd_attr dhd_secondary_mask =
+__ATTR(secondary_mask, 0660, show_secondary_mask, set_secondary_mask);
+
+static ssize_t
+show_rx_cpu(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n", atomic_read(&dev->rx_napi_cpu));
+	return ret;
+}
+
+static ssize_t
+set_rx_cpu(struct dhd_info *dev, const char *buf, size_t count)
+{
+	uint32 val;
+
+	if (!dev->dhd_lb_candidacy_override) {
+		DHD_ERROR(("dhd_lb_candidacy_override is required %d\n",
+			dev->dhd_lb_candidacy_override));
+		return count;
+	}
+
+	val = (uint32)bcm_atoi(buf);
+	if (val >= nr_cpu_ids)
+	{
+		DHD_ERROR(("%s : can't set the value out of number of cpus, val = %u\n",
+			__FUNCTION__, val));
+	}
+
+	atomic_set(&dev->rx_napi_cpu, val);
+	DHD_ERROR(("%s: rx_napi_cpu = %d\n", __FUNCTION__, atomic_read(&dev->rx_napi_cpu)));
+	return count;
+}
+
+static struct dhd_attr dhd_rx_cpu =
+__ATTR(rx_cpu, 0660, show_rx_cpu, set_rx_cpu);
+
+static ssize_t
+show_tx_cpu(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n", atomic_read(&dev->tx_cpu));
+	return ret;
+}
+
+static ssize_t
+set_tx_cpu(struct dhd_info *dev, const char *buf, size_t count)
+{
+	uint32 val;
+
+	if (!dev->dhd_lb_candidacy_override) {
+		DHD_ERROR(("dhd_lb_candidacy_override is required %d\n",
+			dev->dhd_lb_candidacy_override));
+		return count;
+	}
+
+	val = (uint32)bcm_atoi(buf);
+	if (val >= nr_cpu_ids)
+	{
+		DHD_ERROR(("%s : can't set the value out of number of cpus, val = %u\n",
+			__FUNCTION__, val));
+		return count;
+	}
+
+	atomic_set(&dev->tx_cpu, val);
+	DHD_ERROR(("%s: tx_cpu = %d\n", __FUNCTION__, atomic_read(&dev->tx_cpu)));
+	return count;
+}
+
+static struct dhd_attr dhd_tx_cpu =
+__ATTR(tx_cpu, 0660, show_tx_cpu, set_tx_cpu);
+
+static struct attribute *debug_lb_attrs[] = {
+#if defined(DHD_LB_TXP)
+	&dhd_attr_lbtxp.attr,
+#endif /* DHD_LB_TXP */
+#if defined(DHD_LB_RXP)
+	&dhd_attr_lbrxp.attr,
+	&dhd_attr_lb_rxp_stop_thr.attr,
+	&dhd_attr_lb_rxp_strt_thr.attr,
+#endif /* DHD_LB_RXP */
+	&dhd_candidacy_override.attr,
+	&dhd_primary_mask.attr,
+	&dhd_secondary_mask.attr,
+	&dhd_rx_cpu.attr,
+	&dhd_tx_cpu.attr,
+	NULL
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
+static const struct attribute_group debug_lb_group = {
+	.attrs = debug_lb_attrs
+};
+static const struct attribute_group *debug_lb_groups[] = {
+	&debug_lb_group,
+	NULL
+};
+#endif /* LINUX_VER >= 5.18 */
+#define to_dhd_lb(k) container_of(k, struct dhd_info, dhd_lb_kobj)
+
+/*
+ * wifi/lb kobject show function, the "attr" attribute specifices to which
+ * node under "sys/wifi/lb" the show function is called.
+ */
+static ssize_t dhd_lb_show(struct kobject *kobj, struct attribute *attr, char *buf)
+{
+	dhd_info_t *dhd;
+	struct dhd_attr *d_attr;
+	int ret;
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd = to_dhd_lb(kobj);
+	d_attr = to_attr(attr);
+	GCC_DIAGNOSTIC_POP();
+
+	if (d_attr->show)
+		ret = d_attr->show(dhd, buf);
+	else
+		ret = -EIO;
+
+	return ret;
+}
+
+/*
+ * wifi kobject show function, the "attr" attribute specifices to which
+ * node under "sys/wifi/lb" the store function is called.
+ */
+static ssize_t dhd_lb_store(struct kobject *kobj, struct attribute *attr,
+		const char *buf, size_t count)
+{
+	dhd_info_t *dhd;
+	struct dhd_attr *d_attr;
+	int ret;
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd = to_dhd_lb(kobj);
+	d_attr = to_attr(attr);
+	GCC_DIAGNOSTIC_POP();
+
+	if (d_attr->store)
+		ret = d_attr->store(dhd, buf, count);
+	else
+		ret = -EIO;
+
+	return ret;
+
+}
+
+static const struct sysfs_ops dhd_sysfs_lb_ops = {
+	.show = dhd_lb_show,
+	.store = dhd_lb_store,
+};
+
+static struct kobj_type dhd_lb_ktype = {
+	.sysfs_ops = &dhd_sysfs_lb_ops,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
+	.default_groups = debug_lb_groups,
+#else
+	.default_attrs = debug_lb_attrs,
+#endif /* LINUX_VER >= 5.18 */
+};
+#endif /* DHD_LB */
+
+#ifdef CUSTOMER_HW4
+#define CONST_SYNA_DHD_KOBJ_NAME      "wifi"
+#define CONST_SYNA_DHD_CSI_OBJ_NAME    "csi"
+#define CONST_SYNA_DHD_LB_OBJ_NAME    "lb"
+#else
+#ifdef BCMPCIE
+#define CONST_SYNA_DHD_KOBJ_NAME       "wifi_pcie"
+#define CONST_SYNA_DHD_CSI_OBJ_NAME    "csi"
+#define CONST_SYNA_DHD_LB_OBJ_NAME     "lb_pcie"
+#else /* BCMSDIO */
+#define CONST_SYNA_DHD_KOBJ_NAME       "wifi_sdio"
+#define CONST_SYNA_DHD_CSI_OBJ_NAME    "csi"
+#define CONST_SYNA_DHD_LB_OBJ_NAME     "lb_sdio"
+#endif /* BCMPCIE */
+#endif /* CUSTOMER_HW4 */
+
+/*
+ * ************ DPC BOUNDS *************
+ */
+
+static ssize_t
+show_ctrl_cpl_post_bound(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n",
+		dhd_prot_get_ctrl_cpl_post_bound(&dev->pub));
+	return ret;
+}
+
+static ssize_t
+set_ctrl_cpl_post_bound(struct dhd_info *dev, const char *buf, size_t count)
+{
+	int val;
+
+	val = (uint32)bcm_atoi(buf);
+	if (val <= 0)
+	{
+		DHD_ERROR(("%s : invalid ctrl_cpl_post_bound %u\n",
+			__FUNCTION__, val));
+		return count;
+	}
+
+	dhd_prot_set_ctrl_cpl_post_bound(&dev->pub, val);
+	return count;
+}
+
+static ssize_t
+show_tx_post_bound(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n", dhd_prot_get_tx_post_bound(&dev->pub));
+	return ret;
+}
+
+static ssize_t
+set_tx_post_bound(struct dhd_info *dev, const char *buf, size_t count)
+{
+	int val;
+
+	val = (uint32)bcm_atoi(buf);
+	if (val <= 0)
+	{
+		DHD_ERROR(("%s : invalid tx_post_bound %u\n",
+			__FUNCTION__, val));
+		return count;
+	}
+
+	dhd_prot_set_tx_post_bound(&dev->pub, val);
+	return count;
+}
+
+static ssize_t
+show_rx_cpl_post_bound(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n",
+		dhd_prot_get_rx_cpl_post_bound(&dev->pub));
+	return ret;
+}
+
+static ssize_t
+set_rx_cpl_post_bound(struct dhd_info *dev, const char *buf, size_t count)
+{
+	int val;
+
+	val = (uint32)bcm_atoi(buf);
+	if (val <= 0)
+	{
+		DHD_ERROR(("%s : invalid rx_cpl_post_bound %u\n",
+			__FUNCTION__, val));
+		return count;
+	}
+
+	dhd_prot_set_rx_cpl_post_bound(&dev->pub, val);
+	return count;
+}
+
+static ssize_t
+show_tx_cpl_bound(struct dhd_info *dev, char *buf)
+{
+	ssize_t ret = 0;
+
+	ret = scnprintf(buf, PAGE_SIZE - 1, "%d\n", dhd_prot_get_tx_cpl_bound(&dev->pub));
+	return ret;
+}
+
+static ssize_t
+set_tx_cpl_bound(struct dhd_info *dev, const char *buf, size_t count)
+{
+	int val;
+
+	val = (uint32)bcm_atoi(buf);
+	if (val <= 0)
+	{
+		DHD_ERROR(("%s : invalid tx_cpl_bound %u\n",
+			__FUNCTION__, val));
+		return count;
+	}
+
+	dhd_prot_set_tx_cpl_bound(&dev->pub, val);
+	return count;
+}
+
+static struct dhd_attr dhd_attr_ctrl_cpl_post_bound =
+__ATTR(ctrl_cpl_post_bound, 0660, show_ctrl_cpl_post_bound, set_ctrl_cpl_post_bound);
+static struct dhd_attr dhd_attr_tx_post_bound =
+__ATTR(tx_post_bound, 0660, show_tx_post_bound, set_tx_post_bound);
+static struct dhd_attr dhd_attr_rx_cpl_post_bound =
+__ATTR(rx_cpl_post_bound, 0660, show_rx_cpl_post_bound, set_rx_cpl_post_bound);
+static struct dhd_attr dhd_attr_tx_cpl_bound =
+__ATTR(tx_cpl_bound, 0660, show_tx_cpl_bound, set_tx_cpl_bound);
+
+static struct attribute *debug_dpc_bounds_attrs[] = {
+	&dhd_attr_tx_cpl_bound.attr,
+	&dhd_attr_rx_cpl_post_bound.attr,
+	&dhd_attr_tx_post_bound.attr,
+	&dhd_attr_ctrl_cpl_post_bound.attr,
+	NULL
+};
+
+#define to_dhd_dpc_bounds(k) container_of(k, struct dhd_info, dhd_dpc_bounds_kobj)
+
+/*
+ * wifi/dpc_bounds kobject show function, the "attr" attribute specifices to which
+ * node under "sys/wifi/dpc_bounds" the show function is called.
+ */
+static ssize_t dhd_dpc_bounds_show(struct kobject *kobj, struct attribute *attr, char *buf)
+{
+	dhd_info_t *dhd;
+	struct dhd_attr *d_attr;
+	int ret;
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd = to_dhd_dpc_bounds(kobj);
+	d_attr = to_attr(attr);
+	GCC_DIAGNOSTIC_POP();
+
+	if (d_attr->show)
+		ret = d_attr->show(dhd, buf);
+	else
+		ret = -EIO;
+
+	return ret;
+}
+
+/*
+ * wifi/dpc_bounds kobject store function, the "attr" attribute specifices to which
+ * node under "sys/wifi/dpc_bounds" the store function is called.
+ */
+static ssize_t dhd_dpc_bounds_store(struct kobject *kobj, struct attribute *attr,
+		const char *buf, size_t count)
+{
+	dhd_info_t *dhd;
+	struct dhd_attr *d_attr;
+	int ret;
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd = to_dhd_dpc_bounds(kobj);
+	d_attr = to_attr(attr);
+	GCC_DIAGNOSTIC_POP();
+
+	if (d_attr->store)
+		ret = d_attr->store(dhd, buf, count);
+	else
+		ret = -EIO;
+
+	return ret;
+
+}
+
+static struct sysfs_ops dhd_sysfs_dpc_bounds_ops = {
+	.show = dhd_dpc_bounds_show,
+	.store = dhd_dpc_bounds_store,
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
+static const struct attribute_group debug_dpc_bounds_group = {
+	.attrs = debug_dpc_bounds_attrs
+};
+static const struct attribute_group *debug_dpc_bounds_groups[] = {
+	&debug_dpc_bounds_group,
+	NULL
+};
+#endif /* LINUX_VER >= 5.18 */
+
+static struct kobj_type dhd_dpc_bounds_ktype = {
+	.sysfs_ops = &dhd_sysfs_dpc_bounds_ops,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 18, 0)
+	.default_groups = debug_dpc_bounds_groups,
+#else
+	.default_attrs = debug_dpc_bounds_attrs,
+#endif /* LINUX_VER >= 5.18 */
+};
+
+/*
+ * *************************************
+ */
+
+#ifdef CSI_SUPPORT
+/* Function to show current ccode */
+static ssize_t read_csi_data(struct file *filp, struct kobject *kobj,
+	struct bin_attribute *bin_attr, char *buf, loff_t off, size_t count)
+{
+	dhd_info_t *dhd = to_dhd(kobj);
+	int n = 0;
+
+	n = dhd_csi_data_queue_polling(&dhd->pub, buf, (uint)count);
+	DHD_TRACE(("Dump data to file, size %d\n", n));
+
+	return n;
+}
+
+static struct bin_attribute dhd_attr_csi = {
+	.attr = {
+		.name = CONST_SYNA_DHD_CSI_OBJ_NAME,
+		.mode = 0660
+	},
+	.size = CONST_CSI_SYS_FILE_SIZE_MAX,
+	.read = read_csi_data,
+};
+#endif /* CSI_SUPPORT */
+
+/* Create a kobject and attach to sysfs interface */
+int dhd_sysfs_init(dhd_info_t *dhd)
+{
+	int ret = -1;
+
+	dhd->flag_kobj = 0x0;
+
+	if (dhd == NULL) {
+		DHD_ERROR(("%s(): dhd is NULL \r\n", __FUNCTION__));
+		return ret;
+	}
+
+	/* Initialize the kobject */
+	ret = kobject_init_and_add(&dhd->dhd_kobj, &dhd_ktype, NULL, "wifi" BUS_TYPE);
+	if (ret) {
+		kobject_put(&dhd->dhd_kobj);
+		DHD_ERROR(("%s(): Unable to allocate kobject \r\n", __FUNCTION__));
+		return ret;
+	} else {
+		dhd->flag_kobj |= 0x01;
+	}
+
+	/*
+	 * We are always responsible for sending the uevent that the kobject
+	 * was added to the system.
+	 */
+	kobject_uevent(&dhd->dhd_kobj, KOBJ_ADD);
+
+#ifdef DHD_LB
+	ret  = kobject_init_and_add(&dhd->dhd_lb_kobj,
+			&dhd_lb_ktype, &dhd->dhd_kobj, "lb");
+	if (ret) {
+		kobject_put(&dhd->dhd_lb_kobj);
+		DHD_ERROR(("%s(): Unable to allocate kobject for 'lb'\r\n", __FUNCTION__));
+		return ret;
+	} else {
+		dhd->flag_kobj |= 0x02;
+	}
+
+	kobject_uevent(&dhd->dhd_lb_kobj, KOBJ_ADD);
+#endif /* DHD_LB */
+
+	/* DPC bounds */
+	ret  = kobject_init_and_add(&dhd->dhd_dpc_bounds_kobj,
+			&dhd_dpc_bounds_ktype, &dhd->dhd_kobj, "dpc_bounds");
+	if (ret) {
+		kobject_put(&dhd->dhd_dpc_bounds_kobj);
+		DHD_ERROR(("%s(): Unable to allocate kobject for 'dpc_bounds'\r\n", __FUNCTION__));
+		return ret;
+	}
+	kobject_uevent(&dhd->dhd_dpc_bounds_kobj, KOBJ_ADD);
+
+#ifdef CSI_SUPPORT
+	ret = sysfs_create_bin_file(&dhd->dhd_kobj, &dhd_attr_csi);
+	if (ret) {
+		DHD_ERROR(("%s: can't create %s\n", __func__, dhd_attr_csi.attr.name));
+		return ret;
+	} else {
+		dhd->flag_kobj |= 0x04;
+	}
+#endif /* CSI_SUPPORT */
+
+	return ret;
+}
+
+/* Done with the kobject and detach the sysfs interface */
+void dhd_sysfs_exit(dhd_info_t *dhd)
+{
+	if (dhd == NULL) {
+		DHD_ERROR(("%s(): dhd is NULL \r\n", __FUNCTION__));
+		return;
+	}
+
+#ifdef CSI_SUPPORT
+	if (0x04 & dhd->flag_kobj) {
+		sysfs_remove_bin_file(&dhd->dhd_kobj, &dhd_attr_csi);
+	}
+#endif /* CSI_SUPPORT */
+
+#ifdef DHD_LB
+	if (0X02 & dhd->flag_kobj) {
+		kobject_put(&dhd->dhd_lb_kobj);
+	}
+#endif /* DHD_LB */
+
+	/* DPC bounds */
+	kobject_put(&dhd->dhd_dpc_bounds_kobj);
+
+	/* Release the kobject */
+	if (0X01 & dhd->flag_kobj) {
+		kobject_put(&dhd->dhd_kobj);
+	}
+
+	dhd->flag_kobj = 0X0;
+}
+
+#ifdef DHD_SUPPORT_HDM
+static ssize_t
+hdm_load_module(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
+{
+	int val = bcm_atoi(buf);
+
+	if (val == 1) {
+		DHD_ERROR(("%s : Load module from the hdm %d\n", __FUNCTION__, val));
+		dhd_module_init_hdm();
+	} else {
+		DHD_ERROR(("Module load triggered with invalid value : %d\n", val));
+	}
+
+	return count;
+}
+
+static struct kobj_attribute hdm_wlan_attr =
+	__ATTR(hdm_wlan_loader, 0660, NULL, hdm_load_module);
+
+void
+dhd_hdm_wlan_sysfs_init()
+{
+	DHD_ERROR(("export hdm_wlan_loader\n"));
+	if (sysfs_create_file(kernel_kobj, &hdm_wlan_attr.attr)) {
+		DHD_ERROR(("export hdm_load failed\n"));
+	}
+}
+
+void
+dhd_hdm_wlan_sysfs_deinit(struct work_struct *work)
+{
+	sysfs_remove_file(kernel_kobj,  &hdm_wlan_attr.attr);
+
+}
+#endif /* DHD_SUPPORT_HDM */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux_lb.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux_lb.c
@@ -0,0 +1,1549 @@
+/*
+ * Broadcom Dongle Host Driver (DHD), Linux-specific network interface
+ * Basically selected code segments from usb-cdc.c and usb-rndis.c
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <dhd_linux_priv.h>
+
+extern dhd_pub_t* g_dhd_pub;
+
+#if defined(DHD_LB)
+
+#ifdef DHD_LB_STATS
+#define DHD_NUM_NAPI_LATENCY_ROWS (17u)
+#define DHD_NAPI_LATENCY_SIZE (sizeof(uint64) * DHD_NUM_NAPI_LATENCY_ROWS)
+#endif /* DHD_LB_STATS */
+
+/* latency improvement */
+#define DHD_LB_ACTIVE_LOW_WATERMARK    3
+
+void
+dhd_lb_set_default_cpus(dhd_info_t *dhd)
+{
+	/* Default CPU allocation for the jobs */
+	atomic_set(&dhd->rx_napi_cpu, 1);
+	atomic_set(&dhd->tx_cpu, 2);
+	atomic_set(&dhd->net_tx_cpu, 0);
+	atomic_set(&dhd->dpc_cpu, 0);
+}
+
+void
+dhd_cpumasks_deinit(dhd_info_t *dhd)
+{
+	free_cpumask_var(dhd->cpumask_curr_avail);
+	free_cpumask_var(dhd->cpumask_primary);
+	free_cpumask_var(dhd->cpumask_primary_new);
+	free_cpumask_var(dhd->cpumask_secondary);
+	free_cpumask_var(dhd->cpumask_secondary_new);
+}
+
+int
+dhd_cpumasks_init(dhd_info_t *dhd)
+{
+	int id;
+	uint32 cpus, num_cpus = num_possible_cpus();
+	int ret = 0;
+
+	DHD_ERROR(("%s CPU masks primary(big)=0x%x secondary(little)=0x%x\n", __FUNCTION__,
+		DHD_LB_PRIMARY_CPUS, DHD_LB_SECONDARY_CPUS));
+
+	/* FIXME: If one alloc fails we must free_cpumask_var the previous */
+	if (!alloc_cpumask_var(&dhd->cpumask_curr_avail, GFP_KERNEL) ||
+	    !alloc_cpumask_var(&dhd->cpumask_primary, GFP_KERNEL) ||
+	    !alloc_cpumask_var(&dhd->cpumask_primary_new, GFP_KERNEL) ||
+	    !alloc_cpumask_var(&dhd->cpumask_secondary, GFP_KERNEL) ||
+	    !alloc_cpumask_var(&dhd->cpumask_secondary_new, GFP_KERNEL)) {
+		DHD_ERROR(("%s Failed to init cpumasks\n", __FUNCTION__));
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	cpumask_copy(dhd->cpumask_curr_avail, cpu_online_mask);
+	cpumask_clear(dhd->cpumask_primary);
+	cpumask_clear(dhd->cpumask_secondary);
+
+	if (num_cpus > 32) {
+		DHD_ERROR(("%s max cpus must be 32, %d too big\n", __FUNCTION__, num_cpus));
+		ASSERT(0);
+	}
+
+	cpus = DHD_LB_PRIMARY_CPUS;
+	for (id = 0; id < num_cpus; id++) {
+		if (isset(&cpus, id))
+			cpumask_set_cpu(id, dhd->cpumask_primary);
+	}
+
+	cpus = DHD_LB_SECONDARY_CPUS;
+	for (id = 0; id < num_cpus; id++) {
+		if (isset(&cpus, id))
+			cpumask_set_cpu(id, dhd->cpumask_secondary);
+	}
+
+	return ret;
+fail:
+	dhd_cpumasks_deinit(dhd);
+	return ret;
+}
+
+/*
+ * The CPU Candidacy Algorithm
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * The available CPUs for selection are divided into two groups
+ *  Primary Set - A CPU mask that carries the First Choice CPUs
+ *  Secondary Set - A CPU mask that carries the Second Choice CPUs.
+ *
+ * There are two types of Job, that needs to be assigned to
+ * the CPUs, from one of the above mentioned CPU group. The Jobs are
+ * 1) Rx Packet Processing - napi_cpu
+ *
+ * To begin with napi_cpu is on CPU0. Whenever a CPU goes
+ * on-line/off-line the CPU candidacy algorithm is triggerd. The candidacy
+ * algo tries to pickup the first available non boot CPU (CPU0) for napi_cpu.
+ *
+ */
+void dhd_select_cpu_candidacy(dhd_info_t *dhd)
+{
+	uint32 primary_available_cpus; /* count of primary available cpus */
+	uint32 secondary_available_cpus; /* count of secondary available cpus */
+	uint32 napi_cpu = 0; /* cpu selected for napi rx processing */
+	uint32 tx_cpu = 0; /* cpu selected for tx processing job */
+	uint32 dpc_cpu = atomic_read(&dhd->dpc_cpu);
+	uint32 net_tx_cpu = atomic_read(&dhd->net_tx_cpu);
+
+	cpumask_clear(dhd->cpumask_primary_new);
+	cpumask_clear(dhd->cpumask_secondary_new);
+
+	/*
+	 * Now select from the primary mask. Even if a Job is
+	 * already running on a CPU in secondary group, we still move
+	 * to primary CPU. So no conditional checks.
+	 */
+	cpumask_and(dhd->cpumask_primary_new, dhd->cpumask_primary,
+		dhd->cpumask_curr_avail);
+
+	cpumask_and(dhd->cpumask_secondary_new, dhd->cpumask_secondary,
+		dhd->cpumask_curr_avail);
+
+	/* Clear DPC cpu from new masks so that dpc cpu is not chosen for LB */
+	cpumask_clear_cpu(dpc_cpu, dhd->cpumask_primary_new);
+	cpumask_clear_cpu(dpc_cpu, dhd->cpumask_secondary_new);
+
+	/* Clear net_tx_cpu from new masks so that same is not chosen for LB */
+	cpumask_clear_cpu(net_tx_cpu, dhd->cpumask_primary_new);
+	cpumask_clear_cpu(net_tx_cpu, dhd->cpumask_secondary_new);
+
+	primary_available_cpus = cpumask_weight(dhd->cpumask_primary_new);
+
+#if defined(DHD_LB_HOST_CTRL)
+	/* Does not use promary cpus if DHD received affinity off cmd
+	*  from framework
+	*/
+	if (primary_available_cpus > 0 && dhd->permitted_primary_cpu)
+#else
+	if (primary_available_cpus > 0)
+#endif /* DHD_LB_HOST_CTRL */
+	{
+		napi_cpu = cpumask_first(dhd->cpumask_primary_new);
+
+		/* If no further CPU is available,
+		 * cpumask_next returns >= nr_cpu_ids
+		 */
+		tx_cpu = cpumask_next(napi_cpu, dhd->cpumask_primary_new);
+		if (tx_cpu >= nr_cpu_ids) {
+			/* If no CPU is available for tx processing in primary CPUs,
+			 * choose the same CPU with net_tx_cpu
+			 * in case net_tx_cpu is in primary CPUs.
+			 */
+			cpumask_and(dhd->cpumask_primary_new, dhd->cpumask_primary,
+					dhd->cpumask_curr_avail);
+
+			if (cpumask_test_cpu(net_tx_cpu, dhd->cpumask_primary_new)) {
+				tx_cpu = net_tx_cpu;
+				DHD_INFO(("%s If no CPU is for tx cpu, use net_tx_cpu %d\n",
+					__FUNCTION__, net_tx_cpu));
+			} else {
+				tx_cpu = 0;
+			}
+		}
+	}
+
+	DHD_INFO(("%s After primary CPU check napi_cpu %d tx_cpu %d\n",
+		__FUNCTION__, napi_cpu, tx_cpu));
+
+	/* -- Now check for the CPUs from the secondary mask -- */
+	secondary_available_cpus = cpumask_weight(dhd->cpumask_secondary_new);
+
+	DHD_INFO(("%s Available secondary cpus %d nr_cpu_ids %d\n",
+		__FUNCTION__, secondary_available_cpus, nr_cpu_ids));
+
+	if (secondary_available_cpus > 0) {
+		/* At this point if napi_cpu is unassigned it means no CPU
+		 * is online from Primary Group
+		 */
+#if defined(DHD_LB_TXP_LITTLE_CORE_CTRL)
+		/* Clear tx_cpu, so that it can be picked from little core */
+		tx_cpu = 0;
+#endif /* DHD_LB_TXP_LITTLE_CORE_CTRL */
+		if (napi_cpu == 0) {
+			napi_cpu = cpumask_first(dhd->cpumask_secondary_new);
+			tx_cpu = cpumask_next(napi_cpu, dhd->cpumask_secondary_new);
+		} else if (tx_cpu == 0) {
+			tx_cpu = cpumask_first(dhd->cpumask_secondary_new);
+		}
+	}
+
+	if ((primary_available_cpus == 0) &&
+		(secondary_available_cpus == 0)) {
+		/* No CPUs available from primary or secondary mask */
+		tx_cpu = napi_cpu = nr_cpu_ids - 1;
+	}
+
+	/* If no CPU was available for napi processing, choose CPU 0 */
+	if (napi_cpu >= nr_cpu_ids)
+		napi_cpu = 0;
+
+	/* If no CPU was available for tx processing, choose CPU 0 */
+	if (tx_cpu >= nr_cpu_ids)
+		tx_cpu = 0;
+
+	DHD_INFO(("%s After secondary CPU check napi_cpu %d tx_cpu %d nr cpu ids %d\n",
+		__FUNCTION__, napi_cpu, tx_cpu, nr_cpu_ids));
+
+	if (!cpu_online(napi_cpu)) {
+		napi_cpu = 0;
+	}
+	if (!cpu_online(tx_cpu)) {
+		tx_cpu = 0;
+	}
+
+	atomic_set(&dhd->rx_napi_cpu, napi_cpu);
+	atomic_set(&dhd->tx_cpu, tx_cpu);
+
+	return;
+}
+
+/*
+ * Function to handle CPU Hotplug notifications.
+ * One of the task it does is to trigger the CPU Candidacy algorithm
+ * for load balancing.
+ */
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
+
+int dhd_cpu_startup_callback(unsigned int cpu)
+{
+	dhd_info_t *dhd = g_dhd_pub->info;
+
+	if (!dhd || !(dhd->dhd_state & DHD_ATTACH_STATE_LB_ATTACH_DONE)) {
+		DHD_ERROR(("%s(): LB data is not initialized yet.\n",
+			__FUNCTION__));
+		return 0;
+	}
+
+	DHD_INFO(("%s(): \r\n cpu:%d", __FUNCTION__, cpu));
+	DHD_LB_STATS_INCR(dhd->cpu_online_cnt[cpu]);
+	cpumask_set_cpu(cpu, dhd->cpumask_curr_avail);
+	dhd_select_cpu_candidacy(dhd);
+
+	return 0;
+}
+
+int dhd_cpu_teardown_callback(unsigned int cpu)
+{
+	dhd_info_t *dhd = g_dhd_pub->info;
+
+	if (!dhd || !(dhd->dhd_state & DHD_ATTACH_STATE_LB_ATTACH_DONE)) {
+		DHD_ERROR(("%s(): LB data is not initialized yet.\n",
+			__FUNCTION__));
+		return 0;
+	}
+
+	DHD_INFO(("%s(): \r\n cpu:%d", __FUNCTION__, cpu));
+	DHD_LB_STATS_INCR(dhd->cpu_offline_cnt[cpu]);
+	cpumask_clear_cpu(cpu, dhd->cpumask_curr_avail);
+	dhd_select_cpu_candidacy(dhd);
+
+	return 0;
+}
+#else
+int
+dhd_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+	unsigned long int cpu = (unsigned long int)hcpu;
+	dhd_info_t *dhd;
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd = container_of(nfb, dhd_info_t, cpu_notifier);
+	GCC_DIAGNOSTIC_POP();
+
+	if (!dhd || !(dhd->dhd_state & DHD_ATTACH_STATE_LB_ATTACH_DONE)) {
+		DHD_INFO(("%s(): LB data is not initialized yet.\n",
+			__FUNCTION__));
+		return NOTIFY_BAD;
+	}
+
+	/* XXX: Do we need other action types ? */
+	switch (action)
+	{
+		case CPU_ONLINE:
+		case CPU_ONLINE_FROZEN:
+			DHD_LB_STATS_INCR(dhd->cpu_online_cnt[cpu]);
+			cpumask_set_cpu(cpu, dhd->cpumask_curr_avail);
+			dhd_select_cpu_candidacy(dhd);
+			break;
+
+		case CPU_DOWN_PREPARE:
+		case CPU_DOWN_PREPARE_FROZEN:
+			DHD_LB_STATS_INCR(dhd->cpu_offline_cnt[cpu]);
+			cpumask_clear_cpu(cpu, dhd->cpumask_curr_avail);
+			dhd_select_cpu_candidacy(dhd);
+			break;
+		default:
+			break;
+	}
+
+	return NOTIFY_OK;
+}
+#endif /* LINUX_VERSION_CODE < 4.10.0 */
+
+int dhd_register_cpuhp_callback(dhd_info_t *dhd)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
+	dhd->dhd_cpuhp_state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "dhd",
+		dhd_cpu_startup_callback, dhd_cpu_teardown_callback);
+
+	if (dhd->dhd_cpuhp_state < 0) {
+		DHD_ERROR(("%s(): cpuhp_setup_state failed %d RX LB won't happen \r\n",
+			__FUNCTION__, dhd->dhd_cpuhp_state));
+	}
+#else
+	/*
+	 * If we are able to initialize CPU masks, lets register to the
+	 * CPU Hotplug framework to change the CPU for each job dynamically
+	 * using candidacy algorithm.
+	 */
+	dhd->cpu_notifier.notifier_call = dhd_cpu_callback;
+	register_hotcpu_notifier(&dhd->cpu_notifier); /* Register a callback */
+#endif /* LINUX_VERSION_CODE < 4.10.0 */
+	return dhd->dhd_cpuhp_state;
+}
+
+int dhd_unregister_cpuhp_callback(dhd_info_t *dhd)
+{
+	int ret = 0;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
+	/* Don't want to call tear down while unregistering */
+	if (dhd->dhd_cpuhp_state >= 0) {
+		cpuhp_remove_state_nocalls(dhd->dhd_cpuhp_state);
+	}
+#else
+	if (dhd->cpu_notifier.notifier_call != NULL) {
+		unregister_cpu_notifier(&dhd->cpu_notifier);
+	}
+#endif /* LINUX_VERSION_CODE < 4.10.0 */
+	return ret;
+}
+
+#if defined(DHD_LB_STATS)
+void dhd_lb_stats_reset(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd;
+	int i, j, num_cpus = num_possible_cpus();
+
+	if (dhdp == NULL) {
+		DHD_ERROR(("%s dhd pub pointer is NULL \n",
+			__FUNCTION__));
+		return;
+	}
+
+	dhd = dhdp->info;
+	if (dhd == NULL) {
+		DHD_ERROR(("%s(): DHD pointer is NULL \n", __FUNCTION__));
+		return;
+	}
+
+	DHD_LB_STATS_CLR(dhd->dhd_dpc_cnt);
+	DHD_LB_STATS_CLR(dhd->napi_sched_cnt);
+
+	/* reset NAPI latency stats */
+	if (dhd->napi_latency) {
+		bzero(dhd->napi_latency, DHD_NAPI_LATENCY_SIZE);
+	}
+	/* reset NAPI per cpu stats */
+	if (dhd->napi_percpu_run_cnt) {
+		for (i = 0; i < num_cpus; i++) {
+			DHD_LB_STATS_CLR(dhd->napi_percpu_run_cnt[i]);
+		}
+	}
+
+	DHD_LB_STATS_CLR(dhd->rxc_sched_cnt);
+
+	if (dhd->rxc_percpu_run_cnt) {
+		for (i = 0; i < num_cpus; i++) {
+			DHD_LB_STATS_CLR(dhd->rxc_percpu_run_cnt[i]);
+		}
+	}
+
+	DHD_LB_STATS_CLR(dhd->txc_sched_cnt);
+
+	if (dhd->txc_percpu_run_cnt) {
+		for (i = 0; i < num_cpus; i++) {
+			DHD_LB_STATS_CLR(dhd->txc_percpu_run_cnt[i]);
+		}
+	}
+
+	if (dhd->txp_percpu_run_cnt) {
+		for (i = 0; i < num_cpus; i++) {
+			DHD_LB_STATS_CLR(dhd->txp_percpu_run_cnt[i]);
+		}
+	}
+
+	if (dhd->tx_start_percpu_run_cnt) {
+		for (i = 0; i < num_cpus; i++) {
+			DHD_LB_STATS_CLR(dhd->tx_start_percpu_run_cnt[i]);
+		}
+	}
+
+	for (j = 0; j < HIST_BIN_SIZE; j++) {
+		for (i = 0; i < num_cpus; i++) {
+			DHD_LB_STATS_CLR(dhd->napi_rx_hist[j][i]);
+		}
+	}
+
+	dhd->pub.lb_rxp_strt_thr_hitcnt = 0;
+	dhd->pub.lb_rxp_stop_thr_hitcnt = 0;
+
+	dhd->pub.lb_rxp_napi_sched_cnt = 0;
+	dhd->pub.lb_rxp_napi_complete_cnt = 0;
+	return;
+}
+
+void dhd_lb_stats_init(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd;
+	int i, j, num_cpus = num_possible_cpus();
+	int alloc_size = sizeof(uint32) * num_cpus;
+
+	if (dhdp == NULL) {
+		DHD_ERROR(("%s(): Invalid argument dhd pubb pointer is NULL \n",
+			__FUNCTION__));
+		return;
+	}
+
+	dhd = dhdp->info;
+	if (dhd == NULL) {
+		DHD_ERROR(("%s(): DHD pointer is NULL \n", __FUNCTION__));
+		return;
+	}
+
+	DHD_LB_STATS_CLR(dhd->dhd_dpc_cnt);
+	DHD_LB_STATS_CLR(dhd->napi_sched_cnt);
+
+	/* NAPI latency stats */
+	dhd->napi_latency = (uint64 *)MALLOCZ(dhdp->osh, DHD_NAPI_LATENCY_SIZE);
+	/* NAPI per cpu stats */
+	dhd->napi_percpu_run_cnt = (uint32 *)MALLOC(dhdp->osh, alloc_size);
+	if (!dhd->napi_percpu_run_cnt) {
+		DHD_ERROR(("%s(): napi_percpu_run_cnt malloc failed \n",
+			__FUNCTION__));
+		return;
+	}
+	for (i = 0; i < num_cpus; i++)
+		DHD_LB_STATS_CLR(dhd->napi_percpu_run_cnt[i]);
+
+	DHD_LB_STATS_CLR(dhd->rxc_sched_cnt);
+
+	dhd->rxc_percpu_run_cnt = (uint32 *)MALLOC(dhdp->osh, alloc_size);
+	if (!dhd->rxc_percpu_run_cnt) {
+		DHD_ERROR(("%s(): rxc_percpu_run_cnt malloc failed \n",
+			__FUNCTION__));
+		return;
+	}
+	for (i = 0; i < num_cpus; i++)
+		DHD_LB_STATS_CLR(dhd->rxc_percpu_run_cnt[i]);
+
+	DHD_LB_STATS_CLR(dhd->txc_sched_cnt);
+
+	dhd->txc_percpu_run_cnt = (uint32 *)MALLOC(dhdp->osh, alloc_size);
+	if (!dhd->txc_percpu_run_cnt) {
+		DHD_ERROR(("%s(): txc_percpu_run_cnt malloc failed \n",
+			__FUNCTION__));
+		return;
+	}
+	for (i = 0; i < num_cpus; i++)
+		DHD_LB_STATS_CLR(dhd->txc_percpu_run_cnt[i]);
+
+	dhd->cpu_online_cnt = (uint32 *)MALLOC(dhdp->osh, alloc_size);
+	if (!dhd->cpu_online_cnt) {
+		DHD_ERROR(("%s(): cpu_online_cnt malloc failed \n",
+			__FUNCTION__));
+		return;
+	}
+	for (i = 0; i < num_cpus; i++)
+		DHD_LB_STATS_CLR(dhd->cpu_online_cnt[i]);
+
+	dhd->cpu_offline_cnt = (uint32 *)MALLOC(dhdp->osh, alloc_size);
+	if (!dhd->cpu_offline_cnt) {
+		DHD_ERROR(("%s(): cpu_offline_cnt malloc failed \n",
+			__FUNCTION__));
+		return;
+	}
+	for (i = 0; i < num_cpus; i++)
+		DHD_LB_STATS_CLR(dhd->cpu_offline_cnt[i]);
+
+	dhd->txp_percpu_run_cnt = (uint32 *)MALLOC(dhdp->osh, alloc_size);
+	if (!dhd->txp_percpu_run_cnt) {
+		DHD_ERROR(("%s(): txp_percpu_run_cnt malloc failed \n",
+			__FUNCTION__));
+		return;
+	}
+	for (i = 0; i < num_cpus; i++)
+		DHD_LB_STATS_CLR(dhd->txp_percpu_run_cnt[i]);
+
+	dhd->tx_start_percpu_run_cnt = (uint32 *)MALLOC(dhdp->osh, alloc_size);
+	if (!dhd->tx_start_percpu_run_cnt) {
+		DHD_ERROR(("%s(): tx_start_percpu_run_cnt malloc failed \n",
+			__FUNCTION__));
+		return;
+	}
+	for (i = 0; i < num_cpus; i++)
+		DHD_LB_STATS_CLR(dhd->tx_start_percpu_run_cnt[i]);
+
+	for (j = 0; j < HIST_BIN_SIZE; j++) {
+		dhd->napi_rx_hist[j] = (uint32 *)MALLOC(dhdp->osh, alloc_size);
+		if (!dhd->napi_rx_hist[j]) {
+			DHD_ERROR(("%s(): dhd->napi_rx_hist[%d] malloc failed \n",
+				__FUNCTION__, j));
+			return;
+		}
+		for (i = 0; i < num_cpus; i++) {
+			DHD_LB_STATS_CLR(dhd->napi_rx_hist[j][i]);
+		}
+	}
+
+	dhd->pub.lb_rxp_strt_thr_hitcnt = 0;
+	dhd->pub.lb_rxp_stop_thr_hitcnt = 0;
+
+	dhd->pub.lb_rxp_napi_sched_cnt = 0;
+	dhd->pub.lb_rxp_napi_complete_cnt = 0;
+	return;
+}
+
+void dhd_lb_stats_deinit(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd;
+	int j, num_cpus = num_possible_cpus();
+	int alloc_size = sizeof(uint32) * num_cpus;
+
+	if (dhdp == NULL) {
+		DHD_ERROR(("%s(): Invalid argument dhd pubb pointer is NULL \n",
+			__FUNCTION__));
+		return;
+	}
+
+	dhd = dhdp->info;
+	if (dhd == NULL) {
+		DHD_ERROR(("%s(): DHD pointer is NULL \n", __FUNCTION__));
+		return;
+	}
+
+	if (dhd->napi_percpu_run_cnt) {
+		MFREE(dhdp->osh, dhd->napi_percpu_run_cnt, alloc_size);
+	}
+	if (dhd->rxc_percpu_run_cnt) {
+		MFREE(dhdp->osh, dhd->rxc_percpu_run_cnt, alloc_size);
+	}
+	if (dhd->txc_percpu_run_cnt) {
+		MFREE(dhdp->osh, dhd->txc_percpu_run_cnt, alloc_size);
+	}
+	if (dhd->cpu_online_cnt) {
+		MFREE(dhdp->osh, dhd->cpu_online_cnt, alloc_size);
+	}
+	if (dhd->cpu_offline_cnt) {
+		MFREE(dhdp->osh, dhd->cpu_offline_cnt, alloc_size);
+	}
+
+	if (dhd->txp_percpu_run_cnt) {
+		MFREE(dhdp->osh, dhd->txp_percpu_run_cnt, alloc_size);
+	}
+	if (dhd->tx_start_percpu_run_cnt) {
+		MFREE(dhdp->osh, dhd->tx_start_percpu_run_cnt, alloc_size);
+	}
+	if (dhd->napi_latency) {
+		MFREE(dhdp->osh, dhd->napi_latency, DHD_NAPI_LATENCY_SIZE);
+	}
+
+	for (j = 0; j < HIST_BIN_SIZE; j++) {
+		if (dhd->napi_rx_hist[j]) {
+			MFREE(dhdp->osh, dhd->napi_rx_hist[j], alloc_size);
+		}
+	}
+
+	return;
+}
+
+void dhd_lb_stats_dump_napi_latency(dhd_pub_t *dhdp,
+	struct bcmstrbuf *strbuf, uint64 *napi_latency)
+{
+	uint32 i;
+
+	bcm_bprintf(strbuf, "napi-latency(us): \t count\n");
+	for (i = 0; i < DHD_NUM_NAPI_LATENCY_ROWS; i++) {
+		bcm_bprintf(strbuf, "%16u: \t %llu\n", 1U<<i, napi_latency[i]);
+	}
+}
+
+void dhd_lb_stats_dump_histo(dhd_pub_t *dhdp,
+	struct bcmstrbuf *strbuf, uint32 **hist)
+{
+	int i, j;
+	uint32 *per_cpu_total;
+	uint32 total = 0;
+	uint32 num_cpus = num_possible_cpus();
+
+	per_cpu_total = (uint32 *)MALLOC(dhdp->osh, sizeof(uint32) * num_cpus);
+	if (!per_cpu_total) {
+		DHD_ERROR(("%s(): dhd->per_cpu_total malloc failed \n", __FUNCTION__));
+		return;
+	}
+	bzero(per_cpu_total, sizeof(uint32) * num_cpus);
+
+	bcm_bprintf(strbuf, "CPU: \t\t");
+	for (i = 0; i < num_cpus; i++)
+		bcm_bprintf(strbuf, "%d\t", i);
+	bcm_bprintf(strbuf, "\nBin\n");
+
+	for (i = 0; i < HIST_BIN_SIZE; i++) {
+		bcm_bprintf(strbuf, "%d:\t\t", 1<<i);
+		for (j = 0; j < num_cpus; j++) {
+			bcm_bprintf(strbuf, "%d\t", hist[i][j]);
+		}
+		bcm_bprintf(strbuf, "\n");
+	}
+	bcm_bprintf(strbuf, "Per CPU Total \t");
+	total = 0;
+	for (i = 0; i < num_cpus; i++) {
+		for (j = 0; j < HIST_BIN_SIZE; j++) {
+			per_cpu_total[i] += (hist[j][i] * (1<<j));
+		}
+		bcm_bprintf(strbuf, "%d\t", per_cpu_total[i]);
+		total += per_cpu_total[i];
+	}
+	bcm_bprintf(strbuf, "\nTotal\t\t%d \n", total);
+
+	if (per_cpu_total) {
+		MFREE(dhdp->osh, per_cpu_total, sizeof(uint32) * num_cpus);
+	}
+	return;
+}
+
+void dhd_lb_stats_dump_cpu_array(struct bcmstrbuf *strbuf, uint32 *p)
+{
+	int i, num_cpus = num_possible_cpus();
+
+	bcm_bprintf(strbuf, "CPU: \t\t");
+	for (i = 0; i < num_cpus; i++)
+		bcm_bprintf(strbuf, "%d\t", i);
+	bcm_bprintf(strbuf, "\n");
+
+	bcm_bprintf(strbuf, "Val: \t\t");
+	for (i = 0; i < num_cpus; i++)
+		bcm_bprintf(strbuf, "%u\t", *(p+i));
+	bcm_bprintf(strbuf, "\n");
+	return;
+}
+
+#ifdef DHD_MEM_STATS
+uint64 dhd_lb_mem_usage(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+{
+	dhd_info_t *dhd;
+	uint16 rxbufpost_alloc_sz;
+	uint16 rx_post_active = 0;
+	uint16 rx_cmpl_active = 0;
+	uint64 rx_path_memory_usage = 0;
+
+	if (dhdp == NULL || strbuf == NULL) {
+		DHD_ERROR(("%s(): Invalid argument dhdp %p strbuf %p \n",
+			__FUNCTION__, dhdp, strbuf));
+		return 0;
+	}
+
+	dhd = dhdp->info;
+	if (dhd == NULL) {
+		DHD_ERROR(("%s(): DHD pointer is NULL \n", __FUNCTION__));
+		return 0;
+	}
+	rxbufpost_alloc_sz = dhd_prot_get_rxbufpost_alloc_sz(dhdp);
+	if (rxbufpost_alloc_sz == 0) {
+		rxbufpost_alloc_sz = DHD_FLOWRING_RX_BUFPOST_PKTSZ;
+	}
+	rx_path_memory_usage = rxbufpost_alloc_sz * (skb_queue_len(&dhd->rx_emerge_queue) +
+		skb_queue_len(&dhd->rx_pend_queue) +
+		skb_queue_len(&dhd->rx_napi_queue) +
+		skb_queue_len(&dhd->rx_process_queue));
+	rx_post_active = dhd_prot_get_h2d_rx_post_active(dhdp);
+	if (rx_post_active != 0) {
+		rx_path_memory_usage += (rxbufpost_alloc_sz * rx_post_active);
+	}
+
+	rx_cmpl_active = dhd_prot_get_d2h_rx_cpln_active(dhdp);
+	if (rx_cmpl_active != 0) {
+		rx_path_memory_usage += (rxbufpost_alloc_sz * rx_cmpl_active);
+	}
+
+	dhdp->rxpath_mem = rx_path_memory_usage;
+	bcm_bprintf(strbuf, "\nrxbufpost_alloc_sz: %d rx_post_active: %d rx_cmpl_active: %d "
+		"emerge_queue_len: %d pend_queue_len: %d napi_queue_len: %d"
+		" process_queue_len: %d\n",
+		rxbufpost_alloc_sz, rx_post_active, rx_cmpl_active,
+		skb_queue_len(&dhd->rx_emerge_queue), skb_queue_len(&dhd->rx_pend_queue),
+		skb_queue_len(&dhd->rx_napi_queue), skb_queue_len(&dhd->rx_process_queue));
+	bcm_bprintf(strbuf, "DHD rx-path memory_usage: %llubytes %lluKB \n",
+		rx_path_memory_usage, (rx_path_memory_usage/ 1024));
+	return rx_path_memory_usage;
+}
+#endif /* DHD_MEM_STATS */
+
+void dhd_lb_stats_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
+{
+	dhd_info_t *dhd;
+
+	if (dhdp == NULL || strbuf == NULL) {
+		DHD_ERROR(("%s(): Invalid argument dhdp %p strbuf %p \n",
+			__FUNCTION__, dhdp, strbuf));
+		return;
+	}
+
+	dhd = dhdp->info;
+	if (dhd == NULL) {
+		DHD_ERROR(("%s(): DHD pointer is NULL \n", __FUNCTION__));
+		return;
+	}
+
+	bcm_bprintf(strbuf, "\nLoad Balancing/NAPI stats:\n==========================\n");
+	bcm_bprintf(strbuf, "\ncpu_online_cnt:\n");
+	dhd_lb_stats_dump_cpu_array(strbuf, dhd->cpu_online_cnt);
+
+	bcm_bprintf(strbuf, "\ncpu_offline_cnt:\n");
+	dhd_lb_stats_dump_cpu_array(strbuf, dhd->cpu_offline_cnt);
+
+	bcm_bprintf(strbuf, "\nsched_cnt: dhd_dpc %u napi %u rxc %u txc %u\n",
+		dhd->dhd_dpc_cnt, dhd->napi_sched_cnt, dhd->rxc_sched_cnt,
+		dhd->txc_sched_cnt);
+
+	bcm_bprintf(strbuf, "\nCPUs: dpc_cpu %u napi_cpu %u net_tx_cpu %u tx_cpu %u\n",
+		atomic_read(&dhd->dpc_cpu),
+		atomic_read(&dhd->rx_napi_cpu),
+		atomic_read(&dhd->net_tx_cpu),
+		atomic_read(&dhd->tx_cpu));
+
+#ifdef DHD_LB_RXP
+	bcm_bprintf(strbuf, "\nnapi_percpu_run_cnt:\n");
+	dhd_lb_stats_dump_cpu_array(strbuf, dhd->napi_percpu_run_cnt);
+	bcm_bprintf(strbuf, "\nNAPI Packets Received Histogram:\n");
+	dhd_lb_stats_dump_histo(dhdp, strbuf, dhd->napi_rx_hist);
+	bcm_bprintf(strbuf, "\nNAPI poll latency stats ie from napi schedule to napi execution\n");
+	dhd_lb_stats_dump_napi_latency(dhdp, strbuf, dhd->napi_latency);
+
+	bcm_bprintf(strbuf, "\nlb_rxp_stop_thr_hitcnt: %llu lb_rxp_strt_thr_hitcnt: %llu"
+		" rx_dma_stall_hc_ignore_cnt: %llu\n",
+		dhdp->lb_rxp_stop_thr_hitcnt, dhdp->lb_rxp_strt_thr_hitcnt,
+		dhdp->rx_dma_stall_hc_ignore_cnt);
+	bcm_bprintf(strbuf, "\nlb_rxp_napi_sched_cnt: %llu lb_rxp_napi_omplete_cnt: %llu\n",
+		dhdp->lb_rxp_napi_sched_cnt, dhdp->lb_rxp_napi_complete_cnt);
+#endif /* DHD_LB_RXP */
+
+#ifdef DHD_LB_TXP
+	bcm_bprintf(strbuf, "\ntxp_percpu_run_cnt:\n");
+	dhd_lb_stats_dump_cpu_array(strbuf, dhd->txp_percpu_run_cnt);
+
+	bcm_bprintf(strbuf, "\ntx_start_percpu_run_cnt:\n");
+	dhd_lb_stats_dump_cpu_array(strbuf, dhd->tx_start_percpu_run_cnt);
+#endif /* DHD_LB_TXP */
+	bcm_bprintf(strbuf, "\n");
+}
+
+void dhd_lb_stats_update_napi_latency(uint64 *bin, uint32 latency)
+{
+	uint64 *p;
+	uint32 bin_power;
+	bin_power = next_larger_power2(latency);
+
+	switch (bin_power) {
+		case   1: p = bin + 0; break;
+		case   2: p = bin + 1; break;
+		case   4: p = bin + 2; break;
+		case   8: p = bin + 3; break;
+		case  16: p = bin + 4; break;
+		case  32: p = bin + 5; break;
+		case  64: p = bin + 6; break;
+		case 128: p = bin + 7; break;
+		case 256: p = bin + 8; break;
+		case 512: p = bin + 9; break;
+		case 1024: p = bin + 10; break;
+		case 2048: p = bin + 11; break;
+		case 4096: p = bin + 12; break;
+		case 8192: p = bin + 13; break;
+		case 16384: p = bin + 14; break;
+		case 32768: p = bin + 15; break;
+		default : p = bin + 16; break;
+	}
+	ASSERT((p - bin) < DHD_NUM_NAPI_LATENCY_ROWS);
+	*p = *p + 1;
+	return;
+
+}
+
+void dhd_lb_stats_update_histo(uint32 **bin, uint32 count, uint32 cpu)
+{
+	uint32 bin_power;
+	uint32 *p;
+	bin_power = next_larger_power2(count);
+
+	switch (bin_power) {
+		case   1: p = bin[0] + cpu; break;
+		case   2: p = bin[1] + cpu; break;
+		case   4: p = bin[2] + cpu; break;
+		case   8: p = bin[3] + cpu; break;
+		case  16: p = bin[4] + cpu; break;
+		case  32: p = bin[5] + cpu; break;
+		case  64: p = bin[6] + cpu; break;
+		case 128: p = bin[7] + cpu; break;
+		default : p = bin[8] + cpu; break;
+	}
+
+	*p = *p + 1;
+	return;
+}
+
+void dhd_lb_stats_update_napi_histo(dhd_pub_t *dhdp, uint32 count)
+{
+	int cpu;
+	dhd_info_t *dhd = dhdp->info;
+
+	cpu = get_cpu();
+	put_cpu();
+	dhd_lb_stats_update_histo(dhd->napi_rx_hist, count, cpu);
+
+	return;
+}
+
+void dhd_lb_stats_update_txc_histo(dhd_pub_t *dhdp, uint32 count)
+{
+	int cpu;
+	dhd_info_t *dhd = dhdp->info;
+
+	cpu = get_cpu();
+	put_cpu();
+	dhd_lb_stats_update_histo(dhd->txc_hist, count, cpu);
+
+	return;
+}
+
+void dhd_lb_stats_update_rxc_histo(dhd_pub_t *dhdp, uint32 count)
+{
+	int cpu;
+	dhd_info_t *dhd = dhdp->info;
+
+	cpu = get_cpu();
+	put_cpu();
+	dhd_lb_stats_update_histo(dhd->rxc_hist, count, cpu);
+
+	return;
+}
+
+void dhd_lb_stats_txc_percpu_cnt_incr(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = dhdp->info;
+	DHD_LB_STATS_PERCPU_ARR_INCR(dhd->txc_percpu_run_cnt);
+}
+
+void dhd_lb_stats_rxc_percpu_cnt_incr(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = dhdp->info;
+	DHD_LB_STATS_PERCPU_ARR_INCR(dhd->rxc_percpu_run_cnt);
+}
+#endif /* DHD_LB_STATS */
+
+/**
+ * dhd_tasklet_schedule - Function that runs in IPI context of the destination
+ * CPU and schedules a tasklet.
+ * @tasklet: opaque pointer to the tasklet
+ */
+INLINE void
+dhd_tasklet_schedule(void *tasklet)
+{
+	tasklet_schedule((struct tasklet_struct *)tasklet);
+}
+
+/**
+ * dhd_work_schedule_on - Executes the passed work in a given CPU
+ * @work: work to be scheduled
+ * @on_cpu: cpu core id
+ *
+ * If the requested cpu is online, then an IPI is sent to this cpu via the
+ * schedule_work_on and the work function
+ * will be invoked to schedule the specified work on the requested CPU.
+ */
+
+INLINE void
+dhd_work_schedule_on(struct work_struct *work, int on_cpu)
+{
+	schedule_work_on(on_cpu, work);
+}
+
+INLINE void
+dhd_delayed_work_schedule_on(struct delayed_work *dwork, int on_cpu, ulong delay)
+{
+	schedule_delayed_work_on(on_cpu, dwork, delay);
+}
+
+#if defined(DHD_LB_TXP)
+void dhd_tx_dispatcher_work(struct work_struct * work)
+{
+	struct dhd_info *dhd;
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd = container_of(work, struct dhd_info, tx_dispatcher_work);
+	GCC_DIAGNOSTIC_POP();
+
+	dhd_tasklet_schedule(&dhd->tx_tasklet);
+}
+
+/**
+ * dhd_lb_tx_dispatch - load balance by dispatching the tx_tasklet
+ * on another cpu. The tx_tasklet will take care of actually putting
+ * the skbs into appropriate flow ring and ringing H2D interrupt
+ *
+ * @dhdp: pointer to dhd_pub object
+ */
+void
+dhd_lb_tx_dispatch(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = dhdp->info;
+	int curr_cpu;
+	int tx_cpu;
+	int prev_net_tx_cpu;
+
+	/*
+	 * Get cpu will disable pre-ermption and will not allow any cpu to go offline
+	 * and call put_cpu() only after scheduling rx_napi_dispatcher_work.
+	 */
+	curr_cpu = get_cpu();
+
+	/* Record the CPU in which the TX request from Network stack came */
+	prev_net_tx_cpu = atomic_read(&dhd->net_tx_cpu);
+	atomic_set(&dhd->net_tx_cpu, curr_cpu);
+
+	tx_cpu = atomic_read(&dhd->tx_cpu);
+
+	/*
+	 * Avoid cpu candidacy, if override is set via sysfs for changing cpu mannually
+	 */
+	if (dhd->dhd_lb_candidacy_override) {
+		if (!cpu_online(tx_cpu)) {
+			tx_cpu = curr_cpu;
+		}
+	} else {
+		/*
+		 * Now if the NET TX has scheduled in the same CPU
+		 * that is chosen for Tx processing
+		 * OR scheduled on different cpu than previously it was scheduled,
+		 * OR if tx_cpu is offline,
+		 * Call cpu candidacy algorithm to recompute tx_cpu.
+		 */
+		if ((curr_cpu == tx_cpu) || (curr_cpu != prev_net_tx_cpu) ||
+			!cpu_online(tx_cpu)) {
+			/* Re compute LB CPUs */
+			dhd_select_cpu_candidacy(dhd);
+			/* Use updated tx cpu */
+			tx_cpu = atomic_read(&dhd->tx_cpu);
+		}
+	}
+	/*
+	 * Schedule tx_dispatcher_work to on the cpu which
+	 * in turn will schedule tx_tasklet.
+	 */
+	dhd_work_schedule_on(&dhd->tx_dispatcher_work, tx_cpu);
+
+	put_cpu();
+}
+#endif /* DHD_LB_TXP */
+
+#if defined(DHD_LB_RXP)
+
+/**
+ * dhd_napi_poll - Load balance napi poll function to process received
+ * packets and send up the network stack using netif_receive_skb()
+ *
+ * @napi: napi object in which context this poll function is invoked
+ * @budget: number of packets to be processed.
+ *
+ * Fetch the dhd_info given the rx_napi_struct. Move all packets from the
+ * rx_napi_queue into a local rx_process_queue (lock and queue move and unlock).
+ * Dequeue each packet from head of rx_process_queue, fetch the ifid from the
+ * packet tag and sendup.
+ */
+int
+dhd_napi_poll(struct napi_struct *napi, int budget)
+{
+	int ifid;
+	const int pkt_count = 1;
+	const int chan = 0;
+	struct sk_buff * skb;
+	unsigned long flags;
+	struct dhd_info *dhd;
+	int processed = 0;
+	int dpc_cpu;
+#ifdef DHD_LB_STATS
+	uint32 napi_latency;
+#endif /* DHD_LB_STATS */
+
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd = container_of(napi, struct dhd_info, rx_napi_struct);
+	GCC_DIAGNOSTIC_POP();
+
+#ifdef DHD_LB_STATS
+	napi_latency = (uint32)(OSL_SYSUPTIME_US() - dhd->napi_schedule_time);
+	dhd_lb_stats_update_napi_latency(dhd->napi_latency, napi_latency);
+#endif /* DHD_LB_STATS */
+	DHD_INFO(("%s napi_queue<%d> budget<%d>\n",
+		__FUNCTION__, skb_queue_len(&dhd->rx_napi_queue), budget));
+
+	/*
+	 * Extract the entire rx_napi_queue into another rx_process_queue
+	 * and process only 'budget' number of skbs from rx_process_queue.
+	 * If there are more items to be processed, napi poll will be rescheduled
+	 * During the next iteration, next set of skbs from
+	 * rx_napi_queue will be extracted and attached to the tail of rx_process_queue.
+	 * Again budget number of skbs will be processed from rx_process_queue.
+	 * If there are less than budget number of skbs in rx_process_queue,
+	 * call napi_complete to stop rescheduling napi poll.
+	 */
+	DHD_RX_NAPI_QUEUE_LOCK(&dhd->rx_napi_queue.lock, flags);
+	skb_queue_splice_tail_init(&dhd->rx_napi_queue, &dhd->rx_process_queue);
+	DHD_RX_NAPI_QUEUE_UNLOCK(&dhd->rx_napi_queue.lock, flags);
+
+	while ((processed < budget) && (skb = __skb_dequeue(&dhd->rx_process_queue)) != NULL) {
+		OSL_PREFETCH(skb->data);
+
+		ifid = DHD_PKTTAG_IFID((dhd_pkttag_fr_t *)PKTTAG(skb));
+
+		DHD_INFO(("%s dhd_rx_frame pkt<%p> ifid<%d>\n",
+			__FUNCTION__, skb, ifid));
+
+		dhd_rx_frame(&dhd->pub, ifid, skb, pkt_count, chan);
+		processed++;
+	}
+
+	if (atomic_read(&dhd->pub.lb_rxp_flow_ctrl) &&
+		(dhd_lb_rxp_process_qlen(&dhd->pub) <= dhd->pub.lb_rxp_strt_thr)) {
+		/*
+		 * If the dpc CPU is online Schedule dhd_dpc_dispatcher_work on the dpc cpu which
+		 * in turn will schedule dpc tasklet. Else schedule dpc takslet.
+		 */
+		get_cpu();
+		dpc_cpu = atomic_read(&dhd->dpc_cpu);
+		if (!cpu_online(dpc_cpu)) {
+			dhd_tasklet_schedule(&dhd->tasklet);
+		} else {
+			dhd_delayed_work_schedule_on(&dhd->dhd_dpc_dispatcher_work, dpc_cpu, 0);
+		}
+		put_cpu();
+	}
+	DHD_LB_STATS_UPDATE_NAPI_HISTO(&dhd->pub, processed);
+
+	DHD_INFO(("%s processed %d\n", __FUNCTION__, processed));
+
+	/*
+	 * Signal napi complete only when no more packets are processed and
+	 * none are left in the enqueued queue.
+	 */
+	if ((processed == 0) && (skb_queue_len(&dhd->rx_napi_queue) == 0)) {
+		napi_complete(napi);
+#ifdef DHD_LB_STATS
+		dhd->pub.lb_rxp_napi_complete_cnt++;
+#endif /* DHD_LB_STATS */
+		DHD_GENERAL_LOCK(&dhd->pub, flags);
+		DHD_BUS_BUSY_CLEAR_IN_NAPI(&dhd->pub);
+		DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+		return 0;
+	}
+
+#ifdef DHD_LB_STATS
+	dhd->napi_schedule_time = OSL_SYSUPTIME_US();
+#endif /* DHD_LB_STATS */
+
+	/* Return budget so that it gets rescheduled immediately */
+	return budget;
+}
+
+/**
+ * dhd_napi_schedule - Place the napi struct into the current cpus softnet napi
+ * poll list. This function may be invoked via the smp_call_function_single
+ * from a remote CPU.
+ *
+ * This function will essentially invoke __raise_softirq_irqoff(NET_RX_SOFTIRQ)
+ * after the napi_struct is added to the softnet data's poll_list
+ *
+ * @info: pointer to a dhd_info struct
+ */
+static void
+dhd_napi_schedule(void *info)
+{
+	dhd_info_t *dhd = (dhd_info_t *)info;
+	unsigned long flags;
+
+	DHD_INFO(("%s rx_napi_struct<%p> on cpu<%d>\n",
+		__FUNCTION__, &dhd->rx_napi_struct, atomic_read(&dhd->rx_napi_cpu)));
+
+	/* On Android platform, napi prevention during suspend in progress causes
+	 * rx performance drop of ~5Mbs(SWWLAN-349763).
+	 * So, excludes this prevention for Android platform.
+	 */
+#ifndef OEM_ANDROID
+	DHD_GENERAL_LOCK(&dhd->pub, flags);
+
+	if (DHD_BUS_BUSY_CHECK_SUSPEND_IN_PROGRESS(&dhd->pub)) {
+		DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+		return;
+	}
+
+	DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+#endif /* OEM_ANDROID */
+
+	/* add napi_struct to softnet data poll list and raise NET_RX_SOFTIRQ */
+	if (napi_schedule_prep(&dhd->rx_napi_struct)) {
+
+		/*
+		 * Set busbusystate in NAPI, which will be cleared after
+		 * napi_complete from napi_poll context
+		 */
+		DHD_GENERAL_LOCK(&dhd->pub, flags);
+		DHD_BUS_BUSY_SET_IN_NAPI(&dhd->pub);
+		DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+
+#ifdef DHD_LB_STATS
+		dhd->napi_schedule_time = OSL_SYSUPTIME_US();
+		dhd->pub.lb_rxp_napi_sched_cnt++;
+#endif /* DHD_LB_STATS */
+		__napi_schedule(&dhd->rx_napi_struct);
+#ifdef WAKEUP_KSOFTIRQD_POST_NAPI_SCHEDULE
+		raise_softirq(NET_RX_SOFTIRQ);
+#endif /* WAKEUP_KSOFTIRQD_POST_NAPI_SCHEDULE */
+	}
+
+	/*
+	 * If the rx_napi_struct was already running, then we let it complete
+	 * processing all its packets. The rx_napi_struct may only run on one
+	 * core at a time, to avoid out-of-order handling.
+	 */
+}
+
+/*
+ * Call get_online_cpus/put_online_cpus around dhd_napi_schedule_on
+ * Why should we do this?
+ * The candidacy algorithm is run from the call back function
+ * registered to CPU hotplug notifier. This call back happens from Worker
+ * context. The dhd_napi_schedule_on is also from worker context.
+ * Note that both of this can run on two different CPUs at the same time.
+ * So we can possibly have a window where a given CPUn is being brought
+ * down from CPUm while we try to run a function on CPUn.
+ * To prevent this its better have the whole code to execute an SMP
+ * function under get_online_cpus.
+ * This function call ensures that hotplug mechanism does not kick-in
+ * until we are done dealing with online CPUs
+ * If the hotplug worker is already running, no worries because the
+ * candidacy algo would then reflect the same in dhd->rx_napi_cpu.
+ *
+ * The below mentioned code structure is proposed in
+ * https://www.kernel.org/doc/Documentation/cpu-hotplug.txt
+ * for the question
+ * Q: I need to ensure that a particular cpu is not removed when there is some
+ *    work specific to this cpu is in progress
+ *
+ * According to the documentation calling get_online_cpus is NOT required, if
+ * we are running from tasklet context. Since dhd_rx_napi_dispatcher_work can
+ * run from Work Queue context we have to call these functions
+ */
+void dhd_rx_napi_dispatcher_work(struct work_struct * work)
+{
+	struct dhd_info *dhd;
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	dhd = container_of(work, struct dhd_info, rx_napi_dispatcher_work);
+	GCC_DIAGNOSTIC_POP();
+
+	dhd_napi_schedule(dhd);
+}
+
+/**
+ * dhd_lb_rx_napi_dispatch - load balance by dispatching the rx_napi_struct
+ * to run on another CPU. The rx_napi_struct's poll function will retrieve all
+ * the packets enqueued into the rx_napi_queue and sendup.
+ * The producer's rx packet queue is appended to the rx_napi_queue before
+ * dispatching the rx_napi_struct.
+ */
+void
+dhd_lb_rx_napi_dispatch(dhd_pub_t *dhdp)
+{
+	unsigned long flags;
+	dhd_info_t *dhd = dhdp->info;
+	int curr_cpu;
+	int rx_napi_cpu;
+	int prev_dpc_cpu;
+
+	if (dhd->rx_napi_netdev == NULL) {
+		DHD_ERROR(("%s: dhd->rx_napi_netdev is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	DHD_INFO(("%s append napi_queue<%d> pend_queue<%d>\n", __FUNCTION__,
+		skb_queue_len(&dhd->rx_napi_queue), skb_queue_len(&dhd->rx_pend_queue)));
+
+	/* append the producer's queue of packets to the napi's rx process queue */
+	DHD_RX_NAPI_QUEUE_LOCK(&dhd->rx_napi_queue.lock, flags);
+	skb_queue_splice_tail_init(&dhd->rx_pend_queue, &dhd->rx_napi_queue);
+	DHD_RX_NAPI_QUEUE_UNLOCK(&dhd->rx_napi_queue.lock, flags);
+
+	/* If sysfs lb_rxp_active is not set, schedule on current cpu */
+	if (!atomic_read(&dhd->lb_rxp_active) ||
+		(skb_queue_len(&dhd->rx_napi_queue) < DHD_LB_ACTIVE_LOW_WATERMARK))
+	{
+		dhd_napi_schedule(dhd);
+		return;
+	}
+
+	/*
+	 * Get cpu will disable pre-ermption and will not allow any cpu to go offline
+	 * and call put_cpu() only after scheduling rx_napi_dispatcher_work.
+	 */
+	curr_cpu = get_cpu();
+
+	prev_dpc_cpu = atomic_read(&dhd->prev_dpc_cpu);
+
+	rx_napi_cpu = atomic_read(&dhd->rx_napi_cpu);
+
+	/*
+	 * Avoid cpu candidacy, if override is set via sysfs for changing cpu mannually
+	 */
+	if (dhd->dhd_lb_candidacy_override) {
+		if (!cpu_online(rx_napi_cpu)) {
+			rx_napi_cpu = curr_cpu;
+		}
+	} else {
+		/*
+		 * Now if the DPC has scheduled in the same CPU
+		 * that is chosen for Rx napi processing
+		 * OR scheduled on different cpu than previously it was scheduled,
+		 * OR if rx_napi_cpu is offline,
+		 * Call cpu candidacy algorithm to recompute napi_cpu.
+		 */
+		if ((curr_cpu == rx_napi_cpu) || (curr_cpu != prev_dpc_cpu) ||
+			!cpu_online(rx_napi_cpu)) {
+			/* Re compute LB CPUs */
+			dhd_select_cpu_candidacy(dhd);
+			/* Use updated napi cpu */
+			rx_napi_cpu = atomic_read(&dhd->rx_napi_cpu);
+		}
+
+	}
+
+	DHD_INFO(("%s : schedule to curr_cpu : %d, rx_napi_cpu : %d\n",
+		__FUNCTION__, curr_cpu, rx_napi_cpu));
+	dhd_work_schedule_on(&dhd->rx_napi_dispatcher_work, rx_napi_cpu);
+	DHD_LB_STATS_INCR(dhd->napi_sched_cnt);
+
+	put_cpu();
+}
+
+/**
+ * dhd_rx_emerge_enqueue - Enqueue the packet into the ememrgency queue for repost
+ */
+void
+dhd_rx_emerge_enqueue(dhd_pub_t *dhdp, void *pkt)
+{
+	dhd_info_t *dhd = dhdp->info;
+	skb_queue_tail(&dhd->rx_emerge_queue, pkt);
+}
+
+/**
+ * dhd_rx_emerge_dequeue - Deueue the packet from the emergency queue for repost
+ */
+void *
+dhd_rx_emerge_dequeue(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = dhdp->info;
+	return skb_dequeue(&dhd->rx_emerge_queue);
+}
+
+/**
+ * dhd_lb_rx_pkt_enqueue - Enqueue the packet into the producer's queue
+ */
+void
+dhd_lb_rx_pkt_enqueue(dhd_pub_t *dhdp, void *pkt, int ifidx)
+{
+	dhd_info_t *dhd = dhdp->info;
+
+	DHD_INFO(("%s enqueue pkt<%p> ifidx<%d> pend_queue<%d>\n", __FUNCTION__,
+		pkt, ifidx, skb_queue_len(&dhd->rx_pend_queue)));
+	DHD_PKTTAG_SET_IFID((dhd_pkttag_fr_t *)PKTTAG(pkt), ifidx);
+	__skb_queue_tail(&dhd->rx_pend_queue, pkt);
+	DHD_LB_STATS_PERCPU_ARR_INCR(dhd->napi_percpu_run_cnt);
+}
+
+unsigned long
+dhd_read_lb_rxp(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = dhdp->info;
+	return atomic_read(&dhd->lb_rxp_active);
+}
+
+uint32
+dhd_lb_rxp_process_qlen(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = dhdp->info;
+	return skb_queue_len(&dhd->rx_process_queue);
+}
+#endif /* DHD_LB_RXP */
+
+#if defined(DHD_LB_TXP)
+int
+BCMFASTPATH(dhd_lb_sendpkt)(dhd_info_t *dhd, struct net_device *net,
+	int ifidx, void *skb)
+{
+	DHD_LB_STATS_PERCPU_ARR_INCR(dhd->tx_start_percpu_run_cnt);
+
+	/* If the feature is disabled run-time do TX from here */
+	if (atomic_read(&dhd->lb_txp_active) == 0) {
+		DHD_LB_STATS_PERCPU_ARR_INCR(dhd->txp_percpu_run_cnt);
+		 return __dhd_sendpkt(&dhd->pub, ifidx, skb);
+	}
+
+	/* Store the address of net device and interface index in the Packet tag */
+	DHD_LB_TX_PKTTAG_SET_NETDEV((dhd_tx_lb_pkttag_fr_t *)PKTTAG(skb), net);
+	DHD_LB_TX_PKTTAG_SET_IFIDX((dhd_tx_lb_pkttag_fr_t *)PKTTAG(skb), ifidx);
+
+	/* Enqueue the skb into tx_pend_queue */
+	skb_queue_tail(&dhd->tx_pend_queue, skb);
+
+	DHD_TRACE(("%s(): Added skb %p for netdev %p \r\n", __FUNCTION__, skb, net));
+
+	/* Dispatch the Tx job to be processed by the tx_tasklet */
+	dhd_lb_tx_dispatch(&dhd->pub);
+
+	return NETDEV_TX_OK;
+}
+#endif /* DHD_LB_TXP */
+
+#ifdef DHD_LB_TXP
+#ifndef DHD_LB_TXBOUND
+#define DHD_LB_TXBOUND	64
+#endif
+/*
+ * Function that performs the TX processing on a given CPU
+ */
+bool
+dhd_lb_tx_process(dhd_info_t *dhd)
+{
+	struct sk_buff *skb;
+	int cnt = 0;
+	struct net_device *net;
+	int ifidx;
+	bool resched = FALSE;
+
+	DHD_TRACE(("%s(): TX Processing \r\n", __FUNCTION__));
+	if (dhd == NULL) {
+		DHD_ERROR((" Null pointer DHD \r\n"));
+		return resched;
+	}
+
+	BCM_REFERENCE(net);
+
+	DHD_LB_STATS_PERCPU_ARR_INCR(dhd->txp_percpu_run_cnt);
+
+	/* Base Loop to perform the actual Tx */
+	do {
+		skb = skb_dequeue(&dhd->tx_pend_queue);
+		if (skb == NULL) {
+			DHD_TRACE(("Dequeued a Null Packet \r\n"));
+			break;
+		}
+		cnt++;
+
+		net =  DHD_LB_TX_PKTTAG_NETDEV((dhd_tx_lb_pkttag_fr_t *)PKTTAG(skb));
+		ifidx = DHD_LB_TX_PKTTAG_IFIDX((dhd_tx_lb_pkttag_fr_t *)PKTTAG(skb));
+
+		DHD_TRACE(("Processing skb %p for net %p index %d \r\n", skb,
+			net, ifidx));
+
+		__dhd_sendpkt(&dhd->pub, ifidx, skb);
+
+		if (cnt >= DHD_LB_TXBOUND) {
+			resched = TRUE;
+			break;
+		}
+
+	} while (1);
+
+	DHD_INFO(("%s(): Processed %d packets \r\n", __FUNCTION__, cnt));
+
+	return resched;
+}
+
+void
+dhd_lb_tx_handler(unsigned long data)
+{
+	dhd_info_t *dhd = (dhd_info_t *)data;
+
+	if (dhd_lb_tx_process(dhd)) {
+		dhd_tasklet_schedule(&dhd->tx_tasklet);
+	}
+}
+
+#endif /* DHD_LB_TXP */
+#endif /* DHD_LB */
+
+#if defined(SET_PCIE_IRQ_CPU_CORE) || defined(DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON)
+void
+dhd_irq_set_affinity(dhd_pub_t *dhdp, const struct cpumask *cpumask)
+{
+	unsigned int irq = (unsigned int)-1;
+	int err = BCME_OK;
+
+	if (!dhdp) {
+		DHD_ERROR(("%s : dhdp is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	if (!dhdp->bus) {
+		DHD_ERROR(("%s : bus is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	DHD_ERROR(("%s : irq set affinity cpu:0x%lx\n",
+			__FUNCTION__, *cpumask_bits(cpumask)));
+
+	dhdpcie_get_pcieirq(dhdp->bus, &irq);
+#ifdef BCMDHD_MODULAR
+	err = irq_set_affinity_hint(irq, cpumask);
+#else
+	err = irq_set_affinity(irq, cpumask);
+#endif /* BCMDHD_MODULAR */
+	if (err)
+		DHD_ERROR(("%s : irq set affinity is failed cpu:0x%lx\n",
+				__FUNCTION__, *cpumask_bits(cpumask)));
+}
+#endif /* SET_PCIE_IRQ_CPU_CORE ||  DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */
+
+#ifdef SET_PCIE_IRQ_CPU_CORE
+void
+dhd_set_irq_cpucore(dhd_pub_t *dhdp, int affinity_cmd)
+{
+#if defined(DHD_LB) && defined(DHD_LB_HOST_CTRL)
+	struct dhd_info  *dhd = NULL;
+#endif /* DHD_LB && DHD_LB_HOST_CTRL */
+
+	if (!dhdp) {
+		DHD_ERROR(("%s : dhd is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	if (!dhdp->bus) {
+		DHD_ERROR(("%s : dhd->bus is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	if (affinity_cmd < DHD_AFFINITY_OFF || affinity_cmd > DHD_AFFINITY_LAST) {
+		DHD_ERROR(("Wrong Affinity cmds:%d, %s\n", affinity_cmd, __FUNCTION__));
+		return;
+	}
+
+	DHD_ERROR(("Enter %s, PCIe affinity cmd=0x%x\n", __FUNCTION__, affinity_cmd));
+
+#if defined(DHD_LB) && defined(DHD_LB_HOST_CTRL)
+	dhd = dhdp->info;
+
+	if (affinity_cmd == DHD_AFFINITY_OFF) {
+		dhd->permitted_primary_cpu = FALSE;
+	} else if (affinity_cmd == DHD_AFFINITY_TPUT_150MBPS ||
+		affinity_cmd == DHD_AFFINITY_TPUT_300MBPS) {
+		dhd->permitted_primary_cpu = TRUE;
+	}
+	dhd_select_cpu_candidacy(dhd);
+	/*
+	* It needs to NAPI disable -> enable to raise NET_RX napi CPU core
+	* during Rx traffic
+	* NET_RX does not move to NAPI CPU core if continusly calling napi polling
+	* function
+	*/
+	napi_disable(&dhd->rx_napi_struct);
+	napi_enable(&dhd->rx_napi_struct);
+#endif /* DHD_LB && DHD_LB_HOST_CTRL */
+
+	/*
+		irq_set_affinity() assign dedicated CPU core PCIe interrupt
+		If dedicated CPU core is not on-line,
+		PCIe interrupt scheduled on CPU core 0
+	*/
+	switch (affinity_cmd) {
+		case DHD_AFFINITY_OFF:
+#if defined(DHD_LB) && defined(DHD_LB_HOST_CTRL)
+			dhd_irq_set_affinity(dhdp, dhdp->info->cpumask_secondary);
+#endif /* DHD_LB && DHD_LB_HOST_CTRL */
+			break;
+		case DHD_AFFINITY_TPUT_150MBPS:
+			dhd_irq_set_affinity(dhdp, dhdp->info->cpumask_primary);
+			break;
+		case DHD_AFFINITY_TPUT_300MBPS:
+#ifdef CONFIG_ARCH_EXYNOS
+			dhd_irq_set_affinity(dhdp, cpumask_of(PCIE_IRQ_CPU_CORE));
+#else
+			dhd_irq_set_affinity(dhdp, dhdp->info->cpumask_primary);
+#endif /* CONFIG_ARCH_EXYNOS */
+			break;
+		default:
+			DHD_ERROR(("%s, Unknown PCIe affinity cmd=0x%x\n",
+				__FUNCTION__, affinity_cmd));
+	}
+}
+#endif /* SET_PCIE_IRQ_CPU_CORE */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux_pktdump.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux_pktdump.c
@@ -0,0 +1,2281 @@
+/*
+ * Packet dump helper functions
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <typedefs.h>
+#include <ethernet.h>
+#include <bcmutils.h>
+#include <bcmevent.h>
+#include <bcmendian.h>
+#include <bcmtlv.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_dbg.h>
+#include <bcmip.h>
+#include <bcmudp.h>
+#include <bcmdhcp.h>
+#include <bcmarp.h>
+#include <bcmicmp.h>
+#include <bcmigmp.h>
+#include <dhd_linux_pktdump.h>
+#ifdef WL_CFGVENDOR_CUST_ADVLOG
+#include <wl_cfg80211.h>
+#include <wl_cfgvendor.h>
+#include <dhd_flowring.h>
+#endif /* WL_CFGVENDOR_CUST_ADVLOG */
+#include <dhd_config.h>
+#include <wl_android.h>
+
+#define DHD_PKTDUMP(arg)	printf arg
+#define DHD_PKTDUMP_MEM(arg)	printf arg
+#define PACKED_STRUCT __attribute__ ((packed))
+
+#define EAPOL_HDR_LEN		4
+
+/* EAPOL types */
+#define EAP_PACKET		0
+#define EAPOL_START		1
+#define EAPOL_LOGOFF		2
+#define EAPOL_KEY		3
+#define EAPOL_ASF		4
+
+/* EAPOL-Key types */
+#define EAPOL_RC4_KEY		1
+#define EAPOL_WPA2_KEY		2	/* 802.11i/WPA2 */
+#define EAPOL_WPA_KEY		254	/* WPA */
+
+/* EAPOL-Key header field size */
+#define AKW_BLOCK_LEN		8
+#define WPA_KEY_REPLAY_LEN	8
+#define WPA_KEY_NONCE_LEN	32
+#define WPA_KEY_IV_LEN		16
+#define WPA_KEY_RSC_LEN		8
+#define WPA_KEY_ID_LEN		8
+#define WPA_KEY_MIC_LEN		16
+#define WPA_MAX_KEY_SIZE	32
+#define WPA_KEY_DATA_LEN	(WPA_MAX_KEY_SIZE + AKW_BLOCK_LEN)
+
+/* Key information bit */
+#define KEYINFO_TYPE_MASK	(1 << 3)
+#define KEYINFO_INSTALL_MASK	(1 << 6)
+#define KEYINFO_KEYACK_MASK	(1 << 7)
+#define KEYINFO_KEYMIC_MASK	(1 << 8)
+#define KEYINFO_SECURE_MASK	(1 << 9)
+#define KEYINFO_ERROR_MASK	(1 << 10)
+#define KEYINFO_REQ_MASK	(1 << 11)
+
+/* EAP Code */
+#define EAP_CODE_REQUEST	1	/* Request */
+#define EAP_CODE_RESPONSE	2	/* Response */
+#define EAP_CODE_SUCCESS	3	/* Success */
+#define EAP_CODE_FAILURE	4	/* Failure */
+
+/* EAP Type */
+#define EAP_TYPE_RSVD		0	/* Reserved */
+#define EAP_TYPE_IDENT		1	/* Identify */
+#define EAP_TYPE_NOTI		2	/* Notification */
+#define EAP_TYPE_TLS		13	/* EAP-TLS */
+#define EAP_TYPE_LEAP		17	/* Cisco-LEAP */
+#define EAP_TYPE_TTLS		21	/* EAP-TTLS */
+#define EAP_TYPE_AKA		23	/* EAP-AKA */
+#define EAP_TYPE_PEAP		25	/* EAP-PEAP */
+#define EAP_TYPE_FAST		43	/* EAP-FAST */
+#define EAP_TYPE_PSK		47	/* EAP-PSK */
+#define EAP_TYPE_AKAP		50	/* EAP-AKA' */
+#define EAP_TYPE_EXP		254	/* Reserved for Expended Type */
+
+/* WSC */
+#define EAP_HDR_LEN		5
+#define EAP_WSC_NONCE_OFFSET	10
+#define EAP_WSC_DATA_OFFSET	(OFFSETOF(eap_wsc_fmt_t, data))
+#define EAP_WSC_MIN_DATA_LEN	((EAP_HDR_LEN) + (EAP_WSC_DATA_OFFSET))
+#define WFA_VID			"\x00\x37\x2A"	/* WFA SMI code */
+#define WFA_VID_LEN		3		/* WFA VID length */
+#define WFA_VTYPE		1u		/* WFA Vendor type */
+
+/* WSC opcode */
+#define WSC_OPCODE_UPNP		0
+#define WSC_OPCODE_START	1
+#define WSC_OPCODE_ACK		2
+#define WSC_OPCODE_NACK		3
+#define WSC_OPCODE_MSG		4
+#define WSC_OPCODE_DONE		5
+#define WSC_OPCODE_FRAG_ACK	6
+
+/* WSC flag */
+#define WSC_FLAG_MF		1	/* more fragements */
+#define WSC_FLAG_LF		2	/* length field */
+
+/* WSC message code */
+#define WSC_ATTR_MSG		0x1022
+#define WSC_MSG_M1		0x04
+#define WSC_MSG_M2		0x05
+#define WSC_MSG_M3		0x07
+#define WSC_MSG_M4		0x08
+#define WSC_MSG_M5		0x09
+#define WSC_MSG_M6		0x0A
+#define WSC_MSG_M7		0x0B
+#define WSC_MSG_M8		0x0C
+
+/* Debug prints */
+typedef enum pkt_cnt_type {
+	PKT_CNT_TYPE_INVALID	= 0,
+	PKT_CNT_TYPE_ARP	= 1,
+	PKT_CNT_TYPE_DNS	= 2,
+	PKT_CNT_TYPE_MAX	= 3
+} pkt_cnt_type_t;
+
+typedef struct pkt_cnt {
+	uint32 tx_cnt;
+	uint32 tx_err_cnt;
+	uint32 rx_cnt;
+} pkt_cnt_t;
+
+typedef struct pkt_cnt_log {
+	bool enabled;
+	uint16 reason;
+	timer_list_compat_t pktcnt_timer;
+	pkt_cnt_t arp_cnt;
+	pkt_cnt_t dns_cnt;
+} pkt_cnts_log_t;
+
+#define PKT_CNT_TIMER_INTERNVAL_MS		5000	/* packet count timeout(ms) */
+#define PKT_CNT_RSN_VALID(rsn)	\
+	(((rsn) > (PKT_CNT_RSN_INVALID)) && ((rsn) < (PKT_CNT_RSN_MAX)))
+
+#ifdef DHD_PKTDUMP_ROAM
+static const char pkt_cnt_msg[][20] = {
+	"INVALID",
+	"ROAM_SUCCESS",
+	"GROUP_KEY_UPDATE",
+	"CONNECT_SUCCESS",
+	"INVALID"
+};
+#endif
+
+#if defined(DHD_DNS_DUMP) || defined(DHD_ARP_DUMP) || defined(DHD_ICMP_DUMP) || \
+	defined(DHD_DHCP_DUMP) || defined(DHD_8021X_DUMP) || defined(DHD_PKTDUMP_ROAM)
+#define DHD_PKTFATE_STR_MAX 30
+#define DHD_PKTFATE_EX_STR_MAX 10
+typedef struct dhd_tx_pktfate_entry {
+	const char reason[DHD_PKTFATE_STR_MAX];
+	const char ex[DHD_PKTFATE_EX_STR_MAX];
+} dhd_tx_pktfate_entry_t;
+
+static dhd_tx_pktfate_entry_t tx_pktfate[] = {
+	{"TX_PKT_FATE_ACKED", "ACK"},			/* 0: WLFC_CTL_PKTFLAG_DISCARD */
+	{"TX_PKT_FATE_FW_D11SUPPRESS", "TX_FAIL"},	/* 1: WLFC_CTL_PKTFLAG_D11SUPPRESS */
+	{"TX_PKT_FATE_FW_WLSUPPRESS", "TX_FAIL"},	/* 2: WLFC_CTL_PKTFLAG_WLSUPPRESS */
+	{"TX_PKT_FATE_FW_TOSSED_BYWLC", "TX_FAIL"},	/* 3: WLFC_CTL_PKTFLAG_TOSSED_BYWLC */
+	{"TX_PKT_FATE_SENT_NOACK", "NO_ACK"},		/* 4: WLFC_CTL_PKTFLAG_DISCARD_NOACK */
+	{"TX_PKT_FATE_FW_SUPPRESS_ACKED", "TX_FAIL"},	/* 5: WLFC_CTL_PKTFLAG_SUPPRESS_ACKED */
+	{"TX_PKT_FATE_FW_DROP_EXPTIME",	"TX_FAIL"},	/* 6: WLFC_CTL_PKTFLAG_EXPIRED */
+	{"TX_PKT_FATE_FW_DROP_OTHER", "TX_FAIL"},	/* 7: WLFC_CTL_PKTFLAG_DROPPED */
+	{"TX_PKT_FATE_FW_PKT_FREE", "TX_FAIL"},		/* 8: WLFC_CTL_PKTFLAG_MKTFREE */
+	{"TX_PKT_FATE_FW_MAX_SUP_RETR", "TX_FAIL"},	/* 9: WLFC_CTL_PKTFLAG_MAX_SUP_RETR */
+	{"TX_PKT_FATE_FW_FORCED_EXPIRED", "TX_FAIL"},	/* 10: WLFC_CTL_PKTFLAG_FORCED_EXPIRED */
+};
+
+#define DBGREPLAY		" Replay Counter: %02x%02x%02x%02x%02x%02x%02x%02x"
+#define REPLAY_FMT(key)		((const eapol_key_hdr_t *)(key))->replay[0], \
+				((const eapol_key_hdr_t *)(key))->replay[1], \
+				((const eapol_key_hdr_t *)(key))->replay[2], \
+				((const eapol_key_hdr_t *)(key))->replay[3], \
+				((const eapol_key_hdr_t *)(key))->replay[4], \
+				((const eapol_key_hdr_t *)(key))->replay[5], \
+				((const eapol_key_hdr_t *)(key))->replay[6], \
+				((const eapol_key_hdr_t *)(key))->replay[7]
+#define TXFATE_FMT		" TX_PKTHASH:0x%X TX_PKT_FATE:%s"
+#define TX_PKTHASH(pkthash)		((pkthash) ? (*pkthash) : (0))
+#define TX_FATE_STR(fate)	(((*fate) <= (WLFC_CTL_PKTFLAG_FORCED_EXPIRED)) ? \
+				(tx_pktfate[(*fate)].reason) : "TX_PKT_FATE_UNKNOWN")
+#define TX_FATE_STR_EX(fate)	(((*fate) <= (WLFC_CTL_PKTFLAG_FORCED_EXPIRED)) ? \
+				(tx_pktfate[(*fate)].ex) : NULL)
+#define TX_FATE(fate)		((fate) ? (TX_FATE_STR(fate)) : "N/A")
+#define TX_FATE_EX(fate)	((fate) ? (TX_FATE_STR_EX(fate)) : NULL)
+#define TX_FATE_ACKED(fate)	((fate) ? ((*fate) == (WLFC_CTL_PKTFLAG_DISCARD)) : (0))
+#endif /*
+	* DHD_DNS_DUMP || DHD_ARP_DUMP || DHD_ICMP_DUMP ||
+	* DHD_DHCP_DUMP || DHD_8021X_DUMP || DHD_PKTDUMP_ROAM
+	*/
+
+#define EAP_PRINT(x, args...) \
+	do { \
+		if (dump_msg_level & DUMP_EAPOL_VAL) { \
+			if (tx) { \
+				DHD_PKTDUMP(("[%s] 802_1X " x " [TX] : (%s) %s (%s)"TXFATE_FMT"\n", \
+					ifname, ## args, \
+					tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf, \
+					TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+			} else { \
+				DHD_PKTDUMP(("[%s] 802_1X " x " [RX] : (%s) %s (%s)\n", \
+					ifname, ## args, \
+					tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf)); \
+			} \
+		} \
+	} while (0)
+
+#define EAP_PRINT_REPLAY(x, args...) \
+	do { \
+		if (dump_msg_level & DUMP_EAPOL_VAL) { \
+			if (tx) { \
+				DHD_PKTDUMP(("[%s] 802_1X " x " [TX] : (%s) %s (%s)"DBGREPLAY TXFATE_FMT"\n", \
+					ifname, ## args, \
+					tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf, \
+					REPLAY_FMT(eap_key), TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+			} else { \
+				DHD_PKTDUMP(("[%s] 802_1X " x " [RX] : (%s) %s (%s)"DBGREPLAY"\n", \
+					ifname, ## args, \
+					tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf, \
+					REPLAY_FMT(eap_key))); \
+			} \
+		} \
+	} while (0)
+
+#define EAP_PRINT_OTHER(x, args...) \
+	do { \
+		if (dump_msg_level & DUMP_EAPOL_VAL) { \
+			if (tx) { \
+				DHD_PKTDUMP(("[%s] 802_1X " x " [TX] : (%s) %s (%s) " \
+					"ver %d, type %d"TXFATE_FMT"\n", \
+					ifname, ## args, \
+					tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf, \
+					eapol_hdr->version, eapol_hdr->type, \
+					TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+			} else { \
+				DHD_PKTDUMP(("[%s] 802_1X " x " [RX] : (%s) %s (%s) " \
+					"ver %d, type %d\n", \
+					ifname, ## args, \
+					tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf, \
+					eapol_hdr->version, eapol_hdr->type)); \
+			} \
+		} \
+	} while (0)
+
+#define EAP_PRINT_OTHER_4WAY(x, args...) \
+	do { \
+		if (dump_msg_level & DUMP_EAPOL_VAL) { \
+			if (tx) { \
+				DHD_PKTDUMP(("[%s] 802_1X " x " [TX] : (%s) %s (%s) " \
+					"ver %d type %d keytype %d keyinfo 0x%02X"TXFATE_FMT"\n", \
+					ifname, ## args, \
+					tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf, \
+					eapol_hdr->version, eapol_hdr->type, eap_key->type, \
+					(uint32)hton16(eap_key->key_info), \
+					TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+			} else { \
+				DHD_PKTDUMP(("[%s] 802_1X " x " [RX] : (%s) %s (%s) " \
+					"ver %d type %d keytype %d keyinfo 0x%02X\n", \
+					ifname, ## args, \
+					tx?seabuf:deabuf, tx?"->":"<-", tx?deabuf:seabuf, \
+					eapol_hdr->version, eapol_hdr->type, eap_key->type, \
+					(uint32)hton16(eap_key->key_info))); \
+			} \
+		} \
+	} while (0)
+
+#define UDP_PORT_DNS	53	/* UDP DNS port */
+
+/* EAPOL header */
+typedef struct eapol_header {
+	struct ether_header eth;	/* 802.3/Ethernet header */
+	uint8 version;			/* EAPOL protocol version */
+	uint8 type;			/* EAPOL type */
+	uint16 length;			/* Length of body */
+	uint8 body[1];			/* Body (optional) */
+} PACKED_STRUCT eapol_header_t;
+
+/* EAP header */
+typedef struct eap_header_fmt {
+	uint8 code;
+	uint8 id;
+	uint16 len;
+	uint8 type;
+	uint8 data[1];
+} PACKED_STRUCT eap_header_fmt_t;
+
+/* WSC EAP format */
+typedef struct eap_wsc_fmt {
+	uint8 oui[3];
+	uint32 ouitype;
+	uint8 opcode;
+	uint8 flags;
+	uint8 data[1];
+} PACKED_STRUCT eap_wsc_fmt_t;
+
+/* EAPOL-Key */
+typedef struct eapol_key_hdr {
+	uint8 type;				/* Key Descriptor Type */
+	uint16 key_info;			/* Key Information (unaligned) */
+	uint16 key_len;				/* Key Length (unaligned) */
+	uint8 replay[WPA_KEY_REPLAY_LEN];	/* Replay Counter */
+	uint8 nonce[WPA_KEY_NONCE_LEN];		/* Nonce */
+	uint8 iv[WPA_KEY_IV_LEN];		/* Key IV */
+	uint8 rsc[WPA_KEY_RSC_LEN];		/* Key RSC */
+	uint8 id[WPA_KEY_ID_LEN];		/* WPA:Key ID, 802.11i/WPA2: Reserved */
+	uint8 mic[WPA_KEY_MIC_LEN];		/* Key MIC */
+	uint16 data_len;			/* Key Data Length */
+	uint8 data[WPA_KEY_DATA_LEN];		/* Key data */
+} PACKED_STRUCT eapol_key_hdr_t;
+
+typedef struct hdr_fmt {
+	struct ipv4_hdr iph;
+	struct bcmudp_hdr udph;
+} PACKED_STRUCT hdr_fmt_t;
+
+#ifdef DHD_IPV6_DUMP
+typedef struct ipv6hdr_fmt {
+	struct ipv6_hdr ip6h;
+	struct bcmudp_hdr udph;
+} PACKED_STRUCT ipv6hdr_fmt_t;
+
+typedef struct dhcp6_fmt {
+	struct ipv6_hdr iph;
+	struct bcmudp_hdr udph;
+	uint8 msgtype;
+} PACKED_STRUCT dhcp6_fmt_t;
+
+typedef struct icmpv6 {
+	uint8   icmp6_type;
+	uint8   icmp6_code;
+	uint16  icmp6_cksum;
+	uint16  id;
+	uint16  seq;
+} PACKED_STRUCT icmpv6_hdr_t;
+
+typedef struct dns6_fmt {
+	struct ipv6_hdr ip6h;
+	struct bcmudp_hdr udph;
+	uint16 id;
+	uint16 flags;
+	uint16 qdcount;
+	uint16 ancount;
+	uint16 nscount;
+	uint16 arcount;
+} PACKED_STRUCT dns6_fmt_t;
+#endif /* DHD_IPV6_DUMP */
+
+msg_eapol_t
+dhd_is_4way_msg(uint8 *pktdata)
+{
+	eapol_header_t *eapol_hdr;
+	eapol_key_hdr_t *eap_key;
+	msg_eapol_t type = EAPOL_OTHER;
+	bool pair, ack, mic, kerr, req, sec, install;
+	uint16 key_info;
+
+	if (!pktdata) {
+		DHD_PKTDUMP(("%s: pktdata is NULL\n", __FUNCTION__));
+		return type;
+	}
+
+	eapol_hdr = (eapol_header_t *)pktdata;
+	eap_key = (eapol_key_hdr_t *)(eapol_hdr->body);
+	if (eap_key->type != EAPOL_WPA2_KEY && eap_key->type != EAPOL_WPA_KEY) {
+		return type;
+	}
+
+	key_info = hton16(eap_key->key_info);
+	pair = !!(key_info & KEYINFO_TYPE_MASK);
+	ack = !!(key_info & KEYINFO_KEYACK_MASK);
+	mic = !!(key_info & KEYINFO_KEYMIC_MASK);
+	kerr = !!(key_info & KEYINFO_ERROR_MASK);
+	req = !!(key_info & KEYINFO_REQ_MASK);
+	sec = !!(key_info & KEYINFO_SECURE_MASK);
+	install = !!(key_info & KEYINFO_INSTALL_MASK);
+
+	if (eap_key->type == EAPOL_WPA2_KEY) {
+		if (pair && !install && ack && !mic && !sec && !kerr && !req) {
+			type = EAPOL_4WAY_M1;
+		} else if (pair && !install && !ack && mic && !sec && !kerr && !req) {
+			type = EAPOL_4WAY_M2;
+		} else if (pair && ack && mic && sec && !kerr && !req) {
+			type = EAPOL_4WAY_M3;
+		} else if (pair && !install && !ack && mic && sec && !req && !kerr) {
+			type = EAPOL_4WAY_M4;
+		} else if (!pair && !install && ack && mic && sec && !req && !kerr) {
+			type = EAPOL_GROUPKEY_M1;
+		} else if (!pair && !install && !ack && mic && sec && !req && !kerr) {
+			type = EAPOL_GROUPKEY_M2;
+		} else {
+			type = EAPOL_OTHER;
+			if (dump_msg_level & DUMP_EAPOL_VAL) {
+				printf("WPA2: key_info=0x%x, pair=%d, ack=%d, mic=%d, sec=%d, kerr=%d, req=%d\n",
+					key_info, pair, ack, mic, sec, kerr, req);
+			}
+		}
+	}
+	else if (eap_key->type == EAPOL_WPA_KEY) {
+		if (pair && !install && ack && !mic && !sec && !kerr && !req) {
+			type = EAPOL_4WAY_M1;
+		} else if (pair && !install && !ack && mic && !sec && !kerr && !req && eap_key->data_len) {
+			type = EAPOL_4WAY_M2;
+		} else if (pair && install && ack && mic && !sec && !kerr && !req) {
+			type = EAPOL_4WAY_M3;
+		} else if (pair && !install && !ack && mic && !sec && !req && !kerr) {
+			type = EAPOL_4WAY_M4;
+		} else if (!pair && !install && ack && mic && sec && !req && !kerr) {
+			type = EAPOL_GROUPKEY_M1;
+		} else if (!pair && !install && !ack && mic && sec && !req && !kerr) {
+			type = EAPOL_GROUPKEY_M2;
+		} else {
+			type = EAPOL_OTHER;
+			if (dump_msg_level & DUMP_EAPOL_VAL) {
+				printf("WPA: key_info=0x%x, pair=%d, ack=%d, mic=%d, sec=%d, kerr=%d, req=%d\n",
+					key_info, pair, ack, mic, sec, kerr, req);
+			}
+		}
+	}
+	else {
+		type = EAPOL_OTHER;
+		if (dump_msg_level & DUMP_EAPOL_VAL) {
+			printf("OTHER: key_info=0x%x, pair=%d, ack=%d, mic=%d, sec=%d, kerr=%d, req=%d\n",
+				key_info, pair, ack, mic, sec, kerr, req);
+		}
+	}
+
+	return type;
+}
+
+void
+dhd_dump_pkt(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, uint32 pktlen,
+	bool tx, uint32 *pkthash, uint16 *pktfate)
+{
+	struct ether_header *eh;
+	uint16 ether_type;
+
+	if (!pktdata || pktlen < ETHER_HDR_LEN) {
+		return;
+	}
+
+#if 0 // defined(BCMPCIE) && defined(DHD_PKT_LOGGING)
+	if (tx && !pkthash && !pktfate) {
+		return;
+	}
+#endif /* BCMPCIE && DHD_PKT_LOGGING */
+
+	eh = (struct ether_header *)pktdata;
+	ether_type = ntoh16(eh->ether_type);
+	if (ether_type == ETHER_TYPE_802_1X) {
+		dhd_dump_eapol_message(dhdp, ifidx, pktdata, pktlen,
+			tx, pkthash, pktfate);
+	}
+	if (ether_type == ETHER_TYPE_IP) {
+		if (dhd_check_dhcp(pktdata)) {
+			dhd_dhcp_dump(dhdp, ifidx, pktdata, tx, pkthash, pktfate);
+		} else if (dhd_check_icmp(pktdata)) {
+			dhd_icmp_dump(dhdp, ifidx, pktdata, tx, pkthash, pktfate);
+		} else if (dhd_check_dns(pktdata)) {
+			dhd_dns_dump(dhdp, ifidx, pktdata, tx, pkthash, pktfate);
+		}
+	}
+	if (ether_type == ETHER_TYPE_ARP) {
+		if (dhd_check_arp(pktdata, ether_type)) {
+			dhd_arp_dump(dhdp, ifidx, pktdata, tx, pkthash, pktfate);
+		}
+	}
+	dhd_trx_pkt_dump(dhdp, ifidx, pktdata, pktlen, tx);
+}
+
+#ifdef DHD_PKTDUMP_ROAM
+static void
+dhd_dump_pkt_cnts_inc(dhd_pub_t *dhdp, bool tx, uint16 *pktfate, uint16 pkttype)
+{
+	pkt_cnts_log_t *pktcnts;
+	pkt_cnt_t *cnt;
+
+	if (!dhdp) {
+		DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	pktcnts = (pkt_cnts_log_t *)(dhdp->pktcnts);
+	if (!pktcnts) {
+		DHD_ERROR(("%s: pktcnts is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	if (!pktcnts->enabled || (tx && !pktfate)) {
+		return;
+	}
+
+	if (pkttype == PKT_CNT_TYPE_ARP) {
+		cnt = (pkt_cnt_t *)&pktcnts->arp_cnt;
+	} else if (pkttype == PKT_CNT_TYPE_DNS) {
+		cnt = (pkt_cnt_t *)&pktcnts->dns_cnt;
+	} else {
+		/* invalid packet type */
+		return;
+	}
+
+	if (tx) {
+		TX_FATE_ACKED(pktfate) ? cnt->tx_cnt++ : cnt->tx_err_cnt++;
+	} else {
+		cnt->rx_cnt++;
+	}
+}
+
+static void
+dhd_dump_pkt_timer(unsigned long data)
+{
+	dhd_pub_t *dhdp = (dhd_pub_t *)data;
+	pkt_cnts_log_t *pktcnts = (pkt_cnts_log_t *)(dhdp->pktcnts);
+
+	pktcnts->enabled = FALSE;
+
+	/* print out the packet counter value */
+	DHD_PKTDUMP(("============= PACKET COUNT SUMMARY ============\n"));
+	DHD_PKTDUMP(("- Reason: %s\n", pkt_cnt_msg[pktcnts->reason]));
+	DHD_PKTDUMP(("- Duration: %d msec(s)\n", PKT_CNT_TIMER_INTERNVAL_MS));
+	DHD_PKTDUMP(("- ARP PACKETS: tx_success:%d tx_fail:%d rx_cnt:%d\n",
+		pktcnts->arp_cnt.tx_cnt, pktcnts->arp_cnt.tx_err_cnt,
+		pktcnts->arp_cnt.rx_cnt));
+	DHD_PKTDUMP(("- DNS PACKETS: tx_success:%d tx_fail:%d rx_cnt:%d\n",
+		pktcnts->dns_cnt.tx_cnt, pktcnts->dns_cnt.tx_err_cnt,
+		pktcnts->dns_cnt.rx_cnt));
+	DHD_PKTDUMP(("============= END OF COUNT SUMMARY ============\n"));
+}
+
+void
+dhd_dump_mod_pkt_timer(dhd_pub_t *dhdp, uint16 rsn)
+{
+	pkt_cnts_log_t *pktcnts;
+
+	if (!dhdp || !dhdp->pktcnts) {
+		DHD_ERROR(("%s: dhdp or dhdp->pktcnts is NULL\n",
+			__FUNCTION__));
+		return;
+	}
+
+	if (!PKT_CNT_RSN_VALID(rsn)) {
+		DHD_ERROR(("%s: invalid reason code %d\n",
+			__FUNCTION__, rsn));
+		return;
+	}
+
+	pktcnts = (pkt_cnts_log_t *)(dhdp->pktcnts);
+	if (timer_pending(&pktcnts->pktcnt_timer)) {
+		del_timer_sync(&pktcnts->pktcnt_timer);
+	}
+
+	bzero(&pktcnts->arp_cnt, sizeof(pkt_cnt_t));
+	bzero(&pktcnts->dns_cnt, sizeof(pkt_cnt_t));
+	pktcnts->reason = rsn;
+	pktcnts->enabled = TRUE;
+	mod_timer(&pktcnts->pktcnt_timer,
+		jiffies + msecs_to_jiffies(PKT_CNT_TIMER_INTERNVAL_MS));
+	DHD_PKTDUMP(("%s: Arm the pktcnt timer. reason=%d\n",
+		__FUNCTION__, rsn));
+}
+
+void
+dhd_dump_pkt_init(dhd_pub_t *dhdp)
+{
+	pkt_cnts_log_t *pktcnts;
+
+	if (!dhdp) {
+		DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	pktcnts = (pkt_cnts_log_t *)MALLOCZ(dhdp->osh, sizeof(pkt_cnts_log_t));
+	if (!pktcnts) {
+		DHD_ERROR(("%s: failed to allocate memory for pktcnts\n",
+			__FUNCTION__));
+		return;
+	}
+
+	/* init timers */
+	init_timer_compat(&pktcnts->pktcnt_timer, dhd_dump_pkt_timer, dhdp);
+	dhdp->pktcnts = pktcnts;
+}
+
+void
+dhd_dump_pkt_deinit(dhd_pub_t *dhdp)
+{
+	pkt_cnts_log_t *pktcnts;
+
+	if (!dhdp || !dhdp->pktcnts) {
+		DHD_ERROR(("%s: dhdp or pktcnts is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	pktcnts = (pkt_cnts_log_t *)(dhdp->pktcnts);
+	pktcnts->enabled = FALSE;
+	del_timer_sync(&pktcnts->pktcnt_timer);
+	MFREE(dhdp->osh, dhdp->pktcnts, sizeof(pkt_cnts_log_t));
+	dhdp->pktcnts = NULL;
+}
+
+void
+dhd_dump_pkt_clear(dhd_pub_t *dhdp)
+{
+	pkt_cnts_log_t *pktcnts;
+
+	if (!dhdp || !dhdp->pktcnts) {
+		DHD_ERROR(("%s: dhdp or pktcnts is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	pktcnts = (pkt_cnts_log_t *)(dhdp->pktcnts);
+	pktcnts->enabled = FALSE;
+	del_timer_sync(&pktcnts->pktcnt_timer);
+	pktcnts->reason = 0;
+	bzero(&pktcnts->arp_cnt, sizeof(pkt_cnt_t));
+	bzero(&pktcnts->dns_cnt, sizeof(pkt_cnt_t));
+}
+
+bool
+dhd_dump_pkt_enabled(dhd_pub_t *dhdp)
+{
+	pkt_cnts_log_t *pktcnts;
+
+	if (!dhdp || !dhdp->pktcnts) {
+		return FALSE;
+	}
+
+	pktcnts = (pkt_cnts_log_t *)(dhdp->pktcnts);
+
+	return pktcnts->enabled;
+}
+#else
+static INLINE void
+dhd_dump_pkt_cnts_inc(dhd_pub_t *dhdp, bool tx, uint16 *pktfate, uint16 pkttype) { }
+static INLINE bool
+dhd_dump_pkt_enabled(dhd_pub_t *dhdp) { return FALSE; }
+#endif /* DHD_PKTDUMP_ROAM */
+
+#ifdef DHD_8021X_DUMP
+static void
+dhd_dump_wsc_message(dhd_pub_t *dhd, int ifidx, uint8 *pktdata,
+	uint32 pktlen, bool tx, uint32 *pkthash, uint16 *pktfate)
+{
+	eapol_header_t *eapol_hdr;
+	eap_header_fmt_t *eap_hdr;
+	eap_wsc_fmt_t *eap_wsc;
+	char *ifname;
+	uint16 eap_len;
+	bool cond;
+	char seabuf[ETHER_ADDR_STR_LEN]="";
+	char deabuf[ETHER_ADDR_STR_LEN]="";
+
+	if (!pktdata) {
+		DHD_ERROR(("%s: pktdata is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	if (pktlen < (ETHER_HDR_LEN + EAPOL_HDR_LEN)) {
+		DHD_ERROR(("%s: invalid pkt length\n", __FUNCTION__));
+		return;
+	}
+
+	bcm_ether_ntoa((struct ether_addr *)pktdata, deabuf);
+	bcm_ether_ntoa((struct ether_addr *)(pktdata+6), seabuf);
+
+	eapol_hdr = (eapol_header_t *)pktdata;
+	eap_hdr = (eap_header_fmt_t *)(eapol_hdr->body);
+	if (eap_hdr->type != EAP_TYPE_EXP) {
+		return;
+	}
+
+	eap_len = ntoh16(eap_hdr->len);
+	if (eap_len < EAP_WSC_MIN_DATA_LEN) {
+		return;
+	}
+
+	eap_wsc = (eap_wsc_fmt_t *)(eap_hdr->data);
+	if (bcmp(eap_wsc->oui, (const uint8 *)WFA_VID, WFA_VID_LEN) ||
+		(ntoh32(eap_wsc->ouitype) != WFA_VTYPE)) {
+		return;
+	}
+
+	if (eap_wsc->flags) {
+		return;
+	}
+
+	ifname = dhd_ifname(dhd, ifidx);
+	cond = (tx && pktfate) ? FALSE : TRUE;
+
+	if (eap_wsc->opcode == WSC_OPCODE_MSG) {
+		const uint8 *tlv_buf = (const uint8 *)(eap_wsc->data);
+		const uint8 *msg;
+		uint16 msglen;
+		uint16 wsc_data_len = (uint16)(eap_len - EAP_HDR_LEN - EAP_WSC_DATA_OFFSET);
+		bcm_xtlv_opts_t opt = BCM_XTLV_OPTION_IDBE | BCM_XTLV_OPTION_LENBE;
+
+		msg = bcm_get_data_from_xtlv_buf(tlv_buf, wsc_data_len,
+			WSC_ATTR_MSG, &msglen, opt);
+		if (msg && msglen) {
+			switch (*msg) {
+			case WSC_MSG_M1:
+#ifdef WL_EXT_IAPSTA
+				wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_WPS_M1);
+#endif
+				DHD_STATLOG_DATA(dhd, ST(WPS_M1), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, WPS M1");
+				break;
+			case WSC_MSG_M2:
+#ifdef WL_EXT_IAPSTA
+				wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_WPS_M2);
+#endif
+				DHD_STATLOG_DATA(dhd, ST(WPS_M2), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, WPS M2");
+				break;
+			case WSC_MSG_M3:
+#ifdef WL_EXT_IAPSTA
+				wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_WPS_M3);
+#endif
+				DHD_STATLOG_DATA(dhd, ST(WPS_M3), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, WPS M3");
+				break;
+			case WSC_MSG_M4:
+#ifdef WL_EXT_IAPSTA
+				wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_WPS_M4);
+#endif
+				DHD_STATLOG_DATA(dhd, ST(WPS_M4), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, WPS M4");
+				break;
+			case WSC_MSG_M5:
+#ifdef WL_EXT_IAPSTA
+				wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_WPS_M5);
+#endif
+				DHD_STATLOG_DATA(dhd, ST(WPS_M5), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, WPS M5");
+				break;
+			case WSC_MSG_M6:
+#ifdef WL_EXT_IAPSTA
+				wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_WPS_M6);
+#endif
+				DHD_STATLOG_DATA(dhd, ST(WPS_M6), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, WPS M6");
+				break;
+			case WSC_MSG_M7:
+#ifdef WL_EXT_IAPSTA
+				wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_WPS_M7);
+#endif
+				DHD_STATLOG_DATA(dhd, ST(WPS_M7), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, WPS M7");
+				break;
+			case WSC_MSG_M8:
+#ifdef WL_EXT_IAPSTA
+				wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_WPS_M8);
+#endif
+				DHD_STATLOG_DATA(dhd, ST(WPS_M8), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, WPS M8");
+				break;
+			default:
+				EAP_PRINT("EAP Packet, WPS MSG TYPE %d", *msg);
+				break;
+			}
+		}
+	} else if (eap_wsc->opcode == WSC_OPCODE_START) {
+#ifdef WL_EXT_IAPSTA
+		wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_WSC_START);
+#endif
+		DHD_STATLOG_DATA(dhd, ST(WSC_START), ifidx, tx, cond);
+		EAP_PRINT("EAP Packet, WSC Start");
+	} else if (eap_wsc->opcode == WSC_OPCODE_DONE) {
+#ifdef WL_EXT_IAPSTA
+		wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_WSC_DONE);
+#endif
+		DHD_STATLOG_DATA(dhd, ST(WSC_DONE), ifidx, tx, cond);
+		EAP_PRINT("EAP Packet, WSC Done");
+	} else {
+		EAP_PRINT("EAP Packet, WSC opcode=%d", eap_wsc->opcode);
+	}
+}
+
+static void
+dhd_dump_eap_packet(dhd_pub_t *dhd, int ifidx, uint8 *pktdata,
+	uint32 pktlen, bool tx, uint32 *pkthash, uint16 *pktfate)
+{
+	eapol_header_t *eapol_hdr;
+	eap_header_fmt_t *eap_hdr;
+	char *ifname;
+	bool cond;
+	char seabuf[ETHER_ADDR_STR_LEN]="";
+	char deabuf[ETHER_ADDR_STR_LEN]="";
+
+	if (!pktdata) {
+		DHD_PKTDUMP(("%s: pktdata is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	bcm_ether_ntoa((struct ether_addr *)pktdata, deabuf);
+	bcm_ether_ntoa((struct ether_addr *)(pktdata+6), seabuf);
+
+	eapol_hdr = (eapol_header_t *)pktdata;
+	eap_hdr = (eap_header_fmt_t *)(eapol_hdr->body);
+	ifname = dhd_ifname(dhd, ifidx);
+	cond = (tx && pktfate) ? FALSE : TRUE;
+
+	if (eap_hdr->code == EAP_CODE_REQUEST ||
+		eap_hdr->code == EAP_CODE_RESPONSE) {
+		bool isreq = (eap_hdr->code == EAP_CODE_REQUEST);
+		switch (eap_hdr->type) {
+		case EAP_TYPE_IDENT:
+			if (isreq) {
+#ifdef WL_EXT_IAPSTA
+				wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_REQID);
+#endif
+				DHD_STATLOG_DATA(dhd, ST(EAP_REQ_IDENTITY), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Request, Identity");
+			} else {
+#ifdef WL_EXT_IAPSTA
+				wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_RSPID);
+#endif
+				DHD_STATLOG_DATA(dhd, ST(EAP_RESP_IDENTITY), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Response, Identity");
+			}
+			break;
+		case EAP_TYPE_TLS:
+			if (isreq) {
+				DHD_STATLOG_DATA(dhd, ST(EAP_REQ_TLS), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Request, TLS");
+			} else {
+				DHD_STATLOG_DATA(dhd, ST(EAP_RESP_TLS), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Response, TLS");
+			}
+			break;
+		case EAP_TYPE_LEAP:
+			if (isreq) {
+				DHD_STATLOG_DATA(dhd, ST(EAP_REQ_LEAP), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Request, LEAP");
+			} else {
+				DHD_STATLOG_DATA(dhd, ST(EAP_RESP_LEAP), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Response, LEAP");
+			}
+			break;
+		case EAP_TYPE_TTLS:
+			if (isreq) {
+				DHD_STATLOG_DATA(dhd, ST(EAP_REQ_TTLS), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Request, TTLS");
+			} else {
+				DHD_STATLOG_DATA(dhd, ST(EAP_RESP_TTLS), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Response, TTLS");
+			}
+			break;
+		case EAP_TYPE_AKA:
+			if (isreq) {
+				DHD_STATLOG_DATA(dhd, ST(EAP_REQ_AKA), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Request, AKA");
+			} else {
+				DHD_STATLOG_DATA(dhd, ST(EAP_RESP_AKA), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Response, AKA");
+			}
+			break;
+		case EAP_TYPE_PEAP:
+			if (isreq) {
+				DHD_STATLOG_DATA(dhd, ST(EAP_REQ_PEAP), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Request, PEAP");
+			} else {
+				DHD_STATLOG_DATA(dhd, ST(EAP_RESP_PEAP), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Response, PEAP");
+			}
+			break;
+		case EAP_TYPE_FAST:
+			if (isreq) {
+				DHD_STATLOG_DATA(dhd, ST(EAP_REQ_FAST), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Request, FAST");
+			} else {
+				DHD_STATLOG_DATA(dhd, ST(EAP_RESP_FAST), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Response, FAST");
+			}
+			break;
+		case EAP_TYPE_PSK:
+			if (isreq) {
+				DHD_STATLOG_DATA(dhd, ST(EAP_REQ_PSK), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Request, PSK");
+			} else {
+				DHD_STATLOG_DATA(dhd, ST(EAP_RESP_PSK), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Response, PSK");
+			}
+			break;
+		case EAP_TYPE_AKAP:
+			if (isreq) {
+				DHD_STATLOG_DATA(dhd, ST(EAP_REQ_AKAP), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Request, AKAP");
+			} else {
+				DHD_STATLOG_DATA(dhd, ST(EAP_RESP_AKAP), ifidx, tx, cond);
+				EAP_PRINT("EAP Packet, Response, AKAP");
+			}
+			break;
+		case EAP_TYPE_EXP:
+			dhd_dump_wsc_message(dhd, ifidx, pktdata, pktlen, tx,
+				pkthash, pktfate);
+			break;
+		default:
+			EAP_PRINT("EAP Packet, EAP TYPE %d", eap_hdr->type);
+			break;
+		}
+	} else if (eap_hdr->code == EAP_CODE_SUCCESS) {
+		DHD_STATLOG_DATA(dhd, ST(EAP_SUCCESS), ifidx, tx, cond);
+		EAP_PRINT("EAP Packet, Success");
+	} else if (eap_hdr->code == EAP_CODE_FAILURE) {
+		DHD_STATLOG_DATA(dhd, ST(EAP_FAILURE), ifidx, tx, cond);
+		EAP_PRINT("EAP Packet, Failure");
+	} else {
+		EAP_PRINT("EAP Packet, EAP CODE %d", eap_hdr->code);
+	}
+}
+
+static void
+dhd_dump_eapol_4way_message(dhd_pub_t *dhd, int ifidx, uint8 *pktdata, bool tx,
+	uint32 *pkthash, uint16 *pktfate)
+{
+	eapol_header_t *eapol_hdr;
+	eapol_key_hdr_t *eap_key;
+	msg_eapol_t type;
+	char *ifname;
+	bool cond;
+	char seabuf[ETHER_ADDR_STR_LEN]="";
+	char deabuf[ETHER_ADDR_STR_LEN]="";
+
+	if (!pktdata) {
+		DHD_PKTDUMP(("%s: pktdata is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	bcm_ether_ntoa((struct ether_addr *)pktdata, deabuf);
+	bcm_ether_ntoa((struct ether_addr *)(pktdata+6), seabuf);
+
+	type = dhd_is_4way_msg(pktdata);
+	ifname = dhd_ifname(dhd, ifidx);
+	eapol_hdr = (eapol_header_t *)pktdata;
+	eap_key = (eapol_key_hdr_t *)(eapol_hdr->body);
+	cond = (tx && pktfate) ? FALSE : TRUE;
+
+	if (eap_key->type != EAPOL_WPA2_KEY && eap_key->type != EAPOL_WPA_KEY) {
+		EAP_PRINT_OTHER("NON EAPOL_WPA2_KEY %d", eap_key->type);
+		return;
+	}
+
+	switch (type) {
+	case EAPOL_4WAY_M1:
+#ifdef WL_EXT_IAPSTA
+		wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_4WAY_M1);
+#endif
+		DHD_STATLOG_DATA(dhd, ST(EAPOL_M1), ifidx, tx, cond);
+		EAP_PRINT("EAPOL Packet, 4-way handshake, M1");
+		break;
+	case EAPOL_4WAY_M2:
+#ifdef WL_EXT_IAPSTA
+		wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_4WAY_M2);
+#endif
+		DHD_STATLOG_DATA(dhd, ST(EAPOL_M2), ifidx, tx, cond);
+		EAP_PRINT("EAPOL Packet, 4-way handshake, M2");
+		break;
+	case EAPOL_4WAY_M3:
+#ifdef WL_EXT_IAPSTA
+		wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_4WAY_M3);
+#endif
+		DHD_STATLOG_DATA(dhd, ST(EAPOL_M3), ifidx, tx, cond);
+		EAP_PRINT("EAPOL Packet, 4-way handshake, M3");
+		break;
+	case EAPOL_4WAY_M4:
+#ifdef WL_EXT_IAPSTA
+		wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_4WAY_M4);
+#endif
+		DHD_STATLOG_DATA(dhd, ST(EAPOL_M4), ifidx, tx, cond);
+		EAP_PRINT("EAPOL Packet, 4-way handshake, M4");
+		break;
+	case EAPOL_GROUPKEY_M1:
+#ifdef WL_EXT_IAPSTA
+		wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_GROUPKEY_M1);
+#endif
+		DHD_STATLOG_DATA(dhd, ST(EAPOL_GROUPKEY_M1), ifidx, tx, cond);
+		EAP_PRINT_REPLAY("EAPOL Packet, GROUP Key handshake, M1");
+		break;
+	case EAPOL_GROUPKEY_M2:
+#ifdef WL_EXT_IAPSTA
+		wl_ext_update_conn_state(dhd, ifidx, CONN_STATE_GROUPKEY_M2);
+#endif
+		DHD_STATLOG_DATA(dhd, ST(EAPOL_GROUPKEY_M2), ifidx, tx, cond);
+		EAP_PRINT_REPLAY("EAPOL Packet, GROUP Key handshake, M2");
+		if (ifidx == 0 && tx && pktfate) {
+			dhd_dump_mod_pkt_timer(dhd, PKT_CNT_RSN_GRPKEY_UP);
+		}
+		break;
+	default:
+		DHD_STATLOG_DATA(dhd, ST(8021X_OTHER), ifidx, tx, cond);
+		EAP_PRINT_OTHER("OTHER 4WAY type=%d", type);
+		break;
+	}
+}
+
+void
+dhd_dump_eapol_message(dhd_pub_t *dhd, int ifidx, uint8 *pktdata,
+	uint32 pktlen, bool tx, uint32 *pkthash, uint16 *pktfate)
+{
+	char *ifname;
+	eapol_header_t *eapol_hdr = (eapol_header_t *)pktdata;
+	bool cond;
+	char seabuf[ETHER_ADDR_STR_LEN]="";
+	char deabuf[ETHER_ADDR_STR_LEN]="";
+
+	if (!pktdata) {
+		DHD_ERROR(("%s: pktdata is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	bcm_ether_ntoa((struct ether_addr *)pktdata, deabuf);
+	bcm_ether_ntoa((struct ether_addr *)(pktdata+6), seabuf);
+
+	eapol_hdr = (eapol_header_t *)pktdata;
+	ifname = dhd_ifname(dhd, ifidx);
+	cond = (tx && pktfate) ? FALSE : TRUE;
+
+	if (eapol_hdr->type == EAP_PACKET) {
+		dhd_dump_eap_packet(dhd, ifidx, pktdata, pktlen, tx,
+			pkthash, pktfate);
+	} else if (eapol_hdr->type == EAPOL_START) {
+		DHD_STATLOG_DATA(dhd, ST(EAPOL_START), ifidx, tx, cond);
+		EAP_PRINT("EAP Packet, EAPOL-Start");
+	} else if (eapol_hdr->type == EAPOL_KEY) {
+		dhd_dump_eapol_4way_message(dhd, ifidx, pktdata, tx,
+			pkthash, pktfate);
+	} else {
+		DHD_STATLOG_DATA(dhd, ST(8021X_OTHER), ifidx, tx, cond);
+		EAP_PRINT_OTHER("OTHER 8021X");
+	}
+}
+#endif /* DHD_8021X_DUMP */
+
+bool
+dhd_check_ip_prot(uint8 *pktdata, uint16 ether_type)
+{
+	hdr_fmt_t *b = (hdr_fmt_t *)&pktdata[ETHER_HDR_LEN];
+	struct ipv4_hdr *iph = &b->iph;
+
+	/* check IP header */
+	if ((ether_type != ETHER_TYPE_IP) ||
+		(IPV4_HLEN(iph) < IPV4_HLEN_MIN) ||
+		(IP_VER(iph) != IP_VER_4)) {
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+bool
+dhd_check_dhcp(uint8 *pktdata)
+{
+	hdr_fmt_t *b = (hdr_fmt_t *)&pktdata[ETHER_HDR_LEN];
+	struct ipv4_hdr *iph = &b->iph;
+
+	if (IPV4_PROT(iph) != IP_PROT_UDP) {
+		return FALSE;
+	}
+
+	/* check UDP port for bootp (67, 68) */
+	if (b->udph.src_port != htons(DHCP_PORT_SERVER) &&
+	        b->udph.src_port != htons(DHCP_PORT_CLIENT) &&
+	        b->udph.dst_port != htons(DHCP_PORT_SERVER) &&
+	        b->udph.dst_port != htons(DHCP_PORT_CLIENT)) {
+	        return FALSE;
+	}
+
+	/* check header length */
+	if (ntohs(iph->tot_len) < ntohs(b->udph.len) + sizeof(struct bcmudp_hdr)) {
+	        return FALSE;
+	}
+	return TRUE;
+}
+
+#define BOOTP_CHADDR_LEN		16
+#define BOOTP_SNAME_LEN			64
+#define BOOTP_FILE_LEN			128
+#define BOOTP_MIN_DHCP_OPT_LEN		312
+#define BOOTP_MAGIC_COOKIE_LEN		4
+
+typedef struct bootp_fmt {
+	struct ipv4_hdr iph;
+	struct bcmudp_hdr udph;
+	uint8 op;
+	uint8 htype;
+	uint8 hlen;
+	uint8 hops;
+	uint32 transaction_id;
+	uint16 secs;
+	uint16 flags;
+	uint32 client_ip;
+	uint32 assigned_ip;
+	uint32 server_ip;
+	uint32 relay_ip;
+	uint8 hw_address[BOOTP_CHADDR_LEN];
+	uint8 server_name[BOOTP_SNAME_LEN];
+	uint8 file_name[BOOTP_FILE_LEN];
+	uint8 options[BOOTP_MIN_DHCP_OPT_LEN];
+} PACKED_STRUCT bootp_fmt_t;
+static const uint8 bootp_magic_cookie[4] = { 99, 130, 83, 99 };
+
+#ifdef DHD_DHCP_DUMP
+#if defined(DHD_DHCP_DUMP) || defined(WL_CFGVENDOR_CUST_ADVLOG)
+#define DHCP_MSGTYPE_DISCOVER		1
+#define DHCP_MSGTYPE_OFFER		2
+#define DHCP_MSGTYPE_REQUEST		3
+#define DHCP_MSGTYPE_DECLINE		4
+#define DHCP_MSGTYPE_ACK		5
+#define DHCP_MSGTYPE_NAK		6
+#define DHCP_MSGTYPE_RELEASE		7
+#define DHCP_MSGTYPE_INFORM		8
+#endif /* DHD_DHCP_DUMP || WL_CFGVENDOR_CUST_ADVLOG */
+
+#define DHCP_PRINT(str) \
+	do { \
+		if (tx) { \
+			DHD_PKTDUMP(("[%s] " str " %8s[%8s] [TX] : %s(%s) %s %s(%s)"TXFATE_FMT"\n", \
+				ifname, typestr, opstr, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+				tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, \
+				TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+		} else { \
+			DHD_PKTDUMP(("[%s] " str " %8s[%8s] [RX] : %s(%s) %s %s(%s)\n", \
+				ifname, typestr, opstr, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+				tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf)); \
+		} \
+	} while (0)
+
+#define MAX_DHCP_OPS_STR 3
+#define MAX_DHCP_TYPES_STR 9
+
+static char dhcp_ops[MAX_DHCP_OPS_STR][10] = {
+	"NA", "REQUEST", "REPLY"
+};
+static char dhcp_types[MAX_DHCP_TYPES_STR][10] = {
+	"NA", "DISCOVER", "OFFER", "REQUEST", "DECLINE", "ACK", "NAK", "RELEASE", "INFORM"
+};
+
+#define DHCP_OPS_STR(ops)	((ops < MAX_DHCP_OPS_STR) ? \
+				(dhcp_ops[ops]) : "UNKNOWN_DHCP_OPS")
+#define DHCP_TYPES_STR(type)	((type < MAX_DHCP_TYPES_STR) ? \
+				(dhcp_types[type]) : "UNKNOWN_DHCP_TYPE")
+
+#ifdef DHD_IPV6_DUMP
+#define DHCP6_PRINT(str) \
+		do { \
+			if (tx) { \
+				DHD_PKTDUMP_MEM((str " %s[%s] [TX] -" TXFATE_FMT "\n", \
+					typestr, ifname, \
+					TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+			} else { \
+				DHD_PKTDUMP_MEM((str " %s[%s] [RX]\n", \
+					typestr, ifname)); \
+			} \
+		} while (0)
+
+#define ICMPv6_PRINT(str) \
+	do { \
+		if (tx) { \
+			DHD_PKTDUMP_MEM((str " %s[%s] [TX] -" TXFATE_FMT "\n", \
+				typestr, ifname, \
+				TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+		} else { \
+			if (msgtype == ICMPV6_PKT_TYPE_RA) { \
+				DHD_PKTDUMP_MEM((str " %s[%s] flags 0x%x [RX]\n", \
+					typestr, ifname, icmp6_ra_flag)); \
+			} else { \
+				DHD_PKTDUMP_MEM((str " %s[%s] [RX]\n", \
+					typestr, ifname)); \
+			} \
+		} \
+	} while (0)
+
+#define MAX_DHCP6_TYPES_STR 11
+#define MAX_DHCP6_TYPES_STAT 11
+
+static char dhcp6_types[MAX_DHCP6_TYPES_STR][10] = {
+	"NA", "SOLICIT", "ADVERTISE", "REQUEST", "CONFIRM",
+	"RENEW", "REBIND", "REPLY", "RELEASE", "DECLINE", "RECONFIG"
+};
+#define DHCP6_TYPES_STR(type)    ((type < MAX_DHCP6_TYPES_STR) ? \
+		(dhcp6_types[type]) : "UNKNOWN_DHCP_TYPE")
+
+static const int dhcp6_types_stat[MAX_DHCP6_TYPES_STAT] = {
+	ST(INVALID), ST(SOLICIT), ST(ADVERTISE), ST(REQUEST),
+	ST(CONFIRM), ST(RENEW), ST(REBIND), ST(REPLY),
+	ST(RELEASE), ST(DECLINE), ST(RECONFIGURE)
+};
+#define DHCP6_TYPES_STAT(type)   ((type < MAX_DHCP6_TYPES_STAT) ? \
+		(dhcp6_types_stat[type]) : ST(INVALID))
+
+#define MAX_ICMPV6_TYPES_STAT 10
+static const int icmpv6_types_stat[MAX_ICMPV6_TYPES_STAT] = {
+	ST(INVALID), ST(ECHO_REQ), ST(ECHO_REPLY), ST(MULTI_QUERY),
+	ST(MULTI_REPORT), ST(MULTI_DONE), ST(ROUTER_SOLIC), ST(ROUTER_ADV),
+	ST(NEIGHBOR_SOLIC), ST(NEIGHBOR_ADV)
+};
+#define ICMPV6_TYPES_STAT(type)   ((type < MAX_ICMPV6_TYPES_STAT) ? \
+		(icmpv6_types_stat[type]) : ST(INVALID))
+#endif /* DHD_IPV6_DUMP */
+
+#ifdef DHD_STATUS_LOGGING
+#define MAX_DHCP_TYPES_STAT	9
+#define DHCP_TYPES_STAT(type)	((type < MAX_DHCP_TYPES_STAT) ? \
+				(dhcp_types_stat[type]) : ST(INVALID))
+static const int dhcp_types_stat[MAX_DHCP_TYPES_STAT] = {
+	ST(INVALID), ST(DHCP_DISCOVER), ST(DHCP_OFFER), ST(DHCP_REQUEST),
+	ST(DHCP_DECLINE), ST(DHCP_ACK), ST(DHCP_NAK), ST(DHCP_RELEASE),
+	ST(DHCP_INFORM)
+};
+#endif /* DHD_STATUS_LOGGING */
+
+void
+dhd_dhcp_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
+	uint32 *pkthash, uint16 *pktfate)
+{
+	bootp_fmt_t *b = (bootp_fmt_t *)&pktdata[ETHER_HDR_LEN];
+	struct ipv4_hdr *iph = &b->iph;
+	uint8 *ptr, *opt, *end = (uint8 *) b + ntohs(b->iph.tot_len);
+	uint8 dhcp_type = 0;
+	int len, opt_len;
+	char *ifname = NULL, *typestr = NULL, *opstr = NULL;
+	bool cond;
+	char sabuf[20]="", dabuf[20]="";
+	char seabuf[ETHER_ADDR_STR_LEN]="";
+	char deabuf[ETHER_ADDR_STR_LEN]="";
+
+	if (!(dump_msg_level & DUMP_DHCP_VAL))
+		return;
+	bcm_ip_ntoa((struct ipv4_addr *)iph->src_ip, sabuf);
+	bcm_ip_ntoa((struct ipv4_addr *)iph->dst_ip, dabuf);
+	bcm_ether_ntoa((struct ether_addr *)pktdata, deabuf);
+	bcm_ether_ntoa((struct ether_addr *)(pktdata+6), seabuf);
+
+	ifname = dhd_ifname(dhdp, ifidx);
+	cond = (tx && pktfate) ? FALSE : TRUE;
+	len = ntohs(b->udph.len) - sizeof(struct bcmudp_hdr);
+	opt_len = len - (sizeof(*b) - sizeof(struct ipv4_hdr) -
+		sizeof(struct bcmudp_hdr) - sizeof(b->options));
+
+	/* parse bootp options */
+	if (opt_len >= BOOTP_MAGIC_COOKIE_LEN &&
+		!memcmp(b->options, bootp_magic_cookie, BOOTP_MAGIC_COOKIE_LEN)) {
+		ptr = &b->options[BOOTP_MAGIC_COOKIE_LEN];
+		while (ptr < end && *ptr != 0xff) {
+			opt = ptr++;
+			if (*opt == 0) {
+				continue;
+			}
+			ptr += *ptr + 1;
+			if (ptr >= end) {
+				break;
+			}
+			if (*opt == DHCP_OPT_MSGTYPE) {
+				if (opt[1]) {
+					dhcp_type = opt[2];
+					typestr = DHCP_TYPES_STR(dhcp_type);
+					opstr = DHCP_OPS_STR(b->op);
+					DHD_STATLOG_DATA(dhdp, DHCP_TYPES_STAT(dhcp_type),
+						ifidx, tx, cond);
+					DHCP_PRINT("DHCP");
+					break;
+				}
+			}
+		}
+	}
+}
+#endif /* DHD_DHCP_DUMP */
+
+bool
+dhd_check_icmp(uint8 *pktdata)
+{
+	uint8 *pkt = (uint8 *)&pktdata[ETHER_HDR_LEN];
+	struct ipv4_hdr *iph = (struct ipv4_hdr *)pkt;
+
+	if (IPV4_PROT(iph) != IP_PROT_ICMP) {
+		return FALSE;
+	}
+
+	/* check header length */
+	if (ntohs(iph->tot_len) - IPV4_HLEN(iph) < sizeof(struct bcmicmp_hdr)) {
+		return FALSE;
+	}
+	return TRUE;
+}
+
+bool
+dhd_check_icmpv6(uint8 *pktdata, uint32 plen)
+{
+	uint8 *pkt = (uint8 *)&pktdata[ETHER_HDR_LEN];
+	struct ipv6_hdr *ip6h = (struct ipv6_hdr *)pkt;
+
+	if (IPV6_PROT(ip6h) != IP_PROT_ICMP6) {
+		return FALSE;
+	}
+
+	/* check header length */
+	if (plen <= IPV6_MIN_HLEN) {
+		return FALSE;
+	}
+	return TRUE;
+}
+
+#ifdef DHD_ICMP_DUMP
+#define ICMP_TYPE_DEST_UNREACH		3
+#define ICMP_ECHO_SEQ_OFFSET		6
+#define ICMP_ECHO_SEQ(h) (*(uint16 *)((uint8 *)(h) + (ICMP_ECHO_SEQ_OFFSET)))
+#define ICMP_PING_PRINT(str) \
+	do { \
+		if (tx) { \
+			DHD_PKTDUMP_MEM(("[%s] "str " [TX] : %s(%s) %s %s(%s) SEQNUM=%d" \
+				TXFATE_FMT"\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+				tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, seqnum, \
+				TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+		} else { \
+			DHD_PKTDUMP_MEM(("[%s] "str " [RX] : %s(%s) %s %s(%s) SEQNUM=%d\n", \
+				ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+				tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, seqnum)); \
+		} \
+	} while (0)
+
+#define ICMP_PRINT(str) \
+	do { \
+		if (tx) { \
+			DHD_PKTDUMP_MEM(("[%s] "str " [TX] : %s(%s) %s %s(%s) TYPE=%d, CODE=%d" \
+				TXFATE_FMT "\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+				tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, type, code, \
+				TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+		} else { \
+			DHD_PKTDUMP_MEM(("[%s] "str " [RX] : %s(%s) %s %s(%s) TYPE=%d," \
+				" CODE=%d\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+				tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, type, code)); \
+		} \
+	} while (0)
+
+void
+dhd_icmp_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
+	uint32 *pkthash, uint16 *pktfate)
+{
+	uint8 *pkt = (uint8 *)&pktdata[ETHER_HDR_LEN];
+	struct ipv4_hdr *iph = (struct ipv4_hdr *)pkt;
+	struct bcmicmp_hdr *icmph;
+	char *ifname;
+	bool cond;
+	uint16 seqnum, type, code;
+	char sabuf[20]="", dabuf[20]="";
+	char seabuf[ETHER_ADDR_STR_LEN]="";
+	char deabuf[ETHER_ADDR_STR_LEN]="";
+
+	if (!(dump_msg_level & DUMP_ICMP_VAL))
+		return;
+
+	ifname = dhd_ifname(dhdp, ifidx);
+	cond = (tx && pktfate) ? FALSE : TRUE;
+	icmph = (struct bcmicmp_hdr *)((uint8 *)pkt + sizeof(struct ipv4_hdr));
+	seqnum = 0;
+	type = icmph->type;
+	code = icmph->code;
+	bcm_ip_ntoa((struct ipv4_addr *)iph->src_ip, sabuf);
+	bcm_ip_ntoa((struct ipv4_addr *)iph->dst_ip, dabuf);
+	bcm_ether_ntoa((struct ether_addr *)pktdata, deabuf);
+	bcm_ether_ntoa((struct ether_addr *)(pktdata+6), seabuf);
+	if (type == ICMP_TYPE_ECHO_REQUEST) {
+		seqnum = ntoh16(ICMP_ECHO_SEQ(icmph));
+		DHD_STATLOG_DATA(dhdp, ST(ICMP_PING_REQ), ifidx, tx, cond);
+		ICMP_PING_PRINT("PING REQUEST");
+	} else if (type == ICMP_TYPE_ECHO_REPLY) {
+		seqnum = ntoh16(ICMP_ECHO_SEQ(icmph));
+		DHD_STATLOG_DATA(dhdp, ST(ICMP_PING_RESP), ifidx, tx, cond);
+		ICMP_PING_PRINT("PING REPLY  ");
+	} else if (type == ICMP_TYPE_DEST_UNREACH) {
+		DHD_STATLOG_DATA(dhdp, ST(ICMP_DEST_UNREACH), ifidx, tx, cond);
+		ICMP_PRINT("ICMP DEST UNREACH");
+	} else {
+		DHD_STATLOG_DATA(dhdp, ST(ICMP_OTHER), ifidx, tx, cond);
+		ICMP_PRINT("ICMP OTHER");
+	}
+}
+#endif /* DHD_ICMP_DUMP */
+
+bool
+dhd_check_arp(uint8 *pktdata, uint16 ether_type)
+{
+	uint8 *pkt = (uint8 *)&pktdata[ETHER_HDR_LEN];
+	struct bcmarp *arph = (struct bcmarp *)pkt;
+
+	/* validation check */
+	if ((ether_type != ETHER_TYPE_ARP) ||
+		(arph->htype != hton16(HTYPE_ETHERNET)) ||
+		(arph->hlen != ETHER_ADDR_LEN) ||
+		(arph->plen != 4)) {
+		return FALSE;
+	}
+	return TRUE;
+}
+
+#ifdef DHD_ARP_DUMP
+#ifdef BOARD_HIKEY
+/* On Hikey, due to continuous ARP prints
+ * DPC not scheduled. Hence rate limit the prints.
+ */
+#define DHD_PKTDUMP_ARP DHD_ERROR_RLMT
+#else
+#define DHD_PKTDUMP_ARP DHD_PKTDUMP
+#endif /* BOARD_HIKEY */
+
+#define ARP_PRINT(str) \
+	do { \
+		if (tx) { \
+			if (dump_enabled && pktfate && !TX_FATE_ACKED(pktfate)) { \
+				DHD_PKTDUMP(("[%s] "str " [TX] : %s(%s) %s %s(%s)"TXFATE_FMT"\n", \
+					ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+					tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, \
+					TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+			} else { \
+				DHD_PKTDUMP_MEM(("[%s] "str " [TX] : %s(%s) %s %s(%s)"TXFATE_FMT"\n", \
+					ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+					tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, \
+					TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+			} \
+		} else { \
+			DHD_PKTDUMP_MEM(("[%s] "str " [RX] : %s(%s) %s %s(%s)\n", \
+				ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+				tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf)); \
+		} \
+	} while (0) \
+
+#define ARP_PRINT_OTHER(str) \
+	do { \
+		if (tx) { \
+			if (dump_enabled && pktfate && !TX_FATE_ACKED(pktfate)) { \
+				DHD_PKTDUMP(("[%s] "str " [TX] : %s(%s) %s %s(%s) op_code=%d" \
+					TXFATE_FMT "\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+					tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, opcode, \
+					TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+			} else { \
+				DHD_PKTDUMP_MEM(("[%s] "str " [TX] : %s(%s) %s %s(%s) op_code=%d" \
+				TXFATE_FMT "\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+					tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, opcode, \
+				TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+			} \
+		} else { \
+			DHD_PKTDUMP_MEM(("[%s] "str " [RX] : %s(%s) %s %s(%s) op_code=%d\n", \
+				ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+					tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, opcode)); \
+		} \
+	} while (0)
+
+void
+dhd_arp_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
+	uint32 *pkthash, uint16 *pktfate)
+{
+	uint8 *pkt = (uint8 *)&pktdata[ETHER_HDR_LEN];
+	struct bcmarp *arph = (struct bcmarp *)pkt;
+	char *ifname;
+	uint16 opcode;
+	bool cond, dump_enabled;
+	char sabuf[20]="", dabuf[20]="";
+	char seabuf[ETHER_ADDR_STR_LEN]="";
+	char deabuf[ETHER_ADDR_STR_LEN]="";
+
+	if (!(dump_msg_level & DUMP_ARP_VAL))
+		return;
+
+	ifname = dhd_ifname(dhdp, ifidx);
+	opcode = ntoh16(arph->oper);
+	cond = (tx && pktfate) ? FALSE : TRUE;
+	dump_enabled = dhd_dump_pkt_enabled(dhdp);
+	bcm_ip_ntoa((struct ipv4_addr *)arph->src_ip, sabuf);
+	bcm_ip_ntoa((struct ipv4_addr *)arph->dst_ip, dabuf);
+	bcm_ether_ntoa((struct ether_addr *)arph->dst_eth, deabuf);
+	bcm_ether_ntoa((struct ether_addr *)arph->src_eth, seabuf);
+	if (opcode == ARP_OPC_REQUEST) {
+		DHD_STATLOG_DATA(dhdp, ST(ARP_REQ), ifidx, tx, cond);
+		ARP_PRINT("ARP REQUEST ");
+	} else if (opcode == ARP_OPC_REPLY) {
+		DHD_STATLOG_DATA(dhdp, ST(ARP_RESP), ifidx, tx, cond);
+		ARP_PRINT("ARP RESPONSE");
+	} else {
+		ARP_PRINT_OTHER("ARP OTHER");
+	}
+
+	if (ifidx == 0) {
+		dhd_dump_pkt_cnts_inc(dhdp, tx, pktfate, PKT_CNT_TYPE_ARP);
+	}
+}
+#endif /* DHD_ARP_DUMP */
+
+bool
+dhd_check_dns(uint8 *pktdata)
+{
+	hdr_fmt_t *dnsh = (hdr_fmt_t *)&pktdata[ETHER_HDR_LEN];
+	struct ipv4_hdr *iph = &dnsh->iph;
+
+	if (IPV4_PROT(iph) != IP_PROT_UDP) {
+		return FALSE;
+	}
+
+	/* check UDP port for DNS */
+	if (dnsh->udph.src_port != hton16(UDP_PORT_DNS) &&
+		dnsh->udph.dst_port != hton16(UDP_PORT_DNS)) {
+		return FALSE;
+	}
+
+	/* check header length */
+	if (ntoh16(iph->tot_len) < (ntoh16(dnsh->udph.len) +
+		sizeof(struct bcmudp_hdr))) {
+		return FALSE;
+	}
+	return TRUE;
+}
+
+#ifdef DHD_DNS_DUMP
+typedef struct dns_fmt {
+	struct ipv4_hdr iph;
+	struct bcmudp_hdr udph;
+	uint16 id;
+	uint16 flags;
+	uint16 qdcount;
+	uint16 ancount;
+	uint16 nscount;
+	uint16 arcount;
+} PACKED_STRUCT dns_fmt_t;
+
+#define DNS_QR_LOC		15
+#define DNS_OPCODE_LOC		11
+#define DNS_RCODE_LOC		0
+#define DNS_QR_MASK		((0x1) << (DNS_QR_LOC))
+#define DNS_OPCODE_MASK		((0xF) << (DNS_OPCODE_LOC))
+#define DNS_RCODE_MASK		((0xF) << (DNS_RCODE_LOC))
+#define GET_DNS_QR(flags)	(((flags) & (DNS_QR_MASK)) >> (DNS_QR_LOC))
+#define GET_DNS_OPCODE(flags)	(((flags) & (DNS_OPCODE_MASK)) >> (DNS_OPCODE_LOC))
+#define GET_DNS_RCODE(flags)	(((flags) & (DNS_RCODE_MASK)) >> (DNS_RCODE_LOC))
+#define DNS_UNASSIGNED_OPCODE(flags) ((GET_DNS_OPCODE(flags) >= (6)))
+
+static const char dns_opcode_types[][11] = {
+	"QUERY", "IQUERY", "STATUS", "UNASSIGNED", "NOTIFY", "UPDATE"
+};
+
+#define DNSOPCODE(op)	\
+	(DNS_UNASSIGNED_OPCODE(flags) ? "UNASSIGNED" : dns_opcode_types[op])
+
+#define DNS_REQ_PRINT(str) \
+	do { \
+		if (tx) { \
+			if (dump_enabled && pktfate && !TX_FATE_ACKED(pktfate)) { \
+				DHD_PKTDUMP(("[%s] " str " [TX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s" \
+					TXFATE_FMT "\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+					tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, \
+					id, DNSOPCODE(opcode), TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+			} else { \
+				DHD_PKTDUMP_MEM(("[%s] " str " [TX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s" \
+					TXFATE_FMT "\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+					tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, \
+					id, DNSOPCODE(opcode), TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+			} \
+		} else { \
+			DHD_PKTDUMP_MEM(("[%s] " str " [RX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s\n", \
+				ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, tx?"->":"<-", \
+				tx?dabuf:sabuf, tx?deabuf:seabuf, id, DNSOPCODE(opcode))); \
+		} \
+	} while (0)
+
+#define DNS_RESP_PRINT(str) \
+	do { \
+		if (tx) { \
+			if (dump_enabled && pktfate && !TX_FATE_ACKED(pktfate)) { \
+				DHD_PKTDUMP(("[%s] " str " [TX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s RCODE:%d" \
+					TXFATE_FMT "\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+					tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, id, DNSOPCODE(opcode), \
+					GET_DNS_RCODE(flags), TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+			} else { \
+				DHD_PKTDUMP_MEM(("[%s] " str " [TX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s RCODE:%d" \
+					TXFATE_FMT "\n", ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+					tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, id, DNSOPCODE(opcode), \
+					GET_DNS_RCODE(flags), TX_PKTHASH(pkthash), TX_FATE(pktfate))); \
+			} \
+		} else { \
+			DHD_PKTDUMP_MEM(("[%s] " str " [RX] : %s(%s) %s %s(%s) ID:0x%04X OPCODE:%s RCODE:%d\n", \
+				ifname, tx?sabuf:dabuf, tx?seabuf:deabuf, \
+				tx?"->":"<-", tx?dabuf:sabuf, tx?deabuf:seabuf, \
+				id, DNSOPCODE(opcode), GET_DNS_RCODE(flags))); \
+		} \
+	} while (0)
+
+void
+dhd_dns_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
+	uint32 *pkthash, uint16 *pktfate)
+{
+	dns_fmt_t *dnsh = (dns_fmt_t *)&pktdata[ETHER_HDR_LEN];
+	struct ipv4_hdr *iph = &dnsh->iph;
+	uint16 flags, opcode, id;
+	char *ifname;
+	bool cond, dump_enabled;
+	char sabuf[20]="", dabuf[20]="";
+	char seabuf[ETHER_ADDR_STR_LEN]="";
+	char deabuf[ETHER_ADDR_STR_LEN]="";
+
+	if (!(dump_msg_level & DUMP_DNS_VAL))
+		return;
+
+	ifname = dhd_ifname(dhdp, ifidx);
+	cond = (tx && pktfate) ? FALSE : TRUE;
+	dump_enabled = dhd_dump_pkt_enabled(dhdp);
+	flags = hton16(dnsh->flags);
+	opcode = GET_DNS_OPCODE(flags);
+	id = hton16(dnsh->id);
+	bcm_ip_ntoa((struct ipv4_addr *)iph->src_ip, sabuf);
+	bcm_ip_ntoa((struct ipv4_addr *)iph->dst_ip, dabuf);
+	bcm_ether_ntoa((struct ether_addr *)pktdata, deabuf);
+	bcm_ether_ntoa((struct ether_addr *)(pktdata+6), seabuf);
+	if (GET_DNS_QR(flags)) {
+		/* Response */
+		DHD_STATLOG_DATA(dhdp, ST(DNS_RESP), ifidx, tx, cond);
+		DNS_RESP_PRINT("DNS RESPONSE");
+	} else {
+		/* Request */
+		DHD_STATLOG_DATA(dhdp, ST(DNS_QUERY), ifidx, tx, cond);
+		DNS_REQ_PRINT("DNS REQUEST");
+	}
+
+	if (ifidx == 0) {
+		dhd_dump_pkt_cnts_inc(dhdp, tx, pktfate, PKT_CNT_TYPE_DNS);
+	}
+}
+#endif /* DHD_DNS_DUMP */
+
+#ifdef DHD_IPV6_DUMP
+void
+dhd_dhcp6_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
+uint32 *pkthash, uint16 *pktfate)
+{
+	dhcp6_fmt_t *b = (dhcp6_fmt_t *)&pktdata[ETHER_HDR_LEN];
+	char *ifname = NULL, *typestr = NULL;
+	uint8 msgtype;
+	bool cond;
+
+	ifname = dhd_ifname(dhdp, ifidx);
+	msgtype = ntoh16(b->msgtype);
+	cond = (tx && pktfate) ? FALSE : TRUE;
+
+	/* only handle DHCPv6 msgtype from 1 ~ 10 */
+	if (msgtype > 10)
+		return;
+
+	typestr = DHCP6_TYPES_STR(msgtype);
+	DHD_STATLOG_DATA(dhdp, DHCP6_TYPES_STAT(msgtype),
+			ifidx, tx, cond);
+	DHCP6_PRINT("DHCPv6");
+	return;
+}
+
+void
+dhd_dns6_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
+	uint32 *pkthash, uint16 *pktfate)
+{
+	dns6_fmt_t *dns6h = (dns6_fmt_t *)&pktdata[ETHER_HDR_LEN];
+	uint16 flags, opcode, id;
+	char *ifname;
+	bool cond, dump_enabled;
+
+	ifname = dhd_ifname(dhdp, ifidx);
+	cond = (tx && pktfate) ? FALSE : TRUE;
+	dump_enabled = dhd_dump_pkt_enabled(dhdp);
+	flags = hton16(dns6h->flags);
+	opcode = GET_DNS_OPCODE(flags);
+	id = hton16(dns6h->id);
+	if (GET_DNS_QR(flags)) {
+		/* Response */
+		DHD_STATLOG_DATA(dhdp, ST(DNS_RESP), ifidx, tx, cond);
+		DNS_RESP_PRINT("DNS6 RESPONSE");
+	} else {
+		/* Request */
+		DHD_STATLOG_DATA(dhdp, ST(DNS_QUERY), ifidx, tx, cond);
+		DNS_REQ_PRINT("DNS6 REQUEST");
+	}
+}
+
+char*
+icmpv6_types(uint8 type)
+{
+	switch (type) {
+		case ICMPV6_PKT_TYPE_ECHO_REQ:
+			return "Echo Request";
+		case ICMPV6_PKT_TYPE_ECHO_REPLY:
+			return "Echo Reply";
+		case ICMPV6_PKT_TYPE_MULTI_LST_QUERY:
+			return "Multicast Listener Query";
+		case ICMPV6_PKT_TYPE_MULTI_LST_REPORT:
+			return "Multicast Listener Report";
+		case ICMPV6_PKT_TYPE_MULTI_LST_DONE:
+			return "Multicast Listener Done";
+		case ICMPV6_PKT_TYPE_RS:
+			return "Router Solicitation";
+		case ICMPV6_PKT_TYPE_RA:
+			return "Router Advertisement";
+		case ICMPV6_PKT_TYPE_NS:
+			return "Neighbor Solicitation";
+		case ICMPV6_PKT_TYPE_NA:
+			return "Neighbor Advertisement";
+		default:
+			return NULL;
+	}
+}
+
+void
+dhd_icmpv6_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
+uint32 *pkthash, uint16 *pktfate)
+{
+	struct ipv6_hdr *ip6h = (struct ipv6_hdr *)&pktdata[ETHER_HDR_LEN];
+	struct icmp6_hdr *icmpv6;
+	char *ifname = NULL, *typestr = NULL;
+	uint8 icmp6_ra_flag;
+	uint8 msgtype;
+	bool cond;
+
+	uint8 nexthdr = ip6h->nexthdr;
+
+	if (nexthdr != ICMPV6_HEADER_TYPE)
+		return;
+
+	icmpv6 = (struct icmp6_hdr *) ((uint8 *)ip6h + sizeof(struct ipv6_hdr));
+	ifname = dhd_ifname(dhdp, ifidx);
+	msgtype = icmpv6->icmp6_type;
+	cond = (tx && pktfate) ? FALSE : TRUE;
+	typestr = icmpv6_types(msgtype);
+
+	/* only handle ICMPv6 msgtype from 128 ~ 136 */
+	if (!typestr)
+		return;
+
+	if (msgtype == ICMPV6_PKT_TYPE_RA) {
+		/* check IPv6 configuration is stateless or stateful DHCPv6 */
+		icmp6_ra_flag = *((uint8 *)ip6h + sizeof(struct ipv6_hdr) + ICMPV6_RA_FLAG_OFFSET);
+	}
+
+	DHD_STATLOG_DATA(dhdp, ICMPV6_TYPES_STAT(msgtype - 127),
+			ifidx, tx, cond);
+	ICMPv6_PRINT("ICMPv6");
+	return;
+}
+
+bool
+dhd_check_dhcp6(uint8 *pktdata, uint32 plen)
+{
+	ipv6hdr_fmt_t *b = (ipv6hdr_fmt_t *)&pktdata[ETHER_HDR_LEN];
+	struct ipv6_hdr *ip6h = &b->ip6h;
+
+	/* check header length */
+	if (plen <= IPV6_MIN_HLEN) {
+		return FALSE;
+	}
+
+	if (IPV6_PROT(ip6h) != IP_PROT_UDP) {
+		return FALSE;
+	}
+
+	/* check UDP port for bootp (546, 547) */
+	if (b->udph.src_port != htons(DHCP6_PORT_SERVER) &&
+			b->udph.src_port != htons(DHCP6_PORT_CLIENT) &&
+			b->udph.dst_port != htons(DHCP6_PORT_SERVER) &&
+			b->udph.dst_port != htons(DHCP6_PORT_CLIENT)) {
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+bool
+dhd_check_dns6(uint8 *pktdata, uint32 plen)
+{
+	ipv6hdr_fmt_t *b = (ipv6hdr_fmt_t *)&pktdata[ETHER_HDR_LEN];
+	struct ipv6_hdr *ip6h = &b->ip6h;
+
+	/* check header length */
+	if (plen <= IPV6_MIN_HLEN) {
+		return FALSE;
+	}
+
+	if (IPV6_PROT(ip6h) != IP_PROT_UDP) {
+		return FALSE;
+	}
+
+	/* check UDP port for DNS */
+	if (b->udph.src_port != hton16(UDP_PORT_DNS) &&
+		b->udph.dst_port != hton16(UDP_PORT_DNS)) {
+		return FALSE;
+	}
+
+	return TRUE;
+}
+#endif /* DHD_IPV6_DUMP */
+
+#ifdef DHD_TRX_DUMP
+void
+dhd_trx_pkt_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, uint32 pktlen, bool tx)
+{
+	struct ether_header *eh;
+	uint16 protocol;
+	char *pkttype = "UNKNOWN";
+
+	if (!(dump_msg_level & DUMP_TRX_VAL))
+		return;
+
+	if (!dhdp) {
+		DHD_ERROR(("%s: dhdp is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	if (!pktdata) {
+		DHD_ERROR(("%s: pktdata is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	eh = (struct ether_header *)pktdata;
+	protocol = hton16(eh->ether_type);
+	BCM_REFERENCE(pktlen);
+
+	switch (protocol) {
+	case ETHER_TYPE_IP:
+		pkttype = "IP";
+		break;
+	case ETHER_TYPE_ARP:
+		pkttype = "ARP";
+		break;
+	case ETHER_TYPE_BRCM:
+		pkttype = "BRCM";
+		break;
+	case ETHER_TYPE_802_1X:
+		pkttype = "802.1X";
+		break;
+	case ETHER_TYPE_WAI:
+		pkttype = "WAPI";
+		break;
+	default:
+		break;
+	}
+
+	if (protocol != ETHER_TYPE_BRCM) {
+		if (pktdata[0] == 0xFF) {
+			DHD_PKTDUMP(("[%s] %s BROADCAST DUMP - %s\n",
+				dhd_ifname(dhdp, ifidx), tx?"TX":"RX", pkttype));
+		} else if (pktdata[0] & 1) {
+			DHD_PKTDUMP(("[%s] %s MULTICAST DUMP " MACDBG " - %s\n",
+				dhd_ifname(dhdp, ifidx), tx?"TX":"RX", MAC2STRDBG(pktdata), pkttype));
+		} else {
+			DHD_PKTDUMP(("[%s] %s DUMP - %s\n",
+				dhd_ifname(dhdp, ifidx), tx?"TX":"RX", pkttype));
+		}
+#ifdef DHD_RX_FULL_DUMP
+		prhex("Data", pktdata, pktlen);
+#endif /* DHD_RX_FULL_DUMP */
+	}
+	else {
+		DHD_PKTDUMP(("[%s] %s DUMP - %s\n",
+			dhd_ifname(dhdp, ifidx), tx?"TX":"RX", pkttype));
+	}
+}
+#endif /* DHD_RX_DUMP */
+
+#ifdef WL_CFGVENDOR_CUST_ADVLOG
+typedef struct dhd_advlog_arr_map_entry {
+	uint32 avglog_type;
+	dhd_advlog_map_entry_t *arr;
+	uint32 arr_len;
+} dhd_advlog_arr_map_entry_t;
+
+typedef enum dhd_advlog_type {
+	DHD_ADVLOG_DHCP_TX      = 0,
+	DHD_ADVLOG_DHCP_RX      = 1,
+	DHD_ADVLOG_EAP          = 2,
+	DHD_ADVLOG_EAPOL        = 3,
+	DHD_ADVLOG_LAST         = 4
+} dhd_advlog_type_t;
+
+static dhd_advlog_map_entry_t eap_type_map[] = {
+	{EAP_TYPE_IDENT, "Identity"},
+	{EAP_TYPE_TLS, "TLS"},
+	{EAP_TYPE_LEAP, "LEAP"},
+	{EAP_TYPE_TTLS, "TTLS"},
+	{EAP_TYPE_AKA, "AKA"},
+	{EAP_TYPE_PEAP, "PEAP"},
+	{EAP_TYPE_FAST,	"FAST"},
+	{EAP_TYPE_PSK, "PSK"},
+	{EAP_TYPE_AKAP, "AKAP"},
+};
+
+static dhd_advlog_map_entry_t eap_advlog_map[] = {
+	{EAP_CODE_REQUEST, "[EAP] REQ type=%s len=%d"},
+	{EAP_CODE_RESPONSE, "[EAP] RESP type=%s len=%d tx_status=%s"},
+	{EAP_CODE_SUCCESS, "[EAP] SUCC"},
+	{EAP_CODE_FAILURE, "[EAP] FAIL"},
+};
+
+static dhd_advlog_map_entry_t dhcp_tx_advlog_map[] = {
+	{DHCP_MSGTYPE_DISCOVER, "[DHCP] DISCOVER tx_status=%s"},
+	{DHCP_MSGTYPE_REQUEST, "[DHCP] REQUEST tx_status=%s"},
+};
+
+static dhd_advlog_map_entry_t dhcp_rx_advlog_map[] = {
+	{DHCP_MSGTYPE_OFFER, "[DHCP] OFFER"},
+	{DHCP_MSGTYPE_ACK, "[DHCP] ACK"},
+	{DHCP_MSGTYPE_NAK, "[DHCP] NAK"},
+};
+
+static dhd_advlog_map_entry_t eapol_advlog_map[] = {
+	{EAPOL_4WAY_M1, "[EAPOL] 4WAY M1"},
+	{EAPOL_4WAY_M2, "[EAPOL] 4WAY M2 tx_status=%s"},
+	{EAPOL_4WAY_M3, "[EAPOL] 4WAY M3"},
+	{EAPOL_4WAY_M4, "[EAPOL] 4WAY M4 tx_status=%s"},
+	{EAPOL_GROUPKEY_M1, "[EAPOL] GTK M1"},
+	{EAPOL_GROUPKEY_M2, "[EAPOL] GTK M2 tx_status=%s"},
+};
+
+static dhd_advlog_arr_map_entry_t advlog_map_arr[] = {
+	{DHD_ADVLOG_DHCP_TX, dhcp_tx_advlog_map, ARRAY_SIZE(dhcp_tx_advlog_map)},
+	{DHD_ADVLOG_DHCP_RX, dhcp_rx_advlog_map, ARRAY_SIZE(dhcp_rx_advlog_map)},
+	{DHD_ADVLOG_EAP, eap_advlog_map, ARRAY_SIZE(eap_advlog_map)},
+	{DHD_ADVLOG_EAPOL, eapol_advlog_map, ARRAY_SIZE(eapol_advlog_map)},
+};
+
+const char* get_advlog_val(dhd_advlog_map_entry_t *arr, uint32 arr_len, int tag)
+{
+	int i;
+	for (i = 0; i < arr_len; i++) {
+		if (tag == arr[i].key) {
+			return arr[i].val;
+		}
+	}
+	return NULL;
+}
+
+static int get_dhcp_type(uint8 *pktdata)
+{
+	bootp_fmt_t *b = (bootp_fmt_t *)&pktdata[ETHER_HDR_LEN];
+	uint8 *ptr, *opt, *end = (uint8 *) b + ntohs(b->iph.tot_len);
+	int dhcp_type = 0, len, opt_len;
+
+	len = ntohs(b->udph.len) - sizeof(struct bcmudp_hdr);
+	opt_len = len - (sizeof(*b) - sizeof(struct ipv4_hdr) -
+		sizeof(struct bcmudp_hdr) - sizeof(b->options));
+
+	/* parse bootp options */
+	if (opt_len >= BOOTP_MAGIC_COOKIE_LEN &&
+		!memcmp(b->options, bootp_magic_cookie, BOOTP_MAGIC_COOKIE_LEN)) {
+		ptr = &b->options[BOOTP_MAGIC_COOKIE_LEN];
+		while (ptr < end && *ptr != 0xff) {
+			opt = ptr++;
+			if (*opt == 0) {
+				continue;
+			}
+			ptr += *ptr + 1;
+			if (ptr >= end) {
+				break;
+			}
+			if (*opt == DHCP_OPT_MSGTYPE) {
+				if (opt[1]) {
+					dhcp_type = opt[2];
+					return dhcp_type;
+				}
+			}
+		}
+	}
+	return BCME_ERROR;
+}
+
+static int dhd_send_supp(uint32 avglog_type, int arg_tag, int arg_type, uint32 pktlen,
+	bool tx, uint16 *pktfate)
+{
+	const char *type_str = NULL;
+	const char *fmt_str = NULL;
+	dhd_advlog_map_entry_t *fmt_arr;
+	uint32 fmt_arr_len;
+
+	if (avglog_type >= DHD_ADVLOG_LAST) {
+		DHD_ERROR(("%s incorrect array index type:%d tag:%d\n",
+			__func__, avglog_type, arg_tag));
+		return BCME_ERROR;
+	}
+	if ((arg_type && !pktlen) || (!arg_type && pktlen)) {
+		DHD_ERROR(("%s Not expected value pair type:%d tag:%d pktlen:%u\n",
+			__func__, avglog_type, arg_tag, pktlen));
+		return BCME_ERROR;
+	}
+	if (arg_tag <= 0) {
+		DHD_ERROR(("%s Invalid tag number type:%d tag:%d\n",
+			__func__, avglog_type, arg_tag));
+		return BCME_ERROR;
+	}
+
+	/* Get the format string corresponding to the type */
+	fmt_arr = advlog_map_arr[avglog_type].arr;
+	fmt_arr_len = advlog_map_arr[avglog_type].arr_len;
+	fmt_str = get_advlog_val(fmt_arr, fmt_arr_len, arg_tag);
+	if (!fmt_str) {
+		DHD_ERROR(("%s map arr not found type:%d tag:%d\n",
+			__func__, avglog_type, arg_tag));
+		return BCME_ERROR;
+	}
+
+	/* EAP REQ/RESP */
+	if (arg_type && pktlen) {
+		/* Get Identity/PEAP/FAST/etc string */
+		type_str = get_advlog_val(eap_type_map, ARRAY_SIZE(eap_type_map), arg_type);
+		if (!type_str) {
+			DHD_ERROR(("%s type string not found type:%d tag:%d\n",
+				__func__, avglog_type, arg_tag));
+			return BCME_ERROR;
+		}
+		if (tx && pktfate) {
+			/* EAP RESP */
+			SUPP_ADVLOG((fmt_str, type_str, pktlen, TX_FATE_EX(pktfate)));
+		} else if (!tx) {
+			/* EAP REQ */
+			SUPP_ADVLOG((fmt_str, type_str, pktlen));
+		}
+	} else {
+		if (tx && pktfate) {
+			/* EAPOL M2/M4, GTK M2, DHCP DISC/REQ */
+			SUPP_ADVLOG((fmt_str, TX_FATE_EX(pktfate)));
+		} else if (!tx) {
+			/* EAPOL M1/M3, GTK M1, DHCP OFFER/ACK/NAK, EAP SUCC/FAIL */
+			SUPP_ADVLOG((fmt_str));
+		}
+	}
+	return BCME_OK;
+}
+
+void dhd_send_supp_dhcp(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx, uint16 *pktfate)
+{
+	uint32 advlog_type;
+
+	/* Advanced Logging supports only STA mode */
+	if (!DHD_IF_ROLE_STA(dhdp, ifidx)) {
+		return;
+	}
+
+	if (tx) {
+		advlog_type = DHD_ADVLOG_DHCP_TX;
+	} else {
+		advlog_type = DHD_ADVLOG_DHCP_RX;
+	}
+	dhd_send_supp(advlog_type, get_dhcp_type(pktdata), 0, 0, tx, pktfate);
+}
+
+void dhd_send_supp_eap(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, uint32 pktlen,
+	bool tx, uint16 *pktfate)
+{
+	eapol_header_t *eapol_hdr;
+	eap_header_fmt_t *eap_hdr;
+	uint16 len = 0;
+	uint8 type = 0;
+
+	/* Advanced Logging supports only STA mode */
+	if (!DHD_IF_ROLE_STA(dhdp, ifidx)) {
+		return;
+	}
+
+	eapol_hdr = (eapol_header_t *)pktdata;
+	eap_hdr = (eap_header_fmt_t *)(eapol_hdr->body);
+
+	if (eapol_hdr->type == EAP_PACKET) {
+		/* EAP SUCC/FAIL has no arg to print */
+		if (eap_hdr->code != EAP_CODE_SUCCESS &&
+			eap_hdr->code != EAP_CODE_FAILURE) {
+			type = eap_hdr->type;
+			len = ntoh16(eap_hdr->len);
+		}
+		dhd_send_supp(DHD_ADVLOG_EAP, eap_hdr->code, type, len, tx, pktfate);
+	} else if (eapol_hdr->type == EAPOL_KEY) {
+		dhd_send_supp(DHD_ADVLOG_EAPOL, dhd_is_4way_msg(pktdata),
+			0, 0, tx, pktfate);
+	}
+}
+#endif /* WL_CFGVENDOR_CUST_ADVLOG */
+
+#ifdef BCMPCIE
+static bool
+dhd_is_eapol_pkt(dhd_pub_t *dhd, uint8 *pktdata, uint32 pktlen)
+{
+	eapol_header_t *eapol_hdr = (eapol_header_t *)pktdata;
+
+	eapol_hdr = (eapol_header_t *)pktdata;
+
+	if (eapol_hdr->type == EAP_PACKET) {
+		return TRUE;
+	} else if (eapol_hdr->type == EAPOL_START) {
+		return TRUE;
+	} else if (eapol_hdr->type == EAPOL_KEY) {
+		return TRUE;
+	} else {
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static bool
+dhd_is_arp_pkt(dhd_pub_t *dhdp, uint8 *pktdata)
+{
+	uint8 *pkt = (uint8 *)&pktdata[ETHER_HDR_LEN];
+	struct bcmarp *arph = (struct bcmarp *)pkt;
+	uint16 opcode;
+
+	/* validation check */
+	if (arph->htype != hton16(HTYPE_ETHERNET) ||
+		arph->hlen != ETHER_ADDR_LEN ||
+		arph->plen != 4) {
+		return FALSE;
+	}
+
+	opcode = ntoh16(arph->oper);
+	if (opcode == ARP_OPC_REQUEST) {
+		return TRUE;
+	} else if (opcode == ARP_OPC_REPLY) {
+		return TRUE;
+	} else {
+		return TRUE;
+	}
+	return FALSE;
+}
+
+static bool
+dhd_is_dhcp_pkt(dhd_pub_t *dhdp, uint8 *pktdata)
+{
+	bootp_fmt_t *b = (bootp_fmt_t *)&pktdata[ETHER_HDR_LEN];
+	struct ipv4_hdr *iph = &b->iph;
+	uint8 *ptr, *opt, *end = (uint8 *) b + ntohs(b->iph.tot_len);
+	int len, opt_len;
+
+	/* check IP header */
+	if ((IPV4_HLEN(iph) < IPV4_HLEN_MIN) ||
+		IP_VER(iph) != IP_VER_4 ||
+		IPV4_PROT(iph) != IP_PROT_UDP) {
+		return FALSE;
+	}
+
+	/* check UDP port for bootp (67, 68) */
+	if (b->udph.src_port != htons(DHCP_PORT_SERVER) &&
+		b->udph.src_port != htons(DHCP_PORT_CLIENT) &&
+		b->udph.dst_port != htons(DHCP_PORT_SERVER) &&
+		b->udph.dst_port != htons(DHCP_PORT_CLIENT)) {
+		return FALSE;
+	}
+
+	/* check header length */
+	if (ntohs(iph->tot_len) < ntohs(b->udph.len) + sizeof(struct bcmudp_hdr)) {
+		return FALSE;
+	}
+
+	len = ntohs(b->udph.len) - sizeof(struct bcmudp_hdr);
+	opt_len = len - (sizeof(*b) - sizeof(struct ipv4_hdr) -
+		sizeof(struct bcmudp_hdr) - sizeof(b->options));
+
+	/* parse bootp options */
+	if (opt_len >= BOOTP_MAGIC_COOKIE_LEN &&
+		!memcmp(b->options, bootp_magic_cookie, BOOTP_MAGIC_COOKIE_LEN)) {
+		ptr = &b->options[BOOTP_MAGIC_COOKIE_LEN];
+		while (ptr < end && *ptr != 0xff) {
+			opt = ptr++;
+			if (*opt == 0) {
+				continue;
+			}
+			ptr += *ptr + 1;
+			if (ptr >= end) {
+				break;
+			}
+			if (*opt == DHCP_OPT_MSGTYPE) {
+				if (opt[1]) {
+					return TRUE;
+				}
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+static bool
+dhd_is_icmp_pkt(dhd_pub_t *dhd, uint8 *pktdata, uint32 pktlen)
+{
+	uint8 *pkt;
+	struct ipv4_hdr *iph;
+
+	pkt = (uint8 *)&pktdata[ETHER_HDR_LEN];
+	iph = (struct ipv4_hdr *)pkt;
+
+	/* check IP header */
+	if ((IPV4_HLEN(iph) < IPV4_HLEN_MIN) ||
+		IP_VER(iph) != IP_VER_4 ||
+		IPV4_PROT(iph) != IP_PROT_ICMP) {
+		return FALSE;
+	}
+
+	/* check header length */
+	if (ntohs(iph->tot_len) - IPV4_HLEN(iph) < sizeof(struct bcmicmp_hdr)) {
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+bool
+dhd_match_pkt_type(dhd_pub_t *dhd, uint8 *pktdata, uint32 pktlen)
+{
+	struct ether_header *eh;
+	uint16 ether_type;
+	bool match = FALSE;
+
+	if (!pktdata || pktlen < ETHER_HDR_LEN) {
+		return match;
+	}
+
+	eh = (struct ether_header *)pktdata;
+	ether_type = ntoh16(eh->ether_type);
+	if ((dhd->conf->enq_hdr_pkt & ENQ_PKT_TYPE_EAPOL) &&
+			ether_type == ETHER_TYPE_802_1X) {
+		match = dhd_is_eapol_pkt(dhd, pktdata, pktlen);
+	}
+	else if ((dhd->conf->enq_hdr_pkt & ENQ_PKT_TYPE_ARP) &&
+			ntoh16(eh->ether_type) == ETHER_TYPE_ARP) {
+		match = dhd_is_arp_pkt(dhd, pktdata);
+	}
+	else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) {
+		if (dhd->conf->enq_hdr_pkt & ENQ_PKT_TYPE_ICMP)
+			match = dhd_is_icmp_pkt(dhd, pktdata, pktlen);
+		if (!match && dhd->conf->enq_hdr_pkt & ENQ_PKT_TYPE_DHCP)
+			match = dhd_is_dhcp_pkt(dhd, pktdata);
+	}
+
+	return match;
+}
+#endif /* BCMPCIE */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux_pktdump.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux_pktdump.h
@@ -0,0 +1,186 @@
+/*
+ * Header file for the Packet dump helper functions
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef __DHD_LINUX_PKTDUMP_H_
+#define __DHD_LINUX_PKTDUMP_H_
+
+#include <typedefs.h>
+#include <dhd.h>
+
+typedef enum {
+	EAPOL_OTHER = 0,
+	EAPOL_4WAY_M1,
+	EAPOL_4WAY_M2,
+	EAPOL_4WAY_M3,
+	EAPOL_4WAY_M4,
+	EAPOL_GROUPKEY_M1,
+	EAPOL_GROUPKEY_M2
+} msg_eapol_t;
+
+typedef enum pkt_cnt_rsn {
+	PKT_CNT_RSN_INVALID	= 0,
+	PKT_CNT_RSN_ROAM	= 1,
+	PKT_CNT_RSN_GRPKEY_UP	= 2,
+	PKT_CNT_RSN_CONNECT	= 3,
+	PKT_CNT_RSN_MAX		= 4
+} pkt_cnt_rsn_t;
+
+enum pkt_type {
+	PKT_TYPE_DATA = 0,
+	PKT_TYPE_DHCP = 1,
+	PKT_TYPE_ICMP = 2,
+	PKT_TYPE_ICMPV6 = 3,
+	PKT_TYPE_DNS = 4,
+	PKT_TYPE_ARP = 5,
+	PKT_TYPE_EAP = 6,
+	PKT_TYPE_DHCP6 = 7,
+	PKT_TYPE_DNS6 = 8
+};
+
+#ifdef WL_CFGVENDOR_CUST_ADVLOG
+#define DHD_ADVLOG_FMT_MAX      256u
+typedef struct dhd_advlog_map_entry {
+	uint32 key;
+	const char val[DHD_ADVLOG_FMT_MAX];
+} dhd_advlog_map_entry_t;
+
+extern void dhd_send_supp_dhcp(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata,
+	bool tx, uint16 *pktfate);
+extern void dhd_send_supp_eap(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, uint32 pktlen,
+	bool tx, uint16 *pktfate);
+#else
+static INLINE void dhd_send_supp_dhcp(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata,
+	bool tx, uint16 *pktfate) {}
+static INLINE void dhd_send_supp_eap(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata,
+	uint32 pktlen, bool tx, uint16 *pktfate) {}
+#endif /* WL_CFGVENDOR_CUST_ADVLOG */
+
+extern msg_eapol_t dhd_is_4way_msg(uint8 *pktdata);
+extern void dhd_dump_pkt(dhd_pub_t *dhd, int ifidx, uint8 *pktdata,
+	uint32 pktlen, bool tx, uint32 *pkthash, uint16 *pktfate);
+#ifdef BCMPCIE
+extern bool dhd_match_pkt_type(dhd_pub_t *dhd, uint8 *pktdata, uint32 pktlen);
+#endif /* BCMPCIE */
+#ifdef DHD_PKTDUMP_ROAM
+extern void dhd_dump_mod_pkt_timer(dhd_pub_t *dhdp, uint16 rsn);
+extern void dhd_dump_pkt_init(dhd_pub_t *dhdp);
+extern void dhd_dump_pkt_deinit(dhd_pub_t *dhdp);
+extern void dhd_dump_pkt_clear(dhd_pub_t *dhdp);
+#else
+static INLINE void dhd_dump_mod_pkt_timer(dhd_pub_t *dhdp, uint16 rsn) { }
+static INLINE void dhd_dump_pkt_init(dhd_pub_t *dhdp) { }
+static INLINE void dhd_dump_pkt_deinit(dhd_pub_t *dhdp) { }
+static INLINE void dhd_dump_pkt_clear(dhd_pub_t *dhdp) { }
+#endif /* DHD_PKTDUMP_ROAM */
+
+/* Rx packet dump */
+#ifdef DHD_TRX_DUMP
+extern void dhd_trx_pkt_dump(dhd_pub_t *dhdp, int ifidx,
+	uint8 *pktdata, uint32 pktlen, bool tx);
+#else
+static INLINE void dhd_trx_pkt_dump(dhd_pub_t *dhdp, int ifidx,
+	uint8 *pktdata, uint32 pktlen, bool tx) { }
+#endif /* DHD_TRX_DUMP */
+
+/* DHCP packet dump */
+#ifdef DHD_DHCP_DUMP
+extern void dhd_dhcp_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
+	uint32 *pkthash, uint16 *pktfate);
+#else
+static INLINE void dhd_dhcp_dump(dhd_pub_t *dhdp, int ifidx,
+	uint8 *pktdata, bool tx, uint32 *pkthash, uint16 *pktfate) { }
+#endif /* DHD_DHCP_DUMP */
+
+/* DNS packet dump */
+#ifdef DHD_DNS_DUMP
+extern void dhd_dns_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
+	uint32 *pkthash, uint16 *pktfate);
+#else
+static INLINE void dhd_dns_dump(dhd_pub_t *dhdp, int ifidx,
+	uint8 *pktdata, bool tx, uint32 *pkthash, uint16 *pktfate) { }
+#endif /* DHD_DNS_DUMP */
+
+/* ICMP packet dump */
+#ifdef DHD_ICMP_DUMP
+extern void dhd_icmp_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
+	uint32 *pkthash, uint16 *pktfate);
+#else
+static INLINE void dhd_icmp_dump(dhd_pub_t *dhdp, int ifidx,
+	uint8 *pktdata, bool tx, uint32 *pkthash, uint16 *pktfate) { }
+#endif /* DHD_ICMP_DUMP */
+
+/* ARP packet dump */
+#ifdef DHD_ARP_DUMP
+extern void dhd_arp_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
+	uint32 *pkthash, uint16 *pktfate);
+#else
+static INLINE void dhd_arp_dump(dhd_pub_t *dhdp, int ifidx,
+	uint8 *pktdata, bool tx, uint32 *pkthash, uint16 *pktfate) { }
+#endif /* DHD_ARP_DUMP */
+
+/* 802.1X packet dump */
+#ifdef DHD_8021X_DUMP
+extern void dhd_dump_eapol_message(dhd_pub_t *dhd, int ifidx,
+        uint8 *pktdata, uint32 pktlen, bool tx, uint32 *pkthash, uint16 *pktfate);
+#else
+static INLINE void dhd_dump_eapol_message(dhd_pub_t *dhd, int ifidx,
+        uint8 *pktdata, uint32 pktlen, bool tx, uint32 *pkthash, uint16 *pktfate) { }
+#endif /* DHD_8021X_DUMP */
+#ifdef DHD_IPV6_DUMP
+extern void dhd_dhcp6_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
+	uint32 *pkthash, uint16 *pktfate);
+extern void dhd_icmpv6_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
+	uint32 *pkthash, uint16 *pktfate);
+extern void dhd_dns6_dump(dhd_pub_t *dhdp, int ifidx, uint8 *pktdata, bool tx,
+    uint32 *pkthash, uint16 *pktfate);
+extern bool dhd_check_dhcp6(uint8 *pktdata, uint32 plen);
+extern bool dhd_check_dns6(uint8 *pktdata, uint32 plen);
+#endif
+extern bool dhd_check_ip_prot(uint8 *pktdata, uint16 ether_type);
+extern bool dhd_check_arp(uint8 *pktdata, uint16 ether_type);
+extern bool dhd_check_dhcp(uint8 *pktdata);
+extern bool dhd_check_icmp(uint8 *pktdata);
+extern bool dhd_check_icmpv6(uint8 *pktdata, uint32 plen);
+extern bool dhd_check_dns(uint8 *pktdata);
+#endif /* __DHD_LINUX_PKTDUMP_H_ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux_platdev.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux_platdev.c
@@ -0,0 +1,1266 @@
+/*
+ * Linux platform device for DHD WLAN adapter
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+#include <typedefs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <bcmutils.h>
+#include <linux_osl.h>
+#include <dhd_dbg.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_bus.h>
+#include <dhd_linux.h>
+#if defined(OEM_ANDROID)
+#include <wl_android.h>
+#endif
+#include <dhd_plat.h>
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+#include <linux/wlan_plat.h>
+#endif /* CONFIG_WIFI_CONTROL_FUNC */
+#ifdef CONFIG_DTS
+#include<linux/regulator/consumer.h>
+#include<linux/of_gpio.h>
+#endif /* CONFIG_DTS */
+
+#if defined(CUSTOMER_HW) || defined(BCMDHD_PLATDEV)
+extern int dhd_wlan_init_plat_data(wifi_adapter_info_t *adapter);
+extern void dhd_wlan_deinit_plat_data(wifi_adapter_info_t *adapter);
+#endif /* CUSTOMER_HW */
+
+#define WIFI_PLAT_NAME		"bcmdhd_wlan"
+#define WIFI_PLAT_NAME2		"bcm4329_wlan"
+#define WIFI_PLAT_EXT		"bcmdhd_wifi_platform"
+
+#if defined(SUPPORT_MULTIPLE_BOARD_REVISION)
+#include <linux/of.h>
+extern char* dhd_get_device_dt_name(void);
+#endif /* SUPPORT_MULTIPLE_BOARD_REVISION */
+
+#ifdef DHD_WIFI_SHUTDOWN
+extern void wifi_plat_dev_drv_shutdown(struct platform_device *pdev);
+#endif
+
+#ifdef CONFIG_DTS
+struct regulator *wifi_regulator = NULL;
+#endif /* CONFIG_DTS */
+
+bool cfg_multichip = FALSE;
+bcmdhd_wifi_platdata_t *dhd_wifi_platdata = NULL;
+static int wifi_plat_dev_probe_ret = 0;
+bool is_power_on = FALSE;
+/* XXX Some Qualcomm based CUSTOMER_HW4 platforms are using platform
+ * device structure even if the Kernel uses device tree structure.
+ * Therefore, the CONFIG_ARCH_MSM condition is temporarly remained
+ * to support in this case.
+ */
+#if !defined(CONFIG_DTS)
+#if defined(DHD_OF_SUPPORT)
+static bool dts_enabled = TRUE;
+extern struct resource dhd_wlan_resources;
+extern struct wifi_platform_data dhd_wlan_control;
+#else
+static bool dts_enabled = FALSE;
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#endif
+struct resource dhd_wlan_resources = {0};
+extern struct wifi_platform_data dhd_wlan_control;
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+#endif /* CONFIG_OF && !defined(CONFIG_ARCH_MSM) */
+#endif /* !defind(CONFIG_DTS) */
+
+static int dhd_wifi_platform_load(void);
+
+extern void* wl_cfg80211_get_dhdp(struct net_device *dev);
+
+// modify for compatibility
+#if defined(BCMDHD_MODULAR) && defined(BOARD_MODULAR_INIT)
+//extern int dhd_wlan_init(void);
+//extern int dhd_wlan_deinit(void);
+#ifdef WBRC
+extern int wbrc_init(void);
+extern void wbrc_exit(void);
+#endif /* WBRC */
+#endif /* defined(BCMDHD_MODULAR) && defined(BOARD_MODULAR_INIT) */
+
+#ifdef ENABLE_4335BT_WAR
+extern int bcm_bt_lock(int cookie);
+extern void bcm_bt_unlock(int cookie);
+static int lock_cookie_wifi = 'W' | 'i'<<8 | 'F'<<16 | 'i'<<24;	/* cookie is "WiFi" */
+#endif /* ENABLE_4335BT_WAR */
+
+#ifdef BCM4335_XTAL_WAR
+extern bool check_bcm4335_rev(void);
+#endif /* BCM4335_XTAL_WAR */
+
+#if defined(CONFIG_X86)
+#define PCIE_RC_VENDOR_ID 0x8086
+#define PCIE_RC_DEVICE_ID 0x9c1a
+#elif defined(CONFIG_ARCH_TEGRA)
+#define PCIE_RC_VENDOR_ID 0x14e4
+#define PCIE_RC_DEVICE_ID 0x4347
+#else /* CONFIG_ARCH_TEGRA */
+/* Dummy defn */
+#define PCIE_RC_VENDOR_ID 0xffff
+#define PCIE_RC_DEVICE_ID 0xffff
+#endif /* CONFIG_X86 */
+
+wifi_adapter_info_t* dhd_wifi_platform_attach_adapter(uint32 bus_type,
+	uint32 bus_num, uint32 slot_num, unsigned long status)
+{
+	int i;
+
+	if (dhd_wifi_platdata == NULL)
+		return NULL;
+
+	for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
+		wifi_adapter_info_t *adapter = &dhd_wifi_platdata->adapters[i];
+		if ((adapter->bus_type == -1 || adapter->bus_type == bus_type) &&
+			(adapter->bus_num == -1 || adapter->bus_num == bus_num) &&
+			(adapter->slot_num == -1 || adapter->slot_num == slot_num)
+#if defined(ENABLE_INSMOD_NO_FW_LOAD) && !defined(ENABLE_INSMOD_NO_POWER_OFF)
+			&& (wifi_chk_adapter_status(adapter, status))
+#endif
+		) {
+			DHD_ERROR(("attach adapter info '%s'\n", adapter->name));
+			return adapter;
+		}
+	}
+	return NULL;
+}
+
+wifi_adapter_info_t* dhd_wifi_platform_get_adapter(uint32 bus_type, uint32 bus_num, uint32 slot_num)
+{
+	int i;
+
+	if (dhd_wifi_platdata == NULL)
+		return NULL;
+
+	for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
+		wifi_adapter_info_t *adapter = &dhd_wifi_platdata->adapters[i];
+		if ((adapter->bus_type == -1 || adapter->bus_type == bus_type) &&
+			(adapter->bus_num == -1 || adapter->bus_num == bus_num) &&
+			(adapter->slot_num == -1 || adapter->slot_num == slot_num)) {
+			DHD_TRACE(("found adapter info '%s'\n", adapter->name));
+			return adapter;
+		}
+	}
+	return NULL;
+}
+
+#if defined(CONFIG_WIFI_CONTROL_FUNC) && defined(CONFIG_DHD_USE_STATIC_BUF)
+extern void *dhd_wlan_mem_prealloc(int section, unsigned long size);
+#endif /* CONFIG_WIFI_CONTROL_FUNC && CONFIG_DHD_USE_STATIC_BUF */
+
+void* wifi_platform_prealloc(wifi_adapter_info_t *adapter, int section, unsigned long size)
+{
+	void *alloc_ptr = NULL;
+	struct wifi_platform_data *plat_data;
+
+	if (!adapter || !adapter->wifi_plat_data)
+		return NULL;
+	plat_data = adapter->wifi_plat_data;
+	if (plat_data->mem_prealloc) {
+#if defined(BCMDHD_MDRIVER) && !defined(DHD_STATIC_IN_DRIVER)
+		alloc_ptr = plat_data->mem_prealloc(adapter->bus_type, adapter->index, section, size);
+#else
+#if defined(CONFIG_WIFI_CONTROL_FUNC) && defined(CONFIG_DHD_USE_STATIC_BUF)
+		alloc_ptr = dhd_wlan_mem_prealloc(section, size);
+#else
+		alloc_ptr = plat_data->mem_prealloc(section, size);
+#endif
+#endif
+		if (alloc_ptr) {
+			DHD_INFO(("success alloc section %d\n", section));
+			if (size != 0L)
+				bzero(alloc_ptr, size);
+			return alloc_ptr;
+		}
+	} else
+		return NULL;
+
+	DHD_ERROR(("%s: failed to alloc static mem section %d\n", __FUNCTION__, section));
+	return NULL;
+}
+
+void* wifi_platform_get_prealloc_func_ptr(wifi_adapter_info_t *adapter)
+{
+	struct wifi_platform_data *plat_data;
+
+	if (!adapter || !adapter->wifi_plat_data)
+		return NULL;
+	plat_data = adapter->wifi_plat_data;
+	return plat_data->mem_prealloc;
+}
+
+int wifi_platform_get_irq_number(wifi_adapter_info_t *adapter, unsigned long *irq_flags_ptr)
+{
+	if (adapter == NULL)
+		return -1;
+	if (irq_flags_ptr)
+		*irq_flags_ptr = adapter->intr_flags;
+	return adapter->irq_num;
+}
+
+int wifi_platform_get_irq_level(wifi_adapter_info_t *adapter)
+{
+	struct wifi_platform_data  *plat_data = NULL;
+
+	if (adapter == NULL) {
+		return BCME_BADARG;
+	} else if ((plat_data = adapter->wifi_plat_data) == NULL) {
+		return BCME_BADARG;
+	}
+#ifdef DHD_USE_HOST_WAKE
+	else if (plat_data->get_oob_gpio_level == NULL) {
+		/* use legacy way */
+		extern int dhd_get_wlan_oob_gpio(void);
+		return dhd_get_wlan_oob_gpio();
+	} else {
+		return plat_data->get_oob_gpio_level();
+	}
+#else // DHD_USE_HOST_WAKE
+	else {
+		return BCME_UNSUPPORTED;
+	}
+#endif /* DHD_USE_HOST_WAKE */
+}
+
+int wifi_platform_set_power(wifi_adapter_info_t *adapter, bool on, unsigned long msec)
+{
+	int err = 0;
+	struct wifi_platform_data *plat_data;
+
+	if (on) {
+		wifi_set_adapter_status(adapter, WIFI_STATUS_POWER_ON);
+	} else {
+		wifi_clr_adapter_status(adapter, WIFI_STATUS_POWER_ON);
+	}
+	if (!adapter->wifi_plat_data) {
+		err = -EINVAL;
+		goto fail;
+	}
+	plat_data = adapter->wifi_plat_data;
+
+	DHD_ERROR(("%s = %d, delay: %lu msec\n", __FUNCTION__, on, msec));
+	if (plat_data->set_power) {
+#ifdef ENABLE_4335BT_WAR
+		if (on) {
+			printk("WiFi: trying to acquire BT lock\n");
+			if (bcm_bt_lock(lock_cookie_wifi) != 0)
+				printk("** WiFi: timeout in acquiring bt lock**\n");
+			printk("%s: btlock acquired\n", __FUNCTION__);
+		}
+		else {
+			/* For a exceptional case, release btlock */
+			bcm_bt_unlock(lock_cookie_wifi);
+		}
+#endif /* ENABLE_4335BT_WAR */
+
+#ifdef CONFIG_WIFI_CONTROL_FUNC
+		err = plat_data->set_power(on);
+#else
+		err = plat_data->set_power(adapter, on);
+#endif
+	}
+
+	if (msec && !err) {
+		OSL_SLEEP(msec);
+		DHD_ERROR(("%s = %d, sleep done: %lu msec\n", __FUNCTION__, on, msec));
+	}
+
+	if (on && !err)
+		is_power_on = TRUE;
+	else
+		is_power_on = FALSE;
+
+	return err;
+fail:
+	if (on) {
+		wifi_clr_adapter_status(adapter, WIFI_STATUS_POWER_ON);
+	} else {
+		wifi_set_adapter_status(adapter, WIFI_STATUS_POWER_ON);
+	}
+	return err;
+}
+
+int wifi_platform_bus_enumerate(wifi_adapter_info_t *adapter, bool device_present)
+{
+	int err = 0;
+	struct wifi_platform_data *plat_data;
+
+	if (!adapter || !adapter->wifi_plat_data)
+		return -EINVAL;
+	plat_data = adapter->wifi_plat_data;
+
+	DHD_ERROR(("%s device present %d\n", __FUNCTION__, device_present));
+	if (plat_data->set_carddetect) {
+		err = plat_data->set_carddetect(adapter, device_present);
+	}
+	return err;
+
+}
+
+int wifi_platform_get_mac_addr(wifi_adapter_info_t *adapter, unsigned char *buf,
+	int ifidx)
+{
+	struct wifi_platform_data *plat_data;
+
+	DHD_ERROR(("%s\n", __FUNCTION__));
+	if (!buf || !adapter || !adapter->wifi_plat_data)
+		return -EINVAL;
+	plat_data = adapter->wifi_plat_data;
+	if (plat_data->get_mac_addr) {
+#ifdef CONFIG_WIFI_CONTROL_FUNC
+		return plat_data->get_mac_addr(buf);
+#else
+		return plat_data->get_mac_addr(adapter, buf, ifidx);
+#endif
+	}
+	return -EOPNOTSUPP;
+}
+
+#ifdef DHD_COREDUMP
+int wifi_platform_set_coredump(wifi_adapter_info_t *adapter, const char *buf,
+	int buf_len, const char *info)
+{
+	struct wifi_platform_data *plat_data;
+
+	DHD_ERROR(("%s\n", __FUNCTION__));
+	if (!buf || !adapter || !adapter->wifi_plat_data)
+		return -EINVAL;
+	plat_data = adapter->wifi_plat_data;
+	if (plat_data->set_coredump) {
+		return plat_data->set_coredump(buf, buf_len, info);
+	}
+	return -EOPNOTSUPP;
+}
+#endif /* DHD_COREDUMP */
+
+void *
+#ifdef CUSTOM_COUNTRY_CODE
+wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode, u32 flags)
+#else
+wifi_platform_get_country_code(wifi_adapter_info_t *adapter, char *ccode)
+#endif /* CUSTOM_COUNTRY_CODE */
+{
+	/* get_country_code was added after 2.6.39 */
+#if	(LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
+	struct wifi_platform_data *plat_data;
+
+	if (!ccode || !adapter || !adapter->wifi_plat_data)
+		return NULL;
+	plat_data = adapter->wifi_plat_data;
+
+	DHD_TRACE(("%s\n", __FUNCTION__));
+	if (plat_data->get_country_code) {
+#ifdef CUSTOM_FORCE_NODFS_FLAG
+		return plat_data->get_country_code(ccode, flags);
+#else
+		return plat_data->get_country_code(ccode);
+#endif /* CUSTOM_COUNTRY_CODE */
+	}
+#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) */
+
+	return NULL;
+}
+
+#ifndef CUSTOMER_HW
+static int wifi_plat_dev_drv_probe(struct platform_device *pdev)
+{
+	struct resource *resource;
+	wifi_adapter_info_t *adapter;
+
+	/* Android style wifi platform data device ("bcmdhd_wlan" or "bcm4329_wlan")
+	 * is kept for backward compatibility and supports only 1 adapter
+	 */
+	ASSERT(dhd_wifi_platdata != NULL);
+	ASSERT(dhd_wifi_platdata->num_adapters == 1);
+	adapter = &dhd_wifi_platdata->adapters[0];
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+	adapter->wifi_plat_data = (struct wifi_platform_data *)(pdev->dev.platform_data);
+#else
+	adapter->wifi_plat_data = (void *)&dhd_wlan_control;
+#endif
+
+#ifdef BCMDHD_PLATDEV
+	adapter->pdev = pdev;
+	wifi_plat_dev_probe_ret = dhd_wlan_init_plat_data(adapter);
+	if (!wifi_plat_dev_probe_ret)
+		wifi_plat_dev_probe_ret = dhd_wifi_platform_load();
+	return wifi_plat_dev_probe_ret;
+#endif
+
+	resource = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq");
+	if (resource == NULL)
+		resource = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcm4329_wlan_irq");
+	if (resource) {
+		adapter->irq_num = resource->start;
+		adapter->intr_flags = resource->flags & IRQF_TRIGGER_MASK;
+#ifdef DHD_ISR_NO_SUSPEND
+		adapter->intr_flags |= IRQF_NO_SUSPEND;
+#endif
+	}
+
+	wifi_plat_dev_probe_ret = dhd_wifi_platform_load();
+	return wifi_plat_dev_probe_ret;
+}
+
+static int wifi_plat_dev_drv_remove(struct platform_device *pdev)
+{
+	wifi_adapter_info_t *adapter;
+
+	/* Android style wifi platform data device ("bcmdhd_wlan" or "bcm4329_wlan")
+	 * is kept for backward compatibility and supports only 1 adapter
+	 */
+	ASSERT(dhd_wifi_platdata != NULL);
+	ASSERT(dhd_wifi_platdata->num_adapters == 1);
+	adapter = &dhd_wifi_platdata->adapters[0];
+	if (is_power_on) {
+#ifdef BCMPCIE
+		wifi_platform_bus_enumerate(adapter, FALSE);
+		wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
+#else
+		wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
+		wifi_platform_bus_enumerate(adapter, FALSE);
+#endif /* BCMPCIE */
+	}
+
+#ifdef BCMDHD_PLATDEV
+	dhd_wlan_deinit_plat_data(adapter);
+#endif
+	return 0;
+}
+
+static int wifi_plat_dev_drv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	DHD_TRACE(("##> %s\n", __FUNCTION__));
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) && \
+	defined(BCMSDIO)
+	bcmsdh_oob_intr_set(0);
+#endif /* (OOB_INTR_ONLY) */
+	return 0;
+}
+
+static int wifi_plat_dev_drv_resume(struct platform_device *pdev)
+{
+	DHD_TRACE(("##> %s\n", __FUNCTION__));
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 39)) && defined(OOB_INTR_ONLY) && \
+	defined(BCMSDIO)
+	if (dhd_os_check_if_up(wl_cfg80211_get_dhdp()))
+		bcmsdh_oob_intr_set(1);
+#endif /* (OOB_INTR_ONLY) */
+	return 0;
+}
+
+static const struct of_device_id wifi_device_dt_match[] = {
+	{ .compatible = "android,bcmdhd_wlan", .name = "", },
+	{ .name = "" },
+};
+static struct platform_driver wifi_platform_dev_driver = {
+	.probe          = wifi_plat_dev_drv_probe,
+	.remove         = wifi_plat_dev_drv_remove,
+	.suspend        = wifi_plat_dev_drv_suspend,
+	.resume         = wifi_plat_dev_drv_resume,
+#ifdef DHD_WIFI_SHUTDOWN
+	.shutdown       = wifi_plat_dev_drv_shutdown,
+#endif /* DHD_WIFI_SHUTDOWN */
+	.driver         = {
+	.name   = WIFI_PLAT_NAME,
+	.of_match_table = wifi_device_dt_match,
+	}
+};
+
+static struct platform_driver wifi_platform_dev_driver_legacy = {
+	.probe          = wifi_plat_dev_drv_probe,
+	.remove         = wifi_plat_dev_drv_remove,
+	.suspend        = wifi_plat_dev_drv_suspend,
+	.resume         = wifi_plat_dev_drv_resume,
+#ifdef DHD_WIFI_SHUTDOWN
+	.shutdown       = wifi_plat_dev_drv_shutdown,
+#endif /* DHD_WIFI_SHUTDOWN */
+	.driver         = {
+	.name	= WIFI_PLAT_NAME2,
+	}
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
+static int wifi_platdev_match(struct device *dev, const void *data)
+#else
+static int wifi_platdev_match(struct device *dev, void *data)
+#endif /* LINUX_VER >= 5.3.0 */
+{
+	char *name = NULL;
+	const struct platform_device *pdev;
+	GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+	name = (char*)data;
+	pdev = to_platform_device(dev);
+	GCC_DIAGNOSTIC_POP();
+
+	if (strcmp(pdev->name, name) == 0) {
+		DHD_ERROR(("found wifi platform device %s\n", name));
+		return TRUE;
+	}
+
+	return FALSE;
+}
+#endif
+
+static int wifi_ctrlfunc_register_drv(void)
+{
+	wifi_adapter_info_t *adapter;
+
+#ifndef CUSTOMER_HW
+	int err = 0;
+	struct device *dev1, *dev2;
+	dev1 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME, wifi_platdev_match);
+	dev2 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME2, wifi_platdev_match);
+#endif
+
+// modify for compaibility
+#if defined(BCMDHD_MODULAR) && defined(BOARD_MODULAR_INIT)
+//	if ((err = dhd_wlan_init())) {
+//		DHD_ERROR(("%s: dhd_wlan_init() failed(%d)\n", __FUNCTION__, err));
+//		return err;
+//	}
+#ifdef WBRC
+	wbrc_init();
+#endif /* WBRC */
+#endif /* defined(BCMDHD_MODULAR) && defined(BOARD_MODULAR_INIT) */
+
+#if !defined(CONFIG_DTS) && !defined(CUSTOMER_HW)
+	if (!dts_enabled) {
+		if (dev1 == NULL && dev2 == NULL) {
+			DHD_ERROR(("no wifi platform data, skip\n"));
+			return -ENXIO;
+		}
+	}
+#endif /* !defined(CONFIG_DTS) */
+
+	/* multi-chip support not enabled, build one adapter information for
+	 * DHD (either SDIO, USB or PCIe)
+	 */
+	adapter = kzalloc(sizeof(wifi_adapter_info_t), GFP_KERNEL);
+	if (adapter == NULL) {
+		DHD_ERROR(("%s:adapter alloc failed", __FUNCTION__));
+		return -ENOMEM;
+	}
+	adapter->name = "DHD generic adapter";
+	adapter->index = 0;
+	adapter->bus_type = -1;
+	adapter->bus_num = -1;
+	adapter->slot_num = -1;
+	adapter->irq_num = -1;
+	is_power_on = FALSE;
+	wifi_plat_dev_probe_ret = 0;
+	dhd_wifi_platdata = kzalloc(sizeof(bcmdhd_wifi_platdata_t), GFP_KERNEL);
+	if (dhd_wifi_platdata == NULL) {
+		DHD_ERROR(("%s:dhd_wifi_platdata alloc failed", __FUNCTION__));
+		kfree(adapter);
+		return -ENOMEM;
+	}
+	dhd_wifi_platdata->num_adapters = 1;
+	dhd_wifi_platdata->adapters = adapter;
+	init_waitqueue_head(&adapter->status_event);
+
+#ifndef CUSTOMER_HW
+	if (dev1) {
+		err = platform_driver_register(&wifi_platform_dev_driver);
+		if (err) {
+			DHD_ERROR(("%s: failed to register wifi ctrl func driver\n",
+				__FUNCTION__));
+			return err;
+		}
+	}
+	if (dev2) {
+		err = platform_driver_register(&wifi_platform_dev_driver_legacy);
+		if (err) {
+			DHD_ERROR(("%s: failed to register wifi ctrl func legacy driver\n",
+				__FUNCTION__));
+			return err;
+		}
+	}
+#endif
+
+#if !defined(CONFIG_DTS)
+	if (dts_enabled) {
+		adapter->wifi_plat_data = (void *)&dhd_wlan_control;
+#ifdef CUSTOMER_HW
+		wifi_plat_dev_probe_ret = dhd_wlan_init_plat_data(adapter);
+		if (wifi_plat_dev_probe_ret)
+			return wifi_plat_dev_probe_ret;
+#endif
+#ifdef DHD_ISR_NO_SUSPEND
+		adapter->intr_flags |= IRQF_NO_SUSPEND;
+#endif
+		wifi_plat_dev_probe_ret = dhd_wifi_platform_load();
+	}
+#endif /* !defined(CONFIG_DTS) */
+
+#if defined(CONFIG_DTS) && !defined(CUSTOMER_HW)
+	wifi_plat_dev_probe_ret = platform_driver_register(&wifi_platform_dev_driver);
+#endif /* CONFIG_DTS */
+
+	/* return probe function's return value if registeration succeeded */
+	return wifi_plat_dev_probe_ret;
+}
+
+void wifi_ctrlfunc_unregister_drv(void)
+{
+	wifi_adapter_info_t *adapter = NULL;
+
+#ifndef CUSTOMER_HW
+	struct device *dev1, *dev2;
+	dev1 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME, wifi_platdev_match);
+	dev2 = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_NAME2, wifi_platdev_match);
+	if (!dts_enabled)
+		if (dev1 == NULL && dev2 == NULL)
+			return;
+#endif
+
+	DHD_ERROR(("unregister wifi platform drivers\n"));
+
+	if (!dhd_wifi_platdata) {
+		goto done;
+	}
+
+	if (dts_enabled) {
+		adapter = &dhd_wifi_platdata->adapters[0];
+		if (is_power_on) {
+			wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
+		}
+		wifi_platform_bus_enumerate(adapter, FALSE);
+	} else {
+#ifndef CUSTOMER_HW
+		if (dev1)
+			platform_driver_unregister(&wifi_platform_dev_driver);
+		if (dev2)
+			platform_driver_unregister(&wifi_platform_dev_driver_legacy);
+#endif
+	}
+
+// modify for compaibility
+#if defined(BCMDHD_MODULAR) && defined(BOARD_MODULAR_INIT)
+//	dhd_wlan_deinit();
+	osl_static_mem_deinit(NULL, NULL);
+#ifdef WBRC
+	wbrc_exit();
+#endif /* WBRC */
+#endif /* defined(BCMDHD_MODULAR) && defined(BOARD_MODULAR_INIT) */
+
+#if defined(CUSTOMER_HW)
+	if (adapter)
+		dhd_wlan_deinit_plat_data(adapter);
+#endif
+
+done:
+	if (dhd_wifi_platdata && dhd_wifi_platdata->adapters) {
+		kfree(dhd_wifi_platdata->adapters);
+		dhd_wifi_platdata->adapters = NULL;
+		dhd_wifi_platdata->num_adapters = 0;
+	}
+	if (dhd_wifi_platdata) {
+		kfree(dhd_wifi_platdata);
+		dhd_wifi_platdata = NULL;
+	}
+}
+
+#ifndef CUSTOMER_HW
+static int bcmdhd_wifi_plat_dev_drv_probe(struct platform_device *pdev)
+{
+	dhd_wifi_platdata = (bcmdhd_wifi_platdata_t *)(pdev->dev.platform_data);
+
+	return dhd_wifi_platform_load();
+}
+
+static int bcmdhd_wifi_plat_dev_drv_remove(struct platform_device *pdev)
+{
+	int i;
+	wifi_adapter_info_t *adapter;
+	ASSERT(dhd_wifi_platdata != NULL);
+
+	/* power down all adapters */
+	for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
+		adapter = &dhd_wifi_platdata->adapters[i];
+		wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
+		wifi_platform_bus_enumerate(adapter, FALSE);
+	}
+	return 0;
+}
+
+static struct platform_driver dhd_wifi_platform_dev_driver = {
+	.probe          = bcmdhd_wifi_plat_dev_drv_probe,
+	.remove         = bcmdhd_wifi_plat_dev_drv_remove,
+	.driver         = {
+	.name   = WIFI_PLAT_EXT,
+	}
+};
+#endif
+
+int dhd_wifi_platform_register_drv(void)
+{
+	int err = 0;
+#ifndef CUSTOMER_HW
+	struct device *dev;
+
+	/* register Broadcom wifi platform data driver if multi-chip is enabled,
+	 * otherwise use Android style wifi platform data (aka wifi control function)
+	 * if it exists
+	 *
+	 * to support multi-chip DHD, Broadcom wifi platform data device must
+	 * be added in kernel early boot (e.g. board config file).
+	 */
+	if (cfg_multichip) {
+		dev = bus_find_device(&platform_bus_type, NULL, WIFI_PLAT_EXT, wifi_platdev_match);
+		if (dev == NULL) {
+			DHD_ERROR(("bcmdhd wifi platform data device not found!!\n"));
+			return -ENXIO;
+		}
+		err = platform_driver_register(&dhd_wifi_platform_dev_driver);
+	} else
+#endif
+	{
+		err = wifi_ctrlfunc_register_drv();
+
+		/* no wifi ctrl func either, load bus directly and ignore this error */
+		if (err) {
+			if (err == -ENXIO) {
+				/* wifi ctrl function does not exist */
+				err = dhd_wifi_platform_load();
+			} else {
+				/* unregister driver due to initialization failure */
+				wifi_ctrlfunc_unregister_drv();
+			}
+		}
+	}
+
+	return err;
+}
+
+#ifdef BCMPCIE
+static int dhd_wifi_platform_load_pcie(void)
+{
+	int i;
+	int err;
+	int retry;
+	wifi_adapter_info_t *adapter;
+
+	if (dhd_wifi_platdata) {
+		/* enumerate PCIe RC */
+		for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
+			adapter = &dhd_wifi_platdata->adapters[i];
+			err = wifi_platform_bus_enumerate(adapter, TRUE);
+			if (err) {
+				DHD_ERROR(("failed to enumerate bus %s err=%d",
+					adapter->name, err));
+				return err;
+			}
+		}
+#ifdef DHD_SUPPORT_HDM
+		if (dhd_download_fw_on_driverload || hdm_trigger_init)
+#else
+		if (dhd_download_fw_on_driverload)
+#endif /* DHD_SUPPORT_HDM */
+		{
+			/* power up all adapters */
+			for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
+				retry = POWERUP_MAX_RETRY;
+				adapter = &dhd_wifi_platdata->adapters[i];
+
+				DHD_ERROR(("Power-up adapter '%s'\n", adapter->name));
+				DHD_INFO((" - irq %d [flags %d], firmware: %s, nvram: %s\n",
+					adapter->irq_num, adapter->intr_flags, adapter->fw_path,
+					adapter->nv_path));
+				DHD_INFO((" - bus type %d, bus num %d, slot num %d\n\n",
+					adapter->bus_type, adapter->bus_num, adapter->slot_num));
+
+				do {
+					err = wifi_platform_set_power(adapter,
+						TRUE, WIFI_TURNON_DELAY);
+					if (err) {
+						DHD_ERROR(("failed to power up %s,"
+							" %d retry left\n",
+							adapter->name, retry));
+						/* WL_REG_ON state unknown, Power off forcely */
+						wifi_platform_set_power(adapter,
+							FALSE, WIFI_TURNOFF_DELAY);
+						continue;
+					}
+
+					err = wifi_platform_bus_enumerate(adapter, TRUE);
+					if (err) {
+						DHD_ERROR(("failed to enumerate bus %s, "
+							"%d retry left\n",
+							adapter->name, retry));
+						wifi_platform_set_power(adapter, FALSE,
+							WIFI_TURNOFF_DELAY);
+					} else {
+						break;
+					}
+				} while (retry--);
+
+				if (retry < 0) {
+					DHD_ERROR(("failed to power up %s, max retry reached**\n",
+						adapter->name));
+					return -ENODEV;
+				}
+			}
+		}
+	}
+
+	err = dhd_bus_register();
+	if (err) {
+		DHD_ERROR(("%s: dhd_bus_register failed err=%d\n", __FUNCTION__, err));
+		if (dhd_wifi_platdata && dhd_download_fw_on_driverload) {
+			/* power down all adapters */
+			for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
+				adapter = &dhd_wifi_platdata->adapters[i];
+				wifi_platform_bus_enumerate(adapter, FALSE);
+				wifi_platform_set_power(adapter,
+					FALSE, WIFI_TURNOFF_DELAY);
+			}
+		}
+	}
+
+	return err;
+}
+#else
+static int dhd_wifi_platform_load_pcie(void)
+{
+	return 0;
+}
+#endif /* BCMPCIE  */
+
+void dhd_wifi_platform_unregister_drv(void)
+{
+#ifndef CUSTOMER_HW
+	if (cfg_multichip)
+		platform_driver_unregister(&dhd_wifi_platform_dev_driver);
+	else
+#endif
+		wifi_ctrlfunc_unregister_drv();
+}
+
+extern int dhd_watchdog_prio;
+extern int dhd_dpc_prio;
+extern uint dhd_deferred_tx;
+#if defined(OEM_ANDROID) && (defined(BCMLXSDMMC) || defined(BCMDBUS))
+extern struct semaphore dhd_registration_sem;
+#endif /* defined(OEM_ANDROID) && defined(BCMLXSDMMC) */
+
+#ifdef BCMSDIO
+static int dhd_wifi_platform_load_sdio(void)
+{
+	int i;
+	int err = 0;
+	wifi_adapter_info_t *adapter;
+
+	BCM_REFERENCE(i);
+	BCM_REFERENCE(adapter);
+	/* Sanity check on the module parameters
+	 * - Both watchdog and DPC as tasklets are ok
+	 * - If both watchdog and DPC are threads, TX must be deferred
+	 */
+	if (!(dhd_watchdog_prio < 0 && dhd_dpc_prio < 0) &&
+		!(dhd_watchdog_prio >= 0 && dhd_dpc_prio >= 0 && dhd_deferred_tx))
+		return -EINVAL;
+
+#if defined(OEM_ANDROID) && defined(BCMLXSDMMC) && !defined(DHD_PRELOAD)
+	sema_init(&dhd_registration_sem, 0);
+#endif
+
+	if (dhd_wifi_platdata == NULL) {
+		DHD_ERROR(("DHD wifi platform data is required for Android build\n"));
+		DHD_ERROR(("DHD registering bus directly\n"));
+		/* x86 bring-up PC needs no power-up operations */
+		err = dhd_bus_register();
+		return err;
+	}
+
+#if defined(OEM_ANDROID) && defined(BCMLXSDMMC) && !defined(DHD_PRELOAD)
+	/* power up all adapters */
+	for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
+		bool chip_up = FALSE;
+		int retry = POWERUP_MAX_RETRY;
+#ifndef DHD_INSMOD_NOWAIT
+		struct semaphore dhd_chipup_sem;
+#endif
+
+		adapter = &dhd_wifi_platdata->adapters[i];
+
+		DHD_ERROR(("Power-up adapter '%s'\n", adapter->name));
+		DHD_INFO((" - irq %d [flags %d], firmware: %s, nvram: %s\n",
+			adapter->irq_num, adapter->intr_flags, adapter->fw_path, adapter->nv_path));
+		DHD_INFO((" - bus type %d, bus num %d, slot num %d\n\n",
+			adapter->bus_type, adapter->bus_num, adapter->slot_num));
+
+		do {
+#ifdef DHD_INSMOD_NOWAIT
+			err = wifi_platform_set_power(adapter, TRUE, WIFI_TURNON_DELAY);
+			if (err) {
+				DHD_ERROR(("%s: wifi pwr on error ! \n", __FUNCTION__));
+				wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
+				continue;
+			} else {
+				wifi_platform_bus_enumerate(adapter, TRUE);
+				chip_up = TRUE;
+				break;
+			}
+#else
+			sema_init(&dhd_chipup_sem, 0);
+			err = dhd_bus_reg_sdio_notify(&dhd_chipup_sem);
+			if (err) {
+				DHD_ERROR(("%s dhd_bus_reg_sdio_notify fail(%d)\n\n",
+					__FUNCTION__, err));
+				return err;
+			}
+			err = wifi_platform_set_power(adapter, TRUE, WIFI_TURNON_DELAY);
+			if (err) {
+				DHD_ERROR(("%s: wifi pwr on error ! \n", __FUNCTION__));
+				dhd_bus_unreg_sdio_notify();
+				/* WL_REG_ON state unknown, Power off forcely */
+				wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
+				continue;
+			} else {
+				wifi_platform_bus_enumerate(adapter, TRUE);
+			}
+
+			if (down_timeout(&dhd_chipup_sem, msecs_to_jiffies(POWERUP_WAIT_MS)) == 0) {
+				dhd_bus_unreg_sdio_notify();
+				chip_up = TRUE;
+				break;
+			}
+
+			DHD_ERROR(("failed to power up %s, %d retry left\n", adapter->name, retry));
+			dhd_bus_unreg_sdio_notify();
+			wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
+			wifi_platform_bus_enumerate(adapter, FALSE);
+#endif
+		} while (retry--);
+
+		if (!chip_up) {
+			DHD_ERROR(("failed to power up %s, max retry reached**\n", adapter->name));
+			return -ENODEV;
+		}
+
+	}
+
+	err = dhd_bus_register();
+
+	if (err) {
+		DHD_ERROR(("%s: sdio_register_driver failed\n", __FUNCTION__));
+		goto fail;
+	}
+
+#ifndef DHD_INSMOD_NOWAIT
+	/*
+	 * Wait till MMC sdio_register_driver callback called and made driver attach.
+	 * It's needed to make sync up exit from dhd insmod  and
+	 * Kernel MMC sdio device callback registration
+	 */
+	err = down_timeout(&dhd_registration_sem, msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT));
+	if (err) {
+		DHD_ERROR(("%s: sdio_register_driver timeout or error \n", __FUNCTION__));
+		dhd_bus_unregister();
+		goto fail;
+	}
+#endif
+
+	return err;
+
+fail:
+	/* power down all adapters */
+	for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
+		adapter = &dhd_wifi_platdata->adapters[i];
+		wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
+		wifi_platform_bus_enumerate(adapter, FALSE);
+	}
+#else
+	/* x86 bring-up PC needs no power-up operations */
+	err = dhd_bus_register();
+#endif /* defined(OEM_ANDROID) && defined(BCMLXSDMMC) */
+
+	return err;
+}
+#else /* BCMSDIO */
+static int dhd_wifi_platform_load_sdio(void)
+{
+	return 0;
+}
+#endif /* BCMSDIO */
+
+#ifdef BCMDBUS
+static int dhd_wifi_platform_load_usb(void)
+{
+	int err = 0;
+#if !defined(DHD_PRELOAD)
+	wifi_adapter_info_t *adapter;
+	s32 timeout = -1;
+	int i;
+#endif
+
+#if !defined(DHD_PRELOAD) && !defined(ENABLE_INSMOD_NO_POWER_OFF)
+	/* power down all adapters */
+	for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
+		adapter = &dhd_wifi_platdata->adapters[i];
+		wifi_platform_set_power(adapter, FALSE, 0);
+		if (err) {
+			DHD_ERROR(("failed to wifi_platform_set_power off %s\n", adapter->name));
+			goto exit;
+		}
+	}
+	OSL_SLEEP(200);
+#endif
+
+	err = dhd_bus_register();
+	if (err) {
+		DHD_ERROR(("%s: usb_register failed\n", __FUNCTION__));
+		goto exit;
+	}
+
+#if !defined(DHD_PRELOAD)
+	/* power up all adapters */
+	for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
+		adapter = &dhd_wifi_platdata->adapters[i];
+		DHD_ERROR(("Power-up adapter '%s'\n", adapter->name));
+		DHD_INFO((" - irq %d [flags %d], firmware: %s, nvram: %s\n",
+			adapter->irq_num, adapter->intr_flags, adapter->fw_path, adapter->nv_path));
+		DHD_INFO((" - bus type %d, bus num %d, slot num %d\n\n",
+			adapter->bus_type, adapter->bus_num, adapter->slot_num));
+		err = wifi_platform_set_power(adapter, TRUE, WIFI_TURNON_DELAY);
+		if (err) {
+			DHD_ERROR(("failed to wifi_platform_set_power on %s\n", adapter->name));
+			goto fail;
+		}
+		timeout = wait_event_interruptible_timeout(adapter->status_event,
+			wifi_get_adapter_status(adapter, WIFI_STATUS_NET_ATTACHED),
+			msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT));
+		if (timeout <= 0) {
+			err = -1;
+			DHD_ERROR(("%s: usb_register_driver timeout\n", __FUNCTION__));
+			goto fail;
+		}
+	}
+#endif
+
+exit:
+	return err;
+
+#if !defined(DHD_PRELOAD)
+fail:
+	dhd_bus_unregister();
+	/* power down all adapters */
+	for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
+		adapter = &dhd_wifi_platdata->adapters[i];
+		wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
+	}
+
+	return err;
+#endif
+}
+#else /* BCMDBUS */
+static int dhd_wifi_platform_load_usb(void)
+{
+	return 0;
+}
+#endif /* BCMDBUS */
+
+static int dhd_wifi_platform_load(void)
+{
+	int err = 0;
+	printf("%s: Enter\n", __FUNCTION__);
+
+#if defined(OEM_ANDROID)
+	wl_android_init();
+#endif /* OEM_ANDROID */
+
+	if ((err = dhd_wifi_platform_load_usb())) {
+		goto end;
+	} else if ((err = dhd_wifi_platform_load_sdio())) {
+		goto end;
+	} else {
+		err = dhd_wifi_platform_load_pcie();
+	}
+
+end:
+#if defined(OEM_ANDROID)
+	if (err)
+		wl_android_exit();
+#if !defined(MULTIPLE_SUPPLICANT)
+	else
+		wl_android_post_init();
+#endif
+#endif /* OEM_ANDROID */
+
+	return err;
+}
+
+#if defined(SUPPORT_MULTIPLE_BOARD_REVISION)
+void
+concate_custom_board_revision(char *nv_path)
+{
+	uint32 board_revision = 0;
+	struct device_node *root_node = NULL;
+	char* wlan_node = NULL;
+
+	if (!nv_path) {
+		DHD_ERROR(("nv_path is null\n"));
+		return;
+	}
+
+	wlan_node = dhd_get_device_dt_name();
+	if (!wlan_node) {
+		DHD_ERROR(("Failed to dt name\n"));
+		return;
+	}
+
+	root_node = of_find_compatible_node(NULL, NULL, wlan_node);
+	if (!root_node) {
+		DHD_ERROR(("Failed to get device node\n"));
+		return;
+	}
+
+	if (of_property_read_u32(root_node, "nvram-ES", &board_revision)) {
+		DHD_ERROR(("No board revision property in dtsi\n"));
+		return;
+	}
+
+	DHD_INFO(("Board revision:%d\n", board_revision));
+
+	if (board_revision == 1) {
+		strcat(nv_path, "_ES10");
+		DHD_INFO(("Mached Board revision ES10: nvram name:%s\n", nv_path));
+	}
+
+}
+#endif /* SUPPORT_MULTIPLE_BOARD_REVISION */
+
+/* Weak functions that can be overridden in Platform specific implementation */
+char* __attribute__ ((weak)) dhd_get_device_dt_name(void)
+{
+	return NULL;
+}
+
+uint32 __attribute__ ((weak)) dhd_plat_get_info_size(void)
+{
+	return 0;
+}
+
+int __attribute__ ((weak)) dhd_plat_pcie_register_event(void *plat_info,
+		struct pci_dev *pdev, dhd_pcie_event_cb_t pfn)
+{
+	return 0;
+}
+
+void __attribute__ ((weak)) dhd_plat_pcie_deregister_event(void *plat_info)
+{
+	return;
+}
+
+void __attribute__ ((weak)) dhd_plat_l1ss_ctrl(bool ctrl)
+{
+	return;
+}
+
+void __attribute__ ((weak)) dhd_plat_l1_exit_io(void)
+{
+	return;
+}
+
+void __attribute__ ((weak)) dhd_plat_l1_exit(void)
+{
+	return;
+}
+
+void __attribute__ ((weak)) dhd_plat_report_bh_sched(void *plat_info, int resched)
+{
+	return;
+}
+
+int __attribute__ ((weak)) dhd_plat_pcie_suspend(void *plat_info)
+{
+	return 0;
+}
+
+int __attribute__ ((weak)) dhd_plat_pcie_resume(void *plat_info)
+{
+	return 0;
+}
+
+void __attribute__ ((weak)) dhd_plat_pcie_register_dump(void *plat_info)
+{
+	return;
+}
+
+void __attribute__ ((weak)) dhd_plat_pin_dbg_show(void *plat_info)
+{
+	return;
+}
+
+uint32 __attribute__ ((weak)) dhd_plat_get_rc_vendor_id(void)
+{
+	return PCIE_RC_VENDOR_ID;
+}
+
+uint32 __attribute__ ((weak)) dhd_plat_get_rc_device_id(void)
+{
+	return PCIE_RC_DEVICE_ID;
+}
+
+uint16 __attribute__ ((weak)) dhd_plat_align_rxbuf_size(uint16 rxbufpost_sz)
+{
+	return rxbufpost_sz;
+}
+
+int
+__attribute__ ((weak)) dhd_get_platform_naming_for_nvram_clmblob_file(download_type_t component,
+	char *file_name)
+{
+	return BCME_ERROR;
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux_priv.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux_priv.h
@@ -0,0 +1,575 @@
+/*
+ * DHD Linux header file - contains private structure definition of the Linux specific layer
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef __DHD_LINUX_PRIV_H__
+#define __DHD_LINUX_PRIV_H__
+
+#include <osl.h>
+
+#ifdef SHOW_LOGTRACE
+#include <linux/syscalls.h>
+#include <event_log.h>
+#endif /* SHOW_LOGTRACE */
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+#endif /* CONFIG COMPAT */
+#ifdef CONFIG_HAS_WAKELOCK
+#include <linux/pm_wakeup.h>
+#endif /* CONFIG_HAS_WAKELOCK */
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_dbg.h>
+#include <dhd_debug.h>
+#include <dhd_linux.h>
+#include <dhd_bus.h>
+
+#ifdef PCIE_FULL_DONGLE
+#include <bcmmsgbuf.h>
+#include <dhd_flowring.h>
+#endif /* PCIE_FULL_DONGLE */
+#if defined(DHD_HWTSTAMP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
+#include <linux/net_tstamp.h>
+#endif /* defined(DHD_HWTSTAMP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)) */
+
+#ifdef RX_PKT_POOL
+#define RX_PKTPOOL_RESCHED_DELAY_MS 500u
+#define RX_PKTPOOL_FETCH_MAX_ATTEMPTS 10u
+typedef struct pkt_pool {
+	struct sk_buff_head skb_q     ____cacheline_aligned;
+	uint32 max_size;
+	uint16 rxbuf_sz;
+} pkt_pool_t;
+#endif /* RX_PKT_POOL */
+
+/*
+ * Do not include this header except for the dhd_linux.c dhd_linux_sysfs.c
+ * Local private structure (extension of pub)
+ */
+typedef struct dhd_info {
+#if defined(WL_WIRELESS_EXT)
+	wl_iw_t		iw;		/* wireless extensions state (must be first) */
+#endif /* defined(WL_WIRELESS_EXT) */
+	dhd_pub_t pub;
+	/* for supporting multiple interfaces.
+	* static_ifs hold the net ifaces without valid FW IF
+	*/
+	dhd_if_t *iflist[DHD_MAX_IFS + DHD_MAX_STATIC_IFS];
+	wifi_adapter_info_t *adapter;			/* adapter information, interrupt, fw path etc. */
+	char fw_path[PATH_MAX];		/* path to firmware image */
+	char nv_path[PATH_MAX];		/* path to nvram vars file */
+	char clm_path[PATH_MAX];	/* path to CLM data */
+	char conf_path[PATH_MAX];	/* path to config vars file */
+	char sig_path[PATH_MAX];	/* path to rtecdc.sig file */
+#ifdef DHD_UCODE_DOWNLOAD
+	char uc_path[PATH_MAX];	/* path to ucode image */
+#endif /* DHD_UCODE_DOWNLOAD */
+
+	/* serialize dhd iovars */
+	struct mutex dhd_iovar_mutex;
+
+	struct semaphore proto_sem;
+#ifdef PROP_TXSTATUS
+	spinlock_t	wlfc_spinlock;
+
+#ifdef BCMDBUS
+	ulong		wlfc_lock_flags;
+	ulong		wlfc_pub_lock_flags;
+#endif /* BCMDBUS */
+#endif /* PROP_TXSTATUS */
+	wait_queue_head_t ioctl_resp_wait;
+	wait_queue_head_t d3ack_wait;
+	wait_queue_head_t dhd_bus_busy_state_wait;
+	wait_queue_head_t dmaxfer_wait;
+	uint32	default_wd_interval;
+
+	timer_list_compat_t timer;
+	bool wd_timer_valid;
+	struct tasklet_struct tasklet;
+	spinlock_t	sdlock;
+	spinlock_t	txqlock;
+	spinlock_t	dhd_lock;
+	spinlock_t	txoff_lock;
+#ifdef BCMDBUS
+	ulong		txqlock_flags;
+#endif /* BCMDBUS */
+
+#ifndef BCMDBUS
+	struct semaphore sdsem;
+	tsk_ctl_t	thr_dpc_ctl;
+	tsk_ctl_t	thr_wdt_ctl;
+#endif /* BCMDBUS */
+
+	tsk_ctl_t	thr_rxf_ctl;
+	spinlock_t	rxf_lock;
+	bool		rxthread_enabled;
+
+	/* Wakelocks */
+#if defined(CONFIG_HAS_WAKELOCK)
+	struct wakeup_source *wl_wifi;   /* Wifi wakelock */
+	struct wakeup_source *wl_rxwake; /* Wifi rx wakelock */
+	struct wakeup_source *wl_ctrlwake; /* Wifi ctrl wakelock */
+	struct wakeup_source *wl_wdwake; /* Wifi wd wakelock */
+	struct wakeup_source *wl_evtwake; /* Wifi event wakelock */
+	struct wakeup_source *wl_pmwake;   /* Wifi pm handler wakelock */
+	struct wakeup_source *wl_txflwake; /* Wifi tx flow wakelock */
+#ifdef BCMPCIE_OOB_HOST_WAKE
+	struct wakeup_source *wl_intrwake; /* Host wakeup wakelock */
+#endif /* BCMPCIE_OOB_HOST_WAKE */
+#ifdef DHD_USE_SCAN_WAKELOCK
+	struct wakeup_source *wl_scanwake;  /* Wifi scan wakelock */
+#endif /* DHD_USE_SCAN_WAKELOCK */
+	struct wakeup_source *wl_nanwake; /* NAN wakelock */
+#endif /* CONFIG_HAS_WAKELOCK */
+
+#if defined(OEM_ANDROID)
+	/* net_device interface lock, prevent race conditions among net_dev interface
+	 * calls and wifi_on or wifi_off
+	 */
+	struct mutex dhd_net_if_mutex;
+	struct mutex dhd_suspend_mutex;
+#if defined(APF)
+	struct mutex dhd_apf_mutex;
+#endif /* APF */
+#else
+#if defined(APF)
+	struct mutex dhd_apf_mutex;
+#endif /* APF */
+#endif /* OEM_ANDROID */
+	spinlock_t wakelock_spinlock;
+	spinlock_t wakelock_evt_spinlock;
+	uint32 wakelock_counter;
+	int wakelock_wd_counter;
+	int wakelock_rx_timeout_enable;
+	int wakelock_ctrl_timeout_enable;
+	bool waive_wakelock;
+	uint32 wakelock_before_waive;
+
+	/* Thread to issue ioctl for multicast */
+	wait_queue_head_t ctrl_wait;
+	atomic_t pend_8021x_cnt;
+	dhd_attach_states_t dhd_state;
+#ifdef SHOW_LOGTRACE
+	dhd_event_log_t event_data;
+#endif /* SHOW_LOGTRACE */
+
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(DHD_USE_EARLYSUSPEND)
+	struct early_suspend early_suspend;
+#endif /* CONFIG_HAS_EARLYSUSPEND && DHD_USE_EARLYSUSPEND */
+
+#ifdef ARP_OFFLOAD_SUPPORT
+	u32 pend_ipaddr;
+#endif /* ARP_OFFLOAD_SUPPORT */
+#ifdef DHDTCPACK_SUPPRESS
+	spinlock_t	tcpack_lock;
+#endif /* DHDTCPACK_SUPPRESS */
+#ifdef FIX_CPU_MIN_CLOCK
+	bool cpufreq_fix_status;
+	struct mutex cpufreq_fix;
+	struct pm_qos_request dhd_cpu_qos;
+#ifdef FIX_BUS_MIN_CLOCK
+	struct pm_qos_request dhd_bus_qos;
+#endif /* FIX_BUS_MIN_CLOCK */
+#endif /* FIX_CPU_MIN_CLOCK */
+	void			*dhd_deferred_wq;
+#if (defined(BCM_ROUTER_DHD) && defined(HNDCTF))
+	ctf_t		*cih;		/* ctf instance handle */
+	ctf_brc_hot_t *brc_hot;			/* hot ctf bridge cache entry */
+#endif /* BCM_ROUTER_DHD && HNDCTF */
+#ifdef DEBUG_CPU_FREQ
+	struct notifier_block freq_trans;
+	int __percpu *new_freq;
+#endif
+	unsigned int unit;
+	struct notifier_block pm_notifier;
+#ifdef DHD_PSTA
+	uint32	psta_mode;	/* PSTA or PSR */
+#endif /* DHD_PSTA */
+#ifdef DHD_WET
+	        uint32  wet_mode;
+#endif /* DHD_WET */
+#ifdef DHD_DEBUG
+	dhd_dump_t *dump;
+	timer_list_compat_t join_timer;
+	u32 join_timeout_val;
+	bool join_timer_active;
+	uint scan_time_count;
+	timer_list_compat_t scan_timer;
+	bool scan_timer_active;
+#endif
+	struct delayed_work	dhd_dpc_dispatcher_work;
+
+	/* CPU on which the DHD DPC is running */
+	atomic_t	dpc_cpu;
+	atomic_t	prev_dpc_cpu;
+#if defined(DHD_LB)
+#if defined(DHD_LB_HOST_CTRL)
+	bool permitted_primary_cpu;
+#endif /* DHD_LB_HOST_CTRL */
+	/* CPU Load Balance dynamic CPU selection */
+
+	/* Variable that tracks the currect CPUs available for candidacy */
+	cpumask_var_t cpumask_curr_avail;
+
+	/* Primary and secondary CPU mask */
+	cpumask_var_t cpumask_primary, cpumask_secondary; /* configuration */
+	cpumask_var_t cpumask_primary_new, cpumask_secondary_new; /* temp */
+
+	struct notifier_block cpu_notifier;
+
+	/* Napi struct for handling rx packet sendup. Packets are removed from
+	 * H2D RxCompl ring and placed into rx_pend_queue. rx_pend_queue is then
+	 * appended to rx_napi_queue (w/ lock) and the rx_napi_struct is scheduled
+	 * to run to rx_napi_cpu.
+	 */
+	struct sk_buff_head   rx_pend_queue  ____cacheline_aligned;
+	struct sk_buff_head   rx_napi_queue  ____cacheline_aligned;
+	struct sk_buff_head   rx_process_queue  ____cacheline_aligned;
+	struct napi_struct    rx_napi_struct ____cacheline_aligned;
+	atomic_t                   rx_napi_cpu; /* cpu on which the napi is dispatched */
+	struct net_device    *rx_napi_netdev; /* netdev of primary interface */
+
+	struct work_struct    rx_napi_dispatcher_work;
+	struct work_struct    tx_compl_dispatcher_work;
+	struct work_struct    tx_dispatcher_work;
+	struct work_struct    rx_compl_dispatcher_work;
+
+	/* Emergency queue to hold pkts when flow control is enabled and
+	 * same pkts will be posted back to the dongle till flow control is disabled.
+	*/
+	struct sk_buff_head   rx_emerge_queue	____cacheline_aligned;
+
+	/* Number of times DPC Tasklet ran */
+	uint32	dhd_dpc_cnt;
+	/* Number of times NAPI processing got scheduled */
+	uint32	napi_sched_cnt;
+	/* NAPI latency stats */
+	uint64  *napi_latency;
+	uint64 napi_schedule_time;
+	/* Number of times NAPI processing ran on each available core */
+	uint32	*napi_percpu_run_cnt;
+	/* Number of times RX Completions got scheduled */
+	uint32	rxc_sched_cnt;
+	/* Number of times RX Completion ran on each available core */
+	uint32	*rxc_percpu_run_cnt;
+	/* Number of times TX Completions got scheduled */
+	uint32	txc_sched_cnt;
+	/* Number of times TX Completions ran on each available core */
+	uint32	*txc_percpu_run_cnt;
+	/* CPU status */
+	/* Number of times each CPU came online */
+	uint32	*cpu_online_cnt;
+	/* Number of times each CPU went offline */
+	uint32	*cpu_offline_cnt;
+
+	/* Number of times TX processing run on each core */
+	uint32	*txp_percpu_run_cnt;
+	/* Number of times TX start run on each core */
+	uint32	*tx_start_percpu_run_cnt;
+
+	/* Tx load balancing */
+
+	/* TODO: Need to see if batch processing is really required in case of TX
+	 * processing. In case of RX the Dongle can send a bunch of rx completions,
+	 * hence we took a 3 queue approach
+	 * enque - adds the skbs to rx_pend_queue
+	 * dispatch - uses a lock and adds the list of skbs from pend queue to
+	 *            napi queue
+	 * napi processing - copies the pend_queue into a local queue and works
+	 * on it.
+	 * But for TX its going to be 1 skb at a time, so we are just thinking
+	 * of using only one queue and use the lock supported skb queue functions
+	 * to add and process it. If its in-efficient we'll re-visit the queue
+	 * design.
+	 */
+
+	/* When the NET_TX tries to send a TX packet put it into tx_pend_queue */
+	/* struct sk_buff_head		tx_pend_queue  ____cacheline_aligned;  */
+	/*
+	 * From the Tasklet that actually sends out data
+	 * copy the list tx_pend_queue into tx_active_queue. There by we need
+	 * to spinlock to only perform the copy the rest of the code ie to
+	 * construct the tx_pend_queue and the code to process tx_active_queue
+	 * can be lockless. The concept is borrowed as is from RX processing
+	 */
+	/* struct sk_buff_head		tx_active_queue  ____cacheline_aligned; */
+
+	/* Control TXP in runtime, enable by default */
+	atomic_t                lb_txp_active;
+
+	/* Control RXP in runtime, enable by default */
+	atomic_t                lb_rxp_active;
+
+	/*
+	 * When the NET_TX tries to send a TX packet put it into tx_pend_queue
+	 * For now, the processing tasklet will also direcly operate on this
+	 * queue
+	 */
+	struct sk_buff_head	tx_pend_queue  ____cacheline_aligned;
+
+	/* cpu on which the DHD Tx is happenning */
+	atomic_t		tx_cpu;
+
+	/* CPU on which the Network stack is calling the DHD's xmit function */
+	atomic_t		net_tx_cpu;
+
+	/* Tasklet context from which the DHD's TX processing happens */
+	struct tasklet_struct tx_tasklet;
+
+	/*
+	 * Consumer Histogram - NAPI RX Packet processing
+	 * -----------------------------------------------
+	 * On Each CPU, when the NAPI RX Packet processing call back was invoked
+	 * how many packets were processed is captured in this data structure.
+	 * Now its difficult to capture the "exact" number of packets processed.
+	 * So considering the packet counter to be a 32 bit one, we have a
+	 * bucket with 8 bins (2^1, 2^2 ... 2^8). The "number" of packets
+	 * processed is rounded off to the next power of 2 and put in the
+	 * approriate "bin" the value in the bin gets incremented.
+	 * For example, assume that in CPU 1 if NAPI Rx runs 3 times
+	 * and the packet count processed is as follows (assume the bin counters are 0)
+	 * iteration 1 - 10 (the bin counter 2^4 increments to 1)
+	 * iteration 2 - 30 (the bin counter 2^5 increments to 1)
+	 * iteration 3 - 15 (the bin counter 2^4 increments by 1 to become 2)
+	 */
+	uint32 *napi_rx_hist[HIST_BIN_SIZE];
+	uint32 *txc_hist[HIST_BIN_SIZE];
+	uint32 *rxc_hist[HIST_BIN_SIZE];
+	struct kobject dhd_lb_kobj;
+	bool dhd_lb_candidacy_override;
+	enum cpuhp_state dhd_cpuhp_state;
+#endif /* DHD_LB */
+
+	/* DPC bounds sysfs */
+	struct kobject dhd_dpc_bounds_kobj;
+
+#if defined(DNGL_AXI_ERROR_LOGGING) && defined(DHD_USE_WQ_FOR_DNGL_AXI_ERROR)
+	struct work_struct	  axi_error_dispatcher_work;
+#endif /* DNGL_AXI_ERROR_LOGGING && DHD_USE_WQ_FOR_DNGL_AXI_ERROR */
+#ifdef SHOW_LOGTRACE
+#ifdef DHD_USE_KTHREAD_FOR_LOGTRACE
+	tsk_ctl_t	  thr_logtrace_ctl;
+#else
+	struct delayed_work	  event_log_dispatcher_work;
+#endif /* DHD_USE_KTHREAD_FOR_LOGTRACE */
+#endif /* SHOW_LOGTRACE */
+
+#ifdef EWP_EDL
+	struct delayed_work edl_dispatcher_work;
+#endif
+#if defined(WLAN_ACCEL_BOOT)
+	bool wl_accel_force_reg_on;
+#endif
+#if defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW)
+#if defined(BCMDBUS)
+	struct task_struct *fw_download_task;
+	struct semaphore fw_download_lock;
+	bool fw_download_thread_exit;
+#endif /* BCMDBUS */
+#endif /* defined(BCM_DNGL_EMBEDIMAGE) || defined(BCM_REQUEST_FW) */
+	uint32 flag_kobj;    /* Add for duplicate kobj processing */
+	struct kobject dhd_kobj;
+	timer_list_compat_t timesync_timer;
+#if defined(BT_OVER_SDIO)
+    char btfw_path[PATH_MAX];
+#endif /* defined (BT_OVER_SDIO) */
+#ifdef WL_MONITOR
+	struct net_device *monitor_dev; /* monitor pseudo device */
+	struct sk_buff *monitor_skb;
+	uint	monitor_len;
+	uint	monitor_type;   /* monitor pseudo device */
+#ifdef HOST_RADIOTAP_CONV
+	monitor_info_t *monitor_info;
+	uint host_radiotap_conv;
+#endif /* HOST_RADIOTAP_CONV */
+#endif /* WL_MONITOR */
+#if defined(BT_OVER_SDIO)
+    struct mutex bus_user_lock; /* lock for sdio bus apis shared between WLAN & BT */
+    int     bus_user_count; /* User counts of sdio bus shared between WLAN & BT */
+#endif /* BT_OVER_SDIO */
+#ifdef SHOW_LOGTRACE
+	struct sk_buff_head   evt_trace_queue     ____cacheline_aligned;
+#endif
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+	struct workqueue_struct *tx_wq;
+	struct workqueue_struct *rx_wq;
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+#ifdef PCIE_INB_DW
+	wait_queue_head_t ds_exit_wait;
+#endif /* PCIE_INB_DW */
+#ifdef DHD_DEBUG_UART
+	bool duart_execute;
+#endif	/* DHD_DEBUG_UART */
+	struct mutex logdump_lock;
+#if defined(DHD_MQ) && defined(DHD_MQ_STATS)
+	uint64 pktcnt_qac_histo[MQ_MAX_QUEUES][AC_COUNT];
+	uint64 pktcnt_per_ac[AC_COUNT];
+	uint64 cpu_qstats[MQ_MAX_QUEUES][MQ_MAX_CPUS];
+#endif /* DHD_MQ && DHD_MQ_STATS */
+	/* indicates mem_dump was scheduled as work queue or called directly */
+	bool scheduled_memdump;
+	struct work_struct dhd_hang_process_work;
+#ifdef WL_CFGVENDOR_SEND_ALERT_EVENT
+	struct work_struct dhd_alert_process_work;
+#endif /* WL_CFGVENDOR_SEND_ALERT_EVENT */
+#ifdef RX_PKT_POOL
+	pkt_pool_t rx_pkt_pool;
+	tsk_ctl_t rx_pktpool_thread;
+#endif
+#if defined(DHD_FILE_DUMP_EVENT) && defined(DHD_FW_COREDUMP)
+	osl_atomic_t dump_status;
+	struct work_struct dhd_dump_proc_work;
+#endif /* DHD_FILE_DUMP_EVENT && DHD_FW_COREDUMP */
+#if defined(DHD_HWTSTAMP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
+	struct hwtstamp_config stmpconf;
+#endif /* defined(DHD_HWTSTAMP) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)) */
+} dhd_info_t;
+
+/** priv_link is the link between netdev and the dhdif and dhd_info structs. */
+typedef struct dhd_dev_priv {
+	dhd_info_t * dhd; /* cached pointer to dhd_info in netdevice priv */
+	dhd_if_t   * ifp; /* cached pointer to dhd_if in netdevice priv */
+	int          ifidx; /* interface index */
+	void       * lkup;
+} dhd_dev_priv_t;
+
+#define DHD_DEV_PRIV_SIZE       (sizeof(dhd_dev_priv_t))
+#define DHD_DEV_PRIV(dev)       ((dhd_dev_priv_t *)DEV_PRIV(dev))
+#define DHD_DEV_INFO(dev)       (((dhd_dev_priv_t *)DEV_PRIV(dev))->dhd)
+#define DHD_DEV_IFP(dev)        (((dhd_dev_priv_t *)DEV_PRIV(dev))->ifp)
+#define DHD_DEV_IFIDX(dev)      (((dhd_dev_priv_t *)DEV_PRIV(dev))->ifidx)
+#define DHD_DEV_LKUP(dev)		(((dhd_dev_priv_t *)DEV_PRIV(dev))->lkup)
+
+#ifdef WL_MONITOR
+#define MONPKT_EXTRA_LEN	48u
+#endif /* WL_MONITOR */
+
+extern int dhd_sysfs_init(dhd_info_t *dhd);
+extern void dhd_sysfs_exit(dhd_info_t *dhd);
+extern void dhd_dbg_ring_proc_create(dhd_pub_t *dhdp);
+extern void dhd_dbg_ring_proc_destroy(dhd_pub_t *dhdp);
+
+int __dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf);
+
+void dhd_dpc_tasklet_dispatcher_work(struct work_struct * work);
+#if defined(DHD_LB)
+#if defined(DHD_LB_TXP)
+int dhd_lb_sendpkt(dhd_info_t *dhd, struct net_device *net, int ifidx, void *skb);
+void dhd_tx_dispatcher_work(struct work_struct * work);
+void dhd_tx_dispatcher_fn(dhd_pub_t *dhdp);
+void dhd_lb_tx_dispatch(dhd_pub_t *dhdp);
+void dhd_lb_tx_handler(unsigned long data);
+#endif /* DHD_LB_TXP */
+
+#if defined(DHD_LB_RXP)
+int dhd_napi_poll(struct napi_struct *napi, int budget);
+void dhd_rx_napi_dispatcher_work(struct work_struct * work);
+void dhd_lb_rx_napi_dispatch(dhd_pub_t *dhdp);
+void dhd_lb_rx_pkt_enqueue(dhd_pub_t *dhdp, void *pkt, int ifidx);
+unsigned long dhd_read_lb_rxp(dhd_pub_t *dhdp);
+#endif /* DHD_LB_RXP */
+
+void dhd_lb_set_default_cpus(dhd_info_t *dhd);
+void dhd_cpumasks_deinit(dhd_info_t *dhd);
+int dhd_cpumasks_init(dhd_info_t *dhd);
+
+void dhd_select_cpu_candidacy(dhd_info_t *dhd);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
+int dhd_cpu_startup_callback(unsigned int cpu);
+int dhd_cpu_teardown_callback(unsigned int cpu);
+#else
+int dhd_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu);
+#endif /* LINUX_VERSION_CODE < 4.10.0 */
+
+int dhd_register_cpuhp_callback(dhd_info_t *dhd);
+int dhd_unregister_cpuhp_callback(dhd_info_t *dhd);
+#endif /* DHD_LB */
+
+#ifdef RX_PKT_POOL
+void dhd_rx_pktpool_init(dhd_info_t *dhd);
+void dhd_rx_pktpool_deinit(dhd_info_t *dhd);
+#endif /* RX_PKT_POOL */
+
+#if defined(SET_PCIE_IRQ_CPU_CORE) || defined(DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON)
+void dhd_irq_set_affinity(dhd_pub_t *dhdp, const struct cpumask *cpumask);
+#endif /* SET_PCIE_IRQ_CPU_CORE ||  DHD_CONTROL_PCIE_CPUCORE_WIFI_TURNON */
+
+void dhd_flush_logtrace_process(dhd_info_t *dhd);
+
+#ifdef DHD_SSSR_DUMP
+extern uint sssr_enab;
+extern uint fis_enab;
+#endif /* DHD_SSSR_DUMP */
+
+#if (ANDROID_VERSION > 0) && (LINUX_VERSION_CODE  >= KERNEL_VERSION(4, 14, 0))
+#define WAKELOCK_BACKPORT
+#endif
+
+#ifdef CONFIG_HAS_WAKELOCK
+#if ((LINUX_VERSION_CODE  >= KERNEL_VERSION(5, 4, 0)) || defined(WAKELOCK_BACKPORT))
+#define dhd_wake_lock_init(wakeup_source, dev, name) \
+do { \
+	wakeup_source = wakeup_source_register(dev, name); \
+} while (0);
+#else
+#define dhd_wake_lock_init(wakeup_source, dev, name) \
+do { \
+	wakeup_source = wakeup_source_register(name); \
+} while (0);
+#endif /* LINUX_VERSION >= 5.4.0 */
+#define dhd_wake_lock_destroy(wakeup_source) \
+do { \
+	wakeup_source_unregister(wakeup_source); \
+} while (0);
+#define dhd_wake_lock(wakeup_source)			__pm_stay_awake(wakeup_source)
+#define dhd_wake_unlock(wakeup_source)			__pm_relax(wakeup_source)
+#define dhd_wake_lock_active(wakeup_source)		((wakeup_source)->active)
+#define dhd_wake_lock_timeout(wakeup_source, timeout)	\
+	__pm_wakeup_event(wakeup_source, jiffies_to_msecs(timeout))
+#endif /* CONFIG_HAS_WAKELOCK */
+
+#endif /* __DHD_LINUX_PRIV_H__ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux_rx.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux_rx.c
@@ -0,0 +1,1742 @@
+/*
+ * Broadcom Dongle Host Driver (DHD),
+ * Linux-specific network interface for receive(rx) path
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+#ifdef SHOW_LOGTRACE
+#include <linux/syscalls.h>
+#include <event_log.h>
+#endif /* SHOW_LOGTRACE */
+
+#ifdef PCIE_FULL_DONGLE
+#include <bcmmsgbuf.h>
+#endif /* PCIE_FULL_DONGLE */
+
+#include <bcmsdpcm.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/etherdevice.h>
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/ethtool.h>
+#include <linux/fcntl.h>
+#include <linux/fs.h>
+#include <linux/ip.h>
+#include <linux/reboot.h>
+#include <linux/notifier.h>
+#include <linux/irq.h>
+#if defined(CONFIG_TIZEN)
+#include <linux/net_stat_tizen.h>
+#endif /* CONFIG_TIZEN */
+#include <net/addrconf.h>
+#include <net/ndisc.h>
+#ifdef ENABLE_ADAPTIVE_SCHED
+#include <linux/cpufreq.h>
+#endif /* ENABLE_ADAPTIVE_SCHED */
+#include <linux/rtc.h>
+#include <linux/namei.h>
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+#include <dhd_linux_priv.h>
+
+#include <epivers.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <bcmdevs.h>
+#include <bcmdevs_legacy.h>    /* need to still support chips no longer in trunk firmware */
+#include <bcmiov.h>
+#include <bcmstdlib_s.h>
+#include <bcmsdpcm.h>
+
+#include <ethernet.h>
+#include <bcmevent.h>
+#include <vlan.h>
+#include <802.3.h>
+
+#include <dhd_linux_wq.h>
+#include <dhd.h>
+#include <dhd_linux.h>
+#include <dhd_linux_pktdump.h>
+#ifdef DHD_WET
+#include <dhd_wet.h>
+#endif /* DHD_WET */
+#ifdef PCIE_FULL_DONGLE
+#include <dhd_flowring.h>
+#endif
+#include <dhd_bus.h>
+#include <dhd_proto.h>
+#include <dhd_dbg.h>
+#include <dhd_dbg_ring.h>
+#include <dhd_debug.h>
+#if defined(WL_CFG80211)
+#include <wl_cfg80211.h>
+#ifdef WL_BAM
+#include <wl_bam.h>
+#endif	/* WL_BAM */
+#endif	/* WL_CFG80211 */
+#ifdef PNO_SUPPORT
+#include <dhd_pno.h>
+#endif
+#ifdef RTT_SUPPORT
+#include <dhd_rtt.h>
+#endif
+
+#include <dhd_linux_sock_qos.h>
+
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+#endif
+
+#ifdef DHD_WMF
+#include <dhd_wmf_linux.h>
+#endif /* DHD_WMF */
+
+#ifdef DHD_L2_FILTER
+#include <bcmicmp.h>
+#include <bcm_l2_filter.h>
+#include <dhd_l2_filter.h>
+#endif /* DHD_L2_FILTER */
+
+#ifdef DHD_PSTA
+#include <dhd_psta.h>
+#endif /* DHD_PSTA */
+
+#ifdef AMPDU_VO_ENABLE
+/* XXX: Enabling VO AMPDU to reduce FER */
+#include <802.1d.h>
+#endif /* AMPDU_VO_ENABLE */
+
+#if defined(DHDTCPACK_SUPPRESS) || defined(DHDTCPSYNC_FLOOD_BLK)
+#include <dhd_ip.h>
+#endif /* DHDTCPACK_SUPPRESS || DHDTCPSYNC_FLOOD_BLK */
+#include <dhd_daemon.h>
+#ifdef DHD_PKT_LOGGING
+#include <dhd_pktlog.h>
+#endif /* DHD_PKT_LOGGING */
+#ifdef DHD_4WAYM4_FAIL_DISCONNECT
+#include <eapol.h>
+#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
+
+#ifdef ENABLE_DHD_GRO
+#include <net/sch_generic.h>
+#endif /* ENABLE_DHD_GRO */
+
+#ifdef FIX_CPU_MIN_CLOCK
+#include <linux/pm_qos.h>
+#endif /* FIX_CPU_MIN_CLOCK */
+
+#ifdef PROP_TXSTATUS
+#include <wlfc_proto.h>
+#include <dhd_wlfc.h>
+#endif
+
+#if defined(OEM_ANDROID)
+#include <wl_android.h>
+#endif
+
+#ifdef CSI_SUPPORT
+#include <dhd_csi.h>
+#endif /* CSI_SUPPORT */
+#include <dhd_config.h>
+
+/* RX frame thread priority */
+int dhd_rxf_prio = CUSTOM_RXF_PRIO_SETTING;
+module_param(dhd_rxf_prio, int, 0);
+
+/* Request scheduling of the bus rx frame */
+static void dhd_os_rxflock(dhd_pub_t *pub);
+static void dhd_os_rxfunlock(dhd_pub_t *pub);
+
+static int dhd_wl_host_event(dhd_info_t *dhd, int ifidx, void *pktdata, uint16 pktlen,
+                wl_event_msg_t *event_ptr, void **data_ptr);
+
+static inline int dhd_rxf_enqueue(dhd_pub_t *dhdp, void* skb)
+{
+	uint32 store_idx;
+	uint32 sent_idx;
+
+	if (!skb) {
+		DHD_ERROR(("dhd_rxf_enqueue: NULL skb!!!\n"));
+		return BCME_ERROR;
+	}
+
+	dhd_os_rxflock(dhdp);
+	store_idx = dhdp->store_idx;
+	sent_idx = dhdp->sent_idx;
+	if (dhdp->skbbuf[store_idx] != NULL) {
+		/* Make sure the previous packets are processed */
+		dhd_os_rxfunlock(dhdp);
+#ifdef RXF_DEQUEUE_ON_BUSY
+		DHD_TRACE(("dhd_rxf_enqueue: pktbuf not consumed %p, store idx %d sent idx %d\n",
+			skb, store_idx, sent_idx));
+		return BCME_BUSY;
+#else /* RXF_DEQUEUE_ON_BUSY */
+		DHD_ERROR(("dhd_rxf_enqueue: pktbuf not consumed %p, store idx %d sent idx %d\n",
+			skb, store_idx, sent_idx));
+		/* removed msleep here, should use wait_event_timeout if we
+		 * want to give rx frame thread a chance to run
+		 */
+#if defined(WAIT_DEQUEUE)
+		OSL_SLEEP(1);
+#endif
+		return BCME_ERROR;
+#endif /* RXF_DEQUEUE_ON_BUSY */
+	}
+	DHD_TRACE(("dhd_rxf_enqueue: Store SKB %p. idx %d -> %d\n",
+		skb, store_idx, (store_idx + 1) & (MAXSKBPEND - 1)));
+	dhdp->skbbuf[store_idx] = skb;
+	dhdp->store_idx = (store_idx + 1) & (MAXSKBPEND - 1);
+	dhd_os_rxfunlock(dhdp);
+
+	return BCME_OK;
+}
+
+static inline void* dhd_rxf_dequeue(dhd_pub_t *dhdp)
+{
+	uint32 store_idx;
+	uint32 sent_idx;
+	void *skb;
+
+	dhd_os_rxflock(dhdp);
+
+	store_idx = dhdp->store_idx;
+	sent_idx = dhdp->sent_idx;
+	skb = dhdp->skbbuf[sent_idx];
+
+	if (skb == NULL) {
+		dhd_os_rxfunlock(dhdp);
+		DHD_ERROR(("dhd_rxf_dequeue: Dequeued packet is NULL, store idx %d sent idx %d\n",
+			store_idx, sent_idx));
+		return NULL;
+	}
+
+	dhdp->skbbuf[sent_idx] = NULL;
+	dhdp->sent_idx = (sent_idx + 1) & (MAXSKBPEND - 1);
+
+	DHD_TRACE(("dhd_rxf_dequeue: netif_rx_ni(%p), sent idx %d\n",
+		skb, sent_idx));
+
+	dhd_os_rxfunlock(dhdp);
+
+	return skb;
+}
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+void dhd_rx_wq_wakeup(struct work_struct *ptr)
+{
+	struct dhd_rx_tx_work *work;
+	struct dhd_pub * pub;
+
+	work = container_of(ptr, struct dhd_rx_tx_work, work);
+
+	pub = work->pub;
+
+	DHD_RPM(("%s: ENTER. \n", __FUNCTION__));
+
+	if (atomic_read(&pub->block_bus) || pub->busstate == DHD_BUS_DOWN) {
+		return;
+	}
+
+	DHD_OS_WAKE_LOCK(pub);
+	if (pm_runtime_get_sync(dhd_bus_to_dev(pub->bus)) >= 0) {
+
+		// do nothing but wakeup the bus.
+		pm_runtime_mark_last_busy(dhd_bus_to_dev(pub->bus));
+		pm_runtime_put_autosuspend(dhd_bus_to_dev(pub->bus));
+	}
+	DHD_OS_WAKE_UNLOCK(pub);
+	kfree(work);
+}
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+#ifdef DHD_WMF
+bool
+dhd_is_rxthread_enabled(dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd = dhdp->info;
+
+	return dhd->rxthread_enabled;
+}
+#endif /* DHD_WMF */
+
+/** Called when a frame is received by the dongle on interface 'ifidx' */
+void
+dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+	struct sk_buff *skb;
+	uchar *eth;
+	uint len;
+	void *data, *pnext = NULL;
+	int i;
+	dhd_if_t *ifp;
+	wl_event_msg_t event;
+#if defined(OEM_ANDROID)
+	int tout_rx = 0;
+	int tout_ctrl = 0;
+#endif /* OEM_ANDROID */
+	void *skbhead = NULL;
+	void *skbprev = NULL;
+	uint16 protocol;
+	unsigned char *dump_data;
+#ifdef DHD_MCAST_REGEN
+	uint8 interface_role;
+	if_flow_lkup_t *if_flow_lkup;
+	unsigned long flags;
+#endif
+#ifdef DHD_WAKE_STATUS
+	wake_counts_t *wcp = NULL;
+#endif /* DHD_WAKE_STATUS */
+	int pkt_wake = 0;
+#ifdef ENABLE_DHD_GRO
+	bool dhd_gro_enable = TRUE;
+	struct Qdisc *qdisc = NULL;
+#endif /* ENABLE_DHD_GRO */
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+	BCM_REFERENCE(dump_data);
+	BCM_REFERENCE(pkt_wake);
+
+#ifdef DHD_TPUT_PATCH
+	if (dhdp->conf->pktsetsum)
+		PKTSETSUMGOOD(pktbuf, TRUE);
+#endif
+
+#ifdef ENABLE_DHD_GRO
+	if (ifidx < DHD_MAX_IFS) {
+		ifp = dhd->iflist[ifidx];
+		if (ifp && ifp->net->qdisc) {
+			if (ifp->net->qdisc->ops->cl_ops) {
+				dhd_gro_enable = FALSE;
+				DHD_TRACE(("%s: disable sw gro becasue of"
+						" qdisc tx traffic control\n", __FUNCTION__));
+			}
+
+			if (dev_ingress_queue(ifp->net)) {
+				qdisc = dev_ingress_queue(ifp->net)->qdisc_sleeping;
+				if (qdisc != NULL && (qdisc->flags & TCQ_F_INGRESS)) {
+					if (
+#if defined(CONFIG_NET_XGRESS)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0))
+						(ifp->net->tcx_ingress != NULL) ||
+#endif /* LINUX_VERSION >= 6.6.0 */
+#elif defined(CONFIG_NET_CLS_ACT)
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
+						(ifp->net->miniq_ingress != NULL) ||
+#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
+						(ifp->net->ingress_cl_list != NULL) ||
+#endif /* LINUX_VERSION >= 4.2.0 */
+#endif /* CONFIG_NET_CLS_ACT */
+						0) {
+						dhd_gro_enable = FALSE;
+						DHD_TRACE(("%s: disable sw gro because of"
+						" qdisc rx traffic control\n", __FUNCTION__));
+					}
+				}
+			}
+		}
+	}
+#ifdef DHD_GRO_ENABLE_HOST_CTRL
+	if (!dhdp->permitted_gro && dhd_gro_enable) {
+		dhd_gro_enable = FALSE;
+	}
+#endif /* DHD_GRO_ENABLE_HOST_CTRL */
+#endif /* ENABLE_DHD_GRO */
+
+	for (i = 0; pktbuf && i < numpkt; i++, pktbuf = pnext) {
+		struct ether_header *eh;
+
+		pnext = PKTNEXT(dhdp->osh, pktbuf);
+		PKTSETNEXT(dhdp->osh, pktbuf, NULL);
+
+		/* info ring "debug" data, which is not a 802.3 frame, is sent/hacked with a
+		 * special ifidx of DHD_DUMMY_INFO_IF.  This is just internal to dhd to get the data
+		 * from dhd_msgbuf.c:dhd_prot_infobuf_cmplt_process() to here (dhd_rx_frame).
+		 */
+		if (ifidx == DHD_DUMMY_INFO_IF) {
+			/* Event msg printing is called from dhd_rx_frame which is in Tasklet
+			 * context in case of PCIe FD, in case of other bus this will be from
+			 * DPC context. If we get bunch of events from Dongle then printing all
+			 * of them from Tasklet/DPC context that too in data path is costly.
+			 * Also in the new Dongle SW(4359, 4355 onwards) console prints too come as
+			 * events with type WLC_E_TRACE.
+			 * We'll print this console logs from the WorkQueue context by enqueing SKB
+			 * here and Dequeuing will be done in WorkQueue and will be freed only if
+			 * logtrace_pkt_sendup is TRUE
+			 */
+#ifdef SHOW_LOGTRACE
+			dhd_event_logtrace_enqueue(dhdp, ifidx, pktbuf);
+#else /* !SHOW_LOGTRACE */
+			/* If SHOW_LOGTRACE not defined and ifidx is DHD_DUMMY_INFO_IF,
+			 * free the PKT here itself
+			 */
+			PKTFREE_CTRLBUF(dhdp->osh, pktbuf, FALSE);
+#endif /* SHOW_LOGTRACE */
+			continue;
+		}
+
+		eh = (struct ether_header *)PKTDATA(dhdp->osh, pktbuf);
+
+		/* Check if dhd_stop is in progress */
+		if (dhdp->stop_in_progress) {
+			DHD_ERROR_RLMT(("%s: dhd_stop in progress ignore received packet\n",
+				__FUNCTION__));
+			RX_PKTFREE(dhdp->osh, eh->ether_type, pktbuf, FALSE);
+			continue;
+		}
+
+#ifdef DHD_WAKE_STATUS
+		/* Get pkt_wake and clear it */
+#if defined(BCMPCIE)
+		pkt_wake = dhd_bus_set_get_bus_wake_pkt_dump(dhdp, 0);
+#elif defined(BCMSDIO)
+		pkt_wake = dhd_bus_set_get_bus_wake(dhdp, 0);
+#endif /* BCMPCIE */
+#ifdef BCMDBUS
+		wcp = NULL;
+#else
+		wcp = dhd_bus_get_wakecount(dhdp);
+#endif /* BCMDBUS */
+		if (wcp == NULL) {
+			/* If wakeinfo count buffer is null do not  update wake count values */
+			pkt_wake = 0;
+		}
+#endif /* DHD_WAKE_STATUS */
+
+		if (dhd->pub.tput_data.tput_test_running &&
+			dhd->pub.tput_data.direction == TPUT_DIR_RX &&
+			ntoh16(eh->ether_type) == ETHER_TYPE_IP) {
+			dhd_tput_test_rx(dhdp, pktbuf);
+			PKTFREE(dhd->pub.osh, pktbuf, FALSE);
+			continue;
+		}
+
+		if (ifidx >= DHD_MAX_IFS) {
+			DHD_ERROR(("%s: ifidx(%d) Out of bound. drop packet\n",
+				__FUNCTION__, ifidx));
+			RX_PKTFREE(dhdp->osh, eh->ether_type, pktbuf, FALSE);
+			continue;
+		}
+
+		ifp = dhd->iflist[ifidx];
+		if (ifp == NULL) {
+			DHD_ERROR_RLMT(("%s: ifp is NULL. drop packet\n",
+				__FUNCTION__));
+			RX_PKTFREE(dhdp->osh, eh->ether_type, pktbuf, FALSE);
+			continue;
+		}
+
+		/* Dropping only data packets before registering net device to avoid kernel panic */
+#ifndef PROP_TXSTATUS_VSDB
+		if ((!ifp->net || ifp->net->reg_state != NETREG_REGISTERED) &&
+			(ntoh16(eh->ether_type) != ETHER_TYPE_BRCM))
+#else
+		if ((!ifp->net || ifp->net->reg_state != NETREG_REGISTERED || !dhd->pub.up) &&
+			(ntoh16(eh->ether_type) != ETHER_TYPE_BRCM))
+#endif /* PROP_TXSTATUS_VSDB */
+		{
+			DHD_ERROR(("%s: net device is NOT registered yet. drop packet\n",
+			__FUNCTION__));
+			PKTCFREE(dhdp->osh, pktbuf, FALSE);
+			continue;
+		}
+
+#ifdef PROP_TXSTATUS
+		if (dhd_wlfc_is_header_only_pkt(dhdp, pktbuf)) {
+			/* WLFC may send header only packet when
+			there is an urgent message but no packet to
+			piggy-back on
+			*/
+			PKTCFREE(dhdp->osh, pktbuf, FALSE);
+			continue;
+		}
+#endif
+#ifdef DHD_L2_FILTER
+		/* If block_ping is enabled drop the ping packet */
+		if (ifp->block_ping) {
+			if (bcm_l2_filter_block_ping(dhdp->osh, pktbuf) == BCME_OK) {
+				PKTCFREE(dhdp->osh, pktbuf, FALSE);
+				continue;
+			}
+		}
+		if (ifp->grat_arp && DHD_IF_ROLE_STA(dhdp, ifidx)) {
+		    if (bcm_l2_filter_gratuitous_arp(dhdp->osh, pktbuf) == BCME_OK) {
+				PKTCFREE(dhdp->osh, pktbuf, FALSE);
+				continue;
+		    }
+		}
+		if (ifp->parp_enable && DHD_IF_ROLE_AP(dhdp, ifidx)) {
+			int ret = dhd_l2_filter_pkt_handle(dhdp, ifidx, pktbuf, FALSE);
+
+			/* Drop the packets if l2 filter has processed it already
+			 * otherwise continue with the normal path
+			 */
+			if (ret == BCME_OK) {
+				PKTCFREE(dhdp->osh, pktbuf, TRUE);
+				continue;
+			}
+		}
+		if (ifp->block_tdls) {
+			if (bcm_l2_filter_block_tdls(dhdp->osh, pktbuf) == BCME_OK) {
+				PKTCFREE(dhdp->osh, pktbuf, FALSE);
+				continue;
+			}
+		}
+#endif /* DHD_L2_FILTER */
+
+#ifdef DHD_MCAST_REGEN
+		DHD_FLOWID_LOCK(dhdp->flowid_lock, flags);
+		if_flow_lkup = (if_flow_lkup_t *)dhdp->if_flow_lkup;
+		ASSERT(if_flow_lkup);
+
+		interface_role = if_flow_lkup[ifidx].role;
+		DHD_FLOWID_UNLOCK(dhdp->flowid_lock, flags);
+
+		if (ifp->mcast_regen_bss_enable && (interface_role != WLC_E_IF_ROLE_WDS) &&
+				!DHD_IF_ROLE_AP(dhdp, ifidx) &&
+				ETHER_ISUCAST(eh->ether_dhost)) {
+			if (dhd_mcast_reverse_translation(eh) ==  BCME_OK) {
+#ifdef DHD_PSTA
+				/* Change bsscfg to primary bsscfg for unicast-multicast packets */
+				if ((dhd_get_psta_mode(dhdp) == DHD_MODE_PSTA) ||
+						(dhd_get_psta_mode(dhdp) == DHD_MODE_PSR)) {
+					if (ifidx != 0) {
+						/* Let the primary in PSTA interface handle this
+						 * frame after unicast to Multicast conversion
+						 */
+						ifp = dhd_get_ifp(dhdp, 0);
+						ASSERT(ifp);
+					}
+				}
+			}
+#endif /* PSTA */
+		}
+#endif /* MCAST_REGEN */
+
+#ifdef DHD_WMF
+		/* WMF processing for multicast packets */
+		if (ifp->wmf.wmf_enable && (ETHER_ISMULTI(eh->ether_dhost))) {
+			dhd_sta_t *sta;
+			int ret;
+
+			sta = dhd_find_sta(dhdp, ifidx, (void *)eh->ether_shost);
+			ret = dhd_wmf_packets_handle(dhdp, pktbuf, sta, ifidx, 1);
+			switch (ret) {
+				case WMF_TAKEN:
+					/* The packet is taken by WMF. Continue to next iteration */
+					continue;
+				case WMF_DROP:
+					/* Packet DROP decision by WMF. Toss it */
+					DHD_ERROR(("%s: WMF decides to drop packet\n",
+						__FUNCTION__));
+					PKTCFREE(dhdp->osh, pktbuf, FALSE);
+					continue;
+				default:
+					/* Continue the transmit path */
+					break;
+			}
+		}
+#endif /* DHD_WMF */
+
+#ifdef DHDTCPSYNC_FLOOD_BLK
+		if (dhd_tcpdata_get_flag(dhdp, pktbuf) == FLAG_SYNC) {
+			int delta_sec;
+			int delta_sync;
+			int sync_per_sec;
+			u64 curr_time = DIV_U64_BY_U32(OSL_LOCALTIME_NS(), NSEC_PER_SEC);
+			ifp->tsync_rcvd ++;
+			delta_sync = ifp->tsync_rcvd - ifp->tsyncack_txed;
+			delta_sec = curr_time - ifp->last_sync;
+			if (delta_sec > 1) {
+				sync_per_sec = delta_sync/delta_sec;
+				if (sync_per_sec > TCP_SYNC_FLOOD_LIMIT) {
+					schedule_work(&ifp->blk_tsfl_work);
+					DHD_ERROR(("ifx %d TCP SYNC Flood attack suspected! "
+						"sync recvied %d pkt/sec \n",
+						ifidx, sync_per_sec));
+					ifp->tsync_per_sec = sync_per_sec;
+				}
+				dhd_reset_tcpsync_info_by_ifp(ifp);
+			}
+
+		}
+#endif /* DHDTCPSYNC_FLOOD_BLK */
+
+#ifdef DHDTCPACK_SUPPRESS
+		dhd_tcpdata_info_get(dhdp, pktbuf);
+#endif
+		skb = PKTTONATIVE(dhdp->osh, pktbuf);
+
+		ASSERT(ifp);
+		skb->dev = ifp->net;
+#ifdef DHD_WET
+		/* wet related packet proto manipulation should be done in DHD
+		 * since dongle doesn't have complete payload
+		 */
+		if (WET_ENABLED(&dhd->pub) && (dhd_wet_recv_proc(dhd->pub.wet_info,
+				pktbuf) < 0)) {
+			DHD_INFO(("%s:%s: wet recv proc failed\n",
+				__FUNCTION__, dhd_ifname(dhdp, ifidx)));
+		}
+#endif /* DHD_WET */
+
+#ifdef DHD_PSTA
+		if (PSR_ENABLED(dhdp) &&
+#ifdef BCM_ROUTER_DHD
+				!(ifp->primsta_dwds) &&
+#endif /* BCM_ROUTER_DHD */
+				(dhd_psta_proc(dhdp, ifidx, &pktbuf, FALSE) < 0)) {
+			DHD_ERROR(("%s:%s: psta recv proc failed\n", __FUNCTION__,
+				dhd_ifname(dhdp, ifidx)));
+		}
+#endif /* DHD_PSTA */
+
+#if defined(BCM_ROUTER_DHD)
+		/* XXX Use WOFA for both dhdap and dhdap-atlas router. */
+		/* XXX dhd_sendpkt verify pkt accounting (TO/FRM NATIVE) and PKTCFREE */
+
+		if (DHD_IF_ROLE_AP(dhdp, ifidx) && (!ifp->ap_isolate)) {
+			eh = (struct ether_header *)PKTDATA(dhdp->osh, pktbuf);
+			if (ETHER_ISUCAST(eh->ether_dhost)) {
+				if (dhd_find_sta(dhdp, ifidx, (void *)eh->ether_dhost)) {
+					dhd_sendpkt(dhdp, ifidx, pktbuf);
+					continue;
+				}
+			} else {
+				void *npkt;
+#if defined(HNDCTF)
+				if (PKTISCHAINED(pktbuf)) { /* XXX WAR */
+					DHD_ERROR(("Error: %s():%d Chained non unicast pkt<%p>\n",
+						__FUNCTION__, __LINE__, pktbuf));
+					PKTFRMNATIVE(dhdp->osh, pktbuf);
+					PKTCFREE(dhdp->osh, pktbuf, FALSE);
+					continue;
+				}
+#endif /* HNDCTF */
+				if ((ntoh16(eh->ether_type) != ETHER_TYPE_IAPP_L2_UPDATE) &&
+					((npkt = PKTDUP(dhdp->osh, pktbuf)) != NULL))
+					dhd_sendpkt(dhdp, ifidx, npkt);
+			}
+		}
+
+#if defined(HNDCTF)
+		/* try cut thru' before sending up */
+		if (dhd_ctf_forward(dhd, skb, &pnext) == BCME_OK) {
+			continue;
+		}
+#endif /* HNDCTF */
+
+#else /* !BCM_ROUTER_DHD */
+
+#if defined(DBG_PKT_MON) && !defined(PCIE_FULL_DONGLE)
+		if (chan == SDPCM_EVENT_CHANNEL) {
+			if (dhd_80211_mon_pkt(dhdp, pktbuf, ifidx)) {
+				continue;
+			}
+		}
+#endif
+
+#ifdef PCIE_FULL_DONGLE
+		if ((DHD_IF_ROLE_AP(dhdp, ifidx) || DHD_IF_ROLE_P2PGO(dhdp, ifidx)) &&
+			(!ifp->ap_isolate)) {
+			eh = (struct ether_header *)PKTDATA(dhdp->osh, pktbuf);
+			if (ETHER_ISUCAST(eh->ether_dhost)) {
+				if (dhd_find_sta(dhdp, ifidx, (void *)eh->ether_dhost)) {
+					dhdp->rx_forward++; /* Local count */
+					dhd_sendpkt(dhdp, ifidx, pktbuf);
+					continue;
+				}
+			} else {
+				if ((ntoh16(eh->ether_type) != ETHER_TYPE_IAPP_L2_UPDATE)) {
+					void *npktbuf = NULL;
+					/*
+					* If host_sfhllc_supported enabled, do skb_copy as SFHLLC
+					* header will be inserted during Tx, due to which network
+					* stack will not decode the Rx packet.
+					* Else PKTDUP(skb_clone) is enough.
+					*/
+					if (dhdp->host_sfhllc_supported) {
+						npktbuf = skb_copy(skb, GFP_ATOMIC);
+					} else {
+						npktbuf = PKTDUP(dhdp->osh, pktbuf);
+					}
+					if (npktbuf != NULL) {
+						dhdp->rx_forward++; /* Local count */
+						dhd_sendpkt(dhdp, ifidx, npktbuf);
+					}
+				}
+			}
+		}
+#endif /* PCIE_FULL_DONGLE */
+#endif /* BCM_ROUTER_DHD */
+#ifdef DHD_POST_EAPOL_M1_AFTER_ROAM_EVT
+		if ((IS_STA_IFACE(ndev_to_wdev(ifp->net)) || (IS_P2P_GC(ndev_to_wdev(ifp->net)))) &&
+			(ifp->recv_reassoc_evt == TRUE) && (ifp->post_roam_evt == FALSE) &&
+			(dhd_is_4way_msg((char *)(skb->data)) == EAPOL_4WAY_M1)) {
+				DHD_ERROR(("%s: Reassoc is in progress. "
+					"Drop EAPOL M1 frame\n", __FUNCTION__));
+				PKTFREE(dhdp->osh, pktbuf, FALSE);
+				continue;
+		}
+#endif /* DHD_POST_EAPOL_M1_AFTER_ROAM_EVT */
+#ifdef WLEASYMESH
+		if ((dhdp->conf->fw_type == FW_TYPE_EZMESH) &&
+				(ntoh16(eh->ether_type) != ETHER_TYPE_BRCM)) {
+			uint16 * da = (uint16 *)(eh->ether_dhost);
+			ASSERT(ISALIGNED(da, 2));
+
+			/* XXX: Special handling for 1905 messages
+			 * if DA matches with configured 1905 AL MAC addresses
+			 * bypass fwder and foward it to linux stack
+			 */
+			if (ntoh16(eh->ether_type) == ETHER_TYPE_1905_1) {
+				if (!eacmp(da, ifp->_1905_al_ucast) || !eacmp(da, ifp->_1905_al_mcast)) {
+					//skb->fwr_flood = 0;
+				} else {
+					//skb->fwr_flood = 1;
+				}
+			}
+		}
+#endif /* WLEASYMESH */
+		/* Get the protocol, maintain skb around eth_type_trans()
+		 * The main reason for this hack is for the limitation of
+		 * Linux 2.4 where 'eth_type_trans' uses the 'net->hard_header_len'
+		 * to perform skb_pull inside vs ETH_HLEN. Since to avoid
+		 * coping of the packet coming from the network stack to add
+		 * BDC, Hardware header etc, during network interface registration
+		 * we set the 'net->hard_header_len' to ETH_HLEN + extra space required
+		 * for BDC, Hardware header etc. and not just the ETH_HLEN
+		 */
+		eth = skb->data;
+		len = skb->len;
+		dump_data = skb->data;
+		protocol = (skb->data[12] << 8) | skb->data[13];
+
+		if (protocol == ETHER_TYPE_802_1X) {
+			DBG_EVENT_LOG(dhdp, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED);
+#if defined(WL_CFG80211) && defined(WL_WPS_SYNC)
+			wl_handle_wps_states(ifp->net, dump_data, len, FALSE);
+#endif /* WL_CFG80211 && WL_WPS_SYNC */
+#ifdef DHD_4WAYM4_FAIL_DISCONNECT
+			if (dhd_is_4way_msg((uint8 *)(skb->data)) == EAPOL_4WAY_M3) {
+				OSL_ATOMIC_SET(dhdp->osh, &ifp->m4state, M3_RXED);
+			}
+#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
+#ifdef EAPOL_RESEND
+			wl_ext_release_eapol_txpkt(dhdp, ifidx, TRUE);
+#endif /* EAPOL_RESEND */
+		}
+		dhd_handle_pktdata(dhdp, ifidx, skb, dump_data, FALSE,
+			len, NULL, NULL, NULL, FALSE, pkt_wake, TRUE);
+#if defined(DHD_WAKE_STATUS) && defined(DHD_WAKEPKT_DUMP)
+		if (pkt_wake) {
+			DHD_ERROR(("##### dhdpcie_host_wake caused by packets\n"));
+			dhd_prhex("[wakepkt_dump]", (char*)dump_data, MIN(len, 64), DHD_RPM_VAL);
+			DHD_ERROR(("config check in_suspend: %d\n", dhdp->in_suspend));
+#ifdef ARP_OFFLOAD_SUPPORT
+			DHD_ERROR(("arp hmac_update:%d \n", dhdp->hmac_updated));
+#endif /* ARP_OFFLOAD_SUPPORT */
+#if defined(DHD_WAKEPKT_SET_MARK) && defined(CONFIG_NF_CONNTRACK_MARK)
+			PKTMARK(skb) |= 0x80000000;
+#endif /* DHD_WAKEPKT_SET_MARK && CONFIG_NF_CONNTRACK_MARK */
+		}
+#endif /* DHD_WAKE_STATUS && DHD_WAKEPKT_DUMP */
+
+		skb->protocol = eth_type_trans(skb, skb->dev);
+
+		if (skb->pkt_type == PACKET_MULTICAST) {
+			dhd->pub.rx_multicast++;
+			ifp->stats.multicast++;
+		}
+
+		skb->data = eth;
+		skb->len = len;
+
+		/* TODO: XXX: re-look into dropped packets. */
+		DHD_DBG_PKT_MON_RX(dhdp, skb, FRAME_TYPE_ETHERNET_II);
+		/* Strip header, count, deliver upward */
+		skb_pull(skb, ETH_HLEN);
+
+#ifdef ENABLE_WAKEUP_PKT_DUMP
+		if (dhd_mmc_wake) {
+			DHD_INFO(("wake_pkt %s(%d)\n", __FUNCTION__, __LINE__));
+			prhex("wake_pkt", (char*) eth, MIN(len, 64));
+
+			update_wake_pkt_info(skb);
+			DHD_ERROR(("wake_pkt %s(%d), raw_info=0x%016llx\n",
+				__FUNCTION__, __LINE__, temp_raw))
+#ifdef CONFIG_IRQ_HISTORY
+			add_irq_history(0, "WIFI");
+#endif
+			dhd_mmc_wake = FALSE;
+		}
+#endif /* ENABLE_WAKEUP_PKT_DUMP */
+
+		/* Process special event packets and then discard them */
+		/* XXX Decide on a better way to fit this in */
+		memset(&event, 0, sizeof(event));
+
+		if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) {
+			bcm_event_msg_u_t evu;
+			int ret_event, event_type;
+			void *pkt_data = skb_mac_header(skb);
+
+			ret_event = wl_host_event_get_data(pkt_data, len, &evu);
+
+			if (ret_event != BCME_OK) {
+				DHD_ERROR(("%s: wl_host_event_get_data err = %d\n",
+					__FUNCTION__, ret_event));
+				PKTFREE_CTRLBUF(dhdp->osh, pktbuf, FALSE);
+				continue;
+			}
+
+			memcpy(&event, &evu.event, sizeof(wl_event_msg_t));
+			event_type = ntoh32_ua((void *)&event.event_type);
+#ifdef SHOW_LOGTRACE
+			/* Event msg printing is called from dhd_rx_frame which is in Tasklet
+			 * context in case of PCIe FD, in case of other bus this will be from
+			 * DPC context. If we get bunch of events from Dongle then printing all
+			 * of them from Tasklet/DPC context that too in data path is costly.
+			 * Also in the new Dongle SW(4359, 4355 onwards) console prints too come as
+			 * events with type WLC_E_TRACE.
+			 * We'll print this console logs from the WorkQueue context by enqueing SKB
+			 * here and Dequeuing will be done in WorkQueue and will be freed only if
+			 * logtrace_pkt_sendup is true
+			 */
+			if (event_type == WLC_E_TRACE) {
+				DHD_TRACE(("%s: WLC_E_TRACE\n", __FUNCTION__));
+				dhd_event_logtrace_enqueue(dhdp, ifidx, pktbuf);
+				continue;
+			}
+#endif /* SHOW_LOGTRACE */
+
+#ifdef CSI_SUPPORT
+			if (WLC_E_CSI == event_type) {
+				DHD_TRACE(("%s: WLC_E_CSI\n", __func__));
+				dhd_csi_event_enqueue(dhdp, ifidx, pktbuf);
+				continue;
+			}
+#endif /* CSI_SUPPORT */
+
+			ret_event = dhd_wl_host_event(dhd, ifidx, pkt_data, len, &event, &data);
+
+			wl_event_to_host_order(&event);
+#if defined(OEM_ANDROID)
+			if (!tout_ctrl)
+				tout_ctrl = DHD_PACKET_TIMEOUT_MS;
+#endif /* OEM_ANDROID */
+
+#if (defined(OEM_ANDROID) && defined(PNO_SUPPORT))
+			if (event_type == WLC_E_PFN_NET_FOUND) {
+				/* enforce custom wake lock to garantee that Kernel not suspended */
+				tout_ctrl = CUSTOM_PNO_EVENT_LOCK_xTIME * DHD_PACKET_TIMEOUT_MS;
+			}
+#endif /* PNO_SUPPORT */
+			if (numpkt != 1) {
+				DHD_TRACE(("%s: Got BRCM event packet in a chained packet.\n",
+				__FUNCTION__));
+			}
+
+#ifdef DHD_WAKE_STATUS
+			if (unlikely(pkt_wake)) {
+#ifdef DHD_WAKE_EVENT_STATUS
+				if (event.event_type < WLC_E_LAST) {
+#ifdef CUSTOM_WAKE_REASON_STATS
+					if (wcp->rc_event_idx == MAX_WAKE_REASON_STATS) {
+						wcp->rc_event_idx = 0;
+					}
+					DHD_ERROR(("[pkt_wake] event id %u = %s\n",
+						event.event_type,
+						bcmevent_get_name(event.event_type)));
+					wcp->rc_event[wcp->rc_event_idx] = event.event_type;
+					wcp->rc_event_idx++;
+#else
+					wcp->rc_event[event.event_type]++;
+#endif /* CUSTOM_WAKE_REASON_STATS */
+					wcp->rcwake++;
+					pkt_wake = 0;
+				}
+#endif /* DHD_WAKE_EVENT_STATUS */
+			}
+#endif /* DHD_WAKE_STATUS */
+
+			/* drop events if wl_host_event returns positive */
+			if (0 < ret_event) {
+				DHD_ERROR(("%s: Free event packet, event=%d\n",
+				           __func__, event.event_type));
+				PKTFREE_CTRLBUF(dhdp->osh, pktbuf, FALSE);
+				continue;
+			}
+
+			/*
+			 * For the event packets, there is a possibility
+			 * of ifidx getting modifed.Thus update the ifp
+			 * once again.
+			 */
+			ASSERT(ifidx < DHD_MAX_IFS);
+			ifp = dhd->iflist[ifidx];
+#ifndef PROP_TXSTATUS_VSDB
+			if (!(ifp && ifp->net && (ifp->net->reg_state == NETREG_REGISTERED)))
+#else
+			if (!(ifp && ifp->net && (ifp->net->reg_state == NETREG_REGISTERED) &&
+				dhd->pub.up))
+#endif /* PROP_TXSTATUS_VSDB */
+			{
+				DHD_ERROR(("%s: net device is NOT registered. drop event packet\n",
+				__FUNCTION__));
+				PKTFREE_CTRLBUF(dhdp->osh, pktbuf, FALSE);
+				continue;
+			}
+
+			/* always send up WLC_E_ESCAN_RESULT for WL utility */
+			if ((dhdp->wl_event_enabled) || (WLC_E_ESCAN_RESULT == event_type) ||
+#ifdef SENDPROB
+				(dhdp->recv_probereq && (event.event_type == WLC_E_PROBREQ_MSG)) ||
+#endif
+				/* Also send nan and ranging events for the same */
+				(WLC_E_RANGING_EVENT == event_type) ||
+				(WLC_E_RANGING_RESULTS == event_type) ||
+				(WLC_E_NAN_NON_CRITICAL == event_type) ||
+				(WLC_E_NAN_CRITICAL == event_type) ||
+				0) {
+#ifdef DHD_USE_STATIC_CTRLBUF
+				/* If event bufs are allocated via static buf pool
+				 * and wl events are enabled, make a copy, free the
+				 * local one and send the copy up.
+				 */
+				struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
+				/* Copy event and send it up */
+				PKTFREE_STATIC(dhdp->osh, pktbuf, FALSE);
+				if (nskb) {
+					skb = nskb;
+				} else {
+					DHD_ERROR(("skb clone failed. dropping event.\n"));
+					continue;
+				}
+#endif /* DHD_USE_STATIC_CTRLBUF */
+			} else {
+				/* If event enabled not explictly set, drop events */
+				PKTFREE_CTRLBUF(dhdp->osh, pktbuf, FALSE);
+				continue;
+			}
+		} else {
+#if defined(OEM_ANDROID)
+			tout_rx = DHD_PACKET_TIMEOUT_MS;
+
+			/* Override rx wakelock timeout to give hostapd enough time
+			 * to process retry or error handling for handshake
+			 */
+			if (IS_AP_IFACE(ndev_to_wdev(ifp->net)) &&
+				ntoh16(skb->protocol) == ETHER_TYPE_802_1X) {
+				if (dhd_is_4way_msg(dump_data) == EAPOL_4WAY_M2) {
+					tout_rx = DHD_HANDSHAKE_TIMEOUT_MS;
+				}
+			}
+#endif /* OEM_ANDROID */
+
+#ifdef PROP_TXSTATUS
+			dhd_wlfc_save_rxpath_ac_time(dhdp, (uint8)PKTPRIO(skb));
+#endif /* PROP_TXSTATUS */
+
+#ifdef DHD_WAKE_STATUS
+			if (unlikely(pkt_wake)) {
+				wcp->rxwake++;
+#ifdef DHD_WAKE_RX_STATUS
+
+				if (ntoh16(skb->protocol) == ETHER_TYPE_ARP) /* ARP */
+					wcp->rx_arp++;
+				if (ntoh16(skb->protocol) == ETHER_TYPE_IP) {
+					struct iphdr *ipheader = NULL;
+					ipheader = (struct iphdr*)(skb->data);
+					if (ipheader && ipheader->protocol == IPPROTO_ICMP) {
+						wcp->rx_icmp++;
+					}
+				}
+				if (dump_data[0] == 0xFF) { /* Broadcast */
+					wcp->rx_bcast++;
+				} else if (dump_data[0] & 0x01) { /* Multicast */
+					wcp->rx_mcast++;
+					if (ntoh16(skb->protocol) == ETHER_TYPE_IPV6) {
+					    wcp->rx_multi_ipv6++;
+					    if ((skb->len > ETHER_ICMP6_HEADER) &&
+					        (dump_data[ETHER_ICMP6_HEADER] == IPPROTO_ICMPV6)) {
+					        wcp->rx_icmpv6++;
+					        if (skb->len > ETHER_ICMPV6_TYPE) {
+					            switch (dump_data[ETHER_ICMPV6_TYPE]) {
+					            case NDISC_ROUTER_ADVERTISEMENT:
+					                wcp->rx_icmpv6_ra++;
+					                break;
+					            case NDISC_NEIGHBOUR_ADVERTISEMENT:
+					                wcp->rx_icmpv6_na++;
+					                break;
+					            case NDISC_NEIGHBOUR_SOLICITATION:
+					                wcp->rx_icmpv6_ns++;
+					                break;
+					            }
+					        }
+					    }
+					} else if (dump_data[2] == 0x5E) {
+						wcp->rx_multi_ipv4++;
+					} else {
+						wcp->rx_multi_other++;
+					}
+				} else { /* Unicast */
+					wcp->rx_ucast++;
+				}
+#undef ETHER_ICMP6_HEADER
+#undef ETHER_IPV6_SADDR
+#undef ETHER_IPV6_DAADR
+#undef ETHER_ICMPV6_TYPE
+#ifdef DHD_WAKE_STATUS_PRINT
+				dhd_dump_wake_status(dhdp, wcp, (struct ether_header *)eth);
+#endif /* DHD_WAKE_STATUS_PRINT */
+#endif /* DHD_WAKE_RX_STATUS */
+				pkt_wake = 0;
+			}
+#endif /* DHD_WAKE_STATUS */
+		}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0)
+		ifp->net->last_rx = jiffies;
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) */
+
+		if (ntoh16(skb->protocol) != ETHER_TYPE_BRCM) {
+			dhdp->dstats.rx_bytes += skb->len;
+			dhdp->rx_bytes += skb->len;
+			dhdp->rx_packets++; /* Local count */
+			ifp->stats.rx_bytes += skb->len;
+			ifp->stats.rx_packets++;
+		}
+
+		/* XXX WL here makes sure data is 4-byte aligned? */
+		if (in_interrupt()) {
+			bcm_object_trace_opr(skb, BCM_OBJDBG_REMOVE,
+				__FUNCTION__, __LINE__);
+#if defined(DHD_LB_RXP)
+#ifdef ENABLE_DHD_GRO
+			/* The pktlog module clones a skb using skb_clone and
+			 * stores the skb point to the ring buffer of the pktlog module.
+			 * Once the buffer is full,
+			 * the PKTFREE is called for removing the oldest skb.
+			 * The kernel panic occurred when the pktlog module free
+			 * the rx frame handled by napi_gro_receive().
+			 * It is a fix code that DHD don't use napi_gro_receive() for
+			 * the packet used in pktlog module.
+			 */
+			if (dhd_gro_enable && !skb_cloned(skb) &&
+				ntoh16(skb->protocol) != ETHER_TYPE_BRCM) {
+				napi_gro_receive(&dhd->rx_napi_struct, skb);
+			} else {
+#if defined(WL_MONITOR) && defined(BCMSDIO)
+				if (dhd_monitor_enabled(dhdp, ifidx))
+					dhd_rx_mon_pkt_sdio(dhdp, skb, ifidx);
+				else
+#endif /* WL_MONITOR && BCMSDIO */
+				netif_receive_skb(skb);
+			}
+#else
+#if defined(WL_MONITOR) && defined(BCMSDIO)
+			if (dhd_monitor_enabled(dhdp, ifidx))
+				dhd_rx_mon_pkt_sdio(dhdp, skb, ifidx);
+			else
+#endif /* WL_MONITOR && BCMSDIO */
+			netif_receive_skb(skb);
+#endif /* ENABLE_DHD_GRO */
+#else /* !defined(DHD_LB_RXP) */
+#if defined(WL_MONITOR) && defined(BCMDBUS)
+			if (dhd_monitor_enabled(dhdp, ifidx))
+				dhd_rx_mon_pkt_sdio(dhdp, skb, ifidx);
+			else
+#endif /* WL_MONITOR && BCMDBUS */
+			netif_rx(skb);
+#endif /* !defined(DHD_LB_RXP) */
+		} else {
+			if (dhd->rxthread_enabled) {
+				if (!skbhead)
+					skbhead = skb;
+				else
+					PKTSETNEXT(dhdp->osh, skbprev, skb);
+				skbprev = skb;
+			} else {
+
+				/* If the receive is not processed inside an ISR,
+				 * the softirqd must be woken explicitly to service
+				 * the NET_RX_SOFTIRQ.	In 2.6 kernels, this is handled
+				 * by netif_rx_ni(), but in earlier kernels, we need
+				 * to do it manually.
+				 */
+				bcm_object_trace_opr(skb, BCM_OBJDBG_REMOVE,
+					__FUNCTION__, __LINE__);
+
+#if defined(BCMPCIE) && defined(DHDTCPACK_SUPPRESS)
+				dhd_tcpack_suppress_set(&dhd->pub, TCPACK_SUP_OFF);
+#endif /* BCMPCIE && DHDTCPACK_SUPPRESS */
+#if defined(DHD_LB_RXP)
+#ifdef ENABLE_DHD_GRO
+				if (dhd_gro_enable && !skb_cloned(skb) &&
+					ntoh16(skb->protocol) != ETHER_TYPE_BRCM) {
+					napi_gro_receive(&dhd->rx_napi_struct, skb);
+				} else {
+					netif_receive_skb(skb);
+				}
+#else
+				netif_receive_skb(skb);
+#endif /* ENABLE_DHD_GRO */
+#else /* !defined(DHD_LB_RXP) */
+				dhd_netif_rx_ni(skb);
+#endif /* !defined(DHD_LB_RXP) */
+			}
+		}
+	}
+
+	if (dhd->rxthread_enabled && skbhead)
+		dhd_sched_rxf(dhdp, skbhead);
+
+#if defined(OEM_ANDROID)
+	DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(dhdp, tout_rx);
+	DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhdp, tout_ctrl);
+
+	/* To immediately notify the host that timeout is enabled */
+	DHD_OS_WAKE_LOCK_TIMEOUT(dhdp);
+#endif /* OEM_ANDROID */
+}
+
+int
+dhd_rxf_thread(void *data)
+{
+	tsk_ctl_t *tsk = (tsk_ctl_t *)data;
+	dhd_info_t *dhd = (dhd_info_t *)tsk->parent;
+#if defined(WAIT_DEQUEUE)
+#define RXF_WATCHDOG_TIME 250 /* BARK_TIME(1000) /  */
+	ulong watchdogTime = OSL_SYSUPTIME(); /* msec */
+#endif
+	dhd_pub_t *pub = &dhd->pub;
+
+	/* This thread doesn't need any user-level access,
+	 * so get rid of all our resources
+	 */
+	if (dhd_rxf_prio > 0)
+	{
+		struct sched_param param;
+		param.sched_priority = (dhd_rxf_prio < MAX_RT_PRIO)?dhd_rxf_prio:(MAX_RT_PRIO-1);
+		setScheduler(current, SCHED_FIFO, &param);
+	}
+
+#ifdef CUSTOM_RXF_CPUCORE
+	set_cpus_allowed_ptr(current, cpumask_of(CUSTOM_RXF_CPUCORE));
+#endif
+
+#ifdef CUSTOM_SET_CPUCORE
+	dhd->pub.current_rxf = current;
+#endif /* CUSTOM_SET_CPUCORE */
+	/* Run until signal received */
+	while (1) {
+		if (dhd->pub.conf->rxf_cpucore >= 0) {
+			printf("%s: set rxf_cpucore %d\n", __FUNCTION__, dhd->pub.conf->rxf_cpucore);
+			set_cpus_allowed_ptr(current, cpumask_of(dhd->pub.conf->rxf_cpucore));
+			dhd->pub.conf->rxf_cpucore = -1;
+		}
+		if (down_interruptible(&tsk->sema) == 0) {
+			void *skb;
+#ifdef ENABLE_ADAPTIVE_SCHED
+			dhd_sched_policy(dhd_rxf_prio);
+#endif /* ENABLE_ADAPTIVE_SCHED */
+
+			SMP_RD_BARRIER_DEPENDS();
+
+			if (tsk->terminated) {
+				DHD_OS_WAKE_UNLOCK(pub);
+				break;
+			}
+			skb = dhd_rxf_dequeue(pub);
+
+			if (skb == NULL) {
+				continue;
+			}
+			while (skb) {
+				void *skbnext = PKTNEXT(pub->osh, skb);
+				PKTSETNEXT(pub->osh, skb, NULL);
+				bcm_object_trace_opr(skb, BCM_OBJDBG_REMOVE,
+					__FUNCTION__, __LINE__);
+#if defined(WL_MONITOR) && defined(BCMSDIO)
+				if (dhd_monitor_enabled(pub, 0))
+					dhd_rx_mon_pkt_sdio(pub, skb, 0);
+				else
+#endif /* WL_MONITOR && BCMSDIO */
+				dhd_netif_rx_ni(skb);
+				skb = skbnext;
+			}
+#if defined(WAIT_DEQUEUE)
+			if (OSL_SYSUPTIME() - watchdogTime > RXF_WATCHDOG_TIME) {
+				OSL_SLEEP(1);
+				watchdogTime = OSL_SYSUPTIME();
+			}
+#endif
+
+			DHD_OS_WAKE_UNLOCK(pub);
+		} else {
+			break;
+		}
+	}
+	complete_and_exit(&tsk->completed, 0);
+}
+
+void
+dhd_sched_rxf(dhd_pub_t *dhdp, void *skb)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+#ifdef RXF_DEQUEUE_ON_BUSY
+	int ret = BCME_OK;
+	int retry = 2;
+#endif /* RXF_DEQUEUE_ON_BUSY */
+
+	DHD_OS_WAKE_LOCK(dhdp);
+
+	DHD_TRACE(("dhd_sched_rxf: Enter\n"));
+#ifdef RXF_DEQUEUE_ON_BUSY
+	do {
+		ret = dhd_rxf_enqueue(dhdp, skb);
+		if (ret == BCME_OK || ret == BCME_ERROR)
+			break;
+		else
+			OSL_SLEEP(50); /* waiting for dequeueing */
+	} while (retry-- > 0);
+
+	if (retry <= 0 && ret == BCME_BUSY) {
+		void *skbp = skb;
+
+		while (skbp) {
+			void *skbnext = PKTNEXT(dhdp->osh, skbp);
+			PKTSETNEXT(dhdp->osh, skbp, NULL);
+			bcm_object_trace_opr(skb, BCM_OBJDBG_REMOVE,
+				__FUNCTION__, __LINE__);
+			dhd_netif_rx_ni(skbp);
+			skbp = skbnext;
+		}
+		DHD_ERROR(("send skb to kernel backlog without rxf_thread\n"));
+	} else {
+		if (dhd->thr_rxf_ctl.thr_pid >= 0) {
+			up(&dhd->thr_rxf_ctl.sema);
+		}
+	}
+#else /* RXF_DEQUEUE_ON_BUSY */
+	do {
+		if (dhd_rxf_enqueue(dhdp, skb) == BCME_OK)
+			break;
+	} while (1);
+	if (dhd->thr_rxf_ctl.thr_pid >= 0) {
+		up(&dhd->thr_rxf_ctl.sema);
+	} else {
+		DHD_OS_WAKE_UNLOCK(dhdp);
+	}
+	return;
+#endif /* RXF_DEQUEUE_ON_BUSY */
+}
+
+#ifdef WL_MONITOR
+#if defined(BCMSDIO) || defined(BCMDBUS)
+void
+dhd_rx_mon_pkt_sdio(dhd_pub_t *dhdp, void *pkt, int ifidx)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+
+	if (!dhd->monitor_skb) {
+		if ((dhd->monitor_skb = PKTTONATIVE(dhdp->osh, pkt)) == NULL)
+			return;
+	}
+
+	if (dhd->monitor_type && dhd->monitor_dev)
+		dhd->monitor_skb->dev = dhd->monitor_dev;
+	else {
+		PKTFREE(dhdp->osh, pkt, FALSE);
+		dhd->monitor_skb = NULL;
+		return;
+	}
+
+	dhd->monitor_skb->protocol =
+		eth_type_trans(dhd->monitor_skb, dhd->monitor_skb->dev);
+	dhd->monitor_len = 0;
+
+	netif_rx_ni(dhd->monitor_skb);
+
+	dhd->monitor_skb = NULL;
+}
+#elif defined(BCMPCIE)
+void
+dhd_rx_mon_pkt(dhd_pub_t *dhdp, host_rxbuf_cmpl_t* msg, void *pkt, int ifidx)
+{
+	dhd_info_t *dhd = (dhd_info_t *)dhdp->info;
+#ifdef HOST_RADIOTAP_CONV
+	if (dhd->host_radiotap_conv) {
+		uint16 len = 0, offset = 0;
+		monitor_pkt_info_t pkt_info;
+
+		memcpy(&pkt_info.marker, &msg->marker, sizeof(msg->marker));
+		memcpy(&pkt_info.ts, &msg->ts, sizeof(monitor_pkt_ts_t));
+
+		if (!dhd->monitor_skb) {
+			if ((dhd->monitor_skb = dev_alloc_skb(MAX_MON_PKT_SIZE)) == NULL)
+				return;
+		}
+
+		len = bcmwifi_monitor(dhd->monitor_info, &pkt_info, PKTDATA(dhdp->osh, pkt),
+			PKTLEN(dhdp->osh, pkt), PKTDATA(dhdp->osh, dhd->monitor_skb), &offset);
+
+		if (dhd->monitor_type && dhd->monitor_dev)
+			dhd->monitor_skb->dev = dhd->monitor_dev;
+		else {
+			PKTFREE(dhdp->osh, pkt, FALSE);
+			dev_kfree_skb(dhd->monitor_skb);
+			return;
+		}
+
+		PKTFREE(dhdp->osh, pkt, FALSE);
+
+		if (!len) {
+			return;
+		}
+
+		skb_put(dhd->monitor_skb, len);
+		skb_pull(dhd->monitor_skb, offset);
+
+		dhd->monitor_skb->protocol = eth_type_trans(dhd->monitor_skb,
+			dhd->monitor_skb->dev);
+	}
+	else
+#endif /* HOST_RADIOTAP_CONV */
+	{
+		uint8 amsdu_flag = (msg->flags & BCMPCIE_PKT_FLAGS_MONITOR_MASK) >>
+			BCMPCIE_PKT_FLAGS_MONITOR_SHIFT;
+		switch (amsdu_flag) {
+			case BCMPCIE_PKT_FLAGS_MONITOR_NO_AMSDU:
+			default:
+				if (!dhd->monitor_skb) {
+					if ((dhd->monitor_skb = PKTTONATIVE(dhdp->osh, pkt))
+						== NULL)
+						return;
+				}
+				if (dhd->monitor_type && dhd->monitor_dev)
+					dhd->monitor_skb->dev = dhd->monitor_dev;
+				else {
+					PKTFREE(dhdp->osh, pkt, FALSE);
+					dhd->monitor_skb = NULL;
+					return;
+				}
+				dhd->monitor_skb->protocol =
+					eth_type_trans(dhd->monitor_skb, dhd->monitor_skb->dev);
+				dhd->monitor_len = 0;
+				break;
+
+			case BCMPCIE_PKT_FLAGS_MONITOR_FIRST_PKT:
+				if (!dhd->monitor_skb) {
+					if ((dhd->monitor_skb = dev_alloc_skb(MAX_MON_PKT_SIZE))
+						== NULL)
+						return;
+					dhd->monitor_len = 0;
+				}
+				if (dhd->monitor_type && dhd->monitor_dev)
+					dhd->monitor_skb->dev = dhd->monitor_dev;
+				else {
+					PKTFREE(dhdp->osh, pkt, FALSE);
+					dev_kfree_skb(dhd->monitor_skb);
+					return;
+				}
+				memcpy(PKTDATA(dhdp->osh, dhd->monitor_skb),
+				PKTDATA(dhdp->osh, pkt), PKTLEN(dhdp->osh, pkt));
+				dhd->monitor_len = PKTLEN(dhdp->osh, pkt);
+				PKTFREE(dhdp->osh, pkt, FALSE);
+				return;
+
+			case BCMPCIE_PKT_FLAGS_MONITOR_INTER_PKT:
+				memcpy(PKTDATA(dhdp->osh, dhd->monitor_skb) + dhd->monitor_len,
+				PKTDATA(dhdp->osh, pkt), PKTLEN(dhdp->osh, pkt));
+				dhd->monitor_len += PKTLEN(dhdp->osh, pkt);
+				PKTFREE(dhdp->osh, pkt, FALSE);
+				return;
+
+			case BCMPCIE_PKT_FLAGS_MONITOR_LAST_PKT:
+				memcpy(PKTDATA(dhdp->osh, dhd->monitor_skb) + dhd->monitor_len,
+				PKTDATA(dhdp->osh, pkt), PKTLEN(dhdp->osh, pkt));
+				dhd->monitor_len += PKTLEN(dhdp->osh, pkt);
+				PKTFREE(dhdp->osh, pkt, FALSE);
+				skb_put(dhd->monitor_skb, dhd->monitor_len);
+				dhd->monitor_skb->protocol =
+					eth_type_trans(dhd->monitor_skb, dhd->monitor_skb->dev);
+				dhd->monitor_len = 0;
+				break;
+		}
+	}
+
+	if (skb_headroom(dhd->monitor_skb) < ETHER_HDR_LEN) {
+		struct sk_buff *skb2;
+
+		DHD_INFO(("%s: insufficient headroom\n",
+		          dhd_ifname(&dhd->pub, ifidx)));
+
+		skb2 = skb_realloc_headroom(dhd->monitor_skb, ETHER_HDR_LEN);
+
+		dev_kfree_skb(dhd->monitor_skb);
+		if ((dhd->monitor_skb = skb2) == NULL) {
+			DHD_ERROR(("%s: skb_realloc_headroom failed\n",
+			           dhd_ifname(&dhd->pub, ifidx)));
+			return;
+		}
+	}
+	PKTPUSH(dhd->pub.osh, dhd->monitor_skb, ETHER_HDR_LEN);
+
+	/* XXX WL here makes sure data is 4-byte aligned? */
+	if (in_interrupt()) {
+		bcm_object_trace_opr(skb, BCM_OBJDBG_REMOVE,
+			__FUNCTION__, __LINE__);
+		netif_rx(dhd->monitor_skb);
+	} else {
+		/* If the receive is not processed inside an ISR,
+		 * the softirqd must be woken explicitly to service
+		 * the NET_RX_SOFTIRQ.	In 2.6 kernels, this is handled
+		 * by netif_rx_ni(), but in earlier kernels, we need
+		 * to do it manually.
+		 */
+		bcm_object_trace_opr(dhd->monitor_skb, BCM_OBJDBG_REMOVE,
+			__FUNCTION__, __LINE__);
+
+		dhd_netif_rx_ni(dhd->monitor_skb);
+	}
+
+	dhd->monitor_skb = NULL;
+
+#if defined(OEM_ANDROID)
+	DHD_OS_WAKE_LOCK_RX_TIMEOUT_ENABLE(dhdp, DHD_MONITOR_TIMEOUT_MS);
+	DHD_OS_WAKE_LOCK_TIMEOUT(dhdp);
+#endif /* OEM_ANDROID */
+}
+#endif /* PCIE_FULL_DONGLE */
+#endif /* WL_MONITOR */
+
+static int
+dhd_wl_host_event(dhd_info_t *dhd, int ifidx, void *pktdata, uint16 pktlen,
+	wl_event_msg_t *event, void **data)
+{
+	int bcmerror = 0;
+#ifdef WL_CFG80211
+	unsigned long flags = 0;
+#endif /* WL_CFG80211 */
+	ASSERT(dhd != NULL);
+
+#ifdef SHOW_LOGTRACE
+	bcmerror = wl_process_host_event(&dhd->pub, &ifidx, pktdata, pktlen, event, data,
+		&dhd->event_data);
+#else
+	bcmerror = wl_process_host_event(&dhd->pub, &ifidx, pktdata, pktlen, event, data,
+		NULL);
+#endif /* SHOW_LOGTRACE */
+	if (unlikely(bcmerror != BCME_OK)) {
+		return bcmerror;
+	}
+
+	if (ntoh32(event->event_type) == WLC_E_IF) {
+		/* WLC_E_IF event types are consumed by wl_process_host_event.
+		 * For ifadd/del ops, the netdev ptr may not be valid at this
+		 * point. so return before invoking cfg80211/wext handlers.
+		 */
+		return BCME_OK;
+	}
+
+#ifdef WL_EVENT
+	wl_ext_event_send(dhd->pub.event_params, event, *data);
+#endif
+
+#ifdef WL_CFG80211
+	if (dhd->iflist[ifidx]->net) {
+		DHD_UP_LOCK(&dhd->pub.up_lock, flags);
+		if (dhd->pub.up) {
+			wl_cfg80211_event(dhd->iflist[ifidx]->net, event, *data);
+		}
+		DHD_UP_UNLOCK(&dhd->pub.up_lock, flags);
+	}
+#endif /* defined(WL_CFG80211) */
+
+	return (bcmerror);
+}
+
+void
+dhd_os_sdlock_rxq(dhd_pub_t *pub)
+{
+}
+
+void
+dhd_os_sdunlock_rxq(dhd_pub_t *pub)
+{
+}
+
+static void
+dhd_os_rxflock(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd;
+
+	dhd = (dhd_info_t *)(pub->info);
+	spin_lock_bh(&dhd->rxf_lock);
+
+}
+
+static void
+dhd_os_rxfunlock(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd;
+
+	dhd = (dhd_info_t *)(pub->info);
+	spin_unlock_bh(&dhd->rxf_lock);
+}
+
+#ifdef PKT_FILTER_SUPPORT
+int net_os_rxfilter_add_remove(struct net_device *dev, int add_remove, int num)
+{
+	int ret = 0;
+
+#ifndef GAN_LITE_NAT_KEEPALIVE_FILTER
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+
+	if (!dhd_master_mode)
+		add_remove = !add_remove;
+	DHD_INFO(("%s: add_remove = %d, num = %d\n", __FUNCTION__, add_remove, num));
+	if (!dhd || (num == DHD_UNICAST_FILTER_NUM)) {
+		return 0;
+	}
+
+#ifdef BLOCK_IPV6_PACKET
+	/* customer want to use NO IPV6 packets only */
+	if (num == DHD_MULTICAST6_FILTER_NUM) {
+		return 0;
+	}
+#endif /* BLOCK_IPV6_PACKET */
+
+	if (num >= dhd->pub.pktfilter_count) {
+		return -EINVAL;
+	}
+
+	ret = dhd_packet_filter_add_remove(&dhd->pub, add_remove, num);
+#endif /* !GAN_LITE_NAT_KEEPALIVE_FILTER */
+
+	return ret;
+}
+#endif /* PKT_FILTER_SUPPORT */
+
+int dhd_os_wake_lock_rx_timeout_enable(dhd_pub_t *pub, int val)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+	unsigned long flags;
+
+	if (dhd && (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT)) {
+		DHD_WAKE_SPIN_LOCK(&dhd->wakelock_spinlock, flags);
+		if (val > dhd->wakelock_rx_timeout_enable)
+			dhd->wakelock_rx_timeout_enable = val;
+		DHD_WAKE_SPIN_UNLOCK(&dhd->wakelock_spinlock, flags);
+	}
+	return 0;
+}
+
+int net_os_wake_lock_rx_timeout_enable(struct net_device *dev, int val)
+{
+	dhd_info_t *dhd = DHD_DEV_INFO(dev);
+	int ret = 0;
+
+	if (dhd)
+		ret = dhd_os_wake_lock_rx_timeout_enable(&dhd->pub, val);
+	return ret;
+}
+
+#ifdef DHD_PCIE_NATIVE_RUNTIMEPM
+void
+dhd_flush_rx_tx_wq(dhd_pub_t *dhdp)
+{
+	dhd_info_t * dhd;
+
+	if (dhdp) {
+		dhd = dhdp->info;
+		if (dhd) {
+			flush_workqueue(dhd->tx_wq);
+			flush_workqueue(dhd->rx_wq);
+		}
+	}
+
+	return;
+}
+#endif /* DHD_PCIE_NATIVE_RUNTIMEPM */
+
+#ifdef RX_PKT_POOL
+void *
+BCMFASTPATH(dhd_rxpool_pktget)(osl_t *osh, dhd_info_t *dhd, uint16 len)
+{
+	void *p = NULL;
+	pkt_pool_t *rx_pool = &dhd->rx_pkt_pool;
+
+	if (dhd->rx_pktpool_thread.thr_pid >= 0) {
+		if (rx_pool->rxbuf_sz == len) {
+			p = skb_dequeue(&rx_pool->skb_q);
+			/* kick rx buffer mgmt thread to alloc more rx
+			 * buffers into the pool
+			 */
+			binary_sema_up(&dhd->rx_pktpool_thread);
+		} else {
+			DHD_ERROR_RLMT(("%s: PKTGET_RX_POOL is called with length %u, "
+				"but pkt pool created with length : %u\n", __FUNCTION__,
+				len, rx_pool->rxbuf_sz));
+		}
+	} else {
+		DHD_ERROR_RLMT(("%s: rx_pktpool_thread(%ld) not inited\n", __FUNCTION__,
+			dhd->rx_pktpool_thread.thr_pid));
+	}
+
+	return p;
+}
+
+static int
+dhd_rx_pktpool_thread(void *data)
+{
+	tsk_ctl_t *tsk = (tsk_ctl_t *)data;
+	dhd_info_t *dhd = (dhd_info_t *)tsk->parent;
+	dhd_pub_t *dhdp = (dhd_pub_t *)&dhd->pub;
+	pkt_pool_t *rx_pool = &dhd->rx_pkt_pool;
+	void *p = NULL;
+	int qlen = 0;
+	int num_attempts = 0;
+
+	DHD_TRACE(("%s: STARTED...\n", __FUNCTION__));
+	while (1) {
+		if (!binary_sema_down(tsk)) {
+			SMP_RD_BARRIER_DEPENDS();
+			/* Check terminated before processing the items */
+			if (tsk->terminated) {
+				DHD_ERROR(("%s: task terminated\n", __FUNCTION__));
+				goto exit;
+			}
+			/* Allocate rx buffer only after dongle
+			 * handshake the actual rxbuf size.
+			 */
+			if (rx_pool->rxbuf_sz) {
+				qlen = skb_queue_len(&rx_pool->skb_q);
+				DHD_TRACE(("%s: before alloc - skb_q len=%u, max_size=%u "
+					"rxbuf_sz : %u\n", __FUNCTION__, qlen, rx_pool->max_size,
+					rx_pool->rxbuf_sz));
+				num_attempts = 0;
+				while (qlen < rx_pool->max_size) {
+					p = PKTGET(dhdp->osh, rx_pool->rxbuf_sz, FALSE);
+					if (!p) {
+						DHD_ERROR_RLMT(("%s: pktget fails, resched...\n",
+							__FUNCTION__));
+						/* retry after some time to fetch packets
+						 * if maximum attempts hit, stop
+						 */
+						num_attempts++;
+						if (num_attempts >= RX_PKTPOOL_FETCH_MAX_ATTEMPTS) {
+							DHD_ERROR_RLMT(("%s: max attempts to fetch"
+								" exceeded.\n", __FUNCTION__));
+							break;
+						}
+						OSL_SLEEP(RX_PKTPOOL_RESCHED_DELAY_MS);
+					} else {
+						skb_queue_tail(&rx_pool->skb_q, p);
+					}
+					qlen = skb_queue_len(&rx_pool->skb_q);
+				}
+				DHD_TRACE(("%s: after alloc - skb_q len=%u, max_size=%u \n",
+					__FUNCTION__, qlen, rx_pool->max_size));
+			}
+		} else {
+			DHD_ERROR_RLMT(("%s: unexpected break\n", __FUNCTION__));
+			break;
+		}
+	}
+exit:
+	DHD_TRACE(("%s: EXITED...\n", __FUNCTION__));
+	complete_and_exit(&tsk->completed, 0);
+}
+
+void
+dhd_rx_pktpool_create(dhd_info_t *dhd, uint16 rxbuf_sz)
+{
+	pkt_pool_t *rx_pool = &dhd->rx_pkt_pool;
+	rx_pool->rxbuf_sz = rxbuf_sz;
+	binary_sema_up(&dhd->rx_pktpool_thread);
+}
+
+void
+dhd_rx_pktpool_init(dhd_info_t *dhd)
+{
+	pkt_pool_t *rx_pool = &dhd->rx_pkt_pool;
+
+	skb_queue_head_init(&rx_pool->skb_q);
+	rx_pool->max_size = MAX_RX_PKT_POOL;
+	rx_pool->rxbuf_sz = 0;
+
+	PROC_START(dhd_rx_pktpool_thread, dhd, &dhd->rx_pktpool_thread, 0, "dhd_rx_pktpool_thread");
+}
+
+void
+dhd_rx_pktpool_deinit(dhd_info_t *dhd)
+{
+	pkt_pool_t *rx_pool = &dhd->rx_pkt_pool;
+	tsk_ctl_t *tsk = &dhd->rx_pktpool_thread;
+
+	if (tsk->parent && tsk->thr_pid >= 0) {
+		PROC_STOP_USING_BINARY_SEMA(tsk);
+	} else {
+		DHD_ERROR(("%s: rx_pktpool_thread(%ld) not inited\n",
+			__FUNCTION__, tsk->thr_pid));
+	}
+	/* skb list manipulation functions use internal
+	 * spin lock, so no need to take separate lock
+	 */
+	skb_queue_purge(&rx_pool->skb_q);
+	rx_pool->max_size = 0;
+	DHD_ERROR(("%s: de-alloc'd rx buffers in pool \n",
+		__FUNCTION__));
+}
+#endif /* RX_PKT_POOL */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux_sched.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux_sched.c
@@ -0,0 +1,79 @@
+/*
+ * Expose some of the kernel scheduler routines
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <typedefs.h>
+#include <linuxver.h>
+
+int setScheduler(struct task_struct *p, int policy, struct sched_param *param)
+{
+	int rc = 0;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0))
+	rc = sched_setscheduler(p, policy, param);
+#else
+	switch (policy) {
+		case SCHED_FIFO:
+			sched_set_fifo(p);
+			break;
+		case SCHED_RR:
+			sched_set_fifo_low(p);
+			break;
+		case SCHED_NORMAL:
+		default:
+			sched_set_normal(p, PRIO_TO_NICE(param->sched_priority));
+			break;
+	}
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(5, 9, 0)) */
+
+	return rc;
+}
+
+int get_scheduler_policy(struct task_struct *p)
+{
+	int rc = SCHED_NORMAL;
+	rc = p->policy;
+	return rc;
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux_sock_qos.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux_sock_qos.h
@@ -0,0 +1,95 @@
+/*
+ * Header file for DHD TPA (Traffic Pattern Analyzer)
+ *
+ * Provides type definitions and function prototypes to call into
+ * DHD's QOS on Socket Flow module.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ *
+ */
+
+#ifndef _DHD_LINUX_TPA_H_
+#define _DHD_LINUX_TPA_H_
+
+struct dhd_sock_flow_info;
+
+/* Feature Disabled dummy implementations */
+
+static inline int
+dhd_init_sock_flows_buf(dhd_info_t *dhd, uint watchdog_ms)
+{
+		BCM_REFERENCE(dhd);
+		return BCME_UNSUPPORTED;
+}
+
+static inline int
+dhd_deinit_sock_flows_buf(dhd_info_t *dhd)
+{
+		BCM_REFERENCE(dhd);
+		return BCME_UNSUPPORTED;
+}
+
+static inline void
+dhd_update_sock_flows(dhd_info_t *dhd, struct sk_buff *skb)
+{
+		BCM_REFERENCE(dhd);
+		BCM_REFERENCE(skb);
+		return;
+}
+
+static inline void
+dhd_analyze_sock_flows(dhd_info_t *dhd, uint32 watchdog_ms)
+{
+	BCM_REFERENCE(dhd);
+	BCM_REFERENCE(dhd_watchdog_ms);
+	return;
+}
+
+static inline void
+dhd_sock_qos_update_bus_flowid(dhd_info_t *dhd, void *pktbuf,
+	uint32 bus_flow_id)
+{
+	BCM_REFERENCE(dhd);
+	BCM_REFERENCE(pktbuf);
+	BCM_REFERENCE(bus_flow_id);
+}
+
+#endif /* _DHD_LINUX_TPA_H_ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux_tx.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux_tx.c
@@ -0,0 +1,1318 @@
+/*
+ * Broadcom Dongle Host Driver (DHD),
+ * Linux-specific network interface for transmit(tx) path
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+#ifdef SHOW_LOGTRACE
+#include <linux/syscalls.h>
+#include <event_log.h>
+#endif /* SHOW_LOGTRACE */
+
+#ifdef PCIE_FULL_DONGLE
+#include <bcmmsgbuf.h>
+#endif /* PCIE_FULL_DONGLE */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/etherdevice.h>
+#include <linux/random.h>
+#include <linux/spinlock.h>
+#include <linux/ethtool.h>
+#include <linux/fcntl.h>
+#include <linux/fs.h>
+#include <linux/ip.h>
+#include <linux/reboot.h>
+#include <linux/notifier.h>
+#include <linux/irq.h>
+#if defined(CONFIG_TIZEN)
+#include <linux/net_stat_tizen.h>
+#endif /* CONFIG_TIZEN */
+#include <net/addrconf.h>
+#ifdef ENABLE_ADAPTIVE_SCHED
+#include <linux/cpufreq.h>
+#endif /* ENABLE_ADAPTIVE_SCHED */
+#include <linux/rtc.h>
+#include <linux/namei.h>
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+#include <dhd_linux_priv.h>
+
+#include <epivers.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <bcmdevs.h>
+#include <bcmdevs_legacy.h>    /* need to still support chips no longer in trunk firmware */
+#include <bcmiov.h>
+#include <bcmstdlib_s.h>
+
+#include <ethernet.h>
+#include <bcmevent.h>
+#include <vlan.h>
+#include <802.3.h>
+
+#include <dhd_linux_wq.h>
+#include <dhd.h>
+#include <dhd_linux.h>
+#include <dhd_linux_pktdump.h>
+#ifdef DHD_WET
+#include <dhd_wet.h>
+#endif /* DHD_WET */
+#ifdef PCIE_FULL_DONGLE
+#include <dhd_flowring.h>
+#endif
+#include <dhd_bus.h>
+#include <dhd_proto.h>
+#include <dhd_dbg.h>
+#include <dhd_dbg_ring.h>
+#include <dhd_debug.h>
+#if defined(WL_CFG80211)
+#include <wl_cfg80211.h>
+#ifdef WL_BAM
+#include <wl_bam.h>
+#endif	/* WL_BAM */
+#endif	/* WL_CFG80211 */
+#ifdef PNO_SUPPORT
+#include <dhd_pno.h>
+#endif
+#ifdef RTT_SUPPORT
+#include <dhd_rtt.h>
+#endif
+
+#include <dhd_linux_sock_qos.h>
+
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+#endif
+
+#ifdef DHD_WMF
+#include <dhd_wmf_linux.h>
+#endif /* DHD_WMF */
+
+#ifdef DHD_L2_FILTER
+#include <bcmicmp.h>
+#include <bcm_l2_filter.h>
+#include <dhd_l2_filter.h>
+#endif /* DHD_L2_FILTER */
+
+#ifdef DHD_PSTA
+#include <dhd_psta.h>
+#endif /* DHD_PSTA */
+
+#ifdef AMPDU_VO_ENABLE
+/* XXX: Enabling VO AMPDU to reduce FER */
+#include <802.1d.h>
+#endif /* AMPDU_VO_ENABLE */
+
+#if defined(DHDTCPACK_SUPPRESS) || defined(DHDTCPSYNC_FLOOD_BLK)
+#include <dhd_ip.h>
+#endif /* DHDTCPACK_SUPPRESS || DHDTCPSYNC_FLOOD_BLK */
+#include <dhd_daemon.h>
+#ifdef DHD_PKT_LOGGING
+#include <dhd_pktlog.h>
+#endif /* DHD_PKT_LOGGING */
+#ifdef DHD_4WAYM4_FAIL_DISCONNECT
+#include <eapol.h>
+#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
+
+#ifdef ENABLE_DHD_GRO
+#include <net/sch_generic.h>
+#endif /* ENABLE_DHD_GRO */
+
+#ifdef FIX_CPU_MIN_CLOCK
+#include <linux/pm_qos.h>
+#endif /* FIX_CPU_MIN_CLOCK */
+
+#ifdef PROP_TXSTATUS
+#include <wlfc_proto.h>
+#include <dhd_wlfc.h>
+#endif
+
+#if defined(OEM_ANDROID)
+#include <wl_android.h>
+#endif
+#include <dhd_config.h>
+
+#define WME_PRIO2AC(prio)  wme_fifo2ac[prio2fifo[(prio)]]
+
+void
+dhd_tx_stop_queues(struct net_device *net)
+{
+#ifdef DHD_MQ
+	netif_tx_stop_all_queues(net);
+#else
+	netif_stop_queue(net);
+#endif
+}
+
+void
+dhd_tx_start_queues(struct net_device *net)
+{
+#ifdef DHD_MQ
+	netif_tx_wake_all_queues(net);
+#else
+	netif_wake_queue(net);
+#endif
+}
+
+int
+BCMFASTPATH(__dhd_sendpkt)(dhd_pub_t *dhdp, int ifidx, void *pktbuf)
+{
+	int ret = BCME_OK;
+	dhd_info_t *dhd = (dhd_info_t *)(dhdp->info);
+	struct ether_header *eh = NULL;
+	uint8 pkt_flow_prio;
+	dhd_if_t *ifp;
+	unsigned long flags;
+	uint datalen;
+
+	DHD_GENERAL_LOCK(dhdp, flags);
+	ifp = dhd_get_ifp(dhdp, ifidx);
+	if (!ifp || ifp->del_in_progress) {
+		DHD_ERROR(("%s: ifp:%p del_in_progress:%d\n",
+			__FUNCTION__, ifp, ifp ? ifp->del_in_progress : 0));
+		DHD_GENERAL_UNLOCK(dhdp, flags);
+		PKTCFREE(dhdp->osh, pktbuf, TRUE);
+		return -ENODEV;
+	}
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+
+	/* Reject if down */
+	if (!dhdp->up || (dhdp->busstate == DHD_BUS_DOWN)) {
+		/* free the packet here since the caller won't */
+		PKTCFREE(dhdp->osh, pktbuf, TRUE);
+		return -ENODEV;
+	}
+
+#ifdef PCIE_FULL_DONGLE
+	if (dhdp->busstate == DHD_BUS_SUSPEND) {
+		DHD_ERROR(("%s : pcie is still in suspend state!!\n", __FUNCTION__));
+		PKTCFREE(dhdp->osh, pktbuf, TRUE);
+		return NETDEV_TX_BUSY;
+	}
+#endif /* PCIE_FULL_DONGLE */
+
+	/* Reject if pktlen > MAX_MTU_SZ */
+	if (PKTLEN(dhdp->osh, pktbuf) > MAX_MTU_SZ) {
+		/* free the packet here since the caller won't */
+		dhdp->tx_big_packets++;
+		PKTCFREE(dhdp->osh, pktbuf, TRUE);
+		return BCME_ERROR;
+	}
+
+	datalen = PKTLEN(dhdp->osh, pktbuf);
+
+#ifdef DHD_L2_FILTER
+	/* if dhcp_unicast is enabled, we need to convert the */
+	/* broadcast DHCP ACK/REPLY packets to Unicast. */
+	if (ifp->dhcp_unicast) {
+	    uint8* mac_addr;
+	    uint8* ehptr = NULL;
+	    int ret;
+	    ret = bcm_l2_filter_get_mac_addr_dhcp_pkt(dhdp->osh, pktbuf, ifidx, &mac_addr);
+	    if (ret == BCME_OK) {
+		/*  if given mac address having valid entry in sta list
+		 *  copy the given mac address, and return with BCME_OK
+		*/
+		if (dhd_find_sta(dhdp, ifidx, mac_addr)) {
+		    ehptr = PKTDATA(dhdp->osh, pktbuf);
+		    bcopy(mac_addr, ehptr + ETHER_DEST_OFFSET, ETHER_ADDR_LEN);
+		}
+	    }
+	}
+
+	if (ifp->grat_arp && DHD_IF_ROLE_AP(dhdp, ifidx)) {
+	    if (bcm_l2_filter_gratuitous_arp(dhdp->osh, pktbuf) == BCME_OK) {
+			PKTCFREE(dhdp->osh, pktbuf, TRUE);
+			return BCME_ERROR;
+	    }
+	}
+
+	if (ifp->parp_enable && DHD_IF_ROLE_AP(dhdp, ifidx)) {
+		ret = dhd_l2_filter_pkt_handle(dhdp, ifidx, pktbuf, TRUE);
+
+		/* Drop the packets if l2 filter has processed it already
+		 * otherwise continue with the normal path
+		 */
+		if (ret == BCME_OK) {
+			PKTCFREE(dhdp->osh, pktbuf, TRUE);
+			return BCME_ERROR;
+		}
+	}
+#endif /* DHD_L2_FILTER */
+	/* Update multicast statistic */
+	if (PKTLEN(dhdp->osh, pktbuf) >= ETHER_HDR_LEN) {
+		uint8 *pktdata = (uint8 *)PKTDATA(dhdp->osh, pktbuf);
+		eh = (struct ether_header *)pktdata;
+
+		if (ETHER_ISMULTI(eh->ether_dhost))
+			dhdp->tx_multicast++;
+		if (ntoh16(eh->ether_type) == ETHER_TYPE_802_1X) {
+#ifdef DHD_LOSSLESS_ROAMING
+			uint8 prio = (uint8)PKTPRIO(pktbuf);
+
+			/* back up 802.1x's priority */
+			dhdp->prio_8021x = prio;
+#endif /* DHD_LOSSLESS_ROAMING */
+			DBG_EVENT_LOG(dhdp, WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED);
+			atomic_inc(&dhd->pend_8021x_cnt);
+#if defined(WL_CFG80211) && defined(WL_WPS_SYNC)
+			wl_handle_wps_states(dhd_idx2net(dhdp, ifidx),
+				pktdata, PKTLEN(dhdp->osh, pktbuf), TRUE);
+#endif /* WL_CFG80211 && WL_WPS_SYNC */
+#ifdef EAPOL_RESEND
+			wl_ext_backup_eapol_txpkt(dhdp, ifidx, pktbuf);
+#endif /* EAPOL_RESEND */
+		}
+		dhd_dump_pkt(dhdp, ifidx, pktdata,
+			(uint32)PKTLEN(dhdp->osh, pktbuf), TRUE, NULL, NULL);
+	} else {
+		PKTCFREE(dhdp->osh, pktbuf, TRUE);
+		return BCME_ERROR;
+	}
+
+#if (defined(BCM_ROUTER_DHD) && defined(QOS_MAP_SET))
+	if (ifp->qosmap_up_table_enable) {
+		pktsetprio_qms(pktbuf, ifp->qosmap_up_table, FALSE);
+	}
+	else
+#endif
+	{
+		/* Look into the packet and update the packet priority */
+#ifndef PKTPRIO_OVERRIDE
+		/* XXX RB:6270 Ignore skb->priority from TCP/IP stack */
+		if (PKTPRIO(pktbuf) == 0)
+#endif /* !PKTPRIO_OVERRIDE */
+		{
+#if (!defined(BCM_ROUTER_DHD) && (defined(QOS_MAP_SET) || \
+	defined(WL_CUSTOM_MAPPING_OF_DSCP)))
+			u8 *up_table = wl_get_up_table(dhdp, ifidx);
+			pktsetprio_qms(pktbuf, up_table, FALSE);
+			if (PKTPRIO(pktbuf) > MAXPRIO) {
+				DHD_ERROR_RLMT(("wrong user prio:%d from qosmap ifidx:%d\n",
+					PKTPRIO(pktbuf), ifidx));
+				if (up_table) {
+					prhex("up_table", up_table, UP_TABLE_MAX);
+				}
+			}
+#else
+			/* For LLR, pkt prio will be changed to 7(NC) here */
+			pktsetprio(pktbuf, FALSE);
+#endif /* QOS_MAP_SET || WL_CUSTOM_MAPPING_OF_DSCP */
+		}
+#ifndef PKTPRIO_OVERRIDE
+		else {
+			/* Some protocols like OZMO use priority values from 256..263.
+			 * these are magic values to indicate a specific 802.1d priority.
+			 * make sure that priority field is in range of 0..7
+			 */
+			PKTSETPRIO(pktbuf, PKTPRIO(pktbuf) & 0x7);
+		}
+#endif /* !PKTPRIO_OVERRIDE */
+	}
+
+#if defined(BCM_ROUTER_DHD)
+	traffic_mgmt_pkt_set_prio(dhdp, pktbuf);
+
+#endif /* BCM_ROUTER_DHD */
+
+	BCM_REFERENCE(pkt_flow_prio);
+	/* Intercept and create Socket level statistics */
+	/*
+	 * TODO: Some how moving this code block above the pktsetprio code
+	 * is resetting the priority back to 0, but this does not happen for
+	 * packets generated from iperf uisng -S option. Can't understand why.
+	 */
+	dhd_update_sock_flows(dhd, pktbuf);
+
+#ifdef SUPPORT_SET_TID
+	dhd_set_tid_based_on_uid(dhdp, pktbuf);
+#endif	/* SUPPORT_SET_TID */
+
+#ifdef PCIE_FULL_DONGLE
+	/*
+	 * Lkup the per interface hash table, for a matching flowring. If one is not
+	 * available, allocate a unique flowid and add a flowring entry.
+	 * The found or newly created flowid is placed into the pktbuf's tag.
+	 */
+
+#ifdef DHD_TX_PROFILE
+	if (dhdp->tx_profile_enab && dhdp->num_profiles > 0 &&
+		dhd_protocol_matches_profile(PKTDATA(dhdp->osh, pktbuf),
+		PKTLEN(dhdp->osh, pktbuf), dhdp->protocol_filters,
+		dhdp->host_sfhllc_supported)) {
+		/* we only have support for one tx_profile at the moment */
+
+		/* tagged packets must be put into TID 6 */
+		PKTSETPRIO(pktbuf, PRIO_8021D_VO);
+	}
+#endif /* defined(DHD_TX_PROFILE) */
+
+	if (PKTPRIO(pktbuf) > MAXPRIO) {
+		DHD_ERROR_RLMT(("Wrong user prio:%d ifidx:%d\n", PKTPRIO(pktbuf), ifidx));
+		/* non-assert build, print ratelimit error, free packet and exit */
+		ASSERT(0);
+		PKTCFREE(dhd->pub.osh, pktbuf, TRUE);
+		return BCME_ERROR;
+	}
+
+	pkt_flow_prio = dhdp->flow_prio_map[(PKTPRIO(pktbuf))];
+
+	ret = dhd_flowid_update(dhdp, ifidx, pkt_flow_prio, pktbuf);
+	if (ret != BCME_OK) {
+		PKTCFREE(dhd->pub.osh, pktbuf, TRUE);
+		return ret;
+	}
+#endif /* PCIE_FULL_DONGLE */
+	/* terence 20150901: Micky add to ajust the 802.1X priority */
+	/* Set the 802.1X packet with the highest priority 7 */
+	if (dhdp->conf->pktprio8021x >= 0)
+		pktset8021xprio(pktbuf, dhdp->conf->pktprio8021x);
+
+#ifdef PROP_TXSTATUS
+	if (dhd_wlfc_is_supported(dhdp)) {
+		DHD_GENERAL_LOCK(dhdp, flags);
+		if (ifp->del_in_progress) {
+			DHD_GENERAL_UNLOCK(dhdp, flags);
+			PKTCFREE(dhdp->osh, pktbuf, TRUE);
+			return -ENODEV;
+		}
+		DHD_GENERAL_UNLOCK(dhdp, flags);
+
+		/* store the interface ID */
+		DHD_PKTTAG_SETIF(PKTTAG(pktbuf), ifidx);
+
+		/* store destination MAC in the tag as well */
+		DHD_PKTTAG_SETDSTN(PKTTAG(pktbuf), eh->ether_dhost);
+
+		/* decide which FIFO this packet belongs to */
+		if (ETHER_ISMULTI(eh->ether_dhost))
+			/* one additional queue index (highest AC + 1) is used for bc/mc queue */
+			DHD_PKTTAG_SETFIFO(PKTTAG(pktbuf), AC_COUNT);
+		else
+			DHD_PKTTAG_SETFIFO(PKTTAG(pktbuf), WME_PRIO2AC(PKTPRIO(pktbuf)));
+	} else
+#endif /* PROP_TXSTATUS */
+	{
+		/* If the protocol uses a data header, apply it */
+		dhd_prot_hdrpush(dhdp, ifidx, pktbuf);
+	}
+
+	/* Use bus module to send data frame */
+#ifdef PROP_TXSTATUS
+	{
+		if (dhd_wlfc_commit_packets(dhdp, (f_commitpkt_t)dhd_bus_txdata,
+			dhdp->bus, pktbuf, TRUE) == WLFC_UNSUPPORTED) {
+			/* non-proptxstatus way */
+#ifdef BCMPCIE
+			ret = dhd_bus_txdata(dhdp->bus, pktbuf, (uint8)ifidx);
+#else
+			ret = dhd_bus_txdata(dhdp->bus, pktbuf);
+#endif /* BCMPCIE */
+		}
+	}
+#else
+#ifdef BCMPCIE
+	ret = dhd_bus_txdata(dhdp->bus, pktbuf, (uint8)ifidx);
+#else
+	ret = dhd_bus_txdata(dhdp->bus, pktbuf);
+#endif /* BCMPCIE */
+#endif /* PROP_TXSTATUS */
+
+	/* Update the packet counters here, as it is called for LB Tx and non-LB Tx too */
+	if (ret) {
+#ifdef BCMDBUS
+		PKTCFREE(dhdp->osh, pktbuf, TRUE);
+#endif /* BCMDBUS */
+		ifp->stats.tx_dropped++;
+		dhdp->tx_dropped++;
+	} else {
+#ifdef PROP_TXSTATUS
+		/* tx_packets counter can counted only when wlfc is disabled */
+		if (!dhd_wlfc_is_supported(dhdp))
+#endif
+		{
+			dhdp->tx_packets++;
+			dhdp->tx_bytes += datalen;
+			ifp->stats.tx_packets++;
+			ifp->stats.tx_bytes += datalen;
+		}
+		dhdp->actual_tx_pkts++;
+	}
+
+	return ret;
+}
+
+int
+BCMFASTPATH(dhd_sendpkt)(dhd_pub_t *dhdp, int ifidx, void *pktbuf)
+{
+	int ret = 0;
+	unsigned long flags;
+	dhd_if_t *ifp;
+
+	DHD_GENERAL_LOCK(dhdp, flags);
+	ifp = dhd_get_ifp(dhdp, ifidx);
+	if (!ifp || ifp->del_in_progress) {
+		DHD_ERROR(("%s: ifp:%p del_in_progress:%d\n",
+			__FUNCTION__, ifp, ifp ? ifp->del_in_progress : 0));
+		DHD_GENERAL_UNLOCK(dhdp, flags);
+		PKTCFREE(dhdp->osh, pktbuf, TRUE);
+		return -ENODEV;
+	}
+	if (DHD_BUS_CHECK_DOWN_OR_DOWN_IN_PROGRESS(dhdp)) {
+		DHD_ERROR(("%s: returning as busstate=%d\n",
+			__FUNCTION__, dhdp->busstate));
+		DHD_GENERAL_UNLOCK(dhdp, flags);
+		PKTCFREE(dhdp->osh, pktbuf, TRUE);
+		return -ENODEV;
+	}
+	DHD_IF_SET_TX_ACTIVE(ifp, DHD_TX_SEND_PKT);
+	DHD_BUS_BUSY_SET_IN_SEND_PKT(dhdp);
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+
+	DHD_GENERAL_LOCK(dhdp, flags);
+	if (DHD_BUS_CHECK_SUSPEND_OR_SUSPEND_IN_PROGRESS(dhdp)) {
+		DHD_ERROR(("%s: bus is in suspend(%d) or suspending(0x%x) state!!\n",
+			__FUNCTION__, dhdp->busstate, dhdp->dhd_bus_busy_state));
+		DHD_BUS_BUSY_CLEAR_IN_SEND_PKT(dhdp);
+		DHD_IF_CLR_TX_ACTIVE(ifp, DHD_TX_SEND_PKT);
+		dhd_os_tx_completion_wake(dhdp);
+		dhd_os_busbusy_wake(dhdp);
+		DHD_GENERAL_UNLOCK(dhdp, flags);
+		PKTCFREE(dhdp->osh, pktbuf, TRUE);
+		return -ENODEV;
+	}
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+
+	ret = __dhd_sendpkt(dhdp, ifidx, pktbuf);
+
+	DHD_GENERAL_LOCK(dhdp, flags);
+	DHD_BUS_BUSY_CLEAR_IN_SEND_PKT(dhdp);
+	DHD_IF_CLR_TX_ACTIVE(ifp, DHD_TX_SEND_PKT);
+	dhd_os_tx_completion_wake(dhdp);
+	dhd_os_busbusy_wake(dhdp);
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+	return ret;
+}
+
+#ifdef DHD_MQ
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+static uint16
+BCMFASTPATH(dhd_select_queue)(struct net_device *net, struct sk_buff *skb,
+       void *accel_priv, select_queue_fallback_t fallback)
+#else
+static uint16
+BCMFASTPATH(dhd_select_queue)(struct net_device *net, struct sk_buff *skb)
+#endif /* LINUX_VERSION_CODE */
+{
+	dhd_info_t *dhd_info = DHD_DEV_INFO(net);
+	dhd_pub_t *dhdp = &dhd_info->pub;
+	uint16 prio = 0;
+
+	BCM_REFERENCE(dhd_info);
+	BCM_REFERENCE(dhdp);
+	BCM_REFERENCE(prio);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+	if (mq_select_disable) {
+		/* if driver side queue selection is disabled via sysfs, call the kernel
+		* supplied fallback function to select the queue, which is usually
+		* '__netdev_pick_tx()' in net/core/dev.c
+		*/
+		return fallback(net, skb);
+	}
+#endif /* LINUX_VERSION */
+
+	prio = dhdp->flow_prio_map[skb->priority];
+	if (prio < AC_COUNT)
+		return prio;
+	else
+		return AC_BK;
+}
+#endif /* DHD_MQ */
+
+netdev_tx_t
+BCMFASTPATH(dhd_start_xmit)(struct sk_buff *skb, struct net_device *net)
+{
+	int ret;
+	void *pktbuf;
+	dhd_info_t *dhd = DHD_DEV_INFO(net);
+	dhd_if_t *ifp = NULL;
+	int ifidx;
+	unsigned long flags;
+#if !defined(BCM_ROUTER_DHD)
+	uint8 htsfdlystat_sz = 0;
+#endif /* ! BCM_ROUTER_DHD */
+#ifdef DHD_WMF
+	struct ether_header *eh;
+	uint8 *iph;
+#endif /* DHD_WMF */
+#if defined(DHD_MQ) && defined(DHD_MQ_STATS)
+	int qidx = 0;
+	int cpuid = 0;
+	int prio = 0;
+#endif /* DHD_MQ && DHD_MQ_STATS */
+#if defined(WL_CFG80211)
+	struct bcm_cfg80211 *cfg = wl_get_cfg(net);
+#endif /* defined(WL_CFG80211) */
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+#if defined(WL_CFG80211)
+	UNUSED_PARAMETER(cfg);
+#endif /* defined(WL_CFG80211) */
+
+#if defined(DHD_MQ) && defined(DHD_MQ_STATS)
+	qidx = skb_get_queue_mapping(skb);
+	/* if in a non pre-emptable context, smp_processor_id can be used
+	* else get_cpu and put_cpu should be used
+	*/
+	if (!CAN_SLEEP()) {
+		cpuid = smp_processor_id();
+	}
+	else {
+		cpuid = get_cpu();
+		put_cpu();
+	}
+	prio = dhd->pub.flow_prio_map[skb->priority];
+	DHD_TRACE(("%s: Q idx = %d, CPU = %d, prio = %d \n", __FUNCTION__,
+		qidx, cpuid, prio));
+	dhd->pktcnt_qac_histo[qidx][prio]++;
+	dhd->pktcnt_per_ac[prio]++;
+	dhd->cpu_qstats[qidx][cpuid]++;
+#endif /* DHD_MQ && DHD_MQ_STATS */
+
+	if (dhd_query_bus_erros(&dhd->pub)) {
+		return -ENODEV;
+	}
+
+	DHD_GENERAL_LOCK(&dhd->pub, flags);
+	DHD_BUS_BUSY_SET_IN_TX(&dhd->pub);
+	DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+
+	DHD_GENERAL_LOCK(&dhd->pub, flags);
+#ifdef BCMPCIE
+	if (DHD_BUS_CHECK_SUSPEND_OR_SUSPEND_IN_PROGRESS(&dhd->pub)) {
+		DHD_ERROR_RLMT(("%s: bus is in suspend(%d) or suspending(0x%x) state!!\n",
+			__FUNCTION__, dhd->pub.busstate, dhd->pub.dhd_bus_busy_state));
+		DHD_BUS_BUSY_CLEAR_IN_TX(&dhd->pub);
+#ifdef PCIE_FULL_DONGLE
+		/* Stop tx queues if suspend is in progress or suspended */
+		if (DHD_BUS_CHECK_ANY_SUSPEND_IN_PROGRESS(&dhd->pub) ||
+			(dhd->pub.busstate == DHD_BUS_SUSPEND &&
+			!DHD_BUS_BUSY_CHECK_RESUME_IN_PROGRESS(&dhd->pub))) {
+			dhd_bus_stop_queue(dhd->pub.bus);
+		}
+#endif /* PCIE_FULL_DONGLE */
+		dhd_os_busbusy_wake(&dhd->pub);
+		DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+		return NETDEV_TX_BUSY;
+	}
+#else
+	if (DHD_BUS_CHECK_SUSPEND_OR_SUSPEND_IN_PROGRESS(&dhd->pub)) {
+		DHD_ERROR(("%s: bus is in suspend(%d) or suspending(0x%x) state!!\n",
+			__FUNCTION__, dhd->pub.busstate, dhd->pub.dhd_bus_busy_state));
+	}
+#endif
+
+	DHD_OS_WAKE_LOCK(&dhd->pub);
+
+#if defined(DHD_HANG_SEND_UP_TEST)
+	if (dhd->pub.req_hang_type == HANG_REASON_BUS_DOWN) {
+		DHD_ERROR(("%s: making DHD_BUS_DOWN\n", __FUNCTION__));
+		dhd->pub.busstate = DHD_BUS_DOWN;
+	}
+#endif /* DHD_HANG_SEND_UP_TEST */
+
+	/* Reject if down */
+	/* XXX kernel panic issue when first bootup time,
+	 *	 rmmod without interface down make unnecessary hang event.
+	 */
+	if (dhd->pub.hang_was_sent || DHD_BUS_CHECK_DOWN_OR_DOWN_IN_PROGRESS(&dhd->pub)) {
+		DHD_ERROR(("%s: xmit rejected pub.up=%d busstate=%d \n",
+			__FUNCTION__, dhd->pub.up, dhd->pub.busstate));
+		dhd_tx_stop_queues(net);
+#if defined(OEM_ANDROID)
+		/* Send Event when bus down detected during data session */
+		if (dhd->pub.up && !dhd->pub.hang_was_sent && !DHD_BUS_CHECK_REMOVE(&dhd->pub)) {
+			DHD_ERROR(("%s: Event HANG sent up\n", __FUNCTION__));
+			dhd->pub.hang_reason = HANG_REASON_BUS_DOWN;
+			net_os_send_hang_message(net);
+		}
+#endif /* OEM_ANDROID */
+		DHD_BUS_BUSY_CLEAR_IN_TX(&dhd->pub);
+		dhd_os_busbusy_wake(&dhd->pub);
+		DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+		DHD_OS_WAKE_UNLOCK(&dhd->pub);
+		return NETDEV_TX_BUSY;
+	}
+
+	ifp = DHD_DEV_IFP(net);
+	ifidx = DHD_DEV_IFIDX(net);
+#ifdef DHD_BUZZZ_LOG_ENABLED
+	BUZZZ_LOG(START_XMIT_BGN, 2, (uint32)ifidx, (uintptr)skb);
+#endif /* DHD_BUZZZ_LOG_ENABLED */
+	if (ifidx == DHD_BAD_IF) {
+		DHD_ERROR(("%s: bad ifidx %d\n", __FUNCTION__, ifidx));
+		dhd_tx_stop_queues(net);
+		DHD_BUS_BUSY_CLEAR_IN_TX(&dhd->pub);
+		dhd_os_busbusy_wake(&dhd->pub);
+		DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+		DHD_OS_WAKE_UNLOCK(&dhd->pub);
+		return NETDEV_TX_BUSY;
+	}
+#ifdef RPM_FAST_TRIGGER
+	/* Xmit is running reset RPM fast trigger */
+	if (dhd->pub.rpm_fast_trigger) {
+		DHD_ERROR(("%s: Reset RPM fast trigger\n", __FUNCTION__));
+		dhd->pub.rpm_fast_trigger = FALSE;
+	}
+#endif /* RPM_FAST_TRIGGER */
+	DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+
+	/* If tput test is in progress */
+	if (dhd->pub.tput_data.tput_test_running) {
+		return NETDEV_TX_BUSY;
+	}
+
+	ASSERT(ifidx == dhd_net2idx(dhd, net));
+	ASSERT((ifp != NULL) && ((ifidx < DHD_MAX_IFS) && (ifp == dhd->iflist[ifidx])));
+
+	bcm_object_trace_opr(skb, BCM_OBJDBG_ADD_PKT, __FUNCTION__, __LINE__);
+
+	/* re-align socket buffer if "skb->data" is odd address */
+	if (((unsigned long)(skb->data)) & 0x1) {
+		unsigned char *data = skb->data;
+		uint32 length = skb->len;
+		PKTPUSH(dhd->pub.osh, skb, 1);
+		memmove(skb->data, data, length);
+		PKTSETLEN(dhd->pub.osh, skb, length);
+	}
+
+	/* Make sure there's enough room for any header */
+#if !defined(BCM_ROUTER_DHD)
+	if (skb_cow(skb, (dhd->pub.hdrlen + htsfdlystat_sz))) {
+		DHD_ERROR(("%s: skb_cow failed\n",
+		           dhd_ifname(&dhd->pub, ifidx)));
+		bcm_object_trace_opr(skb, BCM_OBJDBG_REMOVE, __FUNCTION__, __LINE__);
+		dev_kfree_skb_any(skb);
+		ret = -ENOMEM;
+		goto done;
+	}
+#endif /* !BCM_ROUTER_DHD */
+
+	/* Convert to packet */
+	if (!(pktbuf = PKTFRMNATIVE(dhd->pub.osh, skb))) {
+		DHD_ERROR(("%s: PKTFRMNATIVE failed\n",
+		           dhd_ifname(&dhd->pub, ifidx)));
+		bcm_object_trace_opr(skb, BCM_OBJDBG_REMOVE, __FUNCTION__, __LINE__);
+		dev_kfree_skb_any(skb);
+		ret = -ENOMEM;
+		goto done;
+	}
+
+#ifdef DHD_WET
+	/* wet related packet proto manipulation should be done in DHD
+	   since dongle doesn't have complete payload
+	 */
+	if (WET_ENABLED(&dhd->pub) &&
+			(dhd_wet_send_proc(dhd->pub.wet_info, pktbuf, &pktbuf) < 0)) {
+		DHD_INFO(("%s:%s: wet send proc failed\n",
+				__FUNCTION__, dhd_ifname(&dhd->pub, ifidx)));
+		PKTFREE(dhd->pub.osh, pktbuf, FALSE);
+		ret =  -EFAULT;
+		goto done;
+	}
+#endif /* DHD_WET */
+
+#ifdef DHD_WMF
+	eh = (struct ether_header *)PKTDATA(dhd->pub.osh, pktbuf);
+	iph = (uint8 *)eh + ETHER_HDR_LEN;
+
+	/* WMF processing for multicast packets
+	 * Only IPv4 packets are handled
+	 */
+	if (ifp->wmf.wmf_enable && (ntoh16(eh->ether_type) == ETHER_TYPE_IP) &&
+		(IP_VER(iph) == IP_VER_4) && (ETHER_ISMULTI(eh->ether_dhost) ||
+		((IPV4_PROT(iph) == IP_PROT_IGMP) && dhd->pub.wmf_ucast_igmp))) {
+#if defined(DHD_IGMP_UCQUERY) || defined(DHD_UCAST_UPNP)
+		void *sdu_clone;
+		bool ucast_convert = FALSE;
+#ifdef DHD_UCAST_UPNP
+		uint32 dest_ip;
+
+		dest_ip = ntoh32(*((uint32 *)(iph + IPV4_DEST_IP_OFFSET)));
+		ucast_convert = dhd->pub.wmf_ucast_upnp && MCAST_ADDR_UPNP_SSDP(dest_ip);
+#endif /* DHD_UCAST_UPNP */
+#ifdef DHD_IGMP_UCQUERY
+		ucast_convert |= dhd->pub.wmf_ucast_igmp_query &&
+			(IPV4_PROT(iph) == IP_PROT_IGMP) &&
+			(*(iph + IPV4_HLEN(iph)) == IGMPV2_HOST_MEMBERSHIP_QUERY);
+#endif /* DHD_IGMP_UCQUERY */
+		if (ucast_convert) {
+			dhd_sta_t *sta;
+			unsigned long flags;
+			struct list_head snapshot_list;
+			struct list_head *wmf_ucforward_list;
+
+			ret = NETDEV_TX_OK;
+
+			/* For non BCM_GMAC3 platform we need a snapshot sta_list to
+			 * resolve double DHD_IF_STA_LIST_LOCK call deadlock issue.
+			 */
+			wmf_ucforward_list = DHD_IF_WMF_UCFORWARD_LOCK(dhd, ifp, &snapshot_list);
+
+			GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
+			/* Convert upnp/igmp query to unicast for each assoc STA */
+			list_for_each_entry(sta, wmf_ucforward_list, list) {
+				GCC_DIAGNOSTIC_POP();
+				/* Skip sending to proxy interfaces of proxySTA */
+				if (sta->psta_prim != NULL && !ifp->wmf_psta_disable) {
+					continue;
+				}
+				if ((sdu_clone = PKTDUP(dhd->pub.osh, pktbuf)) == NULL) {
+					ret = WMF_NOP;
+					break;
+				}
+				dhd_wmf_forward(ifp->wmf.wmfh, sdu_clone, 0, sta, 1);
+			}
+			DHD_IF_WMF_UCFORWARD_UNLOCK(dhd, wmf_ucforward_list);
+
+			DHD_GENERAL_LOCK(&dhd->pub, flags);
+			DHD_BUS_BUSY_CLEAR_IN_TX(&dhd->pub);
+			dhd_os_busbusy_wake(&dhd->pub);
+			DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+			DHD_OS_WAKE_UNLOCK(&dhd->pub);
+
+			if (ret == NETDEV_TX_OK)
+				PKTFREE(dhd->pub.osh, pktbuf, TRUE);
+
+			return ret;
+		} else
+#endif /* defined(DHD_IGMP_UCQUERY) || defined(DHD_UCAST_UPNP) */
+		{
+			/* There will be no STA info if the packet is coming from LAN host
+			 * Pass as NULL
+			 */
+			ret = dhd_wmf_packets_handle(&dhd->pub, pktbuf, NULL, ifidx, 0);
+			switch (ret) {
+			case WMF_TAKEN:
+			case WMF_DROP:
+				/* Either taken by WMF or we should drop it.
+				 * Exiting send path
+				 */
+
+				DHD_GENERAL_LOCK(&dhd->pub, flags);
+				DHD_BUS_BUSY_CLEAR_IN_TX(&dhd->pub);
+				dhd_os_busbusy_wake(&dhd->pub);
+				DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+				DHD_OS_WAKE_UNLOCK(&dhd->pub);
+				return NETDEV_TX_OK;
+			default:
+				/* Continue the transmit path */
+				break;
+			}
+		}
+	}
+#endif /* DHD_WMF */
+#ifdef DHD_PSTA
+	/* PSR related packet proto manipulation should be done in DHD
+	 * since dongle doesn't have complete payload
+	 */
+	if (PSR_ENABLED(&dhd->pub) &&
+#ifdef BCM_ROUTER_DHD
+		!(ifp->primsta_dwds) &&
+#endif /* BCM_ROUTER_DHD */
+		(dhd_psta_proc(&dhd->pub, ifidx, &pktbuf, TRUE) < 0)) {
+
+			DHD_ERROR(("%s:%s: psta send proc failed\n", __FUNCTION__,
+				dhd_ifname(&dhd->pub, ifidx)));
+	}
+#endif /* DHD_PSTA */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0) && defined(DHD_TCP_PACING_SHIFT)
+#ifndef DHD_DEFAULT_TCP_PACING_SHIFT
+#define DHD_DEFAULT_TCP_PACING_SHIFT 7
+#endif /* DHD_DEFAULT_TCP_PACING_SHIFT */
+	if (skb->sk) {
+		sk_pacing_shift_update(skb->sk, DHD_DEFAULT_TCP_PACING_SHIFT);
+	}
+#else
+#if defined(BCMPCIE) && defined(DHD_VSDB_SKIP_ORPHAN) && defined(WL_CFG80211)
+	if (!cfg->vsdb_mode)
+#endif /* (BCMPCIE) && (DHD_VSDB_SKIP_ORPHAN) && defined(WL_CFG80211) */
+	skb_orphan(skb);
+#endif /* LINUX_VERSION_CODE >= 4.19.0 && DHD_TCP_PACING_SHIFT */
+
+#ifdef DHDTCPSYNC_FLOOD_BLK
+	if (dhd_tcpdata_get_flag(&dhd->pub, pktbuf) == FLAG_SYNCACK) {
+		ifp->tsyncack_txed ++;
+	}
+#endif /* DHDTCPSYNC_FLOOD_BLK */
+
+#ifdef DHDTCPACK_SUPPRESS
+	if (dhd->pub.tcpack_sup_mode == TCPACK_SUP_HOLD) {
+		/* If this packet has been hold or got freed, just return */
+		if (dhd_tcpack_hold(&dhd->pub, pktbuf, ifidx)) {
+			ret = 0;
+			goto done;
+		}
+	} else {
+		/* If this packet has replaced another packet and got freed, just return */
+		if (dhd_tcpack_suppress(&dhd->pub, pktbuf)) {
+			ret = 0;
+			goto done;
+		}
+	}
+#endif /* DHDTCPACK_SUPPRESS */
+
+	/*
+	 * If Load Balance is enabled queue the packet
+	 * else send directly from here.
+	 */
+#if defined(DHD_LB_TXP)
+	ret = dhd_lb_sendpkt(dhd, net, ifidx, pktbuf);
+#else
+	ret = __dhd_sendpkt(&dhd->pub, ifidx, pktbuf);
+#endif
+	BCM_REFERENCE(ret);
+
+done:
+	DHD_GENERAL_LOCK(&dhd->pub, flags);
+	DHD_BUS_BUSY_CLEAR_IN_TX(&dhd->pub);
+	DHD_IF_CLR_TX_ACTIVE(ifp, DHD_TX_START_XMIT);
+	dhd_os_tx_completion_wake(&dhd->pub);
+	dhd_os_busbusy_wake(&dhd->pub);
+	DHD_GENERAL_UNLOCK(&dhd->pub, flags);
+	DHD_OS_WAKE_UNLOCK(&dhd->pub);
+#ifdef DHD_BUZZZ_LOG_ENABLED
+	BUZZZ_LOG(START_XMIT_END, 0);
+#endif /* DHD_BUZZZ_LOG_ENABLED */
+	/* Return ok: we always eat the packet */
+	return NETDEV_TX_OK;
+}
+
+static void
+__dhd_txflowcontrol(dhd_pub_t *dhdp, struct net_device *net, bool state)
+{
+
+	if (net->reg_state != NETREG_REGISTERED) {
+		return;
+	}
+
+	if (state == ON) {
+		if (!netif_queue_stopped(net)) {
+			DHD_TXFLOWCTL(("%s: Stop Netif Queue\n", __FUNCTION__));
+			netif_stop_queue(net);
+		} else {
+			DHD_INFO(("%s: Netif Queue already stopped\n", __FUNCTION__));
+		}
+	}
+
+	if (state == OFF) {
+		if (netif_queue_stopped(net)) {
+			DHD_TXFLOWCTL(("%s: Start Netif Queue\n", __FUNCTION__));
+			netif_wake_queue(net);
+		} else {
+			DHD_INFO(("%s: Netif Queue already started\n", __FUNCTION__));
+		}
+	}
+}
+
+void
+dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool state)
+{
+	struct net_device *net;
+	dhd_info_t *dhd = dhdp->info;
+	unsigned long flags;
+	int i;
+
+	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
+	ASSERT(dhd);
+
+#ifdef DHD_LOSSLESS_ROAMING
+	/* block flowcontrol during roaming */
+	if ((dhdp->dequeue_prec_map == (1 << dhdp->flow_prio_map[PRIO_8021D_NC])) && (state == ON))
+	{
+		DHD_ERROR_RLMT(("%s: Roaming in progress, cannot stop network queue (0x%x:%d)\n",
+			__FUNCTION__, dhdp->dequeue_prec_map, dhdp->flow_prio_map[PRIO_8021D_NC]));
+		return;
+	}
+#endif
+
+	flags = dhd_os_sdlock_txoff(&dhd->pub);
+	if (ifidx == ALL_INTERFACES) {
+		for (i = 0; i < DHD_MAX_IFS; i++) {
+			if (dhd->iflist[i]) {
+				net = dhd->iflist[i]->net;
+				__dhd_txflowcontrol(dhdp, net, state);
+			}
+		}
+	} else {
+		if (dhd->iflist[ifidx]) {
+			net = dhd->iflist[ifidx]->net;
+			__dhd_txflowcontrol(dhdp, net, state);
+		}
+	}
+	dhdp->txoff = state;
+	dhd_os_sdunlock_txoff(&dhd->pub, flags);
+}
+
+void
+dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(dhdp->info);
+	struct ether_header *eh;
+	uint16 type;
+
+	if (dhdp->tput_data.tput_test_running) {
+
+		dhdp->batch_tx_pkts_cmpl++;
+
+		/* don't count the stop pkt */
+		if (success &&
+			dhdp->batch_tx_pkts_cmpl <= dhdp->batch_tx_num_pkts)
+			dhdp->tput_data.pkts_good++;
+		else if (!success)
+			dhdp->tput_data.pkts_bad++;
+
+		/* we dont care for the stop packet in tput test */
+		if (dhdp->batch_tx_pkts_cmpl == dhdp->batch_tx_num_pkts) {
+			dhdp->tput_stop_ts = OSL_SYSUPTIME_US();
+			dhdp->tput_data.pkts_cmpl += dhdp->batch_tx_pkts_cmpl;
+			dhdp->tput_data.num_pkts += dhdp->batch_tx_num_pkts;
+			dhd_os_tput_test_wake(dhdp);
+		}
+	}
+	/* XXX where does this stuff belong to? */
+	dhd_prot_hdrpull(dhdp, NULL, txp, NULL, NULL);
+
+	/* XXX Use packet tag when it is available to identify its type */
+
+	eh = (struct ether_header *)PKTDATA(dhdp->osh, txp);
+	type  = ntoh16(eh->ether_type);
+
+	if (type == ETHER_TYPE_802_1X) {
+		atomic_dec(&dhd->pend_8021x_cnt);
+	}
+
+#ifdef PROP_TXSTATUS
+	if (dhdp->wlfc_state && (dhdp->proptxstatus_mode != WLFC_FCMODE_NONE)) {
+		dhd_if_t *ifp = dhd->iflist[DHD_PKTTAG_IF(PKTTAG(txp))];
+		uint datalen  = PKTLEN(dhd->pub.osh, txp);
+		if (ifp != NULL) {
+			if (success) {
+				dhd->pub.tx_packets++;
+				dhd->pub.tx_bytes += datalen;
+				ifp->stats.tx_packets++;
+				ifp->stats.tx_bytes += datalen;
+			} else {
+				ifp->stats.tx_dropped++;
+			}
+		}
+	}
+#endif
+	if (success) {
+		dhd->pub.tot_txcpl++;
+	}
+}
+
+void
+dhd_os_tx_completion_wake(dhd_pub_t *dhd)
+{
+	/* Call wmb() to make sure before waking up the other event value gets updated */
+	OSL_SMP_WMB();
+	wake_up(&dhd->tx_completion_wait);
+}
+
+void
+dhd_os_sdlock_txq(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd;
+
+	dhd = (dhd_info_t *)(pub->info);
+#ifdef BCMDBUS
+	spin_lock_irqsave(&dhd->txqlock, dhd->txqlock_flags);
+#else
+	spin_lock_bh(&dhd->txqlock);
+#endif
+}
+
+void
+dhd_os_sdunlock_txq(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd;
+
+	dhd = (dhd_info_t *)(pub->info);
+#ifdef BCMDBUS
+	spin_unlock_irqrestore(&dhd->txqlock, dhd->txqlock_flags);
+#else
+	spin_unlock_bh(&dhd->txqlock);
+#endif
+}
+
+unsigned long
+dhd_os_sdlock_txoff(dhd_pub_t *pub)
+{
+	dhd_info_t *dhd;
+	unsigned long flags = 0;
+
+	dhd = (dhd_info_t *)(pub->info);
+	spin_lock_irqsave(&dhd->txoff_lock, flags);
+
+	return flags;
+}
+
+void
+dhd_os_sdunlock_txoff(dhd_pub_t *pub, unsigned long flags)
+{
+	dhd_info_t *dhd;
+
+	dhd = (dhd_info_t *)(pub->info);
+	spin_unlock_irqrestore(&dhd->txoff_lock, flags);
+}
+
+void
+dhd_txfl_wake_lock_timeout(dhd_pub_t *pub, int val)
+{
+#ifdef CONFIG_HAS_WAKELOCK
+	dhd_info_t *dhd = (dhd_info_t *)(pub->info);
+
+	if (dhd) {
+		dhd_wake_lock_timeout(dhd->wl_txflwake, msecs_to_jiffies(val));
+	}
+#endif /* CONFIG_HAS_WAKE_LOCK */
+}
+
+#ifdef DHD_4WAYM4_FAIL_DISCONNECT
+void
+dhd_eap_txcomplete(dhd_pub_t *dhdp, void *txp, bool success, int ifidx)
+{
+	dhd_info_t *dhd = (dhd_info_t *)(dhdp->info);
+	struct ether_header *eh;
+	uint16 type;
+
+	/* XXX where does this stuff belong to? */
+	dhd_prot_hdrpull(dhdp, NULL, txp, NULL, NULL);
+
+	/* XXX Use packet tag when it is available to identify its type */
+	eh = (struct ether_header *)PKTDATA(dhdp->osh, txp);
+	type  = ntoh16(eh->ether_type);
+	if (type == ETHER_TYPE_802_1X) {
+		if (dhd_is_4way_msg((uint8 *)eh) == EAPOL_4WAY_M4) {
+			dhd_if_t *ifp = NULL;
+			ifp = dhd->iflist[ifidx];
+			if (!ifp || !ifp->net) {
+				return;
+			}
+			if (!success) {
+				DHD_INFO(("%s: M4 TX failed on %d.\n",
+						__FUNCTION__, ifidx));
+
+				OSL_ATOMIC_SET(dhdp->osh, &ifp->m4state, M4_TXFAILED);
+				schedule_delayed_work(&ifp->m4state_work,
+						msecs_to_jiffies(MAX_4WAY_TIMEOUT_MS));
+			} else {
+				cancel_delayed_work(&ifp->m4state_work);
+			}
+		}
+	}
+}
+#endif /* DHD_4WAYM4_FAIL_DISCONNECT */
+
+void
+dhd_handle_pktdata(dhd_pub_t *dhdp, int ifidx, void *pkt, uint8 *pktdata, uint32 pktid,
+	uint32 pktlen, uint16 *pktfate, uint8 *dhd_udr, uint8 *dhd_igmp,
+	bool tx, int pkt_wake, bool pkt_log)
+{
+	struct ether_header *eh;
+	uint16 ether_type;
+	uint32 pkthash;
+	uint8 pkt_type = PKT_TYPE_DATA;
+#ifdef DHD_PKT_LOGGING_DBGRING
+	bool verbose_logging = FALSE;
+	dhd_dbg_ring_t *ring;
+	ring = &dhdp->dbg->dbg_rings[PACKET_LOG_RING_ID];
+	UNUSED_PARAMETER(verbose_logging);
+#endif /* DHD_PKT_LOGGING_DBGRING */
+
+	if (!pktdata || pktlen < ETHER_HDR_LEN) {
+		return;
+	}
+
+	eh = (struct ether_header *)pktdata;
+	ether_type = ntoh16(eh->ether_type);
+
+	/* Check packet type */
+	if (dhd_check_ip_prot(pktdata, ether_type)) {
+		if (dhd_check_dhcp(pktdata)) {
+			pkt_type = PKT_TYPE_DHCP;
+		} else if (dhd_check_icmp(pktdata)) {
+			pkt_type = PKT_TYPE_ICMP;
+		} else if (dhd_check_dns(pktdata)) {
+			pkt_type = PKT_TYPE_DNS;
+		}
+	}
+	else if (ether_type == ETHER_TYPE_IPV6) {
+		if (dhd_check_icmpv6(pktdata, pktlen)) {
+			pkt_type = PKT_TYPE_ICMPV6;
+		}
+#ifdef DHD_IPV6_DUMP
+		else if (dhd_check_dhcp6(pktdata, pktlen)) {
+			pkt_type = PKT_TYPE_DHCP6;
+		} else if (dhd_check_dns6(pktdata, pktlen)) {
+			pkt_type = PKT_TYPE_DNS6;
+		}
+#endif
+	}
+	else if (dhd_check_arp(pktdata, ether_type)) {
+		pkt_type = PKT_TYPE_ARP;
+	}
+	else if (ether_type == ETHER_TYPE_802_1X) {
+		pkt_type = PKT_TYPE_EAP;
+	}
+#ifdef DHD_PKT_LOGGING_DBGRING
+	do {
+		if (!OSL_ATOMIC_READ(dhdp->osh, &dhdp->pktlog->enable)) {
+			struct dhd_pktlog_ring *pktlog_ring;
+
+			pktlog_ring = dhdp->pktlog->pktlog_ring;
+			if (pktlog_ring->pktcount <= DHD_PACKET_LOG_RING_RESUME_THRESHOLD) {
+				dhd_pktlog_resume(dhdp);
+			} else {
+				/* If pktlog disabled(suspeneded), only allowed TXS update */
+				if (tx && pktfate) {
+					DHD_PKTLOG_TXS(dhdp, pkt, pktdata, pktid, *pktfate);
+					pkthash = __dhd_dbg_pkt_hash((uintptr_t)pkt, pktid);
+				}
+				dhd_os_dbg_urgent_pullreq(dhdp->dbg->private,
+					PACKET_LOG_RING_ID);
+				break;
+			}
+		}
+
+		/* Allow logging for all packets without pktlog filter */
+		if (ring->log_level == RING_LOG_LEVEL_EXCESSIVE) {
+			verbose_logging = TRUE;
+			pkt_log = TRUE;
+		/* Not allow logging for any packets */
+		} else if (ring->log_level == RING_LOG_LEVEL_NONE) {
+			verbose_logging = FALSE;
+			pkt_log = FALSE;
+		}
+#endif /* DHD_PKT_LOGGING_DBGRING */
+#ifdef DHD_SBN
+		/* Set UDR based on packet type */
+		if (dhd_udr && (pkt_type == PKT_TYPE_DHCP ||
+			pkt_type == PKT_TYPE_DNS ||
+			pkt_type == PKT_TYPE_ARP)) {
+			*dhd_udr = TRUE;
+		}
+#endif /* DHD_SBN */
+
+#ifdef DHD_PKT_LOGGING
+#ifdef DHD_SKIP_PKTLOGGING_FOR_DATA_PKTS
+		if (pkt_type != PKT_TYPE_DATA)
+#else
+#ifdef DHD_PKT_LOGGING_DBGRING
+		if ((verbose_logging == TRUE) || (pkt_type != PKT_TYPE_DATA))
+#endif /* DHD_PKT_LOGGING_DBGRING */
+#endif /* DHD_PKT_LOGGING */
+		{
+			if (pkt_log) {
+				if (tx) {
+					if (pktfate) {
+						/* Tx status */
+						DHD_PKTLOG_TXS(dhdp, pkt, pktdata, pktid, *pktfate);
+					} else {
+						/* Tx packet */
+						DHD_PKTLOG_TX(dhdp, pkt, pktdata, pktid);
+					}
+					pkthash = __dhd_dbg_pkt_hash((uintptr_t)pkt, pktid);
+				} else {
+					struct sk_buff *skb = (struct sk_buff *)pkt;
+					if (pkt_wake) {
+						DHD_PKTLOG_WAKERX(dhdp, skb, pktdata);
+					} else {
+						DHD_PKTLOG_RX(dhdp, skb, pktdata);
+					}
+				}
+			}
+		}
+#endif /* DHD_PKT_LOGGING */
+#ifdef DHD_PKT_LOGGING_DBGRING
+	} while (FALSE);
+#endif /* DHD_PKT_LOGGING_DBGRING */
+
+	/* Dump packet data */
+	if (!tx)
+		dhd_dump_pkt(dhdp, ifidx, pktdata, pktlen, FALSE, &pkthash, NULL);
+	switch (pkt_type) {
+		case PKT_TYPE_DHCP:
+			dhd_send_supp_dhcp(dhdp, ifidx, pktdata, tx, pktfate);
+			break;
+		case PKT_TYPE_EAP:
+			dhd_send_supp_eap(dhdp, ifidx, pktdata, pktlen, tx, pktfate);
+			break;
+#ifdef DHD_IPV6_DUMP
+		case PKT_TYPE_ICMPV6:
+			dhd_icmpv6_dump(dhdp, ifidx, pktdata, tx, &pkthash, pktfate);
+			break;
+		case PKT_TYPE_DHCP6:
+			dhd_dhcp6_dump(dhdp, ifidx, pktdata, tx, &pkthash, pktfate);
+			break;
+		case PKT_TYPE_DNS6:
+			dhd_dns6_dump(dhdp, ifidx, pktdata, tx, &pkthash, pktfate);
+			break;
+#endif
+		default:
+			break;
+	}
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux_tx.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux_tx.h
@@ -0,0 +1,68 @@
+/*
+ * Broadcom Dongle Host Driver (DHD),
+ * Linux-specific network interface for transmit(tx) path
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef _dhd_linux_tx_h_
+#define _dhd_linux_tx_h_
+void dhd_tx_stop_queues(struct net_device *net);
+void dhd_tx_start_queues(struct net_device *net);
+int BCMFASTPATH(__dhd_sendpkt)(dhd_pub_t *dhdp, int ifidx, void *pktbuf);
+int BCMFASTPATH(dhd_sendpkt)(dhd_pub_t *dhdp, int ifidx, void *pktbuf);
+#ifdef DHD_MQ
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
+uint16
+BCMFASTPATH(dhd_select_queue)(struct net_device *net, struct sk_buff *skb,
+       void *accel_priv, select_queue_fallback_t fallback);
+#else
+uint16
+BCMFASTPATH(dhd_select_queue)(struct net_device *net, struct sk_buff *skb);
+#endif /* LINUX_VERSION_CODE */
+#endif /* DHD_MQ */
+netdev_tx_t BCMFASTPATH(dhd_start_xmit)(struct sk_buff *skb, struct net_device *net);
+void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool state);
+void dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success);
+void dhd_os_tx_completion_wake(dhd_pub_t *dhd);
+void dhd_os_sdlock_txq(dhd_pub_t *pub);
+void dhd_os_sdunlock_txq(dhd_pub_t *pub);
+#endif /* _dhd_linux_tx_h_ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux_wq.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux_wq.c
@@ -0,0 +1,432 @@
+/*
+ * Broadcom Dongle Host Driver (DHD), Generic work queue framework
+ * Generic interface to handle dhd deferred work events
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/fcntl.h>
+#include <linux/fs.h>
+#include <linux/ip.h>
+#include <linux/kfifo.h>
+
+#include <linuxver.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <bcmdevs.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_dbg.h>
+#include <dhd_linux_wq.h>
+
+/*
+ * XXX: always make sure that the size of this structure is aligned to
+ * the power of 2 (2^n) i.e, if any new variable has to be added then
+ * modify the padding accordingly
+ */
+typedef struct dhd_deferred_event {
+	u8 event;		/* holds the event */
+	void *event_data;	/* holds event specific data */
+	event_handler_t event_handler;
+	unsigned long pad;	/* for memory alignment to power of 2 */
+} dhd_deferred_event_t;
+
+#define DEFRD_EVT_SIZE	(sizeof(dhd_deferred_event_t))
+
+/*
+ * work events may occur simultaneously.
+ * can hold upto 64 low priority events and 16 high priority events
+ */
+#define DHD_PRIO_WORK_FIFO_SIZE	(16 * DEFRD_EVT_SIZE)
+#define DHD_WORK_FIFO_SIZE	(64 * DEFRD_EVT_SIZE)
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32))
+#define kfifo_avail(fifo) (fifo->size - kfifo_len(fifo))
+#endif /* (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)) */
+
+#define DHD_FIFO_HAS_FREE_SPACE(fifo) \
+	((fifo) && (kfifo_avail(fifo) >= DEFRD_EVT_SIZE))
+#define DHD_FIFO_HAS_ENOUGH_DATA(fifo) \
+	((fifo) && (kfifo_len(fifo) >= DEFRD_EVT_SIZE))
+
+struct dhd_deferred_wq {
+	struct work_struct deferred_work; /* should be the first member */
+
+	struct kfifo *prio_fifo;
+	struct kfifo			*work_fifo;
+	u8				*prio_fifo_buf;
+	u8				*work_fifo_buf;
+	spinlock_t			work_lock;
+	void				*dhd_info; /* review: does it require */
+	u32				event_skip_mask;
+};
+
+static inline struct kfifo*
+dhd_kfifo_init(u8 *buf, int size, spinlock_t *lock)
+{
+	struct kfifo *fifo;
+	gfp_t flags = CAN_SLEEP()? GFP_KERNEL : GFP_ATOMIC;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33))
+	fifo = kfifo_init(buf, size, flags, lock);
+#else
+	fifo = (struct kfifo *)kzalloc(sizeof(struct kfifo), flags);
+	if (!fifo) {
+		return NULL;
+	}
+	kfifo_init(fifo, buf, size);
+#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)) */
+	return fifo;
+}
+
+static inline void
+dhd_kfifo_free(struct kfifo *fifo)
+{
+	kfifo_free(fifo);
+	kfree(fifo);
+}
+
+/* deferred work functions */
+static void dhd_deferred_work_handler(struct work_struct *data);
+
+void*
+dhd_deferred_work_init(void *dhd_info)
+{
+	struct dhd_deferred_wq	*work = NULL;
+	u8*	buf;
+	unsigned long	fifo_size = 0;
+	gfp_t	flags = CAN_SLEEP()? GFP_KERNEL : GFP_ATOMIC;
+
+	if (!dhd_info) {
+		DHD_ERROR(("%s: dhd info not initialized\n", __FUNCTION__));
+		goto return_null;
+	}
+
+	work = (struct dhd_deferred_wq *)kzalloc(sizeof(struct dhd_deferred_wq),
+		flags);
+	if (!work) {
+		DHD_ERROR(("%s: work queue creation failed\n", __FUNCTION__));
+		goto return_null;
+	}
+
+	INIT_WORK((struct work_struct *)work, dhd_deferred_work_handler);
+
+	/* initialize event fifo */
+	spin_lock_init(&work->work_lock);
+
+	/* allocate buffer to hold prio events */
+	fifo_size = DHD_PRIO_WORK_FIFO_SIZE;
+	fifo_size = is_power_of_2(fifo_size) ? fifo_size :
+			roundup_pow_of_two(fifo_size);
+	buf = (u8*)kzalloc(fifo_size, flags);
+	if (!buf) {
+		DHD_ERROR(("%s: prio work fifo allocation failed\n",
+			__FUNCTION__));
+		goto return_null;
+	}
+
+	/* Initialize prio event fifo */
+	work->prio_fifo = dhd_kfifo_init(buf, fifo_size, &work->work_lock);
+	if (!work->prio_fifo) {
+		kfree(buf);
+		goto return_null;
+	}
+
+	/* allocate buffer to hold work events */
+	fifo_size = DHD_WORK_FIFO_SIZE;
+	fifo_size = is_power_of_2(fifo_size) ? fifo_size :
+			roundup_pow_of_two(fifo_size);
+	buf = (u8*)kzalloc(fifo_size, flags);
+	if (!buf) {
+		DHD_ERROR(("%s: work fifo allocation failed\n", __FUNCTION__));
+		goto return_null;
+	}
+
+	/* Initialize event fifo */
+	work->work_fifo = dhd_kfifo_init(buf, fifo_size, &work->work_lock);
+	if (!work->work_fifo) {
+		kfree(buf);
+		goto return_null;
+	}
+
+	work->dhd_info = dhd_info;
+	work->event_skip_mask = 0;
+	DHD_ERROR(("%s: work queue initialized\n", __FUNCTION__));
+	return work;
+
+return_null:
+	if (work) {
+		dhd_deferred_work_deinit(work);
+	}
+
+	return NULL;
+}
+
+void
+dhd_deferred_work_deinit(void *work)
+{
+	struct dhd_deferred_wq *deferred_work = work;
+
+	if (!deferred_work) {
+		DHD_ERROR(("%s: deferred work has been freed already\n",
+			__FUNCTION__));
+		return;
+	}
+
+	/* cancel the deferred work handling */
+	cancel_work_sync((struct work_struct *)deferred_work);
+
+	/*
+	 * free work event fifo.
+	 * kfifo_free frees locally allocated fifo buffer
+	 */
+	if (deferred_work->prio_fifo) {
+		dhd_kfifo_free(deferred_work->prio_fifo);
+	}
+
+	if (deferred_work->work_fifo) {
+		dhd_kfifo_free(deferred_work->work_fifo);
+	}
+
+	kfree(deferred_work);
+}
+
+/* select kfifo according to priority */
+static inline struct kfifo *
+dhd_deferred_work_select_kfifo(struct dhd_deferred_wq *deferred_wq,
+	u8 priority)
+{
+	if (priority == DHD_WQ_WORK_PRIORITY_HIGH) {
+		return deferred_wq->prio_fifo;
+	} else if (priority == DHD_WQ_WORK_PRIORITY_LOW) {
+		return deferred_wq->work_fifo;
+	} else {
+		return NULL;
+	}
+}
+
+/*
+ *	Prepares event to be queued
+ *	Schedules the event
+ */
+int
+dhd_deferred_schedule_work(void *workq, void *event_data, u8 event,
+	event_handler_t event_handler, u8 priority)
+{
+	struct dhd_deferred_wq *deferred_wq = (struct dhd_deferred_wq *)workq;
+	struct kfifo *fifo;
+	dhd_deferred_event_t deferred_event;
+	int bytes_copied = 0;
+
+	if (!deferred_wq) {
+		DHD_ERROR(("%s: work queue not initialized\n", __FUNCTION__));
+		ASSERT(0);
+		return DHD_WQ_STS_UNINITIALIZED;
+	}
+
+	if (!event || (event >= DHD_MAX_WQ_EVENTS)) {
+		DHD_ERROR(("%s: unknown event, event=%d\n", __FUNCTION__,
+			event));
+		return DHD_WQ_STS_UNKNOWN_EVENT;
+	}
+
+	if (!priority || (priority >= DHD_WQ_MAX_PRIORITY)) {
+		DHD_ERROR(("%s: unknown priority, priority=%d\n",
+			__FUNCTION__, priority));
+		return DHD_WQ_STS_UNKNOWN_PRIORITY;
+	}
+
+	if ((deferred_wq->event_skip_mask & (1 << event))) {
+		DHD_ERROR(("%s: Skip event requested. Mask = 0x%x\n",
+			__FUNCTION__, deferred_wq->event_skip_mask));
+		return DHD_WQ_STS_EVENT_SKIPPED;
+	}
+
+	/*
+	 * default element size is 1, which can be changed
+	 * using kfifo_esize(). Older kernel(FC11) doesn't support
+	 * changing element size. For compatibility changing
+	 * element size is not prefered
+	 */
+	ASSERT(kfifo_esize(deferred_wq->prio_fifo) == 1);
+	ASSERT(kfifo_esize(deferred_wq->work_fifo) == 1);
+
+	deferred_event.event = event;
+	deferred_event.event_data = event_data;
+	deferred_event.event_handler = event_handler;
+
+	fifo = dhd_deferred_work_select_kfifo(deferred_wq, priority);
+	if (DHD_FIFO_HAS_FREE_SPACE(fifo)) {
+		bytes_copied = kfifo_in_spinlocked(fifo, &deferred_event,
+			DEFRD_EVT_SIZE, &deferred_wq->work_lock);
+	}
+	if (bytes_copied != DEFRD_EVT_SIZE) {
+		DHD_ERROR(("%s: failed to schedule deferred work, "
+			"priority=%d, bytes_copied=%d\n", __FUNCTION__,
+			priority, bytes_copied));
+		return DHD_WQ_STS_SCHED_FAILED;
+	}
+	schedule_work((struct work_struct *)deferred_wq);
+	return DHD_WQ_STS_OK;
+}
+
+static bool
+dhd_get_scheduled_work(struct dhd_deferred_wq *deferred_wq,
+	dhd_deferred_event_t *event)
+{
+	int bytes_copied = 0;
+
+	if (!deferred_wq) {
+		DHD_ERROR(("%s: work queue not initialized\n", __FUNCTION__));
+		return DHD_WQ_STS_UNINITIALIZED;
+	}
+
+	/*
+	 * default element size is 1 byte, which can be changed
+	 * using kfifo_esize(). Older kernel(FC11) doesn't support
+	 * changing element size. For compatibility changing
+	 * element size is not prefered
+	 */
+	ASSERT(kfifo_esize(deferred_wq->prio_fifo) == 1);
+	ASSERT(kfifo_esize(deferred_wq->work_fifo) == 1);
+
+	/* handle priority work */
+	if (DHD_FIFO_HAS_ENOUGH_DATA(deferred_wq->prio_fifo)) {
+		bytes_copied = kfifo_out_spinlocked(deferred_wq->prio_fifo,
+			event, DEFRD_EVT_SIZE, &deferred_wq->work_lock);
+	}
+
+	/* handle normal work if priority work doesn't have enough data */
+	if ((bytes_copied != DEFRD_EVT_SIZE) &&
+		DHD_FIFO_HAS_ENOUGH_DATA(deferred_wq->work_fifo)) {
+		bytes_copied = kfifo_out_spinlocked(deferred_wq->work_fifo,
+			event, DEFRD_EVT_SIZE, &deferred_wq->work_lock);
+	}
+
+	return (bytes_copied == DEFRD_EVT_SIZE);
+}
+
+static inline void
+dhd_deferred_dump_work_event(dhd_deferred_event_t *work_event)
+{
+	if (!work_event) {
+		DHD_ERROR(("%s: work_event is null\n", __FUNCTION__));
+		return;
+	}
+
+	DHD_ERROR(("%s: work_event->event = %d\n", __FUNCTION__,
+		work_event->event));
+	DHD_ERROR(("%s: work_event->event_data = %p\n", __FUNCTION__,
+		work_event->event_data));
+	DHD_ERROR(("%s: work_event->event_handler = %p\n", __FUNCTION__,
+		work_event->event_handler));
+}
+
+/*
+ *	Called when work is scheduled
+ */
+static void
+dhd_deferred_work_handler(struct work_struct *work)
+{
+	struct dhd_deferred_wq *deferred_work = (struct dhd_deferred_wq *)work;
+	dhd_deferred_event_t work_event;
+
+	if (!deferred_work) {
+		DHD_ERROR(("%s: work queue not initialized\n", __FUNCTION__));
+		return;
+	}
+
+	do {
+		if (!dhd_get_scheduled_work(deferred_work, &work_event)) {
+			DHD_TRACE(("%s: no event to handle\n", __FUNCTION__));
+			break;
+		}
+
+		if (work_event.event >= DHD_MAX_WQ_EVENTS) {
+			DHD_ERROR(("%s: unknown event\n", __FUNCTION__));
+			dhd_deferred_dump_work_event(&work_event);
+			ASSERT(work_event.event < DHD_MAX_WQ_EVENTS);
+			continue;
+		}
+
+		/*
+		 * XXX: don't do NULL check for 'work_event.event_data'
+		 * as for some events like DHD_WQ_WORK_DHD_LOG_DUMP the
+		 * event data is always NULL even though rest of the
+		 * event parameters are valid
+		 */
+
+		if (work_event.event_handler) {
+			work_event.event_handler(deferred_work->dhd_info,
+				work_event.event_data, work_event.event);
+		} else {
+			DHD_ERROR(("%s: event handler is null\n",
+				__FUNCTION__));
+			dhd_deferred_dump_work_event(&work_event);
+			ASSERT(work_event.event_handler != NULL);
+		}
+	} while (1);
+
+	return;
+}
+
+void
+dhd_deferred_work_set_skip(void *work, u8 event, bool set)
+{
+	struct dhd_deferred_wq *deferred_wq = (struct dhd_deferred_wq *)work;
+
+	if (!deferred_wq || !event || (event >= DHD_MAX_WQ_EVENTS)) {
+		DHD_ERROR(("%s: Invalid!!\n", __FUNCTION__));
+		return;
+	}
+
+	if (set) {
+		/* Set */
+		deferred_wq->event_skip_mask |= (1 << event);
+	} else {
+		/* Clear */
+		deferred_wq->event_skip_mask &= ~(1 << event);
+	}
+}
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_linux_wq.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_linux_wq.h
@@ -0,0 +1,107 @@
+/*
+ * Broadcom Dongle Host Driver (DHD), Generic work queue framework
+ * Generic interface to handle dhd deferred work events
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+#ifndef _dhd_linux_wq_h_
+#define _dhd_linux_wq_h_
+/*
+ *	Work event definitions
+ */
+enum _wq_event {
+	DHD_WQ_WORK_IF_ADD = 1,
+	DHD_WQ_WORK_IF_DEL,
+	DHD_WQ_WORK_SET_MAC,
+	DHD_WQ_WORK_SET_MCAST_LIST,
+	DHD_WQ_WORK_IPV6_NDO,
+	DHD_WQ_WORK_HANG_MSG,
+	DHD_WQ_WORK_DHD_LOG_DUMP,
+	DHD_WQ_WORK_PKTLOG_DUMP,
+	DHD_WQ_WORK_INFORM_DHD_MON,
+	DHD_WQ_WORK_EVENT_LOGTRACE,
+	DHD_WQ_WORK_DMA_LB_MEM_REL,
+	DHD_WQ_WORK_NATOE_EVENT,
+	DHD_WQ_WORK_NATOE_IOCTL,
+	DHD_WQ_WORK_MACDBG,
+	DHD_WQ_WORK_DEBUG_UART_DUMP,
+	DHD_WQ_WORK_GET_BIGDATA_AP,
+	DHD_WQ_WORK_SOC_RAM_DUMP,
+	DHD_WQ_WORK_SOC_RAM_COLLECT,
+	DHD_WQ_WORK_H2D_CONSOLE_TIME_STAMP_MATCH,
+	DHD_WQ_WORK_AXI_ERROR_DUMP,
+	DHD_WQ_WORK_CTO_RECOVERY,
+#ifdef DHD_UPDATE_INTF_MAC
+	DHD_WQ_WORK_IF_UPDATE,
+#endif /* DHD_UPDATE_INTF_MAC */
+	DHD_WQ_WORK_AML_IOVAR,
+	DHD_WQ_WORK_NDEV_UPD_FEATURES,
+	DHD_MAX_WQ_EVENTS
+};
+
+/*
+ *	Work event priority
+ */
+enum wq_priority {
+	DHD_WQ_WORK_PRIORITY_LOW = 1,
+	DHD_WQ_WORK_PRIORITY_HIGH,
+	DHD_WQ_MAX_PRIORITY
+};
+
+/*
+ *	Error definitions
+ */
+#define DHD_WQ_STS_OK			 0
+#define DHD_WQ_STS_FAILED		-1	/* General failure */
+#define DHD_WQ_STS_UNINITIALIZED	-2
+#define DHD_WQ_STS_SCHED_FAILED		-3
+#define DHD_WQ_STS_UNKNOWN_EVENT	-4
+#define DHD_WQ_STS_UNKNOWN_PRIORITY	-5
+#define DHD_WQ_STS_EVENT_SKIPPED	-6
+
+typedef void (*event_handler_t)(void *handle, void *event_data, u8 event);
+
+void *dhd_deferred_work_init(void *dhd);
+void dhd_deferred_work_deinit(void *workq);
+int dhd_deferred_schedule_work(void *workq, void *event_data, u8 event,
+	event_handler_t evt_handler, u8 priority);
+void dhd_deferred_work_set_skip(void *work, u8 event, bool set);
+#endif /* _dhd_linux_wq_h_ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_log_dump.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_log_dump.c
@@ -0,0 +1,2506 @@
+/*
+ * log_dump - debugability support for dumping logs to file
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+#ifdef DHD_LOG_DUMP
+
+#include <osl.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <bcmstdlib_s.h>
+#include <dngl_stats.h>
+#include <dhd_linux_priv.h>
+#include <dhd_linux_wq.h>
+#include <dhd.h>
+#include <dhd_proto.h>
+#include <dhd_log_dump.h>
+#ifdef DHD_EVENT_LOG_FILTER
+#include <dhd_event_log_filter.h>
+#endif /* DHD_EVENT_LOG_FILTER */
+#ifdef DHD_PKT_LOGGING
+#include <dhd_pktlog.h>
+#endif /* DHD_PKT_LOGGING */
+#if defined(WL_CFG80211)
+#include <wl_cfg80211.h>
+#endif
+
+extern char dhd_version[];
+extern char fw_version[];
+struct dhd_log_dump_buf g_dld_buf[DLD_BUFFER_NUM];
+
+/* Only header for log dump buffers is stored in array
+ * header for sections like 'dhd dump', 'ext trap'
+ * etc, is not in the array, because they are not log
+ * ring buffers
+ */
+dld_hdr_t dld_hdrs[DLD_BUFFER_NUM] = {
+		{GENERAL_LOG_HDR, LOG_DUMP_SECTION_GENERAL},
+		{PRESERVE_LOG_HDR, LOG_DUMP_SECTION_PRESERVE},
+		{SPECIAL_LOG_HDR, LOG_DUMP_SECTION_SPECIAL}
+};
+static int dld_buf_size[DLD_BUFFER_NUM] = {
+		LOG_DUMP_GENERAL_MAX_BUFSIZE,	/* DLD_BUF_TYPE_GENERAL */
+		LOG_DUMP_PRESERVE_MAX_BUFSIZE,	/* DLD_BUF_TYPE_PRESERVE */
+		LOG_DUMP_SPECIAL_MAX_BUFSIZE,	/* DLD_BUF_TYPE_SPECIAL */
+};
+
+int logdump_max_filesize = LOG_DUMP_MAX_FILESIZE;
+module_param(logdump_max_filesize, int, 0644);
+int logdump_max_bufsize = LOG_DUMP_GENERAL_MAX_BUFSIZE;
+module_param(logdump_max_bufsize, int, 0644);
+int logdump_periodic_flush = FALSE;
+module_param(logdump_periodic_flush, int, 0644);
+#ifdef EWP_ECNTRS_LOGGING
+int logdump_ecntr_enable = TRUE;
+#else
+int logdump_ecntr_enable = FALSE;
+#endif /* EWP_ECNTRS_LOGGING */
+module_param(logdump_ecntr_enable, int, 0644);
+#ifdef EWP_RTT_LOGGING
+int logdump_rtt_enable = TRUE;
+#else
+int logdump_rtt_enable = FALSE;
+#endif /* EWP_RTT_LOGGING */
+
+int logdump_prsrv_tailsize = DHD_LOG_DUMP_MAX_TAIL_FLUSH_SIZE;
+
+#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
+static dhd_debug_dump_ring_entry_t dhd_debug_dump_ring_map[] = {
+	{LOG_DUMP_SECTION_TIMESTAMP, DEBUG_DUMP_RING1_ID},
+	{LOG_DUMP_SECTION_ECNTRS, DEBUG_DUMP_RING2_ID},
+	{LOG_DUMP_SECTION_STATUS, DEBUG_DUMP_RING1_ID},
+	{LOG_DUMP_SECTION_RTT, DEBUG_DUMP_RING2_ID},
+	{LOG_DUMP_SECTION_PKTID_MAP_LOG, DEBUG_DUMP_RING2_ID},
+	{LOG_DUMP_SECTION_PKTID_UNMAP_LOG, DEBUG_DUMP_RING2_ID},
+	{LOG_DUMP_SECTION_DHD_DUMP, DEBUG_DUMP_RING1_ID},
+	{LOG_DUMP_SECTION_EXT_TRAP, DEBUG_DUMP_RING1_ID},
+	{LOG_DUMP_SECTION_HEALTH_CHK, DEBUG_DUMP_RING1_ID},
+	{LOG_DUMP_SECTION_COOKIE, DEBUG_DUMP_RING1_ID},
+	{LOG_DUMP_SECTION_RING, DEBUG_DUMP_RING1_ID},
+};
+#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
+
+int
+dhd_log_flush(dhd_pub_t *dhdp, log_dump_type_t *type)
+{
+	unsigned long flags = 0;
+#ifdef EWP_EDL
+	int i = 0;
+#endif /* EWP_EDL */
+	dhd_info_t *dhd_info = NULL;
+
+	BCM_REFERENCE(dhd_info);
+
+	/* if dhdp is null, its extremely unlikely that log dump will be scheduled
+	 * so not freeing 'type' here is ok, even if we want to free 'type'
+	 * we cannot do so, since 'dhdp->osh' is unavailable
+	 * as dhdp is null
+	 */
+	if (!dhdp || !type) {
+		if (dhdp) {
+			DHD_GENERAL_LOCK(dhdp, flags);
+			DHD_BUS_BUSY_CLEAR_IN_LOGDUMP(dhdp);
+			dhd_os_busbusy_wake(dhdp);
+			DHD_GENERAL_UNLOCK(dhdp, flags);
+		}
+		return BCME_ERROR;
+	}
+
+#if defined(BCMPCIE)
+	if (dhd_bus_get_linkdown(dhdp)) {
+		/* As link is down donot collect any data over PCIe.
+		 * Also return BCME_OK to caller, so that caller can
+		 * dump all the outstanding data to file
+		 */
+		return BCME_OK;
+	}
+#endif /* BCMPCIE */
+
+	dhd_info = (dhd_info_t *)dhdp->info;
+	/* in case of trap get preserve logs from ETD */
+#if defined(BCMPCIE) && defined(EWP_ETD_PRSRV_LOGS)
+	if (dhdp->dongle_trap_occured &&
+			dhdp->extended_trap_data) {
+		dhdpcie_get_etd_preserve_logs(dhdp, (uint8 *)dhdp->extended_trap_data,
+				&dhd_info->event_data);
+	}
+#endif /* BCMPCIE */
+
+	/* flush the event work items to get any fw events/logs
+	 * flush_work is a blocking call
+	 */
+#ifdef SHOW_LOGTRACE
+#ifdef EWP_EDL
+	if (dhd_info->pub.dongle_edl_support) {
+		/* wait till existing edl items are processed */
+		dhd_flush_logtrace_process(dhd_info);
+		/* dhd_flush_logtrace_process will ensure the work items in the ring
+		* (EDL ring) from rd to wr are processed. But if wr had
+		* wrapped around, only the work items from rd to ring-end are processed.
+		* So to ensure that the work items at the
+		* beginning of ring are also processed in the wrap around case, call
+		* it twice
+		*/
+		for (i = 0; i < 2; i++) {
+			/* blocks till the edl items are processed */
+			dhd_flush_logtrace_process(dhd_info);
+		}
+	} else {
+		dhd_flush_logtrace_process(dhd_info);
+	}
+#else
+	dhd_flush_logtrace_process(dhd_info);
+#endif /* EWP_EDL */
+#endif /* SHOW_LOGTRACE */
+
+	return BCME_OK;
+}
+
+void
+dhd_log_dump(void *handle, void *event_info, u8 event)
+{
+	dhd_info_t *dhd = handle;
+	log_dump_type_t *type = (log_dump_type_t *)event_info;
+
+	if (!dhd || !type) {
+		DHD_ERROR(("%s: dhd/type is NULL\n", __FUNCTION__));
+		return;
+	}
+
+#ifdef WL_CFG80211
+	/* flush the fw preserve logs */
+	wl_flush_fw_log_buffer(dhd_linux_get_primary_netdev(&dhd->pub),
+		FW_LOGSET_MASK_ALL);
+#endif
+
+	/* there are currently 3 possible contexts from which
+	 * log dump can be scheduled -
+	 * 1.TRAP 2.supplicant DEBUG_DUMP pvt driver command
+	 * 3.HEALTH CHECK event
+	 * The concise debug info buffer is a shared resource
+	 * and in case a trap is one of the contexts then both the
+	 * scheduled work queues need to run because trap data is
+	 * essential for debugging. Hence a mutex lock is acquired
+	 * before calling do_dhd_log_dump().
+	 */
+	DHD_ERROR(("%s: calling log dump.. \n", __FUNCTION__));
+	dhd_os_logdump_lock(&dhd->pub);
+	DHD_OS_WAKE_LOCK(&dhd->pub);
+	if (do_dhd_log_dump(&dhd->pub, type) != BCME_OK) {
+		DHD_ERROR(("%s: writing debug dump to the file failed\n", __FUNCTION__));
+	}
+	DHD_OS_WAKE_UNLOCK(&dhd->pub);
+	dhd_os_logdump_unlock(&dhd->pub);
+}
+
+void dhd_schedule_log_dump(dhd_pub_t *dhdp, void *type)
+{
+	DHD_ERROR(("%s: scheduling log dump.. \n", __FUNCTION__));
+
+	dhd_deferred_schedule_work(dhdp->info->dhd_deferred_wq,
+		type, DHD_WQ_WORK_DHD_LOG_DUMP,
+		dhd_log_dump, DHD_WQ_WORK_PRIORITY_HIGH);
+}
+
+void
+dhd_print_buf_addr(dhd_pub_t *dhdp, char *name, void *buf, unsigned int size)
+{
+#ifdef DHD_FW_COREDUMP
+	if ((dhdp->memdump_enabled == DUMP_MEMONLY) ||
+		(dhdp->memdump_enabled == DUMP_MEMFILE_BUGON) ||
+		(dhdp->memdump_type == DUMP_TYPE_SMMU_FAULT) ||
+#ifdef DHD_DETECT_CONSECUTIVE_MFG_HANG
+		(dhdp->op_mode & DHD_FLAG_MFG_MODE &&
+			(dhdp->hang_count >= MAX_CONSECUTIVE_MFG_HANG_COUNT-1)) ||
+#endif /* DHD_DETECT_CONSECUTIVE_MFG_HANG */
+		FALSE)
+#else
+	if (dhdp->memdump_type == DUMP_TYPE_SMMU_FAULT)
+#endif
+	{
+#if defined(CONFIG_ARM64)
+		DHD_ERROR(("-------- %s: buf(va)=%llx, buf(pa)=%llx, bufsize=%d\n",
+			name, (uint64)buf, (uint64)__virt_to_phys((ulong)buf), size));
+#elif defined(__ARM_ARCH_7A__)
+		DHD_ERROR(("-------- %s: buf(va)=%x, buf(pa)=%x, bufsize=%d\n",
+			name, (uint32)buf, (uint32)__virt_to_phys((ulong)buf), size));
+#endif /* __ARM_ARCH_7A__ */
+	}
+}
+
+void
+dhd_log_dump_buf_addr(dhd_pub_t *dhdp, log_dump_type_t *type)
+{
+	int i;
+	unsigned long wr_size = 0;
+	struct dhd_log_dump_buf *dld_buf = &g_dld_buf[0];
+	size_t log_size = 0;
+	char buf_name[DHD_PRINT_BUF_NAME_LEN];
+	dhd_dbg_ring_t *ring = NULL;
+
+	BCM_REFERENCE(ring);
+
+	for (i = 0; i < DLD_BUFFER_NUM; i++) {
+		dld_buf = &g_dld_buf[i];
+		log_size = (unsigned long)dld_buf->max -
+			(unsigned long)dld_buf->buffer;
+		if (dld_buf->wraparound) {
+			wr_size = log_size;
+		} else {
+			wr_size = (unsigned long)dld_buf->present -
+				(unsigned long)dld_buf->front;
+		}
+		scnprintf(buf_name, sizeof(buf_name), "dlb_buf[%d]", i);
+		dhd_print_buf_addr(dhdp, buf_name, dld_buf, dld_buf_size[i]);
+		scnprintf(buf_name, sizeof(buf_name), "dlb_buf[%d] buffer", i);
+		dhd_print_buf_addr(dhdp, buf_name, dld_buf->buffer, wr_size);
+		scnprintf(buf_name, sizeof(buf_name), "dlb_buf[%d] present", i);
+		dhd_print_buf_addr(dhdp, buf_name, dld_buf->present, wr_size);
+		scnprintf(buf_name, sizeof(buf_name), "dlb_buf[%d] front", i);
+		dhd_print_buf_addr(dhdp, buf_name, dld_buf->front, wr_size);
+	}
+
+#ifdef DEBUGABILITY_ECNTRS_LOGGING
+	/* periodic flushing of ecounters is NOT supported */
+	if (*type == DLD_BUF_TYPE_ALL &&
+			logdump_ecntr_enable &&
+			dhdp->ecntr_dbg_ring) {
+
+		ring = (dhd_dbg_ring_t *)dhdp->ecntr_dbg_ring;
+		dhd_print_buf_addr(dhdp, "ecntr_dbg_ring", ring, LOG_DUMP_ECNTRS_MAX_BUFSIZE);
+		dhd_print_buf_addr(dhdp, "ecntr_dbg_ring ring_buf", ring->ring_buf,
+				LOG_DUMP_ECNTRS_MAX_BUFSIZE);
+	}
+#endif /* DEBUGABILITY_ECNTRS_LOGGING */
+
+#if defined(BCMPCIE)
+	if (dhdp->dongle_trap_occured && dhdp->extended_trap_data) {
+		dhd_print_buf_addr(dhdp, "extended_trap_data", dhdp->extended_trap_data,
+				BCMPCIE_EXT_TRAP_DATA_MAXLEN);
+	}
+#endif /* BCMPCIE */
+
+#if defined(DHD_FW_COREDUMP) && defined(DNGL_EVENT_SUPPORT)
+	/* if health check event was received */
+	if (dhdp->memdump_type == DUMP_TYPE_DONGLE_HOST_EVENT) {
+		dhd_print_buf_addr(dhdp, "health_chk_event_data", dhdp->health_chk_event_data,
+				HEALTH_CHK_BUF_SIZE);
+	}
+#endif /* DHD_FW_COREDUMP && DNGL_EVENT_SUPPORT */
+
+	/* append the concise debug information */
+	if (dhdp->concise_dbg_buf) {
+		dhd_print_buf_addr(dhdp, "concise_dbg_buf", dhdp->concise_dbg_buf,
+				CONCISE_DUMP_BUFLEN);
+	}
+}
+
+#ifdef DHD_SSSR_DUMP
+#ifdef DHD_COREDUMP
+extern dhd_coredump_t dhd_coredump_types[];
+#endif /* DHD_COREDUMP */
+int
+dhdpcie_sssr_dump_get_before_after_len(dhd_pub_t *dhd, uint32 *arr_len)
+{
+	int i = 0;
+	uint dig_buf_size = 0;
+
+	DHD_ERROR(("%s\n", __FUNCTION__));
+
+	/* core 0 */
+	i = 0;
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+	if (dhd->sssr_d11_before[i] && dhd->sssr_d11_outofreset[i] &&
+		(dhd->sssr_dump_mode == SSSR_DUMP_MODE_SSSR)) {
+#ifdef DHD_COREDUMP
+		dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_CORE0_BEFORE].length =
+#endif /* DHD_COREDUMP */
+			arr_len[SSSR_C0_D11_BEFORE] = dhd_sssr_mac_buf_size(dhd, i);
+		DHD_ERROR(("%s: arr_len[SSSR_C0_D11_BEFORE] : %d\n", __FUNCTION__,
+			arr_len[SSSR_C0_D11_BEFORE]));
+#ifdef DHD_LOG_DUMP
+		dhd_print_buf_addr(dhd, "SSSR_C0_D11_BEFORE",
+			dhd->sssr_d11_before[i], arr_len[SSSR_C0_D11_BEFORE]);
+#endif /* DHD_LOG_DUMP */
+#ifdef DHD_COREDUMP
+		dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_CORE0_BEFORE].bufptr =
+			dhd->sssr_d11_before[i];
+#endif /* DHD_COREDUMP */
+	}
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+	if (dhd->sssr_d11_after[i] && dhd->sssr_d11_outofreset[i]) {
+#ifdef DHD_COREDUMP
+		dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_CORE0_AFTER].length =
+#endif /* DHD_COREDUMP */
+			arr_len[SSSR_C0_D11_AFTER] = dhd_sssr_mac_buf_size(dhd, i);
+		DHD_ERROR(("%s: arr_len[SSSR_C0_D11_AFTER] : %d\n", __FUNCTION__,
+			arr_len[SSSR_C0_D11_AFTER]));
+#ifdef DHD_LOG_DUMP
+		dhd_print_buf_addr(dhd, "SSSR_C0_D11_AFTER",
+			dhd->sssr_d11_after[i], arr_len[SSSR_C0_D11_AFTER]);
+#endif /* DHD_LOG_DUMP */
+#ifdef DHD_COREDUMP
+		dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_CORE0_AFTER].bufptr =
+			dhd->sssr_d11_after[i];
+#endif /* DHD_COREDUMP */
+	}
+
+	/* core 1 */
+	i = 1;
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+	if (dhd->sssr_d11_before[i] && dhd->sssr_d11_outofreset[i] &&
+		(dhd->sssr_dump_mode == SSSR_DUMP_MODE_SSSR)) {
+#ifdef DHD_COREDUMP
+		dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_CORE1_BEFORE].length =
+#endif /* DHD_COREDUMP */
+			arr_len[SSSR_C1_D11_BEFORE] = dhd_sssr_mac_buf_size(dhd, i);
+		DHD_ERROR(("%s: arr_len[SSSR_C1_D11_BEFORE] : %d\n", __FUNCTION__,
+			arr_len[SSSR_C1_D11_BEFORE]));
+#ifdef DHD_LOG_DUMP
+		dhd_print_buf_addr(dhd, "SSSR_C1_D11_BEFORE",
+			dhd->sssr_d11_before[i], arr_len[SSSR_C1_D11_BEFORE]);
+#endif /* DHD_LOG_DUMP */
+#ifdef DHD_COREDUMP
+		dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_CORE1_BEFORE].bufptr =
+			dhd->sssr_d11_before[i];
+#endif /* DHD_COREDUMP */
+	}
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+	if (dhd->sssr_d11_after[i] && dhd->sssr_d11_outofreset[i]) {
+#ifdef DHD_COREDUMP
+		dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_CORE1_AFTER].length =
+#endif /* DHD_COREDUMP */
+			arr_len[SSSR_C1_D11_AFTER] = dhd_sssr_mac_buf_size(dhd, i);
+		DHD_ERROR(("%s: arr_len[SSSR_C1_D11_AFTER] : %d\n", __FUNCTION__,
+			arr_len[SSSR_C1_D11_AFTER]));
+#ifdef DHD_LOG_DUMP
+		dhd_print_buf_addr(dhd, "SSSR_C1_D11_AFTER",
+			dhd->sssr_d11_after[i], arr_len[SSSR_C1_D11_AFTER]);
+#endif /* DHD_LOG_DUMP */
+#ifdef DHD_COREDUMP
+		dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_CORE1_AFTER].bufptr =
+			dhd->sssr_d11_after[i];
+#endif /* DHD_COREDUMP */
+	}
+
+	/* core 2 scan core */
+	if (dhd->sssr_reg_info->rev2.version >= SSSR_REG_INFO_VER_2) {
+		i = 2;
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+		if (dhd->sssr_d11_before[i] && dhd->sssr_d11_outofreset[i] &&
+			(dhd->sssr_dump_mode == SSSR_DUMP_MODE_SSSR)) {
+#ifdef DHD_COREDUMP
+			dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_CORE2_BEFORE].length =
+#endif /* DHD_COREDUMP */
+				arr_len[SSSR_C2_D11_BEFORE] = dhd_sssr_mac_buf_size(dhd, i);
+			DHD_ERROR(("%s: arr_len[SSSR_C2_D11_BEFORE] : %d\n", __FUNCTION__,
+				arr_len[SSSR_C2_D11_BEFORE]));
+#ifdef DHD_LOG_DUMP
+			dhd_print_buf_addr(dhd, "SSSR_C2_D11_BEFORE",
+				dhd->sssr_d11_before[i], arr_len[SSSR_C2_D11_BEFORE]);
+#endif /* DHD_LOG_DUMP */
+#ifdef DHD_COREDUMP
+		dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_CORE2_BEFORE].bufptr =
+			dhd->sssr_d11_before[i];
+#endif /* DHD_COREDUMP */
+		}
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+		if (dhd->sssr_d11_after[i] && dhd->sssr_d11_outofreset[i]) {
+#ifdef DHD_COREDUMP
+			dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_CORE2_AFTER].length =
+#endif /* DHD_COREDUMP */
+				arr_len[SSSR_C2_D11_AFTER]  = dhd_sssr_mac_buf_size(dhd, i);
+			DHD_ERROR(("%s: arr_len[SSSR_C2_D11_AFTER] : %d\n", __FUNCTION__,
+				arr_len[SSSR_C2_D11_AFTER]));
+#ifdef DHD_LOG_DUMP
+			dhd_print_buf_addr(dhd, "SSSR_C2_D11_AFTER",
+				dhd->sssr_d11_after[i], arr_len[SSSR_C2_D11_AFTER]);
+#endif /* DHD_LOG_DUMP */
+#ifdef DHD_COREDUMP
+			dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_CORE2_AFTER].bufptr =
+				dhd->sssr_d11_after[i];
+#endif /* DHD_COREDUMP */
+		}
+	}
+
+	/* DIG core or VASIP */
+	dig_buf_size = dhd_sssr_dig_buf_size(dhd);
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+#ifdef DHD_COREDUMP
+	dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_DIG_BEFORE].length =
+#endif /* DHD_COREDUMP */
+		arr_len[SSSR_DIG_BEFORE] = (dhd->sssr_dig_buf_before) ? dig_buf_size : 0;
+	DHD_ERROR(("%s: arr_len[SSSR_DIG_BEFORE] : %d\n", __FUNCTION__,
+		arr_len[SSSR_DIG_BEFORE]));
+#ifdef DHD_LOG_DUMP
+	if (dhd->sssr_dig_buf_before) {
+		dhd_print_buf_addr(dhd, "SSSR_DIG_BEFORE",
+			dhd->sssr_dig_buf_before, arr_len[SSSR_DIG_BEFORE]);
+	}
+#endif /* DHD_LOG_DUMP */
+#ifdef DHD_COREDUMP
+	dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_DIG_BEFORE].bufptr =
+		dhd->sssr_dig_buf_before;
+#endif /* DHD_COREDUMP */
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+
+#ifdef DHD_COREDUMP
+	dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_DIG_AFTER].length =
+#endif /* DHD_COREDUMP */
+		arr_len[SSSR_DIG_AFTER] = (dhd->sssr_dig_buf_after) ? dig_buf_size : 0;
+	DHD_ERROR(("%s: arr_len[SSSR_DIG_AFTER] : %d\n", __FUNCTION__,
+		arr_len[SSSR_DIG_AFTER]));
+#ifdef DHD_LOG_DUMP
+	if (dhd->sssr_dig_buf_after) {
+		dhd_print_buf_addr(dhd, "SSSR_DIG_AFTER",
+			dhd->sssr_dig_buf_after, arr_len[SSSR_DIG_AFTER]);
+	}
+#endif /* DHD_LOG_DUMP */
+#ifdef DHD_COREDUMP
+	dhd_coredump_types[DHD_COREDUMP_TYPE_SSSRDUMP_DIG_AFTER].bufptr =
+		dhd->sssr_dig_buf_after;
+#endif /* DHD_COREDUMP */
+
+	return BCME_OK;
+}
+
+void
+dhd_nla_put_sssr_dump_len(void *ndev, uint32 *arr_len)
+{
+	dhd_info_t *dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)ndev);
+	dhd_pub_t *dhdp = &dhd_info->pub;
+
+	if (dhdp->sssr_dump_collected) {
+		dhdpcie_sssr_dump_get_before_after_len(dhdp, arr_len);
+	}
+}
+#endif /* DHD_SSSR_DUMP */
+
+uint32
+dhd_get_time_str_len(void)
+{
+	char *ts = NULL, time_str[128];
+
+	ts = dhd_log_dump_get_timestamp();
+	snprintf(time_str, sizeof(time_str),
+			"\n\n ========== LOG DUMP TAKEN AT : %s =========\n", ts);
+	return strlen(time_str);
+}
+
+#if defined(BCMPCIE)
+uint32
+dhd_get_ext_trap_len(void *ndev, dhd_pub_t *dhdp)
+{
+	int length = 0;
+	log_dump_section_hdr_t sec_hdr;
+	dhd_info_t *dhd_info;
+
+	if (ndev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)ndev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return length;
+
+	if (dhdp->extended_trap_data) {
+		length = (strlen(EXT_TRAP_LOG_HDR)
+					+ sizeof(sec_hdr) + BCMPCIE_EXT_TRAP_DATA_MAXLEN);
+	}
+	return length;
+}
+#endif /* BCMPCIE */
+
+#if defined(DHD_FW_COREDUMP) && defined(DNGL_EVENT_SUPPORT)
+uint32
+dhd_get_health_chk_len(void *ndev, dhd_pub_t *dhdp)
+{
+	int length = 0;
+	log_dump_section_hdr_t sec_hdr;
+	dhd_info_t *dhd_info;
+
+	if (ndev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)ndev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return length;
+
+	if (dhdp->memdump_type == DUMP_TYPE_DONGLE_HOST_EVENT) {
+		length = (strlen(HEALTH_CHK_LOG_HDR)
+			+ sizeof(sec_hdr) + HEALTH_CHK_BUF_SIZE);
+	}
+	return length;
+}
+#endif /* DHD_FW_COREDUMP && DNGL_EVENT_SUPPORT */
+
+uint32
+dhd_get_dhd_dump_len(void *ndev, dhd_pub_t *dhdp)
+{
+	uint32 length = 0;
+	log_dump_section_hdr_t sec_hdr;
+	dhd_info_t *dhd_info;
+	int remain_len = 0;
+
+	if (ndev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)ndev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return length;
+
+	if (dhdp->concise_dbg_buf) {
+		remain_len = dhd_dump(dhdp, (char *)dhdp->concise_dbg_buf, CONCISE_DUMP_BUFLEN);
+		 if (remain_len <= 0 || remain_len >= CONCISE_DUMP_BUFLEN) {
+			DHD_ERROR(("%s: error getting concise debug info ! remain_len: %d\n",
+				__FUNCTION__, remain_len));
+			return length;
+		}
+
+		length += (uint32)(CONCISE_DUMP_BUFLEN - remain_len);
+	}
+
+	length += (uint32)(strlen(DHD_DUMP_LOG_HDR) + sizeof(sec_hdr));
+	return length;
+}
+
+#ifdef EWP_RTT_LOGGING
+uint32
+dhd_get_rtt_len(void *ndev, dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd_info;
+	log_dump_section_hdr_t sec_hdr;
+	int length = 0;
+	dhd_dbg_ring_t *ring;
+
+	if (ndev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)ndev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return length;
+
+	if (logdump_rtt_enable && dhdp->rtt_dbg_ring) {
+		ring = (dhd_dbg_ring_t *)dhdp->rtt_dbg_ring;
+		length = ring->ring_size + strlen(RTT_LOG_HDR) + sizeof(sec_hdr);
+	}
+	return length;
+}
+#endif /* EWP_RTT_LOGGING */
+
+uint32
+dhd_get_cookie_log_len(void *ndev, dhd_pub_t *dhdp)
+{
+	int length = 0;
+	dhd_info_t *dhd_info;
+
+	if (ndev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)ndev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return length;
+
+	if (dhdp->logdump_cookie && dhd_logdump_cookie_count(dhdp) > 0) {
+		length = dhd_log_dump_cookie_len(dhdp);
+	}
+	return length;
+
+}
+
+#ifdef DHD_DUMP_PCIE_RINGS
+uint32
+dhd_get_flowring_len(void *ndev, dhd_pub_t *dhdp)
+{
+	uint32 length = 0;
+	log_dump_section_hdr_t sec_hdr;
+	dhd_info_t *dhd_info;
+	uint16 max_tx_flowrings;
+
+	if (ndev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)ndev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return length;
+
+	length += (uint32) strlen(RING_DUMP_HDR);
+	length += (uint32) sizeof(sec_hdr);
+	length += (uint32) sizeof(max_tx_flowrings);
+	max_tx_flowrings = dhd_get_max_flow_rings(dhdp);
+	/* max_item and item_size value which is of 4bytes is dumped at
+	 * start of each ring dump, so adding 4bytes to total length.
+	 */
+	length += (uint32) ((D2HRING_TXCMPLT_ITEMSIZE * d2h_max_txcpl)
+				+ (sizeof(uint16) * 2)
+				+ (H2DRING_RXPOST_ITEMSIZE * h2d_max_rxpost)
+				+ (sizeof(uint16) * 2)
+				+ (D2HRING_RXCMPLT_ITEMSIZE * d2h_max_rxcpl)
+				+ (sizeof(uint16) * 2)
+				+ (H2DRING_CTRL_SUB_ITEMSIZE * h2d_max_ctrlpost)
+				+ (sizeof(uint16) * 2)
+				+ (D2HRING_CTRL_CMPLT_ITEMSIZE * d2h_max_ctrlcpl)
+				+ (sizeof(uint16) * 2)
+#ifdef EWP_EDL
+				/* EDL ring doesn't have max_item and item_size */
+				+ (D2HRING_EDL_HDR_SIZE * D2HRING_EDL_MAX_ITEM));
+#else
+				+ (H2DRING_INFO_BUFPOST_ITEMSIZE * H2DRING_DYNAMIC_INFO_MAX_ITEM)
+				+ (sizeof(uint16) * 2)
+				+ (D2HRING_INFO_BUFCMPLT_ITEMSIZE * D2HRING_DYNAMIC_INFO_MAX_ITEM)
+				+ (sizeof(uint16) * 2));
+#endif /* EWP_EDL */
+
+	if (dhdp->htput_support) {
+		/* flowring lengths are different for HTPUT rings, handle accordingly */
+		length += ((H2DRING_TXPOST_ITEMSIZE * h2d_htput_max_txpost *
+			HTPUT_TOTAL_FLOW_RINGS) +
+			(H2DRING_TXPOST_ITEMSIZE * h2d_max_txpost *
+			(max_tx_flowrings - HTPUT_TOTAL_FLOW_RINGS)));
+	} else {
+		length += (H2DRING_TXPOST_ITEMSIZE * h2d_max_txpost *
+			max_tx_flowrings);
+	}
+	length += max_tx_flowrings * (sizeof(uint16) * 2);
+
+	return length;
+}
+#endif /* DHD_DUMP_PCIE_RINGS */
+
+#ifdef EWP_ECNTRS_LOGGING
+uint32
+dhd_get_ecntrs_len(void *ndev, dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd_info;
+	log_dump_section_hdr_t sec_hdr;
+	int length = 0;
+	dhd_dbg_ring_t *ring;
+
+	if (ndev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)ndev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return length;
+
+	if (logdump_ecntr_enable && dhdp->ecntr_dbg_ring) {
+		ring = (dhd_dbg_ring_t *)dhdp->ecntr_dbg_ring;
+		length = ring->ring_size + strlen(ECNTRS_LOG_HDR) + sizeof(sec_hdr);
+	}
+	return length;
+}
+#endif /* EWP_ECNTRS_LOGGING */
+
+int
+dhd_get_dld_log_dump(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, int type, void *pos)
+{
+	int ret = BCME_OK;
+	struct dhd_log_dump_buf *dld_buf;
+	log_dump_section_hdr_t sec_hdr;
+	dhd_info_t *dhd_info;
+
+	dld_buf = &g_dld_buf[type];
+
+	if (dev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+		dhdp = &dhd_info->pub;
+	} else if (!dhdp) {
+		return BCME_ERROR;
+	}
+
+	DHD_ERROR(("%s: ENTER \n", __FUNCTION__));
+
+	dhd_init_sec_hdr(&sec_hdr);
+
+	/* write the section header first */
+	ret = dhd_export_debug_data(dld_hdrs[type].hdr_str, fp, user_buf,
+		strlen(dld_hdrs[type].hdr_str), pos);
+	if (ret < 0)
+		goto exit;
+	len -= (uint32)strlen(dld_hdrs[type].hdr_str);
+	len -= (uint32)sizeof(sec_hdr);
+	sec_hdr.type = dld_hdrs[type].sec_type;
+	sec_hdr.length = len;
+	ret = dhd_export_debug_data((char *)&sec_hdr, fp, user_buf, sizeof(sec_hdr), pos);
+	if (ret < 0)
+		goto exit;
+	ret = dhd_export_debug_data(dld_buf->buffer, fp, user_buf, len, pos);
+	if (ret < 0)
+		goto exit;
+
+exit:
+	return ret;
+}
+
+int
+dhd_get_debug_dump_file_name(void *dev, dhd_pub_t *dhdp, char *dump_path, int size)
+{
+	int ret;
+	int len = 0;
+	dhd_info_t *dhd_info;
+
+	if (dev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return BCME_ERROR;
+
+	memset(dump_path, 0, size);
+
+	ret = snprintf(dump_path, size, "%s",
+			DHD_COMMON_DUMP_PATH DHD_DEBUG_DUMP_TYPE);
+	len += ret;
+
+	/* Keep the same timestamp across different dump logs */
+	if (!dhdp->logdump_periodic_flush) {
+		struct rtc_time tm;
+#ifdef DHD_LOG_DUMP
+		clear_debug_dump_time(dhdp->debug_dump_time_str);
+		get_debug_dump_time(dhdp->debug_dump_time_str);
+#endif /* DHD_LOG_DUMP */
+		sscanf(dhdp->debug_dump_time_str, DHD_LOG_DUMP_TS_FMT_YYMMDDHHMMSS,
+			&tm.tm_year, &tm.tm_mon, &tm.tm_mday,
+			&tm.tm_hour, &tm.tm_min, &tm.tm_sec);
+		ret = snprintf(dump_path + len, size - len, "_" DHD_LOG_DUMP_TS_FMT_YYMMDDHHMMSS,
+				tm.tm_year, tm.tm_mon, tm.tm_mday,
+				tm.tm_hour, tm.tm_min, tm.tm_sec);
+		len += ret;
+	}
+
+	ret = 0;
+	switch (dhdp->debug_dump_subcmd) {
+	case CMD_UNWANTED:
+		ret = snprintf(dump_path + len, size - len, "%s", DHD_DUMP_SUBSTR_UNWANTED);
+		break;
+	case CMD_DISCONNECTED:
+		ret = snprintf(dump_path + len, size - len, "%s", DHD_DUMP_SUBSTR_DISCONNECTED);
+		break;
+	default:
+		break;
+	}
+	len += ret;
+
+	return BCME_OK;
+}
+
+uint32
+dhd_get_dld_len(int log_type)
+{
+	unsigned long wr_size = 0;
+	unsigned long buf_size = 0;
+	unsigned long flags = 0;
+	struct dhd_log_dump_buf *dld_buf;
+	log_dump_section_hdr_t sec_hdr;
+
+	/* calculate the length of the log */
+	dld_buf = &g_dld_buf[log_type];
+	buf_size = (unsigned long)dld_buf->max -
+			(unsigned long)dld_buf->buffer;
+
+	if (dld_buf->wraparound) {
+		wr_size = buf_size;
+	} else {
+		/* need to hold the lock before accessing 'present' and 'remain' ptrs */
+		DHD_LOG_DUMP_BUF_LOCK(&dld_buf->lock, flags);
+		wr_size = (unsigned long)dld_buf->present -
+				(unsigned long)dld_buf->front;
+		DHD_LOG_DUMP_BUF_UNLOCK(&dld_buf->lock, flags);
+	}
+	return (wr_size + sizeof(sec_hdr) + strlen(dld_hdrs[log_type].hdr_str));
+}
+
+static void
+dhd_get_time_str(dhd_pub_t *dhdp, char *time_str, int size)
+{
+	char *ts = NULL;
+	memset(time_str, 0, size);
+	ts = dhd_log_dump_get_timestamp();
+	snprintf(time_str, size,
+			"\n\n ========== LOG DUMP TAKEN AT : %s =========\n", ts);
+}
+
+int
+dhd_print_time_str(const void *user_buf, void *fp, uint32 len, void *pos)
+{
+	char *ts = NULL;
+	int ret = 0;
+	char time_str[128];
+
+	memset_s(time_str, sizeof(time_str), 0, sizeof(time_str));
+	ts = dhd_log_dump_get_timestamp();
+	snprintf(time_str, sizeof(time_str),
+			"\n\n ========== LOG DUMP TAKEN AT : %s =========\n", ts);
+
+	/* write the timestamp hdr to the file first */
+	ret = dhd_export_debug_data(time_str, fp, user_buf, strlen(time_str), pos);
+	if (ret < 0) {
+		DHD_ERROR(("write file error, err = %d\n", ret));
+	}
+	return ret;
+}
+
+#if defined(DHD_FW_COREDUMP) && defined(DNGL_EVENT_SUPPORT)
+int
+dhd_print_health_chk_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, void *pos)
+{
+	int ret = BCME_OK;
+	log_dump_section_hdr_t sec_hdr;
+	dhd_info_t *dhd_info;
+
+	if (dev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return BCME_ERROR;
+
+	dhd_init_sec_hdr(&sec_hdr);
+
+	if (dhdp->memdump_type == DUMP_TYPE_DONGLE_HOST_EVENT) {
+		/* write the section header first */
+		ret = dhd_export_debug_data(HEALTH_CHK_LOG_HDR, fp, user_buf,
+			strlen(HEALTH_CHK_LOG_HDR), pos);
+		if (ret < 0)
+			goto exit;
+
+		len -= (uint32)strlen(HEALTH_CHK_LOG_HDR);
+		sec_hdr.type = LOG_DUMP_SECTION_HEALTH_CHK;
+		sec_hdr.length = HEALTH_CHK_BUF_SIZE;
+		ret = dhd_export_debug_data((char *)&sec_hdr, fp, user_buf, sizeof(sec_hdr), pos);
+		if (ret < 0)
+			goto exit;
+
+		len -= (uint32)sizeof(sec_hdr);
+		/* write the log */
+		ret = dhd_export_debug_data((char *)dhdp->health_chk_event_data, fp,
+			user_buf, len, pos);
+		if (ret < 0)
+			goto exit;
+	}
+exit:
+	return ret;
+}
+#endif /* DHD_FW_COREDUMP && DNGL_EVENT_SUPPORT */
+
+#if defined(BCMPCIE)
+int
+dhd_print_ext_trap_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, void *pos)
+{
+	int ret = BCME_OK;
+	log_dump_section_hdr_t sec_hdr;
+	dhd_info_t *dhd_info;
+
+	if (dev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return BCME_ERROR;
+
+	dhd_init_sec_hdr(&sec_hdr);
+
+	/* append extended trap data to the file in case of traps */
+	if (dhdp->dongle_trap_occured &&
+			dhdp->extended_trap_data) {
+		/* write the section header first */
+		ret = dhd_export_debug_data(EXT_TRAP_LOG_HDR, fp, user_buf,
+			strlen(EXT_TRAP_LOG_HDR), pos);
+		if (ret < 0)
+			goto exit;
+
+		len -= (uint32)strlen(EXT_TRAP_LOG_HDR);
+		sec_hdr.type = LOG_DUMP_SECTION_EXT_TRAP;
+		sec_hdr.length = BCMPCIE_EXT_TRAP_DATA_MAXLEN;
+		ret = dhd_export_debug_data((uint8 *)&sec_hdr, fp, user_buf, sizeof(sec_hdr), pos);
+		if (ret < 0)
+			goto exit;
+
+		len -= (uint32)sizeof(sec_hdr);
+		/* write the log */
+		ret = dhd_export_debug_data((uint8 *)dhdp->extended_trap_data, fp,
+			user_buf, len, pos);
+		if (ret < 0)
+			goto exit;
+	}
+exit:
+	return ret;
+}
+#endif /* BCMPCIE */
+
+int
+dhd_print_dump_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, void *pos)
+{
+	int ret = BCME_OK;
+	log_dump_section_hdr_t sec_hdr;
+	dhd_info_t *dhd_info;
+
+	if (dev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return BCME_ERROR;
+
+	dhd_init_sec_hdr(&sec_hdr);
+
+	ret = dhd_export_debug_data(DHD_DUMP_LOG_HDR, fp, user_buf, strlen(DHD_DUMP_LOG_HDR), pos);
+	if (ret < 0)
+		goto exit;
+
+	len -= (uint32)strlen(DHD_DUMP_LOG_HDR);
+	sec_hdr.type = LOG_DUMP_SECTION_DHD_DUMP;
+	sec_hdr.length = len;
+	ret = dhd_export_debug_data((char *)&sec_hdr, fp, user_buf, sizeof(sec_hdr), pos);
+	if (ret < 0)
+		goto exit;
+
+	len -= (uint32)sizeof(sec_hdr);
+
+	if (dhdp->concise_dbg_buf) {
+		dhd_dump(dhdp, (char *)dhdp->concise_dbg_buf, CONCISE_DUMP_BUFLEN);
+		ret = dhd_export_debug_data(dhdp->concise_dbg_buf, fp, user_buf, len, pos);
+		if (ret < 0)
+			goto exit;
+	}
+
+exit:
+	return ret;
+}
+
+int
+dhd_print_cookie_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, void *pos)
+{
+	int ret = BCME_OK;
+	dhd_info_t *dhd_info;
+
+	if (dev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return BCME_ERROR;
+
+	if (dhdp->logdump_cookie && dhd_logdump_cookie_count(dhdp) > 0) {
+		ret = dhd_log_dump_cookie_to_file(dhdp, fp, user_buf, (unsigned long *)pos);
+	}
+	return ret;
+}
+
+#ifdef DHD_DUMP_PCIE_RINGS
+int
+dhd_print_flowring_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+		void *fp, uint32 len, void *pos)
+{
+	log_dump_section_hdr_t sec_hdr;
+	int ret = BCME_OK;
+	uint16 max_tx_flowrings;
+	dhd_info_t *dhd_info;
+
+	if (dev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return BCME_ERROR;
+
+	dhd_init_sec_hdr(&sec_hdr);
+
+	/* write the section header first */
+	ret = dhd_export_debug_data(RING_DUMP_HDR, fp, user_buf,
+		strlen(RING_DUMP_HDR), pos);
+	if (ret < 0)
+		goto exit;
+	len -= strlen(RING_DUMP_HDR);
+
+	sec_hdr.type = LOG_DUMP_SECTION_RING;
+	sec_hdr.length = len - sizeof(sec_hdr);
+	ret = dhd_export_debug_data((char *)&sec_hdr, fp, user_buf, sizeof(sec_hdr), pos);
+	if (ret < 0)
+		goto exit;
+
+	max_tx_flowrings =  dhd_get_max_flow_rings(dhdp);
+	/* write the number of max_tx_flowrings after section header */
+	ret = dhd_export_debug_data((char *)&max_tx_flowrings, fp, user_buf,
+		sizeof(max_tx_flowrings), pos);
+	if (ret < 0)
+		goto exit;
+
+	/* write the log */
+	ret = dhd_d2h_h2d_ring_dump(dhdp, fp, user_buf, (unsigned long *)pos, TRUE);
+	if (ret < 0)
+		goto exit;
+exit:
+	return ret;
+}
+#endif /* DHD_DUMP_PCIE_RINGS */
+
+#ifdef EWP_ECNTRS_LOGGING
+int
+dhd_print_ecntrs_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+		void *fp, uint32 len, void *pos)
+{
+	log_dump_section_hdr_t sec_hdr;
+	int ret = BCME_OK;
+	dhd_info_t *dhd_info;
+
+	if (dev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return BCME_ERROR;
+
+	dhd_init_sec_hdr(&sec_hdr);
+
+	if (logdump_ecntr_enable &&
+			dhdp->ecntr_dbg_ring) {
+		sec_hdr.type = LOG_DUMP_SECTION_ECNTRS;
+		ret = dhd_dump_debug_ring(dhdp, dhdp->ecntr_dbg_ring,
+				user_buf, &sec_hdr, ECNTRS_LOG_HDR, len, LOG_DUMP_SECTION_ECNTRS);
+	}
+	return ret;
+
+}
+#endif /* EWP_ECNTRS_LOGGING */
+
+#ifdef EWP_RTT_LOGGING
+int
+dhd_print_rtt_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+		void *fp, uint32 len, void *pos)
+{
+	log_dump_section_hdr_t sec_hdr;
+	int ret = BCME_OK;
+	dhd_info_t *dhd_info;
+
+	if (dev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp)
+		return BCME_ERROR;
+
+	dhd_init_sec_hdr(&sec_hdr);
+
+	if (logdump_rtt_enable && dhdp->rtt_dbg_ring) {
+		ret = dhd_dump_debug_ring(dhdp, dhdp->rtt_dbg_ring,
+				user_buf, &sec_hdr, RTT_LOG_HDR, len, LOG_DUMP_SECTION_RTT);
+	}
+	return ret;
+
+}
+#endif /* EWP_RTT_LOGGING */
+
+#ifdef DHD_STATUS_LOGGING
+int
+dhd_print_status_log_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, void *pos)
+{
+	dhd_info_t *dhd_info;
+
+	if (dev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)dev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (!dhdp) {
+		return BCME_ERROR;
+	}
+
+	return dhd_statlog_write_logdump(dhdp, user_buf, fp, len, pos);
+}
+
+uint32
+dhd_get_status_log_len(void *ndev, dhd_pub_t *dhdp)
+{
+	dhd_info_t *dhd_info;
+	uint32 length = 0;
+
+	if (ndev) {
+		dhd_info = *(dhd_info_t **)netdev_priv((struct net_device *)ndev);
+		dhdp = &dhd_info->pub;
+	}
+
+	if (dhdp) {
+		length = dhd_statlog_get_logbuf_len(dhdp);
+	}
+
+	return length;
+}
+#endif /* DHD_STATUS_LOGGING */
+
+void
+dhd_init_sec_hdr(log_dump_section_hdr_t *sec_hdr)
+{
+	/* prep the section header */
+	memset(sec_hdr, 0, sizeof(*sec_hdr));
+	sec_hdr->magic = LOG_DUMP_MAGIC;
+	sec_hdr->timestamp = local_clock();
+}
+
+/* Must hold 'dhd_os_logdump_lock' before calling this function ! */
+int
+do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type)
+{
+	int ret = 0, i = 0;
+	struct file *fp = NULL;
+#ifdef get_fs
+	mm_segment_t old_fs;
+#endif /* get_fs */
+	loff_t pos = 0;
+	char dump_path[128];
+	uint32 file_mode;
+	unsigned long flags = 0;
+	size_t log_size = 0;
+	size_t fspace_remain = 0;
+	struct file *filep = NULL;
+	int logstrs_size = 0;
+	char time_str[128];
+	unsigned int len = 0;
+	log_dump_section_hdr_t sec_hdr;
+
+	DHD_ERROR(("%s: ENTER \n", __FUNCTION__));
+
+	DHD_GENERAL_LOCK(dhdp, flags);
+	if (DHD_BUS_CHECK_DOWN_OR_DOWN_IN_PROGRESS(dhdp)) {
+		DHD_GENERAL_UNLOCK(dhdp, flags);
+		DHD_ERROR(("%s: bus is down! can't collect log dump. \n", __FUNCTION__));
+		goto exit1;
+	}
+	DHD_BUS_BUSY_SET_IN_LOGDUMP(dhdp);
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+
+	if ((ret = dhd_log_flush(dhdp, type)) < 0) {
+		goto exit1;
+	}
+#ifdef get_fs
+	/* change to KERNEL_DS address limit */
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
+#endif /* get_fs */
+
+	dhd_get_debug_dump_file_name(NULL, dhdp, dump_path, sizeof(dump_path));
+
+	DHD_ERROR(("debug_dump_path = %s\n", dump_path));
+	DHD_ERROR(("DHD version: %s\n", dhd_version));
+	DHD_ERROR(("F/W version: %s\n", fw_version));
+
+	dhd_log_dump_buf_addr(dhdp, type);
+
+	dhd_get_time_str(dhdp, time_str, 128);
+
+	/* if this is the first time after dhd is loaded,
+	 * or, if periodic flush is disabled, clear the log file
+	 */
+	if (!dhdp->logdump_periodic_flush || dhdp->last_file_posn == 0)
+		file_mode = O_CREAT | O_WRONLY | O_SYNC | O_TRUNC;
+	else
+		file_mode = O_CREAT | O_RDWR | O_SYNC;
+
+	fp = dhd_filp_open(dump_path, file_mode, 0664);
+	if (IS_ERR(fp) || (fp == NULL)) {
+		/* If android installed image, try '/data' directory */
+#if defined(CONFIG_X86) && defined(OEM_ANDROID)
+		DHD_ERROR(("%s: File open error on Installed android image, trying /data...\n",
+			__FUNCTION__));
+		snprintf(dump_path, sizeof(dump_path), "/data/" DHD_DEBUG_DUMP_TYPE);
+		if (!dhdp->logdump_periodic_flush) {
+			snprintf(dump_path + strlen(dump_path),
+				sizeof(dump_path) - strlen(dump_path),
+				"_%s", dhdp->debug_dump_time_str);
+		}
+		fp = dhd_filp_open(dump_path, file_mode, 0664);
+		if (IS_ERR(fp) || (fp == NULL)) {
+			ret = PTR_ERR(fp);
+			DHD_ERROR(("open file error, err = %d\n", ret));
+			goto exit2;
+		}
+		DHD_ERROR(("debug_dump_path = %s\n", dump_path));
+#else
+		ret = PTR_ERR(fp);
+		DHD_ERROR(("open file error, err = %d\n", ret));
+		goto exit2;
+#endif /* CONFIG_X86 && OEM_ANDROID */
+	}
+
+	filep = dhd_filp_open(dump_path, O_RDONLY, 0);
+
+	if (IS_ERR(filep) || (filep == NULL)) {
+		DHD_ERROR(("file stat error, err = %d\n", ret));
+		goto exit2;
+	}
+	logstrs_size = dhd_vfs_size_read(filep);
+	/* if some one else has changed the file */
+	if (dhdp->last_file_posn != 0 &&
+			logstrs_size < dhdp->last_file_posn) {
+		dhdp->last_file_posn = 0;
+	}
+
+	/* XXX: periodic flush is disabled by default, if enabled
+	 * only periodic flushing of 'GENERAL' log dump buffer
+	 * is supported, its not recommended to turn on periodic
+	 * flushing, except for developer unit test.
+	 */
+	if (dhdp->logdump_periodic_flush) {
+		log_size = strlen(time_str) + strlen(DHD_DUMP_LOG_HDR) + sizeof(sec_hdr);
+		/* calculate the amount of space required to dump all logs */
+		for (i = 0; i < DLD_BUFFER_NUM; ++i) {
+			if (*type != DLD_BUF_TYPE_ALL && i != *type)
+				continue;
+
+			if (g_dld_buf[i].wraparound) {
+				log_size += (unsigned long)g_dld_buf[i].max
+						- (unsigned long)g_dld_buf[i].buffer;
+			} else {
+				DHD_LOG_DUMP_BUF_LOCK(&g_dld_buf[i].lock, flags);
+				log_size += (unsigned long)g_dld_buf[i].present -
+						(unsigned long)g_dld_buf[i].front;
+				DHD_LOG_DUMP_BUF_UNLOCK(&g_dld_buf[i].lock, flags);
+			}
+			log_size += strlen(dld_hdrs[i].hdr_str) + sizeof(sec_hdr);
+
+			if (*type != DLD_BUF_TYPE_ALL && i == *type)
+				break;
+		}
+
+		ret = generic_file_llseek(fp, dhdp->last_file_posn, SEEK_CUR);
+		if (ret < 0) {
+			DHD_ERROR(("file seek last posn error ! err = %d \n", ret));
+			goto exit2;
+		}
+		pos = fp->f_pos;
+
+		/* if the max file size is reached, wrap around to beginning of the file
+		 * we're treating the file as a large ring buffer
+		 */
+		fspace_remain = logdump_max_filesize - pos;
+		if (log_size > fspace_remain) {
+			fp->f_pos -= pos;
+			pos = fp->f_pos;
+		}
+	}
+
+	dhd_print_time_str(0, fp, len, &pos);
+
+	for (i = 0; i < DLD_BUFFER_NUM; ++i) {
+
+		if (*type != DLD_BUF_TYPE_ALL && i != *type)
+			continue;
+
+		len = dhd_get_dld_len(i);
+		dhd_get_dld_log_dump(NULL, dhdp, 0, fp, len, i, &pos);
+		if (*type != DLD_BUF_TYPE_ALL)
+			break;
+	}
+
+#ifdef EWP_ECNTRS_LOGGING
+	if (*type == DLD_BUF_TYPE_ALL &&
+			logdump_ecntr_enable &&
+			dhdp->ecntr_dbg_ring) {
+		dhd_log_dump_ring_to_file(dhdp, dhdp->ecntr_dbg_ring,
+				fp, (unsigned long *)&pos,
+				&sec_hdr, ECNTRS_LOG_HDR, LOG_DUMP_SECTION_ECNTRS);
+	}
+#endif /* EWP_ECNTRS_LOGGING */
+
+#ifdef DHD_STATUS_LOGGING
+	if (dhdp->statlog) {
+		/* write the statlog */
+		len = dhd_get_status_log_len(NULL, dhdp);
+		if (len) {
+			if (dhd_print_status_log_data(NULL, dhdp, 0, fp,
+				len, &pos) < 0) {
+				goto exit2;
+			}
+		}
+	}
+#endif /* DHD_STATUS_LOGGING */
+
+#ifdef DHD_STATUS_LOGGING
+	if (dhdp->statlog) {
+		dhd_print_buf_addr(dhdp, "statlog_logbuf", dhd_statlog_get_logbuf(dhdp),
+			dhd_statlog_get_logbuf_len(dhdp));
+	}
+#endif /* DHD_STATUS_LOGGING */
+
+#ifdef EWP_RTT_LOGGING
+	if (*type == DLD_BUF_TYPE_ALL &&
+			logdump_rtt_enable &&
+			dhdp->rtt_dbg_ring) {
+		dhd_log_dump_ring_to_file(dhdp, dhdp->rtt_dbg_ring,
+				fp, (unsigned long *)&pos,
+				&sec_hdr, RTT_LOG_HDR, LOG_DUMP_SECTION_RTT);
+	}
+#endif /* EWP_RTT_LOGGING */
+
+#ifdef EWP_BCM_TRACE
+	if (*type == DLD_BUF_TYPE_ALL &&
+		dhdp->bcm_trace_dbg_ring) {
+		dhd_log_dump_ring_to_file(dhdp, dhdp->bcm_trace_dbg_ring,
+				fp, (unsigned long *)&pos,
+				&sec_hdr, BCM_TRACE_LOG_HDR, LOG_DUMP_SECTION_BCM_TRACE);
+	}
+#endif /* EWP_BCM_TRACE */
+
+#ifdef BCMPCIE
+	len = dhd_get_ext_trap_len(NULL, dhdp);
+	if (len) {
+		if (dhd_print_ext_trap_data(NULL, dhdp, 0, fp, len, &pos) < 0)
+			goto exit2;
+	}
+#endif /* BCMPCIE */
+
+#if defined(DHD_FW_COREDUMP) && defined(DNGL_EVENT_SUPPORT)
+	len = dhd_get_health_chk_len(NULL, dhdp);
+	if (len) {
+		if (dhd_print_health_chk_data(NULL, dhdp, 0, fp, len, &pos) < 0)
+			goto exit2;
+	}
+#endif /* DHD_FW_COREDUMP && DNGL_EVENT_SUPPORT */
+
+	len = dhd_get_dhd_dump_len(NULL, dhdp);
+	if (len) {
+		if (dhd_print_dump_data(NULL, dhdp, 0, fp, len, &pos) < 0)
+			goto exit2;
+	}
+
+	len = dhd_get_cookie_log_len(NULL, dhdp);
+	if (len) {
+		if (dhd_print_cookie_data(NULL, dhdp, 0, fp, len, &pos) < 0)
+			goto exit2;
+	}
+
+#ifdef DHD_DUMP_PCIE_RINGS
+	len = dhd_get_flowring_len(NULL, dhdp);
+	if (len) {
+		if (dhd_print_flowring_data(NULL, dhdp, 0, fp, len, &pos) < 0)
+			goto exit2;
+	}
+#endif
+
+	if (dhdp->logdump_periodic_flush) {
+		/* store the last position written to in the file for future use */
+		dhdp->last_file_posn = pos;
+	}
+
+exit2:
+	if (!IS_ERR(fp) && fp != NULL) {
+		dhd_filp_close(fp, NULL);
+		DHD_ERROR(("%s: Finished writing log dump to file - '%s' \n",
+				__FUNCTION__, dump_path));
+	}
+#ifdef get_fs
+	set_fs(old_fs);
+#endif /* get_fs */
+exit1:
+	if (type) {
+		MFREE(dhdp->osh, type, sizeof(*type));
+	}
+	DHD_GENERAL_LOCK(dhdp, flags);
+	DHD_BUS_BUSY_CLEAR_IN_LOGDUMP(dhdp);
+	dhd_os_busbusy_wake(dhdp);
+	DHD_GENERAL_UNLOCK(dhdp, flags);
+
+#ifdef DHD_DUMP_MNGR
+	if (ret >= 0) {
+		dhd_dump_file_manage_enqueue(dhdp, dump_path, DHD_DEBUG_DUMP_TYPE);
+	}
+#endif /* DHD_DUMP_MNGR */
+
+	return (ret < 0) ? BCME_ERROR : BCME_OK;
+}
+
+bool
+dhd_log_dump_ecntr_enabled(void)
+{
+	return (bool)logdump_ecntr_enable;
+}
+
+bool
+dhd_log_dump_rtt_enabled(void)
+{
+	return (bool)logdump_rtt_enable;
+}
+
+void
+dhd_log_dump_init(dhd_pub_t *dhd)
+{
+	struct dhd_log_dump_buf *dld_buf, *dld_buf_special;
+	int i = 0;
+	uint8 *prealloc_buf = NULL, *bufptr = NULL;
+#if defined(CONFIG_DHD_USE_STATIC_BUF) && defined(DHD_USE_STATIC_MEMDUMP)
+	int prealloc_idx = DHD_PREALLOC_DHD_LOG_DUMP_BUF;
+#endif /* CONFIG_DHD_USE_STATIC_BUF && DHD_USE_STATIC_MEMDUMP */
+	int ret;
+	dhd_dbg_ring_t *ring = NULL;
+	unsigned long flags = 0;
+	dhd_info_t *dhd_info = dhd->info;
+#if defined(EWP_ECNTRS_LOGGING)
+	void *cookie_buf = NULL;
+#endif
+
+	BCM_REFERENCE(ret);
+	BCM_REFERENCE(ring);
+	BCM_REFERENCE(flags);
+
+	/* sanity check */
+	if (logdump_prsrv_tailsize <= 0 ||
+		logdump_prsrv_tailsize > DHD_LOG_DUMP_MAX_TAIL_FLUSH_SIZE) {
+		logdump_prsrv_tailsize = DHD_LOG_DUMP_MAX_TAIL_FLUSH_SIZE;
+	}
+	/* now adjust the preserve log flush size based on the
+	* kernel printk log buffer size
+	*/
+#ifdef CONFIG_LOG_BUF_SHIFT
+	DHD_ERROR(("%s: kernel log buf size = %uKB; logdump_prsrv_tailsize = %uKB;"
+		" limit prsrv tail size to = %uKB\n",
+		__FUNCTION__, (1 << CONFIG_LOG_BUF_SHIFT)/1024,
+		logdump_prsrv_tailsize/1024, LOG_DUMP_KERNEL_TAIL_FLUSH_SIZE/1024));
+
+	if (logdump_prsrv_tailsize > LOG_DUMP_KERNEL_TAIL_FLUSH_SIZE) {
+		logdump_prsrv_tailsize = LOG_DUMP_KERNEL_TAIL_FLUSH_SIZE;
+	}
+#else
+	DHD_ERROR(("%s: logdump_prsrv_tailsize = %uKB \n",
+		__FUNCTION__, logdump_prsrv_tailsize/1024));
+#endif /* CONFIG_LOG_BUF_SHIFT */
+
+	mutex_init(&dhd_info->logdump_lock);
+	/* initialize log dump buf structures */
+	memset(g_dld_buf, 0, sizeof(struct dhd_log_dump_buf) * DLD_BUFFER_NUM);
+
+	/* set the log dump buffer size based on the module_param */
+	if (logdump_max_bufsize > LOG_DUMP_GENERAL_MAX_BUFSIZE ||
+			logdump_max_bufsize <= 0)
+		dld_buf_size[DLD_BUF_TYPE_GENERAL] = LOG_DUMP_GENERAL_MAX_BUFSIZE;
+	else
+		dld_buf_size[DLD_BUF_TYPE_GENERAL] = logdump_max_bufsize;
+
+	/* pre-alloc the memory for the log buffers & 'special' buffer */
+	dld_buf_special = &g_dld_buf[DLD_BUF_TYPE_SPECIAL];
+#if defined(CONFIG_DHD_USE_STATIC_BUF) && defined(DHD_USE_STATIC_MEMDUMP)
+	prealloc_buf = DHD_OS_PREALLOC(dhd, prealloc_idx++, LOG_DUMP_TOTAL_BUFSIZE);
+	dld_buf_special->buffer = DHD_OS_PREALLOC(dhd, prealloc_idx++,
+			dld_buf_size[DLD_BUF_TYPE_SPECIAL]);
+#else
+	prealloc_buf = MALLOCZ(dhd->osh, LOG_DUMP_TOTAL_BUFSIZE);
+	dld_buf_special->buffer = MALLOCZ(dhd->osh, dld_buf_size[DLD_BUF_TYPE_SPECIAL]);
+#endif /* CONFIG_DHD_USE_STATIC_BUF && DHD_USE_STATIC_MEMDUMP */
+
+	if (!prealloc_buf) {
+		DHD_ERROR(("Failed to allocate memory for log buffers\n"));
+		goto fail;
+	}
+	if (!dld_buf_special->buffer) {
+		DHD_ERROR(("Failed to allocate memory for special buffer\n"));
+		goto fail;
+	}
+
+	bufptr = prealloc_buf;
+	for (i = 0; i < DLD_BUFFER_NUM; i++) {
+		dld_buf = &g_dld_buf[i];
+		dld_buf->dhd_pub = dhd;
+		spin_lock_init(&dld_buf->lock);
+		dld_buf->wraparound = 0;
+		if (i != DLD_BUF_TYPE_SPECIAL) {
+			dld_buf->buffer = bufptr;
+			dld_buf->max = (unsigned long)dld_buf->buffer + dld_buf_size[i];
+			bufptr = (uint8 *)dld_buf->max;
+		} else {
+			dld_buf->max = (unsigned long)dld_buf->buffer + dld_buf_size[i];
+		}
+		dld_buf->present = dld_buf->front = dld_buf->buffer;
+		dld_buf->remain = dld_buf_size[i];
+		dld_buf->enable = 1;
+	}
+
+	/* now use the rest of the pre-alloc'd memory for other rings */
+#ifdef EWP_ECNTRS_LOGGING
+	dhd->ecntr_dbg_ring = dhd_dbg_ring_alloc_init(dhd,
+			ECNTR_RING_ID, ECNTR_RING_NAME,
+			LOG_DUMP_ECNTRS_MAX_BUFSIZE,
+			bufptr, TRUE);
+	if (!dhd->ecntr_dbg_ring) {
+		DHD_ERROR(("%s: unable to init ecounters dbg ring !\n",
+				__FUNCTION__));
+		goto fail;
+	}
+	bufptr += LOG_DUMP_ECNTRS_MAX_BUFSIZE;
+#endif /* EWP_ECNTRS_LOGGING */
+
+#ifdef EWP_RTT_LOGGING
+	dhd->rtt_dbg_ring = dhd_dbg_ring_alloc_init(dhd,
+			RTT_RING_ID, RTT_RING_NAME,
+			LOG_DUMP_RTT_MAX_BUFSIZE,
+			bufptr, TRUE);
+	if (!dhd->rtt_dbg_ring) {
+		DHD_ERROR(("%s: unable to init rtt dbg ring !\n",
+				__FUNCTION__));
+		goto fail;
+	}
+	bufptr += LOG_DUMP_RTT_MAX_BUFSIZE;
+#endif /* EWP_RTT_LOGGING */
+
+#ifdef EWP_BCM_TRACE
+	dhd->bcm_trace_dbg_ring = dhd_dbg_ring_alloc_init(dhd,
+			BCM_TRACE_RING_ID, BCM_TRACE_RING_NAME,
+			LOG_DUMP_BCM_TRACE_MAX_BUFSIZE,
+			bufptr, TRUE);
+	if (!dhd->bcm_trace_dbg_ring) {
+		DHD_ERROR(("%s: unable to init bcm trace dbg ring !\n",
+				__FUNCTION__));
+		goto fail;
+	}
+	bufptr += LOG_DUMP_BCM_TRACE_MAX_BUFSIZE;
+#endif /* EWP_BCM_TRACE */
+
+	/* Concise buffer is used as intermediate buffer for following purposes
+	* a) pull ecounters records temporarily before
+	*  writing it to file
+	* b) to store dhd dump data before putting it to file
+	* It should have a size equal to
+	* MAX(largest possible ecntr record, 'dhd dump' data size)
+	*/
+	dhd->concise_dbg_buf = MALLOC(dhd->osh, CONCISE_DUMP_BUFLEN);
+	if (!dhd->concise_dbg_buf) {
+		DHD_ERROR(("%s: unable to alloc mem for concise debug info !\n",
+				__FUNCTION__));
+		goto fail;
+	}
+
+#if defined(DHD_EVENT_LOG_FILTER)
+	/* XXX init filter last, because filter use buffer which alloced by log dump */
+	ret = dhd_event_log_filter_init(dhd,
+		bufptr,
+		LOG_DUMP_FILTER_MAX_BUFSIZE);
+	if (ret != BCME_OK) {
+		goto fail;
+	}
+#endif /* DHD_EVENT_LOG_FILTER */
+
+#if defined(EWP_ECNTRS_LOGGING)
+	cookie_buf = MALLOC(dhd->osh, LOG_DUMP_COOKIE_BUFSIZE);
+	if (!cookie_buf) {
+		DHD_ERROR(("%s: unable to alloc mem for logdump cookie buffer\n",
+			__FUNCTION__));
+		goto fail;
+	}
+
+	ret = dhd_logdump_cookie_init(dhd, cookie_buf, LOG_DUMP_COOKIE_BUFSIZE);
+	if (ret != BCME_OK) {
+		MFREE(dhd->osh, cookie_buf, LOG_DUMP_COOKIE_BUFSIZE);
+		goto fail;
+	}
+#endif /* EWP_ECNTRS_LOGGING */
+	return;
+
+fail:
+
+#if defined(DHD_EVENT_LOG_FILTER)
+	/* XXX deinit filter first, because filter use buffer which alloced by log dump */
+	if (dhd->event_log_filter) {
+		dhd_event_log_filter_deinit(dhd);
+	}
+#endif /* DHD_EVENT_LOG_FILTER */
+
+	if (dhd->concise_dbg_buf) {
+		MFREE(dhd->osh, dhd->concise_dbg_buf, CONCISE_DUMP_BUFLEN);
+	}
+
+#ifdef EWP_ECNTRS_LOGGING
+	if (dhd->logdump_cookie) {
+		dhd_logdump_cookie_deinit(dhd);
+		MFREE(dhd->osh, dhd->logdump_cookie, LOG_DUMP_COOKIE_BUFSIZE);
+		dhd->logdump_cookie = NULL;
+	}
+#endif /* EWP_ECNTRS_LOGGING */
+
+#if defined(CONFIG_DHD_USE_STATIC_BUF) && defined(DHD_USE_STATIC_MEMDUMP)
+	if (prealloc_buf) {
+		DHD_OS_PREFREE(dhd, prealloc_buf, LOG_DUMP_TOTAL_BUFSIZE);
+	}
+	if (dld_buf_special->buffer) {
+		DHD_OS_PREFREE(dhd, dld_buf_special->buffer,
+				dld_buf_size[DLD_BUF_TYPE_SPECIAL]);
+	}
+#else
+	if (prealloc_buf) {
+		MFREE(dhd->osh, prealloc_buf, LOG_DUMP_TOTAL_BUFSIZE);
+	}
+	if (dld_buf_special->buffer) {
+		MFREE(dhd->osh, dld_buf_special->buffer,
+				dld_buf_size[DLD_BUF_TYPE_SPECIAL]);
+	}
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+	for (i = 0; i < DLD_BUFFER_NUM; i++) {
+		dld_buf = &g_dld_buf[i];
+		dld_buf->enable = 0;
+		dld_buf->buffer = NULL;
+	}
+	mutex_destroy(&dhd_info->logdump_lock);
+}
+
+void
+dhd_log_dump_deinit(dhd_pub_t *dhd)
+{
+	struct dhd_log_dump_buf *dld_buf = NULL, *dld_buf_special = NULL;
+	int i = 0;
+	dhd_info_t *dhd_info = dhd->info;
+	dhd_dbg_ring_t *ring = NULL;
+
+	BCM_REFERENCE(ring);
+
+#if defined(DHD_EVENT_LOG_FILTER)
+	/* XXX deinit filter first, because filter use buffer which alloced by log dump */
+	if (dhd->event_log_filter) {
+		dhd_event_log_filter_deinit(dhd);
+	}
+#endif /* DHD_EVENT_LOG_FILTER */
+
+	if (dhd->concise_dbg_buf) {
+		MFREE(dhd->osh, dhd->concise_dbg_buf, CONCISE_DUMP_BUFLEN);
+		dhd->concise_dbg_buf = NULL;
+	}
+
+#ifdef EWP_ECNTRS_LOGGING
+	if (dhd->logdump_cookie) {
+		dhd_logdump_cookie_deinit(dhd);
+		MFREE(dhd->osh, dhd->logdump_cookie, LOG_DUMP_COOKIE_BUFSIZE);
+		dhd->logdump_cookie = NULL;
+	}
+
+	if (dhd->ecntr_dbg_ring) {
+		dhd_dbg_ring_dealloc_deinit(&dhd->ecntr_dbg_ring, dhd);
+	}
+#endif /* EWP_ECNTRS_LOGGING */
+
+#ifdef EWP_RTT_LOGGING
+	if (dhd->rtt_dbg_ring) {
+		dhd_dbg_ring_dealloc_deinit(&dhd->rtt_dbg_ring, dhd);
+	}
+#endif /* EWP_RTT_LOGGING */
+
+#ifdef EWP_BCM_TRACE
+	if (dhd->bcm_trace_dbg_ring) {
+		dhd_dbg_ring_dealloc_deinit(&dhd->bcm_trace_dbg_ring, dhd);
+	}
+#endif /* EWP_BCM_TRACE */
+
+	/* 'general' buffer points to start of the pre-alloc'd memory */
+	dld_buf = &g_dld_buf[DLD_BUF_TYPE_GENERAL];
+	dld_buf_special = &g_dld_buf[DLD_BUF_TYPE_SPECIAL];
+#if defined(CONFIG_DHD_USE_STATIC_BUF) && defined(DHD_USE_STATIC_MEMDUMP)
+	if (dld_buf->buffer) {
+		DHD_OS_PREFREE(dhd, dld_buf->buffer, LOG_DUMP_TOTAL_BUFSIZE);
+	}
+	if (dld_buf_special->buffer) {
+		DHD_OS_PREFREE(dhd, dld_buf_special->buffer,
+				dld_buf_size[DLD_BUF_TYPE_SPECIAL]);
+	}
+#else
+	if (dld_buf->buffer) {
+		MFREE(dhd->osh, dld_buf->buffer, LOG_DUMP_TOTAL_BUFSIZE);
+	}
+	if (dld_buf_special->buffer) {
+		MFREE(dhd->osh, dld_buf_special->buffer,
+				dld_buf_size[DLD_BUF_TYPE_SPECIAL]);
+	}
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
+	for (i = 0; i < DLD_BUFFER_NUM; i++) {
+		dld_buf = &g_dld_buf[i];
+		dld_buf->enable = 0;
+		dld_buf->buffer = NULL;
+	}
+	mutex_destroy(&dhd_info->logdump_lock);
+}
+
+void
+dhd_log_dump_write(int type, char *binary_data,
+		int binary_len, const char *fmt, ...)
+{
+	int len = 0;
+	char tmp_buf[DHD_LOG_DUMP_MAX_TEMP_BUFFER_SIZE] = {0, };
+	va_list args;
+	unsigned long flags = 0;
+	struct dhd_log_dump_buf *dld_buf = NULL;
+	bool flush_log = FALSE;
+
+	if (type < 0 || type >= DLD_BUFFER_NUM) {
+		DHD_INFO(("%s: Unsupported DHD_LOG_DUMP_BUF_TYPE(%d).\n",
+			__FUNCTION__, type));
+		return;
+	}
+
+	dld_buf = &g_dld_buf[type];
+	if (dld_buf->enable != 1) {
+		return;
+	}
+
+	va_start(args, fmt);
+	len = vsnprintf(tmp_buf, DHD_LOG_DUMP_MAX_TEMP_BUFFER_SIZE, fmt, args);
+	/* Non ANSI C99 compliant returns -1,
+	 * ANSI compliant return len >= DHD_LOG_DUMP_MAX_TEMP_BUFFER_SIZE
+	 */
+	va_end(args);
+	if (len < 0) {
+		return;
+	}
+
+	if (len >= DHD_LOG_DUMP_MAX_TEMP_BUFFER_SIZE) {
+		len = DHD_LOG_DUMP_MAX_TEMP_BUFFER_SIZE - 1;
+		tmp_buf[len] = '\0';
+	}
+
+	/* make a critical section to eliminate race conditions */
+	DHD_LOG_DUMP_BUF_LOCK(&dld_buf->lock, flags);
+	if (dld_buf->remain < len) {
+		dld_buf->wraparound = 1;
+		dld_buf->present = dld_buf->front;
+		dld_buf->remain = dld_buf_size[type];
+		/* if wrap around happens, flush the ring buffer to the file */
+		flush_log = TRUE;
+	}
+
+	memcpy(dld_buf->present, tmp_buf, len);
+	dld_buf->remain -= len;
+	dld_buf->present += len;
+	DHD_LOG_DUMP_BUF_UNLOCK(&dld_buf->lock, flags);
+
+	/* double check invalid memory operation */
+	ASSERT((unsigned long)dld_buf->present <= dld_buf->max);
+
+	if (dld_buf->dhd_pub) {
+		dhd_pub_t *dhdp = (dhd_pub_t *)dld_buf->dhd_pub;
+		dhdp->logdump_periodic_flush =
+			logdump_periodic_flush;
+		if (logdump_periodic_flush && flush_log) {
+			log_dump_type_t *flush_type = MALLOCZ(dhdp->osh,
+					sizeof(log_dump_type_t));
+			if (flush_type) {
+				*flush_type = type;
+				dhd_schedule_log_dump(dld_buf->dhd_pub, flush_type);
+			}
+		}
+	}
+}
+
+void
+dhd_log_dump_vendor_trigger(dhd_pub_t *dhd_pub)
+{
+	unsigned long flags = 0;
+	DHD_GENERAL_LOCK(dhd_pub, flags);
+	DHD_BUS_BUSY_SET_IN_DUMP_DONGLE_MEM(dhd_pub);
+	DHD_GENERAL_UNLOCK(dhd_pub, flags);
+
+	dhd_log_dump_trigger(dhd_pub, CMD_DEFAULT);
+
+	DHD_GENERAL_LOCK(dhd_pub, flags);
+	DHD_BUS_BUSY_CLEAR_IN_DUMP_DONGLE_MEM(dhd_pub);
+	dhd_os_busbusy_wake(dhd_pub);
+	DHD_GENERAL_UNLOCK(dhd_pub, flags);
+
+	return;
+}
+
+void
+dhd_log_dump_trigger(dhd_pub_t *dhdp, int subcmd)
+{
+#if defined(DHD_DUMP_FILE_WRITE_FROM_KERNEL)
+	log_dump_type_t *flush_type;
+#endif /* DHD_DUMP_FILE_WRITE_FROM_KERNEL */
+	uint64 current_time_sec;
+
+	if (!dhdp) {
+		DHD_ERROR(("dhdp is NULL !\n"));
+		return;
+	}
+
+	if (subcmd >= CMD_MAX || subcmd < CMD_DEFAULT) {
+		DHD_ERROR(("%s : Invalid subcmd \n", __FUNCTION__));
+		return;
+	}
+
+	current_time_sec = DIV_U64_BY_U32(OSL_LOCALTIME_NS(), NSEC_PER_SEC);
+
+	DHD_ERROR(("%s: current_time_sec=%lld debug_dump_time_sec=%lld interval=%d\n",
+		__FUNCTION__, current_time_sec, dhdp->debug_dump_time_sec,
+		DEBUG_DUMP_TRIGGER_INTERVAL_SEC));
+
+	if ((current_time_sec - dhdp->debug_dump_time_sec) < DEBUG_DUMP_TRIGGER_INTERVAL_SEC) {
+		DHD_ERROR(("%s : Last debug dump triggered(%lld) within %d seconds, so SKIP\n",
+			__FUNCTION__, dhdp->debug_dump_time_sec, DEBUG_DUMP_TRIGGER_INTERVAL_SEC));
+		return;
+	}
+
+	clear_debug_dump_time(dhdp->debug_dump_time_str);
+	/*  */
+
+	dhdp->debug_dump_subcmd = subcmd;
+
+	dhdp->debug_dump_time_sec = DIV_U64_BY_U32(OSL_LOCALTIME_NS(), NSEC_PER_SEC);
+
+#if defined(DHD_DUMP_FILE_WRITE_FROM_KERNEL)
+	/* flush_type is freed at do_dhd_log_dump function */
+	flush_type = MALLOCZ(dhdp->osh, sizeof(log_dump_type_t));
+	if (flush_type) {
+		*flush_type = DLD_BUF_TYPE_ALL;
+		dhd_schedule_log_dump(dhdp, flush_type);
+	} else {
+		DHD_ERROR(("%s Fail to malloc flush_type\n", __FUNCTION__));
+		return;
+	}
+#endif /* DHD_DUMP_FILE_WRITE_FROM_KERNEL */
+
+#if defined(DHD_SDTC_ETB_DUMP) && defined(BCMQT_HW)
+	/* For QT/zebu memdump collection is disabled,
+	 * but set collect_sdtc true here, so that
+	 * developers can issue 'log_dump' dhd iovar
+	 * to get etb/sdtc dumps
+	 */
+	DHD_ERROR(("%s : QT/FPGA set collect_sdtc as TRUE\n", __FUNCTION__));
+	dhdp->collect_sdtc = TRUE;
+#endif /* DHD_SDTC_ETB_DUMP && BCMQT_HW */
+
+	/* Inside dhd_mem_dump, event notification will be sent to HAL and
+	 * from other context DHD pushes memdump, debug_dump and pktlog dump
+	 * to HAL and HAL will write into file
+	 */
+#if (defined(BCMPCIE) || defined(BCMSDIO)) && defined(DHD_FW_COREDUMP)
+	dhdp->memdump_type = DUMP_TYPE_BY_SYSDUMP;
+	dhd_bus_mem_dump(dhdp);
+#endif /* BCMPCIE && DHD_FW_COREDUMP */
+
+#if defined(DHD_PKT_LOGGING) && defined(DHD_DUMP_FILE_WRITE_FROM_KERNEL)
+	dhd_schedule_pktlog_dump(dhdp);
+#endif /* DHD_PKT_LOGGING && DHD_DUMP_FILE_WRITE_FROM_KERNEL */
+}
+
+#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
+int dhd_debug_dump_get_ring_num(int sec_type)
+{
+	int idx = 0;
+	for (idx = 0; idx < ARRAYSIZE(dhd_debug_dump_ring_map); idx++) {
+		if (dhd_debug_dump_ring_map[idx].type == sec_type) {
+			idx = dhd_debug_dump_ring_map[idx].debug_dump_ring;
+			return idx;
+		}
+	}
+	return idx;
+}
+#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
+
+int
+dhd_dump_debug_ring(dhd_pub_t *dhdp, void *ring_ptr, const void *user_buf,
+		log_dump_section_hdr_t *sec_hdr,
+		char *text_hdr, int buflen, uint32 sec_type)
+{
+	uint32 rlen = 0;
+	uint32 data_len = 0;
+	void *data = NULL;
+	unsigned long flags = 0;
+	int ret = 0;
+	dhd_dbg_ring_t *ring = (dhd_dbg_ring_t *)ring_ptr;
+#ifndef DHD_DEBUGABILITY_DEBUG_DUMP
+	int pos = 0;
+#endif /* !DHD_DEBUGABILITY_DEBUG_DUMP */
+	int fpos_sechdr = 0;
+	int tot_len = 0;
+	char *tmp_buf = NULL;
+	int idx;
+	int ring_num = 0;
+
+	BCM_REFERENCE(idx);
+	BCM_REFERENCE(tot_len);
+	BCM_REFERENCE(fpos_sechdr);
+	BCM_REFERENCE(data_len);
+	BCM_REFERENCE(tmp_buf);
+	BCM_REFERENCE(ring_num);
+
+#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
+	if (!dhdp || !ring || !sec_hdr || !text_hdr) {
+		return BCME_BADARG;
+	}
+
+	tmp_buf = (char *)VMALLOCZ(dhdp->osh, ring->ring_size);
+	if (!tmp_buf) {
+		DHD_ERROR(("%s: VMALLOC Fail id:%d size:%u\n",
+			__func__, ring->id, ring->ring_size));
+		return BCME_NOMEM;
+	}
+#else
+	if (!dhdp || !ring || !user_buf || !sec_hdr || !text_hdr) {
+		return BCME_BADARG;
+	}
+#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
+	/* do not allow further writes to the ring
+	 * till we flush it
+	 */
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+	ring->state = RING_SUSPEND;
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
+	ring_num = dhd_debug_dump_get_ring_num(sec_type);
+	dhd_export_debug_data(text_hdr, NULL, NULL, strlen(text_hdr), &ring_num);
+
+	data = tmp_buf;
+	do {
+		rlen = dhd_dbg_ring_pull_single(ring, data, ring->ring_size, TRUE);
+		if (rlen > 0) {
+			tot_len += rlen;
+			data += rlen;
+		}
+	} while ((rlen > 0));
+
+	sec_hdr->type = sec_type;
+	sec_hdr->length = tot_len;
+	DHD_ERROR(("%s: DUMP id:%d type:%u tot_len:%d\n", __func__, ring->id, sec_type, tot_len));
+
+	dhd_export_debug_data((char *)sec_hdr, NULL, NULL, sizeof(*sec_hdr), &ring_num);
+	dhd_export_debug_data(tmp_buf, NULL, NULL, tot_len, &ring_num);
+
+	VMFREE(dhdp->osh, tmp_buf, ring->ring_size);
+#else
+	if (dhdp->concise_dbg_buf) {
+		/* re-use concise debug buffer temporarily
+		 * to pull ring data, to write
+		 * record by record to file
+		 */
+		data_len = CONCISE_DUMP_BUFLEN;
+		data = dhdp->concise_dbg_buf;
+		ret = dhd_export_debug_data(text_hdr, NULL, user_buf, strlen(text_hdr), &pos);
+		/* write the section header now with zero length,
+		 * once the correct length is found out, update
+		 * it later
+		 */
+		fpos_sechdr = pos;
+		sec_hdr->type = sec_type;
+		sec_hdr->length = 0;
+		ret = dhd_export_debug_data((char *)sec_hdr, NULL, user_buf,
+			sizeof(*sec_hdr), &pos);
+		do {
+			rlen = dhd_dbg_ring_pull_single(ring, data, data_len, TRUE);
+			if (rlen > 0) {
+				/* write the log */
+				ret = dhd_export_debug_data(data, NULL, user_buf, rlen, &pos);
+			}
+			DHD_DBGIF(("%s: rlen : %d\n", __FUNCTION__, rlen));
+		} while ((rlen > 0));
+		/* now update the section header length in the file */
+		/* Complete ring size is dumped by HAL, hence updating length to ring size */
+		sec_hdr->length = ring->ring_size;
+		ret = dhd_export_debug_data((char *)sec_hdr, NULL, user_buf,
+			sizeof(*sec_hdr), &fpos_sechdr);
+	} else {
+		DHD_ERROR(("%s: No concise buffer available !\n", __FUNCTION__));
+	}
+#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
+
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+	ring->state = RING_ACTIVE;
+	/* Resetting both read and write pointer,
+	 * since all items are read.
+	 */
+	ring->rp = ring->wp = 0;
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+	return ret;
+}
+
+int
+dhd_log_dump_ring_to_file(dhd_pub_t *dhdp, void *ring_ptr, void *file,
+		unsigned long *file_posn, log_dump_section_hdr_t *sec_hdr,
+		char *text_hdr, uint32 sec_type)
+{
+	uint32 rlen = 0;
+	uint32 data_len = 0, total_len = 0;
+	void *data = NULL;
+	unsigned long fpos_sechdr = 0;
+	unsigned long flags = 0;
+	int ret = 0;
+	dhd_dbg_ring_t *ring = (dhd_dbg_ring_t *)ring_ptr;
+
+	if (!dhdp || !ring || !file || !sec_hdr ||
+		!file_posn || !text_hdr)
+		return BCME_BADARG;
+
+	/* do not allow further writes to the ring
+	 * till we flush it
+	 */
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+	ring->state = RING_SUSPEND;
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+
+	if (dhdp->concise_dbg_buf) {
+		/* re-use concise debug buffer temporarily
+		 * to pull ring data, to write
+		 * record by record to file
+		 */
+		data_len = CONCISE_DUMP_BUFLEN;
+		data = dhdp->concise_dbg_buf;
+		dhd_os_write_file_posn(file, file_posn, text_hdr,
+				strlen(text_hdr));
+		/* write the section header now with zero length,
+		 * once the correct length is found out, update
+		 * it later
+		 */
+		dhd_init_sec_hdr(sec_hdr);
+		fpos_sechdr = *file_posn;
+		sec_hdr->type = sec_type;
+		sec_hdr->length = 0;
+		dhd_os_write_file_posn(file, file_posn, (char *)sec_hdr,
+				sizeof(*sec_hdr));
+		do {
+			rlen = dhd_dbg_ring_pull_single(ring, data, data_len, TRUE);
+			if (rlen > 0) {
+				/* write the log */
+				ret = dhd_os_write_file_posn(file, file_posn, data, rlen);
+				if (ret < 0) {
+					DHD_ERROR(("%s: write file error !\n", __FUNCTION__));
+					DHD_DBG_RING_LOCK(ring->lock, flags);
+					ring->state = RING_ACTIVE;
+					DHD_DBG_RING_UNLOCK(ring->lock, flags);
+					return BCME_ERROR;
+				}
+			}
+			total_len += rlen;
+		} while (rlen > 0);
+		/* now update the section header length in the file */
+		sec_hdr->length = total_len;
+		dhd_os_write_file_posn(file, &fpos_sechdr, (char *)sec_hdr, sizeof(*sec_hdr));
+	} else {
+		DHD_ERROR(("%s: No concise buffer available !\n", __FUNCTION__));
+	}
+
+	DHD_DBG_RING_LOCK(ring->lock, flags);
+	ring->state = RING_ACTIVE;
+	/* Resetting both read and write pointer,
+	 * since all items are read.
+	 */
+	ring->rp = ring->wp = 0;
+	DHD_DBG_RING_UNLOCK(ring->lock, flags);
+	return BCME_OK;
+}
+
+/* logdump cookie */
+#define MAX_LOGUDMP_COOKIE_CNT	10u
+#define LOGDUMP_COOKIE_STR_LEN	50u
+int
+dhd_logdump_cookie_init(dhd_pub_t *dhdp, uint8 *buf, uint32 buf_size)
+{
+	uint32 ring_size;
+
+	if (!dhdp || !buf) {
+		DHD_ERROR(("INVALID PTR: dhdp:%p buf:%p\n", dhdp, buf));
+		return BCME_ERROR;
+	}
+
+	ring_size = dhd_ring_get_hdr_size() + LOGDUMP_COOKIE_STR_LEN * MAX_LOGUDMP_COOKIE_CNT;
+	if (buf_size < ring_size) {
+		DHD_ERROR(("BUF SIZE IS TO SHORT: req:%d buf_size:%d\n",
+			ring_size, buf_size));
+		return BCME_ERROR;
+	}
+
+	dhdp->logdump_cookie = dhd_ring_init(dhdp, buf, buf_size,
+		LOGDUMP_COOKIE_STR_LEN, MAX_LOGUDMP_COOKIE_CNT,
+		DHD_RING_TYPE_FIXED);
+	if (!dhdp->logdump_cookie) {
+		DHD_ERROR(("FAIL TO INIT COOKIE RING\n"));
+		return BCME_ERROR;
+	}
+
+	return BCME_OK;
+}
+
+void
+dhd_logdump_cookie_deinit(dhd_pub_t *dhdp)
+{
+	if (!dhdp) {
+		return;
+	}
+	if (dhdp->logdump_cookie) {
+		dhd_ring_deinit(dhdp, dhdp->logdump_cookie);
+	}
+
+	return;
+}
+
+void
+dhd_logdump_cookie_save(dhd_pub_t *dhdp, char *cookie, char *type)
+{
+	char *ptr;
+
+	if (!dhdp || !cookie || !type || !dhdp->logdump_cookie) {
+		DHD_ERROR(("%s: At least one buffer ptr is NULL dhdp=%p cookie=%p"
+			" type = %p, cookie_cfg:%p\n", __FUNCTION__,
+			dhdp, cookie, type, dhdp?dhdp->logdump_cookie: NULL));
+		return;
+	}
+	ptr = (char *)dhd_ring_get_empty(dhdp->logdump_cookie);
+	if (ptr == NULL) {
+		DHD_ERROR(("%s : Skip to save due to locking\n", __FUNCTION__));
+		return;
+	}
+	scnprintf(ptr, LOGDUMP_COOKIE_STR_LEN, "%s: %s\n", type, cookie);
+	return;
+}
+
+int
+dhd_logdump_cookie_get(dhd_pub_t *dhdp, char *ret_cookie, uint32 buf_size)
+{
+	char *ptr;
+
+	if (!dhdp || !ret_cookie || !dhdp->logdump_cookie) {
+		DHD_ERROR(("%s: At least one buffer ptr is NULL dhdp=%p"
+			"cookie=%p cookie_cfg:%p\n", __FUNCTION__,
+			dhdp, ret_cookie, dhdp?dhdp->logdump_cookie: NULL));
+		return BCME_ERROR;
+	}
+	ptr = (char *)dhd_ring_get_first(dhdp->logdump_cookie);
+	if (ptr == NULL) {
+		DHD_ERROR(("%s : Skip to save due to locking\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+	memcpy(ret_cookie, ptr, MIN(buf_size, strlen(ptr)));
+	dhd_ring_free_first(dhdp->logdump_cookie);
+	return BCME_OK;
+}
+
+int
+dhd_logdump_cookie_count(dhd_pub_t *dhdp)
+{
+	if (!dhdp || !dhdp->logdump_cookie) {
+		DHD_ERROR(("%s: At least one buffer ptr is NULL dhdp=%p cookie=%p\n",
+			__FUNCTION__, dhdp, dhdp?dhdp->logdump_cookie: NULL));
+		return 0;
+	}
+	return dhd_ring_get_cur_size(dhdp->logdump_cookie);
+}
+
+static inline int
+__dhd_log_dump_cookie_to_file(
+	dhd_pub_t *dhdp, void *fp, const void *user_buf, unsigned long *f_pos,
+	char *buf, uint32 buf_size)
+{
+
+	uint32 remain = buf_size;
+	int ret = BCME_ERROR;
+	char tmp_buf[LOGDUMP_COOKIE_STR_LEN];
+	log_dump_section_hdr_t sec_hdr;
+	uint32 read_idx;
+	uint32 write_idx;
+
+	read_idx = dhd_ring_get_read_idx(dhdp->logdump_cookie);
+	write_idx = dhd_ring_get_write_idx(dhdp->logdump_cookie);
+	while (dhd_logdump_cookie_count(dhdp) > 0) {
+		memset(tmp_buf, 0, sizeof(tmp_buf));
+		ret = dhd_logdump_cookie_get(dhdp, tmp_buf, LOGDUMP_COOKIE_STR_LEN);
+		if (ret != BCME_OK) {
+			return ret;
+		}
+		remain -= scnprintf(&buf[buf_size - remain], remain, "%s", tmp_buf);
+	}
+	dhd_ring_set_read_idx(dhdp->logdump_cookie, read_idx);
+	dhd_ring_set_write_idx(dhdp->logdump_cookie, write_idx);
+
+	ret = dhd_export_debug_data(COOKIE_LOG_HDR, fp, user_buf, strlen(COOKIE_LOG_HDR), f_pos);
+	if (ret < 0) {
+		DHD_ERROR(("%s : Write file Error for cookie hdr\n", __FUNCTION__));
+		return ret;
+	}
+	sec_hdr.magic = LOG_DUMP_MAGIC;
+	sec_hdr.timestamp = local_clock();
+	sec_hdr.type = LOG_DUMP_SECTION_COOKIE;
+	sec_hdr.length = buf_size - remain;
+
+	ret = dhd_export_debug_data((char *)&sec_hdr, fp, user_buf, sizeof(sec_hdr), f_pos);
+	if (ret < 0) {
+		DHD_ERROR(("%s : Write file Error for section hdr\n", __FUNCTION__));
+		return ret;
+	}
+
+	ret = dhd_export_debug_data(buf, fp, user_buf, sec_hdr.length, f_pos);
+	if (ret < 0) {
+		DHD_ERROR(("%s : Write file Error for cookie data\n", __FUNCTION__));
+	}
+
+	return ret;
+}
+
+uint32
+dhd_log_dump_cookie_len(dhd_pub_t *dhdp)
+{
+	int len = 0;
+	char tmp_buf[LOGDUMP_COOKIE_STR_LEN];
+	log_dump_section_hdr_t sec_hdr;
+	char *buf = NULL;
+	int ret = BCME_ERROR;
+	uint32 buf_size = MAX_LOGUDMP_COOKIE_CNT * LOGDUMP_COOKIE_STR_LEN;
+	uint32 read_idx;
+	uint32 write_idx;
+	uint32 remain;
+
+	remain = buf_size;
+
+	if (!dhdp || !dhdp->logdump_cookie) {
+		DHD_ERROR(("%s At least one ptr is NULL "
+			"dhdp = %p cookie %p\n",
+			__FUNCTION__, dhdp, dhdp?dhdp->logdump_cookie:NULL));
+		goto exit;
+	}
+
+	buf = (char *)MALLOCZ(dhdp->osh, buf_size);
+	if (!buf) {
+		DHD_ERROR(("%s Fail to malloc buffer\n", __FUNCTION__));
+		goto exit;
+	}
+
+	read_idx = dhd_ring_get_read_idx(dhdp->logdump_cookie);
+	write_idx = dhd_ring_get_write_idx(dhdp->logdump_cookie);
+	while (dhd_logdump_cookie_count(dhdp) > 0) {
+		memset(tmp_buf, 0, sizeof(tmp_buf));
+		ret = dhd_logdump_cookie_get(dhdp, tmp_buf, LOGDUMP_COOKIE_STR_LEN);
+		if (ret != BCME_OK) {
+			goto exit;
+		}
+		remain -= (uint32)strlen(tmp_buf);
+	}
+	dhd_ring_set_read_idx(dhdp->logdump_cookie, read_idx);
+	dhd_ring_set_write_idx(dhdp->logdump_cookie, write_idx);
+	len += strlen(COOKIE_LOG_HDR);
+	len += sizeof(sec_hdr);
+	len += (buf_size - remain);
+exit:
+	if (buf)
+		MFREE(dhdp->osh, buf, buf_size);
+	return len;
+}
+
+int
+dhd_log_dump_cookie(dhd_pub_t *dhdp, const void *user_buf)
+{
+	int ret = BCME_ERROR;
+	char tmp_buf[LOGDUMP_COOKIE_STR_LEN];
+	log_dump_section_hdr_t sec_hdr;
+	char *buf = NULL;
+	uint32 buf_size = MAX_LOGUDMP_COOKIE_CNT * LOGDUMP_COOKIE_STR_LEN;
+	int pos = 0;
+	uint32 read_idx;
+	uint32 write_idx;
+	uint32 remain;
+
+	remain = buf_size;
+
+	if (!dhdp || !dhdp->logdump_cookie) {
+		DHD_ERROR(("%s At least one ptr is NULL "
+			"dhdp = %p cookie %p\n",
+			__FUNCTION__, dhdp, dhdp?dhdp->logdump_cookie:NULL));
+		goto exit;
+	}
+
+	buf = (char *)MALLOCZ(dhdp->osh, buf_size);
+	if (!buf) {
+		DHD_ERROR(("%s Fail to malloc buffer\n", __FUNCTION__));
+		goto exit;
+	}
+
+	read_idx = dhd_ring_get_read_idx(dhdp->logdump_cookie);
+	write_idx = dhd_ring_get_write_idx(dhdp->logdump_cookie);
+	while (dhd_logdump_cookie_count(dhdp) > 0) {
+		memset(tmp_buf, 0, sizeof(tmp_buf));
+		ret = dhd_logdump_cookie_get(dhdp, tmp_buf, LOGDUMP_COOKIE_STR_LEN);
+		if (ret != BCME_OK) {
+			goto exit;
+		}
+		remain -= scnprintf(&buf[buf_size - remain], remain, "%s", tmp_buf);
+	}
+	dhd_ring_set_read_idx(dhdp->logdump_cookie, read_idx);
+	dhd_ring_set_write_idx(dhdp->logdump_cookie, write_idx);
+	ret = dhd_export_debug_data(COOKIE_LOG_HDR, NULL, user_buf, strlen(COOKIE_LOG_HDR), &pos);
+	sec_hdr.magic = LOG_DUMP_MAGIC;
+	sec_hdr.timestamp = local_clock();
+	sec_hdr.type = LOG_DUMP_SECTION_COOKIE;
+	sec_hdr.length = buf_size - remain;
+	ret = dhd_export_debug_data((char *)&sec_hdr, NULL, user_buf, sizeof(sec_hdr), &pos);
+	ret = dhd_export_debug_data(buf, NULL, user_buf, sec_hdr.length, &pos);
+exit:
+	if (buf)
+		MFREE(dhdp->osh, buf, buf_size);
+	return ret;
+}
+
+int
+dhd_log_dump_cookie_to_file(dhd_pub_t *dhdp, void *fp, const void *user_buf, unsigned long *f_pos)
+{
+	char *buf;
+	int ret = BCME_ERROR;
+	uint32 buf_size = MAX_LOGUDMP_COOKIE_CNT * LOGDUMP_COOKIE_STR_LEN;
+
+#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
+	if (!dhdp || !dhdp->logdump_cookie)
+#else
+	if (!dhdp || !dhdp->logdump_cookie || (!fp && !user_buf) || !f_pos)
+#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
+	{
+		DHD_ERROR(("%s At least one ptr is NULL "
+			"dhdp = %p cookie %p fp = %p f_pos = %p\n",
+			__FUNCTION__, dhdp, dhdp?dhdp->logdump_cookie:NULL, fp, f_pos));
+		return ret;
+	}
+
+	buf = (char *)MALLOCZ(dhdp->osh, buf_size);
+	if (!buf) {
+		DHD_ERROR(("%s Fail to malloc buffer\n", __FUNCTION__));
+		return ret;
+	}
+	ret = __dhd_log_dump_cookie_to_file(dhdp, fp, user_buf, f_pos, buf, buf_size);
+	MFREE(dhdp->osh, buf, buf_size);
+
+	return ret;
+}
+
+void
+get_debug_dump_time(char *str)
+{
+	struct osl_timespec curtime;
+	unsigned long long local_time;
+	struct rtc_time tm;
+
+	if (!strlen(str)) {
+		osl_do_gettimeofday(&curtime);
+		local_time = (u64)(curtime.tv_sec -
+				(sys_tz.tz_minuteswest * DHD_LOG_DUMP_TS_MULTIPLIER_VALUE));
+		rtc_time_to_tm(local_time, &tm);
+		snprintf(str, DEBUG_DUMP_TIME_BUF_LEN, DHD_LOG_DUMP_TS_FMT_YYMMDDHHMMSSMSMS,
+				tm.tm_year - 100, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min,
+				tm.tm_sec, curtime.tv_nsec/NSEC_PER_MSEC);
+	}
+}
+
+void
+clear_debug_dump_time(char *str)
+{
+	memset(str, 0, DEBUG_DUMP_TIME_BUF_LEN);
+}
+#if defined(WL_CFGVENDOR_SEND_HANG_EVENT) || defined(DHD_PKT_LOGGING)
+void
+copy_debug_dump_time(char *dest, char *src)
+{
+	memcpy(dest, src, DEBUG_DUMP_TIME_BUF_LEN);
+}
+#endif
+
+#ifdef DHD_IOVAR_LOG_FILTER_DUMP
+typedef struct iovar_log_filter_table {
+	char command[64];
+	int  enable;
+} iovar_log_filter_table_t;
+
+/* WLC_GET_VAR is not being logged by default. Add for logging in debug_dump. */
+static const iovar_log_filter_table_t iovar_get_filter_params[] = {
+	{"cur_etheraddr", TRUE},
+	{"\0", TRUE}
+};
+
+/* WLC_SET_VAR is being logged by default. Add for not logging in debug_dump. */
+static const iovar_log_filter_table_t iovar_set_filter_params[] = {
+	{"pkt_filter_enable", FALSE},
+	{"pkt_filter_mode", FALSE},
+	{"\0", FALSE}
+};
+
+bool
+dhd_iovar_log_dump_check(dhd_pub_t *dhd_pub, uint32 cmd, char *msg)
+{
+	int cnt = 0;
+	const iovar_log_filter_table_t *table;
+	bool ret_val = TRUE;
+
+	/* Logging all IOVARs with DHD_IOVAR_MEM() in debug_dump file
+	 * during during Wifi ON.
+	 */
+	if (dhd_pub->up == FALSE) {
+		return TRUE;
+	}
+
+	if (cmd == WLC_GET_VAR) {
+		ret_val = FALSE;
+		table = iovar_get_filter_params;
+	} else if (cmd == WLC_SET_VAR) {
+		ret_val = TRUE;
+		table = iovar_set_filter_params;
+	} else {
+		return TRUE;
+	}
+	while (strlen(table[cnt].command) > 0) {
+		if (!strncmp(msg, table[cnt].command,
+				strlen(table[cnt].command))) {
+			return table[cnt].enable;
+		}
+
+		cnt++;
+	}
+
+	return ret_val;
+}
+#endif /* DHD_IOVAR_LOG_FILTER_DUMP */
+#endif /* DHD_LOG_DUMP */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_log_dump.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_log_dump.h
@@ -0,0 +1,421 @@
+/*
+ * log_dump - debugability support for dumping logs to file - header file
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+#ifndef __DHD_LOG_DUMP_H__
+#define __DHD_LOG_DUMP_H__
+
+#ifdef DHD_LOG_DUMP
+
+#include <dhd.h>
+
+#define LOG_DUMP_MAGIC 0xDEB3DEB3
+#ifdef EWP_ECNTRS_LOGGING
+#define ECNTR_RING_ID 0xECDB
+#define	ECNTR_RING_NAME	"ewp_ecntr_ring"
+#endif /* EWP_ECNTRS_LOGGING */
+
+#ifdef EWP_RTT_LOGGING
+#define	RTT_RING_ID 0xADCD
+#define	RTT_RING_NAME	"ewp_rtt_ring"
+#endif /* EWP_ECNTRS_LOGGING */
+
+#ifdef EWP_BCM_TRACE
+#define	BCM_TRACE_RING_ID 0xBCBC
+#define	BCM_TRACE_RING_NAME "ewp_bcm_trace_ring"
+#endif /* EWP_BCM_TRACE */
+
+#define DHD_LOG_DUMP_MAX_TEMP_BUFFER_SIZE	512
+#define DHD_LOG_DUMP_MAX_TAIL_FLUSH_SIZE (80 * 1024)
+#define DHD_LOG_DUMP_TS_MULTIPLIER_VALUE    60
+#define DHD_LOG_DUMP_TS_FMT_YYMMDDHHMMSSMSMS    "%02d%02d%02d%02d%02d%02d%04lu"
+#define DHD_LOG_DUMP_TS_FMT_YYMMDDHHMMSS        "%02d%02d%02d%02d%02d%02d"
+#define DHD_DEBUG_DUMP_TYPE		"debug_dump"
+#define DEBUG_DUMP_TRIGGER_INTERVAL_SEC	4
+
+#ifndef _DHD_LOG_DUMP_DEFINITIONS_
+#define _DHD_LOG_DUMP_DEFINITIONS_
+#define GENERAL_LOG_HDR "\n-------------------- General log ---------------------------\n"
+#define PRESERVE_LOG_HDR "\n-------------------- Preserve log ---------------------------\n"
+#define SPECIAL_LOG_HDR "\n-------------------- Special log ---------------------------\n"
+#define DHD_DUMP_LOG_HDR "\n-------------------- 'dhd dump' log -----------------------\n"
+#define EXT_TRAP_LOG_HDR "\n-------------------- Extended trap data -------------------\n"
+#define HEALTH_CHK_LOG_HDR "\n-------------------- Health check data --------------------\n"
+#ifdef DHD_DUMP_PCIE_RINGS
+#define RING_DUMP_HDR "\n-------------------- Ring dump --------------------\n"
+#endif /* DHD_DUMP_PCIE_RINGS */
+#define DHD_LOG_DUMP_DLD(fmt, ...) \
+	dhd_log_dump_write(DLD_BUF_TYPE_GENERAL, NULL, 0, fmt, ##__VA_ARGS__)
+#define DHD_LOG_DUMP_DLD_EX(fmt, ...) \
+	dhd_log_dump_write(DLD_BUF_TYPE_SPECIAL, NULL, 0, fmt, ##__VA_ARGS__)
+#define DHD_LOG_DUMP_DLD_PRSRV(fmt, ...) \
+	dhd_log_dump_write(DLD_BUF_TYPE_PRESERVE, NULL, 0, fmt, ##__VA_ARGS__)
+#endif /* !_DHD_LOG_DUMP_DEFINITIONS_ */
+
+#ifndef DHD_LOG_DUMP_RING_DEFINITIONS
+#define DHD_LOG_DUMP_RING_DEFINITIONS
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+/* Enabled DHD_DEBUGABILITY_LOG_DUMP_RING */
+#define DHD_DBG_RING(fmt, ...) \
+	dhd_dbg_ring_write(DRIVER_LOG_RING_ID, NULL, 0, fmt, ##__VA_ARGS__)
+#define DHD_DBG_RING_EX(fmt, ...) \
+	dhd_dbg_ring_write(FW_VERBOSE_RING_ID, NULL, 0, fmt, ##__VA_ARGS__)
+#define DHD_DBG_RING_ROAM(fmt, ...) \
+	dhd_dbg_ring_write(ROAM_STATS_RING_ID, NULL, 0, fmt, ##__VA_ARGS__)
+
+#define DHD_LOG_DUMP_WRITE		DHD_DBG_RING
+#define DHD_LOG_DUMP_WRITE_EX		DHD_DBG_RING_EX
+#define DHD_LOG_DUMP_WRITE_PRSRV	DHD_DBG_RING_EX
+#define DHD_LOG_DUMP_WRITE_ROAM		DHD_DBG_RING_ROAM
+
+#define DHD_PREFIX_TS "[%s][%s] ",	\
+	OSL_GET_RTCTIME(), dhd_log_dump_get_timestamp()
+#define DHD_PREFIX_TS_FN "[%s][%s] %s: ",	\
+	OSL_GET_RTCTIME(), dhd_log_dump_get_timestamp(), __func__
+#define DHD_LOG_DUMP_WRITE_TS		DHD_DBG_RING(DHD_PREFIX_TS)
+#define DHD_LOG_DUMP_WRITE_TS_FN	DHD_DBG_RING(DHD_PREFIX_TS_FN)
+#define DHD_LOG_DUMP_WRITE_EX_TS	DHD_DBG_RING_EX(DHD_PREFIX_TS)
+#define DHD_LOG_DUMP_WRITE_EX_TS_FN	DHD_DBG_RING_EX(DHD_PREFIX_TS_FN)
+#define DHD_LOG_DUMP_WRITE_PRSRV_TS	DHD_DBG_RING_EX(DHD_PREFIX_TS)
+#define DHD_LOG_DUMP_WRITE_PRSRV_TS_FN	DHD_DBG_RING_EX(DHD_PREFIX_TS_FN)
+#define DHD_LOG_DUMP_WRITE_ROAM_TS	DHD_DBG_RING_ROAM(DHD_PREFIX_TS)
+#define DHD_LOG_DUMP_WRITE_ROAM_TS_FN	DHD_DBG_RING_ROAM(DHD_PREFIX_TS_FN)
+#else
+/* Not enabled DHD_DEBUGABILITY_LOG_DUMP_RING */
+#define DHD_LOG_DUMP_WRITE             DHD_LOG_DUMP_DLD
+#define DHD_LOG_DUMP_WRITE_EX          DHD_LOG_DUMP_DLD_EX
+#define DHD_LOG_DUMP_WRITE_PRSRV       DHD_LOG_DUMP_DLD_PRSRV
+#define DHD_LOG_DUMP_WRITE_ROAM                DHD_LOG_DUMP_DLD
+
+#define DHD_PREFIX_TS "[%s]: ", dhd_log_dump_get_timestamp()
+#define DHD_PREFIX_TS_FN "[%s] %s: ", dhd_log_dump_get_timestamp(), __func__
+#define DHD_LOG_DUMP_WRITE_TS          DHD_LOG_DUMP_DLD(DHD_PREFIX_TS)
+#define DHD_LOG_DUMP_WRITE_TS_FN       DHD_LOG_DUMP_DLD(DHD_PREFIX_TS_FN)
+#define DHD_LOG_DUMP_WRITE_EX_TS       DHD_LOG_DUMP_DLD_EX(DHD_PREFIX_TS)
+#define DHD_LOG_DUMP_WRITE_EX_TS_FN    DHD_LOG_DUMP_DLD_EX(DHD_PREFIX_TS_FN)
+#define DHD_LOG_DUMP_WRITE_PRSRV_TS    DHD_LOG_DUMP_DLD_PRSRV(DHD_PREFIX_TS)
+#define DHD_LOG_DUMP_WRITE_PRSRV_TS_FN DHD_LOG_DUMP_DLD_PRSRV(DHD_PREFIX_TS_FN)
+#define DHD_LOG_DUMP_WRITE_ROAM_TS     DHD_LOG_DUMP_DLD(DHD_PREFIX_TS)
+#define DHD_LOG_DUMP_WRITE_ROAM_TS_FN  DHD_LOG_DUMP_DLD(DHD_PREFIX_TS_FN)
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
+#endif /* DHD_LOG_DUMP_RING_DEFINITIONS */
+
+#define CONCISE_DUMP_BUFLEN 32 * 1024
+#define ECNTRS_LOG_HDR "\n-------------------- Ecounters log --------------------------\n"
+#ifdef DHD_STATUS_LOGGING
+#define STATUS_LOG_HDR "\n-------------------- Status log -----------------------\n"
+#endif /* DHD_STATUS_LOGGING */
+#define RTT_LOG_HDR "\n-------------------- RTT log --------------------------\n"
+#define BCM_TRACE_LOG_HDR "\n-------------------- BCM Trace log --------------------------\n"
+#define COOKIE_LOG_HDR "\n-------------------- Cookie List ----------------------------\n"
+#define DHD_PKTID_MAP_LOG_HDR "\n---------------- PKTID MAP log -----------------------\n"
+#define DHD_PKTID_UNMAP_LOG_HDR "\n------------------ PKTID UNMAP log -----------------------\n"
+#define PKTID_LOG_DUMP_FMT \
+	"\nIndex \t\tTimestamp \tPktaddr(PA) \tPktid \tSize \tPkttype\n(Current=%d)\n"
+
+/* 0: DLD_BUF_TYPE_GENERAL, 1: DLD_BUF_TYPE_PRESERVE
+* 2: DLD_BUF_TYPE_SPECIAL
+*/
+#define DLD_BUFFER_NUM 3
+
+#ifndef CUSTOM_LOG_DUMP_BUFSIZE_MB
+#define CUSTOM_LOG_DUMP_BUFSIZE_MB	4 /* DHD_LOG_DUMP_BUF_SIZE 4 MB static memory in kernel */
+#endif /* CUSTOM_LOG_DUMP_BUFSIZE_MB */
+
+#define LOG_DUMP_TOTAL_BUFSIZE (1024 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
+
+/*
+ * Below are different sections that use the prealloced buffer
+ * and sum of the sizes of these should not cross LOG_DUMP_TOTAL_BUFSIZE
+ */
+#ifdef EWP_BCM_TRACE
+#define LOG_DUMP_GENERAL_MAX_BUFSIZE (192 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
+#define LOG_DUMP_BCM_TRACE_MAX_BUFSIZE (64 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
+#else
+#define LOG_DUMP_GENERAL_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
+#define LOG_DUMP_BCM_TRACE_MAX_BUFSIZE 0
+#endif /* EWP_BCM_TRACE */
+#define LOG_DUMP_PRESERVE_MAX_BUFSIZE (128 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
+#define LOG_DUMP_ECNTRS_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
+#define LOG_DUMP_RTT_MAX_BUFSIZE (256 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
+#define LOG_DUMP_FILTER_MAX_BUFSIZE (128 * 1024 * CUSTOM_LOG_DUMP_BUFSIZE_MB)
+
+#if LOG_DUMP_TOTAL_BUFSIZE < (LOG_DUMP_GENERAL_MAX_BUFSIZE + \
+	LOG_DUMP_PRESERVE_MAX_BUFSIZE + LOG_DUMP_ECNTRS_MAX_BUFSIZE + LOG_DUMP_RTT_MAX_BUFSIZE \
+	+ LOG_DUMP_BCM_TRACE_MAX_BUFSIZE + LOG_DUMP_FILTER_MAX_BUFSIZE)
+#error "LOG_DUMP_TOTAL_BUFSIZE is lesser than sum of all rings"
+#endif
+
+/* Special buffer is allocated as separately in prealloc */
+#define LOG_DUMP_SPECIAL_MAX_BUFSIZE (8 * 1024)
+
+#define LOG_DUMP_MAX_FILESIZE (8 *1024 * 1024) /* 8 MB default */
+
+#ifdef CONFIG_LOG_BUF_SHIFT
+/* 15% of kernel log buf size, if for example klog buf size is 512KB
+* 15% of 512KB ~= 80KB
+*/
+#define LOG_DUMP_KERNEL_TAIL_FLUSH_SIZE \
+	(15 * ((1 << CONFIG_LOG_BUF_SHIFT)/100))
+#endif /* CONFIG_LOG_BUF_SHIFT */
+
+#define LOG_DUMP_COOKIE_BUFSIZE	1024u
+#define DHD_PRINT_BUF_NAME_LEN 30
+
+#ifdef DHD_SSSR_DUMP
+#define DUMP_SSSR_ATTR_START	2
+#define DUMP_SSSR_ATTR_COUNT	10
+
+typedef enum {
+	SSSR_C0_D11_BEFORE = 0,
+	SSSR_C0_D11_AFTER = 1,
+	SSSR_C1_D11_BEFORE = 2,
+	SSSR_C1_D11_AFTER = 3,
+	SSSR_C2_D11_BEFORE = 4,
+	SSSR_C2_D11_AFTER = 5,
+	SSSR_DIG_BEFORE = 6,
+	SSSR_DIG_AFTER = 7
+} EWP_SSSR_DUMP;
+#endif /* DHD_SSSR_DUMP */
+
+typedef enum {
+	DLD_BUF_TYPE_GENERAL = 0,
+	DLD_BUF_TYPE_PRESERVE = 1,
+	DLD_BUF_TYPE_SPECIAL = 2,
+	DLD_BUF_TYPE_ECNTRS = 3,
+	DLD_BUF_TYPE_FILTER = 4,
+	DLD_BUF_TYPE_ALL = 5
+} log_dump_type_t;
+
+/*
+ * XXX: Always add new enums at the end to compatible with parser,
+ * also add new section in split_ret of EWP_config.py
+ */
+typedef enum {
+	LOG_DUMP_SECTION_GENERAL = 0,
+	LOG_DUMP_SECTION_ECNTRS,
+	LOG_DUMP_SECTION_SPECIAL,
+	LOG_DUMP_SECTION_DHD_DUMP,
+	LOG_DUMP_SECTION_EXT_TRAP,
+	LOG_DUMP_SECTION_HEALTH_CHK,
+	LOG_DUMP_SECTION_PRESERVE,
+	LOG_DUMP_SECTION_COOKIE,
+	LOG_DUMP_SECTION_RING,
+	LOG_DUMP_SECTION_STATUS,
+	LOG_DUMP_SECTION_RTT,
+	LOG_DUMP_SECTION_BCM_TRACE,
+	LOG_DUMP_SECTION_PKTID_MAP_LOG,
+	LOG_DUMP_SECTION_PKTID_UNMAP_LOG,
+	LOG_DUMP_SECTION_TIMESTAMP,
+	LOG_DUMP_SECTION_MAX
+} log_dump_section_type_t;
+
+/* Each section in the debug_dump log file shall begin with a header */
+typedef struct {
+	uint32 magic;  /* 0xDEB3DEB3 */
+	uint32 type;   /* of type log_dump_section_type_t */
+	uint64 timestamp;
+	uint32 length;  /* length of the section that follows */
+} log_dump_section_hdr_t;
+
+#ifdef DHD_DEBUGABILITY_LOG_DUMP_RING
+struct dhd_dbg_ring_buf
+{
+	void *dhd_pub;
+};
+extern struct dhd_dbg_ring_buf g_ring_buf;
+#endif /* DHD_DEBUGABILITY_LOG_DUMP_RING */
+
+typedef struct dhd_debug_dump_ring_entry {
+	log_dump_section_type_t type;
+	uint32 debug_dump_ring;
+} dhd_debug_dump_ring_entry_t;
+
+/* below structure describe ring buffer. */
+struct dhd_log_dump_buf
+{
+#if defined(LINUX) || defined(linux) || defined(ANDROID) || defined(OEM_ANDROID)
+	spinlock_t lock;
+#endif
+	void *dhd_pub;
+	unsigned int enable;
+	unsigned int wraparound;
+	unsigned long max;
+	unsigned int remain;
+	char* present;
+	char* front;
+	char* buffer;
+};
+
+typedef struct {
+	char *hdr_str;
+	log_dump_section_type_t sec_type;
+} dld_hdr_t;
+
+extern void dhd_log_dump_write(int type, char *binary_data,
+		int binary_len, const char *fmt, ...);
+void dhd_schedule_log_dump(dhd_pub_t *dhdp, void *type);
+void dhd_log_dump_trigger(dhd_pub_t *dhdp, int subcmd);
+void dhd_log_dump_vendor_trigger(dhd_pub_t *dhd_pub);
+
+#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
+int dhd_debug_dump_get_ring_num(int sec_type);
+#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
+int dhd_log_dump_ring_to_file(dhd_pub_t *dhdp, void *ring_ptr, void *file,
+		unsigned long *file_posn, log_dump_section_hdr_t *sec_hdr, char *text_hdr,
+		uint32 sec_type);
+int dhd_dump_debug_ring(dhd_pub_t *dhdp, void *ring_ptr, const void *user_buf,
+		log_dump_section_hdr_t *sec_hdr, char *text_hdr, int buflen, uint32 sec_type);
+int dhd_log_dump_cookie_to_file(dhd_pub_t *dhdp, void *fp,
+	const void *user_buf, unsigned long *f_pos);
+int dhd_log_dump_cookie(dhd_pub_t *dhdp, const void *user_buf);
+uint32 dhd_log_dump_cookie_len(dhd_pub_t *dhdp);
+int dhd_logdump_cookie_init(dhd_pub_t *dhdp, uint8 *buf, uint32 buf_size);
+void dhd_logdump_cookie_deinit(dhd_pub_t *dhdp);
+void dhd_logdump_cookie_save(dhd_pub_t *dhdp, char *cookie, char *type);
+int dhd_logdump_cookie_get(dhd_pub_t *dhdp, char *ret_cookie, uint32 buf_size);
+int dhd_logdump_cookie_count(dhd_pub_t *dhdp);
+int dhd_get_dld_log_dump(void *dev, dhd_pub_t *dhdp, const void *user_buf, void *fp,
+	uint32 len, int type, void *pos);
+#if defined(BCMPCIE)
+int dhd_print_ext_trap_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, void *pos);
+uint32 dhd_get_ext_trap_len(void *ndev, dhd_pub_t *dhdp);
+#endif /* BCMPCIE */
+int dhd_print_dump_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, void *pos);
+int dhd_print_cookie_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, void *pos);
+int dhd_print_health_chk_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, void *pos);
+int dhd_print_time_str(const void *user_buf, void *fp, uint32 len, void *pos);
+#ifdef DHD_DUMP_PCIE_RINGS
+int dhd_print_flowring_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, void *pos);
+uint32 dhd_get_flowring_len(void *ndev, dhd_pub_t *dhdp);
+#endif /* DHD_DUMP_PCIE_RINGS */
+#ifdef DHD_STATUS_LOGGING
+extern int dhd_print_status_log_data(void *dev, dhd_pub_t *dhdp,
+	const void *user_buf, void *fp, uint32 len, void *pos);
+extern uint32 dhd_get_status_log_len(void *ndev, dhd_pub_t *dhdp);
+#endif /* DHD_STATUS_LOGGING */
+#ifdef DHD_MAP_PKTID_LOGGING
+extern uint32 dhd_pktid_buf_len(dhd_pub_t *dhd, bool is_map);
+extern int dhd_print_pktid_map_log_data(void *dev, dhd_pub_t *dhdp,
+	const void *user_buf, void *fp, uint32 len, void *pos, bool is_map);
+extern int dhd_write_pktid_log_dump(dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, unsigned long *pos, bool is_map);
+extern uint32 dhd_get_pktid_map_logging_len(void *ndev, dhd_pub_t *dhdp, bool is_map);
+#endif /* DHD_MAP_PKTID_LOGGING */
+int dhd_print_ecntrs_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, void *pos);
+int dhd_print_rtt_data(void *dev, dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, void *pos);
+int dhd_get_debug_dump_file_name(void *dev, dhd_pub_t *dhdp,
+	char *dump_path, int size);
+uint32 dhd_get_time_str_len(void);
+uint32 dhd_get_health_chk_len(void *ndev, dhd_pub_t *dhdp);
+uint32 dhd_get_dhd_dump_len(void *ndev, dhd_pub_t *dhdp);
+uint32 dhd_get_cookie_log_len(void *ndev, dhd_pub_t *dhdp);
+uint32 dhd_get_ecntrs_len(void *ndev, dhd_pub_t *dhdp);
+uint32 dhd_get_rtt_len(void *ndev, dhd_pub_t *dhdp);
+uint32 dhd_get_dld_len(int log_type);
+void dhd_init_sec_hdr(log_dump_section_hdr_t *sec_hdr);
+extern char *dhd_log_dump_get_timestamp(void);
+bool dhd_log_dump_ecntr_enabled(void);
+bool dhd_log_dump_rtt_enabled(void);
+void dhd_nla_put_sssr_dump_len(void *ndev, uint32 *arr_len);
+int dhd_get_debug_dump(void *dev, const void *user_buf, uint32 len, int type);
+#ifdef DHD_SSSR_DUMP_BEFORE_SR
+int
+dhd_sssr_dump_d11_buf_before(void *dev, const void *user_buf, uint32 len, int core);
+int
+dhd_sssr_dump_dig_buf_before(void *dev, const void *user_buf, uint32 len);
+#endif /* DHD_SSSR_DUMP_BEFORE_SR */
+int
+dhd_sssr_dump_d11_buf_after(void *dev, const void *user_buf, uint32 len, int core);
+int
+dhd_sssr_dump_dig_buf_after(void *dev, const void *user_buf, uint32 len);
+#ifdef DHD_PKT_LOGGING
+extern int dhd_os_get_pktlog_dump(void *dev, const void *user_buf, uint32 len);
+extern spinlock_t* dhd_os_get_pktlog_lock(dhd_pub_t *dhdp);
+extern uint32 dhd_os_get_pktlog_dump_size(struct net_device *dev);
+extern void dhd_os_get_pktlogdump_filename(struct net_device *dev, char *dump_path, int len);
+#endif /* DHD_PKT_LOGGING */
+
+#ifdef DNGL_AXI_ERROR_LOGGING
+extern int dhd_os_get_axi_error_dump(void *dev, const void *user_buf, uint32 len);
+extern int dhd_os_get_axi_error_dump_size(struct net_device *dev);
+extern void dhd_os_get_axi_error_filename(struct net_device *dev, char *dump_path, int len);
+#endif /*  DNGL_AXI_ERROR_LOGGING */
+
+#ifdef DHD_DEBUGABILITY_DEBUG_DUMP
+extern int dhd_debug_dump_to_ring(dhd_pub_t *dhdp);
+#endif /* DHD_DEBUGABILITY_DEBUG_DUMP */
+
+extern char *dhd_log_dump_get_timestamp(void);
+extern void dhd_dbg_ring_write(int type, char *binary_data,
+	int binary_len, const char *fmt, ...);
+
+void dhd_log_dump_init(dhd_pub_t *dhd);
+void dhd_log_dump_deinit(dhd_pub_t *dhd);
+void dhd_log_dump(void *handle, void *event_info, uint8 event);
+int do_dhd_log_dump(dhd_pub_t *dhdp, log_dump_type_t *type);
+void dhd_print_buf_addr(dhd_pub_t *dhdp, char *name, void *buf, unsigned int size);
+void dhd_log_dump_buf_addr(dhd_pub_t *dhdp, log_dump_type_t *type);
+int dhd_log_flush(dhd_pub_t *dhdp, log_dump_type_t *type);
+
+extern void get_debug_dump_time(char *str);
+extern void clear_debug_dump_time(char *str);
+#if defined(WL_CFGVENDOR_SEND_HANG_EVENT) || defined(DHD_PKT_LOGGING)
+extern void copy_debug_dump_time(char *dest, char *src);
+#endif
+
+void dhd_get_debug_dump_len(void *handle, struct sk_buff *skb, void *event_info, uint8 event);
+void cfgvendor_log_dump_len(dhd_pub_t *dhdp, log_dump_type_t *type, struct sk_buff *skb);
+#ifdef DHD_IOVAR_LOG_FILTER_DUMP
+bool dhd_iovar_log_dump_check(dhd_pub_t *dhd_pub, uint32 cmd, char *msg);
+#endif /* DHD_IOVAR_LOG_FILTER_DUMP */
+#endif /* DHD_LOG_DUMP */
+
+#endif /* !__DHD_LOG_DUMP_H__ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_mschdbg.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_mschdbg.c
@@ -0,0 +1,815 @@
+/*
+ * DHD debugability support
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id: dhd_mschdbg.c 639872 2016-05-25 05:39:30Z $
+ */
+#ifdef SHOW_LOGTRACE
+#include <typedefs.h>
+#include <osl.h>
+#include <bcmutils.h>
+#include <bcmendian.h>
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_dbg.h>
+#include <dhd_debug.h>
+#include <dhd_mschdbg.h>
+
+#include <event_log.h>
+#include <event_trace.h>
+#include <msgtrace.h>
+
+static const char *head_log = "";
+#define MSCH_EVENT_HEAD(space) \
+	do { \
+		MSCH_EVENT(("%s_E:  ", head_log)); \
+		if (space > 0) { \
+			int ii; \
+			for (ii = 0; ii < space; ii += 4) MSCH_EVENT(("    ")); \
+		} \
+	} while (0)
+
+#if defined(CUSTOM_PREFIX)
+#define MSCH_EVENT(args) \
+do {	\
+	if (dhd_msg_level & DHD_EVENT_VAL) {	\
+		DBG_PRINT_SYSTEM_TIME;  \
+		pr_cont args;	\
+	}	\
+} while (0)
+#else
+#define MSCH_EVENT(args) do {if (dhd_msg_level & DHD_EVENT_VAL) printf args;} while (0)
+#endif
+
+static uint64 solt_start_time[4], req_start_time[4], profiler_start_time[4];
+static uint32 solt_chanspec[4] = {0, }, req_start[4] = {0, };
+static bool lastMessages = FALSE;
+
+#define US_PRE_SEC		1000000
+#define DATA_UNIT_FOR_LOG_CNT	4
+
+static void dhd_mschdbg_us_to_sec(uint32 time_h, uint32 time_l, uint32 *sec, uint32 *remain)
+{
+	uint64 cur_time = ((uint64)(ntoh32(time_h)) << 32) | ntoh32(time_l);
+	uint64 r, u = 0;
+
+	r = cur_time;
+	while (time_h != 0) {
+		u += (uint64)((0xffffffff / US_PRE_SEC)) * time_h;
+		r = cur_time - u * US_PRE_SEC;
+		time_h = (uint32)(r >> 32);
+	}
+
+	*sec = (uint32)(u + ((uint32)(r) / US_PRE_SEC));
+	*remain = (uint32)(r) % US_PRE_SEC;
+}
+
+static char *dhd_mschdbg_display_time(uint32 time_h, uint32 time_l)
+{
+	static char display_time[32];
+	uint32 s, ss;
+
+	if (time_h == 0xffffffff && time_l == 0xffffffff) {
+		snprintf(display_time, 31, "-1");
+	} else {
+		dhd_mschdbg_us_to_sec(time_h, time_l, &s, &ss);
+		snprintf(display_time, 31, "%d.%06d", s, ss);
+	}
+	return display_time;
+}
+
+static void
+dhd_mschdbg_chanspec_list(int sp, char *data, uint16 ptr, uint16 chanspec_cnt)
+{
+	int i, cnt = (int)ntoh16(chanspec_cnt);
+	uint16 *chanspec_list = (uint16 *)(data + ntoh16(ptr));
+	char buf[CHANSPEC_STR_LEN];
+	chanspec_t c;
+
+	MSCH_EVENT_HEAD(sp);
+	MSCH_EVENT(("<chanspec_list>:"));
+	for (i = 0; i < cnt; i++) {
+		c = (chanspec_t)ntoh16(chanspec_list[i]);
+		MSCH_EVENT((" %s", wf_chspec_ntoa(c, buf)));
+	}
+	MSCH_EVENT(("\n"));
+}
+
+static void
+dhd_mschdbg_elem_list(int sp, char *title, char *data, uint16 ptr, uint16 list_cnt)
+{
+	int i, cnt = (int)ntoh16(list_cnt);
+	uint32 *list = (uint32 *)(data + ntoh16(ptr));
+
+	MSCH_EVENT_HEAD(sp);
+	MSCH_EVENT(("%s_list: ", title));
+	for (i = 0; i < cnt; i++) {
+		MSCH_EVENT(("0x%08x->", ntoh32(list[i])));
+	}
+	MSCH_EVENT(("null\n"));
+}
+
+static void
+dhd_mschdbg_req_param_profiler_event_data(int sp, int ver, char *data, uint16 ptr)
+{
+	int sn = sp + 4;
+	msch_req_param_profiler_event_data_t *p =
+		(msch_req_param_profiler_event_data_t *)(data + ntoh16(ptr));
+	uint32 type, flags;
+
+	MSCH_EVENT_HEAD(sp);
+	MSCH_EVENT(("<request parameters>\n"));
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("req_type: "));
+
+	type = p->req_type;
+	if (type < 4) {
+		char *req_type[] = {"fixed", "start-flexible", "duration-flexible",
+			"both-flexible"};
+		MSCH_EVENT(("%s", req_type[type]));
+	}
+	else
+		MSCH_EVENT(("unknown(%d)", type));
+
+	flags = ntoh16(p->flags);
+	if (flags & WL_MSCH_REQ_FLAGS_CHAN_CONTIGUOUS)
+		MSCH_EVENT((", CHAN_CONTIGUOUS"));
+	if (flags & WL_MSCH_REQ_FLAGS_MERGE_CONT_SLOTS)
+		MSCH_EVENT((", MERGE_CONT_SLOTS"));
+	if (flags & WL_MSCH_REQ_FLAGS_PREMTABLE)
+		MSCH_EVENT((", PREMTABLE"));
+	if (flags & WL_MSCH_REQ_FLAGS_PREMT_CURTS)
+		MSCH_EVENT((", PREMT_CURTS"));
+	if (flags & WL_MSCH_REQ_FLAGS_PREMT_IMMEDIATE)
+		MSCH_EVENT((", PREMT_IMMEDIATE"));
+	MSCH_EVENT((", priority: %d\n", p->priority));
+
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("start-time: %s, duration: %d(us), interval: %d(us)\n",
+		dhd_mschdbg_display_time(p->start_time_h, p->start_time_l),
+		ntoh32(p->duration), ntoh32(p->interval)));
+
+	if (type == WL_MSCH_RT_DUR_FLEX) {
+		MSCH_EVENT_HEAD(sn);
+		MSCH_EVENT(("dur_flex: %d(us)\n", ntoh32(p->flex.dur_flex)));
+	} else if (type == WL_MSCH_RT_BOTH_FLEX) {
+		MSCH_EVENT_HEAD(sn);
+		MSCH_EVENT(("min_dur: %d(us), max_away_dur: %d(us)\n",
+			ntoh32(p->flex.bf.min_dur), ntoh32(p->flex.bf.max_away_dur)));
+
+		MSCH_EVENT_HEAD(sn);
+		MSCH_EVENT(("hi_prio_time: %s, hi_prio_interval: %d(us)\n",
+			dhd_mschdbg_display_time(p->flex.bf.hi_prio_time_h,
+			p->flex.bf.hi_prio_time_l),
+			ntoh32(p->flex.bf.hi_prio_interval)));
+	}
+}
+
+static void
+dhd_mschdbg_timeslot_profiler_event_data(int sp, int ver, char *title, char *data,
+	uint16 ptr, bool empty)
+{
+	int s, sn = sp + 4;
+	msch_timeslot_profiler_event_data_t *p =
+		(msch_timeslot_profiler_event_data_t *)(data + ntoh16(ptr));
+	char *state[] = {"NONE", "CHN_SW", "ONCHAN_FIRE", "OFF_CHN_PREP",
+		"OFF_CHN_DONE", "TS_COMPLETE"};
+
+	MSCH_EVENT_HEAD(sp);
+	MSCH_EVENT(("<%s timeslot>: ", title));
+	if (empty) {
+		MSCH_EVENT((" null\n"));
+		return;
+	}
+	else
+		MSCH_EVENT(("0x%08x\n", ntoh32(p->p_timeslot)));
+
+	s = (int)(ntoh32(p->state));
+	if (s < 0 || s > 5) s = 0;
+
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("id: %d, state[%d]: %s, chan_ctxt: [0x%08x]\n",
+		ntoh32(p->timeslot_id), ntoh32(p->state), state[s], ntoh32(p->p_chan_ctxt)));
+
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("fire_time: %s",
+		dhd_mschdbg_display_time(p->fire_time_h, p->fire_time_l)));
+
+	MSCH_EVENT((", pre_start_time: %s",
+		dhd_mschdbg_display_time(p->pre_start_time_h, p->pre_start_time_l)));
+
+	MSCH_EVENT((", end_time: %s",
+		dhd_mschdbg_display_time(p->end_time_h, p->end_time_l)));
+
+	MSCH_EVENT((", sch_dur: %s\n",
+		dhd_mschdbg_display_time(p->sch_dur_h, p->sch_dur_l)));
+}
+
+static void
+dhd_mschdbg_req_timing_profiler_event_data(int sp, int ver, char *title, char *data,
+	uint16 ptr, bool empty)
+{
+	int sn = sp + 4;
+	msch_req_timing_profiler_event_data_t *p =
+		(msch_req_timing_profiler_event_data_t *)(data + ntoh16(ptr));
+	uint32 type;
+
+	MSCH_EVENT_HEAD(sp);
+	MSCH_EVENT(("<%s req_timing>: ", title));
+	if (empty) {
+		MSCH_EVENT((" null\n"));
+		return;
+	}
+	else
+		MSCH_EVENT(("0x%08x (prev 0x%08x, next 0x%08x)\n",
+			ntoh32(p->p_req_timing), ntoh32(p->p_prev), ntoh32(p->p_next)));
+
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("flags:"));
+	type = ntoh16(p->flags);
+	if ((type & 0x7f) == 0)
+		MSCH_EVENT((" NONE"));
+	else {
+		if (type & WL_MSCH_RC_FLAGS_ONCHAN_FIRE)
+			MSCH_EVENT((" ONCHAN_FIRE"));
+		if (type & WL_MSCH_RC_FLAGS_START_FIRE_DONE)
+			MSCH_EVENT((" START_FIRE"));
+		if (type & WL_MSCH_RC_FLAGS_END_FIRE_DONE)
+			MSCH_EVENT((" END_FIRE"));
+		if (type & WL_MSCH_RC_FLAGS_ONFIRE_DONE)
+			MSCH_EVENT((" ONFIRE_DONE"));
+		if (type & WL_MSCH_RC_FLAGS_SPLIT_SLOT_START)
+			MSCH_EVENT((" SPLIT_SLOT_START"));
+		if (type & WL_MSCH_RC_FLAGS_SPLIT_SLOT_END)
+			MSCH_EVENT((" SPLIT_SLOT_END"));
+		if (type & WL_MSCH_RC_FLAGS_PRE_ONFIRE_DONE)
+			MSCH_EVENT((" PRE_ONFIRE_DONE"));
+	}
+	MSCH_EVENT(("\n"));
+
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("pre_start_time: %s",
+		dhd_mschdbg_display_time(p->pre_start_time_h, p->pre_start_time_l)));
+
+	MSCH_EVENT((", start_time: %s",
+		dhd_mschdbg_display_time(p->start_time_h, p->start_time_l)));
+
+	MSCH_EVENT((", end_time: %s\n",
+		dhd_mschdbg_display_time(p->end_time_h, p->end_time_l)));
+
+	if (p->p_timeslot && (p->timeslot_ptr == 0)) {
+		MSCH_EVENT_HEAD(sn);
+		MSCH_EVENT(("<%s timeslot>: 0x%08x\n", title, ntoh32(p->p_timeslot)));
+	} else
+		dhd_mschdbg_timeslot_profiler_event_data(sn, ver, title, data, p->timeslot_ptr,
+			(p->timeslot_ptr == 0));
+}
+
+static void
+dhd_mschdbg_chan_ctxt_profiler_event_data(int sp, int ver, char *data, uint16 ptr, bool empty)
+{
+	int sn = sp + 4;
+	msch_chan_ctxt_profiler_event_data_t *p =
+		(msch_chan_ctxt_profiler_event_data_t *)(data + ntoh16(ptr));
+	chanspec_t c;
+	char buf[CHANSPEC_STR_LEN];
+
+	MSCH_EVENT_HEAD(sp);
+	MSCH_EVENT(("<chan_ctxt>: "));
+	if (empty) {
+		MSCH_EVENT((" null\n"));
+		return;
+	}
+	else
+		MSCH_EVENT(("0x%08x (prev 0x%08x, next 0x%08x)\n",
+			ntoh32(p->p_chan_ctxt), ntoh32(p->p_prev), ntoh32(p->p_next)));
+
+	c = (chanspec_t)ntoh16(p->chanspec);
+
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("channel: %s, bf_sch_pending: %s, bf_skipped: %d\n",
+		wf_chspec_ntoa(c, buf), p->bf_sch_pending? "TRUE" : "FALSE",
+		ntoh32(p->bf_skipped_count)));
+
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("bf_link: prev 0x%08x, next 0x%08x\n",
+		ntoh32(p->bf_link_prev), ntoh32(p->bf_link_next)));
+
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("onchan_time: %s",
+		dhd_mschdbg_display_time(p->onchan_time_h, p->onchan_time_l)));
+	MSCH_EVENT((", actual_onchan_dur: %s",
+		dhd_mschdbg_display_time(p->actual_onchan_dur_h, p->actual_onchan_dur_l)));
+	MSCH_EVENT((", pend_onchan_dur: %s\n",
+		dhd_mschdbg_display_time(p->pend_onchan_dur_h, p->pend_onchan_dur_l)));
+
+	dhd_mschdbg_elem_list(sn, "req_entity", data, p->req_entity_list_ptr,
+		p->req_entity_list_cnt);
+	dhd_mschdbg_elem_list(sn, "bf_entity", data, p->bf_entity_list_ptr,
+		p->bf_entity_list_cnt);
+}
+
+static void
+dhd_mschdbg_req_entity_profiler_event_data(int sp, int ver, char *data, uint16 ptr, bool empty)
+{
+	int sn = sp + 4;
+	msch_req_entity_profiler_event_data_t *p =
+		(msch_req_entity_profiler_event_data_t *)(data + ntoh16(ptr));
+	char buf[CHANSPEC_STR_LEN];
+	chanspec_t c;
+	uint32 flags;
+
+	MSCH_EVENT_HEAD(sp);
+	MSCH_EVENT(("<req_entity>: "));
+	if (empty) {
+		MSCH_EVENT((" null\n"));
+		return;
+	}
+	else
+		MSCH_EVENT(("0x%08x (prev 0x%08x, next 0x%08x)\n",
+			ntoh32(p->p_req_entity), ntoh32(p->req_hdl_link_prev),
+			ntoh32(p->req_hdl_link_next)));
+
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("req_hdl: [0x%08x]\n", ntoh32(p->p_req_hdl)));
+
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("chan_ctxt_link: prev 0x%08x, next 0x%08x\n",
+		ntoh32(p->chan_ctxt_link_prev), ntoh32(p->chan_ctxt_link_next)));
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("rt_specific_link: prev 0x%08x, next 0x%08x\n",
+		ntoh32(p->rt_specific_link_prev), ntoh32(p->rt_specific_link_next)));
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("start_fixed_link: prev 0x%08x, next 0x%08x\n",
+		ntoh32(p->start_fixed_link_prev), ntoh32(p->start_fixed_link_next)));
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("both_flex_list: prev 0x%08x, next 0x%08x\n",
+		ntoh32(p->both_flex_list_prev), ntoh32(p->both_flex_list_next)));
+
+	c = (chanspec_t)ntoh16(p->chanspec);
+	MSCH_EVENT_HEAD(sn);
+	if (ver >= 2) {
+		MSCH_EVENT(("channel: %s, onchan Id %d, current chan Id %d, priority %d",
+			wf_chspec_ntoa(c, buf), ntoh16(p->onchan_chn_idx), ntoh16(p->cur_chn_idx),
+			ntoh16(p->priority)));
+		flags = ntoh32(p->flags);
+		if (flags & WL_MSCH_ENTITY_FLAG_MULTI_INSTANCE)
+			MSCH_EVENT((" : MULTI_INSTANCE\n"));
+		else
+			MSCH_EVENT(("\n"));
+		MSCH_EVENT_HEAD(sn);
+		MSCH_EVENT(("actual_start_time: %s, ",
+			dhd_mschdbg_display_time(p->actual_start_time_h, p->actual_start_time_l)));
+		MSCH_EVENT(("curts_fire_time: %s, ",
+			dhd_mschdbg_display_time(p->curts_fire_time_h, p->curts_fire_time_l)));
+	} else {
+		MSCH_EVENT(("channel: %s, priority %d, ", wf_chspec_ntoa(c, buf),
+			ntoh16(p->priority)));
+	}
+	MSCH_EVENT(("bf_last_serv_time: %s\n",
+		dhd_mschdbg_display_time(p->bf_last_serv_time_h, p->bf_last_serv_time_l)));
+
+	dhd_mschdbg_req_timing_profiler_event_data(sn, ver, "current", data, p->cur_slot_ptr,
+		(p->cur_slot_ptr == 0));
+	dhd_mschdbg_req_timing_profiler_event_data(sn, ver, "pending", data, p->pend_slot_ptr,
+		(p->pend_slot_ptr == 0));
+
+	if (p->p_chan_ctxt && (p->chan_ctxt_ptr == 0)) {
+		MSCH_EVENT_HEAD(sn);
+		MSCH_EVENT(("<chan_ctxt>: 0x%08x\n", ntoh32(p->p_chan_ctxt)));
+	}
+	else
+		dhd_mschdbg_chan_ctxt_profiler_event_data(sn, ver, data, p->chan_ctxt_ptr,
+			(p->chan_ctxt_ptr == 0));
+}
+
+static void
+dhd_mschdbg_req_handle_profiler_event_data(int sp, int ver, char *data, uint16 ptr, bool empty)
+{
+	int sn = sp + 4;
+	msch_req_handle_profiler_event_data_t *p =
+		(msch_req_handle_profiler_event_data_t *)(data + ntoh16(ptr));
+	uint32 flags;
+
+	MSCH_EVENT_HEAD(sp);
+	MSCH_EVENT(("<req_handle>: "));
+	if (empty) {
+		MSCH_EVENT((" null\n"));
+		return;
+	}
+	else
+		MSCH_EVENT(("0x%08x (prev 0x%08x, next 0x%08x)\n",
+			ntoh32(p->p_req_handle), ntoh32(p->p_prev), ntoh32(p->p_next)));
+
+	dhd_mschdbg_elem_list(sn, "req_entity", data, p->req_entity_list_ptr,
+		p->req_entity_list_cnt);
+	MSCH_EVENT_HEAD(sn);
+	MSCH_EVENT(("cb_func: [0x%08x], cb_func: [0x%08x]",
+		ntoh32(p->cb_func), ntoh32(p->cb_ctxt)));
+	if (ver < 2) {
+		MSCH_EVENT((", chan_cnt: %d", ntoh16(p->chan_cnt)));
+	}
+	flags = ntoh32(p->flags);
+	if (flags & WL_MSCH_REQ_HDL_FLAGS_NEW_REQ)
+		MSCH_EVENT((", NEW_REQ"));
+	MSCH_EVENT(("\n"));
+
+	dhd_mschdbg_req_param_profiler_event_data(sn, ver, data, p->req_param_ptr);
+
+	if (ver >= 2) {
+		MSCH_EVENT_HEAD(sn);
+		MSCH_EVENT(("req_time: %s\n",
+			dhd_mschdbg_display_time(p->req_time_h, p->req_time_l)));
+		MSCH_EVENT_HEAD(sn);
+		MSCH_EVENT(("chan_cnt: %d, chan idx %d, last chan idx %d\n",
+			ntoh16(p->chan_cnt), ntoh16(p->chan_idx), ntoh16(p->last_chan_idx)));
+		if (p->chanspec_list && p->chanspec_cnt) {
+			dhd_mschdbg_chanspec_list(sn, data, p->chanspec_list, p->chanspec_cnt);
+		}
+	}
+}
+
+static void
+dhd_mschdbg_profiler_profiler_event_data(int sp, int ver, char *data, uint16 ptr)
+{
+	msch_profiler_profiler_event_data_t *p =
+		(msch_profiler_profiler_event_data_t *)(data + ntoh16(ptr));
+	uint32 flags;
+
+	MSCH_EVENT_HEAD(sp);
+	MSCH_EVENT(("free list: req_hdl 0x%08x, req_entity 0x%08x,"
+		" chan_ctxt 0x%08x, chanspec 0x%08x\n",
+		ntoh32(p->free_req_hdl_list), ntoh32(p->free_req_entity_list),
+		ntoh32(p->free_chan_ctxt_list), ntoh32(p->free_chanspec_list)));
+
+	MSCH_EVENT_HEAD(sp);
+	MSCH_EVENT(("alloc count: chanspec %d, req_entity %d, req_hdl %d, "
+		"chan_ctxt %d, timeslot %d\n",
+		ntoh16(p->msch_chanspec_alloc_cnt), ntoh16(p->msch_req_entity_alloc_cnt),
+		ntoh16(p->msch_req_hdl_alloc_cnt), ntoh16(p->msch_chan_ctxt_alloc_cnt),
+		ntoh16(p->msch_timeslot_alloc_cnt)));
+
+	dhd_mschdbg_elem_list(sp, "req_hdl", data, p->msch_req_hdl_list_ptr,
+		p->msch_req_hdl_list_cnt);
+	dhd_mschdbg_elem_list(sp, "chan_ctxt", data, p->msch_chan_ctxt_list_ptr,
+		p->msch_chan_ctxt_list_cnt);
+	dhd_mschdbg_elem_list(sp, "req_timing", data, p->msch_req_timing_list_ptr,
+		p->msch_req_timing_list_cnt);
+	dhd_mschdbg_elem_list(sp, "start_fixed", data, p->msch_start_fixed_list_ptr,
+		p->msch_start_fixed_list_cnt);
+	dhd_mschdbg_elem_list(sp, "both_flex_req_entity", data,
+		p->msch_both_flex_req_entity_list_ptr,
+		p->msch_both_flex_req_entity_list_cnt);
+	dhd_mschdbg_elem_list(sp, "start_flex", data, p->msch_start_flex_list_ptr,
+		p->msch_start_flex_list_cnt);
+	dhd_mschdbg_elem_list(sp, "both_flex", data, p->msch_both_flex_list_ptr,
+		p->msch_both_flex_list_cnt);
+
+	if (p->p_cur_msch_timeslot && (p->cur_msch_timeslot_ptr == 0)) {
+		MSCH_EVENT_HEAD(sp);
+		MSCH_EVENT(("<cur_msch timeslot>: 0x%08x\n",
+			ntoh32(p->p_cur_msch_timeslot)));
+	} else
+		dhd_mschdbg_timeslot_profiler_event_data(sp, ver, "cur_msch", data,
+			p->cur_msch_timeslot_ptr, (p->cur_msch_timeslot_ptr == 0));
+
+	if (p->p_next_timeslot && (p->next_timeslot_ptr == 0)) {
+		MSCH_EVENT_HEAD(sp);
+		MSCH_EVENT(("<next timeslot>: 0x%08x\n",
+			ntoh32(p->p_next_timeslot)));
+	} else
+		dhd_mschdbg_timeslot_profiler_event_data(sp, ver, "next", data,
+			p->next_timeslot_ptr, (p->next_timeslot_ptr == 0));
+
+	MSCH_EVENT_HEAD(sp);
+	MSCH_EVENT(("ts_id: %d, ", ntoh32(p->ts_id)));
+	flags = ntoh32(p->flags);
+	if (flags & WL_MSCH_STATE_IN_TIEMR_CTXT)
+		MSCH_EVENT(("IN_TIEMR_CTXT, "));
+	if (flags & WL_MSCH_STATE_SCHD_PENDING)
+		MSCH_EVENT(("SCHD_PENDING, "));
+	MSCH_EVENT(("slotskip_flags: %d, cur_armed_timeslot: 0x%08x\n",
+		(ver >= 2)? ntoh32(p->slotskip_flag) : 0, ntoh32(p->cur_armed_timeslot)));
+	MSCH_EVENT_HEAD(sp);
+	MSCH_EVENT(("flex_list_cnt: %d, service_interval: %d, "
+		"max_lo_prio_interval: %d\n",
+		ntoh16(p->flex_list_cnt), ntoh32(p->service_interval),
+		ntoh32(p->max_lo_prio_interval)));
+}
+
+static void dhd_mschdbg_dump_data(dhd_pub_t *dhdp, void *raw_event_ptr, int type,
+	char *data, int len)
+{
+	uint64 t = 0, tt = 0;
+	uint32 s = 0, ss = 0;
+	int wlc_index, ver;
+
+	ver = (type & WL_MSCH_PROFILER_VER_MASK) >> WL_MSCH_PROFILER_VER_SHIFT;
+	wlc_index = (type & WL_MSCH_PROFILER_WLINDEX_MASK) >> WL_MSCH_PROFILER_WLINDEX_SHIFT;
+	if (wlc_index >= 4)
+		return;
+
+	type &= WL_MSCH_PROFILER_TYPE_MASK;
+	if (type <= WL_MSCH_PROFILER_PROFILE_END) {
+		msch_profiler_event_data_t *pevent = (msch_profiler_event_data_t *)data;
+		tt = ((uint64)(ntoh32(pevent->time_hi)) << 32) | ntoh32(pevent->time_lo);
+		dhd_mschdbg_us_to_sec(pevent->time_hi, pevent->time_lo, &s, &ss);
+	}
+
+	if (lastMessages && (type != WL_MSCH_PROFILER_MESSAGE) &&
+		(type != WL_MSCH_PROFILER_EVENT_LOG)) {
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("\n"));
+		lastMessages = FALSE;
+	}
+
+	switch (type) {
+	case WL_MSCH_PROFILER_START:
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("%06d.%06d START\n", s, ss));
+		break;
+
+	case WL_MSCH_PROFILER_EXIT:
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("%06d.%06d EXIT\n", s, ss));
+		break;
+
+	case WL_MSCH_PROFILER_REQ:
+	{
+		msch_req_profiler_event_data_t *p = (msch_req_profiler_event_data_t *)data;
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("\n"));
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("===============================\n"));
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("%06d.%06d [wl%d] REGISTER:\n", s, ss, wlc_index));
+		dhd_mschdbg_req_param_profiler_event_data(4, ver, data, p->req_param_ptr);
+		dhd_mschdbg_chanspec_list(4, data, p->chanspec_ptr, p->chanspec_cnt);
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("===============================\n"));
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("\n"));
+	}
+		break;
+
+	case WL_MSCH_PROFILER_CALLBACK:
+	{
+		msch_callback_profiler_event_data_t *p =
+			(msch_callback_profiler_event_data_t *)data;
+		char buf[CHANSPEC_STR_LEN];
+		chanspec_t chanspec;
+		uint16 cbtype;
+
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("%06d.%06d [wl%d] CALLBACK: ", s, ss, wlc_index));
+		chanspec = (chanspec_t)ntoh16(p->chanspec);
+		MSCH_EVENT(("req_hdl[0x%08x], channel %s --",
+			ntoh32(p->p_req_hdl), wf_chspec_ntoa(chanspec, buf)));
+
+		cbtype = ntoh16(p->type);
+		if (cbtype & WL_MSCH_CT_ON_CHAN)
+			MSCH_EVENT((" ON_CHAN"));
+		if (cbtype & WL_MSCH_CT_OFF_CHAN)
+			MSCH_EVENT((" OFF_CHAN"));
+		if (cbtype & WL_MSCH_CT_REQ_START)
+			MSCH_EVENT((" REQ_START"));
+		if (cbtype & WL_MSCH_CT_REQ_END)
+			MSCH_EVENT((" REQ_END"));
+		if (cbtype & WL_MSCH_CT_SLOT_START)
+			MSCH_EVENT((" SLOT_START"));
+		if (cbtype & WL_MSCH_CT_SLOT_SKIP)
+			MSCH_EVENT((" SLOT_SKIP"));
+		if (cbtype & WL_MSCH_CT_SLOT_END)
+			MSCH_EVENT((" SLOT_END"));
+		if (cbtype & WL_MSCH_CT_OFF_CHAN_DONE)
+			MSCH_EVENT((" OFF_CHAN_DONE"));
+		if (cbtype & WL_MSCH_CT_PARTIAL)
+			MSCH_EVENT((" PARTIAL"));
+		if (cbtype & WL_MSCH_CT_PRE_ONCHAN)
+			MSCH_EVENT((" PRE_ONCHAN"));
+		if (cbtype & WL_MSCH_CT_PRE_REQ_START)
+			MSCH_EVENT((" PRE_REQ_START"));
+
+		if (cbtype & WL_MSCH_CT_REQ_START) {
+			req_start[wlc_index] = 1;
+			req_start_time[wlc_index] = tt;
+		} else if (cbtype & WL_MSCH_CT_REQ_END) {
+			if (req_start[wlc_index]) {
+				MSCH_EVENT((" : REQ duration %d",
+					(uint32)(tt - req_start_time[wlc_index])));
+				req_start[wlc_index] = 0;
+			}
+		}
+
+		if (cbtype & WL_MSCH_CT_SLOT_START) {
+			solt_chanspec[wlc_index] = p->chanspec;
+			solt_start_time[wlc_index] = tt;
+		} else if (cbtype & WL_MSCH_CT_SLOT_END) {
+			if (p->chanspec == solt_chanspec[wlc_index]) {
+				MSCH_EVENT((" : SLOT duration %d",
+					(uint32)(tt - solt_start_time[wlc_index])));
+				solt_chanspec[wlc_index] = 0;
+			}
+		}
+		MSCH_EVENT(("\n"));
+
+		if (cbtype & (WL_MSCH_CT_ON_CHAN | WL_MSCH_CT_SLOT_SKIP)) {
+			MSCH_EVENT_HEAD(4);
+			if (cbtype & WL_MSCH_CT_ON_CHAN) {
+				MSCH_EVENT(("ID %d onchan idx %d cur_chan_seq_start %s ",
+					ntoh32(p->timeslot_id), ntoh32(p->onchan_idx),
+					dhd_mschdbg_display_time(p->cur_chan_seq_start_time_h,
+					p->cur_chan_seq_start_time_l)));
+			}
+			t = ((uint64)(ntoh32(p->start_time_h)) << 32) |
+				ntoh32(p->start_time_l);
+			MSCH_EVENT(("start %s ",
+				dhd_mschdbg_display_time(p->start_time_h,
+				p->start_time_l)));
+			tt = ((uint64)(ntoh32(p->end_time_h)) << 32) | ntoh32(p->end_time_l);
+			MSCH_EVENT(("end %s duration %d\n",
+				dhd_mschdbg_display_time(p->end_time_h, p->end_time_l),
+				(p->end_time_h == 0xffffffff && p->end_time_l == 0xffffffff)?
+				-1 : (int)(tt - t)));
+		}
+
+	}
+		break;
+
+	case WL_MSCH_PROFILER_EVENT_LOG:
+	{
+		while (len >= (int)WL_MSCH_EVENT_LOG_HEAD_SIZE) {
+			msch_event_log_profiler_event_data_t *p =
+				(msch_event_log_profiler_event_data_t *)data;
+			/* TODO: How to parse MSCH if extended event tag is present ??? */
+			prcd_event_log_hdr_t hdr;
+			int size = WL_MSCH_EVENT_LOG_HEAD_SIZE + p->hdr.count * sizeof(uint32);
+			if (len < size || size > sizeof(msch_event_log_profiler_event_data_t)) {
+				break;
+			}
+			data += size;
+			len -= size;
+			dhd_mschdbg_us_to_sec(p->time_hi, p->time_lo, &s, &ss);
+			MSCH_EVENT_HEAD(0);
+			MSCH_EVENT(("%06d.%06d [wl%d]: ", s, ss, p->hdr.tag));
+			bzero(&hdr, sizeof(hdr));
+			hdr.tag = EVENT_LOG_TAG_MSCHPROFILE;
+			hdr.count = p->hdr.count + 1;
+			/* exclude LSB 2 bits which indicate binary/non-binary data */
+			hdr.fmt_num = ntoh16(p->hdr.fmt_num) >> 2;
+			hdr.fmt_num_raw = ntoh16(p->hdr.fmt_num);
+			if (ntoh16(p->hdr.fmt_num) == DHD_OW_BI_RAW_EVENT_LOG_FMT) {
+				hdr.binary_payload = TRUE;
+			}
+			dhd_dbg_verboselog_printf(dhdp, &hdr, raw_event_ptr, p->data, 0, 0);
+		}
+		lastMessages = TRUE;
+		break;
+	}
+
+	case WL_MSCH_PROFILER_MESSAGE:
+	{
+		msch_message_profiler_event_data_t *p = (msch_message_profiler_event_data_t *)data;
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("%06d.%06d [wl%d]: %s", s, ss, wlc_index, p->message));
+		lastMessages = TRUE;
+		break;
+	}
+
+	case WL_MSCH_PROFILER_PROFILE_START:
+		profiler_start_time[wlc_index] = tt;
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("-------------------------------\n"));
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("%06d.%06d [wl%d] PROFILE DATA:\n", s, ss, wlc_index));
+		dhd_mschdbg_profiler_profiler_event_data(4, ver, data, 0);
+		break;
+
+	case WL_MSCH_PROFILER_PROFILE_END:
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("%06d.%06d [wl%d] PROFILE END: take time %d\n", s, ss,
+			wlc_index, (uint32)(tt - profiler_start_time[wlc_index])));
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("-------------------------------\n"));
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("\n"));
+		break;
+
+	case WL_MSCH_PROFILER_REQ_HANDLE:
+		dhd_mschdbg_req_handle_profiler_event_data(4, ver, data, 0, FALSE);
+		break;
+
+	case WL_MSCH_PROFILER_REQ_ENTITY:
+		dhd_mschdbg_req_entity_profiler_event_data(4, ver, data, 0, FALSE);
+		break;
+
+	case WL_MSCH_PROFILER_CHAN_CTXT:
+		dhd_mschdbg_chan_ctxt_profiler_event_data(4, ver, data, 0, FALSE);
+		break;
+
+	case WL_MSCH_PROFILER_REQ_TIMING:
+		dhd_mschdbg_req_timing_profiler_event_data(4, ver, "msch", data, 0, FALSE);
+		break;
+
+	default:
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("[wl%d] ERROR: unsupported EVENT reason code:%d; ",
+			wlc_index, type));
+		break;
+	}
+}
+
+void
+wl_mschdbg_event_handler(dhd_pub_t *dhdp, void *raw_event_ptr, int type, void *data, int len)
+{
+	head_log = "MSCH";
+	dhd_mschdbg_dump_data(dhdp, raw_event_ptr, type, (char *)data, len);
+}
+
+void
+wl_mschdbg_verboselog_handler(dhd_pub_t *dhdp, void *raw_event_ptr, prcd_event_log_hdr_t *plog_hdr,
+	uint32 *log_ptr)
+{
+	uint32 log_pyld_len;
+	head_log = "CONSOLE";
+
+	if (plog_hdr->count == 0) {
+		return;
+	}
+	log_pyld_len = (plog_hdr->count - 1) * DATA_UNIT_FOR_LOG_CNT;
+
+	if (plog_hdr->tag == EVENT_LOG_TAG_MSCHPROFILE) {
+		msch_event_log_profiler_event_data_t *p =
+			(msch_event_log_profiler_event_data_t *)log_ptr;
+		/* TODO: How to parse MSCH if extended event tag is present ??? */
+		prcd_event_log_hdr_t hdr;
+		uint32 s, ss;
+
+		if (log_pyld_len < OFFSETOF(msch_event_log_profiler_event_data_t, data) ||
+			log_pyld_len > sizeof(msch_event_log_profiler_event_data_t)) {
+			return;
+		}
+
+		dhd_mschdbg_us_to_sec(p->time_hi, p->time_lo, &s, &ss);
+		MSCH_EVENT_HEAD(0);
+		MSCH_EVENT(("%06d.%06d [wl%d]: ", s, ss, p->hdr.tag));
+		bzero(&hdr, sizeof(hdr));
+		hdr.tag = EVENT_LOG_TAG_MSCHPROFILE;
+		hdr.count = p->hdr.count + 1;
+		/* exclude LSB 2 bits which indicate binary/non-binary data */
+		hdr.fmt_num = ntoh16(p->hdr.fmt_num) >> 2;
+		hdr.fmt_num_raw = ntoh16(p->hdr.fmt_num);
+		if (ntoh16(p->hdr.fmt_num) == DHD_OW_BI_RAW_EVENT_LOG_FMT) {
+			hdr.binary_payload = TRUE;
+		}
+		dhd_dbg_verboselog_printf(dhdp, &hdr, raw_event_ptr, p->data, 0, 0);
+	} else {
+		msch_collect_tlv_t *p = (msch_collect_tlv_t *)log_ptr;
+		int type = ntoh16(p->type);
+		int len = ntoh16(p->size);
+
+		if (log_pyld_len < OFFSETOF(msch_collect_tlv_t, value) + len) {
+			return;
+		}
+
+		dhd_mschdbg_dump_data(dhdp, raw_event_ptr, type, p->value, len);
+	}
+}
+#endif /* SHOW_LOGTRACE */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_mschdbg.h
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_mschdbg.h
@@ -0,0 +1,55 @@
+/*
+ * DHD debugability header file
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id: dhd_mschdbg.h 571265 2015-07-14 20:50:18Z $
+ */
+
+#ifndef _dhd_mschdbg_h_
+#define _dhd_mschdbg_h_
+
+#ifdef SHOW_LOGTRACE
+extern void wl_mschdbg_event_handler(dhd_pub_t *dhdp, void *raw_event_ptr, int type,
+	void *data, int len);
+extern void wl_mschdbg_verboselog_handler(dhd_pub_t *dhdp, void *raw_event_ptr,
+	prcd_event_log_hdr_t *plog_hdr, uint32 *log_ptr);
+#endif /* SHOW_LOGTRACE */
+
+#endif /* _dhd_mschdbg_h_ */
--- linux-qcom-6.8.0.orig/drivers/net/wireless/bcmdhd/dhd_msgbuf.c
+++ linux-qcom-6.8.0/drivers/net/wireless/bcmdhd/dhd_msgbuf.c
@@ -0,0 +1,14846 @@
+/**
+ * @file definition of host message ring functionality
+ * Provides type definitions and function prototypes used to link the
+ * DHD OS, bus, and protocol modules.
+ *
+ * Copyright (C) 2024 Synaptics Incorporated. All rights reserved.
+ *
+ * This software is licensed to you under the terms of the
+ * GNU General Public License version 2 (the "GPL") with Broadcom special exception.
+ *
+ * INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED "AS-IS," AND SYNAPTICS
+ * EXPRESSLY DISCLAIMS ALL EXPRESS AND IMPLIED WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
+ * AND ANY WARRANTIES OF NON-INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS.
+ * IN NO EVENT SHALL SYNAPTICS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OF THE INFORMATION CONTAINED IN THIS DOCUMENT, HOWEVER CAUSED
+ * AND BASED ON ANY THEORY OF LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, AND EVEN IF SYNAPTICS WAS ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE. IF A TRIBUNAL OF COMPETENT JURISDICTION
+ * DOES NOT PERMIT THE DISCLAIMER OF DIRECT DAMAGES OR ANY OTHER DAMAGES,
+ * SYNAPTICS' TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT
+ * EXCEED ONE HUNDRED U.S. DOLLARS
+ *
+ * Copyright (C) 2024, Broadcom.
+ *
+ *      Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ *      As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module.  An independent module is a module which is not
+ * derived from this software.  The special exception does not apply to any
+ * modifications of the software.
+ *
+ *
+ * <<Broadcom-WL-IPTag/Open:>>
+ *
+ * $Id$
+ */
+
+/** XXX Twiki: [PCIeFullDongleArchitecture] */
+
+#include <typedefs.h>
+#include <osl.h>
+
+#include <bcmutils.h>
+#include <bcmmsgbuf.h>
+#include <bcmendian.h>
+#include <bcmstdlib_s.h>
+
+#include <dngl_stats.h>
+#include <dhd.h>
+#include <dhd_proto.h>
+
+#include <dhd_bus.h>
+
+#include <dhd_dbg.h>
+#include <siutils.h>
+#include <dhd_debug.h>
+#ifdef EXT_STA
+#include <wlc_cfg.h>
+#include <wlc_pub.h>
+#include <wl_port_if.h>
+#endif /* EXT_STA */
+
+#include <dhd_flowring.h>
+
+#include <pcie_core.h>
+#include <bcmpcie.h>
+#include <dhd_pcie.h>
+#include <dhd_config.h>
+#if defined(DHD_LB)
+#if !defined(LINUX) && !defined(linux) && !defined(OEM_ANDROID)
+#error "DHD Loadbalancing only supported on LINUX | OEM_ANDROID"
+#endif /* !LINUX && !OEM_ANDROID */
+#include <linux/cpu.h>
+#include <bcm_ring.h>
+#define DHD_LB_WORKQ_SZ			    (8192)
+#define DHD_LB_WORKQ_SYNC           (16)
+#define DHD_LB_WORK_SCHED           (DHD_LB_WORKQ_SYNC * 2)
+#endif /* DHD_LB */
+
+#include <etd.h>
+#include <hnd_debug.h>
+#include <bcmtlv.h>
+#include <hnd_armtrap.h>
+#include <dnglevent.h>
+
+#ifdef DHD_PKT_LOGGING
+#include <dhd_pktlog.h>
+#include <dhd_linux_pktdump.h>
+#endif /* DHD_PKT_LOGGING */
+#ifdef DHD_EWPR_VER2
+#include <dhd_bitpack.h>
+#endif /* DHD_EWPR_VER2 */
+
+extern char dhd_version[];
+extern char fw_version[];
+
+/**
+ * Host configures a soft doorbell for d2h rings, by specifying a 32bit host
+ * address where a value must be written. Host may also interrupt coalescing
+ * on this soft doorbell.
+ * Use Case: Hosts with network processors, may register with the dongle the
+ * network processor's thread wakeup register and a value corresponding to the
+ * core/thread context. Dongle will issue a write transaction <address,value>
+ * to the PCIE RC which will need to be routed to the mapped register space, by
+ * the host.
+ */
+/* #define DHD_D2H_SOFT_DOORBELL_SUPPORT */
+
+/* Dependency Check */
+#if defined(IOCTLRESP_USE_CONSTMEM) && defined(DHD_USE_STATIC_CTRLBUF)
+#error "DHD_USE_STATIC_CTRLBUF is NOT working with DHD_USE_OSLPKT_FOR_RESPBUF"
+#endif /* IOCTLRESP_USE_CONSTMEM && DHD_USE_STATIC_CTRLBUF */
+
+#define RETRIES 2		/* # of retries to retrieve matching ioctl response */
+
+/* For legacy firmware where pcie shared structure does not have max_host_rxbufs, use this */
+#define LEGACY_MAX_RXBUFPOST		256u
+
+/* Read index update Magic sequence */
+#define DHD_DMA_INDX_SEQ_H2D_DB_MAGIC	0xDDDDDDDDAu
+#define DHD_RDPTR_UPDATE_H2D_DB_MAGIC(ring)	(0xDD000000 | (ring->idx << 16u) | ring->rd)
+/* Write index update Magic sequence */
+#define DHD_WRPTR_UPDATE_H2D_DB_MAGIC(ring)	(0xFF000000 | (ring->idx << 16u) | ring->wr)
+#define DHD_AGGR_H2D_DB_MAGIC	0xFFFFFFFAu
+
+#define DHD_STOP_QUEUE_THRESHOLD	200
+#define DHD_START_QUEUE_THRESHOLD	100
+
+#define RX_DMA_OFFSET		8 /* Mem2mem DMA inserts an extra 8 */
+#define IOCT_RETBUF_SIZE	(RX_DMA_OFFSET + WLC_IOCTL_MAXLEN)
+
+/* flags for ioctl pending status */
+#define MSGBUF_IOCTL_ACK_PENDING	(1<<0)
+#define MSGBUF_IOCTL_RESP_PENDING	(1<<1)
+
+#define DHD_IOCTL_REQ_PKTBUFSZ		2048
+#define MSGBUF_IOCTL_MAX_RQSTLEN	(DHD_IOCTL_REQ_PKTBUFSZ - H2DRING_CTRL_SUB_ITEMSIZE)
+
+/**
+ * XXX: DMA_ALIGN_LEN use is overloaded:
+ * - as align bits: in DMA_ALLOC_CONSISTENT 1 << 4
+ * - in ensuring that a buffer's va is 4 Byte aligned
+ * - in rounding up a buffer length to 4 Bytes.
+ */
+#define DMA_ALIGN_LEN		4
+
+#define DMA_D2H_SCRATCH_BUF_LEN	8
+#define DMA_XFER_LEN_LIMIT	0x400000
+
+#ifdef BCM_HOST_BUF
+#ifndef DMA_HOST_BUFFER_LEN
+#define DMA_HOST_BUFFER_LEN	0x200000
+#endif
+#endif /* BCM_HOST_BUF */
+
+#define DHD_FLOWRING_IOCTL_BUFPOST_PKTSZ		8192
+
+#define DHD_FLOWRING_DEFAULT_NITEMS_POSTED_H2D		1
+#define DHD_FLOWRING_MAX_EVENTBUF_POST			32
+#define DHD_FLOWRING_MAX_IOCTLRESPBUF_POST		8
+#define DHD_H2D_INFORING_MAX_BUF_POST			32
+#define DHD_MAX_TSBUF_POST			8
+
+#define DHD_PROT_FUNCS	43
+
+/* Length of buffer in host for bus throughput measurement */
+#define DHD_BUS_TPUT_BUF_LEN 2048
+
+#define TXP_FLUSH_NITEMS
+
+/* optimization to write "n" tx items at a time to ring */
+#define TXP_FLUSH_MAX_ITEMS_FLUSH_CNT	48
+
+#define RING_NAME_MAX_LENGTH		24
+#define CTRLSUB_HOSTTS_MEESAGE_SIZE		1024
+/* Giving room before ioctl_trans_id rollsover. */
+#define BUFFER_BEFORE_ROLLOVER 300
+
+/* 512K memory + 32K registers */
+#define SNAPSHOT_UPLOAD_BUF_SIZE	((512 + 32) * 1024)
+
+struct msgbuf_ring; /* ring context for common and flow rings */
+
+#ifdef DHD_HMAPTEST
+/* 5 * DMA_CONSISTENT_ALIGN as different tests use upto 4th page */
+#define HMAP_SANDBOX_BUFFER_LEN	(DMA_CONSISTENT_ALIGN * 5) /* for a 4k page this is 20K */
+/**
+ * for D11 DMA HMAPTEST thes states are as follows
+ * iovar sets ACTIVE state
+ * next TXPOST / RXPOST sets POSTED state
+ * on TXCPL / RXCPL POSTED + pktid match does buffer free nd state changed to INACTIVE
+ * This ensures that on an iovar only one buffer is replaced from sandbox area
+ */
+#define HMAPTEST_D11_TX_INACTIVE 0
+#define HMAPTEST_D11_TX_ACTIVE 1
+#define HMAPTEST_D11_TX_POSTED 2
+
+#define HMAPTEST_D11_RX_INACTIVE 0
+#define HMAPTEST_D11_RX_ACTIVE 1
+#define HMAPTEST_D11_RX_POSTED 2
+#endif /* DHD_HMAPTEST */
+
+#define PCIE_DMA_LOOPBACK	0
+#define D11_DMA_LOOPBACK	1
+#define BMC_DMA_LOOPBACK	2
+
+/**
+ * PCIE D2H DMA Complete Sync Modes
+ *
+ * Firmware may interrupt the host, prior to the D2H Mem2Mem DMA completes into
+ * Host system memory. A WAR using one of 3 approaches is needed:
+ * 1. Dongle places a modulo-253 seqnum in last word of each D2H message
+ * 2. XOR Checksum, with epoch# in each work item. Dongle builds an XOR checksum
+ *    writes in the last word of each work item. Each work item has a seqnum
+ *    number = sequence num % 253.
+ *
+ * 3. Read Barrier: Dongle does a host memory read access prior to posting an
+ *    interrupt, ensuring that D2H data transfer indeed completed.
+ * 4. Dongle DMA's all indices after producing items in the D2H ring, flushing
+ *    ring contents before the indices.
+ *
+ * Host does not sync for DMA to complete with option #3 or #4, and a noop sync
+ * callback (see dhd_prot_d2h_sync_none) may be bound.
+ *
+ * Dongle advertizes host side sync mechanism requirements.
+ */
+
+#ifdef PCIE_D2H_SYNC_RETRY_CNT_ONE
+#define PCIE_D2H_SYNC_WAIT_TRIES    (1U)
+#define PCIE_D2H_SYNC_NUM_OF_STEPS  (1U)
+#define PCIE_D2H_SYNC_DELAY         (1UL)	/* in terms of usecs */
+#else
+#define PCIE_D2H_SYNC_WAIT_TRIES    (512U)
+#define PCIE_D2H_SYNC_NUM_OF_STEPS  (5U)
+#define PCIE_D2H_SYNC_DELAY         (100UL)	/* in terms of usecs */
+#endif /* PCIE_D2H_SYNC_RETRY_CNT_ONE */
+
+/**
+ * Custom callback attached based upon D2H DMA Sync mode advertized by dongle.
+ *
+ * On success: return cmn_msg_hdr_t::msg_type
+ * On failure: return 0 (invalid msg_type)
+ */
+typedef uint8 (* d2h_sync_cb_t)(dhd_pub_t *dhd, struct msgbuf_ring *ring,
+                                volatile cmn_msg_hdr_t *msg, int msglen);
+
+void dhd_prot_debug_ring_info(dhd_pub_t *dhd);
+
+/**
+ * Custom callback attached based upon D2H DMA Sync mode advertized by dongle.
+ * For EDL messages.
+ *
+ * On success: return cmn_msg_hdr_t::msg_type
+ * On failure: return 0 (invalid msg_type)
+ */
+#ifdef EWP_EDL
+typedef int (* d2h_edl_sync_cb_t)(dhd_pub_t *dhd, struct msgbuf_ring *ring,
+                                volatile cmn_msg_hdr_t *msg);
+#endif /* EWP_EDL */
+
+/*
+ * +----------------------------------------------------------------------------
+ *
+ * RingIds and FlowId are not equivalent as ringids include D2H rings whereas
+ * flowids do not.
+ *
+ * Dongle advertizes the max H2D rings, as max_sub_queues = 'N' which includes
+ * the H2D common rings as well as the (N-BCMPCIE_H2D_COMMON_MSGRINGS) flowrings
+ *
+ * Here is a sample mapping for (based on PCIE Full Dongle Rev5) where,
+ *  BCMPCIE_H2D_COMMON_MSGRINGS = 2, i.e. 2 H2D common rings,
+ *  BCMPCIE_COMMON_MSGRINGS     = 5, i.e. include 3 D2H common rings.
+ *
+ *  H2D Control  Submit   RingId = 0        FlowId = 0 reserved never allocated
+ *  H2D RxPost   Submit   RingId = 1        FlowId = 1 reserved never allocated
+ *
+ *  D2H Control  Complete RingId = 2
+ *  D2H Transmit Complete RingId = 3
+ *  D2H Receive  Complete RingId = 4
+ *
+ *  H2D TxPost   FLOWRING RingId = 5         FlowId = 2     (1st flowring)
+ *  H2D TxPost   FLOWRING RingId = 6         FlowId = 3     (2nd flowring)
+ *  H2D TxPost   FLOWRING RingId = 5 + (N-1) FlowId = (N-1) (Nth flowring)
+ *
+ * When TxPost FlowId(s) are allocated, the FlowIds [0..FLOWID_RESERVED) are
+ * unused, where FLOWID_RESERVED is BCMPCIE_H2D_COMMON_MSGRINGS.
+ *
+ * Example: when a system supports 4 bc/mc and 128 uc flowrings, with
+ * BCMPCIE_H2D_COMMON_MSGRINGS = 2, and BCMPCIE_H2D_COMMON_MSGRINGS = 5, and the
+ * FlowId values would be in the range [2..133] and the corresponding
+ * RingId values would be in the range [5..136].
+ *
+ * The flowId allocator, may chose to, allocate Flowids:
+ *   bc/mc (per virtual interface) in one consecutive range [2..(2+VIFS))
+ *   X# of uc flowids in consecutive ranges (per station Id), where X is the
+ *   packet's access category (e.g. 4 uc flowids per station).
+ *
+ * CAUTION:
+ * When DMA indices array feature is used, RingId=5, corresponding to the 0th
+ * FLOWRING, will actually use the FlowId as index into the H2D DMA index,
+ * since the FlowId truly represents the index in the H2D DMA indices array.
+ *
+ * Likewise, in the D2H direction, the RingId - BCMPCIE_H2D_COMMON_MSGRINGS,
+ * will represent the index in the D2H DMA indices array.
+ *
+ * +----------------------------------------------------------------------------
+ */
+
+/* First TxPost Flowring Id */
+#define DHD_FLOWRING_START_FLOWID   BCMPCIE_H2D_COMMON_MSGRINGS
+
+/* Determine whether a ringid belongs to a TxPost flowring */
+#define DHD_IS_FLOWRING(ringid, max_flow_rings) \
+	((ringid) >= BCMPCIE_COMMON_MSGRINGS && \
+	(ringid) < ((max_flow_rings) + BCMPCIE_COMMON_MSGRINGS))
+
+/* Convert a H2D TxPost FlowId to a MsgBuf RingId */
+#define DHD_FLOWID_TO_RINGID(flowid) \
+	(BCMPCIE_COMMON_MSGRINGS + ((flowid) - BCMPCIE_H2D_COMMON_MSGRINGS))
+
+/* Convert a MsgBuf RingId to a H2D TxPost FlowId */
+#define DHD_RINGID_TO_FLOWID(ringid) \
+	(BCMPCIE_H2D_COMMON_MSGRINGS + ((ringid) - BCMPCIE_COMMON_MSGRINGS))
+
+/* Convert a H2D MsgBuf RingId to an offset index into the H2D DMA indices array
+ * This may be used for the H2D DMA WR index array or H2D DMA RD index array or
+ * any array of H2D rings.
+ */
+#define DHD_H2D_RING_OFFSET(ringid) \
+	(((ringid) >= BCMPCIE_COMMON_MSGRINGS) ? DHD_RINGID_TO_FLOWID(ringid) : (ringid))
+
+/* Convert a H2D MsgBuf Flowring Id to an offset index into the H2D DMA indices array
+ * This may be used for IFRM.
+ */
+#define DHD_H2D_FRM_FLOW_RING_OFFSET(ringid) \
+	((ringid) - BCMPCIE_COMMON_MSGRINGS)
+
+/* Convert a D2H MsgBuf RingId to an offset index into the D2H DMA indices array
+ * This may be used for the D2H DMA WR index array or D2H DMA RD index array or
+ * any array of D2H rings.
+ * d2h debug ring is located at the end, i.e. after all the tx flow rings and h2d debug ring
+ * max_h2d_rings: total number of h2d rings
+ */
+#define DHD_D2H_RING_OFFSET(ringid, max_h2d_rings) \
+	((ringid) > (max_h2d_rings) ? \
+		((ringid) - max_h2d_rings) : \
+		((ringid) - BCMPCIE_H2D_COMMON_MSGRINGS))
+
+/* Convert a D2H DMA Indices Offset to a RingId */
+#define DHD_D2H_RINGID(offset) \
+	((offset) + BCMPCIE_H2D_COMMON_MSGRINGS)
+
+/* XXX: The ringid and flowid and dma indices array index idiosyncracy is error
+ * prone. While a simplification is possible, the backward compatability
+ * requirement (DHD should operate with any PCIE rev version of firmware),
+ * limits what may be accomplished.
+ *
+ * At the minimum, implementation should use macros for any conversions
+ * facilitating introduction of future PCIE FD revs that need more "common" or
+ * other dynamic rings.
+ */
+
+/* XXX: Presently there is no need for maintaining both a dmah and a secdmah */
+#define DHD_DMAH_NULL      ((void*)NULL)
+
+/*
+ * Pad a DMA-able buffer by an additional cachline. If the end of the DMA-able
+ * buffer does not occupy the entire cacheline, and another object is placed
+ * following the DMA-able buffer, data corruption may occur if the DMA-able
+ * buffer is used to DMAing into (e.g. D2H direction), when HW cache coherency
+ * is not available.
+ */
+#if defined(L1_CACHE_BYTES)
+#define DHD_DMA_PAD        (L1_CACHE_BYTES)
+#else
+#define DHD_DMA_PAD        (128)
+#endif
+
+/*
+ * +----------------------------------------------------------------------------
+ * Flowring Pool
+ *
+ * Unlike common rings, which are attached very early on (dhd_prot_attach),
+ * flowrings are dynamically instantiated. Moreover, flowrings may require a
+ * larger DMA-able buffer. To avoid issues with fragmented cache coherent
+ * DMA-able memory, a pre-allocated pool of msgbuf_ring_t is allocated once.
+ * The DMA-able buffers are attached to these pre-allocated msgbuf_ring.
+ *
+ * Each DMA-able buffer may be allocated independently, or may be carved out
+ * of a single large contiguous region that is registered with the protocol
+ * layer into flowrings_dma_buf. On a 64bit platform, this contiguous region
+ * may not span 0x00000000FFFFFFFF (avoid dongle side 64bit ptr arithmetic).
+ *
+ * No flowring pool action is performed in dhd_prot_attach(), as the number
+ * of h2d rings is not yet known.
+ *
+ * In dhd_prot_init(), the dongle advertized number of h2d rings is used to
+ * determine the number of flowrings required, and a pool of msgbuf_rings are
+ * allocated and a DMA-able buffer (carved or allocated) is attached.
+ * See: dhd_prot_flowrings_pool_attach()
+ *
+ * A flowring msgbuf_ring object may be fetched from this pool during flowring
+ * creation, using the flowid. Likewise, flowrings may be freed back into the
+ * pool on flowring deletion.
+ * See: dhd_prot_flowrings_pool_fetch(), dhd_prot_flowrings_pool_release()
+ *
+ * In dhd_prot_detach(), the flowring pool is detached. The DMA-able buffers
+ * are detached (returned back to the carved region or freed), and the pool of
+ * msgbuf_ring and any objects allocated against it are freed.
+ * See: dhd_prot_flowrings_pool_detach()
+ *
+ * In dhd_prot_reset(), the flowring pool is simply reset by returning it to a
+ * state as-if upon an attach. All DMA-able buffers are retained.
+ * Following a dhd_prot_reset(), in a subsequent dhd_prot_init(), the flowring
+ * pool attach will notice that the pool persists and continue to use it. This
+ * will avoid the case of a fragmented DMA-able region.
+ *
+ * +----------------------------------------------------------------------------
+ */
+
+/* Conversion of a flowid to a flowring pool index */
+#define DHD_FLOWRINGS_POOL_OFFSET(flowid) \
+	((flowid) - BCMPCIE_H2D_COMMON_MSGRINGS)
+
+/* Fetch the msgbuf_ring_t from the flowring pool given a flowid */
+#define DHD_RING_IN_FLOWRINGS_POOL(prot, flowid) \
+	(msgbuf_ring_t*)((prot)->h2d_flowrings_pool) + \
+	    DHD_FLOWRINGS_POOL_OFFSET(flowid)
+
+/* Traverse each flowring in the flowring pool, assigning ring and flowid */
+#define FOREACH_RING_IN_FLOWRINGS_POOL(prot, ring, flowid, total_flowrings) \
+	for ((flowid) = DHD_FLOWRING_START_FLOWID, \
+		(ring) = DHD_RING_IN_FLOWRINGS_POOL(prot, flowid); \
+		 (flowid) < ((total_flowrings) + DHD_FLOWRING_START_FLOWID); \
+		 (ring)++, (flowid)++)
+
+/* Used in loopback tests */
+typedef struct dhd_dmaxfer {
+	dhd_dma_buf_t srcmem;
+	dhd_dma_buf_t dstmem;
+	uint32        srcdelay;
+	uint32        destdelay;
+	uint32        len;
+	bool          in_progress;
+	uint64        start_usec;
+	uint64        time_taken;
+	uint32        d11_lpbk;
+	int           status;
+} dhd_dmaxfer_t;
+
+#ifdef DHD_HMAPTEST
+/* Used in HMAP test */
+typedef struct dhd_hmaptest {
+	dhd_dma_buf_t	mem;
+	uint32		len;
+	bool	in_progress;
+	uint32	is_write;
+	uint32	accesstype;
+	uint64  start_usec;
+	uint32	offset;
+} dhd_hmaptest_t;
+#endif /* DHD_HMAPTEST */
+/**
+ * msgbuf_ring : This object manages the host side ring that includes a DMA-able
+ * buffer, the WR and RD indices, ring parameters such as max number of items
+ * an length of each items, and other miscellaneous runtime state.
+ * A msgbuf_ring may be used to represent a H2D or D2H common ring or a
+ * H2D TxPost ring as specified in the PCIE FullDongle Spec.
+ * Ring parameters are conveyed to the dongle, which maintains its own peer end
+ * ring state. Depending on whether the DMA Indices feature is supported, the
+ * host will update the WR/RD index in the DMA indices array in host memory or
+ * directly in dongle memory.
+ */
+typedef struct msgbuf_ring {
+	bool           inited;
+	uint16         idx;       /* ring id */
+	uint16         rd;        /* read index */
+	uint16         curr_rd;   /* read index for debug */
+	uint16         wr;        /* write index */
+	uint16         max_items; /* maximum number of items in ring */
+	uint16         item_len;  /* length of each item in the ring */
+	sh_addr_t      base_addr; /* LITTLE ENDIAN formatted: base address */
+	dhd_dma_buf_t  dma_buf;   /* DMA-able buffer: pa, va, len, dmah, secdma */
+	uint32         seqnum;    /* next expected item's sequence number */
+#ifdef TXP_FLUSH_NITEMS
+	void           *start_addr;
+	/* # of messages on ring not yet announced to dongle */
+	uint16         pend_items_count;
+#ifdef AGG_H2D_DB
+	osl_atomic_t	inflight;
+#endif /* AGG_H2D_DB */
+#endif /* TXP_FLUSH_NITEMS */
+
+	uint8           ring_type;
+	uint8           n_completion_ids;
+	bool            create_pending;
+	uint16          create_req_id;
+	uint8           current_phase;
+	uint16	        compeltion_ring_ids[MAX_COMPLETION_RING_IDS_ASSOCIATED];
+	uchar		name[RING_NAME_MAX_LENGTH];
+	uint32		ring_mem_allocated;
+	void	        *ring_lock;
+	struct msgbuf_ring *linked_ring; /* Ring Associated to metadata ring */
+} msgbuf_ring_t;
+
+#define DHD_RING_BGN_VA(ring)           ((ring)->dma_buf.va)
+#define DHD_RING_END_VA(ring) \
+	((uint8 *)(DHD_RING_BGN_VA((ring))) + \
+	 (((ring)->max_items - 1) * (ring)->item_len))
+
+#if (defined(BCM_ROUTER_DHD) && defined(HNDCTF))
+/** D2H WLAN Rx Packet Chaining context */
+typedef struct rxchain_info {
+	uint		pkt_count;
+	uint		ifidx;
+	void		*pkthead;
+	void		*pkttail;
+	uint8		*h_da;	/* pointer to da of chain head */
+	uint8		*h_sa;	/* pointer to sa of chain head */
+	uint8		h_prio; /* prio of chain head */
+} rxchain_info_t;
+#endif /* BCM_ROUTER_DHD && HNDCTF */
+
+/* Legacy ring sizes for 1Gbps and lesser */
+#define H2DRING_TXPOST_SIZE_V1		512u
+#define H2DRING_HTPUT_TXPOST_SIZE_V1	512u	/* Keep it same as H2DRING_TXPOST_SIZE_V1 */
+#define D2HRING_TXCPL_SIZE_V1		1024u
+
+#define H2DRING_RXPOST_SIZE_V1		512u
+#define D2HRING_RXCPL_SIZE_V1		512u
+
+#define H2DRING_CTRLPOST_SIZE_V1	64u
+#define D2HRING_CTRLCPL_SIZE_V1		64u
+
+#define RX_BUF_BURST_V1			32u	/* Rx buffers for MSDU Data */
+#define RX_BUFPOST_THRESHOLD_V1		32u	/* Rxbuf post threshold */
+
+/* Ring sizes version 2 for 2Gbps */
+#define H2DRING_TXPOST_SIZE_V2		512u
+#define H2DRING_HTPUT_TXPOST_SIZE_V2	2048u	/* ONLY for 4 160 MHz BE flowrings */
+#define D2HRING_TXCPL_SIZE_V2		2048u
+
+#define H2DRING_RXPOST_SIZE_V2		2048u
+#define D2HRING_RXCPL_SIZE_V2		1024u
+
+#define H2DRING_CTRLPOST_SIZE_V2	128u
+#define D2HRING_CTRLCPL_SIZE_V2		64u
+
+#define RX_BUF_BURST_V2			64u	/* Rx buffers for MSDU Data */
+#define RX_BUFPOST_THRESHOLD_V2		64u	/* Rxbuf post threshold */
+
+int ring_size_version;
+int ring_size_alloc_version;
+
+uint h2d_max_txpost;
+uint h2d_htput_max_txpost;
+uint d2h_max_txcpl;
+
+uint h2d_max_rxpost;
+uint d2h_max_rxcpl;
+
+uint h2d_max_ctrlpost;
+uint d2h_max_ctrlcpl;
+
+uint rx_buf_burst;
+uint rx_bufpost_threshold;
+
+#ifndef DHD_RX_CPL_POST_BOUND
+#define DHD_RX_CPL_POST_BOUND		1024
+#endif
+#ifndef DHD_TX_POST_BOUND
+#define DHD_TX_POST_BOUND		256
+#endif
+#ifndef DHD_CTRL_CPL_POST_BOUND
+#define DHD_CTRL_CPL_POST_BOUND		64
+#endif
+#ifndef DHD_TX_CPL_BOUND
+#define DHD_TX_CPL_BOUND		2048
+#endif
+
+uint dhd_rx_cpl_post_bound = DHD_RX_CPL_POST_BOUND;
+uint dhd_tx_post_bound = DHD_TX_POST_BOUND;
+uint dhd_tx_cpl_bound = DHD_TX_CPL_BOUND;
+uint dhd_ctrl_cpl_post_bound = DHD_CTRL_CPL_POST_BOUND;
+
+#ifdef AGG_H2D_DB
+bool agg_h2d_db_enab = TRUE;
+
+#define AGG_H2D_DB_TIMEOUT_USEC		(1000u)	/* 1 msec */
+uint32 agg_h2d_db_timeout = AGG_H2D_DB_TIMEOUT_USEC;
+
+#ifndef AGG_H2D_DB_INFLIGHT_THRESH
+/* Keep inflight threshold same as txp_threshold */
+#define AGG_H2D_DB_INFLIGHT_THRESH TXP_FLUSH_MAX_ITEMS_FLUSH_CNT
+#endif /* !AGG_H2D_DB_INFLIGHT_THRESH */
+
+uint32 agg_h2d_db_inflight_thresh = AGG_H2D_DB_INFLIGHT_THRESH;
+
+#define DHD_NUM_INFLIGHT_HISTO_ROWS (14u)
+#define DHD_INFLIGHT_HISTO_SIZE (sizeof(uint64) * DHD_NUM_INFLIGHT_HISTO_ROWS)
+
+typedef struct _agg_h2d_db_info {
+	void *dhd;
+	struct hrtimer timer;
+	bool init;
+	uint32 direct_db_cnt;
+	uint32 timer_db_cnt;
+	uint64  *inflight_histo;
+} agg_h2d_db_info_t;
+#endif /* AGG_H2D_DB */
+
+#define DHD_DEBUG_INVALID_PKTID
+
+/** DHD protocol handle. Is an opaque type to other DHD software layers. */
+typedef struct dhd_prot {
+	osl_t *osh;		/* OSL handle */
+	uint16 rxbufpost_sz;		/* Size of rx buffer posted to dongle */
+	uint16 rxbufpost_alloc_sz;	/* Actual rx buffer packet allocated in the host */
+	uint16 rxbufpost;
+	uint16 rx_buf_burst;
+	uint16 rx_bufpost_threshold;
+	uint16 max_rxbufpost;
+	uint32 tot_rxbufpost;
+	uint32 tot_rxcpl;
+	uint16 max_eventbufpost;
+	uint16 max_ioctlrespbufpost;
+	uint16 max_tsbufpost;
+	uint16 max_infobufpost;
+	uint16 infobufpost;
+	uint16 cur_event_bufs_posted;
+	uint16 cur_ioctlresp_bufs_posted;
+	uint16 cur_ts_bufs_posted;
+
+	/* Flow control mechanism based on active transmits pending */
+	osl_atomic_t active_tx_count; /* increments/decrements on every packet tx/tx_status */
+	uint16 h2d_max_txpost;
+	uint16 h2d_htput_max_txpost;
+	uint16 txp_threshold;  /* optimization to write "n" tx items at a time to ring */
+
+	/* MsgBuf Ring info: has a dhd_dma_buf that is dynamically allocated */
+	msgbuf_ring_t h2dring_ctrl_subn; /* H2D ctrl message submission ring */
+	msgbuf_ring_t h2dring_rxp_subn; /* H2D RxBuf post ring */
+	msgbuf_ring_t d2hring_ctrl_cpln; /* D2H ctrl completion ring */
+	msgbuf_ring_t d2hring_tx_cpln; /* D2H Tx complete message ring */
+	msgbuf_ring_t d2hring_rx_cpln; /* D2H Rx complete message ring */
+	msgbuf_ring_t *h2dring_info_subn; /* H2D info submission ring */
+	msgbuf_ring_t *d2hring_info_cpln; /* D2H info completion ring */
+	msgbuf_ring_t *d2hring_edl; /* D2H Enhanced Debug Lane (EDL) ring */
+
+	msgbuf_ring_t *h2d_flowrings_pool; /* Pool of preallocated flowings */
+	dhd_dma_buf_t flowrings_dma_buf; /* Contiguous DMA buffer for flowrings */
+	uint16        h2d_rings_total; /* total H2D (common rings + flowrings) */
+
+	uint32		rx_dataoffset;
+
+	dhd_mb_ring_t	mb_ring_fn;	/* called when dongle needs to be notified of new msg */
+	dhd_mb_ring_2_t	mb_2_ring_fn;	/* called when dongle needs to be notified of new msg */
+
+	/* ioctl related resources */
+	uint8 ioctl_state;
+	int16 ioctl_status;		/* status returned from dongle */
+	uint16 ioctl_resplen;
+	dhd_ioctl_recieved_status_t ioctl_received;
+	uint curr_ioctl_cmd;
+	dhd_dma_buf_t	retbuf;		/* For holding ioctl response */
+	dhd_dma_buf_t	ioctbuf;	/* For holding ioctl request */
+
+	dhd_dma_buf_t	d2h_dma_scratch_buf;	/* For holding d2h scratch */
+
+	/* DMA-able arrays for holding WR and RD indices */
+	uint32          rw_index_sz; /* Size of a RD or WR index in dongle */
+	dhd_dma_buf_t   h2d_dma_indx_wr_buf;	/* Array of H2D WR indices */
+	dhd_dma_buf_t	h2d_dma_indx_rd_buf;	/* Array of H2D RD indices */
+	dhd_dma_buf_t	d2h_dma_indx_wr_buf;	/* Array of D2H WR indices */
+	dhd_dma_buf_t	d2h_dma_indx_rd_buf;	/* Array of D2H RD indices */
+	dhd_dma_buf_t h2d_ifrm_indx_wr_buf;	/* Array of H2D WR indices for ifrm */
+
+	dhd_dma_buf_t	host_bus_throughput_buf; /* bus throughput measure buffer */
+
+	dhd_dma_buf_t   *flowring_buf;    /* pool of flow ring buf */
+#ifdef DHD_DMA_INDICES_SEQNUM
+	char *h2d_dma_indx_rd_copy_buf; /* Local copy of H2D WR indices array */
+	char *d2h_dma_indx_wr_copy_buf; /* Local copy of D2H WR indices array */
+	uint32 h2d_dma_indx_rd_copy_bufsz; /* H2D WR indices array size */
+	uint32 d2h_dma_indx_wr_copy_bufsz; /* D2H WR indices array size */
+	uint32 host_seqnum;	/* Seqence number for D2H DMA Indices sync */
+#endif /* DHD_DMA_INDICES_SEQNUM */
+	uint32			flowring_num;
+
+	d2h_sync_cb_t d2h_sync_cb; /* Sync on D2H DMA done: SEQNUM or XORCSUM */
+#ifdef EWP_EDL
+	d2h_edl_sync_cb_t d2h_edl_sync_cb; /* Sync on EDL D2H DMA done: SEQNUM or XORCSUM */
+#endif /* EWP_EDL */
+	ulong d2h_sync_wait_max; /* max number of wait loops to receive one msg */
+	ulong d2h_sync_wait_tot; /* total wait loops */
+
+	dhd_dmaxfer_t	dmaxfer; /* for test/DMA loopback */
+
+	uint16		ioctl_seq_no;
+	uint16		data_seq_no;  /* XXX this field is obsolete */
+	uint16		ioctl_trans_id;
+	void		*pktid_ctrl_map; /* a pktid maps to a packet and its metadata */
+	void		*pktid_rx_map;	/* pktid map for rx path */
+	void		*pktid_tx_map;	/* pktid map for tx path */
+	bool		metadata_dbg;
+	void		*pktid_map_handle_ioctl;
+#ifdef DHD_MAP_PKTID_LOGGING
+	void		*pktid_dma_map;	/* pktid map for DMA MAP */
+	void		*pktid_dma_unmap; /* pktid map for DMA UNMAP */
+#endif /* DHD_MAP_PKTID_LOGGING */
+	uint32		pktid_depleted_cnt;	/* pktid depleted count */
+	/* netif tx queue stop count */
+	uint8		pktid_txq_stop_cnt;
+	/* netif tx queue start count */
+	uint8		pktid_txq_start_cnt;
+	uint64		ioctl_fillup_time;	/* timestamp for ioctl fillup */
+	uint64		ioctl_ack_time;		/* timestamp for ioctl ack */
+	uint64		ioctl_cmplt_time;	/* timestamp for ioctl completion */
+
+	/* Applications/utilities can read tx and rx metadata using IOVARs */
+	uint16		rx_metadata_offset;
+	uint16		tx_metadata_offset;
+
+#if (defined(BCM_ROUTER_DHD) && defined(HNDCTF))
+	rxchain_info_t	rxchain;	/* chain of rx packets */
+#endif
+
+#if defined(DHD_D2H_SOFT_DOORBELL_SUPPORT)
+	/* Host's soft doorbell configuration */
+	bcmpcie_soft_doorbell_t soft_doorbell[BCMPCIE_D2H_COMMON_MSGRINGS];
+#endif /* DHD_D2H_SOFT_DOORBELL_SUPPORT */
+
+	/* Work Queues to be used by the producer and the consumer, and threshold
+	 * when the WRITE index must be synced to consumer's workq
+	 */
+	dhd_dma_buf_t	fw_trap_buf; /* firmware trap buffer */
+#ifdef FLOW_RING_PREALLOC
+	/* pre-allocation htput ring buffer */
+	dhd_dma_buf_t	htput_ring_buf[HTPUT_TOTAL_FLOW_RINGS];
+	/* pre-allocation folw ring(non htput rings) */
+	dhd_dma_buf_t	flow_ring_buf[MAX_FLOW_RINGS];
+#endif /* FLOW_RING_PREALLOC */
+	uint32  host_ipc_version; /* Host sypported IPC rev */
+	uint32  device_ipc_version; /* FW supported IPC rev */
+	uint32  active_ipc_version; /* Host advertised IPC rev */
+	dhd_dma_buf_t   hostts_req_buf; /* For holding host timestamp request buf */
+	bool    hostts_req_buf_inuse;
+	bool    rx_ts_log_enabled;
+	bool    tx_ts_log_enabled;
+#ifdef DHD_HMAPTEST
+	uint32 hmaptest_rx_active;
+	uint32 hmaptest_rx_pktid;
+	char *hmap_rx_buf_va;
+	dmaaddr_t hmap_rx_buf_pa;
+	uint32 hmap_rx_buf_len;
+
+	uint32 hmaptest_tx_active;
+	uint32 hmaptest_tx_pktid;
+	char *hmap_tx_buf_va;
+	dmaaddr_t hmap_tx_buf_pa;
+	uint32	  hmap_tx_buf_len;
+	dhd_hmaptest_t	hmaptest; /* for hmaptest */
+	bool hmap_enabled; /* TRUE = hmap is enabled */
+#endif /* DHD_HMAPTEST */
+	bool no_retry;
+	bool no_aggr;
+	bool fixed_rate;
+	dhd_dma_buf_t	host_scb_buf; /* scb host offload buffer */
+	bool no_tx_resource;
+	uint32 txcpl_db_cnt;
+#ifdef AGG_H2D_DB
+	agg_h2d_db_info_t agg_h2d_db_info;
+#endif /* AGG_H2D_DB */
+	uint64 tx_h2d_db_cnt;
+#ifdef DHD_DEBUG_INVALID_PKTID
+	uint8 ctrl_cpl_snapshot[D2HRING_CTRL_CMPLT_ITEMSIZE];
+#endif /* DHD_DEBUG_INVALID_PKTID */
+	uint32 event_wakeup_pkt; /* Number of event wakeup packet rcvd */
+	uint32 rx_wakeup_pkt;    /* Number of Rx wakeup packet rcvd */
+	uint32 info_wakeup_pkt;  /* Number of info cpl wakeup packet rcvd */
+	msgbuf_ring_t *d2hring_md_cpl; /* D2H metadata completion ring */
+	/* no. which controls how many rx cpl/post items are processed per dpc */
+	uint32 rx_cpl_post_bound;
+	/*
+	 * no. which controls how many tx post items are processed per dpc,
+	 * i.e, how many tx pkts are posted to flowring from the bkp queue
+	 * from dpc context
+	 */
+	uint32 tx_post_bound;
+	/* no. which controls how many tx cpl items are processed per dpc */
+	uint32 tx_cpl_bound;
+	/* no. which controls how many ctrl cpl/post items are processed per dpc */
+	uint32 ctrl_cpl_post_bound;
+} dhd_prot_t;
+
+#ifdef DHD_EWPR_VER2
+#define HANG_INFO_BASE64_BUFFER_SIZE 640
+#endif
+
+#ifdef DHD_DUMP_PCIE_RINGS
+static
+int dhd_ring_write(dhd_pub_t *dhd, msgbuf_ring_t *ring, void *file,
+	const void *user_buf, unsigned long *file_posn);
+#ifdef EWP_EDL
+static
+int dhd_edl_ring_hdr_write(dhd_pub_t *dhd, msgbuf_ring_t *ring, void *file, const void *user_buf,
+	unsigned long *file_posn);
+#endif /* EWP_EDL */
+#endif /* DHD_DUMP_PCIE_RINGS */
+extern bool dhd_timesync_delay_post_bufs(dhd_pub_t *dhdp);
+extern void dhd_schedule_dmaxfer_free(dhd_pub_t* dhdp, dmaxref_mem_map_t *dmmap);
+/* Convert a dmaaddr_t to a base_addr with htol operations */
+static INLINE void dhd_base_addr_htolpa(sh_addr_t *base_addr, dmaaddr_t pa);
+
+/* APIs for managing a DMA-able buffer */
+static int  dhd_dma_buf_audit(dhd_pub_t *dhd, dhd_dma_buf_t *dma_buf);
+static void dhd_dma_buf_reset(dhd_pub_t *dhd, dhd_dma_buf_t *dma_buf);
+
+/* msgbuf ring management */
+static int dhd_prot_allocate_bufs(dhd_pub_t *dhd, dhd_prot_t *prot);
+static int dhd_prot_ring_attach(dhd_pub_t *dhd, msgbuf_ring_t *ring,
+	const char *name, uint16 max_items, uint16 len_item, uint16 ringid);
+static void dhd_prot_ring_init(dhd_pub_t *dhd, msgbuf_ring_t *ring);
+static void dhd_prot_ring_reset(dhd_pub_t *dhd, msgbuf_ring_t *ring);
+static void dhd_prot_ring_detach(dhd_pub_t *dhd, msgbuf_ring_t *ring);
+static void dhd_prot_process_fw_timestamp(dhd_pub_t *dhd, void* buf);
+
+/* Pool of pre-allocated msgbuf_ring_t with DMA-able buffers for Flowrings */
+static int  dhd_prot_flowrings_pool_attach(dhd_pub_t *dhd);
+static void dhd_prot_flowrings_pool_reset(dhd_pub_t *dhd);
+static void dhd_prot_flowrings_pool_detach(dhd_pub_t *dhd);
+
+/* Fetch and Release a flowring msgbuf_ring from flowring  pool */
+static msgbuf_ring_t *dhd_prot_flowrings_pool_fetch(dhd_pub_t *dhd,
+	uint16 flowid);
+/* see also dhd_prot_flowrings_pool_release() in dhd_prot.h */
+
+/* Producer: Allocate space in a msgbuf ring */
+static void* dhd_prot_alloc_ring_space(dhd_pub_t *dhd, msgbuf_ring_t *ring,
+	uint16 nitems, uint16 *alloced, bool exactly_nitems);
+static void* dhd_prot_get_ring_space(msgbuf_ring_t *ring, uint16 nitems,
+	uint16 *alloced, bool exactly_nitems);
+
+/* Consumer: Determine the location where the next message may be consumed */
+static uint8* dhd_prot_get_read_addr(dhd_pub_t *dhd, msgbuf_ring_t *ring,
+	uint32 *available_len, uint32 bound);
+
+/* Producer (WR index update) or Consumer (RD index update) indication */
+static void dhd_prot_ring_write_complete(dhd_pub_t *dhd, msgbuf_ring_t *ring,
+	void *p, uint16 len);
+
+#ifdef AGG_H2D_DB
+static void dhd_prot_agg_db_ring_write(dhd_pub_t *dhd, msgbuf_ring_t * ring,
+		void* p, uint16 len);
+static void dhd_prot_aggregate_db_ring_door_bell(dhd_pub_t *dhd, uint16 flowid, bool ring_db);
+static void dhd_prot_txdata_aggr_db_write_flush(dhd_pub_t *dhd, uint16 flowid);
+#endif /* AGG_H2D_DB */
+static void dhd_prot_ring_doorbell(dhd_pub_t *dhd, uint32 value);
+static void dhd_prot_upd_read_idx(dhd_pub_t *dhd, msgbuf_ring_t *ring);
+
+static INLINE int dhd_prot_dma_indx_alloc(dhd_pub_t *dhd, uint8 type,
+	dhd_dma_buf_t *dma_buf, uint32 bufsz);
+
+/* Set/Get a RD or WR index in the array of indices */
+/* See also: dhd_prot_dma_indx_init() */
+void dhd_prot_dma_indx_set(dhd_pub_t *dhd, uint16 new_index, uint8 type,
+	uint16 ringid);
+static uint16 dhd_prot_dma_indx_get(dhd_pub_t *dhd, uint8 type, uint16 ringid);
+
+/* Locate a packet given a pktid */
+static INLINE void *dhd_prot_packet_get(dhd_pub_t *dhd, uint32 pktid, uint8 pkttype,
+	bool free_pktid);
+/* Locate a packet given a PktId and free it. */
+static INLINE void dhd_prot_packet_free(dhd_pub_t *dhd, void *pkt, uint8 pkttype, bool send);
+
+static int dhd_msgbuf_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd,
+	void *buf, uint len, uint8 action);
+static int dhd_msgbuf_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd,
+	void *buf, uint len, uint8 action);
+static int dhd_msgbuf_wait_ioctl_cmplt(dhd_pub_t *dhd, uint32 len, void *buf);
+static int dhd_fillup_ioct_reqst(dhd_pub_t *dhd, uint16 len, uint cmd,
+	void *buf, int ifidx);
+static void dhd_msgbuf_dump_iovar_name(dhd_pub_t *dhd);
+
+/* Post buffers for Rx, control ioctl response and events */
+static uint16 dhd_msgbuf_rxbuf_post_ctrlpath(dhd_pub_t *dhd, uint8 msgid, uint32 max_to_post);
+static void dhd_msgbuf_rxbuf_post_ioctlresp_bufs(dhd_pub_t *pub);
+static void dhd_msgbuf_rxbuf_post_event_bufs(dhd_pub_t *pub);
+static void dhd_msgbuf_rxbuf_post(dhd_pub_t *dhd, bool use_rsv_pktid);
+static int dhd_prot_rxbuf_post(dhd_pub_t *dhd, uint16 count, bool use_rsv_pktid);
+static int dhd_msgbuf_rxbuf_post_ts_bufs(dhd_pub_t *pub);
+
+static void dhd_prot_return_rxbuf(dhd_pub_t *dhd, msgbuf_ring_t *ring, uint32 pktid, uint32 rxcnt);
+
+/* D2H Message handling */
+static int dhd_prot_process_msgtype(dhd_pub_t *dhd, msgbuf_ring_t *ring, uint8 *buf, uint32 len);
+
+/* D2H Message handlers */
+static void dhd_prot_noop(dhd_pub_t *dhd, void *msg);
+static void dhd_prot_txstatus_process(dhd_pub_t *dhd, void *msg);
+static void dhd_prot_ioctcmplt_process(dhd_pub_t *dhd, void *msg);
+static void dhd_prot_ioctack_process(dhd_pub_t *dhd, void *msg);
+static void dhd_prot_ringstatus_process(dhd_pub_t *dhd, void *msg);
+static void dhd_prot_genstatus_process(dhd_pub_t *dhd, void *msg);
+static void dhd_prot_event_process(dhd_pub_t *dhd, void *msg);
+
+/* Loopback test with dongle */
+static void dmaxfer_free_dmaaddr(dhd_pub_t *dhd, dhd_dmaxfer_t *dma);
+static int dmaxfer_prepare_dmaaddr(dhd_pub_t *dhd, uint len, uint srcdelay,
+	uint destdelay, dhd_dmaxfer_t *dma);
+static void dhd_msgbuf_dmaxfer_process(dhd_pub_t *dhd, void *msg);
+
+/* Flowring management communication with dongle */
+static void dhd_prot_flow_ring_create_response_process(dhd_pub_t *dhd, void *msg);
+static void dhd_prot_flow_ring_delete_response_process(dhd_pub_t *dhd, void *msg);
+static void dhd_prot_flow_ring_flush_response_process(dhd_pub_t *dhd, void *msg);
+static void dhd_prot_process_flow_ring_resume_response(dhd_pub_t *dhd, void* msg);
+static void dhd_prot_process_flow_ring_suspend_response(dhd_pub_t *dhd, void* msg);
+
+/* Monitor Mode */
+#if defined(WL_MONITOR)
+extern bool dhd_monitor_enabled(dhd_pub_t *dhd, int ifidx);
+extern void dhd_rx_mon_pkt(dhd_pub_t *dhdp, host_rxbuf_cmpl_t* msg, void *pkt, int ifidx);
+#if defined(DBG_PKT_MON)
+extern void dhd_80211_mon_pkt(dhd_pub_t *dhdp, host_rxbuf_cmpl_t* msg, void *pkt, int ifidx);
+#endif /* DBG_PKT_MON */
+#endif /* WL_MONITOR */
+
+/* Configure a soft doorbell per D2H ring */
+static void dhd_msgbuf_ring_config_d2h_soft_doorbell(dhd_pub_t *dhd);
+static void dhd_prot_process_d2h_ring_config_complete(dhd_pub_t *dhd, void *msg);
+static void dhd_prot_process_d2h_ring_create_complete(dhd_pub_t *dhd, void *buf);
+#if !defined(BCM_ROUTER_DHD)
+static void dhd_prot_process_h2d_ring_create_complete(dhd_pub_t *dhd, void *buf);
+static void dhd_prot_process_infobuf_complete(dhd_pub_t *dhd, void* buf);
+#endif /* !BCM_ROUTER_DHD */
+static void dhd_prot_process_d2h_mb_data(dhd_pub_t *dhd, void* buf);
+static void dhd_prot_detach_info_rings(dhd_pub_t *dhd);
+#ifdef EWP_EDL
+static void dhd_prot_detach_edl_rings(dhd_pub_t *dhd);
+#endif
+static void dhd_prot_detach_md_rings(dhd_pub_t *dhd);
+static void dhd_prot_process_d2h_host_ts_complete(dhd_pub_t *dhd, void* buf);
+static void dhd_prot_process_snapshot_complete(dhd_pub_t *dhd, void *buf);
+
+#ifdef DHD_FLOW_RING_STATUS_TRACE
+void dhd_dump_bus_flow_ring_status_isr_trace(dhd_bus_t *bus, struct bcmstrbuf *strbuf);
+void dhd_dump_bus_flow_ring_status_dpc_trace(dhd_bus_t *bus, struct bcmstrbuf *strbuf);
+#endif /* DHD_FLOW_RING_STATUS_TRACE */
+
+#ifdef DHD_TX_PROFILE
+extern bool dhd_protocol_matches_profile(uint8 *p, int plen, const
+		dhd_tx_profile_protocol_t *proto, bool is_host_sfhllc);
+#endif /* defined(DHD_TX_PROFILE) */
+
+static void dhd_update_rxstats(dhd_pub_t *dhd, host_rxbuf_cmpl_t *rxstatus);
+typedef void (*dhd_msgbuf_func_t)(dhd_pub_t *dhd, void *msg);
+
+/** callback functions for messages generated by the dongle */
+#define MSG_TYPE_INVALID 0
+
+static dhd_msgbuf_func_t table_lookup[DHD_PROT_FUNCS] = {
+	dhd_prot_noop, /* 0 is MSG_TYPE_INVALID */
+	dhd_prot_genstatus_process, /* MSG_TYPE_GEN_STATUS */
+	dhd_prot_ringstatus_process, /* MSG_TYPE_RING_STATUS */
+	NULL,
+	dhd_prot_flow_ring_create_response_process, /* MSG_TYPE_FLOW_RING_CREATE_CMPLT */
+	NULL,
+	dhd_prot_flow_ring_delete_response_process, /* MSG_TYPE_FLOW_RING_DELETE_CMPLT */
+	NULL,
+	dhd_prot_flow_ring_flush_response_process, /* MSG_TYPE_FLOW_RING_FLUSH_CMPLT */
+	NULL,
+	dhd_prot_ioctack_process, /* MSG_TYPE_IOCTLPTR_REQ_ACK */
+	NULL,
+	dhd_prot_ioctcmplt_process, /* MSG_TYPE_IOCTL_CMPLT */
+	NULL,
+	dhd_prot_event_process, /* MSG_TYPE_WL_EVENT */
+	NULL,
+	dhd_prot_txstatus_process, /* MSG_TYPE_TX_STATUS */
+	NULL,
+	NULL,	/* MSG_TYPE_RX_CMPLT use dedicated handler */
+	NULL,
+	dhd_msgbuf_dmaxfer_process, /* MSG_TYPE_LPBK_DMAXFER_CMPLT */
+	NULL, /* MSG_TYPE_FLOW_RING_RESUME */
+	dhd_prot_process_flow_ring_resume_response, /* MSG_TYPE_FLOW_RING_RESUME_CMPLT */
+	NULL, /* MSG_TYPE_FLOW_RING_SUSPEND */
+	dhd_prot_process_flow_ring_suspend_response, /* MSG_TYPE_FLOW_RING_SUSPEND_CMPLT */
+	NULL, /* MSG_TYPE_INFO_BUF_POST */
+#if defined(BCM_ROUTER_DHD)
+	NULL, /* MSG_TYPE_INFO_BUF_CMPLT */
+#else
+	dhd_prot_process_infobuf_complete, /* MSG_TYPE_INFO_BUF_CMPLT */
+#endif /* BCM_ROUTER_DHD */
+	NULL, /* MSG_TYPE_H2D_RING_CREATE */
+	NULL, /* MSG_TYPE_D2H_RING_CREATE */
+#if defined(BCM_ROUTER_DHD)
+	NULL, /* MSG_TYPE_H2D_RING_CREATE_CMPLT */
+#else
+	dhd_prot_process_h2d_ring_create_complete, /* MSG_TYPE_H2D_RING_CREATE_CMPLT */
+#endif /* BCM_ROUTER_DHD */
+	dhd_prot_process_d2h_ring_create_complete, /* MSG_TYPE_D2H_RING_CREATE_CMPLT */
+	NULL, /* MSG_TYPE_H2D_RING_CONFIG */
+	NULL, /* MSG_TYPE_D2H_RING_CONFIG */
+	NULL, /* MSG_TYPE_H2D_RING_CONFIG_CMPLT */
+	dhd_prot_process_d2h_ring_config_complete, /* MSG_TYPE_D2H_RING_CONFIG_CMPLT */
+	NULL, /* MSG_TYPE_H2D_MAILBOX_DATA */
+	dhd_prot_process_d2h_mb_data, /* MSG_TYPE_D2H_MAILBOX_DATA */
+	NULL,	/* MSG_TYPE_TIMSTAMP_BUFPOST */
+	NULL,	/* MSG_TYPE_HOSTTIMSTAMP */
+	dhd_prot_process_d2h_host_ts_complete,	/* MSG_TYPE_HOSTTIMSTAMP_CMPLT */
+	dhd_prot_process_fw_timestamp,	/* MSG_TYPE_FIRMWARE_TIMESTAMP */
+	NULL,	/* MSG_TYPE_SNAPSHOT_UPLOAD */
+	dhd_prot_process_snapshot_complete,	/* MSG_TYPE_SNAPSHOT_CMPLT */
+};
+
+#if (defined(BCM_ROUTER_DHD) && defined(HNDCTF))
+/* Related to router CPU mapping per radio core */
+#define DHD_RX_CHAINING
+#endif /* BCM_ROUTER_DHD && HNDCTF */
+
+#ifdef DHD_RX_CHAINING
+
+#define PKT_CTF_CHAINABLE(dhd, ifidx, evh, prio, h_sa, h_da, h_prio) \
+	(dhd_wet_chainable(dhd) && \
+	dhd_rx_pkt_chainable((dhd), (ifidx)) && \
+	!ETHER_ISNULLDEST(((struct ether_header *)(evh))->ether_dhost) && \
+	!ETHER_ISMULTI(((struct ether_header *)(evh))->ether_dhost) && \
+	!eacmp((h_da), ((struct ether_header *)(evh))->ether_dhost) && \
+	!eacmp((h_sa), ((struct ether_header *)(evh))->ether_shost) && \
+	((h_prio) == (prio)) && (dhd_ctf_hotbrc_check((dhd), (evh), (ifidx))) && \
+	((((struct ether_header *)(evh))->ether_type == HTON16(ETHER_TYPE_IP)) || \
+	(((struct ether_header *)(evh))->ether_type == HTON16(ETHER_TYPE_IPV6))))
+
+static INLINE void dhd_rxchain_reset(rxchain_info_t *rxchain);
+static void dhd_rxchain_frame(dhd_pub_t *dhd, void *pkt, uint ifidx);
+static void dhd_rxchain_commit(dhd_pub_t *dhd);
+
+#define DHD_PKT_CTF_MAX_CHAIN_LEN	64
+
+#endif /* DHD_RX_CHAINING */
+
+#define DHD_LPBKDTDUMP_ON()	(dhd_msg_level & DHD_LPBKDTDUMP_VAL)
+
+static void dhd_prot_h2d_sync_init(dhd_pub_t *dhd);
+
+uint32
+dhd_prot_get_tx_post_bound(dhd_pub_t *dhd)
+{
+	dhd_prot_t *prot = dhd->prot;
+	return prot->tx_post_bound;
+}
+
+uint32
+dhd_prot_get_ctrl_cpl_post_bound(dhd_pub_t *dhd)
+{
+	dhd_prot_t *prot = dhd->prot;
+	return prot->ctrl_cpl_post_bound;
+}
+
+uint32
+dhd_prot_get_tx_cpl_bound(dhd_pub_t *dhd)
+{
+	dhd_prot_t *prot = dhd->prot;
+	return prot->tx_cpl_bound;
+}
+
+uint32
+dhd_prot_get_rx_cpl_post_bound(dhd_pub_t *dhd)
+{
+	dhd_prot_t *prot = dhd->prot;
+	return prot->rx_cpl_post_bound;
+}
+
+void
+dhd_prot_set_tx_post_bound(dhd_pub_t *dhd, uint32 val)
+{
+	dhd_prot_t *prot = dhd->prot;
+	prot->tx_post_bound = val;
+}
+
+void
+dhd_prot_set_ctrl_cpl_post_bound(dhd_pub_t *dhd, uint32 val)
+{
+	dhd_prot_t *prot = dhd->prot;
+	prot->ctrl_cpl_post_bound = val;
+}
+
+void
+dhd_prot_set_tx_cpl_bound(dhd_pub_t *dhd, uint32 val)
+{
+	dhd_prot_t *prot = dhd->prot;
+	prot->tx_cpl_bound = val;
+}
+
+void dhd_prot_set_rx_cpl_post_bound(dhd_pub_t *dhd, uint32 val)
+{
+	dhd_prot_t *prot = dhd->prot;
+	prot->rx_cpl_post_bound = val;
+}
+
+void
+dhd_prot_set_ring_size_ver(dhd_pub_t *dhd, int version)
+{
+	if (ring_size_alloc_version < version) {
+		DHD_ERROR(("%s: Ring alloced version(%d) is lesser than requested(%d), ABORT\n",
+			__FUNCTION__, ring_size_alloc_version, version));
+		return;
+	}
+	ring_size_version = version;
+
+	/* Change each parameters only if they are 0s, non-zero means,
+	 * it is overridden via module parameter.
+	 */
+	switch (version) {
+		case 1:
+			if (!h2d_max_txpost) {
+				h2d_max_txpost = H2DRING_TXPOST_SIZE_V1;
+			}
+			if (!h2d_htput_max_txpost) {
+				h2d_htput_max_txpost = H2DRING_HTPUT_TXPOST_SIZE_V1;
+			}
+			if (!d2h_max_txcpl) {
+				d2h_max_txcpl = D2HRING_TXCPL_SIZE_V1;
+			}
+
+			if (!h2d_max_rxpost) {
+				h2d_max_rxpost = H2DRING_RXPOST_SIZE_V1;
+			}
+			if (!d2h_max_rxcpl) {
+				d2h_max_rxcpl = D2HRING_RXCPL_SIZE_V1;
+			}
+
+			if (!h2d_max_ctrlpost) {
+				h2d_max_ctrlpost = H2DRING_CTRLPOST_SIZE_V1;
+			}
+			if (!d2h_max_ctrlcpl) {
+				d2h_max_ctrlcpl = D2HRING_CTRLCPL_SIZE_V1;
+			}
+
+			if (!rx_buf_burst) {
+				rx_buf_burst = RX_BUF_BURST_V1;
+			}
+			if (!rx_bufpost_threshold) {
+				rx_bufpost_threshold = RX_BUFPOST_THRESHOLD_V1;
+			}
+			break;
+		case 2:
+			if (!h2d_max_txpost) {
+				h2d_max_txpost = H2DRING_TXPOST_SIZE_V2;
+			}
+			if (!h2d_htput_max_txpost) {
+				h2d_htput_max_txpost = H2DRING_HTPUT_TXPOST_SIZE_V2;
+			}
+			if (!d2h_max_txcpl) {
+				d2h_max_txcpl = D2HRING_TXCPL_SIZE_V2;
+			}
+
+			if (!h2d_max_rxpost) {
+				h2d_max_rxpost = H2DRING_RXPOST_SIZE_V2;
+			}
+			if (!d2h_max_rxcpl) {
+				d2h_max_rxcpl = D2HRING_RXCPL_SIZE_V2;
+			}
+
+			if (!h2d_max_ctrlpost) {
+				h2d_max_ctrlpost = H2DRING_CTRLPOST_SIZE_V2;
+			}
+			if (!d2h_max_ctrlcpl) {
+				d2h_max_ctrlcpl = D2HRING_CTRLCPL_SIZE_V2;
+			}
+
+			if (!rx_buf_burst) {
+				rx_buf_burst = RX_BUF_BURST_V2;
+			}
+			if (!rx_bufpost_threshold) {
+				rx_bufpost_threshold = RX_BUFPOST_THRESHOLD_V2;
+			}
+			break;
+		default:
+			DHD_ERROR(("%s: invalid override version:%d", __FUNCTION__, version));
+	}
+}
+
+#ifdef D2H_MINIDUMP
+dhd_dma_buf_t *
+dhd_prot_get_minidump_buf(dhd_pub_t *dhd)
+{
+	return &dhd->prot->fw_trap_buf;
+}
+#endif /* D2H_MINIDUMP */
+
+uint16
+dhd_prot_get_rxbufpost_sz(dhd_pub_t *dhd)
+{
+	return dhd->prot->rxbufpost_sz;
+}
+
+uint16
+dhd_prot_get_rxbufpost_alloc_sz(dhd_pub_t *dhd)
+{
+	return dhd->prot->rxbufpost_alloc_sz;
+}
+uint16
+dhd_prot_get_h2d_rx_post_active(dhd_pub_t *dhd)
+{
+	dhd_prot_t *prot = dhd->prot;
+	msgbuf_ring_t *flow_ring = &prot->h2dring_rxp_subn;
+	uint16 rd, wr;
+
+	/* Since wr is owned by host in h2d direction, directly read wr */
+	wr = flow_ring->wr;
+
+	if (dhd->dma_d2h_ring_upd_support) {
+		rd = dhd_prot_dma_indx_get(dhd, H2D_DMA_INDX_RD_UPD, flow_ring->idx);
+	} else {
+		dhd_bus_cmn_readshared(dhd->bus, &rd, RING_RD_UPD, flow_ring->idx);
+	}
+	return NTXPACTIVE(rd, wr, flow_ring->max_items);
+}
+
+uint16
+dhd_prot_get_d2h_rx_cpln_active(dhd_pub_t *dhd)
+{
+	dhd_prot_t *prot = dhd->prot;
+	msgbuf_ring_t *flow_ring = &prot->d2hring_rx_cpln;
+	uint16 rd, wr;
+
+	if (dhd->dma_d2h_ring_upd_support) {
+		wr = dhd_prot_dma_indx_get(dhd, D2H_DMA_INDX_WR_UPD, flow_ring->idx);
+	} else {
+		dhd_bus_cmn_readshared(dhd->bus, &wr, RING_WR_UPD, flow_ring->idx);
+	}
+
+	/* Since rd is owned by host in d2h direction, directly read rd */
+	rd = flow_ring->rd;
+
+	return NTXPACTIVE(rd, wr, flow_ring->max_items);
+}
+
+bool
+dhd_prot_is_h2d_ring_empty(dhd_pub_t *dhd, void *prot_info)
+{
+	msgbuf_ring_t *ring = (msgbuf_ring_t *)prot_info;
+	uint16 rd, wr;
+	bool ret;
+
+	/* For h2d ring, WR is owned by host, RD is owned by dongle */
+	wr = ring->wr;
+	if (dhd->dma_h2d_ring_upd_support) {
+		rd = dhd_prot_dma_indx_get(dhd, H2D_DMA_INDX_RD_UPD, ring->idx);
+	} else {
+		dhd_bus_cmn_readshared(dhd->bus, &rd, RING_RD_UPD, ring->idx);
+	}
+	ret = (wr == rd) ? TRUE : FALSE;
+	return ret;
+}
+
+/* returns TRUE if there are pending ctrl completions to be processed at host */
+bool
+dhd_prot_check_pending_ctrl_cmpls(dhd_pub_t *dhd)
+{
+	msgbuf_ring_t *ring = &dhd->prot->d2hring_ctrl_cpln;
+	uint16 wr, host_rd;
+	bool ret;
+
+	/* For Completion ring, WR is owned by dongle, RD is owned by Host */
+	if (dhd->dma_d2h_ring_upd_support) {
+		wr = dhd_prot_dma_indx_get(dhd, D2H_DMA_INDX_WR_UPD, ring->idx);
+	} else {
+		dhd_bus_cmn_readshared(dhd->bus, &wr, RING_WR_UPD, ring->idx);
+	}
+
+	if (wr > ring->max_items) {
+		DHD_ERROR(("%s(): ring %p, ring->name %s, wr %d ring->max_items %d\n",
+			__FUNCTION__, ring, ring->name, wr, ring->max_items));
+		return FALSE;
+	}
+
+	host_rd = ring->rd;
+
+	/* Consider the ring as processed if host rd and dongle wr are same */
+	ret = (host_rd != wr) ? TRUE : FALSE;
+	return ret;
+}
+
+void
+dhd_prot_dump_ring_ptrs(void *prot_info)
+{
+	msgbuf_ring_t *ring = (msgbuf_ring_t *)prot_info;
+	DHD_ERROR(("%s curr_rd: %d rd: %d wr: %d \n", __FUNCTION__,
+		ring->curr_rd, ring->rd, ring->wr));
+}
+
+/**
+ * D2H DMA to completion callback handlers. Based on the mode advertised by the
+ * dongle through the PCIE shared region, the appropriate callback will be
+ * registered in the proto layer to be invoked prior to precessing any message
+ * from a D2H DMA ring. If the dongle uses a read barrier or another mode that
+ * does not require host participation, then a noop callback handler will be
+ * bound that simply returns the msg_type.
+ */
+static void dhd_prot_d2h_sync_livelock(dhd_pub_t *dhd, uint32 msg_seqnum, msgbuf_ring_t *ring,
+                                       uint32 tries, volatile uchar *msg, int msglen);
+static uint8 dhd_prot_d2h_sync_seqnum(dhd_pub_t *dhd, msgbuf_ring_t *ring,
+                                      volatile cmn_msg_hdr_t *msg, int msglen);
+static uint8 dhd_prot_d2h_sync_xorcsum(dhd_pub_t *dhd, msgbuf_ring_t *ring,
+                                       volatile cmn_msg_hdr_t *msg, int msglen);
+static uint8 dhd_prot_d2h_sync_none(dhd_pub_t *dhd, msgbuf_ring_t *ring,
+                                    volatile cmn_msg_hdr_t *msg, int msglen);
+static void dhd_prot_d2h_sync_init(dhd_pub_t *dhd);
+static int dhd_send_d2h_ringcreate(dhd_pub_t *dhd, msgbuf_ring_t *ring_to_create,
+	uint16 ring_type, uint32 id);
+static int dhd_send_h2d_ringcreate(dhd_pub_t *dhd, msgbuf_ring_t *ring_to_create,
+	uint8 type, uint32 id);
+
+/**
+ * dhd_prot_d2h_sync_livelock - when the host determines that a DMA transfer has
+ * not completed, a livelock condition occurs. Host will avert this livelock by
+ * dropping this message and moving to the next. This dropped message can lead
+ * to a packet leak, or even something disastrous in the case the dropped
+ * message happens to be a control response.
+ * Here we will log this condition. One may choose to reboot the dongle.
+ *
+ */
+static void
+dhd_prot_d2h_sync_livelock(dhd_pub_t *dhd, uint32 msg_seqnum, msgbuf_ring_t *ring, uint32 tries,
+                           volatile uchar *msg, int msglen)
+{
+	uint32 ring_seqnum = ring->seqnum;
+
+	if (dhd_query_bus_erros(dhd)) {
+		return;
+	}
+
+	DHD_ERROR((
+		"LIVELOCK DHD<%p> ring<%s> msg_seqnum<%u> ring_seqnum<%u:%u> tries<%u> max<%lu>"
+		" tot<%lu> dma_buf va<%p> msg<%p> curr_rd<%d> rd<%d> wr<%d>\n",
+		dhd, ring->name, msg_seqnum, ring_seqnum, ring_seqnum% D2H_EPOCH_MODULO, tries,
+		dhd->prot->d2h_sync_wait_max, dhd->prot->d2h_sync_wait_tot,
+		ring->dma_buf.va, msg, ring->curr_rd, ring->rd, ring->wr));
+
+	dhd_prhex("D2H MsgBuf Failure", msg, msglen, DHD_ERROR_VAL);
+
+	/* Try to resume if already suspended or suspend in progress */
+
+	/* Skip if still in suspended or suspend in progress */
+	if (DHD_BUS_CHECK_SUSPEND_OR_ANY_SUSPEND_IN_PROGRESS(dhd)) {
+		DHD_ERROR(("%s: bus is in suspend(%d) or suspending(0x%x) state, so skip\n",
+			__FUNCTION__, dhd->busstate, dhd->dhd_bus_busy_state));
+		goto exit;
+	}
+
+	dhd_bus_dump_console_buffer(dhd->bus);
+	dhd_prot_debug_info_print(dhd);
+
+#ifdef DHD_FW_COREDUMP
+	if (dhd->memdump_enabled) {
+		/* collect core dump */
+		dhd->memdump_type = DUMP_TYPE_BY_LIVELOCK;
+		dhd_bus_mem_dump(dhd);
+	}
+#endif /* DHD_FW_COREDUMP */
+
+exit:
+	dhd_schedule_reset(dhd);
+
+#ifdef OEM_ANDROID
+#endif /* OEM_ANDROID */
+	dhd->livelock_occured = TRUE;
+}
+
+/**
+ * dhd_prot_d2h_sync_seqnum - Sync on a D2H DMA completion using the SEQNUM
+ * mode. Sequence number is always in the last word of a message.
+ */
+static uint8
+BCMFASTPATH(dhd_prot_d2h_sync_seqnum)(dhd_pub_t *dhd, msgbuf_ring_t *ring,
+                         volatile cmn_msg_hdr_t *msg, int msglen)
+{
+	uint32 tries;
+	uint32 ring_seqnum = ring->seqnum % D2H_EPOCH_MODULO;
+	int num_words = msglen / sizeof(uint32); /* num of 32bit words */
+	volatile uint32 *marker = (volatile uint32 *)msg + (num_words - 1); /* last word */
+	dhd_prot_t *prot = dhd->prot;
+	uint32 msg_seqnum;
+	uint32 step = 0;
+	uint32 delay = PCIE_D2H_SYNC_DELAY;
+	uint32 total_tries = 0;
+
+	ASSERT(msglen == ring->item_len);
+
+	BCM_REFERENCE(delay);
+	/*
+	 * For retries we have to make some sort of stepper algorithm.
+	 * We see that every time when the Dongle comes out of the D3
+	 * Cold state, the first D2H mem2mem DMA takes more time to
+	 * complete, leading to livelock issues.
+	 *
+	 * Case 1 - Apart from Host CPU some other bus master is
+	 * accessing the DDR port, probably page close to the ring
+	 * so, PCIE does not get a change to update the memory.
+	 * Solution - Increase the number of tries.
+	 *
+	 * Case 2 - The 50usec delay given by the Host CPU is not
+	 * sufficient for the PCIe RC to start its work.
+	 * In this case the breathing time of 50usec given by
+	 * the Host CPU is not sufficient.
+	 * Solution: Increase the delay in a stepper fashion.
+	 * This is done to ensure that there are no
+	 * unwanted extra delay introdcued in normal conditions.
+	 */
+	for (step = 1; step <= PCIE_D2H_SYNC_NUM_OF_STEPS; step++) {
+		for (tries = 0; tries < PCIE_D2H_SYNC_WAIT_TRIES; tries++) {
+			msg_seqnum = *marker;
+			if (ltoh32(msg_seqnum) == ring_seqnum) { /* dma upto last word done */
+				ring->seqnum++; /* next expected sequence number */
+				/* Check for LIVELOCK induce flag, which is set by firing
+				 * dhd iovar to induce LIVELOCK error. If flag is set,
+				 * MSG_TYPE_INVALID is returned, which results in to LIVELOCK error.
+				 */
+				if (dhd->dhd_induce_error != DHD_INDUCE_LIVELOCK) {
+					goto dma_completed;
+				}
+			}
+
+			total_tries = (uint32)(((step-1) * PCIE_D2H_SYNC_WAIT_TRIES) + tries);
+
+			if (total_tries > prot->d2h_sync_wait_max)
+				prot->d2h_sync_wait_max = total_tries;
+
+			OSL_CACHE_INV(msg, msglen); /* invalidate and try again */
+			OSL_CPU_RELAX(); /* CPU relax for msg_seqnum  value to update */
+			OSL_DELAY(delay * step); /* Add stepper delay */
+
+		} /* for PCIE_D2H_SYNC_WAIT_TRIES */
+	} /* for PCIE_D2H_SYNC_NUM_OF_STEPS */
+
+	dhd_prot_d2h_sync_livelock(dhd, msg_seqnum, ring, total_tries,
+		(volatile uchar *) msg, msglen);
+
+	ring->seqnum++; /* skip this message ... leak of a pktid */
+	return MSG_TYPE_INVALID; /* invalid msg_type 0 -> noop callback */
+
+dma_completed:
+
+	prot->d2h_sync_wait_tot += tries;
+	return msg->msg_type;
+}
+
+/**
+ * dhd_prot_d2h_sync_xorcsum - Sync on a D2H DMA completion using the XORCSUM
+ * mode. The xorcsum is placed in the last word of a message. Dongle will also
+ * place a seqnum in the epoch field of the cmn_msg_hdr.
+ */
+static uint8
+BCMFASTPATH(dhd_prot_d2h_sync_xorcsum)(dhd_pub_t *dhd, msgbuf_ring_t *ring,
+                          volatile cmn_msg_hdr_t *msg, int msglen)
+{
+	uint32 tries;
+	uint32 prot_checksum = 0; /* computed checksum */
+	int num_words = msglen / sizeof(uint32); /* num of 32bit words */
+	uint8 ring_seqnum = ring->seqnum % D2H_EPOCH_MODULO;
+	dhd_prot_t *prot = dhd->prot;
+	uint32 step = 0;
+	uint32 delay = PCIE_D2H_SYNC_DELAY;
+	uint32 total_tries = 0;
+
+	ASSERT(msglen == ring->item_len);
+
+	BCM_REFERENCE(delay);
+	/*
+	 * For retries we have to make some sort of stepper algorithm.
+	 * We see that every time when the Dongle comes out of the D3
+	 * Cold state, the first D2H mem2mem DMA takes more time to
+	 * complete, leading to livelock issues.
+	 *
+	 * Case 1 - Apart from Host CPU some other bus master is
+	 * accessing the DDR port, probably page close to the ring
+	 * so, PCIE does not get a change to update the memory.
+	 * Solution - Increase the number of tries.
+	 *
+	 * Case 2 - The 50usec delay given by the Host CPU is not
+	 * sufficient for the PCIe RC to start its work.
+	 * In this case the breathing time of 50usec given by
+	 * the Host CPU is not sufficient.
+	 * Solution: Increase the delay in a stepper fashion.
+	 * This is done to ensure that there are no
+	 * unwanted extra delay introdcued in normal conditions.
+	 */
+	for (step = 1; step <= PCIE_D2H_SYNC_NUM_OF_STEPS; step++) {
+		for (tries = 0; tries < PCIE_D2H_SYNC_WAIT_TRIES; tries++) {
+			/* First verify if the seqnumber has been update,
+			 * if yes, then only check xorcsum.
+			 * Once seqnum and xorcsum is proper that means
+			 * complete message has arrived.
+			 */
+			if (msg->epoch == ring_seqnum) {
+				prot_checksum = bcm_compute_xor32((volatile uint32 *)msg,
+					num_words);
+				if (prot_checksum == 0U) { /* checksum is OK */
+					ring->seqnum++; /* next expected sequence number */
+					/* Check for LIVELOCK induce flag, which is set by firing
+					 * dhd iovar to induce LIVELOCK error. If flag is set,
+					 * MSG_TYPE_INVALID is returned, which results in to
+					 * LIVELOCK error.
+					 */
+					if (dhd->dhd_induce_error != DHD_INDUCE_LIVELOCK) {
+						goto dma_completed;
+					}
+				}
+			}
+
+			total_tries = ((step-1) * PCIE_D2H_SYNC_WAIT_TRIES) + tries;
+
+			if (total_tries > prot->d2h_sync_wait_max)
+				prot->d2h_sync_wait_max = total_tries;
+
+			OSL_CACHE_INV(msg, msglen); /* invalidate and try again */
+			OSL_CPU_RELAX(); /* CPU relax for msg_seqnum  value to update */
+			OSL_DELAY(delay * step); /* Add stepper delay */
+
+		} /* for PCIE_D2H_SYNC_WAIT_TRIES */
+	} /* for PCIE_D2H_SYNC_NUM_OF_STEPS */
+
+	DHD_ERROR(("%s: prot_checksum = 0x%x\n", __FUNCTION__, prot_checksum));
+	dhd_prot_d2h_sync_livelock(dhd, msg->epoch, ring, total_tries,
+		(volatile uchar *) msg, msglen);
+
+	ring->seqnum++; /* skip this message ... leak of a pktid */
+	return MSG_TYPE_INVALID; /* invalid msg_type 0 -> noop callback */
+
+dma_completed:
+
+	prot->d2h_sync_wait_tot += tries;
+	return msg->msg_type;
+}
+
+/**
+ * dhd_prot_d2h_sync_none - Dongle ensure that the DMA will complete and host
+ * need to try to sync. This noop sync handler will be bound when the dongle
+ * advertises that neither the SEQNUM nor XORCSUM mode of DMA sync is required.
+ */
+static uint8
+BCMFASTPATH(dhd_prot_d2h_sync_none)(dhd_pub_t *dhd, msgbuf_ring_t *ring,
+                       volatile cmn_msg_hdr_t *msg, int msglen)
+{
+	/* Check for LIVELOCK induce flag, which is set by firing
+	* dhd iovar to induce LIVELOCK error. If flag is set,
+	* MSG_TYPE_INVALID is returned, which results in to LIVELOCK error.
+	*/
+	if (dhd->dhd_induce_error == DHD_INDUCE_LIVELOCK) {
+		DHD_ERROR(("%s: Inducing livelock\n", __FUNCTION__));
+		return MSG_TYPE_INVALID;
+	} else {
+		return msg->msg_type;
+	}
+}
+
+#ifdef EWP_EDL
+/**
+ * dhd_prot_d2h_sync_edl - Sync on a D2H DMA completion by validating the cmn_msg_hdr_t
+ * header values at both the beginning and end of the payload.
+ * The cmn_msg_hdr_t is placed at the start and end of the payload
+ * in each work item in the EDL ring.
+ * Dongle will place a seqnum inside the cmn_msg_hdr_t 'epoch' field
+ * and the length of the payload in the 'request_id' field.
+ * Structure of each work item in the EDL ring:
+ * | cmn_msg_hdr_t | payload (var len) | cmn_msg_hdr_t |
+ * NOTE: - it was felt that calculating xorcsum for the entire payload (max length of 1648 bytes) is
+ * too costly on the dongle side and might take up too many ARM cycles,
+ * hence the xorcsum sync method is not being used for EDL ring.
+ */
+static int
+BCMFASTPATH(dhd_prot_d2h_sync_edl)(dhd_pub_t *dhd, msgbuf_ring_t *ring,
+                          volatile cmn_msg_hdr_t *msg)
+{
+	uint32 tries;
+	int msglen = 0, len = 0;
+	uint32 ring_seqnum = ring->seqnum % D2H_EPOCH_MODULO;
+	dhd_prot_t *prot = dhd->prot;
+	uint32 step = 0;
+	uint32 delay = PCIE_D2H_SYNC_DELAY;
+	uint32 total_tries = 0;
+	volatile cmn_msg_hdr_t *trailer = NULL;
+	volatile uint8 *buf = NULL;
+	bool valid_msg = FALSE;
+
+	BCM_REFERENCE(delay);
+	/*
+	 * For retries we have to make some sort of stepper algorithm.
+	 * We see that every time when the Dongle comes out of the D3
+	 * Cold state, the first D2H mem2mem DMA takes more time to
+	 * complete, leading to livelock issues.
+	 *
+	 * Case 1 - Apart from Host CPU some other bus master is
+	 * accessing the DDR port, probably page close to the ring
+	 * so, PCIE does not get a change to update the memory.
+	 * Solution - Increase the number of tries.
+	 *
+	 * Case 2 - The 50usec delay given by the Host CPU is not
+	 * sufficient for the PCIe RC to start its work.
+	 * In this case the breathing time of 50usec given by
+	 * the Host CPU is not sufficient.
+	 * Solution: Increase the delay in a stepper fashion.
+	 * This is done to ensure that there are no
+	 * unwanted extra delay introdcued in normal conditions.
+	 */
+	for (step = 1; step <= PCIE_D2H_SYNC_NUM_OF_STEPS; step++) {
+		for (tries = 0; tries < PCIE_D2H_SYNC_WAIT_TRIES; tries++) {
+			/* First verify if the seqnumber has been updated,
+			 * if yes, only then validate the header and trailer.
+			 * Once seqnum, header and trailer have been validated, it means
+			 * that the complete message has arrived.
+			 */
+			valid_msg = FALSE;
+			if (msg->epoch == ring_seqnum &&
+				msg->msg_type == MSG_TYPE_INFO_PYLD &&
+				msg->request_id > 0 &&
+				msg->request_id <= ring->item_len) {
+				/* proceed to check trailer only if header is valid */
+				buf = (volatile uint8 *)msg;
+				msglen = sizeof(cmn_msg_hdr_t) + msg->request_id;
+				buf += msglen;
+				if (msglen + sizeof(cmn_msg_hdr_t) <= ring->item_len) {
+					trailer = (volatile cmn_msg_hdr_t *)buf;
+					valid_msg = (trailer->epoch == ring_seqnum) &&
+						(trailer->msg_type == msg->msg_type) &&
+						(trailer->request_id == msg->request_id);
+					if (!valid_msg) {
+						DHD_TRACE(("%s:invalid trailer! seqnum=%u;reqid=%u"
+						" expected, seqnum=%u; reqid=%u. Retrying... \n",
+						__FUNCTION__, trailer->epoch, trailer->request_id,
+						msg->epoch, msg->request_id));
+					}
+				} else {
+					DHD_TRACE(("%s: invalid payload length (%u)! Retrying.. \n",
+						__FUNCTION__, msg->request_id));
+				}
+
+				if (valid_msg) {
+					/* data is OK */
+					ring->seqnum++; /* next expected sequence number */
+					if (dhd->dhd_induce_error != DHD_INDUCE_LIVELOCK) {
+						goto dma_completed;
+					}
+				}
+			} else {
+				DHD_TRACE(("%s: wrong hdr, seqnum expected %u, got %u."
+					" msg_type=0x%x, request_id=%u."
+					" Retrying...\n",
+					__FUNCTION__, ring_seqnum, msg->epoch,
+					msg->msg_type, msg->request_id));
+			}
+
+			total_tries = ((step-1) * PCIE_D2H_SYNC_WAIT_TRIES) + tries;
+
+			if (total_tries > prot->d2h_sync_wait_max)
+				prot->d2h_sync_wait_max = total_tries;
+
+			OSL_CACHE_INV(msg, msglen); /* invalidate and try again */
+#if !(defined(BCM_ROUTER_DHD) && defined(BCM_GMAC3))
+			OSL_CPU_RELAX(); /* CPU relax for msg_seqnum  value to update */
+			OSL_DELAY(delay * step); /* Add stepper delay */
+#endif /* !(defined(BCM_ROUTER_DHD) && defined(BCM_GMAC3)) */
+
+		} /* for PCIE_D2H_SYNC_WAIT_TRIES */
+	} /* for PCIE_D2H_SYNC_NUM_OF_STEPS */
+
+	DHD_ERROR(("%s: EDL header check fails !\n", __FUNCTION__));
+	DHD_ERROR(("%s: header: seqnum=%u; expected-seqnum=%u"
+		" msgtype=0x%x; expected-msgtype=0x%x"
+		" length=%u; expected-max-length=%u", __FUNCTION__,
+		msg->epoch, ring_seqnum, msg->msg_type, MSG_TYPE_INFO_PYLD,
+		msg->request_id, ring->item_len));
+	dhd_prhex("msg header bytes: ", (volatile uchar *)msg, sizeof(*msg), DHD_ERROR_VAL);
+	if (trailer && msglen > 0 &&
+			(msglen + sizeof(cmn_msg_hdr_t)) <= ring->item_len) {
+		DHD_ERROR(("%s: trailer: seqnum=%u; expected-seqnum=%u"
+			" msgtype=0x%x; expected-msgtype=0x%x"
+			" length=%u; expected-length=%u", __FUNCTION__,
+			trailer->epoch, ring_seqnum, trailer->msg_type, MSG_TYPE_INFO_PYLD,
+			trailer->request_id, msg->request_id));
+		dhd_prhex("msg trailer bytes: ", (volatile uchar *)trailer,
+			sizeof(*trailer), DHD_ERROR_VAL);
+	}
+
+	if ((msglen + sizeof(cmn_msg_hdr_t)) <= ring->item_len)
+		len = msglen + sizeof(cmn_msg_hdr_t);
+	else
+		len = ring->item_len;
+
+	dhd_prot_d2h_sync_livelock(dhd, msg->epoch, ring, total_tries,
+		(volatile uchar *) msg, len);
+
+	ring->seqnum++; /* skip this message */
+	return BCME_ERROR; /* invalid msg_type 0 -> noop callback */
+
+dma_completed:
+	DHD_TRACE(("%s: EDL header check pass, seqnum=%u; reqid=%u\n", __FUNCTION__,
+		msg->epoch, msg->request_id));
+
+	prot->d2h_sync_wait_tot += tries;
+	return BCME_OK;
+}
+
+/**
+ * dhd_prot_d2h_sync_edl_none - Dongle ensure that the DMA will complete and host
+ * need to try to sync. This noop sync handler will be bound when the dongle
+ * advertises that neither the SEQNUM nor XORCSUM mode of DMA sync is required.
+ */
+static int BCMFASTPATH
+(dhd_prot_d2h_sync_edl_none)(dhd_pub_t *dhd, msgbuf_ring_t *ring,
+                       volatile cmn_msg_hdr_t *msg)
+{
+	/* Check for LIVELOCK induce flag, which is set by firing
+	* dhd iovar to induce LIVELOCK error. If flag is set,
+	* MSG_TYPE_INVALID is returned, which results in to LIVELOCK error.
+	*/
+	if (dhd->dhd_induce_error == DHD_INDUCE_LIVELOCK) {
+		DHD_ERROR(("%s: Inducing livelock\n", __FUNCTION__));
+		return BCME_ERROR;
+	} else {
+		if (msg->msg_type == MSG_TYPE_INFO_PYLD)
+			return BCME_OK;
+		else
+			return msg->msg_type;
+	}
+}
+#endif /* EWP_EDL */
+
+INLINE void
+dhd_wakeup_ioctl_event(dhd_pub_t *dhd, dhd_ioctl_recieved_status_t reason)
+{
+	/* To synchronize with the previous memory operations call wmb() */
+	OSL_SMP_WMB();
+	dhd->prot->ioctl_received = reason;
+	/* Call another wmb() to make sure before waking up the other event value gets updated */
+	OSL_SMP_WMB();
+	dhd_os_ioctl_resp_wake(dhd);
+}
+
+/**
+ * dhd_prot_d2h_sync_init - Setup the host side DMA sync mode based on what
+ * dongle advertizes.
+ */
+static void
+dhd_prot_d2h_sync_init(dhd_pub_t *dhd)
+{
+	dhd_prot_t *prot = dhd->prot;
+	prot->d2h_sync_wait_max = 0UL;
+	prot->d2h_sync_wait_tot = 0UL;
+
+	prot->d2hring_ctrl_cpln.seqnum = D2H_EPOCH_INIT_VAL;
+	prot->d2hring_ctrl_cpln.current_phase = BCMPCIE_CMNHDR_PHASE_BIT_INIT;
+
+	prot->d2hring_tx_cpln.seqnum = D2H_EPOCH_INIT_VAL;
+	prot->d2hring_tx_cpln.current_phase = BCMPCIE_CMNHDR_PHASE_BIT_INIT;
+
+	prot->d2hring_rx_cpln.seqnum = D2H_EPOCH_INIT_VAL;
+	prot->d2hring_rx_cpln.current_phase = BCMPCIE_CMNHDR_PHASE_BIT_INIT;
+
+	if (dhd->d2h_sync_mode & PCIE_SHARED_D2H_SYNC_SEQNUM) {
+		prot->d2h_sync_cb = dhd_prot_d2h_sync_seqnum;
+#ifdef EWP_EDL
+		prot->d2h_edl_sync_cb = dhd_prot_d2h_sync_edl;
+#endif /* EWP_EDL */
+		DHD_ERROR(("%s(): D2H sync mechanism is SEQNUM \r\n", __FUNCTION__));
+	} else if (dhd->d2h_sync_mode & PCIE_SHARED_D2H_SYNC_XORCSUM) {
+		prot->d2h_sync_cb = dhd_prot_d2h_sync_xorcsum;
+#ifdef EWP_EDL
+		prot->d2h_edl_sync_cb = dhd_prot_d2h_sync_edl;
+#endif /* EWP_EDL */
+		DHD_ERROR(("%s(): D2H sync mechanism is XORCSUM \r\n", __FUNCTION__));
+	} else {
+		prot->d2h_sync_cb = dhd_prot_d2h_sync_none;
+#ifdef EWP_EDL
+		prot->d2h_edl_sync_cb = dhd_prot_d2h_sync_edl_none;
+#endif /* EWP_EDL */
+		DHD_ERROR(("%s(): D2H sync mechanism is NONE \r\n", __FUNCTION__));
+	}
+}
+
+/**
+ * dhd_prot_h2d_sync_init - Per H2D common ring, setup the msgbuf ring seqnum
+ */
+static void
+dhd_prot_h2d_sync_init(dhd_pub_t *dhd)
+{
+	dhd_prot_t *prot = dhd->prot;
+	prot->h2dring_rxp_subn.seqnum = H2D_EPOCH_INIT_VAL;
+
+	prot->h2dring_rxp_subn.current_phase = 0;
+
+	prot->h2dring_ctrl_subn.seqnum = H2D_EPOCH_INIT_VAL;
+	prot->h2dring_ctrl_subn.current_phase = 0;
+}
+
+/* +-----------------  End of PCIE DHD H2D DMA SYNC ------------------------+ */
+
+/*
+ * +---------------------------------------------------------------------------+
+ * PCIE DMA-able buffer. Sets up a dhd_dma_buf_t object, which includes the
+ * virtual and physical address, the buffer lenght and the DMA handler.
+ * A secdma handler is also included in the dhd_dma_buf object.
+ * +---------------------------------------------------------------------------+
+ */
+
+static INLINE void
+dhd_base_addr_htolpa(sh_addr_t *base_addr, dmaaddr_t pa)
+{
+	base_addr->low_addr = htol32(PHYSADDRLO(pa));
+	base_addr->high_addr = htol32(PHYSADDRHI(pa));
+}
+
+/**
+ * dhd_dma_buf_audit - Any audits on a DHD DMA Buffer.
+ */
+static int
+dhd_dma_buf_audit(dhd_pub_t *dhd, dhd_dma_buf_t *dma_buf)
+{
+	uint32 pa_lowaddr, end; /* dongle uses 32bit ptr arithmetic */
+	ASSERT(dma_buf);
+	pa_lowaddr = PHYSADDRLO(dma_buf->pa);
+	ASSERT(PHYSADDRLO(dma_buf->pa) || PHYSADDRHI(dma_buf->pa));
+	ASSERT(ISALIGNED(pa_lowaddr, DMA_ALIGN_LEN));
+	ASSERT(dma_buf->len != 0);
+
+	/* test 32bit offset arithmetic over dma buffer for loss of carry-over */
+	end = (pa_lowaddr + dma_buf->len); /* end address */
+
+	if ((end & 0xFFFFFFFF) < (pa_lowaddr & 0xFFFFFFFF)) { /* exclude carryover */
+		DHD_ERROR(("%s: dma_buf %x len %d spans dongle 32bit ptr arithmetic\n",
+			__FUNCTION__, pa_lowaddr, dma_buf->len));
+		return BCME_ERROR;
+	}
+
+	return BCME_OK;
+}
+
+/**
+ * dhd_dma_buf_alloc - Allocate a cache coherent DMA-able buffer.
+ * returns BCME_OK=0 on success
+ * returns non-zero negative error value on failure.
+ */
+int
+dhd_dma_buf_alloc(dhd_pub_t *dhd, dhd_dma_buf_t *dma_buf, uint32 buf_len)
+{
+	uint32 dma_pad = 0;
+	osl_t *osh = dhd->osh;
+	uint16 dma_align = DMA_ALIGN_LEN;
+	uint32 rem = 0;
+
+	ASSERT(dma_buf != NULL);
+	ASSERT(dma_buf->va == NULL);
+	ASSERT(dma_buf->len == 0);
+
+	/* Pad the buffer length to align to cacheline size. */
+	rem = (buf_len % DHD_DMA_PAD);
+	dma_pad = rem ? (DHD_DMA_PAD - rem) : 0;
+
+	dma_buf->va = DMA_ALLOC_CONSISTENT(osh, buf_len + dma_pad,
+		dma_align, &dma_buf->_alloced, &dma_buf->pa, &dma_buf->dmah);
+
+	if (dma_buf->va == NULL) {
+		DHD_ERROR(("%s: buf_len %d, no memory available\n",
+			__FUNCTION__, buf_len));
+		return BCME_NOMEM;
+	}
+
+	dma_buf->len = buf_len; /* not including padded len */
+
+	if (dhd_dma_buf_audit(dhd, dma_buf) != BCME_OK) { /* audit dma buf */
+		dhd_dma_buf_free(dhd, dma_buf);
+		return BCME_ERROR;
+	}
+
+	dhd_dma_buf_reset(dhd, dma_buf); /* zero out and cache flush */
+
+	return BCME_OK;
+}
+
+/**
+ * dhd_dma_buf_reset - Reset a cache coherent DMA-able buffer.
+ */
+static void
+dhd_dma_buf_reset(dhd_pub_t *dhd, dhd_dma_buf_t *dma_buf)
+{
+	if ((dma_buf == NULL) || (dma_buf->va == NULL))
+		return;
+
+	(void)dhd_dma_buf_audit(dhd, dma_buf);
+
+	/* Zero out the entire buffer and cache flush */
+	memset((void*)dma_buf->va, 0, dma_buf->len);
+	OSL_CACHE_FLUSH((void *)dma_buf->va, dma_buf->len);
+}
+
+void
+dhd_local_buf_reset(char *buf, uint32 len)
+{
+	/* Zero out the entire buffer and cache flush */
+	memset((void*)buf, 0, len);
+	OSL_CACHE_FLUSH((void *)buf, len);
+}
+
+/**
+ * dhd_dma_buf_free - Free a DMA-able buffer that was previously allocated using
+ * dhd_dma_buf_alloc().
+ */
+void
+dhd_dma_buf_free(dhd_pub_t *dhd, dhd_dma_buf_t *dma_buf)
+{
+	osl_t *osh = dhd->osh;
+
+	ASSERT(dma_buf);
+
+	if (dma_buf->va == NULL)
+		return; /* Allow for free invocation, when alloc failed */
+
+	/* DEBUG: dhd_dma_buf_reset(dhd, dma_buf) */
+	(void)dhd_dma_buf_audit(dhd, dma_buf);
+
+	/* dma buffer may have been padded at allocation */
+	DMA_FREE_CONSISTENT(osh, dma_buf->va, dma_buf->_alloced,
+		dma_buf->pa, dma_buf->dmah);
+
+	memset(dma_buf, 0, sizeof(dhd_dma_buf_t));
+}
+
+/**
+ * dhd_dma_buf_init - Initialize a dhd_dma_buf with speicifed values.
+ * Do not use dhd_dma_buf_init to zero out a dhd_dma_buf_t object. Use memset 0.
+ */
+void
+dhd_dma_buf_init(dhd_pub_t *dhd, void *dhd_dma_buf,
+	void *va, uint32 len, dmaaddr_t pa, void *dmah, void *secdma)
+{
+	dhd_dma_buf_t *dma_buf;
+	ASSERT(dhd_dma_buf);
+	dma_buf = (dhd_dma_buf_t *)dhd_dma_buf;
+	dma_buf->va = va;
+	dma_buf->len = len;
+	dma_buf->pa = pa;
+	dma_buf->dmah = dmah;
+	dma_buf->secdma = secdma;
+
+	/* Audit user defined configuration */
+	(void)dhd_dma_buf_audit(dhd, dma_buf);
+}
+
+/* +------------------  End of PCIE DHD DMA BUF ADT ------------------------+ */
+
+/*
+ * +---------------------------------------------------------------------------+
+ * DHD_MAP_PKTID_LOGGING
+ * Logging the PKTID and DMA map/unmap information for the SMMU fault issue
+ * debugging in customer platform.
+ * +---------------------------------------------------------------------------+
+ */
+
+#ifdef DHD_MAP_PKTID_LOGGING
+typedef struct dhd_pktid_log_item {
+	dmaaddr_t pa;		/* DMA bus address */
+	uint64 ts_nsec;		/* Timestamp: nsec */
+	uint32 size;		/* DMA map/unmap size */
+	uint32 pktid;		/* Packet ID */
+	uint8 pkttype;		/* Packet Type */
+	uint8 rsvd[7];		/* Reserved for future use */
+} dhd_pktid_log_item_t;
+
+typedef struct dhd_pktid_log {
+	uint32 items;		/* number of total items */
+	uint32 index;		/* index of pktid_log_item */
+	dhd_pktid_log_item_t map[0];	/* metadata storage */
+} dhd_pktid_log_t;
+
+typedef void * dhd_pktid_log_handle_t; /* opaque handle to pktid log */
+
+#define	MAX_PKTID_LOG				(2048u)
+/*
+ * index timestamp pktaddr(pa) pktid size
+ * index(5) + timestamp (<= 20) + dummy(4) + pa (<=11) + pktid (10) + size(7) +
+ * pkttype(7) + space(6) + null/lf(2)
+ * ex) 1367          78348654722      0xabbe69040       3317    1920       1
+ */
+#define PKTID_LOG_STR_SZ			72u
+#define MAX_PKTID_LOG_BUF_SZ			MAX_PKTID_LOG * PKTID_LOG_STR_SZ + \
+	strlen(PKTID_LOG_DUMP_FMT)
+#define DHD_PKTID_LOG_ITEM_SZ			(sizeof(dhd_pktid_log_item_t))
+#define DHD_PKTID_LOG_SZ(items)			(uint32)((sizeof(dhd_pktid_log_t)) + \
+					((DHD_PKTID_LOG_ITEM_SZ) * (items)))
+
+#define DHD_PKTID_LOG_INIT(dhd, hdl)		dhd_pktid_logging_init((dhd), (hdl))
+#define DHD_PKTID_LOG_FINI(dhd, hdl)		dhd_pktid_logging_fini((dhd), (hdl))
+#define DHD_PKTID_LOG(dhd, hdl, pa, pktid, len, pkttype)	\
+	dhd_pktid_logging((dhd), (hdl), (pa), (pktid), (len), (pkttype))
+#ifndef DHD_IGNORE_PKTID_AUDIT_ERROR
+#define DHD_PKTID_LOG_DUMP(dhd)			dhd_pktid_logging_dump((dhd))
+#else
+#define DHD_PKTID_LOG_DUMP(dhd)
+#endif /* DHD_IGNORE_PKTID_AUDIT_ERROR */
+
+static dhd_pktid_log_handle_t *
+dhd_pktid_logging_init(dhd_pub_t *dhd, uint32 num_items)
+{
+	dhd_pktid_log_t *log;
+	uint32 log_size;
+
+	log_size = DHD_PKTID_LOG_SZ(num_items);
+	log = (dhd_pktid_log_t *)KVMALLOCZ(dhd->osh, log_size);
+	if (log == NULL) {
+		DHD_ERROR(("%s: KVMALLOC failed for size %d\n",
+			__FUNCTION__, log_size));
+		return (dhd_pktid_log_handle_t *)NULL;
+	}
+
+	log->items = num_items;
+	log->index = 0;
+
+	return (dhd_pktid_log_handle_t *)log; /* opaque handle */
+}
+
+static void
+dhd_pktid_logging_fini(dhd_pub_t *dhd, dhd_pktid_log_handle_t *handle)
+{
+	dhd_pktid_log_t *log;
+	uint32 log_size;
+
+	if (handle == NULL) {
+		DHD_ERROR(("%s: handle is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	log = (dhd_pktid_log_t *)handle;
+	log_size = DHD_PKTID_LOG_SZ(log->items);
+	KVMFREE(dhd->osh, handle, log_size);
+}
+
+static void
+dhd_pktid_logging(dhd_pub_t *dhd, dhd_pktid_log_handle_t *handle, dmaaddr_t pa,
+	uint32 pktid, uint32 len, uint8 pkttype)
+{
+	dhd_pktid_log_t *log;
+	uint32 idx;
+
+	if (handle == NULL) {
+		DHD_ERROR(("%s: handle is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	log = (dhd_pktid_log_t *)handle;
+	idx = log->index;
+	log->map[idx].ts_nsec = OSL_LOCALTIME_NS();
+	log->map[idx].pa = pa;
+	log->map[idx].pktid = pktid;
+	log->map[idx].size = len;
+	log->map[idx].pkttype = pkttype;
+	log->index = (idx + 1) % (log->items);	/* update index */
+}
+
+void
+dhd_pktid_logging_dump(dhd_pub_t *dhd)
+{
+	dhd_prot_t *prot = dhd->prot;
+	dhd_pktid_log_t *map_log, *unmap_log;
+	uint64 ts_sec, ts_usec;
+
+	if (prot == NULL) {
+		DHD_ERROR(("%s: prot is NULL\n", __FUNCTION__));
+		return;
+	}
+
+	dhd->enable_pktid_log_dump = TRUE;
+
+	map_log = (dhd_pktid_log_t *)(prot->pktid_dma_map);
+	unmap_log = (dhd_pktid_log_t *)(prot->pktid_dma_unmap);
+	OSL_GET_LOCALTIME(&ts_sec, &ts_usec);
+	if (map_log && unmap_log) {
+		DHD_ERROR(("%s: map_log(%s), unmap_log(%s)\n", __FUNCTION__,
+			is_vmalloc_addr(map_log) ? "vmalloc" : "kmalloc",
+			is_vmalloc_addr(unmap_log) ? "vmalloc" : "kmalloc"));
+		DHD_ERROR(("%s: map_idx=%d unmap_idx=%d "
+			"current time=[%5lu.%06lu]\n", __FUNCTION__,
+			map_log->index, unmap_log->index,
+			(unsigned long)ts_sec, (unsigned long)ts_usec));
+		DHD_ERROR(("%s: pktid_map_log(pa)=0x%llx size=%d, "
+			"pktid_unmap_log(pa)=0x%llx size=%d\n", __FUNCTION__,
+			(uint64)__virt_to_phys((ulong)(map_log->map)),
+			(uint32)(DHD_PKTID_LOG_ITEM_SZ * map_log->items),
+			(uint64)__virt_to_phys((ulong)(unmap_log->map)),
+			(uint32)(DHD_PKTID_LOG_ITEM_SZ * unmap_log->items)));
+	}
+}
+
+uint32
+dhd_pktid_buf_len(dhd_pub_t *dhd, bool is_map)
+{
+	dhd_prot_t *prot = dhd->prot;
+	dhd_pktid_log_t *pktlog_buf;
+	uint32 len = 0;
+
+	if (is_map == TRUE) {
+		pktlog_buf = (dhd_pktid_log_t *)(prot->pktid_dma_map);
+		len += strlen(DHD_PKTID_MAP_LOG_HDR);
+	} else {
+		pktlog_buf = (dhd_pktid_log_t *)(prot->pktid_dma_unmap);
+		len += strlen(DHD_PKTID_UNMAP_LOG_HDR);
+	}
+
+	if (!pktlog_buf) {
+		return 0; /* len should be 0. */
+	}
+
+	/* Adding Format string + LineFeed */
+	len += strlen(PKTID_LOG_DUMP_FMT) + 2;
+	len += (uint32)PKTID_LOG_STR_SZ * pktlog_buf->items;
+
+	return len;
+}
+
+int
+dhd_write_pktid_log_dump(dhd_pub_t *dhdp, const void *user_buf,
+	void *fp, uint32 len, unsigned long *pos, bool is_map)
+{
+	dhd_prot_t *prot = dhdp->prot;
+	dhd_pktid_log_t *log_buf;
+	log_dump_section_hdr_t sec_hdr;
+	char *buf;
+	uint32 buflen = 0, remain_len = 0;
+	unsigned long long addr = 0;
+	int i = 0;
+	int ret = BCME_OK;
+
+	if (prot == NULL) {
+		DHD_ERROR(("%s: prot is NULL\n", __FUNCTION__));
+		return BCME_ERROR;
+	}
+
+	buf = (char *)VMALLOCZ(dhdp->osh, MAX_PKTID_LOG_BUF_SZ);
+	if (!buf) {
+		DHD_ERROR(("%s: buf alloc fails!\n", __FUNCTION__));
+		return BCME_NOMEM;
+	}
+	remain_len = buflen = MAX_PKTID_LOG_BUF_SZ;
+
+	dhd_init_sec_hdr(&sec_hdr);
+	sec_hdr.magic = LOG_DUMP_MAGIC;
+
+	if (is_map) {
+		log_buf = prot->pktid_dma_map;
+		ret = dhd_export_debug_data(DHD_PKTID_MAP_LOG_HDR, fp, user_buf,
+			strlen(DHD_PKTID_MAP_LOG_HDR), pos);
+		if (ret < 0) {
+			DHD_ERROR(("%s :  PKTID_MAP_LOG_HDR write error\n",
+				__FUNCTION__));
+			goto exit;
+		}
+		sec_hdr.type = LOG_DUMP_SECTION_PKTID_MAP_LOG;
+	} else {
+		log_buf = prot->pktid_dma_unmap;
+		ret = dhd_export_debug_data(DHD_PKTID_UNMAP_LOG_HDR, fp, user_buf,
+			strlen(DHD_PKTID_UNMAP_LOG_HDR), pos);
+		if (ret < 0) {
+			DHD_ERROR(("%s :  PKTID_UNMAP_LOG_HDR write error\n",
+				__FUNCTION__));
+			goto exit;
+		}
+		sec_hdr.type = LOG_DUMP_SECTION_PKTID_UNMAP_LOG;
+	}
+
+	remain_len -= scnprintf(&buf[buflen - remain_len], remain_len,
+			PKTID_LOG_DUMP_FMT, log_buf->index);
+
+	for (i = 0; i < log_buf->items; i++) {
+#ifdef BCMDMA64OSL
+		PHYSADDRTOULONG(log_buf->map[i].pa, addr);
+#else
+		addr = PHYSADDRLO(log_buf->map[i].pa);
+#endif /* BCMDMA64OSL */
+		remain_len -= scnprintf(&buf[buflen - remain_len], remain_len,
+			"%5u %20llu %4s 0x%llx %10u %7u %7u\n",
+			i, log_buf->map[i].ts_nsec, " ", addr,
+			log_buf->map[i].pktid, log_buf->map[i].size,
+			log_buf->map[i].pkttype);
+	}
+	remain_len -= scnprintf(&buf[buflen - remain_len], remain_len, "\n");
+
+	sec_hdr.timestamp = local_clock();
+	sec_hdr.length = buflen - remain_len;
+
+	ret = dhd_export_debug_data((char *)&sec_hdr, NULL, user_buf, sizeof(sec_hdr), pos);
+	ret = dhd_export_debug_data(buf, NULL, user_buf, sec_hdr.length, pos);
+
+exit:
+	if (buf) {
+		VMFREE(dhdp->osh, buf, buflen);
+	}
+
+	return ret;
+}
+#endif /* DHD_MAP_PKTID_LOGGING */
+
+/* +-----------------  End of DHD_MAP_PKTID_LOGGING -----------------------+ */
+
+/*
+ * +---------------------------------------------------------------------------+
+ * PktId Map: Provides a native packet pointer to unique 32bit PktId mapping.
+ * Main purpose is to save memory on the dongle, has other purposes as well.
+ * The packet id map, also includes storage for some packet parameters that
+ * may be saved. A native packet pointer along with the parameters may be saved
+ * and a unique 32bit pkt id will be returned. Later, the saved packet pointer
+ * and the metadata may be retrieved using the previously allocated packet id.
+ * +---------------------------------------------------------------------------+
+ */
+#define DHD_PCIE_PKTID
+
+/* On Router, the pktptr serves as a pktid. */
+#if defined(BCM_ROUTER_DHD) && !defined(BCA_HNDROUTER)
+#undef DHD_PCIE_PKTID		/* Comment this undef, to reenable PKTIDMAP */
+#endif /* BCM_ROUTER_DHD && !BCA_HNDROUTER */
+
+#if defined(BCM_ROUTER_DHD) && defined(DHD_PCIE_PKTID)
+#undef MAX_TX_PKTID
+#define MAX_TX_PKTID     ((36 * 1024) - 1) /* Extend for 64 clients support. */
+#endif /* BCM_ROUTER_DHD && DHD_PCIE_PKTID */
+
+/* XXX: PROP_TXSTATUS: WLFS defines a private pkttag layout.
+ * Hence cannot store the dma parameters in the pkttag and the pktidmap locker
+ * is required.
+ */
+#if defined(PROP_TXSTATUS) && !defined(DHD_PCIE_PKTID)
+#error "PKTIDMAP must be supported with PROP_TXSTATUS/WLFC"
+#endif
+
+/* Enum for marking the buffer color based on usage */
+typedef enum dhd_pkttype {
+	PKTTYPE_DATA_TX = 0,
+	PKTTYPE_DATA_RX,
+	PKTTYPE_IOCTL_RX,
+	PKTTYPE_EVENT_RX,
+	PKTTYPE_INFO_RX,
+	/* dhd_prot_pkt_free no check, if pktid reserved and no space avail case */
+	PKTTYPE_NO_CHECK,
+	PKTTYPE_TSBUF_RX
+} dhd_pkttype_t;
+
+#define DHD_PKTID_MIN_AVAIL_COUNT		512U
+#define DHD_PKTID_DEPLETED_MAX_COUNT		(DHD_PKTID_MIN_AVAIL_COUNT * 2U)
+#define DHD_PKTID_INVALID			(0U)
+#define DHD_IOCTL_REQ_PKTID			(0xFFFE)
+#define DHD_FAKE_PKTID				(0xFACE)
+#define DHD_H2D_DBGRING_REQ_PKTID		0xFFFD
+#define DHD_D2H_DBGRING_REQ_PKTID		0xFFFC
+#define DHD_H2D_HOSTTS_REQ_PKTID		0xFFFB
+#define DHD_H2D_BTLOGRING_REQ_PKTID		0xFFFA
+#define DHD_D2H_BTLOGRING_REQ_PKTID		0xFFF9
+#define DHD_H2D_SNAPSHOT_UPLOAD_REQ_PKTID	0xFFF8
+#define DHD_D2H_MDRING_REQ_PKTID		0xFFF8
+
+#define IS_FLOWRING(ring) \
+	((strncmp(ring->name, "h2dflr", sizeof("h2dflr"))) == (0))
+
+typedef void * dhd_pktid_map_handle_t; /* opaque handle to a pktid map */
+
+/* Construct a packet id mapping table, returning an opaque map handle */
+static dhd_pktid_map_handle_t *dhd_pktid_map_init(dhd_pub_t *dhd, uint32 num_items);
+
+/* Destroy a packet id mapping table, freeing all packets active in the table */
+static void dhd_pktid_map_fini(dhd_pub_t *dhd, dhd_pktid_map_handle_t *map);
+
+#define DHD_NATIVE_TO_PKTID_INIT(dhd, items) dhd_pktid_map_init((dhd), (items))
+#define DHD_NATIVE_TO_PKTID_RESET(dhd, map)  dhd_pktid_map_reset((dhd), (map))
+#define DHD_NATIVE_TO_PKTID_FINI(dhd, map)   dhd_pktid_map_fini((dhd), (map))
+#define DHD_NATIVE_TO_PKTID_FINI_IOCTL(osh, map)  dhd_pktid_map_fini_ioctl((osh), (map))
+
+#if defined(DHD_PCIE_PKTID)
+#if defined(NDIS)
+/* XXX: for NDIS, using consistent memory instead of buffer from PKTGET for
+ * up to 8K ioctl response
+ */
+#define IOCTLRESP_USE_CONSTMEM
+static void free_ioctl_return_buffer(dhd_pub_t *dhd, dhd_dma_buf_t *retbuf);
+static int  alloc_ioctl_return_buffer(dhd_pub_t *dhd, dhd_dma_buf_t *retbuf);
+#endif
+
+/* Determine number of pktids that are available */
+static INLINE uint32 dhd_pktid_map_avail_cnt(dhd_pktid_map_handle_t *handle);
+
+/* Allocate a unique pktid against which a pkt and some metadata is saved */
+static INLINE uint32 dhd_pktid_map_reserve(dhd_pub_t *dhd, dhd_pktid_map_handle_t *handle,
+	void *pkt, dhd_pkttype_t pkttype);
+static INLINE void dhd_pktid_map_save(dhd_pub_t *dhd, dhd_pktid_map_handle_t *handle,
+	void *pkt, uint32 nkey, dmaaddr_t pa, uint32 len, uint8 dma,
+	void *dmah, void *secdma, dhd_pkttype_t pkttype);
+static uint32 dhd_pktid_map_alloc(dhd_pub_t *dhd, dhd_pktid_map_handle_t *map,
+	void *pkt, dmaaddr_t pa, uint32 len, uint8 dma,
+	void *dmah, void *secdma, dhd_pkttype_t pkttype);
+
+/* Return an allocated pktid, retrieving previously saved pkt and metadata */
+static void *dhd_pktid_map_free(dhd_pub_t *dhd, dhd_pktid_map_handle_t *map,
+	uint32 id, dmaaddr_t *pa, uint32 *len, void **dmah,
+	void **secdma, dhd_pkttype_t pkttype, bool rsv_locker);
+
+/* Metadata d2h completion ring linking/unlink ring types */
+typedef enum dhd_mdata_linked_ring_idx {
+	DHD_METADATA_NO_RING = 0,
+	DHD_METADATA_D2H_TXCPL,
+	DHD_METADATA_D2H_RXCPL,
+	DHD_METADATA_D2H_HP2PTX,
+	DHD_METADATA_D2H_HP2PRX
+} dhd_mdata_linked_ring_idx_t;
+
+/*
+ * DHD_PKTID_AUDIT_ENABLED: Audit of PktIds in DHD for duplicate alloc and frees
+ *
+ * DHD_PKTID_AUDIT_MAP: Audit the LIFO or FIFO PktIdMap allocator
+ * DHD_PKTID_AUDIT_RING: Audit the pktid during producer/consumer ring operation
+ *
+ * CAUTION: When DHD_PKTID_AUDIT_ENABLED is defined,
+ *    either DHD_PKTID_AUDIT_MAP or DHD_PKTID_AUDIT_RING may be selected.
+ */
+#if defined(DHD_PKTID_AUDIT_ENABLED)
+#define USE_DHD_PKTID_AUDIT_LOCK 1
+/* Audit the pktidmap allocator */
+/* #define DHD_PKTID_AUDIT_MAP */
+
+/* Audit the pktid during production/consumption of workitems */
+#define DHD_PKTID_AUDIT_RING
+
+#if defined(DHD_PKTID_AUDIT_MAP) && defined(DHD_PKTID_AUDIT_RING)
+#error "May only enabled audit of MAP or RING, at a time."
+#endif /* DHD_PKTID_AUDIT_MAP && DHD_PKTID_AUDIT_RING */
+
+#define DHD_DUPLICATE_ALLOC     1
+#define DHD_DUPLICATE_FREE      2
+#define DHD_TEST_IS_ALLOC       3
+#define DHD_TEST_IS_FREE        4
+
+typedef enum dhd_pktid_map_type {
+	DHD_PKTID_MAP_TYPE_CTRL = 1,
+	DHD_PKTID_MAP_TYPE_TX,
+	DHD_PKTID_MAP_TYPE_RX,
+	DHD_PKTID_MAP_TYPE_UNKNOWN
+} dhd_pktid_map_type_t;
+
+#ifdef USE_DHD_PKTID_AUDIT_LOCK
+#define DHD_PKTID_AUDIT_LOCK_INIT(osh)          osl_spin_lock_init(osh)
+#define DHD_PKTID_AUDIT_LOCK_DEINIT(osh, lock)  osl_spin_lock_deinit(osh, lock)
+#define DHD_PKTID_AUDIT_LOCK(lock)              osl_spin_lock(lock)
+#define DHD_PKTID_AUDIT_UNLOCK(lock, flags)     osl_spin_unlock(lock, flags)
+#else
+#define DHD_PKTID_AUDIT_LOCK_INIT(osh)          (void *)(1)
+#define DHD_PKTID_AUDIT_LOCK_DEINIT(osh, lock)  do { /* noop */ } while (0)
+#define DHD_PKTID_AUDIT_LOCK(lock)              0
+#define DHD_PKTID_AUDIT_UNLOCK(lock, flags)     do { /* noop */ } while (0)
+#endif /* !USE_DHD_PKTID_AUDIT_LOCK */
+
+#endif /* DHD_PKTID_AUDIT_ENABLED */
+
+#define USE_DHD_PKTID_LOCK   1
+
+#ifdef USE_DHD_PKTID_LOCK
+#define DHD_PKTID_LOCK_INIT(osh)                osl_spin_lock_init(osh)
+#define DHD_PKTID_LOCK_DEINIT(osh, lock)        osl_spin_lock_deinit(osh, lock)
+#define DHD_PKTID_LOCK(lock, flags)             (flags) = osl_spin_lock(lock)
+#define DHD_PKTID_UNLOCK(lock, flags)           osl_spin_unlock(lock, flags)
+#else
+#define DHD_PKTID_LOCK_INIT(osh)                (void *)(1)
+#define DHD_PKTID_LOCK_DEINIT(osh, lock)	\
+	do { \
+		BCM_REFERENCE(osh); \
+		BCM_REFERENCE(lock); \
+	} while (0)
+#define DHD_PKTID_LOCK(lock)                    0
+#define DHD_PKTID_UNLOCK(lock, flags)           \
+	do { \
+		BCM_REFERENCE(lock); \
+		BCM_REFERENCE(flags); \
+	} while (0)
+#endif /* !USE_DHD_PKTID_LOCK */
+
+typedef enum dhd_locker_state {
+	LOCKER_IS_FREE,
+	LOCKER_IS_BUSY,
+	LOCKER_IS_RSVD
+} dhd_locker_state_t;
+
+/* Packet metadata saved in packet id mapper */
+
+typedef struct dhd_pktid_item {
+	dhd_locker_state_t state;  /* tag a locker to be free, busy or reserved */
+	uint8       dir;      /* dma map direction (Tx=flush or Rx=invalidate) */
+	dhd_pkttype_t pkttype; /* pktlists are maintained based on pkttype */
+	uint16      len;      /* length of mapped packet's buffer */
+	void        *pkt;     /* opaque native pointer to a packet */
+	dmaaddr_t   pa;       /* physical address of mapped packet's buffer */
+	void        *dmah;    /* handle to OS specific DMA map */
+	void		*secdma;
+} dhd_pktid_item_t;
+
+typedef uint32 dhd_pktid_key_t;
+
+typedef struct dhd_pktid_map {
+	uint32      items;    /* total items in map */
+	uint32      avail;    /* total available items */
+	int         failures; /* lockers unavailable count */
+	/* Spinlock to protect dhd_pktid_map in process/tasklet context */
+	void        *pktid_lock; /* Used when USE_DHD_PKTID_LOCK is defined */
+
+#if defined(DHD_PKTID_AUDIT_ENABLED)
+	void		*pktid_audit_lock;
+	struct bcm_mwbmap *pktid_audit; /* multi word bitmap based audit */
+#endif /* DHD_PKTID_AUDIT_ENABLED */
+	dhd_pktid_key_t	*keys; /* map_items +1 unique pkt ids */
+	dhd_pktid_item_t lockers[0];           /* metadata storage */
+} dhd_pktid_map_t;
+
+/*
+ * PktId (Locker) #0 is never allocated and is considered invalid.
+ *
+ * On request for a pktid, a value DHD_PKTID_INVALID must be treated as a
+ * depleted pktid pool and must not be used by the caller.
+ *
+ * Likewise, a caller must never free a pktid of value DHD_PKTID_INVALID.
+ */
+
+#define DHD_PKTID_FREE_LOCKER           (FALSE)
+#define DHD_PKTID_RSV_LOCKER            (TRUE)
+
+#define DHD_PKTID_ITEM_SZ               (sizeof(dhd_pktid_item_t))
+#define DHD_PKIDMAP_ITEMS(items)        (items)
+#define DHD_PKTID_MAP_SZ(items)         (sizeof(dhd_pktid_map_t) + \
+	                                     (DHD_PKTID_ITEM_SZ * ((items) + 1)))
+#define DHD_PKTIDMAP_KEYS_SZ(items)     (sizeof(dhd_pktid_key_t) * ((items) + 1))
+
+#define DHD_NATIVE_TO_PKTID_RESET_IOCTL(dhd, map)  dhd_pktid_map_reset_ioctl((dhd), (map))
+
+/* Convert a packet to a pktid, and save pkt pointer in busy locker */
+#define DHD_NATIVE_TO_PKTID_RSV(dhd, map, pkt, pkttype)    \
+	dhd_pktid_map_reserve((dhd), (map), (pkt), (pkttype))
+/* Reuse a previously reserved locker to save packet params */
+#define DHD_NATIVE_TO_PKTID_SAVE(dhd, map, pkt, nkey, pa, len, dir, dmah, secdma, pkttype) \
+	dhd_pktid_map_save((dhd), (map), (void *)(pkt), (nkey), (pa), (uint32)(len), \
+		(uint8)(dir), (void *)(dmah), (void *)(secdma), \
+		(dhd_pkttype_t)(pkttype))
+/* Convert a packet to a pktid, and save packet params in locker */
+#define DHD_NATIVE_TO_PKTID(dhd, map, pkt, pa, len, dir, dmah, secdma, pkttype) \
+	dhd_pktid_map_alloc((dhd), (map), (void *)(pkt), (pa), (uint32)(len), \
+		(uint8)(dir), (void *)(dmah), (void *)(secdma), \
+		(dhd_pkttype_t)(pkttype))
+
+/* Convert pktid to a packet, and free the locker */
+#define DHD_PKTID_TO_NATIVE(dhd, map, pktid, pa, len, dmah, secdma, pkttype) \
+	dhd_pktid_map_free((dhd), (map), (uint32)(pktid), \
+		(dmaaddr_t *)&(pa), (uint32 *)&(len), (void **)&(dmah), \
+		(void **)&(secdma), (dhd_pkttype_t)(pkttype), DHD_PKTID_FREE_LOCKER)
+
+/* Convert the pktid to a packet, empty locker, but keep it reserved */
+#define DHD_PKTID_TO_NATIVE_RSV(dhd, map, pktid, pa, len, dmah, secdma, pkttype) \
+	dhd_pktid_map_free((dhd), (map), (uint32)(pktid), \
+	                   (dmaaddr_t *)&(pa), (uint32 *)&(len), (void **)&(dmah), \
+	                   (void **)&(secdma), (dhd_pkttype_t)(pkttype), DHD_PKTID_RSV_LOCKER)
+
+#define DHD_PKTID_AVAIL(map)                 dhd_pktid_map_avail_cnt(map)
+
+#if defined(DHD_PKTID_AUDIT_ENABLED)
+
+#ifndef DHD_IGNORE_PKTID_AUDIT_ERROR
+#define DHD_PKTID_ERROR_HANDLER(dhdp)	dhd_pktid_error_handler((dhdp))
+#else
+#define DHD_PKTID_ERROR_HANDLER(dhdp)
+#endif /* DHD_IGNORE_PKTID_AUDIT_ERROR */
+
+static int
+dhd_get_pktid_map_type(dhd_pub_t *dhd, dhd_pktid_map_t *pktid_map)
+{
+	dhd_prot_t *prot = dhd->prot;
+	int pktid_map_type;
+
+	if (pktid_map == prot->pktid_ctrl_map) {
+		pktid_map_type = DHD_PKTID_MAP_TYPE_CTRL;
+	} else if (pktid_map == prot->pktid_tx_map) {
+		pktid_map_type = DHD_PKTID_MAP_TYPE_TX;
+	} else if (pktid_map == prot->pktid_rx_map) {
+		pktid_map_type = DHD_PKTID_MAP_TYPE_RX;
+	} else {
+		pktid_map_type = DHD_PKTID_MAP_TYPE_UNKNOWN;
+	}
+
+	return pktid_map_type;
+}
+
+/**
+* __dhd_pktid_audit - Use the mwbmap to audit validity of a pktid.
+*/
+static int
+__dhd_pktid_audit(dhd_pub_t *dhd, dhd_pktid_map_t *pktid_map, uint32 pktid,
+	const int test_for, const char *errmsg)
+{
+#define DHD_PKT_AUDIT_STR "ERROR: %16s Host PktId Audit: "
+	struct bcm_mwbmap *handle;
+	uint32	flags;
+	bool ignore_audit;
+	int error = BCME_OK;
+
+	if (pktid_map == (dhd_pktid_map_t *)NULL) {
+		DHD_ERROR((DHD_PKT_AUDIT_STR "Pkt id map NULL\n", errmsg));
+		return BCME_OK;
+	}
+
+	flags = DHD_PKTID_AUDIT_LOCK(pktid_map->pktid_audit_lock);
+
+	handle = pktid_map->pktid_audit;
+	if (handle == (struct bcm_mwbmap *)NULL) {
+		DHD_ERROR((DHD_PKT_AUDIT_STR "Handle NULL\n", errmsg));
+		goto out;
+	}
+
+	/* Exclude special pktids from audit */
+	ignore_audit = (pktid == DHD_IOCTL_REQ_PKTID) | (pktid == DHD_FAKE_PKTID);
+	if (ignore_audit) {
+		goto out;
+	}
+
+	if ((pktid == DHD_PKTID_INVALID) || (pktid > pktid_map->items)) {
+		DHD_ERROR((DHD_PKT_AUDIT_STR "PktId<%d> invalid\n", errmsg, pktid));
+		error = BCME_ERROR;
+		goto out;
+	}
+
+	/* Perform audit */
+	switch (test_for) {
+		case DHD_DUPLICATE_ALLOC:
+			if (!bcm_mwbmap_isfree(handle, pktid)) {
+				DHD_ERROR((DHD_PKT_AUDIT_STR "PktId<%d> alloc duplicate\n",
+				           errmsg, pktid));
+				error = BCME_ERROR;
+			} else {
+				bcm_mwbmap_force(handle, pktid);
+			}
+			break;
+
+		case DHD_DUPLICATE_FREE:
+			if (bcm_mwbmap_isfree(handle, pktid)) {
+				DHD_ERROR((DHD_PKT_AUDIT_STR "PktId<%d> free duplicate\n",
+				           errmsg, pktid));
+				error = BCME_ERROR;
+			} else {
+				bcm_mwbmap_free(handle, pktid);
+			}
+			break;
+
+		case DHD_TEST_IS_ALLOC:
+			if (bcm_mwbmap_isfree(handle, pktid)) {
+				DHD_ERROR((DHD_PKT_AUDIT_STR "PktId<%d> is not allocated\n",
+				           errmsg, pktid));
+				error = BCME_ERROR;
+			}
+			break;
+
+		case DHD_TEST_IS_FREE:
+			if (!bcm_mwbmap_isfree(handle, pktid)) {
+				DHD_ERROR((DHD_PKT_AUDIT_STR "PktId<%d> is not free",
+				           errmsg, pktid));
+				error = BCME_ERROR;
+			}
+			break;
+
+		default:
+			DHD_ERROR(("%s: Invalid test case: %d\n", __FUNCTION__, test_for));
+			error = BCME_ERROR;
+			break;
+	}
+
+out:
+	DHD_PKTID_AUDIT_UNLOCK(pktid_map->pktid_audit_lock, flags);
+
+	if (error != BCME_OK) {
+#ifndef DHD_IGNORE_PKTID_AUDIT_ERROR
+		dhd->pktid_audit_failed = TRUE;
+#endif /* !DHD_IGNORE_PKTID_AUDIT_ERROR */
+	}
+
+	return error;
+}
+
+static int
+dhd_pktid_audit(dhd_pub_t *dhdp, dhd_pktid_map_t *pktid_map, uint32 pktid,
+	const int test_for, const char *errmsg)
+{
+	int ret = BCME_OK;
+	ret = __dhd_pktid_audit(dhdp, pktid_map, pktid, test_for, errmsg);
+	if (ret == BCME_ERROR) {
+		DHD_ERROR(("%s: Got Pkt Id Audit failure: PKTID<%d> PKTID MAP TYPE<%d>\n",
+			__FUNCTION__, pktid, dhd_get_pktid_map_type(dhdp, pktid_map)));
+		DHD_PKTID_ERROR_HANDLER(dhdp);
+#ifdef DHD_MAP_PKTID_LOGGING
+		DHD_PKTID_LOG_DUMP(dhdp);
+#endif /* DHD_MAP_PKTID_LOGGING */
+	}
+
+	return ret;
+}
+
+#define DHD_PKTID_AUDIT(dhdp, map, pktid, test_for) \
+	dhd_pktid_audit((dhdp), (dhd_pktid_map_t *)(map), (pktid), (test_for), __FUNCTION__)
+
+static int
+dhd_pktid_audit_ring_debug(dhd_pub_t *dhdp, dhd_pktid_map_t *map, uint32 pktid,
+	const int test_for, void *msg, uint32 msg_len, const char *func)
+{
+	int ret = BCME_OK;
+
+	if (dhd_query_bus_erros(dhdp)) {
+		return BCME_ERROR;
+	}
+
+	ret = __dhd_pktid_audit(dhdp, map, pktid, test_for, func);
+	if (ret == BCME_ERROR) {
+		DHD_ERROR(("%s: Got Pkt Id Audit failure: PKTID<%d> PKTID MAP TYPE<%d>\n",
+			__FUNCTION__, pktid, dhd_get_pktid_map_type(dhdp, map)));
+		prhex(func, (uchar *)msg, msg_len);
+		if (map == dhdp->prot->pktid_ctrl_map) {
+#ifdef DHD_DEBUG_INVALID_PKTID
+			prhex("ctrl_cpl_snapshot", dhdp->prot->ctrl_cpl_snapshot,
+				D2HRING_CTRL_CMPLT_ITEMSIZE);
+#endif /* DHD_DEBUG_INVALID_PKTID */
+		}
+		DHD_ERROR(("%s: ### For pktid audit failures, read curr_rd as curr_rd - 1,"
+			" as it is updated early before item processing ###\n",
+			__FUNCTION__));
+		dhd_prot_debug_ring_info(dhdp);
+		DHD_PKTID_ERROR_HANDLER(dhdp);
+#ifdef DHD_MAP_PKTID_LOGGING
+		DHD_PKTID_LOG_DUMP(dhdp);
+#endif /* DHD_MAP_PKTID_LOGGING */
+	}
+	return ret;
+}
+#define DHD_PKTID_AUDIT_RING_DEBUG(dhdp, map, pktid, test_for, msg, msg_len) \
+	dhd_pktid_audit_ring_debug((dhdp), (dhd_pktid_map_t *)(map), \
+		(pktid), (test_for), msg, msg_len, __FUNCTION__)
+
+#endif /* DHD_PKTID_AUDIT_ENABLED */
+
+/**
+ * +---------------------------------------------------------------------------+
+ * Packet to Packet Id mapper using a <numbered_key, locker> paradigm.
+ *
+ * dhd_pktid_map manages a set of unique Packet Ids range[1..MAX_xxx_PKTID].
+ *
+ * dhd_pktid_map_alloc() may be used to save some packet metadata, and a unique
+ * packet id is returned. This unique packet id may be used to retrieve the
+ * previously saved packet metadata, using dhd_pktid_map_free(). On invocation
+ * of dhd_pktid_map_free(), the unique packet id is essentially freed. A
+ * subsequent call to dhd_pktid_map_alloc() may reuse this packet id.
+ *
+ * Implementation Note:
+ * Convert this into a <key,locker> abstraction and place into bcmutils !
+ * Locker abstraction should treat contents as opaque storage, and a
+ * callback should be registered to handle busy lockers on destructor.
+ *
+ * +---------------------------------------------------------------------------+
+ */
+
+/** Allocate and initialize a mapper of num_items <numbered_key, locker> */
+
+static dhd_pktid_map_handle_t *
+dhd_pktid_map_init(dhd_pub_t *dhd, uint32 num_items)
+{
+	void* osh;
+	uint32 nkey;
+	dhd_pktid_map_t *map;
+	uint32 dhd_pktid_map_sz;
+	uint32 map_items;
+	uint32 map_keys_sz;
+	osh = dhd->osh;
+
+	dhd_pktid_map_sz = DHD_PKTID_MAP_SZ(num_items);
+
+	map = (dhd_pktid_map_t *)VMALLOC(osh, dhd_pktid_map_sz);
+	if (map == NULL) {
+		DHD_ERROR(("%s:%d: VMALLOC failed for size %d\n",
+			__FUNCTION__, __LINE__, dhd_pktid_map_sz));
+		return (dhd_pktid_map_handle_t *)NULL;
+	}
+
+	map->items = num_items;
+	map->avail = num_items;
+
+	map_items = DHD_PKIDMAP_ITEMS(map->items);
+
+	map_keys_sz = DHD_PKTIDMAP_KEYS_SZ(map->items);
+
+	/* Initialize the lock that protects this structure */
+	map->pktid_lock = DHD_PKTID_LOCK_INIT(osh);
+	if (map->pktid_lock == NULL) {
+		DHD_ERROR(("%s:%d: Lock init failed \r\n", __FUNCTION__, __LINE__));
+		goto error;
+	}
+
+	map->keys = (dhd_pktid_key_t *)VMALLOC(osh, map_keys_sz);
+	if (map->keys == NULL) {
+		DHD_ERROR(("%s:%d: VMALLOC failed for map->keys size %d\n",
+			__FUNCTION__, __LINE__, map_keys_sz));
+		goto error;
+	}
+
+#if defined(DHD_PKTID_AUDIT_ENABLED)
+		/* Incarnate a hierarchical multiword bitmap for auditing pktid allocator */
+		map->pktid_audit = bcm_mwbmap_init(osh, map_items + 1);
+		if (map->pktid_audit == (struct bcm_mwbmap *)NULL) {
+			DHD_ERROR(("%s:%d: pktid_audit init failed\r\n", __FUNCTION__, __LINE__));
+			goto error;
+		} else {
+			DHD_ERROR(("%s:%d: pktid_audit init succeeded %d\n",
+				__FUNCTION__, __LINE__, map_items + 1));
+		}
+		map->pktid_audit_lock = DHD_PKTID_AUDIT_LOCK_INIT(osh);
+#endif /* DHD_PKTID_AUDIT_ENABLED */
+
+	for (nkey = 1; nkey <= map_items; nkey++) { /* locker #0 is reserved */
+		map->keys[nkey] = nkey; /* populate with unique keys */
+		map->lockers[nkey].state = LOCKER_IS_FREE;
+		map->lockers[nkey].pkt   = NULL; /* bzero: redundant */
+		map->lockers[nkey].len   = 0;
+	}
+
+	/* Reserve pktid #0, i.e. DHD_PKTID_INVALID to be inuse */
+	map->lockers[DHD_PKTID_INVALID].state = LOCKER_IS_BUSY; /* tag locker #0 as inuse */
+	map->lockers[DHD_PKTID_INVALID].pkt   = NULL; /* bzero: redundant */
+	map->lockers[DHD_PKTID_INVALID].len   = 0;
+
+#if defined(DHD_PKTID_AUDIT_ENABLED)
+	/* do not use dhd_pktid_audit() here, use bcm_mwbmap_force directly */
+	bcm_mwbmap_force(map->pktid_audit, DHD_PKTID_INVALID);
+#endif /* DHD_PKTID_AUDIT_ENABLED */
+
+	return (dhd_pktid_map_handle_t *)map; /* opaque handle */
+
+error:
+	if (map) {
+#if defined(DHD_PKTID_AUDIT_ENABLED)
+		if (map->pktid_audit != (struct bcm_mwbmap *)NULL) {
+			bcm_mwbmap_fini(osh, map->pktid_audit); /* Destruct pktid_audit */
+			map->pktid_audit = (struct bcm_mwbmap *)NULL;
+			if (map->pktid_audit_lock)
+				DHD_PKTID_AUDIT_LOCK_DEINIT(osh, map->pktid_audit_lock);
+		}
+#endif /* DHD_PKTID_AUDIT_ENABLED */
+
+		if (map->keys) {
+			VMFREE(osh, map->keys, map_keys_sz);
+		}
+
+		if (map->pktid_lock) {
+			DHD_PKTID_LOCK_DEINIT(osh, map->pktid_lock);
+		}
+
+		VMFREE(osh, map, dhd_pktid_map_sz);
+	}
+	return (dhd_pktid_map_handle_t *)NULL;
+}
+
+/**
+ * Retrieve all allocated keys and free all <numbered_key, locker>.
+ * Freeing implies: unmapping the buffers and freeing the native packet
+ * This could have been a callback registered with the pktid mapper.
+ */
+static void
+dhd_pktid_map_reset(dhd_pub_t *dhd, dhd_pktid_map_handle_t *handle)
+{
+	void *osh;
+	uint32 nkey;
+	dhd_pktid_map_t *map;
+	dhd_pktid_item_t *locker;
+	uint32 map_items;
+	unsigned long flags;
+	bool data_tx = FALSE;
+
+	if (handle == NULL) {
+		return;
+	}
+
+	map = (dhd_pktid_map_t *)handle;
+	DHD_PKTID_LOCK(map->pktid_lock, flags);
+	osh = dhd->osh;
+
+	map_items = DHD_PKIDMAP_ITEMS(map->items);
+	/* skip reserved KEY #0, and start from 1 */
+
+	for (nkey = 1; nkey <= map_items; nkey++) {
+		if (map->lockers[nkey].state == LOCKER_IS_BUSY) {
+			locker = &map->lockers[nkey];
+			locker->state = LOCKER_IS_FREE;
+			data_tx = (locker->pkttype == PKTTYPE_DATA_TX);
+			if (data_tx) {
+				OSL_ATOMIC_DEC(dhd->osh, &dhd->prot->active_tx_count);
+			}
+
+#ifdef DHD_PKTID_AUDIT_RING
+			DHD_PKTID_AUDIT(dhd, map, nkey, DHD_DUPLICATE_FREE); /* duplicate frees */
+#endif /* DHD_PKTID_AUDIT_RING */
+#ifdef DHD_MAP_PKTID_LOGGING
+			DHD_PKTID_LOG(dhd, dhd->prot->pktid_dma_unmap,
+				locker->pa, nkey, locker->len,
+				locker->pkttype);
+#endif /* DHD_MAP_PKTID_LOGGING */
+
+			DMA_UNMAP(osh, locker->pa, locker->len, locker->dir, 0, locker->dmah);
+			dhd_prot_packet_free(dhd, (ulong*)locker->pkt,
+				locker->pkttype, data_tx);
+		}
+		else {
+#ifdef DHD_PKTID_AUDIT_RING
+			DHD_PKTID_AUDIT(dhd, map, nkey, DHD_TEST_IS_FREE);
+#endif /* DHD_PKTID_AUDIT_RING */
+		}
+		map->keys[nkey] = nkey; /* populate with unique keys */
+	}
+
+	map->avail = map_items;
+	memset(&map->lockers[1], 0, sizeof(dhd_pktid_item_t) * map_items);
+	DHD_PKTID_UNLOCK(map->pktid_lock, flags);
+}
+
+#ifdef IOCTLRESP_USE_CONSTMEM
+/** Called in detach scenario. Releasing IOCTL buffers. */
+static void
+dhd_pktid_map_reset_ioctl(dhd_pub_t *dhd, dhd_pktid_map_handle_t *handle)
+{
+	uint32 nkey;
+	dhd_pktid_map_t *map;
+	dhd_pktid_item_t *locker;
+	uint32 map_items;
+	unsigned long flags;
+
+	if (handle == NULL) {
+		return;
+	}
+
+	map = (dhd_pktid_map_t *)handle;
+	DHD_PKTID_LOCK(map->pktid_lock, flags);
+
+	map_items = DHD_PKIDMAP_ITEMS(map->items);
+	/* skip reserved KEY #0, and start from 1 */
+	for (nkey = 1; nkey <= map_items; nkey++) {
+		if (map->lockers[nkey].state == LOCKER_IS_BUSY) {
+			dhd_dma_buf_t retbuf;
+
+#ifdef DHD_PKTID_AUDIT_RING
+			DHD_PKTID_AUDIT(dhd, map, nkey, DHD_DUPLICATE_FREE); /* duplicate frees */
+#endif /* DHD_PKTID_AUDIT_RING */
+
+			locker = &map->lockers[nkey];
+			retbuf.va = locker->pkt;
+			retbuf.len = locker->len;
+			retbuf.pa = locker->pa;
+			retbuf.dmah = locker->dmah;
+			retbuf.secdma = locker->secdma;
+
+			free_ioctl_return_buffer(dhd, &retbuf);
+		}
+		else {
+#ifdef DHD_PKTID_AUDIT_RING
+			DHD_PKTID_AUDIT(dhd, map, nkey, DHD_TEST_IS_FREE);
+#endif /* DHD_PKTID_AUDIT_RING */
+		}
+		map->keys[nkey] = nkey; /* populate with unique keys */
+	}
+
+	map->avail = map_items;
+	memset(&map->lockers[1], 0, sizeof(dhd_pktid_item_t) * map_items);
+	DHD_PKTID_UNLOCK(map->pktid_lock, flags);
+}
+#endif /* IOCTLRESP_USE_CONSTMEM */
+
+/**
+ * Free the pktid map.
+ */
+static void
+dhd_pktid_map_fini(dhd_pub_t *dhd, dhd_pktid_map_handle_t *handle)
+{
+	dhd_pktid_map_t *map;
+	uint32 dhd_pktid_map_sz;
+	uint32 map_keys_sz;
+
+	if (handle == NULL)
+		return;
+
+	/* Free any pending packets */
+	dhd_pktid_map_reset(dhd, handle);
+
+	map = (dhd_pktid_map_t *)handle;
+	dhd_pktid_map_sz = DHD_PKTID_MAP_SZ(map->items);
+	map_keys_sz = DHD_PKTIDMAP_KEYS_SZ(map->items);
+
+	DHD_PKTID_LOCK_DEINIT(dhd->osh, map->pktid_lock);
+
+#if defined(DHD_PKTID_AUDIT_ENABLED)
+	if (map->pktid_audit != (struct bcm_mwbmap *)NULL) {
+		bcm_mwbmap_fini(dhd->osh, map->pktid_audit); /* Destruct pktid_audit */
+		map->pktid_audit = (struct bcm_mwbmap *)NULL;
+		if (map->pktid_audit_lock) {
+			DHD_PKTID_AUDIT_LOCK_DEINIT(dhd->osh, map->pktid_audit_lock);
+		}
+	}
+#endif /* DHD_PKTID_AUDIT_ENABLED */
+	VMFREE(dhd->osh, map->keys, map_keys_sz);
+	VMFREE(dhd->osh, handle, dhd_pktid_map_sz);
+}
+
+#ifdef IOCTLRESP_USE_CONSTMEM
+static void
+dhd_pktid_map_fini_ioctl(dhd_pub_t *dhd, dhd_pktid_map_handle_t *handle)
+{
+	dhd_pktid_map_t *map;
+	uint32 dhd_pktid_map_sz;
+	uint32 map_keys_sz;
+
+	if (handle == NULL)
+		return;
+
+	/* Free any pending packets */
+	dhd_pktid_map_reset_ioctl(dhd, handle);
+
+	map = (dhd_pktid_map_t *)handle;
+	dhd_pktid_map_sz = DHD_PKTID_MAP_SZ(map->items);
+	map_keys_sz = DHD_PKTIDMAP_KEYS_SZ(map->items);
+
+	DHD_PKTID_LOCK_DEINIT(dhd->osh, map->pktid_lock);
+
+#if defined(DHD_PKTID_AUDIT_ENABLED)
+	if (map->pktid_audit != (struct bcm_mwbmap *)NULL) {
+		bcm_mwbmap_fini(dhd->osh, map->pktid_audit); /* Destruct pktid_audit */
+		map->pktid_audit = (struct bcm_mwbmap *)NULL;
+		if (map->pktid_audit_lock) {
+			DHD_PKTID_AUDIT_LOCK_DEINIT(dhd->osh, map->pktid_audit_lock);
+		}
+	}
+#endif /* DHD_PKTID_AUDIT_ENABLED */
+
+	VMFREE(dhd->osh, map->keys, map_keys_sz);
+	VMFREE(dhd->osh, handle, dhd_pktid_map_sz);
+}
+#endif /* IOCTLRESP_USE_CONSTMEM */
+
+/** Get the pktid free count */
+static INLINE uint32
+BCMFASTPATH(dhd_pktid_map_avail_cnt)(dhd_pktid_map_handle_t *handle)
+{
+	dhd_pktid_map_t *map;
+	uint32	avail;
+	unsigned long flags;
+
+	ASSERT(handle != NULL);
+	map = (dhd_pktid_map_t *)handle;
+
+	DHD_PKTID_LOCK(map->pktid_lock, flags);
+	avail = map->avail;
+	DHD_PKTID_UNLOCK(map->pktid_lock, flags);
+
+	return avail;
+}
+
+/**
+ * dhd_pktid_map_reserve - reserve a unique numbered key. Reserved locker is not
+ * yet populated. Invoke the pktid save api to populate the packet parameters
+ * into the locker. This function is not reentrant, and is the caller's
+ * responsibility. Caller must treat a returned value DHD_PKTID_INVALID as
+ * a failure case, implying a depleted pool of pktids.
+ */
+static INLINE uint32
+dhd_pktid_map_reserve(dhd_pub_t *dhd, dhd_pktid_map_handle_t *handle,
+	void *pkt, dhd_pkttype_t pkttype)
+{
+	uint32 nkey;
+	dhd_pktid_map_t *map;
+	dhd_pktid_item_t *locker;
+	unsigned long flags;
+
+	ASSERT(handle != NULL);
+	map = (dhd_pktid_map_t *)handle;
+
+	DHD_PKTID_LOCK(map->pktid_lock, flags);
+
+	if ((int)(map->avail) <= 0) { /* no more pktids to allocate */
+		map->failures++;
+		DHD_INFO(("%s:%d: failed, no free keys\n", __FUNCTION__, __LINE__));
+		DHD_PKTID_UNLOCK(map->pktid_lock, flags);
+		return DHD_PKTID_INVALID; /* failed alloc request */
+	}
+
+	ASSERT(map->avail <= map->items);
+	nkey = map->keys[map->avail]; /* fetch a free locker, pop stack */
+
+	if ((map->avail > map->items) || (nkey > map->items)) {
+		map->failures++;
+		DHD_ERROR(("%s:%d: failed to allocate a new pktid,"
+			" map->avail<%u>, nkey<%u>, pkttype<%u>\n",
+			__FUNCTION__, __LINE__, map->avail, nkey,
+			pkttype));
+		DHD_PKTID_UNLOCK(map->pktid_lock, flags);
+		return DHD_PKTID_INVALID; /* failed alloc request */
+	}
+
+	locker = &map->lockers[nkey]; /* save packet metadata in locker */
+	map->avail--;
+	locker->pkt = pkt; /* pkt is saved, other params not yet saved. */
+	locker->len = 0;
+	locker->state = LOCKER_IS_BUSY; /* reserve this locker */
+
+	DHD_PKTID_UNLOCK(map->pktid_lock, flags);
+
+	ASSERT(nkey != DHD_PKTID_INVALID);
+
+	return nkey; /* return locker's numbered key */
+}
+
+/*
+ * dhd_pktid_map_save - Save a packet's parameters into a locker
+ * corresponding to a previously reserved unique numbered key.
+ */
+static INLINE void
+dhd_pktid_map_save(dhd_pub_t *dhd, dhd_pktid_map_handle_t *handle, void *pkt,
+	uint32 nkey, dmaaddr_t pa, uint32 len, uint8 dir, void *dmah, void *secdma,
+	dhd_pkttype_t pkttype)
+{
+	dhd_pktid_map_t *map;
+	dhd_pktid_item_t *locker;
+	unsigned long flags;
+
+	ASSERT(handle != NULL);
+	map = (dhd_pktid_map_t *)handle;
+
+	DHD_PKTID_LOCK(map->pktid_lock, flags);
+
+	if ((nkey == DHD_PKTID_INVALID) || (nkey > DHD_PKIDMAP_ITEMS(map->items)) ||
+			(dhd->dhd_induce_error == DHD_INDUCE_PKTID_INVALID_SAVE)) {
+		DHD_ERROR(("%s:%d: Error! saving invalid pktid<%u> pkttype<%u>\n",
+			__FUNCTION__, __LINE__, nkey, pkttype));
+		DHD_PKTID_UNLOCK(map->pktid_lock, flags);
+#ifdef DHD_FW_COREDUMP
+		if (dhd->memdump_enabled) {
+			dhd->pktid_invalid_occured = TRUE;
+			/* collect core dump */
+			dhd->memdump_type = DUMP_TYPE_PKTID_INVALID;
+			dhd_bus_mem_dump(dhd);
+#ifdef OEM_ANDROID
+			dhd->hang_reason = HANG_REASON_PCIE_PKTID_ERROR;
+			dhd_os_send_hang_message(dhd);
+#endif /* OEM_ANDROID */
+
+		}
+#else
+		ASSERT(0);
+#endif /* DHD_FW_COREDUMP */
+		return;
+	}
+
+	locker = &map->lockers[nkey];
+
+	ASSERT(((locker->state == LOCKER_IS_BUSY) && (locker->pkt == pkt)) ||
+		((locker->state == LOCKER_IS_RSVD) && (locker->pkt == NULL)));
+
+	/* store contents in locker */
+	locker->dir = dir;
+	locker->pa = pa;
+	locker->len = (uint16)len; /* 16bit len */
+	locker->dmah = dmah; /* 16bit len */
+	locker->secdma = secdma;
+	locker->pkttype = pkttype;
+	locker->pkt = pkt;
+	locker->state = LOCKER_IS_BUSY; /* make this locker busy */
+#ifdef DHD_MAP_PKTID_LOGGING
+	DHD_PKTID_LOG(dhd, dhd->prot->pktid_dma_map, pa, nkey, len, pkttype);
+#endif /* DHD_MAP_PKTID_LOGGING */
+	DHD_PKTID_UNLOCK(map->pktid_lock, flags);
+}
+
+/**
+ * dhd_pktid_map_alloc - Allocate a unique numbered key and save the packet
+ * contents into the corresponding locker. Return the numbered key.
+ */
+static uint32
+BCMFASTPATH(dhd_pktid_map_alloc)(dhd_pub_t *dhd, dhd_pktid_map_handle_t *handle, void *pkt,
+	dmaaddr_t pa, uint32 len, uint8 dir, void *dmah, void *secdma,
+	dhd_pkttype_t pkttype)
+{
+	uint32 nkey;
+
+	nkey = dhd_pktid_map_reserve(dhd, handle, pkt, pkttype);
+	if (nkey != DHD_PKTID_INVALID) {
+		dhd_pktid_map_save(dhd, handle, pkt, nkey, pa,
+			len, dir, dmah, secdma, pkttype);
+	}
+
+	return nkey;
+}
+
+/**
+ * dhd_pktid_map_free - Given a numbered key, return the locker contents.
+ * dhd_pktid_map_free() is not reentrant, and is the caller's responsibility.
+ * Caller may not free a pktid value DHD_PKTID_INVALID or an arbitrary pktid
+ * value. Only a previously allocated pktid may be freed.
+ */
+static void *
+BCMFASTPATH(dhd_pktid_map_free)(dhd_pub_t *dhd, dhd_pktid_map_handle_t *handle, uint32 nkey,
+	dmaaddr_t *pa, uint32 *len, void **dmah, void **secdma, dhd_pkttype_t pkttype,
+	bool rsv_locker)
+{
+	dhd_pktid_map_t *map;
+	dhd_pktid_item_t *locker;
+	void * pkt;
+	unsigned long long locker_addr;
+	unsigned long flags;
+
+	ASSERT(handle != NULL);
+
+	map = (dhd_pktid_map_t *)handle;
+
+	DHD_PKTID_LOCK(map->pktid_lock, flags);
+
+	/* XXX PLEASE DO NOT remove this ASSERT, fix the bug in caller. */
+	if ((nkey == DHD_PKTID_INVALID) || (nkey > DHD_PKIDMAP_ITEMS(map->items)) ||
+			(dhd->dhd_induce_error == DHD_INDUCE_PKTID_INVALID_FREE)) {
+		DHD_ERROR(("%s:%d: Error! Try to free invalid pktid<%u>, pkttype<%d>\n",
+		           __FUNCTION__, __LINE__, nkey, pkttype));
+		DHD_PKTID_UNLOCK(map->pktid_lock, flags);
+#ifdef DHD_FW_COREDUMP
+		if (dhd->memdump_enabled) {
+			dhd->pktid_invalid_occured = TRUE;
+			/* collect core dump */
+			dhd->memdump_type = DUMP_TYPE_PKTID_INVALID;
+			dhd_bus_mem_dump(dhd);
+#ifdef OEM_ANDROID
+			dhd->hang_reason = HANG_REASON_PCIE_PKTID_ERROR;
+			dhd_os_send_hang_message(dhd);
+#endif /* OEM_ANDROID */
+		}
+#else
+		ASSERT(0);
+#endif /* DHD_FW_COREDUMP */
+		return NULL;
+	}
+
+	locker = &map->lockers[nkey];
+
+#if defined(DHD_PKTID_AUDIT_MAP)
+	DHD_PKTID_AUDIT(dhd, map, nkey, DHD_DUPLICATE_FREE); /* Audit duplicate FREE */
+#endif /* DHD_PKTID_AUDIT_MAP */
+
+	/* Debug check for cloned numbered key */
+	if (locker->state == LOCKER_IS_FREE) {
+		DHD_ERROR(("%s:%d: Error! freeing already freed invalid pktid<%u>\n",
+		           __FUNCTION__, __LINE__, n
[file cut: first 33554432 bytes kept]
[document cut: first 30728968 of 33553730 characters kept]
